]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jan 2008 11:54:01 +0000 (22:54 +1100)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 29 Jan 2008 11:54:01 +0000 (22:54 +1100)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25: (1470 commits)
  [IPV6] ADDRLABEL: Fix double free on label deletion.
  [PPP]: Sparse warning fixes.
  [IPV4] fib_trie: remove unneeded NULL check
  [IPV4] fib_trie: More whitespace cleanup.
  [NET_SCHED]: Use nla_policy for attribute validation in ematches
  [NET_SCHED]: Use nla_policy for attribute validation in actions
  [NET_SCHED]: Use nla_policy for attribute validation in classifiers
  [NET_SCHED]: Use nla_policy for attribute validation in packet schedulers
  [NET_SCHED]: sch_api: introduce constant for rate table size
  [NET_SCHED]: Use typeful attribute parsing helpers
  [NET_SCHED]: Use typeful attribute construction helpers
  [NET_SCHED]: Use NLA_PUT_STRING for string dumping
  [NET_SCHED]: Use nla_nest_start/nla_nest_end
  [NET_SCHED]: Propagate nla_parse return value
  [NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get
  [NET_SCHED]: act_api: use nlmsg_parse
  [NET_SCHED]: act_api: fix netlink API conversion bug
  [NET_SCHED]: sch_netem: use nla_parse_nested_compat
  [NET_SCHED]: sch_atm: fix format string warning
  [NETNS]: Add namespace for ICMP replying code.
  ...

1115 files changed:
CREDITS
Documentation/feature-removal-schedule.txt
Documentation/networking/00-INDEX
Documentation/networking/bonding.txt
Documentation/networking/can.txt [new file with mode: 0644]
Documentation/networking/dccp.txt
Documentation/networking/ip-sysctl.txt
Documentation/networking/shaper.txt [deleted file]
Documentation/networking/udplite.txt
Documentation/networking/xfrm_proc.txt [new file with mode: 0644]
MAINTAINERS
arch/ia64/hp/sim/simeth.c
arch/powerpc/platforms/pasemi/Makefile
arch/powerpc/platforms/pasemi/dma_lib.c [new file with mode: 0644]
arch/powerpc/platforms/pasemi/pasemi.h
arch/ppc/8260_io/enet.c
arch/ppc/8260_io/fcc_enet.c
drivers/atm/ambassador.c
drivers/atm/he.c
drivers/connector/cn_queue.c
drivers/connector/connector.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cma.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/net/3c501.c
drivers/net/3c507.c
drivers/net/3c515.c
drivers/net/7990.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/amd8111e.c
drivers/net/at1700.c
drivers/net/b44.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bnx2_fw.h
drivers/net/bnx2_fw2.h
drivers/net/bnx2x.c [new file with mode: 0644]
drivers/net/bnx2x.h [new file with mode: 0644]
drivers/net/bnx2x_fw_defs.h [new file with mode: 0644]
drivers/net/bnx2x_hsi.h [new file with mode: 0644]
drivers/net/bnx2x_init.h [new file with mode: 0644]
drivers/net/bnx2x_init_values.h [new file with mode: 0644]
drivers/net/bnx2x_reg.h [new file with mode: 0644]
drivers/net/bonding/bond_main.c
drivers/net/can/Kconfig [new file with mode: 0644]
drivers/net/can/Makefile [new file with mode: 0644]
drivers/net/can/vcan.c [new file with mode: 0644]
drivers/net/cassini.c
drivers/net/chelsio/common.h
drivers/net/chelsio/cxgb2.c
drivers/net/chelsio/espi.c
drivers/net/chelsio/espi.h
drivers/net/chelsio/sge.c
drivers/net/chelsio/sge.h
drivers/net/chelsio/subr.c
drivers/net/cpmac.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/common.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/firmware_exports.h
drivers/net/cxgb3/l2t.c
drivers/net/cxgb3/regs.h
drivers/net/cxgb3/sge.c
drivers/net/cxgb3/t3_hw.c
drivers/net/cxgb3/version.h
drivers/net/cxgb3/xgmac.c
drivers/net/declance.c
drivers/net/e100.c
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000/e1000_hw.h
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/hw.h
drivers/net/e1000e/lib.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/param.c
drivers/net/e1000e/phy.c
drivers/net/eepro100.c
drivers/net/eexpress.c
drivers/net/enc28j60.c [new file with mode: 0644]
drivers/net/enc28j60_hw.h [new file with mode: 0644]
drivers/net/forcedeth.c
drivers/net/gianfar_sysfs.c
drivers/net/hamradio/6pack.c
drivers/net/hamradio/mkiss.c
drivers/net/hamradio/scc.c
drivers/net/hp100.c
drivers/net/ibm_newemac/core.c
drivers/net/ibmlana.c
drivers/net/igb/Makefile [new file with mode: 0644]
drivers/net/igb/e1000_82575.c [new file with mode: 0644]
drivers/net/igb/e1000_82575.h [new file with mode: 0644]
drivers/net/igb/e1000_defines.h [new file with mode: 0644]
drivers/net/igb/e1000_hw.h [new file with mode: 0644]
drivers/net/igb/e1000_mac.c [new file with mode: 0644]
drivers/net/igb/e1000_mac.h [new file with mode: 0644]
drivers/net/igb/e1000_nvm.c [new file with mode: 0644]
drivers/net/igb/e1000_nvm.h [new file with mode: 0644]
drivers/net/igb/e1000_phy.c [new file with mode: 0644]
drivers/net/igb/e1000_phy.h [new file with mode: 0644]
drivers/net/igb/e1000_regs.h [new file with mode: 0644]
drivers/net/igb/igb.h [new file with mode: 0644]
drivers/net/igb/igb_ethtool.c [new file with mode: 0644]
drivers/net/igb/igb_main.c [new file with mode: 0644]
drivers/net/ipg.c
drivers/net/ipg.h
drivers/net/irda/Kconfig
drivers/net/irda/Makefile
drivers/net/irda/act200l.c [deleted file]
drivers/net/irda/actisys.c [deleted file]
drivers/net/irda/ep7211_ir.c [deleted file]
drivers/net/irda/esi.c [deleted file]
drivers/net/irda/girbil.c [deleted file]
drivers/net/irda/irport.c [deleted file]
drivers/net/irda/irport.h [deleted file]
drivers/net/irda/litelink.c [deleted file]
drivers/net/irda/ma600.c [deleted file]
drivers/net/irda/mcp2120.c [deleted file]
drivers/net/irda/old_belkin.c [deleted file]
drivers/net/irda/smsc-ircc2.c
drivers/net/irda/tekram.c [deleted file]
drivers/net/irda/via-ircc.c
drivers/net/ixgb/ixgb_hw.c
drivers/net/ixgb/ixgb_hw.h
drivers/net/ixgb/ixgb_ids.h
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_phy.h
drivers/net/ixgbe/ixgbe_type.h
drivers/net/loopback.c
drivers/net/lp486e.c
drivers/net/mac89x0.c
drivers/net/mace.c
drivers/net/macvlan.c
drivers/net/myri10ge/myri10ge.c
drivers/net/netconsole.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ethtool.c
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_isr.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/niu.c
drivers/net/ns83820.c
drivers/net/pasemi_mac.c
drivers/net/pasemi_mac.h
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcnet32.c
drivers/net/plip.c
drivers/net/ppp_deflate.c
drivers/net/ppp_generic.c
drivers/net/ppp_synctty.c
drivers/net/pppoe.c
drivers/net/pppol2tp.c
drivers/net/qla3xxx.c
drivers/net/qla3xxx.h
drivers/net/r6040.c [new file with mode: 0644]
drivers/net/rrunner.c
drivers/net/s2io-regs.h
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sgiseeq.c
drivers/net/shaper.c [deleted file]
drivers/net/sis900.c
drivers/net/sk98lin/skgemib.c
drivers/net/sk98lin/skgepnmi.c
drivers/net/sk98lin/skgesirq.c
drivers/net/skfp/hwmtm.c
drivers/net/skfp/smt.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/slhc.c
drivers/net/slip.c
drivers/net/smc9194.c
drivers/net/sundance.c
drivers/net/sungem.c
drivers/net/sungem.h
drivers/net/sunhme.c
drivers/net/sunhme.h
drivers/net/sunvnet.c
drivers/net/tehuti.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tokenring/olympic.c
drivers/net/tokenring/olympic.h
drivers/net/tokenring/smctr.c
drivers/net/tulip/de4x5.c
drivers/net/tun.c
drivers/net/ucc_geth.c
drivers/net/usb/dm9601.c
drivers/net/via-rhine.c
drivers/net/wan/farsync.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wan/hdlc_raw_eth.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wan/lmc/lmc_media.c
drivers/net/wan/lmc/lmc_proto.c
drivers/net/wan/lmc/lmc_proto.h
drivers/net/wan/pc300_drv.c
drivers/net/wan/pc300_tty.c
drivers/net/wan/sbni.c
drivers/net/wan/sdla.c
drivers/net/wan/wanxl.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/adm8211.c
drivers/net/wireless/airo.c
drivers/net/wireless/ath5k/Makefile [new file with mode: 0644]
drivers/net/wireless/ath5k/ath5k.h [new file with mode: 0644]
drivers/net/wireless/ath5k/base.c [new file with mode: 0644]
drivers/net/wireless/ath5k/base.h [new file with mode: 0644]
drivers/net/wireless/ath5k/debug.c [new file with mode: 0644]
drivers/net/wireless/ath5k/debug.h [new file with mode: 0644]
drivers/net/wireless/ath5k/hw.c [new file with mode: 0644]
drivers/net/wireless/ath5k/hw.h [new file with mode: 0644]
drivers/net/wireless/ath5k/initvals.c [new file with mode: 0644]
drivers/net/wireless/ath5k/phy.c [new file with mode: 0644]
drivers/net/wireless/ath5k/reg.h [new file with mode: 0644]
drivers/net/wireless/ath5k/regdom.c [new file with mode: 0644]
drivers/net/wireless/ath5k/regdom.h [new file with mode: 0644]
drivers/net/wireless/atmel.c
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/Makefile
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/debugfs.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/dma.h
drivers/net/wireless/b43/leds.c
drivers/net/wireless/b43/lo.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/main.h
drivers/net/wireless/b43/nphy.c [new file with mode: 0644]
drivers/net/wireless/b43/nphy.h [new file with mode: 0644]
drivers/net/wireless/b43/phy.c
drivers/net/wireless/b43/phy.h
drivers/net/wireless/b43/pio.c [deleted file]
drivers/net/wireless/b43/pio.h [deleted file]
drivers/net/wireless/b43/tables.c
drivers/net/wireless/b43/tables.h
drivers/net/wireless/b43/tables_nphy.c [new file with mode: 0644]
drivers/net/wireless/b43/tables_nphy.h [new file with mode: 0644]
drivers/net/wireless/b43/wa.c [new file with mode: 0644]
drivers/net/wireless/b43/wa.h [new file with mode: 0644]
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.h
drivers/net/wireless/b43legacy/Kconfig
drivers/net/wireless/b43legacy/Makefile
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/debugfs.c
drivers/net/wireless/b43legacy/ilt.c
drivers/net/wireless/b43legacy/leds.c
drivers/net/wireless/b43legacy/leds.h
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/main.h
drivers/net/wireless/b43legacy/phy.c
drivers/net/wireless/b43legacy/phy.h
drivers/net/wireless/b43legacy/radio.c
drivers/net/wireless/b43legacy/radio.h
drivers/net/wireless/b43legacy/rfkill.c [new file with mode: 0644]
drivers/net/wireless/b43legacy/rfkill.h [new file with mode: 0644]
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/bcm43xx/Kconfig
drivers/net/wireless/bcm43xx/bcm43xx.h
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_pio.c
drivers/net/wireless/bcm43xx/bcm43xx_xmit.c
drivers/net/wireless/hostap/hostap_80211.h
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_common.h
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_download.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_info.c
drivers/net/wireless/hostap/hostap_ioctl.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/hostap/hostap_pci.c
drivers/net/wireless/hostap/hostap_wlan.h
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/ipw2200.h
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl-3945-commands.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-3945-debug.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-3945-hw.h
drivers/net/wireless/iwlwifi/iwl-3945-io.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965-commands.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-4965-debug.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-4965-hw.h
drivers/net/wireless/iwlwifi/iwl-4965-io.h [new file with mode: 0644]
drivers/net/wireless/iwlwifi/iwl-4965-rs.c
drivers/net/wireless/iwlwifi/iwl-4965-rs.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-4965.h
drivers/net/wireless/iwlwifi/iwl-channel.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-commands.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-debug.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-eeprom.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl-hw.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-io.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-priv.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/iwlwifi/iwlwifi.h [deleted file]
drivers/net/wireless/libertas/11d.c
drivers/net/wireless/libertas/11d.h
drivers/net/wireless/libertas/README
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/assoc.h
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmd.h [new file with mode: 0644]
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/debugfs.h
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/ethtool.c
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_usb.c
drivers/net/wireless/libertas/if_usb.h
drivers/net/wireless/libertas/join.c
drivers/net/wireless/libertas/join.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/scan.h
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/types.h
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/libertas/wext.h
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco.h
drivers/net/wireless/p54common.c
drivers/net/wireless/p54pci.c
drivers/net/wireless/p54pci.h
drivers/net/wireless/prism54/isl_38xx.h
drivers/net/wireless/prism54/isl_ioctl.c
drivers/net/wireless/prism54/islpci_dev.c
drivers/net/wireless/prism54/islpci_dev.h
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/prism54/islpci_eth.h
drivers/net/wireless/prism54/islpci_mgt.c
drivers/net/wireless/prism54/islpci_mgt.h
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2400pci.h
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500pci.h
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2500usb.h
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00debug.c
drivers/net/wireless/rt2x00/rt2x00debug.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00dump.h [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2x00firmware.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00pci.h
drivers/net/wireless/rt2x00/rt2x00rfkill.c
drivers/net/wireless/rt2x00/rt2x00ring.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rt2x00/rt73usb.h
drivers/net/wireless/rtl8180.h [new file with mode: 0644]
drivers/net/wireless/rtl8180_dev.c [new file with mode: 0644]
drivers/net/wireless/rtl8180_grf5101.c [new file with mode: 0644]
drivers/net/wireless/rtl8180_grf5101.h [new file with mode: 0644]
drivers/net/wireless/rtl8180_max2820.c [new file with mode: 0644]
drivers/net/wireless/rtl8180_max2820.h [new file with mode: 0644]
drivers/net/wireless/rtl8180_rtl8225.c [new file with mode: 0644]
drivers/net/wireless/rtl8180_rtl8225.h [new file with mode: 0644]
drivers/net/wireless/rtl8180_sa2400.c [new file with mode: 0644]
drivers/net/wireless/rtl8180_sa2400.h [new file with mode: 0644]
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187_dev.c
drivers/net/wireless/rtl8187_rtl8225.c
drivers/net/wireless/rtl8187_rtl8225.h
drivers/net/wireless/rtl818x.h
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan.p.h
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wavelan_cs.p.h
drivers/net/wireless/zd1211rw/Kconfig
drivers/net/wireless/zd1211rw/Makefile
drivers/net/wireless/zd1211rw/zd_chip.c
drivers/net/wireless/zd1211rw/zd_chip.h
drivers/net/wireless/zd1211rw/zd_def.h
drivers/net/wireless/zd1211rw/zd_ieee80211.c
drivers/net/wireless/zd1211rw/zd_ieee80211.h
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.h
drivers/net/wireless/zd1211rw/zd_netdev.c [deleted file]
drivers/net/wireless/zd1211rw/zd_netdev.h [deleted file]
drivers/net/wireless/zd1211rw/zd_rf.c
drivers/net/wireless/zd1211rw/zd_rf.h
drivers/net/wireless/zd1211rw/zd_rf_al2230.c
drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/net/wireless/zd1211rw/zd_usb.h
drivers/net/xen-netfront.c
drivers/parisc/led.c
drivers/s390/net/qeth_main.c
drivers/scsi/qla4xxx/ql4_os.c
drivers/scsi/scsi_netlink.c
drivers/scsi/scsi_transport_iscsi.c
drivers/ssb/b43_pci_bridge.c
drivers/ssb/main.c
drivers/ssb/pci.c
drivers/ssb/pcmcia.c
fs/ecryptfs/netlink.c
fs/proc/proc_net.c
fs/splice.c
include/asm-powerpc/pasemi_dma.h [new file with mode: 0644]
include/linux/Kbuild
include/linux/atmbr2684.h
include/linux/atmdev.h
include/linux/can.h [new file with mode: 0644]
include/linux/can/Kbuild [new file with mode: 0644]
include/linux/can/bcm.h [new file with mode: 0644]
include/linux/can/core.h [new file with mode: 0644]
include/linux/can/error.h [new file with mode: 0644]
include/linux/can/raw.h [new file with mode: 0644]
include/linux/connector.h
include/linux/dccp.h
include/linux/ieee80211.h
include/linux/if.h
include/linux/if_addrlabel.h [new file with mode: 0644]
include/linux/if_arp.h
include/linux/if_ether.h
include/linux/if_frad.h
include/linux/if_shaper.h [deleted file]
include/linux/if_tr.h
include/linux/if_tun.h
include/linux/if_tunnel.h
include/linux/if_vlan.h
include/linux/in.h
include/linux/inetdevice.h
include/linux/net.h
include/linux/netfilter.h
include/linux/netfilter/Kbuild
include/linux/netfilter/nf_conntrack_common.h
include/linux/netfilter/nf_conntrack_h323.h
include/linux/netfilter/nf_conntrack_sctp.h
include/linux/netfilter/nfnetlink_conntrack.h
include/linux/netfilter/nfnetlink_log.h
include/linux/netfilter/x_tables.h
include/linux/netfilter/xt_CONNMARK.h
include/linux/netfilter/xt_DSCP.h
include/linux/netfilter/xt_MARK.h
include/linux/netfilter/xt_RATEEST.h [new file with mode: 0644]
include/linux/netfilter/xt_TCPOPTSTRIP.h [new file with mode: 0644]
include/linux/netfilter/xt_connlimit.h
include/linux/netfilter/xt_connmark.h
include/linux/netfilter/xt_conntrack.h
include/linux/netfilter/xt_dscp.h
include/linux/netfilter/xt_hashlimit.h
include/linux/netfilter/xt_iprange.h [new file with mode: 0644]
include/linux/netfilter/xt_mark.h
include/linux/netfilter/xt_owner.h [new file with mode: 0644]
include/linux/netfilter/xt_policy.h
include/linux/netfilter/xt_quota.h
include/linux/netfilter/xt_rateest.h [new file with mode: 0644]
include/linux/netfilter/xt_statistic.h
include/linux/netfilter/xt_string.h
include/linux/netfilter_arp/arp_tables.h
include/linux/netfilter_ipv4.h
include/linux/netfilter_ipv4/ip_tables.h
include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
include/linux/netfilter_ipv4/ipt_addrtype.h
include/linux/netfilter_ipv4/ipt_iprange.h
include/linux/netfilter_ipv6.h
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/netlink.h
include/linux/netpoll.h
include/linux/nl80211.h
include/linux/pci_ids.h
include/linux/pcounter.h [new file with mode: 0644]
include/linux/pkt_sched.h
include/linux/proc_fs.h
include/linux/rtnetlink.h
include/linux/seq_file.h
include/linux/skbuff.h
include/linux/snmp.h
include/linux/socket.h
include/linux/splice.h
include/linux/ssb/ssb.h
include/linux/ssb/ssb_regs.h
include/linux/sysctl.h
include/linux/tcp.h
include/linux/tty.h
include/linux/wireless.h
include/linux/xfrm.h
include/net/act_api.h
include/net/addrconf.h
include/net/af_unix.h
include/net/arp.h
include/net/bluetooth/rfcomm.h
include/net/cfg80211.h
include/net/checksum.h
include/net/dsfield.h
include/net/dst.h
include/net/fib_rules.h
include/net/flow.h
include/net/gen_stats.h
include/net/ieee80211.h
include/net/inet_ecn.h
include/net/inet_frag.h
include/net/inet_hashtables.h
include/net/inet_timewait_sock.h
include/net/ip.h
include/net/ip6_fib.h
include/net/ip6_route.h
include/net/ip_fib.h
include/net/ip_vs.h
include/net/ipip.h
include/net/ipv6.h
include/net/irda/irda_device.h
include/net/mac80211.h
include/net/neighbour.h
include/net/net_namespace.h
include/net/netevent.h
include/net/netfilter/ipv6/nf_conntrack_ipv6.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_core.h
include/net/netfilter/nf_conntrack_expect.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_conntrack_l3proto.h
include/net/netfilter/nf_conntrack_tuple.h
include/net/netfilter/nf_log.h [new file with mode: 0644]
include/net/netfilter/nf_nat.h
include/net/netfilter/nf_nat_protocol.h
include/net/netfilter/nf_queue.h [new file with mode: 0644]
include/net/netfilter/xt_rateest.h [new file with mode: 0644]
include/net/netlink.h
include/net/netns/ipv4.h [new file with mode: 0644]
include/net/netns/ipv6.h [new file with mode: 0644]
include/net/netns/packet.h [new file with mode: 0644]
include/net/netns/unix.h [new file with mode: 0644]
include/net/pkt_cls.h
include/net/pkt_sched.h
include/net/protocol.h
include/net/raw.h
include/net/rawv6.h
include/net/route.h
include/net/sch_generic.h
include/net/sctp/checksum.h [new file with mode: 0644]
include/net/sctp/constants.h
include/net/sctp/sctp.h
include/net/sctp/structs.h
include/net/snmp.h
include/net/sock.h
include/net/tcp.h
include/net/transp_v6.h
include/net/udp.h
include/net/udplite.h
include/net/xfrm.h
kernel/sysctl.c
kernel/sysctl_check.c
lib/Makefile
lib/pcounter.c [new file with mode: 0644]
net/802/Makefile
net/802/sysctl_net_802.c [deleted file]
net/802/tr.c
net/8021q/vlan.c
net/8021q/vlan.h
net/8021q/vlan_dev.c
net/8021q/vlan_netlink.c
net/8021q/vlanproc.c
net/8021q/vlanproc.h
net/Kconfig
net/Makefile
net/appletalk/aarp.c
net/appletalk/atalk_proc.c
net/appletalk/ddp.c
net/appletalk/sysctl_net_atalk.c
net/atm/Kconfig
net/atm/atm_sysfs.c
net/atm/br2684.c
net/atm/clip.c
net/atm/common.c
net/atm/lec.c
net/atm/proc.c
net/ax25/af_ax25.c
net/ax25/ax25_ds_timer.c
net/ax25/ax25_route.c
net/ax25/ax25_std_timer.c
net/ax25/ax25_uid.c
net/ax25/sysctl_net_ax25.c
net/bluetooth/bnep/sock.c
net/bluetooth/cmtp/sock.c
net/bluetooth/hci_conn.c
net/bluetooth/hidp/core.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/sco.c
net/bridge/br_input.c
net/bridge/br_netfilter.c
net/bridge/br_netlink.c
net/bridge/netfilter/Kconfig
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebt_vlan.c
net/bridge/netfilter/ebtable_filter.c
net/bridge/netfilter/ebtable_nat.c
net/bridge/netfilter/ebtables.c
net/can/Kconfig [new file with mode: 0644]
net/can/Makefile [new file with mode: 0644]
net/can/af_can.c [new file with mode: 0644]
net/can/af_can.h [new file with mode: 0644]
net/can/bcm.c [new file with mode: 0644]
net/can/proc.c [new file with mode: 0644]
net/can/raw.c [new file with mode: 0644]
net/compat.c
net/core/datagram.c
net/core/dev.c
net/core/dev_mcast.c
net/core/dst.c
net/core/fib_rules.c
net/core/flow.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/net_namespace.c
net/core/netpoll.c
net/core/pktgen.c
net/core/request_sock.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/core/stream.c
net/core/sysctl_net_core.c
net/core/utils.c
net/dccp/Kconfig
net/dccp/ackvec.c
net/dccp/ackvec.h
net/dccp/ccid.c
net/dccp/ccid.h
net/dccp/ccids/Kconfig
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid2.h
net/dccp/ccids/ccid3.c
net/dccp/ccids/ccid3.h
net/dccp/ccids/lib/Makefile
net/dccp/ccids/lib/loss_interval.c
net/dccp/ccids/lib/loss_interval.h
net/dccp/ccids/lib/packet_history.c
net/dccp/ccids/lib/packet_history.h
net/dccp/ccids/lib/tfrc.c [new file with mode: 0644]
net/dccp/ccids/lib/tfrc.h
net/dccp/dccp.h
net/dccp/feat.c
net/dccp/feat.h
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/minisocks.c
net/dccp/options.c
net/dccp/output.c
net/dccp/proto.c
net/dccp/sysctl.c
net/dccp/timer.c
net/decnet/af_decnet.c
net/decnet/dn_dev.c
net/decnet/dn_fib.c
net/decnet/dn_neigh.c
net/decnet/dn_nsp_out.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/decnet/dn_table.c
net/decnet/netfilter/Kconfig
net/decnet/netfilter/dn_rtmsg.c
net/decnet/sysctl_net_decnet.c
net/econet/af_econet.c
net/ethernet/eth.c
net/ieee80211/Kconfig
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_module.c
net/ieee80211/ieee80211_rx.c
net/ieee80211/ieee80211_tx.c
net/ieee80211/ieee80211_wx.c
net/ieee80211/softmac/ieee80211softmac_auth.c
net/ieee80211/softmac/ieee80211softmac_io.c
net/ipv4/Kconfig
net/ipv4/Makefile
net/ipv4/af_inet.c
net/ipv4/ah4.c
net/ipv4/arp.c
net/ipv4/cipso_ipv4.c
net/ipv4/datagram.c
net/ipv4/devinet.c
net/ipv4/esp4.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_connection_sock.c
net/ipv4/inet_diag.c
net/ipv4/inet_fragment.c
net/ipv4/inet_hashtables.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/ipcomp.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/ipvs/ip_vs_app.c
net/ipv4/ipvs/ip_vs_conn.c
net/ipv4/ipvs/ip_vs_core.c
net/ipv4/ipvs/ip_vs_ctl.c
net/ipv4/ipvs/ip_vs_est.c
net/ipv4/ipvs/ip_vs_lblc.c
net/ipv4/ipvs/ip_vs_lblcr.c
net/ipv4/ipvs/ip_vs_proto.c
net/ipv4/ipvs/ip_vs_proto_esp.c
net/ipv4/ipvs/ip_vs_sched.c
net/ipv4/ipvs/ip_vs_sync.c
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/netfilter.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arptable_filter.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_NETMAP.c
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_SAME.c [deleted file]
net/ipv4/netfilter/ipt_TOS.c [deleted file]
net/ipv4/netfilter/ipt_TTL.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/ipt_ah.c
net/ipv4/netfilter/ipt_ecn.c
net/ipv4/netfilter/ipt_iprange.c [deleted file]
net/ipv4/netfilter/ipt_owner.c [deleted file]
net/ipv4/netfilter/ipt_recent.c
net/ipv4/netfilter/ipt_tos.c [deleted file]
net/ipv4/netfilter/ipt_ttl.c
net/ipv4/netfilter/iptable_filter.c
net/ipv4/netfilter/iptable_mangle.c
net/ipv4/netfilter/iptable_raw.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/netfilter/nf_nat_pptp.c
net/ipv4/netfilter/nf_nat_proto_gre.c
net/ipv4/netfilter/nf_nat_proto_icmp.c
net/ipv4/netfilter/nf_nat_proto_tcp.c
net/ipv4/netfilter/nf_nat_proto_udp.c
net/ipv4/netfilter/nf_nat_proto_unknown.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_sip.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/proc.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp.c
net/ipv4/tcp_bic.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_cubic.c
net/ipv4/tcp_highspeed.c
net/ipv4/tcp_htcp.c
net/ipv4/tcp_hybla.c
net/ipv4/tcp_illinois.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_lp.c
net/ipv4/tcp_output.c
net/ipv4/tcp_scalable.c
net/ipv4/tcp_timer.c
net/ipv4/tcp_vegas.c
net/ipv4/tcp_veno.c
net/ipv4/tcp_yeah.c
net/ipv4/udp.c
net/ipv4/udplite.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_beet.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_policy.c
net/ipv4/xfrm4_state.c
net/ipv6/Makefile
net/ipv6/addrconf.c
net/ipv6/addrlabel.c [new file with mode: 0644]
net/ipv6/af_inet6.c
net/ipv6/ah6.c
net/ipv6/anycast.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/exthdrs.c
net/ipv6/fib6_rules.c
net/ipv6/icmp.c
net/ipv6/inet6_hashtables.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_flowlabel.c
net/ipv6/ip6_input.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ipcomp6.c
net/ipv6/ipv6_sockglue.c
net/ipv6/mcast.c
net/ipv6/mip6.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/Makefile
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_HL.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_eui64.c
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_hl.c
net/ipv6/netfilter/ip6t_ipv6header.c
net/ipv6/netfilter/ip6t_mh.c
net/ipv6/netfilter/ip6t_owner.c [deleted file]
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/ip6table_filter.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/ip6table_raw.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.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/sysctl_net_ipv6.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/udp_impl.h
net/ipv6/udplite.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_mode_beet.c
net/ipv6/xfrm6_mode_ro.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_policy.c
net/ipv6/xfrm6_state.c
net/ipx/sysctl_net_ipx.c
net/irda/af_irda.c
net/irda/ircomm/ircomm_core.c
net/irda/irda_device.c
net/irda/iriap.c
net/irda/irlap_event.c
net/irda/irlmp.c
net/irda/irlmp_event.c
net/irda/irsysctl.c
net/iucv/af_iucv.c
net/iucv/iucv.c
net/key/af_key.c
net/lapb/lapb_iface.c
net/llc/llc_conn.c
net/llc/llc_station.c
net/llc/sysctl_net_llc.c
net/mac80211/Kconfig
net/mac80211/Makefile
net/mac80211/cfg.c
net/mac80211/debugfs_netdev.c
net/mac80211/ieee80211.c
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_iface.c
net/mac80211/ieee80211_ioctl.c
net/mac80211/ieee80211_led.c
net/mac80211/ieee80211_led.h
net/mac80211/ieee80211_rate.c
net/mac80211/ieee80211_rate.h
net/mac80211/ieee80211_sta.c
net/mac80211/key.c
net/mac80211/rc80211_pid.h [new file with mode: 0644]
net/mac80211/rc80211_pid_algo.c [new file with mode: 0644]
net/mac80211/rc80211_pid_debugfs.c [new file with mode: 0644]
net/mac80211/rc80211_simple.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wep.c
net/mac80211/wme.c
net/mac80211/wpa.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/core.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_expect.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_h323_asn1.c
net/netfilter/nf_conntrack_h323_main.c
net/netfilter/nf_conntrack_l3proto_generic.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_conntrack_proto_generic.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_conntrack_proto_udp.c
net/netfilter/nf_conntrack_proto_udplite.c
net/netfilter/nf_conntrack_sip.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_log.c
net/netfilter/nf_queue.c
net/netfilter/nf_sysctl.c [deleted file]
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_CLASSIFY.c
net/netfilter/xt_CONNMARK.c
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_DSCP.c
net/netfilter/xt_MARK.c
net/netfilter/xt_NFLOG.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_NOTRACK.c
net/netfilter/xt_RATEEST.c [new file with mode: 0644]
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_TCPOPTSTRIP.c [new file with mode: 0644]
net/netfilter/xt_TRACE.c
net/netfilter/xt_comment.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_connmark.c
net/netfilter/xt_conntrack.c
net/netfilter/xt_dccp.c
net/netfilter/xt_dscp.c
net/netfilter/xt_esp.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_helper.c
net/netfilter/xt_iprange.c [new file with mode: 0644]
net/netfilter/xt_length.c
net/netfilter/xt_limit.c
net/netfilter/xt_mac.c
net/netfilter/xt_mark.c
net/netfilter/xt_multiport.c
net/netfilter/xt_owner.c [new file with mode: 0644]
net/netfilter/xt_physdev.c
net/netfilter/xt_pkttype.c
net/netfilter/xt_policy.c
net/netfilter/xt_quota.c
net/netfilter/xt_rateest.c [new file with mode: 0644]
net/netfilter/xt_realm.c
net/netfilter/xt_sctp.c
net/netfilter/xt_state.c
net/netfilter/xt_statistic.c
net/netfilter/xt_string.c
net/netfilter/xt_tcpmss.c
net/netfilter/xt_tcpudp.c
net/netfilter/xt_time.c
net/netfilter/xt_u32.c
net/netlink/af_netlink.c
net/netlink/attr.c
net/netrom/nr_timer.c
net/netrom/sysctl_net_netrom.c
net/packet/af_packet.c
net/rose/af_rose.c
net/rose/rose_in.c
net/rose/rose_route.c
net/rose/sysctl_net_rose.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-connection.c
net/rxrpc/ar-input.c
net/rxrpc/ar-peer.c
net/rxrpc/rxkad.c
net/sched/Kconfig
net/sched/act_api.c
net/sched/act_gact.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_simple.c
net/sched/cls_api.c
net/sched/cls_basic.c
net/sched/cls_fw.c
net/sched/cls_route.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/sched/cls_u32.c
net/sched/em_meta.c
net/sched/em_text.c
net/sched/ematch.c
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_blackhole.c
net/sched/sch_cbq.c
net/sched/sch_dsmark.c
net/sched/sch_fifo.c
net/sched/sch_generic.c
net/sched/sch_gred.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_ingress.c
net/sched/sch_netem.c
net/sched/sch_prio.c
net/sched/sch_red.c
net/sched/sch_sfq.c
net/sched/sch_tbf.c
net/sched/sch_teql.c
net/sctp/Kconfig
net/sctp/Makefile
net/sctp/associola.c
net/sctp/bind_addr.c
net/sctp/crc32c.c [deleted file]
net/sctp/input.c
net/sctp/ipv6.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/socket.c
net/sctp/sysctl.c
net/sctp/transport.c
net/sctp/ulpevent.c
net/sctp/ulpqueue.c
net/socket.c
net/sunrpc/cache.c
net/sunrpc/sched.c
net/sunrpc/xprt.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtsock.c
net/sysctl_net.c
net/tipc/core.h
net/tipc/port.c
net/unix/af_unix.c
net/unix/sysctl_net_unix.c
net/wireless/Kconfig
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/wext.c
net/x25/af_x25.c
net/x25/sysctl_net_x25.c
net/x25/x25_facilities.c
net/x25/x25_forward.c
net/x25/x25_in.c
net/x25/x25_link.c
net/x25/x25_proc.c
net/x25/x25_route.c
net/x25/x25_subr.c
net/x25/x25_timer.c
net/xfrm/Kconfig
net/xfrm/Makefile
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_hash.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_proc.c [new file with mode: 0644]
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
security/selinux/hooks.c

diff --git a/CREDITS b/CREDITS
index ee909f2cc49e54f0799a4739d24c4cb9151ae453..edff310dbe531a6f9c2da88578c605f099e79bfc 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1353,6 +1353,14 @@ S: Gen Stedmanstraat 212
 S: 5623 HZ Eindhoven
 S: The Netherlands
 
+N: Oliver Hartkopp
+E: oliver.hartkopp@volkswagen.de
+W: http://www.volkswagen.de
+D: Controller Area Network (network layer core)
+S: Brieffach 1776
+S: 38436 Wolfsburg
+S: Germany
+
 N: Andrew Haylett
 E: ajh@primag.co.uk
 D: Selection mechanism
@@ -3306,6 +3314,14 @@ S: Universit=E9 de Rennes I
 S: F-35042 Rennes Cedex
 S: France
 
+N: Urs Thuermann
+E: urs.thuermann@volkswagen.de
+W: http://www.volkswagen.de
+D: Controller Area Network (network layer core)
+S: Brieffach 1776
+S: 38436 Wolfsburg
+S: Germany
+
 N: Jon Tombs
 E: jon@gte.esi.us.es
 W: http://www.esi.us.es/~jon
index 25370662cc5d00407056788357829bd940a8dcd3..181bff00516784e3b4bc0c8a7f2b94ed47b76e70 100644 (file)
@@ -249,15 +249,6 @@ Who:  Tejun Heo <htejun@gmail.com>
 
 ---------------------------
 
-What:  iptables SAME target
-When:  1.1. 2008
-Files: net/ipv4/netfilter/ipt_SAME.c, include/linux/netfilter_ipv4/ipt_SAME.h
-Why:   Obsolete for multiple years now, NAT core provides the same behaviour.
-       Unfixable broken wrt. 32/64 bit cleanness.
-Who:   Patrick McHardy <kaber@trash.net>
-
----------------------------
-
 What: The arch/ppc and include/asm-ppc directories
 When: Jun 2008
 Why:  The arch/powerpc tree is the merged architecture for ppc32 and ppc64
@@ -289,15 +280,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What:  shaper network driver
-When:  January 2008
-Files: drivers/net/shaper.c, include/linux/if_shaper.h
-Why:   This driver has been marked obsolete for many years.
-       It was only designed to work on lower speed links and has design
-       flaws that lead to machine crashes. The qdisc infrastructure in
-       2.4 or later kernels, provides richer features and is more robust.
-Who:   Stephen Hemminger <shemminger@linux-foundation.org>
-
 ---------------------------
 
 What:  i2c-i810, i2c-prosavage and i2c-savage4
@@ -306,3 +288,69 @@ Why:       These drivers are superseded by i810fb, intelfb and savagefb.
 Who:   Jean Delvare <khali@linux-fr.org>
 
 ---------------------------
+
+What:  bcm43xx wireless network driver
+When:  2.6.26
+Files: drivers/net/wireless/bcm43xx
+Why:   This driver's functionality has been replaced by the
+       mac80211-based b43 and b43legacy drivers.
+Who:   John W. Linville <linville@tuxdriver.com>
+
+---------------------------
+
+What:  ieee80211 softmac wireless networking component
+When:  2.6.26 (or after removal of bcm43xx and port of zd1211rw to mac80211)
+Files: net/ieee80211/softmac
+Why:   No in-kernel drivers will depend on it any longer.
+Who:   John W. Linville <linville@tuxdriver.com>
+
+---------------------------
+
+What:  rc80211-simple rate control algorithm for mac80211
+When:  2.6.26
+Files: net/mac80211/rc80211-simple.c
+Why:   This algorithm was provided for reference but always exhibited bad
+       responsiveness and performance and has some serious flaws. It has been
+       replaced by rc80211-pid.
+Who:   Stefano Brivio <stefano.brivio@polimi.it>
+
+---------------------------
+
+What (Why):
+       - include/linux/netfilter_ipv4/ipt_TOS.h ipt_tos.h header files
+         (superseded by xt_TOS/xt_tos target & match)
+
+       - "forwarding" header files like ipt_mac.h in
+         include/linux/netfilter_ipv4/ and include/linux/netfilter_ipv6/
+
+       - xt_CONNMARK match revision 0
+         (superseded by xt_CONNMARK match revision 1)
+
+       - xt_MARK target revisions 0 and 1
+         (superseded by xt_MARK match revision 2)
+
+       - xt_connmark match revision 0
+         (superseded by xt_connmark match revision 1)
+
+       - xt_conntrack match revision 0
+         (superseded by xt_conntrack match revision 1)
+
+       - xt_iprange match revision 0,
+         include/linux/netfilter_ipv4/ipt_iprange.h
+         (superseded by xt_iprange match revision 1)
+
+       - xt_mark match revision 0
+         (superseded by xt_mark match revision 1)
+
+When:  January 2009 or Linux 2.7.0, whichever comes first
+Why:   Superseded by newer revisions or modules
+Who:   Jan Engelhardt <jengelh@computergmbh.de>
+
+---------------------------
+
+What:  b43 support for firmware revision < 410
+When:  July 2008
+Why:   The support code for the old firmware hurts code readability/maintainability
+       and slightly hurts runtime performance. Bugfixes for the old firmware
+       are not provided by Broadcom anymore.
+Who:   Michael Buesch <mb@bu3sch.de>
index 563e442f2d4246a37ffd46250fa64fa0e494c645..02e56d447a8fcde92eabdecd955ccd99af99dbcf 100644 (file)
@@ -24,6 +24,8 @@ baycom.txt
        - info on the driver for Baycom style amateur radio modems
 bridge.txt
        - where to get user space programs for ethernet bridging with Linux.
+can.txt
+       - documentation on CAN protocol family.
 cops.txt
        - info on the COPS LocalTalk Linux driver
 cs89x0.txt
@@ -82,8 +84,6 @@ policy-routing.txt
        - IP policy-based routing
 ray_cs.txt
        - Raylink Wireless LAN card driver info.
-shaper.txt
-       - info on the module that can shape/limit transmitted traffic.
 sk98lin.txt
        - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
          Ethernet Adapter family driver info
index 6cc30e0d5795ce8e598190fb32edf1624a58a203..a0cda062bc33b6e1de3dd2bb60d5ff62bdf97cd4 100644 (file)
@@ -1,7 +1,7 @@
 
                Linux Ethernet Bonding Driver HOWTO
 
-               Latest update: 24 April 2006
+               Latest update: 12 November 2007
 
 Initial release : Thomas Davis <tadavis at lbl.gov>
 Corrections, HA extensions : 2000/10/03-15 :
@@ -166,12 +166,17 @@ to use ifenslave.
 2. Bonding Driver Options
 =========================
 
-       Options for the bonding driver are supplied as parameters to
-the bonding module at load time.  They may be given as command line
-arguments to the insmod or modprobe command, but are usually specified
-in either the /etc/modules.conf or /etc/modprobe.conf configuration
-file, or in a distro-specific configuration file (some of which are
-detailed in the next section).
+       Options for the bonding driver are supplied as parameters to the
+bonding module at load time, or are specified via sysfs.
+
+       Module options may be given as command line arguments to the
+insmod or modprobe command, but are usually specified in either the
+/etc/modules.conf or /etc/modprobe.conf configuration file, or in a
+distro-specific configuration file (some of which are detailed in the next
+section).
+
+       Details on bonding support for sysfs is provided in the
+"Configuring Bonding Manually via Sysfs" section, below.
 
        The available bonding driver parameters are listed below. If a
 parameter is not specified the default value is used.  When initially
@@ -812,11 +817,13 @@ the system /etc/modules.conf or /etc/modprobe.conf configuration file.
 3.2 Configuration with Initscripts Support
 ------------------------------------------
 
-       This section applies to distros using a version of initscripts
-with bonding support, for example, Red Hat Linux 9 or Red Hat
-Enterprise Linux version 3 or 4.  On these systems, the network
-initialization scripts have some knowledge of bonding, and can be
-configured to control bonding devices.
+       This section applies to distros using a recent version of
+initscripts with bonding support, for example, Red Hat Enterprise Linux
+version 3 or later, Fedora, etc.  On these systems, the network
+initialization scripts have knowledge of bonding, and can be configured to
+control bonding devices.  Note that older versions of the initscripts
+package have lower levels of support for bonding; this will be noted where
+applicable.
 
        These distros will not automatically load the network adapter
 driver unless the ethX device is configured with an IP address.
@@ -864,11 +871,31 @@ USERCTL=no
        Be sure to change the networking specific lines (IPADDR,
 NETMASK, NETWORK and BROADCAST) to match your network configuration.
 
-       Finally, it is necessary to edit /etc/modules.conf (or
-/etc/modprobe.conf, depending upon your distro) to load the bonding
-module with your desired options when the bond0 interface is brought
-up.  The following lines in /etc/modules.conf (or modprobe.conf) will
-load the bonding module, and select its options:
+       For later versions of initscripts, such as that found with Fedora
+7 and Red Hat Enterprise Linux version 5 (or later), it is possible, and,
+indeed, preferable, to specify the bonding options in the ifcfg-bond0
+file, e.g. a line of the format:
+
+BONDING_OPTS="mode=active-backup arp_interval=60 arp_ip_target=+192.168.1.254"
+
+       will configure the bond with the specified options.  The options
+specified in BONDING_OPTS are identical to the bonding module parameters
+except for the arp_ip_target field.  Each target should be included as a
+separate option and should be preceded by a '+' to indicate it should be
+added to the list of queried targets, e.g.,
+
+       arp_ip_target=+192.168.1.1 arp_ip_target=+192.168.1.2
+
+       is the proper syntax to specify multiple targets.  When specifying
+options via BONDING_OPTS, it is not necessary to edit /etc/modules.conf or
+/etc/modprobe.conf.
+
+       For older versions of initscripts that do not support
+BONDING_OPTS, it is necessary to edit /etc/modules.conf (or
+/etc/modprobe.conf, depending upon your distro) to load the bonding module
+with your desired options when the bond0 interface is brought up.  The
+following lines in /etc/modules.conf (or modprobe.conf) will load the
+bonding module, and select its options:
 
 alias bond0 bonding
 options bond0 mode=balance-alb miimon=100
@@ -883,9 +910,10 @@ up and running.
 3.2.1 Using DHCP with Initscripts
 ---------------------------------
 
-       Recent versions of initscripts (the version supplied with
-Fedora Core 3 and Red Hat Enterprise Linux 4 is reported to work) do
-have support for assigning IP information to bonding devices via DHCP.
+       Recent versions of initscripts (the versions supplied with Fedora
+Core 3 and Red Hat Enterprise Linux 4, or later versions, are reported to
+work) have support for assigning IP information to bonding devices via
+DHCP.
 
        To configure bonding for DHCP, configure it as described
 above, except replace the line "BOOTPROTO=none" with "BOOTPROTO=dhcp"
@@ -895,18 +923,14 @@ is case sensitive.
 3.2.2 Configuring Multiple Bonds with Initscripts
 -------------------------------------------------
 
-       At this writing, the initscripts package does not directly
-support loading the bonding driver multiple times, so the process for
-doing so is the same as described in the "Configuring Multiple Bonds
-Manually" section, below.
-
-       NOTE: It has been observed that some Red Hat supplied kernels
-are apparently unable to rename modules at load time (the "-o bond1"
-part).  Attempts to pass that option to modprobe will produce an
-"Operation not permitted" error.  This has been reported on some
-Fedora Core kernels, and has been seen on RHEL 4 as well.  On kernels
-exhibiting this problem, it will be impossible to configure multiple
-bonds with differing parameters.
+       Initscripts packages that are included with Fedora 7 and Red Hat
+Enterprise Linux 5 support multiple bonding interfaces by simply
+specifying the appropriate BONDING_OPTS= in ifcfg-bondX where X is the
+number of the bond.  This support requires sysfs support in the kernel,
+and a bonding driver of version 3.0.0 or later.  Other configurations may
+not support this method for specifying multiple bonding interfaces; for
+those instances, see the "Configuring Multiple Bonds Manually" section,
+below.
 
 3.3 Configuring Bonding Manually with Ifenslave
 -----------------------------------------------
@@ -977,15 +1001,58 @@ initialization scripts lack support for configuring multiple bonds.
 options, you may wish to use the "max_bonds" module parameter,
 documented above.
 
-       To create multiple bonding devices with differing options, it
-is necessary to use bonding parameters exported by sysfs, documented
-in the section below.
+       To create multiple bonding devices with differing options, it is
+preferrable to use bonding parameters exported by sysfs, documented in the
+section below.
+
+       For versions of bonding without sysfs support, the only means to
+provide multiple instances of bonding with differing options is to load
+the bonding driver multiple times.  Note that current versions of the
+sysconfig network initialization scripts handle this automatically; if
+your distro uses these scripts, no special action is needed.  See the
+section Configuring Bonding Devices, above, if you're not sure about your
+network initialization scripts.
+
+       To load multiple instances of the module, it is necessary to
+specify a different name for each instance (the module loading system
+requires that every loaded module, even multiple instances of the same
+module, have a unique name).  This is accomplished by supplying multiple
+sets of bonding options in /etc/modprobe.conf, for example:
+
+alias bond0 bonding
+options bond0 -o bond0 mode=balance-rr miimon=100
+
+alias bond1 bonding
+options bond1 -o bond1 mode=balance-alb miimon=50
+
+       will load the bonding module two times.  The first instance is
+named "bond0" and creates the bond0 device in balance-rr mode with an
+miimon of 100.  The second instance is named "bond1" and creates the
+bond1 device in balance-alb mode with an miimon of 50.
+
+       In some circumstances (typically with older distributions),
+the above does not work, and the second bonding instance never sees
+its options.  In that case, the second options line can be substituted
+as follows:
+
+install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \
+       mode=balance-alb miimon=50
 
+       This may be repeated any number of times, specifying a new and
+unique name in place of bond1 for each subsequent instance.
+
+       It has been observed that some Red Hat supplied kernels are unable
+to rename modules at load time (the "-o bond1" part).  Attempts to pass
+that option to modprobe will produce an "Operation not permitted" error.
+This has been reported on some Fedora Core kernels, and has been seen on
+RHEL 4 as well.  On kernels exhibiting this problem, it will be impossible
+to configure multiple bonds with differing parameters (as they are older
+kernels, and also lack sysfs support).
 
 3.4 Configuring Bonding Manually via Sysfs
 ------------------------------------------
 
-       Starting with version 3.0, Channel Bonding may be configured
+       Starting with version 3.0.0, Channel Bonding may be configured
 via the sysfs interface.  This interface allows dynamic configuration
 of all bonds in the system without unloading the module.  It also
 allows for adding and removing bonds at runtime.  Ifenslave is no
@@ -1030,9 +1097,6 @@ To enslave interface eth0 to bond bond0:
 To free slave eth0 from bond bond0:
 # echo -eth0 > /sys/class/net/bond0/bonding/slaves
 
-       NOTE: The bond must be up before slaves can be added.  All
-slaves are freed when the interface is brought down.
-
        When an interface is enslaved to a bond, symlinks between the
 two are created in the sysfs filesystem.  In this case, you would get
 /sys/class/net/bond0/slave_eth0 pointing to /sys/class/net/eth0, and
@@ -1622,6 +1686,15 @@ one for each switch in the network).  This will insure that,
 regardless of which switch is active, the ARP monitor has a suitable
 target to query.
 
+       Note, also, that of late many switches now support a functionality
+generally referred to as "trunk failover."  This is a feature of the
+switch that causes the link state of a particular switch port to be set
+down (or up) when the state of another switch port goes down (or up).
+It's purpose is to propogate link failures from logically "exterior" ports
+to the logically "interior" ports that bonding is able to monitor via
+miimon.  Availability and configuration for trunk failover varies by
+switch, but this can be a viable alternative to the ARP monitor when using
+suitable switches.
 
 12. Configuring Bonding for Maximum Throughput
 ==============================================
@@ -1709,7 +1782,7 @@ balance-rr: This mode is the only mode that will permit a single
        interfaces. It is therefore the only mode that will allow a
        single TCP/IP stream to utilize more than one interface's
        worth of throughput.  This comes at a cost, however: the
-       striping often results in peer systems receiving packets out
+       striping generally results in peer systems receiving packets out
        of order, causing TCP/IP's congestion control system to kick
        in, often by retransmitting segments.
 
@@ -1721,22 +1794,20 @@ balance-rr: This mode is the only mode that will permit a single
        interface's worth of throughput, even after adjusting
        tcp_reordering.
 
-       Note that this out of order delivery occurs when both the
-       sending and receiving systems are utilizing a multiple
-       interface bond.  Consider a configuration in which a
-       balance-rr bond feeds into a single higher capacity network
-       channel (e.g., multiple 100Mb/sec ethernets feeding a single
-       gigabit ethernet via an etherchannel capable switch).  In this
-       configuration, traffic sent from the multiple 100Mb devices to
-       a destination connected to the gigabit device will not see
-       packets out of order.  However, traffic sent from the gigabit
-       device to the multiple 100Mb devices may or may not see
-       traffic out of order, depending upon the balance policy of the
-       switch.  Many switches do not support any modes that stripe
-       traffic (instead choosing a port based upon IP or MAC level
-       addresses); for those devices, traffic flowing from the
-       gigabit device to the many 100Mb devices will only utilize one
-       interface.
+       Note that the fraction of packets that will be delivered out of
+       order is highly variable, and is unlikely to be zero.  The level
+       of reordering depends upon a variety of factors, including the
+       networking interfaces, the switch, and the topology of the
+       configuration.  Speaking in general terms, higher speed network
+       cards produce more reordering (due to factors such as packet
+       coalescing), and a "many to many" topology will reorder at a
+       higher rate than a "many slow to one fast" configuration.
+
+       Many switches do not support any modes that stripe traffic
+       (instead choosing a port based upon IP or MAC level addresses);
+       for those devices, traffic for a particular connection flowing
+       through the switch to a balance-rr bond will not utilize greater
+       than one interface's worth of bandwidth.
 
        If you are utilizing protocols other than TCP/IP, UDP for
        example, and your application can tolerate out of order
@@ -1936,6 +2007,10 @@ Failover may be delayed via the downdelay bonding module option.
 13.2 Duplicated Incoming Packets
 --------------------------------
 
+       NOTE: Starting with version 3.0.2, the bonding driver has logic to
+suppress duplicate packets, which should largely eliminate this problem.
+The following description is kept for reference.
+
        It is not uncommon to observe a short burst of duplicated
 traffic when the bonding device is first used, or after it has been
 idle for some period of time.  This is most easily observed by issuing
@@ -2096,6 +2171,9 @@ The new driver was designed to be SMP safe from the start.
 EtherExpress PRO/100 and a 3com 3c905b, for example).  For most modes,
 devices need not be of the same speed.
 
+       Starting with version 3.2.1, bonding also supports Infiniband
+slaves in active-backup mode.
+
 3.  How many bonding devices can I have?
 
        There is no limit.
@@ -2154,11 +2232,15 @@ switches currently available support 802.3ad.
 
 8.  Where does a bonding device get its MAC address from?
 
-       If not explicitly configured (with ifconfig or ip link), the
-MAC address of the bonding device is taken from its first slave
-device.  This MAC address is then passed to all following slaves and
-remains persistent (even if the first slave is removed) until the
-bonding device is brought down or reconfigured.
+       When using slave devices that have fixed MAC addresses, or when
+the fail_over_mac option is enabled, the bonding device's MAC address is
+the MAC address of the active slave.
+
+       For other configurations, if not explicitly configured (with
+ifconfig or ip link), the MAC address of the bonding device is taken from
+its first slave device.  This MAC address is then passed to all following
+slaves and remains persistent (even if the first slave is removed) until
+the bonding device is brought down or reconfigured.
 
        If you wish to change the MAC address, you can set it with
 ifconfig or ip link:
diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
new file mode 100644 (file)
index 0000000..f1b2de1
--- /dev/null
@@ -0,0 +1,629 @@
+============================================================================
+
+can.txt
+
+Readme file for the Controller Area Network Protocol Family (aka Socket CAN)
+
+This file contains
+
+  1 Overview / What is Socket CAN
+
+  2 Motivation / Why using the socket API
+
+  3 Socket CAN concept
+    3.1 receive lists
+    3.2 local loopback of sent frames
+    3.3 network security issues (capabilities)
+    3.4 network problem notifications
+
+  4 How to use Socket CAN
+    4.1 RAW protocol sockets with can_filters (SOCK_RAW)
+      4.1.1 RAW socket option CAN_RAW_FILTER
+      4.1.2 RAW socket option CAN_RAW_ERR_FILTER
+      4.1.3 RAW socket option CAN_RAW_LOOPBACK
+      4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
+    4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
+    4.3 connected transport protocols (SOCK_SEQPACKET)
+    4.4 unconnected transport protocols (SOCK_DGRAM)
+
+  5 Socket CAN core module
+    5.1 can.ko module params
+    5.2 procfs content
+    5.3 writing own CAN protocol modules
+
+  6 CAN network drivers
+    6.1 general settings
+    6.2 local loopback of sent frames
+    6.3 CAN controller hardware filters
+    6.4 currently supported CAN hardware
+    6.5 todo
+
+  7 Credits
+
+============================================================================
+
+1. Overview / What is Socket CAN
+--------------------------------
+
+The socketcan package is an implementation of CAN protocols
+(Controller Area Network) for Linux.  CAN is a networking technology
+which has widespread use in automation, embedded devices, and
+automotive fields.  While there have been other CAN implementations
+for Linux based on character devices, Socket CAN uses the Berkeley
+socket API, the Linux network stack and implements the CAN device
+drivers as network interfaces.  The CAN socket API has been designed
+as similar as possible to the TCP/IP protocols to allow programmers,
+familiar with network programming, to easily learn how to use CAN
+sockets.
+
+2. Motivation / Why using the socket API
+----------------------------------------
+
+There have been CAN implementations for Linux before Socket CAN so the
+question arises, why we have started another project.  Most existing
+implementations come as a device driver for some CAN hardware, they
+are based on character devices and provide comparatively little
+functionality.  Usually, there is only a hardware-specific device
+driver which provides a character device interface to send and
+receive raw CAN frames, directly to/from the controller hardware.
+Queueing of frames and higher-level transport protocols like ISO-TP
+have to be implemented in user space applications.  Also, most
+character-device implementations support only one single process to
+open the device at a time, similar to a serial interface.  Exchanging
+the CAN controller requires employment of another device driver and
+often the need for adaption of large parts of the application to the
+new driver's API.
+
+Socket CAN was designed to overcome all of these limitations.  A new
+protocol family has been implemented which provides a socket interface
+to user space applications and which builds upon the Linux network
+layer, so to use all of the provided queueing functionality.  A device
+driver for CAN controller hardware registers itself with the Linux
+network layer as a network device, so that CAN frames from the
+controller can be passed up to the network layer and on to the CAN
+protocol family module and also vice-versa.  Also, the protocol family
+module provides an API for transport protocol modules to register, so
+that any number of transport protocols can be loaded or unloaded
+dynamically.  In fact, the can core module alone does not provide any
+protocol and cannot be used without loading at least one additional
+protocol module.  Multiple sockets can be opened at the same time,
+on different or the same protocol module and they can listen/send
+frames on different or the same CAN IDs.  Several sockets listening on
+the same interface for frames with the same CAN ID are all passed the
+same received matching CAN frames.  An application wishing to
+communicate using a specific transport protocol, e.g. ISO-TP, just
+selects that protocol when opening the socket, and then can read and
+write application data byte streams, without having to deal with
+CAN-IDs, frames, etc.
+
+Similar functionality visible from user-space could be provided by a
+character device, too, but this would lead to a technically inelegant
+solution for a couple of reasons:
+
+* Intricate usage.  Instead of passing a protocol argument to
+  socket(2) and using bind(2) to select a CAN interface and CAN ID, an
+  application would have to do all these operations using ioctl(2)s.
+
+* Code duplication.  A character device cannot make use of the Linux
+  network queueing code, so all that code would have to be duplicated
+  for CAN networking.
+
+* Abstraction.  In most existing character-device implementations, the
+  hardware-specific device driver for a CAN controller directly
+  provides the character device for the application to work with.
+  This is at least very unusual in Unix systems for both, char and
+  block devices.  For example you don't have a character device for a
+  certain UART of a serial interface, a certain sound chip in your
+  computer, a SCSI or IDE controller providing access to your hard
+  disk or tape streamer device.  Instead, you have abstraction layers
+  which provide a unified character or block device interface to the
+  application on the one hand, and a interface for hardware-specific
+  device drivers on the other hand.  These abstractions are provided
+  by subsystems like the tty layer, the audio subsystem or the SCSI
+  and IDE subsystems for the devices mentioned above.
+
+  The easiest way to implement a CAN device driver is as a character
+  device without such a (complete) abstraction layer, as is done by most
+  existing drivers.  The right way, however, would be to add such a
+  layer with all the functionality like registering for certain CAN
+  IDs, supporting several open file descriptors and (de)multiplexing
+  CAN frames between them, (sophisticated) queueing of CAN frames, and
+  providing an API for device drivers to register with.  However, then
+  it would be no more difficult, or may be even easier, to use the
+  networking framework provided by the Linux kernel, and this is what
+  Socket CAN does.
+
+  The use of the networking framework of the Linux kernel is just the
+  natural and most appropriate way to implement CAN for Linux.
+
+3. Socket CAN concept
+---------------------
+
+  As described in chapter 2 it is the main goal of Socket CAN to
+  provide a socket interface to user space applications which builds
+  upon the Linux network layer. In contrast to the commonly known
+  TCP/IP and ethernet networking, the CAN bus is a broadcast-only(!)
+  medium that has no MAC-layer addressing like ethernet. The CAN-identifier
+  (can_id) is used for arbitration on the CAN-bus. Therefore the CAN-IDs
+  have to be chosen uniquely on the bus. When designing a CAN-ECU
+  network the CAN-IDs are mapped to be sent by a specific ECU.
+  For this reason a CAN-ID can be treated best as a kind of source address.
+
+  3.1 receive lists
+
+  The network transparent access of multiple applications leads to the
+  problem that different applications may be interested in the same
+  CAN-IDs from the same CAN network interface. The Socket CAN core
+  module - which implements the protocol family CAN - provides several
+  high efficient receive lists for this reason. If e.g. a user space
+  application opens a CAN RAW socket, the raw protocol module itself
+  requests the (range of) CAN-IDs from the Socket CAN core that are
+  requested by the user. The subscription and unsubscription of
+  CAN-IDs can be done for specific CAN interfaces or for all(!) known
+  CAN interfaces with the can_rx_(un)register() functions provided to
+  CAN protocol modules by the SocketCAN core (see chapter 5).
+  To optimize the CPU usage at runtime the receive lists are split up
+  into several specific lists per device that match the requested
+  filter complexity for a given use-case.
+
+  3.2 local loopback of sent frames
+
+  As known from other networking concepts the data exchanging
+  applications may run on the same or different nodes without any
+  change (except for the according addressing information):
+
+         ___   ___   ___                   _______   ___
+        | _ | | _ | | _ |                 | _   _ | | _ |
+        ||A|| ||B|| ||C||                 ||A| |B|| ||C||
+        |___| |___| |___|                 |_______| |___|
+          |     |     |                       |       |
+        -----------------(1)- CAN bus -(2)---------------
+
+  To ensure that application A receives the same information in the
+  example (2) as it would receive in example (1) there is need for
+  some kind of local loopback of the sent CAN frames on the appropriate
+  node.
+
+  The Linux network devices (by default) just can handle the
+  transmission and reception of media dependent frames. Due to the
+  arbritration on the CAN bus the transmission of a low prio CAN-ID
+  may be delayed by the reception of a high prio CAN frame. To
+  reflect the correct* traffic on the node the loopback of the sent
+  data has to be performed right after a successful transmission. If
+  the CAN network interface is not capable of performing the loopback for
+  some reason the SocketCAN core can do this task as a fallback solution.
+  See chapter 6.2 for details (recommended).
+
+  The loopback functionality is enabled by default to reflect standard
+  networking behaviour for CAN applications. Due to some requests from
+  the RT-SocketCAN group the loopback optionally may be disabled for each
+  separate socket. See sockopts from the CAN RAW sockets in chapter 4.1.
+
+  * = you really like to have this when you're running analyser tools
+      like 'candump' or 'cansniffer' on the (same) node.
+
+  3.3 network security issues (capabilities)
+
+  The Controller Area Network is a local field bus transmitting only
+  broadcast messages without any routing and security concepts.
+  In the majority of cases the user application has to deal with
+  raw CAN frames. Therefore it might be reasonable NOT to restrict
+  the CAN access only to the user root, as known from other networks.
+  Since the currently implemented CAN_RAW and CAN_BCM sockets can only
+  send and receive frames to/from CAN interfaces it does not affect
+  security of others networks to allow all users to access the CAN.
+  To enable non-root users to access CAN_RAW and CAN_BCM protocol
+  sockets the Kconfig options CAN_RAW_USER and/or CAN_BCM_USER may be
+  selected at kernel compile time.
+
+  3.4 network problem notifications
+
+  The use of the CAN bus may lead to several problems on the physical
+  and media access control layer. Detecting and logging of these lower
+  layer problems is a vital requirement for CAN users to identify
+  hardware issues on the physical transceiver layer as well as
+  arbitration problems and error frames caused by the different
+  ECUs. The occurrence of detected errors are important for diagnosis
+  and have to be logged together with the exact timestamp. For this
+  reason the CAN interface driver can generate so called Error Frames
+  that can optionally be passed to the user application in the same
+  way as other CAN frames. Whenever an error on the physical layer
+  or the MAC layer is detected (e.g. by the CAN controller) the driver
+  creates an appropriate error frame. Error frames can be requested by
+  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.
+
+4. How to use Socket CAN
+------------------------
+
+  Like TCP/IP, you first need to open a socket for communicating over a
+  CAN network. Since Socket CAN implements a new protocol family, you
+  need to pass PF_CAN as the first argument to the socket(2) system
+  call. Currently, there are two CAN protocols to choose from, the raw
+  socket protocol and the broadcast manager (BCM). So to open a socket,
+  you would write
+
+    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+
+  and
+
+    s = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
+
+  respectively.  After the successful creation of the socket, you would
+  normally use the bind(2) system call to bind the socket to a CAN
+  interface (which is different from TCP/IP due to different addressing
+  - see chapter 3). After binding (CAN_RAW) or connecting (CAN_BCM)
+  the socket, you can read(2) and write(2) from/to the socket or use
+  send(2), sendto(2), sendmsg(2) and the recv* counterpart operations
+  on the socket as usual. There are also CAN specific socket options
+  described below.
+
+  The basic CAN frame structure and the sockaddr structure are defined
+  in include/linux/can.h:
+
+    struct can_frame {
+            canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+            __u8    can_dlc; /* data length code: 0 .. 8 */
+            __u8    data[8] __attribute__((aligned(8)));
+    };
+
+  The alignment of the (linear) payload data[] to a 64bit boundary
+  allows the user to define own structs and unions to easily access the
+  CAN payload. There is no given byteorder on the CAN bus by
+  default. A read(2) system call on a CAN_RAW socket transfers a
+  struct can_frame to the user space.
+
+  The sockaddr_can structure has an interface index like the
+  PF_PACKET socket, that also binds to a specific interface:
+
+    struct sockaddr_can {
+            sa_family_t can_family;
+            int         can_ifindex;
+            union {
+                    struct { canid_t rx_id, tx_id; } tp16;
+                    struct { canid_t rx_id, tx_id; } tp20;
+                    struct { canid_t rx_id, tx_id; } mcnet;
+                    struct { canid_t rx_id, tx_id; } isotp;
+            } can_addr;
+    };
+
+  To determine the interface index an appropriate ioctl() has to
+  be used (example for CAN_RAW sockets without error checking):
+
+    int s;
+    struct sockaddr_can addr;
+    struct ifreq ifr;
+
+    s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
+
+    strcpy(ifr.ifr_name, "can0" );
+    ioctl(s, SIOCGIFINDEX, &ifr);
+
+    addr.can_family = AF_CAN;
+    addr.can_ifindex = ifr.ifr_ifindex;
+
+    bind(s, (struct sockaddr *)&addr, sizeof(addr));
+
+    (..)
+
+  To bind a socket to all(!) CAN interfaces the interface index must
+  be 0 (zero). In this case the socket receives CAN frames from every
+  enabled CAN interface. To determine the originating CAN interface
+  the system call recvfrom(2) may be used instead of read(2). To send
+  on a socket that is bound to 'any' interface sendto(2) is needed to
+  specify the outgoing interface.
+
+  Reading CAN frames from a bound CAN_RAW socket (see above) consists
+  of reading a struct can_frame:
+
+    struct can_frame frame;
+
+    nbytes = read(s, &frame, sizeof(struct can_frame));
+
+    if (nbytes < 0) {
+            perror("can raw socket read");
+            return 1;
+    }
+
+    /* paraniod check ... */
+    if (nbytes < sizeof(struct can_frame)) {
+            fprintf(stderr, "read: incomplete CAN frame\n");
+            return 1;
+    }
+
+    /* do something with the received CAN frame */
+
+  Writing CAN frames can be done similarly, with the write(2) system call:
+
+    nbytes = write(s, &frame, sizeof(struct can_frame));
+
+  When the CAN interface is bound to 'any' existing CAN interface
+  (addr.can_ifindex = 0) it is recommended to use recvfrom(2) if the
+  information about the originating CAN interface is needed:
+
+    struct sockaddr_can addr;
+    struct ifreq ifr;
+    socklen_t len = sizeof(addr);
+    struct can_frame frame;
+
+    nbytes = recvfrom(s, &frame, sizeof(struct can_frame),
+                      0, (struct sockaddr*)&addr, &len);
+
+    /* get interface name of the received CAN frame */
+    ifr.ifr_ifindex = addr.can_ifindex;
+    ioctl(s, SIOCGIFNAME, &ifr);
+    printf("Received a CAN frame from interface %s", ifr.ifr_name);
+
+  To write CAN frames on sockets bound to 'any' CAN interface the
+  outgoing interface has to be defined certainly.
+
+    strcpy(ifr.ifr_name, "can0");
+    ioctl(s, SIOCGIFINDEX, &ifr);
+    addr.can_ifindex = ifr.ifr_ifindex;
+    addr.can_family  = AF_CAN;
+
+    nbytes = sendto(s, &frame, sizeof(struct can_frame),
+                    0, (struct sockaddr*)&addr, sizeof(addr));
+
+  4.1 RAW protocol sockets with can_filters (SOCK_RAW)
+
+  Using CAN_RAW sockets is extensively comparable to the commonly
+  known access to CAN character devices. To meet the new possibilities
+  provided by the multi user SocketCAN approach, some reasonable
+  defaults are set at RAW socket binding time:
+
+  - The filters are set to exactly one filter receiving everything
+  - The socket only receives valid data frames (=> no error frames)
+  - The loopback of sent CAN frames is enabled (see chapter 3.2)
+  - The socket does not receive its own sent frames (in loopback mode)
+
+  These default settings may be changed before or after binding the socket.
+  To use the referenced definitions of the socket options for CAN_RAW
+  sockets, include <linux/can/raw.h>.
+
+  4.1.1 RAW socket option CAN_RAW_FILTER
+
+  The reception of CAN frames using CAN_RAW sockets can be controlled
+  by defining 0 .. n filters with the CAN_RAW_FILTER socket option.
+
+  The CAN filter structure is defined in include/linux/can.h:
+
+    struct can_filter {
+            canid_t can_id;
+            canid_t can_mask;
+    };
+
+  A filter matches, when
+
+    <received_can_id> & mask == can_id & mask
+
+  which is analogous to known CAN controllers hardware filter semantics.
+  The filter can be inverted in this semantic, when the CAN_INV_FILTER
+  bit is set in can_id element of the can_filter structure. In
+  contrast to CAN controller hardware filters the user may set 0 .. n
+  receive filters for each open socket separately:
+
+    struct can_filter rfilter[2];
+
+    rfilter[0].can_id   = 0x123;
+    rfilter[0].can_mask = CAN_SFF_MASK;
+    rfilter[1].can_id   = 0x200;
+    rfilter[1].can_mask = 0x700;
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
+
+  To disable the reception of CAN frames on the selected CAN_RAW socket:
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
+
+  To set the filters to zero filters is quite obsolete as not read
+  data causes the raw socket to discard the received CAN frames. But
+  having this 'send only' use-case we may remove the receive list in the
+  Kernel to save a little (really a very little!) CPU usage.
+
+  4.1.2 RAW socket option CAN_RAW_ERR_FILTER
+
+  As described in chapter 3.4 the CAN interface driver can generate so
+  called Error Frames that can optionally be passed to the user
+  application in the same way as other CAN frames. The possible
+  errors are divided into different error classes that may be filtered
+  using the appropriate error mask. To register for every possible
+  error condition CAN_ERR_MASK can be used as value for the error mask.
+  The values for the error mask are defined in linux/can/error.h .
+
+    can_err_mask_t err_mask = ( CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF );
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
+               &err_mask, sizeof(err_mask));
+
+  4.1.3 RAW socket option CAN_RAW_LOOPBACK
+
+  To meet multi user needs the local loopback is enabled by default
+  (see chapter 3.2 for details). But in some embedded use-cases
+  (e.g. when only one application uses the CAN bus) this loopback
+  functionality can be disabled (separately for each socket):
+
+    int loopback = 0; /* 0 = disabled, 1 = enabled (default) */
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));
+
+  4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
+
+  When the local loopback is enabled, all the sent CAN frames are
+  looped back to the open CAN sockets that registered for the CAN
+  frames' CAN-ID on this given interface to meet the multi user
+  needs. The reception of the CAN frames on the same socket that was
+  sending the CAN frame is assumed to be unwanted and therefore
+  disabled by default. This default behaviour may be changed on
+  demand:
+
+    int recv_own_msgs = 1; /* 0 = disabled (default), 1 = enabled */
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS,
+               &recv_own_msgs, sizeof(recv_own_msgs));
+
+  4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
+  4.3 connected transport protocols (SOCK_SEQPACKET)
+  4.4 unconnected transport protocols (SOCK_DGRAM)
+
+
+5. Socket CAN core module
+-------------------------
+
+  The Socket CAN core module implements the protocol family
+  PF_CAN. CAN protocol modules are loaded by the core module at
+  runtime. The core module provides an interface for CAN protocol
+  modules to subscribe needed CAN IDs (see chapter 3.1).
+
+  5.1 can.ko module params
+
+  - stats_timer: To calculate the Socket CAN core statistics
+    (e.g. current/maximum frames per second) this 1 second timer is
+    invoked at can.ko module start time by default. This timer can be
+    disabled by using stattimer=0 on the module comandline.
+
+  - debug: (removed since SocketCAN SVN r546)
+
+  5.2 procfs content
+
+  As described in chapter 3.1 the Socket CAN core uses several filter
+  lists to deliver received CAN frames to CAN protocol modules. These
+  receive lists, their filters and the count of filter matches can be
+  checked in the appropriate receive list. All entries contain the
+  device and a protocol module identifier:
+
+    foo@bar:~$ cat /proc/net/can/rcvlist_all
+
+    receive list 'rx_all':
+      (vcan3: no entry)
+      (vcan2: no entry)
+      (vcan1: no entry)
+      device   can_id   can_mask  function  userdata   matches  ident
+       vcan0     000    00000000  f88e6370  f6c6f400         0  raw
+      (any: no entry)
+
+  In this example an application requests any CAN traffic from vcan0.
+
+    rcvlist_all - list for unfiltered entries (no filter operations)
+    rcvlist_eff - list for single extended frame (EFF) entries
+    rcvlist_err - list for error frames masks
+    rcvlist_fil - list for mask/value filters
+    rcvlist_inv - list for mask/value filters (inverse semantic)
+    rcvlist_sff - list for single standard frame (SFF) entries
+
+  Additional procfs files in /proc/net/can
+
+    stats       - Socket CAN core statistics (rx/tx frames, match ratios, ...)
+    reset_stats - manual statistic reset
+    version     - prints the Socket CAN core version and the ABI version
+
+  5.3 writing own CAN protocol modules
+
+  To implement a new protocol in the protocol family PF_CAN a new
+  protocol has to be defined in include/linux/can.h .
+  The prototypes and definitions to use the Socket CAN core can be
+  accessed by including include/linux/can/core.h .
+  In addition to functions that register the CAN protocol and the
+  CAN device notifier chain there are functions to subscribe CAN
+  frames received by CAN interfaces and to send CAN frames:
+
+    can_rx_register   - subscribe CAN frames from a specific interface
+    can_rx_unregister - unsubscribe CAN frames from a specific interface
+    can_send          - transmit a CAN frame (optional with local loopback)
+
+  For details see the kerneldoc documentation in net/can/af_can.c or
+  the source code of net/can/raw.c or net/can/bcm.c .
+
+6. CAN network drivers
+----------------------
+
+  Writing a CAN network device driver is much easier than writing a
+  CAN character device driver. Similar to other known network device
+  drivers you mainly have to deal with:
+
+  - TX: Put the CAN frame from the socket buffer to the CAN controller.
+  - RX: Put the CAN frame from the CAN controller to the socket buffer.
+
+  See e.g. at Documentation/networking/netdevices.txt . The differences
+  for writing CAN network device driver are described below:
+
+  6.1 general settings
+
+    dev->type  = ARPHRD_CAN; /* the netdevice hardware type */
+    dev->flags = IFF_NOARP;  /* CAN has no arp */
+
+    dev->mtu   = sizeof(struct can_frame);
+
+  The struct can_frame is the payload of each socket buffer in the
+  protocol family PF_CAN.
+
+  6.2 local loopback of sent frames
+
+  As described in chapter 3.2 the CAN network device driver should
+  support a local loopback functionality similar to the local echo
+  e.g. of tty devices. In this case the driver flag IFF_ECHO has to be
+  set to prevent the PF_CAN core from locally echoing sent frames
+  (aka loopback) as fallback solution:
+
+    dev->flags = (IFF_NOARP | IFF_ECHO);
+
+  6.3 CAN controller hardware filters
+
+  To reduce the interrupt load on deep embedded systems some CAN
+  controllers support the filtering of CAN IDs or ranges of CAN IDs.
+  These hardware filter capabilities vary from controller to
+  controller and have to be identified as not feasible in a multi-user
+  networking approach. The use of the very controller specific
+  hardware filters could make sense in a very dedicated use-case, as a
+  filter on driver level would affect all users in the multi-user
+  system. The high efficient filter sets inside the PF_CAN core allow
+  to set different multiple filters for each socket separately.
+  Therefore the use of hardware filters goes to the category 'handmade
+  tuning on deep embedded systems'. The author is running a MPC603e
+  @133MHz with four SJA1000 CAN controllers from 2002 under heavy bus
+  load without any problems ...
+
+  6.4 currently supported CAN hardware (September 2007)
+
+  On the project website http://developer.berlios.de/projects/socketcan
+  there are different drivers available:
+
+    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)
+
+  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
+
+  Please check the Mailing Lists on the berlios OSS project website.
+
+  6.5 todo (September 2007)
+
+  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.
+
+7. Credits
+----------
+
+  Oliver Hartkopp (PF_CAN core, filters, drivers, bcm)
+  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)
+  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)
+  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)
index afb66f9a8aff5aa3f32ea32ea65784ac80d6131e..39131a3c78f8826bb9949ddf25ff50e591904028 100644 (file)
@@ -14,24 +14,35 @@ Introduction
 ============
 
 Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
-based protocol designed to solve issues present in UDP and TCP particularly
-for real time and multimedia traffic.
+oriented protocol designed to solve issues present in UDP and TCP, particularly
+for real-time and multimedia (streaming) traffic.
+It divides into a base protocol (RFC 4340) and plugable congestion control
+modules called CCIDs. Like plugable TCP congestion control, at least one CCID
+needs to be enabled in order for the protocol to function properly. In the Linux
+implementation, this is the TCP-like CCID2 (RFC 4341). Additional CCIDs, such as
+the TCP-friendly CCID3 (RFC 4342), are optional.
+For a brief introduction to CCIDs and suggestions for choosing a CCID to match
+given applications, see section 10 of RFC 4340.
 
 It has a base protocol and pluggable congestion control IDs (CCIDs).
 
-It is at proposed standard RFC status and the homepage for DCCP as a protocol
-is at:
-       http://www.read.cs.ucla.edu/dccp/
+DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol
+is at http://www.ietf.org/html.charters/dccp-charter.html
 
 Missing features
 ================
 
-The DCCP implementation does not currently have all the features that are in
-the RFC.
+The Linux DCCP implementation does not currently support all the features that are
+specified in RFCs 4340...42.
 
 The known bugs are at:
        http://linux-net.osdl.org/index.php/TODO#DCCP
 
+For more up-to-date versions of the DCCP implementation, please consider using
+the experimental DCCP test tree; instructions for checking this out are on:
+http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree
+
+
 Socket options
 ==============
 
@@ -46,6 +57,12 @@ can be set before calling bind().
 DCCP_SOCKOPT_GET_CUR_MPS is read-only and retrieves the current maximum packet
 size (application payload size) in bytes, see RFC 4340, section 14.
 
+DCCP_SOCKOPT_SERVER_TIMEWAIT enables the server (listening socket) to hold
+timewait state when closing the connection (RFC 4340, 8.3). The usual case is
+that the closing server sends a CloseReq, whereupon the client holds timewait
+state. When this boolean socket option is on, the server sends a Close instead
+and will enter TIMEWAIT. This option must be set after accept() returns.
+
 DCCP_SOCKOPT_SEND_CSCOV and DCCP_SOCKOPT_RECV_CSCOV are used for setting the
 partial checksum coverage (RFC 4340, sec. 9.2). The default is that checksums
 always cover the entire packet and that only fully covered application data is
@@ -72,6 +89,8 @@ DCCP_SOCKOPT_CCID_TX_INFO
        Returns a `struct tfrc_tx_info' in optval; the buffer for optval and
        optlen must be set to at least sizeof(struct tfrc_tx_info).
 
+On unidirectional connections it is useful to close the unused half-connection
+via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs.
 
 Sysctl variables
 ================
@@ -123,6 +142,12 @@ sync_ratelimit = 125 ms
        sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit
        of this parameter is milliseconds; a value of 0 disables rate-limiting.
 
+IOCTLS
+======
+FIONREAD
+       Works as in udp(7): returns in the `int' argument pointer the size of
+       the next pending datagram in bytes, or 0 when no datagram is pending.
+
 Notes
 =====
 
index 6f7872ba1def0e0e8af4bc61694e75466239e44a..17a6e46fbd43abfce8ad5558f99200f8389ac650 100644 (file)
@@ -446,6 +446,33 @@ tcp_dma_copybreak - INTEGER
        and CONFIG_NET_DMA is enabled.
        Default: 4096
 
+UDP variables:
+
+udp_mem - vector of 3 INTEGERs: min, pressure, max
+       Number of pages allowed for queueing by all UDP sockets.
+
+       min: Below this number of pages UDP is not bothered about its
+       memory appetite. When amount of memory allocated by UDP exceeds
+       this number, UDP starts to moderate memory usage.
+
+       pressure: This value was introduced to follow format of tcp_mem.
+
+       max: Number of pages allowed for queueing by all UDP sockets.
+
+       Default is calculated at boot time from amount of available memory.
+
+udp_rmem_min - INTEGER
+       Minimal size of receive buffer used by UDP sockets in moderation.
+       Each UDP socket is able to use the size for receiving data, even if
+       total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
+       Default: 4096
+
+udp_wmem_min - INTEGER
+       Minimal size of send buffer used by UDP sockets in moderation.
+       Each UDP socket is able to use the size for sending data, even if
+       total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
+       Default: 4096
+
 CIPSOv4 Variables:
 
 cipso_cache_enable - BOOLEAN
diff --git a/Documentation/networking/shaper.txt b/Documentation/networking/shaper.txt
deleted file mode 100644 (file)
index 6c4ebb6..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-Traffic Shaper For Linux
-
-This is the current BETA release of the traffic shaper for Linux. It works
-within the following limits:
-
-o      Minimum shaping speed is currently about 9600 baud (it can only
-shape down to 1 byte per clock tick)
-
-o      Maximum is about 256K, it will go above this but get a bit blocky.
-
-o      If you ifconfig the master device that a shaper is attached to down
-then your machine will follow.
-
-o      The shaper must be a module.
-
-
-Setup:
-
-       A shaper device is configured using the shapeconfig program.
-Typically you will do something like this
-
-shapecfg attach shaper0 eth1
-shapecfg speed shaper0 64000
-ifconfig shaper0 myhost netmask 255.255.255.240 broadcast 1.2.3.4.255 up
-route add -net some.network netmask a.b.c.d dev shaper0
-
-The shaper should have the same IP address as the device it is attached to
-for normal use.
-
-Gotchas:
-
-       The shaper shapes transmitted traffic. It's rather impossible to
-shape received traffic except at the end (or a router) transmitting it.
-
-       Gated/routed/rwhod/mrouted all see the shaper as an additional device
-and will treat it as such unless patched. Note that for mrouted you can run
-mrouted tunnels via a traffic shaper to control bandwidth usage.
-
-       The shaper is device/route based. This makes it very easy to use
-with any setup BUT less flexible. You may need to use iproute2 to set up
-multiple route tables to get the flexibility.
-
-       There is no "borrowing" or "sharing" scheme. This is a simple
-traffic limiter. We implement Van Jacobson and Sally Floyd's CBQ
-architecture into Linux 2.2. This is the preferred solution. Shaper is
-for simple or back compatible setups.
-
-Alan
index b6409cab075ca53aa3a5f4a6276403e0a0463c89..3870f280280b34e6f81cce2229b896357091f7c6 100644 (file)
 
   This displays UDP-Lite statistics variables, whose meaning is as follows.
 
-   InDatagrams:     Total number of received datagrams.
+   InDatagrams:     The total number of datagrams delivered to users.
 
    NoPorts:         Number of packets received to an unknown port.
                     These cases are counted separately (not as InErrors).
diff --git a/Documentation/networking/xfrm_proc.txt b/Documentation/networking/xfrm_proc.txt
new file mode 100644 (file)
index 0000000..53c1a58
--- /dev/null
@@ -0,0 +1,70 @@
+XFRM proc - /proc/net/xfrm_* files
+==================================
+Masahide NAKAMURA <nakam@linux-ipv6.org>
+
+
+Transformation Statistics
+-------------------------
+xfrm_proc is a statistics shown factor dropped by transformation
+for developer.
+It is a counter designed from current transformation source code
+and defined like linux private MIB.
+
+Inbound statistics
+~~~~~~~~~~~~~~~~~~
+XfrmInError:
+       All errors which is not matched others
+XfrmInBufferError:
+       No buffer is left
+XfrmInHdrError:
+       Header error
+XfrmInNoStates:
+       No state is found
+       i.e. Either inbound SPI, address, or IPsec protocol at SA is wrong
+XfrmInStateProtoError:
+       Transformation protocol specific error
+       e.g. SA key is wrong
+XfrmInStateModeError:
+       Transformation mode specific error
+XfrmInSeqOutOfWindow:
+       Sequence out of window
+XfrmInStateExpired:
+       State is expired
+XfrmInStateMismatch:
+       State has mismatch option
+       e.g. UDP encapsulation type is mismatch
+XfrmInStateInvalid:
+       State is invalid
+XfrmInTmplMismatch:
+       No matching template for states
+       e.g. Inbound SAs are correct but SP rule is wrong
+XfrmInNoPols:
+       No policy is found for states
+       e.g. Inbound SAs are correct but no SP is found
+XfrmInPolBlock:
+       Policy discards
+XfrmInPolError:
+       Policy error
+
+Outbound errors
+~~~~~~~~~~~~~~~
+XfrmOutError:
+       All errors which is not matched others
+XfrmOutBundleGenError:
+       Bundle generation error
+XfrmOutBundleCheckError:
+       Bundle check error
+XfrmOutNoStates:
+       No state is found
+XfrmOutStateProtoError:
+       Transformation protocol specific error
+XfrmOutStateModeError:
+       Transformation mode specific error
+XfrmOutStateExpired:
+       State is expired
+XfrmOutPolBlock:
+       Policy discards
+XfrmOutPolDead:
+       Policy is dead
+XfrmOutPolError:
+       Policy error
index 29371226f682d1967126ac9d866c1661d6caf3ff..ba05e8058689dc0471ddb9fe753290075404774d 100644 (file)
@@ -646,6 +646,17 @@ M: ecashin@coraid.com
 W:     http://www.coraid.com/support/linux
 S:     Supported
 
+ATHEROS ATH5K WIRELESS DRIVER
+P:     Jiri Slaby
+M:     jirislaby@gmail.com
+P:     Nick Kossifidis
+M:     mickflemm@gmail.com
+P:     Luis R. Rodriguez
+M:     mcgrof@gmail.com
+L:     linux-wireless@vger.kernel.org
+L:     ath5k-devel@lists.ath5k.org
+S:     Maintained
+
 ATL1 ETHERNET DRIVER
 P:     Jay Cliburn
 M:     jcliburn@gmail.com
@@ -809,7 +820,7 @@ P:  Stefano Brivio
 M:     stefano.brivio@polimi.it
 L:     linux-wireless@vger.kernel.org
 W:     http://bcm43xx.berlios.de/
-S:     Maintained
+S:     Obsolete
 
 BEFS FILE SYSTEM
 P:     Sergey S. Kostyliov
@@ -982,6 +993,15 @@ M: corbet@lwn.net
 L:     video4linux-list@redhat.com
 S:     Maintained
 
+CAN NETWORK LAYER
+P:     Urs Thuermann
+M:     urs.thuermann@volkswagen.de
+P:     Oliver Hartkopp
+M:     oliver.hartkopp@volkswagen.de
+L:     socketcan-core@lists.berlios.de
+W:     http://developer.berlios.de/projects/socketcan/
+S:     Maintained
+
 CALGARY x86-64 IOMMU
 P:     Muli Ben-Yehuda
 M:     muli@il.ibm.com
@@ -2027,10 +2047,12 @@ W:      http://sourceforge.net/projects/e1000/
 S:     Supported
 
 INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
-P:     Yi Zhu
+P:     Zhu Yi
 M:     yi.zhu@intel.com
 P:     James Ketrenos
 M:     jketreno@linux.intel.com
+P:     Reinette Chatre
+M:     reinette.chatre@intel.com
 L:     linux-wireless@vger.kernel.org
 L:     ipw2100-devel@lists.sourceforge.net
 W:     http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
@@ -2038,10 +2060,12 @@ W:      http://ipw2100.sourceforge.net
 S:     Supported
 
 INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
-P:     Yi Zhu
+P:     Zhu Yi
 M:     yi.zhu@intel.com
 P:     James Ketrenos
 M:     jketreno@linux.intel.com
+P:     Reinette Chatre
+M:     reinette.chatre@intel.com
 L:     linux-wireless@vger.kernel.org
 L:     ipw2100-devel@lists.sourceforge.net
 W:     http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
@@ -2051,6 +2075,8 @@ S:        Supported
 INTEL WIRELESS WIFI LINK (iwlwifi)
 P:     Zhu Yi
 M:     yi.zhu@intel.com
+P:     Reinette Chatre
+M:     reinette.chatre@intel.com
 L:     linux-wireless@vger.kernel.org
 L:     ipw3945-devel@lists.sourceforge.net
 W:     http://intellinuxwireless.org
@@ -2482,6 +2508,16 @@ W:       http://linuxwireless.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
 S:     Maintained
 
+MAC80211 PID RATE CONTROL
+P:     Stefano Brivio
+M:     stefano.brivio@polimi.it
+P:     Mattias Nissler
+M:     mattias.nissler@gmx.de
+L:     linux-wireless@vger.kernel.org
+W:     http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/PID
+T:     git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
+S:     Maintained
+
 MACVLAN DRIVER
 P:     Patrick McHardy
 M:     kaber@trash.net
@@ -3183,6 +3219,12 @@ M:       mporter@kernel.crashing.org
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
+RDC R6040 FAST ETHERNET DRIVER
+P:     Florian Fainelli
+M:     florian.fainelli@telecomint.eu
+L:     netdev@vger.kernel.org
+S:     Maintained
+
 READ-COPY UPDATE (RCU)
 P:     Dipankar Sarma
 M:     dipankar@in.ibm.com
index 08b117e2c54bdade231aa96c29cac4f4ce1bc728..9898febf609a34b8073f288295d1f24446931621 100644 (file)
@@ -497,11 +497,6 @@ simeth_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
-       if ( dev == NULL ) {
-               printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
-               return IRQ_NONE;
-       }
-
        /*
         * very simple loop because we get interrupts only when receiving
         */
index f47fcac7e5812d6270f388bf0f893cbe177b4ca8..e636daa7a80e128c7a80b080f65ac12816ec7818 100644 (file)
@@ -1,4 +1,4 @@
-obj-y  += setup.o pci.o time.o idle.o powersave.o iommu.o
+obj-y  += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o
 obj-$(CONFIG_PPC_PASEMI_MDIO)  += gpio_mdio.o
 obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c
new file mode 100644 (file)
index 0000000..c529d8d
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2006-2007 PA Semi, Inc
+ *
+ * Common functions for DMA access on PA Semi PWRficient
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/of.h>
+
+#include <asm/pasemi_dma.h>
+
+#define MAX_TXCH 64
+#define MAX_RXCH 64
+
+static struct pasdma_status *dma_status;
+
+static void __iomem *iob_regs;
+static void __iomem *mac_regs[6];
+static void __iomem *dma_regs;
+
+static int base_hw_irq;
+
+static int num_txch, num_rxch;
+
+static struct pci_dev *dma_pdev;
+
+/* Bitmaps to handle allocation of channels */
+
+static DECLARE_BITMAP(txch_free, MAX_TXCH);
+static DECLARE_BITMAP(rxch_free, MAX_RXCH);
+
+/* pasemi_read_iob_reg - read IOB register
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_iob_reg(unsigned int reg)
+{
+       return in_le32(iob_regs+reg);
+}
+EXPORT_SYMBOL(pasemi_read_iob_reg);
+
+/* pasemi_write_iob_reg - write IOB register
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_iob_reg(unsigned int reg, unsigned int val)
+{
+       out_le32(iob_regs+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_iob_reg);
+
+/* pasemi_read_mac_reg - read MAC register
+ * @intf: MAC interface
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_mac_reg(int intf, unsigned int reg)
+{
+       return in_le32(mac_regs[intf]+reg);
+}
+EXPORT_SYMBOL(pasemi_read_mac_reg);
+
+/* pasemi_write_mac_reg - write MAC register
+ * @intf: MAC interface
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val)
+{
+       out_le32(mac_regs[intf]+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_mac_reg);
+
+/* pasemi_read_dma_reg - read DMA register
+ * @reg: Register to read (offset into PCI CFG space)
+ */
+unsigned int pasemi_read_dma_reg(unsigned int reg)
+{
+       return in_le32(dma_regs+reg);
+}
+EXPORT_SYMBOL(pasemi_read_dma_reg);
+
+/* pasemi_write_dma_reg - write DMA register
+ * @reg: Register to write to (offset into PCI CFG space)
+ * @val: Value to write
+ */
+void pasemi_write_dma_reg(unsigned int reg, unsigned int val)
+{
+       out_le32(dma_regs+reg, val);
+}
+EXPORT_SYMBOL(pasemi_write_dma_reg);
+
+static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type type)
+{
+       int bit;
+       int start, limit;
+
+       switch (type & (TXCHAN_EVT0|TXCHAN_EVT1)) {
+       case TXCHAN_EVT0:
+               start = 0;
+               limit = 10;
+               break;
+       case TXCHAN_EVT1:
+               start = 10;
+               limit = MAX_TXCH;
+               break;
+       default:
+               start = 0;
+               limit = MAX_TXCH;
+               break;
+       }
+retry:
+       bit = find_next_bit(txch_free, MAX_TXCH, start);
+       if (bit >= limit)
+               return -ENOSPC;
+       if (!test_and_clear_bit(bit, txch_free))
+               goto retry;
+
+       return bit;
+}
+
+static void pasemi_free_tx_chan(int chan)
+{
+       BUG_ON(test_bit(chan, txch_free));
+       set_bit(chan, txch_free);
+}
+
+static int pasemi_alloc_rx_chan(void)
+{
+       int bit;
+retry:
+       bit = find_first_bit(rxch_free, MAX_RXCH);
+       if (bit >= MAX_TXCH)
+               return -ENOSPC;
+       if (!test_and_clear_bit(bit, rxch_free))
+               goto retry;
+
+       return bit;
+}
+
+static void pasemi_free_rx_chan(int chan)
+{
+       BUG_ON(test_bit(chan, rxch_free));
+       set_bit(chan, rxch_free);
+}
+
+/* pasemi_dma_alloc_chan - Allocate a DMA channel
+ * @type: Type of channel to allocate
+ * @total_size: Total size of structure to allocate (to allow for more
+ *             room behind the structure to be used by the client)
+ * @offset: Offset in bytes from start of the total structure to the beginning
+ *         of struct pasemi_dmachan. Needed when struct pasemi_dmachan is
+ *         not the first member of the client structure.
+ *
+ * pasemi_dma_alloc_chan allocates a DMA channel for use by a client. The
+ * type argument specifies whether it's a RX or TX channel, and in the case
+ * of TX channels which group it needs to belong to (if any).
+ *
+ * Returns a pointer to the total structure allocated on success, NULL
+ * on failure.
+ */
+void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
+                           int total_size, int offset)
+{
+       void *buf;
+       struct pasemi_dmachan *chan;
+       int chno;
+
+       BUG_ON(total_size < sizeof(struct pasemi_dmachan));
+
+       buf = kzalloc(total_size, GFP_KERNEL);
+
+       if (!buf)
+               return NULL;
+       chan = buf + offset;
+
+       chan->priv = buf;
+
+       switch (type & (TXCHAN|RXCHAN)) {
+       case RXCHAN:
+               chno = pasemi_alloc_rx_chan();
+               chan->chno = chno;
+               chan->irq = irq_create_mapping(NULL,
+                                              base_hw_irq + num_txch + chno);
+               chan->status = &dma_status->rx_sta[chno];
+               break;
+       case TXCHAN:
+               chno = pasemi_alloc_tx_chan(type);
+               chan->chno = chno;
+               chan->irq = irq_create_mapping(NULL, base_hw_irq + chno);
+               chan->status = &dma_status->tx_sta[chno];
+               break;
+       }
+
+       chan->chan_type = type;
+
+       return chan;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_chan);
+
+/* pasemi_dma_free_chan - Free a previously allocated channel
+ * @chan: Channel to free
+ *
+ * Frees a previously allocated channel. It will also deallocate any
+ * descriptor ring associated with the channel, if allocated.
+ */
+void pasemi_dma_free_chan(struct pasemi_dmachan *chan)
+{
+       if (chan->ring_virt)
+               pasemi_dma_free_ring(chan);
+
+       switch (chan->chan_type & (RXCHAN|TXCHAN)) {
+       case RXCHAN:
+               pasemi_free_rx_chan(chan->chno);
+               break;
+       case TXCHAN:
+               pasemi_free_tx_chan(chan->chno);
+               break;
+       }
+
+       kfree(chan->priv);
+}
+EXPORT_SYMBOL(pasemi_dma_free_chan);
+
+/* pasemi_dma_alloc_ring - Allocate descriptor ring for a channel
+ * @chan: Channel for which to allocate
+ * @ring_size: Ring size in 64-bit (8-byte) words
+ *
+ * Allocate a descriptor ring for a channel. Returns 0 on success, errno
+ * on failure. The passed in struct pasemi_dmachan is updated with the
+ * virtual and DMA addresses of the ring.
+ */
+int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size)
+{
+       BUG_ON(chan->ring_virt);
+
+       chan->ring_size = ring_size;
+
+       chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev,
+                                            ring_size * sizeof(u64),
+                                            &chan->ring_dma, GFP_KERNEL);
+
+       if (!chan->ring_virt)
+               return -ENOMEM;
+
+       memset(chan->ring_virt, 0, ring_size * sizeof(u64));
+
+       return 0;
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_ring);
+
+/* pasemi_dma_free_ring - Free an allocated descriptor ring for a channel
+ * @chan: Channel for which to free the descriptor ring
+ *
+ * Frees a previously allocated descriptor ring for a channel.
+ */
+void pasemi_dma_free_ring(struct pasemi_dmachan *chan)
+{
+       BUG_ON(!chan->ring_virt);
+
+       dma_free_coherent(&dma_pdev->dev, chan->ring_size * sizeof(u64),
+                         chan->ring_virt, chan->ring_dma);
+       chan->ring_virt = NULL;
+       chan->ring_size = 0;
+       chan->ring_dma = 0;
+}
+EXPORT_SYMBOL(pasemi_dma_free_ring);
+
+/* pasemi_dma_start_chan - Start a DMA channel
+ * @chan: Channel to start
+ * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write
+ *
+ * Enables (starts) a DMA channel with optional additional arguments.
+ */
+void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta)
+{
+       if (chan->chan_type == RXCHAN)
+               pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno),
+                                    cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN);
+       else
+               pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno),
+                                    cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN);
+}
+EXPORT_SYMBOL(pasemi_dma_start_chan);
+
+/* pasemi_dma_stop_chan - Stop a DMA channel
+ * @chan: Channel to stop
+ *
+ * Stops (disables) a DMA channel. This is done by setting the ST bit in the
+ * CMDSTA register and waiting on the ACT (active) bit to clear, then
+ * finally disabling the whole channel.
+ *
+ * This function will only try for a short while for the channel to stop, if
+ * it doesn't it will return failure.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+#define MAX_RETRIES 5000
+int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan)
+{
+       int reg, retries;
+       u32 sta;
+
+       if (chan->chan_type == RXCHAN) {
+               reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno);
+               pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST);
+               for (retries = 0; retries < MAX_RETRIES; retries++) {
+                       sta = pasemi_read_dma_reg(reg);
+                       if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
+                               pasemi_write_dma_reg(reg, 0);
+                               return 1;
+                       }
+                       cond_resched();
+               }
+       } else {
+               reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno);
+               pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST);
+               for (retries = 0; retries < MAX_RETRIES; retries++) {
+                       sta = pasemi_read_dma_reg(reg);
+                       if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
+                               pasemi_write_dma_reg(reg, 0);
+                               return 1;
+                       }
+                       cond_resched();
+               }
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(pasemi_dma_stop_chan);
+
+/* pasemi_dma_alloc_buf - Allocate a buffer to use for DMA
+ * @chan: Channel to allocate for
+ * @size: Size of buffer in bytes
+ * @handle: DMA handle
+ *
+ * Allocate a buffer to be used by the DMA engine for read/write,
+ * similar to dma_alloc_coherent().
+ *
+ * Returns the virtual address of the buffer, or NULL in case of failure.
+ */
+void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
+                          dma_addr_t *handle)
+{
+       return dma_alloc_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
+}
+EXPORT_SYMBOL(pasemi_dma_alloc_buf);
+
+/* pasemi_dma_free_buf - Free a buffer used for DMA
+ * @chan: Channel the buffer was allocated for
+ * @size: Size of buffer in bytes
+ * @handle: DMA handle
+ *
+ * Frees a previously allocated buffer.
+ */
+void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
+                        dma_addr_t *handle)
+{
+       dma_free_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
+}
+EXPORT_SYMBOL(pasemi_dma_free_buf);
+
+static void *map_onedev(struct pci_dev *p, int index)
+{
+       struct device_node *dn;
+       void __iomem *ret;
+
+       dn = pci_device_to_OF_node(p);
+       if (!dn)
+               goto fallback;
+
+       ret = of_iomap(dn, index);
+       if (!ret)
+               goto fallback;
+
+       return ret;
+fallback:
+       /* This is hardcoded and ugly, but we have some firmware versions
+        * that don't provide the register space in the device tree. Luckily
+        * they are at well-known locations so we can just do the math here.
+        */
+       return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
+}
+
+/* pasemi_dma_init - Initialize the PA Semi DMA library
+ *
+ * This function initializes the DMA library. It must be called before
+ * any other function in the library.
+ *
+ * Returns 0 on success, errno on failure.
+ */
+int pasemi_dma_init(void)
+{
+       static spinlock_t init_lock = SPIN_LOCK_UNLOCKED;
+       struct pci_dev *iob_pdev;
+       struct pci_dev *pdev;
+       struct resource res;
+       struct device_node *dn;
+       int i, intf, err = 0;
+       u32 tmp;
+
+       if (!machine_is(pasemi))
+               return -ENODEV;
+
+       spin_lock(&init_lock);
+
+       /* Make sure we haven't already initialized */
+       if (dma_pdev)
+               goto out;
+
+       iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+       if (!iob_pdev) {
+               BUG();
+               printk(KERN_WARNING "Can't find I/O Bridge\n");
+               err = -ENODEV;
+               goto out;
+       }
+       iob_regs = map_onedev(iob_pdev, 0);
+
+       dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+       if (!dma_pdev) {
+               BUG();
+               printk(KERN_WARNING "Can't find DMA controller\n");
+               err = -ENODEV;
+               goto out;
+       }
+       dma_regs = map_onedev(dma_pdev, 0);
+       base_hw_irq = virq_to_hw(dma_pdev->irq);
+
+       pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp);
+       num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S;
+
+       pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp);
+       num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S;
+
+       intf = 0;
+       for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL);
+            pdev;
+            pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev))
+               mac_regs[intf++] = map_onedev(pdev, 0);
+
+       pci_dev_put(pdev);
+
+       for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL);
+            pdev;
+            pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev))
+               mac_regs[intf++] = map_onedev(pdev, 0);
+
+       pci_dev_put(pdev);
+
+       dn = pci_device_to_OF_node(iob_pdev);
+       if (dn)
+               err = of_address_to_resource(dn, 1, &res);
+       if (!dn || err) {
+               /* Fallback for old firmware */
+               res.start = 0xfd800000;
+               res.end = res.start + 0x1000;
+       }
+       dma_status = __ioremap(res.start, res.end-res.start, 0);
+       pci_dev_put(iob_pdev);
+
+       for (i = 0; i < MAX_TXCH; i++)
+               __set_bit(i, txch_free);
+
+       for (i = 0; i < MAX_RXCH; i++)
+               __set_bit(i, rxch_free);
+
+       printk(KERN_INFO "PA Semi PWRficient DMA library initialized "
+               "(%d tx, %d rx channels)\n", num_txch, num_rxch);
+
+out:
+       spin_unlock(&init_lock);
+       return err;
+}
+EXPORT_SYMBOL(pasemi_dma_init);
index 516acabb4e96a4151b42e2833e907feb633c6ae2..58b344c6fc388d438f95f78471db26895d0c293a 100644 (file)
@@ -9,6 +9,7 @@ extern void __devinit pas_pci_dma_dev_setup(struct pci_dev *dev);
 extern void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset);
 
 extern void __init alloc_iobmap_l2(void);
+extern void __init pasemi_map_registers(void);
 
 /* Power savings modes, implemented in asm */
 extern void idle_spin(void);
index 615b6583d9b01084831bd8eea5ed00aecf9ab30b..06bb5b77ea6245ed370dac0251fea8ee92d114e9 100644 (file)
@@ -272,7 +272,7 @@ scc_enet_timeout(struct net_device *dev)
  * This is called from the CPM handler, not the MPC core interrupt.
  */
 static irqreturn_t
-scc_enet_interrupt(int irq, void * dev_id)
+scc_enet_interrupt(int irq, void *dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct scc_enet_private *cep;
@@ -280,7 +280,7 @@ scc_enet_interrupt(int irq, void * dev_id)
        ushort  int_events;
        int     must_restart;
 
-       cep = (struct scc_enet_private *)dev->priv;
+       cep = dev->priv;
 
        /* Get the interrupt events that caused us to be here.
        */
index 6f3ed6a72e0be3a2c895485824ff8c8ec842e54f..a3a27dafff1fc73fc3d1ebc777213fc3a9819598 100644 (file)
@@ -524,7 +524,7 @@ fcc_enet_timeout(struct net_device *dev)
 
 /* The interrupt handler. */
 static irqreturn_t
-fcc_enet_interrupt(int irq, void * dev_id)
+fcc_enet_interrupt(int irq, void *dev_id)
 {
        struct  net_device *dev = dev_id;
        volatile struct fcc_enet_private *cep;
@@ -532,7 +532,7 @@ fcc_enet_interrupt(int irq, void * dev_id)
        ushort  int_events;
        int     must_restart;
 
-       cep = (struct fcc_enet_private *)dev->priv;
+       cep = dev->priv;
 
        /* Get the interrupt events that caused us to be here.
        */
index b34b3829f6a9a1fa5a37fe4df0dd607dd3e76c13..7b44a5965155d7965464229c1a24dfc895439435 100644 (file)
@@ -2163,7 +2163,6 @@ static int __devinit amb_init (amb_dev * dev)
 static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev) 
 {
       unsigned char pool;
-      memset (dev, 0, sizeof(amb_dev));
       
       // set up known dev items straight away
       dev->pci_dev = pci_dev; 
@@ -2253,7 +2252,7 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_
                goto out_disable;
        }
 
-       dev = kmalloc (sizeof(amb_dev), GFP_KERNEL);
+       dev = kzalloc(sizeof(amb_dev), GFP_KERNEL);
        if (!dev) {
                PRINTK (KERN_ERR, "out of memory!");
                err = -ENOMEM;
index 3b64a99772ea826187dbc792875332722f77f94b..2e3395b7e8c1cd844488521ebc56e65d504980ad 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $ */
-
 /*
 
   he.c
 #define HPRINTK(fmt,args...)   do { } while (0)
 #endif /* HE_DEBUG */
 
-/* version definition */
-
-static char *version = "$Id: he.c,v 1.18 2003/05/06 22:57:15 chas Exp $";
-
 /* declarations */
 
 static int he_open(struct atm_vcc *vcc);
@@ -366,7 +360,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
        struct he_dev *he_dev = NULL;
        int err = 0;
 
-       printk(KERN_INFO "he: %s\n", version);
+       printk(KERN_INFO "ATM he driver\n");
 
        if (pci_enable_device(pci_dev))
                return -EIO;
@@ -1643,6 +1637,8 @@ he_stop(struct he_dev *he_dev)
 
        if (he_dev->rbpl_base) {
 #ifdef USE_RBPL_POOL
+               int i;
+
                for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
                        void *cpuaddr = he_dev->rbpl_virt[i].virt;
                        dma_addr_t dma_handle = he_dev->rbpl_base[i].phys;
@@ -1665,6 +1661,8 @@ he_stop(struct he_dev *he_dev)
 #ifdef USE_RBPS
        if (he_dev->rbps_base) {
 #ifdef USE_RBPS_POOL
+               int i;
+
                for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
                        void *cpuaddr = he_dev->rbps_virt[i].virt;
                        dma_addr_t dma_handle = he_dev->rbps_base[i].phys;
@@ -2933,7 +2931,7 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
 
        left = *pos;
        if (!left--)
-               return sprintf(page, "%s\n", version);
+               return sprintf(page, "ATM he driver\n");
 
        if (!left--)
                return sprintf(page, "%s%s\n\n",
index 12ceed54ab18001f89b2e587106fa8fa7b20de82..5732ca3259f982be418950077e5735e07eadbde7 100644 (file)
@@ -104,7 +104,6 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id
                return -EINVAL;
        }
 
-       cbq->nls = dev->nls;
        cbq->seq = 0;
        cbq->group = cbq->id.id.idx;
 
@@ -146,7 +145,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
        spin_lock_init(&dev->queue_lock);
 
        dev->nls = nls;
-       dev->netlink_groups = 0;
 
        dev->cn_queue = create_workqueue(dev->name);
        if (!dev->cn_queue) {
index bf9716b75513d957a79e8836d8a127295d86f4d4..fea2d3ed9cbdacd57661f5a1a5227a1bde2ffeb2 100644 (file)
@@ -88,6 +88,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
                        if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
                                found = 1;
                                group = __cbq->group;
+                               break;
                        }
                }
                spin_unlock_bh(&dev->cbdev->queue_lock);
@@ -180,34 +181,15 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
        return err;
 }
 
-/*
- * Skb receive helper - checks skb and msg size and calls callback
- * helper.
- */
-static int __cn_rx_skb(struct sk_buff *skb, struct nlmsghdr *nlh)
-{
-       u32 pid, uid, seq, group;
-       struct cn_msg *msg;
-
-       pid = NETLINK_CREDS(skb)->pid;
-       uid = NETLINK_CREDS(skb)->uid;
-       seq = nlh->nlmsg_seq;
-       group = NETLINK_CB((skb)).dst_group;
-       msg = NLMSG_DATA(nlh);
-
-       return cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
-}
-
 /*
  * Main netlink receiving function.
  *
- * It checks skb and netlink header sizes and calls the skb receive
- * helper with a shared skb.
+ * It checks skb, netlink header and msg sizes, and calls callback helper.
  */
 static void cn_rx_skb(struct sk_buff *__skb)
 {
+       struct cn_msg *msg;
        struct nlmsghdr *nlh;
-       u32 len;
        int err;
        struct sk_buff *skb;
 
@@ -223,11 +205,8 @@ static void cn_rx_skb(struct sk_buff *__skb)
                        return;
                }
 
-               len = NLMSG_ALIGN(nlh->nlmsg_len);
-               if (len > skb->len)
-                       len = skb->len;
-
-               err = __cn_rx_skb(skb, nlh);
+               msg = NLMSG_DATA(nlh);
+               err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
                if (err < 0)
                        kfree_skb(skb);
        }
@@ -441,8 +420,7 @@ static int __devinit cn_init(void)
 
        dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls);
        if (!dev->cbdev) {
-               if (dev->nls->sk_socket)
-                       sock_release(dev->nls->sk_socket);
+               netlink_kernel_release(dev->nls);
                return -EINVAL;
        }
        
@@ -452,8 +430,7 @@ static int __devinit cn_init(void)
        if (err) {
                cn_already_initialized = 0;
                cn_queue_free_dev(dev->cbdev);
-               if (dev->nls->sk_socket)
-                       sock_release(dev->nls->sk_socket);
+               netlink_kernel_release(dev->nls);
                return -EINVAL;
        }
 
@@ -468,8 +445,7 @@ static void __devexit cn_fini(void)
 
        cn_del_callback(&dev->id);
        cn_queue_free_dev(dev->cbdev);
-       if (dev->nls->sk_socket)
-               sock_release(dev->nls->sk_socket);
+       netlink_kernel_release(dev->nls);
 }
 
 subsys_initcall(cn_init);
index 5381c80de10aad692290898003c7ebf543274191..a58ad8a470f98219f9286a12ed8bd9195dbae1bf 100644 (file)
@@ -110,7 +110,7 @@ int rdma_translate_ip(struct sockaddr *addr, struct rdma_dev_addr *dev_addr)
        __be32 ip = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
        int ret;
 
-       dev = ip_dev_find(ip);
+       dev = ip_dev_find(&init_net, ip);
        if (!dev)
                return -EADDRNOTAVAIL;
 
@@ -158,7 +158,7 @@ static void addr_send_arp(struct sockaddr_in *dst_in)
 
        memset(&fl, 0, sizeof fl);
        fl.nl_u.ip4_u.daddr = dst_ip;
-       if (ip_route_output_key(&rt, &fl))
+       if (ip_route_output_key(&init_net, &rt, &fl))
                return;
 
        neigh_event_send(rt->u.dst.neighbour, NULL);
@@ -179,7 +179,7 @@ static int addr_resolve_remote(struct sockaddr_in *src_in,
        memset(&fl, 0, sizeof fl);
        fl.nl_u.ip4_u.daddr = dst_ip;
        fl.nl_u.ip4_u.saddr = src_ip;
-       ret = ip_route_output_key(&rt, &fl);
+       ret = ip_route_output_key(&init_net, &rt, &fl);
        if (ret)
                goto out;
 
@@ -261,15 +261,15 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
        __be32 dst_ip = dst_in->sin_addr.s_addr;
        int ret;
 
-       dev = ip_dev_find(dst_ip);
+       dev = ip_dev_find(&init_net, dst_ip);
        if (!dev)
                return -EADDRNOTAVAIL;
 
-       if (ZERONET(src_ip)) {
+       if (ipv4_is_zeronet(src_ip)) {
                src_in->sin_family = dst_in->sin_family;
                src_in->sin_addr.s_addr = dst_ip;
                ret = rdma_copy_addr(addr, dev, dev->dev_addr);
-       } else if (LOOPBACK(src_ip)) {
+       } else if (ipv4_is_loopback(src_ip)) {
                ret = rdma_translate_ip((struct sockaddr *)dst_in, addr);
                if (!ret)
                        memcpy(addr->dst_dev_addr, dev->dev_addr, MAX_ADDR_LEN);
index 637efead97a0ac67e79c0e3f6019449b474b0cd9..1eff1b2c0e08511d6de424381eb33fc5eb668b00 100644 (file)
@@ -630,7 +630,8 @@ static inline int cma_zero_addr(struct sockaddr *addr)
        struct in6_addr *ip6;
 
        if (addr->sa_family == AF_INET)
-               return ZERONET(((struct sockaddr_in *) addr)->sin_addr.s_addr);
+               return ipv4_is_zeronet(
+                       ((struct sockaddr_in *)addr)->sin_addr.s_addr);
        else {
                ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr;
                return (ip6->s6_addr32[0] | ip6->s6_addr32[1] |
@@ -640,7 +641,7 @@ static inline int cma_zero_addr(struct sockaddr *addr)
 
 static inline int cma_loopback_addr(struct sockaddr *addr)
 {
-       return LOOPBACK(((struct sockaddr_in *) addr)->sin_addr.s_addr);
+       return ipv4_is_loopback(((struct sockaddr_in *) addr)->sin_addr.s_addr);
 }
 
 static inline int cma_any_addr(struct sockaddr *addr)
@@ -1288,7 +1289,7 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id,
        atomic_inc(&conn_id->dev_remove);
        conn_id->state = CMA_CONNECT;
 
-       dev = ip_dev_find(iw_event->local_addr.sin_addr.s_addr);
+       dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
        if (!dev) {
                ret = -EADDRNOTAVAIL;
                cma_enable_remove(conn_id);
index f8cb0fe748c37d61f798076c465b062c3e05e73b..e9a08fa3dffeb99ba718b1a1af343f030915603d 100644 (file)
@@ -332,7 +332,7 @@ static struct rtable *find_route(struct t3cdev *dev, __be32 local_ip,
                          }
        };
 
-       if (ip_route_output_flow(&rt, &fl, NULL, 0))
+       if (ip_route_output_flow(&init_net, &rt, &fl, NULL, 0))
                return NULL;
        return rt;
 }
index be71868d15132d06fe28e062798ae19e0f255f17..7d253686ed0d978b175131d8f11cdcabf816746d 100644 (file)
@@ -17,7 +17,7 @@
        Annapolis MD 21403
 
     Fixed (again!) the missing interrupt locking on TX/RX shifting.
-               Alan Cox <Alan.Cox@linux.org>
+       Alan Cox <Alan.Cox@linux.org>
 
     Removed calls to init_etherdev since they are no longer needed, and
     cleaned up modularization just a bit. The driver still allows only
     the board. Now getting 150K/second FTP with a 3c501 card. Still playing
     with a TX-TX optimisation to see if we can touch 180-200K/second as seems
     theoretically maximum.
-               19950402 Alan Cox <Alan.Cox@linux.org>
+               19950402 Alan Cox <Alan.Cox@linux.org>
 
     Cleaned up for 2.3.x because we broke SMP now.
-               20000208 Alan Cox <alan@redhat.com>
+               20000208 Alan Cox <alan@redhat.com>
 
     Check up pass for 2.5. Nothing significant changed
-               20021009 Alan Cox <alan@redhat.com>
+               20021009 Alan Cox <alan@redhat.com>
 
     Fixed zero fill corner case
-               20030104 Alan Cox <alan@redhat.com>
+               20030104 Alan Cox <alan@redhat.com>
 
 
    For the avoidance of doubt the "preferred form" of this code is one which
@@ -139,8 +139,8 @@ static const char version[] =
  *     The boilerplate probe code.
  */
 
-static int io=0x280;
-static int irq=5;
+static int io = 0x280;
+static int irq = 5;
 static int mem_start;
 
 /**
@@ -229,8 +229,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
         *      Read the station address PROM data from the special port.
         */
 
-       for (i = 0; i < 6; i++)
-       {
+       for (i = 0; i < 6; i++) {
                outw(i, ioaddr + EL1_DATAPTR);
                station_addr[i] = inb(ioaddr + EL1_SAPROM);
        }
@@ -240,28 +239,24 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
         */
 
        if (station_addr[0] == 0x02  &&  station_addr[1] == 0x60
-               && station_addr[2] == 0x8c)
-       {
+                                               && station_addr[2] == 0x8c)
                mname = "3c501";
-       } else if (station_addr[0] == 0x00  &&  station_addr[1] == 0x80
-       && station_addr[2] == 0xC8)
-       {
+       else if (station_addr[0] == 0x00  &&  station_addr[1] == 0x80
+                                               && station_addr[2] == 0xC8)
                mname = "NP943";
-       }
-       else {
+       else {
                release_region(ioaddr, EL1_IO_EXTENT);
                return -ENODEV;
        }
 
        /*
-        *      We auto-IRQ by shutting off the interrupt line and letting it float
-        *      high.
+        *      We auto-IRQ by shutting off the interrupt line and letting it
+        *      float high.
         */
 
        dev->irq = irq;
 
-       if (dev->irq < 2)
-       {
+       if (dev->irq < 2) {
                unsigned long irq_mask;
 
                irq_mask = probe_irq_on();
@@ -274,8 +269,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
                mdelay(20);
                autoirq = probe_irq_off(irq_mask);
 
-               if (autoirq == 0)
-               {
+               if (autoirq == 0) {
                        printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
                                mname, ioaddr);
                        release_region(ioaddr, EL1_IO_EXTENT);
@@ -292,7 +286,8 @@ 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", dev->name, mname, dev->base_addr,
+       printk(KERN_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
@@ -343,7 +338,8 @@ static int el_open(struct net_device *dev)
        if (el_debug > 2)
                printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
 
-       if ((retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev)))
+       retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
+       if (retval)
                return retval;
 
        spin_lock_irqsave(&lp->lock, flags);
@@ -371,8 +367,9 @@ 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",
-                       dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS));
+               printk(KERN_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++;
        outb(TX_NORM, TX_CMD);
        outb(RX_NORM, RX_CMD);
@@ -425,8 +422,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       do
-       {
+       do {
                int len = skb->len;
                int pad = 0;
                int gp_start;
@@ -435,10 +431,10 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (len < ETH_ZLEN)
                        pad = ETH_ZLEN - len;
 
-               gp_start = 0x800 - ( len + pad );
+               gp_start = 0x800 - (len + pad);
 
                lp->tx_pkt_start = gp_start;
-               lp->collisions = 0;
+               lp->collisions = 0;
 
                dev->stats.tx_bytes += skb->len;
 
@@ -455,37 +451,42 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
                lp->txing = 1;
 
                /*
-                *      Turn interrupts back on while we spend a pleasant afternoon
-                *      loading bytes into the board
+                *      Turn interrupts back on while we spend a pleasant
+                *      afternoon loading bytes into the board
                 */
 
                spin_unlock_irqrestore(&lp->lock, flags);
 
-               outw(0x00, RX_BUF_CLR);         /* Set rx packet area to 0. */
-               outw(gp_start, GP_LOW);         /* aim - packet will be loaded into buffer start */
-               outsb(DATAPORT,buf,len);        /* load buffer (usual thing each byte increments the pointer) */
+               /* Set rx packet area to 0. */
+               outw(0x00, RX_BUF_CLR);
+               /* aim - packet will be loaded into buffer start */
+               outw(gp_start, GP_LOW);
+               /* load buffer (usual thing each byte increments the pointer) */
+               outsb(DATAPORT, buf, len);
                if (pad) {
-                       while(pad--)            /* Zero fill buffer tail */
+                       while (pad--)           /* Zero fill buffer tail */
                                outb(0, DATAPORT);
                }
-               outw(gp_start, GP_LOW);         /* the board reuses the same register */
+               /* the board reuses the same register */
+               outw(gp_start, GP_LOW);
 
-               if(lp->loading != 2)
-               {
-                       outb(AX_XMIT, AX_CMD);          /* fire ... Trigger xmit.  */
-                       lp->loading=0;
+               if (lp->loading != 2) {
+                       /* fire ... Trigger xmit.  */
+                       outb(AX_XMIT, AX_CMD);
+                       lp->loading = 0;
                        dev->trans_start = jiffies;
                        if (el_debug > 2)
                                printk(KERN_DEBUG " queued xmit.\n");
-                       dev_kfree_skb (skb);
+                       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);
+               if (el_debug > 2)
+                       printk(KERN_DEBUG "%s: burped during tx load.\n",
+                               dev->name);
                spin_lock_irqsave(&lp->lock, flags);
        }
-       while(1);
+       while (1);
 
 }
 
@@ -534,64 +535,59 @@ 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);
-
-        if(lp->loading==1 && !lp->txing)
-               printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
-                       dev->name);
-
-       if (lp->txing)
-       {
+               printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
+                                                       dev->name, axsr);
 
-               /*
-                *      Board in transmit mode. May be loading. If we are
-                *      loading we shouldn't have got this.
-                */
+       if (lp->loading == 1 && !lp->txing)
+               printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
+                       dev->name);
 
+       if (lp->txing) {
+               /*
+                *      Board in transmit mode. May be loading. If we are
+                *      loading we shouldn't have got this.
+                */
                int txsr = inb(TX_STATUS);
 
-               if(lp->loading==1)
-               {
-                       if(el_debug > 2)
-                       {
-                               printk(KERN_DEBUG "%s: Interrupt while loading [", dev->name);
-                               printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
+               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));
                        }
-                       lp->loading=2;          /* Force a reload */
+                       /* 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", txsr, inw(GP_LOW),inw(RX_LOW));
+                       printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
+                                       txsr, inw(GP_LOW), inw(RX_LOW));
 
-               if ((axsr & 0x80) && (txsr & TX_READY) == 0)
-               {
+               if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
                        /*
-                        *      FIXME: is there a logic to whether to keep on trying or
-                        *      reset immediately ?
+                        *      FIXME: is there a logic to whether to keep
+                        *      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", dev->name, txsr, axsr,
-                       inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
+                       if (el_debug > 1)
+                               printk(KERN_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));
                        lp->txing = 0;
                        netif_wake_queue(dev);
-               }
-               else if (txsr & TX_16COLLISIONS)
-               {
+               } else if (txsr & TX_16COLLISIONS) {
                        /*
                         *      Timed out
                         */
                        if (el_debug)
-                               printk (KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name);
+                               printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
                        outb(AX_SYS, AX_CMD);
                        lp->txing = 0;
                        dev->stats.tx_aborted_errors++;
                        netif_wake_queue(dev);
-               }
-               else if (txsr & TX_COLLISION)
-               {
+               } else if (txsr & TX_COLLISION) {
                        /*
                         *      Retrigger xmit.
                         */
@@ -599,7 +595,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                        if (el_debug > 6)
                                printk(KERN_DEBUG " retransmitting after a collision.\n");
                        /*
-                        *      Poor little chip can't reset its own start pointer
+                        *      Poor little chip can't reset its own start
+                        *      pointer
                         */
 
                        outb(AX_SYS, AX_CMD);
@@ -608,53 +605,45 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                        dev->stats.collisions++;
                        spin_unlock(&lp->lock);
                        goto out;
-               }
-               else
-               {
+               } else {
                        /*
                         *      It worked.. we will now fall through and receive
                         */
                        dev->stats.tx_packets++;
                        if (el_debug > 6)
                                printk(KERN_DEBUG " Tx succeeded %s\n",
-                                       (txsr & TX_RDY) ? "." : "but tx is busy!");
+                                       (txsr & TX_RDY) ? "." : "but tx is busy!");
                        /*
                         *      This is safe the interrupt is atomic WRT itself.
                         */
-
                        lp->txing = 0;
-                       netif_wake_queue(dev);  /* In case more to transmit */
+                       /* In case more to transmit */
+                       netif_wake_queue(dev);
                }
-       }
-       else
-       {
-               /*
-                *      In receive mode.
-                */
+       } else {
+               /*
+                *      In receive mode.
+                */
 
                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));
+                       printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
                /*
                 *      Just reading rx_status fixes most errors.
                 */
                if (rxsr & RX_MISSED)
                        dev->stats.rx_missed_errors++;
-               else if (rxsr & RX_RUNT)
-               {       /* Handled to avoid board lock-up. */
+               else if (rxsr & RX_RUNT) {
+                       /* Handled to avoid board lock-up. */
                        dev->stats.rx_length_errors++;
                        if (el_debug > 5)
                                printk(KERN_DEBUG " runt.\n");
-               }
-               else if (rxsr & RX_GOOD)
-               {
+               } else if (rxsr & RX_GOOD) {
                        /*
                         *      Receive worked.
                         */
                        el_receive(dev);
-               }
-               else
-               {
+               } else {
                        /*
                         *      Nothing?  Something is broken!
                         */
@@ -702,8 +691,7 @@ static void el_receive(struct net_device *dev)
        if (el_debug > 4)
                printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
 
-       if ((pkt_len < 60)  ||  (pkt_len > 1536))
-       {
+       if (pkt_len < 60 || pkt_len > 1536) {
                if (el_debug)
                        printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len);
                dev->stats.rx_over_errors++;
@@ -722,26 +710,23 @@ static void el_receive(struct net_device *dev)
         */
 
        outw(0x00, GP_LOW);
-       if (skb == NULL)
-       {
+       if (skb == NULL) {
                printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name);
                dev->stats.rx_dropped++;
                return;
-       }
-       else
-       {
-               skb_reserve(skb,2);     /* Force 16 byte alignment */
+       } else {
+               skb_reserve(skb, 2);    /* Force 16 byte alignment */
                /*
                 *      The read increments through the bytes. The interrupt
                 *      handler will fix the pointer when it returns to
                 *      receive mode.
                 */
-               insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
-               skb->protocol=eth_type_trans(skb,dev);
+               insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
+               skb->protocol = eth_type_trans(skb, dev);
                netif_rx(skb);
                dev->last_rx = jiffies;
                dev->stats.rx_packets++;
-               dev->stats.rx_bytes+=pkt_len;
+               dev->stats.rx_bytes += pkt_len;
        }
        return;
 }
@@ -760,7 +745,7 @@ static void  el_reset(struct net_device *dev)
        struct net_local *lp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
-       if (el_debug> 2)
+       if (el_debug > 2)
                printk(KERN_INFO "3c501 reset...");
        outb(AX_RESET, AX_CMD);         /* Reset the chip */
        outb(AX_LOOP, AX_CMD);          /* Aux control, irq and loopback enabled */
@@ -794,7 +779,8 @@ 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", dev->name, ioaddr);
+               printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
+                                               dev->name, ioaddr);
 
        netif_stop_queue(dev);
 
@@ -822,18 +808,14 @@ static void set_multicast_list(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
 
-       if(dev->flags&IFF_PROMISC)
-       {
+       if (dev->flags & IFF_PROMISC) {
                outb(RX_PROM, RX_CMD);
                inb(RX_STATUS);
-       }
-       else if (dev->mc_list || dev->flags&IFF_ALLMULTI)
-       {
-               outb(RX_MULT, RX_CMD);  /* Multicast or all multicast is the same */
+       } else if (dev->mc_list || dev->flags & IFF_ALLMULTI) {
+               /* Multicast or all multicast is the same */
+               outb(RX_MULT, RX_CMD);
                inb(RX_STATUS);         /* Clear status. */
-       }
-       else
-       {
+       } else {
                outb(RX_NORM, RX_CMD);
                inb(RX_STATUS);
        }
index 964d31ac9449a2b90e1bc5921e774468d4e23a1c..030c147211baf1184662c7d69373277cd309474c 100644 (file)
@@ -747,7 +747,7 @@ 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,"
+                               printk("%s: i82586 initialization timed out with status %04x, "
                                           "cmd %04x.\n", dev->name,
                                           readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
                                break;
@@ -832,10 +832,11 @@ static void el16_rx(struct net_device *dev)
 
                if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
                        || (pkt_len & 0xC000) != 0xC000) {
-                       printk("%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, next_rx_frame, data_buffer_addr,
-                                  pkt_len);
+                       printk(KERN_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,
+                              next_rx_frame, data_buffer_addr, pkt_len);
                } else if ((frame_status & 0x2000) == 0) {
                        /* Frame Rxed, but with error. */
                        dev->stats.rx_errors++;
@@ -851,7 +852,9 @@ static void el16_rx(struct net_device *dev)
                        pkt_len &= 0x3fff;
                        skb = dev_alloc_skb(pkt_len+2);
                        if (skb == NULL) {
-                               printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+                               printk(KERN_ERR "%s: Memory squeeze, "
+                                      "dropping packet.\n",
+                                      dev->name);
                                dev->stats.rx_dropped++;
                                break;
                        }
index 684bab7810156998f3fd366b27ac1b645d5169e7..6ab84b661d70b34549d954ff9f173e07be06bd41 100644 (file)
@@ -1361,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
                        /* Check if the packet is long enough to just accept without
                           copying to a properly sized skbuff. */
                        if (pkt_len < rx_copybreak
-                           && (skb = dev_alloc_skb(pkt_len + 4)) != 0) {
+                           && (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
                                /* 'skb_put()' points to the start of sk_buff data area. */
                                memcpy(skb_put(skb, pkt_len),
index 224e0bff1ae085ab777e1699e80fbd982bd7601a..750a46f4bc582beb5e8ca0762790127c3e0f09fe 100644 (file)
@@ -277,8 +277,6 @@ static int lance_rx (struct net_device *dev)
         volatile struct lance_init_block *ib = lp->init_block;
         volatile struct lance_rx_desc *rd;
         unsigned char bits;
-        int len = 0;                    /* XXX shut up gcc warnings */
-        struct sk_buff *skb = 0;        /* XXX shut up gcc warnings */
 #ifdef TEST_HITS
         int i;
 #endif
@@ -318,10 +316,10 @@ static int lance_rx (struct net_device *dev)
                         if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
                         if (bits & LE_R1_EOP) dev->stats.rx_errors++;
                 } else {
-                        len = (rd->mblength & 0xfff) - 4;
-                        skb = dev_alloc_skb (len+2);
+                       int len = (rd->mblength & 0xfff) - 4;
+                       struct sk_buff *skb = dev_alloc_skb (len+2);
 
-                        if (skb == 0) {
+                        if (!skb) {
                                 printk ("%s: Memory squeeze, deferring packet.\n",
                                         dev->name);
                                 dev->stats.rx_dropped++;
index a6728661c4167ffa065503e2bebcd594b6748b2e..af40ff434def6cddb55b30711d2627cef3d6affe 100644 (file)
@@ -912,6 +912,24 @@ config DM9000
          To compile this driver as a module, choose M here.  The module
          will be called dm9000.
 
+config ENC28J60
+       tristate "ENC28J60 support"
+       depends on EXPERIMENTAL && SPI && NET_ETHERNET
+       select CRC32
+       ---help---
+         Support for the Microchip EN28J60 ethernet chip.
+
+         To compile this driver as a module, choose M here and read
+         <file:Documentation/networking/net-modules.txt>.  The module will be
+         called enc28j60.
+
+config ENC28J60_WRITEVERIFY
+       bool "Enable write verify"
+       depends on ENC28J60
+       ---help---
+         Enable the verify after the buffer write useful for debugging purpose.
+         If unsure, say N.
+
 config SMC911X
        tristate "SMSC LAN911[5678] support"
        select CRC32
@@ -1584,6 +1602,18 @@ config 8139_OLD_RX_RESET
          experience problems, you can enable this option to restore the
          old RX-reset behavior.  If unsure, say N.
 
+config R6040
+       tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)"
+       depends on NET_PCI && PCI
+       select CRC32
+       select MII
+       help
+         This is a driver for the R6040 Fast Ethernet MACs found in the
+         the RDC R-321x System-on-chips.
+
+         To compile this driver as a module, choose M here: the module
+         will be called r6040. This is recommended.
+
 config SIS900
        tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
        depends on NET_PCI && PCI
@@ -1785,7 +1815,7 @@ config DE620
 
 config SGISEEQ
        tristate "SGI Seeq ethernet controller support"
-       depends on SGI_IP22
+       depends on SGI_HAS_SEEQ
        help
          Say Y here if you have an Seeq based Ethernet network card. This is
          used in many Silicon Graphics machines.
@@ -1989,6 +2019,28 @@ config IP1000
          To compile this driver as a module, choose M here: the module
          will be called ipg.  This is recommended.
 
+config IGB
+       tristate "Intel(R) 82575 PCI-Express Gigabit Ethernet support"
+       depends on PCI
+       ---help---
+         This driver supports Intel(R) 82575 gigabit ethernet family of
+         adapters.  For more information on how to identify your adapter, go
+         to the Adapter & Driver ID Guide at:
+
+         <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+         For general information and support, go to the Intel support
+         website at:
+
+         <http://support.intel.com>
+
+         More specific information on configuring the driver is in
+         <file:Documentation/networking/e1000.txt>.
+
+         To compile this driver as a module, choose M here and read
+         <file:Documentation/networking/net-modules.txt>.  The module
+         will be called igb.
+
 source "drivers/net/ixp2000/Kconfig"
 
 config MYRI_SBUS
@@ -2560,6 +2612,7 @@ config PASEMI_MAC
        tristate "PA Semi 1/10Gbit MAC"
        depends on PPC64 && PCI
        select PHYLIB
+       select INET_LRO
        help
          This driver supports the on-chip 1/10Gbit Ethernet controller on
          PA Semi's PWRficient line of chips.
@@ -2585,6 +2638,16 @@ config TEHUTI
        help
          Tehuti Networks 10G Ethernet NIC
 
+config BNX2X
+       tristate "Broadcom NetXtremeII 10Gb support"
+       depends on PCI
+       select ZLIB_INFLATE
+       help
+         This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
+         To compile this driver as a module, choose M here: the module
+         will be called bnx2x.  This is recommended.
+
+
 endif # NETDEV_10000
 
 source "drivers/net/tokenring/Kconfig"
@@ -3015,23 +3078,6 @@ config NET_FC
          adaptor below. You also should have said Y to "SCSI support" and
          "SCSI generic support".
 
-config SHAPER
-       tristate "Traffic Shaper (OBSOLETE)"
-       depends on EXPERIMENTAL
-       ---help---
-         The traffic shaper is a virtual network device that allows you to
-         limit the rate of outgoing data flow over some other network device.
-         The traffic that you want to slow down can then be routed through
-         these virtual devices. See
-         <file:Documentation/networking/shaper.txt> for more information.
-
-         An alternative to this traffic shaper are traffic schedulers which
-         you'll get if you say Y to "QoS and/or fair queuing" in
-         "Networking options".
-
-         To compile this driver as a module, choose M here: the module
-         will be called shaper.  If unsure, say N.
-
 config NETCONSOLE
        tristate "Network console logging support (EXPERIMENTAL)"
        depends on EXPERIMENTAL
index 0e5fde4a1b2cea165d7e3691429bb00425717766..9fc7794e88ea779eefd212c5c18f219fd85ffbe0 100644 (file)
@@ -6,12 +6,14 @@ obj-$(CONFIG_E1000) += e1000/
 obj-$(CONFIG_E1000E) += e1000e/
 obj-$(CONFIG_IBM_EMAC) += ibm_emac/
 obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
+obj-$(CONFIG_IGB) += igb/
 obj-$(CONFIG_IXGBE) += ixgbe/
 obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_IP1000) += ipg.o
 obj-$(CONFIG_CHELSIO_T1) += chelsio/
 obj-$(CONFIG_CHELSIO_T3) += cxgb3/
 obj-$(CONFIG_EHEA) += ehea/
+obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_ATL1) += atl1/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
@@ -54,6 +56,7 @@ obj-$(CONFIG_TLAN) += tlan.o
 obj-$(CONFIG_EPIC100) += epic100.o
 obj-$(CONFIG_SIS190) += sis190.o
 obj-$(CONFIG_SIS900) += sis900.o
+obj-$(CONFIG_R6040) += r6040.o
 obj-$(CONFIG_YELLOWFIN) += yellowfin.o
 obj-$(CONFIG_ACENIC) += acenic.o
 obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o
@@ -63,6 +66,7 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
+obj-$(CONFIG_BNX2X) += bnx2x.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
 obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
@@ -92,7 +96,6 @@ obj-$(CONFIG_NET_SB1000) += sb1000.o
 obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
-obj-$(CONFIG_SHAPER) += shaper.o
 obj-$(CONFIG_HP100) += hp100.o
 obj-$(CONFIG_SMC9194) += smc9194.o
 obj-$(CONFIG_FEC) += fec.o
@@ -216,6 +219,7 @@ obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
 obj-$(CONFIG_MLX4_CORE) += mlx4/
+obj-$(CONFIG_ENC28J60) += enc28j60.o
 
 obj-$(CONFIG_MACB) += macb.o
 
index 18f7f815f66e2166cf4d12af0927cc85a7ec6cd3..6c5719ae8ccaac3fdaac37fe06fc0aa630c83c89 100644 (file)
@@ -269,8 +269,6 @@ static int lance_rx (struct net_device *dev)
        volatile struct lance_regs *ll = lp->ll;
        volatile struct lance_rx_desc *rd;
        unsigned char bits;
-       int len = 0;                    /* XXX shut up gcc warnings */
-       struct sk_buff *skb = 0;        /* XXX shut up gcc warnings */
 
 #ifdef TEST_HITS
        int i;
@@ -306,10 +304,10 @@ static int lance_rx (struct net_device *dev)
                        if (bits & LE_R1_FRA) dev->stats.rx_frame_errors++;
                        if (bits & LE_R1_EOP) dev->stats.rx_errors++;
                } else {
-                       len = (rd->mblength & 0xfff) - 4;
-                       skb = dev_alloc_skb (len+2);
+                       int len = (rd->mblength & 0xfff) - 4;
+                       struct sk_buff *skb = dev_alloc_skb (len+2);
 
-                       if (skb == 0) {
+                       if (!skb) {
                                printk(KERN_WARNING "%s: Memory squeeze, "
                                       "deferring packet.\n", dev->name);
                                dev->stats.rx_dropped++;
@@ -477,7 +475,7 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-struct net_device *last_dev = 0;
+struct net_device *last_dev;
 
 static int lance_open (struct net_device *dev)
 {
index e7fdd81919bd15edd65e6b2e749b8bf827c94b14..85f7276aaba592b4490c3f5c526b938e8cd0045a 100644 (file)
@@ -1945,13 +1945,13 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 
        err = pci_enable_device(pdev);
        if(err){
-               printk(KERN_ERR "amd8111e: Cannot enable new PCI device,"
+               printk(KERN_ERR "amd8111e: Cannot enable new PCI device, "
                        "exiting.\n");
                return err;
        }
 
        if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)){
-               printk(KERN_ERR "amd8111e: Cannot find PCI base address"
+               printk(KERN_ERR "amd8111e: Cannot find PCI base address"
                       "exiting.\n");
                err = -ENODEV;
                goto err_disable_pdev;
index b032c1bf492fc06e03b067a0fe23ae2c24c36bfd..24d81f922533cd778f46ba1e6de93900a223f4ee 100644 (file)
@@ -465,8 +465,9 @@ found:
        /* Snarf the interrupt vector now. */
        ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev);
        if (ret) {
-               printk ("  AT1700 at %#3x is unusable due to a conflict on"
-                               "IRQ %d.\n", ioaddr, irq);
+               printk(KERN_ERR "AT1700 at %#3x is unusable due to a "
+                      "conflict on IRQ %d.\n",
+                      ioaddr, irq);
                goto err_mca;
        }
 
index 3d247f3f4a3c375d285e10caf025fa6fc16f6d3b..ea2a2b548e3c85f380fef916827df61ce45329e9 100644 (file)
@@ -128,6 +128,8 @@ static void b44_init_rings(struct b44 *);
 #define B44_FULL_RESET         1
 #define B44_FULL_RESET_SKIP_PHY        2
 #define B44_PARTIAL_RESET      3
+#define B44_CHIP_RESET_FULL    4
+#define B44_CHIP_RESET_PARTIAL 5
 
 static void b44_init_hw(struct b44 *, int);
 
@@ -1259,7 +1261,7 @@ static void b44_clear_stats(struct b44 *bp)
 }
 
 /* bp->lock is held. */
-static void b44_chip_reset(struct b44 *bp)
+static void b44_chip_reset(struct b44 *bp, int reset_kind)
 {
        struct ssb_device *sdev = bp->sdev;
 
@@ -1281,6 +1283,13 @@ static void b44_chip_reset(struct b44 *bp)
        ssb_device_enable(bp->sdev, 0);
        b44_clear_stats(bp);
 
+       /*
+        * Don't enable PHY if we are doing a partial reset
+        * we are probably going to power down
+        */
+       if (reset_kind == B44_CHIP_RESET_PARTIAL)
+               return;
+
        switch (sdev->bus->bustype) {
        case SSB_BUSTYPE_SSB:
                bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
@@ -1316,7 +1325,14 @@ static void b44_chip_reset(struct b44 *bp)
 static void b44_halt(struct b44 *bp)
 {
        b44_disable_ints(bp);
-       b44_chip_reset(bp);
+       /* reset PHY */
+       b44_phy_reset(bp);
+       /* power down PHY */
+       printk(KERN_INFO PFX "%s: powering down PHY\n", bp->dev->name);
+       bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN);
+       /* now reset the chip, but without enabling the MAC&PHY
+        * part of it. This has to be done _after_ we shut down the PHY */
+       b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
 }
 
 /* bp->lock is held. */
@@ -1365,7 +1381,7 @@ static void b44_init_hw(struct b44 *bp, int reset_kind)
 {
        u32 val;
 
-       b44_chip_reset(bp);
+       b44_chip_reset(bp, B44_CHIP_RESET_FULL);
        if (reset_kind == B44_FULL_RESET) {
                b44_phy_reset(bp);
                b44_setup_phy(bp);
@@ -1422,7 +1438,7 @@ static int b44_open(struct net_device *dev)
        err = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev);
        if (unlikely(err < 0)) {
                napi_disable(&bp->napi);
-               b44_chip_reset(bp);
+               b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL);
                b44_free_rings(bp);
                b44_free_consistent(bp);
                goto out;
@@ -2060,11 +2076,11 @@ static int __devinit b44_get_invariants(struct b44 *bp)
 
        if (sdev->bus->bustype == SSB_BUSTYPE_SSB &&
            instance > 1) {
-               addr = sdev->bus->sprom.r1.et1mac;
-               bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr;
+               addr = sdev->bus->sprom.et1mac;
+               bp->phy_addr = sdev->bus->sprom.et1phyaddr;
        } else {
-               addr = sdev->bus->sprom.r1.et0mac;
-               bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr;
+               addr = sdev->bus->sprom.et0mac;
+               bp->phy_addr = sdev->bus->sprom.et0phyaddr;
        }
        memcpy(bp->dev->dev_addr, addr, 6);
 
@@ -2188,7 +2204,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
        /* Chip reset provides power to the b44 MAC & PCI cores, which
         * is necessary for MAC register access.
         */
-       b44_chip_reset(bp);
+       b44_chip_reset(bp, B44_CHIP_RESET_FULL);
 
        printk(KERN_INFO "%s: Broadcom 44xx/47xx 10/100BaseT Ethernet %s\n",
               dev->name, print_mac(mac, dev->dev_addr));
@@ -2212,6 +2228,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
        unregister_netdev(dev);
        ssb_bus_may_powerdown(sdev->bus);
        free_netdev(dev);
+       ssb_pcihost_set_power_state(sdev, PCI_D3hot);
        ssb_set_drvdata(sdev, NULL);
 }
 
@@ -2240,6 +2257,7 @@ static int b44_suspend(struct ssb_device *sdev, pm_message_t state)
                b44_setup_wol(bp);
        }
 
+       ssb_pcihost_set_power_state(sdev, PCI_D3hot);
        return 0;
 }
 
index 4e7b46e44874ea94f33015a9c058fc2969e95dd9..34aebc6e75896011fae724cf0d44b8b19868c31c 100644 (file)
@@ -1,6 +1,6 @@
 /* bnx2.c: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004-2007 Broadcom Corporation
+ * Copyright (c) 2004-2008 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
 #include "bnx2_fw.h"
 #include "bnx2_fw2.h"
 
-#define FW_BUF_SIZE            0x8000
+#define FW_BUF_SIZE            0x10000
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.6.9"
-#define DRV_MODULE_RELDATE     "December 8, 2007"
+#define DRV_MODULE_VERSION     "1.7.2"
+#define DRV_MODULE_RELDATE     "January 21, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -226,7 +226,7 @@ static struct flash_spec flash_5709 = {
 
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
 
-static inline u32 bnx2_tx_avail(struct bnx2 *bp)
+static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_napi *bnapi)
 {
        u32 diff;
 
@@ -235,7 +235,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp)
        /* The ring uses 256 indices for 255 entries, one of them
         * needs to be skipped.
         */
-       diff = bp->tx_prod - bp->tx_cons;
+       diff = bp->tx_prod - bnapi->tx_cons;
        if (unlikely(diff >= TX_DESC_CNT)) {
                diff &= 0xffff;
                if (diff == TX_DESC_CNT)
@@ -296,7 +296,7 @@ bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
        u32 val1;
        int i, ret;
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -334,7 +334,7 @@ bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val)
                ret = 0;
        }
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -353,7 +353,7 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
        u32 val1;
        int i, ret;
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -383,7 +383,7 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
        else
                ret = 0;
 
-       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING) {
                val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE);
                val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL;
 
@@ -399,30 +399,65 @@ bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val)
 static void
 bnx2_disable_int(struct bnx2 *bp)
 {
-       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
-              BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+       int i;
+       struct bnx2_napi *bnapi;
+
+       for (i = 0; i < bp->irq_nvecs; i++) {
+               bnapi = &bp->bnx2_napi[i];
+               REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+                      BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
+       }
        REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD);
 }
 
 static void
 bnx2_enable_int(struct bnx2 *bp)
 {
-       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
-              BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
-              BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx);
+       int i;
+       struct bnx2_napi *bnapi;
 
-       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
-              BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx);
+       for (i = 0; i < bp->irq_nvecs; i++) {
+               bnapi = &bp->bnx2_napi[i];
+
+               REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+                      BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+                      BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
+                      bnapi->last_status_idx);
 
+               REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+                      BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+                      bnapi->last_status_idx);
+       }
        REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW);
 }
 
 static void
 bnx2_disable_int_sync(struct bnx2 *bp)
 {
+       int i;
+
        atomic_inc(&bp->intr_sem);
        bnx2_disable_int(bp);
-       synchronize_irq(bp->pdev->irq);
+       for (i = 0; i < bp->irq_nvecs; i++)
+               synchronize_irq(bp->irq_tbl[i].vector);
+}
+
+static void
+bnx2_napi_disable(struct bnx2 *bp)
+{
+       int i;
+
+       for (i = 0; i < bp->irq_nvecs; i++)
+               napi_disable(&bp->bnx2_napi[i].napi);
+}
+
+static void
+bnx2_napi_enable(struct bnx2 *bp)
+{
+       int i;
+
+       for (i = 0; i < bp->irq_nvecs; i++)
+               napi_enable(&bp->bnx2_napi[i].napi);
 }
 
 static void
@@ -430,7 +465,7 @@ bnx2_netif_stop(struct bnx2 *bp)
 {
        bnx2_disable_int_sync(bp);
        if (netif_running(bp->dev)) {
-               napi_disable(&bp->napi);
+               bnx2_napi_disable(bp);
                netif_tx_disable(bp->dev);
                bp->dev->trans_start = jiffies; /* prevent tx timeout */
        }
@@ -442,7 +477,7 @@ bnx2_netif_start(struct bnx2 *bp)
        if (atomic_dec_and_test(&bp->intr_sem)) {
                if (netif_running(bp->dev)) {
                        netif_wake_queue(bp->dev);
-                       napi_enable(&bp->napi);
+                       bnx2_napi_enable(bp);
                        bnx2_enable_int(bp);
                }
        }
@@ -468,8 +503,7 @@ bnx2_free_mem(struct bnx2 *bp)
                bp->stats_blk = NULL;
        }
        if (bp->tx_desc_ring) {
-               pci_free_consistent(bp->pdev,
-                                   sizeof(struct tx_bd) * TX_DESC_CNT,
+               pci_free_consistent(bp->pdev, TXBD_RING_SIZE,
                                    bp->tx_desc_ring, bp->tx_desc_mapping);
                bp->tx_desc_ring = NULL;
        }
@@ -477,14 +511,23 @@ bnx2_free_mem(struct bnx2 *bp)
        bp->tx_buf_ring = NULL;
        for (i = 0; i < bp->rx_max_ring; i++) {
                if (bp->rx_desc_ring[i])
-                       pci_free_consistent(bp->pdev,
-                                           sizeof(struct rx_bd) * RX_DESC_CNT,
+                       pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
                                            bp->rx_desc_ring[i],
                                            bp->rx_desc_mapping[i]);
                bp->rx_desc_ring[i] = NULL;
        }
        vfree(bp->rx_buf_ring);
        bp->rx_buf_ring = NULL;
+       for (i = 0; i < bp->rx_max_pg_ring; i++) {
+               if (bp->rx_pg_desc_ring[i])
+                       pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
+                                           bp->rx_pg_desc_ring[i],
+                                           bp->rx_pg_desc_mapping[i]);
+               bp->rx_pg_desc_ring[i] = NULL;
+       }
+       if (bp->rx_pg_ring)
+               vfree(bp->rx_pg_ring);
+       bp->rx_pg_ring = NULL;
 }
 
 static int
@@ -492,38 +535,54 @@ bnx2_alloc_mem(struct bnx2 *bp)
 {
        int i, status_blk_size;
 
-       bp->tx_buf_ring = kzalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
-                                 GFP_KERNEL);
+       bp->tx_buf_ring = kzalloc(SW_TXBD_RING_SIZE, GFP_KERNEL);
        if (bp->tx_buf_ring == NULL)
                return -ENOMEM;
 
-       bp->tx_desc_ring = pci_alloc_consistent(bp->pdev,
-                                               sizeof(struct tx_bd) *
-                                               TX_DESC_CNT,
+       bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, TXBD_RING_SIZE,
                                                &bp->tx_desc_mapping);
        if (bp->tx_desc_ring == NULL)
                goto alloc_mem_err;
 
-       bp->rx_buf_ring = vmalloc(sizeof(struct sw_bd) * RX_DESC_CNT *
-                                 bp->rx_max_ring);
+       bp->rx_buf_ring = vmalloc(SW_RXBD_RING_SIZE * bp->rx_max_ring);
        if (bp->rx_buf_ring == NULL)
                goto alloc_mem_err;
 
-       memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT *
-                                  bp->rx_max_ring);
+       memset(bp->rx_buf_ring, 0, SW_RXBD_RING_SIZE * bp->rx_max_ring);
 
        for (i = 0; i < bp->rx_max_ring; i++) {
                bp->rx_desc_ring[i] =
-                       pci_alloc_consistent(bp->pdev,
-                                            sizeof(struct rx_bd) * RX_DESC_CNT,
+                       pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
                                             &bp->rx_desc_mapping[i]);
                if (bp->rx_desc_ring[i] == NULL)
                        goto alloc_mem_err;
 
        }
 
+       if (bp->rx_pg_ring_size) {
+               bp->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
+                                        bp->rx_max_pg_ring);
+               if (bp->rx_pg_ring == NULL)
+                       goto alloc_mem_err;
+
+               memset(bp->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
+                      bp->rx_max_pg_ring);
+       }
+
+       for (i = 0; i < bp->rx_max_pg_ring; i++) {
+               bp->rx_pg_desc_ring[i] =
+                       pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
+                                            &bp->rx_pg_desc_mapping[i]);
+               if (bp->rx_pg_desc_ring[i] == NULL)
+                       goto alloc_mem_err;
+
+       }
+
        /* Combine status and statistics blocks into one allocation. */
        status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
+       if (bp->flags & BNX2_FLAG_MSIX_CAP)
+               status_blk_size = L1_CACHE_ALIGN(BNX2_MAX_MSIX_HW_VEC *
+                                                BNX2_SBLK_MSIX_ALIGN_SIZE);
        bp->status_stats_size = status_blk_size +
                                sizeof(struct statistics_block);
 
@@ -534,6 +593,18 @@ bnx2_alloc_mem(struct bnx2 *bp)
 
        memset(bp->status_blk, 0, bp->status_stats_size);
 
+       bp->bnx2_napi[0].status_blk = bp->status_blk;
+       if (bp->flags & BNX2_FLAG_MSIX_CAP) {
+               for (i = 1; i < BNX2_MAX_MSIX_VEC; i++) {
+                       struct bnx2_napi *bnapi = &bp->bnx2_napi[i];
+
+                       bnapi->status_blk_msix = (void *)
+                               ((unsigned long) bp->status_blk +
+                                BNX2_SBLK_MSIX_ALIGN_SIZE * i);
+                       bnapi->int_num = i << 24;
+               }
+       }
+
        bp->stats_blk = (void *) ((unsigned long) bp->status_blk +
                                  status_blk_size);
 
@@ -563,7 +634,7 @@ bnx2_report_fw_link(struct bnx2 *bp)
 {
        u32 fw_link_status = 0;
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                return;
 
        if (bp->link_up) {
@@ -605,7 +676,7 @@ bnx2_report_fw_link(struct bnx2 *bp)
                        bnx2_read_phy(bp, bp->mii_bmsr, &bmsr);
 
                        if (!(bmsr & BMSR_ANEGCOMPLETE) ||
-                           bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
+                           bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)
                                fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
                        else
                                fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
@@ -621,7 +692,7 @@ static char *
 bnx2_xceiver_str(struct bnx2 *bp)
 {
        return ((bp->phy_port == PORT_FIBRE) ? "SerDes" :
-               ((bp->phy_flags & PHY_SERDES_FLAG) ? "Remote Copper" :
+               ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" :
                 "Copper"));
 }
 
@@ -681,7 +752,7 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
                return;
        }
 
-       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+       if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
            (CHIP_NUM(bp) == CHIP_NUM_5708)) {
                u32 val;
 
@@ -696,7 +767,7 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
        bnx2_read_phy(bp, bp->mii_adv, &local_adv);
        bnx2_read_phy(bp, bp->mii_lpa, &remote_adv);
 
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                u32 new_local_adv = 0;
                u32 new_remote_adv = 0;
 
@@ -979,7 +1050,7 @@ bnx2_set_mac_link(struct bnx2 *bp)
 static void
 bnx2_enable_bmsr1(struct bnx2 *bp)
 {
-       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+       if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
            (CHIP_NUM(bp) == CHIP_NUM_5709))
                bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
                               MII_BNX2_BLK_ADDR_GP_STATUS);
@@ -988,7 +1059,7 @@ bnx2_enable_bmsr1(struct bnx2 *bp)
 static void
 bnx2_disable_bmsr1(struct bnx2 *bp)
 {
-       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+       if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
            (CHIP_NUM(bp) == CHIP_NUM_5709))
                bnx2_write_phy(bp, MII_BNX2_BLK_ADDR,
                               MII_BNX2_BLK_ADDR_COMBO_IEEEB0);
@@ -1000,7 +1071,7 @@ bnx2_test_and_enable_2g5(struct bnx2 *bp)
        u32 up1;
        int ret = 1;
 
-       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
+       if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
                return 0;
 
        if (bp->autoneg & AUTONEG_SPEED)
@@ -1029,7 +1100,7 @@ bnx2_test_and_disable_2g5(struct bnx2 *bp)
        u32 up1;
        int ret = 0;
 
-       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
+       if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
                return 0;
 
        if (CHIP_NUM(bp) == CHIP_NUM_5709)
@@ -1054,7 +1125,7 @@ bnx2_enable_forced_2g5(struct bnx2 *bp)
 {
        u32 bmcr;
 
-       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
+       if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
                return;
 
        if (CHIP_NUM(bp) == CHIP_NUM_5709) {
@@ -1089,7 +1160,7 @@ bnx2_disable_forced_2g5(struct bnx2 *bp)
 {
        u32 bmcr;
 
-       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
+       if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
                return;
 
        if (CHIP_NUM(bp) == CHIP_NUM_5709) {
@@ -1115,6 +1186,19 @@ bnx2_disable_forced_2g5(struct bnx2 *bp)
        bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
 }
 
+static void
+bnx2_5706s_force_link_dn(struct bnx2 *bp, int start)
+{
+       u32 val;
+
+       bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_SERDES_CTL);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val);
+       if (start)
+               bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val & 0xff0f);
+       else
+               bnx2_write_phy(bp, MII_BNX2_DSP_RW_PORT, val | 0xc0);
+}
+
 static int
 bnx2_set_link(struct bnx2 *bp)
 {
@@ -1126,7 +1210,7 @@ bnx2_set_link(struct bnx2 *bp)
                return 0;
        }
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                return 0;
 
        link_up = bp->link_up;
@@ -1136,10 +1220,14 @@ bnx2_set_link(struct bnx2 *bp)
        bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr);
        bnx2_disable_bmsr1(bp);
 
-       if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+       if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
            (CHIP_NUM(bp) == CHIP_NUM_5706)) {
                u32 val;
 
+               if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
+                       bnx2_5706s_force_link_dn(bp, 0);
+                       bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
+               }
                val = REG_RD(bp, BNX2_EMAC_STATUS);
                if (val & BNX2_EMAC_STATUS_LINK)
                        bmsr |= BMSR_LSTATUS;
@@ -1150,7 +1238,7 @@ bnx2_set_link(struct bnx2 *bp)
        if (bmsr & BMSR_LSTATUS) {
                bp->link_up = 1;
 
-               if (bp->phy_flags & PHY_SERDES_FLAG) {
+               if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                        if (CHIP_NUM(bp) == CHIP_NUM_5706)
                                bnx2_5706s_linkup(bp);
                        else if (CHIP_NUM(bp) == CHIP_NUM_5708)
@@ -1164,11 +1252,19 @@ bnx2_set_link(struct bnx2 *bp)
                bnx2_resolve_flow_ctrl(bp);
        }
        else {
-               if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+               if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) &&
                    (bp->autoneg & AUTONEG_SPEED))
                        bnx2_disable_forced_2g5(bp);
 
-               bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+               if (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT) {
+                       u32 bmcr;
+
+                       bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
+                       bmcr |= BMCR_ANENABLE;
+                       bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
+
+                       bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
+               }
                bp->link_up = 0;
        }
 
@@ -1213,7 +1309,7 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
        if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) ==
                (FLOW_CTRL_RX | FLOW_CTRL_TX)) {
 
-               if (bp->phy_flags & PHY_SERDES_FLAG) {
+               if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                        adv = ADVERTISE_1000XPAUSE;
                }
                else {
@@ -1221,7 +1317,7 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
                }
        }
        else if (bp->req_flow_ctrl & FLOW_CTRL_TX) {
-               if (bp->phy_flags & PHY_SERDES_FLAG) {
+               if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                        adv = ADVERTISE_1000XPSE_ASYM;
                }
                else {
@@ -1229,7 +1325,7 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
                }
        }
        else if (bp->req_flow_ctrl & FLOW_CTRL_RX) {
-               if (bp->phy_flags & PHY_SERDES_FLAG) {
+               if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                        adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
                }
                else {
@@ -1304,7 +1400,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
        u32 adv, bmcr;
        u32 new_adv = 0;
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                return (bnx2_setup_remote_phy(bp, port));
 
        if (!(bp->autoneg & AUTONEG_SPEED)) {
@@ -1414,7 +1510,7 @@ bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
 }
 
 #define ETHTOOL_ALL_FIBRE_SPEED                                                \
-       (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ?                       \
+       (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) ?                  \
                (ADVERTISED_2500baseX_Full | ADVERTISED_1000baseT_Full) :\
                (ADVERTISED_1000baseT_Full)
 
@@ -1478,12 +1574,12 @@ bnx2_set_default_remote_link(struct bnx2 *bp)
 static void
 bnx2_set_default_link(struct bnx2 *bp)
 {
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                return bnx2_set_default_remote_link(bp);
 
        bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
        bp->req_line_speed = 0;
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                u32 reg;
 
                bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
@@ -1713,7 +1809,7 @@ bnx2_setup_phy(struct bnx2 *bp, u8 port)
        if (bp->loopback == MAC_LOOPBACK)
                return 0;
 
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                return (bnx2_setup_serdes_phy(bp, port));
        }
        else {
@@ -1748,7 +1844,7 @@ bnx2_init_5709s_phy(struct bnx2 *bp)
 
        bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G);
        bnx2_read_phy(bp, MII_BNX2_OVER1G_UP1, &val);
-       if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)
                val |= BCM5708S_UP1_2G5;
        else
                val &= ~BCM5708S_UP1_2G5;
@@ -1791,7 +1887,7 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
        val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
        bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
 
-       if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) {
                bnx2_read_phy(bp, BCM5708S_UP1, &val);
                val |= BCM5708S_UP1_2G5;
                bnx2_write_phy(bp, BCM5708S_UP1, val);
@@ -1833,7 +1929,7 @@ bnx2_init_5706s_phy(struct bnx2 *bp)
 {
        bnx2_reset_phy(bp);
 
-       bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+       bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
 
        if (CHIP_NUM(bp) == CHIP_NUM_5706)
                REG_WR(bp, BNX2_MISC_GP_HW_CTL0, 0x300);
@@ -1872,7 +1968,7 @@ bnx2_init_copper_phy(struct bnx2 *bp)
 
        bnx2_reset_phy(bp);
 
-       if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_CRC_FIX) {
                bnx2_write_phy(bp, 0x18, 0x0c00);
                bnx2_write_phy(bp, 0x17, 0x000a);
                bnx2_write_phy(bp, 0x15, 0x310b);
@@ -1883,7 +1979,7 @@ bnx2_init_copper_phy(struct bnx2 *bp)
                bnx2_write_phy(bp, 0x18, 0x0400);
        }
 
-       if (bp->phy_flags & PHY_DIS_EARLY_DAC_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_DIS_EARLY_DAC) {
                bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS,
                               MII_BNX2_DSP_EXPAND_REG | 0x8);
                bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &val);
@@ -1923,8 +2019,8 @@ bnx2_init_phy(struct bnx2 *bp)
        u32 val;
        int rc = 0;
 
-       bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG;
-       bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG;
+       bp->phy_flags &= ~BNX2_PHY_FLAG_INT_MODE_MASK;
+       bp->phy_flags |= BNX2_PHY_FLAG_INT_MODE_LINK_READY;
 
        bp->mii_bmcr = MII_BMCR;
        bp->mii_bmsr = MII_BMSR;
@@ -1934,7 +2030,7 @@ bnx2_init_phy(struct bnx2 *bp)
 
         REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                goto setup_phy;
 
        bnx2_read_phy(bp, MII_PHYSID1, &val);
@@ -1942,7 +2038,7 @@ bnx2_init_phy(struct bnx2 *bp)
        bnx2_read_phy(bp, MII_PHYSID2, &val);
        bp->phy_id |= val & 0xffff;
 
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                if (CHIP_NUM(bp) == CHIP_NUM_5706)
                        rc = bnx2_init_5706s_phy(bp);
                else if (CHIP_NUM(bp) == CHIP_NUM_5708)
@@ -2125,15 +2221,12 @@ bnx2_init_context(struct bnx2 *bp)
                        vcid_addr += (i << PHY_CTX_SHIFT);
                        pcid_addr += (i << PHY_CTX_SHIFT);
 
-                       REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00);
+                       REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
                        REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
 
                        /* Zero out the context. */
                        for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
-                               CTX_WR(bp, 0x00, offset, 0);
-
-                       REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr);
-                       REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr);
+                               CTX_WR(bp, vcid_addr, offset, 0);
                }
        }
 }
@@ -2206,7 +2299,43 @@ bnx2_set_mac_addr(struct bnx2 *bp)
 }
 
 static inline int
-bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
+bnx2_alloc_rx_page(struct bnx2 *bp, u16 index)
+{
+       dma_addr_t mapping;
+       struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
+       struct rx_bd *rxbd =
+               &bp->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
+       struct page *page = alloc_page(GFP_ATOMIC);
+
+       if (!page)
+               return -ENOMEM;
+       mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
+                              PCI_DMA_FROMDEVICE);
+       rx_pg->page = page;
+       pci_unmap_addr_set(rx_pg, mapping, mapping);
+       rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
+       rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
+       return 0;
+}
+
+static void
+bnx2_free_rx_page(struct bnx2 *bp, u16 index)
+{
+       struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
+       struct page *page = rx_pg->page;
+
+       if (!page)
+               return;
+
+       pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
+                      PCI_DMA_FROMDEVICE);
+
+       __free_page(page);
+       rx_pg->page = NULL;
+}
+
+static inline int
+bnx2_alloc_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, u16 index)
 {
        struct sk_buff *skb;
        struct sw_bd *rx_buf = &bp->rx_buf_ring[index];
@@ -2231,15 +2360,15 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
        rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
        rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
 
-       bp->rx_prod_bseq += bp->rx_buf_use_size;
+       bnapi->rx_prod_bseq += bp->rx_buf_use_size;
 
        return 0;
 }
 
 static int
-bnx2_phy_event_is_set(struct bnx2 *bp, u32 event)
+bnx2_phy_event_is_set(struct bnx2 *bp, struct bnx2_napi *bnapi, u32 event)
 {
-       struct status_block *sblk = bp->status_blk;
+       struct status_block *sblk = bnapi->status_blk;
        u32 new_link_state, old_link_state;
        int is_set = 1;
 
@@ -2257,30 +2386,41 @@ bnx2_phy_event_is_set(struct bnx2 *bp, u32 event)
 }
 
 static void
-bnx2_phy_int(struct bnx2 *bp)
+bnx2_phy_int(struct bnx2 *bp, struct bnx2_napi *bnapi)
 {
-       if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_LINK_STATE)) {
+       if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_LINK_STATE)) {
                spin_lock(&bp->phy_lock);
                bnx2_set_link(bp);
                spin_unlock(&bp->phy_lock);
        }
-       if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_TIMER_ABORT))
+       if (bnx2_phy_event_is_set(bp, bnapi, STATUS_ATTN_BITS_TIMER_ABORT))
                bnx2_set_remote_link(bp);
 
 }
 
-static void
-bnx2_tx_int(struct bnx2 *bp)
+static inline u16
+bnx2_get_hw_tx_cons(struct bnx2_napi *bnapi)
+{
+       u16 cons;
+
+       if (bnapi->int_num == 0)
+               cons = bnapi->status_blk->status_tx_quick_consumer_index0;
+       else
+               cons = bnapi->status_blk_msix->status_tx_quick_consumer_index;
+
+       if (unlikely((cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT))
+               cons++;
+       return cons;
+}
+
+static int
+bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 {
-       struct status_block *sblk = bp->status_blk;
        u16 hw_cons, sw_cons, sw_ring_cons;
-       int tx_free_bd = 0;
+       int tx_pkt = 0;
 
-       hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
-       if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
-               hw_cons++;
-       }
-       sw_cons = bp->tx_cons;
+       hw_cons = bnx2_get_hw_tx_cons(bnapi);
+       sw_cons = bnapi->tx_cons;
 
        while (sw_cons != hw_cons) {
                struct sw_bd *tx_buf;
@@ -2327,19 +2467,16 @@ bnx2_tx_int(struct bnx2 *bp)
 
                sw_cons = NEXT_TX_BD(sw_cons);
 
-               tx_free_bd += last + 1;
-
                dev_kfree_skb(skb);
+               tx_pkt++;
+               if (tx_pkt == budget)
+                       break;
 
-               hw_cons = bp->hw_tx_cons =
-                       sblk->status_tx_quick_consumer_index0;
-
-               if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
-                       hw_cons++;
-               }
+               hw_cons = bnx2_get_hw_tx_cons(bnapi);
        }
 
-       bp->tx_cons = sw_cons;
+       bnapi->hw_tx_cons = hw_cons;
+       bnapi->tx_cons = sw_cons;
        /* Need to make the tx_cons update visible to bnx2_start_xmit()
         * before checking for netif_queue_stopped().  Without the
         * memory barrier, there is a small possibility that bnx2_start_xmit()
@@ -2348,17 +2485,68 @@ bnx2_tx_int(struct bnx2 *bp)
        smp_mb();
 
        if (unlikely(netif_queue_stopped(bp->dev)) &&
-                    (bnx2_tx_avail(bp) > bp->tx_wake_thresh)) {
+                    (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh)) {
                netif_tx_lock(bp->dev);
                if ((netif_queue_stopped(bp->dev)) &&
-                   (bnx2_tx_avail(bp) > bp->tx_wake_thresh))
+                   (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh))
                        netif_wake_queue(bp->dev);
                netif_tx_unlock(bp->dev);
        }
+       return tx_pkt;
+}
+
+static void
+bnx2_reuse_rx_skb_pages(struct bnx2 *bp, struct bnx2_napi *bnapi,
+                       struct sk_buff *skb, int count)
+{
+       struct sw_pg *cons_rx_pg, *prod_rx_pg;
+       struct rx_bd *cons_bd, *prod_bd;
+       dma_addr_t mapping;
+       int i;
+       u16 hw_prod = bnapi->rx_pg_prod, prod;
+       u16 cons = bnapi->rx_pg_cons;
+
+       for (i = 0; i < count; i++) {
+               prod = RX_PG_RING_IDX(hw_prod);
+
+               prod_rx_pg = &bp->rx_pg_ring[prod];
+               cons_rx_pg = &bp->rx_pg_ring[cons];
+               cons_bd = &bp->rx_pg_desc_ring[RX_RING(cons)][RX_IDX(cons)];
+               prod_bd = &bp->rx_pg_desc_ring[RX_RING(prod)][RX_IDX(prod)];
+
+               if (i == 0 && skb) {
+                       struct page *page;
+                       struct skb_shared_info *shinfo;
+
+                       shinfo = skb_shinfo(skb);
+                       shinfo->nr_frags--;
+                       page = shinfo->frags[shinfo->nr_frags].page;
+                       shinfo->frags[shinfo->nr_frags].page = NULL;
+                       mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
+                                              PCI_DMA_FROMDEVICE);
+                       cons_rx_pg->page = page;
+                       pci_unmap_addr_set(cons_rx_pg, mapping, mapping);
+                       dev_kfree_skb(skb);
+               }
+               if (prod != cons) {
+                       prod_rx_pg->page = cons_rx_pg->page;
+                       cons_rx_pg->page = NULL;
+                       pci_unmap_addr_set(prod_rx_pg, mapping,
+                               pci_unmap_addr(cons_rx_pg, mapping));
+
+                       prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
+                       prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
+
+               }
+               cons = RX_PG_RING_IDX(NEXT_RX_BD(cons));
+               hw_prod = NEXT_RX_BD(hw_prod);
+       }
+       bnapi->rx_pg_prod = hw_prod;
+       bnapi->rx_pg_cons = cons;
 }
 
 static inline void
-bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
+bnx2_reuse_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
        u16 cons, u16 prod)
 {
        struct sw_bd *cons_rx_buf, *prod_rx_buf;
@@ -2371,7 +2559,7 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
                pci_unmap_addr(cons_rx_buf, mapping),
                bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 
-       bp->rx_prod_bseq += bp->rx_buf_use_size;
+       bnapi->rx_prod_bseq += bp->rx_buf_use_size;
 
        prod_rx_buf->skb = skb;
 
@@ -2387,10 +2575,102 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
        prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
 }
 
+static int
+bnx2_rx_skb(struct bnx2 *bp, struct bnx2_napi *bnapi, struct sk_buff *skb,
+           unsigned int len, unsigned int hdr_len, dma_addr_t dma_addr,
+           u32 ring_idx)
+{
+       int err;
+       u16 prod = ring_idx & 0xffff;
+
+       err = bnx2_alloc_rx_skb(bp, bnapi, prod);
+       if (unlikely(err)) {
+               bnx2_reuse_rx_skb(bp, bnapi, skb, (u16) (ring_idx >> 16), prod);
+               if (hdr_len) {
+                       unsigned int raw_len = len + 4;
+                       int pages = PAGE_ALIGN(raw_len - hdr_len) >> PAGE_SHIFT;
+
+                       bnx2_reuse_rx_skb_pages(bp, bnapi, NULL, pages);
+               }
+               return err;
+       }
+
+       skb_reserve(skb, bp->rx_offset);
+       pci_unmap_single(bp->pdev, dma_addr, bp->rx_buf_use_size,
+                        PCI_DMA_FROMDEVICE);
+
+       if (hdr_len == 0) {
+               skb_put(skb, len);
+               return 0;
+       } else {
+               unsigned int i, frag_len, frag_size, pages;
+               struct sw_pg *rx_pg;
+               u16 pg_cons = bnapi->rx_pg_cons;
+               u16 pg_prod = bnapi->rx_pg_prod;
+
+               frag_size = len + 4 - hdr_len;
+               pages = PAGE_ALIGN(frag_size) >> PAGE_SHIFT;
+               skb_put(skb, hdr_len);
+
+               for (i = 0; i < pages; i++) {
+                       frag_len = min(frag_size, (unsigned int) PAGE_SIZE);
+                       if (unlikely(frag_len <= 4)) {
+                               unsigned int tail = 4 - frag_len;
+
+                               bnapi->rx_pg_cons = pg_cons;
+                               bnapi->rx_pg_prod = pg_prod;
+                               bnx2_reuse_rx_skb_pages(bp, bnapi, NULL,
+                                                       pages - i);
+                               skb->len -= tail;
+                               if (i == 0) {
+                                       skb->tail -= tail;
+                               } else {
+                                       skb_frag_t *frag =
+                                               &skb_shinfo(skb)->frags[i - 1];
+                                       frag->size -= tail;
+                                       skb->data_len -= tail;
+                                       skb->truesize -= tail;
+                               }
+                               return 0;
+                       }
+                       rx_pg = &bp->rx_pg_ring[pg_cons];
+
+                       pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping),
+                                      PAGE_SIZE, PCI_DMA_FROMDEVICE);
+
+                       if (i == pages - 1)
+                               frag_len -= 4;
+
+                       skb_fill_page_desc(skb, i, rx_pg->page, 0, frag_len);
+                       rx_pg->page = NULL;
+
+                       err = bnx2_alloc_rx_page(bp, RX_PG_RING_IDX(pg_prod));
+                       if (unlikely(err)) {
+                               bnapi->rx_pg_cons = pg_cons;
+                               bnapi->rx_pg_prod = pg_prod;
+                               bnx2_reuse_rx_skb_pages(bp, bnapi, skb,
+                                                       pages - i);
+                               return err;
+                       }
+
+                       frag_size -= frag_len;
+                       skb->data_len += frag_len;
+                       skb->truesize += frag_len;
+                       skb->len += frag_len;
+
+                       pg_prod = NEXT_RX_BD(pg_prod);
+                       pg_cons = RX_PG_RING_IDX(NEXT_RX_BD(pg_cons));
+               }
+               bnapi->rx_pg_prod = pg_prod;
+               bnapi->rx_pg_cons = pg_cons;
+       }
+       return 0;
+}
+
 static inline u16
-bnx2_get_hw_rx_cons(struct bnx2 *bp)
+bnx2_get_hw_rx_cons(struct bnx2_napi *bnapi)
 {
-       u16 cons = bp->status_blk->status_rx_quick_consumer_index0;
+       u16 cons = bnapi->status_blk->status_rx_quick_consumer_index0;
 
        if (unlikely((cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT))
                cons++;
@@ -2398,22 +2678,22 @@ bnx2_get_hw_rx_cons(struct bnx2 *bp)
 }
 
 static int
-bnx2_rx_int(struct bnx2 *bp, int budget)
+bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 {
        u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
        struct l2_fhdr *rx_hdr;
-       int rx_pkt = 0;
+       int rx_pkt = 0, pg_ring_used = 0;
 
-       hw_cons = bnx2_get_hw_rx_cons(bp);
-       sw_cons = bp->rx_cons;
-       sw_prod = bp->rx_prod;
+       hw_cons = bnx2_get_hw_rx_cons(bnapi);
+       sw_cons = bnapi->rx_cons;
+       sw_prod = bnapi->rx_prod;
 
        /* Memory barrier necessary as speculative reads of the rx
         * buffer can be ahead of the index in the status block
         */
        rmb();
        while (sw_cons != hw_cons) {
-               unsigned int len;
+               unsigned int len, hdr_len;
                u32 status;
                struct sw_bd *rx_buf;
                struct sk_buff *skb;
@@ -2433,7 +2713,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
                        bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 
                rx_hdr = (struct l2_fhdr *) skb->data;
-               len = rx_hdr->l2_fhdr_pkt_len - 4;
+               len = rx_hdr->l2_fhdr_pkt_len;
 
                if ((status = rx_hdr->l2_fhdr_status) &
                        (L2_FHDR_ERRORS_BAD_CRC |
@@ -2442,18 +2722,30 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
                        L2_FHDR_ERRORS_TOO_SHORT |
                        L2_FHDR_ERRORS_GIANT_FRAME)) {
 
-                       goto reuse_rx;
+                       bnx2_reuse_rx_skb(bp, bnapi, skb, sw_ring_cons,
+                                         sw_ring_prod);
+                       goto next_rx;
+               }
+               hdr_len = 0;
+               if (status & L2_FHDR_STATUS_SPLIT) {
+                       hdr_len = rx_hdr->l2_fhdr_ip_xsum;
+                       pg_ring_used = 1;
+               } else if (len > bp->rx_jumbo_thresh) {
+                       hdr_len = bp->rx_jumbo_thresh;
+                       pg_ring_used = 1;
                }
 
-               /* Since we don't have a jumbo ring, copy small packets
-                * if mtu > 1500
-                */
-               if ((bp->dev->mtu > 1500) && (len <= RX_COPY_THRESH)) {
+               len -= 4;
+
+               if (len <= bp->rx_copy_thresh) {
                        struct sk_buff *new_skb;
 
                        new_skb = netdev_alloc_skb(bp->dev, len + 2);
-                       if (new_skb == NULL)
-                               goto reuse_rx;
+                       if (new_skb == NULL) {
+                               bnx2_reuse_rx_skb(bp, bnapi, skb, sw_ring_cons,
+                                                 sw_ring_prod);
+                               goto next_rx;
+                       }
 
                        /* aligned copy */
                        skb_copy_from_linear_data_offset(skb, bp->rx_offset - 2,
@@ -2461,24 +2753,13 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
                        skb_reserve(new_skb, 2);
                        skb_put(new_skb, len);
 
-                       bnx2_reuse_rx_skb(bp, skb,
+                       bnx2_reuse_rx_skb(bp, bnapi, skb,
                                sw_ring_cons, sw_ring_prod);
 
                        skb = new_skb;
-               }
-               else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) {
-                       pci_unmap_single(bp->pdev, dma_addr,
-                               bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
-
-                       skb_reserve(skb, bp->rx_offset);
-                       skb_put(skb, len);
-               }
-               else {
-reuse_rx:
-                       bnx2_reuse_rx_skb(bp, skb,
-                               sw_ring_cons, sw_ring_prod);
+               } else if (unlikely(bnx2_rx_skb(bp, bnapi, skb, len, hdr_len,
+                          dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
                        goto next_rx;
-               }
 
                skb->protocol = eth_type_trans(skb, bp->dev);
 
@@ -2501,7 +2782,7 @@ reuse_rx:
                }
 
 #ifdef BCM_VLAN
-               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && (bp->vlgrp != 0)) {
+               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) {
                        vlan_hwaccel_receive_skb(skb, bp->vlgrp,
                                rx_hdr->l2_fhdr_vlan_tag);
                }
@@ -2521,16 +2802,20 @@ next_rx:
 
                /* Refresh hw_cons to see if there is new work */
                if (sw_cons == hw_cons) {
-                       hw_cons = bnx2_get_hw_rx_cons(bp);
+                       hw_cons = bnx2_get_hw_rx_cons(bnapi);
                        rmb();
                }
        }
-       bp->rx_cons = sw_cons;
-       bp->rx_prod = sw_prod;
+       bnapi->rx_cons = sw_cons;
+       bnapi->rx_prod = sw_prod;
+
+       if (pg_ring_used)
+               REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX,
+                        bnapi->rx_pg_prod);
 
        REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, sw_prod);
 
-       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bnapi->rx_prod_bseq);
 
        mmiowb();
 
@@ -2546,8 +2831,9 @@ bnx2_msi(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
 
-       prefetch(bp->status_blk);
+       prefetch(bnapi->status_blk);
        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
                BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -2556,7 +2842,7 @@ bnx2_msi(int irq, void *dev_instance)
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       netif_rx_schedule(dev, &bp->napi);
+       netif_rx_schedule(dev, &bnapi->napi);
 
        return IRQ_HANDLED;
 }
@@ -2566,14 +2852,15 @@ bnx2_msi_1shot(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
 
-       prefetch(bp->status_blk);
+       prefetch(bnapi->status_blk);
 
        /* Return here if interrupt is disabled. */
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       netif_rx_schedule(dev, &bp->napi);
+       netif_rx_schedule(dev, &bnapi->napi);
 
        return IRQ_HANDLED;
 }
@@ -2583,7 +2870,8 @@ bnx2_interrupt(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct bnx2 *bp = netdev_priv(dev);
-       struct status_block *sblk = bp->status_blk;
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+       struct status_block *sblk = bnapi->status_blk;
 
        /* When using INTx, it is possible for the interrupt to arrive
         * at the CPU before the status block posted prior to the
@@ -2591,7 +2879,7 @@ bnx2_interrupt(int irq, void *dev_instance)
         * When using MSI, the MSI message will always complete after
         * the status block write.
         */
-       if ((sblk->status_idx == bp->last_status_idx) &&
+       if ((sblk->status_idx == bnapi->last_status_idx) &&
            (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
             BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
                return IRQ_NONE;
@@ -2609,24 +2897,41 @@ bnx2_interrupt(int irq, void *dev_instance)
        if (unlikely(atomic_read(&bp->intr_sem) != 0))
                return IRQ_HANDLED;
 
-       if (netif_rx_schedule_prep(dev, &bp->napi)) {
-               bp->last_status_idx = sblk->status_idx;
-               __netif_rx_schedule(dev, &bp->napi);
+       if (netif_rx_schedule_prep(dev, &bnapi->napi)) {
+               bnapi->last_status_idx = sblk->status_idx;
+               __netif_rx_schedule(dev, &bnapi->napi);
        }
 
        return IRQ_HANDLED;
 }
 
+static irqreturn_t
+bnx2_tx_msix(int irq, void *dev_instance)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2 *bp = netdev_priv(dev);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[BNX2_TX_VEC];
+
+       prefetch(bnapi->status_blk_msix);
+
+       /* Return here if interrupt is disabled. */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0))
+               return IRQ_HANDLED;
+
+       netif_rx_schedule(dev, &bnapi->napi);
+       return IRQ_HANDLED;
+}
+
 #define STATUS_ATTN_EVENTS     (STATUS_ATTN_BITS_LINK_STATE | \
                                 STATUS_ATTN_BITS_TIMER_ABORT)
 
 static inline int
-bnx2_has_work(struct bnx2 *bp)
+bnx2_has_work(struct bnx2_napi *bnapi)
 {
-       struct status_block *sblk = bp->status_blk;
+       struct status_block *sblk = bnapi->status_blk;
 
-       if ((bnx2_get_hw_rx_cons(bp) != bp->rx_cons) ||
-           (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
+       if ((bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons) ||
+           (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons))
                return 1;
 
        if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) !=
@@ -2636,16 +2941,40 @@ bnx2_has_work(struct bnx2 *bp)
        return 0;
 }
 
-static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget)
+static int bnx2_tx_poll(struct napi_struct *napi, int budget)
+{
+       struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
+       struct bnx2 *bp = bnapi->bp;
+       int work_done = 0;
+       struct status_block_msix *sblk = bnapi->status_blk_msix;
+
+       do {
+               work_done += bnx2_tx_int(bp, bnapi, budget - work_done);
+               if (unlikely(work_done >= budget))
+                       return work_done;
+
+               bnapi->last_status_idx = sblk->status_idx;
+               rmb();
+       } while (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons);
+
+       netif_rx_complete(bp->dev, napi);
+       REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, bnapi->int_num |
+              BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
+              bnapi->last_status_idx);
+       return work_done;
+}
+
+static int bnx2_poll_work(struct bnx2 *bp, struct bnx2_napi *bnapi,
+                         int work_done, int budget)
 {
-       struct status_block *sblk = bp->status_blk;
+       struct status_block *sblk = bnapi->status_blk;
        u32 status_attn_bits = sblk->status_attn_bits;
        u32 status_attn_bits_ack = sblk->status_attn_bits_ack;
 
        if ((status_attn_bits & STATUS_ATTN_EVENTS) !=
            (status_attn_bits_ack & STATUS_ATTN_EVENTS)) {
 
-               bnx2_phy_int(bp);
+               bnx2_phy_int(bp, bnapi);
 
                /* This is needed to take care of transient status
                 * during link changes.
@@ -2655,49 +2984,50 @@ static int bnx2_poll_work(struct bnx2 *bp, int work_done, int budget)
                REG_RD(bp, BNX2_HC_COMMAND);
        }
 
-       if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
-               bnx2_tx_int(bp);
+       if (bnx2_get_hw_tx_cons(bnapi) != bnapi->hw_tx_cons)
+               bnx2_tx_int(bp, bnapi, 0);
 
-       if (bnx2_get_hw_rx_cons(bp) != bp->rx_cons)
-               work_done += bnx2_rx_int(bp, budget - work_done);
+       if (bnx2_get_hw_rx_cons(bnapi) != bnapi->rx_cons)
+               work_done += bnx2_rx_int(bp, bnapi, budget - work_done);
 
        return work_done;
 }
 
 static int bnx2_poll(struct napi_struct *napi, int budget)
 {
-       struct bnx2 *bp = container_of(napi, struct bnx2, napi);
+       struct bnx2_napi *bnapi = container_of(napi, struct bnx2_napi, napi);
+       struct bnx2 *bp = bnapi->bp;
        int work_done = 0;
-       struct status_block *sblk = bp->status_blk;
+       struct status_block *sblk = bnapi->status_blk;
 
        while (1) {
-               work_done = bnx2_poll_work(bp, work_done, budget);
+               work_done = bnx2_poll_work(bp, bnapi, work_done, budget);
 
                if (unlikely(work_done >= budget))
                        break;
 
-               /* bp->last_status_idx is used below to tell the hw how
+               /* bnapi->last_status_idx is used below to tell the hw how
                 * much work has been processed, so we must read it before
                 * checking for more work.
                 */
-               bp->last_status_idx = sblk->status_idx;
+               bnapi->last_status_idx = sblk->status_idx;
                rmb();
-               if (likely(!bnx2_has_work(bp))) {
+               if (likely(!bnx2_has_work(bnapi))) {
                        netif_rx_complete(bp->dev, napi);
-                       if (likely(bp->flags & USING_MSI_FLAG)) {
+                       if (likely(bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)) {
                                REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                                       BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
-                                      bp->last_status_idx);
+                                      bnapi->last_status_idx);
                                break;
                        }
                        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
                               BNX2_PCICFG_INT_ACK_CMD_MASK_INT |
-                              bp->last_status_idx);
+                              bnapi->last_status_idx);
 
                        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
                               BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
-                              bp->last_status_idx);
+                              bnapi->last_status_idx);
                        break;
                }
        }
@@ -2721,10 +3051,10 @@ bnx2_set_rx_mode(struct net_device *dev)
                                  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
        sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 #ifdef BCM_VLAN
-       if (!bp->vlgrp && !(bp->flags & ASF_ENABLE_FLAG))
+       if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE))
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #else
-       if (!(bp->flags & ASF_ENABLE_FLAG))
+       if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #endif
        if (dev->flags & IFF_PROMISC) {
@@ -2781,7 +3111,7 @@ bnx2_set_rx_mode(struct net_device *dev)
 }
 
 static void
-load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
+load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len,
        u32 rv2p_proc)
 {
        int i;
@@ -2789,9 +3119,9 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
 
 
        for (i = 0; i < rv2p_code_len; i += 8) {
-               REG_WR(bp, BNX2_RV2P_INSTR_HIGH, cpu_to_le32(*rv2p_code));
+               REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code));
                rv2p_code++;
-               REG_WR(bp, BNX2_RV2P_INSTR_LOW, cpu_to_le32(*rv2p_code));
+               REG_WR(bp, BNX2_RV2P_INSTR_LOW, le32_to_cpu(*rv2p_code));
                rv2p_code++;
 
                if (rv2p_proc == RV2P_PROC1) {
@@ -2837,7 +3167,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
                        return rc;
 
                for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
-                       REG_WR_IND(bp, offset, cpu_to_le32(fw->text[j]));
+                       REG_WR_IND(bp, offset, le32_to_cpu(fw->text[j]));
                }
        }
 
@@ -2900,20 +3230,34 @@ bnx2_init_cpus(struct bnx2 *bp)
 {
        struct cpu_reg cpu_reg;
        struct fw_info *fw;
-       int rc;
-       void *text;
+       int rc, rv2p_len;
+       void *text, *rv2p;
 
        /* Initialize the RV2P processor. */
        text = vmalloc(FW_BUF_SIZE);
        if (!text)
                return -ENOMEM;
-       rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1));
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               rv2p = bnx2_xi_rv2p_proc1;
+               rv2p_len = sizeof(bnx2_xi_rv2p_proc1);
+       } else {
+               rv2p = bnx2_rv2p_proc1;
+               rv2p_len = sizeof(bnx2_rv2p_proc1);
+       }
+       rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
        if (rc < 0)
                goto init_cpu_err;
 
        load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1);
 
-       rc = zlib_inflate_blob(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2));
+       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+               rv2p = bnx2_xi_rv2p_proc2;
+               rv2p_len = sizeof(bnx2_xi_rv2p_proc2);
+       } else {
+               rv2p = bnx2_rv2p_proc2;
+               rv2p_len = sizeof(bnx2_rv2p_proc2);
+       }
+       rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len);
        if (rc < 0)
                goto init_cpu_err;
 
@@ -3029,14 +3373,14 @@ bnx2_init_cpus(struct bnx2 *bp)
        cpu_reg.spad_base = BNX2_CP_SCRATCH;
        cpu_reg.mips_view_base = 0x8000000;
 
-       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+       if (CHIP_NUM(bp) == CHIP_NUM_5709)
                fw = &bnx2_cp_fw_09;
+       else
+               fw = &bnx2_cp_fw_06;
+
+       fw->text = text;
+       rc = load_cpu_fw(bp, &cpu_reg, fw);
 
-               fw->text = text;
-               rc = load_cpu_fw(bp, &cpu_reg, fw);
-               if (rc)
-                       goto init_cpu_err;
-       }
 init_cpu_err:
        vfree(text);
        return rc;
@@ -3148,7 +3492,7 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state)
                        wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL;
                }
 
-               if (!(bp->flags & NO_WOL_FLAG))
+               if (!(bp->flags & BNX2_FLAG_NO_WOL))
                        bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg, 0);
 
                pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
@@ -3360,10 +3704,8 @@ bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
 
                val = REG_RD(bp, BNX2_NVM_COMMAND);
                if (val & BNX2_NVM_COMMAND_DONE) {
-                       val = REG_RD(bp, BNX2_NVM_READ);
-
-                       val = be32_to_cpu(val);
-                       memcpy(ret_val, &val, 4);
+                       __be32 v = cpu_to_be32(REG_RD(bp, BNX2_NVM_READ));
+                       memcpy(ret_val, &v, 4);
                        break;
                }
        }
@@ -3377,7 +3719,8 @@ bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags)
 static int
 bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags)
 {
-       u32 cmd, val32;
+       u32 cmd;
+       __be32 val32;
        int j;
 
        /* Build the command word. */
@@ -3394,10 +3737,9 @@ bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags)
        REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE);
 
        memcpy(&val32, val, 4);
-       val32 = cpu_to_be32(val32);
 
        /* Write the data. */
-       REG_WR(bp, BNX2_NVM_WRITE, val32);
+       REG_WR(bp, BNX2_NVM_WRITE, be32_to_cpu(val32));
 
        /* Address of the NVRAM to write to. */
        REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE);
@@ -3796,8 +4138,8 @@ bnx2_init_remote_phy(struct bnx2 *bp)
 {
        u32 val;
 
-       bp->phy_flags &= ~REMOTE_PHY_CAP_FLAG;
-       if (!(bp->phy_flags & PHY_SERDES_FLAG))
+       bp->phy_flags &= ~BNX2_PHY_FLAG_REMOTE_PHY_CAP;
+       if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES))
                return;
 
        val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
@@ -3805,7 +4147,7 @@ bnx2_init_remote_phy(struct bnx2 *bp)
                return;
 
        if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
-               bp->phy_flags |= REMOTE_PHY_CAP_FLAG;
+               bp->phy_flags |= BNX2_PHY_FLAG_REMOTE_PHY_CAP;
 
                val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
                if (val & BNX2_LINK_STATUS_SERDES_LINK)
@@ -3831,6 +4173,15 @@ bnx2_init_remote_phy(struct bnx2 *bp)
        }
 }
 
+static void
+bnx2_setup_msix_tbl(struct bnx2 *bp)
+{
+       REG_WR(bp, BNX2_PCI_GRC_WINDOW_ADDR, BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN);
+
+       REG_WR(bp, BNX2_PCI_GRC_WINDOW2_ADDR, BNX2_MSIX_TABLE_ADDR);
+       REG_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
+}
+
 static int
 bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
 {
@@ -3917,7 +4268,8 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
        spin_lock_bh(&bp->phy_lock);
        old_port = bp->phy_port;
        bnx2_init_remote_phy(bp);
-       if ((bp->phy_flags & REMOTE_PHY_CAP_FLAG) && old_port != bp->phy_port)
+       if ((bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) &&
+           old_port != bp->phy_port)
                bnx2_set_default_remote_link(bp);
        spin_unlock_bh(&bp->phy_lock);
 
@@ -3930,6 +4282,9 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
                rc = bnx2_alloc_bad_rbuf(bp);
        }
 
+       if (bp->flags & BNX2_FLAG_USING_MSIX)
+               bnx2_setup_msix_tbl(bp);
+
        return rc;
 }
 
@@ -3937,7 +4292,7 @@ static int
 bnx2_init_chip(struct bnx2 *bp)
 {
        u32 val;
-       int rc;
+       int rc, i;
 
        /* Make sure the interrupt is not active. */
        REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
@@ -3953,11 +4308,11 @@ bnx2_init_chip(struct bnx2 *bp)
 
        val |= (0x2 << 20) | (1 << 11);
 
-       if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz == 133))
+       if ((bp->flags & BNX2_FLAG_PCIX) && (bp->bus_speed_mhz == 133))
                val |= (1 << 23);
 
        if ((CHIP_NUM(bp) == CHIP_NUM_5706) &&
-           (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG))
+           (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & BNX2_FLAG_PCIX))
                val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA;
 
        REG_WR(bp, BNX2_DMA_CONFIG, val);
@@ -3968,7 +4323,7 @@ bnx2_init_chip(struct bnx2 *bp)
                REG_WR(bp, BNX2_TDMA_CONFIG, val);
        }
 
-       if (bp->flags & PCIX_FLAG) {
+       if (bp->flags & BNX2_FLAG_PCIX) {
                u16 val16;
 
                pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD,
@@ -4033,7 +4388,9 @@ bnx2_init_chip(struct bnx2 *bp)
                val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA;
        REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val);
 
-       bp->last_status_idx = 0;
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+               bp->bnx2_napi[i].last_status_idx = 0;
+
        bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE;
 
        /* Set up how to generate a link change interrupt. */
@@ -4080,7 +4437,25 @@ bnx2_init_chip(struct bnx2 *bp)
                      BNX2_HC_CONFIG_COLLECT_STATS;
        }
 
-       if (bp->flags & ONE_SHOT_MSI_FLAG)
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
+               REG_WR(bp, BNX2_HC_MSIX_BIT_VECTOR,
+                      BNX2_HC_MSIX_BIT_VECTOR_VAL);
+
+               REG_WR(bp, BNX2_HC_SB_CONFIG_1,
+                       BNX2_HC_SB_CONFIG_1_TX_TMR_MODE |
+                       BNX2_HC_SB_CONFIG_1_ONE_SHOT);
+
+               REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP_1,
+                       (bp->tx_quick_cons_trip_int << 16) |
+                        bp->tx_quick_cons_trip);
+
+               REG_WR(bp, BNX2_HC_TX_TICKS_1,
+                       (bp->tx_ticks_int << 16) | bp->tx_ticks);
+
+               val |= BNX2_HC_CONFIG_SB_ADDR_INC_128B;
+       }
+
+       if (bp->flags & BNX2_FLAG_ONE_SHOT_MSI)
                val |= BNX2_HC_CONFIG_ONE_SHOT;
 
        REG_WR(bp, BNX2_HC_CONFIG, val);
@@ -4111,6 +4486,25 @@ bnx2_init_chip(struct bnx2 *bp)
        return rc;
 }
 
+static void
+bnx2_clear_ring_states(struct bnx2 *bp)
+{
+       struct bnx2_napi *bnapi;
+       int i;
+
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+               bnapi = &bp->bnx2_napi[i];
+
+               bnapi->tx_cons = 0;
+               bnapi->hw_tx_cons = 0;
+               bnapi->rx_prod_bseq = 0;
+               bnapi->rx_prod = 0;
+               bnapi->rx_cons = 0;
+               bnapi->rx_pg_prod = 0;
+               bnapi->rx_pg_cons = 0;
+       }
+}
+
 static void
 bnx2_init_tx_context(struct bnx2 *bp, u32 cid)
 {
@@ -4144,7 +4538,17 @@ static void
 bnx2_init_tx_ring(struct bnx2 *bp)
 {
        struct tx_bd *txbd;
-       u32 cid;
+       u32 cid = TX_CID;
+       struct bnx2_napi *bnapi;
+
+       bp->tx_vec = 0;
+       if (bp->flags & BNX2_FLAG_USING_MSIX) {
+               cid = TX_TSS_CID;
+               bp->tx_vec = BNX2_TX_VEC;
+               REG_WR(bp, BNX2_TSCH_TSS_CFG, BNX2_TX_INT_NUM |
+                      (TX_TSS_CID << 7));
+       }
+       bnapi = &bp->bnx2_napi[bp->tx_vec];
 
        bp->tx_wake_thresh = bp->tx_ring_size / 2;
 
@@ -4154,11 +4558,8 @@ bnx2_init_tx_ring(struct bnx2 *bp)
        txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff;
 
        bp->tx_prod = 0;
-       bp->tx_cons = 0;
-       bp->hw_tx_cons = 0;
        bp->tx_prod_bseq = 0;
 
-       cid = TX_CID;
        bp->tx_bidx_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BIDX;
        bp->tx_bseq_addr = MB_GET_CID_ADDR(cid) + BNX2_L2CTX_TX_HOST_BSEQ;
 
@@ -4166,84 +4567,152 @@ bnx2_init_tx_ring(struct bnx2 *bp)
 }
 
 static void
-bnx2_init_rx_ring(struct bnx2 *bp)
+bnx2_init_rxbd_rings(struct rx_bd *rx_ring[], dma_addr_t dma[], u32 buf_size,
+                    int num_rings)
 {
-       struct rx_bd *rxbd;
        int i;
-       u16 prod, ring_prod;
-       u32 val;
-
-       /* 8 for CRC and VLAN */
-       bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
-       /* hw alignment */
-       bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
-
-       ring_prod = prod = bp->rx_prod = 0;
-       bp->rx_cons = 0;
-       bp->rx_prod_bseq = 0;
+       struct rx_bd *rxbd;
 
-       for (i = 0; i < bp->rx_max_ring; i++) {
+       for (i = 0; i < num_rings; i++) {
                int j;
 
-               rxbd = &bp->rx_desc_ring[i][0];
+               rxbd = &rx_ring[i][0];
                for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) {
-                       rxbd->rx_bd_len = bp->rx_buf_use_size;
+                       rxbd->rx_bd_len = buf_size;
                        rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
                }
-               if (i == (bp->rx_max_ring - 1))
+               if (i == (num_rings - 1))
                        j = 0;
                else
                        j = i + 1;
-               rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping[j] >> 32;
-               rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping[j] &
-                                      0xffffffff;
+               rxbd->rx_bd_haddr_hi = (u64) dma[j] >> 32;
+               rxbd->rx_bd_haddr_lo = (u64) dma[j] & 0xffffffff;
+       }
+}
+
+static void
+bnx2_init_rx_ring(struct bnx2 *bp)
+{
+       int i;
+       u16 prod, ring_prod;
+       u32 val, rx_cid_addr = GET_CID_ADDR(RX_CID);
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
+
+       bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
+                            bp->rx_buf_use_size, bp->rx_max_ring);
+
+       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
+       if (bp->rx_pg_ring_size) {
+               bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
+                                    bp->rx_pg_desc_mapping,
+                                    PAGE_SIZE, bp->rx_max_pg_ring);
+               val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
+               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
+               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
+                      BNX2_L2CTX_RBDC_JUMBO_KEY);
+
+               val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
+               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
+
+               val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
+               CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
+
+               if (CHIP_NUM(bp) == CHIP_NUM_5709)
+                       REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
        }
 
        val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
        val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
        val |= 0x02 << 8;
-       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
+       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val);
 
        val = (u64) bp->rx_desc_mapping[0] >> 32;
-       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val);
+       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val);
 
        val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
-       CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
+       CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
 
+       ring_prod = prod = bnapi->rx_pg_prod;
+       for (i = 0; i < bp->rx_pg_ring_size; i++) {
+               if (bnx2_alloc_rx_page(bp, ring_prod) < 0)
+                       break;
+               prod = NEXT_RX_BD(prod);
+               ring_prod = RX_PG_RING_IDX(prod);
+       }
+       bnapi->rx_pg_prod = prod;
+
+       ring_prod = prod = bnapi->rx_prod;
        for (i = 0; i < bp->rx_ring_size; i++) {
-               if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) {
+               if (bnx2_alloc_rx_skb(bp, bnapi, ring_prod) < 0) {
                        break;
                }
                prod = NEXT_RX_BD(prod);
                ring_prod = RX_RING_IDX(prod);
        }
-       bp->rx_prod = prod;
+       bnapi->rx_prod = prod;
 
+       REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX,
+                bnapi->rx_pg_prod);
        REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod);
 
-       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
+       REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bnapi->rx_prod_bseq);
 }
 
-static void
-bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
+static u32 bnx2_find_max_ring(u32 ring_size, u32 max_size)
 {
-       u32 num_rings, max;
+       u32 max, num_rings = 1;
 
-       bp->rx_ring_size = size;
-       num_rings = 1;
-       while (size > MAX_RX_DESC_CNT) {
-               size -= MAX_RX_DESC_CNT;
+       while (ring_size > MAX_RX_DESC_CNT) {
+               ring_size -= MAX_RX_DESC_CNT;
                num_rings++;
        }
        /* round to next power of 2 */
-       max = MAX_RX_RINGS;
+       max = max_size;
        while ((max & num_rings) == 0)
                max >>= 1;
 
        if (num_rings != max)
                max <<= 1;
 
-       bp->rx_max_ring = max;
+       return max;
+}
+
+static void
+bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
+{
+       u32 rx_size, rx_space, jumbo_size;
+
+       /* 8 for CRC and VLAN */
+       rx_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
+
+       rx_space = SKB_DATA_ALIGN(rx_size + BNX2_RX_ALIGN) + NET_SKB_PAD +
+               sizeof(struct skb_shared_info);
+
+       bp->rx_copy_thresh = RX_COPY_THRESH;
+       bp->rx_pg_ring_size = 0;
+       bp->rx_max_pg_ring = 0;
+       bp->rx_max_pg_ring_idx = 0;
+       if ((rx_space > PAGE_SIZE) && !(bp->flags & BNX2_FLAG_JUMBO_BROKEN)) {
+               int pages = PAGE_ALIGN(bp->dev->mtu - 40) >> PAGE_SHIFT;
+
+               jumbo_size = size * pages;
+               if (jumbo_size > MAX_TOTAL_RX_PG_DESC_CNT)
+                       jumbo_size = MAX_TOTAL_RX_PG_DESC_CNT;
+
+               bp->rx_pg_ring_size = jumbo_size;
+               bp->rx_max_pg_ring = bnx2_find_max_ring(jumbo_size,
+                                                       MAX_RX_PG_RINGS);
+               bp->rx_max_pg_ring_idx = (bp->rx_max_pg_ring * RX_DESC_CNT) - 1;
+               rx_size = RX_COPY_THRESH + bp->rx_offset;
+               bp->rx_copy_thresh = 0;
+       }
+
+       bp->rx_buf_use_size = rx_size;
+       /* hw alignment */
+       bp->rx_buf_size = bp->rx_buf_use_size + BNX2_RX_ALIGN;
+       bp->rx_jumbo_thresh = rx_size - bp->rx_offset;
+       bp->rx_ring_size = size;
+       bp->rx_max_ring = bnx2_find_max_ring(size, MAX_RX_RINGS);
        bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
 }
 
@@ -4306,6 +4775,8 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
 
                dev_kfree_skb(skb);
        }
+       for (i = 0; i < bp->rx_max_pg_ring_idx; i++)
+               bnx2_free_rx_page(bp, i);
 }
 
 static void
@@ -4328,6 +4799,7 @@ bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
        if ((rc = bnx2_init_chip(bp)) != 0)
                return rc;
 
+       bnx2_clear_ring_states(bp);
        bnx2_init_tx_ring(bp);
        bnx2_init_rx_ring(bp);
        return 0;
@@ -4599,13 +5071,18 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        struct sw_bd *rx_buf;
        struct l2_fhdr *rx_hdr;
        int ret = -ENODEV;
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[0], *tx_napi;
+
+       tx_napi = bnapi;
+       if (bp->flags & BNX2_FLAG_USING_MSIX)
+               tx_napi = &bp->bnx2_napi[BNX2_TX_VEC];
 
        if (loopback_mode == BNX2_MAC_LOOPBACK) {
                bp->loopback = MAC_LOOPBACK;
                bnx2_set_mac_loopback(bp);
        }
        else if (loopback_mode == BNX2_PHY_LOOPBACK) {
-               if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                        return 0;
 
                bp->loopback = PHY_LOOPBACK;
@@ -4614,7 +5091,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        else
                return -EINVAL;
 
-       pkt_size = 1514;
+       pkt_size = min(bp->dev->mtu + ETH_HLEN, bp->rx_jumbo_thresh - 4);
        skb = netdev_alloc_skb(bp->dev, pkt_size);
        if (!skb)
                return -ENOMEM;
@@ -4633,7 +5110,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        REG_RD(bp, BNX2_HC_COMMAND);
 
        udelay(5);
-       rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0;
+       rx_start_idx = bnx2_get_hw_rx_cons(bnapi);
 
        num_pkts = 0;
 
@@ -4663,11 +5140,10 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
        pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
        dev_kfree_skb(skb);
 
-       if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) {
+       if (bnx2_get_hw_tx_cons(tx_napi) != bp->tx_prod)
                goto loopback_test_done;
-       }
 
-       rx_idx = bp->status_blk->status_rx_quick_consumer_index0;
+       rx_idx = bnx2_get_hw_rx_cons(bnapi);
        if (rx_idx != rx_start_idx + num_pkts) {
                goto loopback_test_done;
        }
@@ -4739,7 +5215,7 @@ bnx2_test_loopback(struct bnx2 *bp)
 static int
 bnx2_test_nvram(struct bnx2 *bp)
 {
-       u32 buf[NVRAM_SIZE / 4];
+       __be32 buf[NVRAM_SIZE / 4];
        u8 *data = (u8 *) buf;
        int rc = 0;
        u32 magic, csum;
@@ -4776,7 +5252,7 @@ bnx2_test_link(struct bnx2 *bp)
 {
        u32 bmsr;
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
                if (bp->link_up)
                        return 0;
                return -ENODEV;
@@ -4824,13 +5300,51 @@ bnx2_test_intr(struct bnx2 *bp)
        return -ENODEV;
 }
 
+static int
+bnx2_5706_serdes_has_link(struct bnx2 *bp)
+{
+       u32 mode_ctl, an_dbg, exp;
+
+       bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_MODE_CTL);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &mode_ctl);
+
+       if (!(mode_ctl & MISC_SHDW_MODE_CTL_SIG_DET))
+               return 0;
+
+       bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+       bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg);
+
+       if (an_dbg & MISC_SHDW_AN_DBG_NOSYNC)
+               return 0;
+
+       bnx2_write_phy(bp, MII_BNX2_DSP_ADDRESS, MII_EXPAND_REG1);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &exp);
+       bnx2_read_phy(bp, MII_BNX2_DSP_RW_PORT, &exp);
+
+       if (exp & MII_EXPAND_REG1_RUDI_C)       /* receiving CONFIG */
+               return 0;
+
+       return 1;
+}
+
 static void
 bnx2_5706_serdes_timer(struct bnx2 *bp)
 {
+       int check_link = 1;
+
        spin_lock(&bp->phy_lock);
-       if (bp->serdes_an_pending)
+       if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) {
+               bnx2_5706s_force_link_dn(bp, 0);
+               bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN;
+               spin_unlock(&bp->phy_lock);
+               return;
+       }
+
+       if (bp->serdes_an_pending) {
                bp->serdes_an_pending--;
-       else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
+               check_link = 0;
+       } else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
                u32 bmcr;
 
                bp->current_interval = bp->timer_interval;
@@ -4838,30 +5352,19 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
                bnx2_read_phy(bp, bp->mii_bmcr, &bmcr);
 
                if (bmcr & BMCR_ANENABLE) {
-                       u32 phy1, phy2;
-
-                       bnx2_write_phy(bp, 0x1c, 0x7c00);
-                       bnx2_read_phy(bp, 0x1c, &phy1);
-
-                       bnx2_write_phy(bp, 0x17, 0x0f01);
-                       bnx2_read_phy(bp, 0x15, &phy2);
-                       bnx2_write_phy(bp, 0x17, 0x0f01);
-                       bnx2_read_phy(bp, 0x15, &phy2);
-
-                       if ((phy1 & 0x10) &&    /* SIGNAL DETECT */
-                               !(phy2 & 0x20)) {       /* no CONFIG */
-
+                       if (bnx2_5706_serdes_has_link(bp)) {
                                bmcr &= ~BMCR_ANENABLE;
                                bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX;
                                bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
-                               bp->phy_flags |= PHY_PARALLEL_DETECT_FLAG;
+                               bp->phy_flags |= BNX2_PHY_FLAG_PARALLEL_DETECT;
                        }
                }
        }
        else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) &&
-                (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) {
+                (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) {
                u32 phy2;
 
+               check_link = 0;
                bnx2_write_phy(bp, 0x17, 0x0f01);
                bnx2_read_phy(bp, 0x15, &phy2);
                if (phy2 & 0x20) {
@@ -4871,21 +5374,33 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
                        bmcr |= BMCR_ANENABLE;
                        bnx2_write_phy(bp, bp->mii_bmcr, bmcr);
 
-                       bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
+                       bp->phy_flags &= ~BNX2_PHY_FLAG_PARALLEL_DETECT;
                }
        } else
                bp->current_interval = bp->timer_interval;
 
+       if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) {
+               u32 val;
+
+               bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG);
+               bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
+               bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val);
+
+               if (val & MISC_SHDW_AN_DBG_NOSYNC) {
+                       bnx2_5706s_force_link_dn(bp, 1);
+                       bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN;
+               }
+       }
        spin_unlock(&bp->phy_lock);
 }
 
 static void
 bnx2_5708_serdes_timer(struct bnx2 *bp)
 {
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                return;
 
-       if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
+       if ((bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) == 0) {
                bp->serdes_an_pending = 0;
                return;
        }
@@ -4932,7 +5447,7 @@ bnx2_timer(unsigned long data)
                REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd |
                                            BNX2_HC_COMMAND_STATS_NOW);
 
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                if (CHIP_NUM(bp) == CHIP_NUM_5706)
                        bnx2_5706_serdes_timer(bp);
                else
@@ -4947,18 +5462,23 @@ static int
 bnx2_request_irq(struct bnx2 *bp)
 {
        struct net_device *dev = bp->dev;
-       int rc = 0;
+       unsigned long flags;
+       struct bnx2_irq *irq;
+       int rc = 0, i;
 
-       if (bp->flags & USING_MSI_FLAG) {
-               irq_handler_t   fn = bnx2_msi;
-
-               if (bp->flags & ONE_SHOT_MSI_FLAG)
-                       fn = bnx2_msi_1shot;
+       if (bp->flags & BNX2_FLAG_USING_MSI_OR_MSIX)
+               flags = 0;
+       else
+               flags = IRQF_SHARED;
 
-               rc = request_irq(bp->pdev->irq, fn, 0, dev->name, dev);
-       } else
-               rc = request_irq(bp->pdev->irq, bnx2_interrupt,
-                                IRQF_SHARED, dev->name, dev);
+       for (i = 0; i < bp->irq_nvecs; i++) {
+               irq = &bp->irq_tbl[i];
+               rc = request_irq(irq->vector, irq->handler, flags, irq->name,
+                                dev);
+               if (rc)
+                       break;
+               irq->requested = 1;
+       }
        return rc;
 }
 
@@ -4966,13 +5486,81 @@ static void
 bnx2_free_irq(struct bnx2 *bp)
 {
        struct net_device *dev = bp->dev;
+       struct bnx2_irq *irq;
+       int i;
 
-       if (bp->flags & USING_MSI_FLAG) {
-               free_irq(bp->pdev->irq, dev);
+       for (i = 0; i < bp->irq_nvecs; i++) {
+               irq = &bp->irq_tbl[i];
+               if (irq->requested)
+                       free_irq(irq->vector, dev);
+               irq->requested = 0;
+       }
+       if (bp->flags & BNX2_FLAG_USING_MSI)
                pci_disable_msi(bp->pdev);
-               bp->flags &= ~(USING_MSI_FLAG | ONE_SHOT_MSI_FLAG);
-       } else
-               free_irq(bp->pdev->irq, dev);
+       else if (bp->flags & BNX2_FLAG_USING_MSIX)
+               pci_disable_msix(bp->pdev);
+
+       bp->flags &= ~(BNX2_FLAG_USING_MSI_OR_MSIX | BNX2_FLAG_ONE_SHOT_MSI);
+}
+
+static void
+bnx2_enable_msix(struct bnx2 *bp)
+{
+       int i, rc;
+       struct msix_entry msix_ent[BNX2_MAX_MSIX_VEC];
+
+       bnx2_setup_msix_tbl(bp);
+       REG_WR(bp, BNX2_PCI_MSIX_CONTROL, BNX2_MAX_MSIX_HW_VEC - 1);
+       REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
+       REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
+
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+               msix_ent[i].entry = i;
+               msix_ent[i].vector = 0;
+       }
+
+       rc = pci_enable_msix(bp->pdev, msix_ent, BNX2_MAX_MSIX_VEC);
+       if (rc != 0)
+               return;
+
+       bp->irq_tbl[BNX2_BASE_VEC].handler = bnx2_msi_1shot;
+       bp->irq_tbl[BNX2_TX_VEC].handler = bnx2_tx_msix;
+
+       strcpy(bp->irq_tbl[BNX2_BASE_VEC].name, bp->dev->name);
+       strcat(bp->irq_tbl[BNX2_BASE_VEC].name, "-base");
+       strcpy(bp->irq_tbl[BNX2_TX_VEC].name, bp->dev->name);
+       strcat(bp->irq_tbl[BNX2_TX_VEC].name, "-tx");
+
+       bp->irq_nvecs = BNX2_MAX_MSIX_VEC;
+       bp->flags |= BNX2_FLAG_USING_MSIX | BNX2_FLAG_ONE_SHOT_MSI;
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++)
+               bp->irq_tbl[i].vector = msix_ent[i].vector;
+}
+
+static void
+bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
+{
+       bp->irq_tbl[0].handler = bnx2_interrupt;
+       strcpy(bp->irq_tbl[0].name, bp->dev->name);
+       bp->irq_nvecs = 1;
+       bp->irq_tbl[0].vector = bp->pdev->irq;
+
+       if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !dis_msi)
+               bnx2_enable_msix(bp);
+
+       if ((bp->flags & BNX2_FLAG_MSI_CAP) && !dis_msi &&
+           !(bp->flags & BNX2_FLAG_USING_MSIX)) {
+               if (pci_enable_msi(bp->pdev) == 0) {
+                       bp->flags |= BNX2_FLAG_USING_MSI;
+                       if (CHIP_NUM(bp) == CHIP_NUM_5709) {
+                               bp->flags |= BNX2_FLAG_ONE_SHOT_MSI;
+                               bp->irq_tbl[0].handler = bnx2_msi_1shot;
+                       } else
+                               bp->irq_tbl[0].handler = bnx2_msi;
+
+                       bp->irq_tbl[0].vector = bp->pdev->irq;
+               }
+       }
 }
 
 /* Called with rtnl_lock */
@@ -4991,19 +5579,12 @@ bnx2_open(struct net_device *dev)
        if (rc)
                return rc;
 
-       napi_enable(&bp->napi);
-
-       if ((bp->flags & MSI_CAP_FLAG) && !disable_msi) {
-               if (pci_enable_msi(bp->pdev) == 0) {
-                       bp->flags |= USING_MSI_FLAG;
-                       if (CHIP_NUM(bp) == CHIP_NUM_5709)
-                               bp->flags |= ONE_SHOT_MSI_FLAG;
-               }
-       }
+       bnx2_setup_int_mode(bp, disable_msi);
+       bnx2_napi_enable(bp);
        rc = bnx2_request_irq(bp);
 
        if (rc) {
-               napi_disable(&bp->napi);
+               bnx2_napi_disable(bp);
                bnx2_free_mem(bp);
                return rc;
        }
@@ -5011,7 +5592,7 @@ bnx2_open(struct net_device *dev)
        rc = bnx2_init_nic(bp);
 
        if (rc) {
-               napi_disable(&bp->napi);
+               bnx2_napi_disable(bp);
                bnx2_free_irq(bp);
                bnx2_free_skbs(bp);
                bnx2_free_mem(bp);
@@ -5024,7 +5605,7 @@ bnx2_open(struct net_device *dev)
 
        bnx2_enable_int(bp);
 
-       if (bp->flags & USING_MSI_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSI) {
                /* Test MSI to make sure it is working
                 * If MSI test fails, go back to INTx mode
                 */
@@ -5038,13 +5619,15 @@ bnx2_open(struct net_device *dev)
                        bnx2_disable_int(bp);
                        bnx2_free_irq(bp);
 
+                       bnx2_setup_int_mode(bp, 1);
+
                        rc = bnx2_init_nic(bp);
 
                        if (!rc)
                                rc = bnx2_request_irq(bp);
 
                        if (rc) {
-                               napi_disable(&bp->napi);
+                               bnx2_napi_disable(bp);
                                bnx2_free_skbs(bp);
                                bnx2_free_mem(bp);
                                del_timer_sync(&bp->timer);
@@ -5053,9 +5636,10 @@ bnx2_open(struct net_device *dev)
                        bnx2_enable_int(bp);
                }
        }
-       if (bp->flags & USING_MSI_FLAG) {
+       if (bp->flags & BNX2_FLAG_USING_MSI)
                printk(KERN_INFO PFX "%s: using MSI\n", dev->name);
-       }
+       else if (bp->flags & BNX2_FLAG_USING_MSIX)
+               printk(KERN_INFO PFX "%s: using MSIX\n", dev->name);
 
        netif_start_queue(dev);
 
@@ -5119,8 +5703,10 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u32 len, vlan_tag_flags, last_frag, mss;
        u16 prod, ring_prod;
        int i;
+       struct bnx2_napi *bnapi = &bp->bnx2_napi[bp->tx_vec];
 
-       if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) {
+       if (unlikely(bnx2_tx_avail(bp, bnapi) <
+           (skb_shinfo(skb)->nr_frags + 1))) {
                netif_stop_queue(dev);
                printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
                        dev->name);
@@ -5136,7 +5722,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
                vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
        }
 
-       if (bp->vlgrp != 0 && vlan_tx_tag_present(skb)) {
+       if (bp->vlgrp && vlan_tx_tag_present(skb)) {
                vlan_tag_flags |=
                        (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
        }
@@ -5235,9 +5821,9 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        bp->tx_prod = prod;
        dev->trans_start = jiffies;
 
-       if (unlikely(bnx2_tx_avail(bp) <= MAX_SKB_FRAGS)) {
+       if (unlikely(bnx2_tx_avail(bp, bnapi) <= MAX_SKB_FRAGS)) {
                netif_stop_queue(dev);
-               if (bnx2_tx_avail(bp) > bp->tx_wake_thresh)
+               if (bnx2_tx_avail(bp, bnapi) > bp->tx_wake_thresh)
                        netif_wake_queue(dev);
        }
 
@@ -5259,9 +5845,9 @@ bnx2_close(struct net_device *dev)
                msleep(1);
 
        bnx2_disable_int_sync(bp);
-       napi_disable(&bp->napi);
+       bnx2_napi_disable(bp);
        del_timer_sync(&bp->timer);
-       if (bp->flags & NO_WOL_FLAG)
+       if (bp->flags & BNX2_FLAG_NO_WOL)
                reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
@@ -5375,7 +5961,7 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        int support_serdes = 0, support_copper = 0;
 
        cmd->supported = SUPPORTED_Autoneg;
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
                support_serdes = 1;
                support_copper = 1;
        } else if (bp->phy_port == PORT_FIBRE)
@@ -5386,7 +5972,7 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (support_serdes) {
                cmd->supported |= SUPPORTED_1000baseT_Full |
                        SUPPORTED_FIBRE;
-               if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)
+               if (bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)
                        cmd->supported |= SUPPORTED_2500baseX_Full;
 
        }
@@ -5442,7 +6028,8 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        if (cmd->port != PORT_TP && cmd->port != PORT_FIBRE)
                goto err_out_unlock;
 
-       if (cmd->port != bp->phy_port && !(bp->phy_flags & REMOTE_PHY_CAP_FLAG))
+       if (cmd->port != bp->phy_port &&
+           !(bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP))
                goto err_out_unlock;
 
        if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -5462,7 +6049,7 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        advertising = cmd->advertising;
 
                } else if (cmd->advertising == ADVERTISED_2500baseX_Full) {
-                       if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) ||
+                       if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE) ||
                            (cmd->port == PORT_TP))
                                goto err_out_unlock;
                } else if (cmd->advertising == ADVERTISED_1000baseT_Full)
@@ -5485,7 +6072,7 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                                goto err_out_unlock;
 
                        if (cmd->speed == SPEED_2500 &&
-                           !(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG))
+                           !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
                                goto err_out_unlock;
                }
                else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
@@ -5584,7 +6171,7 @@ bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct bnx2 *bp = netdev_priv(dev);
 
-       if (bp->flags & NO_WOL_FLAG) {
+       if (bp->flags & BNX2_FLAG_NO_WOL) {
                wol->supported = 0;
                wol->wolopts = 0;
        }
@@ -5607,7 +6194,7 @@ bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
                return -EINVAL;
 
        if (wol->wolopts & WAKE_MAGIC) {
-               if (bp->flags & NO_WOL_FLAG)
+               if (bp->flags & BNX2_FLAG_NO_WOL)
                        return -EINVAL;
 
                bp->wol = 1;
@@ -5630,7 +6217,7 @@ bnx2_nway_reset(struct net_device *dev)
 
        spin_lock_bh(&bp->phy_lock);
 
-       if (bp->phy_flags & REMOTE_PHY_CAP_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) {
                int rc;
 
                rc = bnx2_setup_remote_phy(bp, bp->phy_port);
@@ -5639,7 +6226,7 @@ bnx2_nway_reset(struct net_device *dev)
        }
 
        /* Force a link down visible on the other side */
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK);
                spin_unlock_bh(&bp->phy_lock);
 
@@ -5778,27 +6365,19 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 
        ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
        ering->rx_mini_max_pending = 0;
-       ering->rx_jumbo_max_pending = 0;
+       ering->rx_jumbo_max_pending = MAX_TOTAL_RX_PG_DESC_CNT;
 
        ering->rx_pending = bp->rx_ring_size;
        ering->rx_mini_pending = 0;
-       ering->rx_jumbo_pending = 0;
+       ering->rx_jumbo_pending = bp->rx_pg_ring_size;
 
        ering->tx_max_pending = MAX_TX_DESC_CNT;
        ering->tx_pending = bp->tx_ring_size;
 }
 
 static int
-bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
 {
-       struct bnx2 *bp = netdev_priv(dev);
-
-       if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) ||
-               (ering->tx_pending > MAX_TX_DESC_CNT) ||
-               (ering->tx_pending <= MAX_SKB_FRAGS)) {
-
-               return -EINVAL;
-       }
        if (netif_running(bp->dev)) {
                bnx2_netif_stop(bp);
                bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
@@ -5806,8 +6385,8 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
                bnx2_free_mem(bp);
        }
 
-       bnx2_set_rx_ring_size(bp, ering->rx_pending);
-       bp->tx_ring_size = ering->tx_pending;
+       bnx2_set_rx_ring_size(bp, rx);
+       bp->tx_ring_size = tx;
 
        if (netif_running(bp->dev)) {
                int rc;
@@ -5818,10 +6397,25 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
                bnx2_init_nic(bp);
                bnx2_netif_start(bp);
        }
-
        return 0;
 }
 
+static int
+bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+       struct bnx2 *bp = netdev_priv(dev);
+       int rc;
+
+       if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) ||
+               (ering->tx_pending > MAX_TX_DESC_CNT) ||
+               (ering->tx_pending <= MAX_SKB_FRAGS)) {
+
+               return -EINVAL;
+       }
+       rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending);
+       return rc;
+}
+
 static void
 bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
 {
@@ -6244,7 +6838,7 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        case SIOCGMIIREG: {
                u32 mii_regval;
 
-               if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                        return -EOPNOTSUPP;
 
                if (!netif_running(dev))
@@ -6263,7 +6857,7 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
 
-               if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
+               if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP)
                        return -EOPNOTSUPP;
 
                if (!netif_running(dev))
@@ -6310,14 +6904,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu)
                return -EINVAL;
 
        dev->mtu = new_mtu;
-       if (netif_running(dev)) {
-               bnx2_netif_stop(bp);
-
-               bnx2_init_nic(bp);
-
-               bnx2_netif_start(bp);
-       }
-       return 0;
+       return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size));
 }
 
 #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
@@ -6342,7 +6929,7 @@ bnx2_get_5709_media(struct bnx2 *bp)
        if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C)
                return;
        else if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
-               bp->phy_flags |= PHY_SERDES_FLAG;
+               bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
                return;
        }
 
@@ -6356,7 +6943,7 @@ bnx2_get_5709_media(struct bnx2 *bp)
                case 0x4:
                case 0x5:
                case 0x6:
-                       bp->phy_flags |= PHY_SERDES_FLAG;
+                       bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
                        return;
                }
        } else {
@@ -6364,7 +6951,7 @@ bnx2_get_5709_media(struct bnx2 *bp)
                case 0x1:
                case 0x2:
                case 0x4:
-                       bp->phy_flags |= PHY_SERDES_FLAG;
+                       bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
                        return;
                }
        }
@@ -6379,7 +6966,7 @@ bnx2_get_pci_speed(struct bnx2 *bp)
        if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
                u32 clkreg;
 
-               bp->flags |= PCIX_FLAG;
+               bp->flags |= BNX2_FLAG_PCIX;
 
                clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS);
 
@@ -6418,7 +7005,7 @@ bnx2_get_pci_speed(struct bnx2 *bp)
        }
 
        if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET)
-               bp->flags |= PCI_32BIT_FLAG;
+               bp->flags |= BNX2_FLAG_PCI_32BIT;
 
 }
 
@@ -6506,7 +7093,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                        rc = -EIO;
                        goto err_out_unmap;
                }
-               bp->flags |= PCIE_FLAG;
+               bp->flags |= BNX2_FLAG_PCIE;
+               if (CHIP_REV(bp) == CHIP_REV_Ax)
+                       bp->flags |= BNX2_FLAG_JUMBO_BROKEN;
        } else {
                bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
                if (bp->pcix_cap == 0) {
@@ -6517,9 +7106,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                }
        }
 
+       if (CHIP_NUM(bp) == CHIP_NUM_5709 && CHIP_REV(bp) != CHIP_REV_Ax) {
+               if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
+                       bp->flags |= BNX2_FLAG_MSIX_CAP;
+       }
+
        if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) {
                if (pci_find_capability(pdev, PCI_CAP_ID_MSI))
-                       bp->flags |= MSI_CAP_FLAG;
+                       bp->flags |= BNX2_FLAG_MSI_CAP;
        }
 
        /* 5708 cannot support DMA addresses > 40-bit.  */
@@ -6542,7 +7136,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                goto err_out_unmap;
        }
 
-       if (!(bp->flags & PCIE_FLAG))
+       if (!(bp->flags & BNX2_FLAG_PCIE))
                bnx2_get_pci_speed(bp);
 
        /* 5706A0 may falsely detect SERR and PERR. */
@@ -6552,7 +7146,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                REG_WR(bp, PCI_COMMAND, reg);
        }
        else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) &&
-               !(bp->flags & PCIX_FLAG)) {
+               !(bp->flags & BNX2_FLAG_PCIX)) {
 
                dev_err(&pdev->dev,
                        "5706 A1 can only be used in a PCIX bus, aborting.\n");
@@ -6602,7 +7196,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
                bp->wol = 1;
 
        if (reg & BNX2_PORT_FEATURE_ASF_ENABLED) {
-               bp->flags |= ASF_ENABLE_FLAG;
+               bp->flags |= BNX2_FLAG_ASF_ENABLE;
 
                for (i = 0; i < 30; i++) {
                        reg = REG_RD_IND(bp, bp->shmem_base +
@@ -6638,13 +7232,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        bp->mac_addr[4] = (u8) (reg >> 8);
        bp->mac_addr[5] = (u8) reg;
 
+       bp->rx_offset = sizeof(struct l2_fhdr) + 2;
+
        bp->tx_ring_size = MAX_TX_DESC_CNT;
        bnx2_set_rx_ring_size(bp, 255);
 
        bp->rx_csum = 1;
 
-       bp->rx_offset = sizeof(struct l2_fhdr) + 2;
-
        bp->tx_quick_cons_trip_int = 20;
        bp->tx_quick_cons_trip = 20;
        bp->tx_ticks_int = 80;
@@ -6666,36 +7260,36 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        if (CHIP_NUM(bp) == CHIP_NUM_5709)
                bnx2_get_5709_media(bp);
        else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
-               bp->phy_flags |= PHY_SERDES_FLAG;
+               bp->phy_flags |= BNX2_PHY_FLAG_SERDES;
 
        bp->phy_port = PORT_TP;
-       if (bp->phy_flags & PHY_SERDES_FLAG) {
+       if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) {
                bp->phy_port = PORT_FIBRE;
                reg = REG_RD_IND(bp, bp->shmem_base +
                                     BNX2_SHARED_HW_CFG_CONFIG);
                if (!(reg & BNX2_SHARED_HW_CFG_GIG_LINK_ON_VAUX)) {
-                       bp->flags |= NO_WOL_FLAG;
+                       bp->flags |= BNX2_FLAG_NO_WOL;
                        bp->wol = 0;
                }
                if (CHIP_NUM(bp) != CHIP_NUM_5706) {
                        bp->phy_addr = 2;
                        if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
-                               bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
+                               bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE;
                }
                bnx2_init_remote_phy(bp);
 
        } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
                   CHIP_NUM(bp) == CHIP_NUM_5708)
-               bp->phy_flags |= PHY_CRC_FIX_FLAG;
+               bp->phy_flags |= BNX2_PHY_FLAG_CRC_FIX;
        else if (CHIP_NUM(bp) == CHIP_NUM_5709 &&
                 (CHIP_REV(bp) == CHIP_REV_Ax ||
                  CHIP_REV(bp) == CHIP_REV_Bx))
-               bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG;
+               bp->phy_flags |= BNX2_PHY_FLAG_DIS_EARLY_DAC;
 
        if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
            (CHIP_ID(bp) == CHIP_ID_5708_B0) ||
            (CHIP_ID(bp) == CHIP_ID_5708_B1)) {
-               bp->flags |= NO_WOL_FLAG;
+               bp->flags |= BNX2_FLAG_NO_WOL;
                bp->wol = 0;
        }
 
@@ -6769,13 +7363,13 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
 {
        char *s = str;
 
-       if (bp->flags & PCIE_FLAG) {
+       if (bp->flags & BNX2_FLAG_PCIE) {
                s += sprintf(s, "PCI Express");
        } else {
                s += sprintf(s, "PCI");
-               if (bp->flags & PCIX_FLAG)
+               if (bp->flags & BNX2_FLAG_PCIX)
                        s += sprintf(s, "-X");
-               if (bp->flags & PCI_32BIT_FLAG)
+               if (bp->flags & BNX2_FLAG_PCI_32BIT)
                        s += sprintf(s, " 32-bit");
                else
                        s += sprintf(s, " 64-bit");
@@ -6784,6 +7378,21 @@ bnx2_bus_string(struct bnx2 *bp, char *str)
        return str;
 }
 
+static void __devinit
+bnx2_init_napi(struct bnx2 *bp)
+{
+       int i;
+       struct bnx2_napi *bnapi;
+
+       for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
+               bnapi = &bp->bnx2_napi[i];
+               bnapi->bp = bp;
+       }
+       netif_napi_add(bp->dev, &bp->bnx2_napi[0].napi, bnx2_poll, 64);
+       netif_napi_add(bp->dev, &bp->bnx2_napi[BNX2_TX_VEC].napi, bnx2_tx_poll,
+                      64);
+}
+
 static int __devinit
 bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -6825,7 +7434,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->ethtool_ops = &bnx2_ethtool_ops;
 
        bp = netdev_priv(dev);
-       netif_napi_add(dev, &bp->napi, bnx2_poll, 64);
+       bnx2_init_napi(bp);
 
 #if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
        dev->poll_controller = poll_bnx2;
@@ -6910,7 +7519,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
        bnx2_netif_stop(bp);
        netif_device_detach(dev);
        del_timer_sync(&bp->timer);
-       if (bp->flags & NO_WOL_FLAG)
+       if (bp->flags & BNX2_FLAG_NO_WOL)
                reset_code = BNX2_DRV_MSG_CODE_UNLOAD_LNK_DN;
        else if (bp->wol)
                reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL;
index 30ba366608b0dd4f1e83ca59ee881f0979e562c0..d8e034700c363420e1aef24dd27a01bf56358da8 100644 (file)
@@ -154,6 +154,33 @@ struct status_block {
 #endif
 };
 
+/*
+ *  status_block definition
+ */
+struct status_block_msix {
+#if defined(__BIG_ENDIAN)
+       u16 status_tx_quick_consumer_index;
+       u16 status_rx_quick_consumer_index;
+       u16 status_completion_producer_index;
+       u16 status_cmd_consumer_index;
+       u32 status_unused;
+       u16 status_idx;
+       u8 status_unused2;
+       u8 status_blk_num;
+#elif defined(__LITTLE_ENDIAN)
+       u16 status_rx_quick_consumer_index;
+       u16 status_tx_quick_consumer_index;
+       u16 status_cmd_consumer_index;
+       u16 status_completion_producer_index;
+       u32 status_unused;
+       u8 status_blk_num;
+       u8 status_unused2;
+       u16 status_idx;
+#endif
+};
+
+#define BNX2_SBLK_MSIX_ALIGN_SIZE      128
+
 
 /*
  *  statistics_block definition
@@ -259,6 +286,7 @@ struct l2_fhdr {
                #define L2_FHDR_STATUS_TCP_SEGMENT      (1<<14)
                #define L2_FHDR_STATUS_UDP_DATAGRAM     (1<<15)
 
+               #define L2_FHDR_STATUS_SPLIT            (1<<16)
                #define L2_FHDR_ERRORS_BAD_CRC          (1<<17)
                #define L2_FHDR_ERRORS_PHY_DECODE       (1<<18)
                #define L2_FHDR_ERRORS_ALIGNMENT        (1<<19)
@@ -332,6 +360,12 @@ struct l2_fhdr {
 #define BNX2_L2CTX_NX_BDHADDR_LO                       0x00000014
 #define BNX2_L2CTX_NX_BDIDX                            0x00000018
 
+#define BNX2_L2CTX_HOST_PG_BDIDX                       0x00000044
+#define BNX2_L2CTX_PG_BUF_SIZE                         0x00000048
+#define BNX2_L2CTX_RBDC_KEY                            0x0000004c
+#define BNX2_L2CTX_RBDC_JUMBO_KEY                       0x3ffe
+#define BNX2_L2CTX_NX_PG_BDHADDR_HI                    0x00000050
+#define BNX2_L2CTX_NX_PG_BDHADDR_LO                    0x00000054
 
 /*
  *  pci_config_l definition
@@ -406,6 +440,7 @@ struct l2_fhdr {
 #define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM        (1L<<17)
 #define BNX2_PCICFG_INT_ACK_CMD_MASK_INT                (1L<<18)
 #define BNX2_PCICFG_INT_ACK_CMD_INTERRUPT_NUM           (0xfL<<24)
+#define BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT           24
 
 #define BNX2_PCICFG_STATUS_BIT_SET_CMD                 0x00000088
 #define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD               0x0000008c
@@ -421,6 +456,9 @@ struct l2_fhdr {
 #define BNX2_PCI_GRC_WINDOW_ADDR_VALUE                  (0x1ffL<<13)
 #define BNX2_PCI_GRC_WINDOW_ADDR_SEP_WIN                (1L<<31)
 
+#define BNX2_PCI_GRC_WINDOW2_BASE                       0xc000
+#define BNX2_PCI_GRC_WINDOW3_BASE                       0xe000
+
 #define BNX2_PCI_CONFIG_1                              0x00000404
 #define BNX2_PCI_CONFIG_1_RESERVED0                     (0xffL<<0)
 #define BNX2_PCI_CONFIG_1_READ_BOUNDARY                         (0x7L<<8)
@@ -693,6 +731,8 @@ struct l2_fhdr {
 #define BNX2_PCI_GRC_WINDOW3_ADDR                      0x00000618
 #define BNX2_PCI_GRC_WINDOW3_ADDR_VALUE                         (0x1ffL<<13)
 
+#define BNX2_MSIX_TABLE_ADDR                            0x318000
+#define BNX2_MSIX_PBA_ADDR                              0x31c000
 
 /*
  *  misc_reg definition
@@ -4445,6 +4485,14 @@ struct l2_fhdr {
 #define BNX2_MQ_MEM_RD_DATA2_VALUE                      (0x3fffffffL<<0)
 #define BNX2_MQ_MEM_RD_DATA2_VALUE_XI                   (0x7fffffffL<<0)
 
+#define BNX2_MQ_MAP_L2_3                               0x00003d2c
+#define BNX2_MQ_MAP_L2_3_MQ_OFFSET                      (0xffL<<0)
+#define BNX2_MQ_MAP_L2_3_SZ                             (0x3L<<8)
+#define BNX2_MQ_MAP_L2_3_CTX_OFFSET                     (0x2ffL<<10)
+#define BNX2_MQ_MAP_L2_3_BIN_OFFSET                     (0x7L<<23)
+#define BNX2_MQ_MAP_L2_3_ARM                            (0x3L<<26)
+#define BNX2_MQ_MAP_L2_3_ENA                            (0x1L<<31)
+#define BNX2_MQ_MAP_L2_3_DEFAULT                        0x82004646
 
 /*
  *  tsch_reg definition
@@ -6296,6 +6344,15 @@ struct l2_fhdr {
 #define MII_BNX2_DSP_RW_PORT                   0x15
 #define MII_BNX2_DSP_ADDRESS                   0x17
 #define MII_BNX2_DSP_EXPAND_REG                         0x0f00
+#define MII_EXPAND_REG1                                  (MII_BNX2_DSP_EXPAND_REG | 1)
+#define MII_EXPAND_REG1_RUDI_C                    0x20
+#define MII_EXPAND_SERDES_CTL                    (MII_BNX2_DSP_EXPAND_REG | 2)
+
+#define MII_BNX2_MISC_SHADOW                   0x1c
+#define MISC_SHDW_AN_DBG                        0x6800
+#define MISC_SHDW_AN_DBG_NOSYNC                          0x0002
+#define MISC_SHDW_MODE_CTL                      0x7c00
+#define MISC_SHDW_MODE_CTL_SIG_DET               0x0010
 
 #define MII_BNX2_BLK_ADDR                      0x1f
 #define MII_BNX2_BLK_ADDR_IEEE0                         0x0000
@@ -6336,7 +6393,7 @@ struct l2_fhdr {
 #define MAX_ETHERNET_PACKET_SIZE       1514
 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
 
-#define RX_COPY_THRESH                 92
+#define RX_COPY_THRESH                 128
 
 #define BNX2_MISC_ENABLE_DEFAULT       0x7ffffff
 
@@ -6355,9 +6412,11 @@ struct l2_fhdr {
 #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
 
 #define MAX_RX_RINGS   4
+#define MAX_RX_PG_RINGS        16
 #define RX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct rx_bd))
 #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
 #define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
+#define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)
 
 #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) ==                        \
                (MAX_TX_DESC_CNT - 1)) ?                                \
@@ -6370,6 +6429,7 @@ struct l2_fhdr {
        (x) + 2 : (x) + 1
 
 #define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
+#define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
 
 #define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
 #define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
@@ -6408,6 +6468,17 @@ struct sw_bd {
        DECLARE_PCI_UNMAP_ADDR(mapping)
 };
 
+struct sw_pg {
+       struct page             *page;
+       DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
+#define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
+#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
+#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT)
+#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
+
 /* Buffered flash (Atmel: AT45DB011B) specific information */
 #define SEEPROM_PAGE_BITS                      2
 #define SEEPROM_PHY_PAGE_SIZE                  (1 << SEEPROM_PAGE_BITS)
@@ -6465,6 +6536,39 @@ struct flash_spec {
        u8  *name;
 };
 
+#define BNX2_MAX_MSIX_HW_VEC   9
+#define BNX2_MAX_MSIX_VEC      2
+#define BNX2_BASE_VEC          0
+#define BNX2_TX_VEC            1
+#define BNX2_TX_INT_NUM        (BNX2_TX_VEC << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT)
+
+struct bnx2_irq {
+       irq_handler_t   handler;
+       u16             vector;
+       u8              requested;
+       char            name[16];
+};
+
+struct bnx2_napi {
+       struct napi_struct      napi            ____cacheline_aligned;
+       struct bnx2             *bp;
+       struct status_block     *status_blk;
+       struct status_block_msix        *status_blk_msix;
+       u32                     last_status_idx;
+       u32                     int_num;
+
+       u16                     tx_cons;
+       u16                     hw_tx_cons;
+
+       u32                     rx_prod_bseq;
+       u16                     rx_prod;
+       u16                     rx_cons;
+
+       u16                     rx_pg_prod;
+       u16                     rx_pg_cons;
+
+};
+
 struct bnx2 {
        /* Fields used in the tx and intr/napi performance paths are grouped */
        /* together in the beginning of the structure. */
@@ -6473,33 +6577,32 @@ struct bnx2 {
        struct net_device       *dev;
        struct pci_dev          *pdev;
 
-       struct napi_struct      napi;
-
        atomic_t                intr_sem;
 
-       struct status_block     *status_blk;
-       u32                     last_status_idx;
-
        u32                     flags;
-#define PCIX_FLAG                      0x00000001
-#define PCI_32BIT_FLAG                 0x00000002
-#define ONE_TDMA_FLAG                  0x00000004      /* no longer used */
-#define NO_WOL_FLAG                    0x00000008
-#define USING_MSI_FLAG                 0x00000020
-#define ASF_ENABLE_FLAG                        0x00000040
-#define MSI_CAP_FLAG                   0x00000080
-#define ONE_SHOT_MSI_FLAG              0x00000100
-#define PCIE_FLAG                      0x00000200
+#define BNX2_FLAG_PCIX                 0x00000001
+#define BNX2_FLAG_PCI_32BIT            0x00000002
+#define BNX2_FLAG_MSIX_CAP             0x00000004
+#define BNX2_FLAG_NO_WOL               0x00000008
+#define BNX2_FLAG_USING_MSI            0x00000020
+#define BNX2_FLAG_ASF_ENABLE           0x00000040
+#define BNX2_FLAG_MSI_CAP              0x00000080
+#define BNX2_FLAG_ONE_SHOT_MSI         0x00000100
+#define BNX2_FLAG_PCIE                 0x00000200
+#define BNX2_FLAG_USING_MSIX           0x00000400
+#define BNX2_FLAG_USING_MSI_OR_MSIX    (BNX2_FLAG_USING_MSI | \
+                                        BNX2_FLAG_USING_MSIX)
+#define BNX2_FLAG_JUMBO_BROKEN         0x00000800
 
        /* Put tx producer and consumer fields in separate cache lines. */
 
        u32             tx_prod_bseq __attribute__((aligned(L1_CACHE_BYTES)));
        u16             tx_prod;
+       u8              tx_vec;
        u32             tx_bidx_addr;
        u32             tx_bseq_addr;
 
-       u16             tx_cons __attribute__((aligned(L1_CACHE_BYTES)));
-       u16             hw_tx_cons;
+       struct bnx2_napi        bnx2_napi[BNX2_MAX_MSIX_VEC];
 
 #ifdef BCM_VLAN
        struct                  vlan_group *vlgrp;
@@ -6508,16 +6611,17 @@ struct bnx2 {
        u32                     rx_offset;
        u32                     rx_buf_use_size;        /* useable size */
        u32                     rx_buf_size;            /* with alignment */
+       u32                     rx_copy_thresh;
+       u32                     rx_jumbo_thresh;
        u32                     rx_max_ring_idx;
-
-       u32                     rx_prod_bseq;
-       u16                     rx_prod;
-       u16                     rx_cons;
+       u32                     rx_max_pg_ring_idx;
 
        u32                     rx_csum;
 
        struct sw_bd            *rx_buf_ring;
        struct rx_bd            *rx_desc_ring[MAX_RX_RINGS];
+       struct sw_pg            *rx_pg_ring;
+       struct rx_bd            *rx_pg_desc_ring[MAX_RX_PG_RINGS];
 
        /* TX constants */
        struct tx_bd    *tx_desc_ring;
@@ -6540,15 +6644,16 @@ struct bnx2 {
        spinlock_t              indirect_lock;
 
        u32                     phy_flags;
-#define PHY_SERDES_FLAG                        1
-#define PHY_CRC_FIX_FLAG               2
-#define PHY_PARALLEL_DETECT_FLAG       4
-#define PHY_2_5G_CAPABLE_FLAG          8
-#define PHY_INT_MODE_MASK_FLAG         0x300
-#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
-#define PHY_INT_MODE_LINK_READY_FLAG   0x200
-#define PHY_DIS_EARLY_DAC_FLAG         0x400
-#define REMOTE_PHY_CAP_FLAG            0x800
+#define BNX2_PHY_FLAG_SERDES                   0x00000001
+#define BNX2_PHY_FLAG_CRC_FIX                  0x00000002
+#define BNX2_PHY_FLAG_PARALLEL_DETECT          0x00000004
+#define BNX2_PHY_FLAG_2_5G_CAPABLE             0x00000008
+#define BNX2_PHY_FLAG_INT_MODE_MASK            0x00000300
+#define BNX2_PHY_FLAG_INT_MODE_AUTO_POLLING    0x00000100
+#define BNX2_PHY_FLAG_INT_MODE_LINK_READY      0x00000200
+#define BNX2_PHY_FLAG_DIS_EARLY_DAC            0x00000400
+#define BNX2_PHY_FLAG_REMOTE_PHY_CAP           0x00000800
+#define BNX2_PHY_FLAG_FORCED_DOWN              0x00001000
 
        u32                     mii_bmcr;
        u32                     mii_bmsr;
@@ -6605,6 +6710,10 @@ struct bnx2 {
        int                     rx_ring_size;
        dma_addr_t              rx_desc_mapping[MAX_RX_RINGS];
 
+       int                     rx_max_pg_ring;
+       int                     rx_pg_ring_size;
+       dma_addr_t              rx_pg_desc_mapping[MAX_RX_PG_RINGS];
+
        u16                     tx_quick_cons_trip;
        u16                     tx_quick_cons_trip_int;
        u16                     rx_quick_cons_trip;
@@ -6622,6 +6731,7 @@ struct bnx2 {
 
        u32                     stats_ticks;
 
+       struct status_block     *status_blk;
        dma_addr_t              status_blk_mapping;
 
        struct statistics_block *stats_blk;
@@ -6680,6 +6790,9 @@ struct bnx2 {
        u32                     flash_size;
 
        int                     status_stats_size;
+
+       struct bnx2_irq         irq_tbl[BNX2_MAX_MSIX_VEC];
+       int                     irq_nvecs;
 };
 
 static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
@@ -6737,7 +6850,7 @@ struct fw_info {
        const u32 text_addr;
        const u32 text_len;
        const u32 text_index;
-       u32 *text;
+       __le32 *text;
        u8 *gz_text;
        const u32 gz_text_len;
 
index a6d78243163b1b54ff6170f72609b1e1458639a7..c1ad4dd38c32e4d87613e7d79f519ae337178964 100644 (file)
@@ -1,13 +1,13 @@
 /* bnx2_fw.h: Broadcom NX2 network driver.
  *
- * Copyright (c) 2004, 2005, 2006 Broadcom Corporation
+ * Copyright (c) 2004, 2005, 2006, 2007 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) 2004, 2005, 2006 Broadcom Corporation.
+ * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation.
  *
  * Permission is hereby granted for the distribution of this firmware data
  * in hexadecimal or equivalent format, provided this copyright notice is
  */
 
 static u8 bnx2_COM_b06FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x00, 0x45, 0x30, 0xe7, 0x45, 0x00, 0x03, */
-                                                                   0xdc, 0x5a,
-       0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae, 0xc8, 0x15,
-       0x35, 0xa2, 0xc6, 0xf4, 0x5a, 0xa2, 0xed, 0x5d, 0x72, 0x28, 0x12, 0x96,
-       0xec, 0x6e, 0x68, 0xda, 0x62, 0x8c, 0x8d, 0xb4, 0xd9, 0xa5, 0x0c, 0xa1,
-       0x65, 0x6b, 0x4a, 0xa2, 0x6d, 0x05, 0x11, 0x02, 0x62, 0x49, 0xa9, 0x46,
-       0x50, 0xb7, 0x92, 0xab, 0xb6, 0x81, 0x6b, 0x4b, 0x6b, 0x92, 0x6a, 0x09,
-       0x84, 0xe6, 0x08, 0x11, 0x43, 0x19, 0xa9, 0x11, 0x10, 0xa4, 0x1c, 0xbb,
-       0xc0, 0xb6, 0x2b, 0xbf, 0x05, 0x34, 0x2e, 0x15, 0x4a, 0x6e, 0xd4, 0x34,
-       0x30, 0xfc, 0xa7, 0xa8, 0x51, 0x38, 0xad, 0xe1, 0x04, 0xa8, 0x9b, 0x16,
-       0x45, 0xd0, 0xfc, 0x88, 0x0a, 0xdb, 0xd9, 0x7e, 0xdf, 0x9d, 0x3b, 0xcb,
-       0xe1, 0x92, 0xd4, 0xc3, 0x8f, 0xfe, 0x28, 0x81, 0xe5, 0xcc, 0xbd, 0x73,
-       0xe7, 0xde, 0x73, 0xcf, 0xe3, 0x3b, 0x8f, 0xb9, 0x77, 0x8a, 0x34, 0x88,
-       0xfe, 0x5b, 0x8f, 0x5f, 0xf2, 0xd1, 0x3f, 0x18, 0xbe, 0xab, 0xe7, 0xae,
-       0xbb, 0x71, 0x7b, 0xb7, 0x19, 0xb1, 0x22, 0xec, 0xe7, 0x3f, 0x07, 0xbf,
-       0x6e, 0x7d, 0xbf, 0xda, 0x9f, 0x8d, 0xdf, 0x65, 0xfc, 0x86, 0x7e, 0x2e,
-       0x62, 0xac, 0x31, 0x26, 0xfc, 0x57, 0xa9, 0x5c, 0xfd, 0xb9, 0x49, 0x5a,
-       0xae, 0xf2, 0x3c, 0xe2, 0x2f, 0xa9, 0x68, 0xe6, 0x4f, 0x62, 0x66, 0x46,
-       0x8e, 0xe7, 0x5c, 0x89, 0x45, 0x32, 0x1f, 0x1c, 0x1f, 0x76, 0x45, 0xb2,
-       0xa5, 0x6d, 0xc9, 0xbc, 0x7c, 0x5c, 0x29, 0x3a, 0x96, 0xb0, 0xff, 0xd6,
-       0xcc, 0x47, 0x27, 0xde, 0xd8, 0x91, 0xfa, 0xc5, 0x6c, 0x44, 0x62, 0x76,
-       0xe6, 0x15, 0xb1, 0xb7, 0x4a, 0xac, 0x15, 0xef, 0x3c, 0xdb, 0x99, 0x33,
-       0xa4, 0x29, 0x98, 0xeb, 0x83, 0xca, 0x1b, 0x9d, 0x52, 0xdc, 0x9c, 0x89,
-       0x89, 0x99, 0xe9, 0x78, 0x27, 0x17, 0xb1, 0x87, 0x22, 0x19, 0x5b, 0x16,
-       0xca, 0x32, 0x30, 0x32, 0x29, 0xb1, 0x58, 0x66, 0x22, 0x56, 0xdf, 0x21,
-       0xb1, 0x68, 0x66, 0xe8, 0xf8, 0xf7, 0xdc, 0x13, 0x15, 0xd3, 0x75, 0x93,
-       0xa3, 0x12, 0xef, 0x1d, 0xef, 0xc1, 0xf3, 0x52, 0x0a, 0x04, 0xef, 0x10,
-       0xd3, 0x2d, 0xc6, 0x23, 0x6e, 0x4c, 0x72, 0x65, 0x57, 0xf2, 0x65, 0x91,
-       0x1f, 0x96, 0x0c, 0x19, 0x77, 0x5b, 0x64, 0x74, 0xfb, 0x47, 0x95, 0x2c,
-       0x68, 0xf9, 0x3b, 0x77, 0xe8, 0xf8, 0x73, 0x2e, 0xe9, 0x9d, 0x8e, 0xf9,
-       0xf4, 0x8e, 0xd7, 0x0f, 0xbb, 0x96, 0xcc, 0x95, 0xd8, 0x77, 0xd0, 0x64,
-       0x9f, 0x95, 0xf9, 0x7e, 0xc3, 0xb8, 0x1b, 0xd7, 0x7d, 0x13, 0xd9, 0x1c,
-       0xe6, 0x9b, 0x2f, 0x71, 0xec, 0xbb, 0x5f, 0x18, 0x76, 0x1d, 0xdd, 0x9f,
-       0xdd, 0x91, 0x73, 0x13, 0xe8, 0x6f, 0xd5, 0xcf, 0x9e, 0x79, 0x74, 0xd8,
-       0x75, 0xf5, 0x33, 0xcb, 0xca, 0xb9, 0x5d, 0xba, 0xbf, 0xb4, 0x6b, 0xd8,
-       0xdd, 0xae, 0xfb, 0x7f, 0xbc, 0x2b, 0xe7, 0xa6, 0x75, 0x7f, 0xef, 0x57,
-       0x86, 0xdd, 0x1e, 0xdd, 0xff, 0xf6, 0xce, 0x9c, 0xdb, 0xab, 0xfb, 0x4f,
-       0xf5, 0x0e, 0xbb, 0xb6, 0x9c, 0x2d, 0x25, 0xf1, 0x9b, 0x88, 0x59, 0x1d,
-       0x19, 0x3d, 0xe6, 0x59, 0xd0, 0x9b, 0xc5, 0x98, 0x3e, 0xf4, 0xef, 0xc1,
-       0xaf, 0x1f, 0xbf, 0xf2, 0x06, 0x69, 0x1a, 0xc0, 0xf3, 0x0f, 0xb7, 0xf8,
-       0x3c, 0x04, 0xaf, 0xbc, 0x98, 0xbc, 0x17, 0x49, 0xc8, 0x1b, 0x9d, 0xef,
-       0x81, 0x97, 0xb6, 0x9c, 0x2b, 0x8b, 0x31, 0xd0, 0x99, 0x00, 0x0f, 0x1d,
-       0x79, 0xb1, 0xdc, 0x28, 0x91, 0x6f, 0x45, 0xc0, 0xa3, 0xaf, 0x4a, 0xc1,
-       0x89, 0xc9, 0xc6, 0x19, 0x43, 0xda, 0xba, 0xd7, 0x49, 0xd6, 0x2e, 0x4a,
-       0xbe, 0x13, 0x52, 0x9f, 0x72, 0xc4, 0x9a, 0x59, 0xdc, 0x68, 0xa2, 0xc7,
-       0x94, 0x54, 0xa2, 0x80, 0x19, 0x47, 0xce, 0xbe, 0x4b, 0x1d, 0xa5, 0x7c,
-       0xf1, 0x4b, 0x4a, 0x7e, 0xf2, 0x0e, 0x19, 0xb2, 0x49, 0xe7, 0x9f, 0xdd,
-       0xea, 0xaf, 0x19, 0x33, 0x72, 0x67, 0x06, 0xe5, 0xa4, 0x17, 0x37, 0xf2,
-       0x67, 0x76, 0x4a, 0x2e, 0x2d, 0x8e, 0x29, 0x1d, 0xea, 0xdd, 0xf9, 0xd2,
-       0xa0, 0x8c, 0x7b, 0x62, 0xe4, 0x3c, 0x4b, 0x46, 0x4b, 0x2d, 0x78, 0xde,
-       0xa4, 0xc6, 0xa2, 0xaf, 0x35, 0x22, 0x1d, 0x76, 0x5e, 0x62, 0xe8, 0xb7,
-       0xd1, 0xdf, 0x6c, 0xf4, 0xa9, 0x39, 0x54, 0x7f, 0x72, 0x4c, 0xe2, 0xd8,
-       0x9b, 0xa3, 0xc7, 0x56, 0x2a, 0xb9, 0xb4, 0x8d, 0x71, 0x83, 0x32, 0xe6,
-       0x39, 0x32, 0x84, 0xeb, 0xa8, 0xc7, 0xf5, 0x13, 0xd0, 0xb1, 0xb7, 0x8e,
-       0x17, 0xa6, 0xd5, 0x7c, 0xc9, 0x48, 0x86, 0xf3, 0xb5, 0x62, 0xdc, 0x05,
-       0xd0, 0x65, 0x88, 0xa5, 0x64, 0x9b, 0x95, 0xc2, 0xa4, 0x21, 0xe4, 0x5b,
-       0x41, 0xf1, 0xb0, 0x0f, 0xf4, 0x5b, 0xe2, 0x76, 0x1b, 0x32, 0xec, 0xde,
-       0x2c, 0x45, 0x1b, 0xed, 0xd2, 0x79, 0x33, 0xe7, 0xd5, 0x4b, 0xde, 0x4a,
-       0x62, 0xff, 0x94, 0xfd, 0x90, 0x8c, 0xe1, 0x1d, 0xd3, 0xe5, 0x98, 0x8f,
-       0xb0, 0x77, 0xb4, 0xf1, 0x6e, 0x5d, 0xe6, 0xa0, 0x5c, 0x9a, 0x2c, 0x9a,
-       0xb9, 0x72, 0x8b, 0x44, 0x66, 0x52, 0xd0, 0xfe, 0x71, 0x33, 0xff, 0xbc,
-       0x25, 0xd1, 0x29, 0xea, 0x97, 0xd8, 0x91, 0xcc, 0x84, 0xb9, 0xbb, 0x7c,
-       0xde, 0xcc, 0x97, 0xf9, 0x0e, 0xc6, 0x96, 0x4c, 0xf0, 0x96, 0xf7, 0xdb,
-       0xc0, 0x4b, 0xea, 0x36, 0xdf, 0x81, 0x1c, 0xb0, 0x87, 0x17, 0x3d, 0xc8,
-       0x45, 0xc9, 0x29, 0x09, 0x39, 0x89, 0xd1, 0xd7, 0x19, 0x93, 0xb1, 0x69,
-       0x4b, 0x0a, 0xe9, 0x9b, 0x15, 0xe7, 0x0b, 0xe9, 0x25, 0x9a, 0x46, 0x27,
-       0x6b, 0x69, 0xe2, 0x7b, 0xa4, 0xc9, 0xa7, 0x65, 0x6c, 0x9a, 0xb4, 0xf9,
-       0xb4, 0x9c, 0x9c, 0x24, 0x8d, 0x5c, 0x87, 0xf4, 0x90, 0xae, 0x80, 0x26,
-       0xbe, 0x43, 0x9a, 0x36, 0x61, 0x7e, 0x65, 0xc0, 0x46, 0x1f, 0x68, 0x18,
-       0xf3, 0x2c, 0xc8, 0x26, 0x2e, 0x05, 0xbb, 0x68, 0x8c, 0xf5, 0x6e, 0x4b,
-       0xc0, 0xaa, 0x8d, 0xd1, 0x5e, 0xd2, 0xeb, 0x42, 0x7e, 0x75, 0x4a, 0xce,
-       0x66, 0x66, 0x9c, 0x3c, 0xc3, 0x78, 0xae, 0x8d, 0xfb, 0x92, 0x2d, 0xe3,
-       0x6a, 0x3e, 0xd2, 0xf3, 0x59, 0xcc, 0x43, 0x7a, 0x2f, 0x43, 0x57, 0x7b,
-       0xa0, 0xa3, 0x69, 0xf9, 0xdb, 0xf2, 0x76, 0x79, 0xbd, 0xdc, 0x25, 0xaf,
-       0xc1, 0x7e, 0x5f, 0x2d, 0x27, 0xe5, 0x95, 0x72, 0xab, 0xbc, 0x5c, 0x4e,
-       0xc8, 0x4b, 0x4a, 0x7f, 0xfb, 0x44, 0x9a, 0x94, 0x4e, 0xc7, 0x6e, 0x86,
-       0x3e, 0xb6, 0x40, 0x1f, 0x9b, 0x61, 0x4f, 0x1b, 0x61, 0xab, 0xdf, 0x06,
-       0x0f, 0xa7, 0x3b, 0x25, 0xbb, 0x09, 0xfd, 0xb7, 0x65, 0x2c, 0xa5, 0x23,
-       0x16, 0x9e, 0x8f, 0x4d, 0x46, 0x25, 0x6f, 0x9f, 0x95, 0xf7, 0xa7, 0x2c,
-       0x19, 0x2b, 0x3f, 0x79, 0x9b, 0xaf, 0xb3, 0x6c, 0xcf, 0xca, 0x45, 0xf4,
-       0xe5, 0xed, 0x59, 0xb9, 0xb4, 0xd5, 0x94, 0xd1, 0xe9, 0xef, 0x4a, 0xee,
-       0xf9, 0xb3, 0xf2, 0xd3, 0xbf, 0x16, 0x19, 0x00, 0xef, 0xcd, 0xee, 0xff,
-       0xaa, 0x64, 0x6d, 0xec, 0xb1, 0x7b, 0xbb, 0x92, 0x89, 0xd9, 0x4d, 0x3d,
-       0x4e, 0x02, 0x57, 0x2c, 0x23, 0xef, 0xbd, 0x00, 0x6c, 0x69, 0x34, 0x72,
-       0xa7, 0x45, 0x86, 0x4f, 0x57, 0x64, 0x38, 0x1d, 0x95, 0xc7, 0xec, 0x8a,
-       0xf4, 0xa5, 0xeb, 0xe4, 0xa8, 0x4d, 0xac, 0x39, 0x6e, 0x04, 0xb8, 0xfe,
-       0xed, 0xf2, 0x09, 0xdc, 0xb3, 0x4f, 0x64, 0x5a, 0xdd, 0xfb, 0xfd, 0xc5,
-       0x72, 0x54, 0xb2, 0x4e, 0x31, 0x61, 0x49, 0x9b, 0xe9, 0xd3, 0xf4, 0xcd,
-       0xe0, 0x19, 0x78, 0x35, 0x04, 0x2c, 0xf5, 0xed, 0xaf, 0x30, 0xb9, 0xee,
-       0x4a, 0x56, 0x75, 0x47, 0x29, 0x3b, 0xe8, 0x34, 0x79, 0x9d, 0x1c, 0x32,
-       0x32, 0x8e, 0xb4, 0x29, 0xbc, 0xe8, 0xc1, 0x98, 0x5e, 0x63, 0x7f, 0x99,
-       0x7a, 0x8e, 0xfb, 0x12, 0x69, 0xdd, 0x8c, 0xb1, 0x16, 0xae, 0x59, 0x4d,
-       0x73, 0x98, 0x4e, 0xce, 0x45, 0x3a, 0x79, 0x7d, 0x21, 0x44, 0xe7, 0x5f,
-       0x56, 0xef, 0xa7, 0x43, 0xf7, 0xc5, 0xf2, 0x0f, 0x1a, 0x7c, 0xfa, 0xc8,
-       0xcf, 0x5e, 0xe8, 0xe3, 0x37, 0xf4, 0x5a, 0xb8, 0x2f, 0x71, 0x8d, 0xb3,
-       0x15, 0x5f, 0xa7, 0x8a, 0xd7, 0x58, 0xeb, 0x62, 0x68, 0xad, 0x4b, 0xa1,
-       0xb5, 0x2e, 0x85, 0xd6, 0x2a, 0x82, 0xb7, 0xb2, 0xc1, 0x74, 0xa3, 0xc0,
-       0x27, 0xf6, 0x4c, 0x60, 0xce, 0x67, 0x21, 0x97, 0x9f, 0x60, 0x4c, 0x46,
-       0x16, 0x3d, 0xf0, 0xe3, 0x74, 0x54, 0xf6, 0xa9, 0x67, 0xbd, 0x9a, 0xae,
-       0xf0, 0xb3, 0x98, 0xec, 0x75, 0x78, 0x1f, 0x3c, 0xb3, 0xc0, 0x63, 0xb6,
-       0xff, 0xe1, 0x16, 0xbf, 0xcd, 0xfb, 0xf3, 0x9a, 0xfe, 0x87, 0xfc, 0xf7,
-       0xca, 0x1f, 0x28, 0x9c, 0x5c, 0x28, 0x13, 0xc7, 0x24, 0x1d, 0x71, 0xe5,
-       0x48, 0x5f, 0x1a, 0x76, 0x65, 0x1b, 0xe9, 0xd1, 0xae, 0x7a, 0xf2, 0x3c,
-       0x6b, 0xba, 0x8d, 0xc0, 0x0a, 0x49, 0x9a, 0xd0, 0xb3, 0x51, 0xb5, 0x97,
-       0x75, 0xa6, 0x4f, 0xb3, 0xcd, 0xf6, 0x80, 0xe9, 0x36, 0xd7, 0xf4, 0xd3,
-       0xde, 0x1b, 0x71, 0x4f, 0xdd, 0x7e, 0x4c, 0xcb, 0x37, 0x8e, 0x36, 0xf1,
-       0xb9, 0x5f, 0xb7, 0x83, 0xe7, 0x39, 0x6b, 0x79, 0xfb, 0xed, 0x2d, 0xcb,
-       0xdb, 0x01, 0x76, 0x84, 0xb1, 0x9d, 0x7b, 0x4d, 0x4a, 0xc4, 0xa5, 0xce,
-       0x45, 0x41, 0x6b, 0x1a, 0xb6, 0x58, 0xaf, 0x69, 0xb8, 0x5d, 0xd3, 0x00,
-       0x5a, 0x31, 0x6e, 0x54, 0xd9, 0x98, 0x12, 0x5f, 0x4d, 0x9b, 0xfc, 0x0e,
-       0xee, 0xd7, 0xab, 0xe7, 0xbe, 0x2d, 0x06, 0x57, 0x31, 0x76, 0x77, 0x52,
-       0xe6, 0x13, 0x90, 0x79, 0x5c, 0xe6, 0xa7, 0xc9, 0xb3, 0x54, 0xe2, 0x71,
-       0x41, 0xbb, 0x94, 0x90, 0xb3, 0x93, 0x92, 0x3d, 0x7c, 0xaa, 0x57, 0xfa,
-       0x60, 0x9f, 0x73, 0x93, 0x57, 0x2a, 0xe0, 0xdb, 0xbd, 0x75, 0xe2, 0x02,
-       0x83, 0xe1, 0xef, 0x7b, 0xa2, 0x12, 0xc9, 0x64, 0xa0, 0x0b, 0x69, 0xe5,
-       0x83, 0x97, 0xfe, 0x2c, 0xeb, 0xfe, 0x65, 0xed, 0x3a, 0xf8, 0x79, 0xcc,
-       0xdb, 0x93, 0x56, 0x7a, 0x13, 0xfe, 0xcb, 0x01, 0x57, 0x72, 0xe9, 0x8f,
-       0xa1, 0x5b, 0x01, 0x4d, 0x81, 0x6d, 0xd0, 0x07, 0x7d, 0x10, 0xf2, 0x6d,
-       0xad, 0xc0, 0x17, 0x07, 0xf2, 0x0b, 0xfc, 0x11, 0xfd, 0x44, 0x82, 0x58,
-       0x0e, 0x5b, 0xa0, 0x6f, 0x88, 0x8b, 0x39, 0x63, 0x69, 0xff, 0x11, 0xd3,
-       0xfe, 0x23, 0x0e, 0xdf, 0xc1, 0xb6, 0xad, 0xdb, 0x8e, 0x6e, 0x27, 0xd0,
-       0x46, 0xec, 0x31, 0x43, 0xbb, 0x7a, 0xeb, 0xf8, 0xc8, 0xb4, 0xf2, 0x49,
-       0xf4, 0x67, 0xf0, 0x14, 0xf4, 0x29, 0xf4, 0x2d, 0xd8, 0x6f, 0x09, 0xeb,
-       0x55, 0x31, 0x9c, 0xf2, 0x08, 0xd3, 0x43, 0x5a, 0xd6, 0x89, 0x09, 0x3f,
-       0x9b, 0x75, 0x48, 0xef, 0x77, 0x20, 0x0f, 0x62, 0x25, 0xe9, 0xbe, 0x15,
-       0xb4, 0x72, 0x3f, 0xff, 0x97, 0xb4, 0x72, 0xbd, 0x5a, 0x7a, 0x3f, 0x2d,
-       0x66, 0x2b, 0xec, 0xc0, 0x9e, 0x33, 0xc0, 0x66, 0x31, 0xf6, 0x77, 0x0e,
-       0x62, 0xcf, 0x03, 0xc0, 0xee, 0x7e, 0x60, 0xf7, 0x1e, 0x60, 0x77, 0x1f,
-       0xb0, 0x3b, 0x0b, 0xec, 0xee, 0x05, 0x6e, 0xf7, 0x00, 0xb7, 0xd3, 0xe0,
-       0x8d, 0x23, 0xb3, 0xc0, 0xf1, 0x59, 0xe8, 0xcb, 0x2c, 0xe6, 0x28, 0xcc,
-       0x88, 0xf1, 0x35, 0xec, 0xe1, 0xe8, 0x54, 0x6a, 0x16, 0xfa, 0x9d, 0x18,
-       0x32, 0xa1, 0x07, 0xe9, 0xbb, 0x61, 0x6f, 0x88, 0x9b, 0xca, 0x83, 0x32,
-       0x0c, 0xbf, 0xdf, 0xb6, 0xb5, 0x1d, 0xfa, 0x84, 0x68, 0x24, 0x11, 0xe8,
-       0x68, 0xbf, 0x14, 0xbc, 0x76, 0xbb, 0xcd, 0xec, 0x42, 0x5f, 0x2a, 0x89,
-       0x18, 0xd5, 0x38, 0x74, 0x3a, 0x65, 0x8c, 0x9c, 0x26, 0x0f, 0x26, 0x81,
-       0x83, 0x15, 0x19, 0x4f, 0x53, 0x4f, 0x2b, 0xf2, 0x5c, 0x3a, 0xd5, 0x5b,
-       0x94, 0x46, 0x39, 0xe9, 0x4c, 0x2a, 0xdf, 0x6f, 0x65, 0x4e, 0x29, 0x1f,
-       0x3a, 0xec, 0xe2, 0x5a, 0x6a, 0x33, 0x0a, 0xa7, 0xb9, 0xd7, 0x76, 0xfc,
-       0xa2, 0x58, 0xf7, 0x57, 0x90, 0x91, 0x25, 0x7d, 0x3d, 0x62, 0x1c, 0xee,
-       0x2c, 0x02, 0x39, 0x53, 0xf6, 0x22, 0x56, 0xcb, 0x4f, 0xb6, 0x27, 0xda,
-       0x4d, 0x4b, 0x86, 0x2c, 0x43, 0x46, 0x61, 0x5f, 0x7d, 0xe9, 0xff, 0xa9,
-       0x9c, 0x74, 0xf8, 0xbc, 0x5e, 0xfe, 0x5c, 0x61, 0x31, 0xd6, 0x9e, 0x9f,
-       0xc6, 0xba, 0x51, 0xf0, 0x9b, 0xeb, 0x72, 0x1e, 0xb4, 0x81, 0x8b, 0x96,
-       0x9b, 0x9a, 0x2d, 0xca, 0x2e, 0xd8, 0xe9, 0x06, 0xc9, 0x6d, 0xaf, 0x93,
-       0xec, 0x40, 0x52, 0x0a, 0x53, 0xbb, 0x80, 0x8d, 0x31, 0x65, 0xab, 0x85,
-       0xc1, 0xa4, 0x3c, 0x36, 0xc5, 0xbe, 0x2c, 0xf6, 0x9a, 0x3a, 0x95, 0x15,
-       0xee, 0xd5, 0x90, 0xec, 0xc1, 0xac, 0x3c, 0xe6, 0x65, 0x65, 0x04, 0xf2,
-       0x3a, 0x0b, 0x5e, 0x1e, 0xf2, 0x5c, 0x79, 0x0e, 0xbe, 0x26, 0x7f, 0x1a,
-       0x58, 0xeb, 0xae, 0x07, 0x2e, 0xa6, 0xce, 0x31, 0xc6, 0x37, 0x19, 0x87,
-       0x82, 0x97, 0x7f, 0x34, 0x45, 0x5e, 0x9a, 0x32, 0x7d, 0xaf, 0x01, 0x3c,
-       0x48, 0x82, 0x77, 0xae, 0xfc, 0xb1, 0x97, 0x3a, 0x9f, 0x35, 0x81, 0xc5,
-       0xe9, 0xde, 0x88, 0x34, 0x24, 0x30, 0xce, 0x1f, 0x93, 0x4f, 0x47, 0x20,
-       0xd7, 0x22, 0xc6, 0xa6, 0xd0, 0xcf, 0x77, 0x1d, 0xfc, 0xb2, 0x18, 0x07,
-       0x5d, 0xb5, 0x53, 0xe7, 0x67, 0x4d, 0x8e, 0x4f, 0x42, 0x3e, 0x36, 0xc6,
-       0x03, 0xf8, 0x6c, 0xde, 0xa7, 0x8d, 0x02, 0x69, 0xf0, 0xa8, 0x53, 0x88,
-       0x49, 0xcb, 0xc4, 0xd4, 0xf6, 0x73, 0xaf, 0x0b, 0xd7, 0xf9, 0x22, 0xc6,
-       0x7f, 0x88, 0x38, 0xdc, 0x96, 0x79, 0xc8, 0xe5, 0xa7, 0xe0, 0x55, 0x36,
-       0xe1, 0xb7, 0x0b, 0x33, 0xa9, 0x73, 0x8b, 0x26, 0xef, 0xdd, 0xe2, 0xa8,
-       0xd9, 0x23, 0xd2, 0x4c, 0x7e, 0xa5, 0xc1, 0x2b, 0xd7, 0x36, 0xcd, 0xb4,
-       0xf2, 0x65, 0xbe, 0x2d, 0xdf, 0x05, 0x9a, 0xa0, 0xf3, 0xdd, 0x61, 0x9b,
-       0xa0, 0xaf, 0x0d, 0x6c, 0x22, 0x95, 0x98, 0x35, 0xe1, 0x9f, 0xbb, 0x2d,
-       0x39, 0xa5, 0xda, 0xe0, 0xd1, 0x60, 0x2a, 0x91, 0x35, 0x11, 0x33, 0x95,
-       0xba, 0xe4, 0xac, 0xc7, 0xf1, 0x49, 0x85, 0x51, 0xfe, 0x78, 0xc4, 0x7a,
-       0x1e, 0xe3, 0xc5, 0x2e, 0xd0, 0xec, 0xdb, 0xc9, 0xdc, 0xa4, 0xa3, 0x9e,
-       0x9d, 0xf4, 0xfc, 0xb8, 0xd0, 0x44, 0xec, 0x38, 0x8b, 0xd8, 0x31, 0xaf,
-       0x6c, 0xc6, 0xce, 0x22, 0xd7, 0x80, 0xce, 0xfb, 0xf6, 0x32, 0x5f, 0xba,
-       0x4f, 0x86, 0xcf, 0x7c, 0x3f, 0x6e, 0x22, 0xce, 0x2a, 0x38, 0xa4, 0x8b,
-       0xe3, 0xcf, 0x81, 0x4e, 0xf2, 0x4e, 0x86, 0x18, 0x57, 0x21, 0x16, 0x7e,
-       0x84, 0x32, 0x1e, 0xed, 0x7e, 0x88, 0x7c, 0x2b, 0x82, 0xe8, 0x53, 0x3e,
-       0x8e, 0x49, 0x91, 0x71, 0xe8, 0x62, 0xe4, 0x09, 0x19, 0x9a, 0xa7, 0x2f,
-       0xc4, 0xcf, 0x23, 0x26, 0x02, 0xc7, 0x94, 0xcf, 0x6a, 0x87, 0x3e, 0x14,
-       0xc1, 0xef, 0x8d, 0x3a, 0x0e, 0x3b, 0x08, 0xf9, 0xf6, 0x43, 0xfe, 0x19,
-       0x19, 0x39, 0x33, 0x42, 0xdd, 0xee, 0x9a, 0x97, 0x54, 0xd7, 0x49, 0xd9,
-       0x66, 0xcf, 0xc1, 0x06, 0xb3, 0x83, 0x95, 0x5d, 0x66, 0x86, 0xef, 0x9c,
-       0xc0, 0x3b, 0xb8, 0xce, 0x8f, 0xc8, 0xd1, 0x32, 0xfb, 0x9e, 0x05, 0xdf,
-       0x11, 0x17, 0xf7, 0x1c, 0xd4, 0xf6, 0x80, 0xf9, 0xac, 0x60, 0xbe, 0x11,
-       0x3d, 0x1f, 0xc7, 0x71, 0x0c, 0xdf, 0x59, 0x9a, 0x77, 0x37, 0x7d, 0x22,
-       0x30, 0xa8, 0xc3, 0xac, 0xec, 0x8a, 0xe2, 0xf9, 0x73, 0x3d, 0xbc, 0xc7,
-       0x3c, 0xf0, 0x89, 0xb6, 0xdb, 0x8f, 0xb1, 0x83, 0x98, 0x73, 0x9d, 0xb4,
-       0xb5, 0x04, 0xf4, 0x52, 0x3f, 0x18, 0xab, 0xb0, 0x3d, 0xb2, 0xc9, 0x97,
-       0xd1, 0xab, 0x11, 0xdf, 0xc7, 0xcc, 0xa2, 0x4d, 0x3b, 0x3c, 0x26, 0x79,
-       0x2f, 0x85, 0x7d, 0x42, 0x06, 0xe5, 0x51, 0xbd, 0x47, 0xc8, 0x69, 0xe0,
-       0x29, 0xf0, 0x41, 0x8a, 0x3e, 0x6f, 0xc8, 0x17, 0xf2, 0xe4, 0x38, 0x6c,
-       0xe0, 0x71, 0x8c, 0x41, 0xbc, 0xab, 0x78, 0x60, 0x6f, 0xf2, 0xe3, 0xf5,
-       0x54, 0x31, 0xcb, 0xbc, 0xb3, 0x99, 0xba, 0x0d, 0xdc, 0x2a, 0x0f, 0xd8,
-       0x9c, 0x7b, 0xd6, 0x64, 0x7e, 0x92, 0x4a, 0x5e, 0x88, 0xec, 0x67, 0xbb,
-       0x6b, 0xd6, 0x84, 0x8c, 0x20, 0xc7, 0xdc, 0xf6, 0x76, 0x8d, 0x55, 0xef,
-       0x28, 0x5d, 0xa6, 0xde, 0x17, 0xbc, 0x6d, 0xf6, 0x43, 0x42, 0x5d, 0x76,
-       0xa0, 0x17, 0xc4, 0x0b, 0x5e, 0x2d, 0xf8, 0xee, 0x04, 0x74, 0x61, 0xbd,
-       0xa6, 0x9d, 0xf7, 0x96, 0xcc, 0xda, 0x58, 0xc3, 0xfb, 0x8f, 0x0d, 0x7e,
-       0x1f, 0xef, 0x19, 0x33, 0x05, 0x72, 0x0c, 0x68, 0xa5, 0x3c, 0x6b, 0x65,
-       0xf8, 0x24, 0x68, 0x67, 0x3f, 0xae, 0xf3, 0xc7, 0x60, 0xa7, 0xc0, 0x94,
-       0x9e, 0x8e, 0xc4, 0x45, 0x8c, 0xcf, 0x03, 0xf7, 0x8b, 0x16, 0x9f, 0x5d,
-       0x31, 0x96, 0xde, 0x31, 0x19, 0x27, 0x23, 0x1e, 0xbf, 0x60, 0x7c, 0x0d,
-       0xb1, 0x4e, 0x6e, 0xfe, 0x8a, 0x91, 0x87, 0x5e, 0xcc, 0x7b, 0x77, 0x43,
-       0x9f, 0x68, 0x57, 0x36, 0xd6, 0x4e, 0x25, 0xfe, 0xc9, 0x6c, 0x4f, 0xce,
-       0x01, 0x03, 0x0e, 0x81, 0xb1, 0xbe, 0x2c, 0x5d, 0x25, 0xdb, 0x45, 0x33,
-       0xaa, 0xf1, 0x8f, 0xed, 0x94, 0xfd, 0xb0, 0xc0, 0x58, 0x1a, 0xf6, 0x80,
-       0xcf, 0x7b, 0x64, 0xb8, 0x9c, 0x91, 0xc2, 0x99, 0x6d, 0xf6, 0x28, 0x72,
-       0xf5, 0x25, 0xda, 0x89, 0x75, 0x45, 0x60, 0x1d, 0xfc, 0xb7, 0x27, 0xc5,
-       0xba, 0x0c, 0x31, 0xaf, 0x03, 0xfa, 0x84, 0xbe, 0xd2, 0x92, 0x4e, 0xde,
-       0xbf, 0x62, 0x3f, 0xf4, 0xdb, 0xcb, 0xf7, 0x34, 0x2f, 0xd7, 0xde, 0xd3,
-       0xee, 0xea, 0x9e, 0x88, 0x31, 0xf0, 0x03, 0x1e, 0xfc, 0x00, 0x74, 0xfa,
-       0x75, 0x0f, 0x7e, 0xc0, 0x83, 0x1f, 0x80, 0x3d, 0xbe, 0x02, 0x7d, 0x7c,
-       0xd9, 0x83, 0x2f, 0xf0, 0xe0, 0x0b, 0x3c, 0xf8, 0x02, 0x2f, 0x07, 0xd9,
-       0x11, 0xef, 0xe9, 0x4b, 0x0e, 0x54, 0xfd, 0xa7, 0x1f, 0x83, 0xdd, 0xa2,
-       0xe3, 0x1a, 0xd8, 0xae, 0xbd, 0x59, 0x46, 0xbb, 0x98, 0x13, 0x35, 0xe0,
-       0xda, 0x88, 0x2b, 0x62, 0x98, 0xae, 0x2f, 0x69, 0xdb, 0x79, 0x1c, 0x74,
-       0x01, 0x17, 0xba, 0xbe, 0x08, 0xdd, 0x44, 0x1c, 0xe1, 0xfe, 0x86, 0x8e,
-       0x7f, 0x7e, 0x64, 0xf9, 0xba, 0xd9, 0x88, 0xbe, 0xfb, 0xd0, 0xd7, 0x88,
-       0x31, 0x47, 0x31, 0x86, 0xf1, 0x53, 0x93, 0xee, 0x0b, 0x8f, 0x63, 0x1c,
-       0xf5, 0x00, 0xd6, 0x4a, 0x61, 0x5c, 0x13, 0xe6, 0x6e, 0xc5, 0x98, 0x9d,
-       0x18, 0x73, 0x2b, 0xda, 0x8c, 0xb9, 0xb7, 0xa0, 0x7d, 0x4f, 0xcd, 0x3b,
-       0xb7, 0xa3, 0xef, 0x4b, 0x35, 0x7d, 0x8b, 0xe8, 0xeb, 0x41, 0xdf, 0x45,
-       0xfd, 0x5e, 0x11, 0xed, 0x96, 0x9a, 0x31, 0x97, 0xd1, 0x87, 0xb8, 0xd9,
-       0xfe, 0x7b, 0x5c, 0xfb, 0x71, 0x25, 0x4d, 0xc1, 0x33, 0xc6, 0xcd, 0xc8,
-       0x41, 0xab, 0xb1, 0xef, 0x5b, 0x8c, 0x0b, 0xe1, 0x7b, 0x7f, 0x6c, 0xf9,
-       0x71, 0xe3, 0x77, 0x6d, 0x5f, 0x57, 0x83, 0xf6, 0x8f, 0x6a, 0xda, 0x1c,
-       0xfb, 0xdf, 0x35, 0x7d, 0x3b, 0x36, 0x2e, 0x6f, 0xdf, 0x59, 0xb7, 0xf2,
-       0x9d, 0x89, 0x9a, 0x31, 0x2f, 0x37, 0x2f, 0x6f, 0xff, 0xe9, 0x2a, 0xef,
-       0xec, 0xd9, 0xb0, 0xbc, 0xef, 0xd1, 0x4d, 0x35, 0x63, 0xa0, 0x53, 0x0e,
-       0x72, 0xab, 0x60, 0xfc, 0x03, 0x37, 0xf9, 0xcf, 0xc9, 0xdf, 0x5a, 0x5d,
-       0x52, 0x5b, 0x47, 0xdb, 0x84, 0x1c, 0x2e, 0x18, 0xb0, 0x39, 0xdb, 0xcc,
-       0x5c, 0x32, 0xf2, 0xd0, 0xa9, 0x5c, 0x39, 0x98, 0x8f, 0xb6, 0x5c, 0x5b,
-       0xdb, 0x08, 0x6a, 0x1a, 0x8c, 0xbb, 0xe2, 0xd0, 0x9b, 0xfd, 0x90, 0x71,
-       0x6a, 0xa2, 0x28, 0x4b, 0x36, 0xdc, 0x66, 0xae, 0x65, 0xc3, 0x4f, 0x6b,
-       0xdc, 0x7a, 0x0a, 0x74, 0x56, 0x64, 0x20, 0x5d, 0x4f, 0xff, 0xa4, 0xf1,
-       0x8c, 0x58, 0x54, 0xa9, 0x44, 0xb6, 0x56, 0xe4, 0x48, 0xfa, 0xc3, 0x8a,
-       0x28, 0x1c, 0x9c, 0x50, 0x58, 0x94, 0x34, 0xdb, 0x21, 0x23, 0x1b, 0xb9,
-       0x8d, 0x23, 0x43, 0x0e, 0xfd, 0xd9, 0x31, 0xc6, 0x29, 0x27, 0x7c, 0x9c,
-       0x25, 0x16, 0xa1, 0x8d, 0xbc, 0xae, 0x70, 0xda, 0x50, 0x31, 0x70, 0x61,
-       0x9e, 0xd8, 0x4e, 0x3c, 0x85, 0xdf, 0xb6, 0x39, 0xef, 0x6a, 0x78, 0x19,
-       0x8b, 0x32, 0x3e, 0xb4, 0xdc, 0x17, 0xe0, 0x1b, 0xf9, 0x8c, 0x71, 0x04,
-       0xee, 0x4b, 0xaa, 0xae, 0x56, 0x5c, 0xbe, 0x97, 0xcd, 0xcc, 0x43, 0xae,
-       0x63, 0x7f, 0xab, 0x63, 0x54, 0xbb, 0x79, 0x6d, 0x7b, 0xde, 0x5b, 0xb5,
-       0xe7, 0x40, 0xdf, 0x56, 0xab, 0x59, 0xbc, 0xa3, 0xf8, 0xff, 0x52, 0x39,
-       0x75, 0xaa, 0x08, 0xfb, 0x59, 0x50, 0x39, 0x7a, 0x20, 0x0b, 0xc6, 0x3c,
-       0xa9, 0x67, 0x66, 0xe9, 0x2d, 0x54, 0x8e, 0xc2, 0xfc, 0xa4, 0x22, 0xbb,
-       0xd3, 0xff, 0xa6, 0xf6, 0x9e, 0x35, 0x3b, 0xeb, 0x18, 0x63, 0x2c, 0x78,
-       0xe4, 0x53, 0x1a, 0xcf, 0x11, 0xfb, 0xa7, 0x7f, 0x26, 0x79, 0x87, 0x7d,
-       0xbf, 0xac, 0xcc, 0x21, 0x36, 0x52, 0xf1, 0x92, 0x8a, 0x0f, 0x18, 0xef,
-       0x1d, 0x01, 0x8f, 0xc8, 0xc7, 0x01, 0xf0, 0x36, 0x88, 0x19, 0xfe, 0x91,
-       0xbe, 0x58, 0x96, 0xc7, 0xd1, 0xc8, 0xb4, 0x4a, 0x97, 0x30, 0xa7, 0x89,
-       0xf9, 0xe8, 0xe3, 0xe8, 0x47, 0xd8, 0x5f, 0x88, 0x32, 0xb6, 0xf3, 0x63,
-       0x83, 0x08, 0xd6, 0xb3, 0x80, 0x83, 0xef, 0x0a, 0x63, 0x9a, 0x61, 0x25,
-       0x03, 0x62, 0x29, 0x9f, 0xb1, 0x2f, 0xa6, 0x63, 0xef, 0xb8, 0x8e, 0xb5,
-       0x6d, 0x1d, 0x6b, 0x93, 0x0e, 0xd6, 0x2d, 0x83, 0x38, 0x82, 0x72, 0xba,
-       0x70, 0xdc, 0xdc, 0xca, 0x38, 0xa2, 0x49, 0x56, 0x8f, 0x23, 0x02, 0x9a,
-       0x76, 0x82, 0x26, 0xc6, 0x7d, 0xaa, 0x4e, 0xd5, 0xec, 0xd7, 0xc6, 0x48,
-       0x43, 0xe0, 0x27, 0x95, 0x3f, 0x9e, 0x80, 0xeb, 0xc3, 0xde, 0x10, 0x48,
-       0x02, 0xdb, 0x73, 0x93, 0x3b, 0xb5, 0xdf, 0x65, 0x0e, 0xc1, 0xf8, 0xdd,
-       0xd7, 0xd3, 0x5c, 0x7a, 0x34, 0x98, 0xa7, 0x05, 0x9e, 0x32, 0x54, 0x43,
-       0xe3, 0x5a, 0x8c, 0x7b, 0x82, 0x18, 0x68, 0x8f, 0x8e, 0x81, 0xfa, 0xe5,
-       0x88, 0xe7, 0xe7, 0x0c, 0x03, 0xa5, 0x01, 0xf4, 0x29, 0xda, 0x13, 0x8c,
-       0x35, 0x4d, 0x93, 0xb1, 0x66, 0x0a, 0xc9, 0x87, 0xbf, 0x97, 0xb6, 0xad,
-       0xac, 0x65, 0x06, 0x7b, 0x69, 0xbc, 0xb0, 0x7c, 0x2f, 0xbb, 0x94, 0xde,
-       0x9b, 0xe0, 0x9d, 0x8f, 0x4d, 0x9c, 0xf3, 0x7c, 0x94, 0xb8, 0x35, 0x50,
-       0x1a, 0x54, 0xf3, 0x8e, 0xaf, 0x98, 0x57, 0xb0, 0xc7, 0x03, 0x6b, 0x3c,
-       0xe3, 0xfe, 0x19, 0x5b, 0xd8, 0x7a, 0xff, 0x81, 0x0c, 0x2f, 0x63, 0xce,
-       0x2e, 0xa3, 0xa0, 0xe2, 0xb6, 0x83, 0x4a, 0x1e, 0x85, 0xd2, 0x10, 0xae,
-       0xb4, 0x17, 0x35, 0x8f, 0xb2, 0x99, 0x51, 0x25, 0x83, 0x11, 0xb5, 0xc7,
-       0xb9, 0xd2, 0x23, 0x88, 0xd7, 0xbe, 0x0e, 0x3f, 0x18, 0xae, 0x2b, 0x3a,
-       0x18, 0x43, 0x5e, 0x15, 0x43, 0x78, 0x4a, 0x9a, 0x59, 0x33, 0xbc, 0x82,
-       0x35, 0xb8, 0xe7, 0x38, 0xe4, 0x6f, 0xf8, 0xcf, 0xd5, 0xfa, 0x01, 0xcf,
-       0xeb, 0x42, 0xf4, 0x54, 0x10, 0xbf, 0x26, 0x40, 0x43, 0xf8, 0x9d, 0x63,
-       0xd2, 0xe7, 0x51, 0x56, 0xed, 0x89, 0x11, 0xe4, 0xbb, 0x05, 0x09, 0x62,
-       0x11, 0xae, 0x4f, 0x0c, 0xc8, 0x23, 0x97, 0x4a, 0x60, 0x7f, 0x01, 0x5f,
-       0x03, 0x9e, 0xc6, 0x2f, 0xd4, 0xea, 0xc7, 0x38, 0xe8, 0x19, 0xf6, 0xc8,
-       0xa7, 0x40, 0x6f, 0x83, 0xb5, 0x2f, 0xab, 0xfd, 0x8c, 0xa9, 0xda, 0xe7,
-       0xfa, 0xba, 0x40, 0x7f, 0x47, 0x11, 0xb7, 0xf8, 0xfa, 0xf8, 0x7b, 0x9a,
-       0x37, 0x81, 0xde, 0xc6, 0xb5, 0x0e, 0x30, 0x47, 0xa4, 0x5d, 0x05, 0x3a,
-       0xd2, 0x61, 0xef, 0x57, 0xbc, 0xe0, 0x33, 0x95, 0x13, 0x2a, 0x39, 0x0f,
-       0x55, 0xe5, 0xbc, 0xbe, 0x46, 0x67, 0x3b, 0x6d, 0xdf, 0x46, 0x69, 0x8b,
-       0xb0, 0x69, 0xd0, 0xf7, 0xd2, 0x32, 0xdb, 0xef, 0x5a, 0xa3, 0xae, 0x1c,
-       0x97, 0xc8, 0xcc, 0x0f, 0xc0, 0xcb, 0xdb, 0x91, 0xd7, 0x20, 0xcb, 0x9f,
-       0x22, 0x46, 0x31, 0xfe, 0x58, 0x8a, 0x89, 0xe7, 0x64, 0xb5, 0x78, 0xf8,
-       0x5a, 0xb1, 0xc7, 0x9d, 0xd7, 0x19, 0x7b, 0xfc, 0x49, 0x1d, 0xf3, 0x9c,
-       0x05, 0xd8, 0xe9, 0x21, 0xbc, 0x5f, 0xe7, 0xfe, 0x10, 0x3e, 0xed, 0xaf,
-       0xac, 0x7a, 0x37, 0xc0, 0x8b, 0xb8, 0x6c, 0x9c, 0xd9, 0xac, 0x30, 0xc3,
-       0x9e, 0x5a, 0xc2, 0x8c, 0x51, 0xcf, 0xd7, 0x5f, 0xf0, 0xca, 0xd9, 0x28,
-       0xd7, 0x9b, 0x77, 0x2f, 0xe5, 0x10, 0x43, 0xd5, 0x1c, 0xe2, 0x96, 0x1a,
-       0x3e, 0xae, 0x86, 0x99, 0xe7, 0x54, 0xbe, 0xfc, 0x6a, 0x39, 0xf5, 0x82,
-       0x48, 0x1f, 0xf2, 0xe4, 0xd4, 0x79, 0x91, 0x2c, 0x72, 0x65, 0xe6, 0x73,
-       0x7b, 0x90, 0x3b, 0xa7, 0x7e, 0x21, 0xd2, 0x8b, 0x9c, 0x99, 0xf9, 0x70,
-       0x3f, 0xf8, 0xda, 0x03, 0x4c, 0x4d, 0x03, 0x63, 0xb7, 0x83, 0xbf, 0x5d,
-       0x0a, 0x57, 0x0f, 0x9d, 0x46, 0xae, 0xad, 0xea, 0xec, 0xb4, 0x75, 0x07,
-       0x7e, 0xb5, 0x52, 0x79, 0x2c, 0xdd, 0x8e, 0x7c, 0x3f, 0x29, 0x5f, 0xb6,
-       0x98, 0xf3, 0x1a, 0x56, 0xae, 0x7b, 0x26, 0x12, 0x8e, 0x63, 0x0b, 0xd7,
-       0xf4, 0x11, 0x2b, 0x79, 0x3f, 0xac, 0xfc, 0xc4, 0x78, 0xe4, 0x6a, 0xbc,
-       0xdf, 0x5f, 0xe5, 0xfd, 0x9d, 0x0d, 0xd2, 0xd0, 0xaf, 0xea, 0x0b, 0xb9,
-       0xee, 0xaf, 0x13, 0xcb, 0xd2, 0xf0, 0xf3, 0xf0, 0xc7, 0x15, 0xb9, 0x3f,
-       0x7d, 0xa5, 0x72, 0xd1, 0xdd, 0x20, 0x85, 0xed, 0x07, 0x34, 0x9e, 0x1f,
-       0x78, 0x32, 0xe7, 0x16, 0x61, 0x1f, 0xfa, 0xdb, 0xc2, 0x64, 0x0c, 0x51,
-       0x29, 0xff, 0x9a, 0x65, 0xae, 0xf7, 0xf6, 0x7a, 0x69, 0xd8, 0xf6, 0x02,
-       0x8b, 0x63, 0xc4, 0x99, 0x39, 0x27, 0xae, 0xea, 0xdd, 0x37, 0xb9, 0xec,
-       0xb7, 0x21, 0xd3, 0xdf, 0x92, 0x39, 0xc4, 0x13, 0xf3, 0xbd, 0xa0, 0x71,
-       0x7b, 0x0b, 0xc6, 0xd3, 0xee, 0xc8, 0xf3, 0xdf, 0x96, 0xa1, 0x41, 0xf2,
-       0xd4, 0xc1, 0xf8, 0xfb, 0x31, 0xa6, 0x19, 0xd7, 0x07, 0x23, 0x73, 0x76,
-       0xcc, 0x6f, 0x0f, 0x70, 0x0e, 0xfa, 0x52, 0xce, 0xc3, 0xb5, 0x5a, 0x94,
-       0xcd, 0x2f, 0xcd, 0xcf, 0xb9, 0xf9, 0xec, 0xe3, 0xca, 0xbe, 0xee, 0xee,
-       0xd0, 0x1a, 0x4d, 0xa1, 0x35, 0x7a, 0x42, 0x6b, 0x90, 0xb6, 0xe6, 0x10,
-       0x6d, 0xcd, 0x78, 0xff, 0x3e, 0xac, 0xd7, 0xaf, 0xe3, 0x94, 0x60, 0x9d,
-       0x60, 0x1f, 0x2d, 0xa1, 0xb1, 0x1f, 0x62, 0x0d, 0xf6, 0x39, 0xa1, 0x3e,
-       0xae, 0x0b, 0x1c, 0x73, 0xd8, 0x6e, 0x0e, 0xd1, 0x42, 0xfa, 0x1a, 0xd0,
-       0xaf, 0xe6, 0x02, 0x3f, 0x1b, 0xe0, 0xbb, 0x4c, 0xf8, 0x8f, 0x08, 0xe2,
-       0xaa, 0x60, 0x4f, 0xc1, 0x1c, 0x0e, 0xde, 0xe3, 0x18, 0xff, 0xb9, 0xff,
-       0x0e, 0xfb, 0xf9, 0x3c, 0x22, 0xdf, 0x53, 0xf4, 0xb2, 0xcd, 0x3d, 0x34,
-       0x81, 0x56, 0x5e, 0x53, 0x32, 0xdb, 0x0c, 0xd9, 0x77, 0x33, 0x9f, 0x36,
-       0xe4, 0x36, 0xd7, 0x34, 0xf2, 0xdd, 0x94, 0xef, 0x06, 0x8d, 0x97, 0x0d,
-       0x46, 0xee, 0x34, 0x6b, 0x08, 0x8d, 0x3a, 0xf7, 0x43, 0xbe, 0xa1, 0x7c,
-       0x4c, 0xe0, 0x03, 0xe8, 0x63, 0x18, 0xab, 0xd0, 0x7f, 0x66, 0xf5, 0x3d,
-       0xae, 0xd0, 0xd3, 0xc3, 0xf3, 0xcd, 0x72, 0x51, 0xf1, 0xd0, 0x96, 0xc5,
-       0x2a, 0x0f, 0xa3, 0xfa, 0xbb, 0xd1, 0x31, 0xfd, 0x4d, 0x66, 0x3f, 0xe2,
-       0x01, 0xdc, 0x97, 0x80, 0xb9, 0xdd, 0xd0, 0xb7, 0x6e, 0xe6, 0x70, 0x45,
-       0x5c, 0x59, 0xc3, 0x30, 0x70, 0x75, 0x70, 0x8d, 0xe1, 0x0a, 0xbf, 0x04,
-       0xac, 0xc9, 0x77, 0xbf, 0x0d, 0x1d, 0x82, 0x6c, 0xca, 0xb6, 0x71, 0xbf,
-       0xe7, 0xd7, 0x87, 0x16, 0xdd, 0xd5, 0xeb, 0x43, 0x8b, 0xa2, 0xea, 0x43,
-       0x13, 0xd7, 0xa8, 0x0f, 0x65, 0xaf, 0xbf, 0x3e, 0x74, 0xa2, 0x9e, 0x18,
-       0xbc, 0xb7, 0x47, 0x8c, 0xdf, 0xd5, 0xf5, 0xa1, 0xf7, 0xc5, 0xaf, 0x0f,
-       0x5d, 0x94, 0xd5, 0xeb, 0x43, 0x13, 0x35, 0xf5, 0xa1, 0x8d, 0xaa, 0x3e,
-       0xc4, 0x79, 0xfc, 0xfa, 0x10, 0xdb, 0x6d, 0xdd, 0xbd, 0xa1, 0x3a, 0x08,
-       0xf0, 0x54, 0xe5, 0x84, 0xb6, 0x31, 0xe8, 0x05, 0x18, 0x45, 0x2c, 0xbf,
-       0xb9, 0xea, 0x8f, 0x96, 0xf0, 0xca, 0x50, 0xba, 0x75, 0x2d, 0xbc, 0x1a,
-       0xf4, 0x63, 0x90, 0x65, 0x58, 0x35, 0x5e, 0x8d, 0x53, 0x5e, 0xab, 0x67,
-       0xde, 0x3c, 0x56, 0x5a, 0x9a, 0x77, 0x0c, 0xb2, 0x1d, 0xaa, 0xd6, 0x50,
-       0xd6, 0x8a, 0x85, 0x1c, 0x39, 0xb6, 0xea, 0x37, 0xb8, 0x44, 0x76, 0xe5,
-       0x37, 0x38, 0x43, 0x1c, 0xd0, 0xd9, 0xd6, 0x5d, 0x50, 0x79, 0xd5, 0x9c,
-       0xf7, 0x55, 0xb9, 0xf0, 0xb0, 0x0d, 0x3c, 0x09, 0x6a, 0x26, 0x94, 0xe5,
-       0x92, 0x8f, 0x28, 0x98, 0x9f, 0x5f, 0xdd, 0xe4, 0xb0, 0xaa, 0x9b, 0xfc,
-       0xbc, 0x3e, 0x5c, 0x37, 0x59, 0x94, 0xab, 0xd7, 0x4d, 0x0e, 0xaf, 0x52,
-       0x37, 0x79, 0x53, 0x96, 0xea, 0x26, 0x6f, 0x4a, 0x50, 0x37, 0x89, 0xc8,
-       0x85, 0x4d, 0x9c, 0xe7, 0x08, 0xde, 0x19, 0xc0, 0xaf, 0x1f, 0x3f, 0xbf,
-       0x8e, 0xb2, 0x58, 0xa5, 0x7f, 0xb5, 0x3a, 0x4a, 0x7d, 0xec, 0x93, 0xd4,
-       0x51, 0x7c, 0x4c, 0x0f, 0xea, 0x28, 0x0d, 0x88, 0x5f, 0xe0, 0x43, 0xcc,
-       0x70, 0x1d, 0xa5, 0x15, 0xf3, 0xb2, 0x8f, 0x6d, 0xf6, 0xc3, 0x2e, 0xe0,
-       0x67, 0xb2, 0xaa, 0xce, 0xf1, 0x9b, 0x9a, 0x87, 0x07, 0xb0, 0xe7, 0x24,
-       0x64, 0x41, 0x3e, 0xb6, 0xab, 0x38, 0x32, 0x6b, 0x25, 0x8c, 0x5c, 0x27,
-       0xbc, 0xd3, 0x24, 0xbf, 0xd9, 0x27, 0x64, 0xa4, 0x4c, 0x1d, 0x6f, 0x45,
-       0xdc, 0x6d, 0xa1, 0xef, 0x00, 0xda, 0x41, 0x8c, 0xd4, 0x5d, 0x9d, 0x83,
-       0x76, 0x38, 0xc7, 0x7a, 0x9f, 0x73, 0x3d, 0x3e, 0x67, 0x27, 0x68, 0x0e,
-       0xef, 0xa3, 0x08, 0x7f, 0x83, 0x3e, 0x25, 0x73, 0xc6, 0x8a, 0x01, 0x2d,
-       0x49, 0xda, 0xf4, 0x75, 0xcc, 0xc7, 0xbe, 0x9d, 0x2a, 0xdf, 0x1a, 0xee,
-       0xe1, 0x5e, 0xe9, 0xbb, 0x16, 0x40, 0x1f, 0xfa, 0xe6, 0x99, 0xe3, 0xd1,
-       0x8f, 0x05, 0x39, 0x58, 0x5c, 0xe5, 0x60, 0x2d, 0x8a, 0x1f, 0xe4, 0xf5,
-       0x23, 0x31, 0xe2, 0x63, 0x8b, 0xcb, 0x3d, 0xf4, 0x6b, 0x5c, 0x63, 0xdb,
-       0xcf, 0xf5, 0x58, 0x8f, 0x6e, 0x71, 0x9f, 0x80, 0x5c, 0x59, 0xab, 0x09,
-       0xe4, 0xf7, 0x0d, 0xbd, 0xef, 0x5e, 0x29, 0xb6, 0x48, 0x6c, 0x23, 0xe8,
-       0x69, 0x9b, 0x62, 0x8c, 0x7d, 0x8f, 0xca, 0x37, 0x1c, 0x77, 0x6d, 0xbb,
-       0xdd, 0x7f, 0x03, 0x76, 0x3b, 0x70, 0x55, 0xbb, 0x3d, 0x1b, 0x0b, 0xdb,
-       0xed, 0xfe, 0x1b, 0xb0, 0xdb, 0x23, 0x37, 0x64, 0xb7, 0xdc, 0x1b, 0x31,
-       0x29, 0xa8, 0x8b, 0xad, 0x8c, 0x9b, 0x82, 0x75, 0x47, 0xb1, 0x66, 0x76,
-       0x8d, 0x35, 0x87, 0xd6, 0xac, 0xbb, 0xd6, 0xc6, 0x4c, 0xd7, 0x23, 0x6f,
-       0xe6, 0x21, 0xf4, 0xab, 0x71, 0xed, 0x83, 0x9e, 0xd6, 0x3a, 0x1f, 0xe4,
-       0xed, 0x61, 0xfb, 0xa1, 0x5e, 0x50, 0x17, 0x7e, 0x02, 0x7e, 0x51, 0x1f,
-       0x02, 0x9b, 0x6b, 0xaf, 0xd1, 0xc1, 0x05, 0xe4, 0xf3, 0xed, 0x5a, 0x07,
-       0x29, 0xeb, 0x4e, 0xf5, 0x3d, 0x69, 0xde, 0x7b, 0xc2, 0xcf, 0xe3, 0xa1,
-       0x03, 0x85, 0xf9, 0xc0, 0xd6, 0x92, 0x58, 0x37, 0x78, 0x46, 0x3e, 0xba,
-       0x88, 0x61, 0xb6, 0x21, 0xfe, 0x02, 0x8f, 0x54, 0xff, 0xf2, 0x3a, 0xf0,
-       0xd5, 0xf1, 0x4c, 0x8a, 0x51, 0x8c, 0x7d, 0xae, 0x07, 0x36, 0xde, 0x43,
-       0x8c, 0xca, 0x20, 0x8f, 0xa1, 0x1e, 0x52, 0x37, 0x3b, 0xba, 0x0e, 0x99,
-       0x8c, 0x91, 0x0e, 0xc2, 0xf6, 0x6c, 0xa5, 0xc7, 0xbb, 0xcb, 0x1d, 0xe7,
-       0x16, 0x4d, 0xae, 0x51, 0xa9, 0x14, 0x54, 0xbd, 0x5e, 0xcc, 0x5c, 0xf7,
-       0x4d, 0xeb, 0xe8, 0x97, 0x6e, 0x76, 0x23, 0x5a, 0xd7, 0xb2, 0xb8, 0xa7,
-       0xde, 0xfe, 0x2b, 0x7c, 0x3b, 0xf2, 0x89, 0xee, 0x7f, 0x41, 0x7f, 0x02,
-       0x36, 0x4f, 0x5f, 0xce, 0xfc, 0x62, 0x87, 0x1e, 0xd7, 0xae, 0xbe, 0x95,
-       0xaa, 0xef, 0x2d, 0x4e, 0xe0, 0x7f, 0x52, 0xf4, 0xcf, 0xcb, 0xe4, 0xcc,
-       0xb3, 0x1b, 0x79, 0x95, 0x9f, 0xf0, 0x7d, 0xa5, 0x93, 0xc8, 0x29, 0xac,
-       0x50, 0x9d, 0x3d, 0xa6, 0x73, 0x31, 0xda, 0x58, 0x5c, 0xe5, 0x89, 0x7e,
-       0xee, 0xc1, 0x5c, 0x75, 0xf9, 0x99, 0x8d, 0xd5, 0x75, 0x60, 0xf3, 0x27,
-       0xd0, 0x81, 0x5a, 0xf9, 0xc5, 0x60, 0xfb, 0x81, 0xfc, 0x82, 0x98, 0x65,
-       0x56, 0xef, 0xbb, 0xdd, 0x97, 0xe1, 0xff, 0x8b, 0x7d, 0x1a, 0xa1, 0x7d,
-       0x06, 0x78, 0x74, 0x58, 0xef, 0x73, 0x47, 0x0d, 0x1e, 0x0d, 0xd4, 0xd8,
-       0xec, 0xe7, 0x89, 0x47, 0x97, 0xd7, 0x7d, 0xfe, 0x78, 0xc4, 0x7d, 0x6d,
-       0x59, 0x15, 0x87, 0xfc, 0x7d, 0x3c, 0x2d, 0x66, 0xe6, 0xb3, 0xcc, 0xdf,
-       0x3e, 0x89, 0x7c, 0xc2, 0x38, 0x42, 0x99, 0x34, 0xa9, 0x78, 0xd5, 0xb7,
-       0x3d, 0xf8, 0xf2, 0xf9, 0xa8, 0xbc, 0xf7, 0x50, 0x4c, 0x7e, 0x75, 0x2f,
-       0xbf, 0x95, 0x59, 0xba, 0x7e, 0xc5, 0x76, 0xb4, 0xc1, 0xf7, 0x43, 0x48,
-       0x24, 0x94, 0xdf, 0xe1, 0x3b, 0x81, 0x3d, 0xdb, 0x78, 0xce, 0x67, 0x5b,
-       0xe4, 0x42, 0xf3, 0x8d, 0xe4, 0x74, 0x1d, 0xf6, 0xfb, 0xe6, 0x6a, 0x39,
-       0xdd, 0xd5, 0x6b, 0x7f, 0x4b, 0x39, 0x1d, 0x71, 0xb6, 0x59, 0xd7, 0x7b,
-       0x98, 0xd7, 0xec, 0xd7, 0xd8, 0xc9, 0x7b, 0xe4, 0xaa, 0x1e, 0xf2, 0x57,
-       0xc8, 0xf6, 0x35, 0xc4, 0x4b, 0xaf, 0x7a, 0xc8, 0x59, 0x3d, 0xe4, 0xaa,
-       0x1e, 0x72, 0x55, 0x0f, 0xb9, 0xaa, 0xd7, 0xa5, 0x73, 0xde, 0x01, 0x5d,
-       0xd7, 0xe7, 0xf7, 0x70, 0xd6, 0x0b, 0x8a, 0xf0, 0x25, 0xe3, 0x3c, 0x63,
-       0x61, 0xe6, 0xd2, 0xeb, 0x82, 0x73, 0x48, 0xba, 0xe6, 0xdd, 0xaa, 0x6b,
-       0x30, 0x75, 0x37, 0x29, 0xdf, 0x6c, 0xbe, 0xd1, 0xe0, 0x7f, 0x33, 0xe7,
-       0xf9, 0x8f, 0x3f, 0x44, 0x5c, 0xc2, 0x1a, 0xd8, 0x04, 0x6d, 0xb4, 0x62,
-       0x66, 0x58, 0x63, 0x11, 0xd3, 0xcc, 0x7c, 0x01, 0xef, 0x6c, 0xc3, 0x1e,
-       0xea, 0x69, 0xdb, 0x11, 0x33, 0xd3, 0x48, 0x9e, 0x1a, 0x66, 0x66, 0xbd,
-       0x9e, 0xeb, 0x6f, 0x1a, 0xfc, 0xd8, 0xaa, 0x93, 0x6d, 0xcb, 0x64, 0x9c,
-       0xa0, 0x62, 0xed, 0xa0, 0x7f, 0x4f, 0xf3, 0xf2, 0xb5, 0xa2, 0x0a, 0xdf,
-       0x73, 0xe9, 0x87, 0x31, 0x9f, 0x3a, 0xdb, 0x54, 0xe5, 0xb7, 0xb9, 0x26,
-       0xbf, 0xa3, 0x9a, 0xdf, 0x3e, 0x8f, 0x23, 0x1c, 0xa7, 0xea, 0xbe, 0xe4,
-       0x75, 0x30, 0x9f, 0xaa, 0xe1, 0x61, 0x1d, 0x75, 0x8e, 0x03, 0xd7, 0xbb,
-       0xa2, 0xd2, 0x34, 0x78, 0x20, 0xea, 0x86, 0xd7, 0x25, 0x46, 0xf5, 0x2e,
-       0xfb, 0xfe, 0xb4, 0xf6, 0x9a, 0xed, 0xea, 0xdb, 0x99, 0xef, 0x33, 0xa2,
-       0x4a, 0x07, 0x2d, 0x75, 0x36, 0xef, 0xd7, 0xea, 0xcc, 0x0d, 0xf5, 0x2f,
-       0x8f, 0x3c, 0x66, 0xbc, 0xa7, 0x23, 0x69, 0x99, 0x7f, 0xd1, 0xc0, 0x5a,
-       0x6b, 0x5f, 0x39, 0xc0, 0x3d, 0xae, 0x57, 0xeb, 0xc7, 0x59, 0x27, 0x0b,
-       0xf0, 0x4c, 0x36, 0xfb, 0xf5, 0xb3, 0x4f, 0x63, 0x4b, 0x0d, 0x35, 0xb6,
-       0x14, 0xec, 0xd3, 0xcf, 0x57, 0xf9, 0xdd, 0x7a, 0xb5, 0xb3, 0x13, 0x0b,
-       0xe5, 0xd0, 0xf7, 0x8f, 0xaa, 0x6e, 0xf0, 0x5c, 0xcb, 0x83, 0xd0, 0x41,
-       0xd6, 0xfe, 0xf7, 0xc0, 0x8e, 0x2a, 0x95, 0x3e, 0xd6, 0x93, 0xb7, 0x3f,
-       0xa0, 0xcf, 0x27, 0x3c, 0xa3, 0xea, 0x09, 0xd6, 0x8a, 0x7a, 0x42, 0x1f,
-       0x74, 0x05, 0x31, 0x00, 0x6c, 0xb0, 0xa0, 0x64, 0xc9, 0x78, 0xa0, 0xf6,
-       0xfb, 0xca, 0xf9, 0x46, 0x9f, 0x0f, 0xb7, 0x37, 0xfa, 0xdf, 0x18, 0x7e,
-       0xe9, 0x2c, 0x6f, 0xf3, 0xfd, 0x44, 0x63, 0x70, 0xce, 0x67, 0xf8, 0x4c,
-       0x1f, 0x74, 0xb1, 0x4e, 0xf2, 0x6a, 0x3e, 0xc4, 0xbb, 0xcf, 0xff, 0xac,
-       0x79, 0xf9, 0x78, 0xf4, 0x9d, 0x09, 0xc6, 0x37, 0xd7, 0x8c, 0x6f, 0xc6,
-       0xf8, 0x7f, 0xaf, 0x19, 0xdf, 0x1c, 0x1a, 0xef, 0xd4, 0x8c, 0x77, 0x30,
-       0xbe, 0x7e, 0xd3, 0xf2, 0xf1, 0x4e, 0x68, 0x7c, 0x4b, 0xcd, 0xf8, 0x16,
-       0x8c, 0x6f, 0xa8, 0x19, 0x8f, 0xbe, 0x33, 0x75, 0xfa, 0xbb, 0x17, 0x31,
-       0xf6, 0x88, 0xce, 0xbb, 0x71, 0x2d, 0xd5, 0x7e, 0x4b, 0xa1, 0xde, 0xb5,
-       0x42, 0x06, 0xc1, 0x39, 0x3b, 0xda, 0x6b, 0x16, 0xf6, 0xba, 0x14, 0xcb,
-       0xf8, 0xfa, 0x18, 0xd6, 0x45, 0xe2, 0x43, 0x51, 0x22, 0x2e, 0x74, 0x67,
-       0x1e, 0x3a, 0x34, 0x1f, 0xf8, 0x24, 0x9e, 0x99, 0x4a, 0x75, 0xf9, 0x7a,
-       0x6a, 0x48, 0xd4, 0x5d, 0xd0, 0x39, 0xd8, 0x4e, 0xd2, 0x0e, 0xbc, 0x0c,
-       0x30, 0x53, 0x4e, 0xf9, 0x76, 0x43, 0xfd, 0xe5, 0xfc, 0xda, 0x7e, 0xa8,
-       0xab, 0x7a, 0x9d, 0xbe, 0x15, 0xb8, 0x96, 0x5c, 0x51, 0xab, 0x8a, 0x5c,
-       0x07, 0xae, 0x0d, 0x54, 0x71, 0xed, 0x41, 0x99, 0xad, 0xe6, 0xdb, 0xfd,
-       0x72, 0xd4, 0xdb, 0xcb, 0xf3, 0x38, 0xa7, 0xb2, 0xf2, 0xd9, 0xe4, 0xdb,
-       0x7b, 0xab, 0x7e, 0x32, 0x35, 0x91, 0x95, 0x0b, 0xc7, 0x99, 0x43, 0x05,
-       0xb5, 0xd6, 0x71, 0xef, 0x5b, 0x94, 0x0b, 0x6c, 0xe3, 0x46, 0xf3, 0x6d,
-       0xce, 0xe7, 0xc8, 0x51, 0xff, 0x2c, 0x44, 0x75, 0xde, 0x62, 0x75, 0xde,
-       0x84, 0xb6, 0x37, 0xfa, 0xe0, 0x25, 0x7f, 0x99, 0x87, 0xbf, 0x1c, 0x42,
-       0xce, 0xbd, 0xe0, 0xad, 0x56, 0xef, 0xbc, 0x51, 0x7f, 0x59, 0x5b, 0x37,
-       0xae, 0xf5, 0x97, 0x5c, 0xa7, 0xb6, 0x56, 0x9c, 0xac, 0xc1, 0x7f, 0xea,
-       0xd3, 0x53, 0x3a, 0xa6, 0xc6, 0x75, 0xfe, 0x29, 0xd8, 0xa3, 0x29, 0x43,
-       0x4a, 0x7f, 0xd9, 0x0e, 0x72, 0xcb, 0x03, 0xd5, 0xdc, 0x72, 0x29, 0x1f,
-       0x44, 0xec, 0xda, 0x75, 0x9f, 0xc6, 0x47, 0xc6, 0xc8, 0xe3, 0xe8, 0x3f,
-       0x05, 0x1d, 0xe0, 0x33, 0xd6, 0x3f, 0xef, 0x90, 0x2f, 0x5b, 0xbe, 0x7f,
-       0xf2, 0xeb, 0x50, 0x07, 0x54, 0xfc, 0xcf, 0xfa, 0xff, 0x70, 0x7a, 0xa3,
-       0x8e, 0xf7, 0xae, 0x85, 0xab, 0xcb, 0x73, 0x53, 0xd3, 0x3c, 0x81, 0x77,
-       0x99, 0x9b, 0x3e, 0x10, 0x27, 0x86, 0xe6, 0xca, 0x57, 0x7d, 0xbf, 0x48,
-       0xff, 0x32, 0xac, 0xbe, 0xfb, 0xa9, 0x3c, 0x14, 0xe3, 0x16, 0xf4, 0xfb,
-       0x7e, 0x1e, 0x9a, 0x2b, 0x6f, 0x89, 0xfb, 0x38, 0x78, 0xb5, 0x9c, 0xe5,
-       0x58, 0x9c, 0xb5, 0xbc, 0x05, 0xef, 0x5a, 0xb4, 0xae, 0xcc, 0x7b, 0x23,
-       0x2b, 0xf2, 0xde, 0x41, 0x9d, 0xd7, 0x7e, 0x45, 0xe5, 0xbd, 0x3e, 0x8f,
-       0xb9, 0x97, 0x70, 0x1e, 0xe5, 0x02, 0x0b, 0xf9, 0x8d, 0x84, 0xf8, 0x30,
-       0xaa, 0xfc, 0x56, 0x61, 0xf2, 0x77, 0xd4, 0xf9, 0x89, 0x95, 0x7a, 0xf3,
-       0x79, 0xfb, 0x89, 0x60, 0xef, 0x4f, 0x89, 0x5f, 0xaf, 0xdb, 0x03, 0x5a,
-       0x98, 0x5b, 0x45, 0xb5, 0x3e, 0xa4, 0x34, 0x5e, 0x07, 0xe3, 0x82, 0x3c,
-       0xbe, 0xfa, 0x5d, 0xb5, 0x98, 0x5d, 0x56, 0x3f, 0xd9, 0x42, 0x18, 0x86,
-       0xdc, 0xb3, 0x37, 0xf0, 0x1d, 0xe2, 0xd3, 0x9c, 0x7f, 0xa8, 0xf5, 0x6b,
-       0xfc, 0x46, 0xda, 0xaa, 0xcf, 0xc7, 0xb9, 0xb0, 0x01, 0x9e, 0x65, 0x0e,
-       0xe3, 0xab, 0x3a, 0x03, 0x17, 0x73, 0x32, 0x62, 0xec, 0x23, 0x7d, 0xe9,
-       0x7f, 0xd6, 0xfb, 0x4c, 0xc8, 0x91, 0x29, 0xbf, 0xbe, 0x69, 0xae, 0x71,
-       0xfe, 0xcd, 0x34, 0xaf, 0xab, 0xbe, 0x79, 0x03, 0xe7, 0xdf, 0x5e, 0x8f,
-       0x07, 0xf5, 0xcd, 0xda, 0xf3, 0x6f, 0x91, 0xeb, 0x3c, 0xff, 0xe6, 0xd7,
-       0x37, 0x39, 0x4f, 0xb8, 0xbe, 0x79, 0x8f, 0x3a, 0x43, 0x36, 0x3a, 0xd5,
-       0xa3, 0xce, 0x23, 0xb7, 0x75, 0xaf, 0x8d, 0xb3, 0xfb, 0x3e, 0xb3, 0x7c,
-       0xe4, 0x3f, 0xe3, 0xe1, 0x7c, 0x64, 0xdf, 0xe7, 0x92, 0x8f, 0x70, 0x2f,
-       0xbf, 0xef, 0x7f, 0xb7, 0xad, 0x39, 0xfb, 0x95, 0xfb, 0x1c, 0x6b, 0x98,
-       0x47, 0x54, 0x0d, 0x73, 0xcb, 0xfa, 0x70, 0x0d, 0xd3, 0xbc, 0xc6, 0xd9,
-       0xaf, 0x23, 0xab, 0xd4, 0x30, 0xa3, 0xa1, 0xb3, 0x5f, 0x51, 0x7d, 0xf6,
-       0x6b, 0xa3, 0x8b, 0xbc, 0x51, 0xd7, 0x2c, 0xcd, 0xab, 0x9e, 0xfd, 0xea,
-       0x59, 0xff, 0x49, 0x6a, 0x96, 0xb9, 0x65, 0x35, 0xcb, 0x15, 0x67, 0xbf,
-       0xe0, 0xd7, 0x36, 0x4b, 0x32, 0x94, 0xe3, 0xe4, 0x6e, 0xf0, 0x6c, 0x43,
-       0xfe, 0x3a, 0xe2, 0x80, 0x7d, 0x55, 0x5b, 0xe5, 0xd9, 0xfd, 0x3a, 0xec,
-       0x39, 0x2a, 0x7b, 0x1d, 0xea, 0x27, 0xcf, 0x38, 0x76, 0xc2, 0x16, 0x70,
-       0x2d, 0xb3, 0xdd, 0x45, 0x19, 0x19, 0x03, 0x9d, 0xcb, 0xcf, 0x17, 0x2c,
-       0x9d, 0xd3, 0x8d, 0x55, 0xcf, 0xe9, 0x9e, 0x84, 0xde, 0x98, 0x53, 0x31,
-       0x99, 0x0b, 0xe9, 0xd4, 0x38, 0x62, 0x3b, 0x73, 0xc6, 0xd6, 0xcf, 0x93,
-       0x12, 0x99, 0x72, 0x80, 0x6f, 0x3c, 0xdb, 0xdb, 0x24, 0x91, 0x19, 0xff,
-       0x7b, 0xa3, 0xa9, 0xf0, 0x33, 0x81, 0x31, 0x3c, 0xdb, 0x19, 0x95, 0xa3,
-       0xaa, 0x3e, 0x11, 0xe8, 0xf2, 0x37, 0xc1, 0xe3, 0x4d, 0xd9, 0xa5, 0xb6,
-       0xb3, 0x8a, 0x8f, 0x47, 0xcc, 0x38, 0x45, 0x7d, 0xbe, 0x5b, 0xf2, 0xba,
-       0xf6, 0x33, 0x5c, 0xde, 0xa9, 0x73, 0x09, 0xf5, 0xcd, 0x06, 0xbc, 0x6c,
-       0xd3, 0xfe, 0x16, 0xd7, 0xf9, 0x36, 0xfa, 0x37, 0xc6, 0xcc, 0xd2, 0x37,
-       0xb9, 0x2d, 0x31, 0x02, 0x6c, 0x1b, 0x52, 0x6b, 0xde, 0x08, 0xcf, 0x8d,
-       0x15, 0xf1, 0xd7, 0x8d, 0xf1, 0x3d, 0x88, 0x85, 0xdf, 0xc4, 0xfe, 0xda,
-       0xa0, 0x1f, 0x8f, 0x4b, 0xfe, 0xcc, 0x1d, 0xd2, 0x37, 0x9d, 0x02, 0x3d,
-       0xbf, 0xae, 0x0c, 0xa7, 0x11, 0x37, 0x3f, 0xcf, 0x33, 0x60, 0xc0, 0x4b,
-       0xf0, 0xed, 0x95, 0x15, 0xdf, 0xa0, 0xc3, 0xe7, 0xc6, 0xba, 0xaa, 0xe7,
-       0x80, 0x5e, 0x2a, 0x4b, 0xac, 0x99, 0x34, 0x4f, 0x2d, 0x9d, 0x09, 0x5f,
-       0x28, 0xef, 0x56, 0x7e, 0xec, 0xc5, 0xf2, 0xff, 0x52, 0x77, 0x6d, 0xb1,
-       0x6d, 0x9d, 0xf7, 0xfd, 0xcf, 0x43, 0xea, 0x12, 0xdd, 0x7c, 0x24, 0xd3,
-       0x32, 0x2d, 0xd1, 0xf2, 0x39, 0xd2, 0xb1, 0xc5, 0xd8, 0x5a, 0xc7, 0x6a,
-       0xca, 0x26, 0xac, 0x5a, 0xc2, 0x52, 0xf4, 0x65, 0x59, 0x36, 0xd0, 0x97,
-       0x76, 0x1e, 0x16, 0xa0, 0x0e, 0x65, 0x3b, 0x1d, 0xd0, 0x07, 0xb7, 0xd9,
-       0x80, 0xa4, 0x03, 0x6c, 0x96, 0xb2, 0x1c, 0xaf, 0x53, 0x4d, 0x36, 0x66,
-       0xd5, 0xac, 0x1b, 0x50, 0x4e, 0x92, 0x9d, 0xb4, 0x50, 0xc0, 0x64, 0xbd,
-       0x60, 0xd8, 0x43, 0xad, 0xc9, 0xf6, 0xf6, 0xb2, 0x87, 0x6c, 0xd8, 0x83,
-       0x81, 0x0d, 0x98, 0x63, 0x05, 0x68, 0x96, 0x02, 0x49, 0x87, 0x15, 0x43,
-       0x1e, 0x36, 0x70, 0xff, 0xdf, 0x77, 0x21, 0x0f, 0x0f, 0x0f, 0x75, 0x89,
-       0x9d, 0x01, 0x33, 0x60, 0x88, 0xe7, 0x9c, 0xef, 0x9c, 0xf3, 0x7d, 0xff,
-       0xef, 0x7f, 0xbf, 0x9d, 0x3a, 0x3f, 0x8f, 0xd8, 0xc3, 0xdc, 0xca, 0x5b,
-       0x0c, 0x8b, 0xbb, 0x42, 0x96, 0xcd, 0xe5, 0x69, 0x28, 0x48, 0xd8, 0x0f,
-       0x0a, 0x30, 0x0c, 0x44, 0x6e, 0x86, 0x8c, 0xcd, 0x47, 0xc5, 0xbe, 0x4a,
-       0x5e, 0x71, 0xcc, 0x95, 0x5b, 0x51, 0xdb, 0x5b, 0x99, 0x73, 0x21, 0xf7,
-       0x42, 0xe6, 0x85, 0x00, 0x9e, 0xab, 0x17, 0x8f, 0x3b, 0x32, 0x2f, 0x64,
-       0x64, 0x01, 0xe7, 0xfa, 0x3d, 0x72, 0xae, 0x9d, 0x71, 0x00, 0x39, 0x44,
-       0xc8, 0x05, 0xc7, 0x9c, 0x85, 0x5f, 0xc3, 0x37, 0x2e, 0xbd, 0x3d, 0xff,
-       0xaa, 0x7c, 0xe7, 0xb0, 0x78, 0xe7, 0x2e, 0xc5, 0xb3, 0x74, 0x0e, 0x78,
-       0x3c, 0x30, 0x93, 0x1f, 0x8d, 0x04, 0x19, 0xbf, 0x67, 0xca, 0xb0, 0xa5,
-       0x9b, 0xe9, 0x6b, 0x1b, 0xc1, 0x33, 0xd1, 0x00, 0xcf, 0x7a, 0x9a, 0x60,
-       0xdb, 0xbb, 0xca, 0xbb, 0x25, 0xec, 0xe4, 0x79, 0xe4, 0xb7, 0xeb, 0xfc,
-       0x04, 0x09, 0xbb, 0x2a, 0x0d, 0x5d, 0x73, 0xe7, 0x26, 0xd4, 0x60, 0x77,
-       0xa6, 0x0a, 0xbb, 0xdd, 0xff, 0x8f, 0x60, 0x77, 0x4f, 0xe8, 0xba, 0x6f,
-       0x95, 0x91, 0x83, 0xa6, 0xe5, 0xbd, 0xae, 0x5d, 0x02, 0x1c, 0xc1, 0x4f,
-       0xed, 0xd2, 0x2a, 0x81, 0xa7, 0x22, 0x6f, 0xb8, 0x52, 0xf9, 0x41, 0xbc,
-       0xea, 0x93, 0x64, 0x1b, 0x04, 0xb6, 0x08, 0x7c, 0x77, 0xcd, 0x65, 0xe4,
-       0xf1, 0x8f, 0x25, 0x23, 0xa1, 0x17, 0x79, 0x6d, 0x91, 0x1f, 0xf5, 0xb8,
-       0x6d, 0x91, 0xe3, 0xdb, 0xb4, 0x45, 0x2e, 0x48, 0x5b, 0x24, 0xbb, 0x75,
-       0x5b, 0x64, 0xa0, 0x21, 0x5f, 0xab, 0xb6, 0x9e, 0xed, 0xdb, 0x22, 0xc6,
-       0x86, 0xb6, 0xc8, 0x88, 0xcb, 0xef, 0x82, 0xf9, 0xfe, 0x2e, 0x65, 0x4f,
-       0x80, 0xc7, 0x69, 0x38, 0x03, 0xc6, 0x27, 0x3c, 0x3e, 0xe0, 0x4f, 0x12,
-       0xd6, 0xe6, 0x8e, 0xff, 0x5b, 0x58, 0x0f, 0x36, 0xf8, 0xb7, 0x6b, 0xeb,
-       0xa1, 0xf0, 0xce, 0x6d, 0xe9, 0xec, 0x5e, 0x58, 0x0f, 0x36, 0xf5, 0x93,
-       0x36, 0xcf, 0x45, 0xac, 0xf7, 0x93, 0x0e, 0x1b, 0xcd, 0x78, 0xfb, 0x77,
-       0x5d, 0xfe, 0x53, 0x37, 0x7f, 0x07, 0x4d, 0x51, 0xe0, 0xf8, 0xa8, 0x7e,
-       0x17, 0x68, 0xc9, 0xce, 0x66, 0x09, 0xf6, 0x11, 0xde, 0x17, 0x11, 0xb4,
-       0xe6, 0xd1, 0xb7, 0xf8, 0x7d, 0xbc, 0xbe, 0xd7, 0x9e, 0x15, 0x72, 0x4a,
-       0xfa, 0x1a, 0x30, 0x3e, 0x16, 0x38, 0x2b, 0xc6, 0xca, 0xdc, 0x24, 0xe5,
-       0x7b, 0x50, 0x7a, 0x7e, 0x33, 0x9f, 0x43, 0xa3, 0xcc, 0xdb, 0x9e, 0x5d,
-       0xa0, 0x69, 0x7c, 0x1f, 0xef, 0x4b, 0xa4, 0xce, 0xae, 0x02, 0xff, 0xbc,
-       0xc0, 0x7a, 0xc1, 0x70, 0x55, 0x27, 0xa8, 0xdf, 0x9b, 0xcb, 0xc2, 0x7e,
-       0xd3, 0xbc, 0x33, 0x2d, 0xf2, 0xdd, 0x24, 0xef, 0x84, 0x9e, 0xa6, 0x79,
-       0xa7, 0x57, 0x0f, 0xde, 0xe7, 0x83, 0x17, 0xbe, 0x75, 0xa7, 0x7a, 0xef,
-       0x2c, 0xe4, 0x8f, 0xa7, 0x7c, 0xf7, 0xae, 0x5a, 0x77, 0x95, 0xad, 0x8d,
-       0x95, 0xf7, 0xa7, 0xc4, 0xba, 0xa2, 0x4f, 0x27, 0x51, 0x13, 0x57, 0xad,
-       0x09, 0xf2, 0xd6, 0x41, 0x41, 0x0e, 0x68, 0x3a, 0xd4, 0x75, 0xe2, 0x80,
-       0x45, 0xcc, 0xa7, 0x0e, 0xca, 0x2d, 0x4b, 0x70, 0x9f, 0x17, 0x16, 0x35,
-       0x39, 0x32, 0xa7, 0xe4, 0xc8, 0xa2, 0x8b, 0x8f, 0x37, 0xea, 0xed, 0x7d,
-       0x3e, 0x7a, 0xbb, 0xbb, 0xb6, 0x43, 0xd4, 0xb8, 0x35, 0xa9, 0xed, 0xf0,
-       0xab, 0x99, 0xc2, 0xd8, 0x17, 0x59, 0x5f, 0xf9, 0x14, 0xf4, 0x15, 0x13,
-       0x35, 0x4b, 0x52, 0x67, 0xc1, 0x75, 0x96, 0x49, 0xaf, 0x45, 0x18, 0xa7,
-       0x8e, 0xd1, 0x79, 0xd6, 0xc9, 0x6f, 0xd2, 0xe3, 0xca, 0x66, 0x4b, 0xb8,
-       0xf2, 0x4c, 0x91, 0xdf, 0x1f, 0xa0, 0xec, 0xb3, 0x76, 0x2c, 0x41, 0xc7,
-       0xe8, 0x9c, 0xc8, 0x99, 0x41, 0xcc, 0x0f, 0x79, 0x08, 0x07, 0xc5, 0x3c,
-       0xa5, 0x7f, 0xe3, 0x51, 0xe4, 0xcd, 0x6d, 0x3d, 0x67, 0x5f, 0xd7, 0xfa,
-       0x25, 0xc5, 0x3b, 0x97, 0x15, 0xed, 0x89, 0x73, 0x7c, 0xff, 0x8b, 0x46,
-       0xe3, 0xfd, 0x09, 0x23, 0x55, 0x4e, 0x19, 0xc9, 0x25, 0x8c, 0x7b, 0xd1,
-       0x98, 0x2e, 0xc3, 0xd6, 0xd4, 0xb8, 0x64, 0xc7, 0x41, 0x97, 0x6b, 0xb4,
-       0x79, 0x7c, 0x62, 0x91, 0x3c, 0xf5, 0x13, 0x5b, 0x98, 0xf7, 0x91, 0xba,
-       0x79, 0x6b, 0xf8, 0xe2, 0x37, 0x7c, 0x40, 0x09, 0x86, 0xa9, 0xd6, 0x7f,
-       0x3b, 0xe0, 0x73, 0x8f, 0x65, 0x69, 0x23, 0xfd, 0xd7, 0x6e, 0xd0, 0x7f,
-       0x17, 0x37, 0x9d, 0xf7, 0xc3, 0xf2, 0x02, 0x59, 0xc3, 0x1d, 0x74, 0x84,
-       0x9e, 0xcb, 0xf3, 0xae, 0xd3, 0x81, 0x3d, 0x38, 0x85, 0x31, 0xda, 0x37,
-       0xae, 0x7d, 0x63, 0x3d, 0x2a, 0x1f, 0x58, 0xe7, 0x2c, 0x74, 0x28, 0x3c,
-       0xc6, 0x75, 0xd8, 0x62, 0xab, 0x3c, 0x3f, 0xd8, 0x65, 0x4f, 0x8a, 0x39,
-       0xb2, 0x5d, 0x66, 0x4d, 0x93, 0xf4, 0x7f, 0x9f, 0x2d, 0xd7, 0xd5, 0x8f,
-       0xfa, 0xd4, 0x51, 0x0e, 0xfb, 0xd4, 0x51, 0xba, 0x69, 0x32, 0xe4, 0xa2,
-       0xc9, 0x88, 0x4b, 0xbf, 0x8b, 0xb2, 0x7d, 0xd3, 0xc5, 0xbc, 0x06, 0xf6,
-       0x4d, 0x07, 0x05, 0x5f, 0x71, 0xdb, 0x37, 0xde, 0xba, 0x7d, 0xd0, 0x27,
-       0x74, 0x38, 0x69, 0xeb, 0xa4, 0x8a, 0xd5, 0x9a, 0x7f, 0x5e, 0x77, 0xad,
-       0x66, 0x71, 0xa9, 0xa1, 0xbe, 0xd2, 0x6f, 0xbe, 0x43, 0x0d, 0xf3, 0x85,
-       0x9c, 0x4b, 0x34, 0xd5, 0xfd, 0xfc, 0xec, 0xaf, 0x47, 0x35, 0x3f, 0x2f,
-       0xdf, 0xc3, 0xbb, 0x86, 0x85, 0x1f, 0x3c, 0x5b, 0xe5, 0x79, 0x93, 0x72,
-       0xbe, 0xf9, 0x7a, 0x7b, 0x24, 0x78, 0x8d, 0x14, 0xec, 0xfc, 0x65, 0xc0,
-       0xf6, 0x7c, 0x6a, 0x9d, 0x1e, 0xf9, 0x3c, 0xd1, 0x2b, 0x7d, 0x65, 0x2d,
-       0x2a, 0xd7, 0x7a, 0x97, 0xb2, 0x0b, 0x37, 0xc3, 0x77, 0x9c, 0x6b, 0x51,
-       0xfe, 0x45, 0xdb, 0x2a, 0x11, 0xf0, 0xfc, 0xc4, 0xe9, 0x16, 0xc7, 0x54,
-       0xf1, 0x2d, 0xc4, 0xb0, 0x80, 0xf7, 0xfa, 0xf9, 0xb2, 0xd6, 0x6a, 0xf3,
-       0x3d, 0xb3, 0x1a, 0xf6, 0x4c, 0xe2, 0x15, 0x6c, 0x32, 0xe4, 0x10, 0x8f,
-       0x79, 0xf2, 0xb8, 0x1f, 0x06, 0x16, 0x3d, 0x3e, 0xb9, 0xcd, 0xc8, 0x4d,
-       0x6e, 0x36, 0xcf, 0xfb, 0x2e, 0xfd, 0x1d, 0xf3, 0xad, 0x54, 0xde, 0x8c,
-       0x0f, 0x48, 0x99, 0x5d, 0xf6, 0xd7, 0xa5, 0xcc, 0x2d, 0xcf, 0xcf, 0x2b,
-       0xa3, 0xf7, 0x6c, 0x51, 0x46, 0x8b, 0x7e, 0x28, 0x81, 0xc3, 0x82, 0x07,
-       0xa0, 0x06, 0x1b, 0x39, 0xd6, 0x9f, 0x06, 0xcd, 0x33, 0x9f, 0x75, 0xd5,
-       0xaa, 0xf9, 0xef, 0x63, 0x35, 0xce, 0x12, 0x42, 0x2f, 0x88, 0x09, 0xe4,
-       0x9b, 0xf4, 0x31, 0xef, 0xc1, 0xf8, 0xfd, 0xd6, 0x1d, 0xf8, 0x80, 0x95,
-       0x9f, 0x2a, 0xa5, 0xe4, 0xcb, 0xe1, 0x2d, 0xc4, 0x5b, 0xb6, 0xc7, 0xa7,
-       0x6d, 0x6b, 0x95, 0x10, 0x0b, 0x42, 0x4e, 0xf0, 0x0b, 0x3d, 0xd4, 0x73,
-       0xaa, 0xad, 0xcd, 0xb9, 0xdb, 0x2b, 0xe3, 0x53, 0xb8, 0xd6, 0x45, 0x37,
-       0x8a, 0xc8, 0xd7, 0xc6, 0xb5, 0xdf, 0xe3, 0x6b, 0x7e, 0x3c, 0x4a, 0xe7,
-       0x9b, 0x43, 0xe7, 0x93, 0xfb, 0x53, 0x22, 0xd8, 0x54, 0x15, 0xfa, 0xa7,
-       0xf8, 0xaf, 0xc8, 0x18, 0x47, 0xf9, 0x51, 0xc7, 0x6f, 0xfc, 0xfc, 0x8a,
-       0x46, 0xdf, 0xc7, 0xcd, 0x97, 0xfc, 0xf2, 0x96, 0xfc, 0x8a, 0xc8, 0xbb,
-       0xdf, 0x4a, 0x1c, 0x45, 0xc7, 0x8b, 0x27, 0x44, 0xed, 0xa9, 0x1b, 0x0f,
-       0x1e, 0x4d, 0xcc, 0x18, 0xf8, 0x30, 0xd4, 0xc0, 0xab, 0x1e, 0x3e, 0x06,
-       0xe0, 0x85, 0x6b, 0x87, 0xaf, 0x4f, 0xcb, 0x3f, 0x36, 0x8c, 0x3c, 0x00,
-       0xf8, 0xb3, 0x9f, 0xa2, 0xb3, 0xd7, 0x81, 0xc3, 0x06, 0x63, 0xdb, 0x08,
-       0xcd, 0x86, 0x51, 0x57, 0x24, 0x6a, 0x73, 0x54, 0x2c, 0x51, 0xd6, 0x0a,
-       0x9d, 0x15, 0x75, 0x8f, 0xfb, 0x23, 0xeb, 0x94, 0x66, 0xb9, 0x97, 0xa5,
-       0x73, 0x2c, 0x63, 0xcf, 0x2d, 0xd5, 0x74, 0xfc, 0xc6, 0xda, 0xc7, 0x7a,
-       0x1c, 0x5f, 0x17, 0x38, 0x1e, 0xdd, 0x10, 0xc7, 0x8f, 0x56, 0x71, 0x7c,
-       0xae, 0x4f, 0xe2, 0xf3, 0x45, 0x7e, 0x56, 0x0f, 0x1d, 0x16, 0xcf, 0xcd,
-       0xf2, 0xef, 0x4e, 0x3a, 0x2c, 0xfb, 0x62, 0xf0, 0xbb, 0x99, 0xc7, 0xe7,
-       0xb3, 0x74, 0xfe, 0x7a, 0x36, 0x90, 0x12, 0x35, 0x0a, 0xee, 0xbe, 0x1e,
-       0xfa, 0x7e, 0x8c, 0x6b, 0x86, 0xff, 0x9a, 0x2f, 0xc9, 0x9a, 0xab, 0x92,
-       0xe4, 0x4f, 0xf4, 0x76, 0x7c, 0xd0, 0x83, 0xff, 0xf5, 0x36, 0xe6, 0x05,
-       0x25, 0x03, 0x4f, 0x6c, 0xe0, 0xff, 0x68, 0xc4, 0xcb, 0x5e, 0x1f, 0xbd,
-       0xf9, 0x8d, 0x3e, 0x19, 0xbb, 0xda, 0xc8, 0xff, 0xe1, 0xc6, 0xd1, 0xba,
-       0x58, 0x3e, 0xf3, 0xfd, 0x84, 0xaa, 0xff, 0x7b, 0xa7, 0x4f, 0xca, 0x0b,
-       0xd4, 0x04, 0xa6, 0x19, 0x0e, 0x6f, 0xb2, 0xae, 0x32, 0x48, 0xad, 0xaf,
-       0xe8, 0xb5, 0x0e, 0x0a, 0x7e, 0xeb, 0xf6, 0xe7, 0x5c, 0x56, 0xb5, 0xe0,
-       0x39, 0xd7, 0x9a, 0x2e, 0x0b, 0x5b, 0xa8, 0x39, 0xbd, 0x35, 0xcf, 0xc3,
-       0x8a, 0x7a, 0x64, 0x82, 0x17, 0xdf, 0xd0, 0x2f, 0x05, 0xfb, 0x4b, 0x86,
-       0xd4, 0x83, 0x27, 0x59, 0xbf, 0xdd, 0x6e, 0x0c, 0xe9, 0x61, 0x75, 0x44,
-       0x6f, 0x4f, 0x0e, 0xef, 0x6f, 0xec, 0x83, 0xb4, 0x39, 0x32, 0xaf, 0x3d,
-       0x25, 0x78, 0xc1, 0xe5, 0xb1, 0x0a, 0x4d, 0xc7, 0xbb, 0x29, 0x33, 0xc6,
-       0xef, 0x9e, 0x44, 0x4f, 0xac, 0x20, 0x65, 0x99, 0x7e, 0x33, 0x63, 0x8f,
-       0x29, 0x7d, 0x51, 0xfb, 0xdd, 0xdb, 0x54, 0xee, 0xc3, 0x45, 0x11, 0xab,
-       0x94, 0xfd, 0x84, 0xf8, 0xf7, 0x92, 0x7e, 0xf6, 0x45, 0x11, 0x33, 0xcd,
-       0x5c, 0x6f, 0x55, 0xe3, 0x3a, 0x5d, 0xe3, 0x30, 0xa6, 0x53, 0x8d, 0xc5,
-       0x33, 0xb5, 0x4e, 0xd1, 0xae, 0xf8, 0x2d, 0xe8, 0x30, 0xad, 0x6a, 0xf5,
-       0x70, 0xfd, 0x02, 0xcd, 0x54, 0xd7, 0xd2, 0xc9, 0x63, 0xff, 0x5b, 0xf5,
-       0xf2, 0xe8, 0x64, 0x9d, 0x17, 0xf3, 0x6e, 0x9c, 0x13, 0xd6, 0x12, 0x14,
-       0x71, 0x24, 0xfe, 0xad, 0xde, 0x73, 0xa6, 0x3a, 0x27, 0xe4, 0x6d, 0xd8,
-       0x11, 0xf9, 0x2c, 0x3d, 0xae, 0xd3, 0x35, 0x4e, 0xf3, 0x0a, 0x1d, 0xa7,
-       0xf8, 0x57, 0x9e, 0xc7, 0x3f, 0xa8, 0xbc, 0x5e, 0x53, 0xc4, 0x54, 0x65,
-       0xde, 0x86, 0xfe, 0x0d, 0x3f, 0x34, 0xf2, 0x2c, 0x90, 0x3b, 0xe1, 0xe6,
-       0x37, 0x72, 0xbd, 0x21, 0xc8, 0xa2, 0x32, 0x62, 0xa9, 0x88, 0x6b, 0x34,
-       0xd3, 0x9d, 0xf7, 0x20, 0x5f, 0x7f, 0x1b, 0x3a, 0xe8, 0x56, 0xe8, 0xcf,
-       0xf2, 0xa1, 0x3f, 0xf7, 0xfb, 0x51, 0xeb, 0x86, 0x9a, 0xb7, 0x6c, 0xcc,
-       0xa0, 0x0a, 0xdb, 0x0a, 0x06, 0x95, 0xcc, 0x00, 0x9d, 0x77, 0xec, 0xf8,
-       0x12, 0xc9, 0x9a, 0xc9, 0xe9, 0x79, 0x3b, 0xb6, 0x4a, 0x87, 0xcc, 0x73,
-       0x24, 0x7b, 0x25, 0x94, 0x58, 0x06, 0x9f, 0xa1, 0x18, 0xdb, 0x47, 0x6c,
-       0x7f, 0x9e, 0x42, 0x5c, 0x46, 0xef, 0x0b, 0x6a, 0xe3, 0xf1, 0x37, 0xc6,
-       0x70, 0xba, 0xb9, 0x93, 0x3a, 0x12, 0xfc, 0xcc, 0x18, 0xf8, 0x13, 0x3f,
-       0x27, 0x4d, 0x49, 0xb6, 0x93, 0x60, 0xb3, 0x9e, 0x39, 0x65, 0x9b, 0x25,
-       0x32, 0x78, 0x2c, 0x6c, 0x57, 0x3c, 0x07, 0xf7, 0x27, 0xcc, 0x16, 0xf2,
-       0xd6, 0xe1, 0x5e, 0x14, 0x75, 0x8a, 0x6f, 0xc7, 0x0f, 0x92, 0xd1, 0x0f,
-       0x7e, 0x85, 0x7d, 0x1b, 0x55, 0xf1, 0xa4, 0x4b, 0xfc, 0xdb, 0x51, 0xbf,
-       0xbf, 0x2a, 0xea, 0xdd, 0xe4, 0x6f, 0xe0, 0xf6, 0x2f, 0xab, 0x3d, 0xab,
-       0xcb, 0x09, 0x89, 0x8c, 0x18, 0x5f, 0xa5, 0x0b, 0x4b, 0x1b, 0xf9, 0x66,
-       0xfc, 0xea, 0x5b, 0xbb, 0xb6, 0x58, 0xdf, 0xba, 0xbe, 0x53, 0xd6, 0x8c,
-       0xe1, 0xfd, 0x7e, 0xba, 0x97, 0x77, 0x6d, 0xee, 0x7a, 0xd5, 0xef, 0xd0,
-       0xb4, 0xac, 0x35, 0x56, 0xb8, 0x70, 0xbd, 0x89, 0x7f, 0xf3, 0x49, 0x21,
-       0x2f, 0xcf, 0xca, 0x38, 0xc3, 0x80, 0xec, 0x6d, 0x16, 0xa2, 0xe5, 0x6a,
-       0xed, 0x67, 0x50, 0xd5, 0x7f, 0x30, 0x53, 0x7c, 0xa4, 0x75, 0x9f, 0x3a,
-       0x57, 0x15, 0x71, 0xa7, 0xb4, 0x2b, 0x8f, 0x22, 0xa4, 0xf2, 0x24, 0x70,
-       0xdf, 0x48, 0x18, 0x75, 0x5b, 0xb2, 0xd6, 0x12, 0x63, 0x50, 0xe7, 0x08,
-       0x1b, 0x12, 0x75, 0xae, 0xf0, 0xfb, 0x35, 0xab, 0x05, 0xc5, 0x78, 0xf8,
-       0x9f, 0xb4, 0x5d, 0x78, 0x5a, 0xd0, 0x98, 0x7c, 0xa7, 0xac, 0xd9, 0x5c,
-       0x5c, 0x39, 0x23, 0xea, 0x24, 0x93, 0xaa, 0xf6, 0x33, 0x43, 0x5d, 0x42,
-       0x6f, 0xfa, 0xf8, 0x35, 0x9b, 0xe7, 0xc2, 0xdb, 0xaf, 0xd9, 0x74, 0xdf,
-       0xb3, 0xbd, 0x9a, 0x4d, 0x93, 0xd7, 0x6e, 0x2c, 0xc8, 0x9a, 0xcd, 0xfa,
-       0x58, 0x80, 0xf4, 0x43, 0x65, 0x5c, 0xf2, 0x48, 0xea, 0x7f, 0x5f, 0x72,
-       0xe5, 0x08, 0xcb, 0x7a, 0xcc, 0xc5, 0xaa, 0x0e, 0x24, 0xeb, 0x31, 0x65,
-       0x4e, 0xb1, 0xbb, 0x0f, 0x89, 0x8c, 0x39, 0xc8, 0xf7, 0x74, 0x7b, 0x62,
-       0x0e, 0x2d, 0x4c, 0xa3, 0xa3, 0xaa, 0xe6, 0xbc, 0x19, 0x6e, 0xd6, 0xd9,
-       0x2a, 0x4c, 0x73, 0x15, 0xfa, 0x69, 0xfc, 0xd3, 0x74, 0x3f, 0x1c, 0x51,
-       0xb9, 0x74, 0xc8, 0x9d, 0x3b, 0xa8, 0xe0, 0xa8, 0xf5, 0x0f, 0xf2, 0xd1,
-       0x3f, 0x7e, 0x5b, 0xe4, 0x10, 0x4b, 0xfd, 0x65, 0x50, 0xd1, 0x24, 0xe8,
-       0x36, 0xe2, 0xa2, 0xdb, 0x5d, 0x4d, 0xe8, 0x16, 0xf4, 0xf9, 0xdd, 0x1d,
-       0xb2, 0x4f, 0x01, 0xe2, 0xde, 0xdf, 0x57, 0xbf, 0x37, 0xa3, 0xbf, 0xf7,
-       0x78, 0x6f, 0x40, 0x83, 0x78, 0xc6, 0x87, 0xe1, 0x1a, 0x1d, 0xea, 0xdf,
-       0x98, 0xcb, 0x7e, 0xd7, 0x5c, 0x86, 0x5d, 0x73, 0xd9, 0xd7, 0x64, 0x2e,
-       0xac, 0x4f, 0x94, 0x2f, 0xf0, 0xff, 0x8f, 0x3b, 0x27, 0xe1, 0xab, 0x65,
-       0x5a, 0x8d, 0x0b, 0xf9, 0x9a, 0x03, 0x1c, 0x85, 0x9e, 0x32, 0xaa, 0xea,
-       0xe0, 0xdd, 0xf3, 0x6c, 0x66, 0xab, 0x41, 0x16, 0xa0, 0xd7, 0x41, 0x82,
-       0xef, 0xeb, 0x6c, 0xd2, 0xeb, 0x00, 0x3a, 0x86, 0x5f, 0xaf, 0x03, 0x37,
-       0x8f, 0x77, 0xeb, 0x52, 0xd0, 0x7d, 0x21, 0x03, 0xa1, 0xf3, 0xa2, 0x57,
-       0xc1, 0x2f, 0xd1, 0x85, 0xaa, 0x8e, 0x79, 0x90, 0xd2, 0x4a, 0xc7, 0xbc,
-       0xb0, 0xa4, 0xf7, 0x7c, 0xd8, 0xb3, 0xe7, 0x7e, 0x3a, 0xe7, 0x90, 0xca,
-       0xf1, 0xd1, 0xb0, 0xca, 0xba, 0x60, 0x95, 0xf5, 0x81, 0x95, 0x78, 0x47,
-       0x93, 0x79, 0x03, 0x3e, 0xb8, 0x07, 0xff, 0xbf, 0x13, 0x41, 0x8f, 0x16,
-       0xa2, 0xdf, 0xd8, 0x55, 0xf3, 0x0b, 0xe8, 0xdf, 0x98, 0x63, 0xd3, 0xdc,
-       0x4f, 0xa5, 0x0f, 0x0e, 0x06, 0x8e, 0x5c, 0x67, 0x03, 0x9d, 0x65, 0x5e,
-       0xbd, 0x2d, 0xa8, 0x75, 0x85, 0x03, 0x82, 0xef, 0xdd, 0x0f, 0x22, 0x77,
-       0x45, 0x9f, 0xeb, 0xd6, 0xbe, 0x5c, 0xb5, 0xfe, 0xd6, 0x3a, 0x7d, 0xa2,
-       0xa6, 0x4b, 0xe8, 0x1c, 0x54, 0xfd, 0x5b, 0xcb, 0xc0, 0x7b, 0x75, 0xfe,
-       0x89, 0x5b, 0x75, 0xfd, 0x06, 0xe1, 0x0b, 0xea, 0x4e, 0x1b, 0x4e, 0x4a,
-       0xe4, 0x91, 0xf6, 0x3a, 0xf0, 0x7b, 0x25, 0x99, 0x37, 0xf7, 0xa6, 0x91,
-       0xb3, 0xdc, 0x7b, 0xcd, 0xa2, 0x93, 0xf9, 0x2f, 0xed, 0x95, 0x74, 0x7a,
-       0x89, 0x86, 0xc7, 0x79, 0xfc, 0x14, 0x7c, 0xbd, 0x76, 0x2c, 0xc9, 0x4a,
-       0xe4, 0x5c, 0xb9, 0x8d, 0x16, 0x59, 0x5b, 0x0f, 0x3a, 0x25, 0xe1, 0xbb,
-       0x63, 0x99, 0x51, 0x40, 0x6f, 0x55, 0x63, 0xa1, 0x95, 0x9f, 0xdb, 0x4f,
-       0xcb, 0x45, 0xd0, 0x7c, 0x8b, 0xea, 0x11, 0x82, 0xb1, 0x01, 0xea, 0x73,
-       0xfe, 0x84, 0xe1, 0xf5, 0x05, 0x91, 0x47, 0xb9, 0x58, 0xb8, 0x24, 0xff,
-       0x96, 0x5e, 0x52, 0xef, 0xe0, 0xf7, 0x95, 0xff, 0x86, 0x12, 0x7d, 0x96,
-       0xcb, 0x36, 0x73, 0xff, 0xf3, 0xd7, 0x3f, 0x8e, 0x6f, 0x4b, 0xff, 0xc8,
-       0xa6, 0x6b, 0xfa, 0x87, 0xfb, 0xd9, 0x5a, 0x17, 0x39, 0xd6, 0x2f, 0xfb,
-       0x37, 0x00, 0x06, 0x9d, 0xd0, 0xad, 0xd2, 0x80, 0xa5, 0x31, 0x65, 0x47,
-       0x92, 0xc1, 0x49, 0x9a, 0x2d, 0x47, 0x8d, 0x4c, 0x01, 0x3a, 0x30, 0xff,
-       0x2d, 0x5d, 0xd9, 0x2d, 0x7d, 0x2e, 0xfa, 0x1e, 0xf0, 0xf5, 0x9d, 0x3c,
-       0xfe, 0x3f, 0xfa, 0x65, 0xee, 0xb5, 0xfb, 0x7c, 0x0f, 0x9f, 0x7f, 0x2e,
-       0x52, 0x7f, 0xfe, 0x31, 0x3e, 0xdf, 0xc7, 0xe7, 0xe1, 0x87, 0x84, 0x9f,
-       0x31, 0x46, 0x39, 0xde, 0x9f, 0xd9, 0x32, 0xf3, 0xa9, 0x57, 0x58, 0x5e,
-       0x2c, 0xe9, 0x71, 0xbb, 0x50, 0x97, 0x23, 0xf6, 0xc4, 0xe0, 0x31, 0x97,
-       0xf3, 0x63, 0x3c, 0x6e, 0x90, 0x82, 0xaf, 0x58, 0x34, 0xbb, 0xa4, 0x71,
-       0x52, 0xe7, 0xd4, 0xbf, 0xc3, 0xf0, 0x45, 0xde, 0xce, 0x47, 0xbb, 0x25,
-       0xfc, 0x62, 0xc2, 0x87, 0x89, 0x3c, 0x8e, 0x2b, 0x02, 0xf7, 0xec, 0x49,
-       0xab, 0xfa, 0x7e, 0xe0, 0x96, 0x88, 0x73, 0xf0, 0x1a, 0x58, 0x2e, 0x4d,
-       0x39, 0x66, 0xae, 0x9a, 0x8f, 0xf6, 0xe7, 0x03, 0xf2, 0xfe, 0xff, 0xda,
-       0x25, 0xfb, 0xa3, 0xbe, 0x3f, 0xa0, 0xfb, 0x24, 0x4a, 0x9d, 0x00, 0x39,
-       0xca, 0x01, 0x01, 0x9b, 0xe0, 0x02, 0xe4, 0x95, 0xc1, 0xbf, 0x79, 0x3d,
-       0x69, 0xcc, 0xb1, 0xad, 0x5f, 0xf7, 0x7c, 0x91, 0xeb, 0x3a, 0xc6, 0xf3,
-       0x4d, 0xf1, 0xba, 0xf4, 0xf9, 0x04, 0x1f, 0xfb, 0xed, 0x2f, 0x9e, 0xd5,
-       0x91, 0x46, 0x5d, 0x70, 0xe6, 0x54, 0x47, 0x3a, 0x13, 0x93, 0xfb, 0x5c,
-       0xf3, 0xd1, 0x46, 0xaa, 0x3e, 0xda, 0xb9, 0xfc, 0x78, 0x3f, 0xfc, 0x15,
-       0xc6, 0x35, 0xde, 0xef, 0xf0, 0x15, 0x1e, 0x8b, 0x7a, 0x84, 0x1c, 0xff,
-       0xed, 0x52, 0xf9, 0x3c, 0x8d, 0xb8, 0x22, 0xf3, 0x23, 0xb4, 0x5e, 0x81,
-       0x7b, 0x9f, 0xe0, 0x67, 0x48, 0xdd, 0xa2, 0xf9, 0x7b, 0xa8, 0x21, 0xff,
-       0xa5, 0x11, 0xc7, 0x36, 0xf2, 0xab, 0x8a, 0x38, 0xa2, 0x0f, 0x9e, 0x6d,
-       0xd4, 0x83, 0xe0, 0x9e, 0xf0, 0x8b, 0x4d, 0x37, 0xd0, 0x2b, 0xe8, 0x38,
-       0x44, 0x2f, 0xcc, 0x67, 0xe9, 0x31, 0xde, 0xab, 0x3f, 0x30, 0x3e, 0x83,
-       0x38, 0x3b, 0xc9, 0x5c, 0x27, 0x86, 0x71, 0xde, 0x89, 0x9d, 0x33, 0x52,
-       0xe0, 0x8b, 0x95, 0x90, 0xd3, 0x45, 0xad, 0x4c, 0xab, 0xbf, 0x49, 0x23,
-       0x6c, 0xcf, 0x81, 0x66, 0x9d, 0x48, 0x8a, 0x40, 0x6f, 0xb6, 0x79, 0x84,
-       0x71, 0x62, 0xba, 0x0c, 0x7c, 0x36, 0xe8, 0x8b, 0x45, 0xa2, 0xe7, 0x8b,
-       0x23, 0xe6, 0xf7, 0xc8, 0xb1, 0x6a, 0xd7, 0x6d, 0x33, 0xc9, 0xf3, 0x48,
-       0x95, 0x5f, 0xa2, 0xf7, 0x44, 0xdf, 0x12, 0xc0, 0x51, 0xef, 0xfb, 0x1f,
-       0xd1, 0x99, 0x34, 0xe6, 0xbd, 0x75, 0xfa, 0x3c, 0xb9, 0x2d, 0xfa, 0xec,
-       0xf0, 0xa1, 0xcf, 0x7f, 0x54, 0x78, 0x53, 0x61, 0x1c, 0xed, 0xa0, 0x99,
-       0x02, 0x72, 0xbf, 0x3e, 0x8b, 0xfe, 0x52, 0x85, 0x0c, 0xf3, 0xa5, 0x4c,
-       0x8d, 0x2f, 0x5d, 0x4d, 0x06, 0x13, 0xa0, 0x71, 0xf4, 0x65, 0x53, 0xf9,
-       0x3e, 0x58, 0xc7, 0x00, 0x8d, 0x2c, 0x74, 0x22, 0xf6, 0xb5, 0x9a, 0x9c,
-       0x48, 0xa8, 0xfa, 0x7c, 0xdb, 0x9a, 0x66, 0xfe, 0x38, 0xc7, 0xb4, 0x9c,
-       0x2b, 0x1c, 0xa4, 0xc5, 0x70, 0x94, 0x86, 0x17, 0x74, 0xbf, 0x12, 0x11,
-       0x37, 0x89, 0x4a, 0x9e, 0xa4, 0xd7, 0xfd, 0x84, 0xf0, 0x45, 0x58, 0x37,
-       0x3f, 0xa9, 0x75, 0x77, 0x6e, 0xc2, 0x97, 0xde, 0x57, 0x34, 0x5b, 0xb9,
-       0x95, 0x8c, 0x53, 0x36, 0x39, 0xf1, 0xef, 0x02, 0xff, 0x87, 0x6f, 0xc2,
-       0xaf, 0x06, 0x1e, 0x6d, 0x51, 0x3a, 0xef, 0x85, 0x45, 0x94, 0xd7, 0x8d,
-       0xeb, 0x95, 0x0f, 0x67, 0xe2, 0x2f, 0x09, 0xdd, 0x6b, 0xe4, 0x26, 0x8f,
-       0x13, 0xf2, 0x48, 0xf3, 0x0d, 0x3f, 0x3c, 0xd4, 0x3d, 0x29, 0x35, 0x2e,
-       0xca, 0x7c, 0x4e, 0x93, 0x9f, 0x9b, 0x0e, 0x7a, 0x71, 0xf2, 0x5e, 0xe0,
-       0xf8, 0xbc, 0x45, 0x27, 0xf2, 0xf6, 0xab, 0x59, 0x9a, 0x64, 0xba, 0x76,
-       0xcb, 0x0b, 0x1e, 0x4f, 0xc0, 0xb3, 0x29, 0xd0, 0x3e, 0x65, 0x0a, 0x96,
-       0xcc, 0xb7, 0x13, 0x3d, 0xe5, 0x70, 0x8c, 0xda, 0xe2, 0xee, 0xdd, 0x5a,
-       0x1e, 0x64, 0x0a, 0xa8, 0x15, 0xe4, 0xbf, 0x25, 0x1e, 0x8f, 0xfc, 0xfe,
-       0x22, 0x9e, 0x03, 0x19, 0x87, 0xb9, 0xf3, 0xf1, 0xb2, 0xdc, 0xd7, 0x61,
-       0x7e, 0xf6, 0xc8, 0x38, 0xbf, 0xb3, 0x3c, 0xc6, 0xfb, 0xdb, 0x23, 0x78,
-       0xb3, 0xdc, 0xcf, 0x29, 0xba, 0xec, 0xcb, 0x57, 0xe4, 0xbe, 0x64, 0x5c,
-       0xf4, 0x9d, 0x11, 0xf4, 0x3d, 0x25, 0xf6, 0x23, 0x53, 0x34, 0x58, 0x5f,
-       0xd6, 0xbe, 0x04, 0xb6, 0x9b, 0x8b, 0x21, 0xc5, 0x43, 0x70, 0xed, 0x89,
-       0xdd, 0x22, 0x1f, 0x11, 0xf6, 0x74, 0x11, 0x7f, 0xa7, 0xe8, 0x0a, 0xeb,
-       0xfd, 0x2f, 0xe7, 0xdb, 0xe8, 0x4e, 0xa1, 0x8d, 0xee, 0x16, 0xa2, 0x74,
-       0x7b, 0x7e, 0x07, 0x5d, 0x66, 0x9b, 0xe6, 0xb2, 0x13, 0xb2, 0x72, 0xb4,
-       0x03, 0xf1, 0x42, 0xe4, 0x0a, 0x31, 0xdd, 0x61, 0x3c, 0xf4, 0xef, 0xe4,
-       0x1e, 0xc6, 0x39, 0xb6, 0x8d, 0xda, 0xe9, 0x5d, 0x7e, 0x67, 0x2e, 0xaf,
-       0x73, 0x1c, 0xe0, 0x63, 0xdf, 0x5f, 0xb5, 0x1f, 0x36, 0xc7, 0x11, 0x73,
-       0x13, 0x1c, 0x99, 0x12, 0xbc, 0x7e, 0x76, 0x3e, 0x8a, 0xbe, 0xca, 0xd9,
-       0x16, 0xf8, 0x49, 0x99, 0x3f, 0x3f, 0x17, 0xc2, 0x78, 0x9c, 0x73, 0x64,
-       0x8e, 0xa4, 0x58, 0x5b, 0x84, 0x8f, 0x03, 0xa2, 0x0e, 0x5a, 0xc2, 0xa1,
-       0x9d, 0xd7, 0x17, 0x10, 0xe3, 0x33, 0xcb, 0xed, 0x74, 0xb6, 0x68, 0xf2,
-       0x71, 0x90, 0xf5, 0x44, 0x8c, 0xed, 0xdd, 0xa7, 0xfb, 0xcb, 0x5e, 0xe6,
-       0xb9, 0xe7, 0xc4, 0x38, 0xfe, 0xbb, 0xdc, 0x43, 0xb3, 0xc5, 0x2e, 0x75,
-       0x7c, 0x50, 0xe6, 0xf2, 0x8a, 0x5c, 0x6c, 0x5c, 0xdb, 0x88, 0xbf, 0xbd,
-       0xcd, 0x38, 0x05, 0x99, 0x2a, 0x75, 0x7c, 0xf0, 0x9a, 0x5b, 0x0d, 0xfd,
-       0x90, 0x81, 0x73, 0x93, 0xf4, 0x4d, 0x96, 0xb7, 0xc3, 0xaf, 0xc0, 0x1f,
-       0xfc, 0xfb, 0xc0, 0x9b, 0x52, 0x96, 0x06, 0xf9, 0x18, 0x7d, 0x8e, 0x82,
-       0xa2, 0x96, 0x69, 0x3a, 0x1c, 0x13, 0xf5, 0x1f, 0x92, 0x46, 0x4f, 0x89,
-       0x9e, 0x73, 0x3f, 0x12, 0xbc, 0xc9, 0xce, 0x5a, 0x06, 0xf4, 0x11, 0xf8,
-       0x54, 0x64, 0xee, 0xd5, 0x49, 0xa7, 0xf7, 0xed, 0x5d, 0x53, 0xa3, 0x94,
-       0xe8, 0x07, 0xde, 0x4b, 0x9a, 0x55, 0x3d, 0x04, 0x04, 0xbf, 0x37, 0x0f,
-       0xe8, 0x9a, 0x48, 0x7d, 0xac, 0x65, 0x85, 0x3e, 0xee, 0xf2, 0x5c, 0x37,
-       0x3d, 0xd7, 0xab, 0x79, 0x72, 0x2c, 0xf3, 0x58, 0xce, 0x93, 0xec, 0x39,
-       0x84, 0xbe, 0x71, 0xc0, 0x3f, 0xf3, 0xc0, 0x7e, 0xf3, 0x73, 0xca, 0x06,
-       0xca, 0xac, 0x8c, 0x44, 0x7a, 0x8d, 0x98, 0x91, 0x19, 0xfb, 0x97, 0x4a,
-       0x22, 0x0d, 0xbd, 0xe8, 0xc6, 0x6e, 0xc9, 0xe3, 0x30, 0xaf, 0x6c, 0x1c,
-       0xaa, 0xdb, 0xa9, 0x95, 0x2e, 0x5a, 0x15, 0x7d, 0xb5, 0xa0, 0x63, 0xe0,
-       0x7e, 0x3c, 0x27, 0x6b, 0xb6, 0xb0, 0x7d, 0x77, 0xc3, 0x01, 0x8d, 0x1f,
-       0x8a, 0xdc, 0xe4, 0xfd, 0x4c, 0xad, 0x7c, 0x54, 0x39, 0x23, 0xfa, 0xd2,
-       0x60, 0x6c, 0x0f, 0xcd, 0x08, 0x9b, 0x8b, 0xf5, 0x97, 0x3a, 0xbb, 0x76,
-       0x12, 0xf3, 0xcc, 0x22, 0x56, 0x62, 0x38, 0xdf, 0x0e, 0x64, 0x4a, 0x32,
-       0xf6, 0x9d, 0xf2, 0xc4, 0xbe, 0x4f, 0x89, 0xd8, 0x37, 0xe2, 0xde, 0x80,
-       0x2b, 0x60, 0xe9, 0x97, 0xcb, 0x82, 0x7d, 0x8c, 0xf3, 0x3e, 0x5a, 0x34,
-       0x77, 0x5d, 0xf0, 0x9b, 0xc9, 0xe9, 0x60, 0xa2, 0xb7, 0x85, 0xac, 0x40,
-       0xd2, 0xb1, 0xe3, 0x0f, 0x58, 0x87, 0xb8, 0x5d, 0xc0, 0x3c, 0x5f, 0xa2,
-       0xf5, 0x52, 0x0b, 0xd3, 0x89, 0xcd, 0x78, 0xb7, 0xca, 0x3a, 0xed, 0x2c,
-       0xbd, 0x5b, 0x22, 0xba, 0x5d, 0xbc, 0x8a, 0x5e, 0xbb, 0xb1, 0x07, 0x4c,
-       0x2b, 0x88, 0x05, 0x67, 0x62, 0xf0, 0xb1, 0xb1, 0x5e, 0x1b, 0x6b, 0x55,
-       0xb8, 0xd9, 0xc5, 0xb6, 0xa3, 0xc9, 0xff, 0x1d, 0xfe, 0x1f, 0x89, 0x00,
-       0x2e, 0x6b, 0xc5, 0x31, 0xc1, 0x4b, 0x97, 0xf8, 0xfc, 0x12, 0x9f, 0x87,
-       0x4c, 0x5d, 0x2b, 0x56, 0xde, 0x49, 0xc6, 0x13, 0x56, 0x72, 0xe2, 0xa4,
-       0x1c, 0xc3, 0x38, 0x77, 0xf9, 0x7a, 0x62, 0x4f, 0x88, 0xe7, 0x31, 0xc3,
-       0xf3, 0x58, 0x27, 0x99, 0xeb, 0x9d, 0x12, 0xef, 0x26, 0xba, 0x23, 0xde,
-       0xcb, 0x3a, 0x53, 0xfc, 0x71, 0x3a, 0x13, 0x96, 0xef, 0xcf, 0xc5, 0x51,
-       0x73, 0xd5, 0x49, 0xb3, 0x63, 0xa3, 0xaa, 0xe6, 0xea, 0xcd, 0x26, 0x35,
-       0x57, 0xed, 0xb4, 0x36, 0x0f, 0xbb, 0xb7, 0x9d, 0xe9, 0xdd, 0x14, 0xb9,
-       0x7a, 0x6b, 0xf3, 0xa2, 0x1f, 0x3e, 0xaf, 0xa7, 0xb2, 0x3e, 0xc3, 0xaa,
-       0x79, 0x26, 0xde, 0x2d, 0x74, 0xa7, 0xdb, 0xcb, 0xbf, 0xc5, 0xf3, 0x49,
-       0x58, 0x99, 0x09, 0xf7, 0x3a, 0xc4, 0x7c, 0xd7, 0xa7, 0xc5, 0xb8, 0xa0,
-       0x67, 0x5c, 0x82, 0x32, 0x13, 0x98, 0xbf, 0x18, 0xf3, 0x3f, 0xc9, 0xb8,
-       0x5e, 0x8f, 0xfb, 0x7e, 0x8b, 0x72, 0x42, 0xdf, 0xe7, 0xbf, 0x4b, 0x3d,
-       0x81, 0xf5, 0x02, 0xfc, 0x26, 0x06, 0xe3, 0x3f, 0xe6, 0x66, 0x51, 0x76,
-       0x89, 0xd7, 0x75, 0xbd, 0x2b, 0xf0, 0xa0, 0xf0, 0x93, 0x4a, 0xa6, 0x2e,
-       0xb7, 0xa5, 0xde, 0xbf, 0x2e, 0x6d, 0xae, 0x28, 0x39, 0xd7, 0x20, 0x4b,
-       0x21, 0x47, 0xb3, 0x95, 0xa0, 0x03, 0xbd, 0x0f, 0xb6, 0xd0, 0x25, 0xe6,
-       0x63, 0x32, 0x3f, 0x89, 0x79, 0x2a, 0xf3, 0x32, 0x49, 0x47, 0xa9, 0xba,
-       0xcf, 0x32, 0x48, 0x5c, 0x1e, 0xae, 0xe5, 0x45, 0xba, 0xe2, 0xe6, 0x21,
-       0x57, 0xdc, 0xdc, 0x74, 0xe5, 0x45, 0x86, 0x85, 0x9e, 0x56, 0xd3, 0xad,
-       0xc2, 0x4a, 0xb7, 0x8a, 0x8a, 0x9e, 0xf4, 0xe0, 0x71, 0x8b, 0x55, 0x1e,
-       0xb7, 0x73, 0x13, 0x1e, 0xe7, 0x67, 0x9b, 0xae, 0x2a, 0x7e, 0x62, 0xc7,
-       0x21, 0x6b, 0x6e, 0x31, 0xdf, 0xf8, 0x71, 0x79, 0x82, 0xf9, 0x49, 0x9c,
-       0xf9, 0xc9, 0x18, 0xf3, 0x93, 0x18, 0xf3, 0x13, 0x87, 0x61, 0x60, 0xf1,
-       0xda, 0xef, 0x05, 0x6e, 0xcf, 0x43, 0x8e, 0x4c, 0xd2, 0x95, 0x32, 0x78,
-       0xf3, 0x18, 0xeb, 0x42, 0xf7, 0x02, 0x6b, 0xf3, 0x3d, 0x8c, 0xc7, 0x52,
-       0xff, 0xa9, 0xb7, 0x6f, 0xec, 0x57, 0x51, 0x1f, 0x97, 0x8c, 0xaf, 0x81,
-       0xff, 0xbc, 0x99, 0xa5, 0xee, 0xc0, 0xed, 0x42, 0x57, 0x60, 0xad, 0xf0,
-       0x13, 0xf4, 0xa5, 0x78, 0x1d, 0x34, 0x8e, 0xbe, 0xbf, 0x3f, 0x1c, 0x9d,
-       0xe4, 0xb9, 0x77, 0x07, 0x66, 0x79, 0x5f, 0xbe, 0x12, 0x4f, 0xf4, 0xf6,
-       0x49, 0x5a, 0xc8, 0xe6, 0xc0, 0x3d, 0x17, 0x76, 0xd0, 0xfe, 0xf1, 0xe4,
-       0x9e, 0x5e, 0xa6, 0x5b, 0xe0, 0x7b, 0xad, 0xef, 0x4e, 0x90, 0xf1, 0xb0,
-       0x43, 0xf5, 0xeb, 0xb1, 0x58, 0x5e, 0x7e, 0xc8, 0xf7, 0x7f, 0x10, 0xc8,
-       0x15, 0x5e, 0xe3, 0x67, 0xe3, 0xf8, 0x4f, 0xe1, 0xdf, 0x64, 0x7b, 0x01,
-       0xbd, 0x7e, 0x3a, 0x79, 0x0c, 0xc6, 0xe2, 0xd8, 0x8e, 0x31, 0x6f, 0x8b,
-       0xaf, 0x1a, 0xf6, 0x64, 0xc2, 0x78, 0x3e, 0x8a, 0x9e, 0xf1, 0x3f, 0x2c,
-       0x3f, 0x15, 0x95, 0x31, 0xb6, 0xe7, 0xf6, 0x48, 0x3e, 0xc2, 0xb8, 0x19,
-       0x4e, 0x08, 0x9b, 0xad, 0xe5, 0x9a, 0x94, 0x9b, 0x8b, 0xbc, 0xbf, 0x4b,
-       0xf1, 0x18, 0xef, 0x6f, 0x97, 0x92, 0x99, 0x59, 0xbe, 0x2e, 0xe4, 0x31,
-       0xcb, 0x4e, 0x86, 0x77, 0x91, 0x4c, 0xd1, 0x03, 0xe2, 0x14, 0xfa, 0xea,
-       0x3c, 0x83, 0xe7, 0x31, 0xb6, 0x82, 0x6f, 0x7c, 0x18, 0xc8, 0x14, 0xf0,
-       0x5e, 0xe0, 0x1f, 0xff, 0x2e, 0x4d, 0xd2, 0xd5, 0xbc, 0x9e, 0xc3, 0x80,
-       0x61, 0x7c, 0x13, 0xf3, 0x08, 0xd0, 0x4e, 0xe7, 0xdf, 0x18, 0x4e, 0x7c,
-       0xfc, 0x97, 0xde, 0x39, 0x9d, 0x57, 0x73, 0x42, 0x9f, 0xca, 0x36, 0x5e,
-       0xc3, 0x4e, 0x42, 0xff, 0xa2, 0x45, 0xd1, 0x47, 0xb2, 0x55, 0xd8, 0xaa,
-       0x8b, 0xc2, 0xe6, 0x38, 0xba, 0xa7, 0xd6, 0xdb, 0xf2, 0x71, 0xcf, 0xb9,
-       0x9f, 0x07, 0x72, 0xf3, 0x87, 0x85, 0x6e, 0x36, 0x3c, 0xbe, 0x47, 0xd5,
-       0x9c, 0x7e, 0x5e, 0x5c, 0x33, 0x16, 0x70, 0xed, 0x49, 0x75, 0xed, 0xd7,
-       0x84, 0x4e, 0x8c, 0xfc, 0xb8, 0xd0, 0x35, 0x81, 0xdf, 0xbc, 0xaf, 0x4e,
-       0x8c, 0xf1, 0x3b, 0xb2, 0x04, 0xdf, 0xbc, 0x80, 0xa7, 0x86, 0x07, 0x60,
-       0x01, 0x9c, 0xef, 0x52, 0xf8, 0x6e, 0x5b, 0xa9, 0xa0, 0x5e, 0x77, 0x33,
-       0x38, 0xb3, 0x8e, 0x93, 0xc7, 0x5a, 0xb1, 0xa6, 0xdd, 0x81, 0x44, 0xc9,
-       0x32, 0x72, 0xf3, 0xb0, 0x71, 0xe0, 0x7f, 0xdc, 0x8b, 0xbc, 0x28, 0x9e,
-       0xc3, 0x6e, 0x4a, 0xa4, 0x31, 0x2f, 0x8c, 0xd3, 0x30, 0x18, 0xf7, 0xc0,
-       0xc2, 0x7d, 0xdf, 0x0e, 0x75, 0x5f, 0xbb, 0xd8, 0x0b, 0x32, 0xf0, 0x1e,
-       0xfd, 0x6e, 0xbc, 0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x2e,
-       0xe6, 0xd7, 0xc9, 0x09, 0xf9, 0x2c, 0xe3, 0xa6, 0xbc, 0xb6, 0xcb, 0xf1,
-       0x9f, 0xaf, 0xdc, 0x3f, 0xdc, 0xab, 0xf7, 0x6f, 0x07, 0x95, 0x84, 0x5f,
-       0x09, 0xd7, 0xba, 0xc5, 0xb5, 0xa4, 0xd3, 0x2d, 0xf6, 0x75, 0x8e, 0x8f,
-       0xcf, 0x16, 0x7a, 0x02, 0xb0, 0xd5, 0x73, 0xe9, 0xee, 0x40, 0xa9, 0x84,
-       0xf5, 0x76, 0x07, 0x52, 0x8c, 0xf3, 0xd3, 0x85, 0x23, 0x95, 0x59, 0xc1,
-       0x5b, 0x58, 0xc7, 0xed, 0xb3, 0xcd, 0x33, 0xc6, 0xcf, 0xc4, 0x9a, 0xf8,
-       0x7d, 0xfc, 0x9b, 0xe9, 0x2e, 0xcf, 0x74, 0x97, 0x67, 0xba, 0xcb, 0x33,
-       0xdd, 0xb1, 0x8d, 0xfa, 0x83, 0x3c, 0xd3, 0x1d, 0xcb, 0x90, 0xb7, 0x58,
-       0x86, 0x48, 0x5a, 0x4d, 0x28, 0xdf, 0x9e, 0xa6, 0x55, 0x6f, 0x4d, 0xa6,
-       0xa6, 0x4d, 0xc8, 0x6d, 0x0a, 0x1c, 0x1d, 0xad, 0xa7, 0xd1, 0x3b, 0x4c,
-       0xa3, 0x2d, 0x53, 0xfd, 0xf4, 0xa0, 0x88, 0x3d, 0xb3, 0xad, 0x39, 0xe6,
-       0xd1, 0xa9, 0x20, 0x74, 0xac, 0x10, 0xd3, 0x13, 0x74, 0x4c, 0x9b, 0xe1,
-       0xde, 0x4f, 0xeb, 0xc5, 0x76, 0x1e, 0x03, 0x9a, 0xdd, 0xab, 0x8e, 0xf3,
-       0x4c, 0xb3, 0x90, 0x7b, 0xd7, 0x02, 0x77, 0x0a, 0x06, 0xeb, 0x62, 0x21,
-       0x33, 0x43, 0xe0, 0x9f, 0x42, 0x3f, 0xe3, 0x7d, 0x5f, 0x65, 0x7e, 0x0f,
-       0xdf, 0x29, 0x7a, 0x77, 0x95, 0x20, 0x3b, 0x22, 0xb7, 0x99, 0x7f, 0x5e,
-       0x28, 0x5e, 0x63, 0x3a, 0xef, 0xa3, 0x2f, 0x17, 0x21, 0x9f, 0x01, 0x23,
-       0x3e, 0x2e, 0x91, 0xf0, 0x7d, 0x19, 0x53, 0x58, 0xfb, 0xfe, 0xac, 0x21,
-       0xf0, 0xe4, 0xaf, 0x01, 0x07, 0x86, 0xfd, 0xdd, 0x3d, 0xe8, 0x69, 0x9f,
-       0x30, 0x5a, 0x95, 0x8f, 0x17, 0xbf, 0x31, 0x1e, 0x63, 0x01, 0x37, 0x1c,
-       0x37, 0x8b, 0x2f, 0xe2, 0x1b, 0x11, 0x71, 0x86, 0x87, 0x97, 0x5f, 0x5d,
-       0xe5, 0xfb, 0x05, 0xbc, 0x26, 0x93, 0x41, 0xd4, 0x87, 0xd3, 0xd7, 0x82,
-       0x53, 0x93, 0xf4, 0x72, 0x19, 0xf3, 0xbe, 0x42, 0xb3, 0x61, 0xf0, 0x1f,
-       0x3b, 0x7e, 0x9f, 0x24, 0xec, 0xda, 0x59, 0xdf, 0xfc, 0xa2, 0x3f, 0x4f,
-       0xb3, 0x92, 0x42, 0x3f, 0x6e, 0x63, 0x7b, 0x07, 0xb0, 0x79, 0x83, 0x71,
-       0x2d, 0x0e, 0x1f, 0x80, 0xe2, 0x67, 0xdf, 0x67, 0x9e, 0x83, 0x3d, 0xc3,
-       0x71, 0x3d, 0x0f, 0x5b, 0x53, 0x3c, 0xcc, 0x71, 0xf1, 0xb0, 0x5c, 0x95,
-       0x87, 0x31, 0x2e, 0x08, 0xde, 0x05, 0xde, 0x74, 0x82, 0xf5, 0x45, 0xf9,
-       0x1b, 0x7a, 0xe0, 0x4e, 0xc1, 0xab, 0x98, 0xb7, 0xb3, 0xfd, 0xb0, 0x58,
-       0xce, 0x06, 0x8e, 0x08, 0x9e, 0xa1, 0xf1, 0xf9, 0xa9, 0x01, 0x49, 0x07,
-       0xed, 0xd2, 0x1f, 0x79, 0x0a, 0x7c, 0xca, 0x6f, 0xfc, 0x67, 0x78, 0x1c,
-       0xc6, 0x3b, 0x91, 0xd7, 0x99, 0x7f, 0x2d, 0xc6, 0x63, 0x22, 0x06, 0x22,
-       0x6d, 0x9c, 0x2c, 0xdb, 0x01, 0xbb, 0x90, 0x6b, 0x69, 0x25, 0xab, 0xfc,
-       0x4b, 0xd7, 0x1f, 0xc1, 0xaf, 0x88, 0x3d, 0x4e, 0xf4, 0x1a, 0x72, 0x1d,
-       0x16, 0xd6, 0x31, 0x5b, 0xa4, 0xd0, 0x4c, 0x1c, 0xb9, 0x71, 0xe0, 0xeb,
-       0x1f, 0xf0, 0xba, 0xb1, 0xaf, 0x1f, 0x60, 0x5f, 0xe5, 0xb5, 0x89, 0x63,
-       0x62, 0x5e, 0xb3, 0xcb, 0x35, 0xfe, 0x37, 0x97, 0x1f, 0x30, 0x16, 0x0b,
-       0x72, 0x6e, 0x4b, 0xa3, 0x92, 0xc7, 0x2d, 0x96, 0xd0, 0xab, 0x4b, 0xcc,
-       0x91, 0xe7, 0xa6, 0xd7, 0x85, 0xf7, 0x6a, 0x7a, 0xdf, 0x0a, 0x6d, 0x3d,
-       0xc3, 0x74, 0x84, 0x3d, 0xc8, 0xba, 0x70, 0xe4, 0x5b, 0xfc, 0x7e, 0x9c,
-       0x6b, 0x9c, 0xff, 0x83, 0xea, 0xfc, 0x9f, 0xe4, 0xf9, 0x63, 0xcc, 0x07,
-       0x2c, 0xef, 0xe5, 0xfc, 0x1f, 0x54, 0xe7, 0x5f, 0x54, 0xf3, 0xa7, 0x9c,
-       0x31, 0xd5, 0xab, 0xf4, 0xf7, 0xa6, 0xcf, 0x6a, 0x9f, 0x99, 0x10, 0x63,
-       0xcd, 0x19, 0xe8, 0x44, 0xa6, 0x9e, 0x8b, 0xb6, 0x0d, 0xdd, 0x73, 0xb1,
-       0x63, 0xf7, 0xe9, 0x8f, 0x49, 0xea, 0x1d, 0x43, 0xac, 0x77, 0xe0, 0x3c,
-       0xcd, 0x82, 0xcf, 0xe6, 0xc2, 0xe8, 0x11, 0x3b, 0xc8, 0x30, 0x62, 0x3b,
-       0x6a, 0x82, 0xff, 0x0a, 0xbf, 0x18, 0x9e, 0xa3, 0xef, 0xff, 0x43, 0x5a,
-       0x9f, 0x07, 0x2f, 0x86, 0xfe, 0x29, 0xfb, 0xc8, 0xae, 0xaf, 0x48, 0xff,
-       0x6b, 0xca, 0xd7, 0xff, 0x0a, 0xdf, 0xeb, 0x04, 0xf4, 0x73, 0x13, 0x7e,
-       0xda, 0x69, 0xf5, 0xed, 0x8f, 0x5c, 0x19, 0xcf, 0xf2, 0xe3, 0x2b, 0x93,
-       0xae, 0x1c, 0x35, 0xe4, 0x8c, 0x64, 0x99, 0x4f, 0x38, 0x66, 0x8b, 0x21,
-       0x6b, 0x64, 0x6e, 0x95, 0xb5, 0xae, 0x73, 0x8c, 0xf7, 0xc4, 0x89, 0x1b,
-       0x46, 0x4a, 0xf8, 0x08, 0xda, 0x9d, 0x2e, 0x6a, 0x63, 0x39, 0x78, 0x8e,
-       0xd0, 0xe7, 0xcc, 0xb6, 0x10, 0x3b, 0xb9, 0xca, 0x38, 0x36, 0x1b, 0xb7,
-       0x23, 0xcf, 0x0b, 0x7b, 0x12, 0xf2, 0x01, 0xdf, 0x4e, 0x01, 0xac, 0x30,
-       0x07, 0xfe, 0xbd, 0x8c, 0x9e, 0x95, 0x71, 0x5e, 0x3f, 0x7c, 0xbd, 0x23,
-       0xd6, 0x5d, 0x96, 0x2b, 0x57, 0x85, 0x3f, 0xe5, 0x12, 0xeb, 0x92, 0xb6,
-       0x79, 0x54, 0xd0, 0x99, 0x31, 0xc4, 0x54, 0xc1, 0x74, 0x82, 0x1c, 0x81,
-       0xfd, 0xa2, 0xa7, 0x8e, 0xb4, 0x51, 0x78, 0x95, 0x2b, 0xaa, 0x57, 0x41,
-       0x1a, 0xb4, 0xbf, 0x75, 0x5f, 0x42, 0xfa, 0xa1, 0x7d, 0x28, 0x6e, 0x1d,
-       0xca, 0xeb, 0xa7, 0x86, 0x3d, 0x66, 0x89, 0xde, 0x8c, 0x80, 0x9d, 0xf0,
-       0x03, 0x1a, 0x63, 0x0c, 0x37, 0xfd, 0x9d, 0x1a, 0xb7, 0xbd, 0x7f, 0x5e,
-       0xd4, 0xdc, 0xbf, 0x59, 0x96, 0x32, 0x34, 0xc7, 0xb6, 0xf8, 0xec, 0xb8,
-       0x5b, 0xa7, 0xb0, 0x0b, 0xd3, 0xc2, 0x07, 0x33, 0x40, 0xc9, 0x85, 0x31,
-       0xfa, 0x7c, 0x1e, 0x3c, 0x88, 0xee, 0x27, 0x1d, 0xf1, 0xcd, 0x25, 0x9e,
-       0xd3, 0x18, 0xa5, 0xca, 0x80, 0x51, 0x80, 0x66, 0x99, 0xcb, 0xe7, 0x0a,
-       0x88, 0xbd, 0xf3, 0xef, 0x12, 0xbe, 0xa9, 0xf2, 0x3b, 0xca, 0xb7, 0x1d,
-       0xa5, 0xe9, 0x05, 0xca, 0x66, 0xe2, 0x4f, 0x8b, 0x3e, 0xd3, 0x99, 0xf8,
-       0xa8, 0xf2, 0xc9, 0x44, 0xf8, 0x3c, 0xfc, 0x5c, 0x16, 0x7d, 0x2e, 0x6f,
-       0x67, 0x33, 0x24, 0x7d, 0x0d, 0xc4, 0x73, 0x30, 0x58, 0x76, 0xee, 0x64,
-       0x9e, 0x70, 0x52, 0xf8, 0x1b, 0x58, 0xd3, 0x98, 0xc7, 0x78, 0xf8, 0x0a,
-       0xfa, 0x08, 0xf6, 0x55, 0xa6, 0xf0, 0x92, 0x1a, 0x5b, 0x21, 0x93, 0x71,
-       0xc1, 0xfc, 0x55, 0x27, 0x1b, 0x37, 0x6a, 0xf7, 0xc3, 0x57, 0x71, 0x52,
-       0xe8, 0x7d, 0x43, 0xb4, 0x24, 0x68, 0xbd, 0x52, 0x99, 0x11, 0x7e, 0x07,
-       0x3e, 0x2e, 0x4d, 0x0e, 0x4a, 0x5e, 0x25, 0xcf, 0x4b, 0x7f, 0x04, 0x3f,
-       0xb3, 0xc4, 0xf3, 0xa8, 0xcb, 0x7f, 0x8f, 0x52, 0x62, 0x1b, 0xfe, 0xa1,
-       0x53, 0x8f, 0xd4, 0x3f, 0xc4, 0xb0, 0x66, 0xd9, 0x71, 0x8b, 0x69, 0xe3,
-       0xc7, 0x9b, 0xda, 0x6d, 0xef, 0x69, 0x19, 0xcc, 0xb0, 0x32, 0xc5, 0xb7,
-       0x2b, 0xa0, 0x33, 0xcf, 0x96, 0xe7, 0xf0, 0x1d, 0x99, 0x40, 0x5a, 0xe8,
-       0xb2, 0x11, 0xd6, 0x4d, 0xa0, 0xa3, 0x8c, 0x88, 0x78, 0x62, 0xe2, 0x59,
-       0xcb, 0x98, 0x5d, 0xc1, 0xb7, 0xa1, 0xa0, 0x9b, 0xe9, 0x9c, 0x86, 0x76,
-       0x91, 0xa7, 0x2e, 0xe3, 0xbc, 0x90, 0xaf, 0xe0, 0x79, 0x3f, 0x0f, 0x64,
-       0x56, 0x9e, 0xde, 0xa5, 0xf3, 0xd5, 0x12, 0x61, 0x9d, 0x0f, 0xa3, 0x79,
-       0x8a, 0xc6, 0x3d, 0x1d, 0xa3, 0x70, 0x7f, 0xcb, 0x0b, 0xb4, 0xeb, 0xd6,
-       0x09, 0xe0, 0x57, 0x12, 0x7b, 0x74, 0x15, 0xb1, 0x31, 0xa3, 0x2e, 0xfe,
-       0xd0, 0xc6, 0xfb, 0x64, 0x31, 0x6e, 0xc0, 0x5f, 0xf7, 0x05, 0xfe, 0x8b,
-       0x38, 0x42, 0x69, 0x10, 0x7a, 0x50, 0xaf, 0xc3, 0x38, 0x33, 0x81, 0xe3,
-       0x7e, 0x5a, 0x2c, 0x6a, 0xbd, 0x55, 0xfa, 0x90, 0x16, 0x97, 0xf5, 0x7e,
-       0xc1, 0x7f, 0x34, 0xac, 0x7a, 0x08, 0xd8, 0x64, 0xf5, 0x01, 0x4e, 0x9f,
-       0x14, 0x3d, 0x6e, 0x16, 0x73, 0xd8, 0x4a, 0xce, 0x11, 0xbe, 0x2f, 0x86,
-       0x9e, 0x99, 0xfb, 0x00, 0x7b, 0xde, 0x23, 0x77, 0x4c, 0x62, 0x4e, 0x7d,
-       0xff, 0xe7, 0x51, 0xed, 0xdb, 0x63, 0x3e, 0xfb, 0xf6, 0xd1, 0xa0, 0x8c,
-       0x73, 0x3d, 0xa7, 0xc6, 0xf8, 0xe5, 0x99, 0xfe, 0xf3, 0x0b, 0xf0, 0x1f,
-       0xd5, 0xea, 0x25, 0xee, 0x09, 0xbe, 0xd2, 0xe8, 0xc3, 0x8e, 0x30, 0x3f,
-       0x95, 0x74, 0x7c, 0xd2, 0x87, 0x8e, 0xfb, 0x78, 0x8f, 0x4f, 0x3c, 0x04,
-       0x1d, 0x9f, 0x68, 0x4a, 0xc7, 0x87, 0xa2, 0xd2, 0x87, 0xda, 0x48, 0xc7,
-       0xa8, 0xd9, 0x39, 0x59, 0x6e, 0xe6, 0xaf, 0xc2, 0x3e, 0xa0, 0xf6, 0x1c,
-       0xfe, 0x04, 0xc0, 0x4a, 0xfb, 0x14, 0x10, 0xdb, 0x03, 0x3e, 0x22, 0x56,
-       0xf2, 0x17, 0x94, 0x9a, 0xf7, 0xc6, 0x38, 0x37, 0xba, 0xe7, 0x7d, 0x9f,
-       0x7b, 0xa0, 0x6b, 0x83, 0x16, 0xec, 0x88, 0xb4, 0xd5, 0x35, 0xbc, 0xde,
-       0x0d, 0x1c, 0x29, 0xda, 0xd9, 0x12, 0x18, 0x63, 0x4f, 0x98, 0xce, 0x23,
-       0x8e, 0xaf, 0x7c, 0xbe, 0xc7, 0xf3, 0x72, 0xdd, 0xe6, 0xb8, 0xc0, 0x07,
-       0xe8, 0xa3, 0x91, 0x74, 0x30, 0xcd, 0x7b, 0x2a, 0xfd, 0xbd, 0x99, 0xe5,
-       0x88, 0xda, 0x27, 0x1e, 0x8b, 0xe7, 0xf9, 0xd6, 0xf3, 0x61, 0x7f, 0xec,
-       0x57, 0x57, 0xab, 0x79, 0xc1, 0x90, 0x05, 0x15, 0xfa, 0x05, 0xcb, 0xb9,
-       0xe0, 0xb8, 0x29, 0xfa, 0x28, 0xdc, 0x2a, 0x8f, 0xb3, 0x7e, 0x88, 0x3d,
-       0x84, 0xaf, 0x50, 0xfb, 0x72, 0x7f, 0x31, 0x44, 0x3d, 0x87, 0x58, 0xea,
-       0x1b, 0xe4, 0xb0, 0x7e, 0x68, 0x8c, 0x23, 0xbf, 0xdb, 0xe2, 0x7b, 0xd0,
-       0xff, 0x69, 0xbf, 0x95, 0xa2, 0x2e, 0xf8, 0x09, 0xd0, 0xa7, 0xd9, 0xca,
-       0xd5, 0xd1, 0xd4, 0x69, 0x41, 0x53, 0xa9, 0x95, 0xd3, 0x8a, 0xa6, 0x4e,
-       0x2b, 0x7f, 0xf9, 0x69, 0x45, 0x53, 0xa7, 0x15, 0x4d, 0x9d, 0x56, 0x34,
-       0x75, 0x9a, 0xf1, 0x7a, 0xc4, 0xec, 0x13, 0x3a, 0xbb, 0xf6, 0x57, 0xf6,
-       0x50, 0xa6, 0x88, 0xf3, 0x90, 0xc7, 0x5e, 0xba, 0x7a, 0x75, 0x48, 0xd2,
-       0xd5, 0x24, 0x2d, 0xca, 0x3c, 0x39, 0x7e, 0x17, 0xf6, 0xe0, 0xeb, 0x83,
-       0xd4, 0x73, 0x2f, 0x70, 0x76, 0x1e, 0x73, 0x0d, 0xd0, 0xb4, 0xe8, 0xe1,
-       0xda, 0x42, 0x49, 0xb7, 0x2e, 0x6b, 0xa2, 0x7e, 0x4b, 0xda, 0x6a, 0xd9,
-       0xa6, 0xb5, 0x5c, 0x1a, 0x2f, 0xa6, 0xd4, 0x7e, 0x79, 0xed, 0x98, 0x36,
-       0x4a, 0x17, 0x00, 0x57, 0xe4, 0x32, 0x5a, 0xbc, 0x37, 0x02, 0x4e, 0x59,
-       0xd3, 0x07, 0x06, 0xc7, 0x15, 0x0c, 0xbe, 0x22, 0xd6, 0x88, 0x5c, 0x40,
-       0xf8, 0x1c, 0x9b, 0xc3, 0x21, 0x97, 0x1f, 0xe1, 0xe7, 0x30, 0xee, 0x8f,
-       0x47, 0x98, 0x07, 0x6d, 0x1d, 0x0e, 0xb5, 0xb5, 0x37, 0xe3, 0x35, 0x5b,
-       0xad, 0x87, 0xb9, 0xef, 0x92, 0x1d, 0x11, 0x25, 0x37, 0xa4, 0x9e, 0xfb,
-       0x98, 0x63, 0xa7, 0xb3, 0x3c, 0xb7, 0xbf, 0x8f, 0xb7, 0xef, 0xa5, 0x8e,
-       0x0a, 0x1d, 0x8b, 0x03, 0x9f, 0x7b, 0xd8, 0x6e, 0xe4, 0x39, 0xec, 0xaf,
-       0xd0, 0xd5, 0xf8, 0x01, 0xb6, 0x4d, 0xf0, 0x2d, 0xa6, 0x11, 0xfe, 0xef,
-       0x24, 0x82, 0x01, 0xcc, 0xab, 0x8b, 0xef, 0x0d, 0x93, 0xd1, 0x9b, 0xe8,
-       0x6d, 0x57, 0xba, 0x29, 0xfc, 0x6e, 0xac, 0x9b, 0x1a, 0x33, 0xf1, 0x1d,
-       0xaa, 0xa6, 0x0c, 0xbe, 0x6a, 0xc4, 0xb1, 0x7e, 0x56, 0x91, 0xbd, 0x00,
-       0xa2, 0xea, 0xf8, 0xa7, 0x95, 0x44, 0x14, 0xc7, 0x26, 0xdd, 0x60, 0x7b,
-       0x39, 0x11, 0x18, 0xd9, 0x2b, 0x74, 0xf6, 0x80, 0x7d, 0x4c, 0xe6, 0x30,
-       0xd8, 0xa6, 0x15, 0xf0, 0xc3, 0x77, 0xa9, 0xeb, 0xd4, 0xf2, 0x4c, 0x81,
-       0xff, 0x15, 0xfa, 0x4f, 0xa6, 0x55, 0x93, 0x10, 0xb3, 0x98, 0x14, 0xb5,
-       0xce, 0xc8, 0x33, 0x3e, 0x3b, 0x0f, 0x9a, 0x85, 0xdf, 0xd0, 0x51, 0x7b,
-       0xfc, 0x29, 0xe4, 0x89, 0x15, 0x16, 0x69, 0x63, 0x59, 0x01, 0xbf, 0xd8,
-       0xc8, 0xc2, 0x5a, 0x6f, 0x58, 0xd4, 0x5e, 0xc3, 0xcf, 0xa9, 0xf3, 0x89,
-       0xf7, 0xf3, 0xf3, 0x43, 0xe2, 0xdb, 0x72, 0xd3, 0xd7, 0x30, 0xae, 0x95,
-       0x86, 0x17, 0x2a, 0x4f, 0xf1, 0x75, 0x11, 0x2f, 0xcc, 0x50, 0xbb, 0x8a,
-       0x05, 0x74, 0xa9, 0xf8, 0x51, 0x84, 0x69, 0xa8, 0x56, 0x53, 0x3c, 0x5c,
-       0xf5, 0x9d, 0x01, 0xb7, 0xbd, 0xbe, 0xb3, 0xaf, 0x6d, 0x22, 0x67, 0x36,
-       0xc3, 0x67, 0xe4, 0x82, 0xb6, 0x91, 0xf2, 0x09, 0x5a, 0xb3, 0xb4, 0xd5,
-       0xda, 0xb9, 0x6d, 0xdf, 0xd3, 0xde, 0x3a, 0xb5, 0x7a, 0xf1, 0xae, 0xd3,
-       0xa1, 0xf0, 0xa8, 0x95, 0xce, 0x16, 0x3b, 0x58, 0x56, 0xa3, 0xce, 0x09,
-       0xf0, 0x0a, 0x46, 0x51, 0x27, 0xf2, 0x5c, 0xa8, 0x95, 0x96, 0x97, 0x91,
-       0xd3, 0xf0, 0x67, 0x7b, 0x65, 0x7e, 0x6e, 0x9a, 0xe1, 0x72, 0x88, 0xe5,
-       0x9a, 0xa1, 0x62, 0x35, 0x38, 0x07, 0x9e, 0x20, 0x7a, 0x78, 0x86, 0x9e,
-       0x1e, 0xed, 0x60, 0x7d, 0x5e, 0xfa, 0xfa, 0x0f, 0xf3, 0xb3, 0xbf, 0x57,
-       0x4c, 0xc3, 0x4f, 0x65, 0x1e, 0xe5, 0xe7, 0x4f, 0xb3, 0x1e, 0x90, 0xa0,
-       0x56, 0x5a, 0x5a, 0x6e, 0x65, 0x7d, 0xbe, 0x95, 0xf5, 0x80, 0x11, 0x73,
-       0x38, 0x20, 0xde, 0x25, 0x6a, 0x52, 0x3e, 0x1b, 0x3a, 0x64, 0x1e, 0x13,
-       0x79, 0x36, 0x7f, 0xa5, 0xde, 0xe5, 0x7d, 0xc7, 0x07, 0x15, 0x1c, 0x1f,
-       0x0d, 0xae, 0x5e, 0xbc, 0xe3, 0x98, 0x8c, 0x7f, 0x93, 0xac, 0xf3, 0x86,
-       0xc5, 0xf7, 0x17, 0x8d, 0xa9, 0x29, 0xd6, 0xff, 0xf1, 0x8d, 0xb7, 0x67,
-       0x28, 0x5b, 0x3e, 0x45, 0x5f, 0x2f, 0xbb, 0x7d, 0xaf, 0xcf, 0xf0, 0x9c,
-       0x65, 0xed, 0x7c, 0x1b, 0xcf, 0xeb, 0x3d, 0xc7, 0xcb, 0x2b, 0x3a, 0x28,
-       0xf8, 0xad, 0x30, 0xb5, 0x7e, 0x03, 0x3e, 0x8f, 0x0a, 0x15, 0xe2, 0xf6,
-       0xd5, 0xfb, 0x24, 0xfd, 0xbc, 0x37, 0x44, 0x5e, 0x2a, 0xdf, 0xcf, 0xcf,
-       0x9c, 0xc3, 0xb8, 0x1b, 0x16, 0xdd, 0x76, 0x24, 0xbc, 0xff, 0x36, 0x14,
-       0xa6, 0xe0, 0x1b, 0xc8, 0xf5, 0x82, 0x8e, 0xb5, 0x7a, 0xd1, 0x39, 0xc0,
-       0x7c, 0xfa, 0x1b, 0xb8, 0x8f, 0xff, 0xbe, 0x81, 0xe3, 0x0e, 0x5e, 0x27,
-       0xe4, 0x2c, 0x72, 0x4a, 0xc0, 0xdf, 0x0e, 0x45, 0x4c, 0x81, 0x7f, 0xcf,
-       0x30, 0x4e, 0xb5, 0x08, 0x1f, 0x5f, 0x1f, 0xc6, 0x3a, 0x83, 0xac, 0x13,
-       0xac, 0x5e, 0x1c, 0x3d, 0x80, 0xe3, 0x44, 0x6f, 0x90, 0x61, 0x24, 0x71,
-       0xa8, 0xe1, 0x9b, 0x75, 0xa1, 0xc3, 0xa3, 0xe4, 0xfa, 0x6e, 0x1d, 0x7a,
-       0x26, 0x75, 0x50, 0x8a, 0xdf, 0x31, 0x5d, 0x94, 0xeb, 0x9e, 0x2b, 0x07,
-       0x49, 0xfa, 0x87, 0x52, 0x43, 0xfa, 0xfb, 0x84, 0xd4, 0x8f, 0x67, 0x6b,
-       0x5a, 0xc1, 0xef, 0x1e, 0x7a, 0x50, 0xec, 0xa2, 0x75, 0x15, 0x43, 0x7a,
-       0x20, 0xec, 0x29, 0xe6, 0xc5, 0xe9, 0x1e, 0xba, 0xbf, 0xdc, 0x42, 0xd4,
-       0xd7, 0x21, 0x62, 0xbc, 0x0f, 0x8a, 0x8b, 0x94, 0x7c, 0xed, 0xc9, 0x21,
-       0xe9, 0x4f, 0xa9, 0xe1, 0xc8, 0x03, 0x1f, 0x1c, 0x79, 0x57, 0xe0, 0xc8,
-       0xf0, 0xd0, 0xc6, 0x38, 0xb2, 0x47, 0xe7, 0x22, 0x52, 0xab, 0xc2, 0x8f,
-       0xd7, 0x19, 0x3f, 0x5e, 0x66, 0xfc, 0x38, 0xd2, 0x04, 0x3f, 0x0c, 0x0f,
-       0x7e, 0x1c, 0x15, 0xf8, 0xf1, 0xeb, 0x43, 0x1b, 0xe1, 0xc7, 0x91, 0xe0,
-       0x46, 0x3e, 0x1e, 0x8d, 0x9b, 0x03, 0xb4, 0x54, 0x74, 0x68, 0x79, 0xde,
-       0x8e, 0x27, 0x68, 0x35, 0x22, 0x63, 0x83, 0x53, 0xa2, 0x4e, 0x65, 0x51,
-       0xe0, 0x55, 0x5a, 0xf8, 0x2f, 0xfd, 0xbf, 0x1b, 0x68, 0x29, 0xf8, 0xcb,
-       0x3d, 0x99, 0xce, 0xaf, 0x5e, 0xfc, 0x3b, 0xde, 0xc7, 0xdb, 0x2b, 0xa1,
-       0x10, 0xae, 0x05, 0xa7, 0xc2, 0xb4, 0xb6, 0x82, 0xef, 0x12, 0x46, 0xe8,
-       0x4e, 0x31, 0x4a, 0xb7, 0x8b, 0x03, 0xb4, 0x56, 0x1c, 0xa2, 0xbb, 0x45,
-       0xbc, 0x03, 0x30, 0xe7, 0x63, 0x01, 0x73, 0x83, 0x0e, 0x87, 0x79, 0xcc,
-       0xf2, 0x00, 0xad, 0x2e, 0x6b, 0x7c, 0x05, 0xae, 0x62, 0xff, 0xe1, 0x27,
-       0xf0, 0xc7, 0x81, 0xe9, 0x3a, 0x1c, 0x90, 0xf7, 0x60, 0xef, 0x67, 0x1b,
-       0x6b, 0x64, 0x45, 0x9e, 0xa5, 0xc9, 0x38, 0xd2, 0x32, 0x65, 0x0b, 0x5f,
-       0xea, 0xe1, 0x20, 0x74, 0xd9, 0xc4, 0x3e, 0xea, 0xe1, 0x3d, 0x70, 0x90,
-       0x27, 0x34, 0xc4, 0x7a, 0xe9, 0x0e, 0xa1, 0x87, 0x26, 0x9d, 0x50, 0x64,
-       0x9a, 0x2a, 0x97, 0x0c, 0x07, 0x3d, 0x0f, 0xd3, 0xfc, 0x3c, 0x43, 0xf9,
-       0x71, 0xba, 0x5d, 0xf8, 0xe4, 0xd5, 0x39, 0x11, 0x8b, 0x7d, 0x96, 0xe7,
-       0x0c, 0xf9, 0x58, 0x8b, 0x73, 0x50, 0x35, 0xce, 0xd1, 0xce, 0xeb, 0x96,
-       0xb4, 0x34, 0xe3, 0xf0, 0xb8, 0x32, 0x8f, 0x2b, 0x23, 0x76, 0xc6, 0xe7,
-       0x97, 0x11, 0xb7, 0x8d, 0xd2, 0xda, 0x3c, 0x68, 0x0e, 0x7e, 0x89, 0x5a,
-       0xac, 0x74, 0x6d, 0x05, 0xe7, 0xe1, 0x9b, 0xa8, 0xc5, 0x4a, 0xd7, 0x54,
-       0xac, 0x74, 0x6d, 0x65, 0x4a, 0xf0, 0xe1, 0xd9, 0xff, 0xdd, 0x14, 0x60,
-       0x19, 0x30, 0x85, 0x19, 0xba, 0x4e, 0x53, 0x0d, 0x7a, 0xbf, 0x4e, 0x0c,
-       0x78, 0x6c, 0x58, 0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d,
-       0xb8, 0xfd, 0xe3, 0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23,
-       0x80, 0x79, 0x49, 0x18, 0x9a, 0x97, 0x60, 0x73, 0xaf, 0xfc, 0x0c, 0x90,
-       0xbb, 0x7a, 0x6c, 0xc0, 0x6d, 0x7c, 0x48, 0xf9, 0x23, 0x83, 0x56, 0xfe,
-       0x30, 0xb0, 0x38, 0xa9, 0x43, 0xf4, 0x37, 0xad, 0x7f, 0x2c, 0x07, 0x1b,
-       0x5f, 0x6b, 0x02, 0x9a, 0xdb, 0x3c, 0x85, 0x94, 0xb9, 0x5b, 0x60, 0xbd,
-       0x89, 0x75, 0x5d, 0x26, 0xb1, 0x76, 0xc3, 0xd2, 0x42, 0x0c, 0x19, 0xe9,
-       0x09, 0x62, 0x06, 0x22, 0x3d, 0xd9, 0x00, 0xcb, 0x4e, 0x16, 0x60, 0x5e,
-       0x11, 0x02, 0xd6, 0x0f, 0x0c, 0xd0, 0x3a, 0xe6, 0x00, 0x78, 0x2c, 0xa1,
-       0x89, 0x01, 0x74, 0x07, 0x27, 0xd0, 0xfe, 0x7e, 0x65, 0xf0, 0xba, 0xe3,
-       0x06, 0x09, 0x88, 0xa1, 0x8b, 0x7a, 0x14, 0xe5, 0x41, 0x79, 0xd4, 0x49,
-       0x85, 0x81, 0xc4, 0xfc, 0x04, 0xf2, 0x1f, 0xd0, 0x1f, 0x20, 0x3f, 0x02,
-       0xf3, 0x93, 0x33, 0x50, 0x0e, 0xb4, 0x36, 0xaa, 0x79, 0x0d, 0x48, 0x1f,
-       0x28, 0x0c, 0x41, 0x65, 0x2a, 0x68, 0x8c, 0x03, 0xc8, 0x5e, 0x22, 0x04,
-       0x0d, 0x3b, 0x20, 0x0d, 0x64, 0x37, 0x4f, 0x11, 0x01, 0xf3, 0x93, 0x02,
-       0x84, 0x18, 0x1a, 0xe0, 0xf9, 0x89, 0x1d, 0xe8, 0x52, 0x98, 0x9b, 0xfe,
-       0xff, 0x3f, 0xa6, 0xc2, 0x02, 0x4c, 0x7b, 0xa0, 0xb5, 0xb5, 0xbf, 0xff,
-       0x1f, 0x10, 0x61, 0x61, 0x68, 0x81, 0xaf, 0xd1, 0x0b, 0x94, 0x07, 0x95,
-       0x73, 0x0b, 0x80, 0xac, 0x36, 0x78, 0xbd, 0x0d, 0x92, 0x07, 0x89, 0xfd,
-       0x02, 0x96, 0x2b, 0xff, 0xff, 0x2f, 0x85, 0xab, 0x05, 0x01, 0x00, 0xb3,
-       0x28, 0x79, 0xae, 0x58, 0x7d, 0x00, 0x00, 0x00 };
+       0xcd, 0x7c, 0x0d, 0x70, 0x5c, 0xd5, 0x95, 0xe6, 0xe9, 0xd7, 0xdd, 0x52,
+       0x4b, 0x96, 0xe5, 0x27, 0xb9, 0x51, 0x1a, 0xa2, 0x24, 0xef, 0xa9, 0x9f,
+       0xa4, 0x06, 0x29, 0xe4, 0xd9, 0x08, 0x10, 0x49, 0x0f, 0x34, 0xdd, 0x92,
+       0x11, 0x89, 0x77, 0x24, 0x40, 0x61, 0xbc, 0x3b, 0xae, 0xac, 0xa6, 0x2d,
+       0x13, 0x42, 0x31, 0x35, 0xae, 0x0a, 0x3b, 0x71, 0xb2, 0x04, 0x37, 0x2d,
+       0x99, 0x38, 0x8c, 0xec, 0x56, 0x64, 0x59, 0x66, 0x67, 0xd8, 0xd9, 0x4e,
+       0x4b, 0xb2, 0x19, 0xa6, 0xed, 0xc6, 0x90, 0x1f, 0xa6, 0x92, 0x0c, 0x5a,
+       0xe3, 0x00, 0x93, 0xcd, 0x56, 0x41, 0x2a, 0xb5, 0xcb, 0x6c, 0x51, 0xbb,
+       0x5e, 0x27, 0x4c, 0xb2, 0xa9, 0xda, 0x0a, 0x3b, 0x93, 0xda, 0x65, 0xf2,
+       0x33, 0x6f, 0xbf, 0xef, 0xbe, 0xfb, 0xa4, 0x96, 0xac, 0x38, 0x4c, 0xa6,
+       0x52, 0x35, 0xaa, 0xea, 0xba, 0xef, 0xde, 0x77, 0x7f, 0xce, 0x3d, 0xf7,
+       0xdc, 0x73, 0xbe, 0x73, 0xee, 0x7d, 0xba, 0x55, 0xa4, 0x59, 0xf4, 0xdf,
+       0x56, 0xfc, 0x06, 0x7e, 0xff, 0x0f, 0xf6, 0xdd, 0x78, 0xbd, 0x7b, 0x3d,
+       0xf3, 0x46, 0x54, 0x22, 0x4c, 0xc3, 0xf8, 0xc5, 0xf1, 0xdb, 0xa9, 0x9f,
+       0x37, 0xfb, 0x33, 0xf1, 0xbb, 0x29, 0x24, 0x32, 0xf1, 0x23, 0x91, 0xd0,
+       0x86, 0x77, 0xb1, 0x4d, 0xea, 0x7b, 0xde, 0x2f, 0xe9, 0x48, 0xff, 0x19,
+       0xf8, 0x59, 0x57, 0xae, 0xb2, 0x3a, 0xee, 0xaf, 0xfb, 0x17, 0xd6, 0xcd,
+       0xb7, 0xea, 0x9f, 0xc4, 0x8c, 0xf4, 0xc5, 0xdf, 0xce, 0x3a, 0x12, 0x0b,
+       0xa7, 0xbf, 0x3b, 0xba, 0xcf, 0x11, 0xc9, 0x54, 0xfb, 0xac, 0x9c, 0xfc,
+       0xc2, 0x2b, 0xc4, 0x23, 0xc2, 0xf2, 0xf7, 0xa4, 0x7f, 0x7e, 0xe8, 0x1b,
+       0x37, 0xdb, 0x6f, 0x95, 0xc3, 0x12, 0x33, 0xd3, 0x6f, 0x8b, 0xd9, 0x23,
+       0xb1, 0x4e, 0xb4, 0x79, 0xb2, 0xf7, 0x29, 0x43, 0x5a, 0x83, 0xbe, 0xcc,
+       0x89, 0x70, 0x5a, 0xc6, 0x26, 0x67, 0x0e, 0x79, 0x86, 0x23, 0x85, 0x6b,
+       0xd2, 0x8e, 0x55, 0x94, 0x96, 0xc1, 0xe9, 0x81, 0x9b, 0x05, 0xf9, 0xb1,
+       0xc9, 0x6a, 0x4c, 0xb2, 0xb5, 0x42, 0x8b, 0xe1, 0x38, 0x48, 0x63, 0x85,
+       0x77, 0xa7, 0x25, 0xd6, 0x90, 0x9e, 0x6f, 0x7c, 0xc9, 0xe1, 0xf8, 0x89,
+       0xd1, 0xac, 0xf3, 0x6e, 0x89, 0x38, 0x9e, 0x37, 0x8d, 0xf1, 0x77, 0x55,
+       0x7f, 0xe1, 0x3d, 0x1a, 0xf1, 0xc7, 0x36, 0xd2, 0x07, 0xc3, 0x4c, 0x43,
+       0x69, 0x6b, 0xb4, 0xab, 0xaa, 0xf2, 0x0d, 0x7e, 0xde, 0xd1, 0xf9, 0x58,
+       0xb3, 0x4f, 0xbb, 0x34, 0x81, 0xf6, 0x58, 0x24, 0x9d, 0x6e, 0x42, 0x1f,
+       0xb1, 0x68, 0xfa, 0x99, 0xdf, 0x5a, 0x56, 0xf5, 0xee, 0xd7, 0xf5, 0xee,
+       0x8f, 0xfa, 0xed, 0x26, 0x47, 0x7b, 0xaa, 0x4c, 0x1f, 0x1a, 0xed, 0x56,
+       0xe9, 0xc3, 0xa3, 0x49, 0x95, 0x16, 0x54, 0xbd, 0x50, 0x7a, 0x7a, 0xd4,
+       0x51, 0x69, 0xa7, 0x2e, 0x4f, 0x8d, 0x5a, 0x2a, 0xed, 0xd7, 0xa9, 0xab,
+       0xd3, 0x01, 0x9d, 0x0e, 0xea, 0x34, 0xad, 0xd3, 0x8c, 0x4e, 0x87, 0x74,
+       0x3f, 0x23, 0x3a, 0xbf, 0x5b, 0xa7, 0x63, 0x3a, 0x1d, 0xd7, 0xe9, 0x1e,
+       0x9d, 0xee, 0xd5, 0x74, 0x4d, 0xe8, 0xf4, 0x41, 0x5d, 0x7e, 0x40, 0xd3,
+       0x79, 0x10, 0xf4, 0x7c, 0xa6, 0x51, 0xcb, 0x2d, 0xe6, 0x6b, 0xc9, 0xbe,
+       0x99, 0x98, 0x14, 0x4b, 0x61, 0xc9, 0xa9, 0xf5, 0xfc, 0x7c, 0x54, 0x9a,
+       0x63, 0x32, 0x55, 0x8b, 0xc9, 0x45, 0x25, 0xae, 0x3f, 0xf4, 0xbe, 0xd1,
+       0x6b, 0xca, 0x33, 0xb5, 0xb8, 0xbc, 0x50, 0x93, 0xd0, 0x58, 0x6f, 0x93,
+       0x18, 0x73, 0xd7, 0x48, 0xc6, 0x0c, 0x49, 0x58, 0xf1, 0xd5, 0x92, 0xec,
+       0x4c, 0x07, 0xf2, 0x76, 0x42, 0xe4, 0xe5, 0xa8, 0xbf, 0x8e, 0x31, 0x09,
+       0x2f, 0x70, 0x5d, 0x16, 0x46, 0x5f, 0x9a, 0x4f, 0x48, 0xe4, 0x98, 0x85,
+       0xfe, 0x5b, 0x24, 0xba, 0x20, 0x9d, 0x61, 0xe9, 0x4e, 0xdc, 0x87, 0x1a,
+       0x43, 0xd5, 0x88, 0x0c, 0x57, 0x43, 0x58, 0xab, 0x18, 0xe4, 0xa4, 0x05,
+       0x3f, 0x13, 0xbf, 0x38, 0x7e, 0x09, 0xfc, 0x3c, 0xf4, 0xd3, 0x29, 0xb9,
+       0x2a, 0xfb, 0xc4, 0xb8, 0x25, 0x8c, 0x5f, 0xb2, 0xcd, 0x09, 0x21, 0x4d,
+       0x09, 0xf9, 0x46, 0xaf, 0x4f, 0xd3, 0x0b, 0xb5, 0x58, 0x28, 0x7b, 0x52,
+       0x0e, 0xe4, 0x5c, 0xb1, 0x0c, 0xa7, 0x59, 0xf2, 0x66, 0xc8, 0x9a, 0x4c,
+       0xb5, 0x4b, 0x61, 0x1c, 0xef, 0x4a, 0x92, 0x31, 0xd0, 0x77, 0xde, 0x94,
+       0x09, 0xff, 0x1d, 0xcb, 0xfe, 0x1e, 0xfb, 0xd5, 0x36, 0x29, 0xb8, 0x2f,
+       0x94, 0xfe, 0x02, 0xcf, 0xec, 0xeb, 0xcd, 0x88, 0x4f, 0xf3, 0xdb, 0xc8,
+       0xb3, 0xfc, 0x67, 0xdb, 0xfc, 0x3c, 0x9f, 0x59, 0x37, 0x18, 0x33, 0x98,
+       0x2b, 0xc7, 0xee, 0xc5, 0x7c, 0x39, 0xfe, 0xea, 0x7c, 0x41, 0x47, 0x4b,
+       0x28, 0x77, 0xd2, 0x92, 0xc3, 0xa5, 0x5b, 0x25, 0xeb, 0x7a, 0xde, 0x3e,
+       0x57, 0xe2, 0x86, 0x74, 0x9b, 0x39, 0xbc, 0xad, 0x54, 0x25, 0x94, 0x2d,
+       0x05, 0xfc, 0x60, 0xbf, 0x11, 0x94, 0x75, 0xa0, 0x7e, 0x6b, 0x68, 0xe8,
+       0x24, 0x68, 0x4f, 0x93, 0x2f, 0x90, 0x59, 0xb7, 0x3b, 0x31, 0x89, 0xf1,
+       0x16, 0xab, 0xdd, 0xee, 0x79, 0x31, 0xd1, 0x67, 0x3b, 0xea, 0x90, 0x47,
+       0xec, 0x8b, 0x7d, 0xb2, 0xbf, 0x16, 0xb4, 0x8d, 0xe3, 0x1d, 0x69, 0xf2,
+       0xbc, 0xac, 0x6b, 0x32, 0x2f, 0x65, 0xf0, 0xad, 0x4c, 0xbe, 0x35, 0x77,
+       0xca, 0xa9, 0x2a, 0xc7, 0xd8, 0x8c, 0xee, 0xeb, 0xfe, 0x99, 0xd1, 0x9d,
+       0x40, 0xff, 0x71, 0xa4, 0x5b, 0x42, 0xd9, 0xe3, 0x1e, 0xc6, 0x4f, 0xe0,
+       0x79, 0xb3, 0x39, 0x5c, 0xd4, 0x32, 0x98, 0x00, 0xed, 0x71, 0x39, 0xa7,
+       0xe4, 0x70, 0x8b, 0x84, 0x21, 0x87, 0x5c, 0xe3, 0xb6, 0x85, 0x1b, 0x25,
+       0x1f, 0xb7, 0x2d, 0xea, 0xce, 0xae, 0x9d, 0x4d, 0x98, 0xa3, 0xd6, 0x82,
+       0xc7, 0xe2, 0x90, 0xc3, 0xf3, 0x6d, 0x06, 0x4a, 0x0c, 0xb1, 0xcd, 0x7f,
+       0x25, 0x05, 0xc9, 0x2d, 0x7d, 0x2a, 0x24, 0xcd, 0x06, 0xea, 0x5d, 0x1b,
+       0xf2, 0x79, 0x40, 0xfe, 0x64, 0xc0, 0x9f, 0x90, 0xf8, 0xfb, 0x3a, 0x23,
+       0x5d, 0x55, 0xbe, 0xef, 0xb3, 0x0c, 0xf5, 0x6e, 0x08, 0xef, 0x22, 0x92,
+       0xdc, 0x19, 0xbc, 0x1f, 0xc2, 0xfb, 0x6b, 0x64, 0xc2, 0x04, 0x2d, 0xa5,
+       0xe7, 0x8d, 0x2c, 0x68, 0xbc, 0x3d, 0xa2, 0xe6, 0x8a, 0xba, 0x13, 0x75,
+       0xfd, 0x4c, 0xa0, 0xde, 0x1f, 0x63, 0x2c, 0xd0, 0x5b, 0xb2, 0x40, 0x4b,
+       0x07, 0x68, 0x21, 0x8d, 0x05, 0x23, 0x5b, 0x8b, 0x20, 0x3f, 0x6d, 0xe4,
+       0x4e, 0x1f, 0xc1, 0xb3, 0x98, 0x46, 0xfa, 0x79, 0xa6, 0x68, 0xbf, 0xb7,
+       0xae, 0xfd, 0x5e, 0xb4, 0xe7, 0x18, 0x6c, 0xef, 0xcb, 0x7f, 0x41, 0xc9,
+       0xa2, 0x75, 0x05, 0x7e, 0x84, 0x7f, 0x0d, 0x7e, 0x7c, 0x4d, 0xf3, 0xe3,
+       0x67, 0xf2, 0x9b, 0xe7, 0xc7, 0x7f, 0xff, 0x0d, 0xf1, 0x43, 0x24, 0x7f,
+       0x9c, 0xcf, 0x11, 0x29, 0x28, 0xbd, 0xc5, 0x7d, 0x4b, 0x79, 0xa7, 0xce,
+       0x22, 0x9f, 0x28, 0xc7, 0xd8, 0x03, 0xb5, 0x08, 0xd2, 0xa7, 0x90, 0x6e,
+       0x09, 0x8d, 0x1d, 0xbf, 0x84, 0xf5, 0xf7, 0xc4, 0xdc, 0x19, 0xd8, 0x8d,
+       0x42, 0xc2, 0x94, 0x4e, 0x31, 0xaf, 0x87, 0xd1, 0xee, 0xb0, 0xcd, 0xbc,
+       0xbc, 0x89, 0xf7, 0xbf, 0x08, 0x05, 0xf6, 0x3d, 0x3b, 0xd3, 0xf4, 0x76,
+       0x46, 0x3d, 0x45, 0xc9, 0xcf, 0x8c, 0x91, 0x8e, 0x84, 0x72, 0x25, 0x6b,
+       0xc2, 0x48, 0xc7, 0xa1, 0xa7, 0x98, 0x1f, 0x0c, 0xf9, 0x34, 0x0f, 0xa0,
+       0x6e, 0xa0, 0xb3, 0x02, 0xda, 0x07, 0x40, 0xfb, 0x46, 0xdd, 0x95, 0x01,
+       0x2d, 0xa4, 0x81, 0x74, 0x55, 0xc2, 0x9a, 0xf7, 0xe8, 0xe7, 0xa0, 0xea,
+       0x27, 0x9c, 0x1e, 0x14, 0xda, 0xd0, 0xfc, 0x0c, 0xf7, 0x01, 0xdb, 0xb1,
+       0x2f, 0x5f, 0x27, 0xe7, 0xab, 0x41, 0x1f, 0x85, 0xba, 0x3e, 0x0a, 0xa0,
+       0x47, 0xb6, 0x19, 0x4e, 0x14, 0x6b, 0xcf, 0xae, 0x8e, 0xe0, 0xdd, 0x93,
+       0x92, 0x3d, 0x7d, 0xb3, 0x81, 0x39, 0xa0, 0x5f, 0xf2, 0x68, 0x0c, 0x3a,
+       0x9b, 0xfb, 0x2c, 0x26, 0xb9, 0x38, 0xcb, 0x3e, 0xa6, 0xc7, 0x8d, 0x48,
+       0x46, 0xe5, 0x5f, 0x69, 0x5d, 0xa3, 0xe3, 0x79, 0x3d, 0x9f, 0x34, 0xe6,
+       0x43, 0x1a, 0x82, 0xb9, 0xa4, 0xeb, 0xe6, 0x12, 0xf0, 0x9a, 0xbc, 0x30,
+       0xa1, 0xe3, 0x63, 0xda, 0x86, 0xb0, 0xdd, 0x74, 0xdd, 0xda, 0x4d, 0xa3,
+       0x0d, 0x79, 0x8f, 0x3a, 0x1b, 0xec, 0x0a, 0x6d, 0xca, 0x10, 0xfa, 0x29,
+       0xce, 0x1b, 0x92, 0x73, 0x61, 0xab, 0xdd, 0x77, 0x6b, 0x79, 0x5d, 0x93,
+       0xa5, 0xe8, 0xa6, 0xb2, 0x74, 0xc8, 0xf0, 0xf5, 0x35, 0x6c, 0x0b, 0xec,
+       0xcf, 0xd4, 0xbc, 0x9d, 0x0a, 0x64, 0xa9, 0x38, 0xf3, 0x4e, 0x64, 0x29,
+       0x68, 0x1f, 0x83, 0xec, 0x06, 0x63, 0x6c, 0xa4, 0x39, 0xa8, 0x03, 0x1a,
+       0x4b, 0x59, 0x8d, 0x51, 0x38, 0x8e, 0x6f, 0x1b, 0xca, 0xeb, 0x6c, 0xc3,
+       0x11, 0xb4, 0x95, 0x50, 0xae, 0xb7, 0x45, 0xf6, 0xcf, 0x07, 0x7d, 0x1c,
+       0x51, 0x32, 0x3b, 0x39, 0x63, 0x9b, 0xc3, 0x61, 0xc9, 0x0c, 0xcf, 0x0e,
+       0xca, 0x50, 0xad, 0x13, 0x6b, 0xfa, 0xb6, 0x07, 0xdb, 0x79, 0x7d, 0x54,
+       0x1c, 0xe8, 0x45, 0xcc, 0x79, 0x00, 0x3c, 0xae, 0x45, 0xc5, 0x48, 0xbb,
+       0x48, 0xeb, 0x31, 0x56, 0x24, 0x32, 0xbc, 0x2e, 0xdf, 0x80, 0x3a, 0xe8,
+       0x7b, 0x60, 0x63, 0x3d, 0xc8, 0x27, 0x78, 0x9b, 0x75, 0x7f, 0xe1, 0xc1,
+       0x0e, 0x6b, 0x9b, 0xc5, 0x52, 0xea, 0x89, 0x40, 0x47, 0x7c, 0x14, 0xfb,
+       0x5b, 0xed, 0x85, 0x82, 0x91, 0x3e, 0x80, 0x3e, 0x44, 0xc9, 0x69, 0xb1,
+       0xf6, 0x4c, 0xb0, 0xef, 0x55, 0xf9, 0xae, 0x01, 0xca, 0x5e, 0x19, 0x98,
+       0x80, 0x73, 0x5a, 0x52, 0x7b, 0x3d, 0x67, 0xc6, 0x65, 0xba, 0xc4, 0xf9,
+       0x2c, 0x49, 0xb2, 0xfa, 0xa7, 0x92, 0x3b, 0x2d, 0xf2, 0xad, 0x19, 0xd6,
+       0xfb, 0xba, 0xae, 0xf7, 0x3c, 0xea, 0x25, 0xad, 0xa1, 0x90, 0x0d, 0x3b,
+       0x60, 0x63, 0x9b, 0xf4, 0x59, 0x48, 0xcd, 0x11, 0xfc, 0x86, 0x68, 0x64,
+       0x50, 0xcf, 0xc7, 0x40, 0xcf, 0x83, 0x1f, 0x22, 0x77, 0x95, 0x1a, 0xa1,
+       0x4f, 0xfe, 0x27, 0x68, 0x8d, 0xcb, 0xe3, 0x98, 0xc7, 0x4b, 0x33, 0xc4,
+       0x59, 0x5f, 0x97, 0xe5, 0x19, 0xe2, 0xae, 0xe7, 0x65, 0x7a, 0x26, 0xe9,
+       0x7e, 0x0b, 0x7c, 0x3e, 0x25, 0x9c, 0x4b, 0x9f, 0x8b, 0x14, 0x18, 0xd0,
+       0xb6, 0x1e, 0x83, 0x3e, 0xeb, 0xdd, 0xe9, 0xf7, 0xd7, 0xad, 0xfb, 0x73,
+       0xaa, 0xb6, 0x5c, 0x34, 0xa9, 0x9f, 0x2e, 0xdf, 0xe3, 0x59, 0xbd, 0xc7,
+       0xc7, 0xdc, 0x4e, 0x31, 0xb0, 0xaf, 0x33, 0xe3, 0x05, 0x58, 0x3f, 0xee,
+       0xeb, 0xff, 0x6b, 0xac, 0xe1, 0x9f, 0x04, 0xb0, 0xaa, 0xad, 0xec, 0xdd,
+       0x3f, 0x6e, 0x8f, 0xd7, 0xef, 0x6d, 0x8e, 0xdf, 0x8a, 0x36, 0x11, 0xa4,
+       0x57, 0xde, 0xd7, 0xe8, 0xa3, 0xae, 0xed, 0x20, 0xf7, 0x05, 0xda, 0xfc,
+       0x09, 0x78, 0x41, 0xfe, 0xbf, 0x93, 0xfd, 0xdc, 0x17, 0x7e, 0x47, 0xfb,
+       0x79, 0xfc, 0x4a, 0xfb, 0xb9, 0x7e, 0x2f, 0x9f, 0x25, 0x2f, 0x30, 0xb6,
+       0xcc, 0xfa, 0xb2, 0xd5, 0x0d, 0x5e, 0x5b, 0x90, 0x53, 0xd0, 0x50, 0xfa,
+       0x07, 0x2f, 0x13, 0xf1, 0xf1, 0x9c, 0x2f, 0x4f, 0xac, 0x17, 0xd4, 0xf1,
+       0x75, 0xef, 0x50, 0xed, 0xa2, 0xd2, 0xb3, 0xe7, 0x94, 0x9e, 0xb5, 0x8f,
+       0x14, 0x84, 0xf2, 0x76, 0x43, 0x98, 0x7c, 0x7f, 0xc6, 0xfd, 0x2c, 0x68,
+       0xb4, 0x2d, 0xcb, 0xe8, 0x2e, 0x18, 0xc6, 0x67, 0xe5, 0xc0, 0xe2, 0x43,
+       0x72, 0xa0, 0xc4, 0x3e, 0xd2, 0x78, 0xef, 0xa0, 0xac, 0x09, 0xba, 0x96,
+       0x3a, 0xfd, 0xed, 0x90, 0x3f, 0x96, 0x01, 0xfb, 0xb5, 0x12, 0xba, 0xab,
+       0x76, 0x21, 0x94, 0x5d, 0xe4, 0xde, 0x45, 0x79, 0xad, 0x5e, 0xe7, 0x07,
+       0xfa, 0xbe, 0x5e, 0xb7, 0x17, 0x42, 0x63, 0xa5, 0x69, 0xe2, 0x40, 0x23,
+       0xeb, 0x46, 0xb5, 0xee, 0xf8, 0x9a, 0x29, 0xad, 0xb0, 0x2d, 0xc6, 0x3c,
+       0x78, 0x45, 0x9c, 0x4a, 0xde, 0xa5, 0x24, 0x13, 0x21, 0x9e, 0xe4, 0xb3,
+       0x78, 0xe1, 0x34, 0xf7, 0x9e, 0x44, 0xc2, 0xe9, 0x2e, 0xf0, 0x8e, 0x75,
+       0x6e, 0x05, 0xad, 0xb0, 0x7b, 0xee, 0xfb, 0x84, 0x72, 0xf9, 0x42, 0xe9,
+       0x36, 0xe4, 0x23, 0x9a, 0xbf, 0x51, 0xd4, 0x61, 0x7f, 0x3f, 0x6d, 0x90,
+       0xd6, 0xe3, 0xd0, 0x15, 0x41, 0xbf, 0xac, 0x93, 0xd0, 0x75, 0x5a, 0x74,
+       0x9d, 0x5b, 0xf0, 0x7e, 0x0e, 0xf5, 0x6c, 0x57, 0x84, 0x7c, 0x60, 0x59,
+       0x3b, 0xe6, 0x85, 0xba, 0x8b, 0xe9, 0xf0, 0x7a, 0xba, 0x6e, 0xaa, 0xab,
+       0xcb, 0xfc, 0x66, 0x58, 0x97, 0xf2, 0x24, 0x5a, 0x97, 0xb1, 0x6c, 0x10,
+       0xcf, 0x5d, 0x32, 0xb1, 0x98, 0x81, 0x4e, 0xba, 0x5d, 0xf5, 0x13, 0x75,
+       0xd6, 0xd9, 0x3a, 0xd0, 0x64, 0x69, 0x9a, 0xb6, 0x04, 0xfa, 0x18, 0x65,
+       0xae, 0x2e, 0x6b, 0xa8, 0x2b, 0x0b, 0xe4, 0xe7, 0x5f, 0x83, 0x76, 0x8e,
+       0x3d, 0xa2, 0x71, 0x98, 0xe7, 0xe5, 0x28, 0x77, 0xfd, 0xff, 0x52, 0xf3,
+       0xa2, 0x60, 0x86, 0xd5, 0x5e, 0xa9, 0xfe, 0xf6, 0xda, 0x5e, 0x01, 0x6e,
+       0x57, 0xbd, 0x70, 0x8e, 0xa4, 0xa5, 0x05, 0x6b, 0x3b, 0x04, 0x5a, 0xb1,
+       0x86, 0x1d, 0x21, 0xcc, 0xb7, 0x45, 0xf2, 0xb5, 0xb4, 0x7e, 0xc7, 0xf2,
+       0x88, 0x8c, 0xc5, 0x83, 0xf9, 0x7d, 0xc0, 0xf4, 0xb1, 0x37, 0xea, 0x94,
+       0xb6, 0x44, 0xfc, 0xbd, 0x68, 0x4a, 0xfe, 0xe4, 0x10, 0x64, 0x9e, 0xd8,
+       0xb0, 0x01, 0x32, 0x1f, 0x57, 0x36, 0xc7, 0x70, 0x58, 0x1f, 0xef, 0x4e,
+       0xff, 0xbb, 0xb0, 0xdf, 0x86, 0xf5, 0x82, 0x36, 0xc1, 0xd8, 0xed, 0xab,
+       0x6d, 0xc7, 0x5c, 0x43, 0xc2, 0x6a, 0x7c, 0x94, 0x9d, 0x5e, 0x3f, 0xbe,
+       0xd1, 0x11, 0x8c, 0xff, 0xa7, 0xba, 0xaf, 0xf6, 0xba, 0xbe, 0xe2, 0x57,
+       0x18, 0x1f, 0xef, 0x4e, 0xff, 0xee, 0x76, 0xbf, 0x4d, 0xbc, 0xae, 0x4d,
+       0xc7, 0x86, 0x36, 0xac, 0x1f, 0x8c, 0x81, 0x77, 0xa7, 0xef, 0x6b, 0xf1,
+       0xdb, 0xb0, 0x5e, 0x03, 0x6c, 0x2c, 0xdf, 0x71, 0x0f, 0x1e, 0xa8, 0xdb,
+       0x83, 0x07, 0xb0, 0x07, 0x03, 0xd9, 0xde, 0x88, 0xd7, 0x03, 0xbf, 0x8b,
+       0xfe, 0x16, 0x31, 0xde, 0x9a, 0x7f, 0x15, 0x59, 0x68, 0x01, 0x7e, 0x6a,
+       0xa5, 0x4f, 0xa5, 0xf1, 0x39, 0x7d, 0x2c, 0xe2, 0x71, 0x71, 0x22, 0xd2,
+       0x0d, 0x5d, 0xd9, 0x9d, 0xd8, 0xcf, 0x8d, 0x5f, 0x8d, 0x2b, 0xdc, 0x9e,
+       0xd1, 0x63, 0xd0, 0xbf, 0x22, 0xdf, 0x99, 0xcf, 0xad, 0xfa, 0x5b, 0x9d,
+       0xf0, 0xc7, 0x88, 0xbb, 0x89, 0xdb, 0x02, 0xfa, 0x03, 0x7a, 0x0e, 0x1a,
+       0x6b, 0x7b, 0x33, 0x63, 0x0c, 0xd5, 0x86, 0x0c, 0x7f, 0x6f, 0xf2, 0xfd,
+       0x41, 0x6d, 0x5b, 0x37, 0xd2, 0xfb, 0x9e, 0x0d, 0xf4, 0x12, 0xdf, 0x59,
+       0x32, 0x05, 0x19, 0x89, 0x2c, 0x50, 0xd7, 0x2f, 0x8c, 0x2e, 0xcf, 0x13,
+       0xc7, 0xf4, 0x83, 0x2f, 0xa4, 0x97, 0xfc, 0xa3, 0x4e, 0x69, 0x85, 0x9e,
+       0xea, 0x4e, 0x55, 0x50, 0x9f, 0x7e, 0xfe, 0x84, 0xf2, 0x0f, 0x5b, 0x90,
+       0xc2, 0x89, 0x03, 0xad, 0x13, 0xa0, 0x75, 0x42, 0xfb, 0x86, 0xfb, 0x61,
+       0x47, 0x22, 0xc7, 0x02, 0x5a, 0x6f, 0x89, 0x04, 0x6b, 0xb3, 0x9e, 0xf6,
+       0x7a, 0xfb, 0xe7, 0xe3, 0xc0, 0xbb, 0x7a, 0xd5, 0x9e, 0x2c, 0x10, 0x3b,
+       0x4e, 0x9c, 0x0e, 0xf6, 0xa3, 0xf8, 0x7b, 0xa9, 0x35, 0xc0, 0x01, 0x9c,
+       0x0f, 0x71, 0x08, 0x75, 0x4f, 0x30, 0x87, 0x16, 0xe9, 0x5a, 0xe0, 0x1c,
+       0x56, 0xe9, 0x8f, 0x33, 0xca, 0x72, 0x00, 0xfa, 0x3b, 0xaf, 0x68, 0xdd,
+       0x2d, 0x93, 0xa5, 0xf7, 0x69, 0xfa, 0x5b, 0x40, 0xff, 0x18, 0x64, 0x7b,
+       0x4d, 0x77, 0xe5, 0xab, 0xe3, 0xc8, 0xfb, 0x98, 0x90, 0x3c, 0xce, 0x57,
+       0xa9, 0xc7, 0xf4, 0x7c, 0x9a, 0x39, 0x9f, 0x8d, 0x3a, 0x6e, 0x33, 0xbe,
+       0xbe, 0x77, 0x03, 0x5f, 0x45, 0xf3, 0x35, 0x26, 0x0d, 0x0b, 0xca, 0xbf,
+       0x46, 0xbf, 0xe4, 0x35, 0xed, 0xe8, 0xc2, 0xe8, 0xf4, 0xbc, 0xf4, 0x33,
+       0x08, 0x95, 0x07, 0xdf, 0x50, 0x36, 0xd0, 0x20, 0xdd, 0xee, 0x05, 0xcc,
+       0x3b, 0x8f, 0xf5, 0x36, 0x8e, 0xf9, 0xf2, 0x4d, 0xfe, 0xe6, 0xab, 0xcd,
+       0xf0, 0xe9, 0x39, 0x36, 0x79, 0x46, 0xfa, 0x4d, 0x45, 0xcf, 0x2a, 0xbf,
+       0x41, 0xdf, 0x7d, 0xd5, 0x8d, 0xbc, 0xad, 0xd7, 0x33, 0x41, 0xec, 0xe0,
+       0x35, 0xd3, 0xdf, 0x17, 0x9b, 0xc5, 0x0e, 0x5a, 0xa0, 0xa3, 0x23, 0x8c,
+       0x13, 0x80, 0xf7, 0x8c, 0xf3, 0x5c, 0x8a, 0xd0, 0x17, 0x78, 0xa1, 0x04,
+       0x3d, 0x73, 0x9c, 0xd8, 0xa5, 0x55, 0xef, 0x8f, 0x1b, 0xb4, 0x0d, 0x8b,
+       0x2a, 0xdb, 0x21, 0x86, 0x49, 0x7c, 0x84, 0x32, 0xe4, 0x17, 0x99, 0x0f,
+       0xe8, 0xb8, 0x7b, 0x4f, 0xd4, 0x79, 0x21, 0x12, 0xe8, 0x84, 0x35, 0xba,
+       0xea, 0x63, 0x03, 0x1e, 0x30, 0xe5, 0xfb, 0x20, 0xb7, 0xb7, 0xc3, 0xff,
+       0xb7, 0x24, 0x9f, 0xe2, 0x3e, 0x1a, 0x54, 0x3e, 0x92, 0xe1, 0xec, 0x47,
+       0x59, 0x13, 0xca, 0x60, 0x4c, 0x4d, 0xcc, 0xdf, 0xf9, 0x3d, 0x99, 0x80,
+       0x8c, 0xe7, 0x53, 0x7d, 0xa0, 0x83, 0xf8, 0x0e, 0x58, 0xcb, 0x49, 0x31,
+       0x7e, 0x80, 0xbf, 0x7b, 0xa3, 0xfe, 0xbc, 0xf6, 0x20, 0xdf, 0x8c, 0x3a,
+       0x5d, 0xba, 0xce, 0x16, 0x61, 0x1c, 0x2a, 0x6f, 0xb6, 0x22, 0xed, 0xd9,
+       0x50, 0xf7, 0x43, 0xc8, 0xdf, 0xa2, 0xfb, 0x2f, 0xe0, 0xfd, 0x4d, 0xf8,
+       0x0d, 0xa1, 0xec, 0x66, 0x94, 0xb9, 0x28, 0xbb, 0x11, 0xf9, 0x0f, 0xe9,
+       0xb8, 0x44, 0xd0, 0xa6, 0x15, 0xf9, 0x47, 0xf1, 0x1e, 0xba, 0xc2, 0x7c,
+       0x05, 0xef, 0x6f, 0xc1, 0xef, 0xfa, 0x0d, 0x75, 0xda, 0x37, 0xe4, 0x4f,
+       0xae, 0xf2, 0xe0, 0x85, 0xd2, 0x55, 0xfa, 0x99, 0xf2, 0xcc, 0xfc, 0x2b,
+       0x3a, 0x7f, 0xfb, 0x86, 0xf2, 0xfb, 0x83, 0x7c, 0xdd, 0x1a, 0xc2, 0x0e,
+       0x9a, 0x01, 0xd6, 0xbd, 0xda, 0xf4, 0xd7, 0xe0, 0x3d, 0x7e, 0xbc, 0xa0,
+       0x14, 0xb4, 0x23, 0xf6, 0xbd, 0x3d, 0xbc, 0xbe, 0xaf, 0xff, 0xd6, 0xb0,
+       0x96, 0x6f, 0x09, 0x0d, 0x9f, 0x64, 0xd9, 0x4f, 0x1b, 0xd6, 0xd7, 0x79,
+       0x5f, 0xe3, 0x5a, 0x7e, 0x6b, 0x68, 0xf8, 0x38, 0xcb, 0xee, 0x6b, 0x5c,
+       0x5f, 0x67, 0xb8, 0x71, 0x6d, 0x1e, 0x6b, 0xba, 0x30, 0x92, 0xae, 0x50,
+       0x8e, 0xb1, 0x17, 0xaa, 0xa3, 0xd9, 0x19, 0xcf, 0x9b, 0x72, 0x57, 0x12,
+       0x61, 0xa1, 0x0d, 0x22, 0x66, 0x66, 0xf9, 0x53, 0x28, 0x07, 0xa6, 0xaa,
+       0x8d, 0x09, 0x75, 0xd2, 0xe6, 0xd8, 0xd8, 0xd2, 0xd8, 0x58, 0x65, 0x23,
+       0x59, 0x85, 0x65, 0x9f, 0x18, 0x05, 0xf6, 0xd2, 0xcf, 0x4f, 0xe2, 0xd9,
+       0xaa, 0xc7, 0xdf, 0xe8, 0xb7, 0x3c, 0x9a, 0x9d, 0xa7, 0xcd, 0x5b, 0x1a,
+       0xdd, 0x37, 0xcf, 0x3d, 0x7f, 0x0a, 0x7b, 0x3e, 0x24, 0xd3, 0xca, 0xfe,
+       0x91, 0x0e, 0xb6, 0x2b, 0x8f, 0x76, 0x2d, 0x31, 0xad, 0x8c, 0x3a, 0x4b,
+       0x61, 0xd9, 0x1f, 0xf7, 0xdb, 0x32, 0x6f, 0x2d, 0x05, 0x7b, 0xa0, 0x59,
+       0xa2, 0x69, 0xca, 0xa4, 0x9d, 0x82, 0x0f, 0x80, 0xf9, 0x1c, 0x19, 0x9d,
+       0x76, 0x28, 0x9f, 0x9f, 0x82, 0xdd, 0x6f, 0x96, 0x06, 0xa5, 0x6f, 0x1e,
+       0xd7, 0x63, 0x9d, 0xc2, 0x58, 0xdb, 0xd4, 0x7e, 0xca, 0x3a, 0x91, 0x04,
+       0xc6, 0x39, 0x64, 0x38, 0x7d, 0x18, 0x8f, 0x1e, 0x7b, 0xa7, 0x4c, 0xd5,
+       0xb8, 0x6f, 0xf6, 0x44, 0xd7, 0xfc, 0xf4, 0x39, 0xb4, 0x0b, 0xfc, 0x43,
+       0x8e, 0x57, 0x01, 0x3e, 0x84, 0x2c, 0xa7, 0x6d, 0x33, 0x1b, 0x86, 0x9d,
+       0x9f, 0x0f, 0xea, 0x90, 0xa6, 0x63, 0xa3, 0xc9, 0xa5, 0x24, 0xfa, 0xea,
+       0xa4, 0x0e, 0x83, 0xee, 0x0a, 0xe3, 0xc7, 0xbe, 0xd9, 0x0e, 0xb6, 0x68,
+       0x90, 0x76, 0x64, 0x0e, 0x76, 0xa4, 0x53, 0x0e, 0x97, 0x54, 0x1f, 0x16,
+       0xfb, 0x28, 0xea, 0xb6, 0x5d, 0x4b, 0x0d, 0xf0, 0xb1, 0x92, 0xe6, 0x8b,
+       0xb2, 0xd6, 0x76, 0x58, 0xfc, 0x76, 0x7e, 0xdf, 0x3f, 0xf1, 0x32, 0xf1,
+       0xfa, 0xbd, 0xdf, 0x2c, 0x61, 0xd0, 0x91, 0x43, 0x1f, 0x1c, 0x7f, 0xad,
+       0xef, 0xa0, 0xbf, 0xa4, 0x79, 0xfe, 0xb2, 0xbe, 0xb6, 0x69, 0xfc, 0x66,
+       0x5b, 0xb9, 0x5f, 0x6b, 0x6c, 0xce, 0xf7, 0x09, 0xc8, 0x83, 0x44, 0x72,
+       0xbd, 0xd0, 0x8b, 0xb5, 0x41, 0x2d, 0x23, 0x4f, 0xa2, 0xac, 0xde, 0xc7,
+       0xf2, 0xe5, 0xab, 0x00, 0x6c, 0x59, 0xc4, 0x3e, 0x0f, 0xa7, 0x33, 0x6d,
+       0x7e, 0xcc, 0xeb, 0x4a, 0x7e, 0x15, 0xe4, 0x06, 0x7d, 0x16, 0x57, 0xdb,
+       0x72, 0x4e, 0x4f, 0x8e, 0xbe, 0x34, 0x93, 0xc0, 0x9c, 0x7c, 0xbb, 0xe0,
+       0xf3, 0x9a, 0x36, 0x27, 0x24, 0xcb, 0x8e, 0x05, 0xff, 0x9d, 0x36, 0xde,
+       0x92, 0x97, 0x9d, 0xc0, 0xfe, 0xd0, 0x16, 0xa1, 0x7e, 0x8d, 0xb4, 0x91,
+       0xf6, 0x39, 0xcc, 0xcd, 0x93, 0x59, 0xd7, 0x97, 0xc1, 0x5e, 0xd8, 0x91,
+       0xff, 0x18, 0xb1, 0x8f, 0xd0, 0xcf, 0xbb, 0x18, 0xa9, 0x9f, 0x4f, 0x80,
+       0x15, 0x9e, 0xd0, 0x31, 0xe8, 0x39, 0x2d, 0x2f, 0x65, 0xc8, 0x4b, 0x9f,
+       0x65, 0x4a, 0x0f, 0x68, 0x47, 0x9d, 0xfe, 0x6e, 0xf8, 0x5b, 0xf4, 0xe5,
+       0x13, 0xa0, 0xc7, 0x84, 0xee, 0xd8, 0xa6, 0x7d, 0x87, 0xb7, 0xa2, 0xb4,
+       0x6d, 0x6d, 0x2a, 0xbe, 0x3d, 0xa7, 0xe4, 0xd9, 0x97, 0xef, 0xb0, 0x7e,
+       0x1f, 0xc8, 0x54, 0x98, 0x90, 0x46, 0xd6, 0xe2, 0xb8, 0xac, 0xbf, 0xa0,
+       0xeb, 0xcf, 0xa3, 0x7e, 0x08, 0x73, 0xf2, 0xbc, 0x49, 0x45, 0xef, 0x02,
+       0xf8, 0x1e, 0x96, 0xe2, 0xaa, 0xcc, 0x2f, 0x40, 0xe6, 0x29, 0xdf, 0x73,
+       0xd8, 0xaf, 0x20, 0xfe, 0x6e, 0xca, 0x7d, 0x45, 0x86, 0x4e, 0xef, 0x6f,
+       0x60, 0xcc, 0xd5, 0x32, 0xe8, 0x03, 0x53, 0x26, 0x3b, 0xe5, 0xb1, 0x52,
+       0xd2, 0x9c, 0xaa, 0x5b, 0xcb, 0x5d, 0xeb, 0xd6, 0x92, 0x32, 0xa0, 0xea,
+       0xa7, 0x58, 0xbf, 0x52, 0x27, 0x03, 0x8b, 0xf3, 0x57, 0x6a, 0x47, 0x19,
+       0x60, 0xbb, 0xcd, 0xfc, 0x05, 0xc6, 0x28, 0x3d, 0x6f, 0xd9, 0x25, 0xfe,
+       0x6f, 0x94, 0x82, 0x92, 0xb1, 0x90, 0x14, 0x5d, 0xee, 0xab, 0xac, 0x15,
+       0x11, 0x1b, 0x58, 0xe9, 0xf7, 0x41, 0x67, 0x26, 0x15, 0x15, 0x3f, 0xa6,
+       0x31, 0x81, 0x35, 0x58, 0x31, 0x3d, 0xef, 0x25, 0x47, 0xa4, 0x02, 0x1f,
+       0x78, 0x19, 0x69, 0xb1, 0x8a, 0x3d, 0xdb, 0x1c, 0x81, 0x0e, 0x08, 0x64,
+       0x3c, 0x26, 0x65, 0xd4, 0x59, 0xc4, 0xbb, 0xc7, 0xaa, 0x81, 0xc4, 0x78,
+       0x9e, 0x01, 0x1e, 0xed, 0x73, 0x7e, 0xea, 0xe5, 0xe3, 0xf5, 0x75, 0x03,
+       0x4c, 0x4c, 0x2c, 0x4b, 0x6c, 0x4a, 0x4c, 0xc9, 0x77, 0xc4, 0x89, 0x87,
+       0x40, 0x0b, 0xf7, 0x6c, 0xab, 0xc4, 0xd2, 0x76, 0x62, 0x44, 0x02, 0xdb,
+       0xff, 0x3a, 0x64, 0xa9, 0xe0, 0x35, 0x3a, 0x9d, 0xf2, 0x1c, 0xe4, 0xe6,
+       0xd9, 0x55, 0x1c, 0x63, 0x41, 0x8e, 0x68, 0x47, 0x3d, 0x39, 0xe7, 0x3a,
+       0xd6, 0xe7, 0x90, 0x7e, 0xc7, 0xfd, 0x00, 0xf9, 0xf6, 0x84, 0x48, 0x3f,
+       0x7c, 0x32, 0xe8, 0xf5, 0xd9, 0x00, 0xdb, 0xb7, 0xd2, 0x37, 0xd4, 0xb2,
+       0x74, 0x11, 0x7d, 0xda, 0xa6, 0x01, 0x50, 0x7b, 0x07, 0xea, 0xf9, 0x7b,
+       0x23, 0x28, 0x3b, 0x84, 0xba, 0xa4, 0x81, 0x7e, 0xfb, 0x77, 0xb1, 0x67,
+       0x3d, 0xef, 0x1e, 0xf7, 0xe5, 0x3a, 0x5d, 0xb3, 0x80, 0xf5, 0x57, 0x72,
+       0x3e, 0xd0, 0x26, 0x8c, 0xf3, 0x4a, 0x7f, 0xbb, 0xf2, 0x2b, 0xf9, 0x0c,
+       0x79, 0x1f, 0x20, 0x16, 0xb2, 0x14, 0xd6, 0x24, 0x6e, 0x78, 0x16, 0xbc,
+       0xff, 0xa4, 0xc2, 0x34, 0xc4, 0x6f, 0xa0, 0xbf, 0x44, 0x4c, 0xe1, 0x63,
+       0x69, 0x1f, 0xd7, 0x11, 0x5b, 0xa4, 0xb8, 0x36, 0x1a, 0x5f, 0xb0, 0x2d,
+       0xeb, 0xb1, 0x6d, 0xfd, 0xfa, 0xb1, 0xce, 0xb6, 0x50, 0xee, 0x38, 0xe5,
+       0x99, 0xf6, 0xb1, 0x4d, 0xf6, 0xa7, 0x1a, 0xc1, 0xf7, 0x76, 0x6d, 0xc7,
+       0x3f, 0x08, 0xcc, 0x06, 0xec, 0x6d, 0xd2, 0x87, 0x0a, 0x78, 0x7d, 0x23,
+       0xca, 0x7e, 0x0e, 0xfe, 0xb3, 0x0c, 0xfe, 0x95, 0xb2, 0x93, 0x0f, 0x61,
+       0x2f, 0x97, 0xb7, 0xf9, 0x31, 0x34, 0xae, 0x43, 0x80, 0x13, 0x02, 0xdc,
+       0x67, 0x6a, 0xbc, 0xcf, 0xb5, 0xf1, 0xe3, 0x6d, 0x86, 0xaa, 0x4b, 0x5f,
+       0xab, 0xde, 0xc7, 0xe5, 0x1e, 0xf6, 0xbc, 0x73, 0x6e, 0x80, 0x23, 0xeb,
+       0xfd, 0xc4, 0xc0, 0x07, 0x8c, 0x89, 0xd5, 0x4e, 0x4c, 0xf1, 0x47, 0x0d,
+       0x6b, 0x58, 0xe6, 0x1f, 0xbc, 0xb0, 0x43, 0x9f, 0x93, 0x38, 0x26, 0xf0,
+       0x07, 0x59, 0x97, 0xd8, 0xe6, 0x51, 0x8c, 0x11, 0x16, 0xab, 0x83, 0xf9,
+       0x1f, 0xeb, 0x36, 0x7c, 0xf6, 0xa4, 0x67, 0x67, 0xbd, 0x3c, 0x0f, 0xfa,
+       0xfe, 0x62, 0x73, 0x10, 0x03, 0xee, 0x54, 0xfa, 0x64, 0x4d, 0x2e, 0x02,
+       0x9a, 0x82, 0x71, 0x7d, 0xff, 0xb4, 0x1d, 0xb4, 0xdd, 0x05, 0x9b, 0xb2,
+       0xb3, 0xdd, 0xae, 0xf3, 0x45, 0xeb, 0x69, 0xaa, 0xc7, 0x57, 0x16, 0xc6,
+       0x68, 0x94, 0x9d, 0x1d, 0xe4, 0x5d, 0xa7, 0xb2, 0x2d, 0x6b, 0xeb, 0x41,
+       0xdb, 0xcf, 0xb1, 0x37, 0x96, 0xdf, 0x52, 0x47, 0xd7, 0x46, 0xcc, 0x47,
+       0x1f, 0xd7, 0xc7, 0x7c, 0x99, 0xb8, 0x27, 0xbb, 0xdc, 0x00, 0xdf, 0xd5,
+       0xd3, 0x41, 0x8c, 0x47, 0x9a, 0xa3, 0x75, 0x3e, 0xf2, 0xef, 0xea, 0x33,
+       0xaa, 0x39, 0x3d, 0x97, 0xc0, 0x97, 0x4e, 0xa2, 0xfe, 0x7f, 0x00, 0xdd,
+       0x7c, 0x26, 0xed, 0x01, 0x1e, 0x4c, 0xfa, 0x6d, 0x9b, 0x37, 0xc3, 0xfd,
+       0xdc, 0x27, 0x01, 0x6f, 0xda, 0xf5, 0xba, 0xd4, 0xfb, 0xe3, 0xea, 0xe7,
+       0xae, 0xd7, 0x1d, 0x37, 0xd6, 0xcd, 0xa9, 0x5f, 0x0a, 0x8b, 0x94, 0x85,
+       0xf7, 0x23, 0x0d, 0xfc, 0xa1, 0x01, 0xd8, 0x8e, 0x0c, 0xfc, 0x1f, 0xfa,
+       0x45, 0x97, 0xf9, 0x44, 0x3c, 0xc3, 0x1c, 0xcf, 0xc3, 0x47, 0x56, 0xb6,
+       0xc3, 0xb7, 0x8b, 0xc8, 0x43, 0x87, 0xd4, 0xee, 0xa6, 0x5c, 0x8d, 0x4f,
+       0x54, 0xdd, 0xf1, 0xc9, 0xea, 0xc0, 0x38, 0x7d, 0x07, 0x5f, 0xce, 0x50,
+       0xbf, 0x2a, 0x13, 0x06, 0xda, 0x65, 0x55, 0x3b, 0x15, 0xcb, 0xd8, 0xa4,
+       0x1f, 0xe1, 0x1e, 0x9c, 0xf0, 0xc7, 0x8a, 0x8d, 0xe7, 0xa0, 0x77, 0x16,
+       0x67, 0x61, 0xd7, 0x1c, 0x3b, 0x43, 0x59, 0xdc, 0xe7, 0xda, 0x23, 0x4a,
+       0xde, 0xe2, 0xf6, 0x18, 0xd7, 0xaf, 0x32, 0xfb, 0x5e, 0xe8, 0x4d, 0x4f,
+       0xee, 0x84, 0xfe, 0x7b, 0x00, 0xf2, 0x29, 0x67, 0xa0, 0xfc, 0xce, 0x40,
+       0x61, 0x9d, 0x89, 0x8b, 0x71, 0xa2, 0x53, 0xa2, 0x47, 0x13, 0x12, 0x39,
+       0x4a, 0xff, 0x2b, 0x69, 0xde, 0x29, 0x02, 0x3b, 0xf8, 0xe2, 0xcd, 0x86,
+       0xd8, 0x83, 0x19, 0x49, 0xc2, 0x87, 0xec, 0x33, 0x2b, 0x48, 0x8b, 0x92,
+       0x4c, 0x9d, 0x46, 0x5f, 0xd1, 0x33, 0xa8, 0x8b, 0x76, 0x4d, 0xcb, 0x16,
+       0x7e, 0x1d, 0xd2, 0xbc, 0xec, 0xef, 0x8f, 0xe6, 0xe5, 0xf5, 0xf1, 0x9b,
+       0xa1, 0xd5, 0xf8, 0x0d, 0xdf, 0xbf, 0xad, 0xe3, 0x4e, 0x5f, 0xd2, 0xbe,
+       0x0c, 0xe5, 0x82, 0xf6, 0x4c, 0xf9, 0x63, 0xd0, 0xdd, 0x5f, 0x82, 0xff,
+       0xeb, 0x48, 0xae, 0x04, 0x9c, 0x9e, 0xf6, 0xe4, 0x69, 0xb7, 0xe0, 0x65,
+       0x07, 0x3c, 0x79, 0xdd, 0x75, 0x0a, 0x79, 0xb1, 0xdf, 0xa6, 0x8e, 0xfb,
+       0xb1, 0xfb, 0x21, 0xd9, 0xd3, 0x66, 0xef, 0xc9, 0x84, 0x0a, 0x5e, 0x8b,
+       0xd3, 0x2c, 0x57, 0xa7, 0x0f, 0xc9, 0xbe, 0x1d, 0x2b, 0x66, 0x58, 0x32,
+       0x57, 0x03, 0x0b, 0x26, 0xf2, 0x4a, 0x3f, 0xbd, 0xa1, 0x7c, 0xea, 0xfb,
+       0xbb, 0x0f, 0xc9, 0xd6, 0x1d, 0xb6, 0x79, 0x29, 0x4c, 0x9c, 0x76, 0x08,
+       0xf8, 0xdf, 0x4e, 0xe4, 0xc2, 0x8e, 0xb9, 0x5b, 0xec, 0x91, 0x4f, 0x0b,
+       0xcf, 0x8c, 0x1d, 0xe9, 0x3a, 0xea, 0x24, 0x1e, 0x0c, 0xf5, 0x1c, 0x78,
+       0x90, 0x3e, 0xdd, 0x19, 0xe6, 0x3d, 0x89, 0xed, 0x30, 0xf1, 0x1c, 0x97,
+       0xae, 0x13, 0x96, 0x24, 0xc1, 0x97, 0x5e, 0xc5, 0x13, 0x9e, 0x5d, 0x25,
+       0xa4, 0xe7, 0x28, 0x71, 0x93, 0xe2, 0x4d, 0x2f, 0x78, 0x93, 0x02, 0x6f,
+       0xe0, 0x47, 0xf5, 0x99, 0x97, 0x90, 0x9e, 0x97, 0xe4, 0xe0, 0x9b, 0xe0,
+       0x4d, 0x2f, 0x78, 0xd3, 0x73, 0xc6, 0x42, 0x7b, 0xf4, 0xb1, 0xdc, 0x85,
+       0xb4, 0x59, 0x3e, 0x72, 0x55, 0x07, 0x9e, 0x1d, 0x49, 0x1e, 0x8d, 0x61,
+       0x8c, 0x90, 0xec, 0xea, 0x2e, 0xc8, 0xf0, 0x0e, 0xf8, 0x63, 0xf1, 0x43,
+       0x72, 0x01, 0xb6, 0xa7, 0x04, 0xbf, 0xe0, 0xe9, 0x41, 0x7b, 0x6c, 0x05,
+       0xfa, 0xb3, 0x76, 0x97, 0x27, 0xaf, 0xec, 0xf8, 0x2b, 0x2f, 0x71, 0x95,
+       0xbd, 0x47, 0x42, 0x03, 0x32, 0x5d, 0x52, 0x36, 0x21, 0x91, 0x0d, 0x2b,
+       0x2c, 0x86, 0x39, 0x16, 0x60, 0x57, 0x78, 0x16, 0xee, 0x40, 0xbf, 0x7f,
+       0x5a, 0x1e, 0x28, 0x4f, 0xe1, 0x07, 0x1f, 0x73, 0x86, 0x75, 0x0f, 0xc0,
+       0x87, 0x7b, 0x48, 0xf6, 0xcf, 0x00, 0x2f, 0xa6, 0x41, 0xf7, 0x80, 0x03,
+       0x1f, 0xee, 0x7c, 0xa3, 0xb4, 0xa2, 0x0c, 0xbc, 0x1d, 0xab, 0x6d, 0xf4,
+       0xdd, 0x56, 0xb0, 0x0e, 0x83, 0xf2, 0x97, 0xb5, 0x01, 0xf9, 0x6a, 0xad,
+       0x5f, 0xbe, 0x0c, 0x7b, 0xf2, 0x6c, 0xad, 0x13, 0x7b, 0x25, 0x81, 0x35,
+       0x49, 0x63, 0x7d, 0x5c, 0xf9, 0x4a, 0x2d, 0x25, 0x5f, 0x02, 0xaf, 0x9e,
+       0xc3, 0x6f, 0xb8, 0x94, 0x92, 0x5d, 0xa5, 0x7e, 0xbd, 0x46, 0x5c, 0x1f,
+       0x07, 0xf4, 0x38, 0x98, 0xbb, 0xfd, 0x54, 0x01, 0xfb, 0x6f, 0xb1, 0xe6,
+       0xbc, 0x55, 0x91, 0xc7, 0x1a, 0x19, 0x5f, 0x3e, 0xb5, 0x6a, 0x53, 0x0a,
+       0x9e, 0xe9, 0xd8, 0x47, 0x26, 0xb0, 0x0e, 0x15, 0xec, 0xd3, 0x31, 0xc5,
+       0xfb, 0x35, 0x7b, 0x53, 0xf1, 0xed, 0x4d, 0x30, 0xbf, 0xd9, 0xbc, 0x7c,
+       0x47, 0xb2, 0x73, 0xd3, 0xb2, 0xef, 0xb8, 0x27, 0xbf, 0xe3, 0x7a, 0x90,
+       0x63, 0xea, 0xdf, 0x01, 0xea, 0x75, 0x6b, 0x22, 0x6c, 0x28, 0xff, 0xc9,
+       0xc7, 0x2a, 0xbd, 0xdb, 0xb1, 0x67, 0x53, 0x19, 0x63, 0x4a, 0x92, 0x73,
+       0x53, 0xd2, 0x35, 0x07, 0x59, 0x70, 0xd9, 0xd7, 0x8a, 0x69, 0x5c, 0x26,
+       0x0f, 0x1c, 0xc7, 0x1e, 0xcc, 0x89, 0x63, 0xbe, 0x25, 0x29, 0x8c, 0x7f,
+       0x50, 0xba, 0xd1, 0xc6, 0x41, 0x9b, 0x4b, 0x6a, 0xec, 0x16, 0x8c, 0xdd,
+       0x28, 0x87, 0xe3, 0x36, 0x64, 0x8d, 0x76, 0xfb, 0xff, 0x48, 0xb6, 0xc2,
+       0xf4, 0x6f, 0x25, 0x7b, 0xea, 0x91, 0x98, 0x34, 0xf3, 0x19, 0xaa, 0x61,
+       0x81, 0xe5, 0x5d, 0x48, 0x59, 0xee, 0xc0, 0x77, 0xfe, 0x89, 0x64, 0xcf,
+       0x72, 0xec, 0xb7, 0x50, 0xfe, 0x8a, 0x64, 0x8f, 0xfd, 0x1c, 0xf9, 0x0b,
+       0x48, 0xdf, 0x46, 0x3a, 0x26, 0x5d, 0xc7, 0x24, 0x94, 0x3d, 0xfb, 0x6d,
+       0xe4, 0x23, 0x48, 0x0f, 0xa3, 0xde, 0x6d, 0xa0, 0xef, 0xaf, 0xd1, 0x5f,
+       0x06, 0x7a, 0xee, 0xc3, 0x9a, 0x7e, 0x96, 0xb3, 0x8c, 0xef, 0x0e, 0x43,
+       0xa7, 0xfd, 0x0f, 0x8f, 0xf1, 0x44, 0xf5, 0xbc, 0xc8, 0x3c, 0x75, 0x1b,
+       0x9f, 0xa7, 0xc0, 0x93, 0x83, 0xc8, 0x7b, 0xf2, 0x90, 0x4b, 0x1b, 0x73,
+       0x93, 0x8c, 0x9b, 0x05, 0xaf, 0x19, 0x58, 0xa2, 0x05, 0xfb, 0x60, 0x6a,
+       0xe7, 0xe6, 0xfb, 0xe0, 0x48, 0xcf, 0x21, 0x69, 0xda, 0x11, 0xcc, 0x3f,
+       0x98, 0xaf, 0x63, 0xfe, 0x48, 0xf1, 0xc1, 0x2e, 0x3c, 0x28, 0x9c, 0x87,
+       0x93, 0x78, 0xdc, 0xe8, 0xd9, 0xf3, 0x00, 0xf6, 0x81, 0x71, 0x96, 0x79,
+       0x7f, 0x1f, 0x18, 0x67, 0xa1, 0x1b, 0x16, 0xe0, 0x17, 0x2e, 0x74, 0x4a,
+       0xe3, 0xb1, 0xb5, 0x7d, 0xd0, 0x70, 0xec, 0x57, 0xef, 0x83, 0xc6, 0xb3,
+       0xa8, 0x77, 0x96, 0x3c, 0x43, 0x1f, 0xa7, 0xc8, 0xb3, 0x0e, 0xa4, 0x9f,
+       0xc6, 0x5c, 0x49, 0x7b, 0x23, 0x68, 0xf7, 0xb1, 0xd0, 0xcd, 0x90, 0xf7,
+       0xfb, 0x77, 0x1c, 0xd4, 0xe5, 0xff, 0xd9, 0x1b, 0x89, 0xdb, 0x65, 0x09,
+       0x91, 0xa7, 0xa8, 0x5b, 0x21, 0x0f, 0x6f, 0x69, 0x92, 0xe6, 0x03, 0xd2,
+       0x45, 0xfe, 0x55, 0x76, 0x23, 0x5f, 0xf0, 0xa2, 0x4e, 0x8b, 0xe6, 0x27,
+       0xb0, 0xd1, 0x00, 0xcb, 0x5f, 0x83, 0xcc, 0x10, 0xa3, 0xbe, 0x21, 0xfb,
+       0x66, 0x3c, 0x19, 0x77, 0x39, 0xff, 0xef, 0x63, 0xfe, 0x99, 0x1d, 0x71,
+       0x59, 0xb1, 0xe2, 0xe0, 0xc9, 0x22, 0x74, 0xfb, 0x05, 0xf1, 0xf9, 0xc0,
+       0x33, 0x89, 0x5d, 0xe2, 0x24, 0x86, 0xc5, 0x49, 0xbd, 0x09, 0x3e, 0x0c,
+       0x43, 0xf6, 0x73, 0x35, 0xca, 0xce, 0xab, 0x32, 0x04, 0x99, 0xf8, 0x9e,
+       0x6b, 0xa7, 0x80, 0x7f, 0xa0, 0x2f, 0x28, 0x17, 0x94, 0x89, 0x56, 0xa5,
+       0x93, 0x16, 0x5c, 0xfb, 0x89, 0x8a, 0x5c, 0x27, 0x0b, 0xed, 0xa4, 0x1d,
+       0xef, 0x8e, 0x29, 0x7b, 0x91, 0x9a, 0x30, 0xba, 0xa1, 0xa3, 0x53, 0x62,
+       0xf6, 0x7c, 0xb1, 0x31, 0xb8, 0xbf, 0x92, 0x9f, 0x0b, 0xc9, 0x54, 0x0f,
+       0xd7, 0x8a, 0xfd, 0x22, 0x5f, 0x29, 0x78, 0x11, 0xe7, 0x2d, 0xef, 0x64,
+       0x87, 0x25, 0x9f, 0xec, 0x59, 0x95, 0xcb, 0xb2, 0x88, 0xbf, 0x2f, 0x86,
+       0xd4, 0x7a, 0x04, 0x74, 0x07, 0x73, 0x09, 0xde, 0xf5, 0xd7, 0xbd, 0xe3,
+       0x5c, 0x28, 0xeb, 0xab, 0x7b, 0xc7, 0xba, 0x9c, 0xd6, 0x9f, 0x41, 0x9e,
+       0xec, 0x27, 0x8a, 0xf2, 0x3a, 0x64, 0x0f, 0x3c, 0x3c, 0xcb, 0x94, 0x3c,
+       0x9c, 0x82, 0xdc, 0xbf, 0x26, 0xbb, 0xe6, 0xb8, 0x67, 0x5e, 0xc3, 0x5c,
+       0x95, 0x2e, 0x81, 0x8e, 0x60, 0x7f, 0x9e, 0x4c, 0xbb, 0xdd, 0xa9, 0x53,
+       0x72, 0x5d, 0x62, 0x12, 0x7e, 0xe6, 0x84, 0xe9, 0xc9, 0xb2, 0x5b, 0x90,
+       0xe5, 0x41, 0xb4, 0xa9, 0x7c, 0x1a, 0xbf, 0x79, 0x3d, 0xb7, 0x47, 0xc0,
+       0x77, 0xdb, 0x2a, 0x1b, 0x9f, 0x01, 0xdf, 0x1f, 0x92, 0xe4, 0xb1, 0x55,
+       0x5d, 0x03, 0xb9, 0xf3, 0x75, 0x4d, 0xf2, 0xac, 0x29, 0x95, 0x92, 0x23,
+       0x1f, 0xa3, 0x0e, 0x29, 0x71, 0x5e, 0xd0, 0x31, 0x3c, 0xdf, 0x2f, 0x41,
+       0xcf, 0x94, 0xa0, 0x53, 0xa0, 0x43, 0xbe, 0x8c, 0xf2, 0x2f, 0xa1, 0xce,
+       0x73, 0xf0, 0x99, 0x9e, 0x05, 0xde, 0x3b, 0x07, 0x1c, 0xf1, 0x4c, 0x29,
+       0xa3, 0xfd, 0x57, 0x35, 0x5f, 0xd8, 0x2c, 0xe5, 0xef, 0x48, 0xa5, 0x4c,
+       0x7e, 0xfc, 0x44, 0xad, 0x6d, 0xd6, 0xdd, 0x46, 0x6c, 0x05, 0xca, 0x44,
+       0xca, 0xe5, 0x80, 0x27, 0xd4, 0x7d, 0x3c, 0x1b, 0x0a, 0x74, 0x65, 0xcb,
+       0x06, 0x5d, 0x29, 0xf2, 0x62, 0xd5, 0xc7, 0x90, 0xc4, 0xc4, 0xc5, 0x19,
+       0x6b, 0xf5, 0x0c, 0xb5, 0x08, 0xbb, 0x79, 0x1e, 0xbe, 0x45, 0x2c, 0xfd,
+       0x2d, 0x89, 0x9d, 0xf0, 0xbc, 0x1f, 0xc0, 0x6e, 0x16, 0xb0, 0x26, 0x46,
+       0x08, 0xe5, 0x4b, 0x7c, 0x47, 0xb9, 0xa7, 0x6c, 0x87, 0x78, 0x96, 0x22,
+       0x2f, 0xa3, 0xac, 0xa2, 0x7c, 0xae, 0x6f, 0x83, 0x1e, 0x4d, 0x9f, 0x2a,
+       0x63, 0xbd, 0x46, 0xc9, 0x8d, 0xa7, 0xe0, 0xd7, 0xf4, 0x99, 0x8d, 0x68,
+       0x5f, 0x5e, 0x62, 0x1b, 0x7b, 0x90, 0x57, 0xb9, 0x5e, 0x5e, 0x62, 0x79,
+       0xa7, 0x5c, 0x80, 0xff, 0x49, 0x1a, 0x2a, 0xf3, 0x69, 0xf1, 0xe3, 0xc5,
+       0xd4, 0x57, 0xa4, 0x15, 0x79, 0xf0, 0x2b, 0x5b, 0xa2, 0x9d, 0x8d, 0x48,
+       0x21, 0x41, 0x5e, 0x27, 0xe4, 0xfc, 0xcc, 0x1f, 0x37, 0x31, 0x1e, 0x9b,
+       0x75, 0xf8, 0x1c, 0xc4, 0x37, 0xcc, 0x77, 0x10, 0xdf, 0x60, 0x4c, 0x23,
+       0x02, 0x5b, 0xa6, 0xe2, 0x1c, 0x48, 0xad, 0x3a, 0x9f, 0x97, 0xef, 0x7d,
+       0x6c, 0xb4, 0x86, 0x19, 0x89, 0x21, 0x39, 0x5f, 0xbb, 0xb0, 0x02, 0xfd,
+       0xd1, 0x9e, 0x7e, 0x49, 0xee, 0x5e, 0xf0, 0xe7, 0x67, 0x9c, 0x12, 0xde,
+       0xe3, 0x91, 0x4b, 0xf3, 0xb6, 0x7b, 0x51, 0x78, 0x06, 0xe2, 0x62, 0xbd,
+       0xfe, 0xa0, 0x09, 0xfa, 0x6b, 0x30, 0x63, 0x7c, 0xbb, 0xc9, 0xc7, 0x67,
+       0x11, 0x99, 0x9a, 0xe1, 0x99, 0x2b, 0x74, 0x1b, 0x70, 0xe3, 0xef, 0x45,
+       0xf0, 0x5c, 0x65, 0x1e, 0x7e, 0xa8, 0xef, 0xc3, 0xe2, 0xd9, 0xef, 0x8f,
+       0x3c, 0x37, 0x16, 0x38, 0xf7, 0x90, 0xdc, 0x0d, 0x74, 0x22, 0xe8, 0xbf,
+       0x4b, 0x8f, 0xd5, 0x75, 0x2a, 0xc5, 0xf8, 0xb5, 0x24, 0xa1, 0x2f, 0xb2,
+       0xf0, 0x1f, 0x73, 0xf1, 0x4e, 0x8d, 0xc7, 0xf9, 0x6e, 0x23, 0xde, 0x0c,
+       0xfc, 0xba, 0x94, 0x7c, 0xbe, 0x14, 0x60, 0xbd, 0x14, 0x6c, 0xac, 0x44,
+       0x46, 0x7a, 0x3d, 0xf9, 0x81, 0x4b, 0x7e, 0xf5, 0x23, 0xef, 0xca, 0x91,
+       0xda, 0x2f, 0x3b, 0x5b, 0xad, 0xff, 0x6b, 0x01, 0x8d, 0xfc, 0x81, 0x3e,
+       0xe0, 0x23, 0xd2, 0x6e, 0xc0, 0x9e, 0x17, 0x81, 0xbb, 0x8c, 0x33, 0x9d,
+       0xea, 0x9d, 0x01, 0x6c, 0x50, 0x99, 0x81, 0x6e, 0x3c, 0xc3, 0xf3, 0x66,
+       0xe8, 0xb6, 0x33, 0x51, 0x29, 0xce, 0x52, 0x2e, 0xa5, 0xdd, 0xc0, 0x7a,
+       0xb1, 0x7e, 0x65, 0xa6, 0x13, 0x69, 0x0b, 0x52, 0x4b, 0xf5, 0x53, 0x99,
+       0x71, 0x54, 0xfb, 0xca, 0x4c, 0x4a, 0xb5, 0xab, 0xcc, 0xf4, 0x23, 0x75,
+       0xa5, 0xe1, 0x0c, 0x9c, 0xa5, 0x33, 0x3d, 0x32, 0x75, 0x12, 0xf6, 0x65,
+       0xc0, 0x50, 0x77, 0x35, 0x26, 0x60, 0x7f, 0x22, 0xf0, 0xac, 0x2e, 0x9a,
+       0x83, 0xc0, 0x58, 0x37, 0x01, 0x83, 0xdc, 0x24, 0xce, 0x09, 0xce, 0x9f,
+       0xba, 0xf7, 0x3c, 0x63, 0x5e, 0x89, 0x4f, 0x48, 0x46, 0xf6, 0xcf, 0x36,
+       0x62, 0xbf, 0x46, 0xcc, 0xa2, 0x74, 0x9b, 0xc3, 0xc8, 0xe7, 0xcb, 0xe4,
+       0xdb, 0xbd, 0xca, 0x5f, 0xcb, 0xba, 0x37, 0x34, 0x4b, 0x73, 0x1a, 0x63,
+       0xbc, 0x93, 0xf6, 0xbd, 0x90, 0x3f, 0x47, 0xf7, 0x91, 0x06, 0x3d, 0xf5,
+       0xfc, 0xe0, 0x39, 0x73, 0xe6, 0x57, 0x9c, 0x33, 0x53, 0xae, 0xc9, 0xdf,
+       0x7b, 0xe5, 0xbc, 0x93, 0x96, 0x97, 0x9d, 0x94, 0x5c, 0x70, 0x76, 0xca,
+       0x37, 0x61, 0xa7, 0x5f, 0x72, 0xce, 0x34, 0x11, 0x0b, 0x54, 0xd4, 0xd9,
+       0x5d, 0xb0, 0x56, 0x8e, 0x8e, 0x9d, 0xff, 0x50, 0x96, 0x67, 0x88, 0x9d,
+       0xbd, 0xdb, 0xf6, 0xb9, 0x05, 0xda, 0x2d, 0xd0, 0x40, 0xac, 0x56, 0x80,
+       0xfd, 0x3b, 0x24, 0xc3, 0x2e, 0xed, 0x9e, 0xb2, 0x51, 0x89, 0x61, 0x7f,
+       0x3f, 0xbb, 0x79, 0xe8, 0xd5, 0xf3, 0xb3, 0xd8, 0x4f, 0x42, 0xf9, 0xc7,
+       0x73, 0x99, 0xeb, 0xee, 0xc8, 0xe3, 0x25, 0xce, 0xb3, 0xb8, 0xbd, 0x59,
+       0xc2, 0x32, 0xa2, 0xf0, 0x42, 0xab, 0xbc, 0xb8, 0xb4, 0x45, 0x0c, 0x58,
+       0x28, 0xe3, 0xda, 0xa8, 0xba, 0xe5, 0x42, 0x9f, 0x5b, 0xda, 0x78, 0xb6,
+       0xf6, 0x87, 0xe0, 0x0d, 0xfd, 0x7f, 0xcc, 0xad, 0x8d, 0x33, 0x09, 0xf2,
+       0xfd, 0xd8, 0x5f, 0x7c, 0x0e, 0x49, 0xce, 0x89, 0xe3, 0x99, 0x29, 0xf7,
+       0x1c, 0x63, 0x63, 0x61, 0xf1, 0x31, 0xf7, 0x21, 0xf5, 0xbe, 0xd1, 0xb9,
+       0x15, 0xb8, 0x8e, 0xf2, 0x8a, 0x74, 0xd9, 0x1f, 0x37, 0x07, 0x1c, 0x97,
+       0xef, 0xe7, 0x1d, 0x1b, 0x3b, 0x55, 0xc0, 0x5e, 0x98, 0x50, 0xf5, 0x07,
+       0xe4, 0xa5, 0x99, 0x52, 0xb3, 0xbf, 0x3f, 0x06, 0xf5, 0x33, 0xdf, 0xd3,
+       0xa7, 0x62, 0x8c, 0xe4, 0x99, 0xd1, 0x69, 0xe7, 0xa2, 0xde, 0x3f, 0x12,
+       0xba, 0xb3, 0x17, 0x38, 0xf4, 0x68, 0x03, 0xe6, 0x62, 0x5b, 0x56, 0xc8,
+       0xe8, 0x30, 0x80, 0xe3, 0x87, 0x95, 0xcd, 0xed, 0x55, 0x31, 0xe8, 0x53,
+       0xa9, 0x56, 0xa9, 0x98, 0x8e, 0xba, 0x93, 0xb7, 0x62, 0xee, 0x20, 0xd6,
+       0xc7, 0xaf, 0x09, 0x65, 0xdd, 0x48, 0x1b, 0x91, 0xbe, 0x5f, 0x8a, 0xc7,
+       0xcf, 0xe8, 0xf1, 0xa2, 0x1b, 0xf2, 0x1f, 0xd1, 0xe9, 0x67, 0xb5, 0x3f,
+       0xc5, 0x71, 0xa2, 0xe2, 0x7c, 0xa1, 0x45, 0xba, 0x8f, 0x9a, 0xc0, 0xb6,
+       0x09, 0x60, 0xdd, 0x4e, 0x49, 0x1d, 0xb5, 0xe4, 0xda, 0xa3, 0x41, 0x9c,
+       0xe9, 0x2b, 0xa3, 0x49, 0x15, 0xd7, 0xfc, 0xf2, 0xa8, 0x53, 0x56, 0xe7,
+       0xed, 0xfa, 0xee, 0xe0, 0x8a, 0xbe, 0x53, 0xf8, 0xca, 0x68, 0xaf, 0x4a,
+       0xbf, 0x3d, 0x9a, 0x52, 0xe9, 0xab, 0xa3, 0xd7, 0x56, 0x7d, 0xff, 0xa8,
+       0xb8, 0x98, 0x92, 0xcf, 0x95, 0x88, 0x2f, 0x07, 0x80, 0x1d, 0x5d, 0xe8,
+       0x99, 0x7e, 0xe8, 0x99, 0x14, 0xf4, 0xcc, 0x20, 0xf5, 0x0c, 0xf4, 0xf6,
+       0xab, 0xd0, 0xdb, 0xae, 0x7c, 0x0f, 0xf2, 0xfa, 0x8c, 0xdb, 0x08, 0x5c,
+       0xe8, 0x79, 0xfe, 0x5c, 0xed, 0x27, 0x56, 0xb0, 0xbe, 0x95, 0xd3, 0x12,
+       0x6b, 0x83, 0x0e, 0xda, 0xb1, 0xd0, 0x20, 0x8b, 0x71, 0xcf, 0x9b, 0x73,
+       0x1d, 0xb9, 0x84, 0xfa, 0x59, 0x87, 0xfb, 0xf8, 0x6f, 0x9a, 0xe9, 0x8f,
+       0x5d, 0x9a, 0xd9, 0x09, 0x9d, 0x44, 0x79, 0x8f, 0x49, 0x65, 0x3c, 0x21,
+       0x4b, 0xf0, 0xcf, 0xd6, 0xea, 0xa4, 0xf0, 0xcc, 0xfd, 0xff, 0x13, 0xd4,
+       0x4d, 0xc1, 0x3e, 0x98, 0xb2, 0xdc, 0x6b, 0xc9, 0xa9, 0x5e, 0x7b, 0xd0,
+       0x32, 0xa8, 0xbb, 0x2c, 0x29, 0xc3, 0xbf, 0xaf, 0x94, 0x58, 0x9f, 0xf5,
+       0xb0, 0x3f, 0x4b, 0x7e, 0xbb, 0xe9, 0x52, 0xa0, 0x27, 0x06, 0x18, 0x7b,
+       0x8c, 0xe4, 0x7a, 0x7d, 0x1b, 0x60, 0x18, 0x8d, 0x90, 0x03, 0x17, 0xfc,
+       0x1f, 0x47, 0xf9, 0x00, 0xef, 0x9a, 0xa0, 0x8c, 0x58, 0x28, 0xb6, 0x85,
+       0x18, 0x31, 0xe7, 0x8e, 0xa3, 0x8c, 0x6d, 0xec, 0x44, 0x12, 0xe5, 0x63,
+       0x92, 0x4c, 0xe4, 0xd5, 0xbd, 0xb7, 0x0e, 0x94, 0xb1, 0x8f, 0xb0, 0x8e,
+       0xc1, 0x74, 0x6c, 0xf1, 0xcf, 0x7d, 0x83, 0xf2, 0x3e, 0x15, 0x0f, 0xc8,
+       0x98, 0x2e, 0xf6, 0x03, 0xcb, 0x92, 0x26, 0xdb, 0xe5, 0x5c, 0x57, 0xe9,
+       0xc2, 0x7b, 0xaa, 0x3c, 0xb7, 0x8b, 0xc9, 0xdd, 0xd5, 0x16, 0xc9, 0x55,
+       0x1b, 0xae, 0xa0, 0xff, 0x83, 0x3d, 0x79, 0x3e, 0x61, 0x0a, 0xef, 0x60,
+       0xf8, 0xfb, 0x3c, 0xb2, 0x93, 0x7b, 0x02, 0x7c, 0x87, 0xfd, 0x7d, 0x0e,
+       0xf3, 0x7d, 0x16, 0xf6, 0xf7, 0x1c, 0xec, 0xef, 0x33, 0xa5, 0x35, 0xfd,
+       0xe1, 0xdb, 0x5d, 0xea, 0x80, 0xa7, 0xb0, 0x66, 0x63, 0xc0, 0xfd, 0xbb,
+       0xe1, 0x0f, 0x8c, 0x00, 0xfb, 0x0f, 0x61, 0xfd, 0xd2, 0x58, 0xbb, 0x71,
+       0xde, 0x55, 0xc2, 0x3a, 0x0e, 0xaa, 0xb3, 0xe5, 0x59, 0x75, 0xdf, 0xe3,
+       0x87, 0xca, 0xf6, 0x3e, 0x56, 0x32, 0x60, 0x1f, 0x0a, 0xde, 0x76, 0xc7,
+       0x06, 0xfe, 0x5b, 0xdd, 0xcf, 0x83, 0x2f, 0x42, 0xaf, 0xfc, 0x1d, 0xe8,
+       0x7a, 0x76, 0x96, 0xf6, 0x1c, 0x75, 0x7c, 0xbc, 0xed, 0x32, 0xbe, 0x85,
+       0xfd, 0x7c, 0xe4, 0xbc, 0xac, 0x00, 0x77, 0x64, 0x28, 0xc7, 0xf0, 0x1f,
+       0xec, 0x67, 0xca, 0xd2, 0x43, 0x1d, 0x58, 0xe6, 0x5e, 0x19, 0x38, 0x96,
+       0x00, 0xd6, 0x03, 0x92, 0x57, 0x67, 0xa9, 0x78, 0x3e, 0xbb, 0x55, 0x0c,
+       0xe2, 0x3d, 0xf7, 0x2a, 0x94, 0x51, 0x6f, 0x04, 0x18, 0x69, 0x65, 0xb0,
+       0x5d, 0x32, 0x3b, 0xda, 0x95, 0xee, 0xb0, 0xdd, 0x97, 0x31, 0xee, 0x2e,
+       0x69, 0x04, 0x86, 0x2b, 0x60, 0x8c, 0x83, 0xf2, 0x37, 0x2e, 0xe3, 0x52,
+       0xbe, 0xef, 0x07, 0x5a, 0x62, 0xe0, 0x59, 0xd3, 0x3e, 0xc7, 0x8c, 0xed,
+       0xaa, 0xb1, 0xff, 0x98, 0xc2, 0x58, 0x39, 0x61, 0xff, 0xb0, 0x13, 0x18,
+       0x33, 0x79, 0x8c, 0xb2, 0xdf, 0x87, 0x75, 0xfb, 0x2d, 0x60, 0x20, 0x72,
+       0xf5, 0x5b, 0x5b, 0xfc, 0xfd, 0x42, 0xfa, 0x57, 0x88, 0x27, 0x18, 0xf7,
+       0xf7, 0xfd, 0xf2, 0x55, 0xda, 0x06, 0x40, 0xef, 0x73, 0x5b, 0x82, 0xf3,
+       0xe3, 0xae, 0x63, 0xbe, 0xbd, 0xee, 0x3a, 0x8b, 0x56, 0x73, 0xd2, 0xc1,
+       0x93, 0x68, 0x43, 0xae, 0x95, 0xdb, 0x23, 0x7e, 0x3f, 0xc6, 0x82, 0x09,
+       0x59, 0xa5, 0x1e, 0xe8, 0x80, 0x9c, 0x33, 0x4f, 0x9d, 0x42, 0x9d, 0x40,
+       0x59, 0x70, 0xa4, 0x58, 0x83, 0x4e, 0x68, 0xed, 0x94, 0x32, 0x79, 0xb6,
+       0x40, 0x3d, 0xf1, 0x43, 0x99, 0xde, 0xa0, 0x2b, 0x87, 0x24, 0xf0, 0x6b,
+       0x5b, 0x24, 0x9a, 0x76, 0xcc, 0x7b, 0xd4, 0x1c, 0x7d, 0x7d, 0xb9, 0x9f,
+       0xf8, 0x73, 0x36, 0x63, 0xb7, 0x8b, 0xc6, 0x9e, 0x0a, 0x3f, 0x7d, 0x1f,
+       0x73, 0x65, 0x1f, 0x8a, 0x4f, 0x83, 0x43, 0xbe, 0x2f, 0xa0, 0xe2, 0x7c,
+       0xc0, 0xc1, 0x89, 0xbf, 0x83, 0xae, 0xcd, 0x11, 0x97, 0x80, 0xcf, 0x5d,
+       0x73, 0x94, 0xa3, 0xed, 0xd4, 0x65, 0xc0, 0x79, 0x29, 0xea, 0x6b, 0x59,
+       0x3a, 0x06, 0xcc, 0x65, 0xdc, 0x2a, 0x79, 0xca, 0x2b, 0xef, 0x48, 0x2c,
+       0x19, 0x32, 0x3d, 0xdf, 0x2a, 0xdd, 0x0b, 0x8c, 0xa9, 0x7e, 0xb3, 0x59,
+       0x5a, 0x19, 0x57, 0xa5, 0x0d, 0x1a, 0x90, 0x1c, 0xca, 0xbb, 0x16, 0xc2,
+       0x2a, 0x06, 0x56, 0x36, 0xc8, 0xa3, 0x7e, 0xe8, 0x03, 0x3b, 0xb5, 0x62,
+       0x7c, 0xb4, 0xc9, 0xc7, 0x90, 0x90, 0xa5, 0x12, 0x64, 0xac, 0x04, 0x19,
+       0x2b, 0x41, 0xc6, 0x4a, 0x90, 0x31, 0x60, 0xbf, 0x67, 0xb1, 0xff, 0xce,
+       0x95, 0x06, 0xb5, 0x5d, 0xdf, 0xa3, 0xec, 0xfa, 0xe1, 0xd2, 0xab, 0x1e,
+       0xd3, 0x2f, 0x29, 0xdf, 0xb4, 0x1f, 0x32, 0x48, 0x5f, 0x34, 0xf0, 0x51,
+       0x5f, 0x95, 0xa7, 0x66, 0x5f, 0x93, 0x53, 0xb3, 0x6b, 0x38, 0x70, 0xaa,
+       0xe4, 0xc9, 0xcb, 0x2e, 0xfc, 0xcf, 0x45, 0x62, 0xaa, 0x4c, 0x5b, 0xa3,
+       0xc2, 0x56, 0x87, 0x24, 0xaf, 0x70, 0xb2, 0xb2, 0x23, 0xc0, 0x57, 0x0a,
+       0x17, 0x72, 0x6f, 0x4a, 0xfb, 0x8e, 0xd7, 0xe5, 0x1c, 0xec, 0xf8, 0x52,
+       0xed, 0x0d, 0x79, 0x4e, 0xe1, 0x71, 0xf2, 0xe1, 0x7d, 0xf2, 0xb7, 0xa6,
+       0x7f, 0x86, 0x7f, 0x0a, 0x58, 0x63, 0xa9, 0x97, 0xba, 0x23, 0x02, 0x5b,
+       0x60, 0x17, 0xba, 0xb0, 0xaf, 0x0f, 0x18, 0xef, 0x02, 0xa6, 0xe1, 0xfb,
+       0xad, 0xf2, 0xe2, 0x6c, 0xa1, 0x4e, 0x26, 0xa8, 0x1f, 0xec, 0x23, 0x62,
+       0xd0, 0x4e, 0xd1, 0x6e, 0x72, 0xbe, 0xb4, 0x53, 0x6d, 0x2d, 0xbc, 0x3f,
+       0x56, 0x39, 0x7e, 0xc3, 0x16, 0xc6, 0x18, 0xe3, 0x0e, 0x79, 0xfa, 0xba,
+       0x1c, 0xa8, 0xb2, 0xec, 0x35, 0xac, 0x0f, 0xd3, 0x37, 0xbd, 0xbb, 0xe3,
+       0x1c, 0x8f, 0xfd, 0x02, 0x37, 0x75, 0x60, 0xae, 0xa5, 0xcf, 0x6a, 0xcc,
+       0xdd, 0xaf, 0x70, 0xf4, 0xe5, 0x78, 0x99, 0x7c, 0x72, 0xc1, 0xa7, 0xd7,
+       0x55, 0x0c, 0x70, 0x93, 0xd8, 0xf0, 0x13, 0xd8, 0x57, 0x85, 0x8b, 0xc2,
+       0x38, 0x25, 0x63, 0xb8, 0x8c, 0x0f, 0xd7, 0x6b, 0x0c, 0x75, 0x57, 0x40,
+       0xee, 0x82, 0x7e, 0xb9, 0x1b, 0xfa, 0xe5, 0x9e, 0xcb, 0xee, 0x5f, 0x07,
+       0x71, 0xff, 0xee, 0x42, 0xd8, 0xe8, 0x94, 0xb1, 0x6a, 0x7d, 0x5b, 0xc6,
+       0x6e, 0x37, 0x8b, 0xd5, 0x32, 0x8e, 0x9b, 0xda, 0x10, 0xff, 0xa3, 0x6c,
+       0x78, 0xf2, 0x92, 0xcb, 0xb8, 0x5b, 0x70, 0x67, 0x7f, 0x33, 0xfc, 0x65,
+       0xb5, 0x04, 0x71, 0xe6, 0x48, 0xfa, 0xa2, 0xf0, 0xee, 0x7e, 0x71, 0x86,
+       0x78, 0x20, 0xae, 0xee, 0xd9, 0x19, 0x2a, 0xce, 0xe7, 0xb7, 0x2d, 0xce,
+       0xa8, 0x73, 0xa5, 0x02, 0xe3, 0xd5, 0xe6, 0x4e, 0xdb, 0x1c, 0x0b, 0xfb,
+       0xf7, 0x65, 0xb8, 0x97, 0x7d, 0x5d, 0x06, 0x59, 0xac, 0xad, 0xdd, 0xb1,
+       0x1c, 0x52, 0xfa, 0xe2, 0x22, 0xf6, 0x00, 0xd7, 0x0b, 0xfe, 0x02, 0xf6,
+       0xc9, 0x14, 0xf4, 0x53, 0x5e, 0xf5, 0x17, 0xa3, 0x5c, 0x64, 0xb2, 0x61,
+       0x43, 0xa2, 0x27, 0xe8, 0x0b, 0xf9, 0xb1, 0x96, 0x5c, 0xd8, 0x56, 0xfa,
+       0x1b, 0xb4, 0x03, 0x9f, 0x71, 0x7f, 0x5a, 0x13, 0x8d, 0xe9, 0x06, 0xd8,
+       0x55, 0xac, 0x5f, 0x8d, 0x31, 0x01, 0xec, 0xdd, 0xe5, 0xef, 0xca, 0xfe,
+       0xf9, 0xe1, 0x16, 0x5f, 0xfe, 0x19, 0x3b, 0xe6, 0xfc, 0x02, 0x1a, 0xd6,
+       0xf7, 0x6d, 0x9c, 0x90, 0x58, 0x33, 0x6c, 0xda, 0x87, 0xe1, 0x67, 0xec,
+       0x82, 0xac, 0xac, 0xc4, 0xd9, 0xaf, 0xbf, 0x67, 0xa6, 0x4b, 0xec, 0xfb,
+       0xbb, 0x32, 0x3c, 0x7f, 0xb6, 0x85, 0xb6, 0x64, 0x19, 0x7a, 0xe0, 0xbc,
+       0x49, 0x1b, 0x3a, 0x0e, 0x1b, 0xd7, 0x21, 0xdf, 0x9f, 0xa7, 0x7d, 0x4c,
+       0x9a, 0xa7, 0xa4, 0x2f, 0x71, 0x0a, 0x34, 0x7d, 0xde, 0x8d, 0xd0, 0x47,
+       0xf3, 0x86, 0x50, 0xf6, 0x4d, 0x49, 0x9a, 0x5d, 0x21, 0x3e, 0xf7, 0x99,
+       0x8f, 0x03, 0xc3, 0x66, 0xcc, 0xa4, 0x79, 0x5d, 0x88, 0x72, 0x04, 0x9f,
+       0x7b, 0x79, 0x8d, 0xce, 0x37, 0xe7, 0x95, 0x9f, 0xa4, 0xf4, 0xcc, 0xb2,
+       0xcb, 0xf1, 0x40, 0xb7, 0xd2, 0x59, 0xd7, 0x41, 0x9f, 0xc4, 0xf4, 0x99,
+       0x1b, 0xda, 0x10, 0xdb, 0xb8, 0x11, 0x9d, 0x7f, 0x44, 0xb2, 0x27, 0xe3,
+       0xd0, 0x67, 0xec, 0x2b, 0xf0, 0x1d, 0x68, 0x23, 0x03, 0xbc, 0x4d, 0x7b,
+       0x77, 0x2b, 0xec, 0xde, 0x35, 0x8a, 0x9e, 0x11, 0xb7, 0x5f, 0xa6, 0x8e,
+       0x73, 0xec, 0x5e, 0xe8, 0xf2, 0x84, 0x92, 0xdb, 0x62, 0xe9, 0x7c, 0x22,
+       0x06, 0x9d, 0x1c, 0xdb, 0x41, 0x7e, 0x7e, 0x50, 0xee, 0x70, 0xc6, 0xe5,
+       0x4e, 0xc8, 0xce, 0x90, 0xe3, 0xca, 0x30, 0xd6, 0x62, 0x97, 0x03, 0xbb,
+       0xa3, 0x30, 0x74, 0x23, 0xfc, 0x2e, 0x8e, 0xdd, 0xa1, 0xef, 0x5c, 0xf8,
+       0xf8, 0xf1, 0xcf, 0x6a, 0x3e, 0x8f, 0xb2, 0xf3, 0x2f, 0x2b, 0xde, 0x8c,
+       0xb8, 0x37, 0x69, 0x3b, 0xdb, 0x2a, 0x39, 0x55, 0xef, 0x26, 0x65, 0x8f,
+       0x8b, 0x4b, 0xf7, 0x22, 0x85, 0x6d, 0x5e, 0x82, 0xbe, 0x01, 0xe6, 0x2e,
+       0x56, 0x77, 0x22, 0x0f, 0x1b, 0xba, 0x94, 0x46, 0xfa, 0x41, 0xa4, 0xac,
+       0xfb, 0xb9, 0x16, 0x3f, 0x96, 0x5b, 0x7f, 0x87, 0xcc, 0xbf, 0x7f, 0xfa,
+       0x61, 0x85, 0x4b, 0x2f, 0xaa, 0xfb, 0x87, 0x06, 0xb0, 0x4e, 0x16, 0x7a,
+       0xa5, 0x05, 0x18, 0x68, 0xe6, 0x84, 0x9d, 0x1a, 0x0e, 0xdd, 0x26, 0x1f,
+       0x81, 0x2f, 0x5f, 0x71, 0xb9, 0x96, 0x3b, 0xe5, 0x13, 0xb7, 0x50, 0x46,
+       0x6e, 0x93, 0x7d, 0xb7, 0x84, 0x64, 0x5f, 0xbf, 0x9d, 0x21, 0xdd, 0xd7,
+       0xbe, 0x3f, 0xf0, 0xa7, 0xbb, 0x47, 0x92, 0xa1, 0x01, 0x79, 0x1c, 0x32,
+       0x56, 0x80, 0x7c, 0x0d, 0xd7, 0xc8, 0x73, 0xea, 0x7b, 0xea, 0xf9, 0x14,
+       0xb0, 0x72, 0x80, 0xfd, 0x1c, 0x99, 0xa9, 0x35, 0x88, 0x75, 0x15, 0xe3,
+       0xc9, 0x96, 0x7f, 0xae, 0x71, 0x15, 0x65, 0x02, 0x3e, 0xc8, 0x55, 0xfe,
+       0xfe, 0x54, 0xf7, 0xfe, 0xae, 0xf2, 0xed, 0x0a, 0xfc, 0x5f, 0x8f, 0x38,
+       0xcf, 0xbf, 0x5f, 0x70, 0x51, 0xeb, 0xd2, 0xe4, 0xd6, 0x55, 0x7c, 0xd7,
+       0x4a, 0xff, 0xe1, 0xeb, 0x2d, 0x6b, 0xdf, 0x2d, 0x6c, 0x94, 0xc5, 0x20,
+       0xee, 0x56, 0xc6, 0x9c, 0x69, 0xd3, 0x6d, 0x93, 0xba, 0xb0, 0xcd, 0xd9,
+       0x23, 0x7f, 0x09, 0xfb, 0xfe, 0xd5, 0x55, 0xfb, 0xbe, 0x17, 0xfc, 0xd8,
+       0x88, 0x01, 0x1c, 0xf3, 0x2e, 0xcc, 0x65, 0x04, 0xeb, 0x79, 0x27, 0x7e,
+       0x77, 0x94, 0xd6, 0xc5, 0xf1, 0x66, 0x0b, 0xc0, 0x93, 0x0d, 0x0e, 0xfb,
+       0x5b, 0x17, 0xcf, 0x2b, 0xe4, 0x65, 0x35, 0x56, 0x38, 0x78, 0x49, 0x68,
+       0xf7, 0xde, 0x92, 0x68, 0x8f, 0xf3, 0x56, 0x57, 0xc8, 0x79, 0xde, 0x08,
+       0xf1, 0xec, 0xdb, 0x95, 0xd3, 0x35, 0xe2, 0xb0, 0x0b, 0x62, 0x9c, 0x25,
+       0x06, 0x7b, 0x45, 0xc5, 0xa0, 0x2a, 0xa5, 0x6f, 0x23, 0x45, 0x7d, 0xe8,
+       0xc7, 0xb0, 0x1f, 0xa7, 0x50, 0x58, 0x85, 0x7a, 0xf6, 0x4e, 0xac, 0xc3,
+       0x14, 0x7e, 0x5d, 0x3b, 0xae, 0xc3, 0xfe, 0xa5, 0x9c, 0x32, 0xf6, 0xd5,
+       0x63, 0xee, 0x08, 0xf1, 0xdd, 0x66, 0x71, 0xb0, 0xef, 0x48, 0x64, 0x0e,
+       0xb6, 0xce, 0xa0, 0x7e, 0xe0, 0x3c, 0x68, 0x27, 0x4d, 0x59, 0x3c, 0xce,
+       0xbd, 0xbe, 0x59, 0xfd, 0xa0, 0x6e, 0x30, 0x17, 0x65, 0x37, 0x32, 0x79,
+       0xc6, 0x38, 0x4b, 0x5c, 0x03, 0x17, 0x6b, 0xe0, 0xc9, 0x09, 0xb7, 0x0d,
+       0x7a, 0x3b, 0x2e, 0xe1, 0x13, 0x9e, 0x0c, 0x29, 0xec, 0xda, 0x07, 0xcc,
+       0xb5, 0x55, 0xe3, 0x86, 0xb8, 0x44, 0x4e, 0x74, 0x4a, 0x23, 0x70, 0x75,
+       0xc3, 0x51, 0xda, 0xc8, 0xa4, 0x35, 0x04, 0x21, 0x88, 0xa8, 0xbb, 0xac,
+       0xf6, 0xe0, 0xf7, 0xa5, 0xcf, 0xfa, 0xbe, 0x10, 0x2f, 0xfd, 0x7b, 0xac,
+       0x9f, 0xed, 0x5e, 0xd8, 0xa4, 0x7e, 0x71, 0xad, 0x3e, 0xe4, 0x88, 0xb1,
+       0x35, 0xb6, 0x61, 0xac, 0x2d, 0x39, 0xf8, 0x3d, 0xc6, 0xd8, 0xe0, 0x6b,
+       0x36, 0x9c, 0xf1, 0x69, 0x30, 0x96, 0xdb, 0xa5, 0x72, 0x92, 0x7b, 0x94,
+       0x71, 0x16, 0xd3, 0xf7, 0x53, 0x4b, 0xf4, 0x57, 0xf9, 0xde, 0xd2, 0xef,
+       0xbb, 0xf4, 0x7b, 0xfa, 0xa3, 0x05, 0xaf, 0x01, 0x3c, 0xdd, 0x05, 0xfd,
+       0x79, 0xef, 0x4e, 0x47, 0xe1, 0x86, 0x7b, 0x57, 0xd7, 0x6c, 0xb7, 0xba,
+       0x4f, 0x54, 0x29, 0x1d, 0x12, 0x67, 0xc7, 0x4a, 0x2a, 0x22, 0x63, 0x58,
+       0x0b, 0xe6, 0x33, 0xa4, 0x27, 0x75, 0x58, 0x0e, 0xa8, 0xb5, 0xa9, 0x1c,
+       0xb7, 0x8f, 0x58, 0xa1, 0x29, 0x31, 0x2a, 0x7c, 0xfe, 0x34, 0xd2, 0xc3,
+       0xc0, 0x3b, 0x7e, 0xec, 0xd2, 0xa8, 0xac, 0xe7, 0x25, 0x30, 0x86, 0xb9,
+       0x6b, 0x5d, 0x1c, 0x6b, 0x2d, 0xc6, 0xc5, 0xf7, 0x43, 0xea, 0x7d, 0x6a,
+       0x5d, 0x9c, 0x2b, 0x67, 0x10, 0xcb, 0x04, 0xef, 0xb9, 0x16, 0x5c, 0x2f,
+       0xd8, 0xe2, 0xe3, 0x41, 0xcc, 0xab, 0x55, 0xaf, 0x0b, 0xd7, 0x67, 0x46,
+       0xce, 0x99, 0xf6, 0x08, 0xe5, 0xef, 0x86, 0x9d, 0x57, 0xcb, 0x44, 0x07,
+       0xe3, 0x6d, 0xf5, 0x34, 0x6c, 0x8c, 0xa3, 0xd5, 0x8f, 0xbf, 0x31, 0xfe,
+       0xc6, 0xb1, 0xfd, 0x18, 0x5b, 0x76, 0x5d, 0x8c, 0xad, 0x7e, 0x3c, 0x8e,
+       0xb5, 0x15, 0xfe, 0x53, 0xc1, 0x8b, 0x3b, 0x5c, 0xa3, 0x6e, 0x6b, 0x9e,
+       0xf9, 0x2f, 0x1a, 0x58, 0xc7, 0x38, 0xec, 0x08, 0xd7, 0x32, 0x38, 0x6f,
+       0xe6, 0x9a, 0x26, 0xad, 0xc3, 0xfe, 0x7a, 0x0e, 0xfa, 0xeb, 0xee, 0xaf,
+       0xff, 0x85, 0xd5, 0x75, 0xa4, 0x7d, 0xe0, 0x3a, 0x76, 0x88, 0x40, 0xcf,
+       0x1a, 0x47, 0xb9, 0x86, 0x4c, 0xb9, 0x86, 0x7c, 0xc7, 0x35, 0xec, 0xd2,
+       0xef, 0xb8, 0x7e, 0xc0, 0x69, 0x5f, 0xe0, 0x3d, 0xd5, 0xac, 0xfa, 0x06,
+       0xab, 0xab, 0x27, 0xd8, 0x8b, 0x29, 0x79, 0x6e, 0xb1, 0x59, 0xcc, 0xb4,
+       0x3f, 0xaf, 0xf1, 0x75, 0xf1, 0x76, 0x9e, 0x5f, 0xf5, 0x13, 0x7b, 0x06,
+       0xf3, 0x4a, 0x70, 0x5e, 0x07, 0xe4, 0x75, 0xc9, 0xcf, 0x44, 0xe0, 0x03,
+       0xa6, 0x80, 0x73, 0xfa, 0xa1, 0x6f, 0x19, 0x1f, 0x45, 0x59, 0x95, 0x78,
+       0x85, 0xb6, 0x2e, 0x85, 0xbd, 0x42, 0x1d, 0x4c, 0x3c, 0xf2, 0x9a, 0xe4,
+       0xca, 0x81, 0x8e, 0x41, 0xff, 0x46, 0xd0, 0x3f, 0xf9, 0x9c, 0xb9, 0x76,
+       0xbb, 0xac, 0x58, 0xdb, 0xc5, 0xb6, 0x96, 0x64, 0x6d, 0x5d, 0xc7, 0x37,
+       0xe7, 0xbb, 0x7b, 0x6f, 0x78, 0x4d, 0x36, 0xc6, 0x37, 0x59, 0xfb, 0x49,
+       0x09, 0xde, 0x07, 0x6b, 0xbf, 0xe9, 0x3a, 0x14, 0x5e, 0x15, 0xae, 0x05,
+       0x79, 0x40, 0x3c, 0x1c, 0x95, 0x7f, 0x13, 0xe7, 0x7e, 0x2c, 0xa8, 0x33,
+       0xcd, 0xa4, 0xd1, 0xa3, 0x74, 0xc6, 0x90, 0xeb, 0xcb, 0x6b, 0x01, 0xe3,
+       0xc4, 0xba, 0xff, 0xd0, 0x1b, 0x8a, 0xc3, 0xcf, 0xed, 0xa6, 0x7e, 0x09,
+       0xf6, 0x74, 0xb3, 0xda, 0xd3, 0x9f, 0x77, 0x43, 0x52, 0x74, 0x42, 0x32,
+       0xe5, 0x1c, 0x52, 0x18, 0xff, 0xa3, 0xe8, 0xeb, 0x13, 0xba, 0xaf, 0x29,
+       0xe9, 0xd1, 0xfa, 0xe7, 0x20, 0xe4, 0xdc, 0x93, 0x7b, 0xdc, 0x9d, 0x72,
+       0x43, 0x1b, 0xf7, 0x40, 0x30, 0xff, 0x43, 0xd2, 0xbd, 0x73, 0xc5, 0x82,
+       0x67, 0x70, 0x6d, 0x74, 0x95, 0x07, 0xdc, 0x67, 0x81, 0x7c, 0xfb, 0x7c,
+       0xf0, 0xe7, 0xbf, 0x6e, 0xae, 0x7a, 0x9e, 0x9c, 0x33, 0xeb, 0x71, 0xae,
+       0x3e, 0x96, 0x5f, 0x9b, 0x6b, 0x50, 0xbf, 0x05, 0xb2, 0x64, 0x5b, 0x12,
+       0xaa, 0xe7, 0xcd, 0xaa, 0x8e, 0x1a, 0x61, 0x8c, 0x64, 0xc5, 0xb4, 0x53,
+       0x56, 0x28, 0x88, 0x45, 0xfb, 0x58, 0xb7, 0x0b, 0x38, 0xdc, 0xe9, 0xe9,
+       0x49, 0xe5, 0x55, 0x8c, 0xd4, 0x50, 0xf3, 0x9a, 0x02, 0x26, 0x5b, 0x74,
+       0x5f, 0xf5, 0x3e, 0x09, 0xcc, 0x3a, 0x21, 0x0f, 0x49, 0x78, 0x5d, 0x2c,
+       0x17, 0xf9, 0xb3, 0x8c, 0xe7, 0xda, 0x56, 0x06, 0x6b, 0xfc, 0x3b, 0xf0,
+       0xe1, 0x2b, 0xd0, 0xfb, 0x1f, 0xa3, 0x6d, 0x28, 0xc1, 0x5e, 0x00, 0x97,
+       0x7c, 0xf5, 0x8a, 0x18, 0x7e, 0xa2, 0x2e, 0x96, 0xeb, 0xe3, 0xd3, 0x73,
+       0x0a, 0x93, 0x12, 0xb7, 0x1f, 0x09, 0xdd, 0xd5, 0x1b, 0x86, 0x9f, 0x51,
+       0xf0, 0x62, 0x0e, 0x71, 0xdc, 0x21, 0xb9, 0x03, 0xeb, 0x73, 0x7a, 0xb1,
+       0x10, 0xda, 0x55, 0x0a, 0x64, 0x15, 0x7e, 0x65, 0xcd, 0x4e, 0x9d, 0x07,
+       0x3f, 0x9e, 0xd2, 0x98, 0x8f, 0xe7, 0x35, 0x15, 0xed, 0xb3, 0x30, 0x36,
+       0x54, 0xac, 0x1d, 0x92, 0x69, 0x97, 0xb1, 0x9d, 0x6e, 0x29, 0xc6, 0x33,
+       0x57, 0x37, 0xae, 0xf2, 0xc8, 0x36, 0xe1, 0xf3, 0xa5, 0xa8, 0xbf, 0x2b,
+       0xfa, 0xbc, 0xe3, 0x29, 0x25, 0x5f, 0x41, 0x5c, 0x98, 0xfe, 0x11, 0xcf,
+       0xab, 0xba, 0xcd, 0x11, 0x3e, 0x97, 0x29, 0x03, 0xca, 0x67, 0x02, 0x2f,
+       0xef, 0x90, 0xcc, 0x98, 0xa5, 0x70, 0xcb, 0x63, 0x25, 0xee, 0x17, 0xe2,
+       0xff, 0xd7, 0x81, 0xfd, 0x23, 0x58, 0x33, 0xfa, 0x01, 0x1c, 0x9b, 0xfb,
+       0x02, 0x65, 0x55, 0xf3, 0x97, 0xec, 0x8b, 0x0f, 0x6d, 0x23, 0xc6, 0x78,
+       0xa1, 0xf4, 0x98, 0xe2, 0xdf, 0x8a, 0x04, 0xb1, 0x73, 0x85, 0x05, 0x0b,
+       0xd9, 0x70, 0x48, 0x92, 0x73, 0xff, 0x16, 0x32, 0xd4, 0x0f, 0x1f, 0x89,
+       0xf5, 0x44, 0x9d, 0x5f, 0x0d, 0x01, 0x73, 0x19, 0xce, 0xbb, 0xa4, 0x68,
+       0x46, 0xa5, 0xa8, 0xee, 0xfe, 0xf1, 0x3c, 0x37, 0xac, 0x62, 0x3b, 0x45,
+       0x93, 0x98, 0x3f, 0xbd, 0x2d, 0xb8, 0xfb, 0x57, 0x34, 0xd9, 0x8e, 0x79,
+       0x96, 0x4f, 0x49, 0x74, 0xee, 0xa0, 0x34, 0xcc, 0x3d, 0x24, 0x8d, 0xc7,
+       0x88, 0xf1, 0x18, 0xbb, 0x37, 0x6e, 0x6d, 0x14, 0x62, 0xee, 0x6f, 0x61,
+       0xec, 0x43, 0xf2, 0x03, 0x37, 0xa0, 0xe9, 0xba, 0xad, 0xd2, 0xca, 0x3a,
+       0x41, 0x9e, 0xcf, 0xc4, 0x09, 0x3c, 0x17, 0x77, 0xfc, 0x18, 0xa9, 0x3a,
+       0x57, 0x41, 0x5a, 0xe1, 0xb9, 0x38, 0xdf, 0xbf, 0x66, 0xfa, 0xa9, 0x8f,
+       0xf7, 0x7d, 0xdf, 0x83, 0x6d, 0x52, 0x75, 0xd8, 0x62, 0xfd, 0xf7, 0xa1,
+       0x39, 0x94, 0xe7, 0xe7, 0x83, 0x3b, 0x3a, 0x06, 0x7c, 0x5f, 0xbb, 0x40,
+       0x9f, 0xc1, 0xe4, 0xb7, 0x98, 0xf3, 0x05, 0xf0, 0xf9, 0x1a, 0x75, 0xbf,
+       0x87, 0x77, 0x24, 0x50, 0xcf, 0xf2, 0x31, 0x1f, 0xf3, 0x09, 0xf0, 0xf9,
+       0xfd, 0x9d, 0x46, 0xfa, 0x7f, 0x5f, 0x9d, 0x1d, 0x20, 0xa6, 0xd8, 0xc6,
+       0xb3, 0x3f, 0x60, 0x55, 0xae, 0xed, 0x77, 0xb1, 0xb6, 0x8d, 0xea, 0xac,
+       0xa5, 0x58, 0xa2, 0x0f, 0x95, 0xc7, 0x9a, 0xf1, 0x9e, 0x1c, 0x7d, 0xad,
+       0xbc, 0x8e, 0x81, 0x92, 0x4e, 0xe2, 0xe8, 0x00, 0x93, 0xb3, 0xcf, 0xcd,
+       0xee, 0x03, 0x07, 0x7e, 0x12, 0xd7, 0x38, 0xa1, 0x68, 0x1e, 0xde, 0xe0,
+       0x23, 0x1c, 0xc6, 0xfe, 0x5b, 0x84, 0x0c, 0x4d, 0x42, 0xef, 0x0c, 0x85,
+       0xb9, 0x27, 0x9a, 0xb5, 0xff, 0xe8, 0xd0, 0x57, 0x0e, 0x8d, 0xa1, 0x0f,
+       0xe3, 0xd8, 0x1b, 0x32, 0x05, 0x9d, 0x3b, 0x5d, 0x4b, 0xaa, 0x6f, 0x78,
+       0x32, 0x09, 0xde, 0xdb, 0x62, 0xf9, 0x7f, 0x81, 0x8c, 0xbc, 0x01, 0x0c,
+       0xba, 0x05, 0xfc, 0x34, 0xf4, 0xbd, 0x90, 0x0f, 0xe8, 0xf8, 0x4f, 0x8c,
+       0xf1, 0x6f, 0xe8, 0xaa, 0xa2, 0x8f, 0xef, 0xe2, 0xd3, 0x48, 0xbf, 0xd0,
+       0xec, 0xcb, 0xc8, 0xcb, 0x7a, 0x8d, 0x9b, 0x50, 0xfe, 0xa8, 0x8a, 0xfb,
+       0xf9, 0x73, 0xb2, 0xb5, 0x7f, 0x10, 0xc5, 0x3a, 0x73, 0x5e, 0x5f, 0x41,
+       0x3d, 0xae, 0x6f, 0xaf, 0x3e, 0x0f, 0x6d, 0x56, 0x3a, 0x29, 0xe7, 0x5a,
+       0xf0, 0x75, 0x89, 0x89, 0x80, 0xa9, 0x5d, 0xb6, 0x7b, 0x76, 0x1b, 0xcf,
+       0x1b, 0x1b, 0x1c, 0x85, 0xe7, 0x3b, 0xc2, 0x12, 0x94, 0xdd, 0x8e, 0x32,
+       0xc6, 0x25, 0xde, 0x85, 0xb5, 0x61, 0x59, 0x16, 0x79, 0x8e, 0x75, 0xb5,
+       0x1e, 0x87, 0x63, 0x0c, 0xb7, 0xac, 0xa7, 0x89, 0x73, 0xe9, 0xd8, 0xf0,
+       0xfd, 0x00, 0xcb, 0xde, 0xa5, 0xcb, 0x22, 0x7a, 0x7e, 0xb7, 0xeb, 0x6f,
+       0x67, 0xed, 0x23, 0x99, 0x55, 0x3c, 0x4a, 0xfa, 0x62, 0xaa, 0x5d, 0xc6,
+       0xf4, 0x65, 0xe7, 0x30, 0xd6, 0x23, 0x92, 0xf6, 0xda, 0xb9, 0x47, 0x86,
+       0xc2, 0x81, 0x5f, 0x98, 0x50, 0xbe, 0x9e, 0x65, 0xf8, 0x77, 0x84, 0xce,
+       0x5d, 0x76, 0x0f, 0xda, 0xbf, 0x53, 0x3e, 0xdc, 0xdb, 0x24, 0x8b, 0xb3,
+       0x31, 0x7d, 0x3f, 0x31, 0xa1, 0xf6, 0x49, 0x7e, 0x9c, 0xf9, 0x1f, 0x6d,
+       0xe3, 0x77, 0xcb, 0x86, 0xc3, 0xf2, 0x0e, 0xcd, 0xdf, 0x77, 0xa9, 0xfb,
+       0x3c, 0xbc, 0x67, 0x52, 0x2c, 0xff, 0x44, 0xbd, 0x3f, 0x3d, 0xdf, 0xa0,
+       0xea, 0x9f, 0x9e, 0xdf, 0x78, 0x27, 0x87, 0x65, 0xef, 0x66, 0x4c, 0x41,
+       0x96, 0x66, 0x1a, 0x64, 0x79, 0xde, 0xa2, 0x8f, 0x94, 0x6e, 0x5c, 0xfb,
+       0xf6, 0x45, 0x7f, 0xa7, 0xe6, 0xc9, 0x30, 0xd6, 0x6f, 0x71, 0x70, 0x5a,
+       0x2a, 0x83, 0xf4, 0x01, 0xd4, 0xbd, 0x3b, 0xc8, 0x48, 0x03, 0xf0, 0x5f,
+       0xc1, 0xab, 0x38, 0x8c, 0xbd, 0xb6, 0x6a, 0x1f, 0xea, 0xc7, 0xda, 0xcf,
+       0x22, 0x8f, 0x0c, 0xc9, 0xf5, 0x4f, 0x29, 0xba, 0x2a, 0x8a, 0x57, 0xc1,
+       0xb7, 0x45, 0xec, 0x9f, 0xdf, 0x17, 0x85, 0x35, 0x7e, 0x7c, 0x50, 0xf3,
+       0xfc, 0xaf, 0x75, 0xfa, 0x88, 0xec, 0x3b, 0xfe, 0x19, 0xd0, 0xda, 0xe4,
+       0xdf, 0x2d, 0x92, 0xfa, 0xef, 0x36, 0x22, 0xea, 0xdb, 0x95, 0x88, 0xf3,
+       0x08, 0xca, 0x18, 0x7b, 0x7a, 0x44, 0xcd, 0x83, 0xf7, 0xd7, 0x0a, 0xf2,
+       0xab, 0xee, 0x64, 0x04, 0xfe, 0x0f, 0xef, 0x08, 0x35, 0xeb, 0xfe, 0x76,
+       0xe9, 0x75, 0x1c, 0x97, 0x7d, 0xd0, 0xef, 0x79, 0xe0, 0x40, 0xde, 0xab,
+       0x9a, 0x08, 0xd7, 0x8f, 0x19, 0xc8, 0xb2, 0xef, 0x5b, 0x07, 0x67, 0xfd,
+       0x61, 0xe5, 0x03, 0xac, 0xfa, 0xe9, 0xba, 0x7c, 0x5c, 0xf6, 0x97, 0x94,
+       0xbf, 0xae, 0xce, 0xe8, 0xa6, 0xb1, 0x27, 0x87, 0x94, 0x0e, 0x8f, 0x85,
+       0x86, 0xab, 0x69, 0xc9, 0x9f, 0xdc, 0x8d, 0x71, 0x18, 0xfb, 0xca, 0xe8,
+       0xb3, 0xb0, 0xbd, 0xb2, 0xaf, 0xe6, 0x8f, 0x3d, 0x59, 0xe2, 0xfb, 0x24,
+       0xec, 0x22, 0xdf, 0xe7, 0x12, 0x61, 0x15, 0xcd, 0xbf, 0x0e, 0x6d, 0x1b,
+       0x34, 0x6f, 0x79, 0x9f, 0x9e, 0xed, 0xb9, 0xff, 0x3e, 0x6e, 0x4a, 0x73,
+       0x0e, 0xef, 0xd9, 0x26, 0xe8, 0x6f, 0x12, 0x7a, 0x9a, 0xfe, 0xe8, 0xc3,
+       0xb2, 0x52, 0x9e, 0x96, 0xf3, 0xe5, 0x40, 0xce, 0x78, 0xb7, 0x99, 0xb4,
+       0xdf, 0xa9, 0xef, 0x36, 0x67, 0xb0, 0x0e, 0xeb, 0x79, 0x95, 0x5b, 0xf7,
+       0xfd, 0xd1, 0x5f, 0x98, 0xfe, 0x37, 0x80, 0xb7, 0xa9, 0x7b, 0x4a, 0xeb,
+       0xe5, 0x9d, 0xfd, 0x2c, 0x9b, 0x8c, 0xed, 0xfb, 0x77, 0xad, 0x3a, 0xea,
+       0xde, 0xc7, 0xf5, 0xfd, 0xa6, 0xe7, 0xf4, 0x9d, 0x78, 0xf2, 0x73, 0x4c,
+       0xd3, 0x7b, 0x1d, 0xf6, 0x1e, 0xfb, 0x7c, 0x54, 0xaf, 0x1b, 0xd2, 0x45,
+       0x3e, 0x53, 0x0f, 0xad, 0xe8, 0xf3, 0x4e, 0x53, 0x8f, 0x51, 0x7f, 0xbf,
+       0xac, 0xa1, 0x6e, 0x5c, 0xb6, 0xe7, 0xb7, 0x48, 0xc1, 0x5d, 0x6b, 0x96,
+       0x1d, 0xd7, 0xf7, 0xd8, 0x82, 0xbb, 0xd5, 0x2c, 0x0b, 0xee, 0x5b, 0x91,
+       0x5f, 0x8c, 0xe1, 0x21, 0xad, 0x8d, 0xe9, 0xe7, 0xb1, 0xba, 0x6f, 0x74,
+       0x82, 0x3e, 0x23, 0xe8, 0xe3, 0xf6, 0xf0, 0xe5, 0x77, 0xb1, 0xf9, 0xdd,
+       0x14, 0x65, 0xd1, 0xe0, 0x37, 0xdd, 0xf4, 0x7b, 0x80, 0x55, 0xb6, 0xca,
+       0xa4, 0xa2, 0xa7, 0xa0, 0xee, 0x27, 0x64, 0xdd, 0x26, 0x19, 0x32, 0xfd,
+       0xfc, 0xe4, 0xe2, 0x46, 0x39, 0x65, 0xf9, 0xf5, 0x31, 0x69, 0x2e, 0x60,
+       0x1c, 0xbe, 0xdf, 0xec, 0x1b, 0x81, 0xa8, 0xfe, 0x4e, 0xc9, 0x45, 0x9b,
+       0xcf, 0x53, 0xde, 0x0b, 0x85, 0xd5, 0xbb, 0x90, 0x05, 0x15, 0x97, 0x14,
+       0x23, 0xb8, 0x93, 0xc8, 0x6f, 0xd6, 0x45, 0x9e, 0xa9, 0xf2, 0xbb, 0xad,
+       0xdb, 0xd4, 0xbd, 0x11, 0xff, 0x2c, 0x8e, 0x74, 0x75, 0x2b, 0x9d, 0x5c,
+       0xa9, 0x16, 0xc9, 0x53, 0x1d, 0x87, 0x8d, 0xea, 0x38, 0x2c, 0x79, 0x3c,
+       0x02, 0x1e, 0xff, 0x3f, 0xbd, 0x2e, 0xc1, 0x77, 0x5f, 0x3c, 0xeb, 0xe1,
+       0x79, 0xd0, 0xa3, 0x6a, 0x2e, 0xd4, 0xd1, 0x68, 0xfb, 0xde, 0xb0, 0xda,
+       0xbb, 0xea, 0x9b, 0x78, 0xc8, 0x27, 0xbf, 0x71, 0x87, 0x7e, 0x2d, 0xf1,
+       0x5b, 0xf6, 0x11, 0xf5, 0x3d, 0x47, 0xa5, 0xca, 0x75, 0xe5, 0x37, 0xec,
+       0x63, 0x75, 0xf2, 0x18, 0xd6, 0x63, 0x6d, 0x69, 0x93, 0x66, 0x7f, 0xdd,
+       0xf9, 0x2d, 0x48, 0xa5, 0x1a, 0xdc, 0xa3, 0xdc, 0xb2, 0xc2, 0x3d, 0x21,
+       0xbe, 0x5f, 0xab, 0xbe, 0x67, 0xa9, 0xa8, 0xef, 0x43, 0x2c, 0x7e, 0x67,
+       0x09, 0xdb, 0xb1, 0x07, 0xcf, 0x3c, 0x47, 0xdd, 0x8b, 0x14, 0x3a, 0xa7,
+       0x3a, 0x81, 0xf4, 0x21, 0xc9, 0xa9, 0x38, 0x57, 0x0b, 0xf2, 0x93, 0x6a,
+       0xec, 0x62, 0xf5, 0x7e, 0xd9, 0x77, 0xf2, 0x01, 0x7e, 0x43, 0xa3, 0xbe,
+       0xc3, 0xcf, 0xba, 0xa4, 0x31, 0x2e, 0x53, 0x6a, 0xde, 0x85, 0xb5, 0x6f,
+       0x33, 0x7c, 0x39, 0x6a, 0xe3, 0x9a, 0x16, 0xaa, 0x2d, 0xa0, 0x31, 0xa4,
+       0xef, 0x52, 0x12, 0xff, 0x06, 0xf3, 0x6f, 0xe6, 0xfd, 0x3c, 0x8f, 0xe7,
+       0x65, 0xfb, 0x4a, 0xbc, 0x2b, 0x99, 0xd4, 0x7e, 0x31, 0x63, 0x65, 0x8c,
+       0xc7, 0x53, 0xc6, 0xed, 0xd4, 0x04, 0xb4, 0x7f, 0x54, 0x12, 0x3c, 0xcb,
+       0xd5, 0x73, 0x69, 0xa9, 0x9b, 0x0b, 0xef, 0x87, 0xfa, 0xf3, 0xe1, 0x37,
+       0x27, 0xf9, 0x52, 0xfd, 0xf7, 0x32, 0xea, 0x9b, 0x70, 0xf5, 0x7d, 0xca,
+       0x44, 0xf5, 0x41, 0xb9, 0xaf, 0xb4, 0x55, 0x7f, 0x2b, 0x13, 0x93, 0xfb,
+       0xaa, 0x6f, 0x28, 0x9e, 0xe6, 0xd5, 0x77, 0x3e, 0x51, 0xbd, 0x66, 0x71,
+       0xd5, 0xc7, 0xda, 0xf7, 0x3e, 0x76, 0xdd, 0xb7, 0x1f, 0x51, 0x99, 0x58,
+       0xfc, 0x65, 0xdf, 0xfc, 0x3c, 0x2c, 0xfc, 0xee, 0xe3, 0x25, 0x77, 0x5a,
+       0x1e, 0x2b, 0x7b, 0xde, 0x1d, 0x2e, 0xb1, 0xd4, 0x16, 0x39, 0x1f, 0xcf,
+       0x0c, 0x7e, 0xcf, 0x69, 0x0f, 0x55, 0x66, 0x1b, 0xa1, 0xaf, 0x1b, 0x95,
+       0x2d, 0x61, 0x7e, 0x71, 0x96, 0x7b, 0x3e, 0x82, 0x39, 0xda, 0xe6, 0x25,
+       0xf9, 0x54, 0x1b, 0xe3, 0x4c, 0x77, 0xc0, 0x77, 0xfb, 0xb8, 0xeb, 0xeb,
+       0xe5, 0xcf, 0x2d, 0xed, 0x96, 0xcf, 0x55, 0x63, 0xa1, 0xca, 0x0c, 0xef,
+       0xd7, 0xd9, 0x23, 0x65, 0x49, 0xa2, 0x1e, 0xfb, 0x87, 0xbc, 0x24, 0xb6,
+       0xcb, 0xd3, 0xc7, 0x7f, 0xee, 0x5d, 0x72, 0xf0, 0x1e, 0xba, 0xe6, 0xbc,
+       0x1b, 0xc4, 0xd2, 0xe0, 0x37, 0x1f, 0x65, 0xbd, 0xed, 0x90, 0x03, 0xd8,
+       0x6d, 0xec, 0x39, 0xfa, 0x75, 0x97, 0xb4, 0xde, 0x32, 0x8e, 0x5e, 0x23,
+       0x97, 0x56, 0xef, 0xe4, 0xbe, 0x0e, 0xd9, 0xb6, 0x7c, 0xfe, 0xab, 0xd8,
+       0xf3, 0x41, 0x09, 0x7f, 0x01, 0x76, 0xe2, 0x0b, 0x0d, 0x4a, 0xb7, 0xd3,
+       0x9e, 0x01, 0xf3, 0x03, 0xd7, 0x47, 0xd0, 0xcf, 0xfe, 0x36, 0x5f, 0x66,
+       0xa7, 0x45, 0xbe, 0xd8, 0x24, 0x99, 0x36, 0xfa, 0x8d, 0xf2, 0x2b, 0xf4,
+       0x57, 0xfd, 0x3e, 0x4b, 0xc9, 0x9f, 0x71, 0x8f, 0xd7, 0x38, 0x97, 0x64,
+       0xe2, 0x7f, 0xc9, 0x27, 0x65, 0x22, 0xc1, 0xb9, 0x3c, 0x2c, 0x85, 0xf2,
+       0xa3, 0xf8, 0x71, 0x9e, 0xa4, 0xfb, 0x5f, 0xe8, 0xb3, 0xfb, 0x31, 0x29,
+       0xce, 0xa4, 0x65, 0x6a, 0x7e, 0x92, 0xdf, 0xe4, 0x8e, 0xdc, 0xa1, 0xce,
+       0xb4, 0xec, 0x44, 0x32, 0xd4, 0x67, 0x4d, 0xf1, 0xae, 0x82, 0x9a, 0xcf,
+       0x24, 0xe6, 0xf3, 0x4a, 0x1b, 0xef, 0x78, 0x5f, 0x82, 0xfe, 0x35, 0x4e,
+       0x50, 0x0e, 0x6d, 0xb3, 0x2b, 0xc4, 0xfc, 0x5e, 0xf8, 0xab, 0x2c, 0xdb,
+       0x2b, 0xe1, 0xa3, 0xab, 0x7a, 0x1e, 0xe5, 0xfa, 0x6c, 0x55, 0xb5, 0xff,
+       0xaf, 0x68, 0x8b, 0x7a, 0x47, 0x83, 0xb6, 0x41, 0x1d, 0xb6, 0xe5, 0x3c,
+       0x77, 0xc3, 0x4f, 0x0e, 0xe8, 0x82, 0x1c, 0x26, 0xea, 0xf9, 0xdd, 0xbc,
+       0x81, 0xdf, 0x11, 0xe2, 0x4d, 0xf0, 0x8b, 0x3c, 0x0e, 0x6b, 0x1e, 0xff,
+       0x3d, 0xfa, 0x0f, 0xd6, 0xe0, 0x0e, 0x94, 0x99, 0xfa, 0x1b, 0xbc, 0x77,
+       0xc2, 0x77, 0xf2, 0x9c, 0xf5, 0xf7, 0xb7, 0xf9, 0xb2, 0x46, 0x7a, 0x36,
+       0xe3, 0xf9, 0x7b, 0xdb, 0xfd, 0x75, 0xd9, 0x0b, 0x7e, 0xf1, 0x1e, 0x65,
+       0x9f, 0xba, 0x8f, 0x9f, 0x19, 0xdf, 0x0b, 0xd9, 0x09, 0xe6, 0xd5, 0x07,
+       0x19, 0xe3, 0x39, 0x01, 0xeb, 0xd7, 0xf3, 0xc4, 0xb7, 0x7b, 0x61, 0xfa,
+       0xfa, 0x0e, 0xe7, 0x0a, 0x4c, 0xf8, 0x45, 0xf5, 0xfd, 0x0d, 0xf4, 0xe4,
+       0xbb, 0x57, 0xbf, 0xbf, 0xb9, 0xf2, 0x1a, 0x0f, 0xb4, 0xfb, 0x36, 0xca,
+       0x04, 0x4f, 0x5a, 0x75, 0x9b, 0xbd, 0xc0, 0xa7, 0x8c, 0x7f, 0x26, 0x13,
+       0x9f, 0x90, 0x60, 0x1c, 0xef, 0x36, 0xfa, 0x79, 0x43, 0x03, 0x7d, 0xf0,
+       0x69, 0xd5, 0x1d, 0x95, 0x04, 0xef, 0xbc, 0x24, 0x43, 0x7b, 0xd5, 0x7d,
+       0x85, 0x17, 0xd6, 0x7d, 0x43, 0x95, 0x92, 0xa7, 0xd7, 0x64, 0x65, 0xe4,
+       0x47, 0x62, 0x8b, 0x75, 0x35, 0x65, 0x85, 0xfd, 0x4e, 0x72, 0x9e, 0x89,
+       0x07, 0xd4, 0x3c, 0x4d, 0xf8, 0x4d, 0xbc, 0x5b, 0x60, 0x86, 0x2a, 0xf3,
+       0x5c, 0x77, 0xa4, 0x4b, 0x7c, 0x0e, 0xce, 0x37, 0x95, 0x5e, 0xc1, 0xb8,
+       0x2c, 0xa3, 0x6e, 0xe4, 0xfb, 0xb4, 0x3e, 0xff, 0xbc, 0xa7, 0x9d, 0x67,
+       0xf0, 0x79, 0x94, 0x95, 0x97, 0x36, 0xa7, 0xed, 0xe3, 0x4a, 0x0e, 0x1e,
+       0x06, 0xdf, 0xff, 0x04, 0x75, 0x1f, 0x45, 0xca, 0x39, 0xa6, 0x57, 0xd7,
+       0x9d, 0xfc, 0xfe, 0xb0, 0x0c, 0x42, 0x2e, 0x98, 0x7f, 0x58, 0x8a, 0xea,
+       0xee, 0x10, 0xd2, 0x32, 0x9f, 0xa9, 0xeb, 0x1d, 0x6d, 0x4f, 0x49, 0xcb,
+       0x5e, 0xfd, 0xdd, 0x56, 0x20, 0x4f, 0x7b, 0x74, 0xbb, 0xf1, 0x55, 0x5e,
+       0x3d, 0x70, 0x19, 0xde, 0x88, 0xae, 0xe2, 0x0d, 0x7f, 0xac, 0x62, 0x7b,
+       0x80, 0x35, 0xfc, 0x39, 0xf8, 0x58, 0xc3, 0x97, 0xf3, 0x49, 0x89, 0x40,
+       0x8e, 0xc3, 0x6b, 0x72, 0x0c, 0xdc, 0xe3, 0xef, 0x99, 0x29, 0x9e, 0xdb,
+       0x29, 0x3e, 0x53, 0x0e, 0x29, 0xbf, 0x5c, 0xc7, 0xfa, 0xb5, 0xbe, 0xf1,
+       0x97, 0xac, 0xf5, 0x85, 0xf6, 0x00, 0x3f, 0xfc, 0xd3, 0xf6, 0xc1, 0xd7,
+       0xda, 0xd7, 0xf6, 0xc1, 0x35, 0xbf, 0xa1, 0x7d, 0xb0, 0x51, 0x2e, 0xeb,
+       0x65, 0xca, 0x84, 0x3c, 0x71, 0xbd, 0x28, 0x4f, 0x94, 0x23, 0xf2, 0x92,
+       0xfa, 0xb4, 0x91, 0xbe, 0x53, 0xe2, 0xa2, 0xfa, 0x3e, 0x62, 0x1a, 0x3a,
+       0xa8, 0x3d, 0x54, 0x86, 0x5f, 0x5e, 0x5c, 0xba, 0x49, 0xc9, 0xf4, 0xd3,
+       0x35, 0xea, 0xa5, 0x2b, 0xcd, 0x7d, 0xbd, 0xce, 0xcd, 0x6f, 0xd0, 0xb9,
+       0xf9, 0x55, 0x9d, 0xdb, 0xa6, 0xfd, 0xa5, 0x7f, 0x8a, 0xce, 0x8d, 0xd7,
+       0x9d, 0x85, 0x04, 0xe7, 0x20, 0x12, 0xca, 0xf6, 0x36, 0xcb, 0xae, 0xd9,
+       0xb8, 0x8c, 0xcc, 0xec, 0x96, 0x3f, 0x9a, 0x99, 0x56, 0xf7, 0x82, 0xfe,
+       0xca, 0x4d, 0x26, 0xee, 0x0f, 0x79, 0xf2, 0x61, 0xf8, 0xbb, 0x13, 0x9d,
+       0x0d, 0xb2, 0xeb, 0xfd, 0xea, 0x7c, 0xcf, 0xcc, 0x86, 0x3a, 0x84, 0x91,
+       0xe7, 0x9c, 0x6b, 0xbb, 0x56, 0x88, 0x77, 0xc4, 0x1a, 0x65, 0x22, 0xde,
+       0x22, 0xbb, 0x81, 0x9d, 0x0a, 0x57, 0xb9, 0xea, 0x9b, 0xed, 0x8c, 0x3a,
+       0x3f, 0xe9, 0xde, 0xee, 0x8f, 0x0b, 0x3e, 0xb4, 0x9a, 0xf2, 0xe7, 0xb5,
+       0x6e, 0xf5, 0xfd, 0xf1, 0x0b, 0xa5, 0x3f, 0x6f, 0x5b, 0x9f, 0xe7, 0xf3,
+       0x7f, 0x42, 0x9d, 0x38, 0x78, 0x55, 0x7f, 0xdf, 0x26, 0xac, 0xf8, 0x59,
+       0x2c, 0x8f, 0xab, 0x7b, 0x4c, 0x17, 0xc3, 0xe4, 0x97, 0xf2, 0x9b, 0x12,
+       0xd9, 0x30, 0x30, 0xce, 0x2c, 0x90, 0xb4, 0x43, 0x9f, 0x4f, 0xe3, 0x4f,
+       0xe8, 0xff, 0x7d, 0xea, 0x3c, 0x75, 0x05, 0xbc, 0xf1, 0x54, 0xbc, 0x35,
+       0x1f, 0x27, 0xae, 0x5f, 0xbb, 0xb3, 0x7b, 0x39, 0xbe, 0xf7, 0xbf, 0xf1,
+       0xd2, 0xb1, 0x7f, 0x1d, 0x9f, 0xd1, 0x3e, 0xb8, 0x3a, 0xcb, 0xda, 0xec,
+       0xff, 0x50, 0xf8, 0xdf, 0xec, 0x67, 0x4b, 0xc4, 0x76, 0xf6, 0x91, 0xb2,
+       0xf4, 0x6f, 0x57, 0xb1, 0x26, 0xf2, 0xb7, 0x82, 0x75, 0x3a, 0x96, 0x08,
+       0xec, 0x79, 0xa8, 0xeb, 0x6c, 0xbd, 0x1f, 0xc8, 0x3e, 0x62, 0xea, 0x0e,
+       0xc4, 0xda, 0xff, 0xbd, 0x61, 0x4c, 0x25, 0x13, 0xba, 0xab, 0x34, 0x2d,
+       0xe1, 0xb9, 0x31, 0x89, 0x1c, 0x63, 0xfc, 0x3a, 0x23, 0xc5, 0xb8, 0x27,
+       0xf7, 0xb9, 0xeb, 0x7d, 0x93, 0x2e, 0x63, 0x23, 0xed, 0x0f, 0xcb, 0xd0,
+       0xc9, 0x47, 0x25, 0x3a, 0xc7, 0x77, 0xeb, 0xce, 0x2e, 0xa0, 0x8f, 0xb6,
+       0x48, 0x39, 0xce, 0x18, 0x6e, 0x54, 0x9d, 0x05, 0x9f, 0x1f, 0x5f, 0x90,
+       0x22, 0xb0, 0x42, 0x5e, 0xe9, 0x16, 0xa4, 0xab, 0xbe, 0xc4, 0xf4, 0x76,
+       0xee, 0x29, 0xf8, 0x98, 0xa1, 0x89, 0x72, 0x54, 0xdd, 0xc9, 0x39, 0x1f,
+       0x67, 0x5d, 0xf8, 0xef, 0x73, 0xc4, 0x19, 0xd0, 0x1d, 0x63, 0x12, 0x62,
+       0x3e, 0x3c, 0xb7, 0x86, 0x33, 0xa8, 0x13, 0x86, 0xdc, 0xb8, 0x44, 0x4e,
+       0xf9, 0x73, 0xe7, 0x3f, 0x52, 0x32, 0x16, 0x76, 0x4b, 0xf8, 0x18, 0x9f,
+       0xeb, 0xfd, 0x21, 0x62, 0x77, 0xd8, 0x86, 0xb3, 0x9f, 0x45, 0x7f, 0x7c,
+       0x97, 0xd1, 0xdf, 0xc2, 0x22, 0x5f, 0xf9, 0xc7, 0xfe, 0xcf, 0x04, 0xca,
+       0xfe, 0xff, 0x07, 0x3b, 0x97, 0x22, 0x9a, 0xb0, 0x4e, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b06FwRodata[(0x88/4) + 1] = {
-       0x08001c1c, 0x08001c4c, 0x08001c4c, 0x08001c4c, 0x08001c4c, 0x08001c4c,
-       0x08001b74, 0x08001c4c, 0x08001bdc, 0x08001c4c, 0x08001b08, 0x08001c4c,
-       0x08001c4c, 0x08001c4c, 0x08001b14, 0x00000000, 0x08002b58, 0x08002ba8,
-       0x08002bd8, 0x08002c08, 0x08002c38, 0x00000000, 0x080060cc, 0x080060cc,
-       0x080060cc, 0x080060cc, 0x080060cc, 0x08006100, 0x08006100, 0x08006140,
-       0x0800614c, 0x0800614c, 0x080060cc, 0x00000000, 0x00000000 };
+static const u32 bnx2_COM_b06FwRodata[(0x14/4) + 1] = {
+       0x08000f04, 0x08000f4c, 0x08000f80, 0x08000fcc, 0x08001000, 0x00000000
+};
 
 static struct fw_info bnx2_com_fw_06 = {
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x4,
-       .ver_fix                        = 0x3,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x080000b4,
+       .start_addr                     = 0x080000f8,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x7d54,
+       .text_len                       = 0x4eac,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_COM_b06FwText,
        .gz_text_len                    = sizeof(bnx2_COM_b06FwText),
 
-       .data_addr                      = 0x08007e00,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_COM_b06FwData,
 
-       .sbss_addr                      = 0x08007e00,
-       .sbss_len                       = 0x60,
+       .sbss_addr                      = 0x08004ee0,
+       .sbss_len                       = 0x38,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08007e60,
-       .bss_len                        = 0x88,
+       .bss_addr                       = 0x08004f18,
+       .bss_len                        = 0xbc,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08007d58,
-       .rodata_len                     = 0x88,
+       .rodata_addr                    = 0x08004eac,
+       .rodata_len                     = 0x14,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_COM_b06FwRodata,
 };
 
+static u8 bnx2_CP_b06FwText[] = {
+       0x9d, 0xbc, 0x0d, 0x78, 0x13, 0xe7, 0x99, 0x2e, 0x7c, 0xcf, 0x48, 0xb2,
+       0x65, 0x5b, 0xb6, 0xc7, 0xb6, 0x0c, 0x22, 0x65, 0x41, 0x83, 0x47, 0x20,
+       0x62, 0x27, 0x1d, 0x81, 0x49, 0x94, 0xac, 0x36, 0xa8, 0xc6, 0x01, 0x93,
+       0x90, 0xc6, 0x34, 0xb4, 0x75, 0x7a, 0xd2, 0x8d, 0x62, 0x0c, 0x21, 0x84,
+       0x10, 0x67, 0x9b, 0x9e, 0xe3, 0x7c, 0x5f, 0xce, 0x5a, 0x35, 0x06, 0x0c,
+       0xc8, 0x96, 0x31, 0x0e, 0x90, 0xfd, 0x7a, 0x9d, 0x18, 0x6c, 0x30, 0x49,
+       0x65, 0x8b, 0x34, 0x74, 0x97, 0xf4, 0xa3, 0x45, 0x07, 0xf2, 0xe3, 0xfc,
+       0x35, 0xa4, 0xed, 0x76, 0xdb, 0x3d, 0x39, 0x89, 0x0f, 0x25, 0x84, 0xb4,
+       0xdd, 0xfc, 0xb4, 0xdd, 0x2d, 0x69, 0x9b, 0xcc, 0x77, 0x3f, 0x23, 0x09,
+       0x0c, 0x4d, 0x7f, 0xf6, 0xf3, 0x75, 0xcd, 0x65, 0xcd, 0xcc, 0xfb, 0xf3,
+       0xbc, 0xcf, 0xfb, 0x3c, 0xf7, 0x73, 0x3f, 0xef, 0xbc, 0x33, 0xb3, 0x80,
+       0x62, 0xe4, 0xfe, 0x4a, 0x79, 0x5c, 0x5d, 0xdf, 0xbe, 0x1a, 0x8b, 0xae,
+       0x36, 0xe5, 0xdc, 0xe9, 0x82, 0x13, 0x7f, 0xe1, 0x9f, 0xff, 0x2f, 0x2d,
+       0x38, 0xe5, 0xcf, 0x01, 0x68, 0xf9, 0x7e, 0xe5, 0x80, 0x5b, 0x8d, 0x3c,
+       0xf3, 0x5f, 0x1a, 0x0c, 0xb8, 0x1d, 0x91, 0x9e, 0xd6, 0xd5, 0x06, 0x10,
+       0x4d, 0xd5, 0xfa, 0x97, 0xe0, 0x23, 0x2b, 0xee, 0x75, 0x42, 0xae, 0xff,
+       0x55, 0xe4, 0xf7, 0x9d, 0xdf, 0xb9, 0x56, 0x7f, 0x7f, 0xc8, 0x01, 0xb7,
+       0x16, 0xe9, 0x80, 0x36, 0x17, 0xee, 0x99, 0xac, 0xf3, 0xf5, 0x79, 0xdb,
+       0x15, 0x94, 0xe5, 0xdb, 0x3a, 0x67, 0x7d, 0x67, 0x9e, 0x2f, 0x56, 0x14,
+       0xd1, 0x70, 0x3c, 0x8d, 0xe6, 0xba, 0xde, 0x4e, 0xab, 0xd4, 0x08, 0xc1,
+       0x6d, 0x18, 0x2d, 0xbd, 0x8a, 0x27, 0xbc, 0x7e, 0x11, 0x3c, 0x85, 0x06,
+       0xe2, 0x57, 0x44, 0xd0, 0x7c, 0xe5, 0x58, 0x71, 0xdc, 0x19, 0x71, 0xa3,
+       0x29, 0xed, 0x8e, 0x7f, 0x2a, 0x62, 0x60, 0x59, 0xfa, 0xfa, 0x62, 0x94,
+       0xb9, 0xd1, 0x9d, 0xfe, 0xa8, 0x28, 0xdb, 0x5e, 0x73, 0xee, 0xff, 0xec,
+       0xaa, 0xec, 0xff, 0x69, 0x31, 0x67, 0x04, 0xd8, 0x9c, 0xb0, 0xac, 0x82,
+       0xc8, 0x6d, 0xb7, 0xa9, 0x11, 0xc3, 0x77, 0x10, 0x8b, 0xd1, 0xaa, 0xe1,
+       0xe1, 0x2d, 0xf5, 0xbf, 0x54, 0x4e, 0x0c, 0xb2, 0xe1, 0x51, 0x07, 0xa2,
+       0xda, 0x33, 0xfc, 0x3f, 0x6b, 0x56, 0x4b, 0xd8, 0xc0, 0xde, 0xd1, 0xf3,
+       0xbc, 0xee, 0xb4, 0xaf, 0x6d, 0xda, 0x33, 0x6b, 0xd6, 0xed, 0xe1, 0x67,
+       0xf0, 0xe8, 0xa8, 0xfc, 0xbe, 0x1b, 0x9d, 0x75, 0x0a, 0x26, 0x6f, 0x5b,
+       0x0b, 0x87, 0x61, 0xa0, 0x7b, 0x8f, 0xe2, 0xec, 0xaa, 0x53, 0x11, 0xf5,
+       0xea, 0xc1, 0x18, 0x95, 0xef, 0x34, 0x10, 0x2b, 0x8c, 0x84, 0x9d, 0xef,
+       0x24, 0x22, 0x9a, 0xc3, 0xb0, 0xac, 0x60, 0x68, 0x3a, 0x1c, 0x15, 0x96,
+       0xf5, 0xb4, 0xe9, 0x81, 0xff, 0x8b, 0xcf, 0x21, 0x3e, 0xdc, 0x0c, 0xd5,
+       0x78, 0x0e, 0x5d, 0xc3, 0xcf, 0xe1, 0xb1, 0x5d, 0xc5, 0x98, 0xac, 0xe2,
+       0x78, 0x93, 0x3e, 0x7c, 0x67, 0x9e, 0xf4, 0x2d, 0x72, 0xd4, 0xf1, 0x70,
+       0x63, 0xd2, 0xf1, 0x06, 0xff, 0x4b, 0x99, 0xf3, 0xd6, 0xe4, 0xf4, 0x8b,
+       0x65, 0x36, 0xb3, 0x4c, 0xf7, 0x65, 0x65, 0xe2, 0xc3, 0x11, 0xbc, 0x94,
+       0x50, 0xb0, 0x3e, 0x54, 0x86, 0x68, 0x85, 0x8c, 0xd7, 0xb2, 0x46, 0xcd,
+       0xb3, 0xd6, 0xa4, 0x26, 0x7d, 0x4d, 0xe0, 0x65, 0xde, 0xdb, 0x12, 0x3a,
+       0x63, 0x65, 0xbc, 0xd2, 0x5e, 0x3b, 0x6d, 0x67, 0x25, 0xaf, 0x3b, 0x91,
+       0x4c, 0x20, 0x56, 0x16, 0xb9, 0x8d, 0xe7, 0xba, 0xf9, 0xae, 0xe2, 0x76,
+       0xbf, 0x97, 0x70, 0x7f, 0xb1, 0xd4, 0x50, 0x1f, 0x2c, 0xa7, 0x01, 0xbd,
+       0x42, 0x99, 0x8f, 0x9a, 0x6b, 0xe1, 0x32, 0x1e, 0x10, 0x5b, 0xe3, 0xb8,
+       0x7e, 0x68, 0x61, 0x7a, 0xbe, 0xbe, 0xb4, 0xeb, 0xc6, 0x96, 0xa4, 0x65,
+       0x6d, 0x33, 0xa3, 0xd7, 0x15, 0xd1, 0x20, 0x4e, 0x26, 0x9a, 0xe1, 0x8e,
+       0x04, 0xfc, 0xe7, 0x10, 0xc6, 0x92, 0xb4, 0x17, 0xcf, 0x26, 0xe0, 0x6c,
+       0x98, 0xe7, 0x45, 0x57, 0x3a, 0x82, 0x1b, 0xd3, 0x26, 0x1a, 0xd3, 0x7f,
+       0xde, 0xb2, 0x6e, 0x4e, 0xfa, 0x39, 0x86, 0x8f, 0xac, 0xec, 0x18, 0x64,
+       0x7c, 0xd9, 0xff, 0xdd, 0xc9, 0x2b, 0xb0, 0x9d, 0x73, 0xb4, 0x95, 0xf3,
+       0xb7, 0x3c, 0x94, 0x89, 0x16, 0x41, 0x37, 0xcf, 0x21, 0x82, 0xa5, 0x69,
+       0x83, 0x73, 0x1a, 0xc1, 0x92, 0x64, 0x8d, 0x36, 0x8c, 0xf9, 0x88, 0xfa,
+       0xb2, 0x36, 0xbd, 0x83, 0xe3, 0x6d, 0x0d, 0x34, 0xa3, 0x94, 0x36, 0x92,
+       0x5a, 0x14, 0x46, 0x03, 0xfb, 0x5f, 0xf1, 0x17, 0xf4, 0x7f, 0x2b, 0xfb,
+       0x7f, 0x97, 0xfd, 0x67, 0xec, 0xfe, 0xe1, 0xbc, 0x89, 0xe7, 0x6e, 0xda,
+       0xe3, 0xf6, 0x94, 0xd3, 0xb9, 0x3c, 0xe9, 0xc5, 0xb6, 0x94, 0x49, 0x9b,
+       0x93, 0x5b, 0x3e, 0x6c, 0x19, 0x9c, 0x89, 0xad, 0x83, 0xba, 0xef, 0x79,
+       0xfe, 0xde, 0x34, 0x72, 0x05, 0x36, 0x0f, 0x2a, 0xd8, 0x6f, 0x5c, 0x81,
+       0x2e, 0xfe, 0xde, 0x3b, 0x38, 0x0b, 0x8f, 0x0e, 0x3a, 0x10, 0xae, 0xba,
+       0x74, 0x1c, 0x93, 0x8e, 0x2b, 0x10, 0x1f, 0xf1, 0xa3, 0x2b, 0xf1, 0xa2,
+       0xad, 0xc3, 0xd2, 0xc8, 0xff, 0x9b, 0xf7, 0x63, 0xfa, 0x8e, 0x1f, 0xab,
+       0x13, 0x1a, 0xba, 0x92, 0x0e, 0xb1, 0x4b, 0xfe, 0xfd, 0x92, 0xf7, 0x34,
+       0x6c, 0x4a, 0xe7, 0xeb, 0x8b, 0x9f, 0xf9, 0xd1, 0x90, 0x98, 0xa0, 0x9f,
+       0xd4, 0xd3, 0x47, 0x4c, 0x7c, 0x37, 0x5d, 0x87, 0x7f, 0x4a, 0x07, 0xf1,
+       0x8f, 0xd4, 0xc3, 0xb7, 0xd2, 0x7e, 0x1c, 0x49, 0xcf, 0xc4, 0x53, 0x69,
+       0x1f, 0xbe, 0x49, 0xfd, 0x3f, 0x99, 0x6e, 0xa6, 0xed, 0x6a, 0x38, 0x9c,
+       0x16, 0xfd, 0x15, 0x50, 0xde, 0x62, 0x6c, 0x1a, 0xac, 0x09, 0x9e, 0xa4,
+       0x6d, 0xfc, 0xa3, 0x79, 0x13, 0x32, 0x95, 0xf5, 0xb6, 0x4d, 0x6d, 0xe3,
+       0xf5, 0xed, 0x83, 0x35, 0xd1, 0x2b, 0x15, 0xcb, 0x52, 0x43, 0xb5, 0xe1,
+       0x13, 0xaa, 0x8a, 0x49, 0xaf, 0xee, 0xcf, 0xa8, 0xba, 0x3f, 0x0a, 0x17,
+       0x12, 0xb4, 0xed, 0x78, 0xb5, 0x3e, 0x14, 0xa7, 0x4d, 0x78, 0x8d, 0x7d,
+       0x40, 0x99, 0xee, 0x8f, 0xab, 0x6e, 0x6c, 0x4d, 0xea, 0x7b, 0xe3, 0xaa,
+       0x07, 0xf1, 0x74, 0x31, 0xfe, 0x6d, 0x50, 0xef, 0x89, 0xab, 0x9f, 0x45,
+       0xbc, 0xd2, 0xb2, 0xbe, 0x19, 0x42, 0xfb, 0xf4, 0x08, 0xa2, 0xd5, 0x11,
+       0xc4, 0x66, 0x45, 0xbc, 0x48, 0x26, 0x81, 0x77, 0x7b, 0x0d, 0xdf, 0xbf,
+       0x28, 0xcd, 0xf8, 0x6a, 0xb3, 0xee, 0xf7, 0xab, 0xb5, 0xf1, 0x61, 0x75,
+       0x11, 0x5d, 0x12, 0x7e, 0x5f, 0x64, 0x19, 0x3a, 0xec, 0x6b, 0x0a, 0x34,
+       0xc3, 0x83, 0x4d, 0xc9, 0xeb, 0x10, 0xf3, 0xd6, 0xb4, 0xec, 0x54, 0x6b,
+       0xce, 0x9b, 0xaa, 0x3e, 0xd1, 0xac, 0x5a, 0xd6, 0x07, 0x0b, 0xdf, 0xb5,
+       0xfc, 0xd3, 0x2c, 0x6b, 0xc1, 0x42, 0xe9, 0xd3, 0x8f, 0x8a, 0x88, 0x89,
+       0x95, 0xf6, 0x1c, 0x14, 0xe3, 0xec, 0x60, 0x25, 0xfb, 0xd0, 0xf0, 0xcf,
+       0xd7, 0xea, 0xc1, 0xb5, 0x6a, 0x31, 0xde, 0x1a, 0x29, 0xc6, 0x69, 0x8e,
+       0xe7, 0x97, 0x83, 0x3e, 0xfc, 0x7a, 0xd0, 0xb2, 0xbe, 0x68, 0xfe, 0x35,
+       0x06, 0x2a, 0xfb, 0xf1, 0x4f, 0xe3, 0x5e, 0xfc, 0x1b, 0x75, 0x7b, 0x26,
+       0x11, 0x7d, 0xa0, 0x0a, 0x7a, 0x74, 0x5c, 0x39, 0x79, 0x67, 0x19, 0x6a,
+       0x9b, 0xcb, 0x14, 0xbd, 0x69, 0x07, 0x74, 0xdf, 0x95, 0x8a, 0x17, 0xe7,
+       0x52, 0x1a, 0x7e, 0x9a, 0xaa, 0x09, 0xff, 0x80, 0x7d, 0xfe, 0x87, 0xf9,
+       0xb4, 0x95, 0x99, 0x26, 0x7a, 0x13, 0x1d, 0x51, 0xcf, 0x49, 0xea, 0x39,
+       0x49, 0x3d, 0x27, 0xa9, 0x67, 0xca, 0x70, 0x24, 0x49, 0x3d, 0x53, 0x77,
+       0xdf, 0xa4, 0x4d, 0x3c, 0x99, 0xa4, 0x8e, 0x93, 0x32, 0x47, 0x61, 0xfa,
+       0xe7, 0xa7, 0xf0, 0xf7, 0xf6, 0xdc, 0xbd, 0x6c, 0xfd, 0x37, 0xaf, 0x8c,
+       0xe9, 0xfe, 0x69, 0x59, 0xfc, 0x91, 0xb1, 0xbd, 0x64, 0xc5, 0x34, 0x19,
+       0x97, 0x8c, 0xcf, 0xd6, 0x9f, 0xbf, 0x5d, 0xf9, 0xaa, 0x82, 0x62, 0xcb,
+       0xda, 0x65, 0xe6, 0xee, 0x7b, 0xf3, 0xe3, 0xfb, 0x8c, 0x92, 0xb5, 0x8b,
+       0x7f, 0x72, 0x53, 0xdf, 0xc1, 0xa8, 0xba, 0x88, 0xe7, 0x7a, 0x3c, 0x8a,
+       0x9b, 0x0a, 0x2f, 0x3d, 0xbf, 0xb6, 0x5a, 0xe6, 0xc3, 0x7f, 0xe1, 0x9c,
+       0xf6, 0x64, 0xf7, 0xf7, 0x45, 0x9e, 0xcb, 0x58, 0x04, 0x53, 0xc5, 0x06,
+       0xbc, 0xb4, 0x97, 0x45, 0xb9, 0x7b, 0x88, 0xab, 0x91, 0x76, 0x34, 0xd7,
+       0xef, 0xb5, 0xfb, 0x28, 0xe8, 0x13, 0xbb, 0x57, 0xf0, 0xee, 0x75, 0x0a,
+       0x4e, 0x84, 0x0c, 0xda, 0xcc, 0x10, 0xfd, 0x1a, 0x28, 0xec, 0x83, 0xdb,
+       0x13, 0x89, 0x20, 0xd1, 0x0b, 0x77, 0x51, 0x24, 0x8c, 0xf9, 0xbd, 0x35,
+       0xeb, 0xce, 0x42, 0x0f, 0xf6, 0x2a, 0x7a, 0x33, 0x50, 0x6b, 0x8e, 0x51,
+       0x8f, 0x57, 0x2a, 0xba, 0xbf, 0x40, 0x81, 0x5b, 0x61, 0xb9, 0x40, 0x6a,
+       0x08, 0x5b, 0xd3, 0xf2, 0x3b, 0x0c, 0x23, 0xf5, 0xeb, 0x7c, 0x5f, 0xb4,
+       0xeb, 0x76, 0xda, 0xf5, 0x59, 0x8e, 0x5d, 0xf7, 0x13, 0x1f, 0xdd, 0xae,
+       0xc8, 0x3a, 0x1c, 0x48, 0xc0, 0x5d, 0x10, 0xd9, 0x80, 0xe7, 0x12, 0x1f,
+       0x57, 0xe7, 0xcb, 0x29, 0x2c, 0xe7, 0x4f, 0x4d, 0x95, 0xe5, 0x0d, 0x2b,
+       0xea, 0xcd, 0xca, 0x52, 0xdc, 0x37, 0x84, 0x1d, 0x49, 0xa9, 0x1b, 0xb1,
+       0xeb, 0x3a, 0xd9, 0x47, 0x77, 0xa2, 0xa6, 0xe9, 0x66, 0x45, 0x0f, 0x3f,
+       0x8e, 0xda, 0xe8, 0x3b, 0x9c, 0xc3, 0x2e, 0xe8, 0xe7, 0xd7, 0x21, 0x2b,
+       0xcb, 0xbc, 0x54, 0x56, 0x8e, 0xc5, 0x29, 0x28, 0xb7, 0x27, 0xe1, 0xf1,
+       0x19, 0x55, 0x39, 0x5f, 0x84, 0x72, 0x0b, 0xe7, 0x4f, 0x35, 0xfc, 0xb8,
+       0x85, 0x36, 0xb4, 0x61, 0x97, 0x85, 0x4d, 0xa1, 0x4a, 0xfa, 0x5b, 0x33,
+       0xca, 0x88, 0x87, 0x1b, 0x35, 0x44, 0xcb, 0x23, 0x61, 0xe5, 0xd6, 0xf4,
+       0xce, 0x9c, 0xfe, 0x9f, 0xae, 0xa4, 0x7c, 0x4a, 0x63, 0xf2, 0xf2, 0xeb,
+       0x1f, 0xe5, 0xc7, 0x77, 0xd9, 0xf5, 0xb9, 0x05, 0x9f, 0x5c, 0xbe, 0x56,
+       0x1b, 0x81, 0xc2, 0x78, 0x51, 0x44, 0xfd, 0xea, 0x8c, 0xd2, 0xd1, 0xa0,
+       0xcb, 0xbe, 0xe6, 0xc0, 0x90, 0x33, 0xea, 0x73, 0xe0, 0xf7, 0x56, 0x74,
+       0x95, 0x5c, 0x2b, 0x46, 0xac, 0xb9, 0xd6, 0xe7, 0x44, 0x6d, 0x78, 0x33,
+       0xfd, 0x6d, 0x72, 0x55, 0x03, 0xef, 0x05, 0xcc, 0x93, 0xa8, 0xf1, 0x6f,
+       0x86, 0xfc, 0xfe, 0x90, 0x36, 0xd2, 0x20, 0x75, 0x59, 0x46, 0x6c, 0x4e,
+       0xd7, 0x4e, 0xc2, 0x8b, 0xcd, 0xb4, 0xbf, 0xc2, 0x88, 0x6e, 0x2e, 0x73,
+       0x38, 0x71, 0x88, 0x38, 0xec, 0x30, 0x7a, 0x50, 0xc8, 0x31, 0x32, 0x3e,
+       0xe2, 0xf1, 0x04, 0xf0, 0x62, 0xbf, 0x85, 0x86, 0x90, 0x07, 0x4b, 0x6c,
+       0xdb, 0x3c, 0xaa, 0xdc, 0x98, 0xfc, 0xd8, 0x1a, 0x72, 0x16, 0x45, 0xd5,
+       0x48, 0xc0, 0x77, 0x9a, 0xd1, 0xbc, 0x20, 0x52, 0xab, 0x39, 0x11, 0x57,
+       0x9a, 0xd2, 0xdd, 0xca, 0xf2, 0x74, 0x8f, 0xb2, 0xc4, 0xc6, 0x9c, 0xa3,
+       0xca, 0xd2, 0xb4, 0x07, 0xa9, 0x7e, 0x05, 0x3b, 0x42, 0x94, 0xab, 0x3a,
+       0x6b, 0xc7, 0xe9, 0x7e, 0x95, 0x18, 0xf9, 0x2e, 0x31, 0x52, 0x0f, 0x83,
+       0x7d, 0x3f, 0x9d, 0xa8, 0xc4, 0x51, 0x62, 0xe1, 0x4f, 0x52, 0xe5, 0x2a,
+       0x8a, 0xaf, 0xc0, 0x8f, 0x47, 0xca, 0x30, 0x36, 0x38, 0x8b, 0xbf, 0xeb,
+       0xf0, 0xca, 0x88, 0x65, 0x75, 0x9b, 0x96, 0x75, 0xc0, 0x3c, 0xaa, 0x34,
+       0xb0, 0xcf, 0xa8, 0x33, 0x1e, 0x2d, 0x8c, 0x04, 0xcc, 0xad, 0xec, 0xd3,
+       0x11, 0x89, 0x2b, 0x51, 0xf6, 0x77, 0x23, 0xfb, 0x5b, 0x9a, 0xeb, 0x2f,
+       0xdb, 0xaf, 0xc8, 0x22, 0xf5, 0xf2, 0x75, 0xc2, 0xac, 0x03, 0x1c, 0x4c,
+       0x04, 0x82, 0xf9, 0x7a, 0x4b, 0x59, 0xe7, 0xc6, 0x0b, 0x75, 0x80, 0xe1,
+       0x44, 0x90, 0x73, 0x2a, 0xb6, 0xee, 0x67, 0xec, 0xf9, 0x1a, 0x9c, 0x46,
+       0x3d, 0x5a, 0x87, 0x85, 0x47, 0x84, 0xd5, 0xec, 0x3c, 0x49, 0xfc, 0x74,
+       0xdb, 0x31, 0x6b, 0xd2, 0x21, 0x71, 0x34, 0x88, 0x5e, 0xfa, 0x75, 0x57,
+       0x52, 0x6c, 0xbc, 0xfe, 0xcb, 0x89, 0x80, 0x82, 0x6f, 0x04, 0x32, 0xcd,
+       0xa5, 0x28, 0xc7, 0xba, 0x90, 0xd8, 0xa6, 0xf9, 0xe5, 0xe7, 0x0c, 0x3d,
+       0xbc, 0x42, 0xe1, 0x9c, 0x05, 0xf4, 0xa6, 0xa5, 0x0a, 0x10, 0x18, 0x03,
+       0xce, 0xa4, 0xca, 0xb1, 0xda, 0x74, 0x40, 0xad, 0x08, 0xa2, 0x27, 0x3d,
+       0x15, 0xd7, 0x4d, 0xe2, 0xb4, 0xb4, 0x17, 0xa4, 0x5f, 0x97, 0x60, 0x99,
+       0x96, 0xb5, 0x69, 0x37, 0xdb, 0x76, 0x07, 0x32, 0x41, 0x95, 0xf1, 0xea,
+       0x10, 0x2f, 0x9c, 0x64, 0x5c, 0x6a, 0x30, 0x5c, 0x68, 0xd3, 0xca, 0xd1,
+       0x60, 0xfe, 0xd6, 0x5a, 0xb6, 0x4a, 0xee, 0x5d, 0xc4, 0xf7, 0x42, 0xf6,
+       0xfb, 0xb6, 0xa1, 0xfb, 0x47, 0x79, 0x92, 0x49, 0x65, 0xaf, 0xc7, 0x19,
+       0x73, 0x36, 0xb1, 0xdd, 0x2d, 0x6c, 0x77, 0xad, 0xa6, 0x47, 0xe3, 0x17,
+       0xca, 0x65, 0x82, 0x0e, 0xe8, 0x9a, 0x94, 0x6d, 0x64, 0xbb, 0xab, 0xd9,
+       0x6e, 0x8f, 0x26, 0xf2, 0xfd, 0xd6, 0x5a, 0xbb, 0x4a, 0xee, 0x65, 0xed,
+       0x23, 0xdb, 0x6e, 0xbd, 0xb4, 0x6b, 0x8e, 0xe6, 0xfa, 0x3a, 0x91, 0x40,
+       0xbf, 0x23, 0xc2, 0x18, 0x59, 0x1f, 0xf0, 0x77, 0x31, 0x5e, 0x36, 0x32,
+       0x76, 0x64, 0x6d, 0x62, 0x6a, 0xbc, 0x42, 0xfc, 0x62, 0x19, 0xb9, 0x26,
+       0xe5, 0xc4, 0xd6, 0x26, 0xa9, 0x67, 0x89, 0x2f, 0x3e, 0xea, 0x57, 0xb0,
+       0xc5, 0x89, 0xc3, 0x09, 0xe2, 0x3f, 0xbe, 0x46, 0xbb, 0xf3, 0xa3, 0x39,
+       0x5d, 0x83, 0xb6, 0x5d, 0x8c, 0x63, 0x66, 0x05, 0x6d, 0x3d, 0x6b, 0x6f,
+       0xcb, 0xd8, 0xf6, 0xa4, 0xdd, 0x76, 0x5c, 0x69, 0x4e, 0xd7, 0x6a, 0x15,
+       0x8c, 0x99, 0xc7, 0x2f, 0x60, 0xe7, 0xec, 0x68, 0x71, 0x24, 0xd0, 0xb4,
+       0x9e, 0x93, 0xe4, 0x66, 0x7c, 0xfb, 0xce, 0xbc, 0x6e, 0xda, 0x45, 0x0f,
+       0xed, 0x30, 0x3b, 0xbf, 0x4d, 0x62, 0x70, 0xc4, 0x38, 0xa8, 0x35, 0x58,
+       0xbb, 0x4b, 0xfe, 0x93, 0x6b, 0xd4, 0x3f, 0xca, 0x6b, 0x35, 0x58, 0x3d,
+       0xfc, 0x0d, 0xda, 0x99, 0xee, 0x13, 0x3b, 0xec, 0xba, 0x20, 0x97, 0xc8,
+       0x24, 0xb2, 0x89, 0x4c, 0xff, 0x37, 0xcb, 0xcd, 0xa4, 0x7e, 0x04, 0x1b,
+       0x2b, 0x29, 0xcf, 0x36, 0xf2, 0x99, 0xa3, 0xca, 0x67, 0x29, 0x4f, 0xc6,
+       0xe5, 0xc5, 0x63, 0x49, 0x91, 0x47, 0x89, 0xce, 0x88, 0xcc, 0xc4, 0xf9,
+       0x64, 0x20, 0xfe, 0x34, 0x44, 0xb6, 0x6e, 0xa5, 0x45, 0xea, 0x27, 0x7b,
+       0x78, 0x2f, 0x2f, 0x23, 0xb4, 0x72, 0x5b, 0xb6, 0xac, 0x4c, 0xb7, 0x72,
+       0xae, 0x5d, 0xc6, 0xfd, 0xa5, 0x28, 0x73, 0xd2, 0xd6, 0xa4, 0xed, 0x9f,
+       0x59, 0x51, 0x6d, 0x13, 0xaf, 0x79, 0x39, 0x4f, 0x6e, 0xc6, 0x75, 0x3d,
+       0x78, 0x8b, 0x43, 0x69, 0xf6, 0x48, 0xbc, 0xa6, 0x7d, 0xa6, 0x52, 0x4e,
+       0x3c, 0x93, 0x58, 0xba, 0xb4, 0xc4, 0xb8, 0x1a, 0xdf, 0x18, 0xf1, 0x61,
+       0x84, 0x73, 0xfb, 0x62, 0x42, 0xe2, 0xeb, 0x4c, 0x3c, 0x91, 0xf2, 0xe0,
+       0x85, 0x84, 0x1f, 0x8f, 0x33, 0xfe, 0x4c, 0x24, 0x0c, 0x1c, 0x4a, 0x79,
+       0xf1, 0x3c, 0xed, 0x79, 0x34, 0xe5, 0xa3, 0xbd, 0xd4, 0x61, 0x38, 0xd5,
+       0x6c, 0x8f, 0xe1, 0xd9, 0xc4, 0xab, 0x32, 0xd6, 0xa0, 0x8c, 0x75, 0x8b,
+       0x3d, 0xd6, 0x7c, 0x9c, 0x9f, 0x79, 0x61, 0x1e, 0x4e, 0x25, 0x6c, 0x1c,
+       0xe8, 0x59, 0xe6, 0x90, 0x79, 0xa0, 0xcd, 0x0e, 0x08, 0x16, 0xe8, 0xfd,
+       0x71, 0x58, 0xd8, 0x6f, 0xce, 0xa0, 0xff, 0xf7, 0x50, 0x5e, 0xea, 0x94,
+       0xe3, 0x87, 0xab, 0x2c, 0x5a, 0x1a, 0x09, 0xc4, 0x7a, 0xa9, 0x77, 0x67,
+       0x44, 0xf4, 0x90, 0xd5, 0xfb, 0x8a, 0xf4, 0x51, 0x45, 0xb8, 0xda, 0x95,
+       0x03, 0x71, 0xab, 0xc4, 0x10, 0x7d, 0x07, 0x88, 0xb3, 0xc0, 0xfc, 0xfd,
+       0x4e, 0x8e, 0x6f, 0x25, 0xc7, 0x6c, 0xa2, 0xc0, 0xa8, 0xd5, 0x2a, 0x29,
+       0xfb, 0xf1, 0x3f, 0x88, 0x81, 0xa2, 0xa3, 0x35, 0xb9, 0xf9, 0x2a, 0x77,
+       0x50, 0x5e, 0x3f, 0x90, 0x9f, 0x17, 0xcb, 0xda, 0x69, 0xe6, 0xe7, 0xa6,
+       0x1a, 0xfe, 0x4a, 0x3d, 0x3e, 0x44, 0x8b, 0x18, 0x49, 0x54, 0x21, 0xae,
+       0xa9, 0xb9, 0xb6, 0xa3, 0x4a, 0x01, 0xf3, 0x07, 0x8c, 0x8b, 0xef, 0x97,
+       0x22, 0xea, 0x94, 0xfa, 0x88, 0x16, 0x44, 0x02, 0xc1, 0xb9, 0xea, 0x54,
+       0x9b, 0x11, 0x1c, 0x90, 0xbe, 0xe2, 0x94, 0xf5, 0x52, 0x2c, 0x18, 0x49,
+       0xe4, 0x71, 0xe3, 0x3f, 0x53, 0xcf, 0x4b, 0x1f, 0x9b, 0xaa, 0x53, 0x91,
+       0x53, 0xf4, 0xaa, 0xa2, 0x75, 0x50, 0xf4, 0xe7, 0xc4, 0x4a, 0x73, 0x51,
+       0x4e, 0xe6, 0x99, 0x68, 0x4b, 0xa8, 0xd8, 0x30, 0xc8, 0xbe, 0x52, 0x0a,
+       0x36, 0x87, 0x96, 0x60, 0xc8, 0x6b, 0xd3, 0x45, 0xb4, 0x26, 0x1a, 0x69,
+       0x63, 0xc4, 0x99, 0x71, 0x3b, 0x7e, 0xda, 0xfe, 0x33, 0x9b, 0x3e, 0xb1,
+       0x2c, 0xfd, 0x20, 0xd6, 0x26, 0x03, 0xfe, 0x93, 0x78, 0x10, 0x6d, 0x69,
+       0x17, 0x62, 0xc3, 0x1e, 0x74, 0xb2, 0x6f, 0xb5, 0x4f, 0xfc, 0x49, 0x43,
+       0xe7, 0xe8, 0x89, 0x17, 0x54, 0xda, 0x67, 0xe7, 0xa8, 0x97, 0xc7, 0x34,
+       0x1e, 0x6e, 0x3c, 0xc4, 0xe3, 0x28, 0xe7, 0xbf, 0x83, 0x18, 0x9c, 0x4e,
+       0x98, 0xb8, 0x9f, 0x32, 0x8d, 0x27, 0xea, 0xb1, 0x91, 0xf2, 0x8d, 0x25,
+       0x1c, 0xf0, 0x4f, 0x0b, 0xe3, 0x3e, 0xea, 0xf2, 0xc9, 0x44, 0x58, 0x79,
+       0x80, 0xff, 0x0f, 0x51, 0x26, 0xc9, 0x47, 0xd6, 0xd1, 0x0e, 0xa2, 0xd3,
+       0x68, 0x27, 0x6a, 0xad, 0xc3, 0x9e, 0x07, 0x88, 0x7f, 0x5c, 0x3e, 0x57,
+       0xba, 0x16, 0x43, 0x7e, 0xbe, 0x80, 0xa1, 0x14, 0x62, 0xee, 0x48, 0x5d,
+       0x63, 0x41, 0x6f, 0xeb, 0x86, 0xc2, 0x48, 0xfb, 0x43, 0x3f, 0xad, 0x9f,
+       0x85, 0x93, 0x9c, 0x13, 0xa7, 0x6d, 0xe3, 0x51, 0xc5, 0x65, 0x18, 0xb6,
+       0x2f, 0xab, 0xe3, 0xed, 0xb9, 0xbc, 0x4a, 0x97, 0x38, 0xc6, 0x3e, 0x44,
+       0x6f, 0xa2, 0x0b, 0xd1, 0xc3, 0x71, 0x6b, 0xc8, 0xf6, 0x77, 0xf1, 0x39,
+       0x27, 0x75, 0xf4, 0x5d, 0xc6, 0x6f, 0xd1, 0x85, 0x94, 0xdb, 0xca, 0xb6,
+       0x44, 0x1e, 0x3b, 0x16, 0xfa, 0xfe, 0xd0, 0x76, 0xa6, 0xca, 0x53, 0x87,
+       0xed, 0x7b, 0x0c, 0xec, 0xd8, 0x53, 0x4b, 0xbb, 0xfb, 0xa5, 0xe5, 0xaf,
+       0x18, 0x60, 0xdd, 0xa9, 0xb2, 0x08, 0x2f, 0x40, 0xae, 0x5d, 0x69, 0x73,
+       0x13, 0xef, 0x1d, 0xa6, 0xad, 0x49, 0xbb, 0x96, 0xb5, 0xe5, 0x42, 0xdc,
+       0x28, 0x88, 0x16, 0x31, 0x6e, 0x1c, 0x4a, 0x04, 0xc2, 0x2f, 0xd8, 0xb1,
+       0xcd, 0x49, 0xdb, 0x90, 0xf9, 0xef, 0xb6, 0xe7, 0x7e, 0xd9, 0x85, 0xb9,
+       0x9f, 0xbc, 0xc0, 0x91, 0xfa, 0x93, 0x53, 0x7d, 0x2a, 0x3b, 0xef, 0xce,
+       0x3e, 0xbd, 0xc7, 0xb6, 0xd3, 0x94, 0xe0, 0x9f, 0x03, 0x8e, 0x01, 0xce,
+       0xb3, 0x79, 0x15, 0xc7, 0x5f, 0xc9, 0x78, 0x52, 0xc0, 0x83, 0x79, 0xe4,
+       0xf0, 0xa7, 0x50, 0x3c, 0x90, 0xb1, 0x8a, 0xf8, 0xbb, 0x29, 0x14, 0x08,
+       0x17, 0x29, 0x37, 0xe0, 0xee, 0x61, 0x07, 0x0a, 0x06, 0x14, 0x3c, 0x6b,
+       0xd6, 0xe5, 0xec, 0x43, 0xe6, 0xfb, 0x2a, 0xdb, 0x3e, 0xe6, 0x8c, 0xcb,
+       0x7c, 0xcb, 0x1c, 0x7b, 0xe0, 0xeb, 0x53, 0xe0, 0x21, 0x6e, 0x94, 0x18,
+       0x32, 0xd7, 0x1a, 0xca, 0xfb, 0x64, 0xae, 0x49, 0x1b, 0x77, 0x87, 0xb1,
+       0x91, 0xf6, 0x50, 0xba, 0xfb, 0x7a, 0xdc, 0xc7, 0x72, 0x1b, 0x78, 0x6f,
+       0xc3, 0x68, 0x25, 0x0f, 0x2f, 0x8f, 0x69, 0x3c, 0xea, 0x71, 0xef, 0x70,
+       0x0d, 0xa2, 0x95, 0x7a, 0xd0, 0xaf, 0x3a, 0x50, 0x39, 0x20, 0x3a, 0x55,
+       0xb1, 0x72, 0x81, 0x02, 0xf3, 0xea, 0x42, 0xa8, 0x73, 0x3f, 0xc9, 0x37,
+       0xff, 0x9c, 0xac, 0x3f, 0x9a, 0x32, 0x87, 0x6e, 0x8e, 0xfd, 0x9f, 0xed,
+       0x39, 0x9c, 0x33, 0x2e, 0x7d, 0x48, 0x2c, 0xb5, 0xe7, 0xf1, 0x4f, 0xf8,
+       0xfe, 0x73, 0x9c, 0x8f, 0x2e, 0x96, 0xf9, 0xc3, 0xf9, 0xc5, 0x85, 0xf9,
+       0x9d, 0xca, 0x49, 0x25, 0xae, 0xeb, 0xe1, 0x21, 0x9b, 0xc3, 0xf8, 0x99,
+       0xcf, 0xe9, 0x71, 0xd1, 0x39, 0x39, 0x8b, 0x5b, 0x35, 0xe0, 0x2f, 0x30,
+       0xee, 0xc0, 0x3d, 0x9c, 0xa7, 0x03, 0x09, 0x75, 0xa9, 0x0b, 0xea, 0x4c,
+       0x17, 0x13, 0xdb, 0x11, 0x53, 0xc7, 0xba, 0x61, 0xe6, 0x4a, 0xc3, 0xa5,
+       0xe8, 0xd2, 0x14, 0xf7, 0xf6, 0xba, 0x45, 0x92, 0xf3, 0xfa, 0xcb, 0x0d,
+       0xa8, 0x25, 0x8c, 0xef, 0x3b, 0x34, 0x38, 0x0b, 0x0c, 0x45, 0x4d, 0xd4,
+       0x35, 0x22, 0x5e, 0x01, 0x67, 0x99, 0x01, 0x85, 0x39, 0x2d, 0x7a, 0x35,
+       0x08, 0xb6, 0x44, 0x0b, 0x8c, 0x07, 0x71, 0x4f, 0x12, 0x56, 0x71, 0x84,
+       0xf9, 0x4e, 0xc4, 0x20, 0x87, 0x0d, 0xf8, 0x0a, 0x94, 0x07, 0xb1, 0x9a,
+       0xbc, 0x61, 0xcd, 0xb0, 0xc8, 0xe1, 0x21, 0x9f, 0x30, 0xfc, 0xad, 0x60,
+       0x8e, 0xdd, 0xac, 0x07, 0x27, 0x99, 0x67, 0xae, 0xa6, 0xee, 0x47, 0x12,
+       0x0f, 0xa2, 0x21, 0x79, 0xdc, 0xf2, 0x90, 0x27, 0x16, 0x18, 0x35, 0xe7,
+       0xbb, 0x10, 0xa3, 0x0f, 0x0b, 0xff, 0x69, 0xc3, 0x43, 0xf4, 0xbf, 0x74,
+       0x42, 0x7d, 0x86, 0xec, 0x01, 0x1d, 0xa3, 0xeb, 0x71, 0xff, 0xe8, 0x4c,
+       0xfa, 0xea, 0x06, 0xfa, 0x2a, 0xb9, 0x50, 0xff, 0x0d, 0xb8, 0x6f, 0xf8,
+       0x06, 0xdc, 0xbb, 0xcb, 0x08, 0x6e, 0xa0, 0xae, 0xd7, 0x0c, 0x33, 0x10,
+       0x4e, 0x93, 0x76, 0xf3, 0xba, 0x12, 0x3e, 0x48, 0x5d, 0xe4, 0xf4, 0x94,
+       0x41, 0x9e, 0xa3, 0xfc, 0xb3, 0xc5, 0x4b, 0xf1, 0x82, 0x7a, 0xc5, 0xbf,
+       0xb7, 0xee, 0xfb, 0xcc, 0xbd, 0x45, 0x76, 0x44, 0x67, 0x18, 0xaf, 0x5a,
+       0x8f, 0x6a, 0x0a, 0x0a, 0x22, 0x88, 0xcf, 0xae, 0x7f, 0xd9, 0x7a, 0x6c,
+       0x95, 0x5c, 0xbf, 0xd5, 0x89, 0x62, 0x95, 0xd7, 0xa4, 0xcd, 0x1d, 0x32,
+       0x47, 0x44, 0xda, 0x4f, 0x6a, 0x33, 0x63, 0xf5, 0x5d, 0x28, 0x4f, 0xde,
+       0x47, 0xac, 0x7d, 0x3a, 0xe1, 0x45, 0x4f, 0x32, 0xcb, 0x9d, 0x6e, 0x4f,
+       0x0b, 0x67, 0x72, 0xa3, 0xb8, 0x57, 0xe2, 0x46, 0x14, 0xeb, 0xf9, 0xbb,
+       0xa8, 0x57, 0x6f, 0x8e, 0x83, 0xc9, 0xbc, 0xd1, 0xc8, 0xb9, 0xa0, 0xbd,
+       0xf6, 0x3a, 0x50, 0x64, 0x34, 0x65, 0x6d, 0xb5, 0x77, 0x85, 0x8d, 0x4b,
+       0x65, 0xbd, 0xdd, 0x36, 0x2e, 0x95, 0xb2, 0x9e, 0x60, 0x92, 0xa7, 0x77,
+       0x15, 0xed, 0x75, 0x26, 0x4a, 0x7a, 0x5b, 0x70, 0x2f, 0xe7, 0x78, 0x2d,
+       0x79, 0xf6, 0x09, 0xb3, 0x3c, 0xc7, 0x3f, 0x9b, 0x70, 0x77, 0x32, 0x8a,
+       0xd6, 0x64, 0x4d, 0xf4, 0xb4, 0xac, 0x25, 0xb9, 0xb2, 0xd8, 0x19, 0xad,
+       0x16, 0x5d, 0x3c, 0x97, 0xc3, 0x08, 0xbd, 0x29, 0xcb, 0xd9, 0x74, 0xcd,
+       0xaf, 0xe4, 0x65, 0xef, 0x46, 0x8c, 0xf9, 0xc5, 0xec, 0x48, 0x33, 0xac,
+       0xa4, 0xc8, 0x1d, 0xb7, 0x7c, 0xcc, 0x19, 0x3d, 0x11, 0xbd, 0x7d, 0xb1,
+       0xc3, 0xe8, 0xf8, 0xb1, 0x12, 0xc4, 0xad, 0x94, 0xa1, 0xa4, 0xb7, 0x13,
+       0xaf, 0x84, 0x74, 0xdf, 0xb7, 0x15, 0xfd, 0xfc, 0x06, 0xfc, 0x18, 0x3f,
+       0xe7, 0xb5, 0x82, 0xde, 0x09, 0x3c, 0x96, 0x7e, 0x1d, 0x67, 0x29, 0xab,
+       0xda, 0xfb, 0xb1, 0xb5, 0xcc, 0x20, 0x18, 0x14, 0xbb, 0x95, 0xb7, 0xd3,
+       0x53, 0x6d, 0xf1, 0x06, 0xac, 0xde, 0x25, 0xf6, 0xa7, 0x07, 0xe3, 0xa0,
+       0x7c, 0x66, 0x99, 0x60, 0x9c, 0xc4, 0x1f, 0xca, 0xdf, 0x4c, 0xd9, 0x2c,
+       0xfa, 0x07, 0xed, 0xc0, 0x1e, 0xc3, 0x43, 0x36, 0x0e, 0x3a, 0xfb, 0xe4,
+       0xc8, 0xeb, 0x39, 0xa2, 0xb4, 0x8e, 0x5e, 0x53, 0x8c, 0x62, 0x5f, 0xce,
+       0x0f, 0xb2, 0x6b, 0x0a, 0x17, 0xeb, 0xfe, 0xd2, 0x1a, 0xf1, 0x5e, 0x5a,
+       0xb7, 0x8c, 0x39, 0x56, 0x39, 0xc7, 0xf3, 0x5e, 0x6f, 0xdc, 0x2a, 0xce,
+       0x8e, 0xa5, 0xe9, 0x55, 0x45, 0x6c, 0x32, 0x48, 0xee, 0xde, 0x89, 0xab,
+       0x42, 0x7a, 0xcb, 0xb7, 0x15, 0x29, 0xab, 0x87, 0x37, 0x28, 0xf9, 0x7e,
+       0x7e, 0x84, 0xd3, 0x23, 0xd2, 0x87, 0xf4, 0x35, 0xc1, 0x9c, 0xeb, 0x52,
+       0x7f, 0x4a, 0xd9, 0xf3, 0xa9, 0x9b, 0x43, 0xe4, 0x75, 0x2b, 0x38, 0xcc,
+       0x92, 0x5e, 0x19, 0x93, 0xa9, 0xdc, 0x3b, 0x2a, 0xf3, 0xba, 0x40, 0x59,
+       0x4f, 0x2c, 0x29, 0xea, 0xad, 0x57, 0xee, 0x21, 0x96, 0x14, 0xee, 0xac,
+       0x51, 0xee, 0xb6, 0x6d, 0xbe, 0x0a, 0x23, 0xfd, 0xd7, 0x28, 0x6d, 0xc3,
+       0xa2, 0x03, 0x37, 0xc7, 0x3e, 0x8d, 0x63, 0xf7, 0xa2, 0x8f, 0xfe, 0xfb,
+       0x4a, 0x6f, 0x9d, 0x72, 0x1f, 0x7d, 0xa3, 0x73, 0x97, 0x8a, 0xc9, 0x2a,
+       0x85, 0x78, 0x47, 0xfe, 0x6b, 0xf8, 0x94, 0xd6, 0xe1, 0xef, 0x3b, 0x25,
+       0xbe, 0x64, 0x70, 0x03, 0x5a, 0x79, 0x6f, 0xa9, 0xe9, 0x42, 0x46, 0xab,
+       0xd5, 0x34, 0xac, 0xc0, 0xea, 0xe4, 0x2a, 0xb4, 0x25, 0x8b, 0xc9, 0x73,
+       0x65, 0xbc, 0x79, 0xb9, 0xf3, 0xf3, 0xf8, 0x20, 0x5a, 0x92, 0x88, 0xcf,
+       0x88, 0x04, 0x3a, 0x66, 0x38, 0xe8, 0xd2, 0xc5, 0x75, 0xca, 0xfd, 0xe9,
+       0x1a, 0x65, 0xcd, 0xae, 0x72, 0x64, 0xb1, 0xe7, 0x61, 0x34, 0xed, 0xa9,
+       0x57, 0xee, 0xde, 0x53, 0x85, 0x49, 0xcd, 0xb2, 0x9c, 0xa1, 0x7a, 0xa5,
+       0x75, 0x8f, 0x65, 0xdd, 0x64, 0x46, 0x9b, 0x8a, 0xc9, 0x77, 0xb7, 0xb1,
+       0xbd, 0xd6, 0x51, 0xe9, 0xe7, 0xf2, 0x76, 0x4d, 0x65, 0xe3, 0x9e, 0x87,
+       0xb1, 0x82, 0x65, 0x5f, 0x09, 0x45, 0x5b, 0x4a, 0x59, 0x56, 0x74, 0xd6,
+       0x3a, 0xfa, 0x19, 0xf6, 0x21, 0xe5, 0x17, 0x4c, 0x69, 0x67, 0x31, 0xaf,
+       0x49, 0x5b, 0x59, 0xdd, 0x89, 0xde, 0x1e, 0xcf, 0xea, 0x2d, 0x2c, 0x7a,
+       0x5b, 0x4e, 0x5d, 0xba, 0x7a, 0x7d, 0x3c, 0x5c, 0xf4, 0x75, 0x1f, 0xd6,
+       0xa4, 0x65, 0x4c, 0x33, 0x89, 0x03, 0xcd, 0xb4, 0xdb, 0x76, 0xb4, 0x52,
+       0xaf, 0x71, 0x2d, 0x6b, 0x9f, 0x17, 0x7d, 0x4b, 0xf7, 0x4f, 0x72, 0xec,
+       0xad, 0x49, 0xd1, 0x4b, 0x33, 0xcb, 0xdb, 0xf7, 0xe9, 0xdb, 0x53, 0xcb,
+       0x5c, 0x3a, 0x57, 0xfb, 0x13, 0xc2, 0x27, 0x0a, 0xc8, 0x7d, 0x0a, 0xd8,
+       0x5e, 0x96, 0x2b, 0x8a, 0xbd, 0x38, 0x68, 0x2f, 0xcf, 0x98, 0xc5, 0xd8,
+       0xe4, 0x95, 0x31, 0x66, 0xf5, 0x0c, 0x15, 0x58, 0xc7, 0x7b, 0x2e, 0xde,
+       0x2b, 0x0c, 0x15, 0xe2, 0x2d, 0x5b, 0x57, 0x59, 0x3e, 0x98, 0xf7, 0xf3,
+       0xa1, 0x0b, 0xfd, 0x1c, 0xab, 0xce, 0xda, 0xd8, 0x26, 0x57, 0x96, 0x33,
+       0xe6, 0xb9, 0x8d, 0x65, 0x0d, 0x98, 0x79, 0x6e, 0x23, 0x71, 0xee, 0x53,
+       0xc2, 0x15, 0x6c, 0x1e, 0xd6, 0x96, 0xeb, 0xb7, 0xcb, 0x0c, 0xd0, 0x4f,
+       0x85, 0xfb, 0x45, 0x94, 0xb6, 0x3d, 0xa7, 0x68, 0xab, 0x92, 0x8b, 0x01,
+       0x1b, 0x79, 0xbf, 0x94, 0xf7, 0x5f, 0x0b, 0xb9, 0x70, 0xd5, 0x34, 0xe9,
+       0xfb, 0x06, 0x74, 0xec, 0x8a, 0xa2, 0x7c, 0x61, 0x00, 0x93, 0xf6, 0x7a,
+       0x59, 0x9e, 0xa7, 0xbb, 0x70, 0xdf, 0xae, 0x8f, 0xad, 0x32, 0x9b, 0x3b,
+       0x1a, 0xb1, 0x71, 0x45, 0xc5, 0x8e, 0x45, 0xc2, 0xd7, 0x5d, 0x8c, 0x57,
+       0xe4, 0xce, 0x92, 0x0b, 0xb8, 0x4a, 0xc8, 0xb9, 0x85, 0x73, 0x06, 0x32,
+       0xb7, 0xab, 0xd0, 0xb4, 0x88, 0x70, 0xcf, 0x99, 0x36, 0xe7, 0x16, 0xee,
+       0xfd, 0xcd, 0xe4, 0xd1, 0x29, 0xdc, 0xfb, 0x02, 0x4f, 0x61, 0xae, 0xd6,
+       0x8c, 0x44, 0xaf, 0x07, 0xee, 0x88, 0xde, 0xbc, 0x59, 0xe9, 0xc4, 0xf2,
+       0x90, 0x61, 0xca, 0x1a, 0xc0, 0xf5, 0x8a, 0x1e, 0x3c, 0x87, 0x20, 0xe3,
+       0xc7, 0x8f, 0x30, 0x32, 0xf8, 0x0f, 0x2e, 0xf1, 0x8b, 0xcd, 0xe9, 0x8b,
+       0xf2, 0xdc, 0x4d, 0x79, 0xdc, 0x59, 0x79, 0xcc, 0x73, 0x54, 0xe4, 0xb3,
+       0xf5, 0x2e, 0xe2, 0xf0, 0x7f, 0xb7, 0xed, 0x76, 0x89, 0x9d, 0x4b, 0xfc,
+       0x77, 0xc6, 0x93, 0x70, 0x71, 0x5e, 0xcf, 0x9d, 0xc4, 0xab, 0x0f, 0x17,
+       0x16, 0x21, 0x44, 0x7b, 0xaf, 0x30, 0x3a, 0x98, 0xcf, 0x7f, 0x6c, 0xc5,
+       0x9d, 0xa4, 0xdf, 0x06, 0xb4, 0xa2, 0x48, 0x94, 0xb2, 0x35, 0x2a, 0x37,
+       0x0d, 0x8f, 0xb3, 0x9f, 0x0e, 0xe6, 0x29, 0x1e, 0x3c, 0x40, 0x5c, 0x79,
+       0x80, 0xfe, 0xf4, 0x00, 0x63, 0xf3, 0x03, 0xa3, 0xff, 0x8b, 0xd7, 0xa7,
+       0xd9, 0xbf, 0x37, 0x27, 0xf3, 0xf6, 0xe5, 0x64, 0x9c, 0x13, 0xfd, 0x6e,
+       0x21, 0x16, 0x48, 0x9c, 0x03, 0x65, 0xb2, 0x70, 0xda, 0x2c, 0xa4, 0xae,
+       0xf5, 0x60, 0x06, 0x09, 0xd7, 0xc5, 0x3c, 0x35, 0x1f, 0x2b, 0x65, 0x1e,
+       0x5d, 0xb8, 0x87, 0x32, 0x06, 0x43, 0xbf, 0xb1, 0x50, 0x21, 0x58, 0x74,
+       0xf9, 0xfd, 0xec, 0xbc, 0x1e, 0xbf, 0xc0, 0x59, 0x15, 0xc9, 0x91, 0xe8,
+       0xef, 0xfd, 0x36, 0x07, 0x7b, 0x8d, 0x3e, 0xd9, 0xb6, 0xeb, 0xc4, 0x7c,
+       0x31, 0x95, 0x35, 0xa3, 0x51, 0x6c, 0xe2, 0xb8, 0x57, 0x0f, 0x3f, 0x9a,
+       0xd3, 0x4b, 0x7e, 0xbc, 0xe2, 0xd3, 0x1e, 0xda, 0x74, 0x36, 0xb7, 0x6a,
+       0x1d, 0x15, 0x2e, 0x5e, 0xc9, 0xff, 0xc2, 0xc5, 0xc5, 0x7f, 0x84, 0x97,
+       0x4f, 0xe3, 0x7f, 0x27, 0x39, 0xa7, 0x70, 0xe9, 0x3a, 0xf4, 0xd0, 0x8f,
+       0x0a, 0x03, 0x75, 0xd8, 0x3a, 0x7a, 0xf9, 0x1c, 0x5d, 0x2e, 0x8f, 0x3d,
+       0x07, 0xcc, 0xc3, 0x5c, 0x82, 0xad, 0x7e, 0xbf, 0x2a, 0x7d, 0x5b, 0x68,
+       0x37, 0x6f, 0xc8, 0x72, 0xa7, 0x4a, 0xb9, 0x36, 0x95, 0x9f, 0xe7, 0xdb,
+       0x99, 0x7a, 0x4d, 0x2d, 0x40, 0x71, 0x9e, 0x37, 0x78, 0x73, 0xb9, 0x0e,
+       0xf3, 0x9b, 0xa4, 0xe8, 0x4b, 0xc6, 0x90, 0xcd, 0x5f, 0xc5, 0x5e, 0x2e,
+       0xc5, 0x83, 0xf8, 0xb4, 0x22, 0x43, 0x6c, 0x25, 0x48, 0x7f, 0xd6, 0xc3,
+       0x4d, 0x0c, 0x35, 0x67, 0x13, 0x88, 0x39, 0x22, 0x4d, 0x8d, 0x6b, 0x12,
+       0x73, 0xb5, 0x67, 0x72, 0xf9, 0xf1, 0x7e, 0xc6, 0x1e, 0xd5, 0x90, 0xb5,
+       0x19, 0xda, 0xc3, 0xb0, 0xe8, 0xa7, 0x43, 0xb9, 0x98, 0x0b, 0x47, 0xc9,
+       0x15, 0x19, 0x57, 0x0d, 0xc9, 0x91, 0x1a, 0x95, 0xa5, 0xc3, 0x52, 0x87,
+       0xf6, 0x70, 0x19, 0x67, 0xcc, 0x8e, 0xb7, 0x0c, 0x9e, 0x01, 0xe1, 0x8a,
+       0x3a, 0x36, 0x90, 0x9b, 0x94, 0x0c, 0xf8, 0x69, 0xef, 0x95, 0x28, 0xde,
+       0x1d, 0xc1, 0xfa, 0x51, 0x0d, 0x45, 0xbb, 0x2d, 0x6b, 0x6e, 0xa8, 0x1b,
+       0x6b, 0xd3, 0xcb, 0x0b, 0x24, 0x9f, 0x73, 0xf6, 0x11, 0x2b, 0x88, 0x2b,
+       0xeb, 0x92, 0x0a, 0x6e, 0x24, 0x07, 0x88, 0xa2, 0x99, 0xdc, 0x5d, 0xf0,
+       0xc5, 0xea, 0x9c, 0x1d, 0x71, 0xd1, 0x4e, 0x56, 0xf1, 0x7e, 0x0b, 0xb1,
+       0xa7, 0x85, 0x58, 0x62, 0x59, 0x1f, 0x5e, 0x8b, 0xce, 0x92, 0xc8, 0x1d,
+       0xc4, 0xa0, 0x1a, 0xe6, 0x0f, 0xc2, 0x39, 0xae, 0x45, 0x1b, 0xb1, 0xbb,
+       0xb0, 0xcf, 0xce, 0xf1, 0xa8, 0x47, 0xc6, 0xd5, 0x34, 0xe3, 0x32, 0x65,
+       0x7f, 0x9e, 0x7c, 0xbd, 0x83, 0x7e, 0x54, 0xde, 0xb7, 0x81, 0xf1, 0xd9,
+       0x83, 0xb2, 0x81, 0x6b, 0xb0, 0x91, 0xd8, 0x7e, 0xdf, 0x2e, 0x3f, 0x52,
+       0x8b, 0x6e, 0xa0, 0x7c, 0x0f, 0x62, 0x7d, 0xd2, 0x90, 0xbc, 0x2e, 0x1a,
+       0x5c, 0xf4, 0x20, 0xfb, 0xa5, 0x7d, 0xec, 0x92, 0x1c, 0xb1, 0x04, 0x4b,
+       0x9a, 0x81, 0x60, 0x9f, 0x60, 0x8e, 0x8c, 0xff, 0x36, 0x59, 0xcf, 0x82,
+       0xd1, 0x37, 0x75, 0x3e, 0xa6, 0x72, 0x39, 0x59, 0x1b, 0x6c, 0xc6, 0x7c,
+       0xc6, 0x2f, 0xb1, 0x21, 0x8d, 0x79, 0x6f, 0x91, 0x62, 0xf8, 0xf6, 0xd3,
+       0x17, 0x25, 0x17, 0xbb, 0xae, 0x2f, 0x1f, 0xaf, 0xf5, 0xcc, 0x62, 0x47,
+       0x27, 0xb1, 0x42, 0x6f, 0xff, 0xad, 0xa2, 0xaf, 0x3b, 0xa5, 0xfc, 0x18,
+       0x07, 0xc7, 0x5e, 0xc7, 0xd0, 0x98, 0x5b, 0x19, 0x1d, 0x93, 0xbe, 0x26,
+       0xd0, 0x9b, 0xfe, 0x73, 0x7d, 0x4d, 0x5d, 0x13, 0x5a, 0x74, 0xc9, 0x3a,
+       0xd2, 0x8d, 0xb9, 0xdc, 0x75, 0xe9, 0x25, 0x9c, 0x5e, 0xe6, 0x44, 0x6c,
+       0xcf, 0x8b, 0xee, 0xe4, 0xc5, 0xb5, 0x8a, 0xfe, 0xc4, 0x76, 0xdb, 0x07,
+       0x9b, 0xd3, 0x62, 0x93, 0xcc, 0xef, 0xcc, 0x39, 0xf6, 0xb3, 0x1b, 0x59,
+       0x5f, 0x58, 0xb3, 0xab, 0xd7, 0xbe, 0x77, 0xd0, 0xfc, 0x2b, 0x64, 0xec,
+       0x6b, 0x8b, 0xe9, 0x7f, 0x8c, 0x93, 0xc4, 0xbd, 0x60, 0xc8, 0x87, 0xc2,
+       0x0a, 0x59, 0x5b, 0xba, 0xb8, 0x1e, 0xb1, 0x61, 0x17, 0x69, 0x84, 0x8d,
+       0x2b, 0x0d, 0xc4, 0xb8, 0x1a, 0xce, 0x77, 0x16, 0x4b, 0xd6, 0xd3, 0x86,
+       0x6e, 0x11, 0x1b, 0x72, 0x65, 0x6d, 0xe8, 0x0f, 0xd7, 0x3c, 0x54, 0x90,
+       0xaf, 0x6a, 0x65, 0x76, 0x2e, 0xda, 0xa8, 0xdc, 0x9a, 0xb3, 0xab, 0xcf,
+       0xa6, 0xbf, 0x53, 0x90, 0xcb, 0x91, 0x2e, 0x2b, 0xff, 0x49, 0x3a, 0xb8,
+       0xe6, 0x2f, 0xd0, 0x81, 0x60, 0xbe, 0xe4, 0x31, 0xa2, 0x83, 0x99, 0x53,
+       0xfc, 0xf2, 0x93, 0xf4, 0x50, 0x9b, 0xd3, 0xc3, 0x62, 0x62, 0x48, 0x25,
+       0x71, 0x4f, 0x38, 0x4b, 0x00, 0x4f, 0x6a, 0x79, 0x3d, 0x38, 0x73, 0x7a,
+       0xd0, 0xff, 0x40, 0x0f, 0xf7, 0x13, 0x5f, 0x4b, 0xd9, 0x56, 0x31, 0x8f,
+       0x77, 0xa9, 0x87, 0x8d, 0xc3, 0x8b, 0xf1, 0x00, 0x7d, 0x69, 0x83, 0xbd,
+       0x5e, 0x23, 0xcf, 0xef, 0x5c, 0x97, 0xe8, 0x66, 0x25, 0xe5, 0xf7, 0x17,
+       0xa8, 0x98, 0x41, 0x1d, 0xf8, 0x6c, 0x3c, 0x95, 0x3e, 0x1a, 0x95, 0xdb,
+       0x87, 0x05, 0xe3, 0x3e, 0xa6, 0x0e, 0x3a, 0x18, 0x07, 0xfe, 0x54, 0x9e,
+       0x21, 0xfd, 0x7f, 0x7c, 0x41, 0x57, 0x7f, 0xbc, 0xdc, 0x8f, 0xa9, 0x03,
+       0x79, 0x26, 0x22, 0x6b, 0xec, 0xf2, 0x7c, 0x44, 0xf4, 0x61, 0x4c, 0xd1,
+       0x83, 0x65, 0x1d, 0x31, 0xe7, 0x21, 0x56, 0xa9, 0xf7, 0x4b, 0x1c, 0xed,
+       0x27, 0xa6, 0x38, 0x98, 0xb7, 0x17, 0x44, 0xa2, 0x14, 0x5b, 0xbd, 0x81,
+       0x4c, 0xa7, 0xce, 0x81, 0x4e, 0x9c, 0x31, 0x8d, 0x9e, 0xb5, 0xf8, 0x2b,
+       0x74, 0x79, 0x2d, 0x1c, 0x60, 0x3b, 0x9b, 0x92, 0x45, 0x58, 0x57, 0x47,
+       0xd3, 0x5c, 0xe9, 0xc1, 0xce, 0x64, 0xbc, 0x85, 0xd0, 0xc2, 0xd8, 0x74,
+       0xe6, 0xf6, 0x44, 0x40, 0x6f, 0xde, 0x40, 0xbe, 0xb6, 0xbc, 0xd7, 0x0d,
+       0xbf, 0x92, 0x8d, 0xcf, 0x03, 0xaa, 0xac, 0x7f, 0x5e, 0xc9, 0xb1, 0x77,
+       0xdb, 0x79, 0xac, 0x7f, 0x9a, 0xf4, 0xe3, 0x47, 0x3c, 0x2d, 0x75, 0xa9,
+       0xb3, 0xb9, 0x0a, 0x96, 0xcf, 0xd5, 0xe3, 0x51, 0xc5, 0xb2, 0x16, 0x84,
+       0x9c, 0xf6, 0xfd, 0xed, 0xe9, 0xda, 0x96, 0xdb, 0xd4, 0xd7, 0xad, 0xec,
+       0x9a, 0xab, 0xae, 0x45, 0x99, 0x0c, 0x1d, 0xff, 0xa3, 0xcf, 0x1d, 0x82,
+       0x90, 0xe7, 0x41, 0x6e, 0x63, 0x25, 0x0e, 0xe5, 0xd6, 0x1d, 0x5d, 0x91,
+       0xc3, 0x5f, 0x3e, 0x60, 0x48, 0xbe, 0x26, 0x7a, 0x92, 0xfe, 0xc4, 0x9e,
+       0x1e, 0x28, 0x14, 0x1c, 0xed, 0x4a, 0x2f, 0xe4, 0x3c, 0xfe, 0x87, 0x35,
+       0xea, 0x9d, 0x5a, 0x76, 0x89, 0x9a, 0x7d, 0x8e, 0x20, 0x65, 0xf3, 0xe5,
+       0xe6, 0x10, 0x57, 0x1a, 0x30, 0x7c, 0x49, 0x9b, 0x92, 0x6f, 0xe7, 0xdb,
+       0xec, 0x2d, 0x14, 0x5e, 0x55, 0x81, 0x42, 0xe2, 0xe3, 0x6f, 0xac, 0x83,
+       0x97, 0xb4, 0xb7, 0xd1, 0x95, 0x6d, 0x6f, 0x0f, 0xcb, 0x48, 0xd9, 0x02,
+       0xd6, 0x79, 0x37, 0xc7, 0x7f, 0xf3, 0x65, 0x3e, 0x77, 0x59, 0x19, 0x66,
+       0x78, 0xc6, 0x5b, 0xd6, 0xfe, 0x4b, 0xca, 0x7c, 0xda, 0x79, 0x69, 0x19,
+       0x27, 0x66, 0x1b, 0xaf, 0x5b, 0xc7, 0x2f, 0x29, 0x33, 0x70, 0x59, 0x99,
+       0x6b, 0x31, 0x56, 0xf7, 0xb8, 0x35, 0x94, 0x9d, 0x9b, 0x0c, 0x5d, 0xd0,
+       0x3d, 0x23, 0xe2, 0xfe, 0xd2, 0x75, 0xf3, 0x74, 0xf2, 0x4d, 0x79, 0x16,
+       0xe5, 0x46, 0x26, 0x3b, 0x37, 0x71, 0x99, 0x1b, 0xd7, 0x82, 0xfc, 0xdc,
+       0x3c, 0x90, 0xab, 0x9f, 0x6f, 0x37, 0x56, 0x70, 0x69, 0xbb, 0xf9, 0xeb,
+       0x8e, 0xcb, 0xe4, 0x9e, 0xb8, 0xac, 0x5c, 0x51, 0xe1, 0x27, 0xd7, 0xfb,
+       0x81, 0xe3, 0xd2, 0xeb, 0xff, 0x43, 0xbd, 0xf4, 0xfc, 0x9a, 0xdc, 0x79,
+       0x5e, 0xff, 0xd6, 0x65, 0xf7, 0x1d, 0x97, 0x9d, 0x3f, 0xa3, 0x7e, 0x72,
+       0x3f, 0xab, 0x2e, 0xeb, 0xc7, 0x5e, 0x83, 0xc7, 0x73, 0x17, 0x70, 0x03,
+       0x8d, 0x05, 0x08, 0x98, 0x4e, 0x05, 0x7e, 0xe2, 0x87, 0xff, 0xf9, 0xcb,
+       0xd6, 0xe2, 0x1b, 0x2f, 0xe0, 0xc7, 0x25, 0x5c, 0x35, 0x56, 0x18, 0x91,
+       0x38, 0x28, 0x3c, 0x55, 0xf8, 0xe2, 0x27, 0xf1, 0xef, 0xb2, 0x58, 0x51,
+       0xa4, 0x1e, 0xfe, 0xb1, 0x99, 0xfe, 0xb7, 0x12, 0xb2, 0x1e, 0xfb, 0x7b,
+       0x72, 0x2e, 0xc3, 0x77, 0x08, 0x33, 0xfd, 0x3f, 0x4d, 0x95, 0xb8, 0x51,
+       0xe6, 0xc1, 0x8d, 0x89, 0x4f, 0xae, 0xa7, 0x46, 0xa0, 0x2c, 0xab, 0xf7,
+       0x31, 0xaf, 0x84, 0xf3, 0xa6, 0x79, 0x98, 0xf2, 0xd7, 0x2c, 0x79, 0xae,
+       0x7a, 0xb2, 0x3e, 0xcc, 0x18, 0x9f, 0x7d, 0x8e, 0xbc, 0x24, 0xad, 0xfb,
+       0xa2, 0x4a, 0xf6, 0x59, 0xf1, 0xba, 0xd0, 0x47, 0xe4, 0x45, 0x9d, 0x94,
+       0xcb, 0x62, 0x5f, 0xc0, 0x86, 0x84, 0x65, 0x3d, 0xc7, 0xfc, 0x5c, 0xf6,
+       0x20, 0xfc, 0x22, 0xf5, 0x3b, 0x6b, 0xc2, 0xeb, 0xc4, 0xdb, 0xc6, 0xd4,
+       0xf6, 0xfc, 0x28, 0x8f, 0x98, 0xcc, 0x13, 0xed, 0x13, 0x75, 0xcc, 0xa8,
+       0x6d, 0x3f, 0x40, 0xbf, 0x9b, 0x1f, 0xd0, 0xfd, 0x7d, 0xf8, 0x3f, 0x96,
+       0xbf, 0x5a, 0x0f, 0x0e, 0x29, 0xf9, 0xf5, 0xef, 0xcb, 0xd7, 0xb9, 0xcb,
+       0x62, 0x2e, 0x8e, 0x6f, 0xbf, 0xbd, 0xd6, 0x5d, 0x40, 0xac, 0x44, 0xcc,
+       0x19, 0x99, 0xe9, 0xdf, 0x9a, 0xb0, 0xc7, 0x49, 0x5e, 0xa9, 0xe0, 0x64,
+       0xfd, 0x4c, 0xff, 0xa6, 0x94, 0x17, 0x3b, 0x18, 0xd3, 0x8b, 0x8c, 0x7a,
+       0x3c, 0x9e, 0x52, 0x71, 0xcf, 0x23, 0x5e, 0xac, 0x21, 0x67, 0x6d, 0xef,
+       0xfd, 0x1a, 0x8c, 0xab, 0x9c, 0xb8, 0x9b, 0xf6, 0xb7, 0x96, 0xae, 0x23,
+       0xf9, 0xc3, 0xfa, 0x5e, 0x27, 0xea, 0xae, 0x2a, 0x43, 0xbc, 0xba, 0x10,
+       0xdf, 0x33, 0x1d, 0xcc, 0xf7, 0x4a, 0x30, 0x64, 0x73, 0x69, 0xc9, 0xe1,
+       0x05, 0x13, 0x45, 0x6f, 0x0e, 0x7b, 0xbd, 0xf5, 0x93, 0xe3, 0xc1, 0x7f,
+       0x58, 0x99, 0xea, 0x1d, 0x36, 0x8e, 0x3b, 0x22, 0xa6, 0x1d, 0x73, 0x81,
+       0x2c, 0x9f, 0xeb, 0xba, 0xe4, 0x79, 0x77, 0xb3, 0x32, 0x3b, 0x12, 0x98,
+       0x58, 0xac, 0x38, 0x10, 0x0e, 0x94, 0xc5, 0xca, 0x23, 0x61, 0x2c, 0x4b,
+       0x77, 0xf9, 0x7c, 0xf6, 0x33, 0xf4, 0x08, 0xce, 0x2d, 0x32, 0x99, 0xfb,
+       0xc3, 0xb9, 0x8c, 0xba, 0x6f, 0xa4, 0x5e, 0xb7, 0x98, 0x1f, 0x59, 0x19,
+       0xdb, 0xef, 0xdd, 0x88, 0x31, 0x07, 0x5b, 0x4b, 0xfd, 0x3a, 0xa8, 0xc7,
+       0x9f, 0xe7, 0xf4, 0x2b, 0x3a, 0x2d, 0x19, 0xfb, 0x9d, 0x75, 0x92, 0xfa,
+       0x75, 0xb3, 0x3d, 0x37, 0xdb, 0x2b, 0x1a, 0xbb, 0x54, 0xcf, 0x85, 0x94,
+       0x67, 0x99, 0x2d, 0xc3, 0x42, 0x79, 0x86, 0xe9, 0x8f, 0x2a, 0x32, 0x1e,
+       0xc1, 0xf7, 0x3f, 0x37, 0xa6, 0x1f, 0x4f, 0xc9, 0x55, 0x44, 0xff, 0x7e,
+       0xea, 0x5f, 0x30, 0x5c, 0xe6, 0xa0, 0x4e, 0xd6, 0xbb, 0x7a, 0x80, 0x97,
+       0x98, 0xcc, 0x2a, 0xa8, 0x32, 0x22, 0x78, 0xaa, 0xd9, 0x83, 0xb7, 0x12,
+       0xa5, 0xf6, 0xb8, 0xaf, 0x9a, 0x6b, 0x59, 0x4f, 0x86, 0xfc, 0xf8, 0x85,
+       0x51, 0x1b, 0x5e, 0xa0, 0xea, 0xcc, 0x1f, 0xbd, 0x48, 0x10, 0x67, 0xbb,
+       0x92, 0xb3, 0x38, 0x5f, 0x5e, 0x6c, 0x4d, 0xa2, 0x9d, 0xf6, 0xe4, 0x77,
+       0x44, 0x80, 0x33, 0x09, 0x23, 0xb8, 0x85, 0xfd, 0x0f, 0x7b, 0xeb, 0xc9,
+       0xd3, 0xd5, 0x46, 0xd2, 0xbd, 0x78, 0x51, 0xc4, 0x88, 0x6f, 0xc3, 0xcf,
+       0xac, 0x21, 0xe2, 0x7c, 0x41, 0x48, 0xd6, 0x1c, 0x67, 0xe3, 0x19, 0xcd,
+       0x81, 0x17, 0x83, 0xcc, 0x87, 0x2b, 0x1c, 0x28, 0x31, 0xde, 0xb6, 0x7e,
+       0xe0, 0x95, 0x7e, 0x64, 0x2c, 0x33, 0x38, 0x0e, 0xc5, 0xc6, 0xc2, 0xad,
+       0xc9, 0x7a, 0xea, 0xfb, 0xf2, 0xfe, 0xff, 0x8f, 0x35, 0xe9, 0x95, 0xfe,
+       0x75, 0xcd, 0xaf, 0x72, 0x0c, 0x7f, 0x14, 0xbb, 0xbf, 0x6f, 0xbd, 0x64,
+       0xb7, 0x79, 0xbb, 0x3b, 0x1b, 0x4f, 0xa5, 0xbd, 0xb7, 0x38, 0x3e, 0x69,
+       0x33, 0xdf, 0x8f, 0xe8, 0xed, 0x8c, 0x5b, 0xfc, 0x79, 0x6b, 0x52, 0xf4,
+       0x27, 0x78, 0x75, 0xd2, 0xc2, 0x34, 0x39, 0x7f, 0xd6, 0x2e, 0x1b, 0xa7,
+       0xbe, 0xba, 0x68, 0x43, 0x8c, 0xe1, 0x3e, 0xd8, 0xbb, 0x3b, 0x34, 0x3b,
+       0x9f, 0xdb, 0xcc, 0x1c, 0x60, 0xc8, 0x5b, 0x8e, 0xad, 0x26, 0xed, 0xce,
+       0x50, 0xe7, 0x38, 0x61, 0xe1, 0xa4, 0x29, 0xe7, 0x2e, 0x4c, 0x7a, 0x1d,
+       0xd8, 0x66, 0x3a, 0xb1, 0xce, 0x50, 0x75, 0xb9, 0xee, 0x08, 0xc9, 0xb9,
+       0x0b, 0xfe, 0x6a, 0x05, 0x3b, 0x18, 0x3e, 0xd6, 0x1b, 0x5d, 0x7e, 0xb9,
+       0xbe, 0x24, 0x24, 0xe7, 0x0a, 0xda, 0xa8, 0x93, 0xb8, 0xa6, 0x60, 0x83,
+       0x21, 0xcf, 0x4d, 0xb3, 0xfc, 0x39, 0x06, 0xcb, 0xda, 0x61, 0x36, 0x5c,
+       0x57, 0xc2, 0x72, 0x67, 0x4d, 0xe1, 0x83, 0x87, 0xef, 0x98, 0x1f, 0x88,
+       0x47, 0x0b, 0xa0, 0xc7, 0x8a, 0xe8, 0xa7, 0x5b, 0x7b, 0x67, 0xb3, 0x9e,
+       0x42, 0x6e, 0xe0, 0xf4, 0x6d, 0x87, 0xc4, 0xcf, 0x80, 0xff, 0xa7, 0x4c,
+       0xb2, 0x86, 0xbc, 0xf3, 0xa8, 0x59, 0xc3, 0x7f, 0x9a, 0xf3, 0x56, 0x6e,
+       0x38, 0xdb, 0x5f, 0x85, 0xbe, 0xae, 0x48, 0x99, 0x17, 0x2c, 0x63, 0xae,
+       0x10, 0x27, 0xbe, 0x8f, 0x8c, 0x39, 0xb1, 0x25, 0x69, 0x68, 0x07, 0x6d,
+       0xfe, 0xe7, 0xa4, 0x2e, 0x9c, 0xcc, 0xcf, 0x03, 0xda, 0x84, 0x92, 0x3f,
+       0x9f, 0x2d, 0xd8, 0x40, 0x3e, 0x2f, 0xf8, 0x16, 0xb7, 0x9e, 0xad, 0x17,
+       0xaa, 0xe1, 0xf6, 0xc7, 0x52, 0x1e, 0x1e, 0x1a, 0x0f, 0xaf, 0x7f, 0x4d,
+       0xca, 0xe7, 0x6f, 0x4b, 0xc1, 0xdf, 0x9a, 0xca, 0xdb, 0x65, 0xde, 0xb7,
+       0x05, 0xdb, 0x2c, 0x72, 0xd6, 0x6c, 0x6e, 0xd6, 0x25, 0xb9, 0x0f, 0xe4,
+       0xb9, 0xdf, 0xe1, 0x3b, 0x9e, 0xa3, 0xad, 0xbb, 0x98, 0x0f, 0x6c, 0x33,
+       0xe2, 0x51, 0x79, 0x0e, 0x69, 0x84, 0x74, 0x5f, 0x81, 0xe2, 0xc7, 0xd6,
+       0xba, 0xdf, 0x72, 0x3e, 0xc9, 0x93, 0x53, 0x9f, 0x29, 0xca, 0xce, 0x87,
+       0xf8, 0x99, 0x60, 0x80, 0x9f, 0xf9, 0x92, 0xcf, 0xdf, 0xc5, 0x7e, 0x36,
+       0xa7, 0xa6, 0xfa, 0x80, 0x82, 0x9b, 0xd8, 0x56, 0x43, 0x08, 0xce, 0xa5,
+       0x75, 0xbf, 0xb1, 0x32, 0xde, 0xec, 0x33, 0xc8, 0x2c, 0xe6, 0x81, 0x36,
+       0x67, 0xf7, 0xe9, 0xdc, 0x5f, 0x27, 0xfb, 0x8e, 0x14, 0x0c, 0xd3, 0xa7,
+       0x36, 0xa5, 0xc5, 0x9e, 0xb2, 0x7a, 0x8d, 0xff, 0x01, 0xfe, 0x98, 0xb8,
+       0x37, 0x89, 0x58, 0x41, 0x44, 0xf0, 0xc7, 0xed, 0x7f, 0x29, 0x55, 0x47,
+       0x0e, 0x2f, 0xcf, 0xf2, 0xdd, 0x9c, 0x67, 0x8f, 0xff, 0xc5, 0xd4, 0xf5,
+       0xb8, 0x67, 0x4f, 0x18, 0xeb, 0xf6, 0xa0, 0xae, 0x88, 0x72, 0x17, 0x86,
+       0x02, 0xfe, 0x51, 0x68, 0xfe, 0x67, 0xa8, 0x87, 0x13, 0x94, 0xed, 0xe4,
+       0x25, 0xb2, 0x89, 0xde, 0xe0, 0xbf, 0x2f, 0xe1, 0x46, 0x2a, 0xf4, 0xa1,
+       0x15, 0xb7, 0x79, 0x86, 0xd7, 0xbf, 0x31, 0xe1, 0x47, 0xc6, 0xe6, 0xac,
+       0xae, 0x22, 0xc9, 0x1f, 0xbb, 0x93, 0xf1, 0x28, 0xd3, 0xe1, 0xdc, 0x9c,
+       0xea, 0x61, 0x99, 0xcf, 0x33, 0x09, 0xb9, 0x17, 0xfd, 0x9a, 0x0a, 0xdd,
+       0xaf, 0x32, 0x7e, 0xf6, 0x9b, 0x62, 0xb3, 0x35, 0xa2, 0x93, 0x20, 0x2b,
+       0xc6, 0x3d, 0x91, 0x40, 0x4b, 0x1d, 0xaf, 0x6b, 0x0b, 0x10, 0xab, 0x88,
+       0x08, 0x27, 0xf4, 0xfa, 0x6b, 0xc7, 0x7d, 0x7e, 0x73, 0x1c, 0xfe, 0x2b,
+       0xc7, 0xa7, 0x8a, 0x40, 0x6e, 0xff, 0x89, 0xb9, 0x9f, 0xd7, 0xbf, 0x36,
+       0x31, 0x1b, 0x6a, 0x24, 0x6e, 0x2d, 0xa9, 0x3f, 0x67, 0xcd, 0x8e, 0x18,
+       0x99, 0x93, 0x94, 0xe1, 0xc3, 0x6b, 0xf5, 0xf8, 0x0c, 0xc7, 0x89, 0x87,
+       0xb4, 0x29, 0x7d, 0xbc, 0x1f, 0xfa, 0xff, 0xdb, 0x47, 0x3e, 0xb6, 0x89,
+       0xfc, 0x12, 0xdf, 0x72, 0x73, 0xaa, 0xe6, 0xc7, 0xa2, 0x70, 0x4e, 0x39,
+       0x1f, 0xc9, 0x7c, 0xac, 0xb2, 0xac, 0x56, 0xc3, 0x97, 0x7b, 0xfe, 0x07,
+       0xda, 0xcb, 0x89, 0xeb, 0x9c, 0x58, 0x4c, 0x7b, 0x6f, 0xf8, 0x6b, 0x27,
+       0xa2, 0xbe, 0x42, 0xc6, 0x50, 0xd9, 0x53, 0xf0, 0x4c, 0xdd, 0xa4, 0x35,
+       0x61, 0xd4, 0xa1, 0x21, 0x2d, 0xcf, 0x63, 0x1d, 0xb4, 0x63, 0x0b, 0x8f,
+       0x9b, 0x72, 0x5f, 0xf0, 0x24, 0x1e, 0x73, 0xd0, 0x26, 0xdc, 0x86, 0xde,
+       0xf2, 0x0f, 0x4a, 0x19, 0x8a, 0x23, 0xce, 0xe0, 0x04, 0xf4, 0xf0, 0x7a,
+       0x72, 0x63, 0x7f, 0xc5, 0x3c, 0x53, 0xd4, 0xfe, 0x4e, 0x22, 0x60, 0x06,
+       0x72, 0xf1, 0xe7, 0x2c, 0xe7, 0xeb, 0xdd, 0x84, 0xb1, 0xee, 0xb9, 0xdc,
+       0xf9, 0xbf, 0xa5, 0xa6, 0xe6, 0xbf, 0x62, 0x77, 0x6e, 0xf7, 0xe6, 0x04,
+       0xde, 0x77, 0xd4, 0xe3, 0xfd, 0xfd, 0x66, 0x01, 0xf3, 0x36, 0xb1, 0x47,
+       0xb7, 0x7b, 0x6b, 0x02, 0x93, 0x4e, 0x5e, 0x3b, 0x6b, 0xce, 0x22, 0x76,
+       0xa9, 0xbc, 0x16, 0x96, 0x58, 0x10, 0xd3, 0x18, 0x47, 0x8b, 0x23, 0x5e,
+       0x77, 0xf1, 0x38, 0xb4, 0x22, 0xa3, 0x8c, 0x79, 0x31, 0x1a, 0x1d, 0x7d,
+       0xba, 0xbf, 0xc9, 0x51, 0xc7, 0xfc, 0xd8, 0xaf, 0xb8, 0x8c, 0x6f, 0x31,
+       0xcf, 0x97, 0xf5, 0xaa, 0x30, 0xc7, 0xed, 0x64, 0x85, 0x9d, 0xd3, 0xd4,
+       0x88, 0x42, 0xcc, 0x2b, 0xc3, 0xbd, 0xda, 0x86, 0xc5, 0x6a, 0xa4, 0x1f,
+       0xb7, 0xd6, 0xbb, 0x1b, 0xcb, 0xc7, 0xf3, 0x3a, 0x41, 0xcc, 0x13, 0x61,
+       0x0e, 0x63, 0x40, 0x2d, 0x8d, 0x88, 0x6e, 0xfc, 0x8d, 0x7d, 0x63, 0x22,
+       0xab, 0xe6, 0xee, 0x1d, 0xf3, 0x14, 0xa3, 0x38, 0x4c, 0x4c, 0xfa, 0x57,
+       0xdf, 0x7f, 0xae, 0xde, 0x64, 0x91, 0xe0, 0xba, 0xcb, 0x90, 0xff, 0xb6,
+       0x3d, 0xb9, 0xdd, 0x91, 0x63, 0x31, 0x77, 0xc0, 0xb2, 0x18, 0x0f, 0x7d,
+       0x50, 0x66, 0x71, 0x3c, 0xf4, 0x29, 0xce, 0x4d, 0x5b, 0xea, 0x23, 0xeb,
+       0x33, 0x4e, 0x3b, 0xd6, 0xbb, 0x0b, 0x23, 0xe1, 0xbb, 0xde, 0x36, 0x7e,
+       0x6f, 0xbd, 0x95, 0x60, 0x5e, 0x4d, 0xdf, 0x2d, 0x20, 0x6e, 0x6f, 0x37,
+       0x9d, 0x4d, 0x4b, 0x15, 0x05, 0xdd, 0xc6, 0x3c, 0xad, 0x88, 0xf1, 0x68,
+       0x13, 0xfd, 0x37, 0xe6, 0x35, 0x82, 0xfb, 0xc1, 0x72, 0xa9, 0xb5, 0x6b,
+       0x5d, 0x91, 0x8d, 0x77, 0x8d, 0xd4, 0x8b, 0xcf, 0x9f, 0xbf, 0xeb, 0x39,
+       0xa3, 0x19, 0xdd, 0xe9, 0x41, 0xf4, 0xa4, 0xb3, 0xfd, 0x64, 0x30, 0xfb,
+       0x13, 0xfa, 0x59, 0xbb, 0xb6, 0x30, 0x22, 0x1c, 0xeb, 0xe8, 0x5d, 0x07,
+       0x8c, 0x28, 0xb6, 0xa4, 0x37, 0xde, 0x75, 0xb6, 0xbe, 0x9f, 0xff, 0xb3,
+       0x75, 0x86, 0x50, 0xfe, 0x89, 0x75, 0x4a, 0x22, 0xd2, 0x47, 0x98, 0x7d,
+       0x6c, 0xbc, 0x6b, 0xdd, 0xa2, 0xaf, 0x63, 0x73, 0x7a, 0xdd, 0x9f, 0xed,
+       0xa7, 0x94, 0x75, 0x8a, 0x23, 0x1d, 0xad, 0x37, 0x05, 0x36, 0xde, 0x95,
+       0x5a, 0xd4, 0xc3, 0x3e, 0x56, 0x31, 0x8e, 0x64, 0xeb, 0x44, 0x15, 0xc7,
+       0x27, 0xea, 0xa0, 0x28, 0xd2, 0xd3, 0x3a, 0x3f, 0xf0, 0x7b, 0x6b, 0x5e,
+       0x6f, 0x81, 0xad, 0x03, 0x17, 0x75, 0xf0, 0xa8, 0xe9, 0xcc, 0x04, 0x1c,
+       0xb6, 0x0e, 0x3a, 0x7c, 0xd4, 0x41, 0x1f, 0x75, 0x90, 0xa9, 0x36, 0xc2,
+       0xef, 0x51, 0x07, 0xf3, 0xc6, 0xd6, 0xae, 0x2d, 0x8a, 0xc0, 0xe9, 0x30,
+       0x5e, 0x77, 0x38, 0x39, 0x17, 0x2e, 0x63, 0x2d, 0xf5, 0xb6, 0xf1, 0xae,
+       0x39, 0x8b, 0x6c, 0x9d, 0x7f, 0xd9, 0x1d, 0xd8, 0x60, 0xef, 0xdd, 0xdb,
+       0x94, 0x6e, 0xe3, 0xd1, 0xc4, 0xe3, 0x61, 0x1e, 0xdd, 0xcc, 0x4d, 0xee,
+       0xa0, 0xae, 0x1a, 0x39, 0x8e, 0x15, 0x94, 0xab, 0x9d, 0xbf, 0x5b, 0xf8,
+       0xbb, 0x83, 0xbf, 0x65, 0x7e, 0xd4, 0x0b, 0xb2, 0xc5, 0x2e, 0xc8, 0xe6,
+       0xa0, 0x3c, 0x1e, 0x62, 0x94, 0x8c, 0x69, 0xe2, 0xcb, 0x37, 0x05, 0x62,
+       0x6c, 0xe3, 0xa9, 0x62, 0xd9, 0xf7, 0xe4, 0x32, 0xe2, 0x3e, 0x27, 0x44,
+       0x3e, 0xbd, 0x65, 0x1d, 0x32, 0xc4, 0xd8, 0xdf, 0x65, 0x31, 0x96, 0xb2,
+       0x95, 0x71, 0x7e, 0x5e, 0x59, 0x34, 0x34, 0xdd, 0x63, 0xc0, 0xe7, 0x36,
+       0xe2, 0xe8, 0x4d, 0x27, 0xa8, 0x03, 0xb1, 0x93, 0x07, 0xa9, 0xbf, 0x4e,
+       0x74, 0x19, 0x27, 0xf4, 0xec, 0xde, 0x89, 0xbd, 0x94, 0x21, 0x48, 0x7e,
+       0xe8, 0x81, 0x33, 0xa2, 0xfb, 0x1b, 0x1d, 0x5d, 0x41, 0x17, 0x68, 0xcb,
+       0xc5, 0x62, 0xcb, 0x71, 0xc6, 0x35, 0xc1, 0x3a, 0xb7, 0xd6, 0x66, 0xe3,
+       0x5f, 0x7c, 0xbe, 0x0b, 0x1e, 0x6d, 0x4d, 0x2a, 0x1f, 0x0b, 0x3c, 0x5a,
+       0x6b, 0x42, 0xfc, 0x4a, 0xd6, 0xfc, 0xc3, 0x76, 0x2c, 0x3f, 0x9e, 0x7e,
+       0xb1, 0x18, 0x65, 0xb6, 0x8f, 0x95, 0x39, 0x8d, 0x6c, 0xbb, 0x1a, 0xdb,
+       0x6d, 0x76, 0x68, 0xb8, 0xe8, 0x23, 0xba, 0xd6, 0xec, 0x90, 0x7d, 0xae,
+       0xf4, 0xfe, 0x54, 0xae, 0x5e, 0x16, 0x27, 0x16, 0xbb, 0x6c, 0x9c, 0x60,
+       0x1b, 0xc5, 0xc0, 0x92, 0xc4, 0xe5, 0xfd, 0x4b, 0x7f, 0xd2, 0x6f, 0x57,
+       0x85, 0x8a, 0x09, 0xfb, 0x99, 0xcb, 0x91, 0x74, 0x0c, 0x83, 0xc9, 0xa9,
+       0x7b, 0xf9, 0xf4, 0xa3, 0x6c, 0xff, 0x70, 0x9c, 0xfa, 0x98, 0x65, 0xc8,
+       0x3e, 0x3f, 0xd9, 0xdb, 0x37, 0x75, 0x5f, 0x9f, 0xc8, 0x56, 0x58, 0x42,
+       0x00, 0xc1, 0x01, 0xe2, 0x4c, 0xb4, 0x59, 0xea, 0x5b, 0xd6, 0x1b, 0xf3,
+       0x82, 0xc8, 0x54, 0x39, 0x31, 0x38, 0x17, 0x18, 0xe8, 0x93, 0x7d, 0x57,
+       0x47, 0x63, 0xab, 0x99, 0x97, 0x45, 0x2b, 0x6b, 0xb5, 0x4d, 0xaa, 0xec,
+       0x99, 0x3a, 0xf6, 0xe5, 0x6e, 0xa3, 0x46, 0xeb, 0x56, 0x33, 0x87, 0x88,
+       0xdd, 0x7b, 0x81, 0x69, 0x25, 0xe2, 0x6b, 0x15, 0x46, 0xb4, 0xa7, 0x02,
+       0x73, 0xe1, 0xaf, 0xb4, 0xf1, 0x32, 0xfe, 0x94, 0x6a, 0x04, 0x57, 0xda,
+       0x38, 0xf8, 0xa1, 0x35, 0xc4, 0xb8, 0xf4, 0x95, 0xb9, 0x3f, 0x28, 0xce,
+       0xe6, 0xd9, 0xd1, 0x75, 0xd3, 0x38, 0x57, 0xbf, 0x58, 0xa0, 0xfb, 0x53,
+       0x8a, 0xe8, 0x48, 0xb8, 0x49, 0x02, 0xdb, 0xc8, 0x75, 0x7f, 0x33, 0x37,
+       0x82, 0x83, 0xfc, 0xff, 0xf3, 0xeb, 0x65, 0x0f, 0xaa, 0x65, 0x05, 0x03,
+       0xf3, 0xc2, 0x15, 0x1c, 0xc3, 0x8b, 0xbc, 0xdf, 0x93, 0x7e, 0xdb, 0x3a,
+       0x3b, 0xcd, 0xe8, 0x5f, 0xc6, 0x40, 0x32, 0x30, 0xae, 0x6b, 0x93, 0xea,
+       0x7f, 0x76, 0x4f, 0x1d, 0xdc, 0x65, 0x1c, 0xcb, 0xf7, 0x02, 0xb5, 0x5a,
+       0x9f, 0xaa, 0x96, 0x88, 0x5e, 0x07, 0xc6, 0x7f, 0x3c, 0x65, 0xaf, 0x47,
+       0x9e, 0x1f, 0xda, 0x6b, 0x1d, 0x3d, 0x43, 0xf4, 0xa9, 0x21, 0x2d, 0x1a,
+       0xa7, 0xde, 0xdd, 0x55, 0x1c, 0xf3, 0x57, 0xe6, 0xde, 0x6a, 0x8f, 0xb3,
+       0xd2, 0x98, 0xc1, 0x31, 0x2a, 0xd0, 0xe6, 0xfe, 0x2c, 0xb7, 0xee, 0xd9,
+       0x40, 0x36, 0x33, 0x64, 0x35, 0xd2, 0x06, 0x0b, 0x58, 0xe7, 0x46, 0x73,
+       0xdf, 0xf4, 0xae, 0x3a, 0xdd, 0xf7, 0x15, 0xc6, 0xce, 0xd0, 0xdc, 0x5f,
+       0x5b, 0x51, 0xcd, 0x69, 0x7e, 0x93, 0xa3, 0xbe, 0x27, 0x21, 0x65, 0x65,
+       0x5e, 0x8d, 0xe8, 0x5c, 0xe5, 0x5d, 0x0b, 0xd5, 0x81, 0xf0, 0x5c, 0x7b,
+       0xfc, 0xc0, 0xdd, 0xa9, 0x04, 0xb6, 0x27, 0xa5, 0x4d, 0x05, 0xcb, 0x02,
+       0xef, 0x58, 0xfe, 0x69, 0x09, 0x6c, 0x4d, 0xff, 0x29, 0xae, 0x37, 0x28,
+       0x71, 0xbf, 0x25, 0x0e, 0x3d, 0x9a, 0x7d, 0xc6, 0x35, 0x5b, 0xd6, 0x94,
+       0x65, 0x0f, 0xd2, 0x5d, 0x89, 0x00, 0xdc, 0xa5, 0xc4, 0xba, 0xb1, 0x80,
+       0x3c, 0x13, 0xf5, 0x22, 0xd3, 0x2c, 0x65, 0x6a, 0xb4, 0x31, 0x64, 0xc8,
+       0xc4, 0x64, 0x7d, 0xb2, 0xa7, 0x24, 0xbb, 0x9f, 0x82, 0x86, 0x57, 0xad,
+       0x6b, 0x67, 0xc8, 0x9d, 0x9a, 0x0c, 0x69, 0x43, 0xc1, 0xfc, 0x40, 0x15,
+       0x6a, 0x57, 0xbe, 0xfe, 0x66, 0x41, 0xa0, 0x80, 0xb8, 0x2d, 0xfe, 0x64,
+       0xb4, 0x9f, 0xc4, 0xbf, 0xd3, 0xd7, 0x65, 0x6f, 0xd9, 0x16, 0xa9, 0xc7,
+       0xb6, 0xe6, 0x22, 0xa5, 0x39, 0xc9, 0x33, 0x64, 0x9f, 0xb2, 0x65, 0xdd,
+       0x14, 0x78, 0xcb, 0x8a, 0x56, 0x53, 0x1e, 0xf2, 0x9f, 0x6c, 0x5d, 0x29,
+       0x93, 0xdb, 0x33, 0xa4, 0x34, 0xdc, 0x25, 0x3a, 0x79, 0xd6, 0x8c, 0x93,
+       0x5d, 0x0b, 0xbe, 0x1e, 0x8b, 0xbd, 0x6d, 0x28, 0xf6, 0xb3, 0xca, 0x65,
+       0x4a, 0x39, 0xe3, 0x95, 0xd3, 0x3f, 0x62, 0xe7, 0xdf, 0x61, 0x62, 0xa1,
+       0xf0, 0x35, 0xc9, 0xa1, 0x9c, 0x78, 0xce, 0xa8, 0xc0, 0xb3, 0x5a, 0x96,
+       0xfb, 0x10, 0x53, 0xf0, 0x6a, 0x62, 0x5e, 0x86, 0x1e, 0x42, 0x0e, 0x69,
+       0xac, 0x3b, 0xaf, 0xfc, 0x3b, 0xf3, 0x2b, 0xe0, 0x95, 0x54, 0x3b, 0x1e,
+       0x95, 0x75, 0x3d, 0xa5, 0xa6, 0xa9, 0xd6, 0x21, 0xfd, 0xb5, 0x63, 0x5b,
+       0x5a, 0xda, 0x3a, 0x16, 0x3b, 0x60, 0xf4, 0xe7, 0x64, 0x15, 0xcc, 0x3c,
+       0x16, 0x7b, 0xce, 0x78, 0xdc, 0x9e, 0x3b, 0x79, 0x7e, 0xd6, 0x63, 0x0a,
+       0xb6, 0x14, 0x43, 0x25, 0x0f, 0x77, 0x18, 0x77, 0xc0, 0x51, 0xf1, 0x75,
+       0xda, 0x9e, 0xec, 0xbf, 0xb9, 0x13, 0xce, 0x0a, 0x17, 0x7d, 0xf3, 0x6e,
+       0xb8, 0x2a, 0x84, 0xfb, 0xe6, 0x79, 0x69, 0x94, 0xf7, 0x45, 0xb7, 0xe7,
+       0x6d, 0xdd, 0x3a, 0x89, 0xa7, 0xdd, 0x92, 0x27, 0x19, 0xe5, 0xd4, 0x91,
+       0xde, 0x42, 0x8e, 0x8c, 0x52, 0x62, 0x13, 0xe3, 0x90, 0xbb, 0x9c, 0x65,
+       0xde, 0xa3, 0xde, 0xe7, 0xf5, 0x96, 0x90, 0x13, 0x5b, 0xd6, 0x87, 0xe4,
+       0xc4, 0xf3, 0x03, 0xb5, 0x19, 0x83, 0xf1, 0x03, 0xb7, 0xe9, 0x4d, 0x71,
+       0xe6, 0x88, 0xab, 0x8d, 0xf3, 0x56, 0x6c, 0x95, 0x94, 0xd1, 0x7d, 0x31,
+       0x25, 0xdf, 0xc7, 0x02, 0xf8, 0xab, 0x2c, 0xb8, 0x22, 0xb2, 0x96, 0x2f,
+       0x6b, 0xb8, 0x0d, 0xf2, 0xcc, 0xb0, 0x59, 0xc6, 0xef, 0x92, 0x75, 0x41,
+       0x44, 0x27, 0x5c, 0x30, 0x32, 0x07, 0x65, 0xce, 0xa6, 0x5b, 0x08, 0x2c,
+       0xfc, 0x1d, 0x73, 0x0b, 0x99, 0x9f, 0x9a, 0x4c, 0x9d, 0x92, 0x09, 0xfa,
+       0xc8, 0x91, 0x9f, 0x80, 0xde, 0x9c, 0xa0, 0xae, 0x1b, 0x43, 0xb2, 0x0f,
+       0xc0, 0xe9, 0x4b, 0xc0, 0xe6, 0xc5, 0xe6, 0x69, 0x7c, 0x06, 0xa5, 0xcc,
+       0x05, 0xe7, 0x8e, 0xad, 0x40, 0x59, 0x45, 0xd4, 0x57, 0x8c, 0x6b, 0x78,
+       0xde, 0x46, 0xbe, 0xff, 0x05, 0x94, 0xad, 0x6c, 0x41, 0x82, 0x63, 0x2f,
+       0x35, 0xbe, 0xc4, 0x6b, 0x0f, 0xa3, 0x2f, 0xe9, 0xe2, 0x38, 0xfe, 0xd5,
+       0x2a, 0xab, 0x16, 0xd9, 0x4c, 0x6f, 0x09, 0xf3, 0xf4, 0xa8, 0xad, 0x0b,
+       0x62, 0x63, 0x52, 0xb8, 0x48, 0x6d, 0x74, 0x3d, 0x98, 0x2b, 0x57, 0xeb,
+       0x2d, 0x6d, 0x4a, 0x07, 0x6d, 0xb6, 0x9b, 0x3a, 0x97, 0xb2, 0x96, 0xb5,
+       0x3c, 0x30, 0x49, 0x1d, 0x77, 0xf0, 0xdc, 0xf0, 0xbf, 0x05, 0xf5, 0x9a,
+       0x42, 0x9c, 0xb2, 0xe2, 0x9a, 0x8f, 0x76, 0xa9, 0xae, 0x12, 0xde, 0xb2,
+       0x34, 0x74, 0xae, 0x44, 0xf6, 0x21, 0x67, 0xed, 0xf4, 0x68, 0x4e, 0x97,
+       0xe7, 0xef, 0xea, 0x36, 0x5e, 0xb5, 0xaf, 0x3b, 0xec, 0xeb, 0xe1, 0xdc,
+       0xf5, 0xa3, 0xbc, 0xfe, 0x3d, 0x5e, 0xef, 0xa1, 0xee, 0xd5, 0x2b, 0xa4,
+       0xfe, 0x5a, 0x53, 0xea, 0x33, 0x45, 0x31, 0xba, 0x73, 0xf3, 0xd1, 0xd1,
+       0x9a, 0x2d, 0xdb, 0xd3, 0x9a, 0x6d, 0xc3, 0xc9, 0x36, 0xe2, 0xd1, 0x62,
+       0x98, 0x28, 0x61, 0x9c, 0x3f, 0x6b, 0x88, 0x5c, 0x9c, 0xbb, 0xb4, 0xc8,
+       0xd5, 0xc6, 0xb8, 0xd2, 0xf5, 0x42, 0x31, 0xe2, 0x1d, 0x33, 0x6c, 0x3b,
+       0x3c, 0x7a, 0x97, 0xec, 0x8f, 0x7b, 0x5b, 0x69, 0xf0, 0xc9, 0xb6, 0xca,
+       0x24, 0x79, 0xe2, 0x43, 0xa6, 0x33, 0x5c, 0xe7, 0x98, 0x97, 0x29, 0x84,
+       0x11, 0x3b, 0xaf, 0x7c, 0x64, 0xe3, 0x43, 0x22, 0xd5, 0xc0, 0x4c, 0x26,
+       0x1e, 0x64, 0x0e, 0x12, 0x4c, 0x53, 0xb7, 0xad, 0x44, 0xec, 0xa3, 0xf6,
+       0x1e, 0x39, 0xe7, 0xc4, 0x0a, 0x34, 0xe8, 0x0e, 0xcc, 0x0b, 0xcf, 0x60,
+       0x26, 0x43, 0xbb, 0x34, 0x0b, 0x1d, 0xba, 0xff, 0x56, 0x7c, 0xc6, 0x23,
+       0xf5, 0x0e, 0xa6, 0x32, 0xeb, 0x8a, 0x39, 0xa7, 0xdf, 0xa0, 0x1c, 0xdb,
+       0x03, 0x22, 0xc7, 0xd7, 0x73, 0x72, 0xb4, 0x30, 0x66, 0x99, 0xda, 0xcd,
+       0x81, 0x9e, 0x0b, 0x7a, 0x7b, 0xc1, 0xd6, 0xdb, 0xc3, 0x3c, 0x2f, 0x64,
+       0xbe, 0x5c, 0x80, 0x13, 0x75, 0xde, 0xdc, 0x7e, 0x37, 0xc9, 0x7d, 0x04,
+       0x7f, 0xcf, 0x7c, 0x69, 0xb5, 0xa1, 0x87, 0x1d, 0x36, 0x67, 0x76, 0x23,
+       0x6e, 0xf3, 0x51, 0x79, 0x76, 0x5e, 0x86, 0xc7, 0xed, 0x72, 0x2e, 0xea,
+       0xa4, 0x04, 0x4f, 0xe4, 0xfc, 0x45, 0xf6, 0x2e, 0x7c, 0xc3, 0xfe, 0xbd,
+       0x97, 0x73, 0xeb, 0xa2, 0xaf, 0xe6, 0x63, 0x94, 0xac, 0x81, 0x6f, 0xb4,
+       0x7d, 0x7f, 0x08, 0xc7, 0xec, 0xff, 0x99, 0x6c, 0xfe, 0x82, 0x6e, 0x53,
+       0xf6, 0xfc, 0x94, 0x60, 0x93, 0x3c, 0x8b, 0x4c, 0x4b, 0x4e, 0x7d, 0x3d,
+       0xb6, 0x70, 0x54, 0x6e, 0x83, 0x1c, 0x43, 0x13, 0x9b, 0xe8, 0x44, 0x9f,
+       0x66, 0x7a, 0xd3, 0x75, 0x53, 0x73, 0x0f, 0x13, 0xfb, 0xeb, 0x7e, 0x6f,
+       0x45, 0xed, 0x7c, 0xe4, 0x94, 0x75, 0xc0, 0x38, 0x11, 0xa2, 0x07, 0xaf,
+       0x2b, 0xb0, 0xf5, 0x7b, 0xfe, 0x2e, 0x7b, 0x9f, 0x20, 0x65, 0x7e, 0x21,
+       0x21, 0x71, 0x74, 0x36, 0x52, 0xa6, 0xc8, 0xe6, 0x6c, 0xde, 0xc1, 0x39,
+       0xe9, 0x4e, 0x06, 0xa2, 0x57, 0xf2, 0xde, 0x04, 0x63, 0xd9, 0x26, 0xea,
+       0x33, 0xd6, 0x2c, 0x3c, 0xa8, 0x0d, 0x7b, 0x69, 0x63, 0xe3, 0xa6, 0x65,
+       0x1d, 0x24, 0x46, 0x94, 0xcf, 0x53, 0x91, 0xa9, 0x6e, 0x43, 0x92, 0xb1,
+       0xe9, 0xa0, 0xd1, 0xf0, 0x99, 0x02, 0xc4, 0xfd, 0x6e, 0xe8, 0xbe, 0xad,
+       0x1c, 0xcd, 0x43, 0x9c, 0xaf, 0x13, 0xa6, 0xf0, 0x33, 0xe7, 0xf9, 0xa5,
+       0x30, 0xc2, 0x8b, 0x1d, 0xff, 0x6a, 0x4d, 0xda, 0xcf, 0x51, 0xbb, 0xfe,
+       0x27, 0x65, 0x68, 0x17, 0xe7, 0x2d, 0xe7, 0x1c, 0xbf, 0x17, 0x90, 0xe7,
+       0xe0, 0x40, 0x6d, 0x6f, 0xc3, 0x3a, 0x91, 0xe1, 0x40, 0xc8, 0x19, 0x3b,
+       0x88, 0x40, 0xf3, 0x06, 0xe5, 0x22, 0x07, 0xbf, 0x72, 0xcc, 0xc4, 0x68,
+       0xdd, 0x8b, 0xe4, 0x0b, 0x52, 0xbf, 0x10, 0x4f, 0x9b, 0xcf, 0x5b, 0x35,
+       0xd3, 0xbf, 0x67, 0x1d, 0x32, 0xd4, 0xf5, 0xd4, 0x76, 0xac, 0x94, 0x6d,
+       0x95, 0xb0, 0xad, 0x7b, 0x03, 0xba, 0xb9, 0x83, 0x6d, 0x3d, 0x93, 0x38,
+       0x11, 0x74, 0xb3, 0xad, 0x27, 0x4c, 0xe1, 0xe0, 0xce, 0xa6, 0x26, 0xce,
+       0x6d, 0x57, 0x32, 0xe0, 0xdb, 0x46, 0xb9, 0x24, 0x37, 0xba, 0x33, 0x21,
+       0xef, 0x74, 0x7c, 0x9d, 0xe3, 0x89, 0xb6, 0xbb, 0xd0, 0xf0, 0x50, 0x19,
+       0xed, 0xa7, 0x1c, 0x79, 0x5b, 0xd7, 0x7d, 0xc4, 0x3b, 0xdc, 0xcb, 0x32,
+       0x6f, 0x06, 0x66, 0xe3, 0x95, 0x50, 0xc3, 0xca, 0xd9, 0x70, 0xc6, 0x0e,
+       0x29, 0x81, 0xa6, 0x0d, 0x4a, 0x5c, 0x13, 0x5b, 0xbc, 0x27, 0xa5, 0x07,
+       0x1b, 0x21, 0xd8, 0xdd, 0x42, 0x7d, 0xcc, 0xc6, 0x87, 0x0b, 0x45, 0x2e,
+       0x67, 0x38, 0xe8, 0x08, 0x74, 0x3c, 0xcf, 0xf9, 0x2d, 0x9b, 0x97, 0xcd,
+       0xfb, 0xd2, 0xf6, 0xbe, 0xce, 0x16, 0xf4, 0xa5, 0x4f, 0xbd, 0x77, 0xc0,
+       0x80, 0xf3, 0x68, 0xdd, 0xa3, 0x16, 0xec, 0x77, 0x40, 0x1a, 0x64, 0x1e,
+       0x5a, 0x64, 0x1e, 0x8a, 0xe9, 0x4f, 0x37, 0x51, 0xee, 0xf5, 0xb6, 0xdc,
+       0xb3, 0x31, 0x6c, 0xca, 0x7a, 0x92, 0x53, 0xbb, 0x07, 0x3d, 0xc4, 0xce,
+       0xc0, 0xf9, 0x2e, 0xf6, 0xf3, 0x26, 0x65, 0x9e, 0x47, 0xbd, 0x4f, 0x36,
+       0x0b, 0x3f, 0x7c, 0x18, 0xbd, 0xc9, 0xfc, 0x3b, 0x22, 0x0a, 0x52, 0x01,
+       0xe9, 0xe3, 0x61, 0xf2, 0xa5, 0x2e, 0x6b, 0xb2, 0x5a, 0xae, 0xef, 0x65,
+       0x2e, 0x1d, 0xd5, 0xe8, 0x0f, 0xd4, 0x3b, 0xf4, 0xd9, 0xd0, 0x27, 0xce,
+       0x38, 0xa2, 0xf4, 0x01, 0xd3, 0x7b, 0x9e, 0xd8, 0x70, 0x14, 0x1d, 0x16,
+       0x2a, 0x6c, 0x7b, 0xf8, 0xf9, 0x88, 0xf1, 0x0b, 0x45, 0x62, 0x7b, 0x86,
+       0x3a, 0x60, 0xb6, 0xdf, 0x2e, 0x3a, 0x28, 0xa5, 0xcf, 0x8e, 0x05, 0x74,
+       0xff, 0x2b, 0x94, 0x67, 0x07, 0xe5, 0x59, 0x91, 0x9d, 0x43, 0xdf, 0x16,
+       0x45, 0x7c, 0x3a, 0xd0, 0xbc, 0x9a, 0xd7, 0xb7, 0x53, 0x9e, 0x40, 0xaf,
+       0x82, 0xa1, 0xe6, 0x6e, 0xf2, 0xb1, 0x0e, 0xea, 0xe0, 0xa2, 0x3c, 0x6e,
+       0x7b, 0xce, 0x3a, 0xc8, 0x05, 0x0a, 0x99, 0xff, 0x0b, 0x7e, 0x6b, 0x18,
+       0xa6, 0x9d, 0xee, 0xe7, 0x8c, 0x44, 0xbd, 0x2a, 0x0a, 0x0d, 0xc1, 0x80,
+       0x6a, 0x5e, 0x73, 0x71, 0x6e, 0xca, 0x71, 0x48, 0xdb, 0x6b, 0xef, 0x69,
+       0xce, 0xe6, 0xea, 0x1f, 0x59, 0xa3, 0x5e, 0xe1, 0x67, 0xb2, 0xde, 0x24,
+       0x6b, 0x32, 0x71, 0x4f, 0x76, 0x4f, 0xb5, 0x8b, 0x3a, 0xc9, 0x5e, 0x7f,
+       0x41, 0x73, 0xe4, 0xf2, 0x66, 0xb9, 0xfe, 0x81, 0xf5, 0xac, 0x5d, 0x5e,
+       0xca, 0xb9, 0x6c, 0x2e, 0x5c, 0x6c, 0x97, 0xfb, 0xc0, 0x7a, 0x51, 0x73,
+       0x4e, 0x29, 0x97, 0x7f, 0x86, 0x77, 0xe2, 0x6b, 0x4e, 0x62, 0x5e, 0xe1,
+       0xdc, 0xc5, 0x38, 0x69, 0x9c, 0xaa, 0x39, 0x5d, 0xd7, 0xc9, 0x38, 0x36,
+       0x75, 0x1f, 0x98, 0x85, 0x27, 0xed, 0x1c, 0xb7, 0x6b, 0xbe, 0x03, 0x27,
+       0x76, 0x16, 0xd0, 0x27, 0xa3, 0x9a, 0xac, 0x87, 0x45, 0x4b, 0x72, 0x7b,
+       0x55, 0x24, 0x6f, 0x0c, 0xfa, 0xd5, 0xab, 0x6d, 0x6e, 0x18, 0x55, 0xff,
+       0xdc, 0x7e, 0x3b, 0xe1, 0x2e, 0x9d, 0xd8, 0x6f, 0xe4, 0x39, 0xcb, 0x89,
+       0x47, 0x55, 0xe2, 0xe4, 0x80, 0xb9, 0x58, 0x62, 0xb3, 0x9f, 0xf5, 0x83,
+       0x31, 0x75, 0x2a, 0xb7, 0x59, 0xed, 0x41, 0x59, 0xd7, 0x36, 0x07, 0x64,
+       0x9f, 0xa9, 0xec, 0x19, 0x95, 0xbe, 0x8a, 0x72, 0xeb, 0x3c, 0x9f, 0xc4,
+       0x35, 0xf2, 0x7d, 0x09, 0xdf, 0xf8, 0x20, 0xc7, 0xdd, 0xf4, 0x60, 0xd4,
+       0x96, 0xf3, 0x57, 0xd6, 0x4a, 0x2d, 0x33, 0x43, 0xc3, 0xa5, 0xb2, 0x47,
+       0x73, 0xb2, 0xc7, 0x3e, 0x71, 0x9d, 0x4a, 0xfa, 0x99, 0xda, 0x66, 0x7e,
+       0x4f, 0xb7, 0xac, 0x61, 0xca, 0x3d, 0x05, 0x5d, 0xc4, 0xa1, 0xa8, 0xd6,
+       0xc0, 0x38, 0xaf, 0xfb, 0xd6, 0x70, 0x3e, 0xe2, 0x5e, 0xd9, 0xcb, 0x9e,
+       0x8f, 0x91, 0x85, 0xc8, 0xae, 0x25, 0xca, 0x7e, 0x87, 0xec, 0xfa, 0x21,
+       0xed, 0x1e, 0x5d, 0xa9, 0xdf, 0x59, 0x19, 0xaf, 0x93, 0xb1, 0xf0, 0xe2,
+       0x3e, 0xea, 0x21, 0xea, 0x55, 0xd6, 0x41, 0xb6, 0x5c, 0x58, 0xab, 0x90,
+       0x35, 0x1a, 0x89, 0xbd, 0xbf, 0xb5, 0x5a, 0x2f, 0x29, 0x3b, 0x75, 0x4f,
+       0x79, 0x75, 0x4c, 0x9e, 0x83, 0x8d, 0xe6, 0xd6, 0xb1, 0x1b, 0xff, 0xe0,
+       0x39, 0xd8, 0x04, 0x6d, 0x09, 0xd1, 0x2d, 0xe4, 0x76, 0x71, 0x74, 0x63,
+       0x34, 0x51, 0xab, 0x6d, 0x85, 0x26, 0xeb, 0xb7, 0xfc, 0xeb, 0xc6, 0xa1,
+       0x04, 0xa2, 0x05, 0x57, 0x95, 0x93, 0x6f, 0x21, 0xea, 0x60, 0x8c, 0x7a,
+       0x22, 0x51, 0xdb, 0xb4, 0x9d, 0x63, 0xf2, 0xaf, 0xec, 0xc6, 0x70, 0xa2,
+       0xe1, 0x4b, 0x8c, 0x23, 0xfe, 0x12, 0x9b, 0xeb, 0x44, 0xff, 0xcb, 0x01,
+       0xe2, 0xc0, 0xe6, 0xdc, 0x1a, 0x52, 0x6b, 0xe2, 0xd7, 0x94, 0xdf, 0x16,
+       0x92, 0xf5, 0xfe, 0x54, 0xb9, 0x09, 0xe6, 0xd3, 0xa7, 0xb0, 0xb6, 0x5f,
+       0xc1, 0xb3, 0xc6, 0x29, 0xac, 0x19, 0x12, 0x79, 0x4e, 0xa1, 0xad, 0xff,
+       0xfb, 0xd8, 0xdf, 0x3f, 0x1d, 0x8d, 0xb6, 0x6e, 0x3a, 0xb0, 0x61, 0xd7,
+       0x11, 0xec, 0x48, 0x5a, 0xd8, 0x1e, 0xf2, 0x60, 0xfd, 0x3e, 0x05, 0xcb,
+       0x03, 0xc7, 0xb0, 0x75, 0x97, 0x85, 0x39, 0xa1, 0x4e, 0x34, 0x99, 0x25,
+       0x28, 0xac, 0x98, 0xb7, 0x4e, 0x65, 0xb9, 0xd6, 0xe1, 0x8e, 0xdc, 0xfe,
+       0xe5, 0x43, 0xc4, 0x02, 0x15, 0x3e, 0x43, 0xf6, 0x26, 0x47, 0x95, 0xdb,
+       0xd3, 0x8d, 0x4a, 0x4b, 0xee, 0x39, 0xe2, 0xad, 0xe9, 0x8f, 0x99, 0xff,
+       0xc4, 0xb1, 0x3f, 0x74, 0x0a, 0x43, 0x43, 0xbf, 0x2e, 0xcd, 0xfa, 0xcb,
+       0x04, 0xb9, 0x83, 0xe4, 0x1c, 0x26, 0x6d, 0xea, 0x4f, 0xbd, 0x37, 0x24,
+       0x76, 0x37, 0x89, 0x9f, 0x0e, 0x9e, 0xc6, 0xe9, 0xc1, 0x7f, 0xc1, 0x12,
+       0x4d, 0xf2, 0x34, 0xab, 0xd3, 0x19, 0xb1, 0xac, 0x3d, 0xf5, 0x71, 0xab,
+       0xda, 0x78, 0xab, 0x0c, 0xc5, 0x65, 0x98, 0x16, 0x79, 0x0d, 0xdb, 0x35,
+       0xb6, 0x95, 0x3c, 0x84, 0x9d, 0x8c, 0xeb, 0xbe, 0xc8, 0x1d, 0xf0, 0x25,
+       0x33, 0x66, 0x25, 0xa2, 0x3b, 0x2b, 0xa1, 0xb7, 0x57, 0x38, 0x8c, 0x8e,
+       0x7f, 0x56, 0xea, 0x70, 0x6b, 0xfa, 0x34, 0x7e, 0x31, 0x68, 0xef, 0xc9,
+       0x6a, 0xf9, 0xb6, 0x62, 0x75, 0x6e, 0x0f, 0xe9, 0x4d, 0xff, 0x55, 0x89,
+       0xc6, 0x65, 0x2f, 0x4f, 0x11, 0x73, 0x82, 0xdb, 0x06, 0x25, 0xdf, 0x6c,
+       0x81, 0xbb, 0x57, 0xcf, 0x2c, 0x25, 0xcf, 0xfe, 0xca, 0x82, 0xf8, 0x8c,
+       0x2a, 0xda, 0xa5, 0x43, 0xd1, 0x83, 0x86, 0xda, 0x89, 0xe3, 0xa6, 0x3e,
+       0xf1, 0x5b, 0x87, 0x31, 0xf4, 0x2d, 0xd4, 0x61, 0x55, 0x5a, 0x1f, 0xba,
+       0x86, 0x79, 0xd8, 0xd6, 0x3e, 0x13, 0xc9, 0x3e, 0xbd, 0xa5, 0xc3, 0xd1,
+       0x83, 0xfb, 0x02, 0x35, 0xed, 0xef, 0x91, 0xcb, 0x79, 0x88, 0x29, 0x7d,
+       0xe3, 0x23, 0xcc, 0x13, 0x7b, 0xb0, 0x61, 0x5f, 0x04, 0xeb, 0xf7, 0x98,
+       0xe8, 0xee, 0x1b, 0xa1, 0x6c, 0x2f, 0x95, 0xca, 0x1e, 0x96, 0xe6, 0x50,
+       0xfc, 0x66, 0x15, 0x81, 0x28, 0xfb, 0x6c, 0x50, 0x23, 0x01, 0xbf, 0xaa,
+       0x30, 0xfa, 0x8f, 0x3b, 0xb1, 0x89, 0x65, 0x7a, 0x93, 0xb4, 0xb9, 0x3e,
+       0x37, 0xe3, 0xe5, 0x4c, 0x0c, 0x8f, 0xf9, 0x70, 0x70, 0xcc, 0x83, 0xa1,
+       0x31, 0x8d, 0x47, 0x31, 0x1e, 0x1b, 0x90, 0xbd, 0x20, 0x5e, 0x3c, 0x7d,
+       0xc0, 0x8d, 0xcd, 0xbb, 0x3d, 0x98, 0x1d, 0x99, 0x86, 0x03, 0x07, 0x8a,
+       0xb1, 0x97, 0xd7, 0x2b, 0x16, 0xfa, 0xf1, 0x24, 0xaf, 0xf7, 0xef, 0x76,
+       0x71, 0x1e, 0xe6, 0xe0, 0x30, 0x0d, 0x7b, 0x68, 0xac, 0x04, 0xc9, 0x01,
+       0x9a, 0x3c, 0x39, 0xeb, 0xdb, 0xcc, 0x30, 0x46, 0x0f, 0x30, 0x36, 0xee,
+       0x33, 0x91, 0x60, 0x3f, 0x3b, 0xa8, 0xab, 0x6e, 0xe2, 0xda, 0x86, 0x31,
+       0xc1, 0xf8, 0x55, 0xb8, 0xa9, 0x57, 0x6f, 0x6a, 0x54, 0x8c, 0xe8, 0x22,
+       0x7b, 0xbf, 0x97, 0xbc, 0xdf, 0xb5, 0x0a, 0x0d, 0x09, 0xdd, 0x6c, 0x44,
+       0x27, 0x4e, 0x72, 0xdc, 0xff, 0x17, 0xfd, 0x76, 0xb1, 0x43, 0xef, 0xb9,
+       0x51, 0x3d, 0x82, 0x9d, 0xe9, 0xa3, 0xe4, 0xea, 0x40, 0x78, 0xff, 0x11,
+       0xf2, 0xb7, 0xe3, 0xc4, 0x9f, 0x37, 0x2d, 0x9f, 0xa1, 0xe2, 0xd6, 0x47,
+       0x8c, 0xf0, 0xfb, 0x4a, 0xa0, 0xfd, 0x57, 0xd4, 0xc1, 0x67, 0x0f, 0xa8,
+       0xb8, 0x65, 0xe7, 0x62, 0xa4, 0x42, 0x51, 0xec, 0x58, 0xa4, 0xe2, 0xe6,
+       0x7d, 0x47, 0x88, 0xfb, 0x13, 0x36, 0x4f, 0xce, 0xa4, 0x1e, 0x46, 0xb0,
+       0x57, 0xd6, 0xb8, 0xdd, 0x8c, 0xdf, 0xa5, 0x78, 0xa6, 0x9f, 0x39, 0xb4,
+       0x59, 0x8a, 0x13, 0x43, 0x47, 0x68, 0x8f, 0xa5, 0x38, 0xde, 0x6f, 0x4c,
+       0xfc, 0xd4, 0x51, 0x8a, 0xa7, 0x79, 0xbe, 0x93, 0xe7, 0x0b, 0x07, 0x8c,
+       0xfe, 0x0e, 0xb5, 0x14, 0x0b, 0xf6, 0xd7, 0xa3, 0xbf, 0x4f, 0x6c, 0x53,
+       0x43, 0xfb, 0x58, 0x5d, 0x4e, 0xf7, 0xa2, 0x73, 0x2f, 0x36, 0x52, 0x57,
+       0xf7, 0xed, 0xec, 0x64, 0x7f, 0x3e, 0xea, 0xfc, 0x08, 0x1e, 0x63, 0x5e,
+       0xb7, 0xbd, 0xcf, 0x87, 0x73, 0x49, 0xc3, 0xff, 0x45, 0xc5, 0x30, 0x8b,
+       0x94, 0x80, 0xf6, 0x0c, 0x7c, 0x38, 0x9d, 0x2e, 0xc6, 0xa6, 0x81, 0x99,
+       0xf8, 0x29, 0xed, 0xf3, 0xd1, 0xdd, 0xd2, 0xdf, 0x04, 0xe3, 0xc3, 0x2c,
+       0x3c, 0x3d, 0x62, 0xb2, 0x6d, 0x99, 0x27, 0x89, 0x39, 0xdd, 0x70, 0x25,
+       0xc5, 0x37, 0xa2, 0x3b, 0x69, 0x16, 0xc4, 0xc4, 0x63, 0x48, 0xf7, 0xeb,
+       0x3d, 0xb7, 0xa9, 0xc2, 0xab, 0x55, 0xea, 0xd2, 0x81, 0x49, 0x4d, 0x8f,
+       0x57, 0xa8, 0xf1, 0x7e, 0xe6, 0xaf, 0xf1, 0x4a, 0xf5, 0x18, 0x9e, 0xee,
+       0x77, 0x62, 0xde, 0x42, 0x95, 0xd7, 0xe3, 0xe7, 0x19, 0xdb, 0xe2, 0xb3,
+       0x55, 0x13, 0x7b, 0x6d, 0x59, 0x11, 0x2f, 0x20, 0xb7, 0x2f, 0x5f, 0x58,
+       0xc3, 0xf8, 0xe5, 0x10, 0xdb, 0x8b, 0x95, 0xaa, 0x4e, 0xea, 0xfd, 0x34,
+       0x46, 0x68, 0xd7, 0x4f, 0xf0, 0x38, 0x3c, 0x68, 0x75, 0x2e, 0x27, 0xe7,
+       0x9e, 0x13, 0xb0, 0x3a, 0x6f, 0x33, 0x0d, 0x5f, 0x81, 0x1a, 0x88, 0x7e,
+       0x05, 0xa7, 0x71, 0x68, 0x44, 0xca, 0xc0, 0xed, 0x8d, 0x30, 0xaf, 0xee,
+       0xb3, 0x3a, 0x77, 0x9a, 0x73, 0x50, 0x6f, 0xe7, 0xc6, 0x3f, 0x2f, 0xcd,
+       0x62, 0xa6, 0xf8, 0x91, 0xbd, 0xa7, 0x0a, 0xbf, 0x62, 0x3b, 0xef, 0x0f,
+       0x96, 0xa3, 0xaa, 0x52, 0xfc, 0xe0, 0x14, 0xde, 0xe9, 0x7f, 0x0d, 0xe7,
+       0xfa, 0x2d, 0x2c, 0x08, 0x59, 0x70, 0x86, 0x6a, 0xcd, 0x46, 0xf5, 0x1a,
+       0x62, 0x84, 0x82, 0x9b, 0xe6, 0x7e, 0x1f, 0xef, 0xd2, 0xff, 0x6f, 0x9e,
+       0x6b, 0xd9, 0xb2, 0xf4, 0x62, 0xa1, 0xb5, 0xa3, 0x5a, 0xfc, 0xc6, 0xb4,
+       0xf7, 0xd3, 0xfc, 0xe9, 0x3c, 0x38, 0xbf, 0xaf, 0x4b, 0x72, 0xe1, 0xd3,
+       0x18, 0x1e, 0x34, 0xa2, 0x6b, 0xf3, 0x72, 0xf6, 0x9f, 0xa6, 0x0e, 0x2c,
+       0xec, 0x34, 0x4f, 0xec, 0xab, 0xc0, 0xbc, 0xf3, 0xcc, 0x1a, 0xaf, 0x9b,
+       0x4d, 0xdb, 0x59, 0xb0, 0x30, 0x60, 0x2e, 0x53, 0xff, 0x37, 0xfd, 0xf4,
+       0x34, 0x0e, 0x0e, 0xe5, 0xf1, 0xda, 0x87, 0x46, 0xfa, 0x79, 0x76, 0xcf,
+       0xbb, 0x17, 0x0d, 0xc9, 0xa3, 0xf6, 0xfa, 0xc3, 0x61, 0xe2, 0x63, 0xf6,
+       0x19, 0xa1, 0x86, 0x91, 0x74, 0x23, 0xb1, 0x21, 0x8a, 0xef, 0xa6, 0x23,
+       0xc4, 0x87, 0x30, 0xf1, 0xa1, 0x9e, 0xf8, 0x60, 0x12, 0x1f, 0xea, 0x88,
+       0x0f, 0x41, 0xfb, 0xd9, 0xb9, 0xac, 0x47, 0x0f, 0x8d, 0xbe, 0x86, 0x82,
+       0x81, 0x53, 0x70, 0x0d, 0xc8, 0x3e, 0x35, 0x8b, 0xfc, 0xa4, 0x56, 0x6b,
+       0xc3, 0x1c, 0x45, 0xf6, 0x0c, 0x0e, 0xa5, 0x4f, 0xa1, 0x68, 0x40, 0xe3,
+       0x58, 0x64, 0xaf, 0x40, 0x4d, 0xb8, 0x87, 0x58, 0xfd, 0x6b, 0xa3, 0xb6,
+       0xc7, 0x8b, 0xda, 0xbd, 0xd5, 0x30, 0xfa, 0x17, 0xaa, 0x73, 0x95, 0xe8,
+       0xe7, 0xbc, 0x1c, 0x67, 0x25, 0x66, 0xed, 0xd6, 0x30, 0x9b, 0xc7, 0x3f,
+       0x25, 0x6b, 0x26, 0xde, 0x74, 0xc0, 0x3b, 0x9d, 0x74, 0x67, 0x06, 0x99,
+       0x00, 0x59, 0xad, 0xd7, 0x87, 0x2b, 0x0f, 0x9f, 0x56, 0x15, 0x64, 0x3e,
+       0x27, 0x31, 0xaf, 0x36, 0xd8, 0xad, 0x32, 0x5b, 0xd7, 0x04, 0xc3, 0x79,
+       0xa8, 0x88, 0x90, 0x45, 0xcc, 0x64, 0x7e, 0x61, 0xb5, 0x99, 0x45, 0xd8,
+       0x52, 0xa7, 0xca, 0x7e, 0x8d, 0xa3, 0x12, 0xa3, 0xa6, 0x33, 0x46, 0x14,
+       0xf7, 0xc5, 0xef, 0x99, 0x0e, 0x0f, 0x8a, 0xfa, 0x2c, 0xeb, 0x1b, 0x21,
+       0x0d, 0x9e, 0x48, 0x20, 0xba, 0x81, 0x69, 0xe4, 0xe7, 0xe6, 0x85, 0x71,
+       0x53, 0xfa, 0x30, 0x06, 0x38, 0xbe, 0xe5, 0xe9, 0xfc, 0xbb, 0x9c, 0x7f,
+       0xfa, 0xef, 0xe2, 0x3b, 0xa1, 0x57, 0xee, 0x9d, 0x0e, 0x43, 0x7b, 0x40,
+       0xed, 0x28, 0x27, 0x07, 0x3f, 0xcc, 0xb8, 0xa7, 0x4c, 0x7e, 0x5e, 0x41,
+       0xcb, 0x40, 0x1c, 0x55, 0xa1, 0x53, 0x4a, 0x4c, 0xf6, 0x32, 0x29, 0x95,
+       0xf8, 0xfc, 0x6e, 0xea, 0x7a, 0x41, 0x86, 0xb6, 0xe2, 0xc3, 0xb7, 0x46,
+       0x45, 0xb7, 0x35, 0x43, 0x3b, 0x39, 0x8e, 0x37, 0xe6, 0x1e, 0x16, 0x9c,
+       0x3c, 0x32, 0x0b, 0x8e, 0x23, 0xd3, 0x98, 0x9b, 0xd6, 0xcc, 0xbd, 0xf2,
+       0xfc, 0xbf, 0xa8, 0xa2, 0x17, 0x85, 0xd8, 0xa1, 0xf7, 0xc7, 0xd8, 0xf6,
+       0x07, 0x8e, 0xc3, 0xd8, 0x44, 0x0c, 0x3e, 0x9a, 0xfe, 0x0e, 0x75, 0x79,
+       0x28, 0x97, 0x2f, 0xad, 0x42, 0xa2, 0x57, 0xf6, 0xe3, 0x9d, 0xc2, 0xac,
+       0x01, 0xbd, 0x79, 0x9b, 0x62, 0x04, 0x6f, 0x56, 0x4e, 0x61, 0xc6, 0x40,
+       0x90, 0x73, 0xa9, 0x61, 0x59, 0x5f, 0x1e, 0x3f, 0x05, 0x83, 0x57, 0x11,
+       0x83, 0xad, 0xc5, 0x3f, 0x35, 0xe3, 0xcc, 0x71, 0x74, 0xd3, 0xa9, 0xe8,
+       0x2d, 0x73, 0x15, 0xd9, 0x9b, 0x63, 0x9c, 0x6f, 0x65, 0x1d, 0xcf, 0x40,
+       0x1d, 0xee, 0xe4, 0x98, 0x9b, 0x38, 0x6f, 0xaf, 0x2d, 0xb4, 0xb0, 0x68,
+       0xa1, 0xbe, 0xb7, 0xc8, 0x11, 0x7d, 0xa0, 0x02, 0x99, 0x8e, 0x6a, 0xda,
+       0xcd, 0x7d, 0x0b, 0xf4, 0xf0, 0xab, 0xc4, 0x5d, 0xe2, 0x34, 0x36, 0x31,
+       0xee, 0xb4, 0x31, 0x16, 0x15, 0x47, 0xf4, 0x1e, 0xe6, 0xa8, 0xef, 0xdf,
+       0xed, 0x88, 0x86, 0xe4, 0x7d, 0xa3, 0x7f, 0xc0, 0x62, 0xb8, 0x43, 0x65,
+       0xc4, 0x41, 0x3d, 0xf3, 0x1a, 0xf4, 0xbd, 0x77, 0x92, 0x93, 0xfe, 0x84,
+       0xfc, 0xae, 0xfa, 0xaa, 0xa3, 0xc4, 0xa8, 0x11, 0x3c, 0x9a, 0x3e, 0x82,
+       0xbd, 0xe9, 0x14, 0x76, 0xa5, 0x77, 0x28, 0x43, 0xf6, 0xb3, 0x3a, 0x45,
+       0xde, 0xad, 0x8b, 0x96, 0x29, 0x5f, 0x46, 0x69, 0xe8, 0x9b, 0xd6, 0x50,
+       0x85, 0x8a, 0xf2, 0x50, 0x10, 0x37, 0xf5, 0xc5, 0xe1, 0x88, 0xbc, 0x67,
+       0xc9, 0x7b, 0xd9, 0xeb, 0xc7, 0x0d, 0xdc, 0xd8, 0x57, 0x8c, 0xd8, 0x7e,
+       0xcb, 0xea, 0xa9, 0x77, 0x62, 0xcd, 0x78, 0x1d, 0x96, 0x0d, 0x3c, 0x66,
+       0xcd, 0x66, 0xcc, 0xf9, 0xf8, 0x5a, 0x0f, 0xee, 0xde, 0xef, 0x41, 0x6b,
+       0x5f, 0x14, 0xbe, 0x48, 0x09, 0x7f, 0x07, 0xcc, 0x25, 0x30, 0x26, 0x26,
+       0x60, 0xf4, 0xdc, 0xe0, 0x08, 0x1c, 0x0a, 0xab, 0x1e, 0x7c, 0x95, 0x38,
+       0xbe, 0x9c, 0xb8, 0x13, 0x1b, 0xb7, 0x50, 0x1e, 0xf1, 0xe2, 0x1e, 0xd6,
+       0xbf, 0x85, 0x73, 0xff, 0xee, 0xa2, 0x43, 0xc4, 0x02, 0xd9, 0x83, 0xa8,
+       0x61, 0xc3, 0xb8, 0x9b, 0xba, 0x72, 0x23, 0x76, 0xb0, 0x12, 0x37, 0xee,
+       0xf6, 0xe3, 0xee, 0x71, 0x0f, 0x1a, 0xfa, 0xac, 0xc5, 0x87, 0xcd, 0xf8,
+       0x4a, 0x0d, 0x06, 0x5a, 0xc7, 0xbd, 0xf8, 0xdb, 0x3e, 0xdd, 0x77, 0x33,
+       0x73, 0xfe, 0x11, 0x33, 0x88, 0xbf, 0x1f, 0xf7, 0xe1, 0xf6, 0xbe, 0x13,
+       0x92, 0x47, 0x2e, 0x71, 0x32, 0xf6, 0x3c, 0x34, 0x3e, 0x13, 0x2b, 0xfb,
+       0xf4, 0xf3, 0x13, 0xe4, 0x76, 0x9d, 0x07, 0x4d, 0x3c, 0x30, 0xae, 0xa2,
+       0x85, 0xed, 0x7c, 0xbe, 0x6f, 0x16, 0x3a, 0x0e, 0xd6, 0x53, 0x86, 0x85,
+       0x58, 0x3e, 0xe0, 0x84, 0x49, 0x16, 0x8f, 0x2f, 0x00, 0xcd, 0x03, 0x13,
+       0xcc, 0xe3, 0x1e, 0xc6, 0x8e, 0x5e, 0x13, 0xf7, 0x8e, 0xcb, 0xf9, 0x11,
+       0xfb, 0x5d, 0xd8, 0xf7, 0xf7, 0x2d, 0xc4, 0x67, 0x07, 0x54, 0xe2, 0x40,
+       0x21, 0x86, 0x56, 0x2a, 0xf8, 0x5b, 0x5e, 0xdf, 0x96, 0x94, 0xbd, 0xcc,
+       0x40, 0x68, 0x67, 0xe0, 0x50, 0x05, 0x39, 0xc3, 0xa2, 0x7d, 0xd9, 0xeb,
+       0x8f, 0x12, 0xe7, 0x8b, 0x88, 0xf3, 0x25, 0xe4, 0xb0, 0x37, 0x0c, 0x1f,
+       0xc1, 0x23, 0xc4, 0xe5, 0xa3, 0x03, 0x9d, 0x8c, 0x3b, 0xa5, 0x78, 0x92,
+       0x71, 0xa0, 0x8f, 0xe7, 0xa7, 0x76, 0x1a, 0x1d, 0x45, 0xc4, 0xe9, 0x57,
+       0x89, 0xbf, 0x3d, 0xc4, 0x8c, 0xfb, 0xfa, 0x18, 0xee, 0x77, 0x32, 0x07,
+       0xb8, 0x2a, 0x3a, 0xdf, 0xc3, 0x1c, 0xeb, 0x66, 0x25, 0xe0, 0x7b, 0x0b,
+       0xa5, 0x70, 0xec, 0xab, 0x44, 0xc3, 0x6e, 0x29, 0x23, 0xf8, 0xa5, 0x42,
+       0x3d, 0xe0, 0xa4, 0xce, 0x8f, 0xc1, 0xea, 0x77, 0x70, 0xbc, 0x35, 0x26,
+       0x19, 0x38, 0xde, 0x30, 0x75, 0xed, 0xbb, 0xc4, 0xda, 0x0f, 0x89, 0xa9,
+       0xfe, 0xe9, 0xf5, 0x68, 0x34, 0x4c, 0x1e, 0xc7, 0x70, 0xba, 0xdf, 0x30,
+       0x65, 0x9f, 0xdc, 0x9b, 0xe4, 0x79, 0x93, 0xd3, 0x19, 0x33, 0x0d, 0xf1,
+       0xc3, 0x11, 0x8e, 0x47, 0x95, 0xbc, 0x04, 0x8e, 0x31, 0xe0, 0x9d, 0x7d,
+       0x8b, 0x39, 0x2e, 0x89, 0xa5, 0x12, 0xef, 0x46, 0x28, 0xeb, 0x62, 0xac,
+       0xa0, 0x3e, 0x1a, 0xfb, 0x54, 0xa4, 0x0e, 0x46, 0x70, 0xef, 0x9e, 0x6c,
+       0x1c, 0x6e, 0x0f, 0xc5, 0x6f, 0x63, 0x1c, 0x0e, 0x17, 0x33, 0x0e, 0xbb,
+       0x22, 0x22, 0x9b, 0x13, 0xc3, 0x8c, 0xdb, 0x5b, 0x92, 0x61, 0x34, 0x71,
+       0x0e, 0x27, 0x52, 0xec, 0xb7, 0x6f, 0x26, 0x9e, 0x49, 0x79, 0x18, 0xb3,
+       0x34, 0x1e, 0x44, 0xb5, 0x91, 0x69, 0x3c, 0xfc, 0x3c, 0xe6, 0xf0, 0x30,
+       0xec, 0x6b, 0x6d, 0x7d, 0x0a, 0xe2, 0xcd, 0xd9, 0xe7, 0x65, 0xcf, 0xa4,
+       0x04, 0x9b, 0x65, 0x2d, 0xf3, 0xde, 0x72, 0xd9, 0xfb, 0xd9, 0x9f, 0xfc,
+       0x3e, 0xca, 0x89, 0x4f, 0x65, 0x39, 0x1c, 0xfa, 0x79, 0x48, 0x70, 0xb7,
+       0x86, 0xb8, 0x2b, 0xfb, 0x73, 0x2c, 0x6b, 0x55, 0x60, 0x2a, 0x1e, 0xfd,
+       0xef, 0x8f, 0xa3, 0xf6, 0x7e, 0x56, 0xc1, 0x24, 0xe2, 0x5f, 0x92, 0xf8,
+       0xc7, 0x31, 0x74, 0x5d, 0x4f, 0x0c, 0xa4, 0x4c, 0xff, 0x98, 0x24, 0x06,
+       0x12, 0xa7, 0x8f, 0x10, 0xa7, 0x9f, 0x22, 0x4e, 0x7f, 0x93, 0x38, 0xfd,
+       0x24, 0x31, 0x21, 0xbb, 0xa6, 0xd7, 0x24, 0xcf, 0x2f, 0x38, 0x1f, 0xef,
+       0xd9, 0x6b, 0x8b, 0xd5, 0xd4, 0xd5, 0xac, 0x01, 0x79, 0xe7, 0x47, 0x3f,
+       0x24, 0x76, 0xff, 0x13, 0xce, 0x93, 0xbf, 0x2a, 0xbb, 0xef, 0xaa, 0xb1,
+       0xaf, 0x1b, 0xee, 0xbe, 0x5a, 0xad, 0x07, 0xf6, 0xb7, 0x02, 0x4c, 0xe1,
+       0xa2, 0x05, 0x7d, 0x6d, 0x70, 0xf4, 0xd5, 0x1e, 0x3a, 0x29, 0xcf, 0x43,
+       0xa7, 0x49, 0x5e, 0xdf, 0x26, 0x7b, 0xbd, 0x0f, 0xc9, 0x7e, 0xad, 0x65,
+       0xbc, 0xe7, 0xea, 0xab, 0x35, 0xdf, 0x82, 0x8d, 0x6d, 0xfe, 0x49, 0xfb,
+       0x5e, 0xcd, 0xfb, 0x8f, 0x50, 0x5f, 0x19, 0xb6, 0x99, 0x4a, 0xca, 0x7e,
+       0xd4, 0x99, 0x78, 0x22, 0x2d, 0xbf, 0x6b, 0x5b, 0x12, 0xea, 0xe3, 0x88,
+       0x55, 0x0b, 0x1f, 0x0f, 0xe3, 0xd6, 0x3e, 0x0f, 0xed, 0x20, 0x8e, 0x32,
+       0xfa, 0xd6, 0xfd, 0xe3, 0xf5, 0xf4, 0xb5, 0xc7, 0x2c, 0x2d, 0x12, 0x68,
+       0x19, 0x27, 0xe7, 0x59, 0x3f, 0xbe, 0x18, 0x4b, 0x07, 0x2c, 0xcb, 0x73,
+       0x8d, 0x11, 0xde, 0xa0, 0xf8, 0xe1, 0xa2, 0x0f, 0x3a, 0xe8, 0x57, 0x6b,
+       0xf7, 0x07, 0xb4, 0xb7, 0x88, 0xa7, 0xeb, 0xea, 0x0f, 0xd3, 0x3e, 0x8c,
+       0xf3, 0x4d, 0xc4, 0x52, 0x67, 0x24, 0xc0, 0x3c, 0xd1, 0x43, 0xdb, 0xf7,
+       0xe2, 0x7c, 0x42, 0xfc, 0x4b, 0xef, 0xf8, 0x2e, 0x73, 0x93, 0x0e, 0xfa,
+       0xc6, 0x07, 0x89, 0xeb, 0xe9, 0x4b, 0x61, 0x1e, 0x33, 0xe9, 0x0b, 0x6e,
+       0xbc, 0x93, 0x30, 0xe8, 0x77, 0x1e, 0xbc, 0x9b, 0xa8, 0x63, 0x9f, 0x41,
+       0x96, 0xf5, 0x63, 0xa3, 0xfd, 0xde, 0x75, 0x4d, 0xfc, 0x5b, 0x4a, 0x4d,
+       0xff, 0x2c, 0xb5, 0x02, 0xd1, 0x4a, 0x0d, 0x7f, 0x37, 0xfe, 0x37, 0xf8,
+       0x19, 0xe3, 0xf6, 0x9a, 0x3e, 0x70, 0x0e, 0x11, 0x22, 0x0f, 0x9c, 0x38,
+       0x28, 0xcf, 0xe9, 0x50, 0x1b, 0x9d, 0xeb, 0xd0, 0x99, 0xdb, 0xea, 0x99,
+       0x73, 0x0e, 0x27, 0xfb, 0x24, 0x2b, 0x66, 0xd9, 0x0f, 0xfa, 0x8b, 0xf1,
+       0xc0, 0xfe, 0xc3, 0xf4, 0x91, 0x02, 0x2c, 0x78, 0xc4, 0x8d, 0xbf, 0x3b,
+       0x38, 0x22, 0x6b, 0x4b, 0x82, 0x99, 0xfe, 0x21, 0x12, 0x85, 0x30, 0xb9,
+       0xde, 0xfd, 0x7b, 0x46, 0x30, 0x90, 0xe3, 0x79, 0x1f, 0x84, 0xe2, 0x5f,
+       0x51, 0x71, 0x98, 0x3c, 0x22, 0x10, 0xbf, 0x9a, 0x36, 0x26, 0xef, 0xb8,
+       0x49, 0xec, 0x5f, 0x41, 0x1b, 0xeb, 0xe6, 0x7c, 0x7e, 0x83, 0xe3, 0xd8,
+       0x41, 0x1b, 0x1b, 0x4d, 0xcc, 0xc4, 0x56, 0xda, 0x58, 0x9c, 0x36, 0x16,
+       0xa7, 0x3d, 0xc5, 0x69, 0x63, 0xf2, 0x6e, 0x7e, 0x9c, 0x36, 0x16, 0xa7,
+       0x8d, 0xc5, 0x53, 0x8b, 0xf1, 0x14, 0x99, 0xc6, 0xae, 0x91, 0x45, 0xc4,
+       0x31, 0x79, 0xb6, 0xc6, 0x79, 0xb8, 0xed, 0x6f, 0xc8, 0xd9, 0x6f, 0xe0,
+       0xa1, 0xe0, 0x4e, 0xfa, 0xe4, 0x63, 0x43, 0xc4, 0x3b, 0xda, 0xc1, 0xa2,
+       0xb4, 0x70, 0xfc, 0x7a, 0xe6, 0xb1, 0xc7, 0xc8, 0xf3, 0x55, 0x3c, 0x6b,
+       0x4a, 0x1e, 0x6c, 0xf2, 0x9c, 0xb1, 0x26, 0x29, 0x1c, 0xec, 0x18, 0x36,
+       0xf4, 0x03, 0x37, 0x91, 0x17, 0x56, 0x92, 0x97, 0x8c, 0x2c, 0x00, 0x5e,
+       0x1c, 0x12, 0x19, 0xc5, 0xc7, 0xb3, 0xfb, 0x4f, 0x8f, 0xf7, 0xd7, 0x44,
+       0x1b, 0x65, 0x7d, 0x88, 0x9c, 0x64, 0xf1, 0xb0, 0x70, 0xbc, 0xc3, 0xe4,
+       0x48, 0x7a, 0xf8, 0xdf, 0x21, 0x1c, 0xaf, 0x12, 0x65, 0x7b, 0xf4, 0xf0,
+       0x3b, 0x30, 0xd6, 0xfd, 0x52, 0xb1, 0x16, 0xbf, 0x16, 0x0a, 0xc4, 0x9f,
+       0x54, 0x54, 0x34, 0x93, 0xef, 0xdd, 0xbc, 0xd3, 0x89, 0x9e, 0xd0, 0x62,
+       0x7c, 0x85, 0x9c, 0x6f, 0xf5, 0x35, 0x2a, 0x96, 0xec, 0xa3, 0x2d, 0x55,
+       0x0a, 0xc7, 0xd2, 0xc3, 0xe7, 0x30, 0x61, 0xaf, 0x13, 0x8e, 0xa6, 0x8e,
+       0x5b, 0x55, 0x86, 0x60, 0x11, 0xb1, 0xed, 0xea, 0x37, 0x2d, 0xb7, 0xac,
+       0x35, 0x91, 0x03, 0x0e, 0xf7, 0x47, 0x5f, 0x70, 0x12, 0xf7, 0xd7, 0x93,
+       0x07, 0x3e, 0x91, 0xe3, 0x81, 0x07, 0xfb, 0x0d, 0xed, 0x07, 0xc4, 0x8b,
+       0xfd, 0x3c, 0xdf, 0xca, 0x73, 0xab, 0xdf, 0xe0, 0x7c, 0x04, 0x9a, 0x66,
+       0x90, 0x1b, 0xbe, 0x43, 0x99, 0x7b, 0x29, 0x73, 0x82, 0xf6, 0x9f, 0xee,
+       0xd5, 0x90, 0x1c, 0x33, 0x30, 0xde, 0xeb, 0x45, 0xdf, 0x58, 0x10, 0x4f,
+       0xf6, 0xfa, 0xb0, 0x93, 0xfc, 0xf0, 0x70, 0xaf, 0xf8, 0xe2, 0x4c, 0xf4,
+       0x8f, 0xcd, 0xc4, 0x37, 0x92, 0xb2, 0x3e, 0xf5, 0x2e, 0x56, 0x57, 0x88,
+       0x7e, 0xc4, 0x2f, 0xc9, 0xaf, 0x93, 0x7a, 0x4f, 0x8c, 0x63, 0x8a, 0x79,
+       0xf5, 0x43, 0x31, 0xe8, 0x43, 0x9c, 0xc1, 0x8f, 0x87, 0xbe, 0x20, 0x31,
+       0x52, 0x7c, 0x52, 0xc3, 0x13, 0xe4, 0x3c, 0xa5, 0xc4, 0xd5, 0x92, 0x48,
+       0x4d, 0xf4, 0x0b, 0x8a, 0x1e, 0x7b, 0x45, 0xb5, 0xac, 0x4a, 0x89, 0xe1,
+       0x07, 0x35, 0xf2, 0x0f, 0x13, 0x37, 0xdb, 0x31, 0x5b, 0xc3, 0xf4, 0xdd,
+       0x95, 0xa8, 0xda, 0xdd, 0x87, 0xff, 0x56, 0x19, 0xff, 0x60, 0x1a, 0x63,
+       0xfd, 0x34, 0x62, 0xfb, 0xec, 0xbe, 0x93, 0xd3, 0x67, 0x91, 0x33, 0xbf,
+       0xa1, 0xd6, 0x66, 0xbe, 0x0b, 0xfd, 0xd0, 0x69, 0x87, 0x3e, 0x71, 0x94,
+       0xf1, 0xc1, 0x45, 0xfb, 0x9c, 0x31, 0xae, 0xd1, 0x7f, 0x6b, 0x8f, 0x56,
+       0xc1, 0x88, 0x5f, 0xab, 0x3a, 0x2d, 0x54, 0x8a, 0x3c, 0xa1, 0xf2, 0x6c,
+       0x6e, 0x14, 0x26, 0xf6, 0x4b, 0x6c, 0x70, 0x40, 0x23, 0x0e, 0xff, 0x3d,
+       0x7d, 0xe6, 0x4e, 0x3b, 0x1e, 0x1d, 0xb6, 0x9f, 0x85, 0x76, 0x8e, 0xc7,
+       0xe9, 0x27, 0x8b, 0xd1, 0xd1, 0xef, 0x41, 0xbb, 0x1d, 0x8b, 0x1e, 0xb3,
+       0x2a, 0xe8, 0x33, 0x1d, 0xfb, 0x03, 0x4d, 0x37, 0xd2, 0x67, 0xae, 0xbb,
+       0x46, 0xe2, 0xd8, 0x61, 0xf2, 0x5f, 0xc3, 0xbc, 0x8e, 0xf8, 0xb2, 0xb5,
+       0xde, 0xe8, 0x78, 0x9e, 0x32, 0xdd, 0x4f, 0xfb, 0x7f, 0x97, 0x3c, 0xe7,
+       0xdc, 0x9e, 0x43, 0xd4, 0x99, 0x66, 0xfb, 0xc3, 0xcf, 0x92, 0x3e, 0xdb,
+       0x37, 0x62, 0xfc, 0x2d, 0x71, 0x2f, 0x46, 0x5f, 0xfa, 0x37, 0xc6, 0xec,
+       0xe2, 0x50, 0xfc, 0xf6, 0x62, 0x04, 0x71, 0x1f, 0x65, 0xfd, 0x38, 0xa9,
+       0xf7, 0x6f, 0x90, 0x77, 0x8f, 0x43, 0x26, 0x65, 0xf1, 0xe0, 0x83, 0xa4,
+       0xd8, 0xd9, 0x89, 0xff, 0x59, 0x89, 0xf8, 0x26, 0xc6, 0xe0, 0xa0, 0xe6,
+       0x90, 0xb5, 0xf0, 0x99, 0x58, 0x73, 0xf0, 0x1a, 0xca, 0x5c, 0x47, 0xff,
+       0x03, 0xe6, 0x0c, 0x47, 0x70, 0xcf, 0x1e, 0xc9, 0x31, 0xd0, 0x20, 0xb9,
+       0xda, 0xbc, 0x50, 0xc0, 0x3c, 0x43, 0xac, 0x58, 0x3b, 0x76, 0x98, 0x71,
+       0x42, 0xd6, 0x96, 0x91, 0xf1, 0x19, 0x61, 0xbc, 0xda, 0x5b, 0x6f, 0xbf,
+       0xd3, 0x70, 0xff, 0x58, 0x3d, 0x5e, 0xe9, 0x9d, 0x89, 0xfb, 0x98, 0xeb,
+       0xc4, 0x98, 0xeb, 0xc4, 0xc6, 0xbc, 0x88, 0x1d, 0x98, 0xc6, 0x83, 0xb2,
+       0x1d, 0x98, 0xc3, 0x83, 0xb2, 0x8d, 0xa9, 0xf8, 0x2a, 0xf3, 0x97, 0x0d,
+       0xc4, 0xf3, 0x1e, 0xda, 0xe3, 0xff, 0xe0, 0xdc, 0x0f, 0xd0, 0xde, 0xab,
+       0x89, 0xf7, 0x6f, 0xee, 0x02, 0xee, 0xb4, 0xf5, 0x73, 0x84, 0x7a, 0x54,
+       0xf0, 0x15, 0xfa, 0x44, 0x15, 0x63, 0x52, 0x37, 0xe7, 0x7c, 0xe7, 0xa0,
+       0x11, 0x0c, 0xab, 0x01, 0xed, 0x09, 0xce, 0x73, 0xd7, 0x88, 0x8a, 0x47,
+       0xfb, 0x17, 0x63, 0x3e, 0x63, 0xca, 0xb6, 0xa1, 0x09, 0xbb, 0x7c, 0x37,
+       0xfd, 0xe1, 0x6e, 0xfa, 0xc9, 0x7b, 0xf4, 0x93, 0xc9, 0x95, 0xf2, 0x3e,
+       0xa9, 0x93, 0x39, 0xff, 0xc3, 0x58, 0x93, 0x90, 0x78, 0xa7, 0xf7, 0x0c,
+       0xa9, 0xcc, 0xb5, 0x68, 0x9f, 0x5d, 0xcc, 0x51, 0x6e, 0xa7, 0x6d, 0x3e,
+       0x3a, 0x24, 0x3e, 0x24, 0x39, 0x8b, 0x11, 0xde, 0x46, 0xdb, 0x7c, 0x7e,
+       0x48, 0xfc, 0xa3, 0x14, 0xb7, 0xee, 0x94, 0xfd, 0xa6, 0xa5, 0xf8, 0xec,
+       0xbe, 0xc3, 0x94, 0xef, 0x08, 0x76, 0xd1, 0x2e, 0x4b, 0x69, 0x97, 0xf7,
+       0x51, 0xaf, 0x1e, 0xda, 0xe5, 0x06, 0xe2, 0x50, 0x09, 0xed, 0xf2, 0x5e,
+       0xf2, 0x81, 0xca, 0x9c, 0x5d, 0xfe, 0xdd, 0xf8, 0xc2, 0x8a, 0x6c, 0x8c,
+       0xf0, 0x42, 0xdd, 0x2d, 0xef, 0xf7, 0x59, 0xd6, 0xed, 0x66, 0xa6, 0x69,
+       0x06, 0x74, 0xb6, 0x1d, 0xc1, 0xb2, 0xb4, 0x13, 0xe5, 0x7d, 0x11, 0x2c,
+       0x4d, 0xd6, 0xb4, 0x9f, 0x55, 0x22, 0xc8, 0xcc, 0xc8, 0xf2, 0x40, 0x57,
+       0x9f, 0x7c, 0xdf, 0x43, 0x23, 0x07, 0xe1, 0xf8, 0xaf, 0xcd, 0x7e, 0x53,
+       0xe4, 0xf3, 0x7f, 0x01, 0x7f, 0x5c, 0x42, 0x99, 0x3a, 0xcd, 0x8f, 0xac,
+       0xc9, 0xec, 0xf7, 0x07, 0x9c, 0xb7, 0xf1, 0x7c, 0x16, 0xdb, 0xa8, 0x1a,
+       0x77, 0x3a, 0xbf, 0x98, 0xf4, 0x60, 0xfa, 0xb8, 0x89, 0xbf, 0xcd, 0xb6,
+       0xe3, 0x2e, 0x88, 0x34, 0xe2, 0xb9, 0x84, 0x82, 0x69, 0xc6, 0xd3, 0xf8,
+       0x91, 0xbd, 0x2e, 0x50, 0x89, 0xf2, 0xdd, 0xf6, 0x9a, 0x02, 0x0e, 0x24,
+       0xf4, 0xf6, 0x34, 0xcf, 0xcb, 0x0e, 0x7a, 0x51, 0xbc, 0x5b, 0xc1, 0x2d,
+       0x01, 0x2f, 0x4a, 0xf9, 0xdb, 0x43, 0xbe, 0xd9, 0x1d, 0x5a, 0x6e, 0x6d,
+       0x59, 0x25, 0xf6, 0xed, 0x05, 0x0e, 0x96, 0x94, 0x0b, 0x0e, 0x1e, 0x30,
+       0x65, 0xed, 0xd2, 0x40, 0x77, 0xa2, 0x12, 0x85, 0xbb, 0x6b, 0x9a, 0x1a,
+       0x51, 0x63, 0xbe, 0xc3, 0xfa, 0x05, 0x07, 0x3f, 0x5b, 0x21, 0xeb, 0xf6,
+       0x4f, 0x49, 0x8c, 0x1b, 0x92, 0x79, 0xcd, 0xc6, 0x50, 0xe7, 0xd8, 0x5b,
+       0x9a, 0xe8, 0x65, 0x13, 0x39, 0x8a, 0xda, 0xf7, 0xa6, 0x5d, 0xc6, 0x17,
+       0x39, 0x4a, 0x0c, 0x90, 0xf8, 0x72, 0x0a, 0xed, 0xfd, 0xa7, 0x68, 0xff,
+       0xb2, 0x8e, 0xc1, 0xbc, 0x77, 0x81, 0x85, 0xe2, 0x85, 0x99, 0x60, 0x31,
+       0xa2, 0x15, 0x15, 0xc4, 0x6f, 0xfa, 0x00, 0x5e, 0x30, 0xf5, 0x96, 0x87,
+       0x1c, 0xd1, 0x87, 0x8a, 0xa0, 0xaf, 0x7b, 0x5b, 0xe9, 0xc1, 0xc6, 0xc0,
+       0x08, 0xfa, 0xc8, 0x05, 0xf3, 0xf9, 0xf8, 0xba, 0x3d, 0x8c, 0x6f, 0x8e,
+       0x8b, 0xf9, 0xb8, 0x16, 0x8a, 0xff, 0x8e, 0x3c, 0xc0, 0x3f, 0x9b, 0x18,
+       0xed, 0xb0, 0x7d, 0x27, 0x90, 0xd9, 0x44, 0x7b, 0x0d, 0x8f, 0x87, 0xe9,
+       0x23, 0x23, 0x82, 0x7d, 0xf2, 0x35, 0xa3, 0x17, 0x0a, 0x98, 0x3f, 0x16,
+       0x33, 0x0f, 0x39, 0x9d, 0xb4, 0x3a, 0xdd, 0xb4, 0x6b, 0xe7, 0xa2, 0x99,
+       0x50, 0xd3, 0x37, 0xe0, 0x9d, 0x5d, 0x33, 0x51, 0x48, 0x5f, 0xaa, 0x48,
+       0xca, 0x0b, 0x55, 0xea, 0xa7, 0xd9, 0x6f, 0xec, 0x3d, 0x04, 0xda, 0x03,
+       0x8e, 0xda, 0x75, 0x49, 0x45, 0x27, 0xf6, 0xeb, 0x2d, 0xa5, 0xea, 0x4c,
+       0x78, 0x98, 0xaf, 0x94, 0xa4, 0x3d, 0x00, 0xb9, 0x32, 0x58, 0xef, 0xa7,
+       0xbb, 0x5c, 0x28, 0x37, 0x8c, 0xe8, 0x33, 0xcc, 0x81, 0x1c, 0xa3, 0x4e,
+       0xfc, 0xcc, 0x96, 0x6b, 0x1a, 0x8a, 0x47, 0x6f, 0xc0, 0xe9, 0x5d, 0x7e,
+       0xa8, 0xbc, 0x76, 0x76, 0xcf, 0x1c, 0x14, 0x8c, 0x12, 0x08, 0xd2, 0x8b,
+       0xf1, 0xd6, 0x2e, 0x15, 0xae, 0xd1, 0xbf, 0xc1, 0x87, 0xbb, 0x14, 0xcc,
+       0x9f, 0xa7, 0xa0, 0x68, 0x78, 0x84, 0x3a, 0x11, 0xee, 0x45, 0x3f, 0x4d,
+       0xc1, 0xe6, 0x5d, 0x5b, 0x92, 0xc2, 0xed, 0xc9, 0xe9, 0x06, 0x2b, 0x61,
+       0xee, 0x7e, 0xd3, 0xaa, 0x30, 0x8c, 0xd8, 0x2d, 0xaa, 0xb5, 0xb8, 0x72,
+       0x41, 0xa0, 0x65, 0x80, 0x38, 0xfd, 0x12, 0x7d, 0xe0, 0x64, 0x7f, 0xdc,
+       0xf2, 0x18, 0x8b, 0x89, 0xb5, 0x51, 0x34, 0x30, 0x37, 0x97, 0xbc, 0x7b,
+       0x9b, 0x9d, 0xef, 0xca, 0x7e, 0x63, 0x27, 0xfc, 0x63, 0x0f, 0xe3, 0x78,
+       0xc2, 0x8d, 0xc5, 0x63, 0xa5, 0xb8, 0x8e, 0x39, 0x75, 0x98, 0xdc, 0x21,
+       0xbc, 0x2f, 0xcb, 0xf1, 0x9e, 0x27, 0xc7, 0xfb, 0x15, 0xb2, 0x1c, 0x6f,
+       0x80, 0xb9, 0x5a, 0x95, 0x51, 0x8a, 0x5b, 0x06, 0x0c, 0xc6, 0x80, 0x52,
+       0x34, 0xdb, 0xeb, 0x01, 0x1a, 0x6e, 0xa3, 0xff, 0x7e, 0x9e, 0xf9, 0xf8,
+       0xcd, 0x3b, 0x03, 0xbe, 0x1d, 0x8a, 0x8f, 0x71, 0x40, 0xda, 0x3f, 0x4c,
+       0xdc, 0xf0, 0x61, 0x4e, 0xaf, 0x11, 0x5c, 0x8a, 0xc0, 0xf9, 0x43, 0xd4,
+       0xe5, 0xe2, 0xb1, 0x1b, 0x10, 0xa6, 0xee, 0xc2, 0xfb, 0x0e, 0xe7, 0xc6,
+       0x31, 0x41, 0xd9, 0x9d, 0x78, 0x6f, 0x70, 0x16, 0x5e, 0x3d, 0x90, 0xcd,
+       0xc3, 0x03, 0x7d, 0x13, 0xb2, 0x5e, 0xfc, 0x35, 0x86, 0xd7, 0x7b, 0x24,
+       0x0f, 0xff, 0x41, 0xbf, 0xde, 0x5f, 0x2a, 0xeb, 0x84, 0xf4, 0xe7, 0xaf,
+       0x2e, 0x70, 0x30, 0xbe, 0xe8, 0xfe, 0xef, 0x3b, 0xe2, 0xf2, 0x1c, 0xd9,
+       0xff, 0x08, 0xef, 0x7f, 0x9f, 0xf1, 0xfc, 0x36, 0x5e, 0x8f, 0x55, 0x32,
+       0xd7, 0x5e, 0x18, 0x3f, 0xef, 0xe2, 0xf5, 0xc7, 0x38, 0x97, 0x65, 0x46,
+       0x4d, 0xec, 0x15, 0xe5, 0x08, 0x71, 0xc3, 0x81, 0x1d, 0x21, 0x3d, 0xba,
+       0xc3, 0xce, 0xa1, 0x9d, 0x98, 0x48, 0x5f, 0x9d, 0xf3, 0xc1, 0x4a, 0x94,
+       0xec, 0x96, 0xfc, 0xc5, 0x90, 0xf5, 0x9f, 0xfe, 0x12, 0xe6, 0x4f, 0x95,
+       0x17, 0xec, 0x33, 0xbf, 0xff, 0x09, 0xee, 0x8a, 0x48, 0x33, 0x42, 0x7d,
+       0xf9, 0x7d, 0x50, 0x87, 0xd0, 0x9d, 0x7e, 0x10, 0xed, 0xbb, 0xf4, 0x76,
+       0x59, 0x1f, 0x7a, 0x25, 0x14, 0xb7, 0xca, 0x8d, 0x4e, 0xb8, 0x16, 0x18,
+       0xcd, 0xcc, 0x5d, 0x62, 0xdf, 0x56, 0x8a, 0x19, 0x3b, 0x8e, 0x61, 0xf3,
+       0xb0, 0x1e, 0xdc, 0xa1, 0x18, 0xcc, 0xf7, 0x34, 0x1c, 0x1a, 0x2c, 0xc0,
+       0xdd, 0x7b, 0x5a, 0x19, 0xdb, 0x4c, 0xe2, 0x66, 0x8d, 0xff, 0x1c, 0xde,
+       0xc7, 0x49, 0x53, 0xde, 0x11, 0x2a, 0x42, 0xab, 0x26, 0x7b, 0x80, 0x98,
+       0x79, 0x4e, 0xbb, 0xe4, 0x3d, 0x71, 0x4f, 0x91, 0x91, 0x7f, 0xdf, 0xdf,
+       0x60, 0xae, 0x38, 0x89, 0xfd, 0x83, 0xb2, 0x2e, 0x50, 0xa5, 0x1c, 0xef,
+       0x9f, 0xeb, 0xeb, 0x22, 0xe6, 0x3f, 0x64, 0x66, 0x70, 0x7e, 0x61, 0x25,
+       0x30, 0x5d, 0x41, 0xe8, 0xd3, 0x01, 0xf9, 0x9e, 0x0d, 0xff, 0xde, 0xb3,
+       0xfc, 0x5f, 0x90, 0x76, 0x4a, 0xcb, 0xb2, 0x6b, 0x05, 0x3f, 0xaa, 0x94,
+       0xf7, 0x01, 0x8f, 0x27, 0x2b, 0xca, 0xb3, 0xcf, 0x9c, 0xff, 0x54, 0x1f,
+       0x6f, 0x58, 0x7e, 0xbb, 0x8d, 0x7c, 0xdd, 0xd7, 0xad, 0xa8, 0x57, 0xca,
+       0x17, 0xb0, 0x6d, 0xf1, 0xcb, 0x2a, 0x65, 0x1d, 0x71, 0x54, 0x0d, 0x55,
+       0x29, 0xad, 0x43, 0x97, 0xb7, 0xfb, 0x9a, 0x15, 0x6d, 0x96, 0xf3, 0x7c,
+       0x39, 0x8b, 0xf7, 0xa5, 0x6c, 0xfe, 0xfe, 0x0b, 0xb9, 0xb6, 0x0a, 0xc9,
+       0x53, 0xb3, 0x65, 0xee, 0xee, 0x97, 0xfd, 0x4b, 0x51, 0x9c, 0xa8, 0x9f,
+       0xda, 0x5e, 0xbe, 0xef, 0xef, 0x5c, 0xd2, 0x5e, 0xb6, 0x6c, 0x55, 0x15,
+       0x8a, 0xa5, 0x7c, 0x06, 0xff, 0x8f, 0xbd, 0x86, 0x70, 0xc6, 0xde, 0x73,
+       0xb8, 0xcd, 0x6c, 0x88, 0x16, 0xe1, 0x33, 0x50, 0xaf, 0x8a, 0xcf, 0x2f,
+       0xb2, 0xb9, 0x6d, 0xb4, 0xb9, 0x88, 0xf9, 0xad, 0xdb, 0x88, 0x3e, 0xe4,
+       0x46, 0x26, 0xe3, 0x86, 0xde, 0x72, 0x5e, 0x39, 0xa4, 0xdc, 0x1d, 0xd0,
+       0xdb, 0xdf, 0x23, 0xd7, 0x78, 0x39, 0x10, 0xb7, 0x4a, 0x0d, 0xc3, 0xd7,
+       0xab, 0xe8, 0xe6, 0x1a, 0xc6, 0xb2, 0x17, 0x99, 0x3f, 0xb6, 0x05, 0x7a,
+       0xec, 0xe7, 0x8b, 0x4a, 0x64, 0x05, 0xae, 0xb4, 0xbf, 0xdd, 0xd2, 0x0c,
+       0x23, 0xf5, 0xb2, 0xac, 0x77, 0xf1, 0x77, 0x0c, 0xf3, 0xed, 0x6b, 0x6d,
+       0x08, 0xda, 0xff, 0x57, 0xe5, 0xbe, 0xef, 0xd2, 0x82, 0x1a, 0xfb, 0xff,
+       0x1d, 0x98, 0x9b, 0xba, 0xb0, 0x2e, 0x8c, 0x4d, 0xa6, 0x65, 0x3d, 0x67,
+       0x5a, 0x38, 0x73, 0x71, 0xbf, 0xf3, 0x0a, 0x07, 0xf3, 0x0d, 0x52, 0xac,
+       0x58, 0xf6, 0xfb, 0x54, 0x17, 0xdf, 0x97, 0x58, 0x7a, 0xc9, 0x7e, 0x67,
+       0xf9, 0xae, 0x42, 0xa5, 0xfd, 0xfd, 0xb1, 0x79, 0x8b, 0x9c, 0x78, 0x29,
+       0x51, 0x16, 0xf3, 0xf0, 0xf7, 0xe6, 0x45, 0x05, 0x58, 0x4f, 0x4e, 0xd6,
+       0x74, 0xd5, 0x33, 0x38, 0x67, 0x7f, 0xc7, 0x21, 0x1e, 0x92, 0xef, 0x37,
+       0x9c, 0x48, 0xd0, 0xa7, 0x07, 0xbb, 0x43, 0xfb, 0xed, 0xbe, 0x5f, 0xc7,
+       0xa6, 0x51, 0x79, 0xe6, 0xd7, 0x8c, 0xd5, 0x89, 0x49, 0xc6, 0x37, 0x69,
+       0x4b, 0xf2, 0x6e, 0x3d, 0xd3, 0xc6, 0x5c, 0x55, 0x75, 0x04, 0x71, 0x3b,
+       0xe3, 0xca, 0x2b, 0x09, 0xda, 0xe9, 0x42, 0xbd, 0xe3, 0xdb, 0xe4, 0x06,
+       0x65, 0x11, 0x3d, 0xf8, 0xae, 0xd2, 0x82, 0x31, 0xd6, 0x9f, 0x48, 0x88,
+       0x2d, 0x56, 0xc6, 0x0a, 0x39, 0x96, 0x43, 0xe4, 0xa3, 0x2f, 0x27, 0x34,
+       0x9c, 0xab, 0xf7, 0x20, 0x45, 0x7e, 0xfa, 0x52, 0x42, 0xb8, 0x9a, 0x17,
+       0x4f, 0x0c, 0xca, 0xfa, 0x60, 0x23, 0x1a, 0x12, 0xb2, 0x36, 0xec, 0xc5,
+       0xe3, 0x23, 0x5e, 0xda, 0xa3, 0x65, 0x6d, 0xa2, 0xed, 0xb6, 0x6a, 0x13,
+       0xec, 0x53, 0xd6, 0x14, 0xa3, 0xb8, 0xa9, 0xb7, 0x12, 0x4f, 0x8c, 0xf8,
+       0xf0, 0x3d, 0xf2, 0xf1, 0x3e, 0xd6, 0x7b, 0x25, 0xe1, 0x47, 0x6f, 0xca,
+       0x87, 0xe7, 0xc9, 0xcb, 0xb7, 0xf2, 0x5c, 0xbe, 0x05, 0x56, 0x60, 0x04,
+       0x91, 0x48, 0x1d, 0x63, 0x6c, 0xbc, 0x02, 0x6b, 0x57, 0x1e, 0x81, 0xda,
+       0x7b, 0x94, 0xc7, 0xf5, 0x8c, 0xd5, 0xd7, 0x23, 0x39, 0x18, 0x41, 0x72,
+       0xe4, 0x87, 0xe8, 0x19, 0x94, 0x71, 0xc9, 0x37, 0xa1, 0x64, 0x6f, 0x91,
+       0x81, 0xf9, 0x8c, 0xa7, 0x43, 0x23, 0xd2, 0x4f, 0x25, 0xfb, 0xfe, 0x4b,
+       0xdb, 0xff, 0x99, 0xb5, 0xf6, 0xf3, 0xd2, 0xf6, 0x91, 0x3f, 0xd1, 0xbe,
+       0xe8, 0x2a, 0xff, 0x6e, 0x9f, 0xac, 0x73, 0xb8, 0xd9, 0xa6, 0x07, 0x8e,
+       0x48, 0x66, 0x65, 0x29, 0xf4, 0xe8, 0x76, 0xc5, 0x68, 0x2a, 0x51, 0x26,
+       0xb1, 0x3d, 0x2d, 0xef, 0x71, 0x15, 0xe2, 0x79, 0x72, 0x02, 0x57, 0x48,
+       0xd7, 0xbe, 0x4d, 0xdb, 0x59, 0x42, 0x8c, 0x39, 0x63, 0x7e, 0x1a, 0x71,
+       0x4d, 0xf4, 0x57, 0x88, 0x57, 0xfb, 0xdd, 0x78, 0x37, 0xc4, 0x98, 0x6d,
+       0xef, 0xa1, 0xf6, 0xe0, 0x27, 0x09, 0x2f, 0xe7, 0xab, 0x36, 0x63, 0x38,
+       0xe6, 0x02, 0x55, 0xd9, 0x6b, 0x27, 0x12, 0x6d, 0xd8, 0x4f, 0x79, 0x5f,
+       0x49, 0x9c, 0xe7, 0xfc, 0xac, 0xa3, 0xfe, 0x45, 0xdf, 0xf1, 0x9c, 0xae,
+       0xbb, 0xa9, 0xeb, 0x99, 0x78, 0x31, 0xf1, 0x30, 0x9e, 0xa0, 0xfc, 0x8f,
+       0xf7, 0x1b, 0xd1, 0x39, 0xca, 0x31, 0x1c, 0x1a, 0x2a, 0x24, 0x7e, 0xbb,
+       0x71, 0x37, 0xb3, 0xe4, 0x49, 0xe9, 0x2b, 0x29, 0x6b, 0x93, 0x0a, 0xb9,
+       0xc7, 0x31, 0x8c, 0xf3, 0xde, 0x4f, 0xf8, 0x3b, 0xbc, 0xb0, 0x9c, 0x7d,
+       0x88, 0x7e, 0xfc, 0x76, 0x1e, 0xd0, 0x45, 0x7e, 0xb3, 0xbc, 0xfe, 0x98,
+       0xcd, 0x79, 0xba, 0x93, 0xad, 0xe8, 0xe9, 0x7f, 0x9f, 0x7c, 0x8e, 0x38,
+       0xe4, 0xad, 0xa7, 0xad, 0x67, 0xb0, 0x3d, 0xf5, 0xef, 0x55, 0x59, 0xee,
+       0xf9, 0x6a, 0x95, 0xec, 0xeb, 0x3d, 0x91, 0x28, 0xc4, 0x4b, 0xac, 0xb3,
+       0x36, 0xe4, 0xca, 0x3d, 0x2f, 0x39, 0x86, 0x5e, 0xe2, 0x6a, 0x8a, 0x7d,
+       0x24, 0xec, 0x36, 0xaa, 0x94, 0xbd, 0xf4, 0xc3, 0xf2, 0x85, 0x55, 0x4a,
+       0x92, 0xe7, 0x7d, 0xc9, 0x1f, 0xe2, 0xd9, 0x47, 0xb2, 0x3a, 0xdc, 0x6f,
+       0xb6, 0x61, 0x28, 0x75, 0x2a, 0xd7, 0xde, 0x8f, 0xa7, 0xbc, 0x9b, 0x26,
+       0xef, 0xba, 0xe4, 0xdf, 0x7b, 0xc9, 0x3e, 0xcf, 0x7a, 0x2a, 0x5d, 0x46,
+       0xde, 0x5c, 0x4c, 0x5b, 0x2b, 0x88, 0x79, 0x19, 0x4f, 0xdb, 0x16, 0x68,
+       0xd8, 0x75, 0xcd, 0x9c, 0x2a, 0x94, 0x69, 0xee, 0x5f, 0xd7, 0xbf, 0xcc,
+       0x7e, 0xca, 0x62, 0x15, 0x91, 0x8c, 0xbd, 0x07, 0x2a, 0x74, 0x4d, 0x35,
+       0x73, 0x68, 0x79, 0x2e, 0x1c, 0xc3, 0xdb, 0x89, 0xca, 0x58, 0x65, 0xa4,
+       0x9c, 0x78, 0x7b, 0x0e, 0xbd, 0xc3, 0xc4, 0x76, 0xf2, 0xe5, 0xd2, 0xbe,
+       0x4a, 0xb8, 0xed, 0x35, 0xbc, 0x2b, 0x30, 0x63, 0xf7, 0x2c, 0xf8, 0x76,
+       0xcf, 0x24, 0x5f, 0x61, 0x6e, 0x19, 0xb2, 0xac, 0x9f, 0x2f, 0xb4, 0xac,
+       0x2b, 0x79, 0x14, 0xf1, 0x38, 0x1b, 0x12, 0x3f, 0x8d, 0xa2, 0xd6, 0xf6,
+       0x57, 0x03, 0x75, 0xf6, 0xff, 0x46, 0xfa, 0x7a, 0x47, 0x68, 0xfe, 0xf8,
+       0xc3, 0xa1, 0xb9, 0xe3, 0xd5, 0x50, 0x07, 0xa6, 0xc1, 0xc1, 0xb6, 0x3e,
+       0x77, 0x8d, 0x85, 0x46, 0xfa, 0xf0, 0x1a, 0x53, 0xf8, 0x50, 0x1b, 0xf9,
+       0x50, 0x4f, 0xc8, 0x18, 0x3f, 0x82, 0x1b, 0xc9, 0x97, 0xdd, 0x03, 0x3e,
+       0xf6, 0x23, 0xf9, 0xb5, 0x33, 0x33, 0x9b, 0x3c, 0xfb, 0xd3, 0x0b, 0x85,
+       0x1b, 0xb5, 0x90, 0x1b, 0x1d, 0x45, 0xcb, 0xf8, 0x31, 0xdc, 0xca, 0x32,
+       0x1e, 0xe6, 0xfd, 0x7d, 0xe9, 0x1f, 0x92, 0x77, 0x58, 0x8c, 0x39, 0x19,
+       0xdc, 0xcc, 0xb6, 0x8b, 0x07, 0x9a, 0x70, 0xf7, 0xf8, 0x0a, 0xac, 0x1d,
+       0xb7, 0xb0, 0x3c, 0x34, 0x81, 0xe5, 0xe3, 0xe4, 0x9a, 0xe3, 0x79, 0x7f,
+       0x15, 0x9e, 0xb4, 0x82, 0x3c, 0x49, 0xe2, 0xd0, 0x2a, 0x7b, 0x1d, 0x4d,
+       0xa5, 0x1f, 0x36, 0x24, 0xe4, 0x9d, 0x9b, 0x38, 0x56, 0x8f, 0x0b, 0x56,
+       0x3f, 0x88, 0x4d, 0xe3, 0xb2, 0x2e, 0xfb, 0xf5, 0xd0, 0x9c, 0xf1, 0xd7,
+       0xd1, 0x30, 0x3e, 0x14, 0x9a, 0x37, 0x3e, 0x42, 0xb9, 0x13, 0x94, 0xad,
+       0x3f, 0x54, 0x33, 0x3e, 0x18, 0x0a, 0x8e, 0xef, 0x0d, 0x05, 0xc6, 0x9b,
+       0xb1, 0x75, 0x7c, 0x15, 0xb6, 0x8c, 0xb7, 0x63, 0xf3, 0xb8, 0xe0, 0xfc,
+       0x24, 0x96, 0x8d, 0x9f, 0xc1, 0xd2, 0xf1, 0x97, 0xd1, 0x38, 0x7e, 0x0a,
+       0x4b, 0xc6, 0x7f, 0x88, 0xa6, 0xf1, 0x1f, 0x73, 0x2c, 0xb2, 0xce, 0x2b,
+       0x6b, 0xbc, 0xf9, 0x67, 0x6a, 0xf9, 0xf7, 0x44, 0xf3, 0xdf, 0xd7, 0x70,
+       0x21, 0xaa, 0xbd, 0x81, 0xee, 0x3d, 0xf2, 0xbd, 0xc1, 0x5a, 0x6d, 0x93,
+       0xfd, 0xbe, 0xc1, 0xcb, 0xb2, 0x4f, 0x1d, 0x45, 0xc6, 0xe5, 0xef, 0xc5,
+       0xcb, 0x77, 0x31, 0xe4, 0x39, 0xe7, 0x24, 0xba, 0xd2, 0xe7, 0xad, 0xa8,
+       0x26, 0x65, 0xde, 0xc0, 0xe6, 0x3d, 0xf2, 0x3e, 0x71, 0x06, 0x5d, 0x49,
+       0x79, 0x0e, 0x2f, 0xef, 0xa0, 0xbf, 0x81, 0x2d, 0xa3, 0xb6, 0xaf, 0xa1,
+       0x71, 0x48, 0xde, 0x89, 0x69, 0xc3, 0x75, 0xc9, 0x8c, 0xbd, 0x56, 0x5e,
+       0x66, 0xe0, 0xef, 0x67, 0xe0, 0x41, 0xe6, 0x04, 0x05, 0xe4, 0xfd, 0xc5,
+       0xe8, 0x7c, 0x24, 0x6e, 0x15, 0x1a, 0x1e, 0xcc, 0x88, 0x18, 0x99, 0x77,
+       0x1d, 0xc5, 0xe8, 0xe0, 0xb5, 0xfb, 0x76, 0xc2, 0xef, 0x33, 0x44, 0xf7,
+       0x81, 0xd8, 0x28, 0x63, 0xec, 0x86, 0x7d, 0x19, 0xf2, 0x8b, 0x0e, 0xf8,
+       0xf9, 0x7f, 0x7b, 0x52, 0xf6, 0x21, 0x6d, 0x42, 0x74, 0x9f, 0xe8, 0xb0,
+       0x99, 0x3a, 0x9c, 0x64, 0xdc, 0x90, 0x67, 0x38, 0x46, 0x70, 0x2b, 0x64,
+       0x9d, 0x52, 0xc5, 0xf7, 0x06, 0xe5, 0x79, 0x83, 0xde, 0xf1, 0x25, 0xfa,
+       0xf4, 0x87, 0xca, 0x0f, 0x51, 0x76, 0x40, 0xf8, 0xd2, 0x04, 0x7a, 0x84,
+       0x6f, 0x47, 0x14, 0x23, 0x15, 0x38, 0x0b, 0xcf, 0x01, 0xc1, 0x5d, 0x27,
+       0x4a, 0xc6, 0xe4, 0xfb, 0x38, 0x40, 0x31, 0xf3, 0x12, 0x1c, 0x20, 0xa7,
+       0x3d, 0x70, 0x0a, 0xd8, 0x27, 0xeb, 0x56, 0xaf, 0x61, 0x72, 0x48, 0xe6,
+       0xad, 0x8d, 0xf3, 0x26, 0x7e, 0xf8, 0x7d, 0x0c, 0x0f, 0x79, 0xe8, 0xe3,
+       0x13, 0x1c, 0xc7, 0xeb, 0x78, 0x74, 0x8f, 0x3c, 0x17, 0x99, 0x89, 0x36,
+       0xd6, 0x3b, 0xc1, 0x3c, 0xbf, 0x75, 0xcc, 0xe4, 0x78, 0x56, 0xa1, 0xf3,
+       0xc0, 0x17, 0x78, 0x4c, 0xc3, 0x43, 0x07, 0xd6, 0x71, 0x8c, 0x71, 0x74,
+       0x8c, 0x75, 0xf3, 0x68, 0xc5, 0xc6, 0x9d, 0x26, 0xb9, 0xa0, 0xd8, 0xb4,
+       0x46, 0x3f, 0x6b, 0xe5, 0x98, 0xa4, 0x8f, 0xd5, 0xf8, 0x19, 0x31, 0xa6,
+       0x29, 0xb4, 0x1a, 0xe7, 0x6c, 0xbf, 0x5b, 0x8d, 0x2d, 0xfd, 0x46, 0xf0,
+       0x24, 0x56, 0x63, 0x33, 0xcf, 0x1f, 0xa5, 0xef, 0xcf, 0x21, 0x17, 0xbc,
+       0x93, 0xbe, 0xbd, 0x78, 0x78, 0x42, 0xbe, 0x9d, 0x80, 0xbe, 0x5d, 0x32,
+       0x1f, 0x6d, 0xf0, 0x8d, 0x65, 0x50, 0x3e, 0xc6, 0xec, 0x79, 0x27, 0xee,
+       0x2a, 0x43, 0x39, 0xbe, 0x11, 0x92, 0x3d, 0x0b, 0x3f, 0x40, 0xf1, 0x3e,
+       0x91, 0xf5, 0x87, 0x6c, 0xfb, 0x1c, 0x73, 0xf1, 0x53, 0x9c, 0x83, 0xfc,
+       0xb3, 0xf1, 0x5f, 0xe0, 0x60, 0x6a, 0x92, 0xb8, 0x7a, 0x9a, 0xc7, 0xe5,
+       0xcf, 0xa5, 0xbd, 0x76, 0x8e, 0x92, 0xdd, 0xff, 0xed, 0xc4, 0x8c, 0x3e,
+       0x59, 0xdf, 0x6d, 0x86, 0x2f, 0x29, 0x7c, 0x27, 0xb3, 0x8d, 0xf9, 0x4a,
+       0x7b, 0xd8, 0xe6, 0x3f, 0x46, 0x8c, 0xbc, 0xa7, 0xf9, 0xdb, 0x8a, 0x87,
+       0xbc, 0x27, 0x88, 0x15, 0x69, 0x3d, 0x7a, 0x33, 0xf5, 0x5b, 0xf4, 0xc8,
+       0x8f, 0xe0, 0x7c, 0xc4, 0x89, 0x42, 0xe6, 0x37, 0xa1, 0x90, 0xe8, 0x59,
+       0xde, 0x95, 0xcd, 0xe8, 0x85, 0xc4, 0xcc, 0x82, 0xbe, 0x0c, 0xe7, 0x27,
+       0x33, 0xbf, 0x00, 0x7e, 0xce, 0xcd, 0x0d, 0x68, 0xeb, 0x8f, 0x72, 0x6e,
+       0x3e, 0x45, 0x1b, 0x9b, 0xa0, 0xbd, 0x48, 0x4e, 0xf4, 0x32, 0x65, 0x74,
+       0xe5, 0xbe, 0xc9, 0x93, 0xd1, 0x9d, 0xd0, 0x4d, 0xbf, 0x5a, 0x95, 0x7d,
+       0x27, 0x05, 0xf6, 0xb3, 0xe7, 0x30, 0xf0, 0x06, 0x6d, 0x33, 0xcf, 0x67,
+       0x2c, 0xab, 0x9d, 0xf6, 0xd5, 0x3f, 0x2a, 0xbe, 0xb2, 0xb4, 0x2a, 0xfb,
+       0xbe, 0xee, 0x54, 0xae, 0x93, 0xaf, 0xeb, 0x20, 0x36, 0xe6, 0xef, 0xff,
+       0x08, 0x77, 0x32, 0x7e, 0x9d, 0x59, 0x78, 0x2a, 0x67, 0xf3, 0xd3, 0xab,
+       0xb3, 0xf8, 0xf5, 0x49, 0xdf, 0x0b, 0xfa, 0x2b, 0xfb, 0xdb, 0x3b, 0xd9,
+       0x6f, 0x1f, 0x01, 0xcf, 0x26, 0x0a, 0xe4, 0x29, 0xc1, 0x62, 0x17, 0x54,
+       0xaf, 0x0b, 0x85, 0x8c, 0x01, 0xd5, 0xd8, 0xe4, 0xb5, 0x70, 0xa3, 0x59,
+       0x80, 0x43, 0x75, 0xb7, 0x00, 0x15, 0xf1, 0x16, 0x97, 0xfd, 0x4e, 0xde,
+       0xef, 0xbf, 0xf4, 0x87, 0xef, 0xe4, 0x9d, 0xb1, 0xf3, 0xe1, 0x52, 0xe3,
+       0x76, 0xbc, 0x62, 0xc7, 0x09, 0x05, 0x25, 0x73, 0x65, 0x5d, 0xd2, 0x8f,
+       0x17, 0x8d, 0x5a, 0x7f, 0x85, 0x3c, 0x6f, 0x52, 0xce, 0x5a, 0x71, 0xaf,
+       0xbc, 0x87, 0xf7, 0xc7, 0xf6, 0x8f, 0x3f, 0x87, 0xad, 0xbb, 0xc2, 0x90,
+       0xf7, 0x3b, 0x9c, 0x46, 0xa1, 0x37, 0x2b, 0xbf, 0xc8, 0x26, 0xeb, 0x44,
+       0xb7, 0x71, 0x1c, 0x67, 0xe8, 0x8b, 0x67, 0xec, 0x75, 0x2a, 0xb7, 0xf1,
+       0xd7, 0x08, 0x56, 0xe4, 0xc7, 0x2f, 0x39, 0x8d, 0x92, 0xd5, 0x41, 0xf6,
+       0xfd, 0xda, 0x6a, 0xc1, 0xfe, 0x2d, 0xc9, 0x33, 0xf6, 0x9a, 0xac, 0xcb,
+       0xf8, 0x0f, 0xeb, 0x2d, 0x6f, 0x25, 0xcb, 0x3e, 0x95, 0xbb, 0x3f, 0x29,
+       0xeb, 0x38, 0xa6, 0x7c, 0xbb, 0xca, 0x69, 0xd7, 0x11, 0xbd, 0x5f, 0xac,
+       0xb3, 0x89, 0xbc, 0x7a, 0xb6, 0x71, 0xca, 0xea, 0xf4, 0xca, 0x18, 0xd6,
+       0x5c, 0x56, 0x47, 0xd6, 0x08, 0x34, 0xe9, 0x37, 0x2c, 0x63, 0xee, 0x4a,
+       0xff, 0x61, 0x9f, 0xb2, 0x7e, 0x5b, 0x60, 0x94, 0xe0, 0x6c, 0x45, 0x76,
+       0x4d, 0xe5, 0xa2, 0x8c, 0xed, 0xd5, 0xb2, 0xef, 0xae, 0xd0, 0x3e, 0xb7,
+       0xfb, 0x35, 0x2f, 0xd6, 0x7b, 0x30, 0x37, 0xde, 0x4a, 0xfb, 0x9d, 0x9a,
+       0x47, 0x6d, 0xae, 0xe3, 0x98, 0x32, 0xee, 0xdf, 0x78, 0x2f, 0xed, 0xe7,
+       0xf3, 0xb9, 0x7e, 0x45, 0x1e, 0xef, 0x94, 0x3e, 0x44, 0xae, 0xde, 0x5c,
+       0x1d, 0x3d, 0x1c, 0xb5, 0xfb, 0x57, 0x11, 0xde, 0x93, 0xef, 0xd3, 0xb2,
+       0x0a, 0x16, 0xe6, 0xdb, 0xc8, 0xd0, 0x0f, 0xad, 0xce, 0x42, 0xc6, 0xab,
+       0xb3, 0xf5, 0x0f, 0x62, 0x73, 0x42, 0xf4, 0x2c, 0xdf, 0x70, 0x25, 0x2e,
+       0xdb, 0xfc, 0xcb, 0xc5, 0x5c, 0xf6, 0x1a, 0x0c, 0x69, 0x71, 0xec, 0xaf,
+       0x93, 0x77, 0xc8, 0x5c, 0xf4, 0x85, 0x38, 0x71, 0xb0, 0x90, 0x38, 0x1a,
+       0xb7, 0xf7, 0x94, 0x1c, 0x34, 0xf5, 0xe8, 0xb3, 0xf2, 0x8d, 0xb2, 0xab,
+       0xec, 0xb5, 0xa7, 0xa6, 0x21, 0xc8, 0xf5, 0xfc, 0x7a, 0x52, 0xfe, 0xaf,
+       0x88, 0xb6, 0x23, 0x72, 0x89, 0x0d, 0x50, 0xba, 0x84, 0xbc, 0xeb, 0x54,
+       0x1b, 0x23, 0x67, 0xc4, 0x2b, 0x29, 0xd9, 0x7f, 0xf0, 0x5b, 0x2b, 0x5e,
+       0x2d, 0xfb, 0x1c, 0xa7, 0xd6, 0x29, 0x20, 0x97, 0x0b, 0x84, 0xcb, 0x94,
+       0xfc, 0xfb, 0x4e, 0x17, 0xff, 0x6e, 0xa5, 0xcd, 0x9c, 0xb3, 0xdf, 0x51,
+       0x93, 0xb3, 0x08, 0x1a, 0x92, 0xf2, 0xad, 0x52, 0x7d, 0x62, 0x39, 0x6a,
+       0x33, 0x35, 0x0e, 0x67, 0x8e, 0x93, 0x84, 0xb1, 0x82, 0x76, 0xb3, 0x25,
+       0x10, 0xb6, 0xdf, 0xc5, 0x5a, 0x96, 0xac, 0x09, 0x3e, 0xce, 0x1c, 0xfa,
+       0x1d, 0x96, 0xbf, 0x25, 0xfd, 0x3d, 0x6b, 0xc8, 0x2b, 0x63, 0xca, 0x63,
+       0xc3, 0x29, 0xfa, 0x06, 0xf5, 0x18, 0x11, 0xff, 0xf0, 0xa0, 0x22, 0x12,
+       0xa6, 0xff, 0x4a, 0x4c, 0x97, 0xf7, 0xb8, 0xf4, 0xbd, 0x71, 0x98, 0xc4,
+       0xfc, 0x1e, 0xda, 0x91, 0xec, 0x5b, 0xd6, 0xfd, 0x2b, 0x19, 0x5b, 0x8e,
+       0x5f, 0x78, 0xc6, 0x2f, 0x1c, 0xe0, 0xd9, 0xea, 0xdc, 0xde, 0x66, 0xf7,
+       0x6c, 0xc6, 0x3c, 0xcb, 0x7e, 0x6e, 0xdf, 0x66, 0x63, 0x8a, 0x66, 0xe8,
+       0x87, 0x7e, 0xe5, 0xe8, 0xc4, 0xd3, 0x0b, 0x8c, 0x8e, 0xc3, 0x6a, 0x66,
+       0xc8, 0x47, 0x7c, 0xb9, 0xde, 0x11, 0xdd, 0xc9, 0xff, 0xfe, 0xd7, 0xec,
+       0x6f, 0xab, 0x48, 0x5d, 0x3d, 0xb8, 0x4a, 0x95, 0xfd, 0x40, 0xcd, 0x18,
+       0xeb, 0x95, 0x77, 0x06, 0xf4, 0x96, 0xa7, 0x94, 0x4e, 0x6c, 0x08, 0x19,
+       0xcd, 0xed, 0x8a, 0xde, 0xf4, 0x0f, 0x8a, 0xee, 0x0f, 0x29, 0x52, 0x2e,
+       0xc8, 0xbc, 0xeb, 0x62, 0x3c, 0x75, 0xb1, 0x8f, 0x03, 0x09, 0x3d, 0x5c,
+       0xc5, 0xb2, 0x67, 0x4d, 0xc3, 0xf7, 0x3e, 0xdb, 0xfc, 0x57, 0x1e, 0x3b,
+       0xed, 0xf7, 0xc4, 0xa5, 0x7c, 0x74, 0xbe, 0xcb, 0xfe, 0xbe, 0x69, 0x0b,
+       0xe3, 0xae, 0x7c, 0x23, 0x38, 0x06, 0xad, 0x6f, 0x26, 0x4d, 0x4c, 0xef,
+       0xb9, 0x0d, 0xb2, 0xe7, 0xa0, 0x89, 0x09, 0xba, 0x07, 0xde, 0x48, 0x27,
+       0xe6, 0x2e, 0x30, 0x7c, 0x8b, 0x54, 0xbb, 0x7e, 0x30, 0xaa, 0x4a, 0x7d,
+       0xdd, 0x3f, 0x08, 0x69, 0x23, 0x63, 0x69, 0x73, 0xcb, 0xed, 0x3a, 0x0b,
+       0xd4, 0xcf, 0xc0, 0x75, 0xf5, 0xaf, 0xe5, 0x5b, 0x46, 0x5a, 0xa5, 0x21,
+       0x75, 0xe2, 0x3b, 0x35, 0xfc, 0xb1, 0x7a, 0x82, 0x2b, 0xbf, 0xb2, 0x30,
+       0x4d, 0xea, 0xc9, 0x9e, 0xb1, 0x3b, 0x70, 0xaf, 0xfd, 0x3d, 0x16, 0xf1,
+       0x47, 0x3d, 0xfa, 0x15, 0xf2, 0xcf, 0x62, 0x45, 0xb8, 0xa7, 0xf0, 0x84,
+       0x56, 0x74, 0x33, 0x8e, 0x69, 0x21, 0xbd, 0xe7, 0x0a, 0xd5, 0x83, 0xc2,
+       0xc8, 0x63, 0xb2, 0x6f, 0x66, 0xef, 0x3c, 0x35, 0xbb, 0xbf, 0x26, 0xc6,
+       0x76, 0x8f, 0xff, 0xd1, 0xe7, 0xb8, 0xec, 0xab, 0xd8, 0x94, 0xf7, 0x5b,
+       0xec, 0x35, 0xc5, 0xd6, 0x84, 0x23, 0xb7, 0x5f, 0x30, 0x3f, 0xb7, 0x1a,
+       0xda, 0xc8, 0xf5, 0xd7, 0xc8, 0x37, 0x31, 0x39, 0xd6, 0xb5, 0x09, 0x59,
+       0x4d, 0xfa, 0xff, 0x00, 0x85, 0x57, 0x0f, 0xe7, 0xe8, 0x59, 0x00, 0x00,
+       0x00 };
+
+static const u32 bnx2_CP_b06FwData[(0x84/4) + 1] = {
+       0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
+       0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
+       0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
+       0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+       0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+       0x00000001, 0x00000001, 0x00000001, 0x00000000 };
+static const u32 bnx2_CP_b06FwRodata[(0x130/4) + 1] = {
+       0x08001f1c, 0x08001da8, 0x08001ef8, 0x08001ed4, 0x08001eb0, 0x08001e8c,
+       0x08001e64, 0x08001e3c, 0x08001e10, 0x08002014, 0x08002004, 0x08001dc4,
+       0x08001dc4, 0x08001dc4, 0x08001f44, 0x08001f44, 0x08001dc4, 0x08001dc4,
+       0x08001ff4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001fe4,
+       0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
+       0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
+       0x08001dc4, 0x08001dc4, 0x08001fd4, 0x08001dc4, 0x08001dc4, 0x08001fc4,
+       0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
+       0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4,
+       0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001dc4, 0x08001fac,
+       0x08001dc4, 0x08001dc4, 0x08001f9c, 0x08001f8c, 0x080031e8, 0x080031f0,
+       0x080031b8, 0x080031c4, 0x080031d0, 0x080031dc, 0x08005644, 0x08005604,
+       0x080055d0, 0x080055a4, 0x08005580, 0x0800553c, 0x00000000 };
+
+static struct fw_info bnx2_cp_fw_06 = {
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
+
+       .start_addr                     = 0x08000078,
+
+       .text_addr                      = 0x08000000,
+       .text_len                       = 0x59e4,
+       .text_index                     = 0x0,
+       .gz_text                        = bnx2_CP_b06FwText,
+       .gz_text_len                    = sizeof(bnx2_CP_b06FwText),
+
+       .data_addr                      = 0x08005b40,
+       .data_len                       = 0x84,
+       .data_index                     = 0x0,
+       .data                           = bnx2_CP_b06FwData,
+
+       .sbss_addr                      = 0x08005bc4,
+       .sbss_len                       = 0xe9,
+       .sbss_index                     = 0x0,
+
+       .bss_addr                       = 0x08005cb0,
+       .bss_len                        = 0x5d8,
+       .bss_index                      = 0x0,
+
+       .rodata_addr                    = 0x080059e4,
+       .rodata_len                     = 0x130,
+       .rodata_index                   = 0x0,
+       .rodata                         = bnx2_CP_b06FwRodata,
+};
+
 static u8 bnx2_RXP_b06FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x08, 0xcb, 0xa3, 0x46, 0x45, 0x00, 0x03, 0x74, 0x65,
-       0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
-                                                       0xec, 0x5c, 0x6f, 0x6c,
-       0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x4e, 0xd4, 0x91, 0x5c, 0x1e,
-       0x4f, 0xf4, 0x49, 0x66, 0x94, 0x5d, 0x71, 0x25, 0x5e, 0x2d, 0xc6, 0x5d,
-       0x31, 0x57, 0x9b, 0x08, 0xce, 0xf1, 0x79, 0xef, 0x64, 0xb1, 0x86, 0x0a,
-       0x51, 0x0d, 0x1d, 0x1b, 0x85, 0x6b, 0xb0, 0x47, 0x39, 0xae, 0xdb, 0x7e,
-       0x90, 0x65, 0x1b, 0x30, 0xda, 0x10, 0xbe, 0x1c, 0xe9, 0x46, 0x75, 0x2f,
-       0xdc, 0x8b, 0xc4, 0x98, 0x06, 0xfa, 0x07, 0x57, 0x92, 0xfa, 0x83, 0xe0,
-       0xa0, 0x93, 0xe2, 0x26, 0xf5, 0x17, 0x57, 0x84, 0x2a, 0xc7, 0xf9, 0xe0,
-       0x02, 0x4e, 0x63, 0x20, 0x06, 0xea, 0x16, 0xaa, 0xec, 0xd8, 0x46, 0x81,
-       0xa2, 0x42, 0x1c, 0xd8, 0x46, 0xfc, 0x67, 0xfb, 0x7b, 0x33, 0xbb, 0xd4,
-       0x91, 0x96, 0x6d, 0xa0, 0x1f, 0xfa, 0xa5, 0x3b, 0xc0, 0x61, 0x67, 0x66,
-       0xe7, 0xbd, 0x79, 0xf3, 0xfe, 0xbf, 0x59, 0x4a, 0x7f, 0x90, 0xa4, 0x2e,
-       0x0a, 0x5b, 0x37, 0x7e, 0xd6, 0x91, 0xc7, 0x8f, 0xde, 0x3c, 0x76, 0xf3,
-       0x28, 0xd1, 0x97, 0x47, 0xf5, 0x1b, 0x12, 0x22, 0x9a, 0x8f, 0x5b, 0xdc,
-       0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2,
-       0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16,
-       0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7,
-       0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8,
-       0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5,
-       0x2d, 0x6e, 0x71, 0xfb, 0xff, 0xde, 0x74, 0x22, 0x93, 0x9f, 0xdd, 0xe1,
-       0x8f, 0x12, 0x22, 0xbf, 0xfa, 0x90, 0xe7, 0x50, 0x42, 0xcf, 0xbf, 0x34,
-       0x33, 0xed, 0x10, 0x15, 0x9a, 0x7b, 0xac, 0x22, 0x7d, 0x14, 0x54, 0xd2,
-       0x06, 0xf1, 0xfc, 0x17, 0xf2, 0x1f, 0x3e, 0xf1, 0xfc, 0xad, 0xf6, 0xd5,
-       0x86, 0x4e, 0x09, 0x33, 0x3f, 0xb7, 0xd7, 0xdc, 0x4d, 0x89, 0x41, 0xc0,
-       0xfc, 0xf5, 0xf0, 0x7f, 0xf4, 0x50, 0x0f, 0x5d, 0xc3, 0xe3, 0x24, 0xe8,
-       0xb2, 0xfe, 0x9c, 0xe6, 0xb5, 0x82, 0xe0, 0xa4, 0x1b, 0x04, 0x3f, 0xc6,
-       0xef, 0x2d, 0x17, 0x63, 0xff, 0xe3, 0xa0, 0x60, 0xe8, 0x24, 0x9c, 0xbf,
-       0xd4, 0xbc, 0xe5, 0x2e, 0xaa, 0x2e, 0x1a, 0x34, 0xeb, 0xa7, 0xe9, 0x98,
-       0x5f, 0xd1, 0x4a, 0xad, 0x9a, 0xb6, 0xef, 0xf4, 0xbc, 0x76, 0xe7, 0xe9,
-       0x63, 0xda, 0xfe, 0xd3, 0x75, 0xcd, 0x3b, 0x4d, 0x15, 0xb1, 0x37, 0x49,
-       0x05, 0xf3, 0x8c, 0x56, 0x6c, 0x0d, 0x68, 0xde, 0x89, 0x0f, 0xc9, 0x73,
-       0x6d, 0xf3, 0xf7, 0xc8, 0x28, 0x80, 0x16, 0xf2, 0x6a, 0x41, 0xe0, 0xb9,
-       0x06, 0x15, 0xd2, 0x41, 0x20, 0xf2, 0xc1, 0x13, 0x5e, 0xce, 0x31, 0x85,
-       0x96, 0xa6, 0x6a, 0x6b, 0x00, 0x78, 0x93, 0x5a, 0x71, 0xd1, 0xd0, 0x4a,
-       0x7e, 0x70, 0xc1, 0x73, 0x69, 0x50, 0xa7, 0x20, 0x98, 0x73, 0x77, 0x65,
-       0x0e, 0xd3, 0x29, 0xe0, 0x6d, 0x02, 0x1f, 0x99, 0x22, 0xcf, 0xf4, 0x31,
-       0x9d, 0x4c, 0x72, 0x45, 0x2b, 0x0e, 0x47, 0xf4, 0x91, 0xc5, 0xf4, 0x97,
-       0x57, 0x04, 0xe8, 0xdc, 0x42, 0xe5, 0x86, 0x49, 0x53, 0x2b, 0x1b, 0xd7,
-       0x5f, 0x0e, 0x9e, 0x1f, 0x36, 0xe9, 0x5c, 0xcb, 0xae, 0x54, 0x28, 0x41,
-       0x73, 0xbe, 0x45, 0x22, 0x4f, 0x05, 0x2f, 0x37, 0x48, 0x17, 0x5a, 0x19,
-       0xfa, 0x41, 0xcb, 0xc9, 0x54, 0x69, 0x13, 0x95, 0xd3, 0x69, 0x3a, 0xdf,
-       0x4a, 0xe3, 0x8c, 0xc1, 0x05, 0xe1, 0x38, 0x66, 0x15, 0x6b, 0xab, 0xad,
-       0x97, 0xf8, 0xdf, 0xbf, 0x98, 0xd3, 0x39, 0x09, 0x53, 0x01, 0xdd, 0xe1,
-       0x5a, 0x3e, 0x87, 0x5c, 0x2b, 0xcf, 0xa2, 0xd6, 0x52, 0x65, 0x3a, 0x87,
-       0xb9, 0xd6, 0x1d, 0x6b, 0xfc, 0x2d, 0xa4, 0xf9, 0x69, 0x52, 0xd5, 0xef,
-       0x00, 0x6f, 0xb8, 0x3f, 0x88, 0xb3, 0xee, 0xd0, 0xbc, 0xc5, 0x7f, 0x65,
-       0xbc, 0x69, 0x41, 0x3b, 0x30, 0x1e, 0xc4, 0x98, 0xfb, 0xbb, 0x32, 0x65,
-       0x02, 0x8f, 0x5b, 0x49, 0x8c, 0x99, 0xce, 0x20, 0xd8, 0xef, 0x92, 0x59,
-       0x75, 0x7b, 0x01, 0x6b, 0x51, 0xd5, 0xed, 0x01, 0xbe, 0x0e, 0xea, 0x73,
-       0xf8, 0x7c, 0xbc, 0xe7, 0x66, 0xcc, 0x07, 0xdd, 0x7a, 0x3e, 0x08, 0xa6,
-       0x73, 0xd4, 0xa3, 0xe6, 0xf6, 0x48, 0x1c, 0x53, 0x13, 0x1a, 0xd6, 0xbd,
-       0xc3, 0x7b, 0x24, 0x52, 0x79, 0xee, 0xf3, 0x33, 0x47, 0xde, 0xfc, 0x8e,
-       0x90, 0xa6, 0x0c, 0x68, 0xba, 0x31, 0xec, 0x43, 0x0e, 0x3e, 0xf8, 0xe1,
-       0xde, 0x80, 0xb1, 0xf6, 0x45, 0xe0, 0xc9, 0x56, 0x89, 0xf7, 0xe8, 0xa7,
-       0xa5, 0x34, 0x89, 0x2b, 0x6e, 0x5f, 0xb8, 0xae, 0x07, 0xb4, 0x46, 0xfa,
-       0x30, 0x40, 0x73, 0x8b, 0xcc, 0xf3, 0x1a, 0x64, 0x24, 0x68, 0xe7, 0x2d,
-       0x15, 0xad, 0xd0, 0x3a, 0x86, 0xbe, 0x41, 0xd3, 0x4e, 0x70, 0x61, 0xce,
-       0x9d, 0xd7, 0x8a, 0xa7, 0x4f, 0x69, 0xa5, 0xd3, 0xcf, 0x69, 0xfb, 0x5a,
-       0x2f, 0x76, 0x53, 0x97, 0x8d, 0xd3, 0x27, 0xe8, 0x49, 0x5f, 0x23, 0xa6,
-       0x73, 0x09, 0x3c, 0x2c, 0x98, 0x15, 0x32, 0x9c, 0x1e, 0xed, 0x4e, 0xe0,
-       0xe9, 0x70, 0xfe, 0x2c, 0x49, 0x3d, 0x3a, 0x6d, 0x72, 0xa2, 0xb5, 0x69,
-       0xfa, 0x73, 0xd0, 0x74, 0xd1, 0xdd, 0xca, 0x7c, 0xeb, 0x55, 0x30, 0xa9,
-       0x90, 0x0e, 0xd6, 0x2f, 0x96, 0x9f, 0x6d, 0x7a, 0xba, 0xa0, 0xd2, 0xc2,
-       0x5f, 0xf4, 0x57, 0x47, 0xb6, 0xf0, 0x3a, 0xd8, 0xc2, 0xd5, 0x87, 0xa6,
-       0x1d, 0xaf, 0xcf, 0xa0, 0x8a, 0x29, 0xc8, 0x36, 0x8b, 0xf4, 0x45, 0x9a,
-       0x73, 0x89, 0x8a, 0x35, 0xec, 0xeb, 0x18, 0xe0, 0x8f, 0x03, 0xfe, 0xec,
-       0xaa, 0xe8, 0xe2, 0x1e, 0xa0, 0xa9, 0x68, 0x46, 0xc8, 0xcb, 0x25, 0xba,
-       0x4b, 0xc2, 0x8b, 0xbc, 0x0b, 0x5d, 0xed, 0xe2, 0x3e, 0xf6, 0x4e, 0xc8,
-       0xbd, 0xf5, 0xbc, 0x93, 0x59, 0x26, 0xd2, 0x44, 0x7e, 0x0f, 0xf0, 0xb1,
-       0x0e, 0xf3, 0xba, 0x79, 0xd0, 0xc9, 0xf4, 0x73, 0xdf, 0x01, 0x4c, 0x02,
-       0xfa, 0xde, 0xdd, 0x46, 0x2b, 0xe8, 0x49, 0x33, 0xbf, 0x99, 0x7f, 0xf2,
-       0xac, 0xda, 0xb5, 0xb3, 0x7e, 0x10, 0x0c, 0x8f, 0x1a, 0xf4, 0x63, 0x79,
-       0x66, 0xb6, 0x37, 0x5e, 0x97, 0x0e, 0xf5, 0x23, 0x01, 0x9d, 0x22, 0xad,
-       0xec, 0x9a, 0x6b, 0xb8, 0xca, 0x44, 0x42, 0xcf, 0x27, 0xa9, 0x28, 0xe9,
-       0x1b, 0xc3, 0x5e, 0x6c, 0x87, 0xb0, 0x27, 0x87, 0xcf, 0xc2, 0x73, 0x79,
-       0xd8, 0xbb, 0xcd, 0x7d, 0x2a, 0xd7, 0xd9, 0xf6, 0x99, 0xb6, 0x55, 0x5b,
-       0xfe, 0xd3, 0x2c, 0x89, 0x4f, 0x0c, 0xe8, 0xd4, 0x4b, 0x13, 0xee, 0x87,
-       0x81, 0xd8, 0x8d, 0xf7, 0x23, 0x19, 0xd0, 0x66, 0x5b, 0xb0, 0xca, 0x94,
-       0x4e, 0x1a, 0xe8, 0xde, 0x93, 0x31, 0xc9, 0xc1, 0xd9, 0xc0, 0xdf, 0x89,
-       0x55, 0x30, 0xff, 0xd3, 0xe8, 0x54, 0x78, 0x41, 0x66, 0xc1, 0x03, 0x8d,
-       0x9e, 0xfb, 0x65, 0xc9, 0x33, 0x13, 0xe7, 0xd7, 0xe7, 0x99, 0xbf, 0x5d,
-       0xb0, 0x0b, 0x8d, 0xca, 0x2e, 0xe3, 0x8e, 0x70, 0x08, 0x1a, 0xbe, 0xa5,
-       0x1d, 0x47, 0x24, 0x5f, 0xd6, 0x5d, 0x83, 0x46, 0x47, 0x79, 0x2d, 0xaf,
-       0xe3, 0xf5, 0xf6, 0x98, 0x25, 0x3e, 0x08, 0xf6, 0xae, 0xdb, 0xd3, 0x21,
-       0x31, 0x0f, 0x9a, 0x95, 0x2c, 0xc0, 0xc3, 0xcf, 0x5b, 0xcb, 0x72, 0xd8,
-       0xc8, 0x6f, 0x5e, 0xdb, 0xbe, 0x0e, 0xfa, 0x3c, 0xc0, 0x34, 0x9c, 0x4c,
-       0x2a, 0x3b, 0x8d, 0x68, 0x8a, 0x64, 0xa9, 0x85, 0x38, 0x3e, 0xeb, 0x1c,
-       0xbc, 0x1e, 0xfe, 0xc3, 0x87, 0xff, 0x80, 0x4f, 0x3c, 0xef, 0xc3, 0xbf,
-       0xf8, 0xec, 0x6f, 0x2c, 0x7a, 0x7e, 0x18, 0xfe, 0xf1, 0x9a, 0x7f, 0x42,
-       0x1b, 0x47, 0x5f, 0x90, 0x0e, 0xff, 0x34, 0xdb, 0x10, 0xb0, 0x73, 0xf8,
-       0x8a, 0x15, 0x9e, 0x83, 0x5f, 0x58, 0x29, 0xe1, 0xe9, 0x50, 0xb5, 0xc9,
-       0x7a, 0x18, 0xf9, 0x61, 0xf6, 0x57, 0x19, 0xf8, 0x26, 0xf6, 0x47, 0xec,
-       0xb7, 0x78, 0x6d, 0x10, 0x94, 0x5c, 0x86, 0x0d, 0x20, 0x47, 0xb6, 0xbb,
-       0x24, 0x89, 0x54, 0x45, 0x3b, 0x34, 0x0c, 0x7b, 0xbc, 0x89, 0x7d, 0x0b,
-       0xdb, 0xe5, 0x8d, 0x44, 0x9d, 0xbc, 0xdf, 0xaf, 0xbb, 0xd5, 0xbf, 0xd9,
-       0xdb, 0x84, 0x35, 0xf2, 0xd9, 0xa3, 0xc6, 0x66, 0xe8, 0x97, 0xf8, 0xbd,
-       0x6d, 0x15, 0x68, 0x57, 0x38, 0xe6, 0xfe, 0x1a, 0xbd, 0xae, 0xb8, 0x25,
-       0x41, 0x3b, 0x4f, 0x29, 0x7f, 0xba, 0x73, 0x09, 0x9a, 0x71, 0x4a, 0xd1,
-       0xb8, 0xf3, 0x6c, 0xe4, 0x57, 0x93, 0xc0, 0x07, 0xfa, 0xfc, 0xb5, 0x18,
-       0x82, 0xf6, 0x9e, 0x06, 0xd3, 0xc2, 0xdc, 0x46, 0x5e, 0xb0, 0x2f, 0x67,
-       0xfb, 0x34, 0xdb, 0xed, 0x73, 0x2f, 0xec, 0xd3, 0xed, 0x24, 0xdb, 0xfd,
-       0x27, 0xd8, 0xe7, 0xb7, 0x5d, 0x0d, 0xbc, 0x21, 0xba, 0x54, 0xcb, 0xc0,
-       0x3f, 0x18, 0x99, 0xd7, 0x69, 0x97, 0x35, 0x0b, 0xbd, 0x3c, 0xc9, 0x73,
-       0x4d, 0xcc, 0x49, 0x3f, 0xae, 0xfc, 0xc7, 0x65, 0xfd, 0xbb, 0xa0, 0x2b,
-       0x08, 0x66, 0x81, 0xb3, 0x3c, 0xa2, 0x87, 0xb6, 0x18, 0xcd, 0x5f, 0x45,
-       0x3c, 0xf4, 0x7e, 0x43, 0xa7, 0x4a, 0xb6, 0x83, 0xec, 0xec, 0x12, 0x70,
-       0x4f, 0xbb, 0xca, 0xee, 0xd9, 0x36, 0x96, 0x81, 0x7f, 0xce, 0x1f, 0x86,
-       0x5f, 0x60, 0xbb, 0x01, 0x5d, 0xc0, 0xbf, 0x0c, 0xfc, 0x73, 0xad, 0x0e,
-       0xfa, 0x96, 0x11, 0xc5, 0xd9, 0xe8, 0x3c, 0xdb, 0xb0, 0x2c, 0xda, 0xf7,
-       0x08, 0xdd, 0xe5, 0xa7, 0xe0, 0x73, 0xd8, 0x27, 0x57, 0xb3, 0xb0, 0x2b,
-       0xad, 0xea, 0xf2, 0xde, 0x3a, 0x2d, 0xaf, 0xad, 0xa1, 0x42, 0x55, 0xd9,
-       0x6c, 0xc1, 0x1b, 0xae, 0x64, 0x74, 0xe9, 0x7b, 0x88, 0xee, 0x84, 0xad,
-       0x2e, 0x3b, 0x3c, 0xe6, 0x79, 0x35, 0x37, 0x5e, 0x1b, 0xd0, 0x8a, 0xec,
-       0xbf, 0x86, 0x3f, 0x04, 0x7d, 0x6a, 0xee, 0xb7, 0x6b, 0x0f, 0xb1, 0x8c,
-       0x70, 0x16, 0xb2, 0xaa, 0xee, 0x7f, 0x06, 0xd0, 0xdf, 0x75, 0x30, 0xd7,
-       0xc7, 0x63, 0x8f, 0x2b, 0x9d, 0x25, 0x6d, 0xbf, 0x23, 0x06, 0x3a, 0x43,
-       0x9f, 0xb7, 0x1f, 0x93, 0xfb, 0x6a, 0xd5, 0xfe, 0x4e, 0xfa, 0x50, 0xe7,
-       0x18, 0x7c, 0x85, 0xc8, 0xf0, 0x6a, 0xbb, 0xc1, 0x8f, 0x6a, 0x5f, 0xdb,
-       0x5c, 0xa2, 0x54, 0x0b, 0xe8, 0xa2, 0xab, 0x60, 0x30, 0x4e, 0x16, 0x6b,
-       0x62, 0x20, 0x41, 0x6b, 0x63, 0x93, 0x61, 0x56, 0x68, 0x77, 0x76, 0x99,
-       0x24, 0x6c, 0x7f, 0xe2, 0x1a, 0x6c, 0xba, 0x54, 0xab, 0xf6, 0xb5, 0x8d,
-       0x33, 0x45, 0xe0, 0x12, 0x7b, 0xd7, 0x60, 0x07, 0xaf, 0xc1, 0x6e, 0x25,
-       0xab, 0x8f, 0xe1, 0xc5, 0xc0, 0xe6, 0x6b, 0xb8, 0xad, 0x90, 0x9e, 0xfe,
-       0xcd, 0xd7, 0x70, 0x38, 0x8c, 0xb3, 0x6d, 0x9c, 0x65, 0x9c, 0x3b, 0xaf,
-       0xe1, 0x1c, 0x59, 0x4f, 0xcf, 0x11, 0x82, 0x0f, 0x4a, 0x74, 0xe6, 0x69,
-       0xef, 0xa5, 0xda, 0xd0, 0xc4, 0x5d, 0x84, 0xf8, 0x38, 0xb2, 0x29, 0xf4,
-       0xe1, 0xc6, 0x5e, 0x0f, 0xbc, 0x32, 0x88, 0x7d, 0xa2, 0x46, 0x55, 0xc8,
-       0xf9, 0x8f, 0x9a, 0xb4, 0xf7, 0x62, 0xd3, 0x08, 0x75, 0x89, 0x75, 0xe2,
-       0x6d, 0xd8, 0x58, 0x72, 0xca, 0x40, 0x0c, 0xbf, 0x20, 0x6d, 0x8c, 0x26,
-       0xaa, 0x35, 0xaa, 0x6c, 0xcf, 0x3f, 0x11, 0x40, 0x17, 0xa7, 0xe0, 0xd3,
-       0xc0, 0xe3, 0xe4, 0x98, 0x97, 0xc3, 0x7c, 0x93, 0x6d, 0x0b, 0x7e, 0x05,
-       0xb0, 0xd0, 0xb5, 0x84, 0x3e, 0xbf, 0xeb, 0x55, 0x4f, 0xe7, 0x7d, 0x2c,
-       0xe4, 0x5c, 0x89, 0x84, 0x98, 0xbf, 0x1a, 0xb0, 0x9e, 0x4d, 0x8f, 0x5c,
-       0x45, 0x8e, 0x63, 0x92, 0x37, 0x06, 0xff, 0x01, 0x7d, 0x9f, 0x6d, 0x11,
-       0x72, 0x82, 0x3f, 0xed, 0x55, 0x36, 0xf6, 0x9d, 0xad, 0xea, 0x49, 0x06,
-       0xfb, 0xf2, 0xe9, 0x1c, 0xe7, 0x0f, 0x9d, 0x09, 0x2f, 0x37, 0xbe, 0x4d,
-       0x3f, 0x7b, 0x60, 0x9b, 0x38, 0x5b, 0xd9, 0x26, 0x10, 0x03, 0x60, 0x53,
-       0xc2, 0xcb, 0xa1, 0x7f, 0x36, 0xb2, 0xa1, 0x0c, 0x6c, 0x88, 0x69, 0x65,
-       0x3a, 0x7f, 0x04, 0x7b, 0x95, 0xb4, 0xd2, 0x84, 0x0f, 0x9a, 0x46, 0x3f,
-       0x82, 0x9e, 0xe0, 0x2c, 0xf0, 0x81, 0x05, 0x70, 0x49, 0x8c, 0xfe, 0x2a,
-       0xb4, 0x67, 0xee, 0xbf, 0x1b, 0xa8, 0x78, 0x72, 0x30, 0xdc, 0xff, 0x17,
-       0xa1, 0x0f, 0x88, 0x70, 0x31, 0x9e, 0xac, 0x36, 0x81, 0x5c, 0x68, 0xa2,
-       0x65, 0x68, 0xec, 0xcf, 0x8b, 0x3e, 0xe7, 0x30, 0x9c, 0xbf, 0x3c, 0x1e,
-       0xfa, 0x45, 0xce, 0x5b, 0x92, 0x21, 0x4f, 0x73, 0x51, 0x5c, 0x94, 0xf6,
-       0x86, 0x18, 0x65, 0x95, 0x5d, 0x99, 0xd3, 0x68, 0xd3, 0xb9, 0x24, 0xd6,
-       0x61, 0xae, 0x85, 0x73, 0xc3, 0x2f, 0x21, 0x0f, 0xe2, 0xdc, 0x14, 0xeb,
-       0x3b, 0x43, 0x9b, 0xbf, 0x44, 0x65, 0xf8, 0x54, 0xc3, 0xe1, 0xf7, 0x5e,
-       0x2f, 0x75, 0x61, 0xdc, 0xc4, 0x5e, 0xf0, 0x13, 0xba, 0xe4, 0x33, 0x62,
-       0x41, 0xfa, 0x06, 0xce, 0xaf, 0xb0, 0xd6, 0xc2, 0x5a, 0xf6, 0xbb, 0xbc,
-       0xf6, 0x3c, 0xe8, 0xc0, 0xb8, 0xc9, 0x30, 0xec, 0xa3, 0x82, 0xf7, 0xbc,
-       0xdc, 0x1e, 0x73, 0x82, 0x12, 0x21, 0x5e, 0xab, 0x0d, 0xef, 0xc6, 0xb5,
-       0x9c, 0xd3, 0x04, 0x17, 0x74, 0x87, 0xf1, 0x47, 0x79, 0x18, 0xd1, 0xf4,
-       0x09, 0xe4, 0x71, 0x4e, 0x07, 0xe2, 0x14, 0x8f, 0x86, 0x4c, 0x75, 0xce,
-       0x08, 0xe6, 0x81, 0xfe, 0xf5, 0xe3, 0xbb, 0x53, 0xd7, 0xfc, 0x23, 0x5b,
-       0x17, 0x15, 0x10, 0x1f, 0xc0, 0x27, 0x6b, 0x8a, 0x73, 0xbf, 0x62, 0x53,
-       0xa2, 0xc4, 0xdc, 0x18, 0x7c, 0xa2, 0xca, 0xa3, 0x2e, 0xf8, 0x1b, 0xe5,
-       0x66, 0x82, 0xd7, 0x05, 0xf0, 0xd7, 0x82, 0xfe, 0x8c, 0x03, 0x96, 0x8e,
-       0x00, 0x07, 0xc7, 0x6a, 0x57, 0xe4, 0x53, 0x54, 0x36, 0x39, 0xa7, 0xe8,
-       0x64, 0xfa, 0x0a, 0x6c, 0xfb, 0x22, 0xbf, 0x19, 0x73, 0xdc, 0x7f, 0xac,
-       0x57, 0xc9, 0xab, 0x9b, 0xc7, 0x13, 0x22, 0xdf, 0xbb, 0x61, 0xfe, 0x9f,
-       0xbb, 0x15, 0x6d, 0x72, 0x8c, 0xf9, 0x7f, 0xdb, 0x30, 0xfe, 0xe3, 0xd4,
-       0xfa, 0xf1, 0xdd, 0xdb, 0x42, 0xfd, 0x43, 0xff, 0xf1, 0x90, 0x5e, 0xd0,
-       0xb6, 0x46, 0x6b, 0x94, 0x2b, 0x53, 0x5d, 0x20, 0x5f, 0xf4, 0x72, 0xbb,
-       0xac, 0x2a, 0x6c, 0xaa, 0xd4, 0x02, 0xdd, 0x6b, 0x71, 0x6c, 0x6d, 0x4d,
-       0xe5, 0xda, 0x1a, 0xe5, 0xe7, 0x4b, 0xad, 0x00, 0x79, 0x56, 0x7b, 0xcc,
-       0xcb, 0xa2, 0x5f, 0xc1, 0x3e, 0x05, 0x9a, 0xf6, 0x2f, 0x16, 0x84, 0x73,
-       0x4c, 0xe6, 0x89, 0xc2, 0x79, 0x4a, 0x2b, 0x2d, 0x73, 0xfe, 0x08, 0x5b,
-       0x72, 0x64, 0xdd, 0x80, 0x98, 0x72, 0x5c, 0x2b, 0x9c, 0x5e, 0x40, 0xfe,
-       0xb8, 0x82, 0xdf, 0x19, 0xfc, 0x9a, 0xf8, 0x45, 0xf9, 0xfb, 0x33, 0xc8,
-       0xff, 0xa5, 0x7f, 0x45, 0x2c, 0x50, 0xfb, 0xff, 0x62, 0x05, 0x3a, 0xb6,
-       0x90, 0xa6, 0x6f, 0x3b, 0xa2, 0x5f, 0x28, 0x9f, 0x52, 0x40, 0xde, 0x6b,
-       0xbe, 0x4d, 0xbf, 0x13, 0xe6, 0x50, 0x44, 0xaf, 0xd7, 0xc1, 0xc7, 0x91,
-       0xfd, 0xa1, 0xbe, 0x66, 0x1f, 0xf4, 0xa4, 0xef, 0x0c, 0x73, 0x24, 0xe4,
-       0x6a, 0x05, 0xb9, 0xea, 0xfb, 0xe0, 0x8d, 0x46, 0x6f, 0x41, 0x7f, 0x5e,
-       0xaf, 0x77, 0x81, 0x1e, 0x87, 0xca, 0x93, 0xf6, 0x18, 0x69, 0x43, 0xe6,
-       0x26, 0xad, 0x0b, 0x36, 0x0c, 0xfb, 0x96, 0x63, 0x4a, 0x74, 0xe4, 0xcf,
-       0xcd, 0x2c, 0xd5, 0x04, 0xd6, 0x22, 0xef, 0xc9, 0xa1, 0x0f, 0xd9, 0x5f,
-       0xa9, 0x33, 0x9c, 0xa0, 0x37, 0xea, 0x3a, 0xbd, 0x89, 0xbc, 0xeb, 0x2d,
-       0xe7, 0xdc, 0x0c, 0x62, 0xd6, 0x00, 0xe2, 0x03, 0x6a, 0x98, 0x5d, 0xec,
-       0xa3, 0x77, 0x1a, 0x78, 0x96, 0xf0, 0xbb, 0x13, 0x79, 0xe3, 0xf5, 0x61,
-       0x3e, 0x6d, 0x3d, 0xd3, 0x96, 0x00, 0x0c, 0xaf, 0x37, 0x40, 0x5b, 0x0f,
-       0xe4, 0x6f, 0x9b, 0x53, 0xf4, 0xcb, 0x5e, 0x99, 0xab, 0x68, 0x3c, 0xaf,
-       0xfc, 0xd2, 0x27, 0xe7, 0x99, 0xcf, 0x3a, 0x74, 0x9c, 0xc7, 0xfc, 0x8e,
-       0xfd, 0x27, 0xe3, 0xb3, 0xc7, 0x0a, 0x38, 0xcc, 0x95, 0xba, 0xea, 0x47,
-       0x73, 0xa4, 0x45, 0x31, 0x8c, 0xfd, 0x62, 0x89, 0x0a, 0x92, 0xef, 0x13,
-       0x24, 0x65, 0xb0, 0x4e, 0x9e, 0x94, 0x30, 0xf2, 0xf5, 0x99, 0x39, 0x87,
-       0xe5, 0x0a, 0xff, 0x56, 0x8b, 0xe4, 0xca, 0x32, 0xea, 0xa4, 0x6a, 0xfd,
-       0x29, 0xc8, 0x55, 0x84, 0xf5, 0x01, 0xec, 0x7b, 0x81, 0xe5, 0x8b, 0xba,
-       0xb1, 0x8e, 0xbc, 0xa7, 0x4e, 0x29, 0x55, 0xdf, 0x1c, 0x47, 0x5d, 0x00,
-       0xf9, 0xd5, 0x16, 0x80, 0x03, 0x36, 0x5a, 0x5b, 0xc1, 0x13, 0xb5, 0x48,
-       0xed, 0x0c, 0x9e, 0x83, 0x78, 0x36, 0x59, 0x37, 0xc3, 0x3c, 0xe3, 0x13,
-       0xf4, 0xc0, 0x9e, 0x4a, 0x6c, 0x4f, 0xf4, 0x8f, 0xad, 0x3c, 0xfd, 0x43,
-       0x6b, 0x8c, 0x7e, 0xd4, 0xca, 0xd1, 0x0f, 0x5b, 0x2e, 0xfd, 0x7d, 0x6b,
-       0x84, 0x9e, 0x6d, 0x65, 0xb9, 0x96, 0x43, 0xce, 0x64, 0x71, 0xce, 0x44,
-       0x0f, 0xfa, 0xb7, 0xc3, 0xde, 0x59, 0xfe, 0xe7, 0x66, 0x0a, 0xcd, 0x21,
-       0x2a, 0x9f, 0x80, 0x6f, 0x76, 0x6f, 0xe3, 0x1a, 0x94, 0x1e, 0x73, 0xb9,
-       0x86, 0xe8, 0xe0, 0xf7, 0xa8, 0x23, 0xe0, 0xbb, 0xe1, 0xcb, 0xa6, 0xd2,
-       0xf6, 0x39, 0x4f, 0x1f, 0x08, 0x7d, 0xc0, 0x5d, 0x29, 0xea, 0xc2, 0x5e,
-       0xf0, 0x7f, 0x17, 0x9f, 0x86, 0x0d, 0xc8, 0x1a, 0x28, 0x01, 0x5f, 0xc3,
-       0x79, 0x80, 0xc1, 0x76, 0xcc, 0xf5, 0x87, 0xe5, 0xe9, 0x5c, 0x17, 0xb2,
-       0x3d, 0xeb, 0x08, 0x1a, 0x0c, 0x37, 0x69, 0xb2, 0xdc, 0x0c, 0x87, 0x7d,
-       0x6a, 0x21, 0xf4, 0x6f, 0x89, 0x50, 0x2f, 0x4d, 0xcc, 0x3f, 0x15, 0xfa,
-       0xe3, 0x8d, 0xfb, 0x20, 0x56, 0x20, 0x97, 0x54, 0xeb, 0x18, 0x56, 0x0b,
-       0x61, 0xfb, 0xc3, 0xb9, 0x24, 0xf8, 0xed, 0x52, 0xd9, 0x7f, 0x43, 0xe3,
-       0x1c, 0x5b, 0x38, 0xcc, 0xff, 0x11, 0x8c, 0x2f, 0x87, 0xe3, 0xaf, 0xd0,
-       0xf4, 0x22, 0x81, 0xd6, 0xd7, 0xb4, 0xa2, 0x1c, 0x8f, 0x61, 0x2c, 0x30,
-       0xd6, 0xb9, 0x6e, 0xe0, 0x0c, 0x23, 0xc5, 0xba, 0x2e, 0x9c, 0x71, 0xf0,
-       0x71, 0x12, 0xbf, 0x82, 0xfc, 0x3d, 0xe2, 0x0f, 0x15, 0xde, 0x41, 0xbc,
-       0xd0, 0x3a, 0xa2, 0xdc, 0x67, 0x3b, 0x6a, 0xcf, 0x20, 0x38, 0x84, 0x5a,
-       0xdd, 0x4a, 0x19, 0xf4, 0x2f, 0xf3, 0xb6, 0x79, 0x48, 0xcc, 0xe1, 0x4c,
-       0x41, 0x30, 0xe1, 0xd8, 0x95, 0x82, 0xe8, 0xa6, 0x9f, 0x1f, 0xe7, 0xb8,
-       0x5b, 0x9f, 0x79, 0x01, 0xba, 0xd7, 0x58, 0xe9, 0xa4, 0x46, 0xc3, 0xa0,
-       0x2b, 0xa3, 0x43, 0xa0, 0xd3, 0xa4, 0x46, 0x33, 0x85, 0x5c, 0x6e, 0x33,
-       0xa1, 0x3c, 0x94, 0x0e, 0x43, 0xcf, 0x67, 0xa5, 0x8f, 0xf6, 0x1c, 0x3c,
-       0x9b, 0x1f, 0xf4, 0xae, 0x3f, 0x73, 0x09, 0xf4, 0xf7, 0xa0, 0x0a, 0xd9,
-       0x2e, 0xe5, 0x5c, 0xf6, 0x87, 0x4c, 0x4f, 0x20, 0x6e, 0x19, 0x43, 0xe6,
-       0x7e, 0xf1, 0xab, 0xe0, 0x0e, 0x83, 0x65, 0xf7, 0xaa, 0xac, 0x77, 0x64,
-       0x9c, 0xc3, 0x7e, 0x4b, 0x2b, 0xaf, 0x81, 0x16, 0x93, 0x9e, 0x6d, 0x6e,
-       0x0f, 0xc7, 0x96, 0xe4, 0xc5, 0xb3, 0xcd, 0x2e, 0xfa, 0x61, 0x63, 0x0b,
-       0x2d, 0x37, 0xf8, 0x7d, 0x27, 0x2d, 0x35, 0x86, 0xae, 0x1e, 0x15, 0x03,
-       0xb4, 0x7a, 0xe3, 0x4d, 0xe6, 0x57, 0x05, 0xf2, 0x82, 0xc9, 0x8f, 0xe9,
-       0xbd, 0xd1, 0x5e, 0xfa, 0xe9, 0x3d, 0x76, 0xfd, 0x7e, 0x01, 0x1b, 0x18,
-       0x4d, 0xb2, 0x6d, 0xa3, 0xcf, 0xf3, 0xf6, 0x55, 0x4b, 0xb0, 0x6e, 0xff,
-       0x04, 0x3c, 0xb5, 0x8f, 0x29, 0x3b, 0x60, 0xdc, 0x8c, 0x17, 0xba, 0xe1,
-       0xbc, 0x08, 0x9c, 0x78, 0xd7, 0x1c, 0x02, 0xae, 0x17, 0x25, 0x2f, 0x0e,
-       0xb9, 0xf6, 0x55, 0x42, 0x0e, 0x79, 0xc5, 0x19, 0xca, 0x0a, 0xb1, 0x9d,
-       0x1a, 0x99, 0x9b, 0xcc, 0xf3, 0xf0, 0xff, 0xa8, 0xab, 0x2a, 0x97, 0xa9,
-       0x3e, 0x73, 0xc9, 0x61, 0xfd, 0x67, 0xbf, 0xf1, 0x12, 0xf2, 0x4e, 0x93,
-       0x4e, 0x34, 0xd9, 0x5f, 0x32, 0x2e, 0xce, 0xfd, 0x77, 0x9b, 0x5f, 0x13,
-       0x9c, 0x23, 0xe0, 0x1d, 0xe6, 0xf5, 0x2f, 0xb1, 0x9c, 0x3b, 0x18, 0x36,
-       0x6b, 0x89, 0x60, 0x03, 0x8f, 0x86, 0xcc, 0x5d, 0x82, 0xf7, 0xfb, 0x6f,
-       0xec, 0xfb, 0x2e, 0x68, 0x1d, 0x02, 0x2c, 0xe2, 0x65, 0xa6, 0x7d, 0x8f,
-       0x57, 0xe4, 0x1e, 0xc7, 0x9b, 0xc8, 0xf3, 0xd6, 0xf6, 0xc0, 0x5c, 0x53,
-       0xe0, 0x9c, 0x86, 0x94, 0xcb, 0x95, 0x51, 0xe6, 0xef, 0x6d, 0x7d, 0x9c,
-       0x63, 0xea, 0xf9, 0xbf, 0x09, 0xa2, 0x5a, 0xf3, 0x95, 0xf9, 0x49, 0xf8,
-       0xe7, 0x20, 0xa8, 0xee, 0x1e, 0x52, 0x71, 0x68, 0x90, 0xdf, 0x1f, 0x90,
-       0xb2, 0xa8, 0x8a, 0x4e, 0xba, 0xc3, 0xb0, 0x00, 0xcb, 0x73, 0x2f, 0x87,
-       0x72, 0x84, 0x11, 0x75, 0xa1, 0xdf, 0x8c, 0xf4, 0x32, 0x05, 0x1d, 0xdb,
-       0x63, 0x1e, 0x0a, 0x63, 0x32, 0xc7, 0xb4, 0x9f, 0x42, 0xe7, 0xac, 0x14,
-       0xeb, 0x4d, 0xaa, 0xef, 0x9a, 0xde, 0xf0, 0xbb, 0xfa, 0x8c, 0x07, 0xda,
-       0x8a, 0x0b, 0x9d, 0x54, 0xaa, 0x27, 0x90, 0x03, 0x19, 0x34, 0x97, 0xc3,
-       0x18, 0x3a, 0x54, 0x6a, 0xb0, 0xce, 0x57, 0x42, 0x9d, 0x4f, 0x86, 0xb8,
-       0x4f, 0x82, 0x17, 0xb6, 0xb5, 0x2a, 0xb8, 0x76, 0xda, 0x26, 0xeb, 0x5f,
-       0x1d, 0xb6, 0x5c, 0xae, 0x71, 0xed, 0x89, 0xfc, 0xdb, 0x3c, 0x37, 0x33,
-       0xed, 0x18, 0xa0, 0x6b, 0x44, 0x2b, 0xb7, 0x1c, 0xad, 0xec, 0x33, 0x7d,
-       0xbb, 0x41, 0xb7, 0x26, 0x6b, 0xdc, 0xa5, 0xd6, 0x7b, 0xc1, 0xd2, 0xee,
-       0x4d, 0xe8, 0x43, 0xe7, 0x27, 0x58, 0xae, 0x5f, 0x60, 0xba, 0xac, 0x82,
-       0x60, 0x3e, 0xa7, 0xe9, 0xd4, 0xf0, 0xdf, 0xf5, 0x72, 0x3e, 0x75, 0x7a,
-       0x98, 0xf1, 0x83, 0x8e, 0x74, 0x9a, 0x96, 0x7d, 0xde, 0xa3, 0x3e, 0xc3,
-       0x3c, 0x2c, 0x2f, 0x98, 0xf4, 0x88, 0x94, 0xdb, 0x6b, 0xd2, 0xa6, 0xcb,
-       0x2b, 0xb0, 0xa5, 0xd4, 0x90, 0x79, 0x94, 0xec, 0xab, 0x17, 0x75, 0xbb,
-       0x3e, 0x05, 0x7b, 0x5e, 0x5a, 0xd4, 0x69, 0xa7, 0xac, 0xb1, 0x58, 0x36,
-       0xf6, 0x31, 0x58, 0x7c, 0x78, 0xf6, 0x43, 0x6d, 0x67, 0xef, 0xa1, 0x4b,
-       0x4f, 0xff, 0x16, 0x7c, 0x0d, 0xf3, 0xd5, 0xb0, 0x0e, 0x23, 0x9f, 0x58,
-       0x40, 0xee, 0x51, 0x45, 0x6e, 0x5c, 0xc8, 0x30, 0x6c, 0xc4, 0xef, 0xad,
-       0x92, 0xff, 0x42, 0xf2, 0x7f, 0x07, 0x55, 0xa5, 0x0d, 0x65, 0xe4, 0x3b,
-       0x01, 0x1c, 0xea, 0x1d, 0x8f, 0x91, 0x2b, 0xc9, 0x77, 0xf7, 0x2a, 0x38,
-       0xf6, 0x11, 0x19, 0x7e, 0x77, 0x14, 0x7b, 0x32, 0x8f, 0xa3, 0xf9, 0x6e,
-       0x52, 0x36, 0x14, 0xf1, 0x1d, 0x89, 0x44, 0x33, 0x4d, 0xbf, 0x8b, 0x9a,
-       0x67, 0xb2, 0x39, 0x48, 0xa5, 0xa6, 0x05, 0x19, 0xcc, 0xf4, 0xf1, 0xd9,
-       0x8a, 0x2b, 0x38, 0x8f, 0x60, 0x5a, 0xef, 0xa5, 0xc3, 0x7e, 0x44, 0x4f,
-       0x32, 0xa4, 0x6f, 0x32, 0x1c, 0x27, 0x42, 0x1a, 0xda, 0xf1, 0x25, 0x81,
-       0x0b, 0x31, 0x3e, 0xf7, 0x57, 0x21, 0x1e, 0xf6, 0x1f, 0xa0, 0x75, 0x32,
-       0x43, 0x2b, 0x3e, 0xd3, 0xb1, 0x85, 0xaa, 0x69, 0xee, 0x1f, 0x80, 0x9e,
-       0x31, 0x9e, 0x4d, 0x9c, 0xc7, 0xac, 0xe3, 0xf1, 0x91, 0x66, 0x05, 0x3c,
-       0x66, 0xfe, 0xf2, 0xba, 0x24, 0x2d, 0x7d, 0x85, 0xe5, 0xb7, 0x07, 0xf9,
-       0x3b, 0xeb, 0xc2, 0x96, 0x50, 0xaf, 0xd4, 0x9e, 0xa5, 0x85, 0x1e, 0xc8,
-       0x8a, 0xf7, 0xed, 0xa2, 0xbb, 0x61, 0xef, 0xc5, 0x06, 0xef, 0x3f, 0x09,
-       0x3d, 0x7a, 0x59, 0xee, 0x5f, 0x5a, 0x19, 0x08, 0xe1, 0x19, 0xb6, 0x67,
-       0x03, 0x6c, 0x27, 0xed, 0xab, 0x9b, 0xd7, 0x81, 0xff, 0x7d, 0xc0, 0x0b,
-       0x3a, 0x99, 0x63, 0x78, 0xc6, 0x83, 0x75, 0x8d, 0xf4, 0x67, 0xe0, 0x49,
-       0xc9, 0x5a, 0xbe, 0xd8, 0xe8, 0xa4, 0x62, 0x3d, 0xc2, 0xc5, 0x78, 0x3e,
-       0x46, 0xad, 0x7b, 0x9f, 0xc4, 0x35, 0x2d, 0x71, 0xe1, 0x7d, 0x83, 0x7d,
-       0xcd, 0xad, 0x80, 0x47, 0xbd, 0xee, 0x80, 0xb6, 0x54, 0x37, 0x2d, 0xc9,
-       0x7a, 0xbd, 0x4b, 0xf9, 0x98, 0xd4, 0x66, 0xbc, 0xdf, 0x02, 0x5b, 0xdf,
-       0x83, 0x3c, 0xa6, 0x07, 0x73, 0xd6, 0x86, 0xb9, 0x8d, 0xf4, 0x27, 0x36,
-       0xd0, 0xdf, 0x89, 0x75, 0xfd, 0xd8, 0x53, 0xad, 0x2b, 0x61, 0xdd, 0xec,
-       0x02, 0x6c, 0x82, 0x73, 0xf3, 0x34, 0xc7, 0xe4, 0x1b, 0x25, 0x2d, 0xb3,
-       0x2b, 0xef, 0xe1, 0x5c, 0x03, 0x80, 0x8d, 0xc6, 0x8a, 0x0f, 0x75, 0xe0,
-       0xf9, 0x5e, 0x43, 0xde, 0x4b, 0x40, 0x06, 0x9b, 0x53, 0x7c, 0xf6, 0x6a,
-       0xe3, 0xf3, 0x78, 0x76, 0x63, 0x1b, 0xbf, 0x98, 0x57, 0x4c, 0x2f, 0xd3,
-       0x0a, 0x3d, 0x25, 0xd8, 0x9b, 0x8b, 0x9a, 0x2f, 0xa5, 0x53, 0x29, 0x87,
-       0x78, 0xee, 0xf3, 0x5d, 0x2d, 0xdb, 0xe5, 0xa0, 0xaa, 0x0b, 0x1c, 0x8e,
-       0xeb, 0x86, 0x3c, 0xfb, 0xe1, 0x15, 0xbe, 0xaf, 0xb5, 0x10, 0x4f, 0xed,
-       0x2c, 0xe1, 0xec, 0x0f, 0xaf, 0x38, 0xf4, 0x68, 0x33, 0x4b, 0x47, 0x9b,
-       0xb6, 0x79, 0x3f, 0x7c, 0x40, 0x79, 0xed, 0x1e, 0x77, 0x57, 0x8a, 0xfd,
-       0x96, 0x81, 0x9c, 0xb3, 0xc3, 0x51, 0x39, 0x48, 0x95, 0xeb, 0xb1, 0x05,
-       0x9b, 0xef, 0x68, 0xcc, 0x06, 0x6d, 0xcc, 0x53, 0xfe, 0x2f, 0x73, 0x14,
-       0xde, 0x9f, 0xfd, 0x34, 0x72, 0x12, 0x1f, 0x39, 0x89, 0x8f, 0x9c, 0xc4,
-       0x47, 0x4e, 0xe2, 0x23, 0x27, 0xf1, 0x91, 0x93, 0xf8, 0xc8, 0x49, 0x7c,
-       0xe4, 0x24, 0xc8, 0xff, 0x55, 0x5d, 0x30, 0x8e, 0x5c, 0x1b, 0xfe, 0xcb,
-       0xff, 0x6a, 0x98, 0x53, 0x44, 0x31, 0x99, 0xe7, 0x56, 0x37, 0x79, 0x6e,
-       0x74, 0x4f, 0x7c, 0x00, 0x73, 0x13, 0x61, 0xee, 0xc3, 0x6b, 0xa2, 0x98,
-       0xcd, 0xeb, 0x68, 0xcc, 0x43, 0xbd, 0x59, 0x98, 0xe4, 0xdc, 0x48, 0xc5,
-       0x2a, 0x95, 0x97, 0xbf, 0x8a, 0xfc, 0xc8, 0x42, 0x7e, 0x34, 0x88, 0x5c,
-       0x88, 0xef, 0xb5, 0xa3, 0xfb, 0xa3, 0x82, 0x76, 0xc8, 0x1f, 0xd7, 0xbe,
-       0xe6, 0x73, 0xde, 0xee, 0x58, 0x65, 0x21, 0x16, 0xfa, 0x29, 0xa0, 0xe2,
-       0xe8, 0xb7, 0x90, 0x23, 0x7f, 0x4f, 0xde, 0x95, 0x4d, 0x0c, 0xb3, 0xcc,
-       0x27, 0x3e, 0x25, 0x4f, 0x8e, 0xf8, 0xab, 0xee, 0xf8, 0xc4, 0x12, 0xf3,
-       0x8f, 0xa8, 0xef, 0x2c, 0x18, 0x7e, 0x36, 0x41, 0xa9, 0x53, 0x5b, 0x30,
-       0x67, 0x52, 0xbf, 0xbc, 0x27, 0x82, 0x28, 0xcf, 0xfe, 0x1a, 0xf2, 0x72,
-       0x48, 0x9c, 0xe5, 0xdb, 0x04, 0xc6, 0xcb, 0xfe, 0xb5, 0x32, 0x53, 0x6c,
-       0x54, 0xa4, 0x4e, 0x1d, 0x6a, 0x96, 0x90, 0x3f, 0xf5, 0xf6, 0x53, 0x97,
-       0x81, 0x1a, 0x2a, 0xc2, 0xcd, 0x38, 0x7f, 0x99, 0x92, 0xb5, 0xcd, 0xd9,
-       0x35, 0x79, 0x42, 0xd6, 0xbc, 0x4f, 0x65, 0xa6, 0x5a, 0xb7, 0x33, 0x5c,
-       0xd7, 0x82, 0xd6, 0x99, 0x27, 0x81, 0x63, 0x19, 0x39, 0x81, 0x2e, 0xf7,
-       0xae, 0xcc, 0xcc, 0xd6, 0xd5, 0x5d, 0x95, 0xa2, 0x01, 0xf1, 0x2f, 0xd7,
-       0x45, 0xfa, 0x92, 0xba, 0xb3, 0x12, 0x12, 0x96, 0xe1, 0x18, 0xde, 0x00,
-       0x1c, 0xcb, 0x2d, 0x0b, 0x58, 0x96, 0x1d, 0xd3, 0x50, 0x99, 0xa9, 0x34,
-       0xda, 0x69, 0x60, 0x3c, 0x8c, 0x37, 0x3a, 0x0f, 0x9f, 0x25, 0x45, 0xe2,
-       0x54, 0x10, 0x94, 0x47, 0x07, 0xc3, 0x3a, 0x12, 0xf5, 0xe3, 0x09, 0x43,
-       0xea, 0xb9, 0x1a, 0x7f, 0x53, 0xc6, 0x29, 0x4b, 0xf0, 0x3c, 0x3f, 0xf1,
-       0x2e, 0xf7, 0x24, 0xe6, 0x30, 0x5e, 0x8e, 0xd6, 0x8a, 0x70, 0x6d, 0x77,
-       0x1b, 0x3f, 0x3b, 0xc2, 0xfd, 0x98, 0x26, 0x3e, 0xe7, 0x65, 0xec, 0xc5,
-       0x74, 0xf1, 0x1a, 0x13, 0xb4, 0x41, 0x96, 0xfe, 0xff, 0x96, 0xf7, 0xed,
-       0x67, 0x62, 0x9e, 0x1a, 0x80, 0xe1, 0xf5, 0x8c, 0x23, 0x82, 0xc1, 0x8b,
-       0xb3, 0x0a, 0x4e, 0xac, 0xdd, 0xed, 0x7d, 0xd6, 0xbe, 0xed, 0xb4, 0x46,
-       0xfb, 0x47, 0x78, 0xb2, 0x4a, 0x6e, 0x6b, 0xf0, 0xf2, 0xff, 0x0a, 0xc3,
-       0x13, 0xba, 0xf8, 0x89, 0x3b, 0xd2, 0x6c, 0x5b, 0x6d, 0x1c, 0xdd, 0x35,
-       0x70, 0xcd, 0xcf, 0x35, 0x3c, 0x7f, 0x47, 0x68, 0xaf, 0x4b, 0x4b, 0x61,
-       0x2c, 0x83, 0x2e, 0xaa, 0xbb, 0xd4, 0x70, 0x6c, 0x70, 0x6c, 0x43, 0xe3,
-       0x1c, 0x3f, 0xb2, 0x91, 0xf6, 0x7b, 0x42, 0x95, 0x9b, 0x9c, 0x59, 0x8c,
-       0x7c, 0x0e, 0xfc, 0xc1, 0xb0, 0x11, 0xfa, 0xed, 0x24, 0xfc, 0x56, 0x0f,
-       0xed, 0x83, 0xbf, 0xb9, 0x13, 0xfe, 0x66, 0x3f, 0xea, 0xca, 0xf1, 0x95,
-       0xf6, 0xfb, 0x57, 0xae, 0x65, 0xab, 0x74, 0x58, 0xca, 0xae, 0x12, 0xe8,
-       0xce, 0xc7, 0x90, 0xdf, 0x2e, 0x99, 0xa3, 0x29, 0x79, 0xc2, 0x57, 0xba,
-       0xfc, 0x2d, 0x62, 0xe3, 0x3d, 0x6f, 0x16, 0x7a, 0xdd, 0x55, 0x10, 0x32,
-       0xff, 0x52, 0x7c, 0xab, 0x36, 0x14, 0xdf, 0xe0, 0x53, 0x81, 0xdf, 0xa0,
-       0x4a, 0xd3, 0xa4, 0x0a, 0xf6, 0xad, 0x60, 0xdf, 0x0a, 0xea, 0xc1, 0xd9,
-       0x66, 0xfb, 0x77, 0xaa, 0xee, 0xb0, 0xc6, 0x66, 0xd8, 0xa8, 0x6f, 0x86,
-       0xe7, 0xd2, 0xda, 0x9e, 0xc7, 0xc0, 0xbb, 0x47, 0xc1, 0xbb, 0x23, 0xa8,
-       0x83, 0xfe, 0x04, 0x75, 0xd0, 0x1f, 0xa2, 0x0e, 0x3a, 0x8c, 0x3a, 0x68,
-       0x0a, 0x75, 0xd0, 0x7d, 0xb0, 0xfd, 0x7b, 0x61, 0xfb, 0x93, 0xb0, 0xfd,
-       0x09, 0x79, 0xc7, 0x73, 0xc8, 0xdf, 0x78, 0xef, 0x11, 0xed, 0xc5, 0xed,
-       0x4d, 0x22, 0x88, 0xaf, 0x7c, 0x62, 0x9c, 0x1a, 0x2d, 0xae, 0x87, 0x5c,
-       0x79, 0x7f, 0x35, 0xed, 0x4e, 0x6a, 0x53, 0xc8, 0xb9, 0xef, 0x1f, 0xe1,
-       0x3a, 0x29, 0xa5, 0xee, 0x2b, 0x73, 0xf6, 0x73, 0x1e, 0xd2, 0x2e, 0xe4,
-       0x6d, 0x38, 0xb3, 0x7d, 0xa6, 0xa8, 0x47, 0x35, 0x4a, 0xdf, 0x5a, 0x8d,
-       0xb2, 0x3c, 0xcf, 0x35, 0xca, 0xab, 0x6b, 0x35, 0xca, 0xf2, 0x3c, 0xd7,
-       0x28, 0xaf, 0xac, 0xab, 0x51, 0xae, 0x3c, 0xfd, 0xf2, 0xba, 0x1a, 0xe5,
-       0xca, 0xd3, 0x2f, 0x85, 0x63, 0xa6, 0x03, 0x7e, 0xc9, 0x0d, 0x69, 0x35,
-       0x5d, 0x3c, 0x7b, 0xc3, 0x7c, 0xe1, 0xfb, 0xfd, 0xeb, 0xff, 0x1f, 0x3a,
-       0x6e, 0x9d, 0x1a, 0x39, 0xdf, 0xd8, 0xaa, 0xea, 0x9a, 0xf6, 0xf9, 0xde,
-       0xb6, 0xf9, 0x55, 0xf9, 0x6d, 0xb4, 0x5c, 0xdb, 0xfc, 0x3e, 0xbc, 0x27,
-       0xad, 0x0c, 0xdb, 0xf5, 0x02, 0x7d, 0x1c, 0xf0, 0xf7, 0x3d, 0x4f, 0x74,
-       0xc9, 0xef, 0x6a, 0x9e, 0xcc, 0x91, 0x61, 0xa3, 0xa3, 0x47, 0xb7, 0x2a,
-       0x3b, 0xe6, 0x7e, 0x5a, 0x53, 0xbe, 0xf9, 0x41, 0xe0, 0x01, 0xaf, 0x7d,
-       0x43, 0xde, 0xe1, 0xa8, 0xf3, 0xaa, 0xbb, 0x6c, 0x23, 0xbf, 0x8a, 0x38,
-       0x03, 0x59, 0x4b, 0xdc, 0x5c, 0xf3, 0x71, 0x9d, 0x18, 0xf9, 0xef, 0x08,
-       0xd7, 0xcf, 0xd2, 0x8a, 0xee, 0xdb, 0x50, 0xef, 0xf1, 0x9a, 0x68, 0xdc,
-       0x5e, 0x1f, 0x26, 0xc3, 0xfb, 0xac, 0x55, 0x95, 0x13, 0x49, 0x7c, 0x46,
-       0x88, 0xef, 0xbf, 0x02, 0xe5, 0x37, 0x18, 0xde, 0x6c, 0x83, 0x1f, 0x47,
-       0x9e, 0xc6, 0x77, 0x2b, 0x9c, 0x6f, 0x19, 0xf4, 0xee, 0x7c, 0x37, 0xbd,
-       0x73, 0x1c, 0xf9, 0xa6, 0x6b, 0x67, 0x5f, 0x46, 0xbd, 0x70, 0x8a, 0xf3,
-       0xe2, 0x51, 0xa6, 0x73, 0xc8, 0x9a, 0x25, 0xab, 0x5f, 0xe5, 0xd1, 0x47,
-       0xb4, 0x4f, 0xd2, 0x2d, 0xc2, 0x7d, 0x7e, 0xd6, 0xb6, 0x8f, 0xd5, 0xb6,
-       0x4f, 0x81, 0xed, 0xad, 0xf1, 0x75, 0x9c, 0xb9, 0xb2, 0xfd, 0x26, 0x33,
-       0x1d, 0xd6, 0x52, 0x8f, 0x8c, 0x6e, 0xa6, 0xfa, 0x80, 0x7d, 0xee, 0x15,
-       0xe4, 0xda, 0xe5, 0x51, 0xcc, 0xa5, 0x87, 0xf0, 0x8e, 0xe7, 0xed, 0x06,
-       0x09, 0xfb, 0x5c, 0x83, 0x90, 0x4c, 0x77, 0xd9, 0x15, 0xbe, 0x63, 0x4b,
-       0x0b, 0xee, 0x4b, 0xda, 0x1a, 0xa1, 0xfd, 0x66, 0x2e, 0xe2, 0xcc, 0x53,
-       0xa8, 0x99, 0x8e, 0xa8, 0xbb, 0xaf, 0x70, 0x9f, 0x5b, 0xb4, 0x8b, 0x32,
-       0xaf, 0xcd, 0x69, 0x95, 0xb4, 0x3a, 0xe3, 0x37, 0x60, 0xeb, 0xba, 0x60,
-       0xd8, 0x77, 0x81, 0x5b, 0xa3, 0xa5, 0xe3, 0xba, 0xbc, 0xeb, 0x2c, 0x8f,
-       0xb2, 0xac, 0xf9, 0x79, 0x3d, 0xde, 0x45, 0x67, 0xfa, 0xdb, 0xf0, 0x4c,
-       0x5f, 0x0a, 0x6b, 0xed, 0xe8, 0x4c, 0x09, 0x7a, 0x63, 0xde, 0x04, 0xec,
-       0x08, 0xf8, 0x51, 0xa2, 0x95, 0x96, 0xf5, 0x39, 0x78, 0x6a, 0x6d, 0xbc,
-       0x31, 0x36, 0xc8, 0x30, 0xaa, 0x59, 0xc0, 0x83, 0x89, 0x0c, 0xec, 0x70,
-       0xba, 0x3f, 0xba, 0x83, 0xd5, 0x1d, 0xa1, 0xa9, 0xda, 0x9b, 0xe7, 0x07,
-       0x61, 0x8b, 0x16, 0xec, 0x93, 0xf3, 0x9d, 0x12, 0xd7, 0x19, 0xe1, 0xf7,
-       0x4b, 0xdb, 0x9c, 0xa4, 0x2c, 0x6a, 0x15, 0x3e, 0x7f, 0x9e, 0x96, 0x5b,
-       0x11, 0x0d, 0x39, 0xd8, 0xe3, 0x18, 0x7e, 0x23, 0x78, 0xe7, 0xe2, 0xc7,
-       0x75, 0x4e, 0x81, 0x1e, 0x93, 0x79, 0x34, 0xf2, 0xe4, 0x61, 0xa6, 0xef,
-       0x00, 0xd6, 0xb3, 0x3e, 0xb3, 0x9e, 0x1e, 0x20, 0x6f, 0x80, 0x7d, 0x45,
-       0x06, 0xb8, 0x01, 0xe3, 0xbf, 0x0e, 0x5b, 0x1f, 0xc4, 0xd3, 0x36, 0xcb,
-       0xcc, 0x5b, 0x89, 0x3f, 0x08, 0xf4, 0x1c, 0x7f, 0x3b, 0x18, 0x0f, 0xc7,
-       0x43, 0xe6, 0xdd, 0xac, 0x7b, 0x99, 0x1d, 0x74, 0x6e, 0x31, 0x8a, 0x61,
-       0x33, 0xb0, 0x41, 0xbe, 0x53, 0x1d, 0x07, 0x5f, 0x78, 0xac, 0x85, 0xb1,
-       0x0c, 0xf3, 0xcb, 0x0b, 0x38, 0x77, 0x9e, 0x4e, 0xa1, 0x66, 0xa7, 0x01,
-       0x7e, 0x22, 0x57, 0xf5, 0xb7, 0x84, 0xfa, 0xbe, 0x1e, 0x5e, 0x77, 0xb8,
-       0x3f, 0x0e, 0xfa, 0x8c, 0x36, 0x78, 0x86, 0x51, 0xb5, 0xc5, 0x45, 0x42,
-       0x2c, 0xcd, 0x04, 0xb7, 0x8b, 0xfc, 0x7d, 0xf4, 0x80, 0x3c, 0x53, 0x9e,
-       0x0e, 0x2f, 0x06, 0x81, 0x97, 0x1b, 0xca, 0x2e, 0x93, 0x9d, 0x7d, 0x92,
-       0xf6, 0x98, 0xfb, 0x48, 0x97, 0xdf, 0xe0, 0x50, 0x13, 0xdf, 0xde, 0x91,
-       0x0f, 0x82, 0x93, 0xa0, 0xfd, 0x05, 0xb9, 0xcf, 0x7d, 0xa0, 0x1f, 0xbc,
-       0x92, 0xf5, 0x04, 0xd3, 0x0a, 0xde, 0xa4, 0x99, 0xde, 0x24, 0x1d, 0x6e,
-       0x9d, 0x0f, 0x65, 0xf3, 0x28, 0x79, 0xfe, 0xdb, 0x3a, 0xdf, 0x47, 0x97,
-       0x5b, 0x4f, 0x86, 0xb4, 0xe5, 0x41, 0x2f, 0xf6, 0x6f, 0xbd, 0x90, 0x66,
-       0xdf, 0xc0, 0x32, 0xf7, 0x90, 0xf1, 0x79, 0xa3, 0xcf, 0x40, 0x07, 0x3f,
-       0xcd, 0x0f, 0xa4, 0x68, 0xbd, 0x1f, 0x60, 0xb8, 0xd4, 0x75, 0x74, 0x85,
-       0xe9, 0x20, 0xe9, 0x3f, 0x85, 0xb3, 0x19, 0xf4, 0x30, 0x3e, 0x7d, 0x83,
-       0x2f, 0xa8, 0xc8, 0xe7, 0xaa, 0xce, 0xbe, 0x89, 0xe3, 0x14, 0xeb, 0x70,
-       0x0f, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x5c, 0x5c, 0xe4, 0x3b, 0x85, 0x61,
-       0xbe, 0x87, 0x3a, 0x53, 0x82, 0x6c, 0x97, 0xf8, 0xbb, 0x60, 0x5a, 0xe5,
-       0x82, 0xaa, 0x76, 0xb2, 0xd8, 0x17, 0x32, 0xaf, 0xa5, 0x9f, 0x2c, 0xc9,
-       0xef, 0x80, 0x29, 0xac, 0x09, 0xf0, 0x6c, 0xff, 0x9b, 0x88, 0x9f, 0x14,
-       0xd4, 0xdf, 0x44, 0x84, 0xdf, 0x64, 0x1b, 0x2a, 0x07, 0x78, 0xb8, 0x69,
-       0xd0, 0x54, 0x33, 0xfa, 0x1b, 0x09, 0x96, 0x83, 0x83, 0x3a, 0x3e, 0x8a,
-       0xfb, 0x81, 0x8c, 0x2f, 0xd5, 0x75, 0xb2, 0xfc, 0x66, 0x98, 0xcf, 0x70,
-       0xfe, 0xce, 0x3c, 0xc4, 0x78, 0x59, 0xc9, 0x6f, 0x49, 0xec, 0x84, 0xfc,
-       0xc0, 0x73, 0xdf, 0x80, 0x2d, 0x65, 0xc2, 0x98, 0x6c, 0x72, 0x7d, 0x18,
-       0xd6, 0xac, 0xdb, 0xa9, 0x3a, 0xc9, 0xef, 0x13, 0xf4, 0xfa, 0xfc, 0xa0,
-       0x7c, 0x5f, 0xa6, 0x44, 0xf8, 0x9e, 0xc7, 0x29, 0x2a, 0xcb, 0xf7, 0xf7,
-       0x86, 0xf8, 0x50, 0x63, 0xdd, 0x1b, 0x8d, 0x33, 0x90, 0xa3, 0x82, 0x9b,
-       0x46, 0x2c, 0x7b, 0x0c, 0x71, 0x6c, 0x1a, 0x7c, 0x2f, 0x4e, 0x54, 0x68,
-       0x87, 0xc3, 0x3a, 0x0e, 0x99, 0xa5, 0x58, 0xc7, 0x58, 0xbf, 0x18, 0xa6,
-       0x17, 0x79, 0x26, 0xce, 0x3b, 0x4a, 0x53, 0x7a, 0xfe, 0xfd, 0x83, 0xe5,
-       0x9a, 0x6d, 0x16, 0xe8, 0xa3, 0xc0, 0x33, 0x78, 0xbc, 0x7a, 0xf0, 0x61,
-       0x75, 0x4f, 0x2f, 0x44, 0xfe, 0xd2, 0xc1, 0xb2, 0xea, 0xe3, 0xcc, 0xef,
-       0x87, 0x7d, 0x86, 0xd3, 0xe5, 0xf7, 0xd3, 0x7f, 0xbf, 0xd5, 0xa0, 0x8b,
-       0xb7, 0x06, 0xc1, 0xfd, 0xfc, 0x0d, 0x27, 0xac, 0x41, 0xd5, 0x77, 0x71,
-       0x8e, 0x13, 0xa8, 0x37, 0x46, 0x2d, 0xad, 0x04, 0xdb, 0x3d, 0xe5, 0xa3,
-       0x5e, 0x11, 0xf6, 0xd8, 0xaa, 0x30, 0x11, 0x7f, 0xb9, 0x96, 0xff, 0xcd,
-       0x7e, 0xfe, 0x26, 0x3c, 0xe7, 0xf2, 0x9a, 0x6d, 0xea, 0xae, 0xea, 0xe6,
-       0xdb, 0xa4, 0xcf, 0x25, 0x0a, 0xe3, 0xd0, 0xcd, 0xed, 0xf6, 0xd1, 0x9e,
-       0x23, 0xb2, 0x5d, 0xd0, 0x94, 0x01, 0x7a, 0xaa, 0xb5, 0x28, 0xdf, 0xe2,
-       0xef, 0xfd, 0xab, 0x07, 0xbf, 0xdb, 0xbc, 0x74, 0x70, 0x16, 0xf2, 0xe1,
-       0x33, 0xcd, 0x36, 0x23, 0xfd, 0x8b, 0x72, 0x7e, 0xee, 0x23, 0xfe, 0xfb,
-       0x88, 0xff, 0x3e, 0xe2, 0xbf, 0x8f, 0xf8, 0xef, 0x23, 0xfe, 0xfb, 0x88,
-       0xff, 0xe0, 0xe1, 0x0f, 0xa0, 0x2f, 0xe7, 0xfd, 0x89, 0x30, 0xdf, 0x7a,
-       0x7c, 0x2d, 0xdf, 0x3a, 0xd7, 0xe2, 0x6f, 0x3f, 0x92, 0x96, 0x4a, 0x85,
-       0x54, 0xbe, 0x4a, 0x82, 0xf3, 0x9b, 0x28, 0x5f, 0xbd, 0xfe, 0x37, 0x0c,
-       0x05, 0xc7, 0xb9, 0x1a, 0xc3, 0x55, 0x34, 0xe1, 0x30, 0x9c, 0xca, 0xd7,
-       0xb8, 0x46, 0x5a, 0x0f, 0xc3, 0xdf, 0xc9, 0xd8, 0xb7, 0xa9, 0x6f, 0x34,
-       0xea, 0x7b, 0xd0, 0xe3, 0x5f, 0xf7, 0x10, 0x8b, 0xcb, 0x4d, 0x19, 0x8f,
-       0x31, 0x7e, 0x06, 0x63, 0x83, 0xf5, 0x8f, 0xdf, 0xdd, 0xc3, 0x75, 0x41,
-       0xb9, 0x89, 0xbc, 0x68, 0x39, 0xca, 0x85, 0x00, 0xe7, 0xbf, 0xa9, 0x95,
-       0xea, 0x2c, 0x67, 0x41, 0xb3, 0x69, 0x30, 0xc5, 0x69, 0xaf, 0x75, 0x5e,
-       0x96, 0xb5, 0x8e, 0xfa, 0x9b, 0x9e, 0x11, 0xd0, 0x16, 0xdd, 0xfd, 0x12,
-       0xe9, 0xf3, 0x69, 0xf9, 0x77, 0x00, 0x29, 0x67, 0x58, 0xfe, 0x3d, 0x42,
-       0x1f, 0xf6, 0x11, 0xf3, 0x3b, 0xdb, 0xee, 0x56, 0xa9, 0xa0, 0x7c, 0x76,
-       0xa7, 0xfa, 0x3b, 0x08, 0x91, 0x86, 0xed, 0xde, 0xb6, 0x0d, 0x67, 0x83,
-       0x5c, 0x5f, 0xdd, 0x2a, 0xf3, 0x67, 0xf8, 0xd1, 0x93, 0xc3, 0x7d, 0x03,
-       0xd4, 0xb3, 0x9d, 0x4e, 0x0d, 0x73, 0xad, 0xb5, 0x19, 0xf8, 0x78, 0xad,
-       0x9d, 0x2d, 0x88, 0xed, 0x74, 0x7a, 0x11, 0x7e, 0x76, 0xd1, 0x76, 0x59,
-       0x97, 0x97, 0x86, 0xd3, 0xf0, 0xcf, 0x63, 0x03, 0x1c, 0x9f, 0x97, 0x5b,
-       0xac, 0x2b, 0x7d, 0x80, 0x1f, 0x84, 0x5e, 0x6e, 0x82, 0x3d, 0x09, 0xec,
-       0x1f, 0xe1, 0xfe, 0xb9, 0xc4, 0xdd, 0xe7, 0xec, 0xd9, 0x26, 0x75, 0x43,
-       0xd8, 0xa6, 0x25, 0x40, 0xfb, 0x27, 0x6a, 0x44, 0x97, 0xf8, 0x6c, 0xb3,
-       0x7e, 0xfb, 0xb7, 0xba, 0x37, 0xb5, 0x72, 0x9d, 0xff, 0x0e, 0x61, 0x98,
-       0xf6, 0x41, 0xbf, 0x4c, 0xe7, 0x4d, 0xed, 0x81, 0xc6, 0xff, 0x14, 0x6e,
-       0x75, 0xb1, 0x71, 0x5c, 0x55, 0xf8, 0xdc, 0x59, 0xaf, 0xed, 0x38, 0x6b,
-       0x67, 0xe2, 0x6c, 0xec, 0xb5, 0x15, 0xc4, 0xce, 0x7a, 0x12, 0x4f, 0xb5,
-       0x8e, 0x3a, 0xb6, 0x12, 0xb4, 0x42, 0x96, 0x58, 0xed, 0x7a, 0x5d, 0x87,
-       0x92, 0xb2, 0x85, 0x50, 0x05, 0x09, 0x55, 0x96, 0x9d, 0xd2, 0x54, 0x80,
-       0x90, 0xfa, 0x80, 0x78, 0xcb, 0x6a, 0x6d, 0x87, 0xa4, 0xec, 0x76, 0x6d,
-       0x62, 0xd7, 0x2f, 0x3c, 0x2c, 0xeb, 0x75, 0x6a, 0xbb, 0x9b, 0xac, 0x42,
-       0xfb, 0x50, 0x9e, 0x62, 0x99, 0x92, 0xc2, 0x4b, 0x85, 0xc4, 0x03, 0x02,
-       0x54, 0xa9, 0x4a, 0xda, 0x34, 0x0f, 0x25, 0x11, 0xbc, 0x50, 0x0a, 0xd2,
-       0xf0, 0x7d, 0x77, 0x66, 0x1d, 0x27, 0x50, 0x61, 0x69, 0x35, 0x77, 0xee,
-       0xdc, 0x3b, 0x73, 0x7f, 0xce, 0xf9, 0xce, 0x77, 0xce, 0x3d, 0x66, 0x1b,
-       0x1b, 0x65, 0xfa, 0xd3, 0xab, 0x6a, 0xa6, 0xda, 0x2b, 0x0b, 0x90, 0xe3,
-       0xe2, 0x48, 0x38, 0x88, 0x97, 0x76, 0x05, 0xfa, 0x0c, 0xc7, 0xdf, 0xb7,
-       0x57, 0x9a, 0x57, 0x16, 0xcd, 0x4e, 0xcd, 0xab, 0x1e, 0x7d, 0x76, 0x0a,
-       0x63, 0x8a, 0x61, 0x1d, 0xba, 0xfb, 0x34, 0x36, 0x19, 0xbc, 0xef, 0x7f,
-       0xec, 0xbe, 0xef, 0xb1, 0xfb, 0xc3, 0xff, 0xa3, 0x3d, 0xcb, 0x8f, 0xcb,
-       0x03, 0xc7, 0x69, 0xa5, 0xf8, 0x95, 0x62, 0xc9, 0x36, 0x66, 0x4b, 0x56,
-       0x9a, 0xbc, 0x20, 0x2b, 0x9e, 0xca, 0xba, 0xed, 0xc0, 0xbb, 0x76, 0x99,
-       0x5f, 0x86, 0xcc, 0x63, 0x1e, 0x1d, 0x36, 0xcf, 0xb4, 0x13, 0x7d, 0xd4,
-       0x99, 0x4e, 0x6c, 0x83, 0x61, 0x0f, 0xc5, 0xd0, 0xce, 0x7b, 0xc9, 0x4d,
-       0x9a, 0xe7, 0x74, 0x1c, 0x86, 0x7c, 0xc6, 0x53, 0x45, 0x9d, 0x9f, 0xc1,
-       0x36, 0x6d, 0x72, 0xc7, 0xce, 0xf4, 0x06, 0xf9, 0x3e, 0xf0, 0x5b, 0xc7,
-       0xfa, 0xc8, 0x35, 0x5e, 0x74, 0x77, 0xeb, 0xcc, 0xdb, 0xc2, 0x3c, 0x2a,
-       0x08, 0xcd, 0xb3, 0x22, 0xd5, 0xba, 0xc8, 0xeb, 0xf8, 0xfd, 0xae, 0x1e,
-       0xf8, 0x0a, 0x8a, 0x3e, 0xf3, 0xb8, 0x6c, 0x55, 0xbe, 0x2c, 0x0d, 0xd8,
-       0x9f, 0x4d, 0xd7, 0xf3, 0xee, 0xb9, 0x71, 0xbd, 0xe6, 0x3f, 0x29, 0x29,
-       0x49, 0x8c, 0xd2, 0xbe, 0xb5, 0xcb, 0x4f, 0x97, 0xdb, 0x64, 0xdb, 0xb4,
-       0xcc, 0x7b, 0xc2, 0x5c, 0xb6, 0x98, 0x4c, 0x45, 0x43, 0x9a, 0xa3, 0xca,
-       0xb7, 0xc0, 0xa0, 0xf1, 0xec, 0xee, 0xf2, 0x33, 0x7d, 0x8c, 0x9d, 0x7c,
-       0xb4, 0xcc, 0x7b, 0x03, 0x57, 0x43, 0x76, 0xec, 0x10, 0xb8, 0x2c, 0x40,
-       0xc8, 0xe4, 0xba, 0x73, 0xbe, 0xcf, 0x71, 0x6c, 0xa8, 0xa3, 0x2f, 0xda,
-       0x2e, 0xc5, 0xa3, 0xc0, 0x44, 0x35, 0xa4, 0x73, 0x8a, 0x76, 0xa2, 0x1a,
-       0xa3, 0x43, 0x35, 0xe6, 0xc8, 0x99, 0xfb, 0x35, 0x5e, 0x67, 0xae, 0x7d,
-       0x5f, 0xcf, 0x05, 0xe5, 0x42, 0xcd, 0xa5, 0xac, 0x9a, 0xb2, 0x09, 0x5d,
-       0xdb, 0x68, 0x2e, 0xf5, 0x73, 0xaf, 0xb6, 0x9a, 0x3f, 0xe8, 0xf3, 0x7d,
-       0x2d, 0xd6, 0xfd, 0xb0, 0xcf, 0xaf, 0x8b, 0x07, 0xbe, 0x13, 0x7d, 0xac,
-       0x2a, 0xe6, 0xf6, 0xb2, 0x34, 0x57, 0x7f, 0x2c, 0x6f, 0x57, 0x7e, 0x24,
-       0xbf, 0x5a, 0x3d, 0x0b, 0xfe, 0x61, 0x55, 0x0b, 0xb0, 0x27, 0x37, 0x9a,
-       0x9e, 0x77, 0xc3, 0x3d, 0x03, 0x5f, 0xc1, 0xf3, 0xfe, 0xe0, 0x6e, 0x4b,
-       0x62, 0xec, 0x3b, 0x98, 0x73, 0x1e, 0x3a, 0x44, 0x2c, 0x9c, 0x82, 0xbc,
-       0x25, 0xfb, 0xa5, 0x2b, 0xa2, 0xe5, 0x64, 0x68, 0x2c, 0x8c, 0x39, 0x18,
-       0x01, 0x27, 0xe7, 0x5c, 0x46, 0xfa, 0x29, 0x33, 0x46, 0xf3, 0x15, 0x7c,
-       0x3f, 0x0c, 0xbd, 0xd8, 0x8f, 0x9f, 0x92, 0x7b, 0xa3, 0x18, 0xeb, 0x28,
-       0x65, 0x2f, 0x2c, 0x89, 0x27, 0x31, 0x8f, 0x7c, 0x9b, 0xdc, 0x2f, 0x5d,
-       0xe9, 0x63, 0x5c, 0xee, 0x7e, 0x89, 0x65, 0xe3, 0x4b, 0x3d, 0xe2, 0x49,
-       0x1b, 0x6c, 0xf9, 0xfc, 0x09, 0x9f, 0x37, 0xfd, 0x5a, 0x0d, 0xa3, 0xbd,
-       0x5d, 0x78, 0x47, 0x91, 0xe7, 0x15, 0xbc, 0x30, 0x78, 0x79, 0x0e, 0x7c,
-       0x28, 0xd3, 0xbc, 0x20, 0x3b, 0xa3, 0x11, 0xb4, 0x21, 0x5f, 0xd1, 0x58,
-       0x22, 0xd9, 0x12, 0x73, 0xb0, 0x98, 0x0f, 0x85, 0x31, 0x9e, 0x21, 0x6e,
-       0x70, 0x8c, 0xed, 0x3c, 0xb7, 0x0b, 0xea, 0x6c, 0xc8, 0x08, 0xeb, 0x28,
-       0xdf, 0x69, 0xcd, 0xa9, 0x60, 0x43, 0xf1, 0xbe, 0x11, 0xc9, 0xe8, 0x72,
-       0x0f, 0xde, 0x77, 0x41, 0xe7, 0x25, 0xfa, 0xef, 0x4c, 0xa1, 0x0d, 0x71,
-       0x26, 0x05, 0x2e, 0xf1, 0xa1, 0x9a, 0x00, 0xbd, 0x99, 0x29, 0xf5, 0xc9,
-       0x84, 0xb9, 0x6f, 0xcf, 0x1c, 0x0b, 0xda, 0x57, 0x30, 0x8c, 0x91, 0x60,
-       0x4c, 0x3d, 0x7b, 0xc6, 0xc4, 0xfe, 0xf8, 0xc1, 0xc7, 0xcd, 0x2c, 0x2f,
-       0x02, 0xa7, 0x16, 0x7f, 0x9b, 0x71, 0x9f, 0x97, 0x6c, 0xb4, 0x5d, 0xfb,
-       0x36, 0x35, 0xec, 0x4b, 0xb6, 0xc4, 0x78, 0xd4, 0xb7, 0x81, 0x43, 0xfb,
-       0x82, 0x3a, 0xb6, 0x15, 0x23, 0x83, 0xb5, 0x4f, 0x6b, 0x3d, 0x64, 0xdd,
-       0x17, 0x25, 0xb3, 0x98, 0x97, 0x49, 0xdd, 0x8f, 0x6b, 0x38, 0xa8, 0x79,
-       0x08, 0x75, 0x35, 0x71, 0x08, 0x6b, 0x99, 0x0c, 0x07, 0x6d, 0xf7, 0x91,
-       0xc9, 0xe3, 0xef, 0xd3, 0x40, 0x67, 0xf1, 0xec, 0x10, 0xf7, 0xa8, 0x5d,
-       0x12, 0xdf, 0x84, 0xbd, 0x2c, 0xb5, 0xea, 0x23, 0xf2, 0x49, 0xe9, 0xb3,
-       0x3e, 0x9e, 0x93, 0xfc, 0xb5, 0x64, 0xca, 0x47, 0x25, 0x7d, 0x7e, 0x3a,
-       0x1d, 0x12, 0xeb, 0xbc, 0xef, 0x67, 0x1f, 0x9d, 0x9e, 0x57, 0x7c, 0x7e,
-       0xf4, 0xfc, 0xba, 0xea, 0x44, 0xdb, 0x08, 0xda, 0x71, 0x1c, 0xa6, 0xe4,
-       0x4a, 0x7f, 0xf7, 0x66, 0x8e, 0x79, 0xde, 0xa4, 0xce, 0xe1, 0x4a, 0x9a,
-       0xf3, 0xaa, 0xc5, 0xcf, 0x1d, 0x29, 0x45, 0x3b, 0xf0, 0xad, 0xa4, 0xb9,
-       0xae, 0x8e, 0x62, 0x3c, 0x2c, 0x1f, 0xa2, 0x4e, 0xc4, 0xb6, 0x85, 0xef,
-       0xb7, 0xa6, 0xd6, 0x54, 0x32, 0x3e, 0xa4, 0xac, 0x74, 0x11, 0xbf, 0x36,
-       0xa5, 0xcf, 0x1e, 0x63, 0x71, 0x05, 0xdd, 0xc5, 0x9c, 0xec, 0xe3, 0x9e,
-       0x37, 0x65, 0xb3, 0x3e, 0x69, 0x46, 0x14, 0xe3, 0x26, 0x5d, 0xfa, 0x8c,
-       0xf2, 0xd2, 0xe1, 0xa4, 0x79, 0x5c, 0x1d, 0x0c, 0xee, 0x53, 0xc0, 0xcc,
-       0xdd, 0xf7, 0x9d, 0x5d, 0x53, 0xa6, 0x5c, 0x2e, 0x25, 0xe3, 0xb3, 0xca,
-       0xca, 0xe3, 0x9d, 0xf9, 0x09, 0x45, 0xdc, 0x48, 0x9a, 0x5d, 0x8a, 0xb1,
-       0xcd, 0x0e, 0x3d, 0xef, 0x29, 0xf4, 0x4f, 0xaa, 0xb6, 0x60, 0x3c, 0xdc,
-       0xaf, 0xcb, 0xfd, 0xbe, 0xce, 0x10, 0x73, 0x06, 0x8c, 0x99, 0x45, 0xe6,
-       0x83, 0xe9, 0x3c, 0x84, 0x74, 0x62, 0x8c, 0xf7, 0x86, 0x3c, 0x38, 0xf9,
-       0x0f, 0xd4, 0xa1, 0x5c, 0x65, 0x9d, 0x13, 0xe8, 0xdb, 0x31, 0xcd, 0x9f,
-       0x1f, 0x9c, 0x2c, 0xe8, 0xfc, 0xc4, 0x1d, 0x95, 0x08, 0xe6, 0xbd, 0xbb,
-       0x67, 0xf1, 0x8c, 0xfb, 0x05, 0xbe, 0x67, 0x31, 0x34, 0xde, 0x21, 0xcc,
-       0x07, 0xcd, 0x55, 0x5a, 0xb2, 0xc1, 0xd8, 0x00, 0xcf, 0xf7, 0x5b, 0x67,
-       0xe5, 0x17, 0xc4, 0x18, 0xeb, 0xdc, 0x23, 0x27, 0xe0, 0x9d, 0xe0, 0xab,
-       0x75, 0xbc, 0xa7, 0xb8, 0x2c, 0x05, 0xbf, 0xbf, 0x74, 0x32, 0xff, 0xb4,
-       0x58, 0xff, 0xbc, 0x77, 0xf8, 0x36, 0x30, 0x87, 0xfb, 0x07, 0x27, 0x29,
-       0x9f, 0x5c, 0x9b, 0xb8, 0x9a, 0xbc, 0xc2, 0xf1, 0x0c, 0x4a, 0x6e, 0x19,
-       0xdc, 0x08, 0xbf, 0xf9, 0x65, 0x7f, 0xdf, 0xd6, 0xc1, 0xb3, 0x73, 0x25,
-       0x53, 0xeb, 0xeb, 0xac, 0xcb, 0xb3, 0x0f, 0xe8, 0x8a, 0xce, 0x7b, 0x62,
-       0x5f, 0xe6, 0x0a, 0x1e, 0xa1, 0x7d, 0x74, 0x6a, 0x12, 0x45, 0x5b, 0x72,
-       0x56, 0xd6, 0x83, 0xbf, 0xc3, 0x66, 0x16, 0x5f, 0x8d, 0x08, 0x30, 0x39,
-       0x15, 0x0f, 0x1d, 0x90, 0x79, 0xd7, 0x95, 0x46, 0xf3, 0x84, 0x5c, 0x6b,
-       0x3a, 0xfa, 0x19, 0xed, 0xd9, 0xc2, 0x6b, 0xfa, 0x5c, 0x3a, 0xfe, 0xa1,
-       0xb2, 0x9c, 0xab, 0xf0, 0x6b, 0xbe, 0x7b, 0x8c, 0x79, 0xc2, 0xe1, 0x81,
-       0x87, 0x79, 0x70, 0xc0, 0x0e, 0x70, 0x8e, 0xb7, 0xc0, 0x39, 0xde, 0x04,
-       0xe7, 0xf8, 0x25, 0x38, 0xf6, 0x8d, 0xca, 0x54, 0x80, 0xff, 0xd3, 0xc0,
-       0x21, 0xda, 0x6a, 0xeb, 0x2c, 0xf6, 0x74, 0xba, 0x00, 0x19, 0xfc, 0x00,
-       0xfe, 0xc7, 0x56, 0x25, 0x23, 0x1b, 0xab, 0x93, 0xb2, 0xb9, 0xea, 0xe7,
-       0x1c, 0xbf, 0xcb, 0x3c, 0xad, 0x51, 0xee, 0x93, 0x03, 0x1c, 0xda, 0x27,
-       0x89, 0xe3, 0xc4, 0x8f, 0x4e, 0x59, 0x2b, 0xaf, 0x69, 0x1c, 0x5a, 0x2b,
-       0xb3, 0x1c, 0x12, 0x9d, 0xf3, 0x75, 0x66, 0x5b, 0x6a, 0xee, 0x16, 0xea,
-       0xbb, 0x99, 0xdb, 0x15, 0xc4, 0xd6, 0x89, 0x97, 0x7f, 0x0e, 0xf6, 0x5e,
-       0xe9, 0x5c, 0xb8, 0x19, 0xf3, 0x00, 0xda, 0xb5, 0xb0, 0x6b, 0xc8, 0x3f,
-       0x27, 0x57, 0x7f, 0x41, 0x1b, 0x7c, 0x03, 0x9c, 0xf1, 0x2a, 0x6c, 0xc8,
-       0x8e, 0x73, 0x40, 0x73, 0xbf, 0x1d, 0xe7, 0x88, 0xce, 0xad, 0xe5, 0x7b,
-       0x8a, 0x65, 0x5b, 0xe6, 0xca, 0x56, 0xbc, 0x00, 0xf9, 0xbb, 0x06, 0xbf,
-       0x6d, 0x03, 0x7b, 0xb0, 0x89, 0xb5, 0xd8, 0x6a, 0xd2, 0xce, 0xbf, 0xaf,
-       0xb1, 0x77, 0xad, 0xf9, 0x27, 0xbc, 0xc7, 0x3a, 0x9b, 0x96, 0x3f, 0xf6,
-       0x13, 0x03, 0x99, 0x8f, 0x97, 0xd5, 0xfd, 0xfd, 0x7e, 0x1b, 0x68, 0xbb,
-       0xd9, 0x24, 0x1e, 0x8b, 0x5c, 0x2c, 0xd9, 0xb0, 0x25, 0x17, 0x63, 0xe4,
-       0x00, 0x55, 0xd5, 0xea, 0xe7, 0x05, 0x63, 0xf6, 0xbc, 0xfd, 0x36, 0xc7,
-       0xe5, 0x04, 0xb8, 0x4d, 0xdb, 0xbf, 0xad, 0xb9, 0x4d, 0xa9, 0xf2, 0xbc,
-       0x5c, 0x5f, 0x4d, 0x05, 0x1c, 0x27, 0x2f, 0x6f, 0x80, 0xe3, 0x35, 0x2b,
-       0xad, 0x1c, 0xed, 0x71, 0xac, 0x53, 0x45, 0xcd, 0x2d, 0x75, 0xc9, 0xa5,
-       0x95, 0xa2, 0xba, 0xbc, 0x52, 0x52, 0xaf, 0x2c, 0x95, 0x55, 0x71, 0xc9,
-       0xf3, 0xfe, 0xe9, 0xce, 0xc8, 0xdb, 0xab, 0x9e, 0x9c, 0x76, 0x8d, 0x81,
-       0x90, 0xb4, 0xf2, 0xdf, 0x3c, 0xaf, 0x13, 0xd8, 0xbc, 0x75, 0xd8, 0xf3,
-       0x9e, 0x18, 0x1d, 0x15, 0xe7, 0x30, 0x39, 0xca, 0x70, 0x8c, 0x39, 0xac,
-       0xc4, 0x9c, 0x8c, 0x6d, 0x9f, 0xaf, 0x29, 0x05, 0x7c, 0x3b, 0xe0, 0xf3,
-       0x97, 0x27, 0xbb, 0x83, 0x33, 0x8f, 0xb3, 0x2f, 0x31, 0x26, 0x1c, 0xfb,
-       0xaf, 0x98, 0xb0, 0x29, 0xe7, 0xca, 0x58, 0x88, 0xae, 0xa8, 0x7c, 0xaf,
-       0x1c, 0x79, 0xac, 0x6c, 0xe2, 0xea, 0x18, 0xc5, 0xf2, 0x7d, 0x6f, 0x48,
-       0xc7, 0xfe, 0xc1, 0x49, 0x4c, 0xcf, 0x9b, 0x75, 0xf9, 0xbd, 0x03, 0x8c,
-       0xc9, 0x98, 0xdd, 0xb0, 0xff, 0xa7, 0xb5, 0x7d, 0xae, 0xaa, 0x8c, 0x4d,
-       0xfd, 0x8e, 0xca, 0x44, 0x19, 0x36, 0x5e, 0x31, 0x2f, 0x94, 0x5c, 0xc1,
-       0x8a, 0xcd, 0x02, 0x3b, 0x66, 0x80, 0x37, 0x4f, 0xeb, 0xb3, 0xd1, 0x43,
-       0x1a, 0x7b, 0xe6, 0x58, 0xce, 0x4b, 0xba, 0xe6, 0xf6, 0xea, 0xf5, 0xbb,
-       0x7d, 0xad, 0x18, 0xf3, 0xf7, 0x1c, 0x7a, 0x9c, 0xe7, 0xf9, 0x40, 0xaf,
-       0x64, 0xd7, 0xcf, 0x40, 0x27, 0x62, 0x58, 0xdb, 0xb0, 0xd6, 0x87, 0x1d,
-       0xd8, 0xef, 0x1d, 0x27, 0x1c, 0x60, 0x6a, 0x27, 0xee, 0xd9, 0x6e, 0x12,
-       0xfd, 0x3a, 0x24, 0xb3, 0xd4, 0xae, 0x71, 0xf5, 0xd1, 0xba, 0x34, 0x78,
-       0x48, 0x0e, 0xe5, 0x10, 0xea, 0xe2, 0x41, 0x99, 0xdc, 0x6b, 0x1a, 0xe5,
-       0x36, 0x5c, 0xd9, 0xe6, 0x28, 0x78, 0x05, 0xae, 0xbf, 0xc0, 0xfb, 0x46,
-       0x31, 0xe6, 0xbc, 0x29, 0xef, 0x9d, 0xa4, 0x2d, 0x71, 0x0c, 0xe6, 0x1a,
-       0xcf, 0xda, 0xb8, 0x36, 0xca, 0x2a, 0xbb, 0xc8, 0x32, 0xae, 0x55, 0xff,
-       0xf9, 0x23, 0x98, 0x84, 0x3e, 0x99, 0x15, 0x1f, 0x93, 0xde, 0xdb, 0xc5,
-       0x24, 0xd6, 0x75, 0xc8, 0xc4, 0x52, 0x5c, 0x9d, 0xba, 0x62, 0x42, 0xde,
-       0xba, 0x24, 0xbb, 0x12, 0xd5, 0x7c, 0xb4, 0x06, 0x59, 0x5c, 0x87, 0x5c,
-       0xad, 0x41, 0xa6, 0x32, 0x65, 0x2b, 0x35, 0xad, 0xe2, 0x3a, 0x2e, 0x30,
-       0x05, 0x79, 0x0d, 0xbf, 0x4a, 0x2e, 0x4a, 0xfd, 0x75, 0xd0, 0x46, 0x68,
-       0x47, 0xd3, 0x61, 0x65, 0x43, 0x0e, 0x21, 0x97, 0x65, 0x5f, 0x7f, 0xdf,
-       0x51, 0x1a, 0x57, 0x53, 0x77, 0x24, 0xe9, 0xdc, 0x11, 0xcb, 0xdd, 0xc1,
-       0xef, 0x37, 0xe2, 0xca, 0x55, 0xe8, 0xfb, 0xeb, 0xf8, 0x4e, 0xf8, 0x35,
-       0x43, 0x8e, 0x0d, 0x6b, 0x9d, 0x4e, 0x49, 0xc8, 0x72, 0x36, 0xc5, 0xd7,
-       0xf1, 0x75, 0xad, 0xe3, 0x90, 0x37, 0x60, 0x90, 0xaf, 0xd3, 0xe9, 0x40,
-       0x46, 0xbf, 0x01, 0xfd, 0xb5, 0xe0, 0x95, 0xc5, 0x65, 0x1e, 0xfa, 0x7f,
-       0x15, 0xcf, 0x6f, 0x36, 0x3f, 0x56, 0x73, 0x8b, 0x2a, 0xc8, 0x3f, 0x79,
-       0x0e, 0x3c, 0xf9, 0xf7, 0x58, 0xbb, 0x1e, 0xcd, 0xdd, 0x13, 0xa3, 0x3c,
-       0x07, 0xfb, 0xb7, 0xba, 0x64, 0x1f, 0x97, 0xdb, 0x23, 0x27, 0x50, 0xee,
-       0xc6, 0xd5, 0xc0, 0x3a, 0x44, 0xf4, 0xf9, 0xf5, 0x5a, 0x69, 0xc4, 0x28,
-       0xea, 0x33, 0xe6, 0x31, 0xf4, 0x25, 0x96, 0x1d, 0xc6, 0x73, 0xc6, 0x65,
-       0x38, 0x37, 0x70, 0x26, 0x15, 0xd3, 0x39, 0xa1, 0x35, 0x70, 0x89, 0x75,
-       0xbc, 0xef, 0x16, 0xe3, 0x7a, 0x0d, 0xe8, 0xf0, 0xc8, 0x67, 0x5e, 0x3a,
-       0xca, 0xbc, 0xf3, 0xf7, 0x63, 0xbe, 0xfd, 0xfb, 0xc4, 0xbb, 0x6d, 0xcf,
-       0xa5, 0x0c, 0xdc, 0x7c, 0x60, 0x02, 0xef, 0xc8, 0xdb, 0x61, 0x8b, 0xaa,
-       0x5a, 0x7e, 0xd9, 0xce, 0xef, 0x5b, 0x6c, 0x24, 0xcd, 0x77, 0xc5, 0xef,
-       0x3b, 0x6f, 0xd3, 0xee, 0x74, 0x00, 0x5f, 0xe2, 0x9a, 0x57, 0xde, 0xb2,
-       0x0b, 0x40, 0x05, 0x2b, 0x3e, 0x05, 0x19, 0x6d, 0x17, 0xcb, 0xc9, 0xc9,
-       0xc3, 0xef, 0xce, 0xea, 0xbe, 0x6c, 0xdb, 0xea, 0xdb, 0xfa, 0x2e, 0xc7,
-       0xcf, 0xb9, 0x70, 0x0e, 0xf0, 0x6d, 0x4c, 0x53, 0xcb, 0xe8, 0x4e, 0xc3,
-       0x18, 0xf0, 0x65, 0xb4, 0x35, 0x8f, 0xe8, 0xff, 0x99, 0x07, 0xe5, 0x64,
-       0xc4, 0xf0, 0xcf, 0xdb, 0x71, 0x6d, 0x70, 0x3d, 0x3f, 0x06, 0xbf, 0xdf,
-       0x2b, 0x3f, 0xad, 0x38, 0xa3, 0x2f, 0x3f, 0x4f, 0xec, 0xca, 0x0f, 0x7d,
-       0xd4, 0x2e, 0xc9, 0xad, 0xd8, 0x32, 0x59, 0xd6, 0xfb, 0x0d, 0xae, 0xc9,
-       0xf8, 0xd1, 0x09, 0xc8, 0x0d, 0x65, 0x9d, 0xba, 0x65, 0x4a, 0x15, 0x72,
-       0x54, 0x05, 0x3e, 0x55, 0x21, 0x53, 0xe4, 0x40, 0x55, 0xe0, 0x5b, 0xb5,
-       0x69, 0x39, 0x75, 0xcc, 0x99, 0x36, 0x7b, 0x1d, 0x72, 0x74, 0xb5, 0xc9,
-       0xfd, 0xd7, 0x63, 0x36, 0x69, 0x07, 0x6f, 0xee, 0xee, 0xfd, 0xa7, 0xd8,
-       0xfb, 0x23, 0x72, 0x0d, 0x7e, 0xcb, 0xf5, 0xca, 0x08, 0x30, 0x49, 0x80,
-       0x51, 0x2e, 0x64, 0x23, 0x25, 0x1b, 0x95, 0x71, 0xd9, 0x84, 0x7d, 0xda,
-       0x5a, 0x4d, 0x80, 0x4f, 0x03, 0x47, 0xaf, 0x1c, 0x93, 0x37, 0x56, 0x95,
-       0xcc, 0xd8, 0xb0, 0x33, 0x6b, 0x8c, 0xc1, 0x43, 0x9e, 0xab, 0x5d, 0xfa,
-       0xbc, 0x7d, 0xa2, 0xee, 0xc7, 0xe2, 0x73, 0xf5, 0x1e, 0x99, 0xac, 0x9b,
-       0xf2, 0x54, 0xbd, 0x57, 0xbe, 0x5a, 0x8f, 0xca, 0xe9, 0x46, 0x4c, 0xbe,
-       0x56, 0x1f, 0x94, 0xa7, 0xeb, 0x47, 0xe4, 0x99, 0x46, 0x5c, 0xbe, 0x0e,
-       0xbf, 0x30, 0xdf, 0x70, 0x64, 0xaa, 0x31, 0x22, 0xa7, 0x1a, 0x8c, 0xb1,
-       0xe3, 0x7b, 0xf8, 0x65, 0x77, 0x63, 0x17, 0x1c, 0x57, 0x27, 0xc6, 0xe5,
-       0xa8, 0x9c, 0x3e, 0x6f, 0x94, 0xbc, 0x1f, 0xff, 0x10, 0x79, 0x01, 0x7d,
-       0x17, 0xae, 0x28, 0xa9, 0xe9, 0xef, 0xb7, 0xfe, 0x47, 0x24, 0xa2, 0x7d,
-       0xa3, 0x17, 0xaa, 0x83, 0x68, 0x63, 0xd3, 0x27, 0x09, 0xe2, 0x20, 0xad,
-       0xf8, 0x7f, 0xcb, 0xf7, 0x32, 0x74, 0x0c, 0xfb, 0x26, 0x7d, 0x2f, 0xbd,
-       0xf6, 0xc4, 0x0f, 0xfa, 0x39, 0xf4, 0xb5, 0xf6, 0x9e, 0x51, 0xb4, 0xbe,
-       0xbb, 0x90, 0x7f, 0xf4, 0x7f, 0x51, 0xfc, 0xb3, 0xa6, 0x73, 0x8d, 0x41,
-       0xfe, 0x4f, 0x0a, 0xc6, 0xf2, 0xf9, 0xf9, 0xdd, 0x93, 0x95, 0x09, 0xf5,
-       0x54, 0x85, 0x8c, 0xc6, 0x93, 0x85, 0xdd, 0x3c, 0xba, 0xaf, 0xc8, 0x9a,
-       0x1b, 0xd1, 0x63, 0xf0, 0xe3, 0xf6, 0x69, 0x9d, 0x53, 0x37, 0x31, 0x4c,
-       0xf9, 0xe3, 0x19, 0x5a, 0x4f, 0x70, 0xb6, 0x00, 0x6e, 0xeb, 0x9a, 0x72,
-       0xb1, 0xee, 0xc7, 0xaf, 0xe6, 0xb4, 0xbc, 0x5c, 0x87, 0xcc, 0xf1, 0xfc,
-       0xc1, 0xbf, 0x16, 0xaa, 0x7e, 0xdf, 0xec, 0xb0, 0x43, 0x7f, 0x1c, 0xf3,
-       0x35, 0x7a, 0xf9, 0x2d, 0xfe, 0x4f, 0x0e, 0xca, 0xc1, 0x78, 0x99, 0x0f,
-       0x6c, 0x6b, 0x59, 0xf4, 0xcf, 0x67, 0x1d, 0x79, 0x11, 0x7b, 0x51, 0x33,
-       0x39, 0xfe, 0x4e, 0xa9, 0x39, 0xf4, 0x6d, 0x89, 0xdf, 0xc3, 0x52, 0xc5,
-       0x77, 0x6a, 0x4e, 0x2b, 0x36, 0xe6, 0xe3, 0x6c, 0xcd, 0x7c, 0xf8, 0xdd,
-       0xe9, 0xea, 0x41, 0xdc, 0xa3, 0xce, 0x01, 0x67, 0x3a, 0xc3, 0xfb, 0x05,
-       0x94, 0x19, 0x1b, 0x99, 0xc3, 0x35, 0x16, 0xd4, 0xfd, 0x7c, 0x40, 0x73,
-       0xf5, 0xf1, 0x87, 0xfd, 0x66, 0xaa, 0x56, 0x21, 0x13, 0xba, 0xab, 0x8c,
-       0x9f, 0xad, 0x0f, 0x10, 0x73, 0x0f, 0xda, 0xfc, 0x45, 0xe4, 0x6f, 0xa6,
-       0x8e, 0x29, 0x04, 0xcf, 0xf6, 0xc9, 0xb3, 0x26, 0x73, 0xcd, 0xd3, 0x6a,
-       0xa2, 0xf2, 0x72, 0x90, 0x57, 0x7b, 0x57, 0x1d, 0xac, 0x35, 0x07, 0xfc,
-       0xbc, 0x74, 0xbe, 0x7b, 0x6f, 0x2e, 0xfa, 0x5e, 0x39, 0x61, 0x4e, 0x7a,
-       0x07, 0x78, 0xab, 0x36, 0x62, 0xd0, 0x41, 0xe0, 0x9d, 0xdd, 0xa6, 0xf5,
-       0xb1, 0xd8, 0xf8, 0x97, 0xb7, 0xad, 0xf5, 0xb9, 0x15, 0x63, 0xb8, 0x35,
-       0x40, 0xdf, 0x96, 0xb8, 0x71, 0xd1, 0x8f, 0x1b, 0x69, 0x1f, 0x1a, 0x58,
-       0x81, 0x3a, 0xea, 0x2a, 0xf4, 0x64, 0xb7, 0x2d, 0xff, 0xfe, 0x03, 0x7d,
-       0xe7, 0x95, 0xf0, 0x2c, 0x67, 0x00, 0x00, 0x00 };
+       0xec, 0x5b, 0x6d, 0x6c, 0x5c, 0x57, 0x5a, 0x7e, 0xef, 0x99, 0xb1, 0x3d,
+       0x76, 0x6c, 0xe7, 0xda, 0x99, 0xa6, 0x93, 0xe2, 0x6e, 0x67, 0xec, 0x6b,
+       0x7b, 0xba, 0x36, 0xe5, 0x3a, 0x4c, 0x5b, 0xaf, 0x18, 0xb6, 0xc3, 0x1d,
+       0x27, 0x75, 0x77, 0x83, 0xe4, 0xb6, 0x61, 0x37, 0x82, 0xae, 0xb0, 0x66,
+       0x12, 0x51, 0x84, 0x10, 0x21, 0x82, 0xaa, 0x2c, 0x5d, 0x65, 0x34, 0x76,
+       0x53, 0xb7, 0x3b, 0xf1, 0x0c, 0x89, 0x4b, 0xf8, 0xd8, 0x1f, 0xee, 0xd8,
+       0x4e, 0x0a, 0x9a, 0x78, 0xba, 0xcb, 0x8f, 0x5d, 0x56, 0x4d, 0x63, 0xd2,
+       0x12, 0xfa, 0x03, 0x89, 0x16, 0x56, 0x50, 0x89, 0x85, 0x86, 0x24, 0xdb,
+       0x14, 0x09, 0x41, 0x77, 0x01, 0x6d, 0xa1, 0x69, 0x2f, 0xcf, 0x73, 0xee,
+       0xbd, 0xc9, 0xc4, 0x35, 0x6c, 0x7f, 0xf0, 0xf3, 0x1e, 0xc9, 0xba, 0xf7,
+       0x9e, 0xf3, 0x9e, 0xf7, 0xbc, 0xdf, 0x1f, 0x67, 0x92, 0xdf, 0xe8, 0x96,
+       0x2e, 0xf1, 0x47, 0x0f, 0xfe, 0x32, 0x87, 0x9f, 0x3c, 0x72, 0xef, 0x3d,
+       0xf6, 0x3d, 0xfc, 0x8e, 0xb4, 0x49, 0x94, 0x4f, 0x43, 0xc2, 0x11, 0x8e,
+       0x70, 0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70,
+       0x84, 0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84,
+       0x23, 0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23,
+       0x1c, 0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c,
+       0xe1, 0x08, 0x47, 0x38, 0xc2, 0x11, 0x8e, 0x70, 0x84, 0x23, 0x1c, 0xe1,
+       0x08, 0x47, 0x38, 0xc2, 0xf1, 0xff, 0x39, 0x22, 0x22, 0x26, 0x9f, 0x3d,
+       0xfe, 0x9f, 0xc4, 0x54, 0x56, 0x8e, 0x38, 0x96, 0xc4, 0x22, 0xd9, 0xd5,
+       0x27, 0x8a, 0x96, 0x48, 0xae, 0x31, 0x96, 0xcc, 0xcb, 0x87, 0x6e, 0x29,
+       0x1e, 0x15, 0xce, 0xdf, 0x99, 0xbd, 0x7e, 0xf4, 0xdc, 0xfd, 0xa9, 0xf7,
+       0x96, 0x23, 0x12, 0x33, 0xb3, 0x6f, 0x4c, 0x98, 0x23, 0x12, 0x1b, 0xc0,
+       0x9e, 0xaf, 0x8d, 0xbe, 0xbc, 0x5d, 0x7a, 0x03, 0x5c, 0x22, 0xf5, 0x4a,
+       0xca, 0xde, 0x2b, 0x63, 0xe6, 0x05, 0x89, 0x4a, 0x0e, 0x67, 0x9c, 0x6e,
+       0x88, 0x94, 0x2b, 0x06, 0x71, 0x48, 0xb9, 0x11, 0x93, 0x4b, 0x11, 0x42,
+       0x7d, 0xcb, 0x70, 0xaa, 0x1f, 0xb9, 0xb9, 0x28, 0xce, 0xb5, 0xf0, 0xde,
+       0x0c, 0xe6, 0x63, 0xa2, 0xb2, 0xa9, 0x84, 0x13, 0x99, 0x96, 0xc2, 0x92,
+       0xeb, 0xce, 0xdb, 0xb7, 0x03, 0x47, 0xbf, 0xcc, 0x5b, 0xde, 0xb7, 0x63,
+       0x7f, 0xda, 0x9c, 0x92, 0x1d, 0x98, 0x8b, 0x88, 0xb2, 0xee, 0xc0, 0xdf,
+       0x57, 0x0d, 0x67, 0xa5, 0x5b, 0xca, 0x55, 0xc9, 0x39, 0x76, 0x0c, 0xf3,
+       0x09, 0x99, 0xab, 0x26, 0x0d, 0xe7, 0xa4, 0x21, 0xc5, 0x0c, 0xde, 0x9b,
+       0xae, 0x38, 0xf6, 0x47, 0xae, 0x63, 0x11, 0xff, 0x92, 0xe1, 0x9c, 0xf9,
+       0xc8, 0x55, 0x96, 0x65, 0x16, 0x84, 0xdf, 0x09, 0x29, 0x37, 0x89, 0x87,
+       0xef, 0xc4, 0x73, 0xc9, 0x3d, 0x37, 0x9a, 0x90, 0x6f, 0x34, 0xe3, 0xf2,
+       0xf5, 0xa6, 0x29, 0x2f, 0x35, 0x07, 0xe4, 0x7c, 0xd3, 0x75, 0xbf, 0x6e,
+       0xbb, 0xee, 0x1b, 0xf8, 0xfb, 0x81, 0x7d, 0x83, 0x66, 0x8c, 0x92, 0x31,
+       0xd5, 0xfc, 0xc3, 0x6e, 0xe9, 0x4d, 0x25, 0x45, 0x75, 0xe3, 0xcc, 0x84,
+       0xcc, 0x57, 0x2b, 0xc6, 0xc3, 0x67, 0x16, 0x8d, 0x99, 0x33, 0x35, 0x23,
+       0x7f, 0x26, 0x8a, 0x39, 0x29, 0x95, 0xed, 0x17, 0x8d, 0x7c, 0x73, 0xc1,
+       0x78, 0xe4, 0x4c, 0xaf, 0xa6, 0xad, 0x5c, 0xdd, 0x09, 0xda, 0xae, 0x83,
+       0x26, 0xca, 0x34, 0x65, 0xfe, 0x3c, 0xc4, 0xec, 0x54, 0xc8, 0x57, 0xbb,
+       0xe4, 0xe2, 0x5c, 0x77, 0x5d, 0x95, 0x75, 0x8f, 0x3a, 0x19, 0xcb, 0x2c,
+       0x0b, 0xe9, 0xd3, 0x73, 0xe7, 0x23, 0xa0, 0x39, 0x2f, 0xa7, 0x41, 0x7f,
+       0xb7, 0x91, 0x3f, 0x15, 0x05, 0x1d, 0x32, 0x10, 0x11, 0xee, 0x1b, 0x4e,
+       0x14, 0xa4, 0x81, 0x33, 0xc4, 0x54, 0x59, 0xca, 0x11, 0x34, 0x83, 0x96,
+       0x6f, 0x54, 0xc1, 0x43, 0x15, 0x3c, 0x54, 0xc9, 0x5b, 0x52, 0xce, 0x8d,
+       0x06, 0xbc, 0xb9, 0xee, 0x5f, 0xdb, 0xa4, 0x3d, 0x95, 0xcc, 0xa9, 0x80,
+       0x4f, 0xd7, 0xfd, 0xbe, 0x4d, 0x5e, 0xc9, 0x8f, 0xeb, 0xbe, 0x64, 0x53,
+       0x86, 0xee, 0x79, 0x65, 0x55, 0xc0, 0x8b, 0x05, 0xfc, 0x94, 0xef, 0x22,
+       0x78, 0x58, 0x00, 0x7f, 0xa7, 0xc1, 0x5b, 0x0d, 0x74, 0xfc, 0xa8, 0xf3,
+       0x4a, 0x46, 0x7e, 0xf4, 0x86, 0xbc, 0x92, 0x94, 0x71, 0x61, 0x55, 0x41,
+       0xd6, 0xdb, 0xa4, 0xb0, 0x6c, 0xca, 0xec, 0x6a, 0xb0, 0x3f, 0xd0, 0xfb,
+       0x61, 0xd9, 0x57, 0xed, 0x87, 0x6c, 0x28, 0xcb, 0x94, 0x2d, 0x42, 0xbd,
+       0x95, 0xd3, 0x4a, 0xc4, 0x28, 0xd8, 0x47, 0xb5, 0xbe, 0x57, 0x2d, 0xc9,
+       0x15, 0x6c, 0xca, 0x51, 0x92, 0x05, 0xbb, 0x94, 0x88, 0xc2, 0xbe, 0x56,
+       0xad, 0x92, 0x19, 0x15, 0xca, 0x31, 0x95, 0xf8, 0x32, 0x64, 0x79, 0xa8,
+       0x22, 0xb9, 0xcf, 0x55, 0x02, 0x19, 0x7b, 0xf2, 0xfd, 0x7c, 0xe5, 0xa7,
+       0x7b, 0xa4, 0x4b, 0x7d, 0xaa, 0x4d, 0x7e, 0x15, 0x7b, 0x89, 0xfb, 0x96,
+       0xbd, 0xd8, 0xe7, 0xc1, 0x79, 0x7b, 0x53, 0x07, 0x44, 0x08, 0x5b, 0x1e,
+       0x6a, 0xf3, 0x7c, 0xc2, 0x70, 0xac, 0x52, 0x22, 0x02, 0xb8, 0x82, 0x94,
+       0x27, 0xfc, 0xb9, 0x36, 0xc7, 0xba, 0x1e, 0x99, 0xb7, 0x53, 0xc9, 0xb2,
+       0x5c, 0x8f, 0x5c, 0xb4, 0xf5, 0x5c, 0xa7, 0x63, 0xb9, 0xb2, 0x06, 0xec,
+       0xcf, 0xc0, 0xfe, 0x2f, 0x80, 0xa3, 0x5f, 0xae, 0xe8, 0xf9, 0x1e, 0xec,
+       0x4f, 0xb7, 0x01, 0x67, 0x97, 0xa4, 0xd2, 0x75, 0xcc, 0x5f, 0xf4, 0xe6,
+       0xfb, 0x3c, 0xbc, 0xe5, 0xa1, 0x2e, 0x8d, 0x5b, 0xe4, 0x45, 0x6f, 0xfe,
+       0x36, 0x0f, 0x77, 0xf9, 0x6e, 0xcc, 0x03, 0xff, 0xc8, 0xf4, 0xa8, 0xa1,
+       0xe7, 0x77, 0xd1, 0x7f, 0x7e, 0xa9, 0x72, 0x3d, 0xb2, 0x66, 0xbb, 0x92,
+       0x9f, 0x18, 0x99, 0x1e, 0x31, 0x3c, 0x7c, 0xc7, 0xbc, 0x7d, 0x77, 0x7a,
+       0xf8, 0x46, 0xa6, 0xd3, 0x86, 0x87, 0x6f, 0xb5, 0xa2, 0xf7, 0x4a, 0xa1,
+       0x42, 0xd8, 0x91, 0x69, 0xcb, 0xb8, 0x53, 0x66, 0xfb, 0x46, 0xa6, 0x07,
+       0x0d, 0xf5, 0xa9, 0x6d, 0x1e, 0x1f, 0xa9, 0x80, 0x86, 0x6d, 0x9a, 0x06,
+       0x9e, 0xab, 0xe7, 0x87, 0x1d, 0xab, 0x7c, 0xf7, 0x36, 0x7d, 0x3e, 0xcf,
+       0xd4, 0x73, 0x77, 0x93, 0x2e, 0x9e, 0x5d, 0x9c, 0xb8, 0xe5, 0xdc, 0x1f,
+       0xbf, 0x29, 0x9f, 0xad, 0xce, 0xe4, 0x79, 0x12, 0x8b, 0x66, 0xa3, 0x13,
+       0xf3, 0x95, 0xc3, 0xe2, 0x54, 0x93, 0x32, 0x37, 0xde, 0x29, 0xb3, 0xe6,
+       0xd0, 0xec, 0x3e, 0x61, 0xac, 0x89, 0x4d, 0x14, 0x7d, 0x1d, 0xe6, 0xc5,
+       0x90, 0x39, 0xf0, 0xb8, 0xaf, 0x21, 0x31, 0x03, 0xf0, 0x43, 0x8d, 0xa8,
+       0x3c, 0xdb, 0x34, 0xa4, 0x5d, 0xfb, 0x67, 0xca, 0xdc, 0x80, 0x1d, 0x3e,
+       0x5d, 0xa5, 0x1d, 0xd3, 0x66, 0x25, 0x57, 0x87, 0x9d, 0x9e, 0xd7, 0xbe,
+       0xda, 0x45, 0xbd, 0x96, 0x4a, 0x02, 0x57, 0xcc, 0x5a, 0x66, 0x5d, 0x3a,
+       0x24, 0x37, 0x23, 0x25, 0xae, 0xfb, 0xbe, 0x93, 0x58, 0x91, 0x73, 0xb0,
+       0x01, 0x31, 0x9d, 0x0c, 0xe7, 0x09, 0xdf, 0x02, 0x6b, 0x7a, 0x7e, 0x17,
+       0x81, 0xdf, 0x15, 0x33, 0x84, 0x95, 0x92, 0x93, 0xa1, 0xef, 0xc1, 0x16,
+       0x9b, 0xbb, 0x7a, 0xbc, 0xd8, 0x86, 0xd8, 0x12, 0xef, 0x86, 0x8f, 0x7f,
+       0x0a, 0xfe, 0x37, 0x60, 0x38, 0xa7, 0x5c, 0xb7, 0x68, 0x4b, 0x5c, 0x09,
+       0xfd, 0x0f, 0xbe, 0xde, 0xe4, 0x5a, 0x37, 0xe6, 0xc5, 0x9c, 0xb3, 0xfb,
+       0xc0, 0x9f, 0xeb, 0x4e, 0xdb, 0x49, 0x29, 0xdb, 0xdb, 0xb1, 0xaf, 0x4d,
+       0xfa, 0x2c, 0xda, 0x3b, 0x7d, 0x7a, 0x1b, 0xce, 0x33, 0xf8, 0xdd, 0x8b,
+       0xf3, 0x7a, 0x30, 0x97, 0x98, 0xa3, 0x1f, 0x67, 0xc6, 0xc0, 0xbf, 0x17,
+       0x2f, 0x45, 0xde, 0x06, 0xad, 0xdc, 0xa3, 0xe1, 0x62, 0x1d, 0xd9, 0x8c,
+       0x5c, 0xab, 0xec, 0x92, 0x4b, 0x71, 0xf2, 0x0f, 0x9c, 0x55, 0xc4, 0xc4,
+       0xb8, 0x01, 0xfa, 0x13, 0x7e, 0xdc, 0xdb, 0xe1, 0x7f, 0x1b, 0x77, 0x79,
+       0x67, 0x88, 0x19, 0xc9, 0xf6, 0x4a, 0x5e, 0xcf, 0x89, 0x52, 0x13, 0xdb,
+       0xfc, 0xf5, 0x5e, 0x63, 0xef, 0x29, 0x25, 0xa3, 0xf7, 0x21, 0x66, 0xe1,
+       0xac, 0x8b, 0x96, 0xeb, 0x5e, 0xb4, 0xbf, 0x0f, 0x9f, 0x57, 0xd2, 0x66,
+       0xfd, 0x63, 0xaf, 0x74, 0x41, 0x9e, 0x55, 0xa3, 0x45, 0x86, 0x09, 0x39,
+       0x56, 0xe5, 0x9e, 0x92, 0x44, 0x2d, 0xc2, 0x10, 0xfe, 0xef, 0x01, 0x17,
+       0x91, 0x0e, 0xf8, 0xe2, 0x05, 0x3b, 0x4e, 0x7a, 0xb7, 0x7b, 0xf0, 0x7d,
+       0x38, 0x83, 0xb4, 0xd3, 0xf7, 0x5c, 0xed, 0x7b, 0x4e, 0x44, 0xe5, 0xa6,
+       0x96, 0xe0, 0x49, 0xe3, 0x94, 0xb7, 0xd3, 0x87, 0x50, 0x2f, 0x73, 0xa3,
+       0x25, 0x53, 0x69, 0x5d, 0x8b, 0xe4, 0x2b, 0x77, 0xc9, 0xbc, 0x8d, 0xf3,
+       0xac, 0x28, 0x68, 0x66, 0x9c, 0x19, 0x2e, 0x45, 0x14, 0x3c, 0xac, 0x9f,
+       0xb2, 0x0a, 0x68, 0x7d, 0x0b, 0xe7, 0x95, 0x8c, 0xa8, 0xc5, 0x33, 0xbe,
+       0xe4, 0xcb, 0x87, 0x76, 0x67, 0x8b, 0x53, 0xe9, 0xe6, 0x37, 0xe8, 0xe8,
+       0xd2, 0x74, 0x44, 0xb2, 0x5a, 0x77, 0x86, 0xca, 0x52, 0x96, 0x6d, 0x3e,
+       0x3d, 0xb7, 0xe0, 0x01, 0x1f, 0xdc, 0x6b, 0x61, 0x6f, 0x0c, 0x34, 0xf6,
+       0xb4, 0xd0, 0xdf, 0x45, 0x78, 0xc8, 0x2a, 0xe6, 0x9f, 0xa1, 0xf9, 0x36,
+       0x3c, 0xbe, 0x03, 0x59, 0x7d, 0x1b, 0xb2, 0xfa, 0xc0, 0x1d, 0xdd, 0x4d,
+       0x1c, 0x19, 0xe0, 0x60, 0x1e, 0x62, 0xbc, 0x62, 0x8c, 0x32, 0x6f, 0xe0,
+       0x82, 0x1f, 0xa8, 0x48, 0xb6, 0x5b, 0xf2, 0xa6, 0xce, 0x01, 0x80, 0x9d,
+       0x14, 0x1d, 0xe3, 0x2d, 0xf2, 0xe8, 0x7f, 0x5b, 0x29, 0x6d, 0x37, 0x85,
+       0x1a, 0xf3, 0xc0, 0x57, 0x40, 0xdb, 0x46, 0x4a, 0x69, 0xd6, 0xba, 0x21,
+       0x73, 0x89, 0xb5, 0x65, 0xdf, 0x90, 0xb5, 0x8a, 0xda, 0xd9, 0x2e, 0xdb,
+       0x65, 0x06, 0x32, 0xaa, 0x4f, 0x22, 0x7f, 0x8e, 0x77, 0x4b, 0xe4, 0x1e,
+       0xe6, 0x81, 0x04, 0x68, 0xdd, 0x48, 0x99, 0x72, 0xdd, 0x55, 0x23, 0xd8,
+       0x3f, 0x0e, 0x3d, 0xec, 0xa7, 0x4e, 0x95, 0x0f, 0x47, 0x98, 0x08, 0x65,
+       0xde, 0xdf, 0x2e, 0xc4, 0xcd, 0xb5, 0xb1, 0x84, 0x29, 0x9c, 0xef, 0x84,
+       0x5e, 0xb9, 0x97, 0xfc, 0x79, 0x7b, 0x3e, 0xce, 0x5f, 0xb0, 0x4e, 0x99,
+       0x51, 0x76, 0xb0, 0x31, 0xf0, 0xe8, 0xd8, 0x3f, 0xeb, 0xcb, 0xe6, 0x76,
+       0xb9, 0x64, 0x8a, 0x51, 0xb7, 0x6f, 0x6b, 0x91, 0x1f, 0x79, 0xee, 0xdb,
+       0xc4, 0x33, 0x71, 0x6c, 0xcd, 0xf7, 0xc1, 0x1a, 0xcf, 0xf4, 0xce, 0x9e,
+       0xb7, 0x36, 0x52, 0x51, 0xb9, 0x55, 0xbe, 0xd0, 0xa5, 0x14, 0x2b, 0xb4,
+       0x8d, 0x76, 0x29, 0xa0, 0xfe, 0xb0, 0x77, 0x23, 0xa8, 0x3c, 0xa2, 0x64,
+       0xe2, 0x3e, 0xe2, 0xfc, 0x3b, 0xf2, 0x34, 0x99, 0x54, 0x86, 0x14, 0xec,
+       0xce, 0x16, 0x7d, 0x71, 0xae, 0xd5, 0xb6, 0xbf, 0xed, 0xdb, 0xf6, 0x07,
+       0xee, 0xc4, 0xee, 0x40, 0xef, 0x90, 0xd7, 0xc7, 0xf6, 0x08, 0xf4, 0xfc,
+       0x7f, 0xed, 0xa1, 0xad, 0xc4, 0x36, 0xed, 0x29, 0x6d, 0xb1, 0x67, 0x87,
+       0xc8, 0x17, 0xe8, 0x43, 0x3d, 0x7e, 0xcc, 0x08, 0x7c, 0x2a, 0xc0, 0x03,
+       0xdd, 0x68, 0x5b, 0xe5, 0xdc, 0x56, 0xbe, 0x48, 0x1c, 0xc4, 0xc5, 0xbd,
+       0x84, 0x09, 0x72, 0x2a, 0xd4, 0x21, 0x5b, 0xe6, 0x55, 0x8c, 0x69, 0xbc,
+       0x2b, 0xc4, 0xa1, 0xd6, 0xfc, 0xca, 0x39, 0x13, 0xdf, 0x53, 0x78, 0x5a,
+       0x52, 0x68, 0xd0, 0x9f, 0xb8, 0x9f, 0xf9, 0xf6, 0x5d, 0x3f, 0x7e, 0x76,
+       0xcf, 0x46, 0xb3, 0x71, 0xc4, 0x4f, 0x99, 0x29, 0x57, 0x8e, 0xba, 0x11,
+       0x4b, 0x4a, 0x77, 0x64, 0x69, 0x1f, 0xdd, 0x93, 0x88, 0x91, 0x33, 0xe5,
+       0x06, 0xeb, 0x22, 0x84, 0x31, 0xec, 0x43, 0x8e, 0x8e, 0xa9, 0xc5, 0x58,
+       0xe9, 0xc7, 0xb2, 0x8c, 0xcb, 0x49, 0x49, 0x36, 0xde, 0x43, 0xdd, 0x61,
+       0x8a, 0xa3, 0x6d, 0xed, 0xf9, 0x5d, 0xa4, 0xb7, 0x8c, 0x1a, 0x22, 0x9a,
+       0x95, 0xa8, 0xca, 0xb6, 0xc7, 0xe6, 0x32, 0xdd, 0xe2, 0x64, 0xa6, 0x77,
+       0xa9, 0xf5, 0x7d, 0xbb, 0x22, 0xeb, 0x3b, 0x67, 0xdb, 0xb2, 0xa5, 0x5d,
+       0x6a, 0x51, 0x64, 0xa5, 0x22, 0x0a, 0x75, 0x4d, 0xe2, 0xa0, 0xe0, 0x7b,
+       0xfd, 0xd1, 0x47, 0x55, 0x36, 0x02, 0xdd, 0xca, 0x53, 0xab, 0x99, 0x28,
+       0x6b, 0xc6, 0xe4, 0x8c, 0x3c, 0x85, 0x3a, 0xf1, 0x49, 0x99, 0xab, 0x80,
+       0x2e, 0xcd, 0x77, 0x02, 0xfc, 0x0e, 0x00, 0x37, 0x69, 0x8f, 0x23, 0xc6,
+       0x7a, 0xb4, 0x83, 0xe6, 0x5c, 0x9e, 0x75, 0x52, 0x86, 0x79, 0xe5, 0x3d,
+       0xd8, 0x0f, 0xfd, 0xe5, 0x5f, 0x64, 0xcd, 0xea, 0x94, 0x82, 0x17, 0x1f,
+       0x68, 0xaf, 0x58, 0x7b, 0xd7, 0x5f, 0xbb, 0x8a, 0x35, 0xda, 0xef, 0xb6,
+       0x16, 0x1d, 0x7e, 0x55, 0xd7, 0x3a, 0x17, 0x6d, 0xbe, 0x13, 0xf6, 0x2f,
+       0x27, 0x3c, 0xd8, 0xd7, 0x27, 0xd6, 0xac, 0x47, 0xb7, 0x4b, 0x97, 0x49,
+       0xbd, 0xe1, 0x9c, 0x38, 0x63, 0x2c, 0xd6, 0x2f, 0xf9, 0xb8, 0xbe, 0x0b,
+       0x5c, 0xdd, 0xa4, 0x1b, 0x23, 0x8a, 0x75, 0xd0, 0x87, 0x9a, 0xa7, 0x70,
+       0x23, 0xd6, 0x10, 0xf6, 0x65, 0x1f, 0xd7, 0xb7, 0x5a, 0x70, 0x71, 0x8d,
+       0x4f, 0x9e, 0x89, 0xb3, 0xbb, 0xc8, 0x1b, 0xf9, 0xa1, 0x0e, 0xa8, 0x8f,
+       0xb4, 0x31, 0x83, 0xd8, 0x3e, 0xd3, 0xd4, 0xb5, 0x9d, 0x91, 0xaf, 0xa2,
+       0xe6, 0x6a, 0x3e, 0x0f, 0x1a, 0x59, 0xc3, 0x0e, 0xfa, 0xf5, 0x35, 0xed,
+       0x68, 0x43, 0xdb, 0x23, 0xe3, 0x4e, 0x59, 0xdb, 0xd5, 0x6b, 0x9e, 0x5d,
+       0x59, 0xd4, 0xcd, 0x6b, 0x32, 0xd8, 0xa8, 0x6c, 0xf7, 0xfe, 0xaf, 0xb6,
+       0x29, 0x11, 0xad, 0x4f, 0xe6, 0x37, 0xda, 0xd8, 0xed, 0x88, 0xeb, 0xee,
+       0x0f, 0x99, 0x67, 0x66, 0x98, 0x83, 0x66, 0x98, 0x3b, 0x0c, 0x3f, 0x1e,
+       0x26, 0x5b, 0x70, 0x24, 0x81, 0xa3, 0xee, 0xdb, 0xef, 0x73, 0x3e, 0xae,
+       0xa0, 0xfe, 0x0c, 0x62, 0xea, 0xef, 0xdf, 0x71, 0xeb, 0xfa, 0x47, 0x3e,
+       0x7d, 0xed, 0x3a, 0x1e, 0xc3, 0xd6, 0x41, 0x7f, 0x72, 0x56, 0xc1, 0xbe,
+       0xf2, 0x0d, 0x4f, 0x1f, 0xf0, 0x7d, 0xd8, 0x1e, 0x5f, 0x03, 0xdd, 0x7a,
+       0xf5, 0xb7, 0x27, 0x03, 0xea, 0x34, 0x47, 0xbe, 0x73, 0x51, 0xd2, 0xd2,
+       0x9c, 0xc6, 0x7e, 0x39, 0xcc, 0xdc, 0x58, 0x00, 0x1f, 0x07, 0xcd, 0x31,
+       0x73, 0x8e, 0xb8, 0xe3, 0x02, 0x9c, 0xa8, 0x25, 0xb3, 0x1d, 0xbe, 0x9e,
+       0xbf, 0xc9, 0xf3, 0x81, 0x7b, 0x1b, 0xbf, 0xf1, 0xfc, 0xa6, 0x4f, 0xcf,
+       0x95, 0x5e, 0x8f, 0x9e, 0x60, 0x7d, 0xd0, 0xbc, 0xf5, 0xbb, 0xbe, 0xcb,
+       0x97, 0x27, 0xde, 0x9f, 0xf4, 0xe9, 0xa2, 0x6e, 0x5a, 0x69, 0xa2, 0x5e,
+       0xfe, 0x1d, 0x78, 0x74, 0xad, 0x51, 0x52, 0x59, 0xd4, 0x2e, 0x19, 0xe6,
+       0xac, 0xd4, 0x64, 0x4e, 0x2c, 0xe8, 0x24, 0x65, 0xcf, 0x62, 0xd7, 0xbb,
+       0x15, 0xea, 0xf9, 0x3a, 0x62, 0x35, 0xf5, 0xfe, 0xbe, 0xcc, 0x57, 0x86,
+       0xec, 0x76, 0x83, 0xfe, 0x9a, 0x4a, 0x9f, 0x96, 0x31, 0xfb, 0xb4, 0xae,
+       0xa1, 0x52, 0xc9, 0x63, 0x42, 0xd9, 0x5e, 0x97, 0x61, 0x5d, 0xdb, 0xbc,
+       0x2f, 0x16, 0xe4, 0x32, 0x53, 0x85, 0x8f, 0xed, 0xfe, 0x57, 0x57, 0xd7,
+       0xa4, 0x08, 0x6f, 0xef, 0x6c, 0x81, 0xeb, 0x75, 0x8d, 0x87, 0xf8, 0x5a,
+       0x71, 0x19, 0xd2, 0xb1, 0x3b, 0xc0, 0x67, 0xc9, 0x42, 0x33, 0xc0, 0x19,
+       0x45, 0x5c, 0x46, 0x0c, 0xd8, 0xfd, 0x05, 0x5f, 0x1f, 0x7c, 0x7f, 0xd3,
+       0x65, 0x2d, 0xa4, 0xb2, 0xa7, 0xfc, 0xb9, 0x3f, 0xa3, 0x0c, 0xf0, 0x1d,
+       0xc8, 0xfd, 0x79, 0x3f, 0xde, 0x94, 0x8c, 0x5c, 0x93, 0x32, 0xa0, 0xad,
+       0x40, 0xff, 0xda, 0x3e, 0xe1, 0x33, 0xd5, 0xcf, 0x22, 0x66, 0xf5, 0x79,
+       0xf5, 0x03, 0x7a, 0xb0, 0x5c, 0x93, 0x73, 0x1b, 0x1d, 0x8e, 0xdd, 0xe6,
+       0xfb, 0xd2, 0x3e, 0xcc, 0xcd, 0xe0, 0x8f, 0xb2, 0x23, 0xcc, 0x7e, 0xbc,
+       0xe7, 0x7c, 0x38, 0x99, 0x74, 0x90, 0xbb, 0x72, 0xfb, 0xa7, 0xf0, 0x6d,
+       0xf8, 0x7d, 0x96, 0x96, 0x7b, 0x0d, 0xb5, 0x0a, 0xe4, 0x39, 0x0c, 0x7e,
+       0x92, 0x32, 0xd5, 0x84, 0xce, 0x6f, 0xc4, 0xb3, 0x1b, 0x30, 0xa5, 0x9b,
+       0x30, 0x5e, 0xec, 0x9b, 0x6a, 0xbe, 0xe5, 0x32, 0x1e, 0xfc, 0x89, 0xf6,
+       0x97, 0x24, 0x68, 0x0f, 0x7a, 0xb5, 0x9c, 0xf1, 0x70, 0x75, 0xda, 0x78,
+       0xa4, 0xca, 0x3d, 0xea, 0x6b, 0xfd, 0x62, 0x25, 0x1d, 0x85, 0x3a, 0x75,
+       0x77, 0x2f, 0xce, 0x3c, 0x06, 0xdb, 0x28, 0x19, 0x33, 0xa3, 0xdb, 0xa5,
+       0x90, 0xee, 0x07, 0xcd, 0xf7, 0xe3, 0xd9, 0x8e, 0xf9, 0x9f, 0xc2, 0x3c,
+       0xec, 0x28, 0x4d, 0xff, 0xe8, 0xd4, 0xbd, 0xe4, 0xac, 0x49, 0x1a, 0x87,
+       0x7d, 0xdb, 0xfa, 0x8e, 0xe9, 0xd9, 0xd2, 0x13, 0xf8, 0xde, 0x86, 0xf9,
+       0x5f, 0xc0, 0x13, 0xb9, 0x6c, 0x77, 0x30, 0x4f, 0x1f, 0x9c, 0xc4, 0xfc,
+       0xbd, 0xc0, 0xf1, 0xdb, 0x78, 0xbf, 0x0b, 0xef, 0xbf, 0xb5, 0x69, 0xef,
+       0x6f, 0xf2, 0x6c, 0xcc, 0x3b, 0x9b, 0xe6, 0x83, 0xf8, 0xcd, 0xf3, 0x44,
+       0xfa, 0xd6, 0xc1, 0xf8, 0x7a, 0x4c, 0x76, 0x9c, 0xee, 0x12, 0x55, 0xf7,
+       0x62, 0xb8, 0xaa, 0x9b, 0xd2, 0x7f, 0x9a, 0xf1, 0xfb, 0xaf, 0xb0, 0xc7,
+       0x12, 0xb5, 0x0e, 0xa5, 0x51, 0xb7, 0xda, 0x47, 0x0f, 0x1c, 0x19, 0x5c,
+       0xe6, 0x73, 0xf6, 0xc8, 0x44, 0x83, 0x30, 0x7c, 0x7f, 0xec, 0xc8, 0x60,
+       0xe3, 0x6f, 0x01, 0x0b, 0xb9, 0x54, 0x03, 0xfc, 0x84, 0xff, 0xd3, 0x4d,
+       0x67, 0x6a, 0xd9, 0xe2, 0x4c, 0xfa, 0xfd, 0x81, 0x23, 0x4e, 0x8d, 0x75,
+       0x42, 0x2a, 0x21, 0xba, 0x16, 0x9f, 0x3d, 0x52, 0x44, 0x7e, 0x8c, 0x68,
+       0x5a, 0x82, 0x75, 0xae, 0x51, 0x0f, 0x5b, 0xd1, 0x46, 0xba, 0x5a, 0xf1,
+       0x30, 0xcf, 0x10, 0xcf, 0x63, 0xc0, 0x93, 0x06, 0x1e, 0xe6, 0x1b, 0x8f,
+       0xde, 0xe4, 0xf2, 0x56, 0xb4, 0x11, 0x17, 0xcf, 0x0a, 0xf0, 0xf5, 0x8b,
+       0x3a, 0xfd, 0x26, 0xe9, 0x35, 0x59, 0xdb, 0x7a, 0xb1, 0xa6, 0x4d, 0x0a,
+       0x27, 0x99, 0xb3, 0x77, 0xfb, 0xdf, 0x71, 0x93, 0x3d, 0x77, 0x52, 0x71,
+       0x9e, 0x4f, 0xac, 0x65, 0xee, 0xc4, 0x1c, 0xbe, 0x57, 0x02, 0x58, 0xe5,
+       0xc3, 0xf6, 0xb4, 0xf0, 0xdd, 0xe6, 0xcb, 0x9a, 0x67, 0x06, 0xbd, 0x67,
+       0x2b, 0x2d, 0x00, 0x85, 0x1e, 0xfa, 0x6e, 0xe8, 0x21, 0xe0, 0x13, 0x0b,
+       0xeb, 0xa4, 0x2d, 0x0d, 0x5e, 0x03, 0xda, 0x3e, 0xa9, 0xfe, 0xb8, 0x37,
+       0x8d, 0xbf, 0xe0, 0xbc, 0x40, 0x06, 0xa4, 0x8b, 0x4f, 0xd8, 0xf2, 0xc7,
+       0x7a, 0xe7, 0x34, 0xfc, 0x8e, 0xf7, 0x1e, 0xae, 0xbb, 0x66, 0x53, 0xf6,
+       0x1d, 0xd0, 0x3b, 0x79, 0x31, 0xd0, 0x4b, 0x28, 0xd6, 0x74, 0x49, 0xf6,
+       0xac, 0x87, 0xe4, 0x6d, 0xe0, 0xca, 0xa1, 0xaf, 0xf4, 0x7a, 0xa3, 0x59,
+       0xc4, 0xc7, 0x0d, 0xd8, 0xe7, 0x45, 0x8b, 0xf7, 0x2f, 0x51, 0xe6, 0x3b,
+       0x29, 0x37, 0xfe, 0x19, 0x30, 0xac, 0xaf, 0x6e, 0xde, 0xad, 0x2c, 0x03,
+       0x66, 0x05, 0x6b, 0xc7, 0xbc, 0xb8, 0xcc, 0xd8, 0xee, 0x2a, 0xd4, 0x1e,
+       0x45, 0xeb, 0xbf, 0x5d, 0xd6, 0x59, 0x37, 0x61, 0xb7, 0xba, 0x0b, 0x41,
+       0xce, 0x59, 0x4a, 0x2d, 0x2c, 0x23, 0x86, 0xd7, 0x2c, 0xb5, 0x43, 0x69,
+       0x8b, 0x4c, 0xd5, 0x10, 0x93, 0xd0, 0xf5, 0xa6, 0x92, 0xcb, 0xf2, 0x03,
+       0xad, 0x87, 0x36, 0x6b, 0xcc, 0xec, 0x57, 0x5f, 0xa4, 0x5d, 0x69, 0xca,
+       0x23, 0x27, 0x90, 0x97, 0xc7, 0x1f, 0x46, 0xce, 0x81, 0xbc, 0x4e, 0x94,
+       0xd0, 0xc9, 0xd3, 0x46, 0x36, 0x7e, 0xbd, 0x68, 0x79, 0x7d, 0x80, 0xce,
+       0x67, 0xe2, 0xf1, 0x18, 0x39, 0xd1, 0xad, 0xe3, 0x4c, 0x41, 0xc7, 0x9b,
+       0x21, 0x73, 0x46, 0x75, 0xa1, 0xc6, 0x40, 0x01, 0x8a, 0x0a, 0xc7, 0x1c,
+       0x11, 0x19, 0x5c, 0x44, 0x5c, 0x41, 0x1c, 0x1e, 0x5c, 0x47, 0x74, 0x3b,
+       0x41, 0x78, 0x25, 0xd1, 0x13, 0x11, 0x69, 0x3b, 0xc1, 0xfb, 0x10, 0xd9,
+       0x89, 0x7e, 0x8c, 0x38, 0x07, 0xa3, 0x78, 0x4e, 0xe1, 0x6f, 0x0f, 0x6a,
+       0x2b, 0x13, 0x35, 0xf2, 0x16, 0xf0, 0x80, 0xe5, 0x9e, 0xad, 0xe0, 0xbb,
+       0xfb, 0xa4, 0x2b, 0x86, 0x3d, 0x84, 0x8f, 0x82, 0x8e, 0x9d, 0xa0, 0xc7,
+       0x3b, 0x9f, 0x38, 0xa2, 0x27, 0x44, 0x86, 0x16, 0xa5, 0x5f, 0xe9, 0x3d,
+       0x51, 0x29, 0x66, 0xb8, 0xd6, 0x0d, 0x78, 0xee, 0xc3, 0x9a, 0xde, 0xe7,
+       0xdd, 0x2b, 0x15, 0x6e, 0xd2, 0x8d, 0x39, 0x03, 0xef, 0xa8, 0xa7, 0x32,
+       0xa6, 0x0c, 0xd5, 0x3d, 0xd8, 0xc1, 0xf5, 0x43, 0x78, 0x92, 0x57, 0x8f,
+       0x36, 0x85, 0x9a, 0xb8, 0x00, 0xa9, 0x46, 0x47, 0x78, 0x3f, 0x43, 0x18,
+       0xf6, 0xb5, 0xdd, 0x1a, 0xc6, 0x1c, 0xa1, 0xfc, 0xbc, 0x39, 0xa5, 0xfe,
+       0xb7, 0x7b, 0x97, 0xd6, 0x9a, 0x42, 0xfb, 0x0a, 0xf6, 0x7f, 0x45, 0xfb,
+       0x8a, 0xa8, 0xa4, 0xef, 0x2b, 0xf8, 0x5e, 0xe1, 0x77, 0x90, 0x8b, 0x7f,
+       0xed, 0x0e, 0x2f, 0xde, 0xbb, 0x32, 0x67, 0xf3, 0x0e, 0xc3, 0x95, 0x8b,
+       0x76, 0xc9, 0x78, 0xf0, 0x96, 0x3a, 0x33, 0xad, 0xf3, 0x73, 0x11, 0xb2,
+       0xbf, 0xdc, 0xd0, 0x3d, 0x9b, 0x5c, 0x6a, 0xc4, 0xe4, 0xca, 0x6a, 0x97,
+       0x5c, 0x5e, 0xf6, 0x6c, 0xfe, 0xf2, 0x32, 0xed, 0xdc, 0x94, 0xef, 0xad,
+       0x5a, 0x58, 0x4b, 0xe3, 0xaf, 0x5f, 0xde, 0x59, 0xbd, 0xb5, 0xee, 0x3c,
+       0xdf, 0x7c, 0x00, 0xb4, 0xf4, 0x4b, 0xc4, 0x72, 0x75, 0xff, 0x95, 0x47,
+       0xee, 0x2b, 0xc9, 0x94, 0x14, 0xaa, 0x43, 0xe8, 0x01, 0x91, 0x9c, 0xa3,
+       0xcc, 0x41, 0xd0, 0x7f, 0xf5, 0x33, 0xa8, 0x4d, 0x52, 0x70, 0x9e, 0x21,
+       0x7d, 0x8f, 0xf8, 0x33, 0xd1, 0x7e, 0x69, 0xb7, 0xbe, 0xdc, 0xe7, 0xe5,
+       0x2a, 0xd3, 0xeb, 0x53, 0xad, 0x20, 0x5f, 0xbf, 0x0e, 0xdc, 0xe3, 0xb0,
+       0x53, 0xda, 0xa6, 0x0d, 0x9b, 0x35, 0x65, 0x6d, 0x34, 0x55, 0x2b, 0x09,
+       0xe3, 0x43, 0x06, 0x67, 0x7e, 0x08, 0x9e, 0xd3, 0x90, 0x47, 0xa7, 0xae,
+       0x85, 0x72, 0x0a, 0xba, 0x5d, 0x9c, 0x97, 0x42, 0xf3, 0x57, 0x80, 0x2f,
+       0x27, 0xb3, 0xcd, 0x49, 0x9c, 0x75, 0x1c, 0x76, 0x3b, 0xda, 0x2f, 0x5d,
+       0x3c, 0x27, 0x03, 0x1a, 0xef, 0x97, 0xe2, 0xc9, 0x79, 0x39, 0x58, 0x25,
+       0x9d, 0xc8, 0x25, 0x76, 0x2a, 0x9d, 0x97, 0xb1, 0xe4, 0x2a, 0x6a, 0x27,
+       0xcf, 0x1f, 0xb3, 0x52, 0x3c, 0x05, 0x1c, 0x55, 0xde, 0x03, 0x0c, 0xc1,
+       0x6e, 0xc6, 0x74, 0x5f, 0x33, 0xab, 0xe3, 0x0e, 0xe7, 0xdf, 0x84, 0x9e,
+       0x86, 0x4a, 0x7b, 0x00, 0x57, 0x40, 0x0f, 0x34, 0x83, 0x7a, 0x79, 0xa5,
+       0x8a, 0x7e, 0xcf, 0x8e, 0xb0, 0xf6, 0x52, 0xea, 0x9e, 0x01, 0xa9, 0x57,
+       0xc7, 0x4c, 0xa5, 0x58, 0x53, 0x51, 0x17, 0x5c, 0xa3, 0x7f, 0x27, 0x54,
+       0xd4, 0x1a, 0x90, 0xd5, 0x6a, 0x09, 0x7d, 0xb3, 0xf2, 0xef, 0x35, 0x4a,
+       0x62, 0x5a, 0x5e, 0xdc, 0xcb, 0x29, 0xf2, 0x8d, 0xfa, 0xb3, 0xf9, 0x59,
+       0xd0, 0x98, 0x4b, 0x9a, 0x72, 0x14, 0xf4, 0xe1, 0x7d, 0x05, 0x36, 0xbe,
+       0xc8, 0x1a, 0x2e, 0x87, 0xb5, 0xac, 0x1c, 0x3e, 0x33, 0x03, 0x1a, 0x7a,
+       0x65, 0xe8, 0x77, 0xe9, 0x63, 0x07, 0x30, 0xc7, 0xef, 0x14, 0xec, 0xf5,
+       0x31, 0xbc, 0x13, 0x36, 0x81, 0x27, 0xe5, 0x30, 0x80, 0xa7, 0x09, 0x5a,
+       0x62, 0x5e, 0x6f, 0xb2, 0x3f, 0x29, 0xf5, 0x93, 0xf7, 0xc9, 0xec, 0xca,
+       0x7d, 0xc0, 0xff, 0x36, 0xfa, 0x02, 0xe4, 0xb7, 0x15, 0x9e, 0xc5, 0xfa,
+       0x8f, 0xe7, 0x74, 0xf4, 0x6b, 0xdf, 0x58, 0xe4, 0x3c, 0x9f, 0xfb, 0xb0,
+       0x1f, 0x3d, 0x46, 0x35, 0x27, 0xc5, 0x2a, 0xcf, 0x82, 0xee, 0x50, 0x4f,
+       0x15, 0x4e, 0xce, 0xf8, 0x3a, 0xee, 0x97, 0x7c, 0xbc, 0xc4, 0xfe, 0x02,
+       0x79, 0x62, 0x79, 0xc2, 0xa9, 0xa4, 0x4c, 0x47, 0x11, 0x57, 0x5a, 0x98,
+       0x1b, 0xbc, 0xb9, 0x98, 0x58, 0x8b, 0xe8, 0x6d, 0xb3, 0x5c, 0x3b, 0xea,
+       0xdf, 0x1d, 0x10, 0xd7, 0x5b, 0x32, 0x05, 0x1b, 0x1b, 0x5a, 0x1c, 0x47,
+       0x2d, 0xfc, 0x5d, 0xd4, 0x92, 0x77, 0xfa, 0x32, 0x98, 0xf4, 0x6d, 0xa3,
+       0xab, 0xc5, 0x26, 0xa0, 0xe7, 0x2a, 0x74, 0x5f, 0x85, 0x1d, 0x20, 0x56,
+       0xbf, 0x74, 0xc3, 0x3e, 0x26, 0x5b, 0x6a, 0xcc, 0x1e, 0xf9, 0x8b, 0x5a,
+       0x2a, 0xbd, 0x01, 0xfb, 0x79, 0x07, 0xbd, 0xc0, 0x06, 0x7a, 0xd5, 0xcb,
+       0xe8, 0xeb, 0x56, 0x2a, 0xfb, 0x41, 0x3f, 0x6b, 0x4a, 0x7e, 0x27, 0x74,
+       0xad, 0xd3, 0x61, 0x1d, 0xbb, 0x43, 0xdf, 0xed, 0xca, 0xfe, 0x7e, 0xf6,
+       0x9a, 0xec, 0xcb, 0x79, 0x0f, 0x7d, 0x05, 0x7a, 0xdc, 0x30, 0xb9, 0x1e,
+       0xec, 0x63, 0x2f, 0x10, 0xd8, 0x0f, 0x69, 0xa1, 0xfd, 0x70, 0x0f, 0x61,
+       0xfa, 0xb5, 0x9f, 0x14, 0x34, 0x3e, 0xda, 0xec, 0x8b, 0x7d, 0x9e, 0x9f,
+       0xe9, 0x3a, 0xcb, 0xbc, 0x24, 0x81, 0xfd, 0xbe, 0xef, 0xb2, 0xaf, 0x73,
+       0x46, 0x11, 0xbb, 0x9b, 0xae, 0x3c, 0x67, 0xdf, 0xea, 0x77, 0x7b, 0xab,
+       0x81, 0x9c, 0x28, 0xc7, 0xfd, 0x72, 0xac, 0x99, 0x82, 0x4f, 0x50, 0x86,
+       0x56, 0x8b, 0x0c, 0x45, 0xfe, 0xa8, 0x2a, 0xf2, 0x62, 0x95, 0x6b, 0x5a,
+       0x86, 0x09, 0x27, 0xd2, 0xa5, 0xef, 0xd2, 0x0b, 0xf2, 0x1d, 0x39, 0xb8,
+       0x24, 0x72, 0x06, 0xeb, 0x6b, 0x55, 0xfa, 0xea, 0x38, 0xea, 0xd7, 0x6d,
+       0x52, 0x5f, 0x46, 0x4f, 0x56, 0x95, 0x59, 0xe7, 0x5e, 0xe6, 0x9b, 0x98,
+       0x5c, 0xd6, 0x77, 0xb2, 0x22, 0x23, 0x67, 0xa3, 0x12, 0x3d, 0x8b, 0xe6,
+       0x0f, 0xb2, 0x3f, 0x37, 0x1a, 0xdc, 0xd1, 0x7a, 0x3e, 0x5f, 0xae, 0x60,
+       0x6f, 0x75, 0x48, 0xc7, 0xc9, 0x72, 0xa3, 0x28, 0x85, 0x1a, 0xcf, 0xc2,
+       0x73, 0x39, 0x89, 0xb5, 0x8c, 0xcc, 0x9d, 0x1c, 0x97, 0xa7, 0x71, 0x06,
+       0xfa, 0x3f, 0x9c, 0x31, 0x25, 0xa5, 0x33, 0x98, 0x6f, 0x5c, 0x95, 0xe5,
+       0xd5, 0xa2, 0xd4, 0x6b, 0xe7, 0x5d, 0xaf, 0x8f, 0x20, 0x3e, 0x7c, 0x2f,
+       0xb7, 0xf6, 0xb2, 0xfb, 0xd9, 0xcf, 0xa0, 0x57, 0xb5, 0xf0, 0x0d, 0x99,
+       0x35, 0xe6, 0x66, 0x6f, 0xbd, 0x33, 0x6e, 0xed, 0x61, 0xa7, 0x65, 0xa1,
+       0x9a, 0x91, 0xf2, 0xc9, 0x71, 0x7d, 0xd7, 0xd0, 0x91, 0x3d, 0xfc, 0xc4,
+       0x35, 0xe4, 0x8a, 0x69, 0x7d, 0x67, 0x7c, 0x5d, 0x1e, 0xb2, 0x17, 0xe4,
+       0x90, 0xb5, 0x4f, 0x8e, 0xa1, 0xbe, 0xfe, 0x1c, 0x7a, 0xfd, 0x64, 0x1f,
+       0xf5, 0x08, 0x7a, 0x2d, 0xf6, 0xa0, 0xae, 0x4c, 0xd9, 0x9f, 0x36, 0x9f,
+       0x65, 0x97, 0xd0, 0x60, 0x9e, 0xfc, 0x2f, 0x37, 0x87, 0xbc, 0x77, 0x0d,
+       0xbd, 0x63, 0x4e, 0xc3, 0x19, 0x1e, 0x5c, 0x8d, 0x70, 0x63, 0xe6, 0x73,
+       0x84, 0x5b, 0x36, 0x7c, 0x38, 0x03, 0x70, 0x11, 0xb9, 0x60, 0x47, 0x61,
+       0x23, 0xd3, 0xe0, 0x13, 0x31, 0x7e, 0xa2, 0xc7, 0xaf, 0x83, 0x3b, 0x91,
+       0x5b, 0x6f, 0xee, 0x7f, 0xd5, 0xdf, 0xff, 0xb4, 0xbf, 0xff, 0xe2, 0x8d,
+       0xfd, 0x41, 0x7e, 0xfd, 0xd0, 0x95, 0x16, 0xba, 0x5e, 0xad, 0x78, 0xf0,
+       0x0b, 0x3e, 0x5d, 0x17, 0x6f, 0xd0, 0x15, 0xc0, 0x43, 0x9e, 0x9a, 0x67,
+       0xc6, 0x66, 0xc6, 0xe8, 0x21, 0xc8, 0xd1, 0x95, 0xbc, 0x0d, 0xdf, 0xa8,
+       0xa6, 0x26, 0x4b, 0xfa, 0x4e, 0x4d, 0xc9, 0x46, 0x7c, 0x41, 0xa6, 0xad,
+       0xd4, 0xe4, 0x9c, 0x44, 0x60, 0xcb, 0x8c, 0x2d, 0x11, 0xa9, 0x33, 0xe6,
+       0xe0, 0x59, 0xb0, 0xb7, 0xa6, 0xf5, 0x4a, 0x0b, 0xad, 0x91, 0x17, 0x48,
+       0xa3, 0x47, 0x6b, 0x6c, 0xf8, 0x26, 0xad, 0x1e, 0xbc, 0x47, 0xeb, 0x95,
+       0x4a, 0x0b, 0xfc, 0xd9, 0xa8, 0x0f, 0x1f, 0x6d, 0x81, 0xa7, 0x3d, 0xb3,
+       0xae, 0xa0, 0x3d, 0x93, 0xb6, 0x9f, 0x80, 0x6f, 0x48, 0xac, 0x33, 0x7b,
+       0xf8, 0xc8, 0xdd, 0xc3, 0xae, 0xc4, 0x50, 0x6f, 0xb4, 0x63, 0xed, 0x72,
+       0x8d, 0xb5, 0x88, 0x1a, 0x6c, 0x97, 0x11, 0xd8, 0x2c, 0x75, 0xe7, 0xdd,
+       0x0d, 0x3e, 0xa4, 0x6b, 0x02, 0x57, 0x0e, 0xd9, 0xa4, 0xe5, 0x3f, 0xdd,
+       0x17, 0xe3, 0x23, 0x76, 0x59, 0x46, 0xcd, 0x76, 0x9c, 0x5f, 0x6f, 0x6a,
+       0x9c, 0x69, 0xd2, 0x72, 0x7a, 0x74, 0xc8, 0xfc, 0x73, 0xf0, 0x39, 0x55,
+       0x33, 0xa4, 0x6e, 0xa5, 0x12, 0xe7, 0x80, 0x63, 0x0f, 0x74, 0x53, 0x1f,
+       0x27, 0x3d, 0x22, 0x07, 0x61, 0xdf, 0x75, 0x9d, 0x17, 0x69, 0xc7, 0xa9,
+       0xe9, 0x12, 0x6a, 0x9d, 0x3f, 0xd6, 0xb9, 0xcd, 0x75, 0xaf, 0x21, 0xbf,
+       0x4d, 0x6f, 0xb2, 0x3d, 0x75, 0xd6, 0xb3, 0x3d, 0x75, 0x16, 0x3d, 0xf0,
+       0xf1, 0x98, 0x74, 0xac, 0xc1, 0x7f, 0x5e, 0xd8, 0xe9, 0xd5, 0x73, 0x2f,
+       0x24, 0x8d, 0xfc, 0x49, 0xc4, 0xbb, 0xe3, 0x51, 0xb1, 0x8e, 0xeb, 0x7c,
+       0x00, 0x79, 0x4f, 0xc9, 0xdc, 0x29, 0xc6, 0x54, 0x4b, 0x86, 0x8f, 0x53,
+       0x1f, 0xac, 0x6b, 0x96, 0x27, 0x8a, 0xf0, 0x91, 0x79, 0xc4, 0x05, 0xb5,
+       0xf6, 0xae, 0x14, 0x2d, 0xca, 0xa1, 0x57, 0xba, 0xd6, 0xd0, 0x8f, 0xaf,
+       0x21, 0x36, 0xac, 0x25, 0xa4, 0x0d, 0xbe, 0xa5, 0xce, 0xc6, 0x8d, 0xf2,
+       0xd2, 0x0f, 0xe1, 0x0f, 0xfc, 0x0d, 0x07, 0xb5, 0xe5, 0xd9, 0x84, 0x41,
+       0xdf, 0x52, 0x67, 0x69, 0xe7, 0x28, 0xa7, 0xce, 0xd2, 0xce, 0x49, 0x47,
+       0xe0, 0x2f, 0x78, 0x3f, 0x3b, 0xae, 0xef, 0xa9, 0xaf, 0xd9, 0xe4, 0xe5,
+       0x6f, 0xc4, 0xa9, 0xb1, 0x46, 0x24, 0x3f, 0xd2, 0x87, 0x5a, 0x66, 0xbb,
+       0x63, 0x0f, 0x4f, 0x5e, 0x96, 0x4f, 0xca, 0xd7, 0xed, 0x9f, 0x80, 0x2f,
+       0xf2, 0xd1, 0xca, 0x17, 0x79, 0xea, 0x95, 0x36, 0xcd, 0x57, 0xc0, 0x0f,
+       0x04, 0x0d, 0x7e, 0x06, 0x8f, 0x27, 0x80, 0xff, 0x31, 0xc4, 0x80, 0x01,
+       0x3c, 0x0f, 0xe0, 0x89, 0x94, 0x76, 0x96, 0xbc, 0x93, 0xd7, 0x77, 0x50,
+       0x37, 0x06, 0x7c, 0xce, 0xe2, 0xfd, 0x15, 0x99, 0x5b, 0x72, 0x8f, 0x22,
+       0xaf, 0xf2, 0x0e, 0xbd, 0xdf, 0xbb, 0x0f, 0xde, 0xcc, 0xfb, 0x2b, 0xe2,
+       0xc9, 0x27, 0x65, 0xd6, 0x05, 0xef, 0xab, 0x9b, 0x65, 0xd1, 0x1a, 0x3b,
+       0x12, 0xba, 0x0e, 0x3f, 0xd8, 0x60, 0x9c, 0xa0, 0x8c, 0xde, 0x11, 0x67,
+       0x89, 0xf7, 0x5f, 0x1e, 0xbe, 0xd9, 0x46, 0x10, 0x37, 0x5a, 0xf7, 0xd8,
+       0x80, 0x1b, 0x00, 0x1c, 0xe9, 0xda, 0xa0, 0xfc, 0x10, 0x73, 0x76, 0xb5,
+       0xc4, 0x9a, 0xd6, 0x7d, 0x93, 0xf2, 0x0c, 0xea, 0x80, 0x57, 0xed, 0x5b,
+       0xe4, 0x3a, 0xcb, 0x5a, 0xa8, 0xde, 0x98, 0x81, 0x4f, 0xb6, 0x21, 0x96,
+       0x99, 0x72, 0xb9, 0xd2, 0x2e, 0x75, 0xd4, 0x3b, 0x2b, 0xab, 0x8c, 0x85,
+       0xa4, 0xbd, 0x0b, 0xf3, 0x5e, 0xfc, 0x62, 0xac, 0xbd, 0x5c, 0x41, 0x9e,
+       0x85, 0x6f, 0x5f, 0xae, 0xc4, 0xf1, 0x1c, 0xc0, 0xd3, 0xc2, 0x33, 0x89,
+       0x67, 0x1a, 0xcf, 0x71, 0x3c, 0xc7, 0xf1, 0xb4, 0xb0, 0x37, 0x81, 0x67,
+       0xd0, 0x33, 0x10, 0xd7, 0x4d, 0xbe, 0xcb, 0xfa, 0x3c, 0xd4, 0x8a, 0x16,
+       0x73, 0x5a, 0xd4, 0xce, 0xa3, 0x8f, 0x70, 0xc6, 0x75, 0xad, 0x87, 0xfc,
+       0xf6, 0x91, 0x6b, 0x5a, 0xec, 0xcb, 0x4b, 0xc6, 0x9e, 0x51, 0xe6, 0x85,
+       0x1a, 0xf2, 0xc2, 0x7f, 0xec, 0x40, 0xff, 0x68, 0xee, 0xd5, 0x77, 0x47,
+       0x4b, 0xf8, 0xe6, 0x3b, 0x7a, 0xde, 0xf8, 0x3c, 0xf2, 0x14, 0xe3, 0xa7,
+       0x8b, 0x3d, 0x05, 0xc4, 0xf1, 0xed, 0xf0, 0xbf, 0x1c, 0xe2, 0x36, 0xde,
+       0x97, 0x37, 0x76, 0x78, 0x39, 0x15, 0xf5, 0xbb, 0xda, 0x7c, 0x5f, 0x63,
+       0x63, 0xcf, 0x56, 0xbd, 0x41, 0x0f, 0x70, 0xa4, 0x6a, 0xcb, 0xf0, 0xc1,
+       0x37, 0xed, 0xa3, 0xba, 0xb6, 0xa3, 0x2e, 0x9e, 0x46, 0x8d, 0x9a, 0x5f,
+       0x64, 0x0d, 0xf3, 0x14, 0xfa, 0x12, 0xf4, 0x67, 0x71, 0xf6, 0xe4, 0xcc,
+       0x05, 0xba, 0x16, 0x8d, 0x4b, 0x17, 0xf3, 0xc0, 0x15, 0x9c, 0x07, 0xbe,
+       0x56, 0x5c, 0xc8, 0xec, 0x41, 0xd4, 0x84, 0xae, 0x1b, 0xb5, 0xf6, 0x48,
+       0xf2, 0x11, 0xc6, 0x1c, 0xc1, 0x7e, 0x53, 0xbc, 0x7b, 0x75, 0xc4, 0xdd,
+       0x19, 0xfd, 0xfb, 0x30, 0x8c, 0x6b, 0x1c, 0x7b, 0x6f, 0x13, 0xef, 0xb7,
+       0x5c, 0xde, 0x69, 0x8b, 0xec, 0x59, 0xf4, 0x6a, 0x5a, 0x65, 0xb5, 0xe2,
+       0xfb, 0x49, 0x1f, 0x1f, 0xd7, 0x95, 0xff, 0xdb, 0xc6, 0x4e, 0xc8, 0x08,
+       0xfe, 0x00, 0x1d, 0x1f, 0x43, 0xfd, 0x7c, 0x01, 0x7a, 0x79, 0x15, 0x3a,
+       0x79, 0xad, 0x42, 0x5b, 0x1f, 0x83, 0xdd, 0x43, 0x86, 0x33, 0xfa, 0x0c,
+       0x7d, 0xf6, 0x85, 0x0a, 0x62, 0x27, 0xe3, 0x9f, 0xfa, 0x52, 0x9c, 0xf5,
+       0x21, 0xf3, 0xa0, 0x87, 0x67, 0xc0, 0x83, 0x93, 0x60, 0x6d, 0x87, 0xa6,
+       0xa7, 0xae, 0xef, 0xc1, 0x28, 0x27, 0xd8, 0x20, 0x7f, 0x23, 0xd0, 0x30,
+       0x5f, 0x8c, 0xeb, 0x7b, 0x78, 0xc5, 0x39, 0xf2, 0x31, 0x2e, 0xce, 0x62,
+       0xb0, 0xaf, 0x0f, 0xfb, 0x3a, 0x5b, 0x70, 0xdd, 0xbe, 0x89, 0x07, 0xe5,
+       0xf3, 0xc0, 0xf5, 0xcd, 0x75, 0x7f, 0xca, 0x2c, 0xdd, 0xb8, 0x1b, 0x66,
+       0xfe, 0xa5, 0x6e, 0x32, 0xd8, 0x1f, 0xe8, 0x67, 0xc0, 0xef, 0x05, 0x52,
+       0x0b, 0xe8, 0x23, 0x20, 0x7f, 0xea, 0x68, 0x92, 0xf1, 0x09, 0xf8, 0x6d,
+       0xa9, 0x55, 0x3a, 0x44, 0xf5, 0xb3, 0x37, 0x66, 0xad, 0xdc, 0x7a, 0xe6,
+       0x2f, 0xfa, 0x67, 0xa2, 0x9f, 0x3e, 0xc1, 0xba, 0x59, 0xe7, 0x19, 0xc0,
+       0x74, 0x6f, 0xa2, 0xed, 0xe7, 0x7c, 0x38, 0xae, 0xa7, 0xa5, 0x84, 0x3a,
+       0x34, 0xbf, 0x88, 0x8a, 0x1e, 0xf1, 0x5b, 0x65, 0xf9, 0xbb, 0x16, 0xef,
+       0xf0, 0xc6, 0x92, 0x73, 0xa0, 0xb1, 0x64, 0xe6, 0x78, 0x6f, 0x06, 0x1c,
+       0xbb, 0x36, 0xe1, 0x98, 0xf2, 0x71, 0x4c, 0x49, 0xf9, 0xd4, 0x34, 0x7c,
+       0x2d, 0x87, 0xfc, 0x3e, 0x64, 0x3e, 0x28, 0x9f, 0x41, 0x73, 0x8d, 0xb9,
+       0x33, 0xe3, 0xd0, 0x93, 0xeb, 0xee, 0xb1, 0xf7, 0x83, 0xee, 0x97, 0x91,
+       0x5b, 0x83, 0x9a, 0xa7, 0x9c, 0x88, 0x20, 0x87, 0x1d, 0xd6, 0xbf, 0xc3,
+       0x96, 0x4c, 0x13, 0xf6, 0xaa, 0x8c, 0xb1, 0x34, 0xda, 0x7b, 0xe4, 0xb7,
+       0x05, 0xe4, 0x2a, 0xf2, 0xd9, 0x23, 0x65, 0xd3, 0x78, 0x20, 0x82, 0xba,
+       0xc6, 0x59, 0xa4, 0x1f, 0xc9, 0x70, 0x24, 0xdb, 0x8e, 0x9a, 0xd4, 0x95,
+       0xef, 0xd9, 0xfc, 0x77, 0x09, 0x0b, 0x72, 0xa1, 0x61, 0xe2, 0x79, 0x0e,
+       0x7a, 0xf8, 0x3d, 0xbc, 0xff, 0x53, 0x3f, 0xea, 0x3e, 0xac, 0xe4, 0x60,
+       0xbb, 0x69, 0x5d, 0xcf, 0xb0, 0x8e, 0xa8, 0x23, 0xdf, 0x2a, 0xe4, 0x1a,
+       0xd4, 0x55, 0x93, 0xac, 0x5d, 0x9f, 0x59, 0xb9, 0x2a, 0xaf, 0x2d, 0xf1,
+       0x77, 0x50, 0xe6, 0xe5, 0x7d, 0x8c, 0x07, 0xe6, 0x7c, 0x06, 0x73, 0xab,
+       0x8c, 0x65, 0xf8, 0x6e, 0xc2, 0x81, 0xfa, 0x51, 0x23, 0xa0, 0xd6, 0xbe,
+       0x6c, 0xa5, 0xc1, 0xe7, 0x55, 0xb9, 0xb0, 0x14, 0x95, 0x15, 0x8b, 0x75,
+       0x91, 0x24, 0x1d, 0xc0, 0x5e, 0x58, 0xfd, 0x07, 0xcf, 0x26, 0x08, 0x8f,
+       0x9e, 0xa7, 0x84, 0xba, 0xee, 0x41, 0xbd, 0xf7, 0x47, 0xe9, 0x99, 0x34,
+       0xb5, 0xf6, 0x79, 0x45, 0xb9, 0x40, 0x7f, 0xd2, 0xbf, 0x51, 0xb0, 0x36,
+       0x78, 0x0a, 0x36, 0xcb, 0xda, 0x9d, 0xfd, 0x00, 0xde, 0x1b, 0x5c, 0x27,
+       0xef, 0x78, 0x2e, 0x0f, 0x41, 0x36, 0xf4, 0x7b, 0xde, 0x89, 0x21, 0x8f,
+       0x2a, 0xfa, 0x7a, 0x59, 0xc7, 0x82, 0x72, 0xb5, 0x88, 0x9c, 0x82, 0x18,
+       0x60, 0xef, 0x82, 0x2d, 0xce, 0x40, 0x97, 0x93, 0x80, 0xdb, 0x94, 0x4b,
+       0xd6, 0xcb, 0xba, 0x2e, 0x53, 0xa7, 0x6f, 0xde, 0xdf, 0x14, 0xe0, 0x3f,
+       0x6a, 0x1d, 0xb6, 0x05, 0x1f, 0x52, 0xeb, 0x71, 0x3c, 0x11, 0x8f, 0xd7,
+       0xd1, 0x5f, 0x54, 0x78, 0x3f, 0x84, 0xde, 0xa0, 0xc2, 0xbb, 0x93, 0x34,
+       0x9e, 0xe3, 0xbc, 0x2f, 0xf2, 0xe3, 0x1a, 0xf1, 0x93, 0x8e, 0x20, 0xbe,
+       0xb0, 0x96, 0x64, 0x7c, 0x09, 0xea, 0x49, 0xcf, 0x16, 0x8e, 0x55, 0x19,
+       0x43, 0x68, 0xd7, 0x43, 0x88, 0x5b, 0xb4, 0x05, 0xaf, 0x96, 0x5c, 0xad,
+       0x79, 0x32, 0x9b, 0x6b, 0x9e, 0xd7, 0x39, 0x62, 0xaf, 0x58, 0xb0, 0x31,
+       0xca, 0x0e, 0x6b, 0x3a, 0x07, 0x9c, 0x93, 0x9c, 0x7e, 0x52, 0x66, 0xaf,
+       0x48, 0x6e, 0x75, 0x5c, 0x9e, 0xd3, 0x71, 0x2b, 0x88, 0x59, 0xac, 0x21,
+       0xf9, 0xfb, 0x71, 0x5a, 0x9e, 0x3d, 0x79, 0x55, 0x9c, 0xe7, 0x19, 0xb7,
+       0xc6, 0x12, 0x9d, 0x06, 0x63, 0x95, 0x2b, 0x0d, 0xe4, 0xa6, 0x07, 0x6d,
+       0xfe, 0x5b, 0x80, 0x08, 0x7a, 0x3a, 0x57, 0xda, 0x27, 0x52, 0x76, 0xd2,
+       0x18, 0x3a, 0xd0, 0x69, 0x30, 0x37, 0x8e, 0x99, 0x8f, 0x4b, 0x70, 0x1f,
+       0xd5, 0x21, 0x8f, 0xeb, 0xbb, 0x0a, 0xb8, 0xed, 0xe2, 0x07, 0xfa, 0x77,
+       0x94, 0x6b, 0x19, 0xca, 0x1a, 0xdf, 0xeb, 0x9c, 0x2f, 0xc5, 0xae, 0x65,
+       0xda, 0xa4, 0x7c, 0x9b, 0xeb, 0x1e, 0x9a, 0x98, 0xd8, 0xe1, 0xfd, 0x7b,
+       0x91, 0x23, 0xb7, 0x79, 0xb1, 0xa0, 0xe0, 0x7f, 0xaf, 0xe1, 0x49, 0xdb,
+       0x66, 0xbe, 0x65, 0x7e, 0xa4, 0xde, 0xf0, 0x5c, 0xe5, 0x3b, 0x73, 0xef,
+       0x02, 0x72, 0x2f, 0xf3, 0xe5, 0x76, 0xc9, 0xf3, 0x77, 0x3e, 0xa5, 0xe7,
+       0x4b, 0x5e, 0x2d, 0xed, 0xc3, 0xd5, 0x66, 0x65, 0xae, 0xc6, 0x1a, 0xea,
+       0x02, 0x72, 0xd9, 0x28, 0x6c, 0x95, 0x39, 0xed, 0x28, 0xf2, 0x39, 0x7f,
+       0x9f, 0xc6, 0xda, 0x32, 0xf7, 0xa5, 0xd2, 0x49, 0xd5, 0xfa, 0xbb, 0xd2,
+       0xd5, 0x38, 0xef, 0xa3, 0xce, 0x8d, 0x42, 0xef, 0xbf, 0xc3, 0xde, 0x62,
+       0x58, 0xdb, 0x88, 0xf3, 0x02, 0x65, 0xef, 0xfd, 0x7e, 0x2d, 0x7d, 0x9e,
+       0x0f, 0xb0, 0x0e, 0xf8, 0x3c, 0xe4, 0xb2, 0xd7, 0xbe, 0xca, 0xdc, 0xfd,
+       0x6f, 0xca, 0x1a, 0x4b, 0x3f, 0x6e, 0xd0, 0xb7, 0xf1, 0xbd, 0x1a, 0x91,
+       0xe5, 0x38, 0xf9, 0x87, 0xbc, 0x0c, 0xfa, 0xce, 0x56, 0x72, 0xd8, 0x2c,
+       0x83, 0x3f, 0x80, 0x0c, 0x28, 0xcb, 0x40, 0x06, 0x7c, 0x9f, 0x86, 0xbe,
+       0xd8, 0x33, 0x0c, 0xe9, 0x3e, 0xb2, 0xdc, 0xf4, 0xce, 0x2e, 0x57, 0x5b,
+       0x69, 0x26, 0xbd, 0xd4, 0xe9, 0x39, 0xc9, 0x6b, 0xfd, 0x2e, 0x48, 0xbe,
+       0x76, 0x4e, 0xf6, 0xd4, 0x16, 0xe4, 0x21, 0xeb, 0x01, 0xf0, 0x7b, 0xc9,
+       0x2d, 0x5a, 0xba, 0x57, 0x99, 0x2c, 0xe0, 0xec, 0xe2, 0xff, 0x74, 0x6e,
+       0xb5, 0xbf, 0x6d, 0x55, 0x67, 0xfc, 0xf1, 0xb5, 0x9d, 0xa4, 0xa1, 0x09,
+       0xb7, 0xae, 0x93, 0xb8, 0x69, 0x0a, 0x76, 0x7c, 0xdb, 0x46, 0x24, 0xad,
+       0x6e, 0x43, 0x46, 0xa3, 0x2e, 0x53, 0x4c, 0x12, 0xba, 0x74, 0xeb, 0x44,
+       0xda, 0x75, 0x5d, 0x37, 0xd0, 0x64, 0x9c, 0xb4, 0x14, 0x98, 0x54, 0x28,
+       0xac, 0x43, 0x08, 0xa9, 0xc6, 0x6d, 0x35, 0xa6, 0xa5, 0x71, 0xfa, 0x46,
+       0x10, 0x5f, 0xb0, 0x92, 0xb4, 0x65, 0x52, 0x84, 0x5b, 0x04, 0xdb, 0x3e,
+       0xb0, 0xd1, 0xa5, 0x8c, 0x3f, 0x60, 0xfb, 0x30, 0x26, 0xb1, 0x29, 0x2b,
+       0xb0, 0xb1, 0x7d, 0xea, 0x07, 0x26, 0x75, 0xda, 0x8a, 0xf7, 0xfb, 0x3d,
+       0xe7, 0x5e, 0xc7, 0x36, 0x41, 0x48, 0x8b, 0x14, 0xf9, 0x9e, 0x97, 0x7b,
+       0xee, 0xb9, 0xe7, 0x79, 0x7f, 0x9e, 0xdf, 0xed, 0x59, 0x27, 0x9f, 0xc0,
+       0xef, 0x38, 0x35, 0x67, 0x4b, 0xda, 0xee, 0x97, 0x9f, 0x6a, 0x2e, 0x9f,
+       0xf1, 0x49, 0x00, 0x3e, 0xa9, 0xc1, 0x16, 0x48, 0x8b, 0x13, 0xbb, 0x21,
+       0xf4, 0x29, 0xc3, 0xa0, 0x75, 0xdc, 0xf8, 0xcd, 0xb6, 0x19, 0xdf, 0x74,
+       0x06, 0xbe, 0xbb, 0xbb, 0xad, 0xc5, 0xcf, 0xf9, 0x1a, 0xff, 0xf6, 0x7d,
+       0xaf, 0x86, 0xd6, 0x2f, 0xd3, 0xd8, 0xcf, 0x9b, 0xaa, 0x67, 0x1d, 0xf0,
+       0x12, 0x73, 0xd3, 0x31, 0xcd, 0x3f, 0x84, 0xa7, 0xa8, 0xa3, 0xae, 0x40,
+       0x47, 0x0d, 0x50, 0x77, 0x0d, 0xce, 0xb9, 0xcc, 0x0f, 0x44, 0xe5, 0x0f,
+       0x93, 0xd4, 0xc3, 0x71, 0xf9, 0xfd, 0xe4, 0xb3, 0xd8, 0x4f, 0xa2, 0xc0,
+       0x1c, 0xe5, 0xf5, 0xe9, 0xac, 0x62, 0x92, 0x86, 0xd5, 0x07, 0x7e, 0x5a,
+       0xed, 0x40, 0xdc, 0xca, 0xad, 0x0d, 0xab, 0xbe, 0x39, 0xa2, 0xb5, 0xdd,
+       0xb8, 0xd5, 0x21, 0xd7, 0xcf, 0x1b, 0x1d, 0x1b, 0x9e, 0x8a, 0x06, 0x86,
+       0xe7, 0x69, 0x97, 0x92, 0xb1, 0x8c, 0x55, 0x2f, 0x07, 0xa3, 0xcc, 0x3d,
+       0xa7, 0xa8, 0x9f, 0x61, 0x0b, 0xbb, 0xed, 0x8c, 0xd5, 0xe0, 0xd9, 0x9f,
+       0x58, 0x8d, 0x9e, 0x3d, 0xe2, 0xe9, 0x59, 0x8e, 0xa5, 0x40, 0x53, 0xda,
+       0xa2, 0xc4, 0xf4, 0x88, 0x95, 0x84, 0xcd, 0xc3, 0xf5, 0x02, 0xd7, 0x8f,
+       0xcb, 0xd1, 0x85, 0xc3, 0xf0, 0xbf, 0xbb, 0xed, 0xbd, 0xb4, 0xab, 0xf6,
+       0x00, 0xf1, 0x38, 0x78, 0xfe, 0x86, 0x9a, 0xb5, 0x1e, 0xf6, 0xd6, 0xe2,
+       0x38, 0xe4, 0x7c, 0x8a, 0xf5, 0xda, 0x7a, 0xe6, 0x73, 0x74, 0xaf, 0xd5,
+       0x73, 0xf7, 0x94, 0x9f, 0x7b, 0x32, 0xef, 0x78, 0x58, 0x30, 0xfc, 0xc2,
+       0x17, 0xfa, 0x76, 0x84, 0xcf, 0xe4, 0xf3, 0x9a, 0x65, 0x68, 0x3f, 0xf4,
+       0xcb, 0x14, 0xff, 0xb3, 0x5e, 0xed, 0x0a, 0xf1, 0x4a, 0xb4, 0x7d, 0x05,
+       0xdb, 0xf4, 0x35, 0x6f, 0xbd, 0xad, 0xad, 0xd2, 0x18, 0xad, 0x98, 0xcf,
+       0xdc, 0x0a, 0xdb, 0x71, 0xc9, 0x2e, 0xf0, 0xb7, 0x54, 0x8a, 0x38, 0x75,
+       0xb2, 0xd7, 0x5e, 0x5f, 0xb3, 0xc6, 0x16, 0xf4, 0x19, 0x9f, 0x20, 0x38,
+       0x15, 0xf0, 0x7c, 0x8b, 0xbb, 0xe9, 0x37, 0x79, 0xd7, 0x0d, 0x9a, 0x93,
+       0x89, 0x5b, 0xed, 0x35, 0xef, 0x71, 0x77, 0xd9, 0x0e, 0xc7, 0x2d, 0xea,
+       0xce, 0x60, 0x54, 0x9a, 0xc9, 0x43, 0x25, 0xf5, 0xe3, 0x43, 0x8e, 0xc1,
+       0x5c, 0x44, 0x9d, 0xf1, 0x56, 0xe6, 0xec, 0xdf, 0xd1, 0x73, 0x6b, 0xa2,
+       0x4f, 0x80, 0x6b, 0xf0, 0xc9, 0xe7, 0xf2, 0xbd, 0xcc, 0xf5, 0x62, 0xfd,
+       0x46, 0xae, 0xef, 0x7a, 0xe7, 0x9c, 0x70, 0xb3, 0xd6, 0x7d, 0x92, 0x39,
+       0x6f, 0xf8, 0x6f, 0xc8, 0x01, 0xef, 0x35, 0xa3, 0x3d, 0x4f, 0x9b, 0xf0,
+       0x45, 0xeb, 0xf8, 0xb6, 0xa1, 0x4b, 0x6d, 0xc3, 0x89, 0x3c, 0xf9, 0x93,
+       0x7c, 0xe9, 0xf3, 0xa3, 0xaf, 0xf3, 0xc8, 0xa3, 0xd4, 0xb3, 0xfd, 0x72,
+       0x26, 0xcf, 0xb3, 0x49, 0x69, 0x4d, 0x6b, 0xe3, 0xd9, 0x71, 0xc5, 0x64,
+       0x75, 0x4e, 0x25, 0x5e, 0xce, 0xca, 0xa0, 0x5c, 0x71, 0x79, 0x66, 0x89,
+       0x42, 0x3a, 0xd8, 0x54, 0xf1, 0xfe, 0xfb, 0xf5, 0xcc, 0xc2, 0xea, 0x33,
+       0xc6, 0x30, 0xf7, 0x79, 0x8f, 0xde, 0xcd, 0x7a, 0xb6, 0xe9, 0x2a, 0xfa,
+       0x7c, 0x53, 0xcf, 0x29, 0x0c, 0x9d, 0xc8, 0xfa, 0x7e, 0x38, 0xc2, 0x7b,
+       0xf8, 0x5c, 0xfa, 0x7c, 0x7c, 0x16, 0x79, 0xaf, 0x13, 0x16, 0xbb, 0x57,
+       0x82, 0x3b, 0x20, 0xfa, 0x3b, 0x58, 0x47, 0x0e, 0x40, 0x56, 0x37, 0x1a,
+       0x0c, 0xcc, 0x98, 0xf1, 0x35, 0xd2, 0xd6, 0x55, 0x9c, 0x23, 0x62, 0x15,
+       0xf8, 0xd1, 0x27, 0x5e, 0xba, 0x8d, 0xf5, 0xd2, 0x9e, 0xbf, 0xde, 0x87,
+       0xf5, 0x1d, 0xaf, 0xae, 0x3e, 0xb9, 0x8d, 0xbc, 0x3a, 0xa2, 0xf5, 0x41,
+       0xde, 0x43, 0x39, 0xe6, 0x99, 0x91, 0x2e, 0xef, 0xe3, 0x7e, 0xb6, 0xb7,
+       0xd4, 0xd0, 0x31, 0xe9, 0xed, 0xcf, 0x1f, 0x0f, 0x4b, 0xb8, 0x95, 0x3a,
+       0x2e, 0x2a, 0xc9, 0x29, 0xc6, 0x2c, 0xb0, 0x5d, 0x63, 0x5c, 0xeb, 0xcb,
+       0x75, 0x71, 0xfa, 0xff, 0xd4, 0xc5, 0x69, 0xeb, 0x23, 0xe5, 0x9d, 0xb0,
+       0xe6, 0xb1, 0xbe, 0x98, 0xae, 0x85, 0x2a, 0xba, 0xfa, 0xb5, 0xfb, 0x68,
+       0x99, 0x8e, 0x3f, 0xc9, 0xd3, 0x5e, 0xa5, 0x34, 0xa7, 0xfc, 0xb7, 0x49,
+       0x9e, 0x2d, 0xf7, 0x78, 0x85, 0x7b, 0x1c, 0x5c, 0x74, 0x89, 0x83, 0xf9,
+       0x96, 0xca, 0xf0, 0xa9, 0x3c, 0x75, 0x4c, 0x93, 0xcc, 0x4d, 0xfb, 0x7a,
+       0x66, 0xd4, 0xf3, 0x71, 0x73, 0x6b, 0xeb, 0x54, 0xcf, 0xc0, 0xbb, 0x71,
+       0x86, 0x3d, 0xfb, 0xd2, 0x21, 0xb3, 0xe7, 0x69, 0x77, 0x93, 0xe8, 0x8b,
+       0x06, 0x66, 0xe7, 0x59, 0x9b, 0x24, 0x16, 0x65, 0x50, 0x58, 0xf7, 0x1f,
+       0xb6, 0x4f, 0x40, 0xde, 0x62, 0xf2, 0xe1, 0x24, 0x7d, 0xfa, 0x3a, 0xf8,
+       0xc6, 0xcd, 0x35, 0xe7, 0xbb, 0xbd, 0xec, 0x13, 0x56, 0xd3, 0xbd, 0xa3,
+       0x4d, 0x1a, 0xc9, 0xe7, 0x8e, 0x7d, 0x5d, 0xe8, 0x83, 0xf1, 0x3a, 0x83,
+       0x58, 0x80, 0xb1, 0x47, 0x5c, 0x63, 0x8f, 0xd9, 0x02, 0xfb, 0x9a, 0xbc,
+       0xbc, 0x52, 0x93, 0xf2, 0x0a, 0xf9, 0x2d, 0xad, 0xfe, 0xf7, 0x80, 0xea,
+       0xac, 0xdc, 0x64, 0xb7, 0xc1, 0xb1, 0xd8, 0x31, 0xe5, 0x3d, 0xa9, 0xe2,
+       0xbd, 0x98, 0xef, 0x4b, 0xb6, 0x19, 0xdf, 0xca, 0x56, 0x7d, 0x13, 0xd6,
+       0x79, 0xb4, 0x2b, 0x5c, 0x9f, 0xbc, 0x41, 0x1e, 0xa1, 0xce, 0xf3, 0xe7,
+       0xf9, 0xf4, 0xf0, 0xdb, 0x9c, 0x4f, 0xfe, 0xaf, 0xc4, 0x22, 0xf8, 0xb2,
+       0xea, 0xf7, 0xf9, 0x72, 0xc7, 0xb1, 0x4a, 0x9b, 0x40, 0xb9, 0xab, 0xac,
+       0x4f, 0xda, 0x12, 0x99, 0x5a, 0xa6, 0xcb, 0x50, 0x2f, 0xf7, 0xff, 0x3c,
+       0x73, 0xbb, 0x90, 0xb7, 0x95, 0x68, 0x73, 0x4c, 0x69, 0x93, 0x06, 0x6d,
+       0x22, 0x4a, 0x1b, 0xc6, 0x7b, 0x4f, 0x79, 0xfc, 0xd6, 0x84, 0xf3, 0x62,
+       0xae, 0x16, 0xba, 0x6e, 0x1f, 0x75, 0xfe, 0x33, 0x6d, 0x5a, 0x1f, 0x74,
+       0xa8, 0xfb, 0x56, 0x43, 0x9f, 0xb1, 0xbd, 0x59, 0xfd, 0x11, 0x13, 0x6f,
+       0xc5, 0x35, 0x0f, 0x1a, 0x84, 0x7e, 0x9e, 0x9d, 0x84, 0xaf, 0x46, 0xdc,
+       0x5b, 0x15, 0xad, 0x1e, 0xf7, 0xce, 0xeb, 0x55, 0xa5, 0x0d, 0x65, 0x80,
+       0x7a, 0x73, 0x0d, 0xd6, 0xdb, 0x13, 0xed, 0x01, 0x7f, 0xbd, 0x82, 0xfe,
+       0x8d, 0x1a, 0x4f, 0x04, 0x21, 0xf3, 0x37, 0x26, 0x5b, 0xbd, 0x18, 0xce,
+       0x41, 0x1b, 0x71, 0xeb, 0x64, 0x84, 0x31, 0x05, 0xda, 0x5d, 0x52, 0x37,
+       0x85, 0xf8, 0x15, 0x7a, 0x7c, 0x51, 0xed, 0x51, 0x0f, 0xc6, 0xef, 0x20,
+       0xce, 0x0f, 0xd7, 0x87, 0x71, 0x5f, 0xb7, 0xc1, 0x22, 0x44, 0x37, 0xe9,
+       0x99, 0xce, 0x4e, 0x26, 0x62, 0x87, 0xc4, 0xeb, 0x1b, 0x73, 0x55, 0x1f,
+       0x2c, 0xef, 0xeb, 0x01, 0xd9, 0x53, 0xb6, 0x17, 0x8c, 0xa3, 0xe1, 0xc3,
+       0x4f, 0x1b, 0x7b, 0x90, 0x2b, 0xf4, 0x28, 0x3e, 0x2a, 0x38, 0xb0, 0x80,
+       0xb3, 0xa4, 0x4f, 0xba, 0x04, 0x3f, 0xdc, 0xc5, 0x19, 0xd2, 0xef, 0x2e,
+       0x1d, 0x3f, 0xe9, 0xa6, 0x58, 0x1f, 0x83, 0x3e, 0x38, 0x2e, 0xc3, 0x88,
+       0x0b, 0x86, 0x83, 0xcd, 0xcc, 0x2b, 0xc3, 0x37, 0xcc, 0x7a, 0xb9, 0xc7,
+       0x1e, 0xe6, 0x4c, 0xe5, 0xec, 0x3c, 0xf7, 0x4e, 0xd9, 0x36, 0xb1, 0xf7,
+       0xec, 0x24, 0xf7, 0x6b, 0xf2, 0x10, 0x6c, 0x5b, 0x53, 0x2e, 0x7e, 0x79,
+       0x16, 0x7d, 0xf8, 0xed, 0x87, 0x3c, 0x70, 0x2e, 0x7e, 0xe7, 0x97, 0xe4,
+       0xbd, 0xf3, 0xbe, 0x6d, 0x0f, 0xc8, 0xbb, 0x4e, 0xe9, 0xf8, 0x09, 0x77,
+       0x2d, 0xcf, 0xc0, 0xcd, 0xb2, 0x66, 0xed, 0x38, 0x6e, 0x4e, 0x4a, 0xa5,
+       0x45, 0x77, 0x71, 0xad, 0xa5, 0xb4, 0xa4, 0xfc, 0x7f, 0x80, 0x33, 0xbc,
+       0x76, 0xaf, 0x25, 0x86, 0x7e, 0xa4, 0xcd, 0xe7, 0x6b, 0x7f, 0x95, 0xb6,
+       0xc0, 0xd7, 0x7f, 0xe4, 0x47, 0xf2, 0xe5, 0x92, 0xec, 0x54, 0xfd, 0xbf,
+       0xd2, 0x7d, 0x95, 0xba, 0xdf, 0xf7, 0x6f, 0xa9, 0xdf, 0xc9, 0x8b, 0x31,
+       0x8d, 0x0f, 0x36, 0x4d, 0xd5, 0xea, 0x84, 0x1f, 0x78, 0x75, 0x85, 0x95,
+       0x78, 0xef, 0x80, 0xa7, 0x17, 0x52, 0xea, 0x3b, 0xa7, 0x6c, 0xea, 0x07,
+       0xee, 0xa7, 0x51, 0xc6, 0x67, 0x6e, 0x83, 0x26, 0xbe, 0x0e, 0x66, 0xdc,
+       0xe7, 0xeb, 0x8e, 0x66, 0xcf, 0x17, 0xb6, 0xa4, 0xf3, 0x2c, 0x7d, 0x27,
+       0x07, 0x7a, 0xb4, 0x45, 0xd2, 0x63, 0x41, 0x49, 0x9e, 0x6d, 0x89, 0x19,
+       0x5f, 0x97, 0xfc, 0x07, 0x79, 0xd3, 0x3e, 0xb6, 0x37, 0xa0, 0xff, 0x4e,
+       0xe1, 0xb3, 0x0d, 0x3f, 0x43, 0x9e, 0xf7, 0xf9, 0x63, 0x76, 0x0d, 0x8f,
+       0xee, 0xf0, 0x78, 0x94, 0xe3, 0x96, 0xa9, 0x7f, 0x60, 0x6e, 0xe7, 0x59,
+       0xee, 0xd1, 0xdc, 0xd7, 0x79, 0xd6, 0xc4, 0xeb, 0xd5, 0xf7, 0xf5, 0x94,
+       0xef, 0xc3, 0x78, 0x97, 0x62, 0xc3, 0xb0, 0xf6, 0xce, 0x7e, 0xf8, 0x74,
+       0x3d, 0xb4, 0x39, 0xb4, 0xdf, 0x1b, 0xdd, 0x9d, 0x42, 0x7e, 0x4f, 0x78,
+       0x3c, 0x47, 0x7d, 0x13, 0xf1, 0xf4, 0xcd, 0xb2, 0x7d, 0x19, 0x36, 0xf8,
+       0x13, 0xe6, 0x44, 0x2a, 0xec, 0xcb, 0x43, 0xe6, 0xdd, 0xaa, 0xec, 0xcb,
+       0x9d, 0xde, 0x3a, 0xfe, 0x98, 0xaf, 0x57, 0xfc, 0xb6, 0xaf, 0x57, 0x6a,
+       0x7d, 0x5a, 0x9f, 0xf6, 0xd5, 0xb8, 0xaf, 0xca, 0x98, 0x2f, 0xb7, 0x62,
+       0xde, 0x25, 0x83, 0x98, 0x8d, 0x3e, 0x65, 0x22, 0x6b, 0x30, 0xd3, 0xd6,
+       0x19, 0x8b, 0xb8, 0x0f, 0xe7, 0x67, 0x32, 0x14, 0xb9, 0xad, 0xb1, 0xf5,
+       0xa9, 0x99, 0x51, 0xcd, 0xf3, 0xcc, 0xba, 0x9e, 0xde, 0x89, 0xee, 0x86,
+       0x5c, 0xcd, 0x47, 0x96, 0x31, 0x45, 0x4f, 0x1e, 0x1b, 0x82, 0x1d, 0x4a,
+       0x69, 0xbd, 0xec, 0x71, 0xec, 0xb7, 0x5f, 0xf1, 0x5c, 0xab, 0x9c, 0xe7,
+       0x64, 0x97, 0x5d, 0xd2, 0xda, 0x4d, 0xc3, 0x40, 0xf6, 0x58, 0xc3, 0x69,
+       0x9f, 0xef, 0xc9, 0x4f, 0x4f, 0x1e, 0x1b, 0x9f, 0x2e, 0x0d, 0x86, 0xb6,
+       0x75, 0xdb, 0x39, 0x59, 0x0f, 0x9a, 0x0f, 0xca, 0xa3, 0x8a, 0x1d, 0x7e,
+       0x0d, 0xe3, 0xfb, 0x18, 0x5f, 0x26, 0x42, 0x8a, 0x09, 0x4e, 0xc4, 0x26,
+       0x20, 0x8b, 0x19, 0x37, 0xd1, 0x35, 0x14, 0x5c, 0xcd, 0xdc, 0x0d, 0x62,
+       0x66, 0xfa, 0x59, 0xc4, 0x14, 0x3c, 0x2b, 0x87, 0xdc, 0x8d, 0xee, 0xa2,
+       0x64, 0x3d, 0x4c, 0x3e, 0x6b, 0x42, 0xf5, 0x32, 0xe1, 0x86, 0x1a, 0x86,
+       0x8a, 0x46, 0x06, 0x46, 0x82, 0xa9, 0x55, 0x27, 0x9d, 0x68, 0xc3, 0xce,
+       0x22, 0x64, 0xbc, 0x08, 0xfd, 0x5f, 0x8c, 0x05, 0x86, 0x15, 0x9b, 0xf6,
+       0x55, 0x19, 0x6a, 0xa5, 0x9f, 0x4f, 0x7d, 0xf2, 0x35, 0xb9, 0x61, 0x6f,
+       0x96, 0x1b, 0x5d, 0xc4, 0x63, 0xf6, 0xa2, 0x4d, 0x5d, 0xd2, 0x8f, 0xbe,
+       0x24, 0xfa, 0x1a, 0x94, 0x1f, 0x35, 0x3e, 0x83, 0xce, 0xba, 0x61, 0x53,
+       0x57, 0xdd, 0xc5, 0x5f, 0xbc, 0xeb, 0x9f, 0x41, 0x13, 0x62, 0x3b, 0xb6,
+       0xa0, 0x4d, 0x1d, 0x67, 0xd7, 0xf4, 0xb7, 0xa3, 0x7d, 0x2f, 0xd6, 0xa8,
+       0xd3, 0xf7, 0xb3, 0x9c, 0x6d, 0xa6, 0xce, 0x59, 0x35, 0x67, 0x4d, 0x4d,
+       0xfb, 0xdd, 0x16, 0x83, 0x4f, 0xb8, 0x45, 0x7a, 0x67, 0x53, 0xb2, 0xab,
+       0xad, 0xba, 0xfd, 0xcf, 0x9a, 0x76, 0xb3, 0xac, 0x6a, 0x21, 0x19, 0x9e,
+       0x68, 0xad, 0xee, 0xf7, 0xf9, 0xc9, 0x6f, 0xb7, 0xe1, 0x7d, 0x13, 0x30,
+       0x78, 0x49, 0x8d, 0xa5, 0x6e, 0x44, 0xf9, 0xac, 0xbf, 0xd6, 0xdc, 0xc3,
+       0x6b, 0xde, 0xc3, 0x7b, 0x99, 0xd7, 0xfb, 0x37, 0xfb, 0x71, 0x0f, 0x73,
+       0x02, 0xcc, 0x6b, 0x90, 0x67, 0x57, 0x8a, 0xb3, 0x38, 0xe7, 0xf3, 0xf9,
+       0x86, 0x74, 0x99, 0xf7, 0x7c, 0xbd, 0x12, 0x2b, 0x63, 0xd5, 0x76, 0xe6,
+       0xfd, 0x9c, 0x30, 0x69, 0xa7, 0x35, 0xa9, 0xd8, 0x75, 0xd0, 0xf9, 0x20,
+       0xe8, 0xfc, 0x40, 0x90, 0x71, 0x61, 0xa3, 0x47, 0x6b, 0x47, 0x86, 0x8b,
+       0x6f, 0x43, 0xc6, 0xc9, 0xa3, 0xf0, 0x29, 0x8a, 0x96, 0x87, 0xcf, 0xe8,
+       0x83, 0x4d, 0x73, 0x25, 0xa8, 0x79, 0x07, 0xc4, 0xf7, 0x73, 0xd7, 0x64,
+       0x78, 0x92, 0x39, 0x01, 0xf2, 0x33, 0xe3, 0xfa, 0x14, 0xc6, 0x6e, 0x62,
+       0xae, 0x0b, 0x19, 0x1e, 0x05, 0xbf, 0x86, 0xc4, 0x99, 0xda, 0x22, 0xd9,
+       0xb1, 0x51, 0xf5, 0x01, 0x3a, 0x61, 0xa3, 0x4e, 0xb8, 0x23, 0x72, 0xf2,
+       0xf2, 0xdd, 0x90, 0x55, 0xc6, 0xfd, 0x9a, 0xd3, 0x28, 0x85, 0xd5, 0x37,
+       0xa7, 0xcf, 0xc1, 0x3c, 0x9c, 0xa9, 0x31, 0x1b, 0xb9, 0x7d, 0x24, 0x26,
+       0xcd, 0x23, 0x32, 0x3d, 0x63, 0x2b, 0xde, 0x25, 0x25, 0xb7, 0x4b, 0xa4,
+       0x5d, 0x66, 0x5f, 0x1c, 0xba, 0x8a, 0xbe, 0x7c, 0x2e, 0x62, 0xce, 0x72,
+       0x74, 0x1d, 0x63, 0xe2, 0xe4, 0x54, 0xe5, 0x1a, 0x8a, 0x91, 0xc1, 0xd8,
+       0xa5, 0x16, 0x23, 0x33, 0x8c, 0x8f, 0x3f, 0x2a, 0xa5, 0xa2, 0x7c, 0x26,
+       0xe7, 0xb2, 0x76, 0x4b, 0x1e, 0xe1, 0xde, 0xfe, 0xe3, 0xf1, 0xf2, 0x4b,
+       0x58, 0x2f, 0x2e, 0x9d, 0xaf, 0x8f, 0x6a, 0x5c, 0x7f, 0xa2, 0x2a, 0x86,
+       0x35, 0xf9, 0x02, 0x13, 0xc7, 0x5e, 0x93, 0x89, 0x05, 0xd2, 0x87, 0x36,
+       0x3e, 0x20, 0x3f, 0x77, 0xba, 0xed, 0xc7, 0xb4, 0xd6, 0x98, 0x48, 0xb1,
+       0x3e, 0xd3, 0xe8, 0x24, 0xed, 0x39, 0x09, 0xf5, 0x7f, 0x03, 0xd7, 0x8c,
+       0x6b, 0x73, 0x6e, 0xb7, 0xfb, 0x98, 0xf8, 0x38, 0x90, 0x8d, 0xa9, 0xfa,
+       0xc0, 0xad, 0xd2, 0xb5, 0x7d, 0x9c, 0x63, 0x70, 0x20, 0x12, 0x20, 0xad,
+       0x3e, 0xb8, 0x8b, 0xf8, 0x99, 0xea, 0xfc, 0xdf, 0xfd, 0x47, 0xf6, 0xf6,
+       0x25, 0x5e, 0x64, 0x0c, 0x1b, 0x76, 0x0e, 0xac, 0x33, 0xef, 0x9a, 0xcd,
+       0xae, 0x11, 0xad, 0x9f, 0x1d, 0xfd, 0xbb, 0x43, 0x3c, 0x44, 0x22, 0x56,
+       0x6f, 0x31, 0x0f, 0x4e, 0x1d, 0xc7, 0x9a, 0x0a, 0x73, 0x6e, 0xc4, 0xf2,
+       0x37, 0xc8, 0xa5, 0x1e, 0x4b, 0xee, 0x0f, 0xa5, 0xe2, 0x96, 0x6c, 0x8a,
+       0x9f, 0x15, 0x3c, 0x93, 0xf5, 0x95, 0x85, 0x44, 0x96, 0xf3, 0x43, 0x53,
+       0x5c, 0x2f, 0xae, 0xf1, 0x4a, 0x72, 0x53, 0xa9, 0xf4, 0x94, 0x2b, 0x81,
+       0xe4, 0xd6, 0x8f, 0x4b, 0xac, 0x85, 0x5b, 0xaf, 0x7f, 0x11, 0x4e, 0x41,
+       0xbf, 0x1d, 0x98, 0x30, 0x98, 0xc3, 0x89, 0xa3, 0x9d, 0x0b, 0x6c, 0xa7,
+       0x77, 0x99, 0xf6, 0x61, 0xb4, 0xeb, 0x3c, 0xac, 0xd3, 0x0f, 0x8f, 0x76,
+       0x16, 0x9e, 0x58, 0x67, 0xe2, 0xef, 0x25, 0xc5, 0x7f, 0xbd, 0x53, 0x15,
+       0xd3, 0xa4, 0x02, 0x63, 0xf9, 0xd1, 0xc0, 0x68, 0xde, 0xea, 0x69, 0x00,
+       0xad, 0xe6, 0x5d, 0xe6, 0x6a, 0xfc, 0x9c, 0x15, 0xf3, 0xfd, 0x22, 0x4f,
+       0x2a, 0x46, 0x8a, 0x35, 0x45, 0x4b, 0x7d, 0xa1, 0x83, 0xf3, 0xcc, 0xf1,
+       0x47, 0x54, 0x1f, 0x1c, 0x5a, 0x68, 0x96, 0x9c, 0xbd, 0x56, 0x72, 0x2a,
+       0xe3, 0x51, 0xd5, 0x01, 0x96, 0xb3, 0x15, 0x7d, 0xdc, 0xf7, 0x43, 0x8a,
+       0x8b, 0x78, 0x23, 0xdf, 0x8e, 0x36, 0x73, 0xcd, 0xdb, 0x6b, 0xfa, 0x2b,
+       0xeb, 0xb2, 0x09, 0xdb, 0xb2, 0x6a, 0x6b, 0xb2, 0xec, 0xab, 0xad, 0xc5,
+       0x9e, 0x92, 0x6b, 0xe4, 0x9b, 0xa2, 0x9f, 0x73, 0x77, 0xbd, 0x9c, 0xfb,
+       0xf7, 0xb1, 0x26, 0xd7, 0x96, 0x74, 0x68, 0xa0, 0xa1, 0xe7, 0xc4, 0x64,
+       0xf0, 0xe6, 0x72, 0xfe, 0x14, 0xed, 0x85, 0x72, 0xad, 0x1c, 0x63, 0xcf,
+       0xc0, 0x17, 0xc9, 0xc1, 0xaf, 0xc8, 0x7a, 0xdf, 0x1f, 0x70, 0xbc, 0x7c,
+       0xff, 0x97, 0xec, 0xa9, 0x51, 0xeb, 0xec, 0x56, 0x55, 0x9d, 0xfd, 0x7b,
+       0xb8, 0x97, 0x35, 0xf6, 0x6c, 0xa9, 0x0e, 0xbc, 0x5b, 0x47, 0x9c, 0x48,
+       0x79, 0x3e, 0x75, 0xbc, 0xea, 0x72, 0x5d, 0x6b, 0xa7, 0xb7, 0x56, 0x10,
+       0x7a, 0x7e, 0x7c, 0xd2, 0x9f, 0x73, 0x5c, 0xea, 0x7b, 0x13, 0xb1, 0xa0,
+       0xc5, 0x39, 0x46, 0xdf, 0x0f, 0xb9, 0xc7, 0xa1, 0xc7, 0xa9, 0xf3, 0xf9,
+       0xde, 0x0e, 0x7c, 0x3d, 0xea, 0x02, 0xea, 0x73, 0xb5, 0x01, 0xf1, 0x1c,
+       0x74, 0xfd, 0x70, 0xd1, 0x7c, 0xeb, 0xf5, 0xf5, 0x60, 0x62, 0x3a, 0xa3,
+       0xba, 0x01, 0xfe, 0x5e, 0xf1, 0x0d, 0xe6, 0x83, 0x5e, 0x94, 0x40, 0x65,
+       0x9d, 0x86, 0xb1, 0x19, 0x6b, 0x1a, 0x4d, 0xd0, 0x0d, 0x22, 0x57, 0xc0,
+       0x1b, 0x57, 0xe7, 0xc9, 0xaf, 0xc1, 0x56, 0x13, 0x5f, 0x2d, 0x6e, 0xb7,
+       0xa4, 0x55, 0x6b, 0x9f, 0x39, 0x27, 0x42, 0xff, 0x64, 0x30, 0xd9, 0x0b,
+       0x3f, 0x5b, 0xb1, 0x07, 0xcc, 0x57, 0x8e, 0x23, 0x1e, 0xab, 0xcc, 0xb1,
+       0x40, 0xbe, 0xc6, 0xd8, 0x9f, 0x81, 0x5f, 0xb9, 0x5c, 0xf7, 0xc8, 0x15,
+       0x4e, 0x6a, 0x6e, 0x73, 0x76, 0xbe, 0x49, 0x75, 0xec, 0x6c, 0x61, 0x04,
+       0xe7, 0x22, 0x9b, 0xad, 0x81, 0x9c, 0xd7, 0x1f, 0x96, 0x42, 0x81, 0x6d,
+       0xe9, 0xa8, 0xd3, 0x73, 0xf7, 0x6b, 0x3b, 0xb6, 0xcc, 0xc1, 0x57, 0x2c,
+       0x2c, 0x38, 0xf8, 0xef, 0xc2, 0x7f, 0x0f, 0xfe, 0x77, 0xcb, 0xd0, 0x14,
+       0xfd, 0x57, 0xd6, 0x72, 0x9a, 0x6a, 0x9e, 0x4f, 0x1f, 0xa9, 0x43, 0x71,
+       0x60, 0x39, 0x2f, 0xce, 0xc9, 0x15, 0x6a, 0xe5, 0x84, 0x79, 0x52, 0x5f,
+       0x47, 0x30, 0x5f, 0xea, 0xd7, 0xfa, 0x2a, 0x6b, 0x58, 0x96, 0x57, 0xf7,
+       0x22, 0x4f, 0x37, 0xca, 0xa1, 0x82, 0x5f, 0xbb, 0x8a, 0xc9, 0xa3, 0xe5,
+       0xda, 0x95, 0xa4, 0x83, 0x03, 0xb7, 0x1e, 0xcc, 0x4c, 0x2a, 0x9e, 0xc0,
+       0xb2, 0x06, 0xae, 0x3d, 0x38, 0xb1, 0xf0, 0xee, 0x83, 0xcb, 0x98, 0x70,
+       0x8c, 0x2d, 0xac, 0x84, 0x19, 0x22, 0x96, 0xee, 0x33, 0xf2, 0x10, 0x0d,
+       0x27, 0xf6, 0xed, 0xc7, 0x3c, 0xc4, 0xd9, 0x6d, 0xb0, 0x97, 0xf1, 0xcb,
+       0x7e, 0x3c, 0x4a, 0x1c, 0x29, 0xef, 0xab, 0xc4, 0x7e, 0x84, 0x70, 0xfe,
+       0x12, 0xb0, 0x9c, 0x2c, 0xf6, 0x71, 0xa1, 0xdd, 0xf8, 0x81, 0xc4, 0x99,
+       0x26, 0x2a, 0xb0, 0x47, 0x3e, 0xd6, 0xf4, 0x65, 0xac, 0x95, 0x96, 0xdf,
+       0x14, 0x1f, 0x96, 0x5f, 0x16, 0x47, 0x21, 0xdf, 0x13, 0x58, 0xf3, 0x80,
+       0xfc, 0xa2, 0xb8, 0x4f, 0xde, 0x2a, 0x8e, 0xc9, 0x9b, 0xc5, 0xdd, 0x88,
+       0xa9, 0x46, 0x88, 0xf5, 0xf4, 0xb0, 0xd2, 0x83, 0x32, 0x7e, 0x4e, 0x31,
+       0x80, 0x37, 0xe9, 0xf7, 0x1c, 0x55, 0x3f, 0x9b, 0xf8, 0xfa, 0xc4, 0xaf,
+       0x18, 0xcf, 0x13, 0x9b, 0x59, 0x28, 0xfa, 0x18, 0x8e, 0x89, 0x0e, 0x3c,
+       0xdb, 0xe6, 0xb7, 0x29, 0xc3, 0xe7, 0x22, 0x81, 0x91, 0x73, 0xa1, 0xc0,
+       0x03, 0xfa, 0x9d, 0x0b, 0xeb, 0x9d, 0x25, 0x39, 0xe9, 0x3a, 0xe4, 0xcd,
+       0xfe, 0x61, 0xc8, 0xc2, 0x08, 0x54, 0xfd, 0x2e, 0x67, 0xad, 0x80, 0xa4,
+       0xa9, 0x4f, 0xe0, 0x67, 0x26, 0x4f, 0xbb, 0x92, 0xc9, 0xcf, 0x05, 0x0c,
+       0x1e, 0xcd, 0x46, 0xbb, 0x07, 0xed, 0x57, 0xbd, 0xf6, 0x0e, 0xc9, 0xcc,
+       0x48, 0xea, 0x43, 0xf5, 0x87, 0x5f, 0xf1, 0xfa, 0xfa, 0xd1, 0x07, 0xce,
+       0xbc, 0xc0, 0xbe, 0x0b, 0x5e, 0x1f, 0xcf, 0x84, 0xb5, 0xfa, 0xb8, 0xf2,
+       0x55, 0xc6, 0x1e, 0x13, 0xfd, 0xae, 0x41, 0x6b, 0xf1, 0x4b, 0xed, 0x46,
+       0xb7, 0x11, 0x13, 0xf8, 0x8f, 0x76, 0xc6, 0x60, 0x05, 0xc8, 0xd7, 0x5d,
+       0xd0, 0x89, 0x7f, 0xd9, 0xbc, 0xdc, 0xb6, 0x06, 0x3e, 0xad, 0xc0, 0x68,
+       0x7f, 0x2a, 0x9d, 0x0b, 0xff, 0xf2, 0xf0, 0xbc, 0x07, 0xf1, 0x6e, 0x38,
+       0xab, 0x3c, 0x71, 0xe3, 0x71, 0xc8, 0x76, 0x93, 0xac, 0x3d, 0x43, 0x7a,
+       0x75, 0x43, 0x57, 0xa7, 0x20, 0xb7, 0xae, 0xcc, 0x17, 0x43, 0x81, 0xe1,
+       0x7c, 0x4a, 0x0c, 0x9e, 0xda, 0x92, 0x74, 0x34, 0x25, 0xa7, 0xfa, 0x12,
+       0x5d, 0xcc, 0x43, 0x66, 0x7a, 0x5d, 0xb9, 0x58, 0xa4, 0x3d, 0xce, 0xca,
+       0xa5, 0xbe, 0x84, 0x5b, 0x10, 0xe2, 0x62, 0x5c, 0xb9, 0x04, 0xd9, 0xfc,
+       0xdd, 0xb9, 0xdd, 0xf2, 0x68, 0x5e, 0xfd, 0xe0, 0xee, 0xb0, 0xbc, 0x20,
+       0x17, 0xfb, 0x5e, 0xb8, 0x79, 0xd1, 0x7d, 0x04, 0x67, 0x4a, 0x3e, 0xcc,
+       0x74, 0x98, 0x7d, 0x2b, 0x0e, 0x49, 0x98, 0x0f, 0xd1, 0x9a, 0x9a, 0x53,
+       0x2f, 0x43, 0xfb, 0x23, 0x5e, 0x5c, 0x0e, 0x9f, 0x3b, 0xe0, 0x9a, 0x7a,
+       0x4a, 0xc0, 0xdf, 0x67, 0x18, 0x7e, 0x0c, 0xef, 0xf3, 0x69, 0xe3, 0xaf,
+       0xd3, 0x1e, 0x18, 0x9a, 0x69, 0x96, 0xd0, 0x85, 0xaf, 0x80, 0xae, 0x21,
+       0x39, 0xd8, 0x5b, 0x2a, 0x7d, 0xc7, 0x0d, 0xc5, 0x27, 0x10, 0xa3, 0x60,
+       0xff, 0xb2, 0xe6, 0x74, 0x0b, 0x68, 0xd2, 0x20, 0xd1, 0xd3, 0xfe, 0xf3,
+       0xea, 0x3d, 0x2c, 0xc3, 0x99, 0x35, 0xc6, 0x96, 0xf9, 0xd8, 0x06, 0x7f,
+       0x3d, 0x83, 0x29, 0xeb, 0xb4, 0x7a, 0x03, 0xde, 0x77, 0x12, 0x5e, 0x7b,
+       0x6b, 0xe0, 0xfe, 0x50, 0xab, 0x84, 0x9c, 0x67, 0xd7, 0x13, 0x1b, 0xb9,
+       0x98, 0xf7, 0xfb, 0xe1, 0x27, 0x86, 0x7c, 0x7f, 0x58, 0xb6, 0x2d, 0x9f,
+       0xb5, 0x6c, 0xeb, 0x5c, 0xf8, 0xae, 0xb7, 0x66, 0xca, 0x9b, 0x8b, 0x98,
+       0x23, 0xb6, 0x5a, 0xed, 0x93, 0x99, 0xfb, 0x5f, 0x79, 0xba, 0x37, 0xf1,
+       0x9a, 0xe2, 0x64, 0xcb, 0xf7, 0x70, 0x1c, 0x31, 0x64, 0x51, 0xef, 0x89,
+       0xed, 0x01, 0x7d, 0xd3, 0xb1, 0x7b, 0xec, 0x39, 0x2b, 0x18, 0x30, 0xfe,
+       0x48, 0x9d, 0xfc, 0x28, 0x0a, 0xbb, 0xcd, 0x6f, 0x58, 0x98, 0xff, 0x72,
+       0x6f, 0x7b, 0x7e, 0x0a, 0xfb, 0x12, 0x2f, 0x26, 0xad, 0x34, 0xf6, 0xc7,
+       0x33, 0x20, 0x06, 0xd4, 0x02, 0x9d, 0xda, 0xf1, 0x7e, 0x88, 0x9f, 0x7a,
+       0xfd, 0xf7, 0x5f, 0x03, 0x1d, 0xc6, 0xfd, 0x1b, 0x5c, 0x98, 0x58, 0xcc,
+       0x85, 0x0c, 0x7a, 0x18, 0xd8, 0x4a, 0xb9, 0xf5, 0xb1, 0xb1, 0x3e, 0x9e,
+       0x8e, 0x18, 0xa5, 0x18, 0xfc, 0x40, 0xca, 0x04, 0x79, 0xb3, 0x0d, 0xfd,
+       0xab, 0x6e, 0xa5, 0xf4, 0xd5, 0xfd, 0xbe, 0x8f, 0xcb, 0xd8, 0xee, 0x89,
+       0xfc, 0x3e, 0x83, 0xcd, 0xb3, 0x96, 0x24, 0xd5, 0x91, 0xb4, 0x4f, 0x62,
+       0xbf, 0x43, 0xa1, 0x44, 0x21, 0x2b, 0x31, 0x99, 0x83, 0xbe, 0xb8, 0x0a,
+       0xd9, 0x7f, 0xab, 0xc8, 0xef, 0x6d, 0x53, 0x72, 0x28, 0x0f, 0x83, 0x3e,
+       0xa3, 0xdf, 0x7e, 0x41, 0xef, 0x0f, 0xc8, 0x6c, 0x3e, 0xd1, 0x35, 0x07,
+       0xfe, 0x9b, 0xcb, 0x13, 0x5f, 0xd4, 0x1d, 0x1f, 0xc1, 0x8a, 0x8b, 0xf9,
+       0x8d, 0xb0, 0x0f, 0x92, 0xba, 0x08, 0xff, 0xe7, 0x62, 0xb1, 0x0b, 0x7c,
+       0x86, 0xf1, 0xa2, 0x83, 0x5f, 0xe8, 0xcc, 0x62, 0x1f, 0xe4, 0x9c, 0x7b,
+       0xb1, 0x65, 0x7e, 0x33, 0xce, 0x8e, 0x38, 0x22, 0xc5, 0x8f, 0x7f, 0x86,
+       0xf3, 0xf5, 0xdf, 0x7b, 0xbb, 0xda, 0xe9, 0x39, 0xdd, 0x17, 0xec, 0x32,
+       0x62, 0x80, 0x4c, 0xaf, 0xb1, 0xdb, 0x43, 0x91, 0x16, 0x19, 0xba, 0x87,
+       0x76, 0xbc, 0x55, 0x63, 0x44, 0xe5, 0xc5, 0x08, 0xc7, 0x7f, 0xbb, 0xde,
+       0xd0, 0x2f, 0x5c, 0xd3, 0x7e, 0x1b, 0xbf, 0xcd, 0xd2, 0xe6, 0xf0, 0xd7,
+       0xc6, 0xef, 0xb5, 0xf5, 0xac, 0xef, 0xb6, 0x39, 0x49, 0x3c, 0xeb, 0xd7,
+       0x5e, 0xbe, 0x00, 0xd7, 0x73, 0xbc, 0x67, 0x9d, 0xf7, 0x5c, 0xae, 0xdb,
+       0x8c, 0x75, 0x9a, 0xbc, 0x67, 0x35, 0x6b, 0x7e, 0xd2, 0x3c, 0x0b, 0x31,
+       0x6e, 0xfe, 0x4f, 0xeb, 0x79, 0x86, 0xfc, 0xde, 0xb8, 0xba, 0xfd, 0xc7,
+       0xf5, 0xc4, 0xcd, 0xb5, 0x39, 0xcd, 0x8a, 0xf1, 0xbc, 0xd1, 0xda, 0x8a,
+       0x6b, 0x3e, 0x93, 0x73, 0x4c, 0x3e, 0x7c, 0xb6, 0xc8, 0xf5, 0xd9, 0x4e,
+       0xc9, 0x31, 0xcd, 0x67, 0x18, 0x2c, 0xdf, 0x6c, 0xfe, 0x3e, 0x99, 0x38,
+       0xa7, 0xf8, 0xba, 0xe9, 0x9c, 0xc5, 0xef, 0x5e, 0xf8, 0xbd, 0x1c, 0x7d,
+       0x89, 0x51, 0x19, 0xc7, 0xf9, 0x5d, 0x82, 0x4f, 0xb5, 0x68, 0xbe, 0x8b,
+       0xc5, 0xdf, 0x01, 0x9c, 0x4b, 0x08, 0x32, 0x46, 0x19, 0xa5, 0x4c, 0xe1,
+       0xfc, 0xc6, 0x6c, 0x79, 0xaf, 0x8f, 0xf2, 0xdc, 0x27, 0x97, 0xcb, 0xf2,
+       0x9c, 0x85, 0x3c, 0x53, 0x96, 0xb3, 0x90, 0x69, 0xc3, 0xd7, 0xfb, 0x11,
+       0x63, 0xa4, 0x62, 0xb0, 0x57, 0xea, 0x43, 0xbc, 0x0c, 0xbe, 0xb6, 0xbd,
+       0x6f, 0xa5, 0x02, 0x9a, 0xc3, 0xc9, 0xcc, 0xd4, 0x79, 0xdf, 0x01, 0xe0,
+       0xfa, 0xf2, 0x73, 0x32, 0x34, 0xd3, 0x88, 0x7d, 0x6f, 0xe8, 0xe0, 0x99,
+       0x65, 0x2e, 0xf3, 0xdf, 0xe7, 0x45, 0xe2, 0x4d, 0xe9, 0xcf, 0xf2, 0x9a,
+       0x71, 0xde, 0x7a, 0xcc, 0xe9, 0x07, 0x9d, 0x1b, 0xb1, 0x3e, 0xf7, 0xb8,
+       0xd2, 0x3c, 0x8e, 0x87, 0x2a, 0xf0, 0xa9, 0x3e, 0xbd, 0x57, 0xeb, 0x33,
+       0x33, 0xbd, 0x8d, 0xde, 0xfb, 0xf1, 0x1c, 0xc8, 0xf7, 0x31, 0xf0, 0x2d,
+       0x7d, 0x62, 0xf2, 0x4b, 0x4a, 0xcf, 0x61, 0x36, 0x4f, 0xfe, 0x0d, 0x69,
+       0x0e, 0x23, 0x03, 0xdb, 0xb2, 0x57, 0xe7, 0xc7, 0x96, 0xe5, 0xbb, 0x23,
+       0xa0, 0x71, 0x77, 0x26, 0xbf, 0x4a, 0x3a, 0x55, 0x07, 0x75, 0x78, 0xbc,
+       0x0d, 0x7b, 0xa1, 0x58, 0xee, 0x03, 0x72, 0xb4, 0xd8, 0x0f, 0x3a, 0xc4,
+       0xe4, 0x29, 0xf8, 0xcd, 0xcf, 0x14, 0xef, 0x90, 0xa5, 0x08, 0xf6, 0x55,
+       0x96, 0xb1, 0x41, 0xf9, 0xf1, 0xdc, 0x06, 0xef, 0x3a, 0xe1, 0x2e, 0x59,
+       0xdb, 0xb1, 0x07, 0xca, 0x13, 0xe5, 0x8a, 0xf3, 0x82, 0x88, 0x45, 0xb8,
+       0xee, 0x11, 0xa3, 0xdb, 0xb0, 0x6e, 0x21, 0x42, 0xf9, 0xe5, 0xde, 0x42,
+       0x9e, 0xcc, 0x32, 0xae, 0xe2, 0x3b, 0x1b, 0x9b, 0x94, 0xae, 0x3a, 0x8b,
+       0x84, 0xe2, 0x40, 0x97, 0xcf, 0xc0, 0x5f, 0xc7, 0x97, 0x4b, 0xff, 0x3b,
+       0x0a, 0xea, 0x51, 0xd8, 0xca, 0x3c, 0x6c, 0x65, 0x1e, 0x36, 0x12, 0xb2,
+       0xf0, 0x56, 0x1e, 0x36, 0x32, 0x0f, 0x1b, 0x09, 0x7d, 0xf6, 0x06, 0x62,
+       0xbb, 0xab, 0xe0, 0x21, 0xe3, 0x6b, 0x1f, 0xa6, 0xaf, 0x8d, 0xbf, 0xff,
+       0x01, 0x88, 0x97, 0xee, 0xe9, 0xc4, 0x71, 0x00, 0x00, 0x00 };
 
-static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_RXP_b06FwRodata[(0x278/4) + 1] = {
-       0x08003fdc, 0x08003edc, 0x08003f80, 0x08003f98, 0x08003fb0, 0x08003fd0,
-       0x08003fdc, 0x08003fdc, 0x08003ee4, 0x00000000, 0x08004a04, 0x08004a3c,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004a74, 0x08004c38,
-       0x08004b80, 0x08004bb8, 0x08004c38, 0x08004b08, 0x08004c38, 0x08004c38,
-       0x08004bb8, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004bf8,
-       0x08004c38, 0x08004bf8, 0x08004b80, 0x08004c38, 0x08004c38, 0x08004bf8,
-       0x08004bf8, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38, 0x08004c38,
-       0x08004ae4, 0x00000000, 0x08006018, 0x08006030, 0x08006030, 0x08006030,
-       0x08006018, 0x08006030, 0x08006030, 0x08006030, 0x08006018, 0x08006030,
-       0x08006030, 0x08006030, 0x08006018, 0x08006030, 0x08006030, 0x08006030,
-       0x08006024, 0x00000000, 0x00000000 };
+static const u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_RXP_b06FwRodata[(0x24/4) + 1] = {
+       0x08004580, 0x08004580, 0x080044f8, 0x08004530, 0x08004564, 0x08004588,
+       0x08004588, 0x08004588, 0x08004468, 0x00000000 };
 
 static struct fw_info bnx2_rxp_fw_06 = {
-       .ver_major                      = 0x2,
-       .ver_minor                      = 0x8,
-       .ver_fix                        = 0x17,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x08003184,
+       .start_addr                     = 0x080031d0,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x6728,
+       .text_len                       = 0x71c0,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_RXP_b06FwText,
        .gz_text_len                    = sizeof(bnx2_RXP_b06FwText),
 
-       .data_addr                      = 0x080069c0,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_RXP_b06FwData,
 
-       .sbss_addr                      = 0x080069c0,
-       .sbss_len                       = 0x2c,
+       .sbss_addr                      = 0x08007200,
+       .sbss_len                       = 0x58,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080069f0,
-       .bss_len                        = 0x13dc,
+       .bss_addr                       = 0x08007258,
+       .bss_len                        = 0x44c,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08006728,
-       .rodata_len                     = 0x278,
+       .rodata_addr                    = 0x080071c0,
+       .rodata_len                     = 0x24,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_RXP_b06FwRodata,
 };
 
 static u8 bnx2_rv2p_proc1[] = {
-/*     0x1f, 0x8b, 0x08, 0x08, 0x5e, 0xd0, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
-       0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
-                                                       0xc5, 0x56, 0xcf, 0x6b,
-       0x13, 0x51, 0x10, 0x9e, 0xec, 0x6e, 0xb2, 0xdb, 0x74, 0xbb, 0x1b, 0x2b,
-       0xda, 0xa0, 0xb1, 0x8d, 0x51, 0x6a, 0x7f, 0xa4, 0xb4, 0x11, 0x0f, 0x82,
-       0x42, 0x25, 0x3d, 0x04, 0x54, 0x44, 0x7a, 0x28, 0x22, 0x82, 0x36, 0x8a,
-       0xfe, 0x1b, 0xa1, 0x3f, 0xd2, 0x4b, 0x10, 0x7a, 0xb0, 0x58, 0xf1, 0x50,
-       0x10, 0x2a, 0x68, 0x0f, 0xc9, 0xa1, 0x20, 0x52, 0x11, 0xda, 0x8b, 0x07,
-       0x2f, 0x42, 0x0f, 0x7a, 0x69, 0xbd, 0xa8, 0xff, 0x82, 0x08, 0x4d, 0x7c,
-       0x6f, 0x66, 0x9e, 0xee, 0x6e, 0xb2, 0x4d, 0x15, 0xc1, 0x85, 0xf6, 0xe3,
-       0xbd, 0x9d, 0x79, 0x33, 0xf3, 0xcd, 0x37, 0xfb, 0x62, 0x01, 0x40, 0x04,
-       0x60, 0xcd, 0x46, 0x2c, 0x8d, 0x26, 0x04, 0x1a, 0x30, 0x7e, 0x52, 0x62,
-       0x16, 0xde, 0xa6, 0x25, 0x4e, 0x44, 0xc6, 0xd3, 0x49, 0x81, 0x7b, 0x0d,
-       0x28, 0xc9, 0x75, 0x4f, 0xf5, 0x55, 0xad, 0x53, 0xa0, 0x06, 0xbb, 0xa3,
-       0x80, 0xcf, 0x47, 0x9d, 0xf0, 0x7c, 0xd6, 0x42, 0x2c, 0x31, 0xc2, 0x48,
-       0x02, 0x61, 0x7b, 0x51, 0xae, 0xad, 0x48, 0x69, 0xc4, 0x42, 0x3f, 0xd0,
-       0x68, 0x7f, 0x67, 0xd1, 0x15, 0xff, 0x53, 0xf0, 0x39, 0x2f, 0xd7, 0x56,
-       0x7c, 0x0e, 0xed, 0xaa, 0xec, 0x2f, 0xfe, 0xd0, 0xfe, 0xba, 0xf0, 0x03,
-       0x7e, 0x94, 0x5f, 0x02, 0xcf, 0x29, 0x66, 0x65, 0x5e, 0xdd, 0x22, 0xa0,
-       0xca, 0xc7, 0x46, 0x2c, 0xf5, 0x91, 0xb5, 0x89, 0xef, 0xbf, 0x8a, 0xbc,
-       0x55, 0xdc, 0x76, 0xf1, 0x82, 0xf9, 0x06, 0xe3, 0x26, 0x91, 0x1f, 0x28,
-       0xf9, 0xe3, 0x00, 0xc8, 0xfd, 0x4f, 0x8d, 0x5f, 0xfb, 0x83, 0xfe, 0xf7,
-       0xbb, 0x43, 0xf2, 0xbc, 0x28, 0xc0, 0x90, 0xb4, 0xdb, 0xe6, 0x7c, 0xc6,
-       0xe0, 0xb4, 0x96, 0xc4, 0xf7, 0x06, 0xfa, 0x1f, 0x11, 0xe7, 0x4a, 0xec,
-       0x61, 0x3c, 0xce, 0x78, 0x95, 0xb1, 0xc2, 0xe8, 0x32, 0x3a, 0x8c, 0x5d,
-       0x8c, 0x36, 0xe3, 0x26, 0x63, 0x9c, 0xb1, 0x83, 0xd1, 0x62, 0xdc, 0x63,
-       0x8c, 0x31, 0x46, 0x19, 0x1b, 0x8c, 0x46, 0x84, 0x50, 0xe3, 0xf5, 0x63,
-       0x46, 0xe0, 0xba, 0x23, 0x81, 0xba, 0x5f, 0xb3, 0x2e, 0x24, 0x6f, 0xfc,
-       0x7e, 0x50, 0xd9, 0x31, 0xef, 0x58, 0xf7, 0x3a, 0xdb, 0x75, 0x57, 0x57,
-       0x02, 0xfa, 0x49, 0xef, 0xab, 0x9b, 0x54, 0x8b, 0x3e, 0xb8, 0x58, 0xcf,
-       0x9d, 0x82, 0x8b, 0x71, 0x9c, 0x18, 0xed, 0xab, 0xb4, 0x6e, 0xb8, 0x84,
-       0xf7, 0xe2, 0x84, 0x5f, 0x18, 0xef, 0x77, 0x12, 0x4e, 0x77, 0xc9, 0x7c,
-       0x0e, 0x8b, 0x80, 0xea, 0x1c, 0x95, 0x4f, 0xbb, 0x3c, 0xc2, 0xe2, 0xa9,
-       0xbc, 0xda, 0xc5, 0x25, 0x2c, 0x6a, 0xfe, 0xfa, 0x9f, 0x8c, 0x11, 0x1a,
-       0x39, 0x22, 0x75, 0xc9, 0x16, 0x3d, 0x83, 0x46, 0x63, 0xd9, 0x36, 0xe4,
-       0xfa, 0xdc, 0xf2, 0x7b, 0xd4, 0xfb, 0xd9, 0xa5, 0x1a, 0xe7, 0xe7, 0x2a,
-       0x9e, 0x69, 0x0e, 0x32, 0x40, 0xeb, 0x49, 0xe4, 0x1d, 0x04, 0x5a, 0xb8,
-       0x86, 0x8c, 0xbf, 0x5f, 0xa4, 0x43, 0x9d, 0xfb, 0x31, 0xcb, 0xfd, 0x38,
-       0x11, 0xd2, 0x8f, 0xb0, 0xb9, 0x68, 0x9e, 0xc7, 0xdb, 0xe9, 0x20, 0x6f,
-       0x61, 0xf3, 0xa3, 0xf8, 0xa6, 0xdd, 0x3f, 0xe5, 0xf1, 0x01, 0xf3, 0x58,
-       0x24, 0x1e, 0x93, 0xdf, 0x5a, 0xf2, 0x94, 0xf6, 0xf0, 0x24, 0xeb, 0xec,
-       0x0d, 0xe9, 0x73, 0x58, 0x7d, 0xd9, 0xbf, 0xee, 0x73, 0x20, 0x3f, 0xb8,
-       0x8b, 0xdf, 0x9b, 0x04, 0x14, 0x0b, 0x2a, 0x5f, 0x3f, 0xcf, 0xc7, 0xa8,
-       0xdf, 0x30, 0x97, 0x93, 0xfb, 0x62, 0xfe, 0x36, 0x35, 0x5c, 0x1b, 0xf9,
-       0x88, 0x04, 0xab, 0x98, 0x23, 0x7f, 0x47, 0xd3, 0x78, 0x7d, 0x50, 0x5d,
-       0xa8, 0xbe, 0x4b, 0x8c, 0x41, 0x7e, 0x9a, 0xeb, 0xcc, 0x50, 0x3c, 0xd2,
-       0x81, 0xc1, 0x3a, 0xc8, 0xf3, 0xf7, 0x28, 0xc8, 0x87, 0x55, 0x5d, 0x59,
-       0xf4, 0xce, 0x75, 0x12, 0x8a, 0x39, 0xd2, 0x55, 0x73, 0x5f, 0x59, 0x6f,
-       0x6b, 0xea, 0xbb, 0x84, 0xdb, 0xd5, 0x92, 0xee, 0xab, 0xf7, 0x12, 0x64,
-       0xbd, 0x3c, 0x47, 0x5a, 0xe8, 0xa3, 0x5d, 0x1c, 0xdf, 0x79, 0x0e, 0x64,
-       0x5b, 0x7d, 0x6f, 0x4c, 0xae, 0xeb, 0x0c, 0xeb, 0xfb, 0x68, 0x93, 0xbe,
-       0xd5, 0x7d, 0xf5, 0xef, 0x74, 0xce, 0xf5, 0x9b, 0x68, 0x97, 0xda, 0x59,
-       0xf7, 0xde, 0x4f, 0x71, 0xcf, 0xfd, 0x44, 0x6e, 0xa6, 0xca, 0xbb, 0xcf,
-       0x7b, 0xaf, 0x1c, 0x0a, 0xe9, 0x83, 0xf7, 0x3e, 0x0a, 0xd6, 0xeb, 0xd7,
-       0x23, 0xf5, 0x35, 0xce, 0xf5, 0x9b, 0x0d, 0xee, 0xc3, 0x54, 0xff, 0x0c,
-       0xe9, 0x3f, 0x53, 0x90, 0xfa, 0x71, 0xc1, 0x31, 0xe9, 0x7c, 0x42, 0x71,
-       0x8e, 0x66, 0x62, 0xde, 0xf3, 0x1a, 0xad, 0xe7, 0x67, 0xd0, 0x2f, 0x3e,
-       0xa7, 0xf6, 0xf3, 0x48, 0xd8, 0xe4, 0x8b, 0x2d, 0xe2, 0xbd, 0xa6, 0xab,
-       0xb9, 0x70, 0x91, 0xef, 0x01, 0x97, 0xec, 0xcc, 0x2b, 0x8a, 0x2f, 0xb9,
-       0xaf, 0xc3, 0x12, 0xcd, 0xc5, 0xad, 0x47, 0x84, 0x37, 0xe1, 0x32, 0x9d,
-       0xfb, 0xfb, 0xfb, 0x66, 0x21, 0x42, 0x97, 0x57, 0xc7, 0x51, 0xa1, 0x63,
-       0x9c, 0x63, 0x25, 0x57, 0x78, 0xae, 0x11, 0x9f, 0xf3, 0xa4, 0x73, 0x8d,
-       0xf3, 0xc3, 0xab, 0x45, 0x3e, 0xab, 0xba, 0xac, 0xf7, 0x9a, 0xd2, 0x1d,
-       0x0c, 0x9b, 0x38, 0x3f, 0xa9, 0xca, 0x02, 0x2e, 0x7b, 0x1d, 0x46, 0xbb,
-       0x4c, 0x18, 0xc3, 0xfc, 0x75, 0x78, 0x58, 0x93, 0x7e, 0x05, 0xbe, 0xdf,
-       0x7e, 0xb0, 0x5e, 0x74, 0xa8, 0xf0, 0xef, 0x8b, 0x05, 0x7c, 0x3f, 0x01,
-       0xcd, 0xf7, 0x1b, 0xc5, 0x29, 0x0f, 0x11, 0xda, 0xa7, 0xb8, 0xaf, 0xc3,
-       0xd2, 0xce, 0x11, 0x7e, 0xdc, 0x3f, 0xec, 0xc3, 0x05, 0x8f, 0x3f, 0x42,
-       0xe5, 0xc3, 0x40, 0x98, 0xbf, 0xb4, 0xff, 0xde, 0xe2, 0x3e, 0xa5, 0xf7,
-       0x2f, 0xc9, 0x7e, 0xaa, 0xff, 0x19, 0xd7, 0x3f, 0xec, 0xd5, 0xbd, 0x8a,
-       0xf7, 0xae, 0xbe, 0xff, 0x7d, 0xdc, 0xc1, 0x76, 0x5b, 0xfb, 0xd8, 0xd1,
-       0xf1, 0xf9, 0x41, 0xef, 0xfd, 0xfd, 0xa6, 0x4e, 0x3c, 0x6d, 0xd4, 0xd5,
-       0x5c, 0x6d, 0x84, 0xcc, 0xd5, 0xc5, 0xff, 0x3a, 0x57, 0x10, 0x98, 0xab,
-       0xd5, 0xfa, 0xc1, 0xe6, 0x0a, 0xb8, 0x7e, 0x08, 0x99, 0xab, 0x18, 0xf3,
-       0xf0, 0x94, 0xcf, 0x33, 0x20, 0xaa, 0xc7, 0xb0, 0x7d, 0xc6, 0x2c, 0xeb,
-       0x92, 0xf4, 0x68, 0x47, 0xcb, 0xa8, 0x3f, 0xc7, 0x2e, 0x93, 0x9d, 0x41,
-       0xfb, 0x49, 0x85, 0x0b, 0xb3, 0xf4, 0x7b, 0x4a, 0x83, 0x9f, 0x94, 0x15,
-       0x12, 0x3d, 0x80, 0x0b, 0x00, 0x00, 0x00 };
+       /* Date:        12/07/2007 14:57 */
+       0xd5, 0x56, 0x41, 0x6b, 0x13, 0x51, 0x10, 0x9e, 0xdd, 0x6c, 0xbb, 0xdb,
+       0x64, 0xb3, 0x59, 0xaa, 0xd6, 0x50, 0x53, 0x93, 0x06, 0x2f, 0xad, 0x29,
+       0x6d, 0xaa, 0x82, 0x42, 0xa1, 0x92, 0x4b, 0xc1, 0xf6, 0x20, 0xf5, 0x22,
+       0x22, 0xd8, 0x46, 0xd1, 0x5f, 0x21, 0x06, 0xdb, 0xd4, 0x73, 0x05, 0x0b,
+       0xf5, 0xa0, 0x3d, 0x59, 0x11, 0xc1, 0x04, 0x14, 0x44, 0x04, 0x41, 0x45,
+       0x04, 0x3d, 0x78, 0xa8, 0x60, 0x2f, 0xad, 0x22, 0x56, 0x3c, 0x78, 0xd4,
+       0x93, 0x26, 0xbe, 0x37, 0x33, 0xaf, 0xdd, 0xdd, 0x66, 0x9b, 0x2a, 0x82,
+       0x18, 0x68, 0x3f, 0xde, 0xec, 0xbc, 0x37, 0x33, 0xdf, 0xcc, 0x9b, 0x79,
+       0x2e, 0x00, 0xe8, 0x50, 0xaa, 0xa6, 0x05, 0x82, 0xa5, 0x69, 0x96, 0x00,
+       0x0d, 0xe0, 0xae, 0x8d, 0x58, 0xea, 0x77, 0x05, 0xda, 0xda, 0x70, 0x46,
+       0x62, 0x04, 0x86, 0xbb, 0x25, 0xee, 0x87, 0x27, 0x99, 0xa4, 0xc0, 0x9f,
+       0x75, 0x28, 0xc9, 0xf5, 0xee, 0xca, 0xc3, 0x6a, 0x0c, 0xcf, 0x59, 0xed,
+       0x07, 0xfc, 0xbd, 0x8b, 0x10, 0x1e, 0xce, 0x59, 0x88, 0x25, 0x46, 0xe8,
+       0x73, 0x11, 0x96, 0x66, 0x2d, 0x34, 0x57, 0xea, 0xb3, 0x70, 0x1f, 0xe8,
+       0x24, 0x5f, 0x99, 0x4d, 0x88, 0xff, 0x29, 0x78, 0x5f, 0x90, 0x6b, 0x2b,
+       0x3a, 0x8d, 0x7a, 0x15, 0xde, 0x2f, 0xfe, 0x50, 0xff, 0xb8, 0xd8, 0x07,
+       0xfc, 0x53, 0xfb, 0x5c, 0x3c, 0xa7, 0x98, 0x93, 0x7e, 0xb5, 0x0b, 0x83,
+       0xca, 0x1f, 0x9b, 0xe2, 0x4b, 0x93, 0xb6, 0x89, 0xdf, 0xd7, 0x84, 0xdf,
+       0xca, 0x6e, 0x33, 0x7b, 0x41, 0x7f, 0x83, 0x76, 0xe5, 0x79, 0x86, 0xb0,
+       0xe7, 0xb7, 0x03, 0x20, 0xe5, 0xcb, 0xf5, 0x75, 0x79, 0x8f, 0xff, 0xfb,
+       0x6a, 0xaf, 0x3c, 0xaf, 0x05, 0xa0, 0x57, 0xea, 0x2d, 0xb1, 0x3f, 0x83,
+       0xb0, 0x4f, 0x4f, 0xe2, 0x77, 0x03, 0xf7, 0xef, 0x11, 0xe7, 0x4a, 0xec,
+       0x62, 0xec, 0x66, 0x1c, 0x67, 0xbc, 0xca, 0xb8, 0x8b, 0x71, 0x27, 0xe3,
+       0x0e, 0xc6, 0x76, 0xc6, 0x97, 0x8c, 0x2e, 0x63, 0x82, 0xd1, 0x61, 0x7c,
+       0xce, 0x68, 0x33, 0xc6, 0x18, 0x5f, 0x30, 0xbe, 0x62, 0xb4, 0x18, 0x6f,
+       0x30, 0x7e, 0x61, 0xfc, 0xaa, 0xfc, 0xd0, 0x08, 0x1f, 0xf1, 0xfa, 0x10,
+       0xaf, 0x8f, 0x30, 0x02, 0xf3, 0xa4, 0x05, 0x78, 0xba, 0xcf, 0x75, 0x24,
+       0x79, 0xe6, 0xef, 0x3d, 0x4a, 0x8f, 0xf3, 0x84, 0x3c, 0xdd, 0x63, 0xbd,
+       0xf6, 0xca, 0x42, 0xa0, 0xde, 0x32, 0x5b, 0xd6, 0x59, 0xaa, 0x41, 0xde,
+       0x12, 0x18, 0xcf, 0xc4, 0x48, 0x02, 0xed, 0x38, 0xad, 0x24, 0x57, 0x6e,
+       0x9d, 0x4c, 0x10, 0x9e, 0x8b, 0x12, 0x7e, 0x62, 0x3c, 0x1f, 0x23, 0x9c,
+       0x8c, 0x2b, 0x9e, 0xd5, 0x39, 0xca, 0x9f, 0x66, 0x7e, 0x84, 0xd9, 0x53,
+       0x7e, 0x35, 0xb3, 0x4b, 0x58, 0xd4, 0xfd, 0xf1, 0x5f, 0x1f, 0x20, 0x34,
+       0xf2, 0x44, 0xea, 0x9c, 0xdd, 0x26, 0xa0, 0x5e, 0x9f, 0xb7, 0x0d, 0xb9,
+       0x3e, 0x38, 0xff, 0x1a, 0xef, 0xc7, 0xe0, 0x5c, 0x95, 0xfd, 0x4b, 0x28,
+       0x9e, 0xe9, 0xde, 0x64, 0x81, 0xd6, 0xe3, 0xc8, 0xbb, 0xa8, 0xb0, 0x1e,
+       0xee, 0x03, 0x59, 0x7f, 0xbe, 0xa8, 0x6e, 0x23, 0x9c, 0x8f, 0x8b, 0x9c,
+       0x8f, 0xae, 0x90, 0x7c, 0x84, 0xdd, 0xa3, 0xcd, 0xf7, 0xf7, 0x4c, 0x26,
+       0xc8, 0x5b, 0xd8, 0x7d, 0x53, 0x7c, 0x93, 0xf4, 0x77, 0x79, 0xbc, 0xc0,
+       0x3c, 0x16, 0x89, 0xc7, 0xe4, 0xe7, 0x86, 0x3c, 0x65, 0x3c, 0x3c, 0xc9,
+       0x38, 0xf7, 0x86, 0xe4, 0x39, 0x2c, 0xbe, 0xdc, 0x1f, 0xe7, 0x39, 0xe0,
+       0x1f, 0x9c, 0xc5, 0xfe, 0xe4, 0x42, 0x71, 0x44, 0xf9, 0xeb, 0xe7, 0xb9,
+       0x93, 0xf2, 0x0d, 0xd3, 0x79, 0x29, 0xaf, 0x03, 0x3c, 0xd5, 0x71, 0x6d,
+       0x14, 0x34, 0x09, 0x56, 0x31, 0x4f, 0xfb, 0x1d, 0x5d, 0xe7, 0xf5, 0x76,
+       0xeb, 0x42, 0xe5, 0x5d, 0x62, 0x2b, 0x14, 0x26, 0x39, 0xce, 0x2c, 0xd9,
+       0xa3, 0x3a, 0x30, 0xb8, 0x0e, 0x86, 0xb8, 0x7f, 0x05, 0xf9, 0xb0, 0x2a,
+       0x0b, 0xb3, 0xde, 0x7b, 0x9d, 0x84, 0x62, 0x9e, 0xea, 0x6a, 0x73, 0x5e,
+       0xd5, 0xdc, 0x51, 0x7d, 0x09, 0xc5, 0x95, 0x52, 0xc4, 0x17, 0xef, 0x51,
+       0xc8, 0x79, 0x79, 0xd6, 0x1a, 0xd4, 0x47, 0x33, 0x3b, 0xbe, 0xf3, 0x1c,
+       0xc8, 0x35, 0xea, 0x37, 0x26, 0xc7, 0xd5, 0xcd, 0xf5, 0xdd, 0xb1, 0xa9,
+       0xbe, 0xd5, 0x7c, 0xfb, 0x7b, 0x75, 0xce, 0xf1, 0x9b, 0xa8, 0x97, 0x5a,
+       0x79, 0xe0, 0x9d, 0x67, 0x51, 0xcf, 0x3c, 0xa3, 0x6d, 0xa6, 0xf2, 0x3b,
+       0xed, 0x9d, 0x43, 0xb1, 0x90, 0x3c, 0x78, 0xe7, 0x57, 0x30, 0x5e, 0x7f,
+       0x3d, 0x52, 0x5e, 0xa3, 0x1c, 0xbf, 0xd6, 0xa4, 0x2f, 0xb7, 0xb1, 0xde,
+       0x8f, 0x5a, 0xb8, 0x1e, 0x9d, 0x5b, 0xe8, 0xf1, 0xf6, 0xf1, 0xef, 0x35,
+       0x9a, 0x07, 0xdf, 0x6a, 0x8a, 0xdf, 0xc7, 0x21, 0xfc, 0x0e, 0xfd, 0x53,
+       0x7e, 0x21, 0xc0, 0xef, 0x6a, 0x6d, 0x7b, 0xfc, 0x02, 0xc7, 0x0f, 0x21,
+       0xfc, 0xb6, 0x32, 0x0f, 0x6f, 0xb7, 0xe0, 0x4d, 0xea, 0xc5, 0x58, 0xef,
+       0x8d, 0x47, 0x0f, 0xfd, 0x1e, 0xa2, 0x7b, 0x65, 0x16, 0xd7, 0x02, 0xbc,
+       0xe5, 0x73, 0xf2, 0x7e, 0x5f, 0x82, 0x2a, 0xc7, 0xbf, 0xec, 0xe3, 0x21,
+       0x2e, 0xfc, 0x73, 0xd1, 0xfe, 0xed, 0xaa, 0xe2, 0x8b, 0x3e, 0x67, 0x72,
+       0x84, 0x8b, 0xa8, 0xef, 0x7a, 0x78, 0xf3, 0xbe, 0xaf, 0x5c, 0xb8, 0x55,
+       0x55, 0xfd, 0x4c, 0xf6, 0x15, 0x13, 0x06, 0x78, 0x4e, 0x4e, 0x70, 0xff,
+       0xfa, 0x10, 0xa5, 0x3e, 0x59, 0x1c, 0xc5, 0x3e, 0x03, 0x1d, 0xeb, 0xfd,
+       0x8c, 0xd6, 0x9d, 0x71, 0x7a, 0x47, 0x0e, 0x98, 0x36, 0xea, 0x75, 0xc6,
+       0x09, 0x3b, 0x62, 0x72, 0x5f, 0x12, 0x3e, 0x8e, 0xa1, 0x7a, 0x6e, 0xa3,
+       0x3f, 0x05, 0xfb, 0x12, 0xc7, 0x79, 0x40, 0xca, 0x3b, 0x02, 0xfd, 0x48,
+       0xe8, 0xf4, 0x92, 0x7f, 0x37, 0x81, 0xe3, 0x52, 0xfb, 0xd2, 0x92, 0xc7,
+       0xc5, 0x9a, 0xea, 0xe3, 0xd9, 0x11, 0xe9, 0x4f, 0x02, 0x1c, 0x93, 0xf2,
+       0x48, 0x28, 0xf4, 0x74, 0x53, 0x6e, 0x4b, 0x95, 0x75, 0x5a, 0x97, 0x2f,
+       0xe3, 0x31, 0x63, 0x65, 0x25, 0x2f, 0x60, 0x61, 0x8e, 0xdf, 0x79, 0x86,
+       0x72, 0xa7, 0x1a, 0x21, 0xb9, 0x39, 0xaa, 0xf8, 0x48, 0x60, 0x7c, 0x73,
+       0xc4, 0xc7, 0xe9, 0x6b, 0x84, 0xa7, 0xe0, 0x18, 0x62, 0x74, 0x63, 0x2e,
+       0x5b, 0x88, 0x10, 0xf7, 0xf6, 0xdf, 0x16, 0xe1, 0x1e, 0xf6, 0x4d, 0x4f,
+       0x7e, 0x82, 0x73, 0xb5, 0x59, 0x9e, 0xbc, 0x73, 0x5d, 0xe6, 0xa9, 0xd1,
+       0xfc, 0x8e, 0x73, 0x5d, 0x95, 0x9b, 0xd4, 0x9f, 0xea, 0x83, 0x25, 0xae,
+       0xfb, 0x46, 0xef, 0x1a, 0x89, 0x4e, 0xc8, 0xfc, 0x4f, 0xad, 0xfb, 0x95,
+       0x0e, 0x7d, 0x77, 0x91, 0xfe, 0xf6, 0xde, 0x5b, 0x6e, 0xc8, 0x1c, 0xfe,
+       0x1f, 0xde, 0x55, 0x5b, 0xbd, 0xa7, 0x1c, 0xe6, 0xf9, 0x04, 0xf3, 0x6c,
+       0x40, 0x4b, 0x04, 0x89, 0xb1, 0x8d, 0x29, 0x3c, 0x57, 0x2f, 0xd3, 0x58,
+       0xb7, 0x5b, 0x66, 0x70, 0xae, 0x3b, 0xf6, 0x0c, 0xe9, 0x19, 0x24, 0x4f,
+       0x2a, 0xbc, 0x32, 0x45, 0xef, 0x6c, 0x1d, 0x7e, 0x01, 0x50, 0xb6, 0x82,
+       0xa7, 0xd8, 0x0d, 0x00, 0x00, 0x00 };
 
 static u8 bnx2_rv2p_proc2[] = {
-/*     0x1f, 0x8b, 0x08, 0x08, 0x7e, 0xd1, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
-       0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
-                                                       0xcd, 0x58, 0x5b, 0x6c,
-       0x54, 0x55, 0x14, 0x3d, 0xf3, 0xe8, 0xcc, 0x9d, 0xe9, 0xed, 0x9d, 0xf2,
-       0xb2, 0x03, 0xad, 0x08, 0xe5, 0xd1, 0x56, 0x29, 0xe8, 0x54, 0xab, 0x18,
-       0x15, 0x2c, 0x5a, 0x8c, 0x26, 0x68, 0xf0, 0xf9, 0x63, 0x14, 0x04, 0xda,
-       0x9a, 0x56, 0x9b, 0x16, 0xfb, 0x81, 0xaf, 0x09, 0x14, 0x6a, 0x4c, 0x25,
-       0xd6, 0x08, 0xc5, 0x47, 0xa0, 0x11, 0x1f, 0x84, 0xf0, 0xd3, 0x1f, 0x3b,
-       0x8d, 0x7f, 0x0a, 0x24, 0x6a, 0x88, 0xc4, 0xa8, 0x9f, 0x24, 0x68, 0xa0,
-       0x21, 0x0a, 0x58, 0x8b, 0x63, 0x4c, 0xb4, 0xf5, 0xec, 0xbd, 0xf6, 0xb9,
-       0x73, 0xef, 0x6d, 0x8b, 0x1a, 0xf9, 0x70, 0x3e, 0xba, 0x7b, 0xce, 0xd9,
-       0x67, 0x3f, 0xd6, 0xde, 0x67, 0x9f, 0x7d, 0xae, 0x52, 0xfc, 0xbb, 0xb6,
-       0x94, 0xc9, 0x37, 0x83, 0x96, 0xfe, 0x1b, 0x51, 0x0f, 0x85, 0xd3, 0x3c,
-       0x8e, 0x2a, 0xa2, 0x49, 0xa5, 0xb2, 0x5e, 0xea, 0x08, 0x7d, 0x44, 0xe8,
-       0x70, 0x08, 0xf4, 0xb4, 0xd0, 0x77, 0x84, 0xfe, 0x2e, 0xf4, 0x80, 0xd0,
-       0x0f, 0x85, 0xea, 0x5f, 0xd6, 0xd6, 0x7f, 0xf4, 0xb0, 0x46, 0x89, 0x7e,
-       0x1b, 0xd3, 0x35, 0xb0, 0xe3, 0xc1, 0x05, 0xc4, 0x77, 0x61, 0xa2, 0xc0,
-       0x87, 0xf9, 0x53, 0x7d, 0xa0, 0xd7, 0x60, 0xd7, 0xe1, 0xec, 0x0a, 0xb3,
-       0x1f, 0x64, 0x43, 0x09, 0xe8, 0xc6, 0x08, 0xe8, 0xea, 0x65, 0x4c, 0x7a,
-       0x9f, 0x0a, 0x63, 0xdc, 0xb8, 0x94, 0xf6, 0x87, 0x55, 0x83, 0x22, 0x3f,
-       0x67, 0xaa, 0x68, 0x98, 0xc6, 0xf5, 0x56, 0x6c, 0x18, 0xeb, 0x8f, 0xa5,
-       0x40, 0x37, 0x25, 0x41, 0xcf, 0x08, 0xdd, 0x52, 0x2c, 0x7a, 0x6c, 0x31,
-       0xbf, 0x98, 0xf6, 0x25, 0x5c, 0x39, 0xc7, 0x6d, 0xe0, 0x96, 0x95, 0xfd,
-       0x4a, 0xc1, 0xce, 0x03, 0xb2, 0x3e, 0xa3, 0x0a, 0xb3, 0xaf, 0x6f, 0xc1,
-       0xb8, 0xfc, 0x20, 0xf9, 0xa7, 0xff, 0xcf, 0x62, 0x7e, 0xfa, 0xfd, 0xf8,
-       0x15, 0xf6, 0x83, 0x96, 0x2f, 0xa2, 0x75, 0x27, 0xd3, 0x3f, 0x88, 0xf1,
-       0xde, 0x25, 0x32, 0x1f, 0x36, 0xf8, 0x18, 0x79, 0x41, 0x5c, 0x99, 0x58,
-       0xc7, 0x2a, 0x7d, 0xf2, 0x2b, 0x15, 0xe4, 0x2f, 0xc8, 0x2e, 0x35, 0xf2,
-       0x81, 0xfb, 0xfa, 0x16, 0xb2, 0x73, 0x4c, 0xc7, 0x01, 0xb8, 0xcd, 0x0a,
-       0x95, 0xb2, 0xdc, 0x7d, 0x83, 0x5e, 0x3d, 0x51, 0xad, 0x07, 0xfa, 0x54,
-       0xa5, 0xc5, 0x20, 0x65, 0x97, 0x81, 0xaa, 0x5a, 0xbf, 0x1f, 0x7b, 0x97,
-       0x18, 0x7b, 0x30, 0x9e, 0x9d, 0x01, 0xdd, 0x23, 0xf4, 0xaa, 0x3a, 0x26,
-       0xcb, 0x7f, 0xb8, 0xc1, 0x62, 0x0c, 0xb2, 0xb5, 0xde, 0x7c, 0x38, 0x32,
-       0x61, 0xf0, 0x52, 0x8b, 0x40, 0xce, 0x2e, 0x21, 0x3e, 0x1d, 0x9c, 0x4a,
-       0xc8, 0x5d, 0xdf, 0x32, 0x55, 0x1e, 0x7d, 0x30, 0x45, 0x1e, 0x61, 0xff,
-       0xb7, 0x2b, 0x7c, 0xf9, 0xa4, 0xda, 0x25, 0x4f, 0x36, 0x22, 0x8f, 0xac,
-       0xa7, 0x3e, 0x91, 0x85, 0x6b, 0x13, 0xfa, 0xcf, 0x84, 0x7a, 0x32, 0x4e,
-       0x01, 0x8a, 0x2b, 0x87, 0xfd, 0x53, 0xe2, 0xe7, 0x26, 0xed, 0x27, 0xd1,
-       0x8a, 0x50, 0xb6, 0x36, 0xc1, 0x38, 0x35, 0xc4, 0xa0, 0xaf, 0x61, 0x03,
-       0xb6, 0xaf, 0x46, 0x5c, 0x7b, 0x4f, 0x86, 0x8d, 0xfd, 0x51, 0xfa, 0x3b,
-       0xd0, 0xb6, 0x9d, 0x47, 0x03, 0xd1, 0x1d, 0x4c, 0xed, 0x63, 0x95, 0x58,
-       0xee, 0x8a, 0xf0, 0x7a, 0x72, 0x97, 0xcc, 0xf7, 0xec, 0xf0, 0xdb, 0xfd,
-       0x02, 0xf2, 0xdb, 0x7e, 0x7e, 0x47, 0x88, 0xa8, 0x13, 0x73, 0xf9, 0x98,
-       0x3a, 0x3b, 0xb7, 0x13, 0xff, 0x55, 0x6a, 0xd7, 0x20, 0x29, 0x4e, 0xab,
-       0x0d, 0x6b, 0xb1, 0x6f, 0x77, 0x2c, 0xc5, 0xb8, 0x36, 0xad, 0x05, 0xfd,
-       0x1e, 0xf3, 0xf3, 0x9d, 0x1e, 0xe2, 0x2f, 0x9d, 0xe7, 0x0c, 0x71, 0x5e,
-       0xa9, 0x11, 0xce, 0xc7, 0x04, 0x65, 0x06, 0xff, 0xda, 0xaa, 0xc1, 0xdf,
-       0xbc, 0x99, 0x15, 0xbf, 0xd9, 0x9a, 0xe7, 0x3c, 0x18, 0xe8, 0x18, 0x26,
-       0x3f, 0xe7, 0xaa, 0x91, 0x4e, 0xa2, 0x51, 0xd5, 0xb0, 0x90, 0xf0, 0x5e,
-       0x15, 0x36, 0x71, 0x3a, 0x7f, 0x33, 0xcd, 0xcf, 0xd3, 0xeb, 0x26, 0x1e,
-       0x24, 0xd7, 0x92, 0x78, 0x45, 0x5d, 0x7c, 0xf2, 0x61, 0xf8, 0xdb, 0xcd,
-       0x76, 0x5f, 0x97, 0xec, 0xe6, 0xfc, 0x4a, 0xaa, 0x26, 0x8e, 0x7f, 0xd4,
-       0x6a, 0x1b, 0xc6, 0xfa, 0xf9, 0x8f, 0x8d, 0x5c, 0xd2, 0x53, 0x23, 0x75,
-       0x44, 0xb9, 0x72, 0xa2, 0x37, 0x83, 0xee, 0x34, 0x7a, 0xeb, 0x88, 0x6f,
-       0xb1, 0x42, 0xfe, 0x26, 0x26, 0xc9, 0x69, 0x03, 0xce, 0xf6, 0x33, 0xec,
-       0xf7, 0x35, 0xf6, 0x85, 0x3e, 0x63, 0x2f, 0xe6, 0x2f, 0xfa, 0xf4, 0x95,
-       0x7b, 0xf4, 0x11, 0x7f, 0x51, 0xf2, 0x02, 0xef, 0x9b, 0x63, 0x3d, 0x3b,
-       0xcc, 0xb8, 0x58, 0xcf, 0x0c, 0x41, 0xfe, 0xc5, 0x21, 0xe2, 0x9f, 0x23,
-       0x7a, 0xed, 0xff, 0x88, 0xe7, 0x9c, 0x30, 0xe4, 0x4c, 0x8f, 0x5f, 0xc1,
-       0x6f, 0xe3, 0x17, 0xcb, 0xb5, 0x47, 0x73, 0x69, 0xe6, 0x33, 0xf1, 0xe8,
-       0x0e, 0x73, 0x02, 0xa6, 0x1b, 0x16, 0xfa, 0x71, 0x33, 0xf6, 0x9c, 0xdf,
-       0xcc, 0x79, 0x3e, 0xd1, 0x26, 0x75, 0x40, 0x71, 0x9d, 0xb9, 0x5d, 0xe2,
-       0xa1, 0xf3, 0x3a, 0x04, 0xff, 0x46, 0x73, 0x2c, 0x3f, 0xd9, 0xc5, 0x79,
-       0xb9, 0xd2, 0x8e, 0xe6, 0x38, 0x5e, 0xd6, 0xd9, 0x21, 0x6c, 0x2b, 0xd4,
-       0x4f, 0xc8, 0x6b, 0xb6, 0x41, 0x9b, 0xa4, 0x8e, 0x9e, 0x15, 0xda, 0x6d,
-       0x33, 0x3e, 0xba, 0x8e, 0x59, 0x2c, 0x3f, 0x9b, 0x32, 0xf7, 0x0c, 0xd6,
-       0x9f, 0x16, 0x39, 0x3f, 0x0a, 0x55, 0x22, 0xa7, 0x55, 0xf6, 0x9f, 0xf3,
-       0xc9, 0x89, 0x04, 0xe4, 0x84, 0x94, 0xc1, 0xcd, 0x9c, 0xef, 0x5d, 0x52,
-       0xbf, 0xf7, 0xc5, 0xa6, 0xab, 0xb7, 0x7c, 0x0e, 0xdc, 0xba, 0x5a, 0x8e,
-       0x3a, 0x53, 0x1f, 0x0d, 0xb3, 0xbf, 0x03, 0xdd, 0x3b, 0x80, 0x53, 0x8f,
-       0xe0, 0x14, 0x07, 0x4e, 0xf3, 0x0a, 0xf5, 0x59, 0x14, 0xd4, 0x90, 0xfe,
-       0x53, 0x21, 0xe3, 0xc7, 0xbe, 0x98, 0xaf, 0xfe, 0xf6, 0x9a, 0xfa, 0x5b,
-       0xa8, 0xd3, 0xc4, 0xff, 0xb3, 0xa9, 0x6f, 0x5a, 0x9f, 0xd1, 0xff, 0x6f,
-       0xf5, 0x72, 0x9c, 0x92, 0xdd, 0x7d, 0x26, 0xce, 0x98, 0x2e, 0xd4, 0xd9,
-       0x22, 0x22, 0xcb, 0x46, 0x3a, 0x99, 0x5e, 0xdf, 0xbc, 0x15, 0xf3, 0x65,
-       0x7c, 0x4e, 0x6e, 0x09, 0x01, 0xaf, 0xa8, 0x3a, 0xde, 0x87, 0xba, 0xae,
-       0xe2, 0x2c, 0xaf, 0xe2, 0x28, 0xc7, 0x3f, 0xaa, 0xe5, 0x12, 0xdf, 0x67,
-       0xa1, 0x42, 0x3e, 0x7a, 0xfd, 0xd9, 0xad, 0xf3, 0x84, 0xec, 0x88, 0xe9,
-       0xbc, 0xa5, 0xb1, 0x3e, 0x47, 0xb6, 0xe4, 0xf9, 0x1a, 0xe6, 0xb3, 0xc7,
-       0x22, 0x34, 0xff, 0x80, 0xd5, 0xd3, 0x87, 0xf9, 0x9f, 0x1a, 0x69, 0xbc,
-       0xce, 0x7e, 0x0d, 0xe7, 0xcc, 0x7e, 0x0d, 0xf5, 0xcb, 0x2a, 0x3a, 0x88,
-       0xba, 0xd6, 0x78, 0x10, 0xf2, 0x71, 0x4f, 0x7b, 0xfd, 0xf2, 0xe2, 0x47,
-       0xe7, 0xe1, 0xb2, 0x38, 0xd9, 0xcf, 0x09, 0x4e, 0x97, 0x7c, 0xf1, 0x39,
-       0x6c, 0xe2, 0xd3, 0x1b, 0x93, 0xf3, 0xd2, 0x7c, 0x29, 0xe8, 0x17, 0xf1,
-       0x9d, 0x71, 0xef, 0x9d, 0xae, 0x95, 0xa0, 0xdd, 0x2b, 0xe5, 0x9c, 0xd6,
-       0xf9, 0xf3, 0x6b, 0x3e, 0xea, 0xf2, 0xb8, 0x7b, 0x4f, 0x20, 0xbf, 0xac,
-       0x9d, 0xf0, 0x4b, 0xbd, 0x28, 0x79, 0x3c, 0x2e, 0xf4, 0x65, 0xc9, 0xdf,
-       0x6d, 0xd2, 0xb7, 0x98, 0xfe, 0xe2, 0x0f, 0xcc, 0x3b, 0xfd, 0x6e, 0x5f,
-       0x60, 0xea, 0x36, 0x8d, 0x43, 0xca, 0x89, 0x13, 0x83, 0x36, 0xeb, 0x33,
-       0x24, 0x4a, 0xcf, 0x1a, 0xe0, 0x35, 0x52, 0x07, 0xbe, 0xdd, 0x91, 0xb0,
-       0x8c, 0x21, 0x6f, 0xac, 0xda, 0x77, 0x0f, 0xd7, 0x4f, 0xc6, 0x93, 0xe4,
-       0xc6, 0xdc, 0xfa, 0x24, 0x79, 0xaf, 0x26, 0x84, 0x96, 0x2f, 0xbe, 0x2c,
-       0xbe, 0x85, 0xfe, 0x64, 0xa9, 0x17, 0xdf, 0x97, 0x34, 0xbe, 0xbc, 0xaf,
-       0xbe, 0xf9, 0x12, 0xa6, 0x4b, 0x6f, 0x05, 0xed, 0xbb, 0x95, 0xe7, 0x17,
-       0xa3, 0xee, 0x11, 0x7e, 0x9c, 0x5f, 0xf5, 0x6f, 0x0c, 0x9a, 0x7e, 0x42,
-       0xf0, 0x08, 0xf4, 0x41, 0x65, 0x77, 0x80, 0xbe, 0x29, 0x74, 0xce, 0x2a,
-       0xd0, 0xbd, 0xab, 0xfc, 0x71, 0x88, 0xa5, 0x7c, 0x71, 0xac, 0x47, 0x1c,
-       0x8f, 0x4c, 0x04, 0xeb, 0x81, 0xc4, 0x4b, 0xc7, 0x27, 0x70, 0xbf, 0x1b,
-       0xfd, 0xe2, 0xce, 0xdf, 0xc5, 0xed, 0x4a, 0xc7, 0xab, 0x7b, 0x25, 0xee,
-       0x93, 0x0e, 0xe9, 0x4b, 0xc7, 0xdc, 0xfb, 0xe2, 0x9f, 0xc4, 0x31, 0x7e,
-       0x85, 0xe3, 0x78, 0xf7, 0xff, 0x2c, 0x8e, 0x9d, 0x12, 0xc7, 0x22, 0xb9,
-       0x57, 0x4d, 0xbf, 0xd9, 0x2e, 0x7d, 0x18, 0xf5, 0x8d, 0x7e, 0xbd, 0x4f,
-       0x70, 0x1f, 0x78, 0xb5, 0x5b, 0x8f, 0xe7, 0x33, 0x7f, 0x4e, 0xf6, 0x95,
-       0xca, 0xbe, 0x7b, 0x26, 0xed, 0x3b, 0xc5, 0xf5, 0xee, 0xf1, 0xf1, 0xc9,
-       0xef, 0x15, 0x9f, 0x9d, 0x59, 0x95, 0x02, 0xee, 0xa8, 0xe3, 0xb1, 0x29,
-       0xde, 0x37, 0x86, 0x1f, 0xf9, 0xb5, 0x36, 0x85, 0xba, 0x05, 0xfe, 0xb9,
-       0x9e, 0x7a, 0x4a, 0xe3, 0xfb, 0xc7, 0xa7, 0xef, 0x57, 0x8d, 0x3c, 0xc4,
-       0x6d, 0x43, 0xb8, 0x84, 0xf9, 0x4e, 0xb7, 0xf3, 0x7d, 0xe7, 0xfa, 0xb7,
-       0x9a, 0xfd, 0x3a, 0x2a, 0xfe, 0x55, 0x88, 0x7f, 0x7a, 0xb9, 0x96, 0xeb,
-       0xbe, 0x75, 0xba, 0xdd, 0xeb, 0xdf, 0x9d, 0x97, 0xd1, 0xf7, 0x4f, 0xfb,
-       0x63, 0xd1, 0x9b, 0x32, 0xfa, 0x49, 0x5e, 0xb9, 0xf4, 0x7d, 0xd4, 0x4f,
-       0x62, 0x7e, 0x72, 0x9f, 0x41, 0xfa, 0x5b, 0x34, 0x5e, 0x72, 0xdf, 0x70,
-       0x3e, 0x47, 0xac, 0xa3, 0x6c, 0x57, 0x5e, 0xf9, 0x71, 0x39, 0x23, 0x7c,
-       0x53, 0xc5, 0x8d, 0xd6, 0x8b, 0x64, 0x7d, 0x2a, 0xbf, 0xc5, 0x4e, 0x37,
-       0x1f, 0x64, 0x1f, 0xf3, 0x35, 0x0b, 0x5f, 0x34, 0x34, 0x39, 0xfe, 0x18,
-       0xe5, 0xab, 0x38, 0xaf, 0xf7, 0x6f, 0xcb, 0x11, 0x9f, 0x76, 0x9e, 0xf3,
-       0xf0, 0xfb, 0x80, 0x7d, 0xe9, 0x2b, 0x80, 0x23, 0xf1, 0xcd, 0x50, 0x4d,
-       0xce, 0x74, 0x78, 0xe1, 0xdd, 0x30, 0x9a, 0x33, 0x78, 0xdb, 0xec, 0xe7,
-       0x48, 0x27, 0xe9, 0x5f, 0x1d, 0xc0, 0x31, 0x2c, 0x38, 0x9e, 0x50, 0x7f,
-       0x9f, 0xf7, 0xc6, 0x0f, 0x6f, 0x5e, 0x8c, 0xff, 0x19, 0xcc, 0xe3, 0x87,
-       0xe5, 0x5d, 0xdd, 0x18, 0x03, 0xfd, 0x2e, 0x62, 0xec, 0x46, 0x5e, 0xdf,
-       0xc3, 0xe7, 0xb5, 0x4a, 0xf5, 0xf2, 0xbb, 0xc3, 0x52, 0x0d, 0x6b, 0xc9,
-       0xee, 0x94, 0xae, 0x7f, 0xc8, 0x77, 0x27, 0xee, 0xbd, 0xb7, 0x75, 0x0d,
-       0x4c, 0xc4, 0x69, 0x58, 0x31, 0x33, 0xc1, 0x82, 0xde, 0xf8, 0xe2, 0x4b,
-       0x5e, 0x7e, 0xaf, 0xbf, 0x18, 0xf3, 0x65, 0xf7, 0x91, 0x9c, 0x88, 0xda,
-       0x8b, 0xba, 0xfb, 0xee, 0x1e, 0xd0, 0xb7, 0xd5, 0xbd, 0xd8, 0x3f, 0x73,
-       0x3b, 0xd7, 0x51, 0xab, 0x4c, 0xf2, 0x2b, 0x0d, 0x5c, 0xd3, 0xa8, 0xc3,
-       0x13, 0x13, 0xaa, 0x04, 0xf7, 0x9a, 0x79, 0x07, 0xab, 0x1a, 0xd1, 0x8b,
-       0xfa, 0x68, 0x17, 0xde, 0xc1, 0x44, 0x8b, 0x83, 0x7d, 0x9f, 0x55, 0xe8,
-       0xaf, 0x08, 0x8f, 0xf7, 0x5d, 0x1c, 0xd3, 0xe1, 0x60, 0x5d, 0xf2, 0xfa,
-       0x15, 0x93, 0x73, 0xfd, 0xab, 0xfb, 0x6e, 0xee, 0xe1, 0x7e, 0x2a, 0x19,
-       0xac, 0xcb, 0x01, 0xf9, 0xfb, 0x24, 0x7e, 0x49, 0x89, 0x5f, 0x54, 0xc7,
-       0x0f, 0xef, 0xed, 0x4f, 0x7d, 0xef, 0x7a, 0xaa, 0x1b, 0xde, 0xbc, 0xfb,
-       0xfc, 0x4f, 0x63, 0xd7, 0xf6, 0x98, 0xb7, 0x0e, 0x57, 0xbb, 0xe7, 0xae,
-       0x43, 0xde, 0x8b, 0x5d, 0x87, 0x30, 0xce, 0x73, 0xbf, 0xbc, 0x38, 0xd3,
-       0x21, 0x79, 0x74, 0x57, 0x44, 0xf2, 0x41, 0xec, 0xfb, 0x22, 0x62, 0xee,
-       0x1b, 0x8c, 0xbf, 0x92, 0xfb, 0xee, 0x97, 0x2a, 0xf4, 0xd9, 0x17, 0x87,
-       0xcc, 0xfb, 0xc4, 0xbc, 0x57, 0xb0, 0xbe, 0x3e, 0xae, 0x04, 0x67, 0xbe,
-       0xff, 0xb5, 0x3f, 0x9c, 0xaf, 0x99, 0x8e, 0x61, 0x1f, 0x5e, 0x2a, 0x16,
-       0x78, 0xbf, 0xc4, 0xe5, 0xfb, 0x45, 0xbf, 0xe0, 0xe1, 0xf0, 0xf9, 0x29,
-       0xd5, 0xf6, 0x13, 0x4d, 0x65, 0x3a, 0x73, 0xb0, 0xa7, 0xd5, 0xed, 0x23,
-       0xc1, 0x27, 0xd4, 0x79, 0x4b, 0xde, 0xc1, 0xf2, 0x5e, 0xd6, 0xef, 0x61,
-       0xf4, 0x73, 0xad, 0x79, 0x8c, 0xc7, 0xd0, 0xb7, 0x39, 0xbf, 0xca, 0xbd,
-       0xb5, 0x75, 0x9b, 0xe9, 0x4b, 0xa7, 0xde, 0x67, 0xee, 0xb9, 0xb6, 0x6a,
-       0xd0, 0x16, 0xee, 0x5b, 0x1f, 0xb2, 0xf3, 0x92, 0x1f, 0x85, 0x77, 0x89,
-       0xff, 0x3d, 0x62, 0xfa, 0x85, 0x73, 0xc5, 0xb8, 0x67, 0xf3, 0xbd, 0x34,
-       0xa1, 0xdf, 0x23, 0x09, 0x6f, 0x9e, 0x25, 0x32, 0x65, 0x82, 0xfb, 0xec,
-       0x9b, 0x40, 0xf7, 0xdc, 0x84, 0xbe, 0xbc, 0xb5, 0x4b, 0x70, 0xb8, 0x91,
-       0x71, 0x5b, 0x3e, 0x9a, 0x0b, 0x7e, 0x67, 0x21, 0x5c, 0x7f, 0x73, 0xfb,
-       0xd1, 0x73, 0x6c, 0xd7, 0xbc, 0x81, 0x3c, 0xf3, 0xcd, 0x55, 0xb3, 0xf8,
-       0xfc, 0xa6, 0x9d, 0x51, 0xd8, 0x99, 0xe9, 0x17, 0xbf, 0xda, 0x6f, 0x01,
-       0xed, 0x92, 0x3a, 0x73, 0xd2, 0x7d, 0x97, 0xc3, 0x4e, 0x53, 0x4f, 0x26,
-       0xbf, 0x13, 0x30, 0x9e, 0x5b, 0xc7, 0x63, 0xd5, 0xbc, 0x95, 0xe4, 0x97,
-       0x4c, 0x7a, 0xcf, 0x16, 0xe2, 0x6e, 0xf2, 0xc1, 0xe4, 0x8f, 0xf7, 0x1d,
-       0x7b, 0x9b, 0xa7, 0x5e, 0xfa, 0xe3, 0xef, 0x70, 0xbe, 0x84, 0x65, 0x3d,
-       0x96, 0xe9, 0xef, 0xbb, 0x3c, 0x3e, 0x6f, 0x01, 0x9f, 0x8c, 0xd8, 0x6d,
-       0xb7, 0xf0, 0x3b, 0x74, 0x96, 0xda, 0x25, 0xf1, 0x39, 0x57, 0x2d, 0x75,
-       0x50, 0xec, 0xfb, 0x49, 0xfa, 0x1f, 0xc4, 0x31, 0x6e, 0x6f, 0xc9, 0x49,
-       0xdc, 0x24, 0x8f, 0x9e, 0x16, 0xbf, 0x7f, 0x84, 0xdf, 0xb6, 0xf1, 0xbb,
-       0xc5, 0xf5, 0xdb, 0xd4, 0x59, 0xaf, 0x9c, 0x99, 0x3a, 0x1f, 0xb8, 0x5e,
-       0xdb, 0x27, 0xf9, 0xdd, 0x53, 0x24, 0xe7, 0xa1, 0x42, 0xbe, 0x3b, 0x38,
-       0xe2, 0x4f, 0x89, 0x6a, 0x5a, 0xee, 0xdd, 0x57, 0x2c, 0xfb, 0x92, 0x7a,
-       0x1f, 0xe6, 0x71, 0xfe, 0xec, 0x29, 0xf0, 0x34, 0xdf, 0x11, 0x8c, 0xdc,
-       0xe0, 0x39, 0xf2, 0xe2, 0xc7, 0x37, 0x13, 0xff, 0x50, 0x07, 0x74, 0x9c,
-       0x6a, 0xcd, 0xf7, 0x07, 0xcc, 0xe3, 0xfc, 0x26, 0xf7, 0xb7, 0xa1, 0xaf,
-       0xdc, 0xdf, 0x76, 0x48, 0xfa, 0x08, 0xc1, 0xe5, 0x81, 0x21, 0xb2, 0x43,
-       0xc7, 0xae, 0xd2, 0x7f, 0xfe, 0x61, 0x47, 0x54, 0xec, 0x28, 0xf7, 0xd8,
-       0x11, 0xd0, 0x7b, 0x1d, 0xcd, 0xaf, 0x50, 0x5f, 0x73, 0x1e, 0x2e, 0x57,
-       0xeb, 0x29, 0x47, 0xf4, 0xbd, 0xb0, 0xae, 0x88, 0xc6, 0xcb, 0xd4, 0xab,
-       0xf0, 0xb7, 0x37, 0x59, 0x84, 0x3a, 0x96, 0xdc, 0x49, 0xf3, 0x35, 0xea,
-       0xd5, 0x3e, 0x0e, 0xc4, 0x2b, 0xea, 0x18, 0xea, 0x73, 0xe3, 0x41, 0xb6,
-       0x47, 0x1d, 0x1f, 0x34, 0xf5, 0x7a, 0xca, 0xef, 0x98, 0xbd, 0xeb, 0xa4,
-       0x5e, 0x9c, 0xc0, 0x77, 0x51, 0xfd, 0x5e, 0x23, 0xfe, 0xd9, 0xe6, 0x3d,
-       0xb8, 0xfb, 0x98, 0xa1, 0x8b, 0x7c, 0xe3, 0xfd, 0x27, 0x96, 0x0a, 0xad,
-       0xf2, 0x8d, 0x07, 0xd6, 0x55, 0x09, 0xad, 0x36, 0xe3, 0xe9, 0xbe, 0x2b,
-       0x5e, 0x29, 0xf9, 0x62, 0xf7, 0x7b, 0xe2, 0xcf, 0x47, 0xe2, 0xcf, 0x59,
-       0xe0, 0x9f, 0xdc, 0x28, 0x78, 0x2c, 0x0a, 0xea, 0x17, 0xbb, 0xdc, 0x73,
-       0x63, 0xd6, 0x11, 0x8f, 0x47, 0xd5, 0x5f, 0x3f, 0x97, 0x8f, 0x31, 0xd8,
-       0x17, 0x00, 0x00, 0x00 };
+       /* Date:        12/07/2007 14:57 */
+       0xed, 0x59, 0x5d, 0x6c, 0x54, 0xc7, 0x15, 0x9e, 0xbd, 0xbb, 0x7b, 0xf7,
+       0x7a, 0x7d, 0xf7, 0xae, 0x71, 0xa8, 0xff, 0xf9, 0xb3, 0x09, 0xd8, 0xa9,
+       0x21, 0xce, 0x9a, 0x98, 0x02, 0x55, 0x63, 0x39, 0x95, 0x81, 0xa6, 0x55,
+       0x0c, 0x49, 0x9b, 0xbe, 0x35, 0x76, 0x02, 0xb6, 0xa9, 0x4d, 0x2d, 0x43,
+       0x83, 0x4a, 0x1b, 0x65, 0x85, 0xd7, 0xf6, 0xcb, 0x26, 0xea, 0x22, 0xc0,
+       0x24, 0xaa, 0xa8, 0x1b, 0xa4, 0x28, 0xea, 0xdb, 0x56, 0x6a, 0x6d, 0xda,
+       0x97, 0xfe, 0x10, 0xb7, 0x4a, 0xa4, 0x42, 0xa5, 0xf6, 0xa1, 0x52, 0x85,
+       0x44, 0xda, 0x62, 0x99, 0xc4, 0x20, 0x63, 0xba, 0x79, 0x21, 0x75, 0x67,
+       0xce, 0x77, 0xe6, 0xee, 0xbd, 0xeb, 0xb5, 0x21, 0x2d, 0x8f, 0xdd, 0x07,
+       0x1f, 0x66, 0xee, 0x99, 0x33, 0xe7, 0xe7, 0x9b, 0x33, 0x67, 0x0e, 0x65,
+       0x42, 0x08, 0x43, 0x24, 0xb3, 0x1b, 0x24, 0x15, 0x56, 0x20, 0x20, 0xf0,
+       0x7b, 0xac, 0x8c, 0xc8, 0x9f, 0xb3, 0x96, 0xfc, 0x1b, 0x16, 0xcf, 0x1b,
+       0x55, 0x34, 0x0e, 0x09, 0x45, 0x1d, 0x21, 0x92, 0x5e, 0x5a, 0xce, 0xf4,
+       0x67, 0x4c, 0x77, 0x1b, 0xa0, 0x3d, 0x4c, 0xeb, 0x98, 0x9e, 0x64, 0xba,
+       0x91, 0xe9, 0x56, 0xa6, 0x27, 0x98, 0x7e, 0x8f, 0xe9, 0x07, 0x4c, 0x77,
+       0xb2, 0x3c, 0xf9, 0x4b, 0xda, 0xf2, 0x4f, 0x40, 0x24, 0x9b, 0xb4, 0x7e,
+       0x36, 0xa6, 0x9b, 0xa0, 0xe7, 0x73, 0x1b, 0x15, 0xdf, 0xcd, 0xa5, 0x3c,
+       0x1f, 0xe6, 0xaf, 0x65, 0x40, 0x37, 0x60, 0xd5, 0x4f, 0x93, 0x8f, 0xeb,
+       0xf5, 0x20, 0xdd, 0x31, 0xd0, 0x9e, 0x20, 0x68, 0x7b, 0x33, 0x91, 0xf4,
+       0x4b, 0x06, 0xc6, 0x9d, 0x5b, 0x2c, 0xb2, 0x2f, 0x64, 0x28, 0x39, 0xeb,
+       0x2d, 0xf3, 0x12, 0xe6, 0xbf, 0x19, 0x07, 0x7d, 0x39, 0x0a, 0xfa, 0x4f,
+       0xa6, 0x87, 0x4b, 0x59, 0xbe, 0xcd, 0x6a, 0x97, 0x62, 0xfd, 0x8c, 0xad,
+       0x68, 0x50, 0x24, 0x79, 0x9d, 0x10, 0xd0, 0xeb, 0xc7, 0x02, 0xdf, 0xd7,
+       0x6c, 0xc5, 0xec, 0x0f, 0x0f, 0x63, 0x5c, 0x7b, 0xb1, 0x8c, 0xf8, 0xcf,
+       0x67, 0xb5, 0xfe, 0x16, 0x79, 0x3f, 0x19, 0x87, 0x1c, 0x51, 0x6f, 0xd1,
+       0x26, 0xc9, 0x66, 0x50, 0xb1, 0x4d, 0xcb, 0xc3, 0xef, 0xdc, 0xa3, 0xda,
+       0x3f, 0x18, 0xaf, 0x4d, 0x80, 0x9e, 0x65, 0x5a, 0xd1, 0x4a, 0x64, 0xfb,
+       0xdf, 0x9f, 0xb0, 0x48, 0x97, 0xe4, 0x36, 0xaf, 0x1f, 0x7f, 0x23, 0xfd,
+       0xc8, 0x82, 0x1a, 0x40, 0x6e, 0x3c, 0xaa, 0xf8, 0xa4, 0x71, 0xf5, 0x90,
+       0x7b, 0xb0, 0xbf, 0x98, 0xff, 0x7f, 0xf9, 0x19, 0xfc, 0xaf, 0xe4, 0xb5,
+       0xb3, 0xfe, 0x1b, 0xa5, 0xfe, 0x8a, 0xd6, 0x05, 0x92, 0xdb, 0xfc, 0xfe,
+       0xb9, 0x96, 0x89, 0xd3, 0xbf, 0x6f, 0x76, 0x94, 0x91, 0xfd, 0xcf, 0x62,
+       0xfe, 0x74, 0xe7, 0x14, 0xfc, 0xb4, 0x9f, 0xe2, 0x22, 0xa2, 0xa9, 0x9f,
+       0x63, 0x55, 0x77, 0x4c, 0x8d, 0x5f, 0xd8, 0x71, 0x23, 0x8b, 0xef, 0xe1,
+       0x11, 0x35, 0x36, 0xe4, 0x3a, 0xfc, 0xf6, 0x07, 0x09, 0xe0, 0x69, 0x73,
+       0x84, 0x86, 0xf6, 0x0c, 0x7d, 0xb7, 0xc5, 0x78, 0x16, 0xdf, 0x8f, 0x96,
+       0xaa, 0xf1, 0xb3, 0xcd, 0x73, 0x18, 0x37, 0xf7, 0x8f, 0xf1, 0x42, 0xa3,
+       0x44, 0xfe, 0x59, 0x5a, 0xba, 0x69, 0x40, 0x1e, 0x87, 0x37, 0x1a, 0x32,
+       0xe2, 0x64, 0xaf, 0xdd, 0x09, 0x3a, 0x4a, 0xdf, 0xef, 0x05, 0xd2, 0x64,
+       0x77, 0xa7, 0x13, 0x9a, 0x02, 0x23, 0xe3, 0xca, 0xc5, 0x8d, 0xc6, 0xdd,
+       0x83, 0xe2, 0x67, 0xcc, 0xc5, 0x0f, 0xfb, 0xbf, 0x69, 0x25, 0xfc, 0x80,
+       0x76, 0x6e, 0x01, 0x35, 0x1b, 0x14, 0x5f, 0xb8, 0x08, 0x8e, 0xfc, 0x7e,
+       0xe6, 0xf8, 0x14, 0xe2, 0x44, 0xe2, 0x03, 0x63, 0xc6, 0x8b, 0xc4, 0x95,
+       0xe2, 0xaf, 0x96, 0xfe, 0xd2, 0xf1, 0x57, 0x82, 0x22, 0xe2, 0xdb, 0x2c,
+       0xaf, 0x9f, 0xed, 0x1a, 0x60, 0x7b, 0xe6, 0xa3, 0xda, 0xaf, 0xda, 0x1e,
+       0xd0, 0x71, 0x9f, 0x3d, 0x01, 0x89, 0x27, 0x8d, 0x23, 0x9f, 0x3e, 0xe9,
+       0xf7, 0xea, 0xf1, 0x8f, 0x5a, 0xc6, 0xa1, 0x6b, 0xe7, 0x16, 0xc5, 0x67,
+       0x26, 0x26, 0xb2, 0x7e, 0x1c, 0x6e, 0x10, 0x5a, 0x8e, 0x96, 0xaf, 0x70,
+       0x99, 0x93, 0xb8, 0x44, 0xdc, 0xce, 0x67, 0xbd, 0xe7, 0xa8, 0xa6, 0xc8,
+       0x39, 0xf2, 0x9f, 0x07, 0xed, 0x97, 0xa3, 0x31, 0x4a, 0x10, 0x3b, 0xae,
+       0xcc, 0xfa, 0xf7, 0x03, 0xbe, 0x23, 0x2e, 0x7e, 0xd6, 0xb6, 0xb1, 0xff,
+       0x98, 0x56, 0xec, 0x54, 0xf2, 0xba, 0x58, 0x7e, 0x0b, 0xcb, 0xb7, 0x0b,
+       0xce, 0xdb, 0x73, 0xee, 0x79, 0xd3, 0x71, 0xcb, 0x9f, 0x3b, 0xed, 0x3f,
+       0xda, 0xbf, 0xf9, 0xca, 0xac, 0x5a, 0x5f, 0x7b, 0x9f, 0x73, 0xb8, 0xbf,
+       0xc8, 0x39, 0x84, 0x9c, 0xbf, 0x3c, 0xee, 0xb7, 0x6b, 0x88, 0xf3, 0x5c,
+       0x0f, 0xe2, 0x66, 0xbd, 0xf4, 0x2b, 0xfe, 0xf0, 0x18, 0xe1, 0x5d, 0xbc,
+       0x18, 0x41, 0x7c, 0x1d, 0xd2, 0x5f, 0xb0, 0x1d, 0x2f, 0x7b, 0xce, 0x6b,
+       0x09, 0xf9, 0xb5, 0xc3, 0xc4, 0x7e, 0x1d, 0xdd, 0x58, 0xde, 0xce, 0x78,
+       0xc8, 0xf1, 0x79, 0x99, 0xb5, 0x49, 0xff, 0xe8, 0x9d, 0x53, 0x98, 0x1f,
+       0xdd, 0x43, 0x24, 0x7d, 0xd5, 0xd0, 0xf6, 0x86, 0xd4, 0xdf, 0xc9, 0x41,
+       0x7c, 0x9f, 0x0c, 0xf1, 0xf9, 0x7c, 0xaf, 0x9e, 0xd6, 0x5b, 0xf3, 0x19,
+       0xac, 0xcf, 0xb1, 0x7e, 0x27, 0x82, 0xc4, 0x1f, 0x1d, 0x63, 0xbe, 0xf1,
+       0x11, 0xbf, 0x9d, 0x3f, 0x40, 0x3e, 0xb7, 0xbf, 0x3f, 0x42, 0xe7, 0xdd,
+       0x31, 0x5d, 0x3e, 0xa2, 0xce, 0xe8, 0x29, 0xc5, 0x5f, 0x29, 0xc6, 0xb2,
+       0x4a, 0xd1, 0x2a, 0xd1, 0xbd, 0x17, 0xeb, 0xde, 0x30, 0x91, 0x6f, 0x7a,
+       0xf7, 0x82, 0x7e, 0x88, 0xf9, 0xf5, 0xce, 0xb8, 0xe2, 0x5f, 0x53, 0xe3,
+       0x4c, 0x29, 0x1a, 0x97, 0xf6, 0x28, 0xfb, 0xa5, 0xed, 0x8c, 0xcf, 0xc1,
+       0x46, 0xf0, 0xf7, 0x1d, 0xa2, 0x8d, 0xcf, 0x0c, 0xe4, 0x28, 0x5f, 0x4d,
+       0x0e, 0x5f, 0x52, 0x7e, 0xa9, 0x16, 0xb3, 0xc7, 0x14, 0x0d, 0x89, 0x8e,
+       0x4d, 0xec, 0x97, 0x3d, 0xfe, 0xfc, 0x3c, 0xbf, 0x53, 0x8d, 0x6b, 0x24,
+       0x9f, 0x17, 0xbf, 0x16, 0xc7, 0x39, 0xe4, 0xfa, 0xf5, 0x13, 0x03, 0x76,
+       0xa7, 0x48, 0xff, 0x3d, 0xd1, 0x14, 0x9d, 0xeb, 0x98, 0xe8, 0x25, 0x3c,
+       0x85, 0xac, 0xc1, 0x4b, 0xf8, 0x3e, 0xff, 0x0b, 0x2d, 0x57, 0xe1, 0x61,
+       0x17, 0xdf, 0x9f, 0xc2, 0x95, 0x13, 0xda, 0xc9, 0x71, 0xd0, 0xfb, 0xb6,
+       0xe2, 0xbe, 0xe9, 0x08, 0xa8, 0xf1, 0x3a, 0x39, 0xb6, 0x29, 0x6e, 0x1d,
+       0xdd, 0x6a, 0xbd, 0x4c, 0x02, 0x74, 0x7e, 0x1c, 0x29, 0x5f, 0xcd, 0x47,
+       0xa4, 0x1d, 0xfe, 0x7d, 0x06, 0x11, 0x0f, 0xfb, 0x28, 0xf9, 0xe7, 0xf3,
+       0xf6, 0xad, 0x8c, 0xb6, 0x07, 0xf3, 0xb7, 0x5d, 0x7d, 0x6c, 0xb2, 0xab,
+       0x63, 0x13, 0xf6, 0x9b, 0x75, 0x78, 0x9f, 0x4d, 0xbc, 0xef, 0x31, 0xb5,
+       0x5f, 0x83, 0x47, 0x5f, 0xc5, 0x67, 0x45, 0x6f, 0x91, 0xdc, 0x75, 0xd6,
+       0x77, 0x2e, 0x91, 0x7f, 0xad, 0xa3, 0x53, 0xd8, 0xff, 0xf6, 0xd4, 0x6a,
+       0x7a, 0xd7, 0xb0, 0x9c, 0x75, 0xec, 0xd7, 0xd8, 0x43, 0x8c, 0xdb, 0xea,
+       0x71, 0xca, 0xfb, 0x57, 0xfb, 0x87, 0xe4, 0xdb, 0x0b, 0xd3, 0xab, 0xe9,
+       0x2b, 0x6d, 0x4a, 0x82, 0x3f, 0x65, 0xd0, 0xc1, 0xa8, 0x82, 0x5f, 0xf2,
+       0x71, 0xd3, 0xfa, 0xce, 0x1f, 0xc2, 0x7d, 0x34, 0xe8, 0xe6, 0x0b, 0x25,
+       0xb7, 0x9d, 0xf1, 0x20, 0xe5, 0x05, 0xe0, 0x9f, 0x85, 0x69, 0x9c, 0x9b,
+       0x13, 0x74, 0x3e, 0xbe, 0x68, 0x87, 0x68, 0xff, 0xa8, 0x75, 0x83, 0xef,
+       0xa5, 0xfc, 0xfd, 0x03, 0x79, 0x7d, 0x36, 0x68, 0x2f, 0xe7, 0xe9, 0x1b,
+       0x4c, 0x53, 0xb6, 0x5a, 0x57, 0x2a, 0xf3, 0xad, 0x45, 0xf2, 0x91, 0x57,
+       0x4b, 0x5c, 0x7d, 0x8f, 0xb0, 0x9c, 0x8f, 0x98, 0x0a, 0x96, 0x33, 0xc0,
+       0xeb, 0xe7, 0x7c, 0x72, 0x0c, 0x8f, 0x1c, 0x7f, 0x3e, 0x1a, 0xe3, 0x7b,
+       0xef, 0xbc, 0xb9, 0x52, 0xbd, 0xa4, 0x68, 0xb9, 0x5c, 0x8f, 0x59, 0x7d,
+       0x2f, 0xa4, 0x1a, 0x89, 0xb4, 0x85, 0x0c, 0xb2, 0x77, 0x32, 0x35, 0x02,
+       0x3f, 0x8d, 0xb3, 0x9f, 0x22, 0xf0, 0x53, 0x4d, 0xfe, 0x9e, 0xe4, 0x8d,
+       0xf8, 0xfc, 0xcd, 0x6c, 0xf6, 0x9f, 0xc7, 0xf3, 0xa6, 0x8e, 0x2f, 0x91,
+       0x34, 0xf2, 0x90, 0xbe, 0x3f, 0xf5, 0xbd, 0x72, 0x4b, 0xe7, 0x6d, 0xb9,
+       0x6f, 0x81, 0x3e, 0x41, 0x8a, 0x73, 0x74, 0x9c, 0xf3, 0xd1, 0xd5, 0xa0,
+       0x8e, 0x27, 0xf4, 0x1b, 0xff, 0x8c, 0xfa, 0xe5, 0xef, 0xe5, 0xb0, 0x22,
+       0xcd, 0xb3, 0xc7, 0x88, 0xb6, 0xf4, 0x1d, 0xc7, 0x7c, 0x65, 0xab, 0xd2,
+       0xe7, 0x27, 0x01, 0x9c, 0xd3, 0xb0, 0x98, 0xc9, 0xe0, 0x9e, 0x13, 0x11,
+       0xd2, 0xa3, 0xee, 0x32, 0xe1, 0xc2, 0x8c, 0xa6, 0x32, 0x3e, 0x7f, 0x79,
+       0xec, 0x2e, 0x66, 0xef, 0x84, 0xc4, 0x93, 0xfa, 0x6e, 0xf2, 0x79, 0x95,
+       0x78, 0xb5, 0xf9, 0xbc, 0x3c, 0x4d, 0x7c, 0xf6, 0x22, 0xd9, 0xf9, 0x0d,
+       0x6b, 0x9c, 0xeb, 0xb4, 0x8f, 0x3b, 0xd5, 0xf8, 0x79, 0xfb, 0x75, 0x9c,
+       0x77, 0xfb, 0x75, 0xe4, 0x5b, 0x2b, 0x7c, 0x11, 0x79, 0xb8, 0xf3, 0xa2,
+       0x6f, 0xff, 0x74, 0xc8, 0xd0, 0xe7, 0xe7, 0x7f, 0xf2, 0x9b, 0xfd, 0x5d,
+       0xf6, 0xdb, 0xdd, 0xd5, 0xe3, 0x9a, 0x36, 0xf9, 0x1c, 0xf6, 0xdd, 0x2d,
+       0xb4, 0x57, 0xf9, 0xef, 0x43, 0xf7, 0x1e, 0x0e, 0xed, 0x62, 0x7d, 0x76,
+       0x71, 0x1e, 0xe0, 0xfa, 0x67, 0x7d, 0x50, 0xdf, 0x8b, 0x1a, 0x0f, 0x7c,
+       0x3f, 0x02, 0xa7, 0xd6, 0x28, 0xec, 0x15, 0xaf, 0xf2, 0x39, 0xf8, 0x37,
+       0xd3, 0xd7, 0x18, 0xff, 0x27, 0xb9, 0x3e, 0xd2, 0xf5, 0xdd, 0x3d, 0xcc,
+       0x3b, 0x13, 0x6e, 0x3d, 0xa4, 0xef, 0x1f, 0x35, 0x0e, 0x08, 0x27, 0x52,
+       0x4a, 0xfb, 0x25, 0x7f, 0x07, 0x80, 0x8d, 0x3f, 0x0d, 0x3f, 0xce, 0xb6,
+       0x82, 0xef, 0x0d, 0xf8, 0xc7, 0xd1, 0xfa, 0x2d, 0x36, 0xfa, 0xde, 0x01,
+       0x6d, 0xf0, 0xaf, 0xe9, 0xfa, 0x57, 0xe3, 0x73, 0x89, 0x69, 0xed, 0x66,
+       0xb6, 0xf3, 0xbf, 0xf3, 0xbb, 0xa7, 0x1e, 0x5b, 0xc9, 0xef, 0xb4, 0xbe,
+       0xad, 0xef, 0x2e, 0xe6, 0xcb, 0x76, 0x83, 0x66, 0x76, 0xd3, 0xfc, 0x66,
+       0xe4, 0xdb, 0x70, 0xdb, 0xe9, 0xfb, 0xd4, 0xa7, 0xfa, 0x5d, 0x53, 0xf9,
+       0x25, 0xd0, 0x33, 0x4c, 0x3f, 0xf7, 0x14, 0xe8, 0xb9, 0xa7, 0xfc, 0x79,
+       0xc4, 0x8c, 0xfb, 0xe2, 0xdb, 0x86, 0xf8, 0xbe, 0xe3, 0xc6, 0x77, 0x3d,
+       0xea, 0x03, 0x19, 0xaf, 0x55, 0xe3, 0xe9, 0xc6, 0xe9, 0x7e, 0xf1, 0x7c,
+       0xd8, 0x71, 0x4c, 0xed, 0xc2, 0x3d, 0x37, 0xcc, 0xef, 0xcd, 0x45, 0xf7,
+       0x9e, 0x2a, 0x16, 0xdf, 0xc8, 0xff, 0xe3, 0x4b, 0xf1, 0x3d, 0xb2, 0xa4,
+       0xf3, 0x1f, 0xee, 0x79, 0x5d, 0xd7, 0x0f, 0x79, 0xea, 0x7a, 0xff, 0xbe,
+       0xdf, 0xa2, 0x7a, 0x79, 0x34, 0xe0, 0xe2, 0x82, 0xf8, 0xa7, 0x79, 0x5d,
+       0x19, 0xaf, 0xdb, 0xb7, 0x6c, 0xdd, 0xb5, 0x8c, 0x5a, 0xf7, 0xb7, 0x4f,
+       0x97, 0xf7, 0x25, 0x7c, 0x7a, 0x26, 0x45, 0x1c, 0xf1, 0xc1, 0x7d, 0x61,
+       0x16, 0xe9, 0x63, 0xf8, 0x71, 0xb7, 0x37, 0x8e, 0x7c, 0xa8, 0xdf, 0x79,
+       0xfe, 0xba, 0xfe, 0x8f, 0x9f, 0xae, 0x5c, 0xd7, 0x6b, 0x79, 0x88, 0x5f,
+       0xb7, 0x11, 0x23, 0xbe, 0xeb, 0x43, 0x6a, 0x5d, 0xbf, 0x6b, 0x5f, 0x3b,
+       0xd9, 0x75, 0x99, 0xed, 0xab, 0x63, 0xfb, 0xe4, 0xe7, 0x6d, 0x74, 0x9f,
+       0x58, 0xd7, 0x87, 0xbc, 0xf6, 0xfd, 0x7a, 0x95, 0xfd, 0x1e, 0xf4, 0x1d,
+       0xc1, 0xfb, 0xc6, 0xf5, 0xfe, 0x4a, 0x5e, 0x2d, 0xd7, 0x63, 0x8e, 0xe0,
+       0xe7, 0x54, 0x91, 0xba, 0x46, 0xed, 0xff, 0x7b, 0xe9, 0x00, 0xbe, 0xc7,
+       0xe8, 0x1d, 0x11, 0xb4, 0x2e, 0x67, 0x8a, 0xf9, 0xe5, 0x6b, 0x01, 0xf0,
+       0x15, 0x8b, 0x9b, 0xfa, 0x1e, 0x66, 0x39, 0xc5, 0xec, 0x66, 0x3d, 0x5d,
+       0x3c, 0xf0, 0x3a, 0xe2, 0xeb, 0x63, 0xbe, 0x50, 0x91, 0xbe, 0x04, 0x46,
+       0xb9, 0xad, 0x54, 0x2f, 0x5e, 0x38, 0x39, 0xad, 0xf8, 0x62, 0xee, 0xbb,
+       0xcc, 0xaf, 0xdf, 0xc4, 0x43, 0xf0, 0x23, 0xbd, 0x3f, 0x44, 0xaf, 0xb3,
+       0x92, 0xbf, 0xf0, 0x7e, 0x5a, 0x98, 0xd6, 0xfe, 0xb6, 0xc9, 0x4e, 0xd4,
+       0xd3, 0x17, 0x0a, 0xfc, 0x68, 0x78, 0xfc, 0x08, 0xfe, 0x95, 0x71, 0xef,
+       0x7f, 0x97, 0x03, 0x17, 0xaf, 0x16, 0xc1, 0x3d, 0xf5, 0xf7, 0x1e, 0xd8,
+       0xce, 0x03, 0xad, 0x5e, 0xbb, 0x1a, 0xc4, 0x4c, 0x16, 0xf8, 0xef, 0x62,
+       0x9c, 0xbc, 0xc8, 0x79, 0xf6, 0x7a, 0x54, 0x4d, 0x58, 0xa2, 0xe7, 0x19,
+       0xe4, 0xe9, 0x8a, 0x52, 0xd8, 0xdd, 0xf3, 0x55, 0xed, 0x27, 0xcc, 0xd7,
+       0xc4, 0x50, 0x57, 0x77, 0x45, 0xf0, 0xbe, 0xa8, 0x89, 0x81, 0x56, 0x70,
+       0x9e, 0x9e, 0x71, 0xfb, 0x29, 0xa0, 0xf9, 0xfa, 0x12, 0x7d, 0xa5, 0xdf,
+       0x9a, 0xa8, 0xc3, 0x45, 0x13, 0xd7, 0xcf, 0x94, 0xef, 0x82, 0xe2, 0x60,
+       0x13, 0x70, 0x22, 0xea, 0xfd, 0x79, 0x8a, 0xf3, 0xec, 0xb2, 0x7a, 0x0d,
+       0x7d, 0x99, 0x12, 0x4f, 0x5f, 0x42, 0xef, 0xa7, 0xfd, 0xa8, 0xe5, 0xd2,
+       0x70, 0x85, 0xba, 0x72, 0x91, 0xf3, 0xd8, 0x23, 0xe2, 0x0f, 0x59, 0xd8,
+       0x35, 0x93, 0x2d, 0xc4, 0x95, 0xde, 0x4f, 0xcb, 0x83, 0xde, 0xda, 0x8e,
+       0xbc, 0x7c, 0xec, 0x7f, 0x88, 0xf5, 0xfc, 0x07, 0xf5, 0x33, 0x2b, 0xd8,
+       0x1e, 0x25, 0x17, 0xf3, 0xfb, 0xb8, 0x4f, 0x94, 0x74, 0xc7, 0xfe, 0xfe,
+       0x4e, 0x17, 0xe9, 0xb5, 0x86, 0x71, 0x54, 0xe1, 0xc1, 0x39, 0xf8, 0xd7,
+       0xb6, 0x80, 0x9e, 0x6d, 0xd1, 0x71, 0xd0, 0xf1, 0xd2, 0xf1, 0x41, 0x1c,
+       0x2b, 0xd0, 0x4f, 0xda, 0xd1, 0xf3, 0x04, 0xdd, 0x0f, 0x2d, 0x3d, 0x0b,
+       0xfa, 0xdc, 0x61, 0xfd, 0x81, 0x66, 0xc5, 0xff, 0x9a, 0xf8, 0x13, 0xf7,
+       0x1b, 0xfe, 0xca, 0xb4, 0xb0, 0x6f, 0x82, 0xbe, 0x8b, 0x8c, 0x5b, 0x98,
+       0x03, 0xd2, 0xaa, 0xf3, 0xac, 0xf7, 0x9d, 0xa0, 0xcf, 0xdf, 0xd6, 0x65,
+       0x78, 0xcd, 0xe7, 0x4b, 0x6d, 0x9f, 0xe2, 0x6f, 0x66, 0x1c, 0xca, 0xf7,
+       0xe9, 0x5e, 0xa5, 0x47, 0x5c, 0xde, 0xdb, 0xc8, 0xc7, 0x4e, 0xc4, 0x1b,
+       0x27, 0x89, 0x87, 0x92, 0x88, 0x1a, 0xd6, 0x95, 0x97, 0x90, 0x1d, 0xa7,
+       0xdf, 0xff, 0x80, 0x3e, 0xbf, 0x3d, 0x51, 0x8a, 0xf9, 0xca, 0x67, 0xe2,
+       0xe4, 0x87, 0x73, 0xc0, 0xf1, 0x8f, 0xce, 0x82, 0xbe, 0x25, 0xbe, 0x82,
+       0xf5, 0xe5, 0xa7, 0xe8, 0xfe, 0xb7, 0x2a, 0x19, 0x97, 0x55, 0x38, 0xf7,
+       0x69, 0xd4, 0x0f, 0x4b, 0x4b, 0x22, 0x86, 0xba, 0x4d, 0xdf, 0x03, 0xc0,
+       0x65, 0xc8, 0x13, 0xdf, 0xfb, 0xe1, 0x54, 0x51, 0xbb, 0xf0, 0x9d, 0x64,
+       0x15, 0xe2, 0x55, 0xfb, 0xa3, 0xca, 0x28, 0x8a, 0xcf, 0x36, 0x3f, 0x3e,
+       0x4d, 0xc6, 0xe7, 0x5d, 0xb7, 0x8e, 0x5a, 0x2e, 0x97, 0xde, 0x89, 0x12,
+       0xb7, 0x0f, 0x0b, 0xaf, 0xa0, 0xfb, 0x1a, 0xd4, 0xfe, 0x95, 0xcb, 0xf2,
+       0xeb, 0x06, 0x5f, 0x9c, 0x6f, 0xde, 0xd3, 0x7a, 0x9d, 0x32, 0xbd, 0xdf,
+       0x5b, 0xdc, 0x7b, 0x66, 0x98, 0xfb, 0xfc, 0x39, 0xf4, 0xa3, 0x12, 0xf3,
+       0x69, 0x1a, 0xda, 0xd5, 0xef, 0x52, 0xdf, 0x22, 0x31, 0xcc, 0xf9, 0xf3,
+       0xfd, 0xa0, 0xae, 0xb7, 0x30, 0xbe, 0xc2, 0x79, 0xe3, 0x0e, 0xeb, 0x75,
+       0x80, 0x61, 0x39, 0xdf, 0x48, 0x79, 0x37, 0xa1, 0xeb, 0xb4, 0x61, 0x7e,
+       0x5f, 0xe8, 0x3e, 0xd5, 0x97, 0x83, 0x9c, 0x4f, 0xc9, 0x8f, 0xa1, 0xc4,
+       0xed, 0x29, 0xdd, 0x4f, 0xd0, 0xfd, 0x05, 0xd6, 0x07, 0xfd, 0x30, 0x71,
+       0x30, 0x02, 0x2a, 0x9a, 0xfc, 0xf1, 0x11, 0xae, 0x9d, 0x18, 0x99, 0x05,
+       0xfd, 0x86, 0x08, 0xf7, 0x09, 0x27, 0x58, 0xbf, 0x33, 0xfc, 0xbe, 0x73,
+       0xc8, 0x4f, 0x65, 0xd2, 0x7e, 0xea, 0x5b, 0x25, 0x8e, 0x4d, 0xc3, 0xae,
+       0x01, 0xf7, 0xfd, 0x06, 0x3e, 0xa6, 0xce, 0x9b, 0xdc, 0x2f, 0xe3, 0xbe,
+       0x9a, 0x63, 0x8e, 0xc0, 0x9e, 0x81, 0x1c, 0xc6, 0x8b, 0x78, 0x17, 0x39,
+       0xff, 0xe2, 0x3a, 0xef, 0xf8, 0x49, 0xfd, 0x1e, 0x2c, 0xbe, 0x4e, 0xd7,
+       0x85, 0x83, 0xf4, 0x2e, 0x79, 0x61, 0x92, 0xfb, 0xea, 0xa2, 0x9f, 0xea,
+       0xd1, 0xaf, 0xdb, 0x39, 0x1e, 0xe7, 0xfb, 0x07, 0xfe, 0xbe, 0x81, 0xae,
+       0xbf, 0xe7, 0xd0, 0xff, 0x9c, 0xcc, 0xa5, 0x81, 0x97, 0x64, 0x89, 0x17,
+       0xe7, 0x25, 0x89, 0x4a, 0x8e, 0xdb, 0xda, 0x27, 0x41, 0xcf, 0x3e, 0x89,
+       0x77, 0xf2, 0xc0, 0x2b, 0xec, 0x97, 0x1d, 0x14, 0xa7, 0xed, 0xe8, 0xbf,
+       0x78, 0xeb, 0x50, 0x85, 0x9b, 0x4f, 0x5c, 0x3c, 0xcf, 0x91, 0x5e, 0xb5,
+       0x93, 0x39, 0xe2, 0xab, 0x11, 0x8f, 0xd0, 0xbd, 0x57, 0xed, 0x2c, 0x40,
+       0xcf, 0xc4, 0x04, 0xdb, 0x37, 0xf4, 0x05, 0xd0, 0x57, 0x38, 0xce, 0x3a,
+       0x7e, 0x57, 0xdd, 0x3e, 0x1e, 0xf4, 0xd5, 0xf7, 0xf1, 0xf2, 0xf7, 0x3b,
+       0xc6, 0xd5, 0xad, 0x48, 0x60, 0x7d, 0xc7, 0x8b, 0xf7, 0xa7, 0xfc, 0x78,
+       0x50, 0x78, 0xd1, 0xb8, 0xf4, 0xe2, 0xa8, 0xf0, 0x9c, 0xe5, 0x71, 0xe1,
+       0x34, 0x55, 0x91, 0xbf, 0x70, 0x9f, 0x98, 0x89, 0x89, 0xcc, 0xea, 0x7e,
+       0x7a, 0x13, 0x7e, 0x4a, 0xb0, 0xde, 0x76, 0xff, 0x08, 0xee, 0xa1, 0x31,
+       0x8e, 0xd3, 0x5c, 0x23, 0xd7, 0x11, 0xac, 0xdf, 0xc7, 0xfc, 0xce, 0x40,
+       0x3c, 0x23, 0xf6, 0xe1, 0x69, 0x8e, 0x1f, 0xe3, 0xea, 0x08, 0xdb, 0xfd,
+       0x11, 0xec, 0xb6, 0xb5, 0xdd, 0xfd, 0xae, 0xdd, 0xba, 0x4e, 0xf1, 0xca,
+       0x29, 0x97, 0xb8, 0xa0, 0x7a, 0xc7, 0xbe, 0x4a, 0x79, 0x24, 0xcc, 0x76,
+       0x4a, 0xbe, 0x56, 0xfd, 0xff, 0x8e, 0xf0, 0x57, 0xef, 0x76, 0xef, 0xba,
+       0x52, 0x5e, 0x17, 0x95, 0xeb, 0x30, 0x8f, 0xf3, 0x67, 0xaf, 0xe0, 0x4f,
+       0xe5, 0x37, 0x2d, 0xb7, 0xf0, 0x7c, 0x79, 0xfd, 0x47, 0x95, 0x1d, 0xfd,
+       0x90, 0x57, 0x64, 0x9c, 0xe8, 0x1e, 0xb2, 0xdd, 0xbc, 0x72, 0x87, 0xea,
+       0xc0, 0xe8, 0x85, 0x41, 0xe4, 0x81, 0x0b, 0x83, 0xef, 0x72, 0x1d, 0xce,
+       0x7e, 0xe9, 0xa2, 0xff, 0xaf, 0x92, 0xb1, 0xab, 0xf7, 0xe7, 0x15, 0xbf,
+       0x1e, 0xb5, 0x1e, 0x3d, 0xf4, 0xbe, 0xff, 0x01, 0xfe, 0xf0, 0x11, 0xdc,
+       0xa0, 0x1d, 0x00, 0x00, 0x00 };
 
 static u8 bnx2_TPAT_b06FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x08, 0x47, 0xd2, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
-       0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
-                                                       0xc5, 0x57, 0x4d, 0x68,
-       0x1c, 0xe7, 0x19, 0x7e, 0xe7, 0x77, 0x47, 0x62, 0x25, 0x8d, 0x93, 0x3d,
-       0xac, 0x5d, 0xa5, 0x99, 0x91, 0x46, 0x3f, 0x54, 0x26, 0x9e, 0x84, 0xa5,
-       0x56, 0x61, 0x20, 0xe3, 0x99, 0x95, 0x2c, 0x0c, 0x05, 0x07, 0x42, 0x08,
-       0xe4, 0xb2, 0x1d, 0x49, 0x36, 0x85, 0x1e, 0x5a, 0x9a, 0x43, 0xa0, 0x05,
-       0x0f, 0x33, 0xeb, 0x34, 0x87, 0xc5, 0xdb, 0xaa, 0xc5, 0xbe, 0x94, 0xd6,
-       0x95, 0xea, 0xe8, 0xb2, 0x68, 0xe2, 0x53, 0x0f, 0xc5, 0xd8, 0xb4, 0x54,
-       0xd0, 0x53, 0x7b, 0x0a, 0x85, 0x5c, 0x4c, 0x69, 0x20, 0x85, 0x12, 0x44,
-       0x0f, 0x21, 0xd4, 0xad, 0xa7, 0xcf, 0xfb, 0xcd, 0x8c, 0xbc, 0xbb, 0x95,
-       0x5b, 0x1f, 0x02, 0x15, 0xac, 0x66, 0xe6, 0xfb, 0xde, 0xf7, 0xfb, 0x79,
-       0x9f, 0xe7, 0x79, 0xbf, 0xf7, 0x6b, 0xca, 0x34, 0x49, 0xe5, 0xdf, 0x14,
-       0x7e, 0x6f, 0x7f, 0xe3, 0xdb, 0x6f, 0x7f, 0xf5, 0xa5, 0x57, 0x2c, 0xa2,
-       0x57, 0x5e, 0x92, 0x64, 0x5d, 0xa6, 0x2f, 0xe0, 0x4f, 0x21, 0x32, 0xab,
-       0xf1, 0xf9, 0x47, 0x86, 0xec, 0x75, 0xce, 0x04, 0x0e, 0x19, 0x8a, 0x77,
-       0x34, 0xbb, 0xe9, 0x10, 0xf9, 0x83, 0x15, 0x2b, 0xa4, 0x7f, 0xe5, 0x71,
-       0x43, 0x25, 0x6e, 0x7f, 0xc1, 0xfb, 0xe7, 0xb9, 0x7b, 0xe7, 0xed, 0xa3,
-       0xdb, 0x0a, 0x19, 0xa6, 0xd7, 0x31, 0xcc, 0x45, 0x32, 0x66, 0xe1, 0xf3,
-       0xd3, 0xa5, 0x75, 0x8d, 0xa6, 0xab, 0xb1, 0x4c, 0x4a, 0xfa, 0x06, 0xad,
-       0xf5, 0x30, 0x8e, 0xf3, 0x8e, 0x14, 0x66, 0xaa, 0x14, 0xde, 0x32, 0x48,
-       0xf6, 0x7c, 0x29, 0xc8, 0x1c, 0xf4, 0x49, 0x14, 0xb8, 0x35, 0xf2, 0xcd,
-       0x3c, 0xff, 0xa6, 0x2b, 0x93, 0xec, 0x3c, 0xce, 0xe7, 0x17, 0xd6, 0xa5,
-       0x60, 0x7f, 0x43, 0x0a, 0xf7, 0x03, 0xde, 0x37, 0xd6, 0xb1, 0x2e, 0xf9,
-       0xfb, 0xfc, 0xf4, 0x8c, 0xb0, 0x37, 0x4d, 0x9d, 0x06, 0xcd, 0xc8, 0x0e,
-       0xfb, 0x5a, 0x14, 0xba, 0x2b, 0x4d, 0x85, 0xe6, 0xf1, 0x9b, 0xa0, 0x6d,
-       0x97, 0xea, 0x81, 0x4b, 0xaa, 0xe2, 0xc8, 0x14, 0x36, 0x24, 0xfa, 0x65,
-       0x4b, 0xc3, 0xef, 0x92, 0xd4, 0xde, 0xdf, 0x2a, 0xc7, 0x69, 0x50, 0x8a,
-       0xb5, 0x44, 0x0d, 0x5e, 0x5b, 0xe1, 0x1f, 0xb8, 0x2b, 0xa6, 0x4c, 0xf3,
-       0xf8, 0x4d, 0xe1, 0x3d, 0x82, 0x9d, 0x46, 0x41, 0x6b, 0xbc, 0x6f, 0x02,
-       0xef, 0x58, 0x27, 0xc6, 0x0a, 0xc4, 0x3a, 0x2c, 0xac, 0xc3, 0xa1, 0x6e,
-       0x7f, 0x03, 0xfb, 0x58, 0x68, 0x46, 0xa4, 0x53, 0x57, 0xac, 0x7d, 0x8a,
-       0x12, 0x53, 0xa1, 0xe4, 0xac, 0x46, 0xfe, 0x65, 0x15, 0xdf, 0xcf, 0x51,
-       0x6c, 0x4a, 0xb0, 0xe9, 0x96, 0xf8, 0xd5, 0xd0, 0xaf, 0xa3, 0x7d, 0x86,
-       0x92, 0xc6, 0x29, 0x49, 0xf6, 0xbe, 0x8f, 0xf6, 0x05, 0x33, 0xa2, 0xef,
-       0xe1, 0x29, 0xe1, 0xfb, 0x14, 0x8f, 0x87, 0x6f, 0x89, 0x14, 0x87, 0xcc,
-       0x20, 0xb3, 0x28, 0xcd, 0x2a, 0x5f, 0x6e, 0x2f, 0xda, 0xe2, 0x6c, 0x1c,
-       0x3b, 0xd8, 0xf5, 0x5f, 0xa5, 0x8e, 0x49, 0xb1, 0xea, 0xc1, 0xa6, 0xef,
-       0x98, 0x6d, 0xe0, 0xe4, 0x0b, 0x3c, 0xbf, 0xc6, 0xed, 0xfc, 0x87, 0x76,
-       0x8b, 0x14, 0xcf, 0x31, 0x43, 0x6a, 0x51, 0xd1, 0xd7, 0x30, 0x83, 0x5b,
-       0x2f, 0x93, 0x2f, 0xe2, 0x61, 0xe0, 0xdd, 0xc4, 0x9e, 0x74, 0x60, 0x9b,
-       0xf8, 0x32, 0xc5, 0x4d, 0x83, 0xec, 0xd5, 0x2d, 0xf4, 0x7c, 0xdc, 0x53,
-       0x10, 0x67, 0xc6, 0x49, 0x2d, 0xfd, 0x18, 0xd7, 0xdf, 0x62, 0x5d, 0xb1,
-       0x69, 0xd0, 0x0c, 0x75, 0x5e, 0xcf, 0xf3, 0x3b, 0x6e, 0x9e, 0xeb, 0x9e,
-       0xb3, 0xfc, 0x3e, 0xad, 0x34, 0x35, 0x5a, 0x34, 0xf1, 0x44, 0xdc, 0x1c,
-       0xc4, 0x46, 0x2d, 0xe7, 0x9f, 0x2a, 0xd7, 0xfa, 0x48, 0x42, 0xe8, 0xe9,
-       0xcf, 0xbd, 0xdf, 0xf0, 0xde, 0x97, 0xd7, 0x85, 0x7d, 0x9e, 0xef, 0xae,
-       0x3e, 0xcd, 0x5e, 0x93, 0x0b, 0xfb, 0x3c, 0x5f, 0x6b, 0xf1, 0x7c, 0x36,
-       0xf6, 0xc6, 0x9c, 0x24, 0x5a, 0x1b, 0xb8, 0x46, 0xd4, 0xc3, 0xba, 0x1c,
-       0x3c, 0x07, 0x4d, 0xac, 0xdd, 0x5e, 0xb6, 0x24, 0x83, 0x12, 0x27, 0x7f,
-       0x11, 0x3c, 0xf0, 0x43, 0xc7, 0xfe, 0x53, 0xa8, 0xd4, 0x68, 0xcf, 0xad,
-       0x53, 0x37, 0x6b, 0x52, 0x92, 0x75, 0x29, 0xc8, 0x64, 0x8c, 0x5f, 0xa3,
-       0x5d, 0xe7, 0xf3, 0x7c, 0xcd, 0x75, 0x81, 0x33, 0xb1, 0x5f, 0x73, 0x8d,
-       0x66, 0xd1, 0xbf, 0x62, 0x6e, 0x91, 0x8b, 0x98, 0xcb, 0x88, 0xc9, 0xbc,
-       0x78, 0x4f, 0x32, 0x17, 0xfd, 0x14, 0xcb, 0x2d, 0xdb, 0x4c, 0xc8, 0x6e,
-       0x06, 0x0a, 0x99, 0xb2, 0x67, 0xc2, 0x26, 0xa6, 0x76, 0x66, 0xd0, 0x43,
-       0xe5, 0x1d, 0xc1, 0xe3, 0xb4, 0xff, 0x30, 0xbf, 0xb7, 0xd4, 0xa4, 0xfb,
-       0x59, 0x83, 0xee, 0x66, 0x24, 0x47, 0x1c, 0xab, 0x86, 0x49, 0x1f, 0x64,
-       0xd5, 0x3e, 0xc0, 0x65, 0x27, 0x39, 0xa3, 0x40, 0x67, 0x9b, 0xee, 0x03,
-       0xb0, 0xc4, 0x06, 0x0e, 0x31, 0xf6, 0x5c, 0x3d, 0x79, 0x4f, 0xb7, 0xcf,
-       0x6c, 0x3a, 0xf6, 0x7b, 0x21, 0xb3, 0xf3, 0x86, 0x8a, 0xd6, 0xe1, 0x38,
-       0x7c, 0x1d, 0xfe, 0x26, 0x5d, 0x87, 0x5e, 0x64, 0xc4, 0x63, 0xee, 0xc0,
-       0xa0, 0xfd, 0x5e, 0x8d, 0xac, 0x5d, 0x95, 0xa2, 0x7e, 0x83, 0xdc, 0x45,
-       0xdb, 0x22, 0x59, 0x6e, 0xc8, 0x88, 0xdf, 0xdc, 0x6e, 0x4e, 0xeb, 0xae,
-       0x46, 0x87, 0xce, 0x77, 0x75, 0x9a, 0x4e, 0x5c, 0x9d, 0xd8, 0xc6, 0xa0,
-       0xb9, 0xf7, 0x0d, 0x29, 0xec, 0xf3, 0xfa, 0x39, 0xce, 0x46, 0x19, 0x67,
-       0x55, 0x0a, 0x6e, 0xd5, 0x68, 0x7e, 0xe7, 0x6f, 0x79, 0xe0, 0x20, 0xc6,
-       0xe0, 0xf1, 0x66, 0xcb, 0x56, 0x68, 0x12, 0x6d, 0xbb, 0xdc, 0x77, 0x54,
-       0xb6, 0xf3, 0x18, 0x79, 0x1e, 0xb8, 0xcf, 0x53, 0xc0, 0xfc, 0x7e, 0x9d,
-       0x7d, 0x6a, 0x34, 0xb7, 0xc3, 0xba, 0xc0, 0x73, 0x97, 0xbf, 0x79, 0x6d,
-       0x13, 0x14, 0x61, 0x37, 0xd1, 0x72, 0x03, 0xfb, 0x97, 0x85, 0x06, 0x22,
-       0xec, 0x56, 0x76, 0x26, 0xf1, 0x14, 0x71, 0x50, 0x0a, 0x3e, 0x73, 0x5e,
-       0xa8, 0x53, 0x08, 0x5c, 0x55, 0xac, 0x67, 0x8b, 0x16, 0x9a, 0xdb, 0xa2,
-       0x0f, 0x6d, 0x03, 0xee, 0x33, 0xc7, 0xfa, 0xf0, 0x3d, 0xa8, 0xd6, 0x20,
-       0x03, 0xf3, 0x14, 0xb3, 0x68, 0x62, 0xaf, 0x6b, 0x2e, 0xdb, 0xb3, 0x6d,
-       0xbc, 0xac, 0x91, 0xbd, 0xbc, 0x8b, 0xd1, 0xf7, 0x7b, 0xd8, 0xef, 0x4d,
-       0xce, 0x35, 0x8e, 0xf5, 0x17, 0x62, 0xfb, 0x79, 0xec, 0x79, 0x61, 0x35,
-       0xe5, 0xbe, 0x81, 0x46, 0xce, 0x4e, 0x6c, 0xaa, 0x88, 0xbd, 0x8c, 0xc0,
-       0x87, 0x3f, 0xfc, 0x2c, 0xd7, 0x3c, 0x70, 0xb8, 0x35, 0x03, 0x6c, 0x6c,
-       0x2b, 0x85, 0x9e, 0x1d, 0x8c, 0x9b, 0xb8, 0x0a, 0xfc, 0x0a, 0x8c, 0xd8,
-       0x6e, 0xbd, 0x97, 0x53, 0x2a, 0xe6, 0xba, 0xc6, 0x73, 0x21, 0xe7, 0x38,
-       0xab, 0xbf, 0x03, 0x27, 0x22, 0xaa, 0xd3, 0xe2, 0x41, 0x9d, 0xae, 0x0e,
-       0xea, 0x34, 0x77, 0x43, 0x47, 0x1c, 0xf2, 0xbc, 0xdb, 0x62, 0x0d, 0x02,
-       0x6b, 0x87, 0xed, 0xec, 0xa6, 0x22, 0xf3, 0x3a, 0xd0, 0x7f, 0x40, 0xb4,
-       0x35, 0xd0, 0x11, 0x37, 0x75, 0x68, 0x6c, 0x99, 0x2e, 0xfe, 0x84, 0xe8,
-       0xe2, 0x80, 0x7d, 0x79, 0xfc, 0xc2, 0x27, 0xc2, 0x9e, 0x65, 0x60, 0x7e,
-       0x75, 0x20, 0x23, 0x1f, 0x20, 0x5f, 0xee, 0x07, 0xc8, 0x83, 0x6d, 0xfc,
-       0xd6, 0x91, 0x1b, 0x19, 0x1b, 0xce, 0x13, 0x8f, 0x81, 0xcf, 0x06, 0xfa,
-       0x2e, 0xa1, 0x8d, 0xf3, 0x16, 0xdb, 0xea, 0xd4, 0x76, 0xa7, 0x28, 0xad,
-       0x72, 0x91, 0xc9, 0xb9, 0xe8, 0x14, 0xf8, 0x34, 0x81, 0xfc, 0x72, 0x47,
-       0x19, 0xcd, 0x45, 0xc8, 0x59, 0x8d, 0xd3, 0xc8, 0x3d, 0x3f, 0x47, 0x3b,
-       0x8f, 0xf7, 0x33, 0x3c, 0x27, 0xf0, 0x7d, 0x1a, 0xb6, 0xc3, 0x79, 0xa8,
-       0xf2, 0x7b, 0x5a, 0x0e, 0x02, 0xef, 0x76, 0x0c, 0xd8, 0x5b, 0xd0, 0x0b,
-       0xc7, 0xbb, 0x86, 0x7c, 0xc1, 0x31, 0xaf, 0x21, 0xa6, 0x3a, 0xe6, 0x36,
-       0x69, 0xfe, 0x80, 0x62, 0xa5, 0xcc, 0x4f, 0xe1, 0x71, 0x7e, 0x6a, 0x0a,
-       0x1e, 0x24, 0x99, 0x09, 0x1f, 0xd6, 0x6d, 0xa5, 0x53, 0xc6, 0x8e, 0xfc,
-       0x00, 0x1a, 0x0e, 0x94, 0x3c, 0xdf, 0xc4, 0x19, 0x11, 0x01, 0x77, 0x1f,
-       0xda, 0x8d, 0xa0, 0xdd, 0x70, 0x48, 0xbb, 0xe1, 0xff, 0xd4, 0x2e, 0x74,
-       0x09, 0x8d, 0xdc, 0x05, 0xa7, 0x3e, 0xe8, 0x9f, 0xa4, 0x63, 0xd6, 0x30,
-       0x6b, 0xd9, 0xa2, 0x7b, 0x4b, 0xcf, 0xa2, 0xe5, 0xbf, 0x3e, 0xab, 0x96,
-       0x63, 0xd6, 0xb2, 0xca, 0x5a, 0x6e, 0x0c, 0x6b, 0xf9, 0x53, 0xf8, 0x17,
-       0x9a, 0xbc, 0xa0, 0x36, 0x48, 0x5b, 0x04, 0x0e, 0x3b, 0x75, 0x52, 0x6e,
-       0x3c, 0xe1, 0x1b, 0x73, 0x38, 0x1c, 0xe0, 0xdf, 0x81, 0x86, 0x3e, 0x69,
-       0xb4, 0x1d, 0x39, 0x4f, 0xf5, 0xec, 0xe6, 0x96, 0xb0, 0x51, 0x49, 0x47,
-       0xdc, 0xbf, 0xb3, 0x64, 0x5b, 0x96, 0x3c, 0xac, 0x79, 0xa8, 0x7e, 0x27,
-       0xbf, 0xa6, 0x79, 0x3c, 0x4f, 0x6c, 0x81, 0xeb, 0xd6, 0x8f, 0x80, 0x51,
-       0xda, 0x63, 0x9e, 0x3b, 0xe6, 0x9a, 0xe0, 0x17, 0xbe, 0xa1, 0x05, 0x0d,
-       0x7c, 0xad, 0xc1, 0x4e, 0xdd, 0x29, 0xf4, 0x73, 0x17, 0xe3, 0xee, 0xf5,
-       0x98, 0x5f, 0x06, 0xe9, 0x37, 0x9d, 0xe6, 0x55, 0x91, 0x73, 0xe7, 0xcd,
-       0x75, 0x62, 0xed, 0xf1, 0x79, 0x87, 0xfe, 0x41, 0x8d, 0x14, 0xa1, 0xf7,
-       0xc9, 0x52, 0xef, 0x2f, 0x20, 0x46, 0x93, 0xf8, 0x66, 0xcd, 0x9f, 0x2e,
-       0x35, 0x3f, 0x8d, 0x27, 0xb7, 0x5d, 0x54, 0x0b, 0xee, 0x80, 0x87, 0x3b,
-       0x8c, 0x6b, 0x1d, 0xf9, 0x8d, 0xe7, 0xff, 0x7b, 0xbe, 0xe9, 0x30, 0xb6,
-       0x8e, 0xf5, 0x03, 0x5a, 0x80, 0xee, 0xd0, 0x7e, 0xc0, 0xb6, 0xec, 0x53,
-       0xd9, 0x9a, 0xa5, 0xed, 0xa7, 0x63, 0xb6, 0x68, 0x3f, 0x60, 0x3b, 0xd6,
-       0xc5, 0x73, 0xa4, 0xdc, 0xe4, 0xf3, 0x38, 0x60, 0x5d, 0xc0, 0xaf, 0x8d,
-       0x36, 0xae, 0x19, 0xd8, 0x9f, 0xcf, 0x66, 0x5e, 0x27, 0xd7, 0x13, 0x7c,
-       0x7e, 0x8f, 0x9d, 0xd3, 0xc7, 0xda, 0xb8, 0x00, 0xbe, 0x7f, 0x4b, 0xfd,
-       0x4f, 0x6d, 0xbc, 0x06, 0x2d, 0x5c, 0x51, 0x0b, 0x6d, 0x6c, 0xe3, 0x79,
-       0x01, 0xdf, 0xaf, 0x8d, 0x69, 0xa3, 0xf2, 0x7b, 0xfa, 0xf9, 0x9c, 0xf4,
-       0x9b, 0xe2, 0x6c, 0xe5, 0xf9, 0x94, 0x1d, 0x8a, 0xb5, 0x52, 0x07, 0x6b,
-       0xc7, 0x3a, 0x98, 0x44, 0xae, 0x18, 0xe1, 0xb8, 0x12, 0xba, 0xb6, 0x99,
-       0x12, 0x6b, 0x62, 0xf8, 0xfc, 0xfa, 0x7f, 0xe9, 0x82, 0xc0, 0x23, 0x31,
-       0x37, 0x6a, 0x0c, 0x3e, 0x0f, 0xf2, 0xfc, 0x8a, 0x8b, 0xfe, 0xaa, 0xd6,
-       0x10, 0xd8, 0xf3, 0x59, 0xcb, 0x78, 0xa0, 0xbe, 0x73, 0xe6, 0xa1, 0x05,
-       0xce, 0x01, 0x8f, 0xf3, 0x3d, 0x27, 0x40, 0x5b, 0x1b, 0xf1, 0x67, 0x4c,
-       0x36, 0xa4, 0xf5, 0x7d, 0x83, 0xfd, 0xa0, 0xb3, 0x93, 0x6a, 0x2c, 0x1d,
-       0x9a, 0x7a, 0x82, 0x13, 0xf3, 0x28, 0x1a, 0xc2, 0xa9, 0x23, 0x70, 0xfa,
-       0xf0, 0x18, 0xa7, 0xa8, 0xc4, 0x29, 0x12, 0x38, 0xfd, 0xb1, 0xc4, 0xe9,
-       0x0f, 0x4f, 0xc1, 0xe9, 0xc3, 0x67, 0xc0, 0xc9, 0xa0, 0x3d, 0xa7, 0x89,
-       0x73, 0x56, 0x17, 0x35, 0xe9, 0xa1, 0x7b, 0x52, 0x4d, 0x75, 0x52, 0xdc,
-       0x6d, 0x73, 0x8f, 0x86, 0xeb, 0x0e, 0xdb, 0x7a, 0x80, 0xf5, 0xa5, 0xc0,
-       0xee, 0xfa, 0x58, 0xed, 0x91, 0xc0, 0xbe, 0x5d, 0xe2, 0x74, 0x1d, 0x38,
-       0xb5, 0x4b, 0x9c, 0xb6, 0x87, 0x70, 0xda, 0x1e, 0xc1, 0x89, 0xf3, 0x49,
-       0xcb, 0xd8, 0xee, 0x55, 0x18, 0x55, 0xf8, 0xe8, 0x74, 0xdb, 0x9c, 0xc6,
-       0xfe, 0xcf, 0x51, 0xfa, 0x63, 0x95, 0xeb, 0x5a, 0x60, 0xf7, 0xaa, 0x2a,
-       0x8b, 0xf3, 0x80, 0xdf, 0x9f, 0xd4, 0x27, 0x98, 0xcb, 0x0f, 0x5c, 0x8e,
-       0x23, 0xea, 0x57, 0xa7, 0xca, 0x43, 0xcf, 0xab, 0xa8, 0xad, 0xf0, 0xcd,
-       0x36, 0xaa, 0xd4, 0x86, 0xde, 0x15, 0xd4, 0xe5, 0xe1, 0x71, 0x5d, 0x5e,
-       0xc4, 0xe0, 0x7a, 0x59, 0x97, 0xef, 0x39, 0x5c, 0x97, 0x2f, 0x6a, 0x34,
-       0xb9, 0x51, 0x62, 0xc9, 0x9c, 0x9e, 0x42, 0xdf, 0x25, 0x81, 0x79, 0x8a,
-       0xfc, 0xbd, 0x89, 0xfd, 0x47, 0x82, 0x9b, 0xa8, 0xb1, 0x4a, 0xde, 0xa2,
-       0x86, 0xa5, 0x30, 0x2b, 0x62, 0xf5, 0xc5, 0xd6, 0x5d, 0x9f, 0x20, 0x4f,
-       0x1b, 0x1d, 0x15, 0x75, 0xfd, 0xfd, 0x8c, 0xf3, 0x33, 0x5d, 0x4e, 0x7a,
-       0x14, 0x9f, 0xf1, 0xae, 0xe5, 0xc0, 0xdc, 0x7f, 0xeb, 0x3c, 0x9f, 0x33,
-       0xf5, 0xd5, 0xa0, 0x85, 0xf6, 0x81, 0x41, 0xa8, 0x7d, 0x70, 0x4f, 0xa1,
-       0x38, 0x38, 0x2f, 0xa1, 0xc6, 0xc1, 0x37, 0x7c, 0x92, 0x6c, 0xb6, 0x23,
-       0x7b, 0x4d, 0x70, 0x21, 0x26, 0x1f, 0xeb, 0xf4, 0x33, 0x71, 0x57, 0xe9,
-       0x28, 0x9e, 0x81, 0xda, 0x92, 0x0c, 0x9c, 0xf3, 0x88, 0x89, 0x65, 0xa4,
-       0x03, 0xd4, 0x41, 0x38, 0xfb, 0x83, 0x55, 0xc4, 0xe5, 0x2c, 0x70, 0xcb,
-       0x54, 0xf8, 0xbe, 0xa9, 0x17, 0xf7, 0x1c, 0x54, 0x35, 0x22, 0x5e, 0x8f,
-       0x4a, 0x7e, 0x88, 0x3a, 0x4b, 0x6a, 0xf7, 0xc9, 0x8a, 0x5c, 0xf0, 0x1c,
-       0xe7, 0x48, 0x37, 0xe3, 0xda, 0xf9, 0xac, 0x21, 0xdf, 0xe0, 0x5c, 0x7e,
-       0x88, 0x18, 0xe2, 0xfd, 0x80, 0xcf, 0x16, 0x85, 0xeb, 0x6f, 0xdc, 0x67,
-       0x96, 0x90, 0x6b, 0x68, 0x0a, 0x79, 0x0f, 0x79, 0x77, 0x96, 0x71, 0xf2,
-       0x23, 0xc6, 0x4b, 0x9c, 0x1b, 0xe7, 0xe4, 0x62, 0x9e, 0x5f, 0x6b, 0x05,
-       0x7f, 0x71, 0x87, 0x41, 0xfc, 0x36, 0xfb, 0x2e, 0xe7, 0xdb, 0x2f, 0x2b,
-       0x74, 0x44, 0x82, 0x8f, 0xe6, 0xcb, 0xc8, 0xc3, 0xe7, 0xe0, 0xe3, 0x0b,
-       0x2d, 0x16, 0xf5, 0x56, 0xe5, 0xf3, 0xc9, 0xd8, 0x18, 0x1f, 0x29, 0xa3,
-       0xdf, 0x3e, 0xf8, 0xbc, 0x52, 0xce, 0x57, 0xf1, 0xe3, 0x57, 0xe0, 0xc7,
-       0x61, 0xd9, 0xcf, 0x77, 0x16, 0x1d, 0x36, 0xbc, 0x3e, 0xe6, 0x11, 0xdb,
-       0x9b, 0xda, 0xe8, 0x18, 0x5f, 0x1a, 0xf3, 0xff, 0xfd, 0x90, 0xff, 0x34,
-       0xef, 0xc9, 0x8c, 0x0a, 0x0e, 0xe2, 0xef, 0x3d, 0x7d, 0xd4, 0xf7, 0x17,
-       0x6a, 0xf1, 0x7d, 0xb6, 0xe0, 0x9e, 0x83, 0x67, 0x76, 0x38, 0xb4, 0x36,
-       0x75, 0x6c, 0xec, 0x87, 0x18, 0x7b, 0x15, 0x79, 0x84, 0x7c, 0x05, 0x77,
-       0xa6, 0x90, 0xf0, 0x9e, 0x5d, 0xa9, 0xe2, 0x03, 0x4e, 0xd0, 0xe5, 0xb4,
-       0xe4, 0x82, 0x5c, 0x70, 0x81, 0xeb, 0xb4, 0xd5, 0x4d, 0x70, 0x21, 0x05,
-       0x17, 0xe0, 0xd7, 0xd1, 0xbc, 0x59, 0xe0, 0xcc, 0x39, 0x07, 0xdf, 0x19,
-       0xf3, 0x82, 0x79, 0xc0, 0x9c, 0x78, 0xc2, 0x85, 0x2b, 0x3d, 0xc3, 0xd8,
-       0xfd, 0x2f, 0x3c, 0x78, 0x57, 0xf0, 0x80, 0xf9, 0x58, 0xe4, 0x85, 0x2e,
-       0x70, 0x48, 0xca, 0xbc, 0x50, 0xe8, 0x9c, 0xeb, 0x1b, 0xd6, 0x78, 0xa1,
-       0x8d, 0x2d, 0x68, 0xa3, 0xad, 0x70, 0xbd, 0xc3, 0xba, 0x60, 0x3f, 0xd6,
-       0xc6, 0x49, 0x7e, 0x85, 0x46, 0xd2, 0xbe, 0x6d, 0x55, 0xf9, 0x21, 0x85,
-       0x2e, 0xba, 0xa5, 0x46, 0xd2, 0x52, 0x23, 0xb0, 0x89, 0x95, 0x16, 0xe7,
-       0x7a, 0xdb, 0x0a, 0x91, 0x17, 0xba, 0x62, 0xcc, 0x98, 0x8a, 0x3b, 0x09,
-       0xeb, 0x96, 0xf3, 0xe9, 0x50, 0x1e, 0x2d, 0xef, 0xa5, 0x1d, 0x71, 0x2f,
-       0xfd, 0x8a, 0x3e, 0x9a, 0x47, 0x67, 0x90, 0x43, 0xf8, 0x5e, 0x3a, 0xa7,
-       0xf3, 0xbd, 0x14, 0xba, 0xd3, 0x87, 0xef, 0xa5, 0xc9, 0xc8, 0xbd, 0xb4,
-       0xf2, 0xe5, 0xf6, 0x93, 0xf2, 0x69, 0x15, 0x13, 0xce, 0xa9, 0x02, 0xf3,
-       0x13, 0x6a, 0xbf, 0xca, 0x86, 0xf3, 0x0d, 0x6b, 0xb9, 0xcc, 0x51, 0xa8,
-       0xb5, 0xee, 0x67, 0x15, 0xe7, 0xdf, 0xc0, 0x3c, 0xf8, 0xee, 0x9f, 0xc4,
-       0x79, 0xa3, 0xe4, 0xfc, 0x54, 0xe1, 0xd3, 0x1f, 0xe6, 0xfd, 0x1b, 0xfa,
-       0x28, 0xef, 0xab, 0x71, 0x2a, 0xde, 0x17, 0x63, 0x3e, 0x54, 0x9a, 0x38,
-       0xdb, 0x96, 0x91, 0x6b, 0x66, 0xf8, 0xbe, 0x85, 0x5c, 0xe0, 0xd5, 0x71,
-       0xef, 0x98, 0xe1, 0xb1, 0xd3, 0x0c, 0xe7, 0x4d, 0x03, 0xbc, 0x17, 0x9c,
-       0x3d, 0x12, 0xf7, 0x01, 0xac, 0x7b, 0x86, 0xab, 0xab, 0x51, 0x2e, 0xbe,
-       0x88, 0x0b, 0x45, 0xb5, 0x97, 0xaa, 0xcd, 0x19, 0x6a, 0x5b, 0x2e, 0xb1,
-       0x2e, 0x62, 0xfd, 0xa0, 0xb8, 0x8f, 0xd3, 0x2e, 0x6a, 0xb1, 0x43, 0xd4,
-       0x39, 0x77, 0x70, 0x9f, 0x4b, 0x06, 0x8f, 0xf2, 0x07, 0x0d, 0x95, 0xba,
-       0xc7, 0x3e, 0x5d, 0xac, 0xd7, 0x36, 0x6f, 0xe3, 0xed, 0xdd, 0x41, 0x15,
-       0x53, 0xee, 0xe7, 0xb6, 0x7f, 0xe0, 0xbc, 0x45, 0x1d, 0x37, 0x32, 0x67,
-       0xf5, 0xce, 0x7f, 0xff, 0x06, 0x63, 0xe1, 0x4b, 0x7b, 0x30, 0x12, 0x00,
-       0x00, 0x00 };
+       0xbd, 0x59, 0x6f, 0x70, 0x5c, 0xd5, 0x7d, 0x3d, 0x6f, 0xf7, 0xed, 0xee,
+       0x93, 0xb4, 0x92, 0x9e, 0x90, 0x0c, 0xab, 0x56, 0x8d, 0xf6, 0x59, 0x6f,
+       0xa5, 0xc5, 0xab, 0xd8, 0x6f, 0x2d, 0xb9, 0xac, 0x87, 0x37, 0xcd, 0xb3,
+       0x2c, 0x29, 0x8b, 0xec, 0xd8, 0xeb, 0x42, 0x66, 0xe4, 0x09, 0x1d, 0x0b,
+       0x59, 0xd8, 0xc2, 0x18, 0xa2, 0x12, 0x3e, 0xa8, 0x13, 0x4f, 0xbd, 0xe8,
+       0x9f, 0x85, 0xbd, 0xd2, 0x23, 0x02, 0x2c, 0x3b, 0x93, 0x0e, 0x1e, 0xf9,
+       0x8f, 0x18, 0x58, 0x6b, 0xa1, 0xfd, 0x92, 0x69, 0xc3, 0x44, 0x13, 0x1b,
+       0xec, 0x90, 0x38, 0x4e, 0xa7, 0x5f, 0xcc, 0xb4, 0x9d, 0xaa, 0x80, 0x29,
+       0x50, 0x70, 0xdc, 0xce, 0xa4, 0x63, 0x0a, 0xf5, 0xed, 0xb9, 0x6f, 0x57,
+       0x46, 0x38, 0x4e, 0x3f, 0xd6, 0x33, 0x8b, 0x76, 0xef, 0x7b, 0xf7, 0xde,
+       0xdf, 0xbd, 0xbf, 0x73, 0xce, 0xef, 0xdc, 0xcb, 0x6a, 0x1f, 0xca, 0x51,
+       0xfa, 0x57, 0xc9, 0x4f, 0xfb, 0x23, 0x43, 0x4f, 0x6f, 0x58, 0x6b, 0xad,
+       0x95, 0xbf, 0x95, 0x00, 0x54, 0xfc, 0x3f, 0xfe, 0xf3, 0x03, 0xfa, 0x72,
+       0x1c, 0xf2, 0x03, 0xcd, 0x67, 0x2f, 0xae, 0xee, 0x30, 0xa1, 0xf9, 0xed,
+       0x87, 0x5a, 0x76, 0x9b, 0x80, 0x93, 0x4f, 0x44, 0x37, 0xe3, 0x7f, 0x44,
+       0xb6, 0x4e, 0x85, 0x6c, 0xff, 0x23, 0xfb, 0x8b, 0x75, 0x6f, 0xdc, 0x67,
+       0x5c, 0x3f, 0xe1, 0x87, 0xa6, 0xdb, 0x93, 0x9a, 0xde, 0x0c, 0xad, 0x81,
+       0x7d, 0x7e, 0xd4, 0xb2, 0x2b, 0x88, 0xaa, 0xe5, 0xb1, 0x80, 0x93, 0x39,
+       0xc3, 0xda, 0x83, 0x84, 0x7e, 0x8e, 0x0b, 0x72, 0x38, 0xc7, 0x99, 0x3c,
+       0x70, 0x28, 0xa7, 0xe0, 0x2a, 0xc7, 0x1c, 0xcf, 0x6b, 0x58, 0xf2, 0x7b,
+       0xd3, 0xf5, 0x95, 0xd9, 0xc8, 0x98, 0x53, 0x07, 0x45, 0xc8, 0x44, 0xf6,
+       0x0f, 0x6c, 0x33, 0x7e, 0x08, 0xe1, 0xd4, 0x5c, 0x3b, 0x32, 0xab, 0xcf,
+       0x6a, 0xd8, 0xe9, 0x36, 0xf4, 0x69, 0x36, 0xf8, 0x8e, 0x82, 0xd4, 0x7d,
+       0x1a, 0x7a, 0x0b, 0x71, 0x64, 0x0b, 0x59, 0x38, 0x85, 0x31, 0x7e, 0x34,
+       0x84, 0xa6, 0x34, 0x6d, 0xdd, 0xd4, 0xdd, 0xf2, 0x1d, 0x84, 0xa7, 0xae,
+       0x8b, 0x6b, 0x49, 0x1d, 0x6f, 0x6f, 0x14, 0xa2, 0xd2, 0x46, 0xb6, 0xa2,
+       0x3d, 0x0b, 0xbf, 0x6d, 0x58, 0x5b, 0xfc, 0x0a, 0x3a, 0xbf, 0x6e, 0xc6,
+       0xa7, 0x94, 0x07, 0x1f, 0xf4, 0xd9, 0xd0, 0x14, 0x3b, 0xaa, 0x35, 0xe5,
+       0x1b, 0x30, 0x51, 0xd0, 0x71, 0xa8, 0x50, 0x87, 0xb1, 0x02, 0x0e, 0xf8,
+       0x37, 0x04, 0x31, 0xa7, 0xc3, 0xf9, 0x4e, 0xcb, 0x01, 0xec, 0xcb, 0x0d,
+       0x63, 0x77, 0x2e, 0x85, 0xc3, 0x05, 0x19, 0x63, 0x14, 0xa3, 0x05, 0x15,
+       0xc1, 0x29, 0x23, 0xf2, 0x73, 0xdc, 0xe9, 0x99, 0x10, 0x63, 0x56, 0x08,
+       0x23, 0x56, 0x1c, 0xe3, 0xae, 0x8f, 0xeb, 0x0c, 0x61, 0xd4, 0xbc, 0x21,
+       0x06, 0x2c, 0xc3, 0x1a, 0x87, 0x68, 0x3c, 0x6f, 0x19, 0x91, 0x4e, 0x3f,
+       0x9c, 0xef, 0x9b, 0x11, 0x8c, 0x33, 0xf6, 0x31, 0xaf, 0xdf, 0x18, 0x3a,
+       0x6f, 0xf5, 0x73, 0xd8, 0x4f, 0xc7, 0xc4, 0x57, 0xfb, 0x46, 0xc7, 0x91,
+       0x88, 0x4c, 0xc0, 0x87, 0xbe, 0xba, 0x56, 0xf6, 0x6b, 0x8a, 0x4e, 0xc0,
+       0x88, 0x73, 0x9c, 0x6c, 0xb0, 0xdd, 0xe1, 0x18, 0x59, 0xf6, 0x37, 0xa2,
+       0x67, 0x20, 0xc7, 0x6a, 0xe0, 0xef, 0x76, 0xf6, 0x57, 0xe0, 0xb3, 0x63,
+       0xd1, 0x11, 0xf6, 0x39, 0x67, 0xa9, 0x78, 0x93, 0x9f, 0x3e, 0xdd, 0x90,
+       0x99, 0x55, 0x42, 0x6c, 0x3f, 0x04, 0x3e, 0x37, 0x2b, 0x70, 0x22, 0x63,
+       0x61, 0x84, 0xeb, 0xd6, 0xd8, 0x36, 0xc9, 0xb6, 0x80, 0x69, 0x71, 0x7c,
+       0xe8, 0x9d, 0x85, 0x95, 0x98, 0x58, 0xce, 0xcd, 0xef, 0x6b, 0xe7, 0x18,
+       0x6e, 0x31, 0xa7, 0xf2, 0x9d, 0xcd, 0xee, 0x4d, 0xf1, 0x88, 0xba, 0xf2,
+       0xf9, 0xb0, 0xd2, 0xc1, 0x36, 0x47, 0x6d, 0xc0, 0x21, 0x17, 0x5a, 0xd0,
+       0xd4, 0x38, 0x8f, 0x86, 0xf7, 0x72, 0xc3, 0x4a, 0x77, 0xc1, 0x51, 0xba,
+       0xe6, 0x3b, 0x14, 0x67, 0x5e, 0x55, 0x3a, 0x67, 0x65, 0xdc, 0x42, 0x3c,
+       0x6b, 0x29, 0x8c, 0xf9, 0x07, 0x32, 0x5e, 0x27, 0xaa, 0xdc, 0x14, 0x6b,
+       0x62, 0x3e, 0x54, 0x98, 0xdd, 0xca, 0x96, 0x79, 0x21, 0xd2, 0xc9, 0xb4,
+       0xd2, 0x33, 0x0f, 0x2d, 0x6c, 0xdb, 0x5a, 0x6e, 0xea, 0x30, 0xb2, 0xab,
+       0x4c, 0x1c, 0x77, 0xa3, 0xb8, 0x64, 0xf9, 0x70, 0x62, 0x55, 0x19, 0x54,
+       0x53, 0xe1, 0x07, 0xe1, 0xcb, 0x16, 0xd4, 0x2a, 0x7e, 0xbf, 0xb6, 0x43,
+       0xc5, 0x58, 0x7b, 0x8f, 0xd2, 0xc9, 0x3e, 0x01, 0xe6, 0xf9, 0x74, 0x2e,
+       0x8d, 0x30, 0xb1, 0x53, 0x61, 0xc7, 0x22, 0x79, 0xee, 0xcd, 0xdb, 0x56,
+       0x2c, 0xfe, 0xb8, 0xc4, 0x63, 0x8d, 0x11, 0x91, 0x7b, 0x53, 0x69, 0xc7,
+       0xe2, 0x67, 0xb9, 0x0f, 0x7e, 0x53, 0xc5, 0xaf, 0xac, 0x00, 0x16, 0x77,
+       0x58, 0xcc, 0xa9, 0x8e, 0x20, 0xdb, 0xcf, 0x78, 0xed, 0xf2, 0x37, 0xf4,
+       0xae, 0xaf, 0xec, 0x43, 0x71, 0x0f, 0x46, 0xdd, 0x26, 0xc6, 0x5c, 0xdc,
+       0x83, 0xed, 0x5c, 0xef, 0xbf, 0x06, 0xe4, 0xd7, 0xaf, 0xdd, 0x6a, 0xdb,
+       0xc9, 0x38, 0x7d, 0xb6, 0xb9, 0xb8, 0xda, 0x5f, 0x0f, 0xd4, 0xb6, 0xe3,
+       0x30, 0x73, 0xdc, 0x99, 0xbc, 0x1b, 0x59, 0xef, 0x79, 0x9d, 0xbe, 0x65,
+       0xb6, 0x16, 0x7d, 0xab, 0xbc, 0x7d, 0xd3, 0xb7, 0xcd, 0x0a, 0xf1, 0x66,
+       0x32, 0x88, 0xb3, 0xe6, 0x48, 0xa4, 0x12, 0x59, 0xcb, 0xcf, 0x7c, 0x5f,
+       0xe0, 0xfc, 0xf9, 0xa4, 0x1f, 0x27, 0x93, 0x27, 0x90, 0xad, 0x01, 0xe6,
+       0x72, 0x92, 0x57, 0xc6, 0xe2, 0x05, 0xfe, 0xd7, 0x57, 0x90, 0xeb, 0xb3,
+       0xb8, 0x3e, 0x05, 0x67, 0x4c, 0x89, 0x69, 0x4b, 0x6b, 0x26, 0xbf, 0xf6,
+       0x71, 0x3f, 0xeb, 0xdb, 0xc3, 0xc4, 0x27, 0xf0, 0x6e, 0x6e, 0x00, 0x3b,
+       0x8b, 0xb1, 0xe0, 0x46, 0x8e, 0xc2, 0xd2, 0x96, 0xc6, 0x89, 0xe2, 0x6f,
+       0x72, 0x3c, 0xad, 0x75, 0xe4, 0x8c, 0x4c, 0x1a, 0x89, 0x8b, 0x1d, 0x8a,
+       0xec, 0x9f, 0xd6, 0xd6, 0xe4, 0x83, 0x88, 0xd6, 0x16, 0x9f, 0x57, 0xd8,
+       0x5b, 0xb5, 0xc7, 0xa7, 0x14, 0xec, 0x8d, 0xc9, 0x67, 0x5b, 0xb5, 0x96,
+       0x3c, 0xb4, 0x4a, 0x7b, 0x48, 0x3b, 0x3b, 0x65, 0xf4, 0xbd, 0xac, 0x24,
+       0xa2, 0x53, 0x5e, 0x9f, 0x21, 0xad, 0x35, 0x1f, 0xe2, 0x7a, 0xe2, 0xcc,
+       0x09, 0xb4, 0x2a, 0xfb, 0x69, 0xed, 0x57, 0x7c, 0x70, 0xd1, 0xeb, 0xf3,
+       0xb4, 0x16, 0xcf, 0xcb, 0x76, 0xc3, 0x8a, 0x2a, 0x21, 0xdc, 0x9b, 0xd4,
+       0xb0, 0xa6, 0x45, 0x34, 0x76, 0x25, 0x8d, 0xc5, 0x2e, 0x7f, 0x04, 0xc7,
+       0xc9, 0x05, 0xe2, 0xce, 0xf9, 0xc3, 0x96, 0x31, 0x74, 0x15, 0xfc, 0x88,
+       0xd6, 0x38, 0x38, 0xe2, 0x86, 0xf0, 0x33, 0xe2, 0xbf, 0xdb, 0xd2, 0x31,
+       0xe6, 0x1a, 0xf1, 0x5f, 0x20, 0x91, 0x3a, 0xc5, 0x9c, 0x2d, 0x91, 0x03,
+       0x47, 0x0a, 0x4d, 0xf1, 0x53, 0x30, 0x06, 0xbb, 0xc8, 0x01, 0xad, 0x5d,
+       0xc6, 0x00, 0x5d, 0xb5, 0xc9, 0x9d, 0x42, 0x03, 0x72, 0xe4, 0x43, 0x97,
+       0xc7, 0xab, 0x61, 0xa5, 0xb3, 0xf0, 0x4b, 0x6a, 0x6b, 0x37, 0xf1, 0x85,
+       0xea, 0x88, 0x19, 0x44, 0xaa, 0x36, 0x8a, 0xf3, 0xc4, 0x4a, 0xb6, 0xae,
+       0x8c, 0xb9, 0x94, 0xf9, 0x7c, 0x87, 0xcf, 0x7b, 0x94, 0xcd, 0xf3, 0x51,
+       0xfc, 0xcc, 0xfa, 0x42, 0x38, 0x75, 0x95, 0x6c, 0x0b, 0xac, 0x68, 0xd7,
+       0x70, 0xf5, 0x85, 0x72, 0x7c, 0xfc, 0x42, 0x18, 0x9f, 0xbd, 0x40, 0x7e,
+       0xbb, 0x68, 0x2f, 0x87, 0x10, 0xa9, 0x36, 0x21, 0x0a, 0x56, 0x2b, 0xde,
+       0xab, 0x89, 0x45, 0xaf, 0x40, 0x6a, 0xa3, 0xa3, 0xed, 0xce, 0x19, 0x43,
+       0x83, 0x48, 0x38, 0xe7, 0xbc, 0xbd, 0x70, 0xb4, 0xb5, 0xf9, 0xf3, 0x02,
+       0x3b, 0x8a, 0x7b, 0x11, 0xb4, 0x3b, 0xb5, 0xb7, 0x98, 0x9b, 0xcb, 0x5e,
+       0x6e, 0x3a, 0xb5, 0x75, 0xf9, 0xfb, 0xfd, 0x28, 0x2f, 0x3e, 0x53, 0xed,
+       0x8c, 0x36, 0x96, 0x33, 0x7a, 0x27, 0xb9, 0xbe, 0x01, 0xaf, 0x6f, 0x46,
+       0x4b, 0x70, 0xef, 0x97, 0x4a, 0xb9, 0xa9, 0xb4, 0x1f, 0xe2, 0x3e, 0x33,
+       0xf7, 0xde, 0x3e, 0x3e, 0xc4, 0x3d, 0x96, 0xf3, 0x0d, 0xdf, 0x36, 0xdf,
+       0x30, 0xe7, 0x7b, 0x79, 0xc5, 0x7c, 0x07, 0x56, 0xcc, 0x77, 0x60, 0xc5,
+       0x7c, 0x29, 0x72, 0xf5, 0x1f, 0xc4, 0x48, 0x5d, 0x71, 0x6c, 0xd5, 0x1e,
+       0xbc, 0x6d, 0xee, 0x41, 0xce, 0x7d, 0x54, 0x2c, 0x65, 0x8a, 0xe3, 0x54,
+       0xda, 0xfb, 0x57, 0xcc, 0xbd, 0x9f, 0x73, 0x2f, 0x8f, 0xa3, 0x53, 0x8b,
+       0x84, 0xd8, 0x66, 0x09, 0xa1, 0xda, 0xa6, 0xde, 0x89, 0xe6, 0x4c, 0x27,
+       0xb1, 0x53, 0x8e, 0xc4, 0xa2, 0x0f, 0xe6, 0x70, 0xbd, 0x3f, 0x80, 0xa5,
+       0x9a, 0x65, 0x6e, 0x54, 0x96, 0xfe, 0xbe, 0xa4, 0x80, 0x5a, 0xff, 0x6a,
+       0xae, 0x9a, 0x63, 0xc4, 0xf4, 0x01, 0x45, 0x88, 0x73, 0x1b, 0x13, 0x83,
+       0x7e, 0x24, 0xfa, 0xaa, 0x60, 0x12, 0x43, 0x81, 0x12, 0x17, 0x56, 0xf6,
+       0x79, 0xd9, 0xeb, 0x53, 0xf0, 0xfa, 0x08, 0xf1, 0xee, 0x86, 0x0f, 0xc5,
+       0x1b, 0x2d, 0x75, 0xf8, 0x29, 0x39, 0xf9, 0x5a, 0x61, 0x59, 0x57, 0xa4,
+       0x6e, 0xc0, 0x77, 0xce, 0x0a, 0x32, 0xa6, 0x91, 0x7d, 0xc1, 0xaf, 0xf4,
+       0x27, 0x60, 0x4c, 0xd9, 0xe6, 0xc7, 0x2b, 0x49, 0x3c, 0x52, 0x0e, 0xa3,
+       0xf7, 0xb0, 0x92, 0x4d, 0x57, 0xc0, 0x70, 0xd6, 0x28, 0xd9, 0x94, 0x06,
+       0xc9, 0x1b, 0xb5, 0xe9, 0xb4, 0x69, 0x64, 0xaf, 0xf2, 0x65, 0x75, 0xfa,
+       0x4e, 0x31, 0xa8, 0x1c, 0x23, 0x8c, 0x27, 0xdd, 0x0b, 0x58, 0x0c, 0x34,
+       0x50, 0x9f, 0xa5, 0x76, 0x72, 0xe0, 0x05, 0x8d, 0x35, 0x2d, 0x44, 0x22,
+       0xaa, 0x38, 0xe8, 0xfa, 0xce, 0x37, 0x42, 0x20, 0xd8, 0x16, 0xc0, 0x3b,
+       0xe6, 0xa8, 0x55, 0x8f, 0x4d, 0xb8, 0xdc, 0xca, 0x3d, 0x58, 0xa5, 0x22,
+       0x32, 0xb7, 0x72, 0xac, 0x08, 0xc7, 0xfa, 0xb3, 0x10, 0xaa, 0xea, 0xa0,
+       0x36, 0xab, 0xd8, 0xeb, 0x6a, 0x4a, 0x97, 0x2b, 0xb1, 0x6b, 0x46, 0x4e,
+       0xe1, 0x14, 0xb5, 0x82, 0x35, 0xec, 0x8c, 0xaa, 0x6c, 0x99, 0x0d, 0xa1,
+       0x7c, 0xe6, 0x13, 0xf1, 0x18, 0xb5, 0x2f, 0xbd, 0x41, 0x08, 0x33, 0x19,
+       0x82, 0xc6, 0x79, 0x86, 0xc9, 0xe7, 0xea, 0xb6, 0x5a, 0x5c, 0xfb, 0x3a,
+       0xb5, 0xe9, 0xdb, 0x21, 0xf8, 0x67, 0x42, 0x08, 0xce, 0x28, 0x78, 0xa7,
+       0x3d, 0x84, 0xfa, 0x39, 0xf9, 0x5b, 0x41, 0xa3, 0x79, 0x14, 0x07, 0x75,
+       0x3f, 0x63, 0xfc, 0x2b, 0xf4, 0xeb, 0x0d, 0x98, 0xa4, 0x36, 0x3f, 0xea,
+       0x6a, 0xa8, 0x3a, 0x4a, 0x2d, 0xb0, 0x85, 0x38, 0x49, 0xfc, 0x1f, 0x64,
+       0x8c, 0x32, 0xde, 0x0b, 0x56, 0x36, 0x1a, 0x42, 0x00, 0xc1, 0x39, 0x23,
+       0x3d, 0xc9, 0xe8, 0x52, 0x53, 0xaa, 0xb2, 0x7d, 0x96, 0xb5, 0xd7, 0x36,
+       0x7b, 0xeb, 0xfd, 0x42, 0x7c, 0x9a, 0x6c, 0xea, 0x5b, 0xa0, 0x06, 0x8f,
+       0xc4, 0x62, 0x99, 0x7e, 0x05, 0x58, 0x73, 0x96, 0x76, 0x64, 0xe6, 0xbf,
+       0x44, 0x98, 0xe3, 0x1c, 0xd9, 0x20, 0x30, 0x6e, 0x65, 0x23, 0x01, 0x18,
+       0x37, 0x86, 0x50, 0x87, 0x0f, 0x9e, 0x17, 0x42, 0xb4, 0x57, 0xe3, 0x1d,
+       0xcb, 0x18, 0x34, 0xfd, 0x02, 0x3f, 0x4e, 0x66, 0x87, 0x22, 0x30, 0x86,
+       0x7f, 0xad, 0x44, 0xf1, 0xf1, 0x94, 0x91, 0xbe, 0xa8, 0x04, 0x51, 0x39,
+       0x67, 0xea, 0x5b, 0x94, 0x30, 0xca, 0x17, 0xc2, 0x58, 0x7d, 0x36, 0x88,
+       0xc0, 0x4c, 0x18, 0xc1, 0x69, 0xf3, 0xe2, 0x2e, 0x78, 0xe3, 0x2c, 0x0e,
+       0xa1, 0x19, 0xd5, 0xb3, 0x66, 0xf4, 0x5f, 0x20, 0xb1, 0x1d, 0x86, 0xba,
+       0x10, 0x45, 0x7d, 0xc1, 0x44, 0x35, 0xf3, 0x7d, 0xf9, 0xac, 0xcc, 0xb3,
+       0x8e, 0xb0, 0xe9, 0xe3, 0xda, 0x1c, 0x65, 0xab, 0x57, 0x37, 0x3a, 0xf9,
+       0xe9, 0x56, 0x3a, 0xe6, 0xe5, 0x9e, 0x29, 0x28, 0xe3, 0xb3, 0x8b, 0xd6,
+       0x4d, 0xb1, 0x2f, 0x26, 0xeb, 0x44, 0x19, 0x02, 0x76, 0x8f, 0xf2, 0xc0,
+       0x3c, 0x8b, 0x90, 0xa7, 0xef, 0x65, 0x4a, 0xc0, 0x2e, 0x6a, 0xfb, 0x25,
+       0x6a, 0xfb, 0x89, 0x92, 0xb6, 0x57, 0x51, 0xdb, 0x17, 0xfe, 0x4f, 0x6d,
+       0x67, 0xbd, 0x9f, 0xf1, 0xe1, 0xbc, 0x19, 0xc2, 0x71, 0xab, 0x69, 0xb1,
+       0x1e, 0x21, 0x54, 0xb7, 0xe9, 0xa8, 0x5e, 0xb0, 0xf0, 0x1c, 0xf7, 0x16,
+       0x77, 0x15, 0xf5, 0xfd, 0x9b, 0x52, 0xf3, 0x4b, 0x5e, 0xed, 0x71, 0x77,
+       0x59, 0x13, 0xc2, 0xd4, 0x2a, 0x55, 0xe9, 0xa1, 0x9e, 0x3f, 0x90, 0xbc,
+       0x29, 0xe2, 0x31, 0x23, 0x4e, 0xce, 0xde, 0x38, 0x89, 0xa2, 0x46, 0xc4,
+       0xa8, 0x97, 0x4b, 0xb5, 0x71, 0x1c, 0x73, 0x65, 0x4d, 0xeb, 0x64, 0x4d,
+       0x53, 0x30, 0x12, 0x2b, 0x6a, 0xc4, 0xea, 0xbc, 0x6c, 0xd7, 0x51, 0x4f,
+       0x9d, 0x5c, 0xd7, 0x16, 0xc1, 0x31, 0x6a, 0xa4, 0x4b, 0x9f, 0xb3, 0x9d,
+       0xe3, 0x6d, 0x9b, 0x35, 0xb2, 0xdb, 0x99, 0x9f, 0xf3, 0xc4, 0xc5, 0x14,
+       0xab, 0xc3, 0x89, 0x1a, 0x6a, 0x67, 0x73, 0x08, 0x13, 0xd4, 0xcb, 0xf3,
+       0xf4, 0x10, 0x2f, 0xb1, 0xdf, 0xb8, 0x6b, 0x44, 0x5f, 0x22, 0xaf, 0xc7,
+       0x4b, 0x9a, 0xf9, 0x12, 0x7d, 0xc3, 0x38, 0xf3, 0xf4, 0x53, 0x3e, 0x7b,
+       0xcd, 0x35, 0x1c, 0xe9, 0x1f, 0xfc, 0x9e, 0x7f, 0x30, 0xe2, 0x7e, 0x45,
+       0x7a, 0x88, 0x08, 0xde, 0x68, 0x91, 0x58, 0x24, 0xc6, 0x6f, 0xe9, 0xa7,
+       0xaa, 0x7c, 0x6b, 0xf6, 0xba, 0xc8, 0xc7, 0xca, 0x55, 0xc9, 0xbf, 0xb1,
+       0xa4, 0xc4, 0x93, 0x10, 0x65, 0x76, 0x98, 0x5e, 0xcb, 0x8c, 0x7f, 0x84,
+       0x18, 0x71, 0x1b, 0xe1, 0xb3, 0x30, 0xfc, 0x67, 0xb7, 0xa8, 0x9e, 0x8f,
+       0x5d, 0x90, 0x7e, 0x8b, 0x79, 0x9a, 0x32, 0x7b, 0xa7, 0x94, 0x58, 0x66,
+       0x40, 0x91, 0xcf, 0x75, 0x94, 0x9f, 0x5d, 0x22, 0x77, 0x23, 0xe4, 0x6e,
+       0x1d, 0x5e, 0xbf, 0x8d, 0xbf, 0xd4, 0x55, 0xdf, 0x00, 0xf9, 0x9b, 0xad,
+       0x1b, 0xe9, 0xf7, 0x7f, 0x85, 0x7b, 0x87, 0x24, 0x7f, 0xd9, 0xe6, 0xc7,
+       0xb3, 0x49, 0xec, 0x2c, 0x83, 0x91, 0x79, 0x4c, 0xc9, 0x3a, 0xe4, 0x71,
+       0xaa, 0x4c, 0xc9, 0xd2, 0x31, 0x7d, 0xc9, 0xdf, 0x37, 0xf9, 0xb6, 0x9f,
+       0xfc, 0xed, 0xab, 0xbb, 0x9d, 0xbf, 0x47, 0x38, 0x86, 0x8a, 0x27, 0xdc,
+       0xe3, 0x98, 0x0b, 0x04, 0x11, 0x99, 0x09, 0x20, 0x34, 0xa3, 0xa2, 0x92,
+       0x5c, 0x09, 0xdb, 0xd9, 0x78, 0x08, 0x46, 0xfa, 0x35, 0x44, 0x90, 0x98,
+       0xd2, 0xf0, 0xe7, 0x2d, 0x01, 0x9c, 0x89, 0x19, 0x99, 0xfd, 0x4a, 0x84,
+       0x58, 0x1f, 0x61, 0x44, 0x46, 0x34, 0xea, 0x2b, 0xf2, 0x35, 0xd0, 0x1c,
+       0x84, 0x36, 0x23, 0xb9, 0x2e, 0x0e, 0xfa, 0xec, 0x6c, 0x54, 0x23, 0x46,
+       0x7f, 0x40, 0x6c, 0x5c, 0x99, 0x12, 0x62, 0x73, 0xbb, 0x79, 0xf1, 0x3d,
+       0xbf, 0x41, 0xdd, 0x53, 0x89, 0xd3, 0xe2, 0xf8, 0x15, 0x33, 0x1a, 0x82,
+       0x47, 0xbd, 0xf1, 0x6f, 0xbc, 0xce, 0x28, 0x3e, 0x75, 0x55, 0x65, 0x2b,
+       0x71, 0x40, 0x6e, 0x45, 0xe6, 0xa9, 0x7d, 0x87, 0x93, 0x46, 0x7a, 0x8b,
+       0xd2, 0xe4, 0x34, 0xf3, 0xbb, 0x2f, 0x19, 0x8b, 0xf6, 0xf3, 0x9d, 0xf7,
+       0x0b, 0x45, 0x0e, 0xd7, 0x9b, 0xbb, 0xf1, 0x17, 0xe4, 0x70, 0x95, 0xf9,
+       0x14, 0x9e, 0xf4, 0xf4, 0x88, 0x38, 0x98, 0x2e, 0x27, 0xb7, 0x1d, 0x65,
+       0x17, 0x71, 0xbf, 0x73, 0x9e, 0xba, 0x32, 0xd3, 0xee, 0x69, 0x51, 0xc8,
+       0xec, 0x54, 0x7a, 0xe7, 0xbb, 0x3d, 0x0f, 0xb5, 0x7d, 0xd6, 0x87, 0xd7,
+       0xad, 0x4d, 0xf4, 0x2b, 0x69, 0x65, 0xfb, 0xbc, 0xc4, 0x7c, 0x8f, 0xf2,
+       0x4d, 0xe2, 0x3f, 0x7a, 0x97, 0x8a, 0x39, 0x6b, 0x93, 0x12, 0xf4, 0xf0,
+       0x1f, 0x80, 0x93, 0x29, 0x62, 0xdf, 0x6f, 0xc7, 0xac, 0x73, 0x2b, 0xb0,
+       0xdf, 0x7d, 0x07, 0x5f, 0x23, 0xf5, 0x03, 0x45, 0x2d, 0xd7, 0x3b, 0x99,
+       0xaf, 0x67, 0x4a, 0x18, 0x7f, 0x92, 0xed, 0x81, 0x19, 0x68, 0xe5, 0xc4,
+       0x71, 0xcf, 0x54, 0x18, 0xd3, 0x1e, 0x56, 0x04, 0x5e, 0x65, 0x4d, 0xc8,
+       0x27, 0x0d, 0x6b, 0xbf, 0x62, 0xa4, 0xbb, 0x95, 0x44, 0x76, 0x4d, 0xa9,
+       0x1e, 0xde, 0xcb, 0x9a, 0x86, 0xbb, 0xa8, 0x0b, 0x16, 0xb4, 0x10, 0xf1,
+       0xfd, 0x6f, 0xac, 0x4f, 0xff, 0x51, 0xaa, 0x87, 0xc9, 0x7c, 0x39, 0xaa,
+       0x5b, 0xa8, 0xef, 0xc4, 0x73, 0x97, 0xc4, 0x33, 0x3d, 0xc4, 0x18, 0xeb,
+       0xff, 0x4e, 0xe2, 0x79, 0x75, 0x9b, 0x91, 0xed, 0xa4, 0x77, 0xf6, 0xad,
+       0x8f, 0x10, 0xab, 0x71, 0xfa, 0xd5, 0x31, 0x74, 0x70, 0xae, 0xf4, 0xac,
+       0x11, 0xe9, 0x20, 0x07, 0x54, 0xf6, 0x79, 0x89, 0x7d, 0x96, 0x6a, 0xa5,
+       0xaf, 0x0e, 0xe1, 0x59, 0xf6, 0x31, 0x93, 0x8e, 0xa7, 0x15, 0x92, 0x03,
+       0x13, 0x48, 0x64, 0x24, 0x07, 0x9c, 0x55, 0xad, 0xf4, 0xf8, 0x92, 0x03,
+       0xc4, 0xa0, 0x4b, 0x0c, 0x16, 0x79, 0x30, 0x28, 0x79, 0x50, 0x45, 0x0f,
+       0xb1, 0x40, 0x0f, 0x51, 0x61, 0x47, 0xc9, 0x01, 0xc9, 0x89, 0xa2, 0x8f,
+       0xe8, 0x2c, 0xf1, 0x60, 0x8b, 0x37, 0x9f, 0x4a, 0xed, 0x0b, 0xa3, 0x69,
+       0xda, 0xd0, 0x55, 0xe5, 0x3f, 0xc5, 0x2e, 0xd3, 0x5c, 0xdc, 0x4b, 0x2f,
+       0xf0, 0x59, 0x5b, 0x8c, 0x79, 0x0f, 0x63, 0xdd, 0x42, 0x79, 0x40, 0xe2,
+       0xbc, 0x7e, 0x3a, 0x8c, 0xea, 0x69, 0xc9, 0x83, 0xec, 0x24, 0xf5, 0x6f,
+       0xc8, 0xf2, 0xfd, 0x13, 0xf1, 0x1f, 0x25, 0x2e, 0x54, 0xa5, 0x8b, 0x63,
+       0x54, 0xcd, 0xe8, 0x68, 0x9d, 0x36, 0x06, 0x17, 0x70, 0x4d, 0xbc, 0x1a,
+       0x33, 0x33, 0x87, 0x98, 0xff, 0x3d, 0xc9, 0x18, 0xf7, 0x4a, 0xc7, 0xbd,
+       0xb7, 0xc6, 0xf0, 0x38, 0xe1, 0xf4, 0x5b, 0xe1, 0x92, 0xaf, 0xd6, 0xd0,
+       0xef, 0x02, 0x7b, 0x5c, 0x1a, 0x5b, 0xd3, 0xb7, 0x36, 0x88, 0xeb, 0x38,
+       0x49, 0xf4, 0x0f, 0xe8, 0x0e, 0xf3, 0x1f, 0xc2, 0xde, 0xd2, 0x3b, 0x45,
+       0xbf, 0xfd, 0xe3, 0xd2, 0x79, 0xf2, 0x17, 0xfe, 0xe2, 0xdf, 0xbf, 0x55,
+       0x97, 0xcf, 0x97, 0xfd, 0xc4, 0xe0, 0x66, 0x62, 0xb0, 0x9b, 0x39, 0xda,
+       0x6b, 0x91, 0xdf, 0xcc, 0x67, 0x56, 0x0d, 0x51, 0x0f, 0x9b, 0xfa, 0x2a,
+       0xa9, 0x6b, 0x87, 0xa9, 0x51, 0x3f, 0x37, 0xcb, 0xe9, 0xb7, 0x1d, 0xfa,
+       0xed, 0x0e, 0x6a, 0x68, 0x27, 0xf5, 0x53, 0x62, 0x2b, 0x4d, 0x1c, 0x69,
+       0x4a, 0x9a, 0x1e, 0x36, 0x90, 0xa4, 0xd7, 0xae, 0x5b, 0xf6, 0xda, 0x32,
+       0x4e, 0xe9, 0xaf, 0x8d, 0xb8, 0x2c, 0xb5, 0x4f, 0x32, 0x0f, 0x8b, 0x35,
+       0x9b, 0xa0, 0xda, 0x9b, 0x14, 0xd5, 0x96, 0xe7, 0x09, 0x15, 0xdf, 0xa5,
+       0xd6, 0x2e, 0xed, 0x90, 0xe7, 0x0a, 0xae, 0x8b, 0x6d, 0x11, 0x33, 0x16,
+       0x3d, 0x4e, 0x5c, 0x1d, 0xfb, 0x9d, 0x73, 0x46, 0x11, 0x6f, 0xa3, 0xae,
+       0x7a, 0xcb, 0x33, 0x4b, 0x7d, 0xd8, 0x74, 0x0b, 0x6f, 0x1a, 0x9e, 0x68,
+       0x89, 0x12, 0x8f, 0x12, 0x6b, 0x1a, 0xf2, 0x2f, 0x96, 0xe3, 0xd5, 0x17,
+       0xc3, 0x78, 0xe5, 0x45, 0x21, 0xc6, 0x93, 0xe0, 0x69, 0x46, 0x6a, 0xec,
+       0x46, 0xbc, 0xac, 0xc7, 0xa2, 0xcf, 0x7a, 0x9e, 0xd5, 0xa1, 0x67, 0x35,
+       0x06, 0x2f, 0xe0, 0x26, 0xf5, 0x4b, 0x72, 0x3a, 0x41, 0xbe, 0x15, 0xb1,
+       0xe8, 0x79, 0xdb, 0x1a, 0x0d, 0x57, 0x88, 0xbf, 0x6a, 0xe2, 0xef, 0x37,
+       0xd4, 0xdd, 0x6b, 0x25, 0xdd, 0x5d, 0x9b, 0x27, 0x1f, 0xdb, 0x42, 0xe8,
+       0x96, 0x6b, 0x21, 0x0e, 0x47, 0x6f, 0xe1, 0x50, 0x88, 0x0f, 0xb8, 0xe7,
+       0x17, 0x2c, 0x23, 0xbe, 0x99, 0x78, 0x9c, 0xb3, 0x0c, 0xa7, 0x83, 0xde,
+       0x75, 0xd4, 0xc3, 0x24, 0xf5, 0x37, 0x26, 0x71, 0x49, 0x1c, 0x32, 0x27,
+       0x87, 0xd9, 0xe7, 0x3c, 0xfb, 0x4c, 0x94, 0xbc, 0xeb, 0xdb, 0x48, 0xa4,
+       0xa5, 0x77, 0x8d, 0x12, 0x83, 0x87, 0x3d, 0xef, 0x2a, 0xbd, 0xaa, 0xf4,
+       0xa9, 0x32, 0xce, 0x76, 0x2f, 0xce, 0xae, 0x5b, 0x38, 0xa4, 0x86, 0xd5,
+       0x48, 0xfc, 0x7d, 0x03, 0x13, 0xcf, 0x57, 0xa1, 0xda, 0xbc, 0x07, 0x97,
+       0x33, 0xdf, 0x50, 0x23, 0x26, 0xf4, 0x7a, 0xbb, 0x88, 0xc7, 0x9d, 0x85,
+       0x14, 0x5c, 0xf7, 0x2d, 0xe1, 0xd6, 0x19, 0xce, 0x05, 0xcf, 0x7f, 0x0e,
+       0xb2, 0xd6, 0xdc, 0x14, 0xbe, 0x98, 0x71, 0xb1, 0x9f, 0x1e, 0xac, 0xc9,
+       0x5f, 0xf4, 0x72, 0x1b, 0xf3, 0xbf, 0x14, 0xa8, 0x2d, 0xae, 0x53, 0xa5,
+       0x7f, 0x1b, 0x23, 0xe7, 0xc6, 0xcd, 0xa2, 0x97, 0x8b, 0xe5, 0xaf, 0x06,
+       0xa4, 0xa6, 0xfb, 0xda, 0xe4, 0xb8, 0x69, 0x6a, 0xc8, 0xf2, 0xd8, 0x5f,
+       0xea, 0xf2, 0x18, 0x31, 0x38, 0x2a, 0x7d, 0x15, 0x7d, 0x09, 0xcf, 0xe5,
+       0x2b, 0x34, 0x75, 0xd8, 0x0f, 0x53, 0xb6, 0x39, 0xca, 0x03, 0x5c, 0x83,
+       0x66, 0x0e, 0x2b, 0x69, 0x9e, 0x3b, 0x0f, 0x11, 0x5f, 0xdd, 0xac, 0xc3,
+       0x57, 0xad, 0x66, 0x72, 0x98, 0xf5, 0x89, 0xb5, 0xf8, 0xb0, 0xb9, 0x7c,
+       0x7e, 0x93, 0x35, 0x99, 0x35, 0xcc, 0xad, 0x64, 0xfd, 0xee, 0x61, 0xcd,
+       0xe6, 0x28, 0xcc, 0xe9, 0x67, 0x31, 0xd1, 0xb8, 0xb6, 0xcd, 0x18, 0xdc,
+       0xe6, 0x0f, 0x21, 0x47, 0xbc, 0x1f, 0x63, 0x1d, 0x72, 0xb9, 0xa7, 0xd3,
+       0x05, 0x23, 0x95, 0xc5, 0x18, 0xb6, 0x71, 0x4f, 0x79, 0xde, 0x71, 0xfe,
+       0x2e, 0x56, 0x3c, 0x0f, 0xef, 0x65, 0x7d, 0x9b, 0x2c, 0x71, 0xfb, 0x43,
+       0x24, 0x2c, 0xc9, 0xed, 0x45, 0xd6, 0xb7, 0x49, 0x8f, 0xdb, 0x46, 0x4a,
+       0xf2, 0xb9, 0xac, 0x54, 0xd7, 0x3e, 0x82, 0xe4, 0xf0, 0xed, 0x35, 0x4d,
+       0xe2, 0xd9, 0x0e, 0x4a, 0x1f, 0xeb, 0xba, 0xb2, 0x26, 0xc9, 0x5a, 0xb4,
+       0x5c, 0x97, 0x34, 0x79, 0x77, 0x90, 0x69, 0x9c, 0x3a, 0x28, 0x7c, 0xc5,
+       0xfb, 0x87, 0x8b, 0xef, 0xfa, 0xc3, 0xa9, 0xd4, 0x7d, 0xc8, 0x44, 0xce,
+       0x6a, 0xd8, 0xe1, 0x36, 0xf4, 0x85, 0x6c, 0xf0, 0x1d, 0x05, 0xd6, 0x1f,
+       0x6b, 0xc8, 0xdc, 0x76, 0xff, 0xf0, 0x41, 0x4e, 0xd3, 0xaa, 0xa7, 0xee,
+       0x96, 0xef, 0xe0, 0x93, 0xdc, 0x1d, 0xef, 0x1f, 0xd2, 0xbf, 0xef, 0xfe,
+       0xe1, 0x59, 0xf2, 0x63, 0xa2, 0x78, 0xff, 0xe0, 0x7c, 0xa7, 0xc5, 0x8f,
+       0xb9, 0x3a, 0x1c, 0x78, 0xaf, 0x5d, 0xc5, 0xd5, 0x9c, 0x11, 0x79, 0x19,
+       0x07, 0x30, 0xe0, 0xdd, 0x35, 0xf0, 0xcc, 0x6f, 0x0f, 0xe1, 0xd7, 0xed,
+       0xf2, 0xae, 0x21, 0x25, 0xd7, 0x38, 0xc9, 0xe5, 0x43, 0xa3, 0xde, 0x6c,
+       0x61, 0x2d, 0xd8, 0xb7, 0x51, 0xc1, 0x03, 0xc9, 0x7b, 0x3c, 0x6c, 0x4f,
+       0x16, 0x8c, 0x74, 0x94, 0xcf, 0xd6, 0x4d, 0xc9, 0x1a, 0xf9, 0x30, 0xcf,
+       0x86, 0xd0, 0x1a, 0xed, 0x5e, 0x4d, 0xb8, 0x4d, 0x91, 0x0f, 0x15, 0xc3,
+       0x39, 0x09, 0x79, 0x1f, 0x90, 0xb8, 0xe8, 0x57, 0x8c, 0xc5, 0x77, 0xfd,
+       0x46, 0xaa, 0xde, 0xc3, 0xcc, 0xc3, 0x3c, 0xa7, 0xc9, 0xbf, 0xbd, 0xf2,
+       0x8c, 0x87, 0x6d, 0x1c, 0xf3, 0xd2, 0x46, 0x79, 0xee, 0xfc, 0x54, 0x64,
+       0x57, 0x19, 0xce, 0x92, 0xa2, 0x31, 0x37, 0xa0, 0x3e, 0x49, 0x0d, 0x7f,
+       0x98, 0x1a, 0x2e, 0xcf, 0x08, 0xbd, 0x3c, 0x23, 0x34, 0x2d, 0xc6, 0xfd,
+       0x46, 0xe6, 0x06, 0xf5, 0x8e, 0x63, 0xf6, 0xf5, 0x2a, 0x46, 0xef, 0x02,
+       0xf5, 0x7f, 0xbf, 0x52, 0x1c, 0x73, 0x4d, 0x69, 0xcc, 0x7b, 0xf3, 0x9a,
+       0xb2, 0xd9, 0x05, 0x75, 0x07, 0xd1, 0x3d, 0x16, 0xb5, 0xa3, 0x50, 0x4e,
+       0x8e, 0x99, 0x72, 0xcd, 0x8c, 0xad, 0x95, 0xb1, 0x29, 0xf8, 0xb0, 0x45,
+       0xbe, 0xdb, 0x2a, 0xe3, 0x70, 0x2a, 0xec, 0x14, 0xb5, 0xf7, 0xb9, 0x60,
+       0x49, 0xbf, 0x7c, 0xfd, 0xd6, 0x2a, 0x38, 0x75, 0xa8, 0x0e, 0x98, 0xb5,
+       0x18, 0xd7, 0x51, 0x19, 0x36, 0x9b, 0x91, 0xd3, 0x83, 0xe8, 0xb7, 0x7e,
+       0x2b, 0xa8, 0x93, 0x7c, 0x1f, 0x78, 0xec, 0x79, 0x9e, 0xd7, 0xcd, 0xeb,
+       0x88, 0x25, 0x9f, 0xc6, 0x19, 0x7d, 0x08, 0xe5, 0xac, 0xa5, 0xaf, 0x78,
+       0x7a, 0x62, 0x13, 0xcf, 0x0a, 0x31, 0x64, 0xcb, 0x5a, 0x77, 0xdb, 0xd8,
+       0xf2, 0xfe, 0xe1, 0x7d, 0x91, 0x2d, 0x8e, 0xe1, 0xec, 0xb1, 0x32, 0x8c,
+       0xeb, 0x4b, 0xdd, 0xdd, 0x47, 0xdd, 0xa5, 0xb7, 0xfc, 0x5a, 0x39, 0x75,
+       0x77, 0xb7, 0xf5, 0x6d, 0x3c, 0x46, 0x8e, 0x57, 0x98, 0x9f, 0x88, 0xc7,
+       0xeb, 0xe4, 0x98, 0xd4, 0xd7, 0xaa, 0x95, 0xe3, 0xff, 0x33, 0xc7, 0x94,
+       0x73, 0xc8, 0x7a, 0x78, 0x59, 0x48, 0x6f, 0x56, 0x61, 0x0f, 0x2b, 0xdb,
+       0xc8, 0xa9, 0x45, 0x96, 0xde, 0xef, 0x92, 0x4f, 0x4b, 0xcc, 0x4f, 0xe3,
+       0x1d, 0xf8, 0xd4, 0x48, 0x3e, 0xed, 0x5a, 0xc1, 0xa7, 0xe3, 0xe4, 0x53,
+       0x2f, 0xf9, 0xd4, 0xd2, 0xf6, 0x27, 0xd4, 0x15, 0x21, 0x82, 0x6d, 0x37,
+       0xc5, 0x9b, 0x9e, 0xff, 0x95, 0x9e, 0x37, 0xad, 0x74, 0xcd, 0x4b, 0x7d,
+       0xaa, 0xa4, 0x27, 0xee, 0xa1, 0x1f, 0x06, 0x06, 0xc8, 0xa7, 0xc7, 0x4d,
+       0xd1, 0xb8, 0x2f, 0x69, 0xa4, 0x16, 0xe9, 0x6b, 0x7a, 0xc8, 0xa9, 0xb7,
+       0xc8, 0xa9, 0xb1, 0x42, 0x51, 0xa7, 0x0e, 0x73, 0xdd, 0xf7, 0x53, 0xa7,
+       0x7a, 0x0a, 0x52, 0xdb, 0x1c, 0xe2, 0x3f, 0x84, 0x4f, 0xc9, 0xa9, 0xf9,
+       0xa4, 0xa7, 0x53, 0xd6, 0x6f, 0x90, 0x18, 0x3a, 0x2f, 0xf9, 0x44, 0x9d,
+       0x72, 0x0b, 0x4d, 0xd6, 0x79, 0xae, 0x69, 0xd2, 0x35, 0x6e, 0x74, 0x93,
+       0x53, 0x81, 0x76, 0xe3, 0xe2, 0x55, 0x62, 0x37, 0x14, 0x83, 0x1e, 0xb1,
+       0xe5, 0x9a, 0x58, 0x63, 0x59, 0x27, 0x8f, 0x13, 0xff, 0xdd, 0xd4, 0x8c,
+       0xde, 0x82, 0x8d, 0x43, 0x85, 0x95, 0x7b, 0xca, 0x3a, 0x74, 0xc7, 0x7d,
+       0x19, 0x0d, 0xdd, 0xb9, 0x9d, 0xf5, 0xea, 0x8e, 0xed, 0x92, 0xaf, 0x7a,
+       0x48, 0xf2, 0x75, 0xd4, 0xfd, 0x61, 0xe0, 0xce, 0xef, 0xc8, 0xfb, 0x33,
+       0x21, 0x4e, 0x5b, 0xf2, 0xfe, 0x41, 0xfa, 0x1e, 0xfa, 0x68, 0x4b, 0xde,
+       0xa1, 0x75, 0x44, 0x55, 0x18, 0x91, 0x47, 0xf1, 0xb9, 0xc8, 0xd6, 0x39,
+       0xf1, 0x80, 0x57, 0x23, 0x0d, 0xbd, 0x8f, 0xb5, 0x6e, 0xb1, 0x74, 0xce,
+       0x9b, 0xcb, 0x09, 0xf1, 0x16, 0xeb, 0xd4, 0x69, 0x9e, 0xe9, 0x46, 0xf2,
+       0x9f, 0x8b, 0xc5, 0x3a, 0x15, 0x63, 0xe6, 0xad, 0xfb, 0x48, 0x4f, 0xc7,
+       0x4e, 0xf2, 0xd9, 0x44, 0x7e, 0xb9, 0x46, 0x51, 0x33, 0x4d, 0x21, 0x76,
+       0x9b, 0xff, 0x2d, 0xfa, 0xbf, 0xf2, 0xae, 0x10, 0xd3, 0x8c, 0xe1, 0x8a,
+       0x85, 0x03, 0x01, 0xc4, 0xfa, 0x6e, 0xb0, 0xae, 0x5f, 0xda, 0x68, 0x64,
+       0xf2, 0x4a, 0xa2, 0x77, 0xab, 0x22, 0xbd, 0x9e, 0xaf, 0xb3, 0x8c, 0xef,
+       0xb4, 0xd0, 0x1b, 0x7d, 0xc8, 0x0c, 0x06, 0xf9, 0xfd, 0x4d, 0xcb, 0xa0,
+       0x7f, 0x16, 0xa2, 0x3f, 0x25, 0xc7, 0x10, 0xa2, 0xc3, 0x92, 0xe7, 0x80,
+       0x31, 0x9e, 0x03, 0xb2, 0xa2, 0xc2, 0xbc, 0x42, 0x6d, 0x32, 0x32, 0x63,
+       0x8a, 0xc9, 0xbe, 0x51, 0x78, 0x3a, 0xcb, 0x67, 0xda, 0x54, 0x04, 0x7f,
+       0xed, 0xf9, 0xe7, 0x28, 0x35, 0xab, 0x01, 0x7f, 0xe3, 0xe9, 0x96, 0x8a,
+       0x3d, 0xcf, 0x1b, 0x29, 0x55, 0x39, 0x88, 0xf7, 0x2d, 0x43, 0xff, 0x21,
+       0xe3, 0xa6, 0xd6, 0x3c, 0xb7, 0x19, 0x51, 0x70, 0x8e, 0x6c, 0x9f, 0xbf,
+       0x46, 0xd1, 0x58, 0x3b, 0xbe, 0xdf, 0x22, 0x6b, 0xf7, 0x10, 0xba, 0x9b,
+       0xf7, 0xf3, 0xa3, 0xa2, 0x76, 0x46, 0x55, 0x76, 0xd0, 0x93, 0x54, 0xcf,
+       0x54, 0x63, 0xef, 0x7a, 0x21, 0xd6, 0xae, 0x77, 0xc0, 0x33, 0x5f, 0xfc,
+       0x02, 0x6b, 0xd0, 0x89, 0x1a, 0x23, 0x0d, 0xfc, 0x04, 0x3b, 0xe9, 0x65,
+       0x53, 0x6d, 0x39, 0xe0, 0x1e, 0xb9, 0xc6, 0x9f, 0x60, 0xb3, 0xf4, 0xc0,
+       0x56, 0xb5, 0xf4, 0x5b, 0x1e, 0x7e, 0x8b, 0x77, 0x48, 0x4c, 0xf5, 0xd1,
+       0xac, 0x28, 0x37, 0x8d, 0xbe, 0x79, 0xd6, 0xdb, 0x4b, 0xb1, 0xbb, 0xf5,
+       0x6f, 0xcd, 0x4b, 0x0f, 0x6c, 0x46, 0xb7, 0x28, 0x82, 0xb9, 0x78, 0x86,
+       0xb9, 0x88, 0x39, 0x61, 0x5a, 0x86, 0x6a, 0x3b, 0xe6, 0x54, 0x2b, 0xc3,
+       0xca, 0x83, 0xe4, 0x43, 0x5f, 0xb0, 0x9c, 0x1e, 0xc2, 0xa1, 0x7f, 0xf0,
+       0xa1, 0xf2, 0xa8, 0xf4, 0x14, 0x21, 0x6a, 0x4d, 0x53, 0x2f, 0x4f, 0x17,
+       0xd8, 0x97, 0x94, 0xfe, 0x83, 0x58, 0x3f, 0x7a, 0x53, 0x6c, 0xa6, 0xc7,
+       0xdd, 0x5c, 0xf2, 0xb8, 0xbb, 0x66, 0xd3, 0xf4, 0xc0, 0x9a, 0x22, 0xef,
+       0xd3, 0x52, 0x6d, 0x3c, 0x94, 0x3e, 0x28, 0x7d, 0x88, 0x5c, 0x83, 0x8e,
+       0x6b, 0x49, 0x89, 0x5d, 0x1d, 0xa3, 0xed, 0x46, 0x24, 0x0b, 0x79, 0x7f,
+       0x73, 0xbb, 0xbf, 0x80, 0x9e, 0xfe, 0x1d, 0xcf, 0x01, 0x7d, 0x07, 0x63,
+       0x31, 0x82, 0x42, 0xd4, 0x26, 0xfd, 0xe8, 0xf3, 0xce, 0x73, 0x11, 0x3d,
+       0x4d, 0xde, 0x5f, 0xa4, 0x4f, 0xf0, 0xf3, 0xdc, 0x7c, 0x90, 0x58, 0xfa,
+       0xac, 0x65, 0xe4, 0x58, 0x3d, 0xb2, 0x93, 0xb5, 0x30, 0xac, 0xfb, 0xa9,
+       0xab, 0x57, 0x72, 0x0f, 0xb2, 0x9e, 0xfb, 0xda, 0x23, 0x3c, 0x03, 0x34,
+       0xce, 0x64, 0x45, 0x3d, 0xfd, 0xe0, 0x37, 0x78, 0xee, 0xad, 0x69, 0x8b,
+       0xd3, 0x6f, 0x2f, 0xef, 0x95, 0x0f, 0x4f, 0x59, 0x26, 0x1c, 0xef, 0x77,
+       0x58, 0xef, 0x9a, 0xbd, 0x29, 0xe6, 0xcc, 0xbb, 0xf5, 0x8e, 0x62, 0x5c,
+       0x6a, 0x99, 0x6d, 0xa1, 0x65, 0x03, 0xcf, 0x8e, 0x77, 0x88, 0xa9, 0x47,
+       0x7a, 0x9f, 0x40, 0xb1, 0xdf, 0x9f, 0xce, 0x36, 0xe8, 0xdb, 0x59, 0xef,
+       0x16, 0x89, 0x95, 0x5d, 0xeb, 0x2d, 0x19, 0xcb, 0xa2, 0x8c, 0x85, 0xfe,
+       0xd2, 0xb9, 0xdf, 0x47, 0x5f, 0x92, 0x04, 0xaa, 0xcf, 0x3e, 0x45, 0x5e,
+       0xf9, 0x5a, 0xab, 0x91, 0x1d, 0x62, 0x8c, 0xc7, 0xfe, 0x91, 0x5b, 0x33,
+       0x30, 0x8d, 0x01, 0x1f, 0xfb, 0x4c, 0x59, 0xc0, 0x13, 0x0b, 0x3c, 0x97,
+       0x4e, 0xc7, 0xe8, 0xcb, 0xe9, 0x23, 0x17, 0x34, 0x3c, 0x3a, 0x5b, 0x8e,
+       0xef, 0xcd, 0x86, 0xb1, 0x6f, 0xd6, 0xbb, 0xd7, 0xda, 0x5a, 0xcb, 0xf7,
+       0x3a, 0x92, 0x42, 0xcc, 0x5b, 0xeb, 0xf1, 0x1e, 0x3d, 0xd4, 0x6a, 0xc5,
+       0x87, 0xc8, 0x51, 0xe8, 0x3a, 0x71, 0x53, 0xd3, 0xf2, 0x3d, 0x26, 0x58,
+       0x08, 0x73, 0xbd, 0xd4, 0xc9, 0x67, 0xbc, 0xef, 0x63, 0xf4, 0x8f, 0x19,
+       0x89, 0x41, 0x97, 0x18, 0x74, 0x89, 0xc9, 0x5b, 0x9e, 0x5a, 0x62, 0x39,
+       0x4e, 0x1f, 0xfd, 0xb4, 0x28, 0x62, 0xe3, 0x0b, 0x71, 0xda, 0x7c, 0x95,
+       0xfc, 0x55, 0xa9, 0xa1, 0xc0, 0xdf, 0xe7, 0x22, 0xfa, 0x8e, 0x82, 0xcc,
+       0xff, 0x5f, 0x96, 0xf2, 0xbf, 0x18, 0x2a, 0xea, 0x85, 0xe1, 0xcc, 0xa3,
+       0x01, 0xd3, 0x6e, 0x83, 0xbe, 0xd5, 0x1d, 0x19, 0xd6, 0x90, 0x8d, 0x56,
+       0xc3, 0x18, 0x9c, 0x86, 0xaf, 0x35, 0x0c, 0xb9, 0x76, 0x20, 0xef, 0xad,
+       0x51, 0x88, 0x09, 0xea, 0x9b, 0xcc, 0xc1, 0xbf, 0xe7, 0xd0, 0xea, 0x63,
+       0x3e, 0x1c, 0xc6, 0xbe, 0x8f, 0x7b, 0xf0, 0x71, 0x5e, 0xde, 0x73, 0xc6,
+       0xd2, 0x5d, 0xb8, 0xee, 0x8d, 0xf9, 0x51, 0x3e, 0x85, 0x23, 0xee, 0x25,
+       0x71, 0xa4, 0xae, 0xa8, 0xf1, 0x69, 0x9e, 0x8f, 0xaa, 0x8f, 0x96, 0xbc,
+       0x10, 0x39, 0x5c, 0xc9, 0xf5, 0x5e, 0x4b, 0x7a, 0xde, 0x9f, 0x35, 0x72,
+       0x50, 0x3b, 0x6d, 0x6e, 0xe4, 0xda, 0x6e, 0x8a, 0x89, 0x58, 0xb3, 0x56,
+       0x8c, 0x29, 0xa1, 0x9f, 0x42, 0x19, 0xb1, 0x2b, 0xcf, 0x48, 0x52, 0x3f,
+       0xe4, 0x6f, 0x9e, 0x4f, 0x54, 0x27, 0xe2, 0xe7, 0xba, 0x9c, 0x87, 0x64,
+       0x5b, 0xa8, 0xe4, 0x57, 0x97, 0xbd, 0x48, 0x07, 0x9f, 0x49, 0x2f, 0xf2,
+       0xb9, 0xe8, 0xab, 0xeb, 0xb8, 0xa5, 0x39, 0x59, 0xbe, 0x31, 0xee, 0xca,
+       0xfb, 0xab, 0x16, 0x3a, 0x62, 0x05, 0xe7, 0x18, 0xf9, 0xa9, 0xd6, 0x98,
+       0x3e, 0xca, 0xf1, 0x1c, 0x5d, 0x27, 0x97, 0x0f, 0xd2, 0x2f, 0xf3, 0x9d,
+       0x42, 0x0b, 0xfb, 0x48, 0x2d, 0xdb, 0xc1, 0xb5, 0xfe, 0xb6, 0x59, 0x62,
+       0x7b, 0xd4, 0x7d, 0xc3, 0xa7, 0x9a, 0x72, 0x9d, 0x89, 0xd4, 0x28, 0xe3,
+       0x59, 0xd2, 0xa5, 0xb7, 0x76, 0xa8, 0x6d, 0x09, 0xaf, 0x7f, 0x56, 0x95,
+       0x71, 0x78, 0xf1, 0xb0, 0x4d, 0x6a, 0x96, 0x91, 0x39, 0x87, 0x84, 0x33,
+       0x20, 0xcd, 0xc1, 0x2a, 0x19, 0x43, 0x53, 0x64, 0x80, 0xf1, 0x9c, 0xa8,
+       0xf3, 0xf4, 0x90, 0xcf, 0x38, 0x9f, 0xeb, 0xdb, 0x5a, 0x0e, 0x81, 0xd5,
+       0x49, 0xef, 0xdc, 0x5f, 0xfa, 0x7f, 0x18, 0x2a, 0x7d, 0x88, 0xc4, 0xe2,
+       0xff, 0x02, 0xc7, 0x2a, 0x26, 0xcf, 0x94, 0x1a, 0x00, 0x00, 0x00 };
 
-static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
 
 static struct fw_info bnx2_tpat_fw_06 = {
-       .ver_major                      = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
        .ver_minor                      = 0x0,
-       .ver_fix                        = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x08000860,
+       .start_addr                     = 0x08000888,
 
        .text_addr                      = 0x08000800,
-       .text_len                       = 0x122c,
+       .text_len                       = 0x1a90,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TPAT_b06FwText,
        .gz_text_len                    = sizeof(bnx2_TPAT_b06FwText),
 
-       .data_addr                      = 0x08001a60,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_TPAT_b06FwData,
 
-       .sbss_addr                      = 0x08001a60,
-       .sbss_len                       = 0x34,
+       .sbss_addr                      = 0x080022c0,
+       .sbss_len                       = 0x44,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08001aa0,
-       .bss_len                        = 0x250,
+       .bss_addr                       = 0x08002304,
+       .bss_len                        = 0x450,
        .bss_index                      = 0x0,
 
        .rodata_addr                    = 0x00000000,
@@ -2282,450 +3651,877 @@ static struct fw_info bnx2_tpat_fw_06 = {
 };
 
 static u8 bnx2_TXP_b06FwText[] = {
-/*     0x1f, 0x8b, 0x08, 0x08, 0x21, 0xd3, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
-       0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
-                                                       0xed, 0x5c, 0x6d, 0x6c,
-       0x1b, 0xf7, 0x79, 0x7f, 0xee, 0x85, 0xd2, 0x51, 0x96, 0xe9, 0x93, 0xc2,
-       0x78, 0x6c, 0xc0, 0xa6, 0x77, 0xd6, 0x51, 0x66, 0x20, 0xb5, 0xa0, 0x05,
-       0x36, 0x55, 0x87, 0x43, 0x73, 0x3e, 0x52, 0x2f, 0x4e, 0x5c, 0x57, 0x71,
-       0x94, 0x86, 0x6e, 0x0d, 0x8c, 0xa0, 0xec, 0xd8, 0xeb, 0x5a, 0x2c, 0x1f,
-       0x8c, 0xd5, 0x68, 0xd1, 0x99, 0xa1, 0x68, 0xc7, 0xc9, 0x68, 0x51, 0xa9,
-       0xe5, 0xa8, 0x43, 0x57, 0x80, 0x95, 0x64, 0xcb, 0x29, 0x4e, 0x3a, 0x65,
-       0xcb, 0x16, 0x0c, 0x58, 0x16, 0xcd, 0x2f, 0x5d, 0x3f, 0x74, 0x80, 0x3f,
-       0xec, 0x43, 0x3a, 0xec, 0x83, 0x91, 0x14, 0xad, 0x11, 0x6c, 0x59, 0xb0,
-       0x2f, 0x33, 0xd6, 0x26, 0xb7, 0xdf, 0x73, 0x77, 0x94, 0x95, 0xc4, 0x4e,
-       0xab, 0x7d, 0xbe, 0x07, 0x20, 0xee, 0x7f, 0xff, 0xd7, 0xe7, 0xfd, 0xe5,
-       0x7f, 0x90, 0x06, 0xb7, 0x53, 0x17, 0x85, 0xb0, 0x1d, 0x3f, 0xed, 0x99,
-       0x93, 0x27, 0x3e, 0xf7, 0xf9, 0xcf, 0x0d, 0xa1, 0x39, 0x4c, 0x4a, 0x4c,
-       0xe4, 0xc1, 0x5b, 0x12, 0x51, 0xf9, 0x1d, 0x8a, 0x20, 0x82, 0x08, 0x22,
-       0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20,
-       0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08,
-       0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88,
-       0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82,
-       0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22, 0x88, 0x20, 0x82, 0x08, 0x22,
-       0xf8, 0x9d, 0x20, 0x11, 0xa9, 0xfc, 0xdc, 0x1e, 0xfe, 0x48, 0x11, 0xcd,
-       0xf2, 0x53, 0xb6, 0x41, 0x8a, 0x64, 0x1e, 0x39, 0x34, 0x65, 0x10, 0x59,
-       0xce, 0x80, 0x56, 0xa0, 0xf7, 0xbd, 0x6a, 0x52, 0x26, 0xee, 0xff, 0xb4,
-       0xf9, 0xdb, 0x53, 0xaf, 0x7f, 0x41, 0x7f, 0xaf, 0x25, 0x91, 0xa2, 0x9a,
-       0x6b, 0x79, 0xb5, 0x9f, 0x94, 0x34, 0xd6, 0xfc, 0xd5, 0xee, 0xaf, 0xef,
-       0xa0, 0x44, 0x7b, 0xaf, 0x24, 0xd5, 0x9b, 0xb7, 0xbc, 0xd7, 0x77, 0x27,
-       0xe9, 0x15, 0x57, 0xa5, 0x35, 0x57, 0x16, 0x46, 0x9b, 0x0a, 0x4d, 0x37,
-       0x1d, 0x3a, 0xdd, 0xa8, 0x52, 0xc1, 0xbd, 0x4c, 0xb5, 0x39, 0x35, 0x61,
-       0x2f, 0xff, 0x84, 0xa6, 0xe7, 0x7a, 0x13, 0x85, 0x65, 0x87, 0x6a, 0x8d,
-       0x54, 0xc2, 0x76, 0xd5, 0x44, 0x61, 0x3e, 0x89, 0xf7, 0xde, 0x84, 0x3d,
-       0xaf, 0x57, 0x89, 0x76, 0x62, 0x4e, 0x2a, 0x51, 0x68, 0xea, 0x65, 0xa2,
-       0xbe, 0xdc, 0x75, 0x4a, 0x27, 0x0a, 0xee, 0x82, 0xb0, 0xae, 0x0a, 0x54,
-       0xfb, 0x2c, 0xa9, 0x09, 0xf3, 0xb6, 0xf7, 0x29, 0x43, 0xa5, 0x1e, 0x83,
-       0x76, 0xec, 0x30, 0xe8, 0xd9, 0x94, 0xa9, 0x50, 0xe5, 0x7c, 0x9c, 0x2c,
-       0x9f, 0x26, 0x95, 0x2a, 0xf3, 0x03, 0xea, 0x15, 0x8a, 0x91, 0x95, 0x6c,
-       0xbf, 0x7b, 0x9e, 0x9d, 0xfb, 0x16, 0xff, 0x9d, 0x16, 0xce, 0xa2, 0xc4,
-       0xa8, 0x4b, 0x64, 0x03, 0x2f, 0x3b, 0xf7, 0xbe, 0x17, 0xac, 0x51, 0x70,
-       0xae, 0x9c, 0x18, 0x69, 0x7a, 0x5e, 0x31, 0x87, 0x33, 0x72, 0xed, 0xb5,
-       0x31, 0x6a, 0x25, 0xad, 0xd6, 0x74, 0x2e, 0xbf, 0x23, 0xf8, 0x1b, 0x2f,
-       0xa6, 0x91, 0xdf, 0x2d, 0x12, 0x8d, 0xaf, 0x50, 0x25, 0x49, 0xad, 0x5a,
-       0xee, 0x61, 0x7a, 0x21, 0xd7, 0x4d, 0x67, 0xb1, 0xdf, 0xf3, 0x39, 0xf0,
-       0xd1, 0x38, 0x29, 0xd8, 0xae, 0x9e, 0x22, 0xe1, 0x05, 0xb2, 0xe7, 0xfb,
-       0xd4, 0x02, 0xe1, 0x6c, 0xc3, 0xfb, 0x8c, 0x9d, 0xc3, 0x79, 0x83, 0xff,
-       0xeb, 0x59, 0x49, 0xbd, 0xdc, 0xa2, 0x14, 0xd5, 0x9a, 0x7d, 0xb9, 0x9f,
-       0x93, 0x40, 0x9d, 0x06, 0xf3, 0xc7, 0xa3, 0xc7, 0x70, 0xae, 0x6d, 0xa0,
-       0xdf, 0x25, 0x4b, 0xcc, 0xc4, 0xe8, 0x4f, 0x55, 0x5d, 0xb3, 0xa5, 0x5e,
-       0xaa, 0x9d, 0xef, 0x04, 0x9e, 0x56, 0xaf, 0x88, 0xb9, 0x63, 0x79, 0x4a,
-       0x6e, 0x23, 0x12, 0x24, 0x33, 0x83, 0x7d, 0x89, 0x6a, 0x4e, 0x0a, 0x6b,
-       0x33, 0xc3, 0xef, 0xd0, 0x0e, 0xd2, 0x7a, 0x64, 0x9a, 0x76, 0xba, 0xc0,
-       0xc7, 0x6e, 0xc8, 0x20, 0x33, 0xfc, 0x2e, 0x84, 0x22, 0x1a, 0x99, 0xd4,
-       0x49, 0x2a, 0x0b, 0x05, 0xb7, 0x83, 0xa6, 0x33, 0x0a, 0xd5, 0x81, 0x47,
-       0x3d, 0xf7, 0x35, 0xc1, 0x5e, 0x2e, 0x09, 0x85, 0x65, 0xcc, 0x73, 0x5f,
-       0x0b, 0xff, 0x76, 0xad, 0x1b, 0xfb, 0x88, 0x54, 0xcb, 0x94, 0x30, 0xa6,
-       0xd0, 0x14, 0xe6, 0x4d, 0x81, 0xa6, 0x69, 0x77, 0x07, 0xad, 0x4f, 0x26,
-       0x13, 0xcc, 0xab, 0x1a, 0xc6, 0xbf, 0x32, 0x21, 0x90, 0x6a, 0x58, 0xf4,
-       0xeb, 0x3c, 0x64, 0x38, 0xdf, 0xcb, 0x32, 0xa3, 0xd3, 0x4d, 0x4a, 0x8a,
-       0x94, 0x49, 0x55, 0xe8, 0x32, 0x2d, 0x3a, 0x2c, 0x7f, 0xc8, 0x13, 0xf2,
-       0xae, 0x39, 0xbc, 0x0e, 0x72, 0x6b, 0x16, 0xc1, 0x8f, 0x71, 0xe0, 0x70,
-       0x50, 0x78, 0x6c, 0x71, 0x52, 0x18, 0x73, 0x7f, 0x93, 0xa0, 0xae, 0x93,
-       0xc2, 0x01, 0xf7, 0xa8, 0x10, 0xf2, 0x1e, 0xb2, 0x53, 0xc8, 0x9a, 0x50,
-       0xe8, 0x92, 0x1b, 0xc8, 0x6e, 0x01, 0xfa, 0x69, 0xa9, 0x16, 0xe4, 0x70,
-       0x78, 0x63, 0x0e, 0x8f, 0xd5, 0x97, 0x65, 0x3a, 0xed, 0xf2, 0xfc, 0x3f,
-       0x82, 0x7c, 0x14, 0x72, 0x76, 0x77, 0x53, 0x19, 0xfd, 0xb5, 0x79, 0xb2,
-       0xec, 0x9c, 0x88, 0x35, 0x09, 0x92, 0x8c, 0x9d, 0xf8, 0x75, 0xd1, 0xd4,
-       0x62, 0xa7, 0x25, 0x19, 0x49, 0x9a, 0x72, 0x99, 0x87, 0x78, 0x36, 0xdb,
-       0x7c, 0x64, 0x5c, 0xb9, 0x9f, 0xd7, 0x71, 0xbf, 0x8a, 0xfe, 0xcd, 0x7d,
-       0xac, 0x17, 0x09, 0xe0, 0xa3, 0x67, 0x59, 0x9f, 0x2b, 0xcd, 0x8c, 0x7a,
-       0x80, 0x9f, 0x2e, 0xf3, 0xb6, 0xcd, 0x53, 0x19, 0x73, 0x45, 0xaa, 0x2c,
-       0xe2, 0x9c, 0xf3, 0xbf, 0xf5, 0x62, 0x79, 0xbc, 0x1b, 0x1d, 0xa0, 0x8b,
-       0xcf, 0x95, 0x81, 0x93, 0x48, 0xe5, 0x45, 0xde, 0x8b, 0xc7, 0x09, 0xb2,
-       0xaf, 0xf5, 0x88, 0x94, 0x85, 0x7c, 0x75, 0x9c, 0x13, 0xc7, 0x9c, 0x6e,
-       0xf0, 0x0f, 0xb4, 0x2e, 0xa3, 0x0d, 0xda, 0x45, 0x43, 0xc4, 0xfa, 0x4e,
-       0x9a, 0xca, 0xb1, 0xbe, 0x30, 0x9e, 0xdb, 0xb0, 0x77, 0x9c, 0x8e, 0x9c,
-       0x67, 0x7e, 0xc8, 0xf4, 0x3c, 0x70, 0x9c, 0x9e, 0xd7, 0xd5, 0x22, 0xe9,
-       0xe0, 0x8d, 0x85, 0x79, 0x9d, 0x54, 0x56, 0x3d, 0x6f, 0x24, 0x37, 0xa0,
-       0xbe, 0xec, 0xeb, 0xf9, 0x80, 0x9a, 0x11, 0xa8, 0xda, 0x61, 0xfe, 0x21,
-       0x70, 0xd0, 0x4b, 0x44, 0xfc, 0xfe, 0xcf, 0x64, 0x4d, 0xb2, 0xfd, 0x24,
-       0xf9, 0x2c, 0xd8, 0xd3, 0x4e, 0xe0, 0xcf, 0x36, 0x97, 0x86, 0x5c, 0x52,
-       0xbe, 0x1d, 0x8c, 0xdc, 0xd5, 0x0e, 0xf4, 0xf1, 0x16, 0x6c, 0xa6, 0xb6,
-       0x2c, 0xb3, 0xfd, 0xe5, 0xa0, 0x6e, 0xb4, 0xcd, 0x80, 0x6e, 0xf9, 0xb2,
-       0xd9, 0x8f, 0xfd, 0x3d, 0xef, 0xcb, 0xb9, 0x00, 0xa7, 0xda, 0xbc, 0x85,
-       0xb5, 0x32, 0xf8, 0xae, 0x1f, 0xd7, 0xfc, 0xf3, 0xf7, 0x87, 0xe7, 0xab,
-       0x34, 0x05, 0xbc, 0x6b, 0x4d, 0x89, 0x0a, 0x2a, 0xef, 0xf1, 0x2e, 0xf7,
-       0x97, 0x83, 0xbd, 0xa0, 0xb7, 0xe7, 0xfa, 0xd4, 0x7d, 0xb0, 0x25, 0xb6,
-       0xb1, 0xda, 0x0a, 0xf3, 0x18, 0xfb, 0xe4, 0x99, 0xc7, 0xaa, 0x8f, 0xa3,
-       0x3d, 0xcf, 0x7a, 0x44, 0x69, 0x89, 0x58, 0xcf, 0x2f, 0xb3, 0x2e, 0x41,
-       0x3f, 0x03, 0xbd, 0xaa, 0x38, 0x2c, 0xff, 0x2f, 0x85, 0xf6, 0x29, 0x52,
-       0x7f, 0x86, 0xf5, 0xfd, 0x05, 0x2a, 0xc0, 0xc6, 0xa7, 0x70, 0xd2, 0x22,
-       0x68, 0x5a, 0x68, 0xf6, 0x81, 0x57, 0x6d, 0xbb, 0x83, 0x7c, 0x07, 0xff,
-       0xc7, 0x0b, 0xe6, 0x77, 0x03, 0x27, 0xb6, 0x99, 0x9a, 0x2a, 0x52, 0x15,
-       0x3f, 0xe8, 0x8d, 0xa1, 0x67, 0x6d, 0x49, 0x9f, 0x28, 0x03, 0x37, 0xe8,
-       0x3d, 0xd9, 0x7b, 0x58, 0x9f, 0x31, 0xc7, 0xa5, 0xa1, 0xb6, 0x9d, 0x2d,
-       0x38, 0x2c, 0xa7, 0x2e, 0x9c, 0xdb, 0xc6, 0x49, 0x46, 0x1f, 0xef, 0xa3,
-       0x40, 0xe7, 0xdb, 0x3a, 0xc3, 0xfa, 0xa7, 0x5b, 0xeb, 0xd4, 0x41, 0xd9,
-       0x0c, 0x7c, 0xd9, 0xbc, 0x08, 0xf9, 0xa5, 0xe1, 0x53, 0x64, 0x7a, 0xba,
-       0x99, 0xa4, 0x63, 0x4d, 0xc6, 0xaf, 0x08, 0xbb, 0x83, 0x6f, 0x9b, 0x1f,
-       0x85, 0x9d, 0x8d, 0x0b, 0x23, 0xb0, 0x89, 0x47, 0x17, 0x19, 0x27, 0x8f,
-       0xd8, 0x2e, 0x8b, 0xcb, 0x65, 0x61, 0xd4, 0x2d, 0x09, 0xe3, 0xcb, 0x6c,
-       0x27, 0x6c, 0x23, 0xba, 0xfa, 0x38, 0x31, 0x0d, 0x98, 0xe3, 0xfe, 0x22,
-       0xc1, 0xb6, 0x5a, 0x3b, 0x17, 0x07, 0x1e, 0xdb, 0x80, 0x4f, 0x37, 0x6c,
-       0x0f, 0xfa, 0x65, 0xe8, 0x13, 0xac, 0x33, 0xc5, 0x8c, 0xa1, 0xfd, 0x25,
-       0x7d, 0x9c, 0x0f, 0x23, 0x1b, 0x7c, 0x18, 0x00, 0x4f, 0x3e, 0xcc, 0x87,
-       0xfa, 0xc7, 0xf9, 0x60, 0x55, 0xc1, 0x87, 0x3a, 0xfc, 0x50, 0xdd, 0x65,
-       0x9a, 0x3d, 0x12, 0xf7, 0x10, 0xb4, 0x93, 0xf6, 0x8a, 0x26, 0xeb, 0x28,
-       0xdb, 0x49, 0x46, 0x9b, 0xc6, 0x0e, 0x4b, 0x4e, 0xb7, 0x6f, 0x1b, 0xa3,
-       0x3e, 0x2f, 0x7e, 0x17, 0xbd, 0x4c, 0xdf, 0x1d, 0x9a, 0xc7, 0x17, 0xd9,
-       0xdf, 0x40, 0xcf, 0x33, 0x86, 0x7a, 0x88, 0xee, 0xd0, 0xbd, 0xef, 0x0e,
-       0xdd, 0x38, 0xa7, 0xed, 0x83, 0x98, 0xe6, 0xb6, 0x3f, 0x66, 0x5d, 0x79,
-       0xc3, 0x93, 0x0c, 0x03, 0x32, 0x60, 0x7d, 0x61, 0x1c, 0x74, 0xf5, 0xcb,
-       0xa0, 0xa7, 0x02, 0xbf, 0xc0, 0xb6, 0x54, 0xf6, 0xe7, 0x75, 0x50, 0xb9,
-       0x27, 0x98, 0x3f, 0xd5, 0xf4, 0xfe, 0x4b, 0x34, 0x3f, 0xf0, 0xec, 0xbc,
-       0x11, 0xda, 0xb8, 0x42, 0x7f, 0xb2, 0xa8, 0x97, 0x35, 0xa1, 0x9b, 0xaa,
-       0xf7, 0xc3, 0xaf, 0x34, 0xd9, 0x3e, 0x76, 0xde, 0xc3, 0x97, 0xa5, 0x43,
-       0x5f, 0xf6, 0x3e, 0x78, 0xcf, 0xb1, 0xe7, 0xe8, 0x07, 0xeb, 0x49, 0x7e,
-       0x66, 0xd4, 0x09, 0x2a, 0x71, 0xbc, 0xd9, 0x21, 0xfa, 0xfe, 0xbb, 0x8f,
-       0x63, 0x41, 0x55, 0x36, 0xe3, 0x54, 0xed, 0xa1, 0xaa, 0x64, 0xb2, 0x1d,
-       0xb1, 0x6d, 0xb4, 0xf1, 0xde, 0x1e, 0xc6, 0xdd, 0x41, 0x89, 0x0c, 0x1e,
-       0x47, 0x8c, 0x68, 0x32, 0x0d, 0xef, 0x87, 0xf2, 0x60, 0x7f, 0x4a, 0xb1,
-       0x40, 0xdf, 0xf6, 0xc3, 0x5f, 0x32, 0x3f, 0x37, 0xeb, 0x0a, 0xfb, 0x51,
-       0xd2, 0x44, 0x83, 0xfd, 0x28, 0xa9, 0x92, 0x79, 0x50, 0xb0, 0x16, 0xbf,
-       0x26, 0x58, 0xe0, 0x9b, 0x05, 0xbe, 0x59, 0xe0, 0x9b, 0x0d, 0xbe, 0x15,
-       0x5c, 0xc6, 0x85, 0xf1, 0x08, 0xf6, 0x2f, 0x06, 0xfb, 0x03, 0xc7, 0x9d,
-       0x54, 0xf1, 0xed, 0x9b, 0x69, 0x85, 0x3f, 0xf6, 0x7d, 0xc1, 0xa8, 0x10,
-       0xf8, 0x02, 0xde, 0x6f, 0x1c, 0xeb, 0x1f, 0x47, 0x8c, 0xb3, 0x44, 0xd1,
-       0xb8, 0xc3, 0x8f, 0xfa, 0x26, 0x7e, 0x4c, 0x3b, 0xcc, 0x1f, 0x9e, 0xcf,
-       0x76, 0xec, 0x40, 0xe6, 0x6d, 0x9e, 0xec, 0x07, 0x0e, 0x9d, 0x4c, 0x77,
-       0x48, 0x07, 0xef, 0xdf, 0x1b, 0xee, 0x7f, 0x00, 0x7b, 0xb2, 0xdd, 0xde,
-       0xed, 0x5c, 0x3e, 0x93, 0xe3, 0xe8, 0x27, 0xd1, 0x83, 0x3c, 0x02, 0x7e,
-       0x66, 0x0d, 0x76, 0x76, 0x53, 0x4a, 0xd1, 0xeb, 0xbb, 0x6f, 0x20, 0xb7,
-       0xa0, 0xea, 0x03, 0xa6, 0xa7, 0xc9, 0xe6, 0xfb, 0x5e, 0x3d, 0x0f, 0xdf,
-       0x69, 0xea, 0x29, 0x5b, 0x1a, 0xa4, 0x37, 0xdc, 0x2c, 0xfd, 0x9d, 0x6b,
-       0xd0, 0xdf, 0xba, 0x1a, 0xbd, 0xea, 0xa6, 0xe9, 0x6f, 0xdc, 0x14, 0xfd,
-       0xb5, 0xdb, 0xce, 0x43, 0x92, 0xac, 0x47, 0x89, 0xa2, 0x7b, 0xb7, 0x5c,
-       0x08, 0x3a, 0x8e, 0xbd, 0xec, 0xbc, 0x5c, 0x96, 0x4d, 0x3f, 0x3f, 0x98,
-       0x98, 0x6e, 0x90, 0xb2, 0xd3, 0xa0, 0xed, 0xf7, 0x23, 0xef, 0x49, 0x9a,
-       0xb4, 0xe3, 0x3e, 0x3c, 0x7b, 0x4d, 0xb2, 0x7a, 0xcc, 0x53, 0x9e, 0x68,
-       0xb0, 0x1e, 0x75, 0x0f, 0x4f, 0xe5, 0xe3, 0x8c, 0xfb, 0xc4, 0x34, 0xfc,
-       0x91, 0x8d, 0xb3, 0xaa, 0xd0, 0xc5, 0xaa, 0x7b, 0xe8, 0xfe, 0x20, 0x17,
-       0x7a, 0x2f, 0xcc, 0x89, 0x38, 0xaf, 0x5a, 0x7f, 0x6a, 0xc2, 0x60, 0x3f,
-       0x2b, 0x6c, 0xf2, 0xb3, 0x24, 0x14, 0x41, 0x53, 0x1d, 0xb8, 0x16, 0x41,
-       0xe7, 0x57, 0x5d, 0x45, 0x28, 0x9c, 0xef, 0xa5, 0xe9, 0x45, 0x8e, 0x55,
-       0x3c, 0x4f, 0x09, 0x73, 0x19, 0x7e, 0xef, 0xc0, 0x3b, 0x21, 0x7e, 0x14,
-       0xb6, 0x53, 0x42, 0x7f, 0x73, 0x82, 0x9c, 0x30, 0x17, 0x89, 0xd1, 0x05,
-       0x5f, 0x77, 0xb8, 0xdf, 0x2a, 0xfd, 0xb0, 0xff, 0x4e, 0xff, 0xf9, 0x8d,
-       0xfe, 0x72, 0xe9, 0xeb, 0x1b, 0xfd, 0xef, 0xa8, 0x01, 0x4e, 0xc3, 0xc2,
-       0xe3, 0xee, 0xf3, 0x61, 0xdf, 0x6d, 0xf0, 0xd3, 0xf3, 0xea, 0x88, 0x27,
-       0x35, 0xe3, 0x36, 0x72, 0x1f, 0xf6, 0x29, 0x5b, 0xf1, 0x21, 0x1f, 0xf2,
-       0x1f, 0xaa, 0x2d, 0xb1, 0x9c, 0x14, 0x0a, 0xf6, 0xe4, 0xf1, 0x4e, 0xf8,
-       0x92, 0xdb, 0x68, 0x73, 0xec, 0x6a, 0xfb, 0x31, 0x9e, 0xc3, 0xeb, 0x6f,
-       0xdd, 0x43, 0x96, 0x2a, 0x64, 0xb9, 0x35, 0x79, 0xd5, 0x1a, 0xa7, 0x42,
-       0x9f, 0xd0, 0x3d, 0x6c, 0x43, 0x2e, 0x12, 0xe4, 0x52, 0x83, 0x5c, 0x0a,
-       0xf7, 0x94, 0x0b, 0xce, 0xd8, 0xd0, 0x29, 0xc6, 0xa3, 0x2b, 0x3c, 0x9b,
-       0x14, 0xd9, 0xac, 0x96, 0xea, 0xc6, 0xa7, 0x28, 0x66, 0x30, 0x1e, 0x06,
-       0xf0, 0x38, 0x8a, 0xb5, 0x1c, 0xc3, 0x48, 0x89, 0x99, 0x2c, 0xcf, 0xdc,
-       0x13, 0xb6, 0x71, 0xab, 0xb4, 0xe0, 0xdc, 0x2a, 0x5d, 0x34, 0xf8, 0xfd,
-       0xf6, 0x64, 0x90, 0x37, 0x77, 0x3f, 0x89, 0xbc, 0x19, 0xeb, 0xd9, 0x1f,
-       0x72, 0xff, 0x30, 0xe6, 0x71, 0x7c, 0xa0, 0x43, 0x35, 0xfc, 0xea, 0xfe,
-       0xdc, 0x6b, 0x4f, 0xf0, 0xdc, 0x4e, 0x53, 0x9e, 0xfc, 0x35, 0x9e, 0x1d,
-       0xa6, 0xf6, 0xe4, 0x4f, 0x0d, 0xde, 0x77, 0x78, 0xf2, 0xa2, 0xbf, 0x07,
-       0x62, 0xa6, 0xbf, 0x36, 0xfb, 0x24, 0xaf, 0x7d, 0x0e, 0x3e, 0xf6, 0x0c,
-       0xe2, 0xcb, 0x69, 0x47, 0x3b, 0x54, 0xc1, 0x6f, 0x8a, 0x71, 0x6a, 0xf2,
-       0xb8, 0x85, 0x71, 0x19, 0xb1, 0x90, 0xdb, 0x0a, 0x1d, 0xc3, 0xbc, 0xa7,
-       0x31, 0xef, 0xa8, 0x33, 0x8e, 0xbc, 0xbd, 0x4d, 0xd7, 0xbf, 0xc5, 0x0b,
-       0xf3, 0xec, 0xcf, 0x91, 0xed, 0xaf, 0xfc, 0x7b, 0xdc, 0x86, 0x5f, 0x16,
-       0x57, 0x6e, 0xc6, 0x0b, 0xa0, 0x5b, 0x5a, 0xf9, 0x45, 0xbc, 0x08, 0x3d,
-       0x13, 0x0d, 0x09, 0x7e, 0xf9, 0x33, 0x54, 0x53, 0x3d, 0x7a, 0x19, 0xf1,
-       0xab, 0x96, 0x85, 0xbf, 0x82, 0x34, 0x45, 0x03, 0x7e, 0x4c, 0x25, 0xa5,
-       0xcb, 0x3c, 0xa9, 0x52, 0x57, 0x3e, 0x6e, 0x23, 0xde, 0xd4, 0x54, 0x09,
-       0xfd, 0xfd, 0x78, 0x6e, 0xee, 0xff, 0x65, 0x1c, 0x7e, 0x0b, 0x3e, 0x82,
-       0x14, 0x3b, 0xdf, 0x8d, 0xfd, 0xbf, 0x8d, 0x7e, 0x4c, 0xc8, 0x6c, 0xf4,
-       0x3f, 0x1b, 0xf4, 0xdf, 0x02, 0x2e, 0xbc, 0x8e, 0xe3, 0x27, 0x29, 0x53,
-       0x79, 0x15, 0x38, 0xf0, 0xdc, 0xa4, 0x3f, 0xb7, 0x38, 0xcf, 0x3c, 0xa8,
-       0x96, 0x16, 0x8c, 0x34, 0x15, 0xe6, 0x92, 0x34, 0x3a, 0xa7, 0xd2, 0xd8,
-       0x9c, 0x3e, 0xd1, 0x62, 0xfb, 0x01, 0xcd, 0x84, 0x1c, 0x41, 0x5c, 0x21,
-       0x50, 0xac, 0xa7, 0x9e, 0xa6, 0xbe, 0xd4, 0x31, 0xfa, 0x6f, 0x0f, 0xb1,
-       0x08, 0x71, 0xa8, 0x9b, 0x64, 0x7f, 0x9f, 0x54, 0xfb, 0x4c, 0x96, 0xd1,
-       0x87, 0xce, 0x2d, 0xce, 0xdf, 0x6b, 0x5f, 0x28, 0xf1, 0x4a, 0xea, 0x23,
-       0xfb, 0xbe, 0x1b, 0xee, 0xab, 0x62, 0xdf, 0x34, 0xf6, 0x64, 0x1a, 0xf5,
-       0xf8, 0xc8, 0x79, 0xb2, 0x3a, 0x81, 0x5f, 0x31, 0x83, 0x98, 0x8f, 0x7d,
-       0xce, 0xcc, 0xb1, 0xde, 0xd3, 0x4e, 0xfc, 0x06, 0x63, 0x94, 0xc9, 0x2e,
-       0x23, 0x27, 0x18, 0xf1, 0xf7, 0x08, 0xf2, 0x05, 0x71, 0x65, 0x10, 0xf9,
-       0xda, 0x3b, 0xc0, 0x87, 0xe3, 0x18, 0xd3, 0x2c, 0x83, 0xde, 0x41, 0xe4,
-       0x09, 0x9c, 0xe3, 0x7b, 0xa7, 0xec, 0x1c, 0xda, 0xcb, 0x5a, 0xbc, 0x00,
-       0xdb, 0x16, 0x4d, 0x7a, 0x50, 0xf2, 0x7d, 0x2c, 0xcb, 0x65, 0x10, 0x72,
-       0x62, 0xbc, 0x73, 0x90, 0x13, 0xf3, 0x68, 0x38, 0x5e, 0x6c, 0x32, 0x8f,
-       0x08, 0xf8, 0x68, 0xb0, 0x27, 0xd9, 0xcf, 0xf3, 0xc5, 0x15, 0x0b, 0xf3,
-       0x7e, 0xac, 0x72, 0x2e, 0x66, 0x1b, 0xdc, 0x86, 0xed, 0xac, 0x8c, 0x63,
-       0x2e, 0xb7, 0x1f, 0xc6, 0xbe, 0x7d, 0xb9, 0x1a, 0x75, 0xe4, 0x9e, 0x86,
-       0xdd, 0x8a, 0xf9, 0x01, 0xc4, 0x68, 0x01, 0xb9, 0xa0, 0xe7, 0x75, 0xe4,
-       0xbf, 0x00, 0x7a, 0x98, 0x0e, 0xe8, 0xf5, 0x2c, 0xf3, 0x95, 0xfe, 0x40,
-       0xe4, 0x5c, 0x2d, 0xdf, 0xce, 0x6b, 0x38, 0x9e, 0xf3, 0xf9, 0x88, 0x23,
-       0x8d, 0x3d, 0x88, 0xa5, 0xfe, 0xd9, 0xd0, 0xb1, 0x71, 0x2a, 0x34, 0x3e,
-       0x8b, 0x9c, 0x93, 0x6d, 0x67, 0x9b, 0x60, 0x9f, 0x67, 0x1a, 0x09, 0xb1,
-       0x66, 0x8d, 0x2a, 0x0d, 0x39, 0x6c, 0xbf, 0x8a, 0xb6, 0x12, 0xb6, 0xd7,
-       0xd1, 0xee, 0x0e, 0xdb, 0xd7, 0xd0, 0x56, 0xc3, 0xf6, 0xcf, 0xd0, 0x4e,
-       0x86, 0xed, 0x9f, 0xa3, 0x9d, 0x0a, 0xdb, 0x37, 0xd1, 0x4e, 0x87, 0xed,
-       0x5b, 0x68, 0x6b, 0x61, 0xfb, 0x3d, 0xb4, 0x13, 0xb0, 0x73, 0x03, 0xef,
-       0x37, 0x50, 0x2b, 0x66, 0xf1, 0xfc, 0x57, 0xe0, 0x36, 0x08, 0xde, 0x64,
-       0xc1, 0x8f, 0x5e, 0x8c, 0xe5, 0xd0, 0x87, 0x1c, 0xb1, 0x91, 0xc7, 0xd3,
-       0xc1, 0x18, 0x95, 0x61, 0x7b, 0x18, 0x1f, 0x2f, 0x16, 0x1a, 0x26, 0x9e,
-       0x6c, 0x0f, 0xba, 0x4a, 0xc2, 0x65, 0xd8, 0xb9, 0xef, 0x63, 0x72, 0xb6,
-       0x34, 0x09, 0xdb, 0x9e, 0xa0, 0x7f, 0x74, 0xf7, 0xd3, 0x6b, 0xee, 0x38,
-       0xe2, 0x46, 0x11, 0x71, 0xc3, 0x42, 0xdc, 0x30, 0x11, 0x37, 0x86, 0x11,
-       0x37, 0xf2, 0x88, 0x1b, 0x39, 0xc4, 0x0d, 0xa2, 0x33, 0x7e, 0x8c, 0x4a,
-       0x2a, 0xa8, 0x51, 0x15, 0xcb, 0x2d, 0x82, 0xbf, 0x13, 0x90, 0xcd, 0x24,
-       0x78, 0x7d, 0x38, 0x3e, 0xd2, 0xcc, 0xc3, 0x9f, 0x69, 0xf0, 0x11, 0x69,
-       0xf8, 0xf2, 0x1c, 0x6a, 0x13, 0xa2, 0x2b, 0xb3, 0x1a, 0xfc, 0x8f, 0x47,
-       0x45, 0xc4, 0xfe, 0x69, 0x15, 0xb8, 0x19, 0xbb, 0x7c, 0x9b, 0x91, 0xcc,
-       0x2f, 0xf6, 0x50, 0xd7, 0x20, 0xe8, 0x39, 0x8b, 0xbe, 0x14, 0xf6, 0x63,
-       0xbe, 0xde, 0x2a, 0xd9, 0x86, 0x46, 0x0b, 0x6e, 0x1c, 0xfe, 0x9f, 0xdf,
-       0xe3, 0xcc, 0xe3, 0x43, 0x4f, 0x19, 0x4c, 0x03, 0xea, 0x3c, 0x23, 0xad,
-       0x14, 0x1c, 0x81, 0x24, 0x93, 0x9f, 0xed, 0x1c, 0xe2, 0xcf, 0x90, 0x43,
-       0x74, 0x41, 0x06, 0x55, 0xc4, 0x05, 0x9d, 0xf3, 0x0b, 0xe8, 0xf2, 0x27,
-       0xcd, 0xff, 0x1e, 0xe6, 0xef, 0xc5, 0xd9, 0x3c, 0x8f, 0xcf, 0x39, 0x85,
-       0xfa, 0xc1, 0xea, 0x91, 0x68, 0x3d, 0x25, 0xa1, 0x9e, 0x28, 0xd0, 0x59,
-       0x2a, 0x00, 0x9f, 0x82, 0xdb, 0xbe, 0x07, 0xb0, 0x0e, 0x05, 0xfe, 0x6c,
-       0xe2, 0xd0, 0xb7, 0x0d, 0x0b, 0xeb, 0x18, 0x3f, 0xd6, 0x5b, 0xe0, 0xbe,
-       0xb1, 0xe7, 0x05, 0xec, 0xf9, 0x4f, 0x49, 0xea, 0x9a, 0x0c, 0xfc, 0x91,
-       0x5f, 0xf3, 0xca, 0xc2, 0x48, 0xf3, 0x2c, 0xf8, 0xd3, 0x87, 0x1a, 0x05,
-       0x7e, 0xa4, 0xd4, 0x02, 0x9f, 0xda, 0xf3, 0x5f, 0xc1, 0x7c, 0x7e, 0xf7,
-       0xef, 0x0e, 0x4a, 0xd2, 0xea, 0x12, 0xe6, 0x69, 0xac, 0x3f, 0x25, 0xb9,
-       0xff, 0x86, 0xf7, 0xa2, 0x91, 0xa7, 0x5d, 0xab, 0xbc, 0x2e, 0x4b, 0x7d,
-       0xab, 0x37, 0xbc, 0x9a, 0xa3, 0xd1, 0x62, 0x93, 0xc0, 0xab, 0xf8, 0x6d,
-       0x8b, 0xf4, 0x35, 0x12, 0xf5, 0x59, 0x0b, 0x7a, 0x5a, 0x1c, 0x12, 0xc9,
-       0x1e, 0xea, 0x84, 0x8f, 0x32, 0x68, 0x09, 0x7c, 0xdf, 0x35, 0x63, 0xd1,
-       0x13, 0x43, 0xed, 0x7c, 0x10, 0x51, 0x0f, 0xb8, 0xee, 0x5a, 0xd5, 0x30,
-       0x87, 0x73, 0x71, 0xa6, 0x45, 0x03, 0x2f, 0x85, 0x60, 0x8d, 0x1f, 0xb3,
-       0xb8, 0x8e, 0x05, 0xdf, 0xdc, 0xb5, 0xd2, 0xd5, 0x19, 0xd4, 0x1a, 0x90,
-       0xf3, 0xae, 0x19, 0xae, 0x85, 0xb6, 0x81, 0x2f, 0x31, 0xd8, 0x06, 0xe7,
-       0xf1, 0x08, 0xf4, 0xf0, 0x87, 0x27, 0xe0, 0xf1, 0x6b, 0xcd, 0x13, 0xd0,
-       0xfb, 0x2e, 0x2a, 0xcb, 0x3e, 0x11, 0x9f, 0xc0, 0xe3, 0xff, 0xe4, 0xbc,
-       0x0e, 0xf3, 0xbf, 0x4b, 0xc5, 0xd9, 0x2e, 0xec, 0xb5, 0x9b, 0xa6, 0x93,
-       0x8c, 0x9b, 0x3e, 0x8c, 0x41, 0x2d, 0x06, 0x7e, 0xc6, 0xcd, 0x8f, 0xe6,
-       0x7d, 0x6b, 0xa5, 0x2b, 0x33, 0x6b, 0xa5, 0x6b, 0xa0, 0xbf, 0x6e, 0x70,
-       0x8d, 0x0c, 0x5d, 0x6a, 0x70, 0x6d, 0xcf, 0x79, 0xd1, 0x18, 0x74, 0x64,
-       0xbf, 0x5f, 0x33, 0xdb, 0x8b, 0x39, 0xea, 0x3b, 0x47, 0xaa, 0x68, 0x96,
-       0x84, 0x31, 0xe4, 0x45, 0x23, 0xee, 0x49, 0x7f, 0xee, 0x99, 0x06, 0xd7,
-       0x2b, 0x18, 0x5b, 0x61, 0x5d, 0x18, 0x03, 0x3e, 0x49, 0xba, 0xe8, 0xb2,
-       0x4f, 0x0a, 0xec, 0x78, 0x0c, 0xfc, 0x5a, 0xf0, 0xe9, 0x4a, 0x71, 0x1c,
-       0x47, 0xbe, 0xc1, 0xf2, 0xf9, 0x21, 0xc7, 0x41, 0xa1, 0xd3, 0x6c, 0xfb,
-       0xdb, 0x89, 0x5e, 0xe6, 0x59, 0xa1, 0x01, 0xdf, 0x3f, 0x34, 0x11, 0xe6,
-       0x1c, 0x7f, 0x8f, 0x39, 0x8c, 0x3b, 0xcd, 0x4a, 0x26, 0xce, 0xc8, 0x33,
-       0xcf, 0x38, 0xa7, 0xe4, 0x7d, 0xc1, 0x5b, 0xf0, 0x7d, 0x53, 0x6e, 0xe9,
-       0xc3, 0x74, 0x33, 0x46, 0x95, 0x59, 0xf0, 0x2e, 0x8f, 0x27, 0x9c, 0x6b,
-       0x1d, 0x7c, 0x03, 0x2d, 0xd5, 0x20, 0x9f, 0x3d, 0xc1, 0x31, 0x0d, 0xfe,
-       0x06, 0x36, 0xcd, 0x31, 0x6b, 0xe3, 0xde, 0xc9, 0xf7, 0x25, 0x32, 0x19,
-       0x41, 0xce, 0x2a, 0xe2, 0x2c, 0x3b, 0xcf, 0x7e, 0x10, 0xf8, 0xb8, 0xdf,
-       0xa5, 0xfa, 0x2c, 0xd3, 0x05, 0x1b, 0x4f, 0xb2, 0x2e, 0xfe, 0x7f, 0xf9,
-       0x38, 0xba, 0x45, 0x3e, 0x8e, 0x6e, 0x99, 0x8f, 0x12, 0xf8, 0x58, 0xd9,
-       0xe0, 0xa3, 0x82, 0x3d, 0xf8, 0x3e, 0xe1, 0xab, 0x64, 0x4d, 0x3c, 0x02,
-       0x3f, 0x0c, 0xff, 0xd1, 0x3c, 0x05, 0x9f, 0x70, 0x52, 0xb8, 0xda, 0xf0,
-       0x68, 0x1c, 0xb5, 0xb2, 0x74, 0xff, 0x66, 0xfa, 0x33, 0xa0, 0xff, 0xcf,
-       0x31, 0x5e, 0xa5, 0x6b, 0xb3, 0x94, 0x56, 0xa8, 0x7d, 0x2e, 0xed, 0x92,
-       0xe9, 0x3b, 0x74, 0x75, 0xb6, 0x8b, 0xae, 0xcf, 0x66, 0xc0, 0xeb, 0x2c,
-       0xc5, 0x7a, 0x32, 0xc3, 0x15, 0x18, 0xf1, 0xcf, 0x5a, 0xba, 0xc5, 0xba,
-       0xf8, 0xfb, 0xf3, 0x82, 0xf9, 0x70, 0xd0, 0xe7, 0xc3, 0xd8, 0x47, 0xf8,
-       0x30, 0x7e, 0x4f, 0x3e, 0x1c, 0xfc, 0x18, 0x1f, 0xc6, 0x3f, 0xc6, 0x07,
-       0xe6, 0x01, 0xf3, 0xe2, 0xd1, 0xde, 0xf0, 0xff, 0x1f, 0x7d, 0x82, 0x7d,
-       0x7c, 0x09, 0x74, 0x22, 0xa7, 0xd8, 0x19, 0xe4, 0x50, 0x9c, 0x63, 0xd5,
-       0x0c, 0xe6, 0x57, 0x60, 0xbf, 0x32, 0x72, 0xea, 0x23, 0xa1, 0xfd, 0x16,
-       0x1c, 0xe8, 0x65, 0x23, 0xe6, 0xdb, 0xaf, 0x64, 0xe6, 0xe1, 0x03, 0xaa,
-       0xa5, 0x96, 0xc3, 0xfe, 0x07, 0x6d, 0x87, 0x79, 0xda, 0x0b, 0x5a, 0x12,
-       0x54, 0x99, 0x54, 0x10, 0x5f, 0x87, 0xa1, 0xb7, 0x71, 0xdf, 0x07, 0x4a,
-       0x26, 0xeb, 0xe1, 0x7e, 0xcc, 0x3f, 0x1c, 0xe6, 0x45, 0x88, 0x73, 0x38,
-       0xa3, 0xd6, 0x38, 0x0d, 0xfc, 0xf8, 0x9c, 0x6a, 0xa9, 0xec, 0xf0, 0x9a,
-       0x34, 0x62, 0x21, 0x3f, 0x37, 0xeb, 0xb7, 0xaf, 0xef, 0xf7, 0xd2, 0x71,
-       0xe8, 0x26, 0xeb, 0xb4, 0x82, 0xdc, 0x78, 0x02, 0xf1, 0xc5, 0xd7, 0xd3,
-       0xec, 0x02, 0xb1, 0xdf, 0x7f, 0x06, 0x75, 0xd1, 0x61, 0xfc, 0x34, 0x1a,
-       0x71, 0x03, 0x9b, 0x5a, 0xf2, 0xcf, 0xfc, 0xb0, 0x4f, 0xaa, 0x39, 0xeb,
-       0xc8, 0xdf, 0x0d, 0xec, 0xcb, 0xe7, 0x56, 0xc1, 0x1b, 0x09, 0xe7, 0x72,
-       0x5f, 0x37, 0xe2, 0x00, 0xf8, 0xe4, 0xfe, 0x07, 0xfa, 0x97, 0xe0, 0x1f,
-       0x39, 0x2f, 0x68, 0xe3, 0x8e, 0x1c, 0xc2, 0xe1, 0x78, 0x9d, 0x07, 0xcd,
-       0x9c, 0x63, 0x73, 0x2e, 0x81, 0xfc, 0x63, 0xe9, 0x4d, 0xf4, 0x0d, 0xd3,
-       0xe9, 0xa1, 0x2c, 0xe4, 0xc3, 0x7d, 0x0f, 0x84, 0x7d, 0x3c, 0x8f, 0x94,
-       0x07, 0x4d, 0xfd, 0x07, 0x55, 0xdf, 0xaf, 0x43, 0x0f, 0x51, 0xf7, 0xd5,
-       0x96, 0x90, 0x63, 0x00, 0xa7, 0xca, 0x6a, 0x16, 0xb9, 0x3c, 0xdf, 0xab,
-       0xe9, 0x97, 0x91, 0x07, 0x83, 0x27, 0x0a, 0xf5, 0x1a, 0xa5, 0xd0, 0x0f,
-       0xe7, 0x40, 0x1f, 0xdf, 0x3d, 0xf5, 0x21, 0xf7, 0x91, 0xc0, 0x08, 0xd8,
-       0xe9, 0xaa, 0x44, 0x7b, 0xe5, 0x01, 0xb5, 0x46, 0xff, 0x80, 0xb9, 0x32,
-       0x95, 0x57, 0x39, 0x87, 0x90, 0xe9, 0xc8, 0x2a, 0xd1, 0x5b, 0x33, 0xec,
-       0x97, 0x19, 0xd8, 0x2f, 0xb3, 0x7f, 0x7d, 0xd0, 0x1f, 0x7b, 0x6b, 0x06,
-       0x35, 0xf8, 0xcc, 0x00, 0xc7, 0xb0, 0x75, 0x11, 0xbc, 0x44, 0xee, 0xc3,
-       0xf9, 0xf9, 0x5d, 0xee, 0x98, 0xda, 0xf7, 0x4b, 0x0a, 0x55, 0x66, 0xf8,
-       0x6e, 0x49, 0xc6, 0xf9, 0x5c, 0x5b, 0x6c, 0x03, 0x7e, 0x02, 0xa1, 0xee,
-       0x12, 0x38, 0xa6, 0x09, 0xd0, 0xa1, 0x5d, 0x90, 0x3d, 0xf8, 0x1f, 0xb6,
-       0xdb, 0xfa, 0xf4, 0x2f, 0xd0, 0x27, 0x9e, 0x27, 0x6f, 0xc2, 0x25, 0x33,
-       0x6b, 0x8b, 0x1c, 0x1f, 0x3e, 0x0d, 0xdb, 0xb3, 0xe2, 0x63, 0xcd, 0x0e,
-       0x6a, 0xf5, 0xb2, 0x3d, 0xb0, 0x5e, 0x5c, 0x66, 0x9d, 0xc0, 0x19, 0xd0,
-       0xa1, 0x19, 0xae, 0xe7, 0x65, 0xcc, 0xbb, 0x2f, 0x9c, 0xc7, 0xfc, 0xfe,
-       0x1e, 0x4d, 0x0f, 0xa9, 0x42, 0x59, 0x0d, 0xe2, 0x45, 0x6d, 0xa8, 0x03,
-       0x63, 0x22, 0x1d, 0x7c, 0x38, 0x8f, 0xb5, 0x9c, 0x53, 0xc5, 0x85, 0xc0,
-       0x6f, 0x71, 0x1f, 0xdf, 0xd7, 0xa9, 0x54, 0xbe, 0xd4, 0x4b, 0x95, 0x4b,
-       0x0a, 0xf8, 0x02, 0x44, 0x17, 0x82, 0x7d, 0xd8, 0x17, 0x1c, 0x87, 0xdc,
-       0xc4, 0x73, 0x0a, 0xc5, 0xce, 0x21, 0x87, 0xbc, 0xd0, 0x45, 0x1d, 0x17,
-       0xfa, 0x49, 0xba, 0xa0, 0x73, 0x7e, 0xa8, 0x9d, 0x81, 0x0c, 0x8f, 0x50,
-       0x9e, 0x9e, 0x73, 0x07, 0x39, 0xc7, 0xc3, 0x39, 0x5c, 0xe7, 0x25, 0x49,
-       0x42, 0xf2, 0x2f, 0xbe, 0x68, 0xd1, 0x8b, 0x43, 0xc0, 0x2b, 0x8f, 0xf6,
-       0x8f, 0x91, 0xc7, 0xbb, 0x23, 0xf7, 0x71, 0xcc, 0x96, 0xcd, 0x3e, 0xc8,
-       0x16, 0x74, 0xe5, 0x1e, 0xf2, 0xef, 0x44, 0x5f, 0x1c, 0x62, 0x7a, 0x34,
-       0xd0, 0x52, 0x87, 0xae, 0xf3, 0x3d, 0x57, 0x17, 0xd9, 0x32, 0xeb, 0x32,
-       0xf2, 0xaa, 0x0b, 0x75, 0x9a, 0x6a, 0xe8, 0x90, 0x59, 0x1f, 0xf4, 0x02,
-       0x32, 0x4b, 0x73, 0x3f, 0xef, 0x2d, 0x84, 0xfb, 0xde, 0xd1, 0xf7, 0x17,
-       0xef, 0xad, 0xef, 0x3e, 0xd4, 0x9b, 0x8f, 0xc0, 0x67, 0xa3, 0x2e, 0x32,
-       0xe0, 0xd3, 0x55, 0xe4, 0x72, 0x06, 0xbf, 0x07, 0x77, 0x95, 0x15, 0xe4,
-       0x85, 0xfc, 0x5e, 0x6b, 0xdd, 0xcd, 0x77, 0x07, 0xf6, 0x7d, 0x06, 0x3c,
-       0xba, 0x32, 0xf7, 0x00, 0x5d, 0x9d, 0x53, 0xe8, 0x5a, 0x43, 0xcf, 0x16,
-       0xa8, 0x83, 0xaa, 0xc9, 0x34, 0x5d, 0x5f, 0x6a, 0xe7, 0x93, 0x22, 0xf4,
-       0xc4, 0x22, 0xce, 0xcd, 0xaf, 0x2c, 0x55, 0x4b, 0x37, 0x76, 0xa7, 0x49,
-       0x7e, 0x09, 0xb6, 0xfd, 0x92, 0xae, 0xd5, 0xc0, 0xe7, 0xba, 0xe1, 0xa2,
-       0x56, 0xe3, 0x3a, 0x32, 0x05, 0xbb, 0xd3, 0x53, 0x2d, 0xca, 0x90, 0xb4,
-       0xa0, 0xd0, 0xaf, 0x66, 0x74, 0x8d, 0x75, 0xee, 0xa2, 0x81, 0x7e, 0x37,
-       0x7e, 0x7b, 0x3d, 0xd0, 0x43, 0xf4, 0xf5, 0xa3, 0xbe, 0xd5, 0xb3, 0x9a,
-       0xd8, 0x4d, 0x6f, 0x43, 0x27, 0xca, 0x7e, 0xdf, 0x47, 0xf7, 0xbc, 0x1e,
-       0xee, 0x59, 0x2d, 0x5d, 0xe1, 0x3a, 0x68, 0x86, 0x75, 0xbe, 0x17, 0xfe,
-       0x03, 0xef, 0x6e, 0x07, 0x95, 0x27, 0x11, 0xa3, 0x66, 0x1e, 0xa5, 0xc2,
-       0x90, 0x18, 0xd0, 0xed, 0xf3, 0x82, 0xfb, 0xf8, 0x7e, 0xb2, 0x76, 0x1f,
-       0xdb, 0xb2, 0xb8, 0x0a, 0xbd, 0x3a, 0xc8, 0x7a, 0x80, 0xdc, 0x0e, 0x39,
-       0x04, 0xfb, 0x4e, 0x09, 0x39, 0x44, 0xc1, 0x0d, 0x74, 0xa3, 0x75, 0x30,
-       0x49, 0xc7, 0x5e, 0x62, 0x19, 0x61, 0x6c, 0x43, 0xef, 0x36, 0xee, 0xc4,
-       0x31, 0x66, 0xd0, 0xf1, 0xef, 0xb7, 0x73, 0x4a, 0xb6, 0xbd, 0x34, 0xe4,
-       0xa1, 0xa3, 0xf6, 0xe8, 0x53, 0x2b, 0xbe, 0x4f, 0x81, 0x4e, 0xa4, 0x02,
-       0x19, 0xd4, 0x30, 0x36, 0xed, 0x4e, 0xc2, 0x27, 0xc6, 0xe8, 0xe6, 0xa4,
-       0x05, 0x9d, 0x68, 0x01, 0x87, 0xc3, 0x71, 0xbe, 0x4b, 0xb8, 0x39, 0x59,
-       0xc4, 0xfb, 0x61, 0x3f, 0xf7, 0x97, 0xf6, 0x40, 0x97, 0xdc, 0x07, 0xc2,
-       0xfc, 0x9c, 0xcf, 0xd3, 0x84, 0xda, 0xac, 0x2e, 0x4c, 0xcf, 0x7a, 0x34,
-       0x9a, 0xeb, 0x4b, 0x5d, 0xa5, 0x4e, 0xff, 0xce, 0xd8, 0xf7, 0x9b, 0xfe,
-       0x9c, 0x5d, 0x18, 0xff, 0x00, 0x3a, 0x85, 0x27, 0xe2, 0xf5, 0xe9, 0x66,
-       0x35, 0xd5, 0x41, 0xac, 0x53, 0x24, 0x2c, 0x18, 0xec, 0x3b, 0x04, 0xba,
-       0xea, 0xdf, 0x47, 0x13, 0x15, 0x9d, 0xd7, 0x99, 0x6e, 0x61, 0xb1, 0xc5,
-       0x6b, 0x58, 0xce, 0xbc, 0x46, 0xa2, 0x9b, 0x49, 0xd8, 0xe5, 0x9e, 0x3d,
-       0x7e, 0xbd, 0xf8, 0xf8, 0x10, 0xe3, 0xda, 0x0d, 0x99, 0x42, 0xbf, 0x50,
-       0xdb, 0x94, 0x83, 0xbe, 0x59, 0xae, 0x4d, 0xa7, 0xf9, 0xde, 0x23, 0xef,
-       0xeb, 0x5a, 0xa8, 0x1f, 0x1f, 0xd7, 0xb5, 0xe7, 0xb0, 0xf6, 0x2d, 0xf6,
-       0xab, 0x90, 0x75, 0xe0, 0x23, 0xbe, 0x41, 0x6f, 0xcd, 0x55, 0xb3, 0xfc,
-       0xcd, 0xa3, 0x35, 0x21, 0xa0, 0x16, 0x3f, 0x4e, 0x6f, 0xcf, 0x3d, 0x4b,
-       0xbf, 0x9c, 0x65, 0xdd, 0x31, 0x68, 0x14, 0xfa, 0x74, 0x94, 0xe4, 0xec,
-       0x69, 0x1a, 0x50, 0xaf, 0xfb, 0xb5, 0x8d, 0x9e, 0xf3, 0x6b, 0x3a, 0x33,
-       0x4b, 0xc5, 0xc6, 0x40, 0xea, 0x1a, 0xfa, 0xca, 0x93, 0xba, 0xb6, 0x8e,
-       0xdc, 0xa3, 0xd0, 0xfc, 0x80, 0xef, 0x6c, 0xb2, 0x35, 0xd8, 0xde, 0x22,
-       0x6a, 0x9b, 0xb7, 0x9d, 0xbb, 0xe9, 0x2c, 0xd7, 0x56, 0x81, 0xff, 0x5e,
-       0x33, 0x50, 0x63, 0xac, 0xaa, 0xa1, 0x0e, 0x31, 0x70, 0x9d, 0xc1, 0xf1,
-       0x07, 0x4f, 0x37, 0x06, 0x9f, 0xb2, 0x1f, 0x7c, 0x67, 0xd9, 0x42, 0xfe,
-       0xab, 0xfc, 0x8d, 0x0a, 0xf2, 0x5f, 0x5d, 0xfe, 0x40, 0xeb, 0x65, 0x3f,
-       0x6b, 0x80, 0x96, 0x41, 0x3a, 0x33, 0xcf, 0xf2, 0x47, 0xec, 0xf5, 0xed,
-       0x34, 0x0d, 0xfe, 0x72, 0x7c, 0x19, 0xa4, 0x5f, 0x2d, 0x15, 0xfd, 0xfb,
-       0x6b, 0x1b, 0xb9, 0xd6, 0x11, 0x67, 0x12, 0xf5, 0xfa, 0x77, 0x40, 0x2f,
-       0xce, 0x1e, 0xda, 0x8d, 0xa7, 0x0a, 0x9b, 0xdc, 0x72, 0x9e, 0x23, 0x07,
-       0x79, 0xce, 0xde, 0x2d, 0xe6, 0x39, 0x7b, 0xb7, 0x92, 0xe7, 0xc8, 0x9d,
-       0xe0, 0xab, 0xd6, 0xbb, 0x65, 0xdc, 0xa4, 0x00, 0xb7, 0x03, 0x5b, 0xc4,
-       0xed, 0xc0, 0x56, 0x70, 0x93, 0x3a, 0xcd, 0xbf, 0x40, 0x8c, 0x35, 0x10,
-       0xdb, 0xe0, 0xd7, 0x86, 0xfa, 0x59, 0x7f, 0x80, 0xa3, 0x8f, 0xeb, 0xef,
-       0x8b, 0xa7, 0x18, 0xe0, 0xf9, 0xd8, 0x16, 0xf1, 0x7c, 0x6c, 0x2b, 0x78,
-       0x8a, 0x9d, 0x26, 0xe3, 0x28, 0xc3, 0xd7, 0x70, 0x6d, 0x83, 0xd8, 0x3c,
-       0x24, 0x87, 0xba, 0x2e, 0x87, 0x75, 0x0e, 0x03, 0x7c, 0x50, 0xaf, 0x46,
-       0x4b, 0x4c, 0xcb, 0x46, 0xdf, 0x9d, 0x3a, 0x4b, 0x32, 0x5b, 0xa5, 0x4a,
-       0x83, 0xef, 0x95, 0xfb, 0xb0, 0x0f, 0xf7, 0xf1, 0x37, 0x2a, 0x8b, 0x64,
-       0xc4, 0xf7, 0xe7, 0x9a, 0x77, 0xa7, 0xf5, 0x2a, 0x68, 0x9d, 0x0a, 0x69,
-       0xad, 0xf8, 0xb9, 0xe0, 0xbe, 0x4d, 0xb9, 0x60, 0x40, 0xe3, 0x08, 0x68,
-       0x2c, 0x86, 0x34, 0x3e, 0xdd, 0x60, 0xda, 0xf6, 0xf9, 0xb4, 0x2d, 0x6d,
-       0xa2, 0x6d, 0xe4, 0x9e, 0xf9, 0x1f, 0xe3, 0x81, 0x5a, 0x1a, 0xb9, 0xd7,
-       0x6b, 0x4d, 0xd4, 0xd2, 0x4d, 0xd4, 0xd2, 0xd0, 0xf7, 0x57, 0x9b, 0xa8,
-       0xa5, 0x9b, 0xa8, 0xa5, 0x61, 0x07, 0xaf, 0xc0, 0x56, 0x82, 0x3b, 0xdc,
-       0x12, 0x71, 0x0d, 0xee, 0xd7, 0xe3, 0x14, 0xe4, 0x39, 0x05, 0xc4, 0xf0,
-       0xa3, 0xc8, 0xf1, 0xd8, 0x6e, 0x4f, 0x13, 0xc7, 0x04, 0x3d, 0x87, 0x9a,
-       0x2f, 0x5b, 0x25, 0x33, 0x5e, 0x9c, 0x1f, 0x50, 0x97, 0x02, 0xfb, 0xd6,
-       0x5a, 0xc4, 0x71, 0x70, 0x20, 0x85, 0x08, 0xa9, 0xb2, 0x5f, 0xb0, 0x73,
-       0x4c, 0xe7, 0x76, 0xf0, 0x10, 0xbe, 0xdb, 0x60, 0x1f, 0xc6, 0xbe, 0xb4,
-       0x4e, 0x0b, 0x8d, 0xf0, 0x1b, 0x9a, 0xcc, 0xfd, 0xfc, 0xce, 0x31, 0xb7,
-       0xcf, 0xf7, 0x69, 0x76, 0xb6, 0x0f, 0x71, 0x80, 0xfb, 0x15, 0xf8, 0x35,
-       0xe8, 0xca, 0x52, 0x1b, 0x17, 0x19, 0xeb, 0x55, 0xaa, 0xcf, 0x07, 0x31,
-       0x7c, 0xca, 0xe0, 0x38, 0x87, 0xf8, 0xbe, 0xc4, 0xdf, 0xb0, 0x10, 0xeb,
-       0x97, 0xae, 0x68, 0x32, 0x6a, 0xc7, 0x3a, 0x7f, 0xa3, 0x1d, 0xec, 0xc3,
-       0xf9, 0x1d, 0xfe, 0x1d, 0xed, 0x51, 0xff, 0xae, 0xcd, 0xa0, 0x23, 0xad,
-       0x80, 0x16, 0xdb, 0xc8, 0xd0, 0xc8, 0x2c, 0xdf, 0x35, 0x51, 0x8f, 0x68,
-       0xca, 0x54, 0x75, 0xf8, 0x7e, 0x68, 0xe3, 0xbb, 0x49, 0x76, 0x91, 0xeb,
-       0x4f, 0x23, 0xb8, 0xff, 0x3c, 0xed, 0xbc, 0xc9, 0xf7, 0x9f, 0xe1, 0x3a,
-       0x8d, 0xde, 0x70, 0x33, 0x34, 0x8e, 0xf8, 0x5a, 0x6c, 0x68, 0xf0, 0x6f,
-       0xbe, 0x3c, 0x39, 0xa7, 0xad, 0xc6, 0x42, 0x99, 0x8e, 0x84, 0x32, 0xad,
-       0x34, 0xd6, 0x80, 0xdf, 0x0d, 0xef, 0x8f, 0x43, 0x99, 0xee, 0x3a, 0x47,
-       0xda, 0xd5, 0x1c, 0xcb, 0x95, 0x65, 0x19, 0xc8, 0x75, 0x7c, 0xb1, 0x24,
-       0x14, 0x21, 0xd3, 0x51, 0x5f, 0xa6, 0x32, 0xc7, 0x05, 0xec, 0x95, 0x83,
-       0xfc, 0xd9, 0x8f, 0xe1, 0xe9, 0xb0, 0x8c, 0xb9, 0xde, 0xe0, 0x58, 0x98,
-       0xa4, 0x4b, 0x9b, 0xe4, 0x5c, 0xbc, 0xa7, 0x0e, 0xe7, 0xa9, 0xff, 0x9c,
-       0x16, 0xde, 0x9b, 0x66, 0x21, 0xc7, 0x76, 0x2e, 0xf6, 0x23, 0x81, 0x8c,
-       0xf6, 0x9d, 0x6e, 0xbb, 0xef, 0xe5, 0x4d, 0x7d, 0xed, 0x67, 0x9b, 0x56,
-       0xc4, 0xb7, 0x0d, 0xde, 0xf3, 0x1d, 0xe4, 0x9d, 0x7e, 0xc9, 0x1f, 0x53,
-       0x31, 0xd6, 0x4b, 0x85, 0x25, 0x83, 0xac, 0x16, 0xcf, 0x91, 0x49, 0x34,
-       0xda, 0x72, 0xea, 0xa4, 0xf5, 0x30, 0xc6, 0x2d, 0x34, 0x3c, 0xef, 0xa7,
-       0xd0, 0x9d, 0x8b, 0x5c, 0x77, 0x3b, 0xbf, 0xf1, 0xd6, 0x93, 0xc8, 0x21,
-       0x37, 0xce, 0xfc, 0xe6, 0xfd, 0xd4, 0xa5, 0xab, 0x88, 0x09, 0x74, 0xc6,
-       0x09, 0x51, 0x22, 0x1e, 0xe7, 0x3e, 0xfe, 0x06, 0xef, 0x79, 0x17, 0x8d,
-       0x3b, 0x78, 0x75, 0x99, 0xc7, 0x69, 0xdf, 0x39, 0xf6, 0xff, 0x3f, 0xd0,
-       0x2e, 0x1a, 0xd6, 0x9e, 0x38, 0xf2, 0xe7, 0xeb, 0xc4, 0xb1, 0x4f, 0x4e,
-       0x14, 0x9b, 0xba, 0x7a, 0x09, 0x6b, 0x8b, 0x8e, 0xc2, 0xdf, 0xd6, 0xf9,
-       0xfb, 0xa8, 0x76, 0x89, 0xda, 0xf7, 0x65, 0x90, 0xa7, 0xa3, 0xf2, 0x77,
-       0x52, 0xb5, 0x8a, 0xd8, 0x52, 0x70, 0x92, 0x98, 0xaf, 0x62, 0x2e, 0xc7,
-       0x05, 0x8f, 0x14, 0xd8, 0x50, 0xc1, 0x49, 0x27, 0xc6, 0x9a, 0x9e, 0xa7,
-       0x7c, 0x5e, 0xa0, 0x87, 0x32, 0x29, 0x1a, 0x73, 0xf8, 0xfe, 0xf7, 0x9b,
-       0xf4, 0x36, 0xec, 0xac, 0x78, 0x9e, 0x6b, 0x26, 0xf6, 0x29, 0x78, 0x77,
-       0xf8, 0xbe, 0xea, 0x14, 0x3d, 0xb4, 0x47, 0xcf, 0x5e, 0x22, 0xe0, 0xb3,
-       0x42, 0xfd, 0x48, 0x72, 0x53, 0xc7, 0xfd, 0xef, 0x6d, 0x8c, 0x6b, 0x9a,
-       0x96, 0xc0, 0x1b, 0xa7, 0x99, 0xa4, 0x95, 0x66, 0x8a, 0x56, 0xa1, 0x1f,
-       0xdb, 0xcc, 0x32, 0x7d, 0x03, 0x78, 0x2b, 0x66, 0x95, 0x94, 0x8c, 0xb5,
-       0xaf, 0x0b, 0x78, 0x67, 0x05, 0x3d, 0x15, 0x17, 0x18, 0x77, 0x5d, 0x2d,
-       0x03, 0x6f, 0xd6, 0xd1, 0x51, 0xa7, 0x9b, 0x8e, 0x61, 0xed, 0x7e, 0xe4,
-       0x1f, 0xdf, 0x72, 0xa8, 0x2c, 0x99, 0x29, 0x3a, 0x80, 0xf3, 0x8e, 0x36,
-       0x38, 0x57, 0x3b, 0x02, 0x5f, 0x23, 0xd0, 0xa3, 0x19, 0x8f, 0x1e, 0xdd,
-       0xa3, 0x5b, 0x71, 0x01, 0x7b, 0xae, 0xb0, 0x9e, 0xa0, 0xdf, 0x09, 0xce,
-       0x8d, 0xad, 0xf8, 0xba, 0x08, 0x7f, 0xfa, 0x0c, 0x65, 0xce, 0xad, 0xe5,
-       0xa6, 0x90, 0x9f, 0x8f, 0x36, 0xe9, 0x8b, 0x31, 0x9c, 0xf7, 0x36, 0xf8,
-       0x34, 0xea, 0xc8, 0x02, 0xf3, 0xe9, 0x58, 0xc0, 0x27, 0x8c, 0xf1, 0xb7,
-       0x23, 0xce, 0xd1, 0xf8, 0xec, 0x13, 0x74, 0xb6, 0xc1, 0x77, 0xdd, 0x27,
-       0xe8, 0x4a, 0xe3, 0x11, 0xba, 0x98, 0xe3, 0x5c, 0x07, 0xfb, 0xf8, 0x67,
-       0xa0, 0xcf, 0x3f, 0xa3, 0x9b, 0x8e, 0xfb, 0x72, 0xfa, 0x3f, 0xc3, 0x06,
-       0xd0, 0x70, 0x4c, 0x57, 0x00, 0x00, 0x00 };
+       0xad, 0x7b, 0x7f, 0x70, 0x9b, 0x75, 0x7a, 0xe7, 0xe7, 0xd5, 0x0f, 0x5b,
+       0xb2, 0x65, 0x59, 0x0e, 0x4a, 0x90, 0x77, 0xbd, 0x8d, 0x5e, 0xf4, 0xca,
+       0x16, 0xd8, 0x49, 0x5e, 0x25, 0xce, 0xc6, 0x59, 0xab, 0x44, 0x75, 0x1c,
+       0xdb, 0x71, 0x1c, 0x30, 0xc1, 0xdd, 0x3a, 0x3d, 0xae, 0xf1, 0x25, 0x26,
+       0x31, 0x10, 0xc0, 0xe9, 0xa6, 0x7b, 0x62, 0x8f, 0xd6, 0xc2, 0x76, 0x82,
+       0x43, 0x64, 0xbf, 0xce, 0x2a, 0x59, 0x87, 0x4e, 0x67, 0xd6, 0x60, 0x07,
+       0x07, 0x56, 0x8e, 0x60, 0xdb, 0x6b, 0xbb, 0x73, 0xbb, 0x83, 0x8e, 0x40,
+       0xf0, 0x72, 0x01, 0xb6, 0xfd, 0xa3, 0x47, 0x6f, 0xee, 0xda, 0xcc, 0x02,
+       0x59, 0xa0, 0x4b, 0xa0, 0x3b, 0x7b, 0x53, 0x67, 0x0b, 0xbc, 0xf7, 0x79,
+       0xde, 0x57, 0x4a, 0xb2, 0x94, 0x4e, 0x67, 0x3a, 0xe7, 0x19, 0x8f, 0xac,
+       0xf7, 0xc7, 0xf3, 0x7d, 0x7e, 0x3f, 0x9f, 0xe7, 0xf9, 0x7e, 0x5d, 0x0f,
+       0x54, 0xa0, 0xf8, 0x53, 0xc5, 0xdf, 0xe6, 0xe1, 0xd4, 0xe1, 0x8d, 0x6b,
+       0xf5, 0xb5, 0xd6, 0x05, 0x37, 0x5c, 0x72, 0xf3, 0xab, 0x0a, 0x30, 0xf0,
+       0x01, 0xfe, 0x5d, 0x3f, 0x5f, 0xf9, 0xf7, 0xbd, 0x66, 0xfd, 0x38, 0x81,
+       0x40, 0x89, 0x2f, 0xf9, 0x85, 0xc7, 0x91, 0x40, 0x6b, 0x9b, 0x06, 0x8f,
+       0x33, 0xf1, 0x67, 0x89, 0x7d, 0x1a, 0x90, 0xcc, 0x35, 0x86, 0xb7, 0xe2,
+       0x53, 0x33, 0x1d, 0x74, 0x41, 0xae, 0x7f, 0x25, 0xf1, 0xc9, 0xc8, 0x8f,
+       0x36, 0xa9, 0x1f, 0xcf, 0x3a, 0xe1, 0x09, 0x24, 0x4e, 0x23, 0x50, 0x0f,
+       0x4f, 0x1d, 0xdf, 0xf9, 0x93, 0x86, 0x6a, 0x27, 0xfc, 0x25, 0x5a, 0x2d,
+       0x18, 0x33, 0x90, 0xf6, 0x24, 0x86, 0x51, 0xbe, 0x11, 0x78, 0x37, 0x13,
+       0xd5, 0xc7, 0x80, 0x69, 0x47, 0x22, 0x1a, 0x7e, 0x09, 0x3a, 0x8e, 0xe4,
+       0xc3, 0x68, 0xe7, 0xef, 0x76, 0xe3, 0x33, 0x33, 0xec, 0x46, 0xda, 0xc9,
+       0xe7, 0xf6, 0x36, 0x03, 0xdb, 0x32, 0x3a, 0x8e, 0x1a, 0xf0, 0xd4, 0x26,
+       0x1e, 0xc5, 0x66, 0x7e, 0xfa, 0x13, 0x29, 0xbc, 0x31, 0x19, 0x09, 0x3f,
+       0x03, 0xb5, 0x5f, 0x73, 0xaa, 0x29, 0xa0, 0x71, 0x68, 0x50, 0x51, 0x07,
+       0xde, 0x54, 0xd4, 0xde, 0x49, 0x05, 0x1e, 0x85, 0xcf, 0x35, 0xe6, 0xe4,
+       0x33, 0x85, 0xdb, 0x72, 0x1e, 0x5c, 0x72, 0xca, 0xfa, 0xbf, 0x49, 0x7d,
+       0x2b, 0x70, 0x69, 0x2d, 0x18, 0x27, 0x0f, 0xee, 0x84, 0x82, 0xa7, 0x9b,
+       0xa3, 0xa1, 0x51, 0xc8, 0xfd, 0x30, 0xb6, 0xe6, 0xe5, 0x53, 0xa5, 0xd4,
+       0xa6, 0x39, 0xae, 0x9b, 0xe6, 0x19, 0xbd, 0x1c, 0xe9, 0x80, 0x1a, 0x02,
+       0x14, 0x8c, 0xea, 0x0e, 0x24, 0x03, 0x6d, 0x61, 0x17, 0xd4, 0xd0, 0xbd,
+       0xf8, 0x67, 0xca, 0x9c, 0x8c, 0xb9, 0x61, 0x3f, 0x3f, 0x80, 0x72, 0x14,
+       0x02, 0xb6, 0xd6, 0x9e, 0xce, 0x98, 0xe6, 0x05, 0xcd, 0x85, 0x33, 0xd4,
+       0xcf, 0x68, 0xee, 0x9f, 0xcd, 0x02, 0x75, 0x33, 0xae, 0x95, 0xd6, 0xf7,
+       0x60, 0x36, 0x60, 0x9a, 0x73, 0xbc, 0x77, 0x34, 0x57, 0xd2, 0xb3, 0x69,
+       0x3a, 0x34, 0xd3, 0xdc, 0xa7, 0xfd, 0xca, 0xdc, 0xfb, 0x6b, 0xcf, 0x9a,
+       0xe6, 0x13, 0xfa, 0x4d, 0x38, 0x9b, 0x6d, 0x57, 0xba, 0x17, 0x56, 0xf9,
+       0xb7, 0xcf, 0x98, 0xb8, 0xa0, 0x23, 0xe0, 0x48, 0x74, 0x28, 0xdb, 0x17,
+       0xba, 0x94, 0x6d, 0xf9, 0x5d, 0x4a, 0xc7, 0xdc, 0xef, 0x2a, 0x5d, 0x0b,
+       0x03, 0x4a, 0x67, 0x3e, 0x84, 0x79, 0x23, 0x88, 0x39, 0xa3, 0x5f, 0x69,
+       0x5f, 0xe8, 0x53, 0x6c, 0x39, 0x52, 0x4a, 0x5b, 0xbe, 0x44, 0xeb, 0xba,
+       0x1e, 0xb7, 0x67, 0x12, 0x98, 0x30, 0xca, 0xb9, 0xce, 0xb2, 0xf9, 0xa3,
+       0x86, 0x65, 0xca, 0xa9, 0xe3, 0x58, 0xfe, 0x09, 0xec, 0x9c, 0x31, 0xcd,
+       0x5c, 0x1c, 0xc8, 0xe5, 0x81, 0xef, 0x19, 0x91, 0xde, 0x21, 0xc5, 0x34,
+       0x3b, 0xa3, 0xe6, 0xea, 0xcb, 0x7a, 0x63, 0xec, 0x65, 0xfc, 0x93, 0x39,
+       0x1b, 0x44, 0xda, 0x47, 0x1a, 0xc7, 0x69, 0xb3, 0xfb, 0x27, 0xe1, 0x29,
+       0x4f, 0x8c, 0xe3, 0x67, 0x19, 0x78, 0xca, 0x12, 0x69, 0x5c, 0xc8, 0x8c,
+       0x06, 0x3c, 0x88, 0x84, 0xb6, 0x2b, 0xe9, 0x94, 0x03, 0xea, 0xf0, 0xdb,
+       0x50, 0xc3, 0xb4, 0xc7, 0xd2, 0x79, 0x45, 0x2d, 0xbc, 0x0c, 0x35, 0xf9,
+       0x2b, 0x45, 0xed, 0xaa, 0x75, 0x22, 0xe9, 0x88, 0x7a, 0xf0, 0xa3, 0x06,
+       0xb1, 0xc9, 0x38, 0xd6, 0x5a, 0xb6, 0x49, 0xe3, 0xd6, 0x6b, 0xb6, 0x49,
+       0x60, 0x94, 0x7c, 0x1d, 0x25, 0x5f, 0xaf, 0xe8, 0x6a, 0xe8, 0x69, 0x98,
+       0xab, 0x07, 0x75, 0xb9, 0x97, 0xc0, 0x78, 0xde, 0x0c, 0xfb, 0x13, 0x97,
+       0xc8, 0x2f, 0xd2, 0x5f, 0x4a, 0x78, 0xd2, 0xd5, 0x89, 0x4f, 0xcd, 0xd7,
+       0x37, 0x86, 0xf0, 0x62, 0x3e, 0x88, 0x17, 0xf2, 0x01, 0x3c, 0x9f, 0x6f,
+       0x87, 0x91, 0x87, 0x7f, 0x67, 0xfe, 0x8b, 0xfc, 0xd8, 0x84, 0x8f, 0xcf,
+       0x93, 0x6f, 0xff, 0x8e, 0xbc, 0x6b, 0xa0, 0x2c, 0x81, 0xde, 0x1f, 0x67,
+       0x46, 0xcc, 0x0a, 0x0d, 0x03, 0x35, 0x09, 0x2d, 0x79, 0x9b, 0xe2, 0x6b,
+       0xa1, 0x1f, 0xf6, 0xbe, 0x9a, 0x6b, 0x71, 0x69, 0x53, 0x5e, 0xb8, 0xa9,
+       0xff, 0x6d, 0x79, 0xd3, 0x1c, 0xd3, 0x0f, 0xad, 0xdb, 0xdb, 0xf2, 0xa7,
+       0x85, 0x5e, 0xad, 0x07, 0xe9, 0xfc, 0x20, 0xe0, 0x4f, 0xf0, 0x93, 0xa1,
+       0xb8, 0xab, 0xa9, 0x3d, 0x7c, 0xee, 0x41, 0x97, 0xed, 0xcf, 0xe4, 0x81,
+       0x7a, 0x7f, 0xc1, 0x20, 0x0f, 0xc6, 0xb4, 0x1f, 0x15, 0x61, 0xca, 0xf7,
+       0x13, 0xf2, 0x19, 0xc3, 0xf7, 0xf3, 0x1a, 0x79, 0x6b, 0x22, 0x8f, 0x61,
+       0xf2, 0xe7, 0xc1, 0xde, 0xac, 0x3a, 0x9d, 0x86, 0x3a, 0x31, 0x8b, 0x35,
+       0x48, 0x06, 0x03, 0xf4, 0xc1, 0x3f, 0x86, 0x4d, 0xa3, 0x07, 0x53, 0x06,
+       0xd6, 0x07, 0x12, 0xb4, 0x6f, 0x1c, 0x8f, 0x96, 0x21, 0x3a, 0xf0, 0xb1,
+       0xa2, 0xe0, 0xf5, 0x68, 0x0f, 0x26, 0x29, 0x4f, 0x4f, 0xce, 0x8b, 0x07,
+       0xb2, 0x15, 0xb8, 0x2f, 0x6b, 0xe2, 0xfe, 0x38, 0x12, 0x15, 0x94, 0x27,
+       0x16, 0x8f, 0x86, 0xdf, 0x83, 0x0b, 0xed, 0xb9, 0x1e, 0xc6, 0xd2, 0x56,
+       0x24, 0xcb, 0x3c, 0xd8, 0x9a, 0xf3, 0x31, 0x1e, 0x93, 0x38, 0x3d, 0xe3,
+       0x81, 0x7b, 0x83, 0x03, 0xb3, 0xc1, 0x32, 0xc4, 0xea, 0x1d, 0xfc, 0x0d,
+       0xfa, 0xdb, 0x66, 0xea, 0xfc, 0xdb, 0x0c, 0x17, 0x0e, 0x18, 0x0e, 0x8c,
+       0x64, 0x4d, 0xb3, 0x5d, 0x37, 0x71, 0x75, 0x43, 0x00, 0x3f, 0xa0, 0xfe,
+       0x0e, 0x19, 0x21, 0x9c, 0xcd, 0x3f, 0x4e, 0x5e, 0x82, 0x36, 0xbf, 0x06,
+       0x79, 0x37, 0xc8, 0xbb, 0x41, 0xbe, 0x0d, 0xe1, 0xf3, 0x3c, 0x63, 0x46,
+       0xa7, 0x5c, 0x5e, 0xf2, 0x50, 0x89, 0x21, 0xf2, 0x11, 0x89, 0x9b, 0x70,
+       0xc4, 0xd5, 0xf4, 0x5e, 0x26, 0xaf, 0xd5, 0xf5, 0xa6, 0xf9, 0xf1, 0x06,
+       0x91, 0x85, 0x36, 0x77, 0xf4, 0x48, 0x8c, 0xfe, 0x56, 0x15, 0xe3, 0xea,
+       0x6f, 0xa9, 0xb7, 0x27, 0xf3, 0x5e, 0xa4, 0xb2, 0x96, 0xdf, 0x1e, 0x2e,
+       0x23, 0xdf, 0xc2, 0x57, 0x5e, 0x8b, 0x32, 0x46, 0xa3, 0xfd, 0x8c, 0x51,
+       0xec, 0x20, 0xcf, 0xf7, 0x1b, 0xd1, 0x96, 0x5d, 0x8a, 0x0b, 0x9d, 0xb9,
+       0xa0, 0xbf, 0xfd, 0x06, 0x3e, 0x29, 0xaf, 0xc4, 0x20, 0x65, 0x0d, 0x90,
+       0xbf, 0x20, 0xf6, 0x91, 0xcf, 0x17, 0x8a, 0x7c, 0xce, 0xe5, 0x65, 0xad,
+       0xcf, 0xf3, 0x5a, 0xe2, 0x13, 0xe9, 0x15, 0x89, 0xa0, 0x82, 0x0a, 0x1f,
+       0x76, 0xe5, 0xde, 0xa2, 0x2d, 0xea, 0xf0, 0xa7, 0xb4, 0xc1, 0x8b, 0x8c,
+       0x91, 0xef, 0x5f, 0xf3, 0x17, 0xb1, 0xc7, 0x63, 0xb4, 0x83, 0x7a, 0x3a,
+       0x0d, 0x1f, 0x06, 0xf2, 0x49, 0x1c, 0x99, 0x41, 0x72, 0x5e, 0x3f, 0xce,
+       0x78, 0x5f, 0x05, 0xa7, 0x56, 0x9e, 0x0c, 0x68, 0x15, 0xd8, 0x37, 0x17,
+       0xc4, 0x70, 0xbe, 0x0d, 0x46, 0x36, 0x88, 0x83, 0xf4, 0xcd, 0x2b, 0xf1,
+       0xe4, 0xfd, 0x7e, 0x08, 0xef, 0x41, 0x3c, 0xc0, 0x77, 0x9e, 0x98, 0x09,
+       0x62, 0x88, 0x3a, 0xda, 0x1e, 0x8f, 0xb6, 0x78, 0x79, 0xed, 0x00, 0xaf,
+       0x1d, 0xa5, 0xfe, 0xcf, 0xeb, 0x93, 0x18, 0xe8, 0x55, 0x63, 0x40, 0x10,
+       0xfb, 0x0d, 0x04, 0xe8, 0xc2, 0x8f, 0x31, 0xbf, 0xc5, 0xce, 0xf3, 0xfb,
+       0xbd, 0xf9, 0x0a, 0xca, 0xe9, 0x47, 0x48, 0xfb, 0xc4, 0x74, 0x37, 0x9b,
+       0xe6, 0x77, 0xf5, 0xe8, 0xd2, 0x4f, 0x9d, 0x2e, 0x3c, 0x92, 0x77, 0x20,
+       0x35, 0x57, 0x81, 0xdf, 0xcf, 0xba, 0x70, 0x57, 0x7d, 0x05, 0x0e, 0xcd,
+       0x25, 0x31, 0x36, 0x53, 0x81, 0xc1, 0x2c, 0x56, 0xef, 0xd7, 0xc7, 0x6a,
+       0xca, 0xa0, 0x2e, 0xb7, 0x23, 0x86, 0xab, 0xb4, 0xc3, 0x23, 0x73, 0x3e,
+       0x7f, 0xff, 0x4c, 0x00, 0xa9, 0x05, 0x2f, 0x9f, 0x77, 0xf0, 0xf9, 0x72,
+       0xe8, 0xeb, 0x23, 0xa9, 0x00, 0x84, 0xc7, 0x4a, 0x3c, 0x34, 0xe7, 0xc5,
+       0x83, 0xd9, 0x00, 0x0e, 0xce, 0x34, 0x63, 0xda, 0x48, 0xe2, 0x18, 0x73,
+       0xc7, 0xf7, 0xe2, 0x6a, 0xef, 0x41, 0x45, 0x4d, 0x6e, 0x53, 0x92, 0x68,
+       0x88, 0xbb, 0x71, 0x89, 0x79, 0xc8, 0x1d, 0x6f, 0x6c, 0x79, 0x9e, 0xb9,
+       0xa1, 0x2c, 0x11, 0xe4, 0x77, 0x75, 0x82, 0x31, 0x9b, 0x74, 0x3b, 0x36,
+       0x00, 0x2b, 0x25, 0x7e, 0x83, 0xfe, 0x6e, 0x23, 0xe0, 0xef, 0xce, 0xd7,
+       0xf9, 0xb7, 0x1b, 0x21, 0xff, 0x76, 0xc6, 0xd7, 0x36, 0xf1, 0x47, 0xc3,
+       0x83, 0xe3, 0xf1, 0x4f, 0xcd, 0x81, 0x1a, 0x2b, 0x9f, 0xf9, 0x77, 0xce,
+       0xa8, 0xe9, 0x59, 0xa8, 0x3a, 0xab, 0x01, 0x26, 0x17, 0x5c, 0xb4, 0x9f,
+       0x82, 0x1a, 0xad, 0x99, 0x79, 0x3c, 0x80, 0x87, 0x98, 0x53, 0xfe, 0x9a,
+       0x39, 0x65, 0x70, 0x2a, 0x12, 0x98, 0x86, 0x97, 0xfa, 0x06, 0xf6, 0x9e,
+       0x0b, 0xd2, 0xe6, 0x5d, 0x78, 0x9c, 0x7c, 0x6d, 0xdf, 0x18, 0xc4, 0x7d,
+       0xf9, 0x80, 0xbf, 0x8b, 0xf6, 0x7b, 0x2f, 0x17, 0xf2, 0x6f, 0xa5, 0x2d,
+       0xdf, 0xce, 0xa9, 0xe1, 0x02, 0xfe, 0xaf, 0xf8, 0x53, 0x0c, 0x0e, 0x60,
+       0xff, 0x94, 0x1b, 0x85, 0xa0, 0xac, 0x45, 0x9d, 0x1b, 0x2f, 0x9a, 0x3e,
+       0x4d, 0x3b, 0x7d, 0x90, 0xba, 0xfe, 0x46, 0xde, 0x87, 0x07, 0x0d, 0x35,
+       0xf6, 0x7d, 0xc5, 0x47, 0x9d, 0x7a, 0xa8, 0x07, 0x26, 0x98, 0x55, 0xf2,
+       0x5c, 0x1c, 0xe1, 0x55, 0x76, 0xae, 0x3d, 0x34, 0x27, 0x7e, 0x42, 0xdb,
+       0x1b, 0xf4, 0x01, 0xfa, 0xcf, 0xf7, 0xaf, 0xc5, 0xaa, 0x1a, 0x48, 0x5b,
+       0xb9, 0x3b, 0x46, 0x7f, 0xb1, 0x75, 0x74, 0x62, 0x46, 0xf4, 0xa0, 0x4e,
+       0xc3, 0x91, 0xc4, 0xba, 0xf5, 0x7f, 0x6d, 0x5e, 0x5a, 0x29, 0xfa, 0x08,
+       0x60, 0x84, 0x3a, 0x3c, 0x6d, 0x98, 0xe6, 0xd5, 0x0d, 0x1f, 0x9a, 0x2d,
+       0x37, 0x8b, 0x5e, 0x44, 0xd6, 0x1f, 0x28, 0x52, 0x47, 0x6a, 0x34, 0xff,
+       0xff, 0x07, 0x5f, 0xf9, 0xa6, 0x39, 0x60, 0xc9, 0x27, 0xfe, 0xe2, 0xa2,
+       0x2f, 0x3e, 0x4e, 0xda, 0x0e, 0x0c, 0x90, 0xde, 0xc3, 0x86, 0xf9, 0x51,
+       0x6d, 0xe2, 0x33, 0xb3, 0x65, 0x93, 0x36, 0xbc, 0xac, 0xfc, 0x4f, 0x5e,
+       0x0f, 0xe2, 0xa1, 0x7c, 0x0b, 0x75, 0xd7, 0x8e, 0x27, 0xa8, 0xc3, 0xa3,
+       0x86, 0xe4, 0xc4, 0x10, 0xfd, 0xb9, 0x8e, 0xfe, 0xed, 0x52, 0xb6, 0x19,
+       0x39, 0x6c, 0x9f, 0x4c, 0xa3, 0x93, 0xfe, 0xbe, 0x94, 0x89, 0xb4, 0x3c,
+       0x0b, 0x35, 0x4d, 0x19, 0xfc, 0x5d, 0xd4, 0x71, 0xbb, 0xa1, 0x76, 0x89,
+       0x4d, 0xdb, 0x99, 0x97, 0x5e, 0xca, 0x84, 0xfc, 0x6d, 0x79, 0xd1, 0x77,
+       0x9d, 0x7f, 0x6b, 0xfe, 0xab, 0xb4, 0xbd, 0x82, 0xcd, 0x6b, 0x3c, 0xcc,
+       0x33, 0x77, 0xc1, 0xb6, 0xab, 0x6d, 0xbb, 0xd7, 0xe3, 0x8d, 0x03, 0x1f,
+       0x32, 0x3f, 0xa5, 0x57, 0xda, 0xd7, 0x52, 0xbc, 0x56, 0xbd, 0x01, 0xfe,
+       0x3b, 0xe9, 0x07, 0x7b, 0xe8, 0x07, 0x57, 0x37, 0x7c, 0x6a, 0x86, 0x6f,
+       0xb2, 0xfd, 0xa0, 0x6d, 0xc6, 0xe5, 0xef, 0xa0, 0x9e, 0xb6, 0xe9, 0x0a,
+       0xe6, 0xf4, 0x0c, 0x06, 0xae, 0x61, 0x87, 0xe4, 0xec, 0x59, 0x3d, 0xc9,
+       0x3c, 0xf2, 0x9b, 0x70, 0xd5, 0x60, 0xf6, 0x59, 0xfd, 0x71, 0x84, 0x6d,
+       0xdf, 0xc1, 0xc1, 0xac, 0x17, 0xe9, 0xbb, 0x02, 0x98, 0x6f, 0x08, 0xe0,
+       0x61, 0xd2, 0xbe, 0x12, 0x6f, 0x1c, 0x7a, 0x83, 0x3a, 0x98, 0xad, 0x91,
+       0x6b, 0x49, 0xfc, 0xa5, 0xfe, 0x28, 0x70, 0x93, 0xbd, 0xf6, 0x82, 0xc4,
+       0xe8, 0x42, 0x33, 0x8e, 0xe6, 0xfb, 0x15, 0x3b, 0x6f, 0xaa, 0x5d, 0x49,
+       0xfc, 0xc4, 0x94, 0x5c, 0xba, 0x60, 0x30, 0xc7, 0x51, 0x1f, 0xe3, 0xf4,
+       0xa3, 0xd1, 0x5c, 0x9d, 0xbf, 0x93, 0x7e, 0xf4, 0x78, 0x4e, 0x64, 0x8a,
+       0xea, 0xba, 0xb3, 0x96, 0xb5, 0x99, 0xfa, 0x31, 0xac, 0x9a, 0x5f, 0x1d,
+       0xd0, 0x8e, 0x61, 0xda, 0xe2, 0x2d, 0xa5, 0xf4, 0x13, 0x63, 0x30, 0x64,
+       0xaa, 0xcb, 0xb5, 0x43, 0x78, 0xdc, 0xba, 0x16, 0xf4, 0xef, 0x9e, 0x49,
+       0x3a, 0x1c, 0x1a, 0x02, 0x95, 0x89, 0x76, 0x65, 0x37, 0xeb, 0x6e, 0xc7,
+       0x4c, 0x87, 0xd2, 0xb1, 0x20, 0x31, 0xd0, 0xa5, 0x6c, 0x67, 0xcd, 0x4d,
+       0xb2, 0xe6, 0x26, 0x59, 0x73, 0x93, 0xe4, 0x23, 0xc9, 0x5a, 0xdb, 0x96,
+       0x4f, 0x29, 0x3b, 0x44, 0xff, 0xf4, 0xaf, 0xe7, 0x0d, 0x1b, 0x47, 0x30,
+       0x07, 0xf9, 0x3b, 0xf3, 0x6b, 0x1d, 0x36, 0xb6, 0x4b, 0x29, 0x45, 0x2c,
+       0xe3, 0xa9, 0xd0, 0x58, 0xcb, 0x8c, 0x94, 0xd2, 0xcd, 0x7a, 0xdb, 0x6f,
+       0xe9, 0x32, 0x32, 0xfc, 0x0e, 0xeb, 0xec, 0xeb, 0xac, 0xb3, 0xb9, 0x38,
+       0xe3, 0x6a, 0xcd, 0x55, 0x73, 0x60, 0xa5, 0x5d, 0x13, 0xc6, 0xc8, 0xef,
+       0x77, 0x69, 0xb3, 0x02, 0x6b, 0x69, 0xbb, 0x53, 0xc1, 0x7e, 0x0d, 0xd5,
+       0xb5, 0xcc, 0xa9, 0x47, 0xf3, 0xac, 0x03, 0x7a, 0xa4, 0xe5, 0x7d, 0x2a,
+       0xf6, 0xa8, 0xe6, 0xc6, 0xd5, 0x9b, 0x08, 0x76, 0xb4, 0x36, 0x1c, 0xcf,
+       0x96, 0x63, 0x28, 0x9e, 0x5c, 0xe1, 0x21, 0x56, 0xe9, 0x6a, 0xc6, 0xa3,
+       0x5c, 0x5a, 0x09, 0x25, 0xa2, 0xf4, 0x1b, 0x24, 0xa7, 0x58, 0x27, 0x26,
+       0x8d, 0xaf, 0x22, 0xc7, 0x7a, 0x3a, 0xaf, 0xbb, 0xf0, 0x7a, 0x6e, 0x2d,
+       0xf3, 0x5c, 0x54, 0xf7, 0x29, 0x15, 0x8c, 0xdf, 0x04, 0x32, 0x86, 0xe4,
+       0x27, 0xd3, 0x9c, 0x17, 0x1e, 0xa2, 0xd1, 0xe4, 0x28, 0x24, 0x67, 0x99,
+       0xab, 0xef, 0x8d, 0x97, 0x61, 0x73, 0xd4, 0x8f, 0xd5, 0xda, 0x80, 0xd2,
+       0x95, 0x8f, 0xea, 0xe7, 0xf1, 0xbb, 0xca, 0x9e, 0x85, 0x04, 0x63, 0xbb,
+       0x9f, 0xba, 0xa9, 0xc0, 0xa5, 0xa0, 0xf0, 0x88, 0x6a, 0xb7, 0xe6, 0xc0,
+       0xbb, 0x77, 0x2b, 0x08, 0x68, 0x49, 0x5c, 0x68, 0x0e, 0xd0, 0xaf, 0xba,
+       0x88, 0x31, 0xc2, 0x70, 0x2e, 0x86, 0xfc, 0x3b, 0x68, 0x8b, 0xca, 0xc5,
+       0x3a, 0xda, 0x87, 0xbe, 0x47, 0x1d, 0xb6, 0x51, 0x87, 0xdd, 0x73, 0x08,
+       0x54, 0x24, 0xfa, 0x94, 0x8e, 0x7c, 0xbb, 0xd2, 0x9e, 0x57, 0xa9, 0x27,
+       0xd1, 0xc9, 0x37, 0x89, 0x95, 0xc4, 0x57, 0x4a, 0xb6, 0x14, 0x7f, 0xbd,
+       0xd1, 0x9e, 0xfd, 0x0e, 0x89, 0xb9, 0xcd, 0x6b, 0x12, 0x8c, 0x47, 0x07,
+       0xf9, 0x12, 0x1e, 0x3c, 0xa8, 0x6e, 0x30, 0x57, 0x5f, 0x89, 0x33, 0x79,
+       0x56, 0x24, 0x30, 0x95, 0xef, 0xa1, 0x5d, 0x36, 0x14, 0xfd, 0x2b, 0xe0,
+       0xdf, 0x36, 0xd3, 0xae, 0x6c, 0x5b, 0x58, 0xe1, 0xef, 0xa5, 0x0d, 0x7b,
+       0x17, 0x42, 0x42, 0x97, 0xeb, 0x8b, 0x6d, 0x93, 0x70, 0x68, 0xff, 0x9a,
+       0x2d, 0xbf, 0x41, 0x5a, 0x62, 0x4f, 0x6f, 0xc9, 0x4f, 0xfd, 0x7b, 0x66,
+       0x92, 0x78, 0x77, 0x83, 0x9b, 0x35, 0xb5, 0x84, 0x29, 0xaa, 0x8a, 0x9f,
+       0xa7, 0x1d, 0xd0, 0x52, 0x4a, 0x97, 0xf8, 0x91, 0xdb, 0x5e, 0xf3, 0xce,
+       0x19, 0xb8, 0x09, 0x15, 0xc2, 0x4e, 0x62, 0xba, 0x0f, 0xe3, 0xd1, 0x81,
+       0x73, 0x4a, 0x8f, 0xd2, 0x93, 0x97, 0x1a, 0x6c, 0xfb, 0x54, 0x1b, 0x7d,
+       0xaa, 0x9d, 0xfc, 0xb4, 0xd3, 0xa7, 0xba, 0xc9, 0x4f, 0xb7, 0xe5, 0x53,
+       0xe2, 0x9b, 0xbf, 0xce, 0xcb, 0xd6, 0xfc, 0x1e, 0x4b, 0x2f, 0x3b, 0xf8,
+       0x6e, 0x17, 0xe5, 0xe8, 0xe2, 0x7b, 0x7b, 0xf8, 0xde, 0x9e, 0x85, 0xff,
+       0x2d, 0xfc, 0x51, 0x16, 0x3b, 0xf6, 0xaf, 0xd7, 0x34, 0xc9, 0x01, 0xaf,
+       0x15, 0x31, 0x05, 0xd2, 0x8e, 0x84, 0xe4, 0x88, 0x61, 0xf4, 0x36, 0xc3,
+       0xb3, 0x22, 0xf1, 0x93, 0xd6, 0x5d, 0xf5, 0xcc, 0x67, 0xcc, 0xa7, 0x9e,
+       0x29, 0x62, 0x69, 0xe6, 0xe8, 0xf9, 0x16, 0x05, 0x63, 0xfa, 0xcd, 0x8c,
+       0x53, 0x1d, 0x13, 0x79, 0xb5, 0x2b, 0xcc, 0x7b, 0x4d, 0x93, 0x82, 0xf1,
+       0x0f, 0xa2, 0x8d, 0xb8, 0x2e, 0x94, 0x18, 0x42, 0xc8, 0x88, 0x84, 0x26,
+       0x14, 0x75, 0x68, 0x2b, 0xd4, 0x25, 0xd6, 0x86, 0xd4, 0x9c, 0xa2, 0x0e,
+       0xd7, 0x3a, 0xd5, 0xe4, 0x9b, 0x16, 0xbe, 0x3e, 0x88, 0x35, 0x16, 0x86,
+       0x1b, 0x42, 0x8c, 0x58, 0x76, 0x07, 0x69, 0x1e, 0xd8, 0xac, 0xe0, 0xb2,
+       0xfe, 0x21, 0xed, 0xa8, 0x26, 0xd3, 0x8a, 0x8e, 0x0c, 0xf3, 0x44, 0x68,
+       0x4a, 0xb0, 0xfa, 0x41, 0x62, 0x75, 0x78, 0x7c, 0x7c, 0x36, 0x33, 0x19,
+       0x49, 0x79, 0x9c, 0x6a, 0x8c, 0x38, 0x3d, 0x49, 0x9a, 0x7a, 0x9e, 0xf8,
+       0x9d, 0x6b, 0x84, 0xf7, 0x17, 0x69, 0x46, 0x8b, 0x34, 0xb5, 0x1c, 0x18,
+       0x37, 0x13, 0xe8, 0x8c, 0xb2, 0x56, 0x30, 0xe7, 0x1d, 0x93, 0x9e, 0x80,
+       0xf4, 0xca, 0xa7, 0x74, 0x7e, 0x4f, 0x29, 0xbb, 0x25, 0xa6, 0xca, 0x6d,
+       0x2b, 0x54, 0x73, 0x8d, 0xaa, 0xc4, 0x61, 0x2c, 0x5a, 0x6b, 0x0c, 0xcb,
+       0x1a, 0xc3, 0x3f, 0x53, 0xd4, 0xd8, 0x39, 0x45, 0x72, 0x75, 0x63, 0xff,
+       0x39, 0xc6, 0xd0, 0x51, 0x45, 0x6d, 0x39, 0x4e, 0xf1, 0xbd, 0x9a, 0xd0,
+       0x3f, 0x5c, 0x5c, 0x67, 0x18, 0x0d, 0x39, 0xc6, 0x67, 0xde, 0xa3, 0x6c,
+       0xcd, 0xb6, 0x61, 0x6c, 0xae, 0x0d, 0xa3, 0x59, 0x05, 0x7b, 0xf4, 0x95,
+       0xb8, 0x74, 0xb3, 0xd5, 0xa7, 0x54, 0xad, 0xd6, 0x6a, 0x31, 0x12, 0x40,
+       0xb5, 0x43, 0xfb, 0x0a, 0xf6, 0x16, 0x31, 0x7e, 0xe7, 0x89, 0x5e, 0xe6,
+       0x7d, 0x13, 0xef, 0x33, 0x96, 0x22, 0x35, 0x48, 0xba, 0x13, 0x2d, 0xc4,
+       0xe3, 0x75, 0x4e, 0x3b, 0xde, 0xff, 0xc9, 0x63, 0xdb, 0x40, 0xf4, 0xff,
+       0xf9, 0x7b, 0x6d, 0x78, 0x32, 0x5b, 0x86, 0x96, 0x0d, 0xb8, 0x2b, 0x84,
+       0x2a, 0x07, 0x6b, 0xdc, 0x5b, 0xbb, 0x94, 0x14, 0xef, 0x59, 0xcf, 0x7a,
+       0xbe, 0x9c, 0xe8, 0x4d, 0xfc, 0x97, 0x06, 0xb9, 0x6e, 0xe5, 0x8d, 0x1b,
+       0xae, 0x0f, 0x7f, 0xc1, 0x75, 0x05, 0xcf, 0x31, 0x91, 0x7d, 0x8f, 0x35,
+       0x25, 0x97, 0x31, 0xe1, 0x4c, 0xb8, 0x30, 0x34, 0x19, 0xc6, 0xc1, 0xc5,
+       0x20, 0x16, 0x33, 0xea, 0xc0, 0x25, 0xf6, 0x0f, 0x7b, 0x9b, 0x35, 0x3c,
+       0xb8, 0x18, 0xc2, 0x42, 0x06, 0xa6, 0x37, 0xa1, 0x15, 0xbc, 0x4a, 0x0c,
+       0x07, 0x16, 0xeb, 0x70, 0x2e, 0xa3, 0x2d, 0x8d, 0x2a, 0xd1, 0x54, 0x2d,
+       0x71, 0xc7, 0xc3, 0x8b, 0x4d, 0x78, 0x68, 0xd1, 0xc3, 0x77, 0x4c, 0x74,
+       0xc7, 0xeb, 0xf8, 0xbc, 0x03, 0xcf, 0x9e, 0x34, 0x4d, 0xc1, 0x5d, 0x43,
+       0x8b, 0xc0, 0xc2, 0x34, 0x6b, 0xd1, 0x19, 0xd6, 0xa5, 0xa7, 0x80, 0x03,
+       0x4f, 0x39, 0x30, 0x37, 0x6d, 0x62, 0xaf, 0x3e, 0x5a, 0xeb, 0xa0, 0xc3,
+       0x0f, 0xb0, 0x6e, 0xb8, 0x59, 0x03, 0xef, 0x0d, 0xd8, 0xf9, 0xfc, 0x12,
+       0xf3, 0xd4, 0xfd, 0x4f, 0xc5, 0xf0, 0x56, 0x26, 0x8d, 0x6e, 0xe2, 0xf3,
+       0x14, 0x79, 0x79, 0x33, 0xc3, 0x3a, 0xb6, 0xa8, 0xe3, 0x8d, 0x8c, 0x87,
+       0xeb, 0x34, 0xe1, 0xe5, 0x8c, 0x3c, 0x23, 0xcf, 0xfa, 0x30, 0x48, 0x5e,
+       0x5e, 0xcf, 0x84, 0xb8, 0x66, 0x10, 0x3f, 0xe6, 0x73, 0xf7, 0x2d, 0x6a,
+       0xac, 0x5b, 0x1e, 0xae, 0x1b, 0xc6, 0xab, 0x19, 0x1f, 0x79, 0x0d, 0xb2,
+       0x56, 0x0d, 0x62, 0x2c, 0xd3, 0xb8, 0xb4, 0x95, 0x89, 0xda, 0xae, 0x35,
+       0x72, 0xed, 0x1d, 0xb3, 0xc7, 0x8a, 0x45, 0x59, 0xa7, 0xb4, 0xee, 0x20,
+       0x46, 0x33, 0x6f, 0x38, 0x4b, 0xfd, 0xf4, 0x73, 0xd3, 0xcb, 0x16, 0xf6,
+       0x7b, 0xd6, 0xe0, 0xdf, 0x73, 0xc0, 0x39, 0x23, 0x6d, 0x56, 0x27, 0x88,
+       0x75, 0x59, 0xa3, 0x7e, 0xba, 0xb1, 0x89, 0xeb, 0x6a, 0x03, 0x2f, 0x29,
+       0xd2, 0xef, 0xb8, 0x10, 0x7e, 0x4a, 0xf4, 0x45, 0xcc, 0xbc, 0x00, 0xfc,
+       0x25, 0xf1, 0x67, 0xc3, 0xa4, 0x2a, 0x7e, 0xdf, 0x4f, 0x5c, 0xd3, 0x5b,
+       0x40, 0x7d, 0xec, 0x41, 0x8c, 0x98, 0x65, 0xc4, 0xe7, 0xd5, 0xc4, 0xb5,
+       0x8b, 0x4d, 0xac, 0x53, 0x1b, 0x4d, 0xf3, 0x6f, 0x9b, 0x61, 0x3a, 0x12,
+       0x9a, 0x5e, 0xeb, 0x2c, 0x7c, 0xa5, 0x0a, 0xda, 0x92, 0x5f, 0xd1, 0x0a,
+       0x3f, 0x45, 0x74, 0xf8, 0x3c, 0x44, 0xaf, 0xc0, 0xda, 0x45, 0x17, 0xd6,
+       0x51, 0x9e, 0x6d, 0x93, 0x5c, 0x9b, 0xf8, 0x24, 0x4a, 0x99, 0x76, 0x4e,
+       0x12, 0x73, 0x69, 0x3e, 0xac, 0xa1, 0x8e, 0x87, 0x4e, 0x99, 0x66, 0x39,
+       0x75, 0xdc, 0x40, 0xfb, 0xec, 0x3f, 0x61, 0xe2, 0x25, 0xfd, 0x25, 0xea,
+       0x54, 0x21, 0x6e, 0x6c, 0xe6, 0x3b, 0x41, 0x3e, 0xef, 0xc1, 0x81, 0x49,
+       0xe9, 0x97, 0xea, 0xf8, 0xcc, 0x45, 0x1c, 0xcf, 0xc4, 0xd0, 0x44, 0xfd,
+       0x85, 0x49, 0xb3, 0x91, 0xef, 0x84, 0x49, 0x2f, 0xbc, 0xf8, 0x35, 0x6c,
+       0x3f, 0xa5, 0x40, 0x8b, 0x8a, 0x0e, 0xbe, 0x86, 0xf6, 0x33, 0x5f, 0x94,
+       0x13, 0x98, 0xa5, 0xa6, 0xd5, 0x89, 0x02, 0xf1, 0x77, 0x55, 0x62, 0x04,
+       0xac, 0xdf, 0x78, 0x73, 0x56, 0xc1, 0xd4, 0x34, 0xfb, 0xbd, 0x8d, 0x30,
+       0x2b, 0x28, 0xd3, 0x1b, 0xb3, 0xbf, 0x81, 0x67, 0x4e, 0x52, 0x0f, 0x4f,
+       0x07, 0xf1, 0xbd, 0x8c, 0x0b, 0xb7, 0x4e, 0x09, 0xa6, 0xd3, 0x62, 0x07,
+       0x15, 0xe9, 0x8f, 0xa4, 0x6f, 0x89, 0x86, 0xdd, 0x8a, 0x03, 0xf5, 0xcf,
+       0xb8, 0xa0, 0x9d, 0x0b, 0xc3, 0x5d, 0xef, 0x81, 0x56, 0xff, 0xfb, 0xcc,
+       0x35, 0x0e, 0x94, 0xb1, 0x97, 0xed, 0xfc, 0x76, 0x8c, 0xd7, 0x82, 0xbc,
+       0x86, 0xdf, 0x28, 0x87, 0x73, 0x95, 0x93, 0x35, 0xbc, 0x4c, 0x23, 0x1e,
+       0x73, 0x99, 0xa6, 0x93, 0xb5, 0x61, 0xf7, 0x77, 0x4c, 0x33, 0xb2, 0x41,
+       0x9e, 0x0f, 0x20, 0x72, 0x4e, 0xe3, 0x73, 0x76, 0xbd, 0xbc, 0x8e, 0xc7,
+       0x9c, 0xf4, 0x23, 0x89, 0x55, 0xd6, 0x7b, 0xab, 0x87, 0xb2, 0x71, 0xfb,
+       0x0b, 0x79, 0xc1, 0x36, 0x61, 0x4b, 0x86, 0xb3, 0xd3, 0x0a, 0x73, 0x76,
+       0x82, 0xcf, 0x6e, 0x81, 0x33, 0xae, 0x4e, 0xa4, 0xe9, 0x07, 0x7b, 0x03,
+       0x2d, 0x78, 0xce, 0x70, 0xa3, 0x52, 0x5b, 0x85, 0x07, 0x7a, 0x03, 0x78,
+       0x8e, 0x7d, 0x01, 0x6d, 0x16, 0x2b, 0x80, 0x8d, 0xb4, 0x9f, 0xf4, 0x1c,
+       0x3f, 0x84, 0xf6, 0x6d, 0x07, 0xf3, 0x9c, 0xd3, 0xca, 0x73, 0x65, 0xf5,
+       0x40, 0x21, 0xe7, 0xc2, 0x05, 0xcd, 0xc6, 0x84, 0x2f, 0x58, 0x35, 0x5b,
+       0x0d, 0x14, 0xae, 0x61, 0x41, 0xb5, 0x25, 0xa9, 0x90, 0x19, 0xbf, 0xe8,
+       0xae, 0xdf, 0x65, 0xfb, 0xd2, 0xdf, 0x38, 0xa5, 0xe7, 0xb8, 0xfe, 0xbd,
+       0x02, 0x8e, 0x84, 0x1a, 0x6a, 0x73, 0xc2, 0xe3, 0x4a, 0x0c, 0xb5, 0x8e,
+       0x6b, 0x5f, 0xba, 0x81, 0xf7, 0x26, 0x8c, 0xe5, 0xaf, 0xf7, 0xda, 0x5d,
+       0x19, 0xcb, 0x87, 0xba, 0x44, 0xf7, 0x4f, 0xe8, 0x92, 0x67, 0x53, 0x4a,
+       0x3b, 0xf3, 0x56, 0xda, 0x85, 0x74, 0x15, 0x9f, 0xa1, 0xfe, 0x71, 0x74,
+       0x52, 0xe8, 0x1c, 0xc6, 0x78, 0x46, 0x66, 0x1b, 0xc3, 0xd8, 0x6c, 0x44,
+       0x62, 0x4b, 0xec, 0xa1, 0x8f, 0x40, 0xe6, 0x10, 0x8d, 0x85, 0x57, 0x14,
+       0x35, 0x75, 0x8b, 0x53, 0x1d, 0x5a, 0x56, 0xec, 0xbc, 0xb5, 0xb6, 0x98,
+       0xb7, 0xd6, 0xe4, 0x56, 0xf9, 0x7b, 0x58, 0x0f, 0x7a, 0x16, 0x4a, 0xf5,
+       0xa1, 0x47, 0xe9, 0xb4, 0x6a, 0x6b, 0xbf, 0xb2, 0x63, 0xc1, 0xa3, 0x74,
+       0x64, 0x3d, 0x78, 0x85, 0x58, 0x6c, 0xb6, 0x0f, 0x81, 0x5b, 0x37, 0xc2,
+       0xbb, 0x23, 0xdb, 0x8b, 0x72, 0x4d, 0x7a, 0xc8, 0x72, 0x74, 0x5a, 0x75,
+       0xad, 0xce, 0xdf, 0xc3, 0xfa, 0xd3, 0x93, 0xef, 0x63, 0xfe, 0x43, 0xc0,
+       0x9b, 0xb0, 0x67, 0x06, 0x92, 0x0b, 0xef, 0xe0, 0xbb, 0x4b, 0xf1, 0x15,
+       0x80, 0x5d, 0xff, 0x94, 0x7e, 0xf6, 0x12, 0xd5, 0x1b, 0x14, 0x5c, 0xba,
+       0xcb, 0x03, 0xd2, 0x62, 0xcf, 0x7f, 0xb1, 0xf5, 0xc2, 0x74, 0xaf, 0xd2,
+       0x31, 0x37, 0xef, 0xdd, 0x66, 0xc8, 0x2c, 0x62, 0xd6, 0xdb, 0x4e, 0x1e,
+       0xda, 0x17, 0x9e, 0xf6, 0x6e, 0x25, 0x4f, 0x5b, 0x17, 0x3e, 0x4f, 0x53,
+       0xea, 0xca, 0x44, 0x6b, 0x1b, 0x63, 0x7b, 0xb7, 0xfe, 0x91, 0x19, 0xfe,
+       0x1d, 0xa1, 0xb3, 0x58, 0xd4, 0x67, 0x92, 0x7c, 0x05, 0x3d, 0x9d, 0xf9,
+       0x80, 0x27, 0x99, 0x6f, 0xf7, 0xb6, 0x19, 0xbd, 0xde, 0xad, 0x46, 0x9f,
+       0xb7, 0xdd, 0xb8, 0x87, 0xb4, 0x7b, 0xbc, 0x1d, 0x06, 0xe3, 0x3a, 0xdf,
+       0x47, 0xbd, 0xf6, 0x62, 0x3c, 0x7f, 0x0f, 0xb1, 0x87, 0xd0, 0x1c, 0x20,
+       0x0e, 0xf2, 0x52, 0xc6, 0x11, 0xca, 0x58, 0x08, 0xb9, 0x91, 0x54, 0xdd,
+       0xd4, 0xd7, 0x98, 0x65, 0xc7, 0x09, 0x6b, 0x16, 0x55, 0x91, 0x98, 0x6c,
+       0xed, 0x3e, 0xc1, 0x7c, 0x9f, 0x38, 0xda, 0x7a, 0xeb, 0x29, 0xd4, 0xb8,
+       0x13, 0xd2, 0x3b, 0xb3, 0x1f, 0x8e, 0x46, 0xf5, 0xf7, 0x10, 0x0d, 0xbd,
+       0xc2, 0x67, 0x47, 0xe9, 0xbb, 0x63, 0xd6, 0xfc, 0x81, 0x06, 0xc9, 0x35,
+       0xa1, 0xdb, 0xf0, 0x78, 0x77, 0xb2, 0x37, 0xf3, 0x27, 0xd4, 0x96, 0x3b,
+       0x9c, 0x32, 0x0f, 0x29, 0xfc, 0x96, 0x0f, 0x4d, 0xe8, 0xca, 0x7b, 0x28,
+       0xd7, 0x97, 0xf0, 0x0f, 0x27, 0x59, 0xd7, 0x20, 0x7e, 0x68, 0x9a, 0xf7,
+       0xb1, 0xaf, 0x39, 0x96, 0xab, 0xc3, 0x65, 0xcb, 0xc6, 0x2e, 0x1c, 0xcd,
+       0x85, 0xf1, 0x0e, 0xe5, 0x73, 0x2d, 0xd6, 0xe2, 0xed, 0x69, 0x27, 0xf6,
+       0xe9, 0xb7, 0x17, 0xeb, 0x85, 0x03, 0xf7, 0xc6, 0x0e, 0x11, 0x3b, 0x38,
+       0x50, 0x4d, 0xfc, 0xf6, 0xb0, 0x75, 0xcd, 0xc9, 0xfe, 0xef, 0xb7, 0x91,
+       0xb2, 0xeb, 0x09, 0x79, 0x7c, 0x94, 0x3c, 0x36, 0x7b, 0xb7, 0x66, 0x55,
+       0xef, 0x9d, 0x59, 0x78, 0xdc, 0x89, 0xd1, 0xd6, 0x33, 0x27, 0x4d, 0x0c,
+       0xea, 0xb7, 0xe1, 0xca, 0xc9, 0xd1, 0x21, 0x17, 0xfd, 0xe7, 0xe7, 0xf1,
+       0x7e, 0x18, 0x33, 0xb8, 0x40, 0xe4, 0x71, 0xd1, 0xc7, 0xdc, 0xde, 0x10,
+       0x8f, 0x06, 0x58, 0x8b, 0xf5, 0x05, 0xc6, 0x66, 0x07, 0xd4, 0x21, 0xd6,
+       0xe4, 0xa4, 0x33, 0x11, 0x1d, 0x18, 0x23, 0x78, 0xac, 0x22, 0x3f, 0x5e,
+       0xe6, 0x6e, 0xdf, 0x62, 0xd8, 0xbb, 0x9b, 0xf5, 0x26, 0xc4, 0xfe, 0xce,
+       0x1b, 0xc5, 0xed, 0xb5, 0x88, 0xc6, 0x96, 0x29, 0xb7, 0x7b, 0xb1, 0xc9,
+       0x7b, 0x07, 0xeb, 0xc7, 0xe5, 0xa8, 0x39, 0xf2, 0x92, 0xee, 0x83, 0x7f,
+       0x51, 0xa7, 0xbe, 0xfb, 0x31, 0xba, 0xc0, 0x96, 0x2b, 0xca, 0x9e, 0x7f,
+       0xb1, 0xc5, 0xbb, 0x93, 0xb1, 0x59, 0x45, 0x13, 0x35, 0x2e, 0x26, 0xbd,
+       0xd2, 0xf3, 0x35, 0x2d, 0x6e, 0x22, 0x7f, 0xe2, 0xa3, 0x99, 0xd6, 0xcd,
+       0xf4, 0x87, 0xf0, 0x22, 0x3a, 0x99, 0xe6, 0x5e, 0x26, 0xcd, 0xfe, 0x10,
+       0x31, 0xec, 0x81, 0x8d, 0x3e, 0xe6, 0x29, 0xd1, 0x25, 0xf5, 0x98, 0x2f,
+       0xc9, 0x24, 0x75, 0xf9, 0x68, 0xeb, 0xe2, 0x29, 0xa9, 0xcb, 0xa9, 0xd6,
+       0xcc, 0x29, 0x0d, 0xef, 0xb0, 0xb6, 0xac, 0x8d, 0xab, 0xfa, 0x39, 0x25,
+       0x12, 0xba, 0x48, 0x59, 0x5c, 0xf8, 0x85, 0xb9, 0x57, 0x8b, 0x16, 0x6e,
+       0x61, 0x3c, 0x55, 0x33, 0x37, 0x86, 0x98, 0xf3, 0xab, 0x17, 0xa9, 0x98,
+       0x45, 0xa7, 0x1b, 0x15, 0x21, 0x78, 0xa2, 0x1a, 0xde, 0x3d, 0x19, 0xa3,
+       0x1e, 0xae, 0xd1, 0x3c, 0x48, 0xa8, 0x35, 0xc8, 0x52, 0xf8, 0xd8, 0x33,
+       0xf4, 0xc5, 0x71, 0xae, 0x5b, 0xb6, 0x28, 0x3c, 0xcb, 0xf3, 0x41, 0x3e,
+       0x7f, 0x7d, 0xed, 0x6a, 0xae, 0xfd, 0xd1, 0x29, 0xf1, 0xd7, 0x54, 0xeb,
+       0x85, 0x93, 0xf6, 0xda, 0xd1, 0x78, 0x0c, 0x1f, 0x9e, 0x54, 0x87, 0xdf,
+       0x55, 0x22, 0x03, 0x17, 0x14, 0x59, 0x1f, 0x75, 0x55, 0xb8, 0x62, 0x8e,
+       0x46, 0xa3, 0xa9, 0xbd, 0xa4, 0xd9, 0xb2, 0x89, 0xfa, 0xb7, 0xf8, 0xa0,
+       0xcf, 0x33, 0xcf, 0xba, 0xc9, 0x8f, 0xcd, 0x4b, 0x1d, 0x69, 0x9f, 0x2c,
+       0xf6, 0x6a, 0xec, 0x53, 0xaf, 0xf3, 0x13, 0xa4, 0x1e, 0x3c, 0xbb, 0x9b,
+       0x7d, 0xa8, 0xb5, 0x9e, 0x0b, 0xf0, 0x39, 0xd1, 0xc3, 0x2f, 0x15, 0x87,
+       0xf6, 0x1e, 0xf3, 0x98, 0xe4, 0x92, 0x20, 0x73, 0xd8, 0x3d, 0xd2, 0xd3,
+       0xa6, 0xd3, 0xf4, 0x77, 0x37, 0xfd, 0x7d, 0x9b, 0xf8, 0xb4, 0x41, 0x9f,
+       0x36, 0xe8, 0xd3, 0x86, 0x1a, 0x1a, 0x46, 0x24, 0x30, 0x48, 0xbb, 0x25,
+       0x43, 0xe2, 0xeb, 0x7d, 0xd8, 0xc7, 0xdf, 0xfd, 0xbc, 0x7f, 0x94, 0x7d,
+       0x2e, 0x56, 0xc8, 0x9a, 0x87, 0xd1, 0x6e, 0x3c, 0x86, 0xa1, 0x2c, 0x7e,
+       0xe5, 0x6d, 0x2e, 0x47, 0xf9, 0x1a, 0xe9, 0xe1, 0xd5, 0xc0, 0x31, 0x3c,
+       0xc6, 0x3e, 0xea, 0x97, 0x4a, 0xa5, 0xe6, 0xea, 0x3d, 0xae, 0xa8, 0x81,
+       0x76, 0xf6, 0xc3, 0x7b, 0xf3, 0xf7, 0xd0, 0xbe, 0x91, 0xa1, 0x57, 0x14,
+       0xf6, 0x52, 0xb5, 0x5c, 0x9b, 0xb1, 0x74, 0x27, 0xd7, 0x31, 0x84, 0x0f,
+       0x2b, 0xdf, 0xfe, 0x1e, 0x44, 0xb7, 0x3f, 0x6a, 0x18, 0xe4, 0xfa, 0x36,
+       0x1f, 0xa3, 0xec, 0x29, 0x07, 0x19, 0x63, 0xfb, 0xac, 0xf8, 0xea, 0x23,
+       0x8d, 0xeb, 0x79, 0x6c, 0x6b, 0x46, 0x6a, 0xa9, 0x89, 0xc7, 0x75, 0x13,
+       0xcf, 0xf2, 0x77, 0x89, 0xb9, 0x6c, 0xec, 0x86, 0x5c, 0xe6, 0xe0, 0x73,
+       0xbb, 0xf9, 0x5c, 0x0b, 0x53, 0xe7, 0xc2, 0x9c, 0xcc, 0x06, 0x0f, 0xcb,
+       0x6c, 0x10, 0x39, 0x43, 0x74, 0x3f, 0x8c, 0x0b, 0x99, 0x48, 0xca, 0xe9,
+       0x34, 0x47, 0x18, 0x57, 0x4b, 0x1f, 0xd1, 0x77, 0x5f, 0xdf, 0xa8, 0xf6,
+       0x52, 0x87, 0xb1, 0x49, 0x45, 0x0d, 0xbd, 0x86, 0x42, 0xa7, 0x07, 0x8d,
+       0xe1, 0x75, 0xce, 0x68, 0xe0, 0x2c, 0xd4, 0xc2, 0x20, 0x25, 0x7d, 0x3a,
+       0x6f, 0xe7, 0xba, 0xcd, 0xc5, 0x5c, 0xd7, 0x92, 0xab, 0x50, 0xee, 0xcc,
+       0xb2, 0x3e, 0xcf, 0x99, 0x69, 0x3f, 0xeb, 0x55, 0x7e, 0x4e, 0x68, 0x8f,
+       0xa0, 0x31, 0x2e, 0xb4, 0xb4, 0xae, 0x49, 0x05, 0x5f, 0xaf, 0x44, 0x94,
+       0xb5, 0x0a, 0x7a, 0xb9, 0x96, 0x36, 0x59, 0x93, 0x02, 0xee, 0x84, 0xd4,
+       0xce, 0x1e, 0xf6, 0x2d, 0x7d, 0xcc, 0x8b, 0x82, 0xa9, 0x65, 0x5e, 0x6a,
+       0xe7, 0xa3, 0x6d, 0x79, 0xb1, 0x8b, 0xd8, 0x44, 0x6c, 0x73, 0x18, 0x07,
+       0xac, 0x79, 0xb4, 0x89, 0x69, 0x5d, 0x72, 0x83, 0xd8, 0xe9, 0x30, 0xf6,
+       0xe7, 0xdd, 0xb8, 0x97, 0x79, 0x70, 0xbe, 0x99, 0xba, 0xf2, 0xbb, 0x31,
+       0x38, 0x77, 0x3b, 0xf6, 0x65, 0x65, 0x9e, 0xe0, 0xa6, 0xfd, 0x92, 0xc4,
+       0x40, 0xcc, 0x3a, 0xc4, 0x3f, 0x65, 0x5a, 0x49, 0xa7, 0x42, 0x5b, 0x74,
+       0x5a, 0xfa, 0xbe, 0xe0, 0xb6, 0x75, 0x6c, 0xcf, 0x2d, 0x9d, 0x09, 0x59,
+       0xab, 0x34, 0xb3, 0xb4, 0xf5, 0xda, 0x99, 0x91, 0x35, 0x4d, 0x9c, 0xd5,
+       0x6d, 0x4c, 0x5b, 0xd2, 0x67, 0x88, 0x32, 0xd7, 0x6c, 0x02, 0xd6, 0xdd,
+       0x80, 0x6b, 0x2b, 0x78, 0xad, 0xfb, 0x3a, 0xae, 0xed, 0x17, 0xec, 0x4c,
+       0x5c, 0xdb, 0xb5, 0x83, 0xb8, 0xb6, 0x5e, 0x29, 0x61, 0x5a, 0x99, 0x59,
+       0x94, 0x70, 0x6d, 0x75, 0x31, 0x7f, 0x1f, 0xc6, 0x5e, 0x62, 0x9e, 0xda,
+       0xfa, 0x11, 0x78, 0xd6, 0x3b, 0x3e, 0x73, 0x60, 0x84, 0xbd, 0x4c, 0x19,
+       0xb0, 0xd2, 0xc4, 0x2d, 0x1b, 0xd2, 0x66, 0xb9, 0x56, 0x1f, 0x2e, 0x77,
+       0xc8, 0x4c, 0x3a, 0x9a, 0x1e, 0x63, 0x9e, 0x71, 0xac, 0x57, 0xd3, 0x49,
+       0x78, 0x02, 0x35, 0xda, 0x3d, 0xc5, 0x5e, 0x22, 0xe4, 0xd9, 0x4e, 0x4c,
+       0x14, 0x8d, 0x7f, 0x6a, 0xce, 0x06, 0x85, 0x46, 0xa1, 0xe0, 0x41, 0xf2,
+       0x11, 0x0f, 0x6b, 0xd4, 0xb2, 0x32, 0x81, 0xd7, 0xa3, 0x21, 0xcf, 0xce,
+       0x7c, 0xda, 0xdb, 0xdd, 0x70, 0x0b, 0x7a, 0x4e, 0x49, 0x3d, 0x0a, 0x63,
+       0xc7, 0xa9, 0x76, 0xd6, 0x20, 0x0d, 0x1d, 0x93, 0x5d, 0xec, 0xf1, 0x7a,
+       0x95, 0xde, 0x39, 0xd1, 0xa1, 0xd8, 0x40, 0x0d, 0x84, 0x1d, 0x37, 0xce,
+       0x4c, 0x4b, 0xfd, 0xf2, 0x7b, 0x96, 0x7f, 0x8d, 0xeb, 0x01, 0xea, 0xe7,
+       0xaa, 0x1b, 0x7e, 0x13, 0x67, 0x74, 0xf1, 0x4b, 0x7e, 0x37, 0x92, 0xd8,
+       0xd6, 0x3c, 0x6d, 0xba, 0x34, 0x99, 0x7d, 0x87, 0x2c, 0x9b, 0x6e, 0x65,
+       0x9d, 0x6b, 0x9f, 0xeb, 0xa3, 0x1d, 0x4b, 0x73, 0xee, 0x1b, 0xed, 0xb9,
+       0xc5, 0xbb, 0x8d, 0x39, 0x8f, 0x3d, 0xbc, 0xc7, 0xc3, 0x3c, 0xea, 0x39,
+       0x65, 0x62, 0x4e, 0x7f, 0xcb, 0x7c, 0x5c, 0x73, 0xd1, 0x6e, 0x5f, 0x65,
+       0x4e, 0x16, 0xcc, 0x92, 0xf0, 0xde, 0x31, 0xe3, 0x72, 0x54, 0x25, 0xd0,
+       0x5c, 0x46, 0x7f, 0xbc, 0x18, 0xb7, 0xe7, 0x91, 0xc7, 0x73, 0xb7, 0x7b,
+       0xbb, 0xb3, 0xec, 0x33, 0xd8, 0x07, 0xdb, 0xbd, 0xdf, 0x57, 0xbd, 0x7b,
+       0xb2, 0x4e, 0xa5, 0x36, 0x01, 0x67, 0xcb, 0x26, 0x13, 0x1f, 0x6f, 0x88,
+       0xa6, 0x42, 0x0e, 0xe6, 0x4f, 0xd2, 0x32, 0x72, 0xcd, 0xde, 0x7e, 0xe6,
+       0xeb, 0x9d, 0x59, 0xba, 0x01, 0x7d, 0xc7, 0xbf, 0x61, 0x74, 0xc0, 0x0f,
+       0x99, 0xb3, 0xe1, 0xeb, 0x8c, 0xd8, 0x20, 0xfd, 0x31, 0xd4, 0xa6, 0x44,
+       0x97, 0x87, 0x10, 0x5d, 0xfa, 0xd8, 0xf9, 0x96, 0xf9, 0x64, 0x6e, 0x13,
+       0x9f, 0xef, 0x62, 0x2e, 0x4d, 0x32, 0xb7, 0x8e, 0xa6, 0xdc, 0x90, 0x77,
+       0xd4, 0xfe, 0x37, 0x95, 0x08, 0xe3, 0x00, 0xbf, 0xc3, 0xe7, 0x03, 0x1d,
+       0xcc, 0xa3, 0x73, 0x7a, 0x34, 0xb9, 0x15, 0xe9, 0xae, 0x6a, 0xa8, 0x7a,
+       0x83, 0x22, 0x73, 0x31, 0xb1, 0x43, 0x0c, 0x3f, 0xe1, 0x9a, 0x2e, 0x4d,
+       0xf4, 0xb8, 0x85, 0xbe, 0x48, 0x6c, 0xe0, 0xf8, 0xbc, 0xdf, 0xfd, 0x5e,
+       0x19, 0x2a, 0x56, 0x50, 0xb6, 0x9f, 0x58, 0x39, 0xc7, 0xab, 0x69, 0xf8,
+       0xaf, 0xc4, 0x4e, 0x7f, 0x96, 0x97, 0xf9, 0x67, 0x09, 0x0f, 0x8a, 0x6f,
+       0x64, 0x5a, 0x6f, 0x9d, 0x8d, 0x15, 0xe7, 0xa1, 0x1e, 0x6f, 0xd7, 0x8c,
+       0x89, 0xac, 0xee, 0x87, 0xf4, 0xff, 0xe5, 0xf1, 0x02, 0xd1, 0x41, 0x13,
+       0x3a, 0x78, 0xbd, 0x7d, 0xa6, 0x52, 0x69, 0xcf, 0x9a, 0xf8, 0x33, 0x5d,
+       0x4d, 0xb7, 0x39, 0x19, 0xef, 0xba, 0x7a, 0x16, 0xf8, 0x19, 0x71, 0x94,
+       0xf8, 0x98, 0x0b, 0x3e, 0xcd, 0xa6, 0xd5, 0x34, 0x7b, 0x3b, 0xb1, 0x85,
+       0xc4, 0x9f, 0x73, 0x6d, 0x05, 0x9a, 0x95, 0x59, 0x97, 0xe8, 0xad, 0x0b,
+       0xc9, 0x7c, 0xa5, 0xb2, 0x8b, 0xba, 0xbc, 0x73, 0xbd, 0x17, 0x97, 0x2c,
+       0x5d, 0xde, 0x4e, 0x5d, 0xe2, 0x8d, 0xd5, 0x70, 0x5e, 0xa8, 0x05, 0xc1,
+       0x44, 0xb9, 0x1a, 0x1e, 0x70, 0x88, 0x4d, 0x18, 0x27, 0x82, 0xd5, 0x50,
+       0xc9, 0x7a, 0x9e, 0x24, 0x0e, 0x26, 0x6e, 0x0c, 0xf4, 0xe1, 0xdb, 0xcc,
+       0x4b, 0x8f, 0xd3, 0x6f, 0x7f, 0xa1, 0x35, 0xa1, 0xe2, 0x3b, 0xcd, 0xb4,
+       0xe9, 0x26, 0xef, 0xf6, 0x6c, 0x3f, 0x9e, 0x58, 0x30, 0xf1, 0x0c, 0x63,
+       0xa6, 0x21, 0x9e, 0x0e, 0x94, 0xb3, 0xaf, 0x63, 0xed, 0x5b, 0x3e, 0x61,
+       0xf9, 0xfc, 0x68, 0xeb, 0x96, 0xf9, 0x10, 0x9c, 0xdf, 0xb6, 0xf6, 0x7e,
+       0x5a, 0xc3, 0xf3, 0xd6, 0xde, 0x0f, 0x3f, 0x4d, 0x0c, 0xeb, 0x6a, 0xf2,
+       0x63, 0x67, 0x05, 0x2a, 0xa3, 0xa6, 0x39, 0x1c, 0xb7, 0xf6, 0x1f, 0x5a,
+       0x63, 0xd6, 0xfd, 0xa3, 0xfc, 0x2c, 0xcd, 0xae, 0xff, 0x46, 0x30, 0x63,
+       0x38, 0x49, 0xf9, 0x77, 0x10, 0x07, 0xf4, 0x13, 0x07, 0xd4, 0x26, 0xd4,
+       0xe4, 0x6e, 0xa7, 0xcc, 0x69, 0x0a, 0x87, 0xaa, 0x79, 0xfd, 0x8e, 0x22,
+       0x0e, 0xa8, 0x3a, 0x25, 0xb3, 0x3f, 0x62, 0x45, 0xd8, 0x7b, 0x26, 0x3d,
+       0xc4, 0x01, 0x15, 0x93, 0x2e, 0x74, 0x13, 0x03, 0xb8, 0x89, 0xd9, 0xb7,
+       0xe5, 0x6a, 0xe1, 0x3d, 0xe1, 0x44, 0x24, 0xfe, 0x23, 0x1c, 0xa2, 0xbf,
+       0x1d, 0x8a, 0x79, 0x94, 0xf0, 0x2a, 0x07, 0x75, 0xf6, 0x2b, 0x1c, 0x0c,
+       0x38, 0x51, 0xa5, 0xbd, 0x86, 0x07, 0xbf, 0xa0, 0xf6, 0xf7, 0x67, 0x25,
+       0xce, 0x47, 0x5b, 0xbb, 0x4f, 0xd9, 0xb5, 0xdf, 0x77, 0x6a, 0x74, 0x59,
+       0x6a, 0x7f, 0xed, 0x86, 0x7e, 0x9c, 0x9e, 0xc1, 0x37, 0x57, 0x13, 0x64,
+       0xd6, 0x72, 0xcd, 0xfa, 0x78, 0x94, 0x3d, 0xb8, 0x3a, 0xd4, 0xa1, 0x44,
+       0x27, 0xaa, 0x98, 0x0f, 0x4e, 0xb3, 0xf6, 0x7b, 0x12, 0xd1, 0x40, 0xcc,
+       0x81, 0x1e, 0x37, 0x6d, 0xf3, 0x3e, 0xfb, 0xf1, 0x9f, 0xe6, 0xc2, 0xa4,
+       0x59, 0x06, 0x17, 0x6b, 0xff, 0xfb, 0x1a, 0x3e, 0x73, 0xd2, 0x0f, 0xdf,
+       0x71, 0x7a, 0x70, 0x35, 0x67, 0xd7, 0xfe, 0xea, 0x06, 0x73, 0xe4, 0x72,
+       0xdc, 0x87, 0x2b, 0x39, 0x9d, 0xfe, 0xd8, 0x8f, 0xa3, 0xac, 0xfd, 0x97,
+       0xb5, 0x00, 0x3e, 0xcc, 0xb5, 0xd0, 0x47, 0x83, 0xf8, 0x39, 0x71, 0xf2,
+       0x7a, 0xd6, 0xfe, 0xbb, 0xe8, 0x5f, 0x71, 0xd6, 0xfe, 0x36, 0x0b, 0x97,
+       0x64, 0x5a, 0xcf, 0x4c, 0x5b, 0xb5, 0xbf, 0xc1, 0xc1, 0xba, 0xe9, 0x46,
+       0x74, 0x99, 0x39, 0xc3, 0xfc, 0xc5, 0x26, 0x1f, 0x9f, 0xa5, 0xde, 0xf2,
+       0x1b, 0x30, 0x6b, 0xd5, 0xaa, 0x2d, 0xde, 0x5d, 0x5c, 0x7b, 0xa5, 0x15,
+       0x73, 0x26, 0x76, 0xac, 0xff, 0x6b, 0xfc, 0x41, 0x8d, 0x83, 0x3e, 0x99,
+       0xf0, 0xde, 0xc9, 0xb8, 0xf3, 0x27, 0x4a, 0xb3, 0x91, 0x18, 0xd7, 0xb9,
+       0xdd, 0x7b, 0x17, 0xfd, 0xe4, 0x96, 0xf5, 0xcc, 0x2a, 0x01, 0x3b, 0xe6,
+       0xda, 0x19, 0x73, 0x21, 0xc6, 0xdc, 0x6a, 0xc6, 0xdc, 0x93, 0x7a, 0x34,
+       0xb6, 0x85, 0xf8, 0xec, 0x95, 0x9c, 0xc4, 0x5d, 0x33, 0xe9, 0xaa, 0x94,
+       0x6b, 0x74, 0x40, 0xe2, 0x67, 0xc7, 0xfa, 0xd1, 0xb3, 0x95, 0x10, 0x5d,
+       0xe1, 0xb3, 0x95, 0xc4, 0x22, 0xcc, 0x52, 0x4b, 0xcb, 0xce, 0x68, 0xea,
+       0x36, 0x67, 0x74, 0xf8, 0x3d, 0xe5, 0x2d, 0xf3, 0x0d, 0xc6, 0xdc, 0x4e,
+       0xc6, 0xdc, 0x2e, 0xc6, 0x5c, 0x9b, 0x61, 0xe2, 0x85, 0xb8, 0xda, 0xdf,
+       0xe4, 0x88, 0xe8, 0x6d, 0x0e, 0xac, 0xae, 0x64, 0x09, 0xf1, 0x22, 0xda,
+       0xf5, 0x07, 0xe4, 0x7f, 0x49, 0x8f, 0xf6, 0xc6, 0x14, 0x89, 0xb3, 0x30,
+       0x3e, 0xa0, 0xdc, 0xe5, 0xc5, 0x38, 0x3b, 0x30, 0x77, 0xbe, 0xe8, 0x1b,
+       0x25, 0xd9, 0x9d, 0x78, 0x5e, 0x67, 0x5e, 0x5d, 0x21, 0xbe, 0xdb, 0x87,
+       0x09, 0xea, 0xd1, 0x1b, 0xed, 0xc3, 0x31, 0xd6, 0xcd, 0xfb, 0x58, 0xaf,
+       0xef, 0x37, 0x22, 0x2d, 0xdb, 0xd9, 0x27, 0x5d, 0x0a, 0xa9, 0xe1, 0xb0,
+       0xd2, 0x87, 0x41, 0xfa, 0xf0, 0x20, 0xeb, 0x4b, 0x9b, 0xf1, 0x4b, 0xa5,
+       0x83, 0x98, 0x62, 0x7f, 0x5e, 0xde, 0x53, 0x63, 0x69, 0xc7, 0x10, 0x06,
+       0x16, 0x24, 0xcf, 0x21, 0x70, 0x53, 0xa2, 0x0f, 0x53, 0x46, 0x19, 0xfa,
+       0x9a, 0x7b, 0x94, 0x3b, 0xf2, 0x32, 0xa7, 0x63, 0x6c, 0x1a, 0x8c, 0x5d,
+       0x8b, 0x5f, 0x05, 0xb9, 0x68, 0x0f, 0x32, 0x12, 0xab, 0xc6, 0x2e, 0xe5,
+       0xae, 0x39, 0x89, 0xf7, 0x3e, 0xa5, 0x4f, 0xe2, 0xd9, 0x48, 0x29, 0x77,
+       0x4b, 0x7c, 0x5b, 0xb3, 0x6d, 0xc9, 0x01, 0xb2, 0xf7, 0x71, 0x3b, 0xf1,
+       0x1e, 0x18, 0x5f, 0xce, 0xef, 0x84, 0x18, 0x83, 0x6d, 0x65, 0x0e, 0xfa,
+       0x69, 0x84, 0xb6, 0x73, 0xa0, 0x5d, 0xff, 0xb2, 0x99, 0x0e, 0x0c, 0x30,
+       0xa6, 0xfa, 0x70, 0xd4, 0x08, 0x99, 0x97, 0x2d, 0x1c, 0x53, 0xca, 0xf1,
+       0x5b, 0x58, 0xeb, 0x56, 0xc1, 0xa3, 0x49, 0x7d, 0xf7, 0x21, 0x56, 0xe3,
+       0x41, 0x85, 0x26, 0xb5, 0x27, 0xd3, 0xba, 0x78, 0x42, 0x91, 0x3e, 0xa5,
+       0x18, 0xeb, 0x5b, 0xf0, 0x00, 0x73, 0xc2, 0xbe, 0xf8, 0xbd, 0xb8, 0x3f,
+       0x50, 0x01, 0x3f, 0xf5, 0xf4, 0x50, 0xc0, 0xc7, 0x5c, 0xfb, 0x7b, 0x45,
+       0x3a, 0x7f, 0x51, 0x56, 0xec, 0xbf, 0xaf, 0x61, 0xb0, 0x5a, 0xc6, 0xd8,
+       0xe6, 0x19, 0x99, 0x27, 0xa5, 0x5a, 0x43, 0x33, 0x1a, 0xfc, 0xec, 0x7b,
+       0xb7, 0xc4, 0xd5, 0xd4, 0x16, 0x67, 0x44, 0x7a, 0x9a, 0x8c, 0x9f, 0xf8,
+       0x2f, 0x17, 0x8d, 0xf6, 0x36, 0x89, 0x8e, 0xb5, 0x10, 0x3a, 0xa9, 0xa7,
+       0xee, 0x5c, 0x90, 0x31, 0xe4, 0x28, 0x17, 0x2c, 0x95, 0xcc, 0x5d, 0xa7,
+       0x15, 0x22, 0xad, 0xd0, 0x8c, 0xe0, 0xba, 0x14, 0x71, 0x9d, 0xc6, 0x38,
+       0x34, 0xcd, 0xcd, 0xc4, 0x73, 0xbe, 0x53, 0x32, 0x97, 0x8a, 0x4c, 0x10,
+       0x03, 0x37, 0x11, 0x1f, 0xf7, 0xd1, 0xab, 0xcd, 0x5b, 0xea, 0xa3, 0x7a,
+       0x9b, 0x82, 0xc7, 0xe6, 0x9b, 0xe1, 0x71, 0x92, 0xe6, 0x3b, 0xb9, 0x00,
+       0x2e, 0xe7, 0x42, 0x78, 0x9b, 0xb4, 0x2f, 0x59, 0xb4, 0xeb, 0xf0, 0xb3,
+       0x62, 0x0e, 0x8b, 0x33, 0x87, 0x6d, 0xcd, 0x2a, 0xf4, 0xd7, 0x30, 0x46,
+       0xf4, 0xbf, 0xfa, 0xec, 0xd2, 0xcd, 0x1e, 0xea, 0x4d, 0x64, 0x71, 0xf1,
+       0x73, 0x1c, 0x0f, 0x59, 0x39, 0xfb, 0xb5, 0xcf, 0x66, 0x6b, 0x68, 0x2b,
+       0xea, 0xbe, 0xba, 0xf8, 0xde, 0xba, 0xd9, 0x3f, 0x2f, 0xca, 0xdb, 0x53,
+       0xb4, 0x35, 0x71, 0x9b, 0x71, 0x9e, 0xd7, 0x04, 0x47, 0x69, 0x70, 0x9c,
+       0x8a, 0xa1, 0xec, 0xd4, 0x35, 0xfe, 0x35, 0x89, 0x19, 0x56, 0xde, 0xc7,
+       0xbe, 0x4b, 0x9e, 0x1e, 0x21, 0x5e, 0x34, 0xc9, 0xd3, 0x55, 0x8b, 0x97,
+       0x20, 0x79, 0xf9, 0xe4, 0xb3, 0x12, 0xb6, 0x0c, 0x5d, 0x7b, 0x27, 0x40,
+       0x7d, 0xe0, 0xd1, 0x10, 0xf5, 0x79, 0x65, 0xa3, 0x3c, 0xe7, 0xc3, 0x1d,
+       0xb9, 0x44, 0xb9, 0xe4, 0x79, 0xaf, 0xb6, 0x05, 0x7b, 0xe7, 0x3e, 0xaf,
+       0xf7, 0x20, 0x6d, 0x11, 0xa0, 0xf1, 0xe4, 0xde, 0x17, 0xd5, 0xd4, 0x3f,
+       0x42, 0x8a, 0x3d, 0xd3, 0x23, 0xd9, 0x34, 0x1e, 0xca, 0x7e, 0xcb, 0xda,
+       0xcb, 0x5b, 0xb7, 0x01, 0xfb, 0x49, 0xff, 0x60, 0x35, 0xe3, 0xe8, 0x7f,
+       0xc4, 0xa3, 0x82, 0xa5, 0x76, 0x55, 0x42, 0xea, 0x6e, 0xb4, 0xe5, 0x36,
+       0xc5, 0x44, 0x59, 0x1c, 0xc3, 0xed, 0xcd, 0xd1, 0xd8, 0x65, 0x3c, 0x66,
+       0xca, 0x5c, 0xdc, 0x59, 0xac, 0xc1, 0xc4, 0xaf, 0x4a, 0x3b, 0xeb, 0x70,
+       0x5b, 0x11, 0x53, 0x6d, 0xcd, 0xbf, 0xf5, 0xb9, 0xd9, 0x83, 0xf4, 0xed,
+       0x52, 0x7b, 0xbc, 0x4a, 0x1b, 0xd7, 0x39, 0xca, 0x9c, 0xfd, 0xbc, 0xfe,
+       0x52, 0x88, 0x95, 0x19, 0xae, 0xf5, 0x0a, 0x0e, 0x11, 0x3f, 0xa5, 0x83,
+       0x26, 0x76, 0xf1, 0xf3, 0x00, 0x71, 0xd6, 0xbb, 0x7a, 0x15, 0x66, 0x03,
+       0x01, 0x62, 0x4b, 0xe6, 0x60, 0xc7, 0xdf, 0x49, 0x4d, 0x88, 0x85, 0x1d,
+       0xb2, 0x57, 0xff, 0x6f, 0xed, 0xdf, 0xac, 0x27, 0x96, 0x11, 0xd9, 0xbd,
+       0x0a, 0x73, 0x68, 0x0c, 0xc4, 0x37, 0x7b, 0xf5, 0x42, 0xd8, 0x81, 0xe4,
+       0x55, 0x07, 0xd4, 0xd3, 0xef, 0xb0, 0x1f, 0x7c, 0xa4, 0x5e, 0x3d, 0xdd,
+       0xea, 0xd4, 0x90, 0x9a, 0xf2, 0xe0, 0xe1, 0xa9, 0x0e, 0x54, 0x5b, 0x73,
+       0xa4, 0x71, 0xda, 0xcc, 0xc1, 0x3e, 0x6c, 0xf4, 0x53, 0x17, 0xfb, 0xb1,
+       0xab, 0x1b, 0x1e, 0x45, 0x8b, 0x75, 0x7d, 0x0c, 0xfb, 0xb3, 0x5e, 0xa5,
+       0x3b, 0xeb, 0x42, 0xc7, 0x5d, 0x8f, 0xc2, 0xbd, 0x7e, 0x80, 0x7c, 0xc9,
+       0x75, 0xf9, 0xfb, 0x6e, 0xf6, 0x71, 0xc2, 0x5f, 0x19, 0xc2, 0xab, 0xc8,
+       0xdb, 0x7a, 0x0d, 0x23, 0x53, 0x2e, 0x65, 0xb7, 0xf1, 0x37, 0xe6, 0x55,
+       0x6b, 0x6f, 0x48, 0xae, 0x55, 0xc8, 0x99, 0x01, 0x3e, 0x23, 0x39, 0x67,
+       0x10, 0x59, 0xc6, 0xf6, 0xdd, 0xd6, 0xfb, 0xa7, 0xca, 0x6c, 0x99, 0x92,
+       0xec, 0x6f, 0xdb, 0xe9, 0x1f, 0xf2, 0x4c, 0x5b, 0xf1, 0xda, 0x76, 0x8f,
+       0x7d, 0x2e, 0x41, 0xec, 0x3e, 0x88, 0x5b, 0x69, 0x84, 0xfa, 0xa8, 0xf8,
+       0xd8, 0x20, 0xea, 0x73, 0x4c, 0xa8, 0xab, 0x6c, 0x7e, 0x1f, 0x34, 0x0a,
+       0xec, 0x4d, 0x35, 0xe6, 0x4d, 0xea, 0x6e, 0xa5, 0xbc, 0x4f, 0x47, 0xfd,
+       0xb5, 0xf7, 0x4b, 0xf5, 0x54, 0x70, 0xe9, 0x17, 0xdd, 0xff, 0x4d, 0xc8,
+       0x3d, 0x97, 0xf6, 0x87, 0x8c, 0xe3, 0x68, 0x6f, 0xa5, 0x43, 0xfc, 0xe7,
+       0x0f, 0x71, 0xff, 0x1c, 0x1b, 0xd7, 0x0a, 0xa1, 0x4f, 0xdc, 0x6b, 0xb8,
+       0x94, 0x2e, 0xe6, 0x9f, 0x03, 0x53, 0x8e, 0x3b, 0xca, 0xf0, 0xe7, 0x66,
+       0xf9, 0xca, 0x11, 0xd4, 0xc7, 0xc7, 0xf8, 0xbc, 0x82, 0x76, 0x62, 0xc8,
+       0x27, 0xf4, 0xad, 0xe8, 0xa8, 0x91, 0x1c, 0xf0, 0xbc, 0x39, 0xd8, 0x27,
+       0x3a, 0x54, 0xb0, 0x8d, 0xd7, 0x5f, 0xa0, 0x7d, 0x9f, 0xd6, 0x5d, 0xa8,
+       0x5f, 0x21, 0x33, 0x41, 0x75, 0x3a, 0x89, 0x3d, 0x1e, 0x7b, 0x8f, 0x2c,
+       0x6d, 0x56, 0x6b, 0xda, 0xf0, 0x9d, 0x8e, 0xfa, 0xe9, 0x37, 0xe9, 0x4f,
+       0x6d, 0xeb, 0x6f, 0xbc, 0x57, 0xd2, 0x89, 0x8e, 0xd0, 0xfa, 0xe7, 0x4c,
+       0xdc, 0x34, 0x8a, 0xc0, 0xfa, 0x1b, 0xed, 0x5f, 0xe2, 0xfb, 0x30, 0x63,
+       0x10, 0xe9, 0xea, 0x84, 0xcc, 0x89, 0xa2, 0xa4, 0x73, 0x18, 0xbf, 0x9f,
+       0x1f, 0xc3, 0xa1, 0xac, 0xc8, 0xb9, 0x60, 0xf9, 0xb6, 0xb6, 0xfe, 0xba,
+       0x6c, 0x0f, 0x66, 0xa3, 0x03, 0x55, 0x45, 0xd9, 0x0e, 0xb2, 0x1f, 0xa9,
+       0x64, 0x8e, 0x7d, 0x80, 0x3a, 0x1d, 0xb6, 0x74, 0xda, 0x07, 0x3d, 0x77,
+       0x9d, 0xee, 0x10, 0xe9, 0x7a, 0x13, 0xa2, 0x37, 0xd9, 0x97, 0x63, 0x2f,
+       0x40, 0xba, 0xfb, 0x6e, 0xa0, 0x3b, 0xa8, 0x5f, 0xa7, 0xbb, 0x37, 0x1b,
+       0x3d, 0xed, 0x28, 0xd2, 0xfd, 0xc6, 0x5c, 0x89, 0x46, 0x1a, 0x3b, 0xd7,
+       0xa7, 0x91, 0xdb, 0x7c, 0xd0, 0x3c, 0x68, 0xe9, 0xe3, 0xfb, 0xd6, 0xf5,
+       0x6d, 0xf5, 0x12, 0x0f, 0xfc, 0x33, 0xa1, 0x59, 0x67, 0x00, 0x6c, 0x1c,
+       0x76, 0x63, 0x7c, 0xa8, 0x6f, 0x75, 0x3b, 0x93, 0x8c, 0xe3, 0xa0, 0x67,
+       0xfb, 0xe7, 0x66, 0x1f, 0x1d, 0xec, 0xd7, 0x3a, 0x8d, 0x1e, 0x6f, 0x97,
+       0xe1, 0x21, 0x06, 0xab, 0x54, 0xb6, 0x65, 0x65, 0x06, 0x22, 0xb1, 0x5c,
+       0xc4, 0xc5, 0x79, 0xe9, 0x0b, 0xef, 0x61, 0xcf, 0xb0, 0x81, 0xf6, 0x1d,
+       0xc0, 0x44, 0x7e, 0x40, 0x49, 0x06, 0xb9, 0x8e, 0x21, 0x75, 0x05, 0xac,
+       0x79, 0xbd, 0xa8, 0xa4, 0x2f, 0x05, 0x13, 0xd3, 0x89, 0x93, 0xf5, 0x26,
+       0x88, 0x51, 0x3c, 0x2b, 0x12, 0xb3, 0x89, 0x5d, 0xf5, 0x4e, 0x1c, 0xb7,
+       0xb0, 0x98, 0x3a, 0xcb, 0xdf, 0x69, 0x89, 0x99, 0x3b, 0xb3, 0x52, 0xc7,
+       0x08, 0x27, 0xb5, 0x11, 0xfc, 0x63, 0xbc, 0x30, 0x5c, 0x83, 0xe4, 0x7d,
+       0x35, 0x90, 0x1e, 0x63, 0x02, 0x7f, 0xa9, 0x85, 0x3c, 0xfd, 0x79, 0x97,
+       0xd2, 0x6d, 0xcc, 0x7b, 0x77, 0x18, 0x7e, 0xf8, 0xd8, 0xbf, 0xf5, 0x38,
+       0x23, 0xec, 0x39, 0xac, 0x19, 0x7d, 0xeb, 0xad, 0xb9, 0x7e, 0x6f, 0xbb,
+       0x61, 0xe7, 0xc2, 0x5b, 0x66, 0x3d, 0xde, 0x8e, 0x99, 0x48, 0x68, 0xc2,
+       0xc2, 0x62, 0x07, 0x5b, 0x23, 0x39, 0xd3, 0x7c, 0x55, 0x2f, 0x5c, 0x2d,
+       0xb7, 0xbe, 0x4f, 0xb7, 0xc6, 0x72, 0x4d, 0xd8, 0x43, 0xfc, 0xd4, 0x36,
+       0xd3, 0x04, 0x7d, 0x06, 0x38, 0x31, 0x15, 0xc2, 0xba, 0xac, 0x7a, 0x3a,
+       0xe5, 0xec, 0xc7, 0xf4, 0x42, 0x17, 0xb2, 0x79, 0xef, 0x72, 0xd8, 0x41,
+       0x8c, 0x1d, 0x77, 0xe0, 0x0e, 0x7d, 0x83, 0x52, 0xb0, 0x62, 0x5a, 0xc1,
+       0xdd, 0xfa, 0x2e, 0x65, 0xc0, 0xc2, 0x14, 0xf3, 0xc4, 0x22, 0x0a, 0x6e,
+       0xb2, 0x72, 0xef, 0xc9, 0xd6, 0x38, 0xf1, 0xf7, 0x1d, 0x59, 0xa9, 0xef,
+       0x26, 0x2e, 0xc6, 0xa9, 0x97, 0x78, 0xba, 0xdf, 0xcd, 0x7e, 0xe8, 0xa0,
+       0xa2, 0xf6, 0xea, 0x8a, 0x8d, 0xf1, 0x6e, 0x9b, 0xb7, 0x71, 0xe1, 0xad,
+       0xf3, 0xcd, 0x5e, 0xc9, 0x41, 0xed, 0xba, 0x1a, 0x72, 0x39, 0x02, 0x18,
+       0xb6, 0x68, 0xa4, 0x5b, 0xf5, 0xf9, 0x32, 0xac, 0xd6, 0xfa, 0x70, 0xda,
+       0x92, 0x61, 0xa2, 0x75, 0x0b, 0xb1, 0xf6, 0x93, 0x46, 0x3f, 0x7b, 0x65,
+       0xd9, 0x37, 0x8d, 0xc4, 0x5a, 0x9c, 0x6d, 0xc4, 0xb3, 0x91, 0xf0, 0xb2,
+       0x92, 0x54, 0xd2, 0xae, 0xc6, 0xe4, 0x3c, 0x58, 0x51, 0x6a, 0xec, 0xfa,
+       0x26, 0x32, 0x46, 0x89, 0xb3, 0xda, 0xa6, 0xbc, 0xcb, 0x49, 0xd8, 0x73,
+       0x9e, 0x4e, 0xfd, 0xff, 0xe0, 0x52, 0x50, 0x9d, 0x48, 0x92, 0xef, 0x0e,
+       0xe6, 0xdd, 0x42, 0x9f, 0x8b, 0xf7, 0x65, 0xbe, 0x37, 0xdc, 0x3a, 0x9e,
+       0x41, 0xc1, 0x99, 0x90, 0x1e, 0x0b, 0xfe, 0xde, 0x3c, 0x64, 0xd6, 0xc4,
+       0x3e, 0xe3, 0x53, 0xb3, 0xb4, 0xc7, 0xd4, 0x33, 0x63, 0xef, 0x9f, 0x65,
+       0x16, 0x5c, 0xfe, 0x1d, 0x46, 0x33, 0x8e, 0xe7, 0x5d, 0x37, 0xd0, 0x8e,
+       0x4e, 0xdc, 0xe2, 0x70, 0x20, 0xba, 0xfe, 0x6e, 0xa5, 0xb8, 0x07, 0xc5,
+       0x3c, 0x91, 0xb2, 0x6a, 0x62, 0x19, 0xe5, 0xbc, 0x70, 0x52, 0xd6, 0xf8,
+       0x56, 0xeb, 0xf8, 0x49, 0xa9, 0x91, 0xc3, 0xad, 0x21, 0x43, 0xed, 0x95,
+       0x9e, 0xb0, 0x9a, 0x7a, 0xfa, 0x68, 0x52, 0x6a, 0xf0, 0x14, 0x6b, 0xb0,
+       0xba, 0xdc, 0xae, 0x48, 0x1d, 0x53, 0x63, 0x5e, 0xa7, 0x03, 0x57, 0x1a,
+       0xd4, 0xfe, 0x1f, 0x40, 0x1d, 0xb0, 0xe7, 0x8a, 0x8f, 0xb6, 0x36, 0x16,
+       0xf1, 0xf0, 0x6d, 0xf3, 0x83, 0x72, 0xee, 0xc4, 0xd2, 0x71, 0x53, 0x4e,
+       0xb0, 0xb1, 0x69, 0xbe, 0x1c, 0xef, 0x21, 0x6e, 0x10, 0x6c, 0x2c, 0xd7,
+       0x27, 0x5b, 0x1b, 0x66, 0x3d, 0xe4, 0x4d, 0xc1, 0x7b, 0x5a, 0x0f, 0x7d,
+       0xaf, 0xc4, 0xa3, 0x8d, 0x9b, 0xb7, 0x13, 0x37, 0x3b, 0x13, 0x6a, 0xcb,
+       0x56, 0xe2, 0x66, 0x8d, 0xfd, 0x84, 0x0b, 0x7d, 0x78, 0xc2, 0xb0, 0x7b,
+       0x0a, 0xc1, 0xce, 0xe6, 0x49, 0x35, 0x29, 0xb8, 0xf9, 0xea, 0x06, 0x60,
+       0x37, 0x71, 0xf3, 0x72, 0xc6, 0x85, 0x7e, 0xe2, 0xe6, 0x8f, 0x98, 0x82,
+       0xee, 0x24, 0x6e, 0xbe, 0x42, 0x8c, 0x75, 0x3e, 0xfe, 0x73, 0x7c, 0xa3,
+       0x38, 0x3b, 0xdb, 0x4b, 0xec, 0x9c, 0x0c, 0xde, 0x88, 0x9d, 0xff, 0xe2,
+       0x5f, 0x60, 0xe7, 0x3d, 0xc4, 0x84, 0x3d, 0x59, 0xd9, 0x67, 0x1a, 0x6d,
+       0x7d, 0xe3, 0x94, 0x9c, 0x6d, 0xb9, 0x0d, 0xef, 0x9e, 0x1c, 0x1d, 0x22,
+       0x56, 0xc6, 0x58, 0xbc, 0x1f, 0x99, 0x19, 0xac, 0x22, 0x2e, 0x78, 0xd9,
+       0xc9, 0x75, 0xd7, 0xc5, 0x55, 0xfd, 0x4d, 0x25, 0xda, 0xd5, 0x8f, 0x28,
+       0xfb, 0x66, 0x75, 0x99, 0x26, 0x4c, 0xba, 0x12, 0xc4, 0xc6, 0xac, 0x81,
+       0xab, 0x89, 0x9d, 0xab, 0x16, 0x81, 0xda, 0x45, 0x1b, 0x3b, 0xcb, 0xdc,
+       0xac, 0x2a, 0x8a, 0x3f, 0x22, 0x76, 0x66, 0xaf, 0xcb, 0x50, 0x5b, 0x6c,
+       0x62, 0x8c, 0x2a, 0x38, 0x1a, 0xf5, 0xa1, 0x67, 0x8a, 0xb8, 0xc7, 0x9a,
+       0x9b, 0x99, 0x23, 0x3f, 0xd6, 0xfb, 0x71, 0x6c, 0xc1, 0x9e, 0x9b, 0x75,
+       0x12, 0xbf, 0xb9, 0xa2, 0x41, 0x94, 0x2f, 0xba, 0xf0, 0x1c, 0xf1, 0xf3,
+       0x36, 0xda, 0xf9, 0x0c, 0xf1, 0xf3, 0x9e, 0x1b, 0x66, 0x67, 0xb3, 0x8b,
+       0x78, 0x95, 0x58, 0xbe, 0xae, 0x16, 0x51, 0x99, 0x8b, 0x98, 0x57, 0x36,
+       0xfa, 0x70, 0xce, 0xc2, 0xcf, 0xde, 0xe5, 0xb4, 0x62, 0xcb, 0x56, 0x46,
+       0x5b, 0x88, 0x5d, 0x1d, 0xb4, 0x6b, 0xdb, 0x49, 0xb5, 0xeb, 0x25, 0xea,
+       0xa2, 0x31, 0x7a, 0xde, 0xb2, 0xc7, 0x60, 0x5c, 0x66, 0x2c, 0x43, 0xad,
+       0x72, 0xfe, 0xaa, 0x82, 0xf6, 0xee, 0x9e, 0x8c, 0x24, 0x3f, 0x80, 0x1d,
+       0x93, 0xb1, 0x5c, 0x59, 0xb1, 0x1e, 0xca, 0xbd, 0x09, 0xde, 0x4b, 0xa2,
+       0x6b, 0xa3, 0xed, 0xdf, 0xb1, 0xdc, 0x71, 0x62, 0x57, 0xd9, 0x5b, 0x0d,
+       0xf8, 0x3b, 0x8d, 0x2e, 0x4c, 0x1b, 0x61, 0x94, 0x9f, 0x2b, 0xee, 0xd1,
+       0x9e, 0x93, 0x33, 0x7b, 0x8f, 0xb6, 0x06, 0xbe, 0x53, 0xc2, 0x84, 0x49,
+       0xe2, 0xbb, 0xa0, 0xe7, 0x8e, 0xbc, 0xe0, 0xc5, 0x5e, 0x1c, 0x33, 0xd4,
+       0xd0, 0x4f, 0x18, 0x13, 0xf7, 0xc9, 0xfe, 0xfc, 0x0d, 0x33, 0xaa, 0x87,
+       0x79, 0xcf, 0xf8, 0xdc, 0x8c, 0x2a, 0x95, 0xc5, 0xaf, 0x9c, 0xcd, 0xe5,
+       0x70, 0xac, 0x93, 0x19, 0x89, 0x1a, 0x1a, 0xc3, 0x63, 0xc4, 0x1c, 0xbf,
+       0x54, 0x7c, 0x9a, 0x6b, 0xa8, 0xc9, 0xa9, 0x86, 0xe6, 0x15, 0x1f, 0xdf,
+       0xbd, 0x87, 0xf9, 0xed, 0x1e, 0xfa, 0x46, 0x64, 0xb9, 0x42, 0x71, 0xe2,
+       0xd2, 0x97, 0x2d, 0x3c, 0xea, 0xed, 0xe5, 0xb5, 0xe9, 0x7c, 0x09, 0xd7,
+       0xf4, 0x09, 0xaf, 0xe8, 0x9c, 0xb2, 0x73, 0x88, 0x96, 0xf3, 0x2e, 0x5f,
+       0x82, 0x2d, 0x5b, 0x25, 0x65, 0x7d, 0x60, 0x32, 0x60, 0x0e, 0xac, 0x94,
+       0x18, 0xd6, 0xb0, 0xd3, 0x10, 0xff, 0x1a, 0x24, 0x9f, 0x7d, 0x38, 0x62,
+       0xac, 0x66, 0xef, 0x26, 0xf3, 0xd2, 0x26, 0x62, 0xeb, 0x5e, 0xd6, 0x60,
+       0xd3, 0x4c, 0xe9, 0x69, 0xb3, 0x69, 0x93, 0xa6, 0xe7, 0x94, 0x42, 0x4d,
+       0x88, 0xf8, 0x66, 0x3d, 0x6b, 0x77, 0x5b, 0xbe, 0x09, 0x6f, 0x9e, 0xd1,
+       0xe8, 0x9b, 0xed, 0xc4, 0xef, 0xbd, 0xb8, 0x97, 0xf2, 0x7c, 0x23, 0xff,
+       0x4d, 0x24, 0xbf, 0xee, 0xc2, 0xc4, 0x54, 0x12, 0x5b, 0xd6, 0x8f, 0xe0,
+       0xd2, 0xef, 0x78, 0x98, 0xab, 0x7c, 0x78, 0x72, 0x4a, 0xf2, 0x6b, 0x09,
+       0x6f, 0xdf, 0x88, 0x45, 0x3c, 0x08, 0x5b, 0x38, 0xe4, 0x8b, 0xef, 0xd9,
+       0x18, 0xc5, 0xcb, 0x5e, 0xb8, 0xf4, 0x3e, 0xf3, 0xd0, 0xfa, 0x7f, 0x81,
+       0x67, 0x88, 0x5b, 0x88, 0x05, 0x2a, 0x62, 0xd6, 0xf9, 0xb8, 0x12, 0xde,
+       0x75, 0xd1, 0x07, 0x24, 0xa6, 0x57, 0x33, 0xd6, 0x4d, 0x62, 0xe7, 0xe5,
+       0xe2, 0xfc, 0xf2, 0xed, 0x93, 0xea, 0xd2, 0x11, 0x44, 0x88, 0xa1, 0x31,
+       0x28, 0xd8, 0xcd, 0x49, 0xbc, 0x7b, 0x25, 0x1a, 0xd5, 0xcf, 0x11, 0xef,
+       0x8e, 0xd2, 0xd6, 0x2e, 0x4d, 0x7c, 0x33, 0x80, 0xb2, 0xc5, 0x10, 0x7d,
+       0x52, 0xe6, 0x97, 0x7f, 0xe5, 0xb5, 0xe7, 0x97, 0x32, 0x33, 0x97, 0xf3,
+       0x23, 0xe8, 0x28, 0x63, 0xef, 0x56, 0xae, 0xa4, 0x99, 0x93, 0x67, 0xbd,
+       0xbb, 0x99, 0xdf, 0xfb, 0x8d, 0xa0, 0x7f, 0x77, 0x3e, 0xc0, 0xdf, 0x3a,
+       0x7f, 0x7f, 0x7e, 0x07, 0x9f, 0x0f, 0xf1, 0x33, 0x8c, 0x6c, 0x2e, 0x52,
+       0x21, 0xcd, 0x40, 0x36, 0x67, 0xe7, 0xbc, 0x70, 0xee, 0x90, 0x57, 0xb0,
+       0x66, 0xdb, 0x94, 0xfd, 0x5d, 0xbb, 0xe1, 0xfb, 0xe7, 0x31, 0xbf, 0x9b,
+       0x7c, 0x9f, 0x39, 0xa9, 0xe1, 0xa3, 0x93, 0x16, 0xe6, 0x2f, 0x10, 0xf3,
+       0x0f, 0xbb, 0x9d, 0x82, 0x35, 0x7f, 0x61, 0x9e, 0x8f, 0x46, 0x07, 0xe6,
+       0xe8, 0x07, 0x3d, 0xa4, 0xeb, 0xd0, 0x82, 0x16, 0xbf, 0x36, 0x9f, 0xf6,
+       0xcc, 0xf7, 0xf2, 0xc9, 0x18, 0xde, 0xb9, 0x3e, 0x63, 0xfd, 0xa4, 0xcc,
+       0x9a, 0x15, 0xe3, 0xb1, 0x77, 0x37, 0xc1, 0xd3, 0xc2, 0x7e, 0xd3, 0xcd,
+       0xe7, 0x43, 0xd6, 0xf3, 0x32, 0xf3, 0xbd, 0x8e, 0x9d, 0x3f, 0xba, 0xfe,
+       0xce, 0x61, 0x76, 0x6a, 0x9e, 0xf3, 0x8c, 0x2d, 0xa7, 0xf5, 0x9c, 0xcc,
+       0x65, 0xbd, 0xcb, 0xb0, 0xe2, 0x6b, 0x88, 0x32, 0x89, 0x7d, 0x0f, 0x99,
+       0xb6, 0xdf, 0x06, 0xfd, 0x3b, 0x19, 0x0f, 0xdf, 0xa6, 0x7d, 0x76, 0x9e,
+       0xab, 0xf3, 0xdf, 0x6d, 0xec, 0xb2, 0x64, 0xbe, 0xfb, 0x9c, 0xd4, 0x24,
+       0xb9, 0xff, 0x40, 0x85, 0x60, 0xef, 0x27, 0x59, 0xb3, 0x46, 0x0d, 0xd9,
+       0x03, 0x80, 0xe2, 0x4a, 0x1c, 0x41, 0xe7, 0x74, 0x18, 0x6f, 0xeb, 0xde,
+       0xe2, 0x59, 0x17, 0x89, 0xc9, 0x69, 0xc6, 0x64, 0x10, 0x63, 0x46, 0x24,
+       0xfc, 0x36, 0xf1, 0x69, 0x9a, 0x0c, 0x1f, 0xcb, 0x3a, 0xf1, 0x36, 0x31,
+       0x23, 0x14, 0xfb, 0xac, 0xa8, 0xfd, 0x6e, 0xe9, 0xef, 0x4a, 0x84, 0x6b,
+       0x22, 0x2d, 0x07, 0x50, 0x87, 0x0c, 0x73, 0xbe, 0x57, 0xfb, 0x21, 0x8e,
+       0x9f, 0x70, 0xe0, 0x7e, 0xf6, 0x7d, 0xc9, 0xbb, 0x74, 0x7e, 0x6f, 0x1c,
+       0x7a, 0x1f, 0xff, 0x68, 0xce, 0xca, 0x79, 0x2c, 0x45, 0xce, 0x7c, 0x7c,
+       0x62, 0xd6, 0x6a, 0x5a, 0xe1, 0x07, 0xd0, 0x52, 0x57, 0xd1, 0x38, 0xbc,
+       0x8c, 0x0f, 0xcc, 0x02, 0xef, 0xbd, 0xc7, 0xf8, 0x79, 0x49, 0x8f, 0x84,
+       0x1c, 0x14, 0xa6, 0x10, 0x74, 0xe2, 0x3e, 0x5d, 0xe6, 0x29, 0xea, 0xf0,
+       0xb3, 0x50, 0x87, 0x2e, 0x28, 0x72, 0x86, 0xe7, 0x92, 0x99, 0xae, 0x91,
+       0x75, 0x15, 0xac, 0x5b, 0xd3, 0xd8, 0x55, 0x06, 0xb5, 0xc5, 0xad, 0x68,
+       0xfa, 0xfb, 0xca, 0xff, 0x32, 0x0b, 0xc1, 0x4f, 0xcc, 0x77, 0xb4, 0x12,
+       0x5d, 0x35, 0xec, 0x71, 0x96, 0x78, 0xab, 0xc3, 0x71, 0x43, 0xf6, 0xf1,
+       0x7e, 0x88, 0xfb, 0x4f, 0xb8, 0xd0, 0x1e, 0xff, 0xb9, 0x99, 0x0e, 0x0a,
+       0xcd, 0x50, 0x25, 0x2a, 0x84, 0xbe, 0x3d, 0xdb, 0x7e, 0x31, 0x0f, 0xa5,
+       0xc3, 0x10, 0xbc, 0x2c, 0x7e, 0x3a, 0x0d, 0xd3, 0x90, 0x99, 0xa2, 0x89,
+       0x3b, 0xe3, 0x23, 0x78, 0x2f, 0x9e, 0xfc, 0x4f, 0x1e, 0xa8, 0x4b, 0x97,
+       0x9d, 0x6a, 0xa1, 0xc9, 0x19, 0x56, 0xbc, 0x0d, 0xda, 0x70, 0x83, 0x55,
+       0x6f, 0x2e, 0xb2, 0x77, 0xf2, 0x31, 0xb7, 0x48, 0x8f, 0x39, 0x8d, 0xc5,
+       0xc9, 0x34, 0x5c, 0xc4, 0x76, 0xa3, 0xcd, 0x6a, 0xff, 0x33, 0x8a, 0x1a,
+       0x3a, 0xa8, 0x84, 0x95, 0x7b, 0xb5, 0x14, 0x9e, 0xd3, 0xa3, 0xc9, 0x36,
+       0xa5, 0xce, 0xd3, 0x95, 0x2f, 0xd1, 0x6e, 0x27, 0x56, 0x51, 0x0b, 0x97,
+       0x9d, 0xe5, 0xa8, 0xdd, 0xa0, 0x75, 0x95, 0x3b, 0xd5, 0xd4, 0xd7, 0x18,
+       0x5f, 0xdb, 0xf3, 0x05, 0xef, 0xfb, 0x51, 0x07, 0xd6, 0x5a, 0xfb, 0x0d,
+       0x99, 0xe2, 0xbc, 0x74, 0x1a, 0xdd, 0x93, 0xe6, 0x96, 0x8b, 0x71, 0x35,
+       0xf4, 0x8c, 0x92, 0xde, 0xed, 0x23, 0xa6, 0x79, 0x00, 0x5a, 0x78, 0x81,
+       0x75, 0xaa, 0x3d, 0xef, 0xc0, 0x2d, 0xa7, 0x84, 0x66, 0x86, 0x34, 0x8f,
+       0xa0, 0xfc, 0x84, 0xb9, 0x65, 0xb7, 0xae, 0xa6, 0x2e, 0x3b, 0xd3, 0xff,
+       0xbd, 0x96, 0x7a, 0xeb, 0x50, 0x64, 0xbf, 0x6d, 0x84, 0xb8, 0x62, 0x44,
+       0xce, 0xcd, 0xc5, 0xfe, 0x98, 0x98, 0xe2, 0x5b, 0xf4, 0x55, 0x67, 0xc2,
+       0x4f, 0x3e, 0xd5, 0xd8, 0x1c, 0x64, 0xce, 0x1e, 0xc6, 0x65, 0x3d, 0xed,
+       0xed, 0x6c, 0x88, 0x11, 0x9b, 0x85, 0x58, 0x07, 0xc3, 0x38, 0x46, 0x8c,
+       0x77, 0x24, 0x5f, 0x86, 0x42, 0x40, 0x23, 0x36, 0xeb, 0x85, 0x63, 0xd2,
+       0xa7, 0xcc, 0x67, 0x22, 0x7a, 0x3b, 0xfe, 0x33, 0x0a, 0x21, 0x71, 0x91,
+       0x23, 0xf0, 0x9d, 0xf8, 0x7b, 0xb3, 0x4a, 0xd3, 0x5a, 0x26, 0x15, 0xae,
+       0xfb, 0x54, 0x88, 0x3a, 0xe6, 0x7b, 0x72, 0xbe, 0xc5, 0xe8, 0xc1, 0xbd,
+       0x93, 0x41, 0xbe, 0x5f, 0x85, 0x75, 0x27, 0xc2, 0xb8, 0x12, 0xbf, 0x19,
+       0x85, 0x1a, 0x1b, 0x03, 0x79, 0x35, 0xfa, 0x11, 0xfb, 0xac, 0x34, 0x7b,
+       0x4a, 0xd9, 0x63, 0x3a, 0x62, 0x48, 0x7f, 0xee, 0xe2, 0x77, 0x1f, 0x7f,
+       0x45, 0x9f, 0xdf, 0x2a, 0x62, 0x9d, 0xa9, 0xd6, 0xf0, 0xfc, 0xcf, 0x2b,
+       0xec, 0x79, 0x5a, 0x98, 0xcf, 0x05, 0xac, 0x19, 0xe1, 0x28, 0x69, 0x9e,
+       0x9d, 0x96, 0xbe, 0xad, 0x6d, 0xb3, 0xa7, 0xb8, 0x4f, 0xff, 0x53, 0xdd,
+       0x81, 0x2d, 0xec, 0xed, 0x43, 0x9a, 0xd4, 0xcb, 0x51, 0xb5, 0x16, 0x9b,
+       0x71, 0x3a, 0xc0, 0x26, 0x5c, 0xfb, 0x0f, 0x98, 0x08, 0xc4, 0x98, 0xf3,
+       0x35, 0xbc, 0x9b, 0xf9, 0x32, 0xfb, 0x9d, 0x3a, 0x39, 0xe3, 0x83, 0x5b,
+       0x4e, 0xb8, 0xb9, 0xe6, 0x16, 0xe2, 0x9a, 0x4e, 0xbc, 0x16, 0xb0, 0x7b,
+       0x8d, 0xa3, 0xbc, 0x3e, 0x3e, 0xe7, 0x23, 0x16, 0xf5, 0xf0, 0xf7, 0x46,
+       0xde, 0xbe, 0x88, 0x27, 0x91, 0xe5, 0xdf, 0xe2, 0xc9, 0x43, 0x3c, 0xa0,
+       0xe1, 0x6a, 0xe6, 0x65, 0x5c, 0x21, 0xed, 0xf4, 0x9c, 0x4d, 0x73, 0x2a,
+       0x2f, 0x74, 0x65, 0xbd, 0x48, 0xaa, 0xd6, 0x29, 0xf4, 0x7d, 0x72, 0xde,
+       0xf7, 0xdf, 0xb9, 0x06, 0x91, 0xdd, 0x09, 0xf6, 0xc7, 0x7a, 0x03, 0xda,
+       0x03, 0xb4, 0x97, 0x21, 0x6b, 0xa8, 0xec, 0x45, 0xe5, 0xdd, 0x10, 0xd6,
+       0x4e, 0x9a, 0x23, 0xa1, 0x84, 0x5c, 0x37, 0xcd, 0xea, 0x4d, 0x5a, 0xe8,
+       0x4d, 0xc5, 0xc5, 0x5a, 0xe7, 0xa2, 0x0e, 0xc6, 0x71, 0x36, 0xd3, 0xb8,
+       0xf4, 0x1e, 0xb1, 0x53, 0x98, 0xbd, 0xde, 0x25, 0xe7, 0x38, 0xe6, 0x33,
+       0x0b, 0x95, 0x32, 0x23, 0x18, 0xcf, 0xfb, 0x94, 0xb9, 0xcc, 0x91, 0x4a,
+       0xc9, 0x45, 0x63, 0xf4, 0x85, 0xa6, 0x49, 0xe1, 0xd5, 0x1c, 0xa9, 0x22,
+       0x9d, 0x63, 0xa4, 0x33, 0xb7, 0x51, 0xeb, 0x1f, 0x53, 0x44, 0x67, 0x3e,
+       0xe2, 0xba, 0x8b, 0x32, 0x3f, 0xa3, 0xde, 0xfe, 0x94, 0xcf, 0x8b, 0xde,
+       0x82, 0x78, 0xad, 0x48, 0xe7, 0x89, 0xfc, 0x12, 0xe6, 0x32, 0x1f, 0x58,
+       0x7f, 0x8f, 0xe5, 0x63, 0xac, 0x7d, 0x83, 0xc8, 0x31, 0x9f, 0x4c, 0x66,
+       0x1a, 0xfb, 0x27, 0xc9, 0x87, 0x7d, 0x36, 0x6f, 0x10, 0x4f, 0x17, 0x9f,
+       0x19, 0xe5, 0xbb, 0xa3, 0xd7, 0xfe, 0x16, 0x1d, 0xd9, 0xfb, 0xff, 0xf6,
+       0x1e, 0x43, 0x39, 0x6d, 0x67, 0xf7, 0xe1, 0x47, 0x0d, 0xb7, 0xcc, 0xc3,
+       0xf1, 0xf2, 0xf4, 0x16, 0x8c, 0xe9, 0x7f, 0x8e, 0xbd, 0x94, 0x7b, 0x9c,
+       0xfa, 0x3c, 0x61, 0x58, 0xfb, 0xfc, 0x72, 0xfe, 0x8b, 0xb9, 0xfa, 0x60,
+       0xeb, 0x19, 0x62, 0xb1, 0xe3, 0x8c, 0x99, 0xfd, 0xf1, 0xc6, 0xde, 0x57,
+       0xe8, 0x77, 0xc9, 0xdf, 0x96, 0xbd, 0x74, 0x60, 0x32, 0xfb, 0x0d, 0xcc,
+       0xd6, 0x34, 0x2e, 0x3f, 0xcf, 0x9c, 0x70, 0x9a, 0x79, 0xca, 0xc5, 0x9c,
+       0x50, 0x9d, 0x25, 0x86, 0x64, 0x9e, 0x2a, 0x30, 0x4f, 0xb9, 0xb4, 0xc6,
+       0xa5, 0x79, 0xfc, 0x15, 0xf5, 0x22, 0xfc, 0x45, 0x62, 0xf3, 0x90, 0x67,
+       0xed, 0xf9, 0xab, 0x36, 0x3f, 0x84, 0x4b, 0x37, 0xdb, 0x33, 0x34, 0x27,
+       0x6b, 0xf6, 0xbe, 0x4c, 0x63, 0x60, 0x4c, 0x68, 0xf7, 0xa9, 0xa1, 0x34,
+       0x6d, 0x35, 0x61, 0x61, 0xef, 0x61, 0xf6, 0x0b, 0x72, 0xde, 0xab, 0x0a,
+       0x2e, 0xfa, 0xfe, 0x98, 0x2e, 0xe7, 0x20, 0x42, 0xfe, 0xed, 0xb4, 0xe1,
+       0x98, 0xd1, 0xd8, 0x12, 0x51, 0x76, 0xe3, 0x52, 0x31, 0xc7, 0xda, 0x58,
+       0x5a, 0xed, 0x3f, 0x86, 0xc6, 0xde, 0x07, 0xf0, 0x75, 0x24, 0x6b, 0x1a,
+       0x07, 0xa6, 0x11, 0xd1, 0xef, 0x83, 0x9c, 0x1b, 0xb5, 0x69, 0xd5, 0xe7,
+       0x9c, 0xc4, 0x23, 0x9f, 0x98, 0xab, 0xb5, 0x27, 0x30, 0x4d, 0xcc, 0xd8,
+       0xb0, 0x5e, 0x5b, 0xfa, 0x6e, 0xf1, 0x9e, 0xbd, 0xa7, 0x24, 0xfe, 0xe2,
+       0xa1, 0x0e, 0xca, 0xe1, 0x5a, 0x51, 0xc7, 0x35, 0xa8, 0x0b, 0xeb, 0x4c,
+       0xf1, 0x45, 0x1c, 0xa2, 0xbf, 0x4d, 0xe7, 0x15, 0xe8, 0xf5, 0x17, 0x31,
+       0x2c, 0xb5, 0x89, 0xef, 0xb4, 0x65, 0x7c, 0xc4, 0x29, 0x21, 0x94, 0x6b,
+       0x91, 0xf0, 0x28, 0xe5, 0x6b, 0x63, 0x2e, 0x1f, 0x67, 0x0e, 0x49, 0x07,
+       0x7c, 0xd6, 0x39, 0xd7, 0x72, 0x2d, 0x64, 0xfd, 0x6f, 0x82, 0xf4, 0x41,
+       0x0d, 0xb3, 0xb2, 0x9f, 0x7d, 0x04, 0x17, 0xa7, 0x0b, 0x38, 0x1e, 0x4f,
+       0xe2, 0x40, 0x4d, 0x00, 0x93, 0xc6, 0x4a, 0x6b, 0x6e, 0x20, 0xfd, 0x56,
+       0x77, 0xf6, 0xb0, 0x35, 0x8b, 0xdc, 0x16, 0x77, 0xd4, 0xcb, 0x79, 0x8f,
+       0x39, 0xf6, 0x5d, 0xd3, 0xfa, 0x08, 0x0e, 0xe9, 0xdf, 0x82, 0xbe, 0x42,
+       0x72, 0xe7, 0x18, 0xce, 0xcf, 0x4a, 0x0d, 0x9b, 0x68, 0xbd, 0x75, 0x52,
+       0xf4, 0xe3, 0x20, 0xe6, 0xf5, 0xa0, 0xc9, 0xc2, 0x70, 0xaf, 0xb7, 0xae,
+       0x99, 0xb5, 0xb1, 0x5c, 0x53, 0x4e, 0xce, 0x66, 0x57, 0xc1, 0x4f, 0x7d,
+       0x5d, 0x88, 0xbb, 0x99, 0x73, 0x44, 0x9f, 0x72, 0x16, 0xd0, 0x96, 0x33,
+       0x96, 0x53, 0x30, 0xd6, 0x7c, 0xe3, 0x5e, 0x8b, 0xfc, 0x9f, 0xc2, 0xb5,
+       0xf3, 0x89, 0xc5, 0xd9, 0xf8, 0x1f, 0x9b, 0x97, 0x6e, 0x12, 0xb9, 0x5b,
+       0x7d, 0xcc, 0xe9, 0xe1, 0xd9, 0x6b, 0xfa, 0x15, 0x9d, 0x9e, 0x93, 0x9a,
+       0x61, 0xe9, 0xdc, 0x9e, 0xb7, 0xa9, 0xc3, 0xef, 0x28, 0x8d, 0xac, 0x27,
+       0xf4, 0xab, 0x1a, 0xfa, 0x5b, 0x13, 0x06, 0x56, 0x27, 0x5c, 0x7d, 0x57,
+       0x8d, 0x2d, 0x68, 0xd9, 0xf0, 0xae, 0x89, 0x9b, 0xdb, 0xe0, 0xd4, 0xe4,
+       0xfa, 0xac, 0x99, 0x0c, 0xc8, 0xdf, 0x4f, 0xfa, 0xa4, 0x96, 0xbf, 0x68,
+       0x14, 0xcc, 0x35, 0x2b, 0x6d, 0x6c, 0xf8, 0xf7, 0x19, 0xd9, 0x07, 0x4b,
+       0x9b, 0xec, 0xb5, 0x97, 0xde, 0x76, 0x1e, 0xc6, 0xdf, 0xe6, 0x8e, 0xe0,
+       0xad, 0x69, 0x17, 0x71, 0xa6, 0xc8, 0xb2, 0x05, 0xd5, 0x1b, 0xa2, 0xc9,
+       0x77, 0x99, 0x17, 0x97, 0x66, 0x4b, 0x7e, 0xf1, 0x7a, 0xeb, 0xda, 0x59,
+       0x85, 0xb4, 0xaa, 0x50, 0x46, 0x39, 0x7f, 0xac, 0x3b, 0x11, 0x2e, 0x62,
+       0x5b, 0x27, 0xf9, 0xdc, 0x97, 0xb1, 0x31, 0x6f, 0x24, 0x37, 0xed, 0xb3,
+       0xe7, 0x5f, 0x3e, 0xe6, 0xd1, 0x71, 0x4c, 0x64, 0x1a, 0x63, 0xef, 0xc9,
+       0x79, 0x1e, 0xf6, 0x62, 0x97, 0x30, 0x8e, 0x13, 0x99, 0x52, 0x0e, 0x0d,
+       0xc9, 0x39, 0xd8, 0x58, 0xd8, 0x61, 0xe7, 0xc8, 0xb0, 0x43, 0x4d, 0xf3,
+       0xd7, 0x27, 0xd8, 0x60, 0x34, 0x1f, 0x09, 0x95, 0xc3, 0x89, 0xfd, 0xba,
+       0xed, 0x1f, 0xf5, 0xf3, 0x6e, 0x84, 0x57, 0x48, 0x5d, 0x96, 0x9a, 0xec,
+       0x62, 0x4d, 0x5e, 0x89, 0xe4, 0x4a, 0x17, 0x5e, 0xd7, 0x44, 0x1f, 0x53,
+       0x25, 0x7d, 0xe8, 0xe7, 0xf0, 0x90, 0x59, 0xe8, 0x15, 0x5f, 0x72, 0xe3,
+       0x48, 0xd3, 0x9c, 0x39, 0x1b, 0x14, 0xd9, 0x9d, 0x38, 0xcd, 0xfc, 0x8a,
+       0x9b, 0x23, 0xa1, 0xd3, 0xac, 0xd9, 0x63, 0x5a, 0xc9, 0xc7, 0xff, 0x63,
+       0x91, 0x4f, 0xad, 0x7f, 0x01, 0x47, 0xf8, 0x77, 0x7d, 0xe8, 0x80, 0x62,
+       0xaf, 0xb7, 0x66, 0xfe, 0x43, 0x5f, 0x69, 0x76, 0x2a, 0xcf, 0x86, 0x73,
+       0xa7, 0xf9, 0x5d, 0x68, 0xf9, 0xe8, 0x9f, 0xe5, 0x18, 0x08, 0xca, 0x79,
+       0x10, 0xd1, 0x8b, 0xec, 0x3f, 0x82, 0xfa, 0x30, 0xf1, 0x32, 0xf5, 0x71,
+       0xe4, 0xda, 0xd9, 0x2b, 0x3b, 0x7f, 0x55, 0xf0, 0xfa, 0xf6, 0xf8, 0x4b,
+       0x9b, 0xbd, 0xf8, 0x95, 0x79, 0x29, 0x18, 0x62, 0x4e, 0x10, 0x9b, 0xa6,
+       0x2c, 0x1c, 0xe9, 0x24, 0x3e, 0xd9, 0x67, 0x9f, 0x33, 0x69, 0x95, 0xff,
+       0xa1, 0x29, 0xca, 0x51, 0x18, 0x24, 0xce, 0x5e, 0xcc, 0x58, 0x67, 0xfb,
+       0x06, 0xde, 0x54, 0x22, 0xcc, 0x35, 0x5f, 0xc2, 0x40, 0xad, 0xd0, 0x0b,
+       0xf8, 0x77, 0xce, 0xc4, 0xa8, 0x83, 0x3a, 0xa1, 0x6b, 0x3e, 0xc3, 0x6e,
+       0xee, 0xc8, 0xa4, 0xd0, 0x07, 0xc6, 0x26, 0x23, 0x43, 0x3f, 0x06, 0x36,
+       0x57, 0x41, 0x4d, 0x2d, 0x14, 0xff, 0xdf, 0xe3, 0x67, 0x8a, 0xd0, 0x12,
+       0x3a, 0x2e, 0x18, 0xcc, 0x71, 0x53, 0x8b, 0x15, 0xd4, 0x9d, 0xda, 0xfb,
+       0x3d, 0xa5, 0x02, 0x4f, 0x3c, 0x15, 0x23, 0xef, 0x2b, 0xfc, 0xdb, 0x67,
+       0x3c, 0xf0, 0x9e, 0xa9, 0x62, 0xcd, 0xf5, 0xe0, 0x72, 0x33, 0xed, 0xfa,
+       0x54, 0x89, 0x77, 0x6b, 0x9f, 0x14, 0x8f, 0x67, 0xc3, 0x30, 0xe8, 0xb3,
+       0x8b, 0x86, 0xec, 0x17, 0x7b, 0xac, 0xfc, 0xb9, 0xb4, 0xb1, 0xce, 0xda,
+       0xaf, 0x7a, 0x3e, 0xaf, 0x85, 0xce, 0x2a, 0x55, 0xf8, 0xe0, 0x44, 0xe1,
+       0xe6, 0x72, 0x98, 0x2f, 0xae, 0x4e, 0x44, 0xfb, 0xf7, 0xd2, 0xe7, 0xd7,
+       0xae, 0x09, 0xb2, 0x97, 0x61, 0x4f, 0xb9, 0x49, 0xfa, 0xdf, 0x69, 0xf6,
+       0xbf, 0xa5, 0xbd, 0x7f, 0x6d, 0xe8, 0x11, 0x25, 0xdd, 0xe9, 0x87, 0xf9,
+       0x51, 0x79, 0xc2, 0xfc, 0xd8, 0x9d, 0x88, 0xf2, 0x7d, 0xd9, 0xdf, 0x33,
+       0xcd, 0x9f, 0x36, 0x9b, 0x66, 0xae, 0x39, 0xd2, 0x1f, 0x70, 0x06, 0x70,
+       0xa6, 0x41, 0xf6, 0x04, 0x1d, 0xf8, 0x20, 0xaa, 0x85, 0xf6, 0x42, 0xf6,
+       0xe8, 0x99, 0xe3, 0x57, 0xca, 0xf9, 0xc4, 0x3a, 0x7f, 0x97, 0xb1, 0x02,
+       0xcf, 0x2d, 0x6c, 0xc2, 0x80, 0x1b, 0xd6, 0xf9, 0x19, 0x53, 0xc7, 0x9b,
+       0xab, 0x21, 0x75, 0x3b, 0xda, 0xf2, 0x08, 0x82, 0x58, 0xc8, 0x1f, 0xc1,
+       0xc3, 0x27, 0x64, 0xaf, 0x71, 0xb2, 0xd5, 0x73, 0xc2, 0xfc, 0xfb, 0x50,
+       0xa2, 0xc0, 0xbc, 0x68, 0x9a, 0x15, 0x9b, 0x1a, 0x43, 0x2c, 0x47, 0xc4,
+       0x18, 0x69, 0xc1, 0xee, 0x43, 0x1f, 0xa0, 0x06, 0x67, 0xe7, 0x92, 0x37,
+       0xb3, 0x97, 0xec, 0x7a, 0x5a, 0x09, 0xe0, 0x07, 0x94, 0xf1, 0xd9, 0xbc,
+       0xe0, 0x14, 0xa3, 0xb5, 0xfb, 0xc4, 0x2a, 0xbc, 0xb8, 0x10, 0xc4, 0x59,
+       0x43, 0x23, 0x4e, 0x82, 0x52, 0x99, 0x30, 0xab, 0xab, 0xc9, 0x6b, 0xa5,
+       0xd3, 0x89, 0xce, 0xb8, 0xf4, 0x87, 0xda, 0x90, 0x4f, 0xc1, 0xaa, 0x72,
+       0x68, 0xcb, 0x0f, 0x01, 0xc3, 0x5e, 0xf6, 0xab, 0x4f, 0x2b, 0xd1, 0xfe,
+       0xf7, 0x9d, 0x41, 0xfc, 0x80, 0xf9, 0xe7, 0x7b, 0x79, 0x39, 0x5b, 0xc5,
+       0x1c, 0x33, 0x17, 0xa6, 0xad, 0x3c, 0x70, 0xd4, 0x57, 0xe1, 0x28, 0xe3,
+       0xe5, 0x65, 0xbd, 0x8c, 0x39, 0x4a, 0xce, 0x5a, 0x49, 0x7e, 0x7f, 0x54,
+       0xce, 0x94, 0x98, 0xcf, 0x6b, 0x76, 0xbf, 0xaf, 0xcf, 0xdf, 0x78, 0x5e,
+       0x39, 0xc0, 0xbc, 0xde, 0xd8, 0x1b, 0x52, 0x5e, 0x35, 0x93, 0xbf, 0xad,
+       0x50, 0xce, 0x07, 0xab, 0x50, 0x61, 0xc9, 0x8a, 0xd1, 0x6c, 0xa9, 0xa6,
+       0x54, 0x4b, 0x2f, 0xd7, 0x9b, 0x2e, 0xfa, 0x60, 0x25, 0x63, 0xfd, 0x18,
+       0x6b, 0x74, 0xf9, 0x09, 0xa9, 0x25, 0xec, 0x5f, 0x94, 0x2d, 0xc4, 0xc2,
+       0x82, 0x1b, 0x3c, 0x78, 0x20, 0xa0, 0xb6, 0xc8, 0x99, 0xed, 0x67, 0xf3,
+       0x1d, 0x2e, 0x39, 0x3b, 0xf5, 0x5c, 0x5e, 0x6a, 0xb9, 0xe4, 0x82, 0xd2,
+       0x7a, 0x21, 0xd4, 0x4e, 0x8a, 0x8d, 0x86, 0x5b, 0x3f, 0x9a, 0xf4, 0xc9,
+       0xf9, 0xfa, 0x11, 0x07, 0x7b, 0x6d, 0xcf, 0xa4, 0x69, 0xee, 0x69, 0xd6,
+       0x86, 0xb6, 0x38, 0x65, 0x6f, 0x39, 0x32, 0x70, 0x4e, 0x51, 0x5b, 0x26,
+       0x94, 0x1b, 0xe9, 0xfc, 0xb7, 0x2a, 0x89, 0x91, 0x34, 0xe5, 0x7c, 0xdc,
+       0x92, 0x69, 0x8a, 0x32, 0x95, 0xce, 0x16, 0x55, 0xe1, 0xf2, 0x34, 0x34,
+       0x46, 0x2d, 0xce, 0xeb, 0x4c, 0x4e, 0x81, 0x68, 0xb2, 0x1d, 0xe2, 0xff,
+       0xea, 0x80, 0x60, 0xa8, 0x4a, 0xe6, 0xe4, 0xb9, 0x69, 0xa9, 0x31, 0x8a,
+       0xe0, 0x93, 0x34, 0xd7, 0xc6, 0x95, 0x8d, 0xc0, 0xab, 0x93, 0xf6, 0xde,
+       0x7b, 0xf1, 0x2c, 0xb8, 0x75, 0xe6, 0xe1, 0x11, 0xeb, 0x2c, 0x83, 0xd0,
+       0x3f, 0x8c, 0x33, 0x19, 0xc1, 0x94, 0xc3, 0xc4, 0x94, 0x91, 0x14, 0xf1,
+       0x66, 0x4b, 0xde, 0x3e, 0x97, 0xa5, 0x7f, 0x44, 0x9f, 0x7f, 0x9a, 0x58,
+       0xf5, 0x28, 0xec, 0xbd, 0xf7, 0x86, 0xe2, 0x59, 0x85, 0x48, 0xae, 0x4b,
+       0xd9, 0x91, 0x97, 0x18, 0x9b, 0x66, 0x8c, 0xb5, 0x2b, 0xdb, 0x17, 0x3a,
+       0x94, 0xee, 0x85, 0x1e, 0x65, 0x77, 0x5e, 0x7a, 0xd6, 0xc9, 0xd6, 0x07,
+       0x4e, 0xec, 0x52, 0x76, 0xcc, 0xf5, 0x29, 0xc4, 0xb4, 0x01, 0x4f, 0xa2,
+       0x5f, 0xe9, 0x59, 0xb0, 0xe7, 0xe7, 0x5d, 0xec, 0xbb, 0x76, 0x18, 0xa5,
+       0x7e, 0x5e, 0xfe, 0xdf, 0x2b, 0x28, 0xff, 0x5b, 0x31, 0xb0, 0x4d, 0x31,
+       0xcd, 0xdb, 0xe2, 0x7f, 0x27, 0xf6, 0x30, 0x9f, 0x8d, 0xb3, 0x36, 0x1a,
+       0x55, 0x18, 0x64, 0xdf, 0x31, 0xaa, 0xdf, 0x5a, 0xdc, 0x2f, 0x13, 0x99,
+       0xe4, 0x3c, 0x85, 0xf8, 0x2b, 0xd2, 0xe5, 0xe4, 0xe1, 0x1f, 0xc8, 0xff,
+       0x81, 0xa2, 0x5c, 0x3d, 0x72, 0xa6, 0xc0, 0x7d, 0xfd, 0xbc, 0xd9, 0xf1,
+       0xc9, 0xeb, 0x72, 0x31, 0xd7, 0x63, 0x9c, 0xf8, 0xf4, 0x80, 0xa2, 0xa6,
+       0x9e, 0xb1, 0xe5, 0x5a, 0xba, 0xcc, 0x18, 0x1e, 0xb5, 0x62, 0xd8, 0x96,
+       0x6b, 0x5d, 0x51, 0xae, 0xb5, 0xb9, 0x2e, 0xeb, 0x1c, 0x17, 0xf1, 0x7a,
+       0xeb, 0xe2, 0xa4, 0x9c, 0x37, 0x93, 0xd9, 0xa5, 0xc8, 0x26, 0x72, 0x9c,
+       0x30, 0x2b, 0xb4, 0x1e, 0x65, 0xa7, 0x75, 0xfe, 0x4c, 0xce, 0x7e, 0xc9,
+       0x5e, 0x7f, 0x49, 0x2e, 0xa9, 0xe3, 0x2b, 0xfc, 0x1d, 0x33, 0x72, 0x1e,
+       0xdb, 0x34, 0x5f, 0xd3, 0x83, 0x7e, 0x91, 0xe5, 0xac, 0x2e, 0xb2, 0xc8,
+       0xb9, 0x92, 0x92, 0x3c, 0x5f, 0x2b, 0xca, 0x23, 0xb6, 0xba, 0x6e, 0xa7,
+       0xd2, 0xff, 0x09, 0xbe, 0x9d, 0xb1, 0xcf, 0x9c, 0x94, 0xe4, 0xf1, 0x27,
+       0x84, 0xff, 0x8b, 0xad, 0xe3, 0xd3, 0xc3, 0x78, 0x95, 0xf7, 0x7f, 0x9e,
+       0x29, 0xc9, 0xe5, 0xc4, 0xfc, 0x5c, 0xe9, 0x2c, 0x1d, 0x5b, 0x4a, 0x23,
+       0xa2, 0x8f, 0xd1, 0x8f, 0x6c, 0xf9, 0xe4, 0x2c, 0x5d, 0x63, 0xe1, 0xb2,
+       0x35, 0xf7, 0x8a, 0x26, 0xd9, 0x2f, 0xe3, 0x6c, 0xfe, 0xd7, 0xed, 0xd7,
+       0x94, 0xab, 0x60, 0x8f, 0x2c, 0xb4, 0x5f, 0x27, 0x6d, 0x39, 0x73, 0xa2,
+       0xe0, 0x99, 0x39, 0x60, 0xce, 0xe0, 0xb2, 0x89, 0x11, 0x3c, 0xa9, 0x9b,
+       0xe6, 0xd3, 0xcd, 0x9a, 0x9c, 0x15, 0xba, 0x50, 0x6b, 0xcd, 0x85, 0xa0,
+       0x57, 0x69, 0xb2, 0x77, 0x27, 0xe7, 0x4d, 0xfa, 0xa8, 0x03, 0x91, 0x5d,
+       0x7c, 0xa0, 0x64, 0x7b, 0x39, 0x07, 0x97, 0xa6, 0x7e, 0x44, 0x37, 0xa5,
+       0xf3, 0x70, 0x32, 0x73, 0xb9, 0x51, 0x27, 0x5d, 0x96, 0x4e, 0x9e, 0xd5,
+       0xc5, 0x5f, 0x99, 0x7d, 0xe8, 0xab, 0xf3, 0xc4, 0x0f, 0x63, 0xba, 0xdb,
+       0xc2, 0x6a, 0x47, 0x89, 0x4f, 0x26, 0x18, 0x3b, 0x8f, 0x1b, 0x4b, 0x58,
+       0xca, 0xbd, 0x8c, 0x57, 0xaf, 0xfd, 0xcf, 0x9c, 0xf8, 0x8b, 0xde, 0xd2,
+       0x6d, 0x9d, 0x79, 0xfa, 0xa4, 0xe5, 0xd6, 0xa8, 0xe4, 0xa1, 0x1f, 0x36,
+       0xc9, 0x19, 0xa8, 0xf2, 0x44, 0xe0, 0x6b, 0xb2, 0xbf, 0x55, 0x96, 0x98,
+       0xfd, 0xea, 0x05, 0x4d, 0x74, 0xa3, 0x35, 0x9f, 0xd1, 0x44, 0xae, 0x1e,
+       0x7d, 0xdc, 0xfa, 0x1f, 0xce, 0x96, 0x4d, 0xfb, 0x34, 0x89, 0x1d, 0xdf,
+       0xc6, 0x36, 0x2b, 0x27, 0x9c, 0x4e, 0xdc, 0x66, 0xe9, 0xe0, 0x64, 0xe2,
+       0x56, 0xeb, 0x73, 0x3a, 0x11, 0xb3, 0x3e, 0xff, 0x24, 0x61, 0xeb, 0x26,
+       0x97, 0xa8, 0xb7, 0x3e, 0xe7, 0x13, 0xf6, 0xd9, 0xe9, 0xd9, 0x84, 0x66,
+       0x7d, 0x3e, 0x9f, 0x88, 0x58, 0x9f, 0x67, 0x13, 0xb7, 0x5c, 0xe7, 0x8b,
+       0x3f, 0xff, 0x0f, 0x4c, 0xd3, 0x85, 0x76, 0xdc, 0x3a, 0x00, 0x00, 0x00 };
 
-static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
-static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
 
 static struct fw_info bnx2_txp_fw_06 = {
-       .ver_major                      = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
        .ver_minor                      = 0x0,
-       .ver_fix                        = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x080034b0,
+       .start_addr                     = 0x08000098,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x5748,
+       .text_len                       = 0x3ad8,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TXP_b06FwText,
        .gz_text_len                    = sizeof(bnx2_TXP_b06FwText),
 
-       .data_addr                      = 0x08005760,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_TXP_b06FwData,
 
-       .sbss_addr                      = 0x08005760,
-       .sbss_len                       = 0x38,
+       .sbss_addr                      = 0x08003b00,
+       .sbss_len                       = 0x68,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080057a0,
-       .bss_len                        = 0x1c4,
+       .bss_addr                       = 0x08003b68,
+       .bss_len                        = 0x14c,
        .bss_index                      = 0x0,
 
        .rodata_addr                    = 0x00000000,
index 4b129b7cbfad94eb58d1887062027c82c2ce77cf..13b222eb2f63efc064a896aa321e020354d5b56b 100644 (file)
  */
 
 static u8 bnx2_COM_b09FwText[] = {
-       0xdc, 0x5b, 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae,
-       0xc8, 0x15, 0x35, 0x22, 0x57, 0xd4, 0x9a, 0xa2, 0xed, 0x5d, 0x72, 0x28,
-       0xb2, 0x96, 0xea, 0xae, 0x29, 0xa6, 0x62, 0xd3, 0x4d, 0xb4, 0xd9, 0xa5,
-       0x5c, 0xb5, 0x75, 0x5a, 0x4a, 0x26, 0xfc, 0x48, 0x55, 0x83, 0xde, 0xa5,
-       0x9c, 0xa0, 0xa8, 0x53, 0xc9, 0x76, 0x85, 0x20, 0x05, 0xaa, 0x05, 0x1f,
-       0x89, 0x52, 0xb0, 0x1c, 0xc5, 0x92, 0x29, 0xb5, 0x71, 0x6b, 0x96, 0xb4,
-       0x6c, 0x15, 0xd8, 0x6a, 0x65, 0xc7, 0x6d, 0x68, 0x54, 0x2e, 0x65, 0xca,
-       0x69, 0x95, 0x26, 0x48, 0x8d, 0xa0, 0x42, 0x95, 0x3f, 0x8e, 0xe1, 0xf4,
-       0x87, 0x5b, 0xf4, 0x87, 0xd1, 0x07, 0x22, 0xd7, 0x8f, 0xed, 0xf7, 0xdd,
-       0xb9, 0x43, 0x0e, 0x97, 0x14, 0x45, 0xf9, 0xf5, 0xa3, 0x04, 0x56, 0x33,
-       0xf7, 0x7d, 0xee, 0xb9, 0xe7, 0x7c, 0xe7, 0x31, 0x57, 0x3f, 0x2f, 0x52,
-       0x27, 0xfa, 0x6f, 0x3d, 0x7e, 0x89, 0x87, 0x7f, 0xaf, 0x70, 0xfb, 0xce,
-       0xdb, 0x77, 0xe0, 0xf5, 0x0e, 0xd3, 0xa8, 0x0d, 0xb1, 0x9e, 0xff, 0xc4,
-       0xf0, 0xeb, 0xd6, 0xef, 0x2b, 0xfd, 0xd9, 0xf8, 0xbd, 0x89, 0xc6, 0xc1,
-       0x7f, 0x17, 0x31, 0xae, 0xd1, 0x27, 0xf8, 0x57, 0xa9, 0xac, 0xde, 0x6e,
-       0x92, 0x96, 0x55, 0xda, 0x43, 0xde, 0x92, 0x8a, 0x66, 0xfe, 0x24, 0x62,
-       0xa6, 0x33, 0x47, 0xb2, 0x8e, 0x11, 0x09, 0xa5, 0xbb, 0x8a, 0x05, 0x47,
-       0x24, 0x53, 0xda, 0x96, 0xc8, 0xc9, 0x7b, 0x95, 0x62, 0xcc, 0x92, 0xac,
-       0x23, 0x91, 0x9b, 0xd3, 0xef, 0x3e, 0xf5, 0xd2, 0xce, 0xe4, 0x5b, 0x53,
-       0x21, 0x89, 0xd8, 0xe9, 0x17, 0xc4, 0xde, 0x2a, 0x91, 0x56, 0x8c, 0x79,
-       0xb2, 0x33, 0x63, 0x48, 0x83, 0x3f, 0xd7, 0x9b, 0x95, 0x97, 0x3a, 0xa5,
-       0xd8, 0x92, 0x8e, 0x88, 0x99, 0xee, 0xb8, 0x92, 0x0d, 0xd9, 0x83, 0xa1,
-       0xb4, 0x2d, 0x73, 0x65, 0xe9, 0x3f, 0x30, 0x2e, 0x91, 0x48, 0xfa, 0x4b,
-       0x91, 0xda, 0x0e, 0x89, 0x58, 0xe9, 0xa9, 0x23, 0x5f, 0x73, 0x8e, 0x54,
-       0x4c, 0xc7, 0xe9, 0x9a, 0x96, 0x68, 0xef, 0xe9, 0x1e, 0xb4, 0x97, 0x92,
-       0x5d, 0x22, 0x3b, 0xc5, 0x74, 0x8a, 0xd1, 0x90, 0x13, 0x91, 0x6c, 0xd9,
-       0x91, 0x5c, 0x59, 0xe4, 0x1f, 0x4a, 0x86, 0x9c, 0x76, 0x9a, 0x65, 0x7a,
-       0xfb, 0xbb, 0x95, 0x0c, 0x68, 0xf9, 0x7b, 0x67, 0xea, 0xc8, 0xa8, 0x43,
-       0x7a, 0x1f, 0x8b, 0x90, 0xae, 0x50, 0x7a, 0xa8, 0xb6, 0xe0, 0x58, 0x32,
-       0x5c, 0x62, 0xdd, 0x80, 0xc9, 0xba, 0x70, 0x3a, 0x52, 0x77, 0xda, 0x89,
-       0xea, 0xba, 0x52, 0x26, 0x8b, 0xf9, 0x46, 0x4a, 0xec, 0x1b, 0xe9, 0x2e,
-       0x38, 0x31, 0x5d, 0x3f, 0xba, 0x33, 0xeb, 0xc4, 0x51, 0xdf, 0xaa, 0xdb,
-       0x7a, 0xbe, 0x5c, 0x70, 0x1c, 0xdd, 0x76, 0x35, 0x94, 0x75, 0xba, 0x74,
-       0xfd, 0xab, 0xbb, 0x0a, 0xce, 0x76, 0x5d, 0xff, 0xd6, 0xae, 0xac, 0x93,
-       0xd2, 0xf5, 0xe3, 0xf7, 0x17, 0x9c, 0x1e, 0x5d, 0xdf, 0x8a, 0xfa, 0x5e,
-       0x5d, 0xff, 0x83, 0xde, 0x82, 0x93, 0x46, 0xfd, 0x97, 0x22, 0x66, 0x87,
-       0x2d, 0x63, 0xa5, 0x04, 0x7e, 0x19, 0xb4, 0xf5, 0xa1, 0x6e, 0x0f, 0x7e,
-       0x77, 0xe1, 0x37, 0xbf, 0x41, 0x1a, 0xfa, 0xf1, 0x6c, 0x6b, 0xf5, 0x78,
-       0x07, 0x1e, 0xb9, 0x11, 0x79, 0x3d, 0x14, 0x97, 0x97, 0x3a, 0x5f, 0x07,
-       0x0f, 0x6d, 0x39, 0x57, 0x16, 0xa3, 0xbf, 0x33, 0x0e, 0xde, 0xc5, 0xe4,
-       0xb9, 0x72, 0xbd, 0x84, 0x1e, 0x0f, 0x81, 0x37, 0x5f, 0x90, 0x7c, 0x2c,
-       0x22, 0x1b, 0x27, 0x0d, 0x69, 0xeb, 0x8e, 0x48, 0xc6, 0xe6, 0xda, 0x38,
-       0xed, 0x89, 0x98, 0x84, 0x26, 0x33, 0x4d, 0xa6, 0x74, 0xd8, 0x39, 0x29,
-       0x82, 0x77, 0x57, 0x28, 0x97, 0x68, 0x4b, 0x48, 0x6e, 0xfc, 0x36, 0x19,
-       0xb4, 0x49, 0xd7, 0xdc, 0xcd, 0xde, 0x5a, 0x11, 0x23, 0x7b, 0x72, 0x40,
-       0xc6, 0xdc, 0xa8, 0x91, 0x3b, 0xf9, 0x59, 0xc9, 0xa6, 0x24, 0x86, 0x71,
-       0xf1, 0x3c, 0x5a, 0x66, 0x4a, 0x03, 0x32, 0xea, 0x8a, 0x91, 0x75, 0xc9,
-       0xcf, 0x66, 0xb4, 0x37, 0xa8, 0xbe, 0xa8, 0x6b, 0x0d, 0xa9, 0xb9, 0x23,
-       0xa8, 0xb7, 0x51, 0xdf, 0x68, 0xf4, 0xa9, 0x39, 0x54, 0x7d, 0x62, 0x44,
-       0xa2, 0xf2, 0x74, 0x29, 0xa6, 0xfb, 0x56, 0x2a, 0xd9, 0x94, 0x8d, 0x7e,
-       0x03, 0x32, 0xe2, 0xc6, 0x64, 0x10, 0xcf, 0x61, 0x97, 0x72, 0x15, 0x87,
-       0x4c, 0x35, 0x14, 0xf3, 0x27, 0xd4, 0x7c, 0x89, 0x50, 0x9a, 0xf3, 0xb5,
-       0xa2, 0xdf, 0xdb, 0xa0, 0xcb, 0x10, 0x4b, 0x9d, 0x65, 0x46, 0xf2, 0xe3,
-       0x06, 0xe4, 0x0d, 0x4f, 0xc5, 0xd7, 0x3e, 0xd0, 0x6f, 0x89, 0xd3, 0x6d,
-       0x48, 0x01, 0x67, 0x55, 0xb4, 0x51, 0x2e, 0xcd, 0x9a, 0x59, 0xb7, 0x56,
-       0x72, 0x56, 0x42, 0x42, 0x13, 0x94, 0xa5, 0x41, 0x19, 0xc1, 0x18, 0xd3,
-       0x61, 0x9f, 0xb7, 0xb1, 0xef, 0x41, 0x75, 0x0e, 0x35, 0xe9, 0xa2, 0x99,
-       0x2b, 0x37, 0x8b, 0x39, 0xb9, 0x5f, 0x5e, 0x19, 0x17, 0x3b, 0x94, 0x7e,
-       0xb7, 0x92, 0x75, 0x46, 0xcd, 0xec, 0xb3, 0x96, 0x84, 0x27, 0x0c, 0x19,
-       0x75, 0x92, 0xd0, 0x80, 0xa3, 0xe6, 0xee, 0xf2, 0x2c, 0xfa, 0x71, 0x1c,
-       0xfa, 0x95, 0x4c, 0xf0, 0x95, 0xef, 0xdb, 0x6c, 0x53, 0xc9, 0x33, 0xfb,
-       0xe0, 0x0c, 0xb0, 0x8f, 0xe7, 0x5c, 0x9c, 0x89, 0x3a, 0xa3, 0x04, 0xce,
-       0x48, 0x8c, 0xbe, 0x4e, 0xc8, 0xd4, 0x09, 0x4b, 0xf2, 0x29, 0xec, 0x0b,
-       0xbd, 0xf3, 0xa9, 0x45, 0xba, 0x46, 0xc6, 0xab, 0xe9, 0xe2, 0x38, 0xd2,
-       0xe5, 0xd1, 0x34, 0x7c, 0x82, 0xf4, 0x2d, 0xd2, 0x33, 0x36, 0xee, 0xd3,
-       0xc8, 0xf5, 0x48, 0x9b, 0x4f, 0x17, 0xc7, 0x91, 0xae, 0x26, 0x9e, 0x35,
-       0xff, 0x8c, 0x3e, 0xd0, 0x31, 0xe2, 0x5a, 0x38, 0xa3, 0xa8, 0xe4, 0xed,
-       0xa2, 0x31, 0xd2, 0xbb, 0x2d, 0x0e, 0x6d, 0x36, 0x86, 0x7b, 0x49, 0xb3,
-       0x83, 0x73, 0xac, 0x51, 0xe7, 0x0d, 0xf9, 0x26, 0xef, 0xd0, 0x9f, 0xeb,
-       0xe3, 0xbd, 0x64, 0xcb, 0xa8, 0x9a, 0x8f, 0x34, 0x7d, 0x14, 0xf3, 0x90,
-       0xd6, 0x4b, 0x90, 0xd5, 0x1e, 0xc8, 0x68, 0x4a, 0xfe, 0xae, 0xbc, 0x5d,
-       0xbe, 0x53, 0xee, 0x92, 0xbf, 0x81, 0xde, 0xfe, 0x75, 0x39, 0x21, 0x2f,
-       0x94, 0x5b, 0xe5, 0xdb, 0xe5, 0xb8, 0x3c, 0xaf, 0xe4, 0xb7, 0x4f, 0xa4,
-       0x81, 0x32, 0x9d, 0x90, 0x46, 0xe8, 0xcf, 0x46, 0xe8, 0xe6, 0x13, 0xe0,
-       0xdf, 0x89, 0x4e, 0xc9, 0x34, 0xa5, 0x25, 0x72, 0x0b, 0x7e, 0x9b, 0xf1,
-       0x6b, 0x4e, 0x43, 0xee, 0x5c, 0xf2, 0x8e, 0x3c, 0xb4, 0x24, 0xa7, 0xf6,
-       0x6c, 0xc9, 0x48, 0x79, 0xfe, 0x16, 0x4f, 0x76, 0x45, 0xfa, 0xc1, 0x63,
-       0xb3, 0xfb, 0x7f, 0x2a, 0x19, 0x1b, 0xfb, 0xe8, 0xde, 0xa6, 0x78, 0x6f,
-       0x76, 0x53, 0x66, 0x13, 0x90, 0x7b, 0xcb, 0xc8, 0xb9, 0x67, 0x80, 0x1b,
-       0xf5, 0x46, 0xf6, 0x78, 0x51, 0x0a, 0xc7, 0x2b, 0x52, 0x48, 0x85, 0xe5,
-       0x11, 0xbb, 0x22, 0x7d, 0xa9, 0x1a, 0x39, 0x64, 0x83, 0xf7, 0xdb, 0x7f,
-       0xdf, 0xf0, 0x31, 0xfb, 0x89, 0xf2, 0x61, 0xbc, 0xb3, 0x4e, 0xe4, 0x84,
-       0x7a, 0xf7, 0xea, 0x8b, 0xe5, 0xb0, 0x64, 0x62, 0xc5, 0xb8, 0x25, 0x2d,
-       0xa6, 0xb7, 0xee, 0xb0, 0xdf, 0x06, 0x7e, 0x4c, 0x01, 0x27, 0x93, 0x4a,
-       0x5f, 0xf2, 0xe3, 0xeb, 0xae, 0x66, 0x54, 0x35, 0xfa, 0xdb, 0x3d, 0x32,
-       0xaf, 0xf8, 0x99, 0x18, 0x34, 0xd2, 0x31, 0x69, 0x2b, 0xb1, 0xdc, 0x6b,
-       0xdc, 0x5d, 0xa6, 0x3c, 0xe3, 0xbd, 0x4c, 0x3a, 0x6f, 0x42, 0x3f, 0x0b,
-       0xcf, 0x8c, 0xa6, 0x37, 0x48, 0x23, 0xe7, 0x21, 0x8d, 0x7c, 0xfe, 0x79,
-       0x80, 0xc6, 0xa7, 0x16, 0xde, 0x4f, 0x04, 0xde, 0x8b, 0xe5, 0x4b, 0x75,
-       0x1e, 0x6d, 0xbd, 0xf2, 0xc6, 0xc4, 0x57, 0xf4, 0x3a, 0x78, 0x3f, 0xcb,
-       0xf9, 0xff, 0xaa, 0xe2, 0xc9, 0x4b, 0xf1, 0x3a, 0xeb, 0xcc, 0x06, 0xd6,
-       0x79, 0x31, 0xb0, 0xce, 0x8b, 0x81, 0x75, 0x8a, 0xe0, 0xa9, 0x6c, 0x30,
-       0x21, 0xc3, 0x79, 0x9a, 0x31, 0x39, 0x8a, 0x39, 0x5f, 0x97, 0x50, 0x9a,
-       0x7a, 0xee, 0xe3, 0xcd, 0x65, 0xf4, 0x4f, 0xcb, 0xfc, 0x44, 0x51, 0xf2,
-       0xc7, 0xc3, 0xb2, 0x4f, 0xf5, 0xdb, 0xa5, 0xe9, 0x0b, 0xb6, 0x45, 0x64,
-       0x6f, 0x8c, 0xef, 0x7e, 0x9b, 0x05, 0x3e, 0xb3, 0xfc, 0xc6, 0x4d, 0x5e,
-       0x99, 0xef, 0xb3, 0x7a, 0x2f, 0x03, 0xde, 0xb8, 0xb3, 0x6f, 0x2a, 0x3c,
-       0x9c, 0x2b, 0x13, 0xb7, 0x24, 0x15, 0x72, 0xe4, 0x60, 0x5f, 0xaa, 0x59,
-       0x46, 0x6c, 0x23, 0x35, 0xdc, 0x55, 0x4b, 0xbd, 0xc8, 0x98, 0x4e, 0x3d,
-       0xb0, 0x41, 0x12, 0x26, 0x31, 0x5f, 0xed, 0xcb, 0x30, 0x3d, 0xfa, 0x6d,
-       0x96, 0xfb, 0x4d, 0xa7, 0xb1, 0xaa, 0x9e, 0xba, 0x1d, 0xc2, 0x3b, 0x65,
-       0x78, 0xb7, 0x3e, 0x63, 0x0b, 0x65, 0xe2, 0xf0, 0xad, 0xba, 0xec, 0xb7,
-       0xe3, 0xc0, 0x96, 0x94, 0x7f, 0xb6, 0x65, 0x69, 0xd9, 0xc7, 0x89, 0x20,
-       0x86, 0x73, 0xaf, 0xc0, 0x27, 0x87, 0x72, 0x17, 0x06, 0xad, 0x29, 0xe8,
-       0x5c, 0xad, 0xa6, 0x61, 0xb3, 0xa6, 0x01, 0xb4, 0x76, 0x42, 0xb2, 0x94,
-       0x2e, 0x29, 0xd1, 0xaa, 0x2a, 0x93, 0xf7, 0xfe, 0xfb, 0x7a, 0xd5, 0xee,
-       0xe9, 0x9c, 0xff, 0xf4, 0xf1, 0xfd, 0xcd, 0x80, 0xbd, 0x68, 0x85, 0xce,
-       0xc6, 0xc0, 0x2b, 0x1f, 0xeb, 0x89, 0xc1, 0x71, 0xd8, 0x07, 0xc8, 0xaa,
-       0xc2, 0xf6, 0x28, 0xf0, 0xd0, 0xd2, 0xd8, 0x1c, 0xd1, 0xd8, 0x1c, 0x05,
-       0x2e, 0xb3, 0x6c, 0xeb, 0x72, 0x4c, 0x97, 0xe3, 0x28, 0xc3, 0x8e, 0x4f,
-       0x12, 0xbb, 0x1b, 0x8a, 0x43, 0x27, 0x14, 0xde, 0xd3, 0x56, 0x00, 0x85,
-       0x89, 0xd7, 0xc4, 0xed, 0x56, 0x99, 0x2e, 0x61, 0xbd, 0x05, 0x6c, 0xe4,
-       0xde, 0x83, 0xf4, 0x90, 0x96, 0x75, 0x62, 0xc2, 0x76, 0x65, 0x62, 0xa4,
-       0xf7, 0x61, 0xec, 0x9d, 0xf8, 0x43, 0xba, 0x6f, 0x06, 0xad, 0xdc, 0xc7,
-       0x27, 0x49, 0x2b, 0xd7, 0xab, 0xa6, 0xf7, 0xc3, 0xe2, 0x20, 0x69, 0x3f,
-       0x83, 0x3d, 0x67, 0x80, 0x79, 0x62, 0x0c, 0x74, 0x0e, 0x60, 0xcf, 0xfd,
-       0xc0, 0xc3, 0xbb, 0x80, 0x87, 0x7b, 0x80, 0x87, 0x7d, 0xc0, 0xc3, 0x34,
-       0xb0, 0xb0, 0x17, 0x58, 0xd8, 0x03, 0x2c, 0x4c, 0x81, 0x37, 0x31, 0x99,
-       0x02, 0x36, 0x4e, 0x01, 0x23, 0xa7, 0x30, 0xc7, 0xf0, 0xa4, 0x18, 0x0f,
-       0x60, 0x0f, 0xdf, 0x9c, 0x48, 0x9e, 0x82, 0x2c, 0xc5, 0x8b, 0x26, 0xe4,
-       0x3f, 0xd5, 0x0b, 0xd9, 0xee, 0x92, 0x99, 0xb2, 0x25, 0x05, 0xd8, 0xd4,
-       0xb6, 0xad, 0xed, 0xd0, 0x35, 0xc8, 0x7b, 0x5c, 0xf4, 0xdf, 0x7a, 0xfd,
-       0xfc, 0xb1, 0x88, 0xf3, 0x4f, 0x94, 0xc5, 0x84, 0xc8, 0x79, 0xc9, 0xbb,
-       0xed, 0x76, 0x9b, 0xd9, 0x85, 0x7e, 0x2c, 0xa7, 0xcc, 0x03, 0xc7, 0xef,
-       0x30, 0x87, 0x8e, 0x2b, 0x7f, 0x05, 0x78, 0x55, 0x91, 0xd1, 0x14, 0x75,
-       0xab, 0x22, 0xa7, 0x53, 0xc9, 0xde, 0xa2, 0xd4, 0xcb, 0x58, 0x6c, 0x5c,
-       0xd9, 0x5a, 0x2b, 0x7d, 0x4c, 0xd9, 0xab, 0x82, 0x83, 0x67, 0xa9, 0xdb,
-       0xcc, 0x1f, 0xe7, 0xfe, 0xdb, 0xf1, 0x0b, 0x83, 0x16, 0xce, 0x6f, 0x49,
-       0x5f, 0x8f, 0x6d, 0x3e, 0xd4, 0x59, 0x84, 0x42, 0x24, 0xed, 0x79, 0xac,
-       0x9c, 0x1b, 0x6f, 0x8f, 0xb7, 0x9b, 0x96, 0x0c, 0x5a, 0x86, 0x0c, 0x43,
-       0xbe, 0xfb, 0x52, 0x6f, 0x57, 0xc6, 0x62, 0x6c, 0xaf, 0x95, 0xaf, 0x2b,
-       0x9f, 0x03, 0x6b, 0xcf, 0x9c, 0xc0, 0xba, 0x61, 0x9c, 0x01, 0xd7, 0xe5,
-       0x3c, 0x28, 0x97, 0x2c, 0x94, 0x93, 0xa7, 0x8a, 0x52, 0x86, 0x9e, 0x6c,
-       0x90, 0xec, 0xf6, 0x1a, 0xc9, 0xf4, 0x27, 0x64, 0x78, 0xa2, 0x0c, 0x9c,
-       0x8a, 0x28, 0x5d, 0xc9, 0x0f, 0x24, 0xe4, 0xf1, 0x09, 0xd6, 0x9d, 0xc3,
-       0xfe, 0x93, 0xc7, 0x32, 0xc2, 0xfd, 0x1b, 0x92, 0xd9, 0x7f, 0x4e, 0x1e,
-       0x71, 0xcf, 0xc9, 0x10, 0xce, 0xf0, 0xe9, 0xf2, 0xac, 0x1c, 0x70, 0x1d,
-       0x39, 0x0d, 0xbc, 0xcf, 0x1d, 0x07, 0xee, 0x39, 0xeb, 0x81, 0x51, 0xc9,
-       0x73, 0xb4, 0xa1, 0x26, 0xfc, 0xbc, 0x69, 0xf0, 0xf7, 0x89, 0x09, 0xf2,
-       0xd7, 0x94, 0x47, 0x7f, 0xd1, 0x80, 0x3e, 0x26, 0xc0, 0xcf, 0x56, 0x39,
-       0xec, 0x26, 0x67, 0x33, 0x26, 0x70, 0x31, 0x65, 0x87, 0xa4, 0x2e, 0x8e,
-       0x7e, 0x5e, 0x9f, 0x5c, 0x2a, 0x84, 0xb3, 0x2e, 0xa2, 0xef, 0xdb, 0xa0,
-       0x93, 0x63, 0x63, 0xf8, 0x65, 0xd0, 0x0f, 0xf2, 0x6b, 0x27, 0x67, 0xa7,
-       0x4c, 0xf6, 0x4f, 0xe0, 0xcc, 0x80, 0x2b, 0x93, 0x00, 0x1e, 0x9b, 0xef,
-       0x69, 0x33, 0x4f, 0x1a, 0x5c, 0xca, 0x59, 0x02, 0x34, 0x11, 0xd3, 0xda,
-       0xcf, 0x7d, 0x47, 0xb8, 0xce, 0x46, 0xf4, 0x7f, 0x07, 0x7e, 0xae, 0x2d,
-       0x33, 0x38, 0x97, 0x9f, 0x82, 0x57, 0x99, 0xb8, 0x57, 0x1e, 0x9e, 0x4c,
-       0x9e, 0x9b, 0x37, 0xf9, 0xee, 0x14, 0xf3, 0xe6, 0x6d, 0x22, 0x8d, 0xe4,
-       0x57, 0x0a, 0xbc, 0x72, 0x6c, 0xd3, 0xdc, 0xaa, 0x7d, 0x3b, 0xea, 0x89,
-       0x03, 0x9a, 0xe0, 0x67, 0x74, 0x07, 0xf5, 0x84, 0xf6, 0xce, 0xd7, 0x93,
-       0x64, 0x7c, 0xca, 0x84, 0xff, 0xd1, 0x6d, 0xc9, 0x31, 0x55, 0x06, 0x8f,
-       0x06, 0x92, 0xf1, 0x8c, 0x49, 0x9f, 0xb7, 0x4b, 0x9e, 0x76, 0xd9, 0x1f,
-       0x7c, 0x1c, 0x8f, 0xea, 0xfe, 0xe7, 0x20, 0x23, 0xf4, 0xcf, 0xba, 0x40,
-       0xb3, 0xa7, 0x3b, 0xd3, 0xe3, 0x31, 0xd5, 0x36, 0xa6, 0xf6, 0x60, 0x60,
-       0x5d, 0xc8, 0x26, 0x7c, 0xb5, 0x9c, 0xd2, 0x23, 0x3b, 0x03, 0x5f, 0x1e,
-       0x7a, 0xe0, 0xe9, 0xd0, 0x4c, 0x89, 0xb4, 0xdc, 0x43, 0x7e, 0x14, 0x41,
-       0xcc, 0x31, 0x33, 0x8d, 0x73, 0xed, 0x91, 0x22, 0xfd, 0xb9, 0xf9, 0xd0,
-       0xd3, 0x32, 0x38, 0x43, 0x7b, 0x83, 0x9f, 0xeb, 0xd8, 0x8c, 0x1f, 0x32,
-       0xca, 0x16, 0x6c, 0xc1, 0x39, 0xc3, 0x4e, 0xa4, 0x36, 0x6a, 0x3f, 0xe6,
-       0x49, 0x9c, 0xdb, 0x79, 0x9c, 0x6b, 0x49, 0x86, 0x4e, 0x5e, 0xa2, 0xcc,
-       0x76, 0xcd, 0x48, 0xb2, 0x6b, 0x4c, 0xb6, 0xd9, 0xd3, 0xd0, 0xb7, 0xcc,
-       0x40, 0x65, 0x97, 0x99, 0xe6, 0x98, 0x23, 0x18, 0x83, 0xe7, 0xcc, 0x25,
-       0x39, 0x54, 0x66, 0xdd, 0xef, 0x80, 0x9f, 0xb0, 0x3b, 0x3d, 0x4f, 0x6a,
-       0x39, 0xc7, 0x7c, 0x96, 0x3f, 0xdf, 0x25, 0x3d, 0x1f, 0xfb, 0xb1, 0x0f,
-       0xc7, 0x2c, 0xce, 0xbb, 0x9b, 0xb6, 0x06, 0x78, 0xd3, 0x61, 0x56, 0x76,
-       0x85, 0xd1, 0x7e, 0xba, 0x87, 0xef, 0x98, 0x07, 0xb6, 0xc6, 0x76, 0xce,
-       0xa3, 0x2f, 0xf6, 0xe5, 0xae, 0x93, 0xb6, 0x66, 0x9f, 0x5e, 0x9e, 0x3b,
-       0xfd, 0x00, 0x96, 0x1f, 0x6e, 0xf2, 0x78, 0x3f, 0x12, 0xf2, 0xb0, 0xfb,
-       0x2f, 0x51, 0xa6, 0x7e, 0x3d, 0x26, 0x39, 0x37, 0x89, 0x7d, 0x42, 0x87,
-       0xca, 0x0d, 0x86, 0xb7, 0x47, 0xf0, 0xbf, 0xff, 0x32, 0xf8, 0x20, 0x45,
-       0x8f, 0x37, 0xe4, 0x0b, 0x79, 0xd2, 0x00, 0xd9, 0xae, 0xc3, 0xbc, 0x58,
-       0x47, 0xf1, 0xe0, 0x96, 0x26, 0xcf, 0xef, 0x4d, 0x16, 0x33, 0x8c, 0xd7,
-       0x1a, 0x29, 0xb3, 0xc0, 0xa8, 0xf2, 0xfd, 0x36, 0xe7, 0x9e, 0x32, 0xd7,
-       0x91, 0xde, 0xc4, 0x85, 0xd0, 0x7e, 0x96, 0xbb, 0xa6, 0x4c, 0xf0, 0x1e,
-       0xe7, 0x93, 0xdd, 0xde, 0xae, 0x71, 0xe9, 0x99, 0x10, 0x65, 0x94, 0xf2,
-       0x9c, 0x77, 0xb7, 0xd9, 0xf7, 0x08, 0x65, 0x34, 0x86, 0xf3, 0x26, 0x2e,
-       0xf0, 0x69, 0xc1, 0x26, 0xc6, 0x71, 0xc6, 0x5b, 0x34, 0xed, 0x7c, 0xb7,
-       0x64, 0xca, 0xc6, 0x1a, 0xee, 0x7f, 0x6f, 0xf0, 0xea, 0xf8, 0xde, 0xc2,
-       0x33, 0x39, 0xb6, 0x94, 0x56, 0x9e, 0x67, 0xf5, 0x19, 0x9e, 0x06, 0xed,
-       0xac, 0xc7, 0x73, 0xe6, 0x14, 0xf4, 0x0f, 0x58, 0xd1, 0xd3, 0x11, 0xbf,
-       0x88, 0xfe, 0x39, 0x60, 0x7c, 0xd1, 0x62, 0xdb, 0x55, 0x63, 0x71, 0x8c,
-       0x49, 0x3f, 0x13, 0x3e, 0xed, 0x05, 0xe3, 0x81, 0xf2, 0x2b, 0x46, 0x76,
-       0xe6, 0xaa, 0x91, 0x83, 0x5c, 0xcc, 0xb8, 0x3b, 0x20, 0xcf, 0xd4, 0x17,
-       0x1b, 0x6b, 0x27, 0xe3, 0xff, 0x62, 0xb6, 0x27, 0xa6, 0xa1, 0xdb, 0x07,
-       0xc0, 0x58, 0xef, 0x2c, 0x5b, 0xd5, 0xd9, 0xce, 0x9b, 0x61, 0x8d, 0x75,
-       0x2c, 0x27, 0xed, 0x7b, 0xe5, 0x35, 0xec, 0x77, 0x16, 0x7c, 0x9e, 0x95,
-       0x42, 0xb9, 0x24, 0xf9, 0x93, 0xdb, 0xec, 0x61, 0xc4, 0xb8, 0x8b, 0xb4,
-       0x13, 0xc3, 0x8a, 0xf4, 0xbd, 0x8d, 0xdd, 0xae, 0x14, 0x6b, 0xd2, 0xc4,
-       0xb2, 0x0e, 0xc8, 0x13, 0xea, 0x4a, 0x8b, 0x32, 0x79, 0xe7, 0xb2, 0xfd,
-       0x20, 0xbe, 0xed, 0x59, 0xba, 0xa7, 0x19, 0xb9, 0xfe, 0x9e, 0x76, 0x2f,
-       0xec, 0x89, 0xd8, 0x01, 0xcc, 0x77, 0x81, 0xf9, 0x2e, 0x30, 0xdf, 0x05,
-       0xe6, 0xbb, 0xc0, 0x7c, 0x17, 0xf6, 0xc0, 0x05, 0xee, 0xbb, 0xc0, 0x7d,
-       0x17, 0xb8, 0xef, 0x02, 0xf7, 0xdd, 0x2c, 0xce, 0x8e, 0xd8, 0x4e, 0xbb,
-       0x71, 0xdf, 0x82, 0xad, 0xf4, 0x7c, 0x9b, 0x9b, 0xb4, 0xbf, 0x00, 0x9d,
-       0xb4, 0x5b, 0x64, 0xb8, 0x6b, 0x33, 0xf6, 0x56, 0x87, 0x67, 0x3d, 0x9e,
-       0x58, 0xa3, 0xeb, 0x33, 0x5a, 0x77, 0xbe, 0x0a, 0xba, 0x4c, 0x94, 0x7f,
-       0x09, 0xb2, 0x59, 0x03, 0x7a, 0x7e, 0x41, 0xfb, 0x15, 0xa7, 0x2c, 0x4f,
-       0x36, 0xeb, 0x51, 0xf7, 0x69, 0xd4, 0xd5, 0xa3, 0xcf, 0x21, 0xf4, 0xa1,
-       0x5f, 0xd2, 0xa0, 0xeb, 0x82, 0xfd, 0xe8, 0x9f, 0xfc, 0x26, 0xd6, 0x4a,
-       0xa2, 0x5f, 0x03, 0xe6, 0x6e, 0x45, 0x9f, 0xcf, 0xa2, 0xcf, 0xcd, 0x28,
-       0xd3, 0x9f, 0xdd, 0x82, 0xf2, 0xa7, 0xaa, 0xc6, 0xdc, 0x8a, 0xba, 0xcf,
-       0x54, 0xd5, 0xcd, 0xa3, 0x0e, 0x71, 0xb0, 0x7d, 0x51, 0x8f, 0x2b, 0xa2,
-       0xdc, 0x5c, 0xd5, 0xe7, 0x12, 0xea, 0x7a, 0x51, 0xf7, 0x3d, 0x3c, 0x11,
-       0xff, 0xda, 0xa4, 0xc9, 0x6f, 0xa3, 0x6f, 0x9a, 0x40, 0x7d, 0x58, 0xfb,
-       0x97, 0x4f, 0xd2, 0xdf, 0x82, 0x9d, 0xfd, 0x53, 0xcb, 0xf3, 0xc7, 0x9e,
-       0xb1, 0x3d, 0x59, 0xf5, 0xcb, 0x3f, 0xaa, 0x2a, 0xb3, 0xef, 0xff, 0x56,
-       0xd5, 0xed, 0xda, 0xb8, 0xb4, 0xfc, 0x7e, 0x78, 0xf9, 0x98, 0xe3, 0x55,
-       0x7d, 0x5e, 0x6e, 0x5c, 0x5a, 0xfe, 0x7c, 0xcd, 0xf2, 0x31, 0xbf, 0xb5,
-       0x61, 0x69, 0xdd, 0xe1, 0xa6, 0xa5, 0x65, 0xfa, 0x7d, 0x31, 0xc4, 0x2d,
-       0x7e, 0xff, 0x07, 0x37, 0x79, 0xed, 0xe4, 0x6f, 0xb5, 0x2c, 0x29, 0xe3,
-       0x8d, 0xb2, 0x89, 0x73, 0xb8, 0x60, 0x40, 0xe7, 0x6c, 0x33, 0xfd, 0x8a,
-       0x91, 0x83, 0x4c, 0x65, 0xcb, 0xfe, 0x7c, 0xd4, 0xe5, 0xea, 0xdc, 0x80,
-       0x9f, 0x13, 0xa0, 0x8f, 0x15, 0x85, 0xdc, 0x00, 0x8b, 0x63, 0xc9, 0xa3,
-       0x45, 0x59, 0xd4, 0xe1, 0x36, 0xf3, 0x5a, 0x3a, 0x3c, 0xa9, 0x71, 0xeb,
-       0x32, 0xe8, 0xac, 0x48, 0x7f, 0xaa, 0x96, 0x76, 0x47, 0xe3, 0x19, 0xb1,
-       0xa8, 0x52, 0x09, 0x6d, 0xad, 0xc8, 0xc1, 0xd4, 0x3b, 0x15, 0x51, 0x38,
-       0xf8, 0x4d, 0xcd, 0x57, 0xe2, 0xa1, 0x0d, 0xb9, 0x8d, 0x29, 0x3f, 0x2e,
-       0x94, 0x3e, 0x45, 0x9f, 0xe4, 0x88, 0x87, 0xb3, 0xc4, 0x22, 0x94, 0xcb,
-       0x63, 0xe8, 0xc3, 0xf5, 0xf1, 0x9c, 0x21, 0xb6, 0x5b, 0xca, 0xce, 0xe4,
-       0x6d, 0xce, 0xbb, 0x12, 0x5e, 0xfe, 0xd8, 0xa2, 0x2f, 0x68, 0x39, 0x67,
-       0x60, 0xf3, 0xd8, 0x46, 0xff, 0xe0, 0x0c, 0x7d, 0x91, 0x80, 0x6f, 0xd3,
-       0x11, 0x12, 0x67, 0x11, 0x47, 0xbd, 0x7d, 0xb5, 0xd0, 0xd7, 0x5f, 0xc3,
-       0x5e, 0x57, 0xc6, 0xab, 0x76, 0xf3, 0xfa, 0xba, 0xbd, 0x77, 0x41, 0xb7,
-       0x7d, 0xd9, 0x5b, 0x29, 0x07, 0x70, 0x45, 0x9d, 0xc5, 0xf3, 0xe5, 0xe4,
-       0xb1, 0x22, 0x74, 0x69, 0x4e, 0xc5, 0xbb, 0xfe, 0xb9, 0xd0, 0xaf, 0x49,
-       0x9e, 0x9a, 0x82, 0x6c, 0x0f, 0xa9, 0x38, 0x80, 0x31, 0x40, 0x45, 0x76,
-       0xa7, 0x86, 0x62, 0xe4, 0x43, 0xc6, 0xbc, 0x1a, 0xa6, 0x1f, 0x31, 0xe7,
-       0x92, 0x67, 0x29, 0xb4, 0xa7, 0xc0, 0xdb, 0x7f, 0x95, 0x5c, 0x8c, 0x75,
-       0xff, 0x55, 0x99, 0x86, 0xff, 0xa3, 0x7c, 0x22, 0xe5, 0x03, 0xd0, 0xa7,
-       0x83, 0xad, 0x2f, 0x93, 0xa7, 0x17, 0xc0, 0x67, 0xdf, 0x2f, 0xb8, 0x4c,
-       0xbf, 0x54, 0x96, 0xfa, 0xcf, 0x22, 0x8f, 0x94, 0xfe, 0x19, 0x76, 0xc8,
-       0xc4, 0x7c, 0xb4, 0x77, 0xb4, 0x29, 0xac, 0xdf, 0x11, 0xa6, 0xff, 0xe6,
-       0xd9, 0xff, 0x10, 0xd6, 0x43, 0x4c, 0x5d, 0xfa, 0x0f, 0x23, 0xef, 0xb6,
-       0xd2, 0xb7, 0xc2, 0xfe, 0x89, 0xab, 0x6c, 0x63, 0x5d, 0x44, 0xfb, 0xdc,
-       0x51, 0xed, 0x63, 0xdb, 0xda, 0xc7, 0x26, 0x1d, 0x46, 0xc4, 0x4e, 0xfb,
-       0xbe, 0x02, 0xcf, 0x0c, 0x67, 0xb3, 0x55, 0xf9, 0x0a, 0xb2, 0xb2, 0xaf,
-       0xe0, 0xd3, 0x74, 0x16, 0xfb, 0xa4, 0x6f, 0xa7, 0x72, 0x3f, 0x8d, 0x5e,
-       0xbe, 0x89, 0x34, 0xf8, 0x36, 0x53, 0xd9, 0xe6, 0xa3, 0x30, 0x83, 0xd8,
-       0xdb, 0x6f, 0x83, 0xd6, 0x3d, 0x92, 0x1d, 0x3f, 0xab, 0x6d, 0x30, 0x63,
-       0x07, 0xfa, 0xed, 0x9e, 0xcc, 0x66, 0x53, 0x0d, 0x86, 0x9e, 0xa7, 0x19,
-       0x56, 0x33, 0x90, 0x97, 0xe2, 0x5a, 0xf4, 0x6d, 0x7c, 0x3f, 0x67, 0x56,
-       0xfb, 0x39, 0xe7, 0xe5, 0xa0, 0xeb, 0xc5, 0x0a, 0xfd, 0xa5, 0x0b, 0xa8,
-       0x53, 0xb4, 0xc7, 0xe9, 0x4f, 0x9a, 0x26, 0xfd, 0xc9, 0x24, 0x82, 0x0e,
-       0x6f, 0x2f, 0x6d, 0xd8, 0xcb, 0xcc, 0xc2, 0x5e, 0xea, 0x2f, 0x2c, 0xdd,
-       0x0b, 0xe9, 0xb7, 0xc1, 0x4f, 0x4b, 0xe3, 0x14, 0xe7, 0xfc, 0x46, 0x98,
-       0x18, 0xd6, 0x4f, 0x9f, 0xc8, 0xf5, 0x7c, 0xb1, 0xa5, 0xf3, 0xc2, 0x63,
-       0x28, 0x4d, 0x5d, 0xa3, 0x8d, 0xfb, 0xf7, 0xf5, 0xca, 0xd2, 0xd8, 0xce,
-       0x3d, 0xfc, 0x09, 0xe6, 0x8c, 0x19, 0x79, 0xe5, 0x9b, 0xd1, 0xcf, 0x41,
-       0xdc, 0x5d, 0x7a, 0x05, 0x4f, 0xea, 0x8e, 0x9a, 0x07, 0xfb, 0x8d, 0xaa,
-       0xfd, 0x8e, 0xb9, 0x97, 0xd4, 0x1e, 0xa7, 0x4b, 0x3f, 0x90, 0xc2, 0xc9,
-       0x1f, 0xc2, 0x26, 0x06, 0x73, 0x75, 0xcc, 0x73, 0x92, 0x57, 0xc5, 0x00,
-       0xb6, 0x92, 0x66, 0xe6, 0xe1, 0xbe, 0x17, 0xf6, 0xe2, 0x85, 0x71, 0x9c,
-       0xbf, 0xe1, 0xb5, 0xab, 0xf5, 0x7d, 0x9e, 0xd7, 0x04, 0xe8, 0xa9, 0xc0,
-       0x47, 0x8d, 0x83, 0x86, 0xe0, 0x98, 0xc7, 0xa4, 0xcf, 0xe5, 0x59, 0xb5,
-       0xc7, 0x87, 0xc4, 0xb1, 0xf3, 0xe2, 0xfb, 0x25, 0x5c, 0x9f, 0x78, 0x90,
-       0x43, 0x0c, 0xc5, 0xdc, 0xaa, 0xcf, 0x57, 0x9f, 0xa7, 0xd1, 0x0b, 0xd5,
-       0xf2, 0x31, 0x8a, 0xd8, 0xab, 0xe0, 0x92, 0x4f, 0xbe, 0xdc, 0xfa, 0x6b,
-       0x5f, 0x31, 0xb8, 0x9f, 0x11, 0x95, 0x4f, 0x7c, 0x6d, 0x41, 0x7e, 0x87,
-       0x81, 0x2b, 0x9e, 0x3c, 0xbe, 0xaa, 0x79, 0xe3, 0xcb, 0x6d, 0x54, 0xcb,
-       0x00, 0x63, 0x43, 0xea, 0x95, 0x2f, 0x23, 0x1d, 0xf6, 0xdd, 0x8a, 0x17,
-       0x6c, 0x53, 0x79, 0x46, 0x75, 0xce, 0x83, 0x0b, 0xe7, 0xbc, 0xbe, 0x4a,
-       0x66, 0x53, 0xb6, 0xa7, 0xa3, 0xd4, 0x45, 0xe8, 0x34, 0xf8, 0xf5, 0xfc,
-       0x12, 0xdd, 0xef, 0xba, 0x46, 0x8e, 0x36, 0x2a, 0xa1, 0xc9, 0x97, 0xc1,
-       0xcb, 0x5b, 0x11, 0xbb, 0x88, 0x58, 0x13, 0xc4, 0x28, 0xfa, 0x22, 0x8b,
-       0xfe, 0xf1, 0xb4, 0xac, 0xe4, 0x1b, 0x5f, 0xcf, 0x0f, 0xb9, 0x7d, 0x8d,
-       0x7e, 0xc8, 0xaf, 0xd6, 0x30, 0x96, 0x99, 0x83, 0x9e, 0x1e, 0xc0, 0xf8,
-       0x1a, 0xe7, 0x47, 0xb0, 0x6f, 0xa7, 0xad, 0x5a, 0xc7, 0xc7, 0x8b, 0xa8,
-       0x6c, 0x9c, 0xdc, 0xa2, 0x30, 0xc3, 0x9e, 0x58, 0xc4, 0x8c, 0x61, 0x97,
-       0xf2, 0xab, 0xf4, 0x34, 0xb6, 0x51, 0x7c, 0x8c, 0x78, 0xd6, 0x62, 0xbe,
-       0x67, 0x65, 0x1c, 0xf0, 0x72, 0xba, 0x2b, 0xc7, 0x0a, 0x37, 0x55, 0xf1,
-       0x72, 0x25, 0xdc, 0x3c, 0x07, 0xde, 0xa5, 0x11, 0x13, 0x27, 0xcf, 0x88,
-       0xec, 0x41, 0x9c, 0x9c, 0x7c, 0x4b, 0xa4, 0x0f, 0xb1, 0x72, 0x72, 0x56,
-       0x24, 0x83, 0x78, 0x99, 0xf1, 0xdb, 0x5d, 0xe0, 0x69, 0x2f, 0xe2, 0xe9,
-       0x1e, 0x60, 0x6a, 0x0a, 0x18, 0xbb, 0x1d, 0xfc, 0xed, 0x02, 0xbf, 0x6d,
-       0xc4, 0x5b, 0x65, 0x39, 0x70, 0x5c, 0x8c, 0x7d, 0x2a, 0x7f, 0x4d, 0x7d,
-       0x8f, 0xc1, 0xce, 0x56, 0x2a, 0x87, 0x52, 0xed, 0x88, 0xf5, 0x13, 0xf2,
-       0x39, 0x8b, 0xb1, 0xad, 0x61, 0xb5, 0x75, 0x7f, 0x3f, 0x14, 0xf4, 0x6b,
-       0xb3, 0xd7, 0xb5, 0x13, 0xcb, 0xf9, 0x9f, 0x53, 0xb6, 0xe2, 0xc5, 0xd0,
-       0x6a, 0xfc, 0xdf, 0xb7, 0xc0, 0xff, 0x9e, 0x3a, 0xa9, 0xbb, 0x4b, 0xe5,
-       0x16, 0xda, 0xba, 0x0f, 0x11, 0xcf, 0x52, 0xb0, 0xfb, 0xb0, 0xcf, 0x15,
-       0xb9, 0x33, 0x75, 0xb5, 0x72, 0xd1, 0xd9, 0x20, 0xf9, 0xed, 0x0f, 0x6a,
-       0x4c, 0x3f, 0xf5, 0x87, 0x59, 0xa7, 0x08, 0x1d, 0xf1, 0xf2, 0x88, 0x43,
-       0xe3, 0x11, 0x58, 0x0a, 0xfe, 0x35, 0xca, 0x74, 0xef, 0x55, 0x9c, 0xe3,
-       0xb6, 0x33, 0x4c, 0x42, 0x11, 0x6b, 0xa6, 0x63, 0x51, 0x95, 0x43, 0xde,
-       0xe4, 0xb0, 0xde, 0xc6, 0xb9, 0x0e, 0xc8, 0x34, 0xfc, 0x8b, 0x99, 0x5e,
-       0xd0, 0xb8, 0xbd, 0x19, 0xfd, 0xa9, 0x7b, 0xe4, 0xf9, 0x80, 0x0c, 0xc6,
-       0xc8, 0xd3, 0x18, 0xfa, 0xef, 0x45, 0x9f, 0x46, 0x3c, 0xff, 0x28, 0x34,
-       0x6d, 0x33, 0x9e, 0xfe, 0x3c, 0xca, 0x9c, 0x23, 0x68, 0x5b, 0x77, 0x85,
-       0x45, 0xcd, 0xc9, 0x31, 0xcd, 0x0a, 0x03, 0x16, 0xd7, 0xe2, 0x3a, 0x6c,
-       0x7b, 0xaf, 0x72, 0x47, 0x77, 0x6f, 0x60, 0xbd, 0x86, 0xc0, 0x7a, 0xbd,
-       0x81, 0xf5, 0x48, 0x67, 0x63, 0x80, 0xce, 0x46, 0x8c, 0xff, 0x5d, 0xac,
-       0x4d, 0x7e, 0x04, 0xd7, 0xcc, 0x07, 0xd6, 0xf4, 0xf7, 0xd7, 0x1c, 0x18,
-       0xf7, 0x0e, 0xd6, 0x63, 0x5d, 0x2c, 0x50, 0x47, 0x1a, 0x9a, 0x50, 0xc7,
-       0x72, 0x63, 0x80, 0xae, 0xa8, 0x8a, 0xf7, 0xa7, 0xd5, 0x19, 0x92, 0xcf,
-       0x75, 0xb0, 0x6b, 0x26, 0x6c, 0x4b, 0x0d, 0xfc, 0xaf, 0xea, 0xbd, 0x7e,
-       0x0d, 0xeb, 0xfa, 0xf3, 0xc5, 0x30, 0x07, 0xfb, 0xb3, 0x6f, 0x48, 0x8f,
-       0x67, 0x3d, 0xdb, 0xff, 0xb6, 0xf2, 0x8c, 0xe2, 0x5b, 0x1a, 0xb4, 0x93,
-       0xc6, 0x36, 0x99, 0x6a, 0xb4, 0x70, 0x9e, 0xa6, 0xb6, 0xa5, 0xc0, 0xda,
-       0xb2, 0x69, 0xb4, 0x77, 0xf3, 0xfc, 0x37, 0x68, 0x4c, 0xad, 0x33, 0xb2,
-       0xc7, 0x99, 0x4b, 0xa8, 0xd7, 0xb1, 0x22, 0xe2, 0x13, 0x65, 0x87, 0x7c,
-       0x3b, 0x41, 0x3b, 0x44, 0xdf, 0x86, 0x36, 0xf6, 0x9c, 0x7e, 0xc7, 0x13,
-       0x72, 0xfc, 0xd0, 0x4c, 0xa3, 0x5c, 0x54, 0x7c, 0xb5, 0x65, 0x7e, 0x81,
-       0xaf, 0x61, 0xfd, 0xbd, 0xe6, 0x31, 0xfd, 0x2d, 0x64, 0x3f, 0x7c, 0x27,
-       0xbc, 0x97, 0x32, 0xa0, 0x23, 0x21, 0xed, 0xdd, 0xcc, 0x61, 0x14, 0xf1,
-       0x74, 0xf0, 0x34, 0xf0, 0x84, 0xcd, 0x42, 0x0c, 0xd2, 0xde, 0xcd, 0x58,
-       0x50, 0x40, 0xdb, 0x15, 0x15, 0x07, 0xce, 0x94, 0x6d, 0xe3, 0x4e, 0xd7,
-       0xcb, 0x1d, 0xcd, 0x3b, 0xab, 0xe5, 0x8e, 0x1e, 0xa8, 0xc5, 0x79, 0x9c,
-       0xf2, 0x73, 0x47, 0xf3, 0xa2, 0x72, 0x47, 0xa7, 0xae, 0x93, 0x3b, 0xca,
-       0xac, 0x3d, 0x77, 0xc4, 0xf9, 0x2d, 0xb9, 0xbb, 0xc7, 0x36, 0xbf, 0xa8,
-       0x73, 0x47, 0x6f, 0x88, 0x97, 0x3b, 0xba, 0x28, 0x2b, 0xe7, 0x8e, 0x8e,
-       0x56, 0xe5, 0x8e, 0x9a, 0x54, 0xee, 0x88, 0xf3, 0x78, 0xb9, 0x23, 0x96,
-       0xf3, 0xdd, 0xbf, 0xac, 0x72, 0xe9, 0xf9, 0x6e, 0x60, 0xb0, 0xeb, 0x63,
-       0x9c, 0x6d, 0x0c, 0xa8, 0xf8, 0xf2, 0x4a, 0xb8, 0xd9, 0xf1, 0x31, 0x8e,
-       0xb6, 0x60, 0xf3, 0x82, 0x3d, 0xf3, 0xf1, 0x6e, 0x54, 0xd9, 0xbd, 0xe5,
-       0xf9, 0xc5, 0x7b, 0xaa, 0xf2, 0x8b, 0x03, 0x9e, 0xdd, 0x50, 0x38, 0x37,
-       0xa8, 0x71, 0x6e, 0x74, 0xc1, 0xcf, 0x39, 0x59, 0xcb, 0x18, 0x7c, 0xa4,
-       0x14, 0xc4, 0x51, 0x4b, 0x8d, 0xf5, 0xf2, 0x2c, 0x8b, 0x18, 0x7a, 0xb8,
-       0x0a, 0x43, 0x1f, 0x5b, 0xf1, 0xbb, 0x58, 0x3c, 0xb3, 0xfc, 0xbb, 0x98,
-       0x21, 0xcd, 0xf4, 0x39, 0xba, 0xf3, 0xd8, 0x03, 0x63, 0xe6, 0xfd, 0x92,
-       0x19, 0xb0, 0x81, 0x45, 0x7e, 0xfe, 0x85, 0xe7, 0xbc, 0x68, 0x63, 0xb2,
-       0xe6, 0xc7, 0x97, 0x83, 0x79, 0x48, 0xe5, 0x60, 0xbe, 0x5f, 0x1b, 0xcc,
-       0xc1, 0xcc, 0x03, 0xb3, 0x32, 0x16, 0xf3, 0x5b, 0x2b, 0xe7, 0x60, 0x1e,
-       0x5a, 0x21, 0x07, 0xf3, 0x5d, 0x59, 0xcc, 0xc1, 0x7c, 0x57, 0xfc, 0x1c,
-       0x0c, 0xe7, 0x08, 0x69, 0x9f, 0x56, 0x30, 0xee, 0x02, 0x7e, 0xe7, 0xf1,
-       0xf3, 0xf2, 0x32, 0xf3, 0x0b, 0x7b, 0x58, 0x29, 0x2f, 0xf3, 0x6f, 0xb5,
-       0x1f, 0x24, 0x2f, 0xe3, 0xd9, 0x04, 0x3f, 0x2f, 0x83, 0x9f, 0x0d, 0x1b,
-       0x64, 0x06, 0xf3, 0x32, 0xef, 0x53, 0x37, 0x50, 0xc7, 0x32, 0xeb, 0xa1,
-       0x23, 0xb0, 0x53, 0x19, 0xd8, 0x99, 0x69, 0xf7, 0xd7, 0xd5, 0x79, 0xcc,
-       0xb8, 0x53, 0xd8, 0x77, 0x02, 0xe7, 0x41, 0x5e, 0xb6, 0x2b, 0x5f, 0x34,
-       0x63, 0xc5, 0x8d, 0x6c, 0x27, 0xac, 0xda, 0x38, 0xbf, 0x9d, 0x5b, 0xc6,
-       0x50, 0x99, 0xf2, 0x1e, 0x31, 0x0a, 0xd8, 0x4b, 0xdf, 0xf8, 0x94, 0x0c,
-       0x95, 0x7d, 0x3f, 0xab, 0x5b, 0x9f, 0xc5, 0x94, 0xd2, 0xd3, 0x69, 0xf0,
-       0x00, 0x98, 0xb1, 0x06, 0x9b, 0x75, 0x16, 0x34, 0x07, 0xf7, 0x81, 0x18,
-       0xba, 0x07, 0x75, 0xea, 0xdc, 0xe9, 0x6f, 0xfa, 0xb4, 0x24, 0xa8, 0xf3,
-       0x6b, 0x98, 0x8f, 0x75, 0x67, 0x55, 0xfc, 0x56, 0xe8, 0xe1, 0x5e, 0x69,
-       0xfb, 0xe6, 0x40, 0x1f, 0xea, 0x66, 0x18, 0x33, 0xd2, 0x0e, 0xfa, 0x31,
-       0x5d, 0x54, 0xc5, 0x74, 0x9b, 0x15, 0x3f, 0xc8, 0xeb, 0x5f, 0x8b, 0x10,
-       0x3b, 0x37, 0x3b, 0xdc, 0xc3, 0x79, 0x8d, 0x7b, 0x2c, 0xfb, 0xb1, 0x23,
-       0xdf, 0xc9, 0xa7, 0xa7, 0x54, 0xde, 0x67, 0xda, 0xf5, 0xcf, 0xf0, 0x5b,
-       0xd8, 0x3b, 0xcb, 0xbd, 0x72, 0xa1, 0x59, 0x22, 0xb1, 0x34, 0x73, 0xbd,
-       0xf4, 0xd5, 0x77, 0x30, 0xf7, 0x50, 0xd3, 0xb4, 0x8a, 0xfe, 0xee, 0x5b,
-       0x45, 0x7f, 0xef, 0xae, 0xd2, 0xdf, 0xfe, 0x55, 0xf5, 0xf7, 0xeb, 0x91,
-       0xa0, 0xfe, 0xee, 0x5b, 0x45, 0x7f, 0x1f, 0xad, 0xd2, 0xdf, 0x83, 0x37,
-       0xa4, 0xbf, 0x3a, 0x36, 0x4e, 0xdd, 0xaa, 0x72, 0xc6, 0xc3, 0x13, 0xc4,
-       0xac, 0x4f, 0xeb, 0xdc, 0xd5, 0x4a, 0xbe, 0x98, 0x4f, 0x43, 0x5b, 0xcd,
-       0x47, 0xe3, 0x87, 0xfd, 0x23, 0xf6, 0xe9, 0xf9, 0xa3, 0xfd, 0xf0, 0x69,
-       0xaf, 0xbd, 0xee, 0x1f, 0x8b, 0x99, 0xf6, 0x7d, 0xc0, 0xad, 0x1f, 0xd1,
-       0xda, 0x6b, 0x91, 0x3f, 0xc6, 0x56, 0xf4, 0x07, 0xa2, 0xda, 0x66, 0x4e,
-       0x6a, 0x1d, 0xf4, 0xf3, 0x12, 0x41, 0x7d, 0xa6, 0x9c, 0x52, 0x36, 0x7f,
-       0x8a, 0x3d, 0x51, 0x3e, 0x7d, 0x0c, 0xd8, 0x52, 0xa5, 0x13, 0x73, 0x52,
-       0x00, 0x6e, 0x79, 0x3a, 0x41, 0x39, 0xeb, 0xc4, 0xbe, 0x61, 0x2b, 0xdd,
-       0xa7, 0xbd, 0xb3, 0x70, 0xf0, 0x9c, 0xf1, 0x75, 0x3f, 0x81, 0x75, 0xfd,
-       0x36, 0xda, 0x1e, 0x07, 0x3e, 0xd9, 0x36, 0xf8, 0x93, 0x2d, 0xc0, 0x19,
-       0xd6, 0x2f, 0xcd, 0x73, 0xaf, 0x8e, 0xb1, 0x52, 0x0c, 0xa3, 0xef, 0xe9,
-       0x1e, 0x60, 0x4e, 0x0f, 0x71, 0xb3, 0x84, 0xd8, 0x8c, 0x7a, 0x41, 0x5d,
-       0xe9, 0xe8, 0xda, 0x6d, 0xd2, 0xe7, 0x7b, 0x12, 0x71, 0xfc, 0x2d, 0x4a,
-       0xaf, 0x76, 0x97, 0x3b, 0x66, 0xdf, 0x30, 0xb9, 0x46, 0xa5, 0x92, 0x57,
-       0xdf, 0x19, 0xc4, 0x6c, 0xeb, 0xde, 0xb2, 0x8e, 0x36, 0xf3, 0x16, 0x27,
-       0xa4, 0xe5, 0x3e, 0x83, 0x77, 0xea, 0xd1, 0xeb, 0xf0, 0x47, 0x78, 0x47,
-       0xe1, 0x27, 0x2a, 0x5f, 0x37, 0xed, 0xd2, 0xf7, 0x60, 0xcc, 0xb4, 0x53,
-       0xf7, 0xdb, 0xa2, 0xbe, 0xb1, 0x66, 0x53, 0x3b, 0xf4, 0xf7, 0x36, 0xda,
-       0xc4, 0x24, 0x31, 0x75, 0xc9, 0x79, 0xf3, 0x8e, 0x47, 0x4e, 0xc5, 0x5c,
-       0x1c, 0xaf, 0x7c, 0x7f, 0xc4, 0x49, 0x56, 0xe0, 0xfb, 0x40, 0x44, 0xc7,
-       0x97, 0xd4, 0xf9, 0xa8, 0x8a, 0x7d, 0xbd, 0x78, 0x8a, 0xf1, 0xf7, 0xd2,
-       0xbb, 0x1d, 0x2b, 0xcb, 0x40, 0xcb, 0x07, 0x90, 0x81, 0xea, 0xf3, 0x8b,
-       0x00, 0x8b, 0xfc, 0xf3, 0xf3, 0x7d, 0xac, 0xbf, 0xd0, 0xfb, 0xde, 0xa2,
-       0xf5, 0xe9, 0xff, 0xc3, 0x3e, 0x8d, 0xc0, 0x3e, 0x7d, 0x6c, 0xfc, 0xa2,
-       0xde, 0xe7, 0xce, 0x2a, 0x6c, 0xec, 0x41, 0xfd, 0xe1, 0x9a, 0x8d, 0x1f,
-       0x10, 0x1b, 0xf7, 0xde, 0x10, 0x36, 0xfe, 0x70, 0xdd, 0x5a, 0xb1, 0xf1,
-       0xd0, 0x07, 0xc6, 0x46, 0xee, 0x6b, 0x65, 0x3c, 0xda, 0xb7, 0x0c, 0x8f,
-       0xfe, 0xe0, 0x13, 0xc4, 0xa3, 0xd5, 0xb0, 0x84, 0xe7, 0xd2, 0xa0, 0x7c,
-       0x6c, 0x4f, 0xff, 0xe0, 0x5f, 0xcc, 0x84, 0xe5, 0xc2, 0xbd, 0x11, 0x79,
-       0x6d, 0x27, 0xfc, 0x6e, 0xf2, 0x48, 0x9d, 0x07, 0xcb, 0xd1, 0x3a, 0xcf,
-       0x36, 0xc6, 0x1b, 0xbd, 0x9c, 0x02, 0xc7, 0xf8, 0x3a, 0x6d, 0xa3, 0x9d,
-       0x6d, 0x5b, 0xe4, 0xf5, 0xc6, 0x1b, 0x89, 0x53, 0xf9, 0x8d, 0x66, 0xa5,
-       0x38, 0x75, 0xf5, 0x9c, 0xe6, 0x62, 0x9c, 0x4a, 0xac, 0x6d, 0xd4, 0x79,
-       0x2c, 0xc6, 0x67, 0xfb, 0x35, 0x7e, 0xf2, 0x1d, 0xf1, 0xb8, 0x8b, 0x58,
-       0xdc, 0x45, 0x1c, 0xee, 0x22, 0x46, 0x87, 0x6d, 0x7e, 0x01, 0x32, 0xf7,
-       0x6d, 0x17, 0x31, 0xb8, 0x8b, 0x18, 0xdc, 0xed, 0xd2, 0x71, 0x7c, 0xbf,
-       0xfe, 0x76, 0xc1, 0xef, 0xfb, 0xcc, 0x83, 0x14, 0x61, 0x57, 0x46, 0x79,
-       0x3f, 0xc3, 0xcc, 0xa6, 0xd6, 0xe9, 0xfd, 0xf9, 0x79, 0xfd, 0x56, 0x9d,
-       0x5b, 0xda, 0xb4, 0x49, 0xf9, 0x0b, 0xe6, 0x2b, 0x75, 0xde, 0x1d, 0x00,
-       0xde, 0x23, 0x79, 0x14, 0xbe, 0x92, 0xba, 0x87, 0x45, 0x3d, 0xad, 0x98,
-       0x69, 0xe6, 0x8e, 0xc4, 0x34, 0xd3, 0x77, 0x60, 0xcc, 0x36, 0x2f, 0x66,
-       0x89, 0x49, 0xc8, 0x4c, 0xd7, 0x93, 0xa7, 0x86, 0x99, 0x5e, 0xaf, 0xe7,
-       0x9a, 0xaf, 0xf3, 0xfc, 0xbd, 0x4e, 0x96, 0x2d, 0x33, 0xfd, 0x59, 0x3e,
-       0x71, 0xee, 0x7e, 0xfd, 0x3d, 0x8d, 0x4b, 0xd7, 0x1a, 0x53, 0x18, 0x9f,
-       0x4d, 0xdd, 0x8b, 0xf9, 0xd4, 0xfd, 0xa7, 0x05, 0x7e, 0x9b, 0xd7, 0xe4,
-       0xf7, 0x98, 0xe6, 0xb7, 0xc7, 0xe3, 0x10, 0xfb, 0xa9, 0xdc, 0x36, 0x79,
-       0xed, 0xcf, 0xa7, 0x72, 0x93, 0x58, 0x47, 0xdd, 0x01, 0xc1, 0xb3, 0x62,
-       0x49, 0xc3, 0xc0, 0x7d, 0x61, 0x27, 0xb8, 0xae, 0xff, 0x2d, 0x7f, 0x2d,
-       0x6b, 0x6e, 0x51, 0xdf, 0x07, 0x3d, 0xbb, 0x31, 0xa6, 0x64, 0xd0, 0x4a,
-       0x73, 0x5f, 0xef, 0x43, 0xfe, 0xc6, 0x94, 0xfc, 0xe5, 0x10, 0x67, 0x8d,
-       0xf6, 0x74, 0x24, 0x2c, 0x73, 0xba, 0x8e, 0x39, 0xe4, 0xbe, 0xb2, 0x8f,
-       0x7d, 0x5c, 0xaf, 0xda, 0xa6, 0x33, 0xff, 0xe7, 0x63, 0x9a, 0xb4, 0x78,
-       0x79, 0xc1, 0xb5, 0xde, 0xa9, 0x58, 0xd4, 0xa5, 0xc1, 0x05, 0x5d, 0xaa,
-       0xab, 0xd2, 0x25, 0x7f, 0x9f, 0xeb, 0xc5, 0xff, 0xe6, 0xbe, 0xd2, 0x5d,
-       0x90, 0xb9, 0x72, 0xe0, 0x1b, 0xcf, 0x82, 0x6c, 0xf0, 0x4e, 0xcc, 0x3d,
-       0x90, 0x41, 0x7e, 0xdf, 0xd8, 0x03, 0x3d, 0xaa, 0x54, 0xfa, 0x98, 0x27,
-       0xdf, 0xde, 0xaf, 0xef, 0x5b, 0x5c, 0x51, 0x39, 0x12, 0x6b, 0x59, 0x8e,
-       0xa4, 0x0f, 0xb2, 0x02, 0x3f, 0x00, 0x3a, 0x98, 0x57, 0x67, 0x49, 0x9f,
-       0xa0, 0xfa, 0x1b, 0xd2, 0xc5, 0x7a, 0x8f, 0x0f, 0x9d, 0xf5, 0xde, 0x77,
-       0x14, 0x73, 0xd3, 0xd2, 0x32, 0xc7, 0x27, 0xea, 0x3d, 0x59, 0x39, 0x06,
-       0xfb, 0xdc, 0x07, 0x59, 0xac, 0x91, 0x9c, 0x9a, 0xef, 0x98, 0xe4, 0x9f,
-       0xfd, 0xcf, 0xc6, 0xa5, 0xfd, 0x51, 0x77, 0xd2, 0xef, 0xff, 0x78, 0x55,
-       0xff, 0xc7, 0xd1, 0xff, 0x67, 0x55, 0xfd, 0x1f, 0x0f, 0xf4, 0x3f, 0xa1,
-       0xfb, 0xd7, 0xa2, 0xbf, 0xd2, 0x83, 0x26, 0xdf, 0x2f, 0x36, 0x1d, 0xc4,
-       0xb3, 0xcf, 0xfa, 0x63, 0x4e, 0x04, 0xc6, 0x4c, 0x56, 0xad, 0x31, 0x89,
-       0x7e, 0xf1, 0xa6, 0xa5, 0x6b, 0xa0, 0xee, 0x64, 0x8d, 0xfe, 0xbe, 0x47,
-       0x9f, 0xe5, 0xa0, 0xce, 0x17, 0xe0, 0x59, 0x0a, 0x7e, 0x33, 0xe2, 0x77,
-       0x0a, 0xca, 0x9e, 0xff, 0x8d, 0xc2, 0xbf, 0x93, 0x47, 0xbd, 0xcd, 0x40,
-       0x6f, 0x17, 0xfd, 0x1a, 0x4f, 0x2e, 0x83, 0x32, 0x49, 0x9c, 0x28, 0x4a,
-       0xc8, 0x29, 0xd3, 0x57, 0x32, 0x0a, 0x33, 0xbe, 0x7d, 0xe2, 0xbd, 0x2b,
-       0xde, 0xd7, 0xf5, 0xec, 0x70, 0xd8, 0x99, 0xd3, 0x31, 0xe2, 0xaf, 0x90,
-       0x7e, 0xe0, 0xa6, 0x8f, 0x9d, 0x72, 0xcc, 0xd3, 0x1f, 0xca, 0x31, 0xe7,
-       0xd7, 0x7a, 0x44, 0x99, 0xd5, 0xeb, 0xf4, 0x2d, 0xc3, 0xb7, 0xc4, 0xb2,
-       0x3c, 0x5c, 0x68, 0x0d, 0xf8, 0xd6, 0xbf, 0x80, 0x6f, 0xf7, 0xca, 0x94,
-       0x9d, 0x50, 0x79, 0xd0, 0x43, 0x0b, 0x79, 0x81, 0xc3, 0x91, 0x46, 0x87,
-       0x79, 0x81, 0xe4, 0xa9, 0x8c, 0x7c, 0xb0, 0xbc, 0xc0, 0xbe, 0x2a, 0x1d,
-       0xd9, 0xbb, 0xaa, 0xed, 0xfc, 0xb3, 0xfa, 0xb5, 0xe6, 0x05, 0x1e, 0xa9,
-       0xb2, 0x63, 0x87, 0x6e, 0xc0, 0x76, 0xe6, 0x95, 0xed, 0xe4, 0x5e, 0xaf,
-       0xe7, 0xcb, 0x7f, 0x25, 0xf2, 0xd1, 0xd8, 0xce, 0xd5, 0x72, 0xe2, 0x41,
-       0x7b, 0x40, 0xb9, 0xba, 0xac, 0xfd, 0x6c, 0x3c, 0x67, 0x2e, 0x43, 0x3f,
-       0x4d, 0x19, 0x54, 0xb2, 0xcc, 0xb2, 0x1f, 0xff, 0xde, 0xb7, 0x10, 0xff,
-       0x2e, 0xc6, 0xac, 0xf0, 0x67, 0xbb, 0xfc, 0xd8, 0x88, 0x7e, 0xb3, 0x6d,
-       0x14, 0xdc, 0x3d, 0xe6, 0x90, 0x6a, 0x63, 0x8e, 0xf7, 0x36, 0xf9, 0x9c,
-       0xba, 0x27, 0x70, 0x5e, 0xe7, 0xd2, 0xa6, 0x54, 0x4c, 0xc0, 0xef, 0x1c,
-       0x85, 0xd4, 0x46, 0xed, 0x03, 0x5e, 0x0f, 0x67, 0x97, 0xc6, 0xcf, 0xa6,
-       0x79, 0x04, 0x63, 0x19, 0x3f, 0x7f, 0x21, 0x4a, 0x4c, 0xcd, 0x96, 0x57,
-       0x1d, 0x8f, 0x71, 0x1c, 0xcf, 0x3e, 0x2a, 0x56, 0x46, 0xbf, 0x39, 0x3d,
-       0xde, 0x8b, 0x95, 0xb3, 0xe5, 0xad, 0x51, 0x0f, 0x17, 0x57, 0x8b, 0x63,
-       0x8e, 0x44, 0x99, 0x8b, 0x9c, 0x73, 0xaf, 0x47, 0xeb, 0xf2, 0xd8, 0x3c,
-       0xb4, 0x2c, 0x36, 0xb7, 0x74, 0xec, 0x7d, 0xbf, 0x8a, 0xcd, 0x3d, 0x1e,
-       0x73, 0x2f, 0xc1, 0xd8, 0xca, 0x01, 0x36, 0xf2, 0x5b, 0x10, 0xb1, 0x82,
-       0x3e, 0x0b, 0xe4, 0x67, 0xfc, 0x37, 0x94, 0x1f, 0xb3, 0x5c, 0x7e, 0x3e,
-       0x6e, 0xbb, 0xe1, 0xef, 0xfd, 0xb2, 0x78, 0xf9, 0xc5, 0x3d, 0xa0, 0x85,
-       0xf1, 0x56, 0x58, 0xcb, 0xc3, 0xcf, 0x69, 0xfc, 0xf6, 0xfb, 0xf9, 0xb9,
-       0x86, 0x85, 0x6f, 0xc9, 0xc5, 0xcc, 0x92, 0x1c, 0xcf, 0x16, 0xa6, 0xce,
-       0x71, 0xee, 0x99, 0x1b, 0xf8, 0xde, 0xf2, 0x61, 0xee, 0x7c, 0x54, 0xdb,
-       0xb9, 0x57, 0x21, 0xfb, 0x09, 0x7d, 0xff, 0xaf, 0x0b, 0x3a, 0xc0, 0x3b,
-       0xd0, 0xd5, 0x58, 0xab, 0xee, 0xf9, 0x45, 0x36, 0xa5, 0xf9, 0xed, 0x82,
-       0x3e, 0xc1, 0x4f, 0xf4, 0x5e, 0xe3, 0x72, 0x6c, 0xc2, 0xcb, 0xd3, 0x9a,
-       0xab, 0xde, 0xf1, 0xbb, 0x04, 0x5e, 0x24, 0x8f, 0xfa, 0x79, 0x5a, 0xd3,
-       0xbb, 0xe3, 0x77, 0xf4, 0xa3, 0xbb, 0xe3, 0xc7, 0xf9, 0x2d, 0xd9, 0xbb,
-       0xc2, 0x1d, 0xbf, 0xd0, 0x1a, 0xef, 0xf8, 0x6d, 0x54, 0x79, 0x5a, 0xce,
-       0xe3, 0xe5, 0x69, 0x59, 0x6e, 0xeb, 0xfe, 0x94, 0xc2, 0xa8, 0xe9, 0x09,
-       0xe6, 0x75, 0x1e, 0x5c, 0xf7, 0xc9, 0xe4, 0x75, 0xde, 0x8b, 0x7e, 0xfc,
-       0x79, 0x1d, 0x7e, 0x17, 0xf8, 0xb2, 0xf7, 0xdd, 0x5a, 0x6e, 0x24, 0x3f,
-       0xf0, 0xe1, 0x72, 0xb0, 0x07, 0x55, 0x0e, 0x76, 0xfb, 0xfa, 0x60, 0x0e,
-       0xd6, 0xbc, 0xce, 0x3d, 0xb8, 0x83, 0x2b, 0xe4, 0x60, 0xc3, 0x81, 0x7b,
-       0x70, 0x61, 0x7d, 0x0f, 0x6e, 0xa3, 0x83, 0x18, 0x53, 0xe7, 0x5b, 0xcd,
-       0x55, 0xef, 0xc1, 0xed, 0x5e, 0xff, 0xe1, 0xf3, 0xad, 0xcb, 0xee, 0xc1,
-       0x1d, 0xcd, 0x48, 0x8b, 0x24, 0x6e, 0x28, 0x16, 0xfa, 0x30, 0x71, 0x10,
-       0xff, 0x8f, 0x40, 0x0d, 0xf6, 0x0c, 0x99, 0x8f, 0x51, 0x3e, 0x29, 0x77,
-       0x69, 0x33, 0x5f, 0xe6, 0x7b, 0x17, 0xcf, 0xc7, 0xe8, 0xef, 0x5c, 0x7a,
-       0xb7, 0x62, 0xf1, 0x6e, 0x72, 0x64, 0xe1, 0x6e, 0xf2, 0x18, 0x64, 0xc6,
-       0x9c, 0x88, 0xc8, 0x74, 0xc0, 0xb6, 0x8e, 0xba, 0xf0, 0x9b, 0x26, 0x6d,
-       0xdd, 0xce, 0xff, 0xa7, 0x82, 0xb8, 0xb0, 0xc4, 0xfb, 0xcc, 0x0d, 0x12,
-       0x9a, 0x54, 0x98, 0x1a, 0xf3, 0xfe, 0xaf, 0x4e, 0x1c, 0x7d, 0x78, 0x77,
-       0x35, 0x2c, 0x87, 0x62, 0x94, 0x65, 0x5f, 0x8e, 0xbf, 0x05, 0xfe, 0x36,
-       0x65, 0x16, 0xcb, 0x31, 0x2d, 0xd7, 0x94, 0x69, 0x5f, 0xfe, 0x62, 0x32,
-       0x32, 0x41, 0x59, 0xde, 0xa1, 0xff, 0x9f, 0xc4, 0x39, 0x29, 0x94, 0xcf,
-       0xea, 0x78, 0x43, 0x7d, 0x8b, 0x02, 0x1f, 0x5b, 0xb4, 0x0d, 0xc6, 0x73,
-       0xa6, 0x85, 0x36, 0x8f, 0xdf, 0x1e, 0xa5, 0x6f, 0x7c, 0x5b, 0x7c, 0x08,
-       0x78, 0x37, 0xa8, 0x72, 0x27, 0x37, 0xc2, 0x6f, 0xe3, 0x1a, 0xdf, 0x48,
-       0xd7, 0xca, 0x73, 0xdf, 0x5f, 0xbe, 0x8c, 0xfd, 0xb5, 0x40, 0x36, 0xbe,
-       0x2a, 0xb9, 0x93, 0xb7, 0x49, 0xdf, 0x89, 0x24, 0xe8, 0x79, 0xbf, 0x52,
-       0x48, 0xc1, 0xb7, 0x7e, 0x96, 0x77, 0xe1, 0x80, 0xa1, 0x2e, 0x30, 0x14,
-       0xbc, 0x7b, 0x61, 0x99, 0xbf, 0x11, 0xbc, 0x43, 0x97, 0x5a, 0xb8, 0x13,
-       0xf5, 0x7c, 0x59, 0x22, 0x8d, 0xa4, 0x7b, 0x62, 0xf1, 0x2e, 0xfc, 0x5c,
-       0x39, 0xa7, 0xec, 0xdb, 0x73, 0xe5, 0x25, 0x39, 0x21, 0x75, 0x8e, 0xc3,
-       0xa5, 0x97, 0x61, 0xe3, 0x2e, 0x1b, 0xb4, 0x71, 0x63, 0xae, 0xdc, 0x12,
-       0x12, 0x9e, 0x89, 0x18, 0xe0, 0x83, 0xba, 0x9b, 0xe2, 0xdd, 0x4d, 0x68,
-       0x55, 0x67, 0xfb, 0x7f, 0xd4, 0x5d, 0x7d, 0x6c, 0x5b, 0xd7, 0x75, 0x3f,
-       0x7c, 0xa4, 0x3e, 0x4c, 0xcb, 0xd2, 0x93, 0x4c, 0xc9, 0xb4, 0x2d, 0xcb,
-       0x8f, 0xd2, 0x93, 0xa5, 0xc4, 0x4a, 0xc1, 0x79, 0xda, 0xaa, 0x01, 0x5a,
-       0xc7, 0x52, 0xf4, 0xc7, 0x82, 0x60, 0xa5, 0x65, 0x25, 0xf3, 0xd2, 0x2c,
-       0x51, 0x29, 0xdb, 0xc9, 0xfe, 0x18, 0xe0, 0x25, 0xd9, 0x9a, 0xfd, 0x51,
-       0xe4, 0x95, 0x94, 0x12, 0x63, 0x56, 0x4d, 0xc6, 0xe6, 0x84, 0x02, 0x0b,
-       0x36, 0x56, 0x92, 0x9d, 0x14, 0x50, 0xc0, 0x24, 0x6d, 0x87, 0x2c, 0x6d,
-       0x11, 0x55, 0x76, 0xda, 0x7f, 0x8d, 0x2d, 0xc0, 0xb2, 0x2e, 0x69, 0x14,
-       0x3b, 0xc8, 0x02, 0x2c, 0x58, 0xbb, 0x6e, 0x28, 0xf6, 0x4f, 0xc7, 0x9d,
-       0xdf, 0xfd, 0x20, 0x1f, 0xc9, 0x47, 0x7d, 0x24, 0x6e, 0x81, 0x09, 0x10,
-       0xc8, 0xf7, 0xde, 0x7d, 0xef, 0xdd, 0x7b, 0xee, 0xf9, 0xf8, 0x9d, 0x73,
-       0xcf, 0xb9, 0x94, 0xba, 0xe2, 0x35, 0x57, 0x6e, 0x49, 0x65, 0x7e, 0x65,
-       0xce, 0x89, 0x9c, 0x0f, 0x95, 0x43, 0x0b, 0x9a, 0x3a, 0x27, 0x6d, 0x99,
-       0x17, 0x33, 0xb0, 0x80, 0x73, 0x3d, 0x35, 0xf6, 0xaf, 0x95, 0xf9, 0xc0,
-       0x14, 0x31, 0x85, 0x69, 0x13, 0x7d, 0xde, 0x2b, 0xf4, 0x81, 0xf7, 0xba,
-       0x7c, 0x40, 0xe9, 0xbc, 0x56, 0xa5, 0xa3, 0x36, 0xc2, 0x6f, 0xf2, 0x9d,
-       0xfd, 0xe2, 0x9d, 0xdd, 0x4a, 0x67, 0xe9, 0xdc, 0xf7, 0x71, 0x63, 0xba,
-       0x08, 0x5f, 0x9b, 0xe9, 0x52, 0x87, 0xdf, 0xac, 0x4d, 0xe8, 0xf8, 0xb9,
-       0x3a, 0x3a, 0x56, 0xcb, 0x03, 0xfb, 0xe6, 0x65, 0x9d, 0x2d, 0x69, 0x26,
-       0xcf, 0x23, 0x9f, 0x5f, 0xe7, 0x65, 0x48, 0x9a, 0x95, 0xe5, 0xe7, 0x92,
-       0x3b, 0x27, 0xa3, 0x42, 0xb3, 0xe9, 0x32, 0xcd, 0xf6, 0xfc, 0x3f, 0xa0,
-       0xd9, 0x4d, 0x81, 0x79, 0x5f, 0x29, 0x22, 0xff, 0x6e, 0x58, 0xe4, 0x2e,
-       0xac, 0xd2, 0x88, 0xb2, 0xff, 0xee, 0x1a, 0x28, 0xd0, 0x12, 0xba, 0x34,
-       0x52, 0x58, 0xa7, 0x98, 0x8c, 0x43, 0x98, 0xa5, 0xd2, 0x77, 0xa2, 0x90,
-       0x3f, 0xf8, 0x24, 0xf0, 0x51, 0x10, 0xdf, 0x3b, 0xc9, 0x63, 0xfb, 0x97,
-       0x60, 0xd7, 0x06, 0x36, 0xf2, 0xe4, 0x36, 0x7c, 0x94, 0x8a, 0x8d, 0x04,
-       0x5e, 0x22, 0x27, 0x6e, 0x57, 0xf2, 0x5e, 0x66, 0xb3, 0x3f, 0x6c, 0x67,
-       0x3f, 0x92, 0x69, 0x5c, 0x79, 0xee, 0xd6, 0x7c, 0x14, 0x3c, 0x4f, 0xda,
-       0xc9, 0xd9, 0x6c, 0xe5, 0xb9, 0x4e, 0xf9, 0xb9, 0x61, 0x0f, 0x5d, 0x65,
-       0xd1, 0xcc, 0xa5, 0x7d, 0x75, 0xf9, 0x6a, 0x95, 0xf1, 0x48, 0x5f, 0x45,
-       0x8f, 0xe7, 0xc9, 0x4d, 0xf1, 0xa5, 0xcc, 0x3b, 0xab, 0xe4, 0xf0, 0xd4,
-       0xfa, 0x29, 0xfb, 0x5d, 0xf1, 0x19, 0xd0, 0xf8, 0x0f, 0x69, 0x75, 0x12,
-       0x7a, 0xae, 0x96, 0xd6, 0xef, 0xff, 0x9a, 0x68, 0x1d, 0xe9, 0xf8, 0xf5,
-       0xd2, 0x7a, 0x7f, 0x5d, 0x2c, 0xbc, 0x32, 0x1e, 0x0a, 0x75, 0x6f, 0x0b,
-       0xcb, 0xd7, 0xd2, 0x7a, 0x7f, 0xc3, 0x78, 0x6a, 0xe3, 0x5c, 0xcc, 0xea,
-       0x78, 0x6a, 0xbf, 0xc1, 0x32, 0x92, 0x65, 0x79, 0x69, 0xa8, 0xe3, 0xff,
-       0xce, 0x15, 0x6f, 0x75, 0xeb, 0x79, 0xc8, 0x1a, 0xf9, 0x4e, 0x0e, 0xe9,
-       0x77, 0x42, 0xae, 0x22, 0x8e, 0x43, 0xf0, 0x9f, 0xf0, 0x5e, 0xe4, 0x62,
-       0xd5, 0xe1, 0x2e, 0x7e, 0x2f, 0xcb, 0xff, 0x0b, 0xcf, 0x0b, 0x9b, 0x25,
-       0x63, 0x12, 0x68, 0x1f, 0xf2, 0x9d, 0x11, 0x6d, 0x65, 0x8e, 0x96, 0x8a,
-       0x51, 0x28, 0x3f, 0xa0, 0x51, 0x6c, 0xa2, 0xde, 0xfe, 0x6d, 0xcf, 0x6f,
-       0xd0, 0xf1, 0x88, 0x83, 0x3c, 0x3f, 0xe1, 0x2a, 0xbf, 0x0b, 0xfa, 0xf4,
-       0x3c, 0x63, 0x84, 0xfe, 0x32, 0x3e, 0xa8, 0x9e, 0xa3, 0x59, 0xe1, 0xdf,
-       0x69, 0x5d, 0xba, 0x2a, 0x73, 0x6b, 0xc5, 0x79, 0xe0, 0xb5, 0xb2, 0x2e,
-       0xad, 0xc1, 0xc3, 0x07, 0x3d, 0xf8, 0xc3, 0xb3, 0x9e, 0x55, 0xcf, 0xa1,
-       0x85, 0x9c, 0xfa, 0x84, 0xe7, 0x1c, 0x96, 0xeb, 0xd2, 0x9c, 0x4a, 0x5b,
-       0x79, 0x7f, 0x42, 0x8c, 0x6b, 0xea, 0xde, 0x38, 0xea, 0xef, 0xca, 0x35,
-       0x51, 0xb5, 0x75, 0x60, 0xb0, 0x0b, 0x5a, 0x1e, 0x75, 0xcd, 0x39, 0x68,
-       0xd1, 0xe7, 0x51, 0x07, 0xe6, 0xb6, 0x2d, 0xb8, 0xaf, 0x96, 0x16, 0x15,
-       0xbb, 0x32, 0xa7, 0xec, 0xca, 0xa2, 0x4b, 0xaf, 0xd7, 0xe3, 0xf7, 0x2e,
-       0x0f, 0xfc, 0xee, 0x55, 0x0b, 0x86, 0x3e, 0x3d, 0xc5, 0x98, 0xe4, 0x33,
-       0xc0, 0x24, 0x26, 0x6a, 0xb1, 0x24, 0x2e, 0xc1, 0xf5, 0x1c, 0x63, 0x93,
-       0x30, 0xf3, 0xca, 0x6b, 0x74, 0x8e, 0x31, 0xf7, 0x35, 0xba, 0x4b, 0xf9,
-       0x69, 0x90, 0x5f, 0x9d, 0x47, 0x8b, 0x5a, 0x06, 0x1f, 0x39, 0x0f, 0x45,
-       0x86, 0x63, 0xf4, 0x1a, 0x9d, 0x15, 0xf9, 0x3e, 0x58, 0xff, 0x43, 0x9e,
-       0xc4, 0xdd, 0xe2, 0xfd, 0x32, 0xae, 0x71, 0x27, 0xf2, 0x02, 0xb7, 0x5e,
-       0x9f, 0xa0, 0xea, 0x05, 0xb9, 0x1d, 0xde, 0xb9, 0xac, 0x64, 0x4a, 0x9c,
-       0xe3, 0xfb, 0x9f, 0x32, 0xea, 0xef, 0x8f, 0x19, 0x89, 0x62, 0xc2, 0x88,
-       0x2f, 0xa1, 0xdd, 0x53, 0xc6, 0x44, 0x11, 0xbe, 0xa4, 0xe6, 0x91, 0x48,
-       0x14, 0xf2, 0xb6, 0x46, 0x9b, 0xaf, 0x53, 0x2c, 0x52, 0x4d, 0xad, 0xc8,
-       0x16, 0xfa, 0x7d, 0xac, 0xaa, 0xdf, 0x9a, 0xbe, 0xf8, 0x8e, 0xd8, 0xcf,
-       0xcb, 0x4c, 0x53, 0x8d, 0x71, 0x83, 0x88, 0xbd, 0x0f, 0x3b, 0xb4, 0x11,
-       0xc6, 0x8d, 0xd4, 0x61, 0xdc, 0xc5, 0x4d, 0xfb, 0xfd, 0x69, 0x65, 0x5c,
-       0xd6, 0x7c, 0xfb, 0x6d, 0x81, 0x65, 0xb9, 0xdf, 0x55, 0x38, 0xb7, 0x86,
-       0xa7, 0xd0, 0x46, 0xc7, 0xc8, 0x75, 0x4c, 0xac, 0x5d, 0xc5, 0x74, 0x75,
-       0x3e, 0x45, 0x50, 0xc5, 0xb4, 0x71, 0x1d, 0xbe, 0xd6, 0x2a, 0xf7, 0x0f,
-       0x7e, 0x17, 0xe2, 0x3f, 0x6e, 0xbf, 0xcb, 0x1d, 0xf3, 0xf5, 0xaa, 0x0d,
-       0xed, 0xf7, 0xa8, 0x0d, 0x75, 0xcb, 0x59, 0xc0, 0x25, 0x67, 0x61, 0x17,
-       0x86, 0xeb, 0x65, 0xff, 0xa5, 0x8d, 0xf5, 0x07, 0xfc, 0x97, 0x20, 0xf9,
-       0x2f, 0xbb, 0xfd, 0x97, 0xda, 0x3a, 0x7f, 0xc8, 0x1c, 0x70, 0x9a, 0xf4,
-       0x65, 0x12, 0xf9, 0xf2, 0x1e, 0x01, 0x3c, 0xe6, 0x4a, 0x1d, 0xe6, 0x52,
-       0x5d, 0xcd, 0xa8, 0x57, 0x7f, 0xfb, 0xea, 0xfa, 0x0b, 0x1b, 0x16, 0x6b,
-       0x88, 0xef, 0xbc, 0xfc, 0xab, 0x3b, 0xd5, 0xbf, 0x5a, 0x5d, 0x86, 0x77,
-       0xf5, 0x8b, 0x18, 0xb8, 0x53, 0xd6, 0x63, 0x63, 0xb2, 0xbf, 0xd9, 0x6a,
-       0x5f, 0xc3, 0x7f, 0x89, 0x14, 0xed, 0xbc, 0xf5, 0xfa, 0xf6, 0xe2, 0x68,
-       0x3b, 0x6b, 0x6c, 0xef, 0x78, 0xa7, 0x8c, 0x8f, 0xcd, 0xa9, 0x3c, 0xf2,
-       0x6e, 0xe5, 0xf7, 0x6d, 0xc6, 0xeb, 0x38, 0x37, 0xa7, 0x62, 0x8a, 0x11,
-       0xab, 0x40, 0xe0, 0xf1, 0xc9, 0xd3, 0x4d, 0xb6, 0xa9, 0xd6, 0xb8, 0xb0,
-       0x8e, 0x05, 0x9e, 0xd7, 0xcf, 0x97, 0x35, 0x65, 0x9b, 0xcf, 0x99, 0x55,
-       0x37, 0x67, 0x92, 0xaf, 0xe0, 0x6f, 0x21, 0x3f, 0x7a, 0xa4, 0x26, 0x47,
-       0xfd, 0xd3, 0xd0, 0xa2, 0xdd, 0x23, 0x6f, 0x1b, 0x79, 0xd7, 0x8d, 0xfa,
-       0xb9, 0xee, 0xc2, 0xea, 0xb2, 0x6e, 0x63, 0x95, 0xd0, 0xef, 0x52, 0xe9,
-       0xe5, 0x28, 0xb0, 0x69, 0x6f, 0x1d, 0xaf, 0x69, 0xbc, 0x64, 0xba, 0xfa,
-       0xf9, 0xf8, 0xc6, 0xfd, 0xac, 0xb1, 0xbf, 0x7b, 0x3d, 0xec, 0x6f, 0x23,
-       0x5f, 0x42, 0xec, 0x9d, 0xe2, 0x3b, 0x2a, 0x74, 0x41, 0x1b, 0x2d, 0xe5,
-       0x91, 0x4b, 0xfe, 0x1b, 0xa8, 0x67, 0x65, 0x7d, 0xeb, 0xaa, 0xcf, 0xf3,
-       0x9e, 0xd3, 0xf2, 0x7a, 0x4b, 0x60, 0x1c, 0xeb, 0x83, 0xc8, 0x41, 0xe9,
-       0x62, 0x1d, 0x84, 0xf6, 0x83, 0xd6, 0x0d, 0xc4, 0x80, 0x55, 0x3c, 0x2a,
-       0xa1, 0xec, 0xcc, 0xd1, 0x2d, 0xac, 0xbb, 0x6c, 0x4f, 0x5f, 0x47, 0xac,
-       0x55, 0xc2, 0x9a, 0x10, 0xf2, 0x9e, 0x9d, 0x76, 0x6a, 0xbf, 0xbf, 0xa5,
-       0xc5, 0xbe, 0xd9, 0x29, 0xd7, 0xaa, 0x70, 0xad, 0x8d, 0xae, 0xe6, 0x91,
-       0x97, 0x8e, 0x6b, 0x0f, 0xf2, 0x35, 0x2f, 0x7d, 0xf5, 0xb6, 0xe2, 0x25,
-       0x60, 0x3a, 0x39, 0x47, 0x05, 0x92, 0x73, 0xb6, 0x4e, 0xf0, 0xa5, 0x4a,
-       0xf4, 0x4f, 0xd1, 0xdf, 0x14, 0xfe, 0x5f, 0x65, 0xae, 0xb6, 0xb7, 0x8e,
-       0x53, 0x9b, 0x03, 0x31, 0xb9, 0x61, 0x1c, 0xb1, 0xa3, 0x6b, 0xab, 0xeb,
-       0x38, 0xb5, 0x39, 0x10, 0x8f, 0x6f, 0x29, 0x8e, 0x18, 0xb1, 0xa6, 0x37,
-       0xac, 0x33, 0x70, 0xaf, 0xa9, 0xe8, 0xb5, 0xe4, 0x51, 0x51, 0x7b, 0xeb,
-       0xe6, 0x89, 0x3b, 0xb3, 0x9e, 0x0c, 0xde, 0xe8, 0xab, 0xd3, 0x61, 0x77,
-       0x60, 0x3d, 0xa0, 0x86, 0xb6, 0x41, 0xcf, 0x58, 0x96, 0xf7, 0xba, 0x31,
-       0x72, 0x04, 0x10, 0xc3, 0x2e, 0xd2, 0x99, 0x2b, 0xe0, 0x67, 0x83, 0x39,
-       0x6f, 0x80, 0x32, 0x21, 0xd4, 0x52, 0x89, 0xba, 0x28, 0xbd, 0xbe, 0x28,
-       0xea, 0xa3, 0xce, 0x88, 0xba, 0xcf, 0xc1, 0xf0, 0x6d, 0xb6, 0x91, 0x67,
-       0x8a, 0x6f, 0xd1, 0xd9, 0xa5, 0x20, 0xff, 0x57, 0xf0, 0x7c, 0x7d, 0xed,
-       0x67, 0x35, 0xbf, 0xdf, 0x16, 0xfc, 0xde, 0xbb, 0x21, 0xbf, 0x1f, 0x2f,
-       0xf3, 0x3b, 0x77, 0x28, 0x28, 0x6b, 0x2b, 0x53, 0x57, 0xda, 0xe9, 0xa8,
-       0x78, 0xee, 0x5b, 0xfc, 0x7d, 0x27, 0x1d, 0x35, 0xe5, 0xf7, 0xb3, 0x4b,
-       0xac, 0xfb, 0xb3, 0x6f, 0xd1, 0xb9, 0x2b, 0x8e, 0x2f, 0x21, 0xea, 0x32,
-       0xdc, 0x7b, 0x86, 0xe8, 0xfb, 0xd1, 0xce, 0x4b, 0x16, 0xea, 0xf5, 0x55,
-       0x41, 0xea, 0x2b, 0xba, 0x29, 0x62, 0x20, 0xde, 0xfa, 0x0a, 0xfc, 0x79,
-       0x5e, 0xd9, 0xc6, 0xc9, 0x0d, 0x62, 0x1f, 0xf5, 0xbc, 0xd9, 0xe9, 0x81,
-       0x91, 0xbf, 0xdb, 0x25, 0xd7, 0xb1, 0x36, 0x8a, 0x81, 0x54, 0xe5, 0x81,
-       0xb8, 0xd7, 0xf9, 0xd9, 0x1e, 0x4c, 0xaa, 0x75, 0xf7, 0x9f, 0x76, 0x49,
-       0x3b, 0x82, 0x9a, 0xc8, 0x55, 0xa6, 0xc3, 0x3f, 0x30, 0x7e, 0xd9, 0x4f,
-       0xcd, 0x97, 0xf5, 0x58, 0xf7, 0x0b, 0x7f, 0xc8, 0x1d, 0xcb, 0x99, 0x55,
-       0x35, 0xee, 0x69, 0xd7, 0x98, 0x66, 0x85, 0xdf, 0xf3, 0x49, 0xd6, 0x31,
-       0x7b, 0x6b, 0x6c, 0x45, 0x2d, 0xbf, 0x61, 0x3f, 0x16, 0xcc, 0x2f, 0x19,
-       0x12, 0x1b, 0x8f, 0x31, 0xe6, 0xdd, 0xee, 0x7a, 0xd2, 0xa7, 0xc5, 0x8d,
-       0xb5, 0x7b, 0x7d, 0xd4, 0x7e, 0xc7, 0x3c, 0x48, 0x3f, 0x24, 0xf5, 0x42,
-       0x51, 0xe8, 0x82, 0xd9, 0x91, 0x12, 0x4d, 0x44, 0x77, 0x51, 0x6a, 0x84,
-       0xdf, 0x3d, 0x66, 0xb3, 0x3f, 0xe6, 0x27, 0x87, 0xe5, 0x37, 0x35, 0xb2,
-       0x43, 0xd5, 0xcc, 0xe9, 0x58, 0x7b, 0x8b, 0xc2, 0x90, 0xed, 0x62, 0xdd,
-       0x52, 0xee, 0x49, 0xc4, 0xdf, 0x97, 0xf4, 0xb3, 0x71, 0x1e, 0xbc, 0xdb,
-       0xac, 0xda, 0x5d, 0x74, 0xb5, 0x43, 0x9b, 0x8b, 0xaa, 0x2d, 0x9e, 0xa9,
-       0xb1, 0x86, 0xae, 0xd3, 0x82, 0x1c, 0xae, 0xaa, 0xfa, 0x44, 0xf9, 0xbc,
-       0x99, 0xe2, 0x45, 0x6e, 0xd3, 0xa5, 0xae, 0x5f, 0x64, 0xfc, 0x5b, 0x14,
-       0x32, 0x22, 0xfb, 0xd2, 0x54, 0xee, 0x8b, 0xc4, 0xed, 0xb8, 0xa7, 0x5d,
-       0xe5, 0x62, 0xbe, 0x25, 0xd7, 0x05, 0x54, 0x1f, 0xe4, 0x75, 0xfe, 0x5c,
-       0xaa, 0xf6, 0x29, 0xdf, 0x28, 0xea, 0x75, 0x88, 0x8f, 0x7d, 0x33, 0xd9,
-       0x77, 0x7c, 0x32, 0xe7, 0xd8, 0x14, 0x6b, 0xa9, 0x32, 0x7f, 0x43, 0x7f,
-       0x47, 0xac, 0x19, 0x39, 0x16, 0xc8, 0x9f, 0x70, 0xeb, 0x16, 0x39, 0xb6,
-       0x00, 0x6c, 0x50, 0x11, 0x6b, 0xa8, 0x1b, 0xe1, 0xe7, 0xbd, 0xcc, 0x9b,
-       0xe6, 0x36, 0x70, 0xe8, 0x56, 0x64, 0xcd, 0xf2, 0x90, 0x35, 0xf7, 0xfb,
-       0x51, 0xcb, 0x87, 0x9a, 0x3e, 0x67, 0xd8, 0xa0, 0x12, 0xfb, 0x0a, 0x06,
-       0x15, 0x4c, 0x1f, 0x9d, 0xb3, 0x23, 0xd1, 0x25, 0x81, 0x37, 0xef, 0x43,
-       0xce, 0xcf, 0xf0, 0x2a, 0x1d, 0x36, 0xcf, 0x92, 0xdc, 0xef, 0xa1, 0xc0,
-       0xb6, 0x77, 0x9a, 0xf9, 0xed, 0x2c, 0xfb, 0x1f, 0xce, 0x14, 0xd6, 0x5d,
-       0x34, 0xcd, 0xb0, 0x0f, 0x00, 0x3e, 0x2d, 0x9e, 0xa7, 0xe2, 0x6e, 0x0a,
-       0xc6, 0xf8, 0x99, 0x16, 0x74, 0x11, 0x3f, 0x27, 0x49, 0x71, 0xf6, 0x93,
-       0xe0, 0xb3, 0x4e, 0x4f, 0x45, 0xcc, 0x02, 0x19, 0xdc, 0x16, 0xbe, 0x2b,
-       0x9e, 0x83, 0xfb, 0x63, 0x66, 0x13, 0xd5, 0xd6, 0x1c, 0xb7, 0x8b, 0x3a,
-       0xcc, 0x9b, 0xd1, 0x7b, 0xc8, 0xe8, 0x81, 0x6e, 0xc2, 0x9c, 0xdd, 0xad,
-       0xd6, 0x8b, 0x3a, 0xf8, 0xfb, 0x90, 0xfa, 0x2e, 0xe7, 0x5a, 0x7e, 0xd7,
-       0xbc, 0x8c, 0xbf, 0x0f, 0x5b, 0xc8, 0xfe, 0x5d, 0x35, 0x7f, 0xd5, 0xeb,
-       0x66, 0xfd, 0x46, 0x90, 0xce, 0x7b, 0xae, 0x9b, 0x6d, 0x54, 0xcb, 0xdb,
-       0xb1, 0xc5, 0x5a, 0xde, 0x9f, 0xef, 0x96, 0xf5, 0x71, 0xee, 0xbe, 0xfc,
-       0x9c, 0xfb, 0xe2, 0x15, 0x0f, 0x71, 0xeb, 0x5e, 0xad, 0x73, 0x4b, 0xf4,
-       0x6f, 0xd1, 0xcf, 0xd2, 0x7a, 0x28, 0xac, 0xf2, 0x99, 0x90, 0xbf, 0x74,
-       0x8f, 0xe2, 0x55, 0xad, 0xe7, 0xc9, 0x43, 0xcf, 0x3f, 0x20, 0xf2, 0x8e,
-       0xa5, 0x9d, 0xd8, 0xaf, 0xe8, 0x01, 0x9a, 0x85, 0x5d, 0x34, 0xeb, 0x76,
-       0xd1, 0xcc, 0x50, 0xdf, 0x77, 0x89, 0xe3, 0xf3, 0x4b, 0xaf, 0x76, 0xc8,
-       0x7a, 0x78, 0xac, 0x29, 0x7e, 0x5f, 0x7d, 0xdf, 0x6c, 0xbc, 0x0f, 0x84,
-       0x28, 0x28, 0xe2, 0x4d, 0xae, 0xb1, 0xbe, 0x44, 0x64, 0xb3, 0x37, 0x5c,
-       0x47, 0x83, 0x6f, 0xb9, 0xce, 0xa3, 0x8f, 0x83, 0xae, 0x3e, 0xf6, 0xbb,
-       0xfa, 0x78, 0xb0, 0x41, 0x1f, 0x59, 0x9f, 0xf3, 0x7b, 0xce, 0x16, 0x3f,
-       0x69, 0x5f, 0xd1, 0x4f, 0xd4, 0x49, 0x83, 0x9e, 0x3b, 0x29, 0x1d, 0x0a,
-       0x2b, 0x3b, 0x11, 0x55, 0xf5, 0x03, 0x5e, 0x7d, 0xfe, 0x31, 0x35, 0x9e,
-       0x37, 0x37, 0xaf, 0xba, 0xeb, 0xab, 0x9f, 0xa3, 0x09, 0x59, 0x27, 0xaf,
-       0x64, 0xfb, 0x62, 0x83, 0x78, 0x34, 0x72, 0x3b, 0x80, 0x37, 0x84, 0x6f,
-       0xb8, 0x4f, 0xee, 0x6f, 0x17, 0xa0, 0xe5, 0x72, 0xad, 0xb2, 0x5f, 0xd5,
-       0xf0, 0x3d, 0x1b, 0xba, 0xb3, 0x75, 0xca, 0x38, 0xff, 0x3d, 0x11, 0xcb,
-       0x93, 0xeb, 0x48, 0xab, 0xaa, 0xde, 0x3a, 0x62, 0x21, 0x47, 0x60, 0x71,
-       0x05, 0x71, 0xd8, 0x46, 0xb5, 0xc9, 0x52, 0x17, 0xa5, 0xca, 0x7b, 0xc2,
-       0x14, 0x44, 0x1d, 0x86, 0x8c, 0x8f, 0xc9, 0x1a, 0xe2, 0xc5, 0x95, 0x1b,
-       0xa2, 0x6e, 0x37, 0xae, 0x6a, 0x91, 0x53, 0xd4, 0x26, 0x70, 0xed, 0x27,
-       0xaf, 0x21, 0xfe, 0x71, 0x68, 0xfb, 0x35, 0xc4, 0xee, 0x7b, 0xb6, 0x57,
-       0x43, 0x6c, 0xf2, 0xd8, 0x8d, 0x05, 0x59, 0x43, 0x5c, 0xbd, 0x46, 0x23,
-       0x6b, 0x88, 0x53, 0x2e, 0xac, 0x20, 0xf1, 0xf9, 0x4d, 0x57, 0x7e, 0xb7,
-       0xac, 0x0f, 0x5e, 0x2c, 0xe3, 0x53, 0x59, 0x1f, 0x2c, 0xf3, 0xc1, 0xdd,
-       0x7b, 0xdf, 0xc8, 0xb5, 0x20, 0xf9, 0x9e, 0x5d, 0x35, 0x6b, 0x41, 0xb2,
-       0x2e, 0xd8, 0x32, 0xbc, 0xf8, 0x4e, 0xdb, 0x25, 0xec, 0xf7, 0x10, 0x63,
-       0xde, 0xdd, 0xd9, 0x60, 0xbf, 0x87, 0x58, 0x83, 0xfd, 0x1e, 0xdc, 0xba,
-       0xdf, 0x8d, 0xa7, 0x80, 0x7f, 0x61, 0x17, 0x81, 0x7b, 0xb1, 0x5f, 0x43,
-       0x94, 0xce, 0x97, 0x71, 0xe6, 0x3d, 0x94, 0x54, 0x38, 0xf3, 0xfc, 0x92,
-       0xd6, 0x47, 0xfd, 0x35, 0xfa, 0xc8, 0x0b, 0x77, 0x46, 0x54, 0xce, 0x8f,
-       0x96, 0x57, 0xc7, 0x25, 0xaf, 0x8e, 0x87, 0xbc, 0xe2, 0x1e, 0xa7, 0x41,
-       0xbf, 0x41, 0x13, 0xdc, 0x83, 0xff, 0x97, 0xc2, 0xd8, 0xa7, 0x86, 0xe8,
-       0x0b, 0xdd, 0x0a, 0xeb, 0xb9, 0xe4, 0xf5, 0x2c, 0xcb, 0xab, 0x3e, 0x8f,
-       0xfe, 0x36, 0xc2, 0xfb, 0x1a, 0x1f, 0xee, 0xf7, 0x1d, 0xbb, 0xf2, 0x0b,
-       0x91, 0x17, 0x50, 0xed, 0x27, 0x6a, 0x0c, 0x71, 0x48, 0xc8, 0xd2, 0xba,
-       0x1f, 0xf9, 0x2b, 0xfa, 0x1c, 0x6a, 0xa7, 0x20, 0x7f, 0x9a, 0x16, 0xcd,
-       0x35, 0x38, 0xa3, 0x5d, 0xe1, 0x08, 0x91, 0xff, 0xeb, 0xea, 0xdb, 0x7f,
-       0x72, 0xdf, 0xf4, 0x79, 0x6d, 0x33, 0xdf, 0xae, 0x8a, 0x69, 0x54, 0xe7,
-       0x4d, 0x22, 0x7e, 0xb4, 0x2b, 0x69, 0xd8, 0x09, 0x91, 0x7f, 0xda, 0x69,
-       0x23, 0x56, 0x16, 0x67, 0xd9, 0xef, 0x4c, 0x22, 0xd7, 0xb9, 0xf3, 0x92,
-       0x45, 0xa7, 0xb2, 0x57, 0x0f, 0x48, 0x5e, 0x79, 0x5a, 0xec, 0xd3, 0x89,
-       0x7d, 0x1d, 0x27, 0xd8, 0x3e, 0xc7, 0x19, 0x60, 0xce, 0x15, 0x5b, 0x68,
-       0x91, 0x91, 0xbc, 0xdf, 0x2e, 0x88, 0x58, 0x1f, 0xeb, 0xa4, 0x1c, 0xf6,
-       0x6b, 0x35, 0x16, 0x9a, 0xf9, 0xb9, 0x3d, 0xb4, 0x9c, 0x07, 0xcf, 0x35,
-       0xa9, 0xfd, 0x53, 0xd0, 0xd6, 0x47, 0x5d, 0xf6, 0xdf, 0x32, 0xed, 0x1e,
-       0x11, 0x79, 0x97, 0x8b, 0xb9, 0xa7, 0xe5, 0x67, 0xe1, 0x55, 0xf5, 0x0e,
-       0x7e, 0x5f, 0xf1, 0x75, 0x8a, 0x75, 0xb9, 0xf3, 0x00, 0xdd, 0x7f, 0xde,
-       0x78, 0xe5, 0xe4, 0xb6, 0xf0, 0x8a, 0x93, 0xac, 0xe0, 0x15, 0xf7, 0xb3,
-       0x35, 0x76, 0xf9, 0xe3, 0x1e, 0xb9, 0x9f, 0x05, 0x68, 0xb0, 0x13, 0x58,
-       0x2c, 0x09, 0x5a, 0x1a, 0xe3, 0x91, 0x70, 0xdc, 0x3f, 0x46, 0x99, 0xe2,
-       0x35, 0x4a, 0xe5, 0x60, 0xe7, 0xf9, 0xb3, 0xf0, 0x37, 0x7b, 0x64, 0x9c,
-       0x46, 0xdf, 0x03, 0xbd, 0xb2, 0x9b, 0xdb, 0x37, 0xef, 0x91, 0x39, 0xdb,
-       0xee, 0xf3, 0xed, 0x7c, 0xfe, 0xc9, 0x70, 0xf5, 0xf9, 0x1d, 0x7c, 0xbe,
-       0x2b, 0x89, 0x39, 0x34, 0x2e, 0x21, 0x36, 0x39, 0x4c, 0x69, 0x9e, 0x9f,
-       0x4c, 0x91, 0x6d, 0xeb, 0x65, 0xd6, 0x57, 0x4b, 0xba, 0x5d, 0x37, 0xb7,
-       0x0b, 0x89, 0x39, 0x31, 0xb8, 0xcd, 0x6c, 0x76, 0x84, 0xdb, 0xed, 0x27,
-       0xff, 0x65, 0x8b, 0x32, 0x4b, 0x9a, 0x57, 0x75, 0x2e, 0xfe, 0x2f, 0xba,
-       0x65, 0x6e, 0xd5, 0xae, 0xb0, 0xa4, 0xdf, 0xb0, 0x88, 0x7b, 0x22, 0xb7,
-       0xe3, 0x19, 0xc1, 0x87, 0x91, 0x31, 0xab, 0xfc, 0x7e, 0xec, 0x31, 0x26,
-       0xf6, 0x7c, 0xe5, 0x31, 0xb0, 0x5e, 0x1c, 0xb7, 0xcd, 0x74, 0x39, 0x6f,
-       0x6d, 0x6d, 0x9f, 0xbc, 0x7f, 0x67, 0x8f, 0xdc, 0x7f, 0xb5, 0x53, 0xed,
-       0x15, 0xa8, 0x6d, 0xce, 0x17, 0x90, 0xa7, 0x2d, 0x68, 0xe3, 0x5f, 0x80,
-       0xbe, 0x34, 0xf8, 0x3b, 0x8f, 0x27, 0x89, 0x3e, 0xf6, 0xf6, 0xe8, 0x3d,
-       0x17, 0xe5, 0xb8, 0x4e, 0x70, 0x7f, 0x13, 0x3c, 0x2e, 0x7d, 0x3e, 0xc6,
-       0xc7, 0x5e, 0xf3, 0x8b, 0x67, 0x05, 0xf9, 0x39, 0x2c, 0x03, 0x53, 0xc1,
-       0x64, 0x6a, 0x58, 0xce, 0x73, 0x25, 0xae, 0x1b, 0x2e, 0xc7, 0x75, 0xe7,
-       0xb2, 0xc7, 0x7b, 0x10, 0xcf, 0x30, 0x2e, 0xf1, 0x7c, 0x87, 0x9e, 0xe1,
-       0xb6, 0xa8, 0x63, 0x48, 0xf3, 0x67, 0x9b, 0xca, 0xef, 0xa9, 0xe7, 0x15,
-       0x99, 0x2f, 0xa1, 0xed, 0x16, 0xee, 0xbd, 0x97, 0x9f, 0x21, 0x6d, 0x57,
-       0xe3, 0xf7, 0x50, 0x5d, 0x4e, 0x4c, 0x3d, 0x8f, 0x6d, 0x14, 0x8b, 0x15,
-       0xeb, 0x8a, 0x1e, 0x7c, 0xb6, 0x51, 0xac, 0x44, 0xe4, 0x39, 0xfb, 0x26,
-       0xea, 0xe4, 0x15, 0x72, 0x1c, 0xa0, 0x27, 0xe6, 0x1d, 0xda, 0xc1, 0x73,
-       0xf5, 0x27, 0x06, 0xea, 0x86, 0x4b, 0x24, 0x73, 0x9f, 0x98, 0xc6, 0x59,
-       0x7b, 0xf8, 0xac, 0xc1, 0x74, 0xce, 0x3a, 0xa5, 0x80, 0xdd, 0x46, 0xcd,
-       0x2c, 0xab, 0xbf, 0x4f, 0x03, 0xec, 0xeb, 0x41, 0x66, 0xed, 0x70, 0x82,
-       0x20, 0x6f, 0x11, 0xf3, 0x18, 0xf3, 0xc4, 0x44, 0x11, 0xfc, 0x6c, 0xd0,
-       0x63, 0x79, 0xa2, 0x47, 0xf3, 0x03, 0xe6, 0x37, 0xc9, 0xb6, 0x2a, 0xd7,
-       0x23, 0x66, 0x9c, 0xfb, 0x91, 0x28, 0xfe, 0x25, 0x7d, 0x24, 0xf6, 0x71,
-       0x01, 0x1d, 0xf5, 0xbc, 0xff, 0x39, 0x4d, 0x27, 0xd1, 0xef, 0xad, 0xcb,
-       0xe7, 0xa9, 0x6d, 0xc9, 0x67, 0xd0, 0x43, 0x3e, 0x3f, 0x54, 0x7c, 0x53,
-       0x62, 0x1e, 0x0d, 0xd2, 0x4c, 0x0e, 0xb9, 0x60, 0x9f, 0x47, 0x0d, 0x66,
-       0x2e, 0xc5, 0x7a, 0x29, 0x55, 0xd1, 0x4b, 0x17, 0xe2, 0xfe, 0x18, 0x64,
-       0x1c, 0x7b, 0xd1, 0xa9, 0x1c, 0x20, 0x8c, 0x63, 0x1f, 0x0d, 0x2c, 0xec,
-       0xe4, 0x7b, 0x69, 0x35, 0x3e, 0x1a, 0x53, 0x7b, 0x15, 0x44, 0xac, 0x09,
-       0xd6, 0x8f, 0x73, 0x2c, 0xcb, 0xe9, 0xdc, 0xdd, 0xb4, 0x18, 0xea, 0xa5,
-       0xfe, 0x05, 0xbd, 0x7f, 0x0b, 0xc6, 0x3a, 0xd4, 0x2b, 0x75, 0x92, 0x1e,
-       0xf7, 0x6f, 0x89, 0x38, 0x85, 0x75, 0xed, 0x57, 0x35, 0xee, 0x9d, 0x9b,
-       0xe8, 0xa5, 0x92, 0x92, 0xd9, 0xd2, 0x1b, 0xf1, 0x28, 0x39, 0xf1, 0xd1,
-       0xff, 0x15, 0xfc, 0xdf, 0x7f, 0x0d, 0xb5, 0x38, 0xd0, 0xd1, 0x16, 0x25,
-       0xb3, 0xb5, 0xb4, 0xe8, 0xe5, 0x71, 0xe3, 0x7a, 0xe9, 0xa7, 0x33, 0xd1,
-       0x57, 0x85, 0xed, 0x1f, 0xb8, 0xc6, 0xed, 0x84, 0x6d, 0xd2, 0x7a, 0xc3,
-       0x8b, 0x0f, 0xf5, 0xde, 0x9c, 0x9a, 0x17, 0x65, 0xce, 0x27, 0xe3, 0x37,
-       0x33, 0xe9, 0xaf, 0xe5, 0xc9, 0x8f, 0xe9, 0xe4, 0xbc, 0x45, 0x93, 0x59,
-       0xec, 0x81, 0x38, 0xc6, 0x72, 0xed, 0xb6, 0x17, 0xdc, 0x9e, 0xc0, 0x67,
-       0xe3, 0x2c, 0xfb, 0xec, 0xb7, 0xe7, 0x2c, 0x99, 0x7f, 0x27, 0xf6, 0xdb,
-       0x6b, 0x11, 0x7a, 0xd4, 0xb4, 0xfb, 0xf7, 0x68, 0x7b, 0x90, 0xca, 0xa1,
-       0xce, 0x90, 0x3f, 0x0b, 0xdc, 0x3e, 0xdb, 0x43, 0xa9, 0x3c, 0x9e, 0x03,
-       0x7b, 0x87, 0xbe, 0xf3, 0xf1, 0xb2, 0x9c, 0xd7, 0x7e, 0x7e, 0x36, 0xf6,
-       0x0e, 0x98, 0x2c, 0x8e, 0x88, 0x1c, 0x3c, 0xe8, 0x66, 0x39, 0x9f, 0xe3,
-       0x34, 0xeb, 0xa9, 0x57, 0x14, 0xa6, 0x74, 0xc9, 0x77, 0x4a, 0xc8, 0xf7,
-       0xb8, 0x98, 0x8f, 0x54, 0xde, 0x60, 0xbc, 0xa6, 0xe3, 0x0c, 0x5d, 0x7c,
-       0x1c, 0x50, 0x3a, 0x04, 0xd7, 0xee, 0xdd, 0x23, 0xf2, 0x13, 0x6d, 0x9c,
-       0xc7, 0xe7, 0x38, 0x3d, 0xc3, 0xb8, 0xf3, 0xd9, 0x6c, 0x0b, 0xdd, 0xc8,
-       0xb5, 0xd0, 0x9b, 0xb9, 0x5e, 0xba, 0x3e, 0xdf, 0x41, 0xb3, 0x8c, 0x99,
-       0x67, 0xed, 0x80, 0x95, 0x66, 0xff, 0xe2, 0x6a, 0x54, 0xe4, 0x10, 0xb1,
-       0xdc, 0xa1, 0x3d, 0xf0, 0x5f, 0x7c, 0x2f, 0xf3, 0x1c, 0x63, 0xef, 0x56,
-       0xfa, 0x80, 0xdf, 0x99, 0xce, 0xea, 0x9c, 0x07, 0xc4, 0xe3, 0x07, 0xcb,
-       0xf8, 0x75, 0x73, 0x1e, 0x31, 0x37, 0xe1, 0x91, 0x71, 0xa1, 0xeb, 0x33,
-       0xf3, 0x7c, 0x7d, 0x1e, 0x71, 0x73, 0x4b, 0xc4, 0x24, 0xbe, 0x14, 0x40,
-       0x7b, 0x9c, 0xb3, 0x65, 0xce, 0xa4, 0x18, 0x5b, 0x98, 0x8f, 0x41, 0xdb,
-       0xb0, 0xa2, 0x43, 0x2b, 0x8f, 0x4f, 0xc6, 0x30, 0x52, 0xcb, 0xad, 0x74,
-       0x26, 0xcf, 0x18, 0x24, 0xef, 0x67, 0x1f, 0x06, 0x6d, 0x7f, 0xe7, 0xa0,
-       0xde, 0xd3, 0x76, 0x96, 0xfb, 0x9e, 0xce, 0x4b, 0x0c, 0x92, 0x5e, 0x6e,
-       0xa7, 0x4c, 0xbe, 0x4d, 0x1d, 0xdf, 0x2d, 0xf2, 0xdd, 0xe5, 0xde, 0x12,
-       0xb8, 0xb6, 0x91, 0x7e, 0x43, 0xae, 0x11, 0x6c, 0xaa, 0xf4, 0x4b, 0xa1,
-       0x6b, 0xbc, 0xf3, 0x8c, 0xc6, 0xe8, 0x39, 0xb6, 0xb7, 0xfd, 0x97, 0x11,
-       0x2b, 0xfe, 0x22, 0xf8, 0xa6, 0x00, 0x1e, 0xeb, 0xbf, 0x8c, 0x7d, 0x9f,
-       0xfc, 0x22, 0xf7, 0x68, 0x22, 0x34, 0x2c, 0x6a, 0x46, 0xa4, 0x8c, 0x4e,
-       0x89, 0xba, 0xec, 0xef, 0x08, 0xdd, 0x14, 0x71, 0x2c, 0x03, 0x78, 0x24,
-       0x12, 0x26, 0x92, 0x39, 0x59, 0xa7, 0xec, 0xce, 0x9b, 0xdd, 0xe3, 0x43,
-       0x14, 0xeb, 0x01, 0xdf, 0x4b, 0x99, 0x95, 0x7b, 0x22, 0x90, 0xd0, 0xf7,
-       0xe6, 0x21, 0x5d, 0x63, 0xa0, 0x8f, 0xb5, 0xad, 0xd0, 0xc7, 0x6d, 0x35,
-       0xd7, 0xcd, 0x9a, 0xeb, 0x1a, 0x7f, 0x63, 0xad, 0x8c, 0xed, 0x3c, 0xc9,
-       0x3d, 0x98, 0x52, 0x0b, 0x92, 0xff, 0xcc, 0x43, 0x83, 0xe6, 0xfd, 0x0a,
-       0x83, 0xa7, 0x56, 0x06, 0xc2, 0x9d, 0x46, 0x9b, 0x3f, 0x35, 0xf2, 0xaf,
-       0xa5, 0x58, 0x12, 0xb8, 0xe8, 0xf5, 0x3d, 0x52, 0xc7, 0xa1, 0x5f, 0x4e,
-       0x14, 0xd0, 0x6d, 0x6a, 0xa5, 0x8d, 0x56, 0xc5, 0x9e, 0x63, 0xc0, 0x18,
-       0xb8, 0x1f, 0xcf, 0x71, 0xcc, 0x26, 0xc2, 0x3e, 0xf2, 0x90, 0xf1, 0xc3,
-       0xe1, 0x6b, 0x3c, 0x9f, 0x89, 0x95, 0xff, 0x29, 0x4d, 0x8b, 0x7d, 0x7a,
-       0xd0, 0x96, 0x31, 0xa4, 0xc0, 0xfc, 0x8c, 0x5f, 0xaa, 0xfc, 0xaa, 0x31,
-       0xf4, 0xd3, 0xc1, 0x9a, 0x8a, 0x61, 0xbf, 0xc0, 0x32, 0x26, 0xd7, 0xca,
-       0x13, 0x35, 0x6b, 0xe5, 0x53, 0x62, 0xad, 0x1c, 0xeb, 0xe4, 0x1b, 0xe5,
-       0x2d, 0xea, 0x3c, 0x16, 0x8b, 0x66, 0xaf, 0x08, 0x7d, 0x13, 0x9d, 0xf0,
-       0xcb, 0x3c, 0xeb, 0x04, 0xbb, 0x37, 0x86, 0xa8, 0x6d, 0xc0, 0x67, 0xcc,
-       0x88, 0xdb, 0x91, 0xe1, 0x35, 0xc6, 0x14, 0x4b, 0xb9, 0x1d, 0x74, 0xbd,
-       0xd0, 0xc4, 0x98, 0xef, 0x9f, 0x69, 0xad, 0x40, 0x8c, 0x0d, 0x3b, 0x28,
-       0x13, 0x65, 0x5e, 0x1b, 0x0e, 0xf2, 0xbc, 0x32, 0xbe, 0x1d, 0x66, 0xf9,
-       0xe3, 0x31, 0x2c, 0xe5, 0x4b, 0xef, 0xa7, 0xa3, 0x31, 0x2b, 0x3e, 0xda,
-       0xc6, 0xfe, 0x8b, 0xc9, 0xff, 0x36, 0xff, 0x9f, 0x0b, 0x83, 0x36, 0x8b,
-       0xcb, 0xb8, 0xce, 0xd8, 0x27, 0x5b, 0x7a, 0x7f, 0x86, 0xdb, 0xcc, 0x8c,
-       0xc2, 0x0f, 0x82, 0xbf, 0x67, 0xf3, 0xbf, 0x6c, 0xb3, 0xc4, 0x7c, 0x97,
-       0xbe, 0xe2, 0x84, 0x0d, 0xa1, 0xe3, 0xb1, 0x2f, 0xcd, 0x80, 0xfa, 0x8c,
-       0x19, 0x33, 0xdc, 0x97, 0xeb, 0x84, 0x67, 0x58, 0x94, 0x8a, 0x1e, 0x62,
-       0x39, 0xe8, 0xe0, 0x4f, 0xd4, 0x6a, 0xed, 0xa4, 0xcc, 0xc8, 0xa0, 0xaa,
-       0xd5, 0xfa, 0x59, 0x83, 0x5a, 0x2d, 0xdc, 0xc7, 0x38, 0x60, 0xbe, 0x74,
-       0x7b, 0x26, 0xea, 0x7e, 0x2f, 0x19, 0xa9, 0xe8, 0x2e, 0x81, 0x99, 0x96,
-       0x96, 0x1f, 0xe6, 0x3e, 0xc4, 0xac, 0xd4, 0x28, 0xf7, 0x35, 0xef, 0xee,
-       0x7f, 0xe9, 0xf6, 0x44, 0x14, 0xed, 0xfc, 0x35, 0xed, 0x62, 0x24, 0xda,
-       0x2e, 0xa3, 0x7d, 0xe9, 0x97, 0xf1, 0xa8, 0x1e, 0xa7, 0xfb, 0x5e, 0x8c,
-       0x07, 0xf2, 0xc5, 0x9f, 0x4b, 0xef, 0xd0, 0xf5, 0x1c, 0xfc, 0x71, 0x43,
-       0xd5, 0x5f, 0x59, 0xe4, 0x2c, 0x31, 0x06, 0xbc, 0x72, 0xd0, 0xb7, 0x96,
-       0xfb, 0x41, 0x29, 0x55, 0x95, 0xdb, 0x52, 0x1d, 0x73, 0x97, 0x3e, 0x58,
-       0x2f, 0xd9, 0x97, 0x60, 0x43, 0x61, 0x3f, 0x9d, 0x92, 0xdf, 0x06, 0xde,
-       0x83, 0x6f, 0xf4, 0x34, 0xeb, 0x2f, 0x99, 0x9f, 0xc4, 0xba, 0x94, 0x75,
-       0x98, 0x94, 0x9f, 0x44, 0xd5, 0x4f, 0x3c, 0x48, 0x1e, 0xee, 0xaf, 0xe4,
-       0x49, 0xba, 0xd6, 0xd8, 0x03, 0xae, 0x35, 0x76, 0xd3, 0x95, 0x27, 0x19,
-       0x12, 0xf8, 0xac, 0x82, 0xa9, 0x42, 0x0a, 0x53, 0x01, 0x7b, 0x49, 0xdd,
-       0xb6, 0x58, 0xd6, 0x6d, 0xbb, 0x37, 0xd1, 0x6d, 0x5e, 0xbe, 0xea, 0xaa,
-       0xd2, 0x23, 0x91, 0x28, 0x6c, 0x0c, 0xf6, 0x59, 0xfa, 0xfb, 0xe2, 0x28,
-       0xeb, 0x91, 0x28, 0xeb, 0x91, 0x11, 0xd6, 0x23, 0xc3, 0xac, 0x47, 0x6c,
-       0xa6, 0x81, 0xc5, 0x63, 0xff, 0x98, 0xf5, 0x34, 0xec, 0xc7, 0x18, 0x3d,
-       0x53, 0x84, 0x4e, 0x1e, 0x61, 0x0c, 0xf4, 0x31, 0xad, 0xcd, 0xb7, 0x33,
-       0xff, 0x4a, 0xdc, 0x53, 0xed, 0xd7, 0x60, 0xdf, 0x18, 0xc4, 0x86, 0x7f,
-       0x08, 0xbd, 0xf3, 0xb2, 0x43, 0x7d, 0xbe, 0xeb, 0x39, 0xd0, 0x79, 0x0d,
-       0x7b, 0x6b, 0xbc, 0x08, 0xd9, 0xc6, 0xbe, 0xc7, 0xdf, 0x1e, 0x1a, 0xe3,
-       0xbe, 0xf7, 0xf9, 0x32, 0x3c, 0x2f, 0x8f, 0x47, 0x1d, 0xb3, 0x8b, 0x65,
-       0x60, 0x52, 0xc9, 0xc0, 0x64, 0x45, 0x06, 0x9c, 0x34, 0x8f, 0xa4, 0x73,
-       0xa1, 0x83, 0x06, 0x8f, 0xc4, 0xf7, 0x76, 0xb2, 0xfc, 0x22, 0x67, 0xa2,
-       0xb2, 0xff, 0x90, 0x9f, 0xa6, 0x43, 0x41, 0xb5, 0x6f, 0x91, 0xc5, 0x76,
-       0xf3, 0x27, 0x94, 0xc9, 0xbd, 0xcb, 0xb8, 0x84, 0xe5, 0xd4, 0xc4, 0xf1,
-       0x45, 0xc4, 0x45, 0xd9, 0x6f, 0x68, 0x15, 0x71, 0xa5, 0x45, 0xd1, 0x16,
-       0xc7, 0x91, 0x61, 0xd6, 0x71, 0xd1, 0x55, 0x23, 0x32, 0x16, 0x33, 0x2e,
-       0xf7, 0x62, 0x5f, 0xfa, 0x6f, 0x17, 0x1f, 0xeb, 0x95, 0xf5, 0xb9, 0x4f,
-       0xed, 0x95, 0xfa, 0x84, 0x79, 0x34, 0x14, 0x13, 0xbe, 0x5b, 0xd3, 0x25,
-       0x69, 0x3f, 0x17, 0x79, 0xbe, 0x97, 0xa2, 0xc3, 0x3c, 0xdf, 0x6d, 0xca,
-       0x76, 0x3a, 0x7c, 0x5d, 0xd8, 0x65, 0xb6, 0xa1, 0xbd, 0xd8, 0xd3, 0xdf,
-       0x8c, 0x47, 0x9f, 0xe2, 0x77, 0x62, 0x1f, 0xa1, 0x2f, 0xe3, 0x79, 0xcc,
-       0xbd, 0xd0, 0x1f, 0x3f, 0x61, 0x1b, 0x8d, 0xf7, 0x82, 0x1f, 0xf9, 0x7b,
-       0x61, 0x8c, 0x2e, 0x64, 0x75, 0x1f, 0xde, 0x23, 0xe3, 0x39, 0xf4, 0xc3,
-       0x47, 0xbb, 0xed, 0xf7, 0x44, 0x4d, 0x88, 0xf1, 0x8d, 0xda, 0x3e, 0x7d,
-       0x45, 0xf5, 0x09, 0x7b, 0x79, 0xb6, 0xf0, 0x18, 0x76, 0x13, 0xf6, 0x74,
-       0x5a, 0x14, 0x7b, 0x6d, 0x36, 0x0b, 0x9f, 0x75, 0x51, 0xf8, 0x1e, 0x0f,
-       0xef, 0xad, 0xec, 0xff, 0x79, 0x57, 0xcd, 0xb9, 0x75, 0xb6, 0x5b, 0x47,
-       0x05, 0x46, 0xeb, 0xc7, 0x1e, 0xf4, 0xa2, 0x66, 0xf5, 0x4f, 0xc5, 0x35,
-       0x63, 0x01, 0xd7, 0x3e, 0xa7, 0xae, 0x7d, 0x56, 0x60, 0x63, 0x63, 0xbc,
-       0x95, 0xf5, 0xa2, 0xe0, 0x77, 0x9e, 0x67, 0x7b, 0x98, 0xf9, 0x3d, 0xbc,
-       0xc4, 0xcf, 0x9d, 0x16, 0xf4, 0xd4, 0xf4, 0x00, 0x2d, 0x20, 0x03, 0x6d,
-       0x8a, 0xff, 0x23, 0x56, 0xc2, 0xaf, 0xc7, 0xdd, 0x88, 0xce, 0x63, 0xb0,
-       0xcf, 0x3c, 0x56, 0x8c, 0xc9, 0xf2, 0xc5, 0x0a, 0x61, 0x5f, 0x7a, 0x1e,
-       0xbe, 0x0e, 0xea, 0x5e, 0x0e, 0x20, 0x9f, 0x8a, 0xfb, 0xb0, 0x87, 0x62,
-       0x49, 0xf4, 0x0b, 0xed, 0x34, 0x0d, 0xfe, 0xa8, 0x86, 0x16, 0xee, 0xfb,
-       0x3a, 0xd4, 0x7d, 0xad, 0x62, 0x2e, 0xc8, 0xc0, 0x7b, 0xf4, 0xbb, 0xf1,
-       0x5e, 0xbc, 0x1f, 0xf7, 0xe1, 0x79, 0xf2, 0xb9, 0xdd, 0xac, 0xb7, 0xe3,
-       0xa3, 0xf2, 0x59, 0xc6, 0x35, 0x79, 0xad, 0xdb, 0xf6, 0xee, 0xaf, 0x9c,
-       0x3f, 0x9f, 0xda, 0x83, 0x08, 0xf3, 0xd7, 0x41, 0x05, 0x11, 0xfb, 0xc4,
-       0xb5, 0x3e, 0x9f, 0xf0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xe3,
-       0x33, 0xb9, 0x77, 0x84, 0xcf, 0x9e, 0x4e, 0xf6, 0xf9, 0x0a, 0x05, 0x8c,
-       0xb7, 0xcf, 0x97, 0x60, 0x19, 0x98, 0xc8, 0xc5, 0x4b, 0x19, 0xa1, 0x6b,
-       0x18, 0xeb, 0x76, 0x45, 0xcc, 0x69, 0xa3, 0x47, 0x60, 0x3e, 0x7e, 0x1f,
-       0x7f, 0x67, 0x39, 0xcc, 0xb2, 0x1c, 0x66, 0x59, 0x0e, 0xb3, 0x2c, 0x87,
-       0xec, 0xab, 0x7e, 0x2b, 0xcb, 0x72, 0xc8, 0xb6, 0xe4, 0x15, 0xb6, 0x25,
-       0x52, 0x76, 0x63, 0x2a, 0xbe, 0xa9, 0x65, 0x17, 0xeb, 0x7f, 0x6e, 0x1f,
-       0x47, 0xcb, 0x2a, 0xec, 0x37, 0xf9, 0x8e, 0x0f, 0x55, 0xcb, 0xec, 0x0d,
-       0x96, 0xd9, 0xa6, 0xf1, 0x1e, 0xba, 0x95, 0xc7, 0x9c, 0x45, 0xac, 0x39,
-       0xd6, 0xd5, 0x09, 0x3f, 0xb0, 0x56, 0x80, 0xe5, 0x09, 0x58, 0x33, 0xc2,
-       0x74, 0xef, 0xa1, 0xdb, 0xac, 0xaf, 0x6f, 0xe5, 0x21, 0xc3, 0x07, 0xd4,
-       0x71, 0x84, 0x65, 0x18, 0xf6, 0xcf, 0xf6, 0xdd, 0xc8, 0x19, 0x8c, 0xc9,
-       0x02, 0x66, 0x8a, 0xa0, 0x4f, 0x05, 0x4e, 0xe3, 0x79, 0x5f, 0x65, 0xbd,
-       0x8f, 0x18, 0x1e, 0xec, 0xc5, 0x19, 0x1f, 0xdb, 0x8b, 0xf0, 0x75, 0xd6,
-       0xa7, 0xe7, 0xf3, 0x36, 0xcb, 0x7d, 0x17, 0xfd, 0x59, 0x1e, 0x76, 0x1a,
-       0x34, 0xe2, 0xe3, 0x02, 0x89, 0xd8, 0x98, 0x31, 0x8e, 0xb1, 0x0f, 0x3a,
-       0x86, 0xe0, 0x93, 0xdb, 0x98, 0x23, 0xa6, 0xfd, 0x3b, 0x7b, 0xb1, 0x9f,
-       0x7e, 0xcc, 0x68, 0x56, 0xb1, 0x46, 0x7c, 0x47, 0xfb, 0x1e, 0x85, 0x4d,
-       0x71, 0xdc, 0x68, 0x0d, 0x12, 0xbf, 0x43, 0x11, 0x65, 0x7a, 0xd4, 0xea,
-       0xaf, 0x0b, 0x7c, 0xbf, 0xa0, 0xd7, 0x58, 0xdc, 0x8f, 0xfa, 0x72, 0xfa,
-       0xaa, 0x7f, 0x7c, 0x8c, 0x9e, 0x2d, 0xa2, 0xdf, 0x97, 0x29, 0x13, 0x82,
-       0x3e, 0x8a, 0x44, 0xd7, 0x49, 0xd2, 0xae, 0x95, 0x71, 0xe7, 0x63, 0xde,
-       0x3a, 0xce, 0x8a, 0x0b, 0x9c, 0xdc, 0xc2, 0xfa, 0x05, 0xb4, 0xf9, 0x3e,
-       0xf3, 0x5a, 0x14, 0x75, 0x69, 0x4a, 0xbf, 0xbd, 0xce, 0x3a, 0x07, 0x73,
-       0x86, 0xe3, 0x8d, 0x75, 0xda, 0x9a, 0xd2, 0x69, 0xb6, 0x4b, 0xa7, 0xa5,
-       0xcb, 0x3a, 0x8d, 0x79, 0x43, 0xe8, 0xb2, 0xa0, 0xa8, 0x8d, 0x4e, 0xab,
-       0xef, 0xc0, 0x87, 0xbb, 0x85, 0xee, 0x62, 0xdd, 0x3f, 0x84, 0x3d, 0xc8,
-       0x1c, 0xdf, 0x31, 0xa1, 0x43, 0x34, 0x7f, 0x3f, 0xbc, 0x4f, 0xca, 0x45,
-       0xab, 0xd0, 0x07, 0xe9, 0x29, 0xe8, 0x2d, 0xaf, 0xf6, 0x0f, 0x72, 0x3b,
-       0xb4, 0xb7, 0xc3, 0x2f, 0xb2, 0x3e, 0x5b, 0x8c, 0xc2, 0xa7, 0x6d, 0x53,
-       0xbe, 0x0f, 0xf6, 0x14, 0xc3, 0x5a, 0x17, 0xc6, 0xaa, 0xf5, 0x59, 0xb7,
-       0x8a, 0x6b, 0x20, 0x0e, 0x89, 0x39, 0x6f, 0x88, 0x11, 0x2c, 0x60, 0x04,
-       0xbe, 0x27, 0xc0, 0xf4, 0x82, 0x7e, 0x61, 0x3b, 0xf0, 0x2e, 0xad, 0x09,
-       0xd9, 0x78, 0x57, 0x60, 0x97, 0x0c, 0x5f, 0x9b, 0x19, 0x7d, 0x54, 0xf4,
-       0x33, 0xb3, 0x5c, 0xd1, 0x8f, 0x73, 0xd9, 0xf7, 0x60, 0x37, 0x44, 0x5f,
-       0x97, 0x86, 0xa4, 0x0e, 0x5c, 0x2c, 0x98, 0xd8, 0xe3, 0x0c, 0x7d, 0xe6,
-       0xbe, 0xea, 0x71, 0xa2, 0x1f, 0x5a, 0x1f, 0x6c, 0x45, 0xf6, 0x18, 0xd7,
-       0x76, 0x61, 0x8e, 0x1c, 0x17, 0x0f, 0x7d, 0x8f, 0xdf, 0x8f, 0x73, 0x9b,
-       0x8f, 0xe7, 0x76, 0x79, 0x3c, 0x88, 0xed, 0xe1, 0x9e, 0x77, 0xe9, 0x96,
-       0x1a, 0xcf, 0xad, 0xf2, 0x78, 0xbe, 0xab, 0xc6, 0x43, 0x69, 0x63, 0xbc,
-       0x5b, 0xe1, 0xfe, 0x2d, 0x3f, 0xbb, 0x35, 0xce, 0x38, 0x26, 0xbd, 0x0c,
-       0x3a, 0xdf, 0xa5, 0xf8, 0xc9, 0x1d, 0x47, 0x75, 0xf7, 0x35, 0x32, 0xbc,
-       0xce, 0xfa, 0xf7, 0xb6, 0xc0, 0x31, 0x7d, 0x8c, 0x63, 0x70, 0x9e, 0x32,
-       0xd0, 0xd3, 0xe9, 0x10, 0xf6, 0xe1, 0x1d, 0xe3, 0x71, 0xb3, 0x3f, 0x36,
-       0xca, 0x9f, 0x22, 0xbe, 0x26, 0xe2, 0xbe, 0xea, 0xfe, 0xaf, 0xd3, 0xed,
-       0x79, 0xe8, 0x72, 0xe0, 0x58, 0xb9, 0x57, 0xef, 0xed, 0x15, 0x19, 0xdf,
-       0x4d, 0x78, 0xc6, 0x77, 0x11, 0xdb, 0x1d, 0x05, 0xce, 0x37, 0x11, 0x07,
-       0x9e, 0x50, 0xbf, 0x5f, 0x92, 0x2e, 0xe2, 0x59, 0x5e, 0x7a, 0x69, 0xcc,
-       0x95, 0x1f, 0x87, 0xbc, 0x14, 0x87, 0xf5, 0x8c, 0x6d, 0x36, 0x19, 0x47,
-       0x65, 0x9c, 0xb9, 0xa8, 0xb1, 0xd3, 0x09, 0x9e, 0x33, 0x3b, 0x6a, 0x18,
-       0x09, 0x11, 0x6b, 0x68, 0xb5, 0xdb, 0xa8, 0x85, 0xed, 0xe8, 0x59, 0xc2,
-       0x3e, 0x70, 0x11, 0x0b, 0x6b, 0x00, 0x17, 0x98, 0x27, 0x33, 0xd1, 0x48,
-       0xf8, 0x51, 0xe1, 0x97, 0xc2, 0xbe, 0x18, 0xa0, 0x13, 0xd3, 0x1a, 0x7d,
-       0xe0, 0xef, 0xcb, 0xd8, 0x0b, 0x34, 0xca, 0xe3, 0x47, 0xfc, 0x78, 0xc0,
-       0x7a, 0x93, 0xed, 0xd2, 0x05, 0x11, 0x97, 0x79, 0x9a, 0xd2, 0x2c, 0xa7,
-       0xc7, 0x85, 0x9c, 0x1a, 0x7d, 0x2c, 0x45, 0x2c, 0x57, 0xc8, 0x43, 0x18,
-       0x44, 0x0c, 0x50, 0xf9, 0x3a, 0x3c, 0xca, 0x15, 0xb5, 0x57, 0x42, 0x12,
-       0xba, 0x63, 0xeb, 0x31, 0x89, 0xe4, 0xa7, 0x8e, 0xc5, 0xb8, 0x31, 0x59,
-       0xa3, 0xda, 0x51, 0xf8, 0x69, 0x2a, 0x9e, 0x88, 0xfc, 0xf8, 0xf2, 0x6f,
-       0xe9, 0xb8, 0xe3, 0x06, 0xe7, 0x44, 0x6e, 0xe8, 0xcb, 0x45, 0x69, 0x83,
-       0xd3, 0xec, 0xd3, 0x67, 0x8e, 0xb8, 0x31, 0x49, 0x24, 0x37, 0x21, 0x62,
-       0x39, 0xfb, 0x28, 0xbe, 0x30, 0x42, 0x0f, 0x64, 0xa1, 0xc3, 0x68, 0x3d,
-       0x6e, 0xe3, 0x57, 0x72, 0x20, 0xe3, 0x23, 0x94, 0x28, 0x82, 0x46, 0x3e,
-       0xc6, 0x4a, 0xcc, 0x7b, 0x39, 0xac, 0xef, 0xf3, 0xf7, 0x02, 0x7e, 0x1b,
-       0xe6, 0x0f, 0x54, 0xbc, 0xbc, 0x97, 0x26, 0x16, 0xc8, 0x49, 0x45, 0xef,
-       0x15, 0x7b, 0x79, 0xa7, 0xa2, 0x43, 0x2a, 0xb6, 0x13, 0xe6, 0xf3, 0x88,
-       0x97, 0x59, 0x74, 0x7f, 0x36, 0xe2, 0xa4, 0x48, 0xc6, 0x2c, 0x88, 0xfb,
-       0x60, 0xb0, 0xed, 0xdd, 0xcd, 0x3a, 0xe4, 0x94, 0x88, 0x5b, 0x30, 0x52,
-       0x99, 0x47, 0x7b, 0xc4, 0x1c, 0xba, 0x08, 0x7e, 0x5a, 0x2a, 0xf7, 0xaa,
-       0x6a, 0x5b, 0x22, 0x93, 0x79, 0xc1, 0xfc, 0x6d, 0xdb, 0x89, 0x1a, 0x95,
-       0xfb, 0x11, 0xf3, 0x38, 0x25, 0x70, 0x64, 0x1f, 0xfb, 0x3c, 0xa2, 0x5d,
-       0x69, 0x46, 0xc4, 0x2f, 0xf8, 0xb8, 0xf0, 0xc8, 0x7e, 0xa9, 0xdb, 0xe4,
-       0x79, 0x19, 0xd7, 0xe0, 0x67, 0x16, 0xb8, 0x1f, 0x55, 0xf9, 0xf4, 0xbd,
-       0x14, 0xdb, 0x46, 0x9c, 0x69, 0xea, 0x8e, 0xc6, 0x99, 0x98, 0xd6, 0xc5,
-       0xcd, 0x6a, 0x1a, 0xb4, 0xff, 0xf7, 0x91, 0xb6, 0xe1, 0x4c, 0x2b, 0x53,
-       0xfc, 0x16, 0x08, 0x30, 0x78, 0xa6, 0xf8, 0x3c, 0x7e, 0x03, 0xc7, 0x97,
-       0x14, 0xd8, 0x38, 0xcc, 0xd8, 0x06, 0x18, 0x67, 0x40, 0xac, 0x8b, 0xc5,
-       0x1e, 0x0a, 0xfb, 0x32, 0x2b, 0x3d, 0xe4, 0x47, 0x3c, 0xce, 0xd6, 0xb9,
-       0x1c, 0xad, 0x22, 0xef, 0x5d, 0xae, 0x47, 0xc2, 0x3e, 0x43, 0x27, 0xae,
-       0xb3, 0xdf, 0xf0, 0x90, 0xca, 0xb9, 0x41, 0xcd, 0xa6, 0xce, 0xb9, 0xd1,
-       0x3a, 0x45, 0xf3, 0x9e, 0x5e, 0xeb, 0x70, 0xff, 0xde, 0x18, 0x64, 0xd7,
-       0x8d, 0x29, 0x10, 0x9f, 0x12, 0x73, 0x74, 0x81, 0x48, 0xce, 0x71, 0x65,
-       0x1d, 0xa3, 0x85, 0xe7, 0x09, 0xfe, 0x20, 0xe2, 0x7e, 0x8f, 0xf0, 0x27,
-       0xd6, 0x23, 0x7e, 0xb4, 0x1f, 0x38, 0xaa, 0xd3, 0x66, 0x9e, 0x19, 0xc5,
-       0x71, 0x0f, 0xfb, 0x67, 0x1a, 0xf7, 0xca, 0x58, 0x14, 0xfb, 0x6c, 0x6a,
-       0xbe, 0x10, 0x87, 0xea, 0x97, 0x39, 0x4c, 0xd9, 0x08, 0x59, 0x5d, 0xa0,
-       0xd3, 0xaf, 0x4a, 0x1e, 0x37, 0x5b, 0xbb, 0xd8, 0x4a, 0x5e, 0x13, 0x7e,
-       0x0b, 0x0d, 0xfb, 0x8d, 0x1e, 0x04, 0xed, 0x79, 0x8e, 0xdc, 0x6b, 0x1b,
-       0xcf, 0xef, 0xd5, 0xbf, 0xc3, 0x74, 0x67, 0xe6, 0x6d, 0x87, 0xc7, 0xbc,
-       0x1d, 0xec, 0x95, 0x6b, 0x67, 0x7f, 0xa1, 0xda, 0x78, 0xe5, 0xb8, 0x3a,
-       0x4f, 0x22, 0x0e, 0x55, 0xa9, 0xbf, 0x78, 0x5b, 0xe8, 0x95, 0xfa, 0x58,
-       0x78, 0x98, 0xf5, 0xa9, 0x94, 0xe3, 0x53, 0x1e, 0x72, 0xdc, 0x35, 0x0e,
-       0xdc, 0xf2, 0xc9, 0xe5, 0x78, 0xb2, 0xa1, 0x1c, 0x4f, 0xf6, 0xca, 0x58,
-       0x6c, 0xbd, 0x1c, 0xbf, 0x81, 0xbe, 0x14, 0x37, 0xca, 0x81, 0x44, 0x4d,
-       0xbb, 0x3b, 0x56, 0x02, 0x9a, 0xe9, 0x78, 0x09, 0xd6, 0x0d, 0xc1, 0x97,
-       0x58, 0x7b, 0x99, 0x32, 0x12, 0xf3, 0xb5, 0x6b, 0xa9, 0x5b, 0xb9, 0x17,
-       0xeb, 0x34, 0xb5, 0xf7, 0x02, 0xbb, 0x43, 0x36, 0x22, 0x61, 0x19, 0x0b,
-       0xd0, 0xf4, 0xeb, 0xf5, 0x1d, 0xcb, 0x47, 0x9c, 0x02, 0x21, 0xd6, 0x1d,
-       0xa2, 0x73, 0x58, 0x9f, 0x56, 0xb1, 0xe4, 0x93, 0x59, 0x49, 0x07, 0xf3,
-       0x88, 0xe0, 0x0f, 0xe0, 0xdb, 0x70, 0xd2, 0x9f, 0xe4, 0x39, 0x96, 0x71,
-       0xe4, 0xd4, 0x72, 0x58, 0xcd, 0x1b, 0xb7, 0xc5, 0xf3, 0xaa, 0xf6, 0x92,
-       0xd7, 0x71, 0x07, 0xcc, 0x57, 0xe4, 0xeb, 0x95, 0xdc, 0x64, 0xd8, 0x86,
-       0x12, 0xfd, 0x37, 0xdb, 0x3d, 0xff, 0x11, 0x53, 0xec, 0xe3, 0xf0, 0x46,
-       0xf1, 0x08, 0xe3, 0x4d, 0xcc, 0x29, 0x62, 0x90, 0x3a, 0x46, 0xfc, 0xc4,
-       0x41, 0x6a, 0x3f, 0xcc, 0x28, 0xc0, 0x20, 0x9b, 0xf1, 0xa5, 0x71, 0x04,
-       0xb9, 0xe6, 0x16, 0xdf, 0x83, 0xfd, 0xa8, 0x06, 0xad, 0x04, 0xb5, 0x21,
-       0x0e, 0x81, 0xfd, 0xb0, 0xad, 0x74, 0x95, 0x8c, 0x9d, 0x16, 0x32, 0x96,
-       0x58, 0x39, 0xad, 0x64, 0xec, 0xb4, 0x8a, 0xc3, 0x9f, 0x56, 0x32, 0x76,
-       0x5a, 0xc9, 0xd8, 0x69, 0x25, 0x63, 0xa7, 0x99, 0xcf, 0x07, 0x18, 0xdf,
-       0x02, 0x8b, 0xe8, 0x38, 0x68, 0x3b, 0xa5, 0xf2, 0x38, 0x0f, 0xfb, 0x5c,
-       0x2b, 0x67, 0xef, 0xf6, 0x49, 0x39, 0x63, 0x6c, 0x22, 0xeb, 0xc9, 0xf8,
-       0x5d, 0x98, 0x83, 0x57, 0x98, 0xe6, 0x1f, 0xd3, 0x99, 0x79, 0xf4, 0xd5,
-       0x47, 0x13, 0x62, 0x1f, 0xdc, 0x26, 0x8a, 0xbb, 0xb1, 0xb0, 0xc9, 0x63,
-       0xcd, 0x4a, 0xdf, 0xcf, 0x31, 0x6c, 0xc1, 0x27, 0xde, 0x7a, 0x15, 0x7c,
-       0x32, 0xae, 0xe6, 0xab, 0xd6, 0x2f, 0x6a, 0xa1, 0x64, 0x0e, 0x74, 0x45,
-       0xfe, 0xa4, 0xc5, 0x73, 0x23, 0xe8, 0xe4, 0x98, 0x1e, 0x34, 0x38, 0xa9,
-       0x68, 0xf0, 0xb8, 0x18, 0x23, 0xf2, 0x0f, 0x11, 0xcb, 0x6c, 0x4c, 0x87,
-       0x74, 0x76, 0x80, 0x9f, 0xc3, 0xb2, 0x70, 0x24, 0xcc, 0x3a, 0x69, 0xeb,
-       0x74, 0xa8, 0x8c, 0xbd, 0x91, 0xee, 0xd9, 0x6a, 0x5d, 0xce, 0xba, 0xcb,
-       0x96, 0x84, 0x95, 0x1d, 0x91, 0xb8, 0x78, 0x87, 0x5d, 0xa2, 0x13, 0xd1,
-       0x83, 0xfc, 0x3d, 0x92, 0x74, 0xe8, 0x30, 0x19, 0x9d, 0x25, 0xfa, 0x11,
-       0xcb, 0x41, 0x2b, 0xcb, 0xc1, 0x09, 0xe5, 0x97, 0x9c, 0x28, 0xfb, 0x25,
-       0x93, 0x07, 0x90, 0x97, 0x91, 0x12, 0xeb, 0x5e, 0x3b, 0xcb, 0xbf, 0xc3,
-       0x02, 0x3d, 0xb6, 0x88, 0xfd, 0x28, 0x7a, 0x71, 0x6c, 0xd2, 0x55, 0xf6,
-       0xab, 0x63, 0xbe, 0x07, 0x0f, 0x08, 0xec, 0xee, 0x7b, 0x00, 0xf7, 0x9c,
-       0x90, 0x7a, 0xcf, 0x47, 0xfe, 0xc1, 0x77, 0x18, 0x4f, 0x94, 0xe8, 0x31,
-       0x7e, 0x67, 0x26, 0x77, 0x88, 0x9f, 0xad, 0xf7, 0x96, 0xb0, 0x63, 0x86,
-       0x6f, 0x27, 0xf9, 0x3b, 0x1b, 0xbd, 0x3b, 0x22, 0xf8, 0x91, 0xf1, 0xb4,
-       0x31, 0x13, 0x7d, 0xaf, 0x34, 0x3d, 0x85, 0x18, 0x3b, 0xe4, 0x24, 0x62,
-       0x5a, 0x3e, 0x2f, 0xf9, 0x90, 0x58, 0xa9, 0x92, 0x0b, 0x2b, 0xf3, 0xc2,
-       0xff, 0x8b, 0xc7, 0x66, 0x12, 0xd6, 0x4e, 0xe4, 0xf3, 0x93, 0x04, 0x9f,
-       0x00, 0xfb, 0x53, 0x58, 0x4c, 0x67, 0xfd, 0x2e, 0x5b, 0xf1, 0xc6, 0x67,
-       0x90, 0xe7, 0x96, 0x5b, 0xa4, 0x8d, 0x6d, 0x0e, 0xe2, 0x75, 0x03, 0x0b,
-       0x6b, 0x9d, 0x21, 0x51, 0x1b, 0xde, 0xc1, 0x18, 0x49, 0xe7, 0x3e, 0x0f,
-       0xf2, 0xf3, 0x11, 0xc7, 0x0b, 0xd0, 0xc4, 0x25, 0xb4, 0x6b, 0xa6, 0xfe,
-       0x85, 0xd2, 0xef, 0xf1, 0x75, 0xb1, 0x7e, 0x99, 0xa2, 0x56, 0xb5, 0x36,
-       0xa1, 0xf7, 0xad, 0x08, 0xb3, 0xec, 0x55, 0x6a, 0x9f, 0xfb, 0xcb, 0x31,
-       0x3d, 0x21, 0x13, 0x35, 0x31, 0xbd, 0xaf, 0x6e, 0x62, 0xaf, 0x36, 0x93,
-       0x03, 0xe4, 0xd4, 0xb5, 0x90, 0x8a, 0x55, 0x5a, 0x19, 0xda, 0x6a, 0x4d,
-       0xdf, 0x76, 0xef, 0xf1, 0xb5, 0x36, 0x8f, 0x93, 0xf3, 0xa6, 0x1d, 0x54,
-       0xfc, 0xd7, 0x4c, 0x67, 0xf2, 0x41, 0xb6, 0xf9, 0xd0, 0xad, 0xa0, 0x97,
-       0xbf, 0x17, 0xb5, 0x2e, 0x5f, 0x0a, 0x34, 0xd3, 0xf2, 0x32, 0x72, 0x2d,
-       0xfe, 0xf1, 0x80, 0xcc, 0x25, 0x4e, 0x32, 0x5d, 0x0e, 0xb3, 0x7d, 0x34,
-       0xd4, 0xda, 0x11, 0xce, 0x41, 0x97, 0x88, 0xdf, 0x21, 0x0a, 0xdc, 0x3b,
-       0x14, 0x64, 0xbf, 0x40, 0xae, 0x3d, 0x1c, 0xe5, 0x67, 0x7f, 0x33, 0x9f,
-       0x44, 0xbc, 0xcc, 0x3c, 0xce, 0xcf, 0x9f, 0x60, 0x3c, 0x11, 0xa3, 0x66,
-       0x5a, 0x5a, 0x6e, 0x66, 0xbf, 0xa0, 0x99, 0xf1, 0xc4, 0x80, 0xd9, 0xef,
-       0x13, 0xef, 0x12, 0x75, 0x35, 0x9f, 0x0f, 0x1c, 0x66, 0xbe, 0xc2, 0xbb,
-       0xfe, 0x5d, 0xbd, 0xab, 0xf6, 0x1d, 0xff, 0x51, 0xc2, 0xf1, 0x71, 0x3f,
-       0x39, 0x37, 0xf0, 0x1b, 0x5c, 0xf3, 0x63, 0x8c, 0x9d, 0x43, 0x94, 0x99,
-       0x6f, 0xe2, 0x31, 0x8c, 0xb3, 0x1f, 0x11, 0xe5, 0xe3, 0xfb, 0xc8, 0x29,
-       0x4e, 0xd1, 0x5f, 0x15, 0xdd, 0x31, 0xe1, 0xfb, 0xb8, 0xcf, 0xb2, 0xb6,
-       0xbf, 0x85, 0xfb, 0xf5, 0x91, 0x5d, 0xab, 0x63, 0x82, 0xe4, 0xff, 0xeb,
-       0x10, 0x35, 0x7f, 0x0d, 0xb1, 0x97, 0x12, 0xe5, 0xa2, 0xa8, 0x57, 0x90,
-       0xf1, 0xe7, 0xab, 0x22, 0x87, 0x96, 0xef, 0xe7, 0x67, 0xce, 0xa1, 0xdd,
-       0x55, 0x8b, 0xae, 0xdb, 0x92, 0xde, 0x3f, 0x08, 0x84, 0xc8, 0xff, 0x12,
-       0x72, 0x9f, 0xc4, 0xfe, 0x1a, 0x8e, 0x7d, 0x88, 0xf5, 0xfb, 0xd7, 0x70,
-       0x1f, 0x7f, 0xbe, 0x84, 0xe3, 0x20, 0x8f, 0x13, 0xf6, 0x1a, 0xf9, 0x2e,
-       0xd0, 0x8b, 0x87, 0xc3, 0xa6, 0xe0, 0xbf, 0xfb, 0x98, 0xa7, 0x9a, 0x44,
-       0xac, 0xb1, 0x0b, 0x6d, 0xed, 0xfd, 0xc0, 0x16, 0xce, 0xd0, 0x21, 0x1c,
-       0xc7, 0x3a, 0xfd, 0x4c, 0x23, 0xc9, 0x43, 0x18, 0x4f, 0x15, 0x73, 0x07,
-       0x8e, 0x0e, 0x11, 0xcf, 0x27, 0xf0, 0xc7, 0x2f, 0xf1, 0x1b, 0x91, 0x4e,
-       0x3f, 0xbf, 0x23, 0xc1, 0xef, 0x98, 0xc8, 0xcb, 0x71, 0xcf, 0x15, 0xfd,
-       0x24, 0xe3, 0x54, 0x5f, 0xe9, 0xd3, 0xbf, 0xd1, 0x48, 0x3d, 0x78, 0x76,
-       0x59, 0x56, 0xf8, 0x7b, 0x3b, 0xdd, 0xca, 0xb7, 0xd1, 0x6d, 0xb5, 0xa6,
-       0x75, 0x4b, 0xf8, 0x65, 0xac, 0xc3, 0x93, 0xed, 0xb4, 0xbe, 0xdc, 0x44,
-       0xd4, 0x15, 0x14, 0x6b, 0xce, 0xb7, 0xf2, 0x05, 0x7e, 0xff, 0x97, 0xfb,
-       0x64, 0x5c, 0xa7, 0xc2, 0x23, 0xb7, 0x3c, 0x78, 0xe4, 0x03, 0xc1, 0x23,
-       0x5f, 0xec, 0xdb, 0x98, 0x47, 0x50, 0xf3, 0x0f, 0xde, 0x08, 0x52, 0xb3,
-       0xe2, 0x8f, 0x17, 0x99, 0x3f, 0x9e, 0x65, 0xfe, 0x38, 0xd6, 0x80, 0x3f,
-       0x8c, 0x1a, 0xfe, 0x38, 0x2e, 0xf8, 0xe3, 0x89, 0xbe, 0x8d, 0xf8, 0xe3,
-       0x98, 0x7f, 0xa3, 0x58, 0x93, 0xaf, 0x35, 0xc0, 0xef, 0x9e, 0xb3, 0xf7,
-       0x31, 0xaf, 0xdb, 0xb4, 0x34, 0x8f, 0xfa, 0x84, 0xd5, 0xa8, 0x41, 0x3f,
-       0x13, 0x3e, 0xd9, 0x9a, 0xf0, 0xf9, 0xc7, 0x45, 0xcd, 0xc1, 0xa2, 0xe0,
-       0x2f, 0xb6, 0xff, 0xe3, 0xa8, 0xab, 0xaa, 0x9d, 0x8b, 0x56, 0xba, 0x1e,
-       0xc5, 0x5c, 0x58, 0x7a, 0x2e, 0x08, 0xeb, 0xbb, 0x6a, 0xef, 0xc8, 0x40,
-       0x3c, 0x4b, 0xce, 0x07, 0xe0, 0xd1, 0x95, 0xb6, 0xc0, 0x44, 0xf6, 0x1b,
-       0x7d, 0xc0, 0x7f, 0x99, 0x15, 0x72, 0x9d, 0x0f, 0xf0, 0xf9, 0x90, 0xf8,
-       0x6d, 0x2b, 0xc8, 0xca, 0x87, 0xc8, 0x71, 0x64, 0x9e, 0xbc, 0x9e, 0xef,
-       0xa5, 0x1b, 0xf9, 0x7d, 0xb4, 0x96, 0xef, 0xa3, 0x37, 0xc5, 0xbe, 0x1a,
-       0xb2, 0x36, 0x72, 0x4d, 0xcc, 0x91, 0x41, 0x47, 0x43, 0xdc, 0x66, 0x79,
-       0x1f, 0xad, 0x2e, 0x6b, 0xfe, 0x06, 0x6f, 0x83, 0x5f, 0x62, 0x9d, 0xb2,
-       0x66, 0xae, 0x9e, 0x67, 0x26, 0xaa, 0x79, 0x46, 0xdc, 0x03, 0x5e, 0xc9,
-       0xd4, 0xd5, 0xfa, 0x22, 0x5f, 0x11, 0xb9, 0x7a, 0x41, 0x6a, 0x42, 0xde,
-       0xa2, 0x11, 0x19, 0x3e, 0xea, 0x07, 0x86, 0xce, 0xb1, 0xcd, 0xe5, 0x39,
-       0xb3, 0x91, 0xe7, 0xd4, 0xc7, 0x78, 0xb8, 0x43, 0xe0, 0xdf, 0xb8, 0x1d,
-       0x08, 0x4f, 0x50, 0xe9, 0x69, 0xc3, 0xc6, 0x5e, 0x8f, 0x49, 0x7e, 0x9e,
-       0xa1, 0xe2, 0x4d, 0xbb, 0x5c, 0xfc, 0x57, 0x8b, 0x75, 0xb1, 0x96, 0xfc,
-       0x10, 0xf7, 0x19, 0x76, 0xb8, 0xb2, 0x5e, 0x43, 0xe5, 0xf5, 0x9a, 0x56,
-       0x1e, 0xb7, 0x94, 0xbd, 0x19, 0x9b, 0xdb, 0x15, 0xff, 0x6f, 0x40, 0x75,
-       0xeb, 0x41, 0x73, 0x7f, 0x40, 0xf1, 0x25, 0xa0, 0x79, 0x67, 0x19, 0x86,
-       0x43, 0x3d, 0xa0, 0x3c, 0x0a, 0x1a, 0x0f, 0x41, 0xcc, 0xf5, 0x1e, 0x5a,
-       0x03, 0x12, 0x07, 0x8d, 0x89, 0x20, 0xe6, 0x7a, 0x0f, 0x41, 0xe7, 0x7a,
-       0x0f, 0xad, 0xb1, 0x01, 0x97, 0xdb, 0xcd, 0x53, 0x80, 0xe1, 0x3e, 0x85,
-       0x19, 0xba, 0xce, 0x51, 0x0d, 0x7a, 0x77, 0x52, 0x0c, 0x78, 0x4c, 0x5b,
-       0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, 0xb8, 0x9d, 0xe5,
-       0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, 0x80, 0x79, 0x4f,
-       0x18, 0x9a, 0xf7, 0x60, 0x73, 0xc7, 0xfc, 0x0c, 0x90, 0x7b, 0x98, 0x6c,
-       0xc0, 0x7d, 0x0b, 0x48, 0x79, 0x25, 0x83, 0x56, 0x5e, 0x01, 0xd3, 0x84,
-       0x3a, 0x44, 0x7f, 0xd3, 0x7a, 0x0d, 0x79, 0xd8, 0x38, 0x60, 0x13, 0xd0,
-       0xdc, 0xe6, 0x29, 0xa4, 0xcc, 0x3d, 0x03, 0xeb, 0x5b, 0xac, 0x6b, 0x1b,
-       0x6d, 0xc0, 0x7b, 0xac, 0x17, 0x4d, 0x61, 0x61, 0x58, 0xd2, 0xc3, 0x00,
-       0xac, 0x1f, 0x40, 0x69, 0x1d, 0x54, 0x47, 0xc0, 0xd3, 0xbb, 0x40, 0x13,
-       0xd0, 0x7d, 0x4e, 0xc0, 0xb6, 0xa8, 0x73, 0xbf, 0x32, 0x78, 0xad, 0x6c,
-       0x03, 0xf4, 0xfc, 0xaa, 0x45, 0x3d, 0xde, 0xf2, 0xa0, 0x7c, 0xe6, 0xa4,
-       0xc2, 0x40, 0x46, 0x5e, 0x60, 0x83, 0xe6, 0x05, 0x70, 0x38, 0x01, 0xd3,
-       0x3a, 0xb0, 0x8c, 0x5a, 0x93, 0x04, 0x34, 0x8f, 0x87, 0xc5, 0xa5, 0x1f,
-       0x24, 0xc6, 0x00, 0x15, 0x63, 0x01, 0xf2, 0x65, 0x80, 0x6d, 0x4a, 0x90,
-       0x5f, 0x41, 0x79, 0x01, 0x64, 0x36, 0xc8, 0xef, 0xa0, 0xb2, 0x13, 0x94,
-       0x17, 0x81, 0xec, 0x25, 0x42, 0x50, 0x3f, 0x03, 0x69, 0x20, 0xbb, 0x79,
-       0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x07, 0xc4,
-       0x86, 0x31, 0x4c, 0x7d, 0x0c, 0x19, 0xf9, 0x06, 0x62, 0x06, 0x22, 0xdf,
-       0xb0, 0x33, 0x1c, 0x10, 0x80, 0x85, 0xd5, 0xff, 0xff, 0xc7, 0x54, 0x58,
-       0x80, 0xe9, 0x14, 0xb4, 0x8e, 0xf5, 0xf7, 0xff, 0x03, 0x22, 0x2c, 0x0c,
-       0x2d, 0xf0, 0xf5, 0x88, 0x0b, 0xe5, 0x41, 0x65, 0xe8, 0x02, 0x20, 0xab,
-       0x0d, 0xde, 0x26, 0x60, 0x01, 0xdf, 0x61, 0xbd, 0x80, 0xe1, 0x17, 0xb0,
-       0xcc, 0xfa, 0xff, 0x7f, 0x29, 0x5c, 0x2d, 0x08, 0x00, 0x00, 0xff, 0x88,
-       0x78, 0xb5, 0x98, 0x7e, 0x00, 0x00, 0x00 };
+       0xcd, 0x7c, 0x7f, 0x6c, 0x5c, 0xd7, 0x95, 0xde, 0x79, 0x6f, 0x1e, 0xc9,
+       0xe1, 0x88, 0xa2, 0x1e, 0xe9, 0x31, 0x3d, 0x8e, 0xb9, 0xc9, 0x0c, 0xe7,
+       0x91, 0xa2, 0x4d, 0x26, 0xfb, 0xcc, 0x8e, 0x6d, 0x3a, 0x99, 0xb5, 0xc6,
+       0x33, 0x94, 0xad, 0xc4, 0x8c, 0x41, 0x3b, 0xca, 0xd6, 0x28, 0xdc, 0x80,
+       0x1d, 0x52, 0x8e, 0xb3, 0x75, 0xbb, 0x8e, 0x1b, 0xa4, 0x89, 0x11, 0x44,
+       0x93, 0x21, 0xa5, 0x55, 0x82, 0x21, 0x67, 0x22, 0xd3, 0xdc, 0xfc, 0xb1,
+       0x68, 0xc6, 0x43, 0x52, 0x71, 0xb6, 0x23, 0xd1, 0x4e, 0xb2, 0x41, 0x16,
+       0xd8, 0xc0, 0x2c, 0x25, 0xcb, 0xc2, 0x22, 0x2d, 0xdc, 0x34, 0x28, 0x82,
+       0xec, 0xfe, 0x21, 0xc8, 0xce, 0xc6, 0x29, 0xd2, 0xc2, 0xed, 0x06, 0x8d,
+       0x37, 0x48, 0xf2, 0xfa, 0x7d, 0xf7, 0xde, 0x37, 0x1a, 0x8d, 0x68, 0x27,
+       0xdd, 0xfe, 0x53, 0x02, 0x83, 0xfb, 0xde, 0xfd, 0x79, 0xee, 0xb9, 0xe7,
+       0x9e, 0xf3, 0x9d, 0x73, 0xef, 0xe3, 0x3d, 0x22, 0x31, 0x31, 0x7f, 0xfb,
+       0xf1, 0xcb, 0xfc, 0xab, 0x3f, 0x5e, 0xb8, 0xe3, 0x7d, 0xfe, 0xfb, 0xf8,
+       0x6e, 0x77, 0x89, 0xc3, 0x34, 0x82, 0x5f, 0x1c, 0xbf, 0x29, 0xf3, 0xbc,
+       0xd7, 0x9f, 0x8b, 0xdf, 0x9d, 0x96, 0xc8, 0xfc, 0x7f, 0x13, 0xb1, 0x3a,
+       0xca, 0xa2, 0x7b, 0xd4, 0x0f, 0x82, 0xb7, 0xe9, 0xc8, 0xfc, 0xd9, 0xf8,
+       0x25, 0xdf, 0xb9, 0xca, 0xff, 0xf3, 0x5f, 0x44, 0x93, 0xad, 0xe6, 0xcd,
+       0x9f, 0x44, 0xed, 0x6c, 0xfd, 0x81, 0xbc, 0x27, 0xd1, 0x48, 0x76, 0x6d,
+       0x76, 0xc1, 0x13, 0xc9, 0x35, 0x27, 0x92, 0x05, 0xf9, 0x75, 0x50, 0x8a,
+       0x3b, 0xc2, 0xfc, 0xdf, 0xcb, 0xfe, 0xea, 0xab, 0xdf, 0xbd, 0x2b, 0xf5,
+       0x66, 0x3d, 0x22, 0x51, 0x37, 0xfb, 0x96, 0xb8, 0x63, 0x12, 0x1d, 0x46,
+       0x9b, 0x3f, 0x3b, 0x78, 0xc9, 0x96, 0xfe, 0xb0, 0x2f, 0x77, 0x3e, 0x92,
+       0x95, 0xb9, 0x63, 0x95, 0xe3, 0x81, 0xed, 0x49, 0xc9, 0xc9, 0x7a, 0xe3,
+       0x0d, 0xe9, 0x9b, 0xde, 0xca, 0xdc, 0x25, 0x78, 0x9f, 0x3b, 0xd6, 0x8c,
+       0x4a, 0xb9, 0x59, 0xea, 0xb3, 0x3d, 0x0f, 0xa9, 0x44, 0xbb, 0xb3, 0x8b,
+       0xd1, 0x8b, 0x1e, 0xc7, 0xfe, 0x21, 0xc6, 0xbe, 0x45, 0xba, 0xbc, 0x20,
+       0xd8, 0xc2, 0xd8, 0xf7, 0x35, 0x7f, 0x1d, 0x3c, 0xe7, 0xe8, 0x71, 0xed,
+       0xec, 0x93, 0x11, 0xa6, 0x56, 0xf6, 0xf2, 0x03, 0x23, 0x4d, 0xbe, 0x7b,
+       0x3d, 0x9a, 0x4e, 0x37, 0x06, 0x3a, 0xa3, 0x4e, 0x76, 0x2e, 0xb6, 0x8c,
+       0xb4, 0x2b, 0xfb, 0xe8, 0xed, 0x5b, 0xaa, 0xde, 0xeb, 0xa6, 0xde, 0x13,
+       0x5d, 0xba, 0xdd, 0xf8, 0xec, 0x58, 0x93, 0x69, 0x66, 0x76, 0x54, 0xa5,
+       0xd9, 0xd9, 0xb4, 0x4a, 0x73, 0xb3, 0x23, 0x2a, 0x9d, 0x99, 0xf5, 0x54,
+       0xfa, 0xb7, 0x0f, 0xe8, 0xfc, 0x37, 0x1e, 0x48, 0xaa, 0xf4, 0x67, 0x26,
+       0x7d, 0xd3, 0xa4, 0x3f, 0x37, 0xe9, 0x5b, 0x26, 0xfd, 0x95, 0x49, 0x65,
+       0x56, 0xa7, 0x8e, 0xe9, 0x27, 0x6a, 0xde, 0xfb, 0x4c, 0xea, 0x9a, 0x34,
+       0x6e, 0xd2, 0x84, 0x49, 0x87, 0x0d, 0x5d, 0x49, 0x93, 0x7a, 0x26, 0x9d,
+       0x34, 0xe5, 0xbe, 0xa1, 0x77, 0x1a, 0xf4, 0x7e, 0xa1, 0xcb, 0xc8, 0x2a,
+       0xe6, 0x9d, 0x94, 0x85, 0x8a, 0x23, 0xe5, 0x6a, 0x44, 0x0a, 0x6a, 0x0d,
+       0x1f, 0xd9, 0x2f, 0x31, 0x47, 0x96, 0xb6, 0xa3, 0x72, 0x59, 0x89, 0xe8,
+       0x1b, 0xc1, 0x77, 0x0f, 0x4a, 0xc9, 0xce, 0xba, 0xf2, 0xc2, 0x76, 0x5c,
+       0x5e, 0xda, 0x16, 0x6b, 0x2e, 0xd3, 0x2b, 0xf6, 0xe9, 0x77, 0x49, 0xce,
+       0xb5, 0x24, 0xa2, 0x78, 0x9a, 0x94, 0x7c, 0x65, 0x08, 0xef, 0xa9, 0x84,
+       0xc8, 0xe9, 0xfd, 0x7a, 0xfd, 0xa2, 0x12, 0x59, 0xe7, 0x9a, 0x3c, 0x3d,
+       0x7b, 0x71, 0x2d, 0x21, 0xce, 0xea, 0x24, 0xc6, 0xe8, 0x93, 0xae, 0x75,
+       0x19, 0x8e, 0xc8, 0x68, 0xe2, 0x31, 0xd4, 0x98, 0x69, 0x3a, 0x72, 0xb8,
+       0x69, 0x89, 0xe3, 0x45, 0x21, 0x1f, 0x7d, 0xf8, 0xb9, 0xf8, 0xc5, 0xf1,
+       0x4b, 0xe0, 0xf7, 0x97, 0xe8, 0x67, 0x58, 0x0a, 0x4d, 0xf6, 0x89, 0x71,
+       0xab, 0x18, 0xbf, 0x9a, 0x72, 0xe7, 0x85, 0x74, 0x25, 0xe4, 0xbb, 0x07,
+       0x49, 0x97, 0x4b, 0x7a, 0x40, 0x5b, 0xd4, 0xca, 0xaf, 0xc9, 0x93, 0x05,
+       0x5f, 0x92, 0xb6, 0x17, 0x93, 0xa2, 0x6b, 0x25, 0x17, 0xc7, 0x07, 0xa5,
+       0x74, 0x14, 0xe5, 0x55, 0xc9, 0xd9, 0xe8, 0xbf, 0xe8, 0xca, 0xbc, 0x2e,
+       0x63, 0xde, 0x5b, 0xd8, 0xab, 0x29, 0x97, 0x42, 0xfb, 0x52, 0xf5, 0xdb,
+       0x78, 0x66, 0x7f, 0xff, 0xe0, 0x68, 0xba, 0x7f, 0x81, 0x77, 0xe6, 0xff,
+       0x7d, 0x9f, 0x7e, 0xe7, 0x33, 0xeb, 0x86, 0xe3, 0x86, 0xf3, 0xe5, 0xf8,
+       0xe3, 0x98, 0x33, 0x69, 0x08, 0xe7, 0x2c, 0xa5, 0x2e, 0xd0, 0xd2, 0x58,
+       0xeb, 0xb3, 0x36, 0xd6, 0x26, 0xe5, 0x64, 0xf5, 0x1e, 0xc9, 0xfb, 0x41,
+       0xb0, 0xe0, 0x4b, 0xdc, 0x96, 0x51, 0xb7, 0x80, 0x0a, 0xbb, 0x4d, 0xb1,
+       0x1a, 0x15, 0x89, 0xf6, 0x80, 0x2f, 0x3f, 0x59, 0x63, 0xdf, 0x0e, 0xf2,
+       0x86, 0x50, 0xbf, 0xdf, 0xda, 0x5c, 0x03, 0xfd, 0x59, 0xf2, 0x27, 0x08,
+       0x96, 0xfd, 0xd1, 0xc4, 0x22, 0xc6, 0x3c, 0xdf, 0x1c, 0x9d, 0xbe, 0x22,
+       0x2e, 0xfa, 0x1c, 0x44, 0x1d, 0xf2, 0x8a, 0x7d, 0xb1, 0x4f, 0xf6, 0xd7,
+       0x87, 0xb6, 0x71, 0x94, 0x91, 0xae, 0x20, 0xc8, 0xfb, 0x2e, 0xdf, 0x65,
+       0x07, 0xfc, 0xdb, 0x21, 0xff, 0x62, 0xc3, 0xf2, 0x4a, 0x93, 0x63, 0xec,
+       0x45, 0xfb, 0xc4, 0xff, 0x87, 0xb4, 0x27, 0xd0, 0x7f, 0x1c, 0xe9, 0x3e,
+       0xab, 0x51, 0x0b, 0x30, 0x7e, 0x02, 0xcf, 0x7b, 0xcd, 0xe3, 0xb2, 0x5a,
+       0xfb, 0x17, 0xb0, 0xf6, 0x6e, 0x36, 0x2e, 0x2f, 0x6e, 0x0f, 0x63, 0x1e,
+       0x09, 0xf9, 0x06, 0x64, 0x73, 0xe0, 0xce, 0x7d, 0x92, 0x86, 0x6c, 0x72,
+       0xcd, 0xa7, 0xd6, 0x1f, 0x95, 0x62, 0x3c, 0x35, 0x4e, 0x3d, 0x9a, 0x9f,
+       0xea, 0xc1, 0x7c, 0xb5, 0xb6, 0x1a, 0x59, 0x8d, 0x4b, 0x7a, 0x3d, 0x77,
+       0x83, 0x9e, 0x57, 0xdd, 0x92, 0x58, 0x49, 0xec, 0x73, 0x21, 0x6f, 0xc6,
+       0x4d, 0xbd, 0x96, 0x1c, 0x5b, 0xf6, 0x7a, 0x9f, 0x15, 0x59, 0x9f, 0x94,
+       0x13, 0x7b, 0xf0, 0xa4, 0x01, 0x9e, 0xd8, 0xab, 0xa1, 0x9c, 0x3b, 0x78,
+       0x1f, 0x42, 0xdd, 0x7e, 0xcb, 0x59, 0xbf, 0x9e, 0x1f, 0x1b, 0xcd, 0x51,
+       0x7f, 0x17, 0xfc, 0xb0, 0xd7, 0x07, 0x51, 0xe7, 0x7a, 0x7e, 0x34, 0xc0,
+       0x0f, 0x7b, 0x5d, 0xf3, 0xa2, 0x01, 0x5e, 0xd8, 0xa0, 0xb3, 0x01, 0x5e,
+       0xd8, 0xa7, 0x35, 0x2f, 0x1a, 0x66, 0x4f, 0x9c, 0x51, 0xfa, 0x28, 0x07,
+       0x5a, 0x2d, 0xd1, 0x3a, 0x29, 0x27, 0xd4, 0x3d, 0x91, 0xec, 0x0c, 0xf6,
+       0xb2, 0x8d, 0xb9, 0x3a, 0x32, 0x33, 0x65, 0xc9, 0x82, 0x2a, 0x9b, 0x91,
+       0x74, 0xf3, 0x5d, 0x60, 0xd4, 0xc4, 0x38, 0x2c, 0x41, 0xa9, 0x3b, 0xfb,
+       0x1d, 0x7b, 0xb7, 0x12, 0x95, 0x82, 0x93, 0x14, 0x6f, 0x95, 0xfd, 0xcc,
+       0xb7, 0xf5, 0x33, 0x8f, 0x7e, 0x76, 0xc1, 0x0f, 0x0b, 0xba, 0x93, 0x65,
+       0x8f, 0xaa, 0x7d, 0x9d, 0x5e, 0x77, 0x64, 0x74, 0x95, 0x75, 0x4a, 0xf6,
+       0x85, 0xe6, 0xaf, 0x02, 0xdd, 0xef, 0xa3, 0x1c, 0xd3, 0xb5, 0xb3, 0xcb,
+       0xf6, 0xf9, 0xcd, 0x53, 0xf6, 0xcb, 0x4d, 0xf4, 0xdb, 0x24, 0xaf, 0xb1,
+       0x16, 0x55, 0xac, 0x45, 0x15, 0xeb, 0x62, 0xf6, 0x6c, 0x5d, 0xed, 0x9d,
+       0xa4, 0x59, 0x37, 0xd2, 0xc0, 0xb5, 0x4b, 0x60, 0xcd, 0xb8, 0x76, 0x62,
+       0xbd, 0x9a, 0xd9, 0x27, 0x91, 0xd3, 0x11, 0xb5, 0x66, 0x03, 0xeb, 0x1f,
+       0x68, 0xad, 0xd9, 0xc8, 0xd4, 0x81, 0xd6, 0x9a, 0xd9, 0xab, 0xb9, 0x5b,
+       0x6c, 0x39, 0x24, 0x76, 0x16, 0xfc, 0xc9, 0x4c, 0x80, 0x5f, 0x11, 0x94,
+       0xc5, 0xc5, 0x59, 0xcf, 0x21, 0x2f, 0x95, 0x28, 0x82, 0x8f, 0x65, 0xf0,
+       0xb1, 0x28, 0x25, 0xc8, 0xcc, 0xcf, 0x2c, 0xad, 0xdf, 0x7e, 0x29, 0x46,
+       0xb6, 0xdf, 0x91, 0x5f, 0x23, 0xe0, 0x97, 0xf7, 0x3b, 0xf0, 0xcb, 0xd9,
+       0x93, 0x5f, 0xfd, 0x76, 0x27, 0xbf, 0x22, 0xe0, 0x57, 0xd7, 0xef, 0xcc,
+       0x2f, 0xf0, 0x61, 0x4f, 0x5e, 0x45, 0xa1, 0xd7, 0x4a, 0x92, 0xcf, 0x88,
+       0xe4, 0x6b, 0x5a, 0x17, 0x97, 0x94, 0x4e, 0xa6, 0x2e, 0x0a, 0x75, 0x32,
+       0xf5, 0xb1, 0xda, 0x07, 0x56, 0xa1, 0x92, 0x84, 0xae, 0x74, 0x90, 0x3e,
+       0x8f, 0x74, 0x9f, 0x35, 0x57, 0x83, 0x68, 0xf5, 0x07, 0xe2, 0x4e, 0x85,
+       0xf6, 0xb0, 0x94, 0x70, 0xb1, 0x36, 0xee, 0xfb, 0xba, 0x44, 0x86, 0x52,
+       0xe0, 0xd3, 0xcd, 0x28, 0x4f, 0x25, 0x72, 0x92, 0xb1, 0x43, 0xdc, 0x92,
+       0xaf, 0xf4, 0xbe, 0x95, 0x53, 0x4f, 0xcc, 0x67, 0xbb, 0x0c, 0xf2, 0xba,
+       0x64, 0x1e, 0x7a, 0x7e, 0xc6, 0xe3, 0x78, 0xec, 0x3f, 0x39, 0xcf, 0x71,
+       0x0b, 0xcd, 0x50, 0x27, 0x4b, 0x0e, 0x36, 0x1a, 0x65, 0xdc, 0x97, 0xd3,
+       0x56, 0x41, 0xdb, 0x46, 0xf1, 0x9a, 0xed, 0xf6, 0xa3, 0x45, 0x27, 0xf6,
+       0x6b, 0x8e, 0x72, 0x8d, 0xb1, 0x93, 0xd8, 0x73, 0xe5, 0x48, 0xb8, 0x3e,
+       0x4e, 0x76, 0x5a, 0x60, 0x77, 0xa5, 0x5c, 0x61, 0x7f, 0x9f, 0xb1, 0x22,
+       0xe7, 0xc2, 0xfe, 0xc9, 0x47, 0xf6, 0xad, 0xfb, 0x2b, 0x37, 0xdf, 0x30,
+       0x7b, 0x5f, 0xd9, 0x22, 0xf4, 0x57, 0x6a, 0xeb, 0xaf, 0x64, 0x45, 0x56,
+       0xe5, 0x80, 0xd2, 0xf7, 0x47, 0xc9, 0xbf, 0x53, 0x28, 0xbb, 0x2c, 0x11,
+       0xca, 0x8c, 0xda, 0x63, 0xdc, 0xe7, 0x9f, 0xe5, 0x7c, 0xdb, 0x78, 0x3b,
+       0x07, 0x1b, 0xc6, 0xfd, 0x85, 0x35, 0x8e, 0x33, 0xff, 0x2e, 0x43, 0x93,
+       0x23, 0x39, 0xf5, 0xfe, 0xb5, 0x7d, 0xa1, 0x7e, 0xc4, 0x7e, 0x06, 0x6d,
+       0xdf, 0x51, 0x73, 0xb4, 0xb3, 0x59, 0xf0, 0xa6, 0x9d, 0x46, 0x85, 0x05,
+       0xb0, 0xc6, 0xa1, 0x8e, 0x0a, 0xd7, 0x8a, 0xb8, 0xc5, 0xb1, 0x96, 0x2a,
+       0x7d, 0xb0, 0x7f, 0x51, 0x63, 0x63, 0xd9, 0x7e, 0x19, 0xed, 0x99, 0xcf,
+       0xb6, 0x7d, 0xb0, 0xb7, 0x6c, 0xbf, 0x6c, 0xda, 0x5f, 0xb5, 0xbb, 0xdc,
+       0x2b, 0xb4, 0xb9, 0x17, 0x32, 0xc0, 0x3a, 0x6b, 0xb6, 0x14, 0x7c, 0xe0,
+       0x18, 0x7f, 0xd8, 0xec, 0x0b, 0x2d, 0x9b, 0xf7, 0x3a, 0x96, 0xf4, 0x78,
+       0x7b, 0xc9, 0xe6, 0xcb, 0xb6, 0xb6, 0x65, 0x57, 0x65, 0x73, 0x09, 0x3a,
+       0xea, 0x04, 0x64, 0x65, 0xb9, 0x55, 0x8f, 0x72, 0xa9, 0x64, 0x14, 0xb2,
+       0x99, 0x9a, 0xe6, 0x34, 0x2f, 0x34, 0xdb, 0x65, 0x34, 0xec, 0x23, 0xaa,
+       0xe4, 0x40, 0x8f, 0xb3, 0xdc, 0x36, 0xce, 0x72, 0xdb, 0x38, 0x27, 0x0d,
+       0x76, 0x63, 0x3f, 0xda, 0x6e, 0x5e, 0xbe, 0xc6, 0x5e, 0x73, 0xcd, 0x3e,
+       0x8a, 0x3d, 0xa9, 0x65, 0x01, 0x58, 0x4c, 0xaf, 0x41, 0xc5, 0x95, 0xf2,
+       0xf6, 0xd9, 0x70, 0xaf, 0x96, 0x7a, 0x90, 0xff, 0x53, 0xe4, 0x8f, 0xaf,
+       0xb8, 0xb0, 0x43, 0xc4, 0x62, 0x7f, 0x25, 0x5b, 0x15, 0xca, 0xc8, 0x77,
+       0x40, 0x77, 0xda, 0xef, 0xb6, 0xc8, 0xd7, 0xd4, 0xf8, 0x19, 0x49, 0x25,
+       0xcb, 0x32, 0xe1, 0x33, 0x3d, 0x49, 0x45, 0x8d, 0x7a, 0x1a, 0xe3, 0x7c,
+       0x07, 0xf2, 0x27, 0xf2, 0x66, 0xa5, 0x47, 0xec, 0xa9, 0x9f, 0x06, 0xb4,
+       0x73, 0xa7, 0xb6, 0x3b, 0xfb, 0x11, 0x19, 0x5b, 0x51, 0xfd, 0xa0, 0x8f,
+       0xb4, 0x7f, 0x49, 0xf5, 0x17, 0xf6, 0x85, 0x79, 0x4e, 0x75, 0xf6, 0xe7,
+       0xc8, 0x65, 0xd7, 0x46, 0x7f, 0xb7, 0x98, 0x39, 0xf2, 0x19, 0x32, 0xe2,
+       0x3a, 0x48, 0xef, 0xb3, 0x43, 0x99, 0xb1, 0xa7, 0xfe, 0x3a, 0xc8, 0xcd,
+       0x71, 0x6e, 0xff, 0xcc, 0xe4, 0xfd, 0x47, 0x23, 0x6f, 0x52, 0xb3, 0xb3,
+       0xe0, 0x59, 0x66, 0x14, 0xe3, 0xf1, 0x3d, 0x09, 0xfc, 0x23, 0x25, 0xe2,
+       0xaf, 0x62, 0xe5, 0x37, 0x41, 0xce, 0xd1, 0x98, 0x49, 0xaf, 0x3d, 0xcb,
+       0x2d, 0x29, 0xa0, 0xee, 0x92, 0xd1, 0x07, 0x33, 0xcd, 0xcb, 0x8a, 0x7f,
+       0x2f, 0xaa, 0x7d, 0x94, 0x3a, 0x55, 0xa2, 0xde, 0xd8, 0x8e, 0x46, 0xb8,
+       0xc7, 0x5f, 0xf0, 0x37, 0x83, 0xa5, 0x6a, 0x2a, 0x99, 0xb4, 0x47, 0xa5,
+       0x58, 0x1b, 0x2d, 0xd9, 0x48, 0x9f, 0xac, 0x27, 0xe4, 0xc9, 0x0a, 0xfb,
+       0xb9, 0x01, 0x75, 0xa0, 0x88, 0x6c, 0x6c, 0xf2, 0x21, 0xea, 0x1a, 0x8e,
+       0xf9, 0x96, 0xa5, 0xc7, 0xc4, 0x1c, 0xbc, 0x1d, 0xeb, 0x93, 0xcd, 0x0b,
+       0x56, 0xb1, 0xce, 0xf5, 0x47, 0x7e, 0xb3, 0x5d, 0x1f, 0xb5, 0xeb, 0xed,
+       0x50, 0x5f, 0xeb, 0xb5, 0x73, 0xb0, 0xef, 0x6a, 0x95, 0x65, 0xab, 0xbc,
+       0x26, 0x76, 0xde, 0xef, 0x32, 0xf2, 0x68, 0xb9, 0x7a, 0xce, 0x4f, 0x46,
+       0xa8, 0x13, 0x23, 0xde, 0x29, 0xab, 0x5c, 0xb9, 0x55, 0x72, 0x0e, 0x31,
+       0x1c, 0x9f, 0x25, 0x88, 0x64, 0x3d, 0xda, 0x4d, 0x27, 0x92, 0x4d, 0x63,
+       0xbf, 0xb1, 0xce, 0x66, 0xf0, 0x65, 0x8c, 0x33, 0x72, 0x1a, 0xfa, 0xd9,
+       0x7f, 0x0f, 0xfa, 0xe1, 0xf8, 0xbd, 0x78, 0x77, 0xcc, 0xbe, 0xec, 0x42,
+       0xbd, 0x14, 0x36, 0xf7, 0xc5, 0x7e, 0xe9, 0x7f, 0x06, 0x7a, 0x36, 0xec,
+       0x9b, 0x75, 0x12, 0xa6, 0x4e, 0x9f, 0xa9, 0x73, 0x37, 0xca, 0x3f, 0x86,
+       0x7a, 0x29, 0x9f, 0xd0, 0x16, 0x29, 0xf2, 0x06, 0x31, 0x47, 0xd4, 0x6d,
+       0xdc, 0x60, 0xde, 0xc3, 0xf6, 0x77, 0xb6, 0xd5, 0xe5, 0xfb, 0xb5, 0x7a,
+       0x78, 0xbe, 0xa5, 0x87, 0xc9, 0xc3, 0x1c, 0xf4, 0x9e, 0xd8, 0xd8, 0xf7,
+       0x6e, 0x24, 0xcb, 0xfc, 0x69, 0x3c, 0x3f, 0x1f, 0x94, 0xab, 0xd4, 0xfb,
+       0xc0, 0xc1, 0x75, 0xa5, 0xff, 0xd0, 0x6f, 0xce, 0x9a, 0xa9, 0x84, 0xeb,
+       0xc4, 0x79, 0x85, 0xb8, 0x44, 0xf1, 0x0c, 0xf4, 0x26, 0xaf, 0xd2, 0xeb,
+       0x2a, 0x99, 0x40, 0x9e, 0x6f, 0xf2, 0x7a, 0xda, 0xf2, 0x42, 0x9d, 0xf4,
+       0x05, 0xcc, 0x6b, 0x58, 0xad, 0x99, 0x9d, 0x3d, 0x62, 0xe5, 0x15, 0x26,
+       0x0a, 0x82, 0x82, 0xd7, 0x25, 0xc5, 0xc9, 0xa7, 0xc1, 0x2b, 0x96, 0x95,
+       0xdc, 0x88, 0xc2, 0xf1, 0x73, 0x0f, 0x2c, 0x78, 0x29, 0x85, 0x49, 0xf2,
+       0xd0, 0x09, 0x5a, 0x8f, 0x4b, 0x69, 0x00, 0xb4, 0x7b, 0xab, 0xe4, 0xc5,
+       0x66, 0x70, 0x1a, 0xf8, 0x7b, 0x6e, 0x75, 0xc6, 0x1a, 0x59, 0xc5, 0xba,
+       0x0f, 0x59, 0xe0, 0x4b, 0x9f, 0xe4, 0xcf, 0x91, 0x2f, 0xac, 0xc3, 0xfc,
+       0x6e, 0x99, 0x8b, 0x77, 0xda, 0xef, 0x3f, 0x3e, 0x20, 0x31, 0xf2, 0x01,
+       0x75, 0x57, 0x21, 0xec, 0x31, 0x8d, 0x89, 0x47, 0xd6, 0x29, 0x47, 0x33,
+       0xd6, 0x42, 0x85, 0xba, 0xb5, 0x17, 0x36, 0x5b, 0xad, 0x3f, 0xfa, 0x44,
+       0xd9, 0x99, 0xce, 0x3e, 0x3e, 0x1d, 0xd1, 0x7d, 0xb0, 0x5d, 0xd8, 0x47,
+       0x3b, 0x3f, 0xf6, 0x29, 0xdd, 0x3b, 0x98, 0x1d, 0xec, 0xe8, 0x37, 0xd1,
+       0xd6, 0x2f, 0xca, 0xce, 0xfc, 0x34, 0x42, 0x2c, 0xf8, 0x52, 0x15, 0x7c,
+       0x56, 0x73, 0x62, 0x19, 0xdb, 0xcc, 0x58, 0x85, 0xd5, 0x20, 0x98, 0xf3,
+       0x6d, 0x89, 0x0c, 0x85, 0x75, 0xf5, 0xbc, 0x66, 0x30, 0xaf, 0x3c, 0xe6,
+       0x65, 0x0f, 0x75, 0xd2, 0xf4, 0x39, 0x43, 0xd3, 0x60, 0x1b, 0x4d, 0xf1,
+       0x77, 0x98, 0x57, 0x7c, 0x8f, 0x79, 0x9d, 0x1c, 0xd4, 0x7d, 0xc4, 0xdb,
+       0xfa, 0x18, 0xea, 0xe8, 0x03, 0xb6, 0x28, 0xce, 0xf6, 0x43, 0x7b, 0xb4,
+       0xff, 0x49, 0xaf, 0x6e, 0xcf, 0x36, 0xdd, 0xb0, 0x37, 0xc3, 0x46, 0x57,
+       0x3f, 0xd9, 0xa6, 0x5f, 0x9f, 0x84, 0x7e, 0x6d, 0x6f, 0x13, 0xca, 0x65,
+       0xbb, 0x5f, 0x46, 0x9f, 0x2c, 0xc4, 0xaf, 0xef, 0x52, 0xb8, 0xe8, 0x2a,
+       0xae, 0x8f, 0x02, 0x23, 0xf5, 0x01, 0x93, 0xf4, 0xd3, 0xf7, 0x32, 0x38,
+       0x95, 0xbe, 0x18, 0xb1, 0xa9, 0x78, 0x40, 0x76, 0xd0, 0x77, 0xa3, 0x89,
+       0x63, 0x22, 0xca, 0xf7, 0x22, 0xa6, 0xa7, 0x1f, 0xc6, 0x71, 0xe8, 0x87,
+       0x71, 0xdd, 0xf9, 0x5e, 0x68, 0xf9, 0x65, 0xc3, 0xd0, 0x45, 0xc4, 0xe4,
+       0xc4, 0xaf, 0xa1, 0xfd, 0x6b, 0xd7, 0xf1, 0x7b, 0xd1, 0x34, 0xdc, 0x41,
+       0x13, 0xf4, 0x24, 0xfc, 0xc1, 0x25, 0xc8, 0x23, 0x70, 0x32, 0xf4, 0xf2,
+       0xd3, 0xb3, 0x5b, 0x6b, 0x22, 0xc5, 0x26, 0x6d, 0xf6, 0xa4, 0xc0, 0x97,
+       0x03, 0x5d, 0xec, 0x5b, 0xd9, 0x6d, 0xe8, 0xcb, 0xfe, 0x9c, 0x9d, 0x1d,
+       0x85, 0xef, 0xef, 0xc8, 0xa2, 0xa1, 0x6d, 0x5e, 0xf9, 0x8d, 0x7d, 0x48,
+       0x13, 0x4a, 0xae, 0xe6, 0x41, 0x1f, 0x9f, 0xe7, 0x8d, 0xbf, 0x70, 0xac,
+       0xd9, 0x49, 0xdb, 0x0f, 0x41, 0x9b, 0x07, 0x1a, 0x92, 0xf2, 0x2d, 0xf8,
+       0x0b, 0xdf, 0x54, 0xfb, 0x32, 0xd4, 0x67, 0x4a, 0x57, 0xd4, 0x4a, 0xf2,
+       0x7c, 0xb0, 0x56, 0xe5, 0xbe, 0x25, 0xae, 0xe8, 0x93, 0x12, 0xd6, 0x6b,
+       0x64, 0x35, 0x95, 0xcc, 0xd9, 0x62, 0xdd, 0x70, 0x27, 0xe5, 0xe9, 0x09,
+       0x19, 0x39, 0x27, 0x96, 0xb3, 0x8a, 0xbd, 0xde, 0x1f, 0x62, 0x3e, 0xce,
+       0xef, 0xdd, 0x98, 0x1f, 0xfa, 0xae, 0x86, 0xf3, 0xeb, 0x93, 0xe2, 0x3a,
+       0xe7, 0xd7, 0x9a, 0x5b, 0x9c, 0x51, 0x98, 0xa7, 0x60, 0x43, 0x30, 0x47,
+       0xd0, 0x38, 0x0d, 0xec, 0xfd, 0x1e, 0x33, 0xa7, 0x3e, 0xcc, 0x09, 0xb8,
+       0x61, 0x95, 0xed, 0x41, 0x17, 0x68, 0x2e, 0xa2, 0x5e, 0x79, 0x95, 0x6b,
+       0x0e, 0x5a, 0xb1, 0xee, 0xc5, 0x26, 0xd7, 0x9e, 0x73, 0xd3, 0x58, 0xc3,
+       0xf1, 0x38, 0x3f, 0xce, 0x73, 0x1c, 0xf3, 0x62, 0x1d, 0xb6, 0xeb, 0x94,
+       0x91, 0xf1, 0x77, 0x58, 0x8f, 0x77, 0x77, 0xac, 0x87, 0x98, 0xf5, 0x88,
+       0x4a, 0xf7, 0xba, 0xf2, 0xd1, 0x15, 0x0d, 0xf4, 0x6b, 0x1c, 0xd0, 0xbf,
+       0xbc, 0x26, 0x93, 0x0c, 0x60, 0xd1, 0x36, 0x20, 0x2f, 0xd3, 0x2d, 0xa3,
+       0xfe, 0x05, 0xc8, 0x55, 0x11, 0xb2, 0x40, 0x1f, 0xe5, 0xa5, 0xaa, 0x5e,
+       0x8b, 0x62, 0x33, 0x26, 0xf6, 0x69, 0x8e, 0x4f, 0x7e, 0x73, 0x6e, 0xae,
+       0x5a, 0x87, 0xf6, 0x75, 0x79, 0xec, 0xba, 0x75, 0xd9, 0x84, 0x1e, 0xa5,
+       0x1e, 0x20, 0x16, 0xa3, 0x2e, 0x08, 0xe3, 0x10, 0x7f, 0xe4, 0xea, 0xfd,
+       0x14, 0xda, 0xc4, 0xcb, 0x2d, 0xcc, 0xfb, 0xa2, 0xf2, 0x1d, 0xf4, 0x9c,
+       0xf2, 0x19, 0xe8, 0xa5, 0xb5, 0x1b, 0xb0, 0x77, 0x68, 0x13, 0x37, 0x83,
+       0x5a, 0xb5, 0x4b, 0xd1, 0x90, 0xf7, 0xfb, 0x89, 0xdf, 0x44, 0xdb, 0x01,
+       0xa6, 0xcc, 0xa7, 0x8d, 0x44, 0x59, 0x86, 0x6b, 0x89, 0xf7, 0x06, 0xdf,
+       0xdb, 0xf5, 0xfe, 0x7f, 0x72, 0xf4, 0x7e, 0x64, 0xec, 0x69, 0x2f, 0x3b,
+       0x78, 0x35, 0xe6, 0xe0, 0xc0, 0x57, 0x2e, 0xaf, 0x05, 0xc0, 0x63, 0xef,
+       0xc1, 0xde, 0xce, 0x49, 0xd1, 0x85, 0x1d, 0x1f, 0xbf, 0x19, 0x7c, 0x9d,
+       0x16, 0x15, 0x67, 0x18, 0xdf, 0x8f, 0xe7, 0x7d, 0xca, 0xa7, 0x29, 0x8e,
+       0xbf, 0x57, 0x72, 0x73, 0xc4, 0x43, 0x8f, 0xcb, 0x3c, 0x6c, 0x6e, 0x71,
+       0x1c, 0x36, 0x31, 0xce, 0x77, 0xe8, 0x25, 0x6f, 0x8c, 0xb1, 0x09, 0xfc,
+       0xfd, 0x1b, 0x13, 0x93, 0x39, 0x88, 0xf7, 0x7d, 0xa8, 0xf3, 0x31, 0x53,
+       0xa7, 0x7f, 0x8f, 0x3a, 0x79, 0xbc, 0xdf, 0x8d, 0x3a, 0x31, 0x8c, 0x01,
+       0x4c, 0x0b, 0x5b, 0x66, 0x7b, 0x1f, 0x46, 0xde, 0x5d, 0xc8, 0xbb, 0x0b,
+       0x79, 0x77, 0xe0, 0xbd, 0x60, 0x62, 0x1d, 0x61, 0x9b, 0x7e, 0xbc, 0x7f,
+       0x01, 0xe5, 0xd0, 0x33, 0xee, 0x25, 0x94, 0xdf, 0xad, 0xda, 0x5d, 0x5b,
+       0x67, 0xb0, 0xe3, 0x7d, 0xcb, 0xd1, 0xb1, 0x11, 0xe6, 0x0d, 0x9b, 0x67,
+       0xb1, 0x96, 0x2b, 0x7c, 0xff, 0xa1, 0x79, 0xbf, 0xb7, 0x23, 0xff, 0x71,
+       0xf3, 0xde, 0xb9, 0xae, 0xb7, 0x61, 0x5d, 0x59, 0xfe, 0xd1, 0x03, 0x7a,
+       0x3d, 0xc6, 0x74, 0xfc, 0xe1, 0x1a, 0x3c, 0xa2, 0x44, 0x11, 0xcf, 0x3b,
+       0xc0, 0x21, 0xc4, 0x26, 0xed, 0xb8, 0x84, 0x34, 0xa9, 0xfa, 0x66, 0x9c,
+       0xe7, 0xfa, 0xc3, 0x71, 0xcb, 0x90, 0x81, 0xc3, 0x6b, 0x61, 0xfe, 0xc5,
+       0xfe, 0x6b, 0xe9, 0xf9, 0x9f, 0x6d, 0xf5, 0xf6, 0xcb, 0xe1, 0x5a, 0x98,
+       0x7f, 0xe8, 0xc0, 0xb5, 0xf5, 0x6e, 0x3e, 0x70, 0x75, 0xae, 0xad, 0x78,
+       0x09, 0x68, 0xfb, 0x8c, 0x7d, 0x15, 0x2b, 0xe5, 0xec, 0xc5, 0xe6, 0x8c,
+       0xad, 0x69, 0x62, 0x1d, 0x94, 0x35, 0x77, 0x06, 0x1c, 0x25, 0xa3, 0x39,
+       0x9b, 0x7e, 0x4a, 0x69, 0x83, 0xcf, 0x37, 0x23, 0x6d, 0x6f, 0x3b, 0x0c,
+       0x7d, 0x9b, 0xb3, 0xf5, 0x9c, 0x3a, 0xdb, 0x87, 0xf2, 0xed, 0xcb, 0x52,
+       0x0d, 0x32, 0xe9, 0xa5, 0xc6, 0x4b, 0xf0, 0x73, 0x17, 0xfc, 0xd4, 0x1c,
+       0x65, 0x16, 0xbe, 0xf0, 0x23, 0x22, 0xb3, 0x52, 0xae, 0x3d, 0x08, 0xec,
+       0x1e, 0xc8, 0x87, 0x60, 0xff, 0xff, 0x25, 0xf0, 0x43, 0x1d, 0xba, 0xa0,
+       0xde, 0xf4, 0xf0, 0x1b, 0x96, 0xaf, 0x57, 0x12, 0xf2, 0x3c, 0x7c, 0x91,
+       0xc6, 0x1a, 0xf5, 0x65, 0xda, 0xfd, 0x90, 0xc8, 0x80, 0x2d, 0xe7, 0xef,
+       0xb2, 0x65, 0x22, 0x39, 0x62, 0xa5, 0x13, 0xf8, 0xb9, 0xdd, 0xf8, 0xcd,
+       0xc0, 0xff, 0xdb, 0x68, 0x32, 0x8e, 0x10, 0x97, 0x3f, 0xdf, 0x4c, 0xe2,
+       0x37, 0x24, 0xff, 0x7e, 0x93, 0xe3, 0x8f, 0x98, 0x34, 0xf4, 0x4d, 0xbe,
+       0x05, 0x1d, 0x71, 0x29, 0x58, 0xae, 0x32, 0x26, 0x14, 0xda, 0xa1, 0x6f,
+       0x29, 0x3b, 0xb4, 0x54, 0x09, 0x8e, 0x6b, 0x1f, 0xdc, 0x83, 0xcf, 0x8d,
+       0xf7, 0xe6, 0x5b, 0x56, 0xa3, 0x35, 0xc7, 0x1d, 0xab, 0x61, 0xd6, 0xad,
+       0xd1, 0x9a, 0x23, 0xca, 0x9b, 0x17, 0x20, 0x0b, 0xd4, 0xbf, 0xa1, 0xee,
+       0xf5, 0x0c, 0x2e, 0x0a, 0xf5, 0x2f, 0xf6, 0x70, 0x4d, 0xa2, 0xf1, 0xec,
+       0x2f, 0x64, 0xed, 0x34, 0xf7, 0x14, 0xed, 0xe5, 0x34, 0x64, 0x31, 0xf5,
+       0x95, 0x12, 0x71, 0xb6, 0xc7, 0x98, 0xc0, 0x25, 0xf4, 0x31, 0x3f, 0xa8,
+       0x65, 0xe7, 0x12, 0xf6, 0xf9, 0xac, 0x38, 0xa7, 0x3f, 0xdf, 0x25, 0xfd,
+       0xc7, 0x65, 0xd9, 0x87, 0x3f, 0x6b, 0x97, 0x82, 0x88, 0xe7, 0x25, 0x0a,
+       0xca, 0xdf, 0x5a, 0x03, 0x5d, 0xdf, 0x03, 0x26, 0x3e, 0xae, 0xfc, 0xba,
+       0x63, 0x35, 0xd6, 0xed, 0xc6, 0x7a, 0xa4, 0x4a, 0x05, 0xac, 0xd5, 0x89,
+       0xf8, 0x05, 0x94, 0x05, 0x81, 0xed, 0x0d, 0x48, 0xb1, 0x1e, 0x3e, 0x43,
+       0xf6, 0x37, 0xff, 0x01, 0x32, 0xc6, 0x67, 0xc0, 0xc4, 0x75, 0x96, 0x8d,
+       0x20, 0x65, 0x39, 0xcb, 0x3c, 0xa5, 0xeb, 0x8a, 0x4d, 0xd2, 0x31, 0x2b,
+       0x85, 0x1a, 0xe7, 0x04, 0xbb, 0x58, 0xbf, 0x14, 0x9c, 0xa8, 0x5e, 0x00,
+       0xaf, 0x38, 0x5e, 0x56, 0x1a, 0x58, 0x8b, 0x72, 0xf3, 0x71, 0x60, 0xfa,
+       0xd7, 0x91, 0x2e, 0x22, 0xbd, 0x8c, 0xf4, 0x09, 0xa4, 0x6f, 0x20, 0xe5,
+       0xbc, 0x1e, 0x97, 0x46, 0x3d, 0xd1, 0x2d, 0x31, 0xf6, 0xf3, 0xd9, 0xd6,
+       0x7c, 0xca, 0xd0, 0x0d, 0xb9, 0x56, 0x3e, 0x9f, 0x99, 0x7e, 0x02, 0xe9,
+       0x47, 0x91, 0xf7, 0x3d, 0x3c, 0x4f, 0x4b, 0xa1, 0xf2, 0x04, 0xec, 0x30,
+       0xb1, 0xea, 0x27, 0x30, 0x2e, 0xc7, 0x7f, 0x19, 0x74, 0xb0, 0x2c, 0x90,
+       0x4f, 0x62, 0x9e, 0xf9, 0xda, 0x71, 0x79, 0xd8, 0xbf, 0x45, 0xa6, 0x1e,
+       0x26, 0x3d, 0xe4, 0x0d, 0xf5, 0xdb, 0x5e, 0xbc, 0x21, 0x5f, 0x42, 0x7e,
+       0xf4, 0x61, 0x5e, 0xd4, 0x55, 0xc4, 0xc6, 0x10, 0xc0, 0x7e, 0x8d, 0x77,
+       0x46, 0xc6, 0x02, 0x79, 0xc8, 0xcf, 0x4a, 0xe4, 0xf4, 0x98, 0x9b, 0xb1,
+       0x27, 0xe0, 0xf9, 0xa4, 0xf1, 0x3b, 0x0e, 0xb9, 0xf4, 0x4e, 0x8d, 0xd8,
+       0x23, 0xa0, 0x09, 0x65, 0x0d, 0x8e, 0x73, 0x29, 0xf8, 0x93, 0xea, 0xab,
+       0xf0, 0xdb, 0xb3, 0x72, 0xa5, 0xf9, 0x2a, 0xe4, 0x83, 0xf4, 0x08, 0xe8,
+       0x9c, 0x95, 0x1f, 0xd7, 0x5e, 0x96, 0x93, 0xe0, 0xfd, 0x6b, 0x48, 0x97,
+       0x6b, 0x25, 0xf0, 0x95, 0xf1, 0x7b, 0xf6, 0x11, 0x60, 0xcd, 0x46, 0xe1,
+       0x6f, 0xdd, 0x96, 0x58, 0xc4, 0xfa, 0xce, 0xbb, 0x81, 0x6c, 0xf9, 0x25,
+       0xd9, 0x9a, 0x46, 0x9b, 0x3a, 0xdb, 0xf7, 0xca, 0x61, 0x95, 0x52, 0xfe,
+       0xfa, 0x31, 0xc7, 0x98, 0xe2, 0xf3, 0x72, 0x35, 0x94, 0x3d, 0xca, 0x61,
+       0xa7, 0xfc, 0x91, 0xee, 0x1d, 0xeb, 0x9b, 0x4d, 0xda, 0xd1, 0xbd, 0x6c,
+       0x62, 0x28, 0x97, 0xb4, 0x8b, 0xed, 0xb2, 0x29, 0xd2, 0xa8, 0x69, 0xff,
+       0xe6, 0x1b, 0xdb, 0x4a, 0xd6, 0xb1, 0x3e, 0xc4, 0xd3, 0x3f, 0x17, 0xe0,
+       0x37, 0xf0, 0x29, 0x8c, 0x2f, 0x6a, 0xbf, 0xab, 0x0e, 0x7a, 0xe1, 0x6b,
+       0x00, 0x2b, 0x88, 0xd4, 0xeb, 0x9f, 0x57, 0xfc, 0xf2, 0x4e, 0x0f, 0x4b,
+       0xad, 0x4a, 0x1e, 0xa7, 0x5c, 0xdb, 0x56, 0xfe, 0x0d, 0x78, 0xeb, 0x41,
+       0x56, 0xc2, 0xf2, 0x14, 0xfc, 0xaf, 0xe3, 0xe2, 0x4e, 0xc5, 0x60, 0xbf,
+       0xf8, 0x2c, 0x32, 0x77, 0xae, 0x13, 0x0b, 0x86, 0x36, 0xa6, 0x1b, 0x7e,
+       0x7e, 0x17, 0x74, 0x41, 0x1f, 0xfc, 0x74, 0xf8, 0xbf, 0x90, 0xa7, 0x3f,
+       0x01, 0x7e, 0x3a, 0xa5, 0x7c, 0x76, 0xee, 0xc3, 0x07, 0x67, 0x47, 0x36,
+       0x99, 0x7e, 0x78, 0x36, 0x5d, 0x67, 0x7a, 0xd4, 0xc4, 0xf5, 0x1f, 0x31,
+       0xf1, 0xfe, 0xf9, 0xd9, 0x83, 0x2a, 0x5d, 0x9c, 0x1d, 0x57, 0xe9, 0xe3,
+       0xb3, 0x57, 0x63, 0x31, 0x17, 0x20, 0xab, 0xa4, 0x4d, 0x9c, 0x62, 0x26,
+       0x23, 0x9b, 0x15, 0x1f, 0x7e, 0xf7, 0x34, 0xf0, 0xc7, 0x34, 0xe4, 0x36,
+       0x0b, 0x7a, 0xa1, 0x7f, 0xb2, 0x3e, 0x52, 0x31, 0x7f, 0x61, 0xbb, 0x6e,
+       0xc6, 0xdd, 0xb8, 0x66, 0xc6, 0x77, 0xf5, 0xe9, 0xbb, 0xb6, 0xff, 0xb1,
+       0x4f, 0xc8, 0x38, 0xed, 0xee, 0xaf, 0xe1, 0x6f, 0xb3, 0x7f, 0xb6, 0x65,
+       0xff, 0x22, 0xbb, 0x6b, 0x12, 0x8d, 0x66, 0xff, 0x5a, 0xa2, 0xcf, 0x06,
+       0xc1, 0x4f, 0xfc, 0xd4, 0x91, 0x92, 0x80, 0x4f, 0x16, 0xf2, 0x37, 0x59,
+       0x46, 0x9d, 0x35, 0xe1, 0x5e, 0x81, 0xcc, 0xe5, 0x8e, 0x8a, 0xbc, 0x82,
+       0xbc, 0xc6, 0x1a, 0xf9, 0xff, 0x3d, 0xf0, 0xdf, 0xac, 0x87, 0xca, 0x63,
+       0x3d, 0xf8, 0x48, 0x71, 0xca, 0xdc, 0x84, 0xdb, 0x83, 0xf6, 0xf5, 0x4d,
+       0xb6, 0x49, 0x4d, 0xf3, 0x98, 0xec, 0x95, 0xcd, 0x0b, 0x4a, 0x5f, 0x75,
+       0x67, 0xc7, 0x19, 0x43, 0x92, 0x8d, 0xb5, 0xdf, 0x04, 0x0b, 0xfe, 0x0e,
+       0x80, 0x5a, 0x0a, 0x72, 0x9f, 0x95, 0xf3, 0xc0, 0x58, 0xe7, 0x2b, 0x69,
+       0xac, 0x0d, 0xf0, 0x6d, 0x82, 0x24, 0x7b, 0xa8, 0xf7, 0x66, 0x37, 0x71,
+       0x6c, 0x9e, 0xe7, 0x47, 0x95, 0x69, 0xd9, 0x6d, 0xce, 0x09, 0xb1, 0x52,
+       0x3e, 0xc3, 0xf9, 0xb4, 0xf3, 0x41, 0xff, 0x15, 0xb1, 0x06, 0x66, 0x7e,
+       0xea, 0x0f, 0x74, 0x62, 0x3f, 0xa1, 0xbd, 0xbf, 0x83, 0xbd, 0x91, 0x82,
+       0x7e, 0x15, 0x07, 0x7e, 0xa2, 0xa4, 0xcf, 0x3a, 0x4e, 0xbe, 0xe2, 0xc8,
+       0xc8, 0x59, 0x6c, 0xa9, 0xac, 0xe1, 0x43, 0x33, 0x94, 0xb1, 0x50, 0xe7,
+       0x51, 0xa6, 0x38, 0xff, 0x54, 0x69, 0x07, 0x8c, 0x1e, 0xcc, 0x5e, 0x94,
+       0x87, 0xd7, 0xf5, 0x7c, 0xed, 0x33, 0xc2, 0xb3, 0x13, 0xb9, 0xb2, 0x96,
+       0xf2, 0x2f, 0x0b, 0xfd, 0x5f, 0x1f, 0x32, 0x72, 0xb1, 0x1b, 0xfb, 0x79,
+       0x3a, 0x67, 0x1f, 0xec, 0xd1, 0xb6, 0xd9, 0xc1, 0x1e, 0x00, 0x4e, 0xac,
+       0xc0, 0x6f, 0xf6, 0x7a, 0xe4, 0x5f, 0x38, 0x78, 0x26, 0x6e, 0x44, 0x9e,
+       0xb1, 0xa3, 0x78, 0xd6, 0xfd, 0x95, 0x31, 0x0f, 0x1d, 0x57, 0xb6, 0xe4,
+       0x61, 0x58, 0x15, 0x41, 0xff, 0x23, 0x66, 0xac, 0x91, 0x33, 0x17, 0xd4,
+       0x7e, 0x4d, 0xaf, 0x67, 0x81, 0xa3, 0x1c, 0xe3, 0x6f, 0x52, 0x4f, 0xc9,
+       0x1e, 0xfe, 0x4a, 0x28, 0xa3, 0x17, 0x82, 0x2f, 0x56, 0xc3, 0x98, 0x40,
+       0x46, 0x46, 0x56, 0xb4, 0x4c, 0x3d, 0x9e, 0x81, 0xce, 0x86, 0x2c, 0x8d,
+       0xac, 0x04, 0xf2, 0x13, 0xdf, 0x97, 0x53, 0xdb, 0x7b, 0xc9, 0x54, 0xe7,
+       0x5f, 0x1f, 0xe8, 0xe4, 0x6f, 0x48, 0x96, 0xfe, 0x14, 0x74, 0x9e, 0x75,
+       0xf1, 0x9c, 0x9a, 0x9b, 0xa7, 0x8f, 0x70, 0x16, 0xba, 0x14, 0xbe, 0xac,
+       0x7d, 0x76, 0x58, 0xd5, 0xb1, 0xcf, 0xc2, 0xc6, 0x41, 0xc6, 0x6c, 0xf0,
+       0xb5, 0x0c, 0x7b, 0x67, 0x9f, 0xed, 0x82, 0x5d, 0xe4, 0x1e, 0x95, 0x41,
+       0x1b, 0xba, 0x80, 0xf5, 0x1b, 0xd8, 0x2b, 0xf6, 0xd9, 0x3e, 0xa4, 0x49,
+       0xd5, 0x57, 0xa3, 0xe2, 0xa9, 0xf6, 0x8d, 0xca, 0xb8, 0x6a, 0xd7, 0xa8,
+       0x4c, 0x22, 0x85, 0x8e, 0xcf, 0xf8, 0xd2, 0x7d, 0x36, 0x23, 0x72, 0xd6,
+       0x92, 0xe2, 0x5c, 0x10, 0xc4, 0x40, 0x7b, 0xec, 0xec, 0x01, 0xb9, 0xac,
+       0xd6, 0x76, 0x4e, 0x46, 0x9e, 0x25, 0xbf, 0xb2, 0xa8, 0x3b, 0x23, 0xe9,
+       0x67, 0x67, 0xc4, 0x7b, 0x96, 0x3c, 0x61, 0xac, 0x7e, 0x57, 0xc9, 0xd4,
+       0x27, 0xe4, 0x28, 0xec, 0x4a, 0x0f, 0xf6, 0x84, 0xe3, 0x96, 0x65, 0x05,
+       0x6b, 0x32, 0xea, 0x1e, 0x86, 0x9c, 0xc9, 0xdb, 0xd6, 0x67, 0x5d, 0xb6,
+       0x61, 0xfd, 0x83, 0x90, 0x17, 0x0f, 0xf5, 0x8f, 0xc2, 0xc6, 0xb4, 0xf3,
+       0x82, 0xfb, 0x2c, 0xf7, 0x0e, 0xf2, 0x17, 0xee, 0xaf, 0x0b, 0xc1, 0xc9,
+       0x2a, 0xf7, 0x18, 0xf7, 0xd7, 0x87, 0xe4, 0x15, 0x6f, 0x4e, 0x76, 0xbd,
+       0x8c, 0x5c, 0x00, 0x0e, 0x7d, 0xd9, 0x9b, 0x91, 0x8b, 0x5e, 0xb4, 0x87,
+       0x31, 0xb6, 0x06, 0x71, 0x72, 0x6b, 0xcd, 0xe2, 0xc6, 0x1f, 0x79, 0x43,
+       0xb6, 0x2a, 0xb4, 0xd5, 0xc1, 0xa1, 0x05, 0xbf, 0x74, 0x33, 0x68, 0x03,
+       0x1d, 0x8c, 0x1b, 0x5c, 0xb5, 0x11, 0x5d, 0xd8, 0x43, 0x1b, 0xca, 0x46,
+       0xf4, 0xd1, 0x46, 0xf8, 0x05, 0xd9, 0x2f, 0xbb, 0x35, 0x1d, 0xd3, 0xcb,
+       0x03, 0x43, 0xed, 0xd6, 0xb9, 0xfe, 0x71, 0xf9, 0x52, 0x95, 0x73, 0x2d,
+       0xdf, 0x10, 0x93, 0x88, 0x1c, 0x51, 0x36, 0xbb, 0x5f, 0xce, 0x6f, 0x02,
+       0xf3, 0x02, 0x7d, 0xd8, 0xb7, 0x32, 0x26, 0x64, 0xab, 0x18, 0x83, 0x0c,
+       0xd0, 0x66, 0xfd, 0x17, 0xf0, 0x88, 0x71, 0x20, 0xcc, 0x71, 0x80, 0xb3,
+       0x09, 0xdf, 0x27, 0x65, 0xb7, 0xc2, 0x67, 0x4b, 0x0a, 0xf0, 0x27, 0x77,
+       0x2b, 0x4c, 0x13, 0x48, 0x4d, 0x8c, 0x5f, 0x61, 0xf8, 0xbf, 0x55, 0xe5,
+       0x3d, 0xde, 0x2c, 0xd6, 0x85, 0x72, 0x8b, 0x74, 0x4b, 0x8f, 0x5b, 0x80,
+       0xcf, 0x5f, 0x9c, 0xec, 0xa5, 0xfd, 0x02, 0x6e, 0x72, 0x64, 0x5e, 0xd5,
+       0xcf, 0xc8, 0xc5, 0xca, 0xcf, 0xcc, 0x3e, 0x99, 0x36, 0xcf, 0x2c, 0x67,
+       0xac, 0x87, 0x3e, 0xcd, 0x91, 0xd9, 0x65, 0xef, 0x03, 0xa6, 0x5c, 0xc5,
+       0x5c, 0xac, 0x0f, 0x02, 0x43, 0x8e, 0xac, 0x74, 0x63, 0x3e, 0xf6, 0x90,
+       0x3e, 0x93, 0x39, 0x24, 0x33, 0xfe, 0x41, 0xd0, 0x7f, 0x40, 0xca, 0xf0,
+       0x95, 0x96, 0xb6, 0xa1, 0x57, 0xc6, 0xe1, 0x13, 0xbb, 0xb7, 0x13, 0xa3,
+       0xa9, 0x98, 0x52, 0xd9, 0x1d, 0x45, 0xda, 0x83, 0xf4, 0x66, 0x29, 0x3f,
+       0x73, 0x43, 0x54, 0xf7, 0xd7, 0xd5, 0xf1, 0xfe, 0x3c, 0xc7, 0x4e, 0x26,
+       0xad, 0xdf, 0x86, 0x07, 0xdb, 0xb1, 0x20, 0xe9, 0xe8, 0x12, 0xef, 0xcb,
+       0x7d, 0x32, 0xba, 0xe2, 0xca, 0xd8, 0x4a, 0x42, 0x0e, 0xae, 0x0c, 0xcb,
+       0xf8, 0x4a, 0x52, 0x6e, 0x5d, 0x09, 0xf1, 0xd8, 0x83, 0xb3, 0x69, 0x63,
+       0x07, 0xbc, 0xdf, 0xd1, 0x0e, 0xdc, 0xda, 0xd4, 0xd8, 0xb4, 0xbc, 0x71,
+       0x01, 0x36, 0x7b, 0x07, 0xfb, 0x37, 0x03, 0x2c, 0xe6, 0x43, 0x27, 0x4d,
+       0x42, 0x27, 0x8d, 0x43, 0x27, 0x4d, 0x53, 0x27, 0x01, 0xff, 0xbd, 0x0a,
+       0xfc, 0x77, 0x8f, 0xbc, 0x06, 0x9d, 0xfb, 0x82, 0xdf, 0xe3, 0xce, 0x81,
+       0x1f, 0x87, 0xd5, 0xb9, 0x57, 0xea, 0x2b, 0x3b, 0x90, 0x81, 0xc6, 0xd7,
+       0x24, 0x3a, 0x00, 0x7d, 0x75, 0xfb, 0x7a, 0x8f, 0x6c, 0xc4, 0x83, 0xe0,
+       0x34, 0xf6, 0xfa, 0x95, 0x8a, 0x96, 0xd9, 0xbc, 0xc7, 0x3d, 0xff, 0x20,
+       0xe6, 0x3e, 0x89, 0xbc, 0x1c, 0x74, 0x98, 0x8e, 0xa3, 0x34, 0x8e, 0x26,
+       0x64, 0xf3, 0xe0, 0x74, 0x47, 0xbd, 0x0c, 0xde, 0xa9, 0x33, 0xfe, 0x39,
+       0xea, 0x53, 0x7f, 0xbb, 0xb2, 0x05, 0x8c, 0x78, 0xe6, 0x60, 0x6a, 0x3a,
+       0x69, 0x53, 0xdf, 0x25, 0xa5, 0xfe, 0xb5, 0x84, 0x6c, 0x54, 0xb5, 0xcd,
+       0x59, 0x00, 0x26, 0x2c, 0x00, 0xef, 0x6e, 0x00, 0x67, 0x15, 0x9a, 0x5a,
+       0xdf, 0xdb, 0xd9, 0x2e, 0x61, 0x7f, 0x85, 0x66, 0x1e, 0xf8, 0x58, 0x9c,
+       0x7c, 0x86, 0x74, 0x4e, 0x24, 0x22, 0x76, 0x0f, 0x64, 0x81, 0xfb, 0xe3,
+       0x41, 0xd8, 0x53, 0x96, 0xd1, 0x36, 0x53, 0xff, 0x3f, 0x15, 0x25, 0xc6,
+       0x2b, 0xf8, 0xc4, 0xd3, 0x79, 0x94, 0xa5, 0x12, 0x69, 0xe4, 0xcf, 0x49,
+       0x5a, 0x9d, 0x21, 0x2d, 0x60, 0xcf, 0x97, 0x15, 0xcd, 0x11, 0xc6, 0xa4,
+       0x28, 0x1e, 0x51, 0x1d, 0x2f, 0x0c, 0xf3, 0x27, 0xdc, 0x22, 0xd6, 0x38,
+       0xc7, 0xbe, 0xab, 0xcc, 0x4b, 0xbb, 0x6c, 0x57, 0xf0, 0xf9, 0x2e, 0xf2,
+       0x91, 0x26, 0xe3, 0x27, 0x51, 0x79, 0xb8, 0xd9, 0x07, 0x9a, 0xba, 0x7f,
+       0x8b, 0x3d, 0x71, 0xdb, 0xec, 0xc9, 0x6e, 0xc2, 0x85, 0x9e, 0x58, 0x34,
+       0x7a, 0xc5, 0x99, 0xd2, 0x18, 0xf8, 0xa5, 0x2a, 0xd6, 0xa8, 0x8a, 0x35,
+       0xaa, 0x62, 0x8d, 0xaa, 0x58, 0xa3, 0x2a, 0xf5, 0x07, 0x75, 0x4d, 0xce,
+       0x9c, 0x31, 0x50, 0x87, 0x3c, 0x8f, 0xb5, 0x9c, 0x93, 0x6f, 0x6f, 0xcf,
+       0xca, 0x5f, 0x6c, 0x1f, 0x01, 0xc6, 0x9e, 0xc1, 0xba, 0xe6, 0xb0, 0xae,
+       0xd3, 0x58, 0xd3, 0xa3, 0x58, 0xd3, 0x2c, 0xcf, 0xd9, 0xe4, 0xcb, 0x95,
+       0xd4, 0x0b, 0x25, 0x85, 0xef, 0xdf, 0xc0, 0xfa, 0x4e, 0x89, 0xb7, 0x3e,
+       0x0c, 0x9d, 0x50, 0x0a, 0xe2, 0x5e, 0x70, 0x08, 0x18, 0x1a, 0xf3, 0x2f,
+       0xa5, 0x1c, 0x45, 0x83, 0xe7, 0x7e, 0x0a, 0x13, 0xbf, 0x21, 0x9b, 0xaa,
+       0x51, 0x3d, 0x6d, 0xd5, 0xc6, 0xa5, 0x78, 0x0e, 0xf5, 0x4f, 0xf7, 0x81,
+       0xdf, 0xc4, 0x6f, 0xa9, 0x52, 0x51, 0x76, 0xa0, 0xcf, 0x72, 0xa0, 0xf1,
+       0xbd, 0x52, 0x8e, 0xa7, 0x9e, 0xe7, 0x3e, 0xbb, 0x71, 0x95, 0xf1, 0x01,
+       0x1b, 0xbc, 0x21, 0xed, 0x78, 0x3e, 0x97, 0x55, 0x31, 0xbe, 0xbc, 0x7f,
+       0xc0, 0xec, 0x63, 0x8d, 0x49, 0xeb, 0xc2, 0x71, 0x39, 0xde, 0x67, 0x64,
+       0x11, 0xb8, 0xcf, 0xce, 0x12, 0x57, 0x78, 0x09, 0x8c, 0x19, 0x5d, 0x38,
+       0xe7, 0x46, 0x17, 0xcf, 0xb1, 0x9f, 0xa8, 0xa4, 0x57, 0xa9, 0x97, 0xd8,
+       0x0f, 0x74, 0x36, 0xfa, 0x8e, 0xa8, 0x33, 0xb5, 0x09, 0xb4, 0xfb, 0x03,
+       0x60, 0x46, 0xcd, 0xc3, 0xfc, 0x69, 0x6d, 0xc7, 0xf2, 0x8d, 0x76, 0xcc,
+       0x06, 0x1d, 0x02, 0x3b, 0x97, 0x6b, 0x68, 0xfc, 0x35, 0xa3, 0xf0, 0x99,
+       0xc6, 0x66, 0x47, 0xe5, 0x50, 0xaf, 0xc4, 0x3c, 0x35, 0x9f, 0xf4, 0xe9,
+       0x1d, 0x62, 0x52, 0x8c, 0xa1, 0xe3, 0xcc, 0x57, 0xe9, 0xce, 0x60, 0x2e,
+       0x37, 0xf7, 0x86, 0x31, 0x41, 0x7b, 0x55, 0x9f, 0x41, 0xd9, 0xe7, 0x7c,
+       0xcc, 0x47, 0x86, 0x18, 0x65, 0xb4, 0x31, 0x87, 0x7b, 0x95, 0x9d, 0x9d,
+       0x62, 0xec, 0x0f, 0xb2, 0x4d, 0xfd, 0x32, 0x84, 0xbd, 0xc1, 0x77, 0x1d,
+       0x53, 0xee, 0xf1, 0x28, 0x2f, 0x71, 0xc8, 0x20, 0x74, 0x4d, 0xff, 0xb0,
+       0xd4, 0xb7, 0x59, 0x36, 0xac, 0xf4, 0xb0, 0x83, 0x35, 0x58, 0xae, 0x04,
+       0x87, 0xf2, 0x7e, 0x09, 0xda, 0x92, 0x3c, 0x27, 0x3f, 0xc8, 0xf7, 0x49,
+       0xd0, 0x46, 0x1e, 0xf7, 0x97, 0xf4, 0xb9, 0xe6, 0x7e, 0x29, 0xd6, 0xa8,
+       0x8b, 0x91, 0xd6, 0xf7, 0x9b, 0xd8, 0x46, 0x5c, 0x72, 0x73, 0x9c, 0x3b,
+       0x7d, 0x13, 0xa0, 0xba, 0xd5, 0x94, 0x5f, 0xb7, 0x67, 0xa5, 0x48, 0xf9,
+       0x84, 0x6e, 0x2c, 0x6e, 0x4e, 0xc9, 0xf2, 0x1a, 0xe3, 0x7d, 0x3c, 0x7b,
+       0x9e, 0x88, 0x4a, 0x7f, 0x10, 0x6c, 0xf9, 0xb4, 0xf3, 0x79, 0x29, 0x20,
+       0xdf, 0x5e, 0x87, 0x9d, 0x3f, 0xaa, 0x79, 0xc7, 0xf9, 0x96, 0x37, 0xfe,
+       0x6f, 0xf8, 0xf8, 0xf6, 0x38, 0x77, 0x66, 0x0f, 0x9c, 0xfb, 0xea, 0x39,
+       0xc8, 0x5f, 0x15, 0xb2, 0x09, 0x9f, 0xe9, 0x2f, 0xaa, 0x90, 0x4d, 0xd8,
+       0x8c, 0x6f, 0x56, 0x21, 0x9b, 0xd8, 0x3b, 0x2f, 0xc2, 0xa7, 0xd1, 0x98,
+       0xe2, 0x11, 0x85, 0x29, 0x4e, 0x54, 0x89, 0xf9, 0x2f, 0x41, 0x96, 0x27,
+       0x21, 0xc7, 0x49, 0xc8, 0xaf, 0x0f, 0xd9, 0x1d, 0x87, 0x3c, 0x7b, 0x90,
+       0xe7, 0x61, 0x15, 0xf7, 0x79, 0x61, 0x3b, 0x2a, 0xf7, 0xc3, 0x9f, 0x38,
+       0x53, 0x23, 0x1f, 0x8f, 0xcb, 0xff, 0x82, 0x2f, 0xb1, 0xeb, 0xef, 0x80,
+       0x87, 0x39, 0x59, 0xf4, 0xc8, 0xaf, 0x9c, 0xbd, 0xe0, 0xd1, 0xd7, 0x70,
+       0xe5, 0xcc, 0x06, 0x7d, 0x04, 0xea, 0x88, 0x57, 0xe5, 0x9b, 0x95, 0x1f,
+       0xc8, 0xb7, 0x80, 0x05, 0x0a, 0xf0, 0x9b, 0x37, 0x9e, 0xa1, 0xcf, 0xa8,
+       0x68, 0x84, 0xdc, 0xc5, 0x65, 0x73, 0xfb, 0x76, 0x79, 0xca, 0xa5, 0x0c,
+       0xc7, 0xa1, 0x5b, 0xf0, 0x7e, 0x90, 0x7a, 0x28, 0x83, 0xfd, 0x09, 0x39,
+       0x87, 0x6e, 0xa8, 0xd9, 0x3c, 0xc3, 0x28, 0x05, 0x03, 0xd4, 0x59, 0x35,
+       0xcf, 0x1d, 0xb1, 0xc9, 0x9b, 0x5b, 0x18, 0x73, 0xfa, 0x0a, 0x84, 0x17,
+       0x79, 0xb4, 0xd9, 0x48, 0xeb, 0xd0, 0x8d, 0xcf, 0x90, 0x8f, 0xf4, 0x61,
+       0xf1, 0xbc, 0xc1, 0xbd, 0xf6, 0x73, 0x15, 0xcb, 0x2d, 0xce, 0xc1, 0x5f,
+       0xdf, 0x20, 0x9f, 0x20, 0x2b, 0xcf, 0x90, 0x8f, 0xe4, 0x9d, 0xe6, 0xe3,
+       0x43, 0x12, 0xf2, 0x90, 0x65, 0x9d, 0x3c, 0xfc, 0x77, 0x90, 0xc3, 0x38,
+       0xe6, 0xfd, 0xd5, 0x28, 0x63, 0x8e, 0x37, 0x7a, 0x5c, 0xf3, 0x57, 0xe5,
+       0xc9, 0x26, 0xc7, 0x7a, 0xd9, 0x8c, 0xf9, 0xfd, 0xe0, 0xe1, 0x38, 0x69,
+       0xe7, 0x7a, 0xee, 0x93, 0xc6, 0x90, 0x6f, 0xe2, 0x2a, 0xbf, 0xcd, 0xde,
+       0xb0, 0x1e, 0x78, 0x0d, 0xbd, 0xf2, 0xad, 0x2a, 0x78, 0x0c, 0xbf, 0xe9,
+       0x1b, 0xf0, 0x9b, 0x18, 0x6b, 0xd4, 0xeb, 0x32, 0x6d, 0xe2, 0xa6, 0x9d,
+       0xf1, 0xd2, 0x24, 0xd6, 0x85, 0xbe, 0x79, 0xaa, 0x74, 0x19, 0xba, 0xef,
+       0x45, 0x9f, 0x71, 0xc4, 0x40, 0xbe, 0xef, 0xb7, 0x6b, 0x37, 0x15, 0x63,
+       0x96, 0x87, 0xa0, 0x0f, 0x1f, 0x86, 0x3e, 0xfc, 0xc8, 0x75, 0xf7, 0x7b,
+       0x28, 0x67, 0x4f, 0xcf, 0x2e, 0xac, 0x8d, 0x96, 0x22, 0xf6, 0xb0, 0xcc,
+       0x5d, 0xa3, 0x1b, 0x19, 0x4f, 0x4c, 0x9a, 0x78, 0x68, 0x3b, 0xfe, 0x0c,
+       0x63, 0x9e, 0x94, 0xe7, 0x40, 0x2e, 0xfa, 0xa5, 0xbe, 0x88, 0x3a, 0x97,
+       0xe6, 0xba, 0xee, 0x85, 0x2d, 0xbf, 0x6d, 0xf6, 0x30, 0x65, 0xab, 0xf3,
+       0xdc, 0x98, 0xe7, 0xd0, 0xfd, 0xf0, 0x13, 0xb8, 0x57, 0x53, 0xc9, 0x1c,
+       0xf6, 0x73, 0x79, 0x9b, 0xfa, 0x9f, 0xd8, 0xb0, 0x9b, 0xf1, 0xbc, 0xf9,
+       0x9e, 0x2c, 0x63, 0x01, 0xfd, 0xf0, 0x3f, 0x7e, 0x24, 0x5b, 0x6b, 0x7f,
+       0xd3, 0xab, 0xf7, 0x91, 0xbe, 0x6f, 0x66, 0x9f, 0xeb, 0x8c, 0x63, 0xd2,
+       0xa6, 0x4a, 0xb4, 0x17, 0x76, 0xf1, 0xd6, 0x67, 0xfb, 0x95, 0xdd, 0xbb,
+       0xcf, 0x77, 0x64, 0x27, 0xce, 0xfe, 0x7e, 0x24, 0x3f, 0x5e, 0x1b, 0x89,
+       0x31, 0xfe, 0xb9, 0x0c, 0x3e, 0xef, 0x2a, 0xdd, 0xf5, 0x20, 0xea, 0x64,
+       0xe5, 0xf5, 0x35, 0xda, 0xd6, 0xb4, 0x7b, 0x46, 0x26, 0x12, 0x67, 0xc0,
+       0xcb, 0x53, 0x68, 0x03, 0x7f, 0x38, 0x98, 0x41, 0xde, 0xcb, 0xf4, 0xb9,
+       0x2d, 0x3e, 0x4f, 0xb8, 0x5f, 0x04, 0x4e, 0xce, 0xb9, 0x69, 0xb7, 0xd7,
+       0xba, 0xa4, 0xce, 0x9d, 0x22, 0x1e, 0xfb, 0x1a, 0x92, 0xc2, 0xa6, 0xa6,
+       0xf1, 0xca, 0x26, 0xc7, 0xe0, 0x5c, 0x48, 0xe3, 0xdf, 0xf0, 0x5c, 0x01,
+       0xf4, 0xdf, 0x06, 0x9f, 0x84, 0x98, 0xe5, 0x12, 0x64, 0x66, 0x08, 0xfa,
+       0x81, 0xbe, 0x0a, 0xcf, 0x2c, 0xc9, 0xb3, 0xcf, 0x03, 0xef, 0xc7, 0x21,
+       0xab, 0xc8, 0xdf, 0xbc, 0xea, 0x1f, 0x2e, 0xb7, 0x70, 0x3d, 0x6d, 0xe3,
+       0x2c, 0x6c, 0xe4, 0xbb, 0x14, 0x3d, 0x47, 0x7c, 0xf8, 0xda, 0xcf, 0x50,
+       0xbe, 0x0e, 0x4a, 0x31, 0x4e, 0x5c, 0x49, 0x7d, 0xb2, 0x9b, 0x88, 0x02,
+       0xd7, 0x46, 0x6f, 0xe7, 0xbe, 0x3b, 0x22, 0xf7, 0x7b, 0x0f, 0xca, 0x07,
+       0xbd, 0x49, 0x99, 0xf1, 0xee, 0x91, 0xc3, 0x5e, 0x5e, 0xee, 0xf3, 0x60,
+       0x9b, 0x14, 0x3e, 0xef, 0xc1, 0x3c, 0x38, 0xf6, 0x90, 0x39, 0xdf, 0xd3,
+       0xf8, 0xf4, 0xeb, 0xdb, 0x5a, 0x27, 0xe5, 0xd7, 0xb2, 0x31, 0xda, 0xe4,
+       0x23, 0xfe, 0x8c, 0xb1, 0xc9, 0xf0, 0xf9, 0x55, 0xbd, 0x19, 0x65, 0xbb,
+       0xcb, 0x9b, 0x73, 0x48, 0x61, 0xc7, 0x37, 0xa7, 0x81, 0xfb, 0xe9, 0x4b,
+       0xe5, 0xf0, 0x7e, 0x0f, 0xde, 0x3f, 0x84, 0xf4, 0x08, 0x52, 0x75, 0xae,
+       0x19, 0xd3, 0xb1, 0xdb, 0xd6, 0xb9, 0x1d, 0xe4, 0xeb, 0xe8, 0xec, 0x42,
+       0x2d, 0x8c, 0x81, 0x1f, 0x92, 0xc7, 0x7d, 0x7d, 0x96, 0x7e, 0x18, 0x7e,
+       0x74, 0x0c, 0xf8, 0xe9, 0x43, 0xcf, 0x4e, 0x49, 0xe4, 0xee, 0x43, 0x62,
+       0xdf, 0x6d, 0xc9, 0xc2, 0x24, 0xe8, 0x9b, 0x1c, 0xc5, 0x3c, 0x86, 0xe5,
+       0xc4, 0xb6, 0xf2, 0x51, 0x0d, 0x5e, 0xa4, 0x1e, 0x07, 0xd6, 0xdd, 0x0e,
+       0x71, 0x63, 0x37, 0x70, 0x05, 0xe3, 0x7b, 0x49, 0x85, 0x77, 0xed, 0x1b,
+       0xb9, 0xbe, 0x7d, 0x92, 0xbf, 0x91, 0xfc, 0x63, 0x1e, 0xfc, 0x9d, 0x1b,
+       0xb5, 0xdd, 0x48, 0xaf, 0x70, 0x6d, 0x7a, 0x4c, 0xec, 0x96, 0x36, 0x80,
+       0xe9, 0x6a, 0xac, 0x85, 0x0b, 0x19, 0x9f, 0xb1, 0x6e, 0x8f, 0x5d, 0xbd,
+       0x67, 0x16, 0xca, 0x73, 0x78, 0x7f, 0xc0, 0x53, 0x38, 0xe7, 0x44, 0xf5,
+       0x05, 0xcc, 0x81, 0x36, 0x3d, 0x22, 0xdd, 0xd0, 0x6b, 0x5b, 0x1e, 0xf7,
+       0x1e, 0x6d, 0xce, 0x11, 0xcc, 0x87, 0x36, 0x9e, 0xb6, 0xfe, 0xde, 0x7e,
+       0xe9, 0xa7, 0x9d, 0x67, 0xfd, 0x24, 0xca, 0x58, 0x97, 0x79, 0x97, 0x51,
+       0x9f, 0xb1, 0x29, 0xf8, 0x3e, 0xd5, 0x45, 0xe8, 0x19, 0x0f, 0xe9, 0xe3,
+       0x48, 0xc7, 0x91, 0x3e, 0x81, 0x54, 0xc7, 0xb1, 0x36, 0x9f, 0x61, 0x2c,
+       0x49, 0xc5, 0x68, 0x14, 0xbe, 0xa0, 0x4d, 0x9c, 0xf3, 0xa9, 0x27, 0x8f,
+       0x8b, 0x3d, 0x75, 0x1b, 0xf2, 0xe8, 0x6b, 0x63, 0xd4, 0xf7, 0x7f, 0xde,
+       0xc4, 0x88, 0x5a, 0x71, 0x25, 0x63, 0x07, 0xd6, 0xd0, 0x17, 0xfb, 0xa1,
+       0x2f, 0xfb, 0x0b, 0x79, 0xf8, 0x9a, 0xd8, 0x5c, 0x2b, 0xde, 0x34, 0x5d,
+       0x50, 0x3a, 0x96, 0x7c, 0x81, 0x7e, 0x75, 0x33, 0xf2, 0xb5, 0xed, 0x01,
+       0xe8, 0xaf, 0x38, 0xb1, 0x26, 0xf0, 0xb6, 0xc6, 0x6e, 0x8b, 0x98, 0x9b,
+       0xb6, 0xef, 0x71, 0xf9, 0xbb, 0xb5, 0x61, 0xf9, 0x71, 0x25, 0x21, 0xaf,
+       0x57, 0x82, 0xe0, 0xa2, 0x9f, 0xf6, 0xef, 0x13, 0xb9, 0xbd, 0x5b, 0x9f,
+       0xfd, 0xa3, 0x86, 0x3e, 0xaf, 0x2f, 0xab, 0x33, 0x7b, 0xd4, 0x83, 0x5e,
+       0x79, 0xbd, 0xf9, 0xf7, 0xe0, 0xaf, 0xee, 0xb3, 0xb3, 0xed, 0xae, 0x6e,
+       0xcb, 0x33, 0xff, 0xc4, 0x8e, 0xa4, 0xcd, 0xdd, 0x81, 0x34, 0xda, 0xa6,
+       0xc7, 0x37, 0x5a, 0xed, 0xd9, 0x36, 0xa3, 0xec, 0x40, 0x71, 0x73, 0x50,
+       0x1a, 0x7f, 0xca, 0xfd, 0x01, 0xbf, 0x53, 0x9d, 0xcb, 0x30, 0xe5, 0x39,
+       0x07, 0xeb, 0x24, 0x4d, 0xf9, 0x88, 0x29, 0xf7, 0x54, 0x6c, 0x70, 0xb9,
+       0x4a, 0x19, 0x85, 0x1f, 0x4a, 0x6c, 0xd8, 0x24, 0x76, 0x0d, 0xe3, 0x61,
+       0xd4, 0xd3, 0xb3, 0x52, 0x56, 0x71, 0x2d, 0xda, 0xa0, 0x5e, 0x15, 0xd3,
+       0xd2, 0xb1, 0x3e, 0x96, 0x3d, 0x2c, 0x73, 0xee, 0x71, 0x19, 0x98, 0xba,
+       0x36, 0x6e, 0xd7, 0xeb, 0x1d, 0x87, 0x6f, 0xa5, 0xec, 0xac, 0xfb, 0x41,
+       0x21, 0x8f, 0xbb, 0x69, 0x17, 0x72, 0xb6, 0x05, 0xdf, 0xf4, 0xcb, 0x19,
+       0x79, 0x7e, 0x3b, 0x95, 0x14, 0xac, 0xd7, 0x07, 0xe1, 0x7b, 0xda, 0xcf,
+       0xe1, 0x9d, 0x71, 0xae, 0x67, 0xe3, 0x12, 0x79, 0x76, 0x58, 0x7a, 0x56,
+       0x88, 0x3f, 0xc8, 0xd3, 0x84, 0x74, 0xaf, 0x10, 0xfb, 0x32, 0x2e, 0x9c,
+       0x9a, 0xbe, 0x22, 0x8c, 0xb7, 0xa4, 0xfc, 0x0b, 0xf8, 0xed, 0x62, 0xde,
+       0x3d, 0xf0, 0x9b, 0xbb, 0xcf, 0xea, 0x76, 0xf6, 0xd6, 0x10, 0x00, 0x1f,
+       0x7c, 0xee, 0x15, 0xfa, 0xd9, 0x4c, 0xe9, 0x77, 0xb3, 0x0c, 0xb2, 0xbd,
+       0x35, 0x62, 0xca, 0xe8, 0x53, 0x73, 0x7c, 0x9e, 0xd9, 0xeb, 0x7b, 0xa0,
+       0xf6, 0x18, 0x7d, 0x52, 0x5f, 0x5e, 0xdc, 0x60, 0x0c, 0xfc, 0x55, 0xf8,
+       0x6f, 0x19, 0x89, 0xac, 0x64, 0x20, 0x87, 0x3e, 0x6c, 0x29, 0x71, 0x1c,
+       0xed, 0x17, 0xf2, 0x61, 0x73, 0x36, 0x9e, 0x51, 0x31, 0x87, 0x92, 0x93,
+       0x85, 0xcc, 0xd5, 0x3f, 0x63, 0x97, 0xdb, 0x6c, 0x54, 0xd9, 0xd8, 0xa8,
+       0xb2, 0xb1, 0x51, 0xe5, 0x66, 0xb8, 0x3f, 0x38, 0xc6, 0x71, 0xd8, 0xd5,
+       0x2e, 0x79, 0x2a, 0x4e, 0x59, 0xd1, 0xb2, 0x17, 0xb1, 0xc7, 0x94, 0xac,
+       0xce, 0xd0, 0xde, 0x3e, 0xe3, 0xee, 0x83, 0xaf, 0x55, 0x52, 0x7b, 0xe3,
+       0x99, 0x50, 0xce, 0x78, 0xe7, 0x33, 0x90, 0x1a, 0xb0, 0x4c, 0xd9, 0xb3,
+       0x64, 0xc9, 0x3b, 0xae, 0xb0, 0xde, 0xc3, 0xe8, 0xe3, 0x49, 0xd3, 0xc7,
+       0x92, 0x8c, 0x19, 0x79, 0xe7, 0xda, 0x44, 0xd5, 0x79, 0xc5, 0x43, 0xfe,
+       0xef, 0xc9, 0xc0, 0x20, 0xd7, 0x93, 0xf2, 0x4f, 0x7c, 0xc1, 0xf5, 0x60,
+       0x8c, 0xff, 0x6d, 0x63, 0xa9, 0xea, 0x0e, 0x5f, 0xa1, 0x42, 0x5b, 0xb2,
+       0x1f, 0xf2, 0x9b, 0x81, 0xff, 0x1d, 0xc6, 0x53, 0xd5, 0xbe, 0x4a, 0xd8,
+       0x36, 0xec, 0xda, 0xd8, 0xd8, 0x78, 0x51, 0x8e, 0x4b, 0x19, 0x7e, 0x2b,
+       0x69, 0x58, 0x82, 0x1d, 0xdb, 0xf0, 0xff, 0x2e, 0xf8, 0x64, 0x3c, 0x55,
+       0x9a, 0x97, 0xce, 0x18, 0x27, 0x7d, 0xf1, 0xb7, 0x8b, 0x73, 0x1e, 0x51,
+       0xfa, 0xf1, 0x5a, 0x2c, 0x15, 0xc6, 0x38, 0xe7, 0x3a, 0x62, 0x9c, 0xfa,
+       0xec, 0xac, 0x27, 0x4b, 0xbd, 0x7e, 0xca, 0xfa, 0x71, 0x26, 0x22, 0x0d,
+       0x60, 0xca, 0xfb, 0x7c, 0x62, 0xa4, 0x92, 0xf5, 0x7a, 0x45, 0xd4, 0x7b,
+       0xc1, 0x8f, 0xe8, 0x58, 0xbb, 0x0b, 0xdb, 0xb2, 0xed, 0x98, 0xb3, 0x22,
+       0x07, 0x79, 0xb6, 0xf2, 0x77, 0x8b, 0x4a, 0x27, 0x27, 0xfa, 0x24, 0x46,
+       0x3d, 0x75, 0x2f, 0xde, 0x79, 0x5e, 0x71, 0xa4, 0x23, 0x7f, 0x67, 0x80,
+       0x7b, 0xac, 0x0c, 0x3c, 0xb6, 0xe4, 0x69, 0x7e, 0x39, 0xe0, 0xf1, 0x0c,
+       0x30, 0xce, 0x95, 0x26, 0x71, 0x6d, 0xcc, 0xe0, 0x5a, 0xe2, 0x26, 0xac,
+       0xd1, 0xf6, 0x28, 0xca, 0x88, 0x9d, 0xe2, 0xca, 0xaf, 0x53, 0x58, 0xca,
+       0x2f, 0x18, 0x3b, 0x41, 0x99, 0xa2, 0x3c, 0x11, 0x93, 0x69, 0x99, 0x5a,
+       0xa8, 0xb8, 0x1d, 0xf2, 0xe4, 0xfe, 0x23, 0xe5, 0xe9, 0xa6, 0x3e, 0x9e,
+       0xf7, 0xbc, 0x84, 0xfd, 0x79, 0x12, 0xf6, 0x74, 0xa3, 0xb6, 0x4f, 0x76,
+       0x6b, 0xa3, 0xc0, 0xc5, 0xcc, 0xe3, 0xbe, 0x4c, 0xc8, 0xfd, 0x95, 0x59,
+       0x39, 0x5c, 0x8b, 0xca, 0xc5, 0x9a, 0x7d, 0x4f, 0x8f, 0x30, 0x46, 0x4d,
+       0xcc, 0xf1, 0x0d, 0xa5, 0xd7, 0x7e, 0xe2, 0x5f, 0x6d, 0xbf, 0x84, 0xf6,
+       0x0d, 0xb4, 0x5f, 0xa8, 0xdd, 0x28, 0x45, 0xd5, 0x7e, 0xfd, 0xba, 0x31,
+       0xae, 0xd6, 0xe9, 0x33, 0xf6, 0x33, 0x3c, 0x97, 0xa4, 0x6d, 0xee, 0xc2,
+       0xbc, 0xe1, 0x27, 0x65, 0x90, 0xd6, 0x79, 0x36, 0x49, 0xdb, 0xfe, 0x47,
+       0xae, 0x4e, 0x13, 0x6d, 0x76, 0x21, 0xd9, 0x66, 0x17, 0xde, 0x68, 0xbb,
+       0x4b, 0xa9, 0xef, 0x65, 0xbf, 0x9c, 0x01, 0xf6, 0xab, 0x0d, 0xb5, 0xdd,
+       0xa9, 0x48, 0x95, 0x68, 0x93, 0x18, 0x0b, 0xdb, 0xac, 0x84, 0xba, 0x3a,
+       0x37, 0xc0, 0x38, 0xfe, 0xb2, 0x4f, 0xbe, 0x4b, 0x32, 0x92, 0xa5, 0xae,
+       0xf7, 0xa3, 0xbb, 0xc0, 0x68, 0x0d, 0x75, 0x4e, 0x1d, 0xc1, 0x0f, 0xb6,
+       0xd0, 0xb1, 0xc4, 0xf5, 0x98, 0x57, 0xd2, 0x58, 0xd7, 0x85, 0xde, 0xb4,
+       0x55, 0x9d, 0x64, 0xde, 0xbf, 0xc9, 0xbc, 0x43, 0xbf, 0x55, 0xde, 0x3b,
+       0x6c, 0x67, 0xff, 0xfb, 0xcd, 0xf9, 0x0c, 0xcf, 0x0e, 0x99, 0x47, 0xcc,
+       0xfb, 0x03, 0x60, 0x5e, 0xde, 0xb7, 0xe5, 0xba, 0xbc, 0x89, 0xf5, 0xbf,
+       0x08, 0xdb, 0xe2, 0x41, 0xaf, 0x3b, 0xb2, 0x90, 0xb9, 0x68, 0xce, 0x2e,
+       0x38, 0xb7, 0x6e, 0xd8, 0xa8, 0x1f, 0xc9, 0xe1, 0xb5, 0x14, 0xb0, 0x4a,
+       0x88, 0xaf, 0xd8, 0xc7, 0xf5, 0xd8, 0xea, 0x44, 0xb5, 0xfd, 0xfc, 0x37,
+       0xbc, 0x3f, 0x4a, 0xd9, 0x50, 0xe7, 0xda, 0x56, 0x81, 0xf1, 0xc0, 0xd5,
+       0x1f, 0x60, 0x9e, 0xa9, 0x53, 0x22, 0x3c, 0xeb, 0x62, 0x9c, 0x17, 0x3e,
+       0xc2, 0x36, 0xf3, 0xe7, 0xd0, 0xf7, 0x0f, 0x78, 0x97, 0x16, 0xfe, 0x93,
+       0x6d, 0xf8, 0xf3, 0xfb, 0xc6, 0xbf, 0x8f, 0x32, 0x36, 0x0a, 0xd9, 0x2f,
+       0x2b, 0xdb, 0x5d, 0x8c, 0x2f, 0x23, 0xfd, 0x1f, 0xc6, 0x56, 0x7f, 0xbd,
+       0x4f, 0xdb, 0x6a, 0xde, 0x03, 0xf9, 0x02, 0xf7, 0x96, 0xa1, 0x9b, 0xf4,
+       0x92, 0xee, 0x2e, 0xe9, 0x3e, 0x4d, 0x9a, 0xbf, 0x82, 0x7a, 0x94, 0x8d,
+       0x83, 0xe6, 0xbe, 0x08, 0xcf, 0xc1, 0xd9, 0x27, 0x6c, 0x84, 0xc2, 0x5b,
+       0x39, 0xa4, 0x6c, 0xb7, 0x86, 0x7a, 0x39, 0xcc, 0x59, 0x61, 0xb0, 0xa1,
+       0x88, 0x84, 0x79, 0xf7, 0x22, 0x8f, 0x3e, 0xe5, 0x4d, 0xf0, 0x29, 0x99,
+       0x97, 0xc7, 0x3b, 0xc7, 0xba, 0xd9, 0x8c, 0x63, 0x30, 0xdd, 0x35, 0x34,
+       0x71, 0x2e, 0xe1, 0x5a, 0x77, 0x9b, 0x33, 0x73, 0xe6, 0xdd, 0x64, 0xf2,
+       0x1c, 0x33, 0xbf, 0x61, 0x73, 0x8f, 0x3d, 0x75, 0x2a, 0x27, 0xa1, 0xec,
+       0x93, 0xbe, 0x68, 0x1b, 0x16, 0xfc, 0x83, 0xc1, 0xab, 0x77, 0x1c, 0x29,
+       0x6b, 0x94, 0xaf, 0x84, 0xba, 0xbf, 0xc7, 0xf3, 0xf2, 0x17, 0x14, 0xfe,
+       0x0e, 0x71, 0x95, 0xd2, 0x65, 0x3c, 0x07, 0xa8, 0xd9, 0xd9, 0x9e, 0xdf,
+       0xf9, 0x3e, 0x5b, 0x24, 0x1b, 0xb6, 0x03, 0x1e, 0x52, 0x6d, 0x92, 0xb2,
+       0xd8, 0x7c, 0xbb, 0xbb, 0x6f, 0xc0, 0x68, 0xd7, 0xdc, 0x67, 0x49, 0x28,
+       0xfd, 0xb3, 0x51, 0x8b, 0x80, 0xbf, 0x43, 0x78, 0xbe, 0x0c, 0x1e, 0x44,
+       0x31, 0x4f, 0xe0, 0xf4, 0xf8, 0x4d, 0xea, 0xbe, 0x4f, 0xc4, 0xbb, 0xa4,
+       0xce, 0x8d, 0x0a, 0xf5, 0x9f, 0xa9, 0xb2, 0xaf, 0xad, 0xf5, 0xf0, 0x0e,
+       0x28, 0x52, 0x9e, 0x43, 0xff, 0x06, 0x32, 0xd8, 0x65, 0x64, 0x10, 0x69,
+       0x9d, 0xf9, 0xb7, 0xc0, 0x87, 0x14, 0xc8, 0x4b, 0x37, 0xb0, 0xbd, 0xf2,
+       0x13, 0x30, 0x9b, 0xab, 0x34, 0x74, 0x67, 0xc3, 0x3b, 0x97, 0x81, 0x1c,
+       0x86, 0x6c, 0x6c, 0x4c, 0x2f, 0x4b, 0x63, 0xba, 0x1d, 0x27, 0x02, 0x07,
+       0xba, 0xa5, 0xa0, 0xe1, 0x31, 0xd6, 0xd7, 0x6f, 0xee, 0xbf, 0x2d, 0x1a,
+       0x6c, 0x47, 0xfe, 0xdb, 0x52, 0x98, 0x5c, 0x52, 0x32, 0xd5, 0x50, 0xeb,
+       0xe0, 0x58, 0xe7, 0xd5, 0xdd, 0x59, 0x8e, 0xc1, 0xfb, 0xb3, 0x11, 0x83,
+       0x71, 0xfe, 0xa9, 0x59, 0xcf, 0xef, 0xf7, 0x85, 0xdf, 0x64, 0x74, 0x65,
+       0x4f, 0xf2, 0xce, 0x08, 0xf0, 0x6b, 0x6d, 0x76, 0xa1, 0x42, 0xbd, 0x16,
+       0x04, 0x0d, 0x7f, 0x07, 0x3d, 0xbe, 0xa9, 0xf0, 0xd9, 0xae, 0x68, 0xfd,
+       0xb9, 0xa4, 0xee, 0xa1, 0x56, 0x66, 0xf3, 0x2a, 0xa6, 0x06, 0xdc, 0xd1,
+       0x3a, 0xbf, 0x78, 0xa7, 0xb3, 0x8b, 0x28, 0xfc, 0xe5, 0x5e, 0xb3, 0xee,
+       0x51, 0xa7, 0x58, 0xe9, 0x73, 0x16, 0xd4, 0xb9, 0xd2, 0xe7, 0xcc, 0xf7,
+       0x2b, 0xa5, 0xd9, 0x74, 0x33, 0xbb, 0x9f, 0x58, 0x9a, 0x31, 0xfd, 0x42,
+       0x85, 0x67, 0x19, 0xba, 0x3c, 0x6d, 0xca, 0x47, 0x9a, 0xaa, 0x4c, 0xc5,
+       0xe4, 0xe0, 0x77, 0xc1, 0xae, 0x30, 0xfe, 0x47, 0xdd, 0x82, 0xfe, 0xe3,
+       0x7a, 0x0e, 0x91, 0xec, 0x32, 0x7c, 0x3b, 0xd2, 0x77, 0x6a, 0x36, 0xbf,
+       0xc6, 0x7b, 0x47, 0x5f, 0x9a, 0xbd, 0x08, 0xff, 0x63, 0xcb, 0xd3, 0x77,
+       0xb5, 0x37, 0x19, 0x3b, 0x62, 0x3b, 0xd5, 0xe7, 0xb2, 0x89, 0x65, 0x9e,
+       0x9c, 0x1d, 0xdd, 0x8c, 0xc8, 0x49, 0xd3, 0x07, 0xdf, 0x93, 0x2d, 0xdf,
+       0x44, 0xe9, 0x3b, 0x60, 0xf0, 0x27, 0x80, 0xc1, 0x63, 0xb0, 0x8b, 0xc4,
+       0xf2, 0xc4, 0xb7, 0x31, 0xec, 0x15, 0x8e, 0xf3, 0xaf, 0xd5, 0x38, 0x11,
+       0x8c, 0xb3, 0xb0, 0x76, 0x40, 0xdd, 0x23, 0xc9, 0x7b, 0x0e, 0xec, 0x34,
+       0xec, 0xa9, 0xc7, 0x58, 0xb2, 0x8d, 0x39, 0x8f, 0x43, 0x1f, 0xf0, 0x6e,
+       0xc7, 0x60, 0x78, 0xef, 0x85, 0x77, 0xad, 0x4c, 0xbb, 0x4f, 0xa3, 0x1d,
+       0x31, 0x38, 0xdb, 0xca, 0x8d, 0xb6, 0x8c, 0x2a, 0xbb, 0xab, 0x75, 0x0e,
+       0x69, 0xa8, 0x63, 0xae, 0xb4, 0x5d, 0xd8, 0x6b, 0x6a, 0x5e, 0x9f, 0x56,
+       0xed, 0xac, 0xec, 0x53, 0xa0, 0x9d, 0xd8, 0x0a, 0x7d, 0x57, 0x75, 0x7c,
+       0xb0, 0xa0, 0xe4, 0x08, 0x72, 0x32, 0x1d, 0xde, 0x17, 0xd1, 0xed, 0xc2,
+       0xfa, 0x23, 0x9b, 0x9f, 0x35, 0xe3, 0xff, 0x32, 0xc8, 0x1d, 0x8d, 0xa9,
+       0xfb, 0x39, 0x2f, 0x5d, 0x73, 0x87, 0x8a, 0x6d, 0xc2, 0x3a, 0x11, 0x23,
+       0x5b, 0x27, 0xda, 0x68, 0xfe, 0x9c, 0x59, 0x73, 0xb6, 0x63, 0xfc, 0x94,
+       0x79, 0x25, 0xe6, 0x39, 0x8b, 0x19, 0xf6, 0xd1, 0x7e, 0xee, 0x32, 0x09,
+       0x5b, 0xae, 0x6d, 0x46, 0x69, 0xdb, 0x83, 0x4d, 0xec, 0xc6, 0xda, 0xd1,
+       0x06, 0x8c, 0x1a, 0xdc, 0xfe, 0x8e, 0x71, 0x49, 0xa7, 0x98, 0x81, 0x1f,
+       0xdf, 0x6a, 0xcf, 0x75, 0x2c, 0xcd, 0x5e, 0xac, 0x78, 0x72, 0xa2, 0xaa,
+       0xef, 0x37, 0x69, 0x3e, 0x50, 0x37, 0x73, 0x6d, 0x93, 0xb2, 0xe0, 0x31,
+       0xfe, 0x91, 0x94, 0x57, 0xbc, 0x76, 0x3d, 0x8d, 0xfa, 0xdb, 0x93, 0xe6,
+       0x8e, 0xf3, 0xa7, 0x31, 0x7f, 0xe2, 0x31, 0x2d, 0x4b, 0x07, 0x61, 0x77,
+       0xfe, 0x83, 0x43, 0x9d, 0xdd, 0x2d, 0x97, 0x9d, 0xf6, 0xf9, 0x85, 0x71,
+       0x6e, 0x2d, 0x97, 0x0e, 0x64, 0x64, 0xb9, 0xc5, 0x77, 0xf8, 0xbf, 0xef,
+       0x1b, 0x83, 0x8e, 0xb7, 0x64, 0x66, 0xd2, 0x4b, 0x2c, 0x31, 0xee, 0xef,
+       0x4e, 0xb8, 0xae, 0xba, 0xa7, 0x97, 0x04, 0xbd, 0x7c, 0x1e, 0x05, 0x06,
+       0xe1, 0x9d, 0x3a, 0xbc, 0xf3, 0x4e, 0x5b, 0xdc, 0x03, 0xbd, 0xae, 0x8a,
+       0xe7, 0x6b, 0x1d, 0xfd, 0xf5, 0xfd, 0x8c, 0xa7, 0x0c, 0x78, 0xe1, 0xda,
+       0xab, 0x7b, 0xcd, 0xe8, 0x3b, 0x62, 0xca, 0x07, 0x5b, 0xfc, 0x97, 0x21,
+       0xa6, 0xad, 0xbb, 0x52, 0x26, 0x6e, 0xc1, 0xfa, 0x9f, 0x51, 0xb4, 0x2c,
+       0x78, 0x41, 0xb0, 0xa8, 0xe6, 0xf3, 0x34, 0x64, 0x21, 0x22, 0xe5, 0x96,
+       0xfc, 0x3e, 0x0d, 0xf9, 0xdd, 0xc7, 0x6b, 0x35, 0x7b, 0xc8, 0x5a, 0x28,
+       0x63, 0x94, 0x2f, 0xca, 0x56, 0xa2, 0x9f, 0x7b, 0xae, 0xd4, 0x5a, 0x77,
+       0x47, 0xd9, 0xd8, 0xa4, 0x1d, 0xae, 0x3b, 0x9f, 0xf7, 0xba, 0x93, 0x14,
+       0xee, 0x8f, 0xcc, 0x3f, 0x62, 0x6d, 0x7d, 0xb3, 0xb6, 0x99, 0xb6, 0x6f,
+       0x0b, 0xc2, 0xfe, 0x18, 0x3b, 0x54, 0xf6, 0x38, 0x21, 0xd0, 0xd9, 0x25,
+       0x7d, 0xbf, 0x57, 0xe1, 0xd6, 0x9c, 0x9b, 0x4f, 0x32, 0x4e, 0x7c, 0x4c,
+       0xee, 0x02, 0xcd, 0xb9, 0xf1, 0x2e, 0xd1, 0x6d, 0xe7, 0xc1, 0xef, 0x1d,
+       0x17, 0xbe, 0x16, 0xcf, 0x6c, 0x2b, 0x8e, 0x6c, 0xa9, 0xb3, 0x47, 0xec,
+       0xd1, 0x98, 0x23, 0xcb, 0x5e, 0xd8, 0x6f, 0x54, 0xea, 0xa8, 0xb3, 0x81,
+       0xb2, 0x93, 0x2d, 0xda, 0x88, 0xd3, 0xe1, 0xa7, 0x78, 0xbf, 0x0c, 0x8a,
+       0xf1, 0x6b, 0xea, 0x9a, 0x7b, 0xfa, 0x8c, 0x77, 0xf4, 0x29, 0x1f, 0xaa,
+       0x00, 0x9f, 0xab, 0x00, 0x7f, 0xab, 0xa0, 0xf4, 0x02, 0xe3, 0x1f, 0x8c,
+       0x4f, 0x95, 0x80, 0xed, 0x4b, 0x41, 0x8f, 0x77, 0x5c, 0xc5, 0xdd, 0x5e,
+       0xd8, 0xa6, 0x0f, 0xe0, 0x25, 0xef, 0x97, 0xd0, 0x86, 0xf4, 0x97, 0xa2,
+       0xd9, 0xf6, 0x18, 0x56, 0x52, 0xc5, 0x80, 0x7a, 0x81, 0x43, 0x1f, 0x87,
+       0xae, 0x7e, 0xd1, 0x67, 0xec, 0xea, 0x56, 0xf2, 0xfb, 0x2b, 0x9c, 0xa4,
+       0x3d, 0x36, 0x29, 0xde, 0x59, 0x6f, 0xfc, 0x7e, 0x21, 0xb6, 0x4f, 0x25,
+       0x8f, 0x90, 0x6f, 0xad, 0xef, 0x04, 0x42, 0xbb, 0x3a, 0x29, 0xa3, 0x67,
+       0x7f, 0xa4, 0xce, 0x04, 0x3e, 0xe2, 0x77, 0xca, 0x86, 0x8a, 0x7d, 0x4d,
+       0x0e, 0xc8, 0x28, 0xfc, 0x4a, 0x81, 0x75, 0xe2, 0x77, 0x03, 0x96, 0x2c,
+       0x67, 0xd4, 0xbb, 0xcc, 0x35, 0x93, 0xe6, 0x9e, 0x25, 0x63, 0x5b, 0x8c,
+       0x8d, 0x71, 0x4d, 0xfb, 0xd4, 0xdd, 0x4a, 0xde, 0xff, 0x9b, 0x69, 0x6a,
+       0x9b, 0x9b, 0x53, 0x77, 0x1c, 0x19, 0x2b, 0x63, 0xcc, 0x4b, 0xdf, 0x9f,
+       0x3b, 0xdc, 0xdc, 0x2b, 0x2e, 0x16, 0xde, 0xf7, 0xd3, 0x76, 0x6b, 0x37,
+       0x73, 0x00, 0xb6, 0xce, 0x55, 0xf1, 0x89, 0xa2, 0x3b, 0x20, 0xc7, 0xc6,
+       0x7b, 0xc0, 0xf3, 0x41, 0x75, 0x17, 0xcd, 0xf6, 0xde, 0x2f, 0x5d, 0xb4,
+       0x9b, 0xae, 0xba, 0x23, 0x6d, 0xf8, 0x7c, 0x07, 0xf2, 0x7e, 0x05, 0xde,
+       0x33, 0xef, 0x63, 0xfd, 0xda, 0x0e, 0x7d, 0x0a, 0x78, 0x9b, 0xf7, 0xca,
+       0xeb, 0x07, 0xf2, 0x6a, 0x3d, 0xe8, 0xf7, 0x86, 0xba, 0x29, 0xbc, 0xff,
+       0x18, 0x85, 0x6d, 0x72, 0xcd, 0x79, 0x71, 0x49, 0x96, 0x88, 0x01, 0x37,
+       0xa9, 0x7f, 0x2c, 0x35, 0xd6, 0xe5, 0xc8, 0xbb, 0xa4, 0x54, 0xdf, 0xeb,
+       0xdc, 0x3b, 0x08, 0xbe, 0xe1, 0xab, 0x3b, 0x97, 0xa7, 0x4a, 0x66, 0x8d,
+       0xf5, 0x37, 0x85, 0x4e, 0xdb, 0x7d, 0xee, 0xa8, 0xd2, 0xbb, 0xb9, 0x41,
+       0x60, 0x15, 0xef, 0xa3, 0xfd, 0x57, 0xef, 0xf0, 0xfd, 0xc6, 0xe0, 0x58,
+       0xde, 0xdf, 0xd3, 0x77, 0xbb, 0xed, 0x46, 0x28, 0x27, 0xf4, 0x9b, 0x89,
+       0x9f, 0x0f, 0xc2, 0xa7, 0x86, 0xde, 0x1c, 0xe2, 0xfb, 0x5f, 0x9a, 0xb6,
+       0x7c, 0x0e, 0xe4, 0xbe, 0xa9, 0xce, 0x33, 0xed, 0x69, 0x7d, 0x0f, 0x3c,
+       0x16, 0xde, 0x73, 0x1f, 0xee, 0xb8, 0x9b, 0xa4, 0xe8, 0x84, 0x3c, 0x85,
+       0x34, 0xe8, 0xb1, 0x0e, 0x83, 0xde, 0x46, 0x2d, 0x21, 0x83, 0x1e, 0x7d,
+       0xc5, 0x88, 0x4c, 0x0d, 0xa6, 0x5a, 0x77, 0xcd, 0x1b, 0x75, 0xd8, 0xfc,
+       0x5a, 0x48, 0xa7, 0xbe, 0x6b, 0xd8, 0xa8, 0xb3, 0x3c, 0x89, 0xb1, 0x7a,
+       0x64, 0x6a, 0x88, 0x7c, 0xee, 0xa4, 0x23, 0x61, 0xee, 0x23, 0x77, 0xe6,
+       0xdf, 0xdd, 0x46, 0xdf, 0xf5, 0xdf, 0x62, 0xea, 0xfb, 0x8f, 0xbc, 0xcb,
+       0x4e, 0x1a, 0x79, 0xce, 0x82, 0x39, 0xfa, 0xa1, 0x6f, 0x11, 0xf2, 0x65,
+       0x50, 0xdd, 0x97, 0x2f, 0xd4, 0xbb, 0x94, 0x5c, 0x2c, 0x64, 0x38, 0x17,
+       0xe2, 0xa0, 0xf0, 0x4e, 0xfc, 0x3f, 0x39, 0xa0, 0xd7, 0xfc, 0x63, 0xe1,
+       0x1c, 0x4d, 0x3e, 0xdb, 0xdf, 0x82, 0x36, 0x5f, 0x0d, 0xd0, 0x3f, 0x83,
+       0x5b, 0xd8, 0xf3, 0x21, 0x36, 0xbf, 0x45, 0xb7, 0x8f, 0x85, 0xdf, 0xe3,
+       0xb5, 0x7f, 0x1f, 0xc0, 0x3d, 0x15, 0xf2, 0x8d, 0x7d, 0x70, 0x7c, 0xd2,
+       0xc1, 0x71, 0x7b, 0xdb, 0xc6, 0x55, 0x3f, 0xff, 0x5a, 0xbd, 0x76, 0x47,
+       0xdb, 0x7c, 0x29, 0x5f, 0xfd, 0xb2, 0x54, 0x8b, 0x49, 0xb9, 0xa6, 0xfc,
+       0x99, 0x71, 0x20, 0x36, 0xe0, 0x39, 0xee, 0x45, 0x75, 0xff, 0xd6, 0xdc,
+       0x2d, 0x0c, 0xf7, 0x64, 0x3f, 0xea, 0xd1, 0x6e, 0x20, 0xad, 0x6b, 0x9d,
+       0x54, 0x97, 0xeb, 0xbf, 0x77, 0x58, 0x6c, 0x7d, 0xef, 0xa0, 0xfd, 0xe3,
+       0x62, 0xeb, 0x6e, 0x46, 0xb4, 0x34, 0x98, 0x6d, 0xbf, 0xef, 0x53, 0x92,
+       0x87, 0xee, 0xe4, 0x77, 0x06, 0x31, 0x23, 0x97, 0xef, 0x37, 0xe3, 0x60,
+       0xbc, 0xd5, 0x69, 0x19, 0x59, 0xfd, 0xbc, 0x14, 0xe7, 0xd4, 0x9d, 0xed,
+       0xb6, 0x3b, 0xfb, 0xa3, 0xe6, 0x3b, 0xa2, 0x9c, 0xc5, 0x3b, 0x20, 0x85,
+       0x55, 0xac, 0xd1, 0x9d, 0xa9, 0xf1, 0xa4, 0xcd, 0x6f, 0x59, 0x1f, 0x95,
+       0x91, 0xf5, 0x69, 0x49, 0xaf, 0x12, 0x27, 0xf0, 0x74, 0x3c, 0xa5, 0xe2,
+       0x8d, 0xe9, 0x73, 0xba, 0x3f, 0x6f, 0x95, 0xe5, 0x69, 0x60, 0x54, 0x96,
+       0x17, 0x12, 0x11, 0x75, 0x82, 0x7e, 0x1b, 0x64, 0xa8, 0xdb, 0x60, 0x00,
+       0x47, 0xf2, 0xab, 0x6c, 0x4f, 0xbc, 0xf1, 0x1c, 0xd6, 0xac, 0x90, 0xb4,
+       0x85, 0x6d, 0x54, 0x7f, 0x78, 0x8e, 0x2a, 0xec, 0x5c, 0xc8, 0x90, 0xd7,
+       0x93, 0xb2, 0xd9, 0xf4, 0xb0, 0x0f, 0xf4, 0x3d, 0xff, 0x62, 0x3d, 0xbc,
+       0x77, 0xf9, 0x90, 0xf9, 0x6e, 0x40, 0xd3, 0x38, 0x53, 0xe9, 0x94, 0xb7,
+       0xc7, 0xcc, 0x7d, 0x7f, 0xce, 0xdb, 0x6d, 0xd7, 0x79, 0xa6, 0xfe, 0x6b,
+       0x07, 0x78, 0x96, 0x4e, 0x9f, 0x68, 0xa4, 0xdd, 0xff, 0x88, 0xc7, 0xcd,
+       0x77, 0x16, 0x61, 0xbd, 0xff, 0x7d, 0x40, 0xdf, 0xd5, 0x27, 0x9f, 0xb2,
+       0x86, 0xe6, 0x29, 0xe5, 0xdf, 0xbc, 0x54, 0x3d, 0x88, 0xb6, 0x5c, 0x27,
+       0xa4, 0x0d, 0x3e, 0x53, 0x6f, 0x1e, 0x31, 0x67, 0x4e, 0x43, 0x6a, 0x2c,
+       0x37, 0xdb, 0xfe, 0x0d, 0x48, 0x6f, 0xdb, 0xf8, 0x9d, 0xf4, 0xf2, 0x9b,
+       0x90, 0x8b, 0x46, 0x5e, 0x58, 0xce, 0xf7, 0xce, 0x3a, 0x87, 0x0e, 0x84,
+       0xe5, 0x4e, 0xeb, 0xbb, 0x01, 0xf2, 0x92, 0xe7, 0x65, 0x48, 0x79, 0x4e,
+       0xa9, 0x9e, 0x91, 0x9a, 0xef, 0x21, 0x9c, 0x55, 0xfe, 0x3a, 0xfb, 0x71,
+       0xd0, 0x77, 0xb8, 0x4f, 0xf7, 0xba, 0x17, 0x43, 0xfd, 0x7b, 0xca, 0xda,
+       0xad, 0x44, 0xe9, 0xef, 0xc8, 0xb1, 0x4c, 0x3f, 0xfc, 0x7d, 0x9b, 0xdf,
+       0x78, 0x32, 0xb6, 0xc9, 0x33, 0x3d, 0x59, 0x54, 0x7a, 0x6d, 0x4c, 0xf4,
+       0xf7, 0xad, 0xbd, 0x32, 0xe3, 0x52, 0x9e, 0xc7, 0x64, 0xb3, 0x3e, 0xd7,
+       0x76, 0x57, 0xb6, 0xdb, 0xc8, 0xd9, 0x2b, 0x5d, 0x12, 0x2b, 0x59, 0x17,
+       0x2a, 0xe1, 0x3e, 0x1e, 0x93, 0x99, 0x7a, 0xfb, 0x7d, 0x68, 0xde, 0xb3,
+       0xa1, 0xdc, 0x0e, 0xb7, 0xed, 0x3d, 0xde, 0x4d, 0x03, 0x96, 0x8a, 0xd3,
+       0x1f, 0x65, 0xbd, 0xfd, 0xc6, 0xc6, 0x7e, 0xd4, 0x95, 0x98, 0x6b, 0x89,
+       0x47, 0xda, 0xfa, 0x4d, 0x5c, 0x3e, 0x2d, 0xf7, 0xc5, 0x4b, 0xf0, 0xc7,
+       0xc6, 0xcc, 0xb8, 0xef, 0xc1, 0x3b, 0xeb, 0x1e, 0x30, 0xe5, 0xb7, 0x98,
+       0xf7, 0x98, 0x79, 0x8f, 0xe0, 0x9d, 0x77, 0xac, 0xd9, 0x27, 0xd3, 0xe7,
+       0x55, 0xdc, 0x65, 0x20, 0x9b, 0x95, 0xae, 0x73, 0x02, 0xdb, 0x14, 0x93,
+       0xc7, 0xea, 0x8a, 0xbf, 0x96, 0xb7, 0x4a, 0x10, 0x70, 0x83, 0x79, 0xbe,
+       0x7e, 0x0f, 0x3e, 0x75, 0xcd, 0x37, 0x47, 0x7f, 0xe8, 0x6a, 0x59, 0x69,
+       0xa7, 0xf7, 0x6e, 0xd0, 0xfa, 0x76, 0xf7, 0x8f, 0x68, 0x97, 0xb4, 0x9f,
+       0x38, 0x53, 0xa1, 0x0e, 0xcc, 0xca, 0xb1, 0x0a, 0x68, 0xad, 0x0d, 0xbb,
+       0xfa, 0x9e, 0x08, 0xf9, 0xa5, 0xef, 0x0d, 0xe6, 0x6b, 0x63, 0xe6, 0x7c,
+       0x97, 0x6d, 0x79, 0x8f, 0x91, 0x7c, 0x8b, 0x76, 0xc4, 0x11, 0x68, 0x7f,
+       0x68, 0x5b, 0xf8, 0x2d, 0x8e, 0x8f, 0xba, 0xcb, 0xd4, 0x35, 0xb0, 0x4d,
+       0x21, 0x7e, 0xf8, 0x82, 0x89, 0x47, 0x85, 0x76, 0x9e, 0xdf, 0x47, 0x8b,
+       0xfc, 0x67, 0x60, 0x57, 0xfb, 0x74, 0xaf, 0x44, 0x4e, 0x87, 0x77, 0x90,
+       0xb8, 0xc6, 0xa3, 0xea, 0x8e, 0xd9, 0x6e, 0xf3, 0xc3, 0x28, 0x0b, 0xcf,
+       0x8a, 0xbb, 0xcc, 0x59, 0x71, 0x28, 0xe7, 0x70, 0x34, 0x62, 0x51, 0xc8,
+       0x38, 0xdb, 0xe7, 0x14, 0x5f, 0x73, 0x71, 0xe2, 0xac, 0x83, 0x26, 0x6e,
+       0xc0, 0xb2, 0x92, 0x0c, 0xdc, 0xf9, 0x61, 0xee, 0x8d, 0x77, 0x47, 0x24,
+       0xfc, 0x8e, 0x40, 0x8d, 0x13, 0xd7, 0xb8, 0x91, 0xdf, 0x57, 0xfb, 0xd8,
+       0x57, 0xfb, 0x76, 0xc2, 0xef, 0x08, 0xce, 0x37, 0x33, 0xea, 0x7b, 0x05,
+       0x9e, 0x25, 0xec, 0xf2, 0x1e, 0xd6, 0x2a, 0xbf, 0xa5, 0xa6, 0x6c, 0x9b,
+       0xef, 0xa8, 0xfb, 0x87, 0xe5, 0xe5, 0xa6, 0xfe, 0xf6, 0x42, 0xdf, 0xed,
+       0x25, 0x3e, 0x4b, 0xa2, 0x9c, 0x77, 0xc7, 0xf8, 0xad, 0x03, 0xff, 0x9f,
+       0xc2, 0x23, 0x48, 0x3f, 0x25, 0x1b, 0x15, 0x1d, 0xcf, 0x2c, 0xc3, 0x7f,
+       0x18, 0x59, 0x75, 0xd5, 0x99, 0xcb, 0xc8, 0xea, 0x0c, 0xc6, 0x0b, 0xbf,
+       0x7d, 0x8e, 0x23, 0x8f, 0xf4, 0x95, 0xcc, 0x1e, 0x0d, 0xef, 0x4b, 0xfc,
+       0x57, 0x97, 0x36, 0xa1, 0xd4, 0xec, 0x43, 0x5d, 0xcb, 0x60, 0x10, 0xe2,
+       0xbb, 0xf0, 0x1b, 0xaf, 0x18, 0x6d, 0x54, 0x40, 0x9d, 0x94, 0xc6, 0x38,
+       0x8d, 0x0a, 0xef, 0x5d, 0xa8, 0xff, 0xc3, 0xe0, 0x16, 0xe9, 0xa3, 0x29,
+       0x1d, 0x9f, 0x1a, 0x9f, 0x97, 0x82, 0xdb, 0x25, 0x09, 0xf5, 0x7f, 0x1d,
+       0x6c, 0xcc, 0x3d, 0xbf, 0xd6, 0xb7, 0x13, 0xc9, 0x72, 0x6e, 0x1c, 0x9b,
+       0xbe, 0x87, 0x9e, 0x0f, 0xbf, 0x19, 0x71, 0xb2, 0xbc, 0xdb, 0xcd, 0xef,
+       0x9e, 0x98, 0x5f, 0x02, 0xce, 0x0a, 0xbf, 0x73, 0xd1, 0xdf, 0x31, 0xcc,
+       0x37, 0x8f, 0xc8, 0x89, 0xca, 0x7e, 0x7e, 0x6f, 0xe1, 0xef, 0x82, 0x6f,
+       0xc7, 0x9a, 0x7d, 0xea, 0x5b, 0x8a, 0xf9, 0x26, 0xef, 0x8f, 0x85, 0xb6,
+       0x87, 0x6b, 0x15, 0x57, 0x67, 0x18, 0x2f, 0xa8, 0x6f, 0x2d, 0xf4, 0x77,
+       0x16, 0x8f, 0xa9, 0xef, 0x16, 0xf4, 0x7e, 0xbf, 0x1e, 0x7b, 0x53, 0x06,
+       0x3f, 0x07, 0x7f, 0x50, 0xeb, 0xdd, 0xfb, 0x32, 0xbc, 0x23, 0x19, 0x04,
+       0xc7, 0x7c, 0xc6, 0x45, 0x73, 0xd3, 0x1b, 0x98, 0xe3, 0x85, 0x3a, 0x78,
+       0x78, 0x94, 0x79, 0xbc, 0x43, 0xd5, 0x23, 0xf9, 0x49, 0xf5, 0x1d, 0xba,
+       0xb5, 0xe1, 0xed, 0x97, 0xf3, 0x35, 0xee, 0x05, 0x07, 0xf3, 0x4e, 0xb9,
+       0x0d, 0xb9, 0x61, 0x80, 0x67, 0x60, 0x87, 0x55, 0xfb, 0x70, 0xbf, 0xeb,
+       0x58, 0xc1, 0xe1, 0x4d, 0xad, 0x4f, 0x78, 0xbf, 0xae, 0xeb, 0xac, 0x58,
+       0x1f, 0xcf, 0x0c, 0xc3, 0xdf, 0xe6, 0x58, 0x69, 0xb4, 0x83, 0xec, 0x24,
+       0xb8, 0xd7, 0x7f, 0x15, 0x34, 0x40, 0xef, 0x95, 0x26, 0x31, 0x3a, 0x70,
+       0xd3, 0x1c, 0xdb, 0x64, 0xc5, 0x5e, 0x61, 0x9d, 0x41, 0xc8, 0x5f, 0x17,
+       0xe6, 0xe3, 0x00, 0xff, 0x1f, 0x90, 0x86, 0xcb, 0x32, 0x3e, 0x27, 0x4c,
+       0x6c, 0x42, 0x7d, 0x23, 0x0c, 0xfe, 0x25, 0x95, 0x4e, 0xca, 0xb9, 0x7a,
+       0x7c, 0xde, 0xe1, 0x5c, 0xa8, 0xcd, 0x62, 0x0f, 0x39, 0x06, 0x8f, 0x39,
+       0xe8, 0xe3, 0xd7, 0xe6, 0xbb, 0x8c, 0x92, 0x14, 0x32, 0x1a, 0x7f, 0x68,
+       0x1b, 0xc3, 0xf3, 0x12, 0x07, 0xf8, 0x3f, 0xdc, 0x97, 0x8f, 0x1d, 0xb8,
+       0xf6, 0xfb, 0x0d, 0x62, 0x97, 0x74, 0xe2, 0x0c, 0xcf, 0xb9, 0xb6, 0x1f,
+       0x94, 0x79, 0xd0, 0x7c, 0xca, 0xcc, 0xf3, 0xfe, 0x8c, 0x27, 0x97, 0xeb,
+       0x68, 0x93, 0x39, 0x88, 0x94, 0x77, 0xfd, 0x48, 0xf3, 0x84, 0xb9, 0xc7,
+       0x98, 0xc5, 0x5c, 0x1f, 0x95, 0xd7, 0x80, 0xa9, 0x5f, 0xaf, 0xa4, 0xfd,
+       0xc3, 0xea, 0x8e, 0x4e, 0x2a, 0x71, 0x5e, 0x26, 0x92, 0xf4, 0xfb, 0x4a,
+       0x6e, 0x2a, 0x71, 0x59, 0x78, 0xd7, 0xe8, 0xb1, 0x01, 0xfe, 0x4f, 0x87,
+       0x06, 0xec, 0xa1, 0xbe, 0x73, 0x94, 0x62, 0x9c, 0x04, 0xef, 0xc3, 0xe6,
+       0xbb, 0x22, 0x8e, 0xc3, 0xb2, 0x61, 0x79, 0xad, 0xd2, 0xb2, 0xbf, 0x1c,
+       0xc7, 0x7c, 0x4b, 0xce, 0xb1, 0xfe, 0xed, 0x00, 0xf5, 0x10, 0xc7, 0xd3,
+       0x7d, 0x84, 0x75, 0xc8, 0x57, 0xbd, 0xc6, 0xf9, 0x8c, 0xfa, 0xae, 0x35,
+       0x29, 0x96, 0x25, 0xdd, 0x1e, 0xe7, 0x7e, 0xd3, 0x80, 0xc6, 0x40, 0x6c,
+       0x97, 0x76, 0xef, 0x53, 0xfd, 0xf1, 0xac, 0x8c, 0xe7, 0x49, 0x61, 0x3f,
+       0xbc, 0x33, 0x84, 0x75, 0x8f, 0x73, 0xbd, 0xdb, 0x69, 0xd0, 0xf6, 0xff,
+       0x35, 0x15, 0xa3, 0x9e, 0x46, 0x7d, 0xda, 0x68, 0xc8, 0x4b, 0x3d, 0xd1,
+       0xfa, 0x36, 0x42, 0xf3, 0x92, 0xcf, 0x8f, 0xb5, 0xbe, 0x4f, 0xb0, 0x6f,
+       0x77, 0x4d, 0x79, 0x88, 0x45, 0x87, 0xb1, 0x5f, 0x1f, 0x95, 0xc6, 0x5a,
+       0x3a, 0xf1, 0x98, 0x84, 0xfd, 0x06, 0x87, 0x78, 0x8e, 0x30, 0x93, 0x99,
+       0x70, 0x97, 0x14, 0x3d, 0xa9, 0x04, 0xef, 0xdd, 0x9e, 0xc7, 0x78, 0x8d,
+       0x66, 0x67, 0xbc, 0x21, 0x95, 0xdb, 0x91, 0xb4, 0xaf, 0xd7, 0x66, 0x4c,
+       0x76, 0xb0, 0x36, 0x5f, 0x32, 0x6b, 0xf3, 0x41, 0xf4, 0xed, 0xad, 0x4c,
+       0x4a, 0x7a, 0x25, 0x9d, 0x3c, 0x25, 0x3c, 0x9b, 0x3b, 0xc0, 0xb8, 0x95,
+       0x75, 0x7f, 0x26, 0x89, 0xf9, 0xa6, 0x30, 0x5f, 0xa4, 0x4d, 0x3e, 0x4f,
+       0xc0, 0x1f, 0xdf, 0xc7, 0xbd, 0x7d, 0x88, 0x3a, 0x93, 0xbc, 0x98, 0x51,
+       0x65, 0x8f, 0x9a, 0xbb, 0x94, 0xdf, 0xe3, 0xfa, 0xa8, 0xb8, 0xdf, 0xe5,
+       0x26, 0xcf, 0xeb, 0x34, 0x7d, 0x05, 0xd0, 0xb7, 0xa8, 0xe9, 0x4b, 0xce,
+       0xb7, 0xf0, 0x6a, 0x2a, 0x71, 0x42, 0x88, 0x97, 0x88, 0x5f, 0x88, 0xe5,
+       0x6f, 0x19, 0xd4, 0xdf, 0x7e, 0xc0, 0x77, 0xbd, 0x3d, 0xd7, 0x9a, 0x7b,
+       0x37, 0xea, 0x5e, 0x80, 0xee, 0xa7, 0xbc, 0x1c, 0x91, 0x0f, 0x48, 0xee,
+       0x91, 0x54, 0x32, 0x67, 0x79, 0x06, 0x03, 0x22, 0xad, 0xf3, 0x99, 0x3a,
+       0xd7, 0x33, 0xd8, 0x82, 0x6b, 0x93, 0xc1, 0x58, 0xfa, 0x3b, 0x92, 0x5d,
+       0xcc, 0x2d, 0xaf, 0x64, 0xed, 0xf7, 0xb1, 0x87, 0xf4, 0xff, 0xb3, 0x38,
+       0x0f, 0x3e, 0x96, 0xc1, 0xc7, 0xc7, 0xaf, 0xc3, 0x60, 0x5d, 0x2d, 0x0c,
+       0xb6, 0xab, 0xc6, 0xb3, 0x40, 0x53, 0xc1, 0x25, 0xfe, 0x2a, 0xb7, 0x64,
+       0x85, 0x34, 0x4d, 0xf2, 0x7f, 0xd2, 0xc8, 0xcb, 0x19, 0xae, 0x07, 0x30,
+       0x18, 0xfa, 0xdb, 0xb8, 0x2a, 0x4b, 0x98, 0xbf, 0x92, 0x5f, 0xc8, 0x6e,
+       0xca, 0x75, 0x2c, 0xae, 0x05, 0xfb, 0x13, 0xeb, 0x22, 0x68, 0xd9, 0x55,
+       0x72, 0xa0, 0x65, 0x60, 0xb7, 0x1e, 0x7b, 0x07, 0x19, 0xe0, 0x3c, 0x29,
+       0x7f, 0xa1, 0xec, 0xb5, 0xbe, 0x39, 0x87, 0x4f, 0x5b, 0x92, 0xdb, 0xee,
+       0xc8, 0x4a, 0x7e, 0x85, 0x67, 0x4b, 0x62, 0x4d, 0xdc, 0x41, 0x99, 0x24,
+       0x4e, 0x00, 0x86, 0x4c, 0x90, 0xc7, 0x1a, 0x0f, 0xce, 0x3f, 0xb7, 0x1f,
+       0xbf, 0x73, 0x03, 0xbc, 0x5b, 0x92, 0xdf, 0xa2, 0xbe, 0x12, 0xeb, 0xd6,
+       0x3b, 0xb4, 0x4f, 0x78, 0x25, 0x0e, 0x9e, 0xa3, 0x7c, 0xe4, 0xcb, 0xdd,
+       0xd0, 0x57, 0x8e, 0x99, 0x37, 0xdf, 0xc9, 0x57, 0xa4, 0xcf, 0x71, 0x5c,
+       0xed, 0x5f, 0xe8, 0x38, 0x20, 0xf7, 0x45, 0x49, 0x16, 0xa1, 0x0f, 0x16,
+       0x32, 0x31, 0x39, 0x5c, 0x8b, 0xcb, 0x91, 0xca, 0xb4, 0x7c, 0xb1, 0xd2,
+       0xa7, 0x70, 0xc3, 0x9f, 0xfb, 0xe9, 0xc4, 0xb8, 0x15, 0xc8, 0xfd, 0xc0,
+       0x3f, 0xf3, 0xc3, 0xdd, 0xf2, 0xfa, 0xa4, 0xa5, 0xf4, 0xde, 0x15, 0x7e,
+       0x18, 0xed, 0xf2, 0x0e, 0x27, 0xe7, 0x03, 0xbd, 0x6f, 0xc1, 0x17, 0xb0,
+       0x78, 0x6f, 0xaf, 0x4f, 0x1e, 0xf0, 0x91, 0xde, 0xe8, 0xab, 0xef, 0x62,
+       0xcd, 0x77, 0x5c, 0x46, 0x8f, 0x9c, 0x33, 0x63, 0x1f, 0x31, 0x69, 0x6a,
+       0xb0, 0x8d, 0x16, 0x6b, 0x31, 0x13, 0x51, 0xf3, 0x2b, 0xd7, 0xa9, 0xdf,
+       0xd8, 0x06, 0xfa, 0x04, 0x7b, 0xb7, 0x0b, 0x7c, 0xd9, 0x80, 0x7e, 0x29,
+       0xd6, 0xc4, 0xda, 0xca, 0x00, 0x51, 0x7b, 0x1a, 0x7f, 0x16, 0x21, 0x5f,
+       0x0b, 0x35, 0xea, 0xbf, 0x23, 0x90, 0x05, 0xda, 0x6f, 0x87, 0xdf, 0xdc,
+       0x00, 0x43, 0x98, 0x3b, 0x1f, 0x31, 0xc6, 0x40, 0xda, 0x75, 0x58, 0xf8,
+       0x3f, 0x67, 0x3e, 0x3e, 0x28, 0xfd, 0x25, 0xac, 0x4b, 0x88, 0xb9, 0xc1,
+       0x53, 0x8c, 0x99, 0x57, 0xeb, 0x14, 0xae, 0x09, 0x75, 0x4f, 0x88, 0x37,
+       0xda, 0xfd, 0x23, 0xee, 0x59, 0xda, 0x0b, 0x29, 0x45, 0x81, 0x69, 0x7b,
+       0x57, 0x60, 0xbb, 0x6b, 0x59, 0xc8, 0x0a, 0xef, 0xe1, 0x4f, 0x4b, 0x19,
+       0xd8, 0xed, 0xe3, 0xfe, 0xe7, 0xc4, 0x7e, 0xf6, 0xa0, 0x6c, 0xd4, 0x7a,
+       0xc1, 0x0f, 0xda, 0x85, 0x2e, 0xe5, 0x53, 0x5f, 0x39, 0x4a, 0x7b, 0x47,
+       0x5b, 0xa2, 0xd7, 0x62, 0xb7, 0x0e, 0x27, 0x38, 0xa6, 0xf3, 0x76, 0xea,
+       0xa1, 0x2d, 0xe4, 0xf7, 0x34, 0x5d, 0xc6, 0x2e, 0xc7, 0xa0, 0xbb, 0xd7,
+       0xa5, 0xa1, 0xfc, 0x73, 0xce, 0x9f, 0x36, 0xa8, 0x8b, 0xf7, 0xc7, 0xac,
+       0x86, 0xc7, 0xb9, 0xb7, 0xdb, 0x20, 0x8d, 0x3b, 0xdc, 0x3b, 0x39, 0x1e,
+       0xef, 0x26, 0x70, 0x8e, 0x71, 0xe9, 0x3a, 0xf3, 0xa8, 0xd8, 0xf0, 0x5b,
+       0x22, 0xab, 0xc4, 0x7a, 0xd7, 0xfa, 0x2e, 0x91, 0x73, 0x51, 0xf3, 0xfd,
+       0xf0, 0xa8, 0xc6, 0x32, 0x19, 0xa4, 0x8d, 0xf0, 0x9b, 0x62, 0xfe, 0xda,
+       0xed, 0x66, 0xe8, 0x5b, 0xec, 0x69, 0x4b, 0xf1, 0xf7, 0x7f, 0x00, 0xb6,
+       0x9d, 0x3c, 0x32, 0x44, 0x4b, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = {
-       0x08001b7c, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8,
-       0x08001ac8, 0x08001bb8, 0x08001b3c, 0x08001bb8, 0x08001a50, 0x08001bb8,
-       0x08001bb8, 0x08001bb8, 0x08001a5c, 0x00000000, 0x08002b74, 0x08002bc4,
-       0x08002bf4, 0x08002c24, 0x08002c58, 0x00000000, 0x08006120, 0x08006120,
-       0x08006120, 0x08006120, 0x08006120, 0x0800614c, 0x0800614c, 0x0800618c,
-       0x08006198, 0x08006198, 0x08006120, 0x00000000, 0x00000000 };
+static const u32 bnx2_COM_b09FwRodata[(0x30/4) + 1] = {
+       0x80080100, 0x80080080, 0x80080000, 0x80080240, 0x08000e94, 0x08000eec,
+       0x08000f30, 0x08000fc4, 0x08001008, 0x80080100, 0x80080080, 0x80080000,
+       0x00000000 };
 
 static struct fw_info bnx2_com_fw_09 = {
-       /* Firmware version:  3.7.1 */
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x7,
-       .ver_fix                        = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x080000b4,
+       .start_addr                     = 0x080000f8,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x7e94,
+       .text_len                       = 0x4b40,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_COM_b09FwText,
        .gz_text_len                    = sizeof(bnx2_COM_b09FwText),
 
-       .data_addr                      = 0x08007f40,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_COM_b09FwData,
 
-       .sbss_addr                      = 0x08007f40,
-       .sbss_len                       = 0x60,
+       .sbss_addr                      = 0x08004ba0,
+       .sbss_len                       = 0x38,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08007fa0,
-       .bss_len                        = 0x88,
+       .bss_addr                       = 0x08004bd8,
+       .bss_len                        = 0xbc,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08007e98,
-       .rodata_len                     = 0x88,
+       .rodata_addr                    = 0x08004b40,
+       .rodata_len                     = 0x30,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_COM_b09FwRodata,
 };
 
 static u8 bnx2_CP_b09FwText[] = {
-       0xbd, 0x7d, 0x0d, 0x74, 0x5c, 0xd7, 0x5d, 0xe7, 0xff, 0xdd, 0x79, 0x92,
-       0xc6, 0xb2, 0x6c, 0x3f, 0xcb, 0x13, 0x79, 0x62, 0xab, 0xf6, 0x8c, 0xf4,
-       0x64, 0xab, 0x91, 0x08, 0x2f, 0xae, 0x28, 0x82, 0x9d, 0x84, 0xe9, 0x48,
-       0xb2, 0x9d, 0x34, 0xed, 0xca, 0x8d, 0x5b, 0xb2, 0x9c, 0x02, 0x62, 0x24,
-       0x27, 0xe9, 0x77, 0xd2, 0x04, 0xb6, 0xec, 0xc9, 0x6e, 0x26, 0x23, 0xf9,
-       0x83, 0x74, 0xec, 0x51, 0x12, 0x25, 0xce, 0xa1, 0x3d, 0xbb, 0xaa, 0xa4,
-       0xd8, 0x06, 0x06, 0x8f, 0x93, 0xb8, 0xa5, 0xec, 0xa6, 0x54, 0x28, 0xae,
-       0x09, 0xa1, 0x07, 0x52, 0x48, 0xd9, 0x40, 0x53, 0x2a, 0xdc, 0xb4, 0xcd,
-       0x9e, 0x53, 0xb6, 0x01, 0xca, 0x12, 0x68, 0xe8, 0xdb, 0xdf, 0xef, 0xde,
-       0xfb, 0x34, 0xa3, 0x0f, 0xe7, 0xa3, 0xec, 0xe2, 0x73, 0x9e, 0xdf, 0xbc,
-       0xfb, 0xee, 0xc7, 0xff, 0xfe, 0xef, 0xff, 0xfb, 0xfe, 0xef, 0xd3, 0x76,
-       0x91, 0x66, 0xb1, 0xff, 0x36, 0xe0, 0x7a, 0x5b, 0xea, 0xf6, 0xd1, 0x6b,
-       0xae, 0xfe, 0xc9, 0xab, 0xf9, 0xec, 0x3a, 0x4d, 0x31, 0x79, 0x13, 0xff,
-       0x52, 0x6f, 0xa0, 0x0e, 0x3a, 0xf4, 0xa2, 0xb1, 0x78, 0x49, 0x5c, 0x65,
-       0xdc, 0x3b, 0x72, 0xbe, 0xc4, 0x63, 0x99, 0x91, 0x5f, 0x1e, 0xf5, 0x45,
-       0xb2, 0x95, 0x9e, 0xd4, 0x80, 0xfc, 0x4b, 0x58, 0x48, 0xb8, 0xc2, 0xf2,
-       0xb7, 0x64, 0x5e, 0xfd, 0x6f, 0x5f, 0xf8, 0xc9, 0xf4, 0xcb, 0xd3, 0x31,
-       0x89, 0x7b, 0x99, 0x0f, 0x8b, 0xb7, 0x4b, 0xe2, 0xed, 0x19, 0xb9, 0xe3,
-       0xd3, 0xbb, 0xff, 0x46, 0x64, 0x63, 0xd4, 0xd7, 0x4b, 0xe1, 0x17, 0x76,
-       0x4b, 0x61, 0x5b, 0x26, 0x39, 0xd2, 0x90, 0x49, 0xc8, 0x17, 0xab, 0x9e,
-       0x9c, 0xab, 0xca, 0xf0, 0xa9, 0xd2, 0xcb, 0xa1, 0x9b, 0x09, 0x63, 0x13,
-       0x7d, 0x8e, 0xc4, 0x32, 0x72, 0x61, 0xb4, 0xef, 0x9e, 0x50, 0xf9, 0x32,
-       0xe2, 0x65, 0xfc, 0x60, 0x41, 0x5a, 0xfa, 0x2f, 0xf6, 0xa1, 0x4e, 0xe5,
-       0xe0, 0xb5, 0x8d, 0x27, 0xe2, 0xa2, 0x32, 0x5d, 0xcf, 0xe7, 0x62, 0xd7,
-       0x88, 0xf2, 0xfd, 0xe0, 0x82, 0x74, 0x05, 0x4f, 0x09, 0xca, 0xcf, 0xc6,
-       0x25, 0x57, 0x95, 0x16, 0x94, 0xe1, 0xde, 0x8c, 0x3a, 0x69, 0x2f, 0x17,
-       0x4b, 0x48, 0xb1, 0xfa, 0x63, 0xcd, 0x66, 0xec, 0xaf, 0xaf, 0x33, 0xf7,
-       0xdd, 0xf6, 0xbe, 0xee, 0x67, 0xdd, 0x4c, 0x3c, 0xae, 0x4e, 0xc8, 0xcb,
-       0x13, 0x7d, 0x2f, 0x87, 0x31, 0xdf, 0xf7, 0x06, 0xa4, 0x41, 0x06, 0x13,
-       0x80, 0xa9, 0xec, 0xa0, 0xef, 0x14, 0xda, 0xfe, 0x12, 0x70, 0x0e, 0xf8,
-       0xca, 0x29, 0x29, 0x10, 0xce, 0x72, 0x5c, 0x16, 0x63, 0x49, 0x01, 0xfc,
-       0xc0, 0x45, 0xbb, 0x8c, 0xa3, 0x3c, 0x57, 0xe2, 0x7c, 0x5c, 0xc9, 0x7b,
-       0x1e, 0xe6, 0xd2, 0x8e, 0x36, 0x3b, 0x1d, 0xd3, 0x3f, 0x9e, 0x97, 0xd5,
-       0x67, 0xdd, 0xe7, 0x51, 0x37, 0xa5, 0xeb, 0x3d, 0x51, 0x4d, 0xca, 0xe3,
-       0xd5, 0x84, 0x3c, 0x56, 0xfd, 0x98, 0x64, 0x3d, 0xe2, 0x00, 0xb0, 0x96,
-       0x1b, 0x65, 0x60, 0xaa, 0x59, 0x72, 0x53, 0x9d, 0xc9, 0xbc, 0x84, 0xe1,
-       0x9d, 0xc1, 0x07, 0x64, 0xa4, 0x15, 0xf5, 0xcb, 0x7c, 0x97, 0x5c, 0xf6,
-       0x2e, 0x1f, 0xf4, 0x78, 0x79, 0xe5, 0x48, 0xf6, 0x60, 0x3a, 0x39, 0xa2,
-       0xf8, 0xdc, 0x20, 0xb9, 0x5e, 0x3c, 0x0f, 0xbb, 0x12, 0xf3, 0xc3, 0xf0,
-       0x8e, 0x60, 0x17, 0xe0, 0x48, 0xa7, 0x52, 0x8a, 0x6d, 0xd9, 0x2e, 0x5d,
-       0x48, 0xa9, 0x24, 0xe6, 0x71, 0xb5, 0xa4, 0x5a, 0xc3, 0xf0, 0x3d, 0x81,
-       0x8f, 0x72, 0x91, 0x81, 0x92, 0xdc, 0xae, 0x32, 0x3e, 0xfa, 0x94, 0x40,
-       0x65, 0xb6, 0x60, 0x1e, 0x3d, 0xc0, 0x43, 0xa3, 0x64, 0x13, 0x92, 0x55,
-       0x19, 0x49, 0xa9, 0xcc, 0x3a, 0x94, 0x39, 0xd2, 0xe0, 0xff, 0x77, 0x4b,
-       0x7f, 0x9b, 0xf0, 0x2c, 0xc3, 0x2a, 0xd3, 0xba, 0xa2, 0x3c, 0x9d, 0x12,
-       0xf5, 0xe3, 0x71, 0x8c, 0xd9, 0x9d, 0x55, 0x2c, 0xc3, 0x5d, 0x97, 0x15,
-       0x9a, 0x56, 0x97, 0x4d, 0x3a, 0xcb, 0xcb, 0x4e, 0xb5, 0x10, 0x56, 0x51,
-       0xfc, 0x9d, 0xd4, 0x73, 0xcd, 0x26, 0x3a, 0xbd, 0x06, 0xcc, 0x6b, 0x38,
-       0x48, 0x7b, 0x43, 0xea, 0xb9, 0x50, 0xda, 0x08, 0x33, 0xdf, 0x29, 0xbc,
-       0x43, 0xd5, 0x4c, 0x80, 0x75, 0x4e, 0xc8, 0x51, 0xcc, 0xed, 0xd2, 0x54,
-       0xda, 0xeb, 0x50, 0xb8, 0xcf, 0xf1, 0x77, 0x18, 0xe6, 0x82, 0x82, 0xa6,
-       0x81, 0x6f, 0x4e, 0x25, 0xf1, 0x0c, 0xf8, 0x13, 0xd9, 0xf4, 0x66, 0xb9,
-       0xc9, 0xae, 0xcb, 0x37, 0x31, 0x66, 0xa7, 0x77, 0x87, 0xea, 0xf4, 0x02,
-       0x95, 0xf6, 0x66, 0xe4, 0xf7, 0xf1, 0x1c, 0x86, 0x07, 0x82, 0x74, 0xb2,
-       0x80, 0x35, 0x7b, 0xb1, 0x94, 0x90, 0x6f, 0x95, 0xd2, 0xa0, 0xfc, 0x74,
-       0xf7, 0xac, 0xf4, 0x04, 0xb3, 0x80, 0xb7, 0x88, 0xeb, 0x08, 0xdf, 0x55,
-       0xf0, 0xae, 0xc2, 0xb6, 0x61, 0x78, 0x53, 0xf0, 0xeb, 0xe1, 0x48, 0x9b,
-       0xe1, 0xa5, 0x2f, 0x96, 0xb1, 0x9e, 0x80, 0xf9, 0x71, 0xac, 0xd3, 0x63,
-       0xe5, 0x88, 0x4e, 0xba, 0xb1, 0xee, 0xa4, 0x0d, 0xd2, 0xc5, 0x1e, 0x4b,
-       0xff, 0xa3, 0xf6, 0x2e, 0x92, 0x03, 0x8d, 0xe5, 0x82, 0x1f, 0x84, 0x59,
-       0xcd, 0x63, 0xe2, 0x0c, 0x94, 0x49, 0xbb, 0x0d, 0x80, 0x95, 0x8f, 0x1f,
-       0xb3, 0xf5, 0xda, 0x1d, 0xe0, 0x96, 0xeb, 0xc0, 0xf7, 0x71, 0xe5, 0x37,
-       0xd9, 0xf7, 0x11, 0x2f, 0xf1, 0x1f, 0xe8, 0xcd, 0xaf, 0xd5, 0xcb, 0x91,
-       0x26, 0xab, 0x05, 0xc9, 0x3f, 0x18, 0xca, 0x40, 0x00, 0x3c, 0xb1, 0x4f,
-       0x2f, 0x10, 0xdd, 0xd6, 0x63, 0x1d, 0x5d, 0x17, 0xff, 0xae, 0x69, 0xc4,
-       0x18, 0xce, 0x60, 0xb9, 0xd6, 0x76, 0xb0, 0xfc, 0xe4, 0x16, 0x0b, 0x1f,
-       0x9e, 0xfb, 0x9d, 0x5c, 0xf5, 0x6f, 0xed, 0xda, 0x46, 0xf3, 0xb8, 0x69,
-       0x0d, 0xda, 0x0e, 0xc3, 0x89, 0x40, 0x46, 0x54, 0x66, 0x31, 0x9e, 0x2b,
-       0x89, 0xd3, 0x90, 0xf1, 0xbd, 0x21, 0x59, 0x27, 0x76, 0x5e, 0xb6, 0xdc,
-       0x03, 0xaf, 0x74, 0xa1, 0xdc, 0x11, 0xc8, 0x8d, 0x11, 0x07, 0x65, 0x1d,
-       0x15, 0x94, 0x61, 0xfd, 0xc6, 0x81, 0xaf, 0x7c, 0xa9, 0x5f, 0xaf, 0x65,
-       0xbe, 0x34, 0x0c, 0xde, 0xcf, 0xe0, 0x77, 0x76, 0xb3, 0x2b, 0x5d, 0xa0,
-       0x43, 0xae, 0xb1, 0xb8, 0xb9, 0xdd, 0xa0, 0xd5, 0xea, 0xeb, 0x4b, 0x2c,
-       0x3d, 0xf7, 0xe0, 0x5f, 0x88, 0xd3, 0x25, 0x78, 0x62, 0x19, 0xf2, 0xf5,
-       0xf3, 0x21, 0xe8, 0x19, 0x65, 0x84, 0x99, 0x35, 0x13, 0x32, 0x51, 0xde,
-       0x26, 0xc5, 0x29, 0x5f, 0xc6, 0x4b, 0xf3, 0xdd, 0x4a, 0x5e, 0x86, 0xac,
-       0xf1, 0x41, 0x0b, 0x69, 0xf0, 0x41, 0x46, 0x06, 0xaa, 0x18, 0xaf, 0x84,
-       0x7b, 0xb9, 0x13, 0x6d, 0x5d, 0xc9, 0x26, 0xcd, 0x3a, 0x17, 0x4b, 0x63,
-       0xc0, 0x15, 0xd6, 0x8d, 0xb2, 0x41, 0xc3, 0x3c, 0x0c, 0x3a, 0xf4, 0x24,
-       0xd7, 0xa7, 0xe1, 0x7c, 0x13, 0xf0, 0xc5, 0x65, 0x26, 0x68, 0xb4, 0x38,
-       0x22, 0x7f, 0xc6, 0xdd, 0x01, 0xe0, 0x61, 0xa0, 0x72, 0x0f, 0xfa, 0x6f,
-       0xc1, 0x6f, 0x96, 0x89, 0x2d, 0x73, 0xf5, 0xf3, 0x40, 0x85, 0x30, 0x47,
-       0x74, 0x0f, 0x3e, 0x98, 0x82, 0xfc, 0x01, 0xdd, 0x0f, 0x90, 0x5f, 0xe6,
-       0x38, 0x17, 0xc2, 0xb5, 0x4d, 0xff, 0x1e, 0x9f, 0xda, 0xa1, 0x9f, 0xf3,
-       0xc3, 0xdb, 0xa4, 0x30, 0x17, 0xcd, 0x99, 0xb2, 0x87, 0xf2, 0x26, 0x7d,
-       0x0c, 0x74, 0x05, 0xf9, 0x13, 0x86, 0x0f, 0x06, 0x94, 0x41, 0x61, 0xf8,
-       0x78, 0x40, 0x99, 0x74, 0x1e, 0xb2, 0x86, 0x72, 0x88, 0x72, 0x61, 0x50,
-       0x71, 0xdd, 0x73, 0xa5, 0x00, 0xeb, 0xd3, 0x28, 0xf9, 0xde, 0x47, 0x08,
-       0x2b, 0x64, 0xd8, 0xb3, 0x1f, 0xcb, 0xf9, 0x85, 0x64, 0x4c, 0xe3, 0x49,
-       0xb0, 0x5e, 0x71, 0xc9, 0xea, 0x99, 0x75, 0x48, 0xb1, 0x77, 0xd2, 0xd6,
-       0x79, 0x49, 0xd7, 0x71, 0x57, 0xd5, 0xf9, 0x75, 0x65, 0x78, 0x3c, 0xc0,
-       0x5a, 0xfe, 0xb4, 0x22, 0x1e, 0x3b, 0x76, 0xf1, 0x59, 0xe2, 0x0d, 0x99,
-       0xaf, 0xe1, 0xdd, 0xb9, 0x3b, 0x1f, 0xf5, 0xd7, 0x7a, 0xb7, 0xb5, 0x61,
-       0xf5, 0xbb, 0x09, 0x71, 0xfd, 0x74, 0xf7, 0x01, 0xf5, 0x4f, 0x78, 0x17,
-       0x86, 0x8f, 0x06, 0x51, 0x79, 0x6f, 0xc3, 0xea, 0x31, 0x7e, 0x76, 0x8d,
-       0xb2, 0xf3, 0x6b, 0x94, 0xfd, 0xc9, 0x1a, 0x65, 0xef, 0x6d, 0x5c, 0x5d,
-       0xf6, 0xc0, 0x1a, 0x65, 0x4f, 0xaf, 0x51, 0xe6, 0x37, 0xad, 0x2e, 0xdb,
-       0xb5, 0x46, 0xd9, 0x5b, 0xd7, 0x28, 0x3b, 0xb0, 0x46, 0x99, 0x0b, 0x1e,
-       0xde, 0x25, 0xc5, 0xc4, 0xbd, 0x9c, 0xbb, 0xc5, 0xcd, 0xe7, 0x62, 0xab,
-       0x71, 0xd3, 0x80, 0x7a, 0xed, 0x2b, 0xea, 0x7d, 0x6d, 0x8d, 0x7a, 0x8d,
-       0xa8, 0xd7, 0xba, 0xa2, 0xde, 0xcd, 0xee, 0xea, 0x7a, 0x4d, 0xa8, 0x17,
-       0x5f, 0x51, 0xef, 0x77, 0xd7, 0xa8, 0xc7, 0xf2, 0x4f, 0xd9, 0x71, 0x7a,
-       0xa0, 0xd1, 0x5e, 0x6b, 0xbd, 0x1a, 0x45, 0xda, 0x58, 0x1e, 0x40, 0x1f,
-       0xfd, 0xb4, 0x32, 0x32, 0x86, 0xf2, 0x4c, 0xe3, 0x0d, 0x74, 0x9e, 0x04,
-       0xdd, 0x51, 0x26, 0x83, 0xcf, 0x7c, 0xf2, 0xfe, 0x06, 0x19, 0x49, 0xf4,
-       0x78, 0x6f, 0x53, 0x2d, 0xa0, 0xb1, 0xb4, 0x97, 0x52, 0xe4, 0x3f, 0x29,
-       0x80, 0xb7, 0x0b, 0x03, 0xa2, 0x12, 0x4a, 0x42, 0x19, 0x0c, 0x54, 0xab,
-       0x92, 0x7b, 0xc0, 0x5f, 0x59, 0xe8, 0xbf, 0x03, 0xe1, 0x80, 0xe6, 0x2d,
-       0x53, 0xf7, 0xf2, 0xf2, 0xb9, 0x5f, 0x8e, 0x50, 0xae, 0x66, 0x82, 0x3b,
-       0x73, 0xfe, 0x7c, 0x7f, 0x23, 0x68, 0xf6, 0x12, 0xda, 0xec, 0x43, 0xcb,
-       0x43, 0x15, 0x57, 0x06, 0x2b, 0x19, 0xf0, 0x82, 0x23, 0x17, 0xfd, 0x4d,
-       0x72, 0x31, 0x40, 0xdd, 0x6a, 0x4c, 0x16, 0x12, 0x8e, 0x2c, 0xe0, 0x39,
-       0x17, 0xe0, 0x5d, 0x35, 0xe2, 0xad, 0x8c, 0x1c, 0x2e, 0xf7, 0xcb, 0xb1,
-       0xf2, 0x87, 0x55, 0xa4, 0x23, 0x87, 0x82, 0xf5, 0x72, 0xc6, 0x33, 0x7d,
-       0xef, 0xf3, 0xe7, 0xa1, 0x9d, 0x5d, 0xb9, 0xe4, 0xa7, 0x93, 0x0b, 0x9a,
-       0x27, 0xfe, 0x31, 0x1c, 0x44, 0x3f, 0x33, 0x7e, 0xda, 0xfb, 0x03, 0x0a,
-       0xc9, 0x0a, 0x6d, 0xa9, 0x5a, 0x5f, 0xe3, 0xe8, 0xeb, 0x68, 0x79, 0x83,
-       0xdc, 0x6a, 0xdb, 0xef, 0xf5, 0xe7, 0xbb, 0xc1, 0x73, 0xde, 0x29, 0xca,
-       0x90, 0x12, 0xe0, 0x3a, 0x08, 0xde, 0x46, 0xdb, 0x2f, 0x09, 0xdb, 0xc0,
-       0xf6, 0x2a, 0x6d, 0x82, 0xac, 0xff, 0x87, 0xf0, 0xd6, 0x04, 0xeb, 0xb3,
-       0x8c, 0xfa, 0x4b, 0x26, 0x55, 0x06, 0x32, 0xa1, 0xaf, 0x0b, 0xfa, 0x2b,
-       0x25, 0x83, 0x55, 0xc8, 0x9e, 0xf2, 0x0f, 0xc3, 0xac, 0xcb, 0x31, 0xa2,
-       0xb1, 0xa4, 0x50, 0xab, 0xc3, 0x32, 0xd6, 0x23, 0xff, 0x2f, 0x2e, 0xc9,
-       0x8a, 0x02, 0xe4, 0x8b, 0xb1, 0xd1, 0xfe, 0x13, 0x78, 0xb4, 0x5d, 0x06,
-       0x4b, 0xe9, 0x42, 0x56, 0x76, 0x61, 0xfd, 0x7e, 0x0d, 0x6b, 0xea, 0xe2,
-       0xfa, 0x93, 0xf5, 0xb2, 0x31, 0x80, 0x1d, 0xc0, 0x72, 0x74, 0xda, 0x46,
-       0xfb, 0xec, 0x19, 0xe0, 0x61, 0x9c, 0x6b, 0x9e, 0xcc, 0xc5, 0x9c, 0x61,
-       0xda, 0x3e, 0xc3, 0x90, 0x8f, 0xf9, 0x0a, 0xfb, 0x26, 0xbc, 0x49, 0xfb,
-       0x1b, 0x36, 0x5b, 0xa9, 0xdd, 0xfe, 0x6e, 0xc1, 0xef, 0x94, 0xfd, 0x0d,
-       0x99, 0x5a, 0xf2, 0xed, 0xef, 0x04, 0x7e, 0x77, 0xdb, 0xdf, 0x49, 0xfc,
-       0xee, 0xd5, 0xbf, 0x27, 0xca, 0x7b, 0xf7, 0x2a, 0xff, 0x6a, 0xc9, 0xcf,
-       0xb5, 0xcb, 0xe1, 0xd2, 0x7b, 0xad, 0x6c, 0xc1, 0x25, 0x9f, 0x77, 0xcc,
-       0x3c, 0x01, 0x77, 0x99, 0x6d, 0x0a, 0xce, 0xb0, 0xb6, 0xdd, 0xda, 0x61,
-       0xeb, 0xf4, 0x78, 0x9b, 0x85, 0x34, 0x30, 0xe1, 0x0c, 0x54, 0x9d, 0x6c,
-       0x2c, 0xd3, 0x95, 0x1c, 0x97, 0x63, 0xf8, 0x2d, 0x5e, 0x2c, 0xf3, 0x79,
-       0xdc, 0x0d, 0x0e, 0xbe, 0x00, 0x7d, 0x33, 0x5e, 0xa6, 0xbc, 0xf4, 0x31,
-       0xf7, 0x94, 0x9c, 0x5f, 0x66, 0xaf, 0x11, 0x17, 0x4a, 0xf2, 0x53, 0xe9,
-       0x47, 0x0a, 0x92, 0x2e, 0x4c, 0x83, 0x21, 0x0e, 0x04, 0xae, 0xbc, 0x27,
-       0x00, 0xed, 0x5e, 0xed, 0xc8, 0xde, 0xab, 0x5d, 0xd8, 0x57, 0xfe, 0xf4,
-       0x5e, 0xc8, 0xd8, 0x7c, 0xe9, 0xea, 0x18, 0xe9, 0x41, 0x9d, 0x95, 0x11,
-       0x37, 0x03, 0x6c, 0x9f, 0xed, 0x1d, 0x1c, 0x2f, 0xe5, 0x3f, 0xac, 0x32,
-       0xb7, 0xff, 0x6a, 0xae, 0x6f, 0x17, 0x74, 0x79, 0x18, 0xc6, 0x32, 0x6d,
-       0xd0, 0x4b, 0x5c, 0x57, 0xea, 0xa9, 0x9b, 0x6e, 0x8a, 0x65, 0x1a, 0x64,
-       0xe0, 0x60, 0x1b, 0xea, 0xb3, 0x9c, 0xb8, 0x72, 0xd0, 0x47, 0x3a, 0x35,
-       0x28, 0x72, 0xf7, 0x44, 0xdf, 0xa2, 0x33, 0x3e, 0xf9, 0x73, 0xe0, 0xc7,
-       0x7e, 0xc9, 0x1f, 0x7c, 0x00, 0xf8, 0x7d, 0xd9, 0x29, 0x4e, 0xbd, 0xe2,
-       0x8c, 0x4f, 0xfd, 0x9d, 0x33, 0x31, 0xb5, 0x63, 0xc7, 0x50, 0xff, 0x8e,
-       0x1d, 0xa3, 0xfd, 0xae, 0xd5, 0x2d, 0x3b, 0x76, 0x4c, 0xf4, 0x67, 0x31,
-       0xff, 0x1e, 0x6f, 0x50, 0x7c, 0x6f, 0x2f, 0x95, 0x7c, 0xc2, 0xac, 0xfd,
-       0x4c, 0xd0, 0x8d, 0xf7, 0x6c, 0xdf, 0xab, 0xdf, 0x0f, 0x48, 0x4f, 0xb2,
-       0x55, 0x38, 0x7e, 0x87, 0xd5, 0x49, 0x6c, 0x07, 0x7a, 0xe9, 0xa5, 0x1d,
-       0xa8, 0x50, 0x2f, 0x05, 0x7c, 0xd0, 0x26, 0xde, 0x06, 0x1b, 0x82, 0xed,
-       0x94, 0x5d, 0xf7, 0x92, 0x6a, 0xf0, 0x63, 0xba, 0x5f, 0x75, 0x36, 0x13,
-       0x33, 0x6b, 0xde, 0x63, 0xed, 0xeb, 0x4d, 0x28, 0xe7, 0x33, 0x71, 0x49,
-       0x7c, 0xd1, 0xde, 0x69, 0xd0, 0xf6, 0x69, 0xbe, 0x44, 0x5a, 0x72, 0x65,
-       0xac, 0xd4, 0x8f, 0x36, 0xa0, 0x97, 0xb3, 0xf6, 0x3a, 0x81, 0xf1, 0x0e,
-       0xa2, 0xaf, 0x13, 0x47, 0xd1, 0x8e, 0xb2, 0x24, 0xdd, 0x2d, 0xea, 0x41,
-       0xd4, 0xe9, 0xf1, 0xb6, 0x08, 0xed, 0x9a, 0x47, 0x24, 0x5f, 0x26, 0xdf,
-       0xd3, 0x36, 0x88, 0x4b, 0xaa, 0x0d, 0xcf, 0xd5, 0xc3, 0xb0, 0x75, 0x1a,
-       0x22, 0x7b, 0x43, 0x6a, 0x76, 0xd1, 0xaf, 0x2a, 0xf1, 0x0f, 0xcb, 0xc8,
-       0xec, 0x76, 0xd4, 0x33, 0xf6, 0xbc, 0xf2, 0x61, 0x17, 0xcd, 0x66, 0x25,
-       0xb7, 0xeb, 0x5e, 0xdc, 0x3d, 0x3c, 0x17, 0x71, 0x7f, 0x0b, 0xee, 0xe3,
-       0xb8, 0x47, 0x70, 0x02, 0xe7, 0x41, 0xcc, 0xea, 0xb2, 0x51, 0x8c, 0xfd,
-       0xef, 0x25, 0x37, 0x09, 0x7a, 0x2d, 0x85, 0x9b, 0x72, 0x7e, 0xd6, 0x53,
-       0xa2, 0xb6, 0x28, 0x99, 0x40, 0x7d, 0xf8, 0x29, 0xfe, 0x11, 0x19, 0x3d,
-       0x8d, 0xdf, 0x0f, 0xd2, 0xee, 0x9e, 0x90, 0xd1, 0x59, 0x8e, 0x53, 0x02,
-       0x4c, 0x93, 0x92, 0x3f, 0xfd, 0x00, 0xae, 0x29, 0x5c, 0x0f, 0xe3, 0xe2,
-       0xdc, 0xd8, 0xff, 0xc2, 0x66, 0x25, 0x2d, 0xfa, 0x39, 0x4f, 0xfa, 0xae,
-       0xe2, 0x37, 0x69, 0xbb, 0x4a, 0x1b, 0x08, 0x74, 0x5d, 0x8d, 0xe8, 0x3d,
-       0xb0, 0xbf, 0x93, 0x9a, 0xdf, 0x0b, 0xad, 0xa0, 0xa5, 0x6a, 0x56, 0xcb,
-       0x22, 0xc0, 0x00, 0xb9, 0x03, 0x9b, 0xa4, 0x95, 0x73, 0xec, 0xb5, 0x65,
-       0xbd, 0xba, 0x2c, 0xa5, 0xcb, 0xfa, 0x6c, 0x19, 0xee, 0xd5, 0x06, 0x19,
-       0x69, 0x03, 0xc4, 0x94, 0xdb, 0x12, 0xe1, 0x93, 0xb2, 0x01, 0x74, 0x8d,
-       0xf5, 0x3d, 0x7f, 0x59, 0xb9, 0xb8, 0xa8, 0xed, 0xbd, 0x73, 0x55, 0xd2,
-       0x37, 0x69, 0x3e, 0x0c, 0xef, 0x0f, 0x9a, 0xd0, 0x3f, 0x65, 0x81, 0x48,
-       0xc3, 0x09, 0x57, 0xa6, 0x3d, 0xd2, 0xc0, 0xc7, 0x5a, 0x48, 0x03, 0x8d,
-       0x3e, 0x69, 0xbb, 0x9e, 0xef, 0xb8, 0x86, 0xec, 0xaf, 0x00, 0x1b, 0x92,
-       0xb6, 0x64, 0x17, 0xec, 0x73, 0x8e, 0x71, 0x8c, 0xcf, 0x9e, 0x02, 0xaf,
-       0xe5, 0x96, 0x78, 0x4d, 0x64, 0xa6, 0x44, 0xdc, 0x44, 0x36, 0x26, 0xd7,
-       0x99, 0xf8, 0x39, 0x87, 0x39, 0xf3, 0x7e, 0xde, 0xe2, 0xe9, 0xf3, 0x16,
-       0x4f, 0x4f, 0xda, 0xbb, 0xe7, 0xe4, 0xb5, 0xcd, 0x38, 0x8f, 0x67, 0xae,
-       0x0f, 0xe8, 0xaa, 0x4a, 0x9e, 0x9b, 0xc6, 0x1d, 0x75, 0xcb, 0xe7, 0x64,
-       0x54, 0xdb, 0x6f, 0x31, 0x79, 0x87, 0x96, 0x79, 0x5f, 0xc5, 0x5a, 0x96,
-       0x00, 0x73, 0x83, 0x14, 0x12, 0x31, 0xbd, 0xf6, 0xae, 0xff, 0x5b, 0xae,
-       0xa1, 0x55, 0xe2, 0x64, 0x99, 0xbf, 0x56, 0x07, 0x53, 0xe4, 0xa3, 0x12,
-       0x2e, 0xd2, 0xee, 0xa7, 0x35, 0x5c, 0xb7, 0x40, 0x0e, 0x16, 0x44, 0xb5,
-       0x35, 0xca, 0x95, 0xa0, 0x05, 0x95, 0x80, 0x46, 0x0b, 0x9f, 0x82, 0x3d,
-       0x95, 0x9f, 0xa5, 0x9d, 0xde, 0x41, 0xdf, 0x28, 0x9e, 0xef, 0xdd, 0x48,
-       0x3a, 0x52, 0x86, 0x6f, 0x1c, 0x95, 0xef, 0xd5, 0x74, 0xea, 0x28, 0x3f,
-       0xa1, 0x6d, 0x71, 0xd7, 0xdf, 0xea, 0x5a, 0x9f, 0xde, 0x55, 0xfe, 0x96,
-       0x95, 0x65, 0x29, 0xea, 0x67, 0xb4, 0x4b, 0xe5, 0x7b, 0xdb, 0xc8, 0x63,
-       0x1e, 0xfc, 0xe1, 0xac, 0xf2, 0xb5, 0xff, 0x55, 0x50, 0x7d, 0x9b, 0x56,
-       0xd4, 0xd7, 0x77, 0xc7, 0x3e, 0xbb, 0xf6, 0xee, 0xd9, 0x7b, 0xca, 0xde,
-       0x0b, 0x6e, 0x1f, 0xef, 0x8e, 0xb8, 0x19, 0xde, 0xb1, 0x86, 0x19, 0xf6,
-       0xa1, 0xf9, 0x2a, 0x34, 0xb6, 0x72, 0x97, 0x57, 0x14, 0xf2, 0xd5, 0x57,
-       0xe5, 0x96, 0x59, 0x23, 0x97, 0xf7, 0x96, 0xc2, 0x10, 0x3e, 0xa2, 0xb7,
-       0x00, 0xff, 0x38, 0x7b, 0xb0, 0x22, 0xb7, 0x54, 0x89, 0xb7, 0x4f, 0x02,
-       0x7f, 0x43, 0x2e, 0x79, 0xd3, 0x13, 0xca, 0xe3, 0xbb, 0x84, 0xf6, 0x6a,
-       0xb1, 0x44, 0x9c, 0x5f, 0x10, 0xae, 0x4d, 0xb1, 0xf4, 0xb4, 0x5e, 0x9b,
-       0x23, 0xa5, 0x05, 0xe0, 0xe7, 0xcb, 0xa0, 0xfb, 0x30, 0x5c, 0x08, 0x8a,
-       0xa0, 0x9c, 0x3f, 0xc6, 0x6f, 0xd8, 0x28, 0xa5, 0x67, 0xf1, 0x7e, 0xa3,
-       0x14, 0x27, 0xc9, 0x73, 0xae, 0xe5, 0xe1, 0xb3, 0xe0, 0xa7, 0x9f, 0x41,
-       0xbf, 0x28, 0xeb, 0xe3, 0xef, 0x1f, 0xe0, 0x1d, 0xee, 0xb3, 0x58, 0xc4,
-       0x36, 0xda, 0x40, 0x1c, 0x9b, 0x6b, 0xc7, 0x35, 0xa3, 0xaf, 0x5e, 0xef,
-       0x97, 0x73, 0xbd, 0xd2, 0xdd, 0x05, 0x59, 0x8a, 0x2b, 0xc8, 0xb9, 0x12,
-       0xeb, 0x93, 0xfe, 0xfb, 0xd6, 0x19, 0x1d, 0xb1, 0xa1, 0xd9, 0xdc, 0x57,
-       0xb6, 0xe5, 0x9a, 0xd7, 0xd3, 0x20, 0x7d, 0xa8, 0x74, 0x7f, 0x01, 0x72,
-       0xc7, 0xf5, 0x37, 0xca, 0xa0, 0x96, 0x9d, 0xa4, 0x09, 0xd2, 0xc0, 0xcd,
-       0xca, 0xd0, 0xe6, 0xfb, 0x95, 0xa1, 0xcd, 0xa7, 0x41, 0x8b, 0xb8, 0xca,
-       0x8b, 0x8e, 0xa1, 0xcd, 0x2f, 0xe3, 0x8e, 0xab, 0xfc, 0xa2, 0x13, 0xf1,
-       0xf1, 0x00, 0xfc, 0xca, 0xbd, 0x25, 0xd7, 0x19, 0xad, 0x82, 0x7e, 0xcb,
-       0x71, 0x94, 0xcf, 0x13, 0xe7, 0x98, 0x3f, 0xc7, 0xd9, 0x69, 0xfb, 0x3f,
-       0x27, 0x63, 0xe5, 0x50, 0xdb, 0x5b, 0xf9, 0xd9, 0x7b, 0x71, 0x5f, 0xaf,
-       0xe5, 0x8c, 0xf2, 0xb3, 0xca, 0xc8, 0xab, 0x77, 0xe0, 0xde, 0x99, 0x3c,
-       0x22, 0x9d, 0x5e, 0x4c, 0x9e, 0x45, 0x5f, 0xdf, 0x75, 0xc6, 0xaa, 0x2f,
-       0xe3, 0xfa, 0x3e, 0xae, 0x57, 0x71, 0xbd, 0x82, 0x7e, 0x5f, 0x40, 0xf9,
-       0x7a, 0x99, 0xf7, 0x9a, 0x51, 0x5f, 0xd4, 0x68, 0xf5, 0x79, 0x67, 0xe4,
-       0xf4, 0x4b, 0xb8, 0x5c, 0x35, 0x56, 0x7d, 0xce, 0xc9, 0xcf, 0x86, 0x9b,
-       0x16, 0x7c, 0xca, 0xb0, 0xaf, 0x3a, 0xa6, 0xef, 0x0c, 0xe6, 0x00, 0x9a,
-       0x2e, 0xcf, 0x63, 0xec, 0xa7, 0x35, 0xcf, 0x0c, 0x42, 0x1f, 0xe4, 0x61,
-       0xaf, 0x8c, 0x68, 0x98, 0xb6, 0x03, 0x3e, 0xf8, 0xd3, 0x7d, 0xb8, 0xcf,
-       0x36, 0xca, 0x62, 0x82, 0xf6, 0xe5, 0x93, 0xba, 0x7e, 0xbe, 0x7c, 0xbd,
-       0xc6, 0xed, 0xf4, 0x2a, 0xfe, 0xa1, 0x4f, 0x18, 0xc9, 0x03, 0x23, 0x8d,
-       0x67, 0x4a, 0x94, 0x05, 0xd0, 0x4d, 0xa5, 0x09, 0xdc, 0x1b, 0xb5, 0x4c,
-       0x28, 0x4a, 0x24, 0x0f, 0xd8, 0x8e, 0x32, 0xa1, 0x5e, 0xee, 0x50, 0xd6,
-       0x50, 0xf6, 0x50, 0x96, 0x98, 0xf5, 0x18, 0x7d, 0x90, 0x32, 0xfc, 0x3a,
-       0xe8, 0x4d, 0xda, 0x25, 0xbe, 0xf1, 0x4d, 0xa6, 0x72, 0xca, 0xc8, 0xd3,
-       0xfd, 0x7a, 0x2d, 0xc6, 0x4a, 0x2a, 0x01, 0xc8, 0x51, 0x86, 0xeb, 0xe4,
-       0x41, 0xdc, 0xf3, 0x6a, 0x0c, 0x57, 0xfe, 0xe4, 0xfb, 0xf0, 0x9b, 0x6b,
-       0x33, 0x86, 0x7a, 0xb8, 0xca, 0xc3, 0xb8, 0xe3, 0x2a, 0xdf, 0xa8, 0x8c,
-       0x1c, 0xe1, 0x9a, 0x26, 0xed, 0x9a, 0x3e, 0x09, 0x3c, 0x70, 0x7e, 0x4a,
-       0xc7, 0x38, 0x94, 0xbf, 0x07, 0x78, 0xaf, 0x5a, 0x9f, 0x7a, 0xa3, 0x18,
-       0x1e, 0xc4, 0xd5, 0x4d, 0x7e, 0x6e, 0x31, 0xeb, 0xa5, 0x69, 0x77, 0x5d,
-       0x83, 0xe1, 0xc5, 0x04, 0xca, 0x62, 0x28, 0x6b, 0x33, 0x3a, 0x73, 0x09,
-       0x8f, 0x59, 0x8b, 0x47, 0xfe, 0x56, 0xf6, 0x37, 0xe8, 0x09, 0xb6, 0x2e,
-       0xe4, 0x35, 0xc6, 0xc5, 0x5c, 0x4e, 0xee, 0x57, 0xa3, 0x65, 0xfa, 0xc9,
-       0x94, 0xe1, 0x8c, 0x65, 0x70, 0x7e, 0xec, 0x17, 0xe5, 0x1a, 0x07, 0x81,
-       0xd4, 0xe2, 0x04, 0x4f, 0x62, 0xcd, 0xce, 0xc9, 0xa1, 0xf2, 0x47, 0xb4,
-       0xdf, 0xde, 0x78, 0xc2, 0xac, 0x87, 0xa8, 0xa8, 0x1e, 0xfa, 0x4e, 0xd0,
-       0xe6, 0xf9, 0x75, 0xfd, 0xde, 0x3d, 0xc1, 0xdf, 0x49, 0x1d, 0x4f, 0xaa,
-       0xc9, 0x7b, 0x63, 0xef, 0x14, 0x97, 0xc9, 0x3a, 0xda, 0x1d, 0x58, 0xb3,
-       0x4a, 0x3d, 0xde, 0x19, 0x47, 0xa0, 0xcc, 0x23, 0x3f, 0x1d, 0x01, 0x4f,
-       0x60, 0xf2, 0x9a, 0xf7, 0xe9, 0x83, 0xac, 0xc5, 0x4f, 0x3e, 0x6c, 0x62,
-       0x57, 0x4e, 0xc1, 0xa6, 0xdb, 0xbb, 0xd4, 0x07, 0x64, 0x65, 0x22, 0x2e,
-       0xa7, 0x4b, 0x2d, 0x32, 0x5b, 0x52, 0x6d, 0x31, 0x2b, 0x3b, 0x63, 0x92,
-       0xd4, 0xfa, 0x97, 0x76, 0xdf, 0xc0, 0x54, 0xcc, 0xd2, 0xdd, 0x8d, 0xe8,
-       0xff, 0x93, 0xd0, 0xb1, 0x15, 0xe8, 0xd8, 0x8d, 0xd0, 0xc1, 0x2b, 0x65,
-       0xc4, 0xfe, 0x86, 0xd5, 0x32, 0x82, 0x6d, 0xd2, 0xf0, 0xd6, 0x8f, 0xa0,
-       0x5d, 0x44, 0x7f, 0x71, 0x4d, 0x6b, 0x79, 0x29, 0x38, 0x7b, 0xab, 0x13,
-       0xce, 0xbe, 0xea, 0x4a, 0x1d, 0xd4, 0xe3, 0xb9, 0x62, 0x60, 0x3d, 0x5d,
-       0xa2, 0xed, 0x9a, 0x0e, 0x72, 0xc0, 0xc9, 0x3e, 0xd0, 0xdd, 0x53, 0x93,
-       0xf0, 0xef, 0x29, 0x97, 0x01, 0xf3, 0x19, 0xc0, 0x3c, 0x33, 0xe9, 0x44,
-       0xb6, 0x81, 0x30, 0x40, 0x33, 0x33, 0xd5, 0x2b, 0x0b, 0x73, 0xa4, 0x43,
-       0xc8, 0x80, 0x49, 0xac, 0x67, 0xb0, 0x0e, 0x76, 0x00, 0xc7, 0x87, 0xdc,
-       0x9e, 0xda, 0xa6, 0xdf, 0x19, 0x7d, 0xde, 0x2e, 0x0b, 0x95, 0x3b, 0x2d,
-       0x6c, 0xc7, 0xea, 0x60, 0x5b, 0xb7, 0x04, 0xdb, 0x3e, 0xc0, 0xb6, 0x7f,
-       0x4d, 0xd8, 0xd6, 0xd2, 0xc5, 0x1d, 0xb0, 0x69, 0xc8, 0x1f, 0x11, 0x5e,
-       0xdb, 0x2c, 0x3d, 0x94, 0xac, 0x1d, 0x4c, 0x9b, 0xe8, 0x87, 0x80, 0x87,
-       0x34, 0x86, 0xdf, 0xb3, 0x8f, 0x52, 0x96, 0xa1, 0x9c, 0xcf, 0x0f, 0xa1,
-       0x0e, 0x9e, 0x67, 0x13, 0x56, 0x0e, 0x7e, 0xc2, 0xc2, 0x42, 0x3b, 0x21,
-       0x0b, 0x5b, 0x79, 0xd0, 0xc9, 0xcd, 0x12, 0x86, 0x53, 0x80, 0x17, 0xef,
-       0xaa, 0xf5, 0x7d, 0xf2, 0xce, 0x7e, 0xaf, 0xb2, 0xfd, 0xb0, 0xef, 0x68,
-       0x2e, 0xeb, 0xad, 0x9e, 0x8f, 0xe8, 0x2b, 0xb2, 0xbb, 0x27, 0x9c, 0xec,
-       0xaa, 0x79, 0xd5, 0xd3, 0x1c, 0xe5, 0xad, 0x2b, 0x43, 0xa0, 0x93, 0xa1,
-       0x65, 0xb4, 0xa6, 0xdd, 0x13, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x1b,
-       0xbe, 0x09, 0xe2, 0xd0, 0x87, 0x94, 0x37, 0xff, 0xc5, 0xf8, 0xec, 0xf2,
-       0xe5, 0x06, 0xc6, 0x69, 0xcd, 0x33, 0x69, 0x93, 0xbf, 0x29, 0x93, 0x6a,
-       0xb4, 0x68, 0x7c, 0x9a, 0x76, 0x8c, 0x55, 0x6f, 0xc7, 0xbb, 0x32, 0x6c,
-       0xd6, 0xfc, 0x18, 0xd7, 0x9c, 0x3e, 0x4a, 0xe7, 0x03, 0xc3, 0x96, 0xbf,
-       0xd2, 0x93, 0x05, 0xb9, 0xd5, 0xce, 0xfd, 0xd2, 0x1a, 0x6b, 0xb7, 0x71,
-       0x69, 0xed, 0x86, 0xab, 0x2b, 0xe7, 0x28, 0xd2, 0xf1, 0x80, 0xab, 0x7d,
-       0x5e, 0xfa, 0xf0, 0x8d, 0x3e, 0xe5, 0x27, 0x6d, 0x25, 0x94, 0xcf, 0xf4,
-       0x78, 0xad, 0xf0, 0x0d, 0xbe, 0xb8, 0xca, 0xee, 0x4a, 0x59, 0xb9, 0x49,
-       0xff, 0x38, 0x1a, 0xa3, 0x60, 0xe5, 0x64, 0x01, 0xfd, 0x4f, 0x38, 0x43,
-       0xd5, 0xb5, 0xe4, 0x65, 0x24, 0x27, 0x39, 0x9f, 0x7b, 0xe5, 0x8e, 0x07,
-       0xc9, 0xa3, 0x25, 0x6d, 0x5f, 0x5f, 0xb3, 0xe7, 0x30, 0xf0, 0x47, 0xf8,
-       0x17, 0x36, 0xc3, 0x64, 0x80, 0xce, 0xcd, 0xca, 0xa8, 0x5d, 0xb7, 0xd1,
-       0xa5, 0xf5, 0xe7, 0x35, 0x0c, 0xdd, 0xc8, 0x58, 0xae, 0xb2, 0x30, 0x6b,
-       0x3b, 0x16, 0x76, 0xdd, 0x4a, 0x5b, 0x96, 0x73, 0xa0, 0x3d, 0xdb, 0x68,
-       0x6c, 0xc1, 0x32, 0xed, 0x4f, 0xca, 0x2e, 0xda, 0x9f, 0x57, 0x37, 0x4a,
-       0x33, 0xe7, 0x93, 0xb5, 0x65, 0xb4, 0x53, 0x57, 0xce, 0x6f, 0xa5, 0x5f,
-       0x49, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x94, 0x22, 0x6c, 0xa1, 0x0c, 0x07,
-       0xd7, 0xe9, 0x35, 0x50, 0xb4, 0x5d, 0xf7, 0x34, 0x34, 0x9a, 0x38, 0xf6,
-       0x5e, 0xf4, 0xcf, 0x31, 0xc9, 0x7f, 0xbc, 0xd3, 0xce, 0x5f, 0x4b, 0x96,
-       0xd5, 0xeb, 0x9e, 0x2b, 0x97, 0xf0, 0x37, 0xb4, 0x6c, 0x8d, 0x22, 0xfc,
-       0x45, 0x74, 0x51, 0x8f, 0x43, 0xd2, 0x04, 0x69, 0x21, 0xa2, 0xc5, 0x9d,
-       0x56, 0xdf, 0x44, 0xb4, 0xb7, 0x15, 0xb4, 0x77, 0x1f, 0xf0, 0x44, 0x19,
-       0xce, 0x78, 0xde, 0x16, 0x3c, 0x1f, 0xc7, 0x73, 0xc4, 0x27, 0x91, 0x0c,
-       0xa7, 0x4d, 0xb4, 0x52, 0x8e, 0x53, 0x86, 0xc7, 0x61, 0xf7, 0x50, 0xd6,
-       0x6f, 0xb7, 0xfc, 0x94, 0xb3, 0xbc, 0x44, 0x5d, 0xf0, 0xfb, 0xe8, 0xe7,
-       0x86, 0x46, 0x63, 0xa7, 0x17, 0x1b, 0x29, 0x5f, 0x37, 0xcb, 0x91, 0xba,
-       0xb2, 0xcb, 0xc9, 0xef, 0xfa, 0x39, 0x6f, 0xff, 0x7f, 0x30, 0xe7, 0xe4,
-       0x8a, 0x39, 0x7b, 0x76, 0xce, 0x55, 0xbc, 0x6f, 0xc5, 0xfb, 0x16, 0xea,
-       0x82, 0x54, 0x4d, 0xde, 0x58, 0x5c, 0x68, 0x7d, 0x56, 0x2f, 0x27, 0x22,
-       0x19, 0xc1, 0x79, 0x1d, 0xb5, 0x73, 0xf8, 0x7c, 0xdd, 0xbc, 0x8e, 0xbe,
-       0x89, 0x79, 0xb5, 0x2f, 0x9b, 0xd7, 0xde, 0xcb, 0xce, 0x6b, 0x2d, 0x1e,
-       0x27, 0x2f, 0x47, 0xf3, 0x8b, 0xcb, 0x81, 0x12, 0xe7, 0x38, 0x84, 0x39,
-       0x12, 0x86, 0x68, 0x8e, 0x19, 0x3b, 0x47, 0x51, 0x1d, 0x7b, 0x7e, 0x0a,
-       0xbf, 0xeb, 0xe7, 0x47, 0xdd, 0xff, 0xf7, 0xa0, 0xe9, 0x26, 0xf8, 0xc4,
-       0x4d, 0x56, 0xfe, 0x3f, 0x29, 0xb7, 0x96, 0xb9, 0xd6, 0xe9, 0xac, 0xc8,
-       0x7e, 0x75, 0xa8, 0xfc, 0x72, 0x23, 0xf7, 0x11, 0xf6, 0x06, 0x56, 0x8f,
-       0x41, 0x5f, 0xec, 0x83, 0xcd, 0x37, 0x54, 0x52, 0x7d, 0x31, 0x09, 0xc3,
-       0xdb, 0x82, 0x66, 0x8c, 0xbd, 0x49, 0xfb, 0xaa, 0xab, 0x63, 0xf8, 0xcf,
-       0x36, 0x8a, 0x4f, 0x7b, 0x83, 0xfa, 0x1c, 0xfa, 0xee, 0x24, 0x6d, 0xb0,
-       0x1c, 0xec, 0xe4, 0x6c, 0x32, 0xa6, 0x6d, 0x31, 0xea, 0xc4, 0x74, 0x32,
-       0x2b, 0x15, 0xc9, 0x9f, 0xcc, 0x26, 0xe1, 0xd8, 0x62, 0x0c, 0xd8, 0x6a,
-       0xb0, 0x21, 0x6f, 0x85, 0xac, 0xb9, 0xb5, 0x7a, 0x50, 0xdd, 0x02, 0x7b,
-       0xe7, 0x96, 0xd3, 0xef, 0x53, 0xb7, 0xc1, 0xd6, 0xb9, 0xed, 0xf4, 0x8d,
-       0xea, 0x10, 0x6c, 0x9b, 0x43, 0xb0, 0x73, 0x0e, 0x55, 0x69, 0x7b, 0xde,
-       0x0c, 0xba, 0x6b, 0x87, 0x1e, 0xe2, 0x5c, 0xb8, 0x26, 0xb4, 0x71, 0x38,
-       0x3f, 0xe2, 0xfe, 0x0b, 0x5c, 0x83, 0x20, 0xa5, 0x76, 0x34, 0x71, 0x5d,
-       0x5a, 0x97, 0x95, 0xbd, 0x96, 0xac, 0x8a, 0xf4, 0xd3, 0x06, 0x1b, 0x4f,
-       0x32, 0x7e, 0xe5, 0xe5, 0x69, 0x8b, 0x34, 0xe2, 0x01, 0xcf, 0xc4, 0x1f,
-       0x69, 0xab, 0x7e, 0xfe, 0x57, 0x36, 0x89, 0x9f, 0xc3, 0xf8, 0xf7, 0x42,
-       0xbe, 0xd6, 0xd3, 0x14, 0xef, 0x5e, 0x1d, 0x7f, 0x50, 0x06, 0x47, 0xf4,
-       0xb0, 0xf3, 0x35, 0xe4, 0xef, 0x65, 0xe9, 0xe9, 0x9e, 0x58, 0x26, 0x0c,
-       0x47, 0xfb, 0x64, 0x13, 0xe3, 0x01, 0xb9, 0x6a, 0x2d, 0x26, 0xa0, 0xfc,
-       0xfa, 0x98, 0x00, 0xfd, 0xac, 0x4f, 0x03, 0xbf, 0xd3, 0xb8, 0x44, 0x46,
-       0x18, 0x77, 0xa8, 0x46, 0x76, 0xf9, 0x57, 0xac, 0x5d, 0x1e, 0xc1, 0x91,
-       0x02, 0x1c, 0x46, 0x3e, 0xaf, 0xd6, 0x73, 0xcb, 0xf5, 0x77, 0x61, 0xc9,
-       0xa6, 0x4d, 0xc9, 0x81, 0xb2, 0xb6, 0x13, 0x21, 0x83, 0x89, 0x9b, 0x7a,
-       0x19, 0x9c, 0xb4, 0x76, 0x14, 0xea, 0x68, 0xf9, 0xb9, 0x5a, 0x76, 0x52,
-       0xee, 0x31, 0x6e, 0xff, 0x40, 0x40, 0x5a, 0x7f, 0x97, 0x64, 0x97, 0xe2,
-       0xf6, 0x02, 0x7a, 0x93, 0x20, 0x96, 0xd1, 0x7b, 0x7a, 0xde, 0x8c, 0xec,
-       0x93, 0x81, 0x04, 0x63, 0xa0, 0x8c, 0xf3, 0xf9, 0x85, 0x19, 0xe9, 0x66,
-       0x8c, 0x03, 0x16, 0x7c, 0xa3, 0x8c, 0x78, 0xa1, 0xec, 0x0d, 0x1c, 0x1d,
-       0x53, 0x36, 0xba, 0xf6, 0x62, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0x17, 0x5e,
-       0x00, 0xf5, 0x2d, 0x68, 0xfb, 0x56, 0x69, 0xfd, 0x3b, 0xaf, 0xeb, 0xfc,
-       0x41, 0x53, 0x14, 0xdf, 0x5c, 0xf0, 0x62, 0xb6, 0x5e, 0x7d, 0xf9, 0xd7,
-       0x6c, 0xdc, 0xba, 0x1b, 0xb2, 0x3f, 0x2a, 0xfb, 0xde, 0x1a, 0x65, 0xb1,
-       0xf8, 0xea, 0xb2, 0xcd, 0x6b, 0x94, 0x99, 0x78, 0xe1, 0x50, 0x69, 0x27,
-       0xde, 0x4d, 0x68, 0xdf, 0x5d, 0xf4, 0x9e, 0x5b, 0xb7, 0x14, 0x96, 0xea,
-       0x6c, 0xb0, 0x7e, 0x19, 0x63, 0xc7, 0x26, 0x66, 0x9c, 0xd7, 0x31, 0xe3,
-       0x1e, 0x6f, 0x8f, 0xd2, 0x7b, 0x2c, 0xb7, 0x33, 0xfe, 0x78, 0x48, 0xe3,
-       0x85, 0x38, 0xf9, 0x02, 0x63, 0xc3, 0x05, 0xee, 0x0f, 0xa7, 0xd4, 0xe5,
-       0x68, 0xbb, 0x66, 0x9b, 0x98, 0x75, 0xa3, 0x5d, 0xdc, 0x22, 0x83, 0xb0,
-       0x15, 0x86, 0x4a, 0xad, 0xb2, 0x77, 0xea, 0xa3, 0xeb, 0xa8, 0xb7, 0xf6,
-       0x4d, 0x19, 0x7f, 0xf0, 0x10, 0xf8, 0x2a, 0x2b, 0x84, 0x31, 0x1d, 0x88,
-       0xd0, 0x26, 0x5e, 0x6d, 0x0b, 0xbf, 0x76, 0x7f, 0xf7, 0x5f, 0xa6, 0x3f,
-       0x07, 0xb6, 0xc3, 0x1b, 0xed, 0xaf, 0x59, 0x06, 0xa7, 0x22, 0x5c, 0xa9,
-       0x1f, 0xb1, 0x5d, 0xec, 0x32, 0xed, 0xb4, 0x5d, 0x22, 0x4f, 0x2d, 0xc9,
-       0xe2, 0x9d, 0xb0, 0x99, 0x24, 0xcc, 0xf5, 0x49, 0x7b, 0x4c, 0x74, 0x8c,
-       0x27, 0x30, 0xb2, 0xb9, 0x8b, 0x7b, 0x3e, 0xa0, 0x7f, 0x63, 0xab, 0x98,
-       0x78, 0x6a, 0x64, 0xa7, 0xac, 0x45, 0xbb, 0xd7, 0x5b, 0xda, 0xe5, 0xbe,
-       0xee, 0x3e, 0xca, 0x5c, 0xac, 0x89, 0xa1, 0xe3, 0xbd, 0x25, 0x49, 0x45,
-       0x74, 0xbc, 0x20, 0xd9, 0x65, 0x74, 0xbc, 0x20, 0x83, 0x9a, 0x8e, 0x1b,
-       0x97, 0xd1, 0x71, 0xbb, 0xa5, 0xe3, 0x8f, 0xc6, 0x0d, 0x5d, 0x28, 0xad,
-       0xa7, 0x48, 0xa7, 0x86, 0x8e, 0x1d, 0x4d, 0xc7, 0x0b, 0xb8, 0xbb, 0xfe,
-       0xc7, 0x6c, 0x9d, 0x98, 0x2d, 0xe3, 0xef, 0xa8, 0x8c, 0x72, 0x71, 0x2a,
-       0x6e, 0xf4, 0xd2, 0x20, 0xe8, 0x28, 0x2a, 0xff, 0x4d, 0x4b, 0x9f, 0xf5,
-       0x65, 0x26, 0x3e, 0x32, 0x54, 0x3a, 0xb2, 0x82, 0x3e, 0x07, 0x41, 0x9f,
-       0x51, 0x9d, 0xd7, 0xa2, 0xcf, 0x66, 0xbb, 0x9f, 0x91, 0xd4, 0x7b, 0xff,
-       0xd9, 0x84, 0xa1, 0xd5, 0x5b, 0xf4, 0xdc, 0x39, 0xef, 0x0b, 0x6f, 0x80,
-       0x56, 0xcd, 0xda, 0x5c, 0xac, 0xf9, 0xdb, 0x8c, 0x45, 0xa5, 0x4c, 0x6c,
-       0x9b, 0x71, 0xd2, 0xcb, 0xd9, 0x8e, 0x2f, 0xd5, 0xf9, 0x15, 0x1b, 0xa4,
-       0xc0, 0xbc, 0x87, 0xea, 0x46, 0xc6, 0xa2, 0x47, 0xdc, 0x4c, 0x9f, 0x64,
-       0x2b, 0xed, 0xa9, 0x62, 0x89, 0x7e, 0xd1, 0xab, 0x36, 0x37, 0x02, 0xcf,
-       0x95, 0x16, 0x79, 0xb4, 0x44, 0xda, 0x3a, 0x62, 0x70, 0xb1, 0x26, 0xad,
-       0x73, 0xad, 0xd9, 0x4f, 0xbd, 0x0e, 0xe8, 0x83, 0xee, 0xa1, 0xcd, 0xae,
-       0xe5, 0x3e, 0xde, 0xb5, 0xa7, 0x72, 0xa5, 0xa8, 0x5f, 0xee, 0x3f, 0x70,
-       0x4f, 0xb8, 0x3d, 0xd5, 0x51, 0xf1, 0x6d, 0x9c, 0x79, 0x23, 0x9e, 0xfb,
-       0xa4, 0xa3, 0xa2, 0xe4, 0x03, 0x53, 0x2d, 0x72, 0x7b, 0xc9, 0x95, 0x0f,
-       0xa1, 0xfd, 0x07, 0x4b, 0x1e, 0xfc, 0xfb, 0xff, 0x1d, 0xa7, 0x9d, 0x79,
-       0xa8, 0xc4, 0x7d, 0x50, 0x47, 0xdb, 0x2a, 0xcb, 0xf7, 0x86, 0x63, 0xd2,
-       0xd1, 0x55, 0x84, 0xe7, 0x23, 0xee, 0x7e, 0xc0, 0xd1, 0x94, 0xc9, 0xc8,
-       0x77, 0xfa, 0x36, 0xa1, 0x2c, 0xca, 0xf1, 0x18, 0x76, 0x4c, 0xfc, 0xb8,
-       0x5f, 0xde, 0x59, 0xcd, 0xc8, 0x0d, 0x55, 0xb3, 0x77, 0x5b, 0xdb, 0x9b,
-       0x4d, 0x7b, 0xf3, 0xd0, 0x67, 0x59, 0x2f, 0x0c, 0x2f, 0xfa, 0xa0, 0xa2,
-       0xe3, 0xae, 0xc4, 0xbb, 0xd2, 0xc9, 0x79, 0x31, 0xcf, 0x97, 0x2a, 0xff,
-       0x1c, 0x8e, 0x24, 0x5c, 0xf9, 0x8e, 0xcf, 0x39, 0xf6, 0xcb, 0xf5, 0x95,
-       0xfa, 0xb1, 0xb9, 0x3f, 0x1b, 0x5b, 0xc7, 0xfd, 0x90, 0x5c, 0xf5, 0x9f,
-       0xe3, 0x8c, 0xdb, 0xd3, 0x87, 0xe9, 0xf8, 0x31, 0xee, 0x87, 0xbb, 0xb8,
-       0x83, 0x0e, 0x13, 0xb0, 0x21, 0xae, 0x01, 0x8c, 0xd7, 0x30, 0x96, 0xc6,
-       0x18, 0x1a, 0x9f, 0xbf, 0x8c, 0x71, 0xd9, 0xf6, 0x93, 0xd6, 0xfe, 0x3e,
-       0xb2, 0xc4, 0x8b, 0x6b, 0xeb, 0xb1, 0x8d, 0x23, 0xf1, 0x8c, 0x38, 0xf1,
-       0x9f, 0x48, 0xca, 0x3a, 0xbf, 0x7e, 0x7c, 0xee, 0x47, 0xc3, 0xa2, 0xec,
-       0x13, 0x77, 0xdf, 0xee, 0x7e, 0x19, 0xc4, 0xfc, 0x86, 0x56, 0xcd, 0xef,
-       0x1e, 0x61, 0xbc, 0xf6, 0x52, 0x89, 0x73, 0xa8, 0xcd, 0x4b, 0xfd, 0xb6,
-       0x99, 0x57, 0xbc, 0x6b, 0xe5, 0x7c, 0x74, 0x7b, 0x75, 0x0a, 0xb0, 0x7c,
-       0x49, 0xe7, 0x42, 0x84, 0xe1, 0x5b, 0xbb, 0x2e, 0x85, 0xa9, 0x2b, 0xd2,
-       0xdd, 0xf3, 0xb5, 0x7d, 0xa4, 0x91, 0x58, 0x26, 0xab, 0xf5, 0x23, 0x9e,
-       0x53, 0xf9, 0xca, 0x7e, 0xac, 0xa3, 0xb8, 0xf9, 0x5e, 0x57, 0xf3, 0x5d,
-       0xde, 0xdf, 0x6f, 0xf7, 0xca, 0x22, 0x9f, 0x2c, 0x0c, 0x95, 0xbf, 0x52,
-       0x0e, 0x51, 0xff, 0x61, 0xee, 0xf2, 0x98, 0xdd, 0x3f, 0xe8, 0x66, 0x7c,
-       0x0c, 0xb4, 0x18, 0x07, 0xdd, 0xf9, 0xf8, 0xdd, 0x82, 0xfb, 0x1e, 0xd8,
-       0x3f, 0x01, 0xec, 0x23, 0x49, 0x28, 0x23, 0x6b, 0xc0, 0x1b, 0x5d, 0x05,
-       0xa5, 0xc8, 0xeb, 0x5e, 0x6a, 0xbc, 0x92, 0x48, 0x4d, 0x56, 0x9e, 0x60,
-       0x7b, 0xd4, 0x5d, 0x2b, 0x36, 0x68, 0xf2, 0x6c, 0xbe, 0x58, 0xe5, 0x18,
-       0xa4, 0xfb, 0x37, 0x32, 0x86, 0x6b, 0xfb, 0x66, 0x9f, 0x11, 0x5e, 0x5c,
-       0xba, 0xf8, 0xf8, 0xb7, 0xdf, 0xfa, 0x3a, 0x9c, 0xdf, 0x13, 0x16, 0xee,
-       0x95, 0xe3, 0x3e, 0xaf, 0xed, 0xa1, 0xc7, 0xab, 0xb4, 0x41, 0xb9, 0x8f,
-       0x94, 0x7e, 0x64, 0x5a, 0x08, 0x47, 0x18, 0x3e, 0x1b, 0x18, 0x5b, 0xe0,
-       0x8b, 0x55, 0xee, 0x99, 0x84, 0xe1, 0xdf, 0xd2, 0xce, 0x3e, 0x58, 0xc6,
-       0x78, 0x11, 0x0e, 0x76, 0x16, 0x5c, 0xc8, 0xd9, 0x89, 0x3e, 0xe2, 0x57,
-       0xe0, 0xf1, 0x76, 0x79, 0x07, 0x24, 0x9e, 0xfa, 0x78, 0xa5, 0x25, 0x75,
-       0x67, 0xc5, 0x03, 0x9e, 0x39, 0xef, 0x44, 0x6a, 0xcc, 0xce, 0x39, 0x5f,
-       0x21, 0x7e, 0x5f, 0x6b, 0xbf, 0xf3, 0xf9, 0x65, 0xfe, 0x17, 0x61, 0xaa,
-       0xc1, 0x42, 0xd8, 0x52, 0x16, 0x37, 0x61, 0xf8, 0xf7, 0x01, 0xc7, 0xdc,
-       0x0f, 0x1f, 0x46, 0x26, 0x30, 0x6e, 0x61, 0x8b, 0x22, 0x1e, 0xe2, 0xa9,
-       0x3b, 0x30, 0xf6, 0xc7, 0x31, 0xf6, 0xed, 0x15, 0x8e, 0x07, 0xd9, 0x83,
-       0xb9, 0x4f, 0x54, 0x23, 0x78, 0xd7, 0x1a, 0x3b, 0x5a, 0xf3, 0x6e, 0x6b,
-       0x33, 0x46, 0xcf, 0x1a, 0x91, 0x6d, 0x0a, 0xbe, 0x63, 0xae, 0xba, 0xb0,
-       0xd9, 0x95, 0x9f, 0x81, 0x1c, 0x0f, 0xe5, 0x51, 0xc8, 0xc7, 0x05, 0x4d,
-       0x37, 0xb9, 0xed, 0xfc, 0x3f, 0x26, 0x4f, 0xad, 0x63, 0xbc, 0x7a, 0xc0,
-       0xa7, 0x2d, 0xbc, 0x18, 0x2e, 0xf8, 0x94, 0xf7, 0x1b, 0x64, 0xda, 0x2b,
-       0x74, 0x43, 0xf7, 0xa0, 0x6c, 0x23, 0xfd, 0xf7, 0x54, 0x2e, 0x96, 0x4e,
-       0x8d, 0x0b, 0x73, 0xbe, 0x98, 0x13, 0xc1, 0xbc, 0x26, 0xca, 0x06, 0x17,
-       0x32, 0x94, 0x6b, 0x68, 0xc6, 0x1b, 0xaf, 0xd4, 0xea, 0x1e, 0x16, 0xee,
-       0x4d, 0xa6, 0x93, 0x87, 0xb4, 0xbd, 0x23, 0x32, 0x5a, 0x62, 0xdd, 0xdd,
-       0xb0, 0x76, 0xfc, 0xba, 0xfa, 0x3a, 0x57, 0x0d, 0x7c, 0x1e, 0xc5, 0xc5,
-       0xe2, 0xcc, 0x29, 0x79, 0x39, 0xd6, 0x27, 0x2f, 0xd3, 0x8e, 0x1d, 0x00,
-       0x6d, 0x7b, 0xbe, 0xce, 0x2b, 0xd1, 0xe5, 0xb9, 0x40, 0x16, 0x73, 0xfd,
-       0x3d, 0xb4, 0xdb, 0x0b, 0x4a, 0xf3, 0x84, 0x28, 0xb4, 0x8d, 0xe7, 0x2b,
-       0x32, 0x98, 0x2f, 0xd9, 0xd8, 0xd1, 0x30, 0xe7, 0xbc, 0xa1, 0x6e, 0xee,
-       0x1b, 0xc5, 0x05, 0x4c, 0x83, 0xb1, 0x94, 0xd3, 0xe0, 0x7f, 0xaa, 0xc5,
-       0xd8, 0x10, 0xd0, 0x23, 0xad, 0xf7, 0xb7, 0x71, 0x6f, 0x56, 0xc1, 0x27,
-       0x57, 0x6d, 0x1f, 0xbe, 0x56, 0x65, 0xfe, 0x32, 0x09, 0xbd, 0x6a, 0x65,
-       0x65, 0x7c, 0xb0, 0x63, 0x89, 0xbe, 0x39, 0xbe, 0xb4, 0xc5, 0xfc, 0xd4,
-       0xe0, 0x40, 0x45, 0x54, 0x2c, 0xe3, 0xc5, 0x07, 0x2a, 0xcb, 0x69, 0xfe,
-       0x8b, 0xd5, 0xcf, 0x5a, 0xdb, 0xb2, 0x3e, 0x46, 0x5b, 0xff, 0x8e, 0x7c,
-       0xb7, 0x6c, 0xff, 0x23, 0x05, 0xbe, 0xb2, 0xfb, 0xc6, 0x5c, 0x93, 0xec,
-       0x5b, 0x19, 0xd8, 0x9c, 0xd6, 0x3e, 0x1f, 0x73, 0x3b, 0xe2, 0x36, 0xbf,
-       0xce, 0xe0, 0x3a, 0x5b, 0x71, 0x64, 0x02, 0xf2, 0xe1, 0xb0, 0xfc, 0x53,
-       0x98, 0x4d, 0x98, 0xf7, 0x66, 0x7d, 0x59, 0x9f, 0x7b, 0x1b, 0xcd, 0x52,
-       0x3c, 0xed, 0x4a, 0xe1, 0x34, 0xf7, 0xd4, 0xce, 0xdd, 0x51, 0xcb, 0x0f,
-       0xa1, 0x1c, 0xe0, 0xbe, 0xb0, 0x23, 0x45, 0xf8, 0xc8, 0x83, 0xdc, 0xef,
-       0xef, 0xfd, 0x47, 0xe6, 0xea, 0xc4, 0xb9, 0x4e, 0xa6, 0x6d, 0x0b, 0xda,
-       0x36, 0xda, 0xb6, 0xc1, 0xc7, 0xdf, 0x5c, 0xdb, 0x8d, 0x68, 0x1b, 0x8f,
-       0xc6, 0x7d, 0x83, 0x6d, 0x35, 0x3e, 0xaf, 0x1d, 0x28, 0x95, 0x17, 0x5d,
-       0xdf, 0x4f, 0x8e, 0x49, 0xd6, 0x19, 0xed, 0xd3, 0xf3, 0xb9, 0x76, 0xa0,
-       0x02, 0x38, 0x12, 0x61, 0x58, 0x0c, 0x22, 0xbd, 0xce, 0x7f, 0x27, 0xa1,
-       0xde, 0x59, 0xc6, 0x7d, 0x50, 0xfa, 0x27, 0x8c, 0xba, 0x7a, 0xcc, 0xc1,
-       0x93, 0x22, 0xf7, 0x3b, 0x13, 0x9b, 0x70, 0x57, 0x1d, 0xc4, 0x49, 0xde,
-       0x67, 0xfc, 0x78, 0x93, 0x2d, 0x8f, 0xb1, 0x3c, 0xed, 0x42, 0x96, 0x98,
-       0xf2, 0x98, 0x2d, 0x07, 0x4c, 0x41, 0x31, 0x05, 0x6e, 0xb3, 0xe5, 0x7c,
-       0x56, 0xba, 0xdc, 0x3c, 0x1b, 0x1e, 0x1a, 0x11, 0xc6, 0x89, 0x72, 0xd7,
-       0x37, 0xc8, 0x4e, 0xac, 0x0f, 0x7d, 0x50, 0x47, 0x9a, 0x01, 0xc7, 0xc5,
-       0xe0, 0xc7, 0x61, 0xab, 0x87, 0xf2, 0x9d, 0xc0, 0xd0, 0xff, 0x8c, 0x74,
-       0x65, 0x95, 0xc3, 0x5c, 0x83, 0x50, 0x86, 0x82, 0x5d, 0xc9, 0xbd, 0xf8,
-       0x3d, 0xda, 0x9b, 0x92, 0x99, 0x7e, 0xd0, 0x63, 0x2f, 0x79, 0x63, 0x27,
-       0x6c, 0x28, 0xfc, 0xee, 0x6a, 0x91, 0x45, 0xaf, 0xe0, 0xad, 0x83, 0xff,
-       0x37, 0x88, 0x59, 0xcd, 0x96, 0x7c, 0xef, 0x36, 0x08, 0xb9, 0xac, 0xd7,
-       0x85, 0x7b, 0xfd, 0x7c, 0xbf, 0x8e, 0xf9, 0x9e, 0x6b, 0x96, 0x66, 0x96,
-       0xd7, 0xd7, 0x6d, 0x94, 0xfd, 0xde, 0x6e, 0x2f, 0xbe, 0xac, 0xee, 0x25,
-       0xd4, 0x65, 0x99, 0xef, 0x31, 0x17, 0x68, 0xa6, 0x42, 0x3a, 0x33, 0xb0,
-       0x76, 0x74, 0x85, 0xe1, 0xf5, 0x01, 0xc7, 0x0d, 0xc3, 0x1b, 0x82, 0x1e,
-       0xef, 0x19, 0x79, 0x2e, 0x34, 0x36, 0x5a, 0x44, 0x3b, 0xcf, 0x5a, 0x79,
-       0x1d, 0x86, 0x2f, 0x07, 0xdd, 0xf2, 0xb9, 0x6a, 0xfa, 0x1c, 0x7d, 0xf8,
-       0xf3, 0x78, 0x3e, 0x1f, 0x98, 0xfc, 0xa5, 0x3f, 0x43, 0xbb, 0x84, 0xea,
-       0x05, 0x0d, 0xfb, 0xf2, 0x59, 0xed, 0xf3, 0x13, 0x7f, 0x66, 0xcf, 0xa0,
-       0x06, 0x03, 0x26, 0xec, 0xe7, 0x36, 0x7b, 0xcc, 0x69, 0xd4, 0xf4, 0x5b,
-       0xff, 0x4e, 0xe1, 0x1d, 0xcb, 0xc2, 0xf0, 0x8a, 0xbe, 0x96, 0xf5, 0xd0,
-       0xd7, 0x93, 0xdc, 0x0b, 0x7c, 0x9f, 0xe6, 0x3f, 0x91, 0x03, 0xdc, 0xf7,
-       0x02, 0x0e, 0x95, 0xf2, 0x8f, 0x75, 0xa8, 0x74, 0x41, 0xe4, 0x2d, 0x58,
-       0x7f, 0xae, 0x31, 0x18, 0xa4, 0x15, 0xb0, 0xef, 0xfa, 0xa5, 0x66, 0x13,
-       0x9b, 0xa2, 0x6f, 0x9e, 0xdd, 0x0c, 0xdf, 0x59, 0xdb, 0x33, 0xdc, 0x57,
-       0x1f, 0x6b, 0x0d, 0xc3, 0xf7, 0x06, 0xd1, 0x9a, 0xd9, 0xd8, 0x37, 0x74,
-       0x7c, 0xbe, 0x57, 0xd6, 0x1b, 0xbb, 0x90, 0xb9, 0x8d, 0x29, 0xbd, 0x4f,
-       0xa0, 0xda, 0xa0, 0x43, 0x76, 0xfd, 0x00, 0x38, 0xe5, 0x18, 0xcc, 0x73,
-       0x8c, 0x60, 0xaa, 0xb5, 0xcf, 0xf7, 0xae, 0xb3, 0x36, 0xac, 0x0b, 0x5c,
-       0xfa, 0x5e, 0x87, 0xfa, 0x5e, 0x68, 0x74, 0x6b, 0x44, 0xc3, 0xff, 0x10,
-       0x3e, 0x98, 0x30, 0xcf, 0xb9, 0x5d, 0xec, 0x63, 0xa7, 0x8c, 0xef, 0xc2,
-       0xb3, 0x7b, 0x1d, 0xee, 0x03, 0x57, 0xc6, 0xe4, 0xaa, 0xe4, 0x80, 0xda,
-       0xe5, 0x3d, 0x28, 0x3d, 0x56, 0xc6, 0x7d, 0x09, 0xfa, 0xbe, 0x00, 0xff,
-       0xbe, 0x49, 0x1e, 0x04, 0x4d, 0xab, 0xbe, 0x74, 0x6a, 0x5e, 0xa5, 0xbb,
-       0xa7, 0x55, 0x3a, 0x18, 0x51, 0x13, 0x9c, 0x57, 0x3f, 0x71, 0x31, 0x4d,
-       0xfc, 0x96, 0x81, 0xff, 0x32, 0x70, 0x7c, 0xd9, 0x3d, 0xe3, 0xc0, 0xea,
-       0x16, 0xa3, 0xdf, 0x0a, 0x9a, 0x36, 0x8d, 0x9d, 0xff, 0xa7, 0x41, 0xb4,
-       0x86, 0x3d, 0x5e, 0x03, 0x73, 0x71, 0xd6, 0x5c, 0xa3, 0x3c, 0xd7, 0x08,
-       0x8a, 0xa1, 0x00, 0xba, 0x4f, 0xa7, 0xc6, 0xd4, 0x62, 0xb8, 0x79, 0x4f,
-       0x67, 0xf7, 0x63, 0xba, 0x9f, 0x74, 0x90, 0x55, 0x4f, 0x02, 0x9e, 0x9d,
-       0xd2, 0xb4, 0x87, 0x78, 0x26, 0xac, 0x71, 0xc6, 0xa7, 0xbc, 0x3b, 0x50,
-       0x77, 0x44, 0xe9, 0x3d, 0x6d, 0x5b, 0x87, 0x30, 0xbf, 0x1b, 0xf8, 0xa5,
-       0x1e, 0x62, 0xcc, 0xed, 0xb5, 0x74, 0x21, 0x64, 0xd2, 0x49, 0xca, 0xc0,
-       0x98, 0x89, 0x25, 0x57, 0xef, 0xe4, 0xfa, 0xd3, 0x13, 0x88, 0xbb, 0x90,
-       0x51, 0x13, 0xe0, 0xe2, 0xa3, 0x27, 0xc5, 0x6d, 0xf0, 0xbb, 0xd7, 0x1b,
-       0x3f, 0x8c, 0x3e, 0x19, 0xc7, 0x6e, 0x90, 0xe2, 0xaa, 0xf8, 0xcd, 0x24,
-       0xe0, 0x6f, 0x96, 0xf1, 0x93, 0x5c, 0x0b, 0x17, 0x32, 0x87, 0x63, 0x8b,
-       0x9b, 0xeb, 0x0d, 0xc3, 0x51, 0x96, 0x9f, 0x26, 0xff, 0x4a, 0x9a, 0xef,
-       0x0a, 0xa7, 0xe7, 0x37, 0xab, 0x65, 0xb2, 0xb6, 0xc5, 0xc2, 0xa1, 0xf1,
-       0x24, 0x93, 0x5a, 0x8e, 0x50, 0xdf, 0xcc, 0xd4, 0xc1, 0x13, 0x7c, 0x7c,
-       0xc2, 0x6f, 0x7c, 0x13, 0xf0, 0xfc, 0x0f, 0xc0, 0xd3, 0x62, 0xe1, 0x69,
-       0x5c, 0x01, 0x4f, 0x4b, 0x04, 0x0f, 0xe4, 0x1c, 0xe5, 0x6a, 0xfc, 0xda,
-       0x6c, 0x45, 0x9c, 0xa2, 0x2f, 0xed, 0x4a, 0xfb, 0x43, 0xd4, 0x37, 0x8d,
-       0xde, 0x68, 0x9f, 0x27, 0xa3, 0x5a, 0xd7, 0xb8, 0xd7, 0x76, 0x56, 0xe6,
-       0x61, 0xbd, 0x8a, 0x93, 0xf3, 0x09, 0xfb, 0x5a, 0x76, 0xd5, 0x3d, 0x90,
-       0xff, 0x0b, 0x69, 0xd7, 0xda, 0x12, 0x93, 0x01, 0xfd, 0xa0, 0x84, 0xce,
-       0x15, 0xa8, 0xc1, 0xf4, 0x12, 0x60, 0x82, 0x3c, 0x3e, 0xd9, 0xe3, 0x0d,
-       0xcb, 0x56, 0xed, 0xeb, 0x59, 0x5c, 0x63, 0x6e, 0xf1, 0xba, 0xb9, 0x41,
-       0xff, 0xa9, 0x68, 0x6e, 0x90, 0x89, 0xa8, 0x37, 0x29, 0x7f, 0x64, 0x71,
-       0xb1, 0x11, 0x73, 0x8a, 0xd7, 0xcd, 0xa7, 0x33, 0x79, 0x3b, 0xcb, 0xcc,
-       0x7c, 0xba, 0x8a, 0x7e, 0xdc, 0xe2, 0x77, 0x2d, 0x9f, 0xc4, 0xd8, 0x3d,
-       0xd3, 0x12, 0xca, 0x44, 0x80, 0x35, 0xea, 0xa6, 0x7f, 0x12, 0xb7, 0xb9,
-       0xd7, 0x0a, 0xcf, 0x1b, 0x2c, 0x7f, 0x79, 0x52, 0xd4, 0xfe, 0xe0, 0xdf,
-       0x59, 0x3e, 0x75, 0x6d, 0x9e, 0x1c, 0x7f, 0x1f, 0x5c, 0x6f, 0xf3, 0x05,
-       0x0a, 0x59, 0x79, 0x65, 0x3d, 0xed, 0x92, 0x06, 0xff, 0x57, 0x56, 0x94,
-       0xc5, 0x51, 0x76, 0x6a, 0xbd, 0x95, 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1f,
-       0xf3, 0x3e, 0xf8, 0x8e, 0x32, 0xb8, 0x1e, 0x27, 0x3d, 0x60, 0x45, 0xf2,
-       0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, 0x51, 0x6d, 0x8f, 0xe2, 0xf2, 0xf8,
-       0xbd, 0x96, 0xed, 0x4f, 0x7c, 0x13, 0xd7, 0xf2, 0x8d, 0x09, 0xf0, 0xfd,
-       0xe1, 0xc0, 0x71, 0x67, 0x98, 0x57, 0xa0, 0x69, 0xb8, 0xbe, 0xef, 0x1b,
-       0x18, 0x26, 0xb4, 0xb4, 0x4c, 0x7a, 0x21, 0x4f, 0x3b, 0xd2, 0x44, 0x5d,
-       0x7c, 0xd2, 0xd3, 0x39, 0xee, 0x39, 0xad, 0x97, 0xeb, 0xd7, 0xb1, 0x09,
-       0xba, 0x26, 0x61, 0x78, 0xd4, 0x33, 0xfb, 0xe7, 0xb5, 0xfe, 0x46, 0xd0,
-       0x1f, 0xed, 0x34, 0xf8, 0xfd, 0x3e, 0xa3, 0x43, 0x94, 0x5f, 0x8e, 0xab,
-       0xae, 0xd6, 0x7e, 0x6b, 0x5c, 0xe7, 0x37, 0x2d, 0xd5, 0x1d, 0xb3, 0x63,
-       0x93, 0x6e, 0xcd, 0x7e, 0x42, 0x6d, 0x7c, 0x71, 0xd4, 0x2e, 0x01, 0x95,
-       0x35, 0xca, 0x44, 0x1f, 0x69, 0x94, 0x73, 0xd7, 0x36, 0xd4, 0xb5, 0xb4,
-       0x23, 0x0c, 0x7d, 0xd2, 0x76, 0x72, 0xaf, 0xcd, 0x97, 0x1a, 0x8d, 0xcf,
-       0x92, 0x90, 0x2d, 0x0d, 0x3a, 0x2f, 0x01, 0x65, 0x95, 0x48, 0x97, 0xb9,
-       0x32, 0xd3, 0xfb, 0x7f, 0xc2, 0xec, 0x41, 0xd6, 0x5d, 0x33, 0x0f, 0x20,
-       0x39, 0x2d, 0x1a, 0x4f, 0x5f, 0xab, 0xe1, 0xc9, 0xce, 0x2d, 0xb1, 0x72,
-       0x6e, 0x70, 0x6a, 0xfd, 0x7b, 0x20, 0x3b, 0xb9, 0x4e, 0x26, 0xe7, 0xfc,
-       0x9c, 0x38, 0x6e, 0xae, 0x7b, 0xad, 0xb9, 0x4d, 0x46, 0x78, 0xe5, 0xdc,
-       0x40, 0xab, 0xd1, 0xbc, 0x48, 0xdb, 0x09, 0xbd, 0xef, 0xa4, 0x14, 0x61,
-       0xd9, 0xb8, 0x02, 0xb7, 0x11, 0xdd, 0x19, 0x9a, 0xfb, 0xa2, 0xa6, 0xb9,
-       0x16, 0x4b, 0x73, 0xa8, 0xeb, 0x71, 0x1f, 0xfd, 0xbe, 0x96, 0x1a, 0xcd,
-       0x6d, 0xb0, 0x34, 0xa7, 0x5a, 0xcc, 0x1e, 0x7b, 0xb9, 0xc5, 0xec, 0x71,
-       0x25, 0x57, 0x3c, 0xbf, 0x93, 0xcf, 0xf0, 0xc5, 0xa2, 0xe7, 0x7a, 0x58,
-       0xcf, 0x03, 0xd6, 0x7a, 0x59, 0xd3, 0x64, 0xe3, 0x78, 0xdc, 0x8f, 0xa7,
-       0xdf, 0xe7, 0xca, 0xa3, 0xb0, 0x83, 0x8a, 0x95, 0x1f, 0x84, 0xf3, 0xf0,
-       0xfd, 0x26, 0x96, 0x74, 0xef, 0x4c, 0x0b, 0xf9, 0x6d, 0x1a, 0xbf, 0x8e,
-       0xd4, 0xf9, 0x3c, 0x98, 0x2f, 0xca, 0xfe, 0x19, 0xeb, 0x01, 0xb9, 0xbc,
-       0x54, 0x97, 0x31, 0x10, 0xe3, 0xe3, 0x9c, 0xab, 0xb6, 0xdb, 0xfd, 0x49,
-       0xca, 0xf9, 0xbb, 0xe1, 0x13, 0xdd, 0x03, 0x3d, 0x49, 0xfa, 0xee, 0xd8,
-       0x60, 0xf2, 0x89, 0x13, 0xd0, 0x63, 0x3f, 0x6f, 0x73, 0xab, 0x6e, 0xbf,
-       0x7d, 0xed, 0x5c, 0x62, 0xd0, 0xbe, 0x43, 0x9a, 0x79, 0xdb, 0x06, 0x13,
-       0x83, 0xde, 0xba, 0x81, 0x7c, 0xa6, 0x76, 0xed, 0xda, 0xa8, 0xf9, 0xc2,
-       0x89, 0x9e, 0xab, 0x2b, 0x9e, 0xa3, 0x76, 0x7f, 0xb3, 0x71, 0x79, 0xbb,
-       0xa8, 0xfc, 0xce, 0x4d, 0xcb, 0xcb, 0xff, 0xa3, 0xb7, 0xbc, 0x7d, 0xe3,
-       0xe6, 0xe5, 0xcf, 0x7b, 0x57, 0x3c, 0x7f, 0x64, 0xc5, 0xf3, 0xef, 0xad,
-       0x78, 0xde, 0xd1, 0xba, 0xfc, 0xf9, 0x43, 0x2b, 0x9e, 0x4f, 0xb5, 0xae,
-       0x0d, 0xef, 0x42, 0xeb, 0x72, 0xb8, 0xee, 0xd6, 0xfb, 0x07, 0xd3, 0x55,
-       0x57, 0xf6, 0x96, 0xf0, 0xde, 0x79, 0xdf, 0x16, 0xa3, 0xd7, 0xea, 0xdf,
-       0x33, 0x5e, 0xb7, 0x7b, 0xcb, 0xf2, 0xfe, 0x6a, 0xed, 0xf6, 0xd5, 0xda,
-       0x05, 0xb5, 0x76, 0x46, 0xb6, 0xcd, 0x54, 0xf9, 0x8e, 0xe5, 0x51, 0xbf,
-       0xa6, 0xed, 0x44, 0xd9, 0xd7, 0x39, 0xb7, 0xc3, 0x3a, 0xe7, 0x36, 0x05,
-       0x3e, 0xbc, 0x5b, 0xc7, 0xa8, 0x36, 0xc3, 0x50, 0x1e, 0xaf, 0x6e, 0xd4,
-       0x71, 0x2a, 0xd1, 0x79, 0xb7, 0xc3, 0xb0, 0x6d, 0x99, 0x6b, 0x1b, 0xca,
-       0xfe, 0xc0, 0xdc, 0x4d, 0xee, 0xed, 0xb1, 0x70, 0xc0, 0x0b, 0xc3, 0x71,
-       0xff, 0x76, 0x9b, 0x7f, 0x86, 0x7b, 0xd5, 0xb4, 0xa1, 0x0e, 0x7e, 0x0c,
-       0x3a, 0xb8, 0xa6, 0x7b, 0xef, 0xc6, 0x58, 0xf3, 0xa0, 0x99, 0x3e, 0xf9,
-       0x9d, 0x6a, 0xfa, 0xf3, 0xa2, 0xcf, 0x16, 0xf5, 0xc2, 0x86, 0x9b, 0xbf,
-       0xf3, 0xbd, 0x7e, 0x00, 0x5b, 0x2f, 0x94, 0x87, 0x83, 0x7e, 0xd0, 0x50,
-       0x37, 0xec, 0x3d, 0x5f, 0xfb, 0xa5, 0x8f, 0x6b, 0xda, 0x22, 0x8d, 0x31,
-       0xdf, 0x86, 0x76, 0x81, 0x13, 0xcf, 0xf5, 0xfe, 0xb1, 0x89, 0xd3, 0x04,
-       0x9d, 0xde, 0x97, 0xc0, 0xb7, 0x43, 0xfe, 0x0e, 0xf8, 0x28, 0xa4, 0x21,
-       0xc6, 0xd3, 0xb6, 0xdb, 0x7c, 0xc7, 0x36, 0x99, 0x76, 0x19, 0x77, 0x4c,
-       0xf7, 0x8f, 0x08, 0xe7, 0x9d, 0x4e, 0xa6, 0x94, 0xb6, 0xab, 0xc2, 0x03,
-       0x01, 0x73, 0x79, 0xb9, 0x67, 0x43, 0x7e, 0x1e, 0xbe, 0x6b, 0xc2, 0x2f,
-       0x78, 0x31, 0x9b, 0xff, 0x9b, 0x2b, 0x19, 0xda, 0x1c, 0x23, 0x6d, 0xc2,
-       0x9f, 0x5a, 0xe8, 0xfd, 0xbb, 0x90, 0xf6, 0x7d, 0x4a, 0x91, 0xf6, 0xbf,
-       0x17, 0xce, 0xba, 0xec, 0x8b, 0x70, 0x0f, 0xdf, 0x95, 0xd3, 0xb8, 0xba,
-       0x5b, 0x0e, 0x97, 0x69, 0x0b, 0xc7, 0x75, 0x7e, 0xc8, 0x68, 0x40, 0x3b,
-       0x2d, 0x0e, 0x3c, 0x8e, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x6f, 0x44, 0x9d,
-       0x98, 0x8c, 0x0c, 0xb7, 0x80, 0xf7, 0xc8, 0x9f, 0xbc, 0xbb, 0xa8, 0xef,
-       0xc9, 0x5c, 0x69, 0x44, 0xe7, 0xef, 0x3d, 0x8e, 0xb6, 0x4f, 0xe0, 0x9a,
-       0x29, 0x7d, 0x18, 0x6d, 0xde, 0xaf, 0xeb, 0xcf, 0x4c, 0x32, 0x17, 0x5a,
-       0x20, 0x97, 0x3e, 0x21, 0xc5, 0xd9, 0x0e, 0x19, 0x49, 0xcc, 0x4f, 0xbb,
-       0x4b, 0x71, 0x99, 0x47, 0x37, 0x70, 0xcf, 0xa4, 0x78, 0x35, 0xf7, 0x97,
-       0xc5, 0x1d, 0xde, 0xad, 0xba, 0x5b, 0xb5, 0xcf, 0xd5, 0x2f, 0x43, 0xd5,
-       0x8c, 0xdc, 0x54, 0x7d, 0x62, 0x8b, 0x89, 0x45, 0x2d, 0x8b, 0x6f, 0x1d,
-       0xd3, 0x52, 0xe5, 0x84, 0xcb, 0xf3, 0x59, 0x32, 0x73, 0x56, 0x24, 0x76,
-       0x22, 0x8a, 0x4d, 0xb2, 0xcc, 0x93, 0x8e, 0xab, 0x01, 0xd7, 0x59, 0xc8,
-       0xd6, 0x44, 0x5c, 0x3e, 0xbb, 0x2b, 0x1a, 0xab, 0x10, 0x4e, 0xed, 0x2a,
-       0xc8, 0x9d, 0xb8, 0xf2, 0x57, 0xa7, 0x27, 0x73, 0x8a, 0xe3, 0xfe, 0x75,
-       0x48, 0x59, 0xa6, 0x32, 0xbe, 0x14, 0x5a, 0xa3, 0xb1, 0xe1, 0xdf, 0xec,
-       0x89, 0xc6, 0xa7, 0xcd, 0x6d, 0xce, 0x56, 0x14, 0xb9, 0x8f, 0x03, 0xfa,
-       0x8b, 0x65, 0x3e, 0xb7, 0x81, 0xbe, 0xc3, 0x80, 0xb0, 0x1d, 0x64, 0xba,
-       0x62, 0xdf, 0x84, 0x93, 0xf0, 0xd7, 0xc3, 0xb9, 0x90, 0x4a, 0x00, 0x47,
-       0x85, 0xd7, 0x85, 0xb7, 0xc7, 0xf3, 0xd5, 0x5a, 0xf0, 0xde, 0x6c, 0x63,
-       0x89, 0x8c, 0x0f, 0xae, 0x03, 0xde, 0x5a, 0x50, 0x9e, 0x97, 0x89, 0x93,
-       0xb7, 0x6e, 0xe1, 0xde, 0x78, 0x83, 0xef, 0xd8, 0x1c, 0x56, 0x9e, 0x39,
-       0x9a, 0x40, 0x1d, 0xbe, 0x1f, 0x41, 0x9b, 0x74, 0x21, 0x17, 0xdb, 0x02,
-       0x9f, 0x88, 0xe3, 0x86, 0xb1, 0x8e, 0x3d, 0xcd, 0x3a, 0x27, 0x55, 0xce,
-       0x52, 0x9f, 0x47, 0x6d, 0x27, 0x74, 0xce, 0x07, 0xfc, 0xf6, 0xc2, 0x60,
-       0x8c, 0xf2, 0xab, 0x5b, 0x06, 0xa8, 0x4f, 0xce, 0x8e, 0x68, 0xda, 0xef,
-       0xdc, 0xc5, 0xf3, 0x57, 0x3d, 0xc6, 0x46, 0x4f, 0x10, 0xc6, 0x9b, 0x51,
-       0x0e, 0xfb, 0xfd, 0x35, 0x61, 0x28, 0xbc, 0x49, 0x18, 0x0a, 0x6f, 0x12,
-       0x06, 0xe2, 0x02, 0x70, 0x54, 0xaf, 0xd8, 0x18, 0xc5, 0xbe, 0xb7, 0x62,
-       0x1e, 0x47, 0xca, 0x05, 0x39, 0x5a, 0x76, 0x74, 0xdc, 0x71, 0x5e, 0x51,
-       0x26, 0x78, 0xe0, 0x49, 0xf0, 0x5e, 0x19, 0xbc, 0x59, 0x06, 0x2f, 0x96,
-       0xc1, 0x97, 0xb0, 0xff, 0xcf, 0x43, 0x3e, 0x3c, 0x81, 0xb5, 0x79, 0x7c,
-       0x19, 0x2f, 0x67, 0x35, 0x2f, 0x17, 0xcb, 0xf4, 0xd5, 0x7a, 0x2f, 0xc3,
-       0xaf, 0xae, 0x0c, 0x94, 0xd2, 0x50, 0x25, 0x8e, 0x9b, 0xef, 0xfd, 0x28,
-       0xf9, 0x55, 0x1e, 0x0c, 0x0e, 0xa2, 0xcd, 0x24, 0x68, 0x3c, 0x4d, 0x3b,
-       0x90, 0xf6, 0x4f, 0x01, 0xbc, 0x79, 0x8c, 0xbe, 0x9a, 0xba, 0x7a, 0xb3,
-       0x50, 0xbf, 0xb8, 0x7b, 0x98, 0xcb, 0xc8, 0xb9, 0xa6, 0x56, 0xe0, 0xc9,
-       0xf0, 0xef, 0x98, 0x4f, 0x3d, 0x43, 0xbe, 0x7d, 0x96, 0x7c, 0x5b, 0xc7,
-       0xab, 0x3f, 0xc5, 0xf9, 0x85, 0xde, 0xae, 0xb5, 0xda, 0xd6, 0xea, 0x6f,
-       0x5e, 0xaa, 0xaf, 0xc7, 0x9f, 0x24, 0x3f, 0xaa, 0xcc, 0x24, 0x71, 0x9f,
-       0xca, 0xc5, 0x76, 0x58, 0xdc, 0xc3, 0x76, 0xdb, 0x73, 0x05, 0x70, 0xdf,
-       0x2e, 0x85, 0xb9, 0x50, 0xfc, 0x3d, 0x51, 0x9f, 0xb5, 0x7e, 0x3c, 0xdb,
-       0xcf, 0x68, 0xc9, 0x91, 0xc1, 0x5d, 0xdc, 0xd7, 0x70, 0xa0, 0xe7, 0xa3,
-       0xf5, 0x80, 0xbd, 0xaf, 0xd7, 0x9c, 0x32, 0x96, 0xb2, 0xb5, 0xc5, 0xc6,
-       0x9f, 0xd8, 0xdf, 0xe4, 0x8a, 0x75, 0x7a, 0x31, 0xe4, 0xb9, 0xb6, 0x09,
-       0xff, 0x60, 0x1d, 0xad, 0x3c, 0x60, 0x69, 0x45, 0xad, 0x98, 0xc7, 0x5d,
-       0x96, 0x56, 0x22, 0x78, 0x13, 0x11, 0xad, 0x34, 0x45, 0xb4, 0x52, 0x98,
-       0x8e, 0x68, 0x85, 0x6d, 0xef, 0x8a, 0x68, 0x25, 0x55, 0x4f, 0x2b, 0x85,
-       0x69, 0x07, 0xd7, 0x4a, 0x38, 0x48, 0x2f, 0xec, 0x87, 0xf4, 0x02, 0x58,
-       0xaa, 0x9f, 0x59, 0xa2, 0x97, 0x04, 0xfa, 0x39, 0x5a, 0x36, 0x39, 0x22,
-       0xf0, 0xbb, 0xac, 0x0e, 0xf1, 0xb0, 0xe6, 0xc6, 0x47, 0x5c, 0x9b, 0x46,
-       0x02, 0x4b, 0x23, 0xb5, 0x7c, 0xfa, 0x15, 0xb4, 0x01, 0xdc, 0x33, 0x37,
-       0x76, 0xb7, 0xa6, 0x8d, 0xfb, 0x83, 0x12, 0xea, 0x0e, 0x83, 0x36, 0x22,
-       0x1c, 0xbc, 0xc7, 0xe2, 0x60, 0xe5, 0x5a, 0xde, 0x66, 0x71, 0x30, 0x6c,
-       0x71, 0xa0, 0xf9, 0xa5, 0xc0, 0x35, 0x53, 0x1a, 0x07, 0x4d, 0x1a, 0x07,
-       0xa2, 0xa2, 0xb6, 0xb7, 0xad, 0x81, 0x03, 0xd6, 0x19, 0xd6, 0xf3, 0x8f,
-       0x61, 0xfe, 0xb7, 0x63, 0xfe, 0x4a, 0xcf, 0x9f, 0xeb, 0x60, 0x72, 0xb9,
-       0x8b, 0xd5, 0xbf, 0x5e, 0x9a, 0x7f, 0x2b, 0xfa, 0x38, 0x52, 0x8e, 0xe9,
-       0xf9, 0xc3, 0xb6, 0xef, 0x8f, 0xe6, 0xff, 0x78, 0xd5, 0xe4, 0x53, 0x3f,
-       0xbe, 0x4a, 0xcf, 0x95, 0x2c, 0x6f, 0xf8, 0xda, 0x2f, 0x66, 0x4c, 0xfb,
-       0x3c, 0x74, 0xdb, 0x54, 0x90, 0xb2, 0xe7, 0xae, 0x8c, 0xbd, 0xf4, 0x95,
-       0x80, 0xbc, 0xf3, 0x21, 0x9d, 0xd7, 0x72, 0x8e, 0x76, 0x53, 0xb9, 0x55,
-       0x06, 0xa7, 0xea, 0xe1, 0x26, 0xbc, 0x05, 0x2d, 0x47, 0xf3, 0x98, 0xdf,
-       0x68, 0xd0, 0x0d, 0xf9, 0xa6, 0x69, 0x09, 0xe5, 0xe9, 0xc2, 0x40, 0xac,
-       0x49, 0xd4, 0x03, 0xef, 0xc7, 0x9c, 0x5d, 0xd9, 0xe2, 0x77, 0x7a, 0x7b,
-       0x14, 0x75, 0xe1, 0x95, 0x75, 0xba, 0xb0, 0xcd, 0xea, 0xc2, 0xcd, 0xd4,
-       0x85, 0x80, 0xfb, 0x6e, 0x39, 0x56, 0xe6, 0xfa, 0x15, 0x52, 0x4d, 0xd0,
-       0xff, 0xdf, 0xf1, 0x79, 0xc6, 0x45, 0xc7, 0xcd, 0x92, 0xc7, 0x34, 0x2d,
-       0x53, 0xa7, 0xa5, 0xf5, 0x99, 0x90, 0x05, 0xda, 0xd8, 0x09, 0xc6, 0x42,
-       0xa9, 0xf7, 0xfe, 0x3e, 0xfc, 0xcc, 0x1a, 0x7a, 0x6f, 0xbc, 0x6c, 0xec,
-       0xb7, 0x06, 0xd8, 0x84, 0x72, 0xaa, 0x0d, 0xd7, 0x26, 0x9e, 0x89, 0xe8,
-       0xee, 0x52, 0xcd, 0xd2, 0x70, 0x6a, 0xa3, 0x8c, 0x4d, 0x19, 0x1b, 0x57,
-       0x9d, 0x02, 0xfe, 0x4f, 0x31, 0x7f, 0x56, 0x74, 0xbe, 0x7f, 0x7e, 0x12,
-       0x76, 0xee, 0xcc, 0xdd, 0xe6, 0x1c, 0xc8, 0x54, 0x83, 0xfe, 0x4d, 0x1b,
-       0xa4, 0x18, 0x64, 0xa1, 0xef, 0xe2, 0x32, 0x86, 0x3e, 0x3b, 0x77, 0x35,
-       0x62, 0xce, 0x09, 0xb4, 0xa5, 0xcf, 0xc7, 0x38, 0x5a, 0xa3, 0xb8, 0x33,
-       0x49, 0x9d, 0xab, 0xcf, 0xf3, 0xae, 0xb9, 0xfe, 0x56, 0xbc, 0x63, 0x7e,
-       0x84, 0x87, 0xb1, 0x22, 0xd9, 0x8f, 0x7e, 0x4f, 0x88, 0xdd, 0xef, 0xc9,
-       0x68, 0xfd, 0x17, 0x3b, 0xe1, 0xd9, 0xb3, 0x7a, 0xfd, 0x58, 0xf7, 0xb5,
-       0xf4, 0xa2, 0x31, 0x72, 0x73, 0x58, 0x3f, 0x75, 0xd6, 0xc5, 0xbd, 0x1d,
-       0xf7, 0xa8, 0xbf, 0x48, 0x8f, 0x40, 0x37, 0xbe, 0xfd, 0xd0, 0x26, 0x69,
-       0x06, 0xbe, 0x67, 0x14, 0x70, 0x6d, 0x72, 0xbc, 0x0a, 0x9a, 0x17, 0x6a,
-       0xf4, 0xf0, 0xc4, 0xeb, 0xf2, 0x03, 0x69, 0x82, 0xb4, 0x40, 0xb9, 0x48,
-       0xda, 0xa0, 0x4c, 0x24, 0x6d, 0x1b, 0x7a, 0x78, 0x2c, 0xf0, 0x63, 0xcc,
-       0x03, 0x30, 0x71, 0x79, 0xd2, 0x06, 0x69, 0x3e, 0xa5, 0xe3, 0xf5, 0x59,
-       0xf9, 0x96, 0x64, 0x5b, 0x3b, 0x61, 0x97, 0xfd, 0xdb, 0xae, 0xb1, 0x39,
-       0x2b, 0xac, 0x69, 0x0e, 0xba, 0x89, 0x39, 0x79, 0xdd, 0xf2, 0x9e, 0x6a,
-       0x01, 0x78, 0xb8, 0x17, 0x4a, 0xf9, 0x6e, 0x9d, 0xe7, 0xb8, 0xaf, 0xb4,
-       0x49, 0x6e, 0x09, 0xe2, 0x36, 0xee, 0x7e, 0x04, 0x74, 0xb0, 0xe0, 0xc8,
-       0xa9, 0x0b, 0xb8, 0x2e, 0x3a, 0x5c, 0xbf, 0x4b, 0x41, 0x36, 0xad, 0xc8,
-       0xec, 0xbe, 0x9b, 0x5c, 0x90, 0x1e, 0x6f, 0x4c, 0x18, 0xeb, 0x98, 0x77,
-       0x9a, 0x4e, 0xfd, 0xfe, 0x26, 0xe3, 0x4b, 0x03, 0x16, 0xbf, 0xd1, 0x1b,
-       0xa4, 0x2d, 0x17, 0x84, 0x61, 0x9e, 0x76, 0x83, 0x28, 0xed, 0x23, 0xc1,
-       0xe7, 0x43, 0x19, 0xe3, 0x13, 0x3b, 0x9d, 0xc6, 0xb3, 0x2f, 0x58, 0x5a,
-       0x91, 0x98, 0xca, 0x3c, 0xed, 0x34, 0x9c, 0x7a, 0x84, 0x6b, 0xa6, 0xf3,
-       0xae, 0x0d, 0x5d, 0x3d, 0xeb, 0xd4, 0xe8, 0xea, 0x2b, 0xf6, 0xb7, 0xca,
-       0x34, 0x49, 0x36, 0xdd, 0x84, 0xf9, 0x0e, 0x94, 0x22, 0x18, 0xbf, 0x0d,
-       0xb8, 0x08, 0x0f, 0xe8, 0x76, 0xe6, 0x7f, 0xe2, 0x5a, 0x04, 0x2c, 0xf7,
-       0x01, 0xee, 0x4b, 0x80, 0xf9, 0x45, 0x5c, 0x6a, 0x5b, 0x4c, 0xfe, 0xd4,
-       0x89, 0xcd, 0xd4, 0xc3, 0x4b, 0x18, 0xbf, 0x6b, 0xe1, 0x7d, 0x2d, 0x58,
-       0x3d, 0x59, 0xe8, 0xeb, 0x00, 0x3c, 0x84, 0xf3, 0x25, 0xc0, 0x48, 0xbb,
-       0xf5, 0x39, 0x3c, 0x7b, 0x80, 0xef, 0x79, 0x0b, 0x13, 0xe8, 0x71, 0xea,
-       0x2f, 0x6a, 0xbf, 0x4b, 0xb4, 0xa3, 0xff, 0xd2, 0x3e, 0xb7, 0xaf, 0x90,
-       0x01, 0x5d, 0x0e, 0xf1, 0x3c, 0x51, 0x5e, 0xa4, 0x1d, 0x00, 0xbe, 0xff,
-       0xae, 0xc4, 0xce, 0x26, 0xe5, 0x68, 0x89, 0x7b, 0x40, 0xa7, 0x81, 0x0f,
-       0x7d, 0xc6, 0x05, 0x75, 0xae, 0xc2, 0x05, 0x65, 0x3f, 0xb3, 0x1b, 0x57,
-       0x37, 0xae, 0xb7, 0xe2, 0x02, 0x39, 0xcc, 0x9c, 0xc2, 0xd5, 0x83, 0xbe,
-       0x55, 0xa2, 0x49, 0x98, 0x9b, 0xf5, 0x0d, 0xb4, 0xd1, 0xb6, 0x65, 0x41,
-       0x65, 0xfa, 0x80, 0xbf, 0x3e, 0xc0, 0x96, 0xc4, 0xc5, 0x7c, 0xe6, 0xef,
-       0x3a, 0x72, 0xf6, 0x65, 0x5c, 0x60, 0xb0, 0xb3, 0x20, 0xcc, 0xb3, 0xfd,
-       0xb8, 0xa0, 0xc4, 0xce, 0x66, 0x71, 0x0d, 0xe2, 0xfa, 0x2b, 0xc7, 0xf0,
-       0x5c, 0x3b, 0xf0, 0x15, 0xf1, 0x08, 0x70, 0xbe, 0x8c, 0xe7, 0xbe, 0xec,
-       0xbc, 0x71, 0x9e, 0xfb, 0xbe, 0x63, 0x78, 0xee, 0x15, 0xa7, 0xc6, 0x73,
-       0x17, 0x1c, 0xf5, 0xf0, 0xd3, 0x4e, 0xec, 0x61, 0xfa, 0x12, 0x17, 0x1c,
-       0xc3, 0xff, 0x31, 0x19, 0x38, 0x08, 0x5a, 0x7a, 0x78, 0x1e, 0x17, 0xe9,
-       0xea, 0x19, 0x94, 0x3f, 0xbf, 0x62, 0xdc, 0xe7, 0xde, 0xc4, 0xb8, 0xaf,
-       0xda, 0x71, 0x45, 0xd5, 0xc6, 0x7d, 0x11, 0x7d, 0xbf, 0x64, 0xc7, 0x7d,
-       0xb1, 0x6e, 0x5c, 0xd0, 0xca, 0xc3, 0x8b, 0xb8, 0x48, 0x17, 0x2f, 0xa0,
-       0x3c, 0x92, 0x09, 0x1f, 0xf4, 0xa4, 0xb9, 0x01, 0xbc, 0x1b, 0x87, 0x7e,
-       0x6c, 0x58, 0xd2, 0x8d, 0xd9, 0x3a, 0xfd, 0xf0, 0x46, 0xf4, 0xe3, 0x78,
-       0x99, 0x36, 0xe2, 0x7c, 0x9d, 0x5c, 0xa0, 0x6f, 0x14, 0xca, 0x49, 0xed,
-       0x07, 0xd1, 0x27, 0xa2, 0x7f, 0xb4, 0xd2, 0xb6, 0xfa, 0xa8, 0xce, 0x45,
-       0xfb, 0x95, 0x52, 0xbb, 0xdc, 0x59, 0xa2, 0x4d, 0x48, 0x7a, 0x09, 0xc3,
-       0xb1, 0x3d, 0xb4, 0x4f, 0x0b, 0xe1, 0x15, 0x3e, 0xe9, 0xc4, 0xf7, 0x7e,
-       0x79, 0xb5, 0xce, 0x98, 0x1c, 0x80, 0xef, 0x9e, 0x3b, 0xf1, 0x8b, 0xd0,
-       0x19, 0x0d, 0x80, 0x9b, 0xf4, 0xb6, 0x4d, 0x0e, 0x4c, 0xaa, 0x89, 0x2d,
-       0x90, 0x25, 0x37, 0x95, 0x1a, 0x61, 0xf7, 0x30, 0x4f, 0xab, 0x59, 0x3a,
-       0xf7, 0xc4, 0x4d, 0x1e, 0xb9, 0x97, 0xc0, 0x6f, 0xcf, 0xe4, 0xb5, 0x27,
-       0x92, 0x78, 0xff, 0x0f, 0x1e, 0xe5, 0x60, 0xc2, 0xbf, 0x4e, 0xe7, 0x08,
-       0x75, 0xec, 0xa1, 0xdd, 0x72, 0x83, 0xd6, 0xe1, 0xee, 0x2a, 0x3b, 0x49,
-       0x6d, 0xf3, 0xa4, 0x66, 0xa3, 0x8d, 0x96, 0xd2, 0x29, 0xc2, 0xf5, 0x90,
-       0x70, 0xff, 0xeb, 0x1e, 0x29, 0x06, 0x1b, 0xe1, 0x17, 0x30, 0x76, 0x9e,
-       0xee, 0xa6, 0x6d, 0x34, 0x33, 0xe5, 0xd9, 0x3c, 0xeb, 0x4d, 0xf2, 0xac,
-       0x1e, 0xa7, 0x51, 0xc3, 0x68, 0xce, 0x5e, 0x70, 0x1f, 0x21, 0xae, 0xcf,
-       0xfb, 0xcc, 0x54, 0x5a, 0xb4, 0xde, 0x99, 0xa9, 0x30, 0xaf, 0x1f, 0xfe,
-       0x54, 0x85, 0x79, 0xfc, 0x81, 0x78, 0x6f, 0x87, 0x9f, 0x5b, 0xd9, 0x21,
-       0xa3, 0x53, 0xeb, 0xa4, 0xd1, 0x57, 0x89, 0x2d, 0xd0, 0x1f, 0x6c, 0xd3,
-       0xb1, 0x07, 0xfe, 0xe1, 0xf4, 0x4e, 0x79, 0x62, 0x9a, 0x7d, 0x6f, 0x93,
-       0xd9, 0x39, 0x71, 0xbc, 0xb7, 0xaf, 0x47, 0x1d, 0xc8, 0xf5, 0x3d, 0x2c,
-       0x4b, 0xe1, 0x2e, 0xca, 0x7b, 0xbb, 0x2b, 0x17, 0xfb, 0xf8, 0xcc, 0xb3,
-       0x04, 0xe2, 0xb2, 0xbf, 0x8b, 0x7d, 0xed, 0x72, 0x6e, 0x0e, 0x34, 0x01,
-       0xb9, 0x3f, 0x78, 0x8a, 0x30, 0x89, 0xec, 0x9d, 0x61, 0x2c, 0xbd, 0xd3,
-       0x63, 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0xf4, 0x71, 0x2c, 0xe8, 0x25, 0xe8,
-       0xb8, 0x8e, 0x3d, 0x46, 0x16, 0x64, 0x67, 0x1a, 0x50, 0xce, 0x7e, 0xe1,
-       0x3f, 0x1e, 0x64, 0x3f, 0x51, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59,
-       0x5c, 0xa1, 0x3f, 0xce, 0xff, 0x48, 0xf6, 0x37, 0xfb, 0xe8, 0xd6, 0x7b,
-       0x21, 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae,
-       0xba, 0x4a, 0xdb, 0x17, 0xb3, 0x55, 0xae, 0x20, 0x63, 0x51, 0xd1, 0x1a,
-       0x25, 0xe5, 0xd1, 0xf2, 0xd2, 0x3a, 0xed, 0x68, 0x58, 0xbe, 0x4e, 0xa4,
-       0x95, 0x60, 0xc4, 0xda, 0x1e, 0x0b, 0x72, 0x0c, 0x76, 0x59, 0xb7, 0x5e,
-       0xb3, 0x05, 0xd8, 0xb2, 0x76, 0xcd, 0xb4, 0x3d, 0x5b, 0x8c, 0xd6, 0x6c,
-       0x18, 0x1a, 0xa7, 0x92, 0xd9, 0xcc, 0x35, 0xf3, 0x18, 0xef, 0x06, 0xde,
-       0x0b, 0x58, 0xa7, 0x02, 0xd6, 0xa8, 0x50, 0xd9, 0x26, 0x33, 0x27, 0x55,
-       0x7b, 0x83, 0x48, 0x6a, 0xd4, 0xdf, 0x26, 0xe3, 0x73, 0x8c, 0x25, 0xec,
-       0x80, 0x0d, 0xb6, 0x13, 0x57, 0x3b, 0x9e, 0xd9, 0x2e, 0x21, 0xc5, 0x8a,
-       0x42, 0xdb, 0xa6, 0x55, 0x76, 0xd6, 0x39, 0x8c, 0xcd, 0x33, 0x9d, 0x8f,
-       0x01, 0x0f, 0x35, 0xde, 0x29, 0xd5, 0xc5, 0x9f, 0x38, 0x57, 0xad, 0x43,
-       0x31, 0xdf, 0x84, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x37, 0xbe, 0x19, 0x7b,
-       0x2a, 0x49, 0x7b, 0x2a, 0x3f, 0xe9, 0x99, 0xf3, 0x06, 0xc3, 0xf0, 0x9d,
-       0xfc, 0xfc, 0x66, 0xd2, 0xfa, 0xc8, 0x34, 0xe1, 0x8a, 0x47, 0x70, 0x2d,
-       0x5b, 0x33, 0x9e, 0x0f, 0x5b, 0x1d, 0xe7, 0x28, 0x2d, 0xe5, 0x43, 0x9a,
-       0xd8, 0x3e, 0xe3, 0x28, 0xed, 0x6b, 0xc0, 0x74, 0xb7, 0xb6, 0x61, 0x45,
-       0xdd, 0x26, 0x87, 0xcb, 0x3c, 0x5b, 0xc6, 0x78, 0xe2, 0x27, 0x19, 0x5f,
-       0xea, 0x9e, 0x91, 0x63, 0x18, 0x9b, 0xb9, 0x3f, 0xca, 0xc6, 0x6f, 0x36,
-       0xd8, 0x1c, 0x91, 0xfa, 0x18, 0x8e, 0xc9, 0x0d, 0x5a, 0x9e, 0x67, 0x9d,
-       0x1e, 0x5e, 0xc4, 0x3a, 0xff, 0x9a, 0xde, 0x1b, 0x94, 0xc9, 0x18, 0xb4,
-       0xdf, 0x68, 0x5f, 0xba, 0xdf, 0x9c, 0xab, 0x49, 0xc9, 0x50, 0xd9, 0xcc,
-       0xff, 0x92, 0xce, 0x11, 0x32, 0xb9, 0x90, 0x26, 0x7f, 0xe8, 0x1e, 0xb9,
-       0x04, 0x1d, 0x5e, 0x5b, 0xdb, 0x26, 0x19, 0x07, 0x2e, 0xf2, 0x7a, 0x5f,
-       0x22, 0x25, 0xf9, 0xbe, 0x47, 0x37, 0xf3, 0xdc, 0x45, 0x1c, 0xeb, 0x53,
-       0x9c, 0xe6, 0x59, 0x4c, 0xf6, 0x7b, 0xb9, 0xbe, 0x28, 0x66, 0x99, 0xd7,
-       0x0f, 0x59, 0xf9, 0x63, 0x3d, 0xc9, 0x66, 0xfd, 0x7e, 0x9d, 0xcd, 0xdf,
-       0x76, 0x44, 0x0e, 0x84, 0xf2, 0x87, 0xd0, 0x93, 0x67, 0xec, 0x9c, 0x52,
-       0x3a, 0x66, 0x25, 0xe1, 0xc5, 0x20, 0x69, 0x63, 0x96, 0x9c, 0xcb, 0x41,
-       0x4b, 0xdf, 0xc6, 0xfe, 0xa9, 0xd9, 0xd0, 0x66, 0xdf, 0xef, 0x09, 0x2d,
-       0x0b, 0x7b, 0xad, 0xed, 0xac, 0xe3, 0x3c, 0x8f, 0x88, 0xce, 0x09, 0x88,
-       0x7c, 0xa3, 0xae, 0x3a, 0xbf, 0xc0, 0xf8, 0x72, 0xc5, 0xa9, 0xb5, 0x64,
-       0x54, 0xcd, 0x27, 0xa4, 0x2f, 0x37, 0xb6, 0x8b, 0xdf, 0x47, 0x88, 0x7c,
-       0xb9, 0x5e, 0xeb, 0xcb, 0x6d, 0xd4, 0xbe, 0x9c, 0x89, 0x3d, 0x6c, 0x5c,
-       0xf2, 0xe5, 0x8a, 0x53, 0x05, 0xd0, 0x4a, 0xf4, 0x3d, 0x07, 0x63, 0x0b,
-       0x8d, 0x97, 0x78, 0x86, 0xa6, 0x51, 0xf2, 0xc3, 0x0a, 0x7e, 0x83, 0xf1,
-       0xb1, 0x18, 0xab, 0x50, 0xea, 0xeb, 0xd6, 0xbf, 0x68, 0x97, 0x6c, 0xdb,
-       0x3a, 0xcc, 0xfb, 0x6e, 0xbd, 0xe6, 0xb3, 0x25, 0xb3, 0xf7, 0x99, 0x3f,
-       0xc8, 0x98, 0x10, 0xcf, 0x49, 0x69, 0xfe, 0x4a, 0x0d, 0xc4, 0xba, 0x8d,
-       0x3d, 0xeb, 0x7b, 0xad, 0xd2, 0x7c, 0x1a, 0x38, 0x8f, 0xdb, 0x71, 0x53,
-       0x80, 0xe9, 0x30, 0xd6, 0xe6, 0x3a, 0x2b, 0x93, 0x39, 0xf6, 0x47, 0x9b,
-       0x18, 0x1b, 0x98, 0x2b, 0x45, 0x31, 0xc2, 0x98, 0x3d, 0xa3, 0xe9, 0xc7,
-       0x1a, 0xfd, 0x75, 0x6b, 0xda, 0xaa, 0x8f, 0xbf, 0xae, 0x6e, 0x22, 0x2d,
-       0xdd, 0xad, 0xf3, 0x5c, 0xd6, 0xf7, 0xa5, 0xf7, 0xeb, 0x9c, 0x7b, 0x1d,
-       0x63, 0x2c, 0x08, 0x73, 0xd4, 0xbe, 0x29, 0x3f, 0xa1, 0x65, 0xfe, 0xe1,
-       0x80, 0xfa, 0x6b, 0x8f, 0xfe, 0xdd, 0x98, 0x09, 0xc3, 0x8b, 0x7d, 0x13,
-       0x8c, 0x29, 0x7a, 0xdf, 0x96, 0xce, 0xe4, 0x80, 0xb6, 0x9d, 0xb0, 0x46,
-       0x07, 0x9b, 0x65, 0x9d, 0x3f, 0x62, 0x73, 0x66, 0x0a, 0x90, 0x9b, 0x69,
-       0xd8, 0x4c, 0x3c, 0x7f, 0xdc, 0x65, 0xdf, 0x15, 0xc2, 0x66, 0xd0, 0xd1,
-       0x07, 0xc5, 0xc8, 0x98, 0x7c, 0x4d, 0xc6, 0x30, 0xd7, 0x20, 0x4b, 0x42,
-       0x76, 0x8f, 0x4b, 0x9a, 0xdf, 0x2a, 0xe1, 0xd8, 0x45, 0xd9, 0x0a, 0xbd,
-       0xcc, 0x76, 0xb4, 0x55, 0xf9, 0xcc, 0x3d, 0x1c, 0xdf, 0x3b, 0x02, 0xdd,
-       0x72, 0xc3, 0x6a, 0xdd, 0x92, 0xa4, 0x5f, 0x9f, 0x9f, 0xa4, 0x6f, 0xb8,
-       0x1e, 0x6d, 0xb6, 0xc9, 0x87, 0xa6, 0x7e, 0xbe, 0x95, 0xbc, 0x35, 0x02,
-       0xb9, 0xae, 0xee, 0x8f, 0xce, 0x16, 0xb1, 0x8c, 0xef, 0xd9, 0x6f, 0x93,
-       0xa4, 0xde, 0xeb, 0xc9, 0x6f, 0x54, 0xd3, 0xa9, 0x45, 0xe8, 0xa6, 0x11,
-       0xe7, 0x57, 0xb7, 0x9b, 0x98, 0xea, 0x07, 0x5a, 0xcd, 0x59, 0x84, 0x66,
-       0xe0, 0x34, 0x8a, 0xb3, 0xd6, 0xd3, 0xec, 0xa2, 0x95, 0xc7, 0x61, 0xd8,
-       0xdc, 0xa7, 0x65, 0xf0, 0x7e, 0xca, 0xe0, 0xc3, 0x41, 0x97, 0xa1, 0x7d,
-       0xed, 0x33, 0x85, 0x58, 0x47, 0xe0, 0xa1, 0xcf, 0x65, 0xbe, 0x9f, 0xe5,
-       0x4f, 0x3f, 0xbb, 0x60, 0xe5, 0x92, 0x72, 0x56, 0xf3, 0xa5, 0xba, 0x26,
-       0xbe, 0x4c, 0xe6, 0x1e, 0x9d, 0xa2, 0x3e, 0x0e, 0xe6, 0xbf, 0x09, 0x39,
-       0x95, 0xd7, 0x78, 0xd8, 0x26, 0xf7, 0x4d, 0x49, 0xf6, 0x12, 0x74, 0x55,
-       0x71, 0x6e, 0x39, 0x6f, 0xae, 0xee, 0x8f, 0x73, 0x7d, 0xa4, 0xd5, 0xf8,
-       0xb6, 0xcb, 0xe7, 0x3a, 0x8f, 0xb9, 0x66, 0xf5, 0x5c, 0xb9, 0x6f, 0x33,
-       0x67, 0xe7, 0xba, 0x3e, 0x9a, 0x6b, 0xff, 0xf2, 0xb9, 0x46, 0xbe, 0x7d,
-       0x24, 0x77, 0x53, 0x3a, 0xff, 0x5e, 0xe7, 0x7d, 0x4f, 0xad, 0x97, 0x81,
-       0xc9, 0x8d, 0x56, 0x5e, 0x7a, 0xd0, 0x3d, 0xcc, 0x89, 0x9f, 0xbf, 0xd7,
-       0x13, 0x8b, 0x33, 0x45, 0x3c, 0x50, 0xd6, 0xb6, 0xea, 0x33, 0x3b, 0x33,
-       0xf0, 0xaf, 0x6e, 0x2d, 0xb1, 0x6e, 0xf4, 0xfe, 0x72, 0xb1, 0xe3, 0xc8,
-       0xa7, 0xa6, 0xdf, 0xd4, 0xbd, 0x2a, 0xa6, 0x60, 0xe2, 0xc3, 0x8c, 0x0b,
-       0x9b, 0xb3, 0xc4, 0xcc, 0x45, 0xbc, 0x03, 0x3c, 0xf5, 0xf1, 0x52, 0xba,
-       0x3f, 0x17, 0xa3, 0x1c, 0x9d, 0x96, 0xa3, 0xd5, 0x41, 0xe9, 0xd0, 0xe7,
-       0x49, 0x5f, 0x37, 0x76, 0x9c, 0xad, 0x8f, 0x1d, 0x33, 0x9d, 0x80, 0xb1,
-       0xe3, 0xfd, 0x3f, 0x42, 0xec, 0x58, 0x1c, 0x13, 0x3b, 0x5e, 0xcb, 0xbf,
-       0x9a, 0x28, 0x4f, 0x63, 0x5e, 0xcd, 0x90, 0x25, 0x0b, 0x4e, 0x7e, 0xae,
-       0x05, 0xf7, 0x0b, 0xb8, 0xc7, 0x71, 0xbf, 0x84, 0xbb, 0x87, 0xfb, 0x8b,
-       0xb8, 0x27, 0x64, 0x62, 0x49, 0x67, 0x4c, 0x43, 0x6e, 0x50, 0x97, 0xb1,
-       0xad, 0xf1, 0x07, 0x66, 0x2b, 0x6d, 0xfc, 0x2e, 0x8c, 0x33, 0x33, 0xc7,
-       0x39, 0x6c, 0x94, 0xf1, 0x29, 0xca, 0xec, 0x56, 0x99, 0x9c, 0x8a, 0x6c,
-       0xdb, 0xbb, 0xb6, 0x71, 0xcf, 0x60, 0x44, 0x22, 0xdb, 0xf5, 0x77, 0xb7,
-       0xd9, 0x5c, 0xfb, 0x2d, 0xd2, 0xbc, 0x09, 0x6b, 0x70, 0x5a, 0x2e, 0x4d,
-       0x6f, 0x5a, 0x66, 0xc3, 0xa6, 0x6c, 0x4c, 0x70, 0xda, 0xea, 0xde, 0xb5,
-       0x65, 0x44, 0xfd, 0xfa, 0x27, 0x6d, 0x4e, 0x69, 0x94, 0x23, 0x94, 0xd2,
-       0xeb, 0x33, 0x5c, 0x9d, 0xc6, 0x78, 0xfd, 0x92, 0x9d, 0xe6, 0x3c, 0x97,
-       0xbe, 0x4d, 0x01, 0x79, 0x78, 0x0a, 0x7a, 0x75, 0x19, 0x5d, 0x82, 0x6e,
-       0x39, 0x37, 0x07, 0xb4, 0xfb, 0xa8, 0xcc, 0x4c, 0x12, 0xbe, 0xae, 0x64,
-       0x4c, 0x9f, 0x5d, 0xc3, 0xf3, 0xb4, 0xc9, 0x99, 0x1f, 0xa8, 0x46, 0xe7,
-       0xd6, 0x36, 0xeb, 0xef, 0x11, 0x2c, 0x3f, 0xbb, 0x66, 0xf5, 0xb3, 0xb6,
-       0x1d, 0x78, 0x86, 0x2d, 0x9a, 0xc3, 0x5a, 0xf4, 0x14, 0xca, 0xb8, 0xce,
-       0x3b, 0xdb, 0x22, 0x67, 0x1e, 0x5c, 0xca, 0xa1, 0x6d, 0x85, 0x8d, 0xd2,
-       0x0e, 0x13, 0x79, 0xd8, 0xcd, 0x74, 0xc1, 0xc7, 0x63, 0x9e, 0x4c, 0x57,
-       0xf2, 0x36, 0x9d, 0xdb, 0x5c, 0x3b, 0x47, 0x58, 0xcb, 0x6f, 0x8e, 0xce,
-       0x6d, 0x25, 0x65, 0x10, 0x74, 0x38, 0xa4, 0xcb, 0x13, 0x98, 0x0f, 0xf7,
-       0xfd, 0x34, 0x1e, 0x20, 0x7b, 0xb8, 0xe7, 0x87, 0xb9, 0x57, 0xbf, 0x01,
-       0x7a, 0x77, 0xec, 0x19, 0x36, 0xd2, 0x58, 0x9f, 0x8c, 0x55, 0x92, 0xce,
-       0x58, 0xa5, 0xcf, 0x39, 0x54, 0xb1, 0xef, 0xfa, 0x8a, 0x58, 0x0f, 0xfc,
-       0x9e, 0xee, 0x70, 0x46, 0x80, 0xaf, 0x62, 0xb9, 0xd3, 0xc9, 0xea, 0xbb,
-       0x6f, 0xef, 0x90, 0x03, 0x58, 0xab, 0x81, 0xe9, 0xa4, 0x96, 0xf3, 0xb5,
-       0xef, 0x61, 0x45, 0xeb, 0xfa, 0xa4, 0xde, 0x1b, 0x9a, 0x97, 0x69, 0xfd,
-       0x7d, 0x25, 0x63, 0x3b, 0x9c, 0x46, 0x7f, 0xd3, 0x36, 0x26, 0xde, 0xe3,
-       0xe4, 0x75, 0x3f, 0x66, 0x3d, 0x8a, 0xe5, 0x53, 0xb8, 0xaf, 0x3c, 0x43,
-       0x1d, 0xe9, 0x19, 0xc2, 0xfd, 0x08, 0xf4, 0x59, 0x78, 0x8f, 0x91, 0x57,
-       0xd3, 0x32, 0x51, 0x65, 0xfe, 0x08, 0xfb, 0x41, 0x79, 0xe5, 0x30, 0x74,
-       0xd2, 0xf2, 0x33, 0x84, 0x43, 0xb5, 0x75, 0x48, 0x4d, 0x0b, 0x61, 0xe1,
-       0x1a, 0x2c, 0x3f, 0x5f, 0x7f, 0xf9, 0x7f, 0xd1, 0xbe, 0xa2, 0x91, 0xa1,
-       0x16, 0x8e, 0x2c, 0xe5, 0x9d, 0x91, 0x2b, 0x9f, 0x96, 0x23, 0xc0, 0xe3,
-       0x31, 0xc0, 0xa4, 0xee, 0xe7, 0xf7, 0x5e, 0x2a, 0x52, 0x9c, 0xbd, 0x4f,
-       0xd4, 0x43, 0x97, 0x1c, 0xf7, 0xa1, 0x23, 0x12, 0x7b, 0x68, 0xc1, 0x69,
-       0x78, 0xa8, 0x53, 0xfb, 0xe5, 0xfb, 0x82, 0xce, 0xe4, 0x21, 0x39, 0x2d,
-       0xee, 0xfd, 0x4a, 0x9f, 0x27, 0x2b, 0x7a, 0x8c, 0xf1, 0x9d, 0x96, 0xd8,
-       0xfd, 0x71, 0x7b, 0x16, 0xd5, 0xc4, 0xf5, 0x16, 0x35, 0xdf, 0x3f, 0x97,
-       0x20, 0xce, 0x16, 0x65, 0x5a, 0xf3, 0xce, 0x00, 0xf4, 0x44, 0x6e, 0x32,
-       0xb5, 0x54, 0xc7, 0xe4, 0x7b, 0x6e, 0x4c, 0x18, 0x7e, 0x61, 0x9d, 0x2e,
-       0x87, 0xdf, 0x85, 0xb0, 0x3a, 0xff, 0xca, 0x28, 0xf7, 0xd3, 0xac, 0x29,
-       0xdf, 0xff, 0x10, 0x6b, 0xd8, 0x85, 0xf5, 0xe2, 0x78, 0x8e, 0xde, 0xcf,
-       0xe5, 0x59, 0x5c, 0x4f, 0x7a, 0x92, 0x4d, 0x4b, 0x76, 0x10, 0xeb, 0xde,
-       0x27, 0x4d, 0x80, 0x5b, 0x3d, 0x54, 0x34, 0x76, 0x9d, 0x90, 0x4e, 0x05,
-       0x92, 0x9b, 0x34, 0xdb, 0xd5, 0xbf, 0x4f, 0xaf, 0xe1, 0xbd, 0x96, 0x66,
-       0xd6, 0x19, 0xfb, 0x11, 0xcf, 0x86, 0x2e, 0x8a, 0xb2, 0x77, 0xea, 0xbb,
-       0xd0, 0xf3, 0xdc, 0x77, 0xd1, 0xf6, 0xe2, 0x1a, 0xb6, 0x20, 0x79, 0xe9,
-       0x69, 0xeb, 0x57, 0x86, 0xe1, 0x54, 0x10, 0x00, 0x8f, 0x6b, 0xf9, 0x92,
-       0x3b, 0x9c, 0xd9, 0xc9, 0x9d, 0xce, 0xcc, 0x64, 0x28, 0x63, 0x01, 0xbf,
-       0x19, 0xc2, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x84, 0x6e, 0xdd, 0x9d,
-       0xe0, 0xf9, 0xa6, 0x9b, 0xfc, 0x17, 0xc4, 0xd4, 0x23, 0x8e, 0xe9, 0x23,
-       0x77, 0x3e, 0x92, 0x17, 0x7e, 0x9f, 0xa3, 0x27, 0x99, 0xd0, 0xdf, 0x10,
-       0xf9, 0x0c, 0xda, 0x61, 0x8c, 0x32, 0xc7, 0x7d, 0xc6, 0x99, 0x81, 0x3c,
-       0x9b, 0x9d, 0xe2, 0x37, 0x01, 0x98, 0x4f, 0x1b, 0x6b, 0x57, 0x72, 0x95,
-       0x37, 0x6e, 0xbf, 0x5b, 0x57, 0x80, 0x0b, 0x14, 0xd3, 0x65, 0x3d, 0xde,
-       0xe8, 0xd2, 0xb7, 0xec, 0xa2, 0xb2, 0xe8, 0x9b, 0x76, 0x4a, 0xe7, 0x4e,
-       0xc3, 0x97, 0x3d, 0x33, 0x22, 0xdf, 0x77, 0xe6, 0x4a, 0xaf, 0x38, 0x8f,
-       0x96, 0xb2, 0xd7, 0x5c, 0x01, 0xfa, 0xb8, 0x18, 0xe4, 0x29, 0xbf, 0x60,
-       0xf3, 0x4d, 0x49, 0xa1, 0x3a, 0x26, 0xd3, 0xdb, 0x3a, 0xbd, 0xfb, 0xf5,
-       0xda, 0x9c, 0x01, 0xce, 0xbe, 0x81, 0xf5, 0x3b, 0x93, 0xa0, 0x7e, 0x1b,
-       0x2d, 0x29, 0xf0, 0xb2, 0xfa, 0x69, 0x5c, 0xb0, 0x6d, 0x1b, 0xb5, 0x8d,
-       0x72, 0x28, 0x60, 0xbd, 0x9d, 0xce, 0xc0, 0xe4, 0x0e, 0xac, 0xe3, 0x41,
-       0xe8, 0x4f, 0x07, 0x76, 0x1a, 0x68, 0x1b, 0x65, 0xe3, 0xc0, 0xc1, 0x68,
-       0x60, 0xe4, 0xf9, 0x80, 0x14, 0xb4, 0x8f, 0x67, 0xee, 0x59, 0x65, 0x62,
-       0x66, 0x61, 0x38, 0x0b, 0xfb, 0x80, 0xdf, 0xc5, 0x9a, 0xa8, 0xce, 0xe1,
-       0xfa, 0x71, 0xbb, 0xa7, 0x3d, 0x7f, 0x99, 0x3d, 0x6d, 0x4f, 0x4e, 0x57,
-       0xf5, 0x39, 0x79, 0x9d, 0x5f, 0x95, 0x52, 0xeb, 0xda, 0xf4, 0x5a, 0xa9,
-       0x2e, 0x9d, 0x93, 0x96, 0x95, 0x47, 0x12, 0x46, 0x0f, 0x13, 0xa6, 0x14,
-       0xe0, 0xd9, 0x09, 0x5c, 0x10, 0x1e, 0xd3, 0x46, 0xd4, 0x3b, 0xb7, 0x52,
-       0x1f, 0x2e, 0xca, 0xa7, 0x12, 0xd1, 0x19, 0x05, 0xf4, 0x03, 0x19, 0x37,
-       0xb7, 0xd5, 0xe8, 0xc9, 0x2d, 0x6b, 0xf4, 0x13, 0xcd, 0xcd, 0xb1, 0x73,
-       0x23, 0xdd, 0x6e, 0xbe, 0x92, 0x3e, 0xc5, 0xa2, 0x34, 0xad, 0xa8, 0xcf,
-       0x98, 0xfe, 0xbe, 0xed, 0xe6, 0xcc, 0x03, 0xeb, 0x7a, 0xb0, 0x4d, 0x69,
-       0xe7, 0x12, 0x8f, 0x7a, 0xdd, 0x4a, 0x4a, 0x78, 0x6e, 0xe1, 0x0c, 0x64,
-       0xcb, 0x55, 0xde, 0x4f, 0x28, 0xd2, 0x61, 0x84, 0xeb, 0x6f, 0x68, 0x3e,
-       0x19, 0x2d, 0x31, 0xb6, 0xf2, 0x68, 0x98, 0x1d, 0x26, 0x8f, 0xb1, 0x0f,
-       0xbe, 0x9f, 0xd2, 0xf1, 0xdc, 0x83, 0x01, 0x63, 0x45, 0x9d, 0x8f, 0xdc,
-       0xa1, 0x22, 0x39, 0x05, 0xfd, 0x5b, 0x5e, 0x70, 0xf8, 0xdd, 0xbe, 0x03,
-       0x82, 0xfb, 0xdc, 0x82, 0xf3, 0xcd, 0xa9, 0x67, 0xf0, 0xdc, 0x60, 0xbf,
-       0xd5, 0x67, 0xf4, 0x94, 0xc8, 0x1f, 0x46, 0xf3, 0x4d, 0x16, 0xb0, 0xf6,
-       0x2f, 0x62, 0xed, 0xd7, 0xfe, 0x36, 0x1f, 0xde, 0x55, 0xf0, 0xae, 0xf2,
-       0x0b, 0x61, 0xb6, 0x95, 0xb4, 0x18, 0xe8, 0xb3, 0xa9, 0x97, 0xf7, 0x9b,
-       0xfb, 0x35, 0x5f, 0x8c, 0x97, 0xcf, 0x81, 0x2f, 0xb2, 0xdc, 0x6f, 0x0e,
-       0x1f, 0x0e, 0x6e, 0x04, 0x5f, 0xec, 0x97, 0xdf, 0x83, 0x5d, 0xf0, 0x3b,
-       0xd5, 0x0c, 0xf8, 0xa3, 0x1f, 0xfc, 0xd2, 0x07, 0x1e, 0x09, 0xb4, 0x8d,
-       0xfc, 0x18, 0xf4, 0x1f, 0xf4, 0x9a, 0x73, 0x68, 0xb2, 0xc3, 0xc9, 0x4f,
-       0xfa, 0xce, 0xd8, 0x24, 0xbf, 0xff, 0xa2, 0xde, 0xda, 0x20, 0x6e, 0x72,
-       0x56, 0xc8, 0x0b, 0x9d, 0xcc, 0x71, 0x6c, 0x03, 0xae, 0xce, 0x12, 0x57,
-       0xb3, 0xd5, 0x1e, 0xef, 0x0a, 0xf0, 0x44, 0x9b, 0xe6, 0x89, 0x8d, 0x4e,
-       0xd6, 0xbb, 0xd1, 0xf2, 0xc4, 0x0b, 0xe0, 0x89, 0x4b, 0xab, 0x78, 0xe2,
-       0x29, 0x4b, 0xff, 0xf3, 0x75, 0x3c, 0x31, 0x6b, 0xcb, 0xa6, 0x2f, 0xc3,
-       0x13, 0x5b, 0xfd, 0xf4, 0xe7, 0x47, 0xe4, 0x55, 0xf0, 0x84, 0x28, 0xf2,
-       0xc4, 0x56, 0xcd, 0x13, 0x8c, 0x1d, 0x91, 0x2f, 0xda, 0x21, 0x47, 0xc8,
-       0x17, 0x17, 0x64, 0x11, 0x7c, 0xf1, 0x9c, 0xe2, 0xd8, 0x67, 0x68, 0x2b,
-       0x4c, 0xd2, 0x27, 0x3b, 0x55, 0xee, 0x00, 0xbf, 0x2b, 0xf9, 0xaf, 0x53,
-       0x61, 0xb8, 0x00, 0x3f, 0xfd, 0x41, 0xd8, 0xf3, 0xae, 0xfe, 0x0e, 0xe4,
-       0x3c, 0xe8, 0x3e, 0xa2, 0xf7, 0x31, 0x07, 0xf4, 0x7e, 0x6c, 0x06, 0x73,
-       0x18, 0x53, 0x9f, 0x82, 0x2f, 0xec, 0x61, 0x5d, 0x69, 0xe7, 0x9f, 0xd4,
-       0x3c, 0xd4, 0x00, 0x7d, 0xf0, 0x68, 0x1f, 0x63, 0x4d, 0xbe, 0x77, 0x48,
-       0x75, 0x16, 0x06, 0x01, 0x73, 0x4c, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xae,
-       0xb0, 0xf3, 0x29, 0x23, 0x86, 0x21, 0xeb, 0xcc, 0xbb, 0x42, 0xd8, 0x04,
-       0x9b, 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x49, 0x7b, 0x3f, 0x07, 0x01,
-       0xda, 0x08, 0x7b, 0x61, 0x2f, 0x56, 0x7b, 0xb0, 0x54, 0x6f, 0xe3, 0xff,
-       0x67, 0xd8, 0xf8, 0x6c, 0x23, 0xae, 0xb1, 0xf1, 0x7f, 0xc5, 0xf2, 0x1a,
-       0x7f, 0x7b, 0xda, 0xde, 0x3f, 0x0c, 0xf8, 0xf6, 0x2d, 0xd9, 0xfb, 0xec,
-       0x83, 0x76, 0x87, 0xc8, 0x0d, 0xb0, 0xf9, 0xde, 0x09, 0x1e, 0xbc, 0x11,
-       0xbe, 0xd4, 0xbb, 0x4a, 0x9e, 0xec, 0x2f, 0xb5, 0xc1, 0xe7, 0x6e, 0x97,
-       0x77, 0x4f, 0xed, 0x94, 0xa1, 0xc9, 0x0f, 0x5e, 0x21, 0xcd, 0xdb, 0x60,
-       0xa3, 0x4e, 0x01, 0xce, 0x98, 0x95, 0xdb, 0x3f, 0x04, 0xde, 0x3a, 0x53,
-       0xdf, 0x57, 0x6d, 0xdb, 0x8d, 0x9c, 0xe7, 0xd9, 0xc9, 0xb5, 0xfa, 0x49,
-       0xa0, 0x3d, 0x63, 0x29, 0xdb, 0xe4, 0xec, 0x49, 0x7a, 0x5f, 0x29, 0xd8,
-       0xe5, 0x01, 0x6c, 0x92, 0x1d, 0xe8, 0x8f, 0xf1, 0xe4, 0x4d, 0xf2, 0xd4,
-       0x35, 0xee, 0x27, 0xf2, 0x9a, 0x0f, 0xdb, 0x9d, 0xdc, 0xd4, 0x8d, 0x52,
-       0x3c, 0x18, 0xc7, 0x1c, 0x54, 0xdb, 0x16, 0xb9, 0x5e, 0x86, 0xf4, 0x7c,
-       0xce, 0xc8, 0x11, 0xe8, 0xe6, 0x3f, 0x28, 0x0d, 0xc9, 0xe2, 0x70, 0x2b,
-       0x9e, 0xe3, 0xf2, 0x54, 0xa9, 0x07, 0xbe, 0xcf, 0x3b, 0x80, 0xa3, 0x46,
-       0x3c, 0x37, 0xca, 0xc0, 0x15, 0xe4, 0xd5, 0x16, 0x59, 0x40, 0xf9, 0x3b,
-       0xe5, 0xdf, 0xd9, 0x72, 0x96, 0x91, 0x37, 0x5a, 0xd0, 0x36, 0x2e, 0x17,
-       0x4b, 0xb4, 0x2b, 0x35, 0x4f, 0xf4, 0x7f, 0x4b, 0x7a, 0xb2, 0xdf, 0x82,
-       0x9d, 0x7a, 0x01, 0xd7, 0xd3, 0x92, 0xde, 0x3f, 0xea, 0xf4, 0xa4, 0x3a,
-       0x1d, 0xe8, 0x4e, 0x5c, 0xae, 0xd3, 0xe3, 0x35, 0x3a, 0x57, 0xd9, 0x3e,
-       0x1a, 0xe4, 0xe9, 0x83, 0x2a, 0xd9, 0x82, 0x35, 0xd9, 0xed, 0x74, 0xd9,
-       0x32, 0x3e, 0xeb, 0x9c, 0x3c, 0xe9, 0x3c, 0xab, 0x76, 0x6c, 0x10, 0xe9,
-       0x68, 0x81, 0xcd, 0x33, 0x26, 0xaa, 0xad, 0x45, 0x5c, 0xe9, 0x9c, 0x51,
-       0xed, 0x28, 0xf3, 0x6d, 0x59, 0xa2, 0x05, 0xfa, 0x01, 0x65, 0xdb, 0x50,
-       0xb6, 0xcb, 0x96, 0xb5, 0xb6, 0x48, 0x23, 0xca, 0xce, 0x68, 0x9e, 0xbf,
-       0xd4, 0xe5, 0x7b, 0x79, 0xa7, 0x59, 0x3a, 0x4e, 0xb5, 0x40, 0x36, 0x6c,
-       0x92, 0x85, 0x6b, 0x9a, 0xa4, 0x03, 0xef, 0x18, 0xe7, 0x0e, 0x4e, 0xc5,
-       0xe5, 0xba, 0x53, 0x9d, 0xc9, 0x0f, 0x61, 0x0e, 0x9d, 0x67, 0x19, 0xf7,
-       0x7e, 0xf2, 0x0a, 0xc6, 0x7d, 0x3a, 0xce, 0xf2, 0xde, 0xa4, 0xe5, 0x0f,
-       0xf1, 0x61, 0xbe, 0x71, 0x44, 0x99, 0x7c, 0x1a, 0x7e, 0x2e, 0x75, 0x78,
-       0xa7, 0xfd, 0x1e, 0xc7, 0x9f, 0x5e, 0x41, 0xbf, 0x6d, 0x86, 0xf6, 0x54,
-       0x99, 0xfc, 0x48, 0x3d, 0x84, 0xfb, 0xb4, 0x23, 0xc5, 0x9a, 0xcc, 0x9a,
-       0x23, 0x5f, 0x9d, 0x54, 0xcc, 0x65, 0x41, 0x59, 0xf5, 0x67, 0x42, 0xb3,
-       0xc6, 0xe4, 0x05, 0x23, 0x97, 0xde, 0x67, 0xe4, 0xd2, 0x99, 0xf3, 0xcb,
-       0xe4, 0xd2, 0x25, 0x2d, 0x97, 0x0e, 0x0a, 0xee, 0x73, 0x97, 0x20, 0x97,
-       0x5e, 0xc0, 0xb3, 0xa7, 0xe5, 0x52, 0x42, 0xac, 0xbd, 0x2c, 0x3f, 0xd0,
-       0xe3, 0xcf, 0x96, 0x5d, 0x6d, 0x57, 0x15, 0xa7, 0x61, 0x93, 0x94, 0x27,
-       0xac, 0xfe, 0x96, 0x4c, 0xab, 0x74, 0xf5, 0xff, 0x50, 0x22, 0x9b, 0xf3,
-       0xcf, 0xae, 0xe0, 0xf7, 0x46, 0x9f, 0x53, 0x94, 0x61, 0xaf, 0x42, 0x86,
-       0x89, 0x5a, 0x5b, 0x86, 0xe1, 0x5d, 0x05, 0xef, 0x2a, 0xec, 0xf7, 0x6f,
-       0x7f, 0x38, 0xe2, 0x51, 0x7e, 0x50, 0x66, 0x40, 0x26, 0x95, 0x21, 0x93,
-       0xca, 0x90, 0x53, 0x65, 0xc8, 0x25, 0xd8, 0x6c, 0xe7, 0xcb, 0x90, 0x4b,
-       0x65, 0xc8, 0x25, 0xc8, 0xb8, 0xc7, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x86,
-       0x4c, 0x3b, 0x23, 0xf7, 0x59, 0x5d, 0x6f, 0x62, 0x25, 0xbd, 0xd6, 0x47,
-       0xea, 0xd3, 0x31, 0xe4, 0xf3, 0x75, 0xb1, 0xc1, 0x03, 0xc7, 0x35, 0xbf,
-       0x7b, 0xbe, 0xba, 0xca, 0x61, 0x0e, 0xcd, 0xf7, 0xb5, 0xff, 0xbe, 0x9b,
-       0xbf, 0xa5, 0x09, 0x7c, 0xfd, 0x1d, 0xcb, 0xd7, 0xbb, 0x97, 0xf8, 0x3a,
-       0xed, 0x30, 0x56, 0xbc, 0x36, 0x5f, 0x6f, 0xb3, 0xef, 0x0a, 0xe1, 0x3a,
-       0xf0, 0xf5, 0xba, 0x15, 0x7c, 0x1d, 0x07, 0x5f, 0xef, 0x5f, 0xc5, 0xd7,
-       0x1b, 0x9c, 0x01, 0xdd, 0x86, 0x67, 0x24, 0xf8, 0xdc, 0xe8, 0xd4, 0xf8,
-       0xfa, 0x1e, 0xcd, 0xd7, 0x47, 0xc1, 0xd7, 0xd7, 0xd7, 0xf1, 0xf5, 0x7e,
-       0x49, 0xdf, 0x9c, 0x8b, 0xed, 0x94, 0xd1, 0xfb, 0x55, 0xdb, 0x66, 0xf9,
-       0x17, 0x31, 0xed, 0x0d, 0x8f, 0x0d, 0x4c, 0xb5, 0x49, 0xfe, 0xa1, 0x57,
-       0x50, 0x46, 0x3e, 0x4b, 0x8f, 0x64, 0x1d, 0x4f, 0x8e, 0x1c, 0xff, 0xbe,
-       0xcc, 0x6b, 0xde, 0x12, 0x19, 0x3b, 0x1e, 0x97, 0xf1, 0xe3, 0x8c, 0x43,
-       0x7c, 0xcf, 0xd2, 0x7b, 0x93, 0x8c, 0x1f, 0x64, 0xde, 0x9c, 0x2b, 0xa3,
-       0xc7, 0xe1, 0x6f, 0x1d, 0x67, 0x1c, 0xe2, 0xa5, 0x25, 0x1e, 0x9b, 0x87,
-       0x6c, 0x19, 0x3d, 0xce, 0xb5, 0x8e, 0xa3, 0x9f, 0x16, 0x39, 0x7a, 0x5c,
-       0xe4, 0xb6, 0xe3, 0xae, 0x7c, 0xe0, 0xf8, 0x12, 0xaf, 0x0d, 0x47, 0xbc,
-       0xf6, 0x0c, 0x78, 0xad, 0xd3, 0xf2, 0x9a, 0x5a, 0xe2, 0xb5, 0xaf, 0xd6,
-       0xf1, 0x1a, 0xdb, 0x93, 0xd7, 0x9e, 0xb5, 0x65, 0x7c, 0x76, 0xe5, 0xd0,
-       0xf1, 0x76, 0x19, 0x7d, 0xe8, 0x2d, 0x32, 0x76, 0x3f, 0x61, 0x35, 0xdf,
-       0x85, 0xa2, 0x2d, 0x36, 0x5d, 0xed, 0x44, 0xff, 0x51, 0x0e, 0x11, 0x71,
-       0xed, 0x77, 0xcf, 0x48, 0xba, 0xc0, 0xf1, 0x1a, 0xe1, 0x47, 0x9f, 0x82,
-       0x7f, 0x71, 0x08, 0x30, 0xdd, 0x72, 0x5c, 0xd2, 0xae, 0xbc, 0x2c, 0x13,
-       0xc1, 0xe9, 0xed, 0xc6, 0x9e, 0x80, 0x2d, 0xa2, 0x6d, 0x9f, 0xac, 0xe4,
-       0xdf, 0x1e, 0x6a, 0x1f, 0x63, 0xb2, 0x22, 0x8c, 0x05, 0x30, 0x6e, 0x6e,
-       0xbf, 0x85, 0xca, 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0xfb,
-       0xf8, 0x9e, 0xcf, 0xb0, 0x67, 0xf4, 0xd9, 0x45, 0xb6, 0x67, 0x3f, 0x09,
-       0x1d, 0x53, 0x2f, 0x56, 0xf8, 0x4d, 0x1c, 0xf8, 0x9f, 0x15, 0x7e, 0x5b,
-       0xeb, 0x37, 0xdb, 0x4c, 0x7c, 0x96, 0x7c, 0xf7, 0x5d, 0x27, 0x5f, 0x9a,
-       0xd3, 0xdf, 0x38, 0xc8, 0xf9, 0xf8, 0x5d, 0xe1, 0x33, 0xeb, 0xcf, 0x31,
-       0xde, 0x91, 0x4a, 0xa9, 0x63, 0xdb, 0x99, 0x7b, 0x70, 0x70, 0x8e, 0x75,
-       0x77, 0x5a, 0x1e, 0xdd, 0xa9, 0xfd, 0x0e, 0xda, 0x58, 0xa3, 0x93, 0x2f,
-       0x48, 0x91, 0xb6, 0xc9, 0xf0, 0x4e, 0xa7, 0x30, 0xfd, 0x73, 0xdb, 0x8d,
-       0xfd, 0x3c, 0xb0, 0x95, 0x79, 0x87, 0x59, 0xb5, 0x5a, 0x26, 0x9f, 0x92,
-       0x48, 0x26, 0xa7, 0x6f, 0xce, 0xc2, 0xce, 0xce, 0x1f, 0xd7, 0xdf, 0xab,
-       0x4a, 0x75, 0x2a, 0xce, 0xe9, 0x4e, 0xc8, 0xd7, 0x88, 0x16, 0x92, 0xf2,
-       0xd1, 0xe3, 0xa4, 0x07, 0x95, 0xd8, 0x28, 0x1f, 0xb1, 0xf4, 0x70, 0x46,
-       0x4a, 0x90, 0x3b, 0xc7, 0x8f, 0x7f, 0x40, 0xa6, 0x0f, 0xac, 0xa4, 0x87,
-       0xb1, 0x1a, 0x3d, 0x24, 0x60, 0x9f, 0x39, 0xf5, 0xf4, 0xf0, 0xf3, 0x4b,
-       0xf4, 0x30, 0xed, 0xfc, 0x6b, 0xe9, 0xe1, 0x86, 0x65, 0xf4, 0x30, 0xa1,
-       0xe9, 0x61, 0x68, 0x89, 0x1e, 0x26, 0x8e, 0x73, 0x5c, 0xbd, 0x37, 0xea,
-       0x2d, 0x38, 0x5c, 0xf3, 0x25, 0x5a, 0x48, 0x8d, 0xeb, 0x7c, 0xfd, 0x74,
-       0x81, 0xe7, 0x9b, 0x36, 0x28, 0xc6, 0x49, 0x6a, 0xeb, 0xbf, 0xf1, 0xdf,
-       0x74, 0xfd, 0xaf, 0xda, 0xfa, 0xff, 0x77, 0xfd, 0x33, 0x5b, 0x99, 0xbb,
-       0xcf, 0x33, 0xb0, 0x46, 0x1e, 0x47, 0xf4, 0x90, 0xdb, 0x6a, 0xf4, 0x02,
-       0xd7, 0x98, 0xcf, 0x90, 0x67, 0x90, 0x7f, 0xe7, 0x21, 0xff, 0x9e, 0x80,
-       0xfc, 0x7b, 0x7c, 0xd9, 0x9e, 0x40, 0xbf, 0x8d, 0x47, 0x84, 0x72, 0x24,
-       0xa8, 0xe1, 0x63, 0xa1, 0x8f, 0xf8, 0x30, 0xf9, 0x27, 0xcc, 0xfd, 0x5d,
-       0x8e, 0x13, 0x57, 0xe7, 0x1c, 0x3d, 0x1a, 0xd4, 0xe3, 0x84, 0x70, 0xbf,
-       0x5c, 0x37, 0x47, 0xfc, 0xae, 0xf0, 0xf9, 0x8c, 0xce, 0x23, 0x29, 0xea,
-       0x3d, 0x28, 0xe2, 0x85, 0x7b, 0x50, 0xc4, 0x89, 0xab, 0xed, 0xfd, 0x62,
-       0xa5, 0x49, 0xe7, 0xd0, 0x1f, 0x9e, 0x4b, 0xc8, 0x42, 0x82, 0x31, 0x3e,
-       0x7e, 0xe7, 0x90, 0x7e, 0xb3, 0x9f, 0x2c, 0x4a, 0x81, 0xb9, 0x72, 0xe0,
-       0xe9, 0x0d, 0x96, 0xb6, 0x19, 0x1b, 0xe4, 0x19, 0xe0, 0x68, 0x2f, 0xa2,
-       0xdb, 0xca, 0xba, 0x96, 0xba, 0x98, 0x25, 0xf0, 0x3e, 0x25, 0xa9, 0x5c,
-       0x1f, 0xee, 0x73, 0x1c, 0xfb, 0x13, 0x32, 0xf1, 0xe0, 0x87, 0x61, 0xcb,
-       0xbd, 0x1f, 0x3a, 0x87, 0xe7, 0xcf, 0xb8, 0xf7, 0xe0, 0x69, 0x18, 0x66,
-       0xf4, 0x77, 0xac, 0xe8, 0x03, 0x92, 0x1e, 0x92, 0x78, 0x3e, 0x63, 0xe3,
-       0x4a, 0x49, 0x29, 0x96, 0x5e, 0x94, 0x7c, 0x85, 0xdf, 0x5c, 0x7b, 0x09,
-       0xf7, 0xd7, 0x5b, 0x0f, 0xe3, 0x87, 0x0c, 0xeb, 0x3b, 0xd7, 0x66, 0x51,
-       0xb2, 0x15, 0x93, 0xe3, 0x52, 0x8b, 0x9b, 0x9c, 0x91, 0x63, 0xda, 0x7e,
-       0xce, 0xd8, 0xdc, 0x96, 0xf4, 0x70, 0x41, 0x8c, 0x0d, 0xfd, 0x39, 0xd8,
-       0xd0, 0x9f, 0xad, 0x66, 0xf5, 0x3e, 0xd6, 0xe3, 0xb0, 0xa1, 0x1f, 0x83,
-       0xee, 0xa1, 0xce, 0x49, 0x58, 0x9d, 0x33, 0xa1, 0x0e, 0x68, 0x9d, 0xf3,
-       0xe7, 0x5a, 0xe7, 0xbc, 0x7b, 0x95, 0xce, 0x39, 0xaa, 0x3a, 0x27, 0xa9,
-       0x73, 0x06, 0xd4, 0x7e, 0x87, 0xf6, 0xe2, 0x96, 0x35, 0x74, 0xce, 0x7b,
-       0xe4, 0x1d, 0xf6, 0xdd, 0x3d, 0xf2, 0xde, 0x3d, 0x7a, 0xef, 0xc6, 0x9b,
-       0x51, 0xfc, 0x76, 0x93, 0xd1, 0x41, 0xd7, 0xab, 0x6e, 0xbd, 0xe7, 0xfb,
-       0x95, 0x3a, 0x9d, 0xd3, 0xa1, 0xfa, 0x9c, 0x01, 0xdd, 0x86, 0xb1, 0x09,
-       0x3e, 0x07, 0x4e, 0x76, 0xb8, 0x09, 0xcf, 0x49, 0x89, 0x1d, 0xc7, 0xdc,
-       0xcd, 0xf7, 0xa5, 0x94, 0x79, 0xf7, 0x56, 0xfb, 0x4e, 0x45, 0xe5, 0xae,
-       0x29, 0xef, 0xb4, 0xe5, 0x46, 0x57, 0x75, 0xa8, 0x76, 0xad, 0xab, 0x76,
-       0x83, 0xa1, 0x66, 0xa0, 0x5f, 0x67, 0xca, 0x91, 0xce, 0xe2, 0x6f, 0xc6,
-       0x9e, 0x19, 0xa3, 0x88, 0x62, 0xd8, 0x29, 0xd4, 0xc1, 0x55, 0x8e, 0x6c,
-       0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x0e, 0x78, 0xbd, 0x19, 0xfc, 0xf3,
-       0x1f, 0x4a, 0x8c, 0x81, 0xb6, 0xc9, 0x89, 0xa9, 0xfa, 0x77, 0xed, 0xf2,
-       0xae, 0xa9, 0x1d, 0x72, 0xfb, 0xe4, 0xd6, 0xa4, 0x34, 0xef, 0x94, 0x89,
-       0xc9, 0x29, 0x7d, 0xfe, 0x7d, 0xb3, 0xfe, 0x2e, 0x08, 0xbf, 0x97, 0x63,
-       0x64, 0xe4, 0x90, 0x63, 0x64, 0x64, 0x56, 0xd5, 0x6c, 0xd6, 0xa8, 0x4f,
-       0x7e, 0x8b, 0x64, 0x70, 0x32, 0xa9, 0xbf, 0xa5, 0x3a, 0x53, 0xbd, 0x4a,
-       0x7e, 0xfb, 0xa4, 0xba, 0x4b, 0xd5, 0xce, 0xf7, 0x6a, 0x9b, 0x75, 0x76,
-       0x99, 0xcd, 0xfa, 0xbf, 0x64, 0xe1, 0xbd, 0x71, 0xcc, 0x13, 0x34, 0x7c,
-       0xf5, 0xb7, 0xb8, 0x17, 0xda, 0x96, 0x90, 0x17, 0x65, 0x50, 0xe3, 0x8f,
-       0xf2, 0xb4, 0x05, 0x72, 0x70, 0x51, 0xeb, 0xd7, 0x2d, 0xa0, 0x41, 0xca,
-       0xd2, 0x0f, 0xca, 0x0b, 0x5a, 0x9e, 0x6d, 0xb1, 0xb6, 0xeb, 0x3c, 0xbf,
-       0x6d, 0x7d, 0x9c, 0xb6, 0xeb, 0x9f, 0xdb, 0x72, 0x96, 0xa5, 0x93, 0x8b,
-       0x42, 0x7d, 0x97, 0x80, 0x0c, 0xa5, 0x3c, 0x7d, 0xa3, 0xb6, 0xeb, 0x97,
-       0x6c, 0x1f, 0x94, 0x9f, 0x46, 0x76, 0xef, 0x76, 0xe6, 0x6d, 0x19, 0x9f,
-       0xa3, 0x78, 0xba, 0x9f, 0xcd, 0x5b, 0x3e, 0x53, 0xce, 0xe7, 0xf1, 0x7e,
-       0x33, 0xde, 0x93, 0xcf, 0x1e, 0xd7, 0x7c, 0xa6, 0xed, 0x13, 0xa7, 0xd7,
-       0xee, 0x2f, 0x2c, 0xed, 0x0d, 0x14, 0xc8, 0x67, 0xea, 0x84, 0x37, 0x6f,
-       0xe4, 0x01, 0xf3, 0x54, 0x7f, 0x03, 0xba, 0x83, 0x6d, 0x51, 0xfe, 0x70,
-       0x96, 0xbe, 0x2d, 0xfc, 0x9f, 0x8d, 0x78, 0x6e, 0xc3, 0xf3, 0x8c, 0xbc,
-       0xfb, 0x60, 0x5c, 0xcf, 0x7b, 0x02, 0xf3, 0x38, 0x7c, 0x1c, 0x73, 0x72,
-       0x8c, 0xed, 0xec, 0x9e, 0x75, 0xa5, 0xe1, 0x2c, 0xf9, 0x8e, 0x67, 0x6d,
-       0xc2, 0xf0, 0x50, 0x2f, 0xe9, 0x36, 0xed, 0x0d, 0xe9, 0xb3, 0xa5, 0xbb,
-       0x93, 0x31, 0xe0, 0xe4, 0x30, 0xd6, 0x63, 0xa2, 0xe4, 0x7b, 0x39, 0xc7,
-       0x4f, 0x62, 0x9e, 0xb0, 0x01, 0x3b, 0x61, 0x0b, 0x76, 0xc2, 0x0e, 0xec,
-       0x84, 0x1d, 0xb8, 0x49, 0x4e, 0x5d, 0xc3, 0x1c, 0x93, 0xc2, 0x75, 0xf0,
-       0xca, 0xe5, 0xaf, 0x75, 0x9c, 0xbe, 0xf1, 0xe6, 0x41, 0xf8, 0xec, 0xe2,
-       0xa5, 0x87, 0x99, 0x87, 0xbf, 0xe8, 0x35, 0xde, 0x3c, 0x24, 0x9d, 0xfd,
-       0x78, 0xdf, 0xff, 0xa2, 0x74, 0xdd, 0x7c, 0xab, 0xd3, 0x38, 0x3c, 0x08,
-       0x3c, 0x66, 0x9d, 0x74, 0x72, 0xc4, 0x99, 0xc7, 0x38, 0xb9, 0xdd, 0x31,
-       0x61, 0xdc, 0x72, 0x9e, 0xb1, 0x88, 0x9b, 0x3b, 0x63, 0x3d, 0xa9, 0x51,
-       0x27, 0x3d, 0xac, 0x62, 0xe9, 0xe1, 0x41, 0x27, 0xaa, 0xc7, 0x6f, 0xae,
-       0x42, 0xce, 0x00, 0xd6, 0xc3, 0xe5, 0x4f, 0x83, 0x9e, 0x8e, 0x48, 0xf1,
-       0x64, 0x8b, 0xcc, 0x95, 0x3a, 0xbd, 0x9c, 0x4a, 0xe8, 0xdc, 0x12, 0x75,
-       0x0a, 0x44, 0x7f, 0x36, 0x2e, 0x33, 0x93, 0x3b, 0x45, 0x69, 0xdb, 0x7d,
-       0x9b, 0xe4, 0xa6, 0x26, 0xe5, 0x62, 0x9f, 0xb4, 0x2a, 0xf4, 0xcf, 0x6f,
-       0xdc, 0xaa, 0x53, 0xdc, 0x4b, 0x8c, 0x78, 0x61, 0x3b, 0xf9, 0x64, 0x12,
-       0x38, 0x04, 0xdd, 0x32, 0xc6, 0xdb, 0x24, 0x94, 0x7b, 0x1f, 0xd0, 0xf1,
-       0x53, 0xc6, 0x6c, 0xeb, 0xf7, 0x1e, 0xc8, 0x1f, 0xf1, 0x35, 0xf9, 0x63,
-       0xb6, 0xcc, 0x7d, 0x1a, 0x29, 0xb8, 0x8c, 0x11, 0xfb, 0xf8, 0x3d, 0xcd,
-       0xba, 0x4d, 0x32, 0xd1, 0x57, 0xb0, 0x79, 0x1e, 0x7f, 0x9e, 0x64, 0x0e,
-       0x31, 0x71, 0x32, 0xda, 0x47, 0x5e, 0x5f, 0xb9, 0xb7, 0x11, 0xaf, 0x93,
-       0x07, 0x8e, 0x2c, 0x4c, 0x46, 0x7b, 0x21, 0xec, 0x0f, 0xcf, 0xd3, 0x46,
-       0xde, 0xe6, 0x56, 0xb5, 0x23, 0x5c, 0xdc, 0xaf, 0x5c, 0x2e, 0x63, 0x95,
-       0x4f, 0x99, 0xea, 0x69, 0xf9, 0x7a, 0xa6, 0x6a, 0x64, 0xeb, 0x74, 0x35,
-       0xd2, 0x2d, 0x71, 0xa3, 0x4b, 0x57, 0xe9, 0x13, 0x13, 0xcd, 0xac, 0xe9,
-       0x13, 0xea, 0x45, 0x25, 0xef, 0x9b, 0xdb, 0x26, 0xee, 0xc3, 0xb2, 0x38,
-       0xe1, 0x7f, 0x7a, 0x3b, 0x73, 0x35, 0x26, 0x82, 0x37, 0xa3, 0x1f, 0x9b,
-       0xae, 0xa4, 0x3e, 0x1c, 0x51, 0x8d, 0xb8, 0x6f, 0xd6, 0xf4, 0x07, 0x9e,
-       0xc2, 0xb3, 0xf1, 0x13, 0x3e, 0x07, 0x3f, 0xe1, 0xb3, 0xd0, 0x75, 0xe7,
-       0xe1, 0x27, 0x3c, 0x01, 0x3f, 0xe1, 0x71, 0xf8, 0x09, 0x8f, 0x41, 0x4f,
-       0xd6, 0xfb, 0x07, 0xe3, 0xcb, 0xfc, 0x83, 0x50, 0xf3, 0x3f, 0xe3, 0x81,
-       0x4f, 0xd4, 0xf9, 0x06, 0x87, 0x8c, 0xbe, 0x82, 0xdf, 0x6f, 0xf8, 0xa8,
-       0x43, 0xdd, 0xa4, 0xf5, 0xa3, 0xc9, 0xdb, 0x1d, 0x5e, 0xd2, 0x57, 0x1d,
-       0xca, 0xe8, 0xab, 0x99, 0x9a, 0xbe, 0x32, 0x7c, 0xf4, 0xf0, 0xa4, 0xc4,
-       0xfc, 0xc9, 0xf9, 0x5c, 0xb0, 0x57, 0xf3, 0x50, 0xab, 0xbf, 0x53, 0x62,
-       0x0f, 0xa8, 0xb6, 0x06, 0xc9, 0xd9, 0x67, 0xd0, 0xd7, 0x89, 0x4f, 0xa3,
-       0xaf, 0xeb, 0x24, 0xaf, 0xed, 0xb3, 0xcb, 0xe3, 0xfb, 0xb1, 0x15, 0xf8,
-       0x2e, 0x96, 0x27, 0x34, 0xce, 0xef, 0xaf, 0x70, 0x9f, 0xa5, 0x45, 0xc6,
-       0x2b, 0x11, 0xce, 0x79, 0x9e, 0x95, 0xb9, 0x18, 0xed, 0x12, 0x7b, 0x78,
-       0x1b, 0xcf, 0x59, 0xa9, 0x7c, 0xb0, 0x5e, 0xe7, 0xb0, 0x9c, 0xea, 0x93,
-       0x64, 0xbe, 0x8f, 0xb4, 0x7a, 0x9f, 0xcc, 0xe8, 0xb5, 0xd8, 0x26, 0x0d,
-       0x0f, 0xd3, 0x46, 0x89, 0xf6, 0xf3, 0xde, 0x7f, 0xa5, 0xfd, 0xe6, 0x6a,
-       0xdc, 0xd4, 0x13, 0x39, 0xa2, 0xd7, 0x6b, 0x5a, 0xe7, 0x19, 0xde, 0x34,
-       0xc7, 0xb8, 0x3c, 0xbf, 0x6f, 0xc5, 0x98, 0xfc, 0xbf, 0x66, 0xfd, 0x7e,
-       0xf9, 0x4a, 0x63, 0xcf, 0x6c, 0xb6, 0x76, 0x8c, 0x89, 0x53, 0xad, 0x6d,
-       0xc3, 0xb0, 0x9f, 0xfa, 0x6f, 0x32, 0xee, 0x70, 0xc6, 0x27, 0x77, 0x3a,
-       0xc5, 0x49, 0xee, 0x65, 0xdb, 0xbf, 0xd1, 0xe1, 0xed, 0x77, 0x0e, 0xfb,
-       0x3b, 0x50, 0xc6, 0x98, 0x25, 0x63, 0x36, 0xf7, 0x5f, 0xc9, 0x18, 0x6d,
-       0xce, 0xe7, 0xd8, 0x2c, 0xdb, 0xe1, 0x4c, 0x4c, 0x76, 0xc2, 0x37, 0xe7,
-       0xb9, 0x2a, 0xbe, 0x1f, 0xe2, 0xda, 0x41, 0x07, 0x7b, 0xfa, 0xcc, 0xee,
-       0x98, 0x5c, 0x65, 0x63, 0xd0, 0xd4, 0xc3, 0x3f, 0xbd, 0x6c, 0xef, 0xf6,
-       0x28, 0xf4, 0xd8, 0x2d, 0x90, 0x47, 0xd4, 0xc3, 0x47, 0xe5, 0x6d, 0x96,
-       0x9e, 0x97, 0xeb, 0xe1, 0x4b, 0xc2, 0x38, 0x71, 0x2f, 0xde, 0x15, 0xc2,
-       0x38, 0xe8, 0xe1, 0x58, 0x9d, 0xaf, 0x46, 0xbf, 0xaf, 0x29, 0x63, 0xf6,
-       0xc3, 0x96, 0xfb, 0x7d, 0x90, 0x03, 0x89, 0xc8, 0xcf, 0x6b, 0x5c, 0xda,
-       0xaf, 0xdd, 0x6f, 0xdb, 0x4e, 0x04, 0x7f, 0x44, 0x1c, 0xa5, 0x8e, 0xca,
-       0x2f, 0x42, 0xa7, 0x31, 0x07, 0xe4, 0x2f, 0x34, 0xce, 0x44, 0x91, 0xf6,
-       0x36, 0x6b, 0x18, 0xad, 0x9c, 0x4f, 0x45, 0x39, 0x1c, 0x45, 0xdb, 0x76,
-       0xcc, 0xee, 0xc9, 0x17, 0xe5, 0xeb, 0x8c, 0x73, 0xa6, 0x06, 0x63, 0xeb,
-       0xf9, 0x3d, 0x46, 0xb4, 0xfd, 0x45, 0xed, 0xb7, 0x67, 0x25, 0xea, 0x8b,
-       0xcf, 0x0d, 0x75, 0x7d, 0xd3, 0x8e, 0xe2, 0x7d, 0xe5, 0x39, 0xb2, 0xa7,
-       0xf5, 0x3e, 0xa3, 0xf9, 0x5e, 0x42, 0xc4, 0x27, 0xe4, 0x9d, 0x94, 0x3e,
-       0xeb, 0xe4, 0x3f, 0x4c, 0xbb, 0x87, 0x7b, 0xb0, 0xde, 0xfc, 0x78, 0xf0,
-       0x11, 0xfd, 0xcd, 0xc0, 0x69, 0x11, 0xa7, 0x18, 0xdc, 0xa6, 0x73, 0x4f,
-       0x8a, 0x3a, 0xd6, 0x5c, 0xc0, 0xbd, 0xe6, 0xa3, 0x76, 0x3c, 0xcc, 0xbf,
-       0xc3, 0xc1, 0xb2, 0x3c, 0x60, 0xa3, 0x0e, 0xa1, 0xec, 0x4d, 0x48, 0xc7,
-       0x89, 0x5f, 0xd0, 0xbc, 0xb0, 0x05, 0xbe, 0xc0, 0xc0, 0x09, 0xe8, 0xea,
-       0x13, 0x49, 0x19, 0x3a, 0xa1, 0x75, 0x63, 0x76, 0x75, 0xac, 0xa0, 0xc7,
-       0x73, 0x9d, 0x77, 0xe9, 0x73, 0x6c, 0x6f, 0x3d, 0x11, 0x93, 0x63, 0x89,
-       0x1e, 0xaf, 0xcb, 0x79, 0xb7, 0xd5, 0x85, 0x51, 0x0c, 0xbb, 0x05, 0xed,
-       0x5f, 0x2f, 0x8e, 0x1d, 0xc5, 0xaf, 0x63, 0x32, 0x7d, 0xb0, 0x1d, 0xb0,
-       0x75, 0x6e, 0x33, 0x67, 0x90, 0xb1, 0x56, 0xfa, 0x1b, 0xf7, 0x6e, 0x92,
-       0xb2, 0xac, 0x03, 0xb0, 0x0c, 0x9e, 0xa0, 0x3e, 0xf3, 0x35, 0x8f, 0x03,
-       0x06, 0xaf, 0x41, 0xfb, 0x21, 0xe4, 0xcb, 0xb7, 0x88, 0xff, 0x00, 0x64,
-       0xdc, 0x89, 0xb8, 0x74, 0x9d, 0x68, 0x91, 0x5d, 0x27, 0xe8, 0x87, 0xd4,
-       0xfb, 0xa5, 0xb4, 0x4b, 0xe7, 0x30, 0xc7, 0x77, 0x6a, 0x39, 0xc9, 0x3d,
-       0xcd, 0xdb, 0xc9, 0xbb, 0xa8, 0x9b, 0x87, 0xcd, 0x9c, 0x3b, 0xe1, 0xe9,
-       0x3d, 0xd2, 0x1c, 0xe6, 0x9c, 0xaf, 0x78, 0x18, 0xc7, 0xc8, 0x9c, 0x22,
-       0xfd, 0x94, 0xe1, 0x6d, 0xc0, 0xf1, 0x31, 0xcb, 0x3b, 0x43, 0xdb, 0x2c,
-       0x8f, 0xfe, 0x88, 0xbc, 0x77, 0xf3, 0x36, 0x23, 0x3b, 0x7f, 0x76, 0x1b,
-       0x73, 0x93, 0xb6, 0xf8, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7,
-       0xe2, 0x45, 0x01, 0x8e, 0xa2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0xbc, 0x18,
-       0xe8, 0xf3, 0x2b, 0xc1, 0x02, 0xf3, 0x08, 0xf5, 0x77, 0x14, 0x6a, 0xdf,
-       0x5b, 0xd9, 0x5b, 0x65, 0x9c, 0xfc, 0x89, 0xe8, 0x6f, 0xa9, 0xd4, 0xe5,
-       0x1d, 0xd6, 0xef, 0x81, 0x31, 0xd6, 0xb4, 0x94, 0x1b, 0x14, 0x4e, 0xea,
-       0xef, 0x21, 0x3d, 0xeb, 0x5c, 0x2a, 0x5d, 0x70, 0xbe, 0x39, 0x25, 0xa1,
-       0xeb, 0x7f, 0xdf, 0xf9, 0xb6, 0xcf, 0x3d, 0xf3, 0x2f, 0x3b, 0xdf, 0x2a,
-       0xf9, 0xe0, 0xc3, 0x0b, 0x98, 0xc7, 0x2b, 0xce, 0x77, 0xb0, 0xbe, 0x47,
-       0xca, 0xd9, 0xb4, 0x67, 0x63, 0xe2, 0x17, 0x4a, 0xaf, 0x38, 0x5f, 0xaa,
-       0xc5, 0x93, 0xfa, 0x23, 0x1a, 0x39, 0xca, 0x77, 0x15, 0xbc, 0xab, 0xe8,
-       0xfd, 0x1f, 0x67, 0x76, 0xca, 0xe6, 0x97, 0x68, 0x3e, 0x9e, 0x5f, 0xda,
-       0x97, 0x19, 0xd6, 0x7b, 0x15, 0xcf, 0x38, 0xb3, 0x73, 0x9f, 0xdb, 0x66,
-       0xf2, 0x8c, 0x2e, 0xe0, 0x9d, 0xc9, 0xb9, 0x9c, 0x99, 0xbb, 0x80, 0x3a,
-       0x4f, 0x3b, 0x33, 0x3a, 0xfe, 0xc5, 0x76, 0x17, 0x9c, 0xe9, 0xb9, 0xa7,
-       0x9d, 0x39, 0xbd, 0x07, 0x7d, 0xd1, 0x79, 0x74, 0x8a, 0x7d, 0x5f, 0x44,
-       0x9d, 0x79, 0xe7, 0x14, 0xfa, 0x9b, 0x9b, 0xe2, 0x79, 0xdc, 0x4e, 0xd8,
-       0x05, 0xfc, 0x1b, 0x45, 0xfc, 0x1e, 0xc7, 0x33, 0xce, 0xdc, 0x52, 0xbf,
-       0x0b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x19, 0xf4, 0xbf, 0x7a,
-       0xaf, 0x6a, 0x35, 0x4e, 0x9e, 0x07, 0x4e, 0x5e, 0xb4, 0x38, 0x79, 0xd5,
-       0xe2, 0xe4, 0xb9, 0x3a, 0x9c, 0x88, 0x5a, 0x8e, 0x93, 0x57, 0x81, 0x13,
-       0x51, 0x6b, 0xe3, 0x04, 0xef, 0x2a, 0x78, 0xa7, 0x71, 0xf2, 0xd2, 0x0a,
-       0x9c, 0x2c, 0x2e, 0xc5, 0xe5, 0x0d, 0x4e, 0x5e, 0x00, 0x4e, 0x7e, 0x60,
-       0x61, 0x7f, 0xd1, 0xe2, 0x04, 0xf7, 0xb9, 0x17, 0x51, 0xe7, 0xa5, 0x3a,
-       0x9c, 0xbc, 0x08, 0x9c, 0xbc, 0x64, 0x71, 0xf2, 0x6d, 0x8b, 0x93, 0x6f,
-       0xa3, 0xce, 0x22, 0x70, 0x72, 0x69, 0x0d, 0x9c, 0xbc, 0x00, 0x9c, 0x44,
-       0xfd, 0x5e, 0x42, 0x3f, 0xdf, 0xae, 0xc3, 0xc9, 0x0b, 0x6b, 0xe0, 0x84,
-       0x7b, 0xb1, 0x51, 0x4e, 0xf7, 0x99, 0xd7, 0xc9, 0xe9, 0x5e, 0x7c, 0x03,
-       0x39, 0xdd, 0xac, 0x73, 0x46, 0x6a, 0x7f, 0xbb, 0x62, 0xc2, 0xe6, 0xa8,
-       0x99, 0x5c, 0xc0, 0xda, 0x37, 0x9b, 0x3a, 0xc1, 0xe7, 0xc5, 0x02, 0xbc,
-       0x11, 0x9d, 0x53, 0xea, 0xee, 0x19, 0x03, 0xaf, 0xbd, 0x5b, 0x0e, 0x9f,
-       0x6c, 0x3c, 0x96, 0xb7, 0x65, 0xfe, 0x9e, 0xce, 0x82, 0x52, 0x7c, 0x17,
-       0xe5, 0x24, 0xd0, 0x2f, 0x69, 0xe0, 0xb7, 0x0a, 0xbb, 0xb3, 0x52, 0xbf,
-       0x27, 0x3d, 0xc5, 0x6f, 0x34, 0x71, 0x7f, 0x8c, 0x7f, 0x67, 0x23, 0xc5,
-       0x3c, 0xab, 0xa2, 0x86, 0x37, 0x0d, 0xfd, 0xd1, 0xaf, 0x73, 0xab, 0xf8,
-       0x37, 0x82, 0x62, 0xf0, 0xfb, 0x47, 0xfb, 0x68, 0x2b, 0x67, 0xec, 0x99,
-       0xb0, 0x40, 0x9f, 0x53, 0xa9, 0xf1, 0x4f, 0xfd, 0x79, 0x68, 0xf2, 0x5d,
-       0x8d, 0x6e, 0x8e, 0x2c, 0x7d, 0x77, 0xf0, 0xb4, 0x3c, 0xa5, 0x63, 0xc5,
-       0xcd, 0xfa, 0xef, 0x2b, 0x9c, 0x09, 0x4c, 0x8c, 0x76, 0x41, 0xc7, 0x68,
-       0x05, 0xde, 0xf8, 0xb8, 0x8d, 0xd3, 0x76, 0xf5, 0xbf, 0xb4, 0x14, 0xa3,
-       0xad, 0xcf, 0x67, 0x31, 0xfb, 0xeb, 0xb9, 0xc9, 0x39, 0x9d, 0xa3, 0x33,
-       0xc8, 0xef, 0x6f, 0x40, 0x46, 0x8c, 0x4d, 0x57, 0x64, 0xfc, 0x41, 0x3e,
-       0x53, 0xbf, 0xc5, 0xa0, 0xc3, 0x28, 0xc3, 0x0b, 0x92, 0xeb, 0x67, 0x99,
-       0x69, 0x33, 0xa8, 0xfd, 0xe5, 0xd3, 0x32, 0xb0, 0x34, 0x3e, 0xf1, 0xfb,
-       0x89, 0xba, 0xef, 0x60, 0xd3, 0xe6, 0xc9, 0x3a, 0xb9, 0x2a, 0xdf, 0x47,
-       0x7b, 0xe4, 0x9f, 0xb0, 0xdf, 0x0a, 0xe4, 0xfb, 0xfa, 0x6f, 0xbf, 0x6a,
-       0xd1, 0x81, 0xdf, 0xfc, 0xbe, 0xda, 0x84, 0x33, 0x88, 0x36, 0xf3, 0x5e,
-       0xcb, 0xb0, 0xca, 0xdc, 0x38, 0xcc, 0x73, 0x73, 0x33, 0xab, 0xbe, 0x9d,
-       0x5d, 0xd3, 0x8b, 0x45, 0xbd, 0xa6, 0xcc, 0xcf, 0x2a, 0x80, 0x16, 0x35,
-       0x6d, 0x69, 0xfa, 0x3f, 0xbc, 0xa4, 0x2f, 0xa9, 0x67, 0xcd, 0xb7, 0x67,
-       0x8c, 0xbe, 0x4c, 0x27, 0x07, 0x31, 0xbe, 0xfe, 0x1b, 0x0d, 0xf6, 0x5c,
-       0x6f, 0x7e, 0xee, 0x2e, 0xad, 0xeb, 0x27, 0x82, 0x6c, 0xca, 0x95, 0x35,
-       0xea, 0x4e, 0xd6, 0xd5, 0xd5, 0xf3, 0xf6, 0xe4, 0xb7, 0xb0, 0x36, 0xbf,
-       0x51, 0xae, 0xc8, 0xc0, 0xd4, 0x5f, 0xc1, 0x7f, 0x4c, 0xca, 0x6f, 0x96,
-       0x1f, 0x01, 0xbd, 0x16, 0xb6, 0xd8, 0x6f, 0x35, 0xe5, 0x00, 0x37, 0xbf,
-       0xbd, 0xa2, 0xf3, 0x89, 0x63, 0xbf, 0x0d, 0xba, 0xf8, 0xcc, 0x23, 0x1c,
-       0x03, 0xb0, 0xc4, 0x60, 0xdb, 0xc3, 0x4e, 0x98, 0x7e, 0x44, 0xe7, 0xce,
-       0x5d, 0x5f, 0x79, 0x44, 0xc7, 0x2c, 0x86, 0x2a, 0xed, 0xb2, 0xb7, 0xd2,
-       0x22, 0xfb, 0xa0, 0x17, 0xf6, 0x55, 0x7c, 0x5c, 0x71, 0x79, 0x67, 0xc5,
-       0xac, 0xd3, 0x07, 0x2b, 0x5c, 0xef, 0x3d, 0x32, 0x73, 0x72, 0xe5, 0xf7,
-       0x3e, 0xe7, 0x0b, 0xd1, 0xdf, 0x73, 0x52, 0x8a, 0xf9, 0x65, 0xa4, 0x25,
-       0x5c, 0xe5, 0xf4, 0xb1, 0x79, 0x8d, 0x07, 0x66, 0xb8, 0xa6, 0x27, 0x17,
-       0x85, 0x79, 0xfa, 0xfc, 0x1b, 0x4e, 0x7f, 0xb9, 0x9d, 0xe7, 0xa6, 0xf9,
-       0x2d, 0xaf, 0xa1, 0x6a, 0x94, 0x37, 0xbe, 0x56, 0xce, 0x38, 0xec, 0xfc,
-       0x3d, 0x51, 0x8e, 0x5f, 0x9c, 0x39, 0xe3, 0xd2, 0x71, 0xb6, 0x05, 0xf7,
-       0xef, 0x6e, 0xd7, 0x67, 0x9b, 0xcf, 0x8a, 0x2d, 0xd3, 0xf9, 0xe4, 0x78,
-       0x5e, 0xf9, 0xbd, 0xb6, 0x88, 0x1f, 0x6a, 0x7f, 0xf7, 0x40, 0xe4, 0xff,
-       0x02, 0x06, 0x86, 0xe5, 0x0a, 0xd4, 0x6f, 0x00, 0x00, 0x00 };
+       0xad, 0xbc, 0x0f, 0x74, 0x53, 0xd7, 0x95, 0x2e, 0xfe, 0xdd, 0x2b, 0xc9,
+       0x96, 0x6d, 0xd9, 0x96, 0x8d, 0x70, 0xe4, 0xc4, 0x0d, 0x52, 0x7c, 0x05,
+       0x0a, 0x36, 0xe9, 0x95, 0x11, 0x89, 0xd3, 0x77, 0x13, 0x54, 0x70, 0x82,
+       0x49, 0x68, 0xe2, 0x10, 0xa6, 0x75, 0x67, 0x98, 0xa9, 0x1e, 0x21, 0x09,
+       0x49, 0x99, 0x3c, 0xb7, 0xaf, 0xed, 0x23, 0xf9, 0xd1, 0xf1, 0xad, 0xcd,
+       0x1f, 0x03, 0x92, 0x25, 0x1b, 0xf3, 0x27, 0x6f, 0xba, 0x5e, 0x84, 0x31,
+       0x18, 0x12, 0xd9, 0x4e, 0xda, 0x4c, 0x87, 0xbc, 0xd5, 0x79, 0x78, 0x0c,
+       0x24, 0x90, 0x34, 0x7f, 0x9a, 0xb4, 0xab, 0x69, 0xa7, 0x6f, 0xe2, 0x12,
+       0x92, 0x92, 0x7f, 0x94, 0x34, 0x9d, 0x0e, 0x74, 0x86, 0xde, 0xdf, 0xb7,
+       0xaf, 0x24, 0x30, 0x94, 0xa4, 0xed, 0x5a, 0xcf, 0x6b, 0x69, 0x49, 0xf7,
+       0xde, 0x73, 0xf6, 0x39, 0x67, 0x9f, 0xbd, 0xbf, 0xfd, 0xed, 0x73, 0xce,
+       0xf5, 0xa7, 0x80, 0x52, 0xe4, 0xff, 0xca, 0xf9, 0xb9, 0x2e, 0xda, 0x71,
+       0x0f, 0xe6, 0x5d, 0xa7, 0xcb, 0xb5, 0xd3, 0x05, 0x27, 0xfe, 0xc4, 0xbf,
+       0xc0, 0x9f, 0x5a, 0x30, 0xff, 0xe7, 0x00, 0xbc, 0x85, 0x36, 0xe5, 0x03,
+       0xb7, 0x6a, 0xac, 0xfb, 0xe2, 0x02, 0x0d, 0x6e, 0x87, 0x11, 0x5d, 0x7e,
+       0x8f, 0x06, 0xc4, 0xb2, 0x0d, 0x81, 0x85, 0x38, 0x67, 0x99, 0x3e, 0x27,
+       0xe4, 0xfe, 0xa7, 0x8c, 0xff, 0x7c, 0xec, 0x9f, 0x6e, 0x08, 0x9e, 0xce,
+       0x38, 0xe0, 0xf6, 0x1a, 0x5f, 0x83, 0x77, 0x26, 0xdc, 0x75, 0xac, 0xf3,
+       0xed, 0x59, 0xb3, 0x55, 0x54, 0x14, 0x64, 0x05, 0xfd, 0x19, 0x04, 0xbd,
+       0x26, 0x82, 0x61, 0x13, 0x88, 0x3b, 0x0d, 0xc4, 0x8b, 0x0d, 0x37, 0x8a,
+       0xb4, 0x22, 0xc4, 0xbd, 0x6b, 0x02, 0xeb, 0xa2, 0xc0, 0x82, 0x84, 0x3b,
+       0x70, 0x3c, 0x0b, 0xdc, 0x93, 0x70, 0x63, 0xd2, 0xe1, 0x09, 0xbc, 0x99,
+       0xbd, 0xb9, 0x32, 0xa7, 0x83, 0x18, 0x1c, 0x1a, 0xe2, 0xaa, 0x21, 0xf7,
+       0x11, 0x58, 0x98, 0x8d, 0x62, 0x7d, 0xca, 0xb2, 0x9c, 0x1a, 0x9c, 0x83,
+       0x8d, 0x0e, 0xc4, 0xbc, 0x0a, 0x76, 0x6b, 0x51, 0x74, 0x8f, 0x05, 0x39,
+       0x58, 0x29, 0x23, 0xed, 0xfc, 0xe6, 0xdc, 0xc6, 0xd4, 0x49, 0xeb, 0x9f,
+       0x66, 0x79, 0xf1, 0xe4, 0x98, 0x0f, 0x07, 0xc7, 0x82, 0xa6, 0x89, 0x2a,
+       0x9c, 0x48, 0x37, 0xe2, 0xa4, 0x56, 0x87, 0x37, 0x35, 0x0b, 0xeb, 0xf5,
+       0x30, 0x54, 0x2d, 0xa8, 0x43, 0xf1, 0x63, 0xd0, 0x1b, 0x0c, 0xc4, 0xc1,
+       0x4e, 0x54, 0x04, 0xc3, 0xe3, 0xac, 0x9b, 0x4a, 0x21, 0x5e, 0x64, 0x38,
+       0x51, 0xa2, 0xdd, 0x8c, 0x53, 0xdb, 0x0c, 0x7c, 0xb0, 0x0d, 0xcb, 0x2b,
+       0x60, 0x59, 0xd9, 0x48, 0xa8, 0x6d, 0xb5, 0xe2, 0x0d, 0x3c, 0x9f, 0x45,
+       0xe0, 0x58, 0x76, 0xaa, 0xde, 0x38, 0x21, 0xd5, 0x6c, 0x27, 0x15, 0xc5,
+       0x4e, 0xf6, 0xcd, 0x3b, 0x2b, 0x8a, 0xf4, 0x18, 0xdb, 0x4e, 0x49, 0x7f,
+       0xfc, 0xf8, 0xa7, 0x59, 0x7f, 0xcd, 0xf9, 0x64, 0x5b, 0x94, 0xbd, 0x21,
+       0xf5, 0x3a, 0xfb, 0x55, 0x87, 0xef, 0x8e, 0xf9, 0xf1, 0x1d, 0xf6, 0xed,
+       0x29, 0x29, 0x37, 0x16, 0x60, 0x1f, 0xab, 0x70, 0x84, 0xfd, 0xfb, 0x21,
+       0xfb, 0xf7, 0x0a, 0xfb, 0xb7, 0x9b, 0xfd, 0x5b, 0xd1, 0x1c, 0xdc, 0x69,
+       0x42, 0xc1, 0xd2, 0xc6, 0x36, 0xe9, 0x1b, 0xc7, 0xc7, 0x8f, 0xaa, 0x22,
+       0x56, 0x1d, 0x0c, 0x07, 0xd4, 0x60, 0x18, 0x76, 0x9f, 0xa5, 0xfd, 0xdf,
+       0x9c, 0x4b, 0xa6, 0x60, 0xba, 0xa9, 0x57, 0x97, 0x71, 0x33, 0xb2, 0xec,
+       0xf3, 0x13, 0xdb, 0x42, 0xcd, 0xab, 0x54, 0x2c, 0xf1, 0xb0, 0xdf, 0x0f,
+       0x46, 0x42, 0x81, 0xd9, 0xec, 0xf7, 0x50, 0x56, 0x55, 0x55, 0xcd, 0x17,
+       0x18, 0xce, 0x2a, 0x88, 0x2d, 0x55, 0x39, 0x7e, 0xb6, 0x9b, 0x62, 0x5f,
+       0x52, 0xec, 0x4b, 0x8a, 0x7d, 0x49, 0x49, 0x9f, 0xc3, 0xec, 0x6f, 0x4e,
+       0xd7, 0x83, 0xd9, 0xcb, 0xf5, 0x35, 0xd8, 0xc3, 0xb9, 0xa4, 0x3e, 0xa5,
+       0xcf, 0x96, 0xf5, 0xaa, 0xbe, 0x88, 0x7d, 0xb0, 0xac, 0x8f, 0x74, 0xe9,
+       0x9b, 0xf4, 0xab, 0x1c, 0x31, 0x5f, 0x8a, 0x73, 0x56, 0xe8, 0x1b, 0x8c,
+       0x6a, 0xcc, 0x30, 0x5d, 0x86, 0xcc, 0xbb, 0xca, 0xfb, 0x21, 0xfd, 0x23,
+       0xc0, 0x1a, 0x8c, 0x7a, 0x03, 0x1b, 0xb2, 0xbe, 0x40, 0x17, 0x75, 0xd9,
+       0x9d, 0x0d, 0xfa, 0xc5, 0x56, 0xff, 0xb0, 0x2f, 0x41, 0x6f, 0xdc, 0x9e,
+       0x53, 0xe9, 0xd3, 0x64, 0x7e, 0x3e, 0x2d, 0xeb, 0x15, 0xdd, 0xcf, 0xb6,
+       0xa5, 0x3f, 0x51, 0xbb, 0xed, 0x0f, 0x75, 0x44, 0xbd, 0x10, 0xbb, 0x08,
+       0x99, 0x3f, 0xb4, 0xed, 0xcb, 0x1b, 0x48, 0x67, 0x59, 0xe6, 0xbc, 0x1c,
+       0x27, 0xc7, 0x0a, 0xb6, 0x65, 0x59, 0xbb, 0xb5, 0xa0, 0x57, 0xda, 0xca,
+       0x8d, 0x51, 0xec, 0x46, 0xec, 0xc4, 0x1f, 0xf7, 0x18, 0x5e, 0xca, 0x44,
+       0xdb, 0xce, 0x64, 0xa7, 0x55, 0xab, 0x89, 0x2e, 0xb5, 0x35, 0xb5, 0x0e,
+       0x4f, 0xf3, 0xa9, 0x79, 0x5f, 0x31, 0xcb, 0xa3, 0x11, 0x94, 0x6a, 0xf0,
+       0x94, 0x68, 0x68, 0xeb, 0x1d, 0x29, 0x35, 0xcb, 0x8c, 0xef, 0xdf, 0x9d,
+       0x1c, 0x71, 0xa3, 0x74, 0x44, 0x43, 0xc9, 0x48, 0xc8, 0x89, 0x0a, 0x03,
+       0x5b, 0xc6, 0xde, 0x71, 0xe4, 0xc6, 0xbb, 0xb0, 0x30, 0x6e, 0xb1, 0x71,
+       0xf7, 0x5b, 0x89, 0xd3, 0x56, 0x91, 0x56, 0xf2, 0x05, 0x87, 0xa1, 0x05,
+       0xf6, 0x02, 0xa7, 0x57, 0x44, 0xfd, 0xe8, 0xa2, 0xcd, 0xce, 0xd0, 0x7e,
+       0xe2, 0x41, 0x45, 0x2b, 0xcc, 0xb1, 0x1a, 0xf1, 0x07, 0xac, 0x4f, 0x58,
+       0x56, 0x91, 0x71, 0xf7, 0xdd, 0x2c, 0xe7, 0xdd, 0x8b, 0x5a, 0x2c, 0xf4,
+       0x62, 0xed, 0xfa, 0xe8, 0xaf, 0x95, 0x7d, 0x03, 0xcb, 0x61, 0x0e, 0xaf,
+       0xe6, 0x47, 0x05, 0xaa, 0xae, 0xbe, 0xda, 0x71, 0xe3, 0x72, 0x74, 0x0f,
+       0xb3, 0xaf, 0xa9, 0x18, 0xed, 0x53, 0x6c, 0x6b, 0x35, 0x36, 0x0d, 0x3f,
+       0x04, 0x73, 0xf7, 0x4a, 0x96, 0x91, 0x31, 0x75, 0xf1, 0xbb, 0x15, 0x8f,
+       0x8d, 0x89, 0x7c, 0xe9, 0xc6, 0xe5, 0xe4, 0xbf, 0x63, 0x2d, 0xf4, 0x89,
+       0x7c, 0x27, 0x36, 0x26, 0xec, 0x79, 0x51, 0x68, 0x9f, 0xe1, 0x13, 0xb4,
+       0x95, 0x6e, 0xdd, 0x40, 0x4f, 0xaa, 0x19, 0x1b, 0x53, 0xb1, 0x20, 0xd1,
+       0x80, 0xf3, 0xd6, 0x06, 0xd5, 0x08, 0xb5, 0x76, 0x41, 0x7c, 0x02, 0x4a,
+       0xa9, 0x01, 0x67, 0x36, 0x3a, 0xe9, 0x7e, 0x31, 0xa1, 0xb5, 0x3f, 0xae,
+       0xb8, 0x10, 0xaf, 0x92, 0x36, 0x26, 0xdd, 0x2f, 0x27, 0x14, 0xfc, 0x52,
+       0x0b, 0x75, 0xbc, 0xab, 0x4c, 0xba, 0x5f, 0xca, 0x7a, 0x51, 0x9b, 0x0c,
+       0xb6, 0x9b, 0x4a, 0x33, 0x9e, 0xc9, 0xfa, 0xe0, 0x4f, 0x1a, 0x38, 0x90,
+       0xd5, 0xb1, 0xff, 0x22, 0x9f, 0xb9, 0xec, 0x9f, 0xe9, 0x60, 0x5f, 0x57,
+       0x26, 0x02, 0xe8, 0xd2, 0xcf, 0x59, 0x31, 0x2f, 0xe2, 0x95, 0xc6, 0xa4,
+       0xfb, 0x83, 0x24, 0x94, 0x0a, 0x43, 0xf3, 0x8f, 0x2a, 0xbf, 0xb0, 0xe2,
+       0x3e, 0x29, 0xc6, 0xfe, 0x8d, 0xc9, 0x58, 0x97, 0x50, 0xef, 0x06, 0xe7,
+       0xfd, 0xb4, 0x55, 0xc6, 0x39, 0x2b, 0x32, 0xae, 0xc4, 0xf0, 0x80, 0x86,
+       0xfd, 0x1c, 0xeb, 0xfb, 0xfa, 0x78, 0xb3, 0x07, 0x5a, 0xdb, 0x7b, 0x08,
+       0xc6, 0x66, 0x2b, 0x06, 0x8e, 0x66, 0x35, 0x0c, 0x25, 0x0c, 0x1c, 0x4a,
+       0xd4, 0x7b, 0xbb, 0x31, 0x17, 0x31, 0x7f, 0x0e, 0x1f, 0x47, 0xd8, 0xef,
+       0xc1, 0x50, 0x1b, 0x2a, 0x8d, 0x66, 0x4c, 0xb0, 0xdf, 0xa7, 0xe6, 0x89,
+       0x1c, 0x1d, 0x2f, 0xfd, 0x09, 0x7d, 0x15, 0xbd, 0x3e, 0xca, 0xbe, 0x36,
+       0xcf, 0x3d, 0x67, 0x61, 0x9a, 0x1b, 0xc7, 0xf5, 0x2b, 0x88, 0x47, 0x30,
+       0x4b, 0x0c, 0xb7, 0xb3, 0x27, 0xe1, 0xc5, 0xbe, 0xac, 0xc7, 0xd9, 0x9d,
+       0xf0, 0x61, 0x77, 0x36, 0x80, 0x5a, 0x03, 0xa6, 0x9f, 0x72, 0x6b, 0xe9,
+       0x4b, 0xa3, 0x03, 0x75, 0x18, 0x1b, 0x08, 0xea, 0x2f, 0x13, 0x7b, 0xf6,
+       0x0e, 0x5d, 0x89, 0x91, 0x01, 0x05, 0xc3, 0x21, 0xf6, 0x9d, 0xbf, 0x9f,
+       0x18, 0xb8, 0x1a, 0xd9, 0x01, 0x07, 0xb6, 0xd8, 0x7a, 0xb5, 0xfd, 0x30,
+       0xff, 0x7d, 0x25, 0x32, 0x43, 0x70, 0xce, 0x4e, 0x7a, 0xf1, 0x78, 0xd6,
+       0xe9, 0xd4, 0x92, 0x3e, 0x0c, 0x65, 0xbf, 0xce, 0x79, 0x13, 0xd9, 0x01,
+       0x0c, 0x26, 0xfe, 0x9a, 0xbf, 0x65, 0x1c, 0xb7, 0x2b, 0xf9, 0xd8, 0x41,
+       0xcc, 0x0e, 0x10, 0x4f, 0x5b, 0xd0, 0x95, 0x72, 0x60, 0x85, 0x8d, 0xeb,
+       0x29, 0x3e, 0x6b, 0xa1, 0xcd, 0x17, 0xe4, 0x0a, 0xbe, 0x07, 0x88, 0xbd,
+       0x47, 0xe9, 0x03, 0x51, 0xda, 0xbf, 0x8e, 0xff, 0x33, 0xd6, 0x88, 0x7f,
+       0x1c, 0x0b, 0xe3, 0x7b, 0x63, 0x1a, 0xfe, 0x81, 0xb8, 0xf4, 0xf4, 0xd8,
+       0x54, 0xff, 0xbf, 0x9b, 0xe3, 0x13, 0x1f, 0x34, 0xb0, 0x2e, 0x55, 0x84,
+       0x0d, 0x03, 0xa5, 0xe8, 0x1e, 0xa8, 0x0f, 0x1f, 0xa2, 0xdd, 0x7c, 0x4f,
+       0xff, 0x1c, 0xc6, 0xab, 0x29, 0x83, 0xfe, 0xbb, 0x89, 0xf7, 0x37, 0x0f,
+       0xd4, 0x53, 0xef, 0x96, 0xa5, 0x46, 0x1a, 0x9a, 0x27, 0x88, 0x59, 0x93,
+       0xbe, 0x60, 0x60, 0x5c, 0x0d, 0x06, 0x62, 0x70, 0x21, 0xd1, 0xa8, 0xc2,
+       0x9c, 0x1e, 0xcc, 0x98, 0xc4, 0x4d, 0x9f, 0x76, 0xb5, 0x22, 0xd8, 0x66,
+       0xaa, 0x06, 0x6d, 0x8e, 0x78, 0xa7, 0xc6, 0xe8, 0x13, 0xa5, 0xf8, 0x60,
+       0x20, 0xd8, 0x63, 0xaa, 0x77, 0xc1, 0xac, 0xb6, 0xac, 0xef, 0x44, 0xd0,
+       0x71, 0x85, 0x81, 0xd8, 0x74, 0x62, 0xc8, 0xd5, 0xc6, 0x12, 0x10, 0x9f,
+       0x71, 0x2a, 0xa9, 0xf9, 0x7f, 0xa2, 0xdc, 0x8d, 0xaf, 0xb7, 0x05, 0x03,
+       0x01, 0xb5, 0xc1, 0xdc, 0xad, 0x36, 0xd3, 0xd4, 0x11, 0xf0, 0x1b, 0xb7,
+       0x61, 0x8d, 0x3d, 0x56, 0x05, 0x5e, 0x2d, 0x86, 0xee, 0x14, 0x2b, 0xf9,
+       0xea, 0xdb, 0xfb, 0xd4, 0xfa, 0x33, 0xba, 0x1a, 0x3c, 0xda, 0xa6, 0x12,
+       0x2f, 0xe6, 0x9e, 0xb2, 0x02, 0x35, 0x96, 0xd5, 0x34, 0x57, 0xda, 0x0c,
+       0xa0, 0x9a, 0x73, 0x53, 0xc5, 0xb9, 0x69, 0x1a, 0x2d, 0xc5, 0xbb, 0x03,
+       0x30, 0xaf, 0x30, 0x82, 0xad, 0x0f, 0xaa, 0xa5, 0x78, 0x67, 0xa8, 0x14,
+       0x6f, 0x0e, 0x38, 0x71, 0x72, 0xc0, 0xb2, 0xee, 0xd5, 0x2b, 0x51, 0x14,
+       0xc1, 0xf4, 0x22, 0x84, 0x4e, 0x0f, 0xc2, 0xc4, 0xef, 0x59, 0xf6, 0x37,
+       0x03, 0x7e, 0xfc, 0xdb, 0xc0, 0x67, 0xf0, 0x74, 0x75, 0xec, 0xd8, 0x34,
+       0xf8, 0x70, 0x86, 0x73, 0x7e, 0x2a, 0x11, 0x6c, 0xaf, 0x75, 0x04, 0xd7,
+       0x00, 0x0d, 0xab, 0x1e, 0x56, 0x82, 0xf1, 0x97, 0x95, 0x60, 0x20, 0xa9,
+       0xf8, 0xf0, 0x1e, 0x6d, 0xeb, 0x44, 0xb6, 0xbe, 0xf9, 0x35, 0xb6, 0xff,
+       0x5b, 0xfd, 0x7b, 0xd6, 0x78, 0x8d, 0xe8, 0x50, 0xf4, 0x45, 0x9d, 0xa7,
+       0xa8, 0x73, 0xe2, 0xee, 0xf7, 0x52, 0xd4, 0x39, 0xfb, 0xf3, 0xf4, 0x1f,
+       0xe0, 0xa0, 0xcc, 0x57, 0x33, 0x7d, 0xfd, 0x2a, 0xfc, 0x9d, 0x3d, 0xb6,
+       0x63, 0xd6, 0xff, 0xf0, 0xc9, 0xf8, 0x7e, 0x34, 0x3d, 0xe7, 0xe3, 0x32,
+       0xce, 0xa3, 0x56, 0xdc, 0x2b, 0x63, 0x94, 0xb1, 0xda, 0xba, 0x0c, 0x74,
+       0x28, 0xd3, 0x55, 0x94, 0x5a, 0xd6, 0x56, 0x3d, 0xff, 0xdc, 0x57, 0x18,
+       0xeb, 0xbf, 0xd2, 0x0e, 0x64, 0xbc, 0x6b, 0x1d, 0xa2, 0xfb, 0x80, 0xfa,
+       0xaa, 0xf8, 0xbf, 0x19, 0x43, 0xb9, 0x47, 0x62, 0x60, 0xec, 0xfc, 0xf5,
+       0x53, 0x15, 0x17, 0x3f, 0xa7, 0x6d, 0xd9, 0xed, 0xfd, 0x3b, 0xaf, 0x65,
+       0x2c, 0xaf, 0xd0, 0x6e, 0xc4, 0x4e, 0x38, 0x9d, 0x86, 0xd8, 0xcc, 0xa5,
+       0xf6, 0x22, 0xb6, 0xd2, 0x48, 0xbb, 0xfa, 0x17, 0x62, 0x62, 0x07, 0x9e,
+       0xbc, 0xde, 0x2d, 0xd3, 0x1c, 0x70, 0x18, 0x26, 0x3e, 0x1f, 0x75, 0xe0,
+       0xab, 0x51, 0x05, 0xd3, 0xb4, 0x60, 0x06, 0xaa, 0x69, 0x55, 0x91, 0x5b,
+       0x6c, 0xe8, 0x4d, 0x63, 0xc3, 0x18, 0x50, 0xd9, 0x0b, 0x77, 0x85, 0x61,
+       0xe0, 0xa5, 0x24, 0xdc, 0x65, 0xf4, 0xcb, 0x2f, 0x27, 0xeb, 0xc7, 0xdf,
+       0x56, 0x82, 0xb1, 0xd7, 0xa9, 0x4f, 0xea, 0xb5, 0xcd, 0xaf, 0x04, 0x5b,
+       0x57, 0x2b, 0xc1, 0xe6, 0xd9, 0x0a, 0xdc, 0x0a, 0xcb, 0x85, 0xb3, 0x69,
+       0xa4, 0xc6, 0xe4, 0x77, 0x33, 0x66, 0x65, 0xfb, 0xf2, 0x7d, 0x14, 0x3f,
+       0x06, 0x8e, 0xd0, 0xbf, 0x87, 0x9a, 0x15, 0xe2, 0xc9, 0x3b, 0x56, 0xcc,
+       0x47, 0xf9, 0x29, 0xb8, 0x4b, 0x59, 0xe7, 0xb6, 0x64, 0x1a, 0x8c, 0x99,
+       0xee, 0x12, 0xd6, 0xb9, 0x36, 0x09, 0x78, 0x7a, 0x05, 0xf3, 0x83, 0x81,
+       0x6b, 0x94, 0xfa, 0xf6, 0xa4, 0x12, 0x0c, 0xdf, 0xae, 0x34, 0xe8, 0x4f,
+       0x90, 0xb7, 0x6c, 0x40, 0xae, 0x8d, 0x50, 0x36, 0x27, 0xbf, 0x3e, 0x0b,
+       0x65, 0x46, 0x12, 0x9e, 0x5a, 0x6d, 0x26, 0xce, 0x4e, 0xb3, 0xdb, 0x51,
+       0x2a, 0x93, 0x01, 0x3b, 0x96, 0x56, 0x8e, 0x00, 0x2f, 0xf5, 0x5b, 0x38,
+       0x14, 0xa9, 0xa7, 0xbf, 0xb5, 0xc1, 0xcf, 0x32, 0x39, 0x5b, 0xb4, 0xb1,
+       0x42, 0xe9, 0x49, 0xd0, 0xe9, 0xa6, 0xcb, 0xa5, 0x0f, 0xf1, 0xcf, 0x23,
+       0x26, 0xf7, 0x76, 0x26, 0xa0, 0xf4, 0x26, 0x82, 0x3b, 0x01, 0x6d, 0x4d,
+       0x95, 0x23, 0xf6, 0x40, 0x25, 0x3a, 0x31, 0x11, 0x09, 0xc5, 0x07, 0x95,
+       0x50, 0x7b, 0xbf, 0xa2, 0xbb, 0xb7, 0xb0, 0xbd, 0xcd, 0x2c, 0xb3, 0x81,
+       0x9f, 0x45, 0x21, 0xad, 0xf5, 0x43, 0xc4, 0xae, 0x2d, 0x61, 0x99, 0x43,
+       0x7a, 0xe8, 0xcc, 0x6e, 0x84, 0x8e, 0xfe, 0xda, 0xa1, 0xbb, 0x1f, 0xcd,
+       0x8a, 0xac, 0x66, 0x65, 0x68, 0xf4, 0x26, 0x35, 0xe7, 0xfb, 0xff, 0x33,
+       0xaf, 0x83, 0xaf, 0xcb, 0xb5, 0xdd, 0xb6, 0x33, 0x79, 0xb4, 0xf4, 0x0f,
+       0xef, 0x71, 0x92, 0x2e, 0xba, 0xd7, 0xe0, 0x1d, 0xa2, 0xdf, 0x38, 0xb4,
+       0x12, 0xfa, 0xb9, 0xf0, 0x95, 0x58, 0xd8, 0x05, 0xb9, 0xe7, 0x40, 0xc6,
+       0x19, 0xf3, 0x3b, 0xf0, 0x9f, 0x56, 0x6c, 0x99, 0xdc, 0x2b, 0x45, 0xbc,
+       0xad, 0xc1, 0xef, 0x44, 0x43, 0xf3, 0x7a, 0xfa, 0xf0, 0xe4, 0xb2, 0x05,
+       0x7c, 0x16, 0xd2, 0x0f, 0xa1, 0x3e, 0xb0, 0x1e, 0xf2, 0xfb, 0x2c, 0x6d,
+       0x6d, 0x81, 0xd4, 0x65, 0x99, 0x1c, 0x27, 0x13, 0x8c, 0x58, 0xa7, 0x5b,
+       0x78, 0x56, 0x87, 0x59, 0x6c, 0x1c, 0x50, 0x8e, 0x27, 0x7e, 0x6f, 0xc5,
+       0x9c, 0x58, 0x42, 0x7f, 0xd2, 0x35, 0x05, 0x01, 0xb7, 0x11, 0x0a, 0x1c,
+       0x25, 0xfb, 0xa4, 0x6d, 0x28, 0x93, 0xd9, 0x75, 0xca, 0x5b, 0xd9, 0x1e,
+       0xe5, 0x44, 0x56, 0xea, 0x1e, 0x50, 0xde, 0xcc, 0x4a, 0xec, 0xa9, 0x0b,
+       0x1c, 0x61, 0x2c, 0x65, 0x1c, 0x57, 0xbb, 0xc9, 0xda, 0x36, 0xe8, 0x15,
+       0xe4, 0x8e, 0x5a, 0x78, 0x90, 0xfd, 0xdd, 0x13, 0x85, 0xbe, 0x51, 0x77,
+       0x61, 0xd2, 0x0b, 0x4f, 0xb7, 0xee, 0x94, 0x6b, 0xc6, 0x34, 0xa9, 0x5b,
+       0x17, 0x58, 0x9f, 0x3d, 0x47, 0xbf, 0xc8, 0x5d, 0xef, 0x89, 0x16, 0xee,
+       0x7d, 0x64, 0x8d, 0x2f, 0x53, 0x79, 0xfd, 0xa2, 0x8c, 0x9b, 0x75, 0xa7,
+       0x72, 0x45, 0x89, 0xdb, 0x2a, 0xb9, 0x69, 0x15, 0x4c, 0x6f, 0xd0, 0xcc,
+       0x60, 0x09, 0x7d, 0xe7, 0x30, 0xb9, 0xac, 0x9f, 0x71, 0x69, 0x09, 0xb1,
+       0x54, 0x78, 0x98, 0xc2, 0xe7, 0x1e, 0xdc, 0x92, 0xf8, 0x87, 0x3c, 0xc7,
+       0x65, 0x6c, 0xae, 0x71, 0x08, 0x9f, 0xf4, 0xca, 0xdc, 0x1e, 0x4c, 0x4d,
+       0xe5, 0x7e, 0x75, 0x81, 0x93, 0xec, 0x77, 0x89, 0xa6, 0x85, 0x4b, 0x94,
+       0xba, 0xc0, 0x5b, 0xd9, 0x25, 0xf4, 0xcd, 0x77, 0xd9, 0xae, 0x07, 0x6f,
+       0x25, 0x2a, 0xc8, 0x6b, 0x83, 0x31, 0x93, 0x02, 0x6f, 0x25, 0x2f, 0x20,
+       0xbf, 0x98, 0xf2, 0xd7, 0x06, 0xc6, 0x5a, 0x89, 0x87, 0xea, 0xa2, 0x79,
+       0xcd, 0x58, 0x95, 0x85, 0x73, 0x65, 0xd4, 0xc0, 0xbd, 0x8c, 0xa3, 0xf7,
+       0x33, 0x36, 0xad, 0x66, 0xdc, 0xd9, 0x12, 0xe1, 0xd8, 0xaa, 0x2c, 0xab,
+       0x58, 0xeb, 0x14, 0x8e, 0x8c, 0x24, 0xe3, 0xde, 0x3d, 0x9a, 0x13, 0xeb,
+       0xf8, 0xfb, 0xc5, 0xec, 0x7f, 0x58, 0xf7, 0x93, 0xa3, 0x3f, 0x7b, 0x91,
+       0x4c, 0xa8, 0x43, 0x5a, 0x43, 0x78, 0x3d, 0xe3, 0x1e, 0xe5, 0x9a, 0x15,
+       0x86, 0x65, 0x5d, 0x1b, 0x0a, 0xc6, 0x5c, 0x8a, 0x8e, 0x43, 0x23, 0x93,
+       0x56, 0x60, 0xba, 0xf0, 0xf3, 0x42, 0x6c, 0x90, 0xb1, 0x16, 0xf8, 0x9f,
+       0x70, 0xbd, 0xa9, 0x3e, 0xad, 0xe2, 0xd6, 0x01, 0xe1, 0xa6, 0x7e, 0x2c,
+       0x4d, 0x7c, 0x0b, 0x87, 0x1a, 0x9d, 0x68, 0x25, 0x6f, 0x5f, 0x94, 0xf0,
+       0xe0, 0x2e, 0x62, 0xe0, 0xe2, 0x44, 0x31, 0xe7, 0xc6, 0x87, 0xdb, 0x12,
+       0x4e, 0x1c, 0x6e, 0x9c, 0x06, 0xd3, 0x57, 0x8c, 0xf7, 0x74, 0x07, 0x8e,
+       0xe8, 0x5e, 0x64, 0x6c, 0x7f, 0xd8, 0x42, 0xec, 0x0a, 0xe6, 0xf9, 0xa2,
+       0xe8, 0xd0, 0x41, 0x7d, 0xaa, 0x88, 0x9f, 0xd7, 0xe1, 0xe5, 0xb8, 0x60,
+       0x81, 0x07, 0x7e, 0x68, 0xc5, 0xa7, 0x4b, 0x7d, 0x98, 0x1e, 0x43, 0xc6,
+       0x21, 0x5c, 0x4a, 0x47, 0xf7, 0x48, 0x8c, 0x9c, 0x67, 0xea, 0x50, 0x4f,
+       0x93, 0xc7, 0x55, 0xe2, 0x75, 0x4d, 0x78, 0xdc, 0x2b, 0xf0, 0xd2, 0x77,
+       0x7b, 0x46, 0x42, 0x1d, 0xa7, 0x15, 0x07, 0x5e, 0xd4, 0x2a, 0xe2, 0x6e,
+       0xfa, 0xf4, 0xc6, 0x11, 0x38, 0xd7, 0xcf, 0xd3, 0xd1, 0x3b, 0xd2, 0xd5,
+       0x5c, 0x0e, 0x12, 0x9b, 0x79, 0x39, 0xfe, 0xf1, 0x65, 0xea, 0x76, 0x45,
+       0xc4, 0xe6, 0x1f, 0xb9, 0xd8, 0xeb, 0xb5, 0x2c, 0xe6, 0x0c, 0xd4, 0x33,
+       0xb0, 0x2f, 0xaf, 0xe3, 0x3d, 0xfc, 0xdd, 0x93, 0xd7, 0xf1, 0x3a, 0xca,
+       0xa3, 0xff, 0x61, 0xc3, 0x45, 0x9c, 0x21, 0x80, 0x62, 0x43, 0x30, 0x88,
+       0xf8, 0x49, 0x3c, 0x89, 0x51, 0xc7, 0xcf, 0x65, 0x7f, 0xc7, 0xb1, 0x06,
+       0x39, 0xdd, 0x62, 0x4f, 0x8c, 0x85, 0xea, 0x67, 0x1c, 0xc4, 0x55, 0xea,
+       0x41, 0xf4, 0x2c, 0xfa, 0xb5, 0xac, 0x7e, 0x5d, 0x74, 0x2c, 0xfa, 0x16,
+       0xbd, 0xe7, 0xf0, 0x93, 0x7c, 0xbf, 0x07, 0x48, 0xb3, 0xac, 0x83, 0x78,
+       0x69, 0xe0, 0xbb, 0x6d, 0x62, 0x3b, 0xe5, 0x76, 0x8c, 0x9b, 0x33, 0xd3,
+       0xb2, 0x9e, 0x8a, 0x04, 0xf0, 0xbe, 0xd6, 0xd0, 0xdc, 0xa4, 0x06, 0xd9,
+       0xd7, 0x25, 0x48, 0x8c, 0xc5, 0x38, 0x77, 0x57, 0x93, 0x87, 0x8b, 0xad,
+       0xa1, 0xa3, 0xc8, 0xc6, 0x5c, 0xe0, 0x44, 0x42, 0x0b, 0x6f, 0xe0, 0x9c,
+       0xed, 0xf6, 0x2d, 0x23, 0x67, 0x52, 0x5b, 0x98, 0xb5, 0x90, 0xab, 0x68,
+       0xe6, 0x26, 0xbc, 0x6b, 0x65, 0x7c, 0x16, 0xe3, 0x9b, 0x0a, 0xa7, 0x36,
+       0x03, 0x87, 0xbd, 0x0e, 0x3c, 0x1f, 0xae, 0x41, 0xac, 0x4a, 0x41, 0x99,
+       0xf6, 0x4b, 0xeb, 0x05, 0x9f, 0xb4, 0xc3, 0x7c, 0x43, 0xfd, 0x39, 0xfb,
+       0xad, 0xb0, 0x8c, 0xc8, 0x5d, 0x86, 0xae, 0xb1, 0x4b, 0xdb, 0xff, 0x85,
+       0x35, 0xe9, 0x93, 0xf6, 0x83, 0xde, 0x80, 0xfa, 0x49, 0x73, 0xf8, 0xaa,
+       0xf5, 0x5a, 0x4e, 0xa6, 0x1d, 0x7f, 0xa0, 0x8a, 0xbc, 0xc7, 0x39, 0x3e,
+       0x91, 0x59, 0x68, 0x47, 0xfc, 0x6c, 0x3f, 0xef, 0xc9, 0x33, 0xb1, 0x91,
+       0x75, 0x6c, 0xf7, 0x90, 0x85, 0x1a, 0xb9, 0xde, 0x6c, 0x97, 0x35, 0xc7,
+       0x26, 0x16, 0x3b, 0x31, 0x1f, 0xb3, 0x22, 0x0b, 0x16, 0xca, 0x58, 0x54,
+       0x23, 0x16, 0x70, 0xc3, 0xac, 0x71, 0x10, 0x8b, 0xdf, 0x6e, 0x6c, 0xc4,
+       0xc2, 0xec, 0xa4, 0xf5, 0x2e, 0xc1, 0xa5, 0x4b, 0x73, 0x60, 0x9c, 0xe3,
+       0xdb, 0xaf, 0x4b, 0x6e, 0x68, 0x61, 0x51, 0xc4, 0x8c, 0xd3, 0x63, 0xcd,
+       0x72, 0xda, 0x4e, 0xa9, 0x26, 0xf1, 0xb9, 0x02, 0x65, 0x86, 0x33, 0xfc,
+       0x2e, 0x82, 0xfa, 0x16, 0xf2, 0x93, 0x40, 0xd5, 0xac, 0x66, 0x17, 0xb5,
+       0xfb, 0x52, 0x22, 0xd4, 0x7c, 0x44, 0xc9, 0xf9, 0xc3, 0x73, 0x9c, 0xdb,
+       0xd7, 0x13, 0xda, 0x9a, 0x62, 0x47, 0xee, 0xfa, 0xe5, 0xac, 0xe4, 0x23,
+       0x05, 0x7f, 0xf0, 0xe7, 0x71, 0xc3, 0xed, 0x3e, 0x91, 0xc0, 0x69, 0x95,
+       0xf8, 0x53, 0x65, 0xe0, 0x74, 0xb7, 0x9e, 0x51, 0x5c, 0x5a, 0x05, 0x71,
+       0x55, 0xb0, 0xb4, 0x88, 0x31, 0x41, 0x62, 0xb6, 0xdb, 0xfd, 0x2e, 0xcb,
+       0x2c, 0x8e, 0x60, 0x32, 0x7c, 0x63, 0x43, 0xb3, 0x1b, 0x31, 0xb3, 0x98,
+       0x7e, 0x59, 0x6e, 0xf8, 0xdc, 0x73, 0x46, 0xcd, 0x1a, 0x0f, 0xed, 0xba,
+       0xcc, 0x40, 0xcb, 0xac, 0xde, 0xd6, 0x4a, 0x54, 0x34, 0x62, 0xf5, 0x88,
+       0xe4, 0x96, 0x7d, 0x35, 0x2a, 0xfb, 0xea, 0xd2, 0xca, 0xe1, 0xaa, 0x5e,
+       0x3d, 0x5f, 0x35, 0x7e, 0x80, 0xb6, 0xa8, 0xbb, 0x45, 0x1f, 0x9d, 0x9a,
+       0xe3, 0x08, 0x46, 0x9a, 0x35, 0x95, 0xc4, 0xc7, 0x0a, 0x43, 0xf2, 0x9b,
+       0x40, 0xcb, 0xcb, 0x36, 0x7e, 0x7a, 0xc9, 0xc7, 0x7f, 0xe6, 0xff, 0xf3,
+       0xeb, 0x3c, 0x4f, 0x1d, 0x4b, 0x9b, 0xf2, 0x2d, 0xb9, 0x26, 0x9c, 0xcc,
+       0x1d, 0xd1, 0x35, 0xec, 0x61, 0x7e, 0x21, 0x73, 0x03, 0x77, 0x91, 0x11,
+       0xfe, 0xcb, 0x67, 0xe9, 0x17, 0x2e, 0xea, 0x78, 0x93, 0x66, 0x12, 0xce,
+       0x2d, 0x4b, 0x8b, 0x04, 0xfd, 0x45, 0x4a, 0x00, 0x1b, 0x1b, 0x7f, 0x47,
+       0x5b, 0x00, 0xf1, 0x0a, 0x24, 0xab, 0x35, 0x58, 0x37, 0x5c, 0x31, 0xa5,
+       0xde, 0xbe, 0xf3, 0xf5, 0x92, 0x9a, 0x19, 0x97, 0x7a, 0x43, 0x91, 0x60,
+       0xfb, 0x06, 0xd6, 0xdb, 0xcc, 0x7a, 0x31, 0xc6, 0xc8, 0x7b, 0xe9, 0x9b,
+       0x2e, 0xe6, 0x37, 0xeb, 0x99, 0xeb, 0x4c, 0x69, 0xef, 0xaf, 0x0a, 0xf5,
+       0x1e, 0xd5, 0xcc, 0x71, 0xbb, 0xbd, 0xb9, 0xc1, 0x35, 0x45, 0x8e, 0x00,
+       0x7a, 0x59, 0x6f, 0x9c, 0xf5, 0xde, 0x1a, 0xa9, 0xce, 0x97, 0x77, 0x62,
+       0xc3, 0xac, 0x5c, 0xd9, 0x1e, 0xcd, 0xf4, 0x4b, 0x59, 0x67, 0x24, 0xd8,
+       0x7c, 0x1f, 0xb1, 0xba, 0x4b, 0xda, 0x60, 0xdf, 0xde, 0xb2, 0xe3, 0x0a,
+       0x6e, 0x7a, 0x21, 0x91, 0x9a, 0x74, 0x6a, 0x5a, 0xdb, 0x4a, 0x25, 0xa6,
+       0x2c, 0x9e, 0x67, 0xcf, 0xef, 0x4d, 0xc7, 0xb2, 0x9d, 0xd8, 0xa8, 0x4d,
+       0x44, 0x8a, 0x59, 0xef, 0x88, 0x36, 0xe1, 0x77, 0xd1, 0xd7, 0x56, 0xb2,
+       0xed, 0x2e, 0xe6, 0x15, 0x2a, 0x7d, 0x7b, 0xdd, 0xb0, 0xf0, 0x01, 0x9d,
+       0x7c, 0xa3, 0x8e, 0x76, 0x28, 0xfa, 0x91, 0x36, 0x65, 0x9e, 0x45, 0x17,
+       0xc1, 0xf0, 0xb0, 0xad, 0x0b, 0xa5, 0x7a, 0x5f, 0x23, 0x8d, 0xa5, 0x8a,
+       0xfc, 0xab, 0x51, 0x62, 0xa2, 0x42, 0x3c, 0xbe, 0x12, 0x1b, 0xec, 0x3c,
+       0xad, 0x8e, 0x5c, 0xc7, 0xb2, 0xf6, 0xe8, 0x96, 0xf5, 0xac, 0x3e, 0x03,
+       0xfb, 0xf4, 0x60, 0x5c, 0x6c, 0xf3, 0x97, 0xfa, 0x82, 0x6b, 0x5d, 0x08,
+       0x32, 0xe1, 0xff, 0x14, 0xc6, 0x69, 0x2f, 0x25, 0x9a, 0xf8, 0xa0, 0x02,
+       0x7f, 0xc8, 0x19, 0x28, 0x53, 0x2c, 0xb8, 0xe7, 0xce, 0x5c, 0x33, 0x93,
+       0x7a, 0xaa, 0xb8, 0x51, 0xc1, 0x07, 0x73, 0x14, 0x4c, 0xcc, 0x09, 0xf9,
+       0x07, 0x95, 0x72, 0xe2, 0x6d, 0xa8, 0xad, 0x45, 0x31, 0x8f, 0xb2, 0x6e,
+       0xac, 0xd1, 0xc1, 0x7c, 0x5a, 0xa9, 0x24, 0x16, 0xcc, 0x0a, 0x08, 0x1d,
+       0x70, 0x26, 0x43, 0xfe, 0xcd, 0xfc, 0x76, 0x8c, 0x28, 0x18, 0xd1, 0x82,
+       0x31, 0xd8, 0xf2, 0xd9, 0x76, 0x44, 0xc1, 0x75, 0x21, 0xcb, 0x3a, 0x16,
+       0x69, 0xf0, 0x1e, 0xc3, 0x2f, 0x2d, 0x59, 0x4b, 0xf1, 0x87, 0xce, 0xe7,
+       0x06, 0x28, 0x4d, 0x6a, 0xb1, 0x16, 0x65, 0xbb, 0x53, 0x38, 0xc5, 0xaa,
+       0xac, 0xc4, 0xc8, 0x42, 0x7f, 0x0b, 0xb1, 0xd2, 0xb2, 0x7e, 0xa9, 0xe7,
+       0x64, 0x79, 0xa3, 0xc2, 0xcd, 0x66, 0x60, 0x4c, 0x0b, 0xb6, 0x8e, 0x53,
+       0x07, 0x7e, 0xfa, 0x60, 0x2d, 0xe7, 0x7d, 0xd2, 0x15, 0xf4, 0x4e, 0x2a,
+       0x0b, 0xcf, 0xaa, 0x98, 0xbd, 0xea, 0x31, 0xa5, 0xa1, 0xa3, 0x04, 0x5a,
+       0x6c, 0x54, 0xb9, 0x82, 0x3a, 0x31, 0xfd, 0x1e, 0x04, 0xbd, 0x2b, 0x61,
+       0xc7, 0x6d, 0xdc, 0x9e, 0x70, 0xc6, 0xce, 0xa0, 0x9e, 0xfe, 0xa0, 0xb5,
+       0xdf, 0x4f, 0x6e, 0x07, 0x7c, 0x96, 0x84, 0x5f, 0xfa, 0x5a, 0x83, 0xf8,
+       0x5f, 0x58, 0xd6, 0x03, 0xec, 0xeb, 0x16, 0xf6, 0x75, 0x75, 0xe4, 0x7d,
+       0xeb, 0x17, 0xb6, 0xcc, 0x9b, 0x31, 0xa8, 0x5d, 0x2a, 0xf7, 0x3d, 0x0b,
+       0xd3, 0x45, 0xae, 0x0b, 0xb7, 0x4e, 0x67, 0xee, 0x11, 0x15, 0x2c, 0x79,
+       0x84, 0xf9, 0xb9, 0xc8, 0x63, 0x5c, 0x51, 0x2f, 0x8d, 0xcd, 0x0e, 0x30,
+       0xe6, 0xf9, 0xe3, 0x8a, 0x5a, 0x57, 0x06, 0x2f, 0xdc, 0x9a, 0x85, 0x07,
+       0xc9, 0x23, 0x62, 0xd3, 0x2b, 0xf1, 0x90, 0xee, 0x46, 0x79, 0x48, 0xbd,
+       0xd2, 0xc1, 0x39, 0xd9, 0x17, 0x91, 0x6b, 0x17, 0xc6, 0xa7, 0x3b, 0xd0,
+       0x49, 0x7e, 0xe1, 0x0d, 0xa9, 0xb5, 0x72, 0xdf, 0xdd, 0x24, 0xd7, 0xec,
+       0xff, 0x15, 0x0a, 0x1e, 0xa0, 0x55, 0xa8, 0xa1, 0x2e, 0xbf, 0xdc, 0x6f,
+       0xd5, 0xe5, 0x5a, 0x41, 0x7d, 0xc4, 0xc9, 0x79, 0xb1, 0xe0, 0x60, 0xdf,
+       0x4b, 0x43, 0xbc, 0x1f, 0x91, 0xdf, 0xb1, 0x07, 0x38, 0xee, 0xd8, 0x6e,
+       0x45, 0xb0, 0xe7, 0xc7, 0xd6, 0xf3, 0x8c, 0x2d, 0x5e, 0x3e, 0x7f, 0x88,
+       0x6d, 0x1f, 0x8d, 0x3c, 0x6b, 0xd5, 0x12, 0x73, 0x8f, 0x35, 0x07, 0x30,
+       0x63, 0x4e, 0x1d, 0x26, 0xef, 0x96, 0x31, 0x2b, 0x28, 0xd7, 0xca, 0x5d,
+       0x92, 0xe7, 0x55, 0x68, 0x57, 0xe0, 0xd6, 0xbb, 0x72, 0xf7, 0x4a, 0x28,
+       0x2f, 0x4c, 0xdc, 0x2d, 0x99, 0x53, 0x8d, 0x40, 0xfe, 0xde, 0xc2, 0x90,
+       0xb3, 0xad, 0x5c, 0xd1, 0xbc, 0xb7, 0x2b, 0xf2, 0xfc, 0x37, 0xb4, 0x71,
+       0xcb, 0x7a, 0x90, 0xf3, 0x35, 0x2b, 0xe2, 0xc1, 0x29, 0xb6, 0xd3, 0x45,
+       0xfd, 0x2d, 0x39, 0x3f, 0x5f, 0x85, 0xfa, 0xbf, 0xb6, 0x02, 0x7f, 0x21,
+       0x75, 0x45, 0xc6, 0xcc, 0xd6, 0x5b, 0x95, 0xe7, 0x9c, 0x92, 0x33, 0xac,
+       0x8e, 0xd8, 0x3a, 0x63, 0xd9, 0x5a, 0x97, 0x5c, 0x7b, 0xa3, 0xaf, 0x9f,
+       0x5f, 0x7f, 0x39, 0x6d, 0xc7, 0xa8, 0x05, 0x37, 0x7a, 0x31, 0x69, 0x55,
+       0x35, 0x99, 0xde, 0x62, 0x48, 0xac, 0xaa, 0x0f, 0x3f, 0x45, 0xb9, 0xaf,
+       0xe9, 0xb9, 0x38, 0xb6, 0x47, 0x0f, 0xa6, 0x4d, 0xfa, 0x43, 0x9c, 0x39,
+       0x5f, 0x8b, 0xbd, 0x56, 0xb4, 0x87, 0xf3, 0x30, 0x03, 0xc5, 0x4d, 0xc1,
+       0x9e, 0x6b, 0x98, 0x03, 0x39, 0xa2, 0x12, 0xff, 0x64, 0x7e, 0xec, 0x32,
+       0x6c, 0xab, 0x04, 0x0b, 0xd9, 0xc7, 0x48, 0xd3, 0x1f, 0x8b, 0x1d, 0x22,
+       0x47, 0xac, 0x33, 0xd8, 0x13, 0xc3, 0x1f, 0x2b, 0x0b, 0x46, 0x6a, 0xc4,
+       0x1d, 0x86, 0xfb, 0xa6, 0x78, 0x56, 0x25, 0xf7, 0x28, 0xf2, 0x76, 0x45,
+       0x6b, 0xf8, 0x91, 0xe7, 0xce, 0x9b, 0x56, 0x64, 0xcf, 0xaf, 0x29, 0x21,
+       0xad, 0x17, 0x41, 0xbd, 0x4e, 0x70, 0x9c, 0x88, 0xec, 0x95, 0xf1, 0x99,
+       0xcd, 0x5e, 0x3b, 0x87, 0x5e, 0xfb, 0x85, 0x7b, 0xb4, 0xa0, 0xfe, 0x26,
+       0x5b, 0x3c, 0x4c, 0x8e, 0x63, 0xda, 0x9e, 0x21, 0xbe, 0x3e, 0x15, 0x47,
+       0x25, 0xae, 0x88, 0x4c, 0xc1, 0xd0, 0x2b, 0xd1, 0xb7, 0xa3, 0x03, 0x81,
+       0x9a, 0x1c, 0x66, 0xb9, 0x8c, 0xb9, 0xd8, 0x93, 0xde, 0xec, 0xca, 0xf1,
+       0xf2, 0x4e, 0x3c, 0x45, 0x4c, 0xdb, 0xb8, 0x63, 0xa2, 0xb6, 0x8a, 0xba,
+       0xea, 0xd0, 0x1b, 0xf4, 0xd3, 0xb8, 0x83, 0x7e, 0x2e, 0x65, 0x27, 0xbe,
+       0x52, 0x05, 0x29, 0x67, 0xe1, 0x48, 0xa4, 0x06, 0xc9, 0x1d, 0x9f, 0x46,
+       0x66, 0xba, 0xdc, 0x97, 0x7b, 0x6e, 0xe2, 0xb0, 0x0f, 0xeb, 0x77, 0xf8,
+       0x91, 0xf1, 0xc9, 0x5a, 0x99, 0xac, 0x57, 0x0a, 0x36, 0xbf, 0x61, 0x99,
+       0x5e, 0xe9, 0x87, 0xc4, 0xf7, 0x50, 0x73, 0x37, 0x63, 0x9a, 0xd7, 0x88,
+       0x11, 0x3f, 0xc8, 0x3d, 0x46, 0x7f, 0x62, 0x65, 0x6c, 0x0e, 0xef, 0x36,
+       0x85, 0x23, 0x3d, 0xab, 0x35, 0xc4, 0x8e, 0xb0, 0x07, 0xf1, 0xec, 0x7f,
+       0xd2, 0x47, 0x9c, 0xb8, 0x47, 0xfb, 0xb8, 0xfe, 0x7b, 0xd8, 0x3f, 0xb8,
+       0x9d, 0xc4, 0x76, 0xf2, 0x48, 0x62, 0x70, 0xc8, 0x25, 0x31, 0xbf, 0x88,
+       0xed, 0x6f, 0xd9, 0xa1, 0xa0, 0x85, 0x18, 0xb8, 0x99, 0x36, 0xf5, 0x40,
+       0x08, 0xce, 0xd6, 0x39, 0xe4, 0x35, 0xf8, 0x02, 0x73, 0x1a, 0x1f, 0x36,
+       0x0d, 0x63, 0x6e, 0x56, 0x1b, 0xaf, 0xf5, 0xa0, 0xc7, 0x25, 0xdc, 0xd6,
+       0x24, 0xde, 0xe7, 0xe4, 0xec, 0xbb, 0x44, 0x4e, 0x0d, 0x1e, 0xcd, 0xcb,
+       0xd9, 0x49, 0x39, 0x9f, 0x9e, 0x05, 0x67, 0xc5, 0xa7, 0x65, 0x2e, 0x17,
+       0xd2, 0xbf, 0x6a, 0x90, 0xb2, 0xe3, 0x04, 0x79, 0xe0, 0x67, 0xa0, 0x68,
+       0x33, 0x25, 0x67, 0x58, 0x6a, 0xd7, 0xbb, 0xa5, 0x71, 0xfc, 0x4c, 0x15,
+       0xc1, 0xf5, 0xf4, 0xac, 0x71, 0x3a, 0x72, 0x41, 0x27, 0xde, 0x42, 0x5f,
+       0xff, 0xea, 0x42, 0x1b, 0x1c, 0x33, 0xed, 0xcb, 0x1d, 0x95, 0xbe, 0x3d,
+       0x6e, 0xb5, 0x7a, 0x73, 0x73, 0x95, 0xd8, 0x11, 0x0c, 0xb4, 0x51, 0xe7,
+       0x5b, 0xf4, 0xfa, 0xb6, 0x34, 0x29, 0xcc, 0x03, 0x73, 0x3e, 0x4d, 0xdf,
+       0xf7, 0x63, 0xf3, 0x30, 0x6e, 0x18, 0xd1, 0x24, 0xc6, 0x8c, 0x07, 0xcb,
+       0x2f, 0x9a, 0x83, 0xab, 0xa9, 0xef, 0x6a, 0xca, 0x27, 0xbf, 0x9b, 0x55,
+       0xe8, 0x3b, 0xfb, 0x41, 0xfc, 0x7e, 0x74, 0x87, 0xe4, 0xc2, 0x75, 0xe4,
+       0x58, 0x96, 0x75, 0x90, 0x63, 0x68, 0x9e, 0xd5, 0xb0, 0xe6, 0xb8, 0xa3,
+       0x16, 0x93, 0xd3, 0xaf, 0xc4, 0xce, 0x61, 0x89, 0x3f, 0x01, 0xd6, 0x6d,
+       0xaa, 0xcc, 0x71, 0x1b, 0xb8, 0x6e, 0xe5, 0x58, 0x0f, 0xe7, 0xc7, 0xe1,
+       0xd2, 0xc4, 0x26, 0x9a, 0xb0, 0x67, 0xe0, 0xfc, 0xf3, 0xe0, 0x2d, 0xda,
+       0x78, 0xd0, 0xf5, 0x07, 0xb6, 0x32, 0xce, 0xef, 0x0a, 0x89, 0x33, 0x17,
+       0xe9, 0x75, 0xdd, 0xf0, 0x69, 0x7e, 0x57, 0x33, 0x2e, 0xe6, 0xfa, 0xbd,
+       0x6e, 0xf8, 0x5f, 0x79, 0x2d, 0x7d, 0xb7, 0xb0, 0xce, 0xce, 0x63, 0x8a,
+       0x18, 0xdf, 0x04, 0x9b, 0xc5, 0xae, 0x6b, 0x24, 0x8f, 0x6b, 0xce, 0x40,
+       0x62, 0xb3, 0xd8, 0xf2, 0x80, 0xd8, 0x72, 0xd8, 0xa1, 0x00, 0x43, 0xe7,
+       0x6d, 0xb9, 0x13, 0x3f, 0xd0, 0x26, 0xee, 0x2a, 0xc6, 0xc4, 0x17, 0x65,
+       0xad, 0xb8, 0x23, 0x82, 0x63, 0x8b, 0x88, 0x13, 0x6f, 0xe9, 0x05, 0xbd,
+       0x8a, 0x3e, 0x05, 0x43, 0x15, 0x14, 0xd3, 0x66, 0x36, 0x50, 0x8f, 0x45,
+       0xaa, 0x9f, 0xed, 0x5e, 0x8a, 0xa5, 0xd2, 0x7f, 0x1d, 0x7b, 0x12, 0x13,
+       0x0f, 0x17, 0xe3, 0x7f, 0x49, 0x5e, 0xf4, 0xc6, 0x09, 0xca, 0xb9, 0x45,
+       0x17, 0xfd, 0x89, 0xee, 0x0a, 0x32, 0xae, 0x44, 0xef, 0x8e, 0x42, 0x5d,
+       0x05, 0x2f, 0x86, 0xfc, 0xf9, 0xb5, 0xd8, 0x2b, 0x91, 0x1c, 0x9e, 0x38,
+       0x46, 0x2e, 0x44, 0x7d, 0x4e, 0xac, 0xf1, 0xb3, 0x2f, 0xa7, 0x23, 0x05,
+       0xfb, 0x11, 0x9c, 0x98, 0x2a, 0x43, 0xfc, 0x03, 0x4a, 0xc5, 0x4c, 0xac,
+       0xab, 0xa0, 0x1f, 0x64, 0x43, 0x88, 0x97, 0x19, 0x35, 0x48, 0x0c, 0xd3,
+       0xcf, 0x47, 0x8a, 0xe0, 0xbc, 0x5e, 0xec, 0x5e, 0xf8, 0x98, 0xf3, 0xa6,
+       0xe3, 0x89, 0x22, 0x7c, 0x49, 0x3f, 0x67, 0x09, 0x46, 0x1f, 0xd3, 0x70,
+       0x55, 0x11, 0xf5, 0x34, 0x33, 0x12, 0x8a, 0xad, 0x24, 0x3f, 0x38, 0xd2,
+       0xe8, 0xbc, 0xe9, 0x64, 0xf6, 0xb7, 0xe4, 0xbe, 0x97, 0x8e, 0x45, 0xf4,
+       0x81, 0x17, 0x17, 0x87, 0x72, 0x73, 0x4e, 0xde, 0x9f, 0xf7, 0x07, 0x69,
+       0xdf, 0xb2, 0x42, 0x11, 0x1f, 0xed, 0xe2, 0xc2, 0x18, 0xde, 0xd6, 0x0a,
+       0x63, 0xf0, 0x31, 0xb6, 0x2f, 0x21, 0xb7, 0x16, 0xde, 0xef, 0x66, 0x9e,
+       0xeb, 0x64, 0xbe, 0xd0, 0x06, 0xe1, 0xa3, 0x47, 0xc9, 0xab, 0xf6, 0x27,
+       0x80, 0x77, 0xd3, 0x16, 0x16, 0x44, 0xca, 0x89, 0x75, 0x3d, 0x94, 0x2d,
+       0xeb, 0xab, 0x07, 0x94, 0x61, 0xe6, 0xc2, 0x93, 0xce, 0x92, 0x98, 0xca,
+       0xdc, 0x77, 0x5f, 0x36, 0xe4, 0x9f, 0x60, 0x1e, 0xec, 0x66, 0x2e, 0x4e,
+       0xcd, 0x29, 0xfb, 0x99, 0x07, 0xef, 0xce, 0xe7, 0xc1, 0xfb, 0xb2, 0x1e,
+       0x64, 0x69, 0xbc, 0x5b, 0x22, 0xcc, 0xbf, 0xed, 0x75, 0x04, 0x0f, 0xc6,
+       0xd2, 0x2a, 0x4e, 0x45, 0x3e, 0xb0, 0xc6, 0xab, 0x64, 0xcc, 0x3e, 0x3c,
+       0x93, 0xa8, 0xc6, 0x81, 0x81, 0x3a, 0x9c, 0xcd, 0x3e, 0x52, 0x84, 0xd2,
+       0x2b, 0x71, 0x66, 0xa8, 0x02, 0x23, 0x03, 0x9b, 0xf9, 0xbb, 0x11, 0x1f,
+       0x0c, 0xd9, 0x39, 0x38, 0xb1, 0x59, 0xfa, 0x77, 0x40, 0x99, 0xb0, 0x73,
+       0x70, 0x33, 0xc6, 0xdc, 0xbb, 0xb9, 0x27, 0x9f, 0x7b, 0x8f, 0x33, 0xf7,
+       0x3e, 0xc2, 0x36, 0x9f, 0xcb, 0xb7, 0x79, 0xc8, 0xfe, 0x96, 0xbe, 0x48,
+       0xdd, 0xa9, 0xf5, 0x9a, 0x59, 0x0f, 0x18, 0x4e, 0x84, 0xc2, 0x85, 0xba,
+       0xcf, 0xb1, 0xde, 0x91, 0xf3, 0xf5, 0x72, 0x39, 0x35, 0x79, 0x31, 0x36,
+       0x24, 0xec, 0x75, 0x1f, 0xea, 0x23, 0x4c, 0x5d, 0x48, 0x8e, 0x49, 0x7e,
+       0x9e, 0xfd, 0x16, 0xf9, 0xfc, 0x9e, 0x22, 0x54, 0x54, 0x61, 0x61, 0x46,
+       0xd6, 0xb3, 0x4b, 0x98, 0xfb, 0x15, 0xf4, 0x1f, 0x47, 0x32, 0xb5, 0x8a,
+       0xfe, 0x05, 0xb7, 0xc7, 0xc8, 0xfe, 0x55, 0x82, 0xf3, 0xf0, 0x44, 0x68,
+       0xbc, 0xad, 0x1c, 0x95, 0x58, 0x15, 0xb1, 0xf9, 0x23, 0x79, 0x60, 0xb0,
+       0x79, 0x09, 0xe3, 0x9c, 0x23, 0x14, 0x64, 0xcc, 0x02, 0x42, 0x23, 0xcc,
+       0x6f, 0xb2, 0x95, 0xb8, 0x87, 0x79, 0xa6, 0x5a, 0x15, 0x47, 0xcf, 0xf9,
+       0x35, 0x4e, 0xf9, 0x5e, 0x85, 0xee, 0x31, 0x91, 0x17, 0x67, 0xee, 0x50,
+       0x86, 0x45, 0xb9, 0x35, 0x19, 0xb7, 0x9b, 0xb2, 0xdd, 0xa1, 0xf1, 0x30,
+       0x5d, 0x50, 0xdf, 0xc7, 0x1b, 0x87, 0x12, 0x0a, 0x16, 0x68, 0x2e, 0xac,
+       0xf4, 0x56, 0x62, 0x81, 0xfe, 0x3b, 0x6b, 0xd1, 0x32, 0x79, 0x76, 0x61,
+       0xad, 0xb4, 0x98, 0xed, 0xfe, 0x92, 0xf9, 0xc2, 0xb0, 0x78, 0x67, 0x36,
+       0x77, 0xdf, 0xcc, 0x52, 0x36, 0xe5, 0x6e, 0xa0, 0xdc, 0xfb, 0xbc, 0x76,
+       0x2e, 0x9f, 0x2f, 0x37, 0x1e, 0x76, 0x30, 0x3e, 0x49, 0xd9, 0x16, 0xca,
+       0xbd, 0x87, 0x72, 0x7b, 0xbc, 0xd2, 0xbf, 0xdf, 0x59, 0xf7, 0x2d, 0x93,
+       0x67, 0xb9, 0x75, 0x91, 0x9c, 0xdc, 0xac, 0xc8, 0xd5, 0x87, 0xf3, 0x6d,
+       0x4d, 0x24, 0x98, 0xec, 0x11, 0xb3, 0x57, 0x44, 0x43, 0x81, 0x2e, 0x7b,
+       0x4d, 0x3c, 0x80, 0x95, 0xd9, 0x00, 0xee, 0xa5, 0xde, 0x33, 0xce, 0xc2,
+       0x98, 0xec, 0x3e, 0x99, 0x92, 0x17, 0x2c, 0x64, 0xb9, 0xee, 0x3c, 0x7e,
+       0xb7, 0x64, 0xc5, 0xfe, 0x26, 0xf3, 0xf9, 0xa4, 0xc4, 0xb1, 0xba, 0x3c,
+       0x16, 0x38, 0xf1, 0x64, 0xe2, 0x37, 0xe7, 0xfa, 0x52, 0x12, 0x97, 0x65,
+       0xad, 0x27, 0x80, 0x74, 0xf6, 0x2a, 0xd4, 0xf7, 0x7b, 0xb1, 0x42, 0x9f,
+       0x46, 0x9c, 0xf8, 0xd6, 0x79, 0x7b, 0xdc, 0xc7, 0x76, 0xe0, 0xb2, 0xc5,
+       0x2b, 0x4f, 0x66, 0x1b, 0xbc, 0xd5, 0xc4, 0xba, 0x83, 0x17, 0xc5, 0xd7,
+       0x19, 0xb1, 0x32, 0x23, 0xd4, 0xf6, 0x02, 0xe7, 0xbd, 0xc4, 0xce, 0x1b,
+       0xd6, 0x29, 0x19, 0xce, 0xfd, 0xe3, 0xf9, 0xb9, 0xdf, 0x9f, 0x45, 0x71,
+       0x0e, 0xdb, 0xae, 0xc2, 0xac, 0x7e, 0xf9, 0xf6, 0xe2, 0xed, 0x68, 0x29,
+       0xef, 0x5d, 0x85, 0x99, 0x83, 0x57, 0x17, 0xe7, 0xf6, 0xc2, 0x64, 0x7d,
+       0xe1, 0xd2, 0x1c, 0x2a, 0xd8, 0x63, 0xe2, 0x3d, 0xda, 0x44, 0x1d, 0x75,
+       0x26, 0x18, 0x2b, 0xfd, 0xda, 0x74, 0xbe, 0x5f, 0x4f, 0xb0, 0x5f, 0x71,
+       0x97, 0xac, 0xff, 0x4a, 0xbf, 0x94, 0x58, 0x85, 0x51, 0x87, 0x0f, 0x92,
+       0xf0, 0x7a, 0x8d, 0x50, 0xfc, 0x25, 0xfa, 0xca, 0x08, 0xfb, 0x5a, 0x85,
+       0x1e, 0x25, 0x6b, 0xef, 0xfd, 0x1c, 0x60, 0x99, 0xa9, 0x7c, 0x40, 0xfa,
+       0xe9, 0xa4, 0xcd, 0xfd, 0x25, 0x71, 0x58, 0x27, 0x0e, 0x8b, 0xfc, 0x77,
+       0xc8, 0x79, 0xbb, 0x29, 0x7f, 0x09, 0xe7, 0xcf, 0x2d, 0x7b, 0x54, 0x66,
+       0xa9, 0xd1, 0x66, 0x73, 0x6e, 0x27, 0x7d, 0x76, 0x01, 0x6d, 0x6a, 0x7f,
+       0x46, 0xc1, 0x10, 0x95, 0x7e, 0x34, 0x2d, 0x6b, 0xd7, 0x7e, 0xec, 0xcb,
+       0xb8, 0xf0, 0x5c, 0xba, 0x16, 0xc3, 0x99, 0x22, 0x1c, 0x4a, 0x5f, 0x89,
+       0xdd, 0x19, 0x22, 0x67, 0xfa, 0x2a, 0x0c, 0x66, 0xdc, 0x78, 0x23, 0x4d,
+       0x3d, 0x65, 0x4a, 0xf0, 0xd3, 0xf4, 0xa7, 0xf0, 0x4c, 0xa6, 0x14, 0xaf,
+       0xa7, 0xaf, 0xc6, 0x81, 0x4c, 0x19, 0x5e, 0x4e, 0x93, 0x17, 0x67, 0x3c,
+       0x78, 0x29, 0x1d, 0xc0, 0x68, 0xa6, 0x1c, 0x2f, 0xa6, 0x83, 0x18, 0xc9,
+       0x54, 0xe0, 0x07, 0xe9, 0x6b, 0x90, 0xcd, 0x54, 0xe2, 0x85, 0x74, 0x3d,
+       0x9e, 0xa0, 0x0f, 0x3c, 0x9f, 0xd6, 0xf0, 0x78, 0xa6, 0x0a, 0xc7, 0xd2,
+       0x21, 0xb6, 0xeb, 0xc3, 0xd1, 0x81, 0x30, 0xf6, 0x0d, 0xd5, 0xe0, 0xb9,
+       0x81, 0xd9, 0x18, 0x1e, 0xf2, 0xe3, 0xd0, 0x40, 0x23, 0x76, 0x0f, 0x8d,
+       0xdb, 0xfa, 0x39, 0x92, 0x68, 0x39, 0xaf, 0xc7, 0x0d, 0x1f, 0x33, 0xdf,
+       0xaf, 0x24, 0x44, 0x6f, 0x6e, 0xb3, 0x8a, 0x73, 0xf4, 0x64, 0xd6, 0x9e,
+       0x77, 0x68, 0xfd, 0x6d, 0xf4, 0x33, 0x0b, 0xdd, 0xfa, 0x95, 0xcc, 0x47,
+       0x7b, 0x24, 0x1e, 0xd1, 0x16, 0x0e, 0x28, 0x1b, 0x6d, 0x0c, 0xaa, 0x88,
+       0x95, 0x53, 0x97, 0x1c, 0xb6, 0xb7, 0x8c, 0xfe, 0x9c, 0x26, 0x16, 0x98,
+       0x9c, 0xd7, 0x44, 0xf6, 0x80, 0xb2, 0x85, 0xf9, 0xef, 0xb5, 0xfd, 0xa6,
+       0x55, 0x6a, 0x63, 0x71, 0x28, 0x36, 0x9b, 0x3e, 0x17, 0x1e, 0x14, 0x7d,
+       0x96, 0x17, 0x89, 0x3e, 0x8b, 0xb4, 0xcb, 0xd9, 0x49, 0x41, 0xef, 0x3f,
+       0x2e, 0xca, 0xd9, 0xc3, 0xdf, 0x17, 0xe7, 0x72, 0xc9, 0xc2, 0xbc, 0x5b,
+       0x56, 0x9f, 0x5e, 0x98, 0x7b, 0xf2, 0xd8, 0x6a, 0x59, 0x6f, 0x03, 0x63,
+       0x48, 0x15, 0x79, 0x8e, 0xac, 0x45, 0x4c, 0xc5, 0x1b, 0xc4, 0x8a, 0x8d,
+       0x50, 0x60, 0x96, 0x7a, 0x51, 0xfe, 0xea, 0x75, 0xd8, 0xf6, 0x67, 0xda,
+       0x98, 0x75, 0xf8, 0x3c, 0xf6, 0x4c, 0x14, 0x4b, 0x0c, 0xdd, 0x93, 0x90,
+       0xbe, 0x41, 0x2d, 0x92, 0x3e, 0x23, 0x77, 0x0f, 0xa3, 0xb2, 0x9e, 0x77,
+       0x39, 0xbb, 0x53, 0xb1, 0x72, 0xc0, 0x89, 0x2e, 0xfd, 0xbf, 0x48, 0xcc,
+       0x64, 0x3f, 0xea, 0xe8, 0x6f, 0x2a, 0xfe, 0x76, 0x80, 0xf1, 0x25, 0x72,
+       0x37, 0x4c, 0xe2, 0xad, 0x6b, 0xd4, 0x89, 0x15, 0x89, 0x65, 0x7c, 0xee,
+       0x86, 0x3a, 0x4a, 0x56, 0xd1, 0xeb, 0x36, 0x2b, 0x68, 0x33, 0xb2, 0xff,
+       0xd2, 0x3c, 0x66, 0xe2, 0xf0, 0x3c, 0x3f, 0x52, 0x09, 0x59, 0x3f, 0x5d,
+       0x82, 0x9d, 0xa9, 0xd0, 0xaa, 0xb3, 0x8a, 0x1f, 0xc9, 0xac, 0x0b, 0x26,
+       0xe7, 0xbe, 0x9b, 0x7d, 0xf3, 0xf4, 0x7a, 0xd1, 0x3d, 0x54, 0xcd, 0xcf,
+       0xc4, 0x67, 0x3d, 0xc4, 0xea, 0x6e, 0xce, 0x6d, 0xf7, 0x90, 0x07, 0x47,
+       0xf7, 0xb8, 0x51, 0x96, 0x82, 0xf2, 0xec, 0x3c, 0xa2, 0x8d, 0xd6, 0x88,
+       0x17, 0x46, 0x3c, 0x28, 0x25, 0xa7, 0x7d, 0x7e, 0xc4, 0x8b, 0x92, 0xad,
+       0xb4, 0x87, 0x5d, 0x55, 0x28, 0xde, 0xea, 0xc6, 0x73, 0x99, 0x6a, 0xb8,
+       0xb6, 0xde, 0x81, 0xf5, 0x99, 0x69, 0x50, 0xb7, 0x56, 0x63, 0x62, 0x97,
+       0x0f, 0x33, 0x76, 0x18, 0x78, 0x63, 0x4f, 0x0d, 0x6a, 0x77, 0xdc, 0x8c,
+       0x9f, 0xee, 0xf1, 0xa3, 0x92, 0xba, 0x79, 0x79, 0xc4, 0x29, 0xfc, 0x93,
+       0xf3, 0x74, 0xa0, 0x38, 0xbf, 0x6f, 0x1c, 0xbb, 0x94, 0xaf, 0x42, 0x29,
+       0xcc, 0x0d, 0x90, 0xc9, 0xca, 0xfa, 0x68, 0x63, 0x4b, 0x77, 0x62, 0xe4,
+       0x5f, 0x8b, 0x8d, 0x5f, 0xfd, 0x9f, 0xb7, 0xa3, 0x0d, 0xc4, 0x32, 0xf1,
+       0xff, 0x15, 0xab, 0x4b, 0x8c, 0x8e, 0x87, 0xc3, 0xf3, 0x8a, 0xb1, 0xca,
+       0x9e, 0x8f, 0x95, 0xe4, 0x80, 0xcb, 0xd1, 0xbd, 0xa3, 0xa1, 0xed, 0x1e,
+       0xc5, 0x87, 0x58, 0x55, 0x3f, 0xef, 0xa9, 0x79, 0x9f, 0x82, 0x2a, 0xf9,
+       0xba, 0xac, 0x99, 0xa9, 0xa3, 0x8b, 0xf2, 0x7b, 0xa0, 0x3e, 0x7b, 0x0d,
+       0xaa, 0x3b, 0x55, 0xd0, 0xe3, 0x98, 0x65, 0xda, 0xfb, 0x5a, 0xe2, 0xe3,
+       0x4e, 0xac, 0x4c, 0x8c, 0x32, 0x47, 0x11, 0x5d, 0x4a, 0x5f, 0x37, 0x52,
+       0x8e, 0xf4, 0x57, 0x9e, 0x37, 0xc4, 0xaa, 0x3e, 0xb6, 0xbf, 0x85, 0x71,
+       0x75, 0xb3, 0xfc, 0x67, 0xdd, 0x28, 0x95, 0xb2, 0xd2, 0xf7, 0x7a, 0xfe,
+       0x96, 0xfe, 0x5a, 0xd6, 0xc6, 0x8b, 0xe2, 0x54, 0x51, 0xac, 0x94, 0x71,
+       0x6a, 0x7f, 0x22, 0x14, 0x7b, 0x97, 0x78, 0x76, 0x2c, 0xeb, 0x24, 0xf7,
+       0x11, 0xbb, 0x59, 0x47, 0x7b, 0xe9, 0x51, 0x8e, 0x9e, 0xb7, 0x99, 0x42,
+       0x2e, 0xb0, 0x04, 0xe9, 0xd4, 0x54, 0x5f, 0x92, 0xfd, 0x6e, 0x27, 0x5c,
+       0xbd, 0x05, 0xdc, 0x64, 0xac, 0x19, 0x25, 0xbf, 0xcb, 0x3a, 0xe0, 0xe8,
+       0xa7, 0x3d, 0xe8, 0x2a, 0xc7, 0x58, 0xc4, 0x39, 0xaf, 0xe6, 0xc7, 0x6d,
+       0x56, 0x1a, 0x26, 0x4e, 0xcd, 0x2b, 0xc1, 0xa1, 0x5d, 0x57, 0xa1, 0xbc,
+       0x7f, 0xdc, 0xf2, 0xf0, 0x5e, 0xa9, 0x31, 0x1f, 0x4f, 0x44, 0x42, 0xad,
+       0xab, 0x15, 0x13, 0xad, 0xf3, 0xdc, 0x28, 0xd9, 0xe5, 0x40, 0x71, 0x3f,
+       0x79, 0x83, 0x7e, 0x03, 0xc6, 0x7d, 0x39, 0x3c, 0x57, 0x7b, 0x67, 0xdb,
+       0x76, 0x75, 0xcd, 0xa8, 0xdb, 0xf4, 0x1b, 0x13, 0x37, 0xaa, 0x8c, 0xed,
+       0xc5, 0xc3, 0x1e, 0x14, 0xf5, 0x9a, 0x98, 0x71, 0x83, 0xe0, 0x51, 0x23,
+       0x8a, 0x68, 0xaf, 0xae, 0x5e, 0x1f, 0xf3, 0xea, 0x3a, 0xb8, 0xc8, 0xed,
+       0x1c, 0xdb, 0x0d, 0x38, 0xc8, 0xc3, 0xd4, 0xed, 0x37, 0x43, 0x65, 0xd9,
+       0x13, 0x7c, 0x7e, 0x82, 0xfc, 0xf3, 0x04, 0xef, 0x9d, 0x18, 0xae, 0xe1,
+       0xa7, 0x0a, 0xb5, 0xbb, 0xcb, 0x10, 0x5b, 0x2a, 0xeb, 0xac, 0x0e, 0x54,
+       0xf7, 0x8b, 0x7f, 0xaa, 0xb8, 0xab, 0x49, 0x81, 0x7e, 0x1d, 0xdb, 0x9c,
+       0x79, 0x39, 0x5f, 0xbd, 0xd3, 0x8d, 0x8a, 0x2e, 0xb6, 0x77, 0xa9, 0x2f,
+       0x4b, 0xac, 0xba, 0x30, 0x07, 0x01, 0x55, 0x62, 0xb7, 0xcc, 0xd9, 0x27,
+       0xf9, 0xbd, 0x1b, 0xce, 0x5e, 0x99, 0x6b, 0x19, 0xe3, 0x37, 0xdd, 0x39,
+       0x5e, 0x7b, 0xd1, 0x5a, 0x3b, 0xb2, 0x89, 0x25, 0xd8, 0x62, 0x9f, 0x5d,
+       0x08, 0xc0, 0x33, 0x12, 0x6c, 0xcd, 0xe0, 0xf4, 0xb9, 0x9e, 0x94, 0x13,
+       0xf7, 0x26, 0xe5, 0x0c, 0x87, 0x9c, 0x33, 0xe0, 0x58, 0x47, 0xdc, 0x78,
+       0xb0, 0xcf, 0x2d, 0x6b, 0xdc, 0x01, 0x97, 0x56, 0x8b, 0x77, 0x33, 0x82,
+       0x79, 0x25, 0x38, 0x9c, 0xf6, 0xe3, 0x84, 0xfd, 0xbb, 0x94, 0x18, 0x6c,
+       0xa1, 0x45, 0x2f, 0x47, 0xb7, 0xb7, 0x04, 0xc9, 0xf0, 0xcd, 0xc8, 0xdc,
+       0xc5, 0x1c, 0x9a, 0xb6, 0x59, 0x41, 0x4e, 0x41, 0xb7, 0x63, 0x6e, 0xe0,
+       0x40, 0x2a, 0xfc, 0x39, 0x4c, 0x56, 0x39, 0xa9, 0x3f, 0x59, 0x9f, 0x50,
+       0xb1, 0x93, 0x56, 0x45, 0xfc, 0x8b, 0x89, 0xdd, 0x96, 0x27, 0x61, 0x55,
+       0x18, 0x5a, 0x7c, 0x54, 0x09, 0xb5, 0xaf, 0xa7, 0xdf, 0x96, 0x8d, 0x94,
+       0x11, 0x8f, 0x67, 0xa1, 0x74, 0x97, 0xd8, 0xaf, 0x87, 0xd8, 0x70, 0xbd,
+       0xec, 0x07, 0x84, 0x03, 0x8a, 0x07, 0xf7, 0x0d, 0x08, 0xae, 0x2e, 0x47,
+       0xd1, 0x9e, 0x0a, 0x3c, 0x9c, 0x76, 0x12, 0xfb, 0xdc, 0xa8, 0xdd, 0x25,
+       0x3e, 0x5f, 0x89, 0xca, 0xad, 0x07, 0x2d, 0xbf, 0x56, 0x82, 0x4a, 0x5e,
+       0x3f, 0x46, 0x5d, 0x7c, 0x90, 0xfa, 0x1a, 0x46, 0x13, 0xf5, 0x94, 0xdb,
+       0xce, 0xf1, 0xf9, 0xf0, 0x5e, 0xaa, 0x91, 0xb2, 0xfd, 0x78, 0x77, 0x87,
+       0x65, 0xb5, 0x44, 0x62, 0x70, 0x8e, 0x5c, 0x89, 0x5f, 0xf2, 0xf7, 0x71,
+       0xbd, 0x05, 0xea, 0x48, 0x1d, 0xde, 0x4c, 0xb5, 0xc2, 0x31, 0x52, 0x81,
+       0xb3, 0x5b, 0x45, 0xa6, 0x1b, 0x95, 0x7d, 0x5a, 0xf8, 0x0c, 0x6d, 0xdf,
+       0xb5, 0x8b, 0x81, 0xbf, 0x46, 0xda, 0x2f, 0xcc, 0x4f, 0x8e, 0xef, 0x1d,
+       0xcc, 0xcf, 0xcd, 0x38, 0x0a, 0xdc, 0xe9, 0x07, 0xd6, 0x63, 0x4c, 0x67,
+       0x5c, 0xd1, 0x20, 0xba, 0xc3, 0xc7, 0x64, 0xbf, 0x9c, 0xe3, 0x8b, 0x11,
+       0xf3, 0x9f, 0xb5, 0xe4, 0xdc, 0x81, 0x8b, 0xf6, 0x59, 0xac, 0x1d, 0xb2,
+       0x36, 0x2e, 0x93, 0xfb, 0x3f, 0xe7, 0x9c, 0x30, 0x41, 0x31, 0x44, 0xe6,
+       0x16, 0x99, 0x4b, 0xa2, 0xf1, 0xe5, 0x64, 0xfe, 0xa3, 0xf5, 0xe8, 0xf9,
+       0xf2, 0xf0, 0xba, 0xec, 0x75, 0x70, 0x59, 0x87, 0x95, 0xb9, 0x94, 0xf5,
+       0xca, 0x00, 0x56, 0x8d, 0x78, 0xed, 0xdc, 0xf9, 0xdd, 0x84, 0xcc, 0x9f,
+       0x9c, 0xa1, 0xf1, 0x90, 0x9b, 0xe8, 0x28, 0xe5, 0xdc, 0x7d, 0x90, 0x80,
+       0x72, 0x5b, 0xb4, 0x0d, 0xe5, 0xc4, 0xb5, 0x77, 0x12, 0xc1, 0x55, 0x26,
+       0x12, 0x6c, 0x2b, 0x8a, 0x12, 0xd6, 0x79, 0x33, 0xe1, 0x60, 0xbc, 0x6d,
+       0xe6, 0x98, 0xbd, 0xb0, 0x6c, 0xae, 0xbc, 0x0c, 0x33, 0xa8, 0xa7, 0xb3,
+       0x09, 0x03, 0xb5, 0xd4, 0xd3, 0x99, 0x84, 0x13, 0x67, 0xa8, 0x97, 0x53,
+       0x89, 0x00, 0x2a, 0x18, 0x98, 0x8a, 0xfa, 0x2c, 0x4c, 0xe8, 0x95, 0x72,
+       0x3e, 0x02, 0x72, 0xfe, 0xc5, 0x9f, 0xd4, 0x51, 0x9b, 0xac, 0x5f, 0x53,
+       0xeb, 0x70, 0x60, 0xd2, 0xe6, 0x2c, 0x4e, 0xe6, 0xcd, 0xa2, 0x1f, 0x19,
+       0x93, 0x9d, 0xab, 0xb7, 0xca, 0xa1, 0xa6, 0x83, 0x1c, 0x4f, 0x40, 0x29,
+       0x8c, 0x67, 0x19, 0x40, 0x59, 0xa3, 0x89, 0x30, 0x1e, 0x62, 0x5b, 0x6f,
+       0x27, 0x5e, 0xc1, 0xad, 0xfc, 0x7e, 0x3f, 0xf1, 0x23, 0x2c, 0x61, 0x3f,
+       0xde, 0x23, 0x6e, 0xdc, 0x1f, 0xba, 0xad, 0x04, 0xa5, 0x75, 0x58, 0x34,
+       0x72, 0xfa, 0x5c, 0xb7, 0x3d, 0xce, 0x42, 0x4e, 0xe5, 0xc6, 0xfd, 0xe9,
+       0xc2, 0x59, 0xa6, 0x18, 0x7d, 0x58, 0xf0, 0xd5, 0xcd, 0x1c, 0x1e, 0x68,
+       0x4b, 0x7c, 0x23, 0x77, 0x4e, 0x47, 0x95, 0xcf, 0x79, 0x3d, 0x3a, 0x51,
+       0xea, 0xcf, 0xfb, 0x95, 0xf4, 0xe7, 0x93, 0xca, 0x5c, 0xe0, 0xcc, 0xa3,
+       0xb6, 0x7e, 0x65, 0x7d, 0x3e, 0x80, 0xeb, 0x88, 0xe7, 0x27, 0xc9, 0xa1,
+       0x19, 0x93, 0xb1, 0x7a, 0xde, 0x0a, 0xf4, 0xec, 0x11, 0x9d, 0x06, 0xdb,
+       0xd9, 0x87, 0xb6, 0x0c, 0x56, 0x22, 0xb9, 0xc7, 0xc3, 0x31, 0x88, 0xde,
+       0xc9, 0x43, 0xf7, 0xd0, 0xff, 0xd3, 0x7f, 0x83, 0x75, 0xbb, 0xa6, 0xe1,
+       0xad, 0xf4, 0x97, 0xb0, 0x9e, 0x36, 0xe4, 0xa0, 0xef, 0xac, 0xd0, 0xaf,
+       0x42, 0x6e, 0x3f, 0xc3, 0xc7, 0x39, 0x78, 0x9f, 0xbe, 0xb5, 0x0e, 0xef,
+       0x64, 0x67, 0x61, 0x46, 0x9f, 0x8a, 0xc9, 0x69, 0x0a, 0xed, 0x43, 0xf6,
+       0x5e, 0xdc, 0xc4, 0xb7, 0xaf, 0x40, 0xdd, 0x65, 0x62, 0x7d, 0xd4, 0x8d,
+       0xdd, 0xcc, 0x2d, 0x56, 0xc8, 0x7a, 0x98, 0x5d, 0xaf, 0x19, 0x7b, 0x39,
+       0x17, 0x89, 0x04, 0x79, 0x8b, 0x37, 0xa7, 0xe7, 0xf8, 0xf4, 0x62, 0xd6,
+       0xb9, 0xa7, 0xc4, 0xde, 0xcb, 0x50, 0x04, 0x1f, 0x44, 0xcf, 0x05, 0x1d,
+       0x7f, 0x0d, 0x37, 0x26, 0xdf, 0xa7, 0x1d, 0x84, 0xc6, 0xaf, 0x75, 0xfc,
+       0x4f, 0xea, 0x72, 0x1d, 0xe7, 0xf1, 0x6f, 0x30, 0x94, 0xf6, 0xd0, 0x8f,
+       0x64, 0xef, 0x69, 0x2d, 0x8e, 0x6e, 0x8b, 0x33, 0x37, 0x09, 0xea, 0x19,
+       0xf2, 0xfa, 0x4c, 0x95, 0x65, 0x39, 0x22, 0x71, 0x0c, 0x0e, 0x58, 0xd6,
+       0x62, 0x3d, 0xd6, 0x5c, 0x42, 0xfd, 0xde, 0x8f, 0xfd, 0xac, 0xe7, 0xc3,
+       0x91, 0xa1, 0x15, 0xbc, 0x2f, 0x3c, 0x78, 0x2d, 0x1e, 0xe6, 0xf3, 0x2f,
+       0xe9, 0xb1, 0xf1, 0x19, 0x08, 0x72, 0xce, 0x73, 0xcf, 0xc7, 0x86, 0x56,
+       0x7e, 0x4c, 0xbd, 0x0b, 0xfa, 0x7c, 0x22, 0xaf, 0xcf, 0x52, 0xea, 0xf3,
+       0xf6, 0x91, 0xf7, 0xcf, 0x6d, 0x48, 0x05, 0x63, 0x19, 0xc6, 0x98, 0xb7,
+       0xa8, 0xb7, 0x8d, 0xb4, 0x57, 0xe6, 0x1a, 0x38, 0x92, 0x6d, 0xa6, 0x6e,
+       0x5c, 0xe4, 0x44, 0x4e, 0x1c, 0xcb, 0x1a, 0xb4, 0x4d, 0x60, 0x21, 0xe3,
+       0x85, 0xe9, 0xcd, 0xd9, 0x4f, 0xe6, 0xbc, 0x3f, 0x70, 0xee, 0x94, 0x66,
+       0x1c, 0x4f, 0xc8, 0xd8, 0xa5, 0x9c, 0xfd, 0x5c, 0xd6, 0x80, 0xa7, 0x94,
+       0xb9, 0xd0, 0xf6, 0xee, 0x84, 0xf0, 0xf4, 0x00, 0x65, 0x15, 0x53, 0xd6,
+       0xe9, 0x73, 0x9b, 0x52, 0x6d, 0xf6, 0xd9, 0x37, 0xf2, 0x1b, 0x84, 0x69,
+       0xcf, 0xc5, 0x91, 0x32, 0xbc, 0xed, 0x13, 0x19, 0x39, 0x5d, 0x0a, 0x06,
+       0x6e, 0x61, 0x19, 0x79, 0xfe, 0x20, 0x9f, 0xdf, 0x12, 0x29, 0xc2, 0x90,
+       0xb7, 0xb0, 0xee, 0x94, 0xeb, 0x8b, 0x79, 0xbe, 0x9d, 0x6b, 0x2b, 0x73,
+       0x76, 0x55, 0x5c, 0x6a, 0xef, 0x25, 0xd9, 0xdc, 0xaa, 0xee, 0x92, 0xfd,
+       0x3a, 0x89, 0x7f, 0x82, 0x93, 0x39, 0x9c, 0x2d, 0xa1, 0x3d, 0x3d, 0x97,
+       0x90, 0x75, 0x21, 0x93, 0x39, 0x46, 0x18, 0x8b, 0xb2, 0xf6, 0x99, 0x2e,
+       0xc6, 0x37, 0xea, 0x8c, 0xbc, 0x77, 0x65, 0x54, 0xf6, 0xe3, 0x6e, 0xae,
+       0x14, 0x5e, 0xd7, 0x11, 0x95, 0x7c, 0x42, 0x6c, 0xb5, 0x70, 0xcf, 0x8d,
+       0x3d, 0xf9, 0x39, 0x0f, 0xa8, 0x9f, 0x84, 0xfd, 0xaf, 0x5f, 0xc2, 0xf1,
+       0x0a, 0x7b, 0x5a, 0xd2, 0xaf, 0xf3, 0x5c, 0xcf, 0xe6, 0xf5, 0x43, 0xf4,
+       0x37, 0xd3, 0x59, 0x46, 0x7e, 0x27, 0xbc, 0x3e, 0xa4, 0xcf, 0x52, 0x85,
+       0xd3, 0x4b, 0x4e, 0x21, 0x6b, 0x7b, 0x3d, 0xca, 0xde, 0xac, 0xac, 0xef,
+       0x09, 0x9f, 0xbf, 0xdc, 0x1a, 0x9f, 0x9c, 0x8d, 0x93, 0xf8, 0x78, 0xfa,
+       0x5c, 0x7f, 0xaa, 0xcd, 0xde, 0x07, 0x5d, 0xd0, 0x6f, 0xe1, 0x6e, 0xc6,
+       0x82, 0x7b, 0xaa, 0xed, 0x1c, 0x29, 0x9f, 0x8b, 0x9c, 0x3e, 0xb7, 0x33,
+       0xf5, 0x7b, 0x4b, 0xb5, 0xf7, 0x1d, 0x5d, 0x70, 0x6c, 0xd5, 0xce, 0xac,
+       0x20, 0xe7, 0x3b, 0x7b, 0x83, 0xe4, 0x25, 0x2e, 0xc6, 0xc9, 0xff, 0x52,
+       0x2a, 0x7b, 0xe0, 0xe4, 0xcb, 0xb8, 0xa5, 0x3f, 0x86, 0x21, 0xfd, 0x43,
+       0xcb, 0xf4, 0x4d, 0xad, 0xef, 0xc2, 0x92, 0xfe, 0xdf, 0x5b, 0xe5, 0x76,
+       0x7d, 0xad, 0x3d, 0xa9, 0xa8, 0x78, 0x70, 0x9e, 0x0b, 0xb7, 0x0d, 0x86,
+       0xb0, 0xb8, 0x5f, 0x45, 0x78, 0x9e, 0xc8, 0x09, 0xa1, 0x75, 0xb0, 0xde,
+       0x99, 0x5f, 0xd7, 0xc1, 0x22, 0xf6, 0xe3, 0x6d, 0xbd, 0x0c, 0xaf, 0x11,
+       0x77, 0x2b, 0x6c, 0x9e, 0xbd, 0x46, 0x49, 0x09, 0xcf, 0x76, 0xa9, 0x98,
+       0xa6, 0xc1, 0x5b, 0x6d, 0xc4, 0xc8, 0xb1, 0x5b, 0x94, 0xad, 0x99, 0x35,
+       0x4a, 0x7f, 0xb6, 0xd0, 0xbe, 0x07, 0x77, 0x8c, 0x7a, 0x71, 0xc7, 0xde,
+       0x6a, 0x7e, 0x7c, 0xfc, 0xd4, 0xf0, 0xf3, 0x8d, 0xd2, 0xdc, 0xfe, 0xfc,
+       0x12, 0xac, 0x4b, 0x15, 0xec, 0xca, 0xc9, 0xbc, 0x5a, 0x6c, 0x57, 0xea,
+       0x04, 0xb0, 0x97, 0xfc, 0xfc, 0x64, 0x5a, 0xb8, 0xfd, 0x06, 0xea, 0x42,
+       0xd6, 0x99, 0x8b, 0xc9, 0xef, 0xe5, 0x3c, 0x63, 0x24, 0xbf, 0xef, 0x9f,
+       0xb3, 0x1b, 0x9c, 0xb7, 0x1b, 0x17, 0xde, 0xa1, 0x7f, 0xcf, 0x8a, 0xfc,
+       0xbb, 0x35, 0xe9, 0xbd, 0x60, 0x57, 0x17, 0x9e, 0x17, 0xf8, 0xd0, 0xe9,
+       0x73, 0xe9, 0xd4, 0x54, 0x7b, 0x52, 0x50, 0xd4, 0x2f, 0x7c, 0x59, 0xf4,
+       0xe2, 0xc4, 0xab, 0xc4, 0x07, 0x67, 0xff, 0xc4, 0xb5, 0x42, 0xeb, 0x5c,
+       0x7b, 0x63, 0xe8, 0x8e, 0x52, 0xb7, 0x83, 0xa5, 0xc5, 0x39, 0xfb, 0xc8,
+       0xe9, 0x22, 0xa0, 0x0a, 0xbe, 0x78, 0x6c, 0x9e, 0x17, 0x60, 0x2e, 0xa8,
+       0xee, 0x15, 0xce, 0x58, 0xcd, 0x6f, 0xe1, 0xe6, 0xe4, 0x2f, 0x7b, 0x85,
+       0xa7, 0xd7, 0xf0, 0x9b, 0x24, 0xbf, 0x46, 0xec, 0x69, 0x25, 0x7a, 0x18,
+       0x13, 0x8b, 0x43, 0x2b, 0xb1, 0x71, 0xf8, 0x72, 0xb6, 0x95, 0xcb, 0x77,
+       0x0e, 0x5e, 0xb0, 0x6f, 0x69, 0x8f, 0x7d, 0x3a, 0x7d, 0x4e, 0x6c, 0x35,
+       0xc0, 0xb9, 0xda, 0x9d, 0x96, 0x3e, 0x58, 0xe8, 0xd0, 0xc9, 0x8d, 0xe8,
+       0x6b, 0x6a, 0xb5, 0xdc, 0x9f, 0xca, 0x29, 0x0b, 0xb2, 0xa6, 0xde, 0xdb,
+       0x55, 0x2a, 0xeb, 0xec, 0x17, 0xc6, 0x5e, 0x68, 0x43, 0xd6, 0x55, 0x03,
+       0xa8, 0xea, 0x15, 0x3d, 0xca, 0x98, 0x02, 0x70, 0x92, 0x03, 0x56, 0x8d,
+       0x5e, 0x4e, 0x1e, 0x6a, 0x4a, 0xec, 0xf3, 0x83, 0x61, 0xfa, 0x99, 0xc7,
+       0x2c, 0x26, 0x5f, 0x7c, 0x3b, 0x21, 0xe7, 0x32, 0x5b, 0x5b, 0x76, 0x27,
+       0x66, 0x7a, 0x0f, 0xe7, 0xf3, 0xfe, 0x15, 0x70, 0x93, 0xa3, 0x9a, 0x98,
+       0x88, 0x2a, 0x36, 0xde, 0x38, 0xb4, 0x10, 0x16, 0x32, 0xb7, 0xbc, 0x25,
+       0x23, 0xf3, 0xb9, 0x26, 0xbf, 0x26, 0x24, 0xed, 0xc5, 0x94, 0xa1, 0xac,
+       0xe4, 0x05, 0xf0, 0x3a, 0x8d, 0x16, 0x65, 0x5f, 0x46, 0xea, 0xaf, 0xe1,
+       0xbd, 0xc2, 0x9e, 0xf1, 0x12, 0xf4, 0xa7, 0x0a, 0xbe, 0x55, 0xd0, 0x47,
+       0x05, 0x6d, 0x55, 0xf2, 0x3e, 0x13, 0xfa, 0xf5, 0xb5, 0x68, 0x1c, 0x2c,
+       0xc7, 0xed, 0xfd, 0xb9, 0xfd, 0xfa, 0x86, 0xc1, 0x6a, 0xdc, 0xb6, 0x7d,
+       0x39, 0x4a, 0xf7, 0x7a, 0xb1, 0x78, 0xbb, 0xec, 0x0d, 0x2c, 0x43, 0xf1,
+       0xe8, 0xaf, 0x4a, 0xed, 0x9c, 0xbb, 0xb7, 0x99, 0x73, 0xd4, 0x4c, 0xce,
+       0x19, 0x6c, 0x8e, 0x41, 0xd6, 0x3a, 0x0d, 0x14, 0x8d, 0x1a, 0xe4, 0xa6,
+       0x56, 0xe7, 0x0c, 0x83, 0xf3, 0xcc, 0x7e, 0x5e, 0xc3, 0xbc, 0x67, 0x16,
+       0xc7, 0xee, 0xe2, 0xc7, 0xd1, 0x6b, 0x59, 0x67, 0x6f, 0x40, 0x67, 0x19,
+       0xf3, 0x70, 0xc7, 0xe8, 0x55, 0x08, 0x0c, 0x36, 0xa2, 0x76, 0xb4, 0x1a,
+       0xda, 0xa0, 0x0f, 0xad, 0xbd, 0xe2, 0x8b, 0xc1, 0x40, 0x5c, 0x8d, 0xc2,
+       0x3d, 0xca, 0x38, 0xdd, 0xfb, 0x7b, 0xeb, 0x24, 0xe7, 0xba, 0x99, 0x3a,
+       0xbb, 0xb3, 0xb7, 0x15, 0x95, 0xa3, 0xb4, 0xf3, 0xfe, 0x3b, 0x50, 0x31,
+       0xe8, 0x26, 0x4f, 0x0e, 0x20, 0x4b, 0x5e, 0xec, 0x19, 0xf4, 0xa3, 0xb4,
+       0x57, 0x6b, 0xbd, 0x5d, 0x41, 0x6c, 0x26, 0x73, 0xa9, 0x22, 0xb6, 0xe5,
+       0xa2, 0x0f, 0x0d, 0xd2, 0x97, 0x17, 0xd2, 0xcd, 0x3b, 0x7b, 0x05, 0x77,
+       0x44, 0x27, 0x67, 0x6d, 0x9b, 0x5e, 0xd9, 0x7b, 0xf9, 0x33, 0xa3, 0x38,
+       0x7f, 0x66, 0xd4, 0xb4, 0xcf, 0x72, 0x56, 0x1a, 0x50, 0xce, 0xcc, 0xd2,
+       0x7a, 0x6a, 0x79, 0xef, 0x43, 0xc6, 0xfd, 0xaf, 0xf6, 0x7a, 0x18, 0x7f,
+       0x3a, 0xf1, 0xb9, 0xa6, 0xa0, 0x39, 0xaa, 0xbc, 0xc2, 0xf1, 0xff, 0x88,
+       0x01, 0xb7, 0x8e, 0xfd, 0xfc, 0x73, 0xe5, 0x5f, 0xba, 0x26, 0x36, 0xef,
+       0xa2, 0xb5, 0xb4, 0x23, 0xcc, 0x9f, 0xc7, 0x2f, 0x5a, 0x4b, 0x13, 0x2c,
+       0xbd, 0xf4, 0x4c, 0x6d, 0x60, 0xca, 0xfa, 0x8c, 0xcc, 0x99, 0xcc, 0x53,
+       0x61, 0x7d, 0xc6, 0x44, 0xd3, 0xf5, 0x2e, 0x2c, 0xec, 0x97, 0x9c, 0x47,
+       0x62, 0x71, 0x88, 0xb9, 0xc6, 0x66, 0xce, 0x83, 0xbd, 0xae, 0xc2, 0x7b,
+       0x01, 0xe2, 0x4b, 0x80, 0x39, 0x44, 0x92, 0xf7, 0x4a, 0x70, 0x5b, 0x7f,
+       0xb5, 0xbd, 0x87, 0xb5, 0x38, 0x72, 0x15, 0xc2, 0x55, 0xb2, 0xbe, 0x76,
+       0x61, 0x1d, 0x66, 0x0e, 0x73, 0x95, 0x32, 0x1b, 0xbb, 0x16, 0x50, 0xd7,
+       0x57, 0xd1, 0x26, 0x72, 0x78, 0x75, 0xfb, 0x60, 0x0e, 0x97, 0x7a, 0xd9,
+       0xff, 0x71, 0x57, 0xce, 0xde, 0xd2, 0xb4, 0x37, 0xaf, 0xd6, 0xa2, 0xa4,
+       0x33, 0x0d, 0xde, 0x69, 0x97, 0x3d, 0x8b, 0x01, 0x6f, 0xa5, 0x51, 0x38,
+       0x27, 0x4c, 0x4c, 0xcb, 0x3e, 0x58, 0x96, 0xcf, 0xdb, 0x3e, 0xa6, 0xfc,
+       0xc7, 0xe9, 0xeb, 0xfa, 0x3f, 0x51, 0x5f, 0x72, 0xae, 0xac, 0xa0, 0x2f,
+       0x6d, 0xca, 0xd9, 0x88, 0x9c, 0xce, 0xaa, 0x0d, 0x39, 0x4b, 0x78, 0x41,
+       0x67, 0x77, 0x51, 0x67, 0xf5, 0xe7, 0x75, 0x76, 0x5d, 0x5e, 0x67, 0x25,
+       0xd4, 0x59, 0x35, 0x71, 0x57, 0x30, 0xf9, 0x5a, 0x62, 0xf2, 0xb7, 0xec,
+       0x7b, 0xb3, 0xa9, 0x97, 0x9c, 0xce, 0x34, 0xea, 0x6c, 0x2a, 0xde, 0x5f,
+       0x85, 0x76, 0xe2, 0x7d, 0x05, 0xe3, 0x61, 0x99, 0x9c, 0xed, 0xba, 0xe1,
+       0x2a, 0xdc, 0x39, 0x58, 0x82, 0xb9, 0x83, 0x2e, 0xea, 0xd2, 0x8e, 0x01,
+       0xe4, 0xf4, 0xae, 0xf3, 0x7a, 0x6c, 0x18, 0x94, 0x71, 0xad, 0x51, 0x7e,
+       0xc8, 0x71, 0x05, 0x8a, 0x72, 0x7a, 0x7c, 0x25, 0x9b, 0xeb, 0x43, 0xb5,
+       0x26, 0xf1, 0xac, 0x45, 0x79, 0x35, 0x23, 0x38, 0xfb, 0x3d, 0xea, 0x6a,
+       0x0d, 0x9f, 0x35, 0x78, 0x7d, 0xe0, 0x58, 0x3e, 0xf6, 0xbc, 0x9f, 0xe8,
+       0xeb, 0x7b, 0xe7, 0xf5, 0xfa, 0xc7, 0xcb, 0x16, 0xec, 0x4a, 0xce, 0xfb,
+       0x15, 0xf4, 0xa5, 0x4d, 0xc1, 0x48, 0xcb, 0x7a, 0x5a, 0x9f, 0x85, 0x78,
+       0x75, 0x30, 0x2d, 0x6b, 0x46, 0x69, 0xf2, 0x1d, 0x47, 0xaf, 0xf4, 0x59,
+       0x72, 0x03, 0xf5, 0x66, 0xb2, 0xbf, 0x46, 0x07, 0x3a, 0x71, 0x42, 0xd7,
+       0x7a, 0xee, 0xc3, 0xa7, 0xd0, 0xe5, 0xb3, 0xb0, 0x47, 0x6f, 0x67, 0xee,
+       0x53, 0x8a, 0x55, 0x8d, 0x34, 0xf9, 0xbb, 0x62, 0xe8, 0x4b, 0x99, 0xed,
+       0x0e, 0xc8, 0x9a, 0xec, 0xf7, 0xbf, 0x90, 0x08, 0x05, 0xdb, 0x56, 0x2b,
+       0xc0, 0xe2, 0xa4, 0x1b, 0x01, 0xc5, 0xe6, 0x26, 0xe1, 0x7e, 0x55, 0xd6,
+       0x96, 0xb7, 0x17, 0xe5, 0xce, 0x6a, 0xa8, 0x08, 0xd4, 0x48, 0x3b, 0xed,
+       0x30, 0xc7, 0xa4, 0x2e, 0xf5, 0x38, 0x53, 0xc1, 0x6d, 0x33, 0x83, 0x66,
+       0x5c, 0xb1, 0xac, 0xa5, 0x11, 0xa7, 0xfd, 0x7c, 0xcb, 0x58, 0x43, 0xfc,
+       0x6e, 0xf5, 0xe7, 0x96, 0x69, 0xaf, 0x67, 0x07, 0xbd, 0x31, 0xf5, 0x8f,
+       0x8d, 0x93, 0x79, 0x03, 0x73, 0x84, 0xfd, 0xf9, 0x35, 0x5c, 0x97, 0x11,
+       0x5e, 0xbe, 0xc7, 0x5e, 0x47, 0xfe, 0x96, 0x7d, 0x2e, 0x25, 0x9d, 0x92,
+       0x35, 0xc0, 0xa8, 0x07, 0xa5, 0xed, 0xe8, 0x1a, 0xbb, 0x01, 0x23, 0x8d,
+       0xbf, 0xb0, 0x32, 0xb9, 0xbe, 0x8b, 0x79, 0xbb, 0x6b, 0x8d, 0x13, 0x5f,
+       0xb8, 0x71, 0x96, 0x70, 0x47, 0x39, 0x43, 0x4a, 0xde, 0xae, 0xe4, 0xb8,
+       0xec, 0x0c, 0xed, 0x16, 0x1c, 0xbc, 0x48, 0xa6, 0xac, 0x31, 0x14, 0x64,
+       0xb6, 0x51, 0x9e, 0xc8, 0x75, 0x51, 0x57, 0xff, 0x6e, 0x0d, 0xfa, 0xa6,
+       0x96, 0xfb, 0x47, 0x77, 0x2e, 0xc6, 0x49, 0xb9, 0x42, 0xbb, 0xc2, 0xed,
+       0x3e, 0xb0, 0x86, 0x2e, 0x2a, 0xf7, 0x6a, 0x9e, 0x33, 0x3d, 0xe4, 0x91,
+       0x33, 0x2d, 0xe9, 0x54, 0x31, 0xf9, 0xd4, 0x09, 0x6b, 0xef, 0x45, 0x65,
+       0x3e, 0xbc, 0xa4, 0x4c, 0x3d, 0x73, 0xb5, 0x7f, 0xb1, 0x86, 0x2f, 0x2a,
+       0x53, 0x59, 0x7a, 0x71, 0x99, 0x6b, 0x88, 0xb3, 0xaf, 0x5a, 0xbb, 0x2f,
+       0x2a, 0xf3, 0x77, 0x97, 0xc8, 0x99, 0x4b, 0x1b, 0x7f, 0xda, 0xda, 0x97,
+       0x2f, 0xe3, 0x64, 0x99, 0x75, 0xda, 0x53, 0xf9, 0xbc, 0xbc, 0x50, 0xa6,
+       0x70, 0xbf, 0xa4, 0xec, 0xd2, 0xfb, 0x39, 0x99, 0xe1, 0x4b, 0x64, 0x06,
+       0x4d, 0x99, 0x6f, 0x57, 0x53, 0x61, 0xbe, 0xa3, 0xf9, 0xfb, 0xdf, 0x28,
+       0xbb, 0xb8, 0xdc, 0xc4, 0x25, 0xd7, 0x05, 0x79, 0x7f, 0xed, 0xbe, 0xf8,
+       0x7e, 0x65, 0xf1, 0xc5, 0xd7, 0xbb, 0x8b, 0x72, 0xd7, 0x05, 0x9d, 0x6e,
+       0xb9, 0xe4, 0xf9, 0x7f, 0x2b, 0xba, 0xf8, 0xfa, 0xc6, 0xe2, 0xcb, 0xb7,
+       0xf3, 0x93, 0x4b, 0xee, 0x2b, 0x5d, 0xf2, 0xfe, 0x89, 0xc3, 0x50, 0x2b,
+       0xba, 0xa2, 0xab, 0x6e, 0x8a, 0x67, 0x7b, 0x68, 0x9f, 0x62, 0x5b, 0xab,
+       0x6f, 0x5a, 0x91, 0x3d, 0x79, 0x7e, 0x8f, 0x3b, 0xad, 0x2f, 0xf0, 0x7b,
+       0xf1, 0x59, 0xac, 0xb0, 0xf7, 0xd2, 0x64, 0x8d, 0xc7, 0xe4, 0x18, 0xed,
+       0x77, 0x51, 0xdc, 0x8a, 0x11, 0x87, 0x6e, 0x9f, 0x07, 0x5d, 0x89, 0xfa,
+       0xac, 0xbd, 0x8f, 0x17, 0x8e, 0xe3, 0xa0, 0xda, 0xaa, 0x99, 0xf9, 0x73,
+       0x7e, 0xe6, 0x8d, 0x5e, 0xc4, 0xa6, 0xe6, 0xd2, 0x81, 0x61, 0xfb, 0x2c,
+       0x69, 0x07, 0xba, 0xed, 0x73, 0xaa, 0xed, 0xf9, 0xf3, 0xa4, 0xcb, 0xa1,
+       0x65, 0x0b, 0x7c, 0x4b, 0xd6, 0x64, 0xe5, 0x6c, 0x85, 0x45, 0x1f, 0x14,
+       0xfe, 0x70, 0x40, 0x51, 0x93, 0xf6, 0xba, 0xe7, 0x32, 0x07, 0x42, 0xcd,
+       0x2d, 0x0a, 0xe2, 0x25, 0x46, 0x28, 0xf0, 0x4e, 0x1e, 0x2b, 0x5d, 0x23,
+       0xeb, 0x94, 0xa2, 0x91, 0x1e, 0xc5, 0x39, 0x92, 0xc3, 0x4a, 0xc7, 0x88,
+       0xf0, 0xfb, 0x6a, 0x96, 0xf1, 0x62, 0xd6, 0x3c, 0x27, 0x5e, 0x48, 0x54,
+       0xd8, 0xef, 0x34, 0xac, 0x9f, 0x57, 0x84, 0x07, 0x23, 0x0a, 0x5a, 0xe7,
+       0x1c, 0xc6, 0x49, 0xe6, 0x32, 0x87, 0x13, 0x66, 0x64, 0x88, 0x6d, 0x4e,
+       0x24, 0x54, 0x1c, 0x1a, 0x58, 0x17, 0x19, 0xb4, 0xdb, 0x37, 0xd1, 0x6d,
+       0xef, 0x5b, 0x2d, 0xb3, 0x36, 0xa6, 0x96, 0x5b, 0x1b, 0x52, 0x4e, 0xe6,
+       0x9f, 0xd5, 0xf1, 0x4a, 0xd6, 0x3f, 0x39, 0x6f, 0x15, 0x4e, 0xb1, 0xcc,
+       0x48, 0x62, 0x35, 0x3e, 0xc8, 0x7a, 0xed, 0xf5, 0x9a, 0x1f, 0x64, 0x3d,
+       0xcc, 0xa7, 0x5a, 0xf1, 0x42, 0x76, 0x19, 0x9e, 0x1f, 0x90, 0x33, 0xe4,
+       0x2d, 0x58, 0x90, 0x50, 0xb0, 0x38, 0xb4, 0x0c, 0xc7, 0x86, 0x96, 0xe1,
+       0xf0, 0x80, 0xbc, 0x47, 0x70, 0x45, 0xfe, 0xcc, 0xb9, 0x3c, 0x8f, 0xf1,
+       0xf9, 0x52, 0x4c, 0x0c, 0xf9, 0x99, 0x0b, 0xe9, 0x78, 0x33, 0xeb, 0xc3,
+       0x60, 0xa2, 0x11, 0xc7, 0xc9, 0xe7, 0x9f, 0x49, 0x34, 0xe3, 0x2c, 0xaf,
+       0x0f, 0x24, 0x84, 0x07, 0x45, 0x71, 0x26, 0xfb, 0x7d, 0x14, 0x25, 0x6b,
+       0x71, 0xa4, 0xed, 0x69, 0xa8, 0xc9, 0x03, 0xfc, 0xb4, 0xe2, 0xf8, 0x50,
+       0x2b, 0x4e, 0x0c, 0xdc, 0x86, 0x13, 0x43, 0x3f, 0xc3, 0xc9, 0x01, 0xe9,
+       0xaf, 0x9c, 0x2b, 0x17, 0xb9, 0x1a, 0xe5, 0x2e, 0xc3, 0xf8, 0xd0, 0x9f,
+       0x23, 0xfb, 0x3d, 0xeb, 0xc8, 0x32, 0x91, 0xfb, 0xf4, 0x27, 0xc8, 0xce,
+       0xe5, 0x4a, 0x72, 0x66, 0xf4, 0x58, 0xc2, 0x8d, 0xa3, 0x89, 0xf1, 0x6b,
+       0x4b, 0x30, 0x7e, 0x23, 0x91, 0x0e, 0x1b, 0x99, 0xc3, 0x1d, 0x4a, 0xcb,
+       0xba, 0xdf, 0x67, 0x98, 0x17, 0xaf, 0xc3, 0xfa, 0xb1, 0x62, 0xbc, 0x90,
+       0x76, 0x53, 0xc7, 0x37, 0x22, 0x56, 0xd5, 0x4e, 0xfd, 0x79, 0xf0, 0x62,
+       0xc2, 0x87, 0x97, 0x12, 0x0d, 0x8c, 0x0f, 0x4d, 0xc8, 0xad, 0x77, 0x7a,
+       0xa8, 0xef, 0x0e, 0xbb, 0x4f, 0x2f, 0x24, 0x96, 0x59, 0xeb, 0xa9, 0xe3,
+       0x9e, 0xd4, 0xd7, 0xec, 0x33, 0xe1, 0xcf, 0x27, 0xce, 0x30, 0x27, 0x39,
+       0x8a, 0xc7, 0xa9, 0xd3, 0x63, 0x89, 0x38, 0x39, 0x63, 0x1d, 0xe7, 0x68,
+       0x1c, 0x43, 0xd9, 0xb5, 0x78, 0x33, 0xad, 0x1d, 0x5d, 0x81, 0xb5, 0x38,
+       0x9b, 0x29, 0xc6, 0xeb, 0x6c, 0xa3, 0x72, 0xae, 0x13, 0x93, 0xb6, 0xbc,
+       0xb5, 0xf8, 0x20, 0xad, 0x30, 0x8e, 0xaf, 0xc5, 0xfb, 0x7c, 0xf6, 0x32,
+       0x7f, 0x9f, 0x8a, 0xb0, 0x87, 0xf9, 0x67, 0x27, 0xc8, 0xeb, 0x65, 0x7d,
+       0xab, 0x2b, 0xba, 0x16, 0xc7, 0x33, 0xcf, 0x92, 0x0b, 0x57, 0xe2, 0x61,
+       0x7d, 0x1a, 0x9a, 0xa7, 0x91, 0x8b, 0x69, 0xc5, 0x38, 0xc6, 0xe7, 0x33,
+       0x89, 0xbf, 0xe3, 0xde, 0x5c, 0xf9, 0xf7, 0x38, 0x9e, 0x07, 0x29, 0xeb,
+       0xdd, 0xcc, 0x37, 0x29, 0x77, 0x3e, 0xb2, 0x91, 0x6f, 0x52, 0xee, 0xcf,
+       0x30, 0x9c, 0xd7, 0xc7, 0x71, 0x5d, 0xc6, 0xf5, 0xf5, 0x72, 0xc9, 0xa9,
+       0x27, 0x12, 0xdf, 0xe0, 0x77, 0x07, 0x26, 0xb3, 0x3b, 0xf8, 0xfd, 0x03,
+       0xec, 0x63, 0x8c, 0x4e, 0xa4, 0x2e, 0xe5, 0xe3, 0xd3, 0xb1, 0xa9, 0xaf,
+       0x22, 0x5e, 0x45, 0xfb, 0x89, 0x5c, 0x5f, 0x89, 0xd9, 0x91, 0x04, 0x36,
+       0xef, 0x76, 0x62, 0x13, 0xf1, 0x76, 0x73, 0xb2, 0x1a, 0x3b, 0xb7, 0x79,
+       0x91, 0xda, 0x76, 0x25, 0x7a, 0xb7, 0x5d, 0x8d, 0xe4, 0xb6, 0x3a, 0x6c,
+       0xdc, 0x46, 0x9d, 0xcf, 0xb5, 0xac, 0x93, 0x11, 0xcb, 0x3a, 0xcc, 0xcf,
+       0x5e, 0x7e, 0xde, 0xd3, 0xc5, 0x3f, 0x62, 0x08, 0xdb, 0x7e, 0xd2, 0x42,
+       0x3f, 0x91, 0x6f, 0x0d, 0xd7, 0x64, 0xd7, 0x44, 0x66, 0x8e, 0xae, 0x8d,
+       0x34, 0x8c, 0x4e, 0x47, 0x77, 0x5f, 0x0d, 0xd6, 0x6f, 0xab, 0x8e, 0x7b,
+       0xd9, 0x8e, 0xf7, 0x7a, 0x0b, 0x9d, 0xf4, 0x9f, 0x67, 0xf4, 0x9e, 0xc8,
+       0xfc, 0xd1, 0xa7, 0xc9, 0x43, 0x7d, 0xd8, 0xd9, 0xe7, 0x67, 0x1b, 0x0a,
+       0x2a, 0x35, 0xe7, 0xaa, 0x4a, 0x8e, 0xe3, 0x68, 0xe4, 0x00, 0xca, 0x47,
+       0xbf, 0x4f, 0x9e, 0xe7, 0xc3, 0xc6, 0xbe, 0x22, 0x79, 0x4f, 0x08, 0xbd,
+       0x51, 0x0b, 0xef, 0xe9, 0xe3, 0x28, 0xa3, 0xbc, 0xae, 0xbe, 0x0a, 0x74,
+       0x6f, 0xf3, 0x50, 0x66, 0x05, 0x1e, 0xdb, 0x56, 0x1a, 0x2f, 0x32, 0x44,
+       0xde, 0x12, 0xfc, 0x74, 0xe4, 0x6b, 0xd8, 0x34, 0xe6, 0x41, 0x0f, 0xef,
+       0xaf, 0xdb, 0xe6, 0x75, 0xbf, 0xc0, 0x3a, 0xed, 0x6c, 0xeb, 0xbf, 0xf1,
+       0xf3, 0x01, 0xfb, 0x5d, 0x1c, 0x59, 0x83, 0xcd, 0x63, 0xc2, 0x6d, 0x8e,
+       0xc2, 0x3f, 0xda, 0x8a, 0x97, 0x47, 0xda, 0xf0, 0xb7, 0x23, 0xff, 0xea,
+       0x41, 0xc5, 0x32, 0xdc, 0x3f, 0x22, 0xfb, 0xee, 0x71, 0xdc, 0x93, 0x10,
+       0x3c, 0x5a, 0x89, 0x3d, 0x09, 0xd9, 0xbf, 0x6c, 0xc7, 0xb3, 0x09, 0xb1,
+       0xdf, 0xe5, 0xb4, 0xdf, 0x0e, 0xe6, 0x74, 0x92, 0x47, 0x64, 0x22, 0xf5,
+       0xa3, 0xdf, 0x8e, 0x5c, 0x33, 0xfa, 0x73, 0x72, 0xf0, 0xa1, 0x48, 0x68,
+       0x74, 0x27, 0xc7, 0x39, 0x49, 0x5e, 0x7d, 0x82, 0x5c, 0xfb, 0x75, 0x72,
+       0xe1, 0x42, 0x1c, 0xfc, 0xaf, 0xce, 0x5c, 0x8e, 0x52, 0xc8, 0x03, 0x0b,
+       0x6b, 0xed, 0x96, 0xe5, 0x60, 0x9e, 0xb3, 0xd0, 0x2b, 0xb9, 0x42, 0x17,
+       0xd6, 0xef, 0x58, 0x8d, 0x0d, 0x3b, 0x1a, 0xbc, 0x7b, 0x19, 0xb3, 0x62,
+       0x3e, 0xe1, 0xee, 0xf9, 0xfc, 0xee, 0xfc, 0x1a, 0x98, 0xac, 0xd9, 0x77,
+       0xd0, 0xe7, 0xd7, 0xd9, 0xe7, 0x38, 0x4b, 0x35, 0x04, 0x4a, 0xb4, 0xdf,
+       0x5a, 0xb1, 0xf3, 0xf5, 0xdb, 0x2d, 0x59, 0x97, 0x2d, 0x36, 0x14, 0x8c,
+       0x69, 0x6d, 0xf6, 0x7e, 0xd8, 0x71, 0x9b, 0x8f, 0x75, 0x21, 0x35, 0x4c,
+       0x6e, 0xbc, 0x4b, 0xc6, 0xb1, 0x52, 0xc6, 0x61, 0xaa, 0xda, 0x32, 0x6b,
+       0x5d, 0x0a, 0xb7, 0x16, 0x31, 0xbf, 0x58, 0x35, 0x52, 0x84, 0xf8, 0x9e,
+       0x52, 0xdc, 0xb3, 0x6d, 0xb9, 0x95, 0x4a, 0x09, 0xff, 0x96, 0x3c, 0xbb,
+       0x14, 0x9d, 0xbc, 0xb7, 0xa6, 0x4f, 0xf6, 0x21, 0x42, 0x1d, 0xb5, 0x8e,
+       0x52, 0x3c, 0xb4, 0x8b, 0xfd, 0xd8, 0xb5, 0x04, 0xf1, 0x5d, 0x47, 0x60,
+       0x66, 0x54, 0x8c, 0x0c, 0x38, 0xe1, 0x37, 0x4e, 0x93, 0x6f, 0xfd, 0x0c,
+       0xc9, 0x21, 0x15, 0xd9, 0x01, 0x45, 0xdb, 0x18, 0x1a, 0xc5, 0xc6, 0x21,
+       0x27, 0xf6, 0x26, 0x5a, 0xf0, 0x36, 0x71, 0x6e, 0x30, 0x11, 0xc3, 0x71,
+       0xea, 0x76, 0x72, 0xcf, 0x32, 0x7e, 0x3c, 0xf4, 0xf7, 0x83, 0xf4, 0x9d,
+       0x30, 0xba, 0xe9, 0x47, 0x07, 0x13, 0x1a, 0x1e, 0xcb, 0xde, 0x0c, 0x73,
+       0xe8, 0x0e, 0x6c, 0x1e, 0x32, 0xf1, 0xe8, 0x8e, 0x36, 0x7e, 0x1b, 0x78,
+       0x74, 0xe8, 0x6b, 0x58, 0x33, 0x72, 0x14, 0x9b, 0xb2, 0x71, 0xbc, 0x33,
+       0xf2, 0x2c, 0x92, 0x69, 0x9d, 0xbe, 0x21, 0xdc, 0x4d, 0xc1, 0xe6, 0x79,
+       0xcf, 0x62, 0x73, 0xe6, 0x30, 0x36, 0xa6, 0x3b, 0xc9, 0x09, 0x0f, 0x63,
+       0x03, 0x7f, 0xaf, 0x4f, 0x6b, 0xfe, 0x41, 0x1c, 0x46, 0x77, 0x66, 0x2d,
+       0x3a, 0xfb, 0x44, 0x5f, 0x0a, 0xce, 0xde, 0xb0, 0x16, 0x0f, 0xef, 0xea,
+       0xc0, 0x03, 0x23, 0x3f, 0xc0, 0xce, 0xec, 0xb3, 0xe8, 0x4d, 0x27, 0x90,
+       0xda, 0x2a, 0xfa, 0xac, 0xc4, 0x0f, 0x22, 0x78, 0xa0, 0x12, 0xa1, 0xb6,
+       0xa4, 0x22, 0xb2, 0xd6, 0x60, 0x13, 0xfd, 0x7a, 0x63, 0x4a, 0xf4, 0xfb,
+       0x34, 0xdb, 0x3c, 0x40, 0xbc, 0x58, 0x43, 0x7d, 0x3c, 0xc2, 0x4f, 0x61,
+       0xcf, 0x76, 0xea, 0x3e, 0x83, 0xf8, 0x8b, 0xdf, 0xce, 0xe5, 0x4b, 0x7b,
+       0x25, 0xaf, 0x1c, 0x0f, 0x96, 0x92, 0x8b, 0x94, 0xf4, 0x8a, 0x3e, 0xdb,
+       0xad, 0xae, 0xd4, 0xf8, 0x67, 0x4b, 0x20, 0x73, 0x10, 0x20, 0x76, 0xff,
+       0x0c, 0xeb, 0xe9, 0x8f, 0xb7, 0xca, 0xe1, 0x15, 0xc6, 0xa1, 0x43, 0xf4,
+       0xe7, 0xb8, 0xcf, 0xb2, 0x9e, 0xd2, 0x59, 0xad, 0xb7, 0x83, 0x78, 0xe5,
+       0xca, 0xef, 0xc5, 0x8d, 0x5f, 0x5b, 0x41, 0x19, 0xe5, 0xbd, 0x5d, 0x72,
+       0xe6, 0x45, 0xcf, 0xe5, 0xbc, 0x96, 0xb5, 0x25, 0x54, 0xb0, 0x9f, 0xf1,
+       0x6b, 0xcb, 0x31, 0x4d, 0xd6, 0x8f, 0x9b, 0x73, 0xef, 0xc1, 0x9d, 0x63,
+       0x5c, 0xec, 0xc2, 0x96, 0xe1, 0xb6, 0xbc, 0x1d, 0xfd, 0xbf, 0x92, 0x77,
+       0xb9, 0x3d, 0xbe, 0x6b, 0xec, 0x75, 0x1f, 0xd8, 0x67, 0xea, 0x81, 0x7b,
+       0x13, 0xb2, 0x6f, 0xa2, 0xde, 0x40, 0x56, 0x45, 0x0b, 0x2d, 0xc6, 0x61,
+       0xfd, 0x4a, 0x74, 0x93, 0x77, 0xde, 0xa2, 0x17, 0x61, 0xb8, 0xd1, 0xc0,
+       0xa4, 0xd7, 0x6c, 0x13, 0xce, 0x56, 0x66, 0x8c, 0xb7, 0x7f, 0x39, 0x14,
+       0x94, 0xbc, 0x10, 0x61, 0x62, 0x08, 0x6c, 0xce, 0xd6, 0x83, 0x64, 0x4a,
+       0x81, 0x47, 0xbb, 0x03, 0xd9, 0x2a, 0x9f, 0xb4, 0x1f, 0x2e, 0x9c, 0xbf,
+       0x2c, 0xd6, 0xce, 0xe5, 0xdf, 0x7d, 0x5b, 0xc2, 0xf9, 0xa0, 0x6d, 0xcf,
+       0xb4, 0xac, 0xb6, 0x48, 0x00, 0xf5, 0xa1, 0x86, 0x40, 0x95, 0xfa, 0x0b,
+       0xcb, 0x94, 0x3d, 0xa9, 0x31, 0x39, 0x0f, 0x78, 0xb9, 0xfc, 0xfd, 0x21,
+       0x6c, 0xdc, 0x3a, 0x07, 0x93, 0x3e, 0x91, 0xf9, 0x44, 0x79, 0x4e, 0x8e,
+       0xac, 0x5f, 0xbc, 0x5a, 0x81, 0xd2, 0x1e, 0xfa, 0x4a, 0x0f, 0x7a, 0x52,
+       0x2a, 0xdb, 0x78, 0xd3, 0x2a, 0x9e, 0x2e, 0xe3, 0xfe, 0x1f, 0x15, 0xb9,
+       0x32, 0xaf, 0x55, 0x08, 0xbf, 0xd8, 0x94, 0xea, 0xa1, 0xee, 0x54, 0xc6,
+       0x9b, 0x7f, 0xb1, 0x8e, 0xf8, 0xaa, 0xf9, 0x3c, 0x9e, 0x97, 0xb1, 0x4e,
+       0xd6, 0xd1, 0xf4, 0x18, 0xe4, 0xde, 0x2b, 0x2c, 0x2b, 0xfa, 0xea, 0xa1,
+       0x1e, 0x1c, 0xe4, 0x9e, 0x3e, 0x74, 0x7a, 0x73, 0x6b, 0x34, 0x17, 0xc6,
+       0x21, 0x65, 0x64, 0x2c, 0x3d, 0x48, 0xa5, 0x64, 0x1f, 0xe3, 0xac, 0x75,
+       0x6a, 0xba, 0x3c, 0x2f, 0xc9, 0xb7, 0x57, 0x6b, 0xef, 0xad, 0x3d, 0x9a,
+       0x72, 0x4c, 0xe9, 0x9b, 0xd4, 0xb5, 0x65, 0xb3, 0xfe, 0xa7, 0x2e, 0x69,
+       0xd7, 0x6b, 0x73, 0x72, 0xd5, 0x9e, 0xa7, 0x57, 0xf2, 0xe5, 0xcb, 0xcb,
+       0x0b, 0xef, 0x2f, 0xc8, 0xd9, 0xde, 0x0b, 0x6d, 0x4f, 0x2d, 0x23, 0x6b,
+       0x01, 0xb9, 0xba, 0xcd, 0x3b, 0x0a, 0xf2, 0x2d, 0xab, 0x68, 0x6e, 0x3b,
+       0x6d, 0xd4, 0xea, 0x2c, 0x26, 0x46, 0xbe, 0x1d, 0xf5, 0x63, 0x7d, 0x42,
+       0x74, 0xa4, 0xf9, 0xf7, 0x12, 0x03, 0xba, 0x6d, 0x4e, 0xe1, 0x42, 0x57,
+       0xa6, 0x70, 0xde, 0x44, 0xd6, 0x3d, 0xe5, 0xdc, 0x9a, 0xbc, 0x87, 0x43,
+       0x2e, 0xe5, 0x5d, 0x10, 0x70, 0x92, 0x0f, 0xdd, 0x8b, 0xff, 0xe0, 0x5c,
+       0xc8, 0xfb, 0x24, 0xb9, 0x35, 0x91, 0x38, 0x6d, 0x20, 0x17, 0x93, 0x40,
+       0x5f, 0x27, 0x17, 0xca, 0x9f, 0xb3, 0xef, 0xca, 0xfe, 0x87, 0x35, 0x6e,
+       0x9f, 0xb3, 0xbf, 0x70, 0xa6, 0x23, 0xe3, 0x95, 0x77, 0x39, 0x31, 0xe5,
+       0xcc, 0x3d, 0x63, 0x88, 0x26, 0x67, 0xf3, 0x7f, 0x67, 0xad, 0xb8, 0xa8,
+       0xec, 0x78, 0x55, 0xee, 0x1d, 0x94, 0x98, 0xba, 0x40, 0x2b, 0xf0, 0x3b,
+       0xd9, 0x57, 0x12, 0x5e, 0x77, 0x77, 0x65, 0x6e, 0xbd, 0x35, 0xd8, 0xda,
+       0x06, 0xd9, 0xdb, 0x2e, 0xf0, 0x35, 0x4d, 0x9f, 0xad, 0x74, 0x62, 0x56,
+       0xa4, 0x54, 0xde, 0xa9, 0x0d, 0x3a, 0x8d, 0xa0, 0xf7, 0x24, 0x42, 0xe1,
+       0xc3, 0xf6, 0x59, 0x0c, 0xf1, 0x6d, 0x0d, 0xf7, 0x66, 0x1b, 0xa9, 0x1b,
+       0x79, 0x1f, 0x5a, 0x7e, 0xdb, 0xf2, 0xf9, 0x1b, 0xee, 0x72, 0x62, 0xfb,
+       0x48, 0xd2, 0xfc, 0xaf, 0x2e, 0x5b, 0x5e, 0xb0, 0x7d, 0xc8, 0x7e, 0x57,
+       0xa9, 0x20, 0xcf, 0x73, 0x19, 0x79, 0x61, 0xd6, 0x0f, 0x53, 0x96, 0xc8,
+       0xd0, 0x28, 0xe3, 0xd2, 0xf3, 0x39, 0xd3, 0xe3, 0x92, 0x23, 0xef, 0xcb,
+       0xf3, 0xbe, 0xc3, 0x7f, 0x90, 0x23, 0x5f, 0xb6, 0xcd, 0x18, 0xdb, 0x6c,
+       0x2d, 0x55, 0x62, 0x11, 0x79, 0x57, 0xa8, 0x38, 0x12, 0x0a, 0x3f, 0x47,
+       0xe7, 0x74, 0x1a, 0x21, 0xff, 0x90, 0x7d, 0x66, 0x44, 0x77, 0x2f, 0xcc,
+       0xe6, 0xf2, 0x29, 0x73, 0xec, 0x93, 0x75, 0x52, 0xa6, 0x69, 0x6d, 0x0d,
+       0x4a, 0xec, 0x46, 0x22, 0x38, 0xc2, 0x11, 0x04, 0x8a, 0x8c, 0x82, 0x8e,
+       0x42, 0xe1, 0x93, 0x9c, 0xcf, 0x89, 0x68, 0x88, 0x78, 0x29, 0x5c, 0x49,
+       0xf4, 0xa2, 0xbb, 0x73, 0x73, 0xdf, 0x28, 0x9c, 0xda, 0x74, 0x31, 0xee,
+       0x0d, 0x27, 0x64, 0x9d, 0xab, 0xc1, 0xbb, 0x11, 0x55, 0xb4, 0x57, 0xc4,
+       0xba, 0x1b, 0xe3, 0xd8, 0x97, 0x40, 0xcc, 0x31, 0xa7, 0x12, 0x71, 0x92,
+       0x64, 0x87, 0x16, 0x27, 0xef, 0x69, 0x08, 0x6f, 0xa2, 0x0d, 0xca, 0xd9,
+       0x46, 0x13, 0x71, 0x1c, 0x4a, 0x2c, 0xf8, 0x4b, 0x07, 0x4c, 0xbd, 0x0c,
+       0xf2, 0xae, 0x16, 0xbe, 0x78, 0x5b, 0x28, 0x18, 0x78, 0x3e, 0x7f, 0xe6,
+       0xa5, 0x2b, 0xf1, 0x91, 0xbd, 0xa7, 0xe5, 0xd0, 0x3e, 0xa9, 0x8c, 0xdb,
+       0x5e, 0xc7, 0xdd, 0x9b, 0xfe, 0x36, 0xd6, 0x6d, 0x65, 0x1f, 0x99, 0xdf,
+       0x2f, 0xd0, 0x3b, 0xb1, 0x50, 0xf7, 0x60, 0xa5, 0x77, 0x56, 0xb3, 0x9c,
+       0xe9, 0x19, 0xcc, 0xe4, 0xd6, 0x3d, 0xd6, 0xdb, 0x67, 0x6a, 0x06, 0xb0,
+       0x99, 0x3e, 0x56, 0xa2, 0xc9, 0xb9, 0xab, 0x98, 0xb2, 0x39, 0xdb, 0xa2,
+       0x6c, 0xca, 0xaf, 0xb3, 0xf5, 0x64, 0x5f, 0xaf, 0x44, 0xa9, 0x89, 0xe3,
+       0xba, 0xbc, 0x23, 0x29, 0x72, 0x4d, 0x0c, 0x45, 0xff, 0x94, 0x77, 0x25,
+       0x45, 0xa7, 0x6b, 0xd0, 0x3d, 0xf0, 0x08, 0xba, 0x06, 0x5e, 0xb4, 0xcf,
+       0xb6, 0xba, 0x34, 0xb7, 0x79, 0xb5, 0x11, 0x3c, 0x60, 0xe2, 0x69, 0xaf,
+       0xac, 0xe7, 0xd6, 0x18, 0x47, 0xb1, 0xd9, 0x2b, 0xef, 0x00, 0x0e, 0x90,
+       0x03, 0x08, 0xce, 0x2d, 0xc7, 0x97, 0x93, 0x32, 0x87, 0x15, 0xc4, 0xfc,
+       0x60, 0x6c, 0xa5, 0x3d, 0x87, 0x8d, 0x38, 0x36, 0xfa, 0x08, 0xde, 0xde,
+       0xde, 0x09, 0x35, 0x12, 0xf4, 0x2f, 0x82, 0xd5, 0x79, 0x44, 0x8f, 0x99,
+       0x2e, 0x04, 0xf7, 0x39, 0x54, 0xe0, 0xe0, 0x76, 0xc9, 0x69, 0xdb, 0x71,
+       0x23, 0x63, 0x6d, 0xa5, 0x66, 0xcd, 0xff, 0xb7, 0xb9, 0xc1, 0x1e, 0xcd,
+       0x61, 0xfe, 0xf3, 0x74, 0x04, 0xd3, 0xcd, 0xaa, 0xd6, 0x7e, 0xa7, 0x0a,
+       0xc5, 0x63, 0xc8, 0x7b, 0xeb, 0x9d, 0xb8, 0xa3, 0xc9, 0x63, 0x96, 0x1b,
+       0xc1, 0xf4, 0x8b, 0x4a, 0x30, 0x6c, 0xaa, 0x9f, 0xe7, 0x3c, 0x87, 0xf1,
+       0xfc, 0xa8, 0x17, 0xad, 0xbd, 0x3a, 0x16, 0xf7, 0x36, 0xda, 0xb8, 0xa5,
+       0x6a, 0xf5, 0xcd, 0x25, 0x8a, 0x17, 0x8b, 0x46, 0x81, 0x89, 0xcc, 0x72,
+       0xbc, 0xb9, 0x5d, 0x47, 0x0b, 0x9f, 0xf5, 0xa5, 0x9e, 0xaa, 0x94, 0xb3,
+       0x6f, 0x1d, 0xba, 0xd9, 0xa0, 0x22, 0x74, 0xd4, 0xa5, 0x62, 0xc1, 0x0c,
+       0x23, 0x34, 0x3e, 0xdf, 0xe1, 0x44, 0xf3, 0xa8, 0x13, 0x77, 0xb1, 0xcc,
+       0x46, 0x62, 0xfa, 0x9d, 0xbd, 0x6e, 0xf2, 0x87, 0x3a, 0x7c, 0x48, 0xae,
+       0xfb, 0x2b, 0x72, 0xda, 0x49, 0xc6, 0xe6, 0xc9, 0x6c, 0x29, 0xda, 0xfa,
+       0x5d, 0x72, 0x8e, 0x67, 0xdc, 0xc5, 0xb9, 0xa8, 0x68, 0xf2, 0xe1, 0xd4,
+       0x90, 0x1b, 0x9f, 0xdb, 0x1e, 0xdc, 0x39, 0xa9, 0xd6, 0xe0, 0x83, 0xa1,
+       0x52, 0x7b, 0xbd, 0xb2, 0xdc, 0xb0, 0xb0, 0x85, 0x38, 0xfd, 0x1e, 0x9f,
+       0xb5, 0x6c, 0x87, 0x92, 0x9d, 0x77, 0x0d, 0x79, 0xb9, 0xc6, 0xfa, 0x65,
+       0xb8, 0xad, 0x5f, 0xd6, 0x68, 0x54, 0xbc, 0x33, 0xa4, 0xe0, 0x64, 0x46,
+       0xc7, 0x02, 0xb6, 0xd7, 0x9d, 0x3a, 0x68, 0xb9, 0xe9, 0xe7, 0x2b, 0xb2,
+       0x3a, 0xee, 0xcb, 0x34, 0xa2, 0x37, 0xf5, 0x06, 0x39, 0x50, 0x13, 0xde,
+       0xd8, 0xa6, 0x1d, 0x7d, 0xcb, 0x11, 0x1a, 0x9f, 0xe7, 0x68, 0xc2, 0xeb,
+       0x7b, 0x9a, 0xf0, 0xc3, 0xbe, 0xf9, 0xf8, 0x74, 0x53, 0x0c, 0xa7, 0xe7,
+       0x35, 0xe1, 0x95, 0x5d, 0x8d, 0xc4, 0xe8, 0x28, 0x02, 0x23, 0xe3, 0xd8,
+       0x92, 0x6c, 0x46, 0xc3, 0x88, 0x01, 0xad, 0xcf, 0xea, 0x2c, 0x33, 0x3a,
+       0xb1, 0x59, 0x37, 0x30, 0x7b, 0x97, 0xe8, 0xc1, 0xb2, 0x56, 0xce, 0x33,
+       0xf0, 0x5c, 0x5a, 0xa3, 0x9f, 0x1a, 0xd4, 0x43, 0x23, 0x71, 0xd6, 0x40,
+       0x68, 0xab, 0x76, 0x66, 0x37, 0xaf, 0xe7, 0xef, 0x8e, 0xa2, 0x9d, 0xed,
+       0x27, 0x52, 0x31, 0xec, 0x1c, 0x69, 0xe4, 0x98, 0x75, 0x8e, 0xbf, 0xde,
+       0xfc, 0x50, 0x69, 0x41, 0x7a, 0xa4, 0x15, 0xbd, 0x7d, 0x9d, 0x78, 0x31,
+       0xd2, 0x8a, 0x24, 0x65, 0xad, 0x4f, 0xe9, 0xb8, 0xad, 0xb7, 0x15, 0xfb,
+       0x13, 0x72, 0x96, 0x5e, 0x6b, 0xbe, 0x5e, 0x09, 0xe9, 0x27, 0xd1, 0x8a,
+       0xbd, 0xd4, 0xc9, 0x82, 0xfe, 0x25, 0xf6, 0xb9, 0xa1, 0x85, 0xdb, 0x1b,
+       0xf1, 0x58, 0xea, 0x0e, 0xbc, 0x39, 0xac, 0xa3, 0xad, 0x57, 0xf4, 0x2d,
+       0xe7, 0x27, 0xe3, 0x38, 0x92, 0x5a, 0x8b, 0x0f, 0xfb, 0x63, 0xff, 0xcc,
+       0x69, 0x3e, 0xa6, 0xda, 0xfb, 0x5d, 0x2a, 0xae, 0x6b, 0x92, 0x73, 0xad,
+       0x0e, 0xa2, 0x5a, 0xd0, 0xac, 0x54, 0xcd, 0x00, 0xef, 0x9b, 0x4e, 0x75,
+       0x2d, 0xfe, 0xb6, 0xdf, 0x49, 0xde, 0xae, 0x32, 0xdf, 0x30, 0x3b, 0x68,
+       0x1b, 0x66, 0x85, 0x9a, 0x9b, 0x37, 0x7b, 0x7f, 0x40, 0x73, 0x40, 0xce,
+       0xbd, 0x96, 0xb1, 0xde, 0xe2, 0x48, 0x30, 0x56, 0xa2, 0x46, 0xc9, 0x27,
+       0x1e, 0xc1, 0xca, 0xed, 0x8f, 0x60, 0x05, 0x3f, 0x1d, 0xdb, 0xad, 0xce,
+       0x5b, 0x75, 0x05, 0x87, 0x34, 0xab, 0xb3, 0x53, 0xd7, 0x38, 0xb7, 0x32,
+       0xaf, 0x8f, 0x60, 0xcd, 0xde, 0x47, 0xf0, 0x15, 0xda, 0x57, 0x35, 0xfd,
+       0x78, 0x69, 0xaf, 0xd5, 0xf9, 0xe9, 0xa6, 0x30, 0x7e, 0x6d, 0xe7, 0x18,
+       0x62, 0xaf, 0x5b, 0xec, 0xbc, 0x37, 0xa3, 0xca, 0xef, 0xbf, 0xb7, 0x7f,
+       0x9b, 0xea, 0x2b, 0xf9, 0xbd, 0xa8, 0x35, 0xf8, 0x88, 0x72, 0x7f, 0xb3,
+       0xbd, 0x12, 0x5b, 0xab, 0x25, 0x66, 0xb8, 0xcd, 0x12, 0x03, 0x8a, 0x36,
+       0x8f, 0xb9, 0xd4, 0xd6, 0x23, 0x36, 0xdf, 0xf2, 0x45, 0x24, 0xcf, 0x6d,
+       0xd0, 0xd7, 0xa9, 0x37, 0x13, 0xdb, 0xc9, 0xc5, 0x66, 0x7e, 0x1b, 0x49,
+       0xfa, 0xea, 0x96, 0x99, 0xc1, 0x78, 0x12, 0x86, 0xb5, 0x65, 0xfa, 0xc0,
+       0x9f, 0xf1, 0x7e, 0x6c, 0x61, 0xdf, 0x4d, 0xde, 0x91, 0x7d, 0x04, 0x9d,
+       0xdb, 0x65, 0xfe, 0x1f, 0xc1, 0xc3, 0xec, 0xff, 0x9a, 0xfe, 0x47, 0xf0,
+       0x10, 0x6d, 0xa7, 0x6a, 0xee, 0xc4, 0xc3, 0x55, 0x98, 0xc5, 0x4c, 0x68,
+       0xfc, 0x81, 0x6a, 0x39, 0xf3, 0x4a, 0x4c, 0x4c, 0x2a, 0x8f, 0xe0, 0xde,
+       0xc1, 0xfd, 0xf4, 0x45, 0xdb, 0xff, 0x88, 0xc5, 0x85, 0x78, 0xe5, 0xc7,
+       0xca, 0x6c, 0x5d, 0x1e, 0xd7, 0x7d, 0x58, 0x91, 0x78, 0xd2, 0xf6, 0xfd,
+       0x22, 0x63, 0x09, 0xfd, 0xbe, 0x95, 0x7e, 0xdf, 0x42, 0xbf, 0x8f, 0xd1,
+       0xef, 0x0d, 0xfa, 0x7d, 0x33, 0xfd, 0x3e, 0x4a, 0xbf, 0xd7, 0xe9, 0xf7,
+       0x8d, 0xf4, 0xfb, 0xb0, 0xec, 0x47, 0x28, 0x47, 0xa3, 0x47, 0xe0, 0xea,
+       0x73, 0xd3, 0x86, 0x72, 0xef, 0x3d, 0xee, 0x21, 0xfe, 0x1c, 0xd7, 0x67,
+       0xfb, 0x6f, 0x61, 0x2c, 0x1d, 0x22, 0x46, 0x64, 0x86, 0xbf, 0x6d, 0xbf,
+       0x23, 0x97, 0x21, 0xee, 0x3f, 0x4f, 0x7d, 0x2c, 0x8e, 0xd4, 0xeb, 0xfb,
+       0x19, 0xc3, 0x7e, 0xa4, 0x35, 0xf4, 0xf8, 0x58, 0xe6, 0xbb, 0xa9, 0x86,
+       0xf4, 0x34, 0x68, 0x66, 0x93, 0xba, 0x1e, 0x58, 0xea, 0xe3, 0x98, 0x65,
+       0xbf, 0x6e, 0x29, 0x1e, 0x1e, 0x68, 0xc3, 0xdf, 0x0d, 0x78, 0xa9, 0x8b,
+       0xfa, 0xf1, 0x9b, 0x1d, 0xf8, 0xbe, 0x1f, 0x0e, 0xdf, 0x15, 0xc0, 0x7f,
+       0xd6, 0x60, 0xf6, 0x3e, 0x79, 0xcf, 0x3a, 0x53, 0xe3, 0x68, 0x9c, 0x01,
+       0xb1, 0x11, 0x10, 0xa9, 0x1d, 0xcc, 0xf6, 0x66, 0xdb, 0xef, 0x74, 0xc6,
+       0x96, 0x09, 0xa6, 0x97, 0x60, 0x7d, 0xd8, 0xc6, 0xd9, 0x27, 0x65, 0xff,
+       0xb0, 0x86, 0x78, 0xe4, 0x31, 0x5a, 0xb1, 0x21, 0x69, 0x7e, 0xb1, 0x86,
+       0x5c, 0xa9, 0x27, 0x99, 0xd3, 0xc1, 0x03, 0x11, 0xaa, 0xc4, 0x90, 0xff,
+       0x19, 0x01, 0x67, 0x47, 0xb4, 0x19, 0xf7, 0x65, 0x77, 0x22, 0xcd, 0xb1,
+       0xae, 0xa2, 0x9f, 0xad, 0xfc, 0xe3, 0xef, 0xc5, 0xe3, 0xa1, 0x44, 0x80,
+       0xf6, 0x7f, 0xce, 0xca, 0x54, 0xcd, 0x4e, 0xd7, 0x40, 0x5b, 0x73, 0x97,
+       0x7a, 0x3d, 0xf3, 0xd6, 0xe0, 0x01, 0x3e, 0x32, 0xa7, 0xdb, 0xe7, 0xd1,
+       0xdc, 0xb8, 0xa6, 0x1f, 0xca, 0x50, 0xaf, 0xbc, 0xd7, 0xd6, 0x89, 0xbf,
+       0xd1, 0x3f, 0x6f, 0xdb, 0xcf, 0xb8, 0xc3, 0x8b, 0x19, 0xbd, 0x72, 0xdf,
+       0x9a, 0x7f, 0x76, 0x6e, 0x30, 0x1c, 0x70, 0x3c, 0x54, 0x29, 0xfb, 0x12,
+       0xcf, 0x30, 0xce, 0xfa, 0xfb, 0xe7, 0x43, 0x9d, 0xeb, 0xc6, 0xdd, 0x8d,
+       0xe5, 0x88, 0x2f, 0x15, 0x0e, 0x69, 0xef, 0x9b, 0x50, 0x9f, 0x7f, 0x8d,
+       0xfb, 0xf5, 0xa7, 0xc8, 0xd7, 0x76, 0xa2, 0x9f, 0xf8, 0xb5, 0x52, 0xff,
+       0x9c, 0x62, 0xf2, 0xf7, 0x86, 0x94, 0x89, 0x55, 0xfa, 0x6d, 0xc0, 0x5f,
+       0x54, 0xa3, 0x74, 0xbb, 0x94, 0x17, 0xb9, 0x5b, 0x6c, 0x79, 0x7b, 0x52,
+       0xf2, 0xfb, 0xef, 0xf3, 0x6d, 0xde, 0x09, 0x54, 0xbb, 0xed, 0x3c, 0xe7,
+       0x57, 0x33, 0x77, 0x62, 0x6b, 0x0a, 0xdf, 0xaf, 0x44, 0x7d, 0xa6, 0x4f,
+       0x75, 0x7c, 0xff, 0x0a, 0xcc, 0x4e, 0xff, 0x56, 0x95, 0xf9, 0x88, 0xe1,
+       0xbe, 0x99, 0x0a, 0x71, 0x4d, 0x3b, 0x7d, 0x97, 0x1a, 0x34, 0xc7, 0x41,
+       0xf9, 0x63, 0x2f, 0x5a, 0xe3, 0x57, 0xf8, 0xb0, 0x6f, 0x4c, 0xea, 0xb6,
+       0xc1, 0xe2, 0x9c, 0xec, 0xb7, 0xf7, 0xe2, 0x82, 0x47, 0x2d, 0x35, 0x00,
+       0x27, 0xef, 0x9d, 0x1d, 0xd2, 0x99, 0xc7, 0xb7, 0xe1, 0xdf, 0x06, 0x96,
+       0xe2, 0xb7, 0x03, 0xf5, 0x1d, 0x37, 0x28, 0x96, 0x75, 0x28, 0xf2, 0x59,
+       0xfc, 0xb8, 0xda, 0x8b, 0xdd, 0xe4, 0xff, 0xbf, 0x4d, 0x98, 0xb5, 0x57,
+       0x10, 0x0b, 0xfe, 0x3d, 0x11, 0x4c, 0x1f, 0x52, 0xed, 0x77, 0xc6, 0xf5,
+       0x85, 0x6a, 0x70, 0xe7, 0xaf, 0xd8, 0xc6, 0x7d, 0xea, 0x12, 0xfc, 0x3a,
+       0xdb, 0x8a, 0xd3, 0xd9, 0xa9, 0xb6, 0xd0, 0x69, 0xa1, 0x46, 0xec, 0x40,
+       0xec, 0x81, 0xb6, 0x98, 0xa2, 0x2d, 0x92, 0xdf, 0x76, 0x7d, 0x86, 0xf6,
+       0x48, 0x2c, 0xfa, 0x1e, 0x31, 0xea, 0x1f, 0x52, 0xb4, 0x47, 0xfa, 0xcd,
+       0x77, 0xe9, 0x37, 0xdf, 0xa1, 0xdf, 0x3c, 0x45, 0xbf, 0xc9, 0x71, 0xdb,
+       0x36, 0x7b, 0xbd, 0xfe, 0x65, 0xc6, 0xc4, 0xc4, 0xd6, 0x4e, 0x9c, 0x8a,
+       0xd4, 0xaf, 0x1a, 0x45, 0xb0, 0x3d, 0xa9, 0x58, 0x5e, 0xe1, 0x73, 0x5f,
+       0x0b, 0x89, 0x0f, 0xc8, 0xfb, 0x69, 0x7e, 0x3c, 0x3e, 0xdc, 0x59, 0x29,
+       0xef, 0xbb, 0xee, 0xd9, 0xf1, 0x71, 0x3a, 0xfb, 0x07, 0xf6, 0x43, 0xf4,
+       0xf5, 0xe7, 0x8e, 0x5d, 0x74, 0xf9, 0xcf, 0xd6, 0x8f, 0x6b, 0x64, 0xfc,
+       0xcb, 0xf0, 0xfb, 0x81, 0x16, 0x9c, 0x66, 0xfc, 0x7d, 0x7e, 0xee, 0xb8,
+       0xb7, 0x14, 0xc1, 0xb8, 0xaa, 0x1a, 0xc8, 0x66, 0x5b, 0x70, 0x26, 0x61,
+       0xe0, 0x89, 0x44, 0xfd, 0xaa, 0x32, 0xc7, 0xcf, 0xd5, 0x4c, 0xad, 0x58,
+       0x54, 0x0c, 0x27, 0x85, 0x5f, 0x86, 0xda, 0x50, 0x6c, 0x34, 0x63, 0x30,
+       0x2b, 0x76, 0xea, 0xc5, 0x5b, 0x51, 0x5d, 0xde, 0x2f, 0xfb, 0xa3, 0x7f,
+       0xf7, 0xd1, 0x1e, 0x5f, 0x95, 0xff, 0x27, 0xc1, 0x79, 0xf6, 0x1a, 0xcb,
+       0xe0, 0xdc, 0x2e, 0xef, 0xf8, 0x8b, 0x3f, 0x2b, 0xd8, 0xa4, 0x8f, 0x77,
+       0x94, 0x20, 0xf8, 0xe4, 0x4f, 0x68, 0xeb, 0x87, 0x7a, 0xe5, 0x2c, 0x6e,
+       0x0b, 0x7e, 0xc9, 0xf2, 0x95, 0xf4, 0x8b, 0x43, 0x59, 0xa7, 0xf3, 0xc7,
+       0xbd, 0xf2, 0x8e, 0xfa, 0x12, 0xfc, 0x38, 0x3b, 0xa1, 0x7e, 0xe4, 0xd5,
+       0xf1, 0xab, 0xd1, 0xa5, 0xb4, 0x27, 0xc9, 0xe5, 0x63, 0xcc, 0xe5, 0x83,
+       0xde, 0xc7, 0xb1, 0x14, 0xea, 0xde, 0x65, 0xf0, 0x6c, 0x97, 0xf7, 0x67,
+       0x96, 0xa1, 0x8c, 0xbf, 0xfd, 0xdb, 0x2d, 0xcb, 0x39, 0xb7, 0xd2, 0xda,
+       0xb8, 0x4c, 0xe6, 0x4e, 0xf0, 0xe4, 0xff, 0x7a, 0x65, 0x2d, 0x00, 0x7b,
+       0x45, 0xbe, 0x46, 0xf9, 0x4b, 0xe1, 0xde, 0x5e, 0x1f, 0x5e, 0x84, 0xfa,
+       0xd3, 0x2e, 0x65, 0x29, 0xae, 0xde, 0xab, 0x54, 0xa1, 0x54, 0xca, 0x86,
+       0x69, 0x7f, 0x26, 0xe4, 0x9c, 0x74, 0x4b, 0xef, 0xaf, 0xac, 0x19, 0x86,
+       0xbd, 0xbf, 0x86, 0x95, 0xa3, 0x1a, 0xe3, 0x5d, 0x29, 0xe2, 0x83, 0x8f,
+       0x59, 0x95, 0x86, 0x13, 0x2b, 0x46, 0x1b, 0x71, 0x4b, 0xbf, 0x65, 0x9d,
+       0x9a, 0x17, 0x83, 0xc7, 0xf0, 0x10, 0xc3, 0x3c, 0xf8, 0x4a, 0x6f, 0x19,
+       0xbf, 0x2d, 0x14, 0x31, 0x26, 0xcf, 0x52, 0xb5, 0x55, 0xb5, 0x0e, 0xad,
+       0x7d, 0x54, 0x91, 0xb8, 0xef, 0xc1, 0x83, 0x8c, 0xcf, 0x8b, 0x7b, 0xfd,
+       0x88, 0x8f, 0x5a, 0xd6, 0x2b, 0x51, 0x1f, 0x1e, 0x60, 0xfd, 0xd6, 0xde,
+       0x01, 0x74, 0xd1, 0x2e, 0xe2, 0x7b, 0xb5, 0x80, 0x97, 0xf1, 0x7e, 0xe5,
+       0xa8, 0x9b, 0x31, 0xac, 0x1a, 0x8b, 0xb6, 0x07, 0xf0, 0x95, 0x51, 0x0f,
+       0xe3, 0x9b, 0x35, 0xff, 0x4d, 0xdd, 0xbc, 0xd6, 0x01, 0x0d, 0x6b, 0x46,
+       0x7d, 0x58, 0xd2, 0x1b, 0x3c, 0x23, 0xef, 0x5a, 0x9f, 0xd5, 0xc3, 0x58,
+       0x3d, 0xea, 0xc7, 0xed, 0xbd, 0x13, 0x5f, 0x99, 0x01, 0xf3, 0xff, 0xab,
+       0x45, 0x23, 0xbe, 0x3c, 0x5a, 0x47, 0xf9, 0xc1, 0x55, 0x2f, 0x2b, 0x75,
+       0xf8, 0xdb, 0xbd, 0x3a, 0xe5, 0xab, 0xb8, 0x8d, 0x72, 0x6e, 0xed, 0xbd,
+       0x1a, 0x0f, 0xee, 0x8d, 0xe2, 0xbe, 0xd1, 0xb9, 0x58, 0xc8, 0xf8, 0xd4,
+       0xc1, 0xbc, 0x0e, 0x9f, 0x07, 0x6e, 0xef, 0x17, 0xdd, 0x43, 0x79, 0x25,
+       0x3a, 0x0e, 0x37, 0xe3, 0x1d, 0x0d, 0x91, 0xf7, 0x1a, 0xc9, 0xc1, 0x74,
+       0xdc, 0xbe, 0x6b, 0xae, 0xbd, 0x9f, 0x5e, 0x1f, 0x29, 0x46, 0xbc, 0x4d,
+       0x41, 0x4b, 0xbf, 0xc4, 0x59, 0xe1, 0x36, 0x3a, 0xe3, 0x6a, 0x88, 0x6d,
+       0xe8, 0x8c, 0xab, 0xb9, 0xfb, 0x5d, 0x29, 0x39, 0x6b, 0xf5, 0x06, 0xf9,
+       0x52, 0x04, 0x2d, 0x76, 0x8c, 0x76, 0x93, 0x5f, 0x9b, 0x70, 0x32, 0x76,
+       0x47, 0x68, 0xe3, 0xf3, 0x9b, 0x24, 0x56, 0x37, 0x32, 0x4f, 0x34, 0x30,
+       0xd6, 0xa7, 0x75, 0x9c, 0x51, 0x0c, 0x8c, 0xee, 0x92, 0x98, 0xe8, 0xc3,
+       0xea, 0x5e, 0x03, 0x6f, 0xca, 0x59, 0xfa, 0x39, 0xb1, 0xc5, 0x65, 0xd0,
+       0xf4, 0x07, 0x11, 0x32, 0x8f, 0x31, 0xb6, 0x9f, 0xce, 0x54, 0xe3, 0x96,
+       0xed, 0x52, 0xa6, 0x09, 0x6f, 0x0d, 0x39, 0x71, 0x4b, 0xef, 0x5a, 0x3c,
+       0x96, 0x76, 0x60, 0x50, 0xaf, 0xef, 0x51, 0x19, 0x3f, 0x6f, 0x6c, 0x0a,
+       0x7a, 0x9f, 0x21, 0x57, 0x3d, 0x33, 0x97, 0x51, 0xf9, 0x8a, 0x28, 0x5a,
+       0xd8, 0xaf, 0x16, 0x2d, 0x77, 0x96, 0xe2, 0xbe, 0xe8, 0x5a, 0x1c, 0x4b,
+       0x6b, 0xe6, 0x7e, 0xe6, 0xcb, 0xee, 0x26, 0x3e, 0x9f, 0xee, 0x44, 0xb7,
+       0x26, 0x9c, 0xb6, 0x91, 0xbe, 0x25, 0xeb, 0x2a, 0x51, 0xbc, 0x49, 0x7b,
+       0xed, 0xc9, 0xcc, 0x67, 0xec, 0x97, 0x98, 0x2f, 0x67, 0xfd, 0x4c, 0x54,
+       0xde, 0xa0, 0xe0, 0xf8, 0x6e, 0xe1, 0x58, 0xf3, 0xf1, 0x45, 0xea, 0xa9,
+       0xa5, 0x57, 0xc5, 0x8d, 0x7b, 0x97, 0xe3, 0xd4, 0xb6, 0x1c, 0xe7, 0x7a,
+       0x25, 0x62, 0x7e, 0x99, 0x9c, 0xab, 0xbd, 0x9c, 0x9c, 0x8b, 0x5c, 0x2e,
+       0xbc, 0x5a, 0x71, 0x22, 0x34, 0xda, 0x4c, 0x5e, 0x21, 0xfc, 0x82, 0xfe,
+       0x9a, 0x8d, 0x62, 0x51, 0x6f, 0x1d, 0x86, 0xc9, 0xb7, 0x32, 0xc4, 0x8b,
+       0x4c, 0x96, 0x71, 0x65, 0xa8, 0x86, 0x9f, 0x00, 0x3f, 0xd7, 0xf0, 0xa3,
+       0xd9, 0xf7, 0x56, 0xd0, 0x96, 0x63, 0x6d, 0x8a, 0x7d, 0xce, 0x7e, 0x30,
+       0x2b, 0xb1, 0x5a, 0x41, 0x95, 0xf6, 0x17, 0x55, 0x92, 0x67, 0x7a, 0x35,
+       0x05, 0xaf, 0xa5, 0x03, 0xf8, 0x6a, 0xd3, 0x5a, 0x25, 0x56, 0x6d, 0xbf,
+       0xa7, 0x6a, 0x96, 0xb2, 0x6f, 0x8b, 0xe6, 0xc9, 0x3a, 0x64, 0x98, 0x39,
+       0xaf, 0xfc, 0x8f, 0x02, 0x05, 0x0f, 0x30, 0x97, 0x0f, 0x54, 0x05, 0xe4,
+       0x1c, 0x14, 0xfd, 0xdd, 0x87, 0x17, 0x12, 0x71, 0x64, 0x13, 0x0d, 0x3d,
+       0xab, 0x15, 0xd9, 0xef, 0x09, 0x36, 0xc7, 0x95, 0x1c, 0xe7, 0x2f, 0x67,
+       0xdd, 0xdd, 0xf3, 0x3a, 0xd0, 0x41, 0x6e, 0x7f, 0x3a, 0xc7, 0xed, 0x03,
+       0x93, 0xe8, 0xc0, 0xca, 0x84, 0xec, 0x6f, 0xc6, 0xad, 0x2e, 0xce, 0xc1,
+       0xe1, 0x44, 0x07, 0xee, 0x4c, 0x34, 0x74, 0x10, 0x5a, 0x30, 0x7e, 0x57,
+       0x07, 0x5a, 0x12, 0xf5, 0xe3, 0x5b, 0xe5, 0x7f, 0x50, 0x4d, 0xd3, 0x70,
+       0x60, 0x4c, 0x45, 0xad, 0x16, 0x20, 0xf6, 0x07, 0x30, 0x98, 0x6a, 0x38,
+       0xd3, 0xa5, 0xde, 0xa9, 0x4c, 0x5e, 0x21, 0x39, 0x64, 0x33, 0x9e, 0x4f,
+       0x78, 0x50, 0x96, 0x34, 0x69, 0xfb, 0x40, 0xe9, 0x48, 0x94, 0xf9, 0xc3,
+       0x63, 0x56, 0x95, 0x11, 0x4a, 0x8b, 0x5e, 0x4a, 0x46, 0xe6, 0xe3, 0x0d,
+       0xc6, 0xdc, 0xfa, 0xeb, 0x35, 0xef, 0x42, 0x1b, 0x8b, 0x7e, 0x65, 0xd5,
+       0x1a, 0x65, 0x98, 0xb1, 0x2b, 0xd4, 0xdc, 0xc2, 0xf8, 0xda, 0x7c, 0x03,
+       0xed, 0x80, 0xb1, 0xaf, 0xd2, 0xd8, 0xc9, 0x39, 0x16, 0x7b, 0xf2, 0xa0,
+       0x7c, 0xc4, 0x47, 0x1c, 0xa2, 0xe8, 0x11, 0x0d, 0x7b, 0xd9, 0x2f, 0xef,
+       0x88, 0x9c, 0x0b, 0x0a, 0xb6, 0xdf, 0x27, 0xff, 0x53, 0x64, 0x4f, 0xee,
+       0xfc, 0xe1, 0xfb, 0x89, 0xcf, 0x40, 0x92, 0x51, 0xcf, 0x88, 0x07, 0x1f,
+       0x26, 0xe4, 0x0c, 0x1f, 0x69, 0xcd, 0x48, 0x00, 0x55, 0xac, 0xfb, 0x66,
+       0xa2, 0x3e, 0xfd, 0xdf, 0x51, 0x1f, 0xb8, 0x55, 0xad, 0xb4, 0xcf, 0x0a,
+       0x39, 0x47, 0x6e, 0xc2, 0x89, 0x74, 0x70, 0x9c, 0x79, 0xf4, 0xaa, 0x76,
+       0xaa, 0x98, 0xb9, 0xae, 0x79, 0x8d, 0xd2, 0xd0, 0xa1, 0xaa, 0xc1, 0xf0,
+       0xa8, 0x02, 0xca, 0x73, 0xb2, 0x8d, 0x9b, 0xf0, 0x76, 0xba, 0x14, 0x45,
+       0xbb, 0x76, 0xd2, 0xee, 0x8b, 0xb0, 0x78, 0x9b, 0x1b, 0x25, 0x7b, 0xc4,
+       0x56, 0x45, 0xaf, 0x92, 0xef, 0x83, 0xb6, 0x6a, 0x62, 0x6f, 0x74, 0x39,
+       0x9e, 0x1f, 0x90, 0x7d, 0xf4, 0x0b, 0x1c, 0xbc, 0x2d, 0x62, 0xde, 0xae,
+       0x32, 0x06, 0xad, 0x4f, 0x85, 0xe2, 0x25, 0xb4, 0x09, 0x87, 0x11, 0x6a,
+       0xef, 0xe6, 0xd8, 0x1b, 0x46, 0xc5, 0xce, 0x9a, 0xf1, 0x1d, 0x8e, 0xa5,
+       0x9f, 0x36, 0x31, 0x9c, 0xa8, 0xc3, 0x46, 0xda, 0x84, 0x49, 0x9b, 0x30,
+       0x39, 0xff, 0x26, 0x6d, 0xc2, 0xa4, 0x4d, 0x98, 0xb4, 0x09, 0x93, 0x36,
+       0x61, 0x66, 0xe7, 0x63, 0x5f, 0x5a, 0x45, 0xcf, 0x50, 0x19, 0xe2, 0xd5,
+       0xf2, 0x1e, 0xbd, 0x86, 0xb1, 0x54, 0x97, 0x32, 0x79, 0xd7, 0x4d, 0x18,
+       0x4c, 0xdf, 0xcc, 0x8f, 0x82, 0x76, 0xda, 0xc5, 0xce, 0x8c, 0xd8, 0x99,
+       0x1b, 0xdf, 0xcd, 0xce, 0x99, 0x86, 0xd2, 0x5c, 0xac, 0x7c, 0xcc, 0xbe,
+       0xa7, 0x70, 0x8e, 0xdc, 0x78, 0x26, 0x2b, 0xf7, 0x4c, 0x9c, 0xa0, 0xfd,
+       0xf7, 0x50, 0x9e, 0x1a, 0x91, 0xfd, 0x92, 0x28, 0xf9, 0xbe, 0x9c, 0x0b,
+       0xdf, 0xc9, 0x7e, 0x0b, 0xcf, 0x30, 0xb1, 0x65, 0x1e, 0xd0, 0xd4, 0xbf,
+       0x16, 0x0f, 0xf5, 0x61, 0xbc, 0x9c, 0xcf, 0xbe, 0x93, 0xd9, 0x49, 0x1f,
+       0x6e, 0xb4, 0xd7, 0x30, 0xee, 0x6f, 0x52, 0xf0, 0xa5, 0xb4, 0x9c, 0x27,
+       0xaf, 0x8f, 0x6d, 0x44, 0xc4, 0xf6, 0xdb, 0xfe, 0xd4, 0x4e, 0xa4, 0xf8,
+       0xcc, 0x1f, 0x69, 0xa2, 0x4f, 0x56, 0xe3, 0xdd, 0x6d, 0x41, 0xfd, 0x35,
+       0x68, 0xad, 0x23, 0xb0, 0xe6, 0x2f, 0x8c, 0x84, 0xcc, 0x7a, 0xa5, 0x09,
+       0x6d, 0x7b, 0x9b, 0x98, 0x3b, 0x04, 0xf5, 0xd7, 0xe9, 0x73, 0xcf, 0x45,
+       0xe6, 0x33, 0x7f, 0x88, 0xe1, 0x2b, 0xe4, 0xf9, 0x77, 0x0d, 0xaa, 0x1c,
+       0x53, 0xa3, 0xbd, 0xf6, 0xf1, 0x9c, 0xfd, 0x0e, 0x5c, 0x54, 0xce, 0xc8,
+       0x28, 0x0f, 0x12, 0x73, 0x16, 0x27, 0x0f, 0x5a, 0xf2, 0x4e, 0xed, 0xca,
+       0xeb, 0x9a, 0xb1, 0x3f, 0x6b, 0xe0, 0xc9, 0xf4, 0x1b, 0x96, 0xaa, 0xc5,
+       0xce, 0x3a, 0xc9, 0x45, 0x3c, 0xc4, 0x8c, 0x6c, 0x46, 0xfc, 0x5f, 0xf6,
+       0xc0, 0x0d, 0x7c, 0x98, 0xd6, 0xd2, 0x0d, 0x8c, 0x4b, 0xbf, 0xe6, 0xbd,
+       0x9d, 0xc4, 0x11, 0xf7, 0x56, 0xed, 0xa8, 0x4a, 0x0e, 0x3f, 0xdf, 0x61,
+       0xa0, 0x68, 0xb7, 0xcc, 0x81, 0xe0, 0x56, 0x00, 0x63, 0x89, 0x18, 0xee,
+       0xa4, 0xfd, 0x8c, 0x26, 0x5a, 0x70, 0x07, 0x6d, 0x63, 0x24, 0xd1, 0x8a,
+       0xcf, 0x31, 0x37, 0xd8, 0x9d, 0x10, 0x3f, 0x5b, 0x82, 0x85, 0xb4, 0x95,
+       0xfd, 0xa9, 0xff, 0x05, 0x7d, 0x7a, 0x00, 0xbb, 0x6d, 0xae, 0x29, 0xfb,
+       0xd6, 0x50, 0x56, 0x26, 0xdc, 0xcc, 0x6d, 0xe2, 0x56, 0x7f, 0x4a, 0x38,
+       0x50, 0x27, 0x6e, 0x89, 0x34, 0x62, 0x0b, 0xe5, 0x65, 0xc9, 0x75, 0x87,
+       0x98, 0x4f, 0xad, 0xde, 0xb5, 0x9c, 0x98, 0x7c, 0x61, 0xee, 0x4f, 0xeb,
+       0xe6, 0x21, 0x62, 0x41, 0xd8, 0xcf, 0x79, 0x57, 0x69, 0xc3, 0x72, 0xce,
+       0x7c, 0x90, 0x63, 0x9f, 0x43, 0x3c, 0x70, 0xa7, 0xc4, 0x7e, 0x82, 0x47,
+       0x19, 0xf2, 0x1e, 0xae, 0x95, 0x77, 0x15, 0xe8, 0x1b, 0x33, 0x52, 0x56,
+       0xa7, 0x93, 0x71, 0x64, 0x53, 0xb4, 0x0e, 0x07, 0x47, 0x6e, 0x86, 0x77,
+       0x6b, 0x1d, 0x46, 0x93, 0x7e, 0x64, 0x93, 0xa8, 0xf5, 0x42, 0xbd, 0xc1,
+       0x8b, 0x60, 0xf3, 0x21, 0xc6, 0x89, 0xb7, 0x95, 0x86, 0xf6, 0x37, 0x11,
+       0xec, 0xd9, 0xac, 0x04, 0xbd, 0x0d, 0xaa, 0xb4, 0x4d, 0x3c, 0xa1, 0x1f,
+       0x0c, 0xd2, 0xde, 0x33, 0x23, 0xc4, 0x14, 0xd6, 0x75, 0x6d, 0x75, 0xc9,
+       0x3a, 0xf1, 0x78, 0x95, 0xe6, 0xc3, 0x9e, 0x3d, 0xc4, 0xb8, 0x1d, 0xf2,
+       0xbf, 0x03, 0x6a, 0xb0, 0x6f, 0xcf, 0xcd, 0x98, 0xb1, 0x35, 0x80, 0x83,
+       0xbc, 0x57, 0xbb, 0xe3, 0x1a, 0x3c, 0x43, 0x3f, 0xc9, 0xd0, 0x0f, 0x8b,
+       0xb6, 0xaa, 0xd8, 0xbb, 0xe7, 0x26, 0x54, 0x92, 0xd7, 0x9f, 0x0a, 0x29,
+       0x36, 0xf6, 0x26, 0x38, 0xae, 0xdd, 0x29, 0xfb, 0xdc, 0xbc, 0xf2, 0x22,
+       0xf3, 0x81, 0xee, 0x11, 0x1d, 0x9b, 0x79, 0x3f, 0xc5, 0xb9, 0xde, 0x42,
+       0xcc, 0x3d, 0xbe, 0xad, 0x1a, 0xf7, 0x6f, 0xd3, 0x62, 0xd7, 0xa8, 0xd6,
+       0xfc, 0xb7, 0xf4, 0xd0, 0x19, 0x17, 0xe7, 0xd8, 0x62, 0x0e, 0x77, 0xb6,
+       0xef, 0xa0, 0x55, 0x45, 0xac, 0x77, 0x69, 0xf3, 0x31, 0x73, 0x6e, 0x0c,
+       0xaf, 0x47, 0x9b, 0x70, 0x66, 0x97, 0xe8, 0xca, 0x62, 0x0c, 0x90, 0xf8,
+       0x10, 0x45, 0x9c, 0x39, 0xdd, 0x6e, 0xe6, 0x74, 0xf7, 0x30, 0xa7, 0x7b,
+       0xb0, 0x4f, 0x74, 0xdc, 0x89, 0x25, 0x11, 0x83, 0x3a, 0x6c, 0x24, 0x7e,
+       0x19, 0x50, 0xfb, 0xb4, 0xe6, 0xbb, 0x88, 0xf1, 0xc5, 0x76, 0x8e, 0x67,
+       0x10, 0x27, 0x24, 0x4f, 0x30, 0xf0, 0xd3, 0x4c, 0xce, 0xef, 0x6a, 0x19,
+       0xd3, 0x0f, 0x8c, 0xb4, 0xe0, 0xbb, 0xcc, 0xe1, 0x46, 0xfb, 0x42, 0x3b,
+       0x5f, 0x56, 0x5a, 0xf1, 0x5d, 0x3b, 0x5e, 0x88, 0x0d, 0xb7, 0xe2, 0xdd,
+       0x84, 0x16, 0x5f, 0xa8, 0x84, 0xda, 0xd3, 0xbc, 0xff, 0x5e, 0xf6, 0x66,
+       0x72, 0xd8, 0x25, 0x38, 0x4e, 0x1b, 0xee, 0x49, 0x09, 0x96, 0x3b, 0xe1,
+       0xda, 0x76, 0x07, 0xde, 0x1a, 0xce, 0xe5, 0x6e, 0x21, 0xe6, 0x6e, 0x77,
+       0xf6, 0xd3, 0x1e, 0x52, 0x10, 0x6f, 0x60, 0x0e, 0x17, 0x5c, 0x55, 0xc4,
+       0xfc, 0xed, 0xa3, 0x48, 0x2e, 0x7f, 0x8b, 0x57, 0x07, 0xf5, 0x17, 0x15,
+       0x73, 0xa7, 0xbc, 0x7b, 0xf4, 0x1a, 0x72, 0xe7, 0xc6, 0x4f, 0x10, 0x6b,
+       0x37, 0xd1, 0x07, 0xae, 0x8b, 0x48, 0x7e, 0xa7, 0x61, 0x38, 0x65, 0xbf,
+       0xcf, 0xad, 0xff, 0x94, 0xf3, 0xeb, 0xd7, 0xc4, 0x06, 0x1c, 0x38, 0xad,
+       0xd7, 0x7b, 0xbd, 0x0e, 0x07, 0x6e, 0xd1, 0x83, 0xab, 0x8e, 0x20, 0xca,
+       0x79, 0x97, 0xbd, 0xc2, 0x5c, 0x3c, 0x75, 0x26, 0xe5, 0x1d, 0x94, 0x4e,
+       0xbc, 0x35, 0xf7, 0xef, 0xf3, 0x79, 0x58, 0x21, 0x1f, 0x13, 0x9b, 0x6b,
+       0x68, 0x76, 0xa0, 0xde, 0x2c, 0x86, 0x96, 0x49, 0x93, 0x5f, 0xc6, 0x39,
+       0xd7, 0x71, 0x08, 0xf6, 0x37, 0x98, 0x5e, 0x84, 0xed, 0xff, 0xf9, 0xf5,
+       0x7c, 0xc2, 0x3e, 0x03, 0x4a, 0x9c, 0xcb, 0xe1, 0xea, 0x73, 0x89, 0x52,
+       0x80, 0xf8, 0x94, 0xe0, 0xd8, 0x8a, 0x47, 0x4c, 0xb8, 0x0c, 0xfa, 0x57,
+       0x9f, 0x07, 0xea, 0x2e, 0x0f, 0xfc, 0xc9, 0xc7, 0xac, 0x72, 0xe2, 0x6a,
+       0xd9, 0x2e, 0xce, 0x91, 0xc3, 0xb2, 0x9e, 0x9a, 0x27, 0x38, 0x2b, 0x65,
+       0xb5, 0xd6, 0x0f, 0x79, 0xad, 0x11, 0x67, 0x35, 0x62, 0x6b, 0x05, 0xf1,
+       0xb1, 0x3b, 0x59, 0x8d, 0xcd, 0xdb, 0x06, 0xa8, 0x73, 0x2f, 0x1c, 0xbc,
+       0x4e, 0x25, 0xfd, 0x36, 0x76, 0x82, 0xbf, 0x2b, 0xe9, 0x33, 0xa0, 0x9d,
+       0x6d, 0x4d, 0x5a, 0xf3, 0xef, 0x8c, 0x98, 0x7d, 0x95, 0xec, 0xcb, 0x34,
+       0xe2, 0xed, 0xc6, 0x64, 0xd0, 0x7b, 0xab, 0xaa, 0xe0, 0xf6, 0x88, 0xce,
+       0xb6, 0x3d, 0xe8, 0x4b, 0x0a, 0x4e, 0x4c, 0x50, 0x8f, 0x66, 0x43, 0x19,
+       0x75, 0xe9, 0xa2, 0x2e, 0x67, 0xd8, 0xe7, 0x55, 0xeb, 0x50, 0xbe, 0x27,
+       0xca, 0x3e, 0x37, 0x12, 0x8b, 0x4d, 0x6c, 0xe2, 0xcf, 0xf9, 0xbb, 0x97,
+       0xe3, 0xba, 0x6d, 0x76, 0xee, 0xbb, 0x40, 0xf2, 0x99, 0xd7, 0x22, 0x21,
+       0xfd, 0x1e, 0xd5, 0x89, 0xb7, 0xb3, 0x82, 0xb5, 0xf2, 0x3e, 0x3d, 0xc6,
+       0x67, 0x68, 0xcd, 0x58, 0x9a, 0x14, 0x8c, 0xf2, 0x93, 0x67, 0x47, 0xb1,
+       0x24, 0x29, 0xfe, 0x68, 0xe2, 0xb6, 0xeb, 0xeb, 0xf0, 0xfe, 0xf9, 0x75,
+       0x0b, 0x1f, 0x26, 0x89, 0x99, 0x93, 0xc4, 0xcc, 0x49, 0x62, 0xe6, 0xa4,
+       0xbd, 0x16, 0xa1, 0xe2, 0xf4, 0x90, 0x82, 0xf7, 0x6c, 0xfc, 0xdb, 0x69,
+       0x73, 0xa8, 0x27, 0x19, 0xd3, 0xdb, 0xd3, 0x3a, 0x0e, 0xd0, 0x16, 0x92,
+       0x29, 0xb1, 0x35, 0x05, 0x4f, 0xf5, 0x45, 0x50, 0x45, 0xdb, 0xd9, 0x4a,
+       0x9b, 0x7e, 0x78, 0xbb, 0x16, 0x98, 0xef, 0x08, 0xb5, 0xa6, 0xd0, 0x84,
+       0x07, 0x88, 0x57, 0x0f, 0x31, 0x97, 0x39, 0x44, 0x4c, 0xbb, 0x67, 0x70,
+       0x2d, 0x96, 0xf4, 0xa9, 0xc4, 0x2c, 0x62, 0xd5, 0x74, 0xc1, 0x6e, 0xc1,
+       0x4b, 0x79, 0x57, 0x2e, 0x2a, 0xeb, 0x9a, 0xca, 0x5d, 0xc4, 0xaa, 0xc6,
+       0x5e, 0xe1, 0x38, 0xcc, 0x93, 0x18, 0x8b, 0x12, 0xc4, 0xaa, 0x2d, 0x69,
+       0x99, 0xaf, 0x4e, 0xdc, 0x4b, 0xbb, 0x5e, 0x9f, 0x5f, 0x97, 0x98, 0xb3,
+       0x55, 0x3b, 0x73, 0x40, 0xc9, 0x71, 0x9d, 0x5e, 0x5e, 0x1f, 0xee, 0x0b,
+       0x50, 0x0f, 0x06, 0x8e, 0xed, 0x92, 0x3c, 0x48, 0xfa, 0x13, 0xc0, 0x21,
+       0xe2, 0x93, 0x83, 0xba, 0x7e, 0x99, 0xf8, 0x54, 0x49, 0x7c, 0x7a, 0x8d,
+       0xf8, 0x34, 0x8d, 0xf8, 0xf4, 0x6a, 0x1e, 0x9f, 0xaa, 0x47, 0xc4, 0x16,
+       0x72, 0x5c, 0xfb, 0x78, 0xe2, 0xb9, 0x2a, 0xf9, 0x5f, 0x62, 0x82, 0xf3,
+       0x97, 0xc7, 0xff, 0xa5, 0x78, 0x71, 0x00, 0xee, 0x19, 0xe4, 0xb2, 0x16,
+       0xf1, 0xe6, 0x03, 0xc7, 0x52, 0xfc, 0x74, 0xa8, 0xc0, 0x61, 0x27, 0xed,
+       0x5c, 0xb9, 0xdc, 0x90, 0x75, 0x30, 0x59, 0x03, 0xab, 0xcb, 0xef, 0x0b,
+       0x9a, 0xf8, 0xce, 0x3c, 0xe1, 0x8d, 0xb2, 0xae, 0x53, 0x44, 0x7e, 0xd8,
+       0x86, 0xe1, 0x6d, 0xcf, 0x62, 0x53, 0x9f, 0x7a, 0x6b, 0x19, 0xc8, 0x85,
+       0x95, 0x4e, 0x38, 0x22, 0x95, 0x98, 0x19, 0x11, 0x1b, 0x64, 0x2e, 0x32,
+       0xf6, 0x6d, 0x74, 0xef, 0x2e, 0xc3, 0x84, 0xd7, 0xb2, 0x9e, 0xd4, 0x6b,
+       0xe5, 0xdf, 0x00, 0x08, 0x5e, 0x7a, 0x8a, 0x18, 0xa3, 0x6e, 0x1d, 0xfd,
+       0xb8, 0x33, 0xa7, 0x6b, 0xf0, 0xc5, 0xed, 0x8f, 0xa0, 0x7d, 0xfb, 0x37,
+       0xe9, 0x7b, 0x33, 0x7b, 0x6a, 0x69, 0x87, 0xd7, 0x35, 0x8d, 0xe3, 0x44,
+       0x84, 0xb1, 0xcf, 0xa7, 0xe0, 0x87, 0x73, 0x66, 0x8a, 0x1c, 0xfe, 0x7d,
+       0x60, 0x05, 0x6c, 0x79, 0x6f, 0xe5, 0xfd, 0xe3, 0x39, 0x1f, 0xc7, 0x4e,
+       0xd9, 0x27, 0xbc, 0xf9, 0xb3, 0x9b, 0x7f, 0x42, 0x5b, 0x3f, 0x13, 0x19,
+       0xfc, 0x2b, 0xc8, 0x78, 0xdd, 0x8a, 0x2d, 0x93, 0x7a, 0x45, 0xf9, 0x36,
+       0xbe, 0x49, 0x8e, 0x47, 0x9e, 0xa7, 0xf3, 0x7b, 0xf0, 0x59, 0x91, 0xcf,
+       0x67, 0x05, 0xf9, 0x2f, 0x5a, 0xb1, 0x36, 0xb9, 0x96, 0x32, 0x1f, 0xf1,
+       0x99, 0x94, 0x2b, 0x3c, 0x7b, 0x36, 0x2f, 0xa7, 0x18, 0x81, 0xea, 0x9c,
+       0x9c, 0x2f, 0x51, 0xce, 0x69, 0x62, 0x9e, 0x7a, 0xfd, 0x54, 0x59, 0x85,
+       0x76, 0xff, 0xf7, 0x79, 0x59, 0xb9, 0x72, 0x45, 0xd3, 0x51, 0x2a, 0x65,
+       0xa7, 0xae, 0x7b, 0x17, 0xd1, 0x77, 0x43, 0xde, 0xf5, 0xf6, 0x7a, 0xb3,
+       0x8e, 0x15, 0x17, 0xe7, 0x4c, 0xf2, 0xde, 0x1b, 0xb9, 0x82, 0x17, 0x6f,
+       0x33, 0x47, 0xca, 0xad, 0xbf, 0x4b, 0xfe, 0x65, 0xe0, 0xf1, 0x44, 0xb0,
+       0x75, 0xa5, 0xd2, 0x10, 0x9b, 0x4d, 0x6e, 0x81, 0x2a, 0x59, 0x93, 0x6e,
+       0xb6, 0xff, 0x5f, 0x5e, 0x36, 0xd4, 0xcc, 0x3c, 0xcd, 0xa0, 0x2d, 0x05,
+       0x3b, 0x4e, 0xd8, 0xfb, 0x89, 0x06, 0x5e, 0xca, 0xbe, 0x92, 0x3f, 0x8f,
+       0x28, 0x73, 0x1e, 0xe6, 0x9c, 0x4f, 0x5d, 0x13, 0x95, 0xf9, 0x0f, 0xa6,
+       0x33, 0xa8, 0x16, 0x1e, 0x68, 0x9a, 0xd0, 0xe9, 0x37, 0x26, 0x43, 0xd8,
+       0x0d, 0x88, 0xfb, 0x64, 0x6f, 0xc1, 0x97, 0xff, 0x3f, 0x66, 0xac, 0xf7,
+       0x09, 0x6b, 0x3c, 0x60, 0xbd, 0xdc, 0x99, 0x33, 0x1d, 0xe6, 0xd8, 0xd5,
+       0xc8, 0x78, 0x65, 0xfd, 0x00, 0xe6, 0x34, 0x23, 0x00, 0x9f, 0x76, 0x37,
+       0xc7, 0xed, 0xc2, 0x74, 0xe6, 0x47, 0x91, 0x99, 0x0d, 0x6d, 0x4d, 0xea,
+       0x15, 0x88, 0x55, 0xc9, 0x79, 0x22, 0x9d, 0xf6, 0x0f, 0x14, 0xf7, 0xca,
+       0xf9, 0x0d, 0xb3, 0xd5, 0x8d, 0xa0, 0x7f, 0xae, 0xa2, 0xa0, 0x28, 0x04,
+       0xe7, 0xfd, 0x59, 0xf2, 0xb0, 0x99, 0x1f, 0x59, 0x3f, 0xf2, 0xe9, 0xcc,
+       0xe7, 0x0b, 0x7d, 0xd0, 0xf1, 0xf5, 0xd1, 0x4b, 0x33, 0xc8, 0x82, 0xcc,
+       0xf7, 0xad, 0xd8, 0x74, 0x69, 0x5b, 0xe4, 0x7e, 0x52, 0x5f, 0x73, 0x7d,
+       0xfc, 0xa7, 0x59, 0xf5, 0x01, 0x07, 0x2a, 0xb1, 0x5e, 0x37, 0xa6, 0xcb,
+       0xd9, 0xec, 0x7b, 0x65, 0x8d, 0xc5, 0x3e, 0xcf, 0x36, 0xf5, 0x5c, 0xd6,
+       0xd4, 0x75, 0x63, 0x2f, 0xaa, 0x89, 0xe1, 0x25, 0x49, 0xd1, 0xf5, 0x35,
+       0x50, 0xa9, 0xef, 0x63, 0xc4, 0xa2, 0xe2, 0xa4, 0x87, 0x79, 0xab, 0x87,
+       0x58, 0x67, 0xe0, 0xb9, 0x6c, 0x07, 0x5c, 0xe4, 0x4e, 0x13, 0xd9, 0x30,
+       0x5e, 0xcd, 0xce, 0x99, 0x2e, 0xe7, 0x5e, 0xa9, 0x02, 0x38, 0x67, 0xca,
+       0x6f, 0x53, 0xde, 0xe7, 0x53, 0x72, 0xbf, 0xdf, 0xb7, 0xdf, 0x35, 0x77,
+       0x18, 0x2b, 0x71, 0x4f, 0xa2, 0x4a, 0xd6, 0xda, 0x4d, 0x9f, 0x61, 0x5a,
+       0xd3, 0xb4, 0xaa, 0xe9, 0xb9, 0xf3, 0x30, 0xc1, 0xf6, 0xa5, 0xc4, 0x91,
+       0xd5, 0x11, 0xad, 0xed, 0xbf, 0x2b, 0xc1, 0x40, 0x5a, 0x69, 0x63, 0xf9,
+       0x30, 0x36, 0x8f, 0x4a, 0x5d, 0x85, 0xe3, 0x2d, 0xec, 0x57, 0x37, 0x04,
+       0x42, 0xea, 0xaf, 0x0b, 0x67, 0xa1, 0xdd, 0x45, 0x46, 0x1c, 0xcf, 0x26,
+       0xa6, 0xcb, 0xff, 0x2c, 0x90, 0x35, 0x95, 0xbc, 0x4c, 0x8f, 0x59, 0x65,
+       0x48, 0x5b, 0xed, 0x6c, 0xcb, 0x3c, 0xeb, 0x25, 0x86, 0xb8, 0xb4, 0xe0,
+       0xd1, 0xaf, 0x22, 0xb8, 0x66, 0xbe, 0xa3, 0x13, 0x67, 0x22, 0x5a, 0xc7,
+       0x47, 0x6c, 0xa3, 0xca, 0x11, 0x46, 0x6f, 0x5e, 0xbe, 0xfc, 0x9f, 0xd8,
+       0x9c, 0xac, 0x86, 0x55, 0x45, 0xea, 0x69, 0x2b, 0x33, 0x3d, 0x27, 0xbf,
+       0xd8, 0x58, 0xce, 0xfc, 0xd8, 0x43, 0xb9, 0x72, 0xe6, 0x36, 0xb8, 0xf3,
+       0xd7, 0x30, 0xad, 0x6a, 0x4d, 0xeb, 0xf9, 0xaa, 0xda, 0x89, 0x15, 0x4d,
+       0xc1, 0xc0, 0x32, 0xda, 0x48, 0x95, 0x2d, 0x23, 0x16, 0x2e, 0xfa, 0xd8,
+       0x33, 0x71, 0xf4, 0x23, 0xc8, 0xba, 0x23, 0xcb, 0x95, 0xca, 0x99, 0x31,
+       0x79, 0xd7, 0xd4, 0x89, 0x85, 0x8c, 0x6f, 0xf1, 0xc2, 0xff, 0x74, 0xb2,
+       0xf7, 0x86, 0xbe, 0x31, 0xfd, 0xc2, 0xff, 0xd9, 0xfd, 0xff, 0x01, 0x02,
+       0x8b, 0x0c, 0x6e, 0x74, 0x57, 0x00, 0x00, 0x00 };
 
-static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = {
-       0x0800069c, 0x080008bc, 0x08000800, 0x08000828, 0x08000850, 0x08000878,
-       0x080006d4, 0x080006c0, 0x080008e4, 0x080008e4, 0x080006f0, 0x0800070c,
-       0x0800070c, 0x080008e4, 0x08000724, 0x08000738, 0x080008e4, 0x0800074c,
-       0x080008e4, 0x080008e4, 0x08000760, 0x080008e4, 0x080008e4, 0x080008e4,
-       0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4,
-       0x080008e4, 0x08000774, 0x080008e4, 0x08000788, 0x0800079c, 0x080007b0,
-       0x080008e4, 0x080007c4, 0x080007d8, 0x080007ec, 0x080032e8, 0x08003300,
-       0x08003310, 0x08003320, 0x08003338, 0x08003350, 0x08003360, 0x08003370,
-       0x08003390, 0x080033a0, 0x080033b0, 0x08003440, 0x08003380, 0x080033c0,
-       0x080033d0, 0x080033e8, 0x08003408, 0x08003440, 0x08003420, 0x08003420,
-       0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051e4,
-       0x080051e4, 0x0800520c, 0x0800525c, 0x0800522c, 0x00000000 };
+static const u32 bnx2_CP_b09FwData[(0x84/4) + 1] = {
+       0x00000000, 0x0000001b, 0x0000000f, 0x0000000a, 0x00000008, 0x00000006,
+       0x00000005, 0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000003,
+       0x00000003, 0x00000003, 0x00000003, 0x00000002, 0x00000002, 0x00000002,
+       0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+       0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+       0x00000001, 0x00000001, 0x00000001, 0x00000000 };
+static const u32 bnx2_CP_b09FwRodata[(0x178/4) + 1] = {
+       0x80080100, 0x80080080, 0x80080000, 0x080015a0, 0x080015d8, 0x08001600,
+       0x08001600, 0x08001614, 0x080015bc, 0x080018a4, 0x0800186c, 0x080018f8,
+       0x080018f8, 0x08001980, 0x080018b4, 0x80080240, 0x80080100, 0x80080080,
+       0x80080000, 0x08003148, 0x080030b4, 0x08003170, 0x08003198, 0x080031c0,
+       0x080031e4, 0x0800322c, 0x08003208, 0x08003250, 0x0800311c, 0x08003344,
+       0x08003334, 0x080030d0, 0x080030d0, 0x080030d0, 0x080032a4, 0x080032a4,
+       0x080030d0, 0x080030d0, 0x08003324, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x08003314, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x08003304, 0x080030d0,
+       0x080030d0, 0x080032f4, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0, 0x080030d0,
+       0x080030d0, 0x080032dc, 0x080030d0, 0x080030d0, 0x080032cc, 0x080032bc,
+       0x08003c0c, 0x08003be8, 0x08003bbc, 0x08003b9c, 0x08003b7c, 0x08003b24,
+       0x80080100, 0x80080080, 0x80080000, 0x80080080, 0x00000000 };
 
 static struct fw_info bnx2_cp_fw_09 = {
-       /* Firmware version:  3.7.1 */
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x7,
-       .ver_fix                        = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x0800006c,
+       .start_addr                     = 0x08000074,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x6fd0,
+       .text_len                       = 0x5770,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_CP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_CP_b09FwText),
 
-       .data_addr                      = 0x08007100,
-       .data_len                       = 0x0,
+       .data_addr                      = 0x08005900,
+       .data_len                       = 0x84,
        .data_index                     = 0x0,
        .data                           = bnx2_CP_b09FwData,
 
-       .sbss_addr                      = 0x08007104,
-       .sbss_len                       = 0xa9,
+       .sbss_addr                      = 0x08005988,
+       .sbss_len                       = 0x99,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x080071b0,
-       .bss_len                        = 0x3b0,
+       .bss_addr                       = 0x08005a28,
+       .bss_len                        = 0x20c,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08006fd0,
-       .rodata_len                     = 0x118,
+       .rodata_addr                    = 0x08005770,
+       .rodata_len                     = 0x178,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_CP_b09FwRodata,
 };
 
 static u8 bnx2_RXP_b09FwText[] = {
-       0xec, 0x5c, 0x7d, 0x6c, 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x8e,
-       0xd4, 0x91, 0x5c, 0x1e, 0x4f, 0xcc, 0x51, 0xa6, 0xed, 0x5b, 0x71, 0x25,
-       0x9e, 0x4d, 0xc6, 0x59, 0xd1, 0x07, 0x9b, 0x28, 0x0e, 0xc9, 0x66, 0xef,
-       0x24, 0xb1, 0x86, 0x5b, 0x53, 0x35, 0x1d, 0x1b, 0x6d, 0xea, 0xb2, 0x47,
-       0xb5, 0x29, 0x8c, 0x06, 0x90, 0xbf, 0x00, 0x17, 0xa8, 0xe4, 0xcb, 0x91,
-       0x8a, 0x55, 0xf7, 0xc0, 0xbd, 0xc8, 0x8c, 0x18, 0x20, 0x6e, 0x7d, 0x25,
-       0x29, 0x4a, 0x08, 0x0e, 0x3a, 0xa6, 0x71, 0x1a, 0xfd, 0x61, 0xd7, 0x04,
-       0x2b, 0x1b, 0x6e, 0x91, 0xd6, 0x72, 0xe3, 0xb6, 0x46, 0x50, 0x04, 0x84,
-       0xec, 0x34, 0x6e, 0xd0, 0x0f, 0xa1, 0x2e, 0x6c, 0x03, 0x96, 0xbd, 0xfd,
-       0xbd, 0xd9, 0x5d, 0xf2, 0x48, 0x5b, 0x76, 0xd0, 0x3f, 0xfa, 0x4f, 0x77,
-       0x80, 0xc3, 0xce, 0xcc, 0xbe, 0xf7, 0xe6, 0xcd, 0x9b, 0xf7, 0x39, 0x4b,
-       0xe9, 0xb7, 0xe3, 0xd4, 0x4e, 0x41, 0xeb, 0xc0, 0x2f, 0x7d, 0xf4, 0xb1,
-       0x87, 0x6e, 0xb9, 0xfd, 0x96, 0x5b, 0xd1, 0xdd, 0xaf, 0x2a, 0x3b, 0xd4,
-       0x70, 0x3e, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45,
-       0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d,
-       0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a,
-       0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51,
-       0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b,
-       0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0xed, 0xff, 0x7b, 0x53, 0x89,
-       0x74, 0x7e, 0x76, 0x04, 0x3f, 0x8a, 0x89, 0x5c, 0xfa, 0x01, 0xc7, 0xa4,
-       0x98, 0x9a, 0xeb, 0x3f, 0x3e, 0x65, 0x12, 0xd9, 0xf5, 0xa1, 0x74, 0x9e,
-       0x3e, 0xf0, 0x4a, 0x49, 0x8d, 0x78, 0xfe, 0xfa, 0xdc, 0xd5, 0x67, 0x9e,
-       0xbf, 0xdd, 0xb8, 0x52, 0x53, 0x29, 0xa6, 0xe7, 0x66, 0xf6, 0xeb, 0xfb,
-       0x28, 0xd6, 0x0f, 0x9c, 0xa7, 0x07, 0xff, 0xb1, 0x93, 0x3a, 0x43, 0x5a,
-       0x44, 0x0b, 0x15, 0xc3, 0x3a, 0x88, 0xe7, 0x72, 0x7d, 0xc8, 0x5a, 0x23,
-       0x8d, 0x56, 0x75, 0x7f, 0xc5, 0x72, 0x45, 0x61, 0x3a, 0x54, 0xae, 0xc7,
-       0x68, 0x5d, 0xfe, 0x3b, 0x0f, 0xac, 0x69, 0x72, 0xff, 0x82, 0xe2, 0x34,
-       0x3c, 0xef, 0x8c, 0xe5, 0x79, 0x2f, 0xe1, 0xf7, 0x33, 0x0b, 0x63, 0xf7,
-       0x43, 0xcf, 0xd6, 0x54, 0x12, 0xe6, 0x1f, 0x2b, 0xce, 0x62, 0x2b, 0x95,
-       0xe7, 0x89, 0xa6, 0xdd, 0x18, 0x9d, 0x74, 0x4b, 0x4a, 0xa1, 0x51, 0x51,
-       0x0e, 0x9c, 0x9d, 0x55, 0x0e, 0x9e, 0x3d, 0xa9, 0x1c, 0x3a, 0x5b, 0x55,
-       0x9c, 0xb3, 0x54, 0x12, 0xfb, 0xe3, 0x64, 0xeb, 0xe7, 0x94, 0x7c, 0xa3,
-       0x57, 0x71, 0xe6, 0xaf, 0x7a, 0x8e, 0x65, 0xe8, 0xbf, 0x4e, 0x9a, 0xcd,
-       0xeb, 0x39, 0x15, 0x0f, 0x63, 0x8d, 0xec, 0xa4, 0xe7, 0x89, 0x9c, 0xf7,
-       0xb8, 0x93, 0x35, 0x75, 0xa1, 0xc4, 0xa8, 0xdc, 0x68, 0x07, 0x5d, 0x4d,
-       0xc9, 0xbb, 0xde, 0x0b, 0x8e, 0xb5, 0x0c, 0x3a, 0x75, 0xe0, 0x93, 0x2e,
-       0x72, 0xcc, 0x4f, 0xc8, 0x63, 0x49, 0xc9, 0x0f, 0x86, 0xfc, 0x50, 0x9a,
-       0xf9, 0x2d, 0x2e, 0x09, 0xf0, 0xb5, 0x93, 0x8a, 0x35, 0x9d, 0x26, 0x97,
-       0xb6, 0xc3, 0xaf, 0x7b, 0xcf, 0x0f, 0xea, 0xb4, 0xd2, 0x30, 0x4a, 0x25,
-       0xec, 0x7d, 0xc6, 0x4d, 0x93, 0xc8, 0x91, 0xed, 0x64, 0xfb, 0xe9, 0x85,
-       0x46, 0x8a, 0xfe, 0xbc, 0x61, 0xa6, 0xca, 0xb4, 0x83, 0x8a, 0xc9, 0x24,
-       0x7d, 0x17, 0x38, 0xd3, 0x58, 0x5b, 0x98, 0xa6, 0x5e, 0x06, 0x6c, 0xb9,
-       0xf1, 0x23, 0xfe, 0xb7, 0x31, 0xfa, 0x54, 0x56, 0xe2, 0x94, 0xc0, 0x67,
-       0x00, 0xcb, 0x7c, 0x4b, 0x58, 0xc9, 0xbb, 0x0f, 0x4b, 0xa5, 0xa9, 0x2c,
-       0xe6, 0x1a, 0x4e, 0x20, 0xfb, 0x56, 0xec, 0x8f, 0x9f, 0x37, 0x28, 0xf9,
-       0xf9, 0x1b, 0x20, 0x03, 0x4a, 0x0a, 0xda, 0x9b, 0x2a, 0x62, 0x66, 0xba,
-       0x11, 0xc7, 0x98, 0x79, 0xf1, 0xbc, 0x43, 0x16, 0xe9, 0x65, 0xab, 0x0b,
-       0xb2, 0x4a, 0x53, 0xd9, 0xea, 0x04, 0x4e, 0x0b, 0x75, 0x9b, 0xbc, 0x07,
-       0xa6, 0xdb, 0x86, 0x79, 0xaf, 0x43, 0xcd, 0x79, 0xde, 0x54, 0x96, 0x3a,
-       0xfd, 0xb9, 0x21, 0xd0, 0xd0, 0x68, 0x72, 0x5c, 0x01, 0xdc, 0xdb, 0xcc,
-       0x5f, 0x2c, 0x91, 0xe3, 0x3e, 0x3f, 0xb3, 0xe4, 0xcc, 0xa6, 0x83, 0x75,
-       0xe3, 0x54, 0x76, 0xaf, 0x0f, 0xfa, 0x90, 0xad, 0x8b, 0x3d, 0x5b, 0x7d,
-       0x18, 0x2b, 0x37, 0x82, 0x8e, 0x55, 0x26, 0x5e, 0x63, 0x17, 0xad, 0x25,
-       0x49, 0x5c, 0xb6, 0x7a, 0x02, 0xb8, 0x4e, 0xf0, 0x1a, 0x9e, 0x71, 0x3b,
-       0xcd, 0xcc, 0xb7, 0xd2, 0x89, 0x79, 0x96, 0x6d, 0x05, 0x67, 0x21, 0x68,
-       0xcf, 0x6d, 0x25, 0xc5, 0x6e, 0x9c, 0x44, 0x5f, 0xa3, 0x29, 0xd3, 0x7b,
-       0x61, 0xc6, 0x9a, 0x55, 0xf2, 0x67, 0x97, 0x95, 0x02, 0xce, 0xfc, 0xc0,
-       0xd9, 0x0b, 0xca, 0xc1, 0xc6, 0xcb, 0x1d, 0xd4, 0x6e, 0x40, 0xbb, 0x34,
-       0x3a, 0xe1, 0x2a, 0xc4, 0xfc, 0x2e, 0x40, 0x5e, 0xb6, 0x0e, 0xc9, 0x9b,
-       0x9d, 0xca, 0x41, 0xd0, 0x6a, 0x31, 0xbf, 0x1e, 0xa7, 0x4e, 0x95, 0x76,
-       0x98, 0x21, 0x6c, 0x8c, 0xbe, 0x0e, 0xde, 0xd6, 0xac, 0x24, 0xe0, 0xa8,
-       0xcb, 0xc7, 0xe9, 0x0e, 0xf8, 0x61, 0xdd, 0x61, 0xbd, 0x11, 0x76, 0x61,
-       0xee, 0x8f, 0x7a, 0xca, 0xc3, 0x3b, 0x19, 0x06, 0xf6, 0x60, 0x3f, 0x30,
-       0x65, 0x3a, 0xdd, 0x1a, 0x95, 0x74, 0x41, 0x86, 0x9e, 0xa7, 0x1b, 0x69,
-       0xc6, 0x22, 0xca, 0x43, 0x9f, 0x85, 0xa9, 0x41, 0x46, 0x26, 0x64, 0xb4,
-       0xb7, 0xa4, 0x8a, 0x7b, 0x41, 0xa2, 0xa4, 0x68, 0x81, 0x3c, 0x17, 0xe8,
-       0x0e, 0x89, 0x2f, 0x72, 0x16, 0x74, 0xb0, 0x9d, 0xfb, 0x58, 0x37, 0x26,
-       0xd7, 0x55, 0x73, 0x66, 0x6a, 0x91, 0x48, 0x11, 0xb9, 0x21, 0xd0, 0x63,
-       0xdd, 0x64, 0x38, 0x17, 0x3c, 0x32, 0xef, 0xdc, 0x37, 0x81, 0x13, 0x23,
-       0xc7, 0xea, 0x68, 0xe2, 0x13, 0xfc, 0x24, 0x59, 0xe6, 0x2c, 0x43, 0xb9,
-       0x4f, 0x65, 0x73, 0x9f, 0xef, 0x7b, 0x83, 0x23, 0x1a, 0xbd, 0x24, 0xf7,
-       0xcb, 0x76, 0xc4, 0x70, 0x72, 0x8f, 0xc4, 0xf2, 0x99, 0x76, 0x49, 0x29,
-       0x5a, 0xfa, 0x06, 0x2d, 0xe8, 0x85, 0x50, 0x73, 0x71, 0xca, 0x4b, 0xfe,
-       0x46, 0xb1, 0x16, 0xdb, 0x17, 0xec, 0xc4, 0xe4, 0xbd, 0xf0, 0x5c, 0x0e,
-       0xb6, 0x6a, 0x48, 0xfd, 0x29, 0x56, 0xd9, 0xfe, 0x99, 0xb7, 0x55, 0x43,
-       0x50, 0x48, 0x4f, 0xf4, 0xaa, 0xd4, 0x45, 0xe3, 0xd6, 0x55, 0x4f, 0xec,
-       0xc3, 0xfb, 0xe1, 0x14, 0x78, 0x33, 0xd2, 0xb0, 0xb6, 0x84, 0x4a, 0xb0,
-       0x73, 0x6b, 0x28, 0xa5, 0x93, 0x89, 0xbd, 0x25, 0xc8, 0x1e, 0x5f, 0x85,
-       0xe0, 0xaf, 0xc5, 0xa7, 0x4f, 0x17, 0x6c, 0xda, 0x0e, 0x78, 0x74, 0xac,
-       0x5b, 0xa5, 0xcc, 0x74, 0xec, 0x5f, 0x9d, 0x65, 0xf9, 0xb6, 0x43, 0xff,
-       0x15, 0x2a, 0x5a, 0x4c, 0x3b, 0xa4, 0x21, 0x68, 0xf0, 0xb6, 0x66, 0x1a,
-       0xe1, 0xd9, 0xb2, 0xfe, 0x6a, 0x34, 0x32, 0xc2, 0xb0, 0x0c, 0xc7, 0xf0,
-       0xc6, 0x68, 0x5a, 0xbc, 0xef, 0xed, 0xdf, 0xb2, 0xa6, 0x49, 0x62, 0x16,
-       0x3c, 0xfb, 0x67, 0x01, 0x19, 0x7e, 0x1a, 0x2c, 0x9f, 0xc3, 0x76, 0x79,
-       0x33, 0x6c, 0x33, 0x1c, 0x74, 0xa8, 0x97, 0x79, 0xa8, 0xc7, 0x7d, 0x7b,
-       0x0c, 0x79, 0x0a, 0xcf, 0x52, 0x09, 0x68, 0x7c, 0xd2, 0x3e, 0x18, 0x1e,
-       0x7e, 0xc2, 0x85, 0x9f, 0x70, 0xe1, 0x1f, 0x5c, 0xf8, 0x11, 0x97, 0xfd,
-       0x4a, 0x9a, 0x9e, 0x1f, 0x84, 0xdf, 0xdb, 0xf4, 0x43, 0x68, 0x63, 0xe8,
-       0x0b, 0x52, 0xe1, 0x87, 0xa6, 0x6b, 0x02, 0xb6, 0x0e, 0x9b, 0x5b, 0xe2,
-       0x39, 0x1d, 0xcf, 0x02, 0x9e, 0x26, 0xfc, 0x2c, 0xeb, 0x61, 0xe8, 0x5f,
-       0xd9, 0x2f, 0xa5, 0xe0, 0x83, 0xd8, 0xef, 0xb0, 0x7f, 0x62, 0x58, 0xcf,
-       0x2b, 0x58, 0x8c, 0xeb, 0xe1, 0x1c, 0xd9, 0xee, 0xe2, 0x24, 0x12, 0x25,
-       0xe5, 0xf0, 0x20, 0x6c, 0xf2, 0xe6, 0x16, 0xf0, 0xca, 0xb6, 0x79, 0x1d,
-       0xbb, 0x16, 0xb4, 0xf7, 0x3b, 0xfc, 0x7f, 0xb7, 0xb7, 0x03, 0x30, 0xd2,
-       0xc6, 0x3b, 0xfd, 0x71, 0x77, 0xe0, 0x7f, 0xf8, 0xbd, 0x91, 0xb6, 0x69,
-       0x5f, 0x30, 0xe6, 0xfe, 0x06, 0xbf, 0x96, 0xb8, 0x2d, 0x46, 0x7b, 0x96,
-       0x7d, 0xbf, 0xb9, 0x67, 0x01, 0x9a, 0xb1, 0xec, 0xf3, 0xb8, 0xe7, 0x7c,
-       0xe8, 0x3f, 0x3b, 0x40, 0x0f, 0xfc, 0xb9, 0x9b, 0x71, 0x84, 0xe8, 0xbf,
-       0x14, 0x98, 0x16, 0xe6, 0xb6, 0xcb, 0xc2, 0xf3, 0x66, 0x2c, 0xb6, 0x4f,
-       0xbd, 0xd9, 0x3e, 0xf7, 0xc3, 0x3e, 0xad, 0x56, 0x32, 0xac, 0xbf, 0x82,
-       0x7d, 0x3e, 0x61, 0x29, 0x90, 0x0d, 0xd1, 0xc5, 0x4a, 0x1c, 0xbe, 0x41,
-       0x4b, 0xbd, 0x41, 0x7b, 0xd3, 0xd3, 0xd0, 0xcb, 0x33, 0x3c, 0x87, 0x23,
-       0x3a, 0x21, 0xfd, 0xb5, 0xef, 0x0f, 0xd6, 0xd5, 0x6f, 0x80, 0x2f, 0xcf,
-       0x9b, 0x06, 0xcd, 0xe2, 0xb0, 0x1a, 0xd8, 0x62, 0x38, 0x6f, 0x23, 0x26,
-       0x3a, 0x37, 0xa9, 0x54, 0xca, 0xb4, 0x90, 0x91, 0x59, 0x00, 0xed, 0x29,
-       0xcb, 0xb7, 0x7b, 0xb6, 0x8d, 0x45, 0xd0, 0x9f, 0x71, 0x07, 0xe1, 0x17,
-       0xd8, 0x6e, 0xc0, 0x17, 0xe8, 0x2f, 0x82, 0xfe, 0x4c, 0xa3, 0x85, 0xbe,
-       0xa6, 0x85, 0xb1, 0x36, 0xdc, 0x0f, 0x44, 0x6d, 0x86, 0xeb, 0x1e, 0xa5,
-       0x3b, 0xdc, 0x84, 0xe2, 0x3c, 0xc5, 0x7e, 0xb9, 0x9c, 0x81, 0x5d, 0x29,
-       0x65, 0x8b, 0xd7, 0x56, 0x69, 0x71, 0x03, 0x86, 0xec, 0xb2, 0x6f, 0xb3,
-       0xb6, 0x33, 0x58, 0x4a, 0xa9, 0xd2, 0xf7, 0x10, 0x1d, 0xac, 0x68, 0x80,
-       0xe1, 0x31, 0xcf, 0xfb, 0x73, 0x63, 0x95, 0x5e, 0xf8, 0x52, 0x1e, 0x5f,
-       0xf5, 0xa6, 0x2c, 0x7f, 0xee, 0x97, 0x2b, 0x0f, 0xf0, 0x19, 0x61, 0x2f,
-       0x94, 0x2e, 0x5b, 0x3f, 0xf7, 0xa0, 0xbf, 0x5b, 0x70, 0x3e, 0x9e, 0x8e,
-       0x31, 0xe6, 0xeb, 0x2c, 0x29, 0x87, 0x4c, 0xd1, 0xdb, 0x1a, 0xf8, 0xbc,
-       0x43, 0x98, 0x3c, 0x50, 0x29, 0xf7, 0xb4, 0xd2, 0x55, 0x95, 0x63, 0xeb,
-       0x65, 0x38, 0x01, 0xa7, 0xb2, 0x0f, 0xf2, 0x28, 0x77, 0x37, 0xcd, 0xc5,
-       0x0a, 0x15, 0x8f, 0xd6, 0x2c, 0x1f, 0x07, 0xe3, 0x78, 0xbe, 0x22, 0x7a,
-       0x63, 0xb4, 0x31, 0xd6, 0x19, 0x67, 0x89, 0xf6, 0x65, 0x16, 0x49, 0xe2,
-       0xf6, 0xc4, 0x36, 0x71, 0x93, 0x85, 0x4a, 0xb9, 0xbb, 0x69, 0x9c, 0xca,
-       0x83, 0x96, 0xd8, 0xbf, 0x81, 0xdb, 0xbf, 0x89, 0xbb, 0x8b, 0xd2, 0xdd,
-       0x8c, 0x2f, 0x7a, 0xdb, 0x36, 0x69, 0xa7, 0x03, 0x7e, 0x7a, 0xda, 0x36,
-       0x69, 0x98, 0x4c, 0xb3, 0x69, 0x9c, 0x61, 0x9a, 0x7b, 0x36, 0x69, 0x0e,
-       0x6f, 0xe5, 0xe7, 0x28, 0xc1, 0x07, 0xc5, 0x5a, 0x73, 0xb4, 0xff, 0x62,
-       0x65, 0x60, 0xfc, 0x0e, 0x42, 0x8c, 0x1c, 0xde, 0x11, 0xf8, 0x70, 0x6d,
-       0xbf, 0x03, 0x59, 0x69, 0xc4, 0x3e, 0x51, 0xa1, 0x32, 0xce, 0xf9, 0x81,
-       0x3a, 0xed, 0x5f, 0xab, 0x53, 0xa0, 0x4b, 0xac, 0x13, 0x6f, 0xc1, 0xc6,
-       0xa8, 0xb4, 0x3b, 0x17, 0x9f, 0xd4, 0x72, 0x3a, 0x6c, 0x8d, 0xc6, 0xcb,
-       0xf0, 0xe1, 0x6a, 0x6e, 0xef, 0xeb, 0x79, 0xf5, 0x71, 0x4f, 0x35, 0xd9,
-       0x1f, 0xc6, 0x47, 0x9d, 0x2c, 0xe6, 0xeb, 0x6c, 0x5b, 0xf0, 0x2b, 0x0d,
-       0xa6, 0xfd, 0x4c, 0x17, 0x75, 0x22, 0x8e, 0xd6, 0xcf, 0xec, 0xf2, 0x6d,
-       0x87, 0x34, 0x0d, 0xbe, 0x79, 0x26, 0xcb, 0x71, 0xbf, 0x35, 0x06, 0xf8,
-       0x49, 0x35, 0x37, 0xd6, 0x77, 0xa4, 0x7e, 0x67, 0x5f, 0xb1, 0x5e, 0xea,
-       0x2b, 0x56, 0x74, 0xb6, 0x13, 0xe1, 0x64, 0xd1, 0x97, 0xb9, 0x54, 0x0a,
-       0x36, 0xc1, 0x6b, 0x27, 0xb1, 0xe6, 0x0f, 0x60, 0x7f, 0x6c, 0xdf, 0x44,
-       0xe3, 0x2e, 0xd6, 0x18, 0xf9, 0x00, 0xe7, 0x0e, 0xde, 0xe0, 0xd3, 0x6c,
-       0xec, 0x5a, 0x8c, 0xfc, 0x6b, 0x60, 0x9f, 0xdc, 0x7f, 0xc7, 0xf3, 0xe3,
-       0xc3, 0xdd, 0x5d, 0xfe, 0xdc, 0x8f, 0x03, 0x9b, 0x0e, 0x69, 0x31, 0x9d,
-       0x8c, 0x32, 0x8e, 0x1c, 0x66, 0xbc, 0xa1, 0x29, 0xec, 0x9f, 0xf3, 0x2e,
-       0xe7, 0x1e, 0x9c, 0x77, 0x4c, 0x07, 0x7e, 0x8e, 0x6c, 0xe4, 0x4f, 0x9e,
-       0x40, 0x2e, 0x52, 0x84, 0xdd, 0x68, 0xb9, 0x2b, 0x34, 0x23, 0x7d, 0x24,
-       0xc5, 0x5a, 0x72, 0x8f, 0x01, 0xe6, 0xdf, 0x60, 0x73, 0xdd, 0x5d, 0x81,
-       0x1e, 0x06, 0x3e, 0x5e, 0xfa, 0x5d, 0xc0, 0xbe, 0xb5, 0x0d, 0xf6, 0xcd,
-       0x66, 0x58, 0xbc, 0x5f, 0xdf, 0xf6, 0xfe, 0x9f, 0xd9, 0x7e, 0xf1, 0x6e,
-       0x15, 0xfe, 0xb4, 0x35, 0xb0, 0xfd, 0x8b, 0x54, 0x84, 0x6f, 0xd5, 0x4c,
-       0xce, 0x2d, 0x0f, 0x02, 0x17, 0xe3, 0x3a, 0x78, 0x84, 0xbf, 0x40, 0x8c,
-       0x85, 0xbc, 0x11, 0x13, 0x92, 0x37, 0x72, 0x3e, 0x05, 0xd8, 0x34, 0x60,
-       0xd9, 0xff, 0x32, 0xec, 0x85, 0x38, 0xcb, 0xbc, 0x58, 0x67, 0x1c, 0xf6,
-       0x55, 0xe4, 0x39, 0xd9, 0x36, 0x68, 0x94, 0xf7, 0x82, 0x6a, 0x86, 0xb0,
-       0x21, 0xdd, 0xed, 0xb0, 0x9c, 0xdf, 0x30, 0xed, 0xae, 0x20, 0x6f, 0x18,
-       0x23, 0xbb, 0x61, 0xe3, 0x57, 0xa2, 0xa9, 0xa7, 0x90, 0xbb, 0x99, 0x2d,
-       0x2c, 0x0b, 0x9e, 0xd7, 0x7d, 0x19, 0x85, 0x78, 0xa5, 0x9e, 0xad, 0xe3,
-       0xdf, 0x4a, 0x6c, 0xfa, 0x4a, 0xb6, 0x34, 0xb2, 0x11, 0x2b, 0x20, 0xe3,
-       0xf4, 0xa4, 0xc8, 0x25, 0x29, 0x5f, 0xf7, 0xe5, 0x8b, 0xf8, 0x0c, 0xff,
-       0x28, 0xfd, 0x07, 0xce, 0x3d, 0xf4, 0x83, 0xe1, 0x99, 0xb3, 0x9e, 0xd9,
-       0x38, 0x9b, 0x34, 0x74, 0x69, 0x0c, 0xb8, 0x74, 0x14, 0x34, 0x38, 0x6e,
-       0x5b, 0x22, 0x97, 0xa0, 0xa2, 0xce, 0xf9, 0x85, 0xcc, 0x0d, 0x6d, 0xf6,
-       0x03, 0x22, 0xd7, 0x86, 0x39, 0xee, 0xff, 0x41, 0x97, 0x7f, 0xd6, 0x1d,
-       0x3c, 0x1e, 0x17, 0xb9, 0xae, 0x6d, 0xf3, 0x7f, 0xd7, 0xe1, 0xf3, 0x26,
-       0xc7, 0x98, 0xff, 0xc9, 0xb6, 0xf1, 0xa3, 0x89, 0xad, 0xe3, 0xaf, 0xf6,
-       0x85, 0xfa, 0x20, 0x72, 0x8f, 0x05, 0xfc, 0xb2, 0x9e, 0x6e, 0xe7, 0xf5,
-       0x17, 0xd1, 0x97, 0x3f, 0x01, 0x4d, 0xa9, 0xe3, 0xbf, 0x80, 0xbe, 0x6c,
-       0xc0, 0x5e, 0x43, 0x5f, 0x9a, 0x79, 0xd8, 0xa8, 0x3b, 0xaa, 0x02, 0x39,
-       0xac, 0x93, 0xdd, 0x9b, 0x2e, 0xc3, 0xc6, 0x0b, 0x0d, 0xc8, 0x6e, 0x23,
-       0xae, 0x6e, 0xc0, 0x94, 0x36, 0x61, 0xfc, 0xb8, 0x53, 0x68, 0x78, 0xc8,
-       0xfb, 0x9a, 0x63, 0x70, 0x06, 0xfd, 0x12, 0xf6, 0xba, 0x42, 0x53, 0xee,
-       0x9a, 0x2d, 0xcc, 0x93, 0x32, 0x6f, 0x15, 0xe6, 0x93, 0x4a, 0x61, 0x91,
-       0x73, 0xda, 0x18, 0xfa, 0xb2, 0x3e, 0x41, 0x8c, 0x3b, 0xa5, 0xd8, 0x67,
-       0xe7, 0x90, 0xcf, 0x2e, 0xe1, 0x77, 0x0e, 0xbf, 0x3a, 0x7e, 0x61, 0xdd,
-       0xf0, 0x2d, 0xd4, 0x1d, 0xd2, 0xdf, 0x23, 0x36, 0xf9, 0xeb, 0xff, 0x74,
-       0x09, 0xf9, 0xf4, 0x5c, 0x92, 0x9e, 0x30, 0x45, 0x8f, 0xf0, 0x7d, 0x9c,
-       0x8d, 0x5c, 0x5c, 0x7f, 0x8b, 0x7e, 0x25, 0xc8, 0xe9, 0x88, 0xde, 0xa8,
-       0xe2, 0x2c, 0x87, 0x0f, 0x05, 0xfe, 0xe9, 0xe4, 0x57, 0x1c, 0xe9, 0xcb,
-       0x83, 0x9c, 0x0d, 0x7e, 0xc7, 0x96, 0x50, 0xaf, 0x40, 0x3e, 0x0a, 0xfd,
-       0x0c, 0x7a, 0xfc, 0x46, 0xb5, 0x1d, 0xfc, 0x98, 0x54, 0x9c, 0x30, 0x46,
-       0x49, 0x19, 0xd0, 0x77, 0x28, 0xed, 0xc8, 0xdb, 0xe0, 0x77, 0xe4, 0x98,
-       0x65, 0x46, 0xc7, 0x17, 0x2a, 0x02, 0xb0, 0x90, 0x79, 0x16, 0x7d, 0xe8,
-       0xdf, 0xe5, 0x2a, 0xe3, 0x09, 0x7a, 0xb3, 0xaa, 0xd2, 0xbf, 0x20, 0x0f,
-       0xc4, 0xbb, 0xe3, 0xb0, 0xc1, 0x5e, 0xc4, 0xab, 0x7e, 0x95, 0xf6, 0x72,
-       0xcc, 0xd8, 0xa3, 0xe1, 0x59, 0xc0, 0xef, 0x20, 0xf2, 0xc2, 0x6b, 0xe0,
-       0x5c, 0x03, 0x9e, 0x79, 0x8b, 0x01, 0x87, 0xe1, 0x35, 0xf0, 0xd6, 0x09,
-       0x1d, 0x34, 0xf4, 0x49, 0xfa, 0x8c, 0x2e, 0x73, 0x27, 0x85, 0xe7, 0x7d,
-       0x3f, 0xf9, 0xd1, 0x79, 0x96, 0xb3, 0x0a, 0x1d, 0xe2, 0x31, 0xbf, 0x63,
-       0x7f, 0xce, 0xf4, 0x8c, 0x51, 0x1b, 0x9b, 0xb9, 0x5c, 0xf5, 0xfb, 0xe1,
-       0x1c, 0x29, 0x61, 0x4c, 0x65, 0x3f, 0x5d, 0x80, 0xad, 0xf2, 0x78, 0x9c,
-       0xe4, 0x19, 0x6c, 0x39, 0x4f, 0xa9, 0x47, 0xc7, 0x66, 0x4c, 0x3e, 0x57,
-       0x9d, 0xa6, 0x2b, 0xe1, 0xb9, 0xf2, 0x19, 0xa1, 0x0e, 0xad, 0x3e, 0x89,
-       0x73, 0x15, 0x41, 0xcd, 0x02, 0x3f, 0x30, 0xc7, 0xe7, 0x8b, 0x3a, 0xb2,
-       0x8a, 0x3c, 0xac, 0x4a, 0x09, 0xbf, 0xe6, 0x3a, 0x85, 0x3a, 0x05, 0xe7,
-       0x57, 0x99, 0x03, 0x8d, 0x24, 0x9e, 0x4b, 0x78, 0xa6, 0xf0, 0x3c, 0x87,
-       0x67, 0x3f, 0x9e, 0x75, 0xb6, 0x8f, 0x20, 0xef, 0xf9, 0x08, 0x3f, 0xb0,
-       0x93, 0x02, 0xdb, 0x34, 0xfd, 0x65, 0x23, 0x47, 0x3f, 0x68, 0x8c, 0xd2,
-       0x5f, 0x34, 0xb2, 0xf4, 0xfd, 0x86, 0x45, 0xcf, 0x36, 0x86, 0xe9, 0x7b,
-       0x8d, 0x0c, 0xd7, 0x90, 0xc8, 0xe1, 0xd2, 0xf0, 0xcd, 0x17, 0xe8, 0x2b,
-       0x6e, 0x03, 0x3e, 0x47, 0xfa, 0xcb, 0xe3, 0x76, 0xfd, 0x3a, 0x2a, 0x3e,
-       0xa5, 0x23, 0xcf, 0x54, 0xb9, 0x8e, 0xa3, 0x47, 0xad, 0xbb, 0x13, 0x7c,
-       0xf6, 0xc2, 0xe4, 0xba, 0xe6, 0x04, 0xc3, 0xa1, 0x1e, 0x56, 0x90, 0xbf,
-       0xb4, 0xd0, 0x64, 0xd2, 0x58, 0x71, 0xd4, 0x74, 0xe0, 0x8f, 0x26, 0x00,
-       0x87, 0x35, 0xdd, 0x38, 0xad, 0x9d, 0x86, 0x2d, 0x58, 0xa8, 0xa5, 0x93,
-       0x31, 0xf8, 0x3e, 0x99, 0x9f, 0x48, 0xdf, 0xe2, 0xfb, 0xd2, 0xb0, 0xc6,
-       0xe4, 0x39, 0x3b, 0x98, 0xe3, 0xf8, 0xa8, 0x03, 0xb6, 0x11, 0xc4, 0x90,
-       0xed, 0x34, 0xd9, 0x37, 0x4e, 0x04, 0xfe, 0x71, 0x85, 0x1e, 0x76, 0x07,
-       0xec, 0xb7, 0x11, 0x7b, 0x94, 0x96, 0x30, 0x2f, 0xda, 0x0d, 0xde, 0x3c,
-       0xef, 0x30, 0xea, 0xf3, 0x74, 0x42, 0xa3, 0xbf, 0x9f, 0x35, 0xf4, 0xc3,
-       0x02, 0x01, 0xae, 0xdd, 0xf3, 0xc6, 0x4d, 0xa3, 0x64, 0x8b, 0x0e, 0xfa,
-       0xa7, 0x53, 0x1c, 0x93, 0xd7, 0x8f, 0xbd, 0x08, 0x3d, 0xa8, 0x2d, 0xb5,
-       0x52, 0xad, 0xa6, 0xd1, 0xe5, 0x91, 0x01, 0xb9, 0x6e, 0xad, 0x9e, 0x40,
-       0x9e, 0xd7, 0x46, 0x8b, 0xbd, 0x52, 0xd9, 0xe1, 0xb7, 0x33, 0xd2, 0x6f,
-       0x3b, 0x26, 0x9e, 0xf5, 0xb4, 0xbe, 0x95, 0x97, 0x67, 0xa9, 0xe8, 0x76,
-       0xa2, 0x42, 0xd9, 0x0d, 0x99, 0x70, 0x7f, 0x40, 0x77, 0x04, 0x62, 0xa0,
-       0x36, 0xa0, 0x1f, 0x12, 0xff, 0xed, 0x7d, 0x51, 0x63, 0x39, 0xbe, 0x8e,
-       0xd8, 0xc2, 0xb1, 0x52, 0x91, 0x7a, 0xb7, 0xb0, 0xf4, 0xa6, 0xce, 0xfe,
-       0xe5, 0x7b, 0xf5, 0xdd, 0xc1, 0x98, 0xfd, 0x3b, 0x8f, 0xdb, 0xe9, 0xfb,
-       0xb5, 0x9d, 0xb4, 0x58, 0xe3, 0xf7, 0xad, 0xb4, 0x50, 0x1b, 0xb8, 0xf2,
-       0x90, 0xe8, 0xa5, 0xd5, 0xeb, 0x6e, 0xd6, 0x3f, 0x2f, 0x20, 0x93, 0x89,
-       0x0f, 0xe9, 0xdd, 0x91, 0x2e, 0x7a, 0xf5, 0x5e, 0xa3, 0x7a, 0xbf, 0x80,
-       0x3e, 0x8e, 0xc4, 0xd9, 0xce, 0xd0, 0xe7, 0x79, 0xe3, 0x4a, 0x5a, 0xb0,
-       0x9e, 0xbd, 0x0c, 0xfd, 0x32, 0x4e, 0xfa, 0x3a, 0xc9, 0xb4, 0x99, 0x2e,
-       0xce, 0xc7, 0x7c, 0x05, 0x34, 0xf1, 0xae, 0x3e, 0x00, 0x5a, 0xaf, 0x48,
-       0x59, 0x1c, 0xb6, 0x8c, 0x2b, 0x08, 0x51, 0xde, 0x65, 0x73, 0x20, 0x23,
-       0xc4, 0x6e, 0xaa, 0xa5, 0x6e, 0xd6, 0xbf, 0x8b, 0x78, 0x80, 0x9a, 0xab,
-       0xb4, 0x4e, 0xeb, 0xc7, 0x2e, 0x9a, 0xac, 0x8b, 0x6c, 0xc3, 0x3f, 0x44,
-       0x4e, 0xaa, 0xd3, 0x53, 0x75, 0xf6, 0x5d, 0x4c, 0x8b, 0xeb, 0x82, 0x7d,
-       0xfa, 0xdd, 0xe0, 0xc1, 0x19, 0xc6, 0x3b, 0xcc, 0xab, 0x9f, 0xe5, 0x73,
-       0x6b, 0x61, 0xdc, 0x4c, 0x9a, 0x37, 0xb3, 0x45, 0x46, 0x03, 0xfa, 0x5e,
-       0xc1, 0xeb, 0xbd, 0x8b, 0x75, 0xdf, 0x01, 0xaf, 0x03, 0xc0, 0x45, 0x0c,
-       0x4d, 0x35, 0xaf, 0xf1, 0x9a, 0x5c, 0xe3, 0x54, 0x1d, 0x39, 0xe0, 0xc6,
-       0x1a, 0x98, 0xab, 0x0b, 0xec, 0xf3, 0x57, 0x65, 0xfe, 0xac, 0x22, 0xff,
-       0xb9, 0x3c, 0xf2, 0x4c, 0x90, 0x5f, 0x3c, 0x07, 0x59, 0xc7, 0xe8, 0xb5,
-       0x59, 0xae, 0x2f, 0x0f, 0x51, 0x39, 0xb1, 0x7e, 0x6c, 0xca, 0x44, 0x4d,
-       0x8f, 0x38, 0x50, 0xde, 0x37, 0xe0, 0xeb, 0x55, 0x3f, 0xe3, 0x3c, 0x27,
-       0xcf, 0xa4, 0x2c, 0x5a, 0xe9, 0x8b, 0x5a, 0x1a, 0xf8, 0x3c, 0x77, 0x29,
-       0x38, 0xcf, 0x6f, 0x83, 0x1f, 0xf4, 0xeb, 0x3d, 0x81, 0xff, 0x4b, 0x40,
-       0x57, 0x87, 0xf4, 0xc3, 0x14, 0x0b, 0xfc, 0x5f, 0x82, 0x5e, 0x3d, 0xad,
-       0x42, 0x87, 0x58, 0x7f, 0xfa, 0xbb, 0x37, 0xf5, 0x87, 0xdf, 0xad, 0x1f,
-       0x73, 0xc0, 0x63, 0x7e, 0xae, 0x95, 0x0a, 0xd5, 0x18, 0x4d, 0x65, 0x91,
-       0x73, 0x23, 0xfe, 0xe4, 0xa1, 0x4b, 0x85, 0x1a, 0xeb, 0x72, 0x29, 0xd0,
-       0xe5, 0x78, 0x40, 0xfb, 0x6f, 0xa0, 0xcb, 0x46, 0x7a, 0x55, 0x70, 0x7d,
-       0xd5, 0x27, 0x6b, 0x64, 0x15, 0xf6, 0x55, 0xac, 0x70, 0x2c, 0x62, 0xdb,
-       0xa2, 0xe3, 0xcc, 0x7f, 0xb1, 0x32, 0x2a, 0x8a, 0x8d, 0xac, 0x28, 0xba,
-       0xcc, 0xdf, 0x3e, 0xf0, 0xad, 0xc8, 0x3a, 0x78, 0xa1, 0xf1, 0xae, 0xb7,
-       0xb0, 0x6f, 0x07, 0xfa, 0xd0, 0xfd, 0x71, 0x3e, 0xdf, 0xeb, 0x99, 0xaf,
-       0xb4, 0x2d, 0x58, 0xde, 0x49, 0x5a, 0x1e, 0x7c, 0xa9, 0x8b, 0x73, 0xb4,
-       0xb3, 0x83, 0x4c, 0x1f, 0x7c, 0x24, 0x93, 0xb4, 0xe8, 0xf2, 0x1a, 0x2c,
-       0x17, 0xf8, 0xba, 0x39, 0x9d, 0x1e, 0x96, 0xe7, 0xc7, 0xba, 0xc5, 0xf7,
-       0x4d, 0x2a, 0xe5, 0x13, 0x03, 0xfa, 0x43, 0x64, 0x5c, 0x59, 0x53, 0x8d,
-       0xea, 0x24, 0xe2, 0xea, 0xc2, 0xbc, 0x4a, 0x7b, 0x64, 0x1d, 0xc6, 0x67,
-       0x64, 0x9c, 0x84, 0x35, 0x06, 0x7b, 0xff, 0x8d, 0xa6, 0xbd, 0x77, 0xd2,
-       0xc5, 0xd3, 0x9f, 0x85, 0xdd, 0xb3, 0x5c, 0xb5, 0xf4, 0x11, 0xe4, 0x19,
-       0x73, 0x04, 0xf9, 0x22, 0x7f, 0xb6, 0x53, 0xe1, 0xb9, 0xb0, 0xbc, 0x77,
-       0x49, 0xf9, 0x0b, 0x29, 0xff, 0x1b, 0xa8, 0xdc, 0xeb, 0xdb, 0x38, 0xbf,
-       0x13, 0xa0, 0xe1, 0xbf, 0xe3, 0xf1, 0x67, 0x90, 0x1f, 0xf1, 0xbb, 0x9a,
-       0x8f, 0x47, 0x3d, 0x4c, 0x07, 0xef, 0xfe, 0x10, 0x6b, 0xb2, 0x8c, 0xc3,
-       0xf9, 0x0e, 0xf2, 0x6d, 0x29, 0x94, 0x3b, 0x12, 0x8c, 0x7a, 0x92, 0x7e,
-       0xad, 0x9e, 0xa2, 0x89, 0x7a, 0x3f, 0x15, 0xea, 0x69, 0x9c, 0xc1, 0x13,
-       0xdd, 0xbc, 0xb7, 0xfc, 0x12, 0xf6, 0x23, 0x98, 0xd7, 0x1a, 0x1d, 0x71,
-       0x43, 0x7e, 0xe2, 0x01, 0x7f, 0x5a, 0x30, 0x8e, 0x05, 0x3c, 0x34, 0xd3,
-       0x8b, 0x83, 0x96, 0x0d, 0x3a, 0x67, 0x02, 0x3a, 0xec, 0x47, 0xc0, 0xeb,
-       0x44, 0x8a, 0x96, 0x5c, 0xe6, 0x63, 0x27, 0x95, 0x93, 0xdc, 0x7f, 0x0e,
-       0x7a, 0xc6, 0x74, 0x76, 0x70, 0x7e, 0xb3, 0x45, 0xc6, 0x47, 0xeb, 0x25,
-       0xc8, 0x98, 0xe5, 0xcb, 0x70, 0x71, 0x5a, 0xf8, 0x25, 0x3e, 0xbf, 0x21,
-       0xe4, 0xf8, 0xac, 0x0b, 0x3b, 0x03, 0xbd, 0xf2, 0xd7, 0x2c, 0xcc, 0x75,
-       0xe2, 0xac, 0x78, 0xdd, 0x76, 0xba, 0x07, 0x76, 0x9f, 0xaf, 0xf1, 0xfa,
-       0x13, 0xd0, 0xa3, 0x1f, 0xcb, 0xf5, 0x0b, 0x4b, 0xbd, 0x01, 0x3e, 0xe3,
-       0x76, 0x6e, 0xc3, 0x6d, 0xa5, 0x03, 0x55, 0xfd, 0x63, 0xf0, 0x7f, 0x13,
-       0xf8, 0x82, 0xce, 0x64, 0x19, 0x9f, 0xe9, 0x00, 0xae, 0x96, 0xfc, 0x04,
-       0x3a, 0x09, 0x59, 0xef, 0xe7, 0x6b, 0xad, 0x94, 0xaf, 0x86, 0xb4, 0x98,
-       0xce, 0x87, 0xa8, 0x87, 0xbf, 0x2c, 0x69, 0x4d, 0x49, 0x5a, 0x78, 0x5f,
-       0x63, 0x9f, 0x73, 0x3b, 0xf0, 0xe3, 0xec, 0xff, 0x69, 0x21, 0xd1, 0x41,
-       0x0b, 0xb2, 0xa6, 0x6f, 0xf7, 0x7d, 0x4d, 0xa2, 0x0d, 0xef, 0x77, 0xc1,
-       0xe6, 0x87, 0x90, 0x5b, 0x74, 0x62, 0x2e, 0xbd, 0x6d, 0x6e, 0x3b, 0xff,
-       0xb1, 0x6d, 0xfc, 0xeb, 0x80, 0xeb, 0xc1, 0x9a, 0x3e, 0x5c, 0x01, 0x70,
-       0xd3, 0x73, 0x90, 0xb3, 0xc5, 0x7e, 0x85, 0xe3, 0xe4, 0x75, 0x92, 0x97,
-       0xe9, 0x25, 0x05, 0x70, 0xbd, 0xc0, 0x0d, 0xc7, 0xbe, 0x1c, 0xaa, 0xa0,
-       0xf3, 0xcd, 0x9a, 0xbc, 0xbb, 0xc0, 0x19, 0xf4, 0x24, 0x78, 0xef, 0xe5,
-       0xda, 0xa7, 0xc9, 0xec, 0xba, 0x26, 0x79, 0xb1, 0xac, 0x98, 0x5f, 0xe6,
-       0x15, 0x7a, 0x8a, 0x38, 0xe4, 0x58, 0xa8, 0x0b, 0x13, 0x2a, 0x15, 0xb2,
-       0x3a, 0xf2, 0x73, 0xbe, 0xb7, 0x65, 0xbb, 0xd4, 0xf9, 0xae, 0x34, 0x26,
-       0x4c, 0x8e, 0xb5, 0x9a, 0xdc, 0xfb, 0x91, 0x25, 0xbe, 0xbb, 0x4d, 0xf3,
-       0x5d, 0x5f, 0x86, 0xb0, 0xf7, 0x07, 0x97, 0x4c, 0x7a, 0xa4, 0x9e, 0xa1,
-       0x87, 0xea, 0x86, 0x7e, 0x3f, 0x7c, 0x40, 0x71, 0xe3, 0x4e, 0xf7, 0x73,
-       0x09, 0xae, 0x45, 0x34, 0xe4, 0x81, 0x2d, 0xa6, 0x9f, 0x17, 0x94, 0xb9,
-       0x66, 0x9b, 0x33, 0xf8, 0x1e, 0x47, 0xaf, 0xd1, 0xf6, 0xdc, 0xe1, 0xff,
-       0x32, 0x6f, 0xe0, 0xf5, 0xd9, 0x5f, 0x23, 0x4f, 0x70, 0x91, 0x27, 0xb8,
-       0xc8, 0x13, 0x5c, 0xe4, 0x09, 0x2e, 0xf2, 0x04, 0x17, 0x79, 0x82, 0x8b,
-       0x3c, 0xc1, 0x45, 0x9e, 0x80, 0xd8, 0xed, 0xd7, 0x0b, 0x63, 0xc8, 0x7f,
-       0xe1, 0xbf, 0xdc, 0xcf, 0x43, 0x4e, 0x7c, 0xdf, 0xc9, 0x31, 0x87, 0x63,
-       0x33, 0xcf, 0xad, 0xee, 0x70, 0xf8, 0xdc, 0xa4, 0xef, 0xbb, 0x13, 0x73,
-       0xe3, 0x41, 0x3e, 0xc2, 0x30, 0x61, 0xec, 0x66, 0x38, 0x1a, 0x75, 0x2c,
-       0x05, 0x36, 0xc6, 0xf9, 0x8a, 0x1f, 0xb3, 0xfc, 0x5c, 0xf9, 0x75, 0xe4,
-       0x2c, 0x69, 0xe4, 0x2c, 0xfd, 0xc8, 0x4f, 0xf8, 0x8e, 0x3b, 0xbc, 0x63,
-       0xb2, 0x95, 0xc3, 0xee, 0x98, 0x72, 0xb7, 0xcb, 0xb9, 0xb4, 0x99, 0x2e,
-       0x0a, 0x31, 0xd7, 0x43, 0x1e, 0xe5, 0x47, 0xbe, 0x86, 0xbc, 0xf5, 0x9b,
-       0xf2, 0x3e, 0x6d, 0x7c, 0x90, 0xcf, 0x7c, 0xe5, 0x1a, 0xb9, 0x6b, 0x28,
-       0x5f, 0xff, 0x1e, 0x50, 0x2c, 0xb0, 0xfc, 0x88, 0xba, 0xcf, 0x43, 0xe0,
-       0xe7, 0x63, 0x94, 0x58, 0xde, 0x89, 0x39, 0x9d, 0x7a, 0xe4, 0x5d, 0x12,
-       0x8e, 0xf2, 0xbc, 0xd6, 0x43, 0xed, 0x26, 0x89, 0xf3, 0x7c, 0xe3, 0xc0,
-       0x74, 0xd9, 0xbf, 0x5e, 0x3a, 0x96, 0xaf, 0x5d, 0x92, 0x3a, 0x75, 0xb8,
-       0x5e, 0x40, 0x7d, 0xd4, 0x07, 0x18, 0x0d, 0xb5, 0x55, 0x48, 0x9b, 0x69,
-       0x5e, 0x4d, 0xc8, 0x9a, 0xe7, 0xfc, 0xc6, 0x79, 0xe2, 0xac, 0x79, 0x9d,
-       0x4b, 0xc7, 0xca, 0x55, 0x23, 0xc5, 0xb5, 0xb2, 0xad, 0x5f, 0x3a, 0x76,
-       0x02, 0x34, 0x16, 0x91, 0x1b, 0xa8, 0x72, 0xed, 0x4b, 0xc7, 0xa6, 0xab,
-       0xfe, 0x7d, 0x96, 0xcf, 0x03, 0xe2, 0x60, 0xb6, 0x9d, 0xd4, 0x05, 0xff,
-       0x5e, 0x4b, 0x48, 0x5c, 0xc6, 0x63, 0x7c, 0x0d, 0x78, 0x7c, 0x6e, 0x19,
-       0xe0, 0xf2, 0xd9, 0x31, 0x0f, 0x97, 0x8e, 0x95, 0x6a, 0xcd, 0x3c, 0x30,
-       0x1d, 0xa6, 0x1b, 0xee, 0x87, 0xf7, 0x92, 0x20, 0xb1, 0xec, 0x79, 0xc5,
-       0x91, 0xfe, 0x20, 0xef, 0x3a, 0x81, 0xfc, 0x4e, 0x93, 0x7a, 0xee, 0x8f,
-       0xff, 0x4c, 0xc6, 0xa9, 0xb4, 0xe0, 0x79, 0x7e, 0xe2, 0x5d, 0xf6, 0x3b,
-       0x98, 0xc3, 0x78, 0x31, 0x84, 0x15, 0x01, 0x6c, 0x47, 0x93, 0x3c, 0x5b,
-       0x82, 0xf5, 0x98, 0x27, 0xde, 0xe7, 0xcf, 0xb1, 0x7f, 0x79, 0x07, 0xc7,
-       0xf9, 0x18, 0xd6, 0xc5, 0x59, 0xba, 0xff, 0x5b, 0xd9, 0x37, 0xef, 0x89,
-       0x65, 0xaa, 0x01, 0x87, 0xe1, 0x99, 0x46, 0x88, 0x83, 0x17, 0xe7, 0x7d,
-       0x3c, 0xb1, 0x71, 0xff, 0xf7, 0x49, 0xeb, 0x36, 0xf3, 0x1a, 0xae, 0x1f,
-       0xd2, 0xc9, 0xf8, 0xe7, 0xb6, 0x81, 0x2f, 0xff, 0x4f, 0x31, 0x3c, 0xa1,
-       0x8b, 0x1f, 0xb9, 0x47, 0xcd, 0x34, 0xd5, 0xa1, 0xe1, 0xfd, 0x05, 0xdf,
-       0x07, 0x70, 0x7d, 0xcf, 0xdf, 0x1a, 0x9a, 0x6b, 0xc5, 0x67, 0x83, 0x58,
-       0xd6, 0x47, 0xb6, 0xc6, 0x75, 0xc3, 0x85, 0x60, 0xbc, 0x0b, 0xb1, 0x8d,
-       0xc7, 0x0d, 0xc8, 0x17, 0xba, 0x6c, 0xb5, 0x07, 0x75, 0x4b, 0xc2, 0xff,
-       0x26, 0x94, 0x61, 0x3b, 0xe2, 0xba, 0xaf, 0x2d, 0x98, 0x0b, 0xed, 0x88,
-       0xfd, 0xb0, 0x16, 0xcc, 0xb1, 0xbf, 0x15, 0xa8, 0x5d, 0xb8, 0x0f, 0x3a,
-       0x8b, 0xcd, 0xb6, 0x14, 0x3e, 0x13, 0x74, 0x6e, 0x3e, 0xf4, 0x5b, 0xf0,
-       0x29, 0x83, 0x5a, 0xe0, 0xfb, 0xe3, 0xf0, 0x7d, 0x9d, 0x74, 0x00, 0x3e,
-       0xeb, 0x20, 0x7c, 0xd6, 0x21, 0xd4, 0x8b, 0x63, 0x4b, 0xcd, 0xf7, 0xbc,
-       0x5c, 0xa3, 0x76, 0x2a, 0x47, 0xe4, 0xf9, 0x97, 0x3c, 0xd5, 0xfc, 0x10,
-       0x3a, 0xc0, 0x75, 0x57, 0xa8, 0x13, 0xf0, 0xb7, 0x56, 0x02, 0x3a, 0xb1,
-       0xfd, 0x3e, 0x39, 0x03, 0xdb, 0x68, 0xb7, 0x85, 0xcc, 0xe5, 0x7c, 0xd9,
-       0x97, 0x6b, 0xbe, 0xec, 0xe1, 0x97, 0x41, 0x5f, 0xa3, 0x52, 0x5d, 0xa7,
-       0x12, 0xd6, 0x2d, 0x61, 0xdd, 0x12, 0xea, 0xbc, 0xe9, 0x7a, 0xf3, 0x77,
-       0xaf, 0x8e, 0x80, 0x77, 0xc6, 0x0d, 0xfb, 0x7a, 0xd3, 0xfe, 0xc3, 0xe7,
-       0x49, 0xc8, 0xff, 0x11, 0xc8, 0xff, 0x28, 0xea, 0x9b, 0xdf, 0x47, 0x7d,
-       0xf3, 0x7b, 0xa8, 0x6f, 0x8e, 0xa0, 0xbe, 0x99, 0x44, 0x7d, 0xf3, 0x65,
-       0xf8, 0x8f, 0xfb, 0xe0, 0x3f, 0x26, 0xe0, 0x3f, 0xc6, 0xe5, 0xdd, 0xd3,
-       0x61, 0x77, 0xfb, 0x9d, 0x4a, 0xb8, 0x16, 0xb7, 0x9f, 0x12, 0x99, 0x25,
-       0xec, 0x69, 0x8c, 0x6a, 0x0d, 0xae, 0x6f, 0x2c, 0x72, 0x46, 0xb9, 0xbe,
-       0x99, 0x50, 0x26, 0x91, 0xbf, 0xdf, 0x3f, 0xcc, 0x75, 0x4f, 0x42, 0xc9,
-       0xcb, 0xba, 0xc7, 0xb8, 0xe0, 0x20, 0x75, 0x43, 0xee, 0x87, 0x3d, 0x1b,
-       0xe7, 0xf2, 0xe0, 0xc5, 0xcf, 0xf9, 0xba, 0x03, 0xbf, 0x17, 0xa7, 0xc5,
-       0x59, 0xd4, 0x0c, 0xee, 0x3f, 0x28, 0x45, 0xe9, 0x1b, 0x75, 0x8c, 0x51,
-       0x2b, 0xbb, 0xaf, 0x06, 0xe3, 0x11, 0x9a, 0x9a, 0x47, 0x6d, 0x7b, 0xfa,
-       0x6f, 0x95, 0xbc, 0x1c, 0x5b, 0x18, 0x23, 0xdf, 0x3d, 0xfd, 0xd7, 0xc1,
-       0xb8, 0x14, 0xe8, 0x43, 0xc0, 0xab, 0x6e, 0xe1, 0xd9, 0x15, 0xe4, 0x1c,
-       0x2f, 0xf6, 0x6c, 0xfd, 0x3f, 0xef, 0xb8, 0xb5, 0x28, 0x64, 0x1e, 0xdf,
-       0xe5, 0xd7, 0x67, 0xcd, 0xf3, 0x9d, 0x4d, 0xf3, 0xba, 0xfc, 0x0e, 0x5b,
-       0xac, 0xb4, 0xbd, 0x07, 0x0f, 0x4c, 0x4b, 0x83, 0x46, 0xd5, 0xa6, 0x0f,
-       0x3d, 0xfe, 0x5e, 0xe8, 0x88, 0x76, 0xf9, 0x0d, 0xcf, 0x91, 0xf7, 0x7a,
-       0xb0, 0xf3, 0x91, 0x27, 0x77, 0xf9, 0xbe, 0x80, 0xfb, 0x49, 0xc5, 0xf7,
-       0xef, 0x8f, 0x83, 0x0e, 0x64, 0xed, 0x36, 0xd7, 0x70, 0x7a, 0x70, 0x97,
-       0xa2, 0x1f, 0x9f, 0xe1, 0xb3, 0x96, 0xb4, 0xb9, 0xd6, 0xe3, 0xba, 0x2f,
-       0x8c, 0x01, 0x21, 0xad, 0xff, 0x48, 0xfa, 0x7c, 0xdf, 0x87, 0x9a, 0x8e,
-       0x61, 0xc2, 0x71, 0x73, 0xfd, 0x17, 0x0f, 0xee, 0xe1, 0x98, 0xd7, 0x58,
-       0xc0, 0xab, 0x16, 0xd0, 0xfb, 0x77, 0xcf, 0xf7, 0x3d, 0x8c, 0xaf, 0x37,
-       0xe1, 0x5f, 0x40, 0xae, 0xc7, 0x77, 0x26, 0xbb, 0xe5, 0x77, 0xc9, 0x77,
-       0x66, 0x3b, 0xe8, 0xed, 0x53, 0xc8, 0x59, 0x2d, 0x23, 0x73, 0x09, 0xb5,
-       0xc7, 0x32, 0xdb, 0xc9, 0x08, 0xf3, 0x39, 0x90, 0x9e, 0xa6, 0x9b, 0x7b,
-       0xfc, 0x5c, 0xfc, 0xab, 0xca, 0x47, 0xf9, 0x16, 0xc1, 0x3a, 0x3f, 0x6a,
-       0x5a, 0x27, 0xdd, 0xb4, 0xce, 0x0a, 0xdb, 0x6c, 0xed, 0x4b, 0xd8, 0x73,
-       0x69, 0xf7, 0xcd, 0x7a, 0x32, 0xa8, 0xcb, 0x1e, 0x1e, 0x69, 0xa3, 0x6a,
-       0xaf, 0xb1, 0xf2, 0x1a, 0xf2, 0xf5, 0xe2, 0x08, 0xe6, 0x92, 0x03, 0x78,
-       0xc7, 0xf3, 0x46, 0x8d, 0x84, 0xb1, 0x52, 0xa3, 0xcf, 0x01, 0xdf, 0x28,
-       0x11, 0xf1, 0x3c, 0xf7, 0x25, 0x6f, 0xb5, 0xc0, 0x07, 0xa4, 0xd6, 0xb0,
-       0xe7, 0x49, 0xd4, 0x5f, 0x47, 0x37, 0xea, 0x61, 0x5e, 0xe7, 0x56, 0x65,
-       0x4d, 0xe6, 0xc6, 0xfb, 0x95, 0x52, 0xd2, 0xdf, 0xe3, 0xef, 0xc2, 0x5f,
-       0xa8, 0x82, 0x71, 0xdf, 0x01, 0x6d, 0x85, 0x16, 0x4e, 0xa9, 0xf2, 0x0e,
-       0xb6, 0x38, 0xc2, 0x67, 0xcd, 0xcf, 0x8f, 0x93, 0x5d, 0xb8, 0xa7, 0x3f,
-       0x0d, 0xf6, 0x34, 0x16, 0xd4, 0xd3, 0xe1, 0x9e, 0x62, 0xf4, 0xe6, 0xac,
-       0x0e, 0xdc, 0x9b, 0x20, 0x8f, 0x02, 0x2d, 0x35, 0xd2, 0x9f, 0x42, 0xa7,
-       0xd2, 0x24, 0x1b, 0x6d, 0xdb, 0x19, 0x96, 0x36, 0x6b, 0xf8, 0xf1, 0x14,
-       0xec, 0xf0, 0x78, 0x4f, 0x78, 0x37, 0xac, 0x9a, 0x1e, 0xd7, 0x3d, 0x68,
-       0x3c, 0xdf, 0x0f, 0x5b, 0x4c, 0xc3, 0x3e, 0x39, 0x67, 0x2a, 0x70, 0xad,
-       0xc2, 0xf6, 0xa4, 0x3b, 0xaa, 0xa1, 0x4f, 0x50, 0x06, 0xf5, 0x0e, 0xef,
-       0x3f, 0x47, 0x8b, 0x8d, 0x90, 0x87, 0x2c, 0xec, 0x71, 0x14, 0xbf, 0x61,
-       0xbc, 0xb3, 0xf0, 0xe3, 0x5a, 0x69, 0x85, 0x1e, 0x95, 0xb9, 0x38, 0x72,
-       0xed, 0x41, 0xe6, 0xef, 0x4e, 0xc0, 0xb3, 0x3e, 0xb3, 0x9e, 0xde, 0x49,
-       0x4e, 0x2f, 0xfb, 0x8a, 0x14, 0x68, 0x03, 0xc7, 0x5d, 0x87, 0xad, 0xf7,
-       0xe3, 0x69, 0xe8, 0x45, 0x96, 0xad, 0xa4, 0xef, 0x79, 0x6a, 0x96, 0xbf,
-       0x51, 0x5c, 0x08, 0xc6, 0x03, 0xfa, 0x3d, 0xac, 0x7b, 0xa9, 0x1b, 0x68,
-       0x65, 0x3e, 0x8c, 0x83, 0x67, 0x60, 0x83, 0x7c, 0x67, 0x3b, 0x06, 0xb9,
-       0xf0, 0x58, 0x09, 0xe2, 0x21, 0xe6, 0x17, 0x91, 0x94, 0xb4, 0xe7, 0x68,
-       0x19, 0xf5, 0x3f, 0xf5, 0xf2, 0x13, 0xf9, 0xae, 0xbb, 0x33, 0xd0, 0xf7,
-       0xad, 0xf8, 0xaa, 0xc9, 0xfd, 0x31, 0xf0, 0xa7, 0x35, 0xe1, 0x33, 0x8e,
-       0x5f, 0x9f, 0xac, 0x11, 0xe2, 0x71, 0xca, 0xfb, 0x82, 0xc8, 0x3d, 0x4d,
-       0xbf, 0x23, 0xf7, 0x54, 0xa7, 0x23, 0xf3, 0xa8, 0x6d, 0xb3, 0x03, 0x99,
-       0x45, 0x32, 0x32, 0x27, 0x68, 0x48, 0x3f, 0x40, 0xaa, 0xfc, 0xd6, 0x97,
-       0x16, 0xde, 0x17, 0x5a, 0x72, 0x9e, 0x77, 0x06, 0xbc, 0xbf, 0x28, 0xd7,
-       0x79, 0x1a, 0xfc, 0x43, 0x56, 0xb2, 0x26, 0x61, 0x5e, 0xf1, 0x4c, 0x32,
-       0xbf, 0x15, 0x3a, 0xd2, 0xf8, 0x61, 0x70, 0x36, 0x8f, 0x90, 0xe3, 0xbe,
-       0xa5, 0x3a, 0x66, 0x05, 0xb0, 0xdf, 0x09, 0x78, 0xcb, 0x81, 0x5f, 0xac,
-       0xdf, 0x58, 0x4f, 0xb2, 0x6f, 0xe0, 0x33, 0x77, 0x90, 0x35, 0x3a, 0x23,
-       0xc8, 0xa3, 0x92, 0xd7, 0xf2, 0x03, 0x09, 0xda, 0xea, 0x07, 0x18, 0x2f,
-       0xf1, 0x31, 0xba, 0xc2, 0x7c, 0x94, 0xa4, 0xff, 0x94, 0x71, 0x4b, 0xd2,
-       0x53, 0xb7, 0xf9, 0x82, 0x6f, 0xc9, 0xe7, 0xaa, 0xca, 0xbe, 0x89, 0xe3,
-       0x1f, 0xeb, 0x70, 0x27, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x9c, 0x9f, 0xe7,
-       0xfb, 0x89, 0x41, 0xbe, 0x57, 0x3a, 0x57, 0xc0, 0xd9, 0x2e, 0xf0, 0xf7,
-       0xc7, 0xa4, 0x5f, 0x63, 0xfa, 0xf5, 0x57, 0x9a, 0x7d, 0x21, 0xda, 0x92,
-       0xf4, 0x93, 0x05, 0xf9, 0xbd, 0x31, 0x01, 0x18, 0x8f, 0x7d, 0x67, 0xd3,
-       0xdf, 0x58, 0xbc, 0x6c, 0xfb, 0x7f, 0x63, 0x11, 0x7c, 0xfb, 0xad, 0xf9,
-       0x79, 0xc4, 0x83, 0x75, 0x8d, 0x26, 0xeb, 0xe1, 0xdf, 0x5c, 0xf0, 0x39,
-       0xc0, 0x37, 0xd7, 0xc3, 0xdc, 0xc1, 0x93, 0xf1, 0xa5, 0xbc, 0xe5, 0x2c,
-       0x97, 0x82, 0x9c, 0x88, 0x6b, 0x00, 0x96, 0x21, 0xc6, 0x8b, 0xfe, 0xf9,
-       0x2d, 0x88, 0x3d, 0x38, 0x3f, 0xc8, 0x1c, 0x7c, 0xbd, 0x39, 0xeb, 0xd7,
-       0xb9, 0x65, 0xf6, 0x8b, 0xfd, 0x61, 0xdd, 0xbb, 0x9b, 0xca, 0x13, 0xfc,
-       0x3e, 0x46, 0x6f, 0xcc, 0xc6, 0xe4, 0xfb, 0x22, 0xc5, 0x82, 0xf7, 0x3c,
-       0x4e, 0x50, 0x51, 0xbe, 0xaf, 0x05, 0xf4, 0x50, 0xa7, 0xdd, 0x17, 0x8e,
-       0x35, 0xe5, 0x48, 0xc3, 0xc7, 0x9b, 0x6a, 0xd4, 0xe8, 0xd1, 0xc6, 0x2a,
-       0xf6, 0xaf, 0x50, 0x7e, 0xbc, 0x44, 0x37, 0x98, 0xba, 0x8c, 0xfb, 0x4e,
-       0x82, 0x75, 0x8c, 0xf5, 0x6b, 0x4c, 0xd6, 0x9d, 0x25, 0xe4, 0x0b, 0xc5,
-       0x11, 0xfe, 0xc6, 0xf3, 0xde, 0x5d, 0xc5, 0x8a, 0xa1, 0xdb, 0xf4, 0x81,
-       0xe7, 0x68, 0x3c, 0x26, 0x21, 0x72, 0xab, 0x77, 0x3d, 0x58, 0xbf, 0x78,
-       0x97, 0xbf, 0x57, 0xbc, 0xaf, 0x33, 0xac, 0x2a, 0xbf, 0xcd, 0xfe, 0xe4,
-       0x76, 0x8d, 0xd6, 0x6e, 0xf7, 0xbc, 0xfb, 0x2d, 0x9d, 0x9c, 0xa0, 0x76,
-       0xf5, 0xbf, 0xb9, 0xb7, 0xcb, 0x1c, 0xc4, 0x19, 0x49, 0x2b, 0x05, 0xd8,
-       0xeb, 0xb2, 0x8b, 0x3a, 0x47, 0x18, 0xa3, 0xab, 0x42, 0x47, 0xcc, 0xe5,
-       0x3b, 0x80, 0x3b, 0x7a, 0xf8, 0x7b, 0xf3, 0x8c, 0xc5, 0x30, 0x7d, 0xfe,
-       0x5d, 0xd7, 0x2d, 0xf7, 0x49, 0x3f, 0x4b, 0x14, 0xc4, 0x9e, 0x5b, 0x9a,
-       0x6d, 0xa2, 0x39, 0xb7, 0x64, 0x5b, 0xa0, 0x49, 0x0d, 0xbc, 0x94, 0x2b,
-       0x61, 0x9e, 0xc6, 0x7f, 0x4b, 0xb0, 0x7a, 0xd7, 0x37, 0xc0, 0xe7, 0x34,
-       0xf8, 0xe4, 0x7d, 0x4c, 0xd7, 0x43, 0x9d, 0x0b, 0x6b, 0x05, 0xee, 0x23,
-       0xe6, 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x22, 0xe6,
-       0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x8e, 0x07, 0x79,
-       0xda, 0x63, 0x1b, 0x79, 0xda, 0x4a, 0x83, 0xbf, 0x43, 0x49, 0x5e, 0x4a,
-       0x25, 0xf2, 0xf3, 0x5c, 0x12, 0x9c, 0xd3, 0x84, 0x79, 0xee, 0xc7, 0x7f,
-       0x13, 0xf1, 0xf1, 0x38, 0xc7, 0x63, 0xbc, 0x92, 0x22, 0x4c, 0xc6, 0xf3,
-       0xf3, 0x3c, 0xae, 0xad, 0xb6, 0xe2, 0x20, 0x5f, 0xcb, 0xb1, 0x3f, 0x63,
-       0xbb, 0x48, 0xfa, 0xf5, 0x62, 0xee, 0xf5, 0x2f, 0xa1, 0x76, 0x3c, 0x5e,
-       0xac, 0xcb, 0x18, 0x8c, 0xf1, 0x7b, 0x18, 0x6b, 0xac, 0x73, 0xfc, 0xee,
-       0x5e, 0xae, 0x27, 0x8a, 0xf5, 0x14, 0x95, 0x16, 0xc3, 0xfc, 0x07, 0x78,
-       0xee, 0x90, 0x52, 0xa8, 0xf2, 0xd9, 0x0a, 0x9a, 0x4e, 0x42, 0x28, 0x66,
-       0x73, 0x5e, 0x77, 0x49, 0xd6, 0x48, 0xfe, 0xdf, 0x05, 0x0d, 0x83, 0xb7,
-       0xf0, 0x1e, 0x97, 0x48, 0x9d, 0x4d, 0xca, 0xbf, 0x31, 0x48, 0x98, 0x83,
-       0xf2, 0x6f, 0x1d, 0xba, 0xb1, 0x8e, 0x98, 0xdd, 0x13, 0xfe, 0xed, 0x06,
-       0xd7, 0x5d, 0xf6, 0xe6, 0xfd, 0x2b, 0xef, 0x23, 0x09, 0x7b, 0xbd, 0xa7,
-       0x0f, 0x7b, 0xc3, 0xb9, 0x5e, 0xd9, 0x25, 0xf3, 0x6e, 0xf8, 0xce, 0x33,
-       0x83, 0x37, 0xf5, 0x52, 0xe7, 0x6e, 0x5a, 0x1e, 0xe4, 0x1a, 0xad, 0x0d,
-       0xf4, 0x18, 0xd6, 0xc8, 0xd8, 0x62, 0x37, 0x9d, 0x9d, 0x87, 0x6f, 0x9d,
-       0x37, 0x2c, 0xfe, 0xfb, 0x82, 0x85, 0xc1, 0x24, 0x7c, 0xf2, 0x78, 0x2f,
-       0xc7, 0xe4, 0xc5, 0x06, 0xeb, 0x4a, 0x37, 0xf0, 0xfb, 0xa1, 0x8b, 0x3b,
-       0x60, 0x43, 0x02, 0xeb, 0x87, 0xb4, 0xff, 0x53, 0xd2, 0xee, 0x36, 0xf3,
-       0x7d, 0x52, 0x37, 0x84, 0xa1, 0xa7, 0x05, 0x78, 0xff, 0x48, 0x6d, 0x69,
-       0x11, 0x7f, 0x2f, 0x9c, 0x76, 0x9b, 0xbf, 0x1b, 0x0e, 0x29, 0xc5, 0x2a,
-       0xff, 0x8d, 0xc3, 0x20, 0xfd, 0x4f, 0xe1, 0x56, 0x17, 0xd3, 0xd6, 0x79,
-       0x86, 0xdf, 0xcf, 0xe6, 0x2f, 0xc4, 0x81, 0x13, 0xe2, 0x80, 0x41, 0x54,
-       0xf3, 0x31, 0x07, 0xe2, 0xca, 0x44, 0x3d, 0x20, 0x32, 0x59, 0x15, 0x52,
-       0x2d, 0xdb, 0x50, 0xb7, 0x5d, 0x36, 0x77, 0xcb, 0xa6, 0x4c, 0xda, 0x22,
-       0x06, 0x49, 0x9b, 0x6a, 0xd2, 0x2e, 0x76, 0x31, 0xed, 0x2e, 0x96, 0x81,
-       0x34, 0xcd, 0xec, 0x1a, 0x56, 0x32, 0xa4, 0x5d, 0x4c, 0xae, 0x31, 0x04,
-       0x88, 0x53, 0xab, 0x5b, 0x2f, 0x32, 0x4d, 0x53, 0x90, 0x57, 0x25, 0xdd,
-       0x4d, 0x6f, 0x76, 0x3f, 0x55, 0x64, 0xad, 0x72, 0xd1, 0x25, 0x6a, 0xa7,
-       0x6a, 0x7f, 0x17, 0x67, 0xcf, 0xf3, 0x9d, 0x63, 0x20, 0x6c, 0xd5, 0x90,
-       0xac, 0xf3, 0x9d, 0xef, 0x7c, 0xff, 0xdf, 0xfb, 0x3e, 0xef, 0x2f, 0x53,
-       0xa0, 0x2f, 0xc3, 0x8a, 0xa9, 0x4b, 0x65, 0xb6, 0xb1, 0x50, 0xa6, 0x1d,
-       0x7e, 0x13, 0xbc, 0xdc, 0x23, 0x8b, 0xa0, 0xe3, 0xfc, 0x68, 0xab, 0xe7,
-       0x6f, 0xed, 0xf4, 0x78, 0x38, 0xd2, 0xeb, 0xc9, 0x28, 0xad, 0x4b, 0xe6,
-       0xb5, 0x3e, 0xdd, 0x7d, 0xe8, 0xdb, 0x0f, 0xb0, 0xa6, 0x10, 0xce, 0x61,
-       0xb8, 0x57, 0xe3, 0x91, 0x8f, 0xef, 0x7d, 0x87, 0xde, 0x7b, 0x0f, 0xbd,
-       0x9f, 0xfc, 0x1f, 0xed, 0x59, 0x3e, 0x4c, 0x0f, 0x5c, 0xa7, 0x19, 0xe7,
-       0x2c, 0xf9, 0xc2, 0x84, 0x9a, 0x2b, 0x98, 0x09, 0xea, 0x02, 0x29, 0x71,
-       0x54, 0xca, 0x6e, 0x03, 0xc6, 0xb5, 0xc9, 0xc2, 0x0a, 0x68, 0x1e, 0xfb,
-       0x68, 0xb7, 0x18, 0x2f, 0x7f, 0xb6, 0x97, 0x3c, 0xd3, 0x81, 0x6b, 0xf0,
-       0x59, 0x43, 0x21, 0xb4, 0x73, 0x5e, 0xb3, 0x63, 0xc6, 0x45, 0xed, 0xbf,
-       0xa1, 0x0e, 0xe3, 0xa8, 0xbc, 0xce, 0xfd, 0x60, 0x9b, 0x16, 0x79, 0x60,
-       0x25, 0x7b, 0xbc, 0x5c, 0x22, 0xd8, 0xbb, 0x2f, 0xf6, 0x52, 0xbf, 0x78,
-       0xd5, 0xde, 0xab, 0x33, 0x76, 0x85, 0x79, 0x5a, 0x20, 0x9a, 0x97, 0x45,
-       0xca, 0x55, 0x91, 0x9b, 0xf8, 0xfd, 0xb1, 0xea, 0xc5, 0x2f, 0x14, 0x6d,
-       0xed, 0x49, 0xd9, 0x2e, 0x3d, 0x2b, 0x35, 0xc8, 0x9c, 0x2d, 0xdb, 0x71,
-       0x1e, 0xda, 0x61, 0x7d, 0xe6, 0xaf, 0x17, 0x94, 0x44, 0xc6, 0x28, 0xd3,
-       0xda, 0xe4, 0x67, 0x2b, 0xcc, 0xbb, 0x33, 0x8d, 0x87, 0xc2, 0xfc, 0xb7,
-       0x90, 0x64, 0x82, 0x7e, 0xad, 0x97, 0xca, 0xb7, 0x45, 0x3e, 0xc1, 0xb7,
-       0x4f, 0x56, 0x5e, 0xe9, 0xa5, 0xcf, 0xe5, 0xe3, 0x15, 0xbe, 0xfb, 0xf0,
-       0xf4, 0x49, 0xc3, 0xf2, 0x43, 0x7f, 0x05, 0xf0, 0x18, 0x3c, 0x77, 0xee,
-       0xf7, 0x47, 0x5c, 0x1b, 0xea, 0x68, 0xc3, 0xb6, 0x49, 0x7e, 0x18, 0x38,
-       0xa8, 0x86, 0x74, 0xbe, 0x52, 0x23, 0xa8, 0x71, 0xd9, 0x5f, 0x61, 0x5e,
-       0x9d, 0x71, 0x54, 0x63, 0x74, 0xf2, 0xf6, 0x82, 0xde, 0x0b, 0xca, 0xb9,
-       0x8a, 0x4d, 0x5a, 0x35, 0x64, 0x0b, 0xbc, 0xb6, 0x59, 0xdf, 0xea, 0xe3,
-       0x5d, 0x6d, 0xd7, 0x17, 0x7b, 0x5d, 0x1b, 0x8d, 0x75, 0xaf, 0xf7, 0xba,
-       0x75, 0x61, 0xcf, 0xe6, 0xa2, 0x6d, 0x56, 0xc6, 0xde, 0x7e, 0x2c, 0xf5,
-       0xd5, 0x9f, 0xca, 0x9d, 0xd2, 0x4f, 0xe4, 0xb7, 0xab, 0xe7, 0xa1, 0x73,
-       0x98, 0xe5, 0x1c, 0xe4, 0xc9, 0xbb, 0x75, 0xc7, 0x79, 0xd7, 0x3e, 0x07,
-       0xfb, 0xc0, 0x71, 0xfe, 0x64, 0xef, 0x48, 0x64, 0xfc, 0x7b, 0xd8, 0x73,
-       0x16, 0x3c, 0x44, 0x2c, 0xcc, 0x80, 0xde, 0x52, 0x7d, 0xd2, 0x19, 0xd0,
-       0x74, 0x32, 0x34, 0xde, 0x8a, 0x3d, 0xf8, 0x3c, 0x3d, 0x9c, 0x7b, 0x49,
-       0xf7, 0x91, 0x66, 0x7c, 0xf5, 0x0a, 0xe6, 0x6f, 0x05, 0x5f, 0x1c, 0xc5,
-       0x4f, 0xc9, 0xc3, 0x31, 0xac, 0x75, 0x8c, 0xb4, 0xd7, 0x2a, 0x91, 0x67,
-       0xb0, 0x8f, 0x6c, 0x8b, 0x3c, 0x2a, 0xdc, 0xea, 0xa5, 0x3f, 0xef, 0x51,
-       0x81, 0x65, 0xdf, 0x57, 0xbb, 0xc4, 0x91, 0x16, 0xc8, 0xef, 0x85, 0x09,
-       0x57, 0x57, 0xfa, 0x83, 0x3a, 0x85, 0xf6, 0x56, 0xee, 0x7d, 0x45, 0xdd,
-       0x2e, 0xe7, 0xb4, 0x42, 0x17, 0x9f, 0x82, 0x0e, 0x94, 0xac, 0x5f, 0x91,
-       0xc6, 0x58, 0x00, 0x6d, 0xa8, 0xa3, 0x68, 0x2c, 0x91, 0x54, 0x81, 0xf9,
-       0x5d, 0xcc, 0xb5, 0xc2, 0x1a, 0xcf, 0x11, 0x37, 0xb8, 0xc6, 0x36, 0xc6,
-       0xe0, 0xbc, 0x3a, 0x0b, 0x34, 0xc2, 0x3a, 0xd2, 0x77, 0x02, 0x3c, 0x99,
-       0xa0, 0xdc, 0xc4, 0x78, 0xa3, 0x18, 0x8f, 0xe5, 0x2e, 0x8c, 0x77, 0x45,
-       0x92, 0x76, 0x73, 0xcc, 0x38, 0xda, 0x10, 0x67, 0xe2, 0xd0, 0x1f, 0x06,
-       0x55, 0x7a, 0x25, 0x08, 0xf9, 0xdd, 0x2b, 0x69, 0xe3, 0xc8, 0x81, 0x3d,
-       0xe6, 0xb4, 0x7d, 0xe0, 0xf3, 0x8d, 0x7a, 0x6b, 0xea, 0x3a, 0xb0, 0x26,
-       0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x72, 0x65, 0x09, 0x38, 0xb5, 0xf4, 0x41,
-       0xd2, 0xbe, 0x20, 0xa9, 0x20, 0xd7, 0xc4, 0xfa, 0x20, 0xd6, 0x4c, 0x3f,
-       0xd6, 0x77, 0x81, 0x43, 0x47, 0xbc, 0x3a, 0xb6, 0x15, 0x5f, 0x12, 0x67,
-       0xef, 0xda, 0xb5, 0xac, 0xfb, 0x8a, 0x24, 0x97, 0xb2, 0x32, 0xad, 0xfb,
-       0xf1, 0x0c, 0x07, 0xb4, 0xee, 0x41, 0x5e, 0x8d, 0x9c, 0xc0, 0x59, 0xc6,
-       0xf6, 0x6d, 0xe0, 0xf0, 0x09, 0x72, 0x91, 0xd1, 0xe7, 0xf2, 0x2c, 0xbe,
-       0x9d, 0xe0, 0x1d, 0xb5, 0x49, 0xe4, 0x5b, 0x90, 0x91, 0x85, 0x66, 0x7d,
-       0x40, 0x3e, 0x2d, 0xf4, 0xf4, 0x31, 0xce, 0xf2, 0xd7, 0x82, 0x21, 0x1f,
-       0x17, 0x74, 0x2c, 0x74, 0xc6, 0x2f, 0xe6, 0x65, 0xd7, 0x3e, 0x1f, 0x9e,
-       0x59, 0x50, 0xfc, 0x3e, 0x7c, 0x79, 0x5d, 0x75, 0xa0, 0x6d, 0x00, 0xed,
-       0xb8, 0x0e, 0x43, 0xa6, 0x0a, 0x9f, 0x3b, 0xb3, 0x23, 0x8e, 0x33, 0xad,
-       0xf3, 0xc3, 0x62, 0xc6, 0x82, 0x6a, 0xea, 0xe4, 0x51, 0x29, 0x04, 0xdb,
-       0x31, 0x57, 0xcc, 0x58, 0x57, 0xc3, 0x58, 0x0f, 0xcb, 0x27, 0xc8, 0x13,
-       0xa1, 0x1d, 0xe1, 0xf8, 0x66, 0x66, 0x4d, 0xc5, 0xc2, 0x43, 0xca, 0x4c,
-       0xe4, 0xf1, 0x6b, 0x51, 0x3a, 0x8e, 0x18, 0x0a, 0x2b, 0xf0, 0x2e, 0xf6,
-       0x64, 0x9d, 0x76, 0x9c, 0x8c, 0xc5, 0xfa, 0x98, 0x11, 0x50, 0xf4, 0xb7,
-       0x74, 0xea, 0x78, 0xe3, 0xb5, 0x93, 0x31, 0xe3, 0xb4, 0x3a, 0xee, 0xbd,
-       0xc7, 0x81, 0x99, 0x7b, 0xe3, 0x9d, 0x5f, 0x53, 0x86, 0xbc, 0x51, 0x88,
-       0x85, 0xe7, 0x94, 0x99, 0xc5, 0x98, 0xd9, 0xb4, 0x22, 0x6e, 0xc4, 0x8c,
-       0x4e, 0x45, 0x9f, 0x68, 0xbb, 0xde, 0x77, 0x06, 0xfd, 0x63, 0xaa, 0xc5,
-       0x5b, 0x0f, 0xef, 0xeb, 0xed, 0x3e, 0x97, 0x67, 0x88, 0x39, 0x23, 0xc0,
-       0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x44, 0x64, 0x7c, 0x44, 0x63, 0xe8,
-       0xe3, 0x33, 0x7f, 0x47, 0x1d, 0xca, 0x65, 0xd6, 0x45, 0x3d, 0x7e, 0x1b,
-       0xd1, 0x3a, 0xf3, 0xe3, 0x33, 0x39, 0x9d, 0xf7, 0xd8, 0x50, 0x11, 0x6f,
-       0xdf, 0x7b, 0x77, 0x16, 0x4e, 0xda, 0x4f, 0x71, 0x9c, 0x25, 0xff, 0x64,
-       0xbb, 0x30, 0xa7, 0x74, 0xaa, 0xd4, 0xa4, 0x0d, 0xfa, 0x03, 0x98, 0x2f,
-       0xd0, 0x8c, 0x7b, 0x5f, 0x11, 0xdf, 0x78, 0xc7, 0x01, 0x3a, 0x81, 0xae,
-       0x09, 0x1d, 0xb5, 0x8a, 0x71, 0xf2, 0x2b, 0x92, 0x73, 0xfb, 0x4b, 0x07,
-       0x73, 0x58, 0xf3, 0xd5, 0x2f, 0x1b, 0x83, 0x73, 0x63, 0x0e, 0xbc, 0x3f,
-       0x3e, 0x43, 0xfa, 0xe4, 0xd9, 0x84, 0xd5, 0xd4, 0x2a, 0xd7, 0x33, 0x20,
-       0xd3, 0x2b, 0x83, 0x32, 0x87, 0xdf, 0xc2, 0x8a, 0x7b, 0x6f, 0x1b, 0xd0,
-       0xad, 0xa7, 0x0b, 0x86, 0xe6, 0xd7, 0x39, 0x9b, 0x31, 0x13, 0xf0, 0x8a,
-       0xce, 0xa9, 0x62, 0x5f, 0xc6, 0x89, 0x06, 0x29, 0x1f, 0xed, 0x06, 0xe4,
-       0xea, 0x46, 0x9d, 0x7a, 0x2a, 0xeb, 0xcd, 0x78, 0xd8, 0xdf, 0x2d, 0x0b,
-       0xc0, 0xbb, 0x0a, 0x64, 0x67, 0xfe, 0xcd, 0x80, 0xcc, 0x15, 0x74, 0x3c,
-       0x39, 0xfc, 0x17, 0x65, 0x4b, 0xad, 0x3e, 0x21, 0xb7, 0xeb, 0x51, 0xfd,
-       0x8d, 0x72, 0x2d, 0xff, 0x0b, 0x9f, 0xbc, 0x32, 0xa2, 0xf3, 0xea, 0xa2,
-       0x15, 0x79, 0xaa, 0x9f, 0x3a, 0xcf, 0xba, 0xce, 0xb1, 0x03, 0x76, 0x40,
-       0xe7, 0x78, 0x0f, 0x3a, 0xc7, 0x6f, 0xa0, 0x73, 0xfc, 0xba, 0x04, 0x7c,
-       0x29, 0x65, 0x3c, 0xfc, 0x9f, 0x01, 0x0e, 0x51, 0x56, 0x9b, 0xe7, 0x71,
-       0xa7, 0x33, 0x39, 0xd0, 0xe0, 0x47, 0x92, 0x01, 0xde, 0x26, 0x65, 0x73,
-       0x75, 0x5a, 0xb6, 0x56, 0xdd, 0x3c, 0xe5, 0xfb, 0xcc, 0x01, 0x1b, 0xe3,
-       0x3d, 0x45, 0x81, 0x43, 0x47, 0x24, 0x72, 0x9a, 0xf8, 0xd1, 0x21, 0x6b,
-       0xc5, 0xdf, 0x69, 0x1c, 0x5a, 0x2b, 0xb2, 0xec, 0x17, 0x9d, 0x4f, 0x76,
-       0x6e, 0x47, 0x2a, 0x76, 0x03, 0xf5, 0xc7, 0xb4, 0x0f, 0xc8, 0xf5, 0xc9,
-       0x13, 0x2f, 0x3f, 0xf7, 0xee, 0x5e, 0xe9, 0x3c, 0xbb, 0x59, 0xa3, 0x1b,
-       0xed, 0x9a, 0xd8, 0x35, 0xe4, 0xc6, 0xbc, 0xd5, 0xdf, 0xd0, 0x06, 0x73,
-       0x94, 0xba, 0x65, 0x03, 0x32, 0xa4, 0x11, 0xed, 0xd6, 0xba, 0x5f, 0x23,
-       0x3a, 0xa8, 0x73, 0x77, 0x39, 0x4e, 0xbe, 0x68, 0xc9, 0x7c, 0xd1, 0x0c,
-       0xe7, 0x40, 0x7f, 0xb7, 0x61, 0xab, 0x6d, 0xe2, 0x0e, 0xb6, 0x70, 0x06,
-       0xdb, 0x75, 0xca, 0xf9, 0x2f, 0x34, 0xf6, 0xae, 0xd5, 0x3f, 0xc3, 0x38,
-       0xe6, 0xf9, 0x84, 0x3c, 0xee, 0x23, 0x06, 0xd2, 0x1f, 0x95, 0xd2, 0xfd,
-       0xdd, 0x7e, 0x9b, 0x68, 0xbb, 0x55, 0x27, 0x1e, 0x8b, 0x5c, 0x2d, 0x58,
-       0x90, 0x25, 0xbf, 0x0a, 0x51, 0x07, 0x28, 0xab, 0x66, 0x3f, 0xc7, 0x5b,
-       0xb3, 0xe3, 0x1c, 0xb5, 0xb8, 0xae, 0xa8, 0x87, 0xdb, 0x94, 0xfd, 0x3b,
-       0x5a, 0xee, 0x17, 0x4a, 0x17, 0xe4, 0x1d, 0xdc, 0xb7, 0xab, 0xe3, 0x64,
-       0xe5, 0x16, 0x74, 0xbc, 0x7a, 0xa9, 0x99, 0xd7, 0x3d, 0x89, 0x73, 0x32,
-       0xd5, 0xfc, 0xf2, 0x75, 0xb9, 0x76, 0x63, 0x57, 0xbd, 0x71, 0x23, 0xa2,
-       0xae, 0x2f, 0x0f, 0xa9, 0xfc, 0xb2, 0xe3, 0xfc, 0xd3, 0x9e, 0x95, 0x3b,
-       0xab, 0x8e, 0x9c, 0xb5, 0x7d, 0xfd, 0x7e, 0x69, 0xe6, 0xd6, 0x39, 0x4e,
-       0x07, 0xb0, 0x79, 0xfb, 0xa4, 0xe3, 0x3c, 0x3d, 0x36, 0x26, 0xd1, 0x93,
-       0xd4, 0x51, 0x9e, 0x0b, 0x31, 0x3f, 0x96, 0x98, 0x93, 0xb4, 0xac, 0xcb,
-       0x15, 0xa5, 0x80, 0x6f, 0xdd, 0xae, 0xfe, 0xf2, 0xcc, 0x31, 0x2f, 0x56,
-       0x72, 0xe7, 0x35, 0xfa, 0x92, 0x43, 0xff, 0xe5, 0x4b, 0x36, 0xe4, 0x62,
-       0x71, 0x04, 0xfd, 0x83, 0xf2, 0xc3, 0x62, 0xe0, 0x50, 0xd9, 0xc0, 0x73,
-       0x54, 0xe5, 0x8b, 0x8f, 0x9c, 0x21, 0x1d, 0x33, 0x80, 0x4e, 0x62, 0x38,
-       0xce, 0x9c, 0xcd, 0xf9, 0xba, 0x31, 0xdf, 0x8e, 0x71, 0x0c, 0xf2, 0xff,
-       0xac, 0x96, 0xcf, 0x17, 0x15, 0x6c, 0x5f, 0xf0, 0x77, 0x50, 0xd2, 0x45,
-       0xc8, 0x78, 0xc5, 0x9c, 0x53, 0xea, 0x0a, 0x66, 0x68, 0x0e, 0xd8, 0x31,
-       0x0b, 0xbc, 0x79, 0x49, 0xc7, 0x56, 0x4f, 0x68, 0xec, 0x99, 0x67, 0x39,
-       0x2b, 0x89, 0x8a, 0xdd, 0xa3, 0xcf, 0x6f, 0xf7, 0xf6, 0x2f, 0x43, 0xee,
-       0x9d, 0x83, 0x8f, 0xb3, 0x4a, 0xda, 0x60, 0x03, 0xa5, 0xd6, 0xcf, 0x81,
-       0x27, 0x42, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xc8, 0xef, 0x86, 0xf6,
-       0x23, 0xba, 0xf1, 0x8a, 0x86, 0xc1, 0x76, 0x17, 0xd0, 0xaf, 0x5d, 0x92,
-       0xcb, 0x6d, 0x1a, 0x57, 0x9f, 0xac, 0x4b, 0x40, 0x0f, 0xf9, 0x3e, 0xca,
-       0x7e, 0xd4, 0x85, 0xbd, 0xb2, 0x0f, 0xe5, 0x19, 0x94, 0x5b, 0xf0, 0x64,
-       0x9b, 0x61, 0xe8, 0x15, 0x78, 0xbe, 0x8d, 0xf1, 0xc6, 0xb0, 0xe6, 0xac,
-       0x21, 0x1f, 0x9e, 0xa1, 0x2c, 0x19, 0x55, 0xcc, 0x63, 0x9e, 0xb3, 0xf0,
-       0xac, 0x0d, 0xa9, 0xd4, 0x12, 0xcb, 0x78, 0x96, 0xdd, 0xef, 0x4f, 0x60,
-       0x12, 0xfa, 0x24, 0x6f, 0xb8, 0x98, 0xf4, 0xe1, 0x1e, 0x26, 0xb1, 0xae,
-       0x5d, 0xd2, 0xcb, 0xe4, 0x75, 0x03, 0xf4, 0xd6, 0x29, 0xa9, 0x1b, 0x41,
-       0xad, 0x8f, 0x56, 0x40, 0x8b, 0x1b, 0xa0, 0xab, 0x35, 0xd0, 0x54, 0xb2,
-       0x68, 0xc6, 0x67, 0x54, 0x58, 0xfb, 0x02, 0x5e, 0x00, 0xbd, 0x76, 0xbc,
-       0x49, 0x5d, 0x94, 0xbc, 0x1c, 0x05, 0xed, 0x89, 0xd3, 0x61, 0x59, 0x99,
-       0xa8, 0xb2, 0x40, 0x83, 0xa0, 0xcb, 0xa2, 0xcb, 0xd3, 0xef, 0x2b, 0x8d,
-       0xab, 0xf1, 0x07, 0x12, 0x4b, 0x3c, 0x10, 0x13, 0x58, 0x60, 0xda, 0x1f,
-       0x88, 0x8d, 0x31, 0x27, 0xe4, 0x26, 0xe6, 0xf1, 0x81, 0xbf, 0x47, 0x4e,
-       0x69, 0xfe, 0x8e, 0x8b, 0xff, 0x30, 0x8f, 0x83, 0xde, 0x80, 0x41, 0x2e,
-       0x4f, 0x27, 0x3c, 0x1a, 0xfd, 0x26, 0xf8, 0xd7, 0x84, 0x25, 0x16, 0x94,
-       0x05, 0xf0, 0xff, 0x06, 0xbe, 0xdf, 0xad, 0x0f, 0xab, 0xf9, 0x25, 0xe5,
-       0xe5, 0x92, 0x7c, 0x07, 0x7a, 0xf2, 0x43, 0x9c, 0x5d, 0x97, 0xd6, 0xdd,
-       0x23, 0x63, 0x8c, 0x9f, 0x65, 0xd4, 0x35, 0xeb, 0xb4, 0xec, 0x8e, 0x4e,
-       0xa0, 0x7c, 0x0c, 0x4f, 0x1f, 0xce, 0x21, 0xa0, 0xe3, 0xdf, 0x6b, 0x05,
-       0x5b, 0xb9, 0xff, 0xd3, 0x30, 0x8e, 0xbe, 0xc4, 0xb2, 0x93, 0xf8, 0x4e,
-       0x5f, 0x0c, 0xf7, 0x06, 0x9d, 0x49, 0x85, 0x74, 0xbe, 0x69, 0x05, 0xba,
-       0xc4, 0x3a, 0xc6, 0xbb, 0x47, 0x5f, 0x5e, 0x0d, 0x3c, 0x3c, 0xfa, 0x2f,
-       0x27, 0x11, 0x64, 0x4e, 0xfb, 0x17, 0x21, 0x57, 0xfe, 0x7d, 0xea, 0xec,
-       0x5a, 0xf3, 0x71, 0x1f, 0x5e, 0x3e, 0x32, 0x82, 0x68, 0x0b, 0x59, 0x06,
-       0x59, 0x54, 0xd6, 0xf4, 0xcb, 0x76, 0x6e, 0xdf, 0x7c, 0x2d, 0x66, 0xdc,
-       0x17, 0xb7, 0xef, 0x82, 0x45, 0xb9, 0xd3, 0x0e, 0x7c, 0x09, 0x6b, 0xbd,
-       0xf2, 0x9e, 0x95, 0x03, 0x2a, 0x98, 0xe1, 0x0c, 0x68, 0xb4, 0x4d, 0xcc,
-       0xe8, 0x94, 0xec, 0xcf, 0x3b, 0xa7, 0xfb, 0xb2, 0x6d, 0xb3, 0x6f, 0x73,
-       0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, 0x36, 0x34, 0x8d, 0x36,
-       0x6a, 0x03, 0xfd, 0x2e, 0x8d, 0x36, 0xf7, 0x11, 0xfc, 0x3f, 0xfb, 0x20,
-       0x9d, 0xd8, 0xca, 0x8d, 0xd3, 0xe3, 0x59, 0xe3, 0x79, 0x0e, 0x83, 0x36,
-       0x0e, 0xd2, 0x4f, 0xd3, 0xb7, 0xe8, 0xd2, 0xcf, 0xd3, 0x7b, 0xf4, 0x43,
-       0xba, 0xe9, 0x94, 0xf4, 0x0d, 0x4b, 0xa6, 0x8b, 0xfa, 0xbe, 0xa1, 0x6b,
-       0xd2, 0x67, 0x34, 0x01, 0xba, 0x21, 0xad, 0x93, 0xb7, 0x0c, 0x29, 0x83,
-       0x8e, 0xca, 0xc0, 0xa7, 0x32, 0x68, 0xaa, 0x02, 0x7c, 0x2b, 0x03, 0xdf,
-       0xca, 0x75, 0x33, 0x5a, 0xc5, 0x9e, 0x29, 0xb3, 0xd7, 0x41, 0x47, 0x1b,
-       0x75, 0xde, 0xbf, 0x5e, 0xb3, 0x41, 0x39, 0x78, 0x77, 0xef, 0xee, 0xff,
-       0x81, 0xbb, 0x1f, 0x94, 0xdb, 0xb0, 0x5b, 0xde, 0x29, 0x8d, 0x02, 0x93,
-       0x04, 0x18, 0x65, 0x83, 0x36, 0xe2, 0xb2, 0x59, 0x9a, 0x94, 0x2d, 0xc8,
-       0xa7, 0xed, 0xd5, 0x08, 0xf4, 0xe9, 0x90, 0xcc, 0xbf, 0x35, 0x22, 0xb7,
-       0x56, 0x95, 0xcc, 0x82, 0x7e, 0xf3, 0x6b, 0xf4, 0xbb, 0x83, 0x9e, 0xcb,
-       0x9d, 0x3a, 0x4e, 0x9f, 0xae, 0xba, 0xfe, 0xf7, 0xa9, 0x6a, 0x97, 0x4c,
-       0x57, 0x0d, 0x79, 0xbe, 0xda, 0x23, 0x2f, 0x56, 0x83, 0x72, 0x16, 0x76,
-       0xe0, 0xd7, 0xaa, 0x03, 0xf2, 0x52, 0x75, 0x50, 0xbe, 0x5e, 0x0b, 0xcb,
-       0x37, 0x6a, 0x96, 0x64, 0x6b, 0x51, 0xc9, 0xd4, 0x46, 0xe5, 0x85, 0x1a,
-       0xfd, 0xea, 0x98, 0x0f, 0xbf, 0xd4, 0x9e, 0xbf, 0x82, 0xeb, 0xea, 0xc0,
-       0xba, 0xa2, 0x6a, 0x4a, 0xc7, 0x29, 0x25, 0xeb, 0xfa, 0x3c, 0x44, 0x2e,
-       0x61, 0xac, 0xc5, 0xb7, 0x94, 0x54, 0xf4, 0xfc, 0xcd, 0xff, 0x33, 0x09,
-       0x68, 0xdb, 0xe8, 0x52, 0x79, 0x00, 0x6d, 0x20, 0xf7, 0x0a, 0x4d, 0xdf,
-       0x47, 0xd3, 0xe7, 0xdf, 0xb4, 0xbd, 0x7c, 0xda, 0x6f, 0x7d, 0x97, 0xb6,
-       0x97, 0x3e, 0x7b, 0xe2, 0x07, 0xed, 0x9c, 0x9b, 0xda, 0x6f, 0xb2, 0x1f,
-       0xdb, 0x68, 0xce, 0xbb, 0x98, 0x7d, 0xf2, 0xff, 0x59, 0xdc, 0x18, 0xd5,
-       0xc5, 0xda, 0x00, 0xff, 0xaf, 0x05, 0x6b, 0xf9, 0xf2, 0xdc, 0xf1, 0xe9,
-       0x52, 0x5a, 0x3d, 0x5f, 0xa2, 0x46, 0xe3, 0xc8, 0xe2, 0x5e, 0x4e, 0xdc,
-       0x73, 0xb2, 0x66, 0x07, 0xf4, 0x1a, 0x5c, 0x5f, 0x7d, 0x42, 0xe7, 0xc7,
-       0xa5, 0x4f, 0x91, 0xfe, 0x18, 0x7b, 0xeb, 0xf2, 0xe2, 0x09, 0xd0, 0x6d,
-       0x6d, 0x43, 0xae, 0x56, 0x5d, 0x9f, 0xd5, 0xbc, 0xa6, 0x97, 0x7b, 0xa0,
-       0x39, 0xc6, 0x1c, 0xdc, 0x67, 0xae, 0xec, 0xf6, 0x4d, 0xe1, 0xde, 0x60,
-       0x8f, 0x63, 0xbf, 0xbe, 0x1e, 0xce, 0xc5, 0xff, 0xe3, 0x41, 0xd9, 0x5b,
-       0x2f, 0x73, 0x8d, 0x2d, 0x4d, 0x8b, 0x6e, 0x5c, 0x37, 0x2a, 0xaf, 0xe2,
-       0xfc, 0x2a, 0x06, 0xd7, 0xdf, 0x21, 0x95, 0x28, 0x6d, 0x5b, 0xe2, 0xf7,
-       0x29, 0x29, 0x63, 0x9e, 0x4a, 0xb4, 0xe9, 0x0f, 0x73, 0x71, 0xb6, 0x62,
-       0xec, 0xcf, 0x3b, 0x53, 0x3e, 0x8e, 0x77, 0xd4, 0x45, 0xa1, 0x33, 0x9d,
-       0xe3, 0xfb, 0x22, 0xca, 0xf4, 0x8d, 0xcc, 0xe3, 0x19, 0xf2, 0xea, 0xde,
-       0xeb, 0xd7, 0xba, 0xfa, 0xe4, 0x7e, 0xbf, 0xd9, 0xb2, 0x99, 0x4b, 0xfa,
-       0x63, 0xca, 0xf7, 0xf3, 0xdf, 0xf7, 0x13, 0x73, 0x8f, 0x5b, 0xfc, 0x05,
-       0xe4, 0x33, 0x43, 0xfb, 0x14, 0xbc, 0x6f, 0x47, 0xe4, 0x65, 0x83, 0x79,
-       0xec, 0x09, 0x95, 0x2e, 0x5d, 0xf7, 0x72, 0x7c, 0x63, 0xea, 0x78, 0xe5,
-       0x7e, 0xbf, 0x9b, 0xf3, 0xce, 0xb1, 0x0f, 0xe6, 0xb9, 0x1f, 0xa4, 0x13,
-       0xe6, 0xbb, 0xb7, 0xef, 0xfd, 0x0f, 0x55, 0xa5, 0x00, 0xbc, 0xb3, 0x5a,
-       0x34, 0x3f, 0xe6, 0x6b, 0xff, 0x76, 0x76, 0x34, 0x3f, 0x37, 0x7d, 0x0c,
-       0x7f, 0xee, 0xa7, 0x6d, 0x4b, 0xdc, 0xb8, 0xea, 0xe6, 0x8e, 0x6a, 0x1b,
-       0x1a, 0x58, 0x81, 0x3a, 0xf2, 0x2a, 0xf8, 0x64, 0xaf, 0x2d, 0xff, 0xfe,
-       0x03, 0x9a, 0xb8, 0x8a, 0x6c, 0x8c, 0x67, 0x00, 0x00, 0x00 };
+       0xec, 0x5b, 0x7f, 0x70, 0x1c, 0xf5, 0x75, 0xff, 0x7c, 0xf7, 0xf6, 0xa4,
+       0x95, 0x74, 0xba, 0x5b, 0x49, 0x27, 0xf9, 0x14, 0x8c, 0xb5, 0x8b, 0x56,
+       0x27, 0x61, 0x19, 0x77, 0x4f, 0x3a, 0xd9, 0x4a, 0x66, 0x1b, 0x2e, 0xb6,
+       0x63, 0xe4, 0x81, 0x82, 0xb0, 0x09, 0x31, 0x53, 0x26, 0xa8, 0xb6, 0x63,
+       0xc4, 0x8f, 0x34, 0x26, 0x61, 0x06, 0x11, 0x68, 0xd8, 0x48, 0x36, 0xa6,
+       0xf6, 0x9e, 0xd6, 0x36, 0x12, 0xe0, 0x99, 0x74, 0x22, 0x64, 0x59, 0x36,
+       0xe4, 0xa4, 0x33, 0x90, 0x1f, 0x66, 0x5a, 0x6a, 0x81, 0xf9, 0x61, 0x88,
+       0x0d, 0x84, 0x42, 0x02, 0x33, 0x99, 0x89, 0xf9, 0x11, 0xc7, 0x66, 0x68,
+       0x50, 0x5a, 0x92, 0x8a, 0x89, 0xea, 0x6f, 0xdf, 0xbb, 0x93, 0xf8, 0x61,
+       0x3a, 0x4d, 0x3b, 0xd3, 0x3f, 0xf7, 0xcd, 0xdc, 0x68, 0xf7, 0xfb, 0x7d,
+       0xef, 0x7d, 0xdf, 0xef, 0xf7, 0xbe, 0x3b, 0xa3, 0x5b, 0x23, 0x28, 0xc7,
+       0x1c, 0x54, 0xd2, 0x2f, 0xbd, 0xa5, 0xef, 0x5b, 0x1d, 0x4b, 0xed, 0xa5,
+       0xfc, 0x1e, 0x0a, 0x43, 0xe5, 0xbf, 0x02, 0x01, 0x04, 0x10, 0x40, 0x00,
+       0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04,
+       0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40,
+       0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01,
+       0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0x04, 0x10,
+       0x40, 0x00, 0x01, 0x04, 0x10, 0x40, 0x00, 0x01, 0xfc, 0x7f, 0x42, 0x08,
+       0xd0, 0xf9, 0x6f, 0xe5, 0xdc, 0x0f, 0x9a, 0xe2, 0x8c, 0x7c, 0x67, 0x85,
+       0x05, 0x2d, 0xe4, 0xc4, 0xef, 0xd8, 0x68, 0x01, 0x99, 0x5c, 0xab, 0xb1,
+       0x12, 0xff, 0x29, 0xdd, 0xb8, 0x0a, 0x5e, 0x3f, 0xdf, 0x99, 0xfd, 0xc1,
+       0x13, 0xcb, 0xcd, 0xe9, 0x91, 0x10, 0x34, 0xdd, 0x79, 0x39, 0xa5, 0x27,
+       0xa1, 0x2d, 0x24, 0x9a, 0xef, 0x37, 0x6f, 0xab, 0x46, 0x74, 0x9e, 0x17,
+       0x5c, 0xc5, 0x91, 0x72, 0xbf, 0x2d, 0xf1, 0xac, 0xed, 0x8a, 0xae, 0x34,
+       0xdc, 0x90, 0x73, 0x58, 0xdc, 0xe0, 0x9d, 0x95, 0x46, 0xb8, 0x78, 0xb2,
+       0x3a, 0xa1, 0x21, 0xbc, 0x1f, 0xba, 0xea, 0x28, 0x08, 0x5b, 0xe5, 0x28,
+       0x79, 0xb0, 0x02, 0xe1, 0x07, 0x13, 0x28, 0x9d, 0x38, 0x24, 0x7a, 0x46,
+       0x34, 0x9c, 0x0c, 0x1d, 0x16, 0x9b, 0x72, 0xe8, 0x09, 0x3b, 0x33, 0x57,
+       0x8c, 0x12, 0x5d, 0xa6, 0xf0, 0xff, 0x25, 0x53, 0x57, 0x8c, 0xe5, 0xa0,
+       0x87, 0x1c, 0x28, 0xaa, 0xf3, 0x34, 0x3d, 0x33, 0xde, 0xcc, 0x15, 0xfb,
+       0x72, 0xa7, 0xe5, 0x13, 0xcd, 0x71, 0x1c, 0xc9, 0xeb, 0x38, 0x94, 0xff,
+       0x25, 0xc9, 0x61, 0xba, 0x2e, 0x34, 0x57, 0x75, 0x5c, 0x6c, 0x4b, 0x87,
+       0x31, 0xbe, 0xeb, 0xac, 0x0c, 0x59, 0xa6, 0x01, 0xc5, 0xd2, 0x8f, 0x82,
+       0xf0, 0x7c, 0xc2, 0xf3, 0xc3, 0x18, 0x1d, 0x79, 0xb3, 0x1a, 0xe5, 0x09,
+       0x3c, 0xd1, 0xcc, 0xf4, 0x4c, 0xcb, 0x3c, 0x42, 0xb1, 0x79, 0xfa, 0x12,
+       0xa2, 0x7f, 0x26, 0x0d, 0x8c, 0xed, 0xea, 0x26, 0x52, 0x89, 0x01, 0xbb,
+       0x14, 0x1b, 0x74, 0xb8, 0x65, 0x0e, 0xf3, 0x9a, 0xe7, 0xe3, 0x0a, 0x63,
+       0x22, 0xaa, 0x17, 0xf9, 0x40, 0x68, 0x16, 0xdc, 0xd2, 0x73, 0xf6, 0x4f,
+       0xe7, 0xe6, 0xf7, 0xef, 0xa1, 0x73, 0x34, 0xda, 0xef, 0xc5, 0x4f, 0xf2,
+       0x9b, 0xf0, 0xe3, 0xfc, 0xb5, 0x78, 0x2c, 0xdf, 0x4d, 0xe7, 0xde, 0x4a,
+       0xe7, 0x6e, 0xc1, 0x3f, 0xe7, 0x6f, 0xc6, 0x4f, 0xf3, 0x3d, 0xf8, 0x51,
+       0x7e, 0x3d, 0x1e, 0xcd, 0x5f, 0x85, 0x47, 0xf2, 0x28, 0xc8, 0x70, 0x3a,
+       0xdd, 0x22, 0x7e, 0xee, 0x95, 0x41, 0xdd, 0xbd, 0x15, 0x53, 0xb9, 0x30,
+       0xc2, 0xbb, 0x25, 0x76, 0xd9, 0xe6, 0x03, 0x40, 0xb3, 0x1e, 0x86, 0xc0,
+       0x4a, 0xdb, 0x3c, 0x08, 0x7c, 0x01, 0x3d, 0x71, 0xf3, 0x10, 0x50, 0x27,
+       0x5e, 0x19, 0xaa, 0x13, 0x27, 0x86, 0x54, 0xf1, 0xa2, 0x27, 0x10, 0x73,
+       0x10, 0x79, 0x21, 0x2d, 0xe5, 0xa5, 0x6d, 0x52, 0xe6, 0x52, 0x56, 0xd7,
+       0x4b, 0xc2, 0xb4, 0x77, 0x88, 0x45, 0x30, 0x6a, 0xcd, 0xcc, 0x8d, 0x42,
+       0x73, 0xcb, 0x89, 0xff, 0x9a, 0x0e, 0xc0, 0xda, 0x6d, 0x90, 0x1f, 0x58,
+       0xc7, 0x6d, 0xf8, 0x7a, 0x21, 0x26, 0xba, 0x51, 0x63, 0xad, 0xc4, 0xb7,
+       0xbb, 0x6d, 0x8c, 0xe4, 0xa1, 0x55, 0x39, 0x1f, 0x20, 0x35, 0x28, 0x60,
+       0x93, 0xbf, 0x05, 0x3d, 0xdb, 0xb9, 0x27, 0x6b, 0x8a, 0xfe, 0x26, 0xd9,
+       0x7d, 0x92, 0xdd, 0x27, 0xd9, 0x7d, 0xd2, 0xcb, 0x27, 0xbd, 0x7c, 0xd2,
+       0xc1, 0x27, 0xdd, 0x7c, 0xd2, 0xc3, 0x27, 0x3d, 0x7c, 0xd2, 0xd1, 0x67,
+       0x5f, 0xf5, 0x91, 0x0d, 0x22, 0xf8, 0xa5, 0xb7, 0x10, 0x1f, 0x78, 0xe7,
+       0xe3, 0x83, 0xb5, 0x3a, 0x5e, 0x27, 0x19, 0x15, 0xeb, 0xff, 0xca, 0xe3,
+       0xa7, 0x11, 0xf2, 0x91, 0xf1, 0xbf, 0x3f, 0xdb, 0x24, 0x8d, 0xe6, 0x69,
+       0x97, 0xe0, 0x94, 0xf7, 0xb6, 0x2c, 0x59, 0xc0, 0xe7, 0x7e, 0x11, 0x72,
+       0x08, 0x58, 0x34, 0x2c, 0xe5, 0x87, 0xed, 0xbf, 0x96, 0x6f, 0x7c, 0x95,
+       0xf9, 0x39, 0x78, 0x6b, 0x48, 0x41, 0x88, 0xd6, 0x2e, 0xb1, 0xdf, 0x90,
+       0xd7, 0xc7, 0x19, 0xef, 0x8f, 0x11, 0x94, 0xb3, 0xad, 0xa0, 0xd5, 0x38,
+       0xea, 0x1d, 0xdf, 0x4e, 0xc2, 0x8d, 0x3a, 0xaa, 0x78, 0x35, 0x6b, 0x60,
+       0x81, 0x93, 0x41, 0xa5, 0x63, 0xed, 0xba, 0x5f, 0x69, 0xed, 0xab, 0x46,
+       0xe6, 0xc2, 0x18, 0x6c, 0xec, 0xcf, 0xab, 0xe2, 0x78, 0xb6, 0x12, 0xd5,
+       0xbb, 0xad, 0xf5, 0x59, 0xa1, 0xa0, 0xa7, 0x36, 0x83, 0xb1, 0xb4, 0x69,
+       0x8c, 0xc0, 0xc0, 0xfa, 0x36, 0x05, 0x58, 0xe0, 0xe2, 0xee, 0xb4, 0x69,
+       0xbb, 0xe8, 0xc7, 0x54, 0xdc, 0xc6, 0x78, 0x5e, 0xa3, 0xfc, 0x70, 0x71,
+       0x7d, 0x5a, 0x83, 0xdc, 0x95, 0xc1, 0xa9, 0xf6, 0x52, 0x4c, 0x75, 0x73,
+       0x9c, 0xa8, 0x74, 0xf6, 0x76, 0x28, 0xd5, 0xd5, 0xe4, 0x9b, 0xb4, 0x08,
+       0x57, 0x17, 0x52, 0x94, 0xd6, 0x21, 0xfe, 0x35, 0xcd, 0x32, 0x7c, 0x4e,
+       0x1c, 0x1f, 0x8e, 0xa2, 0x7c, 0x58, 0xc3, 0x0f, 0x77, 0xab, 0x58, 0x43,
+       0x3e, 0xbe, 0x3f, 0xa5, 0x1a, 0x37, 0x0a, 0x07, 0x63, 0x79, 0x15, 0xf1,
+       0x6c, 0x3d, 0x8c, 0x2a, 0x0d, 0x8b, 0xb2, 0x2e, 0xde, 0x26, 0xde, 0x7d,
+       0xc4, 0x3b, 0xd6, 0xae, 0xe3, 0x64, 0x6d, 0xd1, 0xbf, 0xb7, 0x78, 0x8d,
+       0xee, 0x6e, 0xa5, 0x04, 0x28, 0x81, 0xab, 0x39, 0x69, 0xdc, 0xe6, 0x35,
+       0x92, 0x1e, 0xd7, 0x60, 0x45, 0x89, 0x86, 0x0d, 0x83, 0xbc, 0xb6, 0x0a,
+       0x98, 0x58, 0x50, 0x89, 0x72, 0xb6, 0x01, 0xe7, 0xf5, 0x4a, 0x7a, 0xe6,
+       0x78, 0xb8, 0x37, 0xce, 0xf6, 0x77, 0x95, 0xff, 0x90, 0x99, 0x38, 0xe3,
+       0x15, 0x73, 0xe5, 0x68, 0x3a, 0x8d, 0xdb, 0xbd, 0xc6, 0xcc, 0x5e, 0xa5,
+       0x06, 0x08, 0x9b, 0x86, 0xa1, 0x40, 0x8b, 0x3b, 0x48, 0x0d, 0x51, 0xdc,
+       0xdc, 0x5b, 0x88, 0x1b, 0xa4, 0xda, 0x73, 0x9c, 0x9f, 0x9a, 0xab, 0x13,
+       0x7e, 0xc3, 0xb2, 0x26, 0xfc, 0xf1, 0x5e, 0xc6, 0x53, 0xf1, 0x3c, 0x3d,
+       0x9f, 0xd9, 0xf7, 0xe6, 0x5c, 0x0d, 0xf9, 0x87, 0x82, 0x7f, 0x0d, 0x65,
+       0xfe, 0x6c, 0x1b, 0xd7, 0x7b, 0x8d, 0x33, 0xdb, 0x15, 0xf2, 0xe1, 0x79,
+       0x11, 0x94, 0x51, 0x1d, 0x0a, 0x13, 0xaf, 0xfd, 0xde, 0x2c, 0xd6, 0xb6,
+       0x99, 0x87, 0xf9, 0xff, 0xce, 0x46, 0xad, 0x22, 0xff, 0x0b, 0x72, 0x36,
+       0x1e, 0xca, 0xdb, 0xd8, 0x48, 0x72, 0xdc, 0x8a, 0x37, 0x81, 0xfa, 0xc5,
+       0xc6, 0x69, 0xe5, 0x2d, 0xe9, 0x5e, 0xc5, 0xfc, 0x16, 0xe2, 0x74, 0x75,
+       0x63, 0xcf, 0x69, 0xc5, 0x1c, 0xb9, 0x47, 0x61, 0x5b, 0x29, 0xf8, 0xab,
+       0xb6, 0x34, 0x46, 0xaa, 0x74, 0x5c, 0xd3, 0xa6, 0xb9, 0x8b, 0x48, 0xa6,
+       0x97, 0x97, 0x6b, 0xa8, 0xdb, 0x93, 0xc1, 0x6b, 0x6d, 0xaf, 0x62, 0x64,
+       0x2d, 0xdb, 0x81, 0xe9, 0x58, 0xe6, 0x04, 0xaa, 0xad, 0x32, 0x54, 0x8f,
+       0x86, 0x11, 0xdb, 0x73, 0x56, 0x26, 0x2c, 0x5e, 0xb7, 0xb6, 0xcc, 0x08,
+       0x96, 0x39, 0x8c, 0xe8, 0xe8, 0xe7, 0xa1, 0x5a, 0x66, 0x0b, 0xf0, 0x8d,
+       0x38, 0xe3, 0x96, 0x58, 0xf3, 0xb2, 0x0b, 0x5c, 0xfa, 0x05, 0x81, 0x1b,
+       0x53, 0x4f, 0xca, 0x4c, 0x2d, 0xd3, 0x3c, 0x46, 0xeb, 0x2c, 0x43, 0xd9,
+       0x4c, 0x06, 0x75, 0x44, 0x33, 0x8f, 0x17, 0x41, 0xef, 0x9e, 0xa2, 0x0c,
+       0x6f, 0x2c, 0xc7, 0x63, 0x1a, 0x3a, 0xd1, 0xec, 0x7f, 0x0f, 0xaf, 0x2d,
+       0x63, 0x9a, 0xef, 0x4d, 0xef, 0x6f, 0xdb, 0x49, 0x36, 0xe1, 0x7a, 0x7a,
+       0xae, 0x5f, 0x78, 0xbf, 0xbb, 0x96, 0xec, 0xd5, 0x02, 0x91, 0xa0, 0x35,
+       0x8e, 0xe1, 0xdd, 0xd2, 0x58, 0x57, 0xf4, 0x4b, 0x29, 0xf1, 0x3b, 0x93,
+       0xee, 0x44, 0x63, 0x56, 0x85, 0xf4, 0x1a, 0xed, 0x5f, 0x87, 0x76, 0xc8,
+       0xa9, 0x6b, 0x79, 0xaf, 0x51, 0x3f, 0x1a, 0x12, 0x58, 0xa1, 0x9a, 0xd3,
+       0x3d, 0x48, 0xe0, 0x20, 0xd5, 0x9a, 0x7a, 0x47, 0xa7, 0xda, 0x13, 0xa7,
+       0x1a, 0x64, 0x88, 0xe6, 0xfb, 0x6d, 0x2c, 0xce, 0x5e, 0x8b, 0x8b, 0x87,
+       0x1d, 0x1c, 0xf6, 0x6d, 0xfc, 0xd0, 0x97, 0xf2, 0x94, 0x2d, 0xe5, 0xfb,
+       0xed, 0x66, 0xef, 0x31, 0x6a, 0x0b, 0x4b, 0x97, 0xb7, 0xf6, 0xc4, 0x42,
+       0x2a, 0xd9, 0xa7, 0xc9, 0xb8, 0x59, 0x98, 0x89, 0x49, 0x61, 0x53, 0xcc,
+       0x75, 0x91, 0xed, 0x0d, 0xec, 0xcb, 0xb7, 0xe0, 0xe1, 0xbc, 0x45, 0xbf,
+       0x25, 0x14, 0x2b, 0x69, 0xaa, 0x6b, 0xac, 0xab, 0x8e, 0xb1, 0x66, 0xca,
+       0x0d, 0x5f, 0xc1, 0x41, 0x9b, 0x72, 0xa0, 0x8a, 0x70, 0xfd, 0xb3, 0xe4,
+       0x3f, 0x0d, 0x2d, 0xbb, 0x33, 0x28, 0x4b, 0xd5, 0xc0, 0xb8, 0xd2, 0xc2,
+       0x98, 0xaf, 0xb9, 0x61, 0x8a, 0xfb, 0x51, 0xef, 0x61, 0x7c, 0x4d, 0x8f,
+       0xa3, 0x9c, 0xec, 0xb7, 0xbe, 0x2d, 0x02, 0xac, 0xe3, 0xbd, 0x08, 0xea,
+       0xad, 0xe7, 0x50, 0x5f, 0x5d, 0x89, 0x92, 0xc5, 0x4f, 0x62, 0x4a, 0x8f,
+       0xa2, 0x94, 0x7a, 0x47, 0x03, 0xe1, 0x34, 0x90, 0xaf, 0x6a, 0x2d, 0x8b,
+       0x78, 0x0a, 0x58, 0x4d, 0x84, 0x4b, 0x39, 0x95, 0x20, 0xdd, 0xc3, 0xcb,
+       0xe3, 0xc8, 0x93, 0xfc, 0x93, 0x9e, 0x94, 0x91, 0xb4, 0xd9, 0xeb, 0x53,
+       0x7e, 0x4e, 0xe4, 0x3a, 0x31, 0x99, 0xbf, 0x9c, 0xea, 0xba, 0x8d, 0x7d,
+       0x9e, 0x83, 0x51, 0x5f, 0x5d, 0xef, 0xc1, 0xec, 0xbe, 0x09, 0x69, 0x3c,
+       0x4c, 0xf1, 0x33, 0xee, 0x9b, 0xc6, 0x53, 0x21, 0x0d, 0xc7, 0xec, 0x0a,
+       0x92, 0x93, 0x72, 0x97, 0x74, 0x7a, 0xdc, 0xbb, 0x0f, 0x56, 0x0d, 0xdb,
+       0x9f, 0xfd, 0x94, 0xc6, 0x01, 0xbf, 0x10, 0xdf, 0x97, 0x6a, 0x70, 0x61,
+       0x77, 0xb0, 0x6f, 0xdc, 0xe9, 0x70, 0x5b, 0xb1, 0x9e, 0x76, 0x77, 0xd8,
+       0x28, 0x1d, 0xec, 0x24, 0xbe, 0x8d, 0xf6, 0x5b, 0xb8, 0x09, 0x53, 0x09,
+       0x17, 0x4b, 0x29, 0xfe, 0x55, 0xe7, 0x81, 0xd4, 0x56, 0xcf, 0x95, 0x31,
+       0xcb, 0xea, 0x7d, 0x49, 0xdc, 0x85, 0xe3, 0x29, 0xae, 0xef, 0x2a, 0xe5,
+       0xbe, 0x8e, 0x9d, 0xf6, 0x2e, 0x9c, 0xc8, 0x7d, 0x09, 0x3d, 0x55, 0x66,
+       0xcb, 0x80, 0xb8, 0x09, 0x87, 0x77, 0x5d, 0x0c, 0x7c, 0x95, 0xf3, 0x84,
+       0x74, 0xb3, 0x6e, 0xc2, 0x91, 0x91, 0xef, 0xe0, 0x99, 0xa1, 0x72, 0x3c,
+       0x6e, 0x55, 0xa3, 0x7e, 0xbc, 0x78, 0xce, 0x97, 0x3b, 0x34, 0x8c, 0x52,
+       0x4e, 0x5f, 0x62, 0xab, 0x38, 0x19, 0xe7, 0x1a, 0x42, 0xb1, 0xd6, 0xf6,
+       0x2d, 0xaa, 0x37, 0x85, 0x16, 0x8c, 0x4d, 0x69, 0x03, 0x9e, 0x97, 0xa1,
+       0x3a, 0x58, 0x86, 0x3d, 0x55, 0x10, 0x1b, 0xa9, 0x97, 0xfd, 0xad, 0xd7,
+       0xd8, 0x3b, 0xa8, 0x54, 0x63, 0xa4, 0x3e, 0x43, 0xbe, 0x10, 0xa8, 0xb3,
+       0x0c, 0x6c, 0xcb, 0x51, 0x25, 0xcd, 0xa9, 0xf8, 0x6e, 0xae, 0x1d, 0x23,
+       0x75, 0x4c, 0x7b, 0x11, 0xa6, 0x0a, 0x7f, 0xc3, 0x38, 0x59, 0x6d, 0x26,
+       0x40, 0x36, 0x1b, 0xf3, 0x55, 0x0c, 0xdb, 0xc3, 0x67, 0x47, 0xd6, 0x9a,
+       0x7a, 0x0f, 0xe5, 0x5b, 0xa8, 0x10, 0xb7, 0xfc, 0x0c, 0x7c, 0xd3, 0xfb,
+       0xbd, 0xfc, 0xa0, 0x70, 0xa6, 0xca, 0xf9, 0x3f, 0xf5, 0x46, 0xe8, 0x8c,
+       0x14, 0xa5, 0xcc, 0xff, 0xf6, 0x68, 0xf1, 0x7f, 0x46, 0x7f, 0xcc, 0xb8,
+       0x19, 0x80, 0xe3, 0x60, 0xc1, 0x27, 0x62, 0x7e, 0xbe, 0x8e, 0x9f, 0x1b,
+       0xd3, 0xc5, 0xfa, 0xa0, 0x2f, 0x63, 0xf9, 0xe6, 0xf3, 0xaf, 0x1a, 0x75,
+       0xe3, 0x4d, 0x28, 0xdb, 0xc3, 0xef, 0xbc, 0x2e, 0x70, 0x41, 0x07, 0xe7,
+       0x5e, 0x13, 0x94, 0xd1, 0x4d, 0xd1, 0x62, 0x7d, 0x9e, 0xaf, 0x1b, 0x7f,
+       0x37, 0x77, 0x6e, 0x61, 0x16, 0xa0, 0xf7, 0x62, 0x7d, 0xfd, 0x6e, 0x9a,
+       0x9f, 0x99, 0xa6, 0x0c, 0xaf, 0xed, 0x33, 0xed, 0x11, 0x65, 0x39, 0xc9,
+       0xc2, 0xf9, 0xca, 0x79, 0x7b, 0xc7, 0x1c, 0x0d, 0xe5, 0x82, 0x7f, 0x50,
+       0xe2, 0x1a, 0xe6, 0x37, 0x4f, 0xdf, 0x84, 0x92, 0x8f, 0xce, 0x55, 0xf1,
+       0x54, 0xfa, 0xdc, 0x73, 0xaf, 0x96, 0xe5, 0x6b, 0xab, 0x29, 0xfe, 0x6a,
+       0xa1, 0x2e, 0xa6, 0x01, 0x40, 0xaf, 0x43, 0x05, 0xe5, 0x73, 0xc8, 0xba,
+       0x52, 0x86, 0xae, 0xe6, 0xf8, 0xd5, 0xdc, 0x88, 0x73, 0x1e, 0x06, 0x77,
+       0x3f, 0x41, 0xbe, 0x8f, 0x72, 0x9c, 0x92, 0xff, 0xcf, 0x43, 0xf6, 0xc1,
+       0x86, 0x28, 0xeb, 0xbb, 0xbe, 0x0d, 0x6e, 0x03, 0xd5, 0xf2, 0xdf, 0xdc,
+       0xdf, 0x2b, 0x47, 0xba, 0x75, 0x3c, 0x9b, 0x5e, 0x49, 0xeb, 0x1c, 0x67,
+       0x36, 0x7e, 0xe4, 0x69, 0xb8, 0x6d, 0x30, 0x41, 0x72, 0x72, 0x0d, 0x2d,
+       0x9b, 0x39, 0xa9, 0xd8, 0x78, 0x8c, 0x62, 0xf4, 0x11, 0x9f, 0x6d, 0xa5,
+       0xe2, 0x82, 0xb6, 0x95, 0xb2, 0xb4, 0x8e, 0xe3, 0x7e, 0x31, 0xd1, 0xe8,
+       0xc4, 0x3b, 0x0a, 0xdd, 0xfa, 0x4b, 0x79, 0x68, 0x2d, 0x3f, 0x5f, 0x48,
+       0x6b, 0x75, 0xf4, 0xf7, 0x2f, 0x64, 0xc5, 0x67, 0xe4, 0xd0, 0xff, 0x3b,
+       0x39, 0x28, 0x1f, 0x4c, 0x7b, 0x33, 0x5a, 0x69, 0x4e, 0x52, 0x91, 0xa1,
+       0xae, 0x39, 0x4e, 0xb1, 0xb1, 0x9d, 0x7a, 0xf4, 0x6f, 0x68, 0x16, 0xdc,
+       0x56, 0x98, 0xb7, 0x0a, 0xe3, 0x5b, 0x61, 0x9e, 0xdb, 0x50, 0x9c, 0xcb,
+       0x34, 0xd5, 0xe2, 0x59, 0x6d, 0x7e, 0x8f, 0x6d, 0xdd, 0x85, 0x0d, 0x43,
+       0x52, 0x6e, 0xb5, 0xe3, 0xc4, 0xa3, 0x1a, 0x5b, 0xad, 0x2e, 0xf4, 0x0e,
+       0x81, 0xf2, 0x5a, 0xca, 0xd2, 0xd4, 0xe2, 0xc4, 0x3b, 0x54, 0xe4, 0x7b,
+       0x74, 0x57, 0x8c, 0xa7, 0x3f, 0x47, 0x76, 0xaa, 0xc0, 0xcf, 0x68, 0xde,
+       0xdb, 0xe1, 0x23, 0xb3, 0x26, 0x55, 0x49, 0xfd, 0x4a, 0x87, 0xef, 0x1b,
+       0x62, 0x72, 0x48, 0x47, 0xd6, 0x3f, 0x2b, 0x8f, 0x37, 0x09, 0xec, 0xef,
+       0x88, 0xe3, 0xf8, 0x18, 0xf3, 0xd7, 0xb1, 0x2d, 0xcf, 0xb3, 0x65, 0x88,
+       0xec, 0xe1, 0x8a, 0x6b, 0xd2, 0xbc, 0x56, 0x01, 0x6b, 0x1f, 0xd7, 0x63,
+       0xcb, 0x9e, 0x11, 0x45, 0x9c, 0xbb, 0xf3, 0xaf, 0xd3, 0x9c, 0x65, 0x50,
+       0x2d, 0x5b, 0x48, 0xf3, 0x55, 0x82, 0x66, 0xa9, 0x38, 0xcd, 0x52, 0xd6,
+       0xdc, 0x7c, 0x68, 0x52, 0x36, 0x4a, 0xf9, 0x18, 0xd5, 0xb2, 0x57, 0xe8,
+       0xf7, 0x01, 0xd5, 0xd3, 0x2a, 0xd2, 0xe5, 0x82, 0x41, 0xd6, 0xc5, 0x15,
+       0x36, 0xd5, 0xdb, 0x8c, 0x52, 0x1e, 0xe3, 0x3e, 0x14, 0x9a, 0x24, 0x5e,
+       0x34, 0x73, 0x6c, 0xf3, 0x81, 0x01, 0x1f, 0xee, 0xd3, 0x94, 0xfb, 0x35,
+       0xe3, 0x51, 0x54, 0x8f, 0xeb, 0x08, 0x8f, 0xb7, 0xd0, 0xbe, 0x86, 0x38,
+       0xbd, 0xbb, 0x34, 0x13, 0xc6, 0x9c, 0x3a, 0xb1, 0xe4, 0xbe, 0x59, 0xb9,
+       0x33, 0xa5, 0xe2, 0xc6, 0x26, 0xb3, 0xeb, 0x4a, 0x81, 0x4c, 0x4b, 0x96,
+       0xf5, 0x2d, 0xa5, 0xdc, 0x94, 0x47, 0xe2, 0x96, 0x94, 0x51, 0x47, 0xde,
+       0x75, 0xa2, 0xc3, 0xb2, 0x4f, 0x80, 0x65, 0x64, 0x1a, 0x5e, 0x77, 0xc5,
+       0xef, 0x3b, 0xac, 0x07, 0x5e, 0x45, 0x12, 0xed, 0xe3, 0xaa, 0xf8, 0xb7,
+       0xec, 0x12, 0xb4, 0x4d, 0x42, 0x2f, 0x71, 0x0e, 0x89, 0x93, 0x0f, 0x1e,
+       0x16, 0xa7, 0x26, 0x48, 0x6e, 0x9f, 0x74, 0xf1, 0x49, 0x17, 0x9f, 0x74,
+       0xf1, 0x49, 0x97, 0xc2, 0x5c, 0xc9, 0xba, 0xb6, 0xd0, 0x3c, 0xf3, 0x7a,
+       0x61, 0xf6, 0xe5, 0x59, 0xb1, 0xca, 0x31, 0x33, 0x2e, 0x58, 0x6f, 0xd6,
+       0x53, 0xca, 0x57, 0xed, 0xa2, 0x3e, 0x2e, 0x95, 0x5b, 0x6d, 0x72, 0xde,
+       0x16, 0x52, 0xfe, 0xbb, 0xcd, 0xb6, 0x60, 0x1d, 0xa5, 0x7c, 0xd4, 0x26,
+       0x9b, 0x12, 0xaf, 0x01, 0x5f, 0x1e, 0x29, 0xb1, 0x2c, 0x63, 0x1c, 0x11,
+       0xd2, 0x2f, 0x4a, 0x7a, 0x69, 0xa4, 0x6b, 0x12, 0x2a, 0xe9, 0x1a, 0x1a,
+       0x87, 0xae, 0x90, 0x3c, 0xc6, 0x28, 0xd9, 0x69, 0xf2, 0xcf, 0xc9, 0xc3,
+       0xfe, 0x71, 0xc5, 0x97, 0x69, 0x3e, 0x51, 0xc9, 0xae, 0x03, 0x14, 0x23,
+       0x3d, 0x2a, 0x8c, 0x52, 0x4b, 0xa1, 0x9e, 0xa8, 0xe1, 0xc0, 0x58, 0x05,
+       0xc6, 0x47, 0x74, 0x8c, 0x8c, 0x41, 0x0f, 0x13, 0x4f, 0x77, 0xe4, 0xb0,
+       0xf8, 0x64, 0x5c, 0x95, 0x3a, 0x5b, 0xf0, 0x0e, 0xd5, 0xa9, 0x41, 0xaf,
+       0x5a, 0x9c, 0xda, 0xa5, 0x61, 0xab, 0xcf, 0xb9, 0x29, 0x71, 0xd4, 0xee,
+       0x4f, 0x10, 0x8a, 0xe8, 0xb7, 0xd7, 0x50, 0x4c, 0x85, 0xb0, 0xd9, 0x42,
+       0x66, 0x9b, 0xdd, 0x05, 0x62, 0x65, 0xec, 0xa5, 0xfa, 0xd7, 0x67, 0xb9,
+       0x7d, 0x34, 0xc6, 0xf4, 0x26, 0x60, 0xae, 0xff, 0xad, 0x30, 0x7b, 0x0e,
+       0x90, 0xfd, 0x37, 0x67, 0x91, 0xd9, 0x99, 0xad, 0x13, 0xef, 0x0e, 0xcd,
+       0xca, 0x35, 0x29, 0x33, 0xd3, 0x4c, 0x6b, 0x95, 0x59, 0x25, 0x59, 0x82,
+       0xfe, 0x8d, 0x84, 0xdb, 0xa2, 0x62, 0x36, 0xb4, 0x3d, 0xd5, 0x5f, 0x45,
+       0x13, 0x90, 0x16, 0xa1, 0x1a, 0xec, 0x35, 0x99, 0x89, 0x1c, 0xad, 0xad,
+       0xa7, 0x7b, 0xcb, 0xf3, 0xb6, 0x79, 0xec, 0x3d, 0x4c, 0x63, 0x83, 0x37,
+       0xad, 0x36, 0xfb, 0x66, 0x5f, 0x24, 0xe4, 0x76, 0x97, 0x41, 0x59, 0x5d,
+       0x81, 0x69, 0xed, 0x4c, 0xd6, 0xb4, 0x2f, 0x13, 0x6e, 0x8b, 0x86, 0xfe,
+       0x46, 0x7a, 0x8f, 0x1c, 0xf3, 0x8a, 0x74, 0x7b, 0xed, 0xfe, 0x27, 0x2b,
+       0x90, 0xec, 0xbb, 0x84, 0x7a, 0xc9, 0x92, 0x90, 0xc4, 0xf5, 0xa9, 0x69,
+       0x7d, 0xb3, 0x37, 0x1b, 0x0a, 0xb7, 0x27, 0xf5, 0x33, 0xc2, 0x4d, 0x94,
+       0x62, 0x3a, 0x7e, 0x45, 0xd6, 0x34, 0x72, 0x48, 0x1e, 0xeb, 0xc2, 0x74,
+       0x62, 0x87, 0x67, 0x4e, 0xdd, 0x8c, 0xe4, 0xfa, 0x64, 0x68, 0x7a, 0x61,
+       0x99, 0x9f, 0xcc, 0x7c, 0x53, 0x24, 0x3b, 0xcb, 0x69, 0x36, 0x1f, 0xa9,
+       0x4d, 0x66, 0xce, 0x14, 0x72, 0x8c, 0xe7, 0x1c, 0x95, 0xe6, 0x9c, 0x2d,
+       0xb8, 0x9d, 0x6c, 0xd2, 0x49, 0x76, 0x9f, 0x58, 0x52, 0x4a, 0xf3, 0x4a,
+       0xa3, 0x1d, 0x0d, 0xb9, 0x9d, 0x61, 0x98, 0xfa, 0x7b, 0x54, 0x8b, 0x27,
+       0xad, 0x19, 0x7b, 0x75, 0x8e, 0xe7, 0x1f, 0x35, 0xb5, 0x94, 0xf2, 0xf5,
+       0x9e, 0xbc, 0xa0, 0x79, 0x91, 0x6d, 0x6a, 0xea, 0x23, 0x74, 0x77, 0x33,
+       0x6a, 0xd8, 0x86, 0x2a, 0xbe, 0x6e, 0xb9, 0x06, 0xe9, 0x6d, 0x33, 0xdd,
+       0x73, 0x30, 0x13, 0xdb, 0xa9, 0x8f, 0x6f, 0xf6, 0x90, 0xb9, 0xd4, 0x7b,
+       0x34, 0x46, 0xf5, 0xb9, 0x17, 0x50, 0x2e, 0xaf, 0x84, 0xdb, 0x57, 0x86,
+       0xfe, 0x75, 0x95, 0x30, 0xed, 0xf7, 0xc4, 0x6c, 0xe8, 0xd2, 0x54, 0xff,
+       0x85, 0x95, 0x98, 0x36, 0x5e, 0xf7, 0x4c, 0xea, 0xf3, 0x12, 0xa3, 0xa9,
+       0xd9, 0xd0, 0x01, 0x7b, 0xda, 0xf2, 0x49, 0xe7, 0xf7, 0xe0, 0x1e, 0x53,
+       0x30, 0xdd, 0xb2, 0xd9, 0x33, 0xbb, 0x96, 0x84, 0x92, 0xdd, 0x09, 0x31,
+       0xbd, 0xe4, 0xa2, 0x6c, 0x32, 0x73, 0x85, 0x48, 0xae, 0x2f, 0x11, 0xbf,
+       0x22, 0x9e, 0xc9, 0xcc, 0x37, 0x04, 0xe7, 0xcf, 0xc9, 0xb9, 0xfb, 0x15,
+       0x32, 0xa3, 0x76, 0x82, 0x62, 0x8f, 0xe3, 0x55, 0x27, 0x3f, 0xf2, 0x3d,
+       0xcb, 0x80, 0xea, 0x58, 0x89, 0x31, 0xba, 0x37, 0xf6, 0x50, 0x1e, 0x1d,
+       0xb4, 0x39, 0xe7, 0xe4, 0x91, 0x52, 0xcb, 0x6a, 0x39, 0x40, 0xb7, 0xd3,
+       0xa3, 0x94, 0xe3, 0x94, 0xf3, 0xc6, 0x24, 0xf5, 0xe2, 0xa9, 0x5a, 0x15,
+       0x55, 0xce, 0x11, 0xca, 0x75, 0x42, 0x2a, 0xb7, 0xf4, 0x3e, 0x30, 0xfe,
+       0x16, 0xa0, 0xd6, 0x00, 0xcd, 0xe6, 0x84, 0x33, 0x23, 0xa7, 0xa8, 0x7e,
+       0x0c, 0xf8, 0x8c, 0x67, 0xf5, 0x3d, 0x82, 0x3f, 0xc8, 0x93, 0x55, 0x8c,
+       0x9f, 0xc1, 0x86, 0x34, 0xc4, 0xe3, 0x76, 0x0c, 0x46, 0x8d, 0x8e, 0x7e,
+       0xea, 0xe7, 0x8a, 0x63, 0xcd, 0x8c, 0x72, 0x7f, 0xab, 0x81, 0x5b, 0x41,
+       0xf3, 0x46, 0x51, 0x86, 0xd3, 0x2c, 0x03, 0xc1, 0x22, 0x71, 0xe3, 0xf0,
+       0x42, 0x71, 0x03, 0xdf, 0x01, 0x52, 0x58, 0x55, 0x86, 0x26, 0xfb, 0x34,
+       0xad, 0x72, 0xce, 0x46, 0x9d, 0x88, 0x38, 0x31, 0x0c, 0x3d, 0x67, 0x53,
+       0xe7, 0xaf, 0x92, 0xf2, 0x60, 0xca, 0x40, 0xde, 0x2e, 0xa1, 0x99, 0x3a,
+       0x8c, 0x2a, 0x0b, 0x7a, 0xc2, 0xb1, 0xee, 0x39, 0x8c, 0xaf, 0xc0, 0xa8,
+       0x43, 0x54, 0xa5, 0x7e, 0x4c, 0x6b, 0x62, 0xdc, 0x2e, 0xa3, 0x39, 0x5f,
+       0x20, 0xe1, 0x24, 0xb0, 0xdd, 0xe7, 0x7a, 0x60, 0xf5, 0x1d, 0xa6, 0x1a,
+       0x50, 0xac, 0x79, 0x3f, 0xa0, 0xb9, 0x47, 0x34, 0x54, 0x3a, 0xbc, 0xcf,
+       0xeb, 0x97, 0xf3, 0x7c, 0x5e, 0x98, 0xc5, 0xb6, 0xd3, 0xbe, 0xe4, 0xde,
+       0x5e, 0x83, 0x18, 0xc9, 0x9b, 0x18, 0xa5, 0xfb, 0x02, 0xdb, 0x28, 0xe2,
+       0x90, 0xe6, 0x75, 0xd0, 0xcb, 0x1c, 0xcb, 0x7d, 0x08, 0x5d, 0x40, 0x35,
+       0xcf, 0x11, 0xd0, 0x4a, 0x1c, 0x1b, 0xcf, 0x7a, 0xdf, 0xa7, 0xb3, 0x90,
+       0x79, 0xd7, 0x86, 0x46, 0xfc, 0x90, 0xa0, 0xbc, 0x8c, 0xb5, 0x53, 0x2c,
+       0x50, 0xff, 0x3f, 0x60, 0x23, 0xd6, 0xe0, 0x58, 0xc7, 0x8e, 0x50, 0x2c,
+       0x18, 0x0b, 0xa0, 0x28, 0xa9, 0x57, 0xc0, 0xf3, 0xbb, 0xea, 0xf0, 0xde,
+       0x04, 0x4e, 0xea, 0x88, 0x95, 0x38, 0x56, 0xd7, 0x38, 0x05, 0x82, 0xee,
+       0x3c, 0x04, 0xbb, 0xaa, 0x90, 0x93, 0xc4, 0xa7, 0x93, 0xf8, 0x80, 0xeb,
+       0xa0, 0x16, 0xa5, 0xe7, 0x17, 0x9b, 0xa4, 0x8c, 0x35, 0x5b, 0xbd, 0x79,
+       0x98, 0x3d, 0x93, 0x42, 0xc5, 0xce, 0xdd, 0x5c, 0xf3, 0xa6, 0x4c, 0x6a,
+       0x9f, 0xd4, 0xb7, 0xa3, 0xa2, 0xe4, 0x3e, 0x05, 0xcd, 0xcb, 0x54, 0xbc,
+       0x48, 0x35, 0xef, 0xd9, 0x14, 0xdf, 0xef, 0x5b, 0x63, 0xc5, 0xb9, 0x9e,
+       0x7c, 0xff, 0x51, 0xbd, 0x98, 0xbf, 0x93, 0x19, 0x54, 0x33, 0xac, 0xae,
+       0x87, 0xb1, 0x4b, 0x1a, 0x55, 0xec, 0x43, 0x9a, 0x85, 0x68, 0xd6, 0xac,
+       0xa4, 0x5a, 0x99, 0xeb, 0xb0, 0x5a, 0x28, 0x9c, 0xdd, 0x8d, 0x1d, 0x0d,
+       0xe4, 0x6f, 0x8e, 0x03, 0x59, 0xa9, 0x14, 0xfc, 0x24, 0xe5, 0x75, 0xe9,
+       0xd6, 0x63, 0x6f, 0x87, 0x0e, 0xd2, 0x9c, 0xcb, 0x36, 0xbe, 0x9c, 0xf6,
+       0xd9, 0xfe, 0x51, 0x91, 0xba, 0xdf, 0xa5, 0xde, 0xc0, 0x67, 0x4a, 0x99,
+       0x6c, 0xa3, 0x83, 0xca, 0x43, 0x34, 0x23, 0x22, 0xf3, 0xba, 0x07, 0x11,
+       0x6b, 0xdf, 0x54, 0xb0, 0xc3, 0xe3, 0x76, 0x2d, 0xc5, 0x01, 0x62, 0x9a,
+       0x63, 0xe9, 0x74, 0x71, 0x56, 0x1a, 0x9c, 0x2a, 0x5c, 0x47, 0xd2, 0x64,
+       0x7d, 0xce, 0xb7, 0x4e, 0xec, 0xf7, 0xf8, 0xfb, 0x47, 0x27, 0x36, 0x12,
+       0x8f, 0x49, 0xcb, 0x22, 0x1d, 0xcd, 0xf5, 0x03, 0x22, 0x2a, 0x9e, 0x1f,
+       0x22, 0x3d, 0x77, 0x33, 0x6f, 0x15, 0xcd, 0x4d, 0x2a, 0x56, 0x35, 0xf1,
+       0x4c, 0x3c, 0x65, 0xaa, 0x60, 0xfd, 0xfe, 0x24, 0x9b, 0xdb, 0x98, 0xce,
+       0xa2, 0xbb, 0x87, 0xa0, 0x5a, 0x97, 0xc5, 0x66, 0x5d, 0xa0, 0xcf, 0xa6,
+       0x28, 0x5e, 0xa0, 0xc2, 0x6e, 0x53, 0xd1, 0x6b, 0xef, 0x05, 0x85, 0x06,
+       0xd5, 0x38, 0x0d, 0x9b, 0xec, 0x2c, 0xdc, 0x38, 0xfb, 0xf2, 0x1f, 0x25,
+       0xae, 0x66, 0xbb, 0xec, 0x98, 0xb3, 0xd1, 0x9e, 0xc2, 0xb7, 0x82, 0x23,
+       0x3e, 0xe3, 0x45, 0xc5, 0xa9, 0x21, 0x57, 0xb0, 0x3e, 0x1f, 0xdb, 0x93,
+       0x75, 0x62, 0x19, 0xea, 0xc4, 0xce, 0x61, 0x64, 0x76, 0x74, 0x48, 0xb9,
+       0x39, 0x65, 0x76, 0xbd, 0x00, 0x05, 0xc9, 0xe1, 0x30, 0x9e, 0x5e, 0xd2,
+       0x27, 0x5d, 0x7d, 0x85, 0x49, 0x79, 0xae, 0x53, 0x54, 0x63, 0xa0, 0xd9,
+       0x9c, 0x59, 0x49, 0x5c, 0x7f, 0xe7, 0x37, 0xe0, 0x0d, 0x9b, 0x62, 0xcc,
+       0x52, 0xfb, 0x3a, 0x43, 0xdc, 0xf7, 0x37, 0x12, 0x9f, 0x26, 0xb7, 0x52,
+       0xb1, 0x7a, 0x26, 0x28, 0xcf, 0x2a, 0x9c, 0x1e, 0xb9, 0xb3, 0x96, 0x63,
+       0x10, 0x4a, 0x34, 0xf5, 0x35, 0x39, 0x55, 0xcb, 0xb1, 0xc8, 0x73, 0x59,
+       0x54, 0xe8, 0xc3, 0x7c, 0x3e, 0xcf, 0x69, 0x2a, 0xc2, 0x49, 0x29, 0xc7,
+       0xed, 0xcd, 0x24, 0x2b, 0xcb, 0x30, 0x2f, 0xeb, 0x26, 0x99, 0xa9, 0x42,
+       0x2c, 0xea, 0x58, 0xbd, 0x93, 0x54, 0xa3, 0x23, 0x4e, 0x2b, 0xdd, 0x7b,
+       0xaf, 0x93, 0xc5, 0x39, 0x94, 0xfb, 0x7e, 0x54, 0x8c, 0x0f, 0x31, 0x0f,
+       0xf6, 0xcd, 0xb9, 0x7a, 0x40, 0xa3, 0xfb, 0x33, 0x26, 0xb2, 0x02, 0xfb,
+       0x52, 0x7d, 0xb2, 0x47, 0x67, 0x7e, 0x51, 0xf1, 0xec, 0xd0, 0xc7, 0x67,
+       0x7e, 0x1a, 0x7f, 0xef, 0x9c, 0x9d, 0xbe, 0x54, 0x8c, 0x09, 0xbf, 0x18,
+       0xa3, 0x25, 0xce, 0xcb, 0x14, 0xfb, 0xca, 0x6a, 0xba, 0x9d, 0x41, 0x4f,
+       0x09, 0x3c, 0xd5, 0x29, 0x70, 0xdd, 0x12, 0x9a, 0xc1, 0x96, 0x5a, 0x14,
+       0x27, 0xd7, 0x48, 0x63, 0xc1, 0x14, 0x05, 0xdc, 0xac, 0x2c, 0x4d, 0xaa,
+       0x78, 0x67, 0x09, 0x25, 0xd1, 0x55, 0x1c, 0xab, 0x0a, 0x5e, 0x20, 0xbc,
+       0xd5, 0x17, 0x59, 0x5d, 0x47, 0x51, 0x01, 0xe3, 0x2b, 0xbc, 0xb6, 0x62,
+       0x43, 0x18, 0xad, 0x09, 0x1d, 0x16, 0xf9, 0xbc, 0x86, 0x67, 0x69, 0x92,
+       0x9f, 0x69, 0xe7, 0x63, 0xdb, 0x2b, 0xc8, 0xd1, 0xbc, 0x8c, 0x9f, 0x59,
+       0xbe, 0x8f, 0xdf, 0x07, 0x86, 0x58, 0x3e, 0xf6, 0x17, 0xf9, 0x9a, 0x64,
+       0x2e, 0x49, 0xcd, 0xc7, 0xc5, 0x6d, 0x73, 0xb2, 0x46, 0x69, 0xae, 0x61,
+       0x9a, 0x62, 0x0c, 0x9d, 0xa0, 0xf8, 0x19, 0xff, 0x08, 0x87, 0x2c, 0x58,
+       0xce, 0xe7, 0x70, 0xac, 0x08, 0x60, 0xad, 0x82, 0xd4, 0x32, 0x9e, 0x11,
+       0x28, 0x06, 0x86, 0xcd, 0x4e, 0x43, 0x59, 0x44, 0xfb, 0x4c, 0x1b, 0x25,
+       0xbf, 0xf3, 0x7b, 0xf1, 0x9c, 0x5b, 0x9a, 0x38, 0xce, 0x5b, 0xe7, 0xfc,
+       0xf1, 0x0b, 0xbd, 0x38, 0xc3, 0x46, 0xa9, 0xe7, 0x81, 0xf6, 0x19, 0x4f,
+       0xc5, 0x1a, 0xc6, 0x49, 0xcd, 0xe3, 0xcc, 0xc7, 0xe8, 0xbf, 0x10, 0xee,
+       0x9f, 0x64, 0xaa, 0x8d, 0xfb, 0x75, 0x54, 0x5c, 0x37, 0xc4, 0xb8, 0x45,
+       0x7b, 0x7f, 0xd8, 0x4c, 0xf8, 0xed, 0xe7, 0xe2, 0xbf, 0xfc, 0x09, 0xfc,
+       0xcf, 0xf4, 0x77, 0x82, 0x2e, 0xb1, 0xc3, 0xa3, 0x0b, 0xbf, 0xa5, 0x5c,
+       0x56, 0x4e, 0x79, 0xfd, 0x10, 0xf5, 0xf9, 0x83, 0x23, 0x5d, 0x62, 0x3b,
+       0x99, 0xe7, 0xc0, 0xd8, 0x2a, 0x71, 0xb7, 0x67, 0xf1, 0x2c, 0x39, 0xd7,
+       0xf3, 0x8b, 0xdf, 0xf7, 0xb6, 0x7d, 0xea, 0xbb, 0x5d, 0xa4, 0x47, 0x77,
+       0xd0, 0x5d, 0x3f, 0x78, 0x97, 0x6c, 0xb0, 0xb8, 0x9e, 0x59, 0x53, 0x17,
+       0x87, 0x22, 0x9d, 0xb1, 0xe5, 0x21, 0x44, 0x2d, 0x74, 0xc7, 0x68, 0xd6,
+       0x7a, 0xb1, 0xd0, 0xe3, 0x0c, 0x18, 0xb9, 0x81, 0xda, 0x62, 0x0c, 0x48,
+       0x49, 0x75, 0x5f, 0xad, 0x74, 0xd0, 0x53, 0xe2, 0x94, 0x68, 0x97, 0x74,
+       0x44, 0x90, 0xeb, 0xe8, 0xaa, 0x3f, 0x9e, 0xbb, 0xac, 0xfe, 0xb9, 0x5c,
+       0x5d, 0x0f, 0xdd, 0x7d, 0xeb, 0x7f, 0xe6, 0x01, 0x67, 0x48, 0x86, 0xb0,
+       0x73, 0xa5, 0xbb, 0x2f, 0x0d, 0xa5, 0xb7, 0xc3, 0x32, 0x16, 0x8b, 0x75,
+       0xeb, 0x48, 0x87, 0xfa, 0x63, 0xb9, 0x3b, 0xd7, 0x85, 0x26, 0xa9, 0xdb,
+       0xe9, 0xb8, 0xf3, 0xed, 0xf4, 0x9d, 0xd8, 0xe2, 0xf5, 0x61, 0x93, 0x17,
+       0x2f, 0xd4, 0xa8, 0x5d, 0x2c, 0x93, 0xcf, 0xdf, 0xec, 0x58, 0xd6, 0x08,
+       0xb6, 0xe6, 0x55, 0xbc, 0x55, 0xd8, 0x33, 0x13, 0xab, 0xf1, 0x31, 0xee,
+       0x67, 0xf1, 0x3e, 0xf9, 0x2d, 0x91, 0x63, 0x06, 0x99, 0xd0, 0xa0, 0x94,
+       0x4a, 0x9a, 0xef, 0x7f, 0xd3, 0x34, 0x0b, 0x73, 0x8d, 0x79, 0x0f, 0xfb,
+       0xad, 0x05, 0xfc, 0x2d, 0x91, 0x21, 0x53, 0x3a, 0xc8, 0x7b, 0xa7, 0xe7,
+       0xf6, 0xde, 0xa1, 0x3d, 0x88, 0x53, 0xd4, 0xab, 0xa8, 0x8e, 0x17, 0xf6,
+       0xcb, 0x07, 0x23, 0xf8, 0x7b, 0x9f, 0x71, 0x4e, 0xce, 0xe1, 0xfc, 0x8a,
+       0x70, 0xe2, 0x58, 0x53, 0x05, 0xb7, 0x92, 0x73, 0x6b, 0x78, 0xfe, 0x5b,
+       0x23, 0xe5, 0x89, 0xfd, 0x61, 0xb4, 0xf8, 0xad, 0x31, 0x2a, 0xb4, 0xfb,
+       0xe8, 0x39, 0xca, 0x71, 0xc8, 0xb1, 0xca, 0xf4, 0xc7, 0x53, 0x45, 0xfa,
+       0x63, 0x29, 0xa6, 0xff, 0x2c, 0x8d, 0x9a, 0x89, 0x0c, 0xc6, 0xa9, 0xfe,
+       0xbe, 0x4b, 0xb5, 0xa0, 0xc8, 0xbb, 0x48, 0xf7, 0x4f, 0x73, 0x74, 0x87,
+       0x89, 0xee, 0x0f, 0x14, 0x87, 0x4c, 0xcb, 0x7a, 0x72, 0x6e, 0xcc, 0xfb,
+       0xaf, 0x45, 0x1c, 0xf2, 0x0c, 0x1c, 0xca, 0xa9, 0x62, 0x1f, 0xd5, 0xda,
+       0x31, 0xba, 0xb7, 0x0c, 0x14, 0xbe, 0xa5, 0xea, 0x64, 0x93, 0x17, 0xaa,
+       0x8a, 0xfe, 0xe2, 0xef, 0xcb, 0x53, 0x58, 0xe1, 0x25, 0xa9, 0xf7, 0x6b,
+       0x05, 0x9d, 0x4a, 0x9d, 0xa7, 0xf1, 0x5b, 0xaa, 0x97, 0xa7, 0x0a, 0xdf,
+       0x6f, 0x9e, 0x46, 0x32, 0xc7, 0x73, 0x8f, 0x25, 0x36, 0x79, 0x46, 0x8f,
+       0x42, 0xbc, 0x57, 0xe5, 0x8a, 0x35, 0x84, 0xfa, 0x5b, 0x86, 0x6a, 0xb3,
+       0x78, 0xa6, 0xf0, 0x5e, 0x43, 0x3d, 0x8f, 0x65, 0xc8, 0x88, 0x44, 0xd2,
+       0x45, 0x43, 0xd2, 0x95, 0xaa, 0x65, 0x1d, 0x53, 0x43, 0x96, 0xfe, 0x4e,
+       0x28, 0x73, 0x8b, 0x82, 0xbb, 0xf0, 0x7e, 0x7b, 0xe6, 0x6f, 0xea, 0xe9,
+       0x6f, 0x65, 0x3b, 0x8c, 0x0a, 0xca, 0xf3, 0x1b, 0x3a, 0x9a, 0x32, 0x2f,
+       0x89, 0xa6, 0xee, 0xac, 0x68, 0x72, 0xd7, 0x88, 0xa6, 0xce, 0x32, 0x61,
+       0x6b, 0xcf, 0x51, 0x13, 0x7f, 0x39, 0x37, 0x6f, 0x07, 0xf6, 0x1f, 0xdb,
+       0x80, 0xc2, 0xdc, 0xb1, 0x32, 0x8b, 0x45, 0x8c, 0xee, 0xfe, 0x9c, 0x0f,
+       0x0d, 0xa0, 0x5e, 0x74, 0x36, 0xd7, 0xd1, 0xba, 0x7e, 0x97, 0x28, 0xa3,
+       0x7a, 0xa0, 0x63, 0x2f, 0xcd, 0x27, 0x0d, 0x16, 0xc7, 0x27, 0x35, 0xc8,
+       0x05, 0x2c, 0xcf, 0xcf, 0x23, 0x45, 0xfd, 0xd6, 0x55, 0x17, 0xf3, 0x4f,
+       0x50, 0x9d, 0x83, 0x16, 0xa3, 0x58, 0x7d, 0x9f, 0xea, 0xda, 0xef, 0x9a,
+       0x8a, 0x71, 0xbb, 0x94, 0xbf, 0x03, 0x17, 0xf0, 0x8e, 0x4b, 0xba, 0x5b,
+       0x91, 0x4e, 0xe7, 0x31, 0x3e, 0xe9, 0x3b, 0x55, 0xfd, 0x69, 0xfa, 0xa2,
+       0x6d, 0x15, 0x9a, 0x01, 0x8e, 0xe4, 0x33, 0x62, 0xb5, 0x87, 0x2d, 0xa1,
+       0x82, 0xfe, 0x06, 0x56, 0xe7, 0xba, 0xc4, 0x2a, 0xcf, 0x32, 0x06, 0xc8,
+       0x06, 0xdb, 0xf4, 0x56, 0x7d, 0x8c, 0xea, 0x16, 0xf1, 0x32, 0x4a, 0x29,
+       0x07, 0x34, 0x67, 0x01, 0xee, 0x99, 0x8b, 0x29, 0xca, 0x0b, 0xb7, 0xcc,
+       0xe9, 0x13, 0x8b, 0x27, 0xf8, 0x95, 0xf8, 0x7c, 0xa4, 0xdf, 0x87, 0x72,
+       0xfb, 0x55, 0xbc, 0xdf, 0x3f, 0xe7, 0x93, 0x9b, 0xf9, 0x4c, 0x7a, 0x3f,
+       0x35, 0x27, 0xc3, 0xff, 0x44, 0x3b, 0x71, 0xfe, 0xa7, 0x69, 0x78, 0xae,
+       0xe3, 0x3b, 0x05, 0xdc, 0x6a, 0x87, 0x67, 0xba, 0x85, 0x73, 0xb1, 0x30,
+       0x4c, 0xbc, 0xb7, 0xe0, 0xca, 0x65, 0x40, 0xf3, 0xe0, 0x42, 0x6c, 0xcf,
+       0x03, 0x2d, 0x83, 0x3c, 0x63, 0xcf, 0xc2, 0xcb, 0x42, 0x2b, 0x73, 0x66,
+       0x70, 0x61, 0xb6, 0xb1, 0xb7, 0x54, 0x98, 0x2d, 0x59, 0x61, 0x76, 0x03,
+       0xad, 0x34, 0x7d, 0x98, 0x89, 0xc5, 0xc2, 0x34, 0x36, 0x83, 0x6d, 0x35,
+       0x8b, 0xa6, 0x42, 0xae, 0xcf, 0xc0, 0x22, 0x7f, 0x77, 0x0f, 0x86, 0xa0,
+       0xb4, 0xfd, 0x8e, 0x6c, 0x66, 0x76, 0x42, 0x2c, 0xa4, 0xf9, 0x96, 0x63,
+       0x72, 0x16, 0x5b, 0xa9, 0x4f, 0xd7, 0x13, 0xce, 0xe7, 0xa9, 0x07, 0x34,
+       0x0e, 0x9a, 0x33, 0x80, 0xd9, 0x77, 0x71, 0xa8, 0xb1, 0xa5, 0x17, 0xe6,
+       0x96, 0x6d, 0x68, 0x9d, 0x7a, 0x46, 0x98, 0x99, 0x19, 0x21, 0x50, 0xda,
+       0x56, 0xe4, 0xb9, 0x74, 0x8e, 0x67, 0x0b, 0xdf, 0x37, 0x0a, 0xb9, 0x45,
+       0x77, 0x92, 0xb6, 0x5f, 0xc8, 0xa9, 0x82, 0xcd, 0xfe, 0x7a, 0x4e, 0xff,
+       0xec, 0x9c, 0x0f, 0xd4, 0xb9, 0xf7, 0x9f, 0x54, 0x73, 0x7d, 0x2f, 0x69,
+       0x2b, 0xcc, 0xe3, 0x14, 0x97, 0x5f, 0x44, 0x3f, 0xcd, 0x7e, 0x99, 0x02,
+       0x7d, 0x17, 0x7a, 0x72, 0x10, 0x9b, 0xbd, 0xa9, 0xd2, 0x67, 0x68, 0xaa,
+       0x1e, 0x29, 0xf0, 0xb9, 0x8c, 0xd6, 0xba, 0xe9, 0xc7, 0x36, 0xfb, 0xaf,
+       0x4a, 0xbe, 0x3d, 0x38, 0xaa, 0xfb, 0x4a, 0xf3, 0xbb, 0xfd, 0x90, 0x5a,
+       0xef, 0xab, 0x27, 0x2d, 0x03, 0x56, 0x37, 0x7d, 0x5b, 0x6a, 0x5b, 0xb2,
+       0xb9, 0x0d, 0xcd, 0x22, 0x7b, 0xb5, 0x4b, 0x1b, 0x84, 0x2c, 0x82, 0xb1,
+       0x65, 0x1b, 0xc7, 0xb8, 0xd6, 0xb5, 0x56, 0xb0, 0x31, 0x18, 0x3b, 0x89,
+       0xec, 0xe1, 0x0f, 0x25, 0x9e, 0x1d, 0xf5, 0x48, 0x20, 0x04, 0xf4, 0x4b,
+       0x12, 0x2c, 0xb0, 0x55, 0x53, 0x6e, 0xf4, 0x00, 0xe2, 0xb4, 0x24, 0xbc,
+       0x99, 0xd4, 0x2a, 0xa9, 0x9a, 0xb1, 0x62, 0xc4, 0x2b, 0x36, 0xc6, 0x9e,
+       0xc9, 0x6c, 0x91, 0x2d, 0xbb, 0xcc, 0x40, 0x00, 0x27, 0x7e, 0xe1, 0xcc,
+       0x4c, 0x2c, 0xc6, 0x89, 0xef, 0x7e, 0xe7, 0xde, 0x6e, 0x10, 0x84, 0xc4,
+       0x35, 0x54, 0xa9, 0xda, 0xdd, 0xf7, 0xf7, 0x3c, 0xbf, 0x73, 0xbe, 0xf3,
+       0x9d, 0x73, 0x7e, 0xd7, 0x92, 0xcb, 0x58, 0xcb, 0xff, 0x0e, 0x9b, 0xed,
+       0x36, 0x45, 0xd1, 0x98, 0x1b, 0xbc, 0x6a, 0x9c, 0x53, 0x2d, 0x1d, 0xb1,
+       0x99, 0x1c, 0xbd, 0x59, 0x9e, 0x25, 0x25, 0x77, 0xb3, 0x3e, 0xe4, 0xf7,
+       0x74, 0x9b, 0xbc, 0xdf, 0x83, 0x67, 0xd2, 0x1e, 0x6c, 0x20, 0xb6, 0xa6,
+       0x4c, 0x6c, 0xbd, 0x1e, 0x1f, 0xd9, 0xd8, 0x6e, 0x05, 0xdb, 0xf5, 0x64,
+       0xb8, 0x53, 0x73, 0xfa, 0xac, 0xa9, 0x2b, 0x8e, 0x26, 0x39, 0x07, 0x91,
+       0xbd, 0xc4, 0x76, 0xd9, 0xd8, 0x57, 0xce, 0x24, 0xac, 0x0c, 0x46, 0x5b,
+       0x95, 0xfe, 0x68, 0x31, 0xe7, 0x8b, 0x28, 0xc9, 0x90, 0x6d, 0x77, 0x29,
+       0xe3, 0xa9, 0x15, 0x8b, 0x56, 0x12, 0x7f, 0xb4, 0x80, 0x66, 0x2b, 0xc1,
+       0xb3, 0x81, 0x39, 0x98, 0x52, 0x97, 0x62, 0x73, 0x20, 0x87, 0x5c, 0x69,
+       0x3f, 0x36, 0xaa, 0xb9, 0xd8, 0x14, 0xf8, 0x0b, 0xe0, 0xe1, 0x3c, 0xea,
+       0xb1, 0xc5, 0x39, 0x73, 0x38, 0x6f, 0x1e, 0x31, 0xe3, 0x39, 0x73, 0xdf,
+       0xe3, 0xb2, 0x57, 0xae, 0xb3, 0x59, 0x49, 0x12, 0xf3, 0x2b, 0x4c, 0xdb,
+       0x9d, 0xf9, 0x7e, 0x28, 0x65, 0xe6, 0x60, 0x5f, 0x5e, 0x6c, 0xca, 0xf9,
+       0xf7, 0xdf, 0xd7, 0xd3, 0xab, 0xcb, 0xc9, 0xd3, 0xa9, 0x3f, 0xcb, 0x11,
+       0xae, 0x5c, 0x82, 0xe7, 0x03, 0x8d, 0x28, 0xd2, 0x9a, 0xf1, 0x6d, 0x35,
+       0x42, 0x4c, 0x1f, 0xc2, 0x77, 0xcc, 0x31, 0x64, 0x3c, 0xb3, 0x66, 0xc4,
+       0x7f, 0xbf, 0xb3, 0x43, 0xfb, 0xba, 0xf8, 0xd2, 0xca, 0xc9, 0xb4, 0xdb,
+       0x9c, 0xe8, 0x19, 0x90, 0x4f, 0x07, 0xbe, 0x13, 0xb2, 0x72, 0xb0, 0xf1,
+       0x21, 0x27, 0x62, 0x03, 0x0e, 0xa4, 0x83, 0x64, 0x3f, 0x95, 0x37, 0x8f,
+       0x3d, 0xc4, 0xb1, 0xad, 0xbc, 0xc5, 0x77, 0x29, 0xd7, 0x73, 0x4e, 0x27,
+       0xb9, 0x10, 0xd4, 0x0a, 0xb6, 0x29, 0x1f, 0x2f, 0x80, 0x7b, 0x48, 0xea,
+       0x4e, 0x93, 0xca, 0x96, 0xb4, 0xd5, 0xe6, 0x7b, 0x52, 0xab, 0xca, 0xb5,
+       0x81, 0xbe, 0x88, 0xdb, 0x75, 0xb0, 0x8d, 0x8b, 0x71, 0x71, 0x3e, 0x6a,
+       0x86, 0x0a, 0xf8, 0xa7, 0xa2, 0xf4, 0x20, 0x1f, 0x8c, 0x37, 0x2b, 0x2f,
+       0x46, 0x03, 0x28, 0x65, 0xbc, 0x5e, 0xd6, 0x64, 0xf5, 0x7f, 0x29, 0xfd,
+       0x75, 0xeb, 0x77, 0xa2, 0xbd, 0x54, 0xce, 0xab, 0x06, 0x85, 0xda, 0x94,
+       0xf1, 0x82, 0x85, 0xf1, 0xa6, 0x2f, 0xed, 0xbe, 0x56, 0xe7, 0x92, 0x35,
+       0x29, 0xc2, 0x5b, 0xd5, 0xf2, 0x26, 0x89, 0x9b, 0xf9, 0xa3, 0x19, 0x77,
+       0xcb, 0x1a, 0x64, 0xec, 0x7c, 0xe4, 0x0e, 0xc9, 0xd8, 0x05, 0xc8, 0xb9,
+       0xb6, 0x16, 0x99, 0x87, 0x61, 0xde, 0xb8, 0xf8, 0x57, 0x99, 0x6f, 0x52,
+       0x19, 0x4c, 0xcb, 0x1a, 0xb2, 0xf3, 0x9e, 0x32, 0x9e, 0x51, 0x0b, 0xe8,
+       0xcf, 0x87, 0x8d, 0x0d, 0x15, 0x86, 0xe1, 0x5f, 0x74, 0xdc, 0x48, 0xad,
+       0x35, 0xb1, 0xd6, 0xd8, 0x9d, 0x70, 0x62, 0x17, 0xe5, 0xb6, 0x39, 0x78,
+       0x58, 0x78, 0x5c, 0xe6, 0x5f, 0x56, 0x6e, 0x47, 0x28, 0xb7, 0xb9, 0x99,
+       0x73, 0x9c, 0x54, 0x8e, 0x5e, 0xf3, 0xf7, 0xb2, 0x46, 0x59, 0x97, 0x82,
+       0x72, 0x4d, 0xd6, 0x65, 0x43, 0x99, 0x96, 0x8f, 0x72, 0xca, 0xa7, 0xcc,
+       0x5c, 0x53, 0xb3, 0xf2, 0x6e, 0x14, 0x6a, 0x09, 0xb9, 0x43, 0xe9, 0xb8,
+       0xb5, 0xae, 0x29, 0xca, 0xe7, 0xcc, 0x35, 0x9d, 0x98, 0x2d, 0x67, 0xa1,
+       0x57, 0x62, 0xd3, 0x33, 0xdf, 0xdf, 0x9a, 0x94, 0x71, 0xed, 0x74, 0x9c,
+       0x0a, 0xb6, 0x87, 0xc4, 0x5f, 0xe0, 0xe5, 0xe5, 0x51, 0x4b, 0x06, 0x36,
+       0xf3, 0x0c, 0xc4, 0x06, 0x64, 0xff, 0xd9, 0xbd, 0x37, 0x2b, 0x4f, 0x45,
+       0xa5, 0xbf, 0x86, 0x1a, 0xb3, 0x9f, 0x15, 0x37, 0xdb, 0xa8, 0x7f, 0xcb,
+       0x79, 0x36, 0xb6, 0x71, 0x4b, 0x37, 0x3d, 0xa9, 0x56, 0xce, 0x2b, 0xe7,
+       0x34, 0xa9, 0x74, 0x72, 0x4e, 0x98, 0x67, 0xfb, 0x5f, 0xcb, 0x2d, 0x5b,
+       0x9f, 0xa4, 0x6d, 0xf2, 0x37, 0xa7, 0x8d, 0xfa, 0x5e, 0x00, 0xc7, 0x90,
+       0xcb, 0xcc, 0xf1, 0xc8, 0xd8, 0xcf, 0x45, 0xcb, 0x90, 0x77, 0x30, 0xdb,
+       0xd7, 0xf2, 0xed, 0x56, 0x8d, 0x30, 0x6b, 0x8f, 0x82, 0x8f, 0xe2, 0x27,
+       0x22, 0x4a, 0xf8, 0x5a, 0x9d, 0x4f, 0x72, 0x5f, 0x52, 0xff, 0xcc, 0xe5,
+       0x7a, 0x24, 0x7f, 0xaa, 0x10, 0x33, 0x6c, 0xc4, 0xe9, 0xe5, 0x1e, 0x07,
+       0x71, 0x6e, 0x03, 0xbe, 0x34, 0x22, 0x15, 0xe1, 0x80, 0x13, 0x56, 0x8c,
+       0xde, 0x8e, 0x5c, 0x58, 0x18, 0x44, 0x2d, 0x8d, 0xd2, 0x1f, 0x73, 0xaf,
+       0xe4, 0x00, 0xe8, 0x4e, 0x7f, 0x69, 0x4c, 0x55, 0x38, 0xe8, 0xf3, 0xaf,
+       0xe5, 0xd6, 0x68, 0x77, 0x86, 0x31, 0xcc, 0x67, 0xbd, 0xe9, 0xec, 0x39,
+       0x91, 0x5b, 0x90, 0x6b, 0x3e, 0xad, 0xfd, 0xbb, 0xb1, 0xfe, 0x86, 0xb6,
+       0x59, 0x6c, 0xb6, 0x62, 0xed, 0x23, 0x26, 0x36, 0x17, 0xa2, 0x77, 0xb7,
+       0x37, 0x99, 0x02, 0x79, 0x8b, 0x66, 0x9b, 0x2b, 0x31, 0x82, 0x1d, 0xde,
+       0xbe, 0x66, 0xc6, 0xfa, 0xc4, 0x4e, 0x4f, 0x0a, 0xff, 0x5c, 0x2e, 0x76,
+       0xc4, 0x78, 0xcd, 0x53, 0x6a, 0x2b, 0x93, 0xb5, 0x9b, 0xab, 0xb2, 0x0f,
+       0xe4, 0x61, 0x43, 0x43, 0x1e, 0x52, 0x6d, 0xc4, 0xac, 0x81, 0x48, 0x2b,
+       0x87, 0x77, 0xe5, 0x37, 0xbd, 0xf5, 0xbd, 0x6f, 0xf8, 0xbd, 0xf4, 0x93,
+       0x40, 0x6e, 0x8c, 0x73, 0x22, 0x83, 0x69, 0x03, 0xde, 0x88, 0xcd, 0x26,
+       0xfd, 0x7f, 0x6b, 0x90, 0x63, 0xb3, 0xaf, 0x8c, 0xc1, 0xb9, 0xff, 0xc8,
+       0x16, 0x24, 0xee, 0xfb, 0xb2, 0x5c, 0xf2, 0x8e, 0x6a, 0xad, 0x82, 0xc2,
+       0x81, 0x42, 0x14, 0x30, 0x4e, 0xdf, 0x55, 0xe9, 0xeb, 0xd0, 0x6d, 0xf9,
+       0x38, 0x7d, 0xd7, 0x7f, 0x41, 0xaa, 0x32, 0x07, 0xae, 0x5a, 0x60, 0x45,
+       0xdc, 0x06, 0x5b, 0x2d, 0xb1, 0x37, 0x04, 0x34, 0x8f, 0xf3, 0xdc, 0x06,
+       0x14, 0x3c, 0x91, 0xb4, 0xe1, 0xc1, 0xa4, 0x1d, 0xab, 0x93, 0xf8, 0xab,
+       0x1a, 0x60, 0xba, 0x1a, 0xfe, 0xf6, 0x19, 0x05, 0x9b, 0x8b, 0x61, 0xfa,
+       0xf8, 0xd6, 0xd5, 0x8c, 0x4b, 0x57, 0x8d, 0x13, 0xcf, 0xd8, 0xd6, 0xc9,
+       0x98, 0xcd, 0xd1, 0x6f, 0x47, 0x75, 0x3f, 0x6e, 0xcf, 0x05, 0x42, 0x4e,
+       0xf8, 0x67, 0xe8, 0x67, 0xca, 0x1c, 0xf0, 0x4f, 0x9d, 0xb7, 0xfb, 0x3b,
+       0xab, 0xed, 0x3c, 0xdc, 0x5a, 0x59, 0x8b, 0x0b, 0x0f, 0x51, 0x9f, 0x6b,
+       0x06, 0xd8, 0xbe, 0xd6, 0x06, 0x55, 0x53, 0x70, 0xe5, 0x71, 0xc9, 0xfb,
+       0xca, 0x33, 0xc9, 0x55, 0x28, 0x28, 0x1e, 0xb0, 0x13, 0xc3, 0xde, 0x34,
+       0x4e, 0x57, 0x0a, 0x7e, 0x03, 0x4f, 0x70, 0x6d, 0x6e, 0xfe, 0xa6, 0xd6,
+       0xba, 0xb0, 0x70, 0xa9, 0x8a, 0x75, 0x43, 0x5f, 0x9a, 0x3a, 0x25, 0xe3,
+       0x38, 0x69, 0x53, 0x39, 0xb4, 0xf1, 0x83, 0x66, 0x0d, 0xd1, 0xc6, 0x3d,
+       0xda, 0x51, 0x30, 0x00, 0xac, 0x8a, 0xe3, 0x91, 0x42, 0xf8, 0xc3, 0xb2,
+       0xc6, 0xba, 0x25, 0x0e, 0xf6, 0x2d, 0x44, 0xeb, 0xb8, 0xd5, 0xef, 0xfe,
+       0xf1, 0x92, 0x0a, 0x2b, 0x07, 0xfe, 0xa7, 0x6b, 0xda, 0x3d, 0x21, 0x3f,
+       0x36, 0x24, 0xa9, 0x73, 0x36, 0x0f, 0x86, 0x32, 0xb9, 0xe8, 0xf5, 0x29,
+       0xef, 0xac, 0x9a, 0xf3, 0xdf, 0x14, 0x66, 0xea, 0xd1, 0xb4, 0x85, 0x19,
+       0x8e, 0x13, 0x51, 0xd6, 0x53, 0x76, 0x43, 0x13, 0x06, 0xa2, 0xba, 0x81,
+       0x31, 0xfe, 0xbd, 0xad, 0x4b, 0xde, 0x63, 0x52, 0x79, 0x26, 0xf6, 0x95,
+       0x11, 0xc9, 0xd8, 0xf3, 0x0f, 0x12, 0x01, 0x65, 0x53, 0x0c, 0x78, 0x95,
+       0xfe, 0xf4, 0x10, 0xff, 0x46, 0x12, 0x92, 0x47, 0xa2, 0xec, 0x69, 0xd7,
+       0xdb, 0x52, 0xc0, 0x70, 0x02, 0xe1, 0xfd, 0x4b, 0x84, 0xc3, 0x17, 0x70,
+       0x3e, 0x5a, 0x0d, 0xdb, 0xa4, 0xf9, 0x77, 0x90, 0x7f, 0x13, 0x3c, 0x53,
+       0xce, 0x87, 0xc0, 0x98, 0x03, 0xe1, 0x31, 0x02, 0xed, 0x58, 0x00, 0x53,
+       0xf4, 0x81, 0x57, 0x47, 0x54, 0x14, 0x1d, 0x2a, 0xc3, 0xa7, 0xa3, 0xc4,
+       0xc7, 0x03, 0x16, 0xef, 0xdf, 0x30, 0x26, 0xf5, 0x42, 0xd9, 0x9f, 0xd4,
+       0xd7, 0xc5, 0x9e, 0xf2, 0x70, 0x28, 0x59, 0x66, 0xd6, 0xd8, 0x2f, 0xe8,
+       0x1c, 0x5b, 0x95, 0xda, 0x68, 0x1b, 0x0e, 0x47, 0x7d, 0x9e, 0x3e, 0xea,
+       0x7c, 0xc4, 0x21, 0x36, 0x16, 0xc2, 0xab, 0xd1, 0x6c, 0x8d, 0xcd, 0xc7,
+       0x78, 0xd7, 0x09, 0x8f, 0xb3, 0x8c, 0xf2, 0x95, 0x67, 0x59, 0x5f, 0x2a,
+       0x7b, 0x96, 0x7c, 0x7e, 0x96, 0xb7, 0xcc, 0xfe, 0xfd, 0xa4, 0x21, 0xb5,
+       0xdf, 0xd7, 0x26, 0xbc, 0x7d, 0x29, 0xe8, 0xa6, 0xaf, 0x1c, 0xad, 0xf3,
+       0x26, 0x23, 0x90, 0xf3, 0x0d, 0x71, 0x0d, 0x1f, 0x53, 0xf7, 0x03, 0x94,
+       0xf5, 0x5f, 0xd3, 0xb7, 0x4b, 0x9e, 0xbc, 0x14, 0xbb, 0xfa, 0xcb, 0xb0,
+       0xb3, 0x3f, 0x82, 0xde, 0x25, 0x6b, 0x71, 0x32, 0x6a, 0x60, 0x43, 0xd0,
+       0xc0, 0xaa, 0xa0, 0x37, 0xf0, 0x03, 0xd4, 0x37, 0x1e, 0xc6, 0x43, 0xe4,
+       0x10, 0x2a, 0x65, 0xf2, 0x24, 0x3e, 0xd8, 0xed, 0xc0, 0xb3, 0xfa, 0x37,
+       0x69, 0xc3, 0x86, 0xf1, 0xab, 0xc5, 0xf3, 0x30, 0x94, 0xa8, 0x57, 0xbb,
+       0xb9, 0xbe, 0xf0, 0x5a, 0x9e, 0x55, 0x83, 0x03, 0x1b, 0xf5, 0xbf, 0x62,
+       0x5b, 0xb7, 0xcd, 0xa1, 0xc9, 0x77, 0x1b, 0xfd, 0xa9, 0x9c, 0x65, 0x84,
+       0xfa, 0x65, 0xf9, 0xb2, 0x70, 0xa6, 0x3e, 0xf1, 0x6c, 0x48, 0x30, 0xbf,
+       0x10, 0x27, 0x28, 0xb7, 0x37, 0x92, 0x61, 0x49, 0x45, 0x29, 0x1b, 0x43,
+       0x5d, 0x78, 0x8a, 0x7c, 0xe3, 0x03, 0x12, 0x81, 0x7b, 0xe2, 0x0a, 0x1a,
+       0xeb, 0x74, 0x9c, 0x4d, 0x3f, 0x89, 0x77, 0x46, 0x9a, 0xf0, 0x36, 0x7d,
+       0xfa, 0xc2, 0xff, 0xe9, 0x65, 0x2c, 0xef, 0xc1, 0xe9, 0x74, 0x13, 0xde,
+       0x8c, 0x7a, 0xdb, 0x5e, 0x20, 0x3f, 0xfa, 0x79, 0xda, 0x81, 0x3b, 0xe2,
+       0x8c, 0x7b, 0x38, 0x8e, 0x3f, 0xee, 0xc0, 0xc5, 0xb4, 0x8a, 0xc3, 0x3c,
+       0x1f, 0x47, 0x70, 0x21, 0xe3, 0x5e, 0x0f, 0x0e, 0x0e, 0x3e, 0x88, 0xa9,
+       0xd4, 0x83, 0x38, 0x96, 0xfc, 0xc0, 0x70, 0x69, 0x52, 0x27, 0x73, 0xe1,
+       0x22, 0x63, 0xb2, 0x69, 0x4a, 0xa3, 0x70, 0x69, 0x1b, 0xfd, 0xbc, 0x16,
+       0x11, 0xb9, 0xbf, 0xc3, 0xdf, 0xee, 0x89, 0x37, 0x62, 0xff, 0x18, 0x45,
+       0x9a, 0xd0, 0x91, 0x88, 0xc9, 0x5c, 0x21, 0xc4, 0xc8, 0x0b, 0x77, 0xf5,
+       0x1b, 0xf4, 0x17, 0x77, 0x48, 0x0c, 0xa2, 0xb4, 0xd6, 0xfe, 0x73, 0x66,
+       0x1f, 0x8d, 0xb3, 0x6a, 0xa0, 0xf9, 0x3c, 0x1b, 0xca, 0x95, 0xfd, 0xfe,
+       0x77, 0xa2, 0xc1, 0xf4, 0x4d, 0x47, 0xae, 0x9d, 0x47, 0x23, 0xcf, 0xe3,
+       0x49, 0x9c, 0xdd, 0xbd, 0x16, 0xef, 0x10, 0xef, 0x8a, 0x17, 0xfb, 0x3a,
+       0x9d, 0xb6, 0x7a, 0x8e, 0x9d, 0x36, 0x52, 0x95, 0x22, 0xd3, 0xb5, 0xf8,
+       0x65, 0x54, 0x64, 0x9a, 0x26, 0xfe, 0xf9, 0x3c, 0x7e, 0xfb, 0x5b, 0xb4,
+       0x09, 0xb7, 0xad, 0xbb, 0xc1, 0xaa, 0xe9, 0x15, 0x2e, 0x75, 0xe1, 0x92,
+       0xb9, 0x36, 0x59, 0xeb, 0x9f, 0x5b, 0xdf, 0x2f, 0x8d, 0x55, 0x95, 0xb2,
+       0xbe, 0x88, 0x91, 0xa3, 0x69, 0x81, 0x1c, 0x45, 0xfc, 0x6c, 0xc0, 0xac,
+       0x63, 0xd4, 0xc5, 0xbb, 0x60, 0x0f, 0x16, 0x32, 0x3e, 0xf3, 0xce, 0x74,
+       0xe0, 0x1d, 0x5c, 0x9e, 0x70, 0x61, 0x41, 0x3c, 0x80, 0x57, 0x26, 0x72,
+       0x2b, 0x91, 0xff, 0x0b, 0x9c, 0xe7, 0x77, 0x5f, 0xdc, 0xb2, 0xb7, 0xee,
+       0xd0, 0x5a, 0xac, 0x48, 0xcb, 0xfe, 0x9e, 0xe4, 0x44, 0x3a, 0xc2, 0x69,
+       0xd9, 0x67, 0x8c, 0xb6, 0x21, 0xfb, 0x2c, 0xfb, 0x9a, 0x7d, 0xbe, 0xcb,
+       0xb5, 0xcf, 0xa3, 0x2d, 0x65, 0x7d, 0x47, 0x11, 0x0e, 0x26, 0x55, 0x9c,
+       0xd0, 0x8b, 0x70, 0x4e, 0x95, 0x7c, 0xbd, 0x8b, 0x3e, 0xc4, 0x81, 0x66,
+       0xc6, 0x4b, 0xc3, 0xd1, 0x3c, 0x3c, 0xa3, 0x3a, 0x70, 0x4a, 0x77, 0xe0,
+       0x98, 0x7e, 0x1b, 0xb1, 0x5e, 0xe2, 0x08, 0xd3, 0xbf, 0x90, 0x31, 0x65,
+       0xf5, 0x58, 0x9e, 0x17, 0xc2, 0x53, 0x5a, 0x86, 0x37, 0x25, 0xef, 0x68,
+       0xb6, 0x71, 0x49, 0xad, 0x17, 0x87, 0x28, 0xb3, 0x9c, 0x58, 0x39, 0x2e,
+       0xb5, 0x35, 0xde, 0xa2, 0x1f, 0x69, 0xac, 0xf6, 0xb1, 0xb1, 0xb9, 0xf2,
+       0xda, 0x98, 0x1e, 0x28, 0x47, 0x2a, 0x2c, 0x9c, 0xc8, 0xd6, 0xe1, 0xb2,
+       0xbe, 0x6c, 0x76, 0xbf, 0xd9, 0xfb, 0x7c, 0xa1, 0x52, 0xb0, 0xc9, 0x61,
+       0xc6, 0x82, 0x6d, 0xdf, 0xa4, 0x8f, 0xa2, 0xcf, 0x5e, 0xbb, 0x45, 0x62,
+       0x43, 0x5b, 0xd3, 0xba, 0x6f, 0x2e, 0xd7, 0x72, 0x60, 0x37, 0xb9, 0xa0,
+       0xe3, 0x65, 0x8b, 0xbf, 0xbb, 0x5e, 0xd6, 0xcc, 0xcf, 0xc2, 0x97, 0x17,
+       0x98, 0x9f, 0xea, 0xcb, 0xbe, 0xd4, 0x75, 0x5f, 0x66, 0xf1, 0x63, 0xf3,
+       0xae, 0x10, 0xfa, 0xf4, 0x88, 0x72, 0x7f, 0x48, 0x78, 0xe6, 0x6c, 0x8e,
+       0x11, 0x50, 0x4e, 0x45, 0x23, 0x46, 0xb5, 0x96, 0x1f, 0x29, 0x26, 0xf7,
+       0x6e, 0xf4, 0x6b, 0xc4, 0x6a, 0x89, 0xe9, 0x34, 0x9c, 0xe1, 0x79, 0x10,
+       0x62, 0xa9, 0xe3, 0xff, 0x0f, 0xd1, 0xdd, 0x68, 0xcf, 0x37, 0x71, 0xc9,
+       0x30, 0x76, 0x05, 0x25, 0x07, 0x21, 0xe3, 0x3a, 0xf0, 0x11, 0xcf, 0xf9,
+       0x37, 0x23, 0x05, 0xf8, 0x30, 0xa5, 0xe1, 0x5c, 0x7a, 0x2d, 0x76, 0x4c,
+       0x58, 0x1c, 0xe4, 0x58, 0xda, 0xe2, 0x44, 0x12, 0xd3, 0xef, 0x27, 0x47,
+       0x88, 0x25, 0x5e, 0x37, 0xf2, 0x34, 0xdf, 0x94, 0xdf, 0xee, 0xc0, 0xbe,
+       0xf4, 0x34, 0x26, 0xfa, 0x3f, 0x33, 0xec, 0x5a, 0x17, 0x3e, 0x0d, 0x4e,
+       0x63, 0xfc, 0x80, 0xd4, 0x50, 0x43, 0xd8, 0x35, 0x18, 0x40, 0x6f, 0xc2,
+       0x86, 0x9d, 0x4b, 0x5a, 0xb1, 0x6b, 0xa2, 0x05, 0x91, 0x43, 0x1e, 0xec,
+       0x4c, 0xa7, 0x31, 0x35, 0x32, 0x8d, 0x93, 0x49, 0x8d, 0xf1, 0xe4, 0x34,
+       0x4e, 0xa4, 0x38, 0x66, 0xe2, 0x3d, 0x44, 0x38, 0xc6, 0xb6, 0xa4, 0xa6,
+       0x0e, 0x9b, 0x7b, 0x9c, 0x46, 0x77, 0xea, 0x56, 0x39, 0x13, 0xae, 0x27,
+       0xd1, 0xd3, 0x6e, 0xd5, 0x45, 0x88, 0xbd, 0x69, 0x4d, 0xe9, 0xe3, 0xf9,
+       0x1d, 0x4e, 0x67, 0x6b, 0x24, 0x37, 0xe7, 0x4a, 0x42, 0xe8, 0x1b, 0x6c,
+       0x65, 0x9f, 0x00, 0xba, 0x13, 0x52, 0x87, 0xf6, 0x71, 0x4e, 0x03, 0xbf,
+       0xd6, 0xbd, 0xee, 0x05, 0xfc, 0x1c, 0xd5, 0x3b, 0xb1, 0x89, 0x63, 0x4d,
+       0x31, 0x46, 0xd2, 0x14, 0x6f, 0x63, 0x04, 0x76, 0xfc, 0x4a, 0x27, 0x1f,
+       0xaa, 0xb0, 0xe3, 0x55, 0xea, 0x5a, 0xb8, 0xd4, 0x8e, 0xfa, 0x20, 0x7d,
+       0x78, 0xc6, 0xa7, 0x7f, 0x92, 0x54, 0xf0, 0x20, 0xf1, 0xf6, 0x8d, 0x60,
+       0x7d, 0xfb, 0x4a, 0x61, 0x7b, 0x07, 0x14, 0x5c, 0xd6, 0xae, 0x1a, 0x11,
+       0xea, 0x87, 0xcb, 0x9f, 0x3d, 0xa3, 0x7f, 0xc9, 0xe4, 0xf0, 0xbe, 0x34,
+       0xb2, 0xfd, 0x66, 0xb8, 0xc6, 0x27, 0xd8, 0x6f, 0xc1, 0xe2, 0xfa, 0x4e,
+       0xe9, 0xe7, 0x26, 0xde, 0x4b, 0xbf, 0x73, 0x95, 0x8e, 0x59, 0xfd, 0x42,
+       0xd8, 0x36, 0xd8, 0x6c, 0xae, 0x77, 0x7b, 0x02, 0x8b, 0x1c, 0x10, 0x5b,
+       0xab, 0x57, 0x2f, 0x02, 0x5d, 0xd3, 0x7a, 0x09, 0x79, 0x90, 0x3f, 0xf0,
+       0x0c, 0x44, 0x56, 0x12, 0x67, 0xbe, 0x87, 0x9d, 0xd1, 0x11, 0x30, 0xd6,
+       0x24, 0x06, 0xfa, 0xd7, 0x0d, 0x23, 0x85, 0xe7, 0xd3, 0x29, 0xbc, 0x40,
+       0x19, 0x45, 0xcc, 0xbb, 0x62, 0x69, 0x7c, 0x3b, 0xfa, 0x1e, 0x62, 0xe6,
+       0x99, 0x1d, 0xc6, 0xfa, 0xa8, 0xbb, 0x0a, 0xf9, 0xd2, 0x77, 0x25, 0xc7,
+       0x17, 0xb9, 0x7a, 0xdb, 0x22, 0xf8, 0x8a, 0xe3, 0xaf, 0x44, 0xcf, 0xb0,
+       0x61, 0xfc, 0x90, 0xbe, 0xed, 0x2d, 0x72, 0xaf, 0xcb, 0x99, 0x7b, 0x67,
+       0x79, 0x94, 0xb7, 0x66, 0xfa, 0xb8, 0xb5, 0x3c, 0xe7, 0x2a, 0xe1, 0xfc,
+       0x28, 0x1a, 0xd3, 0x94, 0x05, 0x31, 0x39, 0x77, 0x72, 0xca, 0x31, 0x0f,
+       0x9e, 0x20, 0x7f, 0xc9, 0x1d, 0xfd, 0x5b, 0x45, 0xfc, 0x5c, 0xf5, 0x01,
+       0xc6, 0x02, 0x07, 0x3c, 0xca, 0xc2, 0x3d, 0x2e, 0x3c, 0x18, 0x73, 0xe0,
+       0xfe, 0x58, 0x0b, 0x7a, 0xf6, 0x6a, 0x6c, 0xe3, 0xd5, 0xcf, 0x30, 0x5e,
+       0x3d, 0x01, 0x9f, 0x67, 0x98, 0x9c, 0xcb, 0x4d, 0x9c, 0x76, 0x8c, 0x16,
+       0xa3, 0x60, 0x54, 0x85, 0x6d, 0xb4, 0x0c, 0x85, 0xa3, 0x6e, 0x54, 0xd3,
+       0xef, 0xb9, 0xc7, 0xce, 0x62, 0x62, 0x8f, 0xe4, 0x53, 0xbf, 0x30, 0x72,
+       0xc9, 0xcb, 0x3e, 0x0d, 0x06, 0x50, 0x3c, 0xb6, 0x05, 0xe9, 0x58, 0x03,
+       0x0a, 0xc7, 0x48, 0xb3, 0xc6, 0x26, 0x95, 0x7a, 0xce, 0xd9, 0x12, 0xd3,
+       0x38, 0x96, 0xc5, 0x83, 0x56, 0xd2, 0x57, 0xf6, 0x25, 0xbc, 0xeb, 0xa4,
+       0x2e, 0x79, 0x59, 0x3f, 0x8e, 0xbc, 0xfe, 0xec, 0xfd, 0x39, 0x78, 0xf3,
+       0x80, 0x92, 0x1e, 0xdd, 0xdf, 0xb6, 0x11, 0xd6, 0x5d, 0xba, 0xfb, 0x33,
+       0x7b, 0x6a, 0x90, 0x3d, 0x39, 0xd7, 0x52, 0x17, 0xe6, 0xa0, 0x84, 0x7b,
+       0x3a, 0x4f, 0xfd, 0xb9, 0x87, 0xeb, 0xbd, 0xca, 0xb8, 0xb1, 0x33, 0x26,
+       0x7a, 0xff, 0xb7, 0x0a, 0xed, 0x06, 0x33, 0xa9, 0x02, 0x7c, 0x96, 0xf2,
+       0x28, 0x3e, 0xee, 0xe7, 0x3b, 0x7c, 0xfe, 0x6d, 0xee, 0x67, 0xeb, 0x5e,
+       0x6f, 0xdb, 0x51, 0xc5, 0xdb, 0xbe, 0x46, 0xf1, 0xa9, 0x5b, 0x95, 0x42,
+       0x9c, 0x1f, 0x29, 0xc6, 0x45, 0xfa, 0xe9, 0xab, 0x23, 0x65, 0xb8, 0x34,
+       0x52, 0x41, 0x5b, 0xd1, 0x38, 0x86, 0x61, 0x14, 0x69, 0x6e, 0xcc, 0xa4,
+       0x5f, 0x40, 0x49, 0x6c, 0x1e, 0x3e, 0x4b, 0x6f, 0x42, 0x71, 0x4c, 0xf8,
+       0xbc, 0x07, 0x9f, 0xf2, 0xf9, 0x27, 0xe9, 0x71, 0xe4, 0xef, 0xf9, 0x82,
+       0x6d, 0x0c, 0xa3, 0x85, 0x7b, 0xbc, 0x94, 0xee, 0x40, 0xe1, 0x9e, 0x97,
+       0xe0, 0xd8, 0x63, 0x74, 0xf5, 0x04, 0xf1, 0x73, 0x3b, 0xf7, 0xd2, 0xad,
+       0x7b, 0xa7, 0x16, 0xd8, 0x1b, 0x38, 0x86, 0xce, 0x31, 0x27, 0x95, 0x85,
+       0x63, 0x2f, 0xa1, 0x78, 0x8f, 0x07, 0x9b, 0x29, 0xcb, 0x71, 0x68, 0x81,
+       0x35, 0xca, 0x4b, 0xc8, 0x19, 0xb5, 0x64, 0xb0, 0x61, 0xcc, 0xb2, 0x91,
+       0x96, 0x90, 0xe4, 0x94, 0x26, 0x95, 0x61, 0xd3, 0x46, 0xdc, 0x72, 0xd7,
+       0x07, 0xd3, 0xe9, 0x02, 0x9c, 0x4a, 0x89, 0x8c, 0xe4, 0xbe, 0xe0, 0x38,
+       0x72, 0xf7, 0x10, 0x3f, 0x47, 0x74, 0x93, 0x5f, 0x88, 0x6d, 0x8c, 0xa4,
+       0x6f, 0x65, 0x5f, 0x3a, 0x76, 0x26, 0xaa, 0x69, 0x5b, 0xf3, 0xb0, 0x6a,
+       0x8f, 0x61, 0x04, 0x82, 0x53, 0xf7, 0xb8, 0xa8, 0x4d, 0x87, 0xd2, 0xb7,
+       0xb2, 0xad, 0x46, 0xea, 0xa9, 0xb7, 0x35, 0x62, 0xe6, 0xbb, 0x0d, 0x4c,
+       0xeb, 0x93, 0x8a, 0x2d, 0x26, 0xb1, 0xd8, 0x5a, 0xda, 0x7c, 0x1b, 0x7a,
+       0x06, 0xd1, 0xbe, 0x3f, 0x24, 0xb5, 0x70, 0x27, 0x86, 0x19, 0x5b, 0x9d,
+       0x67, 0x3c, 0x42, 0x99, 0xab, 0x39, 0x4d, 0x39, 0x18, 0x1a, 0x71, 0xe1,
+       0x27, 0x23, 0x1e, 0x34, 0xc6, 0xbe, 0x20, 0x66, 0xe4, 0x63, 0x92, 0xf2,
+       0x9e, 0x20, 0x37, 0xfa, 0x34, 0xaa, 0x62, 0x9c, 0x7e, 0xf8, 0x93, 0x68,
+       0x05, 0xc6, 0x18, 0x87, 0x7d, 0x1c, 0xd5, 0x90, 0xe6, 0xd9, 0x7c, 0x44,
+       0xbc, 0xf9, 0x61, 0xba, 0x01, 0xbf, 0x89, 0x36, 0xe0, 0x55, 0xca, 0xb1,
+       0x2e, 0xe6, 0xe6, 0x9a, 0x8e, 0x28, 0x38, 0x30, 0xa9, 0xe4, 0x50, 0x2f,
+       0xfc, 0x31, 0xcd, 0x33, 0x9c, 0xd1, 0x0b, 0x6d, 0xac, 0x8d, 0x76, 0x24,
+       0x77, 0x2d, 0xc4, 0x77, 0x38, 0xf4, 0x61, 0x90, 0xef, 0x35, 0x64, 0x73,
+       0x8b, 0x5e, 0xf7, 0x14, 0xaa, 0x68, 0x4b, 0x5f, 0x19, 0xaa, 0x26, 0x79,
+       0xb4, 0x64, 0xf0, 0x72, 0x54, 0x53, 0x2f, 0x99, 0x7b, 0x88, 0x28, 0xce,
+       0x25, 0x92, 0xa3, 0xd8, 0xca, 0xfd, 0x07, 0x88, 0x19, 0x57, 0xcc, 0x73,
+       0x52, 0xb5, 0xe3, 0x68, 0x30, 0xef, 0xa4, 0x31, 0xd6, 0x5b, 0x72, 0x1c,
+       0x77, 0x1e, 0xf8, 0x3f, 0x55, 0x16, 0x57, 0xa2, 0x6d, 0xdb, 0x6e, 0xce,
+       0x83, 0x49, 0x4e, 0x7d, 0x77, 0xf0, 0x78, 0xf4, 0x37, 0x55, 0x52, 0x6b,
+       0x3b, 0x4a, 0xce, 0xb4, 0x3d, 0x71, 0xab, 0x98, 0xc2, 0xc0, 0x3b, 0xc4,
+       0x97, 0x4b, 0x49, 0xe1, 0x55, 0xc2, 0xa7, 0xba, 0xe8, 0xbb, 0x8a, 0xc8,
+       0x27, 0xe8, 0x67, 0xc9, 0xf9, 0x7d, 0xf1, 0x29, 0xc6, 0x34, 0x77, 0x93,
+       0xd3, 0x15, 0x73, 0x98, 0xf7, 0x39, 0x5f, 0x1b, 0x76, 0xd2, 0x4e, 0xf3,
+       0xb4, 0x05, 0x58, 0x45, 0xbe, 0xe4, 0xd0, 0xe8, 0x6e, 0x1e, 0x11, 0x9f,
+       0x03, 0xd4, 0xc6, 0x55, 0x14, 0x36, 0x69, 0xeb, 0xde, 0xc2, 0x3d, 0x68,
+       0xaf, 0x74, 0x41, 0xea, 0x09, 0x6f, 0x63, 0x19, 0x52, 0x8f, 0x89, 0xef,
+       0xb5, 0x49, 0x7d, 0x2c, 0x72, 0x16, 0x35, 0x26, 0x73, 0xcf, 0x6f, 0x92,
+       0xf5, 0x54, 0xf0, 0x2c, 0x54, 0x5c, 0xa0, 0x8c, 0x2f, 0x46, 0x7d, 0x33,
+       0x2b, 0x50, 0x7f, 0xf2, 0xa2, 0x9d, 0xbc, 0xb0, 0x5c, 0xda, 0x37, 0x40,
+       0xe3, 0x78, 0x9f, 0x47, 0x83, 0xe8, 0x57, 0xe5, 0xbb, 0xf0, 0xcb, 0x36,
+       0x74, 0x0f, 0xcb, 0x1a, 0x0c, 0xa3, 0x8c, 0x58, 0xf9, 0x88, 0x39, 0xbf,
+       0xcc, 0x7d, 0x73, 0x7c, 0x92, 0xf5, 0x7f, 0x12, 0xa3, 0x4c, 0xe3, 0x70,
+       0xd2, 0x03, 0xc7, 0x92, 0xaa, 0x39, 0xc8, 0x9f, 0xc6, 0x48, 0x4a, 0x23,
+       0xf7, 0x2c, 0x80, 0xa7, 0x52, 0xc7, 0x2e, 0xfa, 0xfc, 0x18, 0xdb, 0xa7,
+       0x63, 0x05, 0x88, 0x54, 0x5a, 0x73, 0xde, 0x1d, 0xff, 0xd8, 0x98, 0x7a,
+       0xd8, 0xf4, 0xa1, 0xfc, 0x1e, 0x64, 0x9f, 0x39, 0x72, 0xed, 0x14, 0xcf,
+       0xc6, 0x2e, 0x19, 0x53, 0x6d, 0xb3, 0x7f, 0x2f, 0x35, 0xef, 0x6e, 0x85,
+       0x6d, 0x95, 0xfc, 0xb4, 0xe4, 0xd2, 0x4d, 0xb9, 0x94, 0x68, 0xef, 0x19,
+       0x0f, 0x59, 0x72, 0x99, 0x23, 0xf1, 0x40, 0x6d, 0xfc, 0xf1, 0x39, 0x92,
+       0x6f, 0x15, 0x7f, 0xe6, 0x6a, 0xd2, 0x1a, 0x4f, 0xe2, 0x17, 0xc6, 0xb9,
+       0x1b, 0xc6, 0x29, 0xe7, 0x33, 0xf1, 0x4d, 0xe7, 0x32, 0xf7, 0x00, 0xdc,
+       0x99, 0x98, 0x61, 0x1a, 0x47, 0x93, 0xe2, 0x17, 0x3c, 0x58, 0x2f, 0xf9,
+       0x2a, 0xd5, 0xdb, 0x17, 0xc1, 0x14, 0x39, 0xe2, 0x07, 0x94, 0xbd, 0x22,
+       0xf5, 0x3a, 0xf2, 0xc4, 0xd9, 0xbe, 0x2b, 0x8c, 0x94, 0x59, 0x8f, 0x12,
+       0x6c, 0x9d, 0xc6, 0xf6, 0xa4, 0xd4, 0x4d, 0x3f, 0x23, 0x6f, 0xea, 0x22,
+       0x27, 0x9f, 0x46, 0x4f, 0xaa, 0x05, 0xaf, 0xec, 0x6d, 0x25, 0xde, 0x08,
+       0x6e, 0xfa, 0x4e, 0x9e, 0xb7, 0xb7, 0x60, 0xff, 0xa1, 0x34, 0x52, 0xa3,
+       0xe2, 0x2f, 0xe5, 0x1e, 0x9c, 0xf8, 0xca, 0x00, 0xa2, 0x89, 0x13, 0x88,
+       0xf0, 0x73, 0x67, 0xe2, 0x25, 0x84, 0x47, 0xdf, 0x63, 0x2c, 0x30, 0x8d,
+       0x95, 0xd4, 0xb9, 0x83, 0x98, 0xc6, 0xea, 0x03, 0x1a, 0x92, 0x89, 0x56,
+       0x8e, 0xdf, 0x82, 0xde, 0xbd, 0xde, 0x80, 0xc3, 0x56, 0x42, 0x7f, 0xa5,
+       0x61, 0xdb, 0x44, 0x33, 0x22, 0xc3, 0x56, 0x5d, 0xac, 0x21, 0xee, 0x51,
+       0x3e, 0x21, 0x9f, 0xae, 0x8f, 0x7b, 0x19, 0xc7, 0x79, 0x23, 0xab, 0x15,
+       0x9f, 0x27, 0xc7, 0x66, 0x18, 0xbd, 0xf4, 0x1b, 0x27, 0x75, 0x05, 0x79,
+       0xf7, 0x28, 0x08, 0xd2, 0x8f, 0x79, 0xaa, 0xe8, 0x5f, 0x86, 0x43, 0xe8,
+       0x1d, 0x9c, 0x5d, 0x53, 0x94, 0xf3, 0x7a, 0x80, 0xe3, 0xc9, 0xd9, 0xb5,
+       0xa2, 0x77, 0xc2, 0xd7, 0x71, 0xd2, 0xac, 0x39, 0x4a, 0xbb, 0x6c, 0x1b,
+       0x14, 0x7e, 0x16, 0xf2, 0x06, 0x4a, 0x14, 0x69, 0xbb, 0x95, 0x58, 0x36,
+       0xbb, 0x7d, 0x44, 0x49, 0x2e, 0x21, 0x7f, 0xb5, 0x89, 0x5d, 0x74, 0x9b,
+       0xb6, 0x23, 0xb2, 0xe8, 0x4d, 0x86, 0xa9, 0xd3, 0x3f, 0x35, 0x52, 0x6d,
+       0x6d, 0x5c, 0x67, 0xa3, 0xd4, 0x9c, 0x4c, 0x9e, 0x72, 0x5a, 0xf2, 0x73,
+       0x4e, 0xf1, 0xe3, 0xdd, 0xed, 0x2e, 0xea, 0x53, 0x2e, 0xb1, 0x2a, 0x6f,
+       0xdc, 0x05, 0xd7, 0xc1, 0x02, 0xe4, 0x0e, 0x09, 0x9f, 0x83, 0x5a, 0xdc,
+       0xa4, 0xc2, 0x3e, 0x5e, 0x48, 0x1b, 0xe0, 0x19, 0x8e, 0xd3, 0xc6, 0xa2,
+       0x6e, 0xd4, 0x8c, 0xbb, 0xf1, 0x13, 0xe2, 0x41, 0xf5, 0xb8, 0x86, 0x49,
+       0xe2, 0x81, 0x7b, 0x3c, 0x80, 0x09, 0xe2, 0x41, 0x49, 0x26, 0x47, 0xf2,
+       0x76, 0xfa, 0x65, 0x9e, 0xab, 0xcc, 0x25, 0x72, 0xcc, 0x9e, 0xab, 0x9c,
+       0x69, 0x2b, 0x31, 0x50, 0xce, 0xb7, 0x01, 0x3b, 0x06, 0xd3, 0x58, 0xbe,
+       0xc7, 0xc0, 0xbb, 0x7a, 0xbd, 0x3b, 0x4f, 0x91, 0x78, 0xc2, 0x40, 0x5a,
+       0x97, 0x3b, 0xab, 0xde, 0x75, 0x72, 0xaf, 0xbb, 0xbd, 0xc2, 0x40, 0x4e,
+       0xd0, 0xab, 0x13, 0xf9, 0xd7, 0xe5, 0x29, 0xe2, 0xc3, 0xea, 0x3d, 0x9b,
+       0x30, 0x57, 0x6a, 0x8e, 0xfc, 0xb7, 0x02, 0x9b, 0xc8, 0x1b, 0xf3, 0xb5,
+       0x56, 0xec, 0x2c, 0x8d, 0xb8, 0x2e, 0x87, 0x0c, 0x63, 0x43, 0xf0, 0xf1,
+       0x2a, 0x93, 0x03, 0xda, 0xf6, 0xf1, 0x73, 0x2d, 0xf7, 0x2d, 0x7b, 0xef,
+       0x40, 0x6c, 0xb7, 0x82, 0xb4, 0xbf, 0x03, 0xd1, 0x91, 0x0e, 0xec, 0xda,
+       0x2d, 0x98, 0xd0, 0x47, 0x4c, 0x30, 0xba, 0x36, 0x06, 0x1f, 0xc2, 0x25,
+       0x93, 0x11, 0x48, 0x1f, 0x6f, 0xc0, 0x63, 0x9b, 0x7d, 0x0e, 0x1b, 0xb9,
+       0x7e, 0xcb, 0x76, 0x9a, 0xfb, 0x85, 0x7b, 0xfb, 0xfb, 0x7a, 0x79, 0xfe,
+       0x0f, 0x1f, 0x10, 0xdf, 0x63, 0x18, 0x7d, 0xfa, 0x3c, 0xa0, 0x54, 0xf6,
+       0x10, 0x40, 0x3c, 0x61, 0x7c, 0x56, 0xad, 0xf9, 0x66, 0x76, 0xd1, 0xcf,
+       0x9f, 0xdd, 0x53, 0xbf, 0x69, 0x93, 0x70, 0x9a, 0xc5, 0xc2, 0xf3, 0xd2,
+       0x38, 0x33, 0x7a, 0x27, 0x52, 0x0f, 0x73, 0x3f, 0x3c, 0x2b, 0x67, 0xfc,
+       0x4b, 0x43, 0x78, 0x9d, 0x5d, 0x93, 0x9a, 0x2d, 0xa7, 0x1c, 0xf7, 0xa3,
+       0xa7, 0x14, 0x91, 0xcb, 0x21, 0x99, 0xff, 0xda, 0xfa, 0xb9, 0xdf, 0x16,
+       0xec, 0xda, 0x2b, 0xbc, 0x43, 0x38, 0x9a, 0x2f, 0xf2, 0x11, 0x5a, 0x91,
+       0x9c, 0xb0, 0xe6, 0x8a, 0x26, 0x6e, 0xd6, 0x15, 0x39, 0xf7, 0x13, 0xd8,
+       0x41, 0x8e, 0xe7, 0xe2, 0xf8, 0xf4, 0x35, 0x1c, 0x4f, 0x0b, 0xe4, 0xc9,
+       0x7c, 0xe3, 0x3f, 0x35, 0x76, 0x56, 0x8a, 0x6c, 0x64, 0x7c, 0xcd, 0xc4,
+       0x8c, 0x0d, 0xc1, 0x3f, 0xb7, 0xd7, 0x1a, 0x37, 0xf2, 0xbd, 0xad, 0x96,
+       0x3c, 0xa4, 0xad, 0xf6, 0x27, 0xd6, 0xb3, 0x90, 0xed, 0x64, 0x4d, 0x1d,
+       0xd8, 0xb1, 0x1b, 0x91, 0x7c, 0x4d, 0x6a, 0x0d, 0x1d, 0xe8, 0xa3, 0x7c,
+       0xb7, 0x25, 0x3b, 0xb0, 0x9f, 0x36, 0x3b, 0xa4, 0xbf, 0x51, 0x6d, 0x43,
+       0xdd, 0x8c, 0x1d, 0x53, 0x3f, 0xab, 0x21, 0x9e, 0x2e, 0x5c, 0xec, 0xa7,
+       0x7d, 0x75, 0x20, 0x9e, 0xca, 0x75, 0x9b, 0x35, 0x40, 0x9b, 0xf8, 0x42,
+       0x91, 0x45, 0x27, 0xf2, 0xfb, 0x4f, 0xc0, 0xd9, 0xdf, 0x89, 0x3c, 0xff,
+       0x32, 0xdc, 0x1f, 0x3c, 0x67, 0x5c, 0xd2, 0x1c, 0xee, 0xa3, 0x94, 0xcf,
+       0x1b, 0x0d, 0xd5, 0x8c, 0x3b, 0x1b, 0xb0, 0x6d, 0xf8, 0x36, 0xda, 0x7e,
+       0x23, 0xb9, 0x2f, 0xe7, 0x6a, 0xb2, 0x61, 0xf5, 0x12, 0x89, 0xe9, 0xa5,
+       0x3e, 0x5d, 0x25, 0xf7, 0x10, 0xd4, 0xe7, 0x21, 0xf1, 0x1a, 0x39, 0x59,
+       0x85, 0x07, 0x4f, 0xd3, 0xc6, 0xda, 0x55, 0x79, 0xbe, 0x85, 0x71, 0xc4,
+       0x16, 0x54, 0xc7, 0x22, 0x86, 0xc8, 0xfb, 0x28, 0xc2, 0xdf, 0x93, 0x9a,
+       0x4a, 0xe3, 0x62, 0xff, 0xa6, 0x19, 0x45, 0x74, 0xda, 0xdf, 0x3e, 0xae,
+       0xe8, 0xae, 0x07, 0xc6, 0x14, 0x04, 0xfa, 0x39, 0x56, 0xf0, 0xfd, 0x39,
+       0x56, 0x1e, 0x2d, 0xcb, 0xff, 0xb6, 0x90, 0x33, 0x6c, 0x41, 0x11, 0xfb,
+       0xbb, 0x35, 0xc1, 0x86, 0xf0, 0x7d, 0xc5, 0xec, 0x9f, 0x0e, 0xfa, 0xdb,
+       0x0a, 0x15, 0xe1, 0x46, 0xfe, 0xc6, 0xd5, 0x8a, 0xf0, 0x18, 0xe9, 0xa7,
+       0xbb, 0xea, 0xc6, 0xce, 0x66, 0x6a, 0x66, 0x8d, 0xc4, 0x07, 0x8f, 0x79,
+       0x07, 0xd5, 0xba, 0xaf, 0x95, 0xbd, 0xb3, 0xa4, 0xf2, 0xfc, 0x25, 0xc6,
+       0x38, 0x12, 0x5c, 0x1e, 0x6d, 0x92, 0xfb, 0x21, 0xcb, 0x0e, 0x51, 0xef,
+       0xcf, 0xa3, 0x02, 0xff, 0x10, 0x15, 0x5c, 0xf3, 0xe0, 0x1f, 0xa3, 0xb9,
+       0x12, 0x57, 0xa7, 0x24, 0x6f, 0xf9, 0x66, 0x32, 0x62, 0x50, 0xae, 0xad,
+       0xab, 0xa9, 0x4b, 0x81, 0x60, 0x21, 0x50, 0xd9, 0xfd, 0xb4, 0xd3, 0x8c,
+       0xf3, 0x8b, 0x50, 0x4a, 0x1f, 0xd0, 0x3f, 0xfc, 0xa7, 0x72, 0xb4, 0xef,
+       0x9b, 0xdc, 0xf2, 0xef, 0xea, 0xec, 0xd8, 0x16, 0xfc, 0x57, 0x23, 0x95,
+       0xb9, 0x33, 0x7c, 0x66, 0xb7, 0xe8, 0x69, 0x00, 0xb9, 0xf1, 0xb3, 0xd4,
+       0x49, 0x15, 0xa7, 0xa3, 0x3e, 0x7d, 0x8d, 0xed, 0x49, 0xea, 0x7f, 0xcd,
+       0x0d, 0xd8, 0x5d, 0xa3, 0x3d, 0x88, 0xa7, 0x4c, 0xec, 0x0e, 0xa3, 0x87,
+       0xbe, 0x81, 0x9c, 0x6e, 0xdf, 0xd3, 0x36, 0x15, 0x79, 0x31, 0x9f, 0xea,
+       0xa3, 0x4e, 0xf5, 0x70, 0x0e, 0xe1, 0x9b, 0xe5, 0xe4, 0x83, 0x1b, 0xa3,
+       0xf5, 0x9e, 0x7f, 0xc1, 0x7a, 0xda, 0xa3, 0xcc, 0x21, 0x7b, 0xd2, 0x50,
+       0x18, 0xd7, 0x70, 0x8c, 0xfb, 0xd8, 0x56, 0x6a, 0xcd, 0x5b, 0x9c, 0x19,
+       0x3b, 0x3e, 0x2c, 0x5c, 0x6c, 0x29, 0xd6, 0x98, 0x63, 0xeb, 0xb4, 0x4b,
+       0x0d, 0xfb, 0xe4, 0x6e, 0x7f, 0x9d, 0x86, 0x44, 0xba, 0x19, 0x2f, 0x95,
+       0x79, 0xb0, 0x3f, 0xb1, 0x05, 0x8b, 0x12, 0xf7, 0xe1, 0xd1, 0xb2, 0x88,
+       0xdc, 0x85, 0x41, 0x5e, 0x5c, 0x53, 0xef, 0x54, 0xee, 0xcd, 0xd4, 0x29,
+       0x2a, 0xe0, 0x88, 0x8b, 0xcf, 0xcb, 0xc1, 0x80, 0x3a, 0x17, 0x05, 0xe6,
+       0x9d, 0x4a, 0x6b, 0xec, 0x5d, 0xc3, 0xde, 0x8c, 0x1f, 0x24, 0x6a, 0xc4,
+       0x15, 0xf1, 0xbf, 0x81, 0x17, 0x50, 0xce, 0x38, 0x21, 0x82, 0x9c, 0x26,
+       0x2d, 0xf5, 0x2c, 0xf2, 0x10, 0xa9, 0x12, 0x4c, 0x94, 0x3e, 0xb7, 0xdd,
+       0xb4, 0xa6, 0xb2, 0xcc, 0x9a, 0xb2, 0xcf, 0x31, 0x07, 0xc5, 0xa2, 0x5b,
+       0xc2, 0x35, 0xe4, 0xf7, 0x7c, 0xb4, 0x51, 0x9f, 0x2a, 0xb8, 0xe6, 0x84,
+       0x79, 0x5f, 0xd6, 0xab, 0x47, 0x6c, 0x21, 0xfc, 0x76, 0x8f, 0xa5, 0x83,
+       0xeb, 0x6a, 0x79, 0xfe, 0xc5, 0x21, 0xcc, 0x8c, 0x8a, 0x3f, 0xfb, 0x53,
+       0x67, 0x92, 0xf5, 0xc5, 0x72, 0x2e, 0x22, 0x57, 0xef, 0xc9, 0x0b, 0xa8,
+       0x9f, 0x7a, 0xc2, 0x76, 0xd8, 0x40, 0xb9, 0xc8, 0xf8, 0xb8, 0x5b, 0x62,
+       0x58, 0x1b, 0x79, 0x44, 0x24, 0x7d, 0xc5, 0x2d, 0xbe, 0xd2, 0x11, 0x07,
+       0x6a, 0xe2, 0x11, 0xe4, 0x36, 0x69, 0xfb, 0x2e, 0xdb, 0xaf, 0x1a, 0xed,
+       0x55, 0xb7, 0x31, 0x26, 0xbc, 0xbe, 0xe7, 0x3e, 0xae, 0xdd, 0xae, 0xfd,
+       0xd4, 0x58, 0x51, 0x21, 0x6b, 0xac, 0xae, 0xb6, 0xf2, 0xd1, 0xf3, 0x29,
+       0x97, 0xac, 0x4c, 0x0c, 0xea, 0xcf, 0xff, 0x32, 0xbe, 0x71, 0xc3, 0x73,
+       0xe1, 0x33, 0xa2, 0xa7, 0xb3, 0xef, 0x14, 0x8a, 0xce, 0x7a, 0xa8, 0xa7,
+       0xd3, 0x38, 0x94, 0x6c, 0x44, 0x7f, 0x42, 0x64, 0x1c, 0xc6, 0x79, 0x72,
+       0xc5, 0xda, 0x81, 0x69, 0x0c, 0x91, 0x2b, 0xfa, 0xe2, 0xde, 0x7d, 0x94,
+       0x24, 0x5e, 0x52, 0x97, 0x99, 0x3c, 0xc9, 0xa5, 0x65, 0xd7, 0x70, 0xb7,
+       0x29, 0x77, 0xf1, 0x31, 0x3b, 0xb9, 0xdf, 0x3b, 0xc8, 0x93, 0x9a, 0x63,
+       0xb9, 0xd0, 0x4a, 0x8b, 0x51, 0xa8, 0x49, 0x5d, 0xc3, 0x6a, 0x17, 0xe5,
+       0x5a, 0x0a, 0x34, 0x1f, 0x56, 0x9b, 0x6d, 0x3d, 0xe6, 0xfd, 0x09, 0x47,
+       0x99, 0xf8, 0x60, 0xf1, 0xbb, 0xe4, 0xe2, 0x4b, 0xc4, 0xef, 0x86, 0xb9,
+       0xb6, 0x05, 0x3c, 0xb3, 0x45, 0x70, 0xdf, 0xeb, 0x41, 0xf5, 0xbd, 0xf4,
+       0x91, 0x0b, 0x15, 0x94, 0x2d, 0xf4, 0x47, 0x16, 0xd9, 0x9a, 0x81, 0xaa,
+       0x00, 0xf1, 0x47, 0x33, 0x7a, 0x12, 0x7f, 0xe0, 0x18, 0x1d, 0x30, 0x76,
+       0xe7, 0x63, 0xfd, 0xee, 0x12, 0xea, 0xaa, 0x47, 0xf2, 0xf0, 0x2e, 0x57,
+       0x53, 0x34, 0xe8, 0x8a, 0xd5, 0xeb, 0x4e, 0x65, 0x01, 0xfd, 0xb1, 0x9c,
+       0x9f, 0xcc, 0x7f, 0xd7, 0x0d, 0x7c, 0xa9, 0x9c, 0xfe, 0xed, 0x51, 0x73,
+       0x0d, 0x92, 0x2b, 0x96, 0x7e, 0x7f, 0x7c, 0x4e, 0x53, 0xd7, 0xce, 0xe9,
+       0x4e, 0x38, 0x1e, 0xa9, 0x20, 0xff, 0xba, 0xb5, 0x0f, 0xc9, 0xa3, 0x0f,
+       0xb9, 0x23, 0x66, 0x74, 0x6d, 0x0e, 0x16, 0x48, 0xfe, 0xc8, 0xf4, 0x21,
+       0xed, 0xb6, 0x8d, 0xa6, 0xee, 0x38, 0xb5, 0x1e, 0xca, 0xdb, 0xca, 0x47,
+       0x53, 0x06, 0x73, 0xac, 0xbb, 0xb9, 0xd9, 0xdf, 0x3a, 0xb0, 0x9d, 0x98,
+       0x29, 0x77, 0xea, 0x9d, 0x9a, 0x46, 0xfb, 0xef, 0x40, 0x0f, 0xc7, 0x7c,
+       0x85, 0xb8, 0xd9, 0x4f, 0xdc, 0xbc, 0xba, 0xf8, 0x8d, 0x9f, 0x55, 0xa3,
+       0x2e, 0xe9, 0xc6, 0xd4, 0x5f, 0x97, 0x09, 0x6e, 0x2e, 0xf2, 0x77, 0x5c,
+       0x31, 0x71, 0x53, 0xc6, 0x96, 0xf1, 0x66, 0x8f, 0xfd, 0x3f, 0xf8, 0xdf,
+       0xf9, 0x92, 0x73, 0x34, 0x9c, 0xda, 0xff, 0x35, 0xb6, 0x55, 0xc8, 0x5a,
+       0x6f, 0xb5, 0x0e, 0xc1, 0xda, 0xd9, 0x35, 0xfd, 0x69, 0x62, 0xae, 0x19,
+       0x2f, 0xd0, 0xe7, 0x86, 0xb1, 0x6a, 0x89, 0x8a, 0x4b, 0xd1, 0x69, 0xe4,
+       0x1d, 0xc8, 0xe2, 0x93, 0xb1, 0xec, 0x18, 0xb1, 0x69, 0x08, 0x82, 0x47,
+       0x4d, 0x3c, 0x97, 0x08, 0xed, 0xa4, 0x08, 0xe3, 0x49, 0xb9, 0x47, 0x64,
+       0x60, 0x57, 0xd0, 0x45, 0x6e, 0xdb, 0x7d, 0x34, 0xc7, 0xf4, 0x13, 0x45,
+       0x54, 0xad, 0x2c, 0xef, 0x16, 0xce, 0x2d, 0xf8, 0x23, 0xfc, 0xd8, 0x8e,
+       0x92, 0xc5, 0x92, 0x17, 0xf8, 0xc2, 0xb8, 0xf4, 0x98, 0xb4, 0x9b, 0x87,
+       0xa1, 0xdd, 0xa2, 0x7f, 0x3e, 0x54, 0x6b, 0x67, 0x19, 0x73, 0x80, 0x73,
+       0xda, 0x6e, 0xcf, 0x21, 0x37, 0xee, 0xd2, 0x97, 0xe0, 0x6a, 0x79, 0x0f,
+       0x0a, 0x9a, 0xdc, 0xf8, 0x30, 0x3a, 0x85, 0x43, 0xc4, 0x8f, 0x5c, 0xea,
+       0x50, 0x5e, 0x46, 0xcf, 0x76, 0x0c, 0xcb, 0xfe, 0xaa, 0xb1, 0xd2, 0xb4,
+       0x53, 0x19, 0x63, 0x1a, 0xaf, 0x92, 0xcf, 0x36, 0x2f, 0x11, 0x2e, 0xab,
+       0x63, 0x5f, 0xa2, 0x08, 0x35, 0x83, 0x5d, 0x94, 0x5d, 0x11, 0xaa, 0x87,
+       0xc5, 0xbe, 0xe6, 0x0b, 0x8e, 0xca, 0x05, 0x39, 0xca, 0x43, 0xc5, 0xf6,
+       0x68, 0xbd, 0x7a, 0x81, 0x41, 0x42, 0xf8, 0x9a, 0xaf, 0x77, 0xd3, 0xef,
+       0x30, 0x26, 0xca, 0xe8, 0x85, 0x4a, 0xbd, 0x68, 0xbb, 0xc6, 0xa3, 0xb3,
+       0x7b, 0x99, 0x9d, 0x3f, 0x52, 0xb1, 0x23, 0x6a, 0x62, 0x21, 0xfb, 0xfa,
+       0x02, 0x3e, 0x85, 0x58, 0x3e, 0x26, 0x3a, 0xf6, 0x7e, 0x46, 0xce, 0x79,
+       0xb7, 0x59, 0xf7, 0x5a, 0x36, 0xde, 0xf4, 0x5d, 0x6b, 0x7f, 0x13, 0x67,
+       0x8d, 0x5d, 0x8f, 0xc9, 0x1a, 0x8f, 0xe3, 0x60, 0xf2, 0x8a, 0xdc, 0x9b,
+       0xef, 0x38, 0x03, 0x1b, 0x4e, 0x33, 0x76, 0x19, 0x4b, 0xfd, 0xae, 0x5a,
+       0xde, 0x45, 0xd9, 0x97, 0x98, 0xed, 0x3b, 0xc4, 0x2e, 0x3d, 0x19, 0xbf,
+       0x61, 0xd9, 0x67, 0x69, 0x5c, 0xee, 0xaf, 0x1c, 0x09, 0x3e, 0xcd, 0x73,
+       0xf1, 0x2f, 0xaa, 0x37, 0x73, 0x32, 0xe4, 0xc2, 0x8c, 0x53, 0x04, 0x73,
+       0x23, 0xf4, 0xf9, 0x45, 0xf8, 0x79, 0x52, 0x7c, 0xb0, 0x81, 0x5c, 0xea,
+       0xe3, 0xb9, 0x8a, 0xee, 0xe7, 0x4b, 0x4d, 0x6e, 0x5d, 0x84, 0x32, 0xee,
+       0x73, 0x60, 0xf8, 0x56, 0xba, 0x7e, 0xdd, 0x4f, 0xa4, 0x83, 0x0a, 0x71,
+       0xe3, 0x5f, 0xb9, 0x4e, 0xab, 0xcf, 0x99, 0xa4, 0x0b, 0x9f, 0x06, 0xdb,
+       0x31, 0x55, 0x1a, 0xc6, 0x60, 0x22, 0x0f, 0xed, 0x55, 0x75, 0xe6, 0xbb,
+       0x1d, 0xd5, 0x71, 0x0f, 0xce, 0x46, 0x9d, 0x68, 0x9c, 0xe3, 0x31, 0x73,
+       0x83, 0x36, 0x62, 0xfd, 0x07, 0xd1, 0xb0, 0x69, 0x83, 0xb3, 0x7d, 0x48,
+       0x8e, 0xb6, 0x18, 0x2d, 0x19, 0x9c, 0xdf, 0x9f, 0xf8, 0x82, 0x38, 0x54,
+       0x1c, 0x29, 0x6f, 0x2a, 0xc2, 0x1d, 0x83, 0x72, 0xc7, 0x41, 0xee, 0x64,
+       0x68, 0x33, 0x77, 0x2a, 0x45, 0x58, 0x36, 0x2c, 0x98, 0x2f, 0xb6, 0x9b,
+       0xa6, 0xed, 0xae, 0xe5, 0xb9, 0x75, 0x42, 0xde, 0xd9, 0x78, 0x85, 0xb2,
+       0xb7, 0x2b, 0x46, 0xd7, 0x45, 0x3d, 0x2c, 0xf7, 0x3c, 0x3b, 0x5b, 0x68,
+       0x07, 0x33, 0x41, 0x6f, 0x7b, 0xb9, 0x5d, 0xeb, 0xf8, 0x95, 0xd2, 0x80,
+       0xf1, 0x31, 0xa0, 0x7f, 0x34, 0x80, 0x8f, 0x12, 0x12, 0x03, 0x04, 0xf0,
+       0x1b, 0x72, 0xa3, 0x0b, 0x89, 0x06, 0xfa, 0x0b, 0x6f, 0xf8, 0x39, 0x34,
+       0xe0, 0x43, 0x7e, 0xcf, 0x8d, 0xeb, 0xb8, 0x4c, 0xf9, 0x39, 0xe3, 0x21,
+       0x5c, 0x9c, 0xb8, 0x17, 0x97, 0xf6, 0x2a, 0x78, 0x43, 0xbb, 0x17, 0xe7,
+       0x0f, 0x75, 0x62, 0xf1, 0x5e, 0x79, 0xef, 0xef, 0x48, 0x50, 0xa5, 0xaf,
+       0x78, 0xba, 0xd6, 0xe8, 0x7a, 0x51, 0xaf, 0x83, 0x5e, 0xe6, 0xd5, 0xdb,
+       0x89, 0x09, 0x82, 0xf1, 0x61, 0x9b, 0x9c, 0xa1, 0x9c, 0x65, 0x27, 0x2e,
+       0x99, 0xb8, 0x7e, 0x6b, 0xac, 0xb8, 0x8e, 0xe9, 0x32, 0x8f, 0xe0, 0xcb,
+       0x7c, 0xfc, 0x48, 0x0d, 0x70, 0x1f, 0x6e, 0x72, 0xb1, 0x29, 0xfa, 0xc7,
+       0x3c, 0xe4, 0x56, 0x4a, 0xcd, 0x5a, 0x43, 0x3e, 0x71, 0xe4, 0x14, 0x65,
+       0xb7, 0xaa, 0xd2, 0x6b, 0xc6, 0x3a, 0xb9, 0xf1, 0x06, 0xc6, 0x31, 0xe5,
+       0xf8, 0xe8, 0x06, 0xff, 0xfb, 0x23, 0xe3, 0x51, 0x13, 0xaf, 0x13, 0xb7,
+       0x09, 0x1f, 0x7b, 0x3d, 0xf1, 0xf8, 0x6d, 0x82, 0xdb, 0x92, 0x5f, 0x2c,
+       0xd6, 0xb4, 0x4d, 0xdf, 0x81, 0xbc, 0xff, 0xf6, 0xc6, 0x7f, 0x2b, 0x24,
+       0x4f, 0x7e, 0x31, 0x58, 0x17, 0x29, 0x45, 0x1f, 0x9f, 0x4f, 0x2d, 0x56,
+       0x71, 0x90, 0x9f, 0x7e, 0xb6, 0x6b, 0xe0, 0x3a, 0x3e, 0x36, 0x52, 0xaa,
+       0xcf, 0xf4, 0x25, 0x71, 0xfa, 0xd3, 0xd3, 0xb1, 0xfa, 0xf6, 0x51, 0xe5,
+       0xb2, 0x11, 0xa9, 0xac, 0xe5, 0x6f, 0x15, 0x38, 0x13, 0xf5, 0x4e, 0x1d,
+       0x42, 0xbd, 0x67, 0x46, 0xd9, 0x6f, 0x44, 0x54, 0x39, 0x1f, 0xd9, 0xaf,
+       0xf4, 0x5f, 0xc0, 0xe7, 0xe7, 0x66, 0xe9, 0xe1, 0xf5, 0x38, 0xcc, 0x79,
+       0x4d, 0xff, 0x84, 0xa7, 0x18, 0xcb, 0x46, 0xf4, 0x7a, 0xb5, 0x87, 0xd8,
+       0x10, 0x56, 0x6f, 0xa5, 0x7f, 0x79, 0xd4, 0xbf, 0x30, 0xe3, 0xca, 0x22,
+       0xa8, 0xd6, 0x7b, 0x3d, 0x48, 0x0e, 0xcf, 0xe6, 0x9a, 0xa2, 0x77, 0x16,
+       0x6f, 0x6d, 0x2f, 0xed, 0x3e, 0xea, 0x24, 0x36, 0x25, 0x88, 0xeb, 0x71,
+       0xe2, 0x7a, 0x2e, 0x71, 0xfd, 0xe3, 0x3d, 0xf9, 0x38, 0xbd, 0xa7, 0x11,
+       0xe9, 0x52, 0xe9, 0x63, 0x87, 0x93, 0xbb, 0x4b, 0x65, 0xee, 0x39, 0x54,
+       0x0f, 0xdc, 0x27, 0x77, 0x1e, 0x21, 0x7e, 0x36, 0x27, 0xce, 0xb8, 0xab,
+       0xcd, 0x0e, 0x87, 0xf9, 0x4e, 0x43, 0xc9, 0x0d, 0xfa, 0xe7, 0xd2, 0x72,
+       0xd1, 0x4a, 0x39, 0xe6, 0x6a, 0xbe, 0xb9, 0xd6, 0xdd, 0xbe, 0x22, 0xc6,
+       0x91, 0x72, 0x5f, 0x71, 0xa9, 0xd4, 0x03, 0xd9, 0x5e, 0xfa, 0x49, 0xac,
+       0x63, 0x60, 0x07, 0x35, 0xac, 0xae, 0xd2, 0x40, 0x42, 0x0f, 0xd3, 0x87,
+       0x05, 0x11, 0x26, 0xa7, 0x2f, 0xd4, 0xe4, 0xbb, 0x8a, 0x8b, 0x8c, 0xd3,
+       0xc6, 0x1a, 0x14, 0x7c, 0x7a, 0x97, 0x70, 0x03, 0xbf, 0x7e, 0x5a, 0xc1,
+       0x1c, 0xeb, 0x5d, 0x0a, 0xc1, 0x8c, 0x62, 0x13, 0x33, 0x72, 0x4d, 0x9e,
+       0x34, 0xc7, 0xc4, 0x1b, 0x79, 0x57, 0xac, 0x9a, 0x7e, 0xe8, 0x9e, 0x44,
+       0xfd, 0x94, 0xcf, 0x4e, 0xce, 0xf6, 0xf8, 0x5d, 0xe4, 0x6a, 0x26, 0x67,
+       0x20, 0xfe, 0xbf, 0x9f, 0xe1, 0x15, 0xde, 0xc6, 0x9b, 0xef, 0x90, 0x9e,
+       0xbb, 0x16, 0xa7, 0x5b, 0x7b, 0xe8, 0x1f, 0xfe, 0x9d, 0xd1, 0x76, 0xc3,
+       0xfa, 0xb3, 0xb8, 0xb2, 0x80, 0xdf, 0xa5, 0xbf, 0xd8, 0x1d, 0xf5, 0x22,
+       0xfe, 0x33, 0xe3, 0x29, 0x93, 0xdf, 0xd9, 0xe7, 0xca, 0x1d, 0x51, 0xc7,
+       0xc0, 0x17, 0xb7, 0xc9, 0xfb, 0x13, 0xb6, 0x59, 0x3c, 0xc1, 0xf2, 0xbd,
+       0x17, 0x8c, 0xd5, 0xe6, 0x5a, 0xf3, 0x33, 0xed, 0x24, 0xa6, 0x96, 0xb5,
+       0x28, 0xf8, 0x81, 0x56, 0xaf, 0x9e, 0x42, 0xa1, 0xe0, 0x49, 0x58, 0x6a,
+       0x9f, 0xf9, 0x9a, 0xcf, 0x7d, 0x90, 0x9f, 0xbb, 0xf8, 0xfc, 0xb8, 0xe6,
+       0x68, 0xdc, 0x0c, 0xa9, 0xf7, 0xda, 0x78, 0x56, 0xf5, 0xee, 0x53, 0xf0,
+       0x87, 0x73, 0x95, 0x19, 0xa3, 0xbd, 0x42, 0xda, 0x58, 0x75, 0x5f, 0x28,
+       0x67, 0xcd, 0x7c, 0x8a, 0xa5, 0x33, 0xf3, 0xa8, 0x33, 0x82, 0x5d, 0xc2,
+       0x4d, 0x16, 0x72, 0xef, 0x2a, 0x86, 0x27, 0x80, 0x9c, 0x01, 0x97, 0xc9,
+       0x95, 0xd4, 0xda, 0x5a, 0xcf, 0xb3, 0x58, 0x3e, 0x57, 0xde, 0x01, 0xdb,
+       0xaa, 0xe3, 0x76, 0x1b, 0xde, 0xbb, 0xdd, 0xd6, 0x74, 0xdf, 0x77, 0x5b,
+       0x42, 0x9b, 0x65, 0x5f, 0x44, 0x67, 0x33, 0xb7, 0xeb, 0x96, 0x1a, 0xe5,
+       0x4a, 0xfa, 0xb4, 0x21, 0xc6, 0xfc, 0x2b, 0x1b, 0xfe, 0xdd, 0xf8, 0x96,
+       0x23, 0xec, 0xb1, 0xa3, 0xd6, 0xd3, 0x8b, 0xab, 0x46, 0xaa, 0x42, 0x9e,
+       0xcb, 0x18, 0xf2, 0xae, 0xa7, 0xd4, 0x59, 0x0c, 0xe3, 0x8e, 0x5a, 0x83,
+       0xf1, 0xb4, 0x6d, 0xb9, 0x9d, 0x76, 0x91, 0xab, 0x9d, 0x37, 0xea, 0xaa,
+       0x6a, 0xdd, 0x36, 0xa5, 0x8e, 0xda, 0x51, 0x81, 0x57, 0xa9, 0xbf, 0xaf,
+       0x4e, 0x88, 0x0f, 0x54, 0x71, 0x98, 0x76, 0x7a, 0xa8, 0xce, 0xd7, 0x79,
+       0x89, 0xb1, 0xe5, 0x27, 0xe4, 0xfc, 0x6f, 0x6b, 0xde, 0xf6, 0x93, 0x92,
+       0x93, 0x0c, 0x3a, 0xf0, 0x66, 0xc3, 0x55, 0x33, 0x4f, 0x1c, 0x3b, 0xa0,
+       0x62, 0x28, 0x61, 0xd9, 0xfb, 0x6b, 0xb4, 0xe3, 0xeb, 0x77, 0x1e, 0x42,
+       0xe8, 0x19, 0x14, 0xfb, 0x08, 0x99, 0x76, 0x74, 0x3d, 0x77, 0x24, 0x78,
+       0x2d, 0x76, 0xb1, 0x5e, 0x6a, 0x7e, 0x91, 0x14, 0xc8, 0x6d, 0x06, 0x56,
+       0x92, 0x13, 0x8b, 0xcf, 0x6d, 0x60, 0xfc, 0xeb, 0xa0, 0xfd, 0x9c, 0x64,
+       0x2c, 0xc2, 0xb5, 0x35, 0x19, 0xc6, 0x05, 0xc6, 0x66, 0xc3, 0xa8, 0x57,
+       0x8f, 0x61, 0x0d, 0x79, 0x2d, 0x39, 0xcf, 0x44, 0x0b, 0x76, 0x9a, 0xb1,
+       0x95, 0x4f, 0xbd, 0x5f, 0x59, 0xc4, 0xfd, 0xb7, 0xa0, 0xfb, 0x90, 0x87,
+       0x3e, 0xc1, 0x30, 0x1e, 0xd0, 0xff, 0x12, 0x65, 0x83, 0xdd, 0x9d, 0x65,
+       0x94, 0xc7, 0xe7, 0xc1, 0x48, 0x07, 0x31, 0x7d, 0xd3, 0x31, 0x45, 0xee,
+       0xa5, 0x7e, 0x8b, 0xe7, 0x11, 0x30, 0xf9, 0xf6, 0x8e, 0xc4, 0x03, 0xf4,
+       0x71, 0xff, 0x1d, 0x3b, 0x54, 0x65, 0x19, 0xdd, 0x1d, 0x39, 0x23, 0xfc,
+       0x6a, 0x93, 0x76, 0xf2, 0xbc, 0xfd, 0xfb, 0xd0, 0xe7, 0x34, 0xf2, 0x99,
+       0xf8, 0x79, 0x69, 0x0b, 0x5c, 0x88, 0x76, 0xe2, 0x68, 0x9a, 0x7a, 0x1d,
+       0xed, 0xc3, 0xb1, 0xb4, 0xcc, 0x29, 0x9c, 0xab, 0x01, 0xb1, 0x41, 0x3b,
+       0xc6, 0x75, 0x5f, 0xb8, 0x98, 0x72, 0xc9, 0x0f, 0x7a, 0xc3, 0x6b, 0x88,
+       0xb1, 0x7d, 0xc3, 0x69, 0xbc, 0xb9, 0xdb, 0xdb, 0x5e, 0xa7, 0x68, 0x88,
+       0x4e, 0x40, 0x7d, 0x6e, 0x49, 0x1a, 0xa7, 0x46, 0x1e, 0x86, 0xa7, 0xca,
+       0xeb, 0x59, 0xa9, 0xb4, 0x62, 0xeb, 0xc4, 0xd7, 0xe5, 0x9c, 0x34, 0xce,
+       0xdd, 0x8a, 0x08, 0x65, 0xbf, 0x1d, 0xff, 0x38, 0x57, 0x70, 0xac, 0x77,
+       0xa2, 0x10, 0x35, 0xf4, 0x47, 0xaf, 0x98, 0x7e, 0xd7, 0xb2, 0xa3, 0x6a,
+       0xed, 0x53, 0xe3, 0x89, 0x8c, 0x5f, 0xff, 0xf3, 0xf2, 0xfa, 0xb1, 0x11,
+       0x56, 0x45, 0x5e, 0xd2, 0xaf, 0x9a, 0xdc, 0x40, 0x78, 0x81, 0xe5, 0xbf,
+       0x4b, 0xb5, 0xf7, 0x8d, 0x87, 0xcd, 0x31, 0x46, 0x39, 0x8f, 0xec, 0x29,
+       0x90, 0xd9, 0xb7, 0x8e, 0xdf, 0x46, 0x25, 0xf7, 0xa1, 0xe2, 0x98, 0x2e,
+       0x38, 0xd2, 0x4a, 0x5b, 0x75, 0x62, 0x53, 0x03, 0xcd, 0xd1, 0xac, 0x09,
+       0x4c, 0x63, 0x67, 0xf2, 0xf7, 0xc6, 0xf3, 0xd4, 0xa3, 0x55, 0xe4, 0x34,
+       0x1e, 0xe2, 0xc0, 0x33, 0xc1, 0x07, 0xc8, 0x4b, 0xb9, 0xe7, 0x84, 0x83,
+       0x18, 0xa4, 0x20, 0xd1, 0x48, 0xfb, 0x0f, 0x2e, 0xc4, 0x94, 0xd9, 0xfe,
+       0xb1, 0xb9, 0x56, 0xae, 0xb1, 0x61, 0x9e, 0x15, 0x2b, 0x8a, 0xfc, 0xff,
+       0x23, 0xf2, 0x7b, 0xcd, 0xf0, 0x94, 0x89, 0xfc, 0x1c, 0x70, 0xfb, 0x1b,
+       0xb0, 0x8f, 0x6d, 0xce, 0xec, 0x76, 0x60, 0x40, 0x6b, 0xc5, 0xc0, 0x04,
+       0x3c, 0x9f, 0xb3, 0xcd, 0xbb, 0x23, 0xbf, 0x98, 0x6b, 0x71, 0x87, 0xf7,
+       0xd0, 0x1d, 0x7d, 0xc1, 0x58, 0x5e, 0x26, 0xfb, 0x95, 0x7b, 0x3e, 0x6d,
+       0x6c, 0x9f, 0xcd, 0xfb, 0x3d, 0x6b, 0x3c, 0x62, 0xfa, 0x89, 0x7f, 0x9a,
+       0x2b, 0x75, 0xb9, 0xd7, 0x13, 0x06, 0x2e, 0xea, 0xe7, 0xe4, 0xfd, 0x49,
+       0x93, 0xeb, 0xf5, 0x26, 0xe4, 0x6c, 0x65, 0x6d, 0xc7, 0x32, 0xf2, 0x28,
+       0xa8, 0xba, 0x71, 0xdd, 0x67, 0x33, 0x39, 0x50, 0xe1, 0x10, 0x22, 0xab,
+       0x2c, 0xd7, 0xf0, 0x64, 0xf2, 0x6e, 0xc7, 0xd1, 0x93, 0x94, 0x9a, 0xb9,
+       0xbc, 0x9f, 0x5d, 0x82, 0x17, 0xf5, 0x87, 0xb0, 0xa0, 0xec, 0x0f, 0x9c,
+       0x4f, 0x72, 0x30, 0xad, 0x1c, 0xcf, 0x30, 0x36, 0xea, 0xf5, 0xfa, 0x45,
+       0x7c, 0x13, 0x53, 0x15, 0x21, 0xb3, 0x86, 0x91, 0xd7, 0xe4, 0x51, 0xb4,
+       0x3d, 0x6b, 0xe0, 0x2c, 0xd5, 0x88, 0xfd, 0xa2, 0x93, 0x82, 0x31, 0xb2,
+       0x26, 0xc1, 0x19, 0xc9, 0xf1, 0x4b, 0x4e, 0x3c, 0x12, 0xae, 0x69, 0xea,
+       0x54, 0x1e, 0x64, 0xcc, 0xff, 0x4e, 0x50, 0xde, 0x21, 0xf4, 0xb7, 0xd7,
+       0xd8, 0x90, 0x37, 0x19, 0xca, 0xc5, 0x2f, 0x83, 0x72, 0x9f, 0x1b, 0xae,
+       0xb1, 0xb4, 0x37, 0xd2, 0x68, 0x57, 0x5d, 0x69, 0xb3, 0x56, 0x29, 0xb8,
+       0x9b, 0xa0, 0xcc, 0x89, 0x2d, 0x26, 0xa6, 0xdc, 0x85, 0x15, 0xe6, 0x39,
+       0xab, 0xf4, 0xa7, 0xc2, 0x1b, 0x8e, 0x90, 0x37, 0x00, 0xb9, 0x03, 0xc6,
+       0xb2, 0xe6, 0x60, 0xbd, 0xde, 0x87, 0xdb, 0xc9, 0xfd, 0x97, 0xe1, 0x23,
+       0x5d, 0xea, 0x24, 0x91, 0x6f, 0x39, 0xcc, 0xfb, 0x38, 0x87, 0x83, 0x5b,
+       0xa3, 0x2b, 0xb1, 0x7f, 0x30, 0xa2, 0x38, 0x9b, 0xbc, 0xad, 0x31, 0xf2,
+       0x22, 0x42, 0xba, 0x99, 0x23, 0xdc, 0x41, 0xfe, 0x70, 0x38, 0xd4, 0x89,
+       0xed, 0x7a, 0x2e, 0x7a, 0xf5, 0x70, 0x5e, 0xcf, 0x92, 0x2e, 0xbc, 0xa2,
+       0x17, 0x4a, 0x1e, 0x9e, 0xf8, 0xae, 0x6d, 0x4a, 0xc2, 0xdf, 0xf1, 0x21,
+       0xbc, 0x53, 0x47, 0xc9, 0x41, 0xce, 0xdb, 0x15, 0xf8, 0x97, 0x3a, 0x5c,
+       0xb1, 0xb1, 0x26, 0xec, 0x9b, 0xa8, 0x70, 0xc5, 0xc7, 0x18, 0x0f, 0x4e,
+       0x30, 0x86, 0x61, 0x1c, 0xac, 0x8d, 0xad, 0xc4, 0xb6, 0x61, 0xb9, 0xe3,
+       0x1b, 0xc0, 0xdd, 0x65, 0xe7, 0x8c, 0xa7, 0xfd, 0x82, 0xa3, 0xf3, 0x71,
+       0x67, 0x99, 0xcf, 0xf4, 0x81, 0xed, 0xb6, 0xaf, 0xe3, 0x0f, 0x76, 0x6c,
+       0x0e, 0xfe, 0xc8, 0x08, 0x3f, 0x26, 0x72, 0x7b, 0x9e, 0x67, 0xf4, 0x00,
+       0xb1, 0xd4, 0x92, 0xe1, 0x86, 0x6b, 0x32, 0x0c, 0xa1, 0x7b, 0x30, 0x44,
+       0xfb, 0x71, 0x93, 0x6f, 0x5d, 0x3f, 0x87, 0xf5, 0xba, 0x6f, 0x66, 0x08,
+       0xad, 0x78, 0x65, 0xe2, 0x6f, 0xd8, 0x4f, 0xf2, 0x33, 0x4b, 0xd1, 0x91,
+       0x89, 0x47, 0xc2, 0xb6, 0x02, 0xf2, 0x3f, 0xcb, 0x0f, 0x0c, 0x0c, 0xcb,
+       0x73, 0xef, 0xbe, 0x30, 0xb9, 0xcc, 0x8b, 0x0d, 0x33, 0xd4, 0xc3, 0x48,
+       0xa7, 0xdd, 0x7c, 0x2f, 0xe2, 0xca, 0xf7, 0xdc, 0x75, 0xde, 0x75, 0x33,
+       0x0a, 0xf0, 0x17, 0x31, 0xfa, 0x64, 0x9b, 0xf4, 0x95, 0xb1, 0x9d, 0x38,
+       0xd8, 0x30, 0x1f, 0x53, 0x6b, 0x65, 0x4c, 0x99, 0xcf, 0x30, 0x9e, 0xa3,
+       0x8e, 0xff, 0x00, 0x4e, 0xe4, 0xde, 0x65, 0xc7, 0x39, 0x95, 0xb6, 0xa2,
+       0xff, 0xde, 0x48, 0xd3, 0x57, 0x6e, 0xcd, 0xd8, 0xcc, 0x36, 0xda, 0xcc,
+       0x28, 0x6d, 0xa6, 0x9f, 0x36, 0x73, 0xf7, 0xa2, 0x3b, 0x32, 0x36, 0x23,
+       0xb1, 0xe1, 0x34, 0x1e, 0xe9, 0x57, 0xd1, 0xf6, 0x9f, 0xa6, 0xd1, 0x76,
+       0x20, 0xbb, 0x76, 0xd1, 0xbb, 0xec, 0xfa, 0xa5, 0xde, 0x28, 0xf3, 0xc8,
+       0x1a, 0x65, 0x2f, 0xd9, 0xdf, 0xaf, 0x7f, 0xaf, 0xd6, 0x9c, 0x78, 0xc2,
+       0xdc, 0xd7, 0xdf, 0x57, 0x5b, 0x75, 0xfa, 0xec, 0x7e, 0xc2, 0x37, 0x7d,
+       0xaf, 0xbd, 0xed, 0xc6, 0xef, 0x7b, 0xdd, 0x37, 0x7e, 0x3f, 0x79, 0xd3,
+       0xf3, 0xac, 0x6d, 0x5c, 0x97, 0x69, 0xa7, 0xee, 0xeb, 0x9c, 0xe4, 0x3e,
+       0x3f, 0xba, 0xeb, 0xb0, 0xd1, 0xfe, 0xb0, 0xac, 0x25, 0x40, 0x9e, 0x24,
+       0xeb, 0x7b, 0x0f, 0x0b, 0xfe, 0x68, 0x6d, 0xef, 0x64, 0x6c, 0xc9, 0x7c,
+       0x37, 0xc8, 0xd4, 0xab, 0xd7, 0x27, 0x34, 0xfc, 0xf8, 0x86, 0xfb, 0x8b,
+       0x01, 0x65, 0x47, 0x4c, 0x74, 0xca, 0x11, 0x71, 0x35, 0x41, 0xb9, 0xd3,
+       0x1f, 0xc1, 0x42, 0x7f, 0x17, 0x3e, 0xa2, 0xce, 0xb7, 0x29, 0x1a, 0xe3,
+       0xbb, 0x24, 0xe2, 0x63, 0x5e, 0x7d, 0x13, 0xb1, 0x22, 0x36, 0xf6, 0x97,
+       0x38, 0x91, 0xcc, 0xa7, 0x0e, 0x76, 0x61, 0x65, 0xd0, 0x1b, 0x18, 0xa2,
+       0xef, 0xbd, 0xa0, 0x8b, 0x9d, 0x4a, 0xed, 0xd7, 0x43, 0x0c, 0x0d, 0x08,
+       0x06, 0xaa, 0x29, 0xf1, 0xc9, 0xb4, 0x3d, 0xe1, 0xd8, 0x0e, 0xea, 0xc6,
+       0xd6, 0xe1, 0xb7, 0xd0, 0x12, 0x95, 0x7c, 0xeb, 0x71, 0x3c, 0x9a, 0xa4,
+       0x0f, 0xd2, 0x68, 0xb7, 0x8b, 0x1c, 0xd0, 0xca, 0x24, 0x27, 0xec, 0xc0,
+       0xda, 0xf8, 0x7c, 0x44, 0xaa, 0xa4, 0xae, 0xb2, 0x12, 0xdb, 0x07, 0x15,
+       0xfc, 0x56, 0x6a, 0x98, 0x8c, 0xc1, 0x5f, 0x27, 0x47, 0x9c, 0x8c, 0x6e,
+       0xc1, 0x88, 0x59, 0xa3, 0xd6, 0xfa, 0xaa, 0xed, 0xe1, 0x17, 0x4b, 0xc9,
+       0xb7, 0x13, 0xba, 0xbf, 0x9d, 0xf6, 0xe8, 0x29, 0x6a, 0xf2, 0x87, 0x63,
+       0xca, 0x57, 0xf8, 0x37, 0xf3, 0xae, 0x8d, 0xee, 0xda, 0x44, 0x5d, 0xdf,
+       0x33, 0x2c, 0xfd, 0xb8, 0xc7, 0x5b, 0xe6, 0x3a, 0xac, 0x77, 0xdd, 0xad,
+       0xbc, 0xe4, 0x5b, 0x38, 0x98, 0x76, 0xe1, 0xa9, 0xb8, 0x47, 0xb1, 0xef,
+       0x51, 0xd1, 0x12, 0xf7, 0x9e, 0xbc, 0x60, 0x37, 0x8c, 0xba, 0xc5, 0x25,
+       0x98, 0x21, 0xbf, 0xa8, 0x5c, 0x2c, 0x3e, 0xe1, 0x3f, 0x23, 0x55, 0xd5,
+       0x4c, 0x6c, 0x43, 0xa1, 0x6d, 0x89, 0x57, 0xb7, 0xd9, 0x7d, 0xad, 0x33,
+       0xd8, 0x8a, 0xbc, 0xb1, 0x07, 0xcc, 0x75, 0x7f, 0x23, 0x2e, 0xef, 0x2f,
+       0xd5, 0x53, 0xdf, 0xe8, 0x27, 0x0f, 0x89, 0x0c, 0x11, 0xa9, 0x6c, 0x82,
+       0xa7, 0xa2, 0x69, 0xd7, 0x7c, 0xe4, 0x7f, 0x45, 0xce, 0x3d, 0x8d, 0x89,
+       0xa4, 0xd6, 0x51, 0x62, 0x33, 0x70, 0x3a, 0x78, 0x27, 0x52, 0x66, 0x0d,
+       0x63, 0x25, 0xfa, 0x07, 0x25, 0x3f, 0xaf, 0x40, 0x5b, 0x54, 0x40, 0xce,
+       0xa7, 0x05, 0x5e, 0xb4, 0x49, 0xcd, 0x79, 0x0b, 0xbe, 0xc1, 0xbd, 0xde,
+       0x1f, 0x15, 0x7b, 0xd5, 0xdc, 0x6d, 0x4a, 0xf8, 0xaa, 0x9d, 0x7b, 0xfd,
+       0xb5, 0xee, 0x3f, 0xf9, 0x6b, 0xbb, 0x7f, 0x2a, 0x64, 0xd7, 0x5d, 0x93,
+       0xe3, 0x2a, 0x31, 0xc4, 0x8a, 0x31, 0xd3, 0xe4, 0xb4, 0x85, 0x1c, 0xb7,
+       0x20, 0x78, 0x89, 0xdc, 0x40, 0xc6, 0x5d, 0x3e, 0x0f, 0xc5, 0x2d, 0xe8,
+       0xdf, 0xfb, 0xa1, 0x11, 0x6e, 0x93, 0x39, 0xfe, 0xc0, 0xb8, 0xd4, 0x89,
+       0x95, 0x6b, 0x3d, 0x58, 0x11, 0x97, 0x9c, 0xea, 0x8f, 0x2b, 0x2d, 0xdd,
+       0x92, 0xef, 0x0e, 0x74, 0xe8, 0x04, 0xdb, 0xaa, 0x2f, 0x8d, 0x0a, 0x33,
+       0x66, 0xbd, 0x6f, 0xbe, 0xe8, 0x4b, 0x6f, 0xe2, 0x85, 0xf9, 0x62, 0xdf,
+       0xbd, 0x13, 0x4f, 0xbb, 0x2d, 0xbd, 0x7b, 0x99, 0xdf, 0x65, 0x2c, 0x6d,
+       0xdf, 0x16, 0x9c, 0xa9, 0x14, 0x5e, 0xf3, 0xe8, 0xf8, 0xec, 0xf6, 0x56,
+       0xbd, 0xea, 0xf5, 0x6b, 0xb9, 0x1a, 0xa9, 0x13, 0x86, 0x95, 0xb6, 0x68,
+       0xab, 0xb2, 0x3a, 0x2a, 0xb5, 0x42, 0x5b, 0xa8, 0x80, 0x1c, 0xe6, 0x98,
+       0x2e, 0xef, 0xea, 0x65, 0xeb, 0x86, 0x11, 0xa5, 0x2f, 0x44, 0xc6, 0x33,
+       0xd6, 0xac, 0xec, 0x88, 0x96, 0xc9, 0x5d, 0x07, 0xea, 0xa5, 0x83, 0x32,
+       0x75, 0x21, 0x67, 0x54, 0x62, 0xf2, 0x02, 0xe4, 0x1c, 0xd0, 0x90, 0x3b,
+       0xd6, 0x8e, 0x11, 0x32, 0xb8, 0x92, 0xda, 0x72, 0x1c, 0x0a, 0xc8, 0x5d,
+       0x8e, 0x0a, 0x14, 0x09, 0xb6, 0x6a, 0x3d, 0x78, 0xb5, 0x0d, 0x4a, 0x41,
+       0xed, 0x6c, 0x9e, 0x6a, 0xde, 0x5f, 0x57, 0xdd, 0x4d, 0xe2, 0xdb, 0x25,
+       0xc7, 0x6f, 0xd5, 0x1d, 0xcf, 0xa6, 0x37, 0x60, 0x4c, 0xe5, 0xb2, 0xb5,
+       0x7f, 0x33, 0xc6, 0x2b, 0xcc, 0x77, 0x7e, 0xc8, 0x81, 0x0f, 0x93, 0x03,
+       0x1b, 0xcb, 0xba, 0x82, 0x91, 0x9f, 0xd5, 0xc0, 0xdb, 0xa7, 0xdb, 0xbd,
+       0x9e, 0x46, 0x9b, 0xe4, 0x10, 0xa0, 0xe4, 0xd4, 0x46, 0x90, 0x5b, 0x5b,
+       0x18, 0xb1, 0x53, 0xbf, 0xcf, 0xe8, 0x22, 0xfb, 0x2e, 0xec, 0xd4, 0xf3,
+       0xe5, 0x7d, 0xf9, 0x48, 0x31, 0x79, 0x4b, 0x0c, 0x9a, 0x7a, 0x1a, 0xda,
+       0xcc, 0x27, 0xec, 0xb7, 0x82, 0xf6, 0xd0, 0x3d, 0xe6, 0x0d, 0x5f, 0x54,
+       0xbc, 0x53, 0x77, 0xd3, 0x46, 0x5e, 0x19, 0xa3, 0x1d, 0x12, 0x77, 0xfb,
+       0x69, 0x03, 0x7d, 0xb4, 0x85, 0x7d, 0x13, 0x87, 0x84, 0x47, 0xf4, 0xb5,
+       0x2b, 0xd6, 0x3d, 0x4c, 0xab, 0xde, 0x2e, 0x35, 0xb5, 0x88, 0xb2, 0x21,
+       0x24, 0x7e, 0xb0, 0x08, 0xe7, 0x93, 0xc0, 0x91, 0x74, 0x0e, 0x5e, 0x1b,
+       0x41, 0x8b, 0x0d, 0xf6, 0x5e, 0x17, 0xea, 0xd6, 0xa9, 0x78, 0xa3, 0xae,
+       0x40, 0xfe, 0x87, 0x11, 0x15, 0x9d, 0x8c, 0x09, 0xcb, 0xb0, 0x62, 0xb7,
+       0xb1, 0xec, 0xae, 0x45, 0xc6, 0xb2, 0xcd, 0xfa, 0x63, 0x58, 0x63, 0x62,
+       0x4c, 0x77, 0x7b, 0x01, 0xe3, 0xdb, 0x1f, 0x8e, 0x38, 0x91, 0x4a, 0xb1,
+       0x17, 0xe5, 0x35, 0x9c, 0xc2, 0x03, 0x0e, 0x62, 0x27, 0xfd, 0x58, 0x5d,
+       0x71, 0x93, 0xbf, 0xed, 0x6e, 0x85, 0xbc, 0x32, 0x5d, 0x81, 0x54, 0x5a,
+       0xe3, 0x5f, 0x80, 0x7f, 0x0d, 0xfc, 0x6b, 0xc4, 0x9a, 0xa8, 0xe8, 0xa8,
+       0x1b, 0x63, 0xe9, 0x22, 0x7c, 0x98, 0xd4, 0x02, 0x2e, 0xea, 0xcf, 0x88,
+       0x3e, 0x6e, 0x44, 0xda, 0xac, 0x38, 0xe4, 0xf3, 0xa4, 0xe4, 0x74, 0x8a,
+       0xf0, 0x59, 0xea, 0xf4, 0x7c, 0x8b, 0xdb, 0x77, 0xe1, 0x62, 0x30, 0x3f,
+       0x52, 0x6a, 0xfa, 0x1c, 0x6f, 0xe0, 0x35, 0x68, 0xeb, 0xae, 0x70, 0xdf,
+       0xbb, 0xc6, 0x52, 0xc6, 0xb9, 0x0a, 0xb1, 0xf5, 0xe3, 0xf8, 0x49, 0xf2,
+       0x8a, 0x51, 0x23, 0x9c, 0x33, 0x21, 0xf7, 0xf5, 0xad, 0x3c, 0x8b, 0xc4,
+       0x46, 0x85, 0x4b, 0x67, 0x9f, 0xc9, 0x71, 0xa4, 0x53, 0xb3, 0xcf, 0x05,
+       0xed, 0x8e, 0x26, 0x57, 0xc3, 0x8e, 0xa8, 0xfd, 0x4a, 0x3e, 0x79, 0xd4,
+       0xfd, 0x4b, 0x34, 0xbd, 0x4e, 0x71, 0x35, 0xf4, 0xa6, 0x5d, 0x0d, 0x7d,
+       0xd1, 0xd9, 0xe7, 0x7a, 0x44, 0xb1, 0x37, 0xc9, 0x38, 0x7e, 0xc6, 0xdc,
+       0xd9, 0xb1, 0x5c, 0x0d, 0xdd, 0xe9, 0xd9, 0x63, 0x75, 0xa1, 0x23, 0x28,
+       0x67, 0xe4, 0xdd, 0xe4, 0xbc, 0xa1, 0x6e, 0x20, 0x3e, 0xdc, 0x7c, 0xcf,
+       0xa5, 0xe3, 0xbb, 0xd7, 0xfa, 0x6a, 0xc4, 0x32, 0xfa, 0xc5, 0x89, 0xd9,
+       0xfd, 0xa7, 0xf1, 0x6e, 0xd2, 0xfc, 0x7f, 0x06, 0x74, 0x7c, 0xce, 0x18,
+       0xf1, 0x54, 0xf0, 0xb0, 0xe1, 0x29, 0x15, 0x19, 0x1f, 0xc7, 0x07, 0xdc,
+       0x5b, 0xa1, 0xb6, 0xb5, 0xdd, 0xad, 0x69, 0x27, 0x3f, 0xb6, 0x3b, 0x50,
+       0xb7, 0xf4, 0x38, 0x4e, 0xa4, 0xe4, 0x0c, 0x8b, 0xcc, 0x77, 0x6d, 0x27,
+       0x79, 0x06, 0x07, 0x53, 0xc5, 0xb7, 0xcb, 0xfd, 0x75, 0xbb, 0xdc, 0x63,
+       0xc6, 0xff, 0x07, 0xb6, 0x0b, 0xca, 0xea, 0xc4, 0x79, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = {
-       0x08004070, 0x08003f70, 0x08004014, 0x0800402c, 0x08004044, 0x08004064,
-       0x08004070, 0x08004070, 0x08003f78, 0x00000000, 0x08004a2c, 0x08004a64,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004a9c, 0x08004c60,
-       0x08004ba8, 0x08004be0, 0x08004c60, 0x08004b30, 0x08004c60, 0x08004c60,
-       0x08004be0, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c20,
-       0x08004c60, 0x08004c20, 0x08004ba8, 0x08004c60, 0x08004c60, 0x08004c20,
-       0x08004c20, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60,
-       0x08004b0c, 0x00000000, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
-       0x08006078, 0x08006090, 0x08006090, 0x08006090, 0x08006078, 0x08006090,
-       0x08006090, 0x08006090, 0x08006078, 0x08006090, 0x08006090, 0x08006090,
-       0x08006084, 0x00000000, 0x00000000 };
+static const u32 bnx2_RXP_b09FwRodata[(0xb0/4) + 1] = {
+       0x80080100, 0x80080080, 0x80080000, 0x08005054, 0x08005054, 0x08005130,
+       0x08005104, 0x080050e8, 0x08005024, 0x08005024, 0x08005024, 0x0800505c,
+       0x080073b8, 0x08007404, 0x080073c4, 0x080072ec, 0x080073c4, 0x080073f4,
+       0x080073c4, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
+       0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080073e4,
+       0x080073d4, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
+       0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec, 0x080072ec,
+       0x080072ec, 0x080073d4, 0x00000000 };
 
 static struct fw_info bnx2_rxp_fw_09 = {
-       /* Firmware version:  3.7.1 */
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x7,
-       .ver_fix                        = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x08003184,
+       .start_addr                     = 0x080031d0,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x6788,
+       .text_len                       = 0x79c0,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_RXP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_RXP_b09FwText),
 
-       .data_addr                      = 0x08006a20,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_RXP_b09FwData,
 
-       .sbss_addr                      = 0x08006a20,
-       .sbss_len                       = 0x20,
+       .sbss_addr                      = 0x08007aa0,
+       .sbss_len                       = 0x58,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08006a40,
-       .bss_len                        = 0x13dc,
+       .bss_addr                       = 0x08007af8,
+       .bss_len                        = 0x1c,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x08006788,
-       .rodata_len                     = 0x278,
+       .rodata_addr                    = 0x080079c0,
+       .rodata_len                     = 0xb0,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_RXP_b09FwRodata,
 };
 
+static u8 bnx2_xi_rv2p_proc1[] = {
+       /* Date:        12/07/2007 16:21 */
+       0xc5, 0x56, 0xcd, 0x6b, 0x13, 0x51, 0x10, 0x9f, 0xdd, 0xa4, 0xd9, 0x34,
+       0xd9, 0x64, 0x97, 0xaa, 0x25, 0xb4, 0x91, 0xa6, 0x55, 0x0f, 0x69, 0x23,
+       0xb6, 0xea, 0xc1, 0x43, 0xc1, 0xda, 0x8b, 0xa0, 0x9e, 0x7a, 0x10, 0xf1,
+       0xdb, 0x20, 0x05, 0xf1, 0x8f, 0x70, 0x51, 0xab, 0x20, 0x78, 0x28, 0x6a,
+       0xb0, 0x0a, 0xea, 0x49, 0x45, 0x3c, 0x34, 0x07, 0x41, 0x50, 0x14, 0x14,
+       0x3c, 0xe9, 0x4d, 0xf0, 0xe3, 0x50, 0x15, 0x3f, 0x0e, 0x7a, 0x13, 0x8f,
+       0xda, 0xf8, 0xde, 0xcc, 0xef, 0xd9, 0xdd, 0x4d, 0xd3, 0x14, 0x0f, 0xba,
+       0xd0, 0xfc, 0xfa, 0xde, 0x9b, 0x37, 0x6f, 0xe6, 0x37, 0xf3, 0x66, 0x9e,
+       0x4f, 0x44, 0x36, 0x05, 0xf5, 0x3e, 0x85, 0x94, 0xb5, 0x12, 0x69, 0x05,
+       0x16, 0xd1, 0x5d, 0x97, 0x31, 0xd8, 0x40, 0xf2, 0x0d, 0x09, 0x04, 0x43,
+       0xbe, 0xfa, 0xfd, 0x4e, 0x5b, 0x4b, 0x1a, 0x13, 0xb4, 0xb5, 0x5f, 0xe3,
+       0x36, 0x7a, 0x5c, 0x2a, 0x28, 0xfc, 0xd5, 0xa0, 0x40, 0x8f, 0xd7, 0xcc,
+       0xde, 0xaf, 0x67, 0x59, 0xef, 0x3b, 0xec, 0x7f, 0x9d, 0x10, 0xdc, 0x52,
+       0x49, 0x8b, 0x1e, 0x20, 0xad, 0xf7, 0x19, 0x5e, 0x4e, 0xeb, 0x71, 0xd1,
+       0x0a, 0xd6, 0xe3, 0x7c, 0x5b, 0xe6, 0xe7, 0xa6, 0x3d, 0x3d, 0x4f, 0xef,
+       0xc7, 0xf5, 0xd8, 0xcb, 0x9c, 0xae, 0xa7, 0x59, 0xaf, 0xac, 0x77, 0x65,
+       0x4e, 0xf3, 0x3e, 0xd7, 0x12, 0x7d, 0xea, 0x8f, 0xf7, 0x6f, 0x56, 0x7a,
+       0x60, 0x37, 0x89, 0x9e, 0x43, 0x25, 0x3d, 0x3f, 0x06, 0xb9, 0x51, 0xc8,
+       0x15, 0x9b, 0xe4, 0xe6, 0xa6, 0x35, 0x3a, 0x54, 0xad, 0x68, 0x7f, 0xfa,
+       0x95, 0xa1, 0xae, 0xf0, 0xd3, 0x27, 0xfe, 0x4e, 0xc2, 0xec, 0x77, 0x83,
+       0xfa, 0x1f, 0x65, 0xdb, 0xa0, 0x96, 0x9b, 0x53, 0x7e, 0x1b, 0x7f, 0x8d,
+       0xbc, 0xc8, 0x39, 0xac, 0xe7, 0xad, 0x5a, 0x37, 0x7e, 0x85, 0xfd, 0xc9,
+       0x86, 0xfc, 0x89, 0xf9, 0xd9, 0xe4, 0x57, 0x98, 0xa7, 0xf4, 0x22, 0x76,
+       0xeb, 0x73, 0x94, 0x0d, 0x7c, 0x4e, 0x0a, 0xfc, 0xa6, 0x62, 0xfb, 0x52,
+       0x2d, 0xf6, 0x7d, 0x6a, 0x2c, 0xf8, 0x69, 0xd6, 0xf5, 0xfc, 0xd3, 0x85,
+       0xf9, 0x72, 0x74, 0x5d, 0xfc, 0xef, 0x80, 0xff, 0x8f, 0xe0, 0xdf, 0x0e,
+       0x5a, 0x6b, 0x17, 0x78, 0x3d, 0xc9, 0xfb, 0x7b, 0x95, 0x3d, 0x1a, 0x57,
+       0x03, 0xfb, 0x81, 0x07, 0x81, 0x07, 0x80, 0xab, 0x80, 0x2b, 0x81, 0x2b,
+       0x80, 0x5d, 0xc0, 0xcb, 0x40, 0x1f, 0xe8, 0x01, 0xf3, 0xc0, 0x8b, 0x40,
+       0x17, 0x98, 0x05, 0xd6, 0x80, 0x57, 0x81, 0x69, 0xe0, 0x31, 0xe0, 0x23,
+       0xe0, 0x13, 0xe0, 0x37, 0xe0, 0x39, 0xa3, 0xcf, 0xc2, 0xb9, 0x40, 0x42,
+       0x3e, 0x58, 0x31, 0x9e, 0xae, 0x21, 0xef, 0x35, 0xcf, 0x58, 0x2f, 0x1b,
+       0x39, 0xc4, 0x97, 0x79, 0x9a, 0x81, 0x5c, 0xd7, 0xec, 0x8d, 0xd8, 0xfd,
+       0x28, 0xb5, 0xbd, 0x17, 0xf1, 0xb8, 0x79, 0xec, 0xcf, 0xe1, 0xed, 0x1e,
+       0x9f, 0x93, 0x4f, 0xc9, 0xbc, 0x31, 0x6b, 0x8f, 0x27, 0x78, 0x34, 0x23,
+       0xf8, 0x39, 0xd3, 0xa9, 0x7e, 0x1b, 0x8d, 0xc9, 0xac, 0x8c, 0x8f, 0xe4,
+       0x0c, 0xcf, 0x46, 0x8f, 0xb1, 0xa7, 0x9d, 0x1d, 0xad, 0xce, 0x33, 0x76,
+       0xb5, 0x3b, 0x57, 0xb0, 0x6a, 0x47, 0xfd, 0xbf, 0x32, 0x2c, 0x98, 0x1c,
+       0x61, 0xa8, 0xb8, 0xa9, 0xa4, 0xc6, 0xcd, 0xee, 0x33, 0x73, 0x8e, 0x46,
+       0xb7, 0x50, 0xe3, 0xfb, 0x92, 0xa4, 0x5a, 0x4a, 0xeb, 0xfd, 0xd9, 0x38,
+       0x2f, 0x72, 0x3d, 0x47, 0x5e, 0x30, 0x16, 0xae, 0x3c, 0x17, 0xf9, 0x57,
+       0x25, 0x97, 0x71, 0xf7, 0x10, 0xc5, 0x3e, 0xb3, 0x2e, 0xf7, 0x31, 0x60,
+       0xbb, 0x7f, 0x58, 0x41, 0xdd, 0x9c, 0x83, 0x7d, 0xc7, 0x4d, 0x1c, 0x7d,
+       0xb6, 0x73, 0x80, 0x64, 0x3c, 0x51, 0x96, 0xf5, 0x89, 0x32, 0xee, 0xf3,
+       0x40, 0x34, 0x1f, 0xe4, 0x5e, 0x24, 0x10, 0xef, 0x7d, 0xb8, 0x17, 0xf1,
+       0x7b, 0x9c, 0x9e, 0xbd, 0x31, 0x1d, 0xce, 0x97, 0x02, 0x55, 0x47, 0x60,
+       0x4f, 0x53, 0x9c, 0x4d, 0x3d, 0x36, 0xf9, 0xce, 0xd3, 0xb3, 0x41, 0x22,
+       0xc2, 0xdf, 0x18, 0x55, 0xc2, 0x71, 0xb2, 0x16, 0xc9, 0x97, 0x76, 0xe7,
+       0x44, 0xf4, 0xe5, 0x55, 0x04, 0xa8, 0x39, 0x8f, 0x1d, 0xf8, 0x35, 0x86,
+       0x3c, 0xee, 0x6d, 0xca, 0x63, 0x53, 0xe7, 0x25, 0x9f, 0x5b, 0xd5, 0xaf,
+       0xbf, 0xaf, 0xcf, 0x22, 0x17, 0x84, 0xf2, 0xd3, 0xd4, 0x43, 0xf0, 0xe4,
+       0xb0, 0x5c, 0x71, 0xee, 0x9e, 0xc4, 0x4d, 0xea, 0xb8, 0x4a, 0xc6, 0x20,
+       0x6a, 0xa7, 0x63, 0xfc, 0xeb, 0x0b, 0xd7, 0xc1, 0x75, 0x2d, 0xe2, 0x15,
+       0xae, 0xbb, 0x71, 0x5e, 0xa2, 0x79, 0x2f, 0xf1, 0xcf, 0x80, 0xa7, 0xde,
+       0x36, 0x75, 0xa1, 0x13, 0x72, 0xdd, 0x4b, 0xc8, 0x89, 0xde, 0xf1, 0x72,
+       0xb8, 0x8e, 0xf8, 0x0d, 0xd4, 0xc1, 0x3f, 0x71, 0x78, 0xd8, 0x22, 0x0e,
+       0xa3, 0xff, 0x37, 0x0e, 0xe8, 0xa7, 0xed, 0xe2, 0x40, 0xb1, 0x38, 0xfc,
+       0x98, 0x5f, 0x5e, 0x1c, 0x08, 0x3c, 0x51, 0x8b, 0x38, 0xa4, 0xc0, 0xd7,
+       0xd7, 0xf9, 0xa5, 0xe3, 0x90, 0x85, 0xdc, 0xe7, 0x90, 0x1c, 0xdb, 0x3d,
+       0x2a, 0xf7, 0xd4, 0xa9, 0x7e, 0x89, 0xf1, 0x3b, 0x52, 0xd1, 0xf5, 0xe7,
+       0x04, 0xd5, 0xe1, 0xff, 0x9b, 0x08, 0x0f, 0x39, 0x65, 0x9f, 0xbc, 0x23,
+       0x6e, 0xd7, 0x0d, 0x5f, 0xb2, 0x5c, 0xaa, 0x08, 0xde, 0x62, 0x79, 0x3f,
+       0xc4, 0x5b, 0x94, 0x5f, 0xe1, 0xcd, 0xa7, 0x9b, 0x7f, 0xea, 0x92, 0xc7,
+       0xfa, 0x86, 0x51, 0xd7, 0x0f, 0xa3, 0xbe, 0x7e, 0xc8, 0x48, 0xfd, 0xae,
+       0xee, 0xe4, 0x3a, 0x4b, 0xdd, 0xa8, 0xb3, 0xd5, 0x9c, 0x8c, 0x7b, 0x72,
+       0xf2, 0x6e, 0x19, 0x76, 0x5c, 0x96, 0xeb, 0xc9, 0x09, 0x76, 0x67, 0xf5,
+       0xbe, 0x02, 0x7d, 0xdc, 0xc5, 0xe2, 0x95, 0x19, 0x57, 0xea, 0xed, 0xcc,
+       0x73, 0xd4, 0x7f, 0xcf, 0xf0, 0x04, 0x7f, 0x37, 0xe9, 0xf9, 0x6e, 0x55,
+       0xef, 0xc2, 0xfc, 0x2a, 0x99, 0x41, 0xb1, 0xef, 0x3a, 0xac, 0x2f, 0x99,
+       0x7d, 0x7d, 0x9a, 0xcf, 0x07, 0xf3, 0xa6, 0xbf, 0x0c, 0x6c, 0xd7, 0xf6,
+       0x78, 0x94, 0x77, 0x24, 0x9e, 0x82, 0x4a, 0xce, 0x76, 0xf4, 0xb6, 0xe2,
+       0x94, 0x2d, 0xe3, 0xa9, 0x93, 0xac, 0x66, 0xd7, 0x94, 0x99, 0x1f, 0xe7,
+       0x44, 0x9e, 0xb8, 0xf3, 0x94, 0xe7, 0xf3, 0xf5, 0x84, 0xcc, 0x3b, 0x3b,
+       0x0d, 0x1f, 0x1e, 0xfb, 0x57, 0x13, 0x3e, 0xf6, 0x5f, 0x12, 0xdc, 0xab,
+       0x9e, 0x22, 0xfa, 0xcb, 0xd4, 0x5c, 0xe9, 0x3f, 0x33, 0x6e, 0x9a, 0x91,
+       0x98, 0x0f, 0x7b, 0xa3, 0xf4, 0x91, 0x0e, 0xd4, 0xff, 0xce, 0x50, 0x9c,
+       0xe2, 0x7d, 0x79, 0xb9, 0xf1, 0x0a, 0xf7, 0x0b, 0xd3, 0x47, 0xe2, 0x7d,
+       0x21, 0x87, 0x3c, 0xbb, 0xdc, 0x26, 0x1f, 0x4d, 0x9d, 0xbd, 0x80, 0x7b,
+       0xb0, 0x58, 0x3f, 0xd6, 0x98, 0x6f, 0xf1, 0x8e, 0x28, 0x22, 0xff, 0x4c,
+       0xdf, 0x5c, 0xec, 0xbd, 0x20, 0xf2, 0xcb, 0x7b, 0x27, 0xf8, 0x2d, 0xde,
+       0x09, 0xff, 0xec, 0x3d, 0x50, 0x58, 0x88, 0xa3, 0xc9, 0xd3, 0x70, 0x1c,
+       0xc3, 0xf9, 0x1a, 0xef, 0xd7, 0x4b, 0xf5, 0xe9, 0x3c, 0x78, 0x9e, 0x04,
+       0xcf, 0x49, 0xea, 0x48, 0x30, 0x31, 0x6e, 0xf2, 0x14, 0xeb, 0xb5, 0xa7,
+       0x6c, 0x16, 0x77, 0x3b, 0xce, 0x58, 0x1a, 0xf3, 0xee, 0x19, 0x91, 0x4b,
+       0xca, 0x7c, 0xc1, 0xe0, 0xd9, 0x53, 0xf2, 0x3e, 0xb4, 0xe9, 0x37, 0xf9,
+       0x0f, 0x65, 0x7b, 0x50, 0x0d, 0x00, 0x00, 0x00 };
+
+static u8 bnx2_xi_rv2p_proc2[] = {
+       /* Date:        12/07/2007 16:21 */
+       0xad, 0x58, 0x5d, 0x6c, 0xd3, 0x55, 0x14, 0xbf, 0xfd, 0x58, 0xdb, 0xb5,
+       0xff, 0xb6, 0x63, 0x9b, 0xdd, 0xa7, 0x6e, 0x6e, 0x61, 0x6c, 0xd8, 0xcd,
+       0xd1, 0x8d, 0x4f, 0x4d, 0x5c, 0x86, 0x19, 0x20, 0x26, 0x8c, 0x61, 0xd4,
+       0x37, 0xd8, 0x90, 0xb2, 0xb1, 0x8d, 0x2c, 0x8c, 0xf0, 0xc0, 0x8b, 0x0d,
+       0xd3, 0xf1, 0xd2, 0x07, 0x47, 0xb2, 0x0d, 0x8d, 0xc1, 0x45, 0x7d, 0x40,
+       0x9f, 0xec, 0x83, 0x32, 0x30, 0xc6, 0xc4, 0xe8, 0x42, 0xf0, 0x01, 0x48,
+       0x30, 0xc6, 0x68, 0x48, 0x08, 0xea, 0x32, 0x10, 0x75, 0x0c, 0xfb, 0x64,
+       0x98, 0xf7, 0x9e, 0xdf, 0xb9, 0xff, 0xfe, 0xff, 0x6d, 0x27, 0x18, 0xec,
+       0x43, 0x4f, 0xef, 0xbd, 0xe7, 0x9e, 0x7b, 0x3e, 0x7e, 0xe7, 0x9c, 0x7b,
+       0x5b, 0x24, 0x84, 0x70, 0x8a, 0x44, 0xaa, 0x46, 0x52, 0x11, 0x70, 0xb8,
+       0x04, 0x3e, 0x6b, 0x8b, 0x88, 0x5c, 0x4b, 0xf9, 0xe4, 0x77, 0x81, 0x78,
+       0xc9, 0x59, 0x4e, 0x63, 0xb7, 0x50, 0x34, 0x2c, 0x44, 0xc2, 0x4a, 0x4b,
+       0x98, 0x5e, 0x65, 0xfa, 0x3b, 0xd3, 0xc7, 0x1d, 0xa0, 0x57, 0x78, 0xbc,
+       0x85, 0xc7, 0xd7, 0x78, 0xfc, 0x23, 0xd3, 0x8d, 0x3c, 0xbf, 0x99, 0x69,
+       0x92, 0xe9, 0x76, 0x5e, 0x9f, 0x65, 0x2a, 0x3f, 0x09, 0x43, 0x7e, 0xc9,
+       0xe5, 0x26, 0xad, 0xa7, 0x81, 0xe9, 0x26, 0xe8, 0xbb, 0xa7, 0x56, 0xf1,
+       0x2d, 0x2c, 0x67, 0xf8, 0x30, 0x7f, 0x7d, 0x02, 0xb4, 0x06, 0xbb, 0x3e,
+       0x4e, 0x3c, 0xad, 0xf7, 0x83, 0xf4, 0x06, 0x41, 0xfb, 0xd8, 0xfe, 0x8e,
+       0x28, 0x91, 0xe4, 0x7e, 0x27, 0xc6, 0x5d, 0x0d, 0xca, 0x0f, 0xc5, 0xc2,
+       0xed, 0x54, 0x72, 0x5a, 0x7c, 0x9e, 0xf3, 0x98, 0x7f, 0x35, 0x0c, 0xfa,
+       0x9a, 0x1f, 0xf4, 0x17, 0x7f, 0xa1, 0xfc, 0x5e, 0x5e, 0x8e, 0x07, 0x58,
+       0xbe, 0xc1, 0x6a, 0x07, 0xb0, 0x7f, 0xce, 0x80, 0x1e, 0x2f, 0xd7, 0x42,
+       0xbf, 0xef, 0x9f, 0x52, 0xf3, 0x2e, 0x91, 0x60, 0x39, 0x42, 0x68, 0x3d,
+       0x79, 0x7d, 0x10, 0xfb, 0x56, 0xad, 0xc1, 0xea, 0x5b, 0x71, 0x8c, 0xab,
+       0x3e, 0x28, 0xa2, 0xb8, 0x9c, 0x4e, 0x69, 0xfe, 0x7c, 0x72, 0xdd, 0x52,
+       0x2e, 0xe4, 0x8b, 0x3a, 0x1f, 0x29, 0x93, 0x88, 0x82, 0x8a, 0xe6, 0xec,
+       0x73, 0x20, 0x7f, 0x6a, 0xb5, 0x9a, 0x77, 0x8a, 0x1e, 0x97, 0x9a, 0xf7,
+       0x88, 0x9e, 0x01, 0xed, 0x5f, 0xac, 0xc7, 0x3d, 0x44, 0xca, 0x7b, 0xc7,
+       0x95, 0x9d, 0x61, 0xb1, 0xcf, 0x19, 0x26, 0x7e, 0xf8, 0xc5, 0xe5, 0x33,
+       0x3e, 0x03, 0xff, 0x97, 0x35, 0x06, 0xd9, 0x12, 0x6f, 0xc3, 0xbe, 0xd2,
+       0x18, 0xe8, 0x64, 0xac, 0x40, 0x91, 0x68, 0x7c, 0x94, 0x86, 0x2d, 0x37,
+       0xd7, 0xf9, 0x88, 0x2f, 0xd1, 0xac, 0xe3, 0xa7, 0xe3, 0xa5, 0xe2, 0xf8,
+       0x89, 0x8c, 0x23, 0xbb, 0xa5, 0x1e, 0x7e, 0xfd, 0x75, 0xb5, 0xe2, 0x97,
+       0xce, 0xad, 0xc3, 0x39, 0x19, 0xfd, 0xac, 0xf1, 0xff, 0xe8, 0x3f, 0xc4,
+       0x5f, 0xc9, 0xeb, 0x60, 0xbf, 0xd4, 0x4a, 0xbf, 0x28, 0x5a, 0xed, 0x48,
+       0x34, 0xdb, 0xe3, 0x71, 0x7d, 0x22, 0x4c, 0xbf, 0x6f, 0x75, 0x16, 0x91,
+       0x5f, 0x77, 0x61, 0xfe, 0x54, 0xd7, 0x39, 0xc4, 0x63, 0x07, 0xd9, 0x2f,
+       0xfc, 0x6f, 0x7c, 0x8a, 0x5d, 0xbd, 0x41, 0x35, 0x7e, 0xa5, 0x3d, 0x7e,
+       0x01, 0xeb, 0x05, 0x63, 0xf0, 0xeb, 0x2e, 0x96, 0xba, 0xc3, 0xe5, 0x50,
+       0x24, 0xe9, 0x19, 0xa3, 0xa1, 0x31, 0x47, 0xeb, 0x86, 0x38, 0x99, 0xc2,
+       0xfa, 0xe1, 0x80, 0x1a, 0xef, 0x8a, 0x2e, 0x60, 0x1c, 0x1d, 0x18, 0xe7,
+       0x8d, 0x4e, 0xf8, 0xe1, 0x96, 0x13, 0xf2, 0x18, 0x5e, 0x7e, 0x37, 0xc5,
+       0xc1, 0x21, 0x8c, 0x2e, 0xd0, 0x37, 0x69, 0xfd, 0x6f, 0x47, 0x92, 0xec,
+       0xee, 0x0a, 0xb9, 0xcf, 0x81, 0x91, 0x71, 0x6d, 0xe2, 0x56, 0xe3, 0xfe,
+       0x61, 0xf1, 0x3b, 0x6e, 0x68, 0xbc, 0xb2, 0xff, 0xd9, 0xbf, 0xef, 0x89,
+       0x6c, 0x9c, 0x82, 0x76, 0x35, 0x80, 0x7a, 0xea, 0xb3, 0xf1, 0xaa, 0xf1,
+       0x69, 0xf7, 0x33, 0xc7, 0xc7, 0x82, 0x17, 0x22, 0x12, 0x27, 0x36, 0xdc,
+       0x30, 0x4e, 0x2b, 0xa4, 0xbf, 0x74, 0xfc, 0x95, 0x20, 0xaf, 0x18, 0x64,
+       0x79, 0x03, 0x6c, 0xd7, 0x10, 0xdb, 0x75, 0xc7, 0xaf, 0xfd, 0xaa, 0xed,
+       0x01, 0x3d, 0x69, 0xb3, 0xc7, 0x21, 0xf1, 0x64, 0xc7, 0x21, 0xeb, 0x93,
+       0xfc, 0xa6, 0x0e, 0x3f, 0xaa, 0xea, 0x41, 0x4d, 0x3b, 0x1b, 0x14, 0x9f,
+       0x27, 0x36, 0x9d, 0xb2, 0xe3, 0x50, 0xe7, 0xe3, 0x9e, 0x5a, 0x2d, 0x5f,
+       0xe1, 0x32, 0x2d, 0x71, 0x89, 0xb8, 0x9d, 0x4e, 0x59, 0xf3, 0xb3, 0x32,
+       0x4f, 0x7e, 0xda, 0xf3, 0x42, 0xfb, 0xe5, 0x70, 0x90, 0x0a, 0x54, 0xfb,
+       0xe5, 0x79, 0xfb, 0x79, 0xc0, 0xb7, 0xd7, 0xc4, 0x4f, 0xe9, 0x06, 0xf6,
+       0x1f, 0xd3, 0xc8, 0x46, 0x25, 0xaf, 0x9b, 0xe5, 0xb7, 0xb2, 0x7c, 0xc3,
+       0x92, 0x77, 0x4a, 0xbf, 0x4e, 0x33, 0xdf, 0x74, 0xdc, 0x32, 0x79, 0xa7,
+       0xfd, 0x47, 0xe7, 0x47, 0x2f, 0xcf, 0xab, 0xfd, 0x55, 0x0f, 0xc8, 0xc3,
+       0x4d, 0xa6, 0xbc, 0xef, 0xcc, 0x7c, 0x53, 0xeb, 0x01, 0xf1, 0x1c, 0x0f,
+       0xed, 0xf5, 0xe4, 0x4f, 0x59, 0x4f, 0xc8, 0x0e, 0x9f, 0x71, 0x8e, 0xeb,
+       0xc7, 0xa8, 0x3a, 0xa7, 0x9c, 0xf5, 0x2e, 0x67, 0xbd, 0x65, 0xbf, 0x6a,
+       0xe6, 0x3a, 0xb3, 0xd7, 0x5a, 0x2f, 0xd6, 0x5a, 0xf2, 0x5e, 0x8d, 0x1b,
+       0x97, 0x73, 0xfb, 0x85, 0xcd, 0x9f, 0x09, 0x41, 0xfe, 0xf7, 0x72, 0x7c,
+       0x3c, 0x79, 0xfa, 0x8b, 0xe6, 0x07, 0xbe, 0xb6, 0x11, 0xbf, 0xcf, 0xc4,
+       0xbf, 0xdd, 0xde, 0xca, 0x3c, 0x75, 0x27, 0xdb, 0x7e, 0xf8, 0xb3, 0xd7,
+       0x19, 0x24, 0xbe, 0x1b, 0x23, 0x6a, 0xdf, 0x49, 0x87, 0xf6, 0x53, 0x07,
+       0xea, 0x90, 0x03, 0xf6, 0x56, 0xb3, 0xbd, 0x72, 0xb9, 0x99, 0xf0, 0xef,
+       0xbb, 0x31, 0x62, 0xb5, 0xd7, 0xf8, 0x97, 0xf3, 0xec, 0xb8, 0x19, 0xe1,
+       0x3e, 0xd6, 0x87, 0xbc, 0xf0, 0xed, 0xff, 0x5c, 0xeb, 0xc3, 0xe7, 0x86,
+       0xf5, 0xf9, 0x4a, 0x5e, 0x95, 0x98, 0x1f, 0x55, 0xfb, 0x1f, 0x13, 0x0c,
+       0x33, 0x31, 0xdc, 0x88, 0xfa, 0x77, 0xe7, 0x00, 0xf4, 0x1f, 0x6e, 0xd0,
+       0x7d, 0x1c, 0x38, 0x16, 0x5c, 0xff, 0xbf, 0x9e, 0xc8, 0xe7, 0x97, 0x41,
+       0x07, 0xf8, 0x4a, 0xd9, 0xae, 0x22, 0xb6, 0x2b, 0x2a, 0xb2, 0xeb, 0xec,
+       0x5e, 0xca, 0x97, 0x0e, 0xe6, 0x7b, 0x56, 0xd7, 0xe3, 0x1c, 0x3e, 0xd8,
+       0x5f, 0xc0, 0xe7, 0xe7, 0xf3, 0x57, 0x3e, 0xb9, 0xb3, 0x8c, 0xa3, 0x7e,
+       0xe6, 0x73, 0xe7, 0xa9, 0xf3, 0x18, 0xa5, 0xd7, 0x50, 0x9d, 0x3f, 0x73,
+       0x7c, 0x56, 0xf1, 0x05, 0x4d, 0x9c, 0xdb, 0xed, 0xfa, 0xe9, 0xfe, 0xa3,
+       0xfb, 0x5f, 0xf1, 0x45, 0xc4, 0xc1, 0xd0, 0x4a, 0x7e, 0x76, 0xab, 0xe9,
+       0x99, 0xc5, 0x59, 0x1d, 0x27, 0x83, 0xec, 0x9c, 0x1f, 0x55, 0xe7, 0x7f,
+       0x98, 0xe5, 0x7f, 0xa7, 0xc5, 0xff, 0xe0, 0x7f, 0x22, 0xfa, 0xa8, 0x7e,
+       0xcf, 0xd7, 0x97, 0xbf, 0xb8, 0x9f, 0x9b, 0x27, 0x6a, 0xfe, 0xc2, 0x43,
+       0xfb, 0x63, 0x77, 0x9b, 0xd5, 0xfe, 0x7a, 0x31, 0x97, 0x42, 0x7e, 0x75,
+       0x33, 0x0e, 0xf7, 0x71, 0xbd, 0xbe, 0xe1, 0x57, 0x13, 0x3e, 0xd1, 0xb7,
+       0x93, 0xfc, 0x21, 0x22, 0x01, 0xf8, 0xa7, 0xef, 0x45, 0xed, 0x4f, 0xcc,
+       0x57, 0x52, 0xbf, 0x75, 0x89, 0x6e, 0xaf, 0x41, 0xfc, 0x95, 0x41, 0xd0,
+       0x08, 0xd7, 0xf9, 0x39, 0xb3, 0x8f, 0x81, 0x9e, 0xf6, 0xe8, 0xba, 0x8c,
+       0x7e, 0xfe, 0x95, 0x47, 0x31, 0xc8, 0x20, 0x35, 0xa1, 0x3e, 0x77, 0x36,
+       0x18, 0xb4, 0xde, 0xd3, 0x04, 0x3c, 0x89, 0x3a, 0xdd, 0xe7, 0xf0, 0xe1,
+       0x3e, 0x50, 0x99, 0xe9, 0x77, 0xd6, 0x7e, 0x58, 0x68, 0xe9, 0x07, 0xfa,
+       0x3c, 0xed, 0x47, 0x2d, 0x97, 0x86, 0xb2, 0xaf, 0x58, 0xfb, 0xa1, 0xee,
+       0x13, 0x4b, 0xdc, 0x27, 0x4a, 0xc4, 0xc5, 0x14, 0xec, 0x9a, 0x4b, 0x65,
+       0xe3, 0x4f, 0x9f, 0xa7, 0xe5, 0x41, 0x6f, 0x6d, 0x47, 0x46, 0x3e, 0xce,
+       0x3f, 0xc0, 0x7a, 0xfe, 0x4c, 0xf7, 0xd8, 0x08, 0xdb, 0xa3, 0xe4, 0x62,
+       0x7e, 0x3b, 0xf7, 0xe7, 0x84, 0x39, 0xb6, 0xf7, 0xd5, 0x6e, 0xd2, 0xab,
+       0x98, 0xf1, 0x16, 0xb1, 0xe4, 0x03, 0xf8, 0x4b, 0x5b, 0x41, 0x27, 0x5b,
+       0x75, 0x1c, 0x74, 0xbc, 0x74, 0x7c, 0x10, 0xc7, 0xc8, 0x3a, 0x62, 0x6b,
+       0xef, 0x5b, 0x47, 0x7d, 0xa4, 0xb5, 0x6f, 0x51, 0xe3, 0x0f, 0xfb, 0x77,
+       0x47, 0x15, 0xff, 0xeb, 0xe2, 0x2a, 0xe1, 0x50, 0x88, 0x1f, 0x98, 0x66,
+       0xfa, 0x15, 0x07, 0xc0, 0xcc, 0x57, 0x8e, 0x5f, 0x01, 0x4f, 0xb7, 0xe9,
+       0x7a, 0xae, 0xe3, 0x65, 0xcd, 0xd7, 0x78, 0x0e, 0x6e, 0x33, 0x75, 0x59,
+       0xdb, 0xa9, 0xf8, 0xa3, 0x8c, 0x47, 0x9f, 0xe8, 0xdc, 0x86, 0x7b, 0x6e,
+       0xc8, 0x8b, 0xba, 0x1f, 0xf2, 0x5a, 0xe3, 0x25, 0x71, 0x51, 0xe8, 0x55,
+       0xc3, 0xea, 0xe2, 0x42, 0xb2, 0xe7, 0xd4, 0xa5, 0x6f, 0x69, 0xf9, 0xfd,
+       0xe9, 0x00, 0xe6, 0xcb, 0x76, 0x86, 0xc9, 0x1f, 0x53, 0xc0, 0xf3, 0xbb,
+       0x93, 0xa0, 0xef, 0x88, 0x17, 0xb0, 0xbf, 0xf8, 0x04, 0xdd, 0x03, 0x7d,
+       0x65, 0x8c, 0xcf, 0x72, 0xd4, 0x89, 0xe4, 0x34, 0xdd, 0x4b, 0x96, 0x97,
+       0x45, 0x50, 0x51, 0x8f, 0xd9, 0x6f, 0x80, 0x4f, 0xb7, 0x25, 0xce, 0x0f,
+       0xc2, 0x2b, 0xdd, 0x2b, 0x25, 0x1e, 0xb1, 0x9d, 0x71, 0xeb, 0xcb, 0xc6,
+       0xad, 0xf6, 0x47, 0xb9, 0x33, 0x2f, 0x4e, 0x37, 0xd8, 0x71, 0xea, 0x61,
+       0x9c, 0xde, 0x33, 0xfb, 0x7b, 0xae, 0x5c, 0xf4, 0xf9, 0x8b, 0xff, 0x1b,
+       0x6e, 0x41, 0xb7, 0xd7, 0xab, 0xf3, 0xcb, 0x72, 0xea, 0x71, 0x8d, 0x2d,
+       0xce, 0x4d, 0xf7, 0xb5, 0x5e, 0x27, 0x3c, 0xd6, 0xf5, 0x66, 0xb3, 0x9f,
+       0x1d, 0xe1, 0x77, 0x5e, 0xda, 0xa0, 0x1f, 0xb1, 0x3b, 0x49, 0x1a, 0x1a,
+       0x15, 0x67, 0x15, 0x5f, 0x63, 0xec, 0x08, 0xd7, 0xdb, 0x4b, 0x2e, 0xd4,
+       0x9b, 0xfe, 0x03, 0x18, 0x5f, 0xe6, 0xfa, 0x71, 0x77, 0x0d, 0xd5, 0xe5,
+       0xd8, 0x91, 0xf3, 0x5a, 0x1e, 0xc9, 0x31, 0xd2, 0x5c, 0xd7, 0x9f, 0x77,
+       0x71, 0xbd, 0x25, 0xbf, 0xb9, 0x63, 0x7f, 0xd0, 0x7d, 0xc6, 0x2d, 0x3a,
+       0x9f, 0x54, 0xb4, 0x42, 0xd6, 0x6f, 0x3e, 0xff, 0x19, 0xd0, 0x1e, 0x2f,
+       0xa8, 0x68, 0xb2, 0xc7, 0x43, 0x98, 0x76, 0x61, 0xe4, 0xa9, 0x63, 0x39,
+       0xbd, 0x18, 0x7b, 0xf9, 0x5e, 0x36, 0xcd, 0x7e, 0x0a, 0x91, 0x3f, 0x8a,
+       0xa4, 0x9d, 0x8a, 0x86, 0x63, 0xa3, 0xb3, 0xd0, 0x7f, 0x68, 0x2b, 0xec,
+       0x5b, 0x62, 0xbb, 0x99, 0x86, 0xde, 0x1e, 0x23, 0xfc, 0x85, 0xc6, 0xf1,
+       0x0e, 0x09, 0x79, 0xc6, 0x60, 0xc7, 0x50, 0x1a, 0xe3, 0xa5, 0xcd, 0xa0,
+       0x7f, 0x6d, 0xc1, 0xbe, 0xa3, 0xc7, 0xd9, 0x1f, 0x5b, 0xf3, 0xef, 0xeb,
+       0xbf, 0x07, 0xbe, 0xe1, 0x46, 0x75, 0xfe, 0xe0, 0x0c, 0xbf, 0x5f, 0xc4,
+       0x80, 0x4b, 0x8d, 0x07, 0x8c, 0x34, 0x8f, 0x0f, 0x71, 0x7d, 0xbf, 0xcd,
+       0xef, 0x8d, 0xa1, 0xac, 0xf7, 0xc6, 0x02, 0xee, 0x99, 0x33, 0xe9, 0x24,
+       0x70, 0x91, 0x28, 0xcc, 0x7e, 0xaf, 0xaa, 0x71, 0x75, 0xac, 0x8c, 0xe3,
+       0x54, 0xba, 0x1e, 0x74, 0x72, 0x3d, 0xde, 0x09, 0x43, 0xc7, 0xd8, 0x2f,
+       0xed, 0x14, 0xa7, 0x96, 0xc5, 0xd9, 0x95, 0xde, 0xc9, 0xe0, 0x9b, 0xe2,
+       0x73, 0x23, 0xdc, 0x4f, 0x22, 0xc8, 0x3f, 0x51, 0x9e, 0xe4, 0x77, 0xcb,
+       0x04, 0xee, 0x9d, 0x53, 0x06, 0x68, 0x24, 0xa8, 0xf5, 0x45, 0x3e, 0x26,
+       0x52, 0xc8, 0x3b, 0xac, 0x3b, 0x2c, 0xeb, 0x7c, 0x1f, 0xc9, 0x79, 0xe7,
+       0x28, 0xba, 0xe4, 0x28, 0x71, 0x68, 0x3b, 0xb1, 0xda, 0x17, 0x54, 0xf8,
+       0xbd, 0x69, 0xe6, 0xd5, 0x02, 0xf9, 0xad, 0x6a, 0x26, 0x4d, 0xfa, 0x57,
+       0x8a, 0x12, 0xea, 0xc3, 0x15, 0xa1, 0x45, 0xf8, 0x31, 0x36, 0xcd, 0xfe,
+       0x1f, 0xd9, 0x04, 0x7a, 0x8c, 0xf1, 0xa7, 0x71, 0x75, 0x65, 0xa3, 0x41,
+       0xfb, 0xe6, 0x47, 0x71, 0x8e, 0xbe, 0x47, 0x64, 0xbf, 0xc7, 0x35, 0x1e,
+       0x2b, 0xda, 0x50, 0x48, 0xfb, 0x8f, 0xaa, 0x73, 0x82, 0x12, 0x47, 0x4a,
+       0x7f, 0xe9, 0x13, 0xce, 0x47, 0x3b, 0x4e, 0x15, 0x8e, 0x75, 0x7e, 0x58,
+       0xf1, 0x9d, 0x9d, 0xef, 0x19, 0xbc, 0x86, 0xe8, 0x5e, 0x2e, 0x8b, 0x5c,
+       0x82, 0xdf, 0x4d, 0x7c, 0x3f, 0x58, 0x29, 0x7e, 0x6f, 0x23, 0x7e, 0x31,
+       0xd6, 0xdb, 0x18, 0x18, 0x43, 0x5f, 0x1c, 0x67, 0x1c, 0x2d, 0x34, 0xf2,
+       0xfd, 0x87, 0xf5, 0xfb, 0x8d, 0xdf, 0x67, 0xc0, 0x9b, 0xd7, 0x88, 0xcf,
+       0x32, 0xbe, 0x18, 0xf7, 0x87, 0xd8, 0xee, 0xdb, 0xb0, 0xdb, 0xd0, 0x76,
+       0x0f, 0x98, 0x76, 0xeb, 0xfb, 0x95, 0x55, 0x4e, 0xb1, 0xc4, 0xad, 0xa2,
+       0xab, 0x8c, 0x2b, 0x54, 0xcf, 0x0a, 0xd8, 0x4e, 0xc9, 0xd7, 0xa6, 0xec,
+       0x09, 0xb1, 0x3d, 0x41, 0x71, 0xb0, 0xc5, 0xba, 0x2f, 0xc0, 0xfb, 0xfc,
+       0x72, 0x1f, 0xe6, 0x51, 0x17, 0x8c, 0x15, 0xfc, 0xa9, 0xfc, 0xa6, 0xe5,
+       0x66, 0xe7, 0xbd, 0xd5, 0x7f, 0x74, 0x23, 0xa5, 0x0f, 0xea, 0x9b, 0x8c,
+       0x53, 0x33, 0xfe, 0x3f, 0xd0, 0xf5, 0xed, 0x2e, 0xdd, 0x5f, 0xfd, 0x67,
+       0x86, 0x51, 0x9f, 0xce, 0x0c, 0x9f, 0xe5, 0x77, 0x07, 0xfb, 0xa5, 0x9b,
+       0xfe, 0xb7, 0x90, 0xb1, 0xab, 0xb3, 0xd7, 0x37, 0xbb, 0x1e, 0x55, 0x16,
+       0x3d, 0xf4, 0xb9, 0xff, 0x00, 0x0e, 0x4b, 0x7c, 0x26, 0x30, 0x14, 0x00,
+       0x00, 0x00 };
+
 static u8 bnx2_TPAT_b09FwText[] = {
-       0xcd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0xde,
-       0x38, 0xf1, 0x24, 0x19, 0xca, 0xa6, 0x72, 0xe9, 0x8c, 0x3d, 0x76, 0x8c,
-       0x6c, 0x35, 0xd3, 0x76, 0xd5, 0x58, 0x68, 0xa4, 0x4e, 0x67, 0x76, 0x1d,
-       0x2b, 0xf4, 0xc1, 0x85, 0x48, 0x3c, 0xf0, 0xe2, 0xae, 0x1d, 0x05, 0x78,
-       0x2a, 0x28, 0x0f, 0x11, 0x2f, 0x59, 0x76, 0x37, 0xfd, 0x41, 0xdb, 0x2c,
-       0x35, 0xc8, 0x41, 0x02, 0xa4, 0xb0, 0x69, 0xe2, 0x97, 0xad, 0x27, 0x2d,
-       0x45, 0xea, 0x4b, 0x95, 0x28, 0x55, 0x2b, 0xc4, 0x13, 0x2f, 0x54, 0x79,
-       0xac, 0x52, 0x5a, 0xf1, 0x00, 0x28, 0x42, 0x15, 0xaa, 0x68, 0xf0, 0xe5,
-       0x3b, 0x77, 0x66, 0xdc, 0xdd, 0xc4, 0x49, 0xcb, 0x9f, 0x84, 0xa5, 0xf5,
-       0x9d, 0xb9, 0xf7, 0x9e, 0x73, 0xcf, 0x3d, 0x3f, 0xdf, 0x39, 0x67, 0xca,
-       0x2a, 0x95, 0x28, 0xfb, 0xdb, 0x8d, 0xdf, 0xc9, 0xa7, 0x9f, 0x39, 0x79,
-       0xf8, 0xa1, 0x47, 0x1d, 0xa2, 0x87, 0x1f, 0x52, 0x94, 0xa2, 0x46, 0xff,
-       0x85, 0x3f, 0x30, 0xb1, 0x72, 0xfe, 0xfc, 0x23, 0x53, 0x0d, 0x7e, 0xe3,
-       0x44, 0x1e, 0x99, 0x5a, 0xb0, 0xf4, 0xe5, 0x15, 0x8f, 0x28, 0xec, 0xcf,
-       0x3a, 0x31, 0xfd, 0x43, 0x34, 0x6c, 0x9d, 0x78, 0xfe, 0x81, 0xe0, 0xd6,
-       0xa1, 0x37, 0x0f, 0xbb, 0x37, 0xcf, 0x6b, 0x64, 0x5a, 0xc1, 0xb2, 0x69,
-       0x4d, 0x93, 0x39, 0x1e, 0x5c, 0x75, 0x7e, 0x7e, 0x30, 0x28, 0xd0, 0x9e,
-       0x9c, 0x97, 0x4d, 0xcd, 0x2e, 0x35, 0xf4, 0xc0, 0xa4, 0x5a, 0xe7, 0x94,
-       0x12, 0x75, 0x3d, 0xab, 0x0a, 0x1e, 0xa1, 0x0d, 0xfe, 0x1e, 0xde, 0x13,
-       0x5d, 0xa9, 0x9e, 0x33, 0x49, 0x0d, 0x42, 0x3c, 0xcf, 0x51, 0xab, 0x2b,
-       0xc4, 0x0f, 0x7d, 0x85, 0x56, 0x7c, 0x93, 0x96, 0x2d, 0x77, 0x31, 0x54,
-       0xb6, 0x44, 0x3c, 0x25, 0xc4, 0xb7, 0x7d, 0x95, 0x54, 0x6f, 0x41, 0x89,
-       0x36, 0x16, 0x95, 0x78, 0x63, 0x91, 0xf5, 0x01, 0xf9, 0x16, 0x94, 0x70,
-       0x83, 0xc7, 0xc0, 0x8c, 0x3b, 0x7b, 0x68, 0xd9, 0xa6, 0x31, 0xd5, 0x9b,
-       0xc3, 0x79, 0x65, 0xf0, 0x71, 0x28, 0xf2, 0x67, 0x2d, 0x95, 0x26, 0xf1,
-       0x1b, 0xa1, 0x9a, 0x4f, 0x23, 0xaa, 0xa7, 0x52, 0xdd, 0x56, 0xe8, 0xe5,
-       0x8a, 0x81, 0xdf, 0x51, 0xa5, 0xba, 0xf1, 0x9d, 0x8c, 0x0f, 0xef, 0x37,
-       0xb1, 0xc6, 0x32, 0x33, 0xfd, 0x20, 0xed, 0x6e, 0x3c, 0x7f, 0x0b, 0xfb,
-       0x0c, 0x8a, 0x2a, 0xb7, 0xaf, 0x8d, 0xe0, 0x59, 0xc1, 0xfc, 0x51, 0xc8,
-       0xc5, 0x7c, 0x1c, 0xc8, 0x31, 0x4e, 0xed, 0xee, 0x22, 0xee, 0x53, 0xa0,
-       0x86, 0x35, 0x35, 0x53, 0x27, 0x1d, 0x34, 0x1a, 0x85, 0xf6, 0x15, 0xa1,
-       0x06, 0x42, 0x44, 0x15, 0x6f, 0xa6, 0x27, 0xcf, 0x50, 0x49, 0xf3, 0x0a,
-       0x54, 0xf5, 0x77, 0x53, 0xcb, 0xd2, 0xa8, 0x39, 0x67, 0x50, 0xb8, 0xa4,
-       0xe3, 0x8e, 0xfb, 0x40, 0xa7, 0x80, 0xfe, 0xa5, 0xcc, 0xe6, 0x45, 0x6a,
-       0x5a, 0x05, 0xcc, 0x8f, 0x51, 0xd3, 0xde, 0xab, 0xa8, 0xc1, 0x0b, 0x98,
-       0x9f, 0xb2, 0x7a, 0xf4, 0x3c, 0x46, 0x05, 0xef, 0x7b, 0xb1, 0x97, 0xdf,
-       0x15, 0xf0, 0x23, 0x2b, 0x4a, 0x66, 0xa8, 0x95, 0xe4, 0xb4, 0x3c, 0x9f,
-       0xce, 0x35, 0x92, 0xdb, 0xed, 0x8d, 0x7d, 0xdd, 0x1a, 0x74, 0xcc, 0xb6,
-       0xc1, 0x9e, 0xdc, 0x2e, 0xd2, 0x07, 0x1e, 0xe7, 0x79, 0xfe, 0xc3, 0xbc,
-       0x43, 0x5a, 0xe0, 0x59, 0x31, 0x7d, 0x85, 0xd2, 0xb5, 0x54, 0xf6, 0xc8,
-       0x7f, 0x2c, 0x7b, 0xb7, 0xad, 0xe8, 0xdc, 0xa3, 0xb8, 0x9f, 0x74, 0x19,
-       0x3c, 0xdb, 0xb8, 0x7f, 0x01, 0xfe, 0xd1, 0x0c, 0x55, 0x6a, 0x94, 0x4d,
-       0x72, 0xe7, 0x57, 0xb1, 0xf2, 0x41, 0x47, 0xa3, 0x98, 0x75, 0xe5, 0xeb,
-       0x19, 0x1d, 0xfb, 0xc6, 0xbb, 0x90, 0xb3, 0x61, 0x99, 0x70, 0xbc, 0xe5,
-       0x63, 0x42, 0x5c, 0xf4, 0x85, 0x28, 0x04, 0xde, 0xcc, 0x25, 0x9a, 0x2d,
-       0x1b, 0x34, 0x6d, 0x61, 0x84, 0x8e, 0xbd, 0x72, 0x9d, 0x8c, 0x5c, 0x9e,
-       0xdc, 0x37, 0xf1, 0xd7, 0x57, 0x08, 0x3e, 0x79, 0xa3, 0xf3, 0x7b, 0xd6,
-       0xc7, 0xcc, 0x82, 0xa4, 0x11, 0xa2, 0x37, 0x7f, 0x2f, 0x9a, 0x5f, 0x67,
-       0x34, 0x42, 0xd4, 0x2a, 0x7c, 0xae, 0x8b, 0x3b, 0xb3, 0x7f, 0x13, 0xd5,
-       0xfa, 0xbe, 0x59, 0xef, 0x40, 0x3e, 0x0f, 0x63, 0x9f, 0xa8, 0xde, 0xe5,
-       0x7b, 0x98, 0xd4, 0x84, 0xde, 0x5a, 0xd8, 0xaf, 0x56, 0x76, 0xb1, 0x7f,
-       0xc0, 0xc6, 0x4b, 0x66, 0xb5, 0xe3, 0x96, 0x5f, 0xa0, 0x25, 0x33, 0xee,
-       0xcf, 0x96, 0x57, 0xe9, 0x01, 0x3e, 0xc7, 0x34, 0x82, 0x63, 0x66, 0x4f,
-       0xd2, 0x1b, 0x1a, 0x95, 0xf0, 0x0c, 0x1e, 0xcd, 0x0e, 0x29, 0x91, 0xbf,
-       0x8b, 0xef, 0x0b, 0xba, 0xc5, 0x8c, 0x6e, 0x31, 0xa3, 0x1b, 0xcb, 0xe8,
-       0x9e, 0x1c, 0xa0, 0x7b, 0x92, 0xe9, 0xb0, 0x37, 0xcc, 0xf6, 0x86, 0xd9,
-       0x5e, 0x3d, 0xdb, 0x5b, 0xcd, 0xf6, 0x62, 0xec, 0x3b, 0x90, 0xcf, 0x9d,
-       0x09, 0x15, 0xc8, 0xe8, 0x89, 0x07, 0x23, 0x9f, 0xc2, 0xd8, 0x73, 0xaf,
-       0xc7, 0xda, 0x18, 0x5d, 0xf0, 0x2d, 0x6a, 0x27, 0x0e, 0x64, 0x6f, 0x53,
-       0x94, 0xa8, 0xa0, 0x1d, 0xa3, 0x9e, 0x77, 0x53, 0xd4, 0xfc, 0x0a, 0x6c,
-       0x37, 0xca, 0x74, 0xe5, 0x1a, 0x14, 0xd1, 0x4c, 0x66, 0xad, 0x55, 0xaa,
-       0xc0, 0x5f, 0x54, 0xd8, 0x6f, 0x52, 0x3e, 0x37, 0x93, 0x0a, 0xd6, 0xa9,
-       0xa1, 0x56, 0x5c, 0xab, 0x49, 0x6e, 0x39, 0xd2, 0xc8, 0x52, 0x03, 0x1b,
-       0x7b, 0x1a, 0x54, 0x4d, 0x4c, 0x7a, 0x4f, 0x3b, 0x25, 0xe3, 0xb4, 0xd9,
-       0xbd, 0x2e, 0xde, 0x3c, 0xe8, 0xd0, 0x95, 0x64, 0x9c, 0x7e, 0x95, 0x94,
-       0xe9, 0xb5, 0xc4, 0xa6, 0x57, 0x13, 0x52, 0x23, 0x1f, 0x7e, 0x6c, 0x5b,
-       0x74, 0x39, 0x19, 0xd4, 0xfb, 0x07, 0xac, 0x77, 0x73, 0x7f, 0x40, 0xe6,
-       0xbe, 0x80, 0x1a, 0x5a, 0x90, 0xe2, 0x40, 0x9c, 0xe2, 0x80, 0xf4, 0xa9,
-       0x56, 0xb7, 0x79, 0xbf, 0x06, 0x0c, 0x5a, 0xf1, 0xc3, 0xbd, 0x1a, 0xec,
-       0x12, 0x23, 0x0a, 0xd4, 0xed, 0x51, 0xda, 0xc8, 0x5d, 0xf1, 0xdc, 0xe7,
-       0x63, 0xec, 0xf6, 0xce, 0x1a, 0x98, 0xbd, 0xdd, 0xb6, 0x7f, 0xc6, 0x19,
-       0xa3, 0xb0, 0x9b, 0x46, 0x4f, 0xe8, 0x88, 0x1f, 0xef, 0x23, 0x8d, 0x63,
-       0xc0, 0xd9, 0xb4, 0xe9, 0x4c, 0x97, 0x68, 0x62, 0xd3, 0xa4, 0x8d, 0x4e,
-       0x91, 0x9c, 0xde, 0x28, 0xad, 0x74, 0x4b, 0x34, 0x79, 0x49, 0xc7, 0xde,
-       0x5d, 0x34, 0xb9, 0xa6, 0xda, 0x1c, 0xcb, 0x31, 0x74, 0x3c, 0xd1, 0x13,
-       0xf0, 0xd1, 0x12, 0x4d, 0xac, 0xbb, 0xd2, 0x7f, 0x56, 0xbc, 0x96, 0xaf,
-       0xd1, 0x0f, 0xe8, 0xda, 0x5c, 0x01, 0x77, 0xb2, 0xc9, 0x9f, 0x1e, 0x3c,
-       0xcf, 0x80, 0x9b, 0xf1, 0x1c, 0x98, 0xee, 0x71, 0x1d, 0x52, 0x99, 0x9f,
-       0x49, 0x13, 0x97, 0x4c, 0x25, 0xee, 0xb2, 0xce, 0xd8, 0x07, 0xcd, 0xcc,
-       0x07, 0x75, 0x25, 0x3a, 0x57, 0xc4, 0x59, 0x7f, 0x12, 0x91, 0x07, 0xdf,
-       0x03, 0x96, 0xad, 0x54, 0xbe, 0x0f, 0xf9, 0x30, 0xd7, 0xe3, 0xb5, 0x9b,
-       0xd9, 0x3c, 0xf3, 0x00, 0x46, 0xf8, 0xfb, 0x29, 0x62, 0x3c, 0x38, 0xc6,
-       0x34, 0x45, 0x9a, 0x58, 0x63, 0x8c, 0xc1, 0xd8, 0xe3, 0x77, 0xbe, 0xdb,
-       0x08, 0xd5, 0xa1, 0x95, 0xfa, 0x8c, 0x0d, 0xb9, 0x54, 0x89, 0x19, 0x75,
-       0x60, 0x88, 0xea, 0x95, 0x30, 0xf2, 0x79, 0x3f, 0xd3, 0xd2, 0xf8, 0xb7,
-       0xa5, 0xbd, 0x63, 0xf8, 0xaf, 0x0e, 0x79, 0x56, 0x69, 0xaa, 0x7c, 0x5c,
-       0xae, 0x61, 0xae, 0xcf, 0x6b, 0xd6, 0x6d, 0x6b, 0x78, 0xef, 0xe7, 0x32,
-       0x20, 0xc6, 0xbd, 0x16, 0x4e, 0x31, 0x32, 0xbd, 0xf0, 0xfe, 0x46, 0x19,
-       0xb6, 0x01, 0xa6, 0x11, 0x74, 0x49, 0xd4, 0xeb, 0xe8, 0xc0, 0x1c, 0xf5,
-       0x8b, 0x2a, 0xd3, 0xd9, 0xcc, 0x07, 0xf7, 0x5f, 0xd7, 0x95, 0xf8, 0x9c,
-       0xe7, 0xfc, 0x81, 0x98, 0x7e, 0x12, 0x3a, 0x98, 0x9a, 0x6f, 0xf1, 0xfe,
-       0xbe, 0x41, 0xde, 0x5a, 0xc3, 0xd2, 0x61, 0x53, 0x15, 0x06, 0x8d, 0x7f,
-       0x34, 0x06, 0x5b, 0xbb, 0x4e, 0x8b, 0x7e, 0x07, 0x79, 0x0a, 0xe4, 0xf5,
-       0x74, 0x7a, 0xb9, 0xc3, 0xba, 0x30, 0x69, 0x72, 0x5d, 0x88, 0xe7, 0x7c,
-       0xb6, 0xc9, 0xbb, 0xd0, 0x0b, 0xe1, 0x86, 0x53, 0xf3, 0x37, 0x60, 0x9f,
-       0x8d, 0x3e, 0xdb, 0xc6, 0x90, 0x3a, 0xf1, 0xd6, 0xe6, 0x60, 0xd7, 0x99,
-       0x4c, 0x46, 0xb6, 0x97, 0x4e, 0xed, 0x8a, 0x4a, 0x17, 0x2b, 0x9f, 0x08,
-       0xd5, 0x63, 0x8c, 0x2d, 0x40, 0xb7, 0xd8, 0xd7, 0xc3, 0xbe, 0xa4, 0x00,
-       0x1d, 0xfe, 0x4d, 0x18, 0xc0, 0xdf, 0x8b, 0x15, 0xcc, 0xaf, 0x9d, 0x86,
-       0xac, 0x1a, 0x68, 0x53, 0x1f, 0x63, 0x79, 0x16, 0x3a, 0xf9, 0xfd, 0xbc,
-       0xf9, 0xb7, 0x25, 0xbf, 0x51, 0x9a, 0xde, 0x1c, 0xa5, 0x13, 0xfd, 0x51,
-       0x9a, 0x38, 0xcb, 0x34, 0x42, 0xb4, 0x2b, 0x8c, 0x91, 0xf0, 0x51, 0x4f,
-       0xea, 0xa1, 0xac, 0xa9, 0x7c, 0x4f, 0xac, 0x6f, 0x12, 0xad, 0xf6, 0xf9,
-       0x0c, 0x7d, 0x80, 0xa7, 0x4a, 0x47, 0x7e, 0x42, 0x74, 0xa4, 0xcf, 0xb4,
-       0xdb, 0xba, 0x03, 0x5f, 0x0b, 0x3c, 0x2d, 0xe2, 0x5c, 0xa4, 0x79, 0xc8,
-       0x79, 0x1b, 0x11, 0x72, 0x58, 0x15, 0xbf, 0x05, 0xe4, 0x35, 0xbe, 0xff,
-       0x1c, 0xe2, 0x8f, 0xb1, 0x7c, 0x0b, 0x77, 0x2f, 0x50, 0xdb, 0x5f, 0xc4,
-       0x1e, 0xb6, 0xf1, 0x51, 0xac, 0xef, 0x46, 0x2e, 0xc8, 0x72, 0x85, 0xc5,
-       0xb9, 0x62, 0x2f, 0xe2, 0x60, 0x04, 0xf8, 0x7f, 0xbf, 0x3e, 0x9c, 0x2b,
-       0xb0, 0xcf, 0x3e, 0x80, 0xdc, 0x80, 0x44, 0x5d, 0x62, 0x5e, 0xfb, 0x31,
-       0x8e, 0xe0, 0xfd, 0x00, 0xf6, 0x0e, 0xe6, 0x89, 0x9c, 0xee, 0x6e, 0x39,
-       0x02, 0x31, 0xb1, 0x86, 0x58, 0x59, 0x9f, 0x61, 0xcc, 0x80, 0x3d, 0xd8,
-       0xa6, 0x45, 0x60, 0xb8, 0x09, 0x1e, 0x6c, 0xdb, 0x22, 0x6c, 0xc8, 0x79,
-       0xce, 0xa2, 0xc9, 0x4d, 0x8e, 0xeb, 0x34, 0x8f, 0xc4, 0xdb, 0x79, 0x84,
-       0x64, 0x4c, 0x34, 0x13, 0xf6, 0x89, 0xd0, 0x8c, 0xce, 0x6e, 0x09, 0xc4,
-       0x70, 0x39, 0x66, 0x5c, 0xdb, 0x9c, 0x05, 0xbd, 0x86, 0xf8, 0xa8, 0x9a,
-       0xf5, 0xb3, 0x29, 0xa6, 0xd5, 0x37, 0x1d, 0xe9, 0x93, 0xcd, 0xc4, 0xc2,
-       0x3b, 0x63, 0x5a, 0x8e, 0x61, 0x4c, 0x4f, 0x61, 0x04, 0x7c, 0x8b, 0x34,
-       0x21, 0x56, 0xfc, 0x31, 0xaa, 0xc3, 0x3f, 0x43, 0xe0, 0x5a, 0x1d, 0xb8,
-       0x16, 0x0f, 0xe0, 0x5a, 0xfc, 0x99, 0xb8, 0x06, 0xcc, 0xea, 0x02, 0xb3,
-       0x50, 0x23, 0xbc, 0x06, 0x8c, 0x7f, 0x15, 0xe7, 0x5d, 0xee, 0xee, 0x84,
-       0x75, 0x8c, 0x73, 0x8c, 0x77, 0x33, 0xf4, 0xe6, 0xc1, 0x7f, 0x15, 0xef,
-       0xda, 0xc0, 0x06, 0x93, 0xbe, 0x7b, 0xf0, 0xde, 0x98, 0x77, 0x06, 0x98,
-       0x67, 0x7c, 0x36, 0xe6, 0x35, 0x18, 0xf3, 0x74, 0xf8, 0x60, 0x03, 0x78,
-       0xa0, 0xae, 0x0d, 0x9e, 0xd3, 0xc1, 0x39, 0x3c, 0xa7, 0x67, 0x79, 0x55,
-       0xa5, 0x1e, 0xfc, 0x5f, 0xf3, 0xf8, 0x9c, 0x39, 0xd6, 0xbb, 0xd4, 0xff,
-       0x13, 0xba, 0x4d, 0xc6, 0x34, 0xfc, 0x62, 0x6d, 0x94, 0xb4, 0xb3, 0x9f,
-       0xfa, 0x3d, 0x6a, 0x03, 0xc4, 0x3b, 0xfe, 0x6d, 0xe6, 0x3c, 0x4a, 0xc0,
-       0x1c, 0x9d, 0x0a, 0x6b, 0x06, 0xde, 0x95, 0xa1, 0x7d, 0x47, 0x90, 0x77,
-       0xb4, 0xc0, 0x9d, 0x7f, 0x9f, 0x9f, 0xfb, 0xbc, 0xa7, 0x44, 0xea, 0xba,
-       0xeb, 0x38, 0xaa, 0xeb, 0x5f, 0x03, 0x46, 0xbc, 0xe3, 0x31, 0x0e, 0x36,
-       0xe1, 0x0d, 0x05, 0xd2, 0xd7, 0xc4, 0x69, 0x23, 0xe0, 0xb3, 0x1b, 0x0e,
-       0xe2, 0xdd, 0x79, 0x09, 0x7e, 0xc4, 0x39, 0xf4, 0x22, 0xe2, 0xa7, 0x96,
-       0xc5, 0x6a, 0xab, 0x9f, 0x9f, 0xb9, 0x0f, 0x72, 0x1b, 0xa0, 0x19, 0xdc,
-       0xcb, 0x71, 0x20, 0xc4, 0x09, 0xdc, 0x49, 0xc3, 0x39, 0xc6, 0xba, 0x49,
-       0x85, 0x75, 0xd6, 0x8b, 0x0b, 0xfa, 0x49, 0x6b, 0x81, 0xae, 0x0f, 0xe1,
-       0xc2, 0x73, 0xfd, 0xeb, 0x3a, 0x63, 0xa9, 0x86, 0x18, 0x2d, 0xe2, 0x5c,
-       0x63, 0x9b, 0x17, 0x65, 0xbc, 0x98, 0xde, 0x2b, 0x9f, 0xd8, 0xa6, 0x67,
-       0x7c, 0x9b, 0x2a, 0x33, 0x8e, 0xb1, 0x1c, 0x9a, 0xc4, 0xd4, 0x52, 0x86,
-       0xa9, 0x93, 0xb0, 0x67, 0x49, 0xc6, 0xa7, 0xea, 0x3d, 0x98, 0xe1, 0xea,
-       0x5e, 0x8c, 0x3c, 0x27, 0xb2, 0x78, 0xd1, 0x21, 0x2f, 0xf3, 0x2d, 0x91,
-       0xb6, 0xce, 0x35, 0x04, 0xdf, 0xe9, 0xaf, 0xf0, 0x6d, 0xc6, 0x0a, 0xf6,
-       0x4f, 0x89, 0xa9, 0x98, 0x9f, 0x82, 0xcc, 0x8c, 0x0f, 0x4c, 0xc7, 0xf4,
-       0x3b, 0xd1, 0xfd, 0x05, 0x74, 0xd6, 0x0e, 0x74, 0x98, 0xdb, 0x64, 0x1a,
-       0xc6, 0x88, 0x7d, 0xd8, 0x1f, 0x31, 0x3e, 0x40, 0x67, 0x4c, 0x3b, 0x9e,
-       0xc5, 0x63, 0x15, 0x6b, 0x5c, 0x03, 0xcb, 0xf8, 0x22, 0x23, 0xe0, 0x7b,
-       0x70, 0x7d, 0xcc, 0xf9, 0x91, 0x6b, 0x52, 0xae, 0x3d, 0xf3, 0x5a, 0xd5,
-       0x9b, 0xa9, 0xdd, 0xad, 0xee, 0xb4, 0x06, 0xeb, 0xce, 0x43, 0xc6, 0xce,
-       0x75, 0xe7, 0x41, 0x23, 0xad, 0x3b, 0xa7, 0x8d, 0xbb, 0xd7, 0x9d, 0x39,
-       0xed, 0xbd, 0xeb, 0xce, 0x66, 0x97, 0xcf, 0xdc, 0x19, 0x2f, 0x56, 0xe0,
-       0xaf, 0xad, 0x24, 0xbf, 0x27, 0xf7, 0x06, 0xa1, 0x59, 0x3b, 0x9b, 0xda,
-       0xbe, 0x29, 0x7d, 0x11, 0x38, 0xb2, 0x39, 0x0b, 0x3b, 0xa2, 0xa6, 0x1e,
-       0xc2, 0x8e, 0x9c, 0x86, 0x75, 0x5a, 0x02, 0x46, 0xb3, 0x3e, 0x8b, 0x19,
-       0x4e, 0x60, 0xf4, 0x3e, 0x06, 0x4e, 0xe4, 0xf8, 0xc2, 0xfc, 0xfe, 0x9f,
-       0xf0, 0x85, 0xcc, 0x11, 0xe0, 0x84, 0x19, 0x30, 0x5e, 0x4a, 0x59, 0x50,
-       0x93, 0x0b, 0xb1, 0xe0, 0x73, 0x0c, 0x0c, 0xf6, 0x4c, 0xec, 0x0f, 0x45,
-       0x7a, 0xcb, 0x67, 0x9f, 0x40, 0xcf, 0xe4, 0x71, 0x8e, 0x64, 0x3c, 0xde,
-       0x12, 0x6f, 0x79, 0x11, 0xe6, 0xaa, 0xb0, 0x3d, 0xfb, 0xc3, 0xa2, 0x72,
-       0x64, 0xc3, 0x04, 0x1d, 0xfb, 0xc4, 0xf8, 0x1d, 0xbd, 0x50, 0xda, 0xb3,
-       0x70, 0x7d, 0xfc, 0xef, 0xfa, 0xc8, 0x1b, 0x77, 0xf1, 0x91, 0xcb, 0x99,
-       0x8f, 0x24, 0xf7, 0xf0, 0x91, 0x37, 0x3e, 0xa7, 0x8f, 0xb8, 0xe5, 0x0f,
-       0x51, 0x3f, 0xbd, 0x0d, 0x39, 0x42, 0x4b, 0x88, 0x0f, 0xfd, 0x9d, 0xfa,
-       0x94, 0xd0, 0xd4, 0x5f, 0x64, 0x9d, 0xa5, 0x79, 0xa5, 0x85, 0x77, 0xed,
-       0x15, 0xae, 0x97, 0x39, 0xe7, 0xa4, 0xb9, 0x65, 0xe2, 0xc5, 0xd4, 0x3f,
-       0x26, 0x5e, 0x11, 0xe2, 0xc2, 0x0e, 0xfe, 0xc0, 0x35, 0xf4, 0x55, 0xf8,
-       0x55, 0x8b, 0xfe, 0x17, 0x35, 0x34, 0x63, 0x78, 0xc5, 0x3c, 0xde, 0xc9,
-       0xed, 0x9f, 0xdb, 0xbe, 0x40, 0xe7, 0xad, 0x3d, 0xd0, 0xdb, 0xa3, 0xd4,
-       0xfa, 0xb1, 0xce, 0x7d, 0x05, 0xfc, 0xe2, 0x71, 0x9d, 0x63, 0x17, 0x7d,
-       0x24, 0x9e, 0x07, 0xeb, 0x6c, 0xf8, 0xa5, 0x5f, 0xc8, 0xe3, 0x65, 0x00,
-       0xfb, 0x4f, 0xa1, 0x54, 0xb9, 0x23, 0xaf, 0x0c, 0xf5, 0xd4, 0x1a, 0x7a,
-       0xea, 0x58, 0xf2, 0xe0, 0xbe, 0x2b, 0xd5, 0x63, 0x5b, 0xf6, 0xd1, 0x5b,
-       0xa2, 0x25, 0x7b, 0xe9, 0x03, 0x05, 0x2a, 0x2d, 0x66, 0x3e, 0xe3, 0x20,
-       0x1f, 0xb9, 0x7e, 0x03, 0xfc, 0xb9, 0xd6, 0x80, 0x1c, 0xb4, 0x8a, 0x58,
-       0xbc, 0x80, 0x3c, 0xbc, 0x02, 0xbd, 0xd4, 0x65, 0x6c, 0x8c, 0xd1, 0x35,
-       0xe4, 0xfe, 0x36, 0xf2, 0xf3, 0x19, 0xe8, 0xa6, 0x05, 0xdd, 0xc4, 0x49,
-       0x1a, 0x27, 0xd7, 0xa0, 0x9b, 0x85, 0x01, 0xdd, 0x2c, 0xfc, 0x47, 0xfd,
-       0xc5, 0x1f, 0x91, 0x6b, 0xcd, 0x65, 0x1d, 0xf3, 0x57, 0x12, 0x99, 0x5b,
-       0x97, 0x5a, 0x1d, 0x6a, 0xdc, 0x1f, 0x9c, 0xe6, 0xda, 0x8e, 0x6b, 0xb3,
-       0xf9, 0x95, 0x0a, 0xe6, 0xfa, 0x26, 0x45, 0xd0, 0xcf, 0x37, 0x0f, 0xd3,
-       0xb2, 0x16, 0xb0, 0x4f, 0xe3, 0x3d, 0xa1, 0x46, 0x74, 0x18, 0xf5, 0x56,
-       0x32, 0xbe, 0x8c, 0x7e, 0x1c, 0xbe, 0xd5, 0xa0, 0x10, 0x72, 0x86, 0xe0,
-       0xbd, 0xd0, 0x31, 0xcd, 0xd5, 0x0e, 0xf7, 0x51, 0x0d, 0xe2, 0x5e, 0xbd,
-       0xd7, 0xbf, 0x09, 0x7e, 0x23, 0xdf, 0x40, 0x7f, 0xeb, 0x34, 0x81, 0xd3,
-       0xcf, 0xc2, 0x6d, 0x5b, 0x36, 0x7f, 0xcb, 0x60, 0x1c, 0x1d, 0x07, 0x8f,
-       0xa7, 0x0b, 0xa9, 0xaf, 0x8e, 0x83, 0x0f, 0xc7, 0x11, 0xe1, 0x3c, 0xd6,
-       0x65, 0xee, 0x7f, 0xe5, 0x81, 0xfa, 0xbe, 0x40, 0x39, 0x86, 0x35, 0xa1,
-       0x37, 0xd6, 0x75, 0xe4, 0x9d, 0x2c, 0xe4, 0xdf, 0x6d, 0x5a, 0xc0, 0x81,
-       0xfa, 0x1c, 0x63, 0x96, 0x02, 0xdf, 0xa3, 0xb4, 0xaf, 0x44, 0x1f, 0x52,
-       0x9f, 0x43, 0xde, 0xb6, 0x8b, 0x72, 0x6c, 0x24, 0xa7, 0xb3, 0xfd, 0xaa,
-       0xdc, 0xc7, 0xf9, 0xa2, 0x99, 0xc8, 0x7e, 0x42, 0xa9, 0x76, 0xc9, 0xa9,
-       0xfb, 0xe8, 0x93, 0x50, 0x7b, 0xb4, 0x13, 0xce, 0xf5, 0x73, 0xa6, 0x2a,
-       0xb1, 0xef, 0x06, 0x68, 0xf0, 0xbc, 0x49, 0x6a, 0xdd, 0xe7, 0xef, 0x0c,
-       0xfc, 0x0d, 0x04, 0xf1, 0x63, 0xd3, 0x6e, 0xd0, 0x43, 0xae, 0x71, 0x96,
-       0x2b, 0xac, 0xcb, 0x3a, 0x85, 0x79, 0x1f, 0x52, 0xd3, 0x6f, 0x33, 0xef,
-       0x66, 0x67, 0x99, 0x88, 0x1f, 0xc6, 0x5d, 0x9f, 0x73, 0xde, 0x97, 0x34,
-       0xba, 0x49, 0x12, 0x37, 0xad, 0x87, 0x91, 0x0b, 0x0f, 0x83, 0x26, 0x94,
-       0x98, 0x93, 0xf6, 0x15, 0x39, 0x8d, 0xa7, 0x0d, 0xf3, 0x58, 0xd6, 0x87,
-       0xdf, 0x43, 0xc4, 0x59, 0x25, 0x3b, 0x6f, 0xd0, 0x67, 0xdf, 0x87, 0xcf,
-       0xde, 0xc8, 0xf6, 0x00, 0x87, 0xed, 0x02, 0xf6, 0xb1, 0x8c, 0x8c, 0x2f,
-       0x4c, 0xb3, 0x65, 0x0c, 0xf3, 0x99, 0xdc, 0x81, 0xc7, 0x47, 0x03, 0x3c,
-       0x6c, 0xbe, 0x9b, 0x55, 0x4f, 0x7b, 0x6c, 0xf9, 0x57, 0x87, 0x9e, 0xd1,
-       0x93, 0xdc, 0xa7, 0xe2, 0x1e, 0x5c, 0x9b, 0xc5, 0x72, 0xfe, 0x97, 0xc5,
-       0x61, 0xbe, 0xa7, 0xb2, 0x73, 0xfc, 0x34, 0x36, 0x3c, 0x8c, 0xc9, 0x8d,
-       0x01, 0xd9, 0x8d, 0x1d, 0xce, 0xdd, 0xa5, 0xa3, 0x35, 0x50, 0xd8, 0xdf,
-       0xb4, 0x80, 0xf3, 0x33, 0x9e, 0xb7, 0xfd, 0x83, 0x7d, 0xf5, 0xb3, 0x7d,
-       0xd4, 0xf8, 0x9c, 0x3e, 0xfa, 0x72, 0x87, 0x71, 0x23, 0xf5, 0xd1, 0xfa,
-       0x1d, 0x3e, 0x8a, 0xfa, 0xc8, 0xce, 0xfd, 0x93, 0xe3, 0x25, 0xf7, 0xcf,
-       0xfc, 0x99, 0x63, 0x1c, 0xb8, 0x9c, 0xe1, 0x5c, 0x13, 0x38, 0x57, 0x95,
-       0x79, 0xcf, 0x2d, 0x57, 0x29, 0x8d, 0xe5, 0x55, 0xc4, 0x72, 0x55, 0xe3,
-       0x3c, 0xc8, 0x31, 0xcc, 0x74, 0x1c, 0xc7, 0x4c, 0x37, 0x96, 0xd1, 0x61,
-       0x44, 0x3c, 0x57, 0xb3, 0x78, 0x6e, 0x75, 0x5d, 0xa7, 0x9a, 0xc5, 0x73,
-       0x0b, 0x31, 0xdc, 0xce, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0x7f, 0xdf, 0xd3,
-       0x2a, 0x9c, 0x1b, 0x5d, 0x27, 0x06, 0xc6, 0xb5, 0x25, 0xcf, 0x06, 0xee,
-       0x09, 0x19, 0xbb, 0x79, 0x5c, 0xdc, 0xf1, 0x1d, 0x0c, 0xf7, 0xf9, 0x34,
-       0xd7, 0xd4, 0x90, 0x6b, 0x2e, 0x20, 0xd7, 0xf4, 0x06, 0xbe, 0x83, 0x9d,
-       0x97, 0xb9, 0xe6, 0xeb, 0xc5, 0x3c, 0xd7, 0xf4, 0xb2, 0x5c, 0xd3, 0x93,
-       0xb9, 0xe6, 0xab, 0x45, 0xce, 0x35, 0x4d, 0x3a, 0x5a, 0x1c, 0xcc, 0x35,
-       0xcd, 0xa1, 0x5c, 0x93, 0xd3, 0xf2, 0xfc, 0x4e, 0xb9, 0x26, 0xd7, 0xd9,
-       0xbd, 0x6a, 0x92, 0x7c, 0x0f, 0xcb, 0xca, 0xb8, 0xc4, 0x78, 0x9c, 0xd6,
-       0xfc, 0x57, 0x92, 0x3c, 0x96, 0x4e, 0xe3, 0x1c, 0xbc, 0x77, 0x77, 0x8a,
-       0x25, 0x33, 0x8b, 0xa5, 0xdd, 0x29, 0x4d, 0x77, 0x30, 0x9e, 0x4e, 0x17,
-       0x87, 0xe3, 0x29, 0xe7, 0x93, 0xc7, 0x53, 0xca, 0xf3, 0x3d, 0xad, 0xcc,
-       0x35, 0x02, 0xfa, 0x6d, 0xd7, 0x5f, 0xc0, 0xec, 0xa5, 0xfe, 0x2c, 0x6a,
-       0x6e, 0x9d, 0xae, 0xe6, 0x78, 0x23, 0xbf, 0x09, 0x61, 0xec, 0xe7, 0xb2,
-       0x16, 0xb7, 0xd7, 0x7a, 0xa8, 0xbb, 0xdf, 0x01, 0x8e, 0x5c, 0x94, 0xeb,
-       0x9f, 0x88, 0xab, 0x68, 0x09, 0xdb, 0x5e, 0xbe, 0xef, 0x17, 0x38, 0xcf,
-       0xb5, 0xce, 0xe3, 0xe9, 0xd9, 0x7e, 0xae, 0x13, 0x5e, 0xe7, 0xb9, 0xbf,
-       0x23, 0x9f, 0xa0, 0x66, 0xdf, 0xde, 0xcb, 0xfd, 0x8f, 0x87, 0x3b, 0x3b,
-       0xf4, 0xfa, 0x50, 0x0f, 0x94, 0xf6, 0x3e, 0x75, 0xf9, 0x8d, 0x97, 0x6b,
-       0x97, 0xe8, 0x0b, 0x2a, 0x9d, 0xa2, 0xaf, 0xf9, 0x3c, 0xa7, 0x52, 0xed,
-       0x31, 0x21, 0x9e, 0x41, 0x1d, 0xf3, 0xd4, 0x50, 0x1d, 0x53, 0xa4, 0x89,
-       0x47, 0x06, 0x7b, 0xc8, 0x2d, 0x31, 0x31, 0xed, 0x9e, 0x0f, 0x29, 0x54,
-       0x6a, 0x1b, 0x5c, 0xe7, 0x6e, 0xd7, 0xb5, 0x44, 0xfb, 0x6e, 0x09, 0x75,
-       0x9a, 0xf3, 0xe2, 0x6f, 0x33, 0x5d, 0x61, 0xed, 0xdc, 0x2d, 0x60, 0x6b,
-       0x55, 0x7e, 0x0b, 0x0e, 0x37, 0xf8, 0x1c, 0x7e, 0xc7, 0x98, 0x70, 0xcd,
-       0x73, 0xb7, 0xef, 0xb3, 0x3a, 0xec, 0xe2, 0x3a, 0xc7, 0x35, 0x92, 0xdf,
-       0x37, 0x56, 0x7c, 0xf7, 0xa7, 0x2d, 0x4a, 0x71, 0xa2, 0xea, 0x2f, 0x41,
-       0x16, 0xd4, 0x9d, 0xd6, 0x32, 0x6c, 0x33, 0x0d, 0x5c, 0x72, 0x9d, 0x47,
-       0x54, 0x5b, 0xe2, 0xf8, 0x2a, 0x78, 0x6b, 0x8f, 0x70, 0x4d, 0xf9, 0xb1,
-       0x58, 0xed, 0xcb, 0x7c, 0xec, 0xb3, 0x8f, 0xc4, 0xc9, 0x5e, 0x95, 0xc7,
-       0x30, 0xe1, 0xe7, 0x02, 0x71, 0x2d, 0xb9, 0xb3, 0xff, 0xd8, 0x56, 0xf5,
-       0x9c, 0x63, 0xd5, 0xba, 0x8e, 0xb5, 0xd0, 0x55, 0xe1, 0xdd, 0xfb, 0x4c,
-       0xda, 0x03, 0x9b, 0x20, 0x1f, 0xd3, 0x7d, 0x90, 0xe5, 0x92, 0x63, 0xc5,
-       0xa8, 0x0f, 0xbf, 0xa7, 0xb9, 0xd6, 0x53, 0xa4, 0x98, 0x54, 0xba, 0x25,
-       0xd2, 0x6f, 0x33, 0x8e, 0x55, 0xdd, 0x3e, 0xfb, 0x16, 0xce, 0x66, 0x99,
-       0x38, 0x46, 0x39, 0x5f, 0x2e, 0x2a, 0x4b, 0xd0, 0xd1, 0xb1, 0x8d, 0x5d,
-       0xc0, 0x35, 0xce, 0x97, 0x07, 0xb2, 0x6f, 0x50, 0xb0, 0x0f, 0xee, 0xff,
-       0xfa, 0x1d, 0xf5, 0x67, 0x5e, 0x67, 0x32, 0xbd, 0x10, 0xcd, 0x79, 0x3e,
-       0x9f, 0x20, 0xcb, 0xd4, 0xcc, 0x25, 0xd9, 0x13, 0xcd, 0xa2, 0xee, 0xe3,
-       0x51, 0xa0, 0x26, 0xe2, 0xef, 0x61, 0xae, 0x55, 0xc7, 0x73, 0x35, 0x7b,
-       0x6e, 0x72, 0xbf, 0x34, 0xcf, 0x3c, 0xb8, 0x6f, 0xe2, 0xf8, 0xf9, 0x27,
-       0x6e, 0xb7, 0x92, 0x82, 0x90, 0x18, 0x00, 0x00, 0x00 };
+       0xbd, 0x58, 0x5d, 0x6c, 0x1c, 0xd5, 0x15, 0x3e, 0x73, 0x67, 0xd6, 0x3b,
+       0xb6, 0x9c, 0x78, 0x4c, 0xb6, 0xb0, 0x14, 0x47, 0xcc, 0xc4, 0xe3, 0x9f,
+       0xca, 0x16, 0x0c, 0xe9, 0x96, 0x1a, 0x69, 0x55, 0x0d, 0xbb, 0x1b, 0x63,
+       0xa5, 0x3c, 0x18, 0x29, 0x52, 0x91, 0xa0, 0xc8, 0x5d, 0x13, 0xe0, 0x81,
+       0x87, 0xa0, 0xf6, 0xa1, 0x15, 0x0f, 0x59, 0xd6, 0x9b, 0x90, 0x87, 0x6d,
+       0x06, 0x96, 0x2a, 0x79, 0x68, 0x55, 0x45, 0x0e, 0x8e, 0xa3, 0x76, 0xe5,
+       0x25, 0x48, 0x7d, 0x8c, 0x40, 0xa1, 0x4a, 0x5f, 0x79, 0xa0, 0x15, 0x7d,
+       0x22, 0x52, 0x5f, 0x78, 0xe8, 0x4f, 0x84, 0xd4, 0x16, 0xb5, 0x34, 0xb7,
+       0xdf, 0x77, 0x67, 0xc6, 0x6c, 0x4d, 0x22, 0xc4, 0x4b, 0x57, 0x5a, 0xdd,
+       0x99, 0x7b, 0xcf, 0x39, 0xf7, 0xdc, 0xf3, 0xf3, 0x9d, 0x73, 0xe7, 0x90,
+       0x92, 0x31, 0xc9, 0x7e, 0xfb, 0xf0, 0xaf, 0xfc, 0xe0, 0xc4, 0x8f, 0xbe,
+       0xf5, 0x40, 0xf4, 0x00, 0xdf, 0xad, 0x82, 0x38, 0xf2, 0x7f, 0xfc, 0xd9,
+       0x22, 0x5e, 0xae, 0x07, 0xff, 0xe2, 0xaa, 0xea, 0xda, 0xc1, 0x5a, 0x28,
+       0xae, 0x5d, 0x5d, 0x79, 0x60, 0x3d, 0x14, 0x89, 0xfb, 0x0b, 0x7e, 0x5d,
+       0xfe, 0xa3, 0x5b, 0x25, 0x47, 0x38, 0x7f, 0xb0, 0xfa, 0xd9, 0x83, 0x57,
+       0xbf, 0x1d, 0xdc, 0xbc, 0x60, 0x8b, 0xeb, 0x55, 0xcf, 0xb8, 0xde, 0xac,
+       0xb8, 0x53, 0xe0, 0xf9, 0xc5, 0x5c, 0x6f, 0x44, 0xf6, 0xe7, 0xb2, 0x5a,
+       0x5a, 0x85, 0x37, 0xf4, 0xd5, 0xb9, 0xd0, 0x6b, 0x4b, 0x49, 0xae, 0x0c,
+       0x7c, 0xa9, 0x0d, 0xa6, 0xe4, 0x9d, 0x41, 0x59, 0xde, 0x1e, 0x78, 0xf2,
+       0xd6, 0xc0, 0x91, 0xe3, 0x6f, 0x9c, 0x94, 0x4e, 0x14, 0x94, 0x1b, 0xb6,
+       0x2b, 0xaa, 0x1a, 0x94, 0x9b, 0xe2, 0xcb, 0x56, 0x14, 0x9c, 0x59, 0xb3,
+       0x27, 0x2d, 0xb7, 0xea, 0xca, 0xcb, 0x73, 0x4a, 0x2e, 0x94, 0x9e, 0x96,
+       0xe7, 0xc2, 0x27, 0xf1, 0x77, 0xe4, 0x50, 0xcf, 0xb1, 0xea, 0xe7, 0x1d,
+       0x09, 0x7b, 0x13, 0xf2, 0x58, 0xa4, 0xf5, 0x7a, 0x14, 0x83, 0x7f, 0x7a,
+       0xfe, 0x79, 0x19, 0x95, 0x96, 0x17, 0xac, 0x88, 0x14, 0x48, 0x23, 0xb5,
+       0xa8, 0x20, 0xb1, 0x97, 0x9e, 0xed, 0x82, 0x19, 0x3f, 0xd3, 0x5b, 0xe0,
+       0x1f, 0x0d, 0xf3, 0xf5, 0xbb, 0xb2, 0x75, 0x2f, 0x5b, 0x57, 0x72, 0xe8,
+       0x5c, 0xe0, 0x6f, 0xcb, 0x4c, 0xec, 0x58, 0xb7, 0x74, 0x2d, 0xbc, 0xdb,
+       0xab, 0x6d, 0x3b, 0x32, 0xdd, 0xe3, 0x19, 0x42, 0xaf, 0x2e, 0x1a, 0x3c,
+       0x36, 0x79, 0x1c, 0x55, 0xfd, 0x21, 0x7c, 0x37, 0x13, 0x2b, 0x4b, 0xe4,
+       0x5a, 0xb7, 0xec, 0xd5, 0x06, 0x3f, 0xb6, 0x6a, 0xc9, 0x2d, 0x1d, 0x3b,
+       0x63, 0xa2, 0xc2, 0xd8, 0xaa, 0x6d, 0x53, 0xd6, 0xa8, 0x38, 0x61, 0x11,
+       0x3c, 0xd3, 0x9e, 0x12, 0x8e, 0xb5, 0x6c, 0x9e, 0xb2, 0x1b, 0x78, 0x5e,
+       0xb6, 0xe2, 0x6d, 0xc7, 0xaa, 0x9d, 0x5f, 0xc1, 0xb3, 0x0b, 0x7e, 0xd8,
+       0x26, 0xb2, 0x24, 0x5e, 0xb5, 0xc0, 0xc7, 0x73, 0x7a, 0x78, 0x57, 0x12,
+       0x97, 0x3c, 0xd9, 0xa8, 0x04, 0xe5, 0x96, 0x1c, 0xb5, 0xea, 0xdb, 0x5f,
+       0x70, 0x9c, 0xb7, 0x32, 0xf8, 0xe2, 0x1c, 0x75, 0x79, 0xd4, 0xd1, 0x5a,
+       0x3d, 0x54, 0xcc, 0xce, 0x48, 0x79, 0x71, 0xaa, 0x7f, 0x89, 0xef, 0xd0,
+       0x39, 0x81, 0xee, 0xfd, 0x11, 0xe8, 0xa3, 0x35, 0xf7, 0xa9, 0x85, 0xed,
+       0xd7, 0x14, 0x2c, 0x78, 0x97, 0x04, 0xad, 0xa7, 0x68, 0x8d, 0xb3, 0x07,
+       0xc4, 0x9f, 0x54, 0xa1, 0x92, 0xc0, 0xdb, 0x96, 0x29, 0xd9, 0x48, 0xa6,
+       0xbc, 0x23, 0x49, 0xdb, 0x23, 0x0d, 0xe7, 0xea, 0xa0, 0x39, 0xd2, 0xd7,
+       0xfa, 0x52, 0x74, 0x5f, 0x51, 0xf6, 0xab, 0xc5, 0x82, 0x04, 0x7e, 0x6c,
+       0xf8, 0x64, 0xca, 0x11, 0xca, 0xc4, 0xf3, 0x0e, 0xdf, 0x67, 0x0c, 0xad,
+       0xda, 0xd9, 0x6b, 0xcb, 0xb9, 0x4c, 0x37, 0xfa, 0x43, 0xd1, 0x4e, 0xd9,
+       0xfb, 0xb8, 0x57, 0x3b, 0x9f, 0xdb, 0xdf, 0x9c, 0x07, 0xf6, 0x8e, 0xa4,
+       0x56, 0xc1, 0xb9, 0xee, 0x78, 0xd6, 0x9c, 0x8f, 0x3a, 0x72, 0xef, 0x88,
+       0xe7, 0xd9, 0xd5, 0xf5, 0xa9, 0x2f, 0xe8, 0xda, 0xf2, 0x71, 0x4e, 0xff,
+       0xe7, 0x98, 0xdf, 0xe8, 0x4a, 0x49, 0x09, 0xe3, 0x08, 0xcf, 0x7d, 0xbe,
+       0xcf, 0x20, 0x06, 0xf9, 0xac, 0x24, 0x3c, 0xe7, 0x4a, 0x27, 0x7c, 0xc6,
+       0x96, 0xfd, 0x5a, 0x77, 0x22, 0xc7, 0x6a, 0x9c, 0x7f, 0x31, 0x7b, 0x46,
+       0x0c, 0x27, 0x88, 0xe1, 0x04, 0x31, 0x9d, 0x20, 0x8e, 0x13, 0xf1, 0x54,
+       0xd5, 0x97, 0xab, 0x73, 0xae, 0xdc, 0xb0, 0x11, 0x0b, 0x83, 0x05, 0xef,
+       0x4d, 0xc4, 0x63, 0xec, 0x59, 0x62, 0x87, 0xf1, 0x7c, 0x41, 0xf8, 0x8e,
+       0x38, 0x74, 0xe2, 0xb2, 0x8d, 0x38, 0x8c, 0x8f, 0x71, 0xae, 0x28, 0x6b,
+       0xe6, 0xbc, 0x0b, 0xde, 0x29, 0xa1, 0x9f, 0x6b, 0x58, 0x9b, 0xf6, 0x4f,
+       0x31, 0x60, 0xc7, 0x6a, 0x58, 0xa7, 0xac, 0xc0, 0x6b, 0x81, 0xa2, 0x9d,
+       0x7c, 0x8c, 0x1c, 0x2a, 0x21, 0x6f, 0xe6, 0xca, 0x4a, 0x2c, 0x59, 0x5f,
+       0x84, 0xbd, 0x16, 0x69, 0x57, 0xe6, 0x10, 0x63, 0xf2, 0xef, 0xb3, 0x4e,
+       0x78, 0x12, 0xb1, 0x07, 0x5a, 0xd8, 0xe8, 0x54, 0x32, 0x07, 0xfe, 0xc5,
+       0x22, 0x75, 0xdd, 0x8a, 0x1c, 0xe9, 0x24, 0x57, 0x55, 0x21, 0xfc, 0xa7,
+       0x92, 0xfd, 0x41, 0x2b, 0x86, 0x7f, 0x95, 0x52, 0x25, 0x6e, 0xfd, 0xda,
+       0x00, 0x32, 0x8d, 0xfe, 0x0e, 0xf8, 0xca, 0x99, 0xfe, 0xf4, 0x8d, 0xc8,
+       0x66, 0x37, 0x88, 0x96, 0xa1, 0xdb, 0x35, 0xc4, 0x0e, 0xfd, 0x72, 0x09,
+       0xb6, 0x69, 0x77, 0x2d, 0xe6, 0xbe, 0xb4, 0xfb, 0xa4, 0x33, 0x30, 0xb1,
+       0xe6, 0x54, 0x65, 0xb5, 0xdd, 0x3d, 0xa9, 0xed, 0x50, 0xd6, 0x0a, 0x55,
+       0xfa, 0x76, 0x7c, 0x09, 0xbe, 0x5a, 0x6d, 0xf7, 0xa7, 0x1e, 0xdf, 0xec,
+       0x4a, 0xeb, 0xeb, 0x55, 0x69, 0xd9, 0x15, 0x75, 0xb7, 0x92, 0x09, 0xc8,
+       0xad, 0x62, 0x1f, 0xc6, 0x64, 0xe0, 0xd7, 0xed, 0xa9, 0xc7, 0x2f, 0x76,
+       0xef, 0x47, 0xce, 0xcb, 0x67, 0xb5, 0x4a, 0x08, 0x9b, 0x5f, 0xbb, 0xd7,
+       0x96, 0x50, 0x36, 0x06, 0xae, 0xd4, 0x92, 0x29, 0xe9, 0x0c, 0x24, 0x7e,
+       0x6a, 0x0e, 0xfb, 0x55, 0xf0, 0x3e, 0x58, 0x94, 0xd6, 0x60, 0x6a, 0x4d,
+       0x55, 0x5b, 0x12, 0x0f, 0x3a, 0xf8, 0xbb, 0xd2, 0xe8, 0xba, 0xee, 0xc5,
+       0x6e, 0x8b, 0xfc, 0xae, 0x55, 0xf5, 0xdd, 0x43, 0xfd, 0x9b, 0x8c, 0x2d,
+       0xc8, 0x19, 0xfd, 0x9e, 0xaa, 0x3a, 0xd2, 0x2c, 0x95, 0x20, 0xc3, 0x82,
+       0x4d, 0xa8, 0xeb, 0x3c, 0xf6, 0x4d, 0xc7, 0xd6, 0x80, 0xfe, 0x2b, 0x4a,
+       0x3b, 0x5a, 0x84, 0x9d, 0x60, 0x77, 0xaf, 0x28, 0x1b, 0xe1, 0xa7, 0xfa,
+       0xd9, 0x28, 0x80, 0x8f, 0xf4, 0xfd, 0x35, 0x60, 0x51, 0x0d, 0x26, 0x7d,
+       0x39, 0x2c, 0xcb, 0x29, 0xec, 0x9b, 0xf2, 0x75, 0xa0, 0x03, 0xf9, 0x26,
+       0xc0, 0xd7, 0x00, 0x5f, 0x49, 0x4e, 0x1b, 0xde, 0x09, 0xf0, 0xde, 0xcc,
+       0x78, 0x17, 0xca, 0xcb, 0x12, 0x81, 0x67, 0xda, 0x5f, 0x86, 0x3f, 0xd7,
+       0x4a, 0x0d, 0xf0, 0x36, 0xa0, 0x03, 0xc6, 0x44, 0x5a, 0x4e, 0x85, 0x72,
+       0x83, 0xf2, 0xb3, 0xcc, 0x25, 0x23, 0xb3, 0x05, 0x99, 0xd0, 0x2b, 0x71,
+       0x21, 0x67, 0x09, 0xe3, 0x07, 0xba, 0x9d, 0x00, 0xb3, 0x4a, 0x7c, 0x7e,
+       0x47, 0xab, 0x2a, 0xe2, 0xb8, 0x12, 0xfa, 0x6d, 0xe1, 0xfb, 0x88, 0xd4,
+       0x91, 0xa3, 0x2a, 0x9c, 0x90, 0xa6, 0x67, 0x59, 0xaa, 0x6a, 0x4b, 0x13,
+       0x51, 0x1c, 0xaf, 0x3a, 0x66, 0x6e, 0x0d, 0x71, 0xa6, 0xaa, 0x5b, 0x76,
+       0x5a, 0x4f, 0x0a, 0xa0, 0x19, 0xc1, 0xfc, 0x38, 0x6c, 0x30, 0x09, 0xda,
+       0x5f, 0x62, 0x7e, 0x06, 0xf8, 0x3b, 0x09, 0x1a, 0x8e, 0xcc, 0x23, 0xda,
+       0x85, 0xf4, 0x15, 0xe8, 0x98, 0xcf, 0x55, 0x60, 0x9b, 0xe1, 0xd4, 0xca,
+       0x7d, 0x0c, 0x9a, 0xc4, 0xc9, 0x72, 0x73, 0x38, 0xdf, 0xf2, 0x75, 0x1f,
+       0xeb, 0xd7, 0xbe, 0xa1, 0xe4, 0xa6, 0xbe, 0x18, 0x32, 0x86, 0xe5, 0xd3,
+       0x46, 0x18, 0x4f, 0xda, 0x06, 0x23, 0x72, 0xac, 0xe0, 0xc8, 0x5a, 0x72,
+       0xf9, 0xe0, 0x7a, 0x68, 0xd9, 0x9d, 0xc5, 0x03, 0xd2, 0x2a, 0x05, 0x51,
+       0x1d, 0xfe, 0xee, 0x24, 0xcc, 0x8d, 0x09, 0x9c, 0x3b, 0x40, 0xd4, 0x4d,
+       0xe3, 0x39, 0xbe, 0x17, 0x3c, 0xf0, 0x63, 0x0b, 0xb2, 0x38, 0x22, 0x66,
+       0x92, 0x00, 0x3a, 0xc2, 0x1e, 0xe1, 0x82, 0x77, 0x84, 0xf1, 0x58, 0xe2,
+       0x1a, 0x6b, 0xd4, 0x65, 0xd4, 0xa8, 0x20, 0x6a, 0x66, 0xb9, 0xf2, 0x2e,
+       0x6c, 0xdb, 0x4e, 0x58, 0x6f, 0xca, 0xc8, 0x15, 0xd6, 0x1b, 0xe6, 0x07,
+       0x63, 0x25, 0xc7, 0x67, 0xf0, 0x84, 0xcc, 0x4f, 0x37, 0xc3, 0xe9, 0x5a,
+       0x86, 0xc1, 0x4b, 0xd0, 0x43, 0xeb, 0x27, 0x80, 0xbf, 0xed, 0xc8, 0xc4,
+       0x67, 0xcb, 0x57, 0xb7, 0xf4, 0xf4, 0x2c, 0x6d, 0xae, 0xf5, 0x89, 0x68,
+       0x19, 0xb4, 0x7f, 0x83, 0xbd, 0x56, 0x80, 0xc1, 0xc4, 0x6d, 0xee, 0x5d,
+       0x75, 0x6b, 0xdd, 0x7d, 0xd0, 0xc5, 0x07, 0x36, 0xc2, 0x06, 0x06, 0xab,
+       0x47, 0x91, 0xef, 0xcc, 0xf9, 0xc0, 0x5f, 0x13, 0xce, 0xcb, 0xa8, 0xc2,
+       0x7b, 0x13, 0x7e, 0xea, 0x54, 0x8e, 0x5a, 0x8d, 0xed, 0x31, 0x27, 0xab,
+       0xf9, 0x13, 0x0a, 0x75, 0xa8, 0x59, 0x22, 0xdf, 0x08, 0xf8, 0xf6, 0x81,
+       0x67, 0x14, 0x6b, 0x05, 0x8c, 0xc3, 0x72, 0x0c, 0xe6, 0x63, 0x2f, 0x1f,
+       0x7b, 0xad, 0x88, 0x53, 0x7d, 0x05, 0xf8, 0x33, 0xe3, 0x37, 0xe4, 0x57,
+       0x76, 0x5a, 0x63, 0xe9, 0x9b, 0xef, 0x0c, 0xf9, 0xc6, 0x17, 0xdb, 0xe4,
+       0xe0, 0x23, 0x59, 0x4c, 0x11, 0x57, 0x1f, 0xce, 0xd6, 0x4b, 0xc0, 0xc7,
+       0x6f, 0x66, 0xf8, 0xef, 0x12, 0x2b, 0xe5, 0x8c, 0xc1, 0xca, 0x11, 0x62,
+       0x25, 0x70, 0xa5, 0xb5, 0x04, 0x7b, 0x47, 0x1f, 0x03, 0x5f, 0xea, 0xf0,
+       0xc4, 0x6f, 0xbb, 0x0e, 0xe2, 0xca, 0x06, 0x3f, 0xeb, 0xf8, 0x77, 0xa1,
+       0x5b, 0xe0, 0x7d, 0x0c, 0xbc, 0x89, 0x8f, 0x31, 0x0f, 0xb4, 0x46, 0xae,
+       0x03, 0xab, 0x66, 0xcb, 0xa7, 0x10, 0xf7, 0x36, 0x70, 0x02, 0x15, 0x19,
+       0xfb, 0xe6, 0x35, 0x37, 0xaf, 0xff, 0xfc, 0xbd, 0x6f, 0xc1, 0xcd, 0xa8,
+       0x93, 0x47, 0x21, 0x63, 0xc6, 0x3f, 0x02, 0x3f, 0x6e, 0x2c, 0x7d, 0x19,
+       0xcf, 0x1f, 0x33, 0x1e, 0xad, 0x1b, 0x15, 0xee, 0x2b, 0xd2, 0xe8, 0xd3,
+       0x0e, 0x11, 0xec, 0x60, 0x30, 0x08, 0x39, 0x1f, 0x21, 0xe7, 0x45, 0x9a,
+       0xc4, 0x0a, 0x60, 0x18, 0x71, 0x6f, 0x03, 0xf4, 0xaa, 0x52, 0x84, 0x5d,
+       0x11, 0x4b, 0x4a, 0x5c, 0xa7, 0x7a, 0xcc, 0xed, 0x80, 0xb6, 0x50, 0x5d,
+       0x75, 0xb7, 0xc2, 0x17, 0x73, 0xdb, 0x03, 0xc7, 0xc4, 0xaa, 0xa5, 0x7e,
+       0xce, 0xe8, 0x1e, 0xcf, 0xe8, 0x56, 0x86, 0xe9, 0x30, 0xdf, 0xc8, 0xe6,
+       0x63, 0xcc, 0xcf, 0x65, 0x36, 0x67, 0x3d, 0x70, 0x51, 0xa3, 0x59, 0x0b,
+       0x02, 0xdf, 0x57, 0x88, 0xb5, 0x3b, 0xd6, 0x81, 0xa5, 0x21, 0xec, 0x16,
+       0x65, 0x7a, 0x92, 0x12, 0x63, 0x72, 0xf8, 0xac, 0xa3, 0x28, 0x34, 0xbb,
+       0xf1, 0x89, 0xdf, 0xdb, 0xd9, 0x3e, 0xa4, 0x25, 0x5e, 0x0f, 0xd3, 0x22,
+       0x8d, 0x42, 0xd6, 0xd4, 0xdb, 0xd9, 0xec, 0x00, 0xd6, 0x90, 0xf3, 0x89,
+       0x2d, 0x8f, 0x3a, 0xcc, 0xef, 0xc3, 0x05, 0x73, 0x0e, 0xd6, 0xe0, 0x9d,
+       0x29, 0x83, 0x33, 0x2b, 0xdd, 0x22, 0x80, 0x7d, 0x5c, 0x8e, 0x23, 0x9f,
+       0x9f, 0x85, 0xef, 0x2f, 0x46, 0x0a, 0x9d, 0x06, 0x6b, 0x8e, 0x46, 0x1c,
+       0x06, 0xc6, 0x17, 0xb5, 0x70, 0x03, 0x91, 0xfc, 0x8a, 0x5c, 0x5b, 0x1c,
+       0x93, 0xc2, 0x25, 0xea, 0xe0, 0x88, 0xb3, 0x39, 0xbc, 0xcf, 0x02, 0xf6,
+       0x99, 0x02, 0x06, 0x3e, 0x82, 0xfa, 0x52, 0x12, 0x67, 0x16, 0x58, 0x9b,
+       0xb8, 0x56, 0x1d, 0xf2, 0xd5, 0x25, 0x9e, 0x9f, 0x18, 0xec, 0x66, 0xb5,
+       0x8d, 0xb9, 0x55, 0x14, 0xbb, 0xf7, 0x67, 0xe4, 0xae, 0x92, 0xf5, 0x8a,
+       0xd6, 0x47, 0xa2, 0xf7, 0x60, 0x5f, 0xcc, 0x6d, 0x72, 0xed, 0x26, 0xe6,
+       0x39, 0x47, 0x19, 0x8c, 0xc5, 0x03, 0xa8, 0x6b, 0xd8, 0xf3, 0x18, 0x79,
+       0x8a, 0xa2, 0x7a, 0xc4, 0x7f, 0x8c, 0x9b, 0x7c, 0xe7, 0x99, 0x88, 0x6d,
+       0x36, 0xc6, 0x31, 0x8c, 0x3c, 0xd3, 0x47, 0x99, 0xaf, 0xf8, 0xac, 0xb5,
+       0x53, 0x1d, 0x97, 0x7a, 0x37, 0x04, 0xc6, 0xce, 0x94, 0x8f, 0x0b, 0xd7,
+       0xf0, 0xde, 0xe7, 0xbc, 0x37, 0x34, 0x8f, 0xe7, 0xbe, 0xd1, 0x59, 0x9c,
+       0xdd, 0xde, 0x67, 0x03, 0x86, 0x2d, 0x60, 0x1f, 0xf6, 0x39, 0xac, 0x7f,
+       0x06, 0xb7, 0xe6, 0xd9, 0xb7, 0x5c, 0xee, 0xb2, 0x16, 0x3a, 0xcc, 0xcb,
+       0x7b, 0x94, 0x1c, 0x90, 0x7a, 0x29, 0x3f, 0x17, 0xe2, 0x38, 0x22, 0xff,
+       0x34, 0xfb, 0x19, 0x8d, 0xbc, 0x2b, 0xdb, 0xa6, 0x6f, 0x9c, 0x89, 0xd9,
+       0x3f, 0x5c, 0xee, 0x23, 0x97, 0x7b, 0x5a, 0x9a, 0xa9, 0x2c, 0x6f, 0x15,
+       0xfd, 0x6f, 0xed, 0x35, 0xd6, 0x40, 0xda, 0xf9, 0x5e, 0xf8, 0x06, 0x18,
+       0xbd, 0xe9, 0xc8, 0xc5, 0x6e, 0x2a, 0x8b, 0x39, 0xf5, 0x42, 0x26, 0xaf,
+       0x21, 0x7f, 0x80, 0x1c, 0xf6, 0x25, 0xec, 0x31, 0xd1, 0x53, 0x9e, 0x73,
+       0x20, 0x8f, 0x36, 0xc0, 0xb5, 0xa0, 0x37, 0x9f, 0xe9, 0x1b, 0x80, 0xce,
+       0x81, 0x4d, 0x69, 0x4b, 0xca, 0x62, 0xac, 0xfd, 0x5b, 0x13, 0x3f, 0x50,
+       0x37, 0xb0, 0x07, 0xde, 0x07, 0x23, 0xe0, 0x99, 0x92, 0x57, 0x13, 0x83,
+       0xa5, 0xde, 0x09, 0x60, 0x52, 0xa3, 0xfb, 0x8f, 0xbc, 0xb6, 0xc4, 0x6d,
+       0xe0, 0xeb, 0xf3, 0x32, 0x2e, 0xce, 0xce, 0xb8, 0xbc, 0x80, 0x5e, 0xb0,
+       0xd0, 0x43, 0x1d, 0x87, 0x0d, 0xd5, 0xd9, 0xd6, 0x3c, 0xfb, 0xb9, 0xb7,
+       0xd8, 0x17, 0x55, 0xc2, 0xc8, 0xb6, 0x66, 0xe5, 0xcc, 0xcf, 0x82, 0xf9,
+       0x6d, 0x93, 0xaf, 0x58, 0xdf, 0xf1, 0xe5, 0x74, 0x3f, 0x94, 0x33, 0x7d,
+       0x0f, 0x7a, 0x79, 0xbb, 0x3d, 0xaf, 0x0a, 0x89, 0xa7, 0x0d, 0xfc, 0x89,
+       0x97, 0x3c, 0x17, 0x6c, 0x5c, 0xa5, 0x4d, 0xd8, 0xe3, 0xd2, 0x7f, 0xc4,
+       0xaf, 0xa3, 0x78, 0x1e, 0x13, 0x1b, 0x67, 0x52, 0x3d, 0xda, 0x82, 0xf6,
+       0x1f, 0xee, 0x93, 0x89, 0x6d, 0x9e, 0xe9, 0x1d, 0x9b, 0x49, 0x9e, 0x7b,
+       0x79, 0x2e, 0x32, 0xcf, 0x1d, 0x6b, 0x19, 0xf6, 0xba, 0x1e, 0x31, 0x1f,
+       0x6f, 0xe9, 0xeb, 0xa6, 0x3f, 0xf3, 0xd8, 0x33, 0x0f, 0xf5, 0x67, 0x79,
+       0x5f, 0xc3, 0x78, 0x2c, 0x0f, 0xe5, 0xe3, 0x0d, 0x93, 0x8b, 0x57, 0x90,
+       0x97, 0xaf, 0x27, 0x65, 0x93, 0x93, 0x87, 0x0e, 0xdf, 0x2e, 0x27, 0x7f,
+       0xfd, 0x15, 0x72, 0xf2, 0xed, 0x2c, 0x27, 0x47, 0x4c, 0xdc, 0xaa, 0xde,
+       0xf0, 0xda, 0x6f, 0xb0, 0xc6, 0x39, 0xde, 0x37, 0x58, 0x43, 0xd1, 0xff,
+       0x3f, 0x4c, 0x1f, 0xe5, 0xfe, 0x49, 0xe3, 0xb0, 0xee, 0x90, 0x06, 0x3e,
+       0xec, 0x8d, 0x8b, 0x7d, 0x96, 0x39, 0x9b, 0xc7, 0x8c, 0x8f, 0x58, 0xcd,
+       0xf9, 0xd1, 0x4f, 0x1e, 0x63, 0x2c, 0x14, 0x4c, 0x5e, 0xd8, 0xd5, 0x9c,
+       0xa6, 0x2c, 0xcb, 0xe8, 0xd5, 0xde, 0xe3, 0xd8, 0x4f, 0x63, 0x65, 0xa4,
+       0xe7, 0xca, 0x4b, 0x73, 0xc4, 0xa6, 0x20, 0xba, 0x06, 0x9d, 0xaf, 0x87,
+       0x25, 0x29, 0xcc, 0x32, 0x5f, 0x59, 0x6d, 0x46, 0x10, 0x43, 0xb8, 0x77,
+       0x25, 0xfa, 0x24, 0xfa, 0x29, 0xdf, 0x81, 0x9f, 0x5f, 0x47, 0x1c, 0x11,
+       0x3b, 0x11, 0x13, 0xf3, 0x9b, 0x88, 0x89, 0xe3, 0x7c, 0x37, 0xfb, 0x16,
+       0x0c, 0xad, 0x6d, 0xf6, 0x2f, 0x41, 0x7f, 0x57, 0x8a, 0xe7, 0x34, 0xee,
+       0x5b, 0x9f, 0xf3, 0x9d, 0x36, 0xf1, 0x0b, 0xac, 0xc0, 0xfc, 0xba, 0x89,
+       0x5f, 0xfa, 0x34, 0xf0, 0x88, 0xf3, 0x7f, 0x32, 0xb9, 0xf1, 0xa1, 0xc9,
+       0xf1, 0xeb, 0x91, 0x89, 0xe7, 0x88, 0xfd, 0xe4, 0xe9, 0xfe, 0xfb, 0x05,
+       0x83, 0x01, 0xc8, 0x8f, 0x53, 0x91, 0x89, 0xb5, 0xf9, 0x2b, 0x38, 0xf6,
+       0x9b, 0x69, 0x2e, 0x0c, 0xc9, 0x99, 0xf6, 0x1e, 0x4b, 0x73, 0xcb, 0xdf,
+       0x30, 0x77, 0x8a, 0x19, 0xf4, 0x43, 0xa0, 0xeb, 0xef, 0xc5, 0x83, 0x49,
+       0x8c, 0xb4, 0xf7, 0x27, 0x90, 0xeb, 0xc1, 0x86, 0x94, 0x43, 0xbd, 0xa9,
+       0xd7, 0xb8, 0x84, 0x67, 0x73, 0x9d, 0x3e, 0x31, 0xba, 0xfc, 0xaf, 0x3c,
+       0xac, 0xef, 0xdc, 0x8e, 0xcf, 0x1b, 0xe2, 0xfb, 0xeb, 0x6d, 0xf8, 0xb0,
+       0xbe, 0x43, 0x9e, 0xb1, 0xdd, 0x5e, 0xa2, 0xbe, 0x1b, 0xd7, 0x31, 0xe2,
+       0x9e, 0xbc, 0x7b, 0xef, 0x79, 0xc3, 0x39, 0x90, 0xd7, 0x70, 0xc6, 0x39,
+       0xf7, 0xcc, 0x63, 0x3d, 0x8f, 0xf1, 0x3c, 0xe6, 0xf3, 0x58, 0x0f, 0xa2,
+       0xe7, 0x24, 0xf5, 0xaf, 0xd3, 0x0b, 0xb0, 0xff, 0xd8, 0x1d, 0xee, 0x26,
+       0x5f, 0x56, 0x8f, 0x24, 0xfe, 0xfc, 0x1e, 0xf8, 0xfb, 0xac, 0x67, 0x74,
+       0x99, 0x6b, 0xf8, 0xb3, 0x4f, 0xbf, 0x89, 0xfa, 0x1f, 0x65, 0xb6, 0x8d,
+       0xb3, 0x31, 0xa5, 0x49, 0xfb, 0xbd, 0x9f, 0x64, 0x98, 0xfb, 0xfd, 0xb4,
+       0xbe, 0x48, 0x9e, 0x53, 0xcc, 0x21, 0x93, 0x53, 0x3c, 0x0f, 0xee, 0xe8,
+       0x5a, 0xaf, 0xc2, 0x8f, 0x2f, 0x45, 0x79, 0x1e, 0x21, 0x9e, 0x0e, 0xe7,
+       0x39, 0x0e, 0x3b, 0x85, 0xb7, 0xb4, 0x33, 0x1b, 0xc3, 0x66, 0xbc, 0x17,
+       0x37, 0xd0, 0x1b, 0xd1, 0x4e, 0x2b, 0xd6, 0x13, 0xbb, 0x77, 0xe1, 0xbd,
+       0x7d, 0x10, 0xed, 0x46, 0xbb, 0x0e, 0xdb, 0x2d, 0x88, 0x26, 0x15, 0x31,
+       0xe0, 0x76, 0x38, 0x91, 0xd7, 0x6b, 0x60, 0xd0, 0x6c, 0x6e, 0xa7, 0xaf,
+       0x5c, 0xb3, 0xe3, 0xf4, 0x3b, 0xc2, 0x5e, 0x7c, 0xd8, 0xb4, 0x87, 0xf0,
+       0xe1, 0x36, 0x3d, 0x25, 0x65, 0xd0, 0x06, 0xa8, 0x5f, 0xa6, 0xcf, 0x60,
+       0x0f, 0x79, 0x4b, 0xdb, 0xa6, 0x9f, 0x24, 0x36, 0xb2, 0x8f, 0xec, 0x8c,
+       0xc8, 0xd8, 0x3e, 0xf3, 0x1e, 0x6f, 0x73, 0x64, 0x4c, 0x48, 0x5a, 0x97,
+       0x8c, 0xfe, 0xcf, 0x64, 0xfa, 0xa7, 0x3a, 0x8b, 0xba, 0x13, 0xa6, 0x51,
+       0x57, 0x0f, 0xba, 0x3e, 0x94, 0xdb, 0xa5, 0xa5, 0xaa, 0x27, 0xa4, 0x51,
+       0x31, 0x77, 0x5b, 0xdc, 0xa5, 0xa0, 0xc3, 0x12, 0xf5, 0x28, 0x43, 0x8f,
+       0x71, 0xdc, 0x3d, 0x82, 0x95, 0x96, 0x04, 0xf1, 0x1a, 0x08, 0xe7, 0x7e,
+       0x4a, 0xbb, 0x3d, 0xed, 0x6e, 0x75, 0x69, 0xb7, 0x27, 0xdd, 0x4e, 0x77,
+       0x1a, 0xfd, 0x5f, 0x00, 0x6f, 0x07, 0xf3, 0x97, 0x84, 0x31, 0xb6, 0x10,
+       0x71, 0x3c, 0x2d, 0xec, 0xb7, 0x9e, 0x76, 0x67, 0xfa, 0x1c, 0x9f, 0x74,
+       0xc3, 0xfe, 0xb0, 0xdc, 0xbf, 0x68, 0x60, 0x62, 0x7c, 0x03, 0x79, 0xf4,
+       0xea, 0x20, 0xdd, 0x1b, 0xf7, 0xbf, 0x4c, 0x2e, 0xe6, 0x92, 0x5c, 0xb6,
+       0x10, 0xa7, 0x28, 0x1b, 0x72, 0xa7, 0xa3, 0xdf, 0x99, 0x3d, 0x78, 0xff,
+       0xb9, 0xd3, 0x1e, 0x77, 0xe7, 0xdf, 0x2e, 0x90, 0x3b, 0x05, 0x83, 0x3d,
+       0x1b, 0x09, 0xee, 0xcc, 0x25, 0xad, 0x9b, 0xe1, 0x87, 0xb0, 0x1d, 0x7a,
+       0x80, 0x45, 0x0f, 0x7f, 0xe0, 0xea, 0x2a, 0xd7, 0xd0, 0x67, 0xe3, 0xae,
+       0xc7, 0xfb, 0xda, 0x46, 0xc2, 0x35, 0xc6, 0x38, 0x7a, 0xc1, 0xc5, 0x8f,
+       0x40, 0xfb, 0x81, 0x6e, 0x0d, 0x94, 0xb9, 0x8f, 0xab, 0x10, 0xf7, 0xac,
+       0x01, 0xfb, 0x15, 0xb1, 0x1a, 0x89, 0xf8, 0xcd, 0x68, 0xc9, 0xdc, 0xc7,
+       0x62, 0xcf, 0xe7, 0x9d, 0x13, 0x3d, 0xe6, 0xe2, 0x50, 0x8f, 0xb9, 0x88,
+       0x1e, 0xf3, 0x9e, 0x22, 0xe2, 0x3c, 0xc6, 0x3d, 0x53, 0x35, 0xd3, 0xbc,
+       0x99, 0xe0, 0x9d, 0xb2, 0x5d, 0x92, 0x7d, 0xe8, 0x9e, 0xa0, 0x5b, 0x88,
+       0xfd, 0xb9, 0x7e, 0x30, 0xfb, 0xee, 0x85, 0x4d, 0xc7, 0x62, 0xd3, 0x6f,
+       0xb5, 0x4b, 0x23, 0xa8, 0xff, 0xa4, 0xb9, 0x2f, 0xa3, 0x79, 0x6e, 0x0f,
+       0xcd, 0xd7, 0x78, 0x46, 0xca, 0x96, 0xe6, 0x1b, 0xcc, 0x3b, 0xd6, 0xd2,
+       0x91, 0x2c, 0xdf, 0x4e, 0xe0, 0xb9, 0x98, 0x3d, 0xe7, 0xf4, 0x87, 0xf7,
+       0xf0, 0x3f, 0xa2, 0xd2, 0x77, 0x3e, 0x53, 0xe7, 0x98, 0x7d, 0x30, 0xe4,
+       0x2d, 0x59, 0xe9, 0xb7, 0x92, 0xf3, 0x38, 0x3b, 0x7d, 0x92, 0xf6, 0x17,
+       0xc0, 0x60, 0x74, 0x57, 0x33, 0xb0, 0xbb, 0xd6, 0xed, 0x25, 0xe2, 0xda,
+       0xc2, 0xfc, 0x11, 0x83, 0x6f, 0x6a, 0x4a, 0x49, 0x8e, 0xb9, 0xc3, 0xcf,
+       0x18, 0x97, 0xcc, 0x37, 0x01, 0xbc, 0xa7, 0x32, 0xb6, 0x70, 0x3f, 0x16,
+       0xe4, 0x70, 0xcb, 0xe8, 0x65, 0xa5, 0xf7, 0x1e, 0xaf, 0xc6, 0x7a, 0x80,
+       0xba, 0xf1, 0x20, 0xf5, 0xda, 0xfd, 0x76, 0xb1, 0x86, 0x5a, 0xf3, 0x2e,
+       0x62, 0x1f, 0xf9, 0x69, 0x7a, 0xa8, 0x2d, 0xf3, 0xed, 0x00, 0x75, 0x08,
+       0xd7, 0xa0, 0x4e, 0xb8, 0xfb, 0x0d, 0x41, 0x2e, 0x80, 0xe6, 0x22, 0xd6,
+       0x4e, 0xf7, 0xf3, 0x9e, 0x16, 0x7d, 0x3c, 0x70, 0x6f, 0x3d, 0xfc, 0x97,
+       0x6e, 0x96, 0x86, 0x69, 0xf9, 0xfb, 0x2f, 0xb4, 0x78, 0xd5, 0x79, 0x38,
+       0x15, 0x00, 0x00, 0x00 };
 
 static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 };
-static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 };
+static const u32 bnx2_TPAT_b09FwRodata[(0x4/4) + 1] = {
+       0x00000001, 0x00000000 };
 
 static struct fw_info bnx2_tpat_fw_09 = {
-       /* Firmware version:  3.7.1 */
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x7,
-       .ver_fix                        = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x08000860,
+       .start_addr                     = 0x08000888,
 
        .text_addr                      = 0x08000800,
-       .text_len                       = 0x188c,
+       .text_len                       = 0x1534,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TPAT_b09FwText,
        .gz_text_len                    = sizeof(bnx2_TPAT_b09FwText),
 
-       .data_addr                      = 0x080020c0,
+       .data_addr                      = 0x00000000,
        .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_TPAT_b09FwData,
 
-       .sbss_addr                      = 0x080020c8,
-       .sbss_len                       = 0x30,
+       .sbss_addr                      = 0x08001d60,
+       .sbss_len                       = 0x48,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08002100,
-       .bss_len                        = 0x850,
+       .bss_addr                       = 0x08001da8,
+       .bss_len                        = 0x10a0,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x00000000,
-       .rodata_len                     = 0x0,
+       .rodata_addr                    = 0x08001d34,
+       .rodata_len                     = 0x4,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_TPAT_b09FwRodata,
 };
 
 static u8 bnx2_TXP_b09FwText[] = {
-       0xbd, 0x7c, 0x7d, 0x70, 0x1c, 0xe7, 0x79, 0xdf, 0xb3, 0xbb, 0x07, 0xe0,
-       0x00, 0x82, 0xe0, 0x12, 0x39, 0x52, 0x27, 0x0a, 0xa6, 0x6e, 0x89, 0x3d,
-       0x08, 0x32, 0x20, 0x71, 0xc5, 0x20, 0x36, 0x26, 0xb9, 0xca, 0xab, 0xbb,
-       0x03, 0x78, 0x94, 0x31, 0x31, 0xc4, 0xc2, 0x16, 0xed, 0x70, 0xd4, 0xeb,
-       0x01, 0xa4, 0x95, 0x54, 0x9e, 0xb2, 0xb6, 0xda, 0x72, 0x5a, 0x35, 0x3a,
-       0x1f, 0xc0, 0x0f, 0x29, 0x47, 0x1c, 0x24, 0xc0, 0x84, 0xfe, 0x70, 0x93,
-       0x13, 0x0e, 0x24, 0x64, 0xf7, 0x88, 0x93, 0xfc, 0xd9, 0x3f, 0x62, 0x0b,
-       0x03, 0xd2, 0xb4, 0x5a, 0xbb, 0xb5, 0xda, 0x28, 0x13, 0xcf, 0xf4, 0x63,
-       0x30, 0x14, 0xa5, 0x28, 0x71, 0xa7, 0x56, 0x9b, 0x4c, 0xa2, 0x36, 0x94,
-       0xaf, 0xbf, 0xdf, 0xbb, 0xbb, 0xe0, 0x01, 0x22, 0x65, 0x51, 0x93, 0x14,
-       0x33, 0x37, 0x77, 0xfb, 0xee, 0xbb, 0xef, 0xfb, 0x7c, 0xbd, 0xcf, 0xf3,
-       0xfc, 0x9e, 0xf7, 0x5d, 0x44, 0x45, 0xda, 0xc4, 0xff, 0xdb, 0x8a, 0x4f,
-       0xec, 0xd8, 0xf1, 0xc7, 0xef, 0xfd, 0xf8, 0xbd, 0xbf, 0x8a, 0x9f, 0xf7,
-       0x89, 0xd6, 0x62, 0xf0, 0xe6, 0x5b, 0x86, 0x48, 0xf6, 0xcf, 0xe5, 0x43,
-       0xff, 0xe1, 0x71, 0x33, 0x18, 0x9f, 0x1f, 0x09, 0xeb, 0x89, 0x57, 0x87,
-       0x93, 0xb6, 0x84, 0x8d, 0x44, 0xfe, 0xa1, 0x71, 0x5b, 0xc4, 0xad, 0xf6,
-       0xc5, 0x52, 0xf2, 0x6e, 0x3d, 0x1f, 0x09, 0x09, 0xdb, 0x3f, 0x92, 0xb8,
-       0xf6, 0xe4, 0xf7, 0x3e, 0x6e, 0xbd, 0x5d, 0x36, 0x24, 0x6c, 0x26, 0xb2,
-       0x62, 0xf6, 0x48, 0xb8, 0x0b, 0xcf, 0x7c, 0xf5, 0xae, 0x47, 0x0d, 0xe9,
-       0x08, 0xc6, 0x7a, 0xab, 0xfe, 0xbd, 0xbb, 0x24, 0xbf, 0x2b, 0x51, 0x8f,
-       0x85, 0x12, 0xef, 0xd6, 0xa7, 0x06, 0xc2, 0xa2, 0x27, 0xac, 0x68, 0xd2,
-       0x88, 0xc8, 0xcb, 0x35, 0x53, 0x5e, 0xac, 0xc5, 0x64, 0xb2, 0x26, 0x1d,
-       0xe9, 0xda, 0x8d, 0x68, 0xaa, 0xa3, 0xef, 0xbb, 0xf5, 0xe4, 0x40, 0x28,
-       0x6b, 0x24, 0xa4, 0x23, 0x59, 0x93, 0xd1, 0x63, 0xc5, 0xd6, 0x87, 0x9b,
-       0x12, 0x4f, 0xd6, 0x75, 0x5b, 0xb2, 0xa1, 0x84, 0x9d, 0xd7, 0xf5, 0xf6,
-       0x41, 0xf3, 0x63, 0x68, 0xaf, 0x0e, 0x86, 0x26, 0x8b, 0xa6, 0x9c, 0x1b,
-       0x68, 0x15, 0xdd, 0x0e, 0x4b, 0xb2, 0xd6, 0xfa, 0xb0, 0x9e, 0x88, 0x88,
-       0x5b, 0xab, 0xd7, 0x8f, 0x39, 0xff, 0x64, 0xaf, 0xf9, 0xeb, 0xe1, 0xf0,
-       0x64, 0x51, 0xde, 0x0e, 0xd9, 0x76, 0x74, 0x42, 0x7a, 0xcc, 0x9c, 0x68,
-       0x92, 0xec, 0xef, 0x89, 0x1e, 0xc1, 0xf7, 0x78, 0x7f, 0xdc, 0x4c, 0xc9,
-       0x16, 0x71, 0xcd, 0x6f, 0xae, 0x98, 0x3d, 0x5d, 0x59, 0x3d, 0x11, 0x96,
-       0x74, 0x51, 0x13, 0xc3, 0x8e, 0xc8, 0x64, 0xc5, 0x96, 0xfc, 0x52, 0x87,
-       0xe4, 0x2b, 0xf2, 0xc4, 0x94, 0xd3, 0x2e, 0x53, 0x4b, 0x47, 0x7d, 0x5d,
-       0x44, 0xd0, 0xd6, 0x2b, 0xf9, 0x5a, 0x14, 0x9f, 0x9f, 0xf8, 0xfc, 0xea,
-       0x22, 0x3b, 0x05, 0xcf, 0xf7, 0xa7, 0xdd, 0xea, 0xd7, 0xc2, 0x5e, 0xdb,
-       0x7f, 0xd9, 0xe2, 0x7d, 0x83, 0xdf, 0x12, 0xf8, 0x2d, 0x85, 0x65, 0xcd,
-       0x88, 0xca, 0xf7, 0xee, 0x8a, 0xc9, 0x54, 0x69, 0x0d, 0xb2, 0x89, 0xca,
-       0x37, 0x6a, 0x11, 0x79, 0x49, 0xc9, 0x22, 0xa4, 0x0d, 0xa3, 0xcf, 0x64,
-       0x69, 0x42, 0x3f, 0x51, 0xcc, 0x4b, 0xaa, 0x96, 0xd5, 0x0b, 0x73, 0x66,
-       0x47, 0x72, 0x29, 0xa7, 0x4f, 0xce, 0x75, 0x76, 0xa4, 0x96, 0x26, 0xf4,
-       0x42, 0x31, 0x0a, 0x39, 0x98, 0x1d, 0xa9, 0xf9, 0x08, 0xae, 0x3b, 0x3b,
-       0x92, 0xf3, 0xd6, 0x0c, 0x26, 0x45, 0x9f, 0x68, 0x47, 0xaa, 0x64, 0x65,
-       0x45, 0xba, 0x9d, 0x1f, 0x48, 0x57, 0x47, 0xaa, 0xf6, 0x5b, 0xfa, 0x8a,
-       0xa9, 0x49, 0xe1, 0x1e, 0x31, 0xa3, 0x89, 0xb7, 0xeb, 0xb7, 0xdb, 0x9a,
-       0x98, 0xf6, 0x3b, 0xf5, 0xed, 0x90, 0x4d, 0x6e, 0xb6, 0x15, 0xbc, 0x92,
-       0x26, 0x53, 0x72, 0xf3, 0x7d, 0xe6, 0xaa, 0x34, 0x89, 0x1b, 0x09, 0xae,
-       0xeb, 0xf5, 0xa4, 0xf3, 0x07, 0xe4, 0x91, 0xf2, 0xee, 0x18, 0x86, 0x5e,
-       0x92, 0xa0, 0x39, 0xe9, 0xbc, 0x5b, 0xf7, 0x9e, 0x09, 0x63, 0xce, 0x50,
-       0xc7, 0x50, 0xa9, 0x5e, 0x4f, 0x3b, 0x18, 0xdf, 0x09, 0x9e, 0x6d, 0x92,
-       0x72, 0xc4, 0x2d, 0x4f, 0x3a, 0x96, 0xe1, 0xc9, 0x87, 0xba, 0xe7, 0xb5,
-       0x0b, 0x7d, 0xe4, 0x25, 0x17, 0x91, 0x72, 0xc1, 0xf9, 0x98, 0x3c, 0xe5,
-       0x44, 0xc1, 0x5f, 0x58, 0x4e, 0x39, 0xb0, 0x2f, 0xfb, 0xb8, 0x96, 0xac,
-       0x59, 0xb1, 0xac, 0x3c, 0x2d, 0xc9, 0xf9, 0x6e, 0x33, 0x2d, 0x98, 0xdb,
-       0xae, 0xdf, 0x99, 0x74, 0x30, 0x5f, 0xff, 0xff, 0xad, 0xbb, 0x11, 0x2b,
-       0x5b, 0x96, 0x5e, 0x29, 0x94, 0xba, 0x9d, 0x1f, 0x43, 0x4f, 0x61, 0x5b,
-       0xdc, 0x71, 0xdb, 0x84, 0xdc, 0xac, 0xde, 0x94, 0x51, 0x97, 0x07, 0x31,
-       0x7f, 0xd2, 0xc6, 0xfd, 0x9a, 0x6c, 0xd3, 0xed, 0x66, 0x29, 0x98, 0x12,
-       0x69, 0x93, 0xdd, 0x52, 0x98, 0x45, 0xbb, 0xe3, 0x76, 0xea, 0x78, 0x26,
-       0x33, 0xc0, 0x36, 0xd1, 0x8c, 0x04, 0x75, 0x2c, 0xb2, 0x50, 0xed, 0xc5,
-       0xfc, 0x71, 0xb7, 0x55, 0x33, 0x65, 0xcd, 0x0c, 0x49, 0xa5, 0x1a, 0x77,
-       0xa3, 0x5a, 0xb3, 0x9c, 0x8a, 0xb7, 0x41, 0xa6, 0x51, 0x8c, 0x2d, 0x5f,
-       0xd6, 0x13, 0xf1, 0x68, 0x0e, 0x4a, 0xa3, 0x1d, 0x4d, 0x81, 0x9e, 0x29,
-       0x27, 0xab, 0xa5, 0x6a, 0x9f, 0xd3, 0x92, 0x4b, 0x87, 0xb4, 0xfd, 0x4b,
-       0xe8, 0x53, 0xfb, 0x1f, 0xbe, 0x0d, 0x44, 0x41, 0x9b, 0x8e, 0x67, 0xd9,
-       0x0e, 0x9a, 0x15, 0xed, 0x68, 0x83, 0x2e, 0x57, 0xc6, 0x22, 0x1d, 0x49,
-       0xa5, 0x4b, 0xd2, 0xa6, 0x4b, 0x6e, 0x54, 0x93, 0x4e, 0xdb, 0x95, 0xf0,
-       0xaf, 0x41, 0x9f, 0xf3, 0xd0, 0xe5, 0x7c, 0x4c, 0x4e, 0x94, 0x24, 0xa2,
-       0x0b, 0xe7, 0xca, 0xea, 0x95, 0x2a, 0xed, 0x01, 0xba, 0x85, 0xee, 0x0b,
-       0x55, 0x3e, 0x0b, 0x1d, 0x96, 0xd2, 0x90, 0x4f, 0x06, 0x73, 0x1f, 0xd4,
-       0x1e, 0xac, 0x8c, 0x69, 0x19, 0xd8, 0x49, 0x61, 0xb6, 0x0f, 0xba, 0xb3,
-       0x62, 0x6b, 0xb2, 0x4d, 0x0a, 0xb6, 0x1d, 0xfb, 0xac, 0xb4, 0xcb, 0xa9,
-       0x79, 0x5b, 0x4e, 0xcc, 0xc3, 0x1e, 0x4d, 0xcb, 0x5c, 0x94, 0xae, 0xec,
-       0x96, 0x44, 0x87, 0x3c, 0x3d, 0x6b, 0x65, 0xca, 0xd2, 0xed, 0xbe, 0x81,
-       0xfb, 0xb9, 0x33, 0xd4, 0xa9, 0xe4, 0x53, 0x8e, 0x21, 0x59, 0x93, 0x76,
-       0x7d, 0x9b, 0x26, 0x6d, 0xf5, 0x27, 0x93, 0x8e, 0x15, 0xa5, 0xcd, 0xa6,
-       0x3e, 0xdd, 0x6d, 0x1e, 0x10, 0xcb, 0xcc, 0x50, 0xfe, 0x4e, 0x1f, 0xf4,
-       0xf0, 0xbf, 0x29, 0x7b, 0x8c, 0x45, 0x1d, 0xf7, 0x45, 0x4f, 0x41, 0x97,
-       0x59, 0xa5, 0xe3, 0x0e, 0xcc, 0x1f, 0xf2, 0x6d, 0x87, 0x6b, 0xe2, 0x6e,
-       0xcd, 0x93, 0x43, 0x87, 0xcc, 0x54, 0xda, 0xa5, 0x00, 0x1d, 0x16, 0xc4,
-       0x96, 0xc2, 0xd2, 0x5e, 0xbf, 0xdd, 0xc6, 0x7a, 0xf9, 0x53, 0x5d, 0xda,
-       0x8e, 0x6b, 0x87, 0x6a, 0x3f, 0xd7, 0x7c, 0xfb, 0x81, 0xfd, 0x85, 0xc5,
-       0x1d, 0x0d, 0xcb, 0xf9, 0x9a, 0x67, 0x7f, 0x0b, 0xf0, 0x3d, 0xae, 0xe9,
-       0xc2, 0x96, 0xde, 0x5c, 0xef, 0x73, 0xbe, 0xd6, 0x85, 0x67, 0xc3, 0x72,
-       0xa2, 0xc6, 0xfe, 0x79, 0xd8, 0x58, 0x58, 0x96, 0xef, 0x6a, 0x97, 0x2c,
-       0xda, 0x0b, 0xf3, 0xe2, 0x26, 0x1d, 0x1d, 0xcf, 0x74, 0x80, 0x97, 0x9d,
-       0xf8, 0xb4, 0xc9, 0x78, 0xa5, 0xc5, 0xe5, 0x7a, 0x1d, 0xaf, 0x51, 0xff,
-       0xf8, 0x2e, 0x05, 0x36, 0x40, 0xf9, 0xb2, 0x9d, 0xcf, 0xb1, 0xdd, 0x44,
-       0x7b, 0x63, 0x1b, 0x6d, 0x7b, 0x1b, 0x65, 0xda, 0xcb, 0x35, 0x9a, 0x2b,
-       0xc5, 0xcd, 0x43, 0xfc, 0xae, 0xd1, 0x1e, 0x1a, 0x6d, 0x21, 0x84, 0xfe,
-       0xd0, 0x63, 0x05, 0x73, 0xcd, 0x5e, 0xab, 0x37, 0x0d, 0xe0, 0xda, 0xfe,
-       0x1d, 0xf0, 0xc9, 0xb9, 0x43, 0xa0, 0x4b, 0x97, 0x6c, 0x45, 0xd1, 0x16,
-       0xa3, 0x0d, 0x78, 0x7c, 0x74, 0xc9, 0xe4, 0x7c, 0x7b, 0x47, 0x7a, 0x9e,
-       0xed, 0xc9, 0xa8, 0x01, 0x3e, 0xc7, 0x1d, 0x59, 0x99, 0x72, 0xf4, 0xee,
-       0x10, 0xe8, 0x9a, 0xc0, 0x82, 0x03, 0x1f, 0x3e, 0x8d, 0x2b, 0xb8, 0xdf,
-       0x29, 0xe3, 0x4b, 0xec, 0xcb, 0x39, 0x0a, 0xdb, 0x75, 0x49, 0x80, 0x36,
-       0x7c, 0x6c, 0x0b, 0xf7, 0x5b, 0x31, 0x4f, 0x3b, 0x6c, 0x67, 0x9a, 0xba,
-       0xfb, 0x44, 0xd2, 0xe9, 0x94, 0xec, 0x7a, 0x5f, 0x81, 0xdd, 0xb1, 0x7f,
-       0xef, 0xa6, 0xbe, 0x90, 0xef, 0x12, 0xc6, 0x9c, 0x6f, 0x85, 0x0c, 0xd9,
-       0xae, 0x83, 0xe6, 0x16, 0xd0, 0x00, 0x1f, 0x6c, 0x77, 0x63, 0x3d, 0xb4,
-       0x60, 0xfc, 0x2d, 0xe0, 0xa9, 0x55, 0x26, 0x66, 0x3b, 0xa1, 0x0b, 0x13,
-       0x7d, 0xc3, 0xf2, 0x74, 0xc9, 0x82, 0x0d, 0xb0, 0x3f, 0x74, 0x30, 0x6f,
-       0x45, 0x2b, 0xe2, 0xca, 0x94, 0xd3, 0x02, 0xfb, 0xaa, 0xd7, 0x8f, 0xc0,
-       0x3e, 0xbe, 0xae, 0xfc, 0x45, 0x9f, 0x39, 0xa4, 0x49, 0xbe, 0x25, 0xf1,
-       0x7d, 0xd0, 0x63, 0x3d, 0x2a, 0xc2, 0xeb, 0xbd, 0x1a, 0xd7, 0x2c, 0xe4,
-       0xc8, 0xb9, 0xe1, 0x93, 0x76, 0x42, 0x86, 0xf4, 0x5b, 0x5d, 0xb0, 0xe7,
-       0xa8, 0xf2, 0x27, 0x43, 0x37, 0xf4, 0x27, 0xd6, 0x68, 0x19, 0x73, 0x15,
-       0x96, 0x42, 0xf4, 0x61, 0x83, 0x58, 0xae, 0xb2, 0x15, 0x6b, 0x6f, 0x52,
-       0xd9, 0xc7, 0x4f, 0xc8, 0x6f, 0xfd, 0x53, 0x0e, 0xe9, 0x22, 0xbf, 0x2e,
-       0x9e, 0xa5, 0x0d, 0x5a, 0xc7, 0x5d, 0x35, 0xff, 0x4f, 0xfc, 0xf9, 0x3d,
-       0xda, 0x0b, 0xa5, 0x0e, 0x2d, 0xa5, 0x68, 0x08, 0xc6, 0x11, 0x59, 0x3d,
-       0xd3, 0x6d, 0x3e, 0x08, 0x1b, 0xa6, 0x9f, 0x5a, 0xbd, 0x40, 0x1d, 0x63,
-       0x8c, 0x01, 0xea, 0xd8, 0x54, 0xf4, 0x25, 0xe7, 0xb9, 0xf6, 0xa4, 0xcb,
-       0x10, 0xfa, 0x08, 0xf8, 0x5c, 0xac, 0xc5, 0x49, 0x7f, 0x2d, 0xe6, 0xaa,
-       0xb4, 0xbf, 0xc7, 0xf1, 0xac, 0x2e, 0x43, 0x71, 0xfa, 0x87, 0xa7, 0x25,
-       0x05, 0x1f, 0x09, 0x3d, 0x4a, 0x05, 0xbc, 0x2c, 0x94, 0x1a, 0xfd, 0x16,
-       0x6c, 0xab, 0xff, 0xaf, 0xeb, 0x9e, 0x3f, 0xa4, 0x6f, 0xa0, 0xaf, 0x29,
-       0x98, 0x3a, 0x24, 0x87, 0xc8, 0xe0, 0x42, 0x37, 0x4e, 0xd2, 0xb0, 0x32,
-       0x59, 0xc6, 0x1c, 0xbb, 0x2e, 0xf6, 0x7d, 0x82, 0x48, 0xda, 0xcb, 0xf8,
-       0xb7, 0x2f, 0xf0, 0x4f, 0xab, 0xd5, 0x40, 0x17, 0xd4, 0x2b, 0xf5, 0x10,
-       0xf8, 0x88, 0x90, 0x5c, 0x84, 0xef, 0x9a, 0x2a, 0xb5, 0xcb, 0x0a, 0x68,
-       0xba, 0x54, 0x0d, 0x6c, 0xcd, 0xf0, 0x6d, 0x8d, 0xcf, 0xb4, 0xe3, 0xf9,
-       0x10, 0xfc, 0x9a, 0xe4, 0x8d, 0x04, 0x7e, 0x17, 0x39, 0x26, 0xdb, 0x02,
-       0x3b, 0xe7, 0x9a, 0xb1, 0xdc, 0xb2, 0x34, 0x4b, 0x26, 0x8e, 0xf8, 0x31,
-       0xaf, 0x63, 0xae, 0x2e, 0xf8, 0xf2, 0x90, 0x1c, 0x2d, 0x45, 0xe4, 0xf3,
-       0x25, 0xf2, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xbe, 0x0e, 0x9d, 0x0f,
-       0xc3, 0xe7, 0x65, 0xb4, 0x21, 0xf8, 0x9f, 0x03, 0x95, 0xcf, 0x69, 0xe9,
-       0xa5, 0xac, 0x36, 0x5c, 0x3b, 0xa4, 0x65, 0x96, 0xc6, 0xb4, 0xfd, 0x0d,
-       0xbe, 0x48, 0xb4, 0xf7, 0xf7, 0x45, 0x4f, 0xcd, 0x72, 0xce, 0x6e, 0xe7,
-       0xc6, 0xbe, 0xe8, 0xd7, 0xf5, 0x46, 0x5f, 0xd4, 0x0d, 0x5f, 0x94, 0x81,
-       0x2f, 0x1a, 0xbe, 0x65, 0x5f, 0x34, 0xa2, 0xdf, 0xd8, 0x17, 0x1d, 0xd4,
-       0xaf, 0xfb, 0x22, 0xc6, 0x9e, 0x15, 0x5c, 0x9b, 0xb2, 0x67, 0x5f, 0x20,
-       0xe7, 0x28, 0xfc, 0xf0, 0x16, 0xc8, 0xba, 0x8d, 0x6b, 0x27, 0x56, 0x80,
-       0xdd, 0x4f, 0x60, 0xae, 0xdf, 0x86, 0xbd, 0xef, 0x89, 0xdb, 0xe6, 0x43,
-       0x6a, 0xde, 0xf7, 0xea, 0x7c, 0x68, 0x5d, 0xe7, 0xa4, 0xf1, 0x97, 0xea,
-       0xdc, 0xf5, 0x74, 0x4e, 0x5d, 0xb7, 0xca, 0x11, 0x35, 0x6f, 0x5d, 0x42,
-       0xf7, 0x09, 0xbc, 0x8a, 0x3c, 0x60, 0x24, 0x2c, 0x8c, 0xa7, 0x63, 0x7e,
-       0xea, 0x2b, 0x0e, 0x1a, 0x04, 0xfa, 0x6d, 0x57, 0xbe, 0x68, 0x3f, 0xf4,
-       0xbe, 0x5a, 0xbd, 0x35, 0x5d, 0x65, 0x1a, 0x74, 0xf5, 0xe0, 0x06, 0x5d,
-       0xb5, 0x48, 0x7f, 0x3c, 0xd0, 0xd1, 0x36, 0x49, 0xc6, 0xa9, 0xb3, 0x5b,
-       0xd1, 0xd5, 0xb9, 0xbf, 0x25, 0x5d, 0x7d, 0xf7, 0x26, 0xba, 0xfa, 0xde,
-       0x26, 0x5d, 0xd9, 0xe6, 0x33, 0x1a, 0xc7, 0x66, 0xfc, 0xa0, 0x3f, 0xaa,
-       0xdf, 0x39, 0xce, 0xfc, 0xa1, 0xc6, 0x35, 0x1d, 0xe4, 0x1d, 0x5c, 0xcf,
-       0x2f, 0xd7, 0x0d, 0xdb, 0x86, 0xec, 0xb8, 0xa6, 0x29, 0x37, 0xcb, 0xfc,
-       0x14, 0xe9, 0x47, 0xec, 0x18, 0x47, 0xac, 0xf1, 0x68, 0x68, 0x96, 0xf2,
-       0x76, 0xaf, 0xff, 0x78, 0xa9, 0xfe, 0x73, 0x3d, 0xf1, 0x0b, 0xe4, 0x95,
-       0xb6, 0x1f, 0x07, 0xc2, 0xf2, 0x85, 0x8a, 0x95, 0x75, 0xb5, 0x76, 0xc9,
-       0xef, 0x40, 0xec, 0x29, 0xd1, 0x7f, 0xed, 0xbc, 0x49, 0x8c, 0xee, 0xf2,
-       0x63, 0xf4, 0x9f, 0x81, 0x56, 0xe6, 0x57, 0xff, 0xe6, 0xdd, 0x95, 0x08,
-       0xbf, 0xe3, 0xe6, 0x41, 0xf9, 0x2c, 0x79, 0x44, 0xbc, 0x67, 0xdc, 0xb7,
-       0x99, 0xf3, 0xe4, 0x43, 0x89, 0x36, 0xc9, 0x6f, 0xe7, 0x7a, 0xa4, 0x9f,
-       0xa3, 0xef, 0x6a, 0xf6, 0xe9, 0x0e, 0x72, 0x24, 0xfe, 0xb5, 0x18, 0x60,
-       0x19, 0x7d, 0x90, 0x0f, 0x95, 0xc8, 0xc7, 0xbb, 0xbe, 0x3d, 0x31, 0x57,
-       0x90, 0x26, 0xcf, 0x37, 0x8c, 0x20, 0x17, 0xa0, 0x1d, 0x04, 0x3a, 0xa7,
-       0xbe, 0x99, 0x23, 0x48, 0x4c, 0xb7, 0x99, 0x23, 0x88, 0x69, 0x24, 0x0e,
-       0x6a, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0xc9,
-       0xda, 0x71, 0xdc, 0x53, 0x79, 0x08, 0x68, 0xf1, 0xc6, 0x4f, 0x7b, 0xe3,
-       0x83, 0xce, 0x9d, 0x92, 0x53, 0x3a, 0x21, 0xbf, 0xc8, 0x35, 0x94, 0xbf,
-       0x1e, 0xd6, 0x3c, 0x7f, 0xcd, 0xf1, 0x32, 0x78, 0xfe, 0x7e, 0xe4, 0x73,
-       0xae, 0xae, 0xdb, 0xd7, 0x65, 0x32, 0xd5, 0x20, 0x93, 0xc9, 0x2a, 0x65,
-       0xc4, 0xfe, 0xf4, 0xb9, 0x13, 0xfa, 0xc2, 0xba, 0x5c, 0x46, 0x40, 0x43,
-       0x0b, 0x79, 0xf7, 0xf9, 0xe0, 0xf8, 0x9d, 0xfe, 0xf8, 0xbf, 0x81, 0x31,
-       0xe9, 0x5f, 0x6f, 0x34, 0x2f, 0xe7, 0x64, 0xce, 0xf8, 0x7e, 0xfc, 0x20,
-       0x67, 0xc6, 0x1a, 0x78, 0x69, 0x3d, 0x9f, 0x8e, 0x21, 0x9f, 0x7e, 0x07,
-       0xb9, 0x74, 0xbd, 0xce, 0x38, 0x55, 0x40, 0x9e, 0x9b, 0x76, 0xb8, 0xae,
-       0x6f, 0x65, 0xdd, 0x6e, 0x58, 0xb3, 0x66, 0xd2, 0xe0, 0xb8, 0x61, 0xf1,
-       0xc6, 0xe4, 0xfd, 0x16, 0xe4, 0x82, 0xef, 0xe0, 0x37, 0x7d, 0x72, 0x90,
-       0xe7, 0xb1, 0x0f, 0x9f, 0x7f, 0x15, 0x73, 0xf7, 0x03, 0xcf, 0xf4, 0xca,
-       0x77, 0x6a, 0xb6, 0x7c, 0x1b, 0x98, 0xe6, 0x5b, 0xc8, 0x2d, 0xbe, 0x59,
-       0x0b, 0x72, 0xfb, 0xbd, 0x30, 0x75, 0xe6, 0xf7, 0x12, 0xde, 0x69, 0x13,
-       0x57, 0xe5, 0xf7, 0x7f, 0xda, 0x96, 0xad, 0x11, 0xfc, 0xfe, 0x95, 0x84,
-       0x6c, 0xeb, 0xc4, 0xf7, 0xf6, 0x04, 0x4c, 0x27, 0xc1, 0xd8, 0xa8, 0x35,
-       0xc4, 0x46, 0xd1, 0xd2, 0xe0, 0x71, 0x0a, 0xe3, 0xa5, 0xc1, 0xf7, 0x67,
-       0x6a, 0x61, 0x2d, 0x35, 0xbb, 0x1b, 0x98, 0x24, 0xc8, 0x71, 0x91, 0x47,
-       0x99, 0xab, 0xdb, 0x43, 0xf2, 0x36, 0x78, 0x4a, 0x82, 0x76, 0x17, 0x39,
-       0xc0, 0x3f, 0xc5, 0x5c, 0xd6, 0x4f, 0x3f, 0x2d, 0xff, 0xda, 0xcf, 0xc3,
-       0x9b, 0x64, 0x4e, 0xf1, 0xc8, 0x76, 0xc9, 0xfc, 0xcb, 0x9e, 0xeb, 0xed,
-       0xcf, 0xae, 0xb7, 0xc7, 0x32, 0xbf, 0xb1, 0xde, 0x7e, 0x35, 0xe4, 0xe1,
-       0x95, 0x41, 0x6d, 0xb4, 0xf6, 0x2f, 0x8c, 0x00, 0xeb, 0x14, 0x66, 0x7b,
-       0x31, 0xd7, 0x36, 0x99, 0xb4, 0xdf, 0x06, 0xf6, 0xb2, 0x63, 0x39, 0xac,
-       0xaf, 0xa7, 0x36, 0xf9, 0xfa, 0x36, 0xf8, 0x8f, 0xd3, 0xb3, 0xd6, 0x20,
-       0xfd, 0x47, 0x1c, 0x6b, 0x29, 0xf9, 0x1e, 0xff, 0xf1, 0x6d, 0xa3, 0xd1,
-       0x7f, 0x18, 0xf0, 0x1f, 0xfb, 0xdf, 0xc7, 0x7f, 0x3c, 0xf5, 0x1e, 0xff,
-       0xa1, 0xc1, 0x2e, 0xe8, 0x3f, 0x7e, 0x68, 0x04, 0xfe, 0xa3, 0xb0, 0xc1,
-       0x7f, 0x04, 0xfa, 0xb0, 0x55, 0xee, 0xe8, 0xfd, 0x26, 0xfe, 0x6c, 0xf3,
-       0x31, 0xa7, 0x84, 0x43, 0x09, 0x37, 0x33, 0x65, 0xef, 0x92, 0x26, 0xac,
-       0xd1, 0x97, 0x6b, 0x03, 0xf0, 0x25, 0xbf, 0x0f, 0x9c, 0x66, 0x39, 0x4c,
-       0x44, 0x9a, 0x12, 0xd4, 0xcd, 0x48, 0x2c, 0x69, 0xbf, 0x90, 0x59, 0xa8,
-       0xbe, 0x90, 0x39, 0xa7, 0x74, 0x35, 0x61, 0x79, 0x18, 0xf8, 0x09, 0x0b,
-       0x18, 0x18, 0xcf, 0x87, 0x80, 0x21, 0xd8, 0xde, 0x6e, 0x26, 0x91, 0xa3,
-       0x54, 0xaa, 0x2b, 0x99, 0x02, 0x3e, 0x53, 0xaa, 0xef, 0x58, 0x8c, 0x7d,
-       0x5b, 0x12, 0xe5, 0xd8, 0x9f, 0xe2, 0xbb, 0x39, 0x31, 0x67, 0x5d, 0xb6,
-       0x39, 0xee, 0x6b, 0xb1, 0x73, 0x6a, 0x8c, 0x90, 0x14, 0xd4, 0xb3, 0x5f,
-       0xb5, 0xf8, 0xec, 0x29, 0xf8, 0xf8, 0x93, 0x55, 0x53, 0x4e, 0x54, 0xd7,
-       0x32, 0x39, 0x7c, 0x88, 0x6d, 0x5e, 0x2e, 0xf1, 0xfe, 0xb7, 0x70, 0x3f,
-       0x24, 0xcc, 0x3d, 0x3e, 0x8f, 0x3e, 0x47, 0xd1, 0xe7, 0x48, 0x35, 0xc0,
-       0x8d, 0xbc, 0xef, 0x66, 0x52, 0xb8, 0x7f, 0xa4, 0xe8, 0x66, 0xd2, 0x45,
-       0xe6, 0x39, 0x7d, 0xd1, 0x13, 0x90, 0x67, 0x16, 0xb1, 0xdd, 0x15, 0xab,
-       0x37, 0x2f, 0x8f, 0xb5, 0x0e, 0x23, 0xaf, 0x3e, 0x8f, 0x98, 0xe3, 0x8e,
-       0x59, 0x4e, 0x19, 0xcc, 0x4d, 0x95, 0xee, 0x90, 0xc2, 0x0c, 0x62, 0x8c,
-       0x73, 0x0f, 0x73, 0xed, 0x8c, 0x1e, 0x77, 0xe0, 0x13, 0x06, 0x80, 0x27,
-       0xbb, 0x81, 0x85, 0xef, 0x92, 0x15, 0xd3, 0x8a, 0x0e, 0x03, 0x03, 0xa7,
-       0x42, 0xe8, 0xd3, 0x7b, 0x9b, 0x64, 0xa3, 0x94, 0xf5, 0x0e, 0xf8, 0x07,
-       0x4d, 0x5a, 0xec, 0x46, 0x5f, 0xf5, 0x17, 0x10, 0x2f, 0x92, 0xdf, 0x36,
-       0xb6, 0xb7, 0xfa, 0x3a, 0xd9, 0x22, 0xab, 0xef, 0xe9, 0xf7, 0x37, 0x0d,
-       0xfd, 0x1a, 0xdb, 0x35, 0x4d, 0xd0, 0x7f, 0x0d, 0x34, 0x84, 0xe2, 0x90,
-       0x3f, 0x78, 0x68, 0x82, 0x9d, 0x5c, 0x06, 0x3f, 0xf4, 0x9b, 0x85, 0x32,
-       0xe3, 0xa4, 0x21, 0x65, 0x13, 0xf7, 0xaa, 0xf5, 0xfa, 0x82, 0x0d, 0x5a,
-       0x2f, 0x90, 0xde, 0xb0, 0x0c, 0x57, 0x7b, 0xc4, 0x5d, 0xa4, 0x1c, 0x2c,
-       0xac, 0x8e, 0x5d, 0x6d, 0xa9, 0x79, 0xcb, 0xcd, 0x63, 0x44, 0xe3, 0x42,
-       0x57, 0x5b, 0x12, 0x71, 0x51, 0xbf, 0x10, 0x6b, 0x4b, 0xc1, 0x1f, 0x18,
-       0x17, 0x6e, 0x6f, 0x4b, 0xcf, 0x92, 0x2e, 0x03, 0x71, 0xf1, 0x4e, 0xe0,
-       0xc2, 0xba, 0x7c, 0x0d, 0xb9, 0x4f, 0xa1, 0x17, 0x31, 0x03, 0xab, 0x44,
-       0x07, 0xdd, 0x79, 0x53, 0xc2, 0x6d, 0x89, 0x79, 0xd0, 0xd7, 0xdf, 0x9a,
-       0x9c, 0xdd, 0x82, 0x3e, 0x06, 0xda, 0x7b, 0x88, 0x21, 0x1b, 0xda, 0xed,
-       0x36, 0xf8, 0x5f, 0xf8, 0x3a, 0x09, 0x27, 0x07, 0xda, 0x31, 0xfe, 0xd9,
-       0x10, 0x73, 0x87, 0x70, 0x7c, 0xbd, 0xfd, 0xcb, 0x5e, 0x7b, 0x2f, 0x68,
-       0xe1, 0x73, 0xcc, 0x21, 0x25, 0x3c, 0x3e, 0x60, 0x82, 0x06, 0xf6, 0x8d,
-       0xa8, 0xbe, 0xe9, 0x79, 0xda, 0x80, 0x9b, 0x59, 0xb0, 0x77, 0x4b, 0x6a,
-       0x6e, 0xa7, 0x0c, 0xcf, 0x75, 0xca, 0xfe, 0x39, 0xe6, 0xbc, 0xc4, 0xc0,
-       0x60, 0x05, 0x39, 0xa9, 0x7e, 0x81, 0xb9, 0x80, 0x15, 0x3d, 0x2a, 0xdd,
-       0xd1, 0xcf, 0x63, 0x1d, 0x8c, 0xdb, 0xf1, 0xd8, 0x24, 0xd6, 0x58, 0x48,
-       0x8d, 0x13, 0x0d, 0xe6, 0xa4, 0x8d, 0x6e, 0x98, 0x37, 0x3d, 0x7f, 0xb3,
-       0x71, 0xb1, 0x70, 0x2e, 0x44, 0x37, 0x8d, 0xfb, 0x3f, 0xfd, 0x71, 0x4d,
-       0x8c, 0xdb, 0x85, 0x31, 0xc9, 0xe3, 0xed, 0xad, 0x43, 0xb3, 0xe2, 0xb6,
-       0x80, 0xbe, 0x74, 0x7c, 0x97, 0x4c, 0x62, 0x9c, 0x93, 0x73, 0xf4, 0x85,
-       0xb2, 0x13, 0x9f, 0xfe, 0x26, 0x89, 0xf7, 0x2e, 0x21, 0x2f, 0x1e, 0x52,
-       0x63, 0x78, 0x39, 0xaa, 0x7e, 0x21, 0x01, 0x5c, 0xf3, 0x51, 0xd0, 0xc3,
-       0x98, 0x4c, 0x9e, 0x43, 0xe0, 0x37, 0x81, 0x75, 0x48, 0x3c, 0xce, 0xf5,
-       0x8d, 0xdf, 0x4b, 0xd1, 0xd6, 0xd4, 0x6c, 0x33, 0xd6, 0x9d, 0xec, 0x36,
-       0x54, 0xac, 0xa0, 0x5e, 0xec, 0xd6, 0x64, 0x49, 0xd1, 0xdd, 0x9a, 0x2a,
-       0x51, 0x46, 0x4e, 0x6b, 0xba, 0x44, 0x19, 0x09, 0xe8, 0x71, 0xe0, 0x63,
-       0x43, 0x12, 0xdb, 0x4e, 0x3d, 0x1e, 0x43, 0xbf, 0x95, 0x10, 0xf3, 0xfe,
-       0xa4, 0xcd, 0xdf, 0xc0, 0x2b, 0x17, 0x8e, 0xa3, 0x2f, 0x7f, 0xdf, 0x8b,
-       0x71, 0xbb, 0x7b, 0x0b, 0xd2, 0xdc, 0x7b, 0x04, 0x7e, 0x42, 0x1f, 0x00,
-       0xee, 0x50, 0x76, 0x5e, 0x07, 0x26, 0xdb, 0x0b, 0x7e, 0xb0, 0x36, 0xe2,
-       0xb6, 0x4c, 0xcc, 0x50, 0xae, 0x72, 0x1b, 0x78, 0x00, 0xff, 0x71, 0xf8,
-       0x16, 0xf2, 0xc0, 0xb9, 0x05, 0x76, 0xbf, 0x2c, 0xb9, 0x99, 0xb0, 0xc2,
-       0x3e, 0xae, 0xc9, 0xf9, 0x35, 0x4d, 0x4f, 0xb4, 0x41, 0xc7, 0xe4, 0x6d,
-       0x0a, 0xb4, 0x3d, 0x0e, 0x3f, 0x6c, 0xa9, 0x9c, 0xdb, 0x40, 0xff, 0x42,
-       0x69, 0x50, 0x4f, 0x15, 0x49, 0xbf, 0x6f, 0x7b, 0xda, 0x0a, 0x7c, 0x8a,
-       0xaa, 0x63, 0x21, 0xb7, 0x4b, 0xc0, 0x8f, 0x0c, 0xca, 0xf7, 0xe1, 0x4b,
-       0xbe, 0x5b, 0x73, 0xe0, 0xff, 0xfb, 0xe1, 0xff, 0x7b, 0xe1, 0xff, 0x6d,
-       0xf8, 0xff, 0x18, 0xfc, 0x7f, 0x17, 0xfc, 0x7f, 0x94, 0xbe, 0x5f, 0x4e,
-       0xd6, 0xf2, 0xb0, 0xb1, 0x15, 0xf8, 0x41, 0x33, 0xec, 0xd6, 0x22, 0xe1,
-       0x64, 0x2d, 0x1a, 0x4e, 0xd5, 0x42, 0xe0, 0xe9, 0x30, 0xe7, 0x04, 0x7f,
-       0xf9, 0xd6, 0xa1, 0x52, 0x3f, 0xe2, 0x8a, 0x0b, 0xbf, 0x94, 0x86, 0xdf,
-       0x77, 0x80, 0x7f, 0xf3, 0xb2, 0x3a, 0x13, 0xc3, 0x33, 0x75, 0x49, 0x3b,
-       0x4d, 0x32, 0x69, 0x3a, 0x18, 0x63, 0xbb, 0xb2, 0x53, 0x23, 0xb1, 0xab,
-       0x09, 0x76, 0x2a, 0xb9, 0x22, 0xe3, 0x73, 0x17, 0xc6, 0x6b, 0x45, 0x7c,
-       0xa0, 0x7f, 0xa0, 0x2f, 0x58, 0xc9, 0x3c, 0x6c, 0x73, 0xcd, 0xb5, 0x69,
-       0x49, 0xe0, 0x67, 0x62, 0x13, 0xc4, 0x3a, 0xd8, 0x05, 0xdb, 0xf6, 0xe0,
-       0x39, 0xfe, 0xfe, 0x6f, 0x7e, 0x8d, 0xea, 0xaf, 0x5a, 0x04, 0xc6, 0xfb,
-       0x32, 0x63, 0x8f, 0x8d, 0xf1, 0xaa, 0x8d, 0xeb, 0x75, 0x49, 0x17, 0x3b,
-       0xb8, 0xcf, 0x7a, 0x0d, 0x6b, 0x54, 0xaf, 0x80, 0xde, 0x7a, 0x7d, 0x55,
-       0x61, 0x48, 0xe4, 0x33, 0x87, 0xd6, 0xc0, 0x43, 0xe3, 0x33, 0xdf, 0xc0,
-       0x33, 0xaa, 0x2d, 0x6c, 0x26, 0x1c, 0xe6, 0x50, 0xf0, 0x9b, 0x2f, 0xc0,
-       0x47, 0x1e, 0xcb, 0xe8, 0xcb, 0x57, 0xf1, 0x2c, 0x64, 0x5a, 0x3c, 0x96,
-       0x09, 0xf5, 0xbc, 0x5a, 0x7f, 0x16, 0x39, 0xf1, 0xd0, 0xf2, 0x80, 0xa4,
-       0x96, 0xbb, 0xa3, 0x17, 0xa5, 0xf5, 0x1d, 0x17, 0xb1, 0x74, 0xb2, 0x6a,
-       0x9d, 0x76, 0x85, 0x39, 0xba, 0x29, 0x0b, 0xc0, 0xd5, 0x7b, 0xf6, 0x3d,
-       0x0f, 0xda, 0xad, 0x17, 0x45, 0x8f, 0xe1, 0x37, 0x31, 0x0c, 0x79, 0x5c,
-       0x03, 0x7f, 0x1a, 0xae, 0x5b, 0xd6, 0x6b, 0x57, 0x85, 0x12, 0xf8, 0xac,
-       0x1d, 0xcb, 0x5c, 0x9c, 0x06, 0xae, 0x83, 0x3e, 0x92, 0xd3, 0xc4, 0x9c,
-       0x5b, 0x20, 0x93, 0x21, 0xd8, 0x05, 0xf5, 0x1d, 0xc7, 0xb3, 0x75, 0xf9,
-       0x92, 0x43, 0x1b, 0x78, 0x0e, 0x72, 0xc3, 0x58, 0xa1, 0x80, 0x6e, 0x60,
-       0x80, 0x19, 0xca, 0x6a, 0x17, 0xf2, 0x36, 0x57, 0x06, 0xf6, 0x49, 0x78,
-       0x47, 0x62, 0x73, 0x4e, 0x76, 0x2c, 0xb3, 0x3a, 0x8d, 0xf1, 0x7b, 0x80,
-       0x79, 0x84, 0xb5, 0x19, 0xfa, 0x60, 0x81, 0xed, 0xec, 0x87, 0x7e, 0x98,
-       0x7b, 0x33, 0x47, 0xa3, 0x6f, 0x3a, 0xa8, 0xa5, 0x2a, 0x65, 0x43, 0x3a,
-       0x0e, 0x21, 0xb7, 0x71, 0x64, 0x71, 0x9a, 0x39, 0x1a, 0xf3, 0x99, 0x20,
-       0x7f, 0xd1, 0x90, 0x4b, 0xa0, 0x7d, 0xf9, 0x25, 0xa5, 0x07, 0x03, 0xfa,
-       0xca, 0xed, 0xbb, 0x9f, 0x7c, 0xcd, 0x18, 0x09, 0xf8, 0xbf, 0x01, 0xf2,
-       0xa2, 0x68, 0x40, 0xce, 0xc6, 0x35, 0x17, 0x03, 0x5f, 0xf8, 0x5c, 0xcf,
-       0xdd, 0xd4, 0xdf, 0x64, 0xe9, 0x04, 0xec, 0x58, 0xf2, 0x4d, 0x09, 0xf0,
-       0x36, 0x80, 0xdf, 0x58, 0xf8, 0x27, 0xa1, 0xc3, 0x73, 0x03, 0xac, 0x91,
-       0x3d, 0x07, 0xfc, 0x47, 0xfa, 0xe3, 0xb1, 0x13, 0x6a, 0xdd, 0xe2, 0xba,
-       0xca, 0x3c, 0x62, 0x8b, 0x5c, 0x54, 0x7c, 0xde, 0xc1, 0xfc, 0x14, 0x7a,
-       0xb9, 0x15, 0x3e, 0x87, 0x3f, 0x24, 0x9f, 0xde, 0x3c, 0x8c, 0x5b, 0x49,
-       0x3b, 0x26, 0xa9, 0xe2, 0xcb, 0x75, 0xaf, 0x0e, 0xfb, 0x47, 0xb0, 0x2b,
-       0x5c, 0x57, 0xc3, 0xa0, 0x87, 0x75, 0x99, 0x01, 0xa5, 0x5b, 0xd0, 0x43,
-       0x9b, 0xc9, 0x87, 0x13, 0xdb, 0xe4, 0xfc, 0x4c, 0x87, 0x2c, 0xcc, 0xbc,
-       0x26, 0x95, 0x99, 0x36, 0x59, 0x9a, 0xa9, 0xcb, 0x65, 0x47, 0xf9, 0x25,
-       0xbb, 0x59, 0xad, 0x69, 0xd9, 0xe5, 0x61, 0xf6, 0xf8, 0xe0, 0x15, 0x79,
-       0x5a, 0xce, 0x97, 0x3d, 0x1e, 0x32, 0x0d, 0x3c, 0xbc, 0x0a, 0x1b, 0xeb,
-       0xec, 0x21, 0x0f, 0xb4, 0x07, 0xf2, 0xc3, 0xdc, 0x83, 0x39, 0xe6, 0x41,
-       0xac, 0xa3, 0x11, 0x60, 0xa3, 0x83, 0x5a, 0xd2, 0xe7, 0x21, 0xe5, 0xf1,
-       0x90, 0x7d, 0x2f, 0x0f, 0x2d, 0x92, 0xdd, 0x49, 0x3e, 0xa0, 0x83, 0x69,
-       0xea, 0x25, 0xc0, 0x1b, 0x1e, 0xfd, 0xc9, 0xe5, 0x57, 0xeb, 0xfa, 0x74,
-       0x93, 0xa2, 0xdd, 0x48, 0x0c, 0xc0, 0xae, 0x5e, 0xad, 0xcb, 0x32, 0xd7,
-       0x12, 0x7e, 0x57, 0xff, 0x31, 0xfc, 0x55, 0xa7, 0xca, 0x5b, 0x72, 0x63,
-       0xed, 0xad, 0xc9, 0xf9, 0x41, 0xe8, 0xba, 0x55, 0xad, 0x45, 0xb8, 0x0e,
-       0xe8, 0xf0, 0x0f, 0xd1, 0xff, 0xab, 0x5c, 0x73, 0x4a, 0x3e, 0x69, 0xc8,
-       0xa7, 0x50, 0xbc, 0xbd, 0x19, 0x39, 0x37, 0xe6, 0x71, 0x33, 0xd9, 0x2a,
-       0x9f, 0xe9, 0x82, 0x7f, 0xe3, 0xf7, 0x07, 0xb6, 0x8f, 0x3c, 0xfc, 0x2e,
-       0x6c, 0x00, 0xb9, 0x05, 0xd7, 0xf4, 0xc0, 0x0a, 0xe2, 0x6c, 0xbc, 0x77,
-       0x41, 0xd5, 0xf4, 0x1d, 0x85, 0x9f, 0x26, 0xab, 0x5f, 0xc5, 0xc7, 0x9b,
-       0x6f, 0xa8, 0xc6, 0x39, 0x37, 0xf2, 0x84, 0x9c, 0x06, 0xb9, 0xa4, 0x8d,
-       0x71, 0x39, 0x6f, 0x5e, 0x8c, 0x84, 0x81, 0x79, 0xd9, 0xd6, 0x0e, 0x3f,
-       0x13, 0x83, 0xdf, 0xea, 0x87, 0xff, 0xe7, 0x5a, 0xa6, 0xaf, 0x0f, 0x68,
-       0xef, 0xc7, 0x98, 0xf4, 0xc1, 0xfd, 0xe0, 0x99, 0xb9, 0x34, 0x7d, 0x28,
-       0x62, 0xca, 0x62, 0xb4, 0x2d, 0x39, 0xeb, 0xd5, 0x93, 0xbc, 0xdf, 0xbc,
-       0x2f, 0xe1, 0xdd, 0x09, 0xab, 0x9c, 0x47, 0xfe, 0x97, 0xc2, 0xda, 0x4d,
-       0xda, 0xc8, 0xa7, 0x17, 0xad, 0x17, 0x88, 0xd3, 0x74, 0xca, 0x60, 0x99,
-       0x72, 0x62, 0x6d, 0xc3, 0x94, 0xfc, 0xc2, 0xef, 0x42, 0x1e, 0x61, 0xd9,
-       0x6e, 0x67, 0xe1, 0x53, 0x98, 0xb7, 0xb8, 0xe0, 0x8d, 0xbe, 0xa7, 0x1b,
-       0xb1, 0xcc, 0x80, 0x10, 0x90, 0x57, 0x2d, 0x1b, 0xf2, 0x40, 0xa8, 0x0f,
-       0x79, 0xe0, 0xa7, 0xd0, 0x37, 0x24, 0xf9, 0x65, 0xc6, 0x84, 0x90, 0x4c,
-       0x2d, 0x8b, 0x5c, 0x99, 0xa6, 0x5f, 0x51, 0x7f, 0x90, 0xb9, 0x9b, 0x99,
-       0x20, 0x3e, 0x9b, 0xa1, 0x8f, 0xa1, 0xff, 0xd8, 0x01, 0x5d, 0xc4, 0x9f,
-       0xfb, 0x12, 0xe2, 0xd3, 0x64, 0xb1, 0x1b, 0x7e, 0x53, 0x56, 0x74, 0xc8,
-       0x14, 0x71, 0x8d, 0xf5, 0xaa, 0x1b, 0xd4, 0xaa, 0x82, 0x3a, 0x55, 0x58,
-       0x0a, 0xd3, 0xac, 0x51, 0x85, 0x41, 0x0b, 0x73, 0x57, 0x43, 0xe5, 0x42,
-       0x3b, 0x94, 0x7f, 0xe5, 0x77, 0xa8, 0x61, 0xde, 0xf8, 0xe9, 0x3d, 0x3a,
-       0xfd, 0xd8, 0x6e, 0x71, 0x47, 0x8f, 0xb5, 0xee, 0x2f, 0x01, 0x8b, 0x76,
-       0xd2, 0x3e, 0xa9, 0xff, 0xac, 0x4e, 0x7f, 0x3b, 0x55, 0x1a, 0xc0, 0x78,
-       0xc4, 0x95, 0x21, 0xf4, 0x8b, 0xf8, 0xfd, 0x28, 0xd7, 0x7f, 0x25, 0xe3,
-       0xfb, 0xfe, 0x1a, 0x74, 0x79, 0xfe, 0x8e, 0x75, 0xee, 0xdc, 0x67, 0x74,
-       0xb9, 0xef, 0x63, 0x69, 0x3c, 0xcb, 0x78, 0xf8, 0xb6, 0x8f, 0xe1, 0xd8,
-       0xc6, 0xba, 0x1e, 0x72, 0xf5, 0xf3, 0x26, 0xbe, 0x3b, 0x25, 0x7f, 0x3e,
-       0x0c, 0x39, 0x20, 0x2f, 0x5e, 0xf0, 0xc6, 0x62, 0xee, 0x7b, 0x1a, 0x3a,
-       0xd2, 0xcf, 0x84, 0xa5, 0xe9, 0x4c, 0xa7, 0x84, 0xbe, 0xd2, 0x26, 0xcd,
-       0x5f, 0xe9, 0x11, 0xe3, 0x2b, 0xac, 0x3f, 0x58, 0xb1, 0x93, 0xaa, 0xf6,
-       0x91, 0x96, 0x53, 0x88, 0x61, 0x3a, 0xe2, 0xb1, 0xb2, 0x53, 0x73, 0xa7,
-       0x18, 0x48, 0x5e, 0xf5, 0x67, 0x5c, 0xf9, 0xe2, 0xbe, 0x9f, 0xab, 0xda,
-       0x1b, 0x70, 0xb3, 0xe8, 0xcf, 0x67, 0xc4, 0xad, 0xbd, 0x46, 0x3b, 0xcd,
-       0xbc, 0x7a, 0xd7, 0x1d, 0xd0, 0x39, 0x73, 0xcb, 0x5e, 0x55, 0xc7, 0xfd,
-       0xe2, 0x3e, 0xc6, 0x4c, 0x2f, 0xbf, 0x4c, 0x23, 0xbf, 0x9c, 0x94, 0x6e,
-       0xf8, 0x59, 0xf6, 0xdb, 0x29, 0x3a, 0xe6, 0xca, 0x09, 0xf3, 0xf5, 0x3b,
-       0xc5, 0x3d, 0x8c, 0x75, 0x71, 0x56, 0x66, 0xf4, 0x84, 0xa6, 0xc6, 0x34,
-       0x9e, 0xa1, 0xdf, 0xa2, 0x3f, 0xa3, 0x8d, 0xb3, 0x0e, 0x82, 0xb6, 0xe7,
-       0xe9, 0xb3, 0x3c, 0xdb, 0x1e, 0x6a, 0xf0, 0x7d, 0x53, 0xa5, 0x1a, 0x74,
-       0x88, 0xbc, 0xde, 0x6e, 0x02, 0xff, 0x88, 0xeb, 0x36, 0xaf, 0xc9, 0x3f,
-       0x7c, 0x69, 0x24, 0xa2, 0xae, 0x0b, 0x65, 0x0f, 0xf7, 0x7a, 0xe3, 0x33,
-       0x07, 0x81, 0xaf, 0xa9, 0x91, 0x0e, 0xce, 0xdb, 0x25, 0xc6, 0xd9, 0x88,
-       0x84, 0xce, 0xd2, 0xfe, 0xac, 0x58, 0x1a, 0xf2, 0x9b, 0xb2, 0x89, 0xf5,
-       0x0e, 0xc0, 0x17, 0xec, 0x16, 0xfd, 0x7c, 0x2f, 0xd6, 0x8e, 0x15, 0x2d,
-       0x4b, 0x5c, 0x8c, 0x85, 0xb0, 0xbc, 0x09, 0xdf, 0x41, 0x7b, 0x39, 0x87,
-       0x78, 0x75, 0xa2, 0xd6, 0xfa, 0xce, 0x8a, 0xa2, 0x82, 0x6d, 0x43, 0xc0,
-       0x4b, 0x56, 0xaf, 0xab, 0xb7, 0xcb, 0xeb, 0xd0, 0x77, 0x56, 0xb5, 0xed,
-       0xc6, 0xb8, 0xa0, 0xe1, 0x2c, 0xeb, 0x49, 0x1c, 0xf7, 0x1f, 0x60, 0x4c,
-       0x8e, 0xed, 0x66, 0x56, 0x99, 0x9f, 0x4e, 0xd3, 0x76, 0x3b, 0x61, 0x77,
-       0xb8, 0xae, 0x35, 0x4b, 0x76, 0x2c, 0x26, 0xfa, 0xf4, 0x83, 0xd2, 0xbd,
-       0x4f, 0xf7, 0xf8, 0x51, 0x3c, 0xb2, 0x8d, 0x75, 0xca, 0x16, 0xb5, 0x1e,
-       0xf5, 0x65, 0xd8, 0xcc, 0x41, 0xea, 0x18, 0xf1, 0x1f, 0xf1, 0x8d, 0xfe,
-       0xcc, 0x40, 0x7c, 0x4b, 0xd5, 0x3c, 0xbd, 0x97, 0x0f, 0xee, 0x94, 0x53,
-       0x67, 0x69, 0x4f, 0xb8, 0xb7, 0x6e, 0x53, 0xc1, 0x7e, 0x02, 0xef, 0xd9,
-       0x72, 0xfa, 0x59, 0xe6, 0x1f, 0xcc, 0x3b, 0x98, 0x6b, 0x59, 0xd1, 0xfd,
-       0xe0, 0x47, 0xbf, 0x8f, 0xfe, 0x40, 0x57, 0xb6, 0x9b, 0x83, 0xaf, 0x2e,
-       0xd4, 0xa8, 0xb7, 0x7e, 0xee, 0xb9, 0x98, 0xcc, 0xd9, 0xdc, 0xa8, 0x27,
-       0xef, 0x02, 0xda, 0x26, 0x11, 0x07, 0x52, 0xd5, 0x26, 0x59, 0x1b, 0x73,
-       0xa1, 0xfb, 0x8f, 0x82, 0xae, 0xc3, 0xad, 0xc4, 0xab, 0x6b, 0x63, 0x69,
-       0x5c, 0x1f, 0x56, 0x79, 0x9a, 0x71, 0x9f, 0x8b, 0x31, 0x76, 0x72, 0x1d,
-       0xf9, 0x7a, 0x72, 0xf4, 0xc2, 0xcc, 0x7d, 0xfa, 0x24, 0x7c, 0xf7, 0xb0,
-       0xc3, 0x18, 0xcf, 0xfa, 0x73, 0x0b, 0xe8, 0x68, 0x57, 0xd8, 0x42, 0xb7,
-       0xf7, 0xe9, 0x85, 0x32, 0xfd, 0x7d, 0x3e, 0xda, 0x2c, 0x0e, 0x7d, 0x96,
-       0xbe, 0x60, 0x53, 0x27, 0x9a, 0x5c, 0x54, 0xb5, 0x6a, 0x44, 0xa0, 0x6a,
-       0x0a, 0x73, 0x39, 0x7a, 0xa5, 0xbc, 0x4f, 0xcf, 0xc3, 0x55, 0xaf, 0x45,
-       0x48, 0x77, 0x4c, 0xe5, 0xf2, 0xfb, 0x94, 0xad, 0x15, 0x11, 0x53, 0x60,
-       0x33, 0xce, 0x1d, 0x98, 0x57, 0xb5, 0xc1, 0xa6, 0xa8, 0x7b, 0xea, 0x5d,
-       0xf9, 0x48, 0x5f, 0xf7, 0x37, 0x8a, 0xa1, 0x45, 0xf8, 0x5f, 0x62, 0xe9,
-       0x16, 0xbf, 0x3e, 0xf5, 0xcf, 0xfd, 0x9c, 0xe8, 0x71, 0x61, 0x9e, 0x32,
-       0x55, 0x22, 0x2d, 0x45, 0xf8, 0xc3, 0x1b, 0xd9, 0x12, 0xe5, 0xe8, 0xf9,
-       0x94, 0x63, 0xb0, 0x0b, 0x7d, 0xd9, 0xf4, 0x6d, 0x40, 0xe1, 0x67, 0xdc,
-       0x63, 0x0c, 0xc0, 0x77, 0xad, 0x09, 0xeb, 0x7d, 0x04, 0x32, 0xa2, 0x6e,
-       0xa0, 0xbf, 0x65, 0xee, 0xd5, 0x41, 0x7f, 0xcb, 0x97, 0x7e, 0xe1, 0x76,
-       0xd2, 0xe7, 0x0d, 0xc8, 0x29, 0xf8, 0xd1, 0x93, 0xf3, 0xa4, 0x27, 0xad,
-       0xd6, 0xce, 0x14, 0xe4, 0x7d, 0x42, 0xf9, 0xf8, 0x7e, 0x79, 0x73, 0xf1,
-       0x5b, 0x0a, 0x0b, 0xee, 0xd9, 0xb7, 0x22, 0x13, 0xf0, 0x0f, 0x47, 0xaa,
-       0x90, 0xb7, 0x19, 0xc3, 0xfa, 0xdc, 0xa5, 0xfc, 0xe3, 0x17, 0x3f, 0x78,
-       0xae, 0x12, 0xd2, 0x13, 0x0f, 0x7c, 0xc8, 0x18, 0xbe, 0x55, 0xdc, 0xce,
-       0x0f, 0x3c, 0x8f, 0xa1, 0x27, 0xfe, 0x10, 0x3a, 0xfb, 0x4d, 0xcc, 0x15,
-       0x06, 0x9d, 0x6a, 0x3f, 0xe4, 0x83, 0x3c, 0xa7, 0xeb, 0x89, 0x4f, 0x7e,
-       0x48, 0xfa, 0x4c, 0x59, 0x04, 0x7e, 0xc8, 0xab, 0xb8, 0xca, 0xdc, 0xb1,
-       0xc9, 0xd7, 0xe7, 0x0b, 0xc0, 0xd5, 0xc0, 0xd2, 0xc5, 0xc0, 0x17, 0xb7,
-       0x48, 0xbe, 0x33, 0xc8, 0x47, 0xe1, 0xc3, 0xd7, 0xdb, 0x83, 0x1c, 0x97,
-       0xcf, 0x67, 0x33, 0xc8, 0xa9, 0x61, 0x13, 0xb7, 0x61, 0x8d, 0xb2, 0x4d,
-       0xe5, 0xb0, 0x37, 0xa1, 0xdf, 0xa3, 0x3d, 0x57, 0x6c, 0xcc, 0x2d, 0x0e,
-       0xa8, 0xdc, 0x62, 0x68, 0x43, 0x6e, 0x11, 0xd4, 0xb4, 0x02, 0xba, 0x39,
-       0x2e, 0x70, 0x03, 0xec, 0xe0, 0xbb, 0x18, 0xff, 0x3b, 0xd0, 0xf7, 0xb7,
-       0x4b, 0xc0, 0x0d, 0x25, 0xe0, 0x86, 0x12, 0x70, 0x43, 0x09, 0xb8, 0xa1,
-       0x14, 0xf5, 0xeb, 0x5b, 0x2e, 0x71, 0xff, 0x07, 0xb4, 0xe9, 0xa0, 0xee,
-       0xb1, 0xd9, 0x5e, 0xbd, 0x3a, 0x59, 0xaa, 0x16, 0xe0, 0xe7, 0x30, 0xeb,
-       0x76, 0xc0, 0x71, 0x41, 0x4d, 0xc4, 0x8f, 0x1d, 0x8b, 0xdc, 0x43, 0x41,
-       0xec, 0x58, 0x74, 0xb1, 0x9e, 0xfa, 0xa2, 0x06, 0x70, 0xa3, 0x21, 0x51,
-       0xfc, 0x36, 0xe1, 0x93, 0xb9, 0x67, 0xde, 0x8d, 0x15, 0xd6, 0xac, 0x6a,
-       0x4f, 0x27, 0x54, 0x4d, 0xc2, 0x96, 0xc9, 0x72, 0x90, 0xdb, 0xc5, 0x65,
-       0x68, 0x86, 0x58, 0x54, 0xb6, 0xeb, 0x09, 0xe8, 0xa2, 0x4a, 0xfc, 0xc8,
-       0x3d, 0x27, 0xce, 0x1f, 0xef, 0xad, 0x60, 0xce, 0x82, 0xed, 0xd1, 0x77,
-       0xa2, 0xaa, 0xce, 0x05, 0xf8, 0xcf, 0x05, 0x67, 0x01, 0xe2, 0xb2, 0x7f,
-       0x86, 0x7b, 0xef, 0x31, 0x19, 0x2d, 0x3a, 0xc8, 0x65, 0x55, 0x8e, 0x84,
-       0x78, 0xe0, 0xc9, 0x7d, 0xc8, 0x97, 0x7b, 0x0e, 0xd8, 0x61, 0xdc, 0x0e,
-       0xe4, 0x4e, 0x79, 0x8f, 0x68, 0xc3, 0x90, 0xf5, 0x7e, 0x5f, 0xd6, 0xe9,
-       0x25, 0x31, 0x91, 0xff, 0xc4, 0x8c, 0x7d, 0x63, 0xda, 0x68, 0x4d, 0x61,
-       0x16, 0xfa, 0x23, 0x8c, 0xe5, 0x78, 0x6b, 0x1d, 0xf6, 0x92, 0xab, 0x6e,
-       0xde, 0x8f, 0x6f, 0xc4, 0x2f, 0x9f, 0xd5, 0xc4, 0x0e, 0xe4, 0xd8, 0xd8,
-       0x3e, 0xd1, 0xd0, 0xbe, 0x7e, 0xdf, 0xe7, 0x01, 0xbe, 0x72, 0xbd, 0x3e,
-       0x41, 0xbf, 0x76, 0xbd, 0x1d, 0x78, 0x4f, 0x42, 0xea, 0x3e, 0x7c, 0xfe,
-       0x62, 0x44, 0x52, 0x8b, 0xb6, 0xa4, 0xcb, 0xec, 0xc7, 0x9a, 0x07, 0xfd,
-       0xd7, 0x1f, 0x4b, 0x0a, 0x79, 0x6e, 0x36, 0x62, 0x39, 0xae, 0xfc, 0x47,
-       0x59, 0x9d, 0xcb, 0xc7, 0xb8, 0x77, 0x9d, 0x1f, 0xd5, 0xf0, 0xdc, 0x8f,
-       0x71, 0x4d, 0xda, 0x6d, 0xac, 0x0f, 0xc6, 0xa9, 0xbe, 0xe8, 0x22, 0xee,
-       0x65, 0xc7, 0x58, 0xe7, 0x79, 0x2a, 0x2c, 0x6d, 0x56, 0xac, 0x0c, 0x3b,
-       0xb8, 0x54, 0xe4, 0x7c, 0xc0, 0x52, 0x45, 0xd6, 0x82, 0x82, 0xfb, 0x7f,
-       0x0c, 0xec, 0xa8, 0x13, 0x3b, 0x79, 0x7d, 0x94, 0xbe, 0x5c, 0x33, 0x84,
-       0x35, 0xb0, 0xe2, 0xfb, 0xe7, 0x85, 0xa2, 0x57, 0x7b, 0x39, 0x47, 0x3a,
-       0xaa, 0x7f, 0x53, 0x5f, 0x89, 0x20, 0x67, 0x5a, 0xe7, 0xf1, 0x1c, 0xc7,
-       0x37, 0xe1, 0x9e, 0xe5, 0x64, 0x35, 0x90, 0x05, 0xef, 0xb3, 0x8d, 0xfb,
-       0xf3, 0xf5, 0xfa, 0x39, 0xfb, 0xc3, 0xd6, 0xd9, 0x9e, 0xbb, 0x27, 0x69,
-       0xcb, 0x81, 0x85, 0xaa, 0x1c, 0xf0, 0xea, 0x6c, 0xd1, 0xbd, 0x5e, 0x9d,
-       0x2d, 0xb6, 0x77, 0x63, 0x9d, 0xad, 0x7c, 0x8f, 0x57, 0x67, 0x33, 0x0f,
-       0xc0, 0x07, 0x1f, 0xf0, 0xea, 0x6c, 0xff, 0xf5, 0x1e, 0xaf, 0xce, 0xd6,
-       0x75, 0xaf, 0x57, 0x67, 0xeb, 0xdd, 0xeb, 0xd5, 0xd9, 0x46, 0xef, 0xdd,
-       0x58, 0x67, 0x73, 0xf6, 0x6e, 0xac, 0xb3, 0x39, 0x07, 0x72, 0xf8, 0x5c,
-       0xaf, 0xb3, 0x65, 0xf6, 0xde, 0xbc, 0xce, 0xf6, 0x4a, 0x80, 0xf1, 0xc1,
-       0xcf, 0x00, 0x78, 0x70, 0x80, 0xf1, 0xfb, 0x81, 0xf1, 0x6f, 0x56, 0xe3,
-       0x55, 0xe7, 0x37, 0xc0, 0xa7, 0xe6, 0xc7, 0x8f, 0x0f, 0x83, 0xf5, 0xb7,
-       0xfa, 0xcf, 0xba, 0xc8, 0x8f, 0x63, 0x7e, 0x6e, 0x43, 0xbc, 0xbf, 0xcd,
-       0xcf, 0xf1, 0xba, 0x5a, 0xaf, 0x9f, 0xad, 0x68, 0xfc, 0xbe, 0x0d, 0xa9,
-       0x7a, 0x50, 0x03, 0x20, 0x5f, 0x72, 0xe0, 0x61, 0x25, 0x87, 0x3b, 0xd1,
-       0xdf, 0x3c, 0xf0, 0x25, 0x9b, 0x75, 0x81, 0x27, 0xb1, 0x86, 0xdd, 0xed,
-       0x86, 0xda, 0x67, 0x66, 0x4c, 0x3b, 0x2d, 0x29, 0xf4, 0x4f, 0xa9, 0xfe,
-       0xa3, 0x0d, 0xfd, 0xb3, 0xe8, 0xcf, 0x71, 0xad, 0x7f, 0x8b, 0xcf, 0x73,
-       0xca, 0xbe, 0x6d, 0x0f, 0xf7, 0xa7, 0x4b, 0x01, 0x4e, 0x0b, 0xf9, 0x18,
-       0xdc, 0xcd, 0xb8, 0xd5, 0x7b, 0xf1, 0x8c, 0xf5, 0xa2, 0x2b, 0x57, 0x15,
-       0xde, 0x37, 0x12, 0xd6, 0x8b, 0x59, 0x95, 0xdf, 0xb9, 0x99, 0x5c, 0x75,
-       0x3d, 0x5f, 0x07, 0x0e, 0x63, 0xce, 0x03, 0x7b, 0x5f, 0xee, 0x45, 0xdc,
-       0x6b, 0xcc, 0xc9, 0x99, 0x87, 0xeb, 0x7e, 0x1e, 0x6e, 0xca, 0xfd, 0xfb,
-       0x1a, 0x31, 0xbe, 0x73, 0xe0, 0xef, 0x2b, 0x8c, 0xbf, 0x05, 0xb9, 0x3c,
-       0x31, 0x3c, 0x71, 0x0f, 0x31, 0x07, 0x71, 0x3e, 0xeb, 0x0b, 0xcc, 0x7f,
-       0x18, 0x4b, 0x99, 0x0f, 0x45, 0xf0, 0xe1, 0xb9, 0x97, 0x00, 0xeb, 0x37,
-       0xfb, 0xfe, 0x9f, 0x79, 0x54, 0x80, 0x6d, 0xac, 0x2d, 0x5e, 0x2e, 0xb5,
-       0x45, 0xf3, 0xf2, 0xd5, 0x98, 0xdf, 0x27, 0xb4, 0x8e, 0xa5, 0x43, 0xeb,
-       0x58, 0x7a, 0xc3, 0x5e, 0x89, 0xa8, 0x33, 0x36, 0x6a, 0xcf, 0x85, 0x7b,
-       0x30, 0x6e, 0xe6, 0x52, 0x0f, 0xf1, 0x30, 0xf7, 0x62, 0x80, 0x8d, 0xec,
-       0xc6, 0x58, 0xc5, 0x38, 0x45, 0x3c, 0x15, 0xec, 0xb7, 0x06, 0x7a, 0xa2,
-       0xec, 0xd8, 0xf6, 0x47, 0x1a, 0x72, 0x64, 0xa7, 0xd9, 0xde, 0x0f, 0x5a,
-       0x32, 0xf8, 0x0e, 0x64, 0xfa, 0x80, 0x8a, 0x91, 0x2d, 0xb0, 0xdd, 0x13,
-       0x25, 0x62, 0xde, 0x6d, 0xb2, 0xe8, 0xe3, 0xde, 0xf3, 0x33, 0x1e, 0xe6,
-       0x0d, 0x6d, 0xc4, 0xbc, 0xce, 0xaa, 0x78, 0x34, 0xee, 0xbf, 0x21, 0x8d,
-       0xc4, 0xb7, 0xa4, 0x8f, 0x31, 0x89, 0xfe, 0xd1, 0xcd, 0x5c, 0xee, 0x61,
-       0x3c, 0x62, 0x2c, 0x8a, 0xc9, 0xea, 0x4d, 0xe9, 0x53, 0x6d, 0xc7, 0x5a,
-       0xec, 0x30, 0x3e, 0x13, 0xf0, 0x1f, 0xa3, 0x78, 0x26, 0x23, 0x93, 0xb3,
-       0x5f, 0x00, 0x6f, 0x13, 0x72, 0x69, 0x66, 0x0c, 0xf4, 0x3d, 0x29, 0x53,
-       0x4e, 0x1e, 0x7e, 0x84, 0x7b, 0x21, 0xc4, 0x79, 0xdd, 0xfe, 0xf7, 0x84,
-       0x7e, 0xce, 0xb6, 0x88, 0x33, 0xa5, 0x52, 0xa4, 0x0f, 0xe6, 0xbe, 0x14,
-       0xf7, 0x1f, 0x69, 0x3f, 0xac, 0xc3, 0x20, 0xd7, 0x65, 0xce, 0x3b, 0xcd,
-       0xf9, 0x37, 0xea, 0x64, 0xb5, 0x4a, 0xbc, 0xe6, 0x66, 0x56, 0x96, 0x89,
-       0x37, 0x3f, 0x28, 0xf6, 0xa4, 0x1e, 0x88, 0x3f, 0x6f, 0x05, 0x77, 0x5a,
-       0x33, 0xc0, 0x9c, 0x2f, 0xac, 0xe8, 0x8d, 0xb8, 0xd3, 0xc3, 0x9c, 0xc9,
-       0xe5, 0x2c, 0xc6, 0x74, 0x14, 0xb6, 0x46, 0xde, 0x07, 0xb7, 0xd7, 0x8d,
-       0x67, 0xbb, 0x91, 0xc3, 0x7b, 0x18, 0x33, 0x05, 0x8c, 0xf9, 0x0f, 0x81,
-       0x31, 0x27, 0xe5, 0xad, 0x56, 0x62, 0x4c, 0xd7, 0xc7, 0x98, 0x69, 0xd8,
-       0x73, 0x6e, 0x83, 0x3d, 0x6b, 0xaa, 0x76, 0xc5, 0x7b, 0x39, 0x60, 0xc4,
-       0xd4, 0xb4, 0x75, 0x0b, 0xb8, 0x52, 0x93, 0x88, 0x3a, 0xfb, 0x10, 0x6a,
-       0x18, 0x33, 0xc0, 0x8f, 0x7b, 0x14, 0x2e, 0x3c, 0x50, 0xda, 0x82, 0x1c,
-       0x46, 0xe1, 0x44, 0x7f, 0x4f, 0x2e, 0xb4, 0x69, 0x9f, 0x32, 0xd4, 0xb0,
-       0x4f, 0x79, 0x1d, 0x4f, 0xe2, 0x39, 0xbf, 0x3e, 0xd8, 0x04, 0x5f, 0xf0,
-       0x7f, 0x40, 0x13, 0xd7, 0x17, 0xd7, 0x82, 0xe6, 0xad, 0x97, 0xd1, 0x46,
-       0x5c, 0xf9, 0xbf, 0x36, 0xe1, 0x4a, 0xc4, 0xae, 0xf3, 0x11, 0x49, 0x02,
-       0x53, 0xba, 0xcb, 0x1c, 0x8b, 0x6b, 0xba, 0x5f, 0x9a, 0xc1, 0x5f, 0xcb,
-       0x74, 0x27, 0xb0, 0x54, 0x9b, 0x84, 0x81, 0xa9, 0x9a, 0x14, 0xa6, 0xea,
-       0x21, 0xf6, 0xe9, 0x3d, 0x02, 0x2c, 0xb4, 0xb8, 0x8e, 0xab, 0x2c, 0xe7,
-       0x87, 0xd0, 0xcb, 0xa3, 0xca, 0xf7, 0xa4, 0xe5, 0x29, 0xf8, 0xd2, 0xe6,
-       0x65, 0xe0, 0xc1, 0xf3, 0x1e, 0xde, 0x6a, 0xda, 0x84, 0xb7, 0x8e, 0xde,
-       0x10, 0x6f, 0xa9, 0x9a, 0xff, 0x20, 0x65, 0xf2, 0x7a, 0xd5, 0xab, 0xf9,
-       0x5f, 0xa9, 0x7a, 0x35, 0xff, 0xd7, 0xab, 0x8d, 0x35, 0xff, 0x8f, 0x48,
-       0xc1, 0xb4, 0xdc, 0x35, 0xd9, 0x54, 0xf3, 0x1f, 0x65, 0x0d, 0xfd, 0xf7,
-       0xda, 0xbc, 0xda, 0x7e, 0x9b, 0x5f, 0xf3, 0xb7, 0xa4, 0xb0, 0xa1, 0xdd,
-       0x94, 0xb7, 0xec, 0xa0, 0xe6, 0xff, 0x34, 0xda, 0xda, 0x31, 0xc7, 0xc6,
-       0x7a, 0xff, 0x95, 0x2a, 0xeb, 0xfd, 0x11, 0xf6, 0xf3, 0xeb, 0xfd, 0xec,
-       0x87, 0xdc, 0xbf, 0xca, 0x5a, 0xff, 0x6e, 0xc8, 0x62, 0x27, 0xe4, 0xd0,
-       0x29, 0xcd, 0x67, 0xa3, 0xec, 0xa3, 0x6a, 0xfc, 0x6b, 0xc8, 0x37, 0xae,
-       0x54, 0xbd, 0x5a, 0xfc, 0x11, 0xd8, 0xd5, 0xd1, 0xf5, 0x1a, 0xbf, 0x37,
-       0xc7, 0xd5, 0xea, 0xc6, 0xf1, 0x37, 0x8e, 0xd3, 0xe5, 0x8f, 0x13, 0xc1,
-       0x38, 0xd1, 0x4d, 0xe3, 0x5c, 0xaf, 0xe9, 0x5f, 0xad, 0x7a, 0xf5, 0xfc,
-       0xf4, 0xac, 0xb8, 0xcd, 0xf0, 0xcd, 0x2f, 0xf6, 0xec, 0xf2, 0xc7, 0x58,
-       0xaf, 0xe7, 0xd3, 0x87, 0x00, 0xe7, 0xc7, 0xd5, 0xf9, 0x9e, 0x23, 0xff,
-       0x1f, 0xea, 0xf9, 0xac, 0xe5, 0x7b, 0x7b, 0x32, 0x5c, 0x9f, 0xc0, 0xf3,
-       0xcf, 0x7a, 0x75, 0xfc, 0xa1, 0x52, 0x50, 0x9f, 0x67, 0x5e, 0x19, 0x9c,
-       0xbd, 0xe9, 0x8e, 0x9d, 0x10, 0xda, 0x0a, 0xe9, 0xe3, 0xb8, 0xed, 0x32,
-       0xae, 0xf0, 0x14, 0x6c, 0x2a, 0x7e, 0x73, 0x4c, 0xbd, 0x30, 0x1d, 0x60,
-       0xea, 0x88, 0xc2, 0xd4, 0x0b, 0xcb, 0x01, 0xa6, 0x4e, 0xde, 0x04, 0x53,
-       0xff, 0xf7, 0x36, 0x2f, 0x0e, 0x84, 0x25, 0xaf, 0x30, 0xf5, 0xcd, 0xce,
-       0x2b, 0xf1, 0x5e, 0x1b, 0xf1, 0x82, 0x78, 0x7b, 0xd8, 0x9d, 0x37, 0x59,
-       0x6b, 0x01, 0xce, 0x66, 0xec, 0xdf, 0x29, 0xa3, 0x67, 0xaf, 0xe3, 0x6c,
-       0x0f, 0x4b, 0x5b, 0xb1, 0x63, 0x2a, 0x26, 0x02, 0xd7, 0xd5, 0x58, 0x2f,
-       0x27, 0x56, 0x66, 0xcc, 0x09, 0x29, 0x3c, 0x97, 0x2b, 0x32, 0x0f, 0x60,
-       0x1b, 0xb1, 0x73, 0x2b, 0x8f, 0xf2, 0xf8, 0x31, 0x29, 0xc0, 0xa6, 0xc1,
-       0xd9, 0x09, 0xee, 0x4b, 0xbc, 0x65, 0x24, 0x6d, 0xb4, 0x57, 0x83, 0x5c,
-       0xc1, 0x51, 0x67, 0x4e, 0x92, 0xc0, 0x3f, 0xe3, 0xeb, 0xd8, 0x93, 0xbe,
-       0xe2, 0x47, 0xbf, 0x70, 0x4d, 0xfa, 0xb5, 0x00, 0x5b, 0x22, 0x27, 0x2a,
-       0x71, 0x6d, 0x07, 0xd8, 0xd2, 0xc3, 0x95, 0xa9, 0xea, 0x0a, 0xf0, 0x75,
-       0x48, 0x86, 0x80, 0xeb, 0x57, 0x1e, 0x66, 0xcd, 0x2a, 0xc0, 0x4e, 0x2e,
-       0xbe, 0x1b, 0x6b, 0x58, 0xbc, 0x6e, 0x56, 0x7b, 0x87, 0x17, 0x7b, 0xc2,
-       0x0d, 0xed, 0xbf, 0x05, 0xff, 0x8d, 0xfc, 0x08, 0x98, 0xc5, 0xc3, 0x4c,
-       0x7b, 0xa1, 0x83, 0x01, 0x85, 0x99, 0xa6, 0xde, 0x83, 0x99, 0x36, 0xc7,
-       0x28, 0xc6, 0xcc, 0xeb, 0x31, 0x2a, 0x5d, 0xa3, 0x3f, 0xbf, 0x1e, 0xa3,
-       0x6e, 0x1e, 0x43, 0xd9, 0x06, 0xee, 0xec, 0x0c, 0x3e, 0x13, 0x52, 0xd8,
-       0x14, 0xa3, 0xa6, 0x3e, 0x44, 0x8c, 0x1a, 0x56, 0x31, 0xca, 0xa3, 0xfb,
-       0xfb, 0x90, 0xcd, 0x77, 0x21, 0xd3, 0xef, 0x00, 0x8b, 0x7d, 0x1b, 0x7c,
-       0x7d, 0x0b, 0x38, 0xe9, 0x9b, 0xa5, 0xcd, 0x67, 0x0e, 0x06, 0x85, 0xf9,
-       0xa1, 0x87, 0xa5, 0xbc, 0x1a, 0xc0, 0x11, 0xac, 0xae, 0xc5, 0xa2, 0x9b,
-       0x19, 0x2f, 0xf6, 0x99, 0x13, 0xde, 0xde, 0x6b, 0x2c, 0x2b, 0x8f, 0xb5,
-       0xa6, 0xe6, 0x19, 0x33, 0xd4, 0x75, 0x94, 0xf5, 0x4e, 0x62, 0x87, 0x8a,
-       0xca, 0x33, 0x7b, 0xa4, 0xbc, 0xe8, 0xe1, 0xb0, 0xa9, 0x79, 0x6f, 0x8c,
-       0x71, 0x1f, 0x87, 0xe5, 0x7c, 0x1c, 0x96, 0x5d, 0x5c, 0x8d, 0x85, 0xd0,
-       0x7f, 0xca, 0xd9, 0x88, 0xbd, 0x8e, 0xf8, 0xd8, 0x6b, 0xe2, 0x43, 0x61,
-       0x2f, 0x6f, 0xae, 0x1c, 0x9e, 0x19, 0x9e, 0x89, 0xc9, 0x7e, 0xc8, 0x79,
-       0xa8, 0x48, 0x7d, 0xf1, 0x9c, 0xd2, 0x2f, 0xd3, 0x19, 0xf5, 0xe5, 0xe9,
-       0x2a, 0x14, 0x3f, 0xa8, 0x0d, 0x43, 0x57, 0x43, 0xbf, 0x54, 0x57, 0x62,
-       0xbe, 0x39, 0x10, 0xc6, 0xe7, 0x6f, 0x4b, 0x57, 0xe4, 0x83, 0xfa, 0xda,
-       0x8c, 0xc5, 0x6e, 0x05, 0x93, 0x6d, 0xc4, 0x63, 0xae, 0xc2, 0x63, 0xcd,
-       0x7e, 0x9f, 0xfc, 0x81, 0x61, 0xe8, 0xf2, 0x3f, 0xa0, 0xcf, 0x8f, 0xed,
-       0x76, 0xf9, 0x11, 0xfc, 0xf7, 0xbf, 0x87, 0x4e, 0xfe, 0x1d, 0x72, 0x85,
-       0x57, 0xec, 0x2e, 0xf9, 0x21, 0xda, 0xae, 0xe3, 0x1c, 0xf6, 0x9f, 0x72,
-       0x92, 0xf6, 0x28, 0xf0, 0xc9, 0xa8, 0x8f, 0x4f, 0xde, 0x7a, 0x20, 0x69,
-       0x8f, 0xb1, 0xce, 0x0e, 0x39, 0xff, 0x34, 0x39, 0xae, 0xb0, 0x49, 0x80,
-       0x49, 0x1e, 0x4f, 0x73, 0xfe, 0xc9, 0x6a, 0x16, 0xd8, 0x27, 0xeb, 0x63,
-       0x9f, 0x9f, 0xa6, 0x3d, 0xec, 0x33, 0xf5, 0xf7, 0xa8, 0x7f, 0x0f, 0xf7,
-       0x1c, 0x76, 0x93, 0x98, 0x07, 0xb8, 0x07, 0xd7, 0x87, 0x25, 0x5f, 0x1b,
-       0x51, 0x9f, 0x13, 0x25, 0xd7, 0x6a, 0x82, 0x9c, 0x58, 0xab, 0x3d, 0xc3,
-       0x55, 0x59, 0xb5, 0xcc, 0x22, 0xbe, 0xb3, 0x55, 0x2b, 0xfa, 0x7b, 0xfe,
-       0xf5, 0xd3, 0xfe, 0xf5, 0x53, 0xfe, 0xf5, 0x69, 0xc4, 0xe1, 0x53, 0x2a,
-       0x96, 0xb2, 0x9d, 0x6d, 0x50, 0x72, 0x15, 0x63, 0x01, 0x7b, 0x9c, 0xeb,
-       0xff, 0xf3, 0x7a, 0x59, 0xe9, 0x98, 0xe3, 0x8f, 0xe2, 0x73, 0x1a, 0x9f,
-       0x09, 0x7c, 0x0e, 0xe1, 0x93, 0xc7, 0x67, 0x5d, 0xa6, 0x5a, 0xaa, 0x34,
-       0x06, 0x1b, 0xe9, 0x95, 0x54, 0xed, 0x39, 0xe8, 0xf1, 0x49, 0xe8, 0xf6,
-       0xb8, 0x14, 0x2a, 0x7f, 0x22, 0x93, 0x33, 0x9a, 0xb4, 0xd9, 0xd0, 0x69,
-       0x05, 0xb6, 0x3c, 0xe3, 0xed, 0x41, 0xb6, 0x26, 0x46, 0xd0, 0xb7, 0x2e,
-       0x8f, 0x3a, 0x4f, 0x8a, 0x7e, 0xdf, 0x14, 0xfa, 0x89, 0x5e, 0xe8, 0xbf,
-       0x5b, 0xed, 0xbf, 0x55, 0x1c, 0x4f, 0xc6, 0xfb, 0x6d, 0xd7, 0x82, 0xce,
-       0x7b, 0x4f, 0x61, 0xec, 0xa4, 0x3a, 0x7f, 0x99, 0x91, 0x93, 0xb3, 0xab,
-       0xdb, 0x3d, 0xdf, 0x6a, 0x99, 0x57, 0xa9, 0x77, 0xf0, 0xe1, 0xc2, 0x17,
-       0x66, 0x60, 0xef, 0x47, 0xab, 0x21, 0x6d, 0x08, 0xf1, 0x66, 0xa8, 0x7a,
-       0x55, 0xc5, 0x9b, 0x54, 0xd5, 0xcd, 0xc4, 0xcf, 0x44, 0x70, 0xcd, 0x73,
-       0x31, 0x88, 0x8b, 0xea, 0xfc, 0xde, 0x2a, 0xf0, 0x8d, 0xa6, 0xea, 0x86,
-       0x93, 0xeb, 0xfb, 0x4a, 0xea, 0x7c, 0x71, 0x26, 0x1e, 0xd7, 0x25, 0x37,
-       0x40, 0x9c, 0x3b, 0xa2, 0x62, 0x13, 0xd6, 0xea, 0xed, 0xcc, 0x15, 0x5f,
-       0xe7, 0xbb, 0x00, 0xf6, 0x27, 0xd0, 0xaf, 0x0b, 0xfe, 0x18, 0xf7, 0x6a,
-       0xb4, 0x4f, 0xf2, 0xca, 0x67, 0x26, 0xa4, 0x52, 0x1e, 0x04, 0xbf, 0x7e,
-       0x8e, 0xa4, 0x72, 0x89, 0x18, 0xec, 0x31, 0xd8, 0xc3, 0xf2, 0xea, 0x2a,
-       0x95, 0x6a, 0x80, 0x29, 0xda, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xed,
-       0xbf, 0xa9, 0xbd, 0xb7, 0x42, 0x75, 0x10, 0x72, 0x4a, 0xa2, 0x9d, 0xb5,
-       0x6d, 0xfc, 0x2e, 0xeb, 0xaa, 0x26, 0xb0, 0x66, 0x1c, 0x91, 0xc5, 0x72,
-       0x1d, 0xf4, 0x22, 0xe6, 0x6e, 0x3f, 0x22, 0x0b, 0xe5, 0x09, 0x79, 0xa1,
-       0xfc, 0xcd, 0x76, 0x60, 0x2a, 0xc8, 0x94, 0xf4, 0xb7, 0xcb, 0xf5, 0x33,
-       0x9e, 0x41, 0x3b, 0xe4, 0x39, 0x9b, 0x8f, 0x7a, 0x79, 0x6e, 0x5e, 0xd5,
-       0x68, 0xbc, 0x6f, 0x57, 0x1f, 0xb7, 0xad, 0xe8, 0x24, 0x7a, 0x1e, 0x9d,
-       0x53, 0xb6, 0x39, 0x3c, 0x65, 0xef, 0x95, 0xcb, 0xce, 0x36, 0x59, 0x75,
-       0x54, 0x5e, 0x4c, 0xfc, 0x80, 0xb5, 0x6e, 0x99, 0x2b, 0xf2, 0xa0, 0x9c,
-       0xc4, 0xba, 0xbd, 0xec, 0x3c, 0x06, 0x3b, 0x7d, 0x02, 0xb6, 0xc0, 0x1a,
-       0xc0, 0x31, 0xe6, 0x5a, 0xb2, 0xa2, 0x6a, 0x68, 0xf5, 0xfa, 0xb0, 0x3a,
-       0x27, 0xdc, 0x2c, 0xab, 0x0a, 0x8b, 0x79, 0xb5, 0xf6, 0xd5, 0x31, 0x6f,
-       0x8d, 0x18, 0xca, 0xee, 0xbf, 0x01, 0x7a, 0x8a, 0xb0, 0xdd, 0x26, 0xd5,
-       0xc7, 0x48, 0xb4, 0xf8, 0x7d, 0x14, 0x06, 0x6d, 0xe8, 0x63, 0x27, 0x92,
-       0xf6, 0x6b, 0xfb, 0x92, 0xf6, 0xc4, 0x81, 0x5c, 0xd5, 0xf3, 0x99, 0xae,
-       0xb6, 0xb6, 0x5e, 0xff, 0xc9, 0x60, 0x5d, 0xbd, 0xbc, 0x8e, 0xa1, 0x61,
-       0xa4, 0xcf, 0x5f, 0x82, 0x7e, 0x43, 0xd2, 0x7c, 0xa6, 0xfe, 0x89, 0x71,
-       0xa7, 0x2f, 0x76, 0x54, 0x78, 0x32, 0x8b, 0x79, 0xb5, 0xe5, 0x64, 0xe5,
-       0x12, 0xe2, 0xe4, 0x35, 0x62, 0x87, 0xde, 0x8b, 0x72, 0xed, 0x13, 0x49,
-       0x67, 0x50, 0x5b, 0x18, 0x43, 0xd6, 0xf2, 0xfc, 0x18, 0xe3, 0xec, 0x31,
-       0x11, 0xe0, 0xcb, 0x33, 0x03, 0x92, 0x2e, 0xaa, 0x77, 0x21, 0x78, 0x96,
-       0x53, 0x9b, 0x80, 0xfc, 0xf0, 0xfc, 0x28, 0x03, 0xa3, 0x6e, 0x77, 0xc7,
-       0xd2, 0xf2, 0x18, 0x6b, 0x63, 0x92, 0x9b, 0x93, 0x3d, 0x49, 0xf8, 0x55,
-       0x77, 0xb4, 0x59, 0x26, 0x16, 0xdd, 0x4c, 0xf7, 0xf4, 0x13, 0x18, 0x63,
-       0x1c, 0x63, 0x8d, 0x20, 0x37, 0xc9, 0x22, 0x56, 0x53, 0xbe, 0xf4, 0xdd,
-       0x8f, 0x43, 0x46, 0x1f, 0xe1, 0x59, 0xd7, 0xc1, 0xac, 0x58, 0xa3, 0x79,
-       0x35, 0xee, 0xbb, 0x5a, 0xae, 0xff, 0x57, 0x10, 0xeb, 0x42, 0xb2, 0x3f,
-       0x2e, 0xfa, 0x48, 0x3c, 0xf4, 0x8b, 0x71, 0x9b, 0x6d, 0x61, 0xb6, 0xe9,
-       0x68, 0x0b, 0xfd, 0x66, 0x3c, 0xac, 0x27, 0xe3, 0xd6, 0x20, 0xcf, 0xe0,
-       0x1a, 0xf6, 0xb8, 0x18, 0xcf, 0xd7, 0x21, 0x8b, 0x11, 0xe9, 0xb8, 0x60,
-       0x0d, 0xbe, 0x0e, 0x5a, 0x42, 0xca, 0xd7, 0x8f, 0x8b, 0xee, 0xb7, 0xb7,
-       0xaf, 0xb7, 0x87, 0xfc, 0xf6, 0x11, 0x69, 0xbb, 0xd0, 0x67, 0xbe, 0x21,
-       0x47, 0x30, 0xa6, 0x21, 0x57, 0x90, 0xeb, 0xd8, 0x3d, 0xe3, 0xb0, 0xc5,
-       0x47, 0x48, 0xcb, 0x21, 0xd6, 0x1b, 0x5d, 0xd8, 0x5f, 0x8b, 0x7d, 0x87,
-       0x7c, 0xde, 0x6c, 0x95, 0x9c, 0xca, 0x75, 0x43, 0xea, 0xbd, 0x85, 0x1c,
-       0xec, 0xfd, 0xae, 0x9e, 0xa1, 0x0e, 0xaf, 0x5e, 0xc0, 0xfd, 0x91, 0x7e,
-       0xb4, 0x5d, 0xab, 0x9f, 0xb7, 0xd9, 0xc6, 0x7b, 0xd7, 0xea, 0x15, 0xbb,
-       0xcf, 0x4c, 0x69, 0x61, 0x7f, 0xff, 0xfc, 0x98, 0xe2, 0x3d, 0x5f, 0xee,
-       0x36, 0x17, 0xe4, 0x2e, 0x2d, 0xb5, 0x03, 0xf1, 0xa2, 0x9a, 0x42, 0xdf,
-       0x6b, 0x3c, 0x83, 0xa1, 0xf6, 0x03, 0x16, 0x24, 0xb8, 0xe6, 0x38, 0x7d,
-       0xe6, 0xb0, 0x7a, 0xb6, 0xcf, 0x3c, 0xa9, 0x35, 0x3e, 0x1b, 0xd5, 0x86,
-       0x37, 0x3c, 0xdb, 0xa6, 0x64, 0x64, 0xd8, 0x5e, 0x9f, 0xc9, 0xf2, 0x88,
-       0x3c, 0x5d, 0x65, 0xbf, 0x6b, 0xf5, 0x94, 0xbd, 0x55, 0x3b, 0xb9, 0x83,
-       0xbe, 0x90, 0x7d, 0xdf, 0xd9, 0x34, 0x0f, 0xaf, 0x6f, 0x36, 0x47, 0x5d,
-       0x36, 0xce, 0xb1, 0x45, 0xf5, 0xb9, 0xac, 0xfa, 0x84, 0x94, 0xac, 0x37,
-       0xce, 0xf3, 0x17, 0xb2, 0x71, 0x9e, 0xb6, 0x75, 0x9e, 0x27, 0x31, 0xe6,
-       0x29, 0xf4, 0x2d, 0x56, 0xbb, 0xa3, 0x15, 0x79, 0xa7, 0x9e, 0xb3, 0xdf,
-       0x92, 0xcb, 0xeb, 0x63, 0xff, 0x25, 0xae, 0x1b, 0x69, 0xfa, 0x4b, 0x9f,
-       0x46, 0xfe, 0x66, 0xdb, 0x3f, 0x53, 0xf2, 0xde, 0x6a, 0x77, 0x1f, 0x5a,
-       0xd0, 0xac, 0xc1, 0x9f, 0x09, 0x75, 0xf5, 0x3b, 0xca, 0xd7, 0xdc, 0x0d,
-       0x3d, 0xed, 0x79, 0x06, 0x6b, 0xb7, 0x3f, 0xa9, 0xfa, 0x5c, 0xb1, 0x47,
-       0x64, 0xcf, 0x99, 0x6e, 0xf3, 0x8a, 0xdc, 0x2f, 0xe9, 0x08, 0xaf, 0x91,
-       0x43, 0xd9, 0x7c, 0xf7, 0xe1, 0x57, 0x99, 0x17, 0x40, 0x97, 0xdd, 0xbd,
-       0x3f, 0x93, 0x27, 0xe4, 0x64, 0x69, 0x0a, 0xbe, 0x67, 0x5c, 0x7a, 0x9f,
-       0xa1, 0xff, 0xc9, 0x9b, 0x5e, 0xad, 0xc6, 0x8b, 0x89, 0x29, 0x3f, 0x26,
-       0x4e, 0x29, 0x3f, 0xf7, 0x8a, 0x7f, 0x8e, 0xa2, 0xbb, 0xf7, 0x3c, 0x9e,
-       0x7d, 0x41, 0xf9, 0x80, 0x6f, 0x48, 0x05, 0x6b, 0x21, 0xf6, 0xfc, 0x36,
-       0xd9, 0xfa, 0x10, 0x6d, 0x12, 0x19, 0xc0, 0xdd, 0x4d, 0xea, 0x5d, 0x0b,
-       0xdd, 0x6e, 0x11, 0xd9, 0x4e, 0xfb, 0x59, 0xd8, 0x2a, 0x6d, 0xe3, 0xde,
-       0x5e, 0xd9, 0x86, 0x6b, 0x6b, 0x74, 0x4d, 0xca, 0x5b, 0x69, 0x87, 0x1f,
-       0xbd, 0xe0, 0x7d, 0xf7, 0x5f, 0x40, 0xba, 0x1c, 0x1f, 0x91, 0x7b, 0x2f,
-       0x78, 0x76, 0x37, 0x39, 0xf3, 0x84, 0x92, 0xef, 0xb8, 0x92, 0x6f, 0x5d,
-       0x8e, 0x38, 0x94, 0x3d, 0x79, 0xe2, 0xb9, 0x4a, 0x4f, 0x26, 0x9f, 0xf4,
-       0xed, 0xa8, 0xfb, 0x19, 0xbe, 0x23, 0x46, 0x19, 0x91, 0xee, 0x74, 0x07,
-       0xf7, 0x6f, 0xf7, 0x5c, 0x20, 0xbf, 0x5d, 0x1b, 0xf8, 0x7d, 0x0a, 0x3e,
-       0xb6, 0xa7, 0xc7, 0xe3, 0xf9, 0x95, 0x99, 0x0f, 0xce, 0xf3, 0xd7, 0xd6,
-       0x79, 0x36, 0xa4, 0xa2, 0xf2, 0xdc, 0xd0, 0x36, 0x69, 0xcb, 0xc9, 0x0a,
-       0xec, 0xe3, 0xcf, 0x84, 0xe7, 0x92, 0x49, 0x8b, 0x37, 0xef, 0x6a, 0x95,
-       0x34, 0x05, 0x3c, 0x90, 0xae, 0xa4, 0xaf, 0x3f, 0xd2, 0xf1, 0xc4, 0x0d,
-       0xef, 0x5d, 0x11, 0x37, 0xd3, 0x8b, 0x36, 0x5d, 0xe9, 0x70, 0xc8, 0x5f,
-       0x6f, 0x23, 0xa2, 0x2b, 0x1d, 0x26, 0xd7, 0x75, 0xf8, 0x3a, 0x74, 0x58,
-       0x91, 0x8f, 0x83, 0x27, 0xac, 0xef, 0x67, 0xfa, 0xcc, 0x23, 0xb2, 0x53,
-       0xe9, 0xdf, 0xee, 0x81, 0x4f, 0xf5, 0x75, 0xd9, 0x7c, 0x0b, 0xba, 0x7c,
-       0x43, 0x94, 0x3e, 0xd5, 0xd9, 0xa3, 0x8a, 0x1a, 0x87, 0xbe, 0x8d, 0xbc,
-       0x35, 0x2b, 0x9f, 0x40, 0x1a, 0xd5, 0x59, 0x82, 0x51, 0x4f, 0xbf, 0x6a,
-       0xcd, 0xfb, 0xfa, 0xcd, 0x8e, 0x52, 0x87, 0xd1, 0x0e, 0x4f, 0x9f, 0x2d,
-       0xaa, 0xcf, 0x74, 0xfc, 0x36, 0xb5, 0xde, 0xed, 0x9e, 0x9d, 0x1d, 0xd4,
-       0xe9, 0xd3, 0x55, 0xef, 0xbb, 0x88, 0x38, 0x37, 0x5d, 0xfd, 0x65, 0x7a,
-       0xf5, 0x74, 0x3a, 0x24, 0xde, 0xba, 0xda, 0xac, 0x4f, 0xfd, 0x42, 0x48,
-       0xd9, 0xf0, 0x10, 0x64, 0x78, 0xba, 0xb4, 0xc3, 0xb7, 0x7b, 0x8f, 0xe7,
-       0x9e, 0x0f, 0xc8, 0xf3, 0x89, 0x62, 0xb7, 0xf9, 0x16, 0xee, 0x0d, 0x83,
-       0xe7, 0x23, 0xd2, 0x24, 0x29, 0x9f, 0xe7, 0xd8, 0x3a, 0xcf, 0x01, 0x8d,
-       0x5e, 0xbf, 0x14, 0xf3, 0xd8, 0x2a, 0xfd, 0xd7, 0xef, 0xaa, 0x77, 0x1a,
-       0xae, 0x16, 0xe9, 0xb7, 0x81, 0x95, 0x22, 0x9d, 0x72, 0x65, 0x31, 0x26,
-       0x57, 0x88, 0x41, 0x06, 0xf0, 0x5d, 0x9d, 0xf2, 0x63, 0x78, 0x58, 0xde,
-       0x28, 0xde, 0x88, 0x8e, 0x7e, 0x79, 0xbd, 0x18, 0xd0, 0x42, 0x2c, 0xcc,
-       0x7c, 0x61, 0x5c, 0xde, 0x9c, 0xe9, 0x96, 0x95, 0x51, 0xc4, 0xfd, 0x1e,
-       0xca, 0xa4, 0xcf, 0x7c, 0x50, 0xbd, 0xeb, 0x72, 0xad, 0x7e, 0xd1, 0xc6,
-       0xf8, 0x73, 0x75, 0x39, 0xca, 0xfd, 0x6f, 0xfe, 0x5e, 0xbc, 0x5d, 0x56,
-       0x98, 0x53, 0xf4, 0x74, 0xca, 0xc2, 0x1c, 0xf2, 0xf9, 0x22, 0xc7, 0xa7,
-       0xdc, 0x46, 0xd4, 0xef, 0x61, 0xcc, 0xf7, 0x49, 0x9e, 0x41, 0x8f, 0x50,
-       0x37, 0xd7, 0xea, 0xab, 0x36, 0xf7, 0x3f, 0xc7, 0x65, 0x11, 0xfa, 0xfb,
-       0x47, 0x71, 0xee, 0xcf, 0xe7, 0xd4, 0xfb, 0x85, 0x0b, 0x8b, 0xa3, 0xc8,
-       0x1d, 0xae, 0xd5, 0xa7, 0xec, 0x29, 0xa5, 0xb7, 0xc5, 0xf2, 0x43, 0x7e,
-       0x3b, 0xaf, 0x79, 0xcf, 0xcd, 0xec, 0xe9, 0x61, 0xbe, 0xfa, 0x10, 0xf2,
-       0x05, 0xe6, 0xaa, 0xa3, 0xc0, 0x6b, 0x94, 0x49, 0x4c, 0x26, 0x8b, 0x1c,
-       0x4b, 0x22, 0x5b, 0x90, 0xdf, 0xe7, 0x64, 0x18, 0xf4, 0xc4, 0x90, 0xdb,
-       0x33, 0x3e, 0xdc, 0x25, 0xab, 0x11, 0x2f, 0x0e, 0xf0, 0xac, 0xd8, 0x2a,
-       0x62, 0xc3, 0xea, 0x7a, 0x6c, 0xd8, 0x89, 0x6b, 0x37, 0xe3, 0xf4, 0xfc,
-       0x67, 0x8c, 0xcf, 0xba, 0x0d, 0x63, 0xc3, 0x20, 0xfa, 0xb3, 0xad, 0x53,
-       0x26, 0xe7, 0x90, 0x44, 0x20, 0x67, 0x59, 0x10, 0x9e, 0x01, 0xc9, 0xca,
-       0xf4, 0x62, 0x77, 0xf4, 0xa2, 0x96, 0x56, 0x67, 0x45, 0xe2, 0x98, 0x73,
-       0xa1, 0xd8, 0x29, 0x8b, 0x73, 0x12, 0x33, 0x12, 0x8f, 0x48, 0x75, 0xd1,
-       0xc3, 0xec, 0x53, 0x1a, 0xda, 0xab, 0xae, 0x2c, 0x6e, 0xec, 0x63, 0x1a,
-       0x89, 0xc3, 0xf2, 0x75, 0xbf, 0x4f, 0x5a, 0xf5, 0x79, 0xb5, 0x83, 0x7b,
-       0x6c, 0x8b, 0xd5, 0x0e, 0xd0, 0x40, 0xda, 0x76, 0x35, 0xce, 0x1b, 0xbb,
-       0x3e, 0x2f, 0xe7, 0x44, 0x36, 0xb3, 0xdd, 0xc5, 0xbc, 0x17, 0xf1, 0xcc,
-       0x23, 0xa0, 0xe3, 0x9a, 0xa1, 0xdb, 0x8f, 0x48, 0x61, 0x71, 0xf3, 0x1c,
-       0x8d, 0x34, 0xf0, 0x19, 0x8e, 0xcf, 0x79, 0x0e, 0x83, 0xbe, 0x6b, 0x9a,
-       0x6e, 0x1f, 0x86, 0x2c, 0xbd, 0x39, 0x8c, 0xb3, 0x96, 0xf9, 0x23, 0xe9,
-       0x11, 0xfd, 0xbc, 0xa6, 0xe4, 0xaf, 0x2f, 0xf4, 0x63, 0x81, 0x64, 0xa4,
-       0x6d, 0x79, 0x4c, 0x8c, 0x65, 0xd6, 0x10, 0x5e, 0x69, 0x4d, 0xab, 0xfd,
-       0xde, 0x2d, 0x58, 0xdf, 0xe2, 0x86, 0x6c, 0xd6, 0x0b, 0x58, 0x0f, 0xfe,
-       0xfa, 0x36, 0xe9, 0x60, 0xbd, 0x80, 0x79, 0xc3, 0x21, 0x7c, 0x33, 0x77,
-       0x78, 0xb9, 0x9e, 0x74, 0x7e, 0xa6, 0xe2, 0x6b, 0x6e, 0x91, 0xf7, 0xad,
-       0x98, 0x08, 0xef, 0xd1, 0x6f, 0x74, 0x4a, 0xd3, 0x57, 0x7a, 0xe1, 0x2b,
-       0x1e, 0x03, 0xf6, 0xc6, 0xb8, 0x67, 0x7a, 0x24, 0xe4, 0x9d, 0xb1, 0x50,
-       0xf5, 0x96, 0x37, 0xe7, 0x2c, 0xff, 0x9d, 0x21, 0xd9, 0x73, 0xd1, 0x61,
-       0x4d, 0xb4, 0x8b, 0x35, 0x1f, 0xf4, 0x13, 0x7d, 0x15, 0xf9, 0xe9, 0x95,
-       0x45, 0x63, 0x1b, 0xcf, 0x7c, 0xbe, 0x5e, 0xc5, 0x35, 0xb1, 0x7f, 0x44,
-       0x61, 0x4c, 0xff, 0x1e, 0x7f, 0x23, 0x5f, 0x7a, 0xcf, 0xf9, 0x77, 0xe6,
-       0x53, 0x63, 0xfe, 0x59, 0x3b, 0x37, 0x73, 0x72, 0x43, 0x4e, 0xd5, 0xab,
-       0xea, 0xbd, 0x2b, 0x55, 0x1b, 0xfe, 0x71, 0x00, 0xf6, 0xc9, 0x35, 0x50,
-       0xd7, 0x1e, 0x02, 0x36, 0x8b, 0x75, 0xaa, 0x9c, 0xe8, 0xf4, 0x43, 0xe2,
-       0xd9, 0x3b, 0xac, 0x4c, 0xf9, 0xb2, 0x95, 0xb2, 0x97, 0x83, 0xac, 0x96,
-       0x33, 0xf2, 0x9f, 0xaa, 0x97, 0x54, 0xad, 0x75, 0x06, 0x79, 0x49, 0x68,
-       0x5a, 0xe5, 0x64, 0x0d, 0xf8, 0x16, 0x7e, 0xef, 0xd9, 0x2f, 0x62, 0x2d,
-       0x5a, 0xea, 0x4c, 0x83, 0x7e, 0xbe, 0x5e, 0x4f, 0xc1, 0x7f, 0xe8, 0xb6,
-       0x6d, 0x16, 0x10, 0x0f, 0x53, 0xea, 0x5c, 0x0c, 0xd7, 0xf1, 0x61, 0xe5,
-       0x9f, 0x65, 0x01, 0xb2, 0x39, 0x1b, 0xc3, 0x38, 0x9a, 0xb2, 0x4f, 0x43,
-       0xe9, 0xe1, 0x21, 0x85, 0x79, 0x8d, 0xf3, 0x70, 0x58, 0xcb, 0x3d, 0x22,
-       0xe7, 0x33, 0x32, 0x85, 0x35, 0x1c, 0x5a, 0xa6, 0x0e, 0x28, 0xdb, 0x31,
-       0x69, 0x82, 0xec, 0x4f, 0x00, 0x7b, 0x18, 0xd3, 0x94, 0x71, 0x14, 0xeb,
-       0xa2, 0x53, 0x42, 0x67, 0x21, 0xe3, 0x69, 0x60, 0x84, 0xb9, 0x66, 0x79,
-       0x69, 0x31, 0x90, 0xe9, 0xcb, 0x3c, 0xef, 0xaf, 0x8f, 0x0f, 0x74, 0x11,
-       0x47, 0x49, 0x65, 0x71, 0x4a, 0xa6, 0x66, 0x99, 0xb3, 0x8f, 0xa9, 0x33,
-       0x06, 0x21, 0x75, 0xc6, 0xc5, 0xcb, 0x99, 0xbd, 0x6f, 0x0f, 0x63, 0x56,
-       0x84, 0x7b, 0x6d, 0x02, 0xdb, 0xe9, 0xc7, 0xbc, 0x37, 0x92, 0xaf, 0x97,
-       0xab, 0x0e, 0x83, 0xde, 0x8b, 0x33, 0x56, 0x26, 0x2f, 0x0e, 0xcf, 0x5b,
-       0x8f, 0xba, 0xe0, 0x7f, 0x15, 0xfe, 0x73, 0xaa, 0x74, 0x2f, 0xf8, 0x2c,
-       0x60, 0x85, 0x65, 0xe4, 0x62, 0x91, 0x39, 0xe3, 0x47, 0xa1, 0x37, 0x5e,
-       0x17, 0x06, 0x0d, 0xf8, 0x81, 0x35, 0xf5, 0x7e, 0xa1, 0xe5, 0xae, 0x20,
-       0x87, 0x8d, 0x69, 0x87, 0xa0, 0xeb, 0xbc, 0xd9, 0xe4, 0xdb, 0x03, 0xdf,
-       0x35, 0x3e, 0x07, 0x3f, 0xba, 0x24, 0x7c, 0xef, 0xe7, 0x9d, 0x3a, 0xf3,
-       0xa5, 0xcb, 0xf0, 0x7b, 0x99, 0x78, 0x06, 0x36, 0x94, 0x8f, 0xb6, 0x80,
-       0xe6, 0xdf, 0xc6, 0xbd, 0x5c, 0x95, 0xf3, 0x58, 0xce, 0x9a, 0x14, 0x62,
-       0x21, 0xe9, 0x8b, 0x5d, 0x92, 0x6d, 0xf0, 0x64, 0x9a, 0xbc, 0x61, 0x5b,
-       0x83, 0xa2, 0xa9, 0xf1, 0x7a, 0x0f, 0xc0, 0x06, 0xaf, 0xc2, 0xdf, 0x35,
-       0xfb, 0xb9, 0x7e, 0xaa, 0x48, 0x0c, 0xf5, 0x84, 0x3a, 0x8b, 0x70, 0xd9,
-       0x66, 0x1d, 0x90, 0xef, 0xfb, 0xfe, 0x95, 0x9a, 0xe3, 0xfa, 0xde, 0x1d,
-       0xeb, 0xd0, 0xa4, 0xcf, 0xe3, 0x71, 0xbf, 0xed, 0xd1, 0xc8, 0x71, 0x9a,
-       0x1a, 0xc6, 0xb9, 0xe8, 0x8f, 0x73, 0xce, 0x1f, 0x67, 0xc1, 0x1f, 0xe7,
-       0xf2, 0xfa, 0x38, 0x0f, 0xc2, 0x0e, 0xea, 0xf5, 0xa7, 0x80, 0x37, 0x92,
-       0x4e, 0xbd, 0x9e, 0x46, 0x5e, 0x36, 0xd9, 0x3f, 0xa1, 0xf6, 0x5e, 0xf5,
-       0xc4, 0x8b, 0x43, 0x49, 0xdb, 0x93, 0x3f, 0xac, 0x40, 0x26, 0x60, 0x8f,
-       0x79, 0xf1, 0xb0, 0x3a, 0xf7, 0x03, 0xbd, 0xfd, 0xc2, 0x36, 0xf8, 0x81,
-       0xc7, 0x10, 0x4b, 0x9c, 0xe1, 0x25, 0x5b, 0xf2, 0x7b, 0x7e, 0x4d, 0x87,
-       0xbd, 0x77, 0x20, 0x2e, 0xbd, 0x09, 0xdb, 0x71, 0x86, 0x2b, 0x8b, 0x8f,
-       0xa9, 0x3d, 0xe1, 0xa6, 0xc4, 0xbd, 0xd0, 0x67, 0x79, 0x78, 0x61, 0xb1,
-       0x3c, 0x7c, 0x8e, 0xfb, 0x43, 0xe8, 0xb7, 0xb0, 0xd8, 0x0e, 0xb9, 0xb7,
-       0xab, 0xba, 0xca, 0xa5, 0x62, 0x04, 0x7a, 0x34, 0x61, 0xf3, 0x11, 0xb4,
-       0x45, 0x61, 0x07, 0x5d, 0x68, 0x7f, 0x0d, 0x6b, 0x3b, 0x86, 0xf6, 0xb5,
-       0xd6, 0x61, 0x85, 0x63, 0x6d, 0x39, 0x5f, 0xbd, 0x8a, 0x98, 0xfb, 0x16,
-       0xfc, 0x68, 0x2f, 0xfa, 0xf4, 0xa3, 0xcf, 0x0e, 0x13, 0xf8, 0x2a, 0x53,
-       0xbe, 0x21, 0x4d, 0x2e, 0x68, 0xd2, 0x1b, 0x68, 0x72, 0x41, 0x0f, 0x7c,
-       0xe7, 0x19, 0xd6, 0xa0, 0xfb, 0xe5, 0x64, 0x91, 0x67, 0xaa, 0xf8, 0xee,
-       0xb5, 0x29, 0x21, 0x60, 0xd2, 0xa6, 0x33, 0x56, 0x74, 0x45, 0xd5, 0x7a,
-       0x68, 0x5b, 0x7d, 0x4e, 0x45, 0x54, 0x9c, 0x89, 0x9d, 0x44, 0xfc, 0xba,
-       0x5a, 0x6d, 0x97, 0x37, 0xfc, 0xb9, 0xd6, 0x84, 0xfb, 0x97, 0x1b, 0xe7,
-       0x3a, 0x55, 0x1a, 0x1d, 0xfe, 0x81, 0x6d, 0xf8, 0x7c, 0x75, 0x62, 0xae,
-       0x76, 0xf4, 0x1d, 0x1d, 0xbe, 0xb8, 0x78, 0xa3, 0xbe, 0x13, 0xe8, 0xdb,
-       0xd4, 0xd0, 0x77, 0x02, 0xfd, 0xda, 0x11, 0x07, 0xdb, 0x15, 0x4f, 0x93,
-       0xa0, 0xeb, 0x4a, 0x51, 0xbd, 0x0b, 0x0c, 0xb9, 0x73, 0x4e, 0x93, 0x98,
-       0x3a, 0xe3, 0xd5, 0x4a, 0x2c, 0x33, 0xa6, 0xbd, 0xa7, 0xde, 0xa3, 0x6c,
-       0x60, 0xc8, 0x06, 0xee, 0x9d, 0x19, 0xd5, 0x52, 0x95, 0x1c, 0x62, 0xd6,
-       0x2e, 0xe2, 0x27, 0xc7, 0x45, 0xcc, 0x5c, 0xc0, 0x78, 0x8b, 0xc5, 0x15,
-       0x9e, 0xc1, 0x86, 0x5d, 0xbc, 0x4d, 0x9c, 0xbd, 0xcb, 0x50, 0x67, 0x1e,
-       0xd2, 0xaa, 0x66, 0xb7, 0x50, 0x14, 0x33, 0x39, 0xc0, 0x33, 0x0e, 0xf7,
-       0x63, 0x5d, 0x7e, 0x0e, 0x6d, 0x49, 0xc4, 0xc7, 0xc3, 0x5a, 0x72, 0x69,
-       0x18, 0xd7, 0x8f, 0xe0, 0x1a, 0xfe, 0x78, 0x2e, 0x8b, 0xfb, 0x8f, 0xe0,
-       0x7a, 0x42, 0x4b, 0xd5, 0xb2, 0xb8, 0x7e, 0x14, 0xd7, 0x49, 0x93, 0x79,
-       0xca, 0x0f, 0xec, 0x8c, 0xe6, 0x62, 0x2c, 0x77, 0x69, 0x18, 0x9f, 0xc6,
-       0xf1, 0x78, 0x0f, 0x7a, 0x2a, 0x72, 0xaf, 0x2d, 0x0e, 0x9a, 0x0e, 0x6a,
-       0xe9, 0x4a, 0x1b, 0xc6, 0xe8, 0xc1, 0xf3, 0xb4, 0xa9, 0x43, 0xfe, 0xfc,
-       0xac, 0x39, 0xdd, 0xad, 0x6a, 0x4e, 0x46, 0x22, 0x03, 0x9c, 0x7c, 0x1c,
-       0x79, 0x80, 0x26, 0x69, 0xfb, 0x49, 0x29, 0x38, 0xf0, 0x2b, 0x15, 0x43,
-       0x52, 0x91, 0x3c, 0x7e, 0xe7, 0x25, 0x39, 0x88, 0xfb, 0x15, 0xda, 0x02,
-       0xfb, 0xfd, 0x89, 0x14, 0xca, 0xc4, 0xfd, 0xac, 0x33, 0xb1, 0x36, 0xc5,
-       0xfa, 0x52, 0x0e, 0x32, 0x88, 0xd0, 0x7e, 0x6f, 0x50, 0x13, 0xf3, 0xce,
-       0x55, 0x23, 0x2e, 0x6b, 0xc9, 0x0a, 0xf7, 0xfd, 0xdc, 0xcc, 0x45, 0x9b,
-       0xef, 0x28, 0x4d, 0x70, 0x1f, 0xb1, 0x60, 0x24, 0x58, 0x1f, 0x51, 0xf5,
-       0x75, 0xc7, 0xdb, 0x1f, 0xe4, 0xb8, 0x63, 0xe0, 0xb7, 0xb1, 0x6e, 0xc5,
-       0x79, 0xbf, 0x80, 0xe7, 0xbd, 0x7a, 0x56, 0xaa, 0xf6, 0x5e, 0x5d, 0xf0,
-       0xbd, 0x81, 0xf3, 0xd0, 0xc5, 0x45, 0x95, 0x1b, 0x73, 0x0f, 0xf7, 0xfd,
-       0x72, 0x2a, 0xe4, 0x30, 0x45, 0xd6, 0xc8, 0x82, 0x7d, 0xbb, 0x40, 0x8e,
-       0x9b, 0x69, 0x25, 0x9d, 0x47, 0x30, 0xa6, 0x38, 0xf4, 0xbb, 0xd9, 0x08,
-       0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf9, 0x3a, 0xdd, 0xa4, 0x99, 0xf2, 0x38,
-       0x0e, 0xff, 0xc9, 0x77, 0x32, 0x9e, 0x94, 0x9c, 0xc3, 0x1a, 0x8f, 0x81,
-       0xd8, 0x98, 0xc7, 0xef, 0xeb, 0xf2, 0x9b, 0xf4, 0xe5, 0x97, 0x2b, 0xbf,
-       0xa4, 0x74, 0xb8, 0x60, 0x73, 0xbe, 0xa0, 0xf6, 0x31, 0xa2, 0x74, 0xb7,
-       0xa0, 0xce, 0xfd, 0x06, 0x32, 0x08, 0xea, 0x77, 0x37, 0xb6, 0xbd, 0x61,
-       0x9b, 0xb4, 0xdd, 0xce, 0xf3, 0x10, 0xbd, 0xae, 0x90, 0x7e, 0xf2, 0xc1,
-       0x18, 0x16, 0xec, 0xb5, 0x06, 0x3c, 0x04, 0x7c, 0xde, 0xaa, 0x7c, 0x48,
-       0x6f, 0x64, 0xbb, 0xb4, 0x65, 0x4c, 0xc3, 0x66, 0x6c, 0xf8, 0x84, 0xbf,
-       0x3f, 0xf0, 0x77, 0x21, 0x67, 0x4f, 0x16, 0xa1, 0x84, 0x4c, 0xfa, 0xef,
-       0xf8, 0xde, 0xc0, 0x1e, 0x36, 0xef, 0x35, 0xbb, 0x99, 0x73, 0xf6, 0x75,
-       0xbe, 0x17, 0x6e, 0xc0, 0xf7, 0x82, 0xcf, 0x77, 0xe5, 0x16, 0xe9, 0x5d,
-       0x98, 0x71, 0xc1, 0x33, 0x6d, 0xee, 0x46, 0xf6, 0x28, 0xea, 0x7f, 0x5f,
-       0xac, 0x19, 0xe1, 0xb0, 0x5b, 0xbd, 0x59, 0x0d, 0x95, 0x79, 0xb5, 0x67,
-       0x97, 0xe7, 0x10, 0x0b, 0xcb, 0x65, 0x2f, 0xc7, 0x2e, 0x57, 0x59, 0xcb,
-       0x7e, 0x3f, 0x1a, 0xf8, 0xfe, 0xd7, 0x67, 0xd4, 0x79, 0x97, 0xc9, 0xaa,
-       0x57, 0xf7, 0x2a, 0x97, 0x1b, 0x63, 0xea, 0x0e, 0xc6, 0xd3, 0xde, 0xbc,
-       0x8c, 0xf2, 0xbd, 0x65, 0x5c, 0xef, 0x96, 0x4b, 0x73, 0x6a, 0xcf, 0xca,
-       0xdf, 0x1b, 0xe2, 0x9e, 0x8f, 0xda, 0xff, 0x86, 0x5f, 0x1b, 0x53, 0x7e,
-       0x7d, 0x75, 0x4e, 0xdd, 0xf3, 0xb0, 0x52, 0x75, 0x14, 0x7e, 0x1f, 0xb9,
-       0x84, 0xbd, 0x55, 0x0a, 0xc8, 0xb9, 0xcf, 0xd9, 0x0f, 0x6f, 0x27, 0xce,
-       0xe1, 0x58, 0xab, 0x18, 0xeb, 0xe2, 0x9c, 0x6c, 0xe7, 0x99, 0x92, 0xb2,
-       0xda, 0x67, 0xf3, 0xea, 0xe2, 0x13, 0x12, 0xfc, 0x4f, 0x88, 0xb0, 0x1f,
-       0x0b, 0x79, 0xae, 0x85, 0xef, 0xd2, 0xd2, 0x57, 0x20, 0x0f, 0x1a, 0xe5,
-       0x3e, 0x4e, 0xbd, 0xee, 0xd5, 0xcd, 0xeb, 0x58, 0x17, 0x4d, 0x7c, 0xef,
-       0x02, 0x7f, 0xc7, 0x61, 0x3f, 0x58, 0x27, 0xeb, 0xed, 0xbc, 0x66, 0xee,
-       0x11, 0x5c, 0x33, 0xb0, 0xfd, 0x3f, 0xd4, 0x46, 0x90, 0x7c, 0xb4, 0x45,
-       0x00, 0x00, 0x00 };
+       0xa5, 0x7b, 0x0b, 0x74, 0x1c, 0x55, 0x7a, 0xe6, 0x77, 0xab, 0xba, 0xa5,
+       0xea, 0x56, 0xab, 0x55, 0x92, 0xdb, 0xa6, 0x95, 0xd1, 0xe0, 0x2e, 0x77,
+       0xb5, 0xdc, 0x58, 0xc2, 0x54, 0xcb, 0x2d, 0xd3, 0x44, 0xe5, 0xb8, 0xc7,
+       0x08, 0x5b, 0x06, 0x4d, 0x46, 0x38, 0xca, 0xac, 0x98, 0xc3, 0x2e, 0x1d,
+       0x63, 0x83, 0x30, 0x06, 0x04, 0xc3, 0x66, 0x95, 0x2c, 0x89, 0x6a, 0xe4,
+       0x07, 0x7e, 0xb4, 0xba, 0xf5, 0x32, 0x32, 0xd9, 0x9c, 0xb8, 0x2d, 0xc9,
+       0x96, 0x81, 0x7e, 0xc0, 0x00, 0x33, 0x43, 0x76, 0x67, 0xe9, 0x35, 0x60,
+       0x0c, 0x8c, 0x61, 0x92, 0x3d, 0x67, 0x97, 0xc9, 0x99, 0x49, 0x7c, 0x30,
+       0x78, 0x6c, 0xde, 0x9b, 0x99, 0xdd, 0x15, 0x09, 0x93, 0xda, 0xff, 0xaf,
+       0x96, 0x8c, 0x61, 0xd8, 0x24, 0x9b, 0xd5, 0x39, 0x7d, 0x4a, 0x5d, 0x75,
+       0xeb, 0xde, 0xff, 0xfd, 0x7f, 0xff, 0x7f, 0x6f, 0x47, 0x00, 0x2f, 0x16,
+       0xfe, 0x6a, 0xe9, 0x13, 0x1f, 0x18, 0x7c, 0xb0, 0x7d, 0xb5, 0xb1, 0xda,
+       0xb9, 0xe1, 0x86, 0x8b, 0x1f, 0xae, 0x15, 0x40, 0xea, 0x5d, 0xfc, 0x8b,
+       0xfe, 0xbe, 0xfa, 0x2f, 0x7b, 0x0d, 0x32, 0xa0, 0x2e, 0xd2, 0xc4, 0x1f,
+       0x28, 0x92, 0x99, 0xfb, 0xcd, 0x0d, 0x3a, 0x14, 0xd9, 0xec, 0x5b, 0x77,
+       0xbb, 0x0e, 0x24, 0xf3, 0x2d, 0xa1, 0xeb, 0xf1, 0x2b, 0xdb, 0x0a, 0xb8,
+       0xc0, 0xf7, 0xbf, 0x6a, 0x7e, 0x3a, 0xf4, 0xc3, 0x6b, 0xb5, 0x8f, 0x73,
+       0x32, 0x14, 0xd5, 0x9c, 0x84, 0xda, 0x0c, 0xa5, 0x89, 0xde, 0xf9, 0xd3,
+       0x95, 0xdf, 0x77, 0xc1, 0xbf, 0x38, 0x17, 0x2c, 0xb7, 0x69, 0x60, 0x57,
+       0x76, 0x00, 0x73, 0x71, 0xe0, 0x42, 0x3a, 0x62, 0xec, 0x02, 0x46, 0x25,
+       0x33, 0x12, 0x3a, 0x89, 0x10, 0x66, 0xf3, 0xb0, 0xaa, 0x4d, 0x1d, 0xfb,
+       0x4a, 0x21, 0x5c, 0x4c, 0xff, 0x83, 0x1d, 0x72, 0x0f, 0xe0, 0xed, 0x38,
+       0x94, 0xa0, 0xf9, 0x10, 0x82, 0x59, 0x28, 0xb5, 0xe6, 0x20, 0x0a, 0x23,
+       0xc0, 0x9e, 0xb4, 0x36, 0x00, 0x68, 0x7d, 0x45, 0x11, 0x3e, 0x7d, 0x02,
+       0x5a, 0x4f, 0xa3, 0xdc, 0x92, 0xba, 0x45, 0x68, 0xc9, 0x9d, 0x02, 0x8a,
+       0xa0, 0xb1, 0xab, 0xf2, 0x7c, 0x1d, 0x44, 0x34, 0xaf, 0xe0, 0xac, 0xcc,
+       0xcb, 0x9a, 0x24, 0x67, 0x01, 0x97, 0x6e, 0x60, 0x4f, 0x16, 0x96, 0xcb,
+       0x14, 0xd8, 0x15, 0x8f, 0xa8, 0x33, 0xe0, 0xe7, 0x21, 0x0c, 0x3b, 0xe3,
+       0x34, 0xe2, 0xd8, 0xb6, 0x77, 0x1b, 0xb6, 0x7d, 0xcc, 0xa8, 0x86, 0xa5,
+       0x6a, 0x41, 0x40, 0x60, 0xd8, 0x90, 0x90, 0x54, 0x37, 0x84, 0x5c, 0xd0,
+       0x82, 0xdb, 0xf1, 0xf7, 0xc4, 0x6f, 0x32, 0xea, 0x46, 0x65, 0x7c, 0x0a,
+       0xd5, 0x28, 0xab, 0x15, 0x89, 0x4d, 0xa7, 0x6d, 0xfb, 0x94, 0xee, 0xc2,
+       0x31, 0x92, 0xcd, 0x70, 0xfe, 0xef, 0xed, 0x32, 0xc9, 0x65, 0xb7, 0xbe,
+       0xb8, 0xbe, 0x82, 0x9c, 0x6a, 0xdb, 0x33, 0xf4, 0x6c, 0x6f, 0x7e, 0x51,
+       0xc6, 0xb6, 0x2d, 0xe9, 0xb6, 0x7d, 0xbb, 0xfe, 0x77, 0xf6, 0xd6, 0xcf,
+       0x8d, 0x8d, 0xe1, 0xf1, 0x51, 0x15, 0x4f, 0x64, 0x93, 0xc8, 0xa7, 0x6d,
+       0xc8, 0xa6, 0x0b, 0xfd, 0x23, 0x21, 0xec, 0x2c, 0x74, 0xa2, 0x90, 0xd6,
+       0x52, 0x67, 0xe9, 0xbd, 0xad, 0x71, 0x1d, 0xf7, 0x14, 0xba, 0x30, 0x97,
+       0x86, 0xed, 0x31, 0xf5, 0xb2, 0x47, 0x44, 0x71, 0x67, 0xa1, 0x1b, 0xc5,
+       0xb4, 0x7e, 0x7a, 0x58, 0x44, 0x06, 0x1b, 0x65, 0x17, 0xee, 0x2b, 0xb4,
+       0xe2, 0xde, 0x42, 0x82, 0xde, 0xb1, 0x71, 0x63, 0xac, 0x89, 0xc6, 0xb7,
+       0xe1, 0xb1, 0x49, 0xdb, 0x8e, 0xc6, 0x54, 0xf4, 0x17, 0x0c, 0xcc, 0x8d,
+       0x4a, 0x48, 0x1d, 0x73, 0x21, 0x75, 0x14, 0xb8, 0xf3, 0x68, 0x1b, 0x66,
+       0x46, 0x6d, 0x6c, 0x35, 0x86, 0x1b, 0x25, 0x32, 0xbb, 0x94, 0x2a, 0xe0,
+       0xd6, 0xfd, 0xd8, 0xae, 0x56, 0x68, 0x3f, 0x2b, 0x0b, 0xec, 0x38, 0x1a,
+       0xc5, 0x9b, 0x69, 0x0b, 0x37, 0xb6, 0x07, 0x31, 0x58, 0x08, 0xe0, 0x8d,
+       0x74, 0x80, 0xd6, 0x30, 0xf0, 0x7a, 0x5a, 0xa1, 0x75, 0x5a, 0xf1, 0x62,
+       0x9a, 0xc7, 0xf0, 0x58, 0x1f, 0xb6, 0x15, 0x9a, 0x70, 0x26, 0x1d, 0xa4,
+       0x35, 0x03, 0x78, 0x85, 0xc6, 0xdd, 0x55, 0xd0, 0x71, 0x9a, 0xc6, 0xf5,
+       0x17, 0x42, 0x78, 0x39, 0xed, 0x23, 0x5a, 0x03, 0x38, 0x99, 0x1e, 0xc0,
+       0xae, 0x74, 0xcb, 0xe9, 0xeb, 0x49, 0x86, 0xa1, 0x25, 0xbc, 0x0e, 0xdf,
+       0x7b, 0xdb, 0xee, 0x0e, 0x38, 0x66, 0x42, 0xeb, 0x2c, 0xae, 0x3b, 0x80,
+       0xe1, 0xf4, 0x8b, 0x0b, 0x7e, 0x62, 0x60, 0xff, 0xe8, 0xbc, 0xfd, 0xc3,
+       0x95, 0x4d, 0x38, 0x91, 0x05, 0x1e, 0x9b, 0x01, 0x66, 0xb2, 0x96, 0x5d,
+       0x6b, 0xda, 0xf6, 0x74, 0x7b, 0x2b, 0xc9, 0x4b, 0xef, 0xdb, 0x4a, 0xa3,
+       0x9e, 0x28, 0xb9, 0x80, 0xa3, 0x5a, 0x5f, 0x19, 0x12, 0x72, 0x73, 0x2e,
+       0x54, 0x8d, 0x68, 0x5d, 0x39, 0x68, 0xa7, 0xef, 0x24, 0x4f, 0x3a, 0x96,
+       0xd5, 0x7a, 0x2c, 0x0c, 0xd9, 0x41, 0xb3, 0x39, 0xd4, 0x2a, 0xdb, 0xf0,
+       0x93, 0x2d, 0xa4, 0x5b, 0x6d, 0xbb, 0xee, 0x5a, 0xdb, 0x3e, 0xd3, 0x0e,
+       0x5b, 0x32, 0xf5, 0xd3, 0x25, 0xe8, 0xe5, 0x0f, 0xa0, 0x0f, 0x9e, 0x44,
+       0xf9, 0xab, 0x3e, 0x44, 0xfa, 0xc3, 0x72, 0x64, 0x60, 0x9e, 0xde, 0xad,
+       0x2d, 0x90, 0x29, 0x13, 0x2f, 0x3a, 0xd9, 0x60, 0xa1, 0xa4, 0xc0, 0x45,
+       0xfc, 0xb4, 0x8e, 0xd8, 0xb6, 0x4b, 0xf7, 0xc1, 0x47, 0xf2, 0xdd, 0x74,
+       0xc8, 0xb6, 0xcf, 0x1b, 0x2a, 0xaa, 0x48, 0x37, 0x37, 0x8c, 0xd9, 0x98,
+       0x36, 0x4e, 0x92, 0x3c, 0x05, 0x52, 0x3d, 0x71, 0x7a, 0x27, 0x40, 0xe3,
+       0x13, 0xd8, 0x34, 0x12, 0xc4, 0xe3, 0x59, 0x05, 0x3f, 0x5c, 0x19, 0x45,
+       0x0d, 0xcd, 0xe5, 0x25, 0x59, 0x55, 0x93, 0xfc, 0x50, 0x20, 0x73, 0x2b,
+       0x54, 0xec, 0x11, 0x85, 0xb3, 0xc4, 0x63, 0x10, 0xdf, 0x2d, 0x05, 0xf0,
+       0x54, 0x49, 0xc5, 0x93, 0xa5, 0x26, 0x3c, 0x5f, 0x32, 0x90, 0x1d, 0xd5,
+       0xf6, 0x95, 0x61, 0xa3, 0x96, 0xcc, 0xf9, 0x8d, 0x5c, 0x0c, 0x99, 0x51,
+       0xdb, 0xce, 0x13, 0xcd, 0x5e, 0xe2, 0xe1, 0xf5, 0xdc, 0x95, 0x38, 0x3e,
+       0xe9, 0x42, 0x68, 0x3a, 0x80, 0x27, 0xd2, 0x2e, 0x5c, 0x95, 0xd1, 0xac,
+       0x1c, 0xf4, 0xe8, 0x4e, 0xa1, 0x27, 0x57, 0x09, 0x6d, 0xd4, 0x42, 0x24,
+       0xe4, 0x16, 0x12, 0x9a, 0x8f, 0xbb, 0xa0, 0x17, 0x43, 0x70, 0x37, 0x2b,
+       0xd0, 0x9b, 0xc9, 0x8d, 0xfc, 0x12, 0xaa, 0xc8, 0x2f, 0x36, 0x8d, 0x47,
+       0xe9, 0x5e, 0x80, 0xee, 0xe1, 0xca, 0x6a, 0xc8, 0xcb, 0x64, 0x90, 0xdc,
+       0x74, 0x19, 0x49, 0x97, 0x6d, 0xcb, 0x7a, 0x1b, 0xfa, 0x1e, 0xa1, 0xeb,
+       0x1a, 0x1e, 0xaf, 0x22, 0x5c, 0x24, 0x19, 0x34, 0x13, 0x4d, 0x59, 0xa2,
+       0x31, 0x4b, 0x34, 0x66, 0x89, 0xc6, 0xac, 0x4c, 0x36, 0xa3, 0x19, 0xc0,
+       0x1f, 0x92, 0xae, 0x42, 0xc4, 0xdf, 0x9b, 0x8e, 0x9e, 0x9e, 0x2a, 0x05,
+       0x89, 0xfe, 0x90, 0x43, 0xff, 0x63, 0xa3, 0x02, 0x92, 0xae, 0xf5, 0x9c,
+       0xc5, 0x7a, 0x84, 0x63, 0x5a, 0x32, 0x87, 0x24, 0xbd, 0xa7, 0xed, 0xb3,
+       0xa0, 0x75, 0x95, 0x49, 0xff, 0x5b, 0xd5, 0x04, 0xe6, 0xb2, 0x6e, 0xd4,
+       0xe8, 0x5a, 0x88, 0xf4, 0x15, 0x2d, 0x63, 0x09, 0xee, 0x56, 0x69, 0x4e,
+       0xa9, 0x4a, 0x54, 0x62, 0xc8, 0x43, 0x88, 0x8c, 0x4b, 0x98, 0x35, 0x64,
+       0xf2, 0x4f, 0x03, 0x72, 0x33, 0x2d, 0x57, 0x8c, 0xd3, 0x95, 0xe6, 0xcf,
+       0xd2, 0x5a, 0x44, 0x0f, 0xcd, 0x47, 0x7e, 0xc9, 0x72, 0x8c, 0x12, 0x0d,
+       0x7b, 0x1c, 0x7a, 0x9f, 0x2c, 0x75, 0x8b, 0x8a, 0xfd, 0x98, 0x64, 0x2f,
+       0x5a, 0x08, 0x42, 0x8b, 0x86, 0x84, 0x66, 0x24, 0x85, 0x8a, 0x99, 0xd2,
+       0x8f, 0x68, 0x4c, 0xe0, 0xb2, 0x31, 0x3d, 0x18, 0xce, 0x0a, 0x5c, 0xaf,
+       0xdb, 0xd8, 0x60, 0xf4, 0x60, 0x57, 0x69, 0xd1, 0x2f, 0x39, 0x76, 0xa9,
+       0xfe, 0x99, 0x74, 0x27, 0x76, 0x67, 0x43, 0xd8, 0x95, 0x0f, 0xfa, 0xa7,
+       0xd3, 0xfc, 0x4c, 0x27, 0x7f, 0xe7, 0x67, 0x81, 0xcb, 0x9e, 0x35, 0x5d,
+       0xf6, 0x2c, 0x81, 0xe1, 0x89, 0xaf, 0x50, 0x0c, 0xa9, 0xc3, 0x2e, 0xfd,
+       0x63, 0xb2, 0x15, 0x3d, 0xb1, 0x0d, 0x8d, 0x38, 0xab, 0xb6, 0xe2, 0xe0,
+       0x54, 0x37, 0x76, 0x4f, 0xad, 0xc6, 0xfe, 0x89, 0xa6, 0x94, 0xd7, 0x1c,
+       0xa1, 0xf5, 0xc3, 0xc9, 0x6d, 0x42, 0x1b, 0x90, 0x45, 0x38, 0xba, 0x8d,
+       0x6c, 0xb7, 0xb9, 0xde, 0xb6, 0x4f, 0xc6, 0xc8, 0xb6, 0x8d, 0x16, 0x63,
+       0x13, 0x09, 0xa0, 0xdc, 0xa3, 0x75, 0xbd, 0x0d, 0x1f, 0xbe, 0x4e, 0x36,
+       0x37, 0x13, 0xc3, 0x36, 0x19, 0x72, 0xab, 0x0f, 0xbf, 0xb0, 0x8f, 0xba,
+       0x58, 0xee, 0xf6, 0xd0, 0xed, 0xc6, 0x1e, 0xc1, 0x71, 0xae, 0xea, 0x52,
+       0x2c, 0xe1, 0xf9, 0xf9, 0x1d, 0xdb, 0x0e, 0xd3, 0x3c, 0xfd, 0xb1, 0x96,
+       0x44, 0x3f, 0xe6, 0xed, 0xb3, 0xbd, 0xdd, 0xd8, 0x35, 0xb7, 0x1a, 0x07,
+       0x26, 0xdc, 0x48, 0xd6, 0x0b, 0xd4, 0xe9, 0xe1, 0xf2, 0xdd, 0x58, 0x0d,
+       0x6b, 0x86, 0xdf, 0xeb, 0xc6, 0xe1, 0xb9, 0xca, 0xf7, 0xec, 0xa5, 0xef,
+       0x8b, 0xf3, 0x5d, 0x20, 0x9d, 0xb2, 0x3c, 0x39, 0x4e, 0x92, 0x0a, 0xcc,
+       0x16, 0x9c, 0x98, 0x08, 0x90, 0x6e, 0x3b, 0x85, 0xeb, 0xf8, 0x32, 0xbf,
+       0xf7, 0x11, 0x1b, 0xa7, 0x0c, 0xd2, 0x73, 0x76, 0xa3, 0xf0, 0x1e, 0xef,
+       0x12, 0xee, 0xe2, 0x16, 0x51, 0x35, 0xfd, 0x2d, 0xa1, 0x1c, 0x4f, 0x89,
+       0xea, 0x62, 0x2b, 0xc9, 0xbe, 0x4f, 0x78, 0x8e, 0x6b, 0xa1, 0x90, 0xf8,
+       0x03, 0xd2, 0x67, 0xaf, 0x90, 0x8b, 0x50, 0x25, 0x73, 0x50, 0x48, 0x45,
+       0x9a, 0xc3, 0xb1, 0x21, 0x5e, 0x27, 0x48, 0x7a, 0x83, 0x25, 0x9b, 0x03,
+       0xd8, 0x4a, 0x39, 0xe2, 0xa6, 0xb4, 0x89, 0x03, 0xd9, 0x6a, 0x8a, 0x8f,
+       0xec, 0xf7, 0xf3, 0xb4, 0xae, 0x8e, 0x83, 0x25, 0x58, 0x1e, 0xf3, 0x00,
+       0x56, 0x93, 0xbf, 0x9d, 0x89, 0xb1, 0x2f, 0x02, 0xf9, 0x6c, 0x38, 0x79,
+       0x40, 0xd8, 0x76, 0x75, 0xc4, 0x5e, 0x7e, 0xde, 0x68, 0x89, 0xbe, 0x88,
+       0xff, 0x6d, 0xe7, 0x02, 0x03, 0x88, 0xb6, 0x43, 0xa9, 0x36, 0x77, 0xe3,
+       0xe7, 0x69, 0x28, 0x55, 0xa6, 0x85, 0x53, 0x69, 0xc0, 0x37, 0x32, 0xac,
+       0x7a, 0x41, 0x76, 0x80, 0x70, 0xf0, 0xa0, 0xd0, 0x7a, 0xce, 0x51, 0x3a,
+       0x4b, 0xb4, 0x5b, 0x83, 0x12, 0x28, 0x1e, 0x09, 0xad, 0xef, 0x45, 0xb2,
+       0xc7, 0x3f, 0x10, 0x9a, 0x3a, 0x2f, 0xd8, 0x4f, 0x39, 0x97, 0xec, 0x5e,
+       0xc8, 0x29, 0x16, 0xae, 0xba, 0x2c, 0xa7, 0x0c, 0x13, 0x5d, 0x7b, 0x89,
+       0xae, 0x97, 0x0c, 0x2d, 0x38, 0x0d, 0x7b, 0xf9, 0x36, 0x83, 0x9f, 0x99,
+       0xd8, 0x5d, 0xb2, 0x43, 0x2e, 0x93, 0x65, 0x05, 0x4b, 0x31, 0x7f, 0x65,
+       0x0f, 0xc7, 0x55, 0x92, 0x11, 0x79, 0x5a, 0xe1, 0xcb, 0x72, 0xad, 0x8d,
+       0xe5, 0x34, 0xe6, 0x93, 0x6b, 0xe1, 0x6f, 0x2c, 0xb8, 0x52, 0x35, 0x26,
+       0x7a, 0xee, 0x1b, 0xa1, 0xf8, 0xa4, 0x4b, 0x14, 0x9b, 0xf4, 0xc4, 0xbc,
+       0xf0, 0x25, 0xde, 0x8f, 0x7b, 0x04, 0xc5, 0xa6, 0x54, 0xb5, 0x19, 0xec,
+       0xfe, 0x20, 0xef, 0x21, 0xfd, 0xa2, 0x67, 0x67, 0x21, 0xe1, 0x7a, 0x97,
+       0x6c, 0xac, 0x8a, 0x62, 0x29, 0x0a, 0x4d, 0xdd, 0x17, 0x29, 0xff, 0xdc,
+       0x10, 0xf3, 0xfc, 0xab, 0x2a, 0x53, 0xba, 0xd2, 0x83, 0xfb, 0xaf, 0x99,
+       0x4d, 0xd4, 0x51, 0x3c, 0x57, 0x71, 0x3a, 0xde, 0x85, 0xe1, 0x52, 0x35,
+       0xd9, 0xdf, 0xd3, 0xe5, 0x3d, 0x7a, 0x53, 0xf7, 0xbb, 0xe9, 0xe5, 0xf0,
+       0x99, 0xf8, 0xf4, 0x60, 0xbb, 0xde, 0x75, 0x93, 0x38, 0xd9, 0xe8, 0x41,
+       0x9c, 0x6d, 0x5c, 0x99, 0x4f, 0xe3, 0xe3, 0x46, 0x5d, 0xa7, 0xdc, 0xd1,
+       0x3c, 0x70, 0x41, 0x34, 0x27, 0xce, 0x0b, 0x81, 0xf3, 0xad, 0x02, 0x67,
+       0xae, 0x8e, 0x24, 0xcf, 0xc0, 0x03, 0xdc, 0x9c, 0x20, 0xfb, 0x68, 0x4a,
+       0xc9, 0xa6, 0x82, 0x6d, 0x69, 0xf6, 0x63, 0xb2, 0xeb, 0x19, 0x3c, 0x74,
+       0xc4, 0xe8, 0x86, 0x35, 0xc7, 0xb6, 0xd3, 0x8a, 0x23, 0x73, 0x3d, 0xb0,
+       0x4a, 0x32, 0x72, 0x01, 0x93, 0xae, 0x48, 0xb9, 0xcd, 0xd6, 0xce, 0x5c,
+       0x7e, 0xab, 0xbb, 0xe2, 0xbb, 0x24, 0x83, 0xec, 0xbd, 0x7e, 0x78, 0x59,
+       0xbf, 0xa7, 0x49, 0x36, 0xad, 0x78, 0xba, 0x14, 0xa5, 0x18, 0x67, 0x90,
+       0x6c, 0x74, 0x8a, 0x13, 0x21, 0xb2, 0x2b, 0x05, 0x5b, 0x27, 0xb4, 0xc3,
+       0x14, 0x0f, 0x46, 0x73, 0x68, 0x47, 0x32, 0xa0, 0x52, 0xce, 0x3e, 0xb5,
+       0xe0, 0xfb, 0xdb, 0xe9, 0xaa, 0x59, 0x49, 0xe0, 0x45, 0x09, 0x68, 0x6b,
+       0x34, 0x23, 0xfb, 0x1a, 0x49, 0x0f, 0xf5, 0x45, 0x0f, 0xee, 0x9b, 0x68,
+       0xc0, 0xbd, 0x53, 0x5e, 0xec, 0x98, 0xb0, 0xf1, 0x7e, 0x8c, 0x6d, 0x42,
+       0xeb, 0x23, 0x6f, 0xea, 0xac, 0x21, 0xd9, 0x6e, 0x8e, 0x45, 0x12, 0x1e,
+       0xe1, 0x42, 0x75, 0xb1, 0x87, 0x72, 0x7f, 0x92, 0xfd, 0xc1, 0xa0, 0x39,
+       0x42, 0xbb, 0x8c, 0xaf, 0x23, 0x15, 0x50, 0xe0, 0x2e, 0xfa, 0x28, 0x86,
+       0xb0, 0xff, 0xf2, 0xb3, 0x6f, 0x60, 0x6b, 0x95, 0x0f, 0x72, 0x46, 0xc1,
+       0x28, 0xe5, 0x7d, 0x2c, 0xab, 0x42, 0x57, 0xb3, 0x44, 0x9f, 0x80, 0x7f,
+       0x76, 0xb2, 0xc9, 0x7f, 0x8c, 0xe2, 0xea, 0x9d, 0x59, 0x89, 0xd7, 0x61,
+       0x9c, 0x40, 0x73, 0xab, 0x78, 0x8c, 0x62, 0xf4, 0x03, 0x14, 0x77, 0x4e,
+       0x94, 0xf2, 0x82, 0xe3, 0x88, 0xc3, 0x4f, 0x96, 0x78, 0xcb, 0x12, 0x6f,
+       0x59, 0xe2, 0x8b, 0xe2, 0xc1, 0x93, 0x59, 0xe6, 0xe3, 0x23, 0xf2, 0xcd,
+       0x04, 0xf1, 0xee, 0xc1, 0x76, 0xa2, 0xf7, 0xfe, 0xa9, 0x1a, 0xdc, 0x43,
+       0xf4, 0x16, 0x0d, 0xad, 0xef, 0x2f, 0x84, 0x8d, 0x7c, 0x4c, 0xb3, 0x76,
+       0x0a, 0x2f, 0xa4, 0x66, 0xdb, 0xee, 0x31, 0x98, 0x67, 0xb2, 0x4f, 0xc9,
+       0xe1, 0x79, 0x5f, 0x92, 0xe4, 0xdf, 0x4f, 0xef, 0x6c, 0x9b, 0xc2, 0xa7,
+       0x12, 0xf1, 0xe4, 0x21, 0x1e, 0x0f, 0x18, 0x5a, 0x62, 0x15, 0xc5, 0xf3,
+       0x73, 0x7a, 0xa4, 0x7c, 0x4e, 0xc6, 0xd7, 0x48, 0x1e, 0x06, 0xcb, 0xa3,
+       0x99, 0xf8, 0xb9, 0x8f, 0x30, 0x8e, 0xdf, 0x64, 0x3e, 0x23, 0xd1, 0x5f,
+       0x10, 0xef, 0x91, 0x62, 0xc0, 0x7f, 0xe6, 0x50, 0x93, 0xff, 0xa5, 0x91,
+       0x0a, 0xfd, 0x3b, 0x89, 0xfe, 0xd9, 0x98, 0x8d, 0x83, 0x44, 0xff, 0x13,
+       0x44, 0x7f, 0x3f, 0xc7, 0xf1, 0x05, 0xfa, 0x4f, 0x94, 0x78, 0xdd, 0x2f,
+       0xe3, 0x61, 0x91, 0xfe, 0x06, 0x6c, 0x9d, 0x5a, 0x94, 0x97, 0x6d, 0xdf,
+       0x66, 0x3c, 0x63, 0xff, 0x1e, 0xc9, 0x6c, 0x79, 0x91, 0xe5, 0xc6, 0xf8,
+       0x2d, 0x72, 0xf8, 0x4e, 0xdc, 0x21, 0xc1, 0xeb, 0xc3, 0x92, 0x22, 0xe7,
+       0x80, 0x10, 0x9e, 0x21, 0xfd, 0x3e, 0x4f, 0x39, 0xec, 0xe9, 0xd2, 0xe5,
+       0x39, 0x8d, 0x75, 0x3d, 0x49, 0x3a, 0xd6, 0x72, 0x16, 0xc5, 0xb4, 0x54,
+       0x29, 0x89, 0x3d, 0x53, 0x48, 0xce, 0x1a, 0x7f, 0x46, 0x81, 0x65, 0x19,
+       0x64, 0xbd, 0x3a, 0xa9, 0xea, 0x5e, 0xdc, 0x3e, 0x13, 0xc0, 0x40, 0x69,
+       0x03, 0xb2, 0x14, 0x67, 0x76, 0x52, 0x5c, 0xfe, 0x30, 0x96, 0xdc, 0xe1,
+       0x47, 0x84, 0xf4, 0x1b, 0xc0, 0xdd, 0xf4, 0xce, 0x81, 0x29, 0xa6, 0x5f,
+       0x5d, 0xd0, 0x73, 0x00, 0x77, 0xd2, 0xbd, 0xbd, 0x53, 0x0a, 0x5e, 0x30,
+       0x8e, 0x10, 0x8e, 0xa9, 0xe0, 0x8a, 0x3b, 0xb2, 0x50, 0xc9, 0x2d, 0x09,
+       0xf7, 0x45, 0xa2, 0x2f, 0xd0, 0xf7, 0xed, 0x25, 0xaf, 0x7f, 0x78, 0x12,
+       0xdf, 0x59, 0x6e, 0xfa, 0xb1, 0x84, 0x30, 0xd8, 0x2d, 0x46, 0xa4, 0xbc,
+       0x9e, 0x30, 0xd3, 0x60, 0x49, 0xc2, 0xb7, 0x67, 0xbc, 0x78, 0x60, 0xe2,
+       0x53, 0xbb, 0x2a, 0xee, 0xc2, 0xcd, 0xcd, 0x5e, 0xdc, 0x3f, 0x93, 0xc4,
+       0xbe, 0x29, 0x84, 0xaa, 0x63, 0x63, 0x14, 0xb3, 0x2b, 0x79, 0xa0, 0x86,
+       0x78, 0xdf, 0x3f, 0xe5, 0xf3, 0xf7, 0x1f, 0x62, 0x19, 0x6c, 0x08, 0x92,
+       0x77, 0x94, 0xab, 0x63, 0x32, 0xb6, 0x1b, 0xf2, 0x92, 0x6a, 0x32, 0xf4,
+       0x23, 0x34, 0xdf, 0x34, 0xe4, 0x57, 0x97, 0x23, 0x72, 0xb8, 0x51, 0x2e,
+       0x8f, 0x2e, 0x41, 0x03, 0x1e, 0x98, 0x4b, 0x62, 0x8c, 0x6c, 0xf4, 0xbe,
+       0x89, 0xe1, 0xef, 0xd4, 0x53, 0xec, 0xf0, 0xb7, 0x69, 0xfd, 0x6f, 0x08,
+       0x13, 0xf9, 0x88, 0x07, 0x3b, 0x67, 0x7c, 0xfe, 0x1d, 0x87, 0xec, 0xf5,
+       0x6c, 0x4f, 0x77, 0xcd, 0x35, 0xe0, 0x9e, 0x29, 0xba, 0x37, 0xc1, 0x36,
+       0x4c, 0xb6, 0x16, 0xa9, 0x26, 0xde, 0xc2, 0x49, 0x0f, 0xe1, 0x24, 0x39,
+       0x56, 0x43, 0xf2, 0xf0, 0xe0, 0x4e, 0xc7, 0x16, 0x54, 0x6c, 0x9f, 0xb2,
+       0xf1, 0x96, 0x11, 0xc5, 0x28, 0xd9, 0xf5, 0xe1, 0x29, 0x6d, 0xbe, 0x93,
+       0x30, 0xce, 0x3b, 0xb2, 0x76, 0xb8, 0x59, 0x4e, 0xa2, 0x61, 0x0d, 0xc5,
+       0xf6, 0x06, 0xdb, 0xbe, 0xa3, 0xad, 0x65, 0xe0, 0xc7, 0x44, 0x73, 0xbd,
+       0xb9, 0x0c, 0xe5, 0x7a, 0x6d, 0x14, 0x68, 0x19, 0xac, 0x92, 0xae, 0xc6,
+       0xd9, 0xa5, 0x1c, 0xff, 0x38, 0x86, 0x07, 0xfc, 0x0d, 0x99, 0x4a, 0x6e,
+       0x6b, 0x28, 0x36, 0xf9, 0xeb, 0x33, 0x41, 0x7f, 0x7d, 0x11, 0xfe, 0xaa,
+       0x22, 0xf0, 0x03, 0x8a, 0x2f, 0x4b, 0xd6, 0xfc, 0xca, 0x4e, 0x35, 0x38,
+       0x38, 0xd0, 0xff, 0xdc, 0xa4, 0x66, 0x95, 0xa1, 0xed, 0xa3, 0x70, 0x89,
+       0x47, 0xe7, 0x5c, 0xfe, 0xe3, 0x14, 0x07, 0x1a, 0xf4, 0x28, 0xf6, 0x92,
+       0x3e, 0x87, 0xc8, 0x16, 0x7e, 0xb1, 0x06, 0xd8, 0x9f, 0x09, 0x87, 0x0c,
+       0xd1, 0x47, 0x13, 0x03, 0xbb, 0x8b, 0x14, 0xeb, 0xa5, 0xdf, 0xa2, 0x40,
+       0xa6, 0x45, 0x29, 0x9d, 0x21, 0x9d, 0x71, 0xc3, 0x5a, 0x5a, 0xd1, 0xc9,
+       0x3d, 0xd9, 0xe7, 0x6d, 0xbf, 0xae, 0xe7, 0x8a, 0xa4, 0xb3, 0x07, 0x4b,
+       0x3e, 0x0c, 0x12, 0x0e, 0x58, 0x42, 0xd8, 0xf1, 0x7e, 0xb2, 0x8b, 0xfb,
+       0x26, 0x64, 0xa2, 0x8f, 0xc7, 0x25, 0x91, 0x5c, 0x56, 0xc1, 0xa0, 0x0f,
+       0xcc, 0xb0, 0x5d, 0x92, 0x1d, 0x91, 0x2d, 0x3e, 0x43, 0xb9, 0xfe, 0xe9,
+       0xcf, 0x61, 0x0f, 0x4d, 0xb5, 0x2e, 0xe5, 0xfc, 0x8a, 0x3c, 0x86, 0xa7,
+       0x98, 0x67, 0xed, 0x30, 0xa4, 0x24, 0x6e, 0x30, 0x7e, 0x42, 0xb9, 0x80,
+       0x79, 0x27, 0xec, 0x3b, 0x15, 0xc5, 0xc3, 0x59, 0xc2, 0x32, 0xb1, 0xf7,
+       0xed, 0x3b, 0x03, 0x2c, 0x03, 0xe6, 0x27, 0x2e, 0x73, 0xde, 0x6c, 0x20,
+       0xcc, 0xfb, 0xff, 0x6f, 0x77, 0xb7, 0xdb, 0x29, 0x07, 0xc3, 0x12, 0xb6,
+       0x26, 0x7b, 0x4a, 0x5d, 0xb2, 0x9f, 0xfb, 0xed, 0xb3, 0x01, 0xce, 0xd3,
+       0x0d, 0x48, 0x5d, 0xb2, 0x05, 0xb6, 0x25, 0x2c, 0x37, 0xda, 0x76, 0xdd,
+       0xaf, 0x82, 0xed, 0x21, 0x7a, 0x99, 0x3d, 0xb8, 0x89, 0x26, 0x15, 0x3b,
+       0xe6, 0xd8, 0x7e, 0xed, 0x8f, 0x96, 0x9b, 0xff, 0x40, 0x39, 0x42, 0x3f,
+       0xfc, 0x13, 0xdc, 0x48, 0xf7, 0x03, 0xf8, 0x36, 0xf9, 0xd1, 0xdd, 0xc4,
+       0xe7, 0x8e, 0xf6, 0xbb, 0x1d, 0xbf, 0xdd, 0x51, 0xba, 0x8e, 0xee, 0xb3,
+       0xbc, 0x3b, 0xb1, 0x2f, 0x6b, 0x20, 0x9d, 0x2d, 0x3b, 0xf9, 0xc7, 0x65,
+       0xc6, 0xf1, 0x7d, 0x8a, 0xb3, 0xcf, 0x94, 0x18, 0x8b, 0x25, 0x1c, 0x1c,
+       0xf6, 0xbd, 0x52, 0x2b, 0x9e, 0x25, 0x9f, 0x7c, 0x9a, 0x62, 0xee, 0x77,
+       0x1d, 0x7c, 0xe6, 0x12, 0x07, 0xd3, 0x84, 0x45, 0x47, 0x2c, 0xa4, 0xf3,
+       0x21, 0x78, 0x0e, 0x85, 0xf7, 0xed, 0x10, 0xda, 0x0f, 0x48, 0x5e, 0xfe,
+       0xfd, 0xb3, 0x2b, 0x50, 0x7d, 0x48, 0xcb, 0x11, 0xdd, 0xfe, 0x87, 0x67,
+       0x75, 0xc2, 0xd2, 0x41, 0xff, 0xde, 0xbc, 0xea, 0xdf, 0x33, 0x19, 0xf0,
+       0xef, 0x99, 0x6d, 0x20, 0x3f, 0x5a, 0xe6, 0x1f, 0x9e, 0x0d, 0xfa, 0x77,
+       0xa5, 0x9b, 0xfc, 0xbb, 0xf2, 0x6b, 0x10, 0x6a, 0x80, 0xb5, 0x8c, 0x72,
+       0xc4, 0x3d, 0x13, 0xdf, 0x44, 0xae, 0xbe, 0x12, 0xf7, 0x07, 0xc8, 0x36,
+       0xea, 0xc8, 0x0e, 0xaf, 0x91, 0x6e, 0x46, 0x79, 0x69, 0xe5, 0xde, 0xb7,
+       0xe9, 0xde, 0x03, 0x6d, 0xf0, 0xff, 0xa5, 0x13, 0x7b, 0x81, 0x67, 0xc9,
+       0xd6, 0x9e, 0x69, 0xa3, 0x7a, 0xf2, 0x92, 0xad, 0xb9, 0x28, 0xde, 0xda,
+       0xb6, 0xb1, 0x46, 0x20, 0xd8, 0xb6, 0x11, 0x58, 0xb2, 0x58, 0x43, 0x26,
+       0x73, 0xae, 0xb6, 0x24, 0x96, 0xeb, 0x9b, 0x70, 0x44, 0xa5, 0x54, 0xd3,
+       0xf6, 0x35, 0x2c, 0xbc, 0x83, 0x6f, 0x4f, 0x78, 0x90, 0xda, 0xa2, 0x62,
+       0x96, 0x30, 0xca, 0x5d, 0x34, 0xff, 0xca, 0x58, 0x8b, 0x3a, 0x47, 0x7a,
+       0x48, 0xaa, 0x7c, 0x8f, 0x7c, 0xa2, 0x6d, 0x2d, 0xf9, 0x44, 0x65, 0xfd,
+       0xa7, 0x48, 0x5f, 0xa3, 0x73, 0x51, 0xec, 0x29, 0xfd, 0x40, 0xaa, 0xe4,
+       0x17, 0x2d, 0x97, 0xc4, 0x69, 0x67, 0xec, 0x53, 0xd9, 0x37, 0xec, 0x90,
+       0x63, 0x77, 0x02, 0x8f, 0xac, 0x8e, 0xec, 0xfb, 0xef, 0x52, 0x23, 0xf1,
+       0x45, 0xb2, 0xcb, 0x3a, 0xf5, 0x63, 0xdd, 0x15, 0xfa, 0xbf, 0xc5, 0xf7,
+       0x55, 0x96, 0xed, 0xa0, 0xd8, 0x47, 0x75, 0x2a, 0x95, 0x4c, 0x75, 0x4b,
+       0xf4, 0x43, 0x78, 0xba, 0x87, 0xef, 0x05, 0xfc, 0xfb, 0x27, 0x93, 0x52,
+       0x40, 0x87, 0xea, 0x36, 0x3b, 0xc5, 0xfe, 0xd9, 0x65, 0xfe, 0x87, 0x27,
+       0x37, 0x8a, 0x87, 0x67, 0x9b, 0xfc, 0xc3, 0xe9, 0x2e, 0x31, 0x9c, 0xdf,
+       0x22, 0xac, 0xdc, 0xb7, 0x84, 0x35, 0x9b, 0x12, 0x56, 0xbe, 0x8f, 0xae,
+       0xbd, 0x62, 0x32, 0x3f, 0x28, 0xf6, 0xe4, 0x79, 0x7e, 0xd2, 0x15, 0xad,
+       0xf1, 0x3d, 0x8a, 0xbd, 0xcf, 0x52, 0xec, 0x7d, 0x86, 0x62, 0xef, 0xd3,
+       0x64, 0xef, 0xdf, 0xbd, 0x84, 0x6d, 0xd9, 0xc6, 0x93, 0x8c, 0x49, 0xfc,
+       0x7f, 0x51, 0x3c, 0x49, 0xfa, 0x66, 0xd9, 0xfd, 0x27, 0xb2, 0x6d, 0x96,
+       0xc9, 0x03, 0x9c, 0x2b, 0x48, 0x4f, 0x17, 0x1d, 0x5b, 0x7e, 0x64, 0x35,
+       0x63, 0xa8, 0x41, 0xb1, 0x95, 0xe8, 0x4b, 0xba, 0x08, 0xfb, 0xe8, 0x84,
+       0x4b, 0xb2, 0x83, 0xe2, 0x8e, 0x3c, 0xdf, 0x3f, 0x80, 0x9d, 0x54, 0x0b,
+       0x1e, 0x8c, 0x85, 0x7b, 0xb6, 0x11, 0x66, 0xda, 0x4c, 0x98, 0x69, 0x65,
+       0x4c, 0xc1, 0x85, 0xd6, 0x4f, 0x6c, 0x2c, 0x45, 0xf2, 0xde, 0xb8, 0x96,
+       0xcb, 0x55, 0xf2, 0xed, 0x68, 0x06, 0x5c, 0xaf, 0xa3, 0xae, 0x56, 0xd7,
+       0x4e, 0x24, 0x11, 0xde, 0x17, 0x97, 0x60, 0x55, 0x99, 0x6e, 0xdc, 0xe3,
+       0xd4, 0x88, 0x1b, 0x30, 0x31, 0x21, 0xb0, 0xbd, 0x2d, 0xf9, 0x87, 0x6e,
+       0x92, 0xd5, 0x3b, 0xed, 0x08, 0x90, 0x7a, 0x85, 0x42, 0xf5, 0x7c, 0x17,
+       0x49, 0xaf, 0x93, 0x72, 0xee, 0x91, 0xec, 0x5a, 0x34, 0xb6, 0x29, 0xa4,
+       0x43, 0x17, 0x6e, 0x2b, 0xde, 0x40, 0x7a, 0x8c, 0x1c, 0x7e, 0x0e, 0x5e,
+       0xff, 0x0b, 0x93, 0x26, 0x46, 0xb2, 0xf8, 0x8e, 0x8f, 0x6a, 0xb7, 0xbb,
+       0x09, 0x37, 0x7d, 0x97, 0x68, 0xd8, 0xd4, 0x16, 0xe9, 0xa2, 0x1a, 0x5e,
+       0xf5, 0x9a, 0x55, 0x18, 0x6f, 0xf6, 0x43, 0xd5, 0x53, 0xe2, 0x95, 0x7c,
+       0xe4, 0xf0, 0x0e, 0xe9, 0x5b, 0xe2, 0xc7, 0xb3, 0x26, 0x1e, 0x2e, 0xf5,
+       0x89, 0xbf, 0x9c, 0x55, 0x40, 0xba, 0xa1, 0xb8, 0x65, 0xe0, 0x30, 0xd1,
+       0xe5, 0x26, 0x9c, 0xe4, 0xfe, 0x1d, 0x81, 0x2b, 0xf4, 0x24, 0xbe, 0xbd,
+       0x96, 0x7d, 0xa1, 0x12, 0xd3, 0x5c, 0x6b, 0x81, 0x7d, 0x64, 0x93, 0x8d,
+       0x99, 0x4e, 0xb1, 0x9c, 0xfe, 0xbf, 0x40, 0x79, 0x2d, 0x29, 0x75, 0x89,
+       0x46, 0xc2, 0xa4, 0x4b, 0xa7, 0x7b, 0xc5, 0x92, 0x22, 0x63, 0x50, 0xa8,
+       0x4b, 0x49, 0x46, 0x4b, 0x8b, 0xe7, 0xe5, 0x0a, 0xf6, 0x77, 0xb3, 0x2d,
+       0x59, 0x3e, 0x53, 0xf1, 0x1f, 0xa4, 0xd8, 0xbe, 0x23, 0xd6, 0x45, 0xf8,
+       0x98, 0xef, 0x0f, 0x8a, 0x11, 0x92, 0x63, 0xce, 0xed, 0xd8, 0x8e, 0xff,
+       0xc8, 0x24, 0xdc, 0x8d, 0x26, 0x42, 0x55, 0x94, 0x3b, 0xfe, 0xe7, 0x9a,
+       0x88, 0xf5, 0x9c, 0xd4, 0x2d, 0x46, 0xf3, 0x01, 0xff, 0xe1, 0x49, 0xce,
+       0x33, 0x9d, 0xe2, 0x30, 0xe9, 0x3c, 0x4b, 0x3a, 0xcf, 0x92, 0xce, 0x33,
+       0xa4, 0xf3, 0xcc, 0x97, 0xe8, 0x7c, 0x2f, 0xe9, 0x7c, 0x57, 0xfe, 0x63,
+       0x47, 0x87, 0x2e, 0xd3, 0x44, 0x96, 0xf2, 0xf2, 0x78, 0x73, 0x85, 0xbf,
+       0x0f, 0x49, 0x16, 0xa7, 0x62, 0x5f, 0x77, 0xc1, 0x6b, 0x52, 0x6c, 0xed,
+       0xa6, 0x77, 0xbe, 0xb2, 0x60, 0xe3, 0xaa, 0x7f, 0x6c, 0xb2, 0x53, 0x8c,
+       0x91, 0xdf, 0x8d, 0xd3, 0xfc, 0xe3, 0xe4, 0x77, 0xc3, 0xe9, 0x7f, 0x8e,
+       0xdd, 0xb0, 0xdd, 0xc1, 0xf2, 0x52, 0xde, 0xaa, 0x21, 0xbb, 0x74, 0x99,
+       0x6c, 0x43, 0x5b, 0x44, 0xf2, 0xe8, 0xb7, 0x44, 0xf2, 0x58, 0x4a, 0x24,
+       0x0b, 0x7d, 0x74, 0xed, 0x15, 0x37, 0x39, 0xf5, 0xe7, 0xa0, 0xe8, 0x2c,
+       0x04, 0xfc, 0x53, 0xb4, 0xce, 0x14, 0xf1, 0xf1, 0x08, 0xad, 0xf3, 0x88,
+       0x63, 0xbb, 0xe3, 0x2e, 0xce, 0xff, 0xcf, 0x67, 0xd9, 0xce, 0xd8, 0xbe,
+       0xde, 0x25, 0xda, 0xd9, 0x37, 0x2e, 0xf5, 0x76, 0xe8, 0xaf, 0x5d, 0x86,
+       0xbe, 0xc3, 0x55, 0xe1, 0x89, 0x73, 0x3f, 0xe7, 0x7a, 0x8e, 0xc3, 0xaa,
+       0x53, 0x03, 0x3e, 0x73, 0x09, 0x03, 0x30, 0x1e, 0x80, 0xb2, 0xc4, 0x7c,
+       0xb0, 0xe3, 0xdb, 0xcd, 0xff, 0x8b, 0xe6, 0x1b, 0x80, 0xb1, 0x16, 0x4a,
+       0xc0, 0xfc, 0x65, 0xc7, 0x64, 0x33, 0xc5, 0x69, 0x9a, 0x53, 0xc9, 0x00,
+       0x7a, 0x46, 0x60, 0x57, 0x42, 0x10, 0x8e, 0x5d, 0x46, 0x7e, 0xc9, 0xf4,
+       0x6b, 0x5d, 0x49, 0x7a, 0xb6, 0x62, 0x04, 0xca, 0x72, 0x73, 0x27, 0xec,
+       0x2c, 0x94, 0x3a, 0xb3, 0x1f, 0x1f, 0x8d, 0x84, 0x83, 0x5d, 0xd0, 0x52,
+       0xe7, 0x64, 0xad, 0x4c, 0xf9, 0x6d, 0x60, 0x97, 0xd0, 0xfa, 0xe7, 0x05,
+       0xf7, 0x87, 0x18, 0xb3, 0xef, 0x44, 0xab, 0x83, 0xdd, 0xfb, 0xd1, 0x92,
+       0x07, 0xd5, 0xdf, 0x84, 0x6b, 0x69, 0xce, 0x97, 0x8c, 0x0f, 0x38, 0x27,
+       0x24, 0x09, 0x0b, 0x7e, 0x61, 0x2e, 0x10, 0x8e, 0xe1, 0x79, 0x78, 0x8e,
+       0xb0, 0xda, 0x4f, 0xf3, 0xbe, 0x25, 0xb7, 0x0c, 0x0c, 0x0b, 0x2d, 0xf1,
+       0xc5, 0xf9, 0x56, 0xe6, 0x21, 0x56, 0x66, 0x2c, 0xbb, 0x46, 0xf7, 0x32,
+       0x1e, 0x92, 0xce, 0xeb, 0x7a, 0xf2, 0x35, 0x84, 0xb0, 0x92, 0xea, 0xe3,
+       0x68, 0x91, 0x79, 0x18, 0xc2, 0x8b, 0x86, 0xd6, 0x43, 0x55, 0x28, 0xd5,
+       0x2b, 0x9d, 0x38, 0x40, 0xb1, 0xf7, 0xe1, 0x12, 0xf7, 0xb7, 0x06, 0xc5,
+       0xaa, 0x11, 0xf2, 0x4b, 0xc7, 0x9e, 0xa0, 0x34, 0x9a, 0x0f, 0xe2, 0x3a,
+       0x5a, 0xdf, 0x4f, 0x35, 0xcf, 0xeb, 0xb4, 0xbe, 0x94, 0xd1, 0x06, 0x69,
+       0xfd, 0xd4, 0x1b, 0x22, 0x3c, 0x4f, 0x7c, 0xf5, 0xad, 0x97, 0x5b, 0xfa,
+       0x87, 0x84, 0x96, 0x24, 0xd2, 0xc9, 0x8f, 0x79, 0xed, 0x07, 0x99, 0x17,
+       0xba, 0x52, 0x7d, 0x43, 0x76, 0xd4, 0x5c, 0x50, 0x44, 0x64, 0x6c, 0x03,
+       0xf6, 0xcc, 0x6c, 0xc0, 0x6e, 0xf2, 0xc7, 0xfd, 0x46, 0x1d, 0x42, 0xf5,
+       0xa8, 0xad, 0xd3, 0x31, 0x7f, 0x4e, 0x17, 0xf2, 0x8e, 0xd6, 0x26, 0xb2,
+       0xe3, 0x93, 0x8d, 0xd5, 0xf8, 0xd8, 0xde, 0xa6, 0x6f, 0xe8, 0xa2, 0x88,
+       0x78, 0x9d, 0x07, 0x87, 0x64, 0xf2, 0xef, 0x37, 0x7f, 0x41, 0x01, 0xd5,
+       0x63, 0x32, 0x6e, 0x4b, 0x88, 0x8b, 0xf9, 0x53, 0xae, 0x8a, 0x1f, 0x34,
+       0xe3, 0x23, 0x15, 0x75, 0x41, 0x7d, 0x15, 0xe6, 0x55, 0x85, 0xe2, 0x85,
+       0xe5, 0xd4, 0x62, 0x37, 0x8e, 0xf6, 0xa0, 0x91, 0xea, 0xe2, 0xdb, 0x62,
+       0xbf, 0xb0, 0x3f, 0xb9, 0x82, 0xdf, 0xfb, 0x23, 0x4f, 0x25, 0x76, 0x7e,
+       0xd9, 0x1c, 0x71, 0x8a, 0x37, 0x2d, 0x54, 0xc7, 0xd6, 0x50, 0x90, 0xee,
+       0xa2, 0x7c, 0xa4, 0xf5, 0xa5, 0xa9, 0x0e, 0xed, 0x8f, 0xb4, 0x18, 0xb2,
+       0xa8, 0x42, 0x39, 0x10, 0x1e, 0xd8, 0x86, 0xe4, 0x5d, 0xfe, 0x05, 0x3a,
+       0x9e, 0x11, 0x2b, 0xdc, 0xf4, 0x1e, 0xcf, 0x73, 0x99, 0x3d, 0xe5, 0xc9,
+       0x9e, 0xf8, 0x39, 0xff, 0x7f, 0xe9, 0xb9, 0xf2, 0x15, 0xf3, 0x97, 0xe6,
+       0xbf, 0x5f, 0xf9, 0x65, 0xf7, 0x03, 0xeb, 0x7e, 0xfd, 0xfe, 0xff, 0xad,
+       0x9e, 0x2f, 0xd7, 0xbb, 0x1c, 0xcc, 0x90, 0x94, 0xb8, 0x7f, 0xe9, 0x32,
+       0x7d, 0x1d, 0xbb, 0xf5, 0xdf, 0xa0, 0x98, 0xc6, 0xfd, 0x0b, 0xce, 0xd3,
+       0x67, 0x9d, 0xfe, 0xc5, 0xf3, 0x9f, 0xc3, 0xac, 0x1c, 0x5b, 0x3c, 0xa2,
+       0x66, 0xdc, 0xb2, 0x1b, 0xf4, 0xdb, 0xa8, 0xae, 0x19, 0xc2, 0xb6, 0x98,
+       0x81, 0xb1, 0xac, 0xd6, 0x73, 0x33, 0xf4, 0xe4, 0x16, 0x41, 0x13, 0x15,
+       0x3d, 0x42, 0x1e, 0x5f, 0x78, 0x66, 0x58, 0x54, 0xab, 0x95, 0x51, 0x4d,
+       0xb1, 0xc9, 0xa5, 0xab, 0x0a, 0x8a, 0x01, 0xc5, 0x55, 0x0c, 0x2a, 0x55,
+       0xc5, 0x26, 0xa5, 0x9a, 0xc6, 0xf9, 0xc6, 0xb5, 0xf9, 0x9b, 0x31, 0x84,
+       0xf9, 0x35, 0x5e, 0xab, 0xd1, 0xd4, 0xd4, 0x46, 0x79, 0x08, 0xbb, 0x63,
+       0xfc, 0x6e, 0x27, 0xd5, 0x6c, 0x10, 0xf5, 0x19, 0x42, 0xc6, 0xa6, 0xc0,
+       0x9e, 0x76, 0x6d, 0x70, 0x85, 0xa4, 0x77, 0xfd, 0xad, 0x70, 0x29, 0x9e,
+       0x22, 0x84, 0x3f, 0x23, 0xe1, 0x70, 0x3b, 0x3c, 0x9e, 0xb5, 0x5a, 0xff,
+       0x49, 0x31, 0x88, 0x27, 0x62, 0x91, 0x9e, 0xed, 0x22, 0xa4, 0x78, 0xe9,
+       0x99, 0x3b, 0x43, 0xf1, 0x37, 0x63, 0x79, 0xdc, 0x6b, 0xb5, 0xa0, 0x24,
+       0x92, 0xd8, 0xa6, 0xeb, 0xc6, 0x38, 0x14, 0x5a, 0x13, 0xa2, 0x3a, 0xa3,
+       0xcd, 0xbf, 0x45, 0x98, 0xea, 0x93, 0x95, 0x83, 0x68, 0x5b, 0x13, 0xd9,
+       0xd7, 0x27, 0xe9, 0x0a, 0x61, 0x3d, 0xe1, 0xca, 0xf8, 0x70, 0xcd, 0xa1,
+       0xc5, 0x7e, 0x8e, 0x6d, 0x7f, 0x18, 0x2b, 0x93, 0x5e, 0xa0, 0xd4, 0x16,
+       0xa3, 0x8a, 0x8f, 0x70, 0x7d, 0xcb, 0x21, 0xc6, 0x59, 0xb6, 0xbd, 0x23,
+       0x56, 0xfe, 0x9a, 0x17, 0xad, 0xc4, 0x63, 0x0f, 0x66, 0xd2, 0x8c, 0xbb,
+       0x4c, 0x4c, 0x53, 0x4d, 0xa4, 0x8f, 0x34, 0xe1, 0x38, 0xc5, 0xa1, 0xb9,
+       0x34, 0xf7, 0x7d, 0xfa, 0x49, 0xc6, 0x7d, 0x44, 0x7f, 0x2f, 0xd5, 0xc1,
+       0x29, 0x8a, 0x5f, 0x2c, 0xe3, 0x6d, 0x64, 0xf7, 0x50, 0xbc, 0x66, 0xac,
+       0xe3, 0xc6, 0x31, 0x28, 0x1e, 0x73, 0x55, 0xc7, 0x55, 0x87, 0x50, 0x4f,
+       0x79, 0xdf, 0xa4, 0x8a, 0x07, 0xd1, 0x48, 0xc4, 0xb8, 0x80, 0x48, 0xf0,
+       0x25, 0xd2, 0xc7, 0xb0, 0x0e, 0xec, 0x72, 0x6a, 0x6c, 0x17, 0xac, 0x3c,
+       0xd7, 0xcf, 0xf0, 0x54, 0xb7, 0xd7, 0xe3, 0xfc, 0xa8, 0xcb, 0xe9, 0x1d,
+       0x59, 0x54, 0xff, 0xbc, 0x60, 0x68, 0xa9, 0x1c, 0xbd, 0xb7, 0x55, 0xfd,
+       0xd9, 0xde, 0x9a, 0x38, 0x14, 0x8a, 0x69, 0x64, 0x7b, 0x7f, 0xe2, 0x7d,
+       0x8b, 0x6c, 0xf4, 0x96, 0xc9, 0x3f, 0xf5, 0x7e, 0x14, 0xcf, 0x79, 0x3f,
+       0x88, 0xdb, 0x76, 0x82, 0xf0, 0x68, 0x1f, 0xd5, 0xdc, 0x1f, 0x8e, 0x58,
+       0xde, 0x0b, 0x71, 0xee, 0xff, 0xba, 0xf0, 0xdb, 0xf4, 0xfd, 0xb1, 0x11,
+       0x05, 0x9b, 0x0b, 0x8d, 0x70, 0x8f, 0xc9, 0x98, 0x31, 0xae, 0xc7, 0x36,
+       0x55, 0xc2, 0x1d, 0xd1, 0x27, 0xc9, 0x26, 0x25, 0x1a, 0x73, 0x90, 0xbe,
+       0x73, 0x2f, 0xeb, 0x11, 0x6c, 0x57, 0x67, 0xbd, 0xe7, 0xe3, 0x4c, 0x6f,
+       0x88, 0xe9, 0x55, 0x24, 0xfd, 0xeb, 0xd8, 0x7a, 0x33, 0xd7, 0x56, 0xce,
+       0xc7, 0xf3, 0x52, 0x7b, 0x03, 0x8e, 0x8f, 0x36, 0xe2, 0xb9, 0x51, 0xcb,
+       0xf3, 0x5a, 0x7b, 0x14, 0xfd, 0x23, 0x36, 0x5e, 0x36, 0xac, 0xc1, 0x6a,
+       0xb2, 0xf3, 0x04, 0xd5, 0x57, 0xe1, 0x35, 0xdc, 0x43, 0x40, 0x44, 0x46,
+       0x64, 0x80, 0x40, 0xe6, 0xad, 0x14, 0xba, 0x52, 0xb5, 0x54, 0xa7, 0x9d,
+       0x11, 0x76, 0xd5, 0x5d, 0xed, 0x2e, 0xa2, 0x01, 0xd8, 0x58, 0x68, 0x25,
+       0xb9, 0x45, 0xb1, 0x39, 0xa2, 0x60, 0x53, 0xc1, 0xc0, 0x73, 0x69, 0x1f,
+       0x6e, 0x29, 0xc4, 0x09, 0x7b, 0xab, 0x44, 0x7b, 0x02, 0xa5, 0x74, 0x00,
+       0xdf, 0x28, 0x34, 0x91, 0xbc, 0x83, 0xb8, 0xbe, 0x10, 0xc2, 0x89, 0x34,
+       0xe7, 0x6f, 0xd3, 0xb3, 0x35, 0xde, 0x84, 0xae, 0x82, 0x8e, 0xd9, 0x34,
+       0x3c, 0xf7, 0xc5, 0x43, 0xe8, 0x2c, 0x44, 0x51, 0x20, 0x0c, 0xf7, 0x75,
+       0x9a, 0xf3, 0x16, 0xd2, 0x49, 0x6b, 0x21, 0x80, 0x15, 0x11, 0xe0, 0xba,
+       0x82, 0x4f, 0x0c, 0x12, 0xb6, 0x4a, 0x14, 0x1a, 0x70, 0x61, 0x8c, 0xed,
+       0xdc, 0xe8, 0xd8, 0x3d, 0xaa, 0x22, 0x54, 0xc0, 0x35, 0x0a, 0xb0, 0x93,
+       0xaa, 0xc3, 0x54, 0x81, 0xe8, 0x3d, 0xd0, 0x5e, 0xe9, 0xdd, 0xae, 0x2a,
+       0x7c, 0xc6, 0x6f, 0x1d, 0xe9, 0xe9, 0xa3, 0x43, 0xb3, 0xde, 0x4f, 0xe2,
+       0x1c, 0x9b, 0x9a, 0x3a, 0x5e, 0x3f, 0x04, 0x44, 0xa7, 0x98, 0x37, 0x27,
+       0x36, 0x72, 0x3c, 0x6c, 0x55, 0xf0, 0xb7, 0x36, 0xd5, 0xa0, 0xa1, 0x19,
+       0xde, 0x23, 0xd0, 0x7d, 0x44, 0x87, 0x8a, 0x24, 0xad, 0x7d, 0x53, 0xe1,
+       0x7b, 0xf6, 0xd6, 0xa5, 0x41, 0xdc, 0x18, 0xa9, 0xc8, 0xea, 0x0c, 0xe9,
+       0x70, 0x7a, 0xac, 0x11, 0x73, 0x44, 0x83, 0xdb, 0x6c, 0xee, 0x38, 0x36,
+       0x69, 0x63, 0xa3, 0x61, 0x79, 0x5f, 0x6b, 0x5f, 0x85, 0x7b, 0x0f, 0x0d,
+       0x9f, 0xae, 0x22, 0xbd, 0xce, 0x1b, 0xb7, 0xe2, 0xe1, 0x29, 0x5c, 0xd9,
+       0x08, 0x3c, 0x14, 0x04, 0xf7, 0xaa, 0xb5, 0xd0, 0x09, 0x44, 0xba, 0xee,
+       0x43, 0x44, 0xd5, 0x85, 0x66, 0xbc, 0x2c, 0x90, 0xac, 0x31, 0x23, 0xa7,
+       0x6f, 0x02, 0x5e, 0xac, 0x22, 0x0f, 0xbe, 0xa5, 0xe0, 0x22, 0x19, 0x05,
+       0x51, 0x1a, 0xab, 0x82, 0x4c, 0x7e, 0x72, 0x51, 0xc7, 0xc6, 0x3a, 0x92,
+       0xb5, 0x2c, 0x14, 0xd2, 0x73, 0x2b, 0x8e, 0x8d, 0x2c, 0xca, 0xca, 0x87,
+       0x1b, 0x48, 0x86, 0x4f, 0x8c, 0xd8, 0x43, 0x7a, 0x2c, 0x40, 0xb2, 0x56,
+       0x89, 0xbe, 0x45, 0x39, 0xb1, 0xfc, 0x16, 0xe5, 0x74, 0x2b, 0x76, 0xcf,
+       0xb1, 0xdc, 0xfe, 0x5f, 0xe4, 0x35, 0xeb, 0xd8, 0xdd, 0xc6, 0xc9, 0x28,
+       0x1a, 0x0f, 0x5d, 0x92, 0x1d, 0xd3, 0xf7, 0x10, 0xf1, 0xf1, 0x1d, 0xff,
+       0xb5, 0x91, 0xfe, 0xf7, 0x84, 0x8f, 0xe8, 0x51, 0x49, 0x37, 0xef, 0xb9,
+       0x19, 0xbb, 0x93, 0x4c, 0x2e, 0xc9, 0x38, 0x48, 0x32, 0x0e, 0x4e, 0xb1,
+       0xac, 0x9b, 0x48, 0xd6, 0xc0, 0xeb, 0x84, 0xcb, 0xae, 0x8b, 0x45, 0x51,
+       0x7b, 0x48, 0x4b, 0x36, 0xca, 0xe1, 0x44, 0x9d, 0x00, 0x55, 0x25, 0x68,
+       0xad, 0xc5, 0x87, 0x2c, 0x67, 0x83, 0xe4, 0xfc, 0x9d, 0x61, 0xe2, 0x67,
+       0x03, 0xcd, 0xb7, 0x91, 0xe4, 0x9c, 0x24, 0xfe, 0x6f, 0x72, 0xe6, 0x6d,
+       0xa2, 0x79, 0x7b, 0xa9, 0xf6, 0x98, 0xf5, 0x5e, 0x24, 0x7a, 0xa2, 0x9f,
+       0xd1, 0x42, 0x68, 0x3c, 0x12, 0x7c, 0x8f, 0x6a, 0xec, 0xeb, 0x9d, 0x71,
+       0x2a, 0x8d, 0x63, 0xda, 0x7f, 0x5c, 0x2d, 0xe9, 0x5f, 0xd6, 0x67, 0xfe,
+       0x16, 0xb8, 0xe7, 0x60, 0xa1, 0x8f, 0xea, 0x88, 0x5e, 0xaa, 0x95, 0x14,
+       0xca, 0x6d, 0x16, 0xbe, 0x1b, 0xd7, 0xa2, 0xf5, 0x82, 0xe3, 0x9f, 0x45,
+       0x7e, 0x58, 0xa6, 0x3a, 0x29, 0x1c, 0x9a, 0x43, 0x50, 0x91, 0x8a, 0x0a,
+       0xe1, 0xc1, 0x26, 0x45, 0x2e, 0x92, 0xbf, 0x06, 0xfb, 0x08, 0x4f, 0xbb,
+       0xf0, 0x52, 0xde, 0x85, 0x57, 0xd2, 0xbd, 0xd8, 0x5f, 0xf2, 0x10, 0x6e,
+       0xb6, 0x3c, 0xae, 0xb5, 0x7f, 0x56, 0x55, 0x89, 0xc9, 0x2b, 0xd1, 0x3d,
+       0xfe, 0x20, 0x6a, 0x32, 0xae, 0x1e, 0xca, 0xa7, 0xc6, 0x4d, 0x24, 0x97,
+       0x8d, 0x45, 0x7e, 0xde, 0x84, 0x4c, 0x3a, 0x45, 0x18, 0x28, 0x4c, 0x35,
+       0x90, 0x0b, 0xb9, 0xc6, 0x26, 0xa7, 0x9f, 0x3b, 0x4a, 0xf7, 0x46, 0x4b,
+       0x5f, 0xec, 0x33, 0xdf, 0xba, 0xd0, 0x5f, 0xee, 0xc7, 0xde, 0x6c, 0x1f,
+       0x61, 0xd3, 0x5e, 0x8a, 0xef, 0x15, 0x1a, 0x67, 0xe3, 0x3d, 0xd8, 0x9b,
+       0x37, 0x2f, 0xc5, 0x8f, 0x69, 0x27, 0x7e, 0x0c, 0xa0, 0xba, 0x9d, 0xf7,
+       0xad, 0x7a, 0x71, 0x7b, 0x1a, 0x78, 0x37, 0xcd, 0x7d, 0x44, 0xc2, 0x14,
+       0x94, 0x0f, 0x0e, 0x1a, 0x9c, 0x43, 0x7b, 0xb1, 0x22, 0x6f, 0x23, 0x6f,
+       0xd8, 0x38, 0x6d, 0xe8, 0x94, 0xa3, 0x39, 0x57, 0x0f, 0x0a, 0x9d, 0xf2,
+       0xb3, 0xe5, 0x1a, 0x40, 0xa4, 0x9d, 0x75, 0xf4, 0xe0, 0xc2, 0xfe, 0xd3,
+       0x80, 0xb3, 0xff, 0x34, 0x97, 0x96, 0xf1, 0x04, 0x29, 0xe2, 0xb9, 0x6c,
+       0x38, 0xf4, 0x2e, 0xec, 0x21, 0xd9, 0xd4, 0x12, 0x2e, 0x99, 0xf7, 0x65,
+       0x78, 0x5f, 0x4a, 0xef, 0x59, 0x21, 0x6b, 0x46, 0x51, 0xb4, 0xf4, 0xbd,
+       0x8d, 0xf2, 0x26, 0x05, 0x5a, 0xe8, 0x35, 0x44, 0xa2, 0x5d, 0xbc, 0xf7,
+       0x50, 0xaa, 0xe4, 0xee, 0x95, 0x0b, 0xb9, 0x5b, 0xcf, 0x7b, 0x45, 0x78,
+       0x4c, 0x42, 0x6e, 0xc6, 0xb6, 0x24, 0xb2, 0xdf, 0x19, 0x9a, 0xf3, 0x07,
+       0xd9, 0x21, 0x64, 0x63, 0xb6, 0x7d, 0x4b, 0x5c, 0xef, 0x6f, 0x94, 0xf1,
+       0xfb, 0x94, 0xc9, 0x41, 0x36, 0x9f, 0x22, 0x5f, 0x0b, 0xed, 0x68, 0xb7,
+       0xec, 0x2a, 0xa7, 0xae, 0xe0, 0xbe, 0x64, 0xb7, 0x68, 0x2d, 0xf4, 0x8a,
+       0x55, 0x84, 0xdd, 0x42, 0xc7, 0xb6, 0x88, 0xe6, 0xa3, 0x15, 0xec, 0x16,
+       0x29, 0x7c, 0xd6, 0x3b, 0xbd, 0x31, 0x6d, 0x23, 0x4d, 0x7c, 0x3d, 0xf1,
+       0x6b, 0x7c, 0xb1, 0x2e, 0x06, 0x70, 0x55, 0x3b, 0xfb, 0xe2, 0x83, 0x38,
+       0x96, 0x66, 0x3b, 0x1f, 0xc0, 0x6e, 0x92, 0xcf, 0xea, 0x11, 0xde, 0x07,
+       0xd3, 0x4e, 0x0f, 0x23, 0xdc, 0xff, 0xaa, 0xd0, 0xca, 0x05, 0xb4, 0x18,
+       0xb5, 0x32, 0xc7, 0x57, 0x6d, 0xb0, 0x59, 0xae, 0xd0, 0x9f, 0xc8, 0x83,
+       0xe2, 0x69, 0x85, 0x87, 0x6b, 0xf2, 0x2b, 0xc8, 0x56, 0x2d, 0xcf, 0xc5,
+       0x78, 0xcb, 0x40, 0x0d, 0x36, 0x8a, 0x0f, 0x66, 0x43, 0xf0, 0x1e, 0x4a,
+       0x2e, 0xf5, 0xa3, 0x53, 0xbc, 0xeb, 0xd4, 0x8b, 0x5d, 0xe2, 0x7c, 0xbe,
+       0x47, 0xbc, 0x9f, 0xeb, 0x46, 0x64, 0xec, 0x1e, 0xf1, 0x4e, 0x8e, 0xe9,
+       0xec, 0x13, 0x67, 0x67, 0xb9, 0x3f, 0x6a, 0x63, 0xb7, 0xc1, 0xbd, 0xd1,
+       0xa5, 0xd5, 0xf0, 0xdb, 0x38, 0x66, 0xb0, 0x3e, 0xb9, 0x4f, 0x58, 0xe9,
+       0x2f, 0x6d, 0x8c, 0x8f, 0xda, 0x2e, 0x9d, 0x7b, 0xc4, 0x41, 0x87, 0xdf,
+       0x19, 0xc2, 0xd1, 0xb3, 0xb9, 0x5e, 0x71, 0x3c, 0x5f, 0xe1, 0x75, 0x3a,
+       0xcf, 0xf6, 0xab, 0x90, 0x8e, 0xbf, 0x98, 0xa7, 0x2d, 0xa8, 0xed, 0x41,
+       0x54, 0x39, 0xfd, 0x28, 0x1b, 0xe3, 0x46, 0x24, 0xf4, 0x32, 0x82, 0x70,
+       0x15, 0xd9, 0xb6, 0x6d, 0x3c, 0x65, 0xb8, 0x21, 0x8f, 0x2b, 0x24, 0x23,
+       0xb2, 0x25, 0xbf, 0x1b, 0xd2, 0x34, 0xd7, 0x06, 0xeb, 0xab, 0xb9, 0x4f,
+       0x11, 0x92, 0xf8, 0xff, 0x2f, 0xda, 0x9c, 0x9b, 0xf2, 0x01, 0xf7, 0xd5,
+       0xdf, 0xac, 0xaa, 0xd8, 0x5e, 0xa5, 0xb7, 0xeb, 0x31, 0xb9, 0xf7, 0xed,
+       0xac, 0xe7, 0x59, 0xd9, 0xee, 0xc1, 0x3b, 0xa3, 0x55, 0xdc, 0xa2, 0x50,
+       0x6a, 0x28, 0xbe, 0xdd, 0x7d, 0xc8, 0xa6, 0xdc, 0x02, 0x4f, 0xb4, 0xfd,
+       0x4d, 0xfb, 0x00, 0xe5, 0x1d, 0xb7, 0x9e, 0xa0, 0x7c, 0xc5, 0x7b, 0x2d,
+       0xb7, 0x62, 0x7e, 0xd2, 0x25, 0xa9, 0x26, 0xe2, 0x14, 0xf3, 0xec, 0xba,
+       0x35, 0x91, 0x81, 0x8f, 0xc9, 0x36, 0x32, 0xc4, 0xd3, 0x07, 0xa3, 0x21,
+       0xe4, 0xa9, 0x0e, 0xb3, 0x9c, 0x9a, 0xe3, 0xb7, 0x71, 0x6e, 0x54, 0x16,
+       0x3e, 0x13, 0xf2, 0x70, 0xbb, 0x8d, 0x21, 0x23, 0x72, 0xfa, 0x2d, 0x59,
+       0xa1, 0x79, 0x5c, 0x78, 0x34, 0x5f, 0x0f, 0x3f, 0xc5, 0x52, 0x69, 0x6c,
+       0x38, 0xe5, 0xa6, 0xb8, 0xf9, 0xe3, 0xd8, 0x70, 0x50, 0xa5, 0xeb, 0x6d,
+       0x06, 0x4e, 0x11, 0xb4, 0xf9, 0xd1, 0x72, 0xf0, 0x1e, 0x60, 0x64, 0xe0,
+       0xbd, 0x4a, 0xbc, 0xb4, 0x5e, 0x13, 0x6f, 0xda, 0xa3, 0xf9, 0x06, 0xc8,
+       0x63, 0x71, 0x7c, 0x92, 0xf6, 0x89, 0xf5, 0x23, 0xbc, 0xd7, 0xa7, 0x95,
+       0xbb, 0x11, 0x1e, 0x58, 0x2f, 0x63, 0x28, 0x88, 0x48, 0xdf, 0x79, 0xaa,
+       0x03, 0x5f, 0x8a, 0x59, 0xfd, 0x3e, 0x8a, 0xb7, 0xdb, 0x09, 0x6b, 0x3e,
+       0x2e, 0x42, 0x94, 0x9f, 0x58, 0x5e, 0x51, 0xa8, 0x11, 0x85, 0xe4, 0xc8,
+       0xfb, 0x41, 0x16, 0xde, 0x76, 0x64, 0xe6, 0xc1, 0xde, 0x1c, 0xd9, 0x89,
+       0xf4, 0xc5, 0xbe, 0xfd, 0x1f, 0x55, 0xc3, 0xdb, 0xc0, 0x72, 0x5a, 0xe8,
+       0xfb, 0x2d, 0xe2, 0x7d, 0x96, 0x11, 0x63, 0xfe, 0x4a, 0x3d, 0x50, 0x65,
+       0xd6, 0x88, 0x17, 0x46, 0x59, 0x2f, 0x36, 0x9e, 0x36, 0x0c, 0xa6, 0x85,
+       0xea, 0xd6, 0xdf, 0x27, 0x8c, 0xaf, 0x59, 0x0c, 0x95, 0x5f, 0x8a, 0x2b,
+       0x38, 0x31, 0x8a, 0xdf, 0x52, 0x20, 0x37, 0x57, 0xe3, 0x08, 0x15, 0x13,
+       0x2c, 0x3f, 0xb6, 0x37, 0xa3, 0x23, 0x92, 0x83, 0x55, 0x6b, 0x76, 0x21,
+       0xe7, 0xd8, 0x79, 0x8d, 0xb8, 0x9f, 0x64, 0x16, 0x69, 0x23, 0x8c, 0xa9,
+       0x72, 0x2f, 0xc5, 0xa2, 0x58, 0xaf, 0xe0, 0xb6, 0x51, 0xbc, 0xbe, 0x1c,
+       0xf2, 0xa9, 0x46, 0x1c, 0x03, 0xaa, 0x59, 0x9f, 0xfc, 0x3e, 0xe9, 0xce,
+       0xcf, 0xb8, 0x8e, 0xc7, 0xd5, 0x88, 0x1d, 0x63, 0x49, 0x6c, 0x8e, 0xc9,
+       0x84, 0x93, 0xfb, 0x08, 0xbf, 0xf5, 0x11, 0x3e, 0xb5, 0xed, 0xb1, 0x08,
+       0xeb, 0x94, 0x75, 0x66, 0x79, 0xc3, 0xed, 0xad, 0xb8, 0x77, 0xb2, 0x1e,
+       0xae, 0xb1, 0x06, 0x54, 0x8f, 0x05, 0xb1, 0x9d, 0xe8, 0x3d, 0x62, 0x70,
+       0xbf, 0xcd, 0x3a, 0x2d, 0x41, 0x2b, 0xaf, 0x97, 0xb5, 0x7e, 0x55, 0xb6,
+       0xf1, 0xa4, 0xa1, 0x19, 0x4f, 0x0a, 0x2f, 0xde, 0xa0, 0x5a, 0xf0, 0xe3,
+       0xd8, 0xad, 0xc8, 0xcc, 0x31, 0x9d, 0xcd, 0x1d, 0x57, 0xcf, 0xf2, 0x35,
+       0xda, 0xd1, 0xec, 0x5c, 0x57, 0x2d, 0x5c, 0x43, 0x1d, 0x21, 0xe7, 0xda,
+       0x44, 0xd7, 0xc5, 0x1e, 0xef, 0x7f, 0x74, 0xf3, 0x35, 0x09, 0xfe, 0x9c,
+       0x76, 0x57, 0x6c, 0xf0, 0xdf, 0xc0, 0x72, 0xfa, 0x0f, 0x1f, 0x2d, 0x8c,
+       0x81, 0x52, 0x4f, 0xbc, 0xc7, 0xc6, 0x65, 0xc4, 0xdb, 0xa8, 0xf8, 0x6d,
+       0x60, 0x7d, 0xf4, 0x21, 0x43, 0x71, 0xaf, 0x96, 0xe2, 0xde, 0xf1, 0x76,
+       0x81, 0x1f, 0x45, 0x4c, 0xfc, 0x28, 0xcf, 0x71, 0xd0, 0x85, 0x27, 0xd2,
+       0x5a, 0xc8, 0x12, 0xe1, 0x9e, 0x9d, 0x42, 0x42, 0xb2, 0x91, 0x78, 0xa3,
+       0x98, 0x3c, 0x9b, 0xe6, 0x18, 0xec, 0x72, 0xf6, 0xd8, 0xb9, 0xde, 0x48,
+       0x2c, 0xc4, 0xcc, 0x52, 0x5c, 0xb3, 0xfa, 0x28, 0x37, 0x7c, 0x5c, 0xe0,
+       0x39, 0x2d, 0xbc, 0x15, 0x67, 0x79, 0x69, 0xd1, 0x94, 0x74, 0x37, 0x92,
+       0x39, 0xf6, 0x4b, 0x5a, 0x8e, 0xd6, 0x3a, 0x92, 0xad, 0x42, 0x6f, 0xbc,
+       0x5b, 0xdc, 0x56, 0xbc, 0x85, 0xfb, 0xf9, 0xea, 0x12, 0x73, 0x8b, 0xd8,
+       0x30, 0xcd, 0xfd, 0xb8, 0x5e, 0xd1, 0x5b, 0x64, 0x3f, 0x19, 0x14, 0xbf,
+       0x53, 0xbc, 0xbc, 0x37, 0xb7, 0x68, 0x17, 0xdc, 0x93, 0xb3, 0x3c, 0x2f,
+       0x90, 0x5e, 0xee, 0x1f, 0xc5, 0x1f, 0xd7, 0x43, 0xa6, 0x98, 0xd6, 0x8e,
+       0x72, 0xa5, 0xf6, 0xa1, 0xfb, 0x5f, 0xc1, 0x10, 0xe5, 0x57, 0x69, 0x41,
+       0xbf, 0x2b, 0x72, 0x12, 0x3e, 0x59, 0xb3, 0xdf, 0x0e, 0x2d, 0x61, 0xfd,
+       0x12, 0x6e, 0x24, 0xdd, 0xec, 0xce, 0xee, 0xb1, 0xdf, 0x76, 0x7a, 0x6a,
+       0x6c, 0x8f, 0x4e, 0xc9, 0xc4, 0xba, 0xc6, 0x76, 0xf2, 0xb9, 0xc7, 0x47,
+       0x97, 0x41, 0xd1, 0xb9, 0x17, 0x5f, 0x8b, 0xa8, 0xe3, 0x37, 0x1e, 0x14,
+       0x46, 0x19, 0xaf, 0x18, 0x1d, 0xaf, 0x8f, 0x29, 0xf0, 0xd1, 0xb3, 0xd9,
+       0x98, 0xc0, 0xa9, 0xf6, 0xca, 0xfc, 0xcd, 0xb9, 0xab, 0x91, 0x56, 0xbd,
+       0xa8, 0xd3, 0x9b, 0x91, 0x55, 0x7d, 0xb4, 0xee, 0xad, 0x0b, 0x73, 0xfe,
+       0xb8, 0x9a, 0xeb, 0x56, 0xd9, 0xbc, 0xb7, 0xba, 0xa2, 0x0f, 0x45, 0xa9,
+       0xd4, 0x31, 0x8a, 0xe5, 0xa3, 0xb5, 0x0e, 0xb6, 0xf7, 0x62, 0xc7, 0x88,
+       0x4f, 0xbc, 0x92, 0xfe, 0xd7, 0x36, 0xdb, 0xcc, 0x01, 0xb2, 0xe5, 0x2a,
+       0x7d, 0x71, 0xce, 0xd7, 0x9d, 0x77, 0x6b, 0x29, 0x2e, 0x0f, 0x8c, 0x4a,
+       0x08, 0x2c, 0xdc, 0x8f, 0xe7, 0x42, 0x08, 0xb6, 0x09, 0xfa, 0xde, 0x6b,
+       0xe3, 0x0a, 0x05, 0xaa, 0xfe, 0x06, 0x8d, 0x73, 0xd1, 0x55, 0xa1, 0xfa,
+       0xd8, 0xc2, 0xc3, 0xf1, 0x04, 0x2e, 0x10, 0x06, 0xd9, 0x47, 0xf9, 0x72,
+       0x57, 0xda, 0xc4, 0xb9, 0xfc, 0x5f, 0x3b, 0xf3, 0xd4, 0x98, 0x1e, 0x4c,
+       0xe7, 0xbe, 0x48, 0x57, 0x80, 0x68, 0x7d, 0x98, 0x68, 0xe2, 0x67, 0x17,
+       0x9c, 0xda, 0xfa, 0xf9, 0xcb, 0x6a, 0x12, 0x69, 0x9c, 0xfb, 0x31, 0x95,
+       0x38, 0xda, 0x69, 0x28, 0x16, 0xf7, 0xb6, 0xe7, 0x27, 0x2c, 0x9c, 0xbb,
+       0xb6, 0x0e, 0x9f, 0x4c, 0x34, 0xe3, 0xde, 0x51, 0x2f, 0x2e, 0x4e, 0xd8,
+       0xb8, 0x66, 0x0d, 0xee, 0x08, 0x12, 0x8e, 0xa9, 0xa3, 0x78, 0xf1, 0x1a,
+       0xd5, 0x0d, 0x54, 0x53, 0x92, 0xf7, 0x44, 0x12, 0x1b, 0x85, 0x8d, 0x68,
+       0x0c, 0xa9, 0x1b, 0xe2, 0x91, 0xd0, 0x05, 0x7c, 0xc7, 0x26, 0x7d, 0xa8,
+       0xb2, 0xd9, 0x2d, 0x5c, 0xce, 0xde, 0x5c, 0xaf, 0xb3, 0x97, 0x27, 0x4d,
+       0x0f, 0x0a, 0xb9, 0x78, 0xb9, 0xbf, 0x7f, 0x59, 0x0c, 0xe7, 0xb8, 0xcd,
+       0xf5, 0xff, 0xb8, 0xed, 0xd6, 0xb9, 0xcf, 0xb1, 0x45, 0xec, 0xc9, 0x5d,
+       0x8a, 0xeb, 0x97, 0x62, 0xf9, 0xae, 0x85, 0x18, 0x3e, 0x9c, 0x7f, 0xf3,
+       0x0b, 0x18, 0x24, 0xb4, 0xb0, 0x57, 0xc0, 0xb1, 0xdb, 0x23, 0xde, 0x22,
+       0xbf, 0xdb, 0x6b, 0xb0, 0x9f, 0x9d, 0x0c, 0x52, 0x74, 0x85, 0x8b, 0xe4,
+       0x79, 0x3f, 0x9f, 0xcf, 0x08, 0xd8, 0xd8, 0x42, 0x7c, 0x7a, 0x48, 0x8e,
+       0x6b, 0xda, 0xdd, 0xe8, 0xa7, 0x78, 0xee, 0x8e, 0xf9, 0x28, 0x0e, 0xa8,
+       0x78, 0xd5, 0x60, 0x1b, 0xee, 0x59, 0x88, 0xe7, 0xbc, 0x57, 0x55, 0xd9,
+       0x1f, 0xfe, 0x7c, 0xcf, 0x78, 0xd1, 0x36, 0x0d, 0x24, 0x97, 0xc2, 0xfb,
+       0x4e, 0x5c, 0x27, 0xec, 0xad, 0x10, 0xee, 0xde, 0x84, 0xc4, 0x12, 0x8d,
+       0xdb, 0x02, 0x84, 0x5b, 0x2d, 0xfc, 0xd7, 0xf6, 0x7e, 0xdc, 0x33, 0x2e,
+       0xa1, 0x46, 0xe7, 0x3d, 0x1a, 0xb2, 0x83, 0x7a, 0x8e, 0x5f, 0xdd, 0x18,
+       0x1a, 0xf7, 0x88, 0x17, 0xa9, 0x26, 0x39, 0xd2, 0xf3, 0x10, 0x96, 0xb4,
+       0xdd, 0x09, 0x38, 0xb6, 0xc7, 0xff, 0x7f, 0x0b, 0xa9, 0x65, 0xbc, 0x3e,
+       0xf7, 0xa9, 0x04, 0x7c, 0x6d, 0xcc, 0x07, 0xbc, 0xef, 0xd1, 0xfc, 0xdb,
+       0x47, 0x5c, 0xe2, 0x42, 0xfa, 0xa7, 0xf6, 0x89, 0x00, 0xe7, 0x58, 0x7e,
+       0x56, 0x4b, 0xb1, 0x9e, 0xc7, 0xb2, 0x0e, 0x7d, 0x54, 0xd7, 0xf5, 0x63,
+       0x84, 0xe8, 0x3a, 0xe3, 0xcc, 0xf5, 0xbd, 0x05, 0xfa, 0x7d, 0xa2, 0x2e,
+       0xa3, 0x58, 0x41, 0xa2, 0x45, 0xbd, 0xb6, 0x07, 0x75, 0xc5, 0xcb, 0x73,
+       0xd5, 0x5f, 0x29, 0xdc, 0xeb, 0x63, 0xdf, 0xa9, 0x26, 0x5f, 0xf9, 0x79,
+       0x5a, 0xe0, 0xbc, 0x63, 0x7b, 0xdb, 0xd0, 0x9c, 0xa7, 0x1a, 0xda, 0x89,
+       0x21, 0x3c, 0x6e, 0x7d, 0xc5, 0xa6, 0xa5, 0x7e, 0xdc, 0x47, 0xbc, 0xd4,
+       0x12, 0x2f, 0x1f, 0xc6, 0x56, 0xd0, 0x3a, 0x7c, 0x2f, 0xa3, 0x54, 0xec,
+       0x6c, 0x71, 0x2e, 0x2a, 0xc0, 0xfd, 0x5c, 0x2b, 0x45, 0xb0, 0x73, 0x3c,
+       0xd2, 0xe7, 0x93, 0xd8, 0x0e, 0x23, 0xb8, 0x7b, 0xfa, 0x37, 0x3c, 0x54,
+       0x17, 0xd3, 0x5c, 0x41, 0xdc, 0x9e, 0x71, 0x89, 0xb7, 0xa9, 0xd6, 0x78,
+       0x3e, 0x2d, 0x2d, 0x93, 0xf1, 0xac, 0x7d, 0x24, 0x30, 0x84, 0x1b, 0x8c,
+       0x6e, 0xdc, 0x45, 0x36, 0xd8, 0xd9, 0x3c, 0x84, 0x09, 0xb2, 0x81, 0xed,
+       0x0d, 0x54, 0xff, 0xc4, 0x4a, 0xf6, 0xb6, 0x00, 0xcb, 0x51, 0xa0, 0x8b,
+       0xee, 0xd7, 0x53, 0x4d, 0x24, 0xc5, 0xc8, 0xda, 0x1a, 0x04, 0xf9, 0xac,
+       0x36, 0x9a, 0xc4, 0xcf, 0x9d, 0x35, 0xeb, 0xf5, 0xc5, 0xf8, 0xcc, 0x39,
+       0xf6, 0x8b, 0xf4, 0x58, 0x76, 0xb5, 0xae, 0x47, 0x37, 0x49, 0xcd, 0xa3,
+       0x73, 0x64, 0xb3, 0x1b, 0xda, 0x2e, 0x7f, 0x6f, 0x51, 0x46, 0x06, 0xaa,
+       0xda, 0x66, 0xec, 0xb2, 0x3a, 0x0c, 0xb5, 0xed, 0x72, 0xdd, 0x2f, 0xce,
+       0xc1, 0x34, 0x57, 0xe2, 0x5a, 0x48, 0x8a, 0xa8, 0x77, 0xe0, 0x49, 0x5a,
+       0x23, 0x88, 0xad, 0xc5, 0x6e, 0x6c, 0x1b, 0x97, 0x3f, 0xcb, 0xed, 0x7e,
+       0xb6, 0xe5, 0xcf, 0xf8, 0xdf, 0x31, 0x1e, 0xe9, 0xf2, 0x2e, 0xf0, 0x7f,
+       0xd7, 0xf4, 0x67, 0x73, 0x0d, 0x66, 0x38, 0x86, 0xf2, 0x7c, 0x9c, 0x67,
+       0x17, 0xe5, 0x1b, 0xc4, 0x7d, 0xce, 0x7c, 0x5b, 0x3d, 0xec, 0xe3, 0x6e,
+       0xca, 0x95, 0x1b, 0xdb, 0x2c, 0xbc, 0x9a, 0xb8, 0xd7, 0xde, 0xe1, 0xc8,
+       0xa0, 0xc3, 0xc3, 0xef, 0x77, 0x35, 0x9f, 0x5e, 0xd8, 0x43, 0xaf, 0xf4,
+       0x30, 0x9f, 0x2f, 0xb5, 0x3a, 0xfd, 0xf9, 0xef, 0x51, 0x7e, 0x7c, 0xf6,
+       0x73, 0x3d, 0xb2, 0x3b, 0xdd, 0xdc, 0xd7, 0x7f, 0xaa, 0xa4, 0x08, 0xd7,
+       0x78, 0x8d, 0x70, 0x8f, 0x33, 0x6d, 0xff, 0x45, 0xa9, 0xf8, 0xd8, 0x5f,
+       0x23, 0x19, 0xe0, 0x3d, 0xba, 0x8a, 0xfd, 0x47, 0xdb, 0xef, 0x06, 0x8e,
+       0x5a, 0x9e, 0xea, 0xb5, 0xa0, 0x3a, 0xb9, 0xc7, 0xb1, 0x87, 0xa5, 0x66,
+       0x7c, 0xdd, 0xb3, 0xcd, 0x5c, 0x2b, 0x73, 0x5f, 0xad, 0x73, 0xdd, 0x24,
+       0x81, 0xb7, 0xad, 0x2a, 0xaf, 0xa9, 0x9d, 0xe0, 0x5e, 0x37, 0xf7, 0xc0,
+       0x97, 0xeb, 0xf0, 0xd6, 0xaf, 0xb5, 0x3c, 0x4b, 0xd6, 0xba, 0xc4, 0x15,
+       0x99, 0x3e, 0xb2, 0x3d, 0x1d, 0x89, 0x8c, 0xe5, 0x6d, 0x5c, 0x1b, 0xc2,
+       0x03, 0x99, 0x4a, 0x0c, 0x5b, 0x9f, 0x6b, 0x45, 0xeb, 0x14, 0x59, 0x63,
+       0x26, 0x88, 0x96, 0x89, 0xf0, 0xc0, 0xd7, 0xa5, 0xf0, 0xe0, 0xbc, 0xc4,
+       0xcf, 0x7c, 0x1d, 0xd7, 0x38, 0x38, 0x56, 0xed, 0x58, 0xed, 0x5c, 0xe3,
+       0x1d, 0x57, 0xe7, 0x6f, 0x45, 0x7a, 0xce, 0x33, 0x5f, 0x96, 0x6c, 0x3c,
+       0x10, 0x93, 0x70, 0xa3, 0xf1, 0x9f, 0xc9, 0xb7, 0x04, 0xd9, 0xc6, 0xab,
+       0x9c, 0x9f, 0x9d, 0xe0, 0xbc, 0x7c, 0xad, 0x8e, 0xb5, 0x99, 0x7a, 0x8a,
+       0x49, 0x0d, 0x14, 0x9f, 0xea, 0xf1, 0x11, 0xc5, 0xa4, 0xd5, 0x6b, 0x28,
+       0x3c, 0xae, 0xb1, 0xfa, 0xaf, 0x00, 0xef, 0xdf, 0x6a, 0x56, 0x51, 0x68,
+       0x7d, 0xdd, 0x92, 0xd6, 0xd3, 0x20, 0xa9, 0xb8, 0x2b, 0xc2, 0x73, 0x27,
+       0x3a, 0xd6, 0xe6, 0x2b, 0xf9, 0x74, 0x95, 0x93, 0x3f, 0xf5, 0x8e, 0xab,
+       0x66, 0x2b, 0x79, 0xd6, 0x98, 0xd5, 0x7e, 0x90, 0x92, 0x78, 0xcf, 0xa1,
+       0x0f, 0xe3, 0xd9, 0x14, 0xf6, 0x64, 0x43, 0xf8, 0x45, 0xa6, 0x8a, 0x6c,
+       0x23, 0x6c, 0x7c, 0x17, 0x3c, 0xa6, 0xb5, 0x23, 0x96, 0x0f, 0x47, 0x1f,
+       0x90, 0xfe, 0x1c, 0x65, 0x97, 0x76, 0x98, 0x10, 0x36, 0x72, 0xae, 0x96,
+       0xd0, 0x4b, 0xf8, 0x73, 0x67, 0x8f, 0x0a, 0xa8, 0xf0, 0xd0, 0x9c, 0x07,
+       0x46, 0x33, 0x9e, 0x79, 0x38, 0xfd, 0x4c, 0xde, 0x73, 0x95, 0xb0, 0xc1,
+       0xb8, 0x97, 0xe4, 0x2c, 0xd0, 0xdc, 0x56, 0x8f, 0x72, 0xaf, 0x0b, 0xe3,
+       0x24, 0x13, 0xc5, 0x0c, 0x74, 0x28, 0x23, 0x28, 0x2f, 0xec, 0x27, 0x26,
+       0x64, 0xca, 0xd0, 0x2f, 0x17, 0x81, 0x03, 0x14, 0x3b, 0x36, 0xc7, 0x7e,
+       0x45, 0xb9, 0xa1, 0xb2, 0x7f, 0x91, 0x9e, 0x14, 0x58, 0xa2, 0x27, 0x49,
+       0x1e, 0x2e, 0xff, 0x41, 0xaa, 0xef, 0x0f, 0x96, 0xf8, 0x7d, 0xcf, 0x7c,
+       0xd2, 0x99, 0x3f, 0xb2, 0x6f, 0x85, 0x24, 0xe1, 0xea, 0xb6, 0xa3, 0xc8,
+       0x2d, 0xad, 0xd0, 0x10, 0x24, 0x4c, 0xc0, 0x75, 0x60, 0x03, 0xf1, 0xb8,
+       0xe5, 0x11, 0xee, 0x09, 0x5e, 0xd9, 0x71, 0xdd, 0x14, 0xfb, 0x75, 0xa0,
+       0xe3, 0xe7, 0x69, 0x2d, 0xd9, 0x20, 0x33, 0xae, 0x4c, 0x74, 0xdc, 0x3d,
+       0xc2, 0xb9, 0xad, 0x8d, 0x6b, 0x71, 0xca, 0xcb, 0xda, 0x60, 0xa3, 0xf0,
+       0x89, 0x1b, 0x33, 0x54, 0x8f, 0x13, 0xbd, 0xef, 0x47, 0xb4, 0x20, 0xc9,
+       0xae, 0xeb, 0x4e, 0xd1, 0xcf, 0x78, 0xdf, 0x91, 0xdb, 0x55, 0xf9, 0x0a,
+       0xee, 0x08, 0x2f, 0xe0, 0x90, 0xa8, 0x83, 0x3b, 0x6c, 0x7b, 0x77, 0x8c,
+       0xf3, 0xb8, 0xb3, 0x9f, 0x4e, 0xf7, 0x63, 0x94, 0x77, 0x15, 0x0c, 0x33,
+       0x7d, 0x7c, 0x2e, 0x42, 0xa2, 0x3a, 0x2e, 0x7b, 0x7a, 0x01, 0x97, 0xf8,
+       0xb0, 0x97, 0xee, 0x97, 0x1d, 0x7c, 0xc2, 0x67, 0xfb, 0x56, 0x75, 0xa8,
+       0x8f, 0xf0, 0x79, 0xc0, 0x2b, 0x3b, 0x36, 0x4c, 0x6a, 0x21, 0x89, 0xf8,
+       0xd8, 0xc3, 0x7b, 0xdb, 0x34, 0xe7, 0xac, 0xc1, 0x74, 0xfb, 0x3a, 0xb8,
+       0x97, 0xb9, 0x9c, 0xe8, 0xb6, 0xb3, 0x61, 0xc2, 0x49, 0x15, 0x5b, 0x49,
+       0xe4, 0xa9, 0x22, 0xbe, 0xa2, 0xc2, 0xab, 0x9b, 0x74, 0x72, 0x2c, 0x9d,
+       0xc4, 0xf3, 0xf1, 0x8a, 0x7e, 0xd6, 0xe7, 0xbf, 0x81, 0x54, 0x43, 0x27,
+       0x46, 0xb3, 0xaa, 0x7f, 0x63, 0xa6, 0x13, 0x13, 0xa4, 0xc3, 0x3b, 0x8a,
+       0x41, 0x7f, 0x67, 0x46, 0xc7, 0xb6, 0x22, 0xd7, 0x26, 0xa1, 0x8e, 0xdd,
+       0x93, 0xb9, 0x85, 0x1a, 0xb2, 0x92, 0x4b, 0xf6, 0x67, 0x2a, 0x36, 0x17,
+       0xce, 0x7b, 0xe6, 0x43, 0xa2, 0x32, 0xaf, 0x42, 0xeb, 0x28, 0x23, 0x7f,
+       0x6c, 0x63, 0x29, 0xdb, 0xc2, 0xad, 0x98, 0x9c, 0xf2, 0x5b, 0x57, 0x98,
+       0x2a, 0xd6, 0xb6, 0xbd, 0x41, 0xef, 0xb6, 0xe2, 0x97, 0xc7, 0xbf, 0x86,
+       0xf2, 0x37, 0x5d, 0x78, 0x3c, 0x93, 0x44, 0x4b, 0xdb, 0x4d, 0x48, 0xfd,
+       0xae, 0x82, 0xa7, 0x32, 0x3e, 0x3c, 0x97, 0xa9, 0xec, 0x77, 0x7f, 0x3f,
+       0x4b, 0x7e, 0x48, 0x3e, 0xf0, 0xec, 0x97, 0xee, 0x31, 0x52, 0x3c, 0x97,
+       0x79, 0xff, 0xfb, 0x9f, 0x1e, 0x77, 0xd6, 0x19, 0xe7, 0x11, 0xf5, 0xe3,
+       0x8b, 0xf3, 0xda, 0xd0, 0xdb, 0xfe, 0xb1, 0x77, 0xb4, 0x28, 0x40, 0x31,
+       0xa4, 0x72, 0x3e, 0x40, 0x28, 0xe3, 0xce, 0x9e, 0x0b, 0xe1, 0xdf, 0x88,
+       0x71, 0x0e, 0x16, 0xaa, 0x08, 0x57, 0xad, 0x20, 0x59, 0xe8, 0x99, 0x80,
+       0x5f, 0x2a, 0xaa, 0xf4, 0x69, 0xf2, 0xbb, 0x48, 0x3e, 0xae, 0xe2, 0x0f,
+       0x29, 0xa6, 0xb0, 0x4f, 0x55, 0x72, 0x9c, 0x54, 0xdc, 0xec, 0x85, 0x57,
+       0xa7, 0x6b, 0xc5, 0xa6, 0x43, 0xf9, 0xb7, 0xf9, 0x39, 0xd9, 0x75, 0xe5,
+       0x7b, 0xe4, 0xd2, 0x77, 0xd2, 0xb3, 0x23, 0xb3, 0xdb, 0x68, 0x3c, 0xcb,
+       0xe2, 0x59, 0x3b, 0xb5, 0x85, 0xe5, 0x15, 0xf0, 0xbf, 0x41, 0xf2, 0x9f,
+       0x24, 0x1a, 0xb3, 0xb4, 0xc6, 0xeb, 0xb4, 0x66, 0xa6, 0xd8, 0x47, 0x63,
+       0xf8, 0x19, 0xc9, 0xd9, 0xb1, 0xdd, 0xad, 0x5e, 0xde, 0xdb, 0x7f, 0x2e,
+       0x03, 0xaa, 0xbb, 0x2d, 0xcd, 0xb5, 0x70, 0x16, 0x72, 0x18, 0x8b, 0xf8,
+       0xf1, 0x2e, 0x5c, 0x3f, 0xaa, 0x25, 0x2d, 0xc2, 0x61, 0x29, 0x15, 0xc2,
+       0x65, 0xb2, 0x0d, 0xc7, 0xc9, 0x86, 0x9b, 0x88, 0xa7, 0x70, 0xe8, 0x1c,
+       0x8d, 0xb7, 0x5c, 0x0a, 0xf6, 0x4f, 0xc8, 0x38, 0xc7, 0xfb, 0xaf, 0xa2,
+       0xf2, 0x3e, 0x01, 0x7f, 0x1a, 0xbb, 0xf8, 0x7f, 0x0d, 0xe1, 0xf2, 0x70,
+       0x82, 0xb2, 0x2a, 0xe3, 0x5b, 0x4f, 0xbe, 0xfd, 0x21, 0x1c, 0xa4, 0x3a,
+       0x79, 0x47, 0x2c, 0x84, 0x64, 0x7d, 0x1c, 0x1e, 0xbd, 0x65, 0xe0, 0x22,
+       0xfe, 0x87, 0x5d, 0xe6, 0x3d, 0x6c, 0x11, 0x4e, 0x5c, 0xc4, 0xa7, 0xb6,
+       0xac, 0xeb, 0xa7, 0x67, 0xa0, 0x97, 0xcf, 0xa1, 0x65, 0xf0, 0x13, 0xbc,
+       0x6b, 0xf3, 0xfe, 0xb6, 0x22, 0xcb, 0x78, 0xd1, 0x08, 0xab, 0x2e, 0x04,
+       0x50, 0x0e, 0xc8, 0xd8, 0x6c, 0x30, 0xfe, 0xd7, 0x06, 0x1f, 0x83, 0x36,
+       0x70, 0x5e, 0xb4, 0xf4, 0x7f, 0x88, 0xb3, 0x76, 0xae, 0x9e, 0xd7, 0x15,
+       0x48, 0x5c, 0xdd, 0x72, 0xba, 0x0a, 0x5a, 0x97, 0x5b, 0xe8, 0x89, 0x46,
+       0xf9, 0xaf, 0xec, 0xb3, 0x81, 0x4f, 0x6d, 0x3d, 0xf2, 0x29, 0xe1, 0x20,
+       0x3d, 0x38, 0x4d, 0xb6, 0xdf, 0x8f, 0x45, 0xda, 0x5e, 0x27, 0xfe, 0xa9,
+       0xb0, 0xd3, 0x79, 0x9f, 0xc8, 0xf2, 0xec, 0x25, 0xda, 0x5e, 0x23, 0x1c,
+       0xb0, 0x23, 0x76, 0xd1, 0x4e, 0x2e, 0xe5, 0x1a, 0xe9, 0x67, 0xde, 0x4a,
+       0xff, 0x98, 0x7b, 0x0e, 0xb7, 0xe2, 0x76, 0xc2, 0x77, 0xc3, 0xd9, 0x45,
+       0xbc, 0xe6, 0xa6, 0x18, 0xcc, 0xb1, 0xbf, 0x7c, 0x15, 0x95, 0xd4, 0x12,
+       0x95, 0xc7, 0xd8, 0x4d, 0x71, 0x61, 0x97, 0x93, 0x0b, 0xe0, 0x5d, 0xbe,
+       0xb6, 0x0d, 0x9f, 0x4c, 0x95, 0xbc, 0xe4, 0x4b, 0xeb, 0xf5, 0x35, 0x10,
+       0xc1, 0x8c, 0x25, 0xea, 0x4c, 0x19, 0x1f, 0xb6, 0x6b, 0x5d, 0x92, 0x3c,
+       0x88, 0xab, 0x63, 0x96, 0xed, 0xd3, 0xf5, 0xbe, 0x56, 0x11, 0xe9, 0x29,
+       0x8a, 0x28, 0x6a, 0x8a, 0x3e, 0xa5, 0xa6, 0xd8, 0xaa, 0x78, 0x8b, 0x96,
+       0x47, 0x5d, 0x7b, 0x17, 0xd5, 0xb4, 0x43, 0x58, 0x19, 0xf3, 0x51, 0x3d,
+       0xac, 0x19, 0x17, 0x50, 0x45, 0xf2, 0x0f, 0x61, 0x6f, 0xc9, 0x84, 0x2b,
+       0xb3, 0x13, 0xee, 0x4c, 0x58, 0xdd, 0x83, 0x21, 0x24, 0x83, 0x15, 0x4c,
+       0xab, 0x90, 0xae, 0xaa, 0xdb, 0x19, 0xcb, 0xdc, 0x85, 0xb3, 0x39, 0xc6,
+       0xe7, 0x54, 0x9f, 0xa6, 0xf9, 0x3b, 0xbc, 0x2f, 0xc5, 0x4d, 0x3c, 0x49,
+       0x75, 0x95, 0xa7, 0xad, 0x91, 0xf4, 0xd0, 0x84, 0xe1, 0x92, 0x60, 0xb3,
+       0x22, 0x5d, 0xc0, 0xfb, 0x64, 0xbb, 0x82, 0x03, 0x33, 0x94, 0x48, 0x28,
+       0x5f, 0xb9, 0x32, 0x2a, 0xc5, 0x09, 0xc6, 0xd8, 0x3e, 0xfa, 0x1e, 0xe0,
+       0x33, 0x3f, 0x64, 0x67, 0x57, 0x76, 0xb4, 0x3a, 0xb1, 0xa6, 0x8d, 0x6a,
+       0x9c, 0xa7, 0xbd, 0x95, 0x9a, 0xcb, 0x44, 0xcd, 0xf8, 0x62, 0xad, 0xb8,
+       0xe1, 0xe6, 0x1a, 0xaa, 0xc5, 0x87, 0x4b, 0x8c, 0x03, 0x2b, 0x67, 0x3c,
+       0x37, 0xc4, 0xda, 0x08, 0xb3, 0x8b, 0x05, 0x8c, 0x35, 0xac, 0xf9, 0xb0,
+       0x1e, 0x07, 0xa9, 0x56, 0xf6, 0xeb, 0x5b, 0x91, 0x51, 0xcb, 0xde, 0x37,
+       0xe3, 0x8c, 0x7f, 0xe1, 0xdd, 0x46, 0x18, 0x6a, 0x24, 0xfd, 0x55, 0x8e,
+       0x99, 0x9e, 0x3b, 0xe2, 0x06, 0x0e, 0x8f, 0x52, 0x88, 0xd2, 0xd7, 0xa3,
+       0x6e, 0x4d, 0x37, 0x3e, 0xac, 0x67, 0xfc, 0x4b, 0xb1, 0x8a, 0xe8, 0xd9,
+       0x33, 0x13, 0x70, 0xce, 0x24, 0xec, 0x2d, 0x2d, 0xd2, 0x7c, 0x39, 0xad,
+       0x5f, 0x46, 0x23, 0xcb, 0xe4, 0x9f, 0xa2, 0x91, 0x6c, 0x96, 0x30, 0xcf,
+       0x68, 0x7a, 0x1b, 0x5e, 0x4e, 0xf3, 0xbc, 0xe1, 0xa4, 0x21, 0x54, 0xee,
+       0x6b, 0x3b, 0x32, 0xb1, 0x66, 0x78, 0x0d, 0x5e, 0x7f, 0x71, 0x9d, 0x00,
+       0xf6, 0x7d, 0xa9, 0x3c, 0xfe, 0x39, 0x6b, 0x51, 0xdc, 0x18, 0x5d, 0x4f,
+       0x75, 0x50, 0x14, 0xfa, 0xef, 0x94, 0x49, 0x1f, 0xdc, 0xe7, 0x5d, 0x41,
+       0x98, 0x17, 0x9e, 0x57, 0xe2, 0x7c, 0xee, 0xd7, 0x1e, 0x52, 0x4c, 0xdb,
+       0x76, 0xb7, 0xeb, 0xea, 0x3b, 0x60, 0x3b, 0xf4, 0xf1, 0x7e, 0x81, 0x67,
+       0x4f, 0xbb, 0x0f, 0x07, 0x28, 0x07, 0x3e, 0x91, 0x6e, 0xb1, 0x6e, 0x12,
+       0x7c, 0x7e, 0x89, 0x62, 0xb6, 0x48, 0xd1, 0xbb, 0x37, 0xd6, 0xb0, 0xcf,
+       0xee, 0x2e, 0xed, 0x84, 0x94, 0x89, 0xd4, 0x70, 0x3d, 0x51, 0x45, 0x35,
+       0xf4, 0x70, 0x9a, 0xe9, 0xb5, 0x87, 0x5c, 0x34, 0xd7, 0xae, 0xb8, 0x3e,
+       0x7f, 0x3d, 0xd9, 0x45, 0xa3, 0xc9, 0x72, 0x0c, 0xe0, 0x08, 0x8d, 0x0d,
+       0x95, 0x58, 0x96, 0x7d, 0x35, 0xdc, 0x33, 0xdc, 0x4b, 0xfa, 0xad, 0xcb,
+       0x56, 0xe6, 0xc9, 0x96, 0xfa, 0xb1, 0x62, 0x64, 0xdc, 0x99, 0x87, 0x7d,
+       0xe0, 0xc5, 0xf8, 0x00, 0xf6, 0xa6, 0x03, 0x98, 0x49, 0xb7, 0xa8, 0x2f,
+       0x38, 0xfb, 0xed, 0x95, 0xfe, 0xd2, 0x70, 0x7a, 0x71, 0x4c, 0x00, 0xd3,
+       0x97, 0xfe, 0x67, 0xf9, 0x54, 0xfa, 0x8e, 0x95, 0x7e, 0x80, 0x82, 0x5c,
+       0xa0, 0x82, 0x87, 0x28, 0x56, 0x78, 0x1f, 0x26, 0xbd, 0x9e, 0x27, 0xbd,
+       0x4a, 0xa4, 0xd7, 0x17, 0x8c, 0xef, 0x33, 0x66, 0xf1, 0xec, 0x8e, 0xfb,
+       0x78, 0x8f, 0xc5, 0x22, 0xd0, 0xe2, 0x8c, 0xc9, 0xc4, 0x5d, 0x38, 0x33,
+       0xc2, 0xe7, 0xf9, 0xd4, 0x8e, 0x53, 0x69, 0x7b, 0xfd, 0x5c, 0xac, 0x25,
+       0x75, 0x9e, 0xf0, 0xb4, 0xf5, 0xbb, 0x9a, 0x71, 0x96, 0xfc, 0x34, 0x3b,
+       0xf1, 0xfb, 0x38, 0x5b, 0xdf, 0xa2, 0xfe, 0x98, 0xca, 0xf9, 0x47, 0xe3,
+       0x0f, 0x21, 0x31, 0x41, 0x75, 0xc3, 0x9a, 0x7f, 0x47, 0x4e, 0x16, 0x87,
+       0xac, 0xb7, 0xcc, 0xbf, 0x80, 0xff, 0x86, 0xb3, 0x57, 0x84, 0x8d, 0x17,
+       0xc0, 0x63, 0x2a, 0xf5, 0x78, 0x78, 0xf6, 0x1e, 0x3e, 0x8b, 0x14, 0xe4,
+       0x5a, 0xdb, 0xd9, 0x0b, 0x4a, 0xf3, 0xde, 0x95, 0x40, 0xae, 0x57, 0x0b,
+       0xa5, 0x9c, 0xb3, 0x9f, 0xf0, 0x3e, 0x46, 0x7e, 0x11, 0x1d, 0xe3, 0xf1,
+       0x81, 0x0e, 0x3d, 0x1f, 0x82, 0x4c, 0x18, 0x27, 0x15, 0xd0, 0xba, 0x80,
+       0xa0, 0xff, 0xb1, 0x74, 0x10, 0xfb, 0xb2, 0x2d, 0x3d, 0x51, 0x71, 0xdb,
+       0xc2, 0x9e, 0x31, 0xe7, 0xb9, 0x00, 0xe5, 0x39, 0x2d, 0xf5, 0x18, 0x5a,
+       0xfa, 0x7c, 0xe2, 0x56, 0xa4, 0xea, 0x5b, 0xfa, 0x9f, 0x44, 0x38, 0xe1,
+       0x11, 0x5a, 0xf4, 0x2c, 0x2a, 0xf3, 0xac, 0xcc, 0xcb, 0x40, 0x03, 0xc7,
+       0x99, 0x34, 0x9e, 0x54, 0x65, 0xac, 0x6a, 0xd3, 0xe7, 0xa7, 0xb1, 0x68,
+       0x2f, 0x95, 0x31, 0xeb, 0xf3, 0x34, 0x5e, 0x56, 0xa9, 0x0e, 0xae, 0x82,
+       0xab, 0x81, 0xf7, 0xe3, 0x76, 0x62, 0x47, 0x9a, 0xf3, 0x34, 0xc9, 0x85,
+       0x7c, 0xb3, 0x27, 0xb2, 0x13, 0x03, 0xf9, 0x00, 0x0e, 0x66, 0xc3, 0xfb,
+       0xf6, 0x10, 0xae, 0x1b, 0x2b, 0x85, 0x43, 0xdb, 0x45, 0x80, 0xf4, 0x2d,
+       0x21, 0xd4, 0x10, 0x44, 0xb5, 0xae, 0xd2, 0xa7, 0x52, 0xcf, 0x9c, 0xa2,
+       0x7a, 0xe6, 0x0c, 0xf9, 0x9a, 0x6f, 0xa1, 0x46, 0x5d, 0x99, 0xb3, 0x31,
+       0x17, 0xdb, 0x84, 0xf7, 0x1d, 0x9d, 0x05, 0xc9, 0xc6, 0x38, 0x17, 0x39,
+       0x35, 0xa8, 0xd8, 0x3e, 0x66, 0x79, 0xee, 0x6f, 0x0f, 0x22, 0x9c, 0x61,
+       0xcc, 0x29, 0x7d, 0x53, 0x26, 0x79, 0xcc, 0xe8, 0x43, 0xd8, 0x18, 0x1b,
+       0xc2, 0x80, 0xf1, 0xc7, 0xa8, 0x6a, 0xe0, 0x78, 0xa4, 0x58, 0x75, 0x34,
+       0xef, 0xc5, 0xf6, 0x6e, 0x84, 0x8f, 0x72, 0x0e, 0x6e, 0xa5, 0x1c, 0xcc,
+       0xbe, 0xcb, 0xf3, 0xdf, 0xdf, 0xb1, 0x9a, 0x70, 0x45, 0x6d, 0x7b, 0x25,
+       0xcf, 0x5f, 0x9d, 0x57, 0xb9, 0x8f, 0x43, 0xb5, 0x29, 0xbc, 0x6f, 0x5f,
+       0x6b, 0xe2, 0x51, 0x8a, 0x31, 0x89, 0x35, 0x6e, 0x60, 0x09, 0x9f, 0xf7,
+       0x15, 0x0b, 0x3d, 0x80, 0x40, 0xc7, 0x8a, 0xbc, 0xc0, 0x6c, 0x9c, 0xec,
+       0xe3, 0xd7, 0xce, 0xf7, 0x84, 0x16, 0xce, 0x63, 0x72, 0xff, 0xe4, 0x90,
+       0x9d, 0xe4, 0x33, 0xfa, 0xd2, 0x3b, 0x64, 0x57, 0x5a, 0xb0, 0x8c, 0x9f,
+       0xd5, 0x70, 0x5c, 0x96, 0xf5, 0x45, 0xb9, 0xb3, 0xac, 0x4f, 0xd8, 0xb9,
+       0x05, 0x5d, 0xb8, 0xe8, 0x9d, 0xdd, 0x93, 0xda, 0xe0, 0x1e, 0xb4, 0x0c,
+       0xfc, 0x5c, 0x54, 0x3b, 0xbb, 0x7f, 0xd3, 0xad, 0x48, 0x2d, 0x37, 0x5d,
+       0xbd, 0x9f, 0x64, 0xd7, 0x13, 0x1d, 0xe7, 0x08, 0x84, 0x6e, 0x70, 0xf6,
+       0x88, 0xa6, 0x5b, 0xff, 0x84, 0xe6, 0xe6, 0xff, 0xbb, 0x7c, 0x7c, 0x5e,
+       0xf1, 0xf9, 0xec, 0x73, 0x76, 0x74, 0x69, 0x45, 0x3e, 0x27, 0xc9, 0xf7,
+       0x83, 0xa6, 0x84, 0x46, 0x3d, 0x32, 0xdf, 0x47, 0xdf, 0xff, 0x26, 0x4f,
+       0x68, 0xff, 0xda, 0x7e, 0xfc, 0x24, 0x67, 0x62, 0x3f, 0xe5, 0x81, 0x3a,
+       0x5d, 0x53, 0x73, 0x08, 0x71, 0x2d, 0xed, 0xf0, 0x7f, 0x4d, 0x8e, 0xfc,
+       0xb0, 0x5e, 0x75, 0x6a, 0x8c, 0x0a, 0x7f, 0x3e, 0xe2, 0xef, 0xb7, 0x7c,
+       0xec, 0x0b, 0x84, 0x91, 0xc8, 0x66, 0x52, 0x14, 0x57, 0x5a, 0xa2, 0x54,
+       0xc1, 0x93, 0x1f, 0x68, 0xfb, 0x40, 0xfe, 0x3a, 0x96, 0x66, 0xf9, 0x07,
+       0xfd, 0xdb, 0xf8, 0x48, 0xb0, 0xee, 0xf4, 0x24, 0x8d, 0x90, 0xc4, 0x71,
+       0xd7, 0x89, 0xa7, 0x56, 0x48, 0xfa, 0x51, 0x0d, 0xd3, 0x35, 0x5c, 0x0a,
+       0x07, 0xbd, 0x7c, 0x7e, 0x9e, 0xc0, 0xe1, 0x36, 0xa3, 0x92, 0x2b, 0xe7,
+       0x28, 0x1f, 0xbd, 0x4f, 0x74, 0x1c, 0x8c, 0x35, 0x22, 0x45, 0xf9, 0x28,
+       0xa3, 0x57, 0x6c, 0x49, 0x9f, 0x65, 0x8c, 0xd9, 0x46, 0x18, 0x53, 0x0b,
+       0xb9, 0xe5, 0x96, 0xc1, 0x17, 0xb1, 0xd3, 0x3e, 0x5b, 0xcf, 0x36, 0xe5,
+       0xc6, 0xf1, 0xd6, 0x59, 0xbb, 0x1c, 0x60, 0x7e, 0x65, 0x3c, 0x67, 0x90,
+       0xcd, 0x5c, 0x11, 0x0e, 0x3e, 0x47, 0x39, 0x75, 0x66, 0x41, 0x1f, 0xe1,
+       0xfc, 0xa2, 0x3d, 0xd6, 0xf8, 0xb8, 0x06, 0x4c, 0x41, 0x4f, 0xe4, 0x41,
+       0xc5, 0xb6, 0xb7, 0x39, 0xf8, 0xfe, 0x82, 0xad, 0xae, 0x9e, 0xfd, 0x0f,
+       0xbe, 0x85, 0xdf, 0xb2, 0x38, 0xef, 0x84, 0xf2, 0x9b, 0xe8, 0x3b, 0xcf,
+       0x19, 0x60, 0x2c, 0xc3, 0xe7, 0x9c, 0xbc, 0x3b, 0xda, 0xab, 0xd8, 0x5f,
+       0x54, 0x3e, 0xc7, 0xbf, 0x71, 0x8c, 0x7b, 0xaa, 0x36, 0xe5, 0x67, 0x19,
+       0x7b, 0x2e, 0xfd, 0xce, 0x80, 0xaf, 0x5d, 0xd8, 0x3c, 0xc6, 0xbd, 0x88,
+       0x93, 0xd7, 0x29, 0xf8, 0x3b, 0xca, 0xc3, 0xdc, 0x2b, 0x61, 0x5f, 0x6f,
+       0xea, 0x38, 0x35, 0xc9, 0x39, 0x35, 0xde, 0x71, 0x7b, 0x7a, 0x51, 0xc7,
+       0x97, 0x78, 0x3a, 0x7d, 0x07, 0xc5, 0x9d, 0x4c, 0x5a, 0x1b, 0x8c, 0xc8,
+       0xce, 0xde, 0x54, 0xaa, 0x28, 0xbe, 0x4a, 0x45, 0x1a, 0xcf, 0xa7, 0xfa,
+       0x07, 0x0f, 0x85, 0x90, 0xc9, 0x76, 0xe3, 0x1b, 0x63, 0xb6, 0x5d, 0xb5,
+       0xc6, 0x85, 0x57, 0x46, 0x6c, 0x7c, 0x10, 0x03, 0x5e, 0x1e, 0x09, 0x0f,
+       0x9e, 0x01, 0x7e, 0xaf, 0x8e, 0x6a, 0xe4, 0x56, 0xa1, 0xf5, 0x10, 0x36,
+       0x08, 0xbd, 0x8b, 0x96, 0x60, 0x1e, 0xda, 0xe9, 0x5d, 0x34, 0xdf, 0x4b,
+       0x05, 0xe0, 0x27, 0x05, 0x2f, 0xde, 0x1c, 0xe3, 0x39, 0xbd, 0x38, 0x73,
+       0xb4, 0xc1, 0xbf, 0x93, 0xe6, 0x3a, 0x40, 0xf1, 0xbd, 0xfb, 0x58, 0x02,
+       0x9b, 0x0f, 0x09, 0x44, 0x23, 0x09, 0x74, 0x1d, 0xab, 0xc5, 0xa6, 0x31,
+       0x05, 0xef, 0xc5, 0x6b, 0x71, 0xd3, 0xd1, 0x45, 0x3e, 0x2a, 0x7d, 0x0d,
+       0x3e, 0xe7, 0xc8, 0x67, 0xc8, 0x9e, 0xcc, 0x72, 0xcc, 0xa6, 0x7c, 0x91,
+       0xe5, 0x18, 0x68, 0xdb, 0xc1, 0xf6, 0x4a, 0x9f, 0xe3, 0x29, 0xca, 0x1f,
+       0x8f, 0xb6, 0xeb, 0xc1, 0xa0, 0x64, 0x62, 0xd5, 0x44, 0xf9, 0xb6, 0x3a,
+       0xd8, 0xcf, 0xf3, 0x5e, 0xc0, 0xc7, 0xad, 0xb6, 0xbd, 0x39, 0x1e, 0x99,
+       0xbf, 0xdb, 0xc1, 0xb5, 0x71, 0xf2, 0xa9, 0x26, 0x3c, 0x9a, 0x5d, 0xdc,
+       0x2f, 0xd2, 0xfb, 0x2e, 0xca, 0xd6, 0x90, 0x0a, 0xfb, 0xa3, 0x6a, 0xd3,
+       0xfe, 0xd8, 0x6d, 0x46, 0x82, 0xf7, 0x09, 0x3e, 0x67, 0x11, 0xa2, 0x1a,
+       0xc4, 0xb6, 0xdf, 0x8a, 0xdb, 0x76, 0x21, 0x6e, 0x79, 0x56, 0xaf, 0x55,
+       0x71, 0x6c, 0x25, 0xf7, 0x9c, 0xc3, 0xc9, 0x46, 0xb2, 0x2f, 0xef, 0x4a,
+       0x3d, 0xb8, 0x15, 0x9a, 0x65, 0x51, 0x90, 0x0b, 0x2d, 0xd5, 0xfa, 0x80,
+       0x26, 0xff, 0xc1, 0x91, 0x06, 0x3c, 0x3e, 0xf7, 0x9b, 0x7c, 0xf4, 0x85,
+       0x62, 0x84, 0x8d, 0x8f, 0x0c, 0xac, 0xaf, 0x43, 0x24, 0x79, 0x27, 0xe5,
+       0x02, 0xc9, 0xe4, 0xf3, 0xa0, 0x16, 0x6e, 0x8a, 0xf7, 0x63, 0xc7, 0x18,
+       0xef, 0x51, 0xc5, 0x3a, 0x3e, 0x1a, 0xb3, 0xff, 0xc6, 0x43, 0xf4, 0xaf,
+       0x6f, 0x6f, 0x49, 0x79, 0x9d, 0xdf, 0x05, 0xe9, 0x54, 0x07, 0xd4, 0xa3,
+       0x34, 0xa3, 0x97, 0x97, 0x8b, 0xe4, 0x1b, 0x3e, 0x44, 0x82, 0x8d, 0x14,
+       0xab, 0xe6, 0xc8, 0x77, 0x67, 0x4a, 0x5c, 0x07, 0xac, 0xe9, 0xb0, 0x27,
+       0x96, 0x61, 0x7a, 0x8e, 0xe6, 0xca, 0xea, 0x5d, 0x1f, 0x10, 0xce, 0xab,
+       0x31, 0xed, 0x3a, 0xaf, 0x19, 0x39, 0xdd, 0x22, 0x64, 0xcc, 0xaf, 0xb1,
+       0xed, 0xee, 0x76, 0x7d, 0xb0, 0x56, 0x60, 0x80, 0xe6, 0x4a, 0xb4, 0xca,
+       0xb8, 0x32, 0x88, 0x48, 0xd7, 0x5b, 0x88, 0xf4, 0x9d, 0xa3, 0x18, 0xf6,
+       0x44, 0x89, 0xcf, 0xd8, 0x3e, 0x84, 0xbf, 0x19, 0x5b, 0x8a, 0xe7, 0x67,
+       0x06, 0x16, 0x7a, 0x62, 0xf0, 0x5e, 0xbd, 0xd6, 0xc4, 0xf1, 0xb1, 0x10,
+       0xd9, 0x4f, 0x15, 0xc5, 0x75, 0x05, 0x52, 0x33, 0xf7, 0x48, 0x43, 0x1d,
+       0xb1, 0x47, 0x6c, 0x7b, 0x75, 0x73, 0xa5, 0xe6, 0x59, 0x3d, 0x7b, 0xf9,
+       0xef, 0x02, 0x16, 0xfb, 0x3d, 0x41, 0xd2, 0x5f, 0x4b, 0x6a, 0x87, 0x78,
+       0xd1, 0xb6, 0x7e, 0x57, 0x10, 0xcf, 0x91, 0x5a, 0x78, 0x99, 0x6f, 0x05,
+       0xbb, 0x26, 0x08, 0x94, 0x39, 0xe7, 0x56, 0xe0, 0xed, 0x8a, 0xf3, 0x5e,
+       0x33, 0xeb, 0xa8, 0xec, 0xdd, 0x18, 0xa7, 0x98, 0x28, 0xfc, 0x84, 0xa7,
+       0x2c, 0x4f, 0x27, 0xe5, 0xa7, 0xea, 0x31, 0xfe, 0x8d, 0x82, 0x0f, 0xfb,
+       0x29, 0x6e, 0xbc, 0x6f, 0xd4, 0xe0, 0x60, 0xbd, 0x96, 0xe0, 0x7a, 0xfa,
+       0xb1, 0x12, 0xf7, 0x25, 0x77, 0xe2, 0x2e, 0xfe, 0x8d, 0x47, 0xe9, 0x5a,
+       0xe7, 0x5c, 0x1e, 0xdd, 0x23, 0x6c, 0xc0, 0x74, 0x2c, 0xae, 0xdf, 0x85,
+       0xe5, 0x23, 0xac, 0xc7, 0x40, 0x47, 0x90, 0x64, 0xf4, 0x28, 0xd9, 0x85,
+       0x64, 0x76, 0x42, 0x19, 0xb1, 0xed, 0xeb, 0xe3, 0x97, 0xcf, 0xa1, 0x0f,
+       0x9c, 0x93, 0xa9, 0xbe, 0x93, 0x79, 0x4f, 0x4c, 0x4b, 0x9c, 0x10, 0x97,
+       0xcf, 0xf9, 0x87, 0x44, 0x33, 0xcf, 0x5b, 0xc9, 0x4b, 0xc7, 0x29, 0x2f,
+       0xbd, 0x3c, 0xca, 0x3e, 0xd2, 0xe6, 0xf8, 0x88, 0x44, 0xb1, 0x76, 0x43,
+       0x3a, 0x84, 0x73, 0x06, 0xf4, 0x2a, 0xc4, 0x88, 0xee, 0x48, 0x4f, 0xe7,
+       0x02, 0xe6, 0x73, 0x53, 0xfc, 0x9f, 0x19, 0xe5, 0x7d, 0x2a, 0x81, 0x5a,
+       0x9d, 0x6d, 0xc0, 0xc9, 0x05, 0x14, 0xd3, 0x06, 0x50, 0x77, 0x2d, 0x70,
+       0x71, 0x84, 0xf7, 0xcc, 0x74, 0xec, 0x2f, 0x0d, 0x8a, 0xc6, 0x91, 0x7f,
+       0xb0, 0x43, 0xd5, 0x8b, 0xfb, 0x67, 0x0f, 0xf2, 0xfe, 0x19, 0xd9, 0xc0,
+       0x80, 0x73, 0x46, 0xe6, 0xad, 0x34, 0x9f, 0x91, 0x09, 0x87, 0x36, 0x93,
+       0xef, 0x6c, 0x43, 0x8b, 0x31, 0x4b, 0xd8, 0x79, 0x9e, 0xe8, 0x6c, 0x16,
+       0x95, 0x3d, 0xa2, 0xc8, 0xc2, 0x1e, 0xd7, 0xca, 0x7c, 0x97, 0xa8, 0x2d,
+       0x30, 0x4d, 0x71, 0xa2, 0xa9, 0x53, 0xd4, 0x1c, 0xdb, 0x28, 0x7c, 0xc7,
+       0xba, 0x85, 0x54, 0xe0, 0x98, 0x1c, 0xeb, 0xd8, 0x3d, 0xca, 0xf9, 0x6c,
+       0x8b, 0x70, 0x1d, 0xed, 0x15, 0xde, 0x42, 0x9f, 0xf0, 0x1f, 0xb3, 0x70,
+       0x6f, 0xbc, 0x1b, 0x67, 0xc6, 0xf8, 0x1c, 0xd8, 0x3d, 0xa2, 0x76, 0x61,
+       0x5f, 0xcb, 0x5b, 0x68, 0xf2, 0x17, 0x68, 0x7d, 0xc2, 0x12, 0x1d, 0xe9,
+       0x91, 0x65, 0xfe, 0x27, 0x26, 0x03, 0xfe, 0xc7, 0x26, 0xb5, 0x81, 0xbd,
+       0xc2, 0xb6, 0x77, 0xc6, 0xa6, 0x59, 0x87, 0x76, 0x4b, 0xac, 0x82, 0x0f,
+       0x76, 0x91, 0x3c, 0xb6, 0x53, 0x6e, 0x99, 0x36, 0x5a, 0x16, 0xb0, 0x88,
+       0x96, 0xe2, 0xdf, 0x8b, 0xd1, 0xa7, 0x87, 0x73, 0x1b, 0xef, 0x09, 0xba,
+       0xda, 0x41, 0x71, 0xf7, 0x33, 0x5e, 0x6b, 0x47, 0xf8, 0x7c, 0xd7, 0x00,
+       0xfc, 0x5f, 0xb2, 0x27, 0x76, 0xe6, 0xb3, 0x3d, 0xb1, 0xc4, 0x63, 0x42,
+       0x2b, 0xcf, 0x11, 0xbf, 0xd5, 0xf2, 0xe7, 0xf6, 0xc3, 0x16, 0xf6, 0xc2,
+       0xba, 0x84, 0xaf, 0xc0, 0xf5, 0x79, 0xbc, 0xe3, 0xf5, 0x91, 0x4e, 0xe1,
+       0x3d, 0x36, 0x46, 0xf9, 0x71, 0x23, 0xf1, 0xcc, 0xe7, 0xae, 0xba, 0x85,
+       0xbf, 0xb0, 0x45, 0xf8, 0x88, 0xcf, 0x1a, 0xe2, 0x13, 0xc7, 0x3c, 0xc2,
+       0x4b, 0x3c, 0x7a, 0x88, 0x47, 0xef, 0x02, 0x8f, 0x9e, 0x42, 0xd0, 0x9f,
+       0x4e, 0x37, 0xf8, 0x1f, 0x9e, 0x54, 0xfd, 0x7b, 0x27, 0x6d, 0xfb, 0x3d,
+       0xe3, 0x67, 0x0e, 0x5f, 0xaf, 0x1a, 0x5f, 0xe4, 0xeb, 0x3a, 0xe2, 0xab,
+       0xb2, 0x8f, 0x49, 0x3a, 0x4c, 0xb1, 0x0e, 0xf9, 0x0c, 0xc4, 0x22, 0x5f,
+       0x07, 0xd2, 0xbc, 0x8f, 0xc1, 0x7b, 0x7e, 0x83, 0x62, 0x35, 0xf1, 0x55,
+       0x26, 0xbe, 0xae, 0xf9, 0x12, 0xbe, 0x3e, 0xbc, 0x8c, 0xaf, 0x57, 0xff,
+       0x51, 0xbe, 0x3c, 0x62, 0xd5, 0x18, 0xc7, 0xa1, 0xfb, 0x3b, 0x94, 0x31,
+       0x9b, 0xb0, 0xa3, 0x8c, 0xc7, 0x67, 0x80, 0x62, 0x76, 0x08, 0x0a, 0xc5,
+       0x9b, 0x93, 0xf1, 0x48, 0xe8, 0x15, 0xaa, 0x27, 0x67, 0x4b, 0x5e, 0xb1,
+       0xd2, 0xd9, 0xcf, 0xc4, 0x6a, 0x85, 0x68, 0x9a, 0x73, 0x7e, 0x9f, 0x05,
+       0xa3, 0x4e, 0x67, 0x5d, 0xea, 0xa7, 0xb7, 0x22, 0x52, 0x8e, 0xc8, 0xdd,
+       0x22, 0x51, 0xe0, 0xfd, 0xcb, 0x5e, 0x71, 0x8d, 0xb3, 0x77, 0xd9, 0x25,
+       0xae, 0x2e, 0x74, 0x8a, 0x56, 0xb2, 0x8b, 0x96, 0x63, 0x7c, 0x96, 0x6a,
+       0x8b, 0x68, 0x59, 0x90, 0xc7, 0x2a, 0x92, 0xc7, 0xc8, 0xe7, 0xe4, 0xb1,
+       0xc4, 0xcf, 0xf2, 0xf8, 0x91, 0x71, 0xe1, 0xb2, 0x1e, 0x1a, 0xd7, 0x55,
+       0x94, 0x0d, 0xa9, 0x76, 0xaa, 0x5b, 0xa8, 0x9d, 0xde, 0x8e, 0xf1, 0x19,
+       0x19, 0xcb, 0xae, 0xd5, 0x11, 0x72, 0x99, 0x5a, 0xdf, 0x49, 0xa1, 0xa7,
+       0xee, 0x11, 0xc9, 0xcd, 0x3e, 0xaa, 0x7f, 0x76, 0xc4, 0x22, 0xc9, 0x55,
+       0x22, 0x92, 0x70, 0x09, 0xce, 0x2b, 0x86, 0x52, 0x5d, 0xb4, 0xb0, 0x97,
+       0xe2, 0xdb, 0x4b, 0xa3, 0x12, 0x61, 0x07, 0xfe, 0xcd, 0x96, 0x0b, 0xd7,
+       0xab, 0x3e, 0x1c, 0x21, 0xdc, 0xf1, 0x68, 0xb6, 0x1f, 0x47, 0xf2, 0xdb,
+       0xf0, 0x68, 0xfe, 0xd7, 0x7e, 0x9f, 0xa2, 0x78, 0xcd, 0x9e, 0x6b, 0x2b,
+       0xfb, 0xf8, 0xd1, 0xc4, 0x55, 0x11, 0x96, 0xcd, 0x4f, 0x5b, 0x94, 0x08,
+       0xd7, 0xba, 0x89, 0xeb, 0x7e, 0xae, 0xb3, 0x2f, 0xa6, 0xdb, 0x4f, 0x39,
+       0x58, 0xe4, 0xed, 0xb6, 0x63, 0xce, 0xf9, 0xa2, 0x5f, 0xae, 0xde, 0xed,
+       0xfc, 0x7e, 0x32, 0xb9, 0xf6, 0x76, 0x9d, 0xfd, 0xe1, 0xa7, 0x6b, 0x36,
+       0x38, 0xf9, 0xd5, 0x5c, 0x57, 0xf9, 0x6d, 0x49, 0x62, 0x5d, 0xa5, 0x57,
+       0x13, 0x5f, 0x17, 0x75, 0xae, 0xc9, 0x75, 0x95, 0x7d, 0xe2, 0x9e, 0x75,
+       0xcd, 0xce, 0xb5, 0x6b, 0x5d, 0xc5, 0xa7, 0x3a, 0xd7, 0xe9, 0xce, 0xb5,
+       0x77, 0x5d, 0x25, 0x2f, 0x77, 0xaf, 0x5b, 0x71, 0xe9, 0x37, 0x29, 0xfc,
+       0xf7, 0x7f, 0x00, 0x2f, 0xc1, 0x67, 0x8a, 0x54, 0x3a, 0x00, 0x00, 0x00 };
 
-static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = {
-       0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010,
-       0x00000030, 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000010,
-       0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00008002, 0x00000000,
-       0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000,
-       0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
+static const u32 bnx2_TXP_b09FwData[(0x0/4) + 1] = { 0x0 };
 static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = {
-       0x08003fdc, 0x08004008, 0x08004050, 0x08004050, 0x08003edc, 0x08003f08,
-       0x08003f08, 0x08004050, 0x08004050, 0x08004050, 0x08003f70, 0x00000000,
+       0x80000940, 0x80000900, 0x80080100, 0x80080080, 0x80080000, 0x800e0000,
+       0x80080080, 0x80080000, 0x80000a80, 0x80000a00, 0x80000980, 0x80000900,
        0x00000000 };
 
 static struct fw_info bnx2_txp_fw_09 = {
-       /* Firmware version:  3.7.1 */
-       .ver_major                      = 0x3,
-       .ver_minor                      = 0x7,
-       .ver_fix                        = 0x1,
+       /* Firmware version: 4.0.5 */
+       .ver_major                      = 0x4,
+       .ver_minor                      = 0x0,
+       .ver_fix                        = 0x5,
 
-       .start_addr                     = 0x08000060,
+       .start_addr                     = 0x08000094,
 
        .text_addr                      = 0x08000000,
-       .text_len                       = 0x45b0,
+       .text_len                       = 0x3a50,
        .text_index                     = 0x0,
        .gz_text                        = bnx2_TXP_b09FwText,
        .gz_text_len                    = sizeof(bnx2_TXP_b09FwText),
 
-       .data_addr                      = 0x08004600,
-       .data_len                       = 0xd0,
+       .data_addr                      = 0x00000000,
+       .data_len                       = 0x0,
        .data_index                     = 0x0,
        .data                           = bnx2_TXP_b09FwData,
 
-       .sbss_addr                      = 0x080046d0,
-       .sbss_len                       = 0x8c,
+       .sbss_addr                      = 0x08003aa0,
+       .sbss_len                       = 0x6c,
        .sbss_index                     = 0x0,
 
-       .bss_addr                       = 0x08004760,
-       .bss_len                        = 0xa20,
+       .bss_addr                       = 0x08003b0c,
+       .bss_len                        = 0x24c,
        .bss_index                      = 0x0,
 
-       .rodata_addr                    = 0x080045b0,
+       .rodata_addr                    = 0x08003a50,
        .rodata_len                     = 0x30,
        .rodata_index                   = 0x0,
        .rodata                         = bnx2_TXP_b09FwRodata,
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c
new file mode 100644 (file)
index 0000000..4a73c88
--- /dev/null
@@ -0,0 +1,9064 @@
+/* bnx2x.c: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ *
+ * Written by: Eliezer Tamir <eliezert@broadcom.com>
+ * Based on code from Michael Chan's bnx2 driver
+ * UDP CSUM errata workaround by Arik Gendelman
+ * Slowpath rework by Vladislav Zolotarov
+ * Statistics and Link managment by Yitchak Gertner
+ *
+ */
+
+/* define this to make the driver freeze on error
+ * to allow getting debug info
+ * (you will need to reboot afterwords)
+ */
+/*#define BNX2X_STOP_ON_ERROR*/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/device.h>  /* for dev_info() */
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/time.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#ifdef NETIF_F_HW_VLAN_TX
+       #include <linux/if_vlan.h>
+       #define BCM_VLAN 1
+#endif
+#include <net/ip.h>
+#include <net/tcp.h>
+#include <net/checksum.h>
+#include <linux/workqueue.h>
+#include <linux/crc32.h>
+#include <linux/prefetch.h>
+#include <linux/zlib.h>
+#include <linux/version.h>
+#include <linux/io.h>
+
+#include "bnx2x_reg.h"
+#include "bnx2x_fw_defs.h"
+#include "bnx2x_hsi.h"
+#include "bnx2x.h"
+#include "bnx2x_init.h"
+
+#define DRV_MODULE_VERSION      "0.40.15"
+#define DRV_MODULE_RELDATE      "$DateTime: 2007/11/15 07:28:37 $"
+#define BNX2X_BC_VER           0x040009
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT             (5*HZ)
+
+static const char version[] __devinitdata =
+       "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver "
+       DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
+
+MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_MODULE_VERSION);
+MODULE_INFO(cvs_version, "$Revision: #356 $");
+
+static int use_inta;
+static int poll;
+static int onefunc;
+static int nomcp;
+static int debug;
+static int use_multi;
+
+module_param(use_inta, int, 0);
+module_param(poll, int, 0);
+module_param(onefunc, int, 0);
+module_param(debug, int, 0);
+MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X");
+MODULE_PARM_DESC(poll, "use polling (for debug)");
+MODULE_PARM_DESC(onefunc, "enable only first function");
+MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)");
+MODULE_PARM_DESC(debug, "defualt debug msglevel");
+
+#ifdef BNX2X_MULTI
+module_param(use_multi, int, 0);
+MODULE_PARM_DESC(use_multi, "use per-CPU queues");
+#endif
+
+enum bnx2x_board_type {
+       BCM57710 = 0,
+};
+
+/* indexed by board_t, above */
+static const struct {
+       char *name;
+} board_info[] __devinitdata = {
+       { "Broadcom NetXtreme II BCM57710 XGb" }
+};
+
+static const struct pci_device_id bnx2x_pci_tbl[] = {
+       { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 },
+       { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
+
+/****************************************************************************
+* General service functions
+****************************************************************************/
+
+/* used only at init
+ * locking is done by mcp
+ */
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
+{
+       pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
+       pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
+       pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
+                              PCICFG_VENDOR_ID_OFFSET);
+}
+
+#ifdef BNX2X_IND_RD
+static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
+{
+       u32 val;
+
+       pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
+       pci_read_config_dword(bp->pdev, PCICFG_GRC_DATA, &val);
+       pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
+                              PCICFG_VENDOR_ID_OFFSET);
+
+       return val;
+}
+#endif
+
+static const u32 dmae_reg_go_c[] = {
+       DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
+       DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7,
+       DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11,
+       DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15
+};
+
+/* copy command into DMAE command memory and set DMAE command go */
+static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
+                           int idx)
+{
+       u32 cmd_offset;
+       int i;
+
+       cmd_offset = (DMAE_REG_CMD_MEM + sizeof(struct dmae_command) * idx);
+       for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
+               REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
+
+/*             DP(NETIF_MSG_DMAE, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
+                  idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i)); */
+       }
+       REG_WR(bp, dmae_reg_go_c[idx], 1);
+}
+
+static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
+                            u32 dst_addr, u32 len32)
+{
+       struct dmae_command *dmae = &bp->dmae;
+       int port = bp->port;
+       u32 *wb_comp = bnx2x_sp(bp, wb_comp);
+       int timeout = 200;
+
+       memset(dmae, 0, sizeof(struct dmae_command));
+
+       dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+                       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+                       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                       DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                       DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                       (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+       dmae->src_addr_lo = U64_LO(dma_addr);
+       dmae->src_addr_hi = U64_HI(dma_addr);
+       dmae->dst_addr_lo = dst_addr >> 2;
+       dmae->dst_addr_hi = 0;
+       dmae->len = len32;
+       dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+       dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+       dmae->comp_val = BNX2X_WB_COMP_VAL;
+
+/*
+       DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
+          DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
+                   "dst_addr [%x:%08x (%08x)]\n"
+          DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
+          dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+          dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
+          dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+*/
+/*
+       DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+          bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
+          bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+*/
+
+       *wb_comp = 0;
+
+       bnx2x_post_dmae(bp, dmae, port * 8);
+
+       udelay(5);
+       /* adjust timeout for emulation/FPGA */
+       if (CHIP_REV_IS_SLOW(bp))
+               timeout *= 100;
+       while (*wb_comp != BNX2X_WB_COMP_VAL) {
+/*             DP(NETIF_MSG_DMAE, "wb_comp 0x%08x\n", *wb_comp); */
+               udelay(5);
+               if (!timeout) {
+                       BNX2X_ERR("dmae timeout!\n");
+                       break;
+               }
+               timeout--;
+       }
+}
+
+#ifdef BNX2X_DMAE_RD
+static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
+{
+       struct dmae_command *dmae = &bp->dmae;
+       int port = bp->port;
+       u32 *wb_comp = bnx2x_sp(bp, wb_comp);
+       int timeout = 200;
+
+       memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
+       memset(dmae, 0, sizeof(struct dmae_command));
+
+       dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+                       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+                       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                       DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                       DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                       (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+       dmae->src_addr_lo = src_addr >> 2;
+       dmae->src_addr_hi = 0;
+       dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
+       dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data));
+       dmae->len = len32;
+       dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
+       dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
+       dmae->comp_val = BNX2X_WB_COMP_VAL;
+
+/*
+       DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
+          DP_LEVEL "src_addr  [%x:%08x]  len [%d *4]  "
+                   "dst_addr [%x:%08x (%08x)]\n"
+          DP_LEVEL "comp_addr [%x:%08x]  comp_val 0x%08x\n",
+          dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
+          dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
+          dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
+*/
+
+       *wb_comp = 0;
+
+       bnx2x_post_dmae(bp, dmae, port * 8);
+
+       udelay(5);
+       while (*wb_comp != BNX2X_WB_COMP_VAL) {
+               udelay(5);
+               if (!timeout) {
+                       BNX2X_ERR("dmae timeout!\n");
+                       break;
+               }
+               timeout--;
+       }
+/*
+       DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
+          bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
+          bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
+*/
+}
+#endif
+
+static int bnx2x_mc_assert(struct bnx2x *bp)
+{
+       int i, j;
+       int rc = 0;
+       char last_idx;
+       const char storm[] = {"XTCU"};
+       const u32 intmem_base[] = {
+               BAR_XSTRORM_INTMEM,
+               BAR_TSTRORM_INTMEM,
+               BAR_CSTRORM_INTMEM,
+               BAR_USTRORM_INTMEM
+       };
+
+       /* Go through all instances of all SEMIs */
+       for (i = 0; i < 4; i++) {
+               last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET +
+                                  intmem_base[i]);
+               BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n",
+                         storm[i], last_idx);
+
+               /* print the asserts */
+               for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) {
+                       u32 row0, row1, row2, row3;
+
+                       row0 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) +
+                                     intmem_base[i]);
+                       row1 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 4 +
+                                     intmem_base[i]);
+                       row2 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 8 +
+                                     intmem_base[i]);
+                       row3 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 12 +
+                                     intmem_base[i]);
+
+                       if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) {
+                               BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x ="
+                                         " 0x%08x 0x%08x 0x%08x 0x%08x\n",
+                                         storm[i], j, row3, row2, row1, row0);
+                               rc++;
+                       } else {
+                               break;
+                       }
+               }
+       }
+       return rc;
+}
+static void bnx2x_fw_dump(struct bnx2x *bp)
+{
+       u32 mark, offset;
+       u32 data[9];
+       int word;
+
+       mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104);
+       printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark);
+
+       for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) {
+               for (word = 0; word < 8; word++)
+                       data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
+                                                 offset + 4*word));
+               data[8] = 0x0;
+               printk(KERN_ERR PFX "%s", (char *)data);
+       }
+       for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) {
+               for (word = 0; word < 8; word++)
+                       data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH +
+                                                 offset + 4*word));
+               data[8] = 0x0;
+               printk(KERN_ERR PFX "%s", (char *)data);
+       }
+       printk("\n" KERN_ERR PFX "end of fw dump\n");
+}
+
+static void bnx2x_panic_dump(struct bnx2x *bp)
+{
+       int i;
+       u16 j, start, end;
+
+       BNX2X_ERR("begin crash dump -----------------\n");
+
+       for_each_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+               struct eth_tx_db_data *hw_prods = fp->hw_tx_prods;
+
+               BNX2X_ERR("queue[%d]: tx_pkt_prod(%x)  tx_pkt_cons(%x)"
+                         "  tx_bd_prod(%x)  tx_bd_cons(%x)  *tx_cons_sb(%x)"
+                         "  *rx_cons_sb(%x)  rx_comp_prod(%x)"
+                         "  rx_comp_cons(%x)  fp_c_idx(%x)  fp_u_idx(%x)"
+                         "  bd data(%x,%x)\n",
+                         i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod,
+                         fp->tx_bd_cons, *fp->tx_cons_sb, *fp->rx_cons_sb,
+                         fp->rx_comp_prod, fp->rx_comp_cons, fp->fp_c_idx,
+                         fp->fp_u_idx, hw_prods->packets_prod,
+                         hw_prods->bds_prod);
+
+               start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10);
+               end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245);
+               for (j = start; j < end; j++) {
+                       struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j];
+
+                       BNX2X_ERR("packet[%x]=[%p,%x]\n", j,
+                                 sw_bd->skb, sw_bd->first_bd);
+               }
+
+               start = TX_BD(fp->tx_bd_cons - 10);
+               end = TX_BD(fp->tx_bd_cons + 254);
+               for (j = start; j < end; j++) {
+                       u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j];
+
+                       BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n",
+                                 j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]);
+               }
+
+               start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10);
+               end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503);
+               for (j = start; j < end; j++) {
+                       u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j];
+                       struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j];
+
+                       BNX2X_ERR("rx_bd[%x]=[%x:%x]  sw_bd=[%p]\n",
+                                 j, rx_bd[0], rx_bd[1], sw_bd->skb);
+               }
+
+               start = RCQ_BD(fp->rx_comp_cons - 10);
+               end = RCQ_BD(fp->rx_comp_cons + 503);
+               for (j = start; j < end; j++) {
+                       u32 *cqe = (u32 *)&fp->rx_comp_ring[j];
+
+                       BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n",
+                                 j, cqe[0], cqe[1], cqe[2], cqe[3]);
+               }
+       }
+
+       BNX2X_ERR("def_c_idx(%u)  def_u_idx(%u)  def_t_idx(%u)"
+                 "  def_x_idx(%u)  def_att_idx(%u)  attn_state(%u)"
+                 "  spq_prod_idx(%u)\n",
+                 bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx,
+                 bp->def_att_idx, bp->attn_state, bp->spq_prod_idx);
+
+
+       bnx2x_mc_assert(bp);
+       BNX2X_ERR("end crash dump -----------------\n");
+
+       bp->stats_state = STATS_STATE_DISABLE;
+       DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
+}
+
+static void bnx2x_enable_int(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
+       u32 val = REG_RD(bp, addr);
+       int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+
+       if (msix) {
+               val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0;
+               val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+                       HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+       } else {
+               val |= (HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+                       HC_CONFIG_0_REG_INT_LINE_EN_0 |
+                       HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+               val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0;
+       }
+
+       DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)  msi %d\n",
+          val, port, addr, msix);
+
+       REG_WR(bp, addr, val);
+}
+
+static void bnx2x_disable_int(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0;
+       u32 val = REG_RD(bp, addr);
+
+       val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 |
+                HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 |
+                HC_CONFIG_0_REG_INT_LINE_EN_0 |
+                HC_CONFIG_0_REG_ATTN_BIT_EN_0);
+
+       DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n",
+          val, port, addr);
+
+       REG_WR(bp, addr, val);
+       if (REG_RD(bp, addr) != val)
+               BNX2X_ERR("BUG! proper val not read from IGU!\n");
+}
+
+static void bnx2x_disable_int_sync(struct bnx2x *bp)
+{
+
+       int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
+       int i;
+
+       atomic_inc(&bp->intr_sem);
+       /* prevent the HW from sending interrupts*/
+       bnx2x_disable_int(bp);
+
+       /* make sure all ISRs are done */
+       if (msix) {
+               for_each_queue(bp, i)
+                       synchronize_irq(bp->msix_table[i].vector);
+
+               /* one more for the Slow Path IRQ */
+               synchronize_irq(bp->msix_table[i].vector);
+       } else
+               synchronize_irq(bp->pdev->irq);
+
+       /* make sure sp_task is not running */
+       cancel_work_sync(&bp->sp_task);
+
+}
+
+/* fast path code */
+
+/*
+ * general service functions
+ */
+
+static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 id,
+                               u8 storm, u16 index, u8 op, u8 update)
+{
+       u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_PORT_BASE * bp->port) * 8;
+       struct igu_ack_register igu_ack;
+
+       igu_ack.status_block_index = index;
+       igu_ack.sb_id_and_flags =
+                       ((id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) |
+                        (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) |
+                        (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) |
+                        (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT));
+
+/*      DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
+          (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr); */
+       REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack));
+}
+
+static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
+{
+       struct host_status_block *fpsb = fp->status_blk;
+       u16 rc = 0;
+
+       barrier(); /* status block is written to by the chip */
+       if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) {
+               fp->fp_c_idx = fpsb->c_status_block.status_block_index;
+               rc |= 1;
+       }
+       if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) {
+               fp->fp_u_idx = fpsb->u_status_block.status_block_index;
+               rc |= 2;
+       }
+       return rc;
+}
+
+static inline int bnx2x_has_work(struct bnx2x_fastpath *fp)
+{
+       u16 rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb);
+
+       if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+               rx_cons_sb++;
+
+       if ((rx_cons_sb != fp->rx_comp_cons) ||
+           (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons))
+               return 1;
+
+       return 0;
+}
+
+static u16 bnx2x_ack_int(struct bnx2x *bp)
+{
+       u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_PORT_BASE * bp->port) * 8;
+       u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr);
+
+/*      DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n",
+          result, BAR_IGU_INTMEM + igu_addr); */
+
+#ifdef IGU_DEBUG
+#warning IGU_DEBUG active
+       if (result == 0) {
+               BNX2X_ERR("read %x from IGU\n", result);
+               REG_WR(bp, TM_REG_TIMER_SOFT_RST, 0);
+       }
+#endif
+       return result;
+}
+
+
+/*
+ * fast path service functions
+ */
+
+/* free skb in the packet ring at pos idx
+ * return idx of last bd freed
+ */
+static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp,
+                            u16 idx)
+{
+       struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx];
+       struct eth_tx_bd *tx_bd;
+       struct sk_buff *skb = tx_buf->skb;
+       u16 bd_idx = tx_buf->first_bd;
+       int nbd;
+
+       DP(BNX2X_MSG_OFF, "pkt_idx %d  buff @(%p)->skb %p\n",
+          idx, tx_buf, skb);
+
+       /* unmap first bd */
+       DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx);
+       tx_bd = &fp->tx_desc_ring[bd_idx];
+       pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd),
+                        BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+
+       nbd = le16_to_cpu(tx_bd->nbd) - 1;
+#ifdef BNX2X_STOP_ON_ERROR
+       if (nbd > (MAX_SKB_FRAGS + 2)) {
+               BNX2X_ERR("bad nbd!\n");
+               bnx2x_panic();
+       }
+#endif
+
+       /* Skip a parse bd and the TSO split header bd
+          since they have no mapping */
+       if (nbd)
+               bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+
+       if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM |
+                                          ETH_TX_BD_FLAGS_TCP_CSUM |
+                                          ETH_TX_BD_FLAGS_SW_LSO)) {
+               if (--nbd)
+                       bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+               tx_bd = &fp->tx_desc_ring[bd_idx];
+               /* is this a TSO split header bd? */
+               if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) {
+                       if (--nbd)
+                               bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+               }
+       }
+
+       /* now free frags */
+       while (nbd > 0) {
+
+               DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx);
+               tx_bd = &fp->tx_desc_ring[bd_idx];
+               pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd),
+                              BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE);
+               if (--nbd)
+                       bd_idx = TX_BD(NEXT_TX_IDX(bd_idx));
+       }
+
+       /* release skb */
+       BUG_TRAP(skb);
+       dev_kfree_skb(skb);
+       tx_buf->first_bd = 0;
+       tx_buf->skb = NULL;
+
+       return bd_idx;
+}
+
+static inline u32 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
+{
+       u16 used;
+       u32 prod;
+       u32 cons;
+
+       /* Tell compiler that prod and cons can change */
+       barrier();
+       prod = fp->tx_bd_prod;
+       cons = fp->tx_bd_cons;
+
+       used = (NUM_TX_BD - NUM_TX_RINGS + prod - cons +
+               (cons / TX_DESC_CNT) - (prod / TX_DESC_CNT));
+
+       if (prod >= cons) {
+               /* used = prod - cons - prod/size + cons/size */
+               used -= NUM_TX_BD - NUM_TX_RINGS;
+       }
+
+       BUG_TRAP(used <= fp->bp->tx_ring_size);
+       BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL);
+
+       return (fp->bp->tx_ring_size - used);
+}
+
+static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work)
+{
+       struct bnx2x *bp = fp->bp;
+       u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons;
+       int done = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return;
+#endif
+
+       hw_cons = le16_to_cpu(*fp->tx_cons_sb);
+       sw_cons = fp->tx_pkt_cons;
+
+       while (sw_cons != hw_cons) {
+               u16 pkt_cons;
+
+               pkt_cons = TX_BD(sw_cons);
+
+               /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */
+
+               DP(NETIF_MSG_TX_DONE, "hw_cons %u  sw_cons %u  pkt_cons %d\n",
+                  hw_cons, sw_cons, pkt_cons);
+
+/*             if (NEXT_TX_IDX(sw_cons) != hw_cons) {
+                       rmb();
+                       prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb);
+               }
+*/
+               bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons);
+               sw_cons++;
+               done++;
+
+               if (done == work)
+                       break;
+       }
+
+       fp->tx_pkt_cons = sw_cons;
+       fp->tx_bd_cons = bd_cons;
+
+       /* Need to make the tx_cons update visible to start_xmit()
+        * before checking for netif_queue_stopped().  Without the
+        * memory barrier, there is a small possibility that start_xmit()
+        * will miss it and cause the queue to be stopped forever.
+        */
+       smp_mb();
+
+       /* TBD need a thresh? */
+       if (unlikely(netif_queue_stopped(bp->dev))) {
+
+               netif_tx_lock(bp->dev);
+
+               if (netif_queue_stopped(bp->dev) &&
+                   (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3))
+                       netif_wake_queue(bp->dev);
+
+               netif_tx_unlock(bp->dev);
+
+       }
+}
+
+static void bnx2x_sp_event(struct bnx2x_fastpath *fp,
+                          union eth_rx_cqe *rr_cqe)
+{
+       struct bnx2x *bp = fp->bp;
+       int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
+       int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
+
+       DP(NETIF_MSG_RX_STATUS,
+          "fp %d  cid %d  got ramrod #%d  state is %x  type is %d\n",
+          fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.type);
+
+       bp->spq_left++;
+
+       if (fp->index) {
+               switch (command | fp->state) {
+               case (RAMROD_CMD_ID_ETH_CLIENT_SETUP |
+                                               BNX2X_FP_STATE_OPENING):
+                       DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n",
+                          cid);
+                       fp->state = BNX2X_FP_STATE_OPEN;
+                       break;
+
+               case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING):
+                       DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n",
+                          cid);
+                       fp->state = BNX2X_FP_STATE_HALTED;
+                       break;
+
+               default:
+                       BNX2X_ERR("unexpected MC reply(%d)  state is %x\n",
+                                 command, fp->state);
+               }
+               mb(); /* force bnx2x_wait_ramrod to see the change */
+               return;
+       }
+       switch (command | bp->state) {
+       case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT):
+               DP(NETIF_MSG_IFUP, "got setup ramrod\n");
+               bp->state = BNX2X_STATE_OPEN;
+               break;
+
+       case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT):
+               DP(NETIF_MSG_IFDOWN, "got halt ramrod\n");
+               bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE;
+               fp->state = BNX2X_FP_STATE_HALTED;
+               break;
+
+       case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE):
+               DP(NETIF_MSG_IFDOWN, "got delete ramrod\n");
+               bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD;
+               break;
+
+       case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT):
+               DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid);
+               bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_DELETED;
+               break;
+
+       case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN):
+               DP(NETIF_MSG_IFUP, "got set mac ramrod\n");
+               break;
+
+       default:
+               BNX2X_ERR("unexpected ramrod (%d)  state is %x\n",
+                         command, bp->state);
+       }
+
+       mb(); /* force bnx2x_wait_ramrod to see the change */
+}
+
+static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp,
+                                    struct bnx2x_fastpath *fp, u16 index)
+{
+       struct sk_buff *skb;
+       struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index];
+       struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index];
+       dma_addr_t mapping;
+
+       skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size);
+       if (unlikely(skb == NULL))
+               return -ENOMEM;
+
+       mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size,
+                                PCI_DMA_FROMDEVICE);
+       if (unlikely(dma_mapping_error(mapping))) {
+
+               dev_kfree_skb(skb);
+               return -ENOMEM;
+       }
+
+       rx_buf->skb = skb;
+       pci_unmap_addr_set(rx_buf, mapping, mapping);
+
+       rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+       rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+
+       return 0;
+}
+
+/* note that we are not allocating a new skb,
+ * we are just moving one from cons to prod
+ * we are not creating a new mapping,
+ * so there is no need to check for dma_mapping_error().
+ */
+static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp,
+                              struct sk_buff *skb, u16 cons, u16 prod)
+{
+       struct bnx2x *bp = fp->bp;
+       struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons];
+       struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod];
+       struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons];
+       struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod];
+
+       pci_dma_sync_single_for_device(bp->pdev,
+                                      pci_unmap_addr(cons_rx_buf, mapping),
+                                      bp->rx_offset + RX_COPY_THRESH,
+                                      PCI_DMA_FROMDEVICE);
+
+       prod_rx_buf->skb = cons_rx_buf->skb;
+       pci_unmap_addr_set(prod_rx_buf, mapping,
+                          pci_unmap_addr(cons_rx_buf, mapping));
+       *prod_bd = *cons_bd;
+}
+
+static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
+{
+       struct bnx2x *bp = fp->bp;
+       u16 bd_cons, bd_prod, comp_ring_cons;
+       u16 hw_comp_cons, sw_comp_cons, sw_comp_prod;
+       int rx_pkt = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return 0;
+#endif
+
+       hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb);
+       if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT)
+               hw_comp_cons++;
+
+       bd_cons = fp->rx_bd_cons;
+       bd_prod = fp->rx_bd_prod;
+       sw_comp_cons = fp->rx_comp_cons;
+       sw_comp_prod = fp->rx_comp_prod;
+
+       /* Memory barrier necessary as speculative reads of the rx
+        * buffer can be ahead of the index in the status block
+        */
+       rmb();
+
+       DP(NETIF_MSG_RX_STATUS,
+          "queue[%d]:  hw_comp_cons %u  sw_comp_cons %u\n",
+          fp->index, hw_comp_cons, sw_comp_cons);
+
+       while (sw_comp_cons != hw_comp_cons) {
+               unsigned int len, pad;
+               struct sw_rx_bd *rx_buf;
+               struct sk_buff *skb;
+               union eth_rx_cqe *cqe;
+
+               comp_ring_cons = RCQ_BD(sw_comp_cons);
+               bd_prod = RX_BD(bd_prod);
+               bd_cons = RX_BD(bd_cons);
+
+               cqe = &fp->rx_comp_ring[comp_ring_cons];
+
+               DP(NETIF_MSG_RX_STATUS, "hw_comp_cons %u  sw_comp_cons %u"
+                  "  comp_ring (%u)  bd_ring (%u,%u)\n",
+                  hw_comp_cons, sw_comp_cons,
+                  comp_ring_cons, bd_prod, bd_cons);
+               DP(NETIF_MSG_RX_STATUS, "CQE type %x  err %x  status %x"
+                  "  queue %x  vlan %x  len %x\n",
+                  cqe->fast_path_cqe.type,
+                  cqe->fast_path_cqe.error_type_flags,
+                  cqe->fast_path_cqe.status_flags,
+                  cqe->fast_path_cqe.rss_hash_result,
+                  cqe->fast_path_cqe.vlan_tag, cqe->fast_path_cqe.pkt_len);
+
+               /* is this a slowpath msg? */
+               if (unlikely(cqe->fast_path_cqe.type)) {
+                       bnx2x_sp_event(fp, cqe);
+                       goto next_cqe;
+
+               /* this is an rx packet */
+               } else {
+                       rx_buf = &fp->rx_buf_ring[bd_cons];
+                       skb = rx_buf->skb;
+
+                       len = le16_to_cpu(cqe->fast_path_cqe.pkt_len);
+                       pad = cqe->fast_path_cqe.placement_offset;
+
+                       pci_dma_sync_single_for_device(bp->pdev,
+                                       pci_unmap_addr(rx_buf, mapping),
+                                                      pad + RX_COPY_THRESH,
+                                                      PCI_DMA_FROMDEVICE);
+                       prefetch(skb);
+                       prefetch(((char *)(skb)) + 128);
+
+                       /* is this an error packet? */
+                       if (unlikely(cqe->fast_path_cqe.error_type_flags &
+                                                       ETH_RX_ERROR_FALGS)) {
+                       /* do we sometimes forward error packets anyway? */
+                               DP(NETIF_MSG_RX_ERR,
+                                  "ERROR flags(%u) Rx packet(%u)\n",
+                                  cqe->fast_path_cqe.error_type_flags,
+                                  sw_comp_cons);
+                               /* TBD make sure MC counts this as a drop */
+                               goto reuse_rx;
+                       }
+
+                       /* Since we don't have a jumbo ring
+                        * copy small packets if mtu > 1500
+                        */
+                       if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) &&
+                           (len <= RX_COPY_THRESH)) {
+                               struct sk_buff *new_skb;
+
+                               new_skb = netdev_alloc_skb(bp->dev,
+                                                          len + pad);
+                               if (new_skb == NULL) {
+                                       DP(NETIF_MSG_RX_ERR,
+                                          "ERROR packet dropped "
+                                          "because of alloc failure\n");
+                                       /* TBD count this as a drop? */
+                                       goto reuse_rx;
+                               }
+
+                               /* aligned copy */
+                               skb_copy_from_linear_data_offset(skb, pad,
+                                                   new_skb->data + pad, len);
+                               skb_reserve(new_skb, pad);
+                               skb_put(new_skb, len);
+
+                               bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+
+                               skb = new_skb;
+
+                       } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) {
+                               pci_unmap_single(bp->pdev,
+                                       pci_unmap_addr(rx_buf, mapping),
+                                                bp->rx_buf_use_size,
+                                                PCI_DMA_FROMDEVICE);
+                               skb_reserve(skb, pad);
+                               skb_put(skb, len);
+
+                       } else {
+                               DP(NETIF_MSG_RX_ERR,
+                                  "ERROR packet dropped because "
+                                  "of alloc failure\n");
+reuse_rx:
+                               bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod);
+                               goto next_rx;
+                       }
+
+                       skb->protocol = eth_type_trans(skb, bp->dev);
+
+                       skb->ip_summed = CHECKSUM_NONE;
+                       if (bp->rx_csum && BNX2X_RX_SUM_OK(cqe))
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+                       /* TBD do we pass bad csum packets in promisc */
+               }
+
+#ifdef BCM_VLAN
+               if ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags)
+                               & PARSING_FLAGS_NUMBER_OF_NESTED_VLANS)
+                   && (bp->vlgrp != NULL))
+                       vlan_hwaccel_receive_skb(skb, bp->vlgrp,
+                               le16_to_cpu(cqe->fast_path_cqe.vlan_tag));
+               else
+#endif
+               netif_receive_skb(skb);
+
+               bp->dev->last_rx = jiffies;
+
+next_rx:
+               rx_buf->skb = NULL;
+
+               bd_cons = NEXT_RX_IDX(bd_cons);
+               bd_prod = NEXT_RX_IDX(bd_prod);
+next_cqe:
+               sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod);
+               sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons);
+               rx_pkt++;
+
+               if ((rx_pkt == budget))
+                       break;
+       } /* while */
+
+       fp->rx_bd_cons = bd_cons;
+       fp->rx_bd_prod = bd_prod;
+       fp->rx_comp_cons = sw_comp_cons;
+       fp->rx_comp_prod = sw_comp_prod;
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_RCQ_PROD_OFFSET(bp->port, fp->index), sw_comp_prod);
+
+       mmiowb(); /* keep prod updates ordered */
+
+       fp->rx_pkt += rx_pkt;
+       fp->rx_calls++;
+
+       return rx_pkt;
+}
+
+static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie)
+{
+       struct bnx2x_fastpath *fp = fp_cookie;
+       struct bnx2x *bp = fp->bp;
+       struct net_device *dev = bp->dev;
+       int index = fp->index;
+
+       DP(NETIF_MSG_INTR, "got an msix interrupt on [%d]\n", index);
+       bnx2x_ack_sb(bp, index, USTORM_ID, 0, IGU_INT_DISABLE, 0);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return IRQ_HANDLED;
+#endif
+
+       prefetch(fp->rx_cons_sb);
+       prefetch(fp->tx_cons_sb);
+       prefetch(&fp->status_blk->c_status_block.status_block_index);
+       prefetch(&fp->status_blk->u_status_block.status_block_index);
+
+       netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi));
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2x *bp = netdev_priv(dev);
+       u16 status = bnx2x_ack_int(bp);
+
+       if (unlikely(status == 0)) {
+               DP(NETIF_MSG_INTR, "not our interrupt!\n");
+               return IRQ_NONE;
+       }
+
+       DP(NETIF_MSG_INTR, "got an interrupt status is %u\n", status);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return IRQ_HANDLED;
+#endif
+
+       /* Return here if interrupt is shared and is disabled */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+               DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+               return IRQ_HANDLED;
+       }
+
+       if (status & 0x2) {
+               struct bnx2x_fastpath *fp = &bp->fp[0];
+
+               prefetch(fp->rx_cons_sb);
+               prefetch(fp->tx_cons_sb);
+               prefetch(&fp->status_blk->c_status_block.status_block_index);
+               prefetch(&fp->status_blk->u_status_block.status_block_index);
+
+               netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi));
+
+               status &= ~0x2;
+               if (!status)
+                       return IRQ_HANDLED;
+       }
+
+       if (unlikely(status & 0x1)) {
+
+               schedule_work(&bp->sp_task);
+
+               status &= ~0x1;
+               if (!status)
+                       return IRQ_HANDLED;
+       }
+
+       DP(NETIF_MSG_INTR, "got an unknown interrupt! (status is %u)\n",
+          status);
+
+       return IRQ_HANDLED;
+}
+
+/* end of fast path */
+
+/* PHY/MAC */
+
+/*
+ * General service functions
+ */
+
+static void bnx2x_leds_set(struct bnx2x *bp, unsigned int speed)
+{
+       int port = bp->port;
+
+       NIG_WR(NIG_REG_LED_MODE_P0 + port*4,
+              ((bp->hw_config & SHARED_HW_CFG_LED_MODE_MASK) >>
+               SHARED_HW_CFG_LED_MODE_SHIFT));
+       NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
+
+       /* Set blinking rate to ~15.9Hz */
+       NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
+              LED_BLINK_RATE_VAL);
+       NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + port*4, 1);
+
+       /* On Ax chip versions for speeds less than 10G
+          LED scheme is different */
+       if ((CHIP_REV(bp) == CHIP_REV_Ax) && (speed < SPEED_10000)) {
+               NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 1);
+               NIG_WR(NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, 0);
+               NIG_WR(NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + port*4, 1);
+       }
+}
+
+static void bnx2x_leds_unset(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       NIG_WR(NIG_REG_LED_10G_P0 + port*4, 0);
+       NIG_WR(NIG_REG_LED_MODE_P0 + port*4, SHARED_HW_CFG_LED_MAC1);
+}
+
+static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
+{
+       u32 val = REG_RD(bp, reg);
+
+       val |= bits;
+       REG_WR(bp, reg, val);
+       return val;
+}
+
+static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
+{
+       u32 val = REG_RD(bp, reg);
+
+       val &= ~bits;
+       REG_WR(bp, reg, val);
+       return val;
+}
+
+static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val)
+{
+       int rc;
+       u32 tmp, i;
+       int port = bp->port;
+       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+/*      DP(NETIF_MSG_HW, "phy_addr 0x%x  reg 0x%x  val 0x%08x\n",
+          bp->phy_addr, reg, val); */
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               udelay(40);
+       }
+
+       tmp = ((bp->phy_addr << 21) | (reg << 16) |
+              (val & EMAC_MDIO_COMM_DATA) |
+              EMAC_MDIO_COMM_COMMAND_WRITE_22 |
+              EMAC_MDIO_COMM_START_BUSY);
+       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+                       udelay(5);
+                       break;
+               }
+       }
+
+       if (tmp & EMAC_MDIO_COMM_START_BUSY) {
+               BNX2X_ERR("write phy register failed\n");
+
+               rc = -EBUSY;
+       } else {
+               rc = 0;
+       }
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               tmp |= EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+       }
+
+       return rc;
+}
+
+static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val)
+{
+       int port = bp->port;
+       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+       u32 val, i;
+       int rc;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               val &= ~EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               udelay(40);
+       }
+
+       val = ((bp->phy_addr << 21) | (reg << 16) |
+              EMAC_MDIO_COMM_COMMAND_READ_22 |
+              EMAC_MDIO_COMM_START_BUSY);
+       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+                       val &= EMAC_MDIO_COMM_DATA;
+                       break;
+               }
+       }
+
+       if (val & EMAC_MDIO_COMM_START_BUSY) {
+               BNX2X_ERR("read phy register failed\n");
+
+               *ret_val = 0x0;
+               rc = -EBUSY;
+       } else {
+               *ret_val = val;
+               rc = 0;
+       }
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               val |= EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+       }
+
+/*      DP(NETIF_MSG_HW, "phy_addr 0x%x  reg 0x%x  ret_val 0x%08x\n",
+          bp->phy_addr, reg, *ret_val); */
+
+       return rc;
+}
+
+static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+{
+       int rc = 0;
+       u32 tmp, i;
+       int port = bp->port;
+       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               tmp &= ~EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               udelay(40);
+       }
+
+       /* set clause 45 mode */
+       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       tmp |= EMAC_MDIO_MODE_CLAUSE_45;
+       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+
+       /* address */
+       tmp = ((bp->phy_addr << 21) | (reg << 16) | addr |
+              EMAC_MDIO_COMM_COMMAND_ADDRESS |
+              EMAC_MDIO_COMM_START_BUSY);
+       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+                       udelay(5);
+                       break;
+               }
+       }
+
+       if (tmp & EMAC_MDIO_COMM_START_BUSY) {
+               BNX2X_ERR("write phy register failed\n");
+
+               rc = -EBUSY;
+       } else {
+               /* data */
+               tmp = ((bp->phy_addr << 21) | (reg << 16) | val |
+                      EMAC_MDIO_COMM_COMMAND_WRITE_45 |
+                      EMAC_MDIO_COMM_START_BUSY);
+               EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp);
+
+               for (i = 0; i < 50; i++) {
+                       udelay(10);
+
+                       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+                       if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
+                               udelay(5);
+                               break;
+                       }
+               }
+
+               if (tmp & EMAC_MDIO_COMM_START_BUSY) {
+                       BNX2X_ERR("write phy register failed\n");
+
+                       rc = -EBUSY;
+               }
+       }
+
+       /* unset clause 45 mode */
+       tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       tmp &= ~EMAC_MDIO_MODE_CLAUSE_45;
+       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               tmp |= EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp);
+       }
+
+       return rc;
+}
+
+static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr,
+                            u32 *ret_val)
+{
+       int port = bp->port;
+       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+       u32 val, i;
+       int rc = 0;
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               val &= ~EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+               REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               udelay(40);
+       }
+
+       /* set clause 45 mode */
+       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       val |= EMAC_MDIO_MODE_CLAUSE_45;
+       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+
+       /* address */
+       val = ((bp->phy_addr << 21) | (reg << 16) | addr |
+              EMAC_MDIO_COMM_COMMAND_ADDRESS |
+              EMAC_MDIO_COMM_START_BUSY);
+       EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+
+       for (i = 0; i < 50; i++) {
+               udelay(10);
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+               if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+                       udelay(5);
+                       break;
+               }
+       }
+
+       if (val & EMAC_MDIO_COMM_START_BUSY) {
+               BNX2X_ERR("read phy register failed\n");
+
+               *ret_val = 0;
+               rc = -EBUSY;
+       } else {
+               /* data */
+               val = ((bp->phy_addr << 21) | (reg << 16) |
+                      EMAC_MDIO_COMM_COMMAND_READ_45 |
+                      EMAC_MDIO_COMM_START_BUSY);
+               EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val);
+
+               for (i = 0; i < 50; i++) {
+                       udelay(10);
+
+                       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM);
+                       if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
+                               val &= EMAC_MDIO_COMM_DATA;
+                               break;
+                       }
+               }
+
+               if (val & EMAC_MDIO_COMM_START_BUSY) {
+                       BNX2X_ERR("read phy register failed\n");
+
+                       val = 0;
+                       rc = -EBUSY;
+               }
+
+               *ret_val = val;
+       }
+
+       /* unset clause 45 mode */
+       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+       val &= ~EMAC_MDIO_MODE_CLAUSE_45;
+       EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+
+       if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) {
+
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
+               val |= EMAC_MDIO_MODE_AUTO_POLL;
+               EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val);
+       }
+
+       return rc;
+}
+
+static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val)
+{
+       int i;
+       u32 rd_val;
+
+       might_sleep();
+       for (i = 0; i < 10; i++) {
+               bnx2x_mdio45_write(bp, reg, addr, val);
+               msleep(5);
+               bnx2x_mdio45_read(bp, reg, addr, &rd_val);
+               /* if the read value is not the same as the value we wrote,
+                  we should write it again */
+               if (rd_val == val)
+                       return 0;
+       }
+       BNX2X_ERR("MDIO write in CL45 failed\n");
+       return -EBUSY;
+}
+
+/*
+ * link managment
+ */
+
+static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status)
+{
+       u32 ld_pause;   /* local driver */
+       u32 lp_pause;   /* link partner */
+       u32 pause_result;
+
+       bp->flow_ctrl = 0;
+
+       /* reolve from gp_status in case of AN complete and not sgmii */
+       if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) &&
+           (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
+           (!(bp->phy_flags & PHY_SGMII_FLAG)) &&
+           (XGXS_EXT_PHY_TYPE(bp) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
+
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+               bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
+                                 &ld_pause);
+               bnx2x_mdio22_read(bp,
+                       MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
+                                 &lp_pause);
+               pause_result = (ld_pause &
+                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
+               pause_result |= (lp_pause &
+                                MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
+               DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
+
+               switch (pause_result) {                 /* ASYM P ASYM P */
+               case 0xb:                               /*   1  0   1  1 */
+                       bp->flow_ctrl = FLOW_CTRL_TX;
+                       break;
+
+               case 0xe:                               /*   1  1   1  0 */
+                       bp->flow_ctrl = FLOW_CTRL_RX;
+                       break;
+
+               case 0x5:                               /*   0  1   0  1 */
+               case 0x7:                               /*   0  1   1  1 */
+               case 0xd:                               /*   1  1   0  1 */
+               case 0xf:                               /*   1  1   1  1 */
+                       bp->flow_ctrl = FLOW_CTRL_BOTH;
+                       break;
+
+               default:
+                       break;
+               }
+
+       } else { /* forced mode */
+               switch (bp->req_flow_ctrl) {
+               case FLOW_CTRL_AUTO:
+                       if (bp->dev->mtu <= 4500)
+                               bp->flow_ctrl = FLOW_CTRL_BOTH;
+                       else
+                               bp->flow_ctrl = FLOW_CTRL_TX;
+                       break;
+
+               case FLOW_CTRL_TX:
+               case FLOW_CTRL_RX:
+               case FLOW_CTRL_BOTH:
+                       bp->flow_ctrl = bp->req_flow_ctrl;
+                       break;
+
+               case FLOW_CTRL_NONE:
+               default:
+                       break;
+               }
+       }
+       DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl);
+}
+
+static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status)
+{
+       bp->link_status = 0;
+
+       if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
+               DP(NETIF_MSG_LINK, "link up\n");
+
+               bp->link_up = 1;
+               bp->link_status |= LINK_STATUS_LINK_UP;
+
+               if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
+                       bp->duplex = DUPLEX_FULL;
+               else
+                       bp->duplex = DUPLEX_HALF;
+
+               bnx2x_flow_ctrl_resolve(bp, gp_status);
+
+               switch (gp_status & GP_STATUS_SPEED_MASK) {
+               case GP_STATUS_10M:
+                       bp->line_speed = SPEED_10;
+                       if (bp->duplex == DUPLEX_FULL)
+                               bp->link_status |= LINK_10TFD;
+                       else
+                               bp->link_status |= LINK_10THD;
+                       break;
+
+               case GP_STATUS_100M:
+                       bp->line_speed = SPEED_100;
+                       if (bp->duplex == DUPLEX_FULL)
+                               bp->link_status |= LINK_100TXFD;
+                       else
+                               bp->link_status |= LINK_100TXHD;
+                       break;
+
+               case GP_STATUS_1G:
+               case GP_STATUS_1G_KX:
+                       bp->line_speed = SPEED_1000;
+                       if (bp->duplex == DUPLEX_FULL)
+                               bp->link_status |= LINK_1000TFD;
+                       else
+                               bp->link_status |= LINK_1000THD;
+                       break;
+
+               case GP_STATUS_2_5G:
+                       bp->line_speed = SPEED_2500;
+                       if (bp->duplex == DUPLEX_FULL)
+                               bp->link_status |= LINK_2500TFD;
+                       else
+                               bp->link_status |= LINK_2500THD;
+                       break;
+
+               case GP_STATUS_5G:
+               case GP_STATUS_6G:
+                       BNX2X_ERR("link speed unsupported  gp_status 0x%x\n",
+                                 gp_status);
+                       break;
+
+               case GP_STATUS_10G_KX4:
+               case GP_STATUS_10G_HIG:
+               case GP_STATUS_10G_CX4:
+                       bp->line_speed = SPEED_10000;
+                       bp->link_status |= LINK_10GTFD;
+                       break;
+
+               case GP_STATUS_12G_HIG:
+                       bp->line_speed = SPEED_12000;
+                       bp->link_status |= LINK_12GTFD;
+                       break;
+
+               case GP_STATUS_12_5G:
+                       bp->line_speed = SPEED_12500;
+                       bp->link_status |= LINK_12_5GTFD;
+                       break;
+
+               case GP_STATUS_13G:
+                       bp->line_speed = SPEED_13000;
+                       bp->link_status |= LINK_13GTFD;
+                       break;
+
+               case GP_STATUS_15G:
+                       bp->line_speed = SPEED_15000;
+                       bp->link_status |= LINK_15GTFD;
+                       break;
+
+               case GP_STATUS_16G:
+                       bp->line_speed = SPEED_16000;
+                       bp->link_status |= LINK_16GTFD;
+                       break;
+
+               default:
+                       BNX2X_ERR("link speed unsupported  gp_status 0x%x\n",
+                                 gp_status);
+                       break;
+               }
+
+               bp->link_status |= LINK_STATUS_SERDES_LINK;
+
+               if (bp->req_autoneg & AUTONEG_SPEED) {
+                       bp->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
+
+                       if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
+                               bp->link_status |=
+                                       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
+
+                       if (bp->autoneg & AUTONEG_PARALLEL)
+                               bp->link_status |=
+                                       LINK_STATUS_PARALLEL_DETECTION_USED;
+               }
+
+               if (bp->flow_ctrl & FLOW_CTRL_TX)
+                      bp->link_status |= LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
+
+               if (bp->flow_ctrl & FLOW_CTRL_RX)
+                      bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
+
+       } else { /* link_down */
+               DP(NETIF_MSG_LINK, "link down\n");
+
+               bp->link_up = 0;
+
+               bp->line_speed = 0;
+               bp->duplex = DUPLEX_FULL;
+               bp->flow_ctrl = 0;
+       }
+
+       DP(NETIF_MSG_LINK, "gp_status 0x%x  link_up %d\n"
+          DP_LEVEL "  line_speed %d  duplex %d  flow_ctrl 0x%x"
+                   "  link_status 0x%x\n",
+          gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl,
+          bp->link_status);
+}
+
+static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g)
+{
+       int port = bp->port;
+
+       /* first reset all status
+        * we asume only one line will be change at a time */
+       bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+                      (NIG_XGXS0_LINK_STATUS |
+                       NIG_SERDES0_LINK_STATUS |
+                       NIG_STATUS_INTERRUPT_XGXS0_LINK10G));
+       if (bp->link_up) {
+               if (is_10g) {
+                       /* Disable the 10G link interrupt
+                        * by writing 1 to the status register
+                        */
+                       DP(NETIF_MSG_LINK, "10G XGXS link up\n");
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+                                     NIG_STATUS_INTERRUPT_XGXS0_LINK10G);
+
+               } else if (bp->phy_flags & PHY_XGXS_FLAG) {
+                       /* Disable the link interrupt
+                        * by writing 1 to the relevant lane
+                        * in the status register
+                        */
+                       DP(NETIF_MSG_LINK, "1G XGXS link up\n");
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+                                     ((1 << bp->ser_lane) <<
+                                      NIG_XGXS0_LINK_STATUS_SIZE));
+
+               } else { /* SerDes */
+                       DP(NETIF_MSG_LINK, "SerDes link up\n");
+                       /* Disable the link interrupt
+                        * by writing 1 to the status register
+                        */
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+                                     NIG_SERDES0_LINK_STATUS);
+               }
+
+       } else { /* link_down */
+       }
+}
+
+static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp)
+{
+       u32 ext_phy_type;
+       u32 ext_phy_addr;
+       u32 local_phy;
+       u32 val = 0;
+       u32 rx_sd, pcs_status;
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               local_phy = bp->phy_addr;
+               ext_phy_addr = ((bp->ext_phy_config &
+                                PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+               bp->phy_addr = (u8)ext_phy_addr;
+
+               ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "XGXS Direct\n");
+                       val = 1;
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+                       DP(NETIF_MSG_LINK, "XGXS 8705\n");
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val);
+                       DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
+
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val);
+                       DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val);
+
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
+                       val = (rx_sd & 0x1);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+                       DP(NETIF_MSG_LINK, "XGXS 8706\n");
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val);
+                       DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
+
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_LASI_STATUS, &val);
+                       DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val);
+
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                         EXT_PHY_OPT_PMD_RX_SD, &rx_sd);
+                       bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD,
+                                        EXT_PHY_OPT_PCS_STATUS, &pcs_status);
+                       DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
+                          "  pcs_status 0x%x\n", rx_sd, pcs_status);
+                       /* link is up if both bit 0 of pmd_rx and
+                        * bit 0 of pcs_status are set
+                        */
+                       val = (rx_sd & pcs_status);
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       val = 0;
+                       break;
+               }
+               bp->phy_addr = local_phy;
+
+       } else { /* SerDes */
+               ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "SerDes Direct\n");
+                       val = 1;
+                       break;
+
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+                       DP(NETIF_MSG_LINK, "SerDes 5482\n");
+                       val = 1;
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       val = 0;
+                       break;
+               }
+       }
+
+       return val;
+}
+
+static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb)
+{
+       int port = bp->port;
+       u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
+                              NIG_REG_INGRESS_BMAC0_MEM;
+       u32 wb_write[2];
+       u32 val;
+
+       DP(NETIF_MSG_LINK, "enableing BigMAC\n");
+       /* reset and unreset the BigMac */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+       msleep(5);
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+       /* enable access for bmac registers */
+       NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
+
+       /* XGXS control */
+       wb_write[0] = 0x3c;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
+                   wb_write, 2);
+
+       /* tx MAC SA */
+       wb_write[0] = ((bp->dev->dev_addr[2] << 24) |
+                      (bp->dev->dev_addr[3] << 16) |
+                      (bp->dev->dev_addr[4] << 8) |
+                       bp->dev->dev_addr[5]);
+       wb_write[1] = ((bp->dev->dev_addr[0] << 8) |
+                       bp->dev->dev_addr[1]);
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
+                   wb_write, 2);
+
+       /* tx control */
+       val = 0xc0;
+       if (bp->flow_ctrl & FLOW_CTRL_TX)
+               val |= 0x800000;
+       wb_write[0] = val;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_write, 2);
+
+       /* set tx mtu */
+       wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -CRC */
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_write, 2);
+
+       /* mac control */
+       val = 0x3;
+       if (is_lb) {
+               val |= 0x4;
+               DP(NETIF_MSG_LINK, "enable bmac loopback\n");
+       }
+       wb_write[0] = val;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
+                   wb_write, 2);
+
+       /* rx control set to don't strip crc */
+       val = 0x14;
+       if (bp->flow_ctrl & FLOW_CTRL_RX)
+               val |= 0x20;
+       wb_write[0] = val;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_write, 2);
+
+       /* set rx mtu */
+       wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_write, 2);
+
+       /* set cnt max size */
+       wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -VLAN */
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
+                   wb_write, 2);
+
+       /* configure safc */
+       wb_write[0] = 0x1000200;
+       wb_write[1] = 0;
+       REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
+                   wb_write, 2);
+
+       /* fix for emulation */
+       if (CHIP_REV(bp) == CHIP_REV_EMUL) {
+               wb_write[0] = 0xf000;
+               wb_write[1] = 0;
+               REG_WR_DMAE(bp,
+                           bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
+                           wb_write, 2);
+       }
+
+       /* reset old bmac stats */
+       memset(&bp->old_bmac, 0, sizeof(struct bmac_stats));
+
+       NIG_WR(NIG_REG_XCM0_OUT_EN + port*4, 0x0);
+
+       /* select XGXS */
+       NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
+       NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
+
+       /* disable the NIG in/out to the emac */
+       NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x0);
+       NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
+       NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
+
+       /* enable the NIG in/out to the bmac */
+       NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
+
+       NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x1);
+       val = 0;
+       if (bp->flow_ctrl & FLOW_CTRL_TX)
+               val = 1;
+       NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
+       NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
+
+       bp->phy_flags |= PHY_BMAC_FLAG;
+
+       bp->stats_state = STATS_STATE_ENABLE;
+}
+
+static void bnx2x_emac_enable(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
+       u32 val;
+       int timeout;
+
+       DP(NETIF_MSG_LINK, "enableing EMAC\n");
+       /* reset and unreset the emac core */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+              (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
+       msleep(5);
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+              (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
+
+       /* enable emac and not bmac */
+       NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
+
+       /* for paladium */
+       if (CHIP_REV(bp) == CHIP_REV_EMUL) {
+               /* Use lane 1 (of lanes 0-3) */
+               NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
+               NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
+       }
+       /* for fpga */
+       else if (CHIP_REV(bp) == CHIP_REV_FPGA) {
+               /* Use lane 1 (of lanes 0-3) */
+               NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
+               NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
+       }
+       /* ASIC */
+       else {
+               if (bp->phy_flags & PHY_XGXS_FLAG) {
+                       DP(NETIF_MSG_LINK, "XGXS\n");
+                       /* select the master lanes (out of 0-3) */
+                       NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4,
+                              bp->ser_lane);
+                       /* select XGXS */
+                       NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
+
+               } else { /* SerDes */
+                       DP(NETIF_MSG_LINK, "SerDes\n");
+                       /* select SerDes */
+                       NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
+               }
+       }
+
+       /* enable emac */
+       NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 1);
+
+       /* init emac - use read-modify-write */
+       /* self clear reset */
+       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+       EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
+
+       timeout = 200;
+       while (val & EMAC_MODE_RESET) {
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+               DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
+               if (!timeout) {
+                       BNX2X_ERR("EMAC timeout!\n");
+                       break;
+               }
+               timeout--;
+       }
+
+       /* reset tx part */
+       EMAC_WR(EMAC_REG_EMAC_TX_MODE, EMAC_TX_MODE_RESET);
+
+       timeout = 200;
+       while (val & EMAC_TX_MODE_RESET) {
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_TX_MODE);
+               DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
+               if (!timeout) {
+                       BNX2X_ERR("EMAC timeout!\n");
+                       break;
+               }
+               timeout--;
+       }
+
+       if (CHIP_REV_IS_SLOW(bp)) {
+               /* config GMII mode */
+               val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+               EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
+
+       } else { /* ASIC */
+               /* pause enable/disable */
+               bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+                              EMAC_RX_MODE_FLOW_EN);
+               if (bp->flow_ctrl & FLOW_CTRL_RX)
+                       bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
+                                     EMAC_RX_MODE_FLOW_EN);
+
+               bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+                              EMAC_TX_MODE_EXT_PAUSE_EN);
+               if (bp->flow_ctrl & FLOW_CTRL_TX)
+                       bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
+                                     EMAC_TX_MODE_EXT_PAUSE_EN);
+       }
+
+       /* KEEP_VLAN_TAG, promiscous */
+       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
+       val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
+       EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
+
+       /* identify magic packets */
+       val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
+       EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_MPKT));
+
+       /* enable emac for jumbo packets */
+       EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
+               (EMAC_RX_MTU_SIZE_JUMBO_ENA |
+                (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); /* -VLAN */
+
+       /* strip CRC */
+       NIG_WR(NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
+
+       val = ((bp->dev->dev_addr[0] << 8) |
+               bp->dev->dev_addr[1]);
+       EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
+
+       val = ((bp->dev->dev_addr[2] << 24) |
+              (bp->dev->dev_addr[3] << 16) |
+              (bp->dev->dev_addr[4] << 8) |
+               bp->dev->dev_addr[5]);
+       EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
+
+       /* disable the NIG in/out to the bmac */
+       NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x0);
+       NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
+       NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
+
+       /* enable the NIG in/out to the emac */
+       NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x1);
+       val = 0;
+       if (bp->flow_ctrl & FLOW_CTRL_TX)
+               val = 1;
+       NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
+       NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
+
+       if (CHIP_REV(bp) == CHIP_REV_FPGA) {
+               /* take the BigMac out of reset */
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
+                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+               /* enable access for bmac registers */
+               NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
+       }
+
+       bp->phy_flags |= PHY_EMAC_FLAG;
+
+       bp->stats_state = STATS_STATE_ENABLE;
+}
+
+static void bnx2x_emac_program(struct bnx2x *bp)
+{
+       u16 mode = 0;
+       int port = bp->port;
+
+       DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
+       bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
+                      (EMAC_MODE_25G_MODE |
+                       EMAC_MODE_PORT_MII_10M |
+                       EMAC_MODE_HALF_DUPLEX));
+       switch (bp->line_speed) {
+       case SPEED_10:
+               mode |= EMAC_MODE_PORT_MII_10M;
+               break;
+
+       case SPEED_100:
+               mode |= EMAC_MODE_PORT_MII;
+               break;
+
+       case SPEED_1000:
+               mode |= EMAC_MODE_PORT_GMII;
+               break;
+
+       case SPEED_2500:
+               mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
+               break;
+
+       default:
+               /* 10G not valid for EMAC */
+               BNX2X_ERR("Invalid line_speed 0x%x\n", bp->line_speed);
+               break;
+       }
+
+       if (bp->duplex == DUPLEX_HALF)
+               mode |= EMAC_MODE_HALF_DUPLEX;
+       bnx2x_bits_en(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
+                     mode);
+
+       bnx2x_leds_set(bp, bp->line_speed);
+}
+
+static void bnx2x_set_sgmii_tx_driver(struct bnx2x *bp)
+{
+       u32 lp_up2;
+       u32 tx_driver;
+
+       /* read precomp */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
+       bnx2x_mdio22_read(bp, MDIO_OVER_1G_LP_UP2, &lp_up2);
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_TX0);
+       bnx2x_mdio22_read(bp, MDIO_TX0_TX_DRIVER, &tx_driver);
+
+       /* bits [10:7] at lp_up2, positioned at [15:12] */
+       lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
+                  MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
+                 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
+
+       if ((lp_up2 != 0) &&
+           (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
+               /* replace tx_driver bits [15:12] */
+               tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
+               tx_driver |= lp_up2;
+               bnx2x_mdio22_write(bp, MDIO_TX0_TX_DRIVER, tx_driver);
+       }
+}
+
+static void bnx2x_pbf_update(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 init_crd, crd;
+       u32 count = 1000;
+       u32 pause = 0;
+
+
+       /* disable port */
+       REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
+
+       /* wait for init credit */
+       init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
+       crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+       DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
+
+       while ((init_crd != crd) && count) {
+               msleep(5);
+
+               crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+               count--;
+       }
+       crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
+       if (init_crd != crd)
+               BNX2X_ERR("BUG! init_crd 0x%x != crd 0x%x\n", init_crd, crd);
+
+       if (bp->flow_ctrl & FLOW_CTRL_RX)
+               pause = 1;
+       REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause);
+       if (pause) {
+               /* update threshold */
+               REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
+               /* update init credit */
+               init_crd = 778;         /* (800-18-4) */
+
+       } else {
+               u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)/16;
+
+               /* update threshold */
+               REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
+               /* update init credit */
+               switch (bp->line_speed) {
+               case SPEED_10:
+               case SPEED_100:
+               case SPEED_1000:
+                       init_crd = thresh + 55 - 22;
+                       break;
+
+               case SPEED_2500:
+                       init_crd = thresh + 138 - 22;
+                       break;
+
+               case SPEED_10000:
+                       init_crd = thresh + 553 - 22;
+                       break;
+
+               default:
+                       BNX2X_ERR("Invalid line_speed 0x%x\n",
+                                 bp->line_speed);
+                       break;
+               }
+       }
+       REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
+       DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
+          bp->line_speed, init_crd);
+
+       /* probe the credit changes */
+       REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
+       msleep(5);
+       REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
+
+       /* enable port */
+       REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
+}
+
+static void bnx2x_update_mng(struct bnx2x *bp)
+{
+       if (!nomcp)
+               SHMEM_WR(bp, drv_fw_mb[bp->port].link_status,
+                        bp->link_status);
+}
+
+static void bnx2x_link_report(struct bnx2x *bp)
+{
+       if (bp->link_up) {
+               netif_carrier_on(bp->dev);
+               printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name);
+
+               printk("%d Mbps ", bp->line_speed);
+
+               if (bp->duplex == DUPLEX_FULL)
+                       printk("full duplex");
+               else
+                       printk("half duplex");
+
+               if (bp->flow_ctrl) {
+                       if (bp->flow_ctrl & FLOW_CTRL_RX) {
+                               printk(", receive ");
+                               if (bp->flow_ctrl & FLOW_CTRL_TX)
+                                       printk("& transmit ");
+                       } else {
+                               printk(", transmit ");
+                       }
+                       printk("flow control ON");
+               }
+               printk("\n");
+
+       } else { /* link_down */
+               netif_carrier_off(bp->dev);
+               printk(KERN_INFO PFX "%s NIC Link is Down\n", bp->dev->name);
+       }
+}
+
+static void bnx2x_link_up(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       /* PBF - link up */
+       bnx2x_pbf_update(bp);
+
+       /* disable drain */
+       NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
+
+       /* update shared memory */
+       bnx2x_update_mng(bp);
+
+       /* indicate link up */
+       bnx2x_link_report(bp);
+}
+
+static void bnx2x_link_down(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       /* notify stats */
+       if (bp->stats_state != STATS_STATE_DISABLE) {
+               bp->stats_state = STATS_STATE_STOP;
+               DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
+       }
+
+       /* indicate link down */
+       bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG);
+
+       /* reset BigMac */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+              (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
+
+       /* ignore drain flag interrupt */
+       /* activate nig drain */
+       NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+
+       /* update shared memory */
+       bnx2x_update_mng(bp);
+
+       /* indicate link down */
+       bnx2x_link_report(bp);
+}
+
+static void bnx2x_init_mac_stats(struct bnx2x *bp);
+
+/* This function is called upon link interrupt */
+static void bnx2x_link_update(struct bnx2x *bp)
+{
+       u32 gp_status;
+       int port = bp->port;
+       int i;
+       int link_10g;
+
+       DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x,"
+          " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x,"
+          " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG),
+          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4),
+          REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask,
+          REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
+          REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c),
+          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
+          REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)
+       );
+
+       might_sleep();
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS);
+       /* avoid fast toggling */
+       for (i = 0 ; i < 10 ; i++) {
+               msleep(10);
+               bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1,
+                                 &gp_status);
+       }
+
+       bnx2x_link_settings_status(bp, gp_status);
+
+       /* anything 10 and over uses the bmac */
+       link_10g = ((bp->line_speed >= SPEED_10000) &&
+                   (bp->line_speed <= SPEED_16000));
+
+       bnx2x_link_int_ack(bp, link_10g);
+
+       /* link is up only if both local phy and external phy are up */
+       if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) {
+               if (link_10g) {
+                       bnx2x_bmac_enable(bp, 0);
+                       bnx2x_leds_set(bp, SPEED_10000);
+
+               } else {
+                       bnx2x_emac_enable(bp);
+                       bnx2x_emac_program(bp);
+
+                       /* AN complete? */
+                       if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
+                               if (!(bp->phy_flags & PHY_SGMII_FLAG))
+                                       bnx2x_set_sgmii_tx_driver(bp);
+                       }
+               }
+               bnx2x_link_up(bp);
+
+       } else { /* link down */
+               bnx2x_leds_unset(bp);
+               bnx2x_link_down(bp);
+       }
+
+       bnx2x_init_mac_stats(bp);
+}
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_set_aer_mmd(struct bnx2x *bp)
+{
+       u16 offset = (bp->phy_flags & PHY_XGXS_FLAG) ?
+                                       (bp->phy_addr + bp->ser_lane) : 0;
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK);
+       bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
+}
+
+static void bnx2x_set_master_ln(struct bnx2x *bp)
+{
+       u32 new_master_ln;
+
+       /* set the master_ln for AN */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+       bnx2x_mdio22_read(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
+                         &new_master_ln);
+       bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
+                          (new_master_ln | bp->ser_lane));
+}
+
+static void bnx2x_reset_unicore(struct bnx2x *bp)
+{
+       u32 mii_control;
+       int i;
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+       bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
+       /* reset the unicore */
+       bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                          (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET));
+
+       /* wait for the reset to self clear */
+       for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
+               udelay(5);
+
+               /* the reset erased the previous bank value */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+               bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                 &mii_control);
+
+               if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
+                       udelay(5);
+                       return;
+               }
+       }
+
+       BNX2X_ERR("BUG! unicore is still in reset!\n");
+}
+
+static void bnx2x_set_swap_lanes(struct bnx2x *bp)
+{
+       /* Each two bits represents a lane number:
+          No swap is 0123 => 0x1b no need to enable the swap */
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2);
+       if (bp->rx_lane_swap != 0x1b) {
+               bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP,
+                                  (bp->rx_lane_swap |
+                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
+                                  MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
+       } else {
+               bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
+       }
+
+       if (bp->tx_lane_swap != 0x1b) {
+               bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP,
+                                  (bp->tx_lane_swap |
+                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
+       } else {
+               bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
+       }
+}
+
+static void bnx2x_set_parallel_detection(struct bnx2x *bp)
+{
+       u32 control2;
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
+       bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
+                         &control2);
+
+       if (bp->autoneg & AUTONEG_PARALLEL) {
+               control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
+       } else {
+               control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
+       }
+       bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
+                          control2);
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               DP(NETIF_MSG_LINK, "XGXS\n");
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT);
+
+               bnx2x_mdio22_write(bp,
+                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
+                              MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
+
+               bnx2x_mdio22_read(bp,
+                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+                                 &control2);
+
+               if (bp->autoneg & AUTONEG_PARALLEL) {
+                       control2 |=
+                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
+               } else {
+                       control2 &=
+                  ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
+               }
+               bnx2x_mdio22_write(bp,
+                                MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
+                                  control2);
+       }
+}
+
+static void bnx2x_set_autoneg(struct bnx2x *bp)
+{
+       u32 reg_val;
+
+       /* CL37 Autoneg */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+       bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
+       if ((bp->req_autoneg & AUTONEG_SPEED) &&
+           (bp->autoneg & AUTONEG_CL37)) {
+               /* CL37 Autoneg Enabled */
+               reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
+       } else {
+               /* CL37 Autoneg Disabled */
+               reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+                            MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
+       }
+       bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
+
+       /* Enable/Disable Autodetection */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
+       bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
+       reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
+
+       if ((bp->req_autoneg & AUTONEG_SPEED) &&
+           (bp->autoneg & AUTONEG_SGMII_FIBER_AUTODET)) {
+               reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
+       } else {
+               reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
+       }
+       bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
+
+       /* Enable TetonII and BAM autoneg */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_BAM_NEXT_PAGE);
+       bnx2x_mdio22_read(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
+                         &reg_val);
+       if ((bp->req_autoneg & AUTONEG_SPEED) &&
+           (bp->autoneg & AUTONEG_CL37) && (bp->autoneg & AUTONEG_BAM)) {
+               /* Enable BAM aneg Mode and TetonII aneg Mode */
+               reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
+                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
+       } else {
+               /* TetonII and BAM Autoneg Disabled */
+               reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
+                            MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
+       }
+       bnx2x_mdio22_write(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
+                          reg_val);
+
+       /* Enable Clause 73 Aneg */
+       if ((bp->req_autoneg & AUTONEG_SPEED) &&
+           (bp->autoneg & AUTONEG_CL73)) {
+               /* Enable BAM Station Manager */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_USERB0);
+               bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL1,
+                                  (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
+                       MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
+                       MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
+
+               /* Merge CL73 and CL37 aneg resolution */
+               bnx2x_mdio22_read(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3,
+                                 &reg_val);
+               bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3,
+                                  (reg_val |
+                       MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
+
+               /* Set the CL73 AN speed */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB1);
+               bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
+               /* In the SerDes we support only the 1G.
+                  In the XGXS we support the 10G KX4
+                  but we currently do not support the KR */
+               if (bp->phy_flags & PHY_XGXS_FLAG) {
+                       DP(NETIF_MSG_LINK, "XGXS\n");
+                       /* 10G KX4 */
+                       reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
+               } else {
+                       DP(NETIF_MSG_LINK, "SerDes\n");
+                       /* 1000M KX */
+                       reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
+               }
+               bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
+
+               /* CL73 Autoneg Enabled */
+               reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
+       } else {
+               /* CL73 Autoneg Disabled */
+               reg_val = 0;
+       }
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
+       bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
+}
+
+/* program SerDes, forced speed */
+static void bnx2x_program_serdes(struct bnx2x *bp)
+{
+       u32 reg_val;
+
+       /* program duplex, disable autoneg */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+       bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
+       reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
+                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
+       if (bp->req_duplex == DUPLEX_FULL)
+               reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
+       bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
+
+       /* program speed
+          - needed only if the speed is greater than 1G (2.5G or 10G) */
+       if (bp->req_line_speed > SPEED_1000) {
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
+               bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_MISC1, &reg_val);
+               /* clearing the speed value before setting the right speed */
+               reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK;
+               reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
+                           MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
+               if (bp->req_line_speed == SPEED_10000)
+                       reg_val |=
+                               MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
+               bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_MISC1, reg_val);
+       }
+}
+
+static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp)
+{
+       u32 val = 0;
+
+       /* configure the 48 bits for BAM AN */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G);
+
+       /* set extended capabilities */
+       if (bp->advertising & ADVERTISED_2500baseT_Full)
+               val |= MDIO_OVER_1G_UP1_2_5G;
+       if (bp->advertising & ADVERTISED_10000baseT_Full)
+               val |= MDIO_OVER_1G_UP1_10G;
+       bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP1, val);
+
+       bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP3, 0);
+}
+
+static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp)
+{
+       u32 an_adv;
+
+       /* for AN, we are always publishing full duplex */
+       an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
+
+       /* set pause */
+       switch (bp->pause_mode) {
+       case PAUSE_SYMMETRIC:
+               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
+               break;
+       case PAUSE_ASYMMETRIC:
+               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+               break;
+       case PAUSE_BOTH:
+               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
+               break;
+       case PAUSE_NONE:
+               an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
+               break;
+       }
+
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+       bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv);
+}
+
+static void bnx2x_restart_autoneg(struct bnx2x *bp)
+{
+       if (bp->autoneg & AUTONEG_CL73) {
+               /* enable and restart clause 73 aneg */
+               u32 an_ctrl;
+
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
+               bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+                                 &an_ctrl);
+               bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+                                  (an_ctrl |
+                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
+                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
+
+       } else {
+               /* Enable and restart BAM/CL37 aneg */
+               u32 mii_control;
+
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+               bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                 &mii_control);
+               bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                  (mii_control |
+                                   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+                                   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
+       }
+}
+
+static void bnx2x_initialize_sgmii_process(struct bnx2x *bp)
+{
+       u32 control1;
+
+       /* in SGMII mode, the unicore is always slave */
+       MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL);
+       bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
+                         &control1);
+       control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
+       /* set sgmii mode (and not fiber) */
+       control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
+                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
+                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
+       bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
+                          control1);
+
+       /* if forced speed */
+       if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+               /* set speed, disable autoneg */
+               u32 mii_control;
+
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+               bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                 &mii_control);
+               mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
+                              MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK |
+                                MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
+
+               switch (bp->req_line_speed) {
+               case SPEED_100:
+                       mii_control |=
+                               MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
+                       break;
+               case SPEED_1000:
+                       mii_control |=
+                               MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
+                       break;
+               case SPEED_10:
+                       /* there is nothing to set for 10M */
+                       break;
+               default:
+                       /* invalid speed for SGMII */
+                       DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n",
+                          bp->req_line_speed);
+                       break;
+               }
+
+               /* setting the full duplex */
+               if (bp->req_duplex == DUPLEX_FULL)
+                       mii_control |=
+                               MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
+               bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                  mii_control);
+
+       } else { /* AN mode */
+               /* enable and restart AN */
+               bnx2x_restart_autoneg(bp);
+       }
+}
+
+static void bnx2x_link_int_enable(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       /* setting the status to report on link up
+          for either XGXS or SerDes */
+       bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
+                      (NIG_XGXS0_LINK_STATUS |
+                       NIG_STATUS_INTERRUPT_XGXS0_LINK10G |
+                       NIG_SERDES0_LINK_STATUS));
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               /* TBD -
+                * in force mode (not AN) we can enable just the relevant
+                * interrupt
+                * Even in AN we might enable only one according to the AN
+                * speed mask
+                */
+               bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                             (NIG_MASK_XGXS0_LINK_STATUS |
+                              NIG_MASK_XGXS0_LINK10G));
+               DP(NETIF_MSG_LINK, "enable XGXS interrupt\n");
+
+       } else { /* SerDes */
+               bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                             NIG_MASK_SERDES0_LINK_STATUS);
+               DP(NETIF_MSG_LINK, "enable SerDes interrupt\n");
+       }
+}
+
+static void bnx2x_ext_phy_init(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 ext_phy_type;
+       u32 ext_phy_addr;
+       u32 local_phy;
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               local_phy = bp->phy_addr;
+               ext_phy_addr = ((bp->ext_phy_config &
+                                PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+
+               ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "XGXS Direct\n");
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+                       DP(NETIF_MSG_LINK, "XGXS 8705\n");
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                                     NIG_MASK_MI_INT);
+                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
+
+                       bp->phy_addr = ext_phy_type;
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           EXT_PHY_OPT_PMD_MISC_CNTL,
+                                           0x8288);
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           EXT_PHY_OPT_PHY_IDENTIFIER,
+                                           0x7fbf);
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           EXT_PHY_OPT_CMU_PLL_BYPASS,
+                                           0x0100);
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD,
+                                           EXT_PHY_OPT_LASI_CNTL, 0x1);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+                       DP(NETIF_MSG_LINK, "XGXS 8706\n");
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                                     NIG_MASK_MI_INT);
+                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
+
+                       bp->phy_addr = ext_phy_type;
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           EXT_PHY_OPT_PMD_DIGITAL_CNT,
+                                           0x400);
+                       bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                           EXT_PHY_OPT_LASI_CNTL, 0x1);
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       break;
+               }
+               bp->phy_addr = local_phy;
+
+       } else { /* SerDes */
+/*             ext_phy_addr = ((bp->ext_phy_config &
+                                PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >>
+                               PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT);
+*/
+               ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "SerDes Direct\n");
+                       break;
+
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+                       DP(NETIF_MSG_LINK, "SerDes 5482\n");
+                       bnx2x_bits_en(bp,
+                                     NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                                     NIG_MASK_MI_INT);
+                       DP(NETIF_MSG_LINK, "enabled extenal phy int\n");
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       break;
+               }
+       }
+}
+
+static void bnx2x_ext_phy_reset(struct bnx2x *bp)
+{
+       u32 ext_phy_type;
+       u32 ext_phy_addr;
+       u32 local_phy;
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "XGXS Direct\n");
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+                       DP(NETIF_MSG_LINK, "XGXS 8705/6\n");
+                       local_phy = bp->phy_addr;
+                       ext_phy_addr = ((bp->ext_phy_config &
+                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
+                                       PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
+                       bp->phy_addr = (u8)ext_phy_addr;
+                       bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD,
+                                          EXT_PHY_OPT_CNTL, 0xa040);
+                       bp->phy_addr = local_phy;
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       break;
+               }
+
+       } else { /* SerDes */
+               ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+                       DP(NETIF_MSG_LINK, "SerDes Direct\n");
+                       break;
+
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+                       DP(NETIF_MSG_LINK, "SerDes 5482\n");
+                       break;
+
+               default:
+                       DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
+                          bp->ext_phy_config);
+                       break;
+               }
+       }
+}
+
+static void bnx2x_link_initialize(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       /* disable attentions */
+       bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                      (NIG_MASK_XGXS0_LINK_STATUS |
+                       NIG_MASK_XGXS0_LINK10G |
+                       NIG_MASK_SERDES0_LINK_STATUS |
+                       NIG_MASK_MI_INT));
+
+       bnx2x_ext_phy_reset(bp);
+
+       bnx2x_set_aer_mmd(bp);
+
+       if (bp->phy_flags & PHY_XGXS_FLAG)
+               bnx2x_set_master_ln(bp);
+
+       /* reset the SerDes and wait for reset bit return low */
+       bnx2x_reset_unicore(bp);
+
+       bnx2x_set_aer_mmd(bp);
+
+       /* setting the masterLn_def again after the reset */
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               bnx2x_set_master_ln(bp);
+               bnx2x_set_swap_lanes(bp);
+       }
+
+       /* Set Parallel Detect */
+       if (bp->req_autoneg & AUTONEG_SPEED)
+               bnx2x_set_parallel_detection(bp);
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               if (bp->req_line_speed &&
+                   bp->req_line_speed < SPEED_1000) {
+                       bp->phy_flags |= PHY_SGMII_FLAG;
+               } else {
+                       bp->phy_flags &= ~PHY_SGMII_FLAG;
+               }
+       }
+
+       if (!(bp->phy_flags & PHY_SGMII_FLAG)) {
+               u16 bank, rx_eq;
+
+               rx_eq = ((bp->serdes_config &
+                         PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
+                        PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
+
+               DP(NETIF_MSG_LINK, "setting rx eq to %d\n", rx_eq);
+               for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
+                           bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0)) {
+                       MDIO_SET_REG_BANK(bp, bank);
+                       bnx2x_mdio22_write(bp, MDIO_RX0_RX_EQ_BOOST,
+                                          ((rx_eq &
+                               MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
+                               MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
+               }
+
+               /* forced speed requested? */
+               if (!(bp->req_autoneg & AUTONEG_SPEED)) {
+                       DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
+
+                       /* disable autoneg */
+                       bnx2x_set_autoneg(bp);
+
+                       /* program speed and duplex */
+                       bnx2x_program_serdes(bp);
+
+               } else { /* AN_mode */
+                       DP(NETIF_MSG_LINK, "not SGMII, AN\n");
+
+                       /* AN enabled */
+                       bnx2x_set_brcm_cl37_advertisment(bp);
+
+                       /* program duplex & pause advertisment (for aneg) */
+                       bnx2x_set_ieee_aneg_advertisment(bp);
+
+                       /* enable autoneg */
+                       bnx2x_set_autoneg(bp);
+
+                       /* enalbe and restart AN */
+                       bnx2x_restart_autoneg(bp);
+               }
+
+       } else { /* SGMII mode */
+               DP(NETIF_MSG_LINK, "SGMII\n");
+
+               bnx2x_initialize_sgmii_process(bp);
+       }
+
+       /* enable the interrupt */
+       bnx2x_link_int_enable(bp);
+
+       /* init ext phy and enable link state int */
+       bnx2x_ext_phy_init(bp);
+}
+
+static void bnx2x_phy_deassert(struct bnx2x *bp)
+{
+       int port = bp->port;
+       u32 val;
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               DP(NETIF_MSG_LINK, "XGXS\n");
+               val = XGXS_RESET_BITS;
+
+       } else { /* SerDes */
+               DP(NETIF_MSG_LINK, "SerDes\n");
+               val = SERDES_RESET_BITS;
+       }
+
+       val = val << (port*16);
+
+       /* reset and unreset the SerDes/XGXS */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
+       msleep(5);
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
+}
+
+static int bnx2x_phy_init(struct bnx2x *bp)
+{
+       DP(NETIF_MSG_LINK, "started\n");
+       if (CHIP_REV(bp) == CHIP_REV_FPGA) {
+               bp->phy_flags |= PHY_EMAC_FLAG;
+               bp->link_up = 1;
+               bp->line_speed = SPEED_10000;
+               bp->duplex = DUPLEX_FULL;
+               NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0);
+               bnx2x_emac_enable(bp);
+               bnx2x_link_report(bp);
+               return 0;
+
+       } else if (CHIP_REV(bp) == CHIP_REV_EMUL) {
+               bp->phy_flags |= PHY_BMAC_FLAG;
+               bp->link_up = 1;
+               bp->line_speed = SPEED_10000;
+               bp->duplex = DUPLEX_FULL;
+               NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0);
+               bnx2x_bmac_enable(bp, 0);
+               bnx2x_link_report(bp);
+               return 0;
+
+       } else {
+               bnx2x_phy_deassert(bp);
+               bnx2x_link_initialize(bp);
+       }
+
+       return 0;
+}
+
+static void bnx2x_link_reset(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       /* disable attentions */
+       bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
+                      (NIG_MASK_XGXS0_LINK_STATUS |
+                       NIG_MASK_XGXS0_LINK10G |
+                       NIG_MASK_SERDES0_LINK_STATUS |
+                       NIG_MASK_MI_INT));
+
+       bnx2x_ext_phy_reset(bp);
+
+       /* reset the SerDes/XGXS */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
+              (0x1ff << (port*16)));
+
+       /* reset EMAC / BMAC and disable NIG interfaces */
+       NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0);
+       NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0);
+
+       NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0);
+       NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0);
+       NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
+
+       NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
+}
+
+#ifdef BNX2X_XGXS_LB
+static void bnx2x_set_xgxs_loopback(struct bnx2x *bp, int is_10g)
+{
+       int port = bp->port;
+
+       if (is_10g) {
+               u32 md_devad;
+
+               DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
+
+               /* change the uni_phy_addr in the nig */
+               REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18),
+                      &md_devad);
+               NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
+
+               /* change the aer mmd */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK);
+               bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x2800);
+
+               /* config combo IEEE0 control reg for loopback */
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0);
+               bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
+                                  0x6041);
+
+               /* set aer mmd back */
+               bnx2x_set_aer_mmd(bp);
+
+               /* and md_devad */
+               NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad);
+
+       } else {
+               u32 mii_control;
+
+               DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
+
+               MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0);
+               bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                 &mii_control);
+               bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL,
+                                  (mii_control |
+                                   MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
+       }
+}
+#endif
+
+/* end of PHY/MAC */
+
+/* slow path */
+
+/*
+ * General service functions
+ */
+
+/* the slow path queue is odd since completions arrive on the fastpath ring */
+static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid,
+                        u32 data_hi, u32 data_lo, int common)
+{
+       int port = bp->port;
+
+       DP(NETIF_MSG_TIMER,
+          "spe (%x:%x)  command %x  hw_cid %x  data (%x:%x)  left %x\n",
+          (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) +
+          (void *)bp->spq_prod_bd - (void *)bp->spq), command,
+          HW_CID(bp, cid), data_hi, data_lo, bp->spq_left);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return -EIO;
+#endif
+
+       spin_lock(&bp->spq_lock);
+
+       if (!bp->spq_left) {
+               BNX2X_ERR("BUG! SPQ ring full!\n");
+               spin_unlock(&bp->spq_lock);
+               bnx2x_panic();
+               return -EBUSY;
+       }
+       /* CID needs port number to be encoded int it */
+       bp->spq_prod_bd->hdr.conn_and_cmd_data =
+                       cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) |
+                                    HW_CID(bp, cid)));
+       bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE);
+       if (common)
+               bp->spq_prod_bd->hdr.type |=
+                       cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT));
+
+       bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi);
+       bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo);
+
+       bp->spq_left--;
+
+       if (bp->spq_prod_bd == bp->spq_last_bd) {
+               bp->spq_prod_bd = bp->spq;
+               bp->spq_prod_idx = 0;
+               DP(NETIF_MSG_TIMER, "end of spq\n");
+
+       } else {
+               bp->spq_prod_bd++;
+               bp->spq_prod_idx++;
+       }
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(port),
+              bp->spq_prod_idx);
+
+       spin_unlock(&bp->spq_lock);
+       return 0;
+}
+
+/* acquire split MCP access lock register */
+static int bnx2x_lock_alr(struct bnx2x *bp)
+{
+       int rc = 0;
+       u32 i, j, val;
+
+       might_sleep();
+       i = 100;
+       for (j = 0; j < i*10; j++) {
+               val = (1UL << 31);
+               REG_WR(bp, GRCBASE_MCP + 0x9c, val);
+               val = REG_RD(bp, GRCBASE_MCP + 0x9c);
+               if (val & (1L << 31))
+                       break;
+
+               msleep(5);
+       }
+
+       if (!(val & (1L << 31))) {
+               BNX2X_ERR("Cannot acquire nvram interface\n");
+
+               rc = -EBUSY;
+       }
+
+       return rc;
+}
+
+/* Release split MCP access lock register */
+static void bnx2x_unlock_alr(struct bnx2x *bp)
+{
+       u32 val = 0;
+
+       REG_WR(bp, GRCBASE_MCP + 0x9c, val);
+}
+
+static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp)
+{
+       struct host_def_status_block *def_sb = bp->def_status_blk;
+       u16 rc = 0;
+
+       barrier(); /* status block is written to by the chip */
+
+       if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) {
+               bp->def_att_idx = def_sb->atten_status_block.attn_bits_index;
+               rc |= 1;
+       }
+       if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) {
+               bp->def_c_idx = def_sb->c_def_status_block.status_block_index;
+               rc |= 2;
+       }
+       if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) {
+               bp->def_u_idx = def_sb->u_def_status_block.status_block_index;
+               rc |= 4;
+       }
+       if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) {
+               bp->def_x_idx = def_sb->x_def_status_block.status_block_index;
+               rc |= 8;
+       }
+       if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) {
+               bp->def_t_idx = def_sb->t_def_status_block.status_block_index;
+               rc |= 16;
+       }
+       return rc;
+}
+
+/*
+ * slow path service functions
+ */
+
+static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted)
+{
+       int port = bp->port;
+       u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8;
+       u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+                             MISC_REG_AEU_MASK_ATTN_FUNC_0;
+       u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 :
+                                  NIG_REG_MASK_INTERRUPT_PORT0;
+
+       if (~bp->aeu_mask & (asserted & 0xff))
+               BNX2X_ERR("IGU ERROR\n");
+       if (bp->attn_state & asserted)
+               BNX2X_ERR("IGU ERROR\n");
+
+       DP(NETIF_MSG_HW, "aeu_mask %x  newly asserted %x\n",
+          bp->aeu_mask, asserted);
+       bp->aeu_mask &= ~(asserted & 0xff);
+       DP(NETIF_MSG_HW, "after masking: aeu_mask %x\n", bp->aeu_mask);
+
+       REG_WR(bp, aeu_addr, bp->aeu_mask);
+
+       bp->attn_state |= asserted;
+
+       if (asserted & ATTN_HARD_WIRED_MASK) {
+               if (asserted & ATTN_NIG_FOR_FUNC) {
+                       u32 nig_status_port;
+                       u32 nig_int_addr = port ?
+                                       NIG_REG_STATUS_INTERRUPT_PORT1 :
+                                       NIG_REG_STATUS_INTERRUPT_PORT0;
+
+                       bp->nig_mask = REG_RD(bp, nig_mask_addr);
+                       REG_WR(bp, nig_mask_addr, 0);
+
+                       nig_status_port = REG_RD(bp, nig_int_addr);
+                       bnx2x_link_update(bp);
+
+                       /* handle unicore attn? */
+               }
+               if (asserted & ATTN_SW_TIMER_4_FUNC)
+                       DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n");
+
+               if (asserted & GPIO_2_FUNC)
+                       DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n");
+
+               if (asserted & GPIO_3_FUNC)
+                       DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n");
+
+               if (asserted & GPIO_4_FUNC)
+                       DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n");
+
+               if (port == 0) {
+                       if (asserted & ATTN_GENERAL_ATTN_1) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0);
+                       }
+                       if (asserted & ATTN_GENERAL_ATTN_2) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0);
+                       }
+                       if (asserted & ATTN_GENERAL_ATTN_3) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0);
+                       }
+               } else {
+                       if (asserted & ATTN_GENERAL_ATTN_4) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0);
+                       }
+                       if (asserted & ATTN_GENERAL_ATTN_5) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0);
+                       }
+                       if (asserted & ATTN_GENERAL_ATTN_6) {
+                               DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n");
+                               REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0);
+                       }
+               }
+
+       } /* if hardwired */
+
+       DP(NETIF_MSG_HW, "about to mask 0x%08x at IGU addr 0x%x\n",
+          asserted, BAR_IGU_INTMEM + igu_addr);
+       REG_WR(bp, BAR_IGU_INTMEM + igu_addr, asserted);
+
+       /* now set back the mask */
+       if (asserted & ATTN_NIG_FOR_FUNC)
+               REG_WR(bp, nig_mask_addr, bp->nig_mask);
+}
+
+static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted)
+{
+       int port = bp->port;
+       int index;
+       struct attn_route attn;
+       struct attn_route group_mask;
+       u32 reg_addr;
+       u32 val;
+
+       /* need to take HW lock because MCP or other port might also
+          try to handle this event */
+       bnx2x_lock_alr(bp);
+
+       attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4);
+       attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4);
+       attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4);
+       attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4);
+       DP(NETIF_MSG_HW, "attn %llx\n", (unsigned long long)attn.sig[0]);
+
+       for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) {
+               if (deasserted & (1 << index)) {
+                       group_mask = bp->attn_group[index];
+
+                       DP(NETIF_MSG_HW, "group[%d]: %llx\n", index,
+                          (unsigned long long)group_mask.sig[0]);
+
+                       if (attn.sig[3] & group_mask.sig[3] &
+                           EVEREST_GEN_ATTN_IN_USE_MASK) {
+
+                               if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) {
+
+                                       BNX2X_ERR("MC assert!\n");
+                                       bnx2x_panic();
+
+                               } else if (attn.sig[3] & BNX2X_MCP_ASSERT) {
+
+                                       BNX2X_ERR("MCP assert!\n");
+                                       REG_WR(bp,
+                                            MISC_REG_AEU_GENERAL_ATTN_11, 0);
+                                       bnx2x_mc_assert(bp);
+
+                               } else {
+                                       BNX2X_ERR("UNKOWEN HW ASSERT!\n");
+                               }
+                       }
+
+                       if (attn.sig[1] & group_mask.sig[1] &
+                           BNX2X_DOORQ_ASSERT) {
+
+                               val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR);
+                               BNX2X_ERR("DB hw attention 0x%x\n", val);
+                               /* DORQ discard attention */
+                               if (val & 0x2)
+                                       BNX2X_ERR("FATAL error from DORQ\n");
+                       }
+
+                       if (attn.sig[2] & group_mask.sig[2] &
+                           AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) {
+
+                               val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR);
+                               BNX2X_ERR("CFC hw attention 0x%x\n", val);
+                               /* CFC error attention */
+                               if (val & 0x2)
+                                       BNX2X_ERR("FATAL error from CFC\n");
+                       }
+
+                       if (attn.sig[2] & group_mask.sig[2] &
+                           AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) {
+
+                               val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0);
+                               BNX2X_ERR("PXP hw attention 0x%x\n", val);
+                               /* RQ_USDMDP_FIFO_OVERFLOW */
+                               if (val & 0x18000)
+                                       BNX2X_ERR("FATAL error from PXP\n");
+                       }
+
+                       if (attn.sig[3] & group_mask.sig[3] &
+                           EVEREST_LATCHED_ATTN_IN_USE_MASK) {
+
+                               REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL,
+                                      0x7ff);
+                               DP(NETIF_MSG_HW, "got latched bits 0x%x\n",
+                                  attn.sig[3]);
+                       }
+
+                       if ((attn.sig[0] & group_mask.sig[0] &
+                                               HW_INTERRUT_ASSERT_SET_0) ||
+                           (attn.sig[1] & group_mask.sig[1] &
+                                               HW_INTERRUT_ASSERT_SET_1) ||
+                           (attn.sig[2] & group_mask.sig[2] &
+                                               HW_INTERRUT_ASSERT_SET_2))
+                               BNX2X_ERR("FATAL HW block attention\n");
+
+                       if ((attn.sig[0] & group_mask.sig[0] &
+                                               HW_PRTY_ASSERT_SET_0) ||
+                           (attn.sig[1] & group_mask.sig[1] &
+                                               HW_PRTY_ASSERT_SET_1) ||
+                           (attn.sig[2] & group_mask.sig[2] &
+                                               HW_PRTY_ASSERT_SET_2))
+                               BNX2X_ERR("FATAL HW block parity atention\n");
+               }
+       }
+
+       bnx2x_unlock_alr(bp);
+
+       reg_addr = (IGU_ADDR_ATTN_BITS_CLR + IGU_PORT_BASE * port) * 8;
+
+       val = ~deasserted;
+/*      DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n",
+          val, BAR_IGU_INTMEM + reg_addr); */
+       REG_WR(bp, BAR_IGU_INTMEM + reg_addr, val);
+
+       if (bp->aeu_mask & (deasserted & 0xff))
+               BNX2X_ERR("IGU BUG\n");
+       if (~bp->attn_state & deasserted)
+               BNX2X_ERR("IGU BUG\n");
+
+       reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+                         MISC_REG_AEU_MASK_ATTN_FUNC_0;
+
+       DP(NETIF_MSG_HW, "aeu_mask %x\n", bp->aeu_mask);
+       bp->aeu_mask |= (deasserted & 0xff);
+
+       DP(NETIF_MSG_HW, "new mask %x\n", bp->aeu_mask);
+       REG_WR(bp, reg_addr, bp->aeu_mask);
+
+       DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state);
+       bp->attn_state &= ~deasserted;
+       DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state);
+}
+
+static void bnx2x_attn_int(struct bnx2x *bp)
+{
+       /* read local copy of bits */
+       u32 attn_bits = bp->def_status_blk->atten_status_block.attn_bits;
+       u32 attn_ack = bp->def_status_blk->atten_status_block.attn_bits_ack;
+       u32 attn_state = bp->attn_state;
+
+       /* look for changed bits */
+       u32 asserted   =  attn_bits & ~attn_ack & ~attn_state;
+       u32 deasserted = ~attn_bits &  attn_ack &  attn_state;
+
+       DP(NETIF_MSG_HW,
+          "attn_bits %x  attn_ack %x  asserted %x  deasserted %x\n",
+          attn_bits, attn_ack, asserted, deasserted);
+
+       if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state))
+               BNX2X_ERR("bad attention state\n");
+
+       /* handle bits that were raised */
+       if (asserted)
+               bnx2x_attn_int_asserted(bp, asserted);
+
+       if (deasserted)
+               bnx2x_attn_int_deasserted(bp, deasserted);
+}
+
+static void bnx2x_sp_task(struct work_struct *work)
+{
+       struct bnx2x *bp = container_of(work, struct bnx2x, sp_task);
+       u16 status;
+
+       /* Return here if interrupt is disabled */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+               DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+               return;
+       }
+
+       status = bnx2x_update_dsb_idx(bp);
+       if (status == 0)
+               BNX2X_ERR("spurious slowpath interrupt!\n");
+
+       DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status);
+
+       if (status & 0x1) {
+               /* HW attentions */
+               bnx2x_attn_int(bp);
+       }
+
+       /* CStorm events: query_stats, cfc delete ramrods */
+       if (status & 0x2)
+               bp->stat_pending = 0;
+
+       bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, bp->def_att_idx,
+                    IGU_INT_NOP, 1);
+       bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx),
+                    IGU_INT_NOP, 1);
+       bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx),
+                    IGU_INT_NOP, 1);
+       bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx),
+                    IGU_INT_NOP, 1);
+       bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx),
+                    IGU_INT_ENABLE, 1);
+}
+
+static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance)
+{
+       struct net_device *dev = dev_instance;
+       struct bnx2x *bp = netdev_priv(dev);
+
+       /* Return here if interrupt is disabled */
+       if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
+               DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n");
+               return IRQ_HANDLED;
+       }
+
+       bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return IRQ_HANDLED;
+#endif
+
+       schedule_work(&bp->sp_task);
+
+       return IRQ_HANDLED;
+}
+
+/* end of slow path */
+
+/* Statistics */
+
+/****************************************************************************
+* Macros
+****************************************************************************/
+
+#define UPDATE_STAT(s, t) \
+       do { \
+               estats->t += new->s - old->s; \
+               old->s = new->s; \
+       } while (0)
+
+/* sum[hi:lo] += add[hi:lo] */
+#define ADD_64(s_hi, a_hi, s_lo, a_lo) \
+       do { \
+               s_lo += a_lo; \
+               s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \
+       } while (0)
+
+/* difference = minuend - subtrahend */
+#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \
+       do { \
+               if (m_lo < s_lo) {      /* underflow */ \
+                       d_hi = m_hi - s_hi; \
+                       if (d_hi > 0) { /* we can 'loan' 1 */ \
+                               d_hi--; \
+                               d_lo = m_lo + (UINT_MAX - s_lo) + 1; \
+                       } else {        /* m_hi <= s_hi */ \
+                               d_hi = 0; \
+                               d_lo = 0; \
+                       } \
+               } else {                /* m_lo >= s_lo */ \
+                       if (m_hi < s_hi) { \
+                           d_hi = 0; \
+                           d_lo = 0; \
+                       } else {        /* m_hi >= s_hi */ \
+                           d_hi = m_hi - s_hi; \
+                           d_lo = m_lo - s_lo; \
+                       } \
+               } \
+       } while (0)
+
+/* minuend -= subtrahend */
+#define SUB_64(m_hi, s_hi, m_lo, s_lo) \
+       do { \
+               DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \
+       } while (0)
+
+#define UPDATE_STAT64(s_hi, t_hi, s_lo, t_lo) \
+       do { \
+               DIFF_64(diff.hi, new->s_hi, old->s_hi, \
+                       diff.lo, new->s_lo, old->s_lo); \
+               old->s_hi = new->s_hi; \
+               old->s_lo = new->s_lo; \
+               ADD_64(estats->t_hi, diff.hi, \
+                      estats->t_lo, diff.lo); \
+       } while (0)
+
+/* sum[hi:lo] += add */
+#define ADD_EXTEND_64(s_hi, s_lo, a) \
+       do { \
+               s_lo += a; \
+               s_hi += (s_lo < a) ? 1 : 0; \
+       } while (0)
+
+#define UPDATE_EXTEND_STAT(s, t_hi, t_lo) \
+       do { \
+               ADD_EXTEND_64(estats->t_hi, estats->t_lo, new->s); \
+       } while (0)
+
+#define UPDATE_EXTEND_TSTAT(s, t_hi, t_lo) \
+       do { \
+               diff = le32_to_cpu(tclient->s) - old_tclient->s; \
+               old_tclient->s = le32_to_cpu(tclient->s); \
+               ADD_EXTEND_64(estats->t_hi, estats->t_lo, diff); \
+       } while (0)
+
+/*
+ * General service functions
+ */
+
+static inline long bnx2x_hilo(u32 *hiref)
+{
+       u32 lo = *(hiref + 1);
+#if (BITS_PER_LONG == 64)
+       u32 hi = *hiref;
+
+       return HILO_U64(hi, lo);
+#else
+       return lo;
+#endif
+}
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_init_mac_stats(struct bnx2x *bp)
+{
+       struct dmae_command *dmae;
+       int port = bp->port;
+       int loader_idx = port * 8;
+       u32 opcode;
+       u32 mac_addr;
+
+       bp->executer_idx = 0;
+       if (bp->fw_mb) {
+               /* MCP */
+               opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+                         DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                         DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                         DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                         (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+
+               if (bp->link_up)
+                       opcode |= (DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE);
+
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, eth_stats) +
+                                          sizeof(u32));
+               dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, eth_stats) +
+                                          sizeof(u32));
+               dmae->dst_addr_lo = bp->fw_mb >> 2;
+               dmae->dst_addr_hi = 0;
+               dmae->len = (offsetof(struct bnx2x_eth_stats, mac_stx_end) -
+                            sizeof(u32)) >> 2;
+               if (bp->link_up) {
+                       dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+                       dmae->comp_addr_hi = 0;
+                       dmae->comp_val = 1;
+               } else {
+                       dmae->comp_addr_lo = 0;
+                       dmae->comp_addr_hi = 0;
+                       dmae->comp_val = 0;
+               }
+       }
+
+       if (!bp->link_up) {
+               /* no need to collect statistics in link down */
+               return;
+       }
+
+       opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+                 DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
+                 DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                 DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                 DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+
+       if (bp->phy_flags & PHY_BMAC_FLAG) {
+
+               mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM :
+                                  NIG_REG_INGRESS_BMAC0_MEM);
+
+               /* BIGMAC_REGISTER_TX_STAT_GTPKT ..
+                  BIGMAC_REGISTER_TX_STAT_GTBYT */
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = (mac_addr +
+                                    BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+               dmae->src_addr_hi = 0;
+               dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
+               dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
+               dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT -
+                            BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2;
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+
+               /* BIGMAC_REGISTER_RX_STAT_GR64 ..
+                  BIGMAC_REGISTER_RX_STAT_GRIPJ */
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = (mac_addr +
+                                    BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+               dmae->src_addr_hi = 0;
+               dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+                                       offsetof(struct bmac_stats, rx_gr64));
+               dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+                                       offsetof(struct bmac_stats, rx_gr64));
+               dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ -
+                            BIGMAC_REGISTER_RX_STAT_GR64) >> 2;
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+
+       } else if (bp->phy_flags & PHY_EMAC_FLAG) {
+
+               mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0);
+
+               /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = (mac_addr +
+                                    EMAC_REG_EMAC_RX_STAT_AC) >> 2;
+               dmae->src_addr_hi = 0;
+               dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats));
+               dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats));
+               dmae->len = EMAC_REG_EMAC_RX_STAT_AC_COUNT;
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+
+               /* EMAC_REG_EMAC_RX_STAT_AC_28 */
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = (mac_addr +
+                                    EMAC_REG_EMAC_RX_STAT_AC_28) >> 2;
+               dmae->src_addr_hi = 0;
+               dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+                                          offsetof(struct emac_stats,
+                                                   rx_falsecarriererrors));
+               dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+                                          offsetof(struct emac_stats,
+                                                   rx_falsecarriererrors));
+               dmae->len = 1;
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+
+               /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/
+               dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+               dmae->opcode = opcode;
+               dmae->src_addr_lo = (mac_addr +
+                                    EMAC_REG_EMAC_TX_STAT_AC) >> 2;
+               dmae->src_addr_hi = 0;
+               dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) +
+                                          offsetof(struct emac_stats,
+                                                   tx_ifhcoutoctets));
+               dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) +
+                                          offsetof(struct emac_stats,
+                                                   tx_ifhcoutoctets));
+               dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT;
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+       }
+
+       /* NIG */
+       dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]);
+       dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI |
+                       DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE |
+                       DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                       DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                       DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                       (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+       dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD :
+                                   NIG_REG_STAT0_BRB_DISCARD) >> 2;
+       dmae->src_addr_hi = 0;
+       dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig));
+       dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig));
+       dmae->len = (sizeof(struct nig_stats) - 2*sizeof(u32)) >> 2;
+       dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig) +
+                                   offsetof(struct nig_stats, done));
+       dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig) +
+                                   offsetof(struct nig_stats, done));
+       dmae->comp_val = 0xffffffff;
+}
+
+static void bnx2x_init_stats(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       bp->stats_state = STATS_STATE_DISABLE;
+       bp->executer_idx = 0;
+
+       bp->old_brb_discard = REG_RD(bp,
+                                    NIG_REG_STAT0_BRB_DISCARD + port*0x38);
+
+       memset(&bp->old_bmac, 0, sizeof(struct bmac_stats));
+       memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats));
+       memset(&bp->dev->stats, 0, sizeof(struct net_device_stats));
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 1);
+       REG_WR(bp, BAR_XSTRORM_INTMEM +
+              XSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 1);
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
+
+       REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 0);
+       REG_WR(bp, BAR_CSTRORM_INTMEM +
+              CSTORM_STATS_FLAGS_OFFSET(port) + 4, 0);
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM +
+              XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
+              U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+       REG_WR(bp, BAR_XSTRORM_INTMEM +
+              XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
+              U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port),
+              U64_LO(bnx2x_sp_mapping(bp, fw_stats)));
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4,
+              U64_HI(bnx2x_sp_mapping(bp, fw_stats)));
+}
+
+static void bnx2x_stop_stats(struct bnx2x *bp)
+{
+       might_sleep();
+       if (bp->stats_state != STATS_STATE_DISABLE) {
+               int timeout = 10;
+
+               bp->stats_state = STATS_STATE_STOP;
+               DP(BNX2X_MSG_STATS, "stats_state - STOP\n");
+
+               while (bp->stats_state != STATS_STATE_DISABLE) {
+                       if (!timeout) {
+                               BNX2X_ERR("timeout wating for stats stop\n");
+                               break;
+                       }
+                       timeout--;
+                       msleep(100);
+               }
+       }
+       DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n");
+}
+
+/*
+ * Statistics service functions
+ */
+
+static void bnx2x_update_bmac_stats(struct bnx2x *bp)
+{
+       struct regp diff;
+       struct regp sum;
+       struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac);
+       struct bmac_stats *old = &bp->old_bmac;
+       struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
+
+       sum.hi = 0;
+       sum.lo = 0;
+
+       UPDATE_STAT64(tx_gtbyt.hi, total_bytes_transmitted_hi,
+                     tx_gtbyt.lo, total_bytes_transmitted_lo);
+
+       UPDATE_STAT64(tx_gtmca.hi, total_multicast_packets_transmitted_hi,
+                     tx_gtmca.lo, total_multicast_packets_transmitted_lo);
+       ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
+
+       UPDATE_STAT64(tx_gtgca.hi, total_broadcast_packets_transmitted_hi,
+                     tx_gtgca.lo, total_broadcast_packets_transmitted_lo);
+       ADD_64(sum.hi, diff.hi, sum.lo, diff.lo);
+
+       UPDATE_STAT64(tx_gtpkt.hi, total_unicast_packets_transmitted_hi,
+                     tx_gtpkt.lo, total_unicast_packets_transmitted_lo);
+       SUB_64(estats->total_unicast_packets_transmitted_hi, sum.hi,
+              estats->total_unicast_packets_transmitted_lo, sum.lo);
+
+       UPDATE_STAT(tx_gtxpf.lo, pause_xoff_frames_transmitted);
+       UPDATE_STAT(tx_gt64.lo, frames_transmitted_64_bytes);
+       UPDATE_STAT(tx_gt127.lo, frames_transmitted_65_127_bytes);
+       UPDATE_STAT(tx_gt255.lo, frames_transmitted_128_255_bytes);
+       UPDATE_STAT(tx_gt511.lo, frames_transmitted_256_511_bytes);
+       UPDATE_STAT(tx_gt1023.lo, frames_transmitted_512_1023_bytes);
+       UPDATE_STAT(tx_gt1518.lo, frames_transmitted_1024_1522_bytes);
+       UPDATE_STAT(tx_gt2047.lo, frames_transmitted_1523_9022_bytes);
+       UPDATE_STAT(tx_gt4095.lo, frames_transmitted_1523_9022_bytes);
+       UPDATE_STAT(tx_gt9216.lo, frames_transmitted_1523_9022_bytes);
+       UPDATE_STAT(tx_gt16383.lo, frames_transmitted_1523_9022_bytes);
+
+       UPDATE_STAT(rx_grfcs.lo, crc_receive_errors);
+       UPDATE_STAT(rx_grund.lo, runt_packets_received);
+       UPDATE_STAT(rx_grovr.lo, stat_Dot3statsFramesTooLong);
+       UPDATE_STAT(rx_grxpf.lo, pause_xoff_frames_received);
+       UPDATE_STAT(rx_grxcf.lo, control_frames_received);
+       /* UPDATE_STAT(rx_grxpf.lo, control_frames_received); */
+       UPDATE_STAT(rx_grfrg.lo, error_runt_packets_received);
+       UPDATE_STAT(rx_grjbr.lo, error_jabber_packets_received);
+
+       UPDATE_STAT64(rx_grerb.hi, stat_IfHCInBadOctets_hi,
+                     rx_grerb.lo, stat_IfHCInBadOctets_lo);
+       UPDATE_STAT64(tx_gtufl.hi, stat_IfHCOutBadOctets_hi,
+                     tx_gtufl.lo, stat_IfHCOutBadOctets_lo);
+       UPDATE_STAT(tx_gterr.lo, stat_Dot3statsInternalMacTransmitErrors);
+       /* UPDATE_STAT(rx_grxpf.lo, stat_XoffStateEntered); */
+       estats->stat_XoffStateEntered = estats->pause_xoff_frames_received;
+}
+
+static void bnx2x_update_emac_stats(struct bnx2x *bp)
+{
+       struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac);
+       struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
+
+       UPDATE_EXTEND_STAT(tx_ifhcoutoctets, total_bytes_transmitted_hi,
+                                            total_bytes_transmitted_lo);
+       UPDATE_EXTEND_STAT(tx_ifhcoutucastpkts,
+                                       total_unicast_packets_transmitted_hi,
+                                       total_unicast_packets_transmitted_lo);
+       UPDATE_EXTEND_STAT(tx_ifhcoutmulticastpkts,
+                                     total_multicast_packets_transmitted_hi,
+                                     total_multicast_packets_transmitted_lo);
+       UPDATE_EXTEND_STAT(tx_ifhcoutbroadcastpkts,
+                                     total_broadcast_packets_transmitted_hi,
+                                     total_broadcast_packets_transmitted_lo);
+
+       estats->pause_xon_frames_transmitted += new->tx_outxonsent;
+       estats->pause_xoff_frames_transmitted += new->tx_outxoffsent;
+       estats->single_collision_transmit_frames +=
+                               new->tx_dot3statssinglecollisionframes;
+       estats->multiple_collision_transmit_frames +=
+                               new->tx_dot3statsmultiplecollisionframes;
+       estats->late_collision_frames += new->tx_dot3statslatecollisions;
+       estats->excessive_collision_frames +=
+                               new->tx_dot3statsexcessivecollisions;
+       estats->frames_transmitted_64_bytes += new->tx_etherstatspkts64octets;
+       estats->frames_transmitted_65_127_bytes +=
+                               new->tx_etherstatspkts65octetsto127octets;
+       estats->frames_transmitted_128_255_bytes +=
+                               new->tx_etherstatspkts128octetsto255octets;
+       estats->frames_transmitted_256_511_bytes +=
+                               new->tx_etherstatspkts256octetsto511octets;
+       estats->frames_transmitted_512_1023_bytes +=
+                               new->tx_etherstatspkts512octetsto1023octets;
+       estats->frames_transmitted_1024_1522_bytes +=
+                               new->tx_etherstatspkts1024octetsto1522octet;
+       estats->frames_transmitted_1523_9022_bytes +=
+                               new->tx_etherstatspktsover1522octets;
+
+       estats->crc_receive_errors += new->rx_dot3statsfcserrors;
+       estats->alignment_errors += new->rx_dot3statsalignmenterrors;
+       estats->false_carrier_detections += new->rx_falsecarriererrors;
+       estats->runt_packets_received += new->rx_etherstatsundersizepkts;
+       estats->stat_Dot3statsFramesTooLong += new->rx_dot3statsframestoolong;
+       estats->pause_xon_frames_received += new->rx_xonpauseframesreceived;
+       estats->pause_xoff_frames_received += new->rx_xoffpauseframesreceived;
+       estats->control_frames_received += new->rx_maccontrolframesreceived;
+       estats->error_runt_packets_received += new->rx_etherstatsfragments;
+       estats->error_jabber_packets_received += new->rx_etherstatsjabbers;
+
+       UPDATE_EXTEND_STAT(rx_ifhcinbadoctets, stat_IfHCInBadOctets_hi,
+                                              stat_IfHCInBadOctets_lo);
+       UPDATE_EXTEND_STAT(tx_ifhcoutbadoctets, stat_IfHCOutBadOctets_hi,
+                                               stat_IfHCOutBadOctets_lo);
+       estats->stat_Dot3statsInternalMacTransmitErrors +=
+                               new->tx_dot3statsinternalmactransmiterrors;
+       estats->stat_Dot3StatsCarrierSenseErrors +=
+                               new->rx_dot3statscarriersenseerrors;
+       estats->stat_Dot3StatsDeferredTransmissions +=
+                               new->tx_dot3statsdeferredtransmissions;
+       estats->stat_FlowControlDone += new->tx_flowcontroldone;
+       estats->stat_XoffStateEntered += new->rx_xoffstateentered;
+}
+
+static int bnx2x_update_storm_stats(struct bnx2x *bp)
+{
+       struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats);
+       struct tstorm_common_stats *tstats = &stats->tstorm_common;
+       struct tstorm_per_client_stats *tclient =
+                                               &tstats->client_statistics[0];
+       struct tstorm_per_client_stats *old_tclient = &bp->old_tclient;
+       struct xstorm_common_stats *xstats = &stats->xstorm_common;
+       struct nig_stats *nstats = bnx2x_sp(bp, nig);
+       struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
+       u32 diff;
+
+       /* are DMAE stats valid? */
+       if (nstats->done != 0xffffffff) {
+               DP(BNX2X_MSG_STATS, "stats not updated by dmae\n");
+               return -1;
+       }
+
+       /* are storm stats valid? */
+       if (tstats->done.hi != 0xffffffff) {
+               DP(BNX2X_MSG_STATS, "stats not updated by tstorm\n");
+               return -2;
+       }
+       if (xstats->done.hi != 0xffffffff) {
+               DP(BNX2X_MSG_STATS, "stats not updated by xstorm\n");
+               return -3;
+       }
+
+       estats->total_bytes_received_hi =
+       estats->valid_bytes_received_hi =
+                               le32_to_cpu(tclient->total_rcv_bytes.hi);
+       estats->total_bytes_received_lo =
+       estats->valid_bytes_received_lo =
+                               le32_to_cpu(tclient->total_rcv_bytes.lo);
+       ADD_64(estats->total_bytes_received_hi,
+              le32_to_cpu(tclient->rcv_error_bytes.hi),
+              estats->total_bytes_received_lo,
+              le32_to_cpu(tclient->rcv_error_bytes.lo));
+
+       UPDATE_EXTEND_TSTAT(rcv_unicast_pkts,
+                                       total_unicast_packets_received_hi,
+                                       total_unicast_packets_received_lo);
+       UPDATE_EXTEND_TSTAT(rcv_multicast_pkts,
+                                       total_multicast_packets_received_hi,
+                                       total_multicast_packets_received_lo);
+       UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts,
+                                       total_broadcast_packets_received_hi,
+                                       total_broadcast_packets_received_lo);
+
+       estats->frames_received_64_bytes = MAC_STX_NA;
+       estats->frames_received_65_127_bytes = MAC_STX_NA;
+       estats->frames_received_128_255_bytes = MAC_STX_NA;
+       estats->frames_received_256_511_bytes = MAC_STX_NA;
+       estats->frames_received_512_1023_bytes = MAC_STX_NA;
+       estats->frames_received_1024_1522_bytes = MAC_STX_NA;
+       estats->frames_received_1523_9022_bytes = MAC_STX_NA;
+
+       estats->x_total_sent_bytes_hi =
+                               le32_to_cpu(xstats->total_sent_bytes.hi);
+       estats->x_total_sent_bytes_lo =
+                               le32_to_cpu(xstats->total_sent_bytes.lo);
+       estats->x_total_sent_pkts = le32_to_cpu(xstats->total_sent_pkts);
+
+       estats->t_rcv_unicast_bytes_hi =
+                               le32_to_cpu(tclient->rcv_unicast_bytes.hi);
+       estats->t_rcv_unicast_bytes_lo =
+                               le32_to_cpu(tclient->rcv_unicast_bytes.lo);
+       estats->t_rcv_broadcast_bytes_hi =
+                               le32_to_cpu(tclient->rcv_broadcast_bytes.hi);
+       estats->t_rcv_broadcast_bytes_lo =
+                               le32_to_cpu(tclient->rcv_broadcast_bytes.lo);
+       estats->t_rcv_multicast_bytes_hi =
+                               le32_to_cpu(tclient->rcv_multicast_bytes.hi);
+       estats->t_rcv_multicast_bytes_lo =
+                               le32_to_cpu(tclient->rcv_multicast_bytes.lo);
+       estats->t_total_rcv_pkt = le32_to_cpu(tclient->total_rcv_pkts);
+
+       estats->checksum_discard = le32_to_cpu(tclient->checksum_discard);
+       estats->packets_too_big_discard =
+                               le32_to_cpu(tclient->packets_too_big_discard);
+       estats->jabber_packets_received = estats->packets_too_big_discard +
+                                         estats->stat_Dot3statsFramesTooLong;
+       estats->no_buff_discard = le32_to_cpu(tclient->no_buff_discard);
+       estats->ttl0_discard = le32_to_cpu(tclient->ttl0_discard);
+       estats->mac_discard = le32_to_cpu(tclient->mac_discard);
+       estats->mac_filter_discard = le32_to_cpu(tstats->mac_filter_discard);
+       estats->xxoverflow_discard = le32_to_cpu(tstats->xxoverflow_discard);
+       estats->brb_truncate_discard =
+                               le32_to_cpu(tstats->brb_truncate_discard);
+
+       estats->brb_discard += nstats->brb_discard - bp->old_brb_discard;
+       bp->old_brb_discard = nstats->brb_discard;
+
+       estats->brb_packet = nstats->brb_packet;
+       estats->brb_truncate = nstats->brb_truncate;
+       estats->flow_ctrl_discard = nstats->flow_ctrl_discard;
+       estats->flow_ctrl_octets = nstats->flow_ctrl_octets;
+       estats->flow_ctrl_packet = nstats->flow_ctrl_packet;
+       estats->mng_discard = nstats->mng_discard;
+       estats->mng_octet_inp = nstats->mng_octet_inp;
+       estats->mng_octet_out = nstats->mng_octet_out;
+       estats->mng_packet_inp = nstats->mng_packet_inp;
+       estats->mng_packet_out = nstats->mng_packet_out;
+       estats->pbf_octets = nstats->pbf_octets;
+       estats->pbf_packet = nstats->pbf_packet;
+       estats->safc_inp = nstats->safc_inp;
+
+       xstats->done.hi = 0;
+       tstats->done.hi = 0;
+       nstats->done = 0;
+
+       return 0;
+}
+
+static void bnx2x_update_net_stats(struct bnx2x *bp)
+{
+       struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
+       struct net_device_stats *nstats = &bp->dev->stats;
+
+       nstats->rx_packets =
+               bnx2x_hilo(&estats->total_unicast_packets_received_hi) +
+               bnx2x_hilo(&estats->total_multicast_packets_received_hi) +
+               bnx2x_hilo(&estats->total_broadcast_packets_received_hi);
+
+       nstats->tx_packets =
+               bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) +
+               bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) +
+               bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi);
+
+       nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi);
+
+       nstats->tx_bytes =
+               bnx2x_hilo(&estats->total_bytes_transmitted_hi);
+
+       nstats->rx_dropped = estats->checksum_discard +
+                                  estats->mac_discard;
+       nstats->tx_dropped = 0;
+
+       nstats->multicast =
+               bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi);
+
+       nstats->collisions =
+               estats->single_collision_transmit_frames +
+               estats->multiple_collision_transmit_frames +
+               estats->late_collision_frames +
+               estats->excessive_collision_frames;
+
+       nstats->rx_length_errors = estats->runt_packets_received +
+                                  estats->jabber_packets_received;
+       nstats->rx_over_errors = estats->no_buff_discard;
+       nstats->rx_crc_errors = estats->crc_receive_errors;
+       nstats->rx_frame_errors = estats->alignment_errors;
+       nstats->rx_fifo_errors = estats->brb_discard +
+                                      estats->brb_truncate_discard;
+       nstats->rx_missed_errors = estats->xxoverflow_discard;
+
+       nstats->rx_errors = nstats->rx_length_errors +
+                           nstats->rx_over_errors +
+                           nstats->rx_crc_errors +
+                           nstats->rx_frame_errors +
+                           nstats->rx_fifo_errors;
+
+       nstats->tx_aborted_errors = estats->late_collision_frames +
+                                         estats->excessive_collision_frames;
+       nstats->tx_carrier_errors = estats->false_carrier_detections;
+       nstats->tx_fifo_errors = 0;
+       nstats->tx_heartbeat_errors = 0;
+       nstats->tx_window_errors = 0;
+
+       nstats->tx_errors = nstats->tx_aborted_errors +
+                           nstats->tx_carrier_errors;
+
+       estats->mac_stx_start = ++estats->mac_stx_end;
+}
+
+static void bnx2x_update_stats(struct bnx2x *bp)
+{
+       int i;
+
+       if (!bnx2x_update_storm_stats(bp)) {
+
+               if (bp->phy_flags & PHY_BMAC_FLAG) {
+                       bnx2x_update_bmac_stats(bp);
+
+               } else if (bp->phy_flags & PHY_EMAC_FLAG) {
+                       bnx2x_update_emac_stats(bp);
+
+               } else { /* unreached */
+                       BNX2X_ERR("no MAC active\n");
+                       return;
+               }
+
+               bnx2x_update_net_stats(bp);
+       }
+
+       if (bp->msglevel & NETIF_MSG_TIMER) {
+               struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats);
+               struct net_device_stats *nstats = &bp->dev->stats;
+
+               printk(KERN_DEBUG "%s:\n", bp->dev->name);
+               printk(KERN_DEBUG "  tx avail (%4x)  tx hc idx (%x)"
+                                 "  tx pkt (%lx)\n",
+                      bnx2x_tx_avail(bp->fp),
+                      *bp->fp->tx_cons_sb, nstats->tx_packets);
+               printk(KERN_DEBUG "  rx usage (%4x)  rx hc idx (%x)"
+                                 "  rx pkt (%lx)\n",
+                      (u16)(*bp->fp->rx_cons_sb - bp->fp->rx_comp_cons),
+                      *bp->fp->rx_cons_sb, nstats->rx_packets);
+               printk(KERN_DEBUG "  %s (Xoff events %u)  brb drops %u\n",
+                      netif_queue_stopped(bp->dev)? "Xoff" : "Xon",
+                      estats->driver_xoff, estats->brb_discard);
+               printk(KERN_DEBUG "tstats: checksum_discard %u  "
+                       "packets_too_big_discard %u  no_buff_discard %u  "
+                       "mac_discard %u  mac_filter_discard %u  "
+                       "xxovrflow_discard %u  brb_truncate_discard %u  "
+                       "ttl0_discard %u\n",
+                      estats->checksum_discard,
+                      estats->packets_too_big_discard,
+                      estats->no_buff_discard, estats->mac_discard,
+                      estats->mac_filter_discard, estats->xxoverflow_discard,
+                      estats->brb_truncate_discard, estats->ttl0_discard);
+
+               for_each_queue(bp, i) {
+                       printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i,
+                              bnx2x_fp(bp, i, tx_pkt),
+                              bnx2x_fp(bp, i, rx_pkt),
+                              bnx2x_fp(bp, i, rx_calls));
+               }
+       }
+
+       if (bp->state != BNX2X_STATE_OPEN) {
+               DP(BNX2X_MSG_STATS, "state is %x, returning\n", bp->state);
+               return;
+       }
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return;
+#endif
+
+       /* loader */
+       if (bp->executer_idx) {
+               struct dmae_command *dmae = &bp->dmae;
+               int port = bp->port;
+               int loader_idx = port * 8;
+
+               memset(dmae, 0, sizeof(struct dmae_command));
+
+               dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC |
+                               DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE |
+                               DMAE_CMD_DST_RESET |
+#ifdef __BIG_ENDIAN
+                               DMAE_CMD_ENDIANITY_B_DW_SWAP |
+#else
+                               DMAE_CMD_ENDIANITY_DW_SWAP |
+#endif
+                               (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
+               dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0]));
+               dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0]));
+               dmae->dst_addr_lo = (DMAE_REG_CMD_MEM +
+                                    sizeof(struct dmae_command) *
+                                    (loader_idx + 1)) >> 2;
+               dmae->dst_addr_hi = 0;
+               dmae->len = sizeof(struct dmae_command) >> 2;
+               dmae->len--;    /* !!! for A0/1 only */
+               dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2;
+               dmae->comp_addr_hi = 0;
+               dmae->comp_val = 1;
+
+               bnx2x_post_dmae(bp, dmae, loader_idx);
+       }
+
+       if (bp->stats_state != STATS_STATE_ENABLE) {
+               bp->stats_state = STATS_STATE_DISABLE;
+               return;
+       }
+
+       if (bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, 0, 0, 0) == 0) {
+               /* stats ramrod has it's own slot on the spe */
+               bp->spq_left++;
+               bp->stat_pending = 1;
+       }
+}
+
+static void bnx2x_timer(unsigned long data)
+{
+       struct bnx2x *bp = (struct bnx2x *) data;
+
+       if (!netif_running(bp->dev))
+               return;
+
+       if (atomic_read(&bp->intr_sem) != 0)
+               goto bnx2x_restart_timer;
+
+       if (poll) {
+               struct bnx2x_fastpath *fp = &bp->fp[0];
+               int rc;
+
+               bnx2x_tx_int(fp, 1000);
+               rc = bnx2x_rx_int(fp, 1000);
+       }
+
+       if (!nomcp && (bp->bc_ver >= 0x040003)) {
+               int port = bp->port;
+               u32 drv_pulse;
+               u32 mcp_pulse;
+
+               ++bp->fw_drv_pulse_wr_seq;
+               bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK;
+               /* TBD - add SYSTEM_TIME */
+               drv_pulse = bp->fw_drv_pulse_wr_seq;
+               SHMEM_WR(bp, drv_fw_mb[port].drv_pulse_mb, drv_pulse);
+
+               mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].mcp_pulse_mb) &
+                            MCP_PULSE_SEQ_MASK);
+               /* The delta between driver pulse and mcp response
+                * should be 1 (before mcp response) or 0 (after mcp response)
+                */
+               if ((drv_pulse != mcp_pulse) &&
+                   (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) {
+                       /* someone lost a heartbeat... */
+                       BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n",
+                                 drv_pulse, mcp_pulse);
+               }
+       }
+
+       if (bp->stats_state == STATS_STATE_DISABLE)
+               goto bnx2x_restart_timer;
+
+       bnx2x_update_stats(bp);
+
+bnx2x_restart_timer:
+       mod_timer(&bp->timer, jiffies + bp->current_interval);
+}
+
+/* end of Statistics */
+
+/* nic init */
+
+/*
+ * nic init service functions
+ */
+
+static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb,
+                         dma_addr_t mapping, int id)
+{
+       int port = bp->port;
+       u64 section;
+       int index;
+
+       /* USTORM */
+       section = ((u64)mapping) + offsetof(struct host_status_block,
+                                           u_status_block);
+       sb->u_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_USTRORM_INTMEM +
+              USTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section));
+       REG_WR(bp, BAR_USTRORM_INTMEM +
+              ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4),
+              U64_HI(section));
+
+       for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_USTRORM_INTMEM +
+                        USTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1);
+
+       /* CSTORM */
+       section = ((u64)mapping) + offsetof(struct host_status_block,
+                                           c_status_block);
+       sb->c_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_CSTRORM_INTMEM +
+              CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section));
+       REG_WR(bp, BAR_CSTRORM_INTMEM +
+              ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4),
+              U64_HI(section));
+
+       for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_CSTRORM_INTMEM +
+                        CSTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1);
+
+       bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+}
+
+static void bnx2x_init_def_sb(struct bnx2x *bp,
+                             struct host_def_status_block *def_sb,
+                             dma_addr_t mapping, int id)
+{
+       int port = bp->port;
+       int index, val, reg_offset;
+       u64 section;
+
+       /* ATTN */
+       section = ((u64)mapping) + offsetof(struct host_def_status_block,
+                                           atten_status_block);
+       def_sb->atten_status_block.status_block_id = id;
+
+       reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
+                            MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
+
+       for (index = 0; index < 3; index++) {
+               bp->attn_group[index].sig[0] = REG_RD(bp,
+                                                    reg_offset + 0x10*index);
+               bp->attn_group[index].sig[1] = REG_RD(bp,
+                                              reg_offset + 0x4 + 0x10*index);
+               bp->attn_group[index].sig[2] = REG_RD(bp,
+                                              reg_offset + 0x8 + 0x10*index);
+               bp->attn_group[index].sig[3] = REG_RD(bp,
+                                              reg_offset + 0xc + 0x10*index);
+       }
+
+       bp->aeu_mask = REG_RD(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 :
+                                         MISC_REG_AEU_MASK_ATTN_FUNC_0));
+
+       reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L :
+                            HC_REG_ATTN_MSG0_ADDR_L);
+
+       REG_WR(bp, reg_offset, U64_LO(section));
+       REG_WR(bp, reg_offset + 4, U64_HI(section));
+
+       reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0);
+
+       val = REG_RD(bp, reg_offset);
+       val |= id;
+       REG_WR(bp, reg_offset, val);
+
+       /* USTORM */
+       section = ((u64)mapping) + offsetof(struct host_def_status_block,
+                                           u_def_status_block);
+       def_sb->u_def_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_USTRORM_INTMEM +
+              USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
+       REG_WR(bp, BAR_USTRORM_INTMEM +
+              ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
+              U64_HI(section));
+       REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port),
+              BNX2X_BTR);
+
+       for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_USTRORM_INTMEM +
+                        USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+
+       /* CSTORM */
+       section = ((u64)mapping) + offsetof(struct host_def_status_block,
+                                           c_def_status_block);
+       def_sb->c_def_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_CSTRORM_INTMEM +
+              CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
+       REG_WR(bp, BAR_CSTRORM_INTMEM +
+              ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
+              U64_HI(section));
+       REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port),
+              BNX2X_BTR);
+
+       for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_CSTRORM_INTMEM +
+                        CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+
+       /* TSTORM */
+       section = ((u64)mapping) + offsetof(struct host_def_status_block,
+                                           t_def_status_block);
+       def_sb->t_def_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
+              U64_HI(section));
+       REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port),
+              BNX2X_BTR);
+
+       for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_TSTRORM_INTMEM +
+                        TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+
+       /* XSTORM */
+       section = ((u64)mapping) + offsetof(struct host_def_status_block,
+                                           x_def_status_block);
+       def_sb->x_def_status_block.status_block_id = id;
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM +
+              XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section));
+       REG_WR(bp, BAR_XSTRORM_INTMEM +
+              ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4),
+              U64_HI(section));
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port),
+              BNX2X_BTR);
+
+       for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++)
+               REG_WR16(bp, BAR_XSTRORM_INTMEM +
+                        XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1);
+
+       bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+}
+
+static void bnx2x_update_coalesce(struct bnx2x *bp)
+{
+       int port = bp->port;
+       int i;
+
+       for_each_queue(bp, i) {
+
+               /* HC_INDEX_U_ETH_RX_CQ_CONS */
+               REG_WR8(bp, BAR_USTRORM_INTMEM +
+                       USTORM_SB_HC_TIMEOUT_OFFSET(port, i,
+                                                  HC_INDEX_U_ETH_RX_CQ_CONS),
+                       bp->rx_ticks_int/12);
+               REG_WR16(bp, BAR_USTRORM_INTMEM +
+                        USTORM_SB_HC_DISABLE_OFFSET(port, i,
+                                                  HC_INDEX_U_ETH_RX_CQ_CONS),
+                        bp->rx_ticks_int ? 0 : 1);
+
+               /* HC_INDEX_C_ETH_TX_CQ_CONS */
+               REG_WR8(bp, BAR_CSTRORM_INTMEM +
+                       CSTORM_SB_HC_TIMEOUT_OFFSET(port, i,
+                                                  HC_INDEX_C_ETH_TX_CQ_CONS),
+                       bp->tx_ticks_int/12);
+               REG_WR16(bp, BAR_CSTRORM_INTMEM +
+                        CSTORM_SB_HC_DISABLE_OFFSET(port, i,
+                                                  HC_INDEX_C_ETH_TX_CQ_CONS),
+                        bp->tx_ticks_int ? 0 : 1);
+       }
+}
+
+static void bnx2x_init_rx_rings(struct bnx2x *bp)
+{
+       u16 ring_prod;
+       int i, j;
+       int port = bp->port;
+
+       bp->rx_buf_use_size = bp->dev->mtu;
+
+       bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD;
+       bp->rx_buf_size = bp->rx_buf_use_size + 64;
+
+       for_each_queue(bp, j) {
+               struct bnx2x_fastpath *fp = &bp->fp[j];
+
+               fp->rx_bd_cons = 0;
+               fp->rx_cons_sb = BNX2X_RX_SB_INDEX;
+
+               for (i = 1; i <= NUM_RX_RINGS; i++) {
+                       struct eth_rx_bd *rx_bd;
+
+                       rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2];
+                       rx_bd->addr_hi =
+                               cpu_to_le32(U64_HI(fp->rx_desc_mapping +
+                                          BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+                       rx_bd->addr_lo =
+                               cpu_to_le32(U64_LO(fp->rx_desc_mapping +
+                                          BCM_PAGE_SIZE*(i % NUM_RX_RINGS)));
+
+               }
+
+               for (i = 1; i <= NUM_RCQ_RINGS; i++) {
+                       struct eth_rx_cqe_next_page *nextpg;
+
+                       nextpg = (struct eth_rx_cqe_next_page *)
+                               &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1];
+                       nextpg->addr_hi =
+                               cpu_to_le32(U64_HI(fp->rx_comp_mapping +
+                                         BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+                       nextpg->addr_lo =
+                               cpu_to_le32(U64_LO(fp->rx_comp_mapping +
+                                         BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS)));
+               }
+
+               /* rx completion queue */
+               fp->rx_comp_cons = ring_prod = 0;
+
+               for (i = 0; i < bp->rx_ring_size; i++) {
+                       if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
+                               BNX2X_ERR("was only able to allocate "
+                                         "%d rx skbs\n", i);
+                               break;
+                       }
+                       ring_prod = NEXT_RX_IDX(ring_prod);
+                       BUG_TRAP(ring_prod > i);
+               }
+
+               fp->rx_bd_prod = fp->rx_comp_prod = ring_prod;
+               fp->rx_pkt = fp->rx_calls = 0;
+
+               /* Warning! this will genrate an interrupt (to the TSTORM) */
+               /* must only be done when chip is initialized */
+               REG_WR(bp, BAR_TSTRORM_INTMEM +
+                      TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod);
+               if (j != 0)
+                       continue;
+
+               REG_WR(bp, BAR_USTRORM_INTMEM +
+                      USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port),
+                      U64_LO(fp->rx_comp_mapping));
+               REG_WR(bp, BAR_USTRORM_INTMEM +
+                      USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port) + 4,
+                      U64_HI(fp->rx_comp_mapping));
+       }
+}
+
+static void bnx2x_init_tx_ring(struct bnx2x *bp)
+{
+       int i, j;
+
+       for_each_queue(bp, j) {
+               struct bnx2x_fastpath *fp = &bp->fp[j];
+
+               for (i = 1; i <= NUM_TX_RINGS; i++) {
+                       struct eth_tx_bd *tx_bd =
+                               &fp->tx_desc_ring[TX_DESC_CNT * i - 1];
+
+                       tx_bd->addr_hi =
+                               cpu_to_le32(U64_HI(fp->tx_desc_mapping +
+                                          BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+                       tx_bd->addr_lo =
+                               cpu_to_le32(U64_LO(fp->tx_desc_mapping +
+                                          BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+               }
+
+               fp->tx_pkt_prod = 0;
+               fp->tx_pkt_cons = 0;
+               fp->tx_bd_prod = 0;
+               fp->tx_bd_cons = 0;
+               fp->tx_cons_sb = BNX2X_TX_SB_INDEX;
+               fp->tx_pkt = 0;
+       }
+}
+
+static void bnx2x_init_sp_ring(struct bnx2x *bp)
+{
+       int port = bp->port;
+
+       spin_lock_init(&bp->spq_lock);
+
+       bp->spq_left = MAX_SPQ_PENDING;
+       bp->spq_prod_idx = 0;
+       bp->dsb_sp_prod_idx = 0;
+       bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX;
+       bp->spq_prod_bd = bp->spq;
+       bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT;
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port),
+              U64_LO(bp->spq_mapping));
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port) + 4,
+              U64_HI(bp->spq_mapping));
+
+       REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(port),
+              bp->spq_prod_idx);
+}
+
+static void bnx2x_init_context(struct bnx2x *bp)
+{
+       int i;
+
+       for_each_queue(bp, i) {
+               struct eth_context *context = bnx2x_sp(bp, context[i].eth);
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               context->xstorm_st_context.tx_bd_page_base_hi =
+                                               U64_HI(fp->tx_desc_mapping);
+               context->xstorm_st_context.tx_bd_page_base_lo =
+                                               U64_LO(fp->tx_desc_mapping);
+               context->xstorm_st_context.db_data_addr_hi =
+                                               U64_HI(fp->tx_prods_mapping);
+               context->xstorm_st_context.db_data_addr_lo =
+                                               U64_LO(fp->tx_prods_mapping);
+
+               context->ustorm_st_context.rx_bd_page_base_hi =
+                                               U64_HI(fp->rx_desc_mapping);
+               context->ustorm_st_context.rx_bd_page_base_lo =
+                                               U64_LO(fp->rx_desc_mapping);
+               context->ustorm_st_context.status_block_id = i;
+               context->ustorm_st_context.sb_index_number =
+                                               HC_INDEX_U_ETH_RX_CQ_CONS;
+               context->ustorm_st_context.rcq_base_address_hi =
+                                               U64_HI(fp->rx_comp_mapping);
+               context->ustorm_st_context.rcq_base_address_lo =
+                                               U64_LO(fp->rx_comp_mapping);
+               context->ustorm_st_context.flags =
+                               USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT;
+               context->ustorm_st_context.mc_alignment_size = 64;
+               context->ustorm_st_context.num_rss = bp->num_queues;
+
+               context->cstorm_st_context.sb_index_number =
+                                               HC_INDEX_C_ETH_TX_CQ_CONS;
+               context->cstorm_st_context.status_block_id = i;
+
+               context->xstorm_ag_context.cdu_reserved =
+                       CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+                                              CDU_REGION_NUMBER_XCM_AG,
+                                              ETH_CONNECTION_TYPE);
+               context->ustorm_ag_context.cdu_usage =
+                       CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i),
+                                              CDU_REGION_NUMBER_UCM_AG,
+                                              ETH_CONNECTION_TYPE);
+       }
+}
+
+static void bnx2x_init_ind_table(struct bnx2x *bp)
+{
+       int port = bp->port;
+       int i;
+
+       if (!is_multi(bp))
+               return;
+
+       for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
+               REG_WR8(bp, TSTORM_INDIRECTION_TABLE_OFFSET(port) + i,
+                       i % bp->num_queues);
+
+       REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
+}
+
+static void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
+{
+       int mode = bp->rx_mode;
+       int port = bp->port;
+       struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0};
+       int i;
+
+       DP(NETIF_MSG_RX_STATUS, "rx mode is %d\n", mode);
+
+       switch (mode) {
+       case BNX2X_RX_MODE_NONE: /* no Rx */
+               tstorm_mac_filter.ucast_drop_all = 1;
+               tstorm_mac_filter.mcast_drop_all = 1;
+               tstorm_mac_filter.bcast_drop_all = 1;
+               break;
+       case BNX2X_RX_MODE_NORMAL:
+               tstorm_mac_filter.bcast_accept_all = 1;
+               break;
+       case BNX2X_RX_MODE_ALLMULTI:
+               tstorm_mac_filter.mcast_accept_all = 1;
+               tstorm_mac_filter.bcast_accept_all = 1;
+               break;
+       case BNX2X_RX_MODE_PROMISC:
+               tstorm_mac_filter.ucast_accept_all = 1;
+               tstorm_mac_filter.mcast_accept_all = 1;
+               tstorm_mac_filter.bcast_accept_all = 1;
+               break;
+       default:
+               BNX2X_ERR("bad rx mode (%d)\n", mode);
+       }
+
+       for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) {
+               REG_WR(bp, BAR_TSTRORM_INTMEM +
+                      TSTORM_MAC_FILTER_CONFIG_OFFSET(port) + i * 4,
+                      ((u32 *)&tstorm_mac_filter)[i]);
+
+/*             DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i,
+                  ((u32 *)&tstorm_mac_filter)[i]); */
+       }
+}
+
+static void bnx2x_set_client_config(struct bnx2x *bp, int client_id)
+{
+#ifdef BCM_VLAN
+       int mode = bp->rx_mode;
+#endif
+       int port = bp->port;
+       struct tstorm_eth_client_config tstorm_client = {0};
+
+       tstorm_client.mtu = bp->dev->mtu;
+       tstorm_client.statistics_counter_id = 0;
+       tstorm_client.config_flags =
+               TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE;
+#ifdef BCM_VLAN
+       if (mode && bp->vlgrp) {
+               tstorm_client.config_flags |=
+                               TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE;
+               DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
+       }
+#endif
+       tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR |
+                                   TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR |
+                                   TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR |
+                                   TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR);
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_CLIENT_CONFIG_OFFSET(port, client_id),
+              ((u32 *)&tstorm_client)[0]);
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4,
+              ((u32 *)&tstorm_client)[1]);
+
+/*      DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n",
+          ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */
+}
+
+static void bnx2x_init_internal(struct bnx2x *bp)
+{
+       int port = bp->port;
+       struct tstorm_eth_function_common_config tstorm_config = {0};
+       struct stats_indication_flags stats_flags = {0};
+       int i;
+
+       if (is_multi(bp)) {
+               tstorm_config.config_flags = MULTI_FLAGS;
+               tstorm_config.rss_result_mask = MULTI_MASK;
+       }
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM +
+              TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(port),
+              (*(u32 *)&tstorm_config));
+
+/*      DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n",
+          (*(u32 *)&tstorm_config)); */
+
+       bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */
+       bnx2x_set_storm_rx_mode(bp);
+
+       for_each_queue(bp, i)
+               bnx2x_set_client_config(bp, i);
+
+
+       stats_flags.collect_eth = cpu_to_le32(1);
+
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port),
+              ((u32 *)&stats_flags)[0]);
+       REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port) + 4,
+              ((u32 *)&stats_flags)[1]);
+
+       REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port),
+              ((u32 *)&stats_flags)[0]);
+       REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port) + 4,
+              ((u32 *)&stats_flags)[1]);
+
+       REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port),
+              ((u32 *)&stats_flags)[0]);
+       REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port) + 4,
+              ((u32 *)&stats_flags)[1]);
+
+/*      DP(NETIF_MSG_IFUP, "stats_flags: 0x%08x 0x%08x\n",
+          ((u32 *)&stats_flags)[0], ((u32 *)&stats_flags)[1]); */
+}
+
+static void bnx2x_nic_init(struct bnx2x *bp)
+{
+       int i;
+
+       for_each_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               fp->state = BNX2X_FP_STATE_CLOSED;
+               DP(NETIF_MSG_IFUP, "bnx2x_init_sb(%p,%p,%d);\n",
+                  bp, fp->status_blk, i);
+               fp->index = i;
+               bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, i);
+       }
+
+       bnx2x_init_def_sb(bp, bp->def_status_blk,
+                         bp->def_status_blk_mapping, 0x10);
+       bnx2x_update_coalesce(bp);
+       bnx2x_init_rx_rings(bp);
+       bnx2x_init_tx_ring(bp);
+       bnx2x_init_sp_ring(bp);
+       bnx2x_init_context(bp);
+       bnx2x_init_internal(bp);
+       bnx2x_init_stats(bp);
+       bnx2x_init_ind_table(bp);
+       bnx2x_enable_int(bp);
+
+}
+
+/* end of nic init */
+
+/*
+ * gzip service functions
+ */
+
+static int bnx2x_gunzip_init(struct bnx2x *bp)
+{
+       bp->gunzip_buf = pci_alloc_consistent(bp->pdev, FW_BUF_SIZE,
+                                             &bp->gunzip_mapping);
+       if (bp->gunzip_buf  == NULL)
+               goto gunzip_nomem1;
+
+       bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL);
+       if (bp->strm  == NULL)
+               goto gunzip_nomem2;
+
+       bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
+                                     GFP_KERNEL);
+       if (bp->strm->workspace == NULL)
+               goto gunzip_nomem3;
+
+       return 0;
+
+gunzip_nomem3:
+       kfree(bp->strm);
+       bp->strm = NULL;
+
+gunzip_nomem2:
+       pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
+                           bp->gunzip_mapping);
+       bp->gunzip_buf = NULL;
+
+gunzip_nomem1:
+       printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for"
+              " uncompression\n", bp->dev->name);
+       return -ENOMEM;
+}
+
+static void bnx2x_gunzip_end(struct bnx2x *bp)
+{
+       kfree(bp->strm->workspace);
+
+       kfree(bp->strm);
+       bp->strm = NULL;
+
+       if (bp->gunzip_buf) {
+               pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf,
+                                   bp->gunzip_mapping);
+               bp->gunzip_buf = NULL;
+       }
+}
+
+static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
+{
+       int n, rc;
+
+       /* check gzip header */
+       if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
+               return -EINVAL;
+
+       n = 10;
+
+#define FNAME                          0x8
+
+       if (zbuf[3] & FNAME)
+               while ((zbuf[n++] != 0) && (n < len));
+
+       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;
+
+       rc = zlib_inflateInit2(bp->strm, -MAX_WBITS);
+       if (rc != Z_OK)
+               return rc;
+
+       rc = zlib_inflate(bp->strm, Z_FINISH);
+       if ((rc != Z_OK) && (rc != Z_STREAM_END))
+               printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
+                      bp->dev->name, bp->strm->msg);
+
+       bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out);
+       if (bp->gunzip_outlen & 0x3)
+               printk(KERN_ERR PFX "%s: Firmware decompression error:"
+                                   " gunzip_outlen (%d) not aligned\n",
+                      bp->dev->name, bp->gunzip_outlen);
+       bp->gunzip_outlen >>= 2;
+
+       zlib_inflateEnd(bp->strm);
+
+       if (rc == Z_STREAM_END)
+               return 0;
+
+       return rc;
+}
+
+/* nic load/unload */
+
+/*
+ * general service functions
+ */
+
+/* send a NIG loopback debug packet */
+static void bnx2x_lb_pckt(struct bnx2x *bp)
+{
+#ifdef USE_DMAE
+       u32 wb_write[3];
+#endif
+
+       /* Ethernet source and destination addresses */
+#ifdef USE_DMAE
+       wb_write[0] = 0x55555555;
+       wb_write[1] = 0x55555555;
+       wb_write[2] = 0x20;             /* SOP */
+       REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
+#else
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x55555555);
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555);
+       /* SOP */
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x20);
+#endif
+
+       /* NON-IP protocol */
+#ifdef USE_DMAE
+       wb_write[0] = 0x09000000;
+       wb_write[1] = 0x55555555;
+       wb_write[2] = 0x10;             /* EOP, eop_bvalid = 0 */
+       REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3);
+#else
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x09000000);
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555);
+       /* EOP, eop_bvalid = 0 */
+       REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x10);
+#endif
+}
+
+/* some of the internal memories
+ * are not directly readable from the driver
+ * to test them we send debug packets
+ */
+static int bnx2x_int_mem_test(struct bnx2x *bp)
+{
+       int factor;
+       int count, i;
+       u32 val = 0;
+
+       switch (CHIP_REV(bp)) {
+       case CHIP_REV_EMUL:
+               factor = 200;
+               break;
+       case CHIP_REV_FPGA:
+               factor = 120;
+               break;
+       default:
+               factor = 1;
+               break;
+       }
+
+       DP(NETIF_MSG_HW, "start part1\n");
+
+       /* Disable inputs of parser neighbor blocks */
+       REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
+       REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
+       REG_WR(bp, CFC_REG_DEBUG0, 0x1);
+       NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
+
+       /*  Write 0 to parser credits for CFC search request */
+       REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
+
+       /* send Ethernet packet */
+       bnx2x_lb_pckt(bp);
+
+       /* TODO do i reset NIG statistic? */
+       /* Wait until NIG register shows 1 packet of size 0x10 */
+       count = 1000 * factor;
+       while (count) {
+#ifdef BNX2X_DMAE_RD
+               bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+               val = *bnx2x_sp(bp, wb_data[0]);
+#else
+               val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
+               REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
+#endif
+               if (val == 0x10)
+                       break;
+
+               msleep(10);
+               count--;
+       }
+       if (val != 0x10) {
+               BNX2X_ERR("NIG timeout  val = 0x%x\n", val);
+               return -1;
+       }
+
+       /* Wait until PRS register shows 1 packet */
+       count = 1000 * factor;
+       while (count) {
+               val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+
+               if (val == 1)
+                       break;
+
+               msleep(10);
+               count--;
+       }
+       if (val != 0x1) {
+               BNX2X_ERR("PRS timeout val = 0x%x\n", val);
+               return -2;
+       }
+
+       /* Reset and init BRB, PRS */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x3);
+       msleep(50);
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x3);
+       msleep(50);
+       bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
+       bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+
+       DP(NETIF_MSG_HW, "part2\n");
+
+       /* Disable inputs of parser neighbor blocks */
+       REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0);
+       REG_WR(bp, TCM_REG_PRS_IFEN, 0x0);
+       REG_WR(bp, CFC_REG_DEBUG0, 0x1);
+       NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0);
+
+       /* Write 0 to parser credits for CFC search request */
+       REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0);
+
+       /* send 10 Ethernet packets */
+       for (i = 0; i < 10; i++)
+               bnx2x_lb_pckt(bp);
+
+       /* Wait until NIG register shows 10 + 1
+          packets of size 11*0x10 = 0xb0 */
+       count = 1000 * factor;
+       while (count) {
+#ifdef BNX2X_DMAE_RD
+               bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+               val = *bnx2x_sp(bp, wb_data[0]);
+#else
+               val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
+               REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
+#endif
+               if (val == 0xb0)
+                       break;
+
+               msleep(10);
+               count--;
+       }
+       if (val != 0xb0) {
+               BNX2X_ERR("NIG timeout  val = 0x%x\n", val);
+               return -3;
+       }
+
+       /* Wait until PRS register shows 2 packets */
+       val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+       if (val != 2)
+               BNX2X_ERR("PRS timeout  val = 0x%x\n", val);
+
+       /* Write 1 to parser credits for CFC search request */
+       REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1);
+
+       /* Wait until PRS register shows 3 packets */
+       msleep(10 * factor);
+       /* Wait until NIG register shows 1 packet of size 0x10 */
+       val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS);
+       if (val != 3)
+               BNX2X_ERR("PRS timeout  val = 0x%x\n", val);
+
+       /* clear NIG EOP FIFO */
+       for (i = 0; i < 11; i++)
+               REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO);
+       val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY);
+       if (val != 1) {
+               BNX2X_ERR("clear of NIG failed\n");
+               return -4;
+       }
+
+       /* Reset and init BRB, PRS, NIG */
+       REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03);
+       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);
+#ifndef BCM_ISCSI
+       /* set NIC mode */
+       REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif
+
+       /* Enable inputs of parser neighbor blocks */
+       REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff);
+       REG_WR(bp, TCM_REG_PRS_IFEN, 0x1);
+       REG_WR(bp, CFC_REG_DEBUG0, 0x0);
+       NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x1);
+
+       DP(NETIF_MSG_HW, "done\n");
+
+       return 0; /* OK */
+}
+
+static void enable_blocks_attention(struct bnx2x *bp)
+{
+       REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
+       REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0);
+       REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
+       REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
+       REG_WR(bp, QM_REG_QM_INT_MASK, 0);
+       REG_WR(bp, TM_REG_TM_INT_MASK, 0);
+       REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0);
+       REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0);
+       REG_WR(bp, XCM_REG_XCM_INT_MASK, 0);
+/*      REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */
+/*      REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */
+       REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0);
+       REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0);
+       REG_WR(bp, UCM_REG_UCM_INT_MASK, 0);
+/*      REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */
+/*      REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */
+       REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0);
+       REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0);
+       REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0);
+       REG_WR(bp, CCM_REG_CCM_INT_MASK, 0);
+/*      REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */
+/*      REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */
+       REG_WR(bp, PXP2_REG_PXP2_INT_MASK, 0x480000);
+       REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0);
+       REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0);
+       REG_WR(bp, TCM_REG_TCM_INT_MASK, 0);
+/*      REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */
+/*      REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */
+       REG_WR(bp, CDU_REG_CDU_INT_MASK, 0);
+       REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0);
+/*      REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */
+       REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18);         /* bit 3,4 masked */
+}
+
+static int bnx2x_function_init(struct bnx2x *bp, int mode)
+{
+       int func = bp->port;
+       int port = func ? PORT1 : PORT0;
+       u32 val, i;
+#ifdef USE_DMAE
+       u32 wb_write[2];
+#endif
+
+       DP(BNX2X_MSG_MCP, "function is %d  mode is %x\n", func, mode);
+       if ((func != 0) && (func != 1)) {
+               BNX2X_ERR("BAD function number (%d)\n", func);
+               return -ENODEV;
+       }
+
+       bnx2x_gunzip_init(bp);
+
+       if (mode & 0x1) {       /* init common */
+               DP(BNX2X_MSG_MCP, "starting common init  func %d  mode %x\n",
+                  func, mode);
+               REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff);
+               REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc);
+               bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
+
+               REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100);
+               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, PXP2_COMMON_START, PXP2_COMMON_END);
+
+               bnx2x_init_pxp(bp);
+
+               if (CHIP_REV(bp) == CHIP_REV_Ax) {
+                       /* enable HW interrupt from PXP on USDM
+                          overflow bit 16 on INT_MASK_0 */
+                       REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
+               }
+
+#ifdef __BIG_ENDIAN
+               REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
+               REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
+               REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
+               REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
+               REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
+               REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1);
+
+/*             REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
+               REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
+               REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
+               REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
+               REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
+#endif
+
+#ifndef BCM_ISCSI
+               /* set NIC mode */
+               REG_WR(bp, PRS_REG_NIC_MODE, 1);
+#endif
+
+               REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 5);
+#ifdef BCM_ISCSI
+               REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5);
+               REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5);
+               REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5);
+#endif
+
+               bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
+
+               /* let the HW do it's magic ... */
+               msleep(100);
+               /* finish PXP init
+                  (can be moved up if we want to use the DMAE) */
+               val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE);
+               if (val != 1) {
+                       BNX2X_ERR("PXP2 CFG failed\n");
+                       return -EBUSY;
+               }
+
+               val = REG_RD(bp, PXP2_REG_RD_INIT_DONE);
+               if (val != 1) {
+                       BNX2X_ERR("PXP2 RD_INIT failed\n");
+                       return -EBUSY;
+               }
+
+               REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
+               REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
+
+               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);
+
+#ifdef BNX2X_DMAE_RD
+               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);
+#else
+               REG_RD(bp, XSEM_REG_PASSIVE_BUFFER);
+               REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 4);
+               REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 8);
+               REG_RD(bp, CSEM_REG_PASSIVE_BUFFER);
+               REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 4);
+               REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 8);
+               REG_RD(bp, TSEM_REG_PASSIVE_BUFFER);
+               REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 4);
+               REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 8);
+               REG_RD(bp, USEM_REG_PASSIVE_BUFFER);
+               REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 4);
+               REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8);
+#endif
+               bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
+               /* softrest 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);
+#endif
+               bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
+               REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_BITS);
+               if (CHIP_REV(bp) == CHIP_REV_Ax) {
+                       /* 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);
+
+               if (CHIP_REV_IS_SLOW(bp)) {
+                       /* fix for emulation and FPGA for no pause */
+                       REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513);
+                       REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513);
+                       REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0);
+                       REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0);
+               }
+
+               bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+
+               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_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
+               bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
+               bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
+               bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE);
+
+               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);
+
+               /* sync semi rtc */
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+                      0x80000000);
+               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);
+
+               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: repleace with something meaningfull */
+               }
+               /* SRCH COMMON comes here */
+               REG_WR(bp, SRC_REG_SOFT_RST, 0);
+
+               if (sizeof(union cdu_context) != 1024) {
+                       /* we currently assume that a context is 1024 bytes */
+                       printk(KERN_ALERT PFX "please adjust the size of"
+                              " cdu_context(%ld)\n",
+                              (long)sizeof(union cdu_context));
+               }
+               val = (4 << 24) + (0 << 12) + 1024;
+               REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
+               bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
+
+               bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
+               REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
+
+               bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
+               bnx2x_init_block(bp, MISC_AEU_COMMON_START,
+                                MISC_AEU_COMMON_END);
+               /* RXPCS COMMON comes here */
+               /* EMAC0 COMMON comes here */
+               /* EMAC1 COMMON comes here */
+               /* DBU COMMON comes here */
+               /* DBG COMMON comes here */
+               bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
+
+               if (CHIP_REV_IS_SLOW(bp))
+                       msleep(200);
+
+               /* finish CFC init */
+               val = REG_RD(bp, CFC_REG_LL_INIT_DONE);
+               if (val != 1) {
+                       BNX2X_ERR("CFC LL_INIT failed\n");
+                       return -EBUSY;
+               }
+
+               val = REG_RD(bp, CFC_REG_AC_INIT_DONE);
+               if (val != 1) {
+                       BNX2X_ERR("CFC AC_INIT failed\n");
+                       return -EBUSY;
+               }
+
+               val = REG_RD(bp, CFC_REG_CAM_INIT_DONE);
+               if (val != 1) {
+                       BNX2X_ERR("CFC CAM_INIT failed\n");
+                       return -EBUSY;
+               }
+
+               REG_WR(bp, CFC_REG_DEBUG0, 0);
+
+               /* read NIG statistic
+                  to see if this is our first up since powerup */
+#ifdef BNX2X_DMAE_RD
+               bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2);
+               val = *bnx2x_sp(bp, wb_data[0]);
+#else
+               val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET);
+               REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4);
+#endif
+               /* do internal memory self test */
+               if ((val == 0) && bnx2x_int_mem_test(bp)) {
+                       BNX2X_ERR("internal mem selftest failed\n");
+                       return -EBUSY;
+               }
+
+               /* clear PXP2 attentions */
+               REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR);
+
+               enable_blocks_attention(bp);
+               /* enable_blocks_parity(bp); */
+
+       } /* end of common init */
+
+       /* per port init */
+
+       /* the phys address is shifted right 12 bits and has an added
+          1=valid bit added to the 53rd bit
+          then since this is a wide register(TM)
+          we split it into two 32 bit writes
+        */
+#define RQ_ONCHIP_AT_PORT_SIZE  384
+#define ONCHIP_ADDR1(x)   ((u32)(((u64)x >> 12) & 0xFFFFFFFF))
+#define ONCHIP_ADDR2(x)   ((u32)((1 << 20) | ((u64)x >> 44)))
+#define PXP_ONE_ILT(x)    ((x << 10) | x)
+
+       DP(BNX2X_MSG_MCP, "starting per-function init port is %x\n", func);
+
+       REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + func*4, 0);
+
+       /* Port PXP comes here */
+       /* Port PXP2 comes here */
+
+       /* Offset is
+        * Port0  0
+        * Port1  384 */
+       i = func * RQ_ONCHIP_AT_PORT_SIZE;
+#ifdef USE_DMAE
+       wb_write[0] = ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context));
+       wb_write[1] = ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context));
+       REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+#else
+       REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8,
+                  ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context)));
+       REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8 + 4,
+                  ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context)));
+#endif
+       REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, PXP_ONE_ILT(i));
+
+#ifdef BCM_ISCSI
+       /* Port0  1
+        * Port1  385 */
+       i++;
+       wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping);
+       wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping);
+       REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+       REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i));
+
+       /* Port0  2
+        * Port1  386 */
+       i++;
+       wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping);
+       wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping);
+       REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+       REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i));
+
+       /* Port0  3
+        * Port1  387 */
+       i++;
+       wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping);
+       wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping);
+       REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+       REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
+#endif
+
+       /* Port TCM comes here */
+       /* Port UCM comes here */
+       /* Port CCM comes here */
+       bnx2x_init_block(bp, func ? XCM_PORT1_START : XCM_PORT0_START,
+                            func ? XCM_PORT1_END : XCM_PORT0_END);
+
+#ifdef USE_DMAE
+       wb_write[0] = 0;
+       wb_write[1] = 0;
+#endif
+       for (i = 0; i < 32; i++) {
+               REG_WR(bp, QM_REG_BASEADDR + (func*32 + i)*4, 1024 * 4 * i);
+#ifdef USE_DMAE
+               REG_WR_DMAE(bp, QM_REG_PTRTBL + (func*32 + i)*8, wb_write, 2);
+#else
+               REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8, 0);
+               REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8 + 4, 0);
+#endif
+       }
+       REG_WR(bp, QM_REG_CONNNUM_0 + func*4, 1024/16 - 1);
+
+       /* 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);
+#endif
+       /* Port DQ comes here */
+       /* Port BRB1 comes here */
+       bnx2x_init_block(bp, func ? PRS_PORT1_START : PRS_PORT0_START,
+                            func ? PRS_PORT1_END : PRS_PORT0_END);
+       /* Port TSDM comes here */
+       /* Port CSDM comes here */
+       /* Port USDM comes here */
+       /* Port XSDM comes here */
+       bnx2x_init_block(bp, func ? TSEM_PORT1_START : TSEM_PORT0_START,
+                            func ? TSEM_PORT1_END : TSEM_PORT0_END);
+       bnx2x_init_block(bp, func ? USEM_PORT1_START : USEM_PORT0_START,
+                            func ? USEM_PORT1_END : USEM_PORT0_END);
+       bnx2x_init_block(bp, func ? CSEM_PORT1_START : CSEM_PORT0_START,
+                            func ? CSEM_PORT1_END : CSEM_PORT0_END);
+       bnx2x_init_block(bp, func ? XSEM_PORT1_START : XSEM_PORT0_START,
+                            func ? XSEM_PORT1_END : XSEM_PORT0_END);
+       /* Port UPB comes here */
+       /* Port XSDM comes here */
+       bnx2x_init_block(bp, func ? PBF_PORT1_START : PBF_PORT0_START,
+                            func ? PBF_PORT1_END : PBF_PORT0_END);
+
+       /* configure PBF to work without PAUSE mtu 9000 */
+       REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + func*4, 0);
+
+       /* update threshold */
+       REG_WR(bp, PBF_REG_P0_ARB_THRSH + func*4, (9040/16));
+       /* update init credit */
+       REG_WR(bp, PBF_REG_P0_INIT_CRD + func*4, (9040/16) + 553 - 22);
+
+       /* probe changes */
+       REG_WR(bp, PBF_REG_INIT_P0 + func*4, 1);
+       msleep(5);
+       REG_WR(bp, PBF_REG_INIT_P0 + func*4, 0);
+
+#ifdef BCM_ISCSI
+       /* tell the searcher where the T2 table is */
+       REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64);
+
+       wb_write[0] = U64_LO(bp->t2_mapping);
+       wb_write[1] = U64_HI(bp->t2_mapping);
+       REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2);
+       wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64);
+       wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64);
+       REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2);
+
+       REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10);
+       /* Port SRCH comes here */
+#endif
+       /* Port CDU comes here */
+       /* Port CFC comes here */
+       bnx2x_init_block(bp, func ? HC_PORT1_START : HC_PORT0_START,
+                            func ? HC_PORT1_END : HC_PORT0_END);
+       bnx2x_init_block(bp, func ? MISC_AEU_PORT1_START :
+                                   MISC_AEU_PORT0_START,
+                            func ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
+       /* Port PXPCS comes here */
+       /* Port EMAC0 comes here */
+       /* Port EMAC1 comes here */
+       /* Port DBU comes here */
+       /* Port DBG comes here */
+       bnx2x_init_block(bp, func ? NIG_PORT1_START : NIG_PORT0_START,
+                            func ? NIG_PORT1_END : NIG_PORT0_END);
+       REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + func*4, 1);
+       /* Port MCP comes here */
+       /* Port DMAE comes here */
+
+       bnx2x_link_reset(bp);
+
+       /* Reset pciex errors for debug */
+       REG_WR(bp, 0x2114, 0xffffffff);
+       REG_WR(bp, 0x2120, 0xffffffff);
+       REG_WR(bp, 0x2814, 0xffffffff);
+
+       /* !!! move to init_values.h */
+       REG_WR(bp, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
+       REG_WR(bp, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
+       REG_WR(bp, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
+       REG_WR(bp, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1);
+
+       REG_WR(bp, DBG_REG_PCI_REQ_CREDIT, 0x1);
+       REG_WR(bp, TM_REG_PCIARB_CRDCNT_VAL, 0x1);
+       REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264);
+       REG_WR(bp, CDU_REG_CDU_DEBUG, 0x0);
+
+       bnx2x_gunzip_end(bp);
+
+       if (!nomcp) {
+               port = bp->port;
+
+               bp->fw_drv_pulse_wr_seq =
+                               (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) &
+                                DRV_PULSE_SEQ_MASK);
+               bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param);
+               DP(BNX2X_MSG_MCP, "drv_pulse 0x%x  fw_mb 0x%x\n",
+                  bp->fw_drv_pulse_wr_seq, bp->fw_mb);
+       } else {
+               bp->fw_mb = 0;
+       }
+
+       return 0;
+}
+
+
+/* send the MCP a request, block untill there is a reply */
+static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
+{
+       u32 rc = 0;
+       u32 seq = ++bp->fw_seq;
+       int port = bp->port;
+
+       SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq);
+       DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq);
+
+       /* let the FW do it's magic ... */
+       msleep(100); /* TBD */
+
+       if (CHIP_REV_IS_SLOW(bp))
+               msleep(900);
+
+       rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header);
+
+       DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq);
+
+       /* is this a reply to our command? */
+       if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
+               rc &= FW_MSG_CODE_MASK;
+       } else {
+               /* FW BUG! */
+               BNX2X_ERR("FW failed to respond!\n");
+               bnx2x_fw_dump(bp);
+               rc = 0;
+       }
+       return rc;
+}
+
+static void bnx2x_free_mem(struct bnx2x *bp)
+{
+
+#define BNX2X_PCI_FREE(x, y, size) \
+       do { \
+               if (x) { \
+                       pci_free_consistent(bp->pdev, size, x, y); \
+                       x = NULL; \
+                       y = 0; \
+               } \
+       } while (0)
+
+#define BNX2X_FREE(x) \
+       do { \
+               if (x) { \
+                       vfree(x); \
+                       x = NULL; \
+               } \
+       } while (0)
+
+       int i;
+
+       /* fastpath */
+       for_each_queue(bp, i) {
+
+               /* Status blocks */
+               BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk),
+                              bnx2x_fp(bp, i, status_blk_mapping),
+                              sizeof(struct host_status_block) +
+                              sizeof(struct eth_tx_db_data));
+
+               /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
+               BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
+               BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
+                              bnx2x_fp(bp, i, tx_desc_mapping),
+                              sizeof(struct eth_tx_bd) * NUM_TX_BD);
+
+               BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
+               BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
+                              bnx2x_fp(bp, i, rx_desc_mapping),
+                              sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+               BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
+                              bnx2x_fp(bp, i, rx_comp_mapping),
+                              sizeof(struct eth_fast_path_rx_cqe) *
+                              NUM_RCQ_BD);
+       }
+
+       BNX2X_FREE(bp->fp);
+
+       /* end of fastpath */
+
+       BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
+                      (sizeof(struct host_def_status_block)));
+
+       BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping,
+                      (sizeof(struct bnx2x_slowpath)));
+
+#ifdef BCM_ISCSI
+       BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024);
+       BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024);
+       BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024);
+       BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024);
+#endif
+       BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, PAGE_SIZE);
+
+#undef BNX2X_PCI_FREE
+#undef BNX2X_KFREE
+}
+
+static int bnx2x_alloc_mem(struct bnx2x *bp)
+{
+
+#define BNX2X_PCI_ALLOC(x, y, size) \
+       do { \
+               x = pci_alloc_consistent(bp->pdev, size, y); \
+               if (x == NULL) \
+                       goto alloc_mem_err; \
+               memset(x, 0, size); \
+       } while (0)
+
+#define BNX2X_ALLOC(x, size) \
+       do { \
+               x = vmalloc(size); \
+               if (x == NULL) \
+                       goto alloc_mem_err; \
+               memset(x, 0, size); \
+       } while (0)
+
+       int i;
+
+       /* fastpath */
+       BNX2X_ALLOC(bp->fp, sizeof(struct bnx2x_fastpath) * bp->num_queues);
+
+       for_each_queue(bp, i) {
+               bnx2x_fp(bp, i, bp) = bp;
+
+               /* Status blocks */
+               BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk),
+                               &bnx2x_fp(bp, i, status_blk_mapping),
+                               sizeof(struct host_status_block) +
+                               sizeof(struct eth_tx_db_data));
+
+               bnx2x_fp(bp, i, hw_tx_prods) =
+                               (void *)(bnx2x_fp(bp, i, status_blk) + 1);
+
+               bnx2x_fp(bp, i, tx_prods_mapping) =
+                               bnx2x_fp(bp, i, status_blk_mapping) +
+                               sizeof(struct host_status_block);
+
+               /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */
+               BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
+                               sizeof(struct sw_tx_bd) * NUM_TX_BD);
+               BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
+                               &bnx2x_fp(bp, i, tx_desc_mapping),
+                               sizeof(struct eth_tx_bd) * NUM_TX_BD);
+
+               BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
+                               sizeof(struct sw_rx_bd) * NUM_RX_BD);
+               BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
+                               &bnx2x_fp(bp, i, rx_desc_mapping),
+                               sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+               BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
+                               &bnx2x_fp(bp, i, rx_comp_mapping),
+                               sizeof(struct eth_fast_path_rx_cqe) *
+                               NUM_RCQ_BD);
+
+       }
+       /* end of fastpath */
+
+       BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping,
+                       sizeof(struct host_def_status_block));
+
+       BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping,
+                       sizeof(struct bnx2x_slowpath));
+
+#ifdef BCM_ISCSI
+       BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024);
+
+       /* Initialize T1 */
+       for (i = 0; i < 64*1024; i += 64) {
+               *(u64 *)((char *)bp->t1 + i + 56) = 0x0UL;
+               *(u64 *)((char *)bp->t1 + i + 3) = 0x0UL;
+       }
+
+       /* allocate searcher T2 table
+          we allocate 1/4 of alloc num for T2
+         (which is not entered into the ILT) */
+       BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024);
+
+       /* Initialize T2 */
+       for (i = 0; i < 16*1024; i += 64)
+               * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64;
+
+       /* now sixup the last line in the block to point to the next block */
+       *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping;
+
+       /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */
+       BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024);
+
+       /* QM queues (128*MAX_CONN) */
+       BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024);
+#endif
+
+       /* Slow path ring */
+       BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE);
+
+       return 0;
+
+alloc_mem_err:
+       bnx2x_free_mem(bp);
+       return -ENOMEM;
+
+#undef BNX2X_PCI_ALLOC
+#undef BNX2X_ALLOC
+}
+
+static void bnx2x_free_tx_skbs(struct bnx2x *bp)
+{
+       int i;
+
+       for_each_queue(bp, i) {
+               struct bnx2x_fastpath *fp = &bp->fp[i];
+
+               u16 bd_cons = fp->tx_bd_cons;
+               u16 sw_prod = fp->tx_pkt_prod;
+               u16 sw_cons = fp->tx_pkt_cons;
+
+               BUG_TRAP(fp->tx_buf_ring != NULL);
+
+               while (sw_cons != sw_prod) {
+                       bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons));
+                       sw_cons++;
+               }
+       }
+}
+
+static void bnx2x_free_rx_skbs(struct bnx2x *bp)
+{
+       int i, j;
+
+       for_each_queue(bp, j) {
+               struct bnx2x_fastpath *fp = &bp->fp[j];
+
+               BUG_TRAP(fp->rx_buf_ring != NULL);
+
+               for (i = 0; i < NUM_RX_BD; i++) {
+                       struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
+                       struct sk_buff *skb = rx_buf->skb;
+
+                       if (skb == NULL)
+                               continue;
+
+                       pci_unmap_single(bp->pdev,
+                                        pci_unmap_addr(rx_buf, mapping),
+                                        bp->rx_buf_use_size,
+                                        PCI_DMA_FROMDEVICE);
+
+                       rx_buf->skb = NULL;
+                       dev_kfree_skb(skb);
+               }
+       }
+}
+
+static void bnx2x_free_skbs(struct bnx2x *bp)
+{
+       bnx2x_free_tx_skbs(bp);
+       bnx2x_free_rx_skbs(bp);
+}
+
+static void bnx2x_free_msix_irqs(struct bnx2x *bp)
+{
+       int i;
+
+       free_irq(bp->msix_table[0].vector, bp->dev);
+       DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n",
+          bp->msix_table[0].vector);
+
+       for_each_queue(bp, i) {
+               DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq  "
+                  "state(%x)\n", i, bp->msix_table[i + 1].vector,
+                  bnx2x_fp(bp, i, state));
+
+               if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) {
+
+                       free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]);
+                       bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED;
+
+               } else
+                       DP(NETIF_MSG_IFDOWN, "irq not freed\n");
+
+       }
+
+}
+
+static void bnx2x_free_irq(struct bnx2x *bp)
+{
+
+       if (bp->flags & USING_MSIX_FLAG) {
+
+               bnx2x_free_msix_irqs(bp);
+               pci_disable_msix(bp->pdev);
+
+               bp->flags &= ~USING_MSIX_FLAG;
+
+       } else
+               free_irq(bp->pdev->irq, bp->dev);
+}
+
+static int bnx2x_enable_msix(struct bnx2x *bp)
+{
+
+       int i;
+
+       bp->msix_table[0].entry = 0;
+       for_each_queue(bp, i)
+               bp->msix_table[i + 1].entry = i + 1;
+
+       if (pci_enable_msix(bp->pdev, &bp->msix_table[0],
+                                    bp->num_queues + 1)){
+               BNX2X_ERR("failed to enable msix\n");
+               return -1;
+
+       }
+
+       bp->flags |= USING_MSIX_FLAG;
+
+       return 0;
+
+}
+
+
+static int bnx2x_req_msix_irqs(struct bnx2x *bp)
+{
+
+
+       int i, rc;
+
+       DP(NETIF_MSG_IFUP, "about to request sp irq\n");
+
+       rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0,
+                        bp->dev->name, bp->dev);
+
+       if (rc) {
+               BNX2X_ERR("request sp irq failed\n");
+               return -EBUSY;
+       }
+
+       for_each_queue(bp, i) {
+               rc = request_irq(bp->msix_table[i + 1].vector,
+                                bnx2x_msix_fp_int, 0,
+                                bp->dev->name, &bp->fp[i]);
+
+               if (rc) {
+                       BNX2X_ERR("request fp #%d irq failed\n", i);
+                       bnx2x_free_msix_irqs(bp);
+                       return -EBUSY;
+               }
+
+               bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ;
+
+       }
+
+       return 0;
+
+}
+
+static int bnx2x_req_irq(struct bnx2x *bp)
+{
+
+       int rc = request_irq(bp->pdev->irq, bnx2x_interrupt,
+                            IRQF_SHARED, bp->dev->name, bp->dev);
+       if (!rc)
+               bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ;
+
+       return rc;
+
+}
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_set_mac_addr(struct bnx2x *bp)
+{
+       struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config);
+
+       /* CAM allocation
+        * unicasts 0-31:port0 32-63:port1
+        * multicast 64-127:port0 128-191:port1
+        */
+       config->hdr.length_6b = 2;
+       config->hdr.offset = bp->port ? 31 : 0;
+       config->hdr.reserved0 = 0;
+       config->hdr.reserved1 = 0;
+
+       /* primary MAC */
+       config->config_table[0].cam_entry.msb_mac_addr =
+                                       swab16(*(u16 *)&bp->dev->dev_addr[0]);
+       config->config_table[0].cam_entry.middle_mac_addr =
+                                       swab16(*(u16 *)&bp->dev->dev_addr[2]);
+       config->config_table[0].cam_entry.lsb_mac_addr =
+                                       swab16(*(u16 *)&bp->dev->dev_addr[4]);
+       config->config_table[0].cam_entry.flags = cpu_to_le16(bp->port);
+       config->config_table[0].target_table_entry.flags = 0;
+       config->config_table[0].target_table_entry.client_id = 0;
+       config->config_table[0].target_table_entry.vlan_id = 0;
+
+       DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x)\n",
+          config->config_table[0].cam_entry.msb_mac_addr,
+          config->config_table[0].cam_entry.middle_mac_addr,
+          config->config_table[0].cam_entry.lsb_mac_addr);
+
+       /* broadcast */
+       config->config_table[1].cam_entry.msb_mac_addr = 0xffff;
+       config->config_table[1].cam_entry.middle_mac_addr = 0xffff;
+       config->config_table[1].cam_entry.lsb_mac_addr = 0xffff;
+       config->config_table[1].cam_entry.flags = cpu_to_le16(bp->port);
+       config->config_table[1].target_table_entry.flags =
+                               TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST;
+       config->config_table[1].target_table_entry.client_id = 0;
+       config->config_table[1].target_table_entry.vlan_id = 0;
+
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+                     U64_HI(bnx2x_sp_mapping(bp, mac_config)),
+                     U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0);
+}
+
+static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx,
+                            int *state_p, int poll)
+{
+       /* can take a while if any port is running */
+       int timeout = 500;
+
+       /* DP("waiting for state to become %d on IDX [%d]\n",
+       state, sb_idx); */
+
+       might_sleep();
+
+       while (timeout) {
+
+               if (poll) {
+                       bnx2x_rx_int(bp->fp, 10);
+                       /* If index is different from 0
+                        * The reply for some commands will
+                        * be on the none default queue
+                        */
+                       if (idx)
+                               bnx2x_rx_int(&bp->fp[idx], 10);
+               }
+
+               mb(); /* state is changed by bnx2x_sp_event()*/
+
+               if (*state_p != state)
+                       return 0;
+
+               timeout--;
+               msleep(1);
+
+       }
+
+
+       /* timeout! */
+       BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx);
+       return -EBUSY;
+
+}
+
+static int bnx2x_setup_leading(struct bnx2x *bp)
+{
+
+       /* reset IGU staae */
+       bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+
+       /* SETUP ramrod */
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0);
+
+       return bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0);
+
+}
+
+static int bnx2x_setup_multi(struct bnx2x *bp, int index)
+{
+
+       /* reset IGU state */
+       bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0);
+
+       bp->fp[index].state = BNX2X_FP_STATE_OPENING;
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0);
+
+       /* Wait for completion */
+       return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index,
+                                &(bp->fp[index].state), 1);
+
+}
+
+
+static int bnx2x_poll(struct napi_struct *napi, int budget);
+static void bnx2x_set_rx_mode(struct net_device *dev);
+
+static int bnx2x_nic_load(struct bnx2x *bp, int req_irq)
+{
+       int rc;
+       int i = 0;
+
+       bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
+
+       /* Send LOAD_REQUEST command to MCP.
+          Returns the type of LOAD command: if it is the
+          first port to be initialized common blocks should be
+          initialized, otherwise - not.
+       */
+       if (!nomcp) {
+               rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ);
+               if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) {
+                       return -EBUSY; /* other port in diagnostic mode */
+               }
+       } else {
+               rc = FW_MSG_CODE_DRV_LOAD_COMMON;
+       }
+
+       DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues);
+
+       /* if we can't use msix we only need one fp,
+        * so try to enable msix with the requested number of fp's
+        * and fallback to inta with one fp
+        */
+       if (req_irq) {
+
+               if (use_inta) {
+                       bp->num_queues = 1;
+               } else {
+                       if (use_multi > 1 && use_multi <= 16)
+                               /* user requested number */
+                               bp->num_queues = use_multi;
+                       else if (use_multi == 1)
+                               bp->num_queues = num_online_cpus();
+                       else
+                               bp->num_queues = 1;
+
+                       if (bnx2x_enable_msix(bp)) {
+                               /* faild to enable msix */
+                               bp->num_queues = 1;
+                               if (use_multi)
+                                       BNX2X_ERR("Muti requested but failed"
+                                                 " to enable MSI-X\n");
+                       }
+               }
+       }
+
+       if (bnx2x_alloc_mem(bp))
+               return -ENOMEM;
+
+       if (req_irq) {
+               if (bp->flags & USING_MSIX_FLAG) {
+                       if (bnx2x_req_msix_irqs(bp)) {
+                               pci_disable_msix(bp->pdev);
+                               goto out_error;
+                       }
+
+               } else {
+                       if (bnx2x_req_irq(bp)) {
+                               BNX2X_ERR("IRQ request failed, aborting\n");
+                               goto out_error;
+                       }
+               }
+       }
+
+       for_each_queue(bp, i)
+               netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi),
+                              bnx2x_poll, 128);
+
+
+       /* Initialize HW */
+       if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) {
+               BNX2X_ERR("HW init failed, aborting\n");
+               goto out_error;
+       }
+
+
+       atomic_set(&bp->intr_sem, 0);
+
+       /* Reenable SP tasklet */
+       /*if (bp->sp_task_en) {                */
+       /*        tasklet_enable(&bp->sp_task);*/
+       /*} else {                             */
+       /*        bp->sp_task_en = 1;          */
+       /*}                                    */
+
+       /* Setup NIC internals and enable interrupts */
+       bnx2x_nic_init(bp);
+
+       /* Send LOAD_DONE command to MCP */
+       if (!nomcp) {
+               rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE);
+               DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc);
+               if (!rc) {
+                       BNX2X_ERR("MCP response failure, unloading\n");
+                       goto int_disable;
+               }
+       }
+
+       bp->state = BNX2X_STATE_OPENING_WAIT4_PORT;
+
+       /* Enable Rx interrupt handling before sending the ramrod
+          as it's completed on Rx FP queue */
+       for_each_queue(bp, i)
+               napi_enable(&bnx2x_fp(bp, i, napi));
+
+       if (bnx2x_setup_leading(bp))
+               goto stop_netif;
+
+       for_each_nondefault_queue(bp, i)
+               if (bnx2x_setup_multi(bp, i))
+                       goto stop_netif;
+
+       bnx2x_set_mac_addr(bp);
+
+       bnx2x_phy_init(bp);
+
+       /* Start fast path */
+       if (req_irq) { /* IRQ is only requested from bnx2x_open */
+               netif_start_queue(bp->dev);
+               if (bp->flags & USING_MSIX_FLAG)
+                       printk(KERN_INFO PFX "%s: using MSI-X\n",
+                              bp->dev->name);
+
+       /* Otherwise Tx queue should be only reenabled */
+       } else if (netif_running(bp->dev)) {
+               netif_wake_queue(bp->dev);
+               bnx2x_set_rx_mode(bp->dev);
+       }
+
+       /* start the timer */
+       mod_timer(&bp->timer, jiffies + bp->current_interval);
+
+       return 0;
+
+stop_netif:
+       for_each_queue(bp, i)
+               napi_disable(&bnx2x_fp(bp, i, napi));
+
+int_disable:
+       bnx2x_disable_int_sync(bp);
+
+       bnx2x_free_skbs(bp);
+       bnx2x_free_irq(bp);
+
+out_error:
+       bnx2x_free_mem(bp);
+
+       /* TBD we really need to reset the chip
+          if we want to recover from this */
+       return rc;
+}
+
+static void bnx2x_netif_stop(struct bnx2x *bp)
+{
+       int i;
+
+       bp->rx_mode = BNX2X_RX_MODE_NONE;
+       bnx2x_set_storm_rx_mode(bp);
+
+       bnx2x_disable_int_sync(bp);
+       bnx2x_link_reset(bp);
+
+       for_each_queue(bp, i)
+               napi_disable(&bnx2x_fp(bp, i, napi));
+
+       if (netif_running(bp->dev)) {
+               netif_tx_disable(bp->dev);
+               bp->dev->trans_start = jiffies; /* prevent tx timeout */
+       }
+}
+
+static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code)
+{
+       int port = bp->port;
+#ifdef USE_DMAE
+       u32 wb_write[2];
+#endif
+       int base, i;
+
+       DP(NETIF_MSG_IFDOWN, "reset called with code %x\n", reset_code);
+
+       /* Do not rcv packets to BRB */
+       REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0);
+       /* Do not direct rcv packets that are not for MCP to the BRB */
+       REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP :
+                          NIG_REG_LLH0_BRB1_NOT_MCP), 0x0);
+
+       /* Configure IGU and AEU */
+       REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000);
+       REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0);
+
+       /* TODO: Close Doorbell port? */
+
+       /* Clear ILT */
+#ifdef USE_DMAE
+       wb_write[0] = 0;
+       wb_write[1] = 0;
+#endif
+       base = port * RQ_ONCHIP_AT_PORT_SIZE;
+       for (i = base; i < base + RQ_ONCHIP_AT_PORT_SIZE; i++) {
+#ifdef USE_DMAE
+               REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2);
+#else
+               REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT, 0);
+               REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + 4, 0);
+#endif
+       }
+
+       if (reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) {
+               /* reset_common */
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
+                      0xd3ffff7f);
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
+                      0x1403);
+       }
+}
+
+static int bnx2x_stop_multi(struct bnx2x *bp, int index)
+{
+
+       int rc;
+
+       /* halt the connnection */
+       bp->fp[index].state = BNX2X_FP_STATE_HALTING;
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0);
+
+
+       rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index,
+                                      &(bp->fp[index].state), 1);
+       if (rc) /* timout */
+               return rc;
+
+       /* delete cfc entry */
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1);
+
+       return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index,
+                                &(bp->fp[index].state), 1);
+
+}
+
+
+static void bnx2x_stop_leading(struct bnx2x *bp)
+{
+
+       /* if the other port is hadling traffic,
+          this can take a lot of time */
+       int timeout = 500;
+
+       might_sleep();
+
+       /* Send HALT ramrod */
+       bp->fp[0].state = BNX2X_FP_STATE_HALTING;
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, 0, 0);
+
+       if (bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0,
+                              &(bp->fp[0].state), 1))
+               return;
+
+       bp->dsb_sp_prod_idx = *bp->dsb_sp_prod;
+
+       /* Send CFC_DELETE ramrod */
+       bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1);
+
+       /*
+          Wait for completion.
+          we are going to reset the chip anyway
+          so there is not much to do if this times out
+        */
+       while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) {
+                       timeout--;
+                       msleep(1);
+       }
+
+}
+
+static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq)
+{
+       u32 reset_code = 0;
+       int rc;
+       int i;
+
+       bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
+
+       /* Calling flush_scheduled_work() may deadlock because
+        * linkwatch_event() may be on the workqueue and it will try to get
+        * the rtnl_lock which we are holding.
+        */
+
+       while (bp->in_reset_task)
+               msleep(1);
+
+       /* Delete the timer: do it before disabling interrupts, as it
+          may be stil STAT_QUERY ramrod pending after stopping the timer */
+       del_timer_sync(&bp->timer);
+
+       /* Wait until stat ramrod returns and all SP tasks complete */
+       while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING))
+               msleep(1);
+
+       /* Stop fast path, disable MAC, disable interrupts, disable napi */
+       bnx2x_netif_stop(bp);
+
+       if (bp->flags & NO_WOL_FLAG)
+               reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
+       else if (bp->wol) {
+               u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
+               u8 *mac_addr = bp->dev->dev_addr;
+               u32 val = (EMAC_MODE_MPKT | EMAC_MODE_MPKT_RCVD |
+                          EMAC_MODE_ACPI_RCVD);
+
+               EMAC_WR(EMAC_REG_EMAC_MODE, val);
+
+               val = (mac_addr[0] << 8) | mac_addr[1];
+               EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
+
+               val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
+                     (mac_addr[4] << 8) | mac_addr[5];
+               EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
+
+               reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;
+       } else
+               reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
+
+       for_each_nondefault_queue(bp, i)
+               if (bnx2x_stop_multi(bp, i))
+                       goto error;
+
+
+       bnx2x_stop_leading(bp);
+
+error:
+       if (!nomcp)
+               rc = bnx2x_fw_command(bp, reset_code);
+       else
+               rc = FW_MSG_CODE_DRV_UNLOAD_COMMON;
+
+       /* Release IRQs */
+       if (fre_irq)
+               bnx2x_free_irq(bp);
+
+       /* Reset the chip */
+       bnx2x_reset_chip(bp, rc);
+
+       /* Report UNLOAD_DONE to MCP */
+       if (!nomcp)
+               bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
+
+       /* Free SKBs and driver internals */
+       bnx2x_free_skbs(bp);
+       bnx2x_free_mem(bp);
+
+       bp->state = BNX2X_STATE_CLOSED;
+       /* Set link down */
+       bp->link_up = 0;
+       netif_carrier_off(bp->dev);
+
+       return 0;
+}
+
+/* end of nic load/unload */
+
+/* ethtool_ops */
+
+/*
+ * Init service functions
+ */
+
+static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg)
+{
+       int port = bp->port;
+       u32 ext_phy_type;
+
+       bp->phy_flags = 0;
+
+       switch (switch_cfg) {
+       case SWITCH_CFG_1G:
+               BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg);
+
+               ext_phy_type = SERDES_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
+                                      ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10baseT_Half |
+                                         SUPPORTED_10baseT_Full |
+                                         SUPPORTED_100baseT_Half |
+                                         SUPPORTED_100baseT_Full |
+                                         SUPPORTED_1000baseT_Full |
+                                         SUPPORTED_2500baseT_Full |
+                                         SUPPORTED_TP | SUPPORTED_FIBRE |
+                                         SUPPORTED_Autoneg |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n",
+                                      ext_phy_type);
+
+                       bp->phy_flags |= PHY_SGMII_FLAG;
+
+                       bp->supported |= (/* SUPPORTED_10baseT_Half |
+                                            SUPPORTED_10baseT_Full |
+                                            SUPPORTED_100baseT_Half |
+                                            SUPPORTED_100baseT_Full |*/
+                                         SUPPORTED_1000baseT_Full |
+                                         SUPPORTED_TP | SUPPORTED_FIBRE |
+                                         SUPPORTED_Autoneg |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               default:
+                       BNX2X_ERR("NVRAM config error. "
+                                 "BAD SerDes ext_phy_config 0x%x\n",
+                                 bp->ext_phy_config);
+                       return;
+               }
+
+               bp->phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR +
+                                     port*0x10);
+               BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr);
+               break;
+
+       case SWITCH_CFG_10G:
+               BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg);
+
+               bp->phy_flags |= PHY_XGXS_FLAG;
+
+               ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+               switch (ext_phy_type) {
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n",
+                                      ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10baseT_Half |
+                                         SUPPORTED_10baseT_Full |
+                                         SUPPORTED_100baseT_Half |
+                                         SUPPORTED_100baseT_Full |
+                                         SUPPORTED_1000baseT_Full |
+                                         SUPPORTED_2500baseT_Full |
+                                         SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_TP | SUPPORTED_FIBRE |
+                                         SUPPORTED_Autoneg |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+               case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+                       BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n",
+                                      ext_phy_type);
+
+                       bp->supported |= (SUPPORTED_10000baseT_Full |
+                                         SUPPORTED_FIBRE |
+                                         SUPPORTED_Pause |
+                                         SUPPORTED_Asym_Pause);
+                       break;
+
+               default:
+                       BNX2X_ERR("NVRAM config error. "
+                                 "BAD XGXS ext_phy_config 0x%x\n",
+                                 bp->ext_phy_config);
+                       return;
+               }
+
+               bp->phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR +
+                                     port*0x18);
+               BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr);
+
+               bp->ser_lane = ((bp->lane_config &
+                                PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
+                               PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
+               bp->rx_lane_swap = ((bp->lane_config &
+                                    PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
+                                   PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
+               bp->tx_lane_swap = ((bp->lane_config &
+                                    PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
+                                   PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
+               BNX2X_DEV_INFO("rx_lane_swap 0x%x  tx_lane_swap 0x%x\n",
+                              bp->rx_lane_swap, bp->tx_lane_swap);
+               break;
+
+       default:
+               BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
+                         bp->link_config);
+               return;
+       }
+
+       /* mask what we support according to speed_cap_mask */
+       if (!(bp->speed_cap_mask &
+             PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
+               bp->supported &= ~SUPPORTED_10baseT_Half;
+
+       if (!(bp->speed_cap_mask &
+             PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
+               bp->supported &= ~SUPPORTED_10baseT_Full;
+
+       if (!(bp->speed_cap_mask &
+             PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
+               bp->supported &= ~SUPPORTED_100baseT_Half;
+
+       if (!(bp->speed_cap_mask &
+             PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
+               bp->supported &= ~SUPPORTED_100baseT_Full;
+
+       if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
+               bp->supported &= ~(SUPPORTED_1000baseT_Half |
+                                  SUPPORTED_1000baseT_Full);
+
+       if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
+               bp->supported &= ~SUPPORTED_2500baseT_Full;
+
+       if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
+               bp->supported &= ~SUPPORTED_10000baseT_Full;
+
+       BNX2X_DEV_INFO("supported 0x%x\n", bp->supported);
+}
+
+static void bnx2x_link_settings_requested(struct bnx2x *bp)
+{
+       bp->req_autoneg = 0;
+       bp->req_duplex = DUPLEX_FULL;
+
+       switch (bp->link_config & PORT_FEATURE_LINK_SPEED_MASK) {
+       case PORT_FEATURE_LINK_SPEED_AUTO:
+               if (bp->supported & SUPPORTED_Autoneg) {
+                       bp->req_autoneg |= AUTONEG_SPEED;
+                       bp->req_line_speed = 0;
+                       bp->advertising = bp->supported;
+               } else {
+                       u32 ext_phy_type;
+
+                       ext_phy_type = XGXS_EXT_PHY_TYPE(bp);
+                       if ((ext_phy_type ==
+                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
+                           (ext_phy_type ==
+                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) {
+                               /* force 10G, no AN */
+                               bp->req_line_speed = SPEED_10000;
+                               bp->advertising =
+                                               (ADVERTISED_10000baseT_Full |
+                                                ADVERTISED_FIBRE);
+                               break;
+                       }
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  Autoneg not supported\n",
+                                 bp->link_config);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_10M_FULL:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) {
+                       bp->req_line_speed = SPEED_10;
+                       bp->advertising = (ADVERTISED_10baseT_Full |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_10M_HALF:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) {
+                       bp->req_line_speed = SPEED_10;
+                       bp->req_duplex = DUPLEX_HALF;
+                       bp->advertising = (ADVERTISED_10baseT_Half |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_100M_FULL:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) {
+                       bp->req_line_speed = SPEED_100;
+                       bp->advertising = (ADVERTISED_100baseT_Full |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_100M_HALF:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) {
+                       bp->req_line_speed = SPEED_100;
+                       bp->req_duplex = DUPLEX_HALF;
+                       bp->advertising = (ADVERTISED_100baseT_Half |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_1G:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
+                       bp->req_line_speed = SPEED_1000;
+                       bp->advertising = (ADVERTISED_1000baseT_Full |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_2_5G:
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) {
+                       bp->req_line_speed = SPEED_2500;
+                       bp->advertising = (ADVERTISED_2500baseT_Full |
+                                          ADVERTISED_TP);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       case PORT_FEATURE_LINK_SPEED_10G_CX4:
+       case PORT_FEATURE_LINK_SPEED_10G_KX4:
+       case PORT_FEATURE_LINK_SPEED_10G_KR:
+               if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  phy_flags 0x%x\n",
+                                 bp->link_config, bp->phy_flags);
+                       return;
+               }
+               if (bp->speed_cap_mask &
+                   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
+                       bp->req_line_speed = SPEED_10000;
+                       bp->advertising = (ADVERTISED_10000baseT_Full |
+                                          ADVERTISED_FIBRE);
+               } else {
+                       BNX2X_ERR("NVRAM config error. "
+                                 "Invalid link_config 0x%x"
+                                 "  speed_cap_mask 0x%x\n",
+                                 bp->link_config, bp->speed_cap_mask);
+                       return;
+               }
+               break;
+
+       default:
+               BNX2X_ERR("NVRAM config error. "
+                         "BAD link speed link_config 0x%x\n",
+                         bp->link_config);
+               bp->req_autoneg |= AUTONEG_SPEED;
+               bp->req_line_speed = 0;
+               bp->advertising = bp->supported;
+               break;
+       }
+       BNX2X_DEV_INFO("req_line_speed %d  req_duplex %d\n",
+                      bp->req_line_speed, bp->req_duplex);
+
+       bp->req_flow_ctrl = (bp->link_config &
+                            PORT_FEATURE_FLOW_CONTROL_MASK);
+       /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */
+       switch (bp->req_flow_ctrl) {
+       case FLOW_CTRL_AUTO:
+               bp->req_autoneg |= AUTONEG_FLOW_CTRL;
+               if (bp->dev->mtu <= 4500) {
+                       bp->pause_mode = PAUSE_BOTH;
+                       bp->advertising |= (ADVERTISED_Pause |
+                                           ADVERTISED_Asym_Pause);
+               } else {
+                       bp->pause_mode = PAUSE_ASYMMETRIC;
+                       bp->advertising |= ADVERTISED_Asym_Pause;
+               }
+               break;
+
+       case FLOW_CTRL_TX:
+               bp->pause_mode = PAUSE_ASYMMETRIC;
+               bp->advertising |= ADVERTISED_Asym_Pause;
+               break;
+
+       case FLOW_CTRL_RX:
+       case FLOW_CTRL_BOTH:
+               bp->pause_mode = PAUSE_BOTH;
+               bp->advertising |= (ADVERTISED_Pause |
+                                   ADVERTISED_Asym_Pause);
+               break;
+
+       case FLOW_CTRL_NONE:
+       default:
+               bp->pause_mode = PAUSE_NONE;
+               bp->advertising &= ~(ADVERTISED_Pause |
+                                    ADVERTISED_Asym_Pause);
+               break;
+       }
+       BNX2X_DEV_INFO("req_autoneg 0x%x  req_flow_ctrl 0x%x\n"
+            KERN_INFO "  pause_mode %d  advertising 0x%x\n",
+                      bp->req_autoneg, bp->req_flow_ctrl,
+                      bp->pause_mode, bp->advertising);
+}
+
+static void bnx2x_get_hwinfo(struct bnx2x *bp)
+{
+       u32 val, val2, val3, val4, id;
+       int port = bp->port;
+       u32 switch_cfg;
+
+       bp->shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+       BNX2X_DEV_INFO("shmem offset is %x\n", bp->shmem_base);
+
+       /* Get the chip revision id and number. */
+       /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+       val = REG_RD(bp, MISC_REG_CHIP_NUM);
+       id = ((val & 0xffff) << 16);
+       val = REG_RD(bp, MISC_REG_CHIP_REV);
+       id |= ((val & 0xf) << 12);
+       val = REG_RD(bp, MISC_REG_CHIP_METAL);
+       id |= ((val & 0xff) << 4);
+       REG_RD(bp, MISC_REG_BOND_ID);
+       id |= (val & 0xf);
+       bp->chip_id = id;
+       BNX2X_DEV_INFO("chip ID is %x\n", id);
+
+       if (!bp->shmem_base || (bp->shmem_base != 0xAF900)) {
+               BNX2X_DEV_INFO("MCP not active\n");
+               nomcp = 1;
+               goto set_mac;
+       }
+
+       val = SHMEM_RD(bp, validity_map[port]);
+       if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
+               != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
+               BNX2X_ERR("MCP validity signature bad\n");
+
+       bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) &
+                     DRV_MSG_SEQ_NUMBER_MASK);
+
+       bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
+
+       bp->serdes_config =
+               SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config);
+       bp->lane_config =
+               SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
+       bp->ext_phy_config =
+               SHMEM_RD(bp,
+                        dev_info.port_hw_config[port].external_phy_config);
+       bp->speed_cap_mask =
+               SHMEM_RD(bp,
+                        dev_info.port_hw_config[port].speed_capability_mask);
+
+       bp->link_config =
+               SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
+
+       BNX2X_DEV_INFO("hw_config (%08x)  serdes_config (%08x)\n"
+            KERN_INFO "  lane_config (%08x)  ext_phy_config (%08x)\n"
+            KERN_INFO "  speed_cap_mask (%08x)  link_config (%08x)"
+                      "  fw_seq (%08x)\n",
+                      bp->hw_config, bp->serdes_config, bp->lane_config,
+                      bp->ext_phy_config, bp->speed_cap_mask,
+                      bp->link_config, bp->fw_seq);
+
+       switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK);
+       bnx2x_link_settings_supported(bp, switch_cfg);
+
+       bp->autoneg = (bp->hw_config & SHARED_HW_CFG_AN_ENABLE_MASK);
+       /* for now disable cl73 */
+       bp->autoneg &= ~SHARED_HW_CFG_AN_ENABLE_CL73;
+       BNX2X_DEV_INFO("autoneg 0x%x\n", bp->autoneg);
+
+       bnx2x_link_settings_requested(bp);
+
+       val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
+       val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
+       bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff);
+       bp->dev->dev_addr[1] = (u8)(val2 & 0xff);
+       bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff);
+       bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff);
+       bp->dev->dev_addr[4] = (u8)(val >> 8  & 0xff);
+       bp->dev->dev_addr[5] = (u8)(val & 0xff);
+
+       memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
+
+
+       val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num);
+       val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]);
+       val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]);
+       val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]);
+
+       printk(KERN_INFO PFX "part number %X-%X-%X-%X\n",
+              val, val2, val3, val4);
+
+       /* bc ver */
+       if (!nomcp) {
+               bp->bc_ver = val = ((SHMEM_RD(bp, dev_info.bc_rev)) >> 8);
+               BNX2X_DEV_INFO("bc_ver %X\n", val);
+               if (val < BNX2X_BC_VER) {
+                       /* for now only warn
+                        * later we might need to enforce this */
+                       BNX2X_ERR("This driver needs bc_ver %X but found %X,"
+                                 " please upgrade BC\n", BNX2X_BC_VER, val);
+               }
+       } else {
+               bp->bc_ver = 0;
+       }
+
+       val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4);
+       bp->flash_size = (NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE));
+       BNX2X_DEV_INFO("flash_size 0x%x (%d)\n",
+                      bp->flash_size, bp->flash_size);
+
+       return;
+
+set_mac: /* only supposed to happen on emulation/FPGA */
+       BNX2X_ERR("warning constant MAC workaround active\n");
+       bp->dev->dev_addr[0] = 0;
+       bp->dev->dev_addr[1] = 0x50;
+       bp->dev->dev_addr[2] = 0xc2;
+       bp->dev->dev_addr[3] = 0x2c;
+       bp->dev->dev_addr[4] = 0x71;
+       bp->dev->dev_addr[5] = port ? 0x0d : 0x0e;
+
+       memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6);
+
+}
+
+/*
+ * ethtool service functions
+ */
+
+/* All ethtool functions called with rtnl_lock */
+
+static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       cmd->supported = bp->supported;
+       cmd->advertising = bp->advertising;
+
+       if (netif_carrier_ok(dev)) {
+               cmd->speed = bp->line_speed;
+               cmd->duplex = bp->duplex;
+       } else {
+               cmd->speed = bp->req_line_speed;
+               cmd->duplex = bp->req_duplex;
+       }
+
+       if (bp->phy_flags & PHY_XGXS_FLAG) {
+               cmd->port = PORT_FIBRE;
+       } else {
+               cmd->port = PORT_TP;
+       }
+
+       cmd->phy_address = bp->phy_addr;
+       cmd->transceiver = XCVR_INTERNAL;
+
+       if (bp->req_autoneg & AUTONEG_SPEED) {
+               cmd->autoneg = AUTONEG_ENABLE;
+       } else {
+               cmd->autoneg = AUTONEG_DISABLE;
+       }
+
+       cmd->maxtxpkt = 0;
+       cmd->maxrxpkt = 0;
+
+       DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
+          DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
+          DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
+          DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
+          cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+          cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+          cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+       return 0;
+}
+
+static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       u32 advertising;
+
+       DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
+          DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
+          DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
+          DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
+          cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+          cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
+          cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
+
+       switch (cmd->port) {
+       case PORT_TP:
+               if (!(bp->supported & SUPPORTED_TP))
+                       return -EINVAL;
+
+               if (bp->phy_flags & PHY_XGXS_FLAG) {
+                       bnx2x_link_reset(bp);
+                       bnx2x_link_settings_supported(bp, SWITCH_CFG_1G);
+                       bnx2x_phy_deassert(bp);
+               }
+               break;
+
+       case PORT_FIBRE:
+               if (!(bp->supported & SUPPORTED_FIBRE))
+                       return -EINVAL;
+
+               if (!(bp->phy_flags & PHY_XGXS_FLAG)) {
+                       bnx2x_link_reset(bp);
+                       bnx2x_link_settings_supported(bp, SWITCH_CFG_10G);
+                       bnx2x_phy_deassert(bp);
+               }
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               if (!(bp->supported & SUPPORTED_Autoneg))
+                       return -EINVAL;
+
+               /* advertise the requested speed and duplex if supported */
+               cmd->advertising &= bp->supported;
+
+               bp->req_autoneg |= AUTONEG_SPEED;
+               bp->req_line_speed = 0;
+               bp->req_duplex = DUPLEX_FULL;
+               bp->advertising |= (ADVERTISED_Autoneg | cmd->advertising);
+
+       } else { /* forced speed */
+               /* advertise the requested speed and duplex if supported */
+               switch (cmd->speed) {
+               case SPEED_10:
+                       if (cmd->duplex == DUPLEX_FULL) {
+                               if (!(bp->supported & SUPPORTED_10baseT_Full))
+                                       return -EINVAL;
+
+                               advertising = (ADVERTISED_10baseT_Full |
+                                              ADVERTISED_TP);
+                       } else {
+                               if (!(bp->supported & SUPPORTED_10baseT_Half))
+                                       return -EINVAL;
+
+                               advertising = (ADVERTISED_10baseT_Half |
+                                              ADVERTISED_TP);
+                       }
+                       break;
+
+               case SPEED_100:
+                       if (cmd->duplex == DUPLEX_FULL) {
+                               if (!(bp->supported &
+                                               SUPPORTED_100baseT_Full))
+                                       return -EINVAL;
+
+                               advertising = (ADVERTISED_100baseT_Full |
+                                              ADVERTISED_TP);
+                       } else {
+                               if (!(bp->supported &
+                                               SUPPORTED_100baseT_Half))
+                                       return -EINVAL;
+
+                               advertising = (ADVERTISED_100baseT_Half |
+                                              ADVERTISED_TP);
+                       }
+                       break;
+
+               case SPEED_1000:
+                       if (cmd->duplex != DUPLEX_FULL)
+                               return -EINVAL;
+
+                       if (!(bp->supported & SUPPORTED_1000baseT_Full))
+                               return -EINVAL;
+
+                       advertising = (ADVERTISED_1000baseT_Full |
+                                      ADVERTISED_TP);
+                       break;
+
+               case SPEED_2500:
+                       if (cmd->duplex != DUPLEX_FULL)
+                               return -EINVAL;
+
+                       if (!(bp->supported & SUPPORTED_2500baseT_Full))
+                               return -EINVAL;
+
+                       advertising = (ADVERTISED_2500baseT_Full |
+                                      ADVERTISED_TP);
+                       break;
+
+               case SPEED_10000:
+                       if (cmd->duplex != DUPLEX_FULL)
+                               return -EINVAL;
+
+                       if (!(bp->supported & SUPPORTED_10000baseT_Full))
+                               return -EINVAL;
+
+                       advertising = (ADVERTISED_10000baseT_Full |
+                                      ADVERTISED_FIBRE);
+                       break;
+
+               default:
+                       return -EINVAL;
+               }
+
+               bp->req_autoneg &= ~AUTONEG_SPEED;
+               bp->req_line_speed = cmd->speed;
+               bp->req_duplex = cmd->duplex;
+               bp->advertising = advertising;
+       }
+
+       DP(NETIF_MSG_LINK, "req_autoneg 0x%x  req_line_speed %d\n"
+          DP_LEVEL "  req_duplex %d  advertising 0x%x\n",
+          bp->req_autoneg, bp->req_line_speed, bp->req_duplex,
+          bp->advertising);
+
+       bnx2x_stop_stats(bp);
+       bnx2x_link_initialize(bp);
+
+       return 0;
+}
+
+static void bnx2x_get_drvinfo(struct net_device *dev,
+                             struct ethtool_drvinfo *info)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       strcpy(info->driver, DRV_MODULE_NAME);
+       strcpy(info->version, DRV_MODULE_VERSION);
+       snprintf(info->fw_version, 32, "%d.%d.%d:%d (BC VER %x)",
+                BCM_5710_FW_MAJOR_VERSION, BCM_5710_FW_MINOR_VERSION,
+                BCM_5710_FW_REVISION_VERSION, BCM_5710_FW_COMPILE_FLAGS,
+                bp->bc_ver);
+       strcpy(info->bus_info, pci_name(bp->pdev));
+       info->n_stats = BNX2X_NUM_STATS;
+       info->testinfo_len = BNX2X_NUM_TESTS;
+       info->eedump_len = bp->flash_size;
+       info->regdump_len = 0;
+}
+
+static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if (bp->flags & NO_WOL_FLAG) {
+               wol->supported = 0;
+               wol->wolopts = 0;
+       } else {
+               wol->supported = WAKE_MAGIC;
+               if (bp->wol)
+                       wol->wolopts = WAKE_MAGIC;
+               else
+                       wol->wolopts = 0;
+       }
+       memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if (wol->wolopts & ~WAKE_MAGIC)
+               return -EINVAL;
+
+       if (wol->wolopts & WAKE_MAGIC) {
+               if (bp->flags & NO_WOL_FLAG)
+                       return -EINVAL;
+
+               bp->wol = 1;
+       } else {
+               bp->wol = 0;
+       }
+       return 0;
+}
+
+static u32 bnx2x_get_msglevel(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       return bp->msglevel;
+}
+
+static void bnx2x_set_msglevel(struct net_device *dev, u32 level)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if (capable(CAP_NET_ADMIN))
+               bp->msglevel = level;
+}
+
+static int bnx2x_nway_reset(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if (bp->state != BNX2X_STATE_OPEN) {
+               DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state);
+               return -EAGAIN;
+       }
+
+       bnx2x_stop_stats(bp);
+       bnx2x_link_initialize(bp);
+
+       return 0;
+}
+
+static int bnx2x_get_eeprom_len(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       return bp->flash_size;
+}
+
+static int bnx2x_acquire_nvram_lock(struct bnx2x *bp)
+{
+       int port = bp->port;
+       int count, i;
+       u32 val = 0;
+
+       /* adjust timeout for emulation/FPGA */
+       count = NVRAM_TIMEOUT_COUNT;
+       if (CHIP_REV_IS_SLOW(bp))
+               count *= 100;
+
+       /* request access to nvram interface */
+       REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+              (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port));
+
+       for (i = 0; i < count*10; i++) {
+               val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+               if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))
+                       break;
+
+               udelay(5);
+       }
+
+       if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) {
+               DP(NETIF_MSG_NVM, "cannot get access to nvram interface\n");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int bnx2x_release_nvram_lock(struct bnx2x *bp)
+{
+       int port = bp->port;
+       int count, i;
+       u32 val = 0;
+
+       /* adjust timeout for emulation/FPGA */
+       count = NVRAM_TIMEOUT_COUNT;
+       if (CHIP_REV_IS_SLOW(bp))
+               count *= 100;
+
+       /* relinquish nvram interface */
+       REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB,
+              (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port));
+
+       for (i = 0; i < count*10; i++) {
+               val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB);
+               if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)))
+                       break;
+
+               udelay(5);
+       }
+
+       if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) {
+               DP(NETIF_MSG_NVM, "cannot free access to nvram interface\n");
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static void bnx2x_enable_nvram_access(struct bnx2x *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+       /* enable both bits, even on read */
+       REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+              (val | MCPR_NVM_ACCESS_ENABLE_EN |
+                     MCPR_NVM_ACCESS_ENABLE_WR_EN));
+}
+
+static void bnx2x_disable_nvram_access(struct bnx2x *bp)
+{
+       u32 val;
+
+       val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE);
+
+       /* disable both bits, even after read */
+       REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE,
+              (val & ~(MCPR_NVM_ACCESS_ENABLE_EN |
+                       MCPR_NVM_ACCESS_ENABLE_WR_EN)));
+}
+
+static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val,
+                                 u32 cmd_flags)
+{
+       int rc;
+       int count, i;
+       u32 val;
+
+       /* build the command word */
+       cmd_flags |= MCPR_NVM_COMMAND_DOIT;
+
+       /* need to clear DONE bit separately */
+       REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+       /* address of the NVRAM to read from */
+       REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+              (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+       /* issue a read command */
+       REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+       /* adjust timeout for emulation/FPGA */
+       count = NVRAM_TIMEOUT_COUNT;
+       if (CHIP_REV_IS_SLOW(bp))
+               count *= 100;
+
+       /* wait for completion */
+       *ret_val = 0;
+       rc = -EBUSY;
+       for (i = 0; i < count; i++) {
+               udelay(5);
+               val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+
+               if (val & MCPR_NVM_COMMAND_DONE) {
+                       val = REG_RD(bp, MCP_REG_MCPR_NVM_READ);
+                       DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
+                       /* we read nvram data in cpu order
+                        * but ethtool sees it as an array of bytes
+                        * converting to big-endian will do the work */
+                       val = cpu_to_be32(val);
+                       *ret_val = val;
+                       rc = 0;
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf,
+                           int buf_size)
+{
+       int rc;
+       u32 cmd_flags;
+       u32 val;
+
+       if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+               DP(NETIF_MSG_NVM,
+                  "Invalid paramter: offset 0x%x  buf_size 0x%x\n",
+                  offset, buf_size);
+               return -EINVAL;
+       }
+
+       if (offset + buf_size > bp->flash_size) {
+               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+                                 " buf_size (0x%x) > flash_size (0x%x)\n",
+                  offset, buf_size, bp->flash_size);
+               return -EINVAL;
+       }
+
+       /* request access to nvram interface */
+       rc = bnx2x_acquire_nvram_lock(bp);
+       if (rc)
+               return rc;
+
+       /* enable access to nvram interface */
+       bnx2x_enable_nvram_access(bp);
+
+       /* read the first word(s) */
+       cmd_flags = MCPR_NVM_COMMAND_FIRST;
+       while ((buf_size > sizeof(u32)) && (rc == 0)) {
+               rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+               memcpy(ret_buf, &val, 4);
+
+               /* advance to the next dword */
+               offset += sizeof(u32);
+               ret_buf += sizeof(u32);
+               buf_size -= sizeof(u32);
+               cmd_flags = 0;
+       }
+
+       if (rc == 0) {
+               cmd_flags |= MCPR_NVM_COMMAND_LAST;
+               rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags);
+               memcpy(ret_buf, &val, 4);
+       }
+
+       /* disable access to nvram interface */
+       bnx2x_disable_nvram_access(bp);
+       bnx2x_release_nvram_lock(bp);
+
+       return rc;
+}
+
+static int bnx2x_get_eeprom(struct net_device *dev,
+                           struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       int rc;
+
+       DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+          DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
+          eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+          eeprom->len, eeprom->len);
+
+       /* parameters already validated in ethtool_get_eeprom */
+
+       rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
+
+       return rc;
+}
+
+static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val,
+                                  u32 cmd_flags)
+{
+       int rc;
+       int count, i;
+
+       /* build the command word */
+       cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR;
+
+       /* need to clear DONE bit separately */
+       REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE);
+
+       /* write the data */
+       REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val);
+
+       /* address of the NVRAM to write to */
+       REG_WR(bp, MCP_REG_MCPR_NVM_ADDR,
+              (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE));
+
+       /* issue the write command */
+       REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags);
+
+       /* adjust timeout for emulation/FPGA */
+       count = NVRAM_TIMEOUT_COUNT;
+       if (CHIP_REV_IS_SLOW(bp))
+               count *= 100;
+
+       /* wait for completion */
+       rc = -EBUSY;
+       for (i = 0; i < count; i++) {
+               udelay(5);
+               val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND);
+               if (val & MCPR_NVM_COMMAND_DONE) {
+                       rc = 0;
+                       break;
+               }
+       }
+
+       return rc;
+}
+
+#define BYTE_OFFSET(offset)            (8 * (offset & 0x03))
+
+static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf,
+                             int buf_size)
+{
+       int rc;
+       u32 cmd_flags;
+       u32 align_offset;
+       u32 val;
+
+       if (offset + buf_size > bp->flash_size) {
+               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+                                 " buf_size (0x%x) > flash_size (0x%x)\n",
+                  offset, buf_size, bp->flash_size);
+               return -EINVAL;
+       }
+
+       /* request access to nvram interface */
+       rc = bnx2x_acquire_nvram_lock(bp);
+       if (rc)
+               return rc;
+
+       /* enable access to nvram interface */
+       bnx2x_enable_nvram_access(bp);
+
+       cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST);
+       align_offset = (offset & ~0x03);
+       rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags);
+
+       if (rc == 0) {
+               val &= ~(0xff << BYTE_OFFSET(offset));
+               val |= (*data_buf << BYTE_OFFSET(offset));
+
+               /* nvram data is returned as an array of bytes
+                * convert it back to cpu order */
+               val = be32_to_cpu(val);
+
+               DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
+
+               rc = bnx2x_nvram_write_dword(bp, align_offset, val,
+                                            cmd_flags);
+       }
+
+       /* disable access to nvram interface */
+       bnx2x_disable_nvram_access(bp);
+       bnx2x_release_nvram_lock(bp);
+
+       return rc;
+}
+
+static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf,
+                            int buf_size)
+{
+       int rc;
+       u32 cmd_flags;
+       u32 val;
+       u32 written_so_far;
+
+       if (buf_size == 1) {    /* ethtool */
+               return bnx2x_nvram_write1(bp, offset, data_buf, buf_size);
+       }
+
+       if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) {
+               DP(NETIF_MSG_NVM,
+                  "Invalid paramter: offset 0x%x  buf_size 0x%x\n",
+                  offset, buf_size);
+               return -EINVAL;
+       }
+
+       if (offset + buf_size > bp->flash_size) {
+               DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +"
+                                 " buf_size (0x%x) > flash_size (0x%x)\n",
+                  offset, buf_size, bp->flash_size);
+               return -EINVAL;
+       }
+
+       /* request access to nvram interface */
+       rc = bnx2x_acquire_nvram_lock(bp);
+       if (rc)
+               return rc;
+
+       /* enable access to nvram interface */
+       bnx2x_enable_nvram_access(bp);
+
+       written_so_far = 0;
+       cmd_flags = MCPR_NVM_COMMAND_FIRST;
+       while ((written_so_far < buf_size) && (rc == 0)) {
+               if (written_so_far == (buf_size - sizeof(u32)))
+                       cmd_flags |= MCPR_NVM_COMMAND_LAST;
+               else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0)
+                       cmd_flags |= MCPR_NVM_COMMAND_LAST;
+               else if ((offset % NVRAM_PAGE_SIZE) == 0)
+                       cmd_flags |= MCPR_NVM_COMMAND_FIRST;
+
+               memcpy(&val, data_buf, 4);
+               DP(NETIF_MSG_NVM, "val 0x%08x\n", val);
+
+               rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags);
+
+               /* advance to the next dword */
+               offset += sizeof(u32);
+               data_buf += sizeof(u32);
+               written_so_far += sizeof(u32);
+               cmd_flags = 0;
+       }
+
+       /* disable access to nvram interface */
+       bnx2x_disable_nvram_access(bp);
+       bnx2x_release_nvram_lock(bp);
+
+       return rc;
+}
+
+static int bnx2x_set_eeprom(struct net_device *dev,
+                           struct ethtool_eeprom *eeprom, u8 *eebuf)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       int rc;
+
+       DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n"
+          DP_LEVEL "  magic 0x%x  offset 0x%x (%d)  len 0x%x (%d)\n",
+          eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset,
+          eeprom->len, eeprom->len);
+
+       /* parameters already validated in ethtool_set_eeprom */
+
+       rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
+
+       return rc;
+}
+
+static int bnx2x_get_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       memset(coal, 0, sizeof(struct ethtool_coalesce));
+
+       coal->rx_coalesce_usecs = bp->rx_ticks;
+       coal->tx_coalesce_usecs = bp->tx_ticks;
+       coal->stats_block_coalesce_usecs = bp->stats_ticks;
+
+       return 0;
+}
+
+static int bnx2x_set_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       bp->rx_ticks = (u16) coal->rx_coalesce_usecs;
+       if (bp->rx_ticks > 3000)
+               bp->rx_ticks = 3000;
+
+       bp->tx_ticks = (u16) coal->tx_coalesce_usecs;
+       if (bp->tx_ticks > 0x3000)
+               bp->tx_ticks = 0x3000;
+
+       bp->stats_ticks = coal->stats_block_coalesce_usecs;
+       if (bp->stats_ticks > 0xffff00)
+               bp->stats_ticks = 0xffff00;
+       bp->stats_ticks &= 0xffff00;
+
+       if (netif_running(bp->dev))
+               bnx2x_update_coalesce(bp);
+
+       return 0;
+}
+
+static void bnx2x_get_ringparam(struct net_device *dev,
+                               struct ethtool_ringparam *ering)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       ering->rx_max_pending = MAX_RX_AVAIL;
+       ering->rx_mini_max_pending = 0;
+       ering->rx_jumbo_max_pending = 0;
+
+       ering->rx_pending = bp->rx_ring_size;
+       ering->rx_mini_pending = 0;
+       ering->rx_jumbo_pending = 0;
+
+       ering->tx_max_pending = MAX_TX_AVAIL;
+       ering->tx_pending = bp->tx_ring_size;
+}
+
+static int bnx2x_set_ringparam(struct net_device *dev,
+                              struct ethtool_ringparam *ering)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if ((ering->rx_pending > MAX_RX_AVAIL) ||
+           (ering->tx_pending > MAX_TX_AVAIL) ||
+           (ering->tx_pending <= MAX_SKB_FRAGS + 4))
+               return -EINVAL;
+
+       bp->rx_ring_size = ering->rx_pending;
+       bp->tx_ring_size = ering->tx_pending;
+
+       if (netif_running(bp->dev)) {
+               bnx2x_nic_unload(bp, 0);
+               bnx2x_nic_load(bp, 0);
+       }
+
+       return 0;
+}
+
+static void bnx2x_get_pauseparam(struct net_device *dev,
+                                struct ethtool_pauseparam *epause)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       epause->autoneg =
+               ((bp->req_autoneg & AUTONEG_FLOW_CTRL) == AUTONEG_FLOW_CTRL);
+       epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) == FLOW_CTRL_RX);
+       epause->tx_pause = ((bp->flow_ctrl & FLOW_CTRL_TX) == FLOW_CTRL_TX);
+
+       DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
+          DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
+          epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+}
+
+static int bnx2x_set_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *epause)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n"
+          DP_LEVEL "  autoneg %d  rx_pause %d  tx_pause %d\n",
+          epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause);
+
+       bp->req_flow_ctrl = FLOW_CTRL_AUTO;
+       if (epause->autoneg) {
+               bp->req_autoneg |= AUTONEG_FLOW_CTRL;
+               if (bp->dev->mtu <= 4500) {
+                       bp->pause_mode = PAUSE_BOTH;
+                       bp->advertising |= (ADVERTISED_Pause |
+                                           ADVERTISED_Asym_Pause);
+               } else {
+                       bp->pause_mode = PAUSE_ASYMMETRIC;
+                       bp->advertising |= ADVERTISED_Asym_Pause;
+               }
+
+       } else {
+               bp->req_autoneg &= ~AUTONEG_FLOW_CTRL;
+
+               if (epause->rx_pause)
+                       bp->req_flow_ctrl |= FLOW_CTRL_RX;
+               if (epause->tx_pause)
+                       bp->req_flow_ctrl |= FLOW_CTRL_TX;
+
+               switch (bp->req_flow_ctrl) {
+               case FLOW_CTRL_AUTO:
+                       bp->req_flow_ctrl = FLOW_CTRL_NONE;
+                       bp->pause_mode = PAUSE_NONE;
+                       bp->advertising &= ~(ADVERTISED_Pause |
+                                            ADVERTISED_Asym_Pause);
+                       break;
+
+               case FLOW_CTRL_TX:
+                       bp->pause_mode = PAUSE_ASYMMETRIC;
+                       bp->advertising |= ADVERTISED_Asym_Pause;
+                       break;
+
+               case FLOW_CTRL_RX:
+               case FLOW_CTRL_BOTH:
+                       bp->pause_mode = PAUSE_BOTH;
+                       bp->advertising |= (ADVERTISED_Pause |
+                                           ADVERTISED_Asym_Pause);
+                       break;
+               }
+       }
+
+       DP(NETIF_MSG_LINK, "req_autoneg 0x%x  req_flow_ctrl 0x%x\n"
+          DP_LEVEL "  pause_mode %d  advertising 0x%x\n",
+          bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode,
+          bp->advertising);
+
+       bnx2x_stop_stats(bp);
+       bnx2x_link_initialize(bp);
+
+       return 0;
+}
+
+static u32 bnx2x_get_rx_csum(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       return bp->rx_csum;
+}
+
+static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       bp->rx_csum = data;
+       return 0;
+}
+
+static int bnx2x_set_tso(struct net_device *dev, u32 data)
+{
+       if (data)
+               dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
+       else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
+       return 0;
+}
+
+static struct {
+       char string[ETH_GSTRING_LEN];
+} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
+       { "MC Errors  (online)" }
+};
+
+static int bnx2x_self_test_count(struct net_device *dev)
+{
+       return BNX2X_NUM_TESTS;
+}
+
+static void bnx2x_self_test(struct net_device *dev,
+                           struct ethtool_test *etest, u64 *buf)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       int stats_state;
+
+       memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS);
+
+       if (bp->state != BNX2X_STATE_OPEN) {
+               DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state);
+               return;
+       }
+
+       stats_state = bp->stats_state;
+       bnx2x_stop_stats(bp);
+
+       if (bnx2x_mc_assert(bp) != 0) {
+               buf[0] = 1;
+               etest->flags |= ETH_TEST_FL_FAILED;
+       }
+
+#ifdef BNX2X_EXTRA_DEBUG
+       bnx2x_panic_dump(bp);
+#endif
+       bp->stats_state = stats_state;
+}
+
+static struct {
+       char string[ETH_GSTRING_LEN];
+} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = {
+       { "rx_bytes"},                           /*  0 */
+       { "rx_error_bytes"},                     /*  1 */
+       { "tx_bytes"},                           /*  2 */
+       { "tx_error_bytes"},                     /*  3 */
+       { "rx_ucast_packets"},                   /*  4 */
+       { "rx_mcast_packets"},                   /*  5 */
+       { "rx_bcast_packets"},                   /*  6 */
+       { "tx_ucast_packets"},                   /*  7 */
+       { "tx_mcast_packets"},                   /*  8 */
+       { "tx_bcast_packets"},                   /*  9 */
+       { "tx_mac_errors"},                      /* 10 */
+       { "tx_carrier_errors"},                  /* 11 */
+       { "rx_crc_errors"},                      /* 12 */
+       { "rx_align_errors"},                    /* 13 */
+       { "tx_single_collisions"},               /* 14 */
+       { "tx_multi_collisions"},                /* 15 */
+       { "tx_deferred"},                        /* 16 */
+       { "tx_excess_collisions"},               /* 17 */
+       { "tx_late_collisions"},                 /* 18 */
+       { "tx_total_collisions"},                /* 19 */
+       { "rx_fragments"},                       /* 20 */
+       { "rx_jabbers"},                         /* 21 */
+       { "rx_undersize_packets"},               /* 22 */
+       { "rx_oversize_packets"},                /* 23 */
+       { "rx_xon_frames"},                      /* 24 */
+       { "rx_xoff_frames"},                     /* 25 */
+       { "tx_xon_frames"},                      /* 26 */
+       { "tx_xoff_frames"},                     /* 27 */
+       { "rx_mac_ctrl_frames"},                 /* 28 */
+       { "rx_filtered_packets"},                /* 29 */
+       { "rx_discards"},                        /* 30 */
+};
+
+#define STATS_OFFSET32(offset_name) \
+       (offsetof(struct bnx2x_eth_stats, offset_name) / 4)
+
+static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = {
+       STATS_OFFSET32(total_bytes_received_hi),                     /*  0 */
+       STATS_OFFSET32(stat_IfHCInBadOctets_hi),                     /*  1 */
+       STATS_OFFSET32(total_bytes_transmitted_hi),                  /*  2 */
+       STATS_OFFSET32(stat_IfHCOutBadOctets_hi),                    /*  3 */
+       STATS_OFFSET32(total_unicast_packets_received_hi),           /*  4 */
+       STATS_OFFSET32(total_multicast_packets_received_hi),         /*  5 */
+       STATS_OFFSET32(total_broadcast_packets_received_hi),         /*  6 */
+       STATS_OFFSET32(total_unicast_packets_transmitted_hi),        /*  7 */
+       STATS_OFFSET32(total_multicast_packets_transmitted_hi),      /*  8 */
+       STATS_OFFSET32(total_broadcast_packets_transmitted_hi),      /*  9 */
+       STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors),     /* 10 */
+       STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors),            /* 11 */
+       STATS_OFFSET32(crc_receive_errors),                          /* 12 */
+       STATS_OFFSET32(alignment_errors),                            /* 13 */
+       STATS_OFFSET32(single_collision_transmit_frames),            /* 14 */
+       STATS_OFFSET32(multiple_collision_transmit_frames),          /* 15 */
+       STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions),         /* 16 */
+       STATS_OFFSET32(excessive_collision_frames),                  /* 17 */
+       STATS_OFFSET32(late_collision_frames),                       /* 18 */
+       STATS_OFFSET32(number_of_bugs_found_in_stats_spec),          /* 19 */
+       STATS_OFFSET32(runt_packets_received),                       /* 20 */
+       STATS_OFFSET32(jabber_packets_received),                     /* 21 */
+       STATS_OFFSET32(error_runt_packets_received),                 /* 22 */
+       STATS_OFFSET32(error_jabber_packets_received),               /* 23 */
+       STATS_OFFSET32(pause_xon_frames_received),                   /* 24 */
+       STATS_OFFSET32(pause_xoff_frames_received),                  /* 25 */
+       STATS_OFFSET32(pause_xon_frames_transmitted),                /* 26 */
+       STATS_OFFSET32(pause_xoff_frames_transmitted),               /* 27 */
+       STATS_OFFSET32(control_frames_received),                     /* 28 */
+       STATS_OFFSET32(mac_filter_discard),                          /* 29 */
+       STATS_OFFSET32(no_buff_discard),                             /* 30 */
+};
+
+static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = {
+       8, 0, 8, 0, 8, 8, 8, 8, 8, 8,
+       4, 0, 4, 4, 4, 4, 4, 4, 4, 4,
+       4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+       4,
+};
+
+static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
+{
+       switch (stringset) {
+       case ETH_SS_STATS:
+               memcpy(buf, bnx2x_stats_str_arr, sizeof(bnx2x_stats_str_arr));
+               break;
+
+       case ETH_SS_TEST:
+               memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr));
+               break;
+       }
+}
+
+static int bnx2x_get_stats_count(struct net_device *dev)
+{
+       return BNX2X_NUM_STATS;
+}
+
+static void bnx2x_get_ethtool_stats(struct net_device *dev,
+                                   struct ethtool_stats *stats, u64 *buf)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       u32 *hw_stats = (u32 *)bnx2x_sp_check(bp, eth_stats);
+       int i;
+
+       for (i = 0; i < BNX2X_NUM_STATS; i++) {
+               if (bnx2x_stats_len_arr[i] == 0) {
+                       /* skip this counter */
+                       buf[i] = 0;
+                       continue;
+               }
+               if (!hw_stats) {
+                       buf[i] = 0;
+                       continue;
+               }
+               if (bnx2x_stats_len_arr[i] == 4) {
+                       /* 4-byte counter */
+                      buf[i] = (u64) *(hw_stats + bnx2x_stats_offset_arr[i]);
+                       continue;
+               }
+               /* 8-byte counter */
+               buf[i] = HILO_U64(*(hw_stats + bnx2x_stats_offset_arr[i]),
+                                *(hw_stats + bnx2x_stats_offset_arr[i] + 1));
+       }
+}
+
+static int bnx2x_phys_id(struct net_device *dev, u32 data)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       int i;
+
+       if (data == 0)
+               data = 2;
+
+       for (i = 0; i < (data * 2); i++) {
+               if ((i % 2) == 0) {
+                       bnx2x_leds_set(bp, SPEED_1000);
+               } else {
+                       bnx2x_leds_unset(bp);
+               }
+               msleep_interruptible(500);
+               if (signal_pending(current))
+                       break;
+       }
+
+       if (bp->link_up)
+               bnx2x_leds_set(bp, bp->line_speed);
+
+       return 0;
+}
+
+static struct ethtool_ops bnx2x_ethtool_ops = {
+       .get_settings           = bnx2x_get_settings,
+       .set_settings           = bnx2x_set_settings,
+       .get_drvinfo            = bnx2x_get_drvinfo,
+       .get_wol                = bnx2x_get_wol,
+       .set_wol                = bnx2x_set_wol,
+       .get_msglevel           = bnx2x_get_msglevel,
+       .set_msglevel           = bnx2x_set_msglevel,
+       .nway_reset             = bnx2x_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = bnx2x_get_eeprom_len,
+       .get_eeprom             = bnx2x_get_eeprom,
+       .set_eeprom             = bnx2x_set_eeprom,
+       .get_coalesce           = bnx2x_get_coalesce,
+       .set_coalesce           = bnx2x_set_coalesce,
+       .get_ringparam          = bnx2x_get_ringparam,
+       .set_ringparam          = bnx2x_set_ringparam,
+       .get_pauseparam         = bnx2x_get_pauseparam,
+       .set_pauseparam         = bnx2x_set_pauseparam,
+       .get_rx_csum            = bnx2x_get_rx_csum,
+       .set_rx_csum            = bnx2x_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,
+       .set_tso                = bnx2x_set_tso,
+       .self_test_count        = bnx2x_self_test_count,
+       .self_test              = bnx2x_self_test,
+       .get_strings            = bnx2x_get_strings,
+       .phys_id                = bnx2x_phys_id,
+       .get_stats_count        = bnx2x_get_stats_count,
+       .get_ethtool_stats      = bnx2x_get_ethtool_stats
+};
+
+/* end of ethtool_ops */
+
+/****************************************************************************
+* General service functions
+****************************************************************************/
+
+static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state)
+{
+       u16 pmcsr;
+
+       pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr);
+
+       switch (state) {
+       case PCI_D0:
+               pci_write_config_word(bp->pdev,
+                                     bp->pm_cap + PCI_PM_CTRL,
+                                     ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) |
+                                      PCI_PM_CTRL_PME_STATUS));
+
+               if (pmcsr & PCI_PM_CTRL_STATE_MASK)
+               /* delay required during transition out of D3hot */
+                       msleep(20);
+               break;
+
+       case PCI_D3hot:
+               pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
+               pmcsr |= 3;
+
+               if (bp->wol)
+                       pmcsr |= PCI_PM_CTRL_PME_ENABLE;
+
+               pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL,
+                                     pmcsr);
+
+               /* No more memory access after this point until
+               * device is brought back to D0.
+               */
+               break;
+
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * net_device service functions
+ */
+
+/* Called with rtnl_lock from vlan functions and also netif_tx_lock
+ * from set_multicast.
+ */
+static void bnx2x_set_rx_mode(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       u32 rx_mode = BNX2X_RX_MODE_NORMAL;
+
+       DP(NETIF_MSG_IFUP, "called dev->flags = %x\n", dev->flags);
+
+       if (dev->flags & IFF_PROMISC)
+               rx_mode = BNX2X_RX_MODE_PROMISC;
+
+       else if ((dev->flags & IFF_ALLMULTI) ||
+                (dev->mc_count > BNX2X_MAX_MULTICAST))
+               rx_mode = BNX2X_RX_MODE_ALLMULTI;
+
+       else { /* some multicasts */
+               int i, old, offset;
+               struct dev_mc_list *mclist;
+               struct mac_configuration_cmd *config =
+                                               bnx2x_sp(bp, mcast_config);
+
+               for (i = 0, mclist = dev->mc_list;
+                    mclist && (i < dev->mc_count);
+                    i++, mclist = mclist->next) {
+
+                       config->config_table[i].cam_entry.msb_mac_addr =
+                                       swab16(*(u16 *)&mclist->dmi_addr[0]);
+                       config->config_table[i].cam_entry.middle_mac_addr =
+                                       swab16(*(u16 *)&mclist->dmi_addr[2]);
+                       config->config_table[i].cam_entry.lsb_mac_addr =
+                                       swab16(*(u16 *)&mclist->dmi_addr[4]);
+                       config->config_table[i].cam_entry.flags =
+                                                       cpu_to_le16(bp->port);
+                       config->config_table[i].target_table_entry.flags = 0;
+                       config->config_table[i].target_table_entry.
+                                                               client_id = 0;
+                       config->config_table[i].target_table_entry.
+                                                               vlan_id = 0;
+
+                       DP(NETIF_MSG_IFUP,
+                          "setting MCAST[%d] (%04x:%04x:%04x)\n",
+                          i, config->config_table[i].cam_entry.msb_mac_addr,
+                          config->config_table[i].cam_entry.middle_mac_addr,
+                          config->config_table[i].cam_entry.lsb_mac_addr);
+               }
+               old = config->hdr.length_6b;
+               if (old > i) {
+                       for (; i < old; i++) {
+                               if (CAM_IS_INVALID(config->config_table[i])) {
+                                       i--; /* already invalidated */
+                                       break;
+                               }
+                               /* invalidate */
+                               CAM_INVALIDATE(config->config_table[i]);
+                       }
+               }
+
+               if (CHIP_REV_IS_SLOW(bp))
+                       offset = BNX2X_MAX_EMUL_MULTI*(1 + bp->port);
+               else
+                       offset = BNX2X_MAX_MULTICAST*(1 + bp->port);
+
+               config->hdr.length_6b = i;
+               config->hdr.offset = offset;
+               config->hdr.reserved0 = 0;
+               config->hdr.reserved1 = 0;
+
+               bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0,
+                             U64_HI(bnx2x_sp_mapping(bp, mcast_config)),
+                             U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);
+       }
+
+       bp->rx_mode = rx_mode;
+       bnx2x_set_storm_rx_mode(bp);
+}
+
+static int bnx2x_poll(struct napi_struct *napi, int budget)
+{
+       struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath,
+                                                napi);
+       struct bnx2x *bp = fp->bp;
+       int work_done = 0;
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               goto out_panic;
+#endif
+
+       prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb);
+       prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb);
+       prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256);
+
+       bnx2x_update_fpsb_idx(fp);
+
+       if (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons)
+               bnx2x_tx_int(fp, budget);
+
+
+       if (le16_to_cpu(*fp->rx_cons_sb) != fp->rx_comp_cons)
+               work_done = bnx2x_rx_int(fp, budget);
+
+
+       rmb(); /* bnx2x_has_work() reads the status block */
+
+       /* must not complete if we consumed full budget */
+       if ((work_done < budget) && !bnx2x_has_work(fp)) {
+
+#ifdef BNX2X_STOP_ON_ERROR
+out_panic:
+#endif
+               netif_rx_complete(bp->dev, napi);
+
+               bnx2x_ack_sb(bp, fp->index, USTORM_ID,
+                            le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1);
+               bnx2x_ack_sb(bp, fp->index, CSTORM_ID,
+                            le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1);
+       }
+
+       return work_done;
+}
+
+/* Called with netif_tx_lock.
+ * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call
+ * netif_wake_queue().
+ */
+static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+       struct bnx2x_fastpath *fp;
+       struct sw_tx_bd *tx_buf;
+       struct eth_tx_bd *tx_bd;
+       struct eth_tx_parse_bd *pbd = NULL;
+       u16 pkt_prod, bd_prod;
+       int nbd, fp_index = 0;
+       dma_addr_t mapping;
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (unlikely(bp->panic))
+               return NETDEV_TX_BUSY;
+#endif
+
+       fp_index = smp_processor_id() % (bp->num_queues);
+
+       fp = &bp->fp[fp_index];
+       if (unlikely(bnx2x_tx_avail(bp->fp) <
+                                       (skb_shinfo(skb)->nr_frags + 3))) {
+               bp->slowpath->eth_stats.driver_xoff++,
+               netif_stop_queue(dev);
+               BNX2X_ERR("BUG! Tx ring full when queue awake!\n");
+               return NETDEV_TX_BUSY;
+       }
+
+       /*
+       This is a bit ugly. First we use one BD which we mark as start,
+       then for TSO or xsum we have a parsing info BD,
+       and only then we have the rest of the TSO bds.
+       (don't forget to mark the last one as last,
+       and to unmap only AFTER you write to the BD ...)
+       I would like to thank DovH for this mess.
+       */
+
+       pkt_prod = fp->tx_pkt_prod++;
+       bd_prod = fp->tx_bd_prod;
+       bd_prod = TX_BD(bd_prod);
+
+       /* get a tx_buff and first bd */
+       tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)];
+       tx_bd = &fp->tx_desc_ring[bd_prod];
+
+       tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD;
+       tx_bd->general_data = (UNICAST_ADDRESS <<
+                              ETH_TX_BD_ETH_ADDR_TYPE_SHIFT);
+       tx_bd->general_data |= 1; /* header nbd */
+
+       /* remeber the first bd of the packet */
+       tx_buf->first_bd = bd_prod;
+
+       DP(NETIF_MSG_TX_QUEUED,
+          "sending pkt %u @%p  next_idx %u  bd %u @%p\n",
+          pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd);
+
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               struct iphdr *iph = ip_hdr(skb);
+               u8 len;
+
+               tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM;
+
+               /* turn on parsing and get a bd */
+               bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+               pbd = (void *)&fp->tx_desc_ring[bd_prod];
+               len = ((u8 *)iph - (u8 *)skb->data) / 2;
+
+               /* for now NS flag is not used in Linux */
+               pbd->global_data = (len |
+                                   ((skb->protocol == ETH_P_8021Q) <<
+                                    ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT));
+               pbd->ip_hlen = ip_hdrlen(skb) / 2;
+               pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen);
+               if (iph->protocol == IPPROTO_TCP) {
+                       struct tcphdr *th = tcp_hdr(skb);
+
+                       tx_bd->bd_flags.as_bitfield |=
+                                               ETH_TX_BD_FLAGS_TCP_CSUM;
+                       pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF;
+                       pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2);
+                       pbd->tcp_pseudo_csum = swab16(th->check);
+
+               } else if (iph->protocol == IPPROTO_UDP) {
+                       struct udphdr *uh = udp_hdr(skb);
+
+                       tx_bd->bd_flags.as_bitfield |=
+                                               ETH_TX_BD_FLAGS_TCP_CSUM;
+                       pbd->total_hlen += cpu_to_le16(4);
+                       pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG;
+                       pbd->cs_offset = 5; /* 10 >> 1 */
+                       pbd->tcp_pseudo_csum = 0;
+                       /* HW bug: we need to subtract 10 bytes before the
+                        * UDP header from the csum
+                        */
+                       uh->check = (u16) ~csum_fold(csum_sub(uh->check,
+                               csum_partial(((u8 *)(uh)-10), 10, 0)));
+               }
+       }
+
+       if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) {
+               tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb));
+               tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG;
+       } else {
+               tx_bd->vlan = cpu_to_le16(pkt_prod);
+       }
+
+       mapping = pci_map_single(bp->pdev, skb->data,
+                                skb->len, PCI_DMA_TODEVICE);
+
+       tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+       tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+       nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL)? 1 : 2);
+       tx_bd->nbd = cpu_to_le16(nbd);
+       tx_bd->nbytes = cpu_to_le16(skb_headlen(skb));
+
+       DP(NETIF_MSG_TX_QUEUED, "first bd @%p  addr (%x:%x)  nbd %d"
+          "  nbytes %d  flags %x  vlan %u\n",
+          tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, tx_bd->nbd,
+          tx_bd->nbytes, tx_bd->bd_flags.as_bitfield, tx_bd->vlan);
+
+       if (skb_shinfo(skb)->gso_size &&
+           (skb->len > (bp->dev->mtu + ETH_HLEN))) {
+               int hlen = 2 * le32_to_cpu(pbd->total_hlen);
+
+               DP(NETIF_MSG_TX_QUEUED,
+                  "TSO packet len %d  hlen %d  total len %d  tso size %d\n",
+                  skb->len, hlen, skb_headlen(skb),
+                  skb_shinfo(skb)->gso_size);
+
+               tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO;
+
+               if (tx_bd->nbytes > cpu_to_le16(hlen)) {
+                       /* we split the first bd into headers and data bds
+                        * to ease the pain of our fellow micocode engineers
+                        * we use one mapping for both bds
+                        * So far this has only been observed to happen
+                        * in Other Operating Systems(TM)
+                        */
+
+                       /* first fix first bd */
+                       nbd++;
+                       tx_bd->nbd = cpu_to_le16(nbd);
+                       tx_bd->nbytes = cpu_to_le16(hlen);
+
+                       /* we only print this as an error
+                        * because we don't think this will ever happen.
+                        */
+                       BNX2X_ERR("TSO split header size is %d (%x:%x)"
+                                 "  nbd %d\n", tx_bd->nbytes, tx_bd->addr_hi,
+                                 tx_bd->addr_lo, tx_bd->nbd);
+
+                       /* now get a new data bd
+                        * (after the pbd) and fill it */
+                       bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+                       tx_bd = &fp->tx_desc_ring[bd_prod];
+
+                       tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+                       tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping) + hlen);
+                       tx_bd->nbytes = cpu_to_le16(skb_headlen(skb) - hlen);
+                       tx_bd->vlan = cpu_to_le16(pkt_prod);
+                       /* this marks the bd
+                        * as one that has no individual mapping
+                        * the FW ignors this flag in a bd not maked start
+                        */
+                       tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO;
+                       DP(NETIF_MSG_TX_QUEUED,
+                          "TSO split data size is %d (%x:%x)\n",
+                          tx_bd->nbytes, tx_bd->addr_hi, tx_bd->addr_lo);
+               }
+
+               if (!pbd) {
+                       /* supposed to be unreached
+                        * (and therefore not handled properly...)
+                        */
+                       BNX2X_ERR("LSO with no PBD\n");
+                       BUG();
+               }
+
+               pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+               pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq);
+               pbd->ip_id = swab16(ip_hdr(skb)->id);
+               pbd->tcp_pseudo_csum =
+                               swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr,
+                                                         ip_hdr(skb)->daddr,
+                                                         0, IPPROTO_TCP, 0));
+               pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN;
+       }
+
+       {
+               int i;
+
+               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+                       skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+                       bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+                       tx_bd = &fp->tx_desc_ring[bd_prod];
+
+                       mapping = pci_map_page(bp->pdev, frag->page,
+                                              frag->page_offset,
+                                              frag->size, PCI_DMA_TODEVICE);
+
+                       tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping));
+                       tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping));
+                       tx_bd->nbytes = cpu_to_le16(frag->size);
+                       tx_bd->vlan = cpu_to_le16(pkt_prod);
+                       tx_bd->bd_flags.as_bitfield = 0;
+                       DP(NETIF_MSG_TX_QUEUED, "frag %d  bd @%p"
+                          "  addr (%x:%x)  nbytes %d  flags %x\n",
+                          i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo,
+                          tx_bd->nbytes, tx_bd->bd_flags.as_bitfield);
+               } /* for */
+       }
+
+       /* now at last mark the bd as the last bd */
+       tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD;
+
+       DP(NETIF_MSG_TX_QUEUED, "last bd @%p  flags %x\n",
+          tx_bd, tx_bd->bd_flags.as_bitfield);
+
+       tx_buf->skb = skb;
+
+       bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
+
+       /* now send a tx doorbell, counting the next bd
+        * if the packet contains or ends with it
+        */
+       if (TX_BD_POFF(bd_prod) < nbd)
+               nbd++;
+
+       if (pbd)
+               DP(NETIF_MSG_TX_QUEUED,
+                  "PBD @%p  ip_data %x  ip_hlen %u  ip_id %u  lso_mss %u"
+                  "  tcp_flags %x  xsum %x  seq %u  hlen %u\n",
+                  pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id,
+                  pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum,
+                  pbd->tcp_send_seq, pbd->total_hlen);
+
+       DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u  bd %d\n", nbd, bd_prod);
+
+       fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd);
+       mb(); /* FW restriction: must not reorder writing nbd and packets */
+       fp->hw_tx_prods->packets_prod += cpu_to_le32(1);
+       DOORBELL(bp, fp_index, 0);
+
+       mmiowb();
+
+       fp->tx_bd_prod = bd_prod;
+       dev->trans_start = jiffies;
+
+       if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
+               netif_stop_queue(dev);
+               bp->slowpath->eth_stats.driver_xoff++;
+               if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
+                       netif_wake_queue(dev);
+       }
+       fp->tx_pkt++;
+
+       return NETDEV_TX_OK;
+}
+
+static struct net_device_stats *bnx2x_get_stats(struct net_device *dev)
+{
+       return &dev->stats;
+}
+
+/* Called with rtnl_lock */
+static int bnx2x_open(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       bnx2x_set_power_state(bp, PCI_D0);
+
+       return bnx2x_nic_load(bp, 1);
+}
+
+/* Called with rtnl_lock */
+static int bnx2x_close(struct net_device *dev)
+{
+       int rc;
+       struct bnx2x *bp = netdev_priv(dev);
+
+       /* Unload the driver, release IRQs */
+       rc = bnx2x_nic_unload(bp, 1);
+       if (rc) {
+               BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc);
+               return rc;
+       }
+       bnx2x_set_power_state(bp, PCI_D3hot);
+
+       return 0;
+}
+
+/* Called with rtnl_lock */
+static int bnx2x_change_mac_addr(struct net_device *dev, void *p)
+{
+       struct sockaddr *addr = p;
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+       if (netif_running(dev))
+               bnx2x_set_mac_addr(bp);
+
+       return 0;
+}
+
+/* Called with rtnl_lock */
+static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+       struct mii_ioctl_data *data = if_mii(ifr);
+       struct bnx2x *bp = netdev_priv(dev);
+       int err;
+
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = bp->phy_addr;
+
+               /* fallthru */
+       case SIOCGMIIREG: {
+               u32 mii_regval;
+
+               spin_lock_bh(&bp->phy_lock);
+               if (bp->state == BNX2X_STATE_OPEN) {
+                       err = bnx2x_mdio22_read(bp, data->reg_num & 0x1f,
+                                               &mii_regval);
+
+                       data->val_out = mii_regval;
+               } else {
+                       err = -EAGAIN;
+               }
+               spin_unlock_bh(&bp->phy_lock);
+               return err;
+       }
+
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+
+               spin_lock_bh(&bp->phy_lock);
+               if (bp->state == BNX2X_STATE_OPEN) {
+                       err = bnx2x_mdio22_write(bp, data->reg_num & 0x1f,
+                                                data->val_in);
+               } else {
+                       err = -EAGAIN;
+               }
+               spin_unlock_bh(&bp->phy_lock);
+               return err;
+
+       default:
+               /* do nothing */
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+/* Called with rtnl_lock */
+static int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
+           ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE))
+               return -EINVAL;
+
+       /* This does not race with packet allocation
+        * because the actuall alloc size is
+        * only updated as part of load
+        */
+       dev->mtu = new_mtu;
+
+       if (netif_running(dev)) {
+               bnx2x_nic_unload(bp, 0);
+               bnx2x_nic_load(bp, 0);
+       }
+       return 0;
+}
+
+static void bnx2x_tx_timeout(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       if (!bp->panic)
+               bnx2x_panic();
+#endif
+       /* This allows the netif to be shutdown gracefully before resetting */
+       schedule_work(&bp->reset_task);
+}
+
+#ifdef BCM_VLAN
+/* Called with rtnl_lock */
+static void bnx2x_vlan_rx_register(struct net_device *dev,
+                                  struct vlan_group *vlgrp)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       bp->vlgrp = vlgrp;
+       if (netif_running(dev))
+               bnx2x_set_rx_mode(dev);
+}
+#endif
+
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+static void poll_bnx2x(struct net_device *dev)
+{
+       struct bnx2x *bp = netdev_priv(dev);
+
+       disable_irq(bp->pdev->irq);
+       bnx2x_interrupt(bp->pdev->irq, dev);
+       enable_irq(bp->pdev->irq);
+}
+#endif
+
+static void bnx2x_reset_task(struct work_struct *work)
+{
+       struct bnx2x *bp = container_of(work, struct bnx2x, reset_task);
+
+#ifdef BNX2X_STOP_ON_ERROR
+       BNX2X_ERR("reset task called but STOP_ON_ERROR defined"
+                 " so reset not done to allow debug dump,\n"
+        KERN_ERR " you will need to reboot when done\n");
+       return;
+#endif
+
+       if (!netif_running(bp->dev))
+               return;
+
+       bp->in_reset_task = 1;
+
+       bnx2x_netif_stop(bp);
+
+       bnx2x_nic_unload(bp, 0);
+       bnx2x_nic_load(bp, 0);
+
+       bp->in_reset_task = 0;
+}
+
+static int __devinit bnx2x_init_board(struct pci_dev *pdev,
+                                     struct net_device *dev)
+{
+       struct bnx2x *bp;
+       int rc;
+
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       bp = netdev_priv(dev);
+
+       bp->flags = 0;
+       bp->port = PCI_FUNC(pdev->devfn);
+
+       rc = pci_enable_device(pdev);
+       if (rc) {
+               printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n");
+               goto err_out;
+       }
+
+       if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+               printk(KERN_ERR PFX "Cannot find PCI device base address,"
+                      " aborting\n");
+               rc = -ENODEV;
+               goto err_out_disable;
+       }
+
+       if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+               printk(KERN_ERR PFX "Cannot find second PCI device"
+                      " base address, aborting\n");
+               rc = -ENODEV;
+               goto err_out_disable;
+       }
+
+       rc = pci_request_regions(pdev, DRV_MODULE_NAME);
+       if (rc) {
+               printk(KERN_ERR PFX "Cannot obtain PCI resources,"
+                      " aborting\n");
+               goto err_out_disable;
+       }
+
+       pci_set_master(pdev);
+
+       bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+       if (bp->pm_cap == 0) {
+               printk(KERN_ERR PFX "Cannot find power management"
+                      " capability, aborting\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       if (bp->pcie_cap == 0) {
+               printk(KERN_ERR PFX "Cannot find PCI Express capability,"
+                      " aborting\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+               bp->flags |= USING_DAC_FLAG;
+               if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+                       printk(KERN_ERR PFX "pci_set_consistent_dma_mask"
+                              " failed, aborting\n");
+                       rc = -EIO;
+                       goto err_out_release;
+               }
+
+       } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) {
+               printk(KERN_ERR PFX "System does not support DMA,"
+                      " aborting\n");
+               rc = -EIO;
+               goto err_out_release;
+       }
+
+       bp->dev = dev;
+       bp->pdev = pdev;
+
+       spin_lock_init(&bp->phy_lock);
+
+       bp->in_reset_task = 0;
+
+       INIT_WORK(&bp->reset_task, bnx2x_reset_task);
+       INIT_WORK(&bp->sp_task, bnx2x_sp_task);
+
+       dev->base_addr = pci_resource_start(pdev, 0);
+
+       dev->irq = pdev->irq;
+
+       bp->regview = ioremap_nocache(dev->base_addr,
+                                     pci_resource_len(pdev, 0));
+       if (!bp->regview) {
+               printk(KERN_ERR PFX "Cannot map register space, aborting\n");
+               rc = -ENOMEM;
+               goto err_out_release;
+       }
+
+       bp->doorbells = ioremap_nocache(pci_resource_start(pdev , 2),
+                                       pci_resource_len(pdev, 2));
+       if (!bp->doorbells) {
+               printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n");
+               rc = -ENOMEM;
+               goto err_out_unmap;
+       }
+
+       bnx2x_set_power_state(bp, PCI_D0);
+
+       bnx2x_get_hwinfo(bp);
+
+       if (CHIP_REV(bp) == CHIP_REV_FPGA) {
+               printk(KERN_ERR PFX "FPGA detacted. MCP disabled,"
+                      " will only init first device\n");
+               onefunc = 1;
+               nomcp = 1;
+       }
+
+       if (nomcp) {
+               printk(KERN_ERR PFX "MCP disabled, will only"
+                      " init first device\n");
+               onefunc = 1;
+       }
+
+       if (onefunc && bp->port) {
+               printk(KERN_ERR PFX "Second device disabled, exiting\n");
+               rc = -ENODEV;
+               goto err_out_unmap;
+       }
+
+       bp->tx_ring_size = MAX_TX_AVAIL;
+       bp->rx_ring_size = MAX_RX_AVAIL;
+
+       bp->rx_csum = 1;
+
+       bp->rx_offset = 0;
+
+       bp->tx_quick_cons_trip_int = 0xff;
+       bp->tx_quick_cons_trip = 0xff;
+       bp->tx_ticks_int = 50;
+       bp->tx_ticks = 50;
+
+       bp->rx_quick_cons_trip_int = 0xff;
+       bp->rx_quick_cons_trip = 0xff;
+       bp->rx_ticks_int = 25;
+       bp->rx_ticks = 25;
+
+       bp->stats_ticks = 1000000 & 0xffff00;
+
+       bp->timer_interval = HZ;
+       bp->current_interval = (poll ? poll : HZ);
+
+       init_timer(&bp->timer);
+       bp->timer.expires = jiffies + bp->current_interval;
+       bp->timer.data = (unsigned long) bp;
+       bp->timer.function = bnx2x_timer;
+
+       return 0;
+
+err_out_unmap:
+       if (bp->regview) {
+               iounmap(bp->regview);
+               bp->regview = NULL;
+       }
+
+       if (bp->doorbells) {
+               iounmap(bp->doorbells);
+               bp->doorbells = NULL;
+       }
+
+err_out_release:
+       pci_release_regions(pdev);
+
+err_out_disable:
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+
+err_out:
+       return rc;
+}
+
+static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+                                   const struct pci_device_id *ent)
+{
+       static int version_printed;
+       struct net_device *dev = NULL;
+       struct bnx2x *bp;
+       int rc, i;
+       int port = PCI_FUNC(pdev->devfn);
+
+       if (version_printed++ == 0)
+               printk(KERN_INFO "%s", version);
+
+       /* dev zeroed in init_etherdev */
+       dev = alloc_etherdev(sizeof(*bp));
+       if (!dev)
+               return -ENOMEM;
+
+       netif_carrier_off(dev);
+
+       bp = netdev_priv(dev);
+       bp->msglevel = debug;
+
+       if (port && onefunc) {
+               printk(KERN_ERR PFX "second function disabled. exiting\n");
+               return 0;
+       }
+
+       rc = bnx2x_init_board(pdev, dev);
+       if (rc < 0) {
+               free_netdev(dev);
+               return rc;
+       }
+
+       dev->hard_start_xmit = bnx2x_start_xmit;
+       dev->watchdog_timeo = TX_TIMEOUT;
+
+       dev->get_stats = bnx2x_get_stats;
+       dev->ethtool_ops = &bnx2x_ethtool_ops;
+       dev->open = bnx2x_open;
+       dev->stop = bnx2x_close;
+       dev->set_multicast_list = bnx2x_set_rx_mode;
+       dev->set_mac_address = bnx2x_change_mac_addr;
+       dev->do_ioctl = bnx2x_ioctl;
+       dev->change_mtu = bnx2x_change_mtu;
+       dev->tx_timeout = bnx2x_tx_timeout;
+#ifdef BCM_VLAN
+       dev->vlan_rx_register = bnx2x_vlan_rx_register;
+#endif
+#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER)
+       dev->poll_controller = poll_bnx2x;
+#endif
+       dev->features |= NETIF_F_SG;
+       if (bp->flags & USING_DAC_FLAG)
+               dev->features |= NETIF_F_HIGHDMA;
+       dev->features |= NETIF_F_IP_CSUM;
+#ifdef BCM_VLAN
+       dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+#endif
+       dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
+
+       rc = register_netdev(dev);
+       if (rc) {
+               printk(KERN_ERR PFX "Cannot register net device\n");
+               if (bp->regview)
+                       iounmap(bp->regview);
+               if (bp->doorbells)
+                       iounmap(bp->doorbells);
+               pci_release_regions(pdev);
+               pci_disable_device(pdev);
+               pci_set_drvdata(pdev, NULL);
+               free_netdev(dev);
+               return rc;
+       }
+
+       pci_set_drvdata(pdev, dev);
+
+       bp->name = board_info[ent->driver_data].name;
+       printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz "
+              "found at mem %lx, IRQ %d, ",
+              dev->name, bp->name,
+              ((CHIP_ID(bp) & 0xf000) >> 12) + 'A',
+              ((CHIP_ID(bp) & 0x0ff0) >> 4),
+              ((bp->flags & PCIX_FLAG) ? "-X" : ""),
+              ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
+              bp->bus_speed_mhz,
+              dev->base_addr,
+              bp->pdev->irq);
+
+       printk("node addr ");
+       for (i = 0; i < 6; i++)
+               printk("%2.2x", dev->dev_addr[i]);
+       printk("\n");
+
+       return 0;
+}
+
+static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2x *bp = netdev_priv(dev);
+
+       flush_scheduled_work();
+       /*tasklet_kill(&bp->sp_task);*/
+       unregister_netdev(dev);
+
+       if (bp->regview)
+               iounmap(bp->regview);
+
+       if (bp->doorbells)
+               iounmap(bp->doorbells);
+
+       free_netdev(dev);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2x *bp = netdev_priv(dev);
+       int rc;
+
+       if (!netif_running(dev))
+               return 0;
+
+       rc = bnx2x_nic_unload(bp, 0);
+       if (!rc)
+               return rc;
+
+       netif_device_detach(dev);
+       pci_save_state(pdev);
+
+       bnx2x_set_power_state(bp, pci_choose_state(pdev, state));
+       return 0;
+}
+
+static int bnx2x_resume(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+       struct bnx2x *bp = netdev_priv(dev);
+       int rc;
+
+       if (!netif_running(dev))
+               return 0;
+
+       pci_restore_state(pdev);
+
+       bnx2x_set_power_state(bp, PCI_D0);
+       netif_device_attach(dev);
+
+       rc = bnx2x_nic_load(bp, 0);
+       if (rc)
+               return rc;
+
+       return 0;
+}
+
+static struct pci_driver bnx2x_pci_driver = {
+       .name       = DRV_MODULE_NAME,
+       .id_table   = bnx2x_pci_tbl,
+       .probe      = bnx2x_init_one,
+       .remove     = __devexit_p(bnx2x_remove_one),
+       .suspend    = bnx2x_suspend,
+       .resume     = bnx2x_resume,
+};
+
+static int __init bnx2x_init(void)
+{
+       return pci_register_driver(&bnx2x_pci_driver);
+}
+
+static void __exit bnx2x_cleanup(void)
+{
+       pci_unregister_driver(&bnx2x_pci_driver);
+}
+
+module_init(bnx2x_init);
+module_exit(bnx2x_cleanup);
+
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
new file mode 100644 (file)
index 0000000..4f7ae6f
--- /dev/null
@@ -0,0 +1,1071 @@
+/* bnx2x.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ *
+ * Written by: Eliezer Tamir <eliezert@broadcom.com>
+ * Based on code from Michael Chan's bnx2 driver
+ */
+
+#ifndef BNX2X_H
+#define BNX2X_H
+
+/* error/debug prints */
+
+#define DRV_MODULE_NAME        "bnx2x"
+#define PFX DRV_MODULE_NAME     ": "
+
+/* for messages that are currently off */
+#define BNX2X_MSG_OFF                  0
+#define BNX2X_MSG_MCP                  0x10000 /* was: NETIF_MSG_HW */
+#define BNX2X_MSG_STATS                0x20000 /* was: NETIF_MSG_TIMER */
+#define NETIF_MSG_NVM                  0x40000 /* was: NETIF_MSG_HW */
+#define NETIF_MSG_DMAE                 0x80000 /* was: NETIF_MSG_HW */
+
+#define DP_LEVEL                       KERN_NOTICE     /* was: KERN_DEBUG */
+
+/* regular debug print */
+#define DP(__mask, __fmt, __args...) do { \
+       if (bp->msglevel & (__mask)) \
+               printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __FUNCTION__, \
+               __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+       } while (0)
+
+/* for errors (never masked) */
+#define BNX2X_ERR(__fmt, __args...) do { \
+       printk(KERN_ERR "[%s:%d(%s)]" __fmt, __FUNCTION__, \
+               __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \
+       } while (0)
+
+/* before we have a dev->name use dev_info() */
+#define BNX2X_DEV_INFO(__fmt, __args...) do { \
+       if (bp->msglevel & NETIF_MSG_PROBE) \
+               dev_info(&bp->pdev->dev, __fmt, ##__args); \
+       } while (0)
+
+
+#ifdef BNX2X_STOP_ON_ERROR
+#define bnx2x_panic() do { \
+               bp->panic = 1; \
+               BNX2X_ERR("driver assert\n"); \
+               bnx2x_disable_int(bp); \
+               bnx2x_panic_dump(bp); \
+       } while (0)
+#else
+#define bnx2x_panic() do { \
+               BNX2X_ERR("driver assert\n"); \
+               bnx2x_panic_dump(bp); \
+       } while (0)
+#endif
+
+
+#define U64_LO(x)                      (((u64)x) & 0xffffffff)
+#define U64_HI(x)                      (((u64)x) >> 32)
+#define HILO_U64(hi, lo)               (((u64)hi << 32) + lo)
+
+
+#define REG_ADDR(bp, offset)           (bp->regview + offset)
+
+#define REG_RD(bp, offset)             readl(REG_ADDR(bp, offset))
+#define REG_RD8(bp, offset)            readb(REG_ADDR(bp, offset))
+#define REG_RD64(bp, offset)           readq(REG_ADDR(bp, offset))
+
+#define REG_WR(bp, offset, val)        writel((u32)val, REG_ADDR(bp, offset))
+#define REG_WR8(bp, offset, val)       writeb((u8)val, REG_ADDR(bp, offset))
+#define REG_WR16(bp, offset, val)       writew((u16)val, REG_ADDR(bp, offset))
+#define REG_WR32(bp, offset, val)       REG_WR(bp, offset, val)
+
+#define REG_RD_IND(bp, offset)         bnx2x_reg_rd_ind(bp, offset)
+#define REG_WR_IND(bp, offset, val)     bnx2x_reg_wr_ind(bp, offset, val)
+
+#define REG_WR_DMAE(bp, offset, val, len32) \
+       do { \
+               memcpy(bnx2x_sp(bp, wb_data[0]), val, len32 * 4); \
+               bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
+                                offset, len32); \
+       } while (0)
+
+#define SHMEM_RD(bp, type) \
+       REG_RD(bp, bp->shmem_base + offsetof(struct shmem_region, type))
+#define SHMEM_WR(bp, type, val) \
+       REG_WR(bp, bp->shmem_base + offsetof(struct shmem_region, type), val)
+
+#define NIG_WR(reg, val)       REG_WR(bp, reg, val)
+#define EMAC_WR(reg, val)       REG_WR(bp, emac_base + reg, val)
+#define BMAC_WR(reg, val)       REG_WR(bp, GRCBASE_NIG + bmac_addr + reg, val)
+
+
+#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++)
+
+#define for_each_nondefault_queue(bp, var) \
+                               for (var = 1; var < bp->num_queues; var++)
+#define is_multi(bp)           (bp->num_queues > 1)
+
+
+struct regp {
+       u32 lo;
+       u32 hi;
+};
+
+struct bmac_stats {
+       struct regp tx_gtpkt;
+       struct regp tx_gtxpf;
+       struct regp tx_gtfcs;
+       struct regp tx_gtmca;
+       struct regp tx_gtgca;
+       struct regp tx_gtfrg;
+       struct regp tx_gtovr;
+       struct regp tx_gt64;
+       struct regp tx_gt127;
+       struct regp tx_gt255;   /* 10 */
+       struct regp tx_gt511;
+       struct regp tx_gt1023;
+       struct regp tx_gt1518;
+       struct regp tx_gt2047;
+       struct regp tx_gt4095;
+       struct regp tx_gt9216;
+       struct regp tx_gt16383;
+       struct regp tx_gtmax;
+       struct regp tx_gtufl;
+       struct regp tx_gterr;   /* 20 */
+       struct regp tx_gtbyt;
+
+       struct regp rx_gr64;
+       struct regp rx_gr127;
+       struct regp rx_gr255;
+       struct regp rx_gr511;
+       struct regp rx_gr1023;
+       struct regp rx_gr1518;
+       struct regp rx_gr2047;
+       struct regp rx_gr4095;
+       struct regp rx_gr9216;  /* 30 */
+       struct regp rx_gr16383;
+       struct regp rx_grmax;
+       struct regp rx_grpkt;
+       struct regp rx_grfcs;
+       struct regp rx_grmca;
+       struct regp rx_grbca;
+       struct regp rx_grxcf;
+       struct regp rx_grxpf;
+       struct regp rx_grxuo;
+       struct regp rx_grjbr;   /* 40 */
+       struct regp rx_grovr;
+       struct regp rx_grflr;
+       struct regp rx_grmeg;
+       struct regp rx_grmeb;
+       struct regp rx_grbyt;
+       struct regp rx_grund;
+       struct regp rx_grfrg;
+       struct regp rx_grerb;
+       struct regp rx_grfre;
+       struct regp rx_gripj;   /* 50 */
+};
+
+struct emac_stats {
+       u32 rx_ifhcinoctets                        ;
+       u32 rx_ifhcinbadoctets                     ;
+       u32 rx_etherstatsfragments                 ;
+       u32 rx_ifhcinucastpkts                     ;
+       u32 rx_ifhcinmulticastpkts                 ;
+       u32 rx_ifhcinbroadcastpkts                 ;
+       u32 rx_dot3statsfcserrors                  ;
+       u32 rx_dot3statsalignmenterrors            ;
+       u32 rx_dot3statscarriersenseerrors         ;
+       u32 rx_xonpauseframesreceived              ;    /* 10 */
+       u32 rx_xoffpauseframesreceived             ;
+       u32 rx_maccontrolframesreceived            ;
+       u32 rx_xoffstateentered                    ;
+       u32 rx_dot3statsframestoolong              ;
+       u32 rx_etherstatsjabbers                   ;
+       u32 rx_etherstatsundersizepkts             ;
+       u32 rx_etherstatspkts64octets              ;
+       u32 rx_etherstatspkts65octetsto127octets   ;
+       u32 rx_etherstatspkts128octetsto255octets  ;
+       u32 rx_etherstatspkts256octetsto511octets  ;    /* 20 */
+       u32 rx_etherstatspkts512octetsto1023octets ;
+       u32 rx_etherstatspkts1024octetsto1522octets;
+       u32 rx_etherstatspktsover1522octets        ;
+
+       u32 rx_falsecarriererrors                  ;
+
+       u32 tx_ifhcoutoctets                       ;
+       u32 tx_ifhcoutbadoctets                    ;
+       u32 tx_etherstatscollisions                ;
+       u32 tx_outxonsent                          ;
+       u32 tx_outxoffsent                         ;
+       u32 tx_flowcontroldone                     ;    /* 30 */
+       u32 tx_dot3statssinglecollisionframes      ;
+       u32 tx_dot3statsmultiplecollisionframes    ;
+       u32 tx_dot3statsdeferredtransmissions      ;
+       u32 tx_dot3statsexcessivecollisions        ;
+       u32 tx_dot3statslatecollisions             ;
+       u32 tx_ifhcoutucastpkts                    ;
+       u32 tx_ifhcoutmulticastpkts                ;
+       u32 tx_ifhcoutbroadcastpkts                ;
+       u32 tx_etherstatspkts64octets              ;
+       u32 tx_etherstatspkts65octetsto127octets   ;    /* 40 */
+       u32 tx_etherstatspkts128octetsto255octets  ;
+       u32 tx_etherstatspkts256octetsto511octets  ;
+       u32 tx_etherstatspkts512octetsto1023octets ;
+       u32 tx_etherstatspkts1024octetsto1522octet ;
+       u32 tx_etherstatspktsover1522octets        ;
+       u32 tx_dot3statsinternalmactransmiterrors  ;    /* 46 */
+};
+
+union mac_stats {
+       struct emac_stats emac;
+       struct bmac_stats bmac;
+};
+
+struct nig_stats {
+       u32 brb_discard;
+       u32 brb_packet;
+       u32 brb_truncate;
+       u32 flow_ctrl_discard;
+       u32 flow_ctrl_octets;
+       u32 flow_ctrl_packet;
+       u32 mng_discard;
+       u32 mng_octet_inp;
+       u32 mng_octet_out;
+       u32 mng_packet_inp;
+       u32 mng_packet_out;
+       u32 pbf_octets;
+       u32 pbf_packet;
+       u32 safc_inp;
+       u32 done;
+       u32 pad;
+};
+
+struct bnx2x_eth_stats {
+       u32 pad;        /* to make long counters u64 aligned */
+       u32 mac_stx_start;
+       u32 total_bytes_received_hi;
+       u32 total_bytes_received_lo;
+       u32 total_bytes_transmitted_hi;
+       u32 total_bytes_transmitted_lo;
+       u32 total_unicast_packets_received_hi;
+       u32 total_unicast_packets_received_lo;
+       u32 total_multicast_packets_received_hi;
+       u32 total_multicast_packets_received_lo;
+       u32 total_broadcast_packets_received_hi;
+       u32 total_broadcast_packets_received_lo;
+       u32 total_unicast_packets_transmitted_hi;
+       u32 total_unicast_packets_transmitted_lo;
+       u32 total_multicast_packets_transmitted_hi;
+       u32 total_multicast_packets_transmitted_lo;
+       u32 total_broadcast_packets_transmitted_hi;
+       u32 total_broadcast_packets_transmitted_lo;
+       u32 crc_receive_errors;
+       u32 alignment_errors;
+       u32 false_carrier_detections;
+       u32 runt_packets_received;
+       u32 jabber_packets_received;
+       u32 pause_xon_frames_received;
+       u32 pause_xoff_frames_received;
+       u32 pause_xon_frames_transmitted;
+       u32 pause_xoff_frames_transmitted;
+       u32 single_collision_transmit_frames;
+       u32 multiple_collision_transmit_frames;
+       u32 late_collision_frames;
+       u32 excessive_collision_frames;
+       u32 control_frames_received;
+       u32 frames_received_64_bytes;
+       u32 frames_received_65_127_bytes;
+       u32 frames_received_128_255_bytes;
+       u32 frames_received_256_511_bytes;
+       u32 frames_received_512_1023_bytes;
+       u32 frames_received_1024_1522_bytes;
+       u32 frames_received_1523_9022_bytes;
+       u32 frames_transmitted_64_bytes;
+       u32 frames_transmitted_65_127_bytes;
+       u32 frames_transmitted_128_255_bytes;
+       u32 frames_transmitted_256_511_bytes;
+       u32 frames_transmitted_512_1023_bytes;
+       u32 frames_transmitted_1024_1522_bytes;
+       u32 frames_transmitted_1523_9022_bytes;
+       u32 valid_bytes_received_hi;
+       u32 valid_bytes_received_lo;
+       u32 error_runt_packets_received;
+       u32 error_jabber_packets_received;
+       u32 mac_stx_end;
+
+       u32 pad2;
+       u32 stat_IfHCInBadOctets_hi;
+       u32 stat_IfHCInBadOctets_lo;
+       u32 stat_IfHCOutBadOctets_hi;
+       u32 stat_IfHCOutBadOctets_lo;
+       u32 stat_Dot3statsFramesTooLong;
+       u32 stat_Dot3statsInternalMacTransmitErrors;
+       u32 stat_Dot3StatsCarrierSenseErrors;
+       u32 stat_Dot3StatsDeferredTransmissions;
+       u32 stat_FlowControlDone;
+       u32 stat_XoffStateEntered;
+
+       u32 x_total_sent_bytes_hi;
+       u32 x_total_sent_bytes_lo;
+       u32 x_total_sent_pkts;
+
+       u32 t_rcv_unicast_bytes_hi;
+       u32 t_rcv_unicast_bytes_lo;
+       u32 t_rcv_broadcast_bytes_hi;
+       u32 t_rcv_broadcast_bytes_lo;
+       u32 t_rcv_multicast_bytes_hi;
+       u32 t_rcv_multicast_bytes_lo;
+       u32 t_total_rcv_pkt;
+
+       u32 checksum_discard;
+       u32 packets_too_big_discard;
+       u32 no_buff_discard;
+       u32 ttl0_discard;
+       u32 mac_discard;
+       u32 mac_filter_discard;
+       u32 xxoverflow_discard;
+       u32 brb_truncate_discard;
+
+       u32 brb_discard;
+       u32 brb_packet;
+       u32 brb_truncate;
+       u32 flow_ctrl_discard;
+       u32 flow_ctrl_octets;
+       u32 flow_ctrl_packet;
+       u32 mng_discard;
+       u32 mng_octet_inp;
+       u32 mng_octet_out;
+       u32 mng_packet_inp;
+       u32 mng_packet_out;
+       u32 pbf_octets;
+       u32 pbf_packet;
+       u32 safc_inp;
+       u32 driver_xoff;
+       u32 number_of_bugs_found_in_stats_spec; /* just kidding */
+};
+
+#define MAC_STX_NA                     0xffffffff
+
+#ifdef BNX2X_MULTI
+#define MAX_CONTEXT                    16
+#else
+#define MAX_CONTEXT                    1
+#endif
+
+union cdu_context {
+       struct eth_context eth;
+       char pad[1024];
+};
+
+#define MAX_DMAE_C                     5
+
+/* DMA memory not used in fastpath */
+struct bnx2x_slowpath {
+       union cdu_context               context[MAX_CONTEXT];
+       struct eth_stats_query          fw_stats;
+       struct mac_configuration_cmd    mac_config;
+       struct mac_configuration_cmd    mcast_config;
+
+       /* used by dmae command executer */
+       struct dmae_command             dmae[MAX_DMAE_C];
+
+       union mac_stats                 mac_stats;
+       struct nig_stats                nig;
+       struct bnx2x_eth_stats          eth_stats;
+
+       u32                             wb_comp;
+#define BNX2X_WB_COMP_VAL              0xe0d0d0ae
+       u32                             wb_data[4];
+};
+
+#define bnx2x_sp(bp, var)              (&bp->slowpath->var)
+#define bnx2x_sp_check(bp, var) ((bp->slowpath) ? (&bp->slowpath->var) : NULL)
+#define bnx2x_sp_mapping(bp, var) \
+               (bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var))
+
+
+struct sw_rx_bd {
+       struct sk_buff  *skb;
+       DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct sw_tx_bd {
+       struct sk_buff  *skb;
+       u16             first_bd;
+};
+
+struct bnx2x_fastpath {
+
+       struct napi_struct      napi;
+
+       struct host_status_block *status_blk;
+       dma_addr_t              status_blk_mapping;
+
+       struct eth_tx_db_data   *hw_tx_prods;
+       dma_addr_t              tx_prods_mapping;
+
+       struct sw_tx_bd         *tx_buf_ring;
+
+       struct eth_tx_bd        *tx_desc_ring;
+       dma_addr_t              tx_desc_mapping;
+
+       struct sw_rx_bd         *rx_buf_ring;
+
+       struct eth_rx_bd        *rx_desc_ring;
+       dma_addr_t              rx_desc_mapping;
+
+       union eth_rx_cqe        *rx_comp_ring;
+       dma_addr_t              rx_comp_mapping;
+
+       int                     state;
+#define BNX2X_FP_STATE_CLOSED          0
+#define BNX2X_FP_STATE_IRQ             0x80000
+#define BNX2X_FP_STATE_OPENING         0x90000
+#define BNX2X_FP_STATE_OPEN            0xa0000
+#define BNX2X_FP_STATE_HALTING         0xb0000
+#define BNX2X_FP_STATE_HALTED          0xc0000
+#define BNX2X_FP_STATE_DELETED         0xd0000
+#define BNX2X_FP_STATE_CLOSE_IRQ       0xe0000
+
+       int                     index;
+
+       u16                     tx_pkt_prod;
+       u16                     tx_pkt_cons;
+       u16                     tx_bd_prod;
+       u16                     tx_bd_cons;
+       u16                     *tx_cons_sb;
+
+       u16                     fp_c_idx;
+       u16                     fp_u_idx;
+
+       u16                     rx_bd_prod;
+       u16                     rx_bd_cons;
+       u16                     rx_comp_prod;
+       u16                     rx_comp_cons;
+       u16                     *rx_cons_sb;
+
+       unsigned long           tx_pkt,
+                               rx_pkt,
+                               rx_calls;
+
+       struct bnx2x            *bp; /* parent */
+};
+
+#define bnx2x_fp(bp, nr, var)          (bp->fp[nr].var)
+
+
+/* attn group wiring */
+#define MAX_DYNAMIC_ATTN_GRPS          8
+
+struct attn_route {
+       u32     sig[4];
+};
+
+struct bnx2x {
+       /* Fields used in the tx and intr/napi performance paths
+        * are grouped together in the beginning of the structure
+        */
+       struct bnx2x_fastpath   *fp;
+       void __iomem            *regview;
+       void __iomem            *doorbells;
+
+       struct net_device       *dev;
+       struct pci_dev          *pdev;
+
+       atomic_t                intr_sem;
+       struct msix_entry       msix_table[MAX_CONTEXT+1];
+
+       int                     tx_ring_size;
+
+#ifdef BCM_VLAN
+       struct vlan_group       *vlgrp;
+#endif
+
+       u32                     rx_csum;
+       u32                     rx_offset;
+       u32                     rx_buf_use_size;        /* useable size */
+       u32                     rx_buf_size;            /* with alignment */
+#define ETH_OVREHEAD                   (ETH_HLEN + 8)  /* 8 for CRC + VLAN */
+#define ETH_MIN_PACKET_SIZE            60
+#define ETH_MAX_PACKET_SIZE            1500
+#define ETH_MAX_JUMBO_PACKET_SIZE       9600
+
+       struct host_def_status_block *def_status_blk;
+#define DEF_SB_ID              16
+       u16                     def_c_idx;
+       u16                     def_u_idx;
+       u16                     def_t_idx;
+       u16                     def_x_idx;
+       u16                     def_att_idx;
+       u32                     attn_state;
+       struct attn_route       attn_group[MAX_DYNAMIC_ATTN_GRPS];
+       u32                     aeu_mask;
+       u32                     nig_mask;
+
+       /* slow path ring */
+       struct eth_spe          *spq;
+       dma_addr_t              spq_mapping;
+       u16                     spq_prod_idx;
+       u16                     dsb_sp_prod_idx;
+       struct eth_spe          *spq_prod_bd;
+       struct eth_spe          *spq_last_bd;
+       u16                     *dsb_sp_prod;
+       u16                     spq_left; /* serialize spq */
+       spinlock_t              spq_lock;
+
+       /* Flag for marking that there is either
+        * STAT_QUERY or CFC DELETE ramrod pending
+        */
+       u8                      stat_pending;
+
+       /* End of fileds used in the performance code paths */
+
+       int                     panic;
+       int                     msglevel;
+
+       u32                     flags;
+#define PCIX_FLAG                      1
+#define PCI_32BIT_FLAG                 2
+#define ONE_TDMA_FLAG                  4       /* no longer used */
+#define NO_WOL_FLAG                    8
+#define USING_DAC_FLAG                 0x10
+#define USING_MSIX_FLAG                0x20
+#define ASF_ENABLE_FLAG                0x40
+
+       int                     port;
+
+       int                     pm_cap;
+       int                     pcie_cap;
+
+       /* Used to synchronize phy accesses */
+       spinlock_t              phy_lock;
+
+       struct work_struct      reset_task;
+       u16                     in_reset_task;
+
+       struct work_struct      sp_task;
+
+       struct timer_list       timer;
+       int                     timer_interval;
+       int                     current_interval;
+
+       u32                     shmem_base;
+
+       u32                     chip_id;
+/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
+#define CHIP_ID(bp)                    (((bp)->chip_id) & 0xfffffff0)
+
+#define CHIP_NUM(bp)                   (((bp)->chip_id) & 0xffff0000)
+#define CHIP_NUM_5710                  0x57100000
+
+#define CHIP_REV(bp)                   (((bp)->chip_id) & 0x0000f000)
+#define CHIP_REV_Ax                    0x00000000
+#define CHIP_REV_Bx                    0x00001000
+#define CHIP_REV_Cx                    0x00002000
+#define CHIP_REV_EMUL                  0x0000e000
+#define CHIP_REV_FPGA                  0x0000f000
+#define CHIP_REV_IS_SLOW(bp)           ((CHIP_REV(bp) == CHIP_REV_EMUL) || \
+                                        (CHIP_REV(bp) == CHIP_REV_FPGA))
+
+#define CHIP_METAL(bp)                 (((bp)->chip_id) & 0x00000ff0)
+#define CHIP_BOND_ID(bp)               (((bp)->chip_id) & 0x0000000f)
+
+       u16                     fw_seq;
+       u16                     fw_drv_pulse_wr_seq;
+       u32                     fw_mb;
+
+       u32                     hw_config;
+       u32                     serdes_config;
+       u32                     lane_config;
+       u32                     ext_phy_config;
+#define XGXS_EXT_PHY_TYPE(bp)          (bp->ext_phy_config & \
+                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
+#define SERDES_EXT_PHY_TYPE(bp)        (bp->ext_phy_config & \
+                                        PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
+
+       u32                     speed_cap_mask;
+       u32                     link_config;
+#define SWITCH_CFG_1G                  PORT_FEATURE_CON_SWITCH_1G_SWITCH
+#define SWITCH_CFG_10G                 PORT_FEATURE_CON_SWITCH_10G_SWITCH
+#define SWITCH_CFG_AUTO_DETECT         PORT_FEATURE_CON_SWITCH_AUTO_DETECT
+#define SWITCH_CFG_ONE_TIME_DETECT      \
+                               PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT
+
+       u8                      ser_lane;
+       u8                      rx_lane_swap;
+       u8                      tx_lane_swap;
+
+       u8                      link_up;
+
+       u32                     supported;
+/* link settings - missing defines */
+#define SUPPORTED_2500baseT_Full       (1 << 15)
+#define SUPPORTED_CX4                  (1 << 16)
+
+       u32                     phy_flags;
+/*#define PHY_SERDES_FLAG                      0x1*/
+#define PHY_BMAC_FLAG                  0x2
+#define PHY_EMAC_FLAG                  0x4
+#define PHY_XGXS_FLAG                  0x8
+#define PHY_SGMII_FLAG                 0x10
+#define PHY_INT_MODE_MASK_FLAG         0x300
+#define PHY_INT_MODE_AUTO_POLLING_FLAG  0x100
+#define PHY_INT_MODE_LINK_READY_FLAG    0x200
+
+       u32                     phy_addr;
+       u32                     phy_id;
+
+       u32                     autoneg;
+#define AUTONEG_CL37                   SHARED_HW_CFG_AN_ENABLE_CL37
+#define AUTONEG_CL73                   SHARED_HW_CFG_AN_ENABLE_CL73
+#define AUTONEG_BAM                    SHARED_HW_CFG_AN_ENABLE_BAM
+#define AUTONEG_PARALLEL               \
+                               SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
+#define AUTONEG_SGMII_FIBER_AUTODET     \
+                               SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
+#define AUTONEG_REMOTE_PHY             SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
+
+       u32                     req_autoneg;
+#define AUTONEG_SPEED                  0x1
+#define AUTONEG_FLOW_CTRL              0x2
+
+       u32                     req_line_speed;
+/* link settings - missing defines */
+#define SPEED_12000                    12000
+#define SPEED_12500                    12500
+#define SPEED_13000                    13000
+#define SPEED_15000                    15000
+#define SPEED_16000                    16000
+
+       u32                     req_duplex;
+       u32                     req_flow_ctrl;
+#define FLOW_CTRL_AUTO                 PORT_FEATURE_FLOW_CONTROL_AUTO
+#define FLOW_CTRL_TX                   PORT_FEATURE_FLOW_CONTROL_TX
+#define FLOW_CTRL_RX                   PORT_FEATURE_FLOW_CONTROL_RX
+#define FLOW_CTRL_BOTH                 PORT_FEATURE_FLOW_CONTROL_BOTH
+#define FLOW_CTRL_NONE                 PORT_FEATURE_FLOW_CONTROL_NONE
+
+       u32                     pause_mode;
+#define PAUSE_NONE                     0
+#define PAUSE_SYMMETRIC                1
+#define PAUSE_ASYMMETRIC               2
+#define PAUSE_BOTH                     3
+
+       u32                     advertising;
+/* link settings - missing defines */
+#define ADVERTISED_2500baseT_Full       (1 << 15)
+#define ADVERTISED_CX4                 (1 << 16)
+
+       u32                     link_status;
+       u32                     line_speed;
+       u32                     duplex;
+       u32                     flow_ctrl;
+
+       u32                     bc_ver;
+
+       int                     flash_size;
+#define NVRAM_1MB_SIZE                 0x20000 /* 1M bit in bytes */
+#define NVRAM_TIMEOUT_COUNT            30000
+#define NVRAM_PAGE_SIZE                256
+
+       int                     rx_ring_size;
+
+       u16                     tx_quick_cons_trip_int;
+       u16                     tx_quick_cons_trip;
+       u16                     tx_ticks_int;
+       u16                     tx_ticks;
+
+       u16                     rx_quick_cons_trip_int;
+       u16                     rx_quick_cons_trip;
+       u16                     rx_ticks_int;
+       u16                     rx_ticks;
+
+       u32                     stats_ticks;
+
+       int                     state;
+#define BNX2X_STATE_CLOSED             0x0
+#define BNX2X_STATE_OPENING_WAIT4_LOAD  0x1000
+#define BNX2X_STATE_OPENING_WAIT4_PORT  0x2000
+#define BNX2X_STATE_OPEN               0x3000
+#define BNX2X_STATE_CLOSING_WAIT4_HALT  0x4000
+#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000
+#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000
+#define BNX2X_STATE_ERROR              0xF000
+
+       int                     num_queues;
+
+       u32                     rx_mode;
+#define BNX2X_RX_MODE_NONE             0
+#define BNX2X_RX_MODE_NORMAL           1
+#define BNX2X_RX_MODE_ALLMULTI         2
+#define BNX2X_RX_MODE_PROMISC          3
+#define BNX2X_MAX_MULTICAST            64
+#define BNX2X_MAX_EMUL_MULTI           16
+
+       dma_addr_t              def_status_blk_mapping;
+
+       struct bnx2x_slowpath   *slowpath;
+       dma_addr_t              slowpath_mapping;
+
+#ifdef BCM_ISCSI
+       void                    *t1;
+       dma_addr_t              t1_mapping;
+       void                    *t2;
+       dma_addr_t              t2_mapping;
+       void                    *timers;
+       dma_addr_t              timers_mapping;
+       void                    *qm;
+       dma_addr_t              qm_mapping;
+#endif
+
+       char                    *name;
+       u16                     bus_speed_mhz;
+       u8                      wol;
+       u8                      pad;
+
+       /* used to synchronize stats collecting */
+       int                     stats_state;
+#define STATS_STATE_DISABLE            0
+#define STATS_STATE_ENABLE             1
+#define STATS_STATE_STOP               2 /* stop stats on next iteration */
+
+       /* used by dmae command loader */
+       struct dmae_command     dmae;
+       int                     executer_idx;
+
+       u32                     old_brb_discard;
+       struct bmac_stats       old_bmac;
+       struct tstorm_per_client_stats old_tclient;
+       struct z_stream_s       *strm;
+       void                    *gunzip_buf;
+       dma_addr_t              gunzip_mapping;
+       int                     gunzip_outlen;
+#define FW_BUF_SIZE                    0x8000
+
+};
+
+
+/* DMAE command defines */
+#define DMAE_CMD_SRC_PCI               0
+#define DMAE_CMD_SRC_GRC               DMAE_COMMAND_SRC
+
+#define DMAE_CMD_DST_PCI               (1 << DMAE_COMMAND_DST_SHIFT)
+#define DMAE_CMD_DST_GRC               (2 << DMAE_COMMAND_DST_SHIFT)
+
+#define DMAE_CMD_C_DST_PCI             0
+#define DMAE_CMD_C_DST_GRC             (1 << DMAE_COMMAND_C_DST_SHIFT)
+
+#define DMAE_CMD_C_ENABLE              DMAE_COMMAND_C_TYPE_ENABLE
+
+#define DMAE_CMD_ENDIANITY_NO_SWAP      (0 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_SWAP       (1 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_DW_SWAP      (2 << DMAE_COMMAND_ENDIANITY_SHIFT)
+#define DMAE_CMD_ENDIANITY_B_DW_SWAP    (3 << DMAE_COMMAND_ENDIANITY_SHIFT)
+
+#define DMAE_CMD_PORT_0                0
+#define DMAE_CMD_PORT_1                DMAE_COMMAND_PORT
+
+#define DMAE_CMD_SRC_RESET             DMAE_COMMAND_SRC_RESET
+#define DMAE_CMD_DST_RESET             DMAE_COMMAND_DST_RESET
+
+#define DMAE_LEN32_MAX                 0x400
+
+
+/* MC hsi */
+#define RX_COPY_THRESH                 92
+#define BCM_PAGE_BITS                  12
+#define BCM_PAGE_SIZE                  (1 << BCM_PAGE_BITS)
+
+#define NUM_TX_RINGS                   16
+#define TX_DESC_CNT            (BCM_PAGE_SIZE / sizeof(struct eth_tx_bd))
+#define MAX_TX_DESC_CNT                (TX_DESC_CNT - 1)
+#define NUM_TX_BD                      (TX_DESC_CNT * NUM_TX_RINGS)
+#define MAX_TX_BD                      (NUM_TX_BD - 1)
+#define MAX_TX_AVAIL                   (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2)
+#define NEXT_TX_IDX(x)         ((((x) & MAX_TX_DESC_CNT) == \
+                                (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+#define TX_BD(x)                       ((x) & MAX_TX_BD)
+#define TX_BD_POFF(x)                  ((x) & MAX_TX_DESC_CNT)
+
+/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */
+#define NUM_RX_RINGS                   8
+#define RX_DESC_CNT            (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd))
+#define MAX_RX_DESC_CNT                (RX_DESC_CNT - 2)
+#define RX_DESC_MASK                   (RX_DESC_CNT - 1)
+#define NUM_RX_BD                      (RX_DESC_CNT * NUM_RX_RINGS)
+#define MAX_RX_BD                      (NUM_RX_BD - 1)
+#define MAX_RX_AVAIL                   (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
+#define NEXT_RX_IDX(x)         ((((x) & RX_DESC_MASK) == \
+                                (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1)
+#define RX_BD(x)                       ((x) & MAX_RX_BD)
+
+#define NUM_RCQ_RINGS                  (NUM_RX_RINGS * 2)
+#define RCQ_DESC_CNT           (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe))
+#define MAX_RCQ_DESC_CNT               (RCQ_DESC_CNT - 1)
+#define NUM_RCQ_BD                     (RCQ_DESC_CNT * NUM_RCQ_RINGS)
+#define MAX_RCQ_BD                     (NUM_RCQ_BD - 1)
+#define MAX_RCQ_AVAIL                  (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2)
+#define NEXT_RCQ_IDX(x)        ((((x) & MAX_RCQ_DESC_CNT) == \
+                                (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1)
+#define RCQ_BD(x)                      ((x) & MAX_RCQ_BD)
+
+
+/* used on a CID received from the HW */
+#define SW_CID(x)                      (le32_to_cpu(x) & \
+                                        (COMMON_RAMROD_ETH_RX_CQE_CID >> 1))
+#define CQE_CMD(x)                     (le32_to_cpu(x) >> \
+                                       COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT)
+
+#define BD_UNMAP_ADDR(bd)              HILO_U64(le32_to_cpu((bd)->addr_hi), \
+                                                le32_to_cpu((bd)->addr_lo))
+#define BD_UNMAP_LEN(bd)               (le16_to_cpu((bd)->nbytes))
+
+
+#define STROM_ASSERT_ARRAY_SIZE        50
+
+
+#define MDIO_INDIRECT_REG_ADDR         0x1f
+#define MDIO_SET_REG_BANK(bp, reg_bank) \
+               bnx2x_mdio22_write(bp, MDIO_INDIRECT_REG_ADDR, reg_bank)
+
+#define MDIO_ACCESS_TIMEOUT            1000
+
+
+/* must be used on a CID before placing it on a HW ring */
+#define HW_CID(bp, x)                  (x | (bp->port << 23))
+
+#define SP_DESC_CNT            (BCM_PAGE_SIZE / sizeof(struct eth_spe))
+#define MAX_SP_DESC_CNT                (SP_DESC_CNT - 1)
+
+#define ATTN_NIG_FOR_FUNC              (1L << 8)
+#define ATTN_SW_TIMER_4_FUNC           (1L << 9)
+#define GPIO_2_FUNC                    (1L << 10)
+#define GPIO_3_FUNC                    (1L << 11)
+#define GPIO_4_FUNC                    (1L << 12)
+#define ATTN_GENERAL_ATTN_1            (1L << 13)
+#define ATTN_GENERAL_ATTN_2            (1L << 14)
+#define ATTN_GENERAL_ATTN_3            (1L << 15)
+#define ATTN_GENERAL_ATTN_4            (1L << 13)
+#define ATTN_GENERAL_ATTN_5            (1L << 14)
+#define ATTN_GENERAL_ATTN_6            (1L << 15)
+
+#define ATTN_HARD_WIRED_MASK           0xff00
+#define ATTENTION_ID                   4
+
+
+#define BNX2X_BTR                      3
+#define MAX_SPQ_PENDING                8
+
+
+#define BNX2X_NUM_STATS                31
+#define BNX2X_NUM_TESTS                2
+
+
+#define DPM_TRIGER_TYPE                0x40
+#define DOORBELL(bp, cid, val) \
+       do { \
+               writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \
+                      DPM_TRIGER_TYPE); \
+       } while (0)
+
+
+/* stuff added to make the code fit 80Col */
+
+#define TPA_TYPE_START                 ETH_FAST_PATH_RX_CQE_START_FLG
+#define TPA_TYPE_END                   ETH_FAST_PATH_RX_CQE_END_FLG
+#define TPA_TYPE(cqe)          (cqe->fast_path_cqe.error_type_flags & \
+                                (TPA_TYPE_START | TPA_TYPE_END))
+#define BNX2X_RX_SUM_OK(cqe) \
+                       (!(cqe->fast_path_cqe.status_flags & \
+                        (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | \
+                         ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG)))
+
+#define BNX2X_RX_SUM_FIX(cqe) \
+                       ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \
+                         PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \
+                        (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT))
+
+
+#define MDIO_AN_CL73_OR_37_COMPLETE \
+               (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
+                MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
+
+#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
+#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
+#define GP_STATUS_SPEED_MASK \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
+#define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
+#define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
+#define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
+#define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
+#define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
+#define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
+#define GP_STATUS_10G_HIG \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
+#define GP_STATUS_10G_CX4 \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
+#define GP_STATUS_12G_HIG \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
+#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
+#define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
+#define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
+#define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
+#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
+#define GP_STATUS_10G_KX4 \
+                       MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
+
+#define LINK_10THD                     LINK_STATUS_SPEED_AND_DUPLEX_10THD
+#define LINK_10TFD                     LINK_STATUS_SPEED_AND_DUPLEX_10TFD
+#define LINK_100TXHD                   LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
+#define LINK_100T4                     LINK_STATUS_SPEED_AND_DUPLEX_100T4
+#define LINK_100TXFD                   LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
+#define LINK_1000THD                   LINK_STATUS_SPEED_AND_DUPLEX_1000THD
+#define LINK_1000TFD                   LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
+#define LINK_1000XFD                   LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
+#define LINK_2500THD                   LINK_STATUS_SPEED_AND_DUPLEX_2500THD
+#define LINK_2500TFD                   LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
+#define LINK_2500XFD                   LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
+#define LINK_10GTFD                    LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
+#define LINK_10GXFD                    LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
+#define LINK_12GTFD                    LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
+#define LINK_12GXFD                    LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
+#define LINK_12_5GTFD                  LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
+#define LINK_12_5GXFD                  LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
+#define LINK_13GTFD                    LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
+#define LINK_13GXFD                    LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
+#define LINK_15GTFD                    LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
+#define LINK_15GXFD                    LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
+#define LINK_16GTFD                    LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
+#define LINK_16GXFD                    LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
+
+#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \
+               NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
+#define NIG_XGXS0_LINK_STATUS \
+               NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
+#define NIG_XGXS0_LINK_STATUS_SIZE \
+               NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
+#define NIG_SERDES0_LINK_STATUS \
+               NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
+#define NIG_MASK_MI_INT \
+               NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
+#define NIG_MASK_XGXS0_LINK10G \
+               NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
+#define NIG_MASK_XGXS0_LINK_STATUS \
+               NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
+#define NIG_MASK_SERDES0_LINK_STATUS \
+               NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
+
+#define XGXS_RESET_BITS \
+       (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
+
+#define SERDES_RESET_BITS \
+       (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
+        MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
+
+
+#define BNX2X_MC_ASSERT_BITS \
+       (GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+        GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+        GENERAL_ATTEN_OFFSET(CSTORM_FATAL_ASSERT_ATTENTION_BIT) | \
+        GENERAL_ATTEN_OFFSET(XSTORM_FATAL_ASSERT_ATTENTION_BIT))
+
+#define BNX2X_MCP_ASSERT \
+       GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT)
+
+#define BNX2X_DOORQ_ASSERT \
+       AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT
+
+#define HW_INTERRUT_ASSERT_SET_0 \
+                               (AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_0    (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\
+                                AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR)
+#define HW_INTERRUT_ASSERT_SET_1 \
+                               (AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_1    (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\
+                                AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \
+                               AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\
+                           AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\
+                                AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR)
+#define HW_INTERRUT_ASSERT_SET_2 \
+                               (AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \
+                                AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT | \
+                       AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT |\
+                                AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT)
+#define HW_PRTY_ASSERT_SET_2    (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR | \
+                       AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\
+                                AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \
+                                AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR)
+
+
+#define ETH_RX_ERROR_FALGS      (ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG | \
+                                ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | \
+                                ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG)
+
+
+#define MULTI_FLAGS \
+       (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY     | \
+        TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \
+        TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY     | \
+        TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \
+        TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE)
+
+#define MULTI_MASK      0x7f
+
+
+#define U_SB_ETH_RX_CQ_INDEX           HC_INDEX_U_ETH_RX_CQ_CONS
+#define C_SB_ETH_TX_CQ_INDEX           HC_INDEX_C_ETH_TX_CQ_CONS
+#define C_DEF_SB_SP_INDEX              HC_INDEX_DEF_C_ETH_SLOW_PATH
+
+#define BNX2X_RX_SB_INDEX \
+       &fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]
+
+#define BNX2X_TX_SB_INDEX \
+       &fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]
+
+#define BNX2X_SP_DSB_INDEX \
+&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]
+
+
+#define CAM_IS_INVALID(x) \
+(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE)
+
+#define CAM_INVALIDATE(x) \
+x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE
+
+
+/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
+
+#endif /* bnx2x.h */
diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h
new file mode 100644 (file)
index 0000000..62a6eb8
--- /dev/null
@@ -0,0 +1,198 @@
+/* bnx2x_fw_defs.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ */
+
+
+#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
+       (0x1922 + (port * 0x40) + (index * 0x4))
+#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
+       (0x1900 + (port * 0x40))
+#define CSTORM_HC_BTR_OFFSET(port)\
+       (0x1984 + (port * 0xc0))
+#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
+       (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
+#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
+       (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
+#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
+       (0x1400 + (port * 0x280) + (cpu_id * 0x28))
+#define CSTORM_STATS_FLAGS_OFFSET(port)                (0x5108 + (port * 0x8))
+#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id)\
+       (0x1510 + (port * 0x240) + (client_id * 0x20))
+#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
+       (0x138a + (port * 0x28) + (index * 0x4))
+#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
+       (0x1370 + (port * 0x28))
+#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
+       (0x4b70 + (port * 0x8))
+#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function)\
+       (0x1418 + (function * 0x30))
+#define TSTORM_HC_BTR_OFFSET(port)\
+       (0x13c4 + (port * 0x18))
+#define TSTORM_INDIRECTION_TABLE_OFFSET(port)\
+       (0x22c8 + (port * 0x80))
+#define TSTORM_INDIRECTION_TABLE_SIZE                  0x80
+#define TSTORM_MAC_FILTER_CONFIG_OFFSET(port)\
+       (0x1420 + (port * 0x30))
+#define TSTORM_RCQ_PROD_OFFSET(port, client_id)\
+       (0x1508 + (port * 0x240) + (client_id * 0x20))
+#define TSTORM_STATS_FLAGS_OFFSET(port)                (0x4b90 + (port * 0x8))
+#define USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
+       (0x191a + (port * 0x28) + (index * 0x4))
+#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
+       (0x1900 + (port * 0x28))
+#define USTORM_HC_BTR_OFFSET(port)\
+       (0x1954 + (port * 0xb8))
+#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port)\
+       (0x5408 + (port * 0x8))
+#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\
+       (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
+#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\
+       (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4))
+#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\
+       (0x1400 + (port * 0x280) + (cpu_id * 0x28))
+#define XSTORM_ASSERT_LIST_INDEX_OFFSET                0x1000
+#define XSTORM_ASSERT_LIST_OFFSET(idx)                 (0x1020 + (idx * 0x10))
+#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\
+       (0x141a + (port * 0x28) + (index * 0x4))
+#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\
+       (0x1400 + (port * 0x28))
+#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\
+       (0x5408 + (port * 0x8))
+#define XSTORM_HC_BTR_OFFSET(port)\
+       (0x1454 + (port * 0x18))
+#define XSTORM_SPQ_PAGE_BASE_OFFSET(port)\
+       (0x5328 + (port * 0x18))
+#define XSTORM_SPQ_PROD_OFFSET(port)\
+       (0x5330 + (port * 0x18))
+#define XSTORM_STATS_FLAGS_OFFSET(port)                (0x53f8 + (port * 0x8))
+#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0
+
+/**
+* This file defines HSI constatnts for the ETH flow
+*/
+
+/* hash types */
+#define DEFAULT_HASH_TYPE                      0
+#define IPV4_HASH_TYPE                         1
+#define TCP_IPV4_HASH_TYPE                     2
+#define IPV6_HASH_TYPE                         3
+#define TCP_IPV6_HASH_TYPE                     4
+
+/* values of command IDs in the ramrod message */
+#define RAMROD_CMD_ID_ETH_PORT_SETUP                   (80)
+#define RAMROD_CMD_ID_ETH_CLIENT_SETUP                 (85)
+#define RAMROD_CMD_ID_ETH_STAT_QUERY                   (90)
+#define RAMROD_CMD_ID_ETH_UPDATE                       (100)
+#define RAMROD_CMD_ID_ETH_HALT                         (105)
+#define RAMROD_CMD_ID_ETH_SET_MAC                      (110)
+#define RAMROD_CMD_ID_ETH_CFC_DEL                      (115)
+#define RAMROD_CMD_ID_ETH_PORT_DEL                     (120)
+#define RAMROD_CMD_ID_ETH_FORWARD_SETUP                (125)
+
+
+/* command values for set mac command */
+#define T_ETH_MAC_COMMAND_SET                          0
+#define T_ETH_MAC_COMMAND_INVALIDATE                   1
+
+#define T_ETH_INDIRECTION_TABLE_SIZE                   128
+
+/* Maximal L2 clients supported */
+#define ETH_MAX_RX_CLIENTS                             (18)
+
+/**
+* This file defines HSI constatnts common to all microcode flows
+*/
+
+/* Connection types */
+#define ETH_CONNECTION_TYPE                    0
+
+#define PROTOCOL_STATE_BIT_OFFSET              6
+
+#define ETH_STATE      (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET)
+
+/* microcode fixed page page size 4K (chains and ring segments) */
+#define MC_PAGE_SIZE                                           (4096)
+
+/* Host coalescing constants */
+
+/* IGU constants */
+#define IGU_PORT_BASE                          0x0400
+
+#define IGU_ADDR_MSIX                          0x0000
+#define IGU_ADDR_INT_ACK                       0x0200
+#define IGU_ADDR_PROD_UPD                      0x0201
+#define IGU_ADDR_ATTN_BITS_UPD                 0x0202
+#define IGU_ADDR_ATTN_BITS_SET                 0x0203
+#define IGU_ADDR_ATTN_BITS_CLR                 0x0204
+#define IGU_ADDR_COALESCE_NOW                  0x0205
+#define IGU_ADDR_SIMD_MASK                     0x0206
+#define IGU_ADDR_SIMD_NOMASK                   0x0207
+#define IGU_ADDR_MSI_CTL                       0x0210
+#define IGU_ADDR_MSI_ADDR_LO                   0x0211
+#define IGU_ADDR_MSI_ADDR_HI                   0x0212
+#define IGU_ADDR_MSI_DATA                      0x0213
+
+#define IGU_INT_ENABLE                         0
+#define IGU_INT_DISABLE                        1
+#define IGU_INT_NOP                            2
+#define IGU_INT_NOP2                           3
+
+/* index numbers */
+#define HC_USTORM_DEF_SB_NUM_INDICES           4
+#define HC_CSTORM_DEF_SB_NUM_INDICES           8
+#define HC_XSTORM_DEF_SB_NUM_INDICES           4
+#define HC_TSTORM_DEF_SB_NUM_INDICES           4
+#define HC_USTORM_SB_NUM_INDICES               4
+#define HC_CSTORM_SB_NUM_INDICES               4
+
+/* index values - which counterto update */
+
+#define HC_INDEX_U_ETH_RX_CQ_CONS              1
+
+#define HC_INDEX_C_ETH_TX_CQ_CONS              1
+
+#define HC_INDEX_DEF_X_SPQ_CONS                0
+
+#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS       2
+#define HC_INDEX_DEF_C_ETH_SLOW_PATH           3
+
+/* used by the driver to get the SB offset */
+#define USTORM_ID                      0
+#define CSTORM_ID                      1
+#define XSTORM_ID                      2
+#define TSTORM_ID                      3
+#define ATTENTION_ID                   4
+
+/* max number of slow path commands per port */
+#define MAX_RAMRODS_PER_PORT           (8)
+
+/* values for RX ETH CQE type field */
+#define RX_ETH_CQE_TYPE_ETH_FASTPATH   (0)
+#define RX_ETH_CQE_TYPE_ETH_RAMROD             (1)
+
+/* MAC address list size */
+#define T_MAC_ADDRESS_LIST_SIZE        (96)
+
+#define XSTORM_IP_ID_ROLL_HALF 0x8000
+#define XSTORM_IP_ID_ROLL_ALL 0
+
+#define FW_LOG_LIST_SIZE       (50)
+
+#define NUM_OF_PROTOCOLS               4
+#define MAX_COS_NUMBER                 16
+#define MAX_T_STAT_COUNTER_ID  18
+
+#define T_FAIR                                                 1
+#define FAIR_MEM                                               2
+#define RS_PERIODIC_TIMEOUT_IN_SDM_TICS 25
+
+#define UNKNOWN_ADDRESS        0
+#define UNICAST_ADDRESS        1
+#define MULTICAST_ADDRESS      2
+#define BROADCAST_ADDRESS      3
+
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
new file mode 100644 (file)
index 0000000..6fd959c
--- /dev/null
@@ -0,0 +1,2176 @@
+/* bnx2x_hsi.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ */
+
+
+#define FUNC_0                         0
+#define FUNC_1                         1
+#define FUNC_MAX                       2
+
+
+/* This value (in milliseconds) determines the frequency of the driver
+ * issuing the PULSE message code.  The firmware monitors this periodic
+ * pulse to determine when to switch to an OS-absent mode. */
+#define DRV_PULSE_PERIOD_MS            250
+
+/* This value (in milliseconds) determines how long the driver should
+ * wait for an acknowledgement from the firmware before timing out.  Once
+ * the firmware has timed out, the driver will assume there is no firmware
+ * running and there won't be any firmware-driver synchronization during a
+ * driver reset. */
+#define FW_ACK_TIME_OUT_MS             5000
+
+#define FW_ACK_POLL_TIME_MS            1
+
+#define FW_ACK_NUM_OF_POLL     (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS)
+
+/* LED Blink rate that will achieve ~15.9Hz */
+#define LED_BLINK_RATE_VAL             480
+
+/****************************************************************************
+ * Driver <-> FW Mailbox                                                   *
+ ****************************************************************************/
+struct drv_fw_mb {
+       u32 drv_mb_header;
+#define DRV_MSG_CODE_MASK                      0xffff0000
+#define DRV_MSG_CODE_LOAD_REQ                  0x10000000
+#define DRV_MSG_CODE_LOAD_DONE                 0x11000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN         0x20000000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS        0x20010000
+#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP        0x20020000
+#define DRV_MSG_CODE_UNLOAD_DONE               0x21000000
+#define DRV_MSG_CODE_DIAG_ENTER_REQ            0x50000000
+#define DRV_MSG_CODE_DIAG_EXIT_REQ             0x60000000
+#define DRV_MSG_CODE_VALIDATE_KEY              0x70000000
+#define DRV_MSG_CODE_GET_CURR_KEY              0x80000000
+#define DRV_MSG_CODE_GET_UPGRADE_KEY           0x81000000
+#define DRV_MSG_CODE_GET_MANUF_KEY             0x82000000
+#define DRV_MSG_CODE_LOAD_L2B_PRAM             0x90000000
+
+#define DRV_MSG_SEQ_NUMBER_MASK                0x0000ffff
+
+       u32 drv_mb_param;
+
+       u32 fw_mb_header;
+#define FW_MSG_CODE_MASK                       0xffff0000
+#define FW_MSG_CODE_DRV_LOAD_COMMON            0x11000000
+#define FW_MSG_CODE_DRV_LOAD_PORT              0x12000000
+#define FW_MSG_CODE_DRV_LOAD_REFUSED           0x13000000
+#define FW_MSG_CODE_DRV_LOAD_DONE              0x14000000
+#define FW_MSG_CODE_DRV_UNLOAD_COMMON          0x21000000
+#define FW_MSG_CODE_DRV_UNLOAD_PORT            0x22000000
+#define FW_MSG_CODE_DRV_UNLOAD_DONE            0x23000000
+#define FW_MSG_CODE_DIAG_ENTER_DONE            0x50000000
+#define FW_MSG_CODE_DIAG_REFUSE                0x51000000
+#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS       0x70000000
+#define FW_MSG_CODE_VALIDATE_KEY_FAILURE       0x71000000
+#define FW_MSG_CODE_GET_KEY_DONE               0x80000000
+#define FW_MSG_CODE_NO_KEY                     0x8f000000
+#define FW_MSG_CODE_LIC_INFO_NOT_READY         0x8f800000
+#define FW_MSG_CODE_L2B_PRAM_LOADED            0x90000000
+#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE    0x91000000
+#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE    0x92000000
+#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE    0x93000000
+#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE    0x94000000
+
+#define FW_MSG_SEQ_NUMBER_MASK                 0x0000ffff
+
+       u32 fw_mb_param;
+
+       u32 link_status;
+       /* Driver should update this field on any link change event */
+
+#define LINK_STATUS_LINK_FLAG_MASK             0x00000001
+#define LINK_STATUS_LINK_UP                    0x00000001
+#define LINK_STATUS_SPEED_AND_DUPLEX_MASK      0x0000001E
+#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE   (0<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10THD             (1<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD             (2<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD           (3<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100T4             (4<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD           (5<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD           (6<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD           (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD           (7<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD           (8<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD           (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD           (9<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD            (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD            (10<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD            (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD            (11<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD          (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD          (12<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD            (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD            (13<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD            (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD            (14<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD            (15<<1)
+#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD            (15<<1)
+
+#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK           0x00000020
+#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED             0x00000020
+
+#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE            0x00000040
+#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK       0x00000080
+#define LINK_STATUS_PARALLEL_DETECTION_USED            0x00000080
+
+#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE       0x00000200
+#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE       0x00000400
+#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE         0x00000800
+#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE       0x00001000
+#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE       0x00002000
+#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE         0x00004000
+#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE         0x00008000
+
+#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK          0x00010000
+#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED            0x00010000
+
+#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK          0x00020000
+#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED            0x00020000
+
+#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK     0x000C0000
+#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE     (0<<18)
+#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE       (1<<18)
+#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE      (2<<18)
+#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE            (3<<18)
+
+#define LINK_STATUS_SERDES_LINK                        0x00100000
+
+#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE       0x00200000
+#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE       0x00400000
+#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE        0x00800000
+#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE        0x01000000
+#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE      0x02000000
+#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE        0x04000000
+#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE        0x08000000
+#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE        0x10000000
+
+       u32 drv_pulse_mb;
+#define DRV_PULSE_SEQ_MASK                             0x00007fff
+#define DRV_PULSE_SYSTEM_TIME_MASK                     0xffff0000
+       /* The system time is in the format of
+        * (year-2001)*12*32 + month*32 + day. */
+#define DRV_PULSE_ALWAYS_ALIVE                         0x00008000
+       /* Indicate to the firmware not to go into the
+        * OS-absent when it is not getting driver pulse.
+        * This is used for debugging as well for PXE(MBA). */
+
+       u32 mcp_pulse_mb;
+#define MCP_PULSE_SEQ_MASK                             0x00007fff
+#define MCP_PULSE_ALWAYS_ALIVE                         0x00008000
+       /* Indicates to the driver not to assert due to lack
+        * of MCP response */
+#define MCP_EVENT_MASK                                 0xffff0000
+#define MCP_EVENT_OTHER_DRIVER_RESET_REQ               0x00010000
+
+};
+
+
+/****************************************************************************
+ * Shared HW configuration                                                 *
+ ****************************************************************************/
+struct shared_hw_cfg {                                  /* NVRAM Offset */
+       /* Up to 16 bytes of NULL-terminated string */
+       u8  part_num[16];                                       /* 0x104 */
+
+       u32 config;                                             /* 0x114 */
+#define SHARED_HW_CFG_MDIO_VOLTAGE_MASK            0x00000001
+#define SHARED_HW_CFG_MDIO_VOLTAGE_SHIFT           0
+#define SHARED_HW_CFG_MDIO_VOLTAGE_1_2V            0x00000000
+#define SHARED_HW_CFG_MDIO_VOLTAGE_2_5V            0x00000001
+#define SHARED_HW_CFG_MCP_RST_ON_CORE_RST_EN       0x00000002
+
+#define SHARED_HW_CFG_PORT_SWAP                    0x00000004
+
+#define SHARED_HW_CFG_BEACON_WOL_EN                0x00000008
+
+#define SHARED_HW_CFG_MFW_SELECT_MASK              0x00000700
+#define SHARED_HW_CFG_MFW_SELECT_SHIFT             8
+       /* Whatever MFW found in NVM
+          (if multiple found, priority order is: NC-SI, UMP, IPMI) */
+#define SHARED_HW_CFG_MFW_SELECT_DEFAULT           0x00000000
+#define SHARED_HW_CFG_MFW_SELECT_NC_SI             0x00000100
+#define SHARED_HW_CFG_MFW_SELECT_UMP               0x00000200
+#define SHARED_HW_CFG_MFW_SELECT_IPMI              0x00000300
+       /* Use SPIO4 as an arbiter between: 0-NC_SI, 1-IPMI
+         (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
+#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_IPMI   0x00000400
+       /* Use SPIO4 as an arbiter between: 0-UMP, 1-IPMI
+         (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
+#define SHARED_HW_CFG_MFW_SELECT_SPIO4_UMP_IPMI     0x00000500
+       /* Use SPIO4 as an arbiter between: 0-NC-SI, 1-UMP
+         (can only be used when an add-in board, not BMC, pulls-down SPIO4) */
+#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_UMP    0x00000600
+
+#define SHARED_HW_CFG_LED_MODE_MASK                0x000f0000
+#define SHARED_HW_CFG_LED_MODE_SHIFT               16
+#define SHARED_HW_CFG_LED_MAC1                     0x00000000
+#define SHARED_HW_CFG_LED_PHY1                     0x00010000
+#define SHARED_HW_CFG_LED_PHY2                     0x00020000
+#define SHARED_HW_CFG_LED_PHY3                     0x00030000
+#define SHARED_HW_CFG_LED_MAC2                     0x00040000
+#define SHARED_HW_CFG_LED_PHY4                     0x00050000
+#define SHARED_HW_CFG_LED_PHY5                     0x00060000
+#define SHARED_HW_CFG_LED_PHY6                     0x00070000
+#define SHARED_HW_CFG_LED_MAC3                     0x00080000
+#define SHARED_HW_CFG_LED_PHY7                     0x00090000
+#define SHARED_HW_CFG_LED_PHY9                     0x000a0000
+#define SHARED_HW_CFG_LED_PHY11                    0x000b0000
+#define SHARED_HW_CFG_LED_MAC4                     0x000c0000
+#define SHARED_HW_CFG_LED_PHY8                     0x000d0000
+
+#define SHARED_HW_CFG_AN_ENABLE_MASK               0x3f000000
+#define SHARED_HW_CFG_AN_ENABLE_SHIFT              24
+#define SHARED_HW_CFG_AN_ENABLE_CL37               0x01000000
+#define SHARED_HW_CFG_AN_ENABLE_CL73               0x02000000
+#define SHARED_HW_CFG_AN_ENABLE_BAM                0x04000000
+#define SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION  0x08000000
+#define SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT 0x10000000
+#define SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY         0x20000000
+
+       u32 config2;                                            /* 0x118 */
+       /* one time auto detect grace period (in sec) */
+#define SHARED_HW_CFG_GRACE_PERIOD_MASK            0x000000ff
+#define SHARED_HW_CFG_GRACE_PERIOD_SHIFT           0
+
+#define SHARED_HW_CFG_PCIE_GEN2_ENABLED            0x00000100
+
+       /* The default value for the core clock is 250MHz and it is
+          achieved by setting the clock change to 4 */
+#define SHARED_HW_CFG_CLOCK_CHANGE_MASK            0x00000e00
+#define SHARED_HW_CFG_CLOCK_CHANGE_SHIFT           9
+
+#define SHARED_HW_CFG_SMBUS_TIMING_100KHZ          0x00000000
+#define SHARED_HW_CFG_SMBUS_TIMING_400KHZ          0x00001000
+
+#define SHARED_HW_CFG_HIDE_FUNC1                   0x00002000
+
+       u32 power_dissipated;                                   /* 0x11c */
+#define SHARED_HW_CFG_POWER_DIS_CMN_MASK           0xff000000
+#define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT          24
+
+#define SHARED_HW_CFG_POWER_MGNT_SCALE_MASK        0x00ff0000
+#define SHARED_HW_CFG_POWER_MGNT_SCALE_SHIFT       16
+#define SHARED_HW_CFG_POWER_MGNT_UNKNOWN_SCALE     0x00000000
+#define SHARED_HW_CFG_POWER_MGNT_DOT_1_WATT        0x00010000
+#define SHARED_HW_CFG_POWER_MGNT_DOT_01_WATT       0x00020000
+#define SHARED_HW_CFG_POWER_MGNT_DOT_001_WATT      0x00030000
+
+       u32 ump_nc_si_config;                                   /* 0x120 */
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MASK      0x00000003
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_SHIFT     0
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MAC       0x00000000
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_PHY       0x00000001
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MII       0x00000000
+#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_RMII      0x00000002
+
+#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_MASK      0x00000f00
+#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_SHIFT     8
+
+#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_MASK   0x00ff0000
+#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_SHIFT  16
+#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_NONE   0x00000000
+#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000
+
+       u32 board;                                              /* 0x124 */
+#define SHARED_HW_CFG_BOARD_TYPE_MASK              0x0000ffff
+#define SHARED_HW_CFG_BOARD_TYPE_SHIFT             0
+#define SHARED_HW_CFG_BOARD_TYPE_NONE              0x00000000
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000     0x00000001
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001     0x00000002
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G    0x00000003
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G    0x00000004
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G    0x00000005
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G    0x00000006
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G    0x00000007
+#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G    0x00000008
+
+#define SHARED_HW_CFG_BOARD_VER_MASK               0xffff0000
+#define SHARED_HW_CFG_BOARD_VER_SHIFT              16
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK         0xf0000000
+#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT        28
+#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK         0x0f000000
+#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT        24
+#define SHARED_HW_CFG_BOARD_REV_MASK               0x00ff0000
+#define SHARED_HW_CFG_BOARD_REV_SHIFT              16
+
+       u32 reserved;                                           /* 0x128 */
+
+};
+
+/****************************************************************************
+ * Port HW configuration                                                   *
+ ****************************************************************************/
+struct port_hw_cfg {   /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */
+
+       /* Fields below are port specific (in anticipation of dual port
+          devices */
+       u32 pci_id;
+#define PORT_HW_CFG_PCI_VENDOR_ID_MASK             0xffff0000
+#define PORT_HW_CFG_PCI_DEVICE_ID_MASK             0x0000ffff
+
+       u32 pci_sub_id;
+#define PORT_HW_CFG_PCI_SUBSYS_DEVICE_ID_MASK      0xffff0000
+#define PORT_HW_CFG_PCI_SUBSYS_VENDOR_ID_MASK      0x0000ffff
+
+       u32 power_dissipated;
+#define PORT_HW_CFG_POWER_DIS_D3_MASK              0xff000000
+#define PORT_HW_CFG_POWER_DIS_D3_SHIFT             24
+#define PORT_HW_CFG_POWER_DIS_D2_MASK              0x00ff0000
+#define PORT_HW_CFG_POWER_DIS_D2_SHIFT             16
+#define PORT_HW_CFG_POWER_DIS_D1_MASK              0x0000ff00
+#define PORT_HW_CFG_POWER_DIS_D1_SHIFT             8
+#define PORT_HW_CFG_POWER_DIS_D0_MASK              0x000000ff
+#define PORT_HW_CFG_POWER_DIS_D0_SHIFT             0
+
+       u32 power_consumed;
+#define PORT_HW_CFG_POWER_CONS_D3_MASK             0xff000000
+#define PORT_HW_CFG_POWER_CONS_D3_SHIFT            24
+#define PORT_HW_CFG_POWER_CONS_D2_MASK             0x00ff0000
+#define PORT_HW_CFG_POWER_CONS_D2_SHIFT            16
+#define PORT_HW_CFG_POWER_CONS_D1_MASK             0x0000ff00
+#define PORT_HW_CFG_POWER_CONS_D1_SHIFT            8
+#define PORT_HW_CFG_POWER_CONS_D0_MASK             0x000000ff
+#define PORT_HW_CFG_POWER_CONS_D0_SHIFT            0
+
+       u32 mac_upper;
+#define PORT_HW_CFG_UPPERMAC_MASK                  0x0000ffff
+#define PORT_HW_CFG_UPPERMAC_SHIFT                 0
+       u32 mac_lower;
+
+       u32 iscsi_mac_upper;  /* Upper 16 bits are always zeroes */
+       u32 iscsi_mac_lower;
+
+       u32 rdma_mac_upper;   /* Upper 16 bits are always zeroes */
+       u32 rdma_mac_lower;
+
+       u32 serdes_config;
+       /* for external PHY, or forced mode or during AN */
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000
+#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT  16
+
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK    0x0000ffff
+#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT   0
+
+       u16 serdes_tx_driver_pre_emphasis[16];
+       u16 serdes_rx_driver_equalizer[16];
+
+       u32 xgxs_config_lane0;
+       u32 xgxs_config_lane1;
+       u32 xgxs_config_lane2;
+       u32 xgxs_config_lane3;
+       /* for external PHY, or forced mode or during AN */
+#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK   0xffff0000
+#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT  16
+
+#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK     0x0000ffff
+#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT     0
+
+       u16 xgxs_tx_driver_pre_emphasis_lane0[16];
+       u16 xgxs_tx_driver_pre_emphasis_lane1[16];
+       u16 xgxs_tx_driver_pre_emphasis_lane2[16];
+       u16 xgxs_tx_driver_pre_emphasis_lane3[16];
+
+       u16 xgxs_rx_driver_equalizer_lane0[16];
+       u16 xgxs_rx_driver_equalizer_lane1[16];
+       u16 xgxs_rx_driver_equalizer_lane2[16];
+       u16 xgxs_rx_driver_equalizer_lane3[16];
+
+       u32 lane_config;
+#define PORT_HW_CFG_LANE_SWAP_CFG_MASK             0x0000ffff
+#define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT            0
+#define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK          0x000000ff
+#define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT         0
+#define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK          0x0000ff00
+#define PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT         8
+#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK      0x0000c000
+#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT     14
+       /* AN and forced */
+#define PORT_HW_CFG_LANE_SWAP_CFG_01230123         0x00001b1b
+       /* forced only */
+#define PORT_HW_CFG_LANE_SWAP_CFG_01233210         0x00001be4
+       /* forced only */
+#define PORT_HW_CFG_LANE_SWAP_CFG_31203120         0x0000d8d8
+       /* forced only */
+#define PORT_HW_CFG_LANE_SWAP_CFG_32103210         0x0000e4e4
+
+       u32 external_phy_config;
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK       0xff000000
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_SHIFT      24
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT     0x00000000
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482     0x01000000
+#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN    0xff000000
+
+#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK       0x00ff0000
+#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT      16
+
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK         0x0000ff00
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SHIFT        8
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT       0x00000000
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8071      0x00000100
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072      0x00000200
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073      0x00000300
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705      0x00000400
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706      0x00000500
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276      0x00000600
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481      0x00000700
+#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN     0x0000ff00
+
+#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK         0x000000ff
+#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT        0
+
+       u32 speed_capability_mask;
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_MASK       0xffff0000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_SHIFT      16
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL    0x00010000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF    0x00020000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF   0x00040000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL   0x00080000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_1G         0x00100000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G       0x00200000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10G        0x00400000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12G        0x00800000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12_5G      0x01000000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_13G        0x02000000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_15G        0x04000000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_16G        0x08000000
+#define PORT_HW_CFG_SPEED_CAPABILITY_D0_RESERVED    0xf0000000
+
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_MASK       0x0000ffff
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_SHIFT      0
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_FULL    0x00000001
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_HALF    0x00000002
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_HALF   0x00000004
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_FULL   0x00000008
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_1G         0x00000010
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_2_5G       0x00000020
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10G        0x00000040
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12G        0x00000080
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12_5G      0x00000100
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_13G        0x00000200
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_15G        0x00000400
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_16G        0x00000800
+#define PORT_HW_CFG_SPEED_CAPABILITY_D3_RESERVED    0x0000f000
+
+       u32 reserved[2];
+
+};
+
+/****************************************************************************
+ * Shared Feature configuration                                            *
+ ****************************************************************************/
+struct shared_feat_cfg {                                /* NVRAM Offset */
+       u32 bmc_common;                                         /* 0x450 */
+#define SHARED_FEATURE_BMC_ECHO_MODE_EN            0x00000001
+
+};
+
+
+/****************************************************************************
+ * Port Feature configuration                                              *
+ ****************************************************************************/
+struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */
+       u32 config;
+#define PORT_FEATURE_BAR1_SIZE_MASK                0x0000000f
+#define PORT_FEATURE_BAR1_SIZE_SHIFT               0
+#define PORT_FEATURE_BAR1_SIZE_DISABLED            0x00000000
+#define PORT_FEATURE_BAR1_SIZE_64K                 0x00000001
+#define PORT_FEATURE_BAR1_SIZE_128K                0x00000002
+#define PORT_FEATURE_BAR1_SIZE_256K                0x00000003
+#define PORT_FEATURE_BAR1_SIZE_512K                0x00000004
+#define PORT_FEATURE_BAR1_SIZE_1M                  0x00000005
+#define PORT_FEATURE_BAR1_SIZE_2M                  0x00000006
+#define PORT_FEATURE_BAR1_SIZE_4M                  0x00000007
+#define PORT_FEATURE_BAR1_SIZE_8M                  0x00000008
+#define PORT_FEATURE_BAR1_SIZE_16M                 0x00000009
+#define PORT_FEATURE_BAR1_SIZE_32M                 0x0000000a
+#define PORT_FEATURE_BAR1_SIZE_64M                 0x0000000b
+#define PORT_FEATURE_BAR1_SIZE_128M                0x0000000c
+#define PORT_FEATURE_BAR1_SIZE_256M                0x0000000d
+#define PORT_FEATURE_BAR1_SIZE_512M                0x0000000e
+#define PORT_FEATURE_BAR1_SIZE_1G                  0x0000000f
+#define PORT_FEATURE_BAR2_SIZE_MASK                0x000000f0
+#define PORT_FEATURE_BAR2_SIZE_SHIFT               4
+#define PORT_FEATURE_BAR2_SIZE_DISABLED            0x00000000
+#define PORT_FEATURE_BAR2_SIZE_64K                 0x00000010
+#define PORT_FEATURE_BAR2_SIZE_128K                0x00000020
+#define PORT_FEATURE_BAR2_SIZE_256K                0x00000030
+#define PORT_FEATURE_BAR2_SIZE_512K                0x00000040
+#define PORT_FEATURE_BAR2_SIZE_1M                  0x00000050
+#define PORT_FEATURE_BAR2_SIZE_2M                  0x00000060
+#define PORT_FEATURE_BAR2_SIZE_4M                  0x00000070
+#define PORT_FEATURE_BAR2_SIZE_8M                  0x00000080
+#define PORT_FEATURE_BAR2_SIZE_16M                 0x00000090
+#define PORT_FEATURE_BAR2_SIZE_32M                 0x000000a0
+#define PORT_FEATURE_BAR2_SIZE_64M                 0x000000b0
+#define PORT_FEATURE_BAR2_SIZE_128M                0x000000c0
+#define PORT_FEATURE_BAR2_SIZE_256M                0x000000d0
+#define PORT_FEATURE_BAR2_SIZE_512M                0x000000e0
+#define PORT_FEATURE_BAR2_SIZE_1G                  0x000000f0
+#define PORT_FEATURE_EN_SIZE_MASK                  0x07000000
+#define PORT_FEATURE_EN_SIZE_SHIFT                 24
+#define PORT_FEATURE_WOL_ENABLED                   0x01000000
+#define PORT_FEATURE_MBA_ENABLED                   0x02000000
+#define PORT_FEATURE_MFW_ENABLED                   0x04000000
+
+       u32 wol_config;
+       /* Default is used when driver sets to "auto" mode */
+#define PORT_FEATURE_WOL_DEFAULT_MASK              0x00000003
+#define PORT_FEATURE_WOL_DEFAULT_SHIFT             0
+#define PORT_FEATURE_WOL_DEFAULT_DISABLE           0x00000000
+#define PORT_FEATURE_WOL_DEFAULT_MAGIC             0x00000001
+#define PORT_FEATURE_WOL_DEFAULT_ACPI              0x00000002
+#define PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI     0x00000003
+#define PORT_FEATURE_WOL_RES_PAUSE_CAP             0x00000004
+#define PORT_FEATURE_WOL_RES_ASYM_PAUSE_CAP        0x00000008
+#define PORT_FEATURE_WOL_ACPI_UPON_MGMT            0x00000010
+
+       u32 mba_config;
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK      0x00000003
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT     0
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE       0x00000000
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL       0x00000001
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP     0x00000002
+#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_ISCSIB     0x00000003
+#define PORT_FEATURE_MBA_RES_PAUSE_CAP             0x00000100
+#define PORT_FEATURE_MBA_RES_ASYM_PAUSE_CAP        0x00000200
+#define PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE       0x00000400
+#define PORT_FEATURE_MBA_HOTKEY_CTRL_S             0x00000000
+#define PORT_FEATURE_MBA_HOTKEY_CTRL_B             0x00000800
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK         0x000ff000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT        12
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED     0x00000000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2K           0x00001000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4K           0x00002000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8K           0x00003000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16K          0x00004000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32K          0x00005000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_64K          0x00006000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_128K         0x00007000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_256K         0x00008000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_512K         0x00009000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_1M           0x0000a000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2M           0x0000b000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4M           0x0000c000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8M           0x0000d000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16M          0x0000e000
+#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32M          0x0000f000
+#define PORT_FEATURE_MBA_MSG_TIMEOUT_MASK          0x00f00000
+#define PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT         20
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK       0x03000000
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT      24
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO       0x00000000
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS        0x01000000
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H     0x02000000
+#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H     0x03000000
+#define PORT_FEATURE_MBA_LINK_SPEED_MASK           0x3c000000
+#define PORT_FEATURE_MBA_LINK_SPEED_SHIFT          26
+#define PORT_FEATURE_MBA_LINK_SPEED_AUTO           0x00000000
+#define PORT_FEATURE_MBA_LINK_SPEED_10HD           0x04000000
+#define PORT_FEATURE_MBA_LINK_SPEED_10FD           0x08000000
+#define PORT_FEATURE_MBA_LINK_SPEED_100HD          0x0c000000
+#define PORT_FEATURE_MBA_LINK_SPEED_100FD          0x10000000
+#define PORT_FEATURE_MBA_LINK_SPEED_1GBPS          0x14000000
+#define PORT_FEATURE_MBA_LINK_SPEED_2_5GBPS        0x18000000
+#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_CX4     0x1c000000
+#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KX4     0x20000000
+#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KR      0x24000000
+#define PORT_FEATURE_MBA_LINK_SPEED_12GBPS         0x28000000
+#define PORT_FEATURE_MBA_LINK_SPEED_12_5GBPS       0x2c000000
+#define PORT_FEATURE_MBA_LINK_SPEED_13GBPS         0x30000000
+#define PORT_FEATURE_MBA_LINK_SPEED_15GBPS         0x34000000
+#define PORT_FEATURE_MBA_LINK_SPEED_16GBPS         0x38000000
+
+       u32 bmc_config;
+#define PORT_FEATURE_BMC_LINK_OVERRIDE_DEFAULT     0x00000000
+#define PORT_FEATURE_BMC_LINK_OVERRIDE_EN          0x00000001
+
+       u32 mba_vlan_cfg;
+#define PORT_FEATURE_MBA_VLAN_TAG_MASK             0x0000ffff
+#define PORT_FEATURE_MBA_VLAN_TAG_SHIFT            0
+#define PORT_FEATURE_MBA_VLAN_EN                   0x00010000
+
+       u32 resource_cfg;
+#define PORT_FEATURE_RESOURCE_CFG_VALID            0x00000001
+#define PORT_FEATURE_RESOURCE_CFG_DIAG             0x00000002
+#define PORT_FEATURE_RESOURCE_CFG_L2               0x00000004
+#define PORT_FEATURE_RESOURCE_CFG_ISCSI            0x00000008
+#define PORT_FEATURE_RESOURCE_CFG_RDMA             0x00000010
+
+       u32 smbus_config;
+       /* Obsolete */
+#define PORT_FEATURE_SMBUS_EN                      0x00000001
+#define PORT_FEATURE_SMBUS_ADDR_MASK               0x000000fe
+#define PORT_FEATURE_SMBUS_ADDR_SHIFT              1
+
+       u32 iscsib_boot_cfg;
+#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT       0x00000001
+
+       u32 link_config;    /* Used as HW defaults for the driver */
+#define PORT_FEATURE_CONNECTED_SWITCH_MASK         0x03000000
+#define PORT_FEATURE_CONNECTED_SWITCH_SHIFT        24
+       /* (forced) low speed switch (< 10G) */
+#define PORT_FEATURE_CON_SWITCH_1G_SWITCH          0x00000000
+       /* (forced) high speed switch (>= 10G) */
+#define PORT_FEATURE_CON_SWITCH_10G_SWITCH         0x01000000
+#define PORT_FEATURE_CON_SWITCH_AUTO_DETECT        0x02000000
+#define PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT     0x03000000
+
+#define PORT_FEATURE_LINK_SPEED_MASK               0x000f0000
+#define PORT_FEATURE_LINK_SPEED_SHIFT              16
+#define PORT_FEATURE_LINK_SPEED_AUTO               0x00000000
+#define PORT_FEATURE_LINK_SPEED_10M_FULL           0x00010000
+#define PORT_FEATURE_LINK_SPEED_10M_HALF           0x00020000
+#define PORT_FEATURE_LINK_SPEED_100M_HALF          0x00030000
+#define PORT_FEATURE_LINK_SPEED_100M_FULL          0x00040000
+#define PORT_FEATURE_LINK_SPEED_1G                 0x00050000
+#define PORT_FEATURE_LINK_SPEED_2_5G               0x00060000
+#define PORT_FEATURE_LINK_SPEED_10G_CX4            0x00070000
+#define PORT_FEATURE_LINK_SPEED_10G_KX4            0x00080000
+#define PORT_FEATURE_LINK_SPEED_10G_KR             0x00090000
+#define PORT_FEATURE_LINK_SPEED_12G                0x000a0000
+#define PORT_FEATURE_LINK_SPEED_12_5G              0x000b0000
+#define PORT_FEATURE_LINK_SPEED_13G                0x000c0000
+#define PORT_FEATURE_LINK_SPEED_15G                0x000d0000
+#define PORT_FEATURE_LINK_SPEED_16G                0x000e0000
+
+#define PORT_FEATURE_FLOW_CONTROL_MASK             0x00000700
+#define PORT_FEATURE_FLOW_CONTROL_SHIFT            8
+#define PORT_FEATURE_FLOW_CONTROL_AUTO             0x00000000
+#define PORT_FEATURE_FLOW_CONTROL_TX               0x00000100
+#define PORT_FEATURE_FLOW_CONTROL_RX               0x00000200
+#define PORT_FEATURE_FLOW_CONTROL_BOTH             0x00000300
+#define PORT_FEATURE_FLOW_CONTROL_NONE             0x00000400
+
+       /* The default for MCP link configuration,
+          uses the same defines as link_config */
+       u32 mfw_wol_link_cfg;
+
+       u32 reserved[19];
+
+};
+
+
+/****************************************************************************
+ * Device Information                                                      *
+ ****************************************************************************/
+struct dev_info {                                                  /* size */
+
+       u32    bc_rev; /* 8 bits each: major, minor, build */          /* 4 */
+
+       struct shared_hw_cfg     shared_hw_config;                    /* 40 */
+
+       struct port_hw_cfg       port_hw_config[FUNC_MAX];     /* 400*2=800 */
+
+       struct shared_feat_cfg   shared_feature_config;                /* 4 */
+
+       struct port_feat_cfg     port_feature_config[FUNC_MAX];/* 116*2=232 */
+
+};
+
+
+/****************************************************************************
+ * Management firmware state                                               *
+ ****************************************************************************/
+/* Allocate 320 bytes for management firmware: still not known exactly
+ * how much IMD needs. */
+#define MGMTFW_STATE_WORD_SIZE                             80
+
+struct mgmtfw_state {
+       u32 opaque[MGMTFW_STATE_WORD_SIZE];
+};
+
+
+/****************************************************************************
+ * Shared Memory Region                                                    *
+ ****************************************************************************/
+struct shmem_region {                         /*   SharedMem Offset (size) */
+       u32                 validity_map[FUNC_MAX];    /* 0x0 (4 * 2 = 0x8) */
+#define SHR_MEM_VALIDITY_PCI_CFG                   0x00000001
+#define SHR_MEM_VALIDITY_MB                        0x00000002
+#define SHR_MEM_VALIDITY_DEV_INFO                  0x00000004
+       /* One licensing bit should be set */
+#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK     0x00000038
+#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT    0x00000008
+#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT  0x00000010
+#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT      0x00000020
+
+       struct drv_fw_mb    drv_fw_mb[FUNC_MAX];     /* 0x8 (28 * 2 = 0x38) */
+
+       struct dev_info     dev_info;                       /* 0x40 (0x438) */
+
+#ifdef _LICENSE_H
+       license_key_t       drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */
+#else /* Linux! */
+       u8                  reserved[52*FUNC_MAX];
+#endif
+
+       /* FW information (for internal FW use) */
+       u32                 fw_info_fio_offset;            /* 0x4e0 (0x4)   */
+       struct mgmtfw_state mgmtfw_state;                  /* 0x4e4 (0x140) */
+
+};                                                        /* 0x624 */
+
+
+#define BCM_5710_FW_MAJOR_VERSION                      4
+#define BCM_5710_FW_MINOR_VERSION                      0
+#define BCM_5710_FW_REVISION_VERSION                   14
+#define BCM_5710_FW_COMPILE_FLAGS                      1
+
+
+/*
+ * attention bits
+ */
+struct atten_def_status_block {
+       u32 attn_bits;
+       u32 attn_bits_ack;
+#if defined(__BIG_ENDIAN)
+       u16 attn_bits_index;
+       u8 reserved0;
+       u8 status_block_id;
+#elif defined(__LITTLE_ENDIAN)
+       u8 status_block_id;
+       u8 reserved0;
+       u16 attn_bits_index;
+#endif
+       u32 reserved1;
+};
+
+
+/*
+ * common data for all protocols
+ */
+struct doorbell_hdr {
+       u8 header;
+#define DOORBELL_HDR_RX (0x1<<0)
+#define DOORBELL_HDR_RX_SHIFT 0
+#define DOORBELL_HDR_DB_TYPE (0x1<<1)
+#define DOORBELL_HDR_DB_TYPE_SHIFT 1
+#define DOORBELL_HDR_DPM_SIZE (0x3<<2)
+#define DOORBELL_HDR_DPM_SIZE_SHIFT 2
+#define DOORBELL_HDR_CONN_TYPE (0xF<<4)
+#define DOORBELL_HDR_CONN_TYPE_SHIFT 4
+};
+
+/*
+ * doorbell message send to the chip
+ */
+struct doorbell {
+#if defined(__BIG_ENDIAN)
+       u16 zero_fill2;
+       u8 zero_fill1;
+       struct doorbell_hdr header;
+#elif defined(__LITTLE_ENDIAN)
+       struct doorbell_hdr header;
+       u8 zero_fill1;
+       u16 zero_fill2;
+#endif
+};
+
+
+/*
+ * IGU driver acknowlegement register
+ */
+struct igu_ack_register {
+#if defined(__BIG_ENDIAN)
+       u16 sb_id_and_flags;
+#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0)
+#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0
+#define IGU_ACK_REGISTER_STORM_ID (0x7<<5)
+#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5
+#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8)
+#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8
+#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9)
+#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9
+#define IGU_ACK_REGISTER_RESERVED (0x1F<<11)
+#define IGU_ACK_REGISTER_RESERVED_SHIFT 11
+       u16 status_block_index;
+#elif defined(__LITTLE_ENDIAN)
+       u16 status_block_index;
+       u16 sb_id_and_flags;
+#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0)
+#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0
+#define IGU_ACK_REGISTER_STORM_ID (0x7<<5)
+#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5
+#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8)
+#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8
+#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9)
+#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9
+#define IGU_ACK_REGISTER_RESERVED (0x1F<<11)
+#define IGU_ACK_REGISTER_RESERVED_SHIFT 11
+#endif
+};
+
+
+/*
+ * Parser parsing flags field
+ */
+struct parsing_flags {
+       u16 flags;
+#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0)
+#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0
+#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS (0x3<<1)
+#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS_SHIFT 1
+#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL (0x3<<3)
+#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT 3
+#define PARSING_FLAGS_IP_OPTIONS (0x1<<5)
+#define PARSING_FLAGS_IP_OPTIONS_SHIFT 5
+#define PARSING_FLAGS_FRAGMENTATION_STATUS (0x1<<6)
+#define PARSING_FLAGS_FRAGMENTATION_STATUS_SHIFT 6
+#define PARSING_FLAGS_OVER_IP_PROTOCOL (0x3<<7)
+#define PARSING_FLAGS_OVER_IP_PROTOCOL_SHIFT 7
+#define PARSING_FLAGS_PURE_ACK_INDICATION (0x1<<9)
+#define PARSING_FLAGS_PURE_ACK_INDICATION_SHIFT 9
+#define PARSING_FLAGS_TCP_OPTIONS_EXIST (0x1<<10)
+#define PARSING_FLAGS_TCP_OPTIONS_EXIST_SHIFT 10
+#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG (0x1<<11)
+#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG_SHIFT 11
+#define PARSING_FLAGS_CONNECTION_MATCH (0x1<<12)
+#define PARSING_FLAGS_CONNECTION_MATCH_SHIFT 12
+#define PARSING_FLAGS_LLC_SNAP (0x1<<13)
+#define PARSING_FLAGS_LLC_SNAP_SHIFT 13
+#define PARSING_FLAGS_RESERVED0 (0x3<<14)
+#define PARSING_FLAGS_RESERVED0_SHIFT 14
+};
+
+
+/*
+ * dmae command structure
+ */
+struct dmae_command {
+       u32 opcode;
+#define DMAE_COMMAND_SRC (0x1<<0)
+#define DMAE_COMMAND_SRC_SHIFT 0
+#define DMAE_COMMAND_DST (0x3<<1)
+#define DMAE_COMMAND_DST_SHIFT 1
+#define DMAE_COMMAND_C_DST (0x1<<3)
+#define DMAE_COMMAND_C_DST_SHIFT 3
+#define DMAE_COMMAND_C_TYPE_ENABLE (0x1<<4)
+#define DMAE_COMMAND_C_TYPE_ENABLE_SHIFT 4
+#define DMAE_COMMAND_C_TYPE_CRC_ENABLE (0x1<<5)
+#define DMAE_COMMAND_C_TYPE_CRC_ENABLE_SHIFT 5
+#define DMAE_COMMAND_C_TYPE_CRC_OFFSET (0x7<<6)
+#define DMAE_COMMAND_C_TYPE_CRC_OFFSET_SHIFT 6
+#define DMAE_COMMAND_ENDIANITY (0x3<<9)
+#define DMAE_COMMAND_ENDIANITY_SHIFT 9
+#define DMAE_COMMAND_PORT (0x1<<11)
+#define DMAE_COMMAND_PORT_SHIFT 11
+#define DMAE_COMMAND_CRC_RESET (0x1<<12)
+#define DMAE_COMMAND_CRC_RESET_SHIFT 12
+#define DMAE_COMMAND_SRC_RESET (0x1<<13)
+#define DMAE_COMMAND_SRC_RESET_SHIFT 13
+#define DMAE_COMMAND_DST_RESET (0x1<<14)
+#define DMAE_COMMAND_DST_RESET_SHIFT 14
+#define DMAE_COMMAND_RESERVED0 (0x1FFFF<<15)
+#define DMAE_COMMAND_RESERVED0_SHIFT 15
+       u32 src_addr_lo;
+       u32 src_addr_hi;
+       u32 dst_addr_lo;
+       u32 dst_addr_hi;
+#if defined(__BIG_ENDIAN)
+       u16 reserved1;
+       u16 len;
+#elif defined(__LITTLE_ENDIAN)
+       u16 len;
+       u16 reserved1;
+#endif
+       u32 comp_addr_lo;
+       u32 comp_addr_hi;
+       u32 comp_val;
+       u32 crc32;
+       u32 crc32_c;
+#if defined(__BIG_ENDIAN)
+       u16 crc16_c;
+       u16 crc16;
+#elif defined(__LITTLE_ENDIAN)
+       u16 crc16;
+       u16 crc16_c;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 reserved2;
+       u16 crc_t10;
+#elif defined(__LITTLE_ENDIAN)
+       u16 crc_t10;
+       u16 reserved2;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 xsum8;
+       u16 xsum16;
+#elif defined(__LITTLE_ENDIAN)
+       u16 xsum16;
+       u16 xsum8;
+#endif
+};
+
+
+struct double_regpair {
+       u32 regpair0_lo;
+       u32 regpair0_hi;
+       u32 regpair1_lo;
+       u32 regpair1_hi;
+};
+
+
+/*
+ * The eth Rx Buffer Descriptor
+ */
+struct eth_rx_bd {
+       u32 addr_lo;
+       u32 addr_hi;
+};
+
+/*
+ * The eth storm context of Ustorm
+ */
+struct ustorm_eth_st_context {
+#if defined(__BIG_ENDIAN)
+       u8 sb_index_number;
+       u8 status_block_id;
+       u8 __local_rx_bd_cons;
+       u8 __local_rx_bd_prod;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __local_rx_bd_prod;
+       u8 __local_rx_bd_cons;
+       u8 status_block_id;
+       u8 sb_index_number;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 rcq_cons;
+       u16 rx_bd_cons;
+#elif defined(__LITTLE_ENDIAN)
+       u16 rx_bd_cons;
+       u16 rcq_cons;
+#endif
+       u32 rx_bd_page_base_lo;
+       u32 rx_bd_page_base_hi;
+       u32 rcq_base_address_lo;
+       u32 rcq_base_address_hi;
+#if defined(__BIG_ENDIAN)
+       u16 __num_of_returned_cqes;
+       u8 num_rss;
+       u8 flags;
+#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1
+#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2
+#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3)
+#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3
+#elif defined(__LITTLE_ENDIAN)
+       u8 flags;
+#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0
+#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1
+#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2)
+#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2
+#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3)
+#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3
+       u8 num_rss;
+       u16 __num_of_returned_cqes;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 mc_alignment_size;
+       u16 agg_threshold;
+#elif defined(__LITTLE_ENDIAN)
+       u16 agg_threshold;
+       u16 mc_alignment_size;
+#endif
+       struct eth_rx_bd __local_bd_ring[16];
+};
+
+/*
+ * The eth storm context of Tstorm
+ */
+struct tstorm_eth_st_context {
+       u32 __reserved0[28];
+};
+
+/*
+ * The eth aggregative context section of Xstorm
+ */
+struct xstorm_eth_extra_ag_context_section {
+#if defined(__BIG_ENDIAN)
+       u8 __tcp_agg_vars1;
+       u8 __reserved50;
+       u16 __mss;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __mss;
+       u8 __reserved50;
+       u8 __tcp_agg_vars1;
+#endif
+       u32 __snd_nxt;
+       u32 __tx_wnd;
+       u32 __snd_una;
+       u32 __reserved53;
+#if defined(__BIG_ENDIAN)
+       u8 __agg_val8_th;
+       u8 __agg_val8;
+       u16 __tcp_agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __tcp_agg_vars2;
+       u8 __agg_val8;
+       u8 __agg_val8_th;
+#endif
+       u32 __reserved58;
+       u32 __reserved59;
+       u32 __reserved60;
+       u32 __reserved61;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val7_th;
+       u16 __agg_val7;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val7;
+       u16 __agg_val7_th;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 __tcp_agg_vars5;
+       u8 __tcp_agg_vars4;
+       u8 __tcp_agg_vars3;
+       u8 __reserved62;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __reserved62;
+       u8 __tcp_agg_vars3;
+       u8 __tcp_agg_vars4;
+       u8 __tcp_agg_vars5;
+#endif
+       u32 __tcp_agg_vars6;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_misc6;
+       u16 __tcp_agg_vars7;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __tcp_agg_vars7;
+       u16 __agg_misc6;
+#endif
+       u32 __agg_val10;
+       u32 __agg_val10_th;
+#if defined(__BIG_ENDIAN)
+       u16 __reserved3;
+       u8 __reserved2;
+       u8 __agg_misc7;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __agg_misc7;
+       u8 __reserved2;
+       u16 __reserved3;
+#endif
+};
+
+/*
+ * The eth aggregative context of Xstorm
+ */
+struct xstorm_eth_ag_context {
+#if defined(__BIG_ENDIAN)
+       u16 __bd_prod;
+       u8 __agg_vars1;
+       u8 __state;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __state;
+       u8 __agg_vars1;
+       u16 __bd_prod;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 cdu_reserved;
+       u8 __agg_vars4;
+       u8 __agg_vars3;
+       u8 __agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __agg_vars2;
+       u8 __agg_vars3;
+       u8 __agg_vars4;
+       u8 cdu_reserved;
+#endif
+       u32 __more_packets_to_send;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_vars5;
+       u16 __agg_val4_th;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val4_th;
+       u16 __agg_vars5;
+#endif
+       struct xstorm_eth_extra_ag_context_section __extra_section;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_vars7;
+       u8 __agg_val3_th;
+       u8 __agg_vars6;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __agg_vars6;
+       u8 __agg_val3_th;
+       u16 __agg_vars7;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val11_th;
+       u16 __agg_val11;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val11;
+       u16 __agg_val11_th;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 __reserved1;
+       u8 __agg_val6_th;
+       u16 __agg_val9;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val9;
+       u8 __agg_val6_th;
+       u8 __reserved1;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val2_th;
+       u16 __agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val2;
+       u16 __agg_val2_th;
+#endif
+       u32 __agg_vars8;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_misc0;
+       u16 __agg_val4;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val4;
+       u16 __agg_misc0;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 __agg_val3;
+       u8 __agg_val6;
+       u8 __agg_val5_th;
+       u8 __agg_val5;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __agg_val5;
+       u8 __agg_val5_th;
+       u8 __agg_val6;
+       u8 __agg_val3;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __agg_misc1;
+       u16 __bd_ind_max_val;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __bd_ind_max_val;
+       u16 __agg_misc1;
+#endif
+       u32 __reserved57;
+       u32 __agg_misc4;
+       u32 __agg_misc5;
+};
+
+/*
+ * The eth aggregative context section of Tstorm
+ */
+struct tstorm_eth_extra_ag_context_section {
+       u32 __agg_val1;
+#if defined(__BIG_ENDIAN)
+       u8 __tcp_agg_vars2;
+       u8 __agg_val3;
+       u16 __agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val2;
+       u8 __agg_val3;
+       u8 __tcp_agg_vars2;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val5;
+       u8 __agg_val6;
+       u8 __tcp_agg_vars3;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __tcp_agg_vars3;
+       u8 __agg_val6;
+       u16 __agg_val5;
+#endif
+       u32 __reserved63;
+       u32 __reserved64;
+       u32 __reserved65;
+       u32 __reserved66;
+       u32 __reserved67;
+       u32 __tcp_agg_vars1;
+       u32 __reserved61;
+       u32 __reserved62;
+       u32 __reserved2;
+};
+
+/*
+ * The eth aggregative context of Tstorm
+ */
+struct tstorm_eth_ag_context {
+#if defined(__BIG_ENDIAN)
+       u16 __reserved54;
+       u8 __agg_vars1;
+       u8 __state;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __state;
+       u8 __agg_vars1;
+       u16 __reserved54;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val4;
+       u16 __agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_vars2;
+       u16 __agg_val4;
+#endif
+       struct tstorm_eth_extra_ag_context_section __extra_section;
+};
+
+/*
+ * The eth aggregative context of Cstorm
+ */
+struct cstorm_eth_ag_context {
+       u32 __agg_vars1;
+#if defined(__BIG_ENDIAN)
+       u8 __aux1_th;
+       u8 __aux1_val;
+       u16 __agg_vars2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_vars2;
+       u8 __aux1_val;
+       u8 __aux1_th;
+#endif
+       u32 __num_of_treated_packet;
+       u32 __last_packet_treated;
+#if defined(__BIG_ENDIAN)
+       u16 __reserved58;
+       u16 __reserved57;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __reserved57;
+       u16 __reserved58;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 __reserved62;
+       u8 __reserved61;
+       u8 __reserved60;
+       u8 __reserved59;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __reserved59;
+       u8 __reserved60;
+       u8 __reserved61;
+       u8 __reserved62;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __reserved64;
+       u16 __reserved63;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __reserved63;
+       u16 __reserved64;
+#endif
+       u32 __reserved65;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_vars3;
+       u16 __rq_inv_cnt;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __rq_inv_cnt;
+       u16 __agg_vars3;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __packet_index_th;
+       u16 __packet_index;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __packet_index;
+       u16 __packet_index_th;
+#endif
+};
+
+/*
+ * The eth aggregative context of Ustorm
+ */
+struct ustorm_eth_ag_context {
+#if defined(__BIG_ENDIAN)
+       u8 __aux_counter_flags;
+       u8 __agg_vars2;
+       u8 __agg_vars1;
+       u8 __state;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __state;
+       u8 __agg_vars1;
+       u8 __agg_vars2;
+       u8 __aux_counter_flags;
+#endif
+#if defined(__BIG_ENDIAN)
+       u8 cdu_usage;
+       u8 __agg_misc2;
+       u16 __agg_misc1;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_misc1;
+       u8 __agg_misc2;
+       u8 cdu_usage;
+#endif
+       u32 __agg_misc4;
+#if defined(__BIG_ENDIAN)
+       u8 __agg_val3_th;
+       u8 __agg_val3;
+       u16 __agg_misc3;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_misc3;
+       u8 __agg_val3;
+       u8 __agg_val3_th;
+#endif
+       u32 __agg_val1;
+       u32 __agg_misc4_th;
+#if defined(__BIG_ENDIAN)
+       u16 __agg_val2_th;
+       u16 __agg_val2;
+#elif defined(__LITTLE_ENDIAN)
+       u16 __agg_val2;
+       u16 __agg_val2_th;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 __reserved2;
+       u8 __decision_rules;
+       u8 __decision_rule_enable_bits;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __decision_rule_enable_bits;
+       u8 __decision_rules;
+       u16 __reserved2;
+#endif
+};
+
+/*
+ * Timers connection context
+ */
+struct timers_block_context {
+       u32 __reserved_0;
+       u32 __reserved_1;
+       u32 __reserved_2;
+       u32 __reserved_flags;
+};
+
+/*
+ * structure for easy accessability to assembler
+ */
+struct eth_tx_bd_flags {
+       u8 as_bitfield;
+#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0)
+#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0
+#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1)
+#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1
+#define ETH_TX_BD_FLAGS_TCP_CSUM (0x1<<2)
+#define ETH_TX_BD_FLAGS_TCP_CSUM_SHIFT 2
+#define ETH_TX_BD_FLAGS_END_BD (0x1<<3)
+#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3
+#define ETH_TX_BD_FLAGS_START_BD (0x1<<4)
+#define ETH_TX_BD_FLAGS_START_BD_SHIFT 4
+#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5)
+#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5
+#define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6)
+#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6
+#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7)
+#define ETH_TX_BD_FLAGS_IPV6_SHIFT 7
+};
+
+/*
+ * The eth Tx Buffer Descriptor
+ */
+struct eth_tx_bd {
+       u32 addr_lo;
+       u32 addr_hi;
+       u16 nbd;
+       u16 nbytes;
+       u16 vlan;
+       struct eth_tx_bd_flags bd_flags;
+       u8 general_data;
+#define ETH_TX_BD_HDR_NBDS (0x3F<<0)
+#define ETH_TX_BD_HDR_NBDS_SHIFT 0
+#define ETH_TX_BD_ETH_ADDR_TYPE (0x3<<6)
+#define ETH_TX_BD_ETH_ADDR_TYPE_SHIFT 6
+};
+
+/*
+ * Tx parsing BD structure for ETH,Relevant in START
+ */
+struct eth_tx_parse_bd {
+       u8 global_data;
+#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0)
+#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0
+#define ETH_TX_PARSE_BD_CS_ANY_FLG (0x1<<4)
+#define ETH_TX_PARSE_BD_CS_ANY_FLG_SHIFT 4
+#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5)
+#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5
+#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6)
+#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6
+#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7)
+#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7
+       u8 tcp_flags;
+#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0)
+#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0
+#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1)
+#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1
+#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2)
+#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2
+#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3)
+#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3
+#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4)
+#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4
+#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5)
+#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5
+#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6)
+#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6
+#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7)
+#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7
+       u8 ip_hlen;
+       s8 cs_offset;
+       u16 total_hlen;
+       u16 lso_mss;
+       u16 tcp_pseudo_csum;
+       u16 ip_id;
+       u32 tcp_send_seq;
+};
+
+/*
+ * The last BD in the BD memory will hold a pointer to the next BD memory
+ */
+struct eth_tx_next_bd {
+       u32 addr_lo;
+       u32 addr_hi;
+       u8 reserved[8];
+};
+
+/*
+ * union for 3 Bd types
+ */
+union eth_tx_bd_types {
+       struct eth_tx_bd reg_bd;
+       struct eth_tx_parse_bd parse_bd;
+       struct eth_tx_next_bd next_bd;
+};
+
+/*
+ * The eth storm context of Xstorm
+ */
+struct xstorm_eth_st_context {
+       u32 tx_bd_page_base_lo;
+       u32 tx_bd_page_base_hi;
+#if defined(__BIG_ENDIAN)
+       u16 tx_bd_cons;
+       u8 __reserved0;
+       u8 __local_tx_bd_prod;
+#elif defined(__LITTLE_ENDIAN)
+       u8 __local_tx_bd_prod;
+       u8 __reserved0;
+       u16 tx_bd_cons;
+#endif
+       u32 db_data_addr_lo;
+       u32 db_data_addr_hi;
+       u32 __pkt_cons;
+       u32 __gso_next;
+       u32 is_eth_conn_1b;
+       union eth_tx_bd_types __bds[13];
+};
+
+/*
+ * The eth storm context of Cstorm
+ */
+struct cstorm_eth_st_context {
+#if defined(__BIG_ENDIAN)
+       u16 __reserved0;
+       u8 sb_index_number;
+       u8 status_block_id;
+#elif defined(__LITTLE_ENDIAN)
+       u8 status_block_id;
+       u8 sb_index_number;
+       u16 __reserved0;
+#endif
+       u32 __reserved1[3];
+};
+
+/*
+ * Ethernet connection context
+ */
+struct eth_context {
+       struct ustorm_eth_st_context ustorm_st_context;
+       struct tstorm_eth_st_context tstorm_st_context;
+       struct xstorm_eth_ag_context xstorm_ag_context;
+       struct tstorm_eth_ag_context tstorm_ag_context;
+       struct cstorm_eth_ag_context cstorm_ag_context;
+       struct ustorm_eth_ag_context ustorm_ag_context;
+       struct timers_block_context timers_context;
+       struct xstorm_eth_st_context xstorm_st_context;
+       struct cstorm_eth_st_context cstorm_st_context;
+};
+
+
+/*
+ * ethernet doorbell
+ */
+struct eth_tx_doorbell {
+#if defined(__BIG_ENDIAN)
+       u16 npackets;
+       u8 params;
+#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0)
+#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0
+#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6)
+#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6
+#define ETH_TX_DOORBELL_SPARE (0x1<<7)
+#define ETH_TX_DOORBELL_SPARE_SHIFT 7
+       struct doorbell_hdr hdr;
+#elif defined(__LITTLE_ENDIAN)
+       struct doorbell_hdr hdr;
+       u8 params;
+#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0)
+#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0
+#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6)
+#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6
+#define ETH_TX_DOORBELL_SPARE (0x1<<7)
+#define ETH_TX_DOORBELL_SPARE_SHIFT 7
+       u16 npackets;
+#endif
+};
+
+
+/*
+ * ustorm status block
+ */
+struct ustorm_def_status_block {
+       u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * cstorm status block
+ */
+struct cstorm_def_status_block {
+       u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * xstorm status block
+ */
+struct xstorm_def_status_block {
+       u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * tstorm status block
+ */
+struct tstorm_def_status_block {
+       u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * host status block
+ */
+struct host_def_status_block {
+       struct atten_def_status_block atten_status_block;
+       struct ustorm_def_status_block u_def_status_block;
+       struct cstorm_def_status_block c_def_status_block;
+       struct xstorm_def_status_block x_def_status_block;
+       struct tstorm_def_status_block t_def_status_block;
+};
+
+
+/*
+ * ustorm status block
+ */
+struct ustorm_status_block {
+       u16 index_values[HC_USTORM_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * cstorm status block
+ */
+struct cstorm_status_block {
+       u16 index_values[HC_CSTORM_SB_NUM_INDICES];
+       u16 status_block_index;
+       u8 reserved0;
+       u8 status_block_id;
+       u32 __flags;
+};
+
+/*
+ * host status block
+ */
+struct host_status_block {
+       struct ustorm_status_block u_status_block;
+       struct cstorm_status_block c_status_block;
+};
+
+
+/*
+ * The data for RSS setup ramrod
+ */
+struct eth_client_setup_ramrod_data {
+       u32 client_id_5b;
+       u8 is_rdma_1b;
+       u8 reserved0;
+       u16 reserved1;
+};
+
+
+/*
+ * L2 dynamic host coalescing init parameters
+ */
+struct eth_dynamic_hc_config {
+       u32 threshold[3];
+       u8 hc_timeout[4];
+};
+
+
+/*
+ * regular eth FP CQE parameters struct
+ */
+struct eth_fast_path_rx_cqe {
+       u8 type;
+       u8 error_type_flags;
+#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<0)
+#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 0
+#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<1)
+#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 1
+#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<2)
+#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 2
+#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<3)
+#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 3
+#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<4)
+#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 4
+#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x7<<5)
+#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 5
+       u8 status_flags;
+#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0)
+#define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0
+#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG (0x1<<3)
+#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG_SHIFT 3
+#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG (0x1<<4)
+#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG_SHIFT 4
+#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG (0x1<<5)
+#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG_SHIFT 5
+#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG (0x1<<6)
+#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6
+#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7)
+#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7
+       u8 placement_offset;
+       u32 rss_hash_result;
+       u16 vlan_tag;
+       u16 pkt_len;
+       u16 queue_index;
+       struct parsing_flags pars_flags;
+};
+
+
+/*
+ * The data for RSS setup ramrod
+ */
+struct eth_halt_ramrod_data {
+       u32 client_id_5b;
+       u32 reserved0;
+};
+
+
+/*
+ * Place holder for ramrods protocol specific data
+ */
+struct ramrod_data {
+       u32 data_lo;
+       u32 data_hi;
+};
+
+/*
+ * union for ramrod data for ethernet protocol (CQE) (force size of 16 bits)
+ */
+union eth_ramrod_data {
+       struct ramrod_data general;
+};
+
+
+/*
+ * Rx Last BD in page (in ETH)
+ */
+struct eth_rx_bd_next_page {
+       u32 addr_lo;
+       u32 addr_hi;
+       u8 reserved[8];
+};
+
+
+/*
+ * Eth Rx Cqe structure- general structure for ramrods
+ */
+struct common_ramrod_eth_rx_cqe {
+       u8 type;
+       u8 conn_type_3b;
+       u16 reserved;
+       u32 conn_and_cmd_data;
+#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0)
+#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0
+#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24)
+#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24
+       struct ramrod_data protocol_data;
+};
+
+/*
+ * Rx Last CQE in page (in ETH)
+ */
+struct eth_rx_cqe_next_page {
+       u32 addr_lo;
+       u32 addr_hi;
+       u32 reserved0;
+       u32 reserved1;
+};
+
+/*
+ * union for all eth rx cqe types (fix their sizes)
+ */
+union eth_rx_cqe {
+       struct eth_fast_path_rx_cqe fast_path_cqe;
+       struct common_ramrod_eth_rx_cqe ramrod_cqe;
+       struct eth_rx_cqe_next_page next_page_cqe;
+};
+
+
+/*
+ * common data for all protocols
+ */
+struct spe_hdr {
+       u32 conn_and_cmd_data;
+#define SPE_HDR_CID (0xFFFFFF<<0)
+#define SPE_HDR_CID_SHIFT 0
+#define SPE_HDR_CMD_ID (0xFF<<24)
+#define SPE_HDR_CMD_ID_SHIFT 24
+       u16 type;
+#define SPE_HDR_CONN_TYPE (0xFF<<0)
+#define SPE_HDR_CONN_TYPE_SHIFT 0
+#define SPE_HDR_COMMON_RAMROD (0xFF<<8)
+#define SPE_HDR_COMMON_RAMROD_SHIFT 8
+       u16 reserved;
+};
+
+struct regpair {
+       u32 lo;
+       u32 hi;
+};
+
+/*
+ * ethernet slow path element
+ */
+union eth_specific_data {
+       u8 protocol_data[8];
+       struct regpair mac_config_addr;
+       struct eth_client_setup_ramrod_data client_setup_ramrod_data;
+       struct eth_halt_ramrod_data halt_ramrod_data;
+       struct regpair leading_cqe_addr;
+       struct regpair update_data_addr;
+};
+
+/*
+ * ethernet slow path element
+ */
+struct eth_spe {
+       struct spe_hdr hdr;
+       union eth_specific_data data;
+};
+
+
+/*
+ * doorbell data in host memory
+ */
+struct eth_tx_db_data {
+       u32 packets_prod;
+       u16 bds_prod;
+       u16 reserved;
+};
+
+
+/*
+ * Common configuration parameters per port in Tstorm
+ */
+struct tstorm_eth_function_common_config {
+       u32 config_flags;
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5)
+#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3FFFFFF<<6)
+#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 6
+#if defined(__BIG_ENDIAN)
+       u16 __secondary_vlan_id;
+       u8 leading_client_id;
+       u8 rss_result_mask;
+#elif defined(__LITTLE_ENDIAN)
+       u8 rss_result_mask;
+       u8 leading_client_id;
+       u16 __secondary_vlan_id;
+#endif
+};
+
+/*
+ * parameters for eth update ramrod
+ */
+struct eth_update_ramrod_data {
+       struct tstorm_eth_function_common_config func_config;
+       u8 indirectionTable[128];
+};
+
+
+/*
+ * MAC filtering configuration command header
+ */
+struct mac_configuration_hdr {
+       u8 length_6b;
+       u8 offset;
+       u16 reserved0;
+       u32 reserved1;
+};
+
+/*
+ * MAC address in list for ramrod
+ */
+struct tstorm_cam_entry {
+       u16 lsb_mac_addr;
+       u16 middle_mac_addr;
+       u16 msb_mac_addr;
+       u16 flags;
+#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0)
+#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0
+#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1)
+#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1
+#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4)
+#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4
+};
+
+/*
+ * MAC filtering: CAM target table entry
+ */
+struct tstorm_cam_target_table_entry {
+       u8 flags;
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0)
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1)
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2)
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3)
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4)
+#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4
+       u8 client_id;
+       u16 vlan_id;
+};
+
+/*
+ * MAC address in list for ramrod
+ */
+struct mac_configuration_entry {
+       struct tstorm_cam_entry cam_entry;
+       struct tstorm_cam_target_table_entry target_table_entry;
+};
+
+/*
+ * MAC filtering configuration command
+ */
+struct mac_configuration_cmd {
+       struct mac_configuration_hdr hdr;
+       struct mac_configuration_entry config_table[64];
+};
+
+
+/*
+ * Configuration parameters per client in Tstorm
+ */
+struct tstorm_eth_client_config {
+#if defined(__BIG_ENDIAN)
+       u16 statistics_counter_id;
+       u16 mtu;
+#elif defined(__LITTLE_ENDIAN)
+       u16 mtu;
+       u16 statistics_counter_id;
+#endif
+#if defined(__BIG_ENDIAN)
+       u16 drop_flags;
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5
+       u16 config_flags;
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2
+#elif defined(__LITTLE_ENDIAN)
+       u16 config_flags;
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2
+       u16 drop_flags;
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR (0x1<<2)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4)
+#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5)
+#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5
+#endif
+};
+
+
+/*
+ * MAC filtering configuration parameters per port in Tstorm
+ */
+struct tstorm_eth_mac_filter_config {
+       u32 ucast_drop_all;
+       u32 ucast_accept_all;
+       u32 mcast_drop_all;
+       u32 mcast_accept_all;
+       u32 bcast_drop_all;
+       u32 bcast_accept_all;
+       u32 strict_vlan;
+       u32 __secondary_vlan_clients;
+};
+
+
+struct rate_shaping_per_protocol {
+#if defined(__BIG_ENDIAN)
+       u16 reserved0;
+       u16 protocol_rate;
+#elif defined(__LITTLE_ENDIAN)
+       u16 protocol_rate;
+       u16 reserved0;
+#endif
+       u32 protocol_quota;
+       s32 current_credit;
+       u32 reserved;
+};
+
+struct rate_shaping_vars {
+       struct rate_shaping_per_protocol protocol_vars[NUM_OF_PROTOCOLS];
+       u32 pause_mask;
+       u32 periodic_stop;
+       u32 rs_periodic_timeout;
+       u32 rs_threshold;
+       u32 last_periodic_time;
+       u32 reserved;
+};
+
+struct fairness_per_protocol {
+       u32 credit_delta;
+       s32 fair_credit;
+#if defined(__BIG_ENDIAN)
+       u16 reserved0;
+       u8 state;
+       u8 weight;
+#elif defined(__LITTLE_ENDIAN)
+       u8 weight;
+       u8 state;
+       u16 reserved0;
+#endif
+       u32 reserved1;
+};
+
+struct fairness_vars {
+       struct fairness_per_protocol protocol_vars[NUM_OF_PROTOCOLS];
+       u32 upper_bound;
+       u32 port_rate;
+       u32 pause_mask;
+       u32 fair_threshold;
+};
+
+struct safc_struct {
+       u32 cur_pause_mask;
+       u32 expire_time;
+#if defined(__BIG_ENDIAN)
+       u16 reserved0;
+       u8 cur_cos_types;
+       u8 safc_timeout_usec;
+#elif defined(__LITTLE_ENDIAN)
+       u8 safc_timeout_usec;
+       u8 cur_cos_types;
+       u16 reserved0;
+#endif
+       u32 reserved1;
+};
+
+struct demo_struct {
+       u8 con_number[NUM_OF_PROTOCOLS];
+#if defined(__BIG_ENDIAN)
+       u8 reserved1;
+       u8 fairness_enable;
+       u8 rate_shaping_enable;
+       u8 cmng_enable;
+#elif defined(__LITTLE_ENDIAN)
+       u8 cmng_enable;
+       u8 rate_shaping_enable;
+       u8 fairness_enable;
+       u8 reserved1;
+#endif
+};
+
+struct cmng_struct {
+       struct rate_shaping_vars rs_vars;
+       struct fairness_vars fair_vars;
+       struct safc_struct safc_vars;
+       struct demo_struct demo_vars;
+};
+
+
+struct cos_to_protocol {
+       u8 mask[MAX_COS_NUMBER];
+};
+
+
+/*
+ * Common statistics collected by the Xstorm (per port)
+ */
+struct xstorm_common_stats {
+       struct regpair total_sent_bytes;
+       u32 total_sent_pkts;
+       u32 unicast_pkts_sent;
+       struct regpair unicast_bytes_sent;
+       struct regpair multicast_bytes_sent;
+       u32 multicast_pkts_sent;
+       u32 broadcast_pkts_sent;
+       struct regpair broadcast_bytes_sent;
+       struct regpair done;
+};
+
+/*
+ * Protocol-common statistics collected by the Tstorm (per client)
+ */
+struct tstorm_per_client_stats {
+       struct regpair total_rcv_bytes;
+       struct regpair rcv_unicast_bytes;
+       struct regpair rcv_broadcast_bytes;
+       struct regpair rcv_multicast_bytes;
+       struct regpair rcv_error_bytes;
+       u32 checksum_discard;
+       u32 packets_too_big_discard;
+       u32 total_rcv_pkts;
+       u32 rcv_unicast_pkts;
+       u32 rcv_broadcast_pkts;
+       u32 rcv_multicast_pkts;
+       u32 no_buff_discard;
+       u32 ttl0_discard;
+       u32 mac_discard;
+       u32 reserved;
+};
+
+/*
+ * Protocol-common statistics collected by the Tstorm (per port)
+ */
+struct tstorm_common_stats {
+       struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID];
+       u32 mac_filter_discard;
+       u32 xxoverflow_discard;
+       u32 brb_truncate_discard;
+       u32 reserved;
+       struct regpair done;
+};
+
+/*
+ * Eth statistics query sturcture for the eth_stats_quesry ramrod
+ */
+struct eth_stats_query {
+       struct xstorm_common_stats xstorm_common;
+       struct tstorm_common_stats tstorm_common;
+};
+
+
+/*
+ * FW version stored in the Xstorm RAM
+ */
+struct fw_version {
+#if defined(__BIG_ENDIAN)
+       u16 patch;
+       u8 primary;
+       u8 client;
+#elif defined(__LITTLE_ENDIAN)
+       u8 client;
+       u8 primary;
+       u16 patch;
+#endif
+       u32 flags;
+#define FW_VERSION_OPTIMIZED (0x1<<0)
+#define FW_VERSION_OPTIMIZED_SHIFT 0
+#define FW_VERSION_BIG_ENDIEN (0x1<<1)
+#define FW_VERSION_BIG_ENDIEN_SHIFT 1
+#define __FW_VERSION_RESERVED (0x3FFFFFFF<<2)
+#define __FW_VERSION_RESERVED_SHIFT 2
+};
+
+
+/*
+ * FW version stored in first line of pram
+ */
+struct pram_fw_version {
+#if defined(__BIG_ENDIAN)
+       u16 patch;
+       u8 primary;
+       u8 client;
+#elif defined(__LITTLE_ENDIAN)
+       u8 client;
+       u8 primary;
+       u16 patch;
+#endif
+       u8 flags;
+#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0)
+#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0
+#define PRAM_FW_VERSION_STORM_ID (0x3<<1)
+#define PRAM_FW_VERSION_STORM_ID_SHIFT 1
+#define PRAM_FW_VERSION_BIG_ENDIEN (0x1<<3)
+#define PRAM_FW_VERSION_BIG_ENDIEN_SHIFT 3
+#define __PRAM_FW_VERSION_RESERVED0 (0xF<<4)
+#define __PRAM_FW_VERSION_RESERVED0_SHIFT 4
+};
+
+
+/*
+ * The send queue element
+ */
+struct slow_path_element {
+       struct spe_hdr hdr;
+       u8 protocol_data[8];
+};
+
+
+/*
+ * eth/toe flags that indicate if to query
+ */
+struct stats_indication_flags {
+       u32 collect_eth;
+       u32 collect_toe;
+};
+
+
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
new file mode 100644 (file)
index 0000000..04f93bf
--- /dev/null
@@ -0,0 +1,564 @@
+/* bnx2x_init.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ *
+ * Written by: Eliezer Tamir <eliezert@broadcom.com>
+ */
+
+#ifndef BNX2X_INIT_H
+#define BNX2X_INIT_H
+
+#define COMMON                         0x1
+#define PORT0                          0x2
+#define PORT1                          0x4
+
+#define INIT_EMULATION                 0x1
+#define INIT_FPGA                      0x2
+#define INIT_ASIC                      0x4
+#define INIT_HARDWARE                  0x7
+
+#define STORM_INTMEM_SIZE              (0x5800 / 4)
+#define TSTORM_INTMEM_ADDR             0x1a0000
+#define CSTORM_INTMEM_ADDR             0x220000
+#define XSTORM_INTMEM_ADDR             0x2a0000
+#define USTORM_INTMEM_ADDR             0x320000
+
+
+/* Init operation types and structures */
+
+#define OP_RD                  0x1 /* read single register */
+#define OP_WR                  0x2 /* write single register */
+#define OP_IW                  0x3 /* write single register using mailbox */
+#define OP_SW                  0x4 /* copy a string to the device */
+#define OP_SI                  0x5 /* copy a string using mailbox */
+#define OP_ZR                  0x6 /* clear memory */
+#define OP_ZP                  0x7 /* unzip then copy with DMAE */
+#define OP_WB                  0x8 /* copy a string using DMAE */
+
+struct raw_op {
+       u32 op          :8;
+       u32 offset      :24;
+       u32 raw_data;
+};
+
+struct op_read {
+       u32 op          :8;
+       u32 offset      :24;
+       u32 pad;
+};
+
+struct op_write {
+       u32 op          :8;
+       u32 offset      :24;
+       u32 val;
+};
+
+struct op_string_write {
+       u32 op          :8;
+       u32 offset      :24;
+#ifdef __LITTLE_ENDIAN
+       u16 data_off;
+       u16 data_len;
+#else /* __BIG_ENDIAN */
+       u16 data_len;
+       u16 data_off;
+#endif
+};
+
+struct op_zero {
+       u32 op          :8;
+       u32 offset      :24;
+       u32 len;
+};
+
+union init_op {
+       struct op_read          read;
+       struct op_write         write;
+       struct op_string_write  str_wr;
+       struct op_zero          zero;
+       struct raw_op           raw;
+};
+
+#include "bnx2x_init_values.h"
+
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
+
+static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
+                            u32 dst_addr, u32 len32);
+
+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();
+               }
+       }
+}
+
+#define INIT_MEM_WR(reg, data, reg_off, len) \
+       bnx2x_init_str_wr(bp, reg + reg_off*4, data, len)
+
+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_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
+                            u32 len, int gunzip)
+{
+       int offset = 0;
+
+       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) {
+                       DP(NETIF_MSG_HW, "gunzip failed ! rc %d\n", rc);
+                       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 ! len 0x%x\n", len*4);
+                       return;
+               }
+               memcpy(bp->gunzip_buf, data, len * 4);
+       }
+
+       while (len > DMAE_LEN32_MAX) {
+               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                addr + offset, DMAE_LEN32_MAX);
+               offset += DMAE_LEN32_MAX * 4;
+               len -= DMAE_LEN32_MAX;
+       }
+       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
+}
+
+#define INIT_MEM_WB(reg, data, reg_off, len) \
+       bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 0)
+
+#define INIT_GUNZIP_DMAE(reg, data, reg_off, len) \
+       bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 1)
+
+static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
+{
+       int offset = 0;
+
+       if ((len * 4) > FW_BUF_SIZE) {
+               BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len * 4);
+               return;
+       }
+       memset(bp->gunzip_buf, fill, len * 4);
+
+       while (len > DMAE_LEN32_MAX) {
+               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                addr + offset, DMAE_LEN32_MAX);
+               offset += DMAE_LEN32_MAX * 4;
+               len -= DMAE_LEN32_MAX;
+       }
+       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len);
+}
+
+static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
+{
+       int i;
+       union init_op *op;
+       u32 op_type, addr, len;
+       const u32 *data;
+
+       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 = init_data + op->str_wr.data_off;
+
+               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);
+                       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);
+                       break;
+               default:
+                       BNX2X_ERR("BAD init operation!\n");
+               }
+       }
+}
+
+
+/****************************************************************************
+* PXP
+****************************************************************************/
+/*
+ * This code configures the PCI read/write arbiter
+ * which implements a wighted round robin
+ * between the virtual queues in the chip.
+ *
+ * The values were derived for each PCI max payload and max request size.
+ * since max payload and max request size are only known at run time,
+ * this is done as a separate init stage.
+ */
+
+#define NUM_WR_Q                       13
+#define NUM_RD_Q                       29
+#define MAX_RD_ORD                     3
+#define MAX_WR_ORD                     2
+
+/* configuration for one arbiter queue */
+struct arb_line {
+       int l;
+       int add;
+       int ubound;
+};
+
+/* derived configuration for each read queue for each max request size */
+static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
+       {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
+       {{4 , 8 , 4},   {4 , 8 , 4},    {4 , 8 , 4},    {4 , 8 , 4} },
+       {{4 , 3 , 3},   {4 , 3 , 3},    {4 , 3 , 3},    {4 , 3 , 3} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {16 , 3 , 11},  {16 , 3 , 11} },
+       {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {64 , 3 , 41} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 3 , 6},   {16 , 3 , 11},  {32 , 3 , 21},  {32 , 3 , 21} },
+       {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} }
+};
+
+/* derived configuration for each write queue for each max request size */
+static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
+       {{4 , 6 , 3},   {4 , 6 , 3},    {4 , 6 , 3} },
+       {{4 , 2 , 3},   {4 , 2 , 3},    {4 , 2 , 3} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {32 , 2 , 21} },
+       {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
+       {{8 , 2 , 6},   {16 , 2 , 11},  {16 , 2 , 11} },
+       {{8 , 9 , 6},   {16 , 9 , 11},  {32 , 9 , 21} },
+       {{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} },
+       {{8 , 9 , 6},   {16 , 9 , 11},  {16 , 9 , 11} },
+       {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} }
+};
+
+/* register adresses for read queues */
+static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
+       {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
+               PXP2_REG_RQ_BW_RD_UBOUND0},
+       {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+               PXP2_REG_PSWRQ_BW_UB1},
+       {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
+               PXP2_REG_PSWRQ_BW_UB2},
+       {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
+               PXP2_REG_PSWRQ_BW_UB3},
+       {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
+               PXP2_REG_RQ_BW_RD_UBOUND4},
+       {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
+               PXP2_REG_RQ_BW_RD_UBOUND5},
+       {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
+               PXP2_REG_PSWRQ_BW_UB6},
+       {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
+               PXP2_REG_PSWRQ_BW_UB7},
+       {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
+               PXP2_REG_PSWRQ_BW_UB8},
+       {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+               PXP2_REG_PSWRQ_BW_UB9},
+       {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
+               PXP2_REG_PSWRQ_BW_UB10},
+       {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
+               PXP2_REG_PSWRQ_BW_UB11},
+       {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
+               PXP2_REG_RQ_BW_RD_UBOUND12},
+       {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
+               PXP2_REG_RQ_BW_RD_UBOUND13},
+       {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
+               PXP2_REG_RQ_BW_RD_UBOUND14},
+       {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
+               PXP2_REG_RQ_BW_RD_UBOUND15},
+       {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
+               PXP2_REG_RQ_BW_RD_UBOUND16},
+       {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
+               PXP2_REG_RQ_BW_RD_UBOUND17},
+       {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
+               PXP2_REG_RQ_BW_RD_UBOUND18},
+       {PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
+               PXP2_REG_RQ_BW_RD_UBOUND19},
+       {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
+               PXP2_REG_RQ_BW_RD_UBOUND20},
+       {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
+               PXP2_REG_RQ_BW_RD_UBOUND22},
+       {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
+               PXP2_REG_RQ_BW_RD_UBOUND23},
+       {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
+               PXP2_REG_RQ_BW_RD_UBOUND24},
+       {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
+               PXP2_REG_RQ_BW_RD_UBOUND25},
+       {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
+               PXP2_REG_RQ_BW_RD_UBOUND26},
+       {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
+               PXP2_REG_RQ_BW_RD_UBOUND27},
+       {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+               PXP2_REG_PSWRQ_BW_UB28}
+};
+
+/* register adresses for wrtie queues */
+static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
+       {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
+               PXP2_REG_PSWRQ_BW_UB1},
+       {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
+               PXP2_REG_PSWRQ_BW_UB2},
+       {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
+               PXP2_REG_PSWRQ_BW_UB3},
+       {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
+               PXP2_REG_PSWRQ_BW_UB6},
+       {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
+               PXP2_REG_PSWRQ_BW_UB7},
+       {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
+               PXP2_REG_PSWRQ_BW_UB8},
+       {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
+               PXP2_REG_PSWRQ_BW_UB9},
+       {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
+               PXP2_REG_PSWRQ_BW_UB10},
+       {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
+               PXP2_REG_PSWRQ_BW_UB11},
+       {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
+               PXP2_REG_PSWRQ_BW_UB28},
+       {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
+               PXP2_REG_RQ_BW_WR_UBOUND29},
+       {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
+               PXP2_REG_RQ_BW_WR_UBOUND30}
+};
+
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+       int r_order, w_order;
+       u32 val, i;
+
+       pci_read_config_word(bp->pdev,
+                            bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
+       DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val);
+       w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+       r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
+
+       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;
+       }
+       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_MBS0 + 8, w_order);
+       REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
+       REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order);
+
+       REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16);
+}
+
+
+/****************************************************************************
+* CDU
+****************************************************************************/
+
+#define CDU_REGION_NUMBER_XCM_AG       2
+#define CDU_REGION_NUMBER_UCM_AG       4
+
+/**
+ * String-to-compress [31:8] = CID (all 24 bits)
+ * String-to-compress [7:4] = Region
+ * String-to-compress [3:0] = Type
+ */
+#define CDU_VALID_DATA(_cid, _region, _type) \
+               (((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf)))
+#define CDU_CRC8(_cid, _region, _type) \
+                       calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff)
+#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \
+                       (0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f))
+#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \
+       (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;
+}
+
+
+#endif /* BNX2X_INIT_H */
+
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
new file mode 100644 (file)
index 0000000..bef0a9b
--- /dev/null
@@ -0,0 +1,6368 @@
+#ifndef __BNX2X_INIT_VALUES_H__
+#define __BNX2X_INIT_VALUES_H__
+
+/* 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, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
+       {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, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
+       {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, 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, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
+       {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          46
+#define PRS_PORT0_START         46
+       {OP_WR, PRS_REG_CID_PORT_0, 0x0},
+#define PRS_PORT0_END           47
+#define PRS_PORT1_START         47
+       {OP_WR, PRS_REG_CID_PORT_1, 0x800000},
+#define PRS_PORT1_END           48
+#define TSDM_COMMON_START       48
+       {OP_WR, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
+       {OP_WR, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
+       {OP_WR, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
+       {OP_WR, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
+       {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, TSDM_REG_AGG_INT_EVENT_0, 0x80},
+       {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, TSDM_REG_TIMER_TICK, 0x3e8},
+#define TSDM_COMMON_END         76
+#define TCM_COMMON_START        76
+       {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_PRS_WEIGHT, 0x4},
+       {OP_WR, TCM_REG_PBF_WEIGHT, 0x5},
+       {OP_WR, TCM_REG_CP_WEIGHT, 0x0},
+       {OP_WR, TCM_REG_TSDM_WEIGHT, 0x4},
+       {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, TCM_REG_N_SM_CTX_LD_4, 0x4},
+       {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
+       {OP_WR, TCM_REG_PHYS_QNUM0_0, 0xd},
+       {OP_WR, TCM_REG_PHYS_QNUM0_1, 0x2d},
+       {OP_ZR, TCM_REG_PHYS_QNUM1_0, 0x6},
+       {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          126
+#define BRB1_COMMON_START       126
+       {OP_SW, BRB1_REG_LL_RAM, 0x2000020},
+       {OP_WR, BRB1_REG_SOFT_RESET, 0x1},
+       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_2, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_3, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_2, 0x0},
+       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_3, 0x0},
+       {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         139
+#define TSEM_COMMON_START       139
+       {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, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+       {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2000, 0x1b3},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x2000 + 0x6cc, 0x10223},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1fa0, 0x4},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x4cf0, 0x80224},
+       {OP_ZP, TSEM_REG_INT_TABLE, 0x8c022c},
+       {OP_ZP, TSEM_REG_PRAM, 0x3395024f},
+       {OP_ZP, TSEM_REG_PRAM + 0x8000, 0x2c760f35},
+       {OP_ZP, TSEM_REG_PRAM + 0x10000, 0x5e1a53},
+       {OP_ZP, TSEM_REG_PRAM + 0x18000, 0x5e1a6b},
+       {OP_ZP, TSEM_REG_PRAM + 0x20000, 0x5e1a83},
+       {OP_ZP, TSEM_REG_PRAM + 0x28000, 0x5e1a9b},
+       {OP_ZP, TSEM_REG_PRAM + 0x30000, 0x5e1ab3},
+       {OP_ZP, TSEM_REG_PRAM + 0x38000, 0x5e1acb},
+#define TSEM_COMMON_END         202
+#define TSEM_PORT0_START        202
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x4000 + 0x5b0, 0x21ae3},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1370, 0xa},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13c0, 0x6},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1418, 0xc},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1478, 0x12},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1508, 0x90},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x820, 0x10},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x820 + 0x40, 0x21ae5},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2908, 0xa},
+#define TSEM_PORT0_END          213
+#define TSEM_PORT1_START        213
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x45b8, 0x16c},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x45b8 + 0x5b0, 0x21ae7},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1398, 0xa},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13d8, 0x6},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1448, 0xc},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x14c0, 0x12},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1748, 0x90},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x868, 0x10},
+       {OP_SW, TSEM_REG_FAST_MEMORY + 0x868 + 0x40, 0x21ae9},
+       {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2930, 0xa},
+#define TSEM_PORT1_END          224
+#define MISC_COMMON_START       224
+       {OP_WR, 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},
+#define MISC_COMMON_END         230
+#define NIG_COMMON_START        230
+       {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          235
+#define NIG_PORT0_START         235
+       {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
+       {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x26},
+       {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, 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           246
+#define NIG_PORT1_START         246
+       {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
+       {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x26},
+       {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, 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           257
+#define UPB_COMMON_START        257
+       {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
+#define UPB_COMMON_END          258
+#define CSDM_COMMON_START       258
+       {OP_WR, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
+       {OP_WR, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
+       {OP_WR, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+       {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_ZR, CSDM_REG_AGG_INT_EVENT_0, 0x80},
+       {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, CSDM_REG_TIMER_TICK, 0x3e8},
+#define CSDM_COMMON_END         285
+#define USDM_COMMON_START       285
+       {OP_WR, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
+       {OP_WR, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
+       {OP_WR, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+       {OP_WR, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
+       {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_ZR, USDM_REG_AGG_INT_EVENT_1, 0x5f},
+       {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
+       {OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f},
+       {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, USDM_REG_TIMER_TICK, 0x3e8},
+#define USDM_COMMON_END         317
+#define CCM_COMMON_START        317
+       {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_TSEM_WEIGHT, 0x0},
+       {OP_WR, CCM_REG_XSEM_WEIGHT, 0x4},
+       {OP_WR, CCM_REG_USEM_WEIGHT, 0x4},
+       {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
+       {OP_WR, CCM_REG_CQM_P_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, CCM_REG_XX_DESCR_TABLE, 0x241aeb},
+       {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, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
+       {OP_WR, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
+       {OP_WR, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
+       {OP_WR, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
+       {OP_ZR, CCM_REG_QOS_PHYS_QNUM2_0, 0x4},
+       {OP_WR, CCM_REG_PHYS_QNUM1_0, 0xc},
+       {OP_WR, CCM_REG_PHYS_QNUM1_1, 0x2c},
+       {OP_WR, CCM_REG_PHYS_QNUM2_0, 0xb},
+       {OP_WR, CCM_REG_PHYS_QNUM2_1, 0x2b},
+       {OP_ZR, CCM_REG_PHYS_QNUM3_0, 0x2},
+       {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          373
+#define UCM_COMMON_START        373
+       {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_TSEM_WEIGHT, 0x3},
+       {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
+       {OP_WR, UCM_REG_CP_WEIGHT, 0x0},
+       {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x6},
+       {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, 0xc},
+       {OP_WR, UCM_REG_XX_MSG_NUM, 0x20},
+       {OP_ZR, UCM_REG_XX_TABLE, 0x12},
+       {OP_SW, UCM_REG_XX_DESCR_TABLE, 0x201b0f},
+       {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0xa},
+       {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, UCM_REG_N_SM_CTX_LD_4, 0x4},
+       {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
+       {OP_WR, UCM_REG_PHYS_QNUM0_0, 0xf},
+       {OP_WR, UCM_REG_PHYS_QNUM0_1, 0x2f},
+       {OP_WR, UCM_REG_PHYS_QNUM1_0, 0xe},
+       {OP_WR, 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          426
+#define USEM_COMMON_START       426
+       {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, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+       {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
+       {OP_WR, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x5000, 0x102},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1e20, 0x40},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x400},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x2410, 0x6},
+       {OP_SW, USEM_REG_FAST_MEMORY + 0x2410 + 0x18, 0x21b2f},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b68, 0x2},
+       {OP_SW, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x21b31},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b10, 0x2},
+       {OP_SW, USEM_REG_FAST_MEMORY + 0x2c30, 0x21b33},
+       {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
+       {OP_SW, USEM_REG_FAST_MEMORY + 0x10c00, 0x101b35},
+       {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
+       {OP_SW, USEM_REG_FAST_MEMORY + 0x10c40, 0x101b45},
+       {OP_ZP, USEM_REG_INT_TABLE, 0xb41b55},
+       {OP_ZP, USEM_REG_PRAM, 0x32d01b82},
+       {OP_ZP, USEM_REG_PRAM + 0x8000, 0x32172836},
+       {OP_ZP, USEM_REG_PRAM + 0x10000, 0x1a7a34bc},
+       {OP_ZP, USEM_REG_PRAM + 0x18000, 0x5f3b5b},
+       {OP_ZP, USEM_REG_PRAM + 0x20000, 0x5f3b73},
+       {OP_ZP, USEM_REG_PRAM + 0x28000, 0x5f3b8b},
+       {OP_ZP, USEM_REG_PRAM + 0x30000, 0x5f3ba3},
+       {OP_ZP, USEM_REG_PRAM + 0x38000, 0x5f3bbb},
+#define USEM_COMMON_END         498
+#define USEM_PORT0_START        498
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1900, 0xa},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1950, 0x2e},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d00, 0x24},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3200, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3300, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3400, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3500, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3600, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3700, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3800, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3900, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f00, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b78, 0x52},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e08, 0xc},
+#define USEM_PORT0_END          521
+#define USEM_PORT1_START        521
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1928, 0xa},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d90, 0x24},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3280, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3380, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3480, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3580, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3680, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3780, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3880, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3980, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f80, 0x20},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52},
+       {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e38, 0xc},
+#define USEM_PORT1_END          544
+#define CSEM_COMMON_START       544
+       {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, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
+       {OP_SW, CSEM_REG_FAST_MEMORY + 0x25c0 + 0x900, 0x83bd3},
+       {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
+       {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c00, 0x103bdb},
+       {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
+       {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c40, 0x103beb},
+       {OP_ZP, CSEM_REG_INT_TABLE, 0x5f3bfb},
+       {OP_ZP, CSEM_REG_PRAM, 0x32423c13},
+       {OP_ZP, CSEM_REG_PRAM + 0x8000, 0xf2148a4},
+       {OP_ZP, CSEM_REG_PRAM + 0x10000, 0x5f4c6d},
+       {OP_ZP, CSEM_REG_PRAM + 0x18000, 0x5f4c85},
+       {OP_ZP, CSEM_REG_PRAM + 0x20000, 0x5f4c9d},
+       {OP_ZP, CSEM_REG_PRAM + 0x28000, 0x5f4cb5},
+       {OP_ZP, CSEM_REG_PRAM + 0x30000, 0x5f4ccd},
+       {OP_ZP, CSEM_REG_PRAM + 0x38000, 0x5f4ce5},
+#define CSEM_COMMON_END         609
+#define CSEM_PORT0_START        609
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2300, 0x2},
+       {OP_SW, CSEM_REG_FAST_MEMORY + 0x2300 + 0x8, 0x24cfd},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
+#define CSEM_PORT0_END          616
+#define CSEM_PORT1_START        616
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2310, 0x2},
+       {OP_SW, CSEM_REG_FAST_MEMORY + 0x2310 + 0x8, 0x24cff},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
+       {OP_ZR, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
+#define CSEM_PORT1_END          623
+#define XPB_COMMON_START        623
+       {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
+#define XPB_COMMON_END          624
+#define DQ_COMMON_START         624
+       {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           642
+#define TIMERS_COMMON_START     642
+       {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, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
+       {OP_WR, TM_REG_TIMER_TICK_SIZE, 0x3d090},
+       {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       661
+#define TIMERS_PORT0_START      661
+       {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
+#define TIMERS_PORT0_END        662
+#define TIMERS_PORT1_START      662
+       {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
+#define TIMERS_PORT1_END        663
+#define XSDM_COMMON_START       663
+       {OP_WR, XSDM_REG_CFC_RSP_START_ADDR, 0xa14},
+       {OP_WR, XSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
+       {OP_WR, XSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
+       {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_ZR, XSDM_REG_AGG_INT_EVENT_2, 0x5e},
+       {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, XSDM_REG_TIMER_TICK, 0x3e8},
+#define XSDM_COMMON_END         694
+#define QM_COMMON_START         694
+       {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, QM_REG_QVOQIDX_21, 0x4},
+       {OP_WR, QM_REG_WRRWEIGHTS_5, 0x1010101},
+       {OP_ZR, QM_REG_QVOQIDX_25, 0x4},
+       {OP_WR, QM_REG_WRRWEIGHTS_6, 0x1010101},
+       {OP_ZR, QM_REG_QVOQIDX_29, 0x3},
+       {OP_WR, QM_REG_QVOQIDX_32, 0x1},
+       {OP_WR, QM_REG_WRRWEIGHTS_7, 0x1010101},
+       {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, QM_REG_QVOQIDX_54, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_55, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_56, 0x1},
+       {OP_WR, QM_REG_WRRWEIGHTS_13, 0x1010101},
+       {OP_WR, QM_REG_QVOQIDX_57, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_58, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_59, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_60, 0x1},
+       {OP_WR, QM_REG_WRRWEIGHTS_14, 0x1010101},
+       {OP_WR, QM_REG_QVOQIDX_61, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_62, 0x1},
+       {OP_WR, QM_REG_QVOQIDX_63, 0x1},
+       {OP_WR, QM_REG_WRRWEIGHTS_15, 0x1010101},
+       {OP_WR, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
+       {OP_ZR, QM_REG_VOQQMASK_0_MSB, 0x2},
+       {OP_WR, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
+       {OP_WR, QM_REG_VOQQMASK_2_LSB, 0x100},
+       {OP_WR, QM_REG_VOQQMASK_2_MSB, 0x100},
+       {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
+       {OP_WR, QM_REG_VOQQMASK_4_LSB, 0xc0},
+       {OP_WR, QM_REG_VOQQMASK_4_MSB, 0xc0},
+       {OP_WR, QM_REG_VOQQMASK_5_LSB, 0x1e00},
+       {OP_WR, QM_REG_VOQQMASK_5_MSB, 0x1e00},
+       {OP_WR, QM_REG_VOQQMASK_6_LSB, 0x4000},
+       {OP_WR, QM_REG_VOQQMASK_6_MSB, 0x4000},
+       {OP_WR, QM_REG_VOQQMASK_7_LSB, 0x8000},
+       {OP_WR, QM_REG_VOQQMASK_7_MSB, 0x8000},
+       {OP_WR, QM_REG_VOQQMASK_8_LSB, 0x2000},
+       {OP_WR, QM_REG_VOQQMASK_8_MSB, 0x2000},
+       {OP_ZR, QM_REG_VOQQMASK_9_LSB, 0x7},
+       {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, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
+       {OP_WR, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
+       {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, QM_REG_ENBYTECRD_LSB, 0x7},
+       {OP_WR, QM_REG_ENBYTECRD_MSB, 0x7},
+       {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
+       {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
+       {OP_WR, QM_REG_FUNCNUMSEL_LSB, 0x0},
+       {OP_WR, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
+       {OP_WR, QM_REG_CMINTEN, 0xff},
+#define QM_COMMON_END           829
+#define PBF_COMMON_START        829
+       {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          836
+#define PBF_PORT0_START         836
+       {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           840
+#define PBF_PORT1_START         840
+       {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           844
+#define XCM_COMMON_START        844
+       {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, 0x2},
+       {OP_WR, XCM_REG_TSEM_WEIGHT, 0x5},
+       {OP_WR, XCM_REG_CSEM_WEIGHT, 0x2},
+       {OP_WR, XCM_REG_USEM_WEIGHT, 0x2},
+       {OP_WR, XCM_REG_PBF_WEIGHT, 0x7},
+       {OP_WR, XCM_REG_NIG1_WEIGHT, 0x1},
+       {OP_WR, XCM_REG_CP_WEIGHT, 0x0},
+       {OP_WR, XCM_REG_XSDM_WEIGHT, 0x5},
+       {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3},
+       {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, XCM_REG_XX_MSG_NUM, 0x1f},
+       {OP_ZR, XCM_REG_XX_TABLE, 0x12},
+       {OP_SW, XCM_REG_XX_DESCR_TABLE, 0x1f4d01},
+       {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, XCM_REG_N_SM_CTX_LD_4, 0x4},
+       {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          904
+#define XCM_PORT0_START         904
+       {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
+       {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
+       {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
+       {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
+       {OP_WR, XCM_REG_WU_DA_CNT_CMD00, 0x2},
+       {OP_WR, XCM_REG_WU_DA_CNT_CMD10, 0x2},
+       {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
+       {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
+#define XCM_PORT0_END           912
+#define XCM_PORT1_START         912
+       {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
+       {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
+       {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
+       {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
+       {OP_WR, XCM_REG_WU_DA_CNT_CMD01, 0x2},
+       {OP_WR, XCM_REG_WU_DA_CNT_CMD11, 0x2},
+       {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
+       {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
+#define XCM_PORT1_END           920
+#define XSEM_COMMON_START       920
+       {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, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x55d8, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x48},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5128, 0x92},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x5378, 0x0},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x5380, 0x24d20},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x5428, 0x44d22},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x1820, 0x24d26},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad8, 0x24d28},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b08, 0x4},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x1f50, 0x24d2a},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c00, 0x104d2c},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c40, 0x84d3c},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c60, 0x84d44},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x3000000},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c80, 0x84d4c},
+       {OP_ZP, XSEM_REG_INT_TABLE, 0x814d54},
+       {OP_ZP, XSEM_REG_PRAM, 0x35774d75},
+       {OP_ZP, XSEM_REG_PRAM + 0x8000, 0x36525ad3},
+       {OP_ZP, XSEM_REG_PRAM + 0x10000, 0x27266868},
+       {OP_ZP, XSEM_REG_PRAM + 0x18000, 0x5e7232},
+       {OP_ZP, XSEM_REG_PRAM + 0x20000, 0x5e724a},
+       {OP_ZP, XSEM_REG_PRAM + 0x28000, 0x5e7262},
+       {OP_ZP, XSEM_REG_PRAM + 0x30000, 0x5e727a},
+       {OP_ZP, XSEM_REG_PRAM + 0x38000, 0x5e7292},
+#define XSEM_COMMON_END         1000
+#define XSEM_PORT0_START        1000
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5388, 0xc},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x5388 + 0x30, 0x272aa},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x55e0, 0x772ac},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5600, 0x7},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3020, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3030, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3000, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3010, 0x2},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x3040, 0x0},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3048, 0xc},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x3048 + 0x30, 0x272b3},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x30b8, 0x1},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x272b5},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b18, 0x42},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d28, 0x4},
+#define XSEM_PORT0_END          1019
+#define XSEM_PORT1_START        1019
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x53c0, 0xc},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x53c0 + 0x30, 0x272b7},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x5620, 0x772b9},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5640, 0x7},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3028, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3038, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3008, 0x2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3018, 0x2},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x3044, 0x0},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3080, 0xc},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x3080 + 0x30, 0x272c0},
+       {OP_WR, XSEM_REG_FAST_MEMORY + 0x30bc, 0x1},
+       {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x272c2},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4c20, 0x42},
+       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d38, 0x4},
+#define XSEM_PORT1_END          1038
+#define CDU_COMMON_START        1038
+       {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
+       {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
+       {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
+       {OP_WB, CDU_REG_L1TT, 0x20072c4},
+       {OP_WB, CDU_REG_MATT, 0x2074c4},
+       {OP_ZR, CDU_REG_MATT + 0x80, 0x20},
+#define CDU_COMMON_END          1044
+#define DMAE_COMMON_START       1044
+       {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
+       {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
+       {OP_WR, 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         1049
+#define PXP_COMMON_START        1049
+       {OP_SI, PXP_REG_HST_INBOUND_INT + 0x400, 0x574e4},
+       {OP_SI, PXP_REG_HST_INBOUND_INT + 0x420, 0x574e9},
+       {OP_SI, PXP_REG_HST_INBOUND_INT, 0x574ee},
+#define PXP_COMMON_END          1052
+#define CFC_COMMON_START        1052
+       {OP_WR, CFC_REG_CONTROL0, 0x10},
+       {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
+       {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
+#define CFC_COMMON_END          1055
+#define HC_COMMON_START         1055
+       {OP_ZR, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
+#define HC_COMMON_END           1056
+#define HC_PORT0_START          1056
+       {OP_WR, HC_REG_CONFIG_0, 0x1080},
+       {OP_ZR, HC_REG_UC_RAM_ADDR_0, 0x2},
+       {OP_WR, HC_REG_ATTN_NUM_P0, 0x10},
+       {OP_WR, HC_REG_LEADING_EDGE_0, 0xffff},
+       {OP_WR, HC_REG_TRAILING_EDGE_0, 0xffff},
+       {OP_WR, HC_REG_AGG_INT_0, 0x0},
+       {OP_WR, HC_REG_ATTN_IDX, 0x0},
+       {OP_ZR, HC_REG_ATTN_BIT, 0x2},
+       {OP_WR, HC_REG_VQID_0, 0x2b5},
+       {OP_WR, HC_REG_PCI_CONFIG_0, 0x0},
+       {OP_ZR, HC_REG_P0_PROD_CONS, 0x4a},
+       {OP_ZR, HC_REG_PBA_COMMAND, 0x2},
+       {OP_WR, HC_REG_INT_MASK, 0x1ffff},
+       {OP_WR, HC_REG_CONFIG_0, 0x1a82},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS, 0x24},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
+#define HC_PORT0_END            1074
+#define HC_PORT1_START          1074
+       {OP_WR, HC_REG_CONFIG_1, 0x1080},
+       {OP_ZR, HC_REG_UC_RAM_ADDR_1, 0x2},
+       {OP_WR, HC_REG_ATTN_NUM_P1, 0x10},
+       {OP_WR, HC_REG_LEADING_EDGE_1, 0xffff},
+       {OP_WR, HC_REG_TRAILING_EDGE_1, 0xffff},
+       {OP_WR, HC_REG_AGG_INT_1, 0x0},
+       {OP_WR, HC_REG_ATTN_IDX + 0x4, 0x0},
+       {OP_ZR, HC_REG_ATTN_BIT + 0x8, 0x2},
+       {OP_WR, HC_REG_VQID_1, 0x2b5},
+       {OP_WR, HC_REG_PCI_CONFIG_1, 0x0},
+       {OP_ZR, HC_REG_P1_PROD_CONS, 0x4a},
+       {OP_ZR, HC_REG_PBA_COMMAND + 0x8, 0x2},
+       {OP_WR, HC_REG_INT_MASK + 0x4, 0x1ffff},
+       {OP_WR, HC_REG_CONFIG_1, 0x1a82},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
+       {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
+#define HC_PORT1_END            1092
+#define PXP2_COMMON_START       1092
+       {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38324},
+       {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
+       {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, 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, 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, PXP2_REG_PGL_INT_XSDM_0, 0xffff5330},
+       {OP_WR, PXP2_REG_PGL_INT_XSDM_1, 0xffff5348},
+       {OP_WR, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
+       {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_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, PXP2_REG_RQ_RBC_DONE, 0x1},
+#define PXP2_COMMON_END         1200
+#define MISC_AEU_COMMON_START   1200
+       {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
+#define MISC_AEU_COMMON_END     1201
+#define MISC_AEU_PORT0_START    1201
+       {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
+       {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
+       {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
+       {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, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
+       {OP_WR, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
+       {OP_WR, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
+       {OP_WR, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
+       {OP_WR, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
+       {OP_WR, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
+       {OP_WR, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
+       {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
+       {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
+       {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
+#define MISC_AEU_PORT0_END      1221
+#define MISC_AEU_PORT1_START    1221
+       {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
+       {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
+       {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
+       {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, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
+       {OP_WR, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
+       {OP_WR, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
+       {OP_WR, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
+       {OP_WR, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
+       {OP_WR, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
+       {OP_WR, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
+       {OP_WR, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
+       {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
+       {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
+       {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7}
+#define MISC_AEU_PORT1_END      1241
+};
+
+static const u32 init_data[] = {
+       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, 0x00088b1f, 0x00000000,
+       0x51fbff00, 0x03f0c0cf, 0x3130ef8a, 0x22b1c430, 0x3b0143f8, 0x02ecdd01,
+       0xdc406ec4, 0x19b7c404, 0x23dfd348, 0xf1476080, 0x03343031, 0x032f3731,
+       0x423f2483, 0x4d5011fc, 0x02ef9025, 0xa40cdb15, 0x77280475, 0xf2c060fb,
+       0x77629812, 0x056c1144, 0x58c8f22c, 0x4dde4d11, 0x44af950c, 0xe340ff40,
+       0xfca8b235, 0x6d081948, 0x8b5f150b, 0x95051f26, 0xd0849577, 0xe76964eb,
+       0x00607a36, 0x2726b9d6, 0x00000400, 0x00088b1f, 0x00000000, 0x7dedff00,
+       0xd554780b, 0x333ef0b5, 0x64ccce67, 0x093c991e, 0x20f264af, 0xf09c0682,
+       0x93a8a808, 0x07be3040, 0x0e22a5e4, 0x27902018, 0xf5e8bd48, 0x620c19bf,
+       0x2f06d6b4, 0x93a45a2a, 0xb6968a80, 0x6c1a06c1, 0x822203b4, 0x6b06f5bf,
+       0x368b6d7b, 0x2062a28a, 0xa5ebd8b9, 0xaffadaf7, 0x99def6b5, 0x91332673,
+       0xfebffdaa, 0x5fa7f7df, 0xf7b3ecdd, 0xf5ed7bd9, 0xb3ef6b5e, 0xa66e6547,
+       0x97d8ce5d, 0x9be507f8, 0x232c630a, 0xa1bbd65a, 0xed58cc9c, 0x9ef8731e,
+       0xec66c65c, 0x4f2e44b1, 0x12ab7a87, 0xf4dd42b6, 0x4fda9d92, 0x7af5e56f,
+       0x9743f773, 0xb9fb3b40, 0x05053d99, 0x589bb1eb, 0x6c276309, 0xf2f5ff8c,
+       0xaf3b72fa, 0x5feeb6d6, 0x557fa0cc, 0xe1d995a7, 0x661d13fd, 0x3cd7d63f,
+       0xc01984a5, 0x3eefbb50, 0xbf8c046d, 0xdbb4ac22, 0x0a7f50bd, 0xcafb421e,
+       0xfb18730e, 0x33bbb9f7, 0x4ec64e03, 0x5798da36, 0x937ef843, 0xd8c453d9,
+       0x59eef0aa, 0xaadfa023, 0x04cf8a5d, 0xaadaacf3, 0x8c9f2e44, 0x19b095cf,
+       0xe9dea886, 0x1cb1de60, 0xcd192f86, 0xf358eb4b, 0xe30bcc24, 0x0b45b532,
+       0x4dbe70b8, 0xc515d79a, 0x0f46c9cf, 0xb5eb23cd, 0xf03cc2cf, 0x144fdd5e,
+       0xceb12e1f, 0x30ed82c4, 0xf67de9ff, 0xb89ddb85, 0xa15af5be, 0x258ebf4b,
+       0xab1d717b, 0x2cdaadc2, 0xaad5c227, 0x8e8a2f2d, 0xcd33bd57, 0xfc96d708,
+       0x7b5d4161, 0x91b2796c, 0xb4616f31, 0x7f318abe, 0x0fe113bb, 0x47c7b36b,
+       0x29641f9f, 0x9deacf44, 0x45b5e666, 0x442c67c7, 0x17cccdcf, 0x2eb2bc41,
+       0xb74f4f97, 0xdd231e33, 0x7788a4d6, 0x7df3c013, 0x024d8741, 0xf843df4f,
+       0x7bf64ca0, 0xfeb0abd6, 0xa3cc99e4, 0x26fef10c, 0x1ed85b0b, 0x900bbd67,
+       0x1630a619, 0xb7822664, 0xc26f058e, 0x50d4cfb2, 0x5fc3c005, 0xeb002b24,
+       0xefe14fbd, 0xd4bccf5f, 0x9ad1beff, 0xe9bae91f, 0xe6ed92ca, 0x7496b15c,
+       0xfa7f2fac, 0xb5321801, 0xbf10cfc2, 0x88ade22a, 0x43321e16, 0xca576bbb,
+       0x7abc07c4, 0xc72d95fc, 0x4d93dcf9, 0xa678fa06, 0xa9ea1927, 0xf0635333,
+       0xb89cf4eb, 0x4e01d440, 0x827fa9ab, 0x6958cf9a, 0xedf88db6, 0xe48d6c8e,
+       0x38cb8ee6, 0x3b64775c, 0x7fa821c3, 0x08b85f17, 0x42f05aea, 0xc07c1c4f,
+       0x859626cc, 0xa6c4d065, 0x466f6e0d, 0x941f023c, 0xf8517ce5, 0xa6f5941e,
+       0x2814c2fe, 0x21a52b57, 0xc446cbc4, 0x330e9423, 0x3b75c06b, 0xd4f08cac,
+       0x7b64a63c, 0xfba78748, 0xb94f0173, 0xb7ef71d1, 0x1f316434, 0xca840f63,
+       0xc070ea43, 0xf7102e6f, 0x3cb78462, 0xf7802a12, 0x42c8ef73, 0x9034da7c,
+       0x1afcfd03, 0xf3445fcc, 0x1f1e20b7, 0x9d8c7415, 0xcd3856df, 0xaf3dbf30,
+       0x5dbf30ca, 0x2781f983, 0x2b5d089f, 0x8e3c07e6, 0xec07ec60, 0x96df9a5a,
+       0x6fe68eb7, 0x619558d6, 0xf981a4fe, 0xd3ef38c3, 0x2e6fe609, 0xfeb8d8bc,
+       0xf5c655bc, 0xcffd7c6b, 0xf989e685, 0x3ffd6893, 0xfaf8f362, 0xebe2eef3,
+       0xfab8c2b7, 0xf803ddf9, 0xefbc476f, 0xdb7f804d, 0xeb8dd379, 0xae31afcf,
+       0x7fe7cadf, 0x988b7421, 0xfff349df, 0xd7c2dd82, 0xcd377f9f, 0xf836b56f,
+       0xcd64d03c, 0x23086a49, 0x7fe17b5f, 0x802ca0c3, 0x5942a679, 0xbc18ca94,
+       0x47961dff, 0x2923b878, 0xfff61e78, 0xcdf8093c, 0x2c0bd519, 0xb94151bc,
+       0x5d3c13af, 0xf6896bb9, 0xb2a5783d, 0x064beb93, 0xc00c74fa, 0xb3f3ba77,
+       0xf000ffcf, 0xf628ee56, 0x8f24bd99, 0x265bdf0c, 0xe66f5296, 0x902c60f8,
+       0xfa85db3d, 0x673d9029, 0x59f9353c, 0x4645e826, 0xe3e20e30, 0x13962d65,
+       0x5af93a3d, 0x5f58c5b1, 0x25d63619, 0x24c8a5dc, 0xd8ca8650, 0xf79806d8,
+       0x0623e804, 0xd07df27a, 0x647e5847, 0xdda2b761, 0x15f400f8, 0xb572f4d3,
+       0x4272e89e, 0xb13ff8e5, 0xf8f241c5, 0x1ad5a6f9, 0x1c7847cb, 0x7cdd6480,
+       0x1156f621, 0x58be73ac, 0x04b9e127, 0xcf5f15f5, 0x6bdaaefc, 0xdc02c4c0,
+       0x4ef78669, 0xd416225b, 0xf0b0b75b, 0xfe3059bd, 0xb6ee0f6d, 0xf8ff4904,
+       0xae489a47, 0xc81348d9, 0x968582f5, 0xef747bf7, 0x64d8ec2d, 0x8de50919,
+       0x9bf3e341, 0xd3f58cab, 0x84c5b096, 0xc2a57976, 0x5bfc615a, 0x72ed8c1a,
+       0x54b13f9e, 0xdf31674e, 0xf0c5a07c, 0x06575c54, 0xe1e82fd1, 0x3ebb00eb,
+       0x87da246b, 0x53df14db, 0xfb05bf50, 0x1e3a444d, 0xe2f9f0d6, 0x07be2965,
+       0x997860d8, 0xdf40930a, 0x78dd8577, 0x743cb557, 0xfe183291, 0x7e1c979e,
+       0xebc184d3, 0x56fb8588, 0xdc3a21e6, 0x7cf8ceba, 0x7d762849, 0x3bea0f9c,
+       0xd03ed34b, 0xbf6daf3d, 0x1d03ed32, 0x9cef54bf, 0x0cafa86d, 0xbfe868df,
+       0x4312cb62, 0x9596b2fb, 0x9adbf686, 0x4bea1b57, 0xfa1a7742, 0xbd6ebadf,
+       0x8696fda1, 0x37ed0dfb, 0xd4326d57, 0x6e3e0c6f, 0x6160bfe8, 0x795da1ab,
+       0xfa0e6569, 0x305af537, 0xfde03867, 0xacacefd4, 0xb1f2894d, 0x1b8ff3e4,
+       0xd93ca8b3, 0x3d72a5e8, 0xbfc82bca, 0xeb2f1f69, 0xa0e496db, 0xffbe4b9c,
+       0x8d90d2c8, 0xdfcb1272, 0xcb18f2b1, 0x6837c8c7, 0xf3d91287, 0x5005851a,
+       0x6e14fbee, 0x77f3e48f, 0xec65fe84, 0x1ab7921e, 0xcd63cb8d, 0x50cbc3f3,
+       0x48b46a5e, 0xf1338361, 0xa15dacb8, 0x46d63075, 0x830cace3, 0x9ae81854,
+       0x77b3806f, 0xafe699bf, 0x22e3e743, 0x2581f7b4, 0x791fce0a, 0xf186fb39,
+       0x297f8f08, 0x48333bd5, 0x5636f62f, 0x22a07da4, 0x7e5402fe, 0xca90b8dc,
+       0x2a418d13, 0xa2ac683f, 0x06c6fdf2, 0xd71a7b2a, 0x636ef951, 0x8d63ca88,
+       0xbefe54cd, 0xb7ca85b1, 0xf950b71b, 0x9530c6db, 0x54fd1ba7, 0xb5a9f00e,
+       0x43fd10bf, 0x432b07f6, 0x0ebd9717, 0xcdc816fe, 0x7737e919, 0xe11afaf2,
+       0x4bc22737, 0xe213dd2c, 0x434c858f, 0x89292dd1, 0xc4c923d3, 0xf9c8182a,
+       0xfaf6e303, 0x8abaf296, 0xe008032a, 0x0397fbd3, 0x860d22e3, 0xde3d357d,
+       0xf683bb41, 0xd93365ef, 0x99f9163f, 0x1e9706ef, 0xd423401f, 0x8474bf37,
+       0x35fd029f, 0x7e72f14a, 0x9cbc0af9, 0x8dddbc39, 0x964d747a, 0xa4c1f3c9,
+       0x6dabebc4, 0x7538f5cf, 0x1a77d4f0, 0x945a67eb, 0x7a0fee0a, 0x478ee793,
+       0x3e78f07e, 0x65ba4028, 0x59c72951, 0x3e79a593, 0x617ec348, 0x95db0f5a,
+       0xf105fc42, 0xb6fbf508, 0x4e3448e1, 0x760e8e14, 0x1f27de1c, 0xff713f3b,
+       0xfea17c84, 0x9a3f4349, 0x473e5975, 0xff856abb, 0x1401897f, 0xc72ea953,
+       0x87376fad, 0xf3e217ac, 0xe0f9865d, 0xf58caf3d, 0x8a1bccbe, 0x427654ff,
+       0xa4a807f2, 0xacde22a3, 0x18f769de, 0xa18a75f5, 0xdc39df5e, 0xf8dfd063,
+       0x3657900f, 0x5ed15153, 0xe8b608d5, 0x0acd9d53, 0xf90bb7c0, 0xaf52e806,
+       0xb6b57ef0, 0x8f082d1e, 0xcd3474ce, 0x3d8bc4bf, 0xb1bd685b, 0x3c6c9df0,
+       0xc4d555ec, 0xcf9b57f0, 0xe38811dc, 0xf0ae7f97, 0xc4c6a538, 0x0b665ffd,
+       0x584e51b9, 0x873dc856, 0x07399bf8, 0x0b7143f0, 0xcbaba3cc, 0xe9afc071,
+       0x7acf678f, 0x8dafdc4d, 0x526ad79d, 0x757f09ce, 0xc2ce8ebb, 0xb1e2c775,
+       0xb43ff3ae, 0xcc8dc520, 0xdf894780, 0x6ac04a5d, 0xed57f182, 0xf9434f7c,
+       0x2a12d8fa, 0xc4dce7fc, 0xbf0c19f8, 0x2384eb33, 0x7b35ceba, 0xad5fe45c,
+       0xede224d9, 0x79c6eb10, 0x13134e97, 0x74bd017f, 0x62e58070, 0x26dfa826,
+       0x5dee326a, 0xfe4d51da, 0xa42c87d5, 0x89f53fa1, 0xfd04a5b9, 0xaded5583,
+       0x3ce01f9a, 0x88154cc5, 0x4dec53af, 0xbd1d24f7, 0xd11a4c8a, 0xa366b6e9,
+       0xa6fe00df, 0xa6fe0ea1, 0xcd9cbea1, 0x7638c4c9, 0xb80b66f9, 0x434eb4be,
+       0x879328fb, 0x3582b0e8, 0x7afb446c, 0xfcd263bc, 0x3f0e904b, 0xf104b27f,
+       0x479a14bb, 0x8f1e22a6, 0xd6ff1e12, 0xfbe257f9, 0x1bcf0713, 0x7c98dbe5,
+       0xed43c080, 0x8e1fc54e, 0x991737c3, 0xfe4abf38, 0x4ff080da, 0x2dcdfa89,
+       0x4d6bf531, 0x6b724a8a, 0xe3a46666, 0x642d8f29, 0x5f76a64a, 0x7a12f004,
+       0x026beade, 0x12a3fafe, 0xbb226d98, 0x74c0991e, 0x04a8fefd, 0xf2af79e9,
+       0x013472fa, 0xc04c8d4c, 0x06d80b3c, 0xd04d3be2, 0x60f08ad7, 0x1aa59cbc,
+       0x728f59d6, 0x9dd8e30d, 0xb7df0c1d, 0xf1da637b, 0xc637681f, 0x8e1bb232,
+       0x2776c6b1, 0x87f219b0, 0xbe7c67cb, 0x180fc842, 0x4c3be222, 0xebdfa17b,
+       0x662339b6, 0x34d94bf0, 0xce2077b5, 0xc878c3c8, 0xfe91813d, 0x645e52f3,
+       0xaff787ad, 0xb5847913, 0x4b0d94ef, 0xa97fc21d, 0x84b61b3f, 0xb57574d3,
+       0xa97e435f, 0x12c3bb3f, 0xf40df49e, 0x989617a0, 0x279b9519, 0xca236094,
+       0xd49bc4ad, 0x3c3d517f, 0xcb97a3ca, 0xfef431ad, 0x03a470da, 0xec70753d,
+       0x482d8252, 0xbe3858f7, 0x8359f8f6, 0xadfadfc6, 0x68305f8e, 0xf0f19dfc,
+       0x631c7a78, 0x0337a4dd, 0xfee80cc9, 0xa8f3dd9f, 0x8ff7444c, 0x85233e41,
+       0x58f84fe8, 0x4b79e344, 0xb8f8cbac, 0x59e5ebaa, 0x81575718, 0xfe05eb7f,
+       0x485ac95d, 0x294c448f, 0xb335cfc2, 0x55de0e88, 0xfea6bf5d, 0xff783aab,
+       0xfd4ed66a, 0x3119bf31, 0xe1927bac, 0x7def293d, 0x9cd49ec2, 0x1d11612d,
+       0x790b763f, 0xe087bf00, 0x106bcf93, 0xb26bcc3e, 0xb6a79a6e, 0xcf30cd3d,
+       0xf6735f80, 0xf9d11662, 0x376ab53d, 0xd9ed77f1, 0x019e68cb, 0x6afe067b,
+       0xfc6a1b44, 0xa3b80691, 0xc0334fe3, 0x3a7f1d1b, 0xcfc72bcd, 0xca72039a,
+       0x2be513f5, 0xc293cb42, 0xb7a7804d, 0x91f7c1ac, 0x9b5cb25f, 0x76415f73,
+       0x04f1fa5a, 0x744fc7d4, 0x1d34df6c, 0xea09fae8, 0x9b975c39, 0x739eb9b9,
+       0x92174c86, 0x7c853afe, 0x18bfa030, 0x43f1afe8, 0xb7e8c7b4, 0x8c0af851,
+       0x28f59a3f, 0x3746dfa8, 0x8e50f518, 0xef84dd33, 0x3e33ace5, 0x019ea2f7,
+       0x521b95bd, 0x9f5ce263, 0x6fcfc709, 0x9f4f3e36, 0xc73aba51, 0xd3516e07,
+       0x2798a533, 0xba505f4a, 0xb187a47b, 0x7957d40b, 0xe2d299fd, 0x79ff50e1,
+       0x1532bad3, 0x7ff4d5fc, 0x86ce2d2b, 0x91b2d3ba, 0xca15abd7, 0xb7cc592b,
+       0x89be8594, 0xcac0081e, 0x6294728d, 0x0a9cfc06, 0xccbf9b1c, 0x5fb47a8b,
+       0x9e8478e3, 0xd3d19f80, 0x39467e38, 0xfc46ed8f, 0xd67a98e4, 0xc3f973a3,
+       0x052bff17, 0xe62f4643, 0x1e0f013d, 0xf483c1b6, 0xbed34781, 0x8ebfc21c,
+       0x5f2533f5, 0xf305b14c, 0x4b938e10, 0x167f7ec7, 0xeaa27d3c, 0x5b0dc500,
+       0x71f9fe44, 0xf46eb710, 0x326f55bb, 0x3364e3f2, 0x0965d7cf, 0x378ceebf,
+       0xfd487937, 0xa195959e, 0x53eae0ea, 0x9fc8ddfb, 0x5f1c5f7d, 0xd6237e8c,
+       0x13d08653, 0x32a359f5, 0xa3139254, 0x749e667e, 0xc14aa3e2, 0x5b378847,
+       0xb6cf3466, 0x7e510942, 0xc0b5fa44, 0xbf5c1e01, 0x7f31aa12, 0x8edfc179,
+       0xe0d6e3a7, 0x775866d5, 0x83c85985, 0xbdb0b98b, 0xf08f2ab7, 0xf6836e96,
+       0x6b3d688c, 0xe809cee9, 0x0398a4e7, 0xc37be2d7, 0xc6cd9f97, 0x43d98e7a,
+       0xb4a2dbf8, 0x00f8470c, 0xc3cfb48f, 0x569d82f6, 0xdcc93168, 0xcf26f64f,
+       0x69ce2219, 0x1f4acc6b, 0x55cf2fca, 0xde718b83, 0xf7bebdfc, 0xf1fc619b,
+       0xf70f9a95, 0x9bafc65b, 0xccf88e99, 0xc03d7132, 0x72f390ee, 0xf82f5f3d,
+       0xf8aacfae, 0x77ded0fd, 0x8435a7bb, 0xda0b33ed, 0xb519afd1, 0xfdc3ebce,
+       0x42873e80, 0x7a35f7ef, 0xe7282f29, 0x1c95dd1d, 0x9e49bbb1, 0xf3c8373f,
+       0xd07d633a, 0x3b7a5f7c, 0x7fbc707b, 0x9c42f8f6, 0x1d0f949e, 0x67d9e82d,
+       0x725dfbe6, 0xb42cd1be, 0x7391fd1f, 0xcc5fef9d, 0x7fda74ae, 0xba037410,
+       0x925e9084, 0xfbdf402e, 0x121b5f10, 0x78bef7d3, 0x6b6e5df4, 0x5db946c8,
+       0x659f6815, 0xe625e781, 0xafd883e0, 0x21f76166, 0x50decd0b, 0xe927fc88,
+       0x70d0d4ce, 0x740353d4, 0xfc21497f, 0x7c717667, 0xb7361fd6, 0xcb1e7ee2,
+       0x40b7ae0a, 0x42ca99fb, 0xa22627ca, 0xfe75f8f3, 0x017cbd74, 0xfce2b7dd,
+       0x9a8ebbe3, 0xef493e10, 0x49de44c7, 0xffecadca, 0xbdfa598c, 0x0f76be62,
+       0xfc55f7cd, 0x166eb457, 0x7c780b8d, 0x80dfcf56, 0xff9c76c7, 0x1fe166c7,
+       0x3b63c60f, 0x3c073ff6, 0x3c1739ee, 0x939de87e, 0xcfe30799, 0x7f093b32,
+       0x87329f2b, 0xbea4b0ad, 0xf52fd2d9, 0x333c335f, 0x5e5627aa, 0xd71fb0d4,
+       0x8549f2b9, 0x6bb2acf8, 0xc26c35c5, 0xf96378e0, 0xe3e910c2, 0xd903b8d8,
+       0x5ab2f912, 0x7f13178e, 0xff07b354, 0x734e4cc3, 0xf54ef498, 0xbffb634e,
+       0x9b30f945, 0x24ce04f2, 0xf1b1b79e, 0xf1d0b2f1, 0xe248be47, 0x8b26717c,
+       0x619e1c91, 0xd0f7c429, 0xbb608bee, 0x33fca2e6, 0xdc6291db, 0x314cac9f,
+       0x6e8e4fec, 0x4ff21930, 0xc9b1f3b1, 0x5fec4cca, 0x6730e42a, 0x6fb0c99d,
+       0xee321b97, 0xa737e5eb, 0x5a63ea1a, 0x9ffa1846, 0xd0cf25b7, 0xbe7c2e3e,
+       0x9d82fda1, 0xf1f50d13, 0xfa1b17ed, 0x6659d85f, 0xae4717a8, 0x749ff432,
+       0x3ea18e78, 0x4326fba5, 0x2f6fa9ff, 0xd45fb435, 0x7ed0cab3, 0x0c6bc7c9,
+       0xeffb4bf5, 0x2c8ff432, 0x00ac38a9, 0xff025efd, 0xe086f314, 0x67c8a857,
+       0x99acfe07, 0xfc0e4f90, 0xa8c4d0b9, 0x2bc867dd, 0xa673f81e, 0xf81f9f1f,
+       0xfb1f8973, 0xe7cb3295, 0x5952e2f1, 0xdb19b0ce, 0x0be05553, 0xc0d96fb4,
+       0x569a9817, 0x7203f28d, 0x39454235, 0x0fc3a7fb, 0x469d0215, 0x46482cac,
+       0x34f20d3b, 0xbd373d42, 0x27ef8394, 0x962da792, 0x290f1b96, 0xac7ded83,
+       0x38e590be, 0x5bade655, 0xbad37de8, 0x65a7616c, 0xb230f17d, 0x5f9f9233,
+       0x7a1c5333, 0xe3d70366, 0x86a43667, 0xdf9efef9, 0x0fe75c39, 0x24e8399e,
+       0x9efdcefe, 0xaf01db93, 0x892cebd3, 0x7f2901da, 0x323f22f9, 0x7945582a,
+       0xe3fe418f, 0xb8f59ea2, 0x1ff573ce, 0x99c6fd63, 0xff021e92, 0x05d1d709,
+       0xf1f68972, 0x27da1483, 0x7161e35a, 0x36b6eff7, 0x16770f36, 0x4b2e7e0c,
+       0xdce1cd65, 0xb40f30fb, 0xe159f14f, 0x1fd86dfd, 0xbc587bec, 0xb5ea26d7,
+       0xbd454d21, 0xebe22b56, 0x521e71d8, 0x7e466f4b, 0xdd96a1d8, 0xc5d14eac,
+       0xdc5a0dd3, 0xd077c7bc, 0x0473c089, 0x0d80efaa, 0xcf5fefe6, 0xff306d7c,
+       0x0ca78b1a, 0xf4ee6beb, 0x9af21d12, 0x7ae1667b, 0x5dc13a73, 0x73fbd9d7,
+       0xc056a780, 0xd4f08b53, 0xa714fda9, 0xb0a8bff5, 0x879c5cb6, 0x5f66bb8f,
+       0x487e432e, 0xd51ce704, 0x72057c42, 0x738e3770, 0x4ed09aa7, 0xf28e7ddf,
+       0x638d5eb0, 0xf2ec065f, 0xf15bed52, 0x137072c7, 0x9eb44a78, 0xe196d0ff,
+       0x9d39b728, 0xc0a89fa5, 0x60e039b7, 0x9f22a726, 0xd1bef632, 0xebef623f,
+       0xf344d0fc, 0x7689557e, 0xf1157def, 0x0631f7ce, 0xc7231dc1, 0xe46f75de,
+       0xebe9a417, 0x4c17e7af, 0x10950012, 0x306c14bc, 0xe5e2db88, 0x95f6738b,
+       0x2427561e, 0xbdefe786, 0x377881ce, 0x4bfd5e46, 0x7c8f5ec7, 0xb311fb77,
+       0xb2845562, 0xc84178c1, 0xe677b2eb, 0xf0e8a664, 0xe5b1b5b3, 0xaf27556a,
+       0xf7f012a3, 0x9ff72a9b, 0x5c3635b6, 0xe380595d, 0x3d7a4c7a, 0xca13dd90,
+       0xd27988dd, 0x8c2f870e, 0x9327acfa, 0x702b58f0, 0xbe0a6c90, 0xf4bcfc89,
+       0xd7ca6ec2, 0xe97c88e6, 0x297e7168, 0x2ae3be76, 0x97f847cf, 0x8c2958da,
+       0x16cda7fb, 0x34b277f2, 0x08e28798, 0x5a5b9d07, 0x0a6c0636, 0x93db2fb4,
+       0x0c53f5c6, 0xd0c6e15c, 0xa20a1bd5, 0xc71c02f3, 0x3dbc1e51, 0x7f3859c1,
+       0x4451c22e, 0xe11276f2, 0xe84d48fb, 0x473c9dcf, 0xd21beb79, 0x43c6c4fe,
+       0xf0e2fd09, 0xa7e485fd, 0x7e4dffe6, 0xa1c3fa31, 0x0c3fa8a2, 0xd058b2eb,
+       0xeb8c594e, 0x8b55d9d2, 0x95d6dce5, 0xaeda1964, 0x92416e3e, 0x32407389,
+       0x9ae1230f, 0x57f2e169, 0xe618d1ef, 0x4e51ead3, 0x54d9f0e3, 0xbb88628b,
+       0x3138adbf, 0xede6553f, 0x7887bda4, 0xe5c2e311, 0x33a3e24e, 0x0bfbd6de,
+       0x877c7327, 0xc8f7c086, 0x04322375, 0x0f887d5e, 0x16f1c789, 0xbc069ea3,
+       0xb5e2e2fa, 0x326af006, 0x57ca75e0, 0x95fc95e0, 0xa98f9daf, 0x9cefee34,
+       0xa5dff816, 0xde703304, 0x5bbc3753, 0xbab0f982, 0x086b9f79, 0x679ed7d7,
+       0xe7e9b32e, 0x981ef991, 0x9cf383c7, 0x9aafe1be, 0xe825a7d0, 0x39ed3667,
+       0x35cf192f, 0x93f38ad4, 0xfd5af6a7, 0x3e5f8e8a, 0x1e70f2fd, 0x1b4fa5ea,
+       0xf2c7ccaf, 0x5bcf2a54, 0xf53bda9e, 0xa9d5f210, 0xb12d1c9f, 0x9ea738c0,
+       0xd2a25a3f, 0x60d85b3e, 0xef2f6a7f, 0x203b412e, 0x7c03daf3, 0xdfaf8b67,
+       0xfcfe0b56, 0x4aafebda, 0xc8d5e788, 0xef1ca707, 0xebfae096, 0x0f09675c,
+       0x7cb9db0f, 0x6da1923c, 0xd32332c4, 0x17fa10f4, 0x4fc1a45a, 0x5b8788db,
+       0x75265822, 0x7971fbb7, 0x23bbb7ce, 0xfa7bba58, 0xbd7618fd, 0xe201fe05,
+       0x67b1f3d5, 0xbe1fd63f, 0x33e504f2, 0x1ab017d9, 0x80916380, 0x3b59f7e3,
+       0x3a04a91e, 0xf37d2efc, 0x7e86e423, 0xf685eb01, 0xa0dff19b, 0x1e818e87,
+       0xdc6c80f2, 0x7cfb72a4, 0xb512a553, 0x191ff853, 0xe9187947, 0x8a3545d3,
+       0xeea5aec1, 0xd3f94199, 0x6429af3e, 0x61a47581, 0xbff81a56, 0x66ceeb4f,
+       0xc5cec0df, 0x3883bf96, 0x9d9d7de5, 0x0952acfa, 0x67df30a9, 0x7fac8f42,
+       0xd3f1127d, 0x178a65e6, 0xfefb18f1, 0xcb5eeb63, 0x727a099f, 0xf3879dd8,
+       0x6efc8267, 0x90027916, 0xa7cf0537, 0x80f22c3d, 0x877b866b, 0x9ae3ede9,
+       0x8252f323, 0x46defaba, 0x89d6dfbe, 0x7ca15ee7, 0xed7b9c41, 0xfaa2cc6a,
+       0x2a5e8d4b, 0xe9638d23, 0x434b66f9, 0x7bdf9e0a, 0x3342c2cd, 0x77bf97c1,
+       0xe51bff78, 0x1ddb42e0, 0x699b2fbf, 0x33d6f187, 0xd6f8cf3a, 0x13ddefbd,
+       0x1df00e9a, 0x1929a4f8, 0xd2a740ed, 0xa61c478e, 0x23fdbe2a, 0xcb5d4f51,
+       0x75a54f48, 0x306e742a, 0x3611cbad, 0xb7d3fce9, 0x765edc2c, 0x72de785b,
+       0xb442da2a, 0x7fa5b32f, 0xef413fd7, 0x0fea0cc7, 0x7b9e1f81, 0xa98f9d8e,
+       0x4ecf94fd, 0x7c30def4, 0xbfb9fc6f, 0xad4c77d7, 0x2a89f3a0, 0x66a77fb7,
+       0x903eb667, 0xcfebfbcb, 0x79e1f497, 0xfa7238ce, 0xbdef3117, 0xc7f74e16,
+       0x64768d72, 0x8fdb9597, 0x1df316ff, 0xa392dc68, 0x9651bf3f, 0xffe8dfc0,
+       0x335ff2a6, 0xe488ff68, 0x68f596be, 0x3f72bcfc, 0x11fc49e5, 0x3619af8e,
+       0x577d470e, 0xca04b2b1, 0x97ae4e19, 0xe50eb0d2, 0xeb9c550c, 0x689cfc66,
+       0x2b56455a, 0xe28e5f9e, 0x5a73af81, 0x1c16bf4f, 0x7dc3dfcf, 0x7c0fb4df,
+       0x29ebf20a, 0x7fee39a4, 0xfd11b6cc, 0xaa825b67, 0xbc52f486, 0x9d22578f,
+       0x3a238cf6, 0xec958fd9, 0x5c3a464f, 0xde4cf2cb, 0x2dec1f28, 0x9c627a05,
+       0xb6f14fb4, 0xa73ee8b1, 0xe340bf9c, 0x23e595f8, 0xc877e04a, 0xea5a05e7,
+       0x784fdc0c, 0x82581ec4, 0x7e113247, 0x678c165b, 0x478cde0f, 0x5debedd2,
+       0xf4e0154d, 0x3b40b5ed, 0xba360bd4, 0xfe00369b, 0x4704a6f6, 0x6b9796e2,
+       0x30e9a3bd, 0xb970a7b6, 0x68e8d828, 0xd1c8b942, 0xe61f3c3c, 0x5f22e7f4,
+       0x503dd40d, 0xdbabaf1f, 0xaf2aea62, 0xbed575cb, 0xc843e7fc, 0x5c5d75a7,
+       0xd6f006be, 0xfea0ac59, 0x7e135f3c, 0xf4398392, 0x547fddfb, 0xbe341382,
+       0xedc85d8f, 0x4a07dc98, 0x81f62ed0, 0x828b58b2, 0x1e04767a, 0xff47cb60,
+       0x6cca9bba, 0xdca54fd6, 0x59dbc8df, 0xea04607c, 0x76605353, 0x35e7d239,
+       0x18f7970b, 0x72b1efbc, 0x2d6bdd3e, 0xf985659d, 0x63d01e1e, 0x46ba5f7c,
+       0x81b669e8, 0xc15eedeb, 0x9b369fbb, 0xc9c01a42, 0x79e83876, 0x553f388d,
+       0x4c81cef3, 0xd4f8d7dc, 0xc9e22acf, 0x7b085cc5, 0x5b5f8f11, 0xb946822e,
+       0xef907fa8, 0xcc7c819b, 0x21d57c45, 0xd937505c, 0x847ce9ba, 0x87f69ee5,
+       0xff3718cc, 0x73c1e2d8, 0xbeb9d58e, 0xa2fe78fd, 0x0fae5f7a, 0xc3bde555,
+       0x9d577c79, 0xd1399ed2, 0xbacbe519, 0x21d94dce, 0xfb27f7c0, 0x95f2477f,
+       0x61ec878f, 0xa38edafc, 0xd79e105a, 0xa1a7bc75, 0x4524fd61, 0xda3e81fa,
+       0xb877bdb7, 0x9c12f92f, 0x3c6657ef, 0xa7803859, 0x14ee96d1, 0xc3c979fd,
+       0xa0fde7a0, 0x3d035fcf, 0xd021e58f, 0xf3d07eff, 0xd7f8be47, 0xaf3fd44c,
+       0xccd7c25a, 0xcd9e71c1, 0xe15e60f7, 0xc1f84f53, 0xb4ff5089, 0x3d6f8c60,
+       0x6b3e57d4, 0x7fbc600e, 0x96716d44, 0x6083ff40, 0x9dfde847, 0xc2f4eaff,
+       0xdb0583f3, 0xf471bd33, 0xd36795dd, 0x60981f99, 0x7cef997b, 0x36078f94,
+       0x976c9bfa, 0xbeb9f802, 0xea18ac55, 0x0d93795a, 0xa99365e4, 0x1f62d1fd,
+       0xc73867d5, 0xce597f81, 0xf2b187e5, 0x278e52a6, 0x71b4dfaa, 0xdfdc0cd3,
+       0x8a7bbb5b, 0xc89a7c82, 0x7d9d56de, 0xc825ce8e, 0x6b263e7a, 0xd4aaef80,
+       0xaa59e510, 0xce84fece, 0x271acc33, 0x61fe68f3, 0x1f2dc68c, 0x8edd7886,
+       0x13177c7b, 0xbdf843c9, 0x68b2f6c2, 0xabc1f51d, 0xd0be02a9, 0x41334d8d,
+       0x0cb11fbe, 0xdcf1fbb4, 0xe12b9aa0, 0x523c2167, 0xfb26aafc, 0x099a6e2f,
+       0xcd76ea41, 0x36867e38, 0x02afdfd0, 0x249abe1f, 0xfc682beb, 0x6293fd41,
+       0xf1c997fa, 0xf3c2e3eb, 0xb75a3d88, 0x2ff57f41, 0x59fbe8d6, 0x3b68ff88,
+       0xc727978d, 0x56f0475f, 0xf6f3370f, 0xbf65e850, 0x4dcfa51a, 0xeb4dfdda,
+       0xdaaf6f01, 0x97a8a57d, 0xa465affa, 0x7cff916f, 0x49b87e3a, 0xb3aad9e8,
+       0x39fd3157, 0x58b49b92, 0x90c75cba, 0xde3ee76e, 0xa2f186f9, 0x7a604ce3,
+       0x7e047ffa, 0x6fb7584d, 0xedd762bf, 0x03ce90b3, 0xc510b3f3, 0xf35b55f3,
+       0x07a75859, 0x5f1c3ffe, 0x027f0e17, 0x5ffe6638, 0x61ac6386, 0x451c28be,
+       0xfefef806, 0x80259470, 0x02b7d663, 0x959dac47, 0x67617ee5, 0x0d5452fb,
+       0xbdb63bf7, 0x8ffda564, 0x96c85374, 0xceba7687, 0x5b7a7644, 0xbf1f8b6a,
+       0xc6b6d8bf, 0x1ee1e74b, 0x722a04b1, 0xdd0a7fc1, 0xabfda269, 0x6ebe796d,
+       0xf6dadfdc, 0x26be792f, 0x8b3d349c, 0x071662ec, 0x3c5b6d81, 0x087e2aff,
+       0xa3efef8d, 0x3e3b44e9, 0xf646c532, 0xe59cdb72, 0x9f4fff94, 0xda1c7673,
+       0x0a7e9d49, 0x66531d91, 0xf3353f93, 0x3c26d6be, 0x149191ef, 0x2ffd1c78,
+       0x74dad425, 0x76bc7878, 0x58667fae, 0xbe6066db, 0xcf595b68, 0x73938c38,
+       0x803e702e, 0xfcf5abaa, 0xff311311, 0xbc1adc73, 0xbb780ad6, 0x1bf22aca,
+       0xf2852c29, 0xc9051562, 0x6dd2c2a8, 0x5a253ed0, 0xa7caf87f, 0x3191cf29,
+       0xefc860af, 0xaf814b18, 0xa67a3abc, 0xf641ffa9, 0x461afeb9, 0x8bf47179,
+       0x172feff5, 0x027d7d7e, 0xb4e81dff, 0xad1ce11c, 0xd4c21cf4, 0xd1e75d61,
+       0xd45f18d9, 0x139955ae, 0xe46d496c, 0x8bffdc77, 0xfd6207f1, 0x22de595a,
+       0x7c44acfc, 0xf3958cf1, 0x25ff80e5, 0xe40fadfc, 0xb3f0a37e, 0x1ea2ed2a,
+       0x9e506e73, 0xfe13ec17, 0xfc62df4f, 0x37d61268, 0xd769978c, 0xee7ce904,
+       0xe5deb172, 0xd1334a5b, 0x7fdca9bf, 0xd963ad23, 0xf7e4d9e6, 0x84bcdf2f,
+       0x784a7bce, 0x9bfc632a, 0x51265acf, 0x1d112bbe, 0xfd221fa4, 0x273f5899,
+       0xde157bd1, 0x41cfa256, 0x58edafcf, 0xe67cc36e, 0xf67fa8c4, 0x7367c42a,
+       0xf1a6dca0, 0xb31e09ef, 0x1b6d38f3, 0xb6005f7e, 0x399650ff, 0xb957d715,
+       0xdf092329, 0x716b623f, 0xf91e5ca2, 0x61d7d7e2, 0xf093f43f, 0x9529ccbc,
+       0x9eb2a5fb, 0xb72b9e08, 0x55e93f70, 0xe1accf31, 0xeff3661f, 0x1879c4ab,
+       0xe97ca696, 0xec7efc48, 0xa69d9879, 0xaf903bb2, 0x9d7810ef, 0x873e0b62,
+       0x155793f5, 0x5ea79f12, 0xc7cdd079, 0x79d79e37, 0xd3a5c44c, 0xee4dc3fb,
+       0xbfdf3a74, 0x71e5e1db, 0x23ac1946, 0x653e4fed, 0x7f1e8ea9, 0xaf8978b1,
+       0xc528fe31, 0x47d7a438, 0x702ce0f1, 0x0579f82f, 0x7e48df23, 0xa6f3eafb,
+       0x2dff066d, 0x69f4de7a, 0x8b4edbf2, 0xacf5e5b8, 0x724be6c8, 0x51ef6c31,
+       0xdebd4e31, 0xbf416e99, 0x16bcc030, 0xf5ae4b8c, 0x16eb9cc5, 0x11aedae7,
+       0x7dc209fa, 0xfa0daefa, 0xaf15f619, 0xcfac669f, 0x37eb1bf6, 0x7effc454,
+       0xee374d8b, 0xdf169fdb, 0xf0299e75, 0xb10ca726, 0x002d82de, 0x3bbd6eb4,
+       0xae127f54, 0x9bcb4777, 0x26fe7d6e, 0xb0584f36, 0x4f212345, 0x900eee34,
+       0xbca43c0f, 0x9d688580, 0x99dda94f, 0xc0a0b8fa, 0xb579ce22, 0x12f33aff,
+       0x36c391a0, 0x9fea266c, 0xe7eb955e, 0x4afefbbe, 0x4b18ebf1, 0xcefc0de4,
+       0x168bcc78, 0x2853ee2f, 0xff285a2f, 0x4edb3f51, 0xa5bf03df, 0xf7a1935c,
+       0x3900c7c7, 0x5d33ae10, 0x5f3c8663, 0x9bacf73a, 0xb79ec5fa, 0xe7cdfbff,
+       0xcec73c24, 0xe23e5ec7, 0x16007bc6, 0xf9d1366c, 0x5c8b85ab, 0xa4889df4,
+       0x6338ec6f, 0xe171a8b6, 0x84ff844e, 0xb8f4b774, 0x74e6ff71, 0x4af299bb,
+       0x6de3edb1, 0x5f8b37ca, 0xbaf31a17, 0x43fd9ea7, 0x57d60461, 0x375cf4ab,
+       0xd8e2972e, 0x638c36f1, 0x5f719d37, 0x3fbe7a49, 0xaefba033, 0x86fdb7a9,
+       0xe3cf20a4, 0x4903be18, 0x2f128fc4, 0xea70f089, 0x7e16edf0, 0xd164327e,
+       0x28c6d7e7, 0xef9439fe, 0xa7b2a4db, 0xd1a77ce2, 0x7be71364, 0xc44c9ed5,
+       0xfda5dd57, 0x2f2ab714, 0x41eee87e, 0x7ef160bd, 0x23e0e29f, 0xe97b0710,
+       0x3c775efb, 0xfc1bfdfb, 0xc4ec10ee, 0x8fb71b02, 0x12f3edb1, 0x17f8a39c,
+       0xecdf8741, 0x9bd1e4ff, 0xd013e087, 0x6f30733c, 0xd551ef35, 0x3aaef983,
+       0xdbc90f4b, 0x3718affc, 0x76fc7f11, 0xa0f29dbf, 0xe9da160b, 0xf9d888fe,
+       0x8f3dab4e, 0x9df30cde, 0xff707806, 0x00a8f4ff, 0x66f4f1e1, 0xf6fb83d5,
+       0x983ae7f3, 0x54ffd74d, 0x08f9f1c7, 0x0cce99df, 0xba701f3a, 0x49df3e2b,
+       0xfb655d3c, 0x45c57986, 0xf209fcc6, 0x8eadca1f, 0x3c57feff, 0xc70abbfe,
+       0xd7e1c29e, 0xd53a8b9f, 0x8f1c9f91, 0x7c1f72ae, 0x1cf18b4c, 0x2ee80955,
+       0x775eb71e, 0xb180acb0, 0x0c8eb261, 0xa075f30e, 0x7071e39e, 0xfb24f104,
+       0xdd7cd43f, 0x8577dc4c, 0x03f11fba, 0x9d5bf9ef, 0x7762bfd4, 0xe8cfc211,
+       0x059ab9bb, 0x3b01e64e, 0x74a399f4, 0x54f00db3, 0x43407dd2, 0x6475857f,
+       0xc46bfad0, 0x6ef0b1fb, 0x68fd8bb3, 0xe4ca87bb, 0xc23ffdb7, 0xba3a4a7b,
+       0x49f8bc93, 0xfc6a4756, 0x5d9a0073, 0x60039c31, 0xf1e50f6a, 0x3cf06632,
+       0x473eff6b, 0x87894db8, 0x3bfcf59f, 0x2abb18af, 0x8d46b7e5, 0x11ad7d90,
+       0xe6abf5f6, 0x5bdf10ef, 0x9ac492be, 0x355df46d, 0xbfe013e0, 0xb41717fe,
+       0x7af9403d, 0x1cac9dfe, 0xf31164a7, 0x47fae9b7, 0xe33cf26c, 0x833d7cc3,
+       0xbd70e7de, 0xfb033a02, 0x4cf6a667, 0x01bff250, 0x7e316e1f, 0xeb6b5267,
+       0xf43d4429, 0x15fc1284, 0xedfeadd2, 0x77ac4c9e, 0xfc9279bc, 0x67c573ae,
+       0x7f3205ee, 0xeed0d114, 0x3a5dddac, 0xb57f286c, 0x9d40e306, 0x7de28c7e,
+       0xf187c516, 0x5abcc3c6, 0x2c11d9cd, 0xdd143694, 0x126859b2, 0x9fdf33c7,
+       0xdf8099e8, 0x6e3ac1ef, 0x2ff5039d, 0x3fccf462, 0x69e9fc2a, 0x574cffdc,
+       0x730d41d9, 0xdd376a6c, 0x214bf0bf, 0xf214bf2f, 0x33dff1d2, 0x74fa46ae,
+       0xdcf269bc, 0x97e3ab93, 0xc1b21624, 0x7b5bd77b, 0x8efe827e, 0xebf6cbac,
+       0x869d2fc1, 0x72e36afc, 0x66b5e523, 0x7d397c51, 0xfe26e6d2, 0xc476f61c,
+       0xc7ce798d, 0xff23e951, 0x7f271fb7, 0xccd3a3a1, 0x61cd93f0, 0xa0e6828b,
+       0xc1ff8a33, 0x2a3d70e3, 0x96a21de5, 0xde425c0b, 0xe57bdf91, 0x951e59f7,
+       0xc2b5c7fc, 0x3c65ec7f, 0xfb11a87e, 0xf02a7fac, 0x1afe39d3, 0x5c600b3b,
+       0x3f8f27f7, 0x78fc8539, 0xdf2d9fa3, 0xbdf67e93, 0xa55e39eb, 0x38a362de,
+       0xf266647f, 0xaf296bfd, 0xf687ab2c, 0x207f24b1, 0x03d3c4ff, 0xd47a0a97,
+       0xe819359c, 0x46a7a51a, 0xdfcf94f4, 0xd2127b07, 0xfa5cc39d, 0x377d0171,
+       0x51f31b73, 0x66b6e33e, 0xe4e90b07, 0x3e51e3b6, 0xc63dc76f, 0x798967f9,
+       0x3e38925b, 0xf877c43b, 0x91dfaa1d, 0x37d5145a, 0xae075f80, 0xabcbfd4f,
+       0x79498f14, 0x95dce390, 0x7ee1f7c4, 0xadf357f1, 0x2bb67db2, 0x76a5deba,
+       0x2f24b7d3, 0x27de437e, 0x24999f8a, 0xc5e58947, 0x92f215f3, 0x4d05f84e,
+       0xf97b46ea, 0x9f1ff09c, 0x68aa6c3b, 0xdb7fc38b, 0xe73d7c6d, 0xec01a867,
+       0xdb844177, 0x32fd44b3, 0x15f9c553, 0x3c589781, 0x3fc7e7a4, 0xd056b2ff,
+       0x7f8ca6a5, 0x22f78ccf, 0xca0c3e60, 0xd78c1f6c, 0xd10ce65b, 0xef22cbf3,
+       0xcd493ee2, 0xca2f56f3, 0xf6f3ef6f, 0xf49bcc2a, 0x6aad6f3e, 0xc7a60e73,
+       0x1e8d6fe6, 0xebfd6f7f, 0xf42bf49f, 0xbecd3b63, 0xf3c1de31, 0x845dd927,
+       0x93bd019f, 0x68d83fc0, 0x3b3c7273, 0x792d9e38, 0x5ba78f5c, 0xb1ff788d,
+       0x33748790, 0xd7a0b644, 0xfe7905a6, 0x90bb39e9, 0x5b87900f, 0x4eec2f90,
+       0x2c7efe03, 0xafa969fc, 0xc6575f1e, 0x7ee1a78e, 0x6ff6886c, 0xc91f7e3b,
+       0x4b7a79c6, 0xb56fdfe3, 0x6309f05b, 0xea6eff46, 0xfb42af4c, 0x678aede8,
+       0x9ff68b0c, 0xe7bfceda, 0x061ddb35, 0xf02cdbbf, 0x7638e521, 0x3cc40f9e,
+       0x90cfa81d, 0xc31ece2e, 0x03e4bb3e, 0x7ae4d7a9, 0xfd911da4, 0x67f82f7e,
+       0x8ccfe0ba, 0xfc1f3e26, 0xca9ac2b3, 0xdeff01ed, 0x7841eb9d, 0x9da2b21e,
+       0x78f34160, 0xaddd67a0, 0x16f7d18c, 0x33fc1f62, 0xbb2df047, 0x07e81d6e,
+       0x7e16fe92, 0xd738875f, 0xd407fd28, 0x7a9d134f, 0x0e1c43b8, 0x55f5c2b3,
+       0x70927e8c, 0x7cfc3ac0, 0x138d171c, 0x8edc6fb5, 0xb58f42a9, 0x6322ef8a,
+       0xfe7fe6e5, 0x569b911f, 0xe9025e71, 0xbcdf4f10, 0xc96eec25, 0x0562fedb,
+       0xc04c6bf8, 0x624fc3e9, 0x1ce7ba4a, 0xb0bd40b0, 0x37cb414b, 0x82855720,
+       0x45bc70df, 0x18f8a3e3, 0xf032e49d, 0x3e2a3fdf, 0x0366df0a, 0xa3a2dff0,
+       0x2e2494e7, 0xf32a19c7, 0xc3fedf13, 0x80381fc2, 0x00d4efdf, 0xdf34505d,
+       0x969bf01a, 0xbf4763dc, 0x43e66de7, 0xfb74e9bf, 0x8c78d312, 0xbf70b75f,
+       0x6e2f4065, 0xbd07ebe6, 0x6d7a8ed6, 0x477edbcc, 0x2167d411, 0x5bce30fd,
+       0xd379f8c4, 0xe3185776, 0x198f2925, 0xe0667b73, 0xa39d473e, 0xf75dbd61,
+       0x277fa07c, 0xca8dcff4, 0x35ca0d75, 0x82b53bcc, 0x2b4eb3b7, 0x8b160fdd,
+       0x47bec62f, 0xeff226f3, 0x7ae24c6e, 0xd234f50d, 0x6ec21ca9, 0x4afdc03b,
+       0x798cc86e, 0xe4c657d4, 0x957dc44e, 0xa2c14943, 0xa67ef035, 0x29983738,
+       0x26669bce, 0x126b72f1, 0x0e99cbd7, 0x5c1d065e, 0x79ba67bf, 0xef79d8ff,
+       0x54defd12, 0xed7f064c, 0x7c3c8204, 0x38af9f30, 0x327e88cb, 0xed42bf4f,
+       0x8002cdff, 0x9997456f, 0x4d3b07f2, 0xea24fac1, 0xfb1d12a7, 0x0f8b3d4c,
+       0x1ef10123, 0xf3128ba5, 0xb167d493, 0xa3ea34fe, 0xfcf20d9b, 0x3be3825d,
+       0x9190afb8, 0xfafcbfd8, 0x027e7d7c, 0xb7c26b7f, 0xfa496fe2, 0x8c80bccb,
+       0x307f25bf, 0x6bad20f6, 0xbfce4cea, 0x6177afa0, 0xbafa0afc, 0xebc91a68,
+       0x6bbc780f, 0x719178e3, 0x4f66667c, 0xc0b7c61d, 0xbc9ef487, 0xe4f729f7,
+       0xe41e749b, 0xf537248d, 0xb7f0e5db, 0x5bc9c526, 0x6869a88d, 0x8487fba2,
+       0x42f795dd, 0xafdf6a8d, 0x19be3aa8, 0xfee1c555, 0x60c59269, 0x7d443a17,
+       0xd3971277, 0xa5115551, 0xd88dfa00, 0x015143ba, 0xfced119e, 0x0688f77c,
+       0x0c9ff746, 0xf0e61bcc, 0x95870d8e, 0x70a28adb, 0x17669b37, 0xe69e0079,
+       0x09af874c, 0xe0ce699e, 0xcd77080b, 0x039d08b1, 0x5bac7a9d, 0xd32978c5,
+       0xf205ffe9, 0x6bd7849b, 0xbcc08cf6, 0x8718e3bd, 0x9fc065b3, 0x79e6c9ef,
+       0x3c0aefc9, 0xc9fb09b7, 0x4efdd30e, 0x336f6e4e, 0xa6db19ef, 0xfd26673f,
+       0xccd7e858, 0x72e3ee28, 0x614f799e, 0xb8ba03db, 0xb03f3cb1, 0x0f979f03,
+       0xbf11371b, 0x307fcfb7, 0xc73ee2a2, 0x154d5b0b, 0xf6fc38e1, 0xa75394b6,
+       0x2eb8d7ff, 0xc957ff09, 0x4967ec87, 0x1def9a1a, 0xb7060f82, 0xa5ed443f,
+       0x84dfa64f, 0xd06cd6f0, 0x48f16e18, 0x033a67bc, 0x239f1027, 0xc4155bda,
+       0x9f8e63c9, 0xae0e7828, 0xce798aba, 0xaef6d203, 0x7bc1cb6b, 0x7cee6a97,
+       0x79ef072e, 0x38c0f092, 0x98d6ef84, 0x0fd28b73, 0x67e11ff9, 0x67033b94,
+       0xcebafc70, 0xb7bfb44d, 0x5fbf0772, 0xcfbae127, 0x9eb02f11, 0xd5bfc8f5,
+       0x5478bfc0, 0x8dfb0147, 0x6859acf4, 0x6a26efa3, 0x63fe7176, 0x18f0b41b,
+       0x8eefb7ac, 0xe47da098, 0xa61f7edd, 0xed77abef, 0xf0e99656, 0x4c26b235,
+       0xb9e77bfb, 0x97227ee4, 0x4bed11f7, 0xb38f886a, 0x63e43e1c, 0x71d92fcc,
+       0xfdcecf3f, 0x1e52deaa, 0x425af49f, 0xafd0bd63, 0x87c93737, 0xbabd3bdf,
+       0xdefa0afb, 0x35bcf5d0, 0x7ca3b8a2, 0x6f7ac0f3, 0x40f9c229, 0xdf20f339,
+       0x835fde80, 0x2726f2f5, 0x1a9fbe43, 0x77a9c743, 0x3bf6be73, 0xc31ef2dc,
+       0x63d7c889, 0x81aedc1d, 0xeebf205d, 0xf3c38590, 0xdd74e33c, 0x75c8149a,
+       0x87f7e064, 0x54f18611, 0x86bb454a, 0x387608f9, 0xbd5bf095, 0x37d683b5,
+       0x7bf71772, 0x92b577aa, 0x82fd4a3c, 0x7b7bc0f8, 0x457be2a7, 0x47040fc4,
+       0x943b93e9, 0x927fd0e3, 0xbcf3ccc3, 0xc7ec775b, 0xf019887b, 0xd02fc60b,
+       0xce4affbe, 0xe96e2a3f, 0xce3dc80d, 0x59e7c453, 0x097b93a6, 0xbff91c77,
+       0x1e77e118, 0xe5c83eeb, 0x6fefc23f, 0xe921fc12, 0xf5c1c330, 0x21c7a48f,
+       0xe300e80d, 0xa24bca1c, 0xa23ca471, 0xfa11ccfc, 0xc68ce4c9, 0x090e1249,
+       0xd9472ee7, 0xb8298e15, 0x775a6eee, 0xe09556ed, 0x0502d72e, 0x3b7c75ab,
+       0xfbf9c1cf, 0xb57782c0, 0xf9be781e, 0x9f0947e7, 0x3f0a2db5, 0x5472dac7,
+       0x3e7a879b, 0xe319acf4, 0xff19ab9d, 0x51cf747b, 0x7757cfd2, 0x76d7bc70,
+       0x736f56ec, 0xf728f946, 0x74c581e4, 0x95bb751f, 0xe9923fa1, 0x788cde0c,
+       0x024fc418, 0x25cf520f, 0xf4871392, 0xf91a4253, 0xe421e029, 0xf520dc62,
+       0xdf1156e4, 0xfe7f2730, 0x515d624f, 0x41ac10fd, 0xf927947c, 0xdf50d80e,
+       0x3ce8544d, 0xe933b487, 0xf51e3833, 0x37bdc4f0, 0xd287e64f, 0xb25f8c98,
+       0x63bee8e7, 0xe2b7d018, 0x5d04bbfd, 0x3f8479e1, 0x37687967, 0x74b1dc25,
+       0x6bf081fb, 0x1351f0e2, 0x476b1fc2, 0xfac05f24, 0xf73db19a, 0x41ec89a4,
+       0x86d6c86d, 0x98af26fb, 0x75df90e6, 0xf09b8160, 0xdf90b357, 0x67f9bc63,
+       0x84d4af5c, 0x777f749c, 0x256e704d, 0xdba543ed, 0xc50fb87d, 0x79b50782,
+       0xf774c1ae, 0xce9fbf3e, 0xcedd5c31, 0x8f4060e5, 0x4bfa73b6, 0x1fd72efd,
+       0xcfc7375d, 0xec858d2c, 0x6dbc51a9, 0x7d08f24d, 0xdfe5cc10, 0x3ccd7fa3,
+       0x7b1666f7, 0x88b3d29f, 0xcf5b5a8f, 0x2faadc21, 0xd35fbb79, 0xf2c727ef,
+       0xd7baf557, 0xac2ed10a, 0xa54c3aca, 0xb7a0ff3e, 0x7d057b57, 0x8be5149e,
+       0xa7985f48, 0xc93b727a, 0x0d07f54d, 0x0ace6f24, 0xc79c67ae, 0xd6307a8c,
+       0xb4772a5f, 0xdefdc2cf, 0x9e2a1ff2, 0x5ed89626, 0xde7850ac, 0x2fada3f3,
+       0xc19cf1bb, 0xe26bbdc0, 0x0e1bf03c, 0x3bbdffce, 0x97c4e101, 0xfe50da0d,
+       0xc78d57e2, 0x74296f22, 0x7dc0808f, 0x1719aeef, 0xd2e7887d, 0x7e532677,
+       0x375dd3e7, 0xc021f9dc, 0x72e3bbdd, 0x4de943b2, 0xfe9fe201, 0xf70fbb0c,
+       0xa97e20df, 0xebee8050, 0xe3765fdb, 0x3f27e4fe, 0xda2270ba, 0x9c050fb7,
+       0x5e667f27, 0xe7b97887, 0x865e9f99, 0x2561d5ed, 0xef6cf50d, 0x15fe1fce,
+       0x8ed570f5, 0x9a9f8a7a, 0x0d4bf47e, 0xe14d39f7, 0x677cfe56, 0x7dfb07b2,
+       0x65d37db2, 0xf6a6ef88, 0xb93f6a26, 0x07ea95bd, 0x4be9f99e, 0x33f68dff,
+       0xbf61f6e0, 0x4fdb3f93, 0xaa09a974, 0x04f0defc, 0xeee8fd7c, 0xa19f5cfd,
+       0xb07287bf, 0xc919eb90, 0x3f7f92d7, 0x8bd6e679, 0xc6bbfaf4, 0x60a5181c,
+       0x1f5661ff, 0x7d07d79e, 0x15fbfa4e, 0xc4ed533b, 0xce9cadf7, 0xaf74d5e6,
+       0xd73e7943, 0xdc61883b, 0x72febaf7, 0x91477d07, 0x4afb10e1, 0x293f1176,
+       0xbcc3ed0a, 0x6d05e972, 0x217dba4d, 0x9457bf49, 0x1756a3d9, 0x8b379f45,
+       0xb8939b79, 0xf514f93d, 0xd539c430, 0xac1efc65, 0x5f6c7f4f, 0xd6b5fe48,
+       0xd76bf743, 0x34be7114, 0x9a3d393b, 0xb7e57e45, 0x39630ee0, 0xcf02e41e,
+       0x8eeb40d5, 0xfadf292f, 0x1a6fd913, 0xbed357c2, 0x784752da, 0x0e7f11f9,
+       0x8ee7c658, 0x354b06a2, 0x1b592f3c, 0xe91c5e3f, 0x3dfd3274, 0x663a2376,
+       0xde92f28f, 0xe8c6fab1, 0x5511d2fc, 0x27dc26c1, 0x906d6ab8, 0xe17ea9ee,
+       0x5ee937e3, 0x2ac667e3, 0x30df8893, 0x2f76847f, 0x6a79a4e4, 0x70078f31,
+       0x7114ef9e, 0x17a987a3, 0x32aff1eb, 0x75fb49d5, 0x6a97a4fd, 0xdc5d859b,
+       0x5b19e221, 0x6bde367f, 0x2f39ef0a, 0xc09bedd6, 0xd5274e7b, 0x8fe7b3fb,
+       0x5a143b47, 0xabc87648, 0xa527bc11, 0x09a161fe, 0xa1e2e8b7, 0xf51738d8,
+       0xca77e61b, 0xe77ea59d, 0xe3296894, 0xdd3c58df, 0x3877da25, 0xea277efd,
+       0x16e79dc7, 0x7a09d687, 0x2cf4aa3f, 0xed0e3e47, 0x2f907bb3, 0x29eb2eeb,
+       0x3bb1ebd4, 0x0b4e9e04, 0x41dfc13e, 0x64cdb8a0, 0xb5df110a, 0xa4dad05d,
+       0xe77bb60c, 0x44757f09, 0xba41e2a7, 0xc73ad88c, 0x9bf03f40, 0x7f686bd6,
+       0xe4252ac6, 0x7eae76cf, 0x11e61c6d, 0xaf586e81, 0x495d98eb, 0x833b03f8,
+       0xe75d6cfe, 0x73840eec, 0x3eb5fa64, 0x3f0797dc, 0xe77d1664, 0xa0a6c351,
+       0xda3a3efc, 0xad246fbf, 0x1e786143, 0x384b51f3, 0xa3f7ed0b, 0x787d0ae3,
+       0x582ea63e, 0x0af24359, 0x2f7d2d7e, 0xfe40dc15, 0x26f79d6b, 0xc6a7ed1f,
+       0x853ef9ca, 0x1be054fc, 0xab8b1dfa, 0x7c2cbbf1, 0x7920ec3f, 0x2dccebaf,
+       0x9eaef845, 0x9e60f3e9, 0x8fc494ed, 0xf4dd2d2c, 0xf7a7183b, 0x27485958,
+       0x03eeaf97, 0xf80266bf, 0xafc17b35, 0x3fdf8099, 0x1571d9fa, 0x0d7a71c6,
+       0x5deab779, 0xcdef74b9, 0x7f8ed129, 0x2d7ddd5e, 0xe21195b5, 0xcfe11acb,
+       0xc5fd5ba6, 0x26e8ebb7, 0xfa5894fd, 0xf6e4ee3f, 0xe727bce8, 0x00463d12,
+       0x239f103d, 0xa26e9ab6, 0x863485f5, 0x8aaabbeb, 0xbe01ea45, 0x229ab6ab,
+       0xfa884f97, 0x3de3b131, 0x4f7114e9, 0xf518a05a, 0xa702f95b, 0xca87af4f,
+       0xbb26fc93, 0x2c628fce, 0x92e31930, 0x845d338f, 0xaf4e1df7, 0x7e0c87f4,
+       0xd3b8e0cf, 0xe1f8c3ee, 0x04d0969a, 0xaf0e87dc, 0xf2885a4f, 0x49d47a08,
+       0x781eebfb, 0xb6d6e31f, 0xb8f3b64b, 0xf9d689b5, 0xc247a77d, 0xe301b937,
+       0x5ac0fcdc, 0xbe5c7f6e, 0xe5d6fb78, 0x2ee7e94e, 0xbef3c62e, 0x3e9d7375,
+       0xff36af8c, 0xe38a5942, 0x746c85d7, 0x705d6e39, 0xf2579bed, 0x5fdf8038,
+       0xbaa2fc23, 0x347d1bf4, 0x7a7e20ff, 0x4e8ddb8f, 0x4ebaaf4e, 0x1c642f6e,
+       0x5e217a8b, 0x29ca5ede, 0x6b8c63ea, 0x39497f24, 0x3c79573d, 0xfc90096d,
+       0x2375869c, 0xe1f00e3f, 0x630f9c0b, 0xff8934e3, 0x8bc2f8d8, 0xef7506c2,
+       0x8f7d0776, 0xe69af52f, 0x3d451c0c, 0x6476d754, 0xd0abb123, 0xdc2f7543,
+       0x3f94385f, 0x78f95365, 0x3d2b9036, 0x1359e0df, 0x432a44d7, 0xc0df3a4e,
+       0xc6df5fb8, 0x1d8e8fef, 0x4f42b7ef, 0xbf4a7c49, 0xcf82f319, 0xc29ff943,
+       0xfa227d7e, 0xcf29d5fd, 0xfc0d8457, 0xdf0535e7, 0x44f17dc3, 0xf7be56fa,
+       0x7226f34d, 0x63efa97c, 0x99f325e9, 0x45d98eb8, 0xecb5fb89, 0x0c48f117,
+       0x3e0b14ff, 0x80e7037e, 0x07724f75, 0xbea0b917, 0xd3f99928, 0x7e8bdf00,
+       0x29f7e569, 0xc42fed8c, 0x655aaa78, 0x5797cc21, 0xf584b4ef, 0xa1f736e7,
+       0xf5ef040f, 0x33216cb9, 0x3bb95df0, 0x0671c1e8, 0xcbbd87ee, 0xc1e1e74e,
+       0x7282994d, 0x481ed23b, 0xf7e06575, 0x4f743d89, 0x1e0e63ec, 0x311ff44f,
+       0xc5cbcf87, 0xe87bbe7b, 0xacce84f7, 0xea7ca7cd, 0x61fc2f3b, 0xede01fcf,
+       0x1a3e7b53, 0xd493cfad, 0x55364cd9, 0xad3c6f97, 0x2b67dfc4, 0x167d7176,
+       0xf3f65bcd, 0x438be5bc, 0x63eb41e7, 0xf3d1fbf2, 0xfdf9b1b3, 0x6fa878e8,
+       0xfbf263eb, 0x6f5c5d07, 0xf9e7df47, 0xf14c77fd, 0xc7bd6fbf, 0x8bafdc65,
+       0xc5cfbf6d, 0x8f23abf9, 0xe3ff45cb, 0xe4fd184a, 0x115d6be5, 0x396b8fbc,
+       0x63bf463c, 0x311427b9, 0xf9ae51b9, 0xcdfc323e, 0xbe5f81b5, 0xe807d844,
+       0xbe474ea7, 0xff68790c, 0xd0f42831, 0xff57ce92, 0x72f4f18c, 0xc3a6d995,
+       0xbe6d4b38, 0x13fbf843, 0xba673a1f, 0x7e56ed51, 0x744c86e7, 0x6a2d86e6,
+       0xf455bca0, 0xf374f57c, 0xfabe72df, 0x57302bb0, 0x7fd21bf2, 0x5f5cedd1,
+       0x9756fec8, 0xe467373c, 0xd01377b7, 0x665dc739, 0x3ababe46, 0xc698b029,
+       0x4194fdbd, 0x7a569caf, 0xf201fe9e, 0x7bfe6ae3, 0xd7efb147, 0x8afaf98a,
+       0xc53ee9bb, 0xc97fd5be, 0xebaebf26, 0xff51b7d5, 0x817bcad5, 0x7b862c3b,
+       0xfc932b81, 0xf7efc4d5, 0xfba14f4d, 0x73c186ce, 0x1ab82782, 0xf6fe41e1,
+       0xdbf9eba7, 0x2ce78c9b, 0xba01b5ea, 0x921ef7d0, 0xcb946c2e, 0x23ae8f48,
+       0x36a58f44, 0x701bdd3f, 0xf0403f9b, 0x4c8e4a2d, 0x5ff018f1, 0xf7dd37f4,
+       0xf6e42958, 0xfdfe2d1d, 0x3e09f7e2, 0x8dfb283c, 0x4efafce0, 0x1e7aab36,
+       0xff234ccb, 0x2ce42c3e, 0x71cbde2c, 0xbc421ffb, 0x18795e80, 0x8e7400f1,
+       0xcaf5e8a4, 0xe7ba7ee4, 0x374a6fa2, 0xae7d1f7d, 0x80ac66f8, 0x8e784bd6,
+       0xd1385e73, 0xf0b56f7a, 0xb5df0075, 0x47af48b9, 0x87bfebc6, 0x5b80b9ff,
+       0x493be5ca, 0x142cbc46, 0xe091fbeb, 0x87974a93, 0xfd7c1be7, 0x3bce38d9,
+       0xb8f1f1a9, 0x768f8a28, 0x7fb583c2, 0x6fd01a71, 0x6d35d83e, 0x12a7e122,
+       0x938a0f9f, 0x49ff228a, 0x5c6b6dfb, 0x0bc5ed0c, 0xfdc9be72, 0x963f8f3c,
+       0x885a0bcf, 0x57d96eff, 0xc2bd6de0, 0x3145e77f, 0x2b6844c3, 0xdf2f32c7,
+       0x7fce980f, 0x203ecaaf, 0x195c8797, 0xcec4fc51, 0xc09b0c7b, 0xc4bb779e,
+       0xe63e40f7, 0x1f16f7c3, 0x8b75ccfd, 0xf43df0d7, 0xef4e385b, 0x1fc8479d,
+       0x0a45a63b, 0xda719c5b, 0xc7b6c8b5, 0x6b3b6894, 0xadc17ee0, 0xbbe99acf,
+       0x9ea66398, 0x2d7f7047, 0xfc99a6f4, 0x3dde3fa8, 0xfa2bbe83, 0xffa30ef4,
+       0x45d0527a, 0x20309f7e, 0x830b783f, 0xc5eff079, 0xcb9ce6dc, 0x3ee629e5,
+       0x14164af6, 0xfb13fbbf, 0xe103427d, 0x893df079, 0xe73c87eb, 0x7ce6e995,
+       0xf38269f3, 0xebfb8a19, 0x3ee327da, 0xc4bed45d, 0xf1f1d3ee, 0x474e6edc,
+       0xf6fea769, 0x304aaef9, 0xe77175df, 0xba7cf393, 0xb3bafe3c, 0xd58edcdc,
+       0x461becc7, 0xb3e795c7, 0xa49fa85a, 0x2cd9fd77, 0xd2eb2e7a, 0x37be8a8f,
+       0xfd8bc68a, 0x13e6472e, 0xa7beff25, 0x9efd1b30, 0xf224db11, 0x78099e86,
+       0x687bd0bf, 0x06df412f, 0xf52f60af, 0xfe4b8800, 0x9aa17879, 0xd8efe517,
+       0x9d5f0075, 0xd51effd4, 0x4fb8b704, 0x217642ef, 0xf821177d, 0xe59df179,
+       0xf25aee74, 0x854f546f, 0x71adbc78, 0xa7319e3f, 0x18b3ff41, 0x13a4b0fb,
+       0xb204c1ec, 0xfc0e74cb, 0x12378bf8, 0x5f32571f, 0x17d1e926, 0xe93f74ad,
+       0x120bb5d7, 0x4b421b9e, 0x8adefc2c, 0x6bc7ba74, 0x86ff988e, 0x981fee2e,
+       0xfbfe7e6c, 0xf5e67e55, 0x03dff264, 0xca05fb21, 0xa5fa855d, 0x00cc8eb2,
+       0x3162e9f5, 0xf00fbe0a, 0xb64a2a5f, 0xf2859834, 0xb7ffef26, 0x961670b3,
+       0xbcf9174d, 0x04ae5e58, 0xa7070e54, 0x30d62cf3, 0x6c9bfb0a, 0xff9c663d,
+       0x58da7991, 0x4fa01fbc, 0xdf89f249, 0x74fba3fb, 0xf3f303ad, 0x9dd64bba,
+       0x0eefc32e, 0x7dc5bbd4, 0xa366360f, 0x4673ebdf, 0x057da13e, 0x616cda51,
+       0x0701ddfa, 0xcdba448b, 0x8c00fbf8, 0x614f9bbe, 0x3dfc112d, 0xff17be8c,
+       0x1e1c518b, 0x76fc0fbd, 0xef2194f7, 0xc7b6370b, 0x2a9e17dc, 0x7e634ae0,
+       0xad221fba, 0x635f78c2, 0x42ad7386, 0x3016e13f, 0xc444cf3e, 0x0b61ff43,
+       0x6f0bef63, 0xe1fc7051, 0x1b73e341, 0x5f7a463b, 0xbeb20489, 0x93de8b4c,
+       0xdf8920b4, 0x22eff44b, 0x115b9c8e, 0x6f015728, 0xafd88bf3, 0xe8de50fc,
+       0xe1177e09, 0x4370f1bf, 0x17d40d6d, 0xe3c6cebe, 0xc9c530f7, 0x185dea9e,
+       0xefcadd7f, 0x3efe2d6b, 0xec361d67, 0xf0c78a3c, 0xc9b51707, 0x2b2ace78,
+       0xb17d718c, 0xd48fb443, 0x7f18bda8, 0x3fdf1100, 0x95f74bcf, 0x74f38bd4,
+       0x9a7987f8, 0xc333f3d6, 0x67d30768, 0x7ac46ff4, 0xee8cfdff, 0x19f79059,
+       0x408ec76d, 0xbf4afa9f, 0x87da0325, 0xe23e64cf, 0x03bed149, 0xebcf9dff,
+       0xdf889797, 0x5d47c08d, 0x2733ca9b, 0xc6fa9b13, 0x5cfcc1b0, 0x18bb35df,
+       0x73f954f3, 0x297f13a7, 0xba0a2f82, 0x7c51ff14, 0x3f68c22f, 0x972bbeb5,
+       0x1c17dfce, 0x719e51f6, 0xd4e1a981, 0x1bdf5c1e, 0x13effe3c, 0xc84cc6fb,
+       0x7918d4f3, 0xafca24b9, 0xe72c5ed4, 0x7accfb97, 0x3ce046be, 0xfc44a0f0,
+       0xc7bd12c4, 0x1662ece5, 0x6671c3fd, 0xbd25c744, 0xbdb45332, 0x3fdf0b72,
+       0xf646aa9b, 0x225e1ca3, 0x4e5162ca, 0xe2330166, 0x7f73c4ab, 0x5177ce13,
+       0xf21a68e0, 0xaf9b74fd, 0x9f46af19, 0xb86150bb, 0x4e9cc4af, 0xffb17ebe,
+       0x3d8af52d, 0xfb67e799, 0xddbab3dc, 0xdf997dba, 0x30df85ba, 0xb98d8d96,
+       0x24f7ff67, 0x3bffa517, 0xdb18dc91, 0x4066e463, 0x7d3f313f, 0x7dfb18b7,
+       0xff3f3ce1, 0xc05e6a6e, 0x7e3e7cf8, 0xe71f97d7, 0x15d0ec77, 0x0b8e8ccb,
+       0x78416472, 0x6ec77f62, 0x2ab7f48e, 0xa2d6fe8c, 0x8522fa7f, 0xa7b0c0ec,
+       0xc1ccbf6b, 0xe25ce67c, 0xb12ebacb, 0x43fc0f3f, 0xfd89e3df, 0xe34efaf9,
+       0xd77d7cfe, 0x74337b92, 0x9d75f3fb, 0xcf3fb55f, 0x5bbfeeed, 0xd30f74c2,
+       0xd604afbf, 0x165e7982, 0x7107c2fb, 0x9462783f, 0x3cc5aeee, 0xe35073af,
+       0x3107f4fb, 0x4bcba37f, 0xfcf070cc, 0x340b8ce8, 0xe5573e7a, 0x2129f2fb,
+       0x0b92f927, 0x665defc4, 0x7e41d998, 0x1fe7847e, 0xeb3e22c2, 0xb40d7e16,
+       0x47fca06f, 0xa465dc8c, 0x6547ca31, 0xf2963cdc, 0x8abb0b3a, 0x0d3e6327,
+       0x7fe533f4, 0x7a5eddbb, 0x98b0617f, 0x395723f2, 0x8af3a46f, 0x6aad5df5,
+       0x7adf4ea5, 0xf5f78d93, 0x9a5df9c4, 0xfa29e482, 0xe019a5df, 0x489e7a27,
+       0xa7dfcb0f, 0x9bbe62ac, 0x7de2e597, 0x9d774001, 0x3194b79d, 0x53fb4f7e,
+       0x5d2b9d0a, 0x76483ce5, 0x630ed578, 0xd45b943f, 0x6bafd57b, 0xcd537f74,
+       0x467c41ae, 0x5de52d72, 0xa1b517de, 0x3ee0afd4, 0xe611df4f, 0x77fa436b,
+       0xc05b8cc4, 0xe04f98ed, 0xa5e858b3, 0x3666f349, 0x24e53ee1, 0x565f9713,
+       0x7fc91be9, 0xe7917377, 0xc7551d84, 0xfe50cad3, 0x63eb9f40, 0x067dfcb3,
+       0xc4531fd4, 0x717ab1f8, 0x2e03f08a, 0x137d6153, 0x0a7d76a3, 0xa683f5e3,
+       0xbddd332e, 0x3c9ce02f, 0x9fdc4720, 0xd24a7a90, 0xc6e5ef03, 0x92cb5df3,
+       0x63c87e85, 0x184f4879, 0xc157f89f, 0x8d2a73cc, 0xbca1521f, 0xf407cc44,
+       0x84df210e, 0x9dfa364c, 0x034a8d8f, 0xfa1b79e9, 0xa03e508d, 0xfd7f4904,
+       0x46642abc, 0x1ac45ebc, 0x1726b86e, 0x03b758f5, 0xb07c05e9, 0x4d1fcf52,
+       0x5bbd922c, 0xb509f031, 0xe8c4a6f7, 0x3d12a61d, 0xc238304c, 0xa5ad7669,
+       0xc42bf47d, 0x6e53a273, 0xc9d51fb4, 0x3fb4618f, 0x87c01fea, 0xf52fddb1,
+       0x93ea3309, 0x8f05f65c, 0xf43feed3, 0xfb0f8c1d, 0x8c5fc22c, 0xa1dd4ba1,
+       0x641f8b93, 0xbe49fa51, 0x983598ba, 0xca1f00b3, 0xf75e792f, 0x2a5ba462,
+       0xfc8c51fa, 0x892c69a7, 0xe64d8be4, 0x57c907f9, 0xa2255e92, 0x4fa484f6,
+       0x7841cb0e, 0x53b4ed2f, 0xa462e9de, 0x58bdd013, 0x4aed2f8c, 0x6af4e4c4,
+       0xb0174879, 0x7ec1e61b, 0x97aa665e, 0xe4c933e8, 0x614cfa27, 0xdba434be,
+       0xd7ddf6cf, 0xe8eb7084, 0xe3192db0, 0x80e80545, 0x3ed8357c, 0xe463db18,
+       0x94bbe259, 0x2c9fc979, 0x9c394665, 0x670d04e1, 0x8dcafba2, 0xa0b363f7,
+       0x7b94f08a, 0x6f8fdd06, 0x41b1d232, 0xc8ae7845, 0x444bf632, 0xa7a41ccf,
+       0x89690fb4, 0x6ae529e9, 0xa9d39db7, 0xfa84e81e, 0xd2afd266, 0x34813867,
+       0x25ccade7, 0xc53bb0fb, 0xfaf584db, 0xc5f4851a, 0xcbdf6ee4, 0x106fcf58,
+       0x337eb9ed, 0xafd683ee, 0xde53ede5, 0x7ac0cc0a, 0x5ede3ac1, 0xc9b04f7c,
+       0xaddfe385, 0x2fd8bdd0, 0xcbc7727c, 0x47be1ed8, 0xcfca5fbc, 0xe06fd6e1,
+       0xf9847fef, 0x3cf10bde, 0x7c0ccb44, 0x9739ae3e, 0xf0b00eff, 0xfc172e67,
+       0xe3695bb2, 0xc83c20f7, 0xc8715dc7, 0xce28c496, 0x65cafee1, 0x6f979d62,
+       0x3f4cebe5, 0x1785557e, 0x37b2a9f8, 0x2d95d740, 0x1109c164, 0x3372ef58,
+       0xf1f9f204, 0x10bc1be4, 0x0d288f28, 0x500aa744, 0x72fbf49d, 0xc0b67cd3,
+       0xc7ef9e78, 0x92fa79ef, 0xf329bc79, 0x35ffb8e5, 0xfb4f675b, 0x469e7992,
+       0x654ccbf6, 0x09ef3f7c, 0x91a3f917, 0x7c8298c7, 0xfec0b88f, 0x57faf289,
+       0xbd9037e4, 0xe64722ba, 0xa5d47bf3, 0x97f15f30, 0x178acd9f, 0xcc9e7f07,
+       0x62c7e4ed, 0xaf3e4f1f, 0xbdfdf30a, 0xf4cbc8dd, 0x30e9ad7d, 0xe19853d5,
+       0xb9ddab1e, 0xfe7aaebc, 0x28f35f7a, 0x06b35dfc, 0x36ca8435, 0xcc7da15b,
+       0x679fe0eb, 0xffe14627, 0x2830d93f, 0x00800092, 0x00000000, 0x00088b1f,
+       0x00000000, 0x7dedff00, 0x45947c09, 0xf37f78b2, 0x093215cd, 0x87213b93,
+       0x98884013, 0x861c2184, 0x4109264b, 0xe8098414, 0x720d7282, 0xeb22dc85,
+       0x97f75763, 0xd9110441, 0x73d6f8dd, 0x0160763d, 0x18896151, 0xc3824830,
+       0x12a20882, 0x75040411, 0x0844ae22, 0xf1e20c49, 0xabaf2e1e, 0xbe667bba,
+       0xfc38666f, 0xddbf7ffb, 0xdb2e23f7, 0xaaefafa9, 0xeaeaeaea, 0x084c8eaa,
+       0x908238b9, 0xadc4b45b, 0x9680a1cf, 0xc8401bfe, 0xd5fa25dc, 0x3f02242b,
+       0x213c6376, 0x33fe1277, 0x192d7aec, 0xf01dc844, 0x289085bb, 0x2afda4b3,
+       0x9fdefe83, 0xd328bff4, 0xf3bfcf72, 0xc84d94a3, 0x3a558caf, 0xd50a1dd2,
+       0x8459ece8, 0x9c9b359c, 0x7c84be9a, 0xcce2392e, 0x7d690903, 0x965cff76,
+       0x64beceef, 0x47e696be, 0xb048d4d0, 0xefde62df, 0x13d2e27c, 0x977cdfda,
+       0x918f0bee, 0xfd22ed0d, 0xa43a6a57, 0xae9a1a27, 0x232f7e57, 0x41e93d1e,
+       0xf2ad7948, 0xe271257b, 0xe57acaf7, 0x91d99277, 0x845efd06, 0xf69f8a1f,
+       0x5907cb67, 0xcfff6932, 0xe6147fbc, 0xb9346c57, 0x97129a65, 0xc193d5ae,
+       0x1e7ce1eb, 0x4e157f34, 0xc8fba793, 0x64246f17, 0x6cc89752, 0xbb9095d2,
+       0xe67e8ecc, 0xf99c4238, 0x146529e6, 0xe1e9cebf, 0x5c5025d6, 0x4c396536,
+       0x6308fdb4, 0x8bce9b96, 0x4cc588d8, 0x79f12df1, 0x9f0c0d4a, 0x3c52471f,
+       0x4832f8c3, 0xe699e006, 0x14d1f53b, 0x8448e3ee, 0x93881bf1, 0x88c23e00,
+       0x4252112b, 0xbf1846ac, 0x42475e1f, 0x2179adff, 0x57ccaef1, 0x1f027de1,
+       0xd36244cf, 0x47137f41, 0xa775f12b, 0xfbd22169, 0xfbf2bb4e, 0xcb1388af,
+       0xc2ac9a4f, 0x24c9b12f, 0xe0aed7de, 0xca1cbb93, 0x9e041372, 0x3cf1ab47,
+       0xc515fccc, 0x01309d2f, 0x54d24c7c, 0x58c9e3fd, 0xb30d6f0a, 0x1cf6c5ae,
+       0xb852178f, 0xbac12eb3, 0x4b44c002, 0xfdb409d7, 0x926c404a, 0x3d22ae8f,
+       0xab189d58, 0xe707e9ed, 0x93761991, 0xee389e0f, 0x1499a0d8, 0xcfe5d22e,
+       0x06913c03, 0x29837ffa, 0xd210c53f, 0xb2f80994, 0x18262574, 0x52d47107,
+       0xde92d3b8, 0xd814da35, 0x132b488f, 0xfdb4e313, 0xdb4bf8fd, 0x3e066911,
+       0xb0cf20b8, 0x2a383267, 0x53f552f3, 0xc131b4e2, 0x5acf37fa, 0x91787809,
+       0xa38e81e1, 0xadf943de, 0x2b5f7d73, 0x2a7210e5, 0x942468ce, 0xa67467de,
+       0x1f5f52e5, 0xea2ee63e, 0x4a95ed86, 0xd0b6efae, 0xc764836f, 0x52cf3023,
+       0xf8cf5b8d, 0xa13a6aa9, 0x6f3f96ed, 0xf748adb0, 0xf8d43fcd, 0x2d23f008,
+       0xc93bffa2, 0x1d7ad2d0, 0xeaeb1752, 0x0bdefc74, 0xddca2ce8, 0x2b17451f,
+       0x9185ef5d, 0xdd60278e, 0xe8b8c3b7, 0xa309697a, 0xaf8e86eb, 0x01932245,
+       0x74e2549f, 0x7e02ca2d, 0x04eba3bc, 0x951297ca, 0x81d1c953, 0x351856fd,
+       0x5e1fb764, 0x757d78db, 0x096655b9, 0x9989f7c7, 0x4dc7ff60, 0xdf30d5b6,
+       0xae293d16, 0xe96c78a5, 0x9a48d3c2, 0xa01bfad2, 0xcf2840fc, 0x70e0edea,
+       0xabe5868b, 0xbee517db, 0xdd9236ac, 0x545fac74, 0xf29bb213, 0x4369e597,
+       0x4bb68b95, 0x147fd2a6, 0xa2dbed2f, 0x453e0156, 0xbce67dbd, 0xdd1c604f,
+       0x802df64d, 0xcd35d98f, 0xfb5f877a, 0xe01f30ed, 0x579b1d13, 0x454b187b,
+       0x45ccfb7f, 0xef1e209f, 0xbcdd20f2, 0xdb0160f0, 0xe1f6fdb1, 0x1fd21e4c,
+       0x72c3ac0d, 0xc5cb0ebe, 0xae53ab7a, 0x04a64937, 0x63f9468d, 0x5aa0b941,
+       0xc67a957f, 0x17ef844f, 0x4ebac4d3, 0xfb42d089, 0x64535953, 0x1fbec35a,
+       0xa64248a5, 0x64b2c91b, 0x21a33f9a, 0x7175e501, 0x1997b3a4, 0x0cd23ce9,
+       0x0ce489fb, 0x5f862f97, 0xe4b4bf8a, 0xd93e312b, 0xa9ed6fc7, 0xf6cf384d,
+       0x81a63f55, 0x786f2ebc, 0xa875e507, 0x191f3979, 0x48f38516, 0xd6e0fb60,
+       0xd9391b6a, 0x059787d3, 0x428f3666, 0x0f40acb9, 0x313664f2, 0x7ea7e81b,
+       0xc3d3fba4, 0x57b95c28, 0x6f285c47, 0x93901a6c, 0x9c63c397, 0x7e2c435d,
+       0x72612df2, 0xf0c96217, 0x688e49c1, 0xdc5c9c05, 0xb53e514d, 0xff22bbaa,
+       0x147d45ba, 0x1ccee9f9, 0xf963dc05, 0xebf94510, 0x7015f26b, 0x536e67ef,
+       0x35c1bf94, 0xc2770141, 0x9e3f202f, 0xca4e5d97, 0xbfae37a7, 0xde7f515b,
+       0xbf4859be, 0x895ebe3a, 0x4994d6d3, 0xd05b30f1, 0x80686e9f, 0x670e52c7,
+       0x68a3ded5, 0xb725b89f, 0xe1cfcb44, 0x69bb31fc, 0xf94258ee, 0x897d6fa3,
+       0x67221fa2, 0xd28e30ca, 0xa18912ed, 0x46a73eac, 0x7bcc4fb9, 0x37170946,
+       0x992cbe3c, 0xf407ea04, 0xdb4b4327, 0xac5d2129, 0xf5a8dfa0, 0x11519e84,
+       0xdd0fc8b1, 0x57c63748, 0x79303e6a, 0x074861f1, 0xf4f5e83e, 0x3e3e01b0,
+       0x19ebe2f0, 0xb9d5f109, 0x7b8e07b7, 0xee3a36de, 0x18fc40f4, 0x10fc9512,
+       0x43f25166, 0x1f928678, 0x7e4aac22, 0xe4ab9ae8, 0xa3be3507, 0x20fe4a6c,
+       0x105ffa1e, 0x568cc77c, 0xbca94df2, 0xefe00f72, 0x5f9e7872, 0x1fe90abf,
+       0xf0a987a0, 0x1af01e3a, 0xff6bc3ee, 0x2625b6dd, 0x61df660b, 0xe478041c,
+       0x197620f8, 0x046c52e5, 0x3e561dea, 0xcca7a14e, 0x107ae288, 0xd69fa76f,
+       0xf7d613bd, 0xa049c932, 0x967fd09e, 0xdcd3bae4, 0xc639df14, 0xd520a02a,
+       0xa2b3ec6f, 0xd32c1ca8, 0xdf21b3bb, 0xefc1ef4f, 0x417bd2ad, 0xa7411ef5,
+       0x7281c439, 0xa61f0025, 0x2f50f427, 0x3f40ff80, 0xff8411ed, 0xed077ea8,
+       0x5179f256, 0x7234b93a, 0x06a4be20, 0x0d911dc9, 0x72106cd3, 0x3fb171d6,
+       0x157ca366, 0x4a0da2f8, 0xe84772fe, 0x817da28f, 0x448f211f, 0x255206bb,
+       0xab7f0227, 0x50c913e4, 0xa9371de2, 0x223ff841, 0x35e80bd8, 0x416f9bc4,
+       0x0899037e, 0xbc4de94a, 0xd30f723f, 0x06a48d4b, 0xb242b2e9, 0x7f69972e,
+       0x4be975f2, 0x7f4ba508, 0x64ffd533, 0xa69b42d8, 0xd18d77c0, 0x773ec329,
+       0xfe60b91d, 0x3f5a06ea, 0xc5f95d61, 0xbff2d098, 0x5b8d8dfc, 0x281f549d,
+       0x2464f4d9, 0x5afaf4a1, 0xa56f135b, 0x2ed6cbf5, 0xb4d1b48d, 0x7d44eb45,
+       0x3c976bea, 0x7f6415da, 0xed8a3f7e, 0x264274df, 0x7c153f90, 0x795fa72a,
+       0xd7ac1c6c, 0xccead6ef, 0xb9522d32, 0xd036e0de, 0x375151f5, 0x46c92c7f,
+       0x8fc199b8, 0x54f8037c, 0x5e4a1b9f, 0x82de327a, 0x5933a3fb, 0x3ba90893,
+       0x62b4d099, 0x81463fcd, 0x3a49567e, 0xd4b8c196, 0x1fffa0f5, 0x595afee8,
+       0x77d4cf2b, 0xe11e720d, 0xb5d05aeb, 0x6fb1eeb2, 0xcdf848e4, 0x557e07a3,
+       0xbd062f97, 0x3b67ea8e, 0x89bb3c84, 0x45eb04dc, 0xe2b883e0, 0xdf93ef50,
+       0x99bb2178, 0xf66badc2, 0x787e4a47, 0xc421e422, 0xaced674f, 0x0969bcbf,
+       0xaa36874d, 0xfe5e90d7, 0xcf585cf5, 0x9ee12f52, 0x5a581a4a, 0x0e4773a6,
+       0xb654aca5, 0x687a874a, 0xaebfc6d9, 0x33c533fb, 0x5eb06639, 0xdd2fdb4f,
+       0x43c7f6f8, 0xa6bfbe40, 0xa6cb1d8b, 0x7de29261, 0xffa4a974, 0xe8f8e516,
+       0xdbfaf250, 0xfb164b7a, 0x8fb460fe, 0xedafa51e, 0x40ac93d4, 0xeed4147c,
+       0x414c7bd4, 0x3cdb52e8, 0x1e02648a, 0xdd03d27e, 0x9121debf, 0xf820f484,
+       0xa476f55c, 0xe909e383, 0xa5e4e9c8, 0x5cfabd5b, 0x412bf4c9, 0x2bbe7527,
+       0x0afa8cca, 0xca7a87b4, 0xf6ff1b1b, 0xf14fc526, 0xcc2b0627, 0xf76ff8bf,
+       0x4e3cc245, 0x5f18ab69, 0xde34b0bf, 0xd62dfb46, 0x98cde339, 0x2fc5efb2,
+       0x6df91afe, 0x8ebf87de, 0xd93fa827, 0x38b93492, 0xdf9824cf, 0xc4efe79c,
+       0x0e25cdf9, 0x17e2bbe4, 0x9fe83b64, 0xf464b5e7, 0x45d6416b, 0x175b3441,
+       0x15d356a7, 0x4a77e74d, 0xf38044cf, 0x8b5aeca0, 0x517bd287, 0x28dafc18,
+       0x8402ffd6, 0x9d191bcf, 0xf86b45ba, 0xdf4ba2ba, 0x3cd75f9f, 0x39f404d2,
+       0x004b6a9d, 0x6892af3d, 0xd21f1c9d, 0xfcaeda45, 0xa3026161, 0x8568b10f,
+       0xa8f2a47c, 0xf943be00, 0x2c2d9d26, 0x5c8f515b, 0xbff5f74c, 0xc74ff790,
+       0xd0f405dd, 0xf5c1f153, 0xa668caf2, 0x269fd327, 0x7e5fc7e2, 0xf7ad9beb,
+       0xf5b28f35, 0xabbbd62d, 0x7fe43468, 0x1fad887b, 0x839c97a8, 0x602772e3,
+       0x243bcefe, 0xe2060794, 0xd7aeb60e, 0x56baf8e8, 0xa13e0be6, 0xb9c2d6e3,
+       0x842fcbc7, 0xf14e6f9d, 0x27dcc8f3, 0x7dbf3d68, 0x8bfa12be, 0xac4f6c0c,
+       0xfd7c79db, 0xf7cd1cdf, 0xc9febe5d, 0xcf4171f3, 0x5b73eabf, 0xeeb5ce99,
+       0xe95eb0cf, 0x605a74fa, 0x30eceabd, 0x761b33ef, 0x5d377c7d, 0xc56a6727,
+       0x4fca553a, 0xde2d3af5, 0xa7f236fc, 0xa99e9d7a, 0xe83e3b7d, 0xeded7d3a,
+       0xb0664f78, 0x2bbffa75, 0xe6fe053f, 0xa7e52b46, 0xf0a18790, 0x728796a8,
+       0xa9f105b4, 0xe7f48796, 0xc8141910, 0x04ef827f, 0x5abc95bf, 0x1dc81d7e,
+       0xbe0a5f2f, 0xe0a5f2f3, 0x957cf53b, 0x5be753f8, 0xf9472ce1, 0xf0edbec4,
+       0xcf4a64a8, 0x6ac906b2, 0x3dbd60b0, 0xd93c5300, 0x35231b70, 0xfd63927b,
+       0xae0a9761, 0xa9b79555, 0xbcaabb60, 0xa9570543, 0x5c70bbca, 0xf4bbf565,
+       0x5b81e504, 0x10f75e51, 0x3d804671, 0xad7651a1, 0xa76ca8a6, 0xeb465e63,
+       0x47486fb7, 0x12697b7d, 0xc474dbb3, 0xfc8197e9, 0x4477376a, 0x75fc5346,
+       0xb373f184, 0xca3223bd, 0xdcd32ecf, 0xf5fca320, 0xdae8c8b8, 0xaa1af620,
+       0x3cfd2249, 0x62fe5424, 0x4d90bf66, 0xef408b69, 0xa0ad91af, 0x3c5ecd0b,
+       0xcef41229, 0xe31e86f6, 0x73efd327, 0x43baa1f6, 0x903db9da, 0x49b4039e,
+       0x38b3fe94, 0xe710b63f, 0x7ce8c353, 0xa2943566, 0xa57b3e3e, 0x4d735e92,
+       0x9ccf510b, 0x1efd04fb, 0xe12fdf44, 0xaf3f14ed, 0x2b212fcc, 0x1d289f91,
+       0x297760f5, 0x77cca359, 0x2ecffb70, 0x48fde7c1, 0x87b9c53f, 0x3942d5cb,
+       0xb064fc73, 0x0995ec57, 0x836749f0, 0xdcef788c, 0x9e08b920, 0xa83d986b,
+       0x3ca07482, 0x8569f813, 0x2d0fa0f5, 0x7cb75a6f, 0x5a01e83a, 0xf1eb6ca4,
+       0xda68e7ec, 0xaf58f5ba, 0x71bf00ed, 0x0938ed24, 0x08ed3fb2, 0x64dda1b3,
+       0x00cb8447, 0x3f7c6ff4, 0xa3b401ed, 0xce30ac18, 0x67df1df6, 0x3fb4df03,
+       0x79062864, 0xecca9ed5, 0xbf1a4b23, 0xe57266cf, 0x5b57a461, 0x37e99eb4,
+       0x99fdff0d, 0x06fae704, 0xf7d82b3a, 0xf9e38477, 0x30cdf2ad, 0xbff6c117,
+       0xfd30e41f, 0xd0a9f372, 0x61f20713, 0x19bc9904, 0x704517c6, 0x07db953e,
+       0xed3175ff, 0xa76ebcbf, 0x2fcd167e, 0x6ca7eb78, 0x37db0fd8, 0x4da67d33,
+       0x5dd2b847, 0xad1e68f2, 0x61c616d7, 0x056eefe7, 0x160db77d, 0x9e423747,
+       0xab70d98e, 0x4f0c14d3, 0x5e21a53f, 0xd13f10ae, 0xfbe47a31, 0x48fc7d7f,
+       0x2bf28236, 0x609465c2, 0x767e3fde, 0x0ec1e41c, 0x98a9f203, 0xc5da99ef,
+       0x6e5c7fa8, 0xfe62fdde, 0x4ae2f85d, 0xafb92de7, 0x7ff6de64, 0xe21f7a71,
+       0x5d7aa8fb, 0xe379f204, 0x8c6f08fd, 0xaf78e2b0, 0xfeabdf90, 0x337dd1af,
+       0xe5e47ba5, 0x7fc7fde7, 0xa68779f1, 0x9ce9befb, 0xc3b066ee, 0x13f5be55,
+       0xe56aef8e, 0x537fa6dc, 0xba7a17be, 0x3890befa, 0xf0a5a225, 0x744f0e70,
+       0xd2e79e4a, 0xc388f77d, 0xd2113a79, 0xdd475048, 0xcad38f27, 0x2a4b24c3,
+       0xde132828, 0x7a071dec, 0x8aa932cb, 0x4737eca8, 0x6476d3b7, 0x940c474d,
+       0x2d0e242b, 0x217217bb, 0x3c91df1e, 0x15f9d768, 0xb4852db1, 0x9a8ed482,
+       0x3bdd6902, 0x97b42547, 0x923f2184, 0x9e3df57a, 0x0d11f516, 0x1de8019d,
+       0xce2b00a5, 0xbe9f5a77, 0x8bc20722, 0xa293d8e9, 0x313f7f2f, 0xcfccd63a,
+       0x58bd1d7d, 0xc46fd33e, 0xfbe8727d, 0x66f8e55c, 0x4ba76699, 0xf36f41dd,
+       0x8c15c71b, 0x291e0093, 0x3ca6de9e, 0x7bfaa463, 0xd1d1dc12, 0x618fecf1,
+       0x72ef2df4, 0x141b63e2, 0xe694d01b, 0xa9563f7f, 0xec193627, 0xae0d5b24,
+       0xad4fd0b5, 0x1b4ddef2, 0xa1dbcecb, 0xef13d0f1, 0x421e0453, 0x3efaabf1,
+       0x1be80665, 0x667c6103, 0x74c6f8c5, 0x29631bb1, 0xf3d47a9c, 0xd5f1a495,
+       0xd75b942f, 0x60fa073d, 0x2b7fd33d, 0xf57bb386, 0xda326d8a, 0x0c1ada0f,
+       0xb18e892e, 0xde177eb8, 0x1b56b4c7, 0x9eb7dc09, 0xab48eba6, 0x55fe04bd,
+       0x371c0df3, 0xcd67075b, 0xea86a746, 0xee5896d5, 0xb24d908f, 0x3fd31e61,
+       0xcd31173c, 0x9ede7682, 0x5e76feb1, 0xab37fdef, 0xedcf9017, 0xedef54c0,
+       0xcce2f20a, 0x65ef04fd, 0x6d23b689, 0x1cbf9642, 0x23a3ce50, 0xa9e3d186,
+       0xb4167b68, 0xf294dcd7, 0x2857b414, 0x06e9ec37, 0xcec859f8, 0xc40c2359,
+       0x64e94619, 0x56b5ef90, 0xde95c9f9, 0x9cf196bf, 0xfbc2e9fd, 0xfa6567a2,
+       0x692dedda, 0x741eecec, 0xa5bf67f3, 0x988ef4ed, 0xd3daf78a, 0x93bcec0c,
+       0xbbb87f7e, 0x6f5f5d07, 0xf81189e9, 0xeabdd74b, 0x4e70ade0, 0xabad928a,
+       0x32b17f69, 0x217c0919, 0xce1b1bc6, 0xe7be23e6, 0x0246b0bd, 0x8fbe22f9,
+       0x7fd1d258, 0xb1f54d01, 0xf8c53f8c, 0xf4741446, 0xf0f932af, 0xe7e466de,
+       0xd716b319, 0xb4c3b093, 0xec0979c1, 0xeb0e7024, 0x3db7c84b, 0x5e1f786d,
+       0x20ec4611, 0xdb35bef7, 0x7ce146ba, 0xb66f782c, 0xb7acacd0, 0x04fcd3f0,
+       0xa0571f28, 0xe91787bc, 0xc76658ac, 0x4341fb29, 0xe2767e9c, 0x0f5bad32,
+       0x1fb281f6, 0x77e9c4f4, 0x9d05fc0f, 0x5cefd3b7, 0x4f4b4f7e, 0x22cc27b4,
+       0xcc27b456, 0x9c4e1e5a, 0x3aa2e77e, 0xbd350e3e, 0x56fa71cf, 0x96896944,
+       0x2242abce, 0xdb954bf6, 0x9f764ffe, 0x23ff1eaf, 0x70e36eb0, 0x779fb87e,
+       0xab5c1a34, 0x9dcb03d3, 0xb8f6618b, 0x3dc51bf4, 0xc5cf07bf, 0x25e5b70b,
+       0x8aed2090, 0x1b07e2b4, 0xa5e1f971, 0x7983d682, 0x9230fc56, 0x6f07fab8,
+       0x66f982cf, 0x81cede05, 0x5fe81a7c, 0x4df1163f, 0xb091c44f, 0x97a95e7e,
+       0xf13d8347, 0xd19abd95, 0x678c83ab, 0x9f679f03, 0xf5f22d38, 0x5b626e8d,
+       0xa29e8415, 0xdb347c5c, 0x459f0117, 0xa8788159, 0x074cf7cb, 0x2469b87e,
+       0xefeb05b1, 0xc42f9c2f, 0x19a2ebb8, 0x18762b7e, 0xdb405ed0, 0x011455ed,
+       0x71733ddf, 0x74959b3d, 0x8d863cfb, 0x4f36eea3, 0x76d3f41a, 0x083ff72b,
+       0xe173df41, 0xe018f68e, 0x30b449c3, 0xda4187e5, 0xb7ecc92a, 0xbe94ae3e,
+       0xd6ac3f15, 0x102bd3f9, 0xae74ebef, 0xc576befe, 0x22f3643d, 0xe6def519,
+       0x95fefc83, 0x62eee3db, 0x499a4cac, 0x97b02ed5, 0x68495734, 0x41dbbbc7,
+       0xdeba22c8, 0x14b87aef, 0x97d34ded, 0x8234bebe, 0xca907f7f, 0x0912bb8d,
+       0x77a699b9, 0x09da56cf, 0xb70596a6, 0x3f7839a7, 0xfa0748d3, 0xa85f4cf9,
+       0xfb702fb2, 0xe541e383, 0x17e02ff7, 0xc60fd72a, 0x0e43bb72, 0xbd7901c9,
+       0x3d39e960, 0xf8a109a8, 0xc3ca85ba, 0x8b905a9e, 0xab5b4c46, 0x157e98cd,
+       0xf604fb6b, 0x8eb1f3a5, 0xb6ee414f, 0x52e4c87f, 0x4c73cae7, 0x418f2f9e,
+       0x2ef2c73b, 0xd78dff6c, 0xd3ea3b58, 0x3e3efe41, 0x8fc51c71, 0xeb5a2fe1,
+       0x9b878a12, 0xc0d3353c, 0x35e84525, 0x905aac8f, 0x127e8b11, 0xefc041d6,
+       0x32deafb1, 0x7133ec1a, 0x00db86af, 0x5cf22b7f, 0x62b18f78, 0xe7f41771,
+       0x0fcdd232, 0x0d8f7ae4, 0x3fb81a79, 0xb16ea1bd, 0xd76d1ba6, 0x0dd3b0dc,
+       0x35cb0efe, 0x6b3da0df, 0xf984cdf9, 0x287ef17f, 0x6919fb3e, 0x4c13f13b,
+       0x171d2f78, 0x50d44aee, 0xbd46ee38, 0x17ea0975, 0xe0a95f4c, 0x2c976834,
+       0x7e0a1c7f, 0x8264fb64, 0x16b13e7e, 0x087daf94, 0x0b92bfb3, 0x0f945f14,
+       0x8fc40c60, 0x2dab5aef, 0x92fc9f68, 0xd0fb29db, 0xce8ea1f3, 0x4f8a2be7,
+       0x6a1ecb80, 0xebe3051a, 0xabac48d8, 0xb7d89169, 0x912df292, 0xea337780,
+       0x13aba7bb, 0x16e31531, 0x6bd947fb, 0x3f41a36b, 0x9999229e, 0x43d7095f,
+       0x10121f05, 0x4c9e1456, 0x8bbf9c98, 0xa8539feb, 0xe3a30dd8, 0xd35887bd,
+       0x46dddea0, 0xf8a1a912, 0x3b50529f, 0x5299f710, 0xe7ec145d, 0xe30542a0,
+       0x8bfa5087, 0x72ea2758, 0x81af41a7, 0xc98db8f5, 0x11758a83, 0x6bbbb44e,
+       0xecffb03a, 0x7b1ebe38, 0xd22e3f31, 0xfd60d893, 0xbde8ec54, 0xa062e80a,
+       0xa5e303fc, 0x9b98ca72, 0xd19cfa83, 0x7f3fe748, 0x8a5b987b, 0xd9a7a3f4,
+       0xfa034fd6, 0x1c9484fc, 0x4a3a97f4, 0xd80447e5, 0xb8693c71, 0xeb47419e,
+       0x7d5cc306, 0x54ebdc1b, 0xfb30dc50, 0xee0ccbce, 0x2d6761c6, 0x7978d383,
+       0x777066e2, 0xdbddff51, 0xc743fec0, 0x621fcbcb, 0x1f011f70, 0x45b3e566,
+       0xce0c63f9, 0x1927f911, 0x7fb4483c, 0x1843c18a, 0xd3c9fc7c, 0x0f4139b7,
+       0x8ffae289, 0xaee783d5, 0x6b7b378a, 0xde96fdfc, 0xf3726389, 0x772b1874,
+       0x98cc9d3a, 0x08cbf400, 0x5e55fe5e, 0x02c5e85e, 0x493ea27f, 0x266f5e0c,
+       0x80bf37af, 0x64e129eb, 0x5bf31879, 0xba524675, 0xbde86eee, 0xc617ca1a,
+       0xd03a7345, 0xdaf80676, 0xed11f411, 0x244b7e89, 0xe9b497a6, 0xbbd89d98,
+       0xfdb1c66f, 0x30f3f684, 0xd293d3f6, 0x909bda15, 0x81f80fd2, 0xf39681f2,
+       0x80f81681, 0x7c6c5590, 0xc028ddb4, 0x3fa3b9b9, 0xbeedbff8, 0xfba7cb40,
+       0xcbe6adc6, 0xcddf3807, 0x81cec25f, 0x703d511d, 0xce1118bf, 0x403244f4,
+       0x380f8f39, 0x8b89de1e, 0xd2f4f362, 0x7ec24125, 0xa63c7096, 0xc84d7a78,
+       0xff79faba, 0x97e78f9e, 0xbd1fb79e, 0xd7e4326c, 0xcd9ab0df, 0xd60bd187,
+       0x85ea3447, 0x3bda2b8f, 0x3f5558bd, 0x98702e97, 0xac0f746f, 0x311848ff,
+       0xdab277e2, 0x9b3d2f5b, 0xc7a0abe9, 0x27ca2f96, 0x74ff6127, 0x85f78cde,
+       0x952a5c65, 0xe3d26f2f, 0x64ad6bfd, 0xef3cbf43, 0xe00ec73c, 0x79f334f3,
+       0x5d3cd99a, 0x87257e0a, 0x88eed23a, 0x2f63e408, 0x65edbdfe, 0x14f6f0e6,
+       0x7b582372, 0xd1422720, 0xd34bfdc5, 0x85538c45, 0x559e2f4f, 0x84f813e3,
+       0x32f58df5, 0xc6297c95, 0xf5a87af9, 0xfb33fe9d, 0xcaf563cb, 0x08e9437f,
+       0xc945a7fa, 0xe975e5d7, 0x7d327b9a, 0xae8036f5, 0xf3f3e717, 0xfdc71939,
+       0x0a485286, 0x7cce0fec, 0xfec37562, 0xfb80d9b9, 0xfd92e7fe, 0x505c5c54,
+       0xaefc20ff, 0x47b6173e, 0x1bec09e9, 0x7b40fb6a, 0x06c9b59c, 0x0967e5f7,
+       0x550edffa, 0x6fc033d9, 0x57c9b373, 0x295fb7cf, 0x4cf111e1, 0xc3b40cbf,
+       0xe68a7dd0, 0xb868300f, 0x018dd73c, 0x5c203d79, 0xf0d57705, 0xe0c8c4fd,
+       0x293b0e04, 0x2034f14c, 0x3187e459, 0x3f513af8, 0x51bf958c, 0x5f70e794,
+       0xa208fe55, 0xfdb28784, 0xb0a9e624, 0x20ff7031, 0x78d8a0f4, 0x2e43ce0b,
+       0x4be010d0, 0x80d53803, 0xc196f5be, 0xa08d7a05, 0xce94a853, 0x3dd82ab3,
+       0xf0bc6a7e, 0x977e6033, 0xbb40f2e8, 0x047615ca, 0x4761568f, 0x3a348f68,
+       0xc768aee5, 0xadf605eb, 0xf747788c, 0x32bf5a78, 0x3a7a75bc, 0xff0a1f85,
+       0x256cfd0c, 0x258fd31b, 0xa54c998b, 0x575a95e3, 0x23df41d8, 0x16a35625,
+       0x4aedc4e9, 0xe94bf770, 0xcbc77db1, 0x6eb3240f, 0xc18e30ec, 0xee54ae5c,
+       0xe3bbf1f8, 0x369fffb0, 0x7dfae159, 0xf7b3c370, 0xb838be81, 0x4c8fff61,
+       0x5fa1304f, 0x60f718ac, 0xdfa29bf0, 0x380deb73, 0x370dc1fe, 0x43f281cc,
+       0x01e86a3f, 0x84fc377c, 0x9988097b, 0x9237c6f6, 0xb91f281d, 0x25392c9f,
+       0xd5c19c41, 0x7c5e45ea, 0x7e8f43fc, 0x231f141e, 0xcc2e3e19, 0xc5b4fc05,
+       0x41e65c1d, 0x8b0a62a3, 0xe9f5e067, 0xb9fd03b9, 0x2b17493b, 0x23db5dd8,
+       0x3b6a3b58, 0x3a22d1e4, 0x787dfa3f, 0x9f811d07, 0x07e23fde, 0x3e4c1523,
+       0x29448f38, 0x926302e0, 0x39a17ca2, 0x4b7f915d, 0xfc8a0de2, 0x14fd2d5b,
+       0xc18c98f0, 0x5bb7f28a, 0xf8f014f3, 0xe5155bdc, 0x0a456c8b, 0x56bb9fb8,
+       0xdeffbe51, 0x21fe657a, 0x721d0322, 0x41775a8e, 0x1b4bf03a, 0xb507359a,
+       0x7482ed54, 0x1d0cb7f0, 0x90ec3b6a, 0xc1776a1f, 0x15876177, 0xce30f0fa,
+       0x3b2ec22f, 0xf4b93649, 0x89afedc1, 0x959e9a5a, 0x649f283c, 0xafed1d8d,
+       0x078e61c9, 0x473d29e2, 0x2814aa91, 0xb0ec0237, 0x33850894, 0xfc01fece,
+       0x32a73aad, 0x2051dc7b, 0xbbbbc80c, 0x788ed022, 0xf1b55754, 0xce43ea38,
+       0xc3a39054, 0xe62b263b, 0x8707e23d, 0x6479de62, 0xf74e8abe, 0xf342e02a,
+       0x6fe5146f, 0xc8ac5c49, 0xa8f2d5bf, 0x2b8f4e8a, 0xcfaddbe0, 0x4ab4e8aa,
+       0x1597a745, 0x1bbf82f9, 0x076c7db8, 0x3a68b5d8, 0x0054d3cc, 0xa5b9b874,
+       0xdb91e903, 0x74005354, 0x16b4721a, 0x6dc035e9, 0x3bf1002f, 0x2ed56f68,
+       0x5cf4dd48, 0x4efef503, 0xee9035cf, 0xb023e7a6, 0xcea9ed8f, 0xb56f74c0,
+       0x5bbfbf15, 0x7be98b9d, 0x3f4c36d5, 0x698d1ea8, 0xd31db553, 0x2c5aeada,
+       0x9ebab9bf, 0xf862d7d9, 0x0bf1473e, 0x38368c76, 0x9cbca253, 0x0db2f28a,
+       0x5f2850ce, 0x177066ef, 0x0c29930e, 0xebe5648e, 0xf2829a9f, 0x8cf83f74,
+       0x30bf81c4, 0xd824cf4b, 0xdd3409ec, 0x8186e70b, 0x5a89b8be, 0xe4a7688d,
+       0xb1eb9031, 0x525fbc31, 0x4296c632, 0x5ec5d2c8, 0xc18431f8, 0x2307eb28,
+       0x1bc1f8b3, 0xe21b6b61, 0xc61edfab, 0x97c6f7f2, 0x4173818c, 0xf330fae9,
+       0x29747e97, 0xc0528daf, 0xe649f595, 0x88e8fd2f, 0x7654c97e, 0xe5091492,
+       0x36c3d09f, 0x20438e48, 0x1e8dca7f, 0x1aa627f4, 0x6c2bfa30, 0x8044b16c,
+       0x85e0ea5d, 0xcf8011de, 0x672edc83, 0x3374fd23, 0xeda79a69, 0xff7d83a7,
+       0x124f4aa8, 0xef2941e9, 0x56b76853, 0xf413bd63, 0x3a6de724, 0x413ffc02,
+       0x51007662, 0xa604ddee, 0x6edfb4af, 0x21e0f3c0, 0xc60e6d8d, 0x9f024811,
+       0x149f718b, 0x11c2f7f3, 0x7489df22, 0xf9128f6b, 0xe5538e1c, 0x1d60a927,
+       0x5f19df2b, 0x05fe748d, 0x904ff9f1, 0xca7c6a0b, 0x97a66609, 0xa0a96db9,
+       0x50f808c7, 0xe41cad91, 0xdb3ca1c7, 0x83ef30f5, 0x17930376, 0xf5d708f6,
+       0x0db33768, 0xfecfd3bc, 0xc3a09d55, 0x1f00777a, 0xddc4fdc3, 0x3515ca32,
+       0x604a5ffe, 0x15f22afa, 0x0aefbb9c, 0x21cd73c7, 0x1cde290d, 0x387b5e84,
+       0x0974ce1d, 0x277df76e, 0xf9fbed81, 0x6e37cb13, 0x85cf7b81, 0xbb74d861,
+       0x93ea37bd, 0xf31255ed, 0x3aa96903, 0x560df2cb, 0x33f4128e, 0xd1bf029f,
+       0xf70d8dfc, 0xcb4c3f9d, 0xdc30b67f, 0xb9967b8a, 0x6eefe20f, 0x8c5a785e,
+       0x69bff511, 0x61f35213, 0xfdc29e1f, 0x6847a79a, 0x59bdd1e3, 0xd337a51b,
+       0xfa9b6676, 0x2418a32d, 0xf48b6373, 0x4e2e1451, 0xa41977b9, 0xd71f3d25,
+       0x595dd5c3, 0x40cb6be6, 0x22a72f0d, 0x5bca2063, 0x74d5fbcf, 0xc916335c,
+       0xe51e7616, 0xf4adb8fb, 0x045de2aa, 0xf1e21fbf, 0x78091447, 0xf1cbdede,
+       0xe5edea2d, 0xe0482af8, 0x245922f7, 0xb8aca2eb, 0x0125b8f7, 0xbda63dee,
+       0xbdc42bdf, 0xeb9f3288, 0x59eb1fbf, 0x75eba5bf, 0xb9104f2e, 0x9d812fbc,
+       0x89e90f9b, 0x9d55ee0d, 0x277db377, 0x87b9f27b, 0x67f9d206, 0xe8359837,
+       0x7ca33457, 0xb3a1d00b, 0x4751d39e, 0x4dfd61ea, 0xecfcce74, 0x96261230,
+       0x5e1fc7f8, 0x36b67f6e, 0xf7fc0b99, 0x7b1e01e7, 0x9cfeff81, 0x005351db,
+       0x8fd8b0fb, 0xbba83dc5, 0x03ef98ba, 0x77bf2855, 0x78422f57, 0xd313b54f,
+       0xf9cbd5bd, 0xf983503e, 0xc33f55ef, 0xdf1701f7, 0xf7e3d607, 0x98c9ea86,
+       0x6076a8ee, 0xbd8ba63a, 0x1df4e402, 0x47c60746, 0x81acfdbe, 0x675e7dc0,
+       0x47e30183, 0xf1788ae8, 0x538858b9, 0x58579832, 0xd495e302, 0x1f978afb,
+       0xb3fb7e54, 0x0b7ed8bb, 0x99e378fd, 0x2ebd3f40, 0x241d3f34, 0xdf390e5c,
+       0xd0743945, 0x07d6e42c, 0x7808b60c, 0xa2ad833f, 0xf72807fc, 0xbe78da0e,
+       0xed833f73, 0x601c9f3c, 0xefc043b0, 0x944ab831, 0x73dac03f, 0x063df80a,
+       0x4df288d7, 0x7831760c, 0xa21fd3ed, 0xd223cc5c, 0x056f586e, 0x2091f4c6,
+       0x79cd0b62, 0xdd9d61bb, 0x24733892, 0x826333ac, 0x56fcf905, 0x00dde2cb,
+       0xa558c98f, 0xcdba1305, 0xa861efd4, 0xa45b1f97, 0x53237a85, 0xea187dee,
+       0xb8f9ea8d, 0xe8debfd6, 0x061ed7cc, 0x9575ac78, 0x236bf416, 0xbe81c5c8,
+       0xf22c0476, 0xe2213ec5, 0xd836faf0, 0xaeca3f71, 0x247ee3b7, 0x477f9cf0,
+       0x9c3352d1, 0xb325ea03, 0x43b8e304, 0x404f06f2, 0x05c5630c, 0x1e291aba,
+       0xe13c12ea, 0x2b3ce98b, 0xf0821e01, 0xd97f8b63, 0x109dd5fd, 0xc2383f64,
+       0x2be807e5, 0x23ffb445, 0x3f835d74, 0x4bc70442, 0x88ccc365, 0x755e7899,
+       0x189e8044, 0x0490f5c3, 0x2dfe6948, 0xbfcb1d3c, 0xef6c941f, 0x30f8bc82,
+       0x03b79f81, 0x1861cde5, 0x73279507, 0xe40238d9, 0xcb9f328d, 0xdf62239b,
+       0xb2e2c01a, 0x8b0d49cb, 0x7c4cbee7, 0xb8dc405f, 0x84a71e2a, 0xa5b1eed4,
+       0x6f178b07, 0x2e2f1a0a, 0xfd031bfc, 0xb0b9f96d, 0x93cf930b, 0xc3d17641,
+       0xb9686760, 0xab971dfb, 0xcca0f0a1, 0xe0e285ff, 0xf90e2389, 0xbc3c5423,
+       0xf9c08be0, 0xb6f3b0d5, 0xea9fe196, 0x81c4c69f, 0x8823bf20, 0x6794ab1c,
+       0xcf212f87, 0x97f1f2d4, 0x6693bb92, 0xfdc1a794, 0x98b91043, 0xcb54e30a,
+       0xc93e6745, 0x7505fb80, 0x0a68f42a, 0xd3de213b, 0xed0c23b9, 0x8e31f514,
+       0x0fd0448c, 0x83be3bf3, 0xeb122d78, 0x371c3c41, 0xf6846e39, 0xbff33d25,
+       0x2dcdf110, 0x753f7d5e, 0x7923c62c, 0xfb0a7bf5, 0x9efdf7e9, 0xf20b1d49,
+       0xdec9bbad, 0x1921da1f, 0xc85d1fcc, 0xbef1508f, 0x3ed91343, 0xff92981f,
+       0x8e5838b7, 0xae7a369f, 0xf4e74dda, 0x62bf86ce, 0x57d9ccdc, 0x56c1c79a,
+       0x265dba5c, 0xb68f8a46, 0x0dc4110d, 0xe52d1be7, 0xd4969a3f, 0x2b8c36c9,
+       0x4d07bad2, 0x5bd7f08c, 0xe974ff98, 0xcadc08a6, 0x5c1b364b, 0x92fd6963,
+       0xd1b327ad, 0x0ea1f5af, 0xbe730fbc, 0x22d75922, 0x13d93cfa, 0x1b594fc1,
+       0x353e4edc, 0xad87e991, 0x8327c2db, 0xbf5a56bd, 0x25deed13, 0x707493b5,
+       0x4dca2a0f, 0x3e21d44c, 0xa7b43968, 0xb8965f3b, 0xe41eeb1e, 0xfc2caf7f,
+       0x665f5bb7, 0x7a92a976, 0xc60c2b9d, 0x36b5feb7, 0x3929c788, 0x4dfb406a,
+       0xf46ffae5, 0x4d82c740, 0x1f01231b, 0xd932f595, 0x550fbcad, 0x97ac41c6,
+       0xe3f006dd, 0x7f472baf, 0x23370a6e, 0x1e3c1b5c, 0xfafe72e8, 0xb71a9ba5,
+       0x4b0a293a, 0x12297f5f, 0x374e29e2, 0xbc048dad, 0x192f76d3, 0xf7101487,
+       0x25e8fb50, 0x134e1ee3, 0x134b03c6, 0xeb237155, 0xcb71b863, 0x3fdfc83d,
+       0x274787c9, 0xf3c6f3a3, 0x5e5c422f, 0x2f33e6eb, 0xfecb78c2, 0xf045ee79,
+       0xc23b26cf, 0xad0f60cc, 0xc630e57c, 0x7f7a8935, 0x627a6449, 0xe12fcbdb,
+       0x31db6a3d, 0x35b7afa6, 0x6dbe429e, 0x78c7ed7b, 0xd85af388, 0x0efe8858,
+       0x2414b70b, 0x02e72090, 0xbadf0291, 0x4d1e20ae, 0x755daf4d, 0xfc8fd0bb,
+       0xe837a52c, 0x9638dea1, 0x171672da, 0x2bf1e164, 0xfdc7821b, 0xd4abc405,
+       0x1c3f1c4d, 0x3a75e2ec, 0x415c85ab, 0x4a21cadc, 0x4057bec7, 0x728f0dbf,
+       0xf4e0fe7f, 0x50bf0b3b, 0x2a26353a, 0xd7ce56e3, 0x9fcbf9cd, 0x262eaf21,
+       0xfb8adc64, 0xe226f00a, 0xda24570a, 0x6c3c82f6, 0xc62afcdd, 0xc6dd0109,
+       0x6db689d2, 0xf1069f3c, 0x8eba2d98, 0xc1efdce9, 0x25acf70c, 0xfd70478d,
+       0x10f96db4, 0x8f08f6e3, 0xde236bef, 0x258f161f, 0x89ae79f1, 0x1c2ef160,
+       0x030f10ff, 0x3bf4d0f7, 0x7c617b8f, 0x4261e22c, 0x4c5cc1c5, 0x2df6ceec,
+       0xbe58ef1e, 0x2b8f38e6, 0xca4bd1f1, 0x5f353a05, 0xe048be32, 0xb8780cc1,
+       0x2bae3fc9, 0x3791bc78, 0x0bd38ffe, 0x5cf107e8, 0x0a2db8de, 0x3a58430f,
+       0x83c88242, 0x1e2c55b6, 0xe3ff7d4c, 0x3843cfa3, 0xd152ffaf, 0xf433cc59,
+       0xd3ad9239, 0x6aff8dcb, 0xd12673f1, 0x127388a2, 0x10bd6a78, 0x26a78e5c,
+       0x67eafdb1, 0x00b6b7eb, 0x092536fd, 0x66badbf4, 0xe62b7e85, 0x05754adb,
+       0xafadef90, 0x960c77b0, 0x3942eed5, 0x141796ae, 0xf760b62f, 0x98937d0d,
+       0x67a8aa9c, 0xe6eb44fb, 0xb6899708, 0x6df7fad3, 0x1b15cfc8, 0x8fb0f59a,
+       0xbaff59ef, 0xb317f99e, 0x84fb03f5, 0xadfc6fcb, 0x8d99db7f, 0x09fa1b72,
+       0xbce1d742, 0xe086ca9f, 0xf86e54fd, 0xa94fd146, 0xfccf56b3, 0xdfdd2e8d,
+       0x126dad69, 0x49ba77b4, 0x7269a607, 0x6df996ba, 0x24b7fba9, 0x4abdf8e9,
+       0xa8f7d70d, 0xc83f47bc, 0x9c271e61, 0x51c3735b, 0xc5e6b63e, 0x35a45da3,
+       0x6965af55, 0x7fff842f, 0x935bfbdb, 0xbfac8d72, 0x371f1851, 0xd6e8c62e,
+       0x8073f5d0, 0xaf513fbf, 0x00fff677, 0x8707cfee, 0x78e3dfa1, 0x4dbefcc9,
+       0x6827bc0a, 0xdf3537dd, 0x5f781d92, 0x91912ad0, 0x65279512, 0xf0a59acd,
+       0x0fef6aed, 0x477d16ca, 0xa19d1de0, 0x78102e8b, 0xefeae7df, 0xb3a29a13,
+       0x70b7602d, 0xfa6d812c, 0x829ad6a6, 0x597216ae, 0x0edcef3f, 0x67b012d7,
+       0xdec0b88c, 0xba4a18b7, 0x4daae158, 0xfccfddca, 0xbeaa79be, 0x31ae9877,
+       0x83ddf4b9, 0xe7909fbc, 0xdc82481e, 0x867b8837, 0x8ac730e4, 0xf71081a4,
+       0xc01beecf, 0xe4f915f3, 0x3fa6c7b7, 0x3081e780, 0xe71573f4, 0x27f58d99,
+       0x9fac60e3, 0xb93dc537, 0x34af7e9d, 0x79f8877f, 0x8f9f8932, 0xf28ac4ac,
+       0xf50f7e4b, 0xfb25cff8, 0xfb8a49b3, 0x08b9ef58, 0x63efabbf, 0x8cee7f85,
+       0xec276597, 0x0dbf85a3, 0xc608781b, 0x03961751, 0xc31fd8e3, 0x980641fd,
+       0xf1401f6f, 0xf5cb7673, 0x5b3fe039, 0x9eefb5e4, 0x88bcbd47, 0x338963db,
+       0xafd876f3, 0xd7bd848a, 0xdcf961e9, 0xd9febbde, 0x3ac3b7de, 0xa1c1fe14,
+       0xa2c56de4, 0x421f9137, 0xda12cbe6, 0xa6e4c939, 0xbd3f22b4, 0x072e4df9,
+       0x397efdc4, 0xa78b0bf7, 0xf68dc8d3, 0xbc5791f9, 0xba46e611, 0xcec4d97e,
+       0xe976dbc5, 0x09af1d99, 0xa78f21cf, 0x7c02de3a, 0x81da2c55, 0x762626f8,
+       0x6c96396e, 0x1d31fee6, 0x0eae5099, 0x6eb027ce, 0x7da184b6, 0xd1eb4136,
+       0x2ab8e95b, 0x8bf4128e, 0x33c7c638, 0xd40be9a8, 0x70e6bff7, 0x37e67ad7,
+       0xd7c3c6a1, 0xf1aa1149, 0xc60c37bf, 0x2231f02f, 0xfdc2d49c, 0x958f9d30,
+       0x98aac7cf, 0x814fd78f, 0x6ff74bd6, 0xebf0a2d7, 0x5b2af312, 0xdffc49d4,
+       0x1c5d6ad3, 0xe311df7c, 0x97dbdf56, 0x840f7698, 0x2ae4a37d, 0x02a7fafd,
+       0x3e01c46f, 0x871eaa59, 0x7ee32d3a, 0x17efea1d, 0xf67dc492, 0x7fae3b2f,
+       0x69bd7bb7, 0xf9153b55, 0xbbed1633, 0x713f7ba2, 0x75bff71f, 0xdeea17ff,
+       0xf66ec1ef, 0x8e946ecc, 0x29fcdfe3, 0x9df108f3, 0x1105eddb, 0xbe51c718,
+       0xc8156135, 0x7e470fe5, 0xc2f60f14, 0xf71231fd, 0x1cb4bde7, 0xf7bb52b9,
+       0x717bd567, 0x393f625c, 0x5846ed51, 0x3a9f076d, 0xa7bc31e2, 0xdb2dfc1e,
+       0xb05e8637, 0xf2c9b91d, 0xc231edf3, 0x32ec230e, 0xd4cf3b6a, 0xefe4666e,
+       0xec29bfe9, 0x9417fcca, 0xac472e7c, 0xffdc83d1, 0x17ee7cb9, 0xd65d3347,
+       0xe2877b40, 0xce89bda1, 0xb0475ee6, 0xc23de51d, 0x7b8e2e98, 0x73134e80,
+       0x88863f99, 0x5b942a5b, 0x7a049c9f, 0xfb8c934e, 0x7ddfc2d7, 0x2ce7b7f4,
+       0x34a8f481, 0x131ca277, 0x5eeb1774, 0x86a543f0, 0x14e7b1f9, 0x097fd058,
+       0x57d811e4, 0x0d34746b, 0x299ee742, 0x3c600bf9, 0x0e3afded, 0x8abf024f,
+       0x669dff2d, 0x09aebd41, 0xb39779cf, 0xbffd80df, 0xd73b105b, 0xe8393cb2,
+       0x298977fb, 0x6aceff4c, 0xbbfbb0d6, 0x7aeb92f9, 0x347973b0, 0x39acaa88,
+       0xe0192ee9, 0x559f963a, 0x2892e51e, 0x8c38359c, 0x851bdfe5, 0x88d3df71,
+       0xf3fb0747, 0xa60af00c, 0xc1624ce9, 0xf1b11674, 0xba3ae5f7, 0x9cfeb44b,
+       0x83f32306, 0x309e9e25, 0xfa10ec9f, 0xcc6eceef, 0x3bb7d3be, 0xf37ddf93,
+       0x19fc7295, 0x726eff9e, 0xef9849fe, 0x67b66ee9, 0xdd1bed21, 0x704fe2b4,
+       0x21a2dcde, 0x1a9df7a0, 0x9bb41bfc, 0x24df7a8a, 0x8dd8bfe7, 0x3124dbd6,
+       0x23674aff, 0x1d22a78f, 0xb6f6fef1, 0xd60b93d7, 0x02af7b40, 0xae3c815f,
+       0x29be462d, 0x935c3332, 0x457cec91, 0xca5da5eb, 0xf857d20e, 0x5c87c2f7,
+       0x86e117ec, 0xfdba4f3f, 0xbeef3a61, 0x073dfa1a, 0x02d8e5c6, 0xf74beae3,
+       0xff8c1373, 0x40a71e05, 0xdee0d2aa, 0x068bde6c, 0xc79bec0d, 0xbf03bca8,
+       0xa7e0e3eb, 0xb94fd34d, 0xdce7f63f, 0xfc19bb1f, 0x927a69ba, 0xe7482dca,
+       0x842560fc, 0x64c8e7f2, 0x95f2235b, 0x883bf82e, 0x21e726ef, 0xb4ebb31e,
+       0xd7678fb8, 0xfae7227b, 0x377f65d1, 0xb59a1f16, 0x5848cbe5, 0xef666d4f,
+       0xed126cbc, 0x73b71c6a, 0x0736efee, 0xb26ef5e7, 0xe7cc24ed, 0x01c764f5,
+       0xa3feb76c, 0x753f04ff, 0x7fde3eda, 0x4f1d4bb4, 0xf102950d, 0xa37f9dea,
+       0xe39fcd9e, 0xd3545379, 0x69bfa80a, 0x2cc0774b, 0x2c7ee2c9, 0x0527e804,
+       0xe7b33fc3, 0x0c74378d, 0xf8d17380, 0xff50728b, 0x3fef3131, 0xf38b3a0a,
+       0x286ba70e, 0xcf9287ba, 0x80cc78de, 0x442e1377, 0xe22f5c82, 0xbafa9376,
+       0x6fd0079e, 0xe04caf7f, 0x27ca23dd, 0x498efe0a, 0x48807a66, 0xf8f51ab3,
+       0xc6a6cf5e, 0x36ce7aaf, 0xce7a1d21, 0xe4e5e5a1, 0x507a15eb, 0xff1fe0d6,
+       0x2c58a7fc, 0x92412f0f, 0x42aac8bb, 0x629af7b8, 0x4c36f9dc, 0xb9b99a61,
+       0x66bdee10, 0x207b4a24, 0x1f49699d, 0xe25df705, 0x232b38dc, 0xecb00f6f,
+       0xca116b58, 0xc4583ce1, 0x814bfb7e, 0x1eee1c31, 0x39a170bc, 0x92df0146,
+       0x7f28ac98, 0x2287a5ab, 0x8dc64c7f, 0x9faf7c8a, 0xefbfb5bc, 0x47c0777b,
+       0xc3b07747, 0x9ca079d3, 0xb4656b21, 0x396d66db, 0x148ddb74, 0x4eeeb71e,
+       0x9b036c2b, 0xcdb8fe78, 0x4fd82e05, 0xb00a5de1, 0x3ee4b463, 0xa09fd4fa,
+       0x5f7b2d31, 0x74611e63, 0xebfc6b28, 0x799b6028, 0x3da1e6c3, 0x8c9de036,
+       0xd5dfc135, 0x52c1f610, 0x65e9ecc2, 0xbbf6d41b, 0x550ecc95, 0xe54faca7,
+       0x3c827fd1, 0x0ef5bbea, 0x6e97f833, 0x3763fc1a, 0x64d6e790, 0x284bbc65,
+       0xbff2f17e, 0x1fe03964, 0x17e6a1e7, 0xe9120761, 0x6e2c83b8, 0xc5e56ae1,
+       0xf85e403f, 0xe57917c5, 0x31fb9e98, 0xc41278f1, 0x3f1f0f47, 0x628e4b4f,
+       0x5aaf67e5, 0xd0b8ef0a, 0x13c4277c, 0x4b9db291, 0x85efaec1, 0xf32b3617,
+       0x2996941f, 0x95d387e0, 0x65bccaf0, 0xad43f5fe, 0x66fa8abb, 0xefca83bd,
+       0x39d8278a, 0x639f7024, 0x992ee8eb, 0x6fdb0554, 0x4a31fe44, 0x7853f40b,
+       0xc70bed83, 0xfef47aba, 0xc96527fe, 0xbb3b4f4c, 0x7ddff1ed, 0x6de27607,
+       0xce46fd04, 0x5cfb3146, 0x8d29dd76, 0x177ae406, 0xb36caf86, 0xec7e0347,
+       0x4ee1c5ed, 0x9cac83f0, 0x24fe811f, 0x866ce17d, 0xbfedc9e7, 0x7843d1b7,
+       0xbf09efe5, 0x03ff0f57, 0xd13f379c, 0x46fb1468, 0xff9589bb, 0x6cede48f,
+       0xeb67c8df, 0x83d03a63, 0x974261cb, 0xe252e566, 0xeeb0cb95, 0xbf003e60,
+       0xf78edcf6, 0xd37b009f, 0x5a3eb63e, 0x29e3fb89, 0x4cd8bfb8, 0x95a3ebfe,
+       0x7e77b2d4, 0x427dec2d, 0x7218bf71, 0xd1aeecbd, 0xbf8dfbc3, 0x2279baf4,
+       0x843bdf99, 0xc7071f5e, 0xdca93e50, 0x3b1afcc6, 0x4aefae1b, 0x804bd6fc,
+       0x068cf69e, 0x6dc05af9, 0x3bfdfc0d, 0xd8a17c55, 0x17b58837, 0xf78b13fa,
+       0x3ae80f3e, 0x541fa026, 0xc6fd16a3, 0x092ce816, 0x6fea9751, 0xfc5886b9,
+       0x68dbebfa, 0xe62df940, 0x73666ed1, 0x3e78dbed, 0x8171de1a, 0xc3ea3174,
+       0x87fd8a35, 0x58ba73ee, 0xec455810, 0x6370ec5e, 0xe1d03e42, 0x199c44b0,
+       0x309a9839, 0x35fb9bce, 0x27fc244d, 0xffeb4331, 0x6fd0b6ae, 0xf3bc6cef,
+       0x3e87d07a, 0xcee7bbae, 0x24fbf401, 0xe29b9778, 0xfb7740f7, 0x81df9834,
+       0x73f4255f, 0xfa91fc2a, 0x77f7acfc, 0xf307e50b, 0x65dd80c6, 0xfe83312a,
+       0xfa665e3c, 0xad8b7916, 0x2a37212b, 0xe868a6a5, 0x09e4f5ff, 0xbce99287,
+       0x01fd1613, 0x3df569f5, 0x5bea95f3, 0x26b0f285, 0xebede81b, 0x6e7f1625,
+       0x31577c65, 0x9393ccec, 0x7d508e40, 0xf28ff41e, 0x1ef89dfa, 0xe6dcfa81,
+       0xe7d5abd5, 0xf38dabef, 0xedcbd00f, 0x7071c96d, 0x7877388e, 0xcfd40912,
+       0xcd56f27d, 0x021f5477, 0xdc36b479, 0xa6aef8c5, 0x6fce94ad, 0xb364dac1,
+       0xf6e78a13, 0xa2d6f162, 0xdba7f0fc, 0xcbf3437e, 0x83370a5e, 0x9d30bdda,
+       0x818de138, 0xa37aab85, 0xdeafbbbd, 0xd006eaf2, 0xa1d65eaf, 0xe06bf45d,
+       0xbd7f0a1d, 0xd81706f9, 0x2c69e783, 0x8cf7847f, 0xf9193ac9, 0x060bd4ed,
+       0x1fe75fdc, 0x2bfb81e9, 0xa50b23ac, 0x4254a9cf, 0xfcdeb4cc, 0x5db193d7,
+       0xaf7625f9, 0x02537f3b, 0xfa0aa1c6, 0x8610bcb6, 0xd9c591f1, 0xf4dcbdb5,
+       0x47449edb, 0xbc1c4a54, 0x975ae7ff, 0xf054f144, 0xc01f4fd2, 0x537f36be,
+       0x47cbd21c, 0x61fbe0e7, 0xb60f4367, 0x84be39ce, 0xef05fedc, 0x0653120f,
+       0x87895f82, 0xeece77bf, 0x7db8720f, 0xd977cd4e, 0x7e32ffbc, 0xd840c3ce,
+       0x67cff058, 0xdca24cf1, 0x628d14a8, 0x4f942d3f, 0x3e076c54, 0xf9e037ad,
+       0xb82c35b2, 0x0a486a9d, 0x8c2b57db, 0x49ec2adf, 0x507e8b15, 0x322b13d8,
+       0xe7bbde09, 0xbff4b12c, 0x71f7a697, 0xd9c4a7fc, 0x4a7cc387, 0xfadf1f6a,
+       0xf9f1e21e, 0x7e813ffb, 0x3bd89af7, 0x7c31ef6f, 0x6f02ff0b, 0xbe0ec67b,
+       0xf429570e, 0x476db6cb, 0x7f781db2, 0x382bfc77, 0x3c6d9f0f, 0x25a654f2,
+       0xc7cc7ec8, 0x658cec2b, 0x60fede30, 0x4b8db487, 0xb473b3f1, 0x5efc1d7f,
+       0xeeaff44b, 0x53646cf7, 0xb6dbbc36, 0x07698200, 0x46cff2fa, 0x3ec36537,
+       0x4437fc2b, 0x14cccedc, 0x4a947fee, 0xfbc44352, 0x0b8949cc, 0xdf83ef1a,
+       0xe7de3aaf, 0x19f78b3c, 0x7de333fe, 0x0c9f393a, 0xef1e0988, 0x5fcf04f2,
+       0x43d96a42, 0x43ee5c72, 0x077f0dd8, 0x67bc5658, 0x8899e5c9, 0xc0da18f3,
+       0xb943ffec, 0x6364ab1f, 0x88432e71, 0x7aa7b59b, 0xe5640597, 0x89119054,
+       0x113ae237, 0xc606fdef, 0x7be13425, 0x0e9337cd, 0xacc46d4c, 0x1ba29485,
+       0x8ec491d3, 0x855228e9, 0x835268e9, 0x16a46de9, 0x09a4b1d3, 0x8dc7d253,
+       0xff78c7ef, 0xf3adc67e, 0x0cffb034, 0x6f5c1498, 0xbfaf837b, 0x5243e04b,
+       0x9578afbc, 0xd84518f8, 0xf121c5fb, 0x7e819292, 0xea2f0258, 0x9c31bfbf,
+       0x119db078, 0x80f651b0, 0xef0594f3, 0x0d880a4f, 0xc42bc2e1, 0xa1c7ae47,
+       0x2532f665, 0xe0e9025e, 0x1bd4854c, 0x19ee4607, 0x2b038ca7, 0x5e718719,
+       0x5cec39fd, 0xe26ff2c0, 0xb1f79de5, 0x2824507c, 0x82ca45fc, 0x5c71fe71,
+       0xef190f72, 0xb187261d, 0x6ef17ab8, 0x4230e4c9, 0xb5bf809a, 0xcf9438ce,
+       0xde297a8b, 0x392530f3, 0x355ca00e, 0x142d23ba, 0x16670b7f, 0xb1c6ffa2,
+       0xdb8dcb38, 0x7e3c5f25, 0xd75b0a4b, 0xc4aaa547, 0x8f1e743e, 0x77dfa7e4,
+       0xbfafba7f, 0x04e7e82b, 0x3f755bac, 0x3c3ac46f, 0xf6313fd0, 0x2cfcf3c2,
+       0xde6cafbe, 0xaadb343c, 0xaccd7e81, 0xdd67dfdf, 0x32cd3f77, 0x424edaa7,
+       0x821496f9, 0x5da44deb, 0xf02dece2, 0x893bc45d, 0xbf33edef, 0xbe26eadf,
+       0x531faa38, 0x5ca1671c, 0xd693c6a5, 0x571d0e5f, 0x5c46c4b6, 0x655be47a,
+       0x2e3a993c, 0x3df7b68b, 0xee52abcc, 0xd3fc0b98, 0xfe91f516, 0xcaefea2c,
+       0x1dc6acb8, 0x687114fb, 0xe3781d62, 0x1c593ad0, 0x438850da, 0xbff1f48b,
+       0x7c134388, 0x10c3d62c, 0x72c34388, 0xf281cc37, 0x813a3fc3, 0x4e236871,
+       0xda1c7878, 0x9a1c6511, 0x159ffbed, 0xb1de2687, 0xbd85b058, 0xdb80bfa7,
+       0xfd060077, 0x5f7894e2, 0xc4579f86, 0xdf7ca4b9, 0xdf9eecdb, 0x041bff49,
+       0xa7ec907e, 0xe859f9f8, 0x0fe0122f, 0x0cb5c279, 0x0fe01dc6, 0x09aff2a9,
+       0x568277fd, 0xe9fbf506, 0x2bcfca93, 0x5c219f7c, 0xcbc7997f, 0xaec0fcc0,
+       0x8f51a0b5, 0x1782d1fa, 0xfe82b3ee, 0x64d520b4, 0xf2b77945, 0x514be43e,
+       0xfccf3c9e, 0x9b7ac473, 0xdea09cbf, 0xac4f3de5, 0xeff0d833, 0x404bac23,
+       0x3e7bcafd, 0x0814f6e7, 0xebfb84d3, 0xdd1d514d, 0x536ddee1, 0xf4158663,
+       0x5b220fbb, 0x71b14256, 0x5e9f0ce1, 0x0e98797d, 0x9603aff5, 0x74888298,
+       0xf3b13adf, 0xf99e4275, 0x3af98335, 0x7bb136b3, 0xf6a39c85, 0xdc0b4882,
+       0x84fbb02b, 0xefc12d41, 0x4ae7c7a9, 0xc08a7b8a, 0xcb16c9f7, 0x7fb8255d,
+       0x6a10f760, 0xbfb8bd3b, 0x2985b22e, 0xdd423fee, 0x0ef38b67, 0x1e89efdd,
+       0x118d7bf6, 0xc48337fd, 0xf7233dd3, 0xf663bdf0, 0xf3c0e48e, 0xa6c61dd0,
+       0x4fabe034, 0x53731c63, 0xcb6e20e3, 0xce39416a, 0xf17ceae3, 0xbca06f40,
+       0x073ef114, 0x20e32da5, 0x54deea1e, 0xa3d40547, 0x067b30d3, 0x9947def9,
+       0xc5f27b99, 0xa7682dd7, 0xb7f54caf, 0x3bbff3d3, 0x1e2f5ea2, 0x59e3058d,
+       0x5095bf9c, 0x8d0338af, 0x15f3c60c, 0x8a674ff2, 0xdbf98729, 0x4adefeaa,
+       0xdfe5576c, 0xf167a95b, 0xad89a50d, 0x59b3af4c, 0xfa6e2cad, 0x959dfde7,
+       0x9553ddcb, 0xf428b626, 0xe621b255, 0xbea6ec8a, 0xfdae5df9, 0x5a7f6c36,
+       0x7e0a87d5, 0x98e8b198, 0x3a66cf82, 0xb5f9959b, 0xaf7838d2, 0x1567d28c,
+       0x35b3c7d0, 0x0b14d469, 0xf01801f8, 0xf7cbbf5d, 0x77f11a7b, 0xcf09baa2,
+       0x9f5e628b, 0xd8451f55, 0xc651ed53, 0xa979f067, 0x704f8bfd, 0xdc1399bf,
+       0xf704e66f, 0xfdc1399b, 0xbf704e5a, 0x7c87e116, 0x4c8aa242, 0xe47f5074,
+       0x828f8137, 0xc23723f8, 0xc8fe90f7, 0x0a71c7e4, 0xb7e7647f, 0xe47f0b08,
+       0x91e7a95d, 0xec9bbb8f, 0xc43b436f, 0x9ffbd1e6, 0x23f943bb, 0xeeca9fbf,
+       0xa5503e93, 0x22f3d29f, 0xb4f1a9fa, 0x0bd95e50, 0x37ac59df, 0xcb879010,
+       0xf1a6d924, 0xb0f18fbf, 0x16ce5377, 0x1dfc28a5, 0x8b7f962a, 0x0f7e17f8,
+       0xd0196f39, 0xdf7ca04f, 0xd7405ec1, 0xe71d53c7, 0x1dfd9952, 0xab2e87df,
+       0x5fbfb033, 0xbf21cfc7, 0xebf139e0, 0x718181d4, 0x77e6a114, 0x53d34e76,
+       0xe55e7499, 0xef153b91, 0x8af18b22, 0xfa718979, 0x5f8cb9da, 0xc50ef2c9,
+       0xf6db6b3a, 0x63e02f48, 0x9c167ef1, 0xa904275b, 0xe8c69f1f, 0x5287cf42,
+       0xa4bfed1a, 0x7d0f9d8a, 0xffb9adf4, 0x3ec7a013, 0x509dca13, 0x2cf3d5f5,
+       0xf10fb1df, 0xd2173ea1, 0x0b4d7679, 0x3b9fcf32, 0x6bf5abbf, 0x4e217437,
+       0x715097e0, 0x9b250751, 0x2d77c605, 0x4b5e96bd, 0xd2d7a5af, 0xf4b5e96b,
+       0xbd2d7a5a, 0xaf4b5e96, 0x6bd2d7a5, 0xf4e5ffe9, 0xfffd007f, 0x8000c102,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408,
+       0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382,
+       0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 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, 0x00010300, 0x00018600,
+       0x00020900, 0x00028c00, 0x00030f00, 0x00039200, 0x00041500, 0x00049800,
+       0x00051b00, 0x00059e00, 0x00062100, 0x0006a400, 0x00072700, 0x0007aa00,
+       0x00082d00, 0x0008b000, 0x00093300, 0x0009b600, 0x000a3900, 0x000abc00,
+       0x000b3f00, 0x000bc200, 0x000c4500, 0x000cc800, 0x000d4b00, 0x000dce00,
+       0x000e5100, 0x000ed400, 0x000f5700, 0x000fda00, 0x00105d00, 0x00000028,
+       0x00000000, 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, 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x65e21f09,
+       0x63e62860, 0x88237860, 0xcc2b4e2a, 0xfe9942ce, 0x0c0cccf3, 0x32f88117,
+       0xe2055f10, 0xe9a48cd3, 0xb045e2b7, 0x30327377, 0x7df90358, 0x9b8b5a40,
+       0xc8014181, 0xb3e201b6, 0x204bfe40, 0xadc40afe, 0xdc0c0c3c, 0x6a0c0c5c,
+       0xc4042c40, 0xcdf8bcb6, 0xff2023b7, 0xaf951b9f, 0x17ca83cd, 0x3fafc6e6,
+       0x7cbf0789, 0x6c790106, 0xf928b3f8, 0x4620e1f1, 0x2d43749f, 0xca86aeac,
+       0x6065522f, 0xe7c40df8, 0x681ae2a1, 0x10aac5f2, 0x03329cfa, 0x7e1ab243,
+       0xc80853b3, 0x000c060f, 0x4022bae9, 0x00000400, 0x00088b1f, 0x00000000,
+       0x7dedff00, 0xd554780b, 0x733ef0b5, 0x27bcce66, 0x20212793, 0xf0841e4c,
+       0x04242074, 0x11093a8c, 0x5076c403, 0xc2ab16fe, 0x25786784, 0x5ae5a911,
+       0xc0133bff, 0x51b91688, 0x7e2da5a8, 0x68bc104e, 0x01226f69, 0x903a4483,
+       0xbd08a5c0, 0x168b6ad1, 0xe088786d, 0x7e929205, 0xcfe956de, 0xe7dad6bf,
+       0x9939cccc, 0x77e8f881, 0xbf41ffbf, 0xdecfb3ba, 0xd7b5ef67, 0xcfb5ef5e,
+       0x30733d1e, 0xd7632776, 0x73941ff1, 0x4158c645, 0xf81d0ca4, 0x614b3ce2,
+       0xc18b72ec, 0x6c64cc65, 0xe8431eca, 0x68afa84e, 0xd7588214, 0x3633301d,
+       0x5b2bb181, 0xec46bd79, 0xb41b78dc, 0xb645d7b3, 0xd3b60a03, 0x8c8563a6,
+       0xfe31379d, 0xb1d76f4f, 0x9916c634, 0xe3457579, 0x7e3839c1, 0x9991ab55,
+       0x2df3fde1, 0x2beb07a2, 0x26410877, 0x27befb40, 0x7f180ca5, 0x32685071,
+       0xe3bea0bb, 0x6765c959, 0x2f81cd6c, 0x0abce0ae, 0x4dfa9f5c, 0x7c2125cc,
+       0x8d75a5ef, 0xb0696c66, 0x8c066a79, 0xe09774b3, 0x4b3cc1d6, 0x3ba10ab7,
+       0x2173e027, 0xcbb8c228, 0x2b995a76, 0x9d70c38f, 0x8eb4bcd1, 0xbcc02f95,
+       0x83670899, 0xe647b5e4, 0xa9f3f053, 0x72b981bf, 0xaf15f523, 0x5ef03cc0,
+       0x3704aff5, 0xc75ab12e, 0xff304d7c, 0xd9e67d95, 0x7d70d92f, 0x3dae5275,
+       0x7b951d7a, 0x834b1d71, 0x1b54d28d, 0x2d28d5c2, 0x6f191d1a, 0xcc4dced9,
+       0x6b828a65, 0x5f00f64b, 0xfcb6bb54, 0xf054cfd4, 0xd3cc652c, 0x83f84364,
+       0x9131ccd2, 0x22422de7, 0xbe38a963, 0xb19f1aa8, 0x99173d00, 0x6778843b,
+       0xf477766d, 0xaa755dbe, 0xa2656df7, 0x781c6efc, 0x87de45fe, 0x2a4efd67,
+       0xa9d3f937, 0x45dfb1fc, 0x9fc4fe70, 0xfd4fe547, 0x73fe7a6e, 0x2f95117f,
+       0xbe543df8, 0xb2a72fe8, 0x7ea5efd1, 0x5367f92f, 0xa3efc3b9, 0xafeaffe7,
+       0x7f15f2a2, 0x85ff3d2d, 0xbf95357f, 0xf9e807f4, 0x53d7f9bf, 0x04fb8cd9,
+       0x16ff6ee5, 0x83f8f72a, 0xff75efd4, 0xf9f72a4e, 0x33f9e89b, 0x13283f88,
+       0x3d3ace3c, 0x19424fec, 0xb0790273, 0xceb7af64, 0x59e4f500, 0xd7c03ebc,
+       0x7e012750, 0x3a802c06, 0xdaa0dfec, 0xb4233ace, 0xdbc55a0f, 0x6b9c0687,
+       0x743ed04c, 0x6ecf6f1d, 0x4331aef0, 0xde66f67b, 0xb0d83c3e, 0xc3ed02c6,
+       0x51f6f3b7, 0xac6b9d4d, 0x85aa3ed0, 0x721adfb7, 0xfd41b5ae, 0xcf5e0ed6,
+       0xb5aef4ef, 0x5dff3d43, 0xd5d89f5e, 0xef01d6b0, 0xdfc73c4f, 0xd9bde2d7,
+       0x60cf9ce0, 0xee0736af, 0x4207e8f2, 0xc23e725d, 0x1cbd8cdc, 0x77d516f8,
+       0xded4dc1b, 0x47aef81a, 0x92ea093f, 0x058fda9b, 0xc7bed47c, 0x53f6a5e0,
+       0xbed42581, 0xfb52f247, 0x6a4ac095, 0x4b50dd7f, 0x87eeaced, 0x54bafed4,
+       0x7549ed4b, 0xcfbea8eb, 0x8c196d00, 0xe33dd4e5, 0xcdfd0009, 0x511b7c11,
+       0x6aeb747e, 0x12ca18ab, 0xf91d287d, 0xcd8149e9, 0x5d80fe46, 0xf27bba23,
+       0x7c83c916, 0xc29bfcd7, 0x994cc497, 0xbeb052d6, 0x05a7e5e8, 0xd827e71a,
+       0x71825baf, 0xce3e6fb2, 0xaa4563b8, 0xab1dc671, 0x1209c652, 0x8dfe963c,
+       0xb26c7cd3, 0x4b639e1a, 0xa15e7195, 0x5bfd1c71, 0x8ab7b8d7, 0xb5bcf0d5,
+       0x35e7195c, 0x7fa9271a, 0x1b7eecf0, 0xc64423f0, 0xe036fdd9, 0xd9c69327,
+       0xf5a4e34f, 0x77fc9e0f, 0xe4e3548a, 0x8ca553bf, 0xce7841d3, 0xbb38dfe8,
+       0x86ac99df, 0xcaa59de7, 0x9c682738, 0x575bfd21, 0xd58aeffe, 0xb96efcf0,
+       0x69efce32, 0x8dfeac9c, 0x357de7b3, 0x3f79ecfd, 0xa27f3f4c, 0xb7fb7271,
+       0xd40f82ae, 0x41f053f4, 0x102e7e98, 0x6ff6479e, 0xa81f3d9c, 0x07cf67e9,
+       0x33f9fa61, 0x7fb633c1, 0xa3f82aeb, 0xfe0a7e9a, 0xcf9fa618, 0xfdf19e09,
+       0xd3f5e783, 0x7ebcfc6a, 0x511f8c3a, 0xfb0a7840, 0x33c4cf07, 0x3c4cfc6a,
+       0x8d8fc613, 0xbfdc99c6, 0xa33f5e71, 0x67ebcfc6, 0x1549f8c2, 0xf4775d70,
+       0xcf135d6f, 0xf133f1aa, 0x433f186c, 0x19529e08, 0x8ce3061e, 0xbece3f89,
+       0xecfc6a8b, 0x33f1c8bb, 0x3a27d3be, 0xce90dda0, 0xe4ce08dc, 0x0080de0b,
+       0xa814faed, 0x30f4b0bb, 0x3d3bc81f, 0xf8d1ddea, 0x84405772, 0xc4aefb76,
+       0xa2bb4ff1, 0x58e96ff5, 0x8263975c, 0x3877654e, 0x7aaa2d8b, 0x4a925952,
+       0x6454a73f, 0xb369eaa8, 0xf4f554b2, 0xdeaa4707, 0x5e3058cf, 0x7cbc1f55,
+       0x643eaab2, 0x7deaa955, 0x55d3e3d7, 0xeeeb59ed, 0x3673d555, 0xcf554f7c,
+       0x554f3cdd, 0x54badbcf, 0xedc8de35, 0xd1f5552b, 0xd5531ebb, 0x51acb6c7,
+       0x4f6dddd5, 0x3be3eaab, 0x3f8d539e, 0x54cff8e1, 0xb777c2f5, 0xa745eaa9,
+       0x3fbd555e, 0x1a6bdcf9, 0x3ce6c6fb, 0x8bae4a3f, 0xc95acf68, 0x910e33ce,
+       0x192d5ec8, 0xa3faa262, 0x7f546c43, 0x70df0ef4, 0x8fe3ec27, 0x6bd005f0,
+       0x5bbe4a8f, 0x2fec319d, 0x4b1d39d8, 0x63a7d2c7, 0xd7db7d45, 0x80ce801b,
+       0x5e874a2e, 0x650d3dcb, 0x3727ae8d, 0xe8dfca11, 0x2e916a4a, 0x4474151f,
+       0xd591567f, 0x8d58dd22, 0xfd70e88c, 0x0297c2b0, 0x54f87451, 0xcaf39726,
+       0x6a194fb8, 0x3eef51d3, 0x0066f756, 0x9993f2f5, 0x664cbc60, 0x9bc287ec,
+       0xbc0e40a1, 0x3a68f99f, 0x09268bda, 0xf9e8d0ec, 0x347f9825, 0xf9c01fcd,
+       0x6fcce3eb, 0xcd522dca, 0x52aace6f, 0x60966fcd, 0x4f63277e, 0xe7961dd7,
+       0xffde9137, 0xe6987091, 0xa6ad6537, 0xac4bd7f9, 0x25bf354a, 0xf2037f3c,
+       0x7f38f3c1, 0xe7f58c41, 0x3faf564e, 0xfd7aa96b, 0xcfff5f12, 0xf3c84eea,
+       0x3ffd685b, 0xf5f04e17, 0xd7c63d67, 0xa371846f, 0xf18477e7, 0x5ff9c41f,
+       0x69bf338e, 0xfd7ab178, 0xebd5cbd9, 0x5ff9f237, 0x9e4f7bad, 0xfff346df,
+       0xaf8f7842, 0x9a71fb3f, 0x75ac68df, 0x38c9a13b, 0x441b52d4, 0x2fe600b9,
+       0x050c801b, 0xc6444cf3, 0xde0c6248, 0xd164285f, 0x016a3c3e, 0x9ffe83ba,
+       0xd0de8059, 0x72ed977e, 0xd017ac16, 0x6996af0e, 0x4aaec17a, 0x657819e9,
+       0x57f72b41, 0xc333f818, 0xad2bbe00, 0x11fd9fbd, 0x7db05de0, 0xa025c91c,
+       0x2def8674, 0x23529794, 0xe6307c72, 0xe413321d, 0x877bd329, 0x9a863bdc,
+       0x2fd7683c, 0x1f630466, 0x60d85e3a, 0xc515df38, 0xa8b78b6f, 0xea824beb,
+       0x097702ba, 0x81940912, 0x0b579652, 0x7f079ef3, 0x7ddd8180, 0x2c6dec06,
+       0xb9b0313f, 0x0e7e785e, 0x452605fc, 0xed1d55f3, 0xabbd79cb, 0x73d61d3e,
+       0xc3704abe, 0x0d81ec88, 0x3a196395, 0x7bcf0172, 0x77ef0039, 0x852ff298,
+       0x7273e9d6, 0x003617f8, 0x7ff1477f, 0xb0bbc88d, 0x0ee08517, 0x7fbfe790,
+       0xba054573, 0x83d7d0bc, 0x5e577def, 0xc92de2f7, 0xde98f7aa, 0xa9cdef44,
+       0x1ea20c4c, 0xc36ceef8, 0x3b552eb9, 0xf1c03f30, 0xdd0fec91, 0xf1eebacf,
+       0xdfb99e82, 0x75d7eea7, 0x8dd1eac0, 0xbb4b7285, 0x3dbec181, 0x8719a550,
+       0x1f7f6879, 0xa878e192, 0x973edd56, 0x5fd42539, 0x9fab5773, 0xe3b40657,
+       0xcf00f800, 0xf81c793c, 0xe6f844e7, 0xd7f36dcb, 0x7daa021b, 0x0a947a02,
+       0xa22cf6e5, 0xbd0f5a02, 0x3fb7dd9f, 0x434041d0, 0xfb588107, 0xf9f7fffe,
+       0xae7d8dff, 0x3e492d69, 0x8ad70517, 0xe7c969a6, 0xdb2dfaa2, 0x5f555339,
+       0xd55fbc12, 0x4a96f17f, 0x86c2fb55, 0xf9f6aa25, 0xd5561feb, 0xa4ff032b,
+       0x75773fea, 0xa1fdaa9d, 0xed54a7da, 0xab3d540f, 0xfbefdfaa, 0x77ffaaa9,
+       0xdaaa3767, 0x864b0385, 0x46a8dc62, 0x881d0df2, 0x8df7aef1, 0xa1109b6c,
+       0x2fae855b, 0xfca9d3f8, 0xb2a2efd4, 0xc830e50e, 0x5e3edd75, 0x1cab6cd6,
+       0xa15bf28a, 0xb50c4ff3, 0x69fe5043, 0x672b55e9, 0x6325d0fb, 0x88bed083,
+       0x2e596717, 0xf3ca2f30, 0x19db816e, 0xb213f3ca, 0x0d6c675e, 0x8972d7f1,
+       0xd7f2dff3, 0x3f229606, 0xb942972c, 0xe3f8b6b5, 0xd68126b2, 0x1a36d8c1,
+       0x10704967, 0xfbd17918, 0xf382ad9a, 0xe69141d2, 0x6e1f46af, 0xdec1da12,
+       0x3f9c3a0d, 0xbee43ed4, 0xe78f0831, 0xc1c01d19, 0xdf49535a, 0x2797f25d,
+       0xfe23d39f, 0xf05e54bc, 0xbcf2a6cf, 0x39e547df, 0x6795157f, 0x7654b5fc,
+       0xf95357f9, 0xe5403f91, 0x2a7aff29, 0x5037f03f, 0x85bfd279, 0x83fbdfca,
+       0x7bf15e54, 0xf4e854a8, 0xb57d96ff, 0xf2bdb8e8, 0xffafb8df, 0x16afbd1e,
+       0x23c3939d, 0x0d06ebef, 0x55794abc, 0x61797027, 0xf31676e4, 0x788e2958,
+       0xc3078955, 0x94571448, 0xf0ddc1e3, 0xd3f62777, 0x1831e537, 0xcfe8eaef,
+       0x7b8e3173, 0xb191a4f5, 0xd3ebf8cc, 0x3c5c5fee, 0x46ee80b0, 0x3858b7f8,
+       0x72aa015e, 0xdcec1e36, 0xf3dd7b11, 0x92cf5d78, 0x7726fdf0, 0x3c355c74,
+       0xc072e22e, 0xd16af1cd, 0xdacf7b71, 0x847c722e, 0xb3efbb76, 0xc6b5e847,
+       0x718b93d8, 0x2347f662, 0x36c63d43, 0x055871cb, 0x575e015f, 0x3a7ff5f0,
+       0xfda04e3e, 0x1f1f105b, 0x47e0a5dd, 0x32bff0c4, 0x574aafc5, 0xae90439d,
+       0x7bf4cab6, 0x027865b5, 0xe7191d1b, 0xd38b9d6e, 0x7ef04df5, 0x0e4be8f5,
+       0xa657f3b4, 0xf2e79ceb, 0x456fe3e3, 0x16d3a653, 0xaab4a76d, 0x841b57eb,
+       0x70371e72, 0x831acc25, 0x3ce9d1f2, 0x2c728397, 0x9c654a9d, 0xf392e995,
+       0x0bf6325c, 0x2576f872, 0xea7e5f12, 0x6fbf5137, 0xe3788e1a, 0x6168e044,
+       0x247de167, 0xf1d9ebd1, 0x3ba5c7fb, 0x8c245ffd, 0xc336b0c7, 0x985f6867,
+       0xd1d7ffe0, 0xaa7a63ee, 0x34d6e32b, 0xade30189, 0x6a977cf8, 0xa5cf783e,
+       0x67ae94e4, 0xf5be88dd, 0x7f42bcec, 0xa0e7ca20, 0x1079489d, 0xbf6d53b3,
+       0x35eaaa24, 0x2a9d03ad, 0x00ff067b, 0x04cac739, 0x72c1d23d, 0xf5ba2c99,
+       0xc002f5b6, 0x2e9d0937, 0xf78147a4, 0x92ea615b, 0xafa42e7c, 0xcdb9dfb5,
+       0x681b3d85, 0x60f85abd, 0xf5ea66ff, 0x265fe1f1, 0x1bd47d5e, 0x22d7fe83,
+       0xd01ea3fd, 0x999f3f71, 0x43e40e02, 0xdc701e96, 0x6cc3fc4b, 0x9ae0fc61,
+       0x5513cc19, 0xff01c657, 0x5f6d47ad, 0xa4bbbe72, 0x76bbfee3, 0xbcf2cdde,
+       0xf55fc337, 0xe2a7b7ae, 0xac78b5ba, 0xe4b3fd6e, 0x5314fca3, 0xefc151e1,
+       0x59bbd124, 0xee97f984, 0x7f212d3c, 0x7204305d, 0xb903787f, 0x5b7e17df,
+       0x646b79fa, 0xd8f72b9d, 0xf95fbec9, 0x0bd79cac, 0x779c4eb0, 0xf13c915e,
+       0x0515e835, 0xa67c6807, 0xd3d88c2b, 0x5e6d7e4a, 0x27f232cb, 0x0901663e,
+       0xc51792e3, 0x9fb44286, 0x4a353697, 0x32f3801e, 0xbe2395d3, 0x1c77b32e,
+       0xb5fb51f9, 0x9f08944f, 0x899f6760, 0x6cec1386, 0x6cec1d55, 0xbb117d55,
+       0x51f30d37, 0xc01b368b, 0xaa75a7c5, 0x9d115fda, 0x5662ee34, 0xc9768f5b,
+       0xeffc96d9, 0xf0fb86dc, 0x88850bfa, 0x3cd079df, 0xf8f10928, 0xcbf1e136,
+       0xdf04bfce, 0xde77df1f, 0xf26add08, 0x561e328e, 0xc13c14ec, 0x44737418,
+       0x7d0ad796, 0x5f8641fd, 0xc59c0f89, 0xdea4417a, 0xa17fa9ad, 0xfe657fa9,
+       0x4bba014d, 0x24f7ec8b, 0xe91677d1, 0x38f906ad, 0x5fb7c221, 0x3ef4fc79,
+       0xa37f77e3, 0xf3560fe3, 0xc5ff8c0d, 0x4e7e3a37, 0xfa8df81f, 0x77e3be82,
+       0x59631d9b, 0xc4a9d902, 0x3a71815f, 0x1fe9bbf2, 0xd2136bda, 0xc0a69fc9,
+       0x39ddd638, 0xd9a38c41, 0x14e99dcd, 0x54bf07d7, 0x6024f30f, 0x0edf907f,
+       0xf9f016e6, 0x2cd37ed3, 0xf8ca8794, 0xe55eb776, 0xe914267f, 0x7b28fe35,
+       0x61f00737, 0x38a6a793, 0xfcedd41b, 0x5b6b666f, 0xe30b7c4c, 0x04e8fca8,
+       0x2ffe45d6, 0x9e7aa78c, 0xa1d59a38, 0xa8f44a1a, 0x6d154f9f, 0x9c4b6f14,
+       0x9c4e28c6, 0xfad7ae5c, 0xd2c315f7, 0x4740e0a2, 0x32c9ea1b, 0xcfa6e01c,
+       0x67fde014, 0xf08cf4cb, 0xc5ff8012, 0xbc593380, 0x01f9c216, 0x39df155e,
+       0x65f540f2, 0xe7aabc11, 0x4d19e700, 0xe50f207c, 0xb8b31246, 0x53801e71,
+       0xdbd1eed5, 0x0e1e2853, 0xa3e517f2, 0xc989d4cd, 0xaaef9c7f, 0xf4ebaf0a,
+       0x190b23e9, 0xfc385085, 0x942fa601, 0x83ef8bf7, 0xd313bfaa, 0x8f04d9d4,
+       0xd8361c7a, 0x6f8f2d19, 0x8309fd95, 0xe9133bc1, 0xad6870aa, 0xa717f388,
+       0xaec872bb, 0x3a214b68, 0xca5d5acc, 0x685d42ce, 0x9cf78460, 0x39ef1c0d,
+       0xf71e3a3d, 0x0e09675c, 0x268cb183, 0x9c833016, 0x301cad02, 0x8259c78c,
+       0x5ae49fb2, 0xcd3cc3a3, 0x7829a07a, 0x54a7adaf, 0xa73610b7, 0xfc609b09,
+       0x3e3de96f, 0x67c1c63d, 0xe375d2fa, 0x9ae161f0, 0xa5a0c18e, 0xb8211b19,
+       0x05080b41, 0xc2de8e87, 0xdf184a43, 0x790f4185, 0xd72ed46c, 0xdaed0859,
+       0x2faf0b06, 0xae9417d7, 0x988ff787, 0x5d71cbbc, 0x891ce4cc, 0x4a162b79,
+       0xb7c6f5a2, 0x0724024f, 0xb6f2b815, 0x4cb54d77, 0x2814fe40, 0x1ecc3fcf,
+       0x24255bb6, 0xa5361dae, 0x6ed0921e, 0x2dbcb6f5, 0xa2bb7fa1, 0xd76a6de9,
+       0xa1ca1d61, 0x07535dc9, 0xd4f88981, 0xf4d2b2ba, 0x4b5e3011, 0xd60eba65,
+       0xb2badcf5, 0x4f75ea43, 0x1c51d35b, 0x775eb759, 0x77dd66b7, 0xcfdd70df,
+       0x5d2eefe9, 0x75ffdc5f, 0x8b3fbec2, 0xa25199f8, 0xeefe510b, 0xf0282da4,
+       0xec99bb78, 0xc69c7941, 0x1287f638, 0x7e718437, 0xe850eb8a, 0xa14f7947,
+       0x9174789b, 0x79239ccd, 0x1f4d503e, 0x6d9ef4c7, 0x7a4bd708, 0x4054894f,
+       0x787b25eb, 0x2ee7cf86, 0x2dd08fcb, 0xd1f2f9b3, 0xe61832be, 0x57e702fd,
+       0xb2519ae0, 0x7802cc52, 0x21ec6177, 0xd49eb235, 0x2e7301d5, 0x03d533ac,
+       0x7be177d8, 0xcf7c66be, 0x8427bb31, 0x32262647, 0x4620be5f, 0xaf995ee8,
+       0xdf1e4dfe, 0x05d4afaf, 0xed5c90d7, 0x08bc7012, 0xe869743d, 0x43d387a1,
+       0x87a269eb, 0x9cd3b6ea, 0x4aeb5a1e, 0xdbaa9e91, 0x85d1a704, 0x8719eaeb,
+       0xebeffcfb, 0x61ea97e6, 0x7b5a879f, 0x1d0107ea, 0x69655818, 0x7af09985,
+       0xb3ebe118, 0xca7c323f, 0x6fede2ba, 0x1facd1c3, 0x707d468d, 0xe61ee75c,
+       0xe94de08a, 0xd12f4977, 0x7c906c3e, 0x295e90ef, 0xcb823aea, 0x3be8ed7f,
+       0x1c5bb40e, 0x883defc7, 0xc1663bef, 0xf322b90e, 0x535f1c36, 0x1a67e78a,
+       0x64381d60, 0xa009eb02, 0x1f1f13dd, 0xf8c25f9c, 0xf84d3968, 0x9e1d61d1,
+       0xa7e72abf, 0x5ec8cf80, 0x7ee56a19, 0x1e7ac7ee, 0x5e9bfb3f, 0xef6e4b94,
+       0x2abf1ea6, 0x5c4fd0b9, 0xa9fea3a7, 0x5e8e8e58, 0xf7ea3aff, 0x055e5437,
+       0xfb287c11, 0x4813d0a9, 0x5fe62b4a, 0x577c5996, 0x6493f4d5, 0x4f1a8acd,
+       0x9fa36f79, 0x7f8017b9, 0xde63b137, 0x81ff2823, 0xf543fe7e, 0x198318de,
+       0x47f4a6f1, 0x3fb58cfa, 0x14331ef0, 0xd05c79f0, 0xa563b9bf, 0x7f617688,
+       0xf650b5f7, 0xacad0b8f, 0xbf7835f6, 0xac4a0130, 0x01f5cb27, 0x2f107d72,
+       0x75b94fb3, 0x946f3c02, 0x6e9effb8, 0x7a92e390, 0x3bcc48e7, 0x3db81ba5,
+       0x923e9c58, 0xb7c2bee4, 0x2484be88, 0x58021b32, 0xe964f566, 0x3e14df70,
+       0x42e8f7d6, 0x594a5076, 0x0dce977a, 0x61f98fcf, 0x9ff037dd, 0xbd108fa6,
+       0xd1d1ecb1, 0xfcbf5d06, 0x5276b898, 0x6c3b1f57, 0xec9521b4, 0x42f78da3,
+       0xaf447abd, 0xc6b5fb84, 0x8ddb7d5a, 0xe169efce, 0x13ed763f, 0x577bfa07,
+       0x8f2c6afe, 0x5078f715, 0xff51dbc6, 0xb14f7a6c, 0x30ab68a3, 0x3ec0cfbe,
+       0xd70bf0e2, 0x7d92548d, 0x3c890774, 0x3e80c7dc, 0x55a7f509, 0x777e73a0,
+       0xebb3fa46, 0x8477e7c0, 0xb1b05696, 0xb72bf950, 0x3ff04c6f, 0xe98faff4,
+       0xed1e747d, 0x9a79e318, 0x3b6d6b42, 0xd33199d6, 0xf985c3bd, 0xa29e753e,
+       0x2ca1a130, 0x42489509, 0xc533cd26, 0x0e4f69a4, 0xb2fe51e8, 0xe71e4cec,
+       0x945f3062, 0x44f40e9f, 0x7c3658f9, 0x3395d924, 0x65dd2af2, 0x48bdfbf2,
+       0x731b7eac, 0xfae44426, 0xeefdd734, 0xd1dd9532, 0xfd3946e0, 0xe245dfd6,
+       0x7f1e2d6b, 0x7d7ce065, 0x9775efd4, 0x63c5f4e5, 0x67584ba9, 0xa7c5f577,
+       0xfc5a5f16, 0xc95fc3c6, 0x52597729, 0xf1693c0c, 0x46ff0c72, 0x06368f3c,
+       0x9de20203, 0x4b98e9e3, 0x78188160, 0x29d2ec52, 0xa4683176, 0x9dd90f76,
+       0x68f0c977, 0x4f17d6f1, 0xd2bb8a9e, 0x411ff022, 0x4e91e87c, 0x884aefdc,
+       0xdb0304ff, 0xdd0ceb81, 0x6ab7f949, 0x434c1fb9, 0xf93bb579, 0x8375e150,
+       0xf087707c, 0x386301bd, 0x6d55fd7d, 0xb83dde7f, 0x14a0dd72, 0xfb9803c4,
+       0xd4671f1c, 0xf1b8c374, 0x7da4cd61, 0xdba8fc07, 0x587e3993, 0xcbbf6f32,
+       0xd0d769a9, 0x0abd768d, 0x3e1bfcdd, 0x3f17d498, 0x30ecdd0a, 0x067276c8,
+       0x1e788c1b, 0x02426fbb, 0x78da2dc5, 0x4f4b5ede, 0xc37a4f13, 0x47f4c8e3,
+       0x5f3025f4, 0xfb33b9f8, 0x569bc86b, 0xf25166d0, 0x7be8b866, 0x51bc9623,
+       0x7976fff6, 0x81676e9f, 0x4b03a283, 0x74c25ffd, 0xff591993, 0xda275c21,
+       0x20d883e7, 0x8318e75c, 0x7969cb8b, 0xcb75e19d, 0xe58a09e7, 0xb64d8bf9,
+       0x7acb8e10, 0xf8c297f4, 0x5cf8a2cf, 0xc08a4a40, 0xb3fb9061, 0xdb8cb521,
+       0x79d20f5d, 0xbb0bc01c, 0xf1c08d6e, 0xa7a08307, 0xc70c9578, 0x80a69de5,
+       0x57ac2b78, 0xf511fdf4, 0xf8e125d6, 0x3e9f5a58, 0x4a7a8b94, 0xdadbdedb,
+       0xd0ed8d51, 0x93f5116f, 0x71865fe1, 0x9ea7a007, 0x6dc18d37, 0x8a48e231,
+       0x4a6c093d, 0x83e15cf2, 0x6505513b, 0x92dfa5f7, 0x1c7af1d6, 0xa5b74b5f,
+       0x1da159e0, 0xbbd7a5aa, 0x7c1ccf58, 0x4553a5ae, 0x7a597eaf, 0x30a9ec50,
+       0x74d4845d, 0xd003d0a1, 0xfa42ffc7, 0xf1f09ee8, 0x9efe68f3, 0x169bd098,
+       0xbd810f4b, 0xeca293a7, 0xb3f678e8, 0x48273762, 0xc7da333e, 0x595d797a,
+       0x9e1d2e79, 0xf25dba8f, 0x62b9f058, 0x0fccdc4f, 0x80e01d60, 0x91cc7d02,
+       0x83a4ddf1, 0xc0dbe006, 0xf288214a, 0x63d621e6, 0xaa1ef9c0, 0xc9fca835,
+       0x8f9ee639, 0xe6fd087e, 0x3d270dd4, 0xbf28c3e4, 0x38f3ef48, 0xffcf3d44,
+       0x5c9ebcb3, 0xaee6bff4, 0xd1fc6836, 0x39e3a224, 0x23ecfe4e, 0x09303be8,
+       0x4d4aedc7, 0x76f94d1a, 0xfced7f55, 0xe3b43aca, 0x91abdf6a, 0xee78b2e3,
+       0xf7851dca, 0x83b71251, 0x131ef0c2, 0x6f80bc39, 0x6aebac1d, 0xd3e088db,
+       0x2954e831, 0x8e5d267d, 0xef52393e, 0x3b38d37a, 0x955f6318, 0x3f7c1479,
+       0x7c153ac8, 0x0e8b1e7e, 0xffdc7d8b, 0x910e6dd6, 0x2f1dacbd, 0xec8ca7a7,
+       0x81269cb0, 0x4de5deec, 0x2af9ba25, 0xa3fb9bfb, 0xa6efec7d, 0xf2de3483,
+       0xfedc8396, 0x3b23aa6e, 0xf70b797e, 0xa43ec047, 0xc80463f3, 0x15cbb268,
+       0x7983d33f, 0xb79815a2, 0xbd21ede4, 0xf3d5cf0b, 0x78d235fe, 0xf21ca9f1,
+       0xc0ff7913, 0xa7e8b5c4, 0xa85afd86, 0xbab5fb47, 0x9576c2ba, 0x6c281b5f,
+       0x5b5f91bf, 0x05385f53, 0x8fe05afd, 0xcdc15245, 0xe4b663f9, 0x797fa1ba,
+       0x41ade4c4, 0x02e2533e, 0x6abffdda, 0xfd202572, 0xbdfb253d, 0x23cf57d3,
+       0xfc3cde7b, 0xa37990da, 0x7df2de51, 0x76e24c7f, 0x7be88a4b, 0x3eebc70c,
+       0xcf172d74, 0x7fb4d4cb, 0xbcf911ba, 0x1ec3ce4d, 0x5d9157f7, 0x13dfeca3,
+       0xa777b712, 0xa077688f, 0xc14f7ffd, 0xcfe81cef, 0xbcf3d65c, 0x4922a5cf,
+       0x18f66f65, 0xd7027aee, 0x1e8094ad, 0xf16ee511, 0x82938e84, 0x8ffcbe23,
+       0x808f77c8, 0x7b5d9df2, 0x5bd70d3b, 0x81d872d3, 0x7e84bef8, 0x5bc9c610,
+       0x8f30d3da, 0x77f9a2b8, 0x9e7bf40e, 0x7b5db897, 0x40e9df59, 0x1ef96ebf,
+       0x5fc9dbb0, 0x003da50a, 0x32d4ba78, 0x3e69f0bf, 0xbf5a298d, 0x85f57fe1,
+       0x76edbb11, 0xeb282053, 0x284e253b, 0xefa1875c, 0x663d116c, 0xedfb5f47,
+       0x4dacd1f2, 0xcc0fb815, 0x0f861ee0, 0xec83acf5, 0x09962539, 0x21cf0a92,
+       0xbf2b901d, 0xefbde96e, 0xe7162236, 0xda0251ba, 0x0c14be3d, 0x8db69592,
+       0x9188375b, 0x73d950be, 0x12ef7b5a, 0x1b77dd73, 0x7aa3b9ca, 0xd6b37686,
+       0xfdd163fe, 0x9f7fe387, 0xd6bcbc25, 0xfdc56d92, 0x59d320da, 0x54ef4b4d,
+       0x166a97e4, 0x6f7e0efa, 0x3a22dd55, 0x7246ec43, 0xf85bdd77, 0x9b7753fd,
+       0xd8f485c1, 0x34d876dd, 0x22adeb16, 0x4e6a99c5, 0x3a428f14, 0x2866d2ba,
+       0xbcd7bc47, 0xf903b1f9, 0x57cfd15b, 0xde7a44da, 0x9e9676dd, 0x695ee32b,
+       0x7a851e4d, 0xfdc759a5, 0x9f238ebc, 0x7fdf915b, 0x326aed7d, 0x7eb297f9,
+       0xaaa7618d, 0xddad4eec, 0x6e19e53a, 0xb5494e47, 0xec579c93, 0xf8fa3ecb,
+       0x67675b14, 0x6b1f425f, 0x4919f0f4, 0x616ef3b6, 0xd8af31e3, 0x19792d7a,
+       0x9b7765f2, 0xe286b9d5, 0xe88edc1e, 0xb9f4f8ee, 0xb8fcf819, 0xee9c7148,
+       0xf1d1226b, 0x86cb03a1, 0xf1a2d976, 0xf5fb4f5c, 0x5f3fc0d9, 0x3ffd0fd9,
+       0x07716c3b, 0xf77a7d70, 0xd63daf28, 0x78e504be, 0x97432841, 0x4320658e,
+       0xec35f457, 0xe27d93c4, 0x7f91d7f7, 0xa67a9857, 0xddcd18a2, 0xfe425a7a,
+       0x057920df, 0x2687e923, 0x8075f22b, 0x73c20e95, 0x561655cc, 0x53d4f48a,
+       0xa0db9cc7, 0x9d51cf75, 0x30fb04ce, 0x1ba64761, 0xf955edb7, 0xa692f35c,
+       0x4a332906, 0xbf912c5e, 0x0860bb3b, 0x7a8a490c, 0xcb91a4fe, 0x97870bab,
+       0xeef248be, 0x161b237d, 0x362dbf43, 0x5bb57d72, 0x85d8cc0a, 0xe8e8cefd,
+       0x238ec1fb, 0xf3c11c6f, 0xba4e4b10, 0x28bea1c6, 0x6ffa7231, 0x3d6afe3d,
+       0x3d690b9e, 0x76f478c5, 0x83a8a57b, 0x1733f779, 0xabbd3f8f, 0x1c23ff23,
+       0x649e63b7, 0x461de75c, 0x1ff6672e, 0xc74795d5, 0xe7cbf605, 0x1a356e1c,
+       0x4661fc68, 0x8ed7ca91, 0x23cf2696, 0x19e5f3be, 0x75ceef91, 0x915c3bd5,
+       0xef629578, 0xb5f77a4c, 0xcfe06319, 0x4e749749, 0xbbd76edc, 0xaf5c44db,
+       0x896302eb, 0x07fb5f42, 0xf88f1bc6, 0x7fdbc657, 0x70078f89, 0x54be421c,
+       0xf41a0ff0, 0xbea1a347, 0x849f53bf, 0xf82813df, 0xcca1d657, 0x9e626aef,
+       0x8eb11b46, 0xc41bb5e7, 0x8f52314d, 0x54ef91f4, 0x7449cef8, 0x29e486f9,
+       0x1810f4e5, 0x870bf582, 0xec57642d, 0x4b11f596, 0xf88a1caf, 0xbe69f653,
+       0x0513eb91, 0xcff3789e, 0xca54e191, 0xafd74b2f, 0xa2015c1a, 0xc5023d9b,
+       0x90815c19, 0xfb053b29, 0xe739d365, 0x37d8de48, 0xbd87f707, 0xd6ffa6ab,
+       0x8ace9d2e, 0x214df1f2, 0xfde0d291, 0x74c34fb4, 0xfa226fa6, 0x88c93d6b,
+       0x7cee978f, 0x58cdc798, 0x728e9068, 0xc84181c8, 0x9c3fc8b7, 0x0503437f,
+       0x35b52728, 0xf8441dae, 0xaf90390d, 0xbe027822, 0x41b6b2c1, 0xb25d7a42,
+       0xe58b978a, 0x6c9647ef, 0x2e7f11f1, 0x15395ada, 0x98d5a7ed, 0x28bd40f4,
+       0x59d32bd3, 0x4ebcf032, 0x85df6caf, 0xdd3897e1, 0xd4d96c5e, 0x7d02f38e,
+       0x63e233fd, 0xcfb3eb72, 0xbd0ab823, 0xa06edc5e, 0xde90aa71, 0xad74f8a3,
+       0xde7bafbc, 0x693ef4e5, 0x7bf4a1bb, 0x0149eeb0, 0xec38c4e6, 0x443bedfe,
+       0x91fbdf94, 0x9f39339e, 0x70be9ea3, 0x63eb69f8, 0xeb4ecfa8, 0x777bc618,
+       0x39aaac4b, 0x1a3a2f8a, 0xeff1575f, 0x33759dd2, 0x95dcae28, 0xa66ba024,
+       0xf782adf0, 0x1a7b92dd, 0x34b7fff1, 0xdfc65ffc, 0x81ff87df, 0xfe649b7e,
+       0xfc0e54df, 0xb7128f0f, 0xce380a27, 0x79f6296e, 0xfd8d57a1, 0x5710b73b,
+       0x23ef1eae, 0x72355f57, 0x0d91dbff, 0x73df57f3, 0x30effc95, 0x6cdd327c,
+       0x26e8532a, 0x7b71f053, 0xf8839753, 0x3d22bc02, 0xf289bd93, 0xb82b24b6,
+       0x8f45884d, 0x967c946b, 0x72236f8a, 0x5f5fe14d, 0x5853c21b, 0xed16bb56,
+       0x008ae4e4, 0xc145e9d1, 0xf4093437, 0xe7e445da, 0x67e17218, 0x333e5e32,
+       0x1be754f8, 0x32c1c2fb, 0xc0abae90, 0x69f3a2e3, 0xee27055b, 0xdaeed28f,
+       0xf782fdca, 0x9e573e65, 0xf915ffbf, 0x53f78c3e, 0xeface27d, 0x933eb91b,
+       0xdcceb04c, 0x4c67d720, 0x60be2528, 0xc819e9ba, 0x8f404b6f, 0x8f4a2f7d,
+       0x1034345d, 0x38782abd, 0x67fbd32b, 0xcfdd7c89, 0xc41e70c9, 0x5be12998,
+       0x7a0947ce, 0x5af9c0bd, 0x8bbf3814, 0xc3c5fe38, 0xdd11a793, 0xee9b13df,
+       0x246aed97, 0x772c4cfa, 0xb3b9438e, 0x2736ef49, 0x8f258e8e, 0xec765483,
+       0x49f909f8, 0xf7c8c748, 0x0aa0f8f1, 0xa0c580f9, 0x7fd020ff, 0x7429fed4,
+       0x1d717400, 0xd73ca5f1, 0x379285d2, 0x5bb2f053, 0x669b7793, 0x601a78e2,
+       0x25def2e2, 0xfa78a9cb, 0xf3ef2be5, 0x2bf87dbb, 0xe6a054cd, 0x456fdc2f,
+       0x13717c4e, 0xe2679b3e, 0xfa644fed, 0x780ede4e, 0xe4a0627a, 0xeb720b5a,
+       0xe766d809, 0xa63e48f8, 0x595f9e49, 0xa09348c7, 0xf368dbca, 0x6f830629,
+       0x9f0a2984, 0x8d73f798, 0x334bd08e, 0xd81cfce3, 0x43cf946e, 0x5f765538,
+       0xc6912981, 0x40c1ea77, 0x967fd405, 0x0361d959, 0x0ceeeeb8, 0xe1718c54,
+       0x5981db77, 0xbae264f7, 0x853e829c, 0x53ace5d6, 0xdf20ce8e, 0x7c50b71d,
+       0x3ddb3f24, 0x974cfc8a, 0xf7c71f3b, 0xeca4fbc8, 0x6b75bc67, 0xfdbc5cf5,
+       0x21e3279c, 0xcad76e55, 0x2e26418f, 0xf9657a37, 0xf83fe5a1, 0x526f9317,
+       0x3b242fb7, 0x6d8c9d90, 0x326fde07, 0xff5179f0, 0x00d4bf40, 0x23ddfeff,
+       0xdcec27ef, 0xc343c41c, 0xa39d2376, 0x31d7f850, 0xf18e9bcb, 0xe48a4713,
+       0xaeb8c176, 0x7e1a6c59, 0xe8f2efbf, 0xd651bfc8, 0x26e1ff5f, 0x7ea26fba,
+       0x7da19187, 0x57ef209f, 0x0c162cc2, 0xbaf9f109, 0xb1e80763, 0xd3fe2894,
+       0xee89eb07, 0x5103bf80, 0xd93437fc, 0x2d806e97, 0xdbfac1fe, 0xc0b74cca,
+       0x8ccc993c, 0xa82aea16, 0x347c006f, 0x96047924, 0xb675f548, 0x0fe3f181,
+       0x2e4d303f, 0xbf04f3c3, 0x6fbe7a32, 0xc438a54a, 0x1c2cb00f, 0x28b22b50,
+       0x1d99bdbe, 0xb1f955f3, 0xb0738e46, 0x69469036, 0x9ce2f8aa, 0x2f8a2e9d,
+       0x507c8d3e, 0x79fe719d, 0x8da6ae1c, 0x078beb9f, 0x678c8a47, 0x17c4e790,
+       0x115ade29, 0xcf857ffd, 0xc925379e, 0x3011ebfb, 0x1dd0aefe, 0x93da29f2,
+       0xe31d7e4a, 0x2f8a762e, 0xb0ee8907, 0xc23e309e, 0x742a1b7f, 0x61e2b1e5,
+       0xafb64cbb, 0xf23487a7, 0xb17db589, 0x4bd031f7, 0x48b7f835, 0x29976af2,
+       0x54d81eca, 0xc78d2671, 0x439d19cd, 0xe39e447e, 0xffee35c5, 0xe1f28e18,
+       0x947efcb7, 0x80294671, 0xfdc0aae7, 0xe4d33975, 0xda9d90f1, 0xfc1d9084,
+       0xd1cf9add, 0xf37f0173, 0x2f951d73, 0x3cb7b3fe, 0x56d9ed13, 0x032c1b9d,
+       0x5c93ebcc, 0x41650f70, 0x9373d013, 0x2a9b9f85, 0x9079b769, 0x1305bbfe,
+       0x13e99b9d, 0x19ea2f8f, 0xd7da0bb2, 0x411f01b6, 0xb184bbb5, 0xef57844e,
+       0x0ad0f3a6, 0xd89ec77e, 0x63df4794, 0x37dc1be9, 0xcbc55b8a, 0xb6af16df,
+       0x894adc50, 0xf4f71593, 0xb5649d10, 0x61f8ea65, 0x5e8f3e29, 0xd792af5e,
+       0xbef1926d, 0x226be8fb, 0xb2c2b1ea, 0xef68b586, 0xef7d1867, 0x2e4ddd23,
+       0x1339db56, 0x3b76da84, 0x4634d7d2, 0x1fc2827e, 0x20ec5dc9, 0x4f12a986,
+       0xcfd07976, 0x73c17c9a, 0x04a9fd10, 0x77f8132f, 0x24f3e192, 0x58ff70e7,
+       0x07b8478a, 0x13fc29c6, 0xe328bc23, 0x2a5a3eec, 0xd2919da0, 0x46b82659,
+       0x2defa5f7, 0xe04e77e8, 0x5f701ee7, 0xe8687f15, 0x6196462f, 0x2fe9487c,
+       0xbd5cb99a, 0x429be7cd, 0xafa34fa1, 0x349de717, 0xa98ed83b, 0x81558997,
+       0x84f10c76, 0xd184b3d7, 0x02ba8378, 0x27818eb4, 0x9658257d, 0xf7048948,
+       0x3a210be4, 0x96a0312f, 0x5b9231d1, 0xfb25df3a, 0x4eda96e1, 0xf771f701,
+       0xef0443d1, 0x5e0ecee0, 0x9af57cca, 0xb814ffac, 0xa27f644a, 0xd5c38e44,
+       0x8e9f9e5f, 0xecd181fe, 0xa338c12b, 0x12fa8eb2, 0xbf9e3a5f, 0x3ce782dc,
+       0xe73fc426, 0x14966691, 0x8cc1373f, 0xaeecee7e, 0x5a7b4823, 0xf8ed39bf,
+       0xb48fda19, 0xdd1ddcd5, 0x80a57c72, 0xc1e5b5f4, 0x22b37ed8, 0x71c8b62f,
+       0x14f3a8c4, 0x7ad1cd83, 0x9ac932b9, 0xc28f2515, 0x9e722672, 0x9e7cb762,
+       0x6f7aa6c2, 0xa46613cc, 0x27834ea7, 0xdf2b9f07, 0xdf2abce1, 0x71f8a01b,
+       0x961ebe0a, 0x9e68d3f7, 0x1086e749, 0xe3a04e4f, 0xbfb1cd57, 0xd6685987,
+       0xd3977ac9, 0xf4e4eb0b, 0xb688eb82, 0xb999a633, 0xe3cdbd5e, 0x74e7a29b,
+       0x9c788452, 0x476c1454, 0x1e589dba, 0xbffa4768, 0x5274c985, 0x4b44e9ce,
+       0x939bf7ef, 0xa1e93a64, 0xe0260a7b, 0xe43145f7, 0xdb998563, 0xa59d2977,
+       0x0fc03f44, 0x857ce177, 0x03456a83, 0x339cd0a5, 0xf0f8ef50, 0x9e7822f2,
+       0x4769e45f, 0xbc7a737a, 0xa8db8e22, 0xc9ba7277, 0xb8c49ef4, 0xe4aa7d77,
+       0x38d02b5e, 0xe0c736df, 0xa7e416ab, 0x4a7e11d1, 0x5a47e391, 0xc3229cba,
+       0x1cf193e5, 0x43df1e7f, 0xa74a4f38, 0x33f783ce, 0x4c25b9e0, 0x055c4e46,
+       0x96f912fa, 0xd2f9d275, 0x09672aa4, 0xe5a0ddf2, 0xf9f7016e, 0x016fbd25,
+       0x3c76b3ee, 0x350c9f45, 0xbffe8879, 0x6268deb2, 0xf2ff8d26, 0xb5db99b0,
+       0x7e512b1b, 0x8499f2bf, 0xf0a5d5f2, 0xd6f1d1e5, 0xf3745179, 0xf83a5f74,
+       0xa07458a7, 0x3a5a7f95, 0xb50bc888, 0xadbc03fc, 0xedc3fbe5, 0x55ce94dc,
+       0x6a1b9722, 0x7f6f1779, 0x0d0dc8fa, 0x3de98f1e, 0x097ae0cf, 0xf39105e9,
+       0x74f4f1db, 0xae1ff9a3, 0x31cd1ba7, 0xd4ceb4f4, 0x9f3c1bf3, 0x744da2bb,
+       0x5f225c61, 0xf6ba8f3e, 0x4f3a24f1, 0xe09362f0, 0xd1439746, 0x502244d3,
+       0x6127b2bf, 0x4a15bb2c, 0x6ae78078, 0xb2250302, 0x08c759cf, 0x24d633ca,
+       0x1bac70ca, 0xdbb7fa41, 0x51e600a9, 0x256063eb, 0x91d3fa01, 0x684b181d,
+       0xf310783a, 0x988b6b2c, 0xb77000cf, 0x80f3f1b7, 0x485bd62f, 0x7e3eef9f,
+       0x400f37f5, 0x1d71e73d, 0x0e047f1d, 0x4ab673a6, 0x03b145de, 0xe8590e3a,
+       0xb32f703c, 0x7754d1b8, 0xf8790d8b, 0x21fbec02, 0xe8d983c4, 0xe2281fcb,
+       0x77aec439, 0xf1eca38a, 0xccbfd6de, 0xe48ae439, 0x7d0e9a97, 0xdf6d185e,
+       0x14a9f929, 0x3996f7d1, 0x963fdfca, 0x77cb9677, 0x055fb9cd, 0x9c5e309e,
+       0x5da27f1c, 0x2375f04f, 0x48bf687c, 0x10fb861e, 0xe3d648f8, 0xfb94de32,
+       0x0adbba0f, 0xbe80fa4e, 0x98393c5e, 0x7b5be1c7, 0xef7768cd, 0x214ef932,
+       0xf4b7899d, 0xf6a9f9d0, 0xe811deb6, 0xf9fc834f, 0x1ef79f08, 0x9d149b3f,
+       0xeb12feff, 0x3f5a24fb, 0x729f5bc4, 0x1f4b5e3e, 0xda167dda, 0x184dfe0e,
+       0x50c07c4b, 0xb086054e, 0xf567fa20, 0x17adc663, 0x31672371, 0x341dc517,
+       0x999fb479, 0x8e65ffbc, 0x4c679fe2, 0xde21bfde, 0x4efc1e71, 0x05f9d603,
+       0x989ec7d6, 0xdb478f9f, 0xf53ac2be, 0x18fb9896, 0x215afda2, 0xe60567af,
+       0x537cf0fd, 0x3852e18b, 0xef231ddf, 0x8091fb07, 0xdd4a05e3, 0x9fb87d27,
+       0x6bdcd81f, 0x4efa1f11, 0x0091da27, 0xb3b6227f, 0x97ba4aa2, 0x50f060c7,
+       0x3ad5f47e, 0x5bbd7e7e, 0x1e31b8b0, 0x6491dcd6, 0x33f87941, 0xfb1d2f93,
+       0x9d5dd48f, 0x09fa7183, 0x3cdd5e9d, 0x41be53d2, 0xe753b216, 0x8e09eaf7,
+       0xdfda315a, 0xcfeb12fe, 0xe7dcc4b1, 0xc790fb3e, 0xa1f7c5d7, 0xf462e7df,
+       0x3e9c7bfc, 0x45d651f9, 0xfb83f6f1, 0x3cc5c93e, 0x4f81f552, 0x7ead3fc8,
+       0x5b9b48c3, 0x0488c6f6, 0x252be3a4, 0x4b89edb1, 0x1eb75afe, 0x967199ec,
+       0xcb9b922c, 0x23dd2759, 0x61e9a2b0, 0x5e4a3eb7, 0x71d3f62a, 0x8e056743,
+       0x6440bc7f, 0xbd774075, 0x580389ee, 0x94ac390c, 0x097b45bf, 0xfd1f7f60,
+       0x9f9bd4d2, 0x9de6d283, 0x338fb4fb, 0x42a11c53, 0xb3cc8763, 0x88f73d70,
+       0x8fbc325c, 0xbcbce005, 0xe0e74ed7, 0xcf7f8f2e, 0x5c4b1f81, 0x7e5df96e,
+       0xb0ffcf00, 0xbf3047ce, 0x8d8bf816, 0x718aa8fc, 0xd9d7e5ef, 0x3b76fc23,
+       0xdbb0418f, 0x70e13f5f, 0xe68aff41, 0x144094f6, 0xa1e7b4fe, 0xc7d7911e,
+       0x6e745df4, 0x98bfed84, 0x563ef786, 0x829c3bec, 0xec37fdeb, 0xaedfc318,
+       0xf44d5d58, 0x9f22d533, 0x1960caa3, 0x8bfa0f28, 0x0573ed07, 0x5dc7c70f,
+       0xf77a821c, 0xd23b1c4a, 0x75ebf72f, 0xf6801a4f, 0xca14854d, 0x55bf1589,
+       0xbc2d2bfc, 0x3b373b37, 0x58f7e243, 0xb6af9f6a, 0xebdf3d70, 0xf000b336,
+       0x068d23e9, 0xc4eeaefa, 0xcacc3fb5, 0x64f8fd87, 0x06b9c1ab, 0x85eaadf8,
+       0x309bc1f6, 0x48ce395e, 0x5c4f97f1, 0xcba41ca1, 0xf3f02fc5, 0x7d6c9fb8,
+       0xc8f30d24, 0xb5f409ff, 0xdc58e01c, 0x55e7a068, 0xe7a7df8d, 0x5bba6517,
+       0xe52a42fc, 0x3c744f97, 0xaceb869d, 0xdf93fbfa, 0x966ffe41, 0x41c6a39c,
+       0xa0977cb9, 0x74b7773a, 0x575559bb, 0xbacad2f2, 0x8f391099, 0x7e7802e7,
+       0xe79af969, 0x89f57780, 0xc2d2fe5b, 0xdd6f8bed, 0x2eaeeb07, 0xaefb25e8,
+       0x8c8588fd, 0x44db5fa8, 0x71a1dfd2, 0xadd6f5ff, 0x77f29f50, 0xd31f9bbd,
+       0xb239274d, 0xece5c4c8, 0x70fa7d94, 0xff719cbe, 0x615776dd, 0x08797cfc,
+       0xdbd200e4, 0xe18a9f94, 0x79f479bc, 0x5cde6d54, 0xf36b8fc9, 0x029c78e6,
+       0xf2cdf1e5, 0x1c3f0ae6, 0x49cf84b3, 0x1fb7dd12, 0x45f279e1, 0x2f6e45c7,
+       0xfc4e44dd, 0xe3d6e116, 0x107b1efe, 0x6427dde3, 0xf6b89c6c, 0xafbc3ac9,
+       0x012293e1, 0x93ec2033, 0x58f2c66b, 0x2287707c, 0x659cf02f, 0xef5f645e,
+       0xd7092f71, 0x5dbe0d91, 0x1ceab0f4, 0xd5e5ff68, 0x49f0f98d, 0x419eff0b,
+       0xfcb4cf2b, 0x67928ff2, 0x0f0ee315, 0x7ca9d809, 0xcd4bcb19, 0xe568ae5c,
+       0x14a7581b, 0xe4e55a87, 0xa5c0a2f4, 0x5fc57785, 0x3f3058b3, 0xf5177e1a,
+       0x94efa15b, 0xf8acbe50, 0x260b2e6b, 0x50fea37f, 0x3f8635b2, 0xf095fa04,
+       0x07d42815, 0xfd408fd1, 0xdb46fd8f, 0x0025c95c, 0x96673ad2, 0x2772e515,
+       0x416b7fe8, 0x6a313e24, 0xe50e8357, 0x376fd845, 0xc577fda8, 0x72b2c95f,
+       0x795a31ba, 0xddfc98fd, 0x5df3bc4f, 0x3c4af8ca, 0xf184bea4, 0xb91273ef,
+       0x839ca6fd, 0x3967eb5c, 0x933e3df8, 0xd26bc3bf, 0xc8f0eff1, 0xfcf5c4a7,
+       0x83fdc8d8, 0x5c5574bc, 0x29bf09f0, 0x792def07, 0xf7a4efd2, 0x53a7f29f,
+       0x8bbf23f9, 0x79fc67ca, 0x135efc39, 0xc7c8fe46, 0xd18d2c87, 0xe49b04e7,
+       0xb093cdbc, 0xd062d7de, 0xe55623e1, 0xf497a03c, 0xd8d2c2db, 0x567bfdf2,
+       0xe4a5e13d, 0xa087fbf9, 0xc1f1f1dd, 0x097dd1ef, 0x83e26b1f, 0x6e6f250b,
+       0x13f37d2c, 0xc9379f99, 0x32c7e5fa, 0xfd900d7f, 0x9e729047, 0x4f78d1e6,
+       0xff773f30, 0xc31dfcac, 0xa9abfd4f, 0xf3cad3bc, 0x8ff76923, 0xf0073b7f,
+       0x3f036e75, 0xa4ce749f, 0x6cf3bf23, 0x85bcadad, 0xfd8ef0e0, 0xde76511f,
+       0xf1dc329d, 0xfd6355d6, 0x057e726a, 0xdea072eb, 0x876fd30a, 0x5c3e1e3a,
+       0xfa432df4, 0x695d66eb, 0xe846afd8, 0x2315ddcc, 0x79209b8f, 0xff84ac6b,
+       0x5f28219e, 0xed02fd95, 0xfefa2a31, 0xe72b228c, 0x7ce38fcb, 0xa65ab6ff,
+       0xcf25dbdb, 0xfa9e3e6a, 0x195fc37e, 0xf2b43f3d, 0xb4ffe678, 0x8c02f9ca,
+       0xce4894df, 0xdb9d7c70, 0xd635dedb, 0x78997118, 0x8e16bf7e, 0x9e9c6c5b,
+       0xa500f1b4, 0xcf01e254, 0x65044da0, 0x7049d5a6, 0x1803e36b, 0x07158d27,
+       0x8f2b4ff8, 0x3c7ba61f, 0x9f15d5a2, 0xcef8272f, 0x6c9b7dd0, 0x7bf3a336,
+       0x0e9b8a03, 0x60643c62, 0xd90eb059, 0xcb513ea5, 0xc63301a7, 0xba7cb249,
+       0xa4dbcc34, 0xa33f0275, 0x6a9781bd, 0xd69d22a5, 0x4f5d21d6, 0xf168e9f0,
+       0x412c3a13, 0x54e67141, 0x660266e7, 0x0bfeef39, 0xda82f3c2, 0x1db718b5,
+       0x797fbcb4, 0x9f7936f7, 0x84d9bc95, 0xc3c206ed, 0xa63fed84, 0xed84d6fc,
+       0x2885eb77, 0x35693efe, 0x878bff50, 0xff250e97, 0xaa39ce38, 0x26dc794e,
+       0xfc417bc4, 0xadc710f3, 0x8879f8df, 0xb8a8d6e3, 0xab8af54a, 0x5a77c724,
+       0x39f8feb9, 0x9f0169e6, 0xe4a05f3f, 0xfe291b69, 0x9a6a5bb6, 0x40887986,
+       0x43ce8eb5, 0x0bdcf386, 0xf08f79f8, 0x86ef98fb, 0xe2af3fe7, 0xc181eef9,
+       0xf6df2967, 0x03e79999, 0x6461db3f, 0xf25d2798, 0xefe51376, 0xb1d72cb6,
+       0xc364f758, 0x9cf9064c, 0xefcf018e, 0x7ca3fee0, 0x081df653, 0x08fdc24b,
+       0xf9b5c3e7, 0x8bae193f, 0xe9723e72, 0x4869e6ce, 0x93cb1927, 0x563fbc04,
+       0xeaebeb81, 0xbf506f91, 0xe5f7975e, 0x6f55fa66, 0xb55fa18b, 0xe0d3b57a,
+       0x6f52da31, 0x641b5fae, 0x2ab5eafa, 0x78e406e7, 0x6247e637, 0xd633cbec,
+       0x34ce713e, 0x738857db, 0x3149adfa, 0xf7ca9ce3, 0x6c490d9e, 0xfc18ccee,
+       0x37cc98f0, 0x743dcdba, 0x4da5230e, 0x4a972988, 0x17c94924, 0xc545b08d,
+       0x35f2b5c7, 0xd8dd7e06, 0xd0aec47f, 0x3e35ec21, 0x668ac731, 0x9c73e000,
+       0xf2719f0a, 0x9533bf0c, 0xe4a27d90, 0xd49a2e15, 0x6c77dbf6, 0x6dcf3f4a,
+       0xc4b78fb8, 0x6c53db91, 0x297f0282, 0xc5594bf6, 0x2572f154, 0x1b529e4e,
+       0xaffbf010, 0x3f230f14, 0xafb26862, 0x7afd00ce, 0x36f73126, 0xe83c27a8,
+       0x9779412c, 0x883ee554, 0xcbfadda1, 0x0fcaf7f2, 0x395efa33, 0x65f5ef9c,
+       0x7883bd91, 0x4f0efe8f, 0xfaca0fd1, 0x6bdd6f40, 0xb2cd70e3, 0x7d6f40dd,
+       0xcf317c83, 0x58be3fd6, 0xf769708c, 0x81ef1b2d, 0x7fd98d4a, 0xb0feac45,
+       0xd9fdd5cf, 0xbc720de7, 0xa4f9bfbf, 0xf5f0bd46, 0xf17de5e2, 0xbc2c44f2,
+       0xe5d0a86c, 0x009479e1, 0xe963b8b3, 0x7fb62d9d, 0x8b7edc78, 0x9edc462d,
+       0xfebf24dd, 0x49773fe2, 0xe2560f18, 0x507b61cf, 0x9e575793, 0xf909b757,
+       0xb49597e8, 0xb7fb235f, 0x64e7e0fb, 0x8fcdf6ff, 0x025779f3, 0xdc7f2279,
+       0xbf6f9f25, 0xf7fb95ba, 0xa4fd7322, 0x39a8e018, 0x6841606a, 0x606f8abf,
+       0x882116fb, 0x3d5f0bf7, 0x8bea853a, 0x192c09f7, 0xe9e02409, 0x160cefc4,
+       0x425e3e30, 0x8f754e91, 0x7d47a275, 0x7972784f, 0xea9eaa92, 0x3e13df55,
+       0xaa967660, 0xa46fa07d, 0xd5507daa, 0x96fd5578, 0xe13df55a, 0x457f4143,
+       0xd30333d7, 0xd7b3fd55, 0x0faaabdf, 0x13df506b, 0xcbadf8ae, 0xdf0cf5e4,
+       0x2f7d4f32, 0x61084877, 0xbca163be, 0x38e40bdd, 0x52e088c5, 0xc4cb38d5,
+       0xbbf0470d, 0x57de9b8a, 0x7448dad4, 0x68afbdaa, 0x7d754ed9, 0x46fb89ec,
+       0x5e0cf3f1, 0xc675373a, 0xdc5f8ea6, 0xc3035f74, 0x1abed6bf, 0x6afbd5d3,
+       0x886e5976, 0x7a9e6b37, 0x6f7c999f, 0x766f168c, 0xbfff7ab7, 0xed19bc69,
+       0x0c193c6a, 0xe31d8b3e, 0x44abad80, 0x5cb2defa, 0x4bee4e7d, 0xed93ddc4,
+       0xcaeee231, 0xcf376abd, 0x0dffb4a7, 0xd04664f3, 0x173c0634, 0x8536e455,
+       0x48e627f3, 0xaf2b5d9c, 0x75e41294, 0x2af29d8e, 0x5ad3bc91, 0xff21df86,
+       0x2b708bde, 0xf7588979, 0x05ce6880, 0xbe71c68e, 0x4d0afdea, 0xd240e7f8,
+       0xae76f983, 0x51ec0b07, 0x8739507a, 0x78c1e8a2, 0x897928e3, 0x4870a578,
+       0x0f44b8a4, 0xc86257e6, 0xbfdb6ff1, 0x7be93ea6, 0xf6dbf38e, 0xe0bf2882,
+       0x5047bdfb, 0xefde039e, 0xedd9f5c5, 0x888527a0, 0xd589fc9e, 0xf3d3fc41,
+       0x3c38311b, 0x48be7233, 0xe1689fc9, 0x0f7cd62d, 0x87b9a6d9, 0xb73c7eb4,
+       0xb9dae63b, 0xdf2c3d5e, 0xd7235143, 0x7a76346b, 0x8fee7acd, 0x6d15bde2,
+       0x8d5ff651, 0xe7fd4edd, 0x106a4be8, 0xf70b46ee, 0x8105eaab, 0xa67d78f4,
+       0x6e3ef340, 0x71f6a52a, 0x5c6a92f6, 0xacb930f7, 0x2a5e58c1, 0xed443bdd,
+       0x5efb1892, 0x6e765582, 0x7896cf2f, 0xddfd2fff, 0x0ee60ad4, 0x9bbe44a5,
+       0xd3be7162, 0x3d83c6d7, 0x140ece79, 0x3bf55f8b, 0x9a1fc42a, 0x3f1d0ade,
+       0x43e70f63, 0xfaf9fbe8, 0x66e7aecc, 0x109ebee0, 0xdb1e78dd, 0x1d602a75,
+       0x57c7829b, 0xa02256f1, 0x8d6cad93, 0x038bea19, 0x18f78a2e, 0x8fb25fc0,
+       0xcbddf08f, 0xc7c24cf6, 0xd3219398, 0x789f6858, 0xe3107bca, 0x58b3b9c3,
+       0x06ed8a12, 0x7f0530d6, 0x55b0291f, 0x5ab31bce, 0x19abfdfa, 0xe8a52b25,
+       0x5ba94073, 0xe2f3a61f, 0xf87579ca, 0x28fc4167, 0x9e47dff7, 0x4338f3f3,
+       0xe32f654d, 0x98e5297e, 0xc578ec60, 0xccbbf96c, 0x5ddef587, 0x5a63dfb8,
+       0xbddee8ba, 0x5b1c8ac5, 0x9defa3a0, 0xe1f793ef, 0x0f3cadbe, 0xbf5daecc,
+       0xce46162e, 0x0cf8c1fd, 0x2cf173f9, 0xb3bbdd3b, 0xbe932db8, 0x815e668b,
+       0x6d351be2, 0xbf497b6f, 0x44e0984c, 0x01f3d37f, 0x4b7ef013, 0x039701c4,
+       0x952efbea, 0x95efd37b, 0xa77ca7d7, 0x8372f20a, 0x78bbf015, 0x81a1dd6b,
+       0x2f7bde30, 0xa18fba31, 0xf240acf0, 0x37168981, 0xcb85edda, 0x05cfba04,
+       0xbdd1f40f, 0x6d862314, 0x7e3b8e8b, 0xb78bcb2a, 0xe5a078fe, 0x9c297404,
+       0x2a48f952, 0xfda768ec, 0x5dfc54c2, 0x95fdc2a8, 0xa338648f, 0x7b2a9bea,
+       0xde11bb07, 0x80cb530b, 0xe760fe4e, 0x85d74cf0, 0xd9bbfcf4, 0x543fca4e,
+       0xd20f24d8, 0x9d2d8569, 0x80ae37ee, 0xf400bdad, 0xdfa3fd35, 0x9f2e51eb,
+       0x05f7cbb2, 0x5c5cb2e4, 0x77c3b267, 0x2accf89e, 0xaf10339f, 0x0fb68d8d,
+       0xe539f4a3, 0xacdbba47, 0xf9586994, 0x3fe53666, 0xfbb4f795, 0xdf9f9cfa,
+       0xf0ec9873, 0x57fdc79c, 0xfade81fa, 0x93ddeb1c, 0x1db97f3f, 0xfc52bdc6,
+       0x17082197, 0x677e8fe0, 0x4ebfb941, 0x296dc719, 0x3f2762b9, 0x3f717986,
+       0xf9e3936e, 0xbb6d9d93, 0xebb7dd71, 0x0e516b42, 0xa9fef9be, 0x28671c64,
+       0x3eb8e078, 0xf5d573f8, 0x4570bee4, 0xbf7abee4, 0xf9f0a70b, 0xef2bbf0b,
+       0x8bc79b9b, 0x500df7bb, 0x0eed8bc5, 0xbfb86fbe, 0xc0937fd4, 0xcfd9f1ef,
+       0x937c564b, 0x9055fef7, 0x05824f7f, 0xe577e844, 0xc00fde4d, 0x66a87f21,
+       0x13a270ff, 0xb3cb839f, 0x51e7acc9, 0xb6e4e75c, 0x87efa77f, 0xf2792b27,
+       0xb93cea0b, 0xe2a59f0f, 0xf43d23b5, 0xb5f7701d, 0x63796fde, 0x43a95bf0,
+       0xfbf0fbc9, 0x837ec3f0, 0xf87e1f7c, 0xec5342bc, 0x7197f0fb, 0x89f120ca,
+       0xc52f0fdf, 0xe12fe03a, 0xe907f9ef, 0xc166c1fc, 0xb04c798d, 0xcfef5483,
+       0x87ded3c8, 0xf17fefcf, 0xe3df93c9, 0xc91f33ee, 0x1e194adf, 0x5dff1b5f,
+       0xcf3c0e82, 0xdeea7803, 0x51377fc0, 0x777fcf7b, 0x05b7e739, 0x4ba085eb,
+       0x553bfba0, 0xd6650bed, 0x6776085e, 0x3cec9328, 0x3dc477cd, 0x5c5f6c5e,
+       0x041befcc, 0xded34fbb, 0x754fe0a0, 0xf961ec4f, 0xfe1671f7, 0xf237d658,
+       0x64f32fbd, 0x590f31f8, 0xaf591692, 0xf9147fa2, 0xe16050b9, 0x1abee9f7,
+       0xed463ef9, 0xbb95e7fa, 0x36f3cf09, 0x761c6e08, 0xd067aff1, 0x078053f7,
+       0x2f995e95, 0x837e73af, 0x6ff3e740, 0xb2a98f76, 0xeeb845ee, 0xaef6becc,
+       0x50587ef6, 0x5f842e6f, 0xc6b1f990, 0x49afe1c8, 0x885f7466, 0xba25ec90,
+       0x125dc780, 0xf83b0f94, 0x0de10b39, 0xe627c923, 0xf2937b05, 0xe44e6574,
+       0x85058143, 0xcffaa3eb, 0x30fbe1af, 0xf842e7c2, 0x12c98efb, 0xc74cdbf9,
+       0xca3b6dfd, 0xd223d01d, 0x4e10dac9, 0xf2b126b7, 0x67bc0731, 0x20f06aea,
+       0x342e58cb, 0x2cdcb085, 0x3e7bbbc7, 0xaffc1134, 0x846cbe0b, 0x2a18a27f,
+       0xe79af927, 0xee93341b, 0xcaf9e3af, 0x167f328d, 0xaefa06b1, 0xa26b3260,
+       0x527598b2, 0xa1eb0779, 0xac5f83d2, 0xe03da364, 0x798cb2a6, 0x6aca9ca9,
+       0x0d672ca9, 0x712b7e54, 0xc002625e, 0x51359d35, 0x39e402bd, 0x32890bdd,
+       0xf74de319, 0xeecec89a, 0xac1cd37e, 0x0e6af800, 0x38bcb918, 0x577d2560,
+       0x08466073, 0x1fddf9e3, 0x7bf85cd9, 0xa7b176a0, 0xbf48e29a, 0xf7f93ab6,
+       0xbdd52e34, 0x2bb935dc, 0x78e3f77b, 0x7c7f421f, 0xbaad9e90, 0xafe27ba7,
+       0x7a8f907f, 0xe1ade260, 0xe81cf27b, 0xcb6d5fcf, 0xcafe3f26, 0x9446dd40,
+       0x5219d5d3, 0x7ab7e23d, 0x95ee8598, 0x05d3cee9, 0x415b2824, 0xe9fde3fe,
+       0x05efe06f, 0xff26d940, 0xf901c05e, 0xde10f57e, 0xdab60eaf, 0x951e7f21,
+       0x95377e1d, 0x5445fc47, 0xa87bf51e, 0x397f31df, 0x5efdc795, 0x9d1eaf2a,
+       0x77c7df4f, 0x839e9fa7, 0xc87427bf, 0x19a4f951, 0xb28fe1f4, 0x44fc2e7c,
+       0xfdf4eb08, 0x45aec0c8, 0xd508fdf8, 0xd7d67f41, 0xd19dd2f9, 0x555352ed,
+       0x92ea1db8, 0x7008fdfc, 0x629e93d2, 0xea4527a8, 0x118dfdf8, 0xbc199ce3,
+       0x57f3065e, 0xfb5220bf, 0x303f7811, 0xc72bd618, 0x2e094ca3, 0x03461f2e,
+       0x74e18cbd, 0x7c65df83, 0xea99d5d8, 0x69762310, 0x4e5c13e5, 0xedc0be54,
+       0xec67cace, 0x9eeef7f2, 0xef0d2132, 0x89cb511d, 0xf94c45f9, 0xbded13fd,
+       0xea2c45a5, 0x83b9983e, 0xe60f2475, 0xd3f756ae, 0x4ce807ca, 0x95aad3bf,
+       0x643a1f0b, 0x8d9733fb, 0x97faefc1, 0x1d93b1cf, 0xa76ec976, 0x763f7a73,
+       0x0164a475, 0x44fbd5bc, 0x0ab413ca, 0xb5b07640, 0xeab8de7f, 0xced0136e,
+       0xd7a7159d, 0xbeb1b8a6, 0xaefc49fa, 0x4ff352e2, 0x233aa4a7, 0xf4ec59f5,
+       0xdda007c6, 0xddf56eb9, 0x2ffac0f7, 0xb8c0bd23, 0xfc0d5b97, 0x12939b1e,
+       0xded32efd, 0x0b21af4c, 0x763f7bea, 0xa6ff3c33, 0x99bbf5e0, 0xbddbfbfc,
+       0x2b41be99, 0xa7deab47, 0x1afd61df, 0x6bf133ef, 0x00dc2fbe, 0x8a7bed7e,
+       0x7efbdb5c, 0xa77f0dee, 0x6dead976, 0xcea27243, 0x37d32c15, 0x658279d1,
+       0x921e5fab, 0xa5cdf603, 0xe88d96e2, 0x7835ef77, 0xf942ef12, 0x71e06cd5,
+       0xec904366, 0x89af4f80, 0x02466f34, 0x0609fbd7, 0x7c249f6e, 0x3d446a68,
+       0x1382f603, 0x6bdcafbf, 0xa439f0e6, 0xc112572e, 0xc2c3ebc9, 0x86f1f1ef,
+       0xf7b97025, 0xb25eb5e9, 0xd76e7ba7, 0x8082efd3, 0xc4faa07c, 0x6884523b,
+       0x226f67bb, 0x8af3de7f, 0xcc52fd48, 0xf1e8c49e, 0x2f1debb5, 0xdcd7b7cf,
+       0xc53f1aa3, 0xd653dfc0, 0xe36f9da3, 0x9de51324, 0x496e289e, 0xb2ebfcc3,
+       0x207bfe12, 0x8abc3245, 0xa3f1357d, 0xe1a3dba9, 0xeeff289b, 0x26e4ceb0,
+       0x557079fa, 0x7dfa38e2, 0xe297a742, 0xe71e73fb, 0x38f269f5, 0xe08e4520,
+       0xdcb9e772, 0xf20cd153, 0x28657c39, 0x79e417b7, 0x8afd608f, 0xf510a7a1,
+       0x24aab886, 0x33de0030, 0x9f495e3c, 0xd5d719f7, 0x6f34b005, 0xe1036468,
+       0xcdcdc2f9, 0xa13df70c, 0x8a176cf9, 0xefe69499, 0xaf6d7c53, 0xd813a641,
+       0xfe51998f, 0xa96736d7, 0xd7e60137, 0x391db939, 0x4245ac7d, 0x467a607b,
+       0xf5f9d906, 0xcc1cc1a5, 0x308cf70f, 0x3a627c53, 0x9f80258c, 0xc5886c72,
+       0xd412fe83, 0xcf58893d, 0xa7fd4c98, 0x86591d8f, 0xc658f87a, 0xb78c74f7,
+       0x9e2bc7af, 0x5fc0658e, 0xc21fda0e, 0x8969cf57, 0x963eafbe, 0xf92a74b1,
+       0xbd382315, 0x6c78cb1f, 0xd22bf62a, 0xc2cbee05, 0xf289a176, 0x70278fae,
+       0x0c5d3f3d, 0x09efc71d, 0xcef819ef, 0x566ff471, 0xc77ec826, 0x622b9018,
+       0x5c981fc4, 0x9f8edcd4, 0xde7b15cb, 0xeaea829e, 0xb73ff28e, 0x26f1e963,
+       0x2f7aa196, 0x03ae3d9d, 0xccdf32cb, 0xe8731032, 0xf88e3caf, 0x70f55a9e,
+       0x01ffd607, 0x88e3cafe, 0x55c992e7, 0x9f37fbf4, 0xa3e5dfdd, 0x7024e93c,
+       0x7dc463d4, 0x4b09f622, 0x781af7e2, 0x485f5092, 0xdf7db86b, 0x7b244fb3,
+       0x39751582, 0xea6e5c74, 0x33aafe90, 0x9e90d2bb, 0x38f207eb, 0x976715cb,
+       0xfdf2ea83, 0xf322ff02, 0x57624541, 0xc561d21a, 0x9e0261be, 0xe1e2bd3b,
+       0x56a04a76, 0x3061e7e4, 0xff2694cb, 0xd51678ee, 0x93fceec9, 0xfcf5ebc0,
+       0xf3d676ee, 0x23ed237d, 0x2f10cf8c, 0xe30f0f3d, 0xeabe0170, 0xb92f5ef1,
+       0xb983c33f, 0x52abf748, 0x87f21ee9, 0xfc24a72c, 0xe3302469, 0xae3e50d2,
+       0xe276ca68, 0xef06cdf3, 0x15f71a4c, 0x96e389c1, 0x3c966cef, 0x2a4fd236,
+       0x90f41e3b, 0x7ba7eed6, 0x3e32e687, 0xd126dcdf, 0x9aba0663, 0x03fcd2db,
+       0xeecd2e81, 0x8ff7c832, 0x4d6bdea9, 0xfa9f74e0, 0x4fba66cb, 0x87ce1976,
+       0xee81ab65, 0xab365d95, 0xf1443245, 0x3dd6b2cb, 0x577cafd4, 0xcbc5e533,
+       0x2f64ecf3, 0xeb0d634f, 0xdf2d5f28, 0x53e3e457, 0xc9add3b0, 0x65003fcf,
+       0xbe399fc5, 0x3efc53d8, 0x0f83f9b5, 0xbb2f91d9, 0xfc53960a, 0x942143e7,
+       0xf8bd001a, 0x0ee76650, 0xc92e1ff4, 0x0fd68ef6, 0x0b1dfad1, 0xa2a7335c,
+       0xdfd7d149, 0x38e8b660, 0xb03f168a, 0xdef11b1d, 0xa24d45a3, 0xd131ef13,
+       0xfe0a23fa, 0x953f78b4, 0xc7db2290, 0x3f706320, 0x20eca69b, 0xfa71933f,
+       0xd6017b20, 0x987dc971, 0xd39ab3ee, 0x6279efc4, 0x8a14a13d, 0xb3f06b03,
+       0x8cda1f41, 0xd60549f7, 0x02fee819, 0x5c02fe1f, 0x8dfdac52, 0xec4a27ba,
+       0xeb2d3f5b, 0x5bcf3ecb, 0x7a775fb9, 0x1b9f28bd, 0xdbcfb751, 0xb3247f97,
+       0x26fbe31f, 0xeed27df0, 0xcfd002c7, 0xdf8217e4, 0xafa97287, 0xdfa5e85f,
+       0xfed9b883, 0xdffff828, 0xc7a90a29, 0x00008000, 0x00088b1f, 0x00000000,
+       0x7dedff00, 0xc554780b, 0x3d9cf0d9, 0xcd8dcd7b, 0x09c246fd, 0xb8094404,
+       0x9fb1dc24, 0x4a34021b, 0x414045d0, 0x2dc8d812, 0x088d9242, 0x59b6b696,
+       0x5a4062e4, 0x7da5aac1, 0x2c142ea8, 0x11a0d05a, 0x86ec5d43, 0xba8b4508,
+       0x8ad45cb1, 0x14178026, 0xb16d0042, 0xfbdfad1f, 0xbb2733be, 0x6a2364e7,
+       0xffefefd5, 0x27a3cbff, 0x9cccce73, 0x997ef799, 0x6318c399, 0xb17fc39f,
+       0x50dff876, 0x261d8ac6, 0xd8c21b27, 0x4fab569c, 0x8a6c61c9, 0xef74676b,
+       0xa79cc624, 0x18564c0d, 0xedfd2e6b, 0xd543262f, 0x8ad79b24, 0xcb7693f7,
+       0xcd942f0e, 0x3b58eef1, 0xdaf4b7b4, 0xd5f6c468, 0x512c490f, 0x6724ac62,
+       0x618b126f, 0x9b0e576c, 0x7783cae5, 0xd0daefe1, 0x950ed135, 0x6cdb1992,
+       0xfb622577, 0x1b32dee7, 0x1ec60f58, 0x87f5e78c, 0xe3db99bd, 0xfd5098b6,
+       0x687f5841, 0xd5b23ca8, 0x467f58c0, 0xe8c79c3f, 0xb318a30f, 0xebdfca86,
+       0xaf94d048, 0xa9a198bd, 0x68fac85f, 0x0759179e, 0xb38f9e68, 0xdfca6817,
+       0xa9ad1b4f, 0xa4529d7f, 0x3fe84f29, 0xa27f5341, 0xbca6b263, 0xeb8ac8d6,
+       0x63675e61, 0x8f4b5e8c, 0xd8463cd0, 0xb787040d, 0x478702d3, 0x683b584b,
+       0x8576c572, 0xa98d5957, 0x7dec35a3, 0x9c38da0f, 0x819c5d58, 0x4eec630d,
+       0xffa899f5, 0x58df0143, 0x7be0d599, 0xdd46a303, 0xb5bc046f, 0x160d941f,
+       0x42f32fc0, 0xcec614bb, 0x1a17768b, 0xbe207a0b, 0x7f7e01d8, 0xdfdf8d91,
+       0xded1f025, 0xc335e0df, 0x816b5bb8, 0xde85fa26, 0x660c56e3, 0xdd7e1843,
+       0x8259b28d, 0x730370f2, 0x17dd7be3, 0x1059cccd, 0x5163071a, 0xde76bdfc,
+       0xe64e3abf, 0x8defe68c, 0xaedff7e7, 0xec62e245, 0x5d2b5a9d, 0x82cf0e7f,
+       0xc0633e38, 0x691fa0cc, 0x34f8cc74, 0x06f6b7a0, 0xfa016ec9, 0x366c6cac,
+       0xed17f8e3, 0x316549cc, 0x5ea7e15d, 0x31a6d78f, 0x5aabfa05, 0xd52ab2dc,
+       0x1f6ef401, 0x682bf752, 0xe303555f, 0xb1a91200, 0x965bab0f, 0xbb62d8cb,
+       0x6716f442, 0x7f43f981, 0xbff4feef, 0xf0073ccf, 0xd4b3fe3b, 0xfd07e47c,
+       0xffb559f3, 0x17e8f4fc, 0x27f77f3c, 0x83f63f7f, 0xd3ff6a2f, 0x65fbdecf,
+       0xc6eef3d8, 0x932ebb3f, 0x30746129, 0xace1cccc, 0xe90cb7af, 0x3b3ffa0a,
+       0x358f1fea, 0xb2497f43, 0xe01d997b, 0x27cd7edc, 0xc51e0cd9, 0xcc34bf0e,
+       0x37e2131d, 0x095ffb7d, 0xb1bc037e, 0xfb338018, 0x15b7cd81, 0x0ddf06e9,
+       0x924b63e5, 0x5e906b7d, 0x669ac15d, 0x95b1f718, 0xe06b1c7d, 0x0ec7e53d,
+       0x86f7338e, 0x2f3cb1f2, 0x24cbfbc3, 0x2cfb8307, 0x3a446acd, 0x5703899d,
+       0x2b2ef868, 0xd31674e0, 0xf9d02dd2, 0x7c61adfb, 0xb6a96b33, 0x96d5ee5c,
+       0x61fce387, 0xd899cf1e, 0xbc30fab4, 0xeffcc4fb, 0x047c2f89, 0xce3b8be5,
+       0x5376e54e, 0xfac85dc7, 0xbfb4f58c, 0x81fa2d1f, 0x32008e39, 0xb7b2f1c5,
+       0x9fcf34ac, 0xf89183e1, 0xf2266f3f, 0x4f82dbe3, 0xd6c4c4cf, 0x6707c049,
+       0x6f070e14, 0xd2e1cc8d, 0xed056013, 0x6e2777ab, 0xdfc0b822, 0xb3ee5451,
+       0xa4c7cb19, 0xde17b240, 0xfb07265b, 0x28cffbe2, 0x1d630fad, 0x4668e2ef,
+       0x53b491ed, 0x10fa7c04, 0x30f3148c, 0xe7801f01, 0x69d946cc, 0xf1f0441b,
+       0x29a3e0ea, 0xa8d0fe8f, 0x43af7f29, 0xa2f6be5b, 0xb4c85cb6, 0xdaac8bed,
+       0x8e02cbf2, 0xfbdaece3, 0x96d34fdf, 0x1e3a55df, 0x1d8bf2e2, 0xf3c30dca,
+       0x259521cc, 0xcfe00e2c, 0x179c66ec, 0xb864f78c, 0xc11e2b1c, 0x3adb78e1,
+       0x21cbe7c9, 0x5f9e6afc, 0xecab1cc7, 0xdaf74879, 0x418bf0fb, 0xe82b9a7a,
+       0xed3aee67, 0x19dfebf3, 0xbc019e35, 0xe325d84e, 0x207f78fb, 0x4e78881b,
+       0x419f738c, 0xc744f03e, 0xc37d420d, 0x46b9ede4, 0xabd9ff78, 0xe3990e6c,
+       0x3b21cb81, 0x3938ff1f, 0xe7c011c6, 0x058768fe, 0xd3da2d6e, 0x8fe51527,
+       0x37cf5eda, 0x52dc800f, 0x9c7be1fa, 0x99af4867, 0x25d20559, 0x28fa021b,
+       0xe4c2c81d, 0xf6878f8c, 0xceb71dcf, 0x3be04772, 0xef955ce0, 0x77c8259c,
+       0x35f4e63f, 0x1ec8cda6, 0x352c71c7, 0x9c20b26d, 0x8fc427eb, 0xb999fa03,
+       0x5b9df38c, 0x3064ac0a, 0x647b99bf, 0x25cce782, 0x44498f92, 0xf435e72f,
+       0xbea0f022, 0x5e71f00f, 0x329a5fc7, 0xfdd12850, 0xecc62683, 0x678ebef0,
+       0x1466df25, 0x648d53d9, 0xbb6d542f, 0x337047c2, 0xef1117b2, 0x2a8f816e,
+       0xa81e2323, 0x0658fe04, 0x4bd4e7f5, 0x178fae34, 0xa8067c5b, 0x261db55f,
+       0xae3fcf08, 0x2824f931, 0x3328dc7f, 0xbeb10fce, 0x7db550be, 0x7c2f2f3b,
+       0xf82d96fc, 0xff3c5dbc, 0x2db8fb78, 0xa2b5bef8, 0x9062ef7f, 0x6ddf504b,
+       0x3e6b5664, 0x0259b75c, 0x63b7a076, 0x4757f651, 0xe8ed3d21, 0x3e0cf0f3,
+       0xc618c524, 0xab59c74f, 0x85d0e109, 0x9f03b69f, 0x2be575c5, 0xa0f1d237,
+       0x50b9f4ae, 0x839039aa, 0x9267e372, 0x95d2ab63, 0xa974f54e, 0xc17cedd2,
+       0xd9b3d01f, 0x1bca1035, 0x1d38f5f4, 0x1fd635ac, 0xb9e715b9, 0x3bfea642,
+       0xb71009e7, 0xdc2d4902, 0x28c8f7d1, 0xdabe5e78, 0x32efe884, 0x33f3aecf,
+       0x6ce6fcd1, 0x673274e7, 0xa453e4a9, 0xcfd5f3ae, 0x98bccbb3, 0xa63d956b,
+       0xcebafceb, 0x218fd383, 0xf1104876, 0xa2d1be75, 0x9dd1fda0, 0xab5d3b7e,
+       0xff411b64, 0x675adbb6, 0x238c0732, 0x2575bb7e, 0x907688c8, 0x179fa8c1,
+       0xec5ddfac, 0x2d39be05, 0x4a6f7971, 0xf95874e6, 0x5926ea74, 0x6953f50a,
+       0x4073f40e, 0x15e3bbbd, 0x81a56382, 0xc1fa09eb, 0x4e0f4e38, 0xc606bcd8,
+       0x856de601, 0x32679fa6, 0xe361c937, 0x8604b4ab, 0x3b41fa69, 0x7c9fbc26,
+       0x1c19cfde, 0x9fa85e4f, 0xf1da5daa, 0x9a839954, 0xfb0954f1, 0x0ce7ed48,
+       0x9fea078e, 0xf784f1c1, 0x3c769cf3, 0x66a09655, 0x769d553c, 0x9f27e895,
+       0xae55d3f7, 0x73f634f8, 0xb64e7d55, 0x2b4f0c31, 0xfb1631af, 0x0f4dd822,
+       0xbff973c4, 0x7ecd9b70, 0x557eac32, 0xeca6bc7d, 0x9fb74c69, 0x859fa30c,
+       0x3bc807f8, 0x032418b6, 0x314ad3c8, 0xfbb291c4, 0xa3d47881, 0x011faf49,
+       0x5b559a0b, 0xa748cc3b, 0xfcfa5d8c, 0x865861f3, 0xcf1c653f, 0x38450394,
+       0x1d93469f, 0xf00cfd59, 0x71e017bf, 0xf5f061c6, 0x7fddf986, 0x119b83e9,
+       0x4dbb313e, 0x7940f709, 0xab45e3ad, 0xdb5fe302, 0xe5f62a68, 0x67dddea1,
+       0x5f261d9d, 0xfdb93ad7, 0xeb019ccd, 0xfba181e4, 0x8f5f8331, 0x0cf17b43,
+       0x5e2316b3, 0xd6031ad7, 0x587061c1, 0x3eaa2a0b, 0xc5765c02, 0x5fd744cb,
+       0xb54b2e1b, 0x01e15170, 0xf085d9f0, 0x535b58f1, 0xffbb4ed0, 0x6871e39a,
+       0x360d15a7, 0x9ca7a44a, 0x9721e912, 0xabaff39f, 0x0d7f2644, 0x08525626,
+       0xf441bbf0, 0xfa0ad677, 0xdbf06ae9, 0xd885091c, 0xbc71c6ee, 0xd2f978dd,
+       0x9e50c9a1, 0xca993dfc, 0x4d99eeaf, 0xe2600d72, 0x27bc0008, 0xbf258d4f,
+       0x3863fa0e, 0x9fa8a9be, 0xe126d481, 0xa937682d, 0xe005f258, 0x308e377d,
+       0xf3e70f1d, 0x796d4e49, 0x0cb6b172, 0x335f91fd, 0xafbda5d5, 0xe28759da,
+       0x07de9363, 0xb1458c17, 0xfed1cf8c, 0x6632fa11, 0x1f6b5ef0, 0x11d9d718,
+       0xebcd0766, 0xeca9dfd2, 0xb6c0c6bd, 0xa7337b62, 0xb28d9ffb, 0x84e796fa,
+       0x443dfbd3, 0x030e4db7, 0x37fb6133, 0x9bd43e2c, 0xbb33db7f, 0x77a08b17,
+       0xd198ed43, 0x35e34690, 0xdcfeb832, 0xfd8c51d4, 0x067bfcff, 0x8ffa0cb6,
+       0xfb76651b, 0x27bfb422, 0x4231f85e, 0xef072dde, 0x2f2dfd0f, 0x256c728b,
+       0x3f2148bb, 0x58b7f54d, 0xab2a1f5a, 0x340c967e, 0x34fa4419, 0x9e3d1076,
+       0x81e9f7f7, 0xe68d8ce3, 0xa07f3c78, 0x2f6e1ed9, 0x047fa234, 0xd01fc676,
+       0xa36b823f, 0xb5fd7fb0, 0x00bf2a76, 0x035e0e7e, 0x4ff90ab5, 0xd3fb6b7b,
+       0x075ac5f5, 0x8ed7f75d, 0x5a81eba0, 0xb97bd527, 0x07ae98b6, 0x75745d6b,
+       0xf9f025c7, 0xec5db918, 0x920afe79, 0xdbafe073, 0x88e28612, 0x3e20066b,
+       0x793e3bcf, 0x0af0b7f2, 0xafd3a8cf, 0xacf5c116, 0x735771d4, 0x3ff9fc98,
+       0x3f074fcd, 0x7fc71728, 0xef5d7f39, 0xb73d542f, 0x70179763, 0x87a9e0b4,
+       0xfbcc18e2, 0x0a5d7194, 0xadcae1ca, 0x709ce32b, 0x0e3bb305, 0x9f29e1f5,
+       0x3e891c5c, 0xfa54134a, 0x2848c670, 0xabe718e7, 0xefb89e8f, 0xbfabe406,
+       0x51d9356d, 0x7ec0785f, 0xae7e80b1, 0xf89db86e, 0xbc6dca12, 0x1939ef7c,
+       0xfe5a8dcb, 0x87bbf059, 0xa2589452, 0xb74e4cbb, 0xdba44c81, 0x8def2dea,
+       0xb0f23a47, 0xfad3d20e, 0x8bfef876, 0xbd4f7a00, 0xbd7e8e5c, 0xffcab9fe,
+       0x9eae411e, 0xc9cefb86, 0xab57f871, 0xafaef119, 0x0e34815f, 0x41313c7c,
+       0x3670f1f0, 0x156ded1c, 0x4c97cc1e, 0xf73f2cfc, 0xa86d419b, 0x39fcb7bf,
+       0xcaebca4e, 0x67ebe7af, 0xa507fa3f, 0x176cfe7b, 0x6bd7af74, 0x200c234a,
+       0x7e7e8a15, 0xe20534ad, 0xb9fda346, 0xacf244c9, 0x1f6fc772, 0xd3da35fb,
+       0x7d1c5a6f, 0xf69bb415, 0xe505191d, 0x494d3b85, 0x311a7c25, 0x2f084a52,
+       0x696ff81e, 0x0b0f087e, 0x5667d99e, 0x77fbf206, 0xb1f08427, 0x99936770,
+       0x8f0aec0d, 0x7326faa2, 0xbc044c6b, 0x478db7d4, 0xfb9f96be, 0x7ef119a7,
+       0xa58905ea, 0xe78044e6, 0x6e717da6, 0xa3c22701, 0xde2753c0, 0x803df574,
+       0x1553a417, 0x57e7fa4f, 0xc67a7027, 0xa23c94fe, 0x00ff27e7, 0xcb78a9f0,
+       0x57f9c0e2, 0x1c67793c, 0x6303e3ce, 0xdfeba70d, 0xc2714cac, 0xde4c2b7b,
+       0xf95d3b14, 0x96478afd, 0x6fcdbd10, 0xc8c29259, 0x1ba670ee, 0xd33cd046,
+       0x37737e71, 0xcdf9a54e, 0xbba26e63, 0x2ec8df8a, 0x353e2bb4, 0x119de2b2,
+       0xc175e2f8, 0x066c1f17, 0xfbf3046d, 0xef73c840, 0xcb8fb2eb, 0xca183bcd,
+       0xdcaa25c9, 0xfca88b64, 0xe9e395a9, 0xe08304f1, 0x70f2e02b, 0x6f72dd7a,
+       0x51f3f110, 0xfd153396, 0xbf030f47, 0x7d21f797, 0x2dcafd0e, 0x7e3952e3,
+       0xed4cbdb8, 0xc2290ec0, 0x683f58fb, 0xac3b7f22, 0x273cfb1d, 0xe2c5fef4,
+       0x28ee30fd, 0x07f3e409, 0xd36edc29, 0x095fefcf, 0xbf028e3c, 0xafa30b20,
+       0xfce6fe30, 0xe73565be, 0x7ddf956f, 0xf9f18a93, 0xff388727, 0x7cccbb60,
+       0x9520571a, 0x914d379e, 0x58581e48, 0x6f5f1220, 0xd6be0931, 0x04e9573e,
+       0x38c46dc6, 0x60bd2746, 0x7f0409ff, 0x3de787b2, 0xe4c2ed08, 0x17df07a1,
+       0x953fb5d7, 0xfe0be76f, 0x3ff9057f, 0x6cffc43a, 0xeefbe723, 0xf097adf5,
+       0x3df26957, 0x57e46bf6, 0x82af4fe0, 0xe1726afc, 0xdede3fbc, 0xf456e47c,
+       0x3e55eb1b, 0x3d4fcad5, 0xbd3c569f, 0xcf53e88f, 0xefd71fa7, 0xa7c8894b,
+       0xb4a5f73b, 0xd3e245e6, 0xaa7e56ef, 0x2754fbf0, 0xd879553f, 0xf2f51c1d,
+       0x250481f0, 0xdf843ca2, 0x2bac3621, 0xa774a9fd, 0xdf82dbd2, 0xb942f557,
+       0x2a9749d3, 0xa5d275dd, 0xf9fa774a, 0x7fa7e16a, 0x158047fe, 0xb90df9e2,
+       0xf7da1863, 0x45b8c153, 0x03054dbc, 0x6b1f34a3, 0x4d5f11a5, 0xfef3e311,
+       0xb7184983, 0x79c21241, 0xf4bff54d, 0x0df7be19, 0xdfa2f313, 0x2dcf767b,
+       0xab57da0a, 0x990ead92, 0xe68f84e4, 0x5eec8efd, 0xb00f7189, 0x8e51aaa3,
+       0xdb47f74c, 0xddb96ed1, 0x32709eea, 0x7f448411, 0x8dcbe489, 0x07b2656b,
+       0x2e3c79ad, 0xf2611ae1, 0x9efa5fa1, 0x2be345c1, 0xfd5e1829, 0xf73d1a23,
+       0xb93dd1cf, 0x2157c606, 0x8c3f87c6, 0xc2ceddd7, 0x0f5faa7e, 0x46bbce5d,
+       0xa1c5440a, 0xe3b12c3f, 0xddb87061, 0xefe32da7, 0xfd4252bf, 0x777eae5e,
+       0x5f4df47c, 0x3aba05df, 0x1b787e0e, 0xba7c8d5e, 0xcb3cf4e1, 0xa9e8e1cf,
+       0x031fc894, 0x615c9bbc, 0x44bad57e, 0xbddef72e, 0xcce280bb, 0xec0ff785,
+       0x2e6de5c1, 0x423cd7c5, 0x2af79e7e, 0xa8af503d, 0x03f9eef6, 0xe8efe445,
+       0xe822d3c7, 0xdec22ffc, 0x5a563b3d, 0x9ddf0327, 0x3f641d65, 0xd8dac779,
+       0x6f7e08d6, 0x7ea7624d, 0xd430f260, 0x86afea4b, 0x4f13b0f8, 0x329e276b,
+       0x7f0aea0e, 0xe5571dfc, 0xc3effca0, 0xe109f915, 0x1d6b62d9, 0xcf308aef,
+       0x4adc047b, 0x46667ef6, 0x3f937639, 0xb8f084c7, 0xb1acac69, 0x28947f63,
+       0x2b0144e4, 0xec9571c0, 0x246e2ebd, 0xec80e3e2, 0x3d5c01b0, 0xf76673fe,
+       0x11c3cbc0, 0xf5fb47fb, 0x0f31c984, 0x67e278e1, 0x3e05e636, 0x45c44578,
+       0xf51391e0, 0x44e5741a, 0x225f7dfd, 0x9bbc078f, 0x4eb82768, 0x2534292e,
+       0x1af37bc3, 0x6f3183ec, 0xbfea2191, 0xf3d0a89b, 0xad4ed14c, 0xebc95197,
+       0xd5ed99b5, 0x23dfe691, 0x6a5f53b9, 0xdefb35f0, 0x0fe8cd3b, 0xabe16fff,
+       0xc0d8fef0, 0x8d5f8c18, 0x746e4895, 0xfc4663a5, 0x63fc1e70, 0xfbcf13f4,
+       0x7cf2bc79, 0x02c38f09, 0x735db93c, 0x8d764493, 0xf87ae74a, 0xabe0273e,
+       0x28a8ffbe, 0x9db913fb, 0x8557c2a4, 0x6abc7eab, 0xd757907d, 0x1bfbcb86,
+       0x293f071b, 0x2fc23e61, 0x55d00dd9, 0x8cd5b1b5, 0x5c69e77c, 0x667f426f,
+       0x65fbc2ba, 0x29a0d746, 0x6ef37461, 0xdbde91a2, 0x267a3f9c, 0xb585c7d2,
+       0x77f38616, 0x871739ce, 0x8315f37a, 0xc8d1b5e3, 0xe4caaf7f, 0xc707778f,
+       0xafdad6bf, 0xef0c6b1f, 0x39c68737, 0x84d0b2b9, 0x654669ea, 0x8c352993,
+       0x4c4dde8e, 0xfdeae7a0, 0xf2854a8c, 0x1a3ef062, 0x16e7f787, 0xd5e49bca,
+       0xc344c707, 0xf13519f3, 0xc02afe9c, 0x8e72a6f0, 0xbea68f26, 0x5347cf47,
+       0xe535a24a, 0x3dad45d9, 0x96252e11, 0x044762c0, 0xa926f4fa, 0xf535f9f4,
+       0x37e81382, 0x5ffedd02, 0xab1617a7, 0x9355a17a, 0xa92ebecf, 0x8d485e8b,
+       0x2d1617a4, 0x0f115253, 0xd165be6a, 0x2252e34b, 0xb5c385e9, 0x1472df3c,
+       0xcf5e19e4, 0x70bd014e, 0x985e9875, 0xd13a2362, 0xba482bb7, 0xf1505e8c,
+       0x99cb1df4, 0x2217a8c3, 0x24f8f5f0, 0xd9b85ead, 0xe17a4e5f, 0x533229e6,
+       0x497df3c2, 0x56eefec2, 0x4ca6142f, 0x11c9b2a7, 0x106e811d, 0x3a17189e,
+       0xf8eef22a, 0x3f0fd41e, 0xbc13b24e, 0x3ba27af4, 0x39799e39, 0x04bffe39,
+       0x2f8e555f, 0xbd912a9a, 0x18ee95d7, 0xe9a2efd1, 0x16ade512, 0x7c72e1ed,
+       0xf1c81951, 0xae45d61c, 0x0eae50ba, 0xbcab9709, 0xeb9bb57d, 0xce634f01,
+       0xf9e14b2f, 0x0e4cebad, 0x35bfd42b, 0x85876724, 0x271fd9cb, 0x2b672375,
+       0xe0bd9cb8, 0x45f1e82f, 0x4263cb71, 0xcafc82be, 0x8ba04475, 0x9ad1a569,
+       0x06270375, 0x19ef29ff, 0x64578fe4, 0x27bc878a, 0xc1c1fdf4, 0xf6821a7f,
+       0x0f1c61ff, 0x49b7efe0, 0x9f80ef5c, 0xe058fd71, 0xdc39a2fb, 0x2edaae5e,
+       0x1baafc13, 0x6f57bf38, 0x3d0e2893, 0x3333ff3e, 0xf0f6ede5, 0x971a86b8,
+       0xf0bff156, 0x9955d695, 0xc4937cf8, 0xfc0acce3, 0xcd87cb0b, 0xbf242c73,
+       0xad06fe64, 0xe96250ff, 0x4aed8fd8, 0x3639277e, 0xec8bfc91, 0x7e89556f,
+       0x3ed36e16, 0x16ac72af, 0xe48057fe, 0xf6bd5576, 0x5fc15ef9, 0xde40e573,
+       0x7bcf9833, 0xd244764d, 0x4ebd6a67, 0x9bfc5478, 0x780168f0, 0xf0eaf90c,
+       0x44dfddb8, 0x0baf9379, 0x5ffcfd07, 0x3e46e554, 0xf6fc821b, 0x7249c19e,
+       0xcf32fbc3, 0xdf59ce3b, 0xfe3c3537, 0x8ba0bafc, 0x55ee0c57, 0x9aaf58e9,
+       0x6fe73fe7, 0xca1a8704, 0x306cf5a5, 0x37f36efa, 0xa76bf568, 0x48506f3e,
+       0xecd6975f, 0x43cb6e94, 0x5abcf3b8, 0xf8fd6f85, 0xb65e780c, 0xd437f414,
+       0x716f9d9f, 0xc5a8fc63, 0x517241d6, 0x05cfcfa5, 0xe053fcbf, 0xc74644e3,
+       0x8d3bd258, 0x2ef89d92, 0x087ae360, 0x728362f0, 0x8fbfc8f3, 0x5bb07817,
+       0xde392f88, 0xe427803c, 0x517ef1db, 0xddf6e7ae, 0xee39ff0c, 0x4c9bfbff,
+       0x91a2aed8, 0xa0236baf, 0x8c3be986, 0x84a61447, 0x1b4f73e1, 0x92adefa7,
+       0xe0f86e83, 0xe7c197df, 0xdaa8f065, 0x9f165f23, 0x4f3e5c2a, 0xc0827e12,
+       0x582d8b6b, 0xfc798052, 0x3363923d, 0x53c7f656, 0xbae4e15c, 0xd8df843e,
+       0x3d578e64, 0x80dfa3dd, 0xf2d4a6eb, 0xfa201c24, 0x7636c5f4, 0x6f6f7d42,
+       0xcb855f6e, 0xa3be351d, 0xbe6abf5e, 0x1482c3cc, 0x66f352af, 0x83f76523,
+       0x7257a889, 0xa44f5a25, 0x4660cfe6, 0x40dfd7c4, 0xbe9313ff, 0x66967fa0,
+       0xecedebe7, 0xe13b7dea, 0x6e5136e9, 0xb4761ace, 0xa17be014, 0xbae0764e,
+       0xca0c5bb4, 0x9e506b91, 0xe43131ac, 0x4d070b8f, 0xa3df2e4e, 0xbf949f49,
+       0xfa84c272, 0x82731cb0, 0x09ffc798, 0xc4271bd7, 0x3d02de78, 0x2898c4ec,
+       0x093a1fab, 0xd1c53fde, 0x9cf30e34, 0xacb48753, 0xe4ee38c4, 0x2391fb22,
+       0x32d5cf88, 0xaf1e7c43, 0xeb3f222b, 0xe2243bce, 0x6f0037af, 0x94ea7ed8,
+       0xe047239c, 0xc97565bd, 0x75295314, 0x0d3cdf26, 0x6507a5ca, 0x66f50287,
+       0x831b18df, 0xfd09d7f1, 0x830ee665, 0xae0b194f, 0x6957f8c4, 0x71531dcd,
+       0xe7a015dc, 0xe15d1f30, 0x8a97196f, 0xb5128de5, 0xe6dd78f7, 0xe09d2054,
+       0x21e67386, 0x5079fef0, 0xd9eec10f, 0xb679ebc8, 0x754c0e48, 0x27aff3cd,
+       0x8b6f3879, 0x598970c4, 0x2b58ec10, 0x8567d7ef, 0xa11b837e, 0x63e7943d,
+       0x4b77ec7b, 0x90d3cdfc, 0xd49c618f, 0xfdb2c47e, 0x41e72f28, 0x82cc783b,
+       0xfea0ee5b, 0xb128df6e, 0x62afe834, 0x47cfce44, 0x4d077f60, 0xb47e7c0e,
+       0x671457e9, 0x4bef099f, 0xcb67fe87, 0x9d68e3ad, 0x3b258fd7, 0xb92abbad,
+       0x5677f099, 0x9b4b19f0, 0x47baf64a, 0x6f3daa62, 0x3edb8f0c, 0xe89bdc96,
+       0x65d2de78, 0xad5e70ab, 0x031ce4de, 0x5a39d5d1, 0xe0127897, 0xf43b06ed,
+       0x83c79984, 0xcc27bd9b, 0xb37261ad, 0xf10fb939, 0x42c69ce5, 0x3aea2f92,
+       0x6e32f70a, 0xb4adb467, 0x36987ad1, 0xef1b3d93, 0xd0b4af37, 0x5c1df6fd,
+       0xb567b4bf, 0xdc7e83be, 0xcc4d1b07, 0xbe5c630b, 0x88c3cfb1, 0x9bb60fc7,
+       0xdfe4de88, 0xcd8e4898, 0x5be3c1df, 0xbf791bcd, 0x72e36c1f, 0x5337e8ad,
+       0x9ebca3c7, 0x42c9f20f, 0xafcad3f3, 0x1e02ca79, 0x89b75d47, 0x9557cbf4,
+       0x53e45d53, 0x5f1455cf, 0x7aef4eec, 0x77aa8c58, 0x5ebe31f2, 0x7335955e,
+       0x196fd203, 0x03068c4f, 0x087d3fbb, 0x2c6569f5, 0x46d53bc3, 0xa712c3fb,
+       0x96c7ca07, 0x8a7e77fa, 0x6a515ff4, 0xde1e2073, 0xbf23f847, 0x78a44dac,
+       0x395f3cea, 0xab3e79c1, 0xdfcf3821, 0x356fa5a0, 0x2ddd386e, 0x9eb86733,
+       0xce6688aa, 0x7f477ab0, 0xef0a7402, 0xf928d599, 0xdb96126c, 0x42192ff6,
+       0x6b8d3b65, 0x6bfbd0a9, 0x8f8e8963, 0x4adcf0fe, 0x7799d3a4, 0x6eed0c4b,
+       0x42af75e6, 0x41bd57bd, 0xd6bd7052, 0xfb79bbfc, 0xc71ed0f9, 0x9c57f47d,
+       0x15ae809e, 0x8deafba4, 0xfd53f7eb, 0xfd82922d, 0x4e54dd1f, 0x57854276,
+       0x4b7cf466, 0xa001f91b, 0xd30f2897, 0x905395ec, 0x5857abee, 0x57d798ec,
+       0xc7a547e9, 0x661f9136, 0xc9a0c756, 0xb2516ed0, 0xe50e9112, 0xdea75269,
+       0x78f17a44, 0xedb57d39, 0x25903930, 0x7c8f4f2e, 0x6f4a825d, 0x90dbd232,
+       0x6f35bd10, 0xfd23322c, 0xebe3e07d, 0x5e908a11, 0x571f1e91, 0x262c2ae3,
+       0xe9523edc, 0x07e80ab1, 0xe8e5f4e5, 0xd3fa3bb1, 0x02f81dd3, 0xcee47eb4,
+       0x771a3695, 0x37ddaad1, 0xc47ce52f, 0xab459c70, 0x8179487e, 0xff1e4679,
+       0xeb88e156, 0xd24f30da, 0x2e0f1c65, 0x997fa733, 0xf1c6e8f1, 0x10d8e48b,
+       0x96e803fd, 0x01bac59b, 0xe5039443, 0x5698c4d3, 0x31e304a3, 0x51187525,
+       0xe14f0f3f, 0xc23979fa, 0x3325eb0a, 0x67281f5a, 0xacee081a, 0xa3d7c297,
+       0x876476e6, 0xa67b63c7, 0xb06efea8, 0x189fde27, 0x5851e50d, 0xff404db6,
+       0x5745a26e, 0x60a061ee, 0xbc516313, 0x5eca2a9c, 0x4c9d0328, 0x479f54cc,
+       0xd12f72f3, 0xebcd1bde, 0xc79f500f, 0xead5f2f0, 0x7f5e18f3, 0x99e7a334,
+       0x7013b129, 0x14cf573d, 0x237c66bb, 0xfd0d4951, 0x62d957fa, 0x6eb489a8,
+       0x9a8a6fa7, 0xaf146787, 0xf4fff976, 0x5cb5e606, 0xf90098d6, 0xe9d34e07,
+       0x867b30d6, 0x13ca7589, 0xa4b23d04, 0xae0bb238, 0x2f01bfc7, 0x26818c13,
+       0x06b06f6c, 0xb0573f08, 0xfbf7f615, 0xf65222e3, 0xdd05e7e0, 0x56a86bfb,
+       0x6ff30fde, 0x4b632725, 0xc524ae81, 0xe590f94e, 0x46db994b, 0xed4b94eb,
+       0xcc49bf68, 0xaf9cf869, 0xfbe17657, 0xefa8f1d5, 0x802e32ef, 0x7c2131b4,
+       0x1fa91b5c, 0x07675c75, 0xb798bc5b, 0xfd618ef4, 0x74e0c26b, 0xf08ae916,
+       0xe22264b4, 0x098daced, 0xac728bbc, 0x8447fcfa, 0xeaf1b3d7, 0xd64e5173,
+       0x95d74f3d, 0xa4febc4d, 0x78272b94, 0x64b3bde1, 0x6814a4e7, 0xd0c73163,
+       0x28baeaba, 0xbee5debe, 0xed17b764, 0x5a73a023, 0x32cde497, 0x76317f93,
+       0x5f0ce488, 0xd043315f, 0xb114b1f5, 0xaeb2d94e, 0x0ded05a6, 0x4196c3f0,
+       0x0ba5cf7d, 0x4c4f8c66, 0x9199b7f4, 0x401baaee, 0xcb15e26e, 0x68dd5798,
+       0xf75a4676, 0x56452a76, 0xf59a17e3, 0xfab2fbc0, 0xb9424cad, 0xafcb873c,
+       0xc7e3bb45, 0x39517961, 0xbd6ff7b7, 0x0438e766, 0x69ab9941, 0xb1675e25,
+       0x8a687dd6, 0x74517ea3, 0x4edc25fa, 0xd449ab2e, 0x03ad6794, 0x75c20e6c,
+       0xfef5da99, 0xa7b9e44c, 0xe30fd0b3, 0xde04d38d, 0xa5ada7a7, 0xb774f7bc,
+       0x44e73d76, 0x026332ff, 0x2246bb8e, 0xb8e6093d, 0xf066ed82, 0x6c35c219,
+       0x7dc0385d, 0x67d0a35c, 0x97ce5c95, 0xb4a97f0a, 0xdd17af82, 0xc2666597,
+       0x7f71f2df, 0x84d8fd6a, 0xa3f71421, 0x7f1efef5, 0xcfeb098b, 0x137e0258,
+       0x4ec97bf7, 0xda0ea598, 0x86e60ceb, 0xe3c61b8d, 0xe755fa45, 0x3ee50d35,
+       0xf5edc3ae, 0x10ed09be, 0x5d668f98, 0x6d0a8ce9, 0x5b46acb9, 0xf733afd6,
+       0x3b3908a5, 0x7e400d80, 0x19229adb, 0xf944ff89, 0x5791d674, 0xefae0a03,
+       0x194b6d74, 0x0747eb4a, 0x295ca1a1, 0xf9dca9bb, 0xe6a81cdc, 0xc78c07fb,
+       0x25cf895b, 0x26e5dfe2, 0xe310bda7, 0x0fdc5529, 0x35cf819e, 0x7d7806eb,
+       0xcb5dcb2a, 0xfee14d7f, 0x6b9b72da, 0xc12dc531, 0xc13cc54f, 0x98d3a358,
+       0x307c4790, 0x7b3c922d, 0xabffd05b, 0x8c15b40c, 0x25121fab, 0xe4dfa5e0,
+       0xcf8c3e1e, 0xb963fbf5, 0xfd53e317, 0x0aef000a, 0x779e05ca, 0xaef2209d,
+       0xb33e8037, 0x5c9fb5c1, 0xc7f48d3f, 0x176e66d5, 0x2aac7c8b, 0x6b8f9c4f,
+       0x7a13b1f3, 0xe50cf81e, 0xd61b0dce, 0xdb99ff92, 0x1ebf99c7, 0x8d9f77c6,
+       0xddbeffbf, 0xcea98fdc, 0x35f24fdb, 0xf4f229d5, 0x36ce4269, 0xe7559c82,
+       0x454df80f, 0x64fe87b9, 0x37bd1e49, 0x87bd73bd, 0x14a4e493, 0x1cf86318,
+       0x78aa57e4, 0x0a599def, 0x41652bc1, 0xcef384bd, 0x6865de62, 0x6819ff37,
+       0xd7abef0a, 0x533ebdaf, 0x56ebf491, 0x541d2067, 0xf58ab5a5, 0xdfcf5faa,
+       0xe7fe82fc, 0xf7d41ca2, 0xebe7d30f, 0xec4ced04, 0xf144b847, 0xde2e3540,
+       0xad917e9d, 0x30dc8d06, 0xf234a3d9, 0xad7f4265, 0xd0e899bc, 0x471b99ca,
+       0x9f3cd1f4, 0x79a01ce4, 0x40b8b93e, 0x1aea9e53, 0xcb7fa9ad, 0xd94d22b4,
+       0xa6bd7692, 0x49b94dbe, 0x7fee8e53, 0xac7ea6ab, 0x73cd36e3, 0x4ecf4bcb,
+       0x662e0093, 0x0dd5b7ab, 0xde03a870, 0xd2109118, 0xace2031b, 0xaa287eb4,
+       0x6c7e46c0, 0x004b60dd, 0x832ea4e9, 0xbcb0d3ef, 0x002d24b4, 0x6c7b58fd,
+       0xf5c216b7, 0x0c6f92f7, 0x62ac73c6, 0x7755f61d, 0xf95e8d33, 0x2be70665,
+       0xaa657af5, 0x5c1a687b, 0x9929b6f3, 0xf068048c, 0x358fc42a, 0x6bbb718a,
+       0x7437df17, 0x91cfea35, 0x64967ea1, 0xc54a0e15, 0xaf3b7776, 0x91b3bf23,
+       0xbd42fbd9, 0x91bf62cd, 0xda999777, 0x1ab635e5, 0xfdfc619c, 0x0f2e5487,
+       0xb98d721e, 0x32f8898e, 0x0deac3ea, 0xf7e8cdc7, 0x689bfb57, 0xd720e1dd,
+       0x16f7da71, 0x9af42fba, 0xd70a23b1, 0x1f553d3d, 0xc2e23d79, 0x6bcd3354,
+       0x65e390bf, 0x7f61644b, 0x2aa4f8f3, 0x7676cb97, 0x1b8c6404, 0x93e36954,
+       0xf20d397a, 0xded76359, 0x7140223a, 0x11d3900d, 0x0f5545fd, 0x3cd6dc80,
+       0x3af6859f, 0x7943275f, 0x9ae39023, 0x4553d3e7, 0xcb006b3c, 0x6fc275c3,
+       0xe7110cb8, 0x1e0cdbf7, 0x5dc37ebf, 0x087f7044, 0xc21216e3, 0x0e2f0f53,
+       0x69c1cbc7, 0x15bf9a87, 0x7bd7d2f8, 0x6be3832a, 0x3a723747, 0xceedca90,
+       0x1f3052cd, 0x15c7a885, 0x033af445, 0x2014a5d7, 0x0ab6fe1e, 0x67b2a8fd,
+       0xf4fa8625, 0xd12f4daf, 0xae33263a, 0xa438c24f, 0x6954bf58, 0x7fa19652,
+       0x40e0f400, 0x31baa6fb, 0xaaafe340, 0xfbc2682f, 0xce3c8d55, 0xf1e069e2,
+       0x4ad66acb, 0x6ee6dd7e, 0x2a6f75c6, 0x5207efa7, 0xc7bf1a15, 0xbd44ef0d,
+       0xf9f160de, 0x2b7fc424, 0x76ca57c5, 0x941d6c4b, 0x4eb6af37, 0x3d2f648b,
+       0xe2fde02f, 0xf5c3336a, 0x1ed095e6, 0x6b3fb1e7, 0x3be319bf, 0xca253b65,
+       0x5bea7867, 0xd6be62a6, 0xd0c4d8b3, 0x77c7508e, 0x7e482b26, 0x84739be4,
+       0xc787391f, 0xcc5cde2d, 0xee790fed, 0x9d57147b, 0xc8fc255e, 0x0e281739,
+       0xf08566f4, 0xb8f2e723, 0xd43bf4c7, 0x8e968ebc, 0xd3d53a55, 0xf56e9e9f,
+       0xe955faf4, 0xa76a4773, 0xf508319d, 0x1c7be03a, 0x1fdef1fa, 0x4c27ca32,
+       0x426cd4bb, 0x2af7bf3f, 0x281ee3bb, 0x2b7d940f, 0x9ace5e31, 0x95c1f3f9,
+       0x5f2e249b, 0x3e715b94, 0x86667599, 0x020239fb, 0x53c4014f, 0x43a94e32,
+       0x357e468a, 0x1ca37b06, 0x0175c1ca, 0xc1a7c700, 0xf949dfcf, 0x065f2e25,
+       0x69b6973e, 0xd6bd184d, 0xcaa2b908, 0xe66601bd, 0x017189de, 0xc6067d63,
+       0xf8987717, 0xd16c963e, 0x1d3edf5f, 0xb5c127e3, 0x65ffbc4d, 0x7fcb5571,
+       0x94fe10c9, 0x75c11673, 0x5da3c8a2, 0x8a5034bf, 0x744ec8f3, 0x6f315307,
+       0x12a47d99, 0xef5d5af5, 0x1fd0f397, 0xabc3d751, 0x91e6f471, 0x13bc6c1f,
+       0x32bb6be6, 0xdb69f08a, 0xf48edeb3, 0x243beb6b, 0x57de5235, 0x2a2e7abd,
+       0x53fc0dcc, 0x5d37b17d, 0xbda4f2d5, 0x6dfd68a7, 0x78dcffb5, 0x698b8fe2,
+       0xf76d5f74, 0x81ee3127, 0xf32cff62, 0x065e9127, 0x911c6cb9, 0xc2a7aa1f,
+       0x68e75d41, 0xf085bbeb, 0x3c1de775, 0x7ad8c1bf, 0x654667ea, 0xfd0e548b,
+       0x9a7262dc, 0x47de0062, 0x709b4c7a, 0xd5d71732, 0xc1c1b8f3, 0xa5c52b5a,
+       0x53b5ad5e, 0x469b5839, 0x156bd7e5, 0xec915eba, 0x34e104fa, 0xbe9ac5f5,
+       0xace6b708, 0xa7985d87, 0x44d07b3c, 0xaecc60f0, 0xc17de7d9, 0xea3c532f,
+       0x5f5f0342, 0xe67f8ea2, 0x4ee60cc5, 0x8a6371e4, 0x0bfd2c57, 0xc54739c9,
+       0xf7e8f1b9, 0x5b6cae0c, 0xd2cf6585, 0xee9d694f, 0x282fa03b, 0xe3c8d1ef,
+       0x2d8d55a7, 0xf4b9ceb4, 0xb3f50262, 0x1e31d0c3, 0x82fbccf9, 0xde3beb44,
+       0x4e673c69, 0xd288fae5, 0x7c451b3a, 0x3c5a4879, 0x1fe3c1c1, 0xe5f8e06c,
+       0x8245d579, 0xfaae9a1e, 0xc3e21c47, 0xf5a154ba, 0x6407d522, 0x19acb38a,
+       0x8f6711d3, 0x6e317720, 0xde93eb8d, 0xf494eb12, 0xbd99a7cf, 0xc07d717d,
+       0xfde44334, 0x50b48ecf, 0x75d71f7e, 0xc7f53297, 0x3f83d7f7, 0xca88eb43,
+       0x8ca745fc, 0x6ef9ad78, 0x196acff2, 0xfdf0c1fd, 0x320fe806, 0x34bdfbcd,
+       0xae564b7e, 0x85d6ef26, 0x98335bfe, 0xaeaa7802, 0x20173003, 0xd7455f9d,
+       0x2af7ddf6, 0xa8d637c8, 0x2f51878e, 0xf2067eb0, 0x5abcaa27, 0xe84b273b,
+       0xee0cacad, 0x89a7173f, 0x2fc2b2fd, 0x4267ff02, 0xe27ff71a, 0x5f8d32f6,
+       0x7e4fbfa4, 0xc7ec5591, 0x7978001e, 0xafb8c23a, 0xc2e318cc, 0x1d6cd976,
+       0xfa0337d1, 0xcfd2ba46, 0x1f1a4673, 0xd3cfca97, 0x28f39f91, 0xacfc4ece,
+       0x464877ef, 0xcfb40ce1, 0x5fb37756, 0xefc12aeb, 0xc1181b55, 0x8121b3cb,
+       0x6d8674e0, 0x7a018d70, 0xd8e3033c, 0xd678f40c, 0x878e8ae5, 0xaedd67f6,
+       0x109884e8, 0x886f57ff, 0x73ab76a2, 0x872c4a6f, 0xf7a08d72, 0x2b22c6f6,
+       0x06e679c2, 0xfbea77ce, 0x4f4c09de, 0x6a1a3e44, 0xde6330ea, 0x2dbfa7ae,
+       0xa1bbed0e, 0x222727bb, 0x4e3775ff, 0x779f3a77, 0xb445d2d5, 0xb87f155e,
+       0xd0a1627e, 0x3a7b9e63, 0xd57ca11e, 0xdbf44652, 0xd5afebb4, 0xfeedbfc8,
+       0x9e6bca68, 0x7a4d13d9, 0x3cd3ecf0, 0xd4c679af, 0xaa60eb4a, 0xf476cb77,
+       0x7c2f3d07, 0x9ff230fc, 0xa1459767, 0xdeffbd78, 0xb6aeb873, 0xad1d7fd2,
+       0xfedca8c3, 0xd541f2dd, 0xfec8bbd2, 0xd71fcb51, 0x37285d5a, 0x2e5c8ddb,
+       0x867c6c2c, 0x9785d9ec, 0xfcc20c2e, 0xff3d99ef, 0x98e50c3d, 0x86178fe7,
+       0xe7ec3ed1, 0xe7c30c2f, 0x6ba2e79e, 0xef25d922, 0x8e38f066, 0x0e731faa,
+       0x9ef13519, 0x73fe8209, 0xc62bac56, 0xb6864d73, 0xaf84714c, 0xd7da1b1b,
+       0x8617fb40, 0x389b1e1e, 0x8addac37, 0x392fdf20, 0xf46c65a4, 0x747a309c,
+       0xb8d49866, 0xd38ad7d1, 0xa11fb130, 0x34132e33, 0xd5843ed0, 0x6f3f2341,
+       0xa1f242a0, 0x8a7600ff, 0x4bd91dbe, 0xe44f6f67, 0x5d1832e7, 0x1d220613,
+       0xf697dedc, 0x75af3387, 0x3d986e5f, 0xa0683d34, 0xfcd3ddf5, 0xefd90096,
+       0xefad2341, 0x99a4ed56, 0xcd883ee7, 0x5dc42291, 0x0e3ebffa, 0xfe3eb6e5,
+       0x6ec6b3d2, 0x2fef0898, 0x08ecc15d, 0x063c7d3f, 0xfb9db17e, 0xf8d75992,
+       0xd07c128c, 0x5c95ed8a, 0xa7c71d83, 0xb78899da, 0x3efc0886, 0xb3f39d2d,
+       0x822b47ca, 0x8ac7c206, 0x2e6b18e0, 0xe789275c, 0x7136a00d, 0xff0ae8df,
+       0x1f18ade4, 0x96e97158, 0x9ef081e8, 0x626e8715, 0xdbbf20f7, 0x62fb58c7,
+       0xb7df4bbb, 0xd10bcd4e, 0x4a7dfe89, 0x2127d73a, 0x7eb2207b, 0xfbfc178b,
+       0xd8b9e95d, 0x3d6cfff4, 0x52757e07, 0xabf250fa, 0x07b8f067, 0xfaf5abf7,
+       0x6abb9541, 0x7e04e3bf, 0x53ddcabb, 0xff80bf64, 0x5c77724b, 0x7af542ba,
+       0x922527fa, 0x4a687c5f, 0xb5d312a2, 0x87463eff, 0x6baf2121, 0xe69daaff,
+       0x59f73af1, 0xf2717fd1, 0x8a6796fc, 0x90a493e4, 0x4971e75d, 0xa9649f7c,
+       0xd4f587c9, 0xf0a70571, 0xa754e9b8, 0xaa86f289, 0x87daa7fd, 0x3c1dcf9d,
+       0x8bdaa8af, 0x74185daa, 0x94ec38f1, 0x15f9fc21, 0x106beec9, 0xf588ef5e,
+       0xf247432d, 0xf6b98cfb, 0xcb747fa1, 0x7e2312cd, 0x4aa2f617, 0x527b7a9f,
+       0x1ddf6f5d, 0xba0a371e, 0x5b2bf954, 0x9eaa17c7, 0xba7a11aa, 0x2274f51a,
+       0x34cfe9ea, 0x5fbeb776, 0xf4aed3d0, 0x08c76c64, 0x1b0e43be, 0xeefc915d,
+       0x375fa213, 0x3dae0fe2, 0xe2162f83, 0x7058b378, 0xdd8bfa19, 0xb0974fe9,
+       0x5e7bba63, 0x5f9fc693, 0x08d78f8e, 0x7c577ffc, 0x9c3feabc, 0xbeed3b8f,
+       0xba23ce6e, 0x7ef0a332, 0xb928dba4, 0x7c885826, 0xc51367f7, 0x4af5f5c9,
+       0xff063e85, 0xfbbf4355, 0xf406ccb2, 0xdc153c77, 0x578bafff, 0xe4bf235e,
+       0xd5d69925, 0x0eff042c, 0x1705b3ed, 0x44ad74ed, 0x33ae183b, 0xfe50b5b6,
+       0x76854660, 0x831875fc, 0xe477f6c5, 0x32fc7ad0, 0x44e29636, 0x3b78fe65,
+       0x4baf23ee, 0x86f5a7ae, 0xb2b2adde, 0xedfebc35, 0x8f2b7d6a, 0xf74d2d9b,
+       0x6b79e72d, 0xab2fbe8d, 0x5af3dbd1, 0xc45a3ffd, 0x03b3ba7d, 0x71b26f9e,
+       0x26407279, 0x78c6aefe, 0x998cd5d1, 0x4bd5f5d5, 0xdaa39c79, 0x23f68cbf,
+       0x1fe78957, 0x4714831a, 0x5417fca2, 0x9f5fe53d, 0x9cc87c82, 0xd54f7cda,
+       0x2724c396, 0x849f79f5, 0x3c8f2e06, 0xf3c8b295, 0x7d68930c, 0xa7d8a363,
+       0x223728aa, 0xcc5c61dc, 0x863ee0a7, 0xce3fe413, 0xf325fdd8, 0x17f84e3c,
+       0x7fb3cf31, 0xf972a65f, 0x63754f3c, 0x84fd098b, 0xde7be5cb, 0xc38cef49,
+       0x97b09c50, 0x7b5fc791, 0xc63b25f9, 0xf5897a97, 0x4757c37e, 0xc77ff5f1,
+       0xdf2224e6, 0x9f6978ab, 0xfed9e1c4, 0xd88527e6, 0xa331d86e, 0x3e11d71d,
+       0xbfe2e6ff, 0xad32f264, 0x6c7f18d3, 0x25fa3471, 0x4516c7ed, 0x879f3c23,
+       0xb9e3e22b, 0xe3118c37, 0x78a1e589, 0x7bd205f2, 0xb2788b77, 0x6c5ef411,
+       0x6fa32e28, 0xd72153f7, 0x8adf30ea, 0xe79bb974, 0xddd2ebfd, 0x57f953d7,
+       0x13ff69bd, 0xbcc279c3, 0xc63a019e, 0x9800cfb8, 0x9f95e62c, 0x302b628c,
+       0xec9753cf, 0xe6f8997e, 0xf9050657, 0x7e53da06, 0x2153bbc8, 0x55a1883d,
+       0x020cc3cc, 0x7da563dd, 0x8f944979, 0x2fe04ab9, 0xf452fc1d, 0x5334610f,
+       0x403c8f30, 0x450663e4, 0x7ff62331, 0xe6bdc99f, 0x34ffcc4a, 0x88cb1d19,
+       0x93891de8, 0x85e6bb62, 0x77cf2724, 0x3521f9ab, 0x7e5dddef, 0x0cf7c248,
+       0xf945f4e2, 0x3094e620, 0x81e6ae1f, 0x4a2ecdd8, 0x511f2d4e, 0x7967e743,
+       0x9d37d8b2, 0x8b4a29ff, 0xa5719f90, 0x6bef6131, 0xfa6b81f3, 0xfa744d3f,
+       0x6b80f355, 0x71e9bfd2, 0xd5efdc2b, 0xfc487b8d, 0xa3f214f9, 0x3a77f9fe,
+       0xffb560b7, 0xb3bde902, 0x0e71161d, 0x938f2b45, 0x2f144dfb, 0x58fe0b38,
+       0xdd3e9872, 0xddfbc69e, 0xfa222feb, 0x8d8e086f, 0xc487fac6, 0xa687d5fd,
+       0xde7b464c, 0xfa3a341b, 0x7fb848d2, 0x0e3410d5, 0x1be4fb45, 0x7a694bc4,
+       0xa359f984, 0xf3d23eb8, 0xbfe09c51, 0xe70e0cb8, 0x5fb937a2, 0xf3cc59e5,
+       0x1d75761f, 0x73cf0d70, 0x914acfef, 0x6a77f8d4, 0x6ec8fca4, 0xecbd2ebe,
+       0x2df68976, 0xc8fcd97f, 0x7fb6c68c, 0x8fa23f2b, 0x219ddf3b, 0x790322f2,
+       0xdd23b9dc, 0xa84bf34e, 0xfb885c19, 0x7ef9d49e, 0x901f7083, 0x43e6edf9,
+       0xedf9efaf, 0x352fdff6, 0x837cdd02, 0xcb7d97fd, 0x96fc2ffd, 0xf52fbffb,
+       0xdb7f85db, 0xcbffdcb7, 0x8fff72df, 0xff07d244, 0xf5ebe6af, 0xfe7d78f9,
+       0xb7979f5e, 0x8bd734bc, 0xd695eecf, 0x6ae00476, 0x4d35db8d, 0x8c687902,
+       0xbd4562df, 0xe7923259, 0xb58f56af, 0xa14936fa, 0xaf0abe3c, 0x3fdc5991,
+       0xf39de7b3, 0x6ce356e2, 0x226c7067, 0x3246bbc6, 0xdacf6ff2, 0x198b1e78,
+       0xd798e9ed, 0x37e99a82, 0x67521d81, 0x7d079c8b, 0xf7f0a7af, 0x4b1bd1ba,
+       0xc8af0ab2, 0xfed5a64c, 0x59f648ce, 0xdb2f88ad, 0x17c5191b, 0xbf495199,
+       0xa4abde89, 0xe3d3fda3, 0x2e3f7e45, 0x689b9cc0, 0x4dce4a5c, 0x928f6e74,
+       0x407be383, 0xae1367e4, 0xf18397ef, 0x03b004e4, 0x1eb78f31, 0xa7e479f3,
+       0xfa9ea9da, 0xdc99ddbe, 0xc4c07a4f, 0xef305ce8, 0x11dd7c95, 0xbd9156b3,
+       0x0ee1e6a6, 0xcb27029a, 0x8dc3ca25, 0x62bff1c1, 0xce6de408, 0x449c4411,
+       0x3f296dfb, 0xdfc8eaf8, 0x7bd377f5, 0x86fecd14, 0x6187f466, 0x29ee771c,
+       0xb19dfa20, 0x6fed2477, 0x091ae4f0, 0x46fc5dce, 0x43780711, 0x38d431c4,
+       0x7a8f9a80, 0xde3fc45b, 0x3f4ab8c1, 0xa1584f3c, 0xc34caceb, 0x5a9e77bf,
+       0x159cfe57, 0x203d3f49, 0xf78fb8f1, 0x29f71e15, 0x84fa3b30, 0xccac7faf,
+       0x0f2c78e4, 0x1a83bcf0, 0xcc4279c7, 0x7287e0a7, 0x687602c0, 0x6681aac1,
+       0xab05ebd4, 0x3af0a2b2, 0xa433e9c8, 0xcfa7bc00, 0xf15069d9, 0xee8e8917,
+       0x89f114ca, 0x8f941d03, 0x9797467b, 0xd7c99ddf, 0x7165e41b, 0x64ceeefc,
+       0xafb3be54, 0x8b9a3971, 0xcbb1ae3d, 0x6541f291, 0x38e2f7e0, 0xb8f8ebcb,
+       0x05977855, 0x4f7c2294, 0x558ebedb, 0xc8afcd78, 0x79b8a229, 0xb455b9e5,
+       0x85d2e9bf, 0x1c52d7fd, 0xffa0accc, 0x1b55b330, 0xc5909b4f, 0xa0cfe7e3,
+       0xbb708dc1, 0x6ffe48ce, 0xa24675c1, 0x1b32849f, 0x2609a7f9, 0x7960c726,
+       0xf283b712, 0xb08a938b, 0x93c4a6cc, 0x407f97fd, 0x179b9f89, 0x5c256f8a,
+       0xe11938b7, 0xa8bcb974, 0x22bb271a, 0xa44bf9d9, 0x179aafdf, 0x88783aad,
+       0xf3aa7bd6, 0xe6a2e152, 0x8bcbbb37, 0x3c12ebaa, 0xd6689fc5, 0x1d8c7851,
+       0x58ae31e3, 0xaccda7b0, 0xcb4b37ee, 0x0b4de509, 0x7ca39f76, 0xf51f9aa9,
+       0x3b239cd4, 0xb199da1a, 0x3fa0017d, 0x4364e41d, 0xee9bcf2d, 0x1a7bfb12,
+       0xae78fe61, 0xfe601ff6, 0xfcc3f578, 0xb50bfef1, 0xa81ae9fd, 0x6f75d075,
+       0x7aba08ed, 0xcf28e7fc, 0x36a642fa, 0x8f99d75f, 0x084d5d93, 0x1d7cb0af,
+       0x3af9f595, 0x63c78a39, 0xee303f70, 0xb41cf21f, 0xf42efc92, 0x7f42f797,
+       0xee2d6fe0, 0x6aee385e, 0xd18597cc, 0x61d3bb45, 0xdb6c73c3, 0xe61b0e5d,
+       0x4e9a0ac9, 0x6a847ed1, 0x15ce9063, 0xa6073ce8, 0x775f1ce1, 0x21b42feb,
+       0xd79b2f7c, 0x79fffc6a, 0xd7932fad, 0x32f905ba, 0xf23f2439, 0x26e7065d,
+       0xda701ebc, 0x87c986e6, 0x179e2ed5, 0x9bdb9d59, 0x5741eff8, 0x6139f8ef,
+       0xe628adfd, 0xeb848a71, 0xf7e16d72, 0x79e2c89f, 0xb98904ac, 0xe4b1c922,
+       0xbcb8df9e, 0xef648e4e, 0xf402bfb7, 0xc3d03578, 0x5abdf9ee, 0x71b4ae89,
+       0x73c5d5b6, 0xdbb9e17a, 0xac2c37de, 0x69c38f2f, 0x974c6ce2, 0xde2eeb4f,
+       0x40d8a336, 0x7bc2e2e7, 0xeb5f51b3, 0xd8cc62e3, 0xb9f5cd91, 0xe4739c53,
+       0x582364cd, 0x5bdabc97, 0x173877cc, 0x362f4fea, 0xf3509e90, 0x46c5f96b,
+       0x99f40b56, 0xa3e4d4bf, 0xb1b15abc, 0xff0b9e8d, 0x3f3d8570, 0x3bc9e513,
+       0x8c76cd07, 0x60e3e9a3, 0x752de28e, 0xa3bda1bd, 0x6d7da252, 0x373fd65d,
+       0xf8c38d36, 0xaeb660d9, 0x1bd42c6e, 0xe3b06b9c, 0xe5cbe57a, 0x3d85f2e1,
+       0x219f8fa3, 0xa1fda15d, 0x2f5fa38f, 0xb0bd7ef0, 0xbf43ee97, 0x8fd43932,
+       0x2f4f4eda, 0xbe94f68f, 0xbf7f2e30, 0x71456fe8, 0xc45ceafe, 0xa1818967,
+       0x3c5158de, 0xd61b9ac6, 0x234f595f, 0x7986af5f, 0xbcf0a4bd, 0xe9dfcf1e,
+       0x3caa79f3, 0x8cfa682b, 0x083efff6, 0x95f51972, 0xffc78d27, 0x3c285e0b,
+       0x34227280, 0x1f9fae4e, 0x37bf534c, 0x7c6788e0, 0xd14fb45e, 0xb8a247bb,
+       0x27c97e5b, 0xcca1a37b, 0x7fb4f15c, 0x773073de, 0xef939e39, 0xc50e3129,
+       0x971e3afd, 0xc22799d4, 0xd7e4d07c, 0xf5c7ae2a, 0x075305fc, 0xa67e20b7,
+       0x9d689a96, 0xa6d7e4de, 0xaae539d1, 0xba982b9e, 0x7c289ee9, 0xf3a25fde,
+       0x56bf261a, 0x4f9f063c, 0x88c01ed8, 0xb3889b38, 0x3c193907, 0x7c88d278,
+       0xfbb24572, 0x0537c827, 0xa89e4493, 0xa9e3eb94, 0xc62649fe, 0x7e8d46ed,
+       0x1bface6c, 0xf3d479c5, 0x7d711204, 0x2f485e42, 0x7d01ec15, 0x57d21b15,
+       0x7a9eaeff, 0xe09da7b4, 0x2be83579, 0x24c24f1c, 0x62ef4f9e, 0x77fc08bf,
+       0x93ba7fa7, 0xc467a8bb, 0x529983f9, 0xad7d575a, 0x38673c60, 0x9d12e5da,
+       0xfd1dd683, 0xcfec26bd, 0xb6ec6ef8, 0x76fd04d7, 0xf1a9aebb, 0xfd13c9bb,
+       0x787fe7b9, 0x57f8489e, 0xf548be6a, 0x7b09fac7, 0x215ebd57, 0x7b7fbbfc,
+       0xd12a013f, 0x1209fb88, 0x9827ef22, 0xbda12f59, 0xd827eea4, 0x3b856667,
+       0xab3d7093, 0x73e44fd8, 0xefb41d91, 0x7aad6fd7, 0x7bce893c, 0xa0cc6dc0,
+       0x9f485af7, 0x43fd8157, 0x63ff92f6, 0xe7ad3f1e, 0x1aabb1eb, 0xd496fbb5,
+       0x5f616ceb, 0x50f9858f, 0x77ac459e, 0x91ce2f1d, 0xef21c508, 0x21c78632,
+       0x59304a3d, 0xe3eb475d, 0x5c4d1779, 0x6438bbb2, 0x75a0eb35, 0x9215d5b3,
+       0xb7c3f503, 0x91ec971d, 0xddaf5da5, 0x83cb9327, 0x42496e69, 0x706ad5fb,
+       0xf8bad255, 0x6c7ef817, 0x66fa7c3d, 0x413c7971, 0x331e31e4, 0x6c787a73,
+       0x5bfb4494, 0xe21c1f70, 0xf817b1f9, 0xf2c7973e, 0x35173ef9, 0x5feea16f,
+       0xb79432b9, 0xea6ffda0, 0x1f7517be, 0x780fba8b, 0x00a886d2, 0x99f707da,
+       0x1db8d3ea, 0x3c3a25eb, 0xf3d193dc, 0x6f3f0b28, 0xf8ce3f5d, 0x28c3c2ac,
+       0xf37f0f87, 0xac88d176, 0x25a67108, 0xaffc2fc2, 0x98fb2eac, 0x30bffb54,
+       0xfec6a86b, 0xfedeb2a7, 0x16f2a6ff, 0x6f9f0141, 0x32abde70, 0xe6f8ddbf,
+       0xfc72df67, 0x7b247cfa, 0x4b88b976, 0xd9e7e9e9, 0x68bf552c, 0xbac34bbf,
+       0xfae43fec, 0x8e524ebb, 0x2f6bb9d2, 0x542573f1, 0xcb175a39, 0xe4215ffb,
+       0x547d7aa7, 0x914ceb5c, 0x884f5fe3, 0xe764b3e7, 0x0193a472, 0xc8f1b4db,
+       0x78daf581, 0x098dd5e4, 0x40e0f29a, 0xc17ea686, 0xe79ade81, 0x69578343,
+       0x237f0f9e, 0xd91e535f, 0x7f534a3a, 0xb46387f4, 0x68755ae7, 0x5ed791e3,
+       0x2fb749bc, 0x2bf047d2, 0x6f0dca04, 0xad9d6457, 0xa15997a9, 0x8d56579d,
+       0x96bd5e76, 0x2fcee826, 0x78e6fde1, 0x53ebf3b5, 0x025f9da7, 0xbef2d3e6,
+       0xd4cd3e7e, 0xecf7a153, 0x61b1f7f5, 0x738a07bb, 0xa99f686d, 0xc1db99fb,
+       0x6411786e, 0xffb69fdf, 0x9cd7d696, 0x06eda279, 0x79e6cf3a, 0x0379e199,
+       0x5963dbed, 0xa3e3de80, 0x34162873, 0x661ef4c8, 0x1c9b0c0c, 0x9d1afe76,
+       0xe9f28f4c, 0x911258a9, 0xf8b69e0b, 0x82fda04a, 0xe106275d, 0x7bf692fe,
+       0xfbcb3e78, 0x31f14484, 0x841d6de6, 0x60584bdf, 0xa89dfc8c, 0xbcb8b2d7,
+       0x9a3bbd3b, 0xdb49ebd6, 0xbf52669a, 0x3098b7f5, 0xdbd6a69f, 0xa849fc2f,
+       0x3d3df7c7, 0x5e77d12e, 0x71e17c70, 0x27bbf54d, 0xfae71fa7, 0x89a3416f,
+       0xb059efce, 0x9e3b676d, 0x0de0bd57, 0xe65b9d0b, 0xf48e76d9, 0x3b53d16a,
+       0x469ece08, 0xd5a8bd99, 0x8273da57, 0x5db8f1b7, 0xe9154375, 0xff932841,
+       0xf91f5d55, 0x9dcbecbc, 0xa9f0bb67, 0x00bcbb3d, 0xfccf85c2, 0x1ee30e2e,
+       0xc6b7051f, 0xedbedf91, 0xeee9cf8b, 0xfd702e72, 0x173c2fea, 0x03fc23f8,
+       0x2cc5cbe4, 0xdbcab9dd, 0xa9f7c512, 0xf7c2c302, 0xe8e087f9, 0xf1de78e5,
+       0x6e7823e9, 0x3fa7e9fd, 0x5bc7047e, 0x8f0baff9, 0xadf498fc, 0xc3728ecd,
+       0x3a61c4f3, 0x976d5bf7, 0x40e5cd90, 0xa3bfe3fb, 0xdfdbd2f3, 0xb7b038b4,
+       0x641f3df6, 0xefb77d23, 0xe3052cfc, 0x8cf78b5c, 0xe2f078a3, 0xf0be8b67,
+       0xb7486b7b, 0xe3e17ebe, 0x3e7375f2, 0xcd5f16b1, 0x38d9cd0d, 0x6f8033ce,
+       0x9e75f38c, 0xc55f5cf3, 0xc456cdcf, 0x23dbcef9, 0xe5df8b9f, 0xc986e73c,
+       0xed0f7e37, 0x2e7e069e, 0x75cf65cc, 0xbc78043e, 0x6fe04bfa, 0xbe716afb,
+       0x9dfc6449, 0x4f003fc1, 0xb9ed6c8e, 0xcc369fce, 0xf8d7f47d, 0xdbb121ac,
+       0x5f039d73, 0xb9ea6e02, 0x72ccfffb, 0x3e46ce8e, 0x74f7fa7c, 0xade2368e,
+       0x3a73c144, 0x7f46cd3e, 0x075343ee, 0xb1d72b9d, 0xefc762c7, 0x73d82d37,
+       0xfda7f894, 0x64b71e59, 0x76fbfce2, 0xe7e3f9d6, 0x8a988b95, 0x3f2c4b67,
+       0x1fc05a0f, 0xe2568bcf, 0x1738bee8, 0x7ab1d39a, 0xe777745e, 0xeeca2f44,
+       0xf89cf5cd, 0x96d5401e, 0x9fb99abf, 0x3497c21a, 0x7fe9f682, 0x2adbf9e1,
+       0xbfc2ec1c, 0x96dbc4eb, 0x7771e7c8, 0xf02f8f9e, 0x73c3f885, 0x35cf3a3c,
+       0x5435f287, 0x08b28e96, 0x137da0f2, 0xbdbd2f3f, 0xeea9fd1b, 0xd6caaa0f,
+       0x6798a9f1, 0xf2a1fc77, 0xffc6e5e9, 0x3333e155, 0x8bd0d15b, 0x97d3a70a,
+       0x75f1cb22, 0xb6bfef82, 0x62ece3fd, 0xf48fdcff, 0x66d0d558, 0x44d9fbe6,
+       0xf7cc547e, 0xf4dfd834, 0x6427a4fd, 0xd557e3b2, 0xd71c9337, 0x6eea8bcb,
+       0xb39b6df2, 0x7153bac5, 0xa7e9c14e, 0xefb87d63, 0xdddef4ea, 0xf6effd7c,
+       0xfa17b336, 0x19edbfdb, 0x721b8f33, 0xe13d41fe, 0xe9ff1b0b, 0x91069b27,
+       0xdd66eedc, 0x8f78bd77, 0x3df91fc7, 0x34e7ed9e, 0xade859ef, 0x72efff27,
+       0xe8c8fbef, 0xfbfb05bc, 0x3bf7c828, 0x4ffb847e, 0x17ffbc23, 0x176126d9,
+       0x22eb13ae, 0x3f03de41, 0x9ee02bbf, 0x3cf5cbd6, 0x9d1999c2, 0xe3be1083,
+       0x2725917e, 0xaf979f01, 0x7fa8ec95, 0x4c18af67, 0x9ccf9274, 0x89652744,
+       0xfa937bfc, 0xe6cf1cf7, 0x1ab6fc7a, 0xc3fa4313, 0x280cded3, 0xb624eb7f,
+       0x3197fb86, 0xe7425313, 0x6ead56d1, 0x0abc2389, 0xef3d533f, 0x3e66a2b6,
+       0x39fd07c9, 0xdeac9538, 0x2d6fe78c, 0x2dcfcb58, 0xa38b9fd4, 0xcf5dab97,
+       0x85fb5a89, 0x956df672, 0x81cc1cef, 0x07e7377c, 0xd7e456b1, 0x4a68f0ae,
+       0xb3ca05be, 0x07a4c80f, 0x2eb0b854, 0xebcbfddf, 0x7f3cf881, 0x973f2fa0,
+       0xb152515c, 0x3c1e9cde, 0xdd19282e, 0x597ef1c3, 0x19b87ba2, 0xb19beae5,
+       0xb596c7b8, 0x7c50345d, 0x36595980, 0x59d9938e, 0x537db876, 0x60a7b26e,
+       0x16cbc4de, 0x58fc51a5, 0xeb0addff, 0x1eff20da, 0x157bf683, 0x5f9c8965,
+       0xeff3763a, 0x1e46b1ef, 0xeb32b6bf, 0x9c778c32, 0xe0a5d652, 0x95ae5411,
+       0xc53dfe26, 0x4714f1ed, 0x91456db8, 0xba5fcf19, 0xf69e21ad, 0x93af30b5,
+       0xe2a8cfbe, 0xc1456db1, 0xf7e834fe, 0x871cfab6, 0x269fc5ac, 0xaea0bc1e,
+       0xc9dbc54d, 0x64ede0cb, 0xbe01bc24, 0x7a13f734, 0xeec5f169, 0xe94cf6e6,
+       0x62fafb1d, 0x0d7ceefe, 0x77631eff, 0x340e92f2, 0x35c5094a, 0xe33a338b,
+       0xef4829b5, 0x250ed617, 0x55f1e9bc, 0xc3d9affc, 0x7b337f71, 0x05ce962b,
+       0x66c3eb2e, 0x6ff184dd, 0xd953f389, 0xa316262f, 0x8bd01ade, 0xb56bfdf3,
+       0x82d9fe3c, 0x787ecff1, 0xca9dba6e, 0xf3fc4587, 0xe13fc628, 0x3fc626fa,
+       0x7c527ae1, 0x33e5433f, 0xd7a20020, 0x7f38bdc1, 0x8925ee0d, 0x34e2ddf8,
+       0xff8a4bb4, 0x73f38b25, 0x61637d7e, 0xce878d0c, 0xa3fef9cb, 0x7bd1bebf,
+       0x3a37630d, 0x69b4f1b5, 0xb4f1b453, 0x663915f2, 0x736fd7f4, 0xa3d4d68d,
+       0x0f5abc88, 0x925e98ba, 0x337e79a8, 0xbfcc34be, 0xf0a5ee2f, 0x1f7147f8,
+       0x4b5bbd4d, 0x2a5bdfb5, 0xb3c668bf, 0x62dbd985, 0x26b3309f, 0x87bfc219,
+       0xf1ca4402, 0x3e6de762, 0x416e3a31, 0x60e4fc7a, 0x5e7284b2, 0xaf150f8f,
+       0x080037b3, 0x1b39dfa0, 0xbd97940c, 0x55e3b66b, 0xaeeccf3c, 0x7bf7f8a7,
+       0x467bae4e, 0x39805df3, 0xbf84994f, 0xa1fb2763, 0xf232c568, 0x607dca3b,
+       0xcb88022f, 0xa23ef45f, 0x467e3196, 0x0f91594b, 0x80bec90e, 0xe2727844,
+       0x4fbd83f7, 0x7e47eff0, 0x0ed86208, 0x2b7677fa, 0x1287c71f, 0x53e5815b,
+       0xfdfbb7b6, 0x6675e600, 0x0679bae2, 0x307c8dc4, 0xd3e2e499, 0x2cfa4332,
+       0xe744c3bd, 0x587ede39, 0x31f4efa6, 0xc5533f29, 0xd9cbe62b, 0x1dfe1613,
+       0x04a00e9b, 0x71f8b7a8, 0x8f9f7d0b, 0xcfcb0328, 0x11adf40e, 0xf2f48874,
+       0xc6733c61, 0xfe7960d3, 0x6496a3e0, 0x82119f5a, 0xce106f9b, 0xfae09bd7,
+       0xa3a02f51, 0x06f9e68f, 0x3bbafc91, 0x0f47f899, 0x2e6693df, 0xef48bc9f,
+       0xea2e4852, 0x26d996ed, 0xc7df7d07, 0xa3a486cb, 0x96b93a5c, 0xf40f477f,
+       0x3f5f1c4a, 0xabd134f3, 0x46939efa, 0xef8e3c65, 0xe90e5d64, 0x0ad6dbaf,
+       0x06f4137f, 0xfae3efaf, 0x46ecbd6a, 0x275bc3bb, 0xaf9db9b9, 0x4db78fa5,
+       0x688b9ede, 0xd68db1fd, 0x6809dcaf, 0x9dca3cc5, 0x2ec9533b, 0x5bec2998,
+       0x2ddbc696, 0x3b3a73b6, 0x0f4fa07f, 0xea7ad7dc, 0xea01e010, 0x75f3a7b4,
+       0xacc6a705, 0x3747861b, 0x1dec369d, 0xffb803f6, 0xfbef44f1, 0xc8dbc046,
+       0x5ee6f76c, 0xac329f18, 0x4473c6cd, 0xfc4fface, 0xf50fbf1c, 0x83930ed1,
+       0x97e974d8, 0x0c4ed3b3, 0xeb835d8d, 0xf2eb67c2, 0x3f042704, 0x5bf8293c,
+       0x8b6fcfd5, 0xa7036cf2, 0x2482f63f, 0x34c46bbe, 0x9e217872, 0xe4872a43,
+       0x2b872aa5, 0xc7fadd85, 0x3e6edc5e, 0x60a5d6c5, 0x4fa005bd, 0x3b3cfef1,
+       0xb72a4bb7, 0x7ee7eff1, 0x4c9c7c84, 0xf5c31a7d, 0xe4167cf2, 0xea014e7a,
+       0x77dd0949, 0xc0388b45, 0x409fbe3a, 0xb9e7f72f, 0xe06ffb7d, 0xa3003bfd,
+       0x7cffe45d, 0x8f1b1ae6, 0x3c6deb71, 0xff97ac9e, 0xb9b7e84c, 0x3d7a7de2,
+       0xbbe85730, 0x377d3ab9, 0xce8e71cf, 0x0edca91d, 0xb2b945ef, 0xc2efab4e,
+       0x9a44a9e6, 0x872f3ce7, 0x873f3cf7, 0x769d7bcb, 0x08fda30d, 0x3d59dc2a,
+       0x77b4d3fc, 0x791c61c5, 0xc33283fe, 0x78aa1cef, 0x823e66a8, 0xb02cc7f7,
+       0x8f18ed0a, 0x062e31bc, 0xa1f0ba70, 0x2dc7ecbf, 0xa06b944a, 0x7efef3f3,
+       0x9427b3bf, 0xa4b2f37b, 0x6f7efdfc, 0xd570aecf, 0x829bf1c3, 0x6ef9131b,
+       0x9863076a, 0x377f85bb, 0xc91eac3a, 0x0901fffb, 0x00d0a8f5, 0x0000d0a8,
+       0x00088b1f, 0x00000000, 0x3bedff00, 0xe5557469, 0x73dcfbb5, 0xe1dc8487,
+       0xc2040464, 0xc06e49b9, 0x612f4865, 0x1213d41e, 0xde0d4b22, 0x00c10580,
+       0x86120137, 0x7c07504c, 0x0040e3e2, 0xaa1a4583, 0xf50af8a5, 0x22d28342,
+       0xb04a0834, 0xc141170c, 0xd6de8ba7, 0xa44f7d6a, 0x40932861, 0xd2bb6a52,
+       0xf7b79457, 0x3b939df7, 0xed83a404, 0x58b593af, 0x9ef37efb, 0x77f7bdbf,
+       0x52015000, 0xaaa8e601, 0xd08eceb5, 0x092bd00c, 0x72c06e60, 0xd80e35b6,
+       0x37fc0ddf, 0xbb746b7f, 0x01e5e696, 0xf7473754, 0xa41c5fe3, 0xbfe6cc01,
+       0xff5616a1, 0xd845cc41, 0x766f3d12, 0xe890eadc, 0x556679a4, 0x086e17eb,
+       0xa1e6ca0c, 0x840cfada, 0x9f12a24d, 0x6e0f351b, 0xca7a01b8, 0x7773948e,
+       0xde0bc361, 0xc5c2221b, 0x002300c9, 0x5c78174a, 0x439c1cfe, 0x2186f77f,
+       0xb09e7468, 0x39cd23c0, 0x098a6584, 0x68c79cf0, 0xb1c6994f, 0x477f788d,
+       0x617c67e2, 0xc1864ef6, 0x15483f08, 0x3a6f3c54, 0xeba236e1, 0x71eb15be,
+       0xdf8841e7, 0x11f8137a, 0xcbbf5b9e, 0xfe3e47e9, 0x695dc5fe, 0x88772b04,
+       0x66084410, 0xdcf015bf, 0x2f65f582, 0x56fb833f, 0xdaf78d6c, 0x88e2bbb0,
+       0x3c7008bf, 0x252b7c0f, 0xe3d7971c, 0xe070c341, 0x71dd8445, 0x8428f23d,
+       0xdfd982fd, 0x513de68f, 0xd927efe1, 0xd187faa3, 0xf4cc4fbe, 0xee3f7cff,
+       0x04b6c4fb, 0x9248caaf, 0x44e1a682, 0x84041489, 0x7b7f0bd5, 0x04fc8cd2,
+       0x9e8f83f1, 0xf2b8014a, 0xb6c408ba, 0x817f24ec, 0xcfdc4a9c, 0x703d05eb,
+       0x5d29b89e, 0x22f6c4ca, 0xeff9ecec, 0x8d4ce7e7, 0x4fc4e59f, 0xd599e914,
+       0xf3a50e1f, 0xbe70374f, 0x4d99face, 0xf397a7e3, 0xe7e73573, 0x339f8d4c,
+       0x7e35788f, 0x4f892bca, 0x9f8d6af2, 0xeace1c0d, 0x3a7537c2, 0x4fc4f5e1,
+       0xa7155e6c, 0xa60f885c, 0x173f909a, 0x4f508a76, 0x12a80b6d, 0x4485c3da,
+       0xdf511250, 0x3f8d04ff, 0x7e610a0e, 0xe50ecdce, 0xd29e9106, 0xc49d47b5,
+       0x453bb9d7, 0x3f2c704e, 0x73eee941, 0xc81f9e44, 0x24d53c25, 0x087942df,
+       0x408aa5c0, 0xb7fbe12e, 0x825a7df2, 0x79e3e522, 0xde2dfbed, 0x36efc8cd,
+       0x85c01587, 0x8384f676, 0x227265c1, 0x3a81679b, 0x505f3c00, 0xf8845814,
+       0xdd3e50db, 0xb2159e90, 0x5905c6cc, 0x87ec5282, 0x7e13200d, 0x24288282,
+       0x1d2fed75, 0x3e462283, 0x814c3bb5, 0x67ff48cd, 0x3c80d0d6, 0xffaf187b,
+       0xe913b192, 0x03c835f8, 0xd252bce8, 0xccafc235, 0xfc8cd815, 0x6c4c0879,
+       0x0cc087df, 0x982708a5, 0xd8713541, 0xba224f60, 0x3fa85990, 0xf1bf35e3,
+       0x7410e1ed, 0xef82af21, 0x3fae7081, 0x73a55d30, 0xc14d0726, 0x1e0fe87e,
+       0x090f0732, 0xb2714d08, 0x7c73c245, 0x913c84e3, 0x660cb0e4, 0xf15decf8,
+       0x21f846db, 0x1326a5bd, 0x8129ebc7, 0x0a28f1d1, 0xdd32f89d, 0x8444470c,
+       0x4439e28f, 0x5904b4f7, 0x0816f365, 0xa30ccdde, 0x54df8614, 0x2881bf0d,
+       0x4bc87387, 0x0df76ddc, 0x3547d3d4, 0x069f707c, 0xf1cf5b27, 0x1edf9588,
+       0xad004f8d, 0xcd6be256, 0x227fef63, 0x71359d20, 0x49f920f6, 0x6e5cb168,
+       0x39f9afed, 0x48afe1e4, 0xc05f384e, 0xf4f90083, 0x04db06a8, 0xb87b3bb4,
+       0x1e0d21ff, 0xa5ace8d7, 0xde0bca36, 0xdc5b0212, 0x03e73fb7, 0xd3ad8939,
+       0x3b0347f7, 0x1026e34d, 0xed6bfc80, 0xb2562dfe, 0xbf5a79bf, 0xb22187ee,
+       0x5dacde2d, 0x169f912a, 0x41ba6fc0, 0x8b3edad0, 0x13dc2958, 0x7afb25ef,
+       0xa1ecdad4, 0x5e76277b, 0x5874df2c, 0xef53805c, 0x3e75f9a0, 0x03c03465,
+       0x0bdbd3df, 0xcbda0a7c, 0xe39de1a4, 0x8e164a8d, 0x8e7f177f, 0x7828e864,
+       0x452fc133, 0xd7253ede, 0xfce39685, 0x8a728f0a, 0xdcd39ffc, 0xa0fecc0a,
+       0x58bbf191, 0x28061324, 0x28a37d1c, 0xb858f911, 0x6c9e605b, 0xe636e8ea,
+       0x50f13a77, 0xd478619f, 0x76f413ec, 0x71bbc148, 0x36ceeeea, 0xb070a3c3,
+       0xf27c6a2b, 0x9f1a8868, 0x1be91d78, 0x6a71b5a9, 0xd194f488, 0x4a8d9ff1,
+       0x235b6c6f, 0x42dae3e6, 0x4ba74f3a, 0x65ffef0e, 0x835f19e0, 0x9d75d199,
+       0xcc5075f9, 0xba6101be, 0x91df665c, 0x5dff223f, 0xe2a48229, 0xfc5f1aba,
+       0x6117f26a, 0x3d181a7a, 0x8f9d78a1, 0xf1a37cd1, 0x06bfa442, 0x8d55f1f4,
+       0x67cdf20a, 0xd2af9cea, 0x3f3ab1fc, 0x337f7d70, 0x7d6c4973, 0x4686a6d2,
+       0x9fa61ed5, 0xbe18b3b5, 0x7c21ee49, 0x295fd339, 0xc42f48ff, 0x4ef906b3,
+       0x5ca74557, 0x5f8c75d5, 0x6d1131a1, 0xa62337c2, 0xff022ddd, 0x52fc11de,
+       0x59f949d7, 0x7cd2f811, 0x8b4a67c4, 0x127fbd10, 0xb4ddcf1f, 0x1d1d51ae,
+       0x90fc036e, 0x5e8227f1, 0x9d299fc6, 0x9be75ef2, 0x6ac7eb85, 0xfee019fc,
+       0x45e88fa1, 0x7d3972fa, 0xd2fd2881, 0x65bcaef5, 0x14b48aed, 0x2004b38a,
+       0x68f2c37a, 0xe7fc91f2, 0x9bff3a4b, 0x586f8442, 0xa13dbc1e, 0xa9bf3f59,
+       0x64abf491, 0x6f2f4eb7, 0xf70bf587, 0xbff216fb, 0xea7c7a21, 0x53f5e8f2,
+       0x667f73a0, 0xf53a5357, 0xfa43cf17, 0xbcfc69e6, 0x4853537f, 0xbf76fae5,
+       0x67ac353b, 0xad12b365, 0xed85bf74, 0x6be31b71, 0x93b8de27, 0xbc0fe380,
+       0x07c7cd1f, 0xb27b79ea, 0xc1af9b7b, 0x4d7ed91e, 0x7764e3e7, 0x7d72bd94,
+       0xc4fd1df9, 0x4024f37b, 0x161fbd94, 0x4487dba3, 0x437baf9d, 0xa750e58f,
+       0x1f5efe7e, 0xfc0fb7dd, 0x719f1a30, 0xc7bdbd36, 0x6fe91857, 0x5f1937d4,
+       0xf9f4fc74, 0xd7a25f45, 0xddaaf3c3, 0x729afa6f, 0x320cdee8, 0xc49a56ff,
+       0x71c75c21, 0xb56a47bc, 0xbf68a938, 0xbcd00be8, 0xc2cf416e, 0x873d309c,
+       0xff99169e, 0x8085eb56, 0x196cfd07, 0x04ba56c8, 0xa5628267, 0xcb90f5fb,
+       0x9c15e8b5, 0x7169f87f, 0x3df70051, 0xc59928b9, 0xadb81f9b, 0x5d87ff8c,
+       0x6366d37d, 0x0cc250fb, 0x0ef38cab, 0xc1963b3d, 0x7fe93bb7, 0x337a47d7,
+       0xc9a5ce2b, 0x97e65df9, 0xf6f0250e, 0xbedbf72a, 0xd5af28a5, 0xe7ed996e,
+       0x5ad2924f, 0x39e13f50, 0x09916c0b, 0x098fef4f, 0x6de7b2bf, 0xfc239f03,
+       0x4695de96, 0x41ff2ef2, 0x9c4f5149, 0xe2c2be57, 0xab5e7015, 0x7c274a49,
+       0x658dcffd, 0xb96b30fa, 0x18fbd506, 0x4fd5f83c, 0xcf749dea, 0x1c58146e,
+       0xcd17f773, 0xbb62e7ef, 0x4bd321b2, 0x30e81ea8, 0x9ce78481, 0x202fdf5e,
+       0x899dcaa2, 0x3c777baf, 0xbf340f9f, 0x7c7cbaf2, 0x2f9a60fc, 0xfe70cb4a,
+       0x7017ec39, 0x712adcfc, 0x397840b3, 0x2404dd1d, 0xc097dce9, 0x2b73f0ae,
+       0xb865816c, 0x7fbb69cf, 0x673a7afa, 0xd29605bd, 0x93d7413a, 0x4e5f198f,
+       0x3f5cba4b, 0xa1cfcc6e, 0x2dbd3679, 0xca9f2195, 0x157a9d4c, 0x2aefbc04,
+       0xb5fb7912, 0xb6f91f4d, 0x2f73fae0, 0xaaf163f5, 0x276ca19c, 0xa19d3d7d,
+       0x3ffb20ec, 0x462ed5f8, 0x3c4bfb5f, 0x51d03b6e, 0x111e569e, 0x315c5427,
+       0x68387d33, 0x7c231f95, 0x23eb760f, 0x6a2f2ca8, 0xf8a12e4e, 0xe28cf511,
+       0x45ebd46d, 0x1f126ebb, 0x2645ba36, 0x4ddf43af, 0xea472d1d, 0xf9867ab7,
+       0xde64e289, 0x6d6eea3e, 0x9cafd154, 0x33822db5, 0xfaf5e159, 0xe8aef9fe,
+       0x39983938, 0x81d128e1, 0xca30c679, 0xeb7cf453, 0x0733f533, 0xf533f1c9,
+       0xe3630653, 0x43a74ad4, 0xde7fe725, 0x1c9330e1, 0x9c979a4e, 0x62b938a3,
+       0xb9f985a3, 0x8ba98d8a, 0x414e29db, 0x5740f17d, 0x2c32927a, 0xda5b9e8c,
+       0x2beedaa5, 0x07191dec, 0x5dad7fb4, 0xf36a6eb6, 0x6d6fd935, 0x5b129597,
+       0x2d1b4503, 0xcaabb23e, 0xa0330e21, 0xf1b31cbf, 0xefa42d9d, 0xf3e20b95,
+       0xe578886c, 0x53931b46, 0x4aa1c3ab, 0x3a77ee38, 0xaf0889cc, 0x6e8c4dba,
+       0x60cc8657, 0xb8e60881, 0x5397063c, 0xf10d711e, 0xc5f6c649, 0xa3ac2f45,
+       0x0412e4b4, 0x3d430d26, 0xfd70a6bd, 0x0c5bb6bc, 0x66047e50, 0xf98c5cc5,
+       0x7ee01cd3, 0x5dbdfaa2, 0x39fc7cd6, 0x41f2aea7, 0xf9f965c8, 0xfcfc98e9,
+       0x8e1e7474, 0xfe51a61b, 0x30aaffcd, 0xc43b24de, 0x5e6a3d7c, 0xd51e7e44,
+       0xf2d0c96f, 0xa3c83ceb, 0x9d5aee38, 0xdd829b25, 0x13da3b4a, 0x41b059d2,
+       0x2e56f860, 0xc4360312, 0xe79920b7, 0xa0976747, 0x5e8caddc, 0x2576c255,
+       0x37c4b1e5, 0xf8710210, 0x0b0dbef3, 0x1767e4cc, 0x4ca57e6b, 0xdbe91f00,
+       0xfa6f7899, 0x36c78a02, 0x56be33c6, 0xc7ee78fe, 0xd6bae12f, 0xa229c5a5,
+       0x5e87d61c, 0xfee03e9a, 0xde149710, 0x67d2fce7, 0x0bdf49d2, 0x4857ee5e,
+       0x22657871, 0x26e298ec, 0x974cf539, 0x9579e1ed, 0xe6ce9ecb, 0x8083e2f3,
+       0x2ad970f1, 0x6f01d191, 0x521e02d8, 0x4520fec8, 0xf2d66df2, 0x1cd6acf7,
+       0xd34a5bfe, 0xfc991ee2, 0x9c5faf37, 0xced171c6, 0xc676a7f8, 0x066ff8bd,
+       0xf993d5ed, 0x57d13f09, 0x4c66126a, 0x5bb4fb60, 0x328b8ec9, 0xb7701e78,
+       0xbdd2cb06, 0xea8f09d3, 0x32ef3635, 0x1c47df37, 0xb181e1aa, 0x5429b54d,
+       0xf3c223f1, 0x0b779b4d, 0xbc796dc9, 0xb924ef12, 0x0e7af282, 0xad98c7ab,
+       0xa72fb449, 0x76e64ab3, 0x989ffd8c, 0xc1dabfb1, 0x227560fd, 0x15cedbf2,
+       0xb7fb84c4, 0xbe4cafd1, 0xf0dccf5f, 0x85f3cefa, 0xb99df8f0, 0x49e4afc4,
+       0xdb1e108f, 0xc8af6645, 0x29c3358c, 0x0e2ed96e, 0xf1a64e7a, 0x57e445c3,
+       0xc81cefe7, 0x1db2b6e2, 0x617bb21f, 0x56e726be, 0xc7296f2d, 0x33844ef6,
+       0xf8bdb832, 0x666ba845, 0xe8bf9e6d, 0xabc7d6f2, 0x9c985957, 0x937fd1aa,
+       0xfa5ea8e3, 0xb56fb65b, 0x79469423, 0x961bf556, 0xcb6fe4a1, 0x97cbfc35,
+       0x09fd19f6, 0xc5b94fea, 0x543dd125, 0xa95b16a5, 0xb028d55d, 0x6a5d7876,
+       0xe7e3e93a, 0x4938f7cb, 0x07c4ce4f, 0xb4df743d, 0x52f7882f, 0xc0da887e,
+       0x97cf93ee, 0x873f367b, 0xc85259ed, 0xacf8e021, 0xc89332c7, 0x82949f2f,
+       0xd93f1a56, 0x5b5136ec, 0xd4d1a491, 0x62dfcc56, 0x55d1cfed, 0x43fa6b35,
+       0xe046a5fe, 0xed7aacf2, 0xcf0335b0, 0xffc9a95b, 0xb30ff6ca, 0xa756cfc9,
+       0x397db287, 0x14d9de4c, 0x04cfc2ff, 0xbcd6df76, 0xba60ebc6, 0xde486bbc,
+       0x34f35f68, 0xdeecd739, 0x7de924f3, 0xaf3bc90d, 0xdea0beab, 0xaffd611e,
+       0xbe022a6f, 0xc5e908fe, 0x53cc7899, 0x05b97b79, 0xbcacc7db, 0xbfe6acfd,
+       0xf790bfb0, 0x4f3c39ab, 0xac6b79e3, 0xbe4adfbe, 0x263f244d, 0xa7f31b0f,
+       0xadbd1a4d, 0x9270deab, 0x3f6caefc, 0xc1c8eefc, 0x57e61784, 0x5ef44df2,
+       0xd12d47e3, 0xb3f864ef, 0xe896a1b8, 0xefe98675, 0xdecd73d4, 0xa7d3816a,
+       0xd66b5bd3, 0xb5c7d7e8, 0x3a345bf5, 0xd7e340ab, 0xbedc7eee, 0x7b227b34,
+       0xa749fca5, 0xd7c49fcf, 0xbef9faeb, 0x4d6edf46, 0x766a414f, 0xbe487f12,
+       0x7f5067e4, 0xcd50eb14, 0x2b94e06f, 0xfcb1373b, 0x8e979751, 0xfbe1a7ff,
+       0x0a4c4942, 0x04d5b1cb, 0x5ded9a73, 0x1a23c5ef, 0xe8ad4f1f, 0xfc82de9e,
+       0x06f31cfb, 0xbea36e96, 0xd3ce239a, 0xaf3f46f5, 0xfdc95b60, 0x86600eac,
+       0x9fafed20, 0x304d527b, 0x81273ed3, 0xbf8e87db, 0xf505976e, 0xe81feed3,
+       0x1c5779a4, 0x37443999, 0x0cd3ff3f, 0x5457ad89, 0x4af3f307, 0x7010108b,
+       0xebc094e8, 0xec56a782, 0x84e79671, 0x327ffdf5, 0x62ff4e84, 0xa78aeb4e,
+       0xfa117fae, 0x782cf0cc, 0xd4fdf276, 0x7a16f4fe, 0xd74df3a9, 0xca9c584f,
+       0x3d5893e2, 0xca7dedad, 0xf6c5e74a, 0x19caf1eb, 0xfec97bca, 0x10faf2f7,
+       0x5923872c, 0xeeb0f711, 0x0ecff1d7, 0x84f7c343, 0x65e72f7e, 0x2efa3066,
+       0x1f35b341, 0x85d578fd, 0xa6539150, 0xf5644fb8, 0x08bfbba0, 0xb3d42e8a,
+       0xbceeddaa, 0xeaad7bc8, 0xa7a611f2, 0x756210d5, 0x1f55b2cb, 0x7d230f16,
+       0x45c629fc, 0x8c5757e4, 0x3d5c52b5, 0xa1cccb77, 0x0dd3e724, 0xb8badefc,
+       0x142bc87c, 0x786e9f17, 0x0e666d21, 0x1a282bad, 0x6b65fd89, 0x9e393207,
+       0x53150f89, 0x1171fdbb, 0x6a358ea8, 0x53c590cb, 0xd1ca3db1, 0x39e89137,
+       0x8e1624d9, 0x2cfb908c, 0xa54f1690, 0x92eccc78, 0x6a4e0ec8, 0xc2deabfe,
+       0x933bd2e5, 0x277279eb, 0xa0bafee4, 0x44db3ebe, 0x7e84db7c, 0xc5aee913,
+       0xd507a018, 0xff1e054d, 0x5c42b1cc, 0x1fd63ccf, 0x4dfb13d7, 0x09aa2709,
+       0x13c7b6ff, 0x4ddbaa24, 0x883781b3, 0xfb0769ed, 0xa6e851e4, 0xc6287168,
+       0x9d5cecab, 0xbdf9fa4f, 0xc51eb932, 0xf5e20bee, 0xc76fa4a1, 0x19d63ab4,
+       0xcb8bef0d, 0xee893a7f, 0x3d5b8ba5, 0xf9f74449, 0x140df1fd, 0x70b79cc7,
+       0x7fefa57f, 0xd88f77bb, 0x77d88ef7, 0x0c65800d, 0x189901af, 0x6740253f,
+       0xe3eba4fc, 0x70baeaed, 0xcdd78d22, 0xfaf53db5, 0x5ecd1ffa, 0xd64de257,
+       0x12f2f0e9, 0xce365864, 0x9e083aa3, 0xe5f0985f, 0xd9c510ae, 0x86c9368d,
+       0xbd259ef4, 0x86fab6c6, 0x1481eac8, 0x9f9e9313, 0x8050637d, 0x138ab7f2,
+       0x2cd15dbc, 0x7884a804, 0x22b3ed64, 0x718d9fcd, 0x2221775e, 0xed717d6e,
+       0x6bff5224, 0x9ecaff5e, 0x56daff38, 0xe037bd81, 0x5e263db0, 0xfca7b77d,
+       0xf5578bef, 0xe754bffc, 0xa42ef6bb, 0x57cf5bf3, 0x0c5ea20e, 0xedf30bcf,
+       0x2c3992ea, 0xc4bcbd5e, 0x709b60cf, 0x5628cd6a, 0xbab176e7, 0x5e5a2fef,
+       0xdc917b10, 0x4ebc0f77, 0xbb48e779, 0xbdbb224b, 0x401164ba, 0x63abad36,
+       0x5ebb9750, 0xf77bb9df, 0x6aeeb621, 0xa37da0cb, 0xbb01dd70, 0xcee7f98b,
+       0xf79892f7, 0xbc58ef91, 0x7dd913dd, 0x7451dfc1, 0xd772ebf9, 0xded4abe9,
+       0x2ffc7445, 0xdee5c53d, 0xd33aded9, 0xfa1ef449, 0x11bef251, 0x9704ef24,
+       0xb9da7144, 0x5c5fdcf5, 0xf2bd7388, 0xc2fbca20, 0x80698986, 0xa1f6727e,
+       0x7f512787, 0xa2417ec5, 0xbfbbdcf8, 0xd3f949c4, 0x4eadcdef, 0xbf7ef3ca,
+       0x0abf7f5e, 0x469fe488, 0x3489838e, 0x0cd0647f, 0xe233ee32, 0x2337ae41,
+       0x0a039b2e, 0xcfd83bc5, 0xbbd716ea, 0xfe05bab1, 0xfde09725, 0xaf2f7b39,
+       0xd072e873, 0x1a51adf3, 0x9333079d, 0xfeb4ff38, 0xffbce182, 0xe35d86fc,
+       0x4d8bbf69, 0xbef08916, 0xfb6164da, 0xc93cc3cf, 0x5b33ef44, 0xed421e79,
+       0x37d93778, 0x35e637cf, 0x7aa37cf3, 0xbab14581, 0x4167eaba, 0xe7ca3cc4,
+       0x73a64fb0, 0xa7fa6ae7, 0x853cedeb, 0xef0f37d3, 0x5637a235, 0x99a1138f,
+       0x4edddbbd, 0x3d56ff9f, 0x37e31dde, 0xa982584e, 0xef9f8993, 0x77565e89,
+       0xe87e85b9, 0x403f257c, 0xc3ebac7a, 0x0517d43c, 0x079a9287, 0xea3e93e6,
+       0x9bfba1fa, 0xa5e35bf9, 0x2dfe51b3, 0xdb5daa31, 0x1b3a53d2, 0x7a69e719,
+       0x99823908, 0xe9d2abe8, 0x535d6b8b, 0xf8a6b082, 0xc421150f, 0xafe88473,
+       0x9152a4f0, 0xc05e8bef, 0xc69ed964, 0x642091de, 0x061ef601, 0x6a17ff4c,
+       0xa2b1b075, 0xe519bfbd, 0xf3742a58, 0x96d93e52, 0x2e4d50ef, 0xf9327796,
+       0x04253e96, 0xc44ffb00, 0x9ea9733b, 0x0e420330, 0xbb3fb637, 0x464d7643,
+       0xf5ebd5f9, 0x2d63b56a, 0xe65767d5, 0xfffb5a8b, 0x3aa8944a, 0x8afdffc8,
+       0x530f20ea, 0xffb5943d, 0xf6f5425a, 0x71b477b6, 0xe3425eb8, 0xab402b6d,
+       0xdbc57d8b, 0x85c7d03f, 0xdb5fb409, 0xe45c7d2a, 0xfdf5e7ed, 0x98daf6b5,
+       0xe331a5f1, 0x1ff6f12f, 0x504e227e, 0x88f5c273, 0x9ef7b527, 0x7d5a65d2,
+       0x8336f4c2, 0x93df2cf6, 0x1d17cf54, 0xe7941d67, 0x27947914, 0x7bf0dde9,
+       0xcd7ffd7d, 0x44af3844, 0x9f78ad50, 0xd9026fc1, 0xda75e7c4, 0xe1ffdd7c,
+       0xc9bac83c, 0x6f3439bc, 0xcb3cd448, 0xda7de6cd, 0x376ebf75, 0x89e2979b,
+       0xe77f4fde, 0x9c56e29d, 0x278f5f34, 0x94afef62, 0x8c471e2c, 0x699254ca,
+       0xb40b239e, 0xe9bc42b8, 0x16615a3b, 0xbb4a038f, 0x99b677f1, 0x32711d43,
+       0x37e431e2, 0xf9077afe, 0xbe3c0db3, 0x98efb57a, 0xf41fb43e, 0xc757be8e,
+       0xcc43ef21, 0x3cb3b5af, 0x86fb8ff2, 0xd1bfc8b8, 0xebaf24db, 0xea9f7da5,
+       0x759dc5ee, 0x67dfbea6, 0xacb74def, 0x409df543, 0x5f71a875, 0x66f3bd71,
+       0xc93efcf5, 0x01b0da75, 0xb48fc8dd, 0x25effba4, 0xbb0da63c, 0xf9da88bb,
+       0xaef662b6, 0xefafa3dd, 0x6b3fea1e, 0xa1089e52, 0x6346fb3e, 0x7f611b20,
+       0xa2130a13, 0x983f0fda, 0x3d844a0c, 0x57b87a4e, 0xd291fb54, 0x53f9a8cc,
+       0x3515dd67, 0x0d0b6c5e, 0xf69c7966, 0x78ab7cce, 0xc61df3a2, 0x9f3debc1,
+       0xc7d3fbed, 0x6a1fa28f, 0x5d59126b, 0x2dfeee77, 0x70828f1f, 0xec46805c,
+       0x74bdfb22, 0x93ca044c, 0x5757eb63, 0xb46eb420, 0x80f135f0, 0xe5c58474,
+       0x8d1fa8ff, 0xc6a34bc8, 0xfb4567a7, 0x1f756bd3, 0x23180ba5, 0xac7568d5,
+       0x594f7b2b, 0xbbff5e65, 0xeafd0371, 0xde90b47d, 0xfe903b3b, 0x2d7fa841,
+       0x38adaca7, 0xe64b23de, 0x05ef4779, 0xe5007966, 0x4acc0b11, 0xa1171e84,
+       0xbea8b81d, 0xde3f71d2, 0x83474878, 0x74d7d6c2, 0xb8bb5898, 0x5465b4d7,
+       0xc336aa6f, 0xc754dd80, 0x6e2c1d90, 0x7df9fe2a, 0x67e580e3, 0x63f74282,
+       0xe7c2a355, 0x4c1ebf8b, 0x1db1b0f5, 0xc53ed8e3, 0x50131c22, 0xe0281f37,
+       0x31d5d17e, 0x76d7f581, 0x6e0f9b00, 0x54ace2ff, 0x7144aefe, 0x29aefe6f,
+       0x72888985, 0x86795bb2, 0x2297ebf4, 0xfbbb222c, 0x86f7bde5, 0x5f7a1494,
+       0x32283418, 0xc59358ff, 0x6a400ddf, 0x5df74ebf, 0x990481ed, 0xc5eac8e4,
+       0xb7ed0f14, 0xec7c77b1, 0xda90f567, 0x94cdb603, 0xdb3ad5e7, 0x0afec9b3,
+       0x8907c60e, 0xe307438e, 0xcdbf2ccd, 0x73a1aff4, 0x2bf60e0b, 0xd9537ca4,
+       0xf3033367, 0x98f7ca63, 0xca589e3d, 0xd25d3ae4, 0xea37fb04, 0xbfbf6c63,
+       0x4cabf381, 0x872ebbe3, 0x7eef8d72, 0x1a659f8d, 0xdf1067df, 0xc5f2ee91,
+       0x587b6fc8, 0x29a2c52e, 0xb260fd7b, 0xca5e3e8f, 0x15bf743f, 0x8eaaf7cb,
+       0xeaf7c638, 0x7c9a1e8e, 0xa1c945bb, 0xb58323bc, 0xdb7dba07, 0x7ae2ce89,
+       0x5fee2f94, 0x287a0f6e, 0x17519a3f, 0x87f7a5ef, 0x45dd8b6b, 0xab85d7c4,
+       0xfee6e1b0, 0x8ab5ee8b, 0x74add4df, 0x4a65c844, 0xb8c82e47, 0x2c8ec4df,
+       0xebed5f06, 0x2e724bdf, 0xcecf18eb, 0x66c8ef29, 0xa95c62e7, 0x23fef8b0,
+       0xfbffbe3d, 0x20b9c7be, 0x21811b30, 0x75dfca8a, 0x26ef3602, 0xcbfdfc21,
+       0x54238c4c, 0x1696673c, 0x5b650e7f, 0x6c9b7f22, 0xf8424381, 0x72ff18fb,
+       0x9da86a91, 0x3be5d7f6, 0x678c7c99, 0x26e5dd70, 0xd543930b, 0x950f5fa1,
+       0x9092fc70, 0x4eec9ddf, 0xc47ff24d, 0x810995ee, 0xcf6c161d, 0x73977e7f,
+       0x8fd61c84, 0x43d07366, 0xf919a67e, 0xe6b5f548, 0x00b8e2d5, 0x942667af,
+       0x9eb5b80c, 0x83b8ebcc, 0xb79febf1, 0x286b4dd3, 0x66cb869f, 0xed879796,
+       0xb78ef375, 0xb8127f48, 0x6ecadcfe, 0x58912cf7, 0xbf6b167c, 0x959eddba,
+       0xf9227ffd, 0xcfadbbde, 0xfee11fe0, 0x584a5363, 0x99ef1cbd, 0x87583ca8,
+       0x7f31eec9, 0xb3b7f9a1, 0xcac7bb6f, 0xcf6b12f8, 0x6db37d7a, 0xb2019dff,
+       0xf68093f7, 0x2fb47a4f, 0xd9a2de41, 0xdd07f33b, 0xb3af815c, 0x339951f7,
+       0xddef14ed, 0x9e1ddec4, 0xdece6fd4, 0xf23939bf, 0xf85201bc, 0x1c846afb,
+       0xa43d50d7, 0xc9852db8, 0x2e9b9751, 0xba7e5d47, 0xfd963ebc, 0x637d1177,
+       0xd775fdb6, 0xd55762ff, 0x53073deb, 0x793b767c, 0xfee1e3dc, 0x8f285ff6,
+       0xf7373c7b, 0xfe7af7bf, 0x7e8bff09, 0xe26ec072, 0x5bc3a64f, 0xa3f9872f,
+       0xb741e3cb, 0x2433d8bf, 0x68241fcc, 0x6f4fd530, 0x9ee98fc7, 0x99fefc6f,
+       0x67fa0b7e, 0xfff433fc, 0x1292f9c3, 0x78b12f9d, 0x49e50466, 0x5527963e,
+       0xfc83bd53, 0x4fe818df, 0x15bd59f1, 0x9aa43e58, 0xee4979ba, 0x42d97625,
+       0xc5259771, 0x3afd216b, 0xbea211ea, 0x48f56bef, 0x2496087d, 0xbd0ddfe8,
+       0x128cf2cd, 0x43cb4997, 0x30f6f30e, 0x09bdfc7d, 0x0c94d794, 0x18e1c6d2,
+       0x6c089f1f, 0x472df9fc, 0xcdb25e59, 0xfc20aca3, 0x4c48f05e, 0x74b7173e,
+       0xfde7e3ef, 0x5747c40d, 0x04bbffb2, 0x5676ad6b, 0xda136b4f, 0xc3b91773,
+       0xdfb57ff3, 0x8817f271, 0xaca3c877, 0x502f79a1, 0x12352231, 0x16ad79f2,
+       0x84e6f748, 0x5601cbfb, 0xae58bdd0, 0x6044fd1e, 0x1c3c1df1, 0x1fbe9437,
+       0x959f7604, 0x35b1dfeb, 0x06c77f44, 0xb3e3175e, 0xfea11dfe, 0xb09de09d,
+       0xd7bed25c, 0xf92370db, 0x866ce4eb, 0xafdf1173, 0x2e9059b5, 0x22efd757,
+       0xff477d85, 0xabd6fb42, 0xf2cf1ad0, 0xd7efe8d9, 0x4f3013aa, 0x7b287e45,
+       0xca3b411c, 0x04f6e171, 0xab986756, 0xa47b8fd7, 0x31f44bb0, 0x3d03d389,
+       0xfd7dd8d2, 0xe74ba6b8, 0x2cff4097, 0x6fcdc533, 0x1e23355f, 0xeff1f66f,
+       0x99543925, 0x285f483e, 0xdea45d53, 0x95d0f749, 0x4a97a21d, 0x9d5a5530,
+       0xb5529a1e, 0xbc188afa, 0xb98fc717, 0xf54cdcef, 0xfe1ec3bd, 0x0dd9714e,
+       0x5d519dec, 0x10b6936a, 0xa70fd72e, 0x71ed8d3f, 0xe979f719, 0xcef2eefd,
+       0xa366b367, 0xc05ad01c, 0x00fae2c9, 0x36c1675b, 0xd2b91f7d, 0x96ba42fd,
+       0x4220fbbf, 0xbb9f3a1e, 0xa28f1ff0, 0x0e29bdfa, 0x09dede98, 0xc78a241b,
+       0xa58c3975, 0x838a53c7, 0xc8efe0de, 0x6ce8050b, 0x3e725c53, 0x5dfbe78e,
+       0xb0ef8beb, 0x52cd017c, 0x6cdbaa8d, 0xfcf37998, 0xa5602522, 0xbae9bfad,
+       0xf68f25e3, 0x06103e4e, 0x791deff2, 0x9b52a35d, 0x952c5633, 0x6a4f44cd,
+       0xbfe4979c, 0x77666370, 0x7c3043f2, 0x83ce441d, 0x2f4cc90d, 0x1845ba56,
+       0xb7367a8e, 0xfba4c905, 0x160ee5a8, 0x92d83df7, 0xe313a0c4, 0xf8bfea4e,
+       0x7983fbca, 0xa7cb871d, 0x63eed5f8, 0x6afb1c58, 0xf563063f, 0x4fb9fcd6,
+       0xd84b77a1, 0x123ab023, 0x75ca12f9, 0xc7563d75, 0x6eac8378, 0xeec096f7,
+       0xbf9b293d, 0x75495463, 0xd20e1dec, 0xc22f2c7d, 0x2ec94b25, 0x6cddf45d,
+       0x8faeff12, 0xf7dacce5, 0x3e4d4eb1, 0x7df9d009, 0x881bef6c, 0xccb67277,
+       0x3d208bbf, 0x264949c1, 0x5cfc9bb7, 0x393fb66a, 0xe6bde29b, 0x9f54459d,
+       0x4aea0b9a, 0x13d94770, 0x6ae848dc, 0x77b497a7, 0x2b0f5d31, 0x852173b5,
+       0xc6855feb, 0x3e8d4ad6, 0x2b5418cb, 0x4772cfa4, 0x377ae6f6, 0x80fe8691,
+       0x1f0adf7d, 0x40fe3dfc, 0x3f7407bf, 0x2cf535fd, 0xc7d2cfc6, 0x7ce3ddb9,
+       0x0ffd175e, 0x511f5021, 0x6faceac7, 0x77b0233d, 0x326ebd6d, 0xbd0a0ccd,
+       0x095422ef, 0xd2f7d296, 0x8598e104, 0x62e38b9d, 0x8cc3ab12, 0x63ebfc62,
+       0xd39d5952, 0x9830ebce, 0xfd43dc27, 0xbf66ead7, 0x7920f8cb, 0xc51bf7d9,
+       0x6c4f5e36, 0xdf644f7f, 0xee8add1f, 0x555e5af1, 0x6f62e07b, 0x5f71dbb2,
+       0xf7e27e89, 0x11e38b71, 0x67c753ca, 0xf197f7f3, 0x9828a6d9, 0xe98bfb2e,
+       0xea3b3fdc, 0x5f909ba6, 0xc167be7f, 0x8771df2b, 0xae887ae9, 0x40a7ba2c,
+       0x4d3e90b6, 0x371de504, 0xf06df56e, 0x5064f6b3, 0xf7496c19, 0xa54eca4f,
+       0xac0310ef, 0x7dc47c7d, 0x8b125eac, 0x655e2c7f, 0x2c5efcd9, 0xc14536cb,
+       0xcfdfb271, 0x5e1852f1, 0xd1365fb8, 0x24f5e3a5, 0xdfea4ee9, 0x88555f25,
+       0x7ccaef90, 0x02d7df91, 0xf2c3afbf, 0x25496b1d, 0xbd108ef9, 0x0c17ab4c,
+       0xe0f48479, 0xa5eadd9a, 0xbe5d3b77, 0x9bde8108, 0x638e72c3, 0x88ba52fa,
+       0x6c91cbeb, 0x6a0baf37, 0x580e4772, 0xf942ae28, 0x9a7c4d3f, 0x75e44237,
+       0x3fe50938, 0x4addc980, 0x82995e36, 0x2ae8cf72, 0xde2d5adf, 0x66e2d1ad,
+       0x66f51fbd, 0xeae9f105, 0x89fd61de, 0x4607b53f, 0x7a9fc4c8, 0xd4dbcf13,
+       0xd0ead6ff, 0xa38bc99a, 0x47ef62ee, 0x297af660, 0x45be2aff, 0x9355b29e,
+       0x961ef1cb, 0x5fb60171, 0x4076bbf4, 0xa6809fd3, 0x9c70ff57, 0xe2a21fd5,
+       0xffa211ac, 0x754fe265, 0xf32b55dc, 0xfe7bda63, 0x19b37a56, 0xd11fd612,
+       0xb26ff0ea, 0xf5cbe247, 0x55f9f506, 0x44e7ff5a, 0xa64ce7d4, 0xef28e7cf,
+       0x75e56e3c, 0x156456e7, 0xff107ffd, 0xccbbfccb, 0x3e9a77f0, 0xbc512b06,
+       0x8042e704, 0xbad0f9c1, 0x9fce1072, 0x469658d8, 0xfc9854f8, 0xa2ad3eec,
+       0x3be9bc2f, 0xec2f681b, 0x76fcfc81, 0x7a77d2c3, 0x5e538a20, 0x5c285b74,
+       0xb041b49b, 0x97be40f4, 0x41582d34, 0xb78fb46d, 0xb70f4e48, 0x0ee77a6c,
+       0xe39d17ec, 0x8f1c7d98, 0x1cac5391, 0x45fc6b0e, 0xd39b787b, 0x70ba30a5,
+       0xa1ed4dfd, 0xe12bdd06, 0x01ffffa5, 0xd5b93efd, 0xefd023ff, 0xe3781b15,
+       0x7a6ec8e2, 0x3fbfcc83, 0xf3e7f68f, 0xfa27df80, 0x923afa7e, 0xf397dd20,
+       0xf4979ba1, 0xfb8592ea, 0x807d4bcd, 0x0125c1d9, 0xf0bcec2f, 0xfee906fd,
+       0xe199791e, 0xf4d6a37b, 0x39f92e5a, 0xc77e57bc, 0xe699e2fc, 0xe4dd0395,
+       0x64e903ff, 0xd99f96af, 0x735ff5bc, 0x9510ccbf, 0x80ceb4d3, 0x01a03406,
+       0x0340680d, 0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0,
+       0xd01a0340, 0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d,
+       0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0, 0xd01a0340,
+       0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d, 0x055ff01a,
+       0x328d1fff, 0x800060f6, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00,
+       0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
+       0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
+       0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
+       0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
+       0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
+       0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
+       0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
+       0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00,
+       0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4,
+       0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6,
+       0xee017e3f, 0x0014ab55, 0x000014ab, 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, 0x00088b1f, 0x00000000, 0x62f3ff00, 0x51f86063, 0x408cc10f,
+       0x7f120cb6, 0x66476028, 0x48107d08, 0xf3e2061f, 0x2fe9a48c, 0xb9b04160,
+       0x40afec80, 0xa8597833, 0x88a1bee7, 0xcfd2738f, 0x81ae792e, 0x66322ff7,
+       0xe86067e6, 0x6ff047e4, 0xb3caa3f2, 0x3dd7d3f0, 0xb000c6b4, 0x00eeff4a,
+       0x0000eeff, 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc554780b, 0x3d9cf0d9,
+       0x3764dd97, 0x2485cd9b, 0x200d8410, 0x125c40a2, 0x126e20ee, 0xc3116088,
+       0x65e28145, 0xb201ae41, 0xdb3f6911, 0x5cbb7ffa, 0xc6d6a444, 0xa0b45b4b,
+       0x06a2828b, 0x82482459, 0xa5c8ba1b, 0x5835b5b4, 0x0da978aa, 0x24c4dc88,
+       0x97f4b004, 0x3bef3fca, 0xce7bbb33, 0xf4bc4c6e, 0x7d6f9ffb, 0x7339867c,
+       0xef3bccce, 0x6779de7d, 0x313b10a2, 0x0ae42775, 0x64246efc, 0x19084c99,
+       0xbbc32d14, 0x32413cbf, 0x46bcf909, 0x08f39a75, 0x86a1d929, 0xc5f5a46f,
+       0xd400a41b, 0x0893bb4d, 0xd3484819, 0xcaf7563a, 0xa08e8f0d, 0x4ca764ed,
+       0x8482d136, 0x4592266d, 0x610b09c8, 0xd60a673f, 0xeab126e7, 0xee7b0de2,
+       0xd7e7fe82, 0xfd12499a, 0xec8d44fe, 0x4d92fa86, 0xb4488052, 0xad21eebd,
+       0x5e7fed0b, 0x39260a40, 0x63d37d69, 0x9085339a, 0x6cbfbbe5, 0x5c057182,
+       0xe2167c67, 0xbfbe00d4, 0x23f63565, 0xadb03ca4, 0xa7ed0bb4, 0x99725abc,
+       0xebe538e8, 0x038df0a4, 0x9014b9e1, 0x370bbf69, 0x0fb3895b, 0xc10ae183,
+       0x4b1e7171, 0x6971d3d6, 0xd2a9447f, 0xe3a252ca, 0xf19cfc09, 0x4471c5ad,
+       0x744bf17d, 0xc55dfa1c, 0xa60b92ab, 0x9e226158, 0xa9bf1d20, 0xf3da692e,
+       0x32df9836, 0xec4a77ad, 0x0ebe663c, 0x6c0f28f3, 0x006d4ad0, 0x6e6d06d7,
+       0x0b7f68bf, 0x0f56ff37, 0xd99edad7, 0x6376989e, 0x5147c679, 0x2f5a3bda,
+       0xb41dc427, 0x6d01fc01, 0xf3e8ff62, 0x908d295a, 0x4cbfd04e, 0xff68969c,
+       0xb9f1f884, 0xc0615c4c, 0xb8a5093b, 0xead6e962, 0x496dd3d0, 0x0db6ff1a,
+       0xe9c97e78, 0x81cf98f0, 0x1cbe13e5, 0x73e57f2c, 0xf1bf9c22, 0x29f2c1f5,
+       0xff9f0b9f, 0xcb1437d6, 0x96373ef5, 0x62c6facf, 0x8657c1b9, 0x9bef3def,
+       0x9f26e586, 0xe8bf9f07, 0x4be58f9b, 0xfe7c4abe, 0x2c7eef8a, 0xf8fcf8b7,
+       0x356fab7c, 0x557cdb96, 0xf4e76e58, 0xe00be1da, 0x9b7d3b7b, 0x05f3acb1,
+       0xbe1bf9f1, 0x017f2c5a, 0xaa65a478, 0xa14cb1db, 0x4d1d4a74, 0x484d941c,
+       0x32d95946, 0xa633d695, 0xa7b67ab0, 0xf146996a, 0xd69b3d94, 0x2b731d29,
+       0x6999961b, 0xd652ee7b, 0x58efddde, 0xddeda16e, 0x9ef6b257, 0x93cb6555,
+       0x27cf7b68, 0x8135fb59, 0xb4c9e5aa, 0xac8d9afd, 0x61b06fbd, 0xf7b695b9,
+       0xd7ed61ad, 0x6c2b1d87, 0x3efd7eb4, 0x286c2f56, 0xeb42915b, 0x7d598785,
+       0x0ad56348, 0xc87efd3b, 0x88fdf671, 0x4ceca096, 0x55db1fc0, 0xd2843dd7,
+       0x52fed7ee, 0xd68c32b7, 0xc47dd735, 0xff66c845, 0x33a56ead, 0x865a87c5,
+       0xd3fcbbed, 0xc32b5d58, 0x33fcb7f6, 0x6a9dfdf1, 0xec7fb625, 0x9df6c72f,
+       0xb7b6255a, 0xf6c3eff8, 0xdb0ab53a, 0x601ecb4d, 0xdb0aad75, 0x883d9733,
+       0x52a1bfef, 0xd2138760, 0x6ea3d97b, 0x966f853f, 0x7d02a9e4, 0x9caa6cd2,
+       0x28b7404f, 0xaf901ce1, 0x0d322487, 0xc4a7e5e4, 0xa1e6fa89, 0xc83734ab,
+       0x8343f6e1, 0xc539079f, 0xe7d4265f, 0x0f26b0be, 0xfb0a79fb, 0x3d3f68d1,
+       0xf0a7efdb, 0x7ebaa19d, 0x2f99df0a, 0xf80e79fa, 0x63b939be, 0x677f6cfd,
+       0x779e1eb8, 0xaf3f45ca, 0x8ef63f60, 0xaff0abcd, 0xfcf0f523, 0xa7e89175,
+       0xde95e706, 0xbc767831, 0x1793f14f, 0xfbc767ed, 0xf6123f14, 0x64fd8f53,
+       0x419e0c75, 0xf5d50c1f, 0xf983e833, 0xd8039fa2, 0xf58e974f, 0xe183e3b3,
+       0x283e787a, 0x8dbcfd17, 0xd8eb74fd, 0x387d06bc, 0x87cf0f52, 0x473f448b,
+       0x1d1e9fb0, 0x51e767eb, 0x1e767e3d, 0x28e7e08d, 0x63bbd3f6, 0x4c721af3,
+       0xc7219f8f, 0x8339f822, 0x63aebf74, 0xa63cecfd, 0x63cecfc7, 0x479cfc11,
+       0x363bf278, 0xe89f21af, 0x93e433f1, 0x632e7e08, 0x831d053f, 0x1eb4eea7,
+       0x23a7753f, 0x982551f8, 0xc18ee0d7, 0x1e8cec33, 0x44cec33f, 0x009763f0,
+       0xeb1de19e, 0x1e8ceea7, 0x2267753f, 0x7846c9f8, 0x5e6c7546, 0xe3d33ec3,
+       0x1167d867, 0x9e1138fc, 0x08cdcae2, 0xf4fda10f, 0x379fbb6f, 0xcff5e9ce,
+       0xfe98e71b, 0x8fc47819, 0x21cd57fa, 0x6467002e, 0xa25f994b, 0xd6932575,
+       0x89ba509d, 0x055fda87, 0xf83f70ec, 0xd32fd1b8, 0xb4ea94f6, 0x58ce3582,
+       0x02ec5c7b, 0x4d03ec78, 0x18ef7b3a, 0xa7abac99, 0xd9d74e8f, 0x5df1cceb,
+       0x29acf574, 0x9cf5743d, 0x7dd3ae3b, 0x817665df, 0xd175deae, 0xdbbd5d70,
+       0xf7dd62d2, 0xd66e07ce, 0x3958f7b5, 0xf5ef5749, 0xf5750fc8, 0xd2ce4fde,
+       0x2bacfbd5, 0xdd77f5d7, 0x7aba25c6, 0xea9feabf, 0xcb35f9ea, 0x68577575,
+       0xb05eae8d, 0xff5d71ef, 0x5a7adf03, 0xf87c1f57, 0xe87d5d39, 0xbeeb2f47,
+       0x35fc7e1f, 0xd9e47d5d, 0xc7ff065d, 0x97d138e6, 0x77f065d7, 0x9a07e8ad,
+       0xcfe869bb, 0x60b37516, 0x6cddc7fd, 0x28f1ff58, 0x4a0e35cf, 0x07c39fd7,
+       0x58fdeed4, 0x48ef5cf3, 0x25297f60, 0x4a07244d, 0x8d0c898f, 0x52ad5f6f,
+       0x527ca3be, 0xef72fddc, 0x9af4b4a3, 0xd1a77a5a, 0xa2a6eff2, 0x3f17c0a5,
+       0x97e84c95, 0x09526559, 0x1335647c, 0x57d5cbe4, 0x1fde7e0f, 0xe70fdfc3,
+       0xfd14be31, 0xe656ac3e, 0xeffe1d80, 0x83f3bf65, 0x4f287e1d, 0x93ec3b43,
+       0xf7f6177e, 0xfde7dfa2, 0x49fc0738, 0xd4fd468b, 0x3a35f1d8, 0x7f1c3f7e,
+       0xa6bf8c25, 0xbd2df18d, 0x4fc6ea87, 0x375f31ea, 0xc746927e, 0xe8f21077,
+       0xf1f3dfb2, 0x50bafe29, 0x3dfa50bf, 0x71e96f8e, 0x5abf8e3f, 0xe375f323,
+       0x7fc64727, 0x69fde412, 0x82507f18, 0xae1ef7f9, 0x728f7f9f, 0x3635fcfd,
+       0xbd9667ff, 0xc64fc7cd, 0xbd2b3ff9, 0xe3dfe6cd, 0x66fe6ca7, 0xf8ec6fda,
+       0x37fe08f6, 0xb72ff8c2, 0x9ae5be31, 0xf7f9fa91, 0xbf9fa45c, 0xeaff8d99,
+       0xf8f8f7b2, 0xab7f1c36, 0x7f9b1ef4, 0x7c7007cf, 0xe5d2b9b3, 0xeee64da0,
+       0xd00195c9, 0x263dd413, 0x746020d9, 0x2820219c, 0xefd084e9, 0x903d4817,
+       0xa64e3f0e, 0xffdf477c, 0x1bf29922, 0x6fdcf7f8, 0x12558127, 0x1dd74c19,
+       0x5767a79c, 0x417ed4cf, 0xcb5d993f, 0xae8433d6, 0xf0a6ae77, 0xff9ed535,
+       0xef0a43e2, 0x50038dec, 0x274e514f, 0x3e1cddf0, 0xf0ccaf15, 0xb7594841,
+       0x12bf5489, 0xa4dbaca5, 0x06e4d8fe, 0x411e7fbf, 0x78f8e318, 0xa27a954e,
+       0xe6fe4631, 0x17d7d5ad, 0x0175f404, 0x09301177, 0xa4c5fd2d, 0xf71d254f,
+       0x10275d18, 0x447f97ea, 0x594270fd, 0xdc9513f6, 0xf2f1465d, 0x404f5d31,
+       0x27ae91bd, 0x4cae9da0, 0x14c72e91, 0xb63bf382, 0x7a001ada, 0x0193f17c,
+       0xbb87d81a, 0x1bf2a7ef, 0x727edf2b, 0x5fc28738, 0xd339e7c6, 0x076fa19f,
+       0x4c3c53bc, 0x0b2bf3e4, 0x974f1e2d, 0xd59ee4c4, 0x459954b9, 0xf24a6bdf,
+       0x54ffd0a8, 0xe9b356e2, 0x9d2e7778, 0x5f107aa8, 0xca135cee, 0x5135c939,
+       0x56e89f39, 0xf4c6358f, 0x8066a93f, 0x93227b4a, 0xdf9feac7, 0x37afa656,
+       0x44d56ea9, 0x5134d3e9, 0xdda81b22, 0xdf4d3a99, 0x2339c62e, 0xc5fce3a5,
+       0x6e746578, 0x9e61d39d, 0xeffa63f4, 0x3cd83a1f, 0x34bc3ae8, 0x3f73d617,
+       0x689b5c90, 0x57bc2a7d, 0xa83d7400, 0xb769f3c1, 0x90d6b9a4, 0x92897878,
+       0xe11cfd83, 0xca23bceb, 0xcd0c5fa6, 0x83ff878b, 0x29b756dd, 0x461e7e3f,
+       0xa093a7b8, 0xba76f60a, 0xc67cff47, 0x18fce37c, 0x74e09c5f, 0x407c063e,
+       0x07c093cb, 0x39c7cf14, 0x2bf5441f, 0xc01383e3, 0x4eb09907, 0xa7307c66,
+       0x6ffd312a, 0x479ff4e7, 0x29676afc, 0x9ca9f74a, 0xba73b7ee, 0xe7ab5bcf,
+       0x3cf9b88f, 0x1cc1e1b9, 0x3cf98267, 0xa62547b2, 0x657979f8, 0x2ff91f06,
+       0x8e89b029, 0xbea5677b, 0xfd0376fd, 0x777e9c3c, 0x7165e846, 0xbf3e5197,
+       0x011927eb, 0x7c7133d0, 0x31f5e9c1, 0xb5b4d7a7, 0x4cefed8f, 0xe46be1e2,
+       0xf6b13af4, 0xfb44d579, 0x112f9c6b, 0xf08c6ff0, 0x9bbbe11a, 0xdfa03438,
+       0x9febf7dd, 0xa627f4cf, 0x28b6b79f, 0xf3cc78e3, 0x1971c1c5, 0x68e463c7,
+       0xba89e6e1, 0x74c082fa, 0xd6f3fbdd, 0xcfb5d4ce, 0x6ba05aa9, 0xbdf567bf,
+       0xff4cfaba, 0xdfef744f, 0x5d32ff7d, 0x0f959dfb, 0xcc67daeb, 0x9f574c7f,
+       0xf74a79ee, 0x1b69d4fe, 0x95b7ed74, 0x9f6ba4bd, 0xae9b763c, 0xa75dd13e,
+       0xbdda5f7b, 0x9fc43ba0, 0xd9e79abc, 0xbd9b886c, 0x49cf266f, 0xe84c7af1,
+       0x273ee3bb, 0xebe13f3e, 0x9f29e583, 0xf19f9f0b, 0x1972c50d, 0x176a71e8,
+       0xf4ac754c, 0x3bb33e3e, 0x07217fe8, 0x6eaea89f, 0x7a8d3fa0, 0xc4e7a8cf,
+       0x46bd46fb, 0xa7e0b97f, 0x59cf15b4, 0xb0329124, 0xf312cd0b, 0x43f3c457,
+       0xb2123edc, 0x1a45cb1c, 0xaf45d393, 0x39062e75, 0x7b85a45a, 0xeedada57,
+       0x9c250497, 0x9eaa9ccf, 0xade7383a, 0xef806bed, 0x05abe439, 0xf3dd4281,
+       0xe8479b85, 0x47bb3bbe, 0x402af846, 0xff8187b6, 0x04deb65d, 0xb7bc31f6,
+       0x00fee4db, 0x1319fbaf, 0x09db5bc0, 0xdf59eaed, 0x0ae38cd8, 0xcb0cb9e0,
+       0x5869be53, 0xb079f09e, 0x8f9bee3c, 0x255f31e5, 0xfbbe8d96, 0xe7d8fcb1,
+       0xdf23f2c7, 0xf03f2c6a, 0xc4796155, 0x77cb16b7, 0x0f2c017d, 0xf96336fb,
+       0x65882f8e, 0xcb16af83, 0x4b1b9f26, 0xfc312f21, 0x0c73bdd2, 0x277d08bf,
+       0xce29e1f4, 0x5f80672f, 0x73c5f112, 0xa938be7a, 0x185f2256, 0x0e91a1f5,
+       0x6df77d46, 0xf4dd21f9, 0x9443f0fd, 0x7a06b9de, 0xde8f6cf7, 0x397d221f,
+       0x0e4dd3bd, 0xf7a70f06, 0x45780623, 0x041281a9, 0x7e6665bd, 0x595b711e,
+       0xabc453dc, 0x7b8b3249, 0x337578f2, 0xbc0377fd, 0x10fb04a7, 0xbf6b5fda,
+       0xe21bdbff, 0xcc47adcc, 0x3db5e484, 0xdafd233f, 0x9bf103c4, 0xc9ff0ebe,
+       0x14af0cc9, 0xda84b1aa, 0xbed73587, 0xeac59aee, 0x423b010a, 0xb8d8ae82,
+       0xc05fa46f, 0x78fb7665, 0x7f31374d, 0x6657bad3, 0x776f08f8, 0xf2894e4d,
+       0xd2dcd7ab, 0x95f833bb, 0xd8099a1f, 0xe9b01233, 0xf5a7e5f1, 0xb57c51c1,
+       0xf4f68f35, 0xfc2fffde, 0xda8fa7b4, 0xa48743d3, 0x735fc7af, 0x24f75d31,
+       0x008e2f58, 0x6df41c3e, 0x1ba1b0f8, 0xf81061f0, 0x5adff69d, 0xe92a4d73,
+       0x66e7ed17, 0x13af9393, 0xde4e9ebe, 0xd37e0854, 0x1334537e, 0xcbae9eb9,
+       0xf24dcf65, 0x5dcff020, 0x6f4a7e8d, 0x6bab6eff, 0x49d61385, 0x7612fe67,
+       0x75fa17c2, 0xe7c1eb73, 0x59aeb0ed, 0x1c726392, 0x3e9b6c2f, 0x0e79838b,
+       0x547fac5b, 0x56b7afab, 0xdc596349, 0xa53a99c4, 0x8769e83f, 0xd02f78e3,
+       0x8a58399b, 0x68e4967e, 0xf019e38e, 0x79c9805e, 0x81ea1a75, 0xbe0b3e33,
+       0xd1c37df7, 0x38513f56, 0xf427c86a, 0x2b89107b, 0xbf7edb3d, 0x2e56be4d,
+       0x228f1068, 0x580bf521, 0xffd1252f, 0x7e80f4af, 0x7e8bac15, 0x6fd941bd,
+       0x579e1ebe, 0xdfa3c6eb, 0x1b1ec539, 0xfcb6d77c, 0xe084e428, 0x3f374a5f,
+       0x2fb8a7f8, 0xfbd0e494, 0xbaba696d, 0x43b3b6b7, 0x3fc1c7e7, 0x2d1cd1c0,
+       0x8b47c029, 0x2b355b38, 0x8512d5b6, 0x322c066f, 0xf6259f81, 0xa34b62de,
+       0x968fa1e6, 0x7f4148ec, 0x7c63c978, 0x1a4fcd9f, 0x4359fbe0, 0x29970779,
+       0x51fd3154, 0xb44c470b, 0x89af0f7e, 0x3559aefd, 0xff5fd10b, 0xdd71f894,
+       0x1aae5a77, 0x796a7e0c, 0xa6e68370, 0x989cfb74, 0xffbe82c6, 0x2f63bc9c,
+       0x57b7918c, 0x7be70d64, 0xffbd6acf, 0xbab1d74a, 0xeac75d3a, 0xa4c973ea,
+       0x9a17d82c, 0x974aa4fb, 0xd5aeb8d4, 0x7656ffb5, 0x91e77ce0, 0x876055ca,
+       0xbc29a93f, 0x71e0047d, 0xb0c1fae7, 0x9b459c4e, 0x29fea973, 0x03487cdf,
+       0xe3a6f939, 0x0bef802f, 0xf315c7e2, 0xe407db8a, 0x59bc5878, 0xd8120772,
+       0xf76e5abd, 0x3bfa5e84, 0x1eb31fc0, 0x23e7cd3f, 0x3f9adfea, 0x65c32932,
+       0x4339e945, 0xc1921cf6, 0xa49f008e, 0x5be2f946, 0xd7139ff7, 0xd7bfdfff,
+       0x1d12bbfe, 0x4ffed37f, 0xdefc5e83, 0x0715effa, 0xf044c5ff, 0xb22c3a0b,
+       0x17c01c34, 0xbe096e1d, 0x14dcb853, 0x7c60714d, 0x725ab9aa, 0xc4fbe999,
+       0x2c8e9c4d, 0x3d601fa6, 0x6a5afcd9, 0xe1bd413e, 0x1f3a6e20, 0x552e7f2b,
+       0xd123d9ef, 0x3b4ae175, 0xfe51a771, 0x9953e954, 0x692ad1ca, 0xe5a24580,
+       0x7f739ae2, 0x9bf68379, 0x88099214, 0xa1853374, 0xdd97f701, 0xac776069,
+       0x03b411e4, 0x257ec7b0, 0xd1a70a23, 0x0578103e, 0x8d8397ec, 0x61b6463b,
+       0x9d75a6fc, 0x9955718c, 0x919bf75c, 0x0f782f54, 0xeda2f952, 0xb405f0ad,
+       0x5d7095af, 0x04b07adf, 0x24eaf3eb, 0x6beb4192, 0x60f9ec93, 0x26dcd2af,
+       0x63373c5d, 0x4e7e3eac, 0x5806eefc, 0xf3e6cfff, 0x1c00c405, 0x53bd790b,
+       0x7de1ba59, 0x5c4c5ffa, 0xee67b66c, 0x93f14278, 0x771f4d3d, 0x723f285f,
+       0xed3ae200, 0x06ed6dca, 0x9463900d, 0xf59b85db, 0x21b78175, 0x09e64a4a,
+       0x6236c9b0, 0xadb5bc03, 0x67c1dbc7, 0x8cdfef63, 0x7c71d81c, 0xce64f11a,
+       0xc935e3d1, 0xb5abc7a9, 0x066f018f, 0xf4b8a6bc, 0x3a66a2f8, 0xa9af0890,
+       0xfae87b43, 0x7af1bef9, 0x6fb3e017, 0x57f49f14, 0xa262c966, 0x56767007,
+       0x46ffc8c2, 0x85b5c979, 0x55f7f825, 0xf8658199, 0xf5052b95, 0x5f870e40,
+       0xb3becd9a, 0x60c8bc82, 0x2f285d55, 0x3b046910, 0x391f256e, 0xf2268e80,
+       0xb7d2b909, 0x37de3a6d, 0x59d1df71, 0xc075abf4, 0x1f23d7cf, 0xe9fc5d20,
+       0x0f22b024, 0x00e5d1e4, 0x59f416bb, 0xbae9b39c, 0x711f55f1, 0xcdfea6ce,
+       0x96073e6b, 0xf7b0168f, 0x0091fb9b, 0xe1831bac, 0x884e590b, 0xeba1cf67,
+       0x1fffaa34, 0x80265ad5, 0x9517fc3f, 0x55eecfad, 0xab772c35, 0x47ffae26,
+       0x79f201ff, 0x00ffa99a, 0xd0e6a5f1, 0x50d5cb26, 0xbf3195af, 0x75569bc0,
+       0x14df8c2d, 0xb35c1952, 0xf64f182d, 0xc768abd6, 0xc48f669b, 0x9f311a7c,
+       0x163c90a6, 0xa1cdd9e2, 0xc4f7ec4f, 0xdaa69dd8, 0xbb05ae27, 0xb12994f7,
+       0x628cfbff, 0xc87e6efa, 0xfa3d38ba, 0xf509d28c, 0xe83da3e7, 0xb6262a3c,
+       0x9becbf22, 0x77ce337b, 0x9a724847, 0xf2a5dc29, 0x0fe83f1d, 0x537f86fb,
+       0xee24de98, 0x58b333f1, 0x5f563ce8, 0xabd4888c, 0x7ec32afe, 0xc3c45d25,
+       0xcac0e2be, 0x8c87e8b9, 0x0292490e, 0xc108ebfa, 0x0fc8467e, 0x7f32c094,
+       0xe3a28350, 0x0921c1c7, 0x91b836f1, 0x90d37e60, 0x61f6fa23, 0xae218a8d,
+       0x9f819016, 0x3fd29c46, 0x6d7c13af, 0xd7c05927, 0x25965e4f, 0x5b9a4ff0,
+       0x1d396b88, 0x977679bf, 0xf9a78022, 0xd046ec02, 0x363cb2f2, 0x8ff7fad1,
+       0x9e87f30a, 0xc6fed8d2, 0x816d7353, 0x6fbe9465, 0xb8c72dce, 0xf13f17c4,
+       0xbfb44f74, 0x5287a315, 0xdc83684d, 0x75cfb0a9, 0x1295c4df, 0xd552031a,
+       0xfe252cb9, 0x82bfc17d, 0x771f059f, 0x09ec9b9e, 0xb2671824, 0xe294fcca,
+       0x8d247db9, 0x5bb4d7c2, 0x4da57422, 0x747b969a, 0xe9630ef1, 0x0173cb27,
+       0x79ed6f1e, 0x2594ec0d, 0xfa0fd894, 0x3ca3b14c, 0x2ff72d34, 0x1fb5bc83,
+       0x3bf46153, 0x27dfaebf, 0x48723e31, 0x2cefb271, 0x9e813355, 0xe42c732d,
+       0xd6379639, 0xf00a5279, 0x55b8c97b, 0xcba7de14, 0x9f37684c, 0xbf085d52,
+       0x7961317f, 0xa2ff7c71, 0x61b204eb, 0x5cfc8c4d, 0x95248a54, 0x0ea92bf6,
+       0xe3c33fec, 0xd77e0092, 0x8769ffbf, 0x4be690fd, 0x1763a466, 0xdf10f71e,
+       0xfad95575, 0xfeea8371, 0xd0f58152, 0x0b944cfc, 0x9ceec797, 0xf5f2ed4d,
+       0x09ef14b5, 0xffe146fc, 0x98e87ba5, 0x9b749e14, 0xb892f909, 0xd5074edd,
+       0x7e225e77, 0x8883947e, 0xa225845c, 0x51ea8e0c, 0x53852429, 0x681c3ea8,
+       0x5a6585b1, 0xf3a7cfa6, 0x6231fd86, 0x2835fd61, 0x40fb2367, 0x7ca1aeb8,
+       0x4d821839, 0xaef587f4, 0xafd0bfd8, 0x84af2f42, 0x67ed36b8, 0x604a63e5,
+       0x9d67ed05, 0x357498d2, 0xcedcf32d, 0xba412062, 0x5003f4e2, 0x2e27cd57,
+       0xf6b1210a, 0xf1169f5c, 0x0ed0a847, 0x78c64af8, 0xd38e9180, 0xf4f2f822,
+       0xf3fce952, 0x09bcb60f, 0x892b8b6e, 0x6fdae78d, 0xca593b41, 0x4fb0eaed,
+       0x17d0014d, 0xee237c24, 0x112d799b, 0x17d3a0fd, 0xc4686ec3, 0xef61ae7c,
+       0x54a87833, 0x41fde1b9, 0x7d723c11, 0xa136fdc2, 0x8284863f, 0x2eaeb085,
+       0xb5ee1508, 0x3e0bf1d1, 0xa71b7262, 0x15d20e3f, 0xaf6f8f5b, 0x307c8c37,
+       0x90e54c20, 0x1d1fa5d3, 0x23a0f0bf, 0x52f68752, 0x7019ea95, 0xc99eb916,
+       0x1b30389c, 0x7f38bdf7, 0xe42af119, 0x05e728d9, 0x9af6bbf7, 0x0c885c19,
+       0x8a4438e3, 0x09ece1c2, 0x392de87a, 0x1157f415, 0xeb8503c5, 0x696f2e73,
+       0x60e30217, 0x6e864ffe, 0x65df224a, 0x7e99b25d, 0xc62f631d, 0x20d99ec9,
+       0xd85ed477, 0x7b150f01, 0x8f4c682e, 0x11de9185, 0x0172a7be, 0x10b909df,
+       0x6fe46efc, 0xe82b0f21, 0x189ea657, 0x4760249f, 0xce082965, 0xeb61d52e,
+       0xe157801c, 0x1a7f1337, 0x3a9663c6, 0x78eb38d8, 0x24d2ca5e, 0xd7fa7677,
+       0x25ef5fe8, 0xc4c40913, 0x8b4abc39, 0x7bd17a06, 0x8c812349, 0x8d9f80ef,
+       0xad59f871, 0xcfc78a76, 0xebf3c86c, 0xfe02bff4, 0x87fe1180, 0x5ff8519c,
+       0x421456b7, 0xe70efe9d, 0xef9bd2c4, 0x15f90a13, 0xb6b43af2, 0x9cb52f72,
+       0x2719f271, 0x0c80a197, 0x4f978a78, 0xccf41932, 0x23f33088, 0x817a728c,
+       0xf6f9a3cf, 0xefc0de96, 0x0ea7b2f9, 0xf7def7e0, 0x2fe83745, 0xc63249df,
+       0x6bf32053, 0x2bd81765, 0xb3a190d2, 0xda76f107, 0xf5c4e8cf, 0x9f9f057a,
+       0xd4f94b54, 0x9e05fb0e, 0x0affd07d, 0x41ff5b07, 0xc7f41e40, 0x7bf3c545,
+       0x852b0b90, 0xa7e2192d, 0x1879c27d, 0x45c832a7, 0x3560725b, 0xce9079f0,
+       0x9f8cec17, 0xa5ab99da, 0x5879e1b6, 0x52f0634d, 0xa23f07e9, 0x06c260eb,
+       0x8fb820ab, 0xe59f35da, 0x602d74af, 0x729fd6f9, 0x50c27e7d, 0x3eca545e,
+       0x0aa97986, 0xbe0b9bf1, 0x2a00dc3d, 0xaa4e5fc4, 0x1f008fee, 0x9c6eb196,
+       0xb883ae47, 0x72276a24, 0xa2e4a095, 0x722fa470, 0x9fc6bda2, 0xbfb49fb0,
+       0x22cef1dc, 0xd52e77a0, 0xcaf71089, 0x91247f05, 0xc22aa85c, 0x3ef9adfd,
+       0x5f07e710, 0x407f7ce1, 0x18cdf3a3, 0xbcb1a2df, 0xd4ce2a85, 0xdbf0092e,
+       0x4e3b7294, 0xc4a2e9b6, 0x8634fcfc, 0x08bae367, 0x52f30608, 0x8d41fd78,
+       0xb8e94928, 0xbec3f16e, 0xc164dfb2, 0xb8958b75, 0xbae7a082, 0xbe1e2c68,
+       0x86ad724a, 0x16952ffa, 0x78f9e40b, 0xfefd6cad, 0x2e49c8e8, 0xbf62be85,
+       0xd61f35a1, 0x3bcf949e, 0xa6fdf469, 0x57bdad91, 0xba5a0ce2, 0xcb737e31,
+       0x27c12f30, 0xb56e8215, 0x496e8eaa, 0xa1888f10, 0xad148adb, 0x4dc5f80f,
+       0xd60bb252, 0x240b4d29, 0xe164a706, 0xff9053f3, 0x1e127122, 0xf2d42857,
+       0x6f423f10, 0x86acf9d3, 0xfb0dc052, 0xf92fd0fa, 0x89b0359d, 0x8f1bfabe,
+       0x81c433a5, 0xed8e67b3, 0xaf67710c, 0x491ba5bd, 0xf3a60710, 0xcbf3001b,
+       0x40d32b56, 0x79df65cf, 0x30f40edc, 0xd7f62dc2, 0x4bfb07f0, 0x586c656f,
+       0x7125fe83, 0xe7cf7ab3, 0x05094eb0, 0x60e39978, 0x2a49cff0, 0xb7d58acb,
+       0x132cfa4f, 0xef5a2515, 0xec4bc914, 0xffe7cba3, 0x89daefb5, 0xbd7be9a3,
+       0x59372635, 0x9fe3f5a4, 0xd6e671d1, 0x3f105d58, 0x8cf65478, 0x773fb803,
+       0x70975f3b, 0x01295d1d, 0x959f8b1c, 0xf079d3c8, 0x43fb611d, 0x1f943f1c,
+       0xd98ecf3a, 0x2ef3a037, 0xd3c506d3, 0xb52559b5, 0x7212e710, 0x2ca7c999,
+       0x4ba082f4, 0xea9bd026, 0xe5465205, 0x8dce2634, 0xdc6166af, 0xe8527f0a,
+       0xbf02fff7, 0x31437ed1, 0x1ba09dca, 0x48f4c3e9, 0x4c75c812, 0xfeb9aabc,
+       0x14fcabbd, 0x9fffbf8e, 0xb68429f3, 0x496943ff, 0xf53e3901, 0xdc535fc0,
+       0x00f60f90, 0x977acf5b, 0xeebce2a4, 0x8ff77ee2, 0xb46a9e38, 0xd79872b2,
+       0x637fbedd, 0x6fa2379c, 0x8efb67ef, 0x8ffaa80b, 0x4b6a2fdd, 0x1479c32f,
+       0xfd7793a2, 0x8562ecbe, 0x7e30eb9d, 0xeb6349bf, 0x1bd505e6, 0xc0275cb4,
+       0x806ff9e3, 0x5f5f14e7, 0xf161aa9c, 0xacdf011e, 0xf81a01ea, 0x9908ffdc,
+       0x1fed9849, 0xb95f4ca9, 0xb7c5126d, 0x08d1e387, 0x179e01f7, 0x3257e739,
+       0xe933c1fa, 0xb953f758, 0x601684f7, 0xff08c71c, 0x52bcba9c, 0xf3987fc8,
+       0x29eb84b0, 0xaa01ff78, 0x3ff73d3f, 0x68e80e74, 0x9f319f9c, 0x171f18c4,
+       0x43c8b37e, 0x983c4d9b, 0x27171297, 0xfb1cfd0a, 0x9e8bc637, 0x797af8d5,
+       0xfb021930, 0xbef96725, 0x621b9c3a, 0xcb04ebfb, 0x14925072, 0x1e968b9f,
+       0xb926052a, 0xc61b72a3, 0x33f8c5eb, 0xf833f8f8, 0xaae15438, 0xe633c7c0,
+       0xf36217ab, 0xdc68b6dc, 0xc7421e6f, 0x89e3a393, 0x39731671, 0x7a0be314,
+       0xe72abe0a, 0x7f515d74, 0xd3235bb2, 0x0c498703, 0x9ff88c7d, 0xca2b3bf7,
+       0xa1cf0447, 0xfd039c5f, 0x51736738, 0xec271769, 0xc28e545f, 0xcfe269fc,
+       0xe16af961, 0x1bb7581c, 0x36a4def1, 0xd8257376, 0xfee2689f, 0xb9717b5c,
+       0x03c89a1d, 0x94f2c2a8, 0x67e07552, 0x191b87c0, 0xb9de2c1f, 0xb79075e5,
+       0xb2bfadf2, 0x569dbc83, 0xbc60b2aa, 0xb41e9b45, 0x29c57ec3, 0xbd076fc5,
+       0xe4c03a78, 0x8aefc8ce, 0x305bec59, 0xe0f6157e, 0x9f3fcbcc, 0xc5f9fc00,
+       0x7a01d526, 0x1cd9bbde, 0x547c5336, 0xd0fc30d4, 0x7f5651fa, 0xade2f108,
+       0xfe5dc3d5, 0x9cb2afe2, 0xe7969f6c, 0x9d7185f3, 0xd3f1b15f, 0x2f0f9052,
+       0x1d7dc169, 0xfe3077e3, 0x97dc74a5, 0xc6a5a99b, 0x11be0bb7, 0x8d6f05eb,
+       0x3c469be0, 0x7f7c665f, 0x172fd73e, 0xfe72bf05, 0x0120f811, 0x9de457a6,
+       0xd28ff3eb, 0x7f8dd9fa, 0x62fd4bb2, 0xbfcb09f5, 0xf3de0d68, 0xdb672eec,
+       0xe71360fe, 0x0177e8c3, 0xcb59cefc, 0xac4230f3, 0xed86a45c, 0xb4591710,
+       0xecf5c541, 0xbfcf2da2, 0xbdd834f0, 0xabaecdf7, 0xb70bff69, 0x38777fec,
+       0xa6dc2fad, 0xd3678e66, 0x763149b0, 0x5a7c0bda, 0xf943a510, 0xb39afdf6,
+       0x40fe7b3f, 0x0b1e947a, 0x48d1edb7, 0x947c78ff, 0x8c68f704, 0x09740dff,
+       0x7d852d1e, 0xbfe7796e, 0xe9fba035, 0xbc8112dd, 0x6e7c38cc, 0xd2fb8fd8,
+       0x23a42780, 0x6e8453a7, 0x94bdf786, 0x39e7682e, 0xefed8c9d, 0x3fe40e69,
+       0x5dce0fe8, 0x757e7e51, 0xfccfc517, 0x982ecc0f, 0xef57fcff, 0x4e3cc3b3,
+       0xaf8c952a, 0x05983fd7, 0xeabe6476, 0xc96072cf, 0xe67fcf9e, 0xf36fc847,
+       0x8b28fd0e, 0x99d2fd30, 0x9dfcd1c5, 0xd6737e61, 0x9bf386dd, 0x77c83c4b,
+       0x65cbd7f3, 0xa8babf10, 0x12dbb190, 0xb94fc5c8, 0xce7c9c5c, 0x27f8fb8c,
+       0xb8531ec1, 0xccc8effc, 0xa2f721cf, 0x9f11fd7d, 0x58fcb50b, 0x18e3c8bf,
+       0x1e22cd13, 0x2c72b54c, 0xa87c6ebf, 0xe673e801, 0xc436772a, 0xf144bd01,
+       0x57487c73, 0xa1f2bf68, 0x3f5cd931, 0x7f189539, 0xc39e04b7, 0x3baa0dfb,
+       0x1df75f29, 0x1d1792b9, 0x9f1f297f, 0xfb0c9dc2, 0x12b327c6, 0x305f87c7,
+       0xd611624b, 0xa303f3a0, 0x7de4cdf2, 0xbe4cc3e3, 0x2607bc85, 0x0bf6858e,
+       0xc0fc9987, 0x53c7e077, 0xd8d9c2b8, 0x848a67be, 0xc3da80fa, 0x51bd7244,
+       0x6fad72e5, 0xe1427c17, 0x897fc056, 0xfb610bf0, 0x7e7927bc, 0xe927dcfb,
+       0xc1763177, 0xe3d9e30b, 0x3b7213fb, 0x6617f84f, 0x7593fcbd, 0x5bc6129d,
+       0x22c47e8c, 0xd3c2f035, 0x3e54af20, 0xda2edf41, 0xbcc196a2, 0xfbdeab3f,
+       0x9ca90fee, 0x7214167c, 0x469fd7aa, 0xdaff9d39, 0xa34fe47e, 0xdc167e9c,
+       0x4e50959f, 0x73c7edb7, 0xfa72f1b7, 0x053fab3f, 0xf01bd6fe, 0x5b61f427,
+       0xc3ea3478, 0x4fc410e1, 0xb7090fa0, 0x13fe46c3, 0xadf8277c, 0xddc595fc,
+       0xf844ef41, 0x845df052, 0xc5df052f, 0xf0ead1e5, 0x083f3717, 0x589f01a2,
+       0x75828ed6, 0xf6c5c586, 0xcb39ae13, 0x819693e2, 0x67d6fd6c, 0x43f582ad,
+       0xb020c726, 0xec4613fb, 0xa427ecfc, 0xbef9fe6d, 0x963e9dcb, 0x65075fa3,
+       0x895f042f, 0x1090e3a5, 0x16fbd383, 0x7d40f409, 0xf76396e0, 0x930b640b,
+       0xbd1f9df7, 0x2c780856, 0xca97ee6a, 0xae1babf8, 0xb5fc445b, 0x054cefd5,
+       0xea1ada7d, 0xad4f7989, 0x4494e507, 0xe25fa5e7, 0xfb857df4, 0x491bcd5b,
+       0xadf94c95, 0xdfa0b499, 0xc168dfe0, 0xbe38b67c, 0xe67f3330, 0xe803e2bb,
+       0x2978f80f, 0x5134b1a9, 0xf9f09a3c, 0x5ff3784e, 0x0baf1f68, 0xbf81306d,
+       0x9346dd7e, 0x24be4fce, 0x1480baf8, 0x784f5f00, 0x20652933, 0x2ecaf3ee,
+       0x0dee5738, 0x093cd39d, 0xf38c95f2, 0xdfc1fe87, 0xe0716fea, 0xc1a86fb8,
+       0xdbdcf07b, 0xeb0216e7, 0x6aad3a85, 0x3b382261, 0xeb383125, 0x7cba338e,
+       0x6a29785f, 0x618b85b6, 0x61237a7f, 0x3a38f671, 0xde0eb613, 0xaa7f704c,
+       0x7ab32435, 0xa347db35, 0x2462fca0, 0xf699777c, 0xd79f231a, 0x057b6ed4,
+       0x8455e7ce, 0xb6898724, 0x1a8d2857, 0x36b78bf0, 0x363d064d, 0xcbce29c0,
+       0x894ffa3b, 0x16febfe1, 0x77b9e705, 0x00331bf8, 0x6acfe72f, 0xddd5f604,
+       0x60ec5afb, 0x0a87ceef, 0x9adadf91, 0x191f76d7, 0xfee9eb05, 0x78a77f00,
+       0x4eabf63a, 0x9447d5d6, 0x5c00ba78, 0x4b8dcc13, 0xfef0095d, 0xf7d9858a,
+       0xdb3e4bef, 0xbf2c3b2b, 0x7afc8587, 0x7c41bf70, 0x378700ff, 0x13b37e46,
+       0x6592efc9, 0xf7986cce, 0xd99efa92, 0x7f25cf80, 0xe2253b50, 0x963e2dab,
+       0xee15b4df, 0xadf90017, 0x7d7bf2a1, 0x50d6fc8c, 0xff8bcdf9, 0xfbe5ae6e,
+       0x202ddf95, 0xfbe009bf, 0x90af9f09, 0x51d0fcdf, 0x1afcdf94, 0x4acef9fd,
+       0x2bf27b4b, 0xf2c29a75, 0x04d65c60, 0x00f01afa, 0x795bb2f9, 0x038c387e,
+       0x37c2fc72, 0x24bce394, 0x4a7fef06, 0x20ec978e, 0x4f128798, 0x4bc7266f,
+       0x4b1ca8ea, 0xc7267740, 0xcb09ea4b, 0x6fc83407, 0x65f9389f, 0xd98457df,
+       0xbcdadef7, 0xc741dcdf, 0x2eab702b, 0x20bf7d0b, 0x6283cf2a, 0xb685f9e5,
+       0xc760f9e4, 0x970779e4, 0x3da72a67, 0xeae8095c, 0x63f3e90a, 0xb27618de,
+       0xe5f03b7a, 0x275c659f, 0x0f79e21d, 0x7276197f, 0x3fc5f020, 0xff8a1e00,
+       0x9a6f9c3d, 0xbfec7e7c, 0xe853f874, 0xabec9547, 0x03ec35fa, 0x12a8de2e,
+       0x351587d0, 0x328fd147, 0x5f85bfae, 0x0b875c65, 0x7e5ed23d, 0x776e61cc,
+       0x088dca26, 0xc65b792f, 0xf38c3ffb, 0xc1c5ef17, 0x5deab079, 0xc042afb8,
+       0x407c5ed9, 0xb83da3cc, 0x15debcc4, 0x148032f2, 0xe286dc42, 0xffc5e511,
+       0xb5cf1947, 0xad5d1595, 0x23e51fbb, 0xaac2cf8e, 0x870812a2, 0x37e7e44f,
+       0xf7bdaee7, 0x18af9c00, 0x0059c474, 0xe188f4ee, 0xa7ac0f66, 0x416a4a5e,
+       0x49741679, 0xb974624d, 0xa379fbc4, 0xf031654b, 0x7256b79b, 0x86f1dd80,
+       0xc1f785ff, 0x8bea7dec, 0x05a3e052, 0x8cc392f5, 0x834e787c, 0xb5295e75,
+       0x854fc0bf, 0x7eb873a1, 0x245f505b, 0xea0bf7c3, 0xa3c0bc24, 0x9474fc3d,
+       0x0edc296e, 0x6df8016f, 0xb30b6700, 0xd13e1c6b, 0x3afc55ee, 0xbe9e4bf8,
+       0xc1972ab4, 0x571704ed, 0x02283bc0, 0xe7194cef, 0x057841d5, 0x3783dbde,
+       0xc74f4935, 0x679e47b7, 0xb4a110fb, 0xbe6bad0e, 0x97887ee9, 0x4cfae034,
+       0x90cc8bec, 0xac0b663d, 0xf3e97b6f, 0xc1690995, 0xa1efebbc, 0xf5d7ff7f,
+       0x0037d91f, 0xece41dff, 0xcbae2a4f, 0xb338a497, 0x1df1dce1, 0xb75d2af0,
+       0xfb336d34, 0xff313de1, 0xabb73e13, 0xc3710297, 0xf19e58b1, 0xf57ab995,
+       0x4f6fb18a, 0xbe43b79d, 0x821f7357, 0x294d2179, 0xda274e2c, 0x0b3249dd,
+       0x587e73fa, 0xf57c34a4, 0x1b49f821, 0x5c03061b, 0xbcf32e27, 0xb1e6cb92,
+       0xd3ddd689, 0xe7109db9, 0x3802ef28, 0x2fb2249d, 0xe59f377a, 0x927e705d,
+       0xad6667ae, 0xf8852b4b, 0xa0bcf1b2, 0x83403827, 0xde31a438, 0x11b88738,
+       0xd0f9718f, 0xbf1611e4, 0xeedff034, 0x273b0724, 0x706a54aa, 0x3ac4f65e,
+       0x8829f889, 0x8f88db0b, 0xf1e24c6f, 0x1fc20ec8, 0x46b1ce77, 0x11b978c2,
+       0x971b79ee, 0x6042eaad, 0xf15e6cbe, 0xb579b3f0, 0x78d20f35, 0x8bb58923,
+       0xbcec420b, 0x3223c576, 0xaf3c83b3, 0xe02bc044, 0x2a5dc233, 0xa7ff422f,
+       0xfa8cad79, 0x607f2ef7, 0xba479c15, 0xfb84a56b, 0x54f9c62e, 0x009cced4,
+       0xdf43c0fa, 0xf3693887, 0x69ed0447, 0x00296af3, 0xd73f8c78, 0x4bfb66e9,
+       0x427bbc7c, 0x7e7351f2, 0x1ea2f4db, 0x3665d20e, 0x849acba5, 0xd5c8a3fa,
+       0x168e462b, 0x7ab9c604, 0xe20bc6e9, 0xe6e17eba, 0xbfe7ba89, 0x74f1e249,
+       0x4f6fbf1e, 0x6265489e, 0x47e422bd, 0xaf9093c8, 0x817ce0dd, 0x0702519e,
+       0x4f00f372, 0x1a7ea18f, 0x4c5e7b27, 0x8f217962, 0x54afa74e, 0xe79e753c,
+       0x0cbc7085, 0x2399f465, 0x6de7c78f, 0x078a31e9, 0xb6c0fedd, 0xe27c7d24,
+       0xcc47cebb, 0x9881c843, 0x8c0e519f, 0x21e91bdf, 0xba46c0e2, 0x6721e918,
+       0x7e40fa9b, 0x5d939121, 0xb9cb77e0, 0xe8d7caa6, 0x5a7772b8, 0xcbf703f6,
+       0x65a4cf25, 0x7928c955, 0xa8572d16, 0x30ad2f4c, 0x1898b8b1, 0x970e5dff,
+       0xcb923328, 0x3ec1270e, 0x830ddbe3, 0x0c2f2cad, 0x5c7145f7, 0x9215a78a,
+       0xe83f809b, 0xfed04fdf, 0xbd926417, 0x712b7f80, 0xd6fdc50f, 0x9e3e7124,
+       0x5fd2e1e5, 0x582e942e, 0x35a70fc7, 0x83473fff, 0x8ab2ecbf, 0x4f5625fa,
+       0x153de135, 0xab25ffc4, 0xb93af367, 0xa2b9eacc, 0xfc29d69d, 0x7bfceeae,
+       0xef566ff2, 0xcdffda2b, 0xb45ebfde, 0x21dac57f, 0x7fb69481, 0xa357f0f5,
+       0xae7f30fd, 0xbbb548c7, 0x62bbf02f, 0xe529eb62, 0xdcf30d4d, 0x15fe3e44,
+       0x96ab97ce, 0x8562bf15, 0xb762a23c, 0x67c4f213, 0xdf3b73f0, 0x90f414b6,
+       0xf7bc26ad, 0x9ba04a01, 0xc0e2cc96, 0xc6a49e82, 0xcbce17dd, 0x2fbba091,
+       0x246635e4, 0xc192927b, 0x61ab7abf, 0xcd47c814, 0x060c1f3b, 0x0ee80bff,
+       0x05be14fd, 0xfa50da77, 0x436abced, 0x46705e6c, 0x193d9172, 0x6cdd1af2,
+       0x3a724adf, 0x14051dc8, 0xadf6b80e, 0xf4d68427, 0x8035b2fb, 0xfb0f6a3a,
+       0xc1659527, 0x986ba478, 0x9cb8fbc5, 0x2e9ecbe4, 0xb8b9bcf0, 0xe061d1f1,
+       0x7ed89997, 0xef48693b, 0xe5a13f90, 0x74798fdf, 0x47b5b9e9, 0x3e3ee166,
+       0xdc90cfdb, 0x6e838c6e, 0x24179c8d, 0x25603f98, 0x6fdc2ec9, 0x7f1c9177,
+       0x307fcf16, 0x1cccbe31, 0xccffb31c, 0x1fbf45e7, 0x870fe70d, 0x375e5958,
+       0x710ca79d, 0x89c401b8, 0x33e42165, 0xf55604f4, 0x09177d60, 0xed19f91e,
+       0x7624f1ff, 0x336585ef, 0x4c87e5d1, 0xd876664f, 0x21f9656f, 0x12706ac9,
+       0x73e4ede8, 0xbb7a01c4, 0xe0a6bd79, 0xf1c50ef9, 0x3c5fcc03, 0xef002260,
+       0x01c06a8b, 0xd72d7479, 0x48e7ce2a, 0x4e66bfb4, 0xe3efd17f, 0xc85af39a,
+       0xcad078cb, 0xb1162fea, 0xd396833c, 0x5af2005a, 0x952d73d3, 0x93b3f9b1,
+       0xf13f9992, 0x78f14a62, 0x3eb043a0, 0x43f8c099, 0xa2065376, 0xbaa579f4,
+       0x63f80920, 0xe288e02b, 0xb8ecdd21, 0x3f4bfa17, 0xc3cde14f, 0xafc46ee7,
+       0x4a901ce2, 0x66fc3bf1, 0x47ee139b, 0x7829317a, 0xcb41c833, 0x839e1316,
+       0x26b9aade, 0xab6b7d42, 0x257901d3, 0x9305e62f, 0x4c5b3e71, 0xc9ad9f38,
+       0xa12dd72d, 0xa3e9af70, 0x14f8058c, 0xe92c512b, 0xcec54f20, 0x99f3e97b,
+       0xacaf4cc9, 0x7a793134, 0xf589d93c, 0x7e3a25c7, 0x8457bc01, 0x4fce24f2,
+       0x75b0b734, 0x0d29a76b, 0xf275f032, 0x25de7144, 0x3c7f832c, 0xbda08cb2,
+       0x0353691c, 0xb9538c4e, 0xfd29336d, 0x07661147, 0x08b47d46, 0x0528c3f3,
+       0xfda08f0e, 0x04a9b5ed, 0x1e7845e6, 0x4f9c8de8, 0xb28d206e, 0x70dfb685,
+       0x74c2b889, 0xe92f1bbc, 0x2ddcbff3, 0x8d14d18e, 0xb62488a4, 0x78f863c7,
+       0x00adc4c5, 0xf45894ff, 0x7b018def, 0xe318e14c, 0x49339c30, 0x1bb476e6,
+       0x2e7b16e9, 0x8dede447, 0x853dfb91, 0xcd58c0fe, 0x66d87805, 0xfb07bf73,
+       0x9506fe7f, 0x46175a24, 0x6a3ed7d6, 0x61537a39, 0x798c94b9, 0x6d1f947b,
+       0xadd707c0, 0xfdc3f2ad, 0x62f5d787, 0x81df03fd, 0x7d66b95e, 0x87d80666,
+       0x511f4e02, 0x7e033e0a, 0x7e32a472, 0x951f5c72, 0x79c9f5c7, 0xbe429fc8,
+       0x9fa0cf80, 0x46606a5d, 0xe50738a2, 0x9fc0f5cf, 0xfd046cdb, 0xb6779fdb,
+       0x12b9034c, 0xfce31ce3, 0x2d572c6f, 0x8547b25b, 0x76645f79, 0x4b977466,
+       0x3c8c635a, 0xc1852bfe, 0x4d5675eb, 0x1bf1009e, 0x2dfb8a9b, 0x162e3c59,
+       0x639d1fcb, 0x59f043f8, 0x51e58d93, 0xa9297e08, 0xbbae2bfb, 0xe2122e4a,
+       0x3f1123c8, 0x28cbf04f, 0x61f3187f, 0xd7e61147, 0xe8a5f919, 0x7d015382,
+       0xb4bf1ed4, 0x089027c5, 0xc8d27605, 0xb992072f, 0xbf26d29f, 0x5e03b65c,
+       0x6497d696, 0xa4fc5d7f, 0x5b47f396, 0x4cacc3ed, 0x5f9f19ef, 0xa8f66148,
+       0x41faab4e, 0x5b85e83e, 0x7b902e4c, 0x70b90dca, 0x325d513f, 0x95288efb,
+       0x4dbea13d, 0x5b667a61, 0x667a8cc8, 0xc1e3cd9b, 0x161cd07d, 0xa78a241f,
+       0x5c9af211, 0x35ce2c5d, 0x0cfcfc31, 0x1aa0bfe7, 0xe212761e, 0x74607f0b,
+       0x014b7a1f, 0x9d25189c, 0x1fb93367, 0x00db4a78, 0x6c3dcbf7, 0x7c0d3a2d,
+       0x04b20c95, 0x35c74f79, 0x38ad77dc, 0xdbfea1ae, 0x2950fbb9, 0x9e0afdd8,
+       0xd76431e7, 0xd062d2a1, 0x37a65627, 0x29fd71cf, 0x4e60c3ea, 0xf70d0fa0,
+       0x4c230d15, 0x53ddc54f, 0x1f937c04, 0x77bb8f6d, 0x0635d1a8, 0xef771ac8,
+       0x98f711d0, 0x7bdc2714, 0x797bc1e3, 0xe1efeee2, 0x67bc60fc, 0xc7927fa6,
+       0xf83f0562, 0x36dd8695, 0xb3276be0, 0xb2ad41c7, 0xa92bcb2f, 0x23fc09ec,
+       0x147f0ce4, 0xf7bfc15f, 0x7cf62e79, 0xbe7c2dc3, 0xb614b88f, 0x61a8dd3f,
+       0x082fe81e, 0xedc82efb, 0x1e6b6f52, 0x5f4b0bd3, 0x5d7c019d, 0xf98ddf38,
+       0xc8a58fb6, 0x2497fcf8, 0x7409e96c, 0xaf182972, 0x92ceaa0a, 0x3df45293,
+       0x81f594a2, 0x4eaed4b8, 0xfe3085c9, 0xb5cf56c3, 0x5a513f00, 0x4377c20e,
+       0x82141786, 0x580db65e, 0x4a760199, 0x1ae14dc0, 0x8516c9bb, 0x6595c043,
+       0xb0f87c65, 0xd6b5e675, 0xd03bec4e, 0x4f47b53b, 0x417be058, 0x39fd60ff,
+       0x3e18f746, 0xf947ba00, 0xea1bba40, 0xdc050f02, 0xbff2dede, 0x25c60f87,
+       0x87e103e2, 0x76ecbf51, 0x1ff78fc0, 0x73b37b97, 0x6fcf2c1d, 0x24778c88,
+       0x9b25f246, 0xb05d8a72, 0xf9d1597f, 0x3e525887, 0xa067ff3a, 0xff766ee7,
+       0x04e7f0b0, 0x45cbe4df, 0x234bafd8, 0x2e83de78, 0xe21fb0d8, 0x823cc349,
+       0x63060eed, 0x744fdff3, 0x59282ea3, 0x72674d60, 0x1bb5efc9, 0xefd09610,
+       0xc715401c, 0x75d7e81d, 0xe2e8bd45, 0x242725f8, 0x03c5ce09, 0x05c95f2b,
+       0x019c33ff, 0x8f300fe3, 0xed3ec30f, 0xb951d66b, 0xeb029f30, 0x8fc09ec8,
+       0xfa59f7af, 0xaf693027, 0x7dbf9977, 0x4fea33a3, 0x97b8fd09, 0xbfc62b77,
+       0xcbf4cadf, 0xcfb66e8d, 0x163d7a0e, 0x801f610e, 0x1487008c, 0x62ba6a9e,
+       0x6a1dbd45, 0x11be78a4, 0xd8f4a0e0, 0xf01a9123, 0xee4c8a17, 0xfbf012cc,
+       0x8015853a, 0x5ffeb9b3, 0x340e20dd, 0x23fbf43e, 0x9178ef00, 0xe7d2eb1f,
+       0x6cfd1ac7, 0xf588ffe1, 0x148ff086, 0x47e1088a, 0x7874fb41, 0xe0e9f14e,
+       0x0c8de0f7, 0xfefe305b, 0x5af3ab78, 0x85779737, 0x98bc63ce, 0x572be5c7,
+       0x4cba5246, 0x5a3f3120, 0x0a4a05bf, 0x2483f8ff, 0x82f18c9c, 0xe7f80516,
+       0x8e449716, 0xadd9f0c5, 0xf875f543, 0xf68aca8d, 0x46fbded7, 0x2242323b,
+       0xff1f9b5f, 0x3e83cb4d, 0x47f62fb6, 0x18f7db1f, 0x2bf643de, 0xed0db0e0,
+       0x1c3bf6cc, 0xb5070f0c, 0x73ed76c4, 0x4dc3ef2e, 0xef10f98d, 0x4bebb3dd,
+       0xee6fa3b4, 0xf05df2fa, 0x569d871b, 0x8767c408, 0x8a981e9f, 0x39a1d271,
+       0xf442be78, 0xc6b4fdeb, 0xe473d84a, 0xdfff711f, 0x5b8f0a01, 0x582cf803,
+       0xf1f671be, 0x0bbfa027, 0xdbc615c7, 0xcd52fc7c, 0xebe20bd3, 0xc81efca5,
+       0xa7f31203, 0x7e01fb44, 0xd6bbdaef, 0x31105e48, 0x3497d2c7, 0xe820bfa0,
+       0xb1a9cb78, 0x78fc95a7, 0x98efc0ba, 0x39afbfe0, 0x295edccf, 0x714e97f6,
+       0xefbd91bc, 0x4ddb3ee3, 0xe02af735, 0x2394dfa7, 0xb8cc7713, 0xe2569ce3,
+       0xfc6b898e, 0x63f06ac3, 0xc4f4bef6, 0xbf8b8804, 0x2f91e325, 0x9fdb686f,
+       0x20dea1f2, 0x3377dc27, 0xd0a6f5e2, 0xfdf00abd, 0x97931b38, 0x7e1fc6f6,
+       0xeb8fe51d, 0xf984de81, 0x9425837f, 0xdf5d231f, 0x8cdbf5dc, 0xf8f17ec6,
+       0x02de8b6e, 0x6f0e82ef, 0x054e2d9c, 0x0747b47c, 0xa6ee9f23, 0x79d3f3f3,
+       0xfcfce985, 0xd37b4fd4, 0x3efac0e7, 0x05d60e5f, 0x9feb7a7f, 0x4f3f00cf,
+       0x0c98e5f0, 0xeac327c6, 0xb620c89e, 0xf88c9d28, 0x74636eea, 0xc0e9fc9b,
+       0x7e3e5414, 0x6ce700d2, 0x536c38ca, 0x57ef1389, 0xbdfcfc24, 0x954dbed1,
+       0xea0318ef, 0x8cdf68d2, 0x738a6d76, 0xd7c3de26, 0x6384bdde, 0x2052aadf,
+       0x5954b3dd, 0x80fbb0aa, 0xe02e9f99, 0x6ff3d231, 0x09b6eca4, 0x19f0db52,
+       0x67071de9, 0x3d353caf, 0x3fc2bc01, 0x4e10f717, 0x78f686f9, 0xd7cf4db8,
+       0x7e8d4fe7, 0x5b6ad41b, 0x8ba46472, 0x83e85db1, 0x00a01852, 0x23f83f4b,
+       0x48596ce3, 0x1a4bd2bf, 0xb579c371, 0x93e449ae, 0xc642bb18, 0xba7e4777,
+       0xb59ec1cf, 0x97154fc5, 0x1193c44c, 0xf6b52be5, 0x55f02b31, 0x8565529d,
+       0x6c1babfd, 0x52a45713, 0xb4fe8c3c, 0x5bee0a78, 0x84089a35, 0xce84c6c6,
+       0x813885ed, 0x1c5d5f38, 0x7c0253da, 0xc0694fb8, 0x05f35375, 0xf8c61bea,
+       0x15a1b599, 0x6ac3f056, 0x0b8c6533, 0xba23481c, 0x6dc7a073, 0x3daaefcc,
+       0x9dc13ade, 0x0a73bda0, 0xdc4c9f6b, 0x6768f999, 0x51be3053, 0xf384daba,
+       0xf6b92d1f, 0x321f8267, 0xd9afdd9d, 0x7f643f5c, 0xe9b78526, 0x1fd434ce,
+       0xba1f6a63, 0x110941d7, 0x3e2177fc, 0xb929996f, 0x95efa39e, 0x2f585d3a,
+       0xeb879d9d, 0x655f21b8, 0xed0f1e4c, 0xd75c54e3, 0x2917918c, 0x3cfa6f10,
+       0xf5802a47, 0x71a92ee1, 0xe4fc1999, 0xe21c6c89, 0x7ac067f0, 0x19f19df3,
+       0xcf20d603, 0x05d5fa88, 0x75ea186b, 0x3ba5b3eb, 0xbf81efce, 0x36f4b04f,
+       0x8e51cf09, 0x7f12e471, 0xae94ff0c, 0xfea4f4a6, 0x7650a4d7, 0xe4f1f031,
+       0xc40932b1, 0x656df1f0, 0x5d881256, 0xb1f3f20f, 0xde2af52d, 0xf8e42037,
+       0x53bfce66, 0xdee865a7, 0x0ede6fa7, 0x886267f6, 0xfcb841c7, 0xd9cb80fc,
+       0x3bfd7ccd, 0x1bab93dd, 0xbf308cb7, 0x65a4cfe6, 0x671d2a74, 0x960f4a76,
+       0x70d2d51f, 0xe5f07318, 0xcf4083ae, 0x618fa0fd, 0x5a2f2b3d, 0x2390fc89,
+       0xb77f00b9, 0xb7edf4b8, 0xe3d7d50e, 0xe8353fee, 0x74e0db81, 0x0faf1c94,
+       0x56dfdc84, 0xc710ab2f, 0xe288adb9, 0xbd61fd17, 0x5eaede7f, 0x107cecb8,
+       0x5bef86dc, 0xb2a4ec2f, 0xefca9436, 0xae1fa16e, 0x7e815722, 0x3f572318,
+       0x4cd2fc01, 0x01399eed, 0x21fb08bf, 0x54a5f3d6, 0xc83f815e, 0xab8c4cd9,
+       0xe544b98e, 0x9eba2336, 0xea0be88f, 0xf812b84f, 0x7ad81f39, 0x221df6ea,
+       0xd4fe83fa, 0x9fdddfc1, 0xb550a318, 0x75700052, 0xd442fe25, 0x2c571857,
+       0x10450385, 0x8739cbdf, 0x42af1b71, 0x5768a7d7, 0x8c7a679f, 0xd2ae0bfe,
+       0xf46ffc15, 0x789c4433, 0x7ff08a52, 0x89117cf4, 0x31514e17, 0xa1f8238e,
+       0xf208f014, 0x38c6453d, 0x21fc7b7e, 0xe29fffc6, 0xe3c2920b, 0xaf48bd7f,
+       0xe083f08e, 0x4617c103, 0x4347f1fb, 0xfb2da75c, 0xf5f29691, 0x1f7f63f6,
+       0x7b74f515, 0x6764887e, 0x7363d97a, 0xb5f37960, 0x0fc0d9b7, 0x83f5c499,
+       0xf89143b0, 0x17c65ad4, 0x29671bfb, 0x05e46fb0, 0xc51790bd, 0x0adf88bb,
+       0x4d58ac3e, 0x9e397e30, 0x7aa6a5eb, 0x8ef3cf16, 0x12900396, 0xec7a1252,
+       0xf9675609, 0xb79e822e, 0x5228be70, 0xf7f028f6, 0x49756e5f, 0xb913882e,
+       0x82703c79, 0x6078c25b, 0x7f823e9c, 0xc75bf6d0, 0xd758014a, 0xa093f519,
+       0x7fde64f7, 0x7df09f1c, 0xdc9f2357, 0xbee5c290, 0x9ffee93b, 0x03c60bf4,
+       0x4db53b5d, 0x7b7df157, 0xbe0d9d74, 0x5ed9c82d, 0xfe02bf96, 0xa6f5d035,
+       0x3bf60a4b, 0xe7ef4535, 0xf05b385c, 0xf20b5c4b, 0xaf798df7, 0x37b4f9c6,
+       0xc7e124fe, 0x8c5ebf73, 0xf2c2b37b, 0xa6768df9, 0xbfc2bb5d, 0x32abd233,
+       0x26bfb125, 0xde1c6bf4, 0x8b6dfeb9, 0x5fe9ed6e, 0x53feefa1, 0x2bf457fa,
+       0xcf1882ec, 0x5adb97a8, 0xbb3d09cf, 0xe309836a, 0xf5f03727, 0xae3c0df2,
+       0xc3f70cfb, 0xdede3c02, 0xf782d17c, 0xb6550653, 0x63dfe53f, 0xd6d038c3,
+       0xe97fccdd, 0xfbe2756d, 0xc6324a0f, 0x641c1e29, 0xd74c3d42, 0x3f308526,
+       0x3e9098a5, 0x85dacfb0, 0x2b56b3ed, 0xe3d432e1, 0x7e40852e, 0xf1959e54,
+       0xfa6f83c1, 0x0fff4067, 0x5a6deb1e, 0x70e37181, 0x4331f803, 0xa7dc140a,
+       0x313b334a, 0x6f54dcce, 0xe6aabcc6, 0x03daffba, 0xf9aa277f, 0xf2c17122,
+       0x39bd5f66, 0x7a044fb2, 0x96fc8c62, 0xcd11790c, 0x0ef3042d, 0x970b4e47,
+       0x06e97ac0, 0xd602b0d2, 0x7635c3e1, 0xa788dd8e, 0xc6de7ca3, 0xbec8847d,
+       0x1bcb3d41, 0x79e14929, 0x06fb7123, 0x6fb8250d, 0x15ae48a0, 0xd33ed124,
+       0x60df667f, 0xf29ce038, 0x7a0c5ff3, 0x7fb1b488, 0xfb6355b0, 0x54872d4c,
+       0x39327e02, 0x5e309995, 0x423eded3, 0xb764eedd, 0x82fb0ed3, 0xdbaf9fcc,
+       0xccedc5dd, 0xfcfdfb6f, 0x986296c6, 0xd36ad6c6, 0x47632b4a, 0xe246bb8c,
+       0x727c4671, 0xbfedc7bc, 0x61a35c84, 0x63c462dd, 0xe2194b71, 0x4fe29bf7,
+       0x13d6c5c8, 0xebe06ec9, 0xb8ba27ad, 0x3c63dc61, 0x3b32e70e, 0xbf7604fe,
+       0x326b78ee, 0x6e6ab3ee, 0x5a1bac27, 0x762e2cd2, 0xf3e3110f, 0x78dee760,
+       0x3c07fc6f, 0xb935b7ae, 0x337d8fe5, 0xd851f763, 0xc51349be, 0x0faa3eeb,
+       0x3cfd5f7f, 0xfe7e03e6, 0x13cc51f2, 0x4c86f85a, 0xadaf102c, 0x85e7e14e,
+       0x03f81a03, 0xee3235e5, 0x18b9534f, 0x5625393c, 0x7960acdf, 0x3dd95b34,
+       0x99afe59f, 0xf7e9e303, 0x927fafe5, 0x4df6f90f, 0xc00e5bcb, 0xbff01fdf,
+       0x33bfb12c, 0x87cc6fe7, 0x95cb9afb, 0x2eb271c4, 0x9d7fe676, 0x034eb3ad,
+       0xccda40ff, 0x79605efe, 0x8e6aaa70, 0xd9a5ef59, 0xd31ef155, 0xec492f0b,
+       0x5f0a097e, 0xe2bf7dec, 0x7d9c06ef, 0xd5f06249, 0xbbf801aa, 0xb79be583,
+       0xbe39c135, 0x5c6623f2, 0x9f3779bf, 0x4b33fbc3, 0xfcc16eb6, 0x4cad6f60,
+       0x09d619f6, 0x9b53f3ba, 0x45e430e5, 0xbfb0d455, 0x98eb4023, 0x4c115527,
+       0xbdb08e7c, 0xb70b3e73, 0x87eebfd6, 0x2feda83c, 0x9dbec1da, 0x0764d869,
+       0xbf7ed3bc, 0xdc62fcf6, 0xc3e0a979, 0xea5e7b5f, 0x5a72610c, 0x379c3762,
+       0x37c19cdb, 0x6383c223, 0x78a3faf3, 0x70b9fc64, 0xe067c5cb, 0xd7d9ef3c,
+       0xe0067b3e, 0xf9d5f45d, 0x0d7f6067, 0xbd60f512, 0x6ff97dea, 0x7c521e78,
+       0xdff72777, 0x117a5e9a, 0xbd3691cf, 0x6f41766f, 0xbb27f54d, 0xa6ca79c1,
+       0x82caff6d, 0xfad2deb8, 0x2e77e831, 0xcffd41dd, 0xa2bafb04, 0x83e8326c,
+       0x1ab1ceb6, 0x66b7b5e9, 0xf380376f, 0xf06f4a73, 0xdfe7237b, 0x2ecf2c82,
+       0x3aadee72, 0xb8e179f1, 0x93356e73, 0x2061bd6f, 0xd40baa94, 0xdde7bb46,
+       0x5e3a530e, 0x55fa01df, 0xeaf3cc3f, 0x73efd312, 0xd3a507f8, 0xf3faeccf,
+       0xe66b17e6, 0xb434fb3c, 0x79b464d5, 0x01dc2dde, 0xc8f389bc, 0x55eeed63,
+       0xd79b9076, 0x85f3c15e, 0x74f1b740, 0x2e5b4da2, 0xdc738376, 0xbb96d4a7,
+       0xda836f30, 0x940b8843, 0xf287bfd7, 0x10e3b4d3, 0x3f0969c6, 0x2244dc17,
+       0x538e763f, 0x98dcf3e2, 0x71c9cec2, 0x3a39c3fc, 0x39f4e3d0, 0xf8c72f3f,
+       0x6ba39c58, 0xbd5cfceb, 0xefbf07bd, 0x77bb13ba, 0x1a87e378, 0x4a20dfbb,
+       0x3468692f, 0x3a2dbd0f, 0x00383c09, 0xcf62430f, 0xa73e2683, 0xcc373918,
+       0x03f405e9, 0xde722fff, 0x6247d693, 0x248f7a5d, 0x1b4d07d0, 0x26d239d8,
+       0xf53df135, 0xad687ce2, 0x9e62ce81, 0x9087c96d, 0xffe0f6d3, 0xc979f8a6,
+       0x8bf1d4ee, 0xcbd9d3c0, 0x87f8f589, 0xddbbe976, 0x8c96e36b, 0x607cdaf7,
+       0xd3f704ef, 0x98f9e51e, 0xcc5acf2c, 0x96f82cf7, 0xbecf4f94, 0x17fde32c,
+       0x517b82ab, 0x85f51b8f, 0xc23597d8, 0xb78739fb, 0x89d996a2, 0x04a5afb3,
+       0xb39fb46c, 0x3f21d66f, 0xd51f5457, 0xc0ef8f20, 0x8b1aede6, 0x01f933d7,
+       0xc71b113b, 0x9eeafb3a, 0x24dbd47c, 0x97f27e71, 0x437a1f5c, 0x56f1c789,
+       0xb38dd39f, 0xfbc41fd0, 0xef1bdab1, 0x0a9ee28c, 0x50699dfd, 0x4cfa3f31,
+       0x8d41c590, 0xedcc7fe3, 0x203ee466, 0xcf412f6a, 0x5768fb88, 0x3cf30468,
+       0xe79626fd, 0x6a7efc69, 0x00d3c32a, 0xee04b387, 0x82d9750b, 0x52b8b9b8,
+       0xd4cdc32e, 0x6c7b9115, 0xf6f7f85c, 0xe4977922, 0x2f309b91, 0x925de452,
+       0x50bd5927, 0x613703d4, 0xfe10e51e, 0xdac03fbe, 0xeb4c2161, 0xecf97eb3,
+       0x2c7efe4d, 0x3320b26f, 0x9cffcfea, 0x829630fa, 0xd5a67ee8, 0xa049fc4c,
+       0x3ebdf82f, 0x22b27f22, 0x3575e449, 0x9ef7f3b2, 0xfa5f9d6c, 0x77a7bb47,
+       0x5b73ec2a, 0x552776c2, 0xc6eb4b29, 0x4e2a1da0, 0xfabe2075, 0x03911f6e,
+       0xc1ffc1fb, 0x76a707f1, 0xa57f1f8a, 0x6ab7faca, 0xe074dfb4, 0x4025be97,
+       0x09ddbee7, 0x831773e6, 0xa3bf4a13, 0x9e7c14cb, 0xfec1c944, 0x073b995e,
+       0xd22b1fe2, 0x2c63cc34, 0xdd00b0a6, 0x5e5c658c, 0x72a9aa68, 0xa5c72d1b,
+       0xcdc875b2, 0x1ebe4ea9, 0x277f6169, 0xffc2d1cc, 0xe7db184e, 0x9682e597,
+       0xe981d830, 0xecbfcc29, 0xdc31f2da, 0xb4eef1ff, 0x37582ebe, 0x7a4c0d4d,
+       0x21b7e610, 0xf00933d5, 0xeeb4befb, 0x9b5f946a, 0x34fc0527, 0xfcb1ddc9,
+       0x8871f8d0, 0xdbf4fc05, 0x61057187, 0xbc18f763, 0xe955943b, 0xa7c01e78,
+       0xae323f18, 0x03d8bf21, 0x13883d71, 0xf11efbf1, 0xce3a7afe, 0xcc26e3f6,
+       0xb64a6f8f, 0x59b47bf3, 0x00b608dc, 0x3fc7def0, 0xbef9972f, 0x5f775f96,
+       0xa7bb2d5c, 0xb89eee3e, 0x08129e83, 0x8bef1839, 0x3b37de33, 0x4f300494,
+       0xdc7f78d4, 0x307ebe08, 0x40f71bde, 0x5d0fb72a, 0xbddd1748, 0x5fd616db,
+       0xf03d5beb, 0x09dc1b9c, 0x6b3c5325, 0x4d0c994e, 0x0d73ca8f, 0x3e708fd5,
+       0x4e7e75f8, 0xc761ffb8, 0x2d7f003d, 0x79435fdc, 0x1dfc177b, 0x072a2d13,
+       0xbb930ffd, 0xb9a75ec1, 0xacd4ff99, 0xd3cb7bb2, 0xbf4058e8, 0xc98fb834,
+       0x89c4fa0e, 0x9bfe1b79, 0x3c7bee09, 0xa0499729, 0x92e9721f, 0x5c47ee1b,
+       0x3dc7cfc9, 0xf6e9326a, 0xca9d7e61, 0xf96fe3f4, 0xefb1633d, 0xb7a04a4d,
+       0xeb654d9f, 0x552cdb85, 0x9f198557, 0x9f740b3d, 0x70a8f26e, 0x599a9b4f,
+       0x331c42a9, 0xce4fca35, 0x13e2092b, 0xeecedfef, 0xab5f7f4b, 0x81ebf39a,
+       0xef66f3d1, 0xc7814600, 0x6fb8e92c, 0xbee38d3b, 0x4d4ce9d5, 0xd5a7818b,
+       0x99dbe426, 0xeadb720a, 0x91e589e9, 0x1f719a1f, 0xcfa688e9, 0x02f71783,
+       0xc480fb89, 0x7da2417d, 0x291586fe, 0xe91f1fe0, 0x74e77443, 0xd2ff5c42,
+       0xf9039ef5, 0xf3a3047f, 0xa67f73fb, 0xff15dfc2, 0x82f48fab, 0xc5f187bf,
+       0x4cdd73f4, 0x73cddf14, 0xd7f8b9ff, 0x79a3ddb4, 0xdcbc04de, 0x1578db9d,
+       0x531dd7c8, 0x4dfa41ce, 0xf9bf7cdc, 0x9e3f653c, 0x61250ecb, 0xef3bc23c,
+       0x4f180acb, 0xe6f687e8, 0x1d972f9b, 0x2a70bd06, 0x8bde09f0, 0xf626c646,
+       0x8dfe8d5f, 0xe71773e0, 0x0db231f3, 0x493356ed, 0x5cac7966, 0x73ee636e,
+       0xb37ee273, 0xe209fc9b, 0x98f62b3a, 0xd99fec08, 0xe1778941, 0x87754882,
+       0x8af6165d, 0xf5942db8, 0xda1fcd21, 0xb95ea54f, 0x17c42569, 0xc8682fe0,
+       0xfa80faf1, 0x56296e2b, 0x4f2bec0f, 0x79d607ac, 0x5a96c056, 0x58607a7b,
+       0xdb7e84d8, 0x5f07d537, 0xe281f419, 0x82be2270, 0x605033e0, 0xc43e1fff,
+       0x8000938b, 0x00008000, 0x00088b1f, 0x00000000, 0x59edff00, 0xe554707b,
+       0xef773f15, 0xc3cdddde, 0x210366e4, 0x804d8404, 0x85701020, 0x5c7c0188,
+       0x94422101, 0xd6da0300, 0x02101ba9, 0x16a52d79, 0x9b8cea9d, 0x8e233480,
+       0xd29dad13, 0x542cce96, 0x2ec4952a, 0x4dd0689a, 0xd15c04ba, 0x63e02711,
+       0xb46d63a0, 0xec083a2d, 0x98f8a71a, 0xe739ec76, 0x647dd7bb, 0xeffa7471,
+       0xe5f98617, 0x7cebdfbb, 0xe3cefce7, 0x648a12fb, 0x40a50307, 0x676a733f,
+       0xf1d31c02, 0xee016bb7, 0x0d1c442a, 0x00f250e0, 0x007f73e6, 0xd63c03c6,
+       0xe9b6dc06, 0xdb007b5a, 0x2ed8c9ae, 0x95d6c801, 0xfc76edf6, 0x06dbb8fd,
+       0xbab60173, 0xc00f77f0, 0xf9e9b1f0, 0xffbf8150, 0xbe956be7, 0x16bcea57,
+       0x373f4d7c, 0xb772b025, 0xecf7000d, 0xb5ddc372, 0x9d701e34, 0x913ac4a2,
+       0x46383668, 0x9dbac401, 0xef289d7b, 0xb1b0b870, 0xddc3db13, 0x5a64d759,
+       0x1e17c2cf, 0x40074ec2, 0xf3e36e8d, 0x91bdb05c, 0x35eb8157, 0x87973cf5,
+       0x33c685c7, 0xd752e6a7, 0x64df0e9b, 0x4e7dcf1d, 0x9aee5bd9, 0xc1ed1d84,
+       0x508fa459, 0x87df2ca4, 0x43b4ccf2, 0xe47b3ec0, 0xf8ddfefa, 0xcb400e71,
+       0xcce3376e, 0x987a9cf0, 0xe223df85, 0x8687b43c, 0x817ad35d, 0xb77b17db,
+       0xff3d69bb, 0x7c4afa5f, 0x470700b9, 0xc4219dc3, 0x2e98be67, 0x4ec1dbe6,
+       0x05e9e7e3, 0xd0402f2c, 0x39170ab6, 0x9c38e1a8, 0x1b0bf177, 0x9ff6b38f,
+       0xaab37bd9, 0x222a89a3, 0xfa80031d, 0x3d3b0ac8, 0xa7accf64, 0x676e1400,
+       0xfdc14105, 0x528297fa, 0x002bfa89, 0x5dfd82af, 0x01f7f1d9, 0xa73ef1db,
+       0x67f61f67, 0xc6e01de9, 0x421cbbf5, 0x8c00d3ff, 0xdf1372e7, 0xc2b2fdad,
+       0x65c806bf, 0xea411bbb, 0x0dc077b7, 0x9b7e89b9, 0xfdcb057e, 0xa7f05d43,
+       0xcb623b2b, 0x53e23945, 0x5cb1f600, 0xf7813909, 0x169ce4b5, 0x7fb4280c,
+       0xa303ecfc, 0x9f7d2e58, 0x7210e487, 0x67aa7842, 0x0dd7cd3f, 0xee96473e,
+       0x74f8d2f1, 0x20b3fcb9, 0x9e09f908, 0x55018fe2, 0xd13b3df8, 0xfb855d76,
+       0x42de0994, 0xe2fb7660, 0xc4da93eb, 0x7cc4aaf3, 0xfb6d7ebf, 0x1db9e40e,
+       0xa9a2afed, 0x70af1073, 0x7c3d39d3, 0x31bca43e, 0x83d0b67a, 0xe394f517,
+       0x8cdffd12, 0x52e6fe47, 0xf38c573b, 0x659cf53a, 0x400feca5, 0x8202d0fe,
+       0x912af7df, 0x00a937b3, 0xcdaf1fe7, 0x9d73c0af, 0xeb6c0db7, 0xd49f71c4,
+       0xd823ca85, 0xfdf3ceae, 0x5efdc75c, 0xaedd6f7c, 0x739fa899, 0x06b79a5d,
+       0xe050c1e7, 0x8fa87189, 0xcf346786, 0x007e4923, 0xc445e3e3, 0xfc7df4df,
+       0x189eda67, 0x58747e47, 0x1db0b8f1, 0x4813e2d3, 0x47f096ee, 0x7978830e,
+       0x078703f8, 0xf81715e7, 0x543f9276, 0x222eb6f5, 0x8e83cebd, 0x0ce23aed,
+       0xaf88f81b, 0x0f5c62a1, 0xbb7e1df7, 0x926b5f7c, 0x85753a1d, 0x7dc407e3,
+       0x0a916b13, 0xfaffd361, 0xf631721f, 0x24c1f91c, 0x1347bf5a, 0xb5e6b33c,
+       0xd238c0c2, 0x631c1b7b, 0x82c7beb4, 0xd9e26af6, 0x775d778c, 0x9fe3491b,
+       0x69f9fd36, 0x41710fda, 0xc90f6f81, 0x43e478db, 0xf39d1e47, 0x8009a19f,
+       0x4f764243, 0xf97b9ebe, 0xf34fe0f8, 0xee3dbf27, 0x8ffef1a0, 0x7415df91,
+       0x079f0f1e, 0x1f23beed, 0xddf078ed, 0xd875e9de, 0xfc2a53df, 0x1dab47b1,
+       0xdf5be347, 0x086b34b9, 0x123231f1, 0xd7d4bf8e, 0x86f49138, 0x4d985ffc,
+       0xf908767e, 0x69f849ef, 0x8a29f905, 0xaffc415e, 0x8e34f6a4, 0xc18e5dc3,
+       0x3d97ec65, 0x44bf2036, 0x203fb3fe, 0x40fdf5ff, 0x781fd1e3, 0xf3f654fe,
+       0x419b41ae, 0xf1c600ed, 0xb85edc29, 0x835dda9a, 0x73f6758b, 0x3679f21b,
+       0x80646bf9, 0x4c0109d7, 0x5029d321, 0xf648aa1b, 0xa3d63cdb, 0xdba7d4cd,
+       0x55d0dff4, 0x9e2f7c9e, 0x53554723, 0xb54f23fc, 0xb502f225, 0x3fdc2bb7,
+       0xed0df1e6, 0xc13fa24f, 0x740799a0, 0x2d383bc1, 0x5d4ff9e2, 0x7d6ffe22,
+       0x4e8afe65, 0x13d6e73c, 0x13f7f72a, 0xce31ca4f, 0x78193c9b, 0xe536e748,
+       0xe7da0f05, 0xfcc543d8, 0x1b6c5afd, 0x1ae74718, 0xba51165b, 0x38eeaaa9,
+       0x36bf384a, 0xbc4348b4, 0xa3c1cefe, 0x19f3709a, 0x81eebfc4, 0x29d8675b,
+       0x42719dee, 0xfdd88a16, 0x67fdfc55, 0xfadb0f50, 0xf219ff51, 0xf9871e06,
+       0x0e3b5007, 0xc7f6478a, 0xdc8e2b14, 0xbc7c4d5f, 0xda26add8, 0x120b4828,
+       0xf417da9b, 0x6c01ed6d, 0xc46057df, 0x71bf9789, 0x8d44e2fb, 0x8aafc9d8,
+       0xde7b2dc8, 0xe28f30fe, 0x98c3b77f, 0x2ee9fc41, 0x0ca14d83, 0xd74f7d3c,
+       0x4e954f98, 0xdfa992d8, 0xa0fc205d, 0x88bb003c, 0xaadd2d47, 0x5fbb441e,
+       0xc70d56e8, 0x431f00d5, 0x8a02ed60, 0xb0630137, 0x01bff518, 0xc8031fac,
+       0xa6894d1e, 0x68daf641, 0x6b1c3736, 0xd63ca1a8, 0x20e83ea4, 0xa4f8da3f,
+       0x55d0e1f6, 0xffc6ee66, 0x27686153, 0x53ff11c5, 0xed82378a, 0xfb527b4d,
+       0x7887c21b, 0xa953c35e, 0xb13a9bdf, 0xddb44aed, 0x3a8c5705, 0x997f033b,
+       0x42b09304, 0x5c711e20, 0xdc70ecd0, 0xd97dbc89, 0x6f4953ed, 0x3f426d07,
+       0x0fd94f18, 0x2cbf2b55, 0x7e287114, 0x2fec8201, 0xf3474207, 0x9df9ae50,
+       0x63da5ea5, 0xcff45dbe, 0xfce52def, 0xbaa0f602, 0x65500d12, 0xde9096f8,
+       0x176f2f51, 0x9937b9e3, 0xfc7411f1, 0xa6cded87, 0x1e91361e, 0x073635d0,
+       0x079ee553, 0x4fb4edc1, 0x3f3c01fd, 0x903c6bce, 0xd7e96fda, 0xb4d3ae6f,
+       0x2c7464fb, 0x75287362, 0xfd1e1f9c, 0xa17aa554, 0x73fbf537, 0x5cc09bc0,
+       0x60133f4b, 0xeb07e902, 0x97b1802b, 0x8ee4678f, 0x344f97a4, 0x329c5751,
+       0xd7fab1d7, 0x41697c9a, 0x344e28f1, 0xf120d505, 0xc8129365, 0xcfb79503,
+       0xd7b943ad, 0xe0f0bc5b, 0x3dc7d43f, 0x9bd67ea6, 0xe173e0bc, 0x4a3de6fc,
+       0xeff38230, 0xfe553479, 0x25baa10d, 0x79233ce3, 0xab53a9b3, 0x6e7e6073,
+       0xb40e2d80, 0x98de48f9, 0x70e800fa, 0xe74afe50, 0xb94f8b4f, 0x6e46dc8c,
+       0x5fffdcdd, 0xe22d46ee, 0xf8da7ca0, 0x201bc52b, 0xe27fbbf9, 0xe791b280,
+       0x60dbecb0, 0xd73cc4f1, 0x56cf3df7, 0x61d3becb, 0xbab7db3a, 0x37d93bf0,
+       0x6f463ebd, 0xc618ff63, 0x9150577c, 0xfcfa4fe0, 0xbd9d6625, 0x5e303774,
+       0xcf2cfde8, 0x8362f383, 0x68c079c3, 0x47bca6ab, 0xf149c9ed, 0xcec0ada6,
+       0xfe2ceefb, 0x500b63c7, 0x690f4b3f, 0xa0e0ac5e, 0x96ad4ae9, 0x95d373f2,
+       0x4e4d14af, 0xe6ed27ca, 0x3687a5f8, 0x9c5165b4, 0x25e293f8, 0x7f858bf7,
+       0x40ed4036, 0x829de2a7, 0xc383a3f3, 0x7b202e6f, 0xa5cce714, 0xb77dfcf5,
+       0x76c2e8cc, 0xaf1cdf74, 0x17ac49ea, 0x2df38b75, 0x7ce352bd, 0xe724be79,
+       0xbf68350f, 0xfb2f6306, 0x9e97f9f1, 0xc79f9077, 0xc62814ba, 0x47c5a28d,
+       0xbea00d9f, 0xd270bfcf, 0xa2f84541, 0xa18e93ee, 0x2e03a96f, 0x50885504,
+       0x3877b03c, 0xdb52bee8, 0x10c72ff3, 0x7d4f45d5, 0x34bd20e0, 0x471c2af4,
+       0x41a8f61a, 0xb47afe0f, 0xf10745ef, 0x8153a5a8, 0xfdc9a531, 0xe663f71a,
+       0xc23e7964, 0x092adffe, 0xf933ae7e, 0xe2d3f168, 0xce333aeb, 0xe54f6fac,
+       0x763046e3, 0x0dfce096, 0x4f1c759d, 0x8e647437, 0xaabc5633, 0x28ead88f,
+       0x4eefd7ee, 0x1bf9b71d, 0x941c061e, 0xd9e3d317, 0xd3878b51, 0x70f11a60,
+       0xa26eb238, 0xe97f791d, 0xa844c364, 0x37afa918, 0xe56d7ccc, 0xf5e9cbcb,
+       0x0e67ef62, 0xf1fe73ca, 0xfc17df1a, 0x48edffe3, 0xe209c9e6, 0x25b7e609,
+       0x3ed94fe1, 0x8b23e135, 0xc0dbbf69, 0xbdfa44d7, 0x53a39c2d, 0x24335bfd,
+       0xd85976fc, 0x242a0c19, 0xdbf38d9f, 0x41da106d, 0x3bf58ff6, 0x92f03fb9,
+       0x981075c2, 0xd4deac71, 0xdfa9bd77, 0x8d5fbc7a, 0x30f54d9b, 0xfae283ea,
+       0x6ea37b55, 0xbf316fec, 0x3476bd37, 0x0cbcf48f, 0x16599c44, 0xb2c67112,
+       0xd2279597, 0xd0331cfd, 0x8ddec98f, 0x823c2761, 0x719b97e3, 0xc6277966,
+       0xdfa46519, 0x30e6c6c7, 0x423d025f, 0xd8bcf4de, 0xfe3a9dd2, 0x2ba8814c,
+       0xf67acd87, 0xd57b34cb, 0x02a721c4, 0x51e65bd7, 0x359e41bd, 0x8ffda768,
+       0xe1fe42cf, 0x933dc7fa, 0x397b1ef8, 0xd669bd3b, 0x057b56e9, 0xc3ea8b12,
+       0x5b91de90, 0xf737e490, 0x3921d860, 0x01a9e61a, 0xbdd27fd2, 0xd2ecc565,
+       0xdd16f78c, 0x1d5fe38d, 0x6bd1febf, 0xc62def92, 0xe1e272de, 0x597f8a2f,
+       0x43e29b33, 0x172788a7, 0x7cdd70ab, 0xeb81c3aa, 0x33a77f5a, 0x3f0bf748,
+       0xadea88f2, 0xf213c4a5, 0x0b72b0cf, 0xfeeb04f1, 0x4afeb4f1, 0xe146192c,
+       0x8af657f9, 0xe2e5647a, 0xaf77994f, 0x46e7164d, 0x74c98dbd, 0xffeab00f,
+       0x9d442f96, 0xb16f7d69, 0xa03df10f, 0x6f30ac25, 0x9cbe07bb, 0xc6f28a50,
+       0x509f3efa, 0x16eb5887, 0x54f5b479, 0x797d5036, 0xa0ceaff1, 0x74bce513,
+       0x1f0fe5f8, 0x2ea5f6c0, 0xf2e63117, 0xc1d95c71, 0x0da2d37e, 0x721d7115,
+       0xebbceb18, 0x7c73bd68, 0xc81ee88f, 0xbc40dbba, 0x5137ceb8, 0xb5bb16ff,
+       0xa9d71b42, 0x9183b06d, 0x3ae499ea, 0xcac75eae, 0x8d864b14, 0x566bfe66,
+       0x7bc42373, 0x57346e2b, 0x883dc625, 0x6b88dffc, 0x533b38dc, 0x5cec08fc,
+       0x1b8c8ca0, 0x777b158d, 0xfd5321ba, 0x977ce113, 0xe3dcef5e, 0x24e6de46,
+       0x1e2a1b78, 0xde84b67a, 0xa13b4e71, 0xffce94b5, 0xafb204d5, 0x9ceb7e75,
+       0x9e7e4ce7, 0xc601fba7, 0x952ad69d, 0x279b65f5, 0x708baad0, 0x7626f31e,
+       0xf5483732, 0x17fe8cfe, 0x8d0788cb, 0xb25c7007, 0x7d1da1ff, 0x90438854,
+       0x421cdcf9, 0x3ce492a1, 0x74e2ffd8, 0x97d91be2, 0xa6fc9dde, 0xb2e5d37d,
+       0xfdc45150, 0xfb88a6d5, 0x287d8f6b, 0xfe4dee8f, 0x306d6ac3, 0xfcd67ec9,
+       0x80fe4d7b, 0xefd3dc5d, 0x7c4420a7, 0xd81e0b0a, 0xef2204fa, 0x1a778ad6,
+       0x334aca0d, 0x7e442ff4, 0x035e4b7c, 0xea6d0b92, 0x33cce2d7, 0xcb1b49ff,
+       0x5c393fe3, 0x03df9c94, 0x8a18eeb4, 0xc04dad7b, 0x28072471, 0x0b1c62ce,
+       0xf97b63e4, 0x97ae2ce9, 0x6abb65a2, 0xa9956e38, 0x5b6b7140, 0xc9a9e6ff,
+       0x05bfe1f9, 0xe91738aa, 0x95aa98a1, 0xa6fec527, 0x9560da1e, 0xbc17cf79,
+       0x7888140d, 0x27a3f782, 0x47ee19dd, 0x6ddeb5df, 0x3d8273ed, 0xfa974ec9,
+       0x0dfef9ea, 0x52a6f85f, 0xef9f019c, 0xfd6dc26a, 0xfbe953f5, 0x57cdfea5,
+       0xd2a4bbf3, 0x02bf9296, 0xd5315f24, 0x7914ef45, 0xefb9bfb0, 0xd460229d,
+       0x276a7e58, 0x6efdafe7, 0x8ec4e751, 0x84fbf164, 0x07826502, 0xdd653930,
+       0xb857eea6, 0x55ea688e, 0x583e648d, 0x22dc7af3, 0x1e261e0f, 0x1486b620,
+       0x487ced83, 0xf3ef5360, 0x16a34f2c, 0x76b63b62, 0x4bbfa26a, 0x3c97d620,
+       0x00ee002f, 0x39feafc9, 0x52754c3c, 0x87964f73, 0x3eb14bde, 0xc4b1f914,
+       0xfa8fdc19, 0x99c2f459, 0xcd5b8a22, 0xf50a682f, 0xbbea50c3, 0x679b736d,
+       0xbde88fc5, 0xe81575e0, 0xda55e1dd, 0xc4b0ed02, 0x4d54d181, 0x1d66efca,
+       0x5f9bb560, 0xc8d4abaa, 0xcb06dbef, 0xe6ce512b, 0x3b4abafe, 0x78b4f419,
+       0xb634ba0f, 0x3009eb91, 0x95b65d84, 0x27f0a634, 0xf7290300, 0xb14e506e,
+       0x8d61631e, 0x03a281df, 0xfde9ca67, 0x6fe4b9a8, 0x7347e4e5, 0x537bc50a,
+       0x554bbd33, 0x7de27c90, 0x4d7f9aca, 0xafb3f0a1, 0x0b7b7f4d, 0x7bcda3bc,
+       0x9e1b2ece, 0x4d1aadff, 0x05eb847f, 0x6edd9f51, 0xb7d5cdc6, 0xbc5f5c69,
+       0xc78d1e05, 0xcca18a1b, 0xfac8bce5, 0xa78cddb9, 0xe352aa2b, 0xf03dcadb,
+       0x91a11670, 0x635b4eb9, 0x0c0abfae, 0x7575775e, 0x6635b8ea, 0x36a6b69d,
+       0x56e7fbf5, 0x930c9cdc, 0xc2ea6e39, 0x66c75b9e, 0xb90c7e71, 0x0cdef93c,
+       0xb475e279, 0xf541c78f, 0x683c0b9a, 0x1c66e3a7, 0x01c92b6d, 0x177e28f7,
+       0xa3fd9209, 0x53bfbed9, 0x719f8ade, 0x34553bf2, 0x1565ce2d, 0x29cd3f0a,
+       0x514a7114, 0x9b276ca2, 0xa3ed9c72, 0xed9baf28, 0xe7ec5237, 0x533bc4d7,
+       0xfc937914, 0xacc27c8e, 0x788aa223, 0x7b974b47, 0x8778a17c, 0x34dfa11a,
+       0x5fd08ebd, 0x36a2de9a, 0x6ec5c751, 0x5ffef856, 0xc519f58e, 0x958bb5af,
+       0x14f141a0, 0x2bfdc0f5, 0x54c3d615, 0x62704f88, 0x8f981dff, 0x4d8beea8,
+       0xb6fd7513, 0xefe2f9b5, 0x9b780124, 0x64f168ec, 0x57e45d85, 0x286b0f8b,
+       0xdf12cebf, 0x6ede9f29, 0x7755d3e6, 0x850af35e, 0xadaf4b45, 0x2f9ca7e4,
+       0xb1463146, 0x475e20be, 0x53c7eafb, 0x917d23dc, 0xf32f479f, 0xadc2742e,
+       0xa72e7eb1, 0x2fd36abf, 0xa839476e, 0x7adefdae, 0xeba5e734, 0x9530bab3,
+       0x2b581887, 0xf2138fc8, 0xc7e6333b, 0x943ca6d5, 0x47e80363, 0xedfd4d6b,
+       0x2eadf7cd, 0x0477efc4, 0x7e4c3d57, 0xb3d94675, 0xce2410ff, 0x9d187a4d,
+       0x85addeb4, 0x090c3de2, 0x9b7ef192, 0x16f0179e, 0xd7b8e016, 0x54af718f,
+       0x241777bc, 0x933eebe9, 0xb161d7d7, 0x079c764a, 0x25de9501, 0xdc3b03ae,
+       0x443b6d45, 0x200b88ec, 0xfe81dfc2, 0x4fc45608, 0x9d73fcea, 0x9944723d,
+       0xeff8e3c5, 0x9061f343, 0x7108ddc7, 0x3b740346, 0x32f042e1, 0xcb22b956,
+       0x08af6ca9, 0x4baa5485, 0x82f64523, 0x5213a8b3, 0x2473a665, 0xb38763ce,
+       0xd2a2fd56, 0x0b6011df, 0x3cfd3dd9, 0x0c79d61d, 0x0d4a4bc1, 0x555ca177,
+       0x93695210, 0x1548601b, 0x39f32ff1, 0x4ddd6016, 0x01b8b77f, 0xfacd9fed,
+       0xebf8f208, 0xa66a3ce9, 0xaf2d0cf3, 0xeb1615e0, 0x29129f24, 0xf39d7db2,
+       0x2b11cfdd, 0x6f375e02, 0x03e2fc7d, 0xfbbf8995, 0x9eafc378, 0x2a3d3fa6,
+       0xd3f70186, 0x665c4ddf, 0x9fb11add, 0x788f86ff, 0xe17dfd3f, 0x5215dfba,
+       0x7ce8f23c, 0x8781f04e, 0xf60638f8, 0xb23f74e8, 0x7142b8d1, 0x128b8fdc,
+       0x5c103bbc, 0x2f21b1e5, 0xf2e518ee, 0x43cca5aa, 0xab8d675e, 0xcf7a4ae3,
+       0xe14e4d43, 0x91e4c1ba, 0x6aab7f25, 0x2af891fc, 0x8944a251, 0x944a2512,
+       0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2,
+       0x28944a25, 0x8944a251, 0x944a2512, 0x44a25128, 0x4a251289, 0xa2512894,
+       0x25128944, 0x5128944a, 0x128944a2, 0x28944a25, 0x8944a251, 0x944a2512,
+       0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2,
+       0x28944a25, 0xffe12251, 0x72255300, 0x008000ab, 0x00000000, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f,
+       0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1,
+       0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 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, 0x00000000, 0x00010001,
+       0x000e0004, 0xcccccccd, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc,
+       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,
+       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
+       0x40000000, 0x40000000, 0x00088b1f, 0x00000000, 0x1113ff00, 0x51f86066,
+       0x423ec08f, 0xac9d0c0c, 0xc4b462a8, 0x1818990b, 0x12b102fe, 0x3c430333,
+       0x203aded0, 0x2388107d, 0x16181858, 0x2fd610b0, 0x022bd404, 0x2c4062c4,
+       0x19b7c401, 0x9cdfb348, 0x1f0f680b, 0xc8037f82, 0x3f4024be, 0x1c360fff,
+       0xfb5f40ad, 0x1819d502, 0x8aa06bfe, 0xf2a26831, 0x9bf13519, 0xcf2684c1,
+       0x2167c68c, 0x63247fa0, 0x0d75b600, 0x000400f1, 0x00000000, 0x00088b1f,
+       0x00000000, 0x7dd5ff00, 0xd554780b, 0x673ef0b5, 0xf3399cce, 0x00fde4cc,
+       0x108f0992, 0x2104e034, 0x0432b445, 0x3b69488c, 0xc514543c, 0xf791e109,
+       0xb14a3e44, 0x44033bd2, 0x350af808, 0x0380a050, 0xed168d02, 0x06823ca0,
+       0xfda2901c, 0x5a1bdedb, 0xcb6ab7bd, 0x880b851f, 0x52d11921, 0xf77ac5ea,
+       0xcc9f7b5a, 0xd0049339, 0x9fdffed6, 0xcfb3767e, 0xd6bdaf7e, 0xf7b5ebda,
+       0xa441c448, 0x84be421c, 0xfc8471bf, 0xa484205e, 0x83bf52c6, 0xa908a3a6,
+       0x2d0867d9, 0xc26425cf, 0x5c64633e, 0x136fcd0a, 0x179a2642, 0xbcb19b0f,
+       0xfbcb3373, 0xdd4f6d0d, 0x01c9cb4a, 0x1349d903, 0x49116f92, 0x1467211a,
+       0xd146fec2, 0xf321117c, 0xb35b2ccd, 0x426cc8ed, 0x98b797eb, 0x3fb69988,
+       0x81e0d7b3, 0x429dc2fc, 0xd439d088, 0x67255c1c, 0x8417fed1, 0x45d9b084,
+       0x47e93bf3, 0xd7b15e5a, 0x5dfa8210, 0xaf34b68e, 0x01f3908d, 0x9864b885,
+       0xed693bdf, 0x86548405, 0xd16494f6, 0x05bb957a, 0xa9c748b7, 0xc6442cdc,
+       0x42ef828d, 0xa8bb40c8, 0x5712b66a, 0x97c39b3e, 0x75c5c704, 0xc742dc2c,
+       0xa912fda5, 0x61daf651, 0xcbb2b5bc, 0xf9cf831e, 0x51c71380, 0xd3cf35f3,
+       0xdabb6871, 0x2c370497, 0xbe2456b1, 0xf3bf1d30, 0x73e679a0, 0x32df5836,
+       0x5daecf39, 0x587ee947, 0x9b686547, 0x7983625c, 0x17e7936d, 0x6aabfac4,
+       0x6bcfd64e, 0x9f74a0c3, 0x3d3e3ca6, 0x95c4201f, 0x1257cb17, 0x60db09e2,
+       0xea7921fe, 0x63f7d8f0, 0xb3f71124, 0x5c40d9aa, 0x427fac4a, 0x40ddf882,
+       0x2b8011dc, 0xb5bbb569, 0xa9d176fb, 0x8985b7df, 0xf31f6dbc, 0xc3ef9a79,
+       0x27a70e5a, 0x4d347e61, 0x499738f0, 0x1309fd74, 0x4ab85389, 0x3246b5fb,
+       0x7acbdc33, 0x186405ef, 0x888f884d, 0xe25adf38, 0x2ed21fbb, 0x4e9caeb1,
+       0x3245fe9e, 0xabbd74bc, 0xfbfed604, 0x57f585c4, 0xb03d900d, 0x2aef6baf,
+       0xcb90ce7a, 0xf90292d7, 0xd0d6bbf9, 0x7926932e, 0x0257c008, 0x614015b8,
+       0xcb40d07b, 0x4713bbed, 0xe16971ae, 0xc61f3c57, 0x75128c73, 0xcdbce3fb,
+       0x4d27cba2, 0xaf838a4c, 0x46e679cd, 0x34f3a79e, 0xd211d189, 0x67c64220,
+       0x8b6f882b, 0x9ba465b3, 0x79b3b7c5, 0x85b6ce2d, 0x38ff3482, 0xe685b834,
+       0xce4ddf65, 0x4741e05e, 0xa4064916, 0xe98c913e, 0x7000de59, 0x9c5078a4,
+       0x03ef2573, 0x68c5fa9a, 0x1f4d225e, 0x0107c616, 0x8e012b2e, 0x481ab534,
+       0x6adbac1d, 0x86a70822, 0x05cf4521, 0x9d5a7035, 0x1b94e14b, 0xb1b577eb,
+       0x09b8832e, 0x23bc1359, 0xf8526528, 0x1dcdd2e6, 0x23bdf30b, 0xdb4c1c12,
+       0x00ce2ee7, 0xa5322a78, 0x32f8ed03, 0xc700bf1d, 0xae38046f, 0x3f18fbe7,
+       0x463792be, 0x6079be37, 0xb37c6eb9, 0x38a7c74c, 0x5df829b9, 0x63853e3e,
+       0x233f2116, 0x95f1c5df, 0xfc704b81, 0xeb949906, 0x8f74b7c6, 0x7771821f,
+       0x437e31f5, 0xfafd58de, 0xd7ea5607, 0xbff5b32f, 0x8f9bbc10, 0xfff5c16f,
+       0xd6cddc82, 0x6c47f03f, 0xafda26fd, 0x37477c76, 0xf700c3fc, 0x5fc07dfd,
+       0x7e9b7a19, 0xf5aa83fd, 0xf1b137eb, 0xc83e0d5f, 0xf8e1b7c7, 0xd90791af,
+       0xc52d07fa, 0x3aa64df1, 0x991693b7, 0x21752c72, 0xfd176bc0, 0x074d3a5f,
+       0x45be71d3, 0x422482d3, 0x901ffb68, 0xc5870881, 0xa850df16, 0xf142c97f,
+       0x0be316cd, 0x0052b424, 0x38e5afba, 0xa977773d, 0x326d24fc, 0x4bf185b7,
+       0x10e9f942, 0x96cebf3a, 0x4fbd2f4f, 0x47773be7, 0x42e0dba1, 0x6ed0247a,
+       0xdf8a5f1e, 0x8841e0c0, 0x1daa7b37, 0x7b3793f8, 0xf22c70da, 0x40599f00,
+       0xf03d8e70, 0xf1a35e78, 0xbe86bb4c, 0xe7d06c16, 0xbcfa422b, 0x80f1ef3a,
+       0x160d3424, 0x3a3afc93, 0x8fca19ee, 0x1f93e508, 0xe9047e52, 0x08792359,
+       0x94d38dce, 0x4b59115f, 0x5f70cb57, 0xfe0c48ce, 0x91583667, 0x7dad2f1e,
+       0x60832658, 0x640a563e, 0xf24178cd, 0xff9d3e76, 0x089d7c3d, 0x57e022e7,
+       0xb4f73d6c, 0x47a14cd6, 0xb2779d2c, 0x31a75dae, 0xf5be0462, 0x963d0920,
+       0x7b2ffb41, 0x87d18f62, 0x4fd3c7fc, 0xfd26ba44, 0xf7d74a44, 0xd87e34ce,
+       0x733769ae, 0x3f635aef, 0xd3e7de9a, 0xae559f7f, 0x431a77cf, 0xe5ce1146,
+       0xa36c810a, 0xa7583ffd, 0xf9c7572f, 0x7db1248c, 0x43dde3e6, 0x049992d7,
+       0xfe91fa59, 0xeb64e7db, 0x497ae7a0, 0xca1f383f, 0x9a4ef704, 0x8dea107f,
+       0x4b7c7d84, 0xe7b3ef86, 0x90d7ba25, 0x5225f39e, 0x9273f606, 0x25271b9f,
+       0x08b753e3, 0x7edfe73d, 0x4711ead8, 0xfc475cf4, 0x4e221fbc, 0x968787dc,
+       0x0697bfe8, 0xf0c7d7e3, 0x3e32dfc0, 0x7be6b4f9, 0xe4aef84d, 0xa97c1ad3,
+       0xcbaa9e6a, 0xd3ee8457, 0xa1b05fd5, 0xaf3e5754, 0x5e5742b1, 0x2eb0f0d6,
+       0x447c1a5f, 0x25a1ff57, 0x0fe574cb, 0x95d6add6, 0xab5f2acf, 0xdbe7dfcb,
+       0xef7faba8, 0x72ba6dcc, 0x0e4570e1, 0xd97e37c8, 0xe1499397, 0x135de17e,
+       0xf0c42ed9, 0x73f3c558, 0xcf4c0c81, 0x2e985c07, 0xf4a57a03, 0xa9641e2f,
+       0x0e697b7f, 0xf78ab9d0, 0xd9758d67, 0xf8f12740, 0xf18f4f1d, 0x03780c78,
+       0xe75f50e7, 0xbc40b579, 0x025df740, 0xefd48f3b, 0x97fce67f, 0x6f48e590,
+       0xc7a332d5, 0x8b3397ea, 0xe5aa5e81, 0xad9d5e48, 0x58497eef, 0xb21075c0,
+       0x08a9fb1d, 0xedd0aa51, 0x3cdd20eb, 0x70188e3b, 0x3e105afc, 0xdef3816e,
+       0xf8c02a5b, 0xa7b23791, 0x78f9870f, 0x25be60e6, 0x4762f915, 0x69f25260,
+       0xc5e7e009, 0x26605cf4, 0x3e0267a6, 0xca074f4c, 0x5030fd31, 0x607b6987,
+       0x0327a609, 0x14ff4c41, 0xbdf4c068, 0x7fa62340, 0xf4c06c0c, 0x4c21033f,
+       0x4c1e033b, 0x14d4f1bb, 0x90f903cd, 0x20226fbc, 0x2e1492e2, 0x3372a97f,
+       0x5c85f961, 0x2e0bee6e, 0x27defbf1, 0xbc5048fc, 0x2c59beda, 0xa8e83f6c,
+       0xf3a50893, 0xbbf6c335, 0x44bcb0e7, 0xdd843f90, 0xbbb2f95a, 0xf483d85f,
+       0x9fc7ef6b, 0xf381dce1, 0x9e030def, 0x8af2247f, 0x0b5dba7b, 0xc047ba0f,
+       0x86b75e6f, 0xd5fe5276, 0x7c31705f, 0x2e5c06b9, 0x039cf5be, 0x0cc2e8f8,
+       0xe6fa79d1, 0x1357d7be, 0x34da75ce, 0xe8b7f1f3, 0x851b17f3, 0x741e4c49,
+       0x0e18cc25, 0x9e74e0f8, 0x96fb0c1e, 0xcfdaa981, 0x79d90cc2, 0x85ea193a,
+       0x77643d70, 0xd517e222, 0x3fdeb047, 0xf57d1e7b, 0x5ec79b13, 0x47b68a72,
+       0xdf507b19, 0x0bc4fbf5, 0xe41933e9, 0xbc6ad268, 0x85aae704, 0x40e5f7fe,
+       0xbcc257e8, 0x6c3fafda, 0x826e9a08, 0xe375bbef, 0x552e76d1, 0x7d7683d7,
+       0xce449fe3, 0x5941f8a8, 0x6fae09d2, 0x9d9b3556, 0xa89d7e7a, 0x325bfbcb,
+       0x0dfe3a9d, 0x4af4a0ff, 0x9c120a26, 0x2b1cd5bb, 0x835b24ba, 0x1bb7e740,
+       0x8bee86f0, 0x6af5605f, 0x47d97694, 0x67dc2d3f, 0xe17df3c7, 0x05efae5a,
+       0x9fb41b49, 0x70778633, 0xd34ace85, 0x449ce51f, 0x9e32f9a4, 0x39aef553,
+       0x7cf0ab7b, 0x94126fff, 0xc8ff3ce1, 0xe70458d0, 0x9b786553, 0x76fba1ec,
+       0x80938881, 0xbf205cef, 0x91acdc77, 0x3208afe3, 0x41acb7ae, 0x79516e7f,
+       0xf2a79747, 0x9f3f2e8e, 0x3d034b4c, 0x91937e6a, 0xff285e8a, 0x043bcae8,
+       0x80bbf627, 0xfe04add4, 0xcdef6a7e, 0x700adcf7, 0xc8a5b03c, 0x6873f347,
+       0xbf4a3f71, 0x6427cd95, 0x3aaf93a0, 0x1fb4057e, 0x755c73d9, 0x51f43d5d,
+       0x669a870e, 0x85ea13c1, 0xa6459b9f, 0x9f74a9d7, 0x72753a25, 0x7e5c5e5b,
+       0xf6fe5c64, 0xc6d7fcb8, 0x908a149f, 0xdefdb169, 0x44f2f82d, 0x478043e0,
+       0xf9bc3109, 0xf467fdda, 0x3fe47fe8, 0x44feffb5, 0xffb4ff87, 0xfda9ffdb,
+       0xff31ee0f, 0x5ff5bdc9, 0x149e8a6b, 0xdd7b1ce0, 0xe198e78c, 0x7a0839b0,
+       0x19ab7f82, 0xf637dcf5, 0xd01775fd, 0x26b3e75d, 0x8e7a6262, 0x93bff280,
+       0xdf767bf5, 0x0ffeb75f, 0x8d0b3f2d, 0xb60b7f69, 0xef80fad2, 0x64c8adbb,
+       0x184e5eba, 0x2f5d2841, 0xefd1fd78, 0x2e2f2a11, 0x91dee2b0, 0x0f4cbf05,
+       0x51fb00ad, 0x799fcb2a, 0x08284071, 0xed979e76, 0x1808c311, 0xa3ed40f7,
+       0xad2fee30, 0xa42d1e84, 0xd61375f3, 0xa305fceb, 0x2ee78a7f, 0x24415e9d,
+       0xe77e3757, 0xb5241c02, 0xe052f85c, 0xf0e22840, 0xd55ef4a1, 0x8f31e092,
+       0xfbeaf800, 0x2e8c60b9, 0x0eff2376, 0x5bc88966, 0x77205922, 0xcb53d7c7,
+       0x5540e2fd, 0xb6ec581e, 0xfd53eac5, 0x37cb3e79, 0xa0fd3166, 0x052feb0d,
+       0x958d49fa, 0xd597ecf7, 0xcec891ff, 0xac3f58db, 0x53d72d7d, 0x1572e9e3,
+       0xe6aacba7, 0xa6f6862f, 0x7f32f55f, 0xa65fbefc, 0xafdd0582, 0x10e6cbe0,
+       0x23b5616c, 0x6bef7a82, 0x6d511edc, 0x9e1ea089, 0x3905c7c5, 0x6944f20f,
+       0x8ced097f, 0xf404cc07, 0xedd79add, 0x9adfd81e, 0xf33d7ffd, 0x63bdfa33,
+       0xf80dd59f, 0x0ffaf350, 0x4c6bdf71, 0xdd02d991, 0x2a1ee8bf, 0x1dfad2ff,
+       0x4d9d7e7b, 0xc61d3f68, 0x55d27648, 0x613565ec, 0xcafc9c53, 0xe03e7de6,
+       0x98f2019e, 0x3b5447ca, 0x53fb7c5a, 0x45cff162, 0x4417970a, 0x7c88b34f,
+       0xa9df6f4b, 0x5d39525c, 0xfdabde7b, 0xbecc4a54, 0xc43f7ea4, 0x1ba87be1,
+       0x2e935fce, 0xf2e83d6d, 0x02ebcc10, 0xf3834b69, 0x13f9b6a8, 0x4aed4419,
+       0x2e813590, 0xbee032df, 0xa12b9b10, 0x4d4df937, 0x4cc605cf, 0x75de5097,
+       0xfedfea63, 0xc28b2381, 0x4f86fe7f, 0xe91ce1b2, 0x199e643a, 0x7f39fd42,
+       0xbf1834ba, 0xa0f5dca3, 0x51eb8ac1, 0xe3a4abc7, 0xf5b10bd5, 0x755c6b5f,
+       0xaefc753c, 0xcfac9f8d, 0x69f8e174, 0xb8fc7e30, 0x5c753b6a, 0xde7c572a,
+       0xd886978d, 0x414b96fe, 0x72c3ce19, 0x947ee122, 0x14797a93, 0xcd8841d2,
+       0x74ed4977, 0x97ca9f90, 0x4a5d3edc, 0xf900f366, 0x6901e60d, 0x5ef1c6d7,
+       0xfb7fa380, 0x3a520554, 0x305f5c0f, 0x221a16d3, 0x3ca0f9b0, 0x7d414c1f,
+       0x777be257, 0xe9fdf026, 0x17b87f4c, 0xb81d39fb, 0xf1c6f313, 0x1437c875,
+       0x85a988d2, 0x1ffd3184, 0x8f9c46f1, 0x90238a8d, 0x98f81aa7, 0x0e11c359,
+       0xb6245979, 0xe913f87e, 0xcdbf2b38, 0x572ddad7, 0x30e1c53d, 0x580679c5,
+       0xbe47d066, 0x08ae5da4, 0xa3f364cc, 0xbe5128f8, 0x517f84e5, 0xc79d3a78,
+       0x103826ff, 0x4a7ad9ef, 0x5d056848, 0x7c73248f, 0xbe184c99, 0x5e265c34,
+       0xdd3c1d8d, 0x090ef8c0, 0xe83e411e, 0x5fc1fde0, 0x9451e694, 0x245655a7,
+       0x7802df64, 0x089270e1, 0x91b7638c, 0xd8047588, 0x5af3a551, 0x1b79c1f9,
+       0xa8ecebcd, 0x3a78f2fa, 0xb14bed53, 0x7e70db71, 0xe2cfdfb4, 0xae2cfdfa,
+       0xd6aecfdf, 0xbf270aaf, 0x740bddb2, 0x87c058fc, 0xa78ea6fb, 0x7c28f1f0,
+       0x113f51f2, 0x429dee2d, 0xd616ae0c, 0x22633d15, 0xc0337fb8, 0xf4e14ce8,
+       0xe8e1c278, 0xb29050a3, 0xd7fe0081, 0xfd353b73, 0xed34daf3, 0x7a415388,
+       0x99c7cd5e, 0xa1fc6061, 0x9ecff39e, 0xee78cdf5, 0xee6fa8f7, 0xf7a5beab,
+       0xe6bef6fa, 0x3e75ed63, 0xd55f955f, 0xff5ffebe, 0xf869711e, 0x52829396,
+       0x30ccaf2f, 0x126b7ed0, 0x1dbdfccf, 0x0f5144bf, 0xf7ebfa51, 0x4af802cb,
+       0x5832c7f1, 0xa056ddff, 0xf05ee7df, 0xd74996c5, 0x63af9331, 0x14e97366,
+       0x86264738, 0x526496a6, 0x5abfbf3c, 0x17709b70, 0xbce8ffe9, 0xbaf3e3ee,
+       0x3a4051bf, 0x21917fb8, 0x6ec5eae4, 0x41fe0b35, 0x09d567cb, 0xd3d088a1,
+       0x1b4b057e, 0x3e760696, 0x3b4f6e36, 0xeaf1045c, 0x6cde3e21, 0x0c1a4a42,
+       0x845bed3d, 0xef2957e3, 0x35dede27, 0x2ed1b887, 0xffcf2f16, 0xe463e419,
+       0x91b921c7, 0x46c1afee, 0x31e416f1, 0xfe8dc583, 0x3037fe90, 0xdc2159fd,
+       0x2e5047ce, 0xa4040722, 0x573e8bfb, 0xec55d242, 0x33025b30, 0x62f0ced1,
+       0xd9a60360, 0xce043c8b, 0x412f6961, 0xa05b7f79, 0xdf0fbf1c, 0xd1942edb,
+       0x176ce4bc, 0x6774d3e6, 0x1f7e0960, 0x3fafaf58, 0x644baf7c, 0xd4225cf5,
+       0xc3e0367b, 0xea05cf7a, 0x7cf5bed0, 0x3ff301a0, 0xcd31040f, 0x95f3626b,
+       0x2fe82a96, 0x11a045fc, 0x18fed1eb, 0x41427aff, 0x2f7c3cfe, 0x79b797ab,
+       0x2dd6084c, 0x777e7939, 0x197fe639, 0x377f6108, 0xb5fde0ec, 0xb30b9412,
+       0xb3afdd17, 0xce96b863, 0x030fc9d1, 0xe5752beb, 0x3f063aea, 0x6f5750b1,
+       0x5890def8, 0xfdf30056, 0xe4bbee91, 0xffe0890c, 0x5cbcdfcb, 0x3b0dcfd7,
+       0x15eae8d6, 0xae89feec, 0x4ddec47c, 0x75bbbcba, 0xeeaf2ebb, 0xca65f54f,
+       0x5679e9d8, 0x4205f975, 0x2fdb3f28, 0xf4375e79, 0x075cb722, 0x76bca05e,
+       0x69f87c2d, 0x5c7083c0, 0x4840f545, 0xb3fcb833, 0x3493ec1a, 0x27d838ff,
+       0xecc82fd1, 0x3b734f54, 0x3e40dad5, 0xe0267f7e, 0xc0bafcc6, 0x0c6fcc18,
+       0xcffcc24c, 0xdfcc5e02, 0x09bf3123, 0xf00da9e0, 0xda3359f4, 0xe9671087,
+       0x525b5d7f, 0x923f2043, 0x32f1c68c, 0xa2e637e4, 0x3f709a5d, 0xb3a70543,
+       0x955687b3, 0x7122a6ac, 0x288beb55, 0x9939511f, 0x4e9adc80, 0xefd6bd79,
+       0x037f2d77, 0xfef58395, 0x0721b987, 0x258aadf0, 0x0a29c993, 0xcfcda3ef,
+       0xfae9da39, 0x432c762b, 0x3abcbb7d, 0x6d20bb28, 0xd3fd067e, 0x0dc4d5e5,
+       0xb6e547c7, 0x4b9eff6d, 0x99f55dc7, 0x0f80da40, 0x0107214b, 0x91b376bf,
+       0xde58ae72, 0x009cfcdc, 0xd93b34f3, 0xee9d98be, 0x0a79e208, 0xc5710f71,
+       0x519cdaf0, 0x7f6e7e87, 0xe825f47a, 0x3c87dcdf, 0x2ee92bfb, 0xe50d1a41,
+       0x8a30c46d, 0xf7d80cd1, 0x78582f1f, 0xe791ec04, 0x80b7201f, 0x6bf1e73f,
+       0xe74ecbcc, 0x4eeded05, 0x93bb0b06, 0xf36393fb, 0x1d96ff42, 0x9b1b95e6,
+       0xe5e89d97, 0x52bccd62, 0x772854a4, 0x4ece780a, 0xf04f1824, 0x79fa6df4,
+       0xb2f30d3d, 0x44af3df5, 0xebc02f3a, 0xc4af0e44, 0xfd42f09e, 0x5e0e3134,
+       0x6bc37d89, 0x912bcc28, 0xf4230578, 0xebc18333, 0x79fa2999, 0x780d733d,
+       0x4179d2a5, 0xaf0e54fb, 0xc2f09ed4, 0xbc1c6a7c, 0xd786fb52, 0xd2979858,
+       0x0df1d45f, 0x8e8b60cb, 0xefc0d82f, 0xfb5729a7, 0xd2ca8c73, 0xfddf4f7d,
+       0x005150b0, 0xdd40d3f2, 0x3789a4f7, 0x5329f2e8, 0x4ffaea46, 0x9756319b,
+       0x58a078cf, 0x3b9acf97, 0x7fbed759, 0x795d34f5, 0x191103fa, 0xcb9a8bf4,
+       0xd6f9e3db, 0x7c2f523d, 0x0728cbab, 0x35d7cec1, 0x4163c99c, 0xbd63ca81,
+       0x3e8baff0, 0x5b17db86, 0xff436f87, 0x39789fea, 0x1fb40bc7, 0xe0f03d83,
+       0x55f7f450, 0x13ddfa73, 0xf3be4668, 0x7c8c204a, 0x6fb71f68, 0x8738801d,
+       0x0381823c, 0xd378df68, 0x82788215, 0x19e6dfea, 0xfceb3ce0, 0xfc13329d,
+       0x8be69dae, 0xefc8230e, 0x3771d452, 0xa94107cd, 0x8905b881, 0x1f6dea4c,
+       0xb7f38dff, 0x9ecf07e5, 0x1d2f7e84, 0xb44cbb34, 0x56af09df, 0xf9a7643c,
+       0xdd98f7da, 0xfbfe2fa4, 0x63f7c92b, 0x97e62706, 0x93f97da9, 0x5f8e8411,
+       0x00d13bb8, 0x180aa7fc, 0x07f82a44, 0x1f41b3db, 0x05ec791a, 0xfd47fc1d,
+       0xfedd65f6, 0x230b1e14, 0x43f752df, 0x7ee84f3d, 0x8538c034, 0x56e3e07d,
+       0xe225db89, 0x067f74f9, 0xa7c0b3af, 0xbfe59569, 0x9697eca3, 0xda6cdfcf,
+       0xbf9ceb0e, 0xe071d961, 0x1cb767cb, 0x0bbefe38, 0xdbe3a1a7, 0xb9435f54,
+       0xe7f36bf0, 0x53dcf07f, 0xbd7e22f1, 0x119b9755, 0x70f9dd2e, 0xbdcef6ef,
+       0x7b53d312, 0x57b7d3c2, 0x18587f42, 0x2eaa8ee3, 0x7bdf84bf, 0xd42eb1ca,
+       0xd539172f, 0xfdc9b5f9, 0x601d0f80, 0x8545d97e, 0x2fc812e1, 0xbdd1317a,
+       0xf95faa02, 0x46834bf2, 0xda345ece, 0x2af0be93, 0xddea91f6, 0xc5ea1226,
+       0x4625d23e, 0x48d2996b, 0x578a50e5, 0x2768965d, 0xf5477fe4, 0x986349fa,
+       0x12e20abd, 0x62daa59a, 0xbf36ac69, 0xfaca58b0, 0x4d42faea, 0xdfc7c7eb,
+       0x817d3127, 0x427f07ea, 0xf5e814f8, 0xe84f5506, 0xae703d6b, 0x0cec3ea3,
+       0xbbaf5af7, 0x728d75dc, 0xd2e51ae5, 0x45ffca35, 0xcf29f7e3, 0x55ea66bf,
+       0xe058bf9e, 0xd03e074a, 0x76098f45, 0xe064468e, 0x2d0d555f, 0x1adf3f0c,
+       0x8ff9009d, 0x7d5abeb9, 0x72f8c439, 0x5cd79588, 0x788108a6, 0xd426e2ca,
+       0x49163f7e, 0xe17c6f79, 0x1fd32356, 0x20ff5a6b, 0x73cf80bb, 0x7ce1a93a,
+       0x4532e6a4, 0x695f4a28, 0x1bd61346, 0xfe233466, 0xef491915, 0xad8d9f72,
+       0x8027e54f, 0xce4fc093, 0x3cc5cc6e, 0xf5f227e5, 0x8e1a93f0, 0x9f955f67,
+       0x02f30adc, 0xf3da54bc, 0xf7905e30, 0xdaeebf13, 0xa9c20746, 0xfe80ce9b,
+       0xed7e066f, 0x02a63429, 0xf71809dd, 0x4262dd58, 0xa356e439, 0x5eebed8b,
+       0xbeac4fe6, 0x03f18bbc, 0x17d38d89, 0x538fc7be, 0xe3a2d8d5, 0x16f83d4b,
+       0xff8c578f, 0xf1919f7e, 0xe2848bef, 0xfc4f4147, 0xafa2f150, 0x5b2e6b7e,
+       0xdee8f374, 0x767deeef, 0xc6c73ee0, 0x953c7053, 0xa470aa1f, 0x38dbb9f0,
+       0x627c27ba, 0x38412970, 0x48fb7276, 0xc98d5f3c, 0xc55edc0f, 0x81e3d9f9,
+       0xb5adde3f, 0x38fb5af7, 0x387156c7, 0xd1040eac, 0xf51d242e, 0x5aaec138,
+       0x6f07766f, 0x49f0c437, 0xa164d8e6, 0x9d035e62, 0x849525a7, 0x16a6d196,
+       0xe7f02b98, 0x2af8825c, 0xfe1d24d9, 0xaf3429c8, 0x288db7e3, 0x13069b27,
+       0xe957f001, 0x615f2faf, 0x6b3af164, 0x4b3bb7f2, 0x927fbce9, 0xb820fbff,
+       0x6d601dd2, 0xebfda033, 0x63bfaea2, 0xca64dcd2, 0xfcf8132f, 0x72d1b79c,
+       0xc1e6f8cd, 0xade4014e, 0x76fa89a4, 0x0cb070f1, 0x8abfeba6, 0x1c524cdd,
+       0x20a197e8, 0xc2317662, 0x612230e5, 0x272ae8dc, 0xadcb47e3, 0x95d7a40e,
+       0x63ee2239, 0xadb7b713, 0xc81b3b07, 0xfc848a52, 0xeac894cb, 0xb44109cb,
+       0x4ec199a3, 0x8a7d806b, 0xda4ede60, 0xeb009f31, 0xb8f2041e, 0x4c9fd70b,
+       0x6f412b22, 0xbedf1aef, 0x164fbe18, 0xfe02cf7d, 0x3b6cca5c, 0xd53d8029,
+       0xf40a1beb, 0x2c10c1be, 0xcffad174, 0x5085a21a, 0xfd169b2f, 0x39a58931,
+       0xd3e4d710, 0xff987ff8, 0xf437963b, 0x912ce7cc, 0x5721fce2, 0x5fcb6a86,
+       0x012f3d10, 0x129ca79d, 0xba909e50, 0x09bd4de3, 0x2bf70f10, 0xb1878f23,
+       0x2fe93d31, 0x8f4cb9ad, 0xeac721ed, 0xf70537f9, 0x79ba63f4, 0x63f2e3b9,
+       0xd8d31fa6, 0x2797fdc3, 0x0ec1f8ea, 0x1d8d03a0, 0x11e4b07d, 0xa4355fc1,
+       0xcabf7e91, 0x6dd6bf7e, 0x601a0cbf, 0xf8f1f77e, 0xb3d5220b, 0x22f78f3c,
+       0xff744bb0, 0x6cd455df, 0x593bcb3d, 0xf9873fce, 0xc0f9baf3, 0xec045361,
+       0xce1eef7b, 0xdcfb062c, 0x51e8c66b, 0x3ff5c82b, 0xfdcdf260, 0x5a331cef,
+       0xedefba69, 0x4b9076ed, 0x9cfa724f, 0xd846a24d, 0x0f8f1f47, 0xaafaed53,
+       0x55ca8c5d, 0x0f9be046, 0x7f774244, 0x3c1ee697, 0x1c2efa16, 0x8adfb397,
+       0x9ad80afe, 0xb12cec2f, 0x16bb4d12, 0x679671f7, 0x45eb34ed, 0x57ad8e7c,
+       0xd668f5c1, 0x5b15fb8b, 0x50f082af, 0xfc19fbd7, 0x787ce69f, 0x14fbe8db,
+       0xdd7e33f0, 0x5b344ad5, 0xfbf8881a, 0x5a9bc057, 0x8d272f83, 0x00c2e3ae,
+       0x5854d0df, 0xf2325b4f, 0x6ff8bebf, 0xf466fc77, 0xcdb71606, 0xf386a7f1,
+       0x86fb15fb, 0xe11d8026, 0x220daffc, 0x21e7ddc8, 0xbf7e921e, 0x81343cd8,
+       0x73bec55c, 0x2e75db8e, 0xe8095d3a, 0x911d094f, 0xbec00b4b, 0x539e4471,
+       0x9a9eb3d0, 0x91ed0f2f, 0xb20ed14b, 0xa2388647, 0x1af71e1a, 0x993f7fdf,
+       0x6379c1d1, 0x20e804b8, 0x04e0a2fa, 0xeed55eff, 0x5ed1c73d, 0x247123b2,
+       0x710d2f8b, 0x08db473f, 0x908a9fd8, 0x146f1f41, 0x91057266, 0xb0cc46da,
+       0x8f52e16b, 0x63fd34ed, 0xed57dcfc, 0x31496cbf, 0xbb720539, 0xfa0f1cec,
+       0xc32b7043, 0x1e89b2cf, 0x33f69d83, 0x7f4041b6, 0xdba72de5, 0xaca98e31,
+       0xbf409129, 0x472c8f65, 0x9b6d533f, 0xf81da5ab, 0x0f704864, 0x794fe021,
+       0x14c7f0b8, 0xb28eeb1e, 0xc3fc807d, 0xb8f32fe8, 0x6fbb1a6c, 0xd0aeb187,
+       0xa0f0f409, 0x5cf203cd, 0xbbcf0ce9, 0x205957e0, 0xfe008e45, 0x7d2ceba8,
+       0x0e0635c0, 0xd9b0d285, 0x2442a983, 0xa56be50b, 0x4d205112, 0x86648997,
+       0xffcfeb7c, 0x6c289cc2, 0xa216e9bd, 0xfebfefb0, 0x8de1e01b, 0x8edeb2cd,
+       0x6fe7d619, 0x0be7d16a, 0xcdfcfa23, 0x4ff3e96f, 0xf74941c0, 0x0c2fb5f7,
+       0x37f088c4, 0x47fe0085, 0x8588990f, 0x97eaabae, 0x2703d466, 0x9cf0d954,
+       0x7305f8f8, 0xde47f208, 0xec08b57b, 0xb4bf954b, 0x6f01b8b3, 0xaf2825f8,
+       0x811fa97a, 0x0dff7273, 0x8cb7b544, 0xff64b900, 0x3ed80ddf, 0x9fed3cfa,
+       0xe0f8ffd6, 0x947a5fcf, 0xf9f8ffb6, 0x1210497e, 0xdf87d594, 0xef59aabb,
+       0x41ba1e1f, 0x2161ff3f, 0x664abe7d, 0x2f0bfafa, 0x187e2ac8, 0xdba5df18,
+       0x17f5c695, 0x907f9697, 0x6e20fd45, 0x8182e400, 0x4455efb1, 0xbf46afd3,
+       0xe1e9c89f, 0x019dc05c, 0xc88a63e7, 0x85cfeae2, 0x7a0348de, 0x1bc768fa,
+       0xe74f4069, 0x4fd04b03, 0x6767bd55, 0xd5e79c12, 0xf0e1bfcf, 0xaedf7a40,
+       0xdc82c6a7, 0x0c21bcf4, 0xd3dfa0f3, 0xf8477be0, 0xf4598e57, 0xc91db9fb,
+       0xd17def88, 0x30a8457b, 0x7c0e7b43, 0x8ee87c55, 0x383272a3, 0x9de3181c,
+       0x0fba5dfe, 0x780d9b55, 0x7c2aa65f, 0x038677f7, 0xa2366c1d, 0x8f7aabdd,
+       0xbe3ea091, 0x7bb456ed, 0x813eed55, 0x8dfec771, 0x5e5718a5, 0x61af1124,
+       0x664cba24, 0x75ae7a40, 0xb7ec039f, 0x926e7f55, 0xefc81725, 0x78a3fdfa,
+       0x548c7180, 0x069a28f2, 0xb2cf494e, 0xa9bff022, 0x57ae7bdf, 0x5f7e3edf,
+       0x78d5915e, 0xddaf9225, 0xc97af8df, 0x37688253, 0x5cb25ea9, 0x7d500f17,
+       0xfe0651ba, 0x4a0e3f1a, 0xfa739a90, 0x017f0835, 0xeb917f3a, 0x51ce5439,
+       0xc3cfa2e8, 0x3cb106bf, 0x80952b9c, 0x1bfeb047, 0x851744c8, 0x3234d547,
+       0x032cd209, 0xe42c7bc1, 0xefefe615, 0x7a0473a0, 0x237dd8e8, 0x84bab7da,
+       0xc33f5df6, 0xb7c8edfe, 0x07119c3a, 0xb6544dc4, 0xe2ee319a, 0xf2320be3,
+       0x37e1658d, 0xdc6f101c, 0x145992f1, 0xf1f5b0a9, 0x8362e49e, 0x37e7f003,
+       0x4e19aecc, 0x571d962e, 0x7b9a2fd1, 0x00f8b78f, 0xafcf49fe, 0x273d94ff,
+       0x7d678064, 0xe98b9e32, 0xbd8575c9, 0xedaafdc5, 0x42bae452, 0xb3d3c817,
+       0x5aefdc6d, 0x72f80b9f, 0x06e197d1, 0x6054a979, 0xf4480efd, 0xed7e849e,
+       0x924bd6cc, 0x076c32de, 0x70653a7c, 0xf852762f, 0x945e25cd, 0xf28ee60b,
+       0xa48740c9, 0x96fdc59e, 0x51222449, 0xf80cb039, 0xa3cc08ea, 0x59b65efc,
+       0xb9a2f8c0, 0xe775184f, 0x69e1c400, 0x1a4e57d7, 0x124adfb1, 0xb37cb4c6,
+       0xf802bcbe, 0xa5578534, 0x95e0fcc2, 0xf0718c3b, 0x5a3ea089, 0x930bfbbd,
+       0xfd751c76, 0xfaea217f, 0xd1e5973c, 0xfd45fd4c, 0xf70129be, 0xd8c8ffd9,
+       0xe65f380c, 0xf8e0f699, 0x985cfc55, 0x7e58ea4f, 0xa00c8922, 0xeba3cfe3,
+       0x9e607382, 0x918e8242, 0x92309f2c, 0xdf93c7ad, 0x0eb03d73, 0x36f277ed,
+       0x56aaafdb, 0xd61c3221, 0xf20de743, 0x5b47ac37, 0xb3af9aaf, 0xaefd377a,
+       0x7690ffb5, 0xf7bb5fac, 0x5fae930b, 0xe7a0cf6e, 0x7dd33110, 0x37cdd758,
+       0x71b4c343, 0xe1bdaa23, 0xbac78724, 0x0267e7bb, 0x720d3dbd, 0xd8071658,
+       0x8127aa18, 0x032c676f, 0xb7c742ac, 0xc79ddcdc, 0x2ce5a2f2, 0x76b4c83f,
+       0x54fe86c2, 0x32fa310f, 0x3329ae41, 0x68438f78, 0x37c54ece, 0x29c744d4,
+       0x12d93d93, 0x1e4f75f2, 0xb09659da, 0x6474fff5, 0x5ebab0dd, 0xbf7518e4,
+       0x08e10bd6, 0x641d43c6, 0xbd7c41f2, 0x4fc62671, 0x1fb68e12, 0xdd173e07,
+       0x5a11e547, 0xc1f0a36f, 0x6de3b071, 0x5645cbbc, 0xdd067cd0, 0x1b77e01f,
+       0x502f5205, 0x4bda8cb8, 0xa3d01be5, 0xd4378ef7, 0x4cdd70d8, 0x6dd6b06e,
+       0xfa47fb03, 0x0123f943, 0xb930ef5f, 0xdd741e70, 0xe5a34d0f, 0xb983cb19,
+       0x384bff60, 0x0ede6a1a, 0x8b70efe7, 0xa74bc61b, 0x6127b1b0, 0x7fe700da,
+       0x023c2906, 0xc5319574, 0x88ec1235, 0xffac1ceb, 0xd0f0d154, 0x46539054,
+       0x28d27cb2, 0xfb8ed9e2, 0x49c716b3, 0x30499137, 0xf20ef83f, 0xb3d6ed17,
+       0xc4349107, 0x5d4275f6, 0x3e9f8c21, 0x7064a588, 0x8bcbca06, 0x9eaa7cb8,
+       0xf7f59f6f, 0xea3f0024, 0x3f01f7e2, 0x201279b3, 0x1b1c8c8e, 0x9fed6a26,
+       0x0345fd6a, 0xdf50e93c, 0xc124597f, 0x287fe464, 0x5e67fa5f, 0xff857b42,
+       0x1a824cb2, 0x9cbfec3e, 0xd777cfa4, 0xb1f6c34b, 0x4a12167a, 0x839eadee,
+       0x11fd7484, 0x7f2d7f7d, 0xec24f5e5, 0x77698c8f, 0xe9d91c80, 0xdb3e476a,
+       0x46831215, 0x1174f7aa, 0x9dc1f182, 0x6d5df64e, 0x265339df, 0xa2679411,
+       0x40474fd8, 0xb2630881, 0xf413f5a9, 0x1eb7561f, 0x35ef8129, 0x7ce30da4,
+       0x1256c26b, 0xdbffc5ec, 0x970b0011, 0x3f29fce6, 0xfdd4ed8a, 0x9037b588,
+       0xb38fd690, 0x52222da2, 0xeab75a5a, 0xc00a2bd7, 0xd3947704, 0x2b37f04d,
+       0x72d1b73c, 0x23a3a883, 0xba6ea8eb, 0x275f3242, 0x061d181a, 0xe262bb7f,
+       0xaf3c9a6d, 0xf83edddf, 0x291309bb, 0x602a8ddd, 0xf55d9fed, 0x972c6fef,
+       0xae807c62, 0xd76bdb3f, 0xbcb895e4, 0x6b87e68d, 0xf2b8cef2, 0x8cf2b894,
+       0x567f7cb8, 0xc91ec3bf, 0x1ca9b836, 0x13f7eab7, 0x3a4fca24, 0xa9b32332,
+       0x309e4f04, 0x226133bc, 0x6a8f8dc4, 0x5a79c0f3, 0x59b82adb, 0x5f830fb8,
+       0xb9e19bad, 0x832eddcd, 0xaa3adf7f, 0x7688b8ed, 0x7209c12a, 0x27bc2da6,
+       0xe7687982, 0x330bb4d2, 0xfc3aa4fd, 0xb3ebb601, 0xe9117cff, 0x87fe4d7c,
+       0x765aef58, 0x8faf9274, 0x6e2bef83, 0x3be0b770, 0x92bd026a, 0x77bf9144,
+       0x992ff9ec, 0x7c633fdd, 0xf3d333ab, 0x43adf206, 0xb7cb5382, 0xa41f30fc,
+       0x0e5c65e7, 0x935c7062, 0xb886517f, 0xb787f78d, 0xa9c703be, 0xcb27d175,
+       0x73fb1e40, 0x20d1d9cd, 0x1f2d809f, 0x217af4f8, 0xd6f18664, 0x7861a18b,
+       0xc866adff, 0x7a05d111, 0xf016fb7c, 0x75574417, 0xda4ffc22, 0x284007db,
+       0x9755c5fb, 0x7db53e59, 0x5dc7ec0b, 0x009b7f0d, 0x0e4f1ef7, 0xd2201f68,
+       0x8355a5fc, 0x487e6227, 0xf7c816fb, 0x3f2c1c53, 0x81807dbc, 0x0921cfb6,
+       0x76ff6113, 0x8abf193a, 0x3967bfe7, 0xf7e755ff, 0x29cf7f4e, 0x66a90b80,
+       0x1c0b7dfc, 0xed9f94cf, 0x73b538ec, 0x9d9fdd17, 0x9fc8cc4b, 0x10bc6429,
+       0xe1ce938f, 0xf20ee78c, 0x8df50953, 0x926b384c, 0xcf68fb62, 0x7f21736e,
+       0x0f6ea1be, 0xb3e9d79c, 0xff3f900b, 0xac99ec87, 0xfdd2c6a4, 0xfad29a36,
+       0xe3271593, 0xed1106a7, 0xda8fe99e, 0xda78fe51, 0x0561d6cc, 0x1b534afe,
+       0x7c2b8fdf, 0x4c4c571d, 0xdf24b91f, 0xdacdfd81, 0x950cf946, 0x240966db,
+       0x309c80a8, 0x81394655, 0x3341a3aa, 0xdc5537cd, 0xddd27180, 0x335ad2fa,
+       0xd0a9bfce, 0x26760993, 0x9a693f55, 0xd44cc9ea, 0xdb4d65c8, 0x67cab958,
+       0x5e69729b, 0x12102e73, 0xad9779c6, 0xbb424dcf, 0xf3eec4bc, 0x743b5fac,
+       0x573c1afb, 0x9b3ae1a7, 0x68664312, 0x2fffc2a7, 0xf0c93dfd, 0xbef57efd,
+       0x7507df28, 0xd30ac9dc, 0xec0cca87, 0xf1527e3c, 0x44cb3ae1, 0x39a208cf,
+       0x4d03279f, 0xa448e068, 0xfdf0d1f6, 0x8c7843ff, 0xa3fdf586, 0xf1daf8f0,
+       0x84fc71c5, 0xa0bb8df2, 0x67259aff, 0xf30cdc79, 0x5df0a9bf, 0xe98c442f,
+       0x77b06f8c, 0xd077e804, 0x3e4c0abb, 0xe753b42f, 0x1ad1fb3d, 0xf5d4d794,
+       0x60787f58, 0x9d99dc12, 0xc5fe795d, 0xecfdb49d, 0xf775591f, 0xa4be5581,
+       0xae46bde2, 0x11eec618, 0x4fbb29ab, 0xe80a7208, 0x3aeaed77, 0xc4264f24,
+       0x18afaf8b, 0x609e8228, 0x828ff805, 0xb7432efb, 0x9c18132f, 0x9caa9e60,
+       0x08bb8843, 0x2953b3d6, 0xf97d86ae, 0xa05e2952, 0xf071b2a4, 0xa75e097c,
+       0x03d78dfd, 0x7aeae779, 0xfc72610d, 0xefa604a6, 0xd0f10249, 0x8dffcdf9,
+       0x811adb71, 0x13e21f03, 0xb0bb30b6, 0xc357972a, 0x79f74ee9, 0xe7e3973e,
+       0xc17e3973, 0x1deea306, 0x3e908a82, 0xbcd89a4f, 0x523eb9aa, 0x9fb0da45,
+       0xbd7d66aa, 0xd82faa6a, 0x83bf701d, 0x8690f1ca, 0xf9eae5f5, 0xc2f96fe1,
+       0xa0f77fa4, 0xa361f711, 0x09f1c999, 0x8fb93d23, 0xb5fc7f01, 0xffcde511,
+       0xc2a2fbe6, 0xf1624061, 0x8b5f00c3, 0x9ff84441, 0xec394916, 0x95c0676f,
+       0x93307831, 0x02f5a76f, 0x9aaf35bf, 0x361f01cb, 0xffcea22b, 0x64628f78,
+       0xcce5c37e, 0x4fbd1e9e, 0xc8133b46, 0xffbd5ac1, 0xe7d54539, 0x10ff72d7,
+       0x129a33d3, 0xa9bedc99, 0xe9077049, 0x2b4d277c, 0x5ff800af, 0xc021699c,
+       0x3d72e76a, 0x746a42f3, 0xfaadc031, 0x76bb4bbe, 0x7c37d011, 0x74be022f,
+       0xc7ecd18a, 0x967fd172, 0x0fb3fe00, 0x7cef8c43, 0xfdc0eb48, 0x9dab6098,
+       0x4f1355c5, 0xefda3ce6, 0x6ee9d5a9, 0xe3533b88, 0x641d4e49, 0x46f5cbfe,
+       0xf3dc096f, 0xfa63ee0d, 0x574687c3, 0xeb23dc36, 0xd011caf2, 0xd744cbbb,
+       0x7b2025d6, 0xaaf6b61d, 0x5a9ff85f, 0xfeae7180, 0x23dfa5ca, 0xfdd3d157,
+       0xbd3d7a2d, 0x61b34493, 0x07ca9b5d, 0xfc742386, 0x6e61d6ce, 0x40cad666,
+       0x93ad4be3, 0xd54d3dd5, 0x7187bc3a, 0xbdf088c8, 0xff91fede, 0xf0fc7ed1,
+       0x684bf06f, 0xef681fed, 0x7a43dbd0, 0xfabed9e6, 0x7e674d5f, 0xeff2b892,
+       0xb093becb, 0xf93fb50f, 0x0825c9eb, 0x37d228d7, 0x3e7a6469, 0xa144779d,
+       0xb46f4fed, 0xdda77f23, 0xf9fdbde1, 0xbe053654, 0xd194b393, 0xf486f55b,
+       0x4837606d, 0x57eac89c, 0x768a186f, 0xfedcb184, 0xea40df3b, 0x133ba015,
+       0xa1390069, 0x696ae4cc, 0x9c63c4d7, 0x5bd267b9, 0xbcb45f40, 0x0dabca1e,
+       0x82fcdeec, 0x8da2b6b6, 0xecc22f30, 0x02cde5c3, 0x78c53881, 0xdad115fb,
+       0x3560a889, 0x80cdbc36, 0x55d83f4a, 0x55df63f2, 0xbf79ee3a, 0x3d26efe5,
+       0xbf2a82dc, 0x7abd31f1, 0x9ff83a70, 0x901c7a54, 0x48cc95e8, 0xe074ae07,
+       0x3e0c67a7, 0xe02c97b4, 0xb82b1bf7, 0x478eaf9e, 0x3be30df9, 0x281fb70a,
+       0x2d70aecc, 0x47daa3fe, 0x0f403b54, 0xf294b3be, 0xf37d119d, 0x0aea421d,
+       0x80f84ed1, 0xd2740dcd, 0xfe70ff83, 0xba53eea6, 0xd8d0f8cc, 0xd10321a5,
+       0x6497b9c8, 0xcd3697cf, 0xa3ffe2b9, 0x826eb8a2, 0xb40c97bc, 0xbe365c81,
+       0xf70a91d2, 0xcebf98dc, 0xdb3c46da, 0x662df7e8, 0xfed02f2a, 0x90b871ee,
+       0x0cc8647f, 0x97928c0f, 0xa2f2d214, 0xfb9436e2, 0x09c4a9a3, 0xc6decefc,
+       0xa762dffa, 0x3b4246ed, 0xdbba77c6, 0xa2dea42b, 0x2afc5f69, 0xe9725fbb,
+       0xdfed1da0, 0x734b1297, 0xbe748f80, 0xa77e476a, 0xba53bbfa, 0x8958d5df,
+       0x1e1db9eb, 0xd5854a45, 0x3d03f715, 0xfb93088b, 0xd86277b1, 0xf46358b9,
+       0xe9ff00e5, 0x9644d778, 0xe08b7ed3, 0xbc54a231, 0xef0257b7, 0x2ebed536,
+       0xca486400, 0x8216772b, 0x5864d91d, 0xf7428f74, 0x34b0c4a7, 0x576d08fa,
+       0x04e6c033, 0x9cc4c293, 0x7de7fd3f, 0x5ed1ff34, 0xaba7de23, 0x266139d8,
+       0xa2fad1d8, 0xa2fbf8ff, 0x7975bf74, 0xbcbabfba, 0xbf9f45bf, 0x814f6cd7,
+       0x36942cfb, 0xd8cf70dd, 0xb73baa64, 0xf4d7ce8d, 0x354dc99a, 0xd9b37211,
+       0xe81980f7, 0x071e8c5d, 0x3a729978, 0xe17c8046, 0xc044fd6f, 0x559250f7,
+       0x072f80ff, 0x9992e7e8, 0xf3efb3c1, 0x9eec289b, 0x6967551d, 0xc36d94da,
+       0x597a68fd, 0x6f8c0908, 0x045d194f, 0xf7e130e7, 0x97183c4f, 0x265367e5,
+       0x4cfefc4d, 0x68437ed3, 0xded79c19, 0x5c27bc72, 0x856bcf4b, 0xb87177e6,
+       0x8b47d557, 0x53445ee0, 0x3061a4d2, 0xc90be92f, 0x0abbfb0b, 0x17c8d13a,
+       0x3fe2cdcb, 0x115a3f76, 0x2d89efe2, 0x7b873a07, 0xf8e9e39b, 0x0cf8bee3,
+       0xe8532ee3, 0xc9cfc030, 0xee376656, 0xfda21652, 0x43ae6fda, 0x44b8d5bf,
+       0x60b5d709, 0xa0242d80, 0x9f20991d, 0x3932260c, 0xcb41611a, 0xffb986cf,
+       0x0b4e0e3a, 0x9ab930b6, 0xbbe033ec, 0xc1400b31, 0xd5fbb902, 0x700f18a9,
+       0xc9a7f376, 0x5b6e01e3, 0xbb0270ef, 0xccbdf5a2, 0x8369e78f, 0xada4bbf7,
+       0xbd0172df, 0x6262db1f, 0x765448f3, 0xfb8f7ec1, 0x837280c2, 0xc81f1224,
+       0x67b24d0d, 0x6b91d018, 0x8012cef3, 0x59a9d9eb, 0x517fd622, 0x37184e20,
+       0x7c1a4971, 0x5e48205f, 0xfdfa3f46, 0xa26bf753, 0x05c99939, 0x7f782b86,
+       0x4db4d8fa, 0x3e3dcf18, 0xc6f7f367, 0x8d3b7f42, 0xd2846f78, 0x3e703dc7,
+       0xc0f5d0d4, 0xbcb66a7c, 0xb38cc693, 0x628a4484, 0xa3fcdbef, 0xaab26074,
+       0x07975c78, 0xf2c16c7c, 0x3bed3cba, 0x78f03d1e, 0x1b9ba533, 0x166078a9,
+       0xaf2097c8, 0x35ea4ff7, 0x1e5e293e, 0xc54af555, 0x6d3b3c4d, 0x08f3d768,
+       0x329d3f94, 0x4e47c84b, 0x27ac6599, 0xf3616dfd, 0x3f105cef, 0xd02dfbeb,
+       0x60f10e5f, 0xea2b853c, 0x0ee2a62c, 0x69cf0080, 0x9fc599b2, 0xf51f73d1,
+       0x44a9f5a0, 0xffd1aef7, 0x3a51fde5, 0xb2f0077e, 0xc72bddf3, 0xd9b5ae01,
+       0x8f40231d, 0x0cfe5ff0, 0x56b65eed, 0xb9b4f766, 0x0d9e64bd, 0x992a7be8,
+       0x83e3105b, 0xcfe3377e, 0xd1baebf1, 0x63f16462, 0xc7ec5129, 0xd7f4656a,
+       0x4df6f5c4, 0xf7a82c4b, 0x99094a6d, 0x955fd261, 0x573f54ce, 0x2a63b705,
+       0x7b415e3b, 0x4e09090e, 0x2e296bf0, 0xe55d2746, 0x3fcf11b3, 0x882831da,
+       0xd1e3bdf9, 0xf1db65af, 0x8040c35c, 0x83f30b53, 0x0eeddcd9, 0x3b47df58,
+       0x7d60394e, 0xb80c3be5, 0x27d0f2ee, 0x620af369, 0xf049bd74, 0xfaf3c15d,
+       0x46b59d0a, 0xc768fb4f, 0x6d7369a7, 0x730a4f4c, 0x706f417b, 0x2f1952f9,
+       0xc65c2858, 0x751d9839, 0xf7c453dc, 0x386de232, 0x4f6f6b5b, 0x6af3b0b5,
+       0x0dc9859c, 0x7ad0d6e3, 0x7c618788, 0x1ebe29cf, 0x57a32079, 0xf8fc6d3b,
+       0xb4441be7, 0x26ac56a3, 0xff3d6768, 0xf46c81fc, 0x903cee6b, 0x5f53473d,
+       0x6f8c3f8d, 0xf1616d9f, 0xa7f1a41f, 0xe20d251e, 0x7378d83d, 0x2007cabc,
+       0x3b86909f, 0x1e38fa3c, 0xbd4d130a, 0xa7c40dae, 0xefd58a0c, 0x01dcff2a,
+       0x5a736a71, 0xb413110d, 0xa70678f7, 0xebcbbc80, 0x2f77f7c7, 0x45a123c7,
+       0x5ac93d40, 0xfa3e4510, 0x1134f9b5, 0x4d3e5a6c, 0xe324f7f7, 0xf0e3d1d3,
+       0x19d813ee, 0x6b933ce1, 0xf5c8126d, 0x5e182b69, 0xa2207f45, 0xc435ddfc,
+       0xf9522f52, 0xb0cace45, 0xb14aff01, 0x01acb8b0, 0xbf58f959, 0x1a679efb,
+       0x4999e7bb, 0x8a7e30ea, 0x1f51db38, 0x38863fee, 0x580d0e41, 0x41911c98,
+       0x830c1bdc, 0x7a3c9820, 0xf10151ea, 0x8e7c03c4, 0xa9ea0a88, 0x3f185f14,
+       0xfa33e477, 0xf952f0e6, 0xa02ad0a8, 0x92db371c, 0x862bf5c8, 0xa3c2d757,
+       0x3c62ffd9, 0x778ea05a, 0x12e478bd, 0x5be1f5c8, 0x1fc2761f, 0x845fb828,
+       0xf0a771fb, 0x3628a67e, 0xb880af7c, 0xf1dd1d8d, 0xcd9fb464, 0xfd04de54,
+       0xf62bb541, 0x62ea515b, 0x76b6e07e, 0xdface790, 0x7c5cf052, 0x05cb6c5c,
+       0xcede3a79, 0x11367748, 0x533801ce, 0x1f94bd61, 0x5797fb30, 0x9d71fbc6,
+       0xe21b8f01, 0x44880607, 0xcfdf3e02, 0x35ef8b90, 0xdd380bf6, 0x59dc182b,
+       0xbb1e631c, 0xb12b5c0f, 0x075942fb, 0x1772c912, 0x5f4cc7c8, 0xcb8eface,
+       0x78b52e0d, 0x225346ff, 0x7ea987b3, 0x69ecbef7, 0x9f4f41a4, 0xcbad5daa,
+       0x537e174e, 0x0659ce0c, 0x85049f3e, 0x41ee4fdf, 0x35c00ae7, 0xff510c6d,
+       0x4b3e4036, 0x14fe37cd, 0xae957bcf, 0xbd9d7b55, 0x736b9bc0, 0x7abb9213,
+       0x8be031dd, 0xb8e7efd7, 0xfdd5e57f, 0x025dff1c, 0x9e7a0e7e, 0xb4c39776,
+       0xe6ab39e9, 0xae12203d, 0x21cac7b2, 0x11695ece, 0x2575fb78, 0xde5c4877,
+       0x3ee7f1c2, 0x3caaef06, 0xf1ba266d, 0xe293f3b4, 0x629087fa, 0xdfad4b9b,
+       0x5bfa1138, 0x83e79237, 0x5f83d41f, 0xbea369e7, 0x6f29043f, 0x029a990f,
+       0xc9f07fd6, 0x1a9fc741, 0xe1ef3b1c, 0xa97807fc, 0xf7aafee7, 0x44de34a6,
+       0x3f3ab2c7, 0xf50778c5, 0xf4a7f6fc, 0x24e22f7e, 0xff5fe3e7, 0x761e841d,
+       0x261693ca, 0xc90096df, 0xf9003d51, 0x17a97fb2, 0x9ca825e3, 0xb7cc21f1,
+       0x338eddf3, 0xe7796847, 0xf78fcfb4, 0x7d6e3c03, 0x31e83678, 0xfa03b7e0,
+       0x501b37f1, 0x055a55ce, 0x462d6f86, 0x7f1517a4, 0x7f1c9d2a, 0x7f788312,
+       0x3090e9b0, 0x5445ec1a, 0x9bbecd3f, 0xd5b165ee, 0x31c70173, 0x533fdfea,
+       0xeccad953, 0xe2fcfe56, 0xffd0798d, 0xf9c0810e, 0xc3ff26bf, 0xbfa8b9b4,
+       0x4f36907c, 0x65a2aed3, 0x691f8b1d, 0x470af636, 0xfa606ad9, 0x1e7dc1dc,
+       0x43e70be0, 0xca4b1618, 0x906ad0a5, 0x45cbcb57, 0x8546efd4, 0xbe43ef4a,
+       0x2026533d, 0x5c587787, 0xd3cd1e6c, 0xe42f1083, 0xbf81ffa7, 0x7e77936a,
+       0x3347ca29, 0xd5c41b15, 0xce2fcf9e, 0x5795fb44, 0x061c0276, 0x926537bc,
+       0x149ef80b, 0xadb4b8c6, 0x2091b6b5, 0x83efadd7, 0x63693ecf, 0x782f5cfb,
+       0x7e67df83, 0x5bb5a271, 0xf930b4e5, 0xe4cac32e, 0x867bf541, 0xb79dc995,
+       0x0026db05, 0xda961c3a, 0xfaf720ad, 0xd013e789, 0xe6d7894b, 0x0f7089da,
+       0x129ddea3, 0x4d3da170, 0xfc7f6949, 0x4dbf2826, 0x223b38c2, 0xe3033fb5,
+       0x894eae76, 0xfc850bdd, 0x6f680523, 0x1beacc7b, 0x14e3a562, 0xf3b27971,
+       0x10859de0, 0xe1ce38d7, 0xe824c9fa, 0xed0973e7, 0x8a9ee33a, 0xf8004db6,
+       0xd9903e7d, 0x08e895b9, 0x9376b9ed, 0x9e93ad95, 0x92ef286f, 0xfbf237c3,
+       0x1d9eb40a, 0x5a16f1ba, 0xb8de4153, 0xfd18f458, 0x24694c6c, 0x7d549f80,
+       0x9282bb40, 0x872025e2, 0x4a96084c, 0x271cb718, 0x71e04c87, 0xf4a4881d,
+       0xfbc7317b, 0xe1777421, 0x558a2dfd, 0xc7265ff5, 0xaeb792e4, 0xa3e090cc,
+       0x8a88af2a, 0x1399ed0f, 0xc6085a67, 0x1e8cafd3, 0x9e2ec117, 0x0a7af942,
+       0xf160cbde, 0xb32ff9a2, 0x466120fb, 0x3ffeddb7, 0xa8fd1da9, 0x7e56ad93,
+       0xfc33d7ae, 0xb7186d21, 0xb0900940, 0xd6cf68fd, 0xfd5057de, 0xf27f6a86,
+       0xad8f6672, 0x7c17f6e1, 0xdf9696f9, 0xb2ed556d, 0x467e75cb, 0xf0bedc75,
+       0xc6aac2ab, 0x804b4453, 0xd507a31e, 0x4a4f8a78, 0x8cfa2f00, 0x5778e0a7,
+       0x78f572db, 0xd195bf0a, 0x4f1d37c9, 0x913588f1, 0x11f44bc5, 0x471f114f,
+       0x911999d1, 0xda4b5ed0, 0x7d04eeb7, 0x7e84c5bc, 0x6f2d29db, 0xcbce11fe,
+       0x43090a29, 0x5cbc56dc, 0x5f4d35e1, 0x75def80e, 0xc056cce1, 0xef7775c3,
+       0xb03f3377, 0xd7885e5e, 0x7cabb60f, 0x1b73cb97, 0x1fa7d7ad, 0x29bef5a8,
+       0xcbe54eb9, 0x5187ae7e, 0xb9c072fa, 0x23d383b3, 0xd1c41250, 0xdd6dcbc5,
+       0x1c9c7ef2, 0xd19eff11, 0x9d6f69a4, 0x61a47bc1, 0xa87100b3, 0xde0919af,
+       0x63ee0dd3, 0x85b56dfa, 0xc3ea93f1, 0x2ca9fdec, 0xe3ed1793, 0xf22315e4,
+       0xf9e57f0d, 0xfd114497, 0xdc00af04, 0x27e5a653, 0x5faefd40, 0xd50e901b,
+       0x85b690f7, 0x2a74fc98, 0x94c88c5f, 0x79c1b7ce, 0xa13ce30c, 0x3d741bf7,
+       0x31f18fd9, 0x5ae837ee, 0x9706fccd, 0x6033e3cc, 0x330ecaf3, 0xb7197ffb,
+       0xf14aafff, 0xae8332fd, 0xc64ff16b, 0x1e75dda3, 0xd65a61f1, 0xc71bb7a0,
+       0xbfccbdec, 0x78af0554, 0xcc05fbb3, 0x8fb1a7df, 0xae523bc1, 0xce18a906,
+       0x5ce25ca5, 0x15d97c0e, 0x16fdd0a4, 0xbbf9eb4d, 0x802882c3, 0x4ead213c,
+       0xac7ec0b1, 0x012717aa, 0x45eb05bd, 0x5bb88f7c, 0xd7e7e00e, 0x29ffce25,
+       0x8e3042c8, 0x77f3d69a, 0x96fed57b, 0xa9023111, 0x9574b028, 0xdbd49a53,
+       0x57f6a8b9, 0xc653ac6f, 0x4034be83, 0x25ecbb44, 0xe01333d9, 0x8f29297a,
+       0xbd645c40, 0x1261aebd, 0xbf1c472b, 0xb17a8e64, 0x1312dbfc, 0x092b88d8,
+       0xfcdbd9f8, 0xdb878edc, 0x3838c6bc, 0xe3f3d9c6, 0x88cb3ee3, 0xa0e6686f,
+       0x6f92719e, 0x69733e73, 0xbfbf2e4d, 0xaeaee0c0, 0x067f597f, 0x4b007137,
+       0x9e280e07, 0x303ffb09, 0xa04d8651, 0xd223b329, 0x07fce095, 0xef053b7e,
+       0xb7cfc513, 0xc023841e, 0xbdecd5ab, 0xff3aaf8f, 0xddff79f8, 0xcce9c69a,
+       0x5f780193, 0x3df194e6, 0x17d96baf, 0x705cb972, 0xd6a1fe2d, 0x07f806fb,
+       0x1b578bd3, 0x13adbc78, 0x97bc08f9, 0x04a77f08, 0x9e08aef7, 0x79d5a1df,
+       0x06d5aeb0, 0xc27e1f7c, 0xef9e1b74, 0xfbd987b5, 0xdb4b3576, 0xad9ce1b3,
+       0xf7c76e2d, 0x0de1e36b, 0xfe5495b3, 0x49cdeb43, 0x1c6ef821, 0x79fbd069,
+       0x3cb3fa7a, 0xd3e03645, 0x37aec8c6, 0x654338e9, 0xd7c858df, 0x02ee8d2e,
+       0x91e3b579, 0x5e404af7, 0xd26f539b, 0x2792a7c5, 0xd2227ef4, 0x65768490,
+       0x5effa4d2, 0x5dae39be, 0x2351bf0f, 0xd97ae3e2, 0x7be80c37, 0xd3f9839c,
+       0xef88a549, 0x01db75fc, 0xe1ce1a9e, 0xeed3cee7, 0xee7d03ef, 0xef67ad2f,
+       0xf77aef59, 0x2fec02f7, 0xbe6ad7dd, 0x7df617bf, 0xb7f60f2b, 0xf2b7cf63,
+       0x1bd77f60, 0x3f403d1b, 0x0f9f153b, 0xefa73cfc, 0xa39ca2f0, 0x0b5c45c6,
+       0x275d172f, 0xe6fa2e5e, 0xe7aaf2f0, 0xcaa6c05a, 0x5ced5f49, 0x9ead3f83,
+       0x218af87d, 0x34bf4668, 0x3d98ffc3, 0xf077fcec, 0x0a2cb95c, 0xabe8f7e0,
+       0xae5c51bf, 0x104850cc, 0xc54513ec, 0xe8aed8ed, 0xdc809173, 0xf179caa4,
+       0x9f09f870, 0x4f36f3ff, 0x5f879c02, 0xce5aeed7, 0x4fa128eb, 0x43b9fc99,
+       0x6bbb3370, 0x1dd5c598, 0x9d82752a, 0xd9885cf5, 0xb1f76b5d, 0x422bea77,
+       0x5df0446f, 0x09c156f3, 0x8ec541fa, 0xeef01c0f, 0xae4e2690, 0x448ce819,
+       0x9deceff5, 0x40729d0b, 0xb79d1bbc, 0x6b78e415, 0x7a06544a, 0xf1172da8,
+       0x295ab3dd, 0xb5bcf18a, 0x241dc429, 0xf5ea5f20, 0x6c2e352d, 0xba465793,
+       0xdecad4d9, 0x7d934ca1, 0x0f11fdb9, 0x6dfbe3fb, 0xb7edfd2a, 0xf800fe79,
+       0x7ad3f31b, 0x8b576c5a, 0xc32ff91b, 0x617fe636, 0xccd97fe5, 0x6e3502e4,
+       0xce8ff544, 0xf3eef1e7, 0xf83bbc79, 0xf81a236d, 0x9b56df82, 0xd5b6fd57,
+       0x88322f10, 0xe5b56df9, 0x8d687edd, 0xae5b56df, 0xe889178d, 0x93234df8,
+       0x310b0d77, 0x25d2864e, 0x579163c6, 0x88ced505, 0x74a7e9f4, 0x0c6464b0,
+       0xf0fdd57f, 0x12b87f97, 0x3cfcf3e2, 0xf01ab2ee, 0x61c60477, 0x5fc04c46,
+       0x355f14c3, 0x4b6a2efc, 0x7d7374e4, 0x37e8c8f6, 0xedf1df4c, 0xe3c7573f,
+       0xb3aead74, 0x02ad5d7b, 0x75b8c3a3, 0xf189ebc5, 0xcf5569f6, 0x4bdf16bb,
+       0xdf1f5fb6, 0xabfdeb53, 0xfdb65ef9, 0xbef7c39f, 0x47fffb29, 0x3034c6ae,
+       0xe87b3e05, 0xd083df87, 0xad8312a4, 0x4c9477fb, 0xae3fe1d7, 0x437062d9,
+       0x21cd4ddc, 0xaaf21bbb, 0x7fde323f, 0x94f64958, 0xfde3c800, 0x5710d588,
+       0xfedae831, 0xb77b62c4, 0xfb573d5f, 0xb151785e, 0x61bf5f9e, 0xa7d934fb,
+       0x02e2d3c1, 0x82f7e02a, 0x24148ab7, 0xa9f638da, 0x7eb7e676, 0x9fefbf83,
+       0x88069321, 0x6eda7893, 0x14467bc5, 0xa62e306b, 0x6e9dead8, 0x9afc0d1f,
+       0x83d9efc1, 0x0b8812f7, 0xc618d67e, 0x1ac13efb, 0x5727de1b, 0xff6a23ed,
+       0xa97ea96f, 0xcd73e06b, 0xcd73e275, 0xf1cf8c37, 0xe3ab17ed, 0x61dfaf5d,
+       0x06918503, 0xb3f1e3df, 0xf17d76af, 0xef765581, 0x91d23b72, 0x5eb9ef07,
+       0x11e8ff2f, 0xf1b92987, 0x4dc41d5e, 0xfc559c42, 0x74f7a87e, 0x6b70b954,
+       0x97a1fb9f, 0xc57eb707, 0x3c96b8fd, 0x0de2a4f8, 0x8f4f7ac1, 0x3e81e4f7,
+       0xeccecabb, 0x0ccd9b2e, 0x0c0b372f, 0x13e07b1f, 0xe2a3efbf, 0xf5fb01d5,
+       0x7ad43bd9, 0x78fe6aff, 0x2d7c2ed4, 0x69fc077b, 0x886c90f1, 0x7d767be2,
+       0xfe9ec7f2, 0x5977162e, 0x517a86dc, 0xef8090f4, 0xf6f3ab33, 0xd63b31b7,
+       0xd45c39ef, 0x1cb8fbef, 0xfcf0e398, 0xf10a9ec1, 0x8f028a49, 0x59028c3b,
+       0x2f28e40e, 0x0da9378b, 0xda8fb8b3, 0x70e304a5, 0xb511fbd4, 0xc809532d,
+       0xbecd0b6d, 0x55fb433f, 0x8682d9ef, 0x4fa3b004, 0x75a72023, 0x37f2cbbe,
+       0x401f7d9b, 0x3b697fb9, 0xa69bfdda, 0xa138c79d, 0x5d3f2fa2, 0x3a5df609,
+       0xa40bb45f, 0xd3f7f498, 0xc7c60e1d, 0x50ead4d4, 0x7b41ebe1, 0xfb950778,
+       0xa7f2de40, 0x5f609c78, 0x56cded50, 0xe1da1b57, 0x6732f76b, 0xad81915f,
+       0x9fda3c87, 0x8ef6d1f9, 0xe415fc2f, 0x9042e6c3, 0xb7de8b57, 0xe3a8fda1,
+       0x138c2c91, 0xbbeacc78, 0x1f6af80c, 0xe40bba15, 0x0e3a1ccb, 0x7b1dadc8,
+       0x79842aee, 0xe0a17d77, 0xccecbaba, 0x24f5d0bf, 0xcaf88999, 0x665dd1ed,
+       0x9f022786, 0x666ad76f, 0xba1e0a9f, 0xdd03bf91, 0x38368f6d, 0xd1ecc746,
+       0xa5407cf1, 0x08fbeeff, 0x1ff414b3, 0xbd61fcab, 0xeaa39d91, 0xeece77f9,
+       0x3c16f1e2, 0x2a75aeae, 0x79e0d78b, 0xf8554f1b, 0xe3bb6f3e, 0x9cf3ac1c,
+       0xdec7fa5d, 0xe24cbec3, 0x2fd8e7fd, 0xe36939c4, 0xdfe0add5, 0x53897b01,
+       0x37b2bc46, 0xa1dfe610, 0xf9f20578, 0x09b6d16d, 0x839d7409, 0x01b7229b,
+       0x165f0fbc, 0x53a0bbd9, 0x92f78b7f, 0xde360413, 0x57da27a0, 0x8afb050f,
+       0xc36fedf3, 0x9d1abad6, 0x5b92e0c5, 0x870ef668, 0xd52241b8, 0xc578c3e5,
+       0x3c5918ef, 0xda2b21df, 0xabb29a09, 0xbb691273, 0x684cf7ce, 0x03e789af,
+       0xcb241a6a, 0x606f8e31, 0x0ed01fcb, 0xe82bdf6f, 0x93a6a6e0, 0xf7e6361c,
+       0x6095b609, 0x296dc9ac, 0x0e6e77ec, 0x7f041fbd, 0x5f1ab4bd, 0x46f52486,
+       0x7572088f, 0x7b411970, 0xa72690e4, 0xc395fb08, 0x0eba44e3, 0x1f08cfff,
+       0xddaa9f9e, 0x64a9843d, 0x7a095f6c, 0xfdacb495, 0xc7ec20f6, 0xb6b144de,
+       0xd68bfa00, 0x12b27c32, 0x5a739f38, 0x95bf2d06, 0x9c1a73e6, 0x7aea3fe8,
+       0x0de30ab5, 0x439d7483, 0xa167597a, 0xdce5c583, 0xa520e3c8, 0xfc115643,
+       0xb85ad2d2, 0x5341440d, 0xd29671ef, 0x129c43f6, 0xc38e7de2, 0xd4f00b37,
+       0x5902f9ca, 0x9c7f4162, 0x6d78625d, 0x8bdef25f, 0x55bfcf10, 0x1d4fef66,
+       0x34e37c3d, 0x96addfb4, 0xc6ab5ed0, 0x74e02e51, 0x47de13dc, 0xe0725e31,
+       0xbf303fa1, 0xfa0b1d0d, 0x3f0c8c97, 0xf829d5a4, 0xc87fe07e, 0xfd0b8c3e,
+       0x80c47d76, 0xe9e728fe, 0xaeb92667, 0xebc4b7ad, 0x891ccb29, 0x622e295f,
+       0x3d9be399, 0x3fdbe24f, 0x55f78eae, 0xd7a210f5, 0x63e87acf, 0x5c7572f1,
+       0x0ee4befb, 0xf542ee35, 0x504f1177, 0xcc526f17, 0xbe8a21c7, 0xef0b6abf,
+       0x50a3c78f, 0xf205c439, 0xd70ada4e, 0x8ebf8832, 0xdfa098fe, 0x09978d46,
+       0x9738b316, 0xbde0a8a0, 0x88d20cab, 0x48fd3271, 0x1ed01044, 0xd3b6e2c6,
+       0xb6865e21, 0x8818ef5b, 0xee216ffd, 0x41f20306, 0xa4abbe17, 0xfdd055c6,
+       0xd3243a41, 0xc13f1e64, 0x566b37f0, 0x70e2085a, 0x9f7edcfd, 0x7f1f2b35,
+       0x3f135567, 0x33feecc1, 0x7d4f882d, 0x10aa53de, 0xd6253df9, 0x1710d36f,
+       0x4d7ff3de, 0x693e6bb5, 0xe2e3ed67, 0xaa38542c, 0xfc2a1671, 0xf14c7bd4,
+       0x79314c70, 0x57bc02df, 0x7dd425e3, 0x0d8fdeee, 0x55d82ecc, 0x1cbbe221,
+       0x155d7f6a, 0xdc83679f, 0x626adc50, 0xefd712f8, 0xaefbeea6, 0x67c63321,
+       0x96bd7df3, 0xdfbeaa1c, 0x23bf9475, 0xd7bf8c75, 0xc21665de, 0x399f8006,
+       0xc9381b3a, 0xee4784f6, 0x5d817b84, 0xdc3668f6, 0x78dcdc2b, 0xa7cc24ff,
+       0xfe424f46, 0xc3ff84b5, 0x5ba243f2, 0x89e19ee1, 0x1e58b3a7, 0x908b2e70,
+       0x49848e33, 0xe07f82c1, 0xe3d73a5c, 0x022e1a77, 0xfb486b1c, 0xd3b436ca,
+       0x146973f0, 0xa26463e3, 0x44ecc429, 0x13ffdc2e, 0x631dec99, 0xbdc0fe5b,
+       0xdfde506d, 0x5a2df684, 0x627bf88e, 0xee5678c8, 0xfa4dfb62, 0x029c59db,
+       0x13d33dff, 0x1fd1e3b9, 0x4df8035e, 0x462b85e5, 0xc740989f, 0xe1b420bf,
+       0xee27593b, 0xe00161f8, 0x8ffd85eb, 0xe2b9060e, 0x77f7b94e, 0x72731ee1,
+       0x7ec8c239, 0xa34de5f7, 0xf9409acf, 0xb3ad1fc3, 0xff69124b, 0xcbc79333,
+       0xe0ef3089, 0x51eef8f3, 0xc4bfdf2a, 0x4bee4c19, 0x2015e89c, 0x3363f17e,
+       0x1f54b3a3, 0xe2063dfb, 0x3ddc219b, 0x12d7235c, 0xc4113bf6, 0x7b804ae7,
+       0x68eff108, 0x6b5e12dc, 0xf7f73900, 0x780ce881, 0xfefd5552, 0x38f7a107,
+       0xc604828b, 0x5c19a6c7, 0x141f01c3, 0x29cdf1b1, 0x2bc6c4b7, 0xfbf17048,
+       0x70a375c5, 0x51ba86dc, 0x28f4c7a0, 0xd072d1b7, 0xe5a09e93, 0x97297bc3,
+       0xd67afb78, 0x938ef35e, 0xa974e01b, 0x2fbc03f4, 0x04eb38b4, 0xc27647be,
+       0x0ef03c48, 0xfb93304e, 0x0739e8f5, 0x273c7dfb, 0x3b4fc591, 0x40704c37,
+       0xffdb107e, 0xfd0848bb, 0xb06653bc, 0x21df597b, 0xb4edf56d, 0xfa199dde,
+       0xcbb963df, 0x277fcfa5, 0xc29f9f5f, 0xebbe07e3, 0x1eff7fd6, 0x0f804a89,
+       0xffa31fdf, 0x441797dd, 0x0be0094f, 0x2f8c27e5, 0x2aee3c0a, 0xf9c20845,
+       0x2c81e37e, 0xc61a9ef5, 0xf5c0bdb3, 0x7fbf3f11, 0x91aa6701, 0x8586e3ae,
+       0x1bdc9dec, 0x93928833, 0xf92bfc04, 0xf07bbe08, 0xa729f711, 0xf4789bc0,
+       0xd713a97b, 0xf419e2af, 0x1f7c3b75, 0xe2e0cf9d, 0xd2538321, 0x418eefd8,
+       0x6b2309d9, 0x84b1fc1b, 0x7d684e7c, 0x3e2c6ff3, 0xf184bc62, 0xd7ab0277,
+       0x4ff86665, 0xfefc524f, 0xe21ede53, 0x27c89caa, 0x4abfdc2d, 0x8be85df0,
+       0x78d8d2a3, 0xfa8b0f1c, 0x5bc01629, 0x7cbb5df5, 0x1bf6e127, 0x7069a64a,
+       0xe794103e, 0xfd54bc54, 0x3c380348, 0x7f327e28, 0x1f872671, 0x06f7f091,
+       0xcfda8932, 0xadc61374, 0x04bafcf1, 0xde2a6f46, 0xb5ec7fae, 0x5f00a737,
+       0xc03f5c12, 0x3bb2ee7e, 0x74f9bd61, 0x804999ac, 0x78d829bf, 0xf449e707,
+       0x247927bb, 0x8c5d8798, 0xb09a1b18, 0xbf7f307c, 0x4fa4fa6c, 0xfe1a4866,
+       0x61adfb45, 0xfdf55afd, 0x459ba3c2, 0x68337e9a, 0x7e9a49bf, 0xf2c2689f,
+       0xbfe5fbbe, 0xe7e92147, 0xaf8fb6a7, 0xf3f5ea4f, 0x7c7dabec, 0x14f7f53d,
+       0x4df87326, 0xf329e356, 0x640f71f5, 0x7e615b8c, 0xc39c7d6c, 0x8edf1c9b,
+       0x306dff5b, 0x09250be8, 0x2844a70f, 0x1a524c3d, 0xf408dbeb, 0xd0fa461b,
+       0x802ff5d0, 0x7e652e2e, 0xb6fbbf80, 0xd989e078, 0x97a519d0, 0x7ba309dd,
+       0xe7c547ce, 0x3c5179ee, 0xf1543c06, 0xdd9e7e38, 0x30bdfc78, 0xa16d7206,
+       0xaaa407f2, 0x9d48423c, 0x0d70eb80, 0x2283ad88, 0x87528961, 0x22b37ff3,
+       0x33bdf388, 0xff8c19f1, 0x3be49319, 0x799af302, 0x3dec27d3, 0xa1d28c93,
+       0xf9d10720, 0xfd484d1e, 0x355f377f, 0xe1dc796e, 0xbd82373b, 0xe3ee9bb4,
+       0x5fed5ce8, 0xf234d395, 0x2af73b15, 0xf2be5545, 0x19642900, 0xe57cb832,
+       0xacd678c2, 0xf10dcb80, 0x8af91aaa, 0x44d547c9, 0xeece07bd, 0xa060fced,
+       0x987abe5e, 0xb76ebc60, 0x271a557c, 0xede3cd5f, 0xc42092a7, 0x93d936c5,
+       0x805e2c42, 0x162d39ce, 0x8db4dbff, 0xb74d8dc9, 0x82419cb8, 0x33d31672,
+       0xe87bf166, 0x6bde4cb9, 0x77c98fba, 0xbaea1ce3, 0x6b78fa2c, 0x133567ee,
+       0xb8b12f2a, 0x99abb40c, 0xa5d97d9d, 0xb53576f4, 0xf202ffde, 0x007f0832,
+       0x00007f08, 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9,
+       0x64cacb67, 0x109848df, 0x424e3b08, 0x875b3612, 0xe22948b0, 0x3cb888b0,
+       0x4240b21c, 0x3eb44196, 0xc33fedad, 0x0d220222, 0xc168d46d, 0x2a14180e,
+       0x0431a0d8, 0xa4587049, 0x141a87d0, 0x2f1f682d, 0x48145840, 0xad88a0c6,
+       0xbefbffcb, 0xef726e73, 0xf6b42264, 0xfa7fb6ff, 0xef7397b3, 0x6df3be59,
+       0x39ce5be7, 0xd78deec3, 0x1ec658b1, 0xacc630b4, 0x98eb458c, 0xb19436b3,
+       0x96eff0ef, 0x95e5e7ae, 0x6289e63a, 0xa31574ac, 0x47d7e5e7, 0x7a83cfa6,
+       0x4c8c7697, 0x66e783cf, 0x92d433b3, 0x50e158cd, 0x2fa18a7b, 0x7b46f963,
+       0x9b19933a, 0xbeb45e64, 0xcc9eba19, 0xd393f516, 0x5b09fb18, 0xcf074c74,
+       0x48ce9151, 0xc8673fac, 0x287a2967, 0x0379f8b3, 0xfd8c611c, 0xc28f675e,
+       0x19b98cf7, 0x718535c2, 0x4398a6b8, 0xf870f2bd, 0xa5c340f7, 0xfe8c8196,
+       0x1c7183be, 0x4b6f6726, 0x1155630c, 0x67971fb5, 0xa35cf631, 0xe2b6e6c9,
+       0xec1496d7, 0x11deb18f, 0x043086e7, 0x543ce185, 0x39e814f0, 0x4cb2d13c,
+       0x040bf4f0, 0xc65e630f, 0x68e0ba72, 0x94ae8437, 0xb1e0a97a, 0x00d17eb3,
+       0xc7be24a7, 0x06895ab1, 0x6a5383f3, 0x1257e3fc, 0x33d38fd4, 0x63265877,
+       0xea97981b, 0x1ce75efd, 0xb3c6e381, 0xb8e1894a, 0x112b6c2b, 0x96e0dd4f,
+       0xbf30c901, 0x1ec977d9, 0x0ae60c13, 0x7ace1f09, 0xd4fb3d61, 0xba7f1804,
+       0x2af67f18, 0xac0884c7, 0x78e25d37, 0x00ffc2f0, 0xfbe219fe, 0xa9b2c6f4,
+       0x3198e00c, 0x13ba70c1, 0xa66ff83e, 0x0181ba65, 0xc2a6b39c, 0x7bd7737b,
+       0x61d2209c, 0x2cffd28e, 0x6c39bb6d, 0x387267cd, 0x10191696, 0xd5ee735f,
+       0x09669f7e, 0x42173e8b, 0x077c076d, 0x60603af3, 0x79f68f34, 0xe609b3cc,
+       0x82cc56f1, 0x3347f7f5, 0x43b7e036, 0x7fe86533, 0xcd716c62, 0xf4bf283a,
+       0xbf2a60dc, 0x83cf7b15, 0xf3fbf147, 0xa09e54e9, 0x6e504683, 0xb3ce99ff,
+       0x9cd01529, 0x5494d773, 0x9040ff18, 0x467ef7e8, 0x9d83e3ef, 0x5ea1d355,
+       0x99bef0fc, 0x04d3e0cb, 0x0aede323, 0xde9ff7f9, 0x9ce54614, 0x191eacfb,
+       0x6c109cba, 0x30f7d375, 0xaa09b6c9, 0xd130c91e, 0x53e361f7, 0xccbef7f9,
+       0xe7df851e, 0x23fb5185, 0x0b5e2199, 0x47f2f78c, 0x01fbe883, 0x0eb9b3e9,
+       0x595b5120, 0x52e91ea8, 0xe336689e, 0xc940c873, 0x3df0083b, 0x5f8c5221,
+       0x353de7c6, 0xca226b73, 0xdf5c84cd, 0x6850c75c, 0x670e6897, 0xfe1f1137,
+       0x8879f90c, 0x34aadc6d, 0x5f16afe4, 0x150f9a8a, 0xf8574f3a, 0xcf96826f,
+       0xc51e7e40, 0xfa9f0af6, 0x87c2a7f3, 0xea0b3e1a, 0xb97f33e2, 0xd7009e57,
+       0xb18f924a, 0x97721f20, 0xe38e747c, 0xe3fe2727, 0xf8bf24f6, 0xdca2c527,
+       0xc2777f88, 0xd0f24b57, 0xb9e9b99b, 0xcb83e501, 0x8708b3cb, 0xc56cd751,
+       0xdb247df7, 0x33c20b60, 0x0c7666ca, 0x0a372eeb, 0x783ac97c, 0x2e1dd991,
+       0x3943d3fc, 0x45fe7589, 0xb8e0e747, 0xb3b43bfc, 0xb82ec8b3, 0xa4adfc60,
+       0x7870569f, 0xb88b4836, 0xd09763bc, 0x5768b94f, 0x41b7ccae, 0x0678df3b,
+       0x2ffa8778, 0xc4967ec4, 0xfe18dddb, 0x82b87995, 0x4f81ee41, 0x611d9966,
+       0x1dd39846, 0xb724f911, 0xebf73277, 0xb38f8011, 0xc2136706, 0xae643c77,
+       0xed7e1191, 0xf757a146, 0x74285f20, 0xc7f4e052, 0x7a0f794f, 0xfe1e7fcd,
+       0x57a2e978, 0x133e0273, 0x2b2a22d8, 0x79e1bdf3, 0xae5e0ff6, 0x69bdf983,
+       0x147c9df0, 0x6fcdebe4, 0xeb3736cc, 0x20cdf382, 0xbc3d12eb, 0xd992ff77,
+       0xb3e00736, 0x051f8168, 0xb32e772e, 0xcebeb19b, 0x8a9659ec, 0xe06af674,
+       0xcfe88fca, 0x7f174c58, 0x5eeb31c5, 0x2afb3154, 0x3d56b6ec, 0x57a487ad,
+       0xcf50c2d8, 0xab9f6866, 0x99c4e5e7, 0x50a59eb1, 0xdce8f76e, 0x3c6f1806,
+       0x347375e8, 0xefe74fbe, 0x38230b59, 0xc20b3147, 0x90011559, 0xbbaaf7c2,
+       0xd1c03dd2, 0xd95bfeac, 0x7ddf041d, 0x0fa4c1c5, 0xc16032aa, 0x83efc2cb,
+       0x896efbe9, 0xd62ee38f, 0xd355b8d1, 0xeaa8feb9, 0x53b8f16f, 0x54ceb271,
+       0x8daaf7e4, 0xd04884f6, 0x5b328923, 0xa47a0b54, 0xf0ca152a, 0xeec65d8c,
+       0xf4c47d43, 0xc3d3e1f6, 0x78fbf0ba, 0x11deb8d8, 0x84b71fc0, 0x96fe75f3,
+       0x2af9ccb5, 0x29b563d6, 0xd57587d3, 0x00008a8b, 0xd4305eb0, 0x596efe83,
+       0x6286f50d, 0xac2f507f, 0x83763d7b, 0x68a7c476, 0xac608c47, 0x9f11d858,
+       0x8299dd6e, 0x9b27c476, 0xa9e4a677, 0xd8945fea, 0xbfd71c1c, 0xbc656f7d,
+       0x66ec67ca, 0xa0926f18, 0xf98724fb, 0x50eb8494, 0xe77b44fc, 0x1a7c85fa,
+       0x0235bf61, 0xef9061f5, 0xb47ba445, 0xf90e77d1, 0x6261bd8a, 0xa3ae199b,
+       0x1a5d72be, 0xf7876faf, 0x1bc8efe5, 0xdb7e0357, 0xdbfe3862, 0xbe041976,
+       0x2dff9e5b, 0x0c34af94, 0x3c61ab60, 0x0231bc17, 0xd71cbbff, 0x853d702a,
+       0xbfce333f, 0x57112854, 0x55d98983, 0xfc1b60eb, 0xc5d99457, 0xd04ced2f,
+       0xe88421b7, 0x1b372e5b, 0x75caff91, 0x70875d92, 0x59ec1c2c, 0xa7e97526,
+       0xe8af4512, 0x132972d8, 0x262cede9, 0x9827bcbe, 0xfdf0966d, 0x80c5f4e9,
+       0x9af352af, 0xa18f5c66, 0xd70901de, 0xb407a41c, 0x53ed885f, 0xbcb3e3bb,
+       0xad54e00e, 0xb4dba5f7, 0xc6642f70, 0x0784efae, 0xd7cbc937, 0xc414e706,
+       0xb730596b, 0xcd4b2e43, 0xf03f0839, 0xf017b79d, 0x2649afa9, 0xc0c426be,
+       0xbe8a79f8, 0xdc7ce6a9, 0xb3c7d55e, 0x09e7be04, 0xca35e5ba, 0x0b3c135e,
+       0x5a7bbce3, 0x2d4addb0, 0xfbc74b1d, 0x3952ea0e, 0x1ea38e1e, 0x4dc152af,
+       0xa7054e7a, 0xa25cbddc, 0x7d45eef7, 0xc63f3fe0, 0xeba935be, 0x4ab689dd,
+       0xe709f236, 0xf495667b, 0x0797d066, 0x4ca15d05, 0xe62499f3, 0xf5f23466,
+       0x14ef9fdb, 0xd08eaefc, 0x8eba3971, 0xbe412dbc, 0xbcbeb98e, 0xb3fef529,
+       0xdff56de4, 0x06ec6f29, 0x8267c1d7, 0xf8083b98, 0xd8ca5ab3, 0xfab27a8b,
+       0x465b6636, 0x37ebb55f, 0x088673ac, 0xc035fd7c, 0x85987403, 0x9d7906ff,
+       0xad3f7d1d, 0xfc97607b, 0x9cd9f516, 0x776ec201, 0x2424bb70, 0x9b19f38b,
+       0x61fd3cc0, 0x1ca2610a, 0x23d9b932, 0x1eb91f03, 0x006765ce, 0xf8fb311f,
+       0x32f5f2fb, 0xe51375d9, 0xa865d8bf, 0x659431db, 0x5cc80582, 0xd53f4417,
+       0xa633f512, 0x24fee371, 0x6e4c4728, 0x7016464e, 0x6674bc3d, 0x9c0208eb,
+       0xd058b1e8, 0xdfe1f163, 0x67c5bd50, 0x7d827979, 0x57942f60, 0x799921d7,
+       0xa1c761a0, 0x2f2c7a99, 0x28b125d8, 0x104cf718, 0xd501a397, 0xc955663a,
+       0x304f20e3, 0x75f8aab3, 0x4d4896c8, 0xa26d5879, 0x0d4dfea6, 0x33df357d,
+       0xdf3583bc, 0xd4ca1c47, 0xc79bb394, 0x3c8fea68, 0x8f29ab9e, 0xa9a2996e,
+       0x0cc2f63f, 0xbe47f94d, 0x99f535bb, 0x103cdedb, 0xe82050f0, 0x8a0ff8af,
+       0x5ae5bafe, 0x2c3da69e, 0xe8095ec7, 0xb15fc85a, 0xc80b3582, 0x2d07193f,
+       0xc896fdd4, 0x8da20e6b, 0xf5a95856, 0x6b54164f, 0x1b0dc5cb, 0x5609408d,
+       0x2fbed1ec, 0x0f2da2d9, 0x43a79e88, 0x011b3abe, 0xf820c9fe, 0x428b1447,
+       0x2ec9eff9, 0x44efa7f1, 0x00758fe1, 0x7e8098df, 0x33dface9, 0x7d234737,
+       0xdf03cc0d, 0x7e05b03b, 0xf5c1be07, 0x03d0e3a3, 0x8523e43a, 0x3278fede,
+       0x1ee96bc5, 0x3dd2d564, 0xee96a064, 0xdd2d3661, 0xd2d28d7b, 0xa5aec23d,
+       0x2d64d47b, 0x5a1c63dd, 0xd1cdc7ba, 0xa9c13dd2, 0x91527ba5, 0x8bc9ee96,
+       0xf3ef74b4, 0xa9ae96b0, 0xbe5a85ee, 0xc503e3f0, 0xb95b4b4e, 0x8e9eafd8,
+       0xe0fcd4e9, 0x40ca9a28, 0xfcaff4cf, 0x7fffa6b9, 0x45a43f36, 0x92353f0a,
+       0x7e477e45, 0x645fbd86, 0x46ff7776, 0x7f6a6bd1, 0x65d39f42, 0xefa4f67f,
+       0xd3cbd9ba, 0x47a09c78, 0xdc9ad97b, 0xf5272f65, 0x982797cc, 0x4bd689bb,
+       0xf08746b6, 0x70e165dd, 0xa357c15c, 0xd59bbb19, 0x13dfb01a, 0xc0146750,
+       0x03e7027b, 0x9acbdfe3, 0xe65cfde9, 0x5993a7a3, 0x63ccf88c, 0x30167a36,
+       0xe8a73d07, 0x1e22b79c, 0x392dcd4a, 0xceaf6fa8, 0x42527a3b, 0x21448ea0,
+       0x2f23dfd0, 0x4ea75a6e, 0xd999cc57, 0xd6b18fda, 0xb44ce70a, 0x16e33ba7,
+       0x568d6676, 0xbc6f2de1, 0x7a8f5034, 0xa1b60e56, 0xa777943d, 0xde6cf644,
+       0x3739fc97, 0xfe43af92, 0x2b0f65cf, 0xfe14ab78, 0x1e43f707, 0xbb0ab48e,
+       0xc943399e, 0x7059b3be, 0xb8fe805d, 0x9182ff3d, 0x82582eec, 0x2e80d7f5,
+       0x4f4e24db, 0x4dda2ba4, 0x7cccf4c3, 0x9843ca0d, 0x27ccfc93, 0x7892a0f4,
+       0x1fb1833f, 0xa0dbda17, 0x75234a02, 0x8e394e34, 0x3cd4f007, 0xaa20cccb,
+       0xe98126ac, 0x9afb4207, 0xf12ca225, 0xbce1fe32, 0x454cdfc9, 0x4d2b6d78,
+       0x4858af64, 0x4ccd923e, 0xe3dc91c4, 0x493ef0dc, 0xed090d06, 0xbfc01bd6,
+       0x6b942488, 0x2198c3e6, 0xfaf99ce2, 0x934c157e, 0x51f8539d, 0x0a2f7c26,
+       0x1dbfdeb4, 0x9595edc9, 0x40efc715, 0xcdef297a, 0x84b3377a, 0xf7825ea2,
+       0xeb31b92a, 0xb0f11d99, 0x533dc2a2, 0xc8d9ff5d, 0xf1e7ea48, 0x4e2d8bde,
+       0xdf723ef8, 0x720428a2, 0xd9739067, 0x10a1658f, 0xe9458962, 0x069ad46f,
+       0x1ec3fb99, 0x919afd19, 0xd4e7f5c7, 0x2dd1a471, 0x0bd8f2da, 0x0f42b2da,
+       0xc177f376, 0x82650728, 0x00f14caf, 0x195eaa97, 0x67c0f63a, 0x0fdcf165,
+       0x84c1be63, 0x1b90a377, 0x0de49d53, 0xc130f902, 0x0a61925c, 0x9ccc0c2b,
+       0xedeb7480, 0x6e5da0b4, 0xd0ebd44c, 0x2ff2603f, 0xf800ce6c, 0x78a69e53,
+       0x7eb555fd, 0x17ea03f9, 0x48d86bb0, 0xdff11236, 0x41e02f09, 0x1a3a7802,
+       0x46ae36e2, 0xcdcc9c78, 0x613603cb, 0xb3fea7b9, 0x7a59becd, 0x0b6cc110,
+       0xbc3fc67f, 0x447e9674, 0xa3af7af7, 0x64e3075d, 0xd93db8eb, 0x8e5cde9d,
+       0x6bb3e93a, 0x01646c81, 0xb0d553e8, 0x7fd4e3ff, 0x25793e9c, 0x51e22ba9,
+       0x6fc092ee, 0xcd698787, 0xf8009612, 0xc75aac2e, 0x092e3f90, 0x8f325c38,
+       0x24d7b1c3, 0xb5e8a7aa, 0x10022c97, 0x875a1af3, 0x62f04407, 0x0eb72f7a,
+       0x6bd2f2e5, 0x2fae88bd, 0xf1474efe, 0xa3cc41b8, 0x610cf9c3, 0x8c3efa5e,
+       0x26f950b5, 0x67281514, 0xdbf12b30, 0xbb23e608, 0x2b5cf411, 0xd972b9ea,
+       0x2820bbf9, 0xbe764e5f, 0xe84e7a44, 0x4fc174fd, 0xaf7e8ae9, 0xddc7fbd6,
+       0xf8a48d3e, 0xad0b6f4a, 0x54ce4223, 0x3af82674, 0x7f91448e, 0xe768e209,
+       0x544db4e5, 0xc688303e, 0x587c1429, 0x8d88ec98, 0xc5ebd154, 0xf5336b8a,
+       0x7802f92a, 0x5bbf28ec, 0x4d66822a, 0xa397bd50, 0x32071e38, 0xa18fd5df,
+       0x2175f9ff, 0xe047b436, 0xf97ec68d, 0x4729c90f, 0x5b97bc01, 0x9a3af5ac,
+       0xf50ea567, 0x24efd962, 0x33c01cf6, 0x66b97180, 0x7035e2fd, 0x9848a96d,
+       0xf9f40135, 0x0fdc917b, 0x1c7cc971, 0xe28433b6, 0x8cc98531, 0x853f4385,
+       0x7c91a7af, 0x0bd0c40d, 0xcc32b1c2, 0x8c2f7683, 0xdd95151b, 0xf1ff1e1d,
+       0x35df43df, 0xb733f49b, 0x1ef543bf, 0xdd9973f4, 0x7bc7556e, 0x19bb0b56,
+       0xe39213fc, 0x3b9fd160, 0x7aff7197, 0x84fb8f30, 0x296ae6b2, 0x62f5e7ad,
+       0x9a651a20, 0x014c02f5, 0x36ce5718, 0x16ae5c93, 0x47acc472, 0xe18fe8ad,
+       0x3a184673, 0x8f0e9cfd, 0x1cfbb187, 0x24fd7a2a, 0x3f0baf8a, 0x6a78e289,
+       0x077b7337, 0x2a19f5e3, 0x31af387f, 0x251bec9f, 0xec2edfbe, 0x9503f6c9,
+       0x27e8c1b9, 0xbe388a57, 0x058a9fb0, 0xfa682d2b, 0x4ad78e4d, 0x3e91587d,
+       0xfe7de2f9, 0x535dad4a, 0xf649c5b8, 0x24ecf5cf, 0x09c514c0, 0x49a4edfd,
+       0xd96f4251, 0xefc60658, 0x3b49accf, 0x307a8c18, 0x1e305995, 0x9abf249f,
+       0xf11428b1, 0x871cace0, 0x4f543df2, 0x67afeb72, 0x1a87041e, 0xe245b9e9,
+       0xe7f774f4, 0xd92db4f1, 0xb2dcefdc, 0x7f5a63b7, 0x58cbe7e8, 0xdda52f8e,
+       0x6a06b197, 0x38e828f7, 0xd8cb5f7c, 0x6e7e40e4, 0xc977c091, 0x7a8b2096,
+       0x8dab2a7d, 0x0d5d94d0, 0x7af51609, 0x2c28f640, 0x4c146caa, 0x7e2ba721,
+       0x72d0d653, 0x768ac430, 0xca017381, 0xbfc1fb49, 0x3a250f86, 0xff5072f8,
+       0xf9c7183d, 0x02b6e113, 0x9f743b3c, 0xffd355cd, 0x80bd28d1, 0xffa7af9b,
+       0x2d765c30, 0x1e87975c, 0xe1c29d8b, 0xd5c239fa, 0x8b1d3de6, 0x8cb805f4,
+       0xe476b86a, 0x3f9ff8f2, 0xa1fc9e9e, 0x88f564f0, 0x87df35a7, 0xc0c61da7,
+       0x74126cf0, 0x6e80f97b, 0xfac027b2, 0xcfc849b4, 0x1aef0c3f, 0x6b6dfc3f,
+       0x15618d9e, 0xe1137780, 0x9635be2f, 0x7f021672, 0xe04e22b5, 0xc6fa12ce,
+       0xfd03ba06, 0x7a468fba, 0xead40f50, 0x2c54d459, 0x96d814e7, 0x46af3cc0,
+       0x5da0fb38, 0xfe21eae4, 0x7f8091f2, 0x7014a247, 0xef881ffe, 0xf5e48f7b,
+       0x89ff75c1, 0xf28626e3, 0x09ebe0af, 0x1339ad4b, 0xe6fa37fb, 0xf59cb0db,
+       0x1a1ad9b9, 0xef1d7fa0, 0xf27e57ff, 0x3caff4a1, 0xc81a8ddf, 0x01d247e3,
+       0xfb209419, 0x9ac7cdd5, 0x7f9cc3c7, 0x9d27a595, 0x79e30ffa, 0x79fe36b9,
+       0x762c7bd9, 0x778be71a, 0x4b97df51, 0x876fc367, 0xbdf24bb2, 0x97f31433,
+       0xd7cd2746, 0x6d8991f5, 0xbce7600c, 0x9942f821, 0x057f329f, 0x151fb0ee,
+       0xee0091f4, 0x5a2613b0, 0xf5103e0c, 0x97a07595, 0x5e71a3b0, 0xacdc0eb4,
+       0x6ca071e7, 0x57f7d13d, 0x1c50c6a3, 0x27c88768, 0x291b46fa, 0x870fe95e,
+       0xff8f9a21, 0x9bf7b5c4, 0x8d3f62fb, 0x33e78a06, 0x4cfc4b7d, 0xdbd717e0,
+       0x9427877a, 0x8ef266f8, 0x4763a450, 0x753c0b78, 0xa76a06d1, 0x7287bd43,
+       0x8c9e4d71, 0xc8fdae7a, 0xc55916e7, 0xccb472e7, 0xb9ac6be3, 0xbff42c79,
+       0x30599336, 0xd62a1cbe, 0xad23d0df, 0xe87f0845, 0x249b9fa8, 0x4af6fc55,
+       0xadda8994, 0x6d62fa35, 0x09ab9fd0, 0xf78a051c, 0xb1b118b7, 0x85970782,
+       0xeb3ca1e3, 0xe866e800, 0x4760d1a7, 0x2b68e578, 0x7700a7d7, 0x1e0fbc3d,
+       0x1f25b9f4, 0x78c167bf, 0x87dabb7d, 0x833d3859, 0x439e61b3, 0xb3de5f91,
+       0x97b3c014, 0xdf081cc4, 0x3f5cd183, 0xc455702b, 0xfc02fd71, 0xf114321e,
+       0x7ca3ac9a, 0x66fae3ea, 0x96e3dfc2, 0x8c25967e, 0x79c76ef0, 0x299b46f9,
+       0xed1d56ee, 0xf9c6898c, 0x1e1cd818, 0x8c766cf7, 0x32587c27, 0x07002356,
+       0xf0bd9106, 0xc38bc133, 0xb21cf358, 0x168cb20b, 0xf594475c, 0x8ede8bf9,
+       0xcd37685e, 0xd076e68d, 0xd742b7f9, 0xc0abbae0, 0x2c02b677, 0xb957633a,
+       0x8498e6d0, 0x9ccf9978, 0xe78e502b, 0x551e0157, 0xc0de7efc, 0x16bc2dfb,
+       0xaa51bccc, 0x36eea376, 0x6bc2bb62, 0x760bcce1, 0x5e20f9f7, 0x5f187cef,
+       0xf18ac6cf, 0x33fc156f, 0xea07fa33, 0x7c9f9b31, 0x8bf3f86d, 0x8d8f5c79,
+       0x4995bc45, 0x7bb4462d, 0xabf98ed7, 0xb3e9ed11, 0x4de61615, 0x4679beff,
+       0x9c6aaf31, 0xccd77ace, 0x3ca51f34, 0x5b24f917, 0xc250df3d, 0xf88ad9c3,
+       0x4931e0eb, 0xfeaec783, 0xd8f06afb, 0x1a74ffbd, 0xc0c56cff, 0xa43ff4eb,
+       0x1aadfe87, 0xedfabbf8, 0xedb6e347, 0x04297bcb, 0x779f7bf8, 0x31bb73e9,
+       0x64c7bb1e, 0x373ca131, 0x3f22e6d4, 0xbc0edd5e, 0xd0f4fc04, 0xff28af9e,
+       0xa326d0f8, 0x3768c70d, 0x02dae6f8, 0xcc7eefe8, 0xea8dd6e2, 0xa746167a,
+       0xdffd9d11, 0x0b1ef59b, 0x03cd95c6, 0x375c16f5, 0xb3d9accc, 0x4cd7f894,
+       0x3f8944fa, 0x8b4efd28, 0xccfa3592, 0x5fd9f425, 0x9047cef5, 0x5f3aedde,
+       0x89da1e7d, 0xb70f3f03, 0x41117f92, 0x3f12ba76, 0x892383d0, 0x3989ad76,
+       0xde4de618, 0xa3ba758e, 0x82dfbfa1, 0x411c62b8, 0xc4e3561e, 0x2293fb78,
+       0x5064ffee, 0xa54dbc73, 0xeb45d697, 0xb09d987f, 0xb35f8fd2, 0xcbd17c3f,
+       0xc47583d7, 0x2bf372af, 0xb58bbf08, 0xc55c7918, 0x5e67f64a, 0x94e3c1d6,
+       0xacfc520f, 0x05fbfe95, 0xbfd02392, 0xe11de252, 0x9ae2ace8, 0xd68c36bd,
+       0x5e10fceb, 0x28b7ffce, 0x8a819fca, 0x6ac43d26, 0x162f9e65, 0x310e9671,
+       0xdaf37687, 0xda1ff414, 0xa3ab1e45, 0x46e83f71, 0x4fecae78, 0xf37fcf74,
+       0x9f6869d1, 0x79e33e83, 0x5a30a6ab, 0x624df227, 0x9106279c, 0x9123b17f,
+       0x7ab57fdb, 0xcaa6786f, 0x77bc7c1e, 0x685f736e, 0x7f656977, 0x5dcbda1d,
+       0x0efbcdfa, 0x39dae7f6, 0x574df888, 0x39e9e83f, 0xd7489718, 0xdcebb0d9,
+       0x31eaaffa, 0x16b650de, 0xef1801ec, 0xa469e812, 0xc4feae93, 0x705f5c70,
+       0xcb3f5c6c, 0x9fc893ea, 0xd1f10fcc, 0x60b293fe, 0xea05ba5b, 0x4d8fd7e5,
+       0xf33fbe47, 0x5c14a0e4, 0x58c74e0f, 0xdc4f3053, 0x192024fe, 0x69ba79e6,
+       0x6abf7f00, 0x17d470e4, 0x9c436b61, 0xadfc009e, 0x95fcf7e8, 0x14767226,
+       0xcc48ef3a, 0x7c406b68, 0x7e93320c, 0xf6450507, 0xdf21fe53, 0x17786b0c,
+       0x473f159e, 0xa15ac7c1, 0x3ffe954f, 0x79517a16, 0xd299fac2, 0x31ef7082,
+       0x1ccffd11, 0xc38d7bd1, 0xf1b21ed1, 0xd08556f1, 0x0730f978, 0x29cbc80b,
+       0x8e9d8eb1, 0xbc470eb4, 0x2832ebe7, 0xe443ba0f, 0x7c5956e5, 0xe41eb8e1,
+       0x194ad9eb, 0xbe62afea, 0xf8d508f0, 0xd7b28df9, 0xfbddf448, 0x4d5ff90e,
+       0xabe90c61, 0xfc8c337b, 0xa69bd773, 0x018f684d, 0x6821ddfe, 0x91371e17,
+       0xc9afb2df, 0xfb617644, 0xd7f21089, 0x42c3f1fc, 0x3f48297d, 0x44499bd7,
+       0xdf64f6df, 0x0c8edcf3, 0x680f9862, 0x891cea3f, 0xd1694274, 0x9ec3e3c5,
+       0xd5cd7680, 0xda2f20a6, 0x60f4f035, 0x6acdd07c, 0x9efde9e2, 0x347e8610,
+       0xa8643d3c, 0xe0f17549, 0x1082a0b3, 0xfda99bed, 0x01ce2943, 0x4a1f1fa8,
+       0xb143fe83, 0xbbd52b7d, 0x9379d7da, 0x1221c785, 0xd48978c5, 0x5fb7326f,
+       0x8d39f499, 0xef89fd03, 0x65ddf4cd, 0x79a48e72, 0x36c61c7c, 0x61679806,
+       0xa0bcb6a5, 0xf62e5b5a, 0x5b25cb68, 0x745f65b4, 0x814fd114, 0x7f73e15b,
+       0x70c4a4bc, 0x87c142bb, 0xd2769f3f, 0x61f03af3, 0xcbf1013c, 0x571d391a,
+       0x929aba0f, 0x0f2de387, 0x9753e4d6, 0x3e279d34, 0x9fd8376c, 0x77c075c1,
+       0x9136c0d4, 0xd50360fe, 0xf8ffb6fe, 0xe7adf3dd, 0xbcf5be45, 0x26dadf26,
+       0x160c2ef4, 0x5084f18e, 0xe11c359b, 0xad4ba1d8, 0x3d5f22f5, 0xbe7c4419,
+       0x21cbf716, 0x401baddf, 0x054452f0, 0xf0b3cfc6, 0xfd08cff1, 0x54c5e677,
+       0x642d33ca, 0x4b4fa4b5, 0x44bef399, 0x5887e78c, 0x57ff9073, 0xcdfb02d9,
+       0x27baf8fe, 0x34e3d386, 0x7d8ac6b3, 0x6fcc564d, 0x80bfe114, 0x74fd4504,
+       0xdfbe20f6, 0xd175f48f, 0xd481137a, 0xd8ccf7c9, 0xf3ff9655, 0x0d0077cb,
+       0x3655fe11, 0x67ae3877, 0xde7c2c17, 0x91593f60, 0x9f3245be, 0x8875fa07,
+       0x2f120bc7, 0xd942fa2b, 0xdf00b12f, 0x989e7ccb, 0x518f2fa7, 0xc7ae38fc,
+       0xf75e925c, 0xd693e830, 0xf2386b08, 0xb4aaeb53, 0xb79825c8, 0x66c6b088,
+       0x3aecf0aa, 0xd026bcc0, 0x0946d65f, 0xf0ddbf63, 0xf39223b5, 0x085d6fa3,
+       0x8eaf2bad, 0xf6ab996b, 0x8635ff13, 0xc58f91db, 0x16a6ff70, 0x40ec826d,
+       0x5a74e078, 0xcab4e820, 0xf931fce6, 0x16f57e4b, 0xf412f754, 0xb95f7bf3,
+       0x2f295ffb, 0x0fc55eb5, 0x8a4edeb0, 0x385de3e5, 0x374b7464, 0xfb4a5f91,
+       0x82eb7c9a, 0x70bf6ec8, 0xae3a4a68, 0x82eb4543, 0x155f5122, 0x8b135e1d,
+       0x8db8c8f6, 0x3ae2c58f, 0x6269b055, 0x9fe2533a, 0x482a3e2a, 0x3da3a7b1,
+       0xb6567be4, 0xd5453f60, 0x4ab5c132, 0x167e695f, 0x36ab9fde, 0x24549d90,
+       0xdbd73ae0, 0x2f788e19, 0x11bd33d2, 0xef4e7ef0, 0xf03b270c, 0x2ffc9959,
+       0xbd40f9ff, 0x00ccfa63, 0xfa0b3278, 0x00b48be2, 0x47547bfc, 0x66082a74,
+       0x36e75724, 0xb9edfcf2, 0x587de764, 0x157f056e, 0xaaad77f7, 0x0eb70e2c,
+       0x73f78eed, 0xddf12766, 0x051f3102, 0x28e3feaf, 0xbc476d78, 0xe871fda2,
+       0x2768c9b9, 0x91929eb8, 0xc6ded933, 0x8e47e42b, 0x72789a6b, 0x075fbe2c,
+       0xd7158076, 0xdcefbec7, 0x4ad4eb83, 0x909da199, 0xcb1694d7, 0x57d76a86,
+       0xdef22fb4, 0xa3ae159e, 0x90d31df7, 0x6d5b4e9f, 0xfb2a99b1, 0xcfc11dee,
+       0x5fc974fe, 0xec70b7f7, 0x818d68af, 0xdff057e0, 0xfd93630e, 0x41e21953,
+       0xedef6f3e, 0x7a157ea3, 0x2116fd28, 0x81fe15be, 0x2c63577a, 0x7c795f82,
+       0x99d535b1, 0x0fc00b63, 0xe3037ff3, 0x61d57f62, 0xdcbfcc76, 0xbccab8e8,
+       0xc8aae93b, 0xafd399ad, 0x8a54f9f5, 0xea8eeadf, 0xe9e99369, 0x50535bca,
+       0xfd61f2de, 0x5f3a7f46, 0xfe449df2, 0xe315b285, 0x4aebf9d5, 0xf2f1c3ee,
+       0xf874984f, 0xadcf75bd, 0x3f2e09c3, 0x529e01fa, 0x7b75f102, 0xa6c52faa,
+       0xfbac1fc2, 0x7ccacf24, 0x1c137054, 0xe4307fe0, 0xa054f6ff, 0xbfee4a9b,
+       0xf50f7210, 0x63e2462d, 0x5fc470fb, 0x7e2d7ce7, 0xcdf8b5f3, 0x3e2318f7,
+       0xcd273666, 0x9323e0a7, 0xfc17df0e, 0x28e9a7fa, 0xc7abad9f, 0x235abcd3,
+       0x8e51c3ed, 0xffa0535a, 0x59e7dda1, 0xe7986bf0, 0x6799efd0, 0xabd11065,
+       0xfa4679c7, 0x33df679e, 0xed58c8cf, 0xadeacf3c, 0x5c5fa8e1, 0xfb8664bb,
+       0x8ec95cc3, 0xd97963b5, 0x768614b2, 0x05d0f589, 0xd5e912fa, 0xb8a068d6,
+       0x30ef22a1, 0x83f20dde, 0x35a1f88e, 0x28f4fad7, 0x0b656f5a, 0x575bd9c6,
+       0x51e7788f, 0x95aeb728, 0xb407682d, 0x81fc72e6, 0x0f50ebdc, 0xa638a6b4,
+       0xc18f7951, 0x39fa14b2, 0x0fb7f953, 0x0c0bf225, 0x73f34656, 0xbe3b45ac,
+       0xfd45e01d, 0xcd997805, 0xcd034aed, 0xa7cad57f, 0x7777e256, 0xfe964df5,
+       0xa7eb40d6, 0x6b45cf16, 0x321c8d64, 0x73c695bd, 0x8ac93afd, 0x0cf050f3,
+       0xc67d349a, 0x607c2eb0, 0x2eb0d679, 0xfd94b8bc, 0xeb3d626c, 0x9f885bd4,
+       0xc05d7cbe, 0xafa8ea7d, 0xa77d3f70, 0x57affb3c, 0xdfc67a7e, 0xd04db89e,
+       0x16ef5fd3, 0x7ca9cbab, 0x5cbaa15f, 0x4a37a7e2, 0xbac3befd, 0xfc502d3b,
+       0x78e77774, 0x02796f1c, 0xaf5c4a6f, 0xd68949fd, 0xd5bd3cd5, 0xabc17e88,
+       0x155c78e3, 0x8ff301fc, 0x683b0e49, 0xb67a793e, 0xef8994dc, 0x994f546d,
+       0xdcb7f427, 0x8ef46b04, 0xa077ae60, 0xaaa364de, 0x0557e8ac, 0xfe44479e,
+       0xc3fe7942, 0xad64f3fe, 0xb38aacff, 0x201b123f, 0xf7299ece, 0xc608ed7d,
+       0x64c976db, 0xf30eba37, 0x7d7d8575, 0xf06de9e5, 0x1a4f7cbe, 0xe6555bed,
+       0xf6c78fef, 0x7de12b86, 0x21db7de1, 0xcbc63063, 0x72a31af2, 0xf48a2fc9,
+       0xaffbc405, 0xfe94fcc4, 0xe12df4da, 0x2df6d5d3, 0xa19f096b, 0x86bc8fe2,
+       0x164fb42b, 0x5596e7f0, 0x534cfb7a, 0x79fa2e4c, 0xcc4a7ff9, 0x55f3c1d5,
+       0x06b5cf41, 0x506b0beb, 0xc899764e, 0x3c3b6f6f, 0xdbed8747, 0xe789170e,
+       0x9e7a7643, 0xe382933d, 0x7f38eb87, 0x14bde32b, 0x7ca5edcb, 0x7fe7a9dd,
+       0x8dfefa84, 0xaa65d4b8, 0x2ebe69f8, 0x6dc4fc93, 0x845cdf06, 0x95f1ec1b,
+       0xe943efb8, 0x2b58d5e7, 0xebb6d1c1, 0x0fa8f3fc, 0xce4dacce, 0xb6d23544,
+       0xcc70c06b, 0x189db7fb, 0x3fe78e91, 0xb04c9eda, 0x66d81ea1, 0xfc443eb0,
+       0x86cc2ab6, 0x87f4ae72, 0xac7e60e3, 0x1cc8d76d, 0x4edbb3f4, 0x4ca17870,
+       0x73d4377e, 0xa50efee3, 0xf59d70df, 0x8c8fb857, 0x7940c9fd, 0xa4dfc5b4,
+       0x1abfa1c5, 0x5f9c0c6e, 0xbb5dfb40, 0xc1296a7f, 0xf1e3ecad, 0x7d95efb7,
+       0xd17efe3d, 0xf80bd07c, 0x2b7fdfde, 0x702b9562, 0x1fbf917f, 0xdc7e40c7,
+       0xfa62beca, 0xbdf5a5ab, 0x2677cb64, 0x0fb13d4d, 0xbe031a88, 0x571e40f2,
+       0xc3c65c53, 0xe52b5fe3, 0x5f42f980, 0x3ec7cf2c, 0xdcedf213, 0x4f5d1516,
+       0x1e3e98eb, 0xc8da7af0, 0x7f99f1cc, 0xaf973fbf, 0xbacc57de, 0x73a777fb,
+       0x00b9953d, 0x32d5e9d7, 0xa1fd47ed, 0x7b7f9dfe, 0xf3e88480, 0x4effb099,
+       0x3e705cc3, 0x5ab3fb3d, 0x067c1578, 0xfe057d89, 0xfe22cdf5, 0x991bf03e,
+       0x9bee51d9, 0xcfe41e0c, 0x3f9f8d90, 0x67f20f7d, 0x6a92c1a3, 0xed017ca5,
+       0x64bb6573, 0xb75c7f4f, 0x2f84cf1a, 0xd76575c4, 0xd34e3a08, 0x92ecbfe9,
+       0xd6dfee29, 0xf3162570, 0xe50fd003, 0x4f4d5d3b, 0x7b7f90d9, 0x4e312382,
+       0xeffa61fe, 0xa1f8bf66, 0x6db67bc8, 0xfa8e973c, 0x6260f41d, 0xfa67ca1c,
+       0xff9e46d7, 0x7da1c96c, 0x273f1bbf, 0x73ddbcbb, 0x7349ec95, 0x940f6ca3,
+       0x671a1c57, 0x4df061fc, 0xf007c2d0, 0x1478450c, 0x3eadcb38, 0xbd737f3a,
+       0x5d84ffbc, 0x1cf14b85, 0xd1f9e608, 0x94682fbe, 0x582add69, 0x40ac7b2f,
+       0x7e030997, 0xed082fb1, 0x8a24a7d1, 0x6f924e0b, 0xd40e70fe, 0x4ca4f05f,
+       0x1f1bbde5, 0x7480d0fa, 0xbca06f5d, 0x99a682e1, 0xfc57da46, 0x122cc494,
+       0x37d9ab8d, 0x12972c50, 0x09f6dd5c, 0x680fedf8, 0x7d0b76cb, 0xe37ef7e0,
+       0xa2fb198a, 0x9267a9f1, 0x017efbb5, 0xcb103bfc, 0xdfe047cf, 0x126bfe96,
+       0x416d0e91, 0x5ca3358c, 0x5fc85bea, 0x3e7e5e61, 0xd9d76db3, 0xeb97a414,
+       0x5e292f8d, 0xb01c93d9, 0xf33fbe46, 0xfc8938ce, 0x5cdf81d2, 0x5008e699,
+       0x6fc8b67f, 0x13b8316f, 0xb7dd3ed1, 0xe38f2af1, 0xae71e2ec, 0xee67fb1e,
+       0xf26f1e20, 0x2c1c5106, 0x0532d6ab, 0x3cec01e5, 0x36b93fcc, 0x09b198ad,
+       0x0dbb41ca, 0xabab4456, 0x05c9287f, 0xaaa141ca, 0xb61e455f, 0xb2947c88,
+       0xd8b661bf, 0x6feca397, 0xf83bf650, 0x77eca1c3, 0x3bf62d98, 0x78eb1dbc,
+       0xc19e0e28, 0xd9385f3a, 0x5ffb7eb1, 0xe2cfda7a, 0x3fd1efbf, 0x4f9fee6e,
+       0xcbecad5b, 0x47146088, 0x8dfac237, 0xcd86c395, 0xabf51778, 0xfe4c98e1,
+       0xef23ded0, 0xf1f5aac5, 0x38737d0a, 0xd72f31c6, 0xd1fe4419, 0xc316f947,
+       0xa98dcf91, 0x862597a4, 0xca0bae76, 0xb375def8, 0x338eaede, 0xe7c71d3f,
+       0x9d2e22bb, 0xfb7ab7af, 0xb7afcc21, 0x688cf259, 0x148e1b8f, 0x367e464c,
+       0xf919e7c4, 0x54e6b9f8, 0x9e844ba4, 0xa3457ff8, 0x05b36e32, 0x7bf257fb,
+       0x2cc71161, 0x598577c8, 0xbf3fbeb3, 0x4a83f227, 0xdf33af7e, 0x7be33f17,
+       0xe33b7bf3, 0x8bf71d38, 0xff71bbe7, 0x3b7bf2cf, 0x5265fe91, 0x30f1a4cb,
+       0x8ef88ac4, 0x6ebdf9c0, 0xfcb1bcf3, 0x567147de, 0x9ceb7f9e, 0xbdf90f6f,
+       0x58dffd6e, 0xff7baf7e, 0xbaf7e43d, 0xf9837ff5, 0x797ecebd, 0x50f96f7e,
+       0x5b3fed1d, 0xe3c4dc7e, 0xffbe66e4, 0x65e424c3, 0x668277b9, 0x74f284ff,
+       0x184909b3, 0x275e5f27, 0xbcfe464f, 0xa0b3c96c, 0x78221a7c, 0xb064c83c,
+       0xd43f464f, 0x85191114, 0x711ff97c, 0xabaf3469, 0x3f888b11, 0xc87982af,
+       0x722d89cf, 0xef797960, 0xca649902, 0xd6177f2f, 0xd57cf324, 0x7758b368,
+       0x87e4b7df, 0xf3fbfe52, 0x3d1e5538, 0xed00fb2c, 0xce0d648b, 0x8fbf283e,
+       0x127f405b, 0x7c50b79f, 0x7f3928c6, 0x76217187, 0xbb639f82, 0x601ce41a,
+       0x3ea5c951, 0x2eec28de, 0x33ea126f, 0xa7a2ab37, 0xe10ae1ab, 0x2a478959,
+       0x47cc5ddf, 0xa5794778, 0x7a09b8c3, 0x706f7d2b, 0xb573a00e, 0xbb4e8e02,
+       0x6ea18fe0, 0x6a69a73c, 0x8ff286fa, 0x34df7aed, 0x36d4eb8c, 0xfc6a21ca,
+       0xb973c526, 0x9cfe4dc8, 0xd8e556f2, 0x57e617ae, 0x7ca0064b, 0xc37c9b96,
+       0x7b7dee11, 0xf51c36fe, 0x92a6d5ca, 0x0b7ef83e, 0xdc75a7d4, 0xe7572be8,
+       0xaaf3fd5d, 0xf381f1d1, 0x969a5bad, 0xdb1c2225, 0xf6005e30, 0x3fc3f955,
+       0x663a73a7, 0xea0dff66, 0x837a060f, 0x99868afc, 0x93b438f2, 0x01db003e,
+       0xf8bb59ca, 0xcc959bfa, 0x2d37983c, 0x0e60fa6f, 0xdb3cabd2, 0x32974168,
+       0x6de78338, 0x16cdb383, 0x45a6ff5c, 0xe2303e71, 0xed869b3a, 0xdd214627,
+       0x3031c41e, 0x7b73b9cf, 0xb7f01bbd, 0x854f0ff0, 0x27dfc033, 0xafda4afa,
+       0xb1f9ba51, 0x2f3c3b70, 0xc714dde8, 0x0723c4fc, 0x1794ffdc, 0xf6b7f8af,
+       0xfe754950, 0x3fdfd3e0, 0x6ef88d31, 0x7982c1b3, 0x1316d77f, 0xaf2b9f9d,
+       0x33f3a62b, 0xcbc53e50, 0xfe867f8f, 0xbb41ab95, 0xe97c2f4e, 0xad2b58a9,
+       0xb124ee0b, 0x941f11ee, 0x849d9cd7, 0xc1f857f8, 0x8f8e1dbf, 0xb55de5fb,
+       0xaf633cf2, 0x7b15dfee, 0x5dff5943, 0xfb884f75, 0x3fc85a01, 0x845faff0,
+       0xb19a3232, 0xfddaf199, 0x983e0ad1, 0xa3f48627, 0xf0c373bc, 0x54be5053,
+       0x92e16ff3, 0xbf8a4f0a, 0xff9b51d3, 0x3dac37bb, 0xb06defaf, 0x7574b02e,
+       0xb3b50f3b, 0x177e0836, 0xf06a5f7c, 0x955ca386, 0xdcd8346e, 0xfb74baf0,
+       0x973e2f0b, 0xc3667245, 0xfb64ac75, 0x818e1f5b, 0x430ec972, 0x8d3e54f4,
+       0xde754950, 0x61ff05cd, 0xc3a1405e, 0x32ded7c2, 0xf7f1875a, 0xa2ec88bf,
+       0xbd8ec947, 0xfc5e7446, 0x76be31f1, 0xbbf291af, 0x3da974fe, 0xef2b7245,
+       0xbbec86fc, 0x2c48f64f, 0x3e00352e, 0xee15be37, 0x3a227814, 0xd2753a0a,
+       0x92beafcd, 0xe4e8577f, 0xde3b3dff, 0xfd85f242, 0x3f023ca1, 0xc606f2bf,
+       0xd9323ffb, 0xaf45fe70, 0xf38e103c, 0xc45faf38, 0x63c37af9, 0xb71876b1,
+       0xb58ee0c8, 0x2fbf93d0, 0xc467fe7a, 0xfe8e0b6f, 0xcc7fdb8c, 0xfca3a09e,
+       0x7bf29ba5, 0xd0efeb85, 0x0da2ffe8, 0x85ffae3c, 0x11de4d9e, 0x0b8e2e40,
+       0x937e72bd, 0xe7d9f289, 0xf6860f31, 0xdf327bcb, 0xa7eec7b7, 0xdf629078,
+       0xe54d2780, 0xfe1e842f, 0x894ebc43, 0xfc359b7f, 0x3378f35a, 0x64d3e7d2,
+       0x25ea1c7b, 0x05bbd317, 0xa0efa43e, 0xc4e8f95f, 0x1e1f4e38, 0x6076a33f,
+       0xf7c78e8f, 0x40d9bf58, 0x3b5550f1, 0x8f966e71, 0x1f18a0ff, 0x7cc60ee0,
+       0x5658f9ca, 0xd44fc814, 0xe7c67427, 0x29e7359b, 0xcb9be4bb, 0x2e2acd7b,
+       0x7bbc8adf, 0xefc64fa6, 0xf2e31f9f, 0x3292ed83, 0x1c6f2e09, 0x4b3bdf7d,
+       0x27cfce1a, 0x75c9037b, 0xb5c8418d, 0x27c2bbf6, 0xee9eb700, 0x05f85021,
+       0xfc248ffb, 0xbad2d517, 0x1dd8d26d, 0xbc2f1c2e, 0xdc8a7f7b, 0xfff2102e,
+       0x7f38bc7e, 0xad9fe425, 0xf3a1b98f, 0xcf06a545, 0xbca1cf8b, 0xbef7e09e,
+       0x90376e94, 0xdb717e5d, 0x06ef0ffe, 0xab58b939, 0x7f56a9c8, 0xd169cbfa,
+       0x7f116fab, 0xc5e9cbfa, 0x0362b7da, 0xb78ee9ca, 0x2eee0ec8, 0xfab9ffa7,
+       0xdfdfc153, 0xe8a7f0fc, 0xe8f09ec3, 0xe3ab0faf, 0x21f501ad, 0x9f531dfc,
+       0xa5f0537b, 0x6fc29df0, 0xeb2e5f0b, 0x93a77a83, 0xebbe152f, 0xef854be4,
+       0xd73bedba, 0xfbffcfe0, 0xe00df85b, 0x60faec72, 0xb3d01252, 0xc9fb91b4,
+       0x9620eed0, 0x5a764f01, 0x41e558c6, 0x55db6f3c, 0x6b95f8f6, 0xfddbeafd,
+       0xfabf0eca, 0x22f2bf4e, 0x821efabf, 0x3f61b4ab, 0xbcc96fdf, 0xa586fa9a,
+       0xdd161dcc, 0xf31e0e75, 0xcfd02b58, 0xf4f3c6df, 0xb8f0258f, 0xb8c62fa9,
+       0x891ff682, 0xe13e2a7d, 0xb43bb467, 0x354e54fb, 0x5b7fa4ca, 0xf8f3813c,
+       0x3c9209e0, 0x3fb0f4b4, 0x4d3b895e, 0x1e534394, 0x2a3a3806, 0x60a0fc79,
+       0x94e19dc9, 0xbb4c69cf, 0x850ae31d, 0x2c31f987, 0x73143f65, 0xaa09f5db,
+       0x98170efd, 0x319be9fb, 0x4258d64f, 0x35828bf1, 0x0fcd7a5a, 0x0be2907d,
+       0xf7b4abf3, 0xad7c2900, 0xd68b0bc4, 0xc42fbf6b, 0x1ee8847b, 0x47da4a85,
+       0xfb46b0b4, 0x0e7c89dd, 0x41273c7c, 0x2c1909d8, 0xf9bde443, 0x57a11239,
+       0x6f43ca27, 0x21cbfca7, 0x1da5f299, 0xbde1328d, 0xfb449b63, 0x863b9869,
+       0xf99ca5e4, 0xf8299f48, 0x60f284b9, 0x5cdf59ec, 0x73dffd7a, 0xa52a851e,
+       0xff0f1ff5, 0xd52f3c2d, 0x8ddf489f, 0x4e7f9de5, 0xaf7598f9, 0x104f7e3f,
+       0xdf6a1fed, 0x35f74613, 0x9dbd37b5, 0x85e528f2, 0x07ba364c, 0x9497cf61,
+       0x6a5f6b7f, 0xd57d422a, 0xcafdcc9e, 0x0e5f4d65, 0x39657ae7, 0xc098df3f,
+       0x34744dcf, 0x94f28dfe, 0xca268d1d, 0x84f6b933, 0x7ae11f90, 0x9cfc8823,
+       0x292fa6f6, 0x9acffcbe, 0x3788b94f, 0x3cf187b7, 0xbfb8bb4f, 0xf47bb5c4,
+       0x2d87980b, 0x446bdbab, 0x9bfc65bf, 0xdf5d90df, 0x67b72afe, 0x1eded0da,
+       0x5bae7883, 0x7dc44e33, 0x4d0ecca8, 0x0db77b45, 0xb1912385, 0x9d5dcfa1,
+       0x081a1eea, 0x5e50df4f, 0xf3f146f5, 0xfc18ffd2, 0xb9dfb448, 0x63cc31b4,
+       0x5fde7096, 0xf518fc9d, 0xd79e1ec1, 0xb17be657, 0x1fd90976, 0xc1f79bd7,
+       0xfddfee04, 0xe4b799ef, 0x9f7991bd, 0xef4e6ffd, 0x98d43c62, 0xba2e5ddd,
+       0xcf1379f3, 0xb30f6d17, 0xc837bc11, 0xffc486ef, 0x157f7465, 0xfd7e1ee8,
+       0x6ffbf779, 0xe99eef3e, 0xa0ae787e, 0xf3e305bb, 0x21bf37ae, 0x3d5efef8,
+       0xe87fe137, 0xfd3b15fc, 0x6fd7c67d, 0x91c3a257, 0xee9efb88, 0x5f02bc38,
+       0x274e74b9, 0xcd12c3c5, 0x4d9fee74, 0x8e87e28d, 0x33618ef5, 0x57877586,
+       0x25fe1bf1, 0x31273ed1, 0x07feaba6, 0xa619efb3, 0x7d57779e, 0x58d1be3e,
+       0x379d3f7b, 0xfca50b29, 0xc18f6e2c, 0x36cc2f76, 0xf713fe71, 0x990f1c3c,
+       0xa606307b, 0x738347f2, 0xe739c23e, 0xc0ac9fce, 0xca2fb4b2, 0x35e718ba,
+       0xdc4725af, 0xc710b08b, 0xfb3b352f, 0x72f9aa60, 0x2f4073b2, 0x511c47b4,
+       0x1ccb9e3c, 0xe1011cc3, 0x37ce6b77, 0x994bf62a, 0xea3aa1b0, 0xbe517ad2,
+       0x645ed5e4, 0xb8e9b57f, 0xe026d87f, 0xb767e0bd, 0x1a8e7917, 0x5c58ff31,
+       0xcea8d473, 0x7389963f, 0x3fe3fea9, 0x23f3c891, 0x87f6be9f, 0x8bf748ab,
+       0xa3a7d45f, 0x5d2256bd, 0xdd5d79a2, 0x98ae747a, 0xff9c0adf, 0x14be1d43,
+       0xb4abcc23, 0xc791af76, 0xf4fcc523, 0x9beff4be, 0x79ae9b5f, 0xaabb9d12,
+       0x8e7ce897, 0xeeacaed2, 0x93b424e8, 0xe8226a8b, 0xa7dc473e, 0xca9dcfc2,
+       0x7860fb7e, 0x8eb2493f, 0x4bf7dbf8, 0xd21bf689, 0xe9dfb41f, 0xbee0f08e,
+       0xcaee936a, 0x676899b1, 0x8ce7e30f, 0x438307d6, 0xbbc77e0f, 0xc41b5f02,
+       0xbf780779, 0x07c7df12, 0x4ff1f6f3, 0xfedf68eb, 0x9409b90b, 0x7bdd543f,
+       0x72075291, 0x36b26494, 0x49b8c0b4, 0x0f28bd15, 0xb9d13dbc, 0x5f71f105,
+       0x18e52e94, 0x421ce1c1, 0x8e6f80e7, 0x753f21ba, 0xf818b306, 0x9e7e527e,
+       0x4f85867d, 0xb5d850a5, 0xee9d9933, 0x3983b8e1, 0x6d7bdea9, 0xd7da3b46,
+       0x336e61ef, 0xa3f7ee93, 0x0f3177f7, 0x5e61ef3d, 0xac2fffaa, 0x5f0aca85,
+       0x17de3f02, 0x3cf1f9cd, 0x8e8160a6, 0x47dc226f, 0x3f278643, 0xfe9ef80c,
+       0x94fe80cc, 0x76e2ad2f, 0x9ee0f5f0, 0x574bfc2e, 0xf210f3a2, 0x2fe4c77b,
+       0x7e82af9e, 0xf12f6674, 0x91ee7283, 0x7c11884d, 0xdb72fdf1, 0x0f99d1dc,
+       0xe2bf450d, 0x5bd24156, 0x509fdced, 0x2edc0dce, 0xd9ef01e4, 0x343a0489,
+       0xa7bdf95b, 0x3dbd2acc, 0xc793ca02, 0xe59fb4c9, 0x20d6e08f, 0x4331fc7f,
+       0xd9a5f716, 0xd134fda9, 0x3371d4ef, 0x7a82f797, 0xc96ebe93, 0x9327f3c2,
+       0x8afd6b7b, 0x5c6f449f, 0x29cf011e, 0x7fefb4fd, 0x88f59aca, 0xb543a9d7,
+       0x2cb4cdfe, 0x38bdbd6d, 0x2a962466, 0x4b845ee9, 0x193fc289, 0xfdab06cc,
+       0x1d3e6513, 0xd118af53, 0xe493ec17, 0x597482bc, 0xb9d9db7c, 0xcf4ede74,
+       0x4d111ede, 0xbcd1cff7, 0xe6f02b5a, 0x55cec646, 0xa179e998, 0x20ecc2c2,
+       0xc4569ff7, 0x8552f3d3, 0x55b7de95, 0xf8e7a40c, 0x90dfc724, 0x9f95053e,
+       0x670fd1e9, 0xee34e955, 0x9acf8203, 0x9d1d5e75, 0xd124d85f, 0x82079a7e,
+       0x8ef1739a, 0xa73607ac, 0x61739c52, 0x0c41ed43, 0x1d78141f, 0xf39c9093,
+       0x883a2d0f, 0xc06bb2cf, 0x158023e9, 0x24a61c12, 0xa763eb94, 0x7ac6df67,
+       0xe37b1be6, 0xd05183a9, 0x1b0af9ff, 0xc549f5c1, 0xac5e7a28, 0xb3dc13b0,
+       0xa4961c92, 0x67d2a46c, 0x6db73fc4, 0x824fa53b, 0x12ad13fa, 0xb63f2bad,
+       0xe4078f33, 0xd7c0daab, 0xb304ea85, 0xdc74e50d, 0x1e1b19b0, 0x9df7a864,
+       0x1dc70889, 0xe2278a53, 0xcd46d338, 0xeeb47ba3, 0x7bf19afc, 0x58dc2695,
+       0xe9f988dc, 0x247bcbdd, 0x3acbcbe2, 0xff18edeb, 0xa649ff75, 0xde0740fc,
+       0xe3fe80d3, 0xe32f7e71, 0xe2d3d7e2, 0x362f3f50, 0x5fd0e358, 0x79f62ddf,
+       0xe97a045c, 0xc5eceb55, 0x9cce7fed, 0x25bfd2a7, 0xfabaecaf, 0xf2fbf411,
+       0xea1b48c9, 0xe2918bbd, 0x28b6467e, 0x9b48f504, 0x19623bc8, 0xd65015ef,
+       0x5833d45d, 0xebcc18be, 0x9492bce7, 0xe382728b, 0x7a5d8d59, 0x6795fd28,
+       0xed6a3efa, 0x6d4b6f1a, 0x41cf47e1, 0xe747b2f9, 0x723ac036, 0x61b6d599,
+       0x135dd6dc, 0x066dfb4a, 0x87e0fa4a, 0x7c3d6f89, 0xd56488bf, 0xeb6c3c63,
+       0xd1121b2b, 0x392dd80e, 0xfa823ee6, 0xffaf037b, 0xe48fd3d2, 0x53e7c2ed,
+       0x823eaf65, 0xa08a4f78, 0x2b9ff376, 0x36fc8c1e, 0x5d5efd6c, 0xa9bfbc22,
+       0x7c52d4e6, 0xc2a240ce, 0x926d8cf7, 0x8cdd778c, 0x865d4ba8, 0x1fb898af,
+       0xfbc0b06e, 0xed9ff5d0, 0xf4107703, 0x08e2ed6b, 0x525757ca, 0x671bd7bb,
+       0xc10f7fbe, 0x7bc04ee1, 0x8cf3dd35, 0xb8f03edc, 0x5c9f2237, 0x51b40e76,
+       0x7ee1cd7e, 0xd973e916, 0xf5c36b19, 0x0ee75ea0, 0x4ff5831f, 0x76087bf2,
+       0xc70d1cd6, 0xeabd11fd, 0xed082c0c, 0xad1f0c95, 0x56c9654b, 0x259659bc,
+       0x64eb7f3f, 0xd7927946, 0xa53f5237, 0x99e61b66, 0x42bf5e8b, 0x13f61cf1,
+       0xfc8feb66, 0x4fcbc751, 0xfd13b04c, 0xc17e368a, 0x2a0ecdcb, 0x2a77643b,
+       0x0f945fdd, 0xfbf40c76, 0x5877588c, 0x47d270cb, 0x2ed672c4, 0x9f013f7c,
+       0x3abdf02d, 0xfb809dd5, 0x0af594c3, 0x219f99d6, 0x839ba37f, 0xef739bed,
+       0xf775a149, 0xa519d706, 0xfc8c679f, 0x46f5bd7e, 0xb66e1ebe, 0xf42778f0,
+       0x4fe514bf, 0x64931759, 0xae1d5869, 0x6c98cf73, 0x3e37accb, 0xfee2ddce,
+       0x2af813ae, 0x430d6c41, 0xf8ffba42, 0xe9ffc636, 0xfbf23dfe, 0x15675799,
+       0xf941ecf7, 0x4fc3a4e9, 0xe619bf2e, 0xe003f82d, 0x83013820, 0xf2a7f50c,
+       0xe38b2c3e, 0xb669d233, 0x2e2b7e61, 0x33dd116a, 0xd307f0a1, 0xdda0477b,
+       0x995bfab0, 0xffb94bce, 0x7f714a1a, 0x4ddf787f, 0x7af471e2, 0x639e07c0,
+       0x7bf07772, 0x5ac31a9f, 0xf403fe5e, 0x9bdc58df, 0x0dbbc6e2, 0xf756fefc,
+       0xdc5df174, 0x5778dd27, 0xa27dc92c, 0x7601eb89, 0xd38d304f, 0x7e6cf068,
+       0x8f4fbf1a, 0x85c7f6a7, 0xde671d9c, 0x955f707b, 0x7ba467db, 0x1822ab39,
+       0xb55367dd, 0xfdc50064, 0xe07dbfea, 0xbda186df, 0x639f84b2, 0xacf0caab,
+       0x55ff7dc4, 0x70e34cbf, 0x1724de48, 0x260e2fb6, 0xdd355d3d, 0x4071809e,
+       0xba10b4e7, 0xfba7ba57, 0x28323f5e, 0x09ec89e7, 0x0ae78f88, 0xfdf533fa,
+       0xca4e7f41, 0x57748c3d, 0x3a73d1f2, 0x8ecc22f3, 0x21de5bf7, 0x6e15770a,
+       0xbb7e420e, 0x14e828a3, 0x178f6bc6, 0xb8c30d2d, 0x7e4e1de3, 0x359b273f,
+       0x8f3eaed1, 0xfb24e7f9, 0x5657e461, 0xdeedd8a0, 0x1ed3c47c, 0xbdce999f,
+       0xa847f901, 0x7f8544ed, 0xbe77aafe, 0x8ddaed87, 0x92e35ee2, 0xb6cda6af,
+       0x6bf1faaa, 0xf27edfe7, 0x37bf330c, 0x7644cea9, 0x8ec27dc1, 0xb3bc9972,
+       0xad5a0ed1, 0xf607fe73, 0xe9f85aef, 0xa277b470, 0x17fbf067, 0x09be31db,
+       0x7a0a4f75, 0xff7c649d, 0x98517ba0, 0xb2f11bc8, 0x0f28d1f3, 0x9ec7a7bf,
+       0x07e58850, 0x1f70d886, 0x99e45390, 0x7c44b958, 0xf9c2d272, 0x146364e4,
+       0xe33e8fdf, 0x30e9d3da, 0xab8e938f, 0x7a848f6f, 0x79f81b27, 0xcc3cbf8e,
+       0x2f9619cf, 0x60d2913b, 0x7baf3eed, 0xd97bf297, 0x0bf85def, 0x93da6f3a,
+       0xaa5bddfc, 0xd21987dd, 0xce15fedb, 0xb5c67a33, 0x1287a849, 0x2d9f4a4b,
+       0xdbdabd44, 0x2fbe2df9, 0x2394b637, 0xff77ca3e, 0x7fda0a7b, 0xda5ebbed,
+       0xaf9e1071, 0xdeba9d19, 0xade97df8, 0x67618fa9, 0xd72f9ec2, 0xae403d03,
+       0x34edea9f, 0x717e06f6, 0x63a6f04d, 0xe6864bbb, 0xf6378849, 0x1bb31b8b,
+       0x5cdc6d3f, 0x115fa12f, 0x4f4e58dc, 0xe11c33d9, 0xc37928b8, 0xa71e1ef1,
+       0xc97e8fd8, 0x188f0de2, 0x72c7f78a, 0x1f3ff5fe, 0x8ac5a048, 0xaed0327d,
+       0xe71656a4, 0x27143c97, 0x025faff6, 0x0ddea9ef, 0xcbce57be, 0xac344495,
+       0x66f44b1d, 0xee166f5e, 0xf74feceb, 0xfd7e5d32, 0x5fb574a5, 0x0eecffe5,
+       0x9d3f9f2f, 0xa9bcc6e7, 0x7bf7df87, 0xe4068a09, 0x71266db3, 0x51f38f8e,
+       0xc104d6db, 0xda8f9c67, 0xa8f00eb6, 0x9cf3b6e5, 0x8736ada0, 0x6bdbedf6,
+       0x501ed073, 0x6b999fe4, 0x36677ee9, 0xda3876b0, 0xc23d8add, 0xf4e9b51c,
+       0x8e9b53de, 0x3c75ebf5, 0xbb8ca73f, 0x7e24e5f0, 0xeb9998df, 0x0f2f85c5,
+       0x94c6fba1, 0xcf37af7e, 0x4d46d501, 0x5b479079, 0xef9bd69e, 0xeffdf85b,
+       0xcbf1f73b, 0x93c61ec2, 0x40f79d85, 0xbd73de76, 0xf2f05255, 0xfa0e5260,
+       0xaaf28ca3, 0x0be07bbb, 0xbd21ae05, 0xf30b3fb9, 0xbbceb863, 0xbbfae23f,
+       0xf331c33e, 0x6fd72836, 0xb6fb2348, 0xe9f8e74d, 0x79e71c30, 0x3ebaafbe,
+       0x9cf947c2, 0xfdb967fa, 0x5de62e5b, 0x424ce11f, 0xc2a17a7d, 0xffee2f16,
+       0xe96c3b26, 0x98e11589, 0x61dfaff7, 0xd5f8c0c8, 0x63fb3527, 0xad3e2f91,
+       0x37ee9878, 0x75e3bc1c, 0x6e94a3ca, 0x1c7de07d, 0x8336d2f7, 0xd2acdd0d,
+       0x8b5c5ebb, 0x56e948f6, 0x5be716b9, 0xe53f75ba, 0xbed52fc7, 0x71fb8e15,
+       0x9144d42f, 0x53f08c1f, 0x1cf7fafe, 0x2ff8fe0f, 0xabc464f6, 0xc91591f7,
+       0x7f78b5ee, 0x5a2d90c9, 0x3c7d17bc, 0xedea10e9, 0x18cff50b, 0x1fbc56f5,
+       0xa6fdfb56, 0xeff96d06, 0xe4abaf3d, 0xd4e39091, 0xdcc85c74, 0xdda9f507,
+       0xb5645feb, 0x3f18edb3, 0x9727bce8, 0xdae8edcb, 0xbb379475, 0x6e6e78fe,
+       0xe9da853c, 0xa379ab9e, 0xe231b7f8, 0xe6b65efe, 0xdbc424e8, 0x5a2427bc,
+       0x36bde6ef, 0xcfea00e0, 0x9aee3b53, 0x93d9cf42, 0xe8f91f09, 0xd67ee085,
+       0x061bc946, 0x8e28cb65, 0x9e6ac2ef, 0xee5bca17, 0x8d69ee77, 0x2af8fedf,
+       0x0d05f7ed, 0xbcc2bf7b, 0x79f99176, 0x3f741f8a, 0xfba1e3c7, 0x605e177f,
+       0xac2dcfe4, 0x2814cef9, 0xcca851be, 0xda63fdc3, 0x264dc01f, 0xfff0fff0,
+       0x4daee346, 0xe1ea3d47, 0x651b5531, 0x731957c4, 0x2349643e, 0x021bc5bf,
+       0x8137cfe3, 0xeb4992dd, 0x4ae7cd21, 0x8f3a2f75, 0x5059ef0e, 0xda03de26,
+       0xe4eb839c, 0x1b30ba95, 0x9cd69fdf, 0x02d57683, 0x21f9d328, 0x0bce2956,
+       0xf1fee87b, 0xcd06d505, 0x1ec5e07d, 0x7255996d, 0xef14b0fb, 0xfa470ed3,
+       0x92bb50b7, 0xa57ada2d, 0x91e39f30, 0xfb51ffb8, 0x5b7cc5de, 0x2b7da45f,
+       0xefd498df, 0xb1547b15, 0x0e38958f, 0xe460b228, 0x7237bb97, 0x04b77a3d,
+       0x0c3b45f3, 0xafb234ed, 0x420e3b3c, 0x2878aab9, 0xdff54fd9, 0xca5bfdf2,
+       0x0caad4f9, 0x279e3a7b, 0x88375aab, 0xb25bbfe6, 0x7a863ea7, 0xd859ba60,
+       0xe1ee8c57, 0xa44e2aaf, 0x1c23fbf5, 0x2ced0132, 0xf729ef6e, 0xeea227f5,
+       0x18e371c2, 0xb53f8fbf, 0xb37a8bd6, 0x3fae29ea, 0x81563b14, 0x4f675f3b,
+       0xb36e75c1, 0xcdebe9d9, 0x23a56ff7, 0x09bff9dc, 0x4557bc22, 0xfce8c2f8,
+       0x0dd4517f, 0xc59ba7ad, 0xabcca0fa, 0x7dd07255, 0x293d4ae8, 0x9cdbeb99,
+       0xa28bfb5c, 0x0b39c51e, 0x6fab1d72, 0x3c147c01, 0x1fa2b3ad, 0xbb6789dd,
+       0x13ef1d3d, 0x94175d68, 0xcc9cf089, 0x47367ae0, 0xf6061bdc, 0x3c137dbb,
+       0x9a759383, 0x32706578, 0xc163a7b7, 0x5af1c27f, 0x5438f227, 0xfc839658,
+       0xe6a9c079, 0x19e53c1e, 0x302be02b, 0xa3f4fe3a, 0xd274f000, 0x7bc7027b,
+       0xad12fdeb, 0xa21f3047, 0x83afce5f, 0x2ad00e28, 0x4e8503d6, 0xb4d92fc0,
+       0x54bd09ce, 0x21f80ab5, 0x2da1ed15, 0x6afa835b, 0x0be286f8, 0x3ebe2eec,
+       0x7c704554, 0x4c393d56, 0x6f82e5d8, 0xbf120c9e, 0x6cedc0c7, 0xec51fd65,
+       0x3d3e6570, 0xef40e1d9, 0x7c2ac961, 0xe999d3f9, 0x7dead93d, 0x5e74fe94,
+       0xd2986e60, 0x0bc1550a, 0x5c067825, 0x6b7d91d2, 0xde0892ce, 0x2a7ad581,
+       0xb259d51f, 0x8da6ee51, 0x11f179dd, 0x7e7857d4, 0xebf47907, 0x39bbbeef,
+       0xa951f707, 0x7dc472fe, 0xeb0fc8ca, 0xef183799, 0xd894afd9, 0xa03acd69,
+       0x8fdfe32d, 0xb9fabb63, 0xf89efd5e, 0xdcfd9ff7, 0x69d8c159, 0xf85d8590,
+       0xebc347ec, 0x4665fbd5, 0xb93c7236, 0x5f4f308e, 0x597677d2, 0x0467ef8d,
+       0xcbfcee1f, 0x6e3023ab, 0x687dae31, 0xe9679e2f, 0xd3ef53a7, 0x5ed660ed,
+       0xa3b4efb8, 0xee17ad31, 0x2438eb4b, 0xf0033987, 0x038056f5, 0x572ff1e3,
+       0x5ed9e998, 0xf0652ac3, 0x8f99da2b, 0x6bba67f6, 0x5f902ccc, 0x73b934ba,
+       0x739319ff, 0x3ba5f7d4, 0xa4ec7d68, 0x9fa9a5d3, 0xc77787e8, 0x569dfe3f,
+       0x87f913d6, 0xebf715e3, 0x06b75e20, 0x740a4cb5, 0xe04aafde, 0xafbeda6d,
+       0xe0e33f68, 0x943a8dc6, 0x3a35c1f7, 0x26b93acd, 0xca43ec59, 0xd7089964,
+       0x61417db4, 0x438f4859, 0xe6082db2, 0xccfc6ae7, 0xd7e00ce8, 0xfb11e3f9,
+       0x8702fdc7, 0xa7842d93, 0xf25a86dd, 0x365f772b, 0xbb29fdd3, 0x8125958c,
+       0x23eccce0, 0xd8ebc405, 0x5f6833f3, 0x5e157fca, 0x7a87b5c7, 0x588e3173,
+       0xbb1c78c3, 0x7d71bf1b, 0xd185b1d4, 0x710ef739, 0x1b63a80e, 0xa01ebca3,
+       0x77dc49e2, 0x8b7df203, 0x80d63f7a, 0xe32f1d86, 0x28de5efa, 0x72e4fed1,
+       0xf7118b7d, 0x221aba5b, 0x65bfcc64, 0xae3dc558, 0x59b0cb7a, 0x9c38392a,
+       0x17e7e7ac, 0x07beecc6, 0xc972bdc7, 0xec87e748, 0xef747c07, 0x11c695c0,
+       0x3cefbebd, 0x6c156bce, 0x7b3bde0a, 0x5f119938, 0xd0c1f3f8, 0xf29ac16d,
+       0x8899d958, 0xd4cd34f2, 0x002da0f2, 0xc4528add, 0x7aa370fa, 0x89fff3cc,
+       0xe8a63b1e, 0x8eaca731, 0x74a46487, 0x817163d3, 0xc962d8f4, 0x5ef8871a,
+       0x871694dc, 0xd87c5cf4, 0x8f481310, 0xac38076d, 0x007f7720, 0x7b67c3f9,
+       0x9bb1e81d, 0x0eac7a54, 0xbf0058f4, 0x3ae52924, 0x5ff3cc7a, 0x51db6f23,
+       0xe798058f, 0x1fae14f0, 0xbc363d14, 0xb1e914f1, 0xcd3a75e1, 0x29feda39,
+       0x5263d3d7, 0x2c68accc, 0x01216c1b, 0x89f106f8, 0x27c47779, 0xd41c713e,
+       0x9629f967, 0xfd9f4bbf, 0xecfa7af8, 0x8abf08bf, 0x3afc5b3e, 0x3ba37f23,
+       0xdfe231df, 0xfd18bbc5, 0x26e2cfce, 0x3716cfae, 0xcf0fbe31, 0xec0d8f4f,
+       0xff18c7a6, 0x6f2f165d, 0x7d486aef, 0x2fe85ee6, 0x99b06ed3, 0x97667ea1,
+       0xeb56cb5e, 0x1e94fcb5, 0x1ba1daf4, 0x0baf6bd3, 0xaafa06bd, 0x7f51ea2f,
+       0x6a35b0be, 0xf763977f, 0x5edbf3e8, 0x5b78f943, 0x4701f3a6, 0x9dfebe45,
+       0x90b3e7d1, 0x1e11eaaf, 0x4235d390, 0xdc2adb5e, 0x03f8ffd4, 0xdb657e7c,
+       0xca0f5a24, 0x57bdb8eb, 0xf07b235e, 0x31a4e180, 0xff3ed15f, 0xe18926e2,
+       0xa6e9b2d1, 0xfef1a7ca, 0x8192f630, 0xd4e53889, 0x143f150c, 0xf8a12a8c,
+       0x999e8161, 0xc96ddf71, 0xb73fbe28, 0x7b959444, 0xf53b0ba2, 0xcdbedfa0,
+       0xf7e9fb86, 0x7bcffc34, 0xdcf7134e, 0xf2417b4d, 0xdd5ffde0, 0x712a7bcf,
+       0x97fbed38, 0xcba77cc5, 0xf61f842d, 0xde73e06e, 0xe5e3fb2f, 0x8d4bc090,
+       0x478bc5ac, 0xe517880a, 0x8782ad5c, 0x565bb7e2, 0xf8a75c60, 0x32fc8959,
+       0x782b79ff, 0x761f76ea, 0x909dff23, 0xdb62f7ee, 0xd25bbf35, 0x144477ed,
+       0x7fcdfb3c, 0x323fa2bb, 0x37bc08d8, 0xf482f81b, 0xfc4ffb87, 0xb8c7421e,
+       0x3d6a71fe, 0xc3c09afc, 0xe371ca88, 0x2e99add1, 0xd5f98afc, 0x804c1ff7,
+       0xb71f67f9, 0x6303fdd2, 0x9ee898c7, 0x3e41adbe, 0x9f0a6fd2, 0x3e70fa19,
+       0xecfd116b, 0x4b945c4e, 0x241a74fb, 0x2e13da0b, 0x37bf106f, 0x082df805,
+       0xf67fecaa, 0x478124ea, 0x689efd0b, 0x006f5883, 0x4e57e8ef, 0xc01fd652,
+       0x88cfca3b, 0xd7074e46, 0x2c874e16, 0xe567e3c6, 0xf30d92d5, 0xf70de5ea,
+       0x8a3e711b, 0x50bf85de, 0xfc545d35, 0x27f357a9, 0x7bad547d, 0x34fbe225,
+       0x1887e553, 0xfc06993f, 0x0cd891be, 0xfc3df7fe, 0x5f77eddb, 0x2f7bf3ae,
+       0xa78e1f72, 0xf44788ed, 0xdc7d12f3, 0xbac2f26e, 0xddf5d610, 0xf06b77a5,
+       0x6bb9fe38, 0x249abf9c, 0x3b01c62b, 0xefc354f1, 0xf056cf6d, 0x788afc84,
+       0x63279c6f, 0xf8837e79, 0xf9bf1fdd, 0xb5083ee2, 0x9d37171c, 0x906ffde2,
+       0xbcc02c6c, 0x7fdfe47b, 0x927b6f90, 0x2d1f435f, 0xe413beff, 0x2efb823b,
+       0x77e24ddc, 0x34231a19, 0x7dfec279, 0x35b01db8, 0xfd1cf808, 0x1b06c3e8,
+       0x2fe0a7de, 0x3d62b1ef, 0xaadf7b43, 0x420f97ca, 0xb12e3180, 0x28ceccc5,
+       0x76e5f470, 0x6edf5aa5, 0xb331620f, 0xbfee7ab2, 0x4f5ba09f, 0x1e528df6,
+       0x5ea1e386, 0x54f1806c, 0x7d7f2cf9, 0xd7e5f8af, 0x0fc6579b, 0xce32979c,
+       0xd87e7bdf, 0xfe799ac5, 0xd0245f02, 0x26dfe179, 0x9fa9bc63, 0x7bdf57a4,
+       0xfe6fdcae, 0x3b3fe84f, 0xfee7a625, 0xf685bc59, 0x4efb2937, 0x0e3cfd94,
+       0xf3fb130b, 0xae33fe6f, 0xfcec57e3, 0x8e9641fc, 0xae33707d, 0x3a06b90f,
+       0x88e57ac7, 0x573fe281, 0x2e7bf026, 0xbf7b7f6f, 0xedf2f51e, 0xff0114a8,
+       0xe44b67b7, 0xaec51d1f, 0x6d1da347, 0x80257da6, 0x1f9811bf, 0x1ca9a8c9,
+       0x333ee78f, 0xe19678b7, 0x17de36d3, 0x6dd20efd, 0x7bf74c9c, 0xc6a3db34,
+       0xc0fa3ae3, 0x71819659, 0xa9ef5877, 0x1621e67d, 0xd8c6f583, 0x18fdc863,
+       0xb1f9f75d, 0xe8c70099, 0x0acdb223, 0x0fefa6f5, 0xf77cc50d, 0xe63af5c0,
+       0x0c6be154, 0x73c32cf3, 0xed5ba33e, 0x22ee1133, 0x2e305fb0, 0x71b8d45f,
+       0x2e439e19, 0x7b512f5a, 0x2939db97, 0xbdb3e61c, 0x4349b3fa, 0x3d401f50,
+       0x9eb5c6ec, 0x48d573d7, 0xcf394c36, 0x24675c6f, 0xefc3517d, 0x91eed86f,
+       0xebf79998, 0xdbbf4331, 0x2cfb43d7, 0xd05b638a, 0x7cd5720e, 0x5cdffb46,
+       0xdfb52700, 0xccc5cfc6, 0x94567687, 0xa9fb9a97, 0x12f5e2bf, 0x457323c3,
+       0x543af8db, 0xc360c474, 0x9f7b75ef, 0x2a74f5a5, 0x8a90978c, 0x02778eeb,
+       0x884739c5, 0xffc77b7d, 0xed5df90f, 0xd58fd38c, 0x2feb92fc, 0x9fbf2989,
+       0x4f9f57ab, 0x97d3e8eb, 0x2db10bef, 0x3f414631, 0x498a8cef, 0x7d5f11d5,
+       0x71b4e746, 0xf013935f, 0x179c547d, 0x8cea3fdb, 0x409f7d51, 0x4f3f2b2f,
+       0x8e30d05b, 0x321551ce, 0x9aa39d07, 0x8fdb9a36, 0xc828feef, 0xde33fb83,
+       0xe37af835, 0xe23ffdfb, 0xb6dcd3bf, 0xb6dfeb9d, 0x1fda16e4, 0x307f1e7b,
+       0xb65c6009, 0x717d265e, 0xce819b7e, 0x7018c90d, 0xe76dfc44, 0xf5fec5f6,
+       0x5bf3dfbc, 0x7e361db8, 0x70931dc3, 0x59b05dbd, 0xf5c46739, 0xce3fe2b3,
+       0x62f388b7, 0xfc8d1b95, 0x5fefacde, 0xac3d1477, 0xbf911efc, 0xfceb2d9e,
+       0xc92f6cfd, 0xffad594f, 0x2ed0ccf9, 0xefe9043f, 0xb9f88afd, 0xa18188fc,
+       0xb99d221f, 0x4f8ff944, 0xef871d70, 0x3b251ba3, 0x3a2a3b9e, 0x1d90f26e,
+       0xdf7799ed, 0x393d71cf, 0x3afba261, 0x1cf055ce, 0xef9328f6, 0xf781bf2f,
+       0xe3351c9f, 0x97e03cce, 0x05ef8479, 0x3be1116c, 0x473f336b, 0x2ab47597,
+       0xe7ae3e76, 0x7fdc7813, 0x9cccb541, 0x89f0fd2a, 0x37799f64, 0x1ee8175f,
+       0x598e856b, 0xb8f9cac6, 0xe562de9e, 0xd9bad8fa, 0x2fcde740, 0x760cfd08,
+       0x5103dd3e, 0xac5d6bbc, 0xe2ff4551, 0xf8b175a6, 0xc42b2853, 0xe265b439,
+       0x91b17a9c, 0x47bc538f, 0x8d546cb2, 0xf4a3f4a3, 0xdbc5dc6b, 0x67f135a5,
+       0x2317fd4f, 0x2fcf347c, 0xfc27a88c, 0x7e36e9fb, 0x7a8cfd0f, 0xee155aff,
+       0xaef51817, 0x8c72974c, 0x2d35333a, 0x0f643ef0, 0xd31fcf8f, 0x747f7e69,
+       0x35825fd4, 0x6cba91f9, 0xdfa07790, 0x4edc0d6d, 0x653ecbab, 0xb2a2cb2c,
+       0x5cbbe505, 0x27cb85c4, 0x75f57df0, 0xa3974719, 0x92cd4fbc, 0xdb981f88,
+       0x29dfc469, 0x8accbb07, 0x5905a779, 0x6802fdbc, 0xf758728f, 0xd04b972c,
+       0x1fd4560f, 0x830017ff, 0x8000007b, 0x00008000, 0x00088b1f, 0x00000000,
+       0x7cedff00, 0x55537c7b, 0x393ef0b6, 0x526d3479, 0xa0fa5b42, 0xb4db4e50,
+       0x9494b14d, 0x27457897, 0x880b5a3c, 0x46107006, 0xf4228206, 0xbd185499,
+       0x35fde338, 0x9c414415, 0x0e7c570b, 0x42d2d37a, 0x1429a2c1, 0x20d5b16c,
+       0xb47441d2, 0x3bd15ef6, 0x0f8afea3, 0x52d25a04, 0x8ef4f987, 0x6b5adfa3,
+       0xa126d39f, 0xdf7ef515, 0x37f5375f, 0xef6758b3, 0xbdeb1fb3, 0xce275ef6,
+       0x620a3b5d, 0xd67318e3, 0x319e920a, 0x6abd54d6, 0xc614f273, 0x2c8ba68a,
+       0x67e7c242, 0xf01192b4, 0x2c7133e6, 0xd3e3b187, 0x1939db3f, 0x74339dda,
+       0x7ff41d26, 0xc637d357, 0xf3ec6064, 0x991cc64a, 0x5ea5b388, 0x698459c0,
+       0x8c09e2c2, 0x060e313d, 0xead8ca99, 0x0c0599e6, 0xeccddf9e, 0xf8bfb19b,
+       0x7981f436, 0x47a20d5d, 0x2e9c0027, 0xc60dba8e, 0xc680f77d, 0x7e3b280a,
+       0xfdda8e83, 0x153da007, 0x4faed8e0, 0xdcbfc004, 0xe86e61a5, 0xc89771b0,
+       0xb2fff418, 0xc5f7a05e, 0x90597ee7, 0x3adaf804, 0x2983aac1, 0xad9aef8f,
+       0x1efec24d, 0xd9bc61c0, 0xbc6869cf, 0x7f78fbb5, 0xc5e433f8, 0xf186b633,
+       0xe2a635bf, 0x632e599b, 0x65a7cce5, 0x69efd0e9, 0x115da7cd, 0xf87bedbc,
+       0x1827b15f, 0xc60fad2f, 0x4bb6d9cb, 0x6f403462, 0x750ef3f0, 0xef386dd7,
+       0xb4f41bfa, 0xb637d9ee, 0xeb8f5e9c, 0x5c30d06e, 0xef1bece7, 0xba02ef8f,
+       0x963351ae, 0x8e90693c, 0x0cc788e5, 0x559d8eb1, 0xb31fa4da, 0x1c75909e,
+       0x3b8c6719, 0x63fc0d7b, 0x3df49b12, 0xb8dcee90, 0x628d8c91, 0x740b5dcc,
+       0xb67e0049, 0xf00f360a, 0x4765b8a5, 0xf3d616bc, 0x02fdfe3d, 0xf11db6f0,
+       0xb6d73c22, 0xbd2fd408, 0xad62c38d, 0x60aff16d, 0x0aafc51f, 0xb0696aa6,
+       0xb9ce32bf, 0x7df10271, 0xbfef3373, 0xb5e015b1, 0xac5f8fc3, 0x0ac6bedd,
+       0x65dd4a70, 0x72b864ad, 0xb17e651c, 0x739c782d, 0x8e857cb2, 0x2c1a2f97,
+       0x10bba46a, 0xaf7e4569, 0xadbcb817, 0xdc799bbf, 0xacc94f20, 0x87406042,
+       0x9013e644, 0xbd29c0df, 0x86fce41d, 0xcb55903e, 0xf17edd20, 0x1d5b0475,
+       0x6c99c740, 0x3b3e1064, 0x7fa82922, 0xa83529be, 0xecc4a6fd, 0x52b9f6a0,
+       0xdf3e105e, 0xff505d72, 0x4199d605, 0xe7d3adf8, 0x685ff506, 0xdb84185b,
+       0xeb8d4998, 0xba5cad6f, 0x999073f8, 0x041d2b57, 0x70287a15, 0xd8c54e86,
+       0xee0bc13f, 0xa036ec9b, 0x19288ccf, 0x3e397367, 0xd8d1f002, 0x06ddb37e,
+       0x20919d74, 0xc7016ce3, 0x05f69593, 0xe538ffbc, 0xfb785bfd, 0x2dfb4a35,
+       0xd2a27dbc, 0xafc72b7e, 0xf1eed467, 0x03776adc, 0x8ed1ebfe, 0xb6f8096a,
+       0x138aebe4, 0xfde9a023, 0xa77745aa, 0x45583f02, 0x18d36306, 0x0034875b,
+       0xed182ed6, 0x351a4a78, 0x7ff4aed8, 0xe357b255, 0xd14bdef3, 0x63226cb9,
+       0x51dfc80d, 0xe6321f3f, 0x716779a3, 0x1159b2d2, 0x33ea1f06, 0x0cf4d08b,
+       0x631a51e8, 0x0db18d82, 0x906f4831, 0x0477a213, 0x89a55f41, 0x8995ebe0,
+       0x94a8df04, 0x63336ad8, 0x821695ed, 0xf4ad2b27, 0x74e554fc, 0xda576f82,
+       0x5953be08, 0xd2a3b048, 0xe290504e, 0x9f1872d8, 0xa23eb1ed, 0xd5b87a41,
+       0xfcc2cf23, 0x7e40cff8, 0xd4c64286, 0x1722acec, 0xcabf79d0, 0x65f48ad6,
+       0x6ce98c6c, 0x5ef3e0d4, 0x815243a1, 0x46a7bade, 0x0f40eb58, 0xf37a0f8c,
+       0x4617a04c, 0x11bac1a7, 0xe59c6168, 0xbb43524b, 0xbad69d71, 0x029fda11,
+       0xf587ab73, 0xda991ad4, 0x1cc9f602, 0x34f1100f, 0xf7aa8d0e, 0x7fec0552,
+       0x1ff5045f, 0x0236c603, 0x196825fa, 0x7de0f7c3, 0x1ffd8116, 0xdfd81163,
+       0x684024fc, 0x10e1adaf, 0x37f48224, 0x43cde741, 0xe2e09efb, 0xd555d8eb,
+       0xee304921, 0x5c7ca9ae, 0x29f13158, 0x8119cc5f, 0x499fb2f6, 0xb8394c23,
+       0x005abd1f, 0x83d5e881, 0x2bb009df, 0x45034f59, 0xdb24f402, 0x01d4c113,
+       0xbd4d757a, 0xe09f0829, 0x3fea0c4d, 0x6a0a59b1, 0x8259f3cf, 0xb49f27da,
+       0x3b53e106, 0xbff507a6, 0x105b43f6, 0x61575d7e, 0xcfebff50, 0xfef083d9,
+       0x618fd81c, 0x94defe78, 0x9ff50428, 0x703ade0b, 0x89aac67c, 0x232df33e,
+       0x1bf79e83, 0x1b869d38, 0x78358177, 0xb71f855c, 0x7f1e0f4e, 0xdc782da1,
+       0x3d87cb1f, 0x906a27a0, 0x13d07aff, 0x4f41fb84, 0x0de720d4, 0xbf8827a0,
+       0xd0827a08, 0xcf827a0b, 0x209e820f, 0x827a04de, 0x13d011f8, 0x4f419bc4,
+       0x3d051e10, 0xa357e7c1, 0xef3cbb57, 0x53de7949, 0xed8cbcf2, 0x8d5d3a20,
+       0xefcb6f2e, 0xdfbf23bf, 0x079bef81, 0x30bcb0e5, 0xc835f543, 0xf398ccf3,
+       0x87582eda, 0x01575d6d, 0x6f7d4dc6, 0x8246ac8a, 0xc9cf0e6e, 0x5aab8c4a,
+       0x9456d962, 0x5bdf7b5f, 0xa70fc42a, 0xfb42b69b, 0x78ffe696, 0x4dfddb07,
+       0xcdf184a2, 0x459fcdeb, 0x5f3d38e3, 0x2c753247, 0x3459f7be, 0xdf654bc6,
+       0x42b7c230, 0xb9c5fa3b, 0xe5f3228d, 0xb57bbaa0, 0x5663ded8, 0xe3168f70,
+       0xa3437b33, 0x5a52f916, 0x6fed48df, 0xedc1357a, 0xed41d5f5, 0xb00fec26,
+       0x4689ed54, 0x56685e7a, 0xff51f3c6, 0xc3f73332, 0x6f8fea17, 0x5bd61ebe,
+       0x562ab8de, 0x3697f584, 0xd77f17bc, 0xe2ffd00f, 0x1c721791, 0x0b797ef0,
+       0x1c18678c, 0x2345bcaf, 0x65fd7ce3, 0x1882c6e6, 0x621a1ba0, 0x87acfcb0,
+       0xc01b676d, 0xd736942e, 0x577c6195, 0xc343b96a, 0x5ebd3e80, 0x01d710b1,
+       0x71062a7f, 0x9189995b, 0x7ef1e87f, 0x8c177d15, 0xc4f79afb, 0x7a87e82d,
+       0xe3478f5b, 0xd04dbdbc, 0xabbf803f, 0xb11c7953, 0xfc4b553a, 0x1e3a69eb,
+       0x16fb412d, 0x774e71ef, 0xfff68fb5, 0x02f78cba, 0x8b377a24, 0x5afa2e3c,
+       0xc6507c45, 0x9a33a173, 0x4619ed8a, 0x97a757dc, 0xaa7f77cf, 0x579b9fc4,
+       0x9ff5c6ad, 0x55365c4a, 0xae05fb24, 0xf1def01a, 0xc2b6ebf3, 0x30bd4a52,
+       0xf7f210ee, 0xbb6e3ca8, 0x69bf471c, 0x1a3ed43e, 0x30aa7ee8, 0x807c8f36,
+       0xaa636fdc, 0x6815fa8a, 0xe80ae61d, 0x8c9069d7, 0x160fcf28, 0xbf911ba6,
+       0xe7c423af, 0x0eb5bb85, 0x7c4d2580, 0x47534ebe, 0x675dca34, 0xe31164d3,
+       0x7fbc6551, 0x901de791, 0xb9be01ef, 0x9e454f89, 0x338e036a, 0xfcfe3fc8,
+       0xbd1354fe, 0xdef3ca77, 0x7f603b92, 0x2b28969d, 0xcb5da5f2, 0xa5fd708a,
+       0xbe7160e8, 0xa46ae4d6, 0xfddf3283, 0x2d7a3f32, 0xbfabe22a, 0xbbf72359,
+       0xf5058ea3, 0xd57e70d3, 0xe4c7af06, 0x3bfbf339, 0x73d97fa0, 0xbef8c322,
+       0x8f11534c, 0x20fcc7fb, 0x9d32dd68, 0xf8be34cb, 0x2d7900f8, 0x1bd0196b,
+       0x8b79c903, 0xf11227a2, 0xa763e153, 0x4aebe445, 0x2c1879d4, 0x8eb1acb9,
+       0xced41ae4, 0x4d3907ad, 0xff20ea8e, 0xdccffc97, 0xfc0ad54f, 0xfb2559b9,
+       0xb5c7154d, 0x3e2fd100, 0x7853fb27, 0x1f00999f, 0x00146c0b, 0x4fa614d7,
+       0x917c4155, 0x21e6362c, 0xb6a9753f, 0xff9854a6, 0xc87ec97d, 0x6489f142,
+       0x553e43b4, 0x66e0d97e, 0x7efed023, 0xdbce24f4, 0x047904df, 0xd11e5bcc,
+       0x9073ef3c, 0x282b7ecf, 0x7fb7ac08, 0x5ce28697, 0x00833b10, 0xe99acd71,
+       0x94be5f5c, 0x8844d31c, 0x54abcb17, 0xc832afb4, 0x5f98f4bf, 0x62eef6c9,
+       0x28adea63, 0x452765a7, 0x2be60453, 0x9d7fd4de, 0x86837881, 0x57a72af2,
+       0xff30fab0, 0x255a326b, 0x9deacfc0, 0x9d379869, 0xe2d3eaad, 0x3e21677b,
+       0xcbcf9c7f, 0xa7cb4f50, 0xd4519f73, 0x193da3bc, 0x57e60960, 0xafc8cfe2,
+       0x3a99f242, 0x8c75c7fc, 0xf21539fd, 0xb26f8c1a, 0x37c63659, 0x048ce2f9,
+       0x7f995fd2, 0x1710276c, 0x13f5a612, 0xdfa809ac, 0x3cd2d45b, 0xab6f77dc,
+       0x71f484c6, 0xc62a1db5, 0x22ca7b75, 0xafd82aad, 0xa251c373, 0x815fef63,
+       0xf65710ce, 0x33ca3226, 0x67a7197b, 0x6797336f, 0x44f04697, 0x9e20fbe0,
+       0xe0845e34, 0x5ea682a9, 0xd9347f77, 0x510ac621, 0xcb2dd7fe, 0x68bc6150,
+       0x80337203, 0x57b91447, 0xf5c0a5fc, 0x977546fc, 0x7bde1238, 0xe7fdc343,
+       0x48d353df, 0x9968e7ee, 0x46f5f103, 0xc62bf92b, 0x887de8aa, 0x52fe28a7,
+       0x67c435fc, 0xc7254f14, 0x147e497a, 0x6d50bc3f, 0xab8e04d2, 0x821bdfbc,
+       0x0580f32b, 0xe0ede3e1, 0xf8c0def1, 0xa6fc7923, 0x1e740f8c, 0x6afe7481,
+       0x70fc958a, 0x91f042ca, 0xa41577a4, 0xf59e8a77, 0x01cd5c80, 0x3810cab9,
+       0x1d76cabf, 0x728073a3, 0x00e741d6, 0xde7cd105, 0xf11f9c02, 0xd2130e48,
+       0xedffda04, 0xdb5e9c69, 0xa7d8a864, 0xc4b66913, 0x698d8034, 0xa469318e,
+       0xb792261f, 0x408cb2f5, 0x35d0927c, 0xf75d7d84, 0xf06e7e27, 0xda3dc815,
+       0x08575f99, 0xfe203992, 0x6ed3fd29, 0x69c34b2d, 0x18161d6c, 0xbd7188af,
+       0xc5d9e451, 0x1b95b2bb, 0x303992f4, 0x7fc3b2fe, 0x72c567a0, 0x279e117b,
+       0xd8e0fe40, 0x27992f10, 0x8f627bc3, 0x4fd73c16, 0x73577396, 0x73d3ee30,
+       0x0519f379, 0xffc9c60f, 0xf5e72694, 0xc8a7fcb2, 0x10ed58f2, 0xabdf683c,
+       0xee1355bf, 0x90782e5e, 0x8784bf07, 0x45e4621b, 0x99a2bf62, 0xbf47f41e,
+       0x8ef29404, 0x2fa4719d, 0xb9fb08d4, 0x2fffde4d, 0x0263bed5, 0xc684e7ec,
+       0xc2f98a9b, 0x2b08f289, 0x418cbf8e, 0x64f60180, 0x7820eb39, 0xd879ca3a,
+       0xc7bb8347, 0x81ff3c62, 0xf8c56743, 0x8d537aa7, 0x2e66ed11, 0x3cc264db,
+       0xff514805, 0x9f1fe4fd, 0x0b8830cf, 0x5f0aff90, 0xcbecd31b, 0x073f00d2,
+       0x749c493c, 0xefa5fbe5, 0x3e468e1f, 0xd0e6ff76, 0xda19db92, 0x3bb23e9d,
+       0x1a551525, 0xa8c41c9c, 0x906d32c3, 0xe0bf0abf, 0x1f1052df, 0x90630f61,
+       0x42cf622e, 0x177ffbd2, 0xabb1fa19, 0xf3a151f1, 0xac7e642f, 0x21f6e16d,
+       0xdd0abf94, 0xa21e676f, 0x5daff81f, 0x23a617c4, 0xffca147b, 0x0407f1ab,
+       0xcd363971, 0xe431d38e, 0xdb8ab26b, 0x2035e4ab, 0x3beeb02f, 0x0bada398,
+       0x8fa892e0, 0x32e72434, 0x7ccb969f, 0x167980fa, 0xdfff5258, 0x9a44e9f1,
+       0xe91a7b63, 0xfd4869ad, 0x32c7d50c, 0xe2aefac9, 0x67a43c6f, 0x3579fac1,
+       0xf85664bd, 0x8e7f802f, 0x7fa4d10d, 0x625d7f0a, 0xd5f7e903, 0xad18f3cf,
+       0xf059bcab, 0x847f52f8, 0x10b00a5e, 0x884363e0, 0x1afc2a3e, 0xf6291ece,
+       0xfb96b4ec, 0xa27df763, 0x8ff2f307, 0x1309df05, 0xceeca7da, 0xd282640c,
+       0x8eaae3ff, 0x38c0f7b1, 0xf0e4cf1f, 0x0159c634, 0xad922db8, 0xa49e23b4,
+       0x3f7ee373, 0xa167b216, 0xf858fe7f, 0x9e385be7, 0x5f1095a0, 0x04cb3096,
+       0xef0d69f8, 0xc57dd8af, 0xecbc7fde, 0x4fd439da, 0xbee06f60, 0x47a25c60,
+       0xa782fddf, 0x256a4406, 0x5f5c6a98, 0x0aa7acea, 0x27f9e0d3, 0x43cf4dbf,
+       0x05d6d87e, 0x2e7e878f, 0x3ce22275, 0xebf1baef, 0x9caacd3e, 0xfc0679c1,
+       0xf44b9cd4, 0xfd53f15c, 0xb25a1965, 0x2833ab53, 0x69922fde, 0x1ec98b6d,
+       0x87f829f1, 0x08fa4f7e, 0x5fa0ce55, 0xc8793fe9, 0xefa008e0, 0x4c3bf079,
+       0x3f67801b, 0x97e81296, 0x3479ed8e, 0xa451f913, 0xb9e2e775, 0x3feab9e3,
+       0x2edfa0a4, 0x2670f3da, 0xb67b8dc5, 0x5ffc6264, 0xa668f354, 0x0728f08d,
+       0x4e6a1fe5, 0xd703ee87, 0x101adeed, 0xf26526a7, 0xc47979f8, 0x1f8c7cb1,
+       0xf1735de7, 0xcbf41321, 0x4260adf8, 0xeb35f831, 0xddfd0878, 0x77970b0a,
+       0xec8233b6, 0x43678c31, 0x2f65d7be, 0x3d7d45a8, 0xb34cf965, 0x74bfe31a,
+       0x056bd135, 0x804b6cf3, 0x6088f676, 0xfd8163aa, 0xff6356c7, 0x6d049b55,
+       0xb1fa1c62, 0x97987991, 0xd247d2e9, 0x247cee3a, 0xaf9f1daf, 0x9f3f8078,
+       0x7534f3a7, 0x694f38e2, 0x37a475ad, 0x278c34f6, 0xd2ebf595, 0xcadef4b5,
+       0xcbc5026d, 0x4f193cca, 0xee0757c6, 0xfdce9753, 0x8db29b32, 0x32adcfec,
+       0xe07e6e5f, 0x611237bd, 0x1d6349dc, 0x7f6874c6, 0x66b389e7, 0x139f3c1f,
+       0xf3073e73, 0xe3ad0c86, 0x77dc62d9, 0xfb8ace8d, 0x2c9b9298, 0xdfff6026,
+       0xe11c7ccc, 0x3d5607ca, 0xf2768c5b, 0x73ca08e9, 0x13adf594, 0x83e61524,
+       0xbf6fabc7, 0xee76e913, 0x778a0889, 0x256755d7, 0xdfc81fb0, 0xa5ff02f7,
+       0x41f6c64c, 0x05f08efe, 0xd825dfc8, 0x44ca81e2, 0x94aa5fc2, 0x5ca5b208,
+       0xb899d6be, 0xbc6e193d, 0x4b9790c9, 0x3ca64760, 0x7c41e302, 0xcd9c6f38,
+       0xcaf40e92, 0xb35e5f18, 0x0657de45, 0x4ee79fbc, 0x98748d9d, 0x769ee5b2,
+       0xd2e31d0c, 0x56f2fe79, 0xa82923e7, 0x381f6bc7, 0xb4317cf3, 0xe7b74aaf,
+       0xbb11fbe1, 0x7e3e512e, 0x15e1e5bc, 0x1aa2ef48, 0xbc9fdf1d, 0x644f73ef,
+       0xe78b3c26, 0x286a6f75, 0x3aed763f, 0x8016fcf3, 0x47bb6d77, 0x3fef281b,
+       0x7113bf76, 0xba7f533d, 0x97470d9e, 0x8f67ae9f, 0xd53e90a6, 0xfce59e80,
+       0x3d733d7c, 0xdcf44550, 0x15ff6e9c, 0x8d39dbca, 0xebf5053b, 0x240df65c,
+       0x8136eef7, 0x5fd8a1f8, 0xf2a5fde5, 0xde554bfe, 0xce02336d, 0xc6432f15,
+       0xd63ef486, 0xc62665f2, 0x979b97b5, 0x47dc088d, 0xfb023c28, 0x35864c86,
+       0xda7dbd03, 0x69a7db2b, 0xd856e91d, 0x8f1534df, 0xabdb4367, 0xbdb255d2,
+       0xcf0ffc85, 0xc5ff1433, 0x0f78b43a, 0xf82ad651, 0xaa3ef122, 0x6af3a6f9,
+       0xd81257ba, 0x7de741a7, 0xe01a7d8c, 0xe75b8777, 0xc713a0d5, 0xe3da0f51,
+       0x31543f6b, 0xbdbf805f, 0xf9922bae, 0xc81de602, 0x114f6023, 0x4b7f1fc0,
+       0xd87d9052, 0xe7042e9e, 0x36aef013, 0x15f21fa0, 0x2dfc65ef, 0x9f8835d9,
+       0xfb3e72d7, 0xc47c408f, 0x389849cf, 0xe71e906d, 0xd173ba5b, 0x70f42b2e,
+       0xb926ed1e, 0xf87e6b29, 0x99f44092, 0x7b9d5e7b, 0xdb1cfa75, 0x7c8b9dd3,
+       0x9ae9af3d, 0x5f947986, 0xfc8b95db, 0xedc2be71, 0x93a54ffe, 0x11f8bcf2,
+       0x05d800d8, 0x3ca260a7, 0xa1ec5f2f, 0x927fdcbc, 0x96cee5e7, 0xfb7764dd,
+       0x88b9f95b, 0x9051d54b, 0x1508e780, 0xeed1da67, 0xfcf227f5, 0x21b7c609,
+       0xcba466bd, 0x97dd53fe, 0xdfec10b2, 0xe1390189, 0xd439da79, 0xe38e2d73,
+       0xc17b432d, 0x1d58a372, 0xf501778c, 0xd8af9e1e, 0xe519ba90, 0xd4679cff,
+       0x6fa3b424, 0x49ddfee5, 0x45af68e7, 0x638a4499, 0x7f0069e0, 0x11e1f607,
+       0x1e282d99, 0x80b6628a, 0x74ad2e7e, 0xa7bfc52b, 0x74c7ba44, 0xc67ae78d,
+       0x2b3d728e, 0x9b4c74df, 0xa35e3018, 0x7894f76c, 0x7f6bde70, 0x345d7d27,
+       0xf023b991, 0x14f597bd, 0x2031b0e7, 0x7a2f80ff, 0xf283c139, 0xdca8f7e0,
+       0x178bc81a, 0x87fee64d, 0x7ef1d21d, 0xa454d289, 0x6af31f87, 0x4c794fa0,
+       0xc00c6647, 0x2b89df23, 0x4e4f98ed, 0x2be01c02, 0xf2cf9702, 0x23991d45,
+       0xd0495cf1, 0xa4bcf0ab, 0x77b786bc, 0x54bc78aa, 0xf7dfc69e, 0x7b57dc0f,
+       0xde821653, 0x9cbdb6f5, 0x5be02772, 0x9c35be0d, 0x7c4cbe0f, 0xb99eda0e,
+       0x46efe608, 0x5cf74d9f, 0x5ed08be5, 0xdc151b75, 0xf78c71c9, 0xb5cd9ee9,
+       0x5baae508, 0xbc15e0af, 0x5c64105d, 0xe5c15f79, 0x8c8547f7, 0xb4859237,
+       0x0a4ff487, 0x3dca35c1, 0x58ff3c9c, 0xb517fefe, 0x7bc22cf7, 0xcf3af9b7,
+       0x57f44ac9, 0xd218692f, 0xf0e07f55, 0x697fa459, 0xb33bf70b, 0x39ee1c0e,
+       0xd872f288, 0xb1e6f748, 0xe3e254e6, 0xdbbd96c6, 0x375ca126, 0xada073f2,
+       0xff3fef0d, 0xc3a7ea3b, 0x57183163, 0xe69eb759, 0xebca2f9d, 0x1e39eb66,
+       0xdfb3b725, 0xb2847c72, 0x3c71dfaf, 0x6b7fb796, 0xa75a17fe, 0xfb81f0ff,
+       0x9fa05e50, 0x17a5e29b, 0xa2605e40, 0x73d94392, 0x1bf59e30, 0xfce0563b,
+       0xab3afdce, 0x09e7c25b, 0x95be30b3, 0xa4dcfccc, 0x14f6fc78, 0x4754a7cc,
+       0x1df9edf7, 0xd7efbb9e, 0x2ba139d3, 0x12a5db86, 0x3dda7ab1, 0xf7bb3f24,
+       0xb5f701fc, 0xf6e74f4f, 0x1edcd1c5, 0xa0c9ef15, 0xfe579ef3, 0x940ad9f1,
+       0xd7717c83, 0xd7fe7c1e, 0xe90abd5a, 0x8db5a9d4, 0x4cfd01b8, 0xa9e286a7,
+       0x3e2f1962, 0x13d7cb1d, 0xf24055d5, 0x653db713, 0x4948c811, 0xe0b7fdec,
+       0xdb8be7ba, 0xce7f479f, 0x0ce8eaf6, 0xa03efceb, 0xbe77bc2b, 0x2da7434e,
+       0x35467dfe, 0xb0b76bca, 0x38b3c57d, 0xd7ef1d7e, 0xf44edfad, 0x3165d776,
+       0x31fa0f9c, 0x16ea9f3c, 0x3f3d0476, 0x1737b75f, 0xfb0bade3, 0xa5dc53e7,
+       0x97a293e8, 0x20bab525, 0x293fc7fd, 0xf963f31e, 0x8666e4cf, 0xc2e9fc80,
+       0xcffc6791, 0x85f5e806, 0x0b4f8d06, 0xb1d62a34, 0xa7af784d, 0xf24963e8,
+       0xbfb8854d, 0xe6755512, 0x278bc03a, 0xbd40ad77, 0x1167af3c, 0x2defd089,
+       0x2e0f3f15, 0x885aaa69, 0xf5b87b76, 0x7c799b14, 0x9f913979, 0xd66e5f97,
+       0xa9cf027b, 0x9547e143, 0x3d5b7a4c, 0x42baff88, 0x19473e47, 0xb7ad2def,
+       0x670ee30c, 0x9fc3f70c, 0x3306ff40, 0xee6661c4, 0x086e56a7, 0x1cdcbfee,
+       0xda9dcf43, 0xcbb44cae, 0xcccbf8ca, 0xd4cf6e26, 0x9fe8995d, 0x7923df43,
+       0x82f57b47, 0xa4aaf640, 0xf7433849, 0xf8d248c7, 0x44967a41, 0xee623db8,
+       0x9c487cd0, 0xc601f326, 0x77ac87fa, 0x9b7a0d25, 0x8d29c61e, 0x7f468aec,
+       0x8aec6655, 0xff6f73c6, 0xc8d59151, 0xc6538bec, 0x4f9c1b4f, 0xbd8b8fc9,
+       0xa87e9b1a, 0x183b60f9, 0x7fc5adef, 0x32622903, 0x3514deb8, 0xcc7cd147,
+       0xe50d35d4, 0xf05768b6, 0x534fb87b, 0x9bfa3e80, 0xc607c777, 0x75c7bfa1,
+       0x8677de53, 0x1ff7a6f4, 0x1ca0a69f, 0x26d8a894, 0x20bee73c, 0xc0617bf0,
+       0x82f85ee9, 0xf25e5e7c, 0xca244337, 0x65cb85cf, 0x01fec7a4, 0xd928fb3b,
+       0x6762bf07, 0x15c70d59, 0x7076cb3b, 0xeecec07c, 0x3762b8e2, 0x42a3fe95,
+       0x1d0a4fde, 0x9077a94f, 0xe6ed93c7, 0x6e7abaa2, 0x7f7e4537, 0x4c6b76c7,
+       0xfce27f3c, 0x19d32b5a, 0x95d3b412, 0x123577e4, 0x19c5b1fa, 0x76a579ca,
+       0xa0e27e90, 0x7499fa3e, 0xbbf509a0, 0x10f940c8, 0x070d15c4, 0x59791cf1,
+       0x07ef15bc, 0x9caee943, 0x7cc5c777, 0x7cf906b3, 0x8af1d6ab, 0x7269ef19,
+       0x82afc8ba, 0x74bf90b6, 0xb8a3aabe, 0xb7d357aa, 0x965fed07, 0xf61af1d6,
+       0x6c76d32b, 0xea4b029e, 0xe3b574d1, 0x943cd091, 0x5c43b257, 0xbb39fd5e,
+       0x39527ce9, 0xe6577f2f, 0x5ea70323, 0x7025f28d, 0x7cde3939, 0x57b46de8,
+       0xf2748efe, 0x03e45703, 0xa3478fcd, 0xe210f9dd, 0x5c407714, 0xbdaae1fc,
+       0x14b50f74, 0xde011fef, 0x7f7829b9, 0xa62edffd, 0x0b6d8838, 0xbcf28e78,
+       0xa50f1833, 0x2fb5ca0b, 0x24dc8f48, 0x9ba5dfc7, 0xeace9608, 0x061d2270,
+       0x8b8045f0, 0x21ebf801, 0x667f4878, 0x1e6266f7, 0x08d61dfa, 0xc6ca3d01,
+       0xbc534efa, 0xd0c3407a, 0xbf046c3f, 0x28e1f849, 0x1d532baa, 0xc718bf00,
+       0x9bfa22fd, 0xca0ee8d2, 0x7587fceb, 0x60f0df74, 0xb82997cb, 0x8ba6bf7f,
+       0x96d295f2, 0x9e31e397, 0x344b358d, 0x78dff83e, 0xdc3d8fba, 0xb6318f12,
+       0xe54cbcf2, 0x94eb94cd, 0x28fed172, 0x5f45cbcf, 0x54bfae26, 0xf6c5c8e8,
+       0xd453b458, 0x7111701f, 0x1328fb46, 0x2d60ddb8, 0x5089f922, 0x706745be,
+       0x25f60bbb, 0x8f11ee97, 0xb15978f2, 0x605f6427, 0x79f1d7bc, 0x261fb70e,
+       0x5e14fce5, 0x31bb462d, 0xa4d99d84, 0x41564dd8, 0x06644d79, 0x3ef2b75f,
+       0x30f3cb8d, 0xd2be776a, 0x83969b9d, 0x7bf249ef, 0x7d2cf601, 0x1da13ed0,
+       0xf23b2449, 0xf61e26a0, 0x60bcf255, 0x14af08dd, 0x802aaf2f, 0xfaad6cee,
+       0x2fca029e, 0x19ee9b99, 0x8575d742, 0x7f39997e, 0xd2f3e44b, 0xbcfc3d92,
+       0x9f8682f4, 0xf2bd832f, 0x3b5afda1, 0xf500aaa7, 0x72b8eeef, 0xdcb9e06d,
+       0xb35fc6d5, 0x5b5f1833, 0x30905551, 0x6c979e84, 0x8a3ed1d8, 0x1d17e10d,
+       0xd2f105d5, 0x7595cf95, 0xeb2bd05f, 0x1519a59c, 0x55a58f48, 0xae00a305,
+       0xf4b9f88d, 0xd0befbe0, 0xdfa1f3a2, 0xf9d2fa06, 0x575f8de9, 0x5c3f9d04,
+       0xe662bc6d, 0xe1c2f3a1, 0xcb0a1fd6, 0xcc69df04, 0x57e818a3, 0xe819e91d,
+       0x2f7cc04d, 0xb4fbfeca, 0x9e78a04a, 0x871aad15, 0xac7301f9, 0x6b7e871a,
+       0x0c0178b8, 0xdd1568e5, 0x8209ba49, 0x0eb0ae1e, 0xffa50f41, 0xbcfc191d,
+       0xaf5945e1, 0x7d2fcf46, 0x9fb420e6, 0x19456c96, 0x5c28a8c0, 0x8945e623,
+       0xda183c23, 0x7203be53, 0x036394ed, 0x5f7cab43, 0xbb522858, 0x586459ab,
+       0x8d12caa7, 0x57d80c9e, 0xf54edb21, 0x7798f37b, 0xa9791506, 0x3d7f7ebb,
+       0x4d7fcfb4, 0xd195bc9c, 0x37e50f7d, 0x330e9105, 0x5fb055c6, 0x4ef43f39,
+       0x7e701859, 0x37f647b7, 0xfc814433, 0x14525f40, 0x5dced39d, 0x503cbe5a,
+       0x10853b4e, 0x72fa79ba, 0xf5f1bf29, 0x6dd206e5, 0x15516bc9, 0xbcc80e74,
+       0xcc049653, 0xaf0672f3, 0x696af89f, 0xb8979d06, 0xd27bf32e, 0x27dbf17c,
+       0xd7588f31, 0x80af7906, 0x407ea7e3, 0x2f906675, 0x0dd09c62, 0xcc1ce9f9,
+       0x66cc1df5, 0x61387b43, 0xae7be514, 0x7ac30203, 0xae8b6733, 0x9d9bef06,
+       0x8c78ae9a, 0xbf34b673, 0xec3f45af, 0x569efc3a, 0x92abbcc2, 0x2637f5c9,
+       0x05d7d215, 0x5bbf40ec, 0x01f59cde, 0x93f2b5da, 0x5cb0d4fc, 0x3fdd1efd,
+       0xce14b9e2, 0x48d4da57, 0xcc658df7, 0xd65f7247, 0xf6ff9c10, 0x075d0e27,
+       0xa76cb2f4, 0xd3ee7c14, 0x225fcf3c, 0xb72f0ab2, 0xce9f148b, 0x73a04c4d,
+       0x38f7c1d8, 0xf7626d7d, 0xdb6e7843, 0x0558269b, 0xd237aa18, 0x26e309bd,
+       0xc73f2677, 0x85f57ded, 0x7ce86b29, 0xeb0533c4, 0x73e57ba4, 0xec8fb9fc,
+       0xeb018b50, 0xebcadb99, 0x59237a17, 0xbbe211d1, 0x23f20c63, 0x92ded52b,
+       0xb6967181, 0xf1eb9def, 0xaf8e59de, 0x57b1f743, 0x253e6fbe, 0xbacae9c7,
+       0xf32727e7, 0x21e618f3, 0xf3976a39, 0xda0a9b62, 0x4cd3ee03, 0x77528299,
+       0x046befc7, 0x9c3e8f7e, 0x17bd617e, 0xbd623bd6, 0x72fdc217, 0x7bd6245d,
+       0x5ca2fe21, 0x5ef58917, 0xbdeb1cf8, 0xeb926f10, 0x0bdeb122, 0x42f7ac71,
+       0x8bae5478, 0xa54b853c, 0xbfd2eef8, 0x3edb9e61, 0xfc721f10, 0x3e084c74,
+       0xe9ffb83a, 0x1f182118, 0x33ff502d, 0xcdfe9775, 0x1675839d, 0xf0dfd926,
+       0x9ce50b3a, 0xb670b3ab, 0xb1f20779, 0x3c24c275, 0x69266747, 0xb74bea04,
+       0x56ffe7cc, 0x1da02fdb, 0xe47d1160, 0x64c4e797, 0x78bb408f, 0xba62e4f2,
+       0xd38feb87, 0x93bc3e91, 0x7ec3e8ee, 0x9e6f98ae, 0xeb06cc3f, 0x265a66e6,
+       0xfc029a6f, 0xe4106998, 0x44fb7238, 0x059f72bb, 0xbadd99fc, 0xdb9a8a6a,
+       0x994e130b, 0xc6ad962f, 0xe925d771, 0xaa1e6327, 0x1dfc734b, 0x5fe855c7,
+       0x19ad7a30, 0x48d76fe7, 0xeabc601f, 0xf3cf13fe, 0xa501fa95, 0x33a927df,
+       0xdef099f5, 0x26fa4b5c, 0x2819ebcc, 0x4dbc8a1f, 0x3e501acb, 0x6128aa6c,
+       0x4933d923, 0x67d5fb8d, 0x92cefdf2, 0x4f80fdf8, 0x6063a92b, 0xcce45f7c,
+       0xdb77cc38, 0x949fbe65, 0xe64a7ef9, 0xcdd1d63b, 0x3a3af351, 0x87475884,
+       0x20ea10f0, 0xdd2fbfcc, 0x7149931e, 0xd20a5f72, 0x984ba95d, 0xedc67a87,
+       0xf5d20a4f, 0x27c72c90, 0x99d3fb64, 0xefe24f66, 0x54acf8f1, 0x96e81fae,
+       0x7d9473cf, 0xbe0def2a, 0xfb05e7cf, 0x6ffee12d, 0x5f645510, 0x5b38e543,
+       0x788efb96, 0xbd4abde3, 0x3739c608, 0x261fdc88, 0x41dffaab, 0x6f1c93bb,
+       0x90c23694, 0x78a3b3f9, 0x09bd36bf, 0xdb6f6c4d, 0xddce7437, 0x296190fb,
+       0x30314fbf, 0x3da11efc, 0xe04d4271, 0xe51fe979, 0x908fc079, 0x9a2cba5e,
+       0x3923f61f, 0x423f01c6, 0x144e66f9, 0x9bf923dd, 0xa4fca2bf, 0x09aa75b7,
+       0xe1dfd4e5, 0x715fa031, 0xc4ffe3fd, 0xb7f0bfa3, 0x6cf5417e, 0xa4bf6ffe,
+       0x722db73a, 0xcdebe1bd, 0x87589d72, 0xbde7c464, 0x60159f85, 0x1c32adbf,
+       0x3cfc23b4, 0x686f814f, 0x681de66c, 0x51509ecf, 0x8dd8a2fe, 0x98597d50,
+       0xf78e5239, 0x676831ec, 0xc4ec5f40, 0x597d01b7, 0xc1798316, 0x12917da0,
+       0x132ea87e, 0xcd598bed, 0xb4420bed, 0xb733662f, 0x7da3882f, 0x05f68841,
+       0x417da39f, 0xe20bed1c, 0x47105f68, 0xed1082fb, 0xebff3e0b, 0xd3a75e52,
+       0x3f29810b, 0x5c5035c7, 0x7f8ebebf, 0x8dbeb27f, 0xafaddbdf, 0xac0ea816,
+       0x94dfe607, 0x509d4439, 0xe4275c93, 0xa2f741dd, 0x15a2c3ae, 0xd6017859,
+       0x6dcf09bd, 0xd0277d35, 0x051ab82f, 0xcf84956b, 0xb63ad297, 0x60fd4eb4,
+       0xd3af3e39, 0x2fe85558, 0xa3c72f5a, 0xad692bdf, 0x2735ff23, 0xbfcb4da1,
+       0x9e181197, 0x71d12f1f, 0xe11728fd, 0x3fba24e9, 0xae5ffb26, 0xad73a0eb,
+       0x0a417ad2, 0x35c08efc, 0x7fc512fd, 0xf2b9fdca, 0x57b94bdd, 0xca0ead2f,
+       0x6ebc6c9f, 0x4aff718b, 0x9e406579, 0xc3277cab, 0x74d56fc4, 0xc08afe3f,
+       0xd7ab8562, 0x36b49573, 0xaffac66e, 0xb4767bd0, 0x16d75424, 0x44febf72,
+       0x95d75ca6, 0x6f30f2c7, 0xf5627c2e, 0x5f30c381, 0xe51d76ff, 0x774f609d,
+       0x409efea1, 0x9cba0439, 0xb9d3d368, 0xb23be7db, 0xde1f1046, 0xf6489914,
+       0xb7d90c72, 0xf2811a75, 0x3597b031, 0xc2ecdef8, 0xceaec8bb, 0xfc8abb06,
+       0x93eee454, 0xca2d7b54, 0x1209bae7, 0x1d7cb9f9, 0x93c697bb, 0x9200c5eb,
+       0x146fe5de, 0x57c02a3c, 0x2f7d2b31, 0x86c812b4, 0xc6af50f1, 0x75d608f0,
+       0xaebc64ad, 0x75a39143, 0x8eef943b, 0x577d10c6, 0xd95cf4c8, 0xb06fc7fa,
+       0x1d2ee36e, 0x56490f3f, 0xe4803af1, 0xe7bebcad, 0xf5e0e66e, 0x8b4d9872,
+       0xdabd2f94, 0x511dcf05, 0x79f85263, 0xe380948f, 0xa1a53aaf, 0x84fce33a,
+       0x8a0e9905, 0xfd50e64f, 0x43bbe086, 0x1f9afefc, 0xeb83878a, 0xec684e37,
+       0x3b573df4, 0x73d925ca, 0x9553c107, 0xbb150445, 0xf63fd4ad, 0x88dcbdb6,
+       0x0cbbe7f3, 0x62b7a456, 0x83a8ae07, 0xa950e48c, 0x100b1c83, 0xc0cc0aeb,
+       0xda0c5363, 0x44ec8967, 0xb273aab2, 0x1bfffb84, 0x3f200eff, 0xe30f2da1,
+       0xfc7974a6, 0x43fd92d3, 0x9a2d9fe4, 0xbc3df1b9, 0xf40eda4f, 0x080dc02c,
+       0x6d7b2f18, 0x6dbfc622, 0x1a46a982, 0x78ee8eca, 0x5c97eb08, 0x7184c166,
+       0xf6e44159, 0xbf1878fc, 0x8ad52d20, 0xccd5dc76, 0x403f2de3, 0x3debf7ce,
+       0x55dfc0a2, 0xce9c63c7, 0xea9596f9, 0x351ccee8, 0xacbe7cf8, 0x5fadbd4f,
+       0xabe3faf1, 0x38b563c7, 0xade99bbe, 0xc8f8f275, 0x8cd7f9f7, 0x914cb8a5,
+       0x8486fe9b, 0xef9b941a, 0x7cbbff65, 0xcc1a7bf9, 0x1cd33b03, 0xaff38dff,
+       0xa1e97d58, 0xd0e7da78, 0xd3a9507e, 0x4a83f50f, 0xabfff37c, 0xcaedff3e,
+       0x54ef820a, 0x51d8206e, 0x51f6a6e9, 0x735cfc59, 0xfc0ab8b8, 0x10d65c43,
+       0xbf4294f1, 0xe4aae221, 0xae3ca9ac, 0x89473cc2, 0xa388aeab, 0x0155df40,
+       0x75bb3efa, 0x608f9de4, 0x6b53b3dc, 0xeb0090c5, 0xc81bd7a8, 0x4d64643e,
+       0x529e2a1d, 0xf8a069e8, 0x27e99fab, 0x2cb3fce1, 0x1fbc6ae9, 0x0425989f,
+       0x3fa80be5, 0x1fd46fb8, 0xea3fa884, 0x39e7b880, 0x14f6a82d, 0x29b82f1e,
+       0xbf13d05e, 0x5d815737, 0x662efc01, 0x3d2bb20a, 0x31857621, 0x1d70affb,
+       0x9d795a6b, 0x3a5f5297, 0x93d7c00b, 0x5e33b086, 0x46c6676e, 0x3ce1f77a,
+       0x54919d63, 0xc3427caf, 0x16c4eee5, 0x9ab82f5e, 0x8ff7f9d9, 0x689bda57,
+       0xb15defa4, 0x01fc9f7d, 0xa8f5dffa, 0xcd9ee281, 0xfda66b49, 0xf8cdec4f,
+       0x7f0f4e2c, 0xe7de6fa5, 0x22731f20, 0x905cf7f9, 0xee2859bb, 0x7e924555,
+       0x8ed97e40, 0x6bac57df, 0x8ed0f211, 0x77d9d1cf, 0x6a9d3ae1, 0x27167ebe,
+       0x3baa27df, 0xbf42f78a, 0x2b64f8ce, 0x1263cfe6, 0xffac308f, 0xe61577ca,
+       0x64ecbda0, 0xbf7be9db, 0x5dc73a8d, 0x39c5e7c8, 0x7b9d0215, 0x5897faca,
+       0x95b35518, 0x153591f8, 0x2708bef9, 0xe6e473a3, 0x2e8f98c5, 0xf1c10a8a,
+       0x8dce8b1e, 0x6c78e55f, 0xd2827b48, 0x1cc9e32e, 0x2f356777, 0xd2e573c6,
+       0xf3e9bd7a, 0x91cffaa0, 0x39abb841, 0x6079f4c9, 0x03fe2a7d, 0x822daecf,
+       0x93dc059a, 0x078e0837, 0x85e53f70, 0x2e39f917, 0x5abf23eb, 0x7d112595,
+       0x7ccebd47, 0x737dff28, 0x902e748d, 0x87915b10, 0x472c09e7, 0x52fd8a9a,
+       0x17147d34, 0x96ab7ef6, 0x8be8b3bf, 0xef202dbe, 0x7f95be7f, 0xcfca117f,
+       0x7b970b3c, 0x0db0d997, 0x8c4ce6f9, 0x7ad82088, 0xa616e289, 0xdef19bb6,
+       0x3a0af214, 0x3f7d08b7, 0xb7efc2dd, 0x656b3753, 0x90ff813a, 0x8e337ae4,
+       0xc674d9bb, 0x948befaa, 0x266ccae9, 0x866d3ff8, 0xfcffc64a, 0x0113e638,
+       0x7fd86dfd, 0x6b5f9db0, 0xf77bef2b, 0x26f8fbbe, 0xca1f3cb3, 0xf1461ad7,
+       0xa0f7e873, 0x06625a9f, 0x2e5033ea, 0x53d38b9e, 0xf7583f9e, 0x6ba0ebcf,
+       0x7f3d72f5, 0xf83fbd68, 0x8ae7f43b, 0x725f7b9f, 0x52bf1d50, 0xf9d4aff7,
+       0xcd2f3127, 0xe027b4a7, 0xda88baed, 0x3847a1db, 0x2193f303, 0x659376e8,
+       0x91647fe6, 0x17d9b8de, 0xfee7c1ea, 0x810de8a8, 0xe486727c, 0x66593737,
+       0xfbca7bd1, 0xb1661be5, 0x26e3262f, 0xaccc38e5, 0x14e7ff22, 0xd9021bd9,
+       0xa28f5e11, 0xec1a77bc, 0x9ff7ce3c, 0x7e11f760, 0x0bfef608, 0xc19fe7a0,
+       0x08fc21de, 0xff3e1dec, 0xc21dec04, 0xf803f02e, 0x03f053fc, 0x61dc9708,
+       0xe57a829c, 0x5f62ae6a, 0x3b3dd704, 0xd3bfe302, 0x97968733, 0x9e2a598b,
+       0xdd0ea5bf, 0xe9e596ae, 0x6f9c8df4, 0x4f3377bd, 0xdfc92a4d, 0x86178c26,
+       0xd7b7eefb, 0x5afbedc8, 0x37bc1cf9, 0xb2e7e389, 0x473cfc34, 0xf7c69ec5,
+       0x3af066d7, 0x2b8ec539, 0x1fc82af9, 0x63acaf8d, 0x29d79c9c, 0x55663cfd,
+       0x0a48f7d0, 0xfde1639c, 0x5f313e48, 0x0d4c7947, 0x44a74f90, 0x172a19f2,
+       0x1d385a9f, 0x772e3acc, 0xa09768c9, 0x9e82727f, 0xe361c6e2, 0x51ef90b0,
+       0x394f90ae, 0x32c64b1e, 0xf3e1988f, 0xf7aca363, 0x7e3f3a3f, 0x943150d8,
+       0x3ff998fd, 0x3e80ffdd, 0x8affef06, 0x8e876b7d, 0xf7db873f, 0xca2bbd40,
+       0xc1f610cf, 0xb81f603a, 0xb164dcfc, 0x1d4cb78d, 0x05483bfe, 0xebe0cdae,
+       0x6a83e456, 0xc5ee3094, 0xee0fa57d, 0x91fd6067, 0xcb5bfb21, 0x94225ee8,
+       0x13df018f, 0x05fafb29, 0x1ba147ae, 0xa38a3e58, 0xa81994c7, 0xc590fbce,
+       0x4769efc4, 0x0762b97d, 0xf645feb4, 0xf1507f13, 0x6ec51a7a, 0xc4173c0f,
+       0x82730b95, 0x513339ec, 0xfd23ad9c, 0x7bbc41f2, 0x4f7830d0, 0xb7f7eca9,
+       0xcbf63eb2, 0x6fffb5f9, 0x8ff65f3c, 0x73dfa3ee, 0xefcd3ff0, 0x9bc460d1,
+       0x6eee0eb1, 0xcc253bf9, 0x9e5ad5af, 0xcf21ab37, 0x7d2f7bf6, 0xae01f782,
+       0xaa3c4467, 0x9733e262, 0xd3fc5097, 0x7e6131a6, 0xc7e9f1be, 0x9dbca24f,
+       0x7424126d, 0xd826fed9, 0x3ba7e636, 0xf43d1e8d, 0xe7e2682f, 0x45eb6b27,
+       0xfcff048f, 0x696efe42, 0xfa1a33f6, 0x234d699e, 0xfe3977af, 0x6bca7af4,
+       0xcf207acf, 0xc40b7186, 0xbcf1da07, 0xfe39e4be, 0xfb2512bb, 0x1efc5adc,
+       0xa05aa4af, 0x97c9537c, 0xaf75e4cb, 0x6c7909d9, 0x30483dd0, 0x14bccc5e,
+       0x06d4955f, 0x086b2f3f, 0xb5ef7fce, 0x94d77c0c, 0xf9c8ebc7, 0x3f62acbd,
+       0xdcab8caf, 0xfac1a7c4, 0xe3c6bfeb, 0x76d8be79, 0x0353e539, 0xf8ca17c7,
+       0xca2fc019, 0xfacaf6e7, 0x62e8fc95, 0x85e29b12, 0x2e313afd, 0x50efe495,
+       0xc8aedf81, 0x1f485bae, 0x8c268a8f, 0x8b34b6b3, 0x7967a46e, 0x7d377eab,
+       0xf4e78537, 0x3df3a446, 0xc26ff7e4, 0x273c267b, 0x83b67c84, 0xce83a6e4,
+       0x6fad99e5, 0xb697dd0d, 0x4fe84de8, 0x683f479d, 0xfd06efc7, 0x57860587,
+       0x7cefcaf8, 0xd78679ac, 0xcddfc199, 0x229afdf8, 0x5f006217, 0x436bef91,
+       0xc33e2af8, 0x8d35f3f3, 0xdedf2823, 0xf568b4f8, 0x39785ca1, 0x17be157f,
+       0x3ce8db88, 0x7c48f805, 0xdd4cfd9e, 0x07289193, 0x05fdf8fb, 0xfdf101c8,
+       0x77ce2eec, 0xc443db6d, 0x2cb57f77, 0xf7fc2d07, 0xf8ea4a49, 0x17e81079,
+       0xf1abc9f9, 0x5f7c6aff, 0x7c83db20, 0x3889c671, 0xe5ef778c, 0xe988adf3,
+       0x9a07bf2e, 0x20bb993e, 0x7975f515, 0x26c6eee1, 0x07891980, 0xce621999,
+       0x51db3a53, 0x5cb9e04b, 0x79d79e9b, 0xca045103, 0x4bfae433, 0x53dd4ce9,
+       0x5e47af68, 0xfe31f143, 0xf79c0445, 0x60cf3f00, 0xb23bd09e, 0xd8cbc0fb,
+       0x7e8e946f, 0x55bca58f, 0xa2e5d3e7, 0x9bf2e45f, 0x715bedaf, 0xafddc60f,
+       0x433ee8ea, 0x45dff1b0, 0xe3fd6d28, 0xc84f7887, 0x416df29a, 0xff209bbf,
+       0xfe2941ae, 0x37b602ae, 0xe8067a68, 0x3fa6ed80, 0x165d7bd1, 0x9e92875e,
+       0x71848370, 0xcc65c6ec, 0x943e9911, 0xe764679d, 0x8729ef95, 0x3986c38d,
+       0x2fe2506f, 0x12331ee6, 0x7df94cf5, 0xad0ec505, 0x3c5bbf95, 0x7529df71,
+       0x96afd22c, 0x714c8eff, 0x389fd82b, 0x7922df3a, 0x38aee73b, 0xbf9782a2,
+       0x468ab944, 0x0e68fab9, 0xc7db2ff6, 0x3c0683fb, 0xdf871919, 0x4f286b29,
+       0x7937d01b, 0xa3df867c, 0x05f3bb40, 0x0ea6c581, 0xab6a2f61, 0x421e8f37,
+       0x2e214a6e, 0xca8745c3, 0xb829b38f, 0x768377df, 0xf8f7c264, 0x9726567d,
+       0x662cf72f, 0x0d5ffdc1, 0x40d8f92a, 0x947e067e, 0x19e660ea, 0xc972df29,
+       0xd5ced2e7, 0x51273a26, 0xed538dfc, 0xf299b33d, 0x43972332, 0x63dfa335,
+       0xb68d54e9, 0xef380d6e, 0x4e979ce8, 0x6fc59fdf, 0xdc70faf4, 0xb58205be,
+       0x44e69a06, 0x5f2efcf1, 0x0bdb2f65, 0xb8a86fed, 0xf30e7ddf, 0x17fd1137,
+       0xff419397, 0x93cfcfc6, 0x7f3c8d0b, 0x9adca8f3, 0xa61df489, 0xdd94eb1b,
+       0x2bd52d76, 0x1d291ced, 0x677c0268, 0xefd90e71, 0x73f1df23, 0x5a65bef4,
+       0xf33bf3f2, 0xae51cbec, 0x4f1b2e77, 0xd208afed, 0xe33f7863, 0x7da48e2e,
+       0xcfc85cec, 0x4c2e771b, 0x5967f6a4, 0xdf1a955f, 0xd9fbe6ab, 0x3a04d8f9,
+       0x39d38dff, 0xbef1b372, 0xd8c7be58, 0xc24b6a99, 0x0527d37a, 0x71bbb2fb,
+       0x1a0609bc, 0xe24590ef, 0xc6cb12f7, 0xe907b63f, 0x8a9a4634, 0x7e0fdb76,
+       0x7ff00def, 0x4dd86c7f, 0xf71732f5, 0xc705b99f, 0xe4057d2f, 0x37f7c60f,
+       0xebbe8318, 0x66efbe57, 0xc5b4df6a, 0xb0bf40c6, 0xbcb5d791, 0xeaf6e464,
+       0x3373cea0, 0xe4725fbc, 0xebb45cb3, 0xdafb07fe, 0xdaee3193, 0x243af02f,
+       0xde2e5777, 0x87a89647, 0xce6faf8e, 0x4f4bf1e6, 0x8c52d44b, 0x63fa84e7,
+       0xe252df54, 0xe7435dbd, 0xd9bf7254, 0x866e3cd9, 0xed1f747e, 0xdfc827de,
+       0x05a6f8bb, 0x752b5bde, 0xb8fb3dcd, 0x6b34951c, 0x92e47be8, 0x51ff46fa,
+       0x59d43fc4, 0xf55d7c51, 0x783ee897, 0xe8074bf6, 0x3fef02de, 0x473a08de,
+       0x3b39dfe6, 0xaae63b65, 0x395ec917, 0x77f9ca9b, 0x19e2f55f, 0xd28fbdc2,
+       0xf15d34ef, 0x27731d5d, 0x5f4912ab, 0x29e6b193, 0xa5f4bdb4, 0x206e23b6,
+       0xbda1e961, 0x2ee7e8d1, 0x2345d474, 0x55dc61dd, 0x5e7c11da, 0x2b883dfc,
+       0x7d05b5c7, 0x6ef2e69f, 0x02ebc4b9, 0x845fc8bb, 0xff80bff6, 0x6f7f3f00,
+       0xd91dfcb6, 0xf25aecb5, 0x14b1f5ff, 0xa6fac157, 0x13b77e05, 0x0f4bffea,
+       0x0dde7e5c, 0xbb073ded, 0x96f5c79f, 0xd515f77d, 0xf557b123, 0xdae6b754,
+       0x73f93eff, 0xcd7fbde5, 0x7fa871e6, 0x583ddedf, 0x2fffea97, 0xf347159d,
+       0x22997db7, 0xe36839e1, 0xf10f7437, 0xfa7cb69b, 0x8737e6de, 0xd0fc2767,
+       0xb7281177, 0x75c0cc9e, 0x92bf8879, 0xac503bfc, 0xfc218655, 0x3c74de3a,
+       0x1179d705, 0xba754df8, 0x72f73f12, 0xbee9cb7a, 0x8007f101, 0x8786cebe,
+       0xb8ffa12f, 0x4d9cff1a, 0x61bd6f8b, 0x2b43d90a, 0xf58b95aa, 0xe87ffdd1,
+       0xfb7c037b, 0xc4e3e04f, 0x86bfc11f, 0x70ff342d, 0xff88bbfc, 0x081d3e00,
+       0xa6e5dfe1, 0xeb1dffbb, 0x6c535968, 0x8128f7d0, 0x08fdf374, 0x7c0915ba,
+       0xdb66dffc, 0xf4bed19a, 0x0f617c1c, 0xdf2309d6, 0x2eb0966e, 0x330a72ed,
+       0x7d30f7e2, 0x697f282b, 0xaed099d3, 0x407db495, 0xeb97e3fa, 0x80cfe029,
+       0x06cfce7e, 0x2fc83afe, 0x55d9b6c9, 0xa2e9f46b, 0xf4efe907, 0xa2942c2c,
+       0x7a19f9e9, 0x8c72e1ee, 0x2ddfc3f4, 0xdd8e7a73, 0x97c10c26, 0x9e34ecde,
+       0xd1467927, 0xff6bcbbe, 0x00c0e3c2, 0x91d3097e, 0x6e28674f, 0x0a4f8e1c,
+       0xeff24c1d, 0xadf00d88, 0x685feb96, 0x87f0177f, 0x7e653fee, 0xf7f0ff21,
+       0xceb85cd4, 0x20cf8e68, 0x0d80f85c, 0xd5fc0f61, 0xfce3ca3a, 0x83c9f721,
+       0xd79079fc, 0xa9ea855d, 0xf4e1cfbc, 0xabd3d143, 0xd2a7ffad, 0x52d92fe7,
+       0x7428bc90, 0x6876f9ea, 0xcf1c6e3b, 0x9f67fef5, 0x3504da3f, 0x7f3a0f8b,
+       0xf3c78c34, 0x4133a6c7, 0x7eca8fe7, 0xda73e47b, 0xf922fd9e, 0xeff2cdc7,
+       0x0bda84ac, 0xd0983be5, 0xd7938ef5, 0x7f7f94eb, 0xd1a0e7a1, 0x7a718063,
+       0x79216f5e, 0xd19c3676, 0x7b6a79e2, 0x9efa21fd, 0xf41fd14e, 0xf5809e13,
+       0x2c78bcf7, 0xce36ec97, 0x275f0433, 0x33cf978c, 0xc79e875b, 0x682970d5,
+       0x57b7529e, 0x57ab754b, 0xda82ef99, 0x778e3b76, 0x7eff83a1, 0xd0ef05e1,
+       0xf1a6a9e7, 0x615cf91a, 0x2fe0873b, 0xbcfe01ed, 0x1b4db053, 0xc30c2a3f,
+       0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3,
+       0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3,
+       0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0xc1b7ff0c, 0x8dca0bff,
+       0x8000e737, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
+       0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
+       0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
+       0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
+       0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
+       0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
+       0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
+       0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
+       0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131,
+       0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d,
+       0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7,
+       0x8000dcb1, 0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0x00100000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+       0xffffffff, 0xffffffff, 0x00100000, 0x00000000, 0xfffffff3, 0x314fffff,
+       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, 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, 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,
+       0x000a0000, 0x000700a0, 0x00028110, 0x000b8138, 0x000201f0, 0x00010210,
+       0x000f0220, 0x00010310, 0x00080000, 0x00080080, 0x00028100, 0x000b8128,
+       0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0,
+       0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338,
+       0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280,
+       0x000e8298, 0x00080380, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
+       0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
+       0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
+};
+
+#endif /*__BNX2X_INIT_VALUES_H__*/
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
new file mode 100644 (file)
index 0000000..8605529
--- /dev/null
@@ -0,0 +1,4394 @@
+/* bnx2x_reg.h: Broadcom Everest network driver.
+ *
+ * Copyright (c) 2007 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.
+ *
+ * The registers description starts with the regsister Access type followed
+ * by size in bits. For example [RW 32]. The access types are:
+ * R  - Read only
+ * RC - Clear on read
+ * RW - Read/Write
+ * ST - Statistics register (clear on read)
+ * W  - Write only
+ * WB - Wide bus register - the size is over 32 bits and it should be
+ *      read/write in consecutive 32 bits accesses
+ * WR - Write Clear (write 1 to clear the bit)
+ *
+ */
+
+
+/* [R 19] Interrupt register #0 read */
+#define BRB1_REG_BRB1_INT_STS                                   0x6011c
+/* [RW 4] Parity mask register #0 read/write */
+#define BRB1_REG_BRB1_PRTY_MASK                                 0x60138
+/* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At
+   address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address
+   BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */
+#define BRB1_REG_FREE_LIST_PRS_CRDT                             0x60200
+/* [RW 23] LL RAM data. */
+#define BRB1_REG_LL_RAM                                         0x61000
+/* [R 24] The number of full blocks. */
+#define BRB1_REG_NUM_OF_FULL_BLOCKS                             0x60090
+/* [ST 32] The number of cycles that the write_full signal towards MAC #0
+   was asserted. */
+#define BRB1_REG_NUM_OF_FULL_CYCLES_0                           0x600c8
+#define BRB1_REG_NUM_OF_FULL_CYCLES_1                           0x600cc
+#define BRB1_REG_NUM_OF_FULL_CYCLES_2                           0x600d0
+#define BRB1_REG_NUM_OF_FULL_CYCLES_3                           0x600d4
+#define BRB1_REG_NUM_OF_FULL_CYCLES_4                           0x600d8
+/* [ST 32] The number of cycles that the pause signal towards MAC #0 was
+   asserted. */
+#define BRB1_REG_NUM_OF_PAUSE_CYCLES_0                          0x600b8
+#define BRB1_REG_NUM_OF_PAUSE_CYCLES_1                          0x600bc
+#define BRB1_REG_NUM_OF_PAUSE_CYCLES_2                          0x600c0
+#define BRB1_REG_NUM_OF_PAUSE_CYCLES_3                          0x600c4
+/* [RW 10] Write client 0: De-assert pause threshold. */
+#define BRB1_REG_PAUSE_HIGH_THRESHOLD_0                         0x60078
+#define BRB1_REG_PAUSE_HIGH_THRESHOLD_1                         0x6007c
+/* [RW 10] Write client 0: Assert pause threshold. */
+#define BRB1_REG_PAUSE_LOW_THRESHOLD_0                          0x60068
+#define BRB1_REG_PAUSE_LOW_THRESHOLD_1                          0x6006c
+/* [RW 1] Reset the design by software. */
+#define BRB1_REG_SOFT_RESET                                     0x600dc
+/* [R 5] Used to read the value of the XX protection CAM occupancy counter. */
+#define CCM_REG_CAM_OCCUP                                       0xd0188
+/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CCM_CFC_IFEN                                    0xd003c
+/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CCM_CQM_IFEN                                    0xd000c
+/* [RW 1] If set the Q index; received from the QM is inserted to event ID.
+   Otherwise 0 is inserted. */
+#define CCM_REG_CCM_CQM_USE_Q                                   0xd00c0
+/* [RW 11] Interrupt mask register #0 read/write */
+#define CCM_REG_CCM_INT_MASK                                    0xd01e4
+/* [R 11] Interrupt register #0 read */
+#define CCM_REG_CCM_INT_STS                                     0xd01d8
+/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS
+   REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
+   Is used to determine the number of the AG context REG-pairs written back;
+   when the input message Reg1WbFlg isn't set. */
+#define CCM_REG_CCM_REG0_SZ                                     0xd00c4
+/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CCM_STORM0_IFEN                                 0xd0004
+/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CCM_STORM1_IFEN                                 0xd0008
+/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define CCM_REG_CDU_AG_RD_IFEN                                  0xd0030
+/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input
+   are disregarded; all other signals are treated as usual; if 1 - normal
+   activity. */
+#define CCM_REG_CDU_AG_WR_IFEN                                  0xd002c
+/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define CCM_REG_CDU_SM_RD_IFEN                                  0xd0038
+/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid
+   input is disregarded; all other signals are treated as usual; if 1 -
+   normal activity. */
+#define CCM_REG_CDU_SM_WR_IFEN                                  0xd0034
+/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 1 at start-up. */
+#define CCM_REG_CFC_INIT_CRD                                    0xd0204
+/* [RW 2] Auxillary counter flag Q number 1. */
+#define CCM_REG_CNT_AUX1_Q                                      0xd00c8
+/* [RW 2] Auxillary counter flag Q number 2. */
+#define CCM_REG_CNT_AUX2_Q                                      0xd00cc
+/* [RW 28] The CM header value for QM request (primary). */
+#define CCM_REG_CQM_CCM_HDR_P                                   0xd008c
+/* [RW 28] The CM header value for QM request (secondary). */
+#define CCM_REG_CQM_CCM_HDR_S                                   0xd0090
+/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CQM_CCM_IFEN                                    0xd0014
+/* [RW 6] QM output initial credit. Max credit available - 32. Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 32 at start-up. */
+#define CCM_REG_CQM_INIT_CRD                                    0xd020c
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_CQM_P_WEIGHT                                    0xd00b8
+/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_CSDM_IFEN                                       0xd0018
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the SDM interface is detected. */
+#define CCM_REG_CSDM_LENGTH_MIS                                 0xd0170
+/* [RW 28] The CM header for QM formatting in case of an error in the QM
+   inputs. */
+#define CCM_REG_ERR_CCM_HDR                                     0xd0094
+/* [RW 8] The Event ID in case the input message ErrorFlg is set. */
+#define CCM_REG_ERR_EVNT_ID                                     0xd0098
+/* [RW 8] FIC0 output initial credit. Max credit available - 255. Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define CCM_REG_FIC0_INIT_CRD                                   0xd0210
+/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define CCM_REG_FIC1_INIT_CRD                                   0xd0214
+/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1
+   - strict priority defined by ~ccm_registers_gr_ag_pr.gr_ag_pr;
+   ~ccm_registers_gr_ld0_pr.gr_ld0_pr and
+   ~ccm_registers_gr_ld1_pr.gr_ld1_pr. Groups are according to channels and
+   outputs to STORM: aggregation; load FIC0; load FIC1 and store. */
+#define CCM_REG_GR_ARB_TYPE                                     0xd015c
+/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed; that the Store channel priority is
+   the compliment to 4 of the rest priorities - Aggregation channel; Load
+   (FIC0) channel and Load (FIC1). */
+#define CCM_REG_GR_LD0_PR                                       0xd0164
+/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed; that the Store channel priority is
+   the compliment to 4 of the rest priorities - Aggregation channel; Load
+   (FIC0) channel and Load (FIC1). */
+#define CCM_REG_GR_LD1_PR                                       0xd0168
+/* [RW 2] General flags index. */
+#define CCM_REG_INV_DONE_Q                                      0xd0108
+/* [RW 4] The number of double REG-pairs(128 bits); loaded from the STORM
+   context and sent to STORM; for a specific connection type. The double
+   REG-pairs are used in order to align to STORM context row size of 128
+   bits. The offset of these data in the STORM context is always 0. Index
+   _(0..15) stands for the connection type (one of 16). */
+#define CCM_REG_N_SM_CTX_LD_0                                   0xd004c
+#define CCM_REG_N_SM_CTX_LD_1                                   0xd0050
+#define CCM_REG_N_SM_CTX_LD_10                                  0xd0074
+#define CCM_REG_N_SM_CTX_LD_11                                  0xd0078
+#define CCM_REG_N_SM_CTX_LD_12                                  0xd007c
+#define CCM_REG_N_SM_CTX_LD_13                                  0xd0080
+#define CCM_REG_N_SM_CTX_LD_14                                  0xd0084
+#define CCM_REG_N_SM_CTX_LD_15                                  0xd0088
+#define CCM_REG_N_SM_CTX_LD_2                                   0xd0054
+#define CCM_REG_N_SM_CTX_LD_3                                   0xd0058
+#define CCM_REG_N_SM_CTX_LD_4                                   0xd005c
+/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define CCM_REG_PBF_IFEN                                        0xd0028
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the pbf interface is detected. */
+#define CCM_REG_PBF_LENGTH_MIS                                  0xd0180
+/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_PBF_WEIGHT                                      0xd00ac
+/* [RW 6] The physical queue number of queue number 1 per port index. */
+#define CCM_REG_PHYS_QNUM1_0                                    0xd0134
+#define CCM_REG_PHYS_QNUM1_1                                    0xd0138
+/* [RW 6] The physical queue number of queue number 2 per port index. */
+#define CCM_REG_PHYS_QNUM2_0                                    0xd013c
+#define CCM_REG_PHYS_QNUM2_1                                    0xd0140
+/* [RW 6] The physical queue number of queue number 3 per port index. */
+#define CCM_REG_PHYS_QNUM3_0                                    0xd0144
+/* [RW 6] The physical queue number of queue number 0 with QOS equal 0 port
+   index 0. */
+#define CCM_REG_QOS_PHYS_QNUM0_0                                0xd0114
+#define CCM_REG_QOS_PHYS_QNUM0_1                                0xd0118
+/* [RW 6] The physical queue number of queue number 0 with QOS equal 1 port
+   index 0. */
+#define CCM_REG_QOS_PHYS_QNUM1_0                                0xd011c
+#define CCM_REG_QOS_PHYS_QNUM1_1                                0xd0120
+/* [RW 6] The physical queue number of queue number 0 with QOS equal 2 port
+   index 0. */
+#define CCM_REG_QOS_PHYS_QNUM2_0                                0xd0124
+/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define CCM_REG_STORM_CCM_IFEN                                  0xd0010
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the STORM interface is detected. */
+#define CCM_REG_STORM_LENGTH_MIS                                0xd016c
+/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define CCM_REG_TSEM_IFEN                                       0xd001c
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the tsem interface is detected. */
+#define CCM_REG_TSEM_LENGTH_MIS                                 0xd0174
+/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_TSEM_WEIGHT                                     0xd00a0
+/* [RW 1] Input usem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define CCM_REG_USEM_IFEN                                       0xd0024
+/* [RC 1] Set when message length mismatch (relative to last indication) at
+   the usem interface is detected. */
+#define CCM_REG_USEM_LENGTH_MIS                                 0xd017c
+/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_USEM_WEIGHT                                     0xd00a8
+/* [RW 1] Input xsem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define CCM_REG_XSEM_IFEN                                       0xd0020
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the xsem interface is detected. */
+#define CCM_REG_XSEM_LENGTH_MIS                                 0xd0178
+/* [RW 3] The weight of the input xsem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define CCM_REG_XSEM_WEIGHT                                     0xd00a4
+/* [RW 19] Indirect access to the descriptor table of the XX protection
+   mechanism. The fields are: [5:0] - message length; [12:6] - message
+   pointer; 18:13] - next pointer. */
+#define CCM_REG_XX_DESCR_TABLE                                  0xd0300
+/* [R 7] Used to read the value of XX protection Free counter. */
+#define CCM_REG_XX_FREE                                         0xd0184
+/* [RW 6] Initial value for the credit counter; responsible for fulfilling
+   of the Input Stage XX protection buffer by the XX protection pending
+   messages. Max credit available - 127. Write writes the initial credit
+   value; read returns the current value of the credit counter. Must be
+   initialized to maximum XX protected message size - 2 at start-up. */
+#define CCM_REG_XX_INIT_CRD                                     0xd0220
+/* [RW 7] The maximum number of pending messages; which may be stored in XX
+   protection. At read the ~ccm_registers_xx_free.xx_free counter is read.
+   At write comprises the start value of the ~ccm_registers_xx_free.xx_free
+   counter. */
+#define CCM_REG_XX_MSG_NUM                                      0xd0224
+/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */
+#define CCM_REG_XX_OVFL_EVNT_ID                                 0xd0044
+/* [RW 18] Indirect access to the XX table of the XX protection mechanism.
+   The fields are: [5:0] - tail pointer; 11:6] - Link List size; 17:12] -
+   header pointer. */
+#define CCM_REG_XX_TABLE                                        0xd0280
+#define CDU_REG_CDU_CHK_MASK0                                   0x101000
+#define CDU_REG_CDU_CHK_MASK1                                   0x101004
+#define CDU_REG_CDU_CONTROL0                                    0x101008
+#define CDU_REG_CDU_DEBUG                                       0x101010
+#define CDU_REG_CDU_GLOBAL_PARAMS                               0x101020
+/* [RW 7] Interrupt mask register #0 read/write */
+#define CDU_REG_CDU_INT_MASK                                    0x10103c
+/* [R 7] Interrupt register #0 read */
+#define CDU_REG_CDU_INT_STS                                     0x101030
+/* [RW 5] Parity mask register #0 read/write */
+#define CDU_REG_CDU_PRTY_MASK                                   0x10104c
+/* [RC 32] logging of error data in case of a CDU load error:
+   {expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error;
+   ype_error; ctual_active; ctual_compressed_context}; */
+#define CDU_REG_ERROR_DATA                                      0x101014
+/* [WB 216] L1TT ram access. each entry has the following format :
+   {mrege_regions[7:0]; ffset12[5:0]...offset0[5:0];
+   ength12[5:0]...length0[5:0]; d12[3:0]...id0[3:0]} */
+#define CDU_REG_L1TT                                            0x101800
+/* [WB 24] MATT ram access. each entry has the following
+   format:{RegionLength[11:0]; egionOffset[11:0]} */
+#define CDU_REG_MATT                                            0x101100
+/* [R 1] indication the initializing the activity counter by the hardware
+   was done. */
+#define CFC_REG_AC_INIT_DONE                                    0x104078
+/* [RW 13] activity counter ram access */
+#define CFC_REG_ACTIVITY_COUNTER                                0x104400
+#define CFC_REG_ACTIVITY_COUNTER_SIZE                           256
+/* [R 1] indication the initializing the cams by the hardware was done. */
+#define CFC_REG_CAM_INIT_DONE                                   0x10407c
+/* [RW 2] Interrupt mask register #0 read/write */
+#define CFC_REG_CFC_INT_MASK                                    0x104108
+/* [R 2] Interrupt register #0 read */
+#define CFC_REG_CFC_INT_STS                                     0x1040fc
+/* [RC 2] Interrupt register #0 read clear */
+#define CFC_REG_CFC_INT_STS_CLR                                 0x104100
+/* [RW 4] Parity mask register #0 read/write */
+#define CFC_REG_CFC_PRTY_MASK                                   0x104118
+/* [RW 21] CID cam access (21:1 - Data; alid - 0) */
+#define CFC_REG_CID_CAM                                         0x104800
+#define CFC_REG_CONTROL0                                        0x104028
+#define CFC_REG_DEBUG0                                          0x104050
+/* [RW 14] indicates per error (in #cfc_registers_cfc_error_vector.cfc_error
+   vector) whether the cfc should be disabled upon it */
+#define CFC_REG_DISABLE_ON_ERROR                                0x104044
+/* [RC 14] CFC error vector. when the CFC detects an internal error it will
+   set one of these bits. the bit description can be found in CFC
+   specifications */
+#define CFC_REG_ERROR_VECTOR                                    0x10403c
+#define CFC_REG_INIT_REG                                        0x10404c
+/* [RW 24] {weight_load_client7[2:0] to weight_load_client0[2:0]}. this
+   field allows changing the priorities of the weighted-round-robin arbiter
+   which selects which CFC load client should be served next */
+#define CFC_REG_LCREQ_WEIGHTS                                   0x104084
+/* [R 1] indication the initializing the link list by the hardware was done. */
+#define CFC_REG_LL_INIT_DONE                                    0x104074
+/* [R 9] Number of allocated LCIDs which are at empty state */
+#define CFC_REG_NUM_LCIDS_ALLOC                                 0x104020
+/* [R 9] Number of Arriving LCIDs in Link List Block */
+#define CFC_REG_NUM_LCIDS_ARRIVING                              0x104004
+/* [R 9] Number of Inside LCIDs in Link List Block */
+#define CFC_REG_NUM_LCIDS_INSIDE                                0x104008
+/* [R 9] Number of Leaving LCIDs in Link List Block */
+#define CFC_REG_NUM_LCIDS_LEAVING                               0x104018
+/* [RW 8] The event id for aggregated interrupt 0 */
+#define CSDM_REG_AGG_INT_EVENT_0                                0xc2038
+/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
+#define CSDM_REG_CFC_RSP_START_ADDR                             0xc2008
+/* [RW 16] The maximum value of the competion counter #0 */
+#define CSDM_REG_CMP_COUNTER_MAX0                               0xc201c
+/* [RW 16] The maximum value of the competion counter #1 */
+#define CSDM_REG_CMP_COUNTER_MAX1                               0xc2020
+/* [RW 16] The maximum value of the competion counter #2 */
+#define CSDM_REG_CMP_COUNTER_MAX2                               0xc2024
+/* [RW 16] The maximum value of the competion counter #3 */
+#define CSDM_REG_CMP_COUNTER_MAX3                               0xc2028
+/* [RW 13] The start address in the internal RAM for the completion
+   counters. */
+#define CSDM_REG_CMP_COUNTER_START_ADDR                         0xc200c
+/* [RW 32] Interrupt mask register #0 read/write */
+#define CSDM_REG_CSDM_INT_MASK_0                                0xc229c
+#define CSDM_REG_CSDM_INT_MASK_1                                0xc22ac
+/* [RW 11] Parity mask register #0 read/write */
+#define CSDM_REG_CSDM_PRTY_MASK                                 0xc22bc
+#define CSDM_REG_ENABLE_IN1                                     0xc2238
+#define CSDM_REG_ENABLE_IN2                                     0xc223c
+#define CSDM_REG_ENABLE_OUT1                                    0xc2240
+#define CSDM_REG_ENABLE_OUT2                                    0xc2244
+/* [RW 4] The initial number of messages that can be sent to the pxp control
+   interface without receiving any ACK. */
+#define CSDM_REG_INIT_CREDIT_PXP_CTRL                           0xc24bc
+/* [ST 32] The number of ACK after placement messages received */
+#define CSDM_REG_NUM_OF_ACK_AFTER_PLACE                         0xc227c
+/* [ST 32] The number of packet end messages received from the parser */
+#define CSDM_REG_NUM_OF_PKT_END_MSG                             0xc2274
+/* [ST 32] The number of requests received from the pxp async if */
+#define CSDM_REG_NUM_OF_PXP_ASYNC_REQ                           0xc2278
+/* [ST 32] The number of commands received in queue 0 */
+#define CSDM_REG_NUM_OF_Q0_CMD                                  0xc2248
+/* [ST 32] The number of commands received in queue 10 */
+#define CSDM_REG_NUM_OF_Q10_CMD                                 0xc226c
+/* [ST 32] The number of commands received in queue 11 */
+#define CSDM_REG_NUM_OF_Q11_CMD                                 0xc2270
+/* [ST 32] The number of commands received in queue 1 */
+#define CSDM_REG_NUM_OF_Q1_CMD                                  0xc224c
+/* [ST 32] The number of commands received in queue 3 */
+#define CSDM_REG_NUM_OF_Q3_CMD                                  0xc2250
+/* [ST 32] The number of commands received in queue 4 */
+#define CSDM_REG_NUM_OF_Q4_CMD                                  0xc2254
+/* [ST 32] The number of commands received in queue 5 */
+#define CSDM_REG_NUM_OF_Q5_CMD                                  0xc2258
+/* [ST 32] The number of commands received in queue 6 */
+#define CSDM_REG_NUM_OF_Q6_CMD                                  0xc225c
+/* [ST 32] The number of commands received in queue 7 */
+#define CSDM_REG_NUM_OF_Q7_CMD                                  0xc2260
+/* [ST 32] The number of commands received in queue 8 */
+#define CSDM_REG_NUM_OF_Q8_CMD                                  0xc2264
+/* [ST 32] The number of commands received in queue 9 */
+#define CSDM_REG_NUM_OF_Q9_CMD                                  0xc2268
+/* [RW 13] The start address in the internal RAM for queue counters */
+#define CSDM_REG_Q_COUNTER_START_ADDR                           0xc2010
+/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */
+#define CSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY                       0xc2548
+/* [R 1] parser fifo empty in sdm_sync block */
+#define CSDM_REG_SYNC_PARSER_EMPTY                              0xc2550
+/* [R 1] parser serial fifo empty in sdm_sync block */
+#define CSDM_REG_SYNC_SYNC_EMPTY                                0xc2558
+/* [RW 32] Tick for timer counter. Applicable only when
+   ~csdm_registers_timer_tick_enable.timer_tick_enable =1 */
+#define CSDM_REG_TIMER_TICK                                     0xc2000
+/* [RW 5] The number of time_slots in the arbitration cycle */
+#define CSEM_REG_ARB_CYCLE_SIZE                                 0x200034
+/* [RW 3] The source that is associated with arbitration element 0. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2 */
+#define CSEM_REG_ARB_ELEMENT0                                   0x200020
+/* [RW 3] The source that is associated with arbitration element 1. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~csem_registers_arb_element0.arb_element0 */
+#define CSEM_REG_ARB_ELEMENT1                                   0x200024
+/* [RW 3] The source that is associated with arbitration element 2. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~csem_registers_arb_element0.arb_element0
+   and ~csem_registers_arb_element1.arb_element1 */
+#define CSEM_REG_ARB_ELEMENT2                                   0x200028
+/* [RW 3] The source that is associated with arbitration element 3. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.Could
+   not be equal to register ~csem_registers_arb_element0.arb_element0 and
+   ~csem_registers_arb_element1.arb_element1 and
+   ~csem_registers_arb_element2.arb_element2 */
+#define CSEM_REG_ARB_ELEMENT3                                   0x20002c
+/* [RW 3] The source that is associated with arbitration element 4. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~csem_registers_arb_element0.arb_element0
+   and ~csem_registers_arb_element1.arb_element1 and
+   ~csem_registers_arb_element2.arb_element2 and
+   ~csem_registers_arb_element3.arb_element3 */
+#define CSEM_REG_ARB_ELEMENT4                                   0x200030
+/* [RW 32] Interrupt mask register #0 read/write */
+#define CSEM_REG_CSEM_INT_MASK_0                                0x200110
+#define CSEM_REG_CSEM_INT_MASK_1                                0x200120
+/* [RW 32] Parity mask register #0 read/write */
+#define CSEM_REG_CSEM_PRTY_MASK_0                               0x200130
+#define CSEM_REG_CSEM_PRTY_MASK_1                               0x200140
+#define CSEM_REG_ENABLE_IN                                      0x2000a4
+#define CSEM_REG_ENABLE_OUT                                     0x2000a8
+/* [RW 32] This address space contains all registers and memories that are
+   placed in SEM_FAST block. The SEM_FAST registers are described in
+   appendix B. In order to access the SEM_FAST registers the base address
+   CSEM_REGISTERS_FAST_MEMORY (Offset: 0x220000) should be added to each
+   SEM_FAST register offset. */
+#define CSEM_REG_FAST_MEMORY                                    0x220000
+/* [RW 1] Disables input messages from FIC0 May be updated during run_time
+   by the microcode */
+#define CSEM_REG_FIC0_DISABLE                                   0x200224
+/* [RW 1] Disables input messages from FIC1 May be updated during run_time
+   by the microcode */
+#define CSEM_REG_FIC1_DISABLE                                   0x200234
+/* [RW 15] Interrupt table Read and write access to it is not possible in
+   the middle of the work */
+#define CSEM_REG_INT_TABLE                                      0x200400
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC0 */
+#define CSEM_REG_MSG_NUM_FIC0                                   0x200000
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC1 */
+#define CSEM_REG_MSG_NUM_FIC1                                   0x200004
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC0 */
+#define CSEM_REG_MSG_NUM_FOC0                                   0x200008
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC1 */
+#define CSEM_REG_MSG_NUM_FOC1                                   0x20000c
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC2 */
+#define CSEM_REG_MSG_NUM_FOC2                                   0x200010
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC3 */
+#define CSEM_REG_MSG_NUM_FOC3                                   0x200014
+/* [RW 1] Disables input messages from the passive buffer May be updated
+   during run_time by the microcode */
+#define CSEM_REG_PAS_DISABLE                                    0x20024c
+/* [WB 128] Debug only. Passive buffer memory */
+#define CSEM_REG_PASSIVE_BUFFER                                 0x202000
+/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */
+#define CSEM_REG_PRAM                                           0x240000
+/* [R 16] Valid sleeping threads indication have bit per thread */
+#define CSEM_REG_SLEEP_THREADS_VALID                            0x20026c
+/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */
+#define CSEM_REG_SLOW_EXT_STORE_EMPTY                           0x2002a0
+/* [RW 16] List of free threads . There is a bit per thread. */
+#define CSEM_REG_THREADS_LIST                                   0x2002e4
+/* [RW 3] The arbitration scheme of time_slot 0 */
+#define CSEM_REG_TS_0_AS                                        0x200038
+/* [RW 3] The arbitration scheme of time_slot 10 */
+#define CSEM_REG_TS_10_AS                                       0x200060
+/* [RW 3] The arbitration scheme of time_slot 11 */
+#define CSEM_REG_TS_11_AS                                       0x200064
+/* [RW 3] The arbitration scheme of time_slot 12 */
+#define CSEM_REG_TS_12_AS                                       0x200068
+/* [RW 3] The arbitration scheme of time_slot 13 */
+#define CSEM_REG_TS_13_AS                                       0x20006c
+/* [RW 3] The arbitration scheme of time_slot 14 */
+#define CSEM_REG_TS_14_AS                                       0x200070
+/* [RW 3] The arbitration scheme of time_slot 15 */
+#define CSEM_REG_TS_15_AS                                       0x200074
+/* [RW 3] The arbitration scheme of time_slot 16 */
+#define CSEM_REG_TS_16_AS                                       0x200078
+/* [RW 3] The arbitration scheme of time_slot 17 */
+#define CSEM_REG_TS_17_AS                                       0x20007c
+/* [RW 3] The arbitration scheme of time_slot 18 */
+#define CSEM_REG_TS_18_AS                                       0x200080
+/* [RW 3] The arbitration scheme of time_slot 1 */
+#define CSEM_REG_TS_1_AS                                        0x20003c
+/* [RW 3] The arbitration scheme of time_slot 2 */
+#define CSEM_REG_TS_2_AS                                        0x200040
+/* [RW 3] The arbitration scheme of time_slot 3 */
+#define CSEM_REG_TS_3_AS                                        0x200044
+/* [RW 3] The arbitration scheme of time_slot 4 */
+#define CSEM_REG_TS_4_AS                                        0x200048
+/* [RW 3] The arbitration scheme of time_slot 5 */
+#define CSEM_REG_TS_5_AS                                        0x20004c
+/* [RW 3] The arbitration scheme of time_slot 6 */
+#define CSEM_REG_TS_6_AS                                        0x200050
+/* [RW 3] The arbitration scheme of time_slot 7 */
+#define CSEM_REG_TS_7_AS                                        0x200054
+/* [RW 3] The arbitration scheme of time_slot 8 */
+#define CSEM_REG_TS_8_AS                                        0x200058
+/* [RW 3] The arbitration scheme of time_slot 9 */
+#define CSEM_REG_TS_9_AS                                        0x20005c
+/* [RW 1] Parity mask register #0 read/write */
+#define DBG_REG_DBG_PRTY_MASK                                   0xc0a8
+/* [RW 2] debug only: These bits indicate the credit for PCI request type 4
+   interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are
+   configured */
+#define DBG_REG_PCI_REQ_CREDIT                                  0xc120
+/* [RW 32] Commands memory. The address to command X; row Y is to calculated
+   as 14*X+Y. */
+#define DMAE_REG_CMD_MEM                                        0x102400
+/* [RW 1] If 0 - the CRC-16c initial value is all zeroes; if 1 - the CRC-16c
+   initial value is all ones. */
+#define DMAE_REG_CRC16C_INIT                                    0x10201c
+/* [RW 1] If 0 - the CRC-16 T10 initial value is all zeroes; if 1 - the
+   CRC-16 T10 initial value is all ones. */
+#define DMAE_REG_CRC16T10_INIT                                  0x102020
+/* [RW 2] Interrupt mask register #0 read/write */
+#define DMAE_REG_DMAE_INT_MASK                                  0x102054
+/* [RW 4] Parity mask register #0 read/write */
+#define DMAE_REG_DMAE_PRTY_MASK                                 0x102064
+/* [RW 1] Command 0 go. */
+#define DMAE_REG_GO_C0                                          0x102080
+/* [RW 1] Command 1 go. */
+#define DMAE_REG_GO_C1                                          0x102084
+/* [RW 1] Command 10 go. */
+#define DMAE_REG_GO_C10                                         0x102088
+#define DMAE_REG_GO_C10_SIZE                                    1
+/* [RW 1] Command 11 go. */
+#define DMAE_REG_GO_C11                                         0x10208c
+#define DMAE_REG_GO_C11_SIZE                                    1
+/* [RW 1] Command 12 go. */
+#define DMAE_REG_GO_C12                                         0x102090
+#define DMAE_REG_GO_C12_SIZE                                    1
+/* [RW 1] Command 13 go. */
+#define DMAE_REG_GO_C13                                         0x102094
+#define DMAE_REG_GO_C13_SIZE                                    1
+/* [RW 1] Command 14 go. */
+#define DMAE_REG_GO_C14                                         0x102098
+#define DMAE_REG_GO_C14_SIZE                                    1
+/* [RW 1] Command 15 go. */
+#define DMAE_REG_GO_C15                                         0x10209c
+#define DMAE_REG_GO_C15_SIZE                                    1
+/* [RW 1] Command 10 go. */
+#define DMAE_REG_GO_C10                                         0x102088
+/* [RW 1] Command 11 go. */
+#define DMAE_REG_GO_C11                                         0x10208c
+/* [RW 1] Command 12 go. */
+#define DMAE_REG_GO_C12                                         0x102090
+/* [RW 1] Command 13 go. */
+#define DMAE_REG_GO_C13                                         0x102094
+/* [RW 1] Command 14 go. */
+#define DMAE_REG_GO_C14                                         0x102098
+/* [RW 1] Command 15 go. */
+#define DMAE_REG_GO_C15                                         0x10209c
+/* [RW 1] Command 2 go. */
+#define DMAE_REG_GO_C2                                          0x1020a0
+/* [RW 1] Command 3 go. */
+#define DMAE_REG_GO_C3                                          0x1020a4
+/* [RW 1] Command 4 go. */
+#define DMAE_REG_GO_C4                                          0x1020a8
+/* [RW 1] Command 5 go. */
+#define DMAE_REG_GO_C5                                          0x1020ac
+/* [RW 1] Command 6 go. */
+#define DMAE_REG_GO_C6                                          0x1020b0
+/* [RW 1] Command 7 go. */
+#define DMAE_REG_GO_C7                                          0x1020b4
+/* [RW 1] Command 8 go. */
+#define DMAE_REG_GO_C8                                          0x1020b8
+/* [RW 1] Command 9 go. */
+#define DMAE_REG_GO_C9                                          0x1020bc
+/* [RW 1] DMAE GRC Interface (Target; aster) enable. If 0 - the acknowledge
+   input is disregarded; valid is deasserted; all other signals are treated
+   as usual; if 1 - normal activity. */
+#define DMAE_REG_GRC_IFEN                                       0x102008
+/* [RW 1] DMAE PCI Interface (Request; ead; rite) enable. If 0 - the
+   acknowledge input is disregarded; valid is deasserted; full is asserted;
+   all other signals are treated as usual; if 1 - normal activity. */
+#define DMAE_REG_PCI_IFEN                                       0x102004
+/* [RW 4] DMAE- PCI Request Interface initial credit. Write writes the
+   initial value to the credit counter; related to the address. Read returns
+   the current value of the counter. */
+#define DMAE_REG_PXP_REQ_INIT_CRD                               0x1020c0
+/* [RW 8] Aggregation command. */
+#define DORQ_REG_AGG_CMD0                                       0x170060
+/* [RW 8] Aggregation command. */
+#define DORQ_REG_AGG_CMD1                                       0x170064
+/* [RW 8] Aggregation command. */
+#define DORQ_REG_AGG_CMD2                                       0x170068
+/* [RW 8] Aggregation command. */
+#define DORQ_REG_AGG_CMD3                                       0x17006c
+/* [RW 28] UCM Header. */
+#define DORQ_REG_CMHEAD_RX                                      0x170050
+/* [RW 5] Interrupt mask register #0 read/write */
+#define DORQ_REG_DORQ_INT_MASK                                  0x170180
+/* [R 5] Interrupt register #0 read */
+#define DORQ_REG_DORQ_INT_STS                                   0x170174
+/* [RC 5] Interrupt register #0 read clear */
+#define DORQ_REG_DORQ_INT_STS_CLR                               0x170178
+/* [RW 2] Parity mask register #0 read/write */
+#define DORQ_REG_DORQ_PRTY_MASK                                 0x170190
+/* [RW 8] The address to write the DPM CID to STORM. */
+#define DORQ_REG_DPM_CID_ADDR                                   0x170044
+/* [RW 5] The DPM mode CID extraction offset. */
+#define DORQ_REG_DPM_CID_OFST                                   0x170030
+/* [RW 12] The threshold of the DQ FIFO to send the almost full interrupt. */
+#define DORQ_REG_DQ_FIFO_AFULL_TH                               0x17007c
+/* [RW 12] The threshold of the DQ FIFO to send the full interrupt. */
+#define DORQ_REG_DQ_FIFO_FULL_TH                                0x170078
+/* [R 13] Current value of the DQ FIFO fill level according to following
+   pointer. The range is 0 - 256 FIFO rows; where each row stands for the
+   doorbell. */
+#define DORQ_REG_DQ_FILL_LVLF                                   0x1700a4
+/* [R 1] DQ FIFO full status. Is set; when FIFO filling level is more or
+   equal to full threshold; reset on full clear. */
+#define DORQ_REG_DQ_FULL_ST                                     0x1700c0
+/* [RW 28] The value sent to CM header in the case of CFC load error. */
+#define DORQ_REG_ERR_CMHEAD                                     0x170058
+#define DORQ_REG_IF_EN                                          0x170004
+#define DORQ_REG_MODE_ACT                                       0x170008
+/* [RW 5] The normal mode CID extraction offset. */
+#define DORQ_REG_NORM_CID_OFST                                  0x17002c
+/* [RW 28] TCM Header when only TCP context is loaded. */
+#define DORQ_REG_NORM_CMHEAD_TX                                 0x17004c
+/* [RW 3] The number of simultaneous outstanding requests to Context Fetch
+   Interface. */
+#define DORQ_REG_OUTST_REQ                                      0x17003c
+#define DORQ_REG_REGN                                           0x170038
+/* [R 4] Current value of response A counter credit. Initial credit is
+   configured through write to ~dorq_registers_rsp_init_crd.rsp_init_crd
+   register. */
+#define DORQ_REG_RSPA_CRD_CNT                                   0x1700ac
+/* [R 4] Current value of response B counter credit. Initial credit is
+   configured through write to ~dorq_registers_rsp_init_crd.rsp_init_crd
+   register. */
+#define DORQ_REG_RSPB_CRD_CNT                                   0x1700b0
+/* [RW 4] The initial credit at the Doorbell Response Interface. The write
+   writes the same initial credit to the rspa_crd_cnt and rspb_crd_cnt. The
+   read reads this written value. */
+#define DORQ_REG_RSP_INIT_CRD                                   0x170048
+/* [RW 4] Initial activity counter value on the load request; when the
+   shortcut is done. */
+#define DORQ_REG_SHRT_ACT_CNT                                   0x170070
+/* [RW 28] TCM Header when both ULP and TCP context is loaded. */
+#define DORQ_REG_SHRT_CMHEAD                                    0x170054
+#define HC_CONFIG_0_REG_ATTN_BIT_EN_0                           (0x1<<4)
+#define HC_CONFIG_0_REG_INT_LINE_EN_0                           (0x1<<3)
+#define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0                       (0x1<<2)
+#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0                         (0x1<<1)
+#define HC_REG_AGG_INT_0                                        0x108050
+#define HC_REG_AGG_INT_1                                        0x108054
+/* [RW 16] attention bit and attention acknowledge bits status for port 0
+   and 1 according to the following address map: addr 0 - attn_bit_0; addr 1
+   - attn_ack_bit_0; addr 2 - attn_bit_1; addr 3 - attn_ack_bit_1; */
+#define HC_REG_ATTN_BIT                                         0x108120
+/* [RW 16] attn bits status index for attn bit msg; addr 0 - function 0;
+   addr 1 - functin 1 */
+#define HC_REG_ATTN_IDX                                         0x108100
+/* [RW 32] port 0 lower 32 bits address field for attn messag. */
+#define HC_REG_ATTN_MSG0_ADDR_L                                 0x108018
+/* [RW 32] port 1 lower 32 bits address field for attn messag. */
+#define HC_REG_ATTN_MSG1_ADDR_L                                 0x108020
+/* [RW 8] status block number for attn bit msg - function 0; */
+#define HC_REG_ATTN_NUM_P0                                      0x108038
+/* [RW 8] status block number for attn bit msg - function 1 */
+#define HC_REG_ATTN_NUM_P1                                      0x10803c
+#define HC_REG_CONFIG_0                                         0x108000
+#define HC_REG_CONFIG_1                                         0x108004
+/* [RW 3] Parity mask register #0 read/write */
+#define HC_REG_HC_PRTY_MASK                                     0x1080a0
+/* [RW 17] status block interrupt mask; one in each bit means unmask; zerow
+   in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1...
+   bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */
+#define HC_REG_INT_MASK                                         0x108108
+/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will
+   lock a change fron 0 to 1 in the corresponding attention signals that
+   comes from the AEU */
+#define HC_REG_LEADING_EDGE_0                                   0x108040
+#define HC_REG_LEADING_EDGE_1                                   0x108048
+/* [RW 16] all producer and consumer of port 0 according to the following
+   addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63;
+   Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons:
+   U/C/X/T/Attn-69/70/71/72/73 */
+#define HC_REG_P0_PROD_CONS                                     0x108200
+/* [RW 16] all producer and consumer of port 1according to the following
+   addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63;
+   Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons:
+   U/C/X/T/Attn-69/70/71/72/73 */
+#define HC_REG_P1_PROD_CONS                                     0x108400
+/* [W 1] This register is write only and has 4 addresses as follow: 0 =
+   clear all PBA bits port 0; 1 = clear all pending interrupts request
+   port0; 2 = clear all PBA bits port 1; 3 = clear all pending interrupts
+   request port1; here is no meaning for the data in this register */
+#define HC_REG_PBA_COMMAND                                      0x108140
+#define HC_REG_PCI_CONFIG_0                                     0x108010
+#define HC_REG_PCI_CONFIG_1                                     0x108014
+/* [RW 24] all counters acording to the following address: LSB: 0=read; 1=
+   read_clear; 0-71 = HW counters (the inside order is the same as the
+   interrupt table in the spec); 72-219 = SW counters 1 (stops after first
+   consumer upd) the inside order is: 72-103 - U_non_default_p0; 104-135
+   C_non_defaul_p0; 36-145 U/C/X/T/Attn_default_p0; 146-177
+   U_non_default_p1; 178-209 C_non_defaul_p1; 10-219 U/C/X/T/Attn_default_p1
+   ; 220-367 = SW counters 2 (stops when prod=cons) the inside order is:
+   220-251 - U_non_default_p0; 252-283 C_non_defaul_p0; 84-293
+   U/C/X/T/Attn_default_p0; 294-325 U_non_default_p1; 326-357
+   C_non_defaul_p1; 58-367 U/C/X/T/Attn_default_p1 ; 368-515 = mailbox
+   counters; (the inside order of the mailbox counter is 368-431 U and C
+   non_default_p0; 432-441 U/C/X/T/Attn_default_p0; 442-505 U and C
+   non_default_p1; 506-515 U/C/X/T/Attn_default_p1) */
+#define HC_REG_STATISTIC_COUNTERS                               0x109000
+/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will
+   lock a change fron 1 to 0 in the corresponding attention signals that
+   comes from the AEU */
+#define HC_REG_TRAILING_EDGE_0                                  0x108044
+#define HC_REG_TRAILING_EDGE_1                                  0x10804c
+#define HC_REG_UC_RAM_ADDR_0                                    0x108028
+#define HC_REG_UC_RAM_ADDR_1                                    0x108030
+/* [RW 16] ustorm address for coalesc now message */
+#define HC_REG_USTORM_ADDR_FOR_COALESCE                         0x108068
+#define HC_REG_VQID_0                                           0x108008
+#define HC_REG_VQID_1                                           0x10800c
+#define MCP_REG_MCPR_NVM_ACCESS_ENABLE                          0x86424
+#define MCP_REG_MCPR_NVM_ADDR                                   0x8640c
+#define MCP_REG_MCPR_NVM_CFG4                                   0x8642c
+#define MCP_REG_MCPR_NVM_COMMAND                                0x86400
+#define MCP_REG_MCPR_NVM_READ                                   0x86410
+#define MCP_REG_MCPR_NVM_SW_ARB                                 0x86420
+#define MCP_REG_MCPR_NVM_WRITE                                  0x86408
+#define MCP_REG_MCPR_NVM_WRITE1                                 0x86428
+#define MCP_REG_MCPR_SCRATCH                                    0xa0000
+/* [R 32] read first 32 bit after inversion of function 0. mapped as
+   follows: [0] NIG attention for function0; [1] NIG attention for
+   function1; [2] GPIO1 mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp;
+   [6] GPIO1 function 1; [7] GPIO2 function 1; [8] GPIO3 function 1; [9]
+   GPIO4 function 1; [10] PCIE glue/PXP VPD event function0; [11] PCIE
+   glue/PXP VPD event function1; [12] PCIE glue/PXP Expansion ROM event0;
+   [13] PCIE glue/PXP Expansion ROM event1; [14] SPIO4; [15] SPIO5; [16]
+   MSI/X indication for mcp; [17] MSI/X indication for function 1; [18] BRB
+   Parity error; [19] BRB Hw interrupt; [20] PRS Parity error; [21] PRS Hw
+   interrupt; [22] SRC Parity error; [23] SRC Hw interrupt; [24] TSDM Parity
+   error; [25] TSDM Hw interrupt; [26] TCM Parity error; [27] TCM Hw
+   interrupt; [28] TSEMI Parity error; [29] TSEMI Hw interrupt; [30] PBF
+   Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_AFTER_INVERT_1_FUNC_0                      0xa42c
+#define MISC_REG_AEU_AFTER_INVERT_1_FUNC_1                      0xa430
+/* [R 32] read first 32 bit after inversion of mcp. mapped as follows: [0]
+   NIG attention for function0; [1] NIG attention for function1; [2] GPIO1
+   mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp; [6] GPIO1 function 1;
+   [7] GPIO2 function 1; [8] GPIO3 function 1; [9] GPIO4 function 1; [10]
+   PCIE glue/PXP VPD event function0; [11] PCIE glue/PXP VPD event
+   function1; [12] PCIE glue/PXP Expansion ROM event0; [13] PCIE glue/PXP
+   Expansion ROM event1; [14] SPIO4; [15] SPIO5; [16] MSI/X indication for
+   mcp; [17] MSI/X indication for function 1; [18] BRB Parity error; [19]
+   BRB Hw interrupt; [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC
+   Parity error; [23] SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw
+   interrupt; [26] TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI
+   Parity error; [29] TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw
+   interrupt; */
+#define MISC_REG_AEU_AFTER_INVERT_1_MCP                         0xa434
+/* [R 32] read second 32 bit after inversion of function 0. mapped as
+   follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM
+   Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw
+   interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity
+   error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw
+   interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14]
+   NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error;
+   [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw
+   interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM
+   Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI
+   Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM
+   Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw
+   interrupt; */
+#define MISC_REG_AEU_AFTER_INVERT_2_FUNC_0                      0xa438
+#define MISC_REG_AEU_AFTER_INVERT_2_FUNC_1                      0xa43c
+/* [R 32] read second 32 bit after inversion of mcp. mapped as follows: [0]
+   PBClient Parity error; [1] PBClient Hw interrupt; [2] QM Parity error;
+   [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw interrupt;
+   [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity error; [9]
+   XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw interrupt; [12]
+   DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] NIG Parity
+   error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; [17] Vaux
+   PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw interrupt;
+   [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM Parity error;
+   [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI Hw interrupt;
+   [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM Parity error;
+   [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw interrupt; */
+#define MISC_REG_AEU_AFTER_INVERT_2_MCP                         0xa440
+/* [R 32] read third 32 bit after inversion of function 0. mapped as
+   follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP Parity
+   error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error; [5]
+   PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw
+   interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity
+   error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC)
+   Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16]
+   pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20]
+   MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23]
+   SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW
+   timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3
+   func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General
+   attn1; */
+#define MISC_REG_AEU_AFTER_INVERT_3_FUNC_0                      0xa444
+#define MISC_REG_AEU_AFTER_INVERT_3_FUNC_1                      0xa448
+/* [R 32] read third 32 bit after inversion of mcp. mapped as follows: [0]
+   CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP Parity error; [3] PXP
+   Hw interrupt; [4] PXPpciClockClient Parity error; [5] PXPpciClockClient
+   Hw interrupt; [6] CFC Parity error; [7] CFC Hw interrupt; [8] CDU Parity
+   error; [9] CDU Hw interrupt; [10] DMAE Parity error; [11] DMAE Hw
+   interrupt; [12] IGU (HC) Parity error; [13] IGU (HC) Hw interrupt; [14]
+   MISC Parity error; [15] MISC Hw interrupt; [16] pxp_misc_mps_attn; [17]
+   Flash event; [18] SMB event; [19] MCP attn0; [20] MCP attn1; [21] SW
+   timers attn_1 func0; [22] SW timers attn_2 func0; [23] SW timers attn_3
+   func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW timers attn_1
+   func1; [27] SW timers attn_2 func1; [28] SW timers attn_3 func1; [29] SW
+   timers attn_4 func1; [30] General attn0; [31] General attn1; */
+#define MISC_REG_AEU_AFTER_INVERT_3_MCP                         0xa44c
+/* [R 32] read fourth 32 bit after inversion of function 0. mapped as
+   follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
+   General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
+   [7] General attn9; [8] General attn10; [9] General attn11; [10] General
+   attn12; [11] General attn13; [12] General attn14; [13] General attn15;
+   [14] General attn16; [15] General attn17; [16] General attn18; [17]
+   General attn19; [18] General attn20; [19] General attn21; [20] Main power
+   interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN
+   Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC
+   Latched timeout attention; [27] GRC Latched reserved access attention;
+   [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP
+   Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
+#define MISC_REG_AEU_AFTER_INVERT_4_FUNC_0                      0xa450
+#define MISC_REG_AEU_AFTER_INVERT_4_FUNC_1                      0xa454
+/* [R 32] read fourth 32 bit after inversion of mcp. mapped as follows: [0]
+   General attn2; [1] General attn3; [2] General attn4; [3] General attn5;
+   [4] General attn6; [5] General attn7; [6] General attn8; [7] General
+   attn9; [8] General attn10; [9] General attn11; [10] General attn12; [11]
+   General attn13; [12] General attn14; [13] General attn15; [14] General
+   attn16; [15] General attn17; [16] General attn18; [17] General attn19;
+   [18] General attn20; [19] General attn21; [20] Main power interrupt; [21]
+   RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN Latched attn; [24]
+   RBCU Latched attn; [25] RBCP Latched attn; [26] GRC Latched timeout
+   attention; [27] GRC Latched reserved access attention; [28] MCP Latched
+   rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched
+   ump_tx_parity; [31] MCP Latched scpad_parity; */
+#define MISC_REG_AEU_AFTER_INVERT_4_MCP                         0xa458
+/* [W 11] write to this register results with the clear of the latched
+   signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in
+   d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP
+   latch; one in d5 clears GRC Latched timeout attention; one in d6 clears
+   GRC Latched reserved access attention; one in d7 clears Latched
+   rom_parity; one in d8 clears Latched ump_rx_parity; one in d9 clears
+   Latched ump_tx_parity; one in d10 clears Latched scpad_parity; read from
+   this register return zero */
+#define MISC_REG_AEU_CLR_LATCH_SIGNAL                           0xa45c
+/* [RW 32] first 32b for enabling the output for function 0 output0. mapped
+   as follows: [0] NIG attention for function0; [1] NIG attention for
+   function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function
+   0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
+   GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
+   function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP
+   Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14]
+   SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X
+   indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt;
+   [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23]
+   SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26]
+   TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29]
+   TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0                       0xa06c
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1                       0xa07c
+#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3                       0xa09c
+/* [RW 32] first 32b for enabling the output for function 1 output0. mapped
+   as follows: [0] NIG attention for function0; [1] NIG attention for
+   function1; [2] GPIO1 function 1; [3] GPIO2 function 1; [4] GPIO3 function
+   1; [5] GPIO4 function 1; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
+   GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
+   function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP
+   Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14]
+   SPIO4; [15] SPIO5; [16] MSI/X indication for function 1; [17] MSI/X
+   indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt;
+   [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23]
+   SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26]
+   TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29]
+   TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0                       0xa10c
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1                       0xa11c
+#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3                       0xa13c
+/* [RW 32] first 32b for enabling the output for close the gate nig 0.
+   mapped as follows: [0] NIG attention for function0; [1] NIG attention for
+   function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function
+   0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
+   GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
+   function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP
+   Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14]
+   SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X
+   indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt;
+   [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23]
+   SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26]
+   TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29]
+   TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_ENABLE1_NIG_0                              0xa0ec
+#define MISC_REG_AEU_ENABLE1_NIG_1                              0xa18c
+/* [RW 32] first 32b for enabling the output for close the gate pxp 0.
+   mapped as follows: [0] NIG attention for function0; [1] NIG attention for
+   function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function
+   0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8]
+   GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
+   function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP
+   Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14]
+   SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X
+   indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt;
+   [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23]
+   SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26]
+   TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29]
+   TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_ENABLE1_PXP_0                              0xa0fc
+#define MISC_REG_AEU_ENABLE1_PXP_1                              0xa19c
+/* [RW 32] second 32b for enabling the output for function 0 output0. mapped
+   as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM
+   Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw
+   interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity
+   error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw
+   interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14]
+   NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error;
+   [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw
+   interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM
+   Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI
+   Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM
+   Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw
+   interrupt; */
+#define MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0                       0xa070
+#define MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1                       0xa080
+/* [RW 32] second 32b for enabling the output for function 1 output0. mapped
+   as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM
+   Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw
+   interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity
+   error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw
+   interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14]
+   NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error;
+   [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw
+   interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM
+   Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI
+   Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM
+   Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw
+   interrupt; */
+#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0                       0xa110
+#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1                       0xa120
+/* [RW 32] second 32b for enabling the output for close the gate nig 0.
+   mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt;
+   [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5]
+   Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8]
+   XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11]
+   XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw
+   interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI
+   core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity
+   error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw
+   interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI
+   Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw
+   interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM
+   Parity error; [31] CCM Hw interrupt; */
+#define MISC_REG_AEU_ENABLE2_NIG_0                              0xa0f0
+#define MISC_REG_AEU_ENABLE2_NIG_1                              0xa190
+/* [RW 32] second 32b for enabling the output for close the gate pxp 0.
+   mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt;
+   [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5]
+   Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8]
+   XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11]
+   XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw
+   interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI
+   core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity
+   error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw
+   interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI
+   Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw
+   interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM
+   Parity error; [31] CCM Hw interrupt; */
+#define MISC_REG_AEU_ENABLE2_PXP_0                              0xa100
+#define MISC_REG_AEU_ENABLE2_PXP_1                              0xa1a0
+/* [RW 32] third 32b for enabling the output for function 0 output0. mapped
+   as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP
+   Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error;
+   [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw
+   interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity
+   error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC)
+   Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16]
+   pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20]
+   MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23]
+   SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW
+   timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3
+   func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General
+   attn1; */
+#define MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0                       0xa074
+#define MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1                       0xa084
+/* [RW 32] third 32b for enabling the output for function 1 output0. mapped
+   as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP
+   Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error;
+   [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw
+   interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity
+   error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC)
+   Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16]
+   pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20]
+   MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23]
+   SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW
+   timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3
+   func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General
+   attn1; */
+#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0                       0xa114
+#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1                       0xa124
+/* [RW 32] third 32b for enabling the output for close the gate nig 0.
+   mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2]
+   PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity
+   error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC
+   Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE
+   Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13]
+   IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt;
+   [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0;
+   [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0;
+   [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST;
+   [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers
+   attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31]
+   General attn1; */
+#define MISC_REG_AEU_ENABLE3_NIG_0                              0xa0f4
+#define MISC_REG_AEU_ENABLE3_NIG_1                              0xa194
+/* [RW 32] third 32b for enabling the output for close the gate pxp 0.
+   mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2]
+   PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity
+   error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC
+   Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE
+   Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13]
+   IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt;
+   [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0;
+   [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0;
+   [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST;
+   [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers
+   attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31]
+   General attn1; */
+#define MISC_REG_AEU_ENABLE3_PXP_0                              0xa104
+#define MISC_REG_AEU_ENABLE3_PXP_1                              0xa1a4
+/* [RW 32] fourth 32b for enabling the output for function 0 output0.mapped
+   as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
+   General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
+   [7] General attn9; [8] General attn10; [9] General attn11; [10] General
+   attn12; [11] General attn13; [12] General attn14; [13] General attn15;
+   [14] General attn16; [15] General attn17; [16] General attn18; [17]
+   General attn19; [18] General attn20; [19] General attn21; [20] Main power
+   interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN
+   Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC
+   Latched timeout attention; [27] GRC Latched reserved access attention;
+   [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP
+   Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0                       0xa078
+#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2                       0xa098
+/* [RW 32] fourth 32b for enabling the output for function 1 output0.mapped
+   as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3]
+   General attn5; [4] General attn6; [5] General attn7; [6] General attn8;
+   [7] General attn9; [8] General attn10; [9] General attn11; [10] General
+   attn12; [11] General attn13; [12] General attn14; [13] General attn15;
+   [14] General attn16; [15] General attn17; [16] General attn18; [17]
+   General attn19; [18] General attn20; [19] General attn21; [20] Main power
+   interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN
+   Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC
+   Latched timeout attention; [27] GRC Latched reserved access attention;
+   [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP
+   Latched ump_tx_parity; [31] MCP Latched scpad_parity; */
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0                       0xa118
+#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2                       0xa138
+/* [RW 32] fourth 32b for enabling the output for close the gate nig
+   0.mapped as follows: [0] General attn2; [1] General attn3; [2] General
+   attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6]
+   General attn8; [7] General attn9; [8] General attn10; [9] General attn11;
+   [10] General attn12; [11] General attn13; [12] General attn14; [13]
+   General attn15; [14] General attn16; [15] General attn17; [16] General
+   attn18; [17] General attn19; [18] General attn20; [19] General attn21;
+   [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched
+   attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched
+   attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved
+   access attention; [28] MCP Latched rom_parity; [29] MCP Latched
+   ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched
+   scpad_parity; */
+#define MISC_REG_AEU_ENABLE4_NIG_0                              0xa0f8
+#define MISC_REG_AEU_ENABLE4_NIG_1                              0xa198
+/* [RW 32] fourth 32b for enabling the output for close the gate pxp
+   0.mapped as follows: [0] General attn2; [1] General attn3; [2] General
+   attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6]
+   General attn8; [7] General attn9; [8] General attn10; [9] General attn11;
+   [10] General attn12; [11] General attn13; [12] General attn14; [13]
+   General attn15; [14] General attn16; [15] General attn17; [16] General
+   attn18; [17] General attn19; [18] General attn20; [19] General attn21;
+   [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched
+   attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched
+   attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved
+   access attention; [28] MCP Latched rom_parity; [29] MCP Latched
+   ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched
+   scpad_parity; */
+#define MISC_REG_AEU_ENABLE4_PXP_0                              0xa108
+#define MISC_REG_AEU_ENABLE4_PXP_1                              0xa1a8
+/* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu
+   128 bit vector */
+#define MISC_REG_AEU_GENERAL_ATTN_0                             0xa000
+#define MISC_REG_AEU_GENERAL_ATTN_1                             0xa004
+#define MISC_REG_AEU_GENERAL_ATTN_10                            0xa028
+#define MISC_REG_AEU_GENERAL_ATTN_11                            0xa02c
+#define MISC_REG_AEU_GENERAL_ATTN_12                            0xa030
+#define MISC_REG_AEU_GENERAL_ATTN_13                            0xa034
+#define MISC_REG_AEU_GENERAL_ATTN_14                            0xa038
+#define MISC_REG_AEU_GENERAL_ATTN_15                            0xa03c
+#define MISC_REG_AEU_GENERAL_ATTN_16                            0xa040
+#define MISC_REG_AEU_GENERAL_ATTN_17                            0xa044
+#define MISC_REG_AEU_GENERAL_ATTN_18                            0xa048
+#define MISC_REG_AEU_GENERAL_ATTN_19                            0xa04c
+#define MISC_REG_AEU_GENERAL_ATTN_11                            0xa02c
+#define MISC_REG_AEU_GENERAL_ATTN_2                             0xa008
+#define MISC_REG_AEU_GENERAL_ATTN_20                            0xa050
+#define MISC_REG_AEU_GENERAL_ATTN_21                            0xa054
+#define MISC_REG_AEU_GENERAL_ATTN_3                             0xa00c
+#define MISC_REG_AEU_GENERAL_ATTN_4                             0xa010
+#define MISC_REG_AEU_GENERAL_ATTN_5                             0xa014
+#define MISC_REG_AEU_GENERAL_ATTN_6                             0xa018
+/* [RW 32] first 32b for inverting the input for function 0; for each bit:
+   0= do not invert; 1= invert; mapped as follows: [0] NIG attention for
+   function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp;
+   [4] GPIO3 mcp; [5] GPIO4 mcp; [6] GPIO1 function 1; [7] GPIO2 function 1;
+   [8] GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event
+   function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP
+   Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14]
+   SPIO4; [15] SPIO5; [16] MSI/X indication for mcp; [17] MSI/X indication
+   for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; [20] PRS
+   Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] SRC Hw
+   interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] TCM
+   Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] TSEMI
+   Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */
+#define MISC_REG_AEU_INVERTER_1_FUNC_0                          0xa22c
+#define MISC_REG_AEU_INVERTER_1_FUNC_1                          0xa23c
+/* [RW 32] second 32b for inverting the input for function 0; for each bit:
+   0= do not invert; 1= invert. mapped as follows: [0] PBClient Parity
+   error; [1] PBClient Hw interrupt; [2] QM Parity error; [3] QM Hw
+   interrupt; [4] Timers Parity error; [5] Timers Hw interrupt; [6] XSDM
+   Parity error; [7] XSDM Hw interrupt; [8] XCM Parity error; [9] XCM Hw
+   interrupt; [10] XSEMI Parity error; [11] XSEMI Hw interrupt; [12]
+   DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] NIG Parity
+   error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; [17] Vaux
+   PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw interrupt;
+   [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM Parity error;
+   [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI Hw interrupt;
+   [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM Parity error;
+   [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw interrupt; */
+#define MISC_REG_AEU_INVERTER_2_FUNC_0                          0xa230
+#define MISC_REG_AEU_INVERTER_2_FUNC_1                          0xa240
+/* [RW 10] [7:0] = mask 8 attention output signals toward IGU function0;
+   [9:8] = mask close the gates signals of function 0 toward PXP [8] and NIG
+   [9]. Zero = mask; one = unmask */
+#define MISC_REG_AEU_MASK_ATTN_FUNC_0                           0xa060
+#define MISC_REG_AEU_MASK_ATTN_FUNC_1                           0xa064
+/* [R 4] This field indicates the type of the device. '0' - 2 Ports; '1' - 1
+   Port. */
+#define MISC_REG_BOND_ID                                        0xa400
+/* [R 8] These bits indicate the metal revision of the chip. This value
+   starts at 0x00 for each all-layer tape-out and increments by one for each
+   tape-out. */
+#define MISC_REG_CHIP_METAL                                     0xa404
+/* [R 16] These bits indicate the part number for the chip. */
+#define MISC_REG_CHIP_NUM                                       0xa408
+/* [R 4] These bits indicate the base revision of the chip. This value
+   starts at 0x0 for the A0 tape-out and increments by one for each
+   all-layer tape-out. */
+#define MISC_REG_CHIP_REV                                       0xa40c
+/* [RW 1] Setting this bit enables a timer in the GRC block to timeout any
+   access that does not finish within
+   ~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is
+   cleared; this timeout is disabled. If this timeout occurs; the GRC shall
+   assert it attention output. */
+#define MISC_REG_GRC_TIMEOUT_EN                                 0xa280
+/* [RW 28] 28 LSB of LCPLL first register; reset val = 521. inside order of
+   the bits is: [2:0] OAC reset value 001) CML output buffer bias control;
+   111 for +40%; 011 for +20%; 001 for 0%; 000 for -20%. [5:3] Icp_ctrl
+   (reset value 001) Charge pump current control; 111 for 720u; 011 for
+   600u; 001 for 480u and 000 for 360u. [7:6] Bias_ctrl (reset value 00)
+   Global bias control; When bit 7 is high bias current will be 10 0gh; When
+   bit 6 is high bias will be 100w; Valid values are 00; 10; 01. [10:8]
+   Pll_observe (reset value 010) Bits to control observability. bit 10 is
+   for test bias; bit 9 is for test CK; bit 8 is test Vc. [12:11] Vth_ctrl
+   (reset value 00) Comparator threshold control. 00 for 0.6V; 01 for 0.54V
+   and 10 for 0.66V. [13] pllSeqStart (reset value 0) Enables VCO tuning
+   sequencer: 1= sequencer disabled; 0= sequencer enabled (inverted
+   internally). [14] reserved (reset value 0) Reset for VCO sequencer is
+   connected to RESET input directly. [15] capRetry_en (reset value 0)
+   enable retry on cap search failure (inverted). [16] freqMonitor_e (reset
+   value 0) bit to continuously monitor vco freq (inverted). [17]
+   freqDetRestart_en (reset value 0) bit to enable restart when not freq
+   locked (inverted). [18] freqDetRetry_en (reset value 0) bit to enable
+   retry on freq det failure(inverted). [19] pllForceFdone_en (reset value
+   0) bit to enable pllForceFdone & pllForceFpass into pllSeq. [20]
+   pllForceFdone (reset value 0) bit to force freqDone. [21] pllForceFpass
+   (reset value 0) bit to force freqPass. [22] pllForceDone_en (reset value
+   0) bit to enable pllForceCapDone. [23] pllForceCapDone (reset value 0)
+   bit to force capDone. [24] pllForceCapPass_en (reset value 0) bit to
+   enable pllForceCapPass. [25] pllForceCapPass (reset value 0) bit to force
+   capPass. [26] capRestart (reset value 0) bit to force cap sequencer to
+   restart. [27] capSelectM_en (reset value 0) bit to enable cap select
+   register bits. */
+#define MISC_REG_LCPLL_CTRL_1                                   0xa2a4
+#define MISC_REG_LCPLL_CTRL_REG_2                               0xa2a8
+/* [RW 4] Interrupt mask register #0 read/write */
+#define MISC_REG_MISC_INT_MASK                                  0xa388
+/* [RW 1] Parity mask register #0 read/write */
+#define MISC_REG_MISC_PRTY_MASK                                 0xa398
+/* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911.
+   inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1
+   divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1
+   divider[3] (reset value 0); [4] P2 divider[0] (reset value 1); [5] P2
+   divider[1] (reset value 0); [6] P2 divider[2] (reset value 0); [7] P2
+   divider[3] (reset value 0); [8] ph_det_dis (reset value 1); [9]
+   freq_det_dis (reset value 0); [10] Icpx[0] (reset value 0); [11] Icpx[1]
+   (reset value 1); [12] Icpx[2] (reset value 0); [13] Icpx[3] (reset value
+   1); [14] Icpx[4] (reset value 0); [15] Icpx[5] (reset value 0); [16]
+   Rx[0] (reset value 1); [17] Rx[1] (reset value 0); [18] vc_en (reset
+   value 1); [19] vco_rng[0] (reset value 1); [20] vco_rng[1] (reset value
+   1); [21] Kvco_xf[0] (reset value 0); [22] Kvco_xf[1] (reset value 0);
+   [23] Kvco_xf[2] (reset value 0); [24] Kvco_xs[0] (reset value 1); [25]
+   Kvco_xs[1] (reset value 1); [26] Kvco_xs[2] (reset value 1); [27]
+   testd_en (reset value 0); [28] testd_sel[0] (reset value 0); [29]
+   testd_sel[1] (reset value 0); [30] testd_sel[2] (reset value 0); [31]
+   testa_en (reset value 0); */
+#define MISC_REG_PLL_STORM_CTRL_1                               0xa294
+#define MISC_REG_PLL_STORM_CTRL_2                               0xa298
+#define MISC_REG_PLL_STORM_CTRL_3                               0xa29c
+#define MISC_REG_PLL_STORM_CTRL_4                               0xa2a0
+/* [RW 32] reset reg#1; rite/read one = the specific block is out of reset;
+   write/read zero = the specific block is in reset; addr 0-wr- the write
+   value will be written to the register; addr 1-set - one will be written
+   to all the bits that have the value of one in the data written (bits that
+   have the value of zero will not be change) ; addr 2-clear - zero will be
+   written to all the bits that have the value of one in the data written
+   (bits that have the value of zero will not be change); addr 3-ignore;
+   read ignore from all addr except addr 00; inside order of the bits is:
+   [0] rst_brb1; [1] rst_prs; [2] rst_src; [3] rst_tsdm; [4] rst_tsem; [5]
+   rst_tcm; [6] rst_rbcr; [7] rst_nig; [8] rst_usdm; [9] rst_ucm; [10]
+   rst_usem; [11] rst_upb; [12] rst_ccm; [13] rst_csem; [14] rst_csdm; [15]
+   rst_rbcu; [16] rst_pbf; [17] rst_qm; [18] rst_tm; [19] rst_dorq; [20]
+   rst_xcm; [21] rst_xsdm; [22] rst_xsem; [23] rst_rbct; [24] rst_cdu; [25]
+   rst_cfc; [26] rst_pxp; [27] rst_pxpv; [28] rst_rbcp; [29] rst_hc; [30]
+   rst_dmae; [31] rst_semi_rtc; */
+#define MISC_REG_RESET_REG_1                                    0xa580
+#define MISC_REG_RESET_REG_2                                    0xa590
+/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is
+   shared with the driver resides */
+#define MISC_REG_SHARED_MEM_ADDR                                0xa2b4
+#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT     (0x1<<0)
+#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS   (0x1<<9)
+#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G         (0x1<<15)
+#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS     (0xf<<18)
+/* [RW 1] Input enable for RX_BMAC0 IF */
+#define NIG_REG_BMAC0_IN_EN                                     0x100ac
+/* [RW 1] output enable for TX_BMAC0 IF */
+#define NIG_REG_BMAC0_OUT_EN                                    0x100e0
+/* [RW 1] output enable for TX BMAC pause port 0 IF */
+#define NIG_REG_BMAC0_PAUSE_OUT_EN                              0x10110
+/* [RW 1] output enable for RX_BMAC0_REGS IF */
+#define NIG_REG_BMAC0_REGS_OUT_EN                               0x100e8
+/* [RW 1] output enable for RX BRB1 port0 IF */
+#define NIG_REG_BRB0_OUT_EN                                     0x100f8
+/* [RW 1] Input enable for TX BRB1 pause port 0 IF */
+#define NIG_REG_BRB0_PAUSE_IN_EN                                0x100c4
+/* [RW 1] output enable for RX BRB1 port1 IF */
+#define NIG_REG_BRB1_OUT_EN                                     0x100fc
+/* [RW 1] Input enable for TX BRB1 pause port 1 IF */
+#define NIG_REG_BRB1_PAUSE_IN_EN                                0x100c8
+/* [RW 1] output enable for RX BRB1 LP IF */
+#define NIG_REG_BRB_LB_OUT_EN                                   0x10100
+/* [WB_W 72] Debug packet to LP from RBC; Data spelling:[63:0] data; 64]
+   error; [67:65]eop_bvalid; [68]eop; [69]sop; [70]port_id; 71]flush */
+#define NIG_REG_DEBUG_PACKET_LB                                 0x10800
+/* [RW 1] Input enable for TX Debug packet */
+#define NIG_REG_EGRESS_DEBUG_IN_EN                              0x100dc
+/* [RW 1] If 1 - egress drain mode for port0 is active. In this mode all
+   packets from PBFare not forwarded to the MAC and just deleted from FIFO.
+   First packet may be deleted from the middle. And last packet will be
+   always deleted till the end. */
+#define NIG_REG_EGRESS_DRAIN0_MODE                              0x10060
+/* [RW 1] Output enable to EMAC0 */
+#define NIG_REG_EGRESS_EMAC0_OUT_EN                             0x10120
+/* [RW 1] MAC configuration for packets of port0. If 1 - all packet outputs
+   to emac for port0; other way to bmac for port0 */
+#define NIG_REG_EGRESS_EMAC0_PORT                               0x10058
+/* [RW 1] Input enable for TX PBF user packet port0 IF */
+#define NIG_REG_EGRESS_PBF0_IN_EN                               0x100cc
+/* [RW 1] Input enable for TX PBF user packet port1 IF */
+#define NIG_REG_EGRESS_PBF1_IN_EN                               0x100d0
+/* [RW 1] Input enable for RX_EMAC0 IF */
+#define NIG_REG_EMAC0_IN_EN                                     0x100a4
+/* [RW 1] output enable for TX EMAC pause port 0 IF */
+#define NIG_REG_EMAC0_PAUSE_OUT_EN                              0x10118
+/* [R 1] status from emac0. This bit is set when MDINT from either the
+   EXT_MDINT pin or from the Copper PHY is driven low. This condition must
+   be cleared in the attached PHY device that is driving the MINT pin. */
+#define NIG_REG_EMAC0_STATUS_MISC_MI_INT                        0x10494
+/* [WB 48] This address space contains BMAC0 registers. The BMAC registers
+   are described in appendix A. In order to access the BMAC0 registers; the
+   base address; NIG_REGISTERS_INGRESS_BMAC0_MEM; Offset: 0x10c00; should be
+   added to each BMAC register offset */
+#define NIG_REG_INGRESS_BMAC0_MEM                               0x10c00
+/* [WB 48] This address space contains BMAC1 registers. The BMAC registers
+   are described in appendix A. In order to access the BMAC0 registers; the
+   base address; NIG_REGISTERS_INGRESS_BMAC1_MEM; Offset: 0x11000; should be
+   added to each BMAC register offset */
+#define NIG_REG_INGRESS_BMAC1_MEM                               0x11000
+/* [R 1] FIFO empty in EOP descriptor FIFO of LP in NIG_RX_EOP */
+#define NIG_REG_INGRESS_EOP_LB_EMPTY                            0x104e0
+/* [RW 17] Debug only. RX_EOP_DSCR_lb_FIFO in NIG_RX_EOP. Data
+   packet_length[13:0]; mac_error[14]; trunc_error[15]; parity[16] */
+#define NIG_REG_INGRESS_EOP_LB_FIFO                             0x104e4
+/* [RW 1] led 10g for port 0 */
+#define NIG_REG_LED_10G_P0                                      0x10320
+/* [RW 1] Port0: This bit is set to enable the use of the
+   ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 field
+   defined below. If this bit is cleared; then the blink rate will be about
+   8Hz. */
+#define NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0                   0x10318
+/* [RW 12] Port0: Specifies the period of each blink cycle (on + off) for
+   Traffic LED in milliseconds. Must be a non-zero value. This 12-bit field
+   is reset to 0x080; giving a default blink period of approximately 8Hz. */
+#define NIG_REG_LED_CONTROL_BLINK_RATE_P0                       0x10310
+/* [RW 1] Port0: If set along with the
+   nig_registers_led_control_override_traffic_p0.led_control_override_traffic_p0
+   bit and ~nig_registers_led_control_traffic_p0.led_control_traffic_p0 LED
+   bit; the Traffic LED will blink with the blink rate specified in
+   ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 and
+   ~nig_registers_led_control_blink_rate_ena_p0.led_control_blink_rate_ena_p0
+   fields. */
+#define NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0                    0x10308
+/* [RW 1] Port0: If set overrides hardware control of the Traffic LED. The
+   Traffic LED will then be controlled via bit ~nig_registers_
+   led_control_traffic_p0.led_control_traffic_p0 and bit
+   ~nig_registers_led_control_blink_traffic_p0.led_control_blink_traffic_p0 */
+#define NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0                 0x102f8
+/* [RW 1] Port0: If set along with the led_control_override_trafic_p0 bit;
+   turns on the Traffic LED. If the led_control_blink_traffic_p0 bit is also
+   set; the LED will blink with blink rate specified in
+   ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 and
+   ~nig_regsters_led_control_blink_rate_ena_p0.led_control_blink_rate_ena_p0
+   fields. */
+#define NIG_REG_LED_CONTROL_TRAFFIC_P0                          0x10300
+/* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3;
+   9-11PHY7; 12 MAC4; 13-15 PHY10; */
+#define NIG_REG_LED_MODE_P0                                     0x102f0
+#define NIG_REG_LLH0_BRB1_DRV_MASK                              0x10244
+/* [RW 1] send to BRB1 if no match on any of RMP rules. */
+#define NIG_REG_LLH0_BRB1_NOT_MCP                               0x1025c
+/* [RW 32] cm header for llh0 */
+#define NIG_REG_LLH0_CM_HEADER                                  0x1007c
+#define NIG_REG_LLH0_ERROR_MASK                                 0x1008c
+/* [RW 8] event id for llh0 */
+#define NIG_REG_LLH0_EVENT_ID                                   0x10084
+/* [RW 8] init credit counter for port0 in LLH */
+#define NIG_REG_LLH0_XCM_INIT_CREDIT                            0x10554
+#define NIG_REG_LLH0_XCM_MASK                                   0x10130
+/* [RW 1] send to BRB1 if no match on any of RMP rules. */
+#define NIG_REG_LLH1_BRB1_NOT_MCP                               0x102dc
+/* [RW 32] cm header for llh1 */
+#define NIG_REG_LLH1_CM_HEADER                                  0x10080
+#define NIG_REG_LLH1_ERROR_MASK                                 0x10090
+/* [RW 8] event id for llh1 */
+#define NIG_REG_LLH1_EVENT_ID                                   0x10088
+/* [RW 8] init credit counter for port1 in LLH */
+#define NIG_REG_LLH1_XCM_INIT_CREDIT                            0x10564
+#define NIG_REG_LLH1_XCM_MASK                                   0x10134
+#define NIG_REG_MASK_INTERRUPT_PORT0                            0x10330
+#define NIG_REG_MASK_INTERRUPT_PORT1                            0x10334
+/* [RW 1] Output signal from NIG to EMAC0. When set enables the EMAC0 block. */
+#define NIG_REG_NIG_EMAC0_EN                                    0x1003c
+/* [RW 1] Output signal from NIG to TX_EMAC0. When set indicates to the
+   EMAC0 to strip the CRC from the ingress packets. */
+#define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC                        0x10044
+/* [RW 1] Input enable for RX PBF LP IF */
+#define NIG_REG_PBF_LB_IN_EN                                    0x100b4
+/* [RW 1] output enable for RX parser descriptor IF */
+#define NIG_REG_PRS_EOP_OUT_EN                                  0x10104
+/* [RW 1] Input enable for RX parser request IF */
+#define NIG_REG_PRS_REQ_IN_EN                                   0x100b8
+/* [RW 5] control to serdes - CL22 PHY_ADD and CL45 PRTAD */
+#define NIG_REG_SERDES0_CTRL_PHY_ADDR                           0x10374
+/* [R 1] status from serdes0 that inputs to interrupt logic of link status */
+#define NIG_REG_SERDES0_STATUS_LINK_STATUS                      0x10578
+/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure
+   for port0 */
+#define NIG_REG_STAT0_BRB_DISCARD                               0x105f0
+/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure
+   for port1 */
+#define NIG_REG_STAT1_BRB_DISCARD                               0x10628
+/* [WB_R 64] Rx statistics : User octets received for LP */
+#define NIG_REG_STAT2_BRB_OCTET                                 0x107e0
+#define NIG_REG_STATUS_INTERRUPT_PORT0                          0x10328
+#define NIG_REG_STATUS_INTERRUPT_PORT1                          0x1032c
+/* [RW 1] output enable for RX_XCM0 IF */
+#define NIG_REG_XCM0_OUT_EN                                     0x100f0
+/* [RW 1] output enable for RX_XCM1 IF */
+#define NIG_REG_XCM1_OUT_EN                                     0x100f4
+/* [RW 5] control to xgxs - CL45 DEVAD */
+#define NIG_REG_XGXS0_CTRL_MD_DEVAD                             0x1033c
+/* [RW 5] control to xgxs - CL22 PHY_ADD and CL45 PRTAD */
+#define NIG_REG_XGXS0_CTRL_PHY_ADDR                             0x10340
+/* [R 1] status from xgxs0 that inputs to interrupt logic of link10g. */
+#define NIG_REG_XGXS0_STATUS_LINK10G                            0x10680
+/* [R 4] status from xgxs0 that inputs to interrupt logic of link status */
+#define NIG_REG_XGXS0_STATUS_LINK_STATUS                        0x10684
+/* [RW 2] selection for XGXS lane of port 0 in NIG_MUX block */
+#define NIG_REG_XGXS_LANE_SEL_P0                                0x102e8
+/* [RW 1] selection for port0 for NIG_MUX block : 0 = SerDes; 1 = XGXS */
+#define NIG_REG_XGXS_SERDES0_MODE_SEL                           0x102e0
+#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS (0x1<<9)
+#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G     (0x1<<15)
+#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS  (0xf<<18)
+#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18
+/* [RW 1] Disable processing further tasks from port 0 (after ending the
+   current task in process). */
+#define PBF_REG_DISABLE_NEW_TASK_PROC_P0                        0x14005c
+/* [RW 1] Disable processing further tasks from port 1 (after ending the
+   current task in process). */
+#define PBF_REG_DISABLE_NEW_TASK_PROC_P1                        0x140060
+/* [RW 1] Disable processing further tasks from port 4 (after ending the
+   current task in process). */
+#define PBF_REG_DISABLE_NEW_TASK_PROC_P4                        0x14006c
+#define PBF_REG_IF_ENABLE_REG                                   0x140044
+/* [RW 1] Init bit. When set the initial credits are copied to the credit
+   registers (except the port credits). Should be set and then reset after
+   the configuration of the block has ended. */
+#define PBF_REG_INIT                                            0x140000
+/* [RW 1] Init bit for port 0. When set the initial credit of port 0 is
+   copied to the credit register. Should be set and then reset after the
+   configuration of the port has ended. */
+#define PBF_REG_INIT_P0                                         0x140004
+/* [RW 1] Init bit for port 1. When set the initial credit of port 1 is
+   copied to the credit register. Should be set and then reset after the
+   configuration of the port has ended. */
+#define PBF_REG_INIT_P1                                         0x140008
+/* [RW 1] Init bit for port 4. When set the initial credit of port 4 is
+   copied to the credit register. Should be set and then reset after the
+   configuration of the port has ended. */
+#define PBF_REG_INIT_P4                                         0x14000c
+/* [RW 1] Enable for mac interface 0. */
+#define PBF_REG_MAC_IF0_ENABLE                                  0x140030
+/* [RW 1] Enable for mac interface 1. */
+#define PBF_REG_MAC_IF1_ENABLE                                  0x140034
+/* [RW 1] Enable for the loopback interface. */
+#define PBF_REG_MAC_LB_ENABLE                                   0x140040
+/* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause
+   not suppoterd. */
+#define PBF_REG_P0_ARB_THRSH                                    0x1400e4
+/* [R 11] Current credit for port 0 in the tx port buffers in 16 byte lines. */
+#define PBF_REG_P0_CREDIT                                       0x140200
+/* [RW 11] Initial credit for port 0 in the tx port buffers in 16 byte
+   lines. */
+#define PBF_REG_P0_INIT_CRD                                     0x1400d0
+/* [RW 1] Indication that pause is enabled for port 0. */
+#define PBF_REG_P0_PAUSE_ENABLE                                 0x140014
+/* [R 8] Number of tasks in port 0 task queue. */
+#define PBF_REG_P0_TASK_CNT                                     0x140204
+/* [R 11] Current credit for port 1 in the tx port buffers in 16 byte lines. */
+#define PBF_REG_P1_CREDIT                                       0x140208
+/* [RW 11] Initial credit for port 1 in the tx port buffers in 16 byte
+   lines. */
+#define PBF_REG_P1_INIT_CRD                                     0x1400d4
+/* [R 8] Number of tasks in port 1 task queue. */
+#define PBF_REG_P1_TASK_CNT                                     0x14020c
+/* [R 11] Current credit for port 4 in the tx port buffers in 16 byte lines. */
+#define PBF_REG_P4_CREDIT                                       0x140210
+/* [RW 11] Initial credit for port 4 in the tx port buffers in 16 byte
+   lines. */
+#define PBF_REG_P4_INIT_CRD                                     0x1400e0
+/* [R 8] Number of tasks in port 4 task queue. */
+#define PBF_REG_P4_TASK_CNT                                     0x140214
+/* [RW 5] Interrupt mask register #0 read/write */
+#define PBF_REG_PBF_INT_MASK                                    0x1401d4
+/* [R 5] Interrupt register #0 read */
+#define PBF_REG_PBF_INT_STS                                     0x1401c8
+#define PB_REG_CONTROL                                          0
+/* [RW 2] Interrupt mask register #0 read/write */
+#define PB_REG_PB_INT_MASK                                      0x28
+/* [R 2] Interrupt register #0 read */
+#define PB_REG_PB_INT_STS                                       0x1c
+/* [RW 4] Parity mask register #0 read/write */
+#define PB_REG_PB_PRTY_MASK                                     0x38
+#define PRS_REG_A_PRSU_20                                       0x40134
+/* [R 8] debug only: CFC load request current credit. Transaction based. */
+#define PRS_REG_CFC_LD_CURRENT_CREDIT                           0x40164
+/* [R 8] debug only: CFC search request current credit. Transaction based. */
+#define PRS_REG_CFC_SEARCH_CURRENT_CREDIT                       0x40168
+/* [RW 6] The initial credit for the search message to the CFC interface.
+   Credit is transaction based. */
+#define PRS_REG_CFC_SEARCH_INITIAL_CREDIT                       0x4011c
+/* [RW 24] CID for port 0 if no match */
+#define PRS_REG_CID_PORT_0                                      0x400fc
+#define PRS_REG_CID_PORT_1                                      0x40100
+/* [RW 32] The CM header for flush message where 'load existed' bit in CFC
+   load response is reset and packet type is 0. Used in packet start message
+   to TCM. */
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0                        0x400dc
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1                        0x400e0
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2                        0x400e4
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3                        0x400e8
+#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4                        0x400ec
+/* [RW 32] The CM header for flush message where 'load existed' bit in CFC
+   load response is set and packet type is 0. Used in packet start message
+   to TCM. */
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0                     0x400bc
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1                     0x400c0
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2                     0x400c4
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3                     0x400c8
+#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4                     0x400cc
+/* [RW 32] The CM header for a match and packet type 1 for loopback port.
+   Used in packet start message to TCM. */
+#define PRS_REG_CM_HDR_LOOPBACK_TYPE_1                          0x4009c
+#define PRS_REG_CM_HDR_LOOPBACK_TYPE_2                          0x400a0
+#define PRS_REG_CM_HDR_LOOPBACK_TYPE_3                          0x400a4
+#define PRS_REG_CM_HDR_LOOPBACK_TYPE_4                          0x400a8
+/* [RW 32] The CM header for a match and packet type 0. Used in packet start
+   message to TCM. */
+#define PRS_REG_CM_HDR_TYPE_0                                   0x40078
+#define PRS_REG_CM_HDR_TYPE_1                                   0x4007c
+#define PRS_REG_CM_HDR_TYPE_2                                   0x40080
+#define PRS_REG_CM_HDR_TYPE_3                                   0x40084
+#define PRS_REG_CM_HDR_TYPE_4                                   0x40088
+/* [RW 32] The CM header in case there was not a match on the connection */
+#define PRS_REG_CM_NO_MATCH_HDR                                 0x400b8
+/* [RW 8] The 8-bit event ID for a match and packet type 1. Used in packet
+   start message to TCM. */
+#define PRS_REG_EVENT_ID_1                                      0x40054
+#define PRS_REG_EVENT_ID_2                                      0x40058
+#define PRS_REG_EVENT_ID_3                                      0x4005c
+/* [RW 8] Context region for flush packet with packet type 0. Used in CFC
+   load request message. */
+#define PRS_REG_FLUSH_REGIONS_TYPE_0                            0x40004
+#define PRS_REG_FLUSH_REGIONS_TYPE_1                            0x40008
+#define PRS_REG_FLUSH_REGIONS_TYPE_2                            0x4000c
+#define PRS_REG_FLUSH_REGIONS_TYPE_3                            0x40010
+#define PRS_REG_FLUSH_REGIONS_TYPE_4                            0x40014
+#define PRS_REG_FLUSH_REGIONS_TYPE_5                            0x40018
+#define PRS_REG_FLUSH_REGIONS_TYPE_6                            0x4001c
+#define PRS_REG_FLUSH_REGIONS_TYPE_7                            0x40020
+/* [RW 4] The increment value to send in the CFC load request message */
+#define PRS_REG_INC_VALUE                                       0x40048
+/* [RW 1] If set indicates not to send messages to CFC on received packets */
+#define PRS_REG_NIC_MODE                                        0x40138
+/* [RW 8] The 8-bit event ID for cases where there is no match on the
+   connection. Used in packet start message to TCM. */
+#define PRS_REG_NO_MATCH_EVENT_ID                               0x40070
+/* [ST 24] The number of input CFC flush packets */
+#define PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES                       0x40128
+/* [ST 32] The number of cycles the Parser halted its operation since it
+   could not allocate the next serial number */
+#define PRS_REG_NUM_OF_DEAD_CYCLES                              0x40130
+/* [ST 24] The number of input packets */
+#define PRS_REG_NUM_OF_PACKETS                                  0x40124
+/* [ST 24] The number of input transparent flush packets */
+#define PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES               0x4012c
+/* [RW 8] Context region for received Ethernet packet with a match and
+   packet type 0. Used in CFC load request message */
+#define PRS_REG_PACKET_REGIONS_TYPE_0                           0x40028
+#define PRS_REG_PACKET_REGIONS_TYPE_1                           0x4002c
+#define PRS_REG_PACKET_REGIONS_TYPE_2                           0x40030
+#define PRS_REG_PACKET_REGIONS_TYPE_3                           0x40034
+#define PRS_REG_PACKET_REGIONS_TYPE_4                           0x40038
+#define PRS_REG_PACKET_REGIONS_TYPE_5                           0x4003c
+#define PRS_REG_PACKET_REGIONS_TYPE_6                           0x40040
+#define PRS_REG_PACKET_REGIONS_TYPE_7                           0x40044
+/* [R 2] debug only: Number of pending requests for CAC on port 0. */
+#define PRS_REG_PENDING_BRB_CAC0_RQ                             0x40174
+/* [R 2] debug only: Number of pending requests for header parsing. */
+#define PRS_REG_PENDING_BRB_PRS_RQ                              0x40170
+/* [R 1] Interrupt register #0 read */
+#define PRS_REG_PRS_INT_STS                                     0x40188
+/* [RW 8] Parity mask register #0 read/write */
+#define PRS_REG_PRS_PRTY_MASK                                   0x401a4
+/* [RW 8] Context region for pure acknowledge packets. Used in CFC load
+   request message */
+#define PRS_REG_PURE_REGIONS                                    0x40024
+/* [R 32] debug only: Serial number status lsb 32 bits. '1' indicates this
+   serail number was released by SDM but cannot be used because a previous
+   serial number was not released. */
+#define PRS_REG_SERIAL_NUM_STATUS_LSB                           0x40154
+/* [R 32] debug only: Serial number status msb 32 bits. '1' indicates this
+   serail number was released by SDM but cannot be used because a previous
+   serial number was not released. */
+#define PRS_REG_SERIAL_NUM_STATUS_MSB                           0x40158
+/* [R 4] debug only: SRC current credit. Transaction based. */
+#define PRS_REG_SRC_CURRENT_CREDIT                              0x4016c
+/* [R 8] debug only: TCM current credit. Cycle based. */
+#define PRS_REG_TCM_CURRENT_CREDIT                              0x40160
+/* [R 8] debug only: TSDM current credit. Transaction based. */
+#define PRS_REG_TSDM_CURRENT_CREDIT                             0x4015c
+/* [R 6] Debug only: Number of used entries in the data FIFO */
+#define PXP2_REG_HST_DATA_FIFO_STATUS                           0x12047c
+/* [R 7] Debug only: Number of used entries in the header FIFO */
+#define PXP2_REG_HST_HEADER_FIFO_STATUS                         0x120478
+#define PXP2_REG_PGL_CONTROL0                                   0x120490
+#define PXP2_REG_PGL_CONTROL1                                   0x120514
+/* [RW 32] Inbound interrupt table for CSDM: bits[31:16]-mask;
+   its[15:0]-address */
+#define PXP2_REG_PGL_INT_CSDM_0                                 0x1204f4
+#define PXP2_REG_PGL_INT_CSDM_1                                 0x1204f8
+#define PXP2_REG_PGL_INT_CSDM_2                                 0x1204fc
+#define PXP2_REG_PGL_INT_CSDM_3                                 0x120500
+#define PXP2_REG_PGL_INT_CSDM_4                                 0x120504
+#define PXP2_REG_PGL_INT_CSDM_5                                 0x120508
+#define PXP2_REG_PGL_INT_CSDM_6                                 0x12050c
+#define PXP2_REG_PGL_INT_CSDM_7                                 0x120510
+/* [RW 32] Inbound interrupt table for TSDM: bits[31:16]-mask;
+   its[15:0]-address */
+#define PXP2_REG_PGL_INT_TSDM_0                                 0x120494
+#define PXP2_REG_PGL_INT_TSDM_1                                 0x120498
+#define PXP2_REG_PGL_INT_TSDM_2                                 0x12049c
+#define PXP2_REG_PGL_INT_TSDM_3                                 0x1204a0
+#define PXP2_REG_PGL_INT_TSDM_4                                 0x1204a4
+#define PXP2_REG_PGL_INT_TSDM_5                                 0x1204a8
+#define PXP2_REG_PGL_INT_TSDM_6                                 0x1204ac
+#define PXP2_REG_PGL_INT_TSDM_7                                 0x1204b0
+/* [RW 32] Inbound interrupt table for USDM: bits[31:16]-mask;
+   its[15:0]-address */
+#define PXP2_REG_PGL_INT_USDM_0                                 0x1204b4
+#define PXP2_REG_PGL_INT_USDM_1                                 0x1204b8
+#define PXP2_REG_PGL_INT_USDM_2                                 0x1204bc
+#define PXP2_REG_PGL_INT_USDM_3                                 0x1204c0
+#define PXP2_REG_PGL_INT_USDM_4                                 0x1204c4
+#define PXP2_REG_PGL_INT_USDM_5                                 0x1204c8
+#define PXP2_REG_PGL_INT_USDM_6                                 0x1204cc
+#define PXP2_REG_PGL_INT_USDM_7                                 0x1204d0
+/* [RW 32] Inbound interrupt table for XSDM: bits[31:16]-mask;
+   its[15:0]-address */
+#define PXP2_REG_PGL_INT_XSDM_0                                 0x1204d4
+#define PXP2_REG_PGL_INT_XSDM_1                                 0x1204d8
+#define PXP2_REG_PGL_INT_XSDM_2                                 0x1204dc
+#define PXP2_REG_PGL_INT_XSDM_3                                 0x1204e0
+#define PXP2_REG_PGL_INT_XSDM_4                                 0x1204e4
+#define PXP2_REG_PGL_INT_XSDM_5                                 0x1204e8
+#define PXP2_REG_PGL_INT_XSDM_6                                 0x1204ec
+#define PXP2_REG_PGL_INT_XSDM_7                                 0x1204f0
+/* [R 1] this bit indicates that a read request was blocked because of
+   bus_master_en was deasserted */
+#define PXP2_REG_PGL_READ_BLOCKED                               0x120568
+/* [R 6] debug only */
+#define PXP2_REG_PGL_TXR_CDTS                                   0x120528
+/* [R 18] debug only */
+#define PXP2_REG_PGL_TXW_CDTS                                   0x12052c
+/* [R 1] this bit indicates that a write request was blocked because of
+   bus_master_en was deasserted */
+#define PXP2_REG_PGL_WRITE_BLOCKED                              0x120564
+#define PXP2_REG_PSWRQ_BW_ADD1                                  0x1201c0
+#define PXP2_REG_PSWRQ_BW_ADD10                                 0x1201e4
+#define PXP2_REG_PSWRQ_BW_ADD11                                 0x1201e8
+#define PXP2_REG_PSWRQ_BW_ADD10                                 0x1201e4
+#define PXP2_REG_PSWRQ_BW_ADD11                                 0x1201e8
+#define PXP2_REG_PSWRQ_BW_ADD2                                  0x1201c4
+#define PXP2_REG_PSWRQ_BW_ADD28                                 0x120228
+#define PXP2_REG_PSWRQ_BW_ADD28                                 0x120228
+#define PXP2_REG_PSWRQ_BW_ADD3                                  0x1201c8
+#define PXP2_REG_PSWRQ_BW_ADD6                                  0x1201d4
+#define PXP2_REG_PSWRQ_BW_ADD7                                  0x1201d8
+#define PXP2_REG_PSWRQ_BW_ADD8                                  0x1201dc
+#define PXP2_REG_PSWRQ_BW_ADD9                                  0x1201e0
+#define PXP2_REG_PSWRQ_BW_CREDIT                                0x12032c
+#define PXP2_REG_PSWRQ_BW_L1                                    0x1202b0
+#define PXP2_REG_PSWRQ_BW_L10                                   0x1202d4
+#define PXP2_REG_PSWRQ_BW_L11                                   0x1202d8
+#define PXP2_REG_PSWRQ_BW_L10                                   0x1202d4
+#define PXP2_REG_PSWRQ_BW_L11                                   0x1202d8
+#define PXP2_REG_PSWRQ_BW_L2                                    0x1202b4
+#define PXP2_REG_PSWRQ_BW_L28                                   0x120318
+#define PXP2_REG_PSWRQ_BW_L28                                   0x120318
+#define PXP2_REG_PSWRQ_BW_L3                                    0x1202b8
+#define PXP2_REG_PSWRQ_BW_L6                                    0x1202c4
+#define PXP2_REG_PSWRQ_BW_L7                                    0x1202c8
+#define PXP2_REG_PSWRQ_BW_L8                                    0x1202cc
+#define PXP2_REG_PSWRQ_BW_L9                                    0x1202d0
+#define PXP2_REG_PSWRQ_BW_RD                                    0x120324
+#define PXP2_REG_PSWRQ_BW_UB1                                   0x120238
+#define PXP2_REG_PSWRQ_BW_UB10                                  0x12025c
+#define PXP2_REG_PSWRQ_BW_UB11                                  0x120260
+#define PXP2_REG_PSWRQ_BW_UB10                                  0x12025c
+#define PXP2_REG_PSWRQ_BW_UB11                                  0x120260
+#define PXP2_REG_PSWRQ_BW_UB2                                   0x12023c
+#define PXP2_REG_PSWRQ_BW_UB28                                  0x1202a0
+#define PXP2_REG_PSWRQ_BW_UB28                                  0x1202a0
+#define PXP2_REG_PSWRQ_BW_UB3                                   0x120240
+#define PXP2_REG_PSWRQ_BW_UB6                                   0x12024c
+#define PXP2_REG_PSWRQ_BW_UB7                                   0x120250
+#define PXP2_REG_PSWRQ_BW_UB8                                   0x120254
+#define PXP2_REG_PSWRQ_BW_UB9                                   0x120258
+#define PXP2_REG_PSWRQ_BW_WR                                    0x120328
+#define PXP2_REG_PSWRQ_CDU0_L2P                                 0x120000
+#define PXP2_REG_PSWRQ_QM0_L2P                                  0x120038
+#define PXP2_REG_PSWRQ_SRC0_L2P                                 0x120054
+#define PXP2_REG_PSWRQ_TM0_L2P                                  0x12001c
+/* [RW 25] Interrupt mask register #0 read/write */
+#define PXP2_REG_PXP2_INT_MASK                                  0x120578
+/* [R 25] Interrupt register #0 read */
+#define PXP2_REG_PXP2_INT_STS                                   0x12056c
+/* [RC 25] Interrupt register #0 read clear */
+#define PXP2_REG_PXP2_INT_STS_CLR                               0x120570
+/* [RW 32] Parity mask register #0 read/write */
+#define PXP2_REG_PXP2_PRTY_MASK_0                               0x120588
+#define PXP2_REG_PXP2_PRTY_MASK_1                               0x120598
+/* [R 1] Debug only: The 'almost full' indication from each fifo (gives
+   indication about backpressure) */
+#define PXP2_REG_RD_ALMOST_FULL_0                               0x120424
+/* [R 8] Debug only: The blocks counter - number of unused block ids */
+#define PXP2_REG_RD_BLK_CNT                                     0x120418
+/* [RW 8] Debug only: Total number of available blocks in Tetris Buffer.
+   Must be bigger than 6. Normally should not be changed. */
+#define PXP2_REG_RD_BLK_NUM_CFG                                 0x12040c
+/* [RW 2] CDU byte swapping mode configuration for master read requests */
+#define PXP2_REG_RD_CDURD_SWAP_MODE                             0x120404
+/* [RW 1] When '1'; inputs to the PSWRD block are ignored */
+#define PXP2_REG_RD_DISABLE_INPUTS                              0x120374
+/* [R 1] PSWRD internal memories initialization is done */
+#define PXP2_REG_RD_INIT_DONE                                   0x120370
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq10 */
+#define PXP2_REG_RD_MAX_BLKS_VQ10                               0x1203a0
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq11 */
+#define PXP2_REG_RD_MAX_BLKS_VQ11                               0x1203a4
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq17 */
+#define PXP2_REG_RD_MAX_BLKS_VQ17                               0x1203bc
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq18 */
+#define PXP2_REG_RD_MAX_BLKS_VQ18                               0x1203c0
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq19 */
+#define PXP2_REG_RD_MAX_BLKS_VQ19                               0x1203c4
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq22 */
+#define PXP2_REG_RD_MAX_BLKS_VQ22                               0x1203d0
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq6 */
+#define PXP2_REG_RD_MAX_BLKS_VQ6                                0x120390
+/* [RW 8] The maximum number of blocks in Tetris Buffer that can be
+   allocated for vq9 */
+#define PXP2_REG_RD_MAX_BLKS_VQ9                                0x12039c
+/* [RW 2] PBF byte swapping mode configuration for master read requests */
+#define PXP2_REG_RD_PBF_SWAP_MODE                               0x1203f4
+/* [R 1] Debug only: Indication if delivery ports are idle */
+#define PXP2_REG_RD_PORT_IS_IDLE_0                              0x12041c
+#define PXP2_REG_RD_PORT_IS_IDLE_1                              0x120420
+/* [RW 2] QM byte swapping mode configuration for master read requests */
+#define PXP2_REG_RD_QM_SWAP_MODE                                0x1203f8
+/* [R 7] Debug only: The SR counter - number of unused sub request ids */
+#define PXP2_REG_RD_SR_CNT                                      0x120414
+/* [RW 2] SRC byte swapping mode configuration for master read requests */
+#define PXP2_REG_RD_SRC_SWAP_MODE                               0x120400
+/* [RW 7] Debug only: Total number of available PCI read sub-requests. Must
+   be bigger than 1. Normally should not be changed. */
+#define PXP2_REG_RD_SR_NUM_CFG                                  0x120408
+/* [RW 1] Signals the PSWRD block to start initializing internal memories */
+#define PXP2_REG_RD_START_INIT                                  0x12036c
+/* [RW 2] TM byte swapping mode configuration for master read requests */
+#define PXP2_REG_RD_TM_SWAP_MODE                                0x1203fc
+/* [RW 10] Bandwidth addition to VQ0 write requests */
+#define PXP2_REG_RQ_BW_RD_ADD0                                  0x1201bc
+/* [RW 10] Bandwidth addition to VQ12 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD12                                 0x1201ec
+/* [RW 10] Bandwidth addition to VQ13 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD13                                 0x1201f0
+/* [RW 10] Bandwidth addition to VQ14 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD14                                 0x1201f4
+/* [RW 10] Bandwidth addition to VQ15 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD15                                 0x1201f8
+/* [RW 10] Bandwidth addition to VQ16 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD16                                 0x1201fc
+/* [RW 10] Bandwidth addition to VQ17 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD17                                 0x120200
+/* [RW 10] Bandwidth addition to VQ18 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD18                                 0x120204
+/* [RW 10] Bandwidth addition to VQ19 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD19                                 0x120208
+/* [RW 10] Bandwidth addition to VQ20 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD20                                 0x12020c
+/* [RW 10] Bandwidth addition to VQ22 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD22                                 0x120210
+/* [RW 10] Bandwidth addition to VQ23 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD23                                 0x120214
+/* [RW 10] Bandwidth addition to VQ24 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD24                                 0x120218
+/* [RW 10] Bandwidth addition to VQ25 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD25                                 0x12021c
+/* [RW 10] Bandwidth addition to VQ26 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD26                                 0x120220
+/* [RW 10] Bandwidth addition to VQ27 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD27                                 0x120224
+/* [RW 10] Bandwidth addition to VQ4 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD4                                  0x1201cc
+/* [RW 10] Bandwidth addition to VQ5 read requests */
+#define PXP2_REG_RQ_BW_RD_ADD5                                  0x1201d0
+/* [RW 10] Bandwidth Typical L for VQ0 Read requests */
+#define PXP2_REG_RQ_BW_RD_L0                                    0x1202ac
+/* [RW 10] Bandwidth Typical L for VQ12 Read requests */
+#define PXP2_REG_RQ_BW_RD_L12                                   0x1202dc
+/* [RW 10] Bandwidth Typical L for VQ13 Read requests */
+#define PXP2_REG_RQ_BW_RD_L13                                   0x1202e0
+/* [RW 10] Bandwidth Typical L for VQ14 Read requests */
+#define PXP2_REG_RQ_BW_RD_L14                                   0x1202e4
+/* [RW 10] Bandwidth Typical L for VQ15 Read requests */
+#define PXP2_REG_RQ_BW_RD_L15                                   0x1202e8
+/* [RW 10] Bandwidth Typical L for VQ16 Read requests */
+#define PXP2_REG_RQ_BW_RD_L16                                   0x1202ec
+/* [RW 10] Bandwidth Typical L for VQ17 Read requests */
+#define PXP2_REG_RQ_BW_RD_L17                                   0x1202f0
+/* [RW 10] Bandwidth Typical L for VQ18 Read requests */
+#define PXP2_REG_RQ_BW_RD_L18                                   0x1202f4
+/* [RW 10] Bandwidth Typical L for VQ19 Read requests */
+#define PXP2_REG_RQ_BW_RD_L19                                   0x1202f8
+/* [RW 10] Bandwidth Typical L for VQ20 Read requests */
+#define PXP2_REG_RQ_BW_RD_L20                                   0x1202fc
+/* [RW 10] Bandwidth Typical L for VQ22 Read requests */
+#define PXP2_REG_RQ_BW_RD_L22                                   0x120300
+/* [RW 10] Bandwidth Typical L for VQ23 Read requests */
+#define PXP2_REG_RQ_BW_RD_L23                                   0x120304
+/* [RW 10] Bandwidth Typical L for VQ24 Read requests */
+#define PXP2_REG_RQ_BW_RD_L24                                   0x120308
+/* [RW 10] Bandwidth Typical L for VQ25 Read requests */
+#define PXP2_REG_RQ_BW_RD_L25                                   0x12030c
+/* [RW 10] Bandwidth Typical L for VQ26 Read requests */
+#define PXP2_REG_RQ_BW_RD_L26                                   0x120310
+/* [RW 10] Bandwidth Typical L for VQ27 Read requests */
+#define PXP2_REG_RQ_BW_RD_L27                                   0x120314
+/* [RW 10] Bandwidth Typical L for VQ4 Read requests */
+#define PXP2_REG_RQ_BW_RD_L4                                    0x1202bc
+/* [RW 10] Bandwidth Typical L for VQ5 Read- currently not used */
+#define PXP2_REG_RQ_BW_RD_L5                                    0x1202c0
+/* [RW 7] Bandwidth upper bound for VQ0 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND0                               0x120234
+/* [RW 7] Bandwidth upper bound for VQ12 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND12                              0x120264
+/* [RW 7] Bandwidth upper bound for VQ13 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND13                              0x120268
+/* [RW 7] Bandwidth upper bound for VQ14 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND14                              0x12026c
+/* [RW 7] Bandwidth upper bound for VQ15 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND15                              0x120270
+/* [RW 7] Bandwidth upper bound for VQ16 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND16                              0x120274
+/* [RW 7] Bandwidth upper bound for VQ17 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND17                              0x120278
+/* [RW 7] Bandwidth upper bound for VQ18 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND18                              0x12027c
+/* [RW 7] Bandwidth upper bound for VQ19 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND19                              0x120280
+/* [RW 7] Bandwidth upper bound for VQ20 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND20                              0x120284
+/* [RW 7] Bandwidth upper bound for VQ22 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND22                              0x120288
+/* [RW 7] Bandwidth upper bound for VQ23 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND23                              0x12028c
+/* [RW 7] Bandwidth upper bound for VQ24 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND24                              0x120290
+/* [RW 7] Bandwidth upper bound for VQ25 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND25                              0x120294
+/* [RW 7] Bandwidth upper bound for VQ26 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND26                              0x120298
+/* [RW 7] Bandwidth upper bound for VQ27 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND27                              0x12029c
+/* [RW 7] Bandwidth upper bound for VQ4 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND4                               0x120244
+/* [RW 7] Bandwidth upper bound for VQ5 read requests */
+#define PXP2_REG_RQ_BW_RD_UBOUND5                               0x120248
+/* [RW 10] Bandwidth addition to VQ29 write requests */
+#define PXP2_REG_RQ_BW_WR_ADD29                                 0x12022c
+/* [RW 10] Bandwidth addition to VQ30 write requests */
+#define PXP2_REG_RQ_BW_WR_ADD30                                 0x120230
+/* [RW 10] Bandwidth Typical L for VQ29 Write requests */
+#define PXP2_REG_RQ_BW_WR_L29                                   0x12031c
+/* [RW 10] Bandwidth Typical L for VQ30 Write requests */
+#define PXP2_REG_RQ_BW_WR_L30                                   0x120320
+/* [RW 7] Bandwidth upper bound for VQ29 */
+#define PXP2_REG_RQ_BW_WR_UBOUND29                              0x1202a4
+/* [RW 7] Bandwidth upper bound for VQ30 */
+#define PXP2_REG_RQ_BW_WR_UBOUND30                              0x1202a8
+/* [RW 2] Endian mode for cdu */
+#define PXP2_REG_RQ_CDU_ENDIAN_M                                0x1201a0
+/* [RW 3] page size in L2P table for CDU module; -4k; -8k; -16k; -32k; -64k;
+   -128k */
+#define PXP2_REG_RQ_CDU_P_SIZE                                  0x120018
+/* [R 1] 1' indicates that the requester has finished its internal
+   configuration */
+#define PXP2_REG_RQ_CFG_DONE                                    0x1201b4
+/* [RW 2] Endian mode for debug */
+#define PXP2_REG_RQ_DBG_ENDIAN_M                                0x1201a4
+/* [RW 1] When '1'; requests will enter input buffers but wont get out
+   towards the glue */
+#define PXP2_REG_RQ_DISABLE_INPUTS                              0x120330
+/* [RW 2] Endian mode for hc */
+#define PXP2_REG_RQ_HC_ENDIAN_M                                 0x1201a8
+/* [WB 53] Onchip address table */
+#define PXP2_REG_RQ_ONCHIP_AT                                   0x122000
+/* [RW 2] Endian mode for qm */
+#define PXP2_REG_RQ_QM_ENDIAN_M                                 0x120194
+/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k;
+   -128k */
+#define PXP2_REG_RQ_QM_P_SIZE                                   0x120050
+/* [RW 1] 1' indicates that the RBC has finished configurating the PSWRQ */
+#define PXP2_REG_RQ_RBC_DONE                                    0x1201b0
+/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B;
+   001:256B; 010: 512B; 11:1K:100:2K; 01:4K */
+#define PXP2_REG_RQ_RD_MBS0                                     0x120160
+/* [RW 2] Endian mode for src */
+#define PXP2_REG_RQ_SRC_ENDIAN_M                                0x12019c
+/* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k;
+   -128k */
+#define PXP2_REG_RQ_SRC_P_SIZE                                  0x12006c
+/* [RW 2] Endian mode for tm */
+#define PXP2_REG_RQ_TM_ENDIAN_M                                 0x120198
+/* [RW 3] page size in L2P table for TM module; -4k; -8k; -16k; -32k; -64k;
+   -128k */
+#define PXP2_REG_RQ_TM_P_SIZE                                   0x120034
+/* [R 5] Number of entries in the ufifo; his fifo has l2p completions */
+#define PXP2_REG_RQ_UFIFO_NUM_OF_ENTRY                          0x12080c
+/* [R 8] Number of entries occupied by vq 0 in pswrq memory */
+#define PXP2_REG_RQ_VQ0_ENTRY_CNT                               0x120810
+/* [R 8] Number of entries occupied by vq 10 in pswrq memory */
+#define PXP2_REG_RQ_VQ10_ENTRY_CNT                              0x120818
+/* [R 8] Number of entries occupied by vq 11 in pswrq memory */
+#define PXP2_REG_RQ_VQ11_ENTRY_CNT                              0x120820
+/* [R 8] Number of entries occupied by vq 12 in pswrq memory */
+#define PXP2_REG_RQ_VQ12_ENTRY_CNT                              0x120828
+/* [R 8] Number of entries occupied by vq 13 in pswrq memory */
+#define PXP2_REG_RQ_VQ13_ENTRY_CNT                              0x120830
+/* [R 8] Number of entries occupied by vq 14 in pswrq memory */
+#define PXP2_REG_RQ_VQ14_ENTRY_CNT                              0x120838
+/* [R 8] Number of entries occupied by vq 15 in pswrq memory */
+#define PXP2_REG_RQ_VQ15_ENTRY_CNT                              0x120840
+/* [R 8] Number of entries occupied by vq 16 in pswrq memory */
+#define PXP2_REG_RQ_VQ16_ENTRY_CNT                              0x120848
+/* [R 8] Number of entries occupied by vq 17 in pswrq memory */
+#define PXP2_REG_RQ_VQ17_ENTRY_CNT                              0x120850
+/* [R 8] Number of entries occupied by vq 18 in pswrq memory */
+#define PXP2_REG_RQ_VQ18_ENTRY_CNT                              0x120858
+/* [R 8] Number of entries occupied by vq 19 in pswrq memory */
+#define PXP2_REG_RQ_VQ19_ENTRY_CNT                              0x120860
+/* [R 8] Number of entries occupied by vq 1 in pswrq memory */
+#define PXP2_REG_RQ_VQ1_ENTRY_CNT                               0x120868
+/* [R 8] Number of entries occupied by vq 20 in pswrq memory */
+#define PXP2_REG_RQ_VQ20_ENTRY_CNT                              0x120870
+/* [R 8] Number of entries occupied by vq 21 in pswrq memory */
+#define PXP2_REG_RQ_VQ21_ENTRY_CNT                              0x120878
+/* [R 8] Number of entries occupied by vq 22 in pswrq memory */
+#define PXP2_REG_RQ_VQ22_ENTRY_CNT                              0x120880
+/* [R 8] Number of entries occupied by vq 23 in pswrq memory */
+#define PXP2_REG_RQ_VQ23_ENTRY_CNT                              0x120888
+/* [R 8] Number of entries occupied by vq 24 in pswrq memory */
+#define PXP2_REG_RQ_VQ24_ENTRY_CNT                              0x120890
+/* [R 8] Number of entries occupied by vq 25 in pswrq memory */
+#define PXP2_REG_RQ_VQ25_ENTRY_CNT                              0x120898
+/* [R 8] Number of entries occupied by vq 26 in pswrq memory */
+#define PXP2_REG_RQ_VQ26_ENTRY_CNT                              0x1208a0
+/* [R 8] Number of entries occupied by vq 27 in pswrq memory */
+#define PXP2_REG_RQ_VQ27_ENTRY_CNT                              0x1208a8
+/* [R 8] Number of entries occupied by vq 28 in pswrq memory */
+#define PXP2_REG_RQ_VQ28_ENTRY_CNT                              0x1208b0
+/* [R 8] Number of entries occupied by vq 29 in pswrq memory */
+#define PXP2_REG_RQ_VQ29_ENTRY_CNT                              0x1208b8
+/* [R 8] Number of entries occupied by vq 2 in pswrq memory */
+#define PXP2_REG_RQ_VQ2_ENTRY_CNT                               0x1208c0
+/* [R 8] Number of entries occupied by vq 30 in pswrq memory */
+#define PXP2_REG_RQ_VQ30_ENTRY_CNT                              0x1208c8
+/* [R 8] Number of entries occupied by vq 31 in pswrq memory */
+#define PXP2_REG_RQ_VQ31_ENTRY_CNT                              0x1208d0
+/* [R 8] Number of entries occupied by vq 3 in pswrq memory */
+#define PXP2_REG_RQ_VQ3_ENTRY_CNT                               0x1208d8
+/* [R 8] Number of entries occupied by vq 4 in pswrq memory */
+#define PXP2_REG_RQ_VQ4_ENTRY_CNT                               0x1208e0
+/* [R 8] Number of entries occupied by vq 5 in pswrq memory */
+#define PXP2_REG_RQ_VQ5_ENTRY_CNT                               0x1208e8
+/* [R 8] Number of entries occupied by vq 6 in pswrq memory */
+#define PXP2_REG_RQ_VQ6_ENTRY_CNT                               0x1208f0
+/* [R 8] Number of entries occupied by vq 7 in pswrq memory */
+#define PXP2_REG_RQ_VQ7_ENTRY_CNT                               0x1208f8
+/* [R 8] Number of entries occupied by vq 8 in pswrq memory */
+#define PXP2_REG_RQ_VQ8_ENTRY_CNT                               0x120900
+/* [R 8] Number of entries occupied by vq 9 in pswrq memory */
+#define PXP2_REG_RQ_VQ9_ENTRY_CNT                               0x120908
+/* [RW 3] Max burst size filed for write requests port 0; 000 - 128B;
+   001:256B; 010: 512B; */
+#define PXP2_REG_RQ_WR_MBS0                                     0x12015c
+/* [RW 10] if Number of entries in dmae fifo will be higer than this
+   threshold then has_payload indication will be asserted; the default value
+   should be equal to &gt;  write MBS size! */
+#define PXP2_REG_WR_DMAE_TH                                     0x120368
+/* [R 1] debug only: Indication if PSWHST arbiter is idle */
+#define PXP_REG_HST_ARB_IS_IDLE                                 0x103004
+/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means
+   this client is waiting for the arbiter. */
+#define PXP_REG_HST_CLIENTS_WAITING_TO_ARB                      0x103008
+/* [WB 160] Used for initialization of the inbound interrupts memory */
+#define PXP_REG_HST_INBOUND_INT                                 0x103800
+/* [RW 32] Interrupt mask register #0 read/write */
+#define PXP_REG_PXP_INT_MASK_0                                  0x103074
+#define PXP_REG_PXP_INT_MASK_1                                  0x103084
+/* [R 32] Interrupt register #0 read */
+#define PXP_REG_PXP_INT_STS_0                                   0x103068
+#define PXP_REG_PXP_INT_STS_1                                   0x103078
+/* [RC 32] Interrupt register #0 read clear */
+#define PXP_REG_PXP_INT_STS_CLR_0                               0x10306c
+/* [RW 26] Parity mask register #0 read/write */
+#define PXP_REG_PXP_PRTY_MASK                                   0x103094
+/* [RW 4] The activity counter initial increment value sent in the load
+   request */
+#define QM_REG_ACTCTRINITVAL_0                                  0x168040
+#define QM_REG_ACTCTRINITVAL_1                                  0x168044
+#define QM_REG_ACTCTRINITVAL_2                                  0x168048
+#define QM_REG_ACTCTRINITVAL_3                                  0x16804c
+/* [RW 32] The base logical address (in bytes) of each physical queue. The
+   index I represents the physical queue number. The 12 lsbs are ignore and
+   considered zero so practically there are only 20 bits in this register. */
+#define QM_REG_BASEADDR                                         0x168900
+/* [RW 16] The byte credit cost for each task. This value is for both ports */
+#define QM_REG_BYTECRDCOST                                      0x168234
+/* [RW 16] The initial byte credit value for both ports. */
+#define QM_REG_BYTECRDINITVAL                                   0x168238
+/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
+   queue uses port 0 else it uses port 1. */
+#define QM_REG_BYTECRDPORT_LSB                                  0x168228
+/* [RW 32] A bit per physical queue. If the bit is cleared then the physical
+   queue uses port 0 else it uses port 1. */
+#define QM_REG_BYTECRDPORT_MSB                                  0x168224
+/* [RW 16] The byte credit value that if above the QM is considered almost
+   full */
+#define QM_REG_BYTECREDITAFULLTHR                               0x168094
+/* [RW 4] The initial credit for interface */
+#define QM_REG_CMINITCRD_0                                      0x1680cc
+#define QM_REG_CMINITCRD_1                                      0x1680d0
+#define QM_REG_CMINITCRD_2                                      0x1680d4
+#define QM_REG_CMINITCRD_3                                      0x1680d8
+#define QM_REG_CMINITCRD_4                                      0x1680dc
+#define QM_REG_CMINITCRD_5                                      0x1680e0
+#define QM_REG_CMINITCRD_6                                      0x1680e4
+#define QM_REG_CMINITCRD_7                                      0x1680e8
+/* [RW 8] A mask bit per CM interface. If this bit is 0 then this interface
+   is masked */
+#define QM_REG_CMINTEN                                          0x1680ec
+/* [RW 12] A bit vector which indicates which one of the queues are tied to
+   interface 0 */
+#define QM_REG_CMINTVOQMASK_0                                   0x1681f4
+#define QM_REG_CMINTVOQMASK_1                                   0x1681f8
+#define QM_REG_CMINTVOQMASK_2                                   0x1681fc
+#define QM_REG_CMINTVOQMASK_3                                   0x168200
+#define QM_REG_CMINTVOQMASK_4                                   0x168204
+#define QM_REG_CMINTVOQMASK_5                                   0x168208
+#define QM_REG_CMINTVOQMASK_6                                   0x16820c
+#define QM_REG_CMINTVOQMASK_7                                   0x168210
+/* [RW 20] The number of connections divided by 16 which dictates the size
+   of each queue per port 0 */
+#define QM_REG_CONNNUM_0                                        0x168020
+/* [R 6] Keep the fill level of the fifo from write client 4 */
+#define QM_REG_CQM_WRC_FIFOLVL                                  0x168018
+/* [RW 8] The context regions sent in the CFC load request */
+#define QM_REG_CTXREG_0                                         0x168030
+#define QM_REG_CTXREG_1                                         0x168034
+#define QM_REG_CTXREG_2                                         0x168038
+#define QM_REG_CTXREG_3                                         0x16803c
+/* [RW 12] The VOQ mask used to select the VOQs which needs to be full for
+   bypass enable */
+#define QM_REG_ENBYPVOQMASK                                     0x16823c
+/* [RW 32] A bit mask per each physical queue. If a bit is set then the
+   physical queue uses the byte credit */
+#define QM_REG_ENBYTECRD_LSB                                    0x168220
+/* [RW 32] A bit mask per each physical queue. If a bit is set then the
+   physical queue uses the byte credit */
+#define QM_REG_ENBYTECRD_MSB                                    0x16821c
+/* [RW 4] If cleared then the secondary interface will not be served by the
+   RR arbiter */
+#define QM_REG_ENSEC                                            0x1680f0
+/* [RW 32] A bit vector per each physical queue which selects which function
+   number to use on PCI access for that queue. */
+#define QM_REG_FUNCNUMSEL_LSB                                   0x168230
+/* [RW 32] A bit vector per each physical queue which selects which function
+   number to use on PCI access for that queue. */
+#define QM_REG_FUNCNUMSEL_MSB                                   0x16822c
+/* [RW 32] A mask register to mask the Almost empty signals which will not
+   be use for the almost empty indication to the HW block */
+#define QM_REG_HWAEMPTYMASK_LSB                                 0x168218
+/* [RW 32] A mask register to mask the Almost empty signals which will not
+   be use for the almost empty indication to the HW block */
+#define QM_REG_HWAEMPTYMASK_MSB                                 0x168214
+/* [RW 4] The number of outstanding request to CFC */
+#define QM_REG_OUTLDREQ                                         0x168804
+/* [RC 1] A flag to indicate that overflow error occurred in one of the
+   queues. */
+#define QM_REG_OVFERROR                                         0x16805c
+/* [RC 6] the Q were the qverflow occurs */
+#define QM_REG_OVFQNUM                                          0x168058
+/* [R 32] Pause state for physical queues 31-0 */
+#define QM_REG_PAUSESTATE0                                      0x168410
+/* [R 32] Pause state for physical queues 64-32 */
+#define QM_REG_PAUSESTATE1                                      0x168414
+/* [RW 2] The PCI attributes field used in the PCI request. */
+#define QM_REG_PCIREQAT                                         0x168054
+/* [R 16] The byte credit of port 0 */
+#define QM_REG_PORT0BYTECRD                                     0x168300
+/* [R 16] The byte credit of port 1 */
+#define QM_REG_PORT1BYTECRD                                     0x168304
+/* [WB 54] Pointer Table Memory; The mapping is as follow: ptrtbl[53:30]
+   read pointer; ptrtbl[29:6] write pointer; ptrtbl[5:4] read bank0;
+   ptrtbl[3:2] read bank 1; ptrtbl[1:0] write bank; */
+#define QM_REG_PTRTBL                                           0x168a00
+/* [RW 2] Interrupt mask register #0 read/write */
+#define QM_REG_QM_INT_MASK                                      0x168444
+/* [R 2] Interrupt register #0 read */
+#define QM_REG_QM_INT_STS                                       0x168438
+/* [RW 9] Parity mask register #0 read/write */
+#define QM_REG_QM_PRTY_MASK                                     0x168454
+/* [R 32] Current queues in pipeline: Queues from 32 to 63 */
+#define QM_REG_QSTATUS_HIGH                                     0x16802c
+/* [R 32] Current queues in pipeline: Queues from 0 to 31 */
+#define QM_REG_QSTATUS_LOW                                      0x168028
+/* [R 24] The number of tasks queued for each queue */
+#define QM_REG_QTASKCTR_0                                       0x168308
+/* [RW 4] Queue tied to VOQ */
+#define QM_REG_QVOQIDX_0                                        0x1680f4
+#define QM_REG_QVOQIDX_10                                       0x16811c
+#define QM_REG_QVOQIDX_11                                       0x168120
+#define QM_REG_QVOQIDX_12                                       0x168124
+#define QM_REG_QVOQIDX_13                                       0x168128
+#define QM_REG_QVOQIDX_14                                       0x16812c
+#define QM_REG_QVOQIDX_15                                       0x168130
+#define QM_REG_QVOQIDX_16                                       0x168134
+#define QM_REG_QVOQIDX_17                                       0x168138
+#define QM_REG_QVOQIDX_21                                       0x168148
+#define QM_REG_QVOQIDX_25                                       0x168158
+#define QM_REG_QVOQIDX_29                                       0x168168
+#define QM_REG_QVOQIDX_32                                       0x168174
+#define QM_REG_QVOQIDX_33                                       0x168178
+#define QM_REG_QVOQIDX_34                                       0x16817c
+#define QM_REG_QVOQIDX_35                                       0x168180
+#define QM_REG_QVOQIDX_36                                       0x168184
+#define QM_REG_QVOQIDX_37                                       0x168188
+#define QM_REG_QVOQIDX_38                                       0x16818c
+#define QM_REG_QVOQIDX_39                                       0x168190
+#define QM_REG_QVOQIDX_40                                       0x168194
+#define QM_REG_QVOQIDX_41                                       0x168198
+#define QM_REG_QVOQIDX_42                                       0x16819c
+#define QM_REG_QVOQIDX_43                                       0x1681a0
+#define QM_REG_QVOQIDX_44                                       0x1681a4
+#define QM_REG_QVOQIDX_45                                       0x1681a8
+#define QM_REG_QVOQIDX_46                                       0x1681ac
+#define QM_REG_QVOQIDX_47                                       0x1681b0
+#define QM_REG_QVOQIDX_48                                       0x1681b4
+#define QM_REG_QVOQIDX_49                                       0x1681b8
+#define QM_REG_QVOQIDX_5                                        0x168108
+#define QM_REG_QVOQIDX_50                                       0x1681bc
+#define QM_REG_QVOQIDX_51                                       0x1681c0
+#define QM_REG_QVOQIDX_52                                       0x1681c4
+#define QM_REG_QVOQIDX_53                                       0x1681c8
+#define QM_REG_QVOQIDX_54                                       0x1681cc
+#define QM_REG_QVOQIDX_55                                       0x1681d0
+#define QM_REG_QVOQIDX_56                                       0x1681d4
+#define QM_REG_QVOQIDX_57                                       0x1681d8
+#define QM_REG_QVOQIDX_58                                       0x1681dc
+#define QM_REG_QVOQIDX_59                                       0x1681e0
+#define QM_REG_QVOQIDX_50                                       0x1681bc
+#define QM_REG_QVOQIDX_51                                       0x1681c0
+#define QM_REG_QVOQIDX_52                                       0x1681c4
+#define QM_REG_QVOQIDX_53                                       0x1681c8
+#define QM_REG_QVOQIDX_54                                       0x1681cc
+#define QM_REG_QVOQIDX_55                                       0x1681d0
+#define QM_REG_QVOQIDX_56                                       0x1681d4
+#define QM_REG_QVOQIDX_57                                       0x1681d8
+#define QM_REG_QVOQIDX_58                                       0x1681dc
+#define QM_REG_QVOQIDX_59                                       0x1681e0
+#define QM_REG_QVOQIDX_6                                        0x16810c
+#define QM_REG_QVOQIDX_60                                       0x1681e4
+#define QM_REG_QVOQIDX_61                                       0x1681e8
+#define QM_REG_QVOQIDX_62                                       0x1681ec
+#define QM_REG_QVOQIDX_63                                       0x1681f0
+#define QM_REG_QVOQIDX_60                                       0x1681e4
+#define QM_REG_QVOQIDX_61                                       0x1681e8
+#define QM_REG_QVOQIDX_62                                       0x1681ec
+#define QM_REG_QVOQIDX_63                                       0x1681f0
+#define QM_REG_QVOQIDX_7                                        0x168110
+#define QM_REG_QVOQIDX_8                                        0x168114
+#define QM_REG_QVOQIDX_9                                        0x168118
+/* [R 24] Remaining pause timeout for port 0 */
+#define QM_REG_REMAINPAUSETM0                                   0x168418
+/* [R 24] Remaining pause timeout for port 1 */
+#define QM_REG_REMAINPAUSETM1                                   0x16841c
+/* [RW 1] Initialization bit command */
+#define QM_REG_SOFT_RESET                                       0x168428
+/* [RW 8] The credit cost per every task in the QM. A value per each VOQ */
+#define QM_REG_TASKCRDCOST_0                                    0x16809c
+#define QM_REG_TASKCRDCOST_1                                    0x1680a0
+#define QM_REG_TASKCRDCOST_10                                   0x1680c4
+#define QM_REG_TASKCRDCOST_11                                   0x1680c8
+#define QM_REG_TASKCRDCOST_2                                    0x1680a4
+#define QM_REG_TASKCRDCOST_4                                    0x1680ac
+#define QM_REG_TASKCRDCOST_5                                    0x1680b0
+/* [R 6] Keep the fill level of the fifo from write client 3 */
+#define QM_REG_TQM_WRC_FIFOLVL                                  0x168010
+/* [R 6] Keep the fill level of the fifo from write client 2 */
+#define QM_REG_UQM_WRC_FIFOLVL                                  0x168008
+/* [RC 32] Credit update error register */
+#define QM_REG_VOQCRDERRREG                                     0x168408
+/* [R 16] The credit value for each VOQ */
+#define QM_REG_VOQCREDIT_0                                      0x1682d0
+#define QM_REG_VOQCREDIT_1                                      0x1682d4
+#define QM_REG_VOQCREDIT_10                                     0x1682f8
+#define QM_REG_VOQCREDIT_11                                     0x1682fc
+#define QM_REG_VOQCREDIT_4                                      0x1682e0
+/* [RW 16] The credit value that if above the QM is considered almost full */
+#define QM_REG_VOQCREDITAFULLTHR                                0x168090
+/* [RW 16] The init and maximum credit for each VoQ */
+#define QM_REG_VOQINITCREDIT_0                                  0x168060
+#define QM_REG_VOQINITCREDIT_1                                  0x168064
+#define QM_REG_VOQINITCREDIT_10                                 0x168088
+#define QM_REG_VOQINITCREDIT_11                                 0x16808c
+#define QM_REG_VOQINITCREDIT_2                                  0x168068
+#define QM_REG_VOQINITCREDIT_4                                  0x168070
+#define QM_REG_VOQINITCREDIT_5                                  0x168074
+/* [RW 1] The port of which VOQ belongs */
+#define QM_REG_VOQPORT_1                                        0x1682a4
+#define QM_REG_VOQPORT_10                                       0x1682c8
+#define QM_REG_VOQPORT_11                                       0x1682cc
+#define QM_REG_VOQPORT_2                                        0x1682a8
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_0_LSB                                   0x168240
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_0_MSB                                   0x168244
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_1_MSB                                   0x16824c
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_2_LSB                                   0x168250
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_2_MSB                                   0x168254
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_3_LSB                                   0x168258
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_4_LSB                                   0x168260
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_4_MSB                                   0x168264
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_5_LSB                                   0x168268
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_5_MSB                                   0x16826c
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_6_LSB                                   0x168270
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_6_MSB                                   0x168274
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_7_LSB                                   0x168278
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_7_MSB                                   0x16827c
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_8_LSB                                   0x168280
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_8_MSB                                   0x168284
+/* [RW 32] The physical queue number associated with each VOQ */
+#define QM_REG_VOQQMASK_9_LSB                                   0x168288
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_0                                     0x16880c
+#define QM_REG_WRRWEIGHTS_1                                     0x168810
+#define QM_REG_WRRWEIGHTS_10                                    0x168814
+#define QM_REG_WRRWEIGHTS_10_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_11                                    0x168818
+#define QM_REG_WRRWEIGHTS_11_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_12                                    0x16881c
+#define QM_REG_WRRWEIGHTS_12_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_13                                    0x168820
+#define QM_REG_WRRWEIGHTS_13_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_14                                    0x168824
+#define QM_REG_WRRWEIGHTS_14_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_15                                    0x168828
+#define QM_REG_WRRWEIGHTS_15_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_10                                    0x168814
+#define QM_REG_WRRWEIGHTS_11                                    0x168818
+#define QM_REG_WRRWEIGHTS_12                                    0x16881c
+#define QM_REG_WRRWEIGHTS_13                                    0x168820
+#define QM_REG_WRRWEIGHTS_14                                    0x168824
+#define QM_REG_WRRWEIGHTS_15                                    0x168828
+#define QM_REG_WRRWEIGHTS_2                                     0x16882c
+#define QM_REG_WRRWEIGHTS_3                                     0x168830
+#define QM_REG_WRRWEIGHTS_4                                     0x168834
+#define QM_REG_WRRWEIGHTS_5                                     0x168838
+#define QM_REG_WRRWEIGHTS_6                                     0x16883c
+#define QM_REG_WRRWEIGHTS_7                                     0x168840
+#define QM_REG_WRRWEIGHTS_8                                     0x168844
+#define QM_REG_WRRWEIGHTS_9                                     0x168848
+/* [R 6] Keep the fill level of the fifo from write client 1 */
+#define QM_REG_XQM_WRC_FIFOLVL                                  0x168000
+#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR                     (0x1<<0)
+#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR_SIZE                0
+#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR                 (0x1<<0)
+#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE            0
+#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR                  (0x1<<0)
+#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR_SIZE             0
+#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR                    (0x1<<0)
+#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR_SIZE               0
+#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR                     (0x1<<0)
+#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR_SIZE                0
+#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR                 (0x1<<0)
+#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE            0
+#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR                  (0x1<<0)
+#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE             0
+#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR                    (0x1<<0)
+#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR_SIZE               0
+#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR                       (0x1<<0)
+#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR_SIZE                  0
+#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR                   (0x1<<0)
+#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE              0
+#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR                    (0x1<<0)
+#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE               0
+#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR                      (0x1<<0)
+#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR_SIZE                 0
+#define CFC_DEBUG1_REG_WRITE_AC                                 (0x1<<4)
+#define CFC_DEBUG1_REG_WRITE_AC_SIZE                            4
+/* [R 1] debug only: This bit indicates wheter indicates that external
+   buffer was wrapped (oldest data was thrown); Relevant only when
+   ~dbg_registers_debug_target=2 (PCI) & ~dbg_registers_full_mode=1 (wrap); */
+#define DBG_REG_WRAP_ON_EXT_BUFFER                              0xc124
+#define DBG_REG_WRAP_ON_EXT_BUFFER_SIZE                         1
+/* [R 1] debug only: This bit indicates wheter the internal buffer was
+   wrapped (oldest data was thrown) Relevant only when
+   ~dbg_registers_debug_target=0 (internal buffer) */
+#define DBG_REG_WRAP_ON_INT_BUFFER                              0xc128
+#define DBG_REG_WRAP_ON_INT_BUFFER_SIZE                         1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_0                                     0x16880c
+#define QM_REG_WRRWEIGHTS_0_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_1                                     0x168810
+#define QM_REG_WRRWEIGHTS_1_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_10                                    0x168814
+#define QM_REG_WRRWEIGHTS_10_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_11                                    0x168818
+#define QM_REG_WRRWEIGHTS_11_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_12                                    0x16881c
+#define QM_REG_WRRWEIGHTS_12_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_13                                    0x168820
+#define QM_REG_WRRWEIGHTS_13_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_14                                    0x168824
+#define QM_REG_WRRWEIGHTS_14_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_15                                    0x168828
+#define QM_REG_WRRWEIGHTS_15_SIZE                               1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_2                                     0x16882c
+#define QM_REG_WRRWEIGHTS_2_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_3                                     0x168830
+#define QM_REG_WRRWEIGHTS_3_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_4                                     0x168834
+#define QM_REG_WRRWEIGHTS_4_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_5                                     0x168838
+#define QM_REG_WRRWEIGHTS_5_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_6                                     0x16883c
+#define QM_REG_WRRWEIGHTS_6_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_7                                     0x168840
+#define QM_REG_WRRWEIGHTS_7_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_8                                     0x168844
+#define QM_REG_WRRWEIGHTS_8_SIZE                                1
+/* [RW 32] Wrr weights */
+#define QM_REG_WRRWEIGHTS_9                                     0x168848
+#define QM_REG_WRRWEIGHTS_9_SIZE                                1
+/* [RW 22] Number of free element in the free list of T2 entries - port 0. */
+#define SRC_REG_COUNTFREE0                                      0x40500
+/* [WB 64] First free element in the free list of T2 entries - port 0. */
+#define SRC_REG_FIRSTFREE0                                      0x40510
+#define SRC_REG_KEYRSS0_0                                       0x40408
+#define SRC_REG_KEYRSS1_9                                       0x40454
+/* [WB 64] Last free element in the free list of T2 entries - port 0. */
+#define SRC_REG_LASTFREE0                                       0x40530
+/* [RW 5] The number of hash bits used for the search (h); Values can be 8
+   to 24. */
+#define SRC_REG_NUMBER_HASH_BITS0                               0x40400
+/* [RW 1] Reset internal state machines. */
+#define SRC_REG_SOFT_RST                                        0x4049c
+/* [R 1] Interrupt register #0 read */
+#define SRC_REG_SRC_INT_STS                                     0x404ac
+/* [RW 3] Parity mask register #0 read/write */
+#define SRC_REG_SRC_PRTY_MASK                                   0x404c8
+/* [R 4] Used to read the value of the XX protection CAM occupancy counter. */
+#define TCM_REG_CAM_OCCUP                                       0x5017c
+/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define TCM_REG_CDU_AG_RD_IFEN                                  0x50034
+/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input
+   are disregarded; all other signals are treated as usual; if 1 - normal
+   activity. */
+#define TCM_REG_CDU_AG_WR_IFEN                                  0x50030
+/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define TCM_REG_CDU_SM_RD_IFEN                                  0x5003c
+/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid
+   input is disregarded; all other signals are treated as usual; if 1 -
+   normal activity. */
+#define TCM_REG_CDU_SM_WR_IFEN                                  0x50038
+/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 1 at start-up. */
+#define TCM_REG_CFC_INIT_CRD                                    0x50204
+/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_CP_WEIGHT                                       0x500c0
+/* [RW 1] Input csem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define TCM_REG_CSEM_IFEN                                       0x5002c
+/* [RC 1] Message length mismatch (relative to last indication) at the In#9
+   interface. */
+#define TCM_REG_CSEM_LENGTH_MIS                                 0x50174
+/* [RW 8] The Event ID in case of ErrorFlg is set in the input message. */
+#define TCM_REG_ERR_EVNT_ID                                     0x500a0
+/* [RW 28] The CM erroneous header for QM and Timers formatting. */
+#define TCM_REG_ERR_TCM_HDR                                     0x5009c
+/* [RW 8] The Event ID for Timers expiration. */
+#define TCM_REG_EXPR_EVNT_ID                                    0x500a4
+/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define TCM_REG_FIC0_INIT_CRD                                   0x5020c
+/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define TCM_REG_FIC1_INIT_CRD                                   0x50210
+/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1
+   - strict priority defined by ~tcm_registers_gr_ag_pr.gr_ag_pr;
+   ~tcm_registers_gr_ld0_pr.gr_ld0_pr and
+   ~tcm_registers_gr_ld1_pr.gr_ld1_pr. */
+#define TCM_REG_GR_ARB_TYPE                                     0x50114
+/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Store channel is the
+   compliment of the other 3 groups. */
+#define TCM_REG_GR_LD0_PR                                       0x5011c
+/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Store channel is the
+   compliment of the other 3 groups. */
+#define TCM_REG_GR_LD1_PR                                       0x50120
+/* [RW 4] The number of double REG-pairs; loaded from the STORM context and
+   sent to STORM; for a specific connection type. The double REG-pairs are
+   used to align to STORM context row size of 128 bits. The offset of these
+   data in the STORM context is always 0. Index _i stands for the connection
+   type (one of 16). */
+#define TCM_REG_N_SM_CTX_LD_0                                   0x50050
+#define TCM_REG_N_SM_CTX_LD_1                                   0x50054
+#define TCM_REG_N_SM_CTX_LD_10                                  0x50078
+#define TCM_REG_N_SM_CTX_LD_11                                  0x5007c
+#define TCM_REG_N_SM_CTX_LD_12                                  0x50080
+#define TCM_REG_N_SM_CTX_LD_13                                  0x50084
+#define TCM_REG_N_SM_CTX_LD_14                                  0x50088
+#define TCM_REG_N_SM_CTX_LD_15                                  0x5008c
+#define TCM_REG_N_SM_CTX_LD_2                                   0x50058
+#define TCM_REG_N_SM_CTX_LD_3                                   0x5005c
+#define TCM_REG_N_SM_CTX_LD_4                                   0x50060
+/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_PBF_IFEN                                        0x50024
+/* [RC 1] Message length mismatch (relative to last indication) at the In#7
+   interface. */
+#define TCM_REG_PBF_LENGTH_MIS                                  0x5016c
+/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_PBF_WEIGHT                                      0x500b4
+/* [RW 6] The physical queue number 0 per port index. */
+#define TCM_REG_PHYS_QNUM0_0                                    0x500e0
+#define TCM_REG_PHYS_QNUM0_1                                    0x500e4
+/* [RW 6] The physical queue number 1 per port index. */
+#define TCM_REG_PHYS_QNUM1_0                                    0x500e8
+/* [RW 1] Input prs Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_PRS_IFEN                                        0x50020
+/* [RC 1] Message length mismatch (relative to last indication) at the In#6
+   interface. */
+#define TCM_REG_PRS_LENGTH_MIS                                  0x50168
+/* [RW 3] The weight of the input prs in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_PRS_WEIGHT                                      0x500b0
+/* [RW 8] The Event ID for Timers formatting in case of stop done. */
+#define TCM_REG_STOP_EVNT_ID                                    0x500a8
+/* [RC 1] Message length mismatch (relative to last indication) at the STORM
+   interface. */
+#define TCM_REG_STORM_LENGTH_MIS                                0x50160
+/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define TCM_REG_STORM_TCM_IFEN                                  0x50010
+/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TCM_CFC_IFEN                                    0x50040
+/* [RW 11] Interrupt mask register #0 read/write */
+#define TCM_REG_TCM_INT_MASK                                    0x501dc
+/* [R 11] Interrupt register #0 read */
+#define TCM_REG_TCM_INT_STS                                     0x501d0
+/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS
+   REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
+   Is used to determine the number of the AG context REG-pairs written back;
+   when the input message Reg1WbFlg isn't set. */
+#define TCM_REG_TCM_REG0_SZ                                     0x500d8
+/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TCM_STORM0_IFEN                                 0x50004
+/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TCM_STORM1_IFEN                                 0x50008
+/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TCM_TQM_IFEN                                    0x5000c
+/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */
+#define TCM_REG_TCM_TQM_USE_Q                                   0x500d4
+/* [RW 28] The CM header for Timers expiration command. */
+#define TCM_REG_TM_TCM_HDR                                      0x50098
+/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define TCM_REG_TM_TCM_IFEN                                     0x5001c
+/* [RW 6] QM output initial credit. Max credit available - 32.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 32 at start-up. */
+#define TCM_REG_TQM_INIT_CRD                                    0x5021c
+/* [RW 28] The CM header value for QM request (primary). */
+#define TCM_REG_TQM_TCM_HDR_P                                   0x50090
+/* [RW 28] The CM header value for QM request (secondary). */
+#define TCM_REG_TQM_TCM_HDR_S                                   0x50094
+/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TQM_TCM_IFEN                                    0x50014
+/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define TCM_REG_TSDM_IFEN                                       0x50018
+/* [RC 1] Message length mismatch (relative to last indication) at the SDM
+   interface. */
+#define TCM_REG_TSDM_LENGTH_MIS                                 0x50164
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define TCM_REG_TSDM_WEIGHT                                     0x500c4
+/* [RW 1] Input usem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define TCM_REG_USEM_IFEN                                       0x50028
+/* [RC 1] Message length mismatch (relative to last indication) at the In#8
+   interface. */
+#define TCM_REG_USEM_LENGTH_MIS                                 0x50170
+/* [RW 21] Indirect access to the descriptor table of the XX protection
+   mechanism. The fields are: [5:0] - length of the message; 15:6] - message
+   pointer; 20:16] - next pointer. */
+#define TCM_REG_XX_DESCR_TABLE                                  0x50280
+/* [R 6] Use to read the value of XX protection Free counter. */
+#define TCM_REG_XX_FREE                                         0x50178
+/* [RW 6] Initial value for the credit counter; responsible for fulfilling
+   of the Input Stage XX protection buffer by the XX protection pending
+   messages. Max credit available - 127.Write writes the initial credit
+   value; read returns the current value of the credit counter. Must be
+   initialized to 19 at start-up. */
+#define TCM_REG_XX_INIT_CRD                                     0x50220
+/* [RW 6] Maximum link list size (messages locked) per connection in the XX
+   protection. */
+#define TCM_REG_XX_MAX_LL_SZ                                    0x50044
+/* [RW 6] The maximum number of pending messages; which may be stored in XX
+   protection. ~tcm_registers_xx_free.xx_free is read on read. */
+#define TCM_REG_XX_MSG_NUM                                      0x50224
+/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */
+#define TCM_REG_XX_OVFL_EVNT_ID                                 0x50048
+/* [RW 16] Indirect access to the XX table of the XX protection mechanism.
+   The fields are:[4:0] - tail pointer; [10:5] - Link List size; 15:11] -
+   header pointer. */
+#define TCM_REG_XX_TABLE                                        0x50240
+/* [RW 4] Load value for for cfc ac credit cnt. */
+#define TM_REG_CFC_AC_CRDCNT_VAL                                0x164208
+/* [RW 4] Load value for cfc cld credit cnt. */
+#define TM_REG_CFC_CLD_CRDCNT_VAL                               0x164210
+/* [RW 8] Client0 context region. */
+#define TM_REG_CL0_CONT_REGION                                  0x164030
+/* [RW 8] Client1 context region. */
+#define TM_REG_CL1_CONT_REGION                                  0x164034
+/* [RW 8] Client2 context region. */
+#define TM_REG_CL2_CONT_REGION                                  0x164038
+/* [RW 2] Client in High priority client number. */
+#define TM_REG_CLIN_PRIOR0_CLIENT                               0x164024
+/* [RW 4] Load value for clout0 cred cnt. */
+#define TM_REG_CLOUT_CRDCNT0_VAL                                0x164220
+/* [RW 4] Load value for clout1 cred cnt. */
+#define TM_REG_CLOUT_CRDCNT1_VAL                                0x164228
+/* [RW 4] Load value for clout2 cred cnt. */
+#define TM_REG_CLOUT_CRDCNT2_VAL                                0x164230
+/* [RW 1] Enable client0 input. */
+#define TM_REG_EN_CL0_INPUT                                     0x164008
+/* [RW 1] Enable client1 input. */
+#define TM_REG_EN_CL1_INPUT                                     0x16400c
+/* [RW 1] Enable client2 input. */
+#define TM_REG_EN_CL2_INPUT                                     0x164010
+/* [RW 1] Enable real time counter. */
+#define TM_REG_EN_REAL_TIME_CNT                                 0x1640d8
+/* [RW 1] Enable for Timers state machines. */
+#define TM_REG_EN_TIMERS                                        0x164000
+/* [RW 4] Load value for expiration credit cnt. CFC max number of
+   outstanding load requests for timers (expiration) context loading. */
+#define TM_REG_EXP_CRDCNT_VAL                                   0x164238
+/* [RW 18] Linear0 Max active cid. */
+#define TM_REG_LIN0_MAX_ACTIVE_CID                              0x164048
+/* [WB 64] Linear0 phy address. */
+#define TM_REG_LIN0_PHY_ADDR                                    0x164270
+/* [RW 24] Linear0 array scan timeout. */
+#define TM_REG_LIN0_SCAN_TIME                                   0x16403c
+/* [WB 64] Linear1 phy address. */
+#define TM_REG_LIN1_PHY_ADDR                                    0x164280
+/* [RW 6] Linear timer set_clear fifo threshold. */
+#define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR                       0x164070
+/* [RW 2] Load value for pci arbiter credit cnt. */
+#define TM_REG_PCIARB_CRDCNT_VAL                                0x164260
+/* [RW 1] Timer software reset - active high. */
+#define TM_REG_TIMER_SOFT_RST                                   0x164004
+/* [RW 20] The amount of hardware cycles for each timer tick. */
+#define TM_REG_TIMER_TICK_SIZE                                  0x16401c
+/* [RW 8] Timers Context region. */
+#define TM_REG_TM_CONTEXT_REGION                                0x164044
+/* [RW 1] Interrupt mask register #0 read/write */
+#define TM_REG_TM_INT_MASK                                      0x1640fc
+/* [R 1] Interrupt register #0 read */
+#define TM_REG_TM_INT_STS                                       0x1640f0
+/* [RW 8] The event id for aggregated interrupt 0 */
+#define TSDM_REG_AGG_INT_EVENT_0                                0x42038
+/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
+#define TSDM_REG_CFC_RSP_START_ADDR                             0x42008
+/* [RW 16] The maximum value of the competion counter #0 */
+#define TSDM_REG_CMP_COUNTER_MAX0                               0x4201c
+/* [RW 16] The maximum value of the competion counter #1 */
+#define TSDM_REG_CMP_COUNTER_MAX1                               0x42020
+/* [RW 16] The maximum value of the competion counter #2 */
+#define TSDM_REG_CMP_COUNTER_MAX2                               0x42024
+/* [RW 16] The maximum value of the competion counter #3 */
+#define TSDM_REG_CMP_COUNTER_MAX3                               0x42028
+/* [RW 13] The start address in the internal RAM for the completion
+   counters. */
+#define TSDM_REG_CMP_COUNTER_START_ADDR                         0x4200c
+#define TSDM_REG_ENABLE_IN1                                     0x42238
+#define TSDM_REG_ENABLE_IN2                                     0x4223c
+#define TSDM_REG_ENABLE_OUT1                                    0x42240
+#define TSDM_REG_ENABLE_OUT2                                    0x42244
+/* [RW 4] The initial number of messages that can be sent to the pxp control
+   interface without receiving any ACK. */
+#define TSDM_REG_INIT_CREDIT_PXP_CTRL                           0x424bc
+/* [ST 32] The number of ACK after placement messages received */
+#define TSDM_REG_NUM_OF_ACK_AFTER_PLACE                         0x4227c
+/* [ST 32] The number of packet end messages received from the parser */
+#define TSDM_REG_NUM_OF_PKT_END_MSG                             0x42274
+/* [ST 32] The number of requests received from the pxp async if */
+#define TSDM_REG_NUM_OF_PXP_ASYNC_REQ                           0x42278
+/* [ST 32] The number of commands received in queue 0 */
+#define TSDM_REG_NUM_OF_Q0_CMD                                  0x42248
+/* [ST 32] The number of commands received in queue 10 */
+#define TSDM_REG_NUM_OF_Q10_CMD                                 0x4226c
+/* [ST 32] The number of commands received in queue 11 */
+#define TSDM_REG_NUM_OF_Q11_CMD                                 0x42270
+/* [ST 32] The number of commands received in queue 1 */
+#define TSDM_REG_NUM_OF_Q1_CMD                                  0x4224c
+/* [ST 32] The number of commands received in queue 3 */
+#define TSDM_REG_NUM_OF_Q3_CMD                                  0x42250
+/* [ST 32] The number of commands received in queue 4 */
+#define TSDM_REG_NUM_OF_Q4_CMD                                  0x42254
+/* [ST 32] The number of commands received in queue 5 */
+#define TSDM_REG_NUM_OF_Q5_CMD                                  0x42258
+/* [ST 32] The number of commands received in queue 6 */
+#define TSDM_REG_NUM_OF_Q6_CMD                                  0x4225c
+/* [ST 32] The number of commands received in queue 7 */
+#define TSDM_REG_NUM_OF_Q7_CMD                                  0x42260
+/* [ST 32] The number of commands received in queue 8 */
+#define TSDM_REG_NUM_OF_Q8_CMD                                  0x42264
+/* [ST 32] The number of commands received in queue 9 */
+#define TSDM_REG_NUM_OF_Q9_CMD                                  0x42268
+/* [RW 13] The start address in the internal RAM for the packet end message */
+#define TSDM_REG_PCK_END_MSG_START_ADDR                         0x42014
+/* [RW 13] The start address in the internal RAM for queue counters */
+#define TSDM_REG_Q_COUNTER_START_ADDR                           0x42010
+/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */
+#define TSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY                       0x42548
+/* [R 1] parser fifo empty in sdm_sync block */
+#define TSDM_REG_SYNC_PARSER_EMPTY                              0x42550
+/* [R 1] parser serial fifo empty in sdm_sync block */
+#define TSDM_REG_SYNC_SYNC_EMPTY                                0x42558
+/* [RW 32] Tick for timer counter. Applicable only when
+   ~tsdm_registers_timer_tick_enable.timer_tick_enable =1 */
+#define TSDM_REG_TIMER_TICK                                     0x42000
+/* [RW 32] Interrupt mask register #0 read/write */
+#define TSDM_REG_TSDM_INT_MASK_0                                0x4229c
+#define TSDM_REG_TSDM_INT_MASK_1                                0x422ac
+/* [RW 11] Parity mask register #0 read/write */
+#define TSDM_REG_TSDM_PRTY_MASK                                 0x422bc
+/* [RW 5] The number of time_slots in the arbitration cycle */
+#define TSEM_REG_ARB_CYCLE_SIZE                                 0x180034
+/* [RW 3] The source that is associated with arbitration element 0. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2 */
+#define TSEM_REG_ARB_ELEMENT0                                   0x180020
+/* [RW 3] The source that is associated with arbitration element 1. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~tsem_registers_arb_element0.arb_element0 */
+#define TSEM_REG_ARB_ELEMENT1                                   0x180024
+/* [RW 3] The source that is associated with arbitration element 2. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~tsem_registers_arb_element0.arb_element0
+   and ~tsem_registers_arb_element1.arb_element1 */
+#define TSEM_REG_ARB_ELEMENT2                                   0x180028
+/* [RW 3] The source that is associated with arbitration element 3. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.Could
+   not be equal to register ~tsem_registers_arb_element0.arb_element0 and
+   ~tsem_registers_arb_element1.arb_element1 and
+   ~tsem_registers_arb_element2.arb_element2 */
+#define TSEM_REG_ARB_ELEMENT3                                   0x18002c
+/* [RW 3] The source that is associated with arbitration element 4. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~tsem_registers_arb_element0.arb_element0
+   and ~tsem_registers_arb_element1.arb_element1 and
+   ~tsem_registers_arb_element2.arb_element2 and
+   ~tsem_registers_arb_element3.arb_element3 */
+#define TSEM_REG_ARB_ELEMENT4                                   0x180030
+#define TSEM_REG_ENABLE_IN                                      0x1800a4
+#define TSEM_REG_ENABLE_OUT                                     0x1800a8
+/* [RW 32] This address space contains all registers and memories that are
+   placed in SEM_FAST block. The SEM_FAST registers are described in
+   appendix B. In order to access the SEM_FAST registers the base address
+   TSEM_REGISTERS_FAST_MEMORY (Offset: 0x1a0000) should be added to each
+   SEM_FAST register offset. */
+#define TSEM_REG_FAST_MEMORY                                    0x1a0000
+/* [RW 1] Disables input messages from FIC0 May be updated during run_time
+   by the microcode */
+#define TSEM_REG_FIC0_DISABLE                                   0x180224
+/* [RW 1] Disables input messages from FIC1 May be updated during run_time
+   by the microcode */
+#define TSEM_REG_FIC1_DISABLE                                   0x180234
+/* [RW 15] Interrupt table Read and write access to it is not possible in
+   the middle of the work */
+#define TSEM_REG_INT_TABLE                                      0x180400
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC0 */
+#define TSEM_REG_MSG_NUM_FIC0                                   0x180000
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC1 */
+#define TSEM_REG_MSG_NUM_FIC1                                   0x180004
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC0 */
+#define TSEM_REG_MSG_NUM_FOC0                                   0x180008
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC1 */
+#define TSEM_REG_MSG_NUM_FOC1                                   0x18000c
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC2 */
+#define TSEM_REG_MSG_NUM_FOC2                                   0x180010
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC3 */
+#define TSEM_REG_MSG_NUM_FOC3                                   0x180014
+/* [RW 1] Disables input messages from the passive buffer May be updated
+   during run_time by the microcode */
+#define TSEM_REG_PAS_DISABLE                                    0x18024c
+/* [WB 128] Debug only. Passive buffer memory */
+#define TSEM_REG_PASSIVE_BUFFER                                 0x181000
+/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */
+#define TSEM_REG_PRAM                                           0x1c0000
+/* [R 8] Valid sleeping threads indication have bit per thread */
+#define TSEM_REG_SLEEP_THREADS_VALID                            0x18026c
+/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */
+#define TSEM_REG_SLOW_EXT_STORE_EMPTY                           0x1802a0
+/* [RW 8] List of free threads . There is a bit per thread. */
+#define TSEM_REG_THREADS_LIST                                   0x1802e4
+/* [RW 3] The arbitration scheme of time_slot 0 */
+#define TSEM_REG_TS_0_AS                                        0x180038
+/* [RW 3] The arbitration scheme of time_slot 10 */
+#define TSEM_REG_TS_10_AS                                       0x180060
+/* [RW 3] The arbitration scheme of time_slot 11 */
+#define TSEM_REG_TS_11_AS                                       0x180064
+/* [RW 3] The arbitration scheme of time_slot 12 */
+#define TSEM_REG_TS_12_AS                                       0x180068
+/* [RW 3] The arbitration scheme of time_slot 13 */
+#define TSEM_REG_TS_13_AS                                       0x18006c
+/* [RW 3] The arbitration scheme of time_slot 14 */
+#define TSEM_REG_TS_14_AS                                       0x180070
+/* [RW 3] The arbitration scheme of time_slot 15 */
+#define TSEM_REG_TS_15_AS                                       0x180074
+/* [RW 3] The arbitration scheme of time_slot 16 */
+#define TSEM_REG_TS_16_AS                                       0x180078
+/* [RW 3] The arbitration scheme of time_slot 17 */
+#define TSEM_REG_TS_17_AS                                       0x18007c
+/* [RW 3] The arbitration scheme of time_slot 18 */
+#define TSEM_REG_TS_18_AS                                       0x180080
+/* [RW 3] The arbitration scheme of time_slot 1 */
+#define TSEM_REG_TS_1_AS                                        0x18003c
+/* [RW 3] The arbitration scheme of time_slot 2 */
+#define TSEM_REG_TS_2_AS                                        0x180040
+/* [RW 3] The arbitration scheme of time_slot 3 */
+#define TSEM_REG_TS_3_AS                                        0x180044
+/* [RW 3] The arbitration scheme of time_slot 4 */
+#define TSEM_REG_TS_4_AS                                        0x180048
+/* [RW 3] The arbitration scheme of time_slot 5 */
+#define TSEM_REG_TS_5_AS                                        0x18004c
+/* [RW 3] The arbitration scheme of time_slot 6 */
+#define TSEM_REG_TS_6_AS                                        0x180050
+/* [RW 3] The arbitration scheme of time_slot 7 */
+#define TSEM_REG_TS_7_AS                                        0x180054
+/* [RW 3] The arbitration scheme of time_slot 8 */
+#define TSEM_REG_TS_8_AS                                        0x180058
+/* [RW 3] The arbitration scheme of time_slot 9 */
+#define TSEM_REG_TS_9_AS                                        0x18005c
+/* [RW 32] Interrupt mask register #0 read/write */
+#define TSEM_REG_TSEM_INT_MASK_0                                0x180100
+#define TSEM_REG_TSEM_INT_MASK_1                                0x180110
+/* [RW 32] Parity mask register #0 read/write */
+#define TSEM_REG_TSEM_PRTY_MASK_0                               0x180120
+#define TSEM_REG_TSEM_PRTY_MASK_1                               0x180130
+/* [R 5] Used to read the XX protection CAM occupancy counter. */
+#define UCM_REG_CAM_OCCUP                                       0xe0170
+/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define UCM_REG_CDU_AG_RD_IFEN                                  0xe0038
+/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input
+   are disregarded; all other signals are treated as usual; if 1 - normal
+   activity. */
+#define UCM_REG_CDU_AG_WR_IFEN                                  0xe0034
+/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define UCM_REG_CDU_SM_RD_IFEN                                  0xe0040
+/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid
+   input is disregarded; all other signals are treated as usual; if 1 -
+   normal activity. */
+#define UCM_REG_CDU_SM_WR_IFEN                                  0xe003c
+/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 1 at start-up. */
+#define UCM_REG_CFC_INIT_CRD                                    0xe0204
+/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_CP_WEIGHT                                       0xe00c4
+/* [RW 1] Input csem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_CSEM_IFEN                                       0xe0028
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the csem interface is detected. */
+#define UCM_REG_CSEM_LENGTH_MIS                                 0xe0160
+/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_CSEM_WEIGHT                                     0xe00b8
+/* [RW 1] Input dorq Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_DORQ_IFEN                                       0xe0030
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the dorq interface is detected. */
+#define UCM_REG_DORQ_LENGTH_MIS                                 0xe0168
+/* [RW 8] The Event ID in case ErrorFlg input message bit is set. */
+#define UCM_REG_ERR_EVNT_ID                                     0xe00a4
+/* [RW 28] The CM erroneous header for QM and Timers formatting. */
+#define UCM_REG_ERR_UCM_HDR                                     0xe00a0
+/* [RW 8] The Event ID for Timers expiration. */
+#define UCM_REG_EXPR_EVNT_ID                                    0xe00a8
+/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define UCM_REG_FIC0_INIT_CRD                                   0xe020c
+/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define UCM_REG_FIC1_INIT_CRD                                   0xe0210
+/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1
+   - strict priority defined by ~ucm_registers_gr_ag_pr.gr_ag_pr;
+   ~ucm_registers_gr_ld0_pr.gr_ld0_pr and
+   ~ucm_registers_gr_ld1_pr.gr_ld1_pr. */
+#define UCM_REG_GR_ARB_TYPE                                     0xe0144
+/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Store channel group is
+   compliment to the others. */
+#define UCM_REG_GR_LD0_PR                                       0xe014c
+/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Store channel group is
+   compliment to the others. */
+#define UCM_REG_GR_LD1_PR                                       0xe0150
+/* [RW 2] The queue index for invalidate counter flag decision. */
+#define UCM_REG_INV_CFLG_Q                                      0xe00e4
+/* [RW 5] The number of double REG-pairs; loaded from the STORM context and
+   sent to STORM; for a specific connection type. the double REG-pairs are
+   used in order to align to STORM context row size of 128 bits. The offset
+   of these data in the STORM context is always 0. Index _i stands for the
+   connection type (one of 16). */
+#define UCM_REG_N_SM_CTX_LD_0                                   0xe0054
+#define UCM_REG_N_SM_CTX_LD_1                                   0xe0058
+#define UCM_REG_N_SM_CTX_LD_10                                  0xe007c
+#define UCM_REG_N_SM_CTX_LD_11                                  0xe0080
+#define UCM_REG_N_SM_CTX_LD_12                                  0xe0084
+#define UCM_REG_N_SM_CTX_LD_13                                  0xe0088
+#define UCM_REG_N_SM_CTX_LD_14                                  0xe008c
+#define UCM_REG_N_SM_CTX_LD_15                                  0xe0090
+#define UCM_REG_N_SM_CTX_LD_2                                   0xe005c
+#define UCM_REG_N_SM_CTX_LD_3                                   0xe0060
+#define UCM_REG_N_SM_CTX_LD_4                                   0xe0064
+/* [RW 6] The physical queue number 0 per port index (CID[23]) */
+#define UCM_REG_PHYS_QNUM0_0                                    0xe0110
+#define UCM_REG_PHYS_QNUM0_1                                    0xe0114
+/* [RW 6] The physical queue number 1 per port index (CID[23]) */
+#define UCM_REG_PHYS_QNUM1_0                                    0xe0118
+#define UCM_REG_PHYS_QNUM1_1                                    0xe011c
+/* [RW 8] The Event ID for Timers formatting in case of stop done. */
+#define UCM_REG_STOP_EVNT_ID                                    0xe00ac
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the STORM interface is detected. */
+#define UCM_REG_STORM_LENGTH_MIS                                0xe0154
+/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_STORM_UCM_IFEN                                  0xe0010
+/* [RW 4] Timers output initial credit. Max credit available - 15.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 4 at start-up. */
+#define UCM_REG_TM_INIT_CRD                                     0xe021c
+/* [RW 28] The CM header for Timers expiration command. */
+#define UCM_REG_TM_UCM_HDR                                      0xe009c
+/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_TM_UCM_IFEN                                     0xe001c
+/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_TSEM_IFEN                                       0xe0024
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the tsem interface is detected. */
+#define UCM_REG_TSEM_LENGTH_MIS                                 0xe015c
+/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_TSEM_WEIGHT                                     0xe00b4
+/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_UCM_CFC_IFEN                                    0xe0044
+/* [RW 11] Interrupt mask register #0 read/write */
+#define UCM_REG_UCM_INT_MASK                                    0xe01d4
+/* [R 11] Interrupt register #0 read */
+#define UCM_REG_UCM_INT_STS                                     0xe01c8
+/* [RW 2] The size of AG context region 0 in REG-pairs. Designates the MS
+   REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
+   Is used to determine the number of the AG context REG-pairs written back;
+   when the Reg1WbFlg isn't set. */
+#define UCM_REG_UCM_REG0_SZ                                     0xe00dc
+/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_UCM_STORM0_IFEN                                 0xe0004
+/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_UCM_STORM1_IFEN                                 0xe0008
+/* [RW 1] CM - Timers Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_UCM_TM_IFEN                                     0xe0020
+/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_UCM_UQM_IFEN                                    0xe000c
+/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */
+#define UCM_REG_UCM_UQM_USE_Q                                   0xe00d8
+/* [RW 6] QM output initial credit. Max credit available - 32.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 32 at start-up. */
+#define UCM_REG_UQM_INIT_CRD                                    0xe0220
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define UCM_REG_UQM_P_WEIGHT                                    0xe00cc
+/* [RW 28] The CM header value for QM request (primary). */
+#define UCM_REG_UQM_UCM_HDR_P                                   0xe0094
+/* [RW 28] The CM header value for QM request (secondary). */
+#define UCM_REG_UQM_UCM_HDR_S                                   0xe0098
+/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_UQM_UCM_IFEN                                    0xe0014
+/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define UCM_REG_USDM_IFEN                                       0xe0018
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the SDM interface is detected. */
+#define UCM_REG_USDM_LENGTH_MIS                                 0xe0158
+/* [RW 1] Input xsem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define UCM_REG_XSEM_IFEN                                       0xe002c
+/* [RC 1] Set when the message length mismatch (relative to last indication)
+   at the xsem interface isdetected. */
+#define UCM_REG_XSEM_LENGTH_MIS                                 0xe0164
+/* [RW 20] Indirect access to the descriptor table of the XX protection
+   mechanism. The fields are:[5:0] - message length; 14:6] - message
+   pointer; 19:15] - next pointer. */
+#define UCM_REG_XX_DESCR_TABLE                                  0xe0280
+/* [R 6] Use to read the XX protection Free counter. */
+#define UCM_REG_XX_FREE                                         0xe016c
+/* [RW 6] Initial value for the credit counter; responsible for fulfilling
+   of the Input Stage XX protection buffer by the XX protection pending
+   messages. Write writes the initial credit value; read returns the current
+   value of the credit counter. Must be initialized to 12 at start-up. */
+#define UCM_REG_XX_INIT_CRD                                     0xe0224
+/* [RW 6] The maximum number of pending messages; which may be stored in XX
+   protection. ~ucm_registers_xx_free.xx_free read on read. */
+#define UCM_REG_XX_MSG_NUM                                      0xe0228
+/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */
+#define UCM_REG_XX_OVFL_EVNT_ID                                 0xe004c
+/* [RW 16] Indirect access to the XX table of the XX protection mechanism.
+   The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] -
+   header pointer. */
+#define UCM_REG_XX_TABLE                                        0xe0300
+/* [RW 8] The event id for aggregated interrupt 0 */
+#define USDM_REG_AGG_INT_EVENT_0                                0xc4038
+#define USDM_REG_AGG_INT_EVENT_1                                0xc403c
+#define USDM_REG_AGG_INT_EVENT_10                               0xc4060
+#define USDM_REG_AGG_INT_EVENT_11                               0xc4064
+#define USDM_REG_AGG_INT_EVENT_12                               0xc4068
+#define USDM_REG_AGG_INT_EVENT_13                               0xc406c
+#define USDM_REG_AGG_INT_EVENT_14                               0xc4070
+#define USDM_REG_AGG_INT_EVENT_15                               0xc4074
+#define USDM_REG_AGG_INT_EVENT_16                               0xc4078
+#define USDM_REG_AGG_INT_EVENT_17                               0xc407c
+#define USDM_REG_AGG_INT_EVENT_18                               0xc4080
+#define USDM_REG_AGG_INT_EVENT_19                               0xc4084
+/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
+   or auto-mask-mode (1) */
+#define USDM_REG_AGG_INT_MODE_0                                 0xc41b8
+#define USDM_REG_AGG_INT_MODE_1                                 0xc41bc
+#define USDM_REG_AGG_INT_MODE_10                                0xc41e0
+#define USDM_REG_AGG_INT_MODE_11                                0xc41e4
+#define USDM_REG_AGG_INT_MODE_12                                0xc41e8
+#define USDM_REG_AGG_INT_MODE_13                                0xc41ec
+#define USDM_REG_AGG_INT_MODE_14                                0xc41f0
+#define USDM_REG_AGG_INT_MODE_15                                0xc41f4
+#define USDM_REG_AGG_INT_MODE_16                                0xc41f8
+#define USDM_REG_AGG_INT_MODE_17                                0xc41fc
+#define USDM_REG_AGG_INT_MODE_18                                0xc4200
+#define USDM_REG_AGG_INT_MODE_19                                0xc4204
+/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
+#define USDM_REG_CFC_RSP_START_ADDR                             0xc4008
+/* [RW 16] The maximum value of the competion counter #0 */
+#define USDM_REG_CMP_COUNTER_MAX0                               0xc401c
+/* [RW 16] The maximum value of the competion counter #1 */
+#define USDM_REG_CMP_COUNTER_MAX1                               0xc4020
+/* [RW 16] The maximum value of the competion counter #2 */
+#define USDM_REG_CMP_COUNTER_MAX2                               0xc4024
+/* [RW 16] The maximum value of the competion counter #3 */
+#define USDM_REG_CMP_COUNTER_MAX3                               0xc4028
+/* [RW 13] The start address in the internal RAM for the completion
+   counters. */
+#define USDM_REG_CMP_COUNTER_START_ADDR                         0xc400c
+#define USDM_REG_ENABLE_IN1                                     0xc4238
+#define USDM_REG_ENABLE_IN2                                     0xc423c
+#define USDM_REG_ENABLE_OUT1                                    0xc4240
+#define USDM_REG_ENABLE_OUT2                                    0xc4244
+/* [RW 4] The initial number of messages that can be sent to the pxp control
+   interface without receiving any ACK. */
+#define USDM_REG_INIT_CREDIT_PXP_CTRL                           0xc44c0
+/* [ST 32] The number of ACK after placement messages received */
+#define USDM_REG_NUM_OF_ACK_AFTER_PLACE                         0xc4280
+/* [ST 32] The number of packet end messages received from the parser */
+#define USDM_REG_NUM_OF_PKT_END_MSG                             0xc4278
+/* [ST 32] The number of requests received from the pxp async if */
+#define USDM_REG_NUM_OF_PXP_ASYNC_REQ                           0xc427c
+/* [ST 32] The number of commands received in queue 0 */
+#define USDM_REG_NUM_OF_Q0_CMD                                  0xc4248
+/* [ST 32] The number of commands received in queue 10 */
+#define USDM_REG_NUM_OF_Q10_CMD                                 0xc4270
+/* [ST 32] The number of commands received in queue 11 */
+#define USDM_REG_NUM_OF_Q11_CMD                                 0xc4274
+/* [ST 32] The number of commands received in queue 1 */
+#define USDM_REG_NUM_OF_Q1_CMD                                  0xc424c
+/* [ST 32] The number of commands received in queue 2 */
+#define USDM_REG_NUM_OF_Q2_CMD                                  0xc4250
+/* [ST 32] The number of commands received in queue 3 */
+#define USDM_REG_NUM_OF_Q3_CMD                                  0xc4254
+/* [ST 32] The number of commands received in queue 4 */
+#define USDM_REG_NUM_OF_Q4_CMD                                  0xc4258
+/* [ST 32] The number of commands received in queue 5 */
+#define USDM_REG_NUM_OF_Q5_CMD                                  0xc425c
+/* [ST 32] The number of commands received in queue 6 */
+#define USDM_REG_NUM_OF_Q6_CMD                                  0xc4260
+/* [ST 32] The number of commands received in queue 7 */
+#define USDM_REG_NUM_OF_Q7_CMD                                  0xc4264
+/* [ST 32] The number of commands received in queue 8 */
+#define USDM_REG_NUM_OF_Q8_CMD                                  0xc4268
+/* [ST 32] The number of commands received in queue 9 */
+#define USDM_REG_NUM_OF_Q9_CMD                                  0xc426c
+/* [RW 13] The start address in the internal RAM for the packet end message */
+#define USDM_REG_PCK_END_MSG_START_ADDR                         0xc4014
+/* [RW 13] The start address in the internal RAM for queue counters */
+#define USDM_REG_Q_COUNTER_START_ADDR                           0xc4010
+/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */
+#define USDM_REG_RSP_PXP_CTRL_RDATA_EMPTY                       0xc4550
+/* [R 1] parser fifo empty in sdm_sync block */
+#define USDM_REG_SYNC_PARSER_EMPTY                              0xc4558
+/* [R 1] parser serial fifo empty in sdm_sync block */
+#define USDM_REG_SYNC_SYNC_EMPTY                                0xc4560
+/* [RW 32] Tick for timer counter. Applicable only when
+   ~usdm_registers_timer_tick_enable.timer_tick_enable =1 */
+#define USDM_REG_TIMER_TICK                                     0xc4000
+/* [RW 32] Interrupt mask register #0 read/write */
+#define USDM_REG_USDM_INT_MASK_0                                0xc42a0
+#define USDM_REG_USDM_INT_MASK_1                                0xc42b0
+/* [RW 11] Parity mask register #0 read/write */
+#define USDM_REG_USDM_PRTY_MASK                                 0xc42c0
+/* [RW 5] The number of time_slots in the arbitration cycle */
+#define USEM_REG_ARB_CYCLE_SIZE                                 0x300034
+/* [RW 3] The source that is associated with arbitration element 0. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2 */
+#define USEM_REG_ARB_ELEMENT0                                   0x300020
+/* [RW 3] The source that is associated with arbitration element 1. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~usem_registers_arb_element0.arb_element0 */
+#define USEM_REG_ARB_ELEMENT1                                   0x300024
+/* [RW 3] The source that is associated with arbitration element 2. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~usem_registers_arb_element0.arb_element0
+   and ~usem_registers_arb_element1.arb_element1 */
+#define USEM_REG_ARB_ELEMENT2                                   0x300028
+/* [RW 3] The source that is associated with arbitration element 3. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.Could
+   not be equal to register ~usem_registers_arb_element0.arb_element0 and
+   ~usem_registers_arb_element1.arb_element1 and
+   ~usem_registers_arb_element2.arb_element2 */
+#define USEM_REG_ARB_ELEMENT3                                   0x30002c
+/* [RW 3] The source that is associated with arbitration element 4. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~usem_registers_arb_element0.arb_element0
+   and ~usem_registers_arb_element1.arb_element1 and
+   ~usem_registers_arb_element2.arb_element2 and
+   ~usem_registers_arb_element3.arb_element3 */
+#define USEM_REG_ARB_ELEMENT4                                   0x300030
+#define USEM_REG_ENABLE_IN                                      0x3000a4
+#define USEM_REG_ENABLE_OUT                                     0x3000a8
+/* [RW 32] This address space contains all registers and memories that are
+   placed in SEM_FAST block. The SEM_FAST registers are described in
+   appendix B. In order to access the SEM_FAST registers... the base address
+   USEM_REGISTERS_FAST_MEMORY (Offset: 0x320000) should be added to each
+   SEM_FAST register offset. */
+#define USEM_REG_FAST_MEMORY                                    0x320000
+/* [RW 1] Disables input messages from FIC0 May be updated during run_time
+   by the microcode */
+#define USEM_REG_FIC0_DISABLE                                   0x300224
+/* [RW 1] Disables input messages from FIC1 May be updated during run_time
+   by the microcode */
+#define USEM_REG_FIC1_DISABLE                                   0x300234
+/* [RW 15] Interrupt table Read and write access to it is not possible in
+   the middle of the work */
+#define USEM_REG_INT_TABLE                                      0x300400
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC0 */
+#define USEM_REG_MSG_NUM_FIC0                                   0x300000
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC1 */
+#define USEM_REG_MSG_NUM_FIC1                                   0x300004
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC0 */
+#define USEM_REG_MSG_NUM_FOC0                                   0x300008
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC1 */
+#define USEM_REG_MSG_NUM_FOC1                                   0x30000c
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC2 */
+#define USEM_REG_MSG_NUM_FOC2                                   0x300010
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC3 */
+#define USEM_REG_MSG_NUM_FOC3                                   0x300014
+/* [RW 1] Disables input messages from the passive buffer May be updated
+   during run_time by the microcode */
+#define USEM_REG_PAS_DISABLE                                    0x30024c
+/* [WB 128] Debug only. Passive buffer memory */
+#define USEM_REG_PASSIVE_BUFFER                                 0x302000
+/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */
+#define USEM_REG_PRAM                                           0x340000
+/* [R 16] Valid sleeping threads indication have bit per thread */
+#define USEM_REG_SLEEP_THREADS_VALID                            0x30026c
+/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */
+#define USEM_REG_SLOW_EXT_STORE_EMPTY                           0x3002a0
+/* [RW 16] List of free threads . There is a bit per thread. */
+#define USEM_REG_THREADS_LIST                                   0x3002e4
+/* [RW 3] The arbitration scheme of time_slot 0 */
+#define USEM_REG_TS_0_AS                                        0x300038
+/* [RW 3] The arbitration scheme of time_slot 10 */
+#define USEM_REG_TS_10_AS                                       0x300060
+/* [RW 3] The arbitration scheme of time_slot 11 */
+#define USEM_REG_TS_11_AS                                       0x300064
+/* [RW 3] The arbitration scheme of time_slot 12 */
+#define USEM_REG_TS_12_AS                                       0x300068
+/* [RW 3] The arbitration scheme of time_slot 13 */
+#define USEM_REG_TS_13_AS                                       0x30006c
+/* [RW 3] The arbitration scheme of time_slot 14 */
+#define USEM_REG_TS_14_AS                                       0x300070
+/* [RW 3] The arbitration scheme of time_slot 15 */
+#define USEM_REG_TS_15_AS                                       0x300074
+/* [RW 3] The arbitration scheme of time_slot 16 */
+#define USEM_REG_TS_16_AS                                       0x300078
+/* [RW 3] The arbitration scheme of time_slot 17 */
+#define USEM_REG_TS_17_AS                                       0x30007c
+/* [RW 3] The arbitration scheme of time_slot 18 */
+#define USEM_REG_TS_18_AS                                       0x300080
+/* [RW 3] The arbitration scheme of time_slot 1 */
+#define USEM_REG_TS_1_AS                                        0x30003c
+/* [RW 3] The arbitration scheme of time_slot 2 */
+#define USEM_REG_TS_2_AS                                        0x300040
+/* [RW 3] The arbitration scheme of time_slot 3 */
+#define USEM_REG_TS_3_AS                                        0x300044
+/* [RW 3] The arbitration scheme of time_slot 4 */
+#define USEM_REG_TS_4_AS                                        0x300048
+/* [RW 3] The arbitration scheme of time_slot 5 */
+#define USEM_REG_TS_5_AS                                        0x30004c
+/* [RW 3] The arbitration scheme of time_slot 6 */
+#define USEM_REG_TS_6_AS                                        0x300050
+/* [RW 3] The arbitration scheme of time_slot 7 */
+#define USEM_REG_TS_7_AS                                        0x300054
+/* [RW 3] The arbitration scheme of time_slot 8 */
+#define USEM_REG_TS_8_AS                                        0x300058
+/* [RW 3] The arbitration scheme of time_slot 9 */
+#define USEM_REG_TS_9_AS                                        0x30005c
+/* [RW 32] Interrupt mask register #0 read/write */
+#define USEM_REG_USEM_INT_MASK_0                                0x300110
+#define USEM_REG_USEM_INT_MASK_1                                0x300120
+/* [RW 32] Parity mask register #0 read/write */
+#define USEM_REG_USEM_PRTY_MASK_0                               0x300130
+#define USEM_REG_USEM_PRTY_MASK_1                               0x300140
+/* [RW 2] The queue index for registration on Aux1 counter flag. */
+#define XCM_REG_AUX1_Q                                          0x20134
+/* [RW 2] Per each decision rule the queue index to register to. */
+#define XCM_REG_AUX_CNT_FLG_Q_19                                0x201b0
+/* [R 5] Used to read the XX protection CAM occupancy counter. */
+#define XCM_REG_CAM_OCCUP                                       0x20244
+/* [RW 1] CDU AG read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define XCM_REG_CDU_AG_RD_IFEN                                  0x20044
+/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input
+   are disregarded; all other signals are treated as usual; if 1 - normal
+   activity. */
+#define XCM_REG_CDU_AG_WR_IFEN                                  0x20040
+/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is
+   disregarded; valid output is deasserted; all other signals are treated as
+   usual; if 1 - normal activity. */
+#define XCM_REG_CDU_SM_RD_IFEN                                  0x2004c
+/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid
+   input is disregarded; all other signals are treated as usual; if 1 -
+   normal activity. */
+#define XCM_REG_CDU_SM_WR_IFEN                                  0x20048
+/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 1 at start-up. */
+#define XCM_REG_CFC_INIT_CRD                                    0x20404
+/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_CP_WEIGHT                                       0x200dc
+/* [RW 1] Input csem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_CSEM_IFEN                                       0x20028
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the csem interface. */
+#define XCM_REG_CSEM_LENGTH_MIS                                 0x20228
+/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_CSEM_WEIGHT                                     0x200c4
+/* [RW 1] Input dorq Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_DORQ_IFEN                                       0x20030
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the dorq interface. */
+#define XCM_REG_DORQ_LENGTH_MIS                                 0x20230
+/* [RW 8] The Event ID in case the ErrorFlg input message bit is set. */
+#define XCM_REG_ERR_EVNT_ID                                     0x200b0
+/* [RW 28] The CM erroneous header for QM and Timers formatting. */
+#define XCM_REG_ERR_XCM_HDR                                     0x200ac
+/* [RW 8] The Event ID for Timers expiration. */
+#define XCM_REG_EXPR_EVNT_ID                                    0x200b4
+/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define XCM_REG_FIC0_INIT_CRD                                   0x2040c
+/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 64 at start-up. */
+#define XCM_REG_FIC1_INIT_CRD                                   0x20410
+/* [RW 8] The maximum delayed ACK counter value.Must be at least 2. Per port
+   value. */
+#define XCM_REG_GLB_DEL_ACK_MAX_CNT_0                           0x20118
+#define XCM_REG_GLB_DEL_ACK_MAX_CNT_1                           0x2011c
+/* [RW 28] The delayed ACK timeout in ticks. Per port value. */
+#define XCM_REG_GLB_DEL_ACK_TMR_VAL_0                           0x20108
+#define XCM_REG_GLB_DEL_ACK_TMR_VAL_1                           0x2010c
+/* [RW 1] Arbitratiojn between Input Arbiter groups: 0 - fair Round-Robin; 1
+   - strict priority defined by ~xcm_registers_gr_ag_pr.gr_ag_pr;
+   ~xcm_registers_gr_ld0_pr.gr_ld0_pr and
+   ~xcm_registers_gr_ld1_pr.gr_ld1_pr. */
+#define XCM_REG_GR_ARB_TYPE                                     0x2020c
+/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Channel group is the
+   compliment of the other 3 groups. */
+#define XCM_REG_GR_LD0_PR                                       0x20214
+/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the
+   highest priority is 3. It is supposed that the Channel group is the
+   compliment of the other 3 groups. */
+#define XCM_REG_GR_LD1_PR                                       0x20218
+/* [RW 1] Input nig0 Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_NIG0_IFEN                                       0x20038
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the nig0 interface. */
+#define XCM_REG_NIG0_LENGTH_MIS                                 0x20238
+/* [RW 1] Input nig1 Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_NIG1_IFEN                                       0x2003c
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the nig1 interface. */
+#define XCM_REG_NIG1_LENGTH_MIS                                 0x2023c
+/* [RW 3] The weight of the input nig1 in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_NIG1_WEIGHT                                     0x200d8
+/* [RW 5] The number of double REG-pairs; loaded from the STORM context and
+   sent to STORM; for a specific connection type. The double REG-pairs are
+   used in order to align to STORM context row size of 128 bits. The offset
+   of these data in the STORM context is always 0. Index _i stands for the
+   connection type (one of 16). */
+#define XCM_REG_N_SM_CTX_LD_0                                   0x20060
+#define XCM_REG_N_SM_CTX_LD_1                                   0x20064
+#define XCM_REG_N_SM_CTX_LD_10                                  0x20088
+#define XCM_REG_N_SM_CTX_LD_11                                  0x2008c
+#define XCM_REG_N_SM_CTX_LD_12                                  0x20090
+#define XCM_REG_N_SM_CTX_LD_13                                  0x20094
+#define XCM_REG_N_SM_CTX_LD_14                                  0x20098
+#define XCM_REG_N_SM_CTX_LD_15                                  0x2009c
+#define XCM_REG_N_SM_CTX_LD_2                                   0x20068
+#define XCM_REG_N_SM_CTX_LD_3                                   0x2006c
+#define XCM_REG_N_SM_CTX_LD_4                                   0x20070
+/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_PBF_IFEN                                        0x20034
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the pbf interface. */
+#define XCM_REG_PBF_LENGTH_MIS                                  0x20234
+/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_PBF_WEIGHT                                      0x200d0
+/* [RW 8] The Event ID for Timers formatting in case of stop done. */
+#define XCM_REG_STOP_EVNT_ID                                    0x200b8
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the STORM interface. */
+#define XCM_REG_STORM_LENGTH_MIS                                0x2021c
+/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_STORM_WEIGHT                                    0x200bc
+/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_STORM_XCM_IFEN                                  0x20010
+/* [RW 4] Timers output initial credit. Max credit available - 15.Write
+   writes the initial credit value; read returns the current value of the
+   credit counter. Must be initialized to 4 at start-up. */
+#define XCM_REG_TM_INIT_CRD                                     0x2041c
+/* [RW 28] The CM header for Timers expiration command. */
+#define XCM_REG_TM_XCM_HDR                                      0x200a8
+/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_TM_XCM_IFEN                                     0x2001c
+/* [RW 1] Input tsem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_TSEM_IFEN                                       0x20024
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the tsem interface. */
+#define XCM_REG_TSEM_LENGTH_MIS                                 0x20224
+/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_TSEM_WEIGHT                                     0x200c0
+/* [RW 2] The queue index for registration on UNA greater NXT decision rule. */
+#define XCM_REG_UNA_GT_NXT_Q                                    0x20120
+/* [RW 1] Input usem Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_USEM_IFEN                                       0x2002c
+/* [RC 1] Message length mismatch (relative to last indication) at the usem
+   interface. */
+#define XCM_REG_USEM_LENGTH_MIS                                 0x2022c
+/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_USEM_WEIGHT                                     0x200c8
+/* [RW 2] DA counter command; used in case of window update doorbell.The
+   first index stands for the value DaEnable of that connection. The second
+   index stands for port number. */
+#define XCM_REG_WU_DA_CNT_CMD00                                 0x201d4
+/* [RW 2] DA counter command; used in case of window update doorbell.The
+   first index stands for the value DaEnable of that connection. The second
+   index stands for port number. */
+#define XCM_REG_WU_DA_CNT_CMD01                                 0x201d8
+/* [RW 2] DA counter command; used in case of window update doorbell.The
+   first index stands for the value DaEnable of that connection. The second
+   index stands for port number. */
+#define XCM_REG_WU_DA_CNT_CMD10                                 0x201dc
+/* [RW 2] DA counter command; used in case of window update doorbell.The
+   first index stands for the value DaEnable of that connection. The second
+   index stands for port number. */
+#define XCM_REG_WU_DA_CNT_CMD11                                 0x201e0
+/* [RW 8] DA counter update value used in case of window update doorbell.The
+   first index stands for the value DaEnable of that connection. The second
+   index stands for port number. */
+#define XCM_REG_WU_DA_CNT_UPD_VAL00                             0x201e4
+/* [RW 8] DA counter update value; used in case of window update
+   doorbell.The first index stands for the value DaEnable of that
+   connection. The second index stands for port number. */
+#define XCM_REG_WU_DA_CNT_UPD_VAL01                             0x201e8
+/* [RW 8] DA counter update value; used in case of window update
+   doorbell.The first index stands for the value DaEnable of that
+   connection. The second index stands for port number. */
+#define XCM_REG_WU_DA_CNT_UPD_VAL10                             0x201ec
+/* [RW 8] DA counter update value; used in case of window update
+   doorbell.The first index stands for the value DaEnable of that
+   connection. The second index stands for port number. */
+#define XCM_REG_WU_DA_CNT_UPD_VAL11                             0x201f0
+/* [RW 1] DA timer command; used in case of window update doorbell.The first
+   index stands for the value DaEnable of that connection. The second index
+   stands for port number. */
+#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00                     0x201c4
+/* [RW 1] DA timer command; used in case of window update doorbell.The first
+   index stands for the value DaEnable of that connection. The second index
+   stands for port number. */
+#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01                     0x201c8
+/* [RW 1] DA timer command; used in case of window update doorbell.The first
+   index stands for the value DaEnable of that connection. The second index
+   stands for port number. */
+#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10                     0x201cc
+/* [RW 1] DA timer command; used in case of window update doorbell.The first
+   index stands for the value DaEnable of that connection. The second index
+   stands for port number. */
+#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11                     0x201d0
+/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XCM_CFC_IFEN                                    0x20050
+/* [RW 14] Interrupt mask register #0 read/write */
+#define XCM_REG_XCM_INT_MASK                                    0x202b4
+/* [R 14] Interrupt register #0 read */
+#define XCM_REG_XCM_INT_STS                                     0x202a8
+/* [RW 4] The size of AG context region 0 in REG-pairs. Designates the MS
+   REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5).
+   Is used to determine the number of the AG context REG-pairs written back;
+   when the Reg1WbFlg isn't set. */
+#define XCM_REG_XCM_REG0_SZ                                     0x200f4
+/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XCM_STORM0_IFEN                                 0x20004
+/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XCM_STORM1_IFEN                                 0x20008
+/* [RW 1] CM - Timers Interface enable. If 0 - the valid input is
+   disregarded; acknowledge output is deasserted; all other signals are
+   treated as usual; if 1 - normal activity. */
+#define XCM_REG_XCM_TM_IFEN                                     0x20020
+/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is
+   disregarded; valid is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XCM_XQM_IFEN                                    0x2000c
+/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */
+#define XCM_REG_XCM_XQM_USE_Q                                   0x200f0
+/* [RW 4] The value by which CFC updates the activity counter at QM bypass. */
+#define XCM_REG_XQM_BYP_ACT_UPD                                 0x200fc
+/* [RW 6] QM output initial credit. Max credit available - 32.Write writes
+   the initial credit value; read returns the current value of the credit
+   counter. Must be initialized to 32 at start-up. */
+#define XCM_REG_XQM_INIT_CRD                                    0x20420
+/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0
+   stands for weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_XQM_P_WEIGHT                                    0x200e4
+/* [RW 28] The CM header value for QM request (primary). */
+#define XCM_REG_XQM_XCM_HDR_P                                   0x200a0
+/* [RW 28] The CM header value for QM request (secondary). */
+#define XCM_REG_XQM_XCM_HDR_S                                   0x200a4
+/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XQM_XCM_IFEN                                    0x20014
+/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded;
+   acknowledge output is deasserted; all other signals are treated as usual;
+   if 1 - normal activity. */
+#define XCM_REG_XSDM_IFEN                                       0x20018
+/* [RC 1] Set at message length mismatch (relative to last indication) at
+   the SDM interface. */
+#define XCM_REG_XSDM_LENGTH_MIS                                 0x20220
+/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for
+   weight 8 (the most prioritised); 1 stands for weight 1(least
+   prioritised); 2 stands for weight 2; tc. */
+#define XCM_REG_XSDM_WEIGHT                                     0x200e0
+/* [RW 17] Indirect access to the descriptor table of the XX protection
+   mechanism. The fields are: [5:0] - message length; 11:6] - message
+   pointer; 16:12] - next pointer. */
+#define XCM_REG_XX_DESCR_TABLE                                  0x20480
+/* [R 6] Used to read the XX protection Free counter. */
+#define XCM_REG_XX_FREE                                         0x20240
+/* [RW 6] Initial value for the credit counter; responsible for fulfilling
+   of the Input Stage XX protection buffer by the XX protection pending
+   messages. Max credit available - 3.Write writes the initial credit value;
+   read returns the current value of the credit counter. Must be initialized
+   to 2 at start-up. */
+#define XCM_REG_XX_INIT_CRD                                     0x20424
+/* [RW 6] The maximum number of pending messages; which may be stored in XX
+   protection. ~xcm_registers_xx_free.xx_free read on read. */
+#define XCM_REG_XX_MSG_NUM                                      0x20428
+/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */
+#define XCM_REG_XX_OVFL_EVNT_ID                                 0x20058
+/* [RW 15] Indirect access to the XX table of the XX protection mechanism.
+   The fields are:[4:0] - tail pointer; 9:5] - Link List size; 14:10] -
+   header pointer. */
+#define XCM_REG_XX_TABLE                                        0x20500
+/* [RW 8] The event id for aggregated interrupt 0 */
+#define XSDM_REG_AGG_INT_EVENT_0                                0x166038
+#define XSDM_REG_AGG_INT_EVENT_1                                0x16603c
+#define XSDM_REG_AGG_INT_EVENT_10                               0x166060
+#define XSDM_REG_AGG_INT_EVENT_11                               0x166064
+#define XSDM_REG_AGG_INT_EVENT_12                               0x166068
+#define XSDM_REG_AGG_INT_EVENT_13                               0x16606c
+#define XSDM_REG_AGG_INT_EVENT_14                               0x166070
+#define XSDM_REG_AGG_INT_EVENT_15                               0x166074
+#define XSDM_REG_AGG_INT_EVENT_16                               0x166078
+#define XSDM_REG_AGG_INT_EVENT_17                               0x16607c
+#define XSDM_REG_AGG_INT_EVENT_18                               0x166080
+#define XSDM_REG_AGG_INT_EVENT_19                               0x166084
+#define XSDM_REG_AGG_INT_EVENT_2                                0x166040
+#define XSDM_REG_AGG_INT_EVENT_20                               0x166088
+#define XSDM_REG_AGG_INT_EVENT_21                               0x16608c
+#define XSDM_REG_AGG_INT_EVENT_22                               0x166090
+#define XSDM_REG_AGG_INT_EVENT_23                               0x166094
+#define XSDM_REG_AGG_INT_EVENT_24                               0x166098
+#define XSDM_REG_AGG_INT_EVENT_25                               0x16609c
+#define XSDM_REG_AGG_INT_EVENT_26                               0x1660a0
+#define XSDM_REG_AGG_INT_EVENT_27                               0x1660a4
+#define XSDM_REG_AGG_INT_EVENT_28                               0x1660a8
+#define XSDM_REG_AGG_INT_EVENT_29                               0x1660ac
+/* [RW 1] For each aggregated interrupt index whether the mode is normal (0)
+   or auto-mask-mode (1) */
+#define XSDM_REG_AGG_INT_MODE_0                                 0x1661b8
+#define XSDM_REG_AGG_INT_MODE_1                                 0x1661bc
+#define XSDM_REG_AGG_INT_MODE_10                                0x1661e0
+#define XSDM_REG_AGG_INT_MODE_11                                0x1661e4
+#define XSDM_REG_AGG_INT_MODE_12                                0x1661e8
+#define XSDM_REG_AGG_INT_MODE_13                                0x1661ec
+#define XSDM_REG_AGG_INT_MODE_14                                0x1661f0
+#define XSDM_REG_AGG_INT_MODE_15                                0x1661f4
+#define XSDM_REG_AGG_INT_MODE_16                                0x1661f8
+#define XSDM_REG_AGG_INT_MODE_17                                0x1661fc
+#define XSDM_REG_AGG_INT_MODE_18                                0x166200
+#define XSDM_REG_AGG_INT_MODE_19                                0x166204
+/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */
+#define XSDM_REG_CFC_RSP_START_ADDR                             0x166008
+/* [RW 16] The maximum value of the competion counter #0 */
+#define XSDM_REG_CMP_COUNTER_MAX0                               0x16601c
+/* [RW 16] The maximum value of the competion counter #1 */
+#define XSDM_REG_CMP_COUNTER_MAX1                               0x166020
+/* [RW 16] The maximum value of the competion counter #2 */
+#define XSDM_REG_CMP_COUNTER_MAX2                               0x166024
+/* [RW 16] The maximum value of the competion counter #3 */
+#define XSDM_REG_CMP_COUNTER_MAX3                               0x166028
+/* [RW 13] The start address in the internal RAM for the completion
+   counters. */
+#define XSDM_REG_CMP_COUNTER_START_ADDR                         0x16600c
+#define XSDM_REG_ENABLE_IN1                                     0x166238
+#define XSDM_REG_ENABLE_IN2                                     0x16623c
+#define XSDM_REG_ENABLE_OUT1                                    0x166240
+#define XSDM_REG_ENABLE_OUT2                                    0x166244
+/* [RW 4] The initial number of messages that can be sent to the pxp control
+   interface without receiving any ACK. */
+#define XSDM_REG_INIT_CREDIT_PXP_CTRL                           0x1664bc
+/* [ST 32] The number of ACK after placement messages received */
+#define XSDM_REG_NUM_OF_ACK_AFTER_PLACE                         0x16627c
+/* [ST 32] The number of packet end messages received from the parser */
+#define XSDM_REG_NUM_OF_PKT_END_MSG                             0x166274
+/* [ST 32] The number of requests received from the pxp async if */
+#define XSDM_REG_NUM_OF_PXP_ASYNC_REQ                           0x166278
+/* [ST 32] The number of commands received in queue 0 */
+#define XSDM_REG_NUM_OF_Q0_CMD                                  0x166248
+/* [ST 32] The number of commands received in queue 10 */
+#define XSDM_REG_NUM_OF_Q10_CMD                                 0x16626c
+/* [ST 32] The number of commands received in queue 11 */
+#define XSDM_REG_NUM_OF_Q11_CMD                                 0x166270
+/* [ST 32] The number of commands received in queue 1 */
+#define XSDM_REG_NUM_OF_Q1_CMD                                  0x16624c
+/* [ST 32] The number of commands received in queue 3 */
+#define XSDM_REG_NUM_OF_Q3_CMD                                  0x166250
+/* [ST 32] The number of commands received in queue 4 */
+#define XSDM_REG_NUM_OF_Q4_CMD                                  0x166254
+/* [ST 32] The number of commands received in queue 5 */
+#define XSDM_REG_NUM_OF_Q5_CMD                                  0x166258
+/* [ST 32] The number of commands received in queue 6 */
+#define XSDM_REG_NUM_OF_Q6_CMD                                  0x16625c
+/* [ST 32] The number of commands received in queue 7 */
+#define XSDM_REG_NUM_OF_Q7_CMD                                  0x166260
+/* [ST 32] The number of commands received in queue 8 */
+#define XSDM_REG_NUM_OF_Q8_CMD                                  0x166264
+/* [ST 32] The number of commands received in queue 9 */
+#define XSDM_REG_NUM_OF_Q9_CMD                                  0x166268
+/* [RW 13] The start address in the internal RAM for queue counters */
+#define XSDM_REG_Q_COUNTER_START_ADDR                           0x166010
+/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */
+#define XSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY                       0x166548
+/* [R 1] parser fifo empty in sdm_sync block */
+#define XSDM_REG_SYNC_PARSER_EMPTY                              0x166550
+/* [R 1] parser serial fifo empty in sdm_sync block */
+#define XSDM_REG_SYNC_SYNC_EMPTY                                0x166558
+/* [RW 32] Tick for timer counter. Applicable only when
+   ~xsdm_registers_timer_tick_enable.timer_tick_enable =1 */
+#define XSDM_REG_TIMER_TICK                                     0x166000
+/* [RW 32] Interrupt mask register #0 read/write */
+#define XSDM_REG_XSDM_INT_MASK_0                                0x16629c
+#define XSDM_REG_XSDM_INT_MASK_1                                0x1662ac
+/* [RW 11] Parity mask register #0 read/write */
+#define XSDM_REG_XSDM_PRTY_MASK                                 0x1662bc
+/* [RW 5] The number of time_slots in the arbitration cycle */
+#define XSEM_REG_ARB_CYCLE_SIZE                                 0x280034
+/* [RW 3] The source that is associated with arbitration element 0. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2 */
+#define XSEM_REG_ARB_ELEMENT0                                   0x280020
+/* [RW 3] The source that is associated with arbitration element 1. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~xsem_registers_arb_element0.arb_element0 */
+#define XSEM_REG_ARB_ELEMENT1                                   0x280024
+/* [RW 3] The source that is associated with arbitration element 2. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~xsem_registers_arb_element0.arb_element0
+   and ~xsem_registers_arb_element1.arb_element1 */
+#define XSEM_REG_ARB_ELEMENT2                                   0x280028
+/* [RW 3] The source that is associated with arbitration element 3. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.Could
+   not be equal to register ~xsem_registers_arb_element0.arb_element0 and
+   ~xsem_registers_arb_element1.arb_element1 and
+   ~xsem_registers_arb_element2.arb_element2 */
+#define XSEM_REG_ARB_ELEMENT3                                   0x28002c
+/* [RW 3] The source that is associated with arbitration element 4. Source
+   decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3-
+   sleeping thread with priority 1; 4- sleeping thread with priority 2.
+   Could not be equal to register ~xsem_registers_arb_element0.arb_element0
+   and ~xsem_registers_arb_element1.arb_element1 and
+   ~xsem_registers_arb_element2.arb_element2 and
+   ~xsem_registers_arb_element3.arb_element3 */
+#define XSEM_REG_ARB_ELEMENT4                                   0x280030
+#define XSEM_REG_ENABLE_IN                                      0x2800a4
+#define XSEM_REG_ENABLE_OUT                                     0x2800a8
+/* [RW 32] This address space contains all registers and memories that are
+   placed in SEM_FAST block. The SEM_FAST registers are described in
+   appendix B. In order to access the SEM_FAST registers the base address
+   XSEM_REGISTERS_FAST_MEMORY (Offset: 0x2a0000) should be added to each
+   SEM_FAST register offset. */
+#define XSEM_REG_FAST_MEMORY                                    0x2a0000
+/* [RW 1] Disables input messages from FIC0 May be updated during run_time
+   by the microcode */
+#define XSEM_REG_FIC0_DISABLE                                   0x280224
+/* [RW 1] Disables input messages from FIC1 May be updated during run_time
+   by the microcode */
+#define XSEM_REG_FIC1_DISABLE                                   0x280234
+/* [RW 15] Interrupt table Read and write access to it is not possible in
+   the middle of the work */
+#define XSEM_REG_INT_TABLE                                      0x280400
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC0 */
+#define XSEM_REG_MSG_NUM_FIC0                                   0x280000
+/* [ST 24] Statistics register. The number of messages that entered through
+   FIC1 */
+#define XSEM_REG_MSG_NUM_FIC1                                   0x280004
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC0 */
+#define XSEM_REG_MSG_NUM_FOC0                                   0x280008
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC1 */
+#define XSEM_REG_MSG_NUM_FOC1                                   0x28000c
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC2 */
+#define XSEM_REG_MSG_NUM_FOC2                                   0x280010
+/* [ST 24] Statistics register. The number of messages that were sent to
+   FOC3 */
+#define XSEM_REG_MSG_NUM_FOC3                                   0x280014
+/* [RW 1] Disables input messages from the passive buffer May be updated
+   during run_time by the microcode */
+#define XSEM_REG_PAS_DISABLE                                    0x28024c
+/* [WB 128] Debug only. Passive buffer memory */
+#define XSEM_REG_PASSIVE_BUFFER                                 0x282000
+/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */
+#define XSEM_REG_PRAM                                           0x2c0000
+/* [R 16] Valid sleeping threads indication have bit per thread */
+#define XSEM_REG_SLEEP_THREADS_VALID                            0x28026c
+/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */
+#define XSEM_REG_SLOW_EXT_STORE_EMPTY                           0x2802a0
+/* [RW 16] List of free threads . There is a bit per thread. */
+#define XSEM_REG_THREADS_LIST                                   0x2802e4
+/* [RW 3] The arbitration scheme of time_slot 0 */
+#define XSEM_REG_TS_0_AS                                        0x280038
+/* [RW 3] The arbitration scheme of time_slot 10 */
+#define XSEM_REG_TS_10_AS                                       0x280060
+/* [RW 3] The arbitration scheme of time_slot 11 */
+#define XSEM_REG_TS_11_AS                                       0x280064
+/* [RW 3] The arbitration scheme of time_slot 12 */
+#define XSEM_REG_TS_12_AS                                       0x280068
+/* [RW 3] The arbitration scheme of time_slot 13 */
+#define XSEM_REG_TS_13_AS                                       0x28006c
+/* [RW 3] The arbitration scheme of time_slot 14 */
+#define XSEM_REG_TS_14_AS                                       0x280070
+/* [RW 3] The arbitration scheme of time_slot 15 */
+#define XSEM_REG_TS_15_AS                                       0x280074
+/* [RW 3] The arbitration scheme of time_slot 16 */
+#define XSEM_REG_TS_16_AS                                       0x280078
+/* [RW 3] The arbitration scheme of time_slot 17 */
+#define XSEM_REG_TS_17_AS                                       0x28007c
+/* [RW 3] The arbitration scheme of time_slot 18 */
+#define XSEM_REG_TS_18_AS                                       0x280080
+/* [RW 3] The arbitration scheme of time_slot 1 */
+#define XSEM_REG_TS_1_AS                                        0x28003c
+/* [RW 3] The arbitration scheme of time_slot 2 */
+#define XSEM_REG_TS_2_AS                                        0x280040
+/* [RW 3] The arbitration scheme of time_slot 3 */
+#define XSEM_REG_TS_3_AS                                        0x280044
+/* [RW 3] The arbitration scheme of time_slot 4 */
+#define XSEM_REG_TS_4_AS                                        0x280048
+/* [RW 3] The arbitration scheme of time_slot 5 */
+#define XSEM_REG_TS_5_AS                                        0x28004c
+/* [RW 3] The arbitration scheme of time_slot 6 */
+#define XSEM_REG_TS_6_AS                                        0x280050
+/* [RW 3] The arbitration scheme of time_slot 7 */
+#define XSEM_REG_TS_7_AS                                        0x280054
+/* [RW 3] The arbitration scheme of time_slot 8 */
+#define XSEM_REG_TS_8_AS                                        0x280058
+/* [RW 3] The arbitration scheme of time_slot 9 */
+#define XSEM_REG_TS_9_AS                                        0x28005c
+/* [RW 32] Interrupt mask register #0 read/write */
+#define XSEM_REG_XSEM_INT_MASK_0                                0x280110
+#define XSEM_REG_XSEM_INT_MASK_1                                0x280120
+/* [RW 32] Parity mask register #0 read/write */
+#define XSEM_REG_XSEM_PRTY_MASK_0                               0x280130
+#define XSEM_REG_XSEM_PRTY_MASK_1                               0x280140
+#define MCPR_NVM_ACCESS_ENABLE_EN                               (1L<<0)
+#define MCPR_NVM_ACCESS_ENABLE_WR_EN                            (1L<<1)
+#define MCPR_NVM_ADDR_NVM_ADDR_VALUE                            (0xffffffL<<0)
+#define MCPR_NVM_CFG4_FLASH_SIZE                                (0x7L<<0)
+#define MCPR_NVM_COMMAND_DOIT                                   (1L<<4)
+#define MCPR_NVM_COMMAND_DONE                                   (1L<<3)
+#define MCPR_NVM_COMMAND_FIRST                                  (1L<<7)
+#define MCPR_NVM_COMMAND_LAST                                   (1L<<8)
+#define MCPR_NVM_COMMAND_WR                                     (1L<<5)
+#define MCPR_NVM_COMMAND_WREN                                   (1L<<16)
+#define MCPR_NVM_COMMAND_WREN_BITSHIFT                          16
+#define MCPR_NVM_COMMAND_WRDI                                   (1L<<17)
+#define MCPR_NVM_COMMAND_WRDI_BITSHIFT                          17
+#define MCPR_NVM_SW_ARB_ARB_ARB1                                (1L<<9)
+#define MCPR_NVM_SW_ARB_ARB_REQ_CLR1                            (1L<<5)
+#define MCPR_NVM_SW_ARB_ARB_REQ_SET1                            (1L<<1)
+#define BIGMAC_REGISTER_BMAC_CONTROL                            (0x00<<3)
+#define BIGMAC_REGISTER_BMAC_XGXS_CONTROL                       (0x01<<3)
+#define BIGMAC_REGISTER_CNT_MAX_SIZE                            (0x05<<3)
+#define BIGMAC_REGISTER_RX_CONTROL                              (0x21<<3)
+#define BIGMAC_REGISTER_RX_LLFC_MSG_FLDS                        (0x46<<3)
+#define BIGMAC_REGISTER_RX_MAX_SIZE                             (0x23<<3)
+#define BIGMAC_REGISTER_RX_STAT_GR64                            (0x26<<3)
+#define BIGMAC_REGISTER_RX_STAT_GRIPJ                           (0x42<<3)
+#define BIGMAC_REGISTER_TX_CONTROL                              (0x07<<3)
+#define BIGMAC_REGISTER_TX_MAX_SIZE                             (0x09<<3)
+#define BIGMAC_REGISTER_TX_PAUSE_THRESHOLD                      (0x0A<<3)
+#define BIGMAC_REGISTER_TX_SOURCE_ADDR                          (0x08<<3)
+#define BIGMAC_REGISTER_TX_STAT_GTBYT                           (0x20<<3)
+#define BIGMAC_REGISTER_TX_STAT_GTPKT                           (0x0C<<3)
+#define EMAC_MDIO_COMM_COMMAND_ADDRESS                          (0L<<26)
+#define EMAC_MDIO_COMM_COMMAND_READ_22                          (2L<<26)
+#define EMAC_MDIO_COMM_COMMAND_READ_45                          (3L<<26)
+#define EMAC_MDIO_COMM_COMMAND_WRITE_22                         (1L<<26)
+#define EMAC_MDIO_COMM_COMMAND_WRITE_45                         (1L<<26)
+#define EMAC_MDIO_COMM_DATA                                     (0xffffL<<0)
+#define EMAC_MDIO_COMM_START_BUSY                               (1L<<29)
+#define EMAC_MDIO_MODE_AUTO_POLL                                (1L<<4)
+#define EMAC_MDIO_MODE_CLAUSE_45                                (1L<<31)
+#define EMAC_MODE_25G_MODE                                      (1L<<5)
+#define EMAC_MODE_ACPI_RCVD                                     (1L<<20)
+#define EMAC_MODE_HALF_DUPLEX                                   (1L<<1)
+#define EMAC_MODE_MPKT                                          (1L<<18)
+#define EMAC_MODE_MPKT_RCVD                                     (1L<<19)
+#define EMAC_MODE_PORT_GMII                                     (2L<<2)
+#define EMAC_MODE_PORT_MII                                      (1L<<2)
+#define EMAC_MODE_PORT_MII_10M                                  (3L<<2)
+#define EMAC_MODE_RESET                                         (1L<<0)
+#define EMAC_REG_EMAC_MAC_MATCH                                 0x10
+#define EMAC_REG_EMAC_MDIO_COMM                                 0xac
+#define EMAC_REG_EMAC_MDIO_MODE                                 0xb4
+#define EMAC_REG_EMAC_MODE                                      0x0
+#define EMAC_REG_EMAC_RX_MODE                                   0xc8
+#define EMAC_REG_EMAC_RX_MTU_SIZE                               0x9c
+#define EMAC_REG_EMAC_RX_STAT_AC                                0x180
+#define EMAC_REG_EMAC_RX_STAT_AC_28                             0x1f4
+#define EMAC_REG_EMAC_RX_STAT_AC_COUNT                          23
+#define EMAC_REG_EMAC_TX_MODE                                   0xbc
+#define EMAC_REG_EMAC_TX_STAT_AC                                0x280
+#define EMAC_REG_EMAC_TX_STAT_AC_COUNT                          22
+#define EMAC_RX_MODE_FLOW_EN                                    (1L<<2)
+#define EMAC_RX_MODE_KEEP_VLAN_TAG                              (1L<<10)
+#define EMAC_RX_MODE_PROMISCUOUS                                (1L<<8)
+#define EMAC_RX_MTU_SIZE_JUMBO_ENA                              (1L<<31)
+#define EMAC_TX_MODE_EXT_PAUSE_EN                               (1L<<3)
+#define EMAC_TX_MODE_RESET                                      (1L<<0)
+#define MISC_REGISTERS_RESET_REG_1_CLEAR                        0x588
+#define MISC_REGISTERS_RESET_REG_1_SET                          0x584
+#define MISC_REGISTERS_RESET_REG_2_CLEAR                        0x598
+#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0                    (0x1<<0)
+#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE          (0x1<<14)
+#define MISC_REGISTERS_RESET_REG_2_SET                          0x594
+#define MISC_REGISTERS_RESET_REG_3_CLEAR                        0x5a8
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ    (0x1<<1)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN  (0x1<<2)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD (0x1<<3)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW  (0x1<<0)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ      (0x1<<5)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN    (0x1<<6)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD  (0x1<<7)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW   (0x1<<4)
+#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8)
+#define MISC_REGISTERS_RESET_REG_3_SET                          0x5a4
+#define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR                (1<<18)
+#define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT                (1<<31)
+#define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT                (1<<9)
+#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR                (1<<8)
+#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT                (1<<7)
+#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR                (1<<6)
+#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT               (1<<29)
+#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR               (1<<28)
+#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT              (1<<1)
+#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR              (1<<0)
+#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR              (1<<18)
+#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT               (1<<11)
+#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT          (1<<13)
+#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR          (1<<12)
+#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR                (1<<12)
+#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT               (1<<15)
+#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR               (1<<14)
+#define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR             (1<<20)
+#define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR           (1<<0)
+#define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT                (1<<31)
+#define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT                (1<<3)
+#define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR                (1<<2)
+#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT   (1<<5)
+#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR   (1<<4)
+#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT                 (1<<3)
+#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR                 (1<<2)
+#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR           (1<<22)
+#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT                (1<<27)
+#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT             (1<<5)
+#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT               (1<<25)
+#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR               (1<<24)
+#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT              (1<<29)
+#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR              (1<<28)
+#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT                (1<<23)
+#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT                (1<<27)
+#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR                (1<<26)
+#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT               (1<<21)
+#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR               (1<<20)
+#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT              (1<<25)
+#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR              (1<<24)
+#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR       (1<<16)
+#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT                (1<<9)
+#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT               (1<<7)
+#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR               (1<<6)
+#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT              (1<<11)
+#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR              (1<<10)
+#define RESERVED_GENERAL_ATTENTION_BIT_0       0
+
+#define EVEREST_GEN_ATTN_IN_USE_MASK           0x3e0
+#define EVEREST_LATCHED_ATTN_IN_USE_MASK       0xffe00000
+
+#define RESERVED_GENERAL_ATTENTION_BIT_6       6
+#define RESERVED_GENERAL_ATTENTION_BIT_7       7
+#define RESERVED_GENERAL_ATTENTION_BIT_8       8
+#define RESERVED_GENERAL_ATTENTION_BIT_9       9
+#define RESERVED_GENERAL_ATTENTION_BIT_10      10
+#define RESERVED_GENERAL_ATTENTION_BIT_11      11
+#define RESERVED_GENERAL_ATTENTION_BIT_12      12
+#define RESERVED_GENERAL_ATTENTION_BIT_13      13
+#define RESERVED_GENERAL_ATTENTION_BIT_14      14
+#define RESERVED_GENERAL_ATTENTION_BIT_15      15
+#define RESERVED_GENERAL_ATTENTION_BIT_16      16
+#define RESERVED_GENERAL_ATTENTION_BIT_17      17
+#define RESERVED_GENERAL_ATTENTION_BIT_18      18
+#define RESERVED_GENERAL_ATTENTION_BIT_19      19
+#define RESERVED_GENERAL_ATTENTION_BIT_20      20
+#define RESERVED_GENERAL_ATTENTION_BIT_21      21
+
+/* storm asserts attention bits */
+#define TSTORM_FATAL_ASSERT_ATTENTION_BIT     RESERVED_GENERAL_ATTENTION_BIT_7
+#define USTORM_FATAL_ASSERT_ATTENTION_BIT     RESERVED_GENERAL_ATTENTION_BIT_8
+#define CSTORM_FATAL_ASSERT_ATTENTION_BIT     RESERVED_GENERAL_ATTENTION_BIT_9
+#define XSTORM_FATAL_ASSERT_ATTENTION_BIT     RESERVED_GENERAL_ATTENTION_BIT_10
+
+/* mcp error attention bit */
+#define MCP_FATAL_ASSERT_ATTENTION_BIT       RESERVED_GENERAL_ATTENTION_BIT_11
+
+#define LATCHED_ATTN_RBCR                      23
+#define LATCHED_ATTN_RBCT                      24
+#define LATCHED_ATTN_RBCN                      25
+#define LATCHED_ATTN_RBCU                      26
+#define LATCHED_ATTN_RBCP                      27
+#define LATCHED_ATTN_TIMEOUT_GRC               28
+#define LATCHED_ATTN_RSVD_GRC                  29
+#define LATCHED_ATTN_ROM_PARITY_MCP            30
+#define LATCHED_ATTN_UM_RX_PARITY_MCP          31
+#define LATCHED_ATTN_UM_TX_PARITY_MCP          32
+#define LATCHED_ATTN_SCPAD_PARITY_MCP          33
+
+#define GENERAL_ATTEN_WORD(atten_name)        ((94 + atten_name) / 32)
+#define GENERAL_ATTEN_OFFSET(atten_name)       (1 << ((94 + atten_name) % 32))
+/*
+ * This file defines GRC base address for every block.
+ * This file is included by chipsim, asm microcode and cpp microcode.
+ * These values are used in Design.xml on regBase attribute
+ * Use the base with the generated offsets of specific registers.
+ */
+
+#define GRCBASE_PXPCS          0x000000
+#define GRCBASE_PCICONFIG      0x002000
+#define GRCBASE_PCIREG         0x002400
+#define GRCBASE_EMAC0          0x008000
+#define GRCBASE_EMAC1          0x008400
+#define GRCBASE_DBU            0x008800
+#define GRCBASE_MISC           0x00A000
+#define GRCBASE_DBG            0x00C000
+#define GRCBASE_NIG            0x010000
+#define GRCBASE_XCM            0x020000
+#define GRCBASE_PRS            0x040000
+#define GRCBASE_SRCH           0x040400
+#define GRCBASE_TSDM           0x042000
+#define GRCBASE_TCM            0x050000
+#define GRCBASE_BRB1           0x060000
+#define GRCBASE_MCP            0x080000
+#define GRCBASE_UPB            0x0C1000
+#define GRCBASE_CSDM           0x0C2000
+#define GRCBASE_USDM           0x0C4000
+#define GRCBASE_CCM            0x0D0000
+#define GRCBASE_UCM            0x0E0000
+#define GRCBASE_CDU            0x101000
+#define GRCBASE_DMAE           0x102000
+#define GRCBASE_PXP            0x103000
+#define GRCBASE_CFC            0x104000
+#define GRCBASE_HC             0x108000
+#define GRCBASE_PXP2           0x120000
+#define GRCBASE_PBF            0x140000
+#define GRCBASE_XPB            0x161000
+#define GRCBASE_TIMERS         0x164000
+#define GRCBASE_XSDM           0x166000
+#define GRCBASE_QM             0x168000
+#define GRCBASE_DQ             0x170000
+#define GRCBASE_TSEM           0x180000
+#define GRCBASE_CSEM           0x200000
+#define GRCBASE_XSEM           0x280000
+#define GRCBASE_USEM           0x300000
+#define GRCBASE_MISC_AEU       GRCBASE_MISC
+
+
+/*the offset of the configuration space in the pci core register*/
+#define PCICFG_OFFSET                                  0x2000
+#define PCICFG_VENDOR_ID_OFFSET                        0x00
+#define PCICFG_DEVICE_ID_OFFSET                        0x02
+#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET              0x2c
+#define PCICFG_SUBSYSTEM_ID_OFFSET                     0x2e
+#define PCICFG_INT_LINE                                0x3c
+#define PCICFG_INT_PIN                                 0x3d
+#define PCICFG_CACHE_LINE_SIZE                         0x0c
+#define PCICFG_LATENCY_TIMER                           0x0d
+#define PCICFG_REVESION_ID                             0x08
+#define PCICFG_BAR_1_LOW                               0x10
+#define PCICFG_BAR_1_HIGH                              0x14
+#define PCICFG_BAR_2_LOW                               0x18
+#define PCICFG_BAR_2_HIGH                              0x1c
+#define PCICFG_GRC_ADDRESS                             0x78
+#define PCICFG_GRC_DATA                                0x80
+#define PCICFG_DEVICE_CONTROL                          0xb4
+#define PCICFG_LINK_CONTROL                            0xbc
+
+#define BAR_USTRORM_INTMEM                             0x400000
+#define BAR_CSTRORM_INTMEM                             0x410000
+#define BAR_XSTRORM_INTMEM                             0x420000
+#define BAR_TSTRORM_INTMEM                             0x430000
+
+#define BAR_IGU_INTMEM                                 0x440000
+
+#define BAR_DOORBELL_OFFSET                            0x800000
+
+#define BAR_ME_REGISTER                                0x450000
+
+
+#define GRC_CONFIG_2_SIZE_REG              0x408 /* config_2 offset */
+#define PCI_CONFIG_2_BAR1_SIZE                     (0xfL<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_DISABLED        (0L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_64K             (1L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_128K            (2L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_256K            (3L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_512K            (4L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_1M              (5L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_2M              (6L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_4M              (7L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_8M              (8L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_16M             (9L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_32M             (10L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_64M             (11L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_128M            (12L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_256M            (13L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_512M            (14L<<0)
+#define PCI_CONFIG_2_BAR1_SIZE_1G              (15L<<0)
+#define PCI_CONFIG_2_BAR1_64ENA                    (1L<<4)
+#define PCI_CONFIG_2_EXP_ROM_RETRY                 (1L<<5)
+#define PCI_CONFIG_2_CFG_CYCLE_RETRY               (1L<<6)
+#define PCI_CONFIG_2_FIRST_CFG_DONE                (1L<<7)
+#define PCI_CONFIG_2_EXP_ROM_SIZE                  (0xffL<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED     (0L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_2K           (1L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_4K           (2L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_8K           (3L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_16K          (4L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_32K          (5L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_64K          (6L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_128K         (7L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_256K         (8L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_512K         (9L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_1M           (10L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_2M           (11L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_4M           (12L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_8M           (13L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_16M          (14L<<8)
+#define PCI_CONFIG_2_EXP_ROM_SIZE_32M          (15L<<8)
+#define PCI_CONFIG_2_BAR_PREFETCH                  (1L<<16)
+#define PCI_CONFIG_2_RESERVED0                     (0x7fffL<<17)
+
+/* config_3 offset */
+#define GRC_CONFIG_3_SIZE_REG                          (0x40c)
+#define PCI_CONFIG_3_STICKY_BYTE                   (0xffL<<0)
+#define PCI_CONFIG_3_FORCE_PME                     (1L<<24)
+#define PCI_CONFIG_3_PME_STATUS                    (1L<<25)
+#define PCI_CONFIG_3_PME_ENABLE                    (1L<<26)
+#define PCI_CONFIG_3_PM_STATE                      (0x3L<<27)
+#define PCI_CONFIG_3_VAUX_PRESET                   (1L<<30)
+#define PCI_CONFIG_3_PCI_POWER                     (1L<<31)
+
+/* config_2 offset */
+#define GRC_CONFIG_2_SIZE_REG              0x408
+
+#define GRC_BAR2_CONFIG                                0x4e0
+#define PCI_CONFIG_2_BAR2_SIZE                     (0xfL<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_DISABLED            (0L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_64K                 (1L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_128K                (2L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_256K                (3L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_512K                (4L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_1M                  (5L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_2M                  (6L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_4M                  (7L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_8M                  (8L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_16M                 (9L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_32M                 (10L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_64M                 (11L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_128M                (12L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_256M                (13L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_512M                (14L<<0)
+#define PCI_CONFIG_2_BAR2_SIZE_1G                  (15L<<0)
+#define PCI_CONFIG_2_BAR2_64ENA                    (1L<<4)
+
+#define PCI_PM_DATA_A                                  (0x410)
+#define PCI_PM_DATA_B                                  (0x414)
+#define PCI_ID_VAL1                                    (0x434)
+#define PCI_ID_VAL2                                    (0x438)
+
+#define MDIO_REG_BANK_CL73_IEEEB0                      0x0
+#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL               0x0
+#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN    0x0200
+#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN         0x1000
+#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST      0x8000
+
+#define MDIO_REG_BANK_CL73_IEEEB1                      0x10
+#define MDIO_CL73_IEEEB1_AN_ADV2                       0x01
+#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M            0x0000
+#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX         0x0020
+#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4          0x0040
+#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR           0x0080
+
+#define MDIO_REG_BANK_RX0                              0x80b0
+#define MDIO_RX0_RX_EQ_BOOST                           0x1c
+#define MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK       0x7
+#define MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL               0x10
+
+#define MDIO_REG_BANK_RX1                              0x80c0
+#define MDIO_RX1_RX_EQ_BOOST                           0x1c
+#define MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK       0x7
+#define MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL               0x10
+
+#define MDIO_REG_BANK_RX2                              0x80d0
+#define MDIO_RX2_RX_EQ_BOOST                           0x1c
+#define MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK       0x7
+#define MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL               0x10
+
+#define MDIO_REG_BANK_RX3                              0x80e0
+#define MDIO_RX3_RX_EQ_BOOST                           0x1c
+#define MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK       0x7
+#define MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL               0x10
+
+#define MDIO_REG_BANK_RX_ALL                           0x80f0
+#define MDIO_RX_ALL_RX_EQ_BOOST                        0x1c
+#define MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK    0x7
+#define MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL            0x10
+
+#define MDIO_REG_BANK_TX0                              0x8060
+#define MDIO_TX0_TX_DRIVER                             0x17
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK            0xf000
+#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT           12
+#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK                0x0f00
+#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT               8
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK             0x00f0
+#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT            4
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK               0x000e
+#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT              1
+#define MDIO_TX0_TX_DRIVER_ICBUF1T                     1
+
+#define MDIO_REG_BANK_XGXS_BLOCK0                      0x8000
+#define MDIO_BLOCK0_XGXS_CONTROL                       0x10
+
+#define MDIO_REG_BANK_XGXS_BLOCK1                      0x8010
+#define MDIO_BLOCK1_LANE_CTRL0                         0x15
+#define MDIO_BLOCK1_LANE_CTRL1                         0x16
+#define MDIO_BLOCK1_LANE_CTRL2                         0x17
+#define MDIO_BLOCK1_LANE_PRBS                          0x19
+
+#define MDIO_REG_BANK_XGXS_BLOCK2                      0x8100
+#define MDIO_XGXS_BLOCK2_RX_LN_SWAP                    0x10
+#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE             0x8000
+#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE       0x4000
+#define MDIO_XGXS_BLOCK2_TX_LN_SWAP                    0x11
+#define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE             0x8000
+#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE                0x15
+
+#define MDIO_REG_BANK_GP_STATUS                        0x8120
+#define MDIO_GP_STATUS_TOP_AN_STATUS1                      0x1B
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE 0x0001
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE 0x0002
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS          0x0004
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS        0x0008
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE 0x0010
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE   0x0020
+
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 0x0040
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE 0x0080
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK     0x3f00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M     0x0000
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M     0x0100
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G      0x0200
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G     0x0300
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G      0x0400
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G      0x0500
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG  0x0600
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4  0x0700
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG  0x0800
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G    0x0900
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G     0x0A00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G     0x0B00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G     0x0C00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX    0x0D00
+#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4  0x0E00
+
+
+#define MDIO_REG_BANK_10G_PARALLEL_DETECT              0x8130
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL       0x11
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN 0x1
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK          0x13
+#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT      (0xb71<<1)
+
+#define MDIO_REG_BANK_SERDES_DIGITAL                   0x8300
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1           0x10
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF    0x0002
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN    0x0004
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT 0x0008
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET   0x0010
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE 0x0020
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2           0x11
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001
+#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1            0x14
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX     0x0004
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G 0x0018
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G   0x0010
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M 0x0008
+#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M  0x0000
+#define MDIO_SERDES_DIGITAL_MISC1                      0x18
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK      0xE000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M       0x0000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M      0x2000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M      0x4000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M   0x6000
+#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M    0x8000
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL      0x0010
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK     0x000f
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G     0x0000
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G       0x0001
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G       0x0002
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG  0x0003
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4  0x0004
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G      0x0005
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G    0x0006
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G      0x0007
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G      0x0008
+#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G      0x0009
+
+#define MDIO_REG_BANK_OVER_1G                          0x8320
+#define MDIO_OVER_1G_DIGCTL_3_4                        0x14
+#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK             0xffe0
+#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT            5
+#define MDIO_OVER_1G_UP1                               0x19
+#define MDIO_OVER_1G_UP1_2_5G                          0x0001
+#define MDIO_OVER_1G_UP1_5G                            0x0002
+#define MDIO_OVER_1G_UP1_6G                            0x0004
+#define MDIO_OVER_1G_UP1_10G                           0x0010
+#define MDIO_OVER_1G_UP1_10GH                          0x0008
+#define MDIO_OVER_1G_UP1_12G                           0x0020
+#define MDIO_OVER_1G_UP1_12_5G                         0x0040
+#define MDIO_OVER_1G_UP1_13G                           0x0080
+#define MDIO_OVER_1G_UP1_15G                           0x0100
+#define MDIO_OVER_1G_UP1_16G                           0x0200
+#define MDIO_OVER_1G_UP2                               0x1A
+#define MDIO_OVER_1G_UP2_IPREDRIVER_MASK               0x0007
+#define MDIO_OVER_1G_UP2_IDRIVER_MASK                  0x0038
+#define MDIO_OVER_1G_UP2_PREEMPHASIS_MASK              0x03C0
+#define MDIO_OVER_1G_UP3                               0x1B
+#define MDIO_OVER_1G_UP3_HIGIG2                        0x0001
+#define MDIO_OVER_1G_LP_UP1                            0x1C
+#define MDIO_OVER_1G_LP_UP2                            0x1D
+#define MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK        0x03ff
+#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK           0x0780
+#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT          7
+#define MDIO_OVER_1G_LP_UP3                            0x1E
+
+#define MDIO_REG_BANK_BAM_NEXT_PAGE                    0x8350
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL          0x10
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE 0x0001
+#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN 0x0002
+
+#define MDIO_REG_BANK_CL73_USERB0                      0x8370
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1                0x12
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN                 0x8000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN    0x4000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN     0x2000
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL3                0x14
+#define MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR 0x0001
+
+#define MDIO_REG_BANK_AER_BLOCK                        0xFFD0
+#define MDIO_AER_BLOCK_AER_REG                         0x1E
+
+#define MDIO_REG_BANK_COMBO_IEEE0                      0xFFE0
+#define MDIO_COMBO_IEEE0_MII_CONTROL                   0x10
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK  0x2040
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10    0x0000
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100   0x2000
+#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000  0x0040
+#define MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX        0x0100
+#define MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN         0x0200
+#define MDIO_COMBO_IEEO_MII_CONTROL_AN_EN              0x1000
+#define MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK           0x4000
+#define MDIO_COMBO_IEEO_MII_CONTROL_RESET              0x8000
+#define MDIO_COMBO_IEEE0_MII_STATUS                    0x11
+#define MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS          0x0004
+#define MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE   0x0020
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV                  0x14
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX      0x0020
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX      0x0040
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK       0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE       0x0000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC  0x0080
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC 0x0100
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH       0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE        0x8000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1 0x15
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE    0x8000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK         0x4000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK   0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE\
+       0x0000
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH\
+       0x0180
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP 0x0040
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP 0x0020
+#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE   0x0001
+
+
+#define EXT_PHY_OPT_PMA_PMD_DEVAD                      0x1
+#define EXT_PHY_OPT_WIS_DEVAD                          0x2
+#define EXT_PHY_OPT_PCS_DEVAD                          0x3
+#define EXT_PHY_OPT_PHY_XS_DEVAD                       0x4
+#define EXT_PHY_OPT_CNTL                               0x0
+#define EXT_PHY_OPT_PMD_RX_SD                          0xa
+#define EXT_PHY_OPT_PMD_MISC_CNTL                      0xca0a
+#define EXT_PHY_OPT_PHY_IDENTIFIER                     0xc800
+#define EXT_PHY_OPT_PMD_DIGITAL_CNT                    0xc808
+#define EXT_PHY_OPT_PMD_DIGITAL_SATUS                  0xc809
+#define EXT_PHY_OPT_CMU_PLL_BYPASS                     0xca09
+#define EXT_PHY_OPT_LASI_CNTL                          0x9002
+#define EXT_PHY_OPT_RX_ALARM                           0x9003
+#define EXT_PHY_OPT_LASI_STATUS                        0x9005
+#define EXT_PHY_OPT_PCS_STATUS                         0x0020
+#define EXT_PHY_OPT_XGXS_LANE_STATUS                   0x0018
+
+#define EXT_PHY_KR_PMA_PMD_DEVAD                       0x1
+#define EXT_PHY_KR_PCS_DEVAD                           0x3
+#define EXT_PHY_KR_AUTO_NEG_DEVAD                      0x7
+#define EXT_PHY_KR_CTRL                                0x0000
+#define EXT_PHY_KR_CTRL2                               0x0007
+#define EXT_PHY_KR_PCS_STATUS                          0x0020
+#define EXT_PHY_KR_PMD_CTRL                            0x0096
+#define EXT_PHY_KR_LASI_CNTL                           0x9002
+#define EXT_PHY_KR_LASI_STATUS                         0x9005
+#define EXT_PHY_KR_MISC_CTRL1                          0xca85
+#define EXT_PHY_KR_GEN_CTRL                            0xca10
+#define EXT_PHY_KR_ROM_CODE                            0xca19
+
index 49a198206e3de901a74f34fc40694bb056ad922c..2039f7838f2df713a0afe9a4bbe1aecc8955e617 100644 (file)
@@ -2517,7 +2517,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                fl.fl4_dst = targets[i];
                fl.fl4_tos = RTO_ONLINK;
 
-               rv = ip_route_output_key(&rt, &fl);
+               rv = ip_route_output_key(&init_net, &rt, &fl);
                if (rv) {
                        if (net_ratelimit()) {
                                printk(KERN_WARNING DRV_NAME
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
new file mode 100644 (file)
index 0000000..57def0d
--- /dev/null
@@ -0,0 +1,25 @@
+menu "CAN Device Drivers"
+       depends on CAN
+
+config CAN_VCAN
+       tristate "Virtual Local CAN Interface (vcan)"
+       depends on CAN
+       default N
+       ---help---
+         Similar to the network loopback devices, vcan offers a
+         virtual local CAN interface.
+
+         This driver can also be built as a module.  If so, the module
+         will be called vcan.
+
+config CAN_DEBUG_DEVICES
+       bool "CAN devices debugging messages"
+       depends on CAN
+       default N
+       ---help---
+         Say Y here if you want the CAN device drivers to produce a bunch of
+         debug messages to the system log.  Select this if you are having
+         a problem with CAN support and want to see more of what is going
+         on.
+
+endmenu
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
new file mode 100644 (file)
index 0000000..c4bead7
--- /dev/null
@@ -0,0 +1,5 @@
+#
+#  Makefile for the Linux Controller Area Network drivers.
+#
+
+obj-$(CONFIG_CAN_VCAN)         += vcan.o
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
new file mode 100644 (file)
index 0000000..103f0f1
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * vcan.c - Virtual CAN interface
+ *
+ * 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/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/can.h>
+#include <net/rtnetlink.h>
+
+static __initdata const char banner[] =
+       KERN_INFO "vcan: Virtual CAN interface driver\n";
+
+MODULE_DESCRIPTION("virtual CAN interface");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
+
+
+/*
+ * CAN test feature:
+ * Enable the echo on driver level for testing the CAN core echo modes.
+ * See Documentation/networking/can.txt for details.
+ */
+
+static int echo; /* echo testing. Default: 0 (Off) */
+module_param(echo, bool, S_IRUGO);
+MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
+
+
+static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct net_device_stats *stats = &dev->stats;
+
+       stats->rx_packets++;
+       stats->rx_bytes += skb->len;
+
+       skb->protocol  = htons(ETH_P_CAN);
+       skb->pkt_type  = PACKET_BROADCAST;
+       skb->dev       = dev;
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+       netif_rx(skb);
+}
+
+static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
+{
+       struct net_device_stats *stats = &dev->stats;
+       int loop;
+
+       stats->tx_packets++;
+       stats->tx_bytes += skb->len;
+
+       /* set flag whether this packet has to be looped back */
+       loop = skb->pkt_type == PACKET_LOOPBACK;
+
+       if (!echo) {
+               /* no echo handling available inside this driver */
+
+               if (loop) {
+                       /*
+                        * only count the packets here, because the
+                        * CAN core already did the echo for us
+                        */
+                       stats->rx_packets++;
+                       stats->rx_bytes += skb->len;
+               }
+               kfree_skb(skb);
+               return NETDEV_TX_OK;
+       }
+
+       /* perform standard echo handling for CAN network interfaces */
+
+       if (loop) {
+               struct sock *srcsk = skb->sk;
+
+               skb = skb_share_check(skb, GFP_ATOMIC);
+               if (!skb)
+                       return NETDEV_TX_OK;
+
+               /* receive with packet counting */
+               skb->sk = srcsk;
+               vcan_rx(skb, dev);
+       } else {
+               /* no looped packets => no counting */
+               kfree_skb(skb);
+       }
+       return NETDEV_TX_OK;
+}
+
+static void vcan_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      = 0;
+       dev->flags             = IFF_NOARP;
+
+       /* set flags according to driver capabilities */
+       if (echo)
+               dev->flags |= IFF_ECHO;
+
+       dev->hard_start_xmit   = vcan_tx;
+       dev->destructor        = free_netdev;
+}
+
+static struct rtnl_link_ops vcan_link_ops __read_mostly = {
+       .kind           = "vcan",
+       .setup          = vcan_setup,
+};
+
+static __init int vcan_init_module(void)
+{
+       printk(banner);
+
+       if (echo)
+               printk(KERN_INFO "vcan: enabled echo on driver level.\n");
+
+       return rtnl_link_register(&vcan_link_ops);
+}
+
+static __exit void vcan_cleanup_module(void)
+{
+       rtnl_link_unregister(&vcan_link_ops);
+}
+
+module_init(vcan_init_module);
+module_exit(vcan_cleanup_module);
index d66915d82b24a7795ce040b3a785c3f6532aac14..14299f8063af16341011a49e7156f2b60688465f 100644 (file)
@@ -4394,7 +4394,7 @@ static struct {
        {"tx_fifo_errors"},
        {"tx_packets"}
 };
-#define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN)
+#define CAS_NUM_STAT_KEYS ARRAY_SIZE(ethtool_cassini_statnames)
 
 static struct {
        const int offsets;      /* neg. values for 2nd arg to cas_read_phy */
@@ -5085,7 +5085,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
 
        /* give us access to cassini registers */
        cp->regs = pci_iomap(pdev, 0, casreg_len);
-       if (cp->regs == 0UL) {
+       if (!cp->regs) {
                dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
                goto err_out_free_res;
        }
index 846ca5383d3c875364bac967772d3290efdfd9f6..4bd2455b0fe31b50bc20fba8f6a35e90ccc323fd 100644 (file)
@@ -379,7 +379,7 @@ extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config
 extern const struct board_info *t1_get_board_info(unsigned int board_id);
 extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid,
                                                    unsigned short ssid);
-extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data);
+extern int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data);
 extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
                     struct adapter_params *p);
 extern int t1_init_hw_modules(adapter_t *adapter);
index c5975047c89b7d034dd607fd0b4c8186847ddf1b..a509337eab2dd44d562e131f814599138d133dfe 100644 (file)
@@ -814,7 +814,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 
        e->magic = EEPROM_MAGIC(adapter);
        for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
-               t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
+               t1_seeprom_read(adapter, i, (__le32 *)&buf[i]);
        memcpy(data, buf + e->offset, e->len);
        return 0;
 }
@@ -1042,7 +1042,7 @@ static int __devinit init_one(struct pci_dev *pdev,
                pci_using_dac = 1;
 
                if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
-                       CH_ERR("%s: unable to obtain 64-bit DMA for"
+                       CH_ERR("%s: unable to obtain 64-bit DMA for "
                               "consistent allocations\n", pci_name(pdev));
                        err = -ENODEV;
                        goto out_disable_pdev;
index d7c5406a6c3f2cb759977d5a9cf11cb6226cbd53..1e0749e000b0972eaa8170b59dc9131c39c2ac3f 100644 (file)
@@ -297,6 +297,7 @@ struct peespi *t1_espi_create(adapter_t *adapter)
        return espi;
 }
 
+#if 0
 void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
 {
        struct peespi *espi = adapter->espi;
@@ -309,6 +310,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val)
        writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL);
        spin_unlock(&espi->lock);
 }
+#endif  /*  0  */
 
 u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait)
 {
index 84f2c98bc4cc6e2c7ebede89a99a8af2b869b724..5694aad4fbc0a014c478b87cb4049a73446457c7 100644 (file)
@@ -62,7 +62,6 @@ void t1_espi_intr_disable(struct peespi *);
 int t1_espi_intr_handler(struct peespi *);
 const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi);
 
-void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val);
 u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait);
 int t1_espi_get_mon_t204(adapter_t *, u32 *, u8);
 
index b301c0428ae081d0c59a2059c9be8893fcafdb82..8a7efd38e95bba6ce63d9d1f0efbd5a7dd380838 100644 (file)
@@ -330,6 +330,8 @@ unsigned int t1_sched_update_parms(struct sge *sge, unsigned int port,
        return max_avail_segs * (p->mtu - 40);
 }
 
+#if 0
+
 /*
  * t1_sched_max_avail_bytes() tells the scheduler the maximum amount of
  * data that can be pushed per port.
@@ -357,6 +359,8 @@ void t1_sched_set_drain_bits_per_us(struct sge *sge, unsigned int port,
        t1_sched_update_parms(sge, port, 0, 0);
 }
 
+#endif  /*  0  */
+
 
 /*
  * get_clock() implements a ns clock (see ktime_get)
index cced9dff91c5ed9f6db257931c9cbc251f6818d8..8c9405123992527300fde59cda7bb74cc45af8bb 100644 (file)
@@ -88,8 +88,6 @@ void t1_sge_intr_disable(struct sge *);
 void t1_sge_intr_clear(struct sge *);
 const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge);
 void t1_sge_get_port_stats(const struct sge *sge, int port, struct sge_port_stats *);
-void t1_sched_set_max_avail_bytes(struct sge *, unsigned int);
-void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int);
 unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int,
                           unsigned int);
 
index dc50151bed811c01610a1bbe632c678812b53c70..7adf30230c4f7123d03d91e2f9c500f26d4a49f8 100644 (file)
@@ -563,10 +563,11 @@ struct chelsio_vpd_t {
  * written to the Control register. The hardware device will set the flag to a
  * one when 4B have been transferred to the Data register.
  */
-int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
+int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data)
 {
        int i = EEPROM_MAX_POLL;
        u16 val;
+       u32 v;
 
        if (addr >= EEPROMSIZE || (addr & 3))
                return -EINVAL;
@@ -582,8 +583,8 @@ int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
                       adapter->name, addr);
                return -EIO;
        }
-       pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data);
-       *data = le32_to_cpu(*data);
+       pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v);
+       *data = cpu_to_le32(v);
        return 0;
 }
 
@@ -593,7 +594,7 @@ static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd)
 
        for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
                ret = t1_seeprom_read(adapter, addr,
-                                     (u32 *)((u8 *)vpd + addr));
+                                     (__le32 *)((u8 *)vpd + addr));
 
        return ret;
 }
index 6e12d48351b8e1a4b243efd80b5c669c689e6830..6ccebb830ff90bc86f4b00ed0f622f8fe0c0245b 100644 (file)
@@ -661,9 +661,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
        int queue;
        u32 status;
 
-       if (!dev)
-               return IRQ_NONE;
-
        priv = netdev_priv(dev);
 
        status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);
index 60a62f510db7b12bc525be5e958e58cbd52d23a9..eb305a0895fc4a82e3ff99717dc82c6d709bf2f4 100644 (file)
@@ -71,6 +71,7 @@ enum {                                /* adapter flags */
        USING_MSI = (1 << 1),
        USING_MSIX = (1 << 2),
        QUEUES_BOUND = (1 << 3),
+       TP_PARITY_INIT = (1 << 4),
 };
 
 struct fl_pg_chunk {
index 99c75d30f67a8538ddd921646666d39d53901295..91ee7277b813bba19ca9a2513820d29d3181bdd1 100644 (file)
@@ -681,8 +681,8 @@ int t3_phy_intr_handler(struct adapter *adapter);
 void t3_link_changed(struct adapter *adapter, int port_id);
 int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
 const struct adapter_info *t3_get_adapter_info(unsigned int board_id);
-int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data);
-int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data);
+int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data);
+int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data);
 int t3_seeprom_wp(struct adapter *adapter, int enable);
 int t3_get_tp_version(struct adapter *adapter, u32 *vers);
 int t3_check_tpsram_version(struct adapter *adapter, int *must_load);
index 61ffc925eae777b065c37dea73c9b938e49ccd8e..fd2e05bbb9036fd8eac062caa7338651e0cf8baa 100644 (file)
@@ -76,20 +76,20 @@ enum {
 
 #define EEPROM_MAGIC 0x38E2F10C
 
-#define CH_DEVICE(devid, ssid, idx) \
-       { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx }
+#define CH_DEVICE(devid, idx) \
+       { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx }
 
 static const struct pci_device_id cxgb3_pci_tbl[] = {
-       CH_DEVICE(0x20, 1, 0),  /* PE9000 */
-       CH_DEVICE(0x21, 1, 1),  /* T302E */
-       CH_DEVICE(0x22, 1, 2),  /* T310E */
-       CH_DEVICE(0x23, 1, 3),  /* T320X */
-       CH_DEVICE(0x24, 1, 1),  /* T302X */
-       CH_DEVICE(0x25, 1, 3),  /* T320E */
-       CH_DEVICE(0x26, 1, 2),  /* T310X */
-       CH_DEVICE(0x30, 1, 2),  /* T3B10 */
-       CH_DEVICE(0x31, 1, 3),  /* T3B20 */
-       CH_DEVICE(0x32, 1, 1),  /* T3B02 */
+       CH_DEVICE(0x20, 0),     /* PE9000 */
+       CH_DEVICE(0x21, 1),     /* T302E */
+       CH_DEVICE(0x22, 2),     /* T310E */
+       CH_DEVICE(0x23, 3),     /* T320X */
+       CH_DEVICE(0x24, 1),     /* T302X */
+       CH_DEVICE(0x25, 3),     /* T320E */
+       CH_DEVICE(0x26, 2),     /* T310X */
+       CH_DEVICE(0x30, 2),     /* T3B10 */
+       CH_DEVICE(0x31, 3),     /* T3B20 */
+       CH_DEVICE(0x32, 1),     /* T3B02 */
        {0,}
 };
 
@@ -306,6 +306,77 @@ static int request_msix_data_irqs(struct adapter *adap)
        return 0;
 }
 
+static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
+                             unsigned long n)
+{
+       int attempts = 5;
+
+       while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
+               if (!--attempts)
+                       return -ETIMEDOUT;
+               msleep(10);
+       }
+       return 0;
+}
+
+static int init_tp_parity(struct adapter *adap)
+{
+       int i;
+       struct sk_buff *skb;
+       struct cpl_set_tcb_field *greq;
+       unsigned long cnt = adap->sge.qs[0].rspq.offload_pkts;
+
+       t3_tp_set_offload_mode(adap, 1);
+
+       for (i = 0; i < 16; i++) {
+               struct cpl_smt_write_req *req;
+
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               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);
+       }
+
+       for (i = 0; i < 2048; i++) {
+               struct cpl_l2t_write_req *req;
+
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               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);
+       }
+
+       for (i = 0; i < 2048; i++) {
+               struct cpl_rte_write_req *req;
+
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               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);
+       }
+
+       skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
+       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));
+       OPCODE_TID(greq) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, 0));
+       greq->mask = cpu_to_be64(1);
+       t3_mgmt_tx(adap, skb);
+
+       i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+       t3_tp_set_offload_mode(adap, 0);
+       return i;
+}
+
 /**
  *     setup_rss - configure RSS
  *     @adap: the adapter
@@ -336,7 +407,7 @@ static void setup_rss(struct adapter *adap)
 
        t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN |
                      F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN |
-                     V_RRCPLCPUSIZE(6), cpus, rspq_map);
+                     V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map);
 }
 
 static void init_napi(struct adapter *adap)
@@ -410,8 +481,7 @@ static int setup_sge_qsets(struct adapter *adap)
        return 0;
 }
 
-static ssize_t attr_show(struct device *d, struct device_attribute *attr,
-                        char *buf,
+static ssize_t attr_show(struct device *d, char *buf,
                         ssize_t(*format) (struct net_device *, char *))
 {
        ssize_t len;
@@ -423,7 +493,7 @@ static ssize_t attr_show(struct device *d, struct device_attribute *attr,
        return len;
 }
 
-static ssize_t attr_store(struct device *d, struct device_attribute *attr,
+static ssize_t attr_store(struct device *d,
                          const char *buf, size_t len,
                          ssize_t(*set) (struct net_device *, unsigned int),
                          unsigned int min_val, unsigned int max_val)
@@ -457,7 +527,7 @@ static ssize_t format_##name(struct net_device *dev, char *buf) \
 static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
                           char *buf) \
 { \
-       return attr_show(d, attr, buf, format_##name); \
+       return attr_show(d, buf, format_##name); \
 }
 
 static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
@@ -480,7 +550,7 @@ static ssize_t set_nfilters(struct net_device *dev, unsigned int val)
 static ssize_t store_nfilters(struct device *d, struct device_attribute *attr,
                              const char *buf, size_t len)
 {
-       return attr_store(d, attr, buf, len, set_nfilters, 0, ~0);
+       return attr_store(d, buf, len, set_nfilters, 0, ~0);
 }
 
 static ssize_t set_nservers(struct net_device *dev, unsigned int val)
@@ -500,7 +570,7 @@ static ssize_t set_nservers(struct net_device *dev, unsigned int val)
 static ssize_t store_nservers(struct device *d, struct device_attribute *attr,
                              const char *buf, size_t len)
 {
-       return attr_store(d, attr, buf, len, set_nservers, 0, ~0);
+       return attr_store(d, buf, len, set_nservers, 0, ~0);
 }
 
 #define CXGB3_ATTR_R(name, val_expr) \
@@ -524,7 +594,7 @@ static struct attribute *cxgb3_attrs[] = {
 
 static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs };
 
-static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
+static ssize_t tm_attr_show(struct device *d,
                            char *buf, int sched)
 {
        struct port_info *pi = netdev_priv(to_net_dev(d));
@@ -550,7 +620,7 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr,
        return len;
 }
 
-static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr,
+static ssize_t tm_attr_store(struct device *d,
                             const char *buf, size_t len, int sched)
 {
        struct port_info *pi = netdev_priv(to_net_dev(d));
@@ -578,12 +648,12 @@ static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr,
 static ssize_t show_##name(struct device *d, struct device_attribute *attr, \
                           char *buf) \
 { \
-       return tm_attr_show(d, attr, buf, sched); \
+       return tm_attr_show(d, buf, sched); \
 } \
 static ssize_t store_##name(struct device *d, struct device_attribute *attr, \
                            const char *buf, size_t len) \
 { \
-       return tm_attr_store(d, attr, buf, len, sched); \
+       return tm_attr_store(d, buf, len, sched); \
 } \
 static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
 
@@ -720,7 +790,7 @@ static int upgrade_fw(struct adapter *adap)
        else
                dev_err(dev, "failed to upgrade to firmware %d.%d.%d\n",
                        FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
-       
+
        return ret;
 }
 
@@ -747,7 +817,7 @@ static int update_tpsram(struct adapter *adap)
        struct device *dev = &adap->pdev->dev;
        int ret;
        char rev;
-       
+
        rev = t3rev2char(adap);
        if (!rev)
                return 0;
@@ -761,10 +831,10 @@ static int update_tpsram(struct adapter *adap)
                        buf);
                return ret;
        }
-       
+
        ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
        if (ret)
-               goto release_tpsram;    
+               goto release_tpsram;
 
        ret = t3_set_proto_sram(adap, tpsram->data);
        if (ret == 0)
@@ -780,7 +850,7 @@ static int update_tpsram(struct adapter *adap)
 
 release_tpsram:
        release_firmware(tpsram);
-       
+
        return ret;
 }
 
@@ -818,6 +888,7 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto out;
 
+               t3_set_reg_field(adap, A_TP_PARA_REG5, 0, F_RXDDPOFFINIT);
                t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));
 
                err = setup_sge_qsets(adap);
@@ -839,7 +910,8 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto irq_err;
 
-               if (request_msix_data_irqs(adap)) {
+               err = request_msix_data_irqs(adap);
+               if (err) {
                        free_irq(adap->msix_info[0].vec, adap);
                        goto irq_err;
                }
@@ -856,6 +928,16 @@ static int cxgb_up(struct adapter *adap)
        t3_sge_start(adap);
        t3_intr_enable(adap);
 
+       if (adap->params.rev >= T3_REV_C && !(adap->flags & TP_PARITY_INIT) &&
+           is_offload(adap) && init_tp_parity(adap) == 0)
+               adap->flags |= TP_PARITY_INIT;
+
+       if (adap->flags & TP_PARITY_INIT) {
+               t3_write_reg(adap, A_TP_INT_CAUSE,
+                            F_CMCACHEPERR | F_ARPLUTPERR);
+               t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff);
+       }
+
        if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
                bind_qsets(adap);
        adap->flags |= QUEUES_BOUND;
@@ -1560,7 +1642,7 @@ static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
 
        e->magic = EEPROM_MAGIC;
        for (i = e->offset & ~3; !err && i < e->offset + e->len; i += 4)
-               err = t3_seeprom_read(adapter, i, (u32 *) & buf[i]);
+               err = t3_seeprom_read(adapter, i, (__le32 *) & buf[i]);
 
        if (!err)
                memcpy(data, buf + e->offset, e->len);
@@ -1573,7 +1655,8 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 {
        struct port_info *pi = netdev_priv(dev);
        struct adapter *adapter = pi->adapter;
-       u32 aligned_offset, aligned_len, *p;
+       u32 aligned_offset, aligned_len;
+       __le32 *p;
        u8 *buf;
        int err;
 
@@ -1587,11 +1670,11 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                buf = kmalloc(aligned_len, GFP_KERNEL);
                if (!buf)
                        return -ENOMEM;
-               err = t3_seeprom_read(adapter, aligned_offset, (u32 *) buf);
+               err = t3_seeprom_read(adapter, aligned_offset, (__le32 *) buf);
                if (!err && aligned_len > 4)
                        err = t3_seeprom_read(adapter,
                                              aligned_offset + aligned_len - 4,
-                                             (u32 *) & buf[aligned_len - 4]);
+                                             (__le32 *) & buf[aligned_len - 4]);
                if (err)
                        goto out;
                memcpy(buf + (eeprom->offset & 3), data, eeprom->len);
@@ -1602,7 +1685,7 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (err)
                goto out;
 
-       for (p = (u32 *) buf; !err && aligned_len; aligned_len -= 4, p++) {
+       for (p = (__le32 *) buf; !err && aligned_len; aligned_len -= 4, p++) {
                err = t3_seeprom_write(adapter, aligned_offset, *p);
                aligned_offset += 4;
        }
@@ -2144,7 +2227,7 @@ static void cxgb_netpoll(struct net_device *dev)
        for (qidx = pi->first_qset; qidx < pi->first_qset + pi->nqsets; qidx++) {
                struct sge_qset *qs = &adapter->sge.qs[qidx];
                void *source;
-               
+
                if (adapter->flags & USING_MSIX)
                        source = qs;
                else
@@ -2315,6 +2398,106 @@ void t3_fatal_err(struct adapter *adapter)
 
 }
 
+/**
+ * t3_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
+                                            pci_channel_state_t state)
+{
+       struct adapter *adapter = pci_get_drvdata(pdev);
+       int i;
+
+       /* Stop all ports */
+       for_each_port(adapter, i) {
+               struct net_device *netdev = adapter->port[i];
+
+               if (netif_running(netdev))
+                       cxgb_close(netdev);
+       }
+
+       if (is_offload(adapter) &&
+           test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
+               offload_close(&adapter->tdev);
+
+       /* Free sge resources */
+       t3_free_sge_resources(adapter);
+
+       adapter->flags &= ~FULL_INIT_DONE;
+
+       pci_disable_device(pdev);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * t3_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ */
+static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
+{
+       struct adapter *adapter = pci_get_drvdata(pdev);
+
+       if (pci_enable_device(pdev)) {
+               dev_err(&pdev->dev,
+                       "Cannot re-enable PCI device after reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       t3_prep_adapter(adapter, adapter->params.info, 1);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * t3_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation.
+ */
+static void t3_io_resume(struct pci_dev *pdev)
+{
+       struct adapter *adapter = pci_get_drvdata(pdev);
+       int i;
+
+       /* Restart the ports */
+       for_each_port(adapter, i) {
+               struct net_device *netdev = adapter->port[i];
+
+               if (netif_running(netdev)) {
+                       if (cxgb_open(netdev)) {
+                               dev_err(&pdev->dev,
+                                       "can't bring device back up"
+                                       " after reset\n");
+                               continue;
+                       }
+                       netif_device_attach(netdev);
+               }
+       }
+
+       if (is_offload(adapter)) {
+               __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map);
+               if (offload_open(adapter->port[0]))
+                       printk(KERN_WARNING
+                              "Could not bring back offload capabilities\n");
+       }
+}
+
+static struct pci_error_handlers t3_err_handler = {
+       .error_detected = t3_io_error_detected,
+       .slot_reset = t3_io_slot_reset,
+       .resume = t3_io_resume,
+};
+
 static int __devinit cxgb_enable_msix(struct adapter *adap)
 {
        struct msix_entry entries[SGE_QSETS + 1];
@@ -2507,7 +2690,7 @@ static int __devinit init_one(struct pci_dev *pdev,
                err = -ENODEV;
                goto out_free_dev;
        }
-               
+
        /*
         * The card is now ready to go.  If any errors occur during device
         * registration we do not fail the whole card but rather proceed only
@@ -2584,10 +2767,6 @@ static void __devexit remove_one(struct pci_dev *pdev)
                sysfs_remove_group(&adapter->port[0]->dev.kobj,
                                   &cxgb3_attr_group);
 
-               for_each_port(adapter, i)
-                   if (test_bit(i, &adapter->registered_device_map))
-                       unregister_netdev(adapter->port[i]);
-
                if (is_offload(adapter)) {
                        cxgb3_adapter_unofld(adapter);
                        if (test_bit(OFFLOAD_DEVMAP_BIT,
@@ -2595,6 +2774,10 @@ static void __devexit remove_one(struct pci_dev *pdev)
                                offload_close(&adapter->tdev);
                }
 
+               for_each_port(adapter, i)
+                   if (test_bit(i, &adapter->registered_device_map))
+                       unregister_netdev(adapter->port[i]);
+
                t3_free_sge_resources(adapter);
                cxgb_disable_msi(adapter);
 
@@ -2615,6 +2798,7 @@ static struct pci_driver driver = {
        .id_table = cxgb3_pci_tbl,
        .probe = init_one,
        .remove = __devexit_p(remove_one),
+       .err_handler = &t3_err_handler,
 };
 
 static int __init cxgb3_init_module(void)
index bd25421bc12a67302eeeb6dcf81296c3c1d71ef2..d48c396bdabb9858f15f8f0264557bb68890d9e4 100644 (file)
@@ -403,8 +403,6 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
 static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs,
                                int n)
 {
-       CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
-              n, ntohl(*(__be32 *)skbs[0]->data));
        while (n--)
                dev_kfree_skb_any(skbs[n]);
        return 0;
@@ -488,7 +486,7 @@ static void t3_process_tid_release_list(struct work_struct *work)
                                           tid_release_task);
        struct sk_buff *skb;
        struct t3cdev *tdev = td->dev;
-       
+
 
        spin_lock_bh(&td->tid_release_lock);
        while (td->tid_release_list) {
@@ -634,6 +632,18 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
        return CPL_RET_BUF_DONE;
 }
 
+static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
+{
+       struct cpl_rte_write_rpl *rpl = cplhdr(skb);
+
+       if (rpl->status != CPL_ERR_NONE)
+               printk(KERN_ERR
+                      "Unexpected RTE_WRITE_RPL status %u for entry %u\n",
+                      rpl->status, GET_TID(rpl));
+
+       return CPL_RET_BUF_DONE;
+}
+
 static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
 {
        struct cpl_act_open_rpl *rpl = cplhdr(skb);
@@ -1004,7 +1014,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
        if (!is_offloading(olddev))
                return;
        if (!is_offloading(newdev)) {
-               printk(KERN_WARNING "%s: Redirect to non-offload"
+               printk(KERN_WARNING "%s: Redirect to non-offload "
                       "device ignored.\n", __FUNCTION__);
                return;
        }
@@ -1257,6 +1267,7 @@ void __init cxgb3_offload_init(void)
 
        t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl);
        t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl);
+       t3_register_cpl_handler(CPL_RTE_WRITE_RPL, do_rte_write_rpl);
        t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl);
        t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl);
        t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr);
index 6a835f6a262af498967d29728e22d05458c4bb07..b75ddd8777fe8dbd0c900e775351e9ebe753fe13 100644 (file)
 #define FW_WROPCODE_MNGT                       0x1D
 #define FW_MNGTOPCODE_PKTSCHED_SET             0x00
 
-/* Maximum size of a WR sent from the host, limited by the SGE. 
+/* Maximum size of a WR sent from the host, limited by the SGE.
  *
- * Note: WR coming from ULP or TP are only limited by CIM. 
+ * Note: WR coming from ULP or TP are only limited by CIM.
  */
 #define FW_WR_SIZE                     128
 
 /* Maximum number of outstanding WRs sent from the host. Value must be
- * programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by 
+ * programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by
  * offload modules to limit the number of WRs per connection.
  */
 #define FW_T3_WR_NUM                   16
@@ -99,7 +99,7 @@
  * queues must start at SGE Egress Context FW_TUNNEL_SGEEC_START and must
  * start at 'TID' (or 'uP Token') FW_TUNNEL_TID_START.
  *
- * Ingress Traffic (e.g. DMA completion credit)  for TUNNEL Queue[i] is sent 
+ * Ingress Traffic (e.g. DMA completion credit)  for TUNNEL Queue[i] is sent
  * to RESP Queue[i].
  */
 #define FW_TUNNEL_NUM                  8
 #define FW_CTRL_SGEEC_START            65528
 #define FW_CTRL_TID_START              65536
 
-/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These 
- * queues must start at SGE Egress Context FW_OFLD_SGEEC_START. 
- * 
- * Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for 
+/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These
+ * queues must start at SGE Egress Context FW_OFLD_SGEEC_START.
+ *
+ * Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for
  * OFFLOAD Queues, as the host is responsible for providing the correct TID in
  * every WR.
  *
 #define FW_OFLD_SGEEC_START            0
 
 /*
- * 
+ *
  */
 #define FW_RI_NUM                      1
 #define FW_RI_SGEEC_START              65527
 #define FW_RI_TID_START                        65552
 
 /*
- * The RX_PKT_TID 
+ * The RX_PKT_TID
  */
 #define FW_RX_PKT_NUM                  1
 #define FW_RX_PKT_TID_START            65553
index d660af74606e4abbb20f9d964c0080367425662e..17ed4c3527b7727bc033ae4d843490f0bf3b0ea0 100644 (file)
@@ -337,7 +337,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
                atomic_set(&e->refcnt, 1);
                neigh_replace(e, neigh);
                if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
-                       e->vlan = VLAN_DEV_INFO(neigh->dev)->vlan_id;
+                       e->vlan = vlan_dev_info(neigh->dev)->vlan_id;
                else
                        e->vlan = VLAN_NONE;
                spin_unlock(&e->lock);
index 6e12bf4bc6cf73fd43b8450e891dcb656359bd2e..02dbbb300929e35458fd3a60a42e04e98a3ab6d6 100644 (file)
@@ -1,5 +1,17 @@
 #define A_SG_CONTROL 0x0
 
+#define S_CONGMODE    29
+#define V_CONGMODE(x) ((x) << S_CONGMODE)
+#define F_CONGMODE    V_CONGMODE(1U)
+
+#define S_TNLFLMODE    28
+#define V_TNLFLMODE(x) ((x) << S_TNLFLMODE)
+#define F_TNLFLMODE    V_TNLFLMODE(1U)
+
+#define S_FATLPERREN    27
+#define V_FATLPERREN(x) ((x) << S_FATLPERREN)
+#define F_FATLPERREN    V_FATLPERREN(1U)
+
 #define S_DROPPKT    20
 #define V_DROPPKT(x) ((x) << S_DROPPKT)
 #define F_DROPPKT    V_DROPPKT(1U)
 
 #define A_SG_INT_CAUSE 0x5c
 
+#define S_HIRCQPARITYERROR    31
+#define V_HIRCQPARITYERROR(x) ((x) << S_HIRCQPARITYERROR)
+#define F_HIRCQPARITYERROR    V_HIRCQPARITYERROR(1U)
+
+#define S_LORCQPARITYERROR    30
+#define V_LORCQPARITYERROR(x) ((x) << S_LORCQPARITYERROR)
+#define F_LORCQPARITYERROR    V_LORCQPARITYERROR(1U)
+
+#define S_HIDRBPARITYERROR    29
+#define V_HIDRBPARITYERROR(x) ((x) << S_HIDRBPARITYERROR)
+#define F_HIDRBPARITYERROR    V_HIDRBPARITYERROR(1U)
+
+#define S_LODRBPARITYERROR    28
+#define V_LODRBPARITYERROR(x) ((x) << S_LODRBPARITYERROR)
+#define F_LODRBPARITYERROR    V_LODRBPARITYERROR(1U)
+
+#define S_FLPARITYERROR    22
+#define M_FLPARITYERROR    0x3f
+#define V_FLPARITYERROR(x) ((x) << S_FLPARITYERROR)
+#define G_FLPARITYERROR(x) (((x) >> S_FLPARITYERROR) & M_FLPARITYERROR)
+
+#define S_ITPARITYERROR    20
+#define M_ITPARITYERROR    0x3
+#define V_ITPARITYERROR(x) ((x) << S_ITPARITYERROR)
+#define G_ITPARITYERROR(x) (((x) >> S_ITPARITYERROR) & M_ITPARITYERROR)
+
+#define S_IRPARITYERROR    19
+#define V_IRPARITYERROR(x) ((x) << S_IRPARITYERROR)
+#define F_IRPARITYERROR    V_IRPARITYERROR(1U)
+
+#define S_RCPARITYERROR    18
+#define V_RCPARITYERROR(x) ((x) << S_RCPARITYERROR)
+#define F_RCPARITYERROR    V_RCPARITYERROR(1U)
+
+#define S_OCPARITYERROR    17
+#define V_OCPARITYERROR(x) ((x) << S_OCPARITYERROR)
+#define F_OCPARITYERROR    V_OCPARITYERROR(1U)
+
+#define S_CPPARITYERROR    16
+#define V_CPPARITYERROR(x) ((x) << S_CPPARITYERROR)
+#define F_CPPARITYERROR    V_CPPARITYERROR(1U)
+
+#define S_R_REQ_FRAMINGERROR    15
+#define V_R_REQ_FRAMINGERROR(x) ((x) << S_R_REQ_FRAMINGERROR)
+#define F_R_REQ_FRAMINGERROR    V_R_REQ_FRAMINGERROR(1U)
+
+#define S_UC_REQ_FRAMINGERROR    14
+#define V_UC_REQ_FRAMINGERROR(x) ((x) << S_UC_REQ_FRAMINGERROR)
+#define F_UC_REQ_FRAMINGERROR    V_UC_REQ_FRAMINGERROR(1U)
+
+#define S_HICTLDRBDROPERR    13
+#define V_HICTLDRBDROPERR(x) ((x) << S_HICTLDRBDROPERR)
+#define F_HICTLDRBDROPERR    V_HICTLDRBDROPERR(1U)
+
+#define S_LOCTLDRBDROPERR    12
+#define V_LOCTLDRBDROPERR(x) ((x) << S_LOCTLDRBDROPERR)
+#define F_LOCTLDRBDROPERR    V_LOCTLDRBDROPERR(1U)
+
 #define S_HIPIODRBDROPERR    11
 #define V_HIPIODRBDROPERR(x) ((x) << S_HIPIODRBDROPERR)
 #define F_HIPIODRBDROPERR    V_HIPIODRBDROPERR(1U)
 
 #define A_PCIX_CFG 0x88
 
+#define S_DMASTOPEN    19
+#define V_DMASTOPEN(x) ((x) << S_DMASTOPEN)
+#define F_DMASTOPEN    V_DMASTOPEN(1U)
+
 #define S_CLIDECEN    18
 #define V_CLIDECEN(x) ((x) << S_CLIDECEN)
 #define F_CLIDECEN    V_CLIDECEN(1U)
 
 #define V_BISTERR(x) ((x) << S_BISTERR)
 
+#define S_TXPARERR    18
+#define V_TXPARERR(x) ((x) << S_TXPARERR)
+#define F_TXPARERR    V_TXPARERR(1U)
+
+#define S_RXPARERR    17
+#define V_RXPARERR(x) ((x) << S_RXPARERR)
+#define F_RXPARERR    V_RXPARERR(1U)
+
+#define S_RETRYLUTPARERR    16
+#define V_RETRYLUTPARERR(x) ((x) << S_RETRYLUTPARERR)
+#define F_RETRYLUTPARERR    V_RETRYLUTPARERR(1U)
+
+#define S_RETRYBUFPARERR    15
+#define V_RETRYBUFPARERR(x) ((x) << S_RETRYBUFPARERR)
+#define F_RETRYBUFPARERR    V_RETRYBUFPARERR(1U)
+
 #define S_PCIE_MSIXPARERR    12
 #define M_PCIE_MSIXPARERR    0x7
 
 
 #define A_PCIE_INT_CAUSE 0x84
 
+#define S_PCIE_DMASTOPEN    24
+#define V_PCIE_DMASTOPEN(x) ((x) << S_PCIE_DMASTOPEN)
+#define F_PCIE_DMASTOPEN    V_PCIE_DMASTOPEN(1U)
+
 #define A_PCIE_CFG 0x88
 
 #define S_PCIE_CLIDECEN    16
 
 #define A_CIM_HOST_INT_ENABLE 0x298
 
+#define S_DTAGPARERR    28
+#define V_DTAGPARERR(x) ((x) << S_DTAGPARERR)
+#define F_DTAGPARERR    V_DTAGPARERR(1U)
+
+#define S_ITAGPARERR    27
+#define V_ITAGPARERR(x) ((x) << S_ITAGPARERR)
+#define F_ITAGPARERR    V_ITAGPARERR(1U)
+
+#define S_IBQTPPARERR    26
+#define V_IBQTPPARERR(x) ((x) << S_IBQTPPARERR)
+#define F_IBQTPPARERR    V_IBQTPPARERR(1U)
+
+#define S_IBQULPPARERR    25
+#define V_IBQULPPARERR(x) ((x) << S_IBQULPPARERR)
+#define F_IBQULPPARERR    V_IBQULPPARERR(1U)
+
+#define S_IBQSGEHIPARERR    24
+#define V_IBQSGEHIPARERR(x) ((x) << S_IBQSGEHIPARERR)
+#define F_IBQSGEHIPARERR    V_IBQSGEHIPARERR(1U)
+
+#define S_IBQSGELOPARERR    23
+#define V_IBQSGELOPARERR(x) ((x) << S_IBQSGELOPARERR)
+#define F_IBQSGELOPARERR    V_IBQSGELOPARERR(1U)
+
+#define S_OBQULPLOPARERR    22
+#define V_OBQULPLOPARERR(x) ((x) << S_OBQULPLOPARERR)
+#define F_OBQULPLOPARERR    V_OBQULPLOPARERR(1U)
+
+#define S_OBQULPHIPARERR    21
+#define V_OBQULPHIPARERR(x) ((x) << S_OBQULPHIPARERR)
+#define F_OBQULPHIPARERR    V_OBQULPHIPARERR(1U)
+
+#define S_OBQSGEPARERR    20
+#define V_OBQSGEPARERR(x) ((x) << S_OBQSGEPARERR)
+#define F_OBQSGEPARERR    V_OBQSGEPARERR(1U)
+
+#define S_DCACHEPARERR    19
+#define V_DCACHEPARERR(x) ((x) << S_DCACHEPARERR)
+#define F_DCACHEPARERR    V_DCACHEPARERR(1U)
+
+#define S_ICACHEPARERR    18
+#define V_ICACHEPARERR(x) ((x) << S_ICACHEPARERR)
+#define F_ICACHEPARERR    V_ICACHEPARERR(1U)
+
+#define S_DRAMPARERR    17
+#define V_DRAMPARERR(x) ((x) << S_DRAMPARERR)
+#define F_DRAMPARERR    V_DRAMPARERR(1U)
+
 #define A_CIM_HOST_INT_CAUSE 0x29c
 
 #define S_BLKWRPLINT    12
 
 #define A_CIM_HOST_ACC_DATA 0x2b4
 
+#define A_CIM_IBQ_DBG_CFG 0x2c0
+
+#define S_IBQDBGADDR    16
+#define M_IBQDBGADDR    0x1ff
+#define V_IBQDBGADDR(x) ((x) << S_IBQDBGADDR)
+#define G_IBQDBGADDR(x) (((x) >> S_IBQDBGADDR) & M_IBQDBGADDR)
+
+#define S_IBQDBGQID    3
+#define M_IBQDBGQID    0x3
+#define V_IBQDBGQID(x) ((x) << S_IBQDBGQID)
+#define G_IBQDBGQID(x) (((x) >> S_IBQDBGQID) & M_IBQDBGQID)
+
+#define S_IBQDBGWR    2
+#define V_IBQDBGWR(x) ((x) << S_IBQDBGWR)
+#define F_IBQDBGWR    V_IBQDBGWR(1U)
+
+#define S_IBQDBGBUSY    1
+#define V_IBQDBGBUSY(x) ((x) << S_IBQDBGBUSY)
+#define F_IBQDBGBUSY    V_IBQDBGBUSY(1U)
+
+#define S_IBQDBGEN    0
+#define V_IBQDBGEN(x) ((x) << S_IBQDBGEN)
+#define F_IBQDBGEN    V_IBQDBGEN(1U)
+
+#define A_CIM_IBQ_DBG_DATA 0x2c8
+
 #define A_TP_IN_CONFIG 0x300
 
+#define S_RXFBARBPRIO    25
+#define V_RXFBARBPRIO(x) ((x) << S_RXFBARBPRIO)
+#define F_RXFBARBPRIO    V_RXFBARBPRIO(1U)
+
+#define S_TXFBARBPRIO    24
+#define V_TXFBARBPRIO(x) ((x) << S_TXFBARBPRIO)
+#define F_TXFBARBPRIO    V_TXFBARBPRIO(1U)
+
 #define S_NICMODE    14
 #define V_NICMODE(x) ((x) << S_NICMODE)
 #define F_NICMODE    V_NICMODE(1U)
 #define V_LOCKTID(x) ((x) << S_LOCKTID)
 #define F_LOCKTID    V_LOCKTID(1U)
 
+#define S_TABLELATENCYDELTA    0
+#define M_TABLELATENCYDELTA    0xf
+#define V_TABLELATENCYDELTA(x) ((x) << S_TABLELATENCYDELTA)
+#define G_TABLELATENCYDELTA(x) \
+       (((x) >> S_TABLELATENCYDELTA) & M_TABLELATENCYDELTA)
+
 #define A_TP_PC_CONFIG2 0x34c
 
+#define S_DISBLEDAPARBIT0    15
+#define V_DISBLEDAPARBIT0(x) ((x) << S_DISBLEDAPARBIT0)
+#define F_DISBLEDAPARBIT0    V_DISBLEDAPARBIT0(1U)
+
+#define S_ENABLEARPMISS    13
+#define V_ENABLEARPMISS(x) ((x) << S_ENABLEARPMISS)
+#define F_ENABLEARPMISS    V_ENABLEARPMISS(1U)
+
+#define S_ENABLENONOFDTNLSYN    12
+#define V_ENABLENONOFDTNLSYN(x) ((x) << S_ENABLENONOFDTNLSYN)
+#define F_ENABLENONOFDTNLSYN    V_ENABLENONOFDTNLSYN(1U)
+
+#define S_ENABLEIPV6RSS    11
+#define V_ENABLEIPV6RSS(x) ((x) << S_ENABLEIPV6RSS)
+#define F_ENABLEIPV6RSS    V_ENABLEIPV6RSS(1U)
+
 #define S_CHDRAFULL    4
 #define V_CHDRAFULL(x) ((x) << S_CHDRAFULL)
 #define F_CHDRAFULL    V_CHDRAFULL(1U)
 
 #define A_TP_PARA_REG4 0x370
 
+#define A_TP_PARA_REG5 0x374
+
+#define S_RXDDPOFFINIT    3
+#define V_RXDDPOFFINIT(x) ((x) << S_RXDDPOFFINIT)
+#define F_RXDDPOFFINIT    V_RXDDPOFFINIT(1U)
+
 #define A_TP_PARA_REG6 0x378
 
 #define S_T3A_ENABLEESND    13
 #define V_TNLLKPEN(x) ((x) << S_TNLLKPEN)
 #define F_TNLLKPEN    V_TNLLKPEN(1U)
 
+#define S_RRCPLMAPEN    7
+#define V_RRCPLMAPEN(x) ((x) << S_RRCPLMAPEN)
+#define F_RRCPLMAPEN    V_RRCPLMAPEN(1U)
+
 #define S_RRCPLCPUSIZE    4
 #define M_RRCPLCPUSIZE    0x7
 #define V_RRCPLCPUSIZE(x) ((x) << S_RRCPLCPUSIZE)
 #define V_RQFEEDBACKENABLE(x) ((x) << S_RQFEEDBACKENABLE)
 #define F_RQFEEDBACKENABLE    V_RQFEEDBACKENABLE(1U)
 
+#define S_HASHTOEPLITZ    2
+#define V_HASHTOEPLITZ(x) ((x) << S_HASHTOEPLITZ)
+#define F_HASHTOEPLITZ    V_HASHTOEPLITZ(1U)
+
 #define S_DISABLE    0
 
 #define A_TP_TM_PIO_ADDR 0x418
 
 #define A_TP_INT_ENABLE 0x470
 
+#define S_FLMTXFLSTEMPTY    30
+#define V_FLMTXFLSTEMPTY(x) ((x) << S_FLMTXFLSTEMPTY)
+#define F_FLMTXFLSTEMPTY    V_FLMTXFLSTEMPTY(1U)
+
+#define S_FLMRXFLSTEMPTY    29
+#define V_FLMRXFLSTEMPTY(x) ((x) << S_FLMRXFLSTEMPTY)
+#define F_FLMRXFLSTEMPTY    V_FLMRXFLSTEMPTY(1U)
+
+#define S_ARPLUTPERR    26
+#define V_ARPLUTPERR(x) ((x) << S_ARPLUTPERR)
+#define F_ARPLUTPERR    V_ARPLUTPERR(1U)
+
+#define S_CMCACHEPERR    24
+#define V_CMCACHEPERR(x) ((x) << S_CMCACHEPERR)
+#define F_CMCACHEPERR    V_CMCACHEPERR(1U)
+
 #define A_TP_INT_CAUSE 0x474
 
 #define A_TP_TX_MOD_Q1_Q0_RATE_LIMIT 0x8
 
 #define A_ULPRX_INT_ENABLE 0x504
 
-#define S_PARERR    0
-#define V_PARERR(x) ((x) << S_PARERR)
-#define F_PARERR    V_PARERR(1U)
+#define S_DATASELFRAMEERR0    7
+#define V_DATASELFRAMEERR0(x) ((x) << S_DATASELFRAMEERR0)
+#define F_DATASELFRAMEERR0    V_DATASELFRAMEERR0(1U)
+
+#define S_DATASELFRAMEERR1    6
+#define V_DATASELFRAMEERR1(x) ((x) << S_DATASELFRAMEERR1)
+#define F_DATASELFRAMEERR1    V_DATASELFRAMEERR1(1U)
+
+#define S_PCMDMUXPERR    5
+#define V_PCMDMUXPERR(x) ((x) << S_PCMDMUXPERR)
+#define F_PCMDMUXPERR    V_PCMDMUXPERR(1U)
+
+#define S_ARBFPERR    4
+#define V_ARBFPERR(x) ((x) << S_ARBFPERR)
+#define F_ARBFPERR    V_ARBFPERR(1U)
+
+#define S_ARBPF0PERR    3
+#define V_ARBPF0PERR(x) ((x) << S_ARBPF0PERR)
+#define F_ARBPF0PERR    V_ARBPF0PERR(1U)
+
+#define S_ARBPF1PERR    2
+#define V_ARBPF1PERR(x) ((x) << S_ARBPF1PERR)
+#define F_ARBPF1PERR    V_ARBPF1PERR(1U)
+
+#define S_PARERRPCMD    1
+#define V_PARERRPCMD(x) ((x) << S_PARERRPCMD)
+#define F_PARERRPCMD    V_PARERRPCMD(1U)
+
+#define S_PARERRDATA    0
+#define V_PARERRDATA(x) ((x) << S_PARERRDATA)
+#define F_PARERRDATA    V_PARERRDATA(1U)
 
 #define A_ULPRX_INT_CAUSE 0x508
 
 
 #define A_ULPTX_CONFIG 0x580
 
+#define S_CFG_CQE_SOP_MASK    1
+#define V_CFG_CQE_SOP_MASK(x) ((x) << S_CFG_CQE_SOP_MASK)
+#define F_CFG_CQE_SOP_MASK    V_CFG_CQE_SOP_MASK(1U)
+
 #define S_CFG_RR_ARB    0
 #define V_CFG_RR_ARB(x) ((x) << S_CFG_RR_ARB)
 #define F_CFG_RR_ARB    V_CFG_RR_ARB(1U)
 
 #define A_CPL_INTR_ENABLE 0x650
 
+#define S_CIM_OP_MAP_PERR    5
+#define V_CIM_OP_MAP_PERR(x) ((x) << S_CIM_OP_MAP_PERR)
+#define F_CIM_OP_MAP_PERR    V_CIM_OP_MAP_PERR(1U)
+
 #define S_CIM_OVFL_ERROR    4
 #define V_CIM_OVFL_ERROR(x) ((x) << S_CIM_OVFL_ERROR)
 #define F_CIM_OVFL_ERROR    V_CIM_OVFL_ERROR(1U)
index c15e43a8543b983f82b0517010979d5eb782bbf8..cb684d30831fcc228da571e80ec9b96b0ee47a8b 100644 (file)
@@ -91,6 +91,10 @@ struct rx_desc {
 
 struct tx_sw_desc {            /* SW state per Tx descriptor */
        struct sk_buff *skb;
+       u8 eop;       /* set if last descriptor for packet */
+       u8 addr_idx;  /* buffer index of first SGL entry in descriptor */
+       u8 fragidx;   /* first page fragment associated with descriptor */
+       s8 sflit;     /* start flit of first SGL entry in descriptor */
 };
 
 struct rx_sw_desc {                /* SW state per Rx descriptor */
@@ -109,13 +113,6 @@ struct rsp_desc {          /* response queue descriptor */
        u8 intr_gen;
 };
 
-struct unmap_info {            /* packet unmapping info, overlays skb->cb */
-       int sflit;              /* start flit of first SGL entry in Tx descriptor */
-       u16 fragidx;            /* first page fragment in current Tx descriptor */
-       u16 addr_idx;           /* buffer index of first SGL entry in descriptor */
-       u32 len;                /* mapped length of skb main body */
-};
-
 /*
  * Holds unmapping information for Tx packets that need deferred unmapping.
  * This structure lives at skb->head and must be allocated by callers.
@@ -177,6 +174,7 @@ static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx)
 static inline void refill_rspq(struct adapter *adapter,
                               const struct sge_rspq *q, unsigned int credits)
 {
+       rmb();
        t3_write_reg(adapter, A_SG_RSPQ_CREDIT_RETURN,
                     V_RSPQ(q->cntxt_id) | V_CREDITS(credits));
 }
@@ -209,32 +207,36 @@ static inline int need_skb_unmap(void)
  *
  *     Unmap the main body of an sk_buff and its page fragments, if any.
  *     Because of the fairly complicated structure of our SGLs and the desire
- *     to conserve space for metadata, we keep the information necessary to
- *     unmap an sk_buff partly in the sk_buff itself (in its cb), and partly
- *     in the Tx descriptors (the physical addresses of the various data
- *     buffers).  The send functions initialize the state in skb->cb so we
- *     can unmap the buffers held in the first Tx descriptor here, and we
- *     have enough information at this point to update the state for the next
- *     Tx descriptor.
+ *     to conserve space for metadata, the information necessary to unmap an
+ *     sk_buff is spread across the sk_buff itself (buffer lengths), the HW Tx
+ *     descriptors (the physical addresses of the various data buffers), and
+ *     the SW descriptor state (assorted indices).  The send functions
+ *     initialize the indices for the first packet descriptor so we can unmap
+ *     the buffers held in the first Tx descriptor here, and we have enough
+ *     information at this point to set the state for the next Tx descriptor.
+ *
+ *     Note that it is possible to clean up the first descriptor of a packet
+ *     before the send routines have written the next descriptors, but this
+ *     race does not cause any problem.  We just end up writing the unmapping
+ *     info for the descriptor first.
  */
 static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
                             unsigned int cidx, struct pci_dev *pdev)
 {
        const struct sg_ent *sgp;
-       struct unmap_info *ui = (struct unmap_info *)skb->cb;
-       int nfrags, frag_idx, curflit, j = ui->addr_idx;
+       struct tx_sw_desc *d = &q->sdesc[cidx];
+       int nfrags, frag_idx, curflit, j = d->addr_idx;
 
-       sgp = (struct sg_ent *)&q->desc[cidx].flit[ui->sflit];
+       sgp = (struct sg_ent *)&q->desc[cidx].flit[d->sflit];
+       frag_idx = d->fragidx;
 
-       if (ui->len) {
-               pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]), ui->len,
-                                PCI_DMA_TODEVICE);
-               ui->len = 0;    /* so we know for next descriptor for this skb */
+       if (frag_idx == 0 && skb_headlen(skb)) {
+               pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]),
+                                skb_headlen(skb), PCI_DMA_TODEVICE);
                j = 1;
        }
 
-       frag_idx = ui->fragidx;
-       curflit = ui->sflit + 1 + j;
+       curflit = d->sflit + 1 + j;
        nfrags = skb_shinfo(skb)->nr_frags;
 
        while (frag_idx < nfrags && curflit < WR_FLITS) {
@@ -250,10 +252,11 @@ static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q,
                frag_idx++;
        }
 
-       if (frag_idx < nfrags) {        /* SGL continues into next Tx descriptor */
-               ui->fragidx = frag_idx;
-               ui->addr_idx = j;
-               ui->sflit = curflit - WR_FLITS - j;     /* sflit can be -1 */
+       if (frag_idx < nfrags) {   /* SGL continues into next Tx descriptor */
+               d = cidx + 1 == q->size ? q->sdesc : d + 1;
+               d->fragidx = frag_idx;
+               d->addr_idx = j;
+               d->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */
        }
 }
 
@@ -281,7 +284,7 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q,
                if (d->skb) {   /* an SGL is present */
                        if (need_unmap)
                                unmap_skb(d->skb, q, cidx, pdev);
-                       if (d->skb->priority == cidx)
+                       if (d->eop)
                                kfree_skb(d->skb);
                }
                ++d;
@@ -456,7 +459,7 @@ nomem:                              q->alloc_failed++;
                }
                q->credits++;
        }
-
+       wmb();
        t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id));
 }
 
@@ -912,15 +915,13 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
 
        sd->skb = skb;
        if (need_skb_unmap()) {
-               struct unmap_info *ui = (struct unmap_info *)skb->cb;
-
-               ui->fragidx = 0;
-               ui->addr_idx = 0;
-               ui->sflit = flits;
+               sd->fragidx = 0;
+               sd->addr_idx = 0;
+               sd->sflit = flits;
        }
 
        if (likely(ndesc == 1)) {
-               skb->priority = pidx;
+               sd->eop = 1;
                wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) |
                                   V_WR_SGLSFLT(flits)) | wr_hi;
                wmb();
@@ -948,6 +949,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
 
                        fp += avail;
                        d++;
+                       sd->eop = 0;
                        sd++;
                        if (++pidx == q->size) {
                                pidx = 0;
@@ -966,7 +968,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb,
                        wr_gen2(d, gen);
                        flits = 1;
                }
-               skb->priority = pidx;
+               sd->eop = 1;
                wrp->wr_hi |= htonl(F_WR_EOP);
                wmb();
                wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo;
@@ -1051,8 +1053,6 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
 
        sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl;
        sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev);
-       if (need_skb_unmap())
-               ((struct unmap_info *)skb->cb)->len = skb_headlen(skb);
 
        write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen,
                         htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl),
@@ -1354,6 +1354,7 @@ static void restart_ctrlq(unsigned long data)
        }
 
        spin_unlock(&q->lock);
+       wmb();
        t3_write_reg(qs->adap, A_SG_KDOORBELL,
                     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
 }
@@ -1363,7 +1364,12 @@ static void restart_ctrlq(unsigned long data)
  */
 int t3_mgmt_tx(struct adapter *adap, struct sk_buff *skb)
 {
-       return ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
+       int ret; 
+       local_bh_disable();
+       ret = ctrl_xmit(adap, &adap->sge.qs[0].txq[TXQ_CTRL], skb);
+       local_bh_enable();
+
+       return ret;
 }
 
 /**
@@ -1380,13 +1386,14 @@ static void deferred_unmap_destructor(struct sk_buff *skb)
        const dma_addr_t *p;
        const struct skb_shared_info *si;
        const struct deferred_unmap_info *dui;
-       const struct unmap_info *ui = (struct unmap_info *)skb->cb;
 
        dui = (struct deferred_unmap_info *)skb->head;
        p = dui->addr;
 
-       if (ui->len)
-               pci_unmap_single(dui->pdev, *p++, ui->len, PCI_DMA_TODEVICE);
+       if (skb->tail - skb->transport_header)
+               pci_unmap_single(dui->pdev, *p++,
+                                skb->tail - skb->transport_header,
+                                PCI_DMA_TODEVICE);
 
        si = skb_shinfo(skb);
        for (i = 0; i < si->nr_frags; i++)
@@ -1451,8 +1458,6 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
        if (need_skb_unmap()) {
                setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits);
                skb->destructor = deferred_unmap_destructor;
-               ((struct unmap_info *)skb->cb)->len = (skb->tail -
-                                                      skb->transport_header);
        }
 
        write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits,
@@ -1574,6 +1579,7 @@ static void restart_offloadq(unsigned long data)
        set_bit(TXQ_RUNNING, &q->flags);
        set_bit(TXQ_LAST_PKT_DB, &q->flags);
 #endif
+       wmb();
        t3_write_reg(adap, A_SG_KDOORBELL,
                     F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id));
 }
@@ -1739,7 +1745,6 @@ static inline int rx_offload(struct t3cdev *tdev, struct sge_rspq *rq,
                             struct sk_buff *skb, struct sk_buff *rx_gather[],
                             unsigned int gather_idx)
 {
-       rq->offload_pkts++;
        skb_reset_mac_header(skb);
        skb_reset_network_header(skb);
        skb_reset_transport_header(skb);
@@ -1809,7 +1814,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
        skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
        skb->dev->last_rx = jiffies;
        pi = netdev_priv(skb->dev);
-       if (pi->rx_csum_offload && p->csum_valid && p->csum == 0xffff &&
+       if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
            !p->fragment) {
                rspq_to_qset(rq)->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1956,7 +1961,7 @@ static int process_responses(struct adapter *adap, struct sge_qset *qs,
                int eth, ethpad = 2;
                struct sk_buff *skb = NULL;
                u32 len, flags = ntohl(r->flags);
-               u32 rss_hi = *(const u32 *)r, rss_lo = r->rss_hdr.rss_hash_val;
+               __be32 rss_hi = *(const __be32 *)r, rss_lo = r->rss_hdr.rss_hash_val;
 
                eth = r->rss_hdr.opcode == CPL_RX_PKT;
 
@@ -2033,6 +2038,7 @@ no_mem:
                        if (eth)
                                rx_eth(adap, q, skb, ethpad);
                        else {
+                               q->offload_pkts++;
                                /* Preserve the RSS info in csum & priority */
                                skb->csum = rss_hi;
                                skb->priority = rss_lo;
@@ -2442,6 +2448,15 @@ irq_handler_t t3_intr_handler(struct adapter *adap, int polling)
        return t3_intr;
 }
 
+#define SGE_PARERR (F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
+                   F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
+                   V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
+                   F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
+                   F_HIRCQPARITYERROR)
+#define SGE_FRAMINGERR (F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR)
+#define SGE_FATALERR (SGE_PARERR | SGE_FRAMINGERR | F_RSPQCREDITOVERFOW | \
+                     F_RSPQDISABLED)
+
 /**
  *     t3_sge_err_intr_handler - SGE async event interrupt handler
  *     @adapter: the adapter
@@ -2452,6 +2467,13 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
 {
        unsigned int v, status = t3_read_reg(adapter, A_SG_INT_CAUSE);
 
+       if (status & SGE_PARERR)
+               CH_ALERT(adapter, "SGE parity error (0x%x)\n",
+                        status & SGE_PARERR);
+       if (status & SGE_FRAMINGERR)
+               CH_ALERT(adapter, "SGE framing error (0x%x)\n",
+                        status & SGE_FRAMINGERR);
+
        if (status & F_RSPQCREDITOVERFOW)
                CH_ALERT(adapter, "SGE response queue credit overflow\n");
 
@@ -2468,7 +2490,7 @@ void t3_sge_err_intr_handler(struct adapter *adapter)
                         status & F_HIPIODRBDROPERR ? "high" : "lo");
 
        t3_write_reg(adapter, A_SG_INT_CAUSE, status);
-       if (status & (F_RSPQCREDITOVERFOW | F_RSPQDISABLED))
+       if (status &  SGE_FATALERR)
                t3_fatal_err(adapter);
 }
 
@@ -2780,7 +2802,7 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
        unsigned int ctrl, ups = ffs(pci_resource_len(adap->pdev, 2) >> 12);
 
        ctrl = F_DROPPKT | V_PKTSHIFT(2) | F_FLMODE | F_AVOIDCQOVFL |
-           F_CQCRDTCTRL |
+           F_CQCRDTCTRL | F_CONGMODE | F_TNLFLMODE | F_FATLPERREN |
            V_HOSTPAGESIZE(PAGE_SHIFT - 11) | F_BIGENDIANINGRESS |
            V_USERSPACESIZE(ups ? ups - 1 : 0) | F_ISCSICOALESCING;
 #if SGE_NUM_GENBITS == 1
@@ -2789,7 +2811,6 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
        if (adap->params.rev > 0) {
                if (!(adap->flags & (USING_MSIX | USING_MSI)))
                        ctrl |= F_ONEINTMULTQ | F_OPTONEINTMULTQ;
-               ctrl |= F_CQCRDTCTRL | F_AVOIDCQOVFL;
        }
        t3_write_reg(adap, A_SG_CONTROL, ctrl);
        t3_write_reg(adap, A_SG_EGR_RCQ_DRB_THRSH, V_HIRCQDRBTHRSH(512) |
@@ -2797,7 +2818,8 @@ void t3_sge_init(struct adapter *adap, struct sge_params *p)
        t3_write_reg(adap, A_SG_TIMER_TICK, core_ticks_per_usec(adap) / 10);
        t3_write_reg(adap, A_SG_CMDQ_CREDIT_TH, V_THRESHOLD(32) |
                     V_TIMEOUT(200 * core_ticks_per_usec(adap)));
-       t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH, 1000);
+       t3_write_reg(adap, A_SG_HI_DRB_HI_THRSH,
+                    adap->params.rev < T3_REV_C ? 1000 : 500);
        t3_write_reg(adap, A_SG_HI_DRB_LO_THRSH, 256);
        t3_write_reg(adap, A_SG_LO_DRB_HI_THRSH, 1000);
        t3_write_reg(adap, A_SG_LO_DRB_LO_THRSH, 256);
index 522834c42ae7e20af003101ffba1fdaf7ab0ff31..7469935877bd746370dc183ec7eaabbfc813b3da 100644 (file)
@@ -62,7 +62,7 @@ int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
                        return 0;
                }
                if (--attempts == 0)
-                       return -EAGAIN;
+                       return -EAGAIN;
                if (delay)
                        udelay(delay);
        }
@@ -537,10 +537,11 @@ struct t3_vpd {
  *     addres is written to the control register.  The hardware device will
  *     set the flag to 1 when 4 bytes have been read into the data register.
  */
-int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
+int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data)
 {
        u16 val;
        int attempts = EEPROM_MAX_POLL;
+       u32 v;
        unsigned int base = adapter->params.pci.vpd_cap_addr;
 
        if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
@@ -556,8 +557,8 @@ int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
                CH_ERR(adapter, "reading EEPROM address 0x%x failed\n", addr);
                return -EIO;
        }
-       pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, data);
-       *data = le32_to_cpu(*data);
+       pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, &v);
+       *data = cpu_to_le32(v);
        return 0;
 }
 
@@ -570,7 +571,7 @@ int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
  *     Write a 32-bit word to a location in VPD EEPROM using the card's PCI
  *     VPD ROM capability.
  */
-int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data)
+int t3_seeprom_write(struct adapter *adapter, u32 addr, __le32 data)
 {
        u16 val;
        int attempts = EEPROM_MAX_POLL;
@@ -580,7 +581,7 @@ int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data)
                return -EINVAL;
 
        pci_write_config_dword(adapter->pdev, base + PCI_VPD_DATA,
-                              cpu_to_le32(data));
+                              le32_to_cpu(data));
        pci_write_config_word(adapter->pdev,base + PCI_VPD_ADDR,
                              addr | PCI_VPD_ADDR_F);
        do {
@@ -631,14 +632,14 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
         * Card information is normally at VPD_BASE but some early cards had
         * it at 0.
         */
-       ret = t3_seeprom_read(adapter, VPD_BASE, (u32 *)&vpd);
+       ret = t3_seeprom_read(adapter, VPD_BASE, (__le32 *)&vpd);
        if (ret)
                return ret;
        addr = vpd.id_tag == 0x82 ? VPD_BASE : 0;
 
        for (i = 0; i < sizeof(vpd); i += 4) {
                ret = t3_seeprom_read(adapter, addr + i,
-                                     (u32 *)((u8 *)&vpd + i));
+                                     (__le32 *)((u8 *)&vpd + i));
                if (ret)
                        return ret;
        }
@@ -865,7 +866,7 @@ int t3_get_tp_version(struct adapter *adapter, u32 *vers)
                              1, 1, 5, 1);
        if (ret)
                return ret;
-       
+
        *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
 
        return 0;
@@ -896,7 +897,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
        major = G_TP_VERSION_MAJOR(vers);
        minor = G_TP_VERSION_MINOR(vers);
 
-       if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) 
+       if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
                return 0;
 
        if (major != TP_VERSION_MAJOR)
@@ -913,7 +914,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
 }
 
 /**
- *     t3_check_tpsram - check if provided protocol SRAM 
+ *     t3_check_tpsram - check if provided protocol SRAM
  *                       is compatible with this driver
  *     @adapter: the adapter
  *     @tp_sram: the firmware image to write
@@ -926,7 +927,7 @@ int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
 {
        u32 csum;
        unsigned int i;
-       const u32 *p = (const u32 *)tp_sram;
+       const __be32 *p = (const __be32 *)tp_sram;
 
        /* Verify checksum */
        for (csum = 0, i = 0; i < size / sizeof(csum); i++)
@@ -988,13 +989,17 @@ int t3_check_fw_version(struct adapter *adapter, int *must_load)
                CH_ERR(adapter, "found wrong FW version(%u.%u), "
                       "driver needs version %u.%u\n", major, minor,
                       FW_VERSION_MAJOR, FW_VERSION_MINOR);
-       else {
+       else if (minor < FW_VERSION_MINOR) {
                *must_load = 0;
-               CH_WARN(adapter, "found wrong FW minor version(%u.%u), "
+               CH_WARN(adapter, "found old FW minor version(%u.%u), "
                        "driver compiled for version %u.%u\n", major, minor,
                        FW_VERSION_MAJOR, FW_VERSION_MINOR);
+       } else {
+               CH_WARN(adapter, "found newer FW version(%u.%u), "
+                       "driver compiled for version %u.%u\n", major, minor,
+                       FW_VERSION_MAJOR, FW_VERSION_MINOR);
+                       return 0;
        }
-
        return -EINVAL;
 }
 
@@ -1036,7 +1041,7 @@ int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size)
 {
        u32 csum;
        unsigned int i;
-       const u32 *p = (const u32 *)fw_data;
+       const __be32 *p = (const __be32 *)fw_data;
        int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
 
        if ((size & 3) || size < FW_MIN_SIZE)
@@ -1259,7 +1264,13 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
        return fatal;
 }
 
-#define SGE_INTR_MASK (F_RSPQDISABLED)
+#define SGE_INTR_MASK (F_RSPQDISABLED | \
+                      F_UC_REQ_FRAMINGERROR | F_R_REQ_FRAMINGERROR | \
+                      F_CPPARITYERROR | F_OCPARITYERROR | F_RCPARITYERROR | \
+                      F_IRPARITYERROR | V_ITPARITYERROR(M_ITPARITYERROR) | \
+                      V_FLPARITYERROR(M_FLPARITYERROR) | F_LODRBPARITYERROR | \
+                      F_HIDRBPARITYERROR | F_LORCQPARITYERROR | \
+                      F_HIRCQPARITYERROR)
 #define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
                       F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
                       F_NFASRCHFAIL)
@@ -1276,16 +1287,23 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
 #define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\
                        F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \
                        /* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \
-                       V_BISTERR(M_BISTERR) | F_PEXERR)
-#define ULPRX_INTR_MASK F_PARERR
-#define ULPTX_INTR_MASK 0
-#define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \
+                       F_RETRYBUFPARERR | F_RETRYLUTPARERR | F_RXPARERR | \
+                       F_TXPARERR | V_BISTERR(M_BISTERR))
+#define ULPRX_INTR_MASK (F_PARERRDATA | F_PARERRPCMD | F_ARBPF1PERR | \
+                        F_ARBPF0PERR | F_ARBFPERR | F_PCMDMUXPERR | \
+                        F_DATASELFRAMEERR1 | F_DATASELFRAMEERR0)
+#define ULPTX_INTR_MASK 0xfc
+#define CPLSW_INTR_MASK (F_CIM_OP_MAP_PERR | F_TP_FRAMING_ERROR | \
                         F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \
                         F_ZERO_SWITCH_ERROR)
 #define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \
                       F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \
                       F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \
-                      F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT)
+                      F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT | \
+                      F_DRAMPARERR | F_ICACHEPARERR | F_DCACHEPARERR | \
+                      F_OBQSGEPARERR | F_OBQULPHIPARERR | F_OBQULPLOPARERR | \
+                      F_IBQSGELOPARERR | F_IBQSGEHIPARERR | F_IBQULPPARERR | \
+                      F_IBQTPPARERR | F_ITAGPARERR | F_DTAGPARERR)
 #define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \
                        V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \
                        V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR))
@@ -1354,6 +1372,10 @@ static void pcie_intr_handler(struct adapter *adapter)
                {F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1},
                {V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR),
                 "PCI MSI-X table/PBA parity error", -1, 1},
+               {F_RETRYBUFPARERR, "PCI retry buffer parity error", -1, 1},
+               {F_RETRYLUTPARERR, "PCI retry LUT parity error", -1, 1},
+               {F_RXPARERR, "PCI Rx parity error", -1, 1},
+               {F_TXPARERR, "PCI Tx parity error", -1, 1},
                {V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1},
                {0}
        };
@@ -1379,8 +1401,16 @@ static void tp_intr_handler(struct adapter *adapter)
                {0}
        };
 
+       static struct intr_info tp_intr_info_t3c[] = {
+               {0x1fffffff, "TP parity error", -1, 1},
+               {F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1},
+               {F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1},
+               {0}
+       };
+
        if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff,
-                                 tp_intr_info, NULL))
+                                 adapter->params.rev < T3_REV_C ?
+                                 tp_intr_info : tp_intr_info_t3c, NULL))
                t3_fatal_err(adapter);
 }
 
@@ -1402,6 +1432,18 @@ static void cim_intr_handler(struct adapter *adapter)
                {F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1},
                {F_BLKRDPLINT, "CIM block read from PL space", -1, 1},
                {F_BLKWRPLINT, "CIM block write to PL space", -1, 1},
+               {F_DRAMPARERR, "CIM DRAM parity error", -1, 1},
+               {F_ICACHEPARERR, "CIM icache parity error", -1, 1},
+               {F_DCACHEPARERR, "CIM dcache parity error", -1, 1},
+               {F_OBQSGEPARERR, "CIM OBQ SGE parity error", -1, 1},
+               {F_OBQULPHIPARERR, "CIM OBQ ULPHI parity error", -1, 1},
+               {F_OBQULPLOPARERR, "CIM OBQ ULPLO parity error", -1, 1},
+               {F_IBQSGELOPARERR, "CIM IBQ SGELO parity error", -1, 1},
+               {F_IBQSGEHIPARERR, "CIM IBQ SGEHI parity error", -1, 1},
+               {F_IBQULPPARERR, "CIM IBQ ULP parity error", -1, 1},
+               {F_IBQTPPARERR, "CIM IBQ TP parity error", -1, 1},
+               {F_ITAGPARERR, "CIM itag parity error", -1, 1},
+               {F_DTAGPARERR, "CIM dtag parity error", -1, 1},
                {0}
        };
 
@@ -1416,7 +1458,14 @@ static void cim_intr_handler(struct adapter *adapter)
 static void ulprx_intr_handler(struct adapter *adapter)
 {
        static const struct intr_info ulprx_intr_info[] = {
-               {F_PARERR, "ULP RX parity error", -1, 1},
+               {F_PARERRDATA, "ULP RX data parity error", -1, 1},
+               {F_PARERRPCMD, "ULP RX command parity error", -1, 1},
+               {F_ARBPF1PERR, "ULP RX ArbPF1 parity error", -1, 1},
+               {F_ARBPF0PERR, "ULP RX ArbPF0 parity error", -1, 1},
+               {F_ARBFPERR, "ULP RX ArbF parity error", -1, 1},
+               {F_PCMDMUXPERR, "ULP RX PCMDMUX parity error", -1, 1},
+               {F_DATASELFRAMEERR1, "ULP RX frame error", -1, 1},
+               {F_DATASELFRAMEERR0, "ULP RX frame error", -1, 1},
                {0}
        };
 
@@ -1435,6 +1484,7 @@ static void ulptx_intr_handler(struct adapter *adapter)
                 STAT_ULP_CH0_PBL_OOB, 0},
                {F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds",
                 STAT_ULP_CH1_PBL_OOB, 0},
+               {0xfc, "ULP TX parity error", -1, 1},
                {0}
        };
 
@@ -1509,7 +1559,8 @@ static void pmrx_intr_handler(struct adapter *adapter)
 static void cplsw_intr_handler(struct adapter *adapter)
 {
        static const struct intr_info cplsw_intr_info[] = {
-/*             { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 }, */
+               {F_CIM_OP_MAP_PERR, "CPL switch CIM parity error", -1, 1},
+               {F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1},
                {F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1},
                {F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1},
                {F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1},
@@ -1730,7 +1781,6 @@ void t3_intr_enable(struct adapter *adapter)
                 MC7_INTR_MASK},
                {A_MC5_DB_INT_ENABLE, MC5_INTR_MASK},
                {A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK},
-               {A_TP_INT_ENABLE, 0x3bfffff},
                {A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK},
                {A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK},
                {A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK},
@@ -1740,6 +1790,8 @@ void t3_intr_enable(struct adapter *adapter)
        adapter->slow_intr_mask = PL_INTR_MASK;
 
        t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0);
+       t3_write_reg(adapter, A_TP_INT_ENABLE,
+                    adapter->params.rev >= T3_REV_C ? 0x2bfffff : 0x3bfffff);
 
        if (adapter->params.rev > 0) {
                t3_write_reg(adapter, A_CPL_INTR_ENABLE,
@@ -1894,6 +1946,16 @@ static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
                               0, SG_CONTEXT_CMD_ATTEMPTS, 1);
 }
 
+static int clear_sge_ctxt(struct adapter *adap, unsigned int id,
+                         unsigned int type)
+{
+       t3_write_reg(adap, A_SG_CONTEXT_DATA0, 0);
+       t3_write_reg(adap, A_SG_CONTEXT_DATA1, 0);
+       t3_write_reg(adap, A_SG_CONTEXT_DATA2, 0);
+       t3_write_reg(adap, A_SG_CONTEXT_DATA3, 0);
+       return t3_sge_write_context(adap, id, type);
+}
+
 /**
  *     t3_sge_init_ecntxt - initialize an SGE egress context
  *     @adapter: the adapter to configure
@@ -2395,7 +2457,7 @@ static inline unsigned int pm_num_pages(unsigned int mem_size,
        t3_write_reg((adap), A_ ## reg, (start)); \
        start += size
 
-/*
+/**
  *     partition_mem - partition memory and configure TP memory settings
  *     @adap: the adapter
  *     @p: the TP parameters
@@ -2480,7 +2542,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
                     V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
                     V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
                     F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
-       t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE,
+       t3_set_reg_field(adap, A_TP_IN_CONFIG, F_RXFBARBPRIO | F_TXFBARBPRIO,
                         F_IPV6ENABLE | F_NICMODE);
        t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
        t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
@@ -2492,10 +2554,12 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
                         F_ENABLEEPCMDAFULL,
                         F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
                         F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
-       t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
+       t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL,
+                        F_ENABLEIPV6RSS | F_ENABLENONOFDTNLSYN |
+                        F_ENABLEARPMISS | F_DISBLEDAPARBIT0);
        t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
        t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
-       
+
        if (adap->params.rev > 0) {
                tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
                t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
@@ -2505,6 +2569,11 @@ static void tp_config(struct adapter *adap, const struct tp_params *p)
        } else
                t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
 
+       if (adap->params.rev == T3_REV_C)
+               t3_set_reg_field(adap, A_TP_PC_CONFIG,
+                                V_TABLELATENCYDELTA(M_TABLELATENCYDELTA),
+                                V_TABLELATENCYDELTA(4));
+
        t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
        t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
        t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
@@ -2809,15 +2878,15 @@ static void ulp_config(struct adapter *adap, const struct tp_params *p)
 int t3_set_proto_sram(struct adapter *adap, u8 *data)
 {
        int i;
-       u32 *buf = (u32 *)data;
+       __be32 *buf = (__be32 *)data;
 
        for (i = 0; i < PROTO_SRAM_LINES; i++) {
-               t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
-               t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
-               t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
-               t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
-               t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
-               
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, be32_to_cpu(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, be32_to_cpu(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, be32_to_cpu(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, be32_to_cpu(*buf++));
+               t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, be32_to_cpu(*buf++));
+
                t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
                if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
                        return -EIO;
@@ -3194,7 +3263,8 @@ static void config_pcie(struct adapter *adap)
                         V_REPLAYLMT(rpllmt));
 
        t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
-       t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN);
+       t3_set_reg_field(adap, A_PCIE_CFG, 0,
+                        F_PCIE_DMASTOPEN | F_PCIE_CLIDECEN);
 }
 
 /*
@@ -3207,7 +3277,7 @@ static void config_pcie(struct adapter *adap)
  */
 int t3_init_hw(struct adapter *adapter, u32 fw_params)
 {
-       int err = -EIO, attempts = 100;
+       int err = -EIO, attempts, i;
        const struct vpd_params *vpd = &adapter->params.vpd;
 
        if (adapter->params.rev > 0)
@@ -3225,6 +3295,10 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
                                adapter->params.mc5.nfilters,
                                adapter->params.mc5.nroutes))
                        goto out_err;
+
+               for (i = 0; i < 32; i++)
+                       if (clear_sge_ctxt(adapter, i, F_CQ))
+                               goto out_err;
        }
 
        if (tp_init(adapter, &adapter->params.tp))
@@ -3240,7 +3314,12 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
        if (is_pcie(adapter))
                config_pcie(adapter);
        else
-               t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
+               t3_set_reg_field(adapter, A_PCIX_CFG, 0,
+                                F_DMASTOPEN | F_CLIDECEN);
+
+       if (adapter->params.rev == T3_REV_C)
+               t3_set_reg_field(adapter, A_ULPTX_CONFIG, 0,
+                                F_CFG_CQE_SOP_MASK);
 
        t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
        t3_write_reg(adapter, A_PM1_RX_MODE, 0);
@@ -3253,6 +3332,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
                     V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
        t3_read_reg(adapter, A_CIM_BOOT_CFG);   /* flush */
 
+       attempts = 100;
        do {                    /* wait for uP to initialize */
                msleep(20);
        } while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
@@ -3387,6 +3467,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
        t3_write_reg(adapter, A_T3DBG_GPIO_EN,
                     ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
        t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
+       t3_write_reg(adapter, A_SG_OCO_BASE, V_BASE1(0xfff));
 
        if (adapter->params.rev == 0 || !uses_xaui(adapter))
                val |= F_ENRGMII;
@@ -3403,13 +3484,13 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
 }
 
 /*
- * Reset the adapter. 
+ * Reset the adapter.
  * Older PCIe cards lose their config space during reset, PCI-X
  * ones don't.
  */
 static int t3_reset_adapter(struct adapter *adapter)
 {
-       int i, save_and_restore_pcie = 
+       int i, save_and_restore_pcie =
            adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
        uint16_t devid = 0;
 
@@ -3436,6 +3517,36 @@ static int t3_reset_adapter(struct adapter *adapter)
        return 0;
 }
 
+static int __devinit init_parity(struct adapter *adap)
+{
+               int i, err, addr;
+
+       if (t3_read_reg(adap, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
+               return -EBUSY;
+
+       for (err = i = 0; !err && i < 16; i++)
+               err = clear_sge_ctxt(adap, i, F_EGRESS);
+       for (i = 0xfff0; !err && i <= 0xffff; i++)
+               err = clear_sge_ctxt(adap, i, F_EGRESS);
+       for (i = 0; !err && i < SGE_QSETS; i++)
+               err = clear_sge_ctxt(adap, i, F_RESPONSEQ);
+       if (err)
+               return err;
+
+       t3_write_reg(adap, A_CIM_IBQ_DBG_DATA, 0);
+       for (i = 0; i < 4; i++)
+               for (addr = 0; addr <= M_IBQDBGADDR; addr++) {
+                       t3_write_reg(adap, A_CIM_IBQ_DBG_CFG, F_IBQDBGEN |
+                                    F_IBQDBGWR | V_IBQDBGQID(i) |
+                                    V_IBQDBGADDR(addr));
+                       err = t3_wait_op_done(adap, A_CIM_IBQ_DBG_CFG,
+                                             F_IBQDBGBUSY, 0, 2, 1);
+                       if (err)
+                               return err;
+               }
+       return 0;
+}
+
 /*
  * Initialize adapter SW state for the various HW modules, set initial values
  * for some adapter tunables, take PHYs out of reset, and initialize the MDIO
@@ -3503,6 +3614,9 @@ int __devinit t3_prep_adapter(struct adapter *adapter,
        }
 
        early_hw_init(adapter, ai);
+       ret = init_parity(adapter);
+       if (ret)
+               return ret;
 
        for_each_port(adapter, i) {
                u8 hw_addr[6];
index ef1c6339c80607437dee90ce103257c5114df7c8..229303ff6a39016c0fd3823d7e5212ecc77fcaff 100644 (file)
@@ -38,7 +38,7 @@
 #define DRV_VERSION "1.0-ko"
 
 /* Firmware version */
-#define FW_VERSION_MAJOR 4
-#define FW_VERSION_MINOR 6
+#define FW_VERSION_MAJOR 5
+#define FW_VERSION_MINOR 0
 #define FW_VERSION_MICRO 0
 #endif                         /* __CHELSIO_VERSION_H */
index efcf09a709cf899c0a3fabdd63cf5daff82e5b76..ffdc0a1892bd2334ed770647ea5c82a8ba498645 100644 (file)
@@ -153,7 +153,7 @@ static int t3b2_mac_reset(struct cmac *mac)
        unsigned int oft = mac->offset;
        u32 val;
 
-       if (!macidx(mac)) 
+       if (!macidx(mac))
                t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0);
        else
                t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0);
@@ -187,11 +187,11 @@ static int t3b2_mac_reset(struct cmac *mac)
                msleep(1);
                t3b_pcs_reset(mac);
        }
-       t3_write_reg(adap, A_XGM_RX_CFG + oft, 
+       t3_write_reg(adap, A_XGM_RX_CFG + oft,
                     F_DISPAUSEFRAMES | F_EN1536BFRAMES |
                     F_RMFCS | F_ENJUMBO | F_ENHASHMCAST);
 
-       if (!macidx(mac)) 
+       if (!macidx(mac))
                t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE);
        else
                t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE);
@@ -336,7 +336,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu)
         * Adjust the PAUSE frame watermarks.  We always set the LWM, and the
         * HWM only if flow-control is enabled.
         */
-       hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, 
+       hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu,
                    MAC_RXFIFO_SIZE * 38 / 100);
        hwm = min(hwm, MAC_RXFIFO_SIZE - 8192);
        lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4);
@@ -449,7 +449,7 @@ int t3_mac_enable(struct cmac *mac, int which)
        struct adapter *adap = mac->adapter;
        unsigned int oft = mac->offset;
        struct mac_stats *s = &mac->stats;
-       
+
        if (which & MAC_DIRECTION_TX) {
                t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
                t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401);
index 00e0194bfef005acea333ed70dd6db7aacc36d37..6b1e77cc069e989b5d48b71911b03f5ed3ddf1f5 100644 (file)
@@ -719,15 +719,15 @@ out:
        spin_unlock(&lp->lock);
 }
 
-static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id)
+static irqreturn_t lance_dma_merr_int(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
 
-       printk("%s: DMA error\n", dev->name);
+       printk(KERN_ERR "%s: DMA error\n", dev->name);
        return IRQ_HANDLED;
 }
 
-static irqreturn_t lance_interrupt(const int irq, void *dev_id)
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
index b87402bc83081fd808681b16166b25b1c20a2020..51cf577035bed0c466a45a4470102c3db56ef6db 100644 (file)
  *     the RFD, the RFD must be dma_sync'ed to maintain a consistent
  *     view from software and hardware.
  *
+ *     In order to keep updates to the RFD link field from colliding with
+ *     hardware writes to mark packets complete, we use the feature that
+ *     hardware will not write to a size 0 descriptor and mark the previous
+ *     packet as end-of-list (EL).   After updating the link, we remove EL
+ *     and only then restore the size such that hardware may use the
+ *     previous-to-end RFD.
+ *
  *     Under typical operation, the  receive unit (RU) is start once,
  *     and the controller happily fills RFDs as frames arrive.  If
  *     replacement RFDs cannot be allocated, or the RU goes non-active,
@@ -281,6 +288,7 @@ struct csr {
 };
 
 enum scb_status {
+       rus_no_res       = 0x08,
        rus_ready        = 0x10,
        rus_mask         = 0x3C,
 };
@@ -393,12 +401,12 @@ enum cb_command {
 };
 
 struct rfd {
-       u16 status;
-       u16 command;
-       u32 link;
-       u32 rbd;
-       u16 actual_size;
-       u16 size;
+       __le16 status;
+       __le16 command;
+       __le32 link;
+       __le32 rbd;
+       __le16 actual_size;
+       __le16 size;
 };
 
 struct rx {
@@ -453,19 +461,19 @@ struct config {
 
 #define E100_MAX_MULTICAST_ADDRS       64
 struct multi {
-       u16 count;
+       __le16 count;
        u8 addr[E100_MAX_MULTICAST_ADDRS * ETH_ALEN + 2/*pad*/];
 };
 
 /* Important: keep total struct u32-aligned */
 #define UCODE_SIZE                     134
 struct cb {
-       u16 status;
-       u16 command;
-       u32 link;
+       __le16 status;
+       __le16 command;
+       __le32 link;
        union {
                u8 iaaddr[ETH_ALEN];
-               u32 ucode[UCODE_SIZE];
+               __le32 ucode[UCODE_SIZE];
                struct config config;
                struct multi multi;
                struct {
@@ -474,12 +482,12 @@ struct cb {
                        u8 threshold;
                        u8 tbd_count;
                        struct {
-                               u32 buf_addr;
-                               u16 size;
+                               __le32 buf_addr;
+                               __le16 size;
                                u16 eol;
                        } tbd;
                } tcb;
-               u32 dump_buffer_addr;
+               __le32 dump_buffer_addr;
        } u;
        struct cb *next, *prev;
        dma_addr_t dma_addr;
@@ -491,15 +499,15 @@ enum loopback {
 };
 
 struct stats {
-       u32 tx_good_frames, tx_max_collisions, tx_late_collisions,
+       __le32 tx_good_frames, tx_max_collisions, tx_late_collisions,
                tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
                tx_multiple_collisions, tx_total_collisions;
-       u32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
+       __le32 rx_good_frames, rx_crc_errors, rx_alignment_errors,
                rx_resource_errors, rx_overrun_errors, rx_cdt_errors,
                rx_short_frame_errors;
-       u32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
-       u16 xmt_tco_frames, rcv_tco_frames;
-       u32 complete;
+       __le32 fc_xmt_pause, fc_rcv_pause, fc_rcv_unsupported;
+       __le16 xmt_tco_frames, rcv_tco_frames;
+       __le32 complete;
 };
 
 struct mem {
@@ -544,7 +552,7 @@ struct nic {
        struct cb *cb_to_use;
        struct cb *cb_to_send;
        struct cb *cb_to_clean;
-       u16 tx_command;
+       __le16 tx_command;
        /* End: frequently used values: keep adjacent for cache effect */
 
        enum {
@@ -585,7 +593,7 @@ struct nic {
 
        u16 leds;
        u16 eeprom_wc;
-       u16 eeprom[256];
+       __le16 eeprom[256];
        spinlock_t mdio_lock;
 };
 
@@ -663,7 +671,7 @@ static int e100_self_test(struct nic *nic)
        return 0;
 }
 
-static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
+static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, __le16 data)
 {
        u32 cmd_addr_data[3];
        u8 ctrl;
@@ -672,7 +680,7 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
        /* Three cmds: write/erase enable, write data, write/erase disable */
        cmd_addr_data[0] = op_ewen << (addr_len - 2);
        cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) |
-               cpu_to_le16(data);
+               le16_to_cpu(data);
        cmd_addr_data[2] = op_ewds << (addr_len - 2);
 
        /* Bit-bang cmds to write word to eeprom */
@@ -701,7 +709,7 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
 };
 
 /* General technique stolen from the eepro100 driver - very clever */
-static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
+static __le16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
 {
        u32 cmd_addr_data;
        u16 data = 0;
@@ -738,7 +746,7 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
        iowrite8(0, &nic->csr->eeprom_ctrl_lo);
        e100_write_flush(nic); udelay(4);
 
-       return le16_to_cpu(data);
+       return cpu_to_le16(data);
 };
 
 /* Load entire EEPROM image into driver cache and validate checksum */
@@ -753,13 +761,12 @@ static int e100_eeprom_load(struct nic *nic)
        for(addr = 0; addr < nic->eeprom_wc; addr++) {
                nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr);
                if(addr < nic->eeprom_wc - 1)
-                       checksum += cpu_to_le16(nic->eeprom[addr]);
+                       checksum += le16_to_cpu(nic->eeprom[addr]);
        }
 
        /* The checksum, stored in the last word, is calculated such that
         * the sum of words should be 0xBABA */
-       checksum = le16_to_cpu(0xBABA - checksum);
-       if(checksum != nic->eeprom[nic->eeprom_wc - 1]) {
+       if (cpu_to_le16(0xBABA - checksum) != nic->eeprom[nic->eeprom_wc - 1]) {
                DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
                if (!eeprom_bad_csum_allow)
                        return -EAGAIN;
@@ -786,8 +793,8 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
        /* The checksum, stored in the last word, is calculated such that
         * the sum of words should be 0xBABA */
        for(addr = 0; addr < nic->eeprom_wc - 1; addr++)
-               checksum += cpu_to_le16(nic->eeprom[addr]);
-       nic->eeprom[nic->eeprom_wc - 1] = le16_to_cpu(0xBABA - checksum);
+               checksum += le16_to_cpu(nic->eeprom[addr]);
+       nic->eeprom[nic->eeprom_wc - 1] = cpu_to_le16(0xBABA - checksum);
        e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1,
                nic->eeprom[nic->eeprom_wc - 1]);
 
@@ -952,7 +959,7 @@ static void e100_get_defaults(struct nic *nic)
                ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
 
        /* Template for a freshly allocated RFD */
-       nic->blank_rfd.command = cpu_to_le16(cb_el);
+       nic->blank_rfd.command = 0;
        nic->blank_rfd.rbd = 0xFFFFFFFF;
        nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
 
@@ -1485,15 +1492,15 @@ static void e100_update_stats(struct nic *nic)
        struct net_device *dev = nic->netdev;
        struct net_device_stats *ns = &dev->stats;
        struct stats *s = &nic->mem->stats;
-       u32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
-               (nic->mac < mac_82559_D101M) ? (u32 *)&s->xmt_tco_frames :
+       __le32 *complete = (nic->mac < mac_82558_D101_A4) ? &s->fc_xmt_pause :
+               (nic->mac < mac_82559_D101M) ? (__le32 *)&s->xmt_tco_frames :
                &s->complete;
 
        /* Device's stats reporting may take several microseconds to
         * complete, so where always waiting for results of the
         * previous command. */
 
-       if(*complete == le32_to_cpu(cuc_dump_reset_complete)) {
+       if(*complete == cpu_to_le32(cuc_dump_reset_complete)) {
                *complete = 0;
                nic->tx_frames = le32_to_cpu(s->tx_good_frames);
                nic->tx_collisions = le32_to_cpu(s->tx_total_collisions);
@@ -1783,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
        rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
                RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
 
-       if(pci_dma_mapping_error(rx->dma_addr)) {
+       if (pci_dma_mapping_error(rx->dma_addr)) {
                dev_kfree_skb_any(rx->skb);
                rx->skb = NULL;
                rx->dma_addr = 0;
@@ -1791,15 +1798,11 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
        }
 
        /* Link the RFD to end of RFA by linking previous RFD to
-        * this one, and clearing EL bit of previous.  */
-       if(rx->prev->skb) {
+        * this one.  We are safe to touch the previous RFD because
+        * it is protected by the before last buffer's el bit being set */
+       if (rx->prev->skb) {
                struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
-               put_unaligned(cpu_to_le32(rx->dma_addr),
-                       (u32 *)&prev_rfd->link);
-               wmb();
-               prev_rfd->command &= ~cpu_to_le16(cb_el);
-               pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
-                       sizeof(struct rfd), PCI_DMA_TODEVICE);
+               put_unaligned(cpu_to_le32(rx->dma_addr), &prev_rfd->link);
        }
 
        return 0;
@@ -1824,8 +1827,19 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
        DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
 
        /* If data isn't ready, nothing to indicate */
-       if(unlikely(!(rfd_status & cb_complete)))
+       if (unlikely(!(rfd_status & cb_complete))) {
+               /* If the next buffer has the el bit, but we think the receiver
+                * is still running, check to see if it really stopped while
+                * we had interrupts off.
+                * This allows for a fast restart without re-enabling
+                * interrupts */
+               if ((le16_to_cpu(rfd->command) & cb_el) &&
+                   (RU_RUNNING == nic->ru_running))
+
+                       if (readb(&nic->csr->scb.status) & rus_no_res)
+                               nic->ru_running = RU_SUSPENDED;
                return -ENODATA;
+       }
 
        /* Get actual data size */
        actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
@@ -1836,9 +1850,18 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
        pci_unmap_single(nic->pdev, rx->dma_addr,
                RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
 
-       /* this allows for a fast restart without re-enabling interrupts */
-       if(le16_to_cpu(rfd->command) & cb_el)
+       /* If this buffer has the el bit, but we think the receiver
+        * is still running, check to see if it really stopped while
+        * we had interrupts off.
+        * This allows for a fast restart without re-enabling interrupts.
+        * This can happen when the RU sees the size change but also sees
+        * the el bit set. */
+       if ((le16_to_cpu(rfd->command) & cb_el) &&
+           (RU_RUNNING == nic->ru_running)) {
+
+           if (readb(&nic->csr->scb.status) & rus_no_res)
                nic->ru_running = RU_SUSPENDED;
+       }
 
        /* Pull off the RFD and put the actual data (minus eth hdr) */
        skb_reserve(skb, sizeof(struct rfd));
@@ -1870,31 +1893,30 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
        unsigned int work_to_do)
 {
        struct rx *rx;
-       int restart_required = 0;
-       struct rx *rx_to_start = NULL;
-
-       /* are we already rnr? then pay attention!!! this ensures that
-        * the state machine progression never allows a start with a
-        * partially cleaned list, avoiding a race between hardware
-        * and rx_to_clean when in NAPI mode */
-       if(RU_SUSPENDED == nic->ru_running)
-               restart_required = 1;
+       int restart_required = 0, err = 0;
+       struct rx *old_before_last_rx, *new_before_last_rx;
+       struct rfd *old_before_last_rfd, *new_before_last_rfd;
 
        /* Indicate newly arrived packets */
        for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) {
-               int err = e100_rx_indicate(nic, rx, work_done, work_to_do);
-               if(-EAGAIN == err) {
-                       /* hit quota so have more work to do, restart once
-                        * cleanup is complete */
-                       restart_required = 0;
+               err = e100_rx_indicate(nic, rx, work_done, work_to_do);
+               /* Hit quota or no more to clean */
+               if (-EAGAIN == err || -ENODATA == err)
                        break;
-               } else if(-ENODATA == err)
-                       break; /* No more to clean */
        }
 
-       /* save our starting point as the place we'll restart the receiver */
-       if(restart_required)
-               rx_to_start = nic->rx_to_clean;
+
+       /* On EAGAIN, hit quota so have more work to do, restart once
+        * cleanup is complete.
+        * Else, are we already rnr? then pay attention!!! this ensures that
+        * the state machine progression never allows a start with a
+        * partially cleaned list, avoiding a race between hardware
+        * and rx_to_clean when in NAPI mode */
+       if (-EAGAIN != err && RU_SUSPENDED == nic->ru_running)
+               restart_required = 1;
+
+       old_before_last_rx = nic->rx_to_use->prev->prev;
+       old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data;
 
        /* Alloc new skbs to refill list */
        for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) {
@@ -1902,10 +1924,42 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done,
                        break; /* Better luck next time (see watchdog) */
        }
 
+       new_before_last_rx = nic->rx_to_use->prev->prev;
+       if (new_before_last_rx != old_before_last_rx) {
+               /* Set the el-bit on the buffer that is before the last buffer.
+                * This lets us update the next pointer on the last buffer
+                * without worrying about hardware touching it.
+                * We set the size to 0 to prevent hardware from touching this
+                * buffer.
+                * When the hardware hits the before last buffer with el-bit
+                * and size of 0, it will RNR interrupt, the RUS will go into
+                * the No Resources state.  It will not complete nor write to
+                * this buffer. */
+               new_before_last_rfd =
+                       (struct rfd *)new_before_last_rx->skb->data;
+               new_before_last_rfd->size = 0;
+               new_before_last_rfd->command |= cpu_to_le16(cb_el);
+               pci_dma_sync_single_for_device(nic->pdev,
+                       new_before_last_rx->dma_addr, sizeof(struct rfd),
+                       PCI_DMA_TODEVICE);
+
+               /* Now that we have a new stopping point, we can clear the old
+                * stopping point.  We must sync twice to get the proper
+                * ordering on the hardware side of things. */
+               old_before_last_rfd->command &= ~cpu_to_le16(cb_el);
+               pci_dma_sync_single_for_device(nic->pdev,
+                       old_before_last_rx->dma_addr, sizeof(struct rfd),
+                       PCI_DMA_TODEVICE);
+               old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
+               pci_dma_sync_single_for_device(nic->pdev,
+                       old_before_last_rx->dma_addr, sizeof(struct rfd),
+                       PCI_DMA_TODEVICE);
+       }
+
        if(restart_required) {
                // ack the rnr?
                writeb(stat_ack_rnr, &nic->csr->scb.stat_ack);
-               e100_start_receiver(nic, rx_to_start);
+               e100_start_receiver(nic, nic->rx_to_clean);
                if(work_done)
                        (*work_done)++;
        }
@@ -1937,6 +1991,7 @@ static int e100_rx_alloc_list(struct nic *nic)
 {
        struct rx *rx;
        unsigned int i, count = nic->params.rfds.count;
+       struct rfd *before_last;
 
        nic->rx_to_use = nic->rx_to_clean = NULL;
        nic->ru_running = RU_UNINITIALIZED;
@@ -1952,6 +2007,19 @@ static int e100_rx_alloc_list(struct nic *nic)
                        return -ENOMEM;
                }
        }
+       /* Set the el-bit on the buffer that is before the last buffer.
+        * This lets us update the next pointer on the last buffer without
+        * worrying about hardware touching it.
+        * We set the size to 0 to prevent hardware from touching this buffer.
+        * When the hardware hits the before last buffer with el-bit and size
+        * of 0, it will RNR interrupt, the RU will go into the No Resources
+        * state.  It will not complete nor write to this buffer. */
+       rx = nic->rxs->prev->prev;
+       before_last = (struct rfd *)rx->skb->data;
+       before_last->command |= cpu_to_le16(cb_el);
+       before_last->size = 0;
+       pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
+               sizeof(struct rfd), PCI_DMA_TODEVICE);
 
        nic->rx_to_use = nic->rx_to_clean = nic->rxs;
        nic->ru_running = RU_SUSPENDED;
@@ -2369,7 +2437,7 @@ static const char e100_gstrings_test[][ETH_GSTRING_LEN] = {
        "Mac loopback     (offline)",
        "Phy loopback     (offline)",
 };
-#define E100_TEST_LEN  sizeof(e100_gstrings_test) / ETH_GSTRING_LEN
+#define E100_TEST_LEN  ARRAY_SIZE(e100_gstrings_test)
 
 static void e100_diag_test(struct net_device *netdev,
        struct ethtool_test *test, u64 *data)
@@ -2431,7 +2499,7 @@ static const char e100_gstrings_stats[][ETH_GSTRING_LEN] = {
        "rx_flow_control_unsupported", "tx_tco_packets", "rx_tco_packets",
 };
 #define E100_NET_STATS_LEN     21
-#define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN
+#define E100_STATS_LEN ARRAY_SIZE(e100_gstrings_stats)
 
 static int e100_get_sset_count(struct net_device *netdev, int sset)
 {
index b83ccce8a9b7d35572ddd85d4810f3c851c64b27..d876787ce336e51aa76c0d32dd7998ce97b9b538 100644 (file)
@@ -110,7 +110,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
        "Interrupt test (offline)", "Loopback test  (offline)",
        "Link test   (on/offline)"
 };
-#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
+#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
 
 static int
 e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
@@ -728,39 +728,65 @@ err_setup:
        return err;
 }
 
-#define REG_PATTERN_TEST(R, M, W)                                              \
-{                                                                              \
-       uint32_t pat, val;                                                     \
-       const uint32_t test[] =                                                \
-               {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};              \
-       for (pat = 0; pat < ARRAY_SIZE(test); pat++) {                         \
-               E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W));             \
-               val = E1000_READ_REG(&adapter->hw, R);                         \
-               if (val != (test[pat] & W & M)) {                              \
-                       DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
-                               "0x%08X expected 0x%08X\n",                    \
-                               E1000_##R, val, (test[pat] & W & M));          \
-                       *data = (adapter->hw.mac_type < e1000_82543) ?         \
-                               E1000_82542_##R : E1000_##R;                   \
-                       return 1;                                              \
-               }                                                              \
-       }                                                                      \
+static bool reg_pattern_test(struct e1000_adapter *adapter, uint64_t *data,
+                            int reg, uint32_t mask, uint32_t write)
+{
+       static const uint32_t test[] =
+               {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+       uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+       uint32_t read;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(test); i++) {
+               writel(write & test[i], address);
+               read = readl(address);
+               if (read != (write & test[i] & mask)) {
+                       DPRINTK(DRV, ERR, "pattern test reg %04X failed: "
+                               "got 0x%08X expected 0x%08X\n",
+                               reg, read, (write & test[i] & mask));
+                       *data = reg;
+                       return true;
+               }
+       }
+       return false;
 }
 
-#define REG_SET_AND_CHECK(R, M, W)                                             \
-{                                                                              \
-       uint32_t val;                                                          \
-       E1000_WRITE_REG(&adapter->hw, R, W & M);                               \
-       val = E1000_READ_REG(&adapter->hw, R);                                 \
-       if ((W & M) != (val & M)) {                                            \
-               DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
-                       "expected 0x%08X\n", E1000_##R, (val & M), (W & M));   \
-               *data = (adapter->hw.mac_type < e1000_82543) ?                 \
-                       E1000_82542_##R : E1000_##R;                           \
-               return 1;                                                      \
-       }                                                                      \
+static bool reg_set_and_check(struct e1000_adapter *adapter, uint64_t *data,
+                             int reg, uint32_t mask, uint32_t write)
+{
+       uint8_t __iomem *address = adapter->hw.hw_addr + reg;
+       uint32_t read;
+
+       writel(write & mask, address);
+       read = readl(address);
+       if ((read & mask) != (write & mask)) {
+               DPRINTK(DRV, ERR, "set/check reg %04X test failed: "
+                       "got 0x%08X expected 0x%08X\n",
+                       reg, (read & mask), (write & mask));
+               *data = reg;
+               return true;
+       }
+       return false;
 }
 
+#define REG_PATTERN_TEST(reg, mask, write)                          \
+       do {                                                         \
+               if (reg_pattern_test(adapter, data,                  \
+                            (adapter->hw.mac_type >= e1000_82543)   \
+                            ? E1000_##reg : E1000_82542_##reg,      \
+                            mask, write))                           \
+                       return 1;                                    \
+       } while (0)
+
+#define REG_SET_AND_CHECK(reg, mask, write)                         \
+       do {                                                         \
+               if (reg_set_and_check(adapter, data,                 \
+                             (adapter->hw.mac_type >= e1000_82543)  \
+                             ? E1000_##reg : E1000_82542_##reg,     \
+                             mask, write))                          \
+                       return 1;                                    \
+       } while (0)
+
 static int
 e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
 {
index a2a86c54a75cae76eb83f3c7e13c2f18e5523d68..a6c3c34feb9889a6f8773abce02c08865a8b886d 100644 (file)
@@ -421,8 +421,6 @@ void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, u
 void e1000_get_bus_info(struct e1000_hw *hw);
 void e1000_pci_set_mwi(struct e1000_hw *hw);
 void e1000_pci_clear_mwi(struct e1000_hw *hw);
-void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
-void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
 void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc);
 int e1000_pcix_get_mmrbc(struct e1000_hw *hw);
@@ -595,35 +593,35 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
 
 /* Receive Descriptor */
 struct e1000_rx_desc {
-    uint64_t buffer_addr; /* Address of the descriptor's data buffer */
-    uint16_t length;     /* Length of data DMAed into data buffer */
-    uint16_t csum;       /* Packet checksum */
+    __le64 buffer_addr; /* Address of the descriptor's data buffer */
+    __le16 length;     /* Length of data DMAed into data buffer */
+    __le16 csum;       /* Packet checksum */
     uint8_t status;      /* Descriptor status */
     uint8_t errors;      /* Descriptor Errors */
-    uint16_t special;
+    __le16 special;
 };
 
 /* Receive Descriptor - Extended */
 union e1000_rx_desc_extended {
     struct {
-        uint64_t buffer_addr;
-        uint64_t reserved;
+        __le64 buffer_addr;
+        __le64 reserved;
     } read;
     struct {
         struct {
-            uint32_t mrq;              /* Multiple Rx Queues */
+            __le32 mrq;              /* Multiple Rx Queues */
             union {
-                uint32_t rss;          /* RSS Hash */
+                __le32 rss;          /* RSS Hash */
                 struct {
-                    uint16_t ip_id;    /* IP id */
-                    uint16_t csum;     /* Packet Checksum */
+                    __le16 ip_id;    /* IP id */
+                    __le16 csum;     /* Packet Checksum */
                 } csum_ip;
             } hi_dword;
         } lower;
         struct {
-            uint32_t status_error;     /* ext status/error */
-            uint16_t length;
-            uint16_t vlan;             /* VLAN tag */
+            __le32 status_error;     /* ext status/error */
+            __le16 length;
+            __le16 vlan;             /* VLAN tag */
         } upper;
     } wb;  /* writeback */
 };
@@ -633,29 +631,29 @@ union e1000_rx_desc_extended {
 union e1000_rx_desc_packet_split {
     struct {
         /* one buffer for protocol header(s), three data buffers */
-        uint64_t buffer_addr[MAX_PS_BUFFERS];
+        __le64 buffer_addr[MAX_PS_BUFFERS];
     } read;
     struct {
         struct {
-            uint32_t mrq;              /* Multiple Rx Queues */
+            __le32 mrq;              /* Multiple Rx Queues */
             union {
-                uint32_t rss;          /* RSS Hash */
+                __le32 rss;          /* RSS Hash */
                 struct {
-                    uint16_t ip_id;    /* IP id */
-                    uint16_t csum;     /* Packet Checksum */
+                    __le16 ip_id;    /* IP id */
+                    __le16 csum;     /* Packet Checksum */
                 } csum_ip;
             } hi_dword;
         } lower;
         struct {
-            uint32_t status_error;     /* ext status/error */
-            uint16_t length0;          /* length of buffer 0 */
-            uint16_t vlan;             /* VLAN tag */
+            __le32 status_error;     /* ext status/error */
+            __le16 length0;          /* length of buffer 0 */
+            __le16 vlan;             /* VLAN tag */
         } middle;
         struct {
-            uint16_t header_status;
-            uint16_t length[3];        /* length of buffers 1-3 */
+            __le16 header_status;
+            __le16 length[3];        /* length of buffers 1-3 */
         } upper;
-        uint64_t reserved;
+        __le64 reserved;
     } wb; /* writeback */
 };
 
@@ -715,21 +713,21 @@ union e1000_rx_desc_packet_split {
 
 /* Transmit Descriptor */
 struct e1000_tx_desc {
-    uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
+    __le64 buffer_addr;       /* Address of the descriptor's data buffer */
     union {
-        uint32_t data;
+        __le32 data;
         struct {
-            uint16_t length;    /* Data buffer length */
+            __le16 length;    /* Data buffer length */
             uint8_t cso;        /* Checksum offset */
             uint8_t cmd;        /* Descriptor control */
         } flags;
     } lower;
     union {
-        uint32_t data;
+        __le32 data;
         struct {
             uint8_t status;     /* Descriptor status */
             uint8_t css;        /* Checksum start */
-            uint16_t special;
+            __le16 special;
         } fields;
     } upper;
 };
@@ -759,49 +757,49 @@ struct e1000_tx_desc {
 /* Offload Context Descriptor */
 struct e1000_context_desc {
     union {
-        uint32_t ip_config;
+        __le32 ip_config;
         struct {
             uint8_t ipcss;      /* IP checksum start */
             uint8_t ipcso;      /* IP checksum offset */
-            uint16_t ipcse;     /* IP checksum end */
+            __le16 ipcse;     /* IP checksum end */
         } ip_fields;
     } lower_setup;
     union {
-        uint32_t tcp_config;
+        __le32 tcp_config;
         struct {
             uint8_t tucss;      /* TCP checksum start */
             uint8_t tucso;      /* TCP checksum offset */
-            uint16_t tucse;     /* TCP checksum end */
+            __le16 tucse;     /* TCP checksum end */
         } tcp_fields;
     } upper_setup;
-    uint32_t cmd_and_length;    /* */
+    __le32 cmd_and_length;    /* */
     union {
-        uint32_t data;
+        __le32 data;
         struct {
             uint8_t status;     /* Descriptor status */
             uint8_t hdr_len;    /* Header length */
-            uint16_t mss;       /* Maximum segment size */
+            __le16 mss;       /* Maximum segment size */
         } fields;
     } tcp_seg_setup;
 };
 
 /* Offload data descriptor */
 struct e1000_data_desc {
-    uint64_t buffer_addr;       /* Address of the descriptor's buffer address */
+    __le64 buffer_addr;       /* Address of the descriptor's buffer address */
     union {
-        uint32_t data;
+        __le32 data;
         struct {
-            uint16_t length;    /* Data buffer length */
+            __le16 length;    /* Data buffer length */
             uint8_t typ_len_ext;        /* */
             uint8_t cmd;        /* */
         } flags;
     } lower;
     union {
-        uint32_t data;
+        __le32 data;
         struct {
             uint8_t status;     /* Descriptor status */
             uint8_t popts;      /* Packet Options */
-            uint16_t special;   /* */
+            __le16 special;   /* */
         } fields;
     } upper;
 };
@@ -817,8 +815,8 @@ struct e1000_data_desc {
 
 /* Receive Address Register */
 struct e1000_rar {
-    volatile uint32_t low;      /* receive address low */
-    volatile uint32_t high;     /* receive address high */
+    volatile __le32 low;      /* receive address low */
+    volatile __le32 high;     /* receive address high */
 };
 
 /* Number of entries in the Multicast Table Array (MTA). */
index 76c0fa690cc6adb60e0ab94d1e4cf7cbb6cbb00f..7f5b2ae70d5d56cdc056fe2a15daceb63d75a537 100644 (file)
@@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x1026),
        INTEL_E1000_ETHERNET_DEVICE(0x1027),
        INTEL_E1000_ETHERNET_DEVICE(0x1028),
-       INTEL_E1000_ETHERNET_DEVICE(0x1049),
-       INTEL_E1000_ETHERNET_DEVICE(0x104A),
-       INTEL_E1000_ETHERNET_DEVICE(0x104B),
-       INTEL_E1000_ETHERNET_DEVICE(0x104C),
-       INTEL_E1000_ETHERNET_DEVICE(0x104D),
-       INTEL_E1000_ETHERNET_DEVICE(0x105E),
-       INTEL_E1000_ETHERNET_DEVICE(0x105F),
-       INTEL_E1000_ETHERNET_DEVICE(0x1060),
        INTEL_E1000_ETHERNET_DEVICE(0x1075),
        INTEL_E1000_ETHERNET_DEVICE(0x1076),
        INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = {
        INTEL_E1000_ETHERNET_DEVICE(0x107A),
        INTEL_E1000_ETHERNET_DEVICE(0x107B),
        INTEL_E1000_ETHERNET_DEVICE(0x107C),
-       INTEL_E1000_ETHERNET_DEVICE(0x107D),
-       INTEL_E1000_ETHERNET_DEVICE(0x107E),
-       INTEL_E1000_ETHERNET_DEVICE(0x107F),
        INTEL_E1000_ETHERNET_DEVICE(0x108A),
-       INTEL_E1000_ETHERNET_DEVICE(0x108B),
-       INTEL_E1000_ETHERNET_DEVICE(0x108C),
-       INTEL_E1000_ETHERNET_DEVICE(0x1096),
-       INTEL_E1000_ETHERNET_DEVICE(0x1098),
        INTEL_E1000_ETHERNET_DEVICE(0x1099),
-       INTEL_E1000_ETHERNET_DEVICE(0x109A),
-       INTEL_E1000_ETHERNET_DEVICE(0x10A4),
-       INTEL_E1000_ETHERNET_DEVICE(0x10A5),
        INTEL_E1000_ETHERNET_DEVICE(0x10B5),
-       INTEL_E1000_ETHERNET_DEVICE(0x10B9),
-       INTEL_E1000_ETHERNET_DEVICE(0x10BA),
-       INTEL_E1000_ETHERNET_DEVICE(0x10BB),
-       INTEL_E1000_ETHERNET_DEVICE(0x10BC),
-       INTEL_E1000_ETHERNET_DEVICE(0x10C4),
-       INTEL_E1000_ETHERNET_DEVICE(0x10C5),
-       INTEL_E1000_ETHERNET_DEVICE(0x10D5),
-       INTEL_E1000_ETHERNET_DEVICE(0x10D9),
-       INTEL_E1000_ETHERNET_DEVICE(0x10DA),
        /* required last entry */
        {0,}
 };
@@ -153,7 +126,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
                                 struct e1000_tx_ring *tx_ring);
 static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
                                 struct e1000_rx_ring *rx_ring);
-static void e1000_set_multi(struct net_device *netdev);
+static void e1000_set_rx_mode(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static void e1000_82547_tx_fifo_stall(unsigned long data);
@@ -299,14 +272,14 @@ module_exit(e1000_exit_module);
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       void (*handler) = &e1000_intr;
+       irq_handler_t handler = e1000_intr;
        int irq_flags = IRQF_SHARED;
        int err;
 
        if (adapter->hw.mac_type >= e1000_82571) {
                adapter->have_msi = !pci_enable_msi(adapter->pdev);
                if (adapter->have_msi) {
-                       handler = &e1000_intr_msi;
+                       handler = e1000_intr_msi;
                        irq_flags = 0;
                }
        }
@@ -514,7 +487,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        int i;
 
-       e1000_set_multi(netdev);
+       e1000_set_rx_mode(netdev);
 
        e1000_restore_vlan(adapter);
        e1000_init_manageability(adapter);
@@ -844,6 +817,64 @@ e1000_reset(struct e1000_adapter *adapter)
        e1000_release_manageability(adapter);
 }
 
+/**
+ *  Dump the eeprom for users having checksum issues
+ **/
+void e1000_dump_eeprom(struct e1000_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct ethtool_eeprom eeprom;
+       const struct ethtool_ops *ops = netdev->ethtool_ops;
+       u8 *data;
+       int i;
+       u16 csum_old, csum_new = 0;
+
+       eeprom.len = ops->get_eeprom_len(netdev);
+       eeprom.offset = 0;
+
+       data = kmalloc(eeprom.len, GFP_KERNEL);
+       if (!data) {
+               printk(KERN_ERR "Unable to allocate memory to dump EEPROM"
+                      " data\n");
+               return;
+       }
+
+       ops->get_eeprom(netdev, &eeprom, data);
+
+       csum_old = (data[EEPROM_CHECKSUM_REG * 2]) +
+                  (data[EEPROM_CHECKSUM_REG * 2 + 1] << 8);
+       for (i = 0; i < EEPROM_CHECKSUM_REG * 2; i += 2)
+               csum_new += data[i] + (data[i + 1] << 8);
+       csum_new = EEPROM_SUM - csum_new;
+
+       printk(KERN_ERR "/*********************/\n");
+       printk(KERN_ERR "Current EEPROM Checksum : 0x%04x\n", csum_old);
+       printk(KERN_ERR "Calculated              : 0x%04x\n", csum_new);
+
+       printk(KERN_ERR "Offset    Values\n");
+       printk(KERN_ERR "========  ======\n");
+       print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, data, 128, 0);
+
+       printk(KERN_ERR "Include this output when contacting your support "
+              "provider.\n");
+       printk(KERN_ERR "This is not a software error! Something bad "
+              "happened to your hardware or\n");
+       printk(KERN_ERR "EEPROM image. Ignoring this "
+              "problem could result in further problems,\n");
+       printk(KERN_ERR "possibly loss of data, corruption or system hangs!\n");
+       printk(KERN_ERR "The MAC Address will be reset to 00:00:00:00:00:00, "
+              "which is invalid\n");
+       printk(KERN_ERR "and requires you to set the proper MAC "
+              "address manually before continuing\n");
+       printk(KERN_ERR "to enable this network device.\n");
+       printk(KERN_ERR "Please inspect the EEPROM dump and report the issue "
+              "to your hardware vendor\n");
+       printk(KERN_ERR "or Intel Customer Support: linux-nics@intel.com\n");
+       printk(KERN_ERR "/*********************/\n");
+
+       kfree(data);
+}
+
 /**
  * e1000_probe - Device Initialization Routine
  * @pdev: PCI device information struct
@@ -927,7 +958,7 @@ e1000_probe(struct pci_dev *pdev,
        netdev->stop = &e1000_close;
        netdev->hard_start_xmit = &e1000_xmit_frame;
        netdev->get_stats = &e1000_get_stats;
-       netdev->set_multicast_list = &e1000_set_multi;
+       netdev->set_rx_mode = &e1000_set_rx_mode;
        netdev->set_mac_address = &e1000_set_mac;
        netdev->change_mtu = &e1000_change_mtu;
        netdev->do_ioctl = &e1000_ioctl;
@@ -995,7 +1026,6 @@ e1000_probe(struct pci_dev *pdev,
        adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
 
        /* initialize eeprom parameters */
-
        if (e1000_init_eeprom_params(&adapter->hw)) {
                E1000_ERR("EEPROM initialization failed\n");
                goto err_eeprom;
@@ -1007,23 +1037,29 @@ e1000_probe(struct pci_dev *pdev,
        e1000_reset_hw(&adapter->hw);
 
        /* make sure the EEPROM is good */
-
        if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
                DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
-               goto err_eeprom;
+               e1000_dump_eeprom(adapter);
+               /*
+                * set MAC address to all zeroes to invalidate and temporary
+                * disable this device for the user. This blocks regular
+                * traffic while still permitting ethtool ioctls from reaching
+                * the hardware as well as allowing the user to run the
+                * interface after manually setting a hw addr using
+                * `ip set address`
+                */
+               memset(adapter->hw.mac_addr, 0, netdev->addr_len);
+       } else {
+               /* copy the MAC address out of the EEPROM */
+               if (e1000_read_mac_addr(&adapter->hw))
+                       DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
        }
-
-       /* copy the MAC address out of the EEPROM */
-
-       if (e1000_read_mac_addr(&adapter->hw))
-               DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
+       /* don't block initalization here due to bad MAC address */
        memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
        memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 
-       if (!is_valid_ether_addr(netdev->perm_addr)) {
+       if (!is_valid_ether_addr(netdev->perm_addr))
                DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
-               goto err_eeprom;
-       }
 
        e1000_get_bus_info(&adapter->hw);
 
@@ -2410,21 +2446,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
 }
 
 /**
- * e1000_set_multi - Multicast and Promiscuous mode set
+ * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
  * @netdev: network interface device structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
+ * The set_rx_mode entry point is called whenever the unicast or multicast
+ * address lists or the network interface flags are updated. This routine is
+ * responsible for configuring the hardware for proper unicast, multicast,
  * promiscuous mode, and all-multi behavior.
  **/
 
 static void
-e1000_set_multi(struct net_device *netdev)
+e1000_set_rx_mode(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       struct dev_mc_list *mc_ptr;
+       struct dev_addr_list *uc_ptr;
+       struct dev_addr_list *mc_ptr;
        uint32_t rctl;
        uint32_t hash_value;
        int i, rar_entries = E1000_RAR_ENTRIES;
@@ -2447,9 +2484,16 @@ e1000_set_multi(struct net_device *netdev)
                rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
        } else if (netdev->flags & IFF_ALLMULTI) {
                rctl |= E1000_RCTL_MPE;
-               rctl &= ~E1000_RCTL_UPE;
        } else {
-               rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+               rctl &= ~E1000_RCTL_MPE;
+       }
+
+       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;
        }
 
        E1000_WRITE_REG(hw, RCTL, rctl);
@@ -2459,7 +2503,10 @@ e1000_set_multi(struct net_device *netdev)
        if (hw->mac_type == e1000_82542_rev2_0)
                e1000_enter_82542_rst(adapter);
 
-       /* load the first 14 multicast address into the exact filters 1-14
+       /* load the first 14 addresses into the exact filters 1-14. Unicast
+        * addresses take precedence to avoid disabling unicast filtering
+        * when possible.
+        *
         * RAR 0 is used for the station MAC adddress
         * if there are not 14 addresses, go ahead and clear the filters
         * -- with 82571 controllers only 0-13 entries are filled here
@@ -2467,8 +2514,11 @@ e1000_set_multi(struct net_device *netdev)
        mc_ptr = netdev->mc_list;
 
        for (i = 1; i < rar_entries; i++) {
-               if (mc_ptr) {
-                       e1000_rar_set(hw, mc_ptr->dmi_addr, i);
+               if (uc_ptr) {
+                       e1000_rar_set(hw, uc_ptr->da_addr, i);
+                       uc_ptr = uc_ptr->next;
+               } else if (mc_ptr) {
+                       e1000_rar_set(hw, mc_ptr->da_addr, i);
                        mc_ptr = mc_ptr->next;
                } else {
                        E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@@ -2477,6 +2527,7 @@ e1000_set_multi(struct net_device *netdev)
                        E1000_WRITE_FLUSH(hw);
                }
        }
+       WARN_ON(uc_ptr != NULL);
 
        /* clear the old settings from the multicast hash table */
 
@@ -2488,7 +2539,7 @@ e1000_set_multi(struct net_device *netdev)
        /* load any remaining addresses into the hash table */
 
        for (; mc_ptr; mc_ptr = mc_ptr->next) {
-               hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
+               hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
                e1000_mta_set(hw, hash_value);
        }
 
@@ -3680,10 +3731,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
        }
 
        /* Fill out the OS statistics structure */
-       adapter->net_stats.rx_packets = adapter->stats.gprc;
-       adapter->net_stats.tx_packets = adapter->stats.gptc;
-       adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-       adapter->net_stats.tx_bytes = adapter->stats.gotcl;
        adapter->net_stats.multicast = adapter->stats.mprc;
        adapter->net_stats.collisions = adapter->stats.colc;
 
@@ -4059,6 +4106,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter,
        }
        adapter->total_tx_bytes += total_tx_bytes;
        adapter->total_tx_packets += total_tx_packets;
+       adapter->net_stats.tx_bytes += total_tx_bytes;
+       adapter->net_stats.tx_packets += total_tx_packets;
        return cleaned;
 }
 
@@ -4106,8 +4155,8 @@ e1000_rx_checksum(struct e1000_adapter *adapter,
                /* Hardware complements the payload checksum, so we undo it
                 * and then put the value in host order for further stack use.
                 */
-               csum = ntohl(csum ^ 0xFFFF);
-               skb->csum = csum;
+               __sum16 sum = (__force __sum16)htons(csum);
+               skb->csum = csum_unfold(~sum);
                skb->ip_summed = CHECKSUM_COMPLETE;
        }
        adapter->hw_csum_good++;
@@ -4281,6 +4330,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -4468,6 +4519,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
        return cleaned;
 }
 
@@ -4631,7 +4684,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                                rx_desc->read.buffer_addr[j+1] =
                                     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
                        } else
-                               rx_desc->read.buffer_addr[j+1] = ~0;
+                               rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
                }
 
                skb = netdev_alloc_skb(netdev,
@@ -4874,22 +4927,6 @@ e1000_pci_clear_mwi(struct e1000_hw *hw)
        pci_clear_mwi(adapter->pdev);
 }
 
-void
-e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
-{
-       struct e1000_adapter *adapter = hw->back;
-
-       pci_read_config_word(adapter->pdev, reg, value);
-}
-
-void
-e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
-{
-       struct e1000_adapter *adapter = hw->back;
-
-       pci_write_config_word(adapter->pdev, reg, *value);
-}
-
 int
 e1000_pcix_get_mmrbc(struct e1000_hw *hw)
 {
@@ -5095,7 +5132,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
        if (wufc) {
                e1000_setup_rctl(adapter);
-               e1000_set_multi(netdev);
+               e1000_set_rx_mode(netdev);
 
                /* turn on all-multi mode if wake on multicast is enabled */
                if (wufc & E1000_WUFC_MC) {
index 14141a55eaa6f1f14754a09ada3377321fba8c76..3beace55b58d8c25efe1a04a4a6f7ed4b042529b 100644 (file)
@@ -194,6 +194,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
                break;
        case E1000_DEV_ID_82571EB_SERDES:
        case E1000_DEV_ID_82572EI_SERDES:
+       case E1000_DEV_ID_82571EB_SERDES_DUAL:
+       case E1000_DEV_ID_82571EB_SERDES_QUAD:
                hw->media_type = e1000_media_type_internal_serdes;
                break;
        default:
@@ -260,6 +262,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
        case E1000_DEV_ID_82571EB_QUAD_COPPER:
        case E1000_DEV_ID_82571EB_QUAD_FIBER:
        case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
+       case E1000_DEV_ID_82571PT_QUAD_COPPER:
                adapter->flags |= FLAG_IS_QUAD_PORT;
                /* mark the first port */
                if (global_quad_port_a == 0)
@@ -285,6 +288,9 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
                if (adapter->flags & FLAG_IS_QUAD_PORT &&
                    (!(adapter->flags & FLAG_IS_QUAD_PORT_A)))
                        adapter->flags &= ~FLAG_HAS_WOL;
+               /* Does not support WoL on any port */
+               if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD)
+                       adapter->flags &= ~FLAG_HAS_WOL;
                break;
 
        case e1000_82573:
@@ -752,6 +758,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
        ew32(IMC, 0xffffffff);
        icr = er32(ICR);
 
+       if (hw->mac.type == e1000_82571 &&
+               hw->dev_spec.e82571.alt_mac_addr_is_present)
+                       e1000e_set_laa_state_82571(hw, true);
+
        return 0;
 }
 
@@ -1339,7 +1349,6 @@ struct e1000_info e1000_82573_info = {
                                  | FLAG_HAS_STATS_ICR_ICT
                                  | FLAG_HAS_SMART_POWER_DOWN
                                  | FLAG_HAS_AMT
-                                 | FLAG_HAS_ASPM
                                  | FLAG_HAS_ERT
                                  | FLAG_HAS_SWSM_ON_LOAD,
        .pba                    = 20,
index b32ed45b4b34cef6b8d73fd373bca61ea78672b8..f2175ea46b830a438380a54d0571bb3c92683586 100644 (file)
 #define NVM_INIT_3GIO_3            0x001A
 #define NVM_INIT_CONTROL3_PORT_A   0x0024
 #define NVM_CFG                    0x0012
+#define NVM_ALT_MAC_ADDR_PTR       0x0037
 #define NVM_CHECKSUM_REG           0x003F
 
 #define E1000_NVM_CFG_DONE_PORT_0  0x40000 /* MNG config cycle done */
index 473f78de4be0d0bce40f3ed370a64f77ff692341..8b88c226e8581908f2d19dfec380ed1cff35ae00 100644 (file)
@@ -288,7 +288,6 @@ struct e1000_info {
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
-#define FLAG_HAS_ASPM                     (1 << 8)
 #define FLAG_HAS_STATS_ICR_ICT            (1 << 9)
 #define FLAG_HAS_STATS_PTC_PRC            (1 << 10)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
index 87f9da1b6b4ef9e2786dba5048414570a670cd66..6d9c27fd0b53b86953ecf3548d59c4825de1e626 100644 (file)
@@ -95,15 +95,14 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
        { "tx_dma_failed", E1000_STAT(tx_dma_failed) },
 };
 
-#define E1000_GLOBAL_STATS_LEN \
-       sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
+#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
 #define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN)
 static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
        "Register test  (offline)", "Eeprom test    (offline)",
        "Interrupt test (offline)", "Loopback test  (offline)",
        "Link test   (on/offline)"
 };
-#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
+#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
 
 static int e1000_get_settings(struct net_device *netdev,
                              struct ethtool_cmd *ecmd)
@@ -691,41 +690,63 @@ err_setup:
        return err;
 }
 
-#define REG_PATTERN_TEST(R, M, W) REG_PATTERN_TEST_ARRAY(R, 0, M, W)
-#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, writeable)                 \
-{                                                                            \
-       u32 _pat;                                                             \
-       u32 _value;                                                           \
-       u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};       \
-       for (_pat = 0; _pat < ARRAY_SIZE(_test); _pat++) {                    \
-               E1000_WRITE_REG_ARRAY(hw, reg, offset,        \
-                                     (_test[_pat] & writeable));             \
-               _value = E1000_READ_REG_ARRAY(hw, reg, offset);     \
-               if (_value != (_test[_pat] & writeable & mask)) {             \
-                       ndev_err(netdev, "pattern test reg %04X "             \
-                                "failed: got 0x%08X expected 0x%08X\n",      \
-                                reg + offset,  \
-                                value, (_test[_pat] & writeable & mask));    \
-                       *data = reg;                                          \
-                       return 1;                                             \
-               }                                                             \
-       }                                                                     \
+bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data,
+                           int reg, int offset, u32 mask, u32 write)
+{
+       int i;
+       u32 read;
+       static const u32 test[] =
+               {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+       for (i = 0; i < ARRAY_SIZE(test); i++) {
+               E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset,
+                                     (test[i] & write));
+               read = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
+               if (read != (test[i] & write & mask)) {
+                       ndev_err(adapter->netdev, "pattern test reg %04X "
+                                "failed: got 0x%08X expected 0x%08X\n",
+                                reg + offset,
+                                read, (test[i] & write & mask));
+                       *data = reg;
+                       return true;
+               }
+       }
+       return false;
 }
 
-#define REG_SET_AND_CHECK(R, M, W)                                           \
-{                                                                            \
-       u32 _value;                                                           \
-       __ew32(hw, R, W & M);                                           \
-       _value = __er32(hw, R);                                         \
-       if ((W & M) != (_value & M)) {                                        \
-               ndev_err(netdev, "set/check reg %04X test failed: "           \
-                        "got 0x%08X expected 0x%08X\n", R, (_value & M),     \
-                        (W & M));                                            \
-               *data = R;                                                    \
-               return 1;                                                     \
-       }                                                                     \
+static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
+                             int reg, u32 mask, u32 write)
+{
+       u32 read;
+       __ew32(&adapter->hw, reg, write & mask);
+       read = __er32(&adapter->hw, reg);
+       if ((write & mask) != (read & mask)) {
+               ndev_err(adapter->netdev, "set/check reg %04X test failed: "
+                        "got 0x%08X expected 0x%08X\n", reg, (read & mask),
+                        (write & mask));
+               *data = reg;
+               return true;
+       }
+       return false;
 }
 
+#define REG_PATTERN_TEST(R, M, W) \
+       do { \
+               if (reg_pattern_test_array(adapter, data, R, 0, M, W)) \
+                       return 1; \
+       } while (0)
+
+#define REG_PATTERN_TEST_ARRAY(R, offset, M, W) \
+       do { \
+               if (reg_pattern_test_array(adapter, data, R, offset, M, W)) \
+                       return 1; \
+       } while (0)
+
+#define REG_SET_AND_CHECK(R, M, W) \
+       do { \
+               if (reg_set_and_check(adapter, data, R, M, W)) \
+                       return 1; \
+       } while (0)
+
 static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 {
        struct e1000_hw *hw = &adapter->hw;
index 64515789fd4d51fb82c9fa3268c7b19a70a58368..3c5862f97dbf3b90a61cc468ab804deb23ca47dc 100644 (file)
@@ -303,8 +303,11 @@ enum e1e_registers {
 #define E1000_DEV_ID_82571EB_FIBER             0x105F
 #define E1000_DEV_ID_82571EB_SERDES            0x1060
 #define E1000_DEV_ID_82571EB_QUAD_COPPER       0x10A4
+#define E1000_DEV_ID_82571PT_QUAD_COPPER       0x10D5
 #define E1000_DEV_ID_82571EB_QUAD_FIBER                0x10A5
 #define E1000_DEV_ID_82571EB_QUAD_COPPER_LP    0x10BC
+#define E1000_DEV_ID_82571EB_SERDES_DUAL       0x10D9
+#define E1000_DEV_ID_82571EB_SERDES_QUAD       0x10DA
 #define E1000_DEV_ID_82572EI_COPPER            0x107D
 #define E1000_DEV_ID_82572EI_FIBER             0x107E
 #define E1000_DEV_ID_82572EI_SERDES            0x107F
@@ -420,35 +423,35 @@ enum e1000_smart_speed {
 
 /* Receive Descriptor */
 struct e1000_rx_desc {
-       u64 buffer_addr; /* Address of the descriptor's data buffer */
-       u16 length;      /* Length of data DMAed into data buffer */
-       u16 csum;       /* Packet checksum */
+       __le64 buffer_addr; /* Address of the descriptor's data buffer */
+       __le16 length;      /* Length of data DMAed into data buffer */
+       __le16 csum;    /* Packet checksum */
        u8  status;      /* Descriptor status */
        u8  errors;      /* Descriptor Errors */
-       u16 special;
+       __le16 special;
 };
 
 /* Receive Descriptor - Extended */
 union e1000_rx_desc_extended {
        struct {
-               u64 buffer_addr;
-               u64 reserved;
+               __le64 buffer_addr;
+               __le64 reserved;
        } read;
        struct {
                struct {
-                       u32 mrq;              /* Multiple Rx Queues */
+                       __le32 mrq;           /* Multiple Rx Queues */
                        union {
-                               u32 rss;            /* RSS Hash */
+                               __le32 rss;         /* RSS Hash */
                                struct {
-                                       u16 ip_id;  /* IP id */
-                                       u16 csum;   /* Packet Checksum */
+                                       __le16 ip_id;  /* IP id */
+                                       __le16 csum;   /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error;     /* ext status/error */
-                       u16 length;
-                       u16 vlan;            /* VLAN tag */
+                       __le32 status_error;     /* ext status/error */
+                       __le16 length;
+                       __le16 vlan;         /* VLAN tag */
                } upper;
        } wb;  /* writeback */
 };
@@ -458,49 +461,49 @@ union e1000_rx_desc_extended {
 union e1000_rx_desc_packet_split {
        struct {
                /* one buffer for protocol header(s), three data buffers */
-               u64 buffer_addr[MAX_PS_BUFFERS];
+               __le64 buffer_addr[MAX_PS_BUFFERS];
        } read;
        struct {
                struct {
-                       u32 mrq;              /* Multiple Rx Queues */
+                       __le32 mrq;           /* Multiple Rx Queues */
                        union {
-                               u32 rss;              /* RSS Hash */
+                               __le32 rss;           /* RSS Hash */
                                struct {
-                                       u16 ip_id;    /* IP id */
-                                       u16 csum;     /* Packet Checksum */
+                                       __le16 ip_id;    /* IP id */
+                                       __le16 csum;     /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error;     /* ext status/error */
-                       u16 length0;      /* length of buffer 0 */
-                       u16 vlan;            /* VLAN tag */
+                       __le32 status_error;     /* ext status/error */
+                       __le16 length0;   /* length of buffer 0 */
+                       __le16 vlan;         /* VLAN tag */
                } middle;
                struct {
-                       u16 header_status;
-                       u16 length[3];  /* length of buffers 1-3 */
+                       __le16 header_status;
+                       __le16 length[3];       /* length of buffers 1-3 */
                } upper;
-               u64 reserved;
+               __le64 reserved;
        } wb; /* writeback */
 };
 
 /* Transmit Descriptor */
 struct e1000_tx_desc {
-       u64 buffer_addr;      /* Address of the descriptor's data buffer */
+       __le64 buffer_addr;      /* Address of the descriptor's data buffer */
        union {
-               u32 data;
+               __le32 data;
                struct {
-                       u16 length;    /* Data buffer length */
+                       __le16 length;    /* Data buffer length */
                        u8 cso; /* Checksum offset */
                        u8 cmd; /* Descriptor control */
                } flags;
        } lower;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 css; /* Checksum start */
-                       u16 special;
+                       __le16 special;
                } fields;
        } upper;
 };
@@ -508,49 +511,49 @@ struct e1000_tx_desc {
 /* Offload Context Descriptor */
 struct e1000_context_desc {
        union {
-               u32 ip_config;
+               __le32 ip_config;
                struct {
                        u8 ipcss;      /* IP checksum start */
                        u8 ipcso;      /* IP checksum offset */
-                       u16 ipcse;     /* IP checksum end */
+                       __le16 ipcse;     /* IP checksum end */
                } ip_fields;
        } lower_setup;
        union {
-               u32 tcp_config;
+               __le32 tcp_config;
                struct {
                        u8 tucss;      /* TCP checksum start */
                        u8 tucso;      /* TCP checksum offset */
-                       u16 tucse;     /* TCP checksum end */
+                       __le16 tucse;     /* TCP checksum end */
                } tcp_fields;
        } upper_setup;
-       u32 cmd_and_length;
+       __le32 cmd_and_length;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 hdr_len;    /* Header length */
-                       u16 mss;       /* Maximum segment size */
+                       __le16 mss;       /* Maximum segment size */
                } fields;
        } tcp_seg_setup;
 };
 
 /* Offload data descriptor */
 struct e1000_data_desc {
-       u64 buffer_addr;   /* Address of the descriptor's buffer address */
+       __le64 buffer_addr;   /* Address of the descriptor's buffer address */
        union {
-               u32 data;
+               __le32 data;
                struct {
-                       u16 length;    /* Data buffer length */
+                       __le16 length;    /* Data buffer length */
                        u8 typ_len_ext;
                        u8 cmd;
                } flags;
        } lower;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 popts;      /* Packet Options */
-                       u16 special;   /* */
+                       __le16 special;   /* */
                } fields;
        } upper;
 };
@@ -816,6 +819,7 @@ struct e1000_bus_info {
 
 struct e1000_dev_spec_82571 {
        bool laa_is_present;
+       bool alt_mac_addr_is_present;
 };
 
 struct e1000_shadow_ram {
index 0bdeca30c75fd3348f5b56fe49e8c03ed581d600..16f35fadb74b8a9ca4ce005b0617791832890832 100644 (file)
@@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
 {
        s32 ret_val;
        u16 offset, nvm_data, i;
+       u16 mac_addr_offset = 0;
+
+       if (hw->mac.type == e1000_82571) {
+               /* Check for an alternate MAC address.  An alternate MAC
+                * address can be setup by pre-boot software and must be
+                * treated like a permanent address and must override the
+                * actual permanent MAC address. */
+               ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+                                               &mac_addr_offset);
+               if (ret_val) {
+                       hw_dbg(hw, "NVM Read Error\n");
+                       return ret_val;
+               }
+               if (mac_addr_offset == 0xFFFF)
+                       mac_addr_offset = 0;
+
+               if (mac_addr_offset) {
+                       if (hw->bus.func == E1000_FUNC_1)
+                               mac_addr_offset += ETH_ALEN/sizeof(u16);
+
+                       /* make sure we have a valid mac address here
+                        * before using it */
+                       ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
+                                                &nvm_data);
+                       if (ret_val) {
+                               hw_dbg(hw, "NVM Read Error\n");
+                               return ret_val;
+                       }
+                       if (nvm_data & 0x0001)
+                               mac_addr_offset = 0;
+               }
+
+               if (mac_addr_offset)
+                       hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
+       }
 
        for (i = 0; i < ETH_ALEN; i += 2) {
-               offset = i >> 1;
+               offset = mac_addr_offset + (i >> 1);
                ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
                if (ret_val) {
                        hw_dbg(hw, "NVM Read Error\n");
@@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
        }
 
        /* Flip last bit of mac address if we're on second port */
-       if (hw->bus.func == E1000_FUNC_1)
+       if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
                hw->mac.perm_addr[5] ^= 1;
 
        for (i = 0; i < ETH_ALEN; i++)
index 9cc5a6b01bc1dcfb73ca17ec11a476e586837951..0a2cb7960c9e8d8dcb85063773a3d800068a9a9d 100644 (file)
@@ -91,7 +91,7 @@ static int e1000_desc_unused(struct e1000_ring *ring)
 static void e1000_receive_skb(struct e1000_adapter *adapter,
                              struct net_device *netdev,
                              struct sk_buff *skb,
-                             u8 status, u16 vlan)
+                             u8 status, __le16 vlan)
 {
        skb->protocol = eth_type_trans(skb, netdev);
 
@@ -142,8 +142,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
                /* Hardware complements the payload checksum, so we undo it
                 * and then put the value in host order for further stack use.
                 */
-               csum = ntohl(csum ^ 0xFFFF);
-               skb->csum = csum;
+               __sum16 sum = (__force __sum16)htons(csum);
+               skb->csum = csum_unfold(~sum);
                skb->ip_summed = CHECKSUM_COMPLETE;
        }
        adapter->hw_csum_good++;
@@ -248,7 +248,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                        ps_page = &buffer_info->ps_pages[j];
                        if (j >= adapter->rx_ps_pages) {
                                /* all unused desc entries get hw null ptr */
-                               rx_desc->read.buffer_addr[j+1] = ~0;
+                               rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
                                continue;
                        }
                        if (!ps_page->page) {
@@ -458,6 +458,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
        return cleaned;
 }
 
@@ -593,6 +595,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
        }
        adapter->total_tx_bytes += total_tx_bytes;
        adapter->total_tx_packets += total_tx_packets;
+       adapter->net_stats.tx_packets += total_tx_packets;
+       adapter->net_stats.tx_bytes += total_tx_bytes;
        return cleaned;
 }
 
@@ -755,6 +759,8 @@ next_desc:
 
        adapter->total_rx_packets += total_rx_packets;
        adapter->total_rx_bytes += total_rx_bytes;
+       adapter->net_stats.rx_packets += total_rx_packets;
+       adapter->net_stats.rx_bytes += total_rx_bytes;
        return cleaned;
 }
 
@@ -935,7 +941,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       void (*handler) = &e1000_intr;
+       irq_handler_t handler = e1000_intr;
        int irq_flags = IRQF_SHARED;
        int err;
 
@@ -945,7 +951,7 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
                 "Unable to allocate MSI interrupt Error: %d\n", err);
        } else {
                adapter->flags |= FLAG_MSI_ENABLED;
-               handler = &e1000_intr_msi;
+               handler = e1000_intr_msi;
                irq_flags = 0;
        }
 
@@ -2535,10 +2541,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        }
 
        /* Fill out the OS statistics structure */
-       adapter->net_stats.rx_packets = adapter->stats.gprc;
-       adapter->net_stats.tx_packets = adapter->stats.gptc;
-       adapter->net_stats.rx_bytes = adapter->stats.gorcl;
-       adapter->net_stats.tx_bytes = adapter->stats.gotcl;
        adapter->net_stats.multicast = adapter->stats.mprc;
        adapter->net_stats.collisions = adapter->stats.colc;
 
@@ -3509,6 +3511,33 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
        return 0;
 }
 
+static void e1000e_disable_l1aspm(struct pci_dev *pdev)
+{
+       int pos;
+       u32 cap;
+       u16 val;
+
+       /*
+        * 82573 workaround - disable L1 ASPM on mobile chipsets
+        *
+        * L1 ASPM on various mobile (ich7) chipsets do not behave properly
+        * resulting in lost data or garbage information on the pci-e link
+        * level. This could result in (false) bad EEPROM checksum errors,
+        * long ping times (up to 2s) or even a system freeze/hang.
+        *
+        * Unfortunately this feature saves about 1W power consumption when
+        * active.
+        */
+       pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+       pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap);
+       pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val);
+       if (val & 0x2) {
+               dev_warn(&pdev->dev, "Disabling L1 ASPM\n");
+               val &= ~0x2;
+               pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val);
+       }
+}
+
 #ifdef CONFIG_PM
 static int e1000_resume(struct pci_dev *pdev)
 {
@@ -3519,6 +3548,7 @@ static int e1000_resume(struct pci_dev *pdev)
 
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
+       e1000e_disable_l1aspm(pdev);
        err = pci_enable_device(pdev);
        if (err) {
                dev_err(&pdev->dev,
@@ -3619,6 +3649,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
 
+       e1000e_disable_l1aspm(pdev);
        if (pci_enable_device(pdev)) {
                dev_err(&pdev->dev,
                        "Cannot re-enable PCI device after reset.\n");
@@ -3720,6 +3751,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        u16 eeprom_data = 0;
        u16 eeprom_apme_mask = E1000_EEPROM_APME;
 
+       e1000e_disable_l1aspm(pdev);
        err = pci_enable_device(pdev);
        if (err)
                return err;
@@ -4056,16 +4088,15 @@ static struct pci_error_handlers e1000_err_handler = {
 };
 
 static struct pci_device_id e1000_pci_tbl[] = {
-       /*
-        * Support for 82571/2/3, es2lan and ich8 will be phased in
-        * stepwise.
-
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
@@ -4088,8 +4119,6 @@ static struct pci_device_id e1000_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
-       */
-
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
index 332789238b9c9309a63210877700b021b3c9acfd..df266c32ac4bc022fa6f5b75877e4ebd707315f5 100644 (file)
@@ -262,13 +262,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                         .max = MAX_RXDELAY } }
                };
 
-               /* modify min and default if 82573 for slow ping w/a,
-                * a value greater than 8 needs to be set for RDTR */
-               if (adapter->flags & FLAG_HAS_ASPM) {
-                       opt.def = 32;
-                       opt.arg.r.min = 8;
-               }
-
                if (num_RxIntDelay > bd) {
                        adapter->rx_int_delay = RxIntDelay[bd];
                        e1000_validate_option(&adapter->rx_int_delay, &opt,
index 793231810ae0a6c119aef80111c2d428578812ca..fc6fee112f1c191231f64e23a98dd9ce19d7f574 100644 (file)
@@ -49,8 +49,7 @@ static const u16 e1000_igp_2_cable_length_table[] =
          100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121,
          124};
 #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
-               (sizeof(e1000_igp_2_cable_length_table) / \
-                sizeof(e1000_igp_2_cable_length_table[0]))
+               ARRAY_SIZE(e1000_igp_2_cable_length_table)
 
 /**
  *  e1000e_check_reset_block_generic - Check if PHY reset is blocked
index 1548a80f917d52650feb344369ab065b16122a4f..e3e26c595fa340b8de1a4c28d8152964c9b42d69 100644 (file)
@@ -304,13 +304,7 @@ enum commands {
 #if defined(__alpha__)
 # define clear_suspend(cmd)  clear_bit(30, &(cmd)->cmd_status);
 #else
-# if defined(__LITTLE_ENDIAN)
-#  define clear_suspend(cmd)  ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x4000
-# elif defined(__BIG_ENDIAN)
-#  define clear_suspend(cmd)  ((__u16 *)&(cmd)->cmd_status)[1] &= ~0x0040
-# else
-#  error Unsupported byteorder
-# endif
+# define clear_suspend(cmd)  ((__le16 *)&(cmd)->cmd_status)[1] &= ~cpu_to_le16(1<<14)
 #endif
 
 enum SCBCmdBits {
@@ -331,17 +325,17 @@ enum SCBPort_cmds {
 
 /* The Speedo3 Rx and Tx frame/buffer descriptors. */
 struct descriptor {                        /* A generic descriptor. */
-       volatile s32 cmd_status;        /* All command and status fields. */
-       u32 link;                                   /* struct descriptor *  */
+       volatile __le32 cmd_status;     /* All command and status fields. */
+       __le32 link;                                /* struct descriptor *  */
        unsigned char params[0];
 };
 
 /* The Speedo3 Rx and Tx buffer descriptors. */
 struct RxFD {                                  /* Receive frame descriptor. */
-       volatile s32 status;
-       u32 link;                                       /* struct RxFD * */
-       u32 rx_buf_addr;                        /* void * */
-       u32 count;
+       volatile __le32 status;
+       __le32 link;                                    /* struct RxFD * */
+       __le32 rx_buf_addr;                     /* void * */
+       __le32 count;
 } RxFD_ALIGNMENT;
 
 /* Selected elements of the Tx/RxFD.status word. */
@@ -354,16 +348,16 @@ enum RxFD_bits {
 
 #define CONFIG_DATA_SIZE 22
 struct TxFD {                                  /* Transmit frame descriptor set. */
-       s32 status;
-       u32 link;                                       /* void * */
-       u32 tx_desc_addr;                       /* Always points to the tx_buf_addr element. */
-       s32 count;                                      /* # of TBD (=1), Tx start thresh., etc. */
+       __le32 status;
+       __le32 link;                                    /* void * */
+       __le32 tx_desc_addr;                    /* Always points to the tx_buf_addr element. */
+       __le32 count;                                   /* # of TBD (=1), Tx start thresh., etc. */
        /* This constitutes two "TBD" entries -- we only use one. */
 #define TX_DESCR_BUF_OFFSET 16
-       u32 tx_buf_addr0;                       /* void *, frame to be transmitted.  */
-       s32 tx_buf_size0;                       /* Length of Tx frame. */
-       u32 tx_buf_addr1;                       /* void *, frame to be transmitted.  */
-       s32 tx_buf_size1;                       /* Length of Tx frame. */
+       __le32 tx_buf_addr0;                    /* void *, frame to be transmitted.  */
+       __le32 tx_buf_size0;                    /* Length of Tx frame. */
+       __le32 tx_buf_addr1;                    /* void *, frame to be transmitted.  */
+       __le32 tx_buf_size1;                    /* Length of Tx frame. */
        /* the structure must have space for at least CONFIG_DATA_SIZE starting
         * from tx_desc_addr field */
 };
@@ -379,23 +373,23 @@ struct speedo_mc_block {
 
 /* Elements of the dump_statistics block. This block must be lword aligned. */
 struct speedo_stats {
-       u32 tx_good_frames;
-       u32 tx_coll16_errs;
-       u32 tx_late_colls;
-       u32 tx_underruns;
-       u32 tx_lost_carrier;
-       u32 tx_deferred;
-       u32 tx_one_colls;
-       u32 tx_multi_colls;
-       u32 tx_total_colls;
-       u32 rx_good_frames;
-       u32 rx_crc_errs;
-       u32 rx_align_errs;
-       u32 rx_resource_errs;
-       u32 rx_overrun_errs;
-       u32 rx_colls_errs;
-       u32 rx_runt_errs;
-       u32 done_marker;
+       __le32 tx_good_frames;
+       __le32 tx_coll16_errs;
+       __le32 tx_late_colls;
+       __le32 tx_underruns;
+       __le32 tx_lost_carrier;
+       __le32 tx_deferred;
+       __le32 tx_one_colls;
+       __le32 tx_multi_colls;
+       __le32 tx_total_colls;
+       __le32 rx_good_frames;
+       __le32 rx_crc_errs;
+       __le32 rx_align_errs;
+       __le32 rx_resource_errs;
+       __le32 rx_overrun_errs;
+       __le32 rx_colls_errs;
+       __le32 rx_runt_errs;
+       __le32 done_marker;
 };
 
 enum Rx_ring_state_bits {
@@ -1139,7 +1133,7 @@ speedo_rx_soft_reset(struct net_device *dev)
 
        rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
 
-       rfd->rx_buf_addr = 0xffffffff;
+       rfd->rx_buf_addr = cpu_to_le32(0xffffffff);
 
        if (wait_for_cmd_done(dev, sp) != 0) {
                printk("%s: RxAbort command stalled\n", dev->name);
@@ -1275,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev)
                rxf->status = cpu_to_le32(0x00000001);  /* '1' is flag value only. */
                rxf->link = 0;                                          /* None yet. */
                /* This field unused by i82557. */
-               rxf->rx_buf_addr = 0xffffffff;
+               rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
                rxf->count = cpu_to_le32(PKT_BUF_SZ << 16);
                pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[i],
                                                                           sizeof(struct RxFD), PCI_DMA_TODEVICE);
@@ -1657,7 +1651,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
                                           PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE);
        skb->dev = dev;
        skb_reserve(skb, sizeof(struct RxFD));
-       rxf->rx_buf_addr = 0xffffffff;
+       rxf->rx_buf_addr = cpu_to_le32(0xffffffff);
        pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry],
                                                                   sizeof(struct RxFD), PCI_DMA_TODEVICE);
        return rxf;
@@ -1788,7 +1782,7 @@ speedo_rx(struct net_device *dev)
                        /* Check if the packet is long enough to just accept without
                           copying to a properly sized skbuff. */
                        if (pkt_len < rx_copybreak
-                               && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
+                               && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
                                /* 'skb_put()' points to the start of sk_buff data area. */
                                pci_dma_sync_single_for_cpu(sp->pdev, sp->rx_ring_dma[entry],
@@ -1933,7 +1927,7 @@ speedo_get_stats(struct net_device *dev)
        void __iomem *ioaddr = sp->regs;
 
        /* Update only if the previous dump finished. */
-       if (sp->lstats->done_marker == le32_to_cpu(0xA007)) {
+       if (sp->lstats->done_marker == cpu_to_le32(0xA007)) {
                sp->stats.tx_aborted_errors += le32_to_cpu(sp->lstats->tx_coll16_errs);
                sp->stats.tx_window_errors += le32_to_cpu(sp->lstats->tx_late_colls);
                sp->stats.tx_fifo_errors += le32_to_cpu(sp->lstats->tx_underruns);
@@ -2142,7 +2136,7 @@ static void set_rx_mode(struct net_device *dev)
                /* The simple case of 0-3 multicast list entries occurs often, and
                   fits within one tx_ring[] entry. */
                struct dev_mc_list *mclist;
-               u16 *setup_params, *eaddrs;
+               __le16 *setup_params, *eaddrs;
 
                spin_lock_irqsave(&sp->lock, flags);
                entry = sp->cur_tx++ % TX_RING_SIZE;
@@ -2154,12 +2148,12 @@ static void set_rx_mode(struct net_device *dev)
                sp->tx_ring[entry].link =
                        cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
                sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
-               setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr;
+               setup_params = (__le16 *)&sp->tx_ring[entry].tx_desc_addr;
                *setup_params++ = cpu_to_le16(dev->mc_count*6);
                /* Fill in the multicast addresses. */
                for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
                         i++, mclist = mclist->next) {
-                       eaddrs = (u16 *)mclist->dmi_addr;
+                       eaddrs = (__le16 *)mclist->dmi_addr;
                        *setup_params++ = *eaddrs++;
                        *setup_params++ = *eaddrs++;
                        *setup_params++ = *eaddrs++;
@@ -2177,7 +2171,7 @@ static void set_rx_mode(struct net_device *dev)
                spin_unlock_irqrestore(&sp->lock, flags);
        } else if (new_rx_mode == 0) {
                struct dev_mc_list *mclist;
-               u16 *setup_params, *eaddrs;
+               __le16 *setup_params, *eaddrs;
                struct speedo_mc_block *mc_blk;
                struct descriptor *mc_setup_frm;
                int i;
@@ -2204,12 +2198,12 @@ static void set_rx_mode(struct net_device *dev)
                mc_setup_frm->cmd_status =
                        cpu_to_le32(CmdSuspend | CmdIntr | CmdMulticastList);
                /* Link set below. */
-               setup_params = (u16 *)&mc_setup_frm->params;
+               setup_params = (__le16 *)&mc_setup_frm->params;
                *setup_params++ = cpu_to_le16(dev->mc_count*6);
                /* Fill in the multicast addresses. */
                for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
                         i++, mclist = mclist->next) {
-                       eaddrs = (u16 *)mclist->dmi_addr;
+                       eaddrs = (__le16 *)mclist->dmi_addr;
                        *setup_params++ = *eaddrs++;
                        *setup_params++ = *eaddrs++;
                        *setup_params++ = *eaddrs++;
index 70509ed6c11de9a77cc5cbe14bc86859e136e363..d5459a8056b1a4f60f8207b1651385e5ff2856d1 100644 (file)
@@ -456,8 +456,9 @@ static int eexp_open(struct net_device *dev)
        if (!dev->irq || !irqrmap[dev->irq])
                return -ENXIO;
 
-       ret = request_irq(dev->irq,&eexp_irq,0,dev->name,dev);
-       if (ret) return ret;
+       ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev);
+       if (ret)
+               return ret;
 
        if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
                printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
@@ -768,7 +769,7 @@ static void eexp_cmd_clear(struct net_device *dev)
        }
 }
 
-static irqreturn_t eexp_irq(int irq, void *dev_info)
+static irqreturn_t eexp_irq(int dummy, void *dev_info)
 {
        struct net_device *dev = dev_info;
        struct net_local *lp;
@@ -783,8 +784,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info)
        old_read_ptr = inw(ioaddr+READ_PTR);
        old_write_ptr = inw(ioaddr+WRITE_PTR);
 
-       outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
-
+       outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ);
 
        status = scb_status(dev);
 
@@ -851,7 +851,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info)
 
        eexp_cmd_clear(dev);
 
-       outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ);
+       outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ);
 
 #if NET_DEBUG > 6
        printk("%s: leaving eexp_irq()\n", dev->name);
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
new file mode 100644 (file)
index 0000000..0809a6a
--- /dev/null
@@ -0,0 +1,1600 @@
+/*
+ * Microchip ENC28J60 ethernet driver (MAC + PHY)
+ *
+ * Copyright (C) 2007 Eurek srl
+ * Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
+ * based on enc28j60.c written by David Anders for 2.4 kernel version
+ *
+ * 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.
+ *
+ * $Id: enc28j60.c,v 1.22 2007/12/20 10:47:01 claudio Exp $
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+
+#include "enc28j60_hw.h"
+
+#define DRV_NAME       "enc28j60"
+#define DRV_VERSION    "1.01"
+
+#define SPI_OPLEN      1
+
+#define ENC28J60_MSG_DEFAULT   \
+       (NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_LINK)
+
+/* Buffer size required for the largest SPI transfer (i.e., reading a
+ * frame). */
+#define SPI_TRANSFER_BUF_LEN   (4 + MAX_FRAMELEN)
+
+#define TX_TIMEOUT     (4 * HZ)
+
+/* Max TX retries in case of collision as suggested by errata datasheet */
+#define MAX_TX_RETRYCOUNT      16
+
+enum {
+       RXFILTER_NORMAL,
+       RXFILTER_MULTI,
+       RXFILTER_PROMISC
+};
+
+/* Driver local data */
+struct enc28j60_net {
+       struct net_device *netdev;
+       struct spi_device *spi;
+       struct mutex lock;
+       struct sk_buff *tx_skb;
+       struct work_struct tx_work;
+       struct work_struct irq_work;
+       struct work_struct setrx_work;
+       struct work_struct restart_work;
+       u8 bank;                /* current register bank selected */
+       u16 next_pk_ptr;        /* next packet pointer within FIFO */
+       u16 max_pk_counter;     /* statistics: max packet counter */
+       u16 tx_retry_count;
+       bool hw_enable;
+       bool full_duplex;
+       int rxfilter;
+       u32 msg_enable;
+       u8 spi_transfer_buf[SPI_TRANSFER_BUF_LEN];
+};
+
+/* use ethtool to change the level for any given device */
+static struct {
+       u32 msg_enable;
+} debug = { -1 };
+
+/*
+ * SPI read buffer
+ * wait for the SPI transfer and copy received data to destination
+ */
+static int
+spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
+{
+       u8 *rx_buf = priv->spi_transfer_buf + 4;
+       u8 *tx_buf = priv->spi_transfer_buf;
+       struct spi_transfer t = {
+               .tx_buf = tx_buf,
+               .rx_buf = rx_buf,
+               .len = SPI_OPLEN + len,
+       };
+       struct spi_message msg;
+       int ret;
+
+       tx_buf[0] = ENC28J60_READ_BUF_MEM;
+       tx_buf[1] = tx_buf[2] = tx_buf[3] = 0;  /* don't care */
+
+       spi_message_init(&msg);
+       spi_message_add_tail(&t, &msg);
+       ret = spi_sync(priv->spi, &msg);
+       if (ret == 0) {
+               memcpy(data, &rx_buf[SPI_OPLEN], len);
+               ret = msg.status;
+       }
+       if (ret && netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
+                       __FUNCTION__, ret);
+
+       return ret;
+}
+
+/*
+ * SPI write buffer
+ */
+static int spi_write_buf(struct enc28j60_net *priv, int len,
+                        const u8 *data)
+{
+       int ret;
+
+       if (len > SPI_TRANSFER_BUF_LEN - 1 || len <= 0)
+               ret = -EINVAL;
+       else {
+               priv->spi_transfer_buf[0] = ENC28J60_WRITE_BUF_MEM;
+               memcpy(&priv->spi_transfer_buf[1], data, len);
+               ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1);
+               if (ret && netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
+                               __FUNCTION__, ret);
+       }
+       return ret;
+}
+
+/*
+ * basic SPI read operation
+ */
+static u8 spi_read_op(struct enc28j60_net *priv, u8 op,
+                          u8 addr)
+{
+       u8 tx_buf[2];
+       u8 rx_buf[4];
+       u8 val = 0;
+       int ret;
+       int slen = SPI_OPLEN;
+
+       /* do dummy read if needed */
+       if (addr & SPRD_MASK)
+               slen++;
+
+       tx_buf[0] = op | (addr & ADDR_MASK);
+       ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen);
+       if (ret)
+               printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
+                       __FUNCTION__, ret);
+       else
+               val = rx_buf[slen - 1];
+
+       return val;
+}
+
+/*
+ * basic SPI write operation
+ */
+static int spi_write_op(struct enc28j60_net *priv, u8 op,
+                       u8 addr, u8 val)
+{
+       int ret;
+
+       priv->spi_transfer_buf[0] = op | (addr & ADDR_MASK);
+       priv->spi_transfer_buf[1] = val;
+       ret = spi_write(priv->spi, priv->spi_transfer_buf, 2);
+       if (ret && netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
+                       __FUNCTION__, ret);
+       return ret;
+}
+
+static void enc28j60_soft_reset(struct enc28j60_net *priv)
+{
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+
+       spi_write_op(priv, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
+       /* Errata workaround #1, CLKRDY check is unreliable,
+        * delay at least 1 mS instead */
+       udelay(2000);
+}
+
+/*
+ * select the current register bank if necessary
+ */
+static void enc28j60_set_bank(struct enc28j60_net *priv, u8 addr)
+{
+       if ((addr & BANK_MASK) != priv->bank) {
+               u8 b = (addr & BANK_MASK) >> 5;
+
+               if (b != (ECON1_BSEL1 | ECON1_BSEL0))
+                       spi_write_op(priv, ENC28J60_BIT_FIELD_CLR, ECON1,
+                                    ECON1_BSEL1 | ECON1_BSEL0);
+               if (b != 0)
+                       spi_write_op(priv, ENC28J60_BIT_FIELD_SET, ECON1, b);
+               priv->bank = (addr & BANK_MASK);
+       }
+}
+
+/*
+ * Register access routines through the SPI bus.
+ * Every register access comes in two flavours:
+ * - nolock_xxx: caller needs to invoke mutex_lock, usually to access
+ *   atomically more than one register
+ * - locked_xxx: caller doesn't need to invoke mutex_lock, single access
+ *
+ * Some registers can be accessed through the bit field clear and
+ * bit field set to avoid a read modify write cycle.
+ */
+
+/*
+ * Register bit field Set
+ */
+static void nolock_reg_bfset(struct enc28j60_net *priv,
+                                     u8 addr, u8 mask)
+{
+       enc28j60_set_bank(priv, addr);
+       spi_write_op(priv, ENC28J60_BIT_FIELD_SET, addr, mask);
+}
+
+static void locked_reg_bfset(struct enc28j60_net *priv,
+                                     u8 addr, u8 mask)
+{
+       mutex_lock(&priv->lock);
+       nolock_reg_bfset(priv, addr, mask);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Register bit field Clear
+ */
+static void nolock_reg_bfclr(struct enc28j60_net *priv,
+                                     u8 addr, u8 mask)
+{
+       enc28j60_set_bank(priv, addr);
+       spi_write_op(priv, ENC28J60_BIT_FIELD_CLR, addr, mask);
+}
+
+static void locked_reg_bfclr(struct enc28j60_net *priv,
+                                     u8 addr, u8 mask)
+{
+       mutex_lock(&priv->lock);
+       nolock_reg_bfclr(priv, addr, mask);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Register byte read
+ */
+static int nolock_regb_read(struct enc28j60_net *priv,
+                                    u8 address)
+{
+       enc28j60_set_bank(priv, address);
+       return spi_read_op(priv, ENC28J60_READ_CTRL_REG, address);
+}
+
+static int locked_regb_read(struct enc28j60_net *priv,
+                                    u8 address)
+{
+       int ret;
+
+       mutex_lock(&priv->lock);
+       ret = nolock_regb_read(priv, address);
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+/*
+ * Register word read
+ */
+static int nolock_regw_read(struct enc28j60_net *priv,
+                                    u8 address)
+{
+       int rl, rh;
+
+       enc28j60_set_bank(priv, address);
+       rl = spi_read_op(priv, ENC28J60_READ_CTRL_REG, address);
+       rh = spi_read_op(priv, ENC28J60_READ_CTRL_REG, address + 1);
+
+       return (rh << 8) | rl;
+}
+
+static int locked_regw_read(struct enc28j60_net *priv,
+                                    u8 address)
+{
+       int ret;
+
+       mutex_lock(&priv->lock);
+       ret = nolock_regw_read(priv, address);
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+/*
+ * Register byte write
+ */
+static void nolock_regb_write(struct enc28j60_net *priv,
+                                      u8 address, u8 data)
+{
+       enc28j60_set_bank(priv, address);
+       spi_write_op(priv, ENC28J60_WRITE_CTRL_REG, address, data);
+}
+
+static void locked_regb_write(struct enc28j60_net *priv,
+                                      u8 address, u8 data)
+{
+       mutex_lock(&priv->lock);
+       nolock_regb_write(priv, address, data);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Register word write
+ */
+static void nolock_regw_write(struct enc28j60_net *priv,
+                                      u8 address, u16 data)
+{
+       enc28j60_set_bank(priv, address);
+       spi_write_op(priv, ENC28J60_WRITE_CTRL_REG, address, (u8) data);
+       spi_write_op(priv, ENC28J60_WRITE_CTRL_REG, address + 1,
+                    (u8) (data >> 8));
+}
+
+static void locked_regw_write(struct enc28j60_net *priv,
+                                      u8 address, u16 data)
+{
+       mutex_lock(&priv->lock);
+       nolock_regw_write(priv, address, data);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Buffer memory read
+ * Select the starting address and execute a SPI buffer read
+ */
+static void enc28j60_mem_read(struct enc28j60_net *priv,
+                                    u16 addr, int len, u8 *data)
+{
+       mutex_lock(&priv->lock);
+       nolock_regw_write(priv, ERDPTL, addr);
+#ifdef CONFIG_ENC28J60_WRITEVERIFY
+       if (netif_msg_drv(priv)) {
+               u16 reg;
+               reg = nolock_regw_read(priv, ERDPTL);
+               if (reg != addr)
+                       printk(KERN_DEBUG DRV_NAME ": %s() error writing ERDPT "
+                               "(0x%04x - 0x%04x)\n", __FUNCTION__, reg, addr);
+       }
+#endif
+       spi_read_buf(priv, len, data);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Write packet to enc28j60 TX buffer memory
+ */
+static void
+enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
+{
+       mutex_lock(&priv->lock);
+       /* Set the write pointer to start of transmit buffer area */
+       nolock_regw_write(priv, EWRPTL, TXSTART_INIT);
+#ifdef CONFIG_ENC28J60_WRITEVERIFY
+       if (netif_msg_drv(priv)) {
+               u16 reg;
+               reg = nolock_regw_read(priv, EWRPTL);
+               if (reg != TXSTART_INIT)
+                       printk(KERN_DEBUG DRV_NAME
+                               ": %s() ERWPT:0x%04x != 0x%04x\n",
+                               __FUNCTION__, reg, TXSTART_INIT);
+       }
+#endif
+       /* Set the TXND pointer to correspond to the packet size given */
+       nolock_regw_write(priv, ETXNDL, TXSTART_INIT + len);
+       /* write per-packet control byte */
+       spi_write_op(priv, ENC28J60_WRITE_BUF_MEM, 0, 0x00);
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME
+                       ": %s() after control byte ERWPT:0x%04x\n",
+                       __FUNCTION__, nolock_regw_read(priv, EWRPTL));
+       /* copy the packet into the transmit buffer */
+       spi_write_buf(priv, len, data);
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME
+                        ": %s() after write packet ERWPT:0x%04x, len=%d\n",
+                        __FUNCTION__, nolock_regw_read(priv, EWRPTL), len);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Wait until the PHY operation is complete.
+ */
+static int wait_phy_ready(struct enc28j60_net *priv)
+{
+       unsigned long timeout = jiffies + 20 * HZ / 1000;
+       int ret = 1;
+
+       /* 20 msec timeout read */
+       while (nolock_regb_read(priv, MISTAT) & MISTAT_BUSY) {
+               if (time_after(jiffies, timeout)) {
+                       if (netif_msg_drv(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": PHY ready timeout!\n");
+                       ret = 0;
+                       break;
+               }
+               cpu_relax();
+       }
+       return ret;
+}
+
+/*
+ * PHY register read
+ * PHY registers are not accessed directly, but through the MII
+ */
+static u16 enc28j60_phy_read(struct enc28j60_net *priv, u8 address)
+{
+       u16 ret;
+
+       mutex_lock(&priv->lock);
+       /* set the PHY register address */
+       nolock_regb_write(priv, MIREGADR, address);
+       /* start the register read operation */
+       nolock_regb_write(priv, MICMD, MICMD_MIIRD);
+       /* wait until the PHY read completes */
+       wait_phy_ready(priv);
+       /* quit reading */
+       nolock_regb_write(priv, MICMD, 0x00);
+       /* return the data */
+       ret  = nolock_regw_read(priv, MIRDL);
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+static int enc28j60_phy_write(struct enc28j60_net *priv, u8 address, u16 data)
+{
+       int ret;
+
+       mutex_lock(&priv->lock);
+       /* set the PHY register address */
+       nolock_regb_write(priv, MIREGADR, address);
+       /* write the PHY data */
+       nolock_regw_write(priv, MIWRL, data);
+       /* wait until the PHY write completes and return */
+       ret = wait_phy_ready(priv);
+       mutex_unlock(&priv->lock);
+
+       return ret;
+}
+
+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static int enc28j60_set_hw_macaddr(struct net_device *ndev)
+{
+       int ret;
+       struct enc28j60_net *priv = netdev_priv(ndev);
+
+       mutex_lock(&priv->lock);
+       if (!priv->hw_enable) {
+               if (netif_msg_drv(priv)) {
+                       DECLARE_MAC_BUF(mac);
+                       printk(KERN_INFO DRV_NAME
+                               ": %s: Setting MAC address to %s\n",
+                               ndev->name, print_mac(mac, ndev->dev_addr));
+               }
+               /* NOTE: MAC address in ENC28J60 is byte-backward */
+               nolock_regb_write(priv, MAADR5, ndev->dev_addr[0]);
+               nolock_regb_write(priv, MAADR4, ndev->dev_addr[1]);
+               nolock_regb_write(priv, MAADR3, ndev->dev_addr[2]);
+               nolock_regb_write(priv, MAADR2, ndev->dev_addr[3]);
+               nolock_regb_write(priv, MAADR1, ndev->dev_addr[4]);
+               nolock_regb_write(priv, MAADR0, ndev->dev_addr[5]);
+               ret = 0;
+       } else {
+               if (netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME
+                               ": %s() Hardware must be disabled to set "
+                               "Mac address\n", __FUNCTION__);
+               ret = -EBUSY;
+       }
+       mutex_unlock(&priv->lock);
+       return ret;
+}
+
+/*
+ * Store the new hardware address in dev->dev_addr, and update the MAC.
+ */
+static int enc28j60_set_mac_address(struct net_device *dev, void *addr)
+{
+       struct sockaddr *address = addr;
+
+       if (netif_running(dev))
+               return -EBUSY;
+       if (!is_valid_ether_addr(address->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
+       return enc28j60_set_hw_macaddr(dev);
+}
+
+/*
+ * Debug routine to dump useful register contents
+ */
+static void enc28j60_dump_regs(struct enc28j60_net *priv, const char *msg)
+{
+       mutex_lock(&priv->lock);
+       printk(KERN_DEBUG DRV_NAME " %s\n"
+               "HwRevID: 0x%02x\n"
+               "Cntrl: ECON1 ECON2 ESTAT  EIR  EIE\n"
+               "       0x%02x  0x%02x  0x%02x  0x%02x  0x%02x\n"
+               "MAC  : MACON1 MACON3 MACON4\n"
+               "       0x%02x   0x%02x   0x%02x\n"
+               "Rx   : ERXST  ERXND  ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\n"
+               "       0x%04x 0x%04x 0x%04x  0x%04x  "
+               "0x%02x    0x%02x    0x%04x\n"
+               "Tx   : ETXST  ETXND  MACLCON1 MACLCON2 MAPHSUP\n"
+               "       0x%04x 0x%04x 0x%02x     0x%02x     0x%02x\n",
+               msg, nolock_regb_read(priv, EREVID),
+               nolock_regb_read(priv, ECON1), nolock_regb_read(priv, ECON2),
+               nolock_regb_read(priv, ESTAT), nolock_regb_read(priv, EIR),
+               nolock_regb_read(priv, EIE), nolock_regb_read(priv, MACON1),
+               nolock_regb_read(priv, MACON3), nolock_regb_read(priv, MACON4),
+               nolock_regw_read(priv, ERXSTL), nolock_regw_read(priv, ERXNDL),
+               nolock_regw_read(priv, ERXWRPTL),
+               nolock_regw_read(priv, ERXRDPTL),
+               nolock_regb_read(priv, ERXFCON),
+               nolock_regb_read(priv, EPKTCNT),
+               nolock_regw_read(priv, MAMXFLL), nolock_regw_read(priv, ETXSTL),
+               nolock_regw_read(priv, ETXNDL),
+               nolock_regb_read(priv, MACLCON1),
+               nolock_regb_read(priv, MACLCON2),
+               nolock_regb_read(priv, MAPHSUP));
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * ERXRDPT need to be set always at odd addresses, refer to errata datasheet
+ */
+static u16 erxrdpt_workaround(u16 next_packet_ptr, u16 start, u16 end)
+{
+       u16 erxrdpt;
+
+       if ((next_packet_ptr - 1 < start) || (next_packet_ptr - 1 > end))
+               erxrdpt = end;
+       else
+               erxrdpt = next_packet_ptr - 1;
+
+       return erxrdpt;
+}
+
+static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
+{
+       u16 erxrdpt;
+
+       if (start > 0x1FFF || end > 0x1FFF || start > end) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_ERR DRV_NAME ": %s(%d, %d) RXFIFO "
+                               "bad parameters!\n", __FUNCTION__, start, end);
+               return;
+       }
+       /* set receive buffer start + end */
+       priv->next_pk_ptr = start;
+       nolock_regw_write(priv, ERXSTL, start);
+       erxrdpt = erxrdpt_workaround(priv->next_pk_ptr, start, end);
+       nolock_regw_write(priv, ERXRDPTL, erxrdpt);
+       nolock_regw_write(priv, ERXNDL, end);
+}
+
+static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
+{
+       if (start > 0x1FFF || end > 0x1FFF || start > end) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_ERR DRV_NAME ": %s(%d, %d) TXFIFO "
+                               "bad parameters!\n", __FUNCTION__, start, end);
+               return;
+       }
+       /* set transmit buffer start + end */
+       nolock_regw_write(priv, ETXSTL, start);
+       nolock_regw_write(priv, ETXNDL, end);
+}
+
+static int enc28j60_hw_init(struct enc28j60_net *priv)
+{
+       u8 reg;
+
+       if (netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __FUNCTION__,
+                       priv->full_duplex ? "FullDuplex" : "HalfDuplex");
+
+       mutex_lock(&priv->lock);
+       /* first reset the chip */
+       enc28j60_soft_reset(priv);
+       /* Clear ECON1 */
+       spi_write_op(priv, ENC28J60_WRITE_CTRL_REG, ECON1, 0x00);
+       priv->bank = 0;
+       priv->hw_enable = false;
+       priv->tx_retry_count = 0;
+       priv->max_pk_counter = 0;
+       priv->rxfilter = RXFILTER_NORMAL;
+       /* enable address auto increment */
+       nolock_regb_write(priv, ECON2, ECON2_AUTOINC);
+
+       nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT);
+       nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT);
+       mutex_unlock(&priv->lock);
+
+       /*
+        * Check the RevID.
+        * If it's 0x00 or 0xFF probably the enc28j60 is not mounted or
+        * damaged
+        */
+       reg = locked_regb_read(priv, EREVID);
+       if (netif_msg_drv(priv))
+               printk(KERN_INFO DRV_NAME ": chip RevID: 0x%02x\n", reg);
+       if (reg == 0x00 || reg == 0xff) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME ": %s() Invalid RevId %d\n",
+                               __FUNCTION__, reg);
+               return 0;
+       }
+
+       /* default filter mode: (unicast OR broadcast) AND crc valid */
+       locked_regb_write(priv, ERXFCON,
+                           ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
+
+       /* enable MAC receive */
+       locked_regb_write(priv, MACON1,
+                           MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
+       /* enable automatic padding and CRC operations */
+       if (priv->full_duplex) {
+               locked_regb_write(priv, MACON3,
+                                   MACON3_PADCFG0 | MACON3_TXCRCEN |
+                                   MACON3_FRMLNEN | MACON3_FULDPX);
+               /* set inter-frame gap (non-back-to-back) */
+               locked_regb_write(priv, MAIPGL, 0x12);
+               /* set inter-frame gap (back-to-back) */
+               locked_regb_write(priv, MABBIPG, 0x15);
+       } else {
+               locked_regb_write(priv, MACON3,
+                                   MACON3_PADCFG0 | MACON3_TXCRCEN |
+                                   MACON3_FRMLNEN);
+               locked_regb_write(priv, MACON4, 1 << 6);        /* DEFER bit */
+               /* set inter-frame gap (non-back-to-back) */
+               locked_regw_write(priv, MAIPGL, 0x0C12);
+               /* set inter-frame gap (back-to-back) */
+               locked_regb_write(priv, MABBIPG, 0x12);
+       }
+       /*
+        * MACLCON1 (default)
+        * MACLCON2 (default)
+        * Set the maximum packet size which the controller will accept
+        */
+       locked_regw_write(priv, MAMXFLL, MAX_FRAMELEN);
+
+       /* Configure LEDs */
+       if (!enc28j60_phy_write(priv, PHLCON, ENC28J60_LAMPS_MODE))
+               return 0;
+
+       if (priv->full_duplex) {
+               if (!enc28j60_phy_write(priv, PHCON1, PHCON1_PDPXMD))
+                       return 0;
+               if (!enc28j60_phy_write(priv, PHCON2, 0x00))
+                       return 0;
+       } else {
+               if (!enc28j60_phy_write(priv, PHCON1, 0x00))
+                       return 0;
+               if (!enc28j60_phy_write(priv, PHCON2, PHCON2_HDLDIS))
+                       return 0;
+       }
+       if (netif_msg_hw(priv))
+               enc28j60_dump_regs(priv, "Hw initialized.");
+
+       return 1;
+}
+
+static void enc28j60_hw_enable(struct enc28j60_net *priv)
+{
+       /* enable interrutps */
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
+                       __FUNCTION__);
+
+       enc28j60_phy_write(priv, PHIE, PHIE_PGEIE | PHIE_PLNKIE);
+
+       mutex_lock(&priv->lock);
+       nolock_reg_bfclr(priv, EIR, EIR_DMAIF | EIR_LINKIF |
+                        EIR_TXIF | EIR_TXERIF | EIR_RXERIF | EIR_PKTIF);
+       nolock_regb_write(priv, EIE, EIE_INTIE | EIE_PKTIE | EIE_LINKIE |
+                         EIE_TXIE | EIE_TXERIE | EIE_RXERIE);
+
+       /* enable receive logic */
+       nolock_reg_bfset(priv, ECON1, ECON1_RXEN);
+       priv->hw_enable = true;
+       mutex_unlock(&priv->lock);
+}
+
+static void enc28j60_hw_disable(struct enc28j60_net *priv)
+{
+       mutex_lock(&priv->lock);
+       /* disable interrutps and packet reception */
+       nolock_regb_write(priv, EIE, 0x00);
+       nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
+       priv->hw_enable = false;
+       mutex_unlock(&priv->lock);
+}
+
+static int
+enc28j60_setlink(struct net_device *ndev, u8 autoneg, u16 speed, u8 duplex)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+       int ret = 0;
+
+       if (!priv->hw_enable) {
+               if (autoneg == AUTONEG_DISABLE && speed == SPEED_10) {
+                       priv->full_duplex = (duplex == DUPLEX_FULL);
+                       if (!enc28j60_hw_init(priv)) {
+                               if (netif_msg_drv(priv))
+                                       dev_err(&ndev->dev,
+                                               "hw_reset() failed\n");
+                               ret = -EINVAL;
+                       }
+               } else {
+                       if (netif_msg_link(priv))
+                               dev_warn(&ndev->dev,
+                                       "unsupported link setting\n");
+                       ret = -EOPNOTSUPP;
+               }
+       } else {
+               if (netif_msg_link(priv))
+                       dev_warn(&ndev->dev, "Warning: hw must be disabled "
+                               "to set link mode\n");
+               ret = -EBUSY;
+       }
+       return ret;
+}
+
+/*
+ * Read the Transmit Status Vector
+ */
+static void enc28j60_read_tsv(struct enc28j60_net *priv, u8 tsv[TSV_SIZE])
+{
+       int endptr;
+
+       endptr = locked_regw_read(priv, ETXNDL);
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME ": reading TSV at addr:0x%04x\n",
+                        endptr + 1);
+       enc28j60_mem_read(priv, endptr + 1, sizeof(tsv), tsv);
+}
+
+static void enc28j60_dump_tsv(struct enc28j60_net *priv, const char *msg,
+                               u8 tsv[TSV_SIZE])
+{
+       u16 tmp1, tmp2;
+
+       printk(KERN_DEBUG DRV_NAME ": %s - TSV:\n", msg);
+       tmp1 = tsv[1];
+       tmp1 <<= 8;
+       tmp1 |= tsv[0];
+
+       tmp2 = tsv[5];
+       tmp2 <<= 8;
+       tmp2 |= tsv[4];
+
+       printk(KERN_DEBUG DRV_NAME ": ByteCount: %d, CollisionCount: %d,"
+               " TotByteOnWire: %d\n", tmp1, tsv[2] & 0x0f, tmp2);
+       printk(KERN_DEBUG DRV_NAME ": TxDone: %d, CRCErr:%d, LenChkErr: %d,"
+               " LenOutOfRange: %d\n", TSV_GETBIT(tsv, TSV_TXDONE),
+               TSV_GETBIT(tsv, TSV_TXCRCERROR),
+               TSV_GETBIT(tsv, TSV_TXLENCHKERROR),
+               TSV_GETBIT(tsv, TSV_TXLENOUTOFRANGE));
+       printk(KERN_DEBUG DRV_NAME ": Multicast: %d, Broadcast: %d, "
+               "PacketDefer: %d, ExDefer: %d\n",
+               TSV_GETBIT(tsv, TSV_TXMULTICAST),
+               TSV_GETBIT(tsv, TSV_TXBROADCAST),
+               TSV_GETBIT(tsv, TSV_TXPACKETDEFER),
+               TSV_GETBIT(tsv, TSV_TXEXDEFER));
+       printk(KERN_DEBUG DRV_NAME ": ExCollision: %d, LateCollision: %d, "
+                "Giant: %d, Underrun: %d\n",
+                TSV_GETBIT(tsv, TSV_TXEXCOLLISION),
+                TSV_GETBIT(tsv, TSV_TXLATECOLLISION),
+                TSV_GETBIT(tsv, TSV_TXGIANT), TSV_GETBIT(tsv, TSV_TXUNDERRUN));
+       printk(KERN_DEBUG DRV_NAME ": ControlFrame: %d, PauseFrame: %d, "
+                "BackPressApp: %d, VLanTagFrame: %d\n",
+                TSV_GETBIT(tsv, TSV_TXCONTROLFRAME),
+                TSV_GETBIT(tsv, TSV_TXPAUSEFRAME),
+                TSV_GETBIT(tsv, TSV_BACKPRESSUREAPP),
+                TSV_GETBIT(tsv, TSV_TXVLANTAGFRAME));
+}
+
+/*
+ * Receive Status vector
+ */
+static void enc28j60_dump_rsv(struct enc28j60_net *priv, const char *msg,
+                             u16 pk_ptr, int len, u16 sts)
+{
+       printk(KERN_DEBUG DRV_NAME ": %s - NextPk: 0x%04x - RSV:\n",
+               msg, pk_ptr);
+       printk(KERN_DEBUG DRV_NAME ": ByteCount: %d, DribbleNibble: %d\n", len,
+                RSV_GETBIT(sts, RSV_DRIBBLENIBBLE));
+       printk(KERN_DEBUG DRV_NAME ": RxOK: %d, CRCErr:%d, LenChkErr: %d,"
+                " LenOutOfRange: %d\n", RSV_GETBIT(sts, RSV_RXOK),
+                RSV_GETBIT(sts, RSV_CRCERROR),
+                RSV_GETBIT(sts, RSV_LENCHECKERR),
+                RSV_GETBIT(sts, RSV_LENOUTOFRANGE));
+       printk(KERN_DEBUG DRV_NAME ": Multicast: %d, Broadcast: %d, "
+                "LongDropEvent: %d, CarrierEvent: %d\n",
+                RSV_GETBIT(sts, RSV_RXMULTICAST),
+                RSV_GETBIT(sts, RSV_RXBROADCAST),
+                RSV_GETBIT(sts, RSV_RXLONGEVDROPEV),
+                RSV_GETBIT(sts, RSV_CARRIEREV));
+       printk(KERN_DEBUG DRV_NAME ": ControlFrame: %d, PauseFrame: %d,"
+                " UnknownOp: %d, VLanTagFrame: %d\n",
+                RSV_GETBIT(sts, RSV_RXCONTROLFRAME),
+                RSV_GETBIT(sts, RSV_RXPAUSEFRAME),
+                RSV_GETBIT(sts, RSV_RXUNKNOWNOPCODE),
+                RSV_GETBIT(sts, RSV_RXTYPEVLAN));
+}
+
+static void dump_packet(const char *msg, int len, const char *data)
+{
+       printk(KERN_DEBUG DRV_NAME ": %s - packet len:%d\n", msg, len);
+       print_hex_dump(KERN_DEBUG, "pk data: ", DUMP_PREFIX_OFFSET, 16, 1,
+                       data, len, true);
+}
+
+/*
+ * Hardware receive function.
+ * Read the buffer memory, update the FIFO pointer to free the buffer,
+ * check the status vector and decrement the packet counter.
+ */
+static void enc28j60_hw_rx(struct net_device *ndev)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+       struct sk_buff *skb = NULL;
+       u16 erxrdpt, next_packet, rxstat;
+       u8 rsv[RSV_SIZE];
+       int len;
+
+       if (netif_msg_rx_status(priv))
+               printk(KERN_DEBUG DRV_NAME ": RX pk_addr:0x%04x\n",
+                       priv->next_pk_ptr);
+
+       if (unlikely(priv->next_pk_ptr > RXEND_INIT)) {
+               if (netif_msg_rx_err(priv))
+                       dev_err(&ndev->dev,
+                               "%s() Invalid packet address!! 0x%04x\n",
+                               __FUNCTION__, priv->next_pk_ptr);
+               /* packet address corrupted: reset RX logic */
+               mutex_lock(&priv->lock);
+               nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
+               nolock_reg_bfset(priv, ECON1, ECON1_RXRST);
+               nolock_reg_bfclr(priv, ECON1, ECON1_RXRST);
+               nolock_rxfifo_init(priv, RXSTART_INIT, RXEND_INIT);
+               nolock_reg_bfclr(priv, EIR, EIR_RXERIF);
+               nolock_reg_bfset(priv, ECON1, ECON1_RXEN);
+               mutex_unlock(&priv->lock);
+               ndev->stats.rx_errors++;
+               return;
+       }
+       /* Read next packet pointer and rx status vector */
+       enc28j60_mem_read(priv, priv->next_pk_ptr, sizeof(rsv), rsv);
+
+       next_packet = rsv[1];
+       next_packet <<= 8;
+       next_packet |= rsv[0];
+
+       len = rsv[3];
+       len <<= 8;
+       len |= rsv[2];
+
+       rxstat = rsv[5];
+       rxstat <<= 8;
+       rxstat |= rsv[4];
+
+       if (netif_msg_rx_status(priv))
+               enc28j60_dump_rsv(priv, __FUNCTION__, next_packet, len, rxstat);
+
+       if (!RSV_GETBIT(rxstat, RSV_RXOK)) {
+               if (netif_msg_rx_err(priv))
+                       dev_err(&ndev->dev, "Rx Error (%04x)\n", rxstat);
+               ndev->stats.rx_errors++;
+               if (RSV_GETBIT(rxstat, RSV_CRCERROR))
+                       ndev->stats.rx_crc_errors++;
+               if (RSV_GETBIT(rxstat, RSV_LENCHECKERR))
+                       ndev->stats.rx_frame_errors++;
+       } else {
+               skb = dev_alloc_skb(len);
+               if (!skb) {
+                       if (netif_msg_rx_err(priv))
+                               dev_err(&ndev->dev,
+                                       "out of memory for Rx'd frame\n");
+                       ndev->stats.rx_dropped++;
+               } else {
+                       skb->dev = ndev;
+                       /* copy the packet from the receive buffer */
+                       enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
+                                       len, skb_put(skb, len));
+                       if (netif_msg_pktdata(priv))
+                               dump_packet(__FUNCTION__, skb->len, skb->data);
+                       skb->protocol = eth_type_trans(skb, ndev);
+                       /* update statistics */
+                       ndev->stats.rx_packets++;
+                       ndev->stats.rx_bytes += len;
+                       ndev->last_rx = jiffies;
+                       netif_rx(skb);
+               }
+       }
+       /*
+        * Move the RX read pointer to the start of the next
+        * received packet.
+        * This frees the memory we just read out
+        */
+       erxrdpt = erxrdpt_workaround(next_packet, RXSTART_INIT, RXEND_INIT);
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT:0x%04x\n",
+                       __FUNCTION__, erxrdpt);
+
+       mutex_lock(&priv->lock);
+       nolock_regw_write(priv, ERXRDPTL, erxrdpt);
+#ifdef CONFIG_ENC28J60_WRITEVERIFY
+       if (netif_msg_drv(priv)) {
+               u16 reg;
+               reg = nolock_regw_read(priv, ERXRDPTL);
+               if (reg != erxrdpt)
+                       printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT verify "
+                               "error (0x%04x - 0x%04x)\n", __FUNCTION__,
+                               reg, erxrdpt);
+       }
+#endif
+       priv->next_pk_ptr = next_packet;
+       /* we are done with this packet, decrement the packet counter */
+       nolock_reg_bfset(priv, ECON2, ECON2_PKTDEC);
+       mutex_unlock(&priv->lock);
+}
+
+/*
+ * Calculate free space in RxFIFO
+ */
+static int enc28j60_get_free_rxfifo(struct enc28j60_net *priv)
+{
+       int epkcnt, erxst, erxnd, erxwr, erxrd;
+       int free_space;
+
+       mutex_lock(&priv->lock);
+       epkcnt = nolock_regb_read(priv, EPKTCNT);
+       if (epkcnt >= 255)
+               free_space = -1;
+       else {
+               erxst = nolock_regw_read(priv, ERXSTL);
+               erxnd = nolock_regw_read(priv, ERXNDL);
+               erxwr = nolock_regw_read(priv, ERXWRPTL);
+               erxrd = nolock_regw_read(priv, ERXRDPTL);
+
+               if (erxwr > erxrd)
+                       free_space = (erxnd - erxst) - (erxwr - erxrd);
+               else if (erxwr == erxrd)
+                       free_space = (erxnd - erxst);
+               else
+                       free_space = erxrd - erxwr - 1;
+       }
+       mutex_unlock(&priv->lock);
+       if (netif_msg_rx_status(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() free_space = %d\n",
+                       __FUNCTION__, free_space);
+       return free_space;
+}
+
+/*
+ * Access the PHY to determine link status
+ */
+static void enc28j60_check_link_status(struct net_device *ndev)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+       u16 reg;
+       int duplex;
+
+       reg = enc28j60_phy_read(priv, PHSTAT2);
+       if (netif_msg_hw(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() PHSTAT1: %04x, "
+                       "PHSTAT2: %04x\n", __FUNCTION__,
+                       enc28j60_phy_read(priv, PHSTAT1), reg);
+       duplex = reg & PHSTAT2_DPXSTAT;
+
+       if (reg & PHSTAT2_LSTAT) {
+               netif_carrier_on(ndev);
+               if (netif_msg_ifup(priv))
+                       dev_info(&ndev->dev, "link up - %s\n",
+                               duplex ? "Full duplex" : "Half duplex");
+       } else {
+               if (netif_msg_ifdown(priv))
+                       dev_info(&ndev->dev, "link down\n");
+               netif_carrier_off(ndev);
+       }
+}
+
+static void enc28j60_tx_clear(struct net_device *ndev, bool err)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+
+       if (err)
+               ndev->stats.tx_errors++;
+       else
+               ndev->stats.tx_packets++;
+
+       if (priv->tx_skb) {
+               if (!err)
+                       ndev->stats.tx_bytes += priv->tx_skb->len;
+               dev_kfree_skb(priv->tx_skb);
+               priv->tx_skb = NULL;
+       }
+       locked_reg_bfclr(priv, ECON1, ECON1_TXRTS);
+       netif_wake_queue(ndev);
+}
+
+/*
+ * RX handler
+ * ignore PKTIF because is unreliable! (look at the errata datasheet)
+ * check EPKTCNT is the suggested workaround.
+ * We don't need to clear interrupt flag, automatically done when
+ * enc28j60_hw_rx() decrements the packet counter.
+ * Returns how many packet processed.
+ */
+static int enc28j60_rx_interrupt(struct net_device *ndev)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+       int pk_counter, ret;
+
+       pk_counter = locked_regb_read(priv, EPKTCNT);
+       if (pk_counter && netif_msg_intr(priv))
+               printk(KERN_DEBUG DRV_NAME ": intRX, pk_cnt: %d\n", pk_counter);
+       if (pk_counter > priv->max_pk_counter) {
+               /* update statistics */
+               priv->max_pk_counter = pk_counter;
+               if (netif_msg_rx_status(priv) && priv->max_pk_counter > 1)
+                       printk(KERN_DEBUG DRV_NAME ": RX max_pk_cnt: %d\n",
+                               priv->max_pk_counter);
+       }
+       ret = pk_counter;
+       while (pk_counter-- > 0)
+               enc28j60_hw_rx(ndev);
+
+       return ret;
+}
+
+static void enc28j60_irq_work_handler(struct work_struct *work)
+{
+       struct enc28j60_net *priv =
+               container_of(work, struct enc28j60_net, irq_work);
+       struct net_device *ndev = priv->netdev;
+       int intflags, loop;
+
+       if (netif_msg_intr(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+       /* disable further interrupts */
+       locked_reg_bfclr(priv, EIE, EIE_INTIE);
+
+       do {
+               loop = 0;
+               intflags = locked_regb_read(priv, EIR);
+               /* DMA interrupt handler (not currently used) */
+               if ((intflags & EIR_DMAIF) != 0) {
+                       loop++;
+                       if (netif_msg_intr(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": intDMA(%d)\n", loop);
+                       locked_reg_bfclr(priv, EIR, EIR_DMAIF);
+               }
+               /* LINK changed handler */
+               if ((intflags & EIR_LINKIF) != 0) {
+                       loop++;
+                       if (netif_msg_intr(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": intLINK(%d)\n", loop);
+                       enc28j60_check_link_status(ndev);
+                       /* read PHIR to clear the flag */
+                       enc28j60_phy_read(priv, PHIR);
+               }
+               /* TX complete handler */
+               if ((intflags & EIR_TXIF) != 0) {
+                       bool err = false;
+                       loop++;
+                       if (netif_msg_intr(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": intTX(%d)\n", loop);
+                       priv->tx_retry_count = 0;
+                       if (locked_regb_read(priv, ESTAT) & ESTAT_TXABRT) {
+                               if (netif_msg_tx_err(priv))
+                                       dev_err(&ndev->dev,
+                                               "Tx Error (aborted)\n");
+                               err = true;
+                       }
+                       if (netif_msg_tx_done(priv)) {
+                               u8 tsv[TSV_SIZE];
+                               enc28j60_read_tsv(priv, tsv);
+                               enc28j60_dump_tsv(priv, "Tx Done", tsv);
+                       }
+                       enc28j60_tx_clear(ndev, err);
+                       locked_reg_bfclr(priv, EIR, EIR_TXIF);
+               }
+               /* TX Error handler */
+               if ((intflags & EIR_TXERIF) != 0) {
+                       u8 tsv[TSV_SIZE];
+
+                       loop++;
+                       if (netif_msg_intr(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": intTXErr(%d)\n", loop);
+                       locked_reg_bfclr(priv, ECON1, ECON1_TXRTS);
+                       enc28j60_read_tsv(priv, tsv);
+                       if (netif_msg_tx_err(priv))
+                               enc28j60_dump_tsv(priv, "Tx Error", tsv);
+                       /* Reset TX logic */
+                       mutex_lock(&priv->lock);
+                       nolock_reg_bfset(priv, ECON1, ECON1_TXRST);
+                       nolock_reg_bfclr(priv, ECON1, ECON1_TXRST);
+                       nolock_txfifo_init(priv, TXSTART_INIT, TXEND_INIT);
+                       mutex_unlock(&priv->lock);
+                       /* Transmit Late collision check for retransmit */
+                       if (TSV_GETBIT(tsv, TSV_TXLATECOLLISION)) {
+                               if (netif_msg_tx_err(priv))
+                                       printk(KERN_DEBUG DRV_NAME
+                                               ": LateCollision TXErr (%d)\n",
+                                               priv->tx_retry_count);
+                               if (priv->tx_retry_count++ < MAX_TX_RETRYCOUNT)
+                                       locked_reg_bfset(priv, ECON1,
+                                                          ECON1_TXRTS);
+                               else
+                                       enc28j60_tx_clear(ndev, true);
+                       } else
+                               enc28j60_tx_clear(ndev, true);
+                       locked_reg_bfclr(priv, EIR, EIR_TXERIF);
+               }
+               /* RX Error handler */
+               if ((intflags & EIR_RXERIF) != 0) {
+                       loop++;
+                       if (netif_msg_intr(priv))
+                               printk(KERN_DEBUG DRV_NAME
+                                       ": intRXErr(%d)\n", loop);
+                       /* Check free FIFO space to flag RX overrun */
+                       if (enc28j60_get_free_rxfifo(priv) <= 0) {
+                               if (netif_msg_rx_err(priv))
+                                       printk(KERN_DEBUG DRV_NAME
+                                               ": RX Overrun\n");
+                               ndev->stats.rx_dropped++;
+                       }
+                       locked_reg_bfclr(priv, EIR, EIR_RXERIF);
+               }
+               /* RX handler */
+               if (enc28j60_rx_interrupt(ndev))
+                       loop++;
+       } while (loop);
+
+       /* re-enable interrupts */
+       locked_reg_bfset(priv, EIE, EIE_INTIE);
+       if (netif_msg_intr(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __FUNCTION__);
+}
+
+/*
+ * Hardware transmit function.
+ * Fill the buffer memory and send the contents of the transmit buffer
+ * onto the network
+ */
+static void enc28j60_hw_tx(struct enc28j60_net *priv)
+{
+       if (netif_msg_tx_queued(priv))
+               printk(KERN_DEBUG DRV_NAME
+                       ": Tx Packet Len:%d\n", priv->tx_skb->len);
+
+       if (netif_msg_pktdata(priv))
+               dump_packet(__FUNCTION__,
+                           priv->tx_skb->len, priv->tx_skb->data);
+       enc28j60_packet_write(priv, priv->tx_skb->len, priv->tx_skb->data);
+
+#ifdef CONFIG_ENC28J60_WRITEVERIFY
+       /* readback and verify written data */
+       if (netif_msg_drv(priv)) {
+               int test_len, k;
+               u8 test_buf[64]; /* limit the test to the first 64 bytes */
+               int okflag;
+
+               test_len = priv->tx_skb->len;
+               if (test_len > sizeof(test_buf))
+                       test_len = sizeof(test_buf);
+
+               /* + 1 to skip control byte */
+               enc28j60_mem_read(priv, TXSTART_INIT + 1, test_len, test_buf);
+               okflag = 1;
+               for (k = 0; k < test_len; k++) {
+                       if (priv->tx_skb->data[k] != test_buf[k]) {
+                               printk(KERN_DEBUG DRV_NAME
+                                        ": Error, %d location differ: "
+                                        "0x%02x-0x%02x\n", k,
+                                        priv->tx_skb->data[k], test_buf[k]);
+                               okflag = 0;
+                       }
+               }
+               if (!okflag)
+                       printk(KERN_DEBUG DRV_NAME ": Tx write buffer, "
+                               "verify ERROR!\n");
+       }
+#endif
+       /* set TX request flag */
+       locked_reg_bfset(priv, ECON1, ECON1_TXRTS);
+}
+
+static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+
+       if (netif_msg_tx_queued(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+
+       /* If some error occurs while trying to transmit this
+        * packet, you should return '1' from this function.
+        * In such a case you _may not_ do anything to the
+        * SKB, it is still owned by the network queueing
+        * layer when an error is returned.  This means you
+        * may not modify any SKB fields, you may not free
+        * the SKB, etc.
+        */
+       netif_stop_queue(dev);
+
+       /* save the timestamp */
+       priv->netdev->trans_start = jiffies;
+       /* Remember the skb for deferred processing */
+       priv->tx_skb = skb;
+       schedule_work(&priv->tx_work);
+
+       return 0;
+}
+
+static void enc28j60_tx_work_handler(struct work_struct *work)
+{
+       struct enc28j60_net *priv =
+               container_of(work, struct enc28j60_net, tx_work);
+
+       /* actual delivery of data */
+       enc28j60_hw_tx(priv);
+}
+
+static irqreturn_t enc28j60_irq(int irq, void *dev_id)
+{
+       struct enc28j60_net *priv = dev_id;
+
+       /*
+        * Can't do anything in interrupt context because we need to
+        * block (spi_sync() is blocking) so fire of the interrupt
+        * handling workqueue.
+        * Remember that we access enc28j60 registers through SPI bus
+        * via spi_sync() call.
+        */
+       schedule_work(&priv->irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static void enc28j60_tx_timeout(struct net_device *ndev)
+{
+       struct enc28j60_net *priv = netdev_priv(ndev);
+
+       if (netif_msg_timer(priv))
+               dev_err(&ndev->dev, DRV_NAME " tx timeout\n");
+
+       ndev->stats.tx_errors++;
+       /* can't restart safely under softirq */
+       schedule_work(&priv->restart_work);
+}
+
+/*
+ * Open/initialize the board. This is called (in the current kernel)
+ * sometime after booting when the 'ifconfig' program is run.
+ *
+ * This routine should set everything up anew at each open, even
+ * registers that "should" only need to be set once at boot, so that
+ * there is non-reboot way to recover if something goes wrong.
+ */
+static int enc28j60_net_open(struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+
+       if (netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+
+       if (!is_valid_ether_addr(dev->dev_addr)) {
+               if (netif_msg_ifup(priv)) {
+                       DECLARE_MAC_BUF(mac);
+                       dev_err(&dev->dev, "invalid MAC address %s\n",
+                               print_mac(mac, dev->dev_addr));
+               }
+               return -EADDRNOTAVAIL;
+       }
+       /* Reset the hardware here */
+       enc28j60_hw_disable(priv);
+       if (!enc28j60_hw_init(priv)) {
+               if (netif_msg_ifup(priv))
+                       dev_err(&dev->dev, "hw_reset() failed\n");
+               return -EINVAL;
+       }
+       /* Update the MAC address (in case user has changed it) */
+       enc28j60_set_hw_macaddr(dev);
+       /* Enable interrupts */
+       enc28j60_hw_enable(priv);
+       /* check link status */
+       enc28j60_check_link_status(dev);
+       /* We are now ready to accept transmit requests from
+        * the queueing layer of the networking.
+        */
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+/* The inverse routine to net_open(). */
+static int enc28j60_net_close(struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+
+       if (netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+
+       enc28j60_hw_disable(priv);
+       netif_stop_queue(dev);
+
+       return 0;
+}
+
+/*
+ * Set or clear the multicast filter for this adapter
+ * num_addrs == -1     Promiscuous mode, receive all packets
+ * num_addrs == 0      Normal mode, filter out multicast packets
+ * num_addrs > 0       Multicast mode, receive normal and MC packets
+ */
+static void enc28j60_set_multicast_list(struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+       int oldfilter = priv->rxfilter;
+
+       if (dev->flags & IFF_PROMISC) {
+               if (netif_msg_link(priv))
+                       dev_info(&dev->dev, "promiscuous mode\n");
+               priv->rxfilter = RXFILTER_PROMISC;
+       } else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count) {
+               if (netif_msg_link(priv))
+                       dev_info(&dev->dev, "%smulticast mode\n",
+                               (dev->flags & IFF_ALLMULTI) ? "all-" : "");
+               priv->rxfilter = RXFILTER_MULTI;
+       } else {
+               if (netif_msg_link(priv))
+                       dev_info(&dev->dev, "normal mode\n");
+               priv->rxfilter = RXFILTER_NORMAL;
+       }
+
+       if (oldfilter != priv->rxfilter)
+               schedule_work(&priv->setrx_work);
+}
+
+static void enc28j60_setrx_work_handler(struct work_struct *work)
+{
+       struct enc28j60_net *priv =
+               container_of(work, struct enc28j60_net, setrx_work);
+
+       if (priv->rxfilter == RXFILTER_PROMISC) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME ": promiscuous mode\n");
+               locked_regb_write(priv, ERXFCON, 0x00);
+       } else if (priv->rxfilter == RXFILTER_MULTI) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME ": multicast mode\n");
+               locked_regb_write(priv, ERXFCON,
+                                       ERXFCON_UCEN | ERXFCON_CRCEN |
+                                       ERXFCON_BCEN | ERXFCON_MCEN);
+       } else {
+               if (netif_msg_drv(priv))
+                       printk(KERN_DEBUG DRV_NAME ": normal mode\n");
+               locked_regb_write(priv, ERXFCON,
+                                       ERXFCON_UCEN | ERXFCON_CRCEN |
+                                       ERXFCON_BCEN);
+       }
+}
+
+static void enc28j60_restart_work_handler(struct work_struct *work)
+{
+       struct enc28j60_net *priv =
+                       container_of(work, struct enc28j60_net, restart_work);
+       struct net_device *ndev = priv->netdev;
+       int ret;
+
+       rtnl_lock();
+       if (netif_running(ndev)) {
+               enc28j60_net_close(ndev);
+               ret = enc28j60_net_open(ndev);
+               if (unlikely(ret)) {
+                       dev_info(&ndev->dev, " could not restart %d\n", ret);
+                       dev_close(ndev);
+               }
+       }
+       rtnl_unlock();
+}
+
+/* ......................... ETHTOOL SUPPORT ........................... */
+
+static void
+enc28j60_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+       strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+       strlcpy(info->bus_info,
+               dev->dev.parent->bus_id, sizeof(info->bus_info));
+}
+
+static int
+enc28j60_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+
+       cmd->transceiver = XCVR_INTERNAL;
+       cmd->supported  = SUPPORTED_10baseT_Half
+                       | SUPPORTED_10baseT_Full
+                       | SUPPORTED_TP;
+       cmd->speed      = SPEED_10;
+       cmd->duplex     = priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
+       cmd->port       = PORT_TP;
+       cmd->autoneg    = AUTONEG_DISABLE;
+
+       return 0;
+}
+
+static int
+enc28j60_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       return enc28j60_setlink(dev, cmd->autoneg, cmd->speed, cmd->duplex);
+}
+
+static u32 enc28j60_get_msglevel(struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+       return priv->msg_enable;
+}
+
+static void enc28j60_set_msglevel(struct net_device *dev, u32 val)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+       priv->msg_enable = val;
+}
+
+static const struct ethtool_ops enc28j60_ethtool_ops = {
+       .get_settings   = enc28j60_get_settings,
+       .set_settings   = enc28j60_set_settings,
+       .get_drvinfo    = enc28j60_get_drvinfo,
+       .get_msglevel   = enc28j60_get_msglevel,
+       .set_msglevel   = enc28j60_set_msglevel,
+};
+
+static int enc28j60_chipset_init(struct net_device *dev)
+{
+       struct enc28j60_net *priv = netdev_priv(dev);
+
+       return enc28j60_hw_init(priv);
+}
+
+static int __devinit enc28j60_probe(struct spi_device *spi)
+{
+       struct net_device *dev;
+       struct enc28j60_net *priv;
+       int ret = 0;
+
+       if (netif_msg_drv(&debug))
+               dev_info(&spi->dev, DRV_NAME " Ethernet driver %s loaded\n",
+                       DRV_VERSION);
+
+       dev = alloc_etherdev(sizeof(struct enc28j60_net));
+       if (!dev) {
+               if (netif_msg_drv(&debug))
+                       dev_err(&spi->dev, DRV_NAME
+                               ": unable to alloc new ethernet\n");
+               ret = -ENOMEM;
+               goto error_alloc;
+       }
+       priv = netdev_priv(dev);
+
+       priv->netdev = dev;     /* priv to netdev reference */
+       priv->spi = spi;        /* priv to spi reference */
+       priv->msg_enable = netif_msg_init(debug.msg_enable,
+                                               ENC28J60_MSG_DEFAULT);
+       mutex_init(&priv->lock);
+       INIT_WORK(&priv->tx_work, enc28j60_tx_work_handler);
+       INIT_WORK(&priv->setrx_work, enc28j60_setrx_work_handler);
+       INIT_WORK(&priv->irq_work, enc28j60_irq_work_handler);
+       INIT_WORK(&priv->restart_work, enc28j60_restart_work_handler);
+       dev_set_drvdata(&spi->dev, priv);       /* spi to priv reference */
+       SET_NETDEV_DEV(dev, &spi->dev);
+
+       if (!enc28j60_chipset_init(dev)) {
+               if (netif_msg_probe(priv))
+                       dev_info(&spi->dev, DRV_NAME " chip not found\n");
+               ret = -EIO;
+               goto error_irq;
+       }
+       random_ether_addr(dev->dev_addr);
+       enc28j60_set_hw_macaddr(dev);
+
+       ret = request_irq(spi->irq, enc28j60_irq, IRQF_TRIGGER_FALLING,
+                         DRV_NAME, priv);
+       if (ret < 0) {
+               if (netif_msg_probe(priv))
+                       dev_err(&spi->dev, DRV_NAME ": request irq %d failed "
+                               "(ret = %d)\n", spi->irq, ret);
+               goto error_irq;
+       }
+
+       dev->if_port = IF_PORT_10BASET;
+       dev->irq = spi->irq;
+       dev->open = enc28j60_net_open;
+       dev->stop = enc28j60_net_close;
+       dev->hard_start_xmit = enc28j60_send_packet;
+       dev->set_multicast_list = &enc28j60_set_multicast_list;
+       dev->set_mac_address = enc28j60_set_mac_address;
+       dev->tx_timeout = &enc28j60_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+       SET_ETHTOOL_OPS(dev, &enc28j60_ethtool_ops);
+
+       ret = register_netdev(dev);
+       if (ret) {
+               if (netif_msg_probe(priv))
+                       dev_err(&spi->dev, "register netdev " DRV_NAME
+                               " failed (ret = %d)\n", ret);
+               goto error_register;
+       }
+       dev_info(&dev->dev, DRV_NAME " driver registered\n");
+
+       return 0;
+
+error_register:
+       free_irq(spi->irq, priv);
+error_irq:
+       free_netdev(dev);
+error_alloc:
+       return ret;
+}
+
+static int enc28j60_remove(struct spi_device *spi)
+{
+       struct enc28j60_net *priv = dev_get_drvdata(&spi->dev);
+
+       if (netif_msg_drv(priv))
+               printk(KERN_DEBUG DRV_NAME ": remove\n");
+
+       unregister_netdev(priv->netdev);
+       free_irq(spi->irq, priv);
+       free_netdev(priv->netdev);
+
+       return 0;
+}
+
+static struct spi_driver enc28j60_driver = {
+       .driver = {
+                  .name = DRV_NAME,
+                  .bus = &spi_bus_type,
+                  .owner = THIS_MODULE,
+                  },
+       .probe = enc28j60_probe,
+       .remove = __devexit_p(enc28j60_remove),
+};
+
+static int __init enc28j60_init(void)
+{
+       return spi_register_driver(&enc28j60_driver);
+}
+
+module_init(enc28j60_init);
+
+static void __exit enc28j60_exit(void)
+{
+       spi_unregister_driver(&enc28j60_driver);
+}
+
+module_exit(enc28j60_exit);
+
+MODULE_DESCRIPTION(DRV_NAME " ethernet driver");
+MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>");
+MODULE_LICENSE("GPL");
+module_param_named(debug, debug.msg_enable, int, 0);
+MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., ffff=all)");
diff --git a/drivers/net/enc28j60_hw.h b/drivers/net/enc28j60_hw.h
new file mode 100644 (file)
index 0000000..1a0b209
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * enc28j60_hw.h: EDTP FrameThrower style enc28j60 registers
+ *
+ * $Id: enc28j60_hw.h,v 1.9 2007/12/14 11:59:16 claudio Exp $
+ */
+
+#ifndef _ENC28J60_HW_H
+#define _ENC28J60_HW_H
+
+/*
+ * ENC28J60 Control Registers
+ * Control register definitions are a combination of address,
+ * bank number, and Ethernet/MAC/PHY indicator bits.
+ * - Register address  (bits 0-4)
+ * - Bank number       (bits 5-6)
+ * - MAC/MII indicator (bit 7)
+ */
+#define ADDR_MASK      0x1F
+#define BANK_MASK      0x60
+#define SPRD_MASK      0x80
+/* All-bank registers */
+#define EIE            0x1B
+#define EIR            0x1C
+#define ESTAT          0x1D
+#define ECON2          0x1E
+#define ECON1          0x1F
+/* Bank 0 registers */
+#define ERDPTL         (0x00|0x00)
+#define ERDPTH         (0x01|0x00)
+#define EWRPTL         (0x02|0x00)
+#define EWRPTH         (0x03|0x00)
+#define ETXSTL         (0x04|0x00)
+#define ETXSTH         (0x05|0x00)
+#define ETXNDL         (0x06|0x00)
+#define ETXNDH         (0x07|0x00)
+#define ERXSTL         (0x08|0x00)
+#define ERXSTH         (0x09|0x00)
+#define ERXNDL         (0x0A|0x00)
+#define ERXNDH         (0x0B|0x00)
+#define ERXRDPTL       (0x0C|0x00)
+#define ERXRDPTH       (0x0D|0x00)
+#define ERXWRPTL       (0x0E|0x00)
+#define ERXWRPTH       (0x0F|0x00)
+#define EDMASTL                (0x10|0x00)
+#define EDMASTH                (0x11|0x00)
+#define EDMANDL                (0x12|0x00)
+#define EDMANDH                (0x13|0x00)
+#define EDMADSTL       (0x14|0x00)
+#define EDMADSTH       (0x15|0x00)
+#define EDMACSL                (0x16|0x00)
+#define EDMACSH                (0x17|0x00)
+/* Bank 1 registers */
+#define EHT0           (0x00|0x20)
+#define EHT1           (0x01|0x20)
+#define EHT2           (0x02|0x20)
+#define EHT3           (0x03|0x20)
+#define EHT4           (0x04|0x20)
+#define EHT5           (0x05|0x20)
+#define EHT6           (0x06|0x20)
+#define EHT7           (0x07|0x20)
+#define EPMM0          (0x08|0x20)
+#define EPMM1          (0x09|0x20)
+#define EPMM2          (0x0A|0x20)
+#define EPMM3          (0x0B|0x20)
+#define EPMM4          (0x0C|0x20)
+#define EPMM5          (0x0D|0x20)
+#define EPMM6          (0x0E|0x20)
+#define EPMM7          (0x0F|0x20)
+#define EPMCSL         (0x10|0x20)
+#define EPMCSH         (0x11|0x20)
+#define EPMOL          (0x14|0x20)
+#define EPMOH          (0x15|0x20)
+#define EWOLIE         (0x16|0x20)
+#define EWOLIR         (0x17|0x20)
+#define ERXFCON                (0x18|0x20)
+#define EPKTCNT                (0x19|0x20)
+/* Bank 2 registers */
+#define MACON1         (0x00|0x40|SPRD_MASK)
+/* #define MACON2      (0x01|0x40|SPRD_MASK) */
+#define MACON3         (0x02|0x40|SPRD_MASK)
+#define MACON4         (0x03|0x40|SPRD_MASK)
+#define MABBIPG                (0x04|0x40|SPRD_MASK)
+#define MAIPGL         (0x06|0x40|SPRD_MASK)
+#define MAIPGH         (0x07|0x40|SPRD_MASK)
+#define MACLCON1       (0x08|0x40|SPRD_MASK)
+#define MACLCON2       (0x09|0x40|SPRD_MASK)
+#define MAMXFLL                (0x0A|0x40|SPRD_MASK)
+#define MAMXFLH                (0x0B|0x40|SPRD_MASK)
+#define MAPHSUP                (0x0D|0x40|SPRD_MASK)
+#define MICON          (0x11|0x40|SPRD_MASK)
+#define MICMD          (0x12|0x40|SPRD_MASK)
+#define MIREGADR       (0x14|0x40|SPRD_MASK)
+#define MIWRL          (0x16|0x40|SPRD_MASK)
+#define MIWRH          (0x17|0x40|SPRD_MASK)
+#define MIRDL          (0x18|0x40|SPRD_MASK)
+#define MIRDH          (0x19|0x40|SPRD_MASK)
+/* Bank 3 registers */
+#define MAADR1         (0x00|0x60|SPRD_MASK)
+#define MAADR0         (0x01|0x60|SPRD_MASK)
+#define MAADR3         (0x02|0x60|SPRD_MASK)
+#define MAADR2         (0x03|0x60|SPRD_MASK)
+#define MAADR5         (0x04|0x60|SPRD_MASK)
+#define MAADR4         (0x05|0x60|SPRD_MASK)
+#define EBSTSD         (0x06|0x60)
+#define EBSTCON                (0x07|0x60)
+#define EBSTCSL                (0x08|0x60)
+#define EBSTCSH                (0x09|0x60)
+#define MISTAT         (0x0A|0x60|SPRD_MASK)
+#define EREVID         (0x12|0x60)
+#define ECOCON         (0x15|0x60)
+#define EFLOCON                (0x17|0x60)
+#define EPAUSL         (0x18|0x60)
+#define EPAUSH         (0x19|0x60)
+/* PHY registers */
+#define PHCON1         0x00
+#define PHSTAT1                0x01
+#define PHHID1         0x02
+#define PHHID2         0x03
+#define PHCON2         0x10
+#define PHSTAT2                0x11
+#define PHIE           0x12
+#define PHIR           0x13
+#define PHLCON         0x14
+
+/* ENC28J60 EIE Register Bit Definitions */
+#define EIE_INTIE      0x80
+#define EIE_PKTIE      0x40
+#define EIE_DMAIE      0x20
+#define EIE_LINKIE     0x10
+#define EIE_TXIE       0x08
+/* #define EIE_WOLIE   0x04 (reserved) */
+#define EIE_TXERIE     0x02
+#define EIE_RXERIE     0x01
+/* ENC28J60 EIR Register Bit Definitions */
+#define EIR_PKTIF      0x40
+#define EIR_DMAIF      0x20
+#define EIR_LINKIF     0x10
+#define EIR_TXIF       0x08
+/* #define EIR_WOLIF   0x04 (reserved) */
+#define EIR_TXERIF     0x02
+#define EIR_RXERIF     0x01
+/* ENC28J60 ESTAT Register Bit Definitions */
+#define ESTAT_INT      0x80
+#define ESTAT_LATECOL  0x10
+#define ESTAT_RXBUSY   0x04
+#define ESTAT_TXABRT   0x02
+#define ESTAT_CLKRDY   0x01
+/* ENC28J60 ECON2 Register Bit Definitions */
+#define ECON2_AUTOINC  0x80
+#define ECON2_PKTDEC   0x40
+#define ECON2_PWRSV    0x20
+#define ECON2_VRPS     0x08
+/* ENC28J60 ECON1 Register Bit Definitions */
+#define ECON1_TXRST    0x80
+#define ECON1_RXRST    0x40
+#define ECON1_DMAST    0x20
+#define ECON1_CSUMEN   0x10
+#define ECON1_TXRTS    0x08
+#define ECON1_RXEN     0x04
+#define ECON1_BSEL1    0x02
+#define ECON1_BSEL0    0x01
+/* ENC28J60 MACON1 Register Bit Definitions */
+#define MACON1_LOOPBK  0x10
+#define MACON1_TXPAUS  0x08
+#define MACON1_RXPAUS  0x04
+#define MACON1_PASSALL 0x02
+#define MACON1_MARXEN  0x01
+/* ENC28J60 MACON2 Register Bit Definitions */
+#define MACON2_MARST   0x80
+#define MACON2_RNDRST  0x40
+#define MACON2_MARXRST 0x08
+#define MACON2_RFUNRST 0x04
+#define MACON2_MATXRST 0x02
+#define MACON2_TFUNRST 0x01
+/* ENC28J60 MACON3 Register Bit Definitions */
+#define MACON3_PADCFG2 0x80
+#define MACON3_PADCFG1 0x40
+#define MACON3_PADCFG0 0x20
+#define MACON3_TXCRCEN 0x10
+#define MACON3_PHDRLEN 0x08
+#define MACON3_HFRMLEN 0x04
+#define MACON3_FRMLNEN 0x02
+#define MACON3_FULDPX  0x01
+/* ENC28J60 MICMD Register Bit Definitions */
+#define MICMD_MIISCAN  0x02
+#define MICMD_MIIRD    0x01
+/* ENC28J60 MISTAT Register Bit Definitions */
+#define MISTAT_NVALID  0x04
+#define MISTAT_SCAN    0x02
+#define MISTAT_BUSY    0x01
+/* ENC28J60 ERXFCON Register Bit Definitions */
+#define ERXFCON_UCEN   0x80
+#define ERXFCON_ANDOR  0x40
+#define ERXFCON_CRCEN  0x20
+#define ERXFCON_PMEN   0x10
+#define ERXFCON_MPEN   0x08
+#define ERXFCON_HTEN   0x04
+#define ERXFCON_MCEN   0x02
+#define ERXFCON_BCEN   0x01
+
+/* ENC28J60 PHY PHCON1 Register Bit Definitions */
+#define PHCON1_PRST    0x8000
+#define PHCON1_PLOOPBK 0x4000
+#define PHCON1_PPWRSV  0x0800
+#define PHCON1_PDPXMD  0x0100
+/* ENC28J60 PHY PHSTAT1 Register Bit Definitions */
+#define PHSTAT1_PFDPX  0x1000
+#define PHSTAT1_PHDPX  0x0800
+#define PHSTAT1_LLSTAT 0x0004
+#define PHSTAT1_JBSTAT 0x0002
+/* ENC28J60 PHY PHSTAT2 Register Bit Definitions */
+#define PHSTAT2_TXSTAT (1 << 13)
+#define PHSTAT2_RXSTAT (1 << 12)
+#define PHSTAT2_COLSTAT        (1 << 11)
+#define PHSTAT2_LSTAT  (1 << 10)
+#define PHSTAT2_DPXSTAT        (1 << 9)
+#define PHSTAT2_PLRITY (1 << 5)
+/* ENC28J60 PHY PHCON2 Register Bit Definitions */
+#define PHCON2_FRCLINK 0x4000
+#define PHCON2_TXDIS   0x2000
+#define PHCON2_JABBER  0x0400
+#define PHCON2_HDLDIS  0x0100
+/* ENC28J60 PHY PHIE Register Bit Definitions */
+#define PHIE_PLNKIE    (1 << 4)
+#define PHIE_PGEIE     (1 << 1)
+/* ENC28J60 PHY PHIR Register Bit Definitions */
+#define PHIR_PLNKIF    (1 << 4)
+#define PHIR_PGEIF     (1 << 1)
+
+/* ENC28J60 Packet Control Byte Bit Definitions */
+#define PKTCTRL_PHUGEEN                0x08
+#define PKTCTRL_PPADEN         0x04
+#define PKTCTRL_PCRCEN         0x02
+#define PKTCTRL_POVERRIDE      0x01
+
+/* ENC28J60 Transmit Status Vector */
+#define TSV_TXBYTECNT          0
+#define TSV_TXCOLLISIONCNT     16
+#define TSV_TXCRCERROR         20
+#define TSV_TXLENCHKERROR      21
+#define TSV_TXLENOUTOFRANGE    22
+#define TSV_TXDONE             23
+#define TSV_TXMULTICAST                24
+#define TSV_TXBROADCAST                25
+#define TSV_TXPACKETDEFER      26
+#define TSV_TXEXDEFER          27
+#define TSV_TXEXCOLLISION      28
+#define TSV_TXLATECOLLISION    29
+#define TSV_TXGIANT            30
+#define TSV_TXUNDERRUN         31
+#define TSV_TOTBYTETXONWIRE    32
+#define TSV_TXCONTROLFRAME     48
+#define TSV_TXPAUSEFRAME       49
+#define TSV_BACKPRESSUREAPP    50
+#define TSV_TXVLANTAGFRAME     51
+
+#define TSV_SIZE               7
+#define TSV_BYTEOF(x)          ((x) / 8)
+#define TSV_BITMASK(x)         (1 << ((x) % 8))
+#define TSV_GETBIT(x, y)       (((x)[TSV_BYTEOF(y)] & TSV_BITMASK(y)) ? 1 : 0)
+
+/* ENC28J60 Receive Status Vector */
+#define RSV_RXLONGEVDROPEV     16
+#define RSV_CARRIEREV          18
+#define RSV_CRCERROR           20
+#define RSV_LENCHECKERR                21
+#define RSV_LENOUTOFRANGE      22
+#define RSV_RXOK               23
+#define RSV_RXMULTICAST                24
+#define RSV_RXBROADCAST                25
+#define RSV_DRIBBLENIBBLE      26
+#define RSV_RXCONTROLFRAME     27
+#define RSV_RXPAUSEFRAME       28
+#define RSV_RXUNKNOWNOPCODE    29
+#define RSV_RXTYPEVLAN         30
+
+#define RSV_SIZE               6
+#define RSV_BITMASK(x)         (1 << ((x) - 16))
+#define RSV_GETBIT(x, y)       (((x) & RSV_BITMASK(y)) ? 1 : 0)
+
+
+/* SPI operation codes */
+#define ENC28J60_READ_CTRL_REG 0x00
+#define ENC28J60_READ_BUF_MEM  0x3A
+#define ENC28J60_WRITE_CTRL_REG 0x40
+#define ENC28J60_WRITE_BUF_MEM 0x7A
+#define ENC28J60_BIT_FIELD_SET 0x80
+#define ENC28J60_BIT_FIELD_CLR 0xA0
+#define ENC28J60_SOFT_RESET    0xFF
+
+
+/* buffer boundaries applied to internal 8K ram
+ * entire available packet buffer space is allocated.
+ * Give TX buffer space for one full ethernet frame (~1500 bytes)
+ * receive buffer gets the rest */
+#define TXSTART_INIT           0x1A00
+#define TXEND_INIT             0x1FFF
+
+/* Put RX buffer at 0 as suggested by the Errata datasheet */
+#define RXSTART_INIT           0x0000
+#define RXEND_INIT             0x19FF
+
+/* maximum ethernet frame length */
+#define MAX_FRAMELEN           1518
+
+/* Prefered half duplex: LEDA: Link status LEDB: Rx/Tx activity */
+#define ENC28J60_LAMPS_MODE    0x3476
+
+#endif
index f84c752997a46c92e03133691ab08d61d37c0c27..7667a62ac31f33c822c03f6ad11619d54e91d7ac 100644 (file)
@@ -712,8 +712,8 @@ static const struct nv_ethtool_str nv_etests_str[] = {
 };
 
 struct register_test {
-       __le32 reg;
-       __le32 mask;
+       __u32 reg;
+       __u32 mask;
 };
 
 static const struct register_test nv_registers_test[] = {
@@ -929,6 +929,16 @@ static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target,
 #define NV_SETUP_RX_RING 0x01
 #define NV_SETUP_TX_RING 0x02
 
+static inline u32 dma_low(dma_addr_t addr)
+{
+       return addr;
+}
+
+static inline u32 dma_high(dma_addr_t addr)
+{
+       return addr>>31>>1;     /* 0 if 32bit, shift down by 32 if 64bit */
+}
+
 static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
 {
        struct fe_priv *np = get_nvpriv(dev);
@@ -936,19 +946,19 @@ static void setup_hw_rings(struct net_device *dev, int rxtx_flags)
 
        if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
                if (rxtx_flags & NV_SETUP_RX_RING) {
-                       writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr);
+                       writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
                }
                if (rxtx_flags & NV_SETUP_TX_RING) {
-                       writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
+                       writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr);
                }
        } else {
                if (rxtx_flags & NV_SETUP_RX_RING) {
-                       writel((u32) cpu_to_le64(np->ring_addr), base + NvRegRxRingPhysAddr);
-                       writel((u32) (cpu_to_le64(np->ring_addr) >> 32), base + NvRegRxRingPhysAddrHigh);
+                       writel(dma_low(np->ring_addr), base + NvRegRxRingPhysAddr);
+                       writel(dma_high(np->ring_addr), base + NvRegRxRingPhysAddrHigh);
                }
                if (rxtx_flags & NV_SETUP_TX_RING) {
-                       writel((u32) cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr);
-                       writel((u32) (cpu_to_le64(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)) >> 32), base + NvRegTxRingPhysAddrHigh);
+                       writel(dma_low(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr);
+                       writel(dma_high(np->ring_addr + np->rx_ring_size*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddrHigh);
                }
        }
 }
@@ -1571,8 +1581,8 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
                                                             skb_tailroom(skb),
                                                             PCI_DMA_FROMDEVICE);
                        np->put_rx_ctx->dma_len = skb_tailroom(skb);
-                       np->put_rx.ex->bufhigh = cpu_to_le64(np->put_rx_ctx->dma) >> 32;
-                       np->put_rx.ex->buflow = cpu_to_le64(np->put_rx_ctx->dma) & 0x0FFFFFFFF;
+                       np->put_rx.ex->bufhigh = cpu_to_le32(dma_high(np->put_rx_ctx->dma));
+                       np->put_rx.ex->buflow = cpu_to_le32(dma_low(np->put_rx_ctx->dma));
                        wmb();
                        np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL);
                        if (unlikely(np->put_rx.ex++ == np->last_rx.ex))
@@ -1937,8 +1947,8 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
                np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
                                                PCI_DMA_TODEVICE);
                np->put_tx_ctx->dma_len = bcnt;
-               put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
-               put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF;
+               put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
+               put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
                put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
                tx_flags = NV_TX2_VALID;
@@ -1963,8 +1973,8 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
                        np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
                                                           PCI_DMA_TODEVICE);
                        np->put_tx_ctx->dma_len = bcnt;
-                       put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
-                       put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FFFFFFFF;
+                       put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
+                       put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
                        put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
                        offset += bcnt;
@@ -2680,8 +2690,8 @@ static void nv_set_multicast(struct net_device *dev)
                                walk = dev->mc_list;
                                while (walk != NULL) {
                                        u32 a, b;
-                                       a = le32_to_cpu(*(u32 *) walk->dmi_addr);
-                                       b = le16_to_cpu(*(u16 *) (&walk->dmi_addr[4]));
+                                       a = le32_to_cpu(*(__le32 *) walk->dmi_addr);
+                                       b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4]));
                                        alwaysOn[0] &= a;
                                        alwaysOff[0] &= ~a;
                                        alwaysOn[1] &= b;
@@ -4539,8 +4549,8 @@ static int nv_loopback_test(struct net_device *dev)
                np->tx_ring.orig[0].buf = cpu_to_le32(test_dma_addr);
                np->tx_ring.orig[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
        } else {
-               np->tx_ring.ex[0].bufhigh = cpu_to_le64(test_dma_addr) >> 32;
-               np->tx_ring.ex[0].buflow = cpu_to_le64(test_dma_addr) & 0x0FFFFFFFF;
+               np->tx_ring.ex[0].bufhigh = cpu_to_le32(dma_high(test_dma_addr));
+               np->tx_ring.ex[0].buflow = cpu_to_le32(dma_low(test_dma_addr));
                np->tx_ring.ex[0].flaglen = cpu_to_le32((pkt_len-1) | np->tx_flags | tx_flags_extra);
        }
        writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
index aec9ab17a9a5884df180ac4e26ec59b3ec82185c..230878b9419053ee65621528d7710e3f74677f94 100644 (file)
 
 #include "gianfar.h"
 
-#define GFAR_ATTR(_name) \
-static ssize_t gfar_show_##_name(struct device *dev, \
-        struct device_attribute *attr, char *buf); \
-static ssize_t gfar_set_##_name(struct device *dev, \
-               struct device_attribute *attr, \
-               const char *buf, size_t count); \
-static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
-
-#define GFAR_CREATE_FILE(_dev, _name) \
-       device_create_file(&_dev->dev, &dev_attr_##_name)
-
-GFAR_ATTR(bd_stash);
-GFAR_ATTR(rx_stash_size);
-GFAR_ATTR(rx_stash_index);
-GFAR_ATTR(fifo_threshold);
-GFAR_ATTR(fifo_starve);
-GFAR_ATTR(fifo_starve_off);
-
 static ssize_t gfar_show_bd_stash(struct device *dev,
                                  struct device_attribute *attr, char *buf)
 {
@@ -100,6 +82,8 @@ static ssize_t gfar_set_bd_stash(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash);
+
 static ssize_t gfar_show_rx_stash_size(struct device *dev,
                                       struct device_attribute *attr, char *buf)
 {
@@ -146,6 +130,9 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size,
+           gfar_set_rx_stash_size);
+
 /* Stashing will only be enabled when rx_stash_size != 0 */
 static ssize_t gfar_show_rx_stash_index(struct device *dev,
                                        struct device_attribute *attr,
@@ -184,6 +171,9 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index,
+           gfar_set_rx_stash_index);
+
 static ssize_t gfar_show_fifo_threshold(struct device *dev,
                                        struct device_attribute *attr,
                                        char *buf)
@@ -219,6 +209,9 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold,
+           gfar_set_fifo_threshold);
+
 static ssize_t gfar_show_fifo_starve(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
@@ -253,6 +246,8 @@ static ssize_t gfar_set_fifo_starve(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve);
+
 static ssize_t gfar_show_fifo_starve_off(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
@@ -288,9 +283,13 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev,
        return count;
 }
 
+DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off,
+           gfar_set_fifo_starve_off);
+
 void gfar_init_sysfs(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
+       int rc;
 
        /* Initialize the default values */
        priv->rx_stash_size = DEFAULT_STASH_LENGTH;
@@ -301,11 +300,12 @@ void gfar_init_sysfs(struct net_device *dev)
        priv->bd_stash_en = DEFAULT_BD_STASH;
 
        /* Create our sysfs files */
-       GFAR_CREATE_FILE(dev, bd_stash);
-       GFAR_CREATE_FILE(dev, rx_stash_size);
-       GFAR_CREATE_FILE(dev, rx_stash_index);
-       GFAR_CREATE_FILE(dev, fifo_threshold);
-       GFAR_CREATE_FILE(dev, fifo_starve);
-       GFAR_CREATE_FILE(dev, fifo_starve_off);
-
+       rc = device_create_file(&dev->dev, &dev_attr_bd_stash);
+       rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size);
+       rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index);
+       rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold);
+       rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve);
+       rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off);
+       if (rc)
+               dev_err(&dev->dev, "Error creating gianfar sysfs files.\n");
 }
index 580cb4ab2af10042fccc2d94e5fad7448944cac1..0a9b75139e0f1f82e648df994b79aa9b05a7d20f 100644 (file)
@@ -701,7 +701,7 @@ static void sixpack_close(struct tty_struct *tty)
        sp = tty->disc_data;
        tty->disc_data = NULL;
        write_unlock(&disc_data_lock);
-       if (sp == 0)
+       if (!sp)
                return;
 
        /*
index 803a3bdea0af5f1e36d02055157f55107aff7c87..cfcd15af501e794777c0926ba45539b0dbfe89c1 100644 (file)
@@ -821,7 +821,7 @@ static void mkiss_close(struct tty_struct *tty)
        tty->disc_data = NULL;
        write_unlock(&disc_data_lock);
 
-       if (ax == 0)
+       if (!ax)
                return;
 
        /*
index 353d13e543ce12228428b90d14df93f903d76b45..f90515935833a8cb25f8dc82b3a67540cb7008af 100644 (file)
@@ -201,7 +201,6 @@ static void z8530_init(void);
 
 static void init_channel(struct scc_channel *scc);
 static void scc_key_trx (struct scc_channel *scc, char tx);
-static irqreturn_t scc_isr(int irq, void *dev_id);
 static void scc_init_timer(struct scc_channel *scc);
 
 static int scc_net_alloc(const char *name, struct scc_channel *scc);
@@ -629,6 +628,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector)
 
 static irqreturn_t scc_isr(int irq, void *dev_id)
 {
+       int chip_irq = (long) dev_id;
        unsigned char vector;   
        struct scc_channel *scc;
        struct scc_ctrl *ctrl;
@@ -665,7 +665,7 @@ static irqreturn_t scc_isr(int irq, void *dev_id)
        ctrl = SCC_ctrl;
        while (ctrl->chan_A)
        {
-               if (ctrl->irq != irq)
+               if (ctrl->irq != chip_irq)
                {
                        ctrl++;
                        continue;
@@ -1732,7 +1732,9 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                                
                        if (!Ivec[hwcfg.irq].used && hwcfg.irq)
                        {
-                               if (request_irq(hwcfg.irq, scc_isr, IRQF_DISABLED, "AX.25 SCC", NULL))
+                               if (request_irq(hwcfg.irq, scc_isr,
+                                               IRQF_DISABLED, "AX.25 SCC",
+                                               (void *)(long) hwcfg.irq))
                                        printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq);
                                else
                                        Ivec[hwcfg.irq].used = 1;
index 49421d1cd3a5d61e1bb4afcd6533478fd8526e31..571dd80fb85009910f6a49d3cda27baa085b54f1 100644 (file)
@@ -1153,7 +1153,7 @@ static void hp100_init_pdls(struct net_device *dev)
        printk("hp100: %s: init pdls\n", dev->name);
 #endif
 
-       if (0 == lp->page_vaddr_algn)
+       if (!lp->page_vaddr_algn)
                printk("hp100: %s: Warning: lp->page_vaddr_algn not initialised!\n", dev->name);
        else {
                /* pageptr shall point into the DMA accessible memory region  */
index cb06280dced5234806ec28c4c6235f0ab978769d..b24bd2dfb7258d27293560db32aedb5ff7a6f80a 100644 (file)
@@ -1297,7 +1297,6 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        return emac_xmit_finish(dev, len);
 }
 
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
 static inline int emac_xmit_split(struct emac_instance *dev, int slot,
                                  u32 pd, int len, int last, u16 base_ctrl)
 {
@@ -1410,9 +1409,6 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
        DBG2(dev, "stopped TX queue" NL);
        return 1;
 }
-#else
-# define emac_start_xmit_sg    emac_start_xmit
-#endif /* !defined(CONFIG_IBM_NEW_EMAC_TAH) */
 
 /* Tx lock BHs */
 static void emac_parse_tx_error(struct emac_instance *dev, u16 ctrl)
@@ -2683,13 +2679,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
 
        /* Fill in the driver function table */
        ndev->open = &emac_open;
-#ifdef CONFIG_IBM_NEW_EMAC_TAH
-       if (dev->tah_dev) {
-               ndev->hard_start_xmit = &emac_start_xmit_sg;
+       if (dev->tah_dev)
                ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-       } else
-#endif
-               ndev->hard_start_xmit = &emac_start_xmit;
        ndev->tx_timeout = &emac_tx_timeout;
        ndev->watchdog_timeo = 5 * HZ;
        ndev->stop = &emac_close;
@@ -2697,8 +2688,11 @@ static int __devinit emac_probe(struct of_device *ofdev,
        ndev->set_multicast_list = &emac_set_multicast_list;
        ndev->do_ioctl = &emac_ioctl;
        if (emac_phy_supports_gige(dev->phy_mode)) {
+               ndev->hard_start_xmit = &emac_start_xmit_sg;
                ndev->change_mtu = &emac_change_mtu;
                dev->commac.ops = &emac_commac_sg_ops;
+       } else {
+               ndev->hard_start_xmit = &emac_start_xmit;
        }
        SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 
index 91d83aca6bc784e886ca15c508dc9125251c2963..46e2c52c7862f436248d85942e6c4cb418b16023 100644 (file)
@@ -83,7 +83,7 @@ History:
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/time.h>
-#include <linux/mca-legacy.h>
+#include <linux/mca.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -161,13 +161,13 @@ static void PrTime(void)
 
 /* deduce resources out of POS registers */
 
-static void getaddrs(int slot, int *base, int *memlen, int *iobase,
-                    int *irq, ibmlana_medium * medium)
+static void getaddrs(struct mca_device *mdev, int *base, int *memlen,
+                    int *iobase, int *irq, ibmlana_medium *medium)
 {
        u_char pos0, pos1;
 
-       pos0 = mca_read_stored_pos(slot, 2);
-       pos1 = mca_read_stored_pos(slot, 3);
+       pos0 = mca_device_read_stored_pos(mdev, 2);
+       pos1 = mca_device_read_stored_pos(mdev, 3);
 
        *base = 0xc0000 + ((pos1 & 0xf0) << 9);
        *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
@@ -704,9 +704,9 @@ static void irqtxerr_handler(struct net_device *dev)
 
 /* general interrupt entry */
 
-static irqreturn_t irq_handler(int irq, void *device)
+static irqreturn_t irq_handler(int dummy, void *device)
 {
-       struct net_device *dev = (struct net_device *) device;
+       struct net_device *dev = device;
        u16 ival;
 
        /* in case we're not meant... */
@@ -744,6 +744,7 @@ static irqreturn_t irq_handler(int irq, void *device)
 
 /* MCA info */
 
+#if 0 /* info available elsewhere, but this is kept for reference */
 static int ibmlana_getinfo(char *buf, int slot, void *d)
 {
        int len = 0, i;
@@ -771,6 +772,7 @@ static int ibmlana_getinfo(char *buf, int slot, void *d)
 
        return len;
 }
+#endif
 
 /* open driver.  Means also initialization and start of LANCE */
 
@@ -890,42 +892,52 @@ static void ibmlana_set_multicast_list(struct net_device *dev)
  * hardware check
  * ------------------------------------------------------------------------ */
 
+static int ibmlana_irq;
+static int ibmlana_io;
 static int startslot;          /* counts through slots when probing multiple devices */
 
-static int ibmlana_probe(struct net_device *dev)
+static short ibmlana_adapter_ids[] __initdata = {
+       IBM_LANA_ID,
+       0x0000
+};
+
+static char *ibmlana_adapter_names[] __initdata = {
+       "IBM LAN Adapter/A",
+       NULL
+};
+
+static int ibmlana_init_one(struct device *kdev)
 {
-       int slot, z;
+       struct mca_device *mdev = to_mca_device(kdev);
+       struct net_device *dev;
+       int slot = mdev->slot, z, rc;
        int base = 0, irq = 0, iobase = 0, memlen = 0;
        ibmlana_priv *priv;
        ibmlana_medium medium;
        DECLARE_MAC_BUF(mac);
 
-       /* can't work without an MCA bus ;-) */
-       if (MCA_bus == 0)
-               return -ENODEV;
+       dev = alloc_etherdev(sizeof(ibmlana_priv));
+       if (!dev)
+               return -ENOMEM;
+
+       dev->irq = ibmlana_irq;
+       dev->base_addr = ibmlana_io;
 
        base = dev->mem_start;
        irq = dev->irq;
 
-       for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
-               /* deduce card addresses */
-               getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
-
-               /* slot already in use ? */
-               if (mca_is_adapter_used(slot))
-                       continue;
-               /* were we looking for something different ? */
-               if (dev->irq && dev->irq != irq)
-                       continue;
-               if (dev->mem_start && dev->mem_start != base)
-                       continue;
-               /* found something that matches */
-               break;
-       }
+       /* deduce card addresses */
+       getaddrs(mdev, &base, &memlen, &iobase, &irq, &medium);
 
-       /* nothing found ? */
-       if (slot == -1)
-               return (base != 0 || irq != 0) ? -ENXIO : -ENODEV;
+       /* were we looking for something different ? */
+       if (dev->irq && dev->irq != irq) {
+               rc = -ENODEV;
+               goto err_out;
+       }
+       if (dev->mem_start && dev->mem_start != base) {
+               rc = -ENODEV;
+               goto err_out;
+       }
 
        /* announce success */
        printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
@@ -934,16 +946,16 @@ static int ibmlana_probe(struct net_device *dev)
        if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
                printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
                startslot = slot + 1;
-               return -EBUSY;
+               rc = -EBUSY;
+               goto err_out;
        }
 
        priv = netdev_priv(dev);
        priv->slot = slot;
-       priv->realirq = irq;
+       priv->realirq = mca_device_transform_irq(mdev, irq);
        priv->medium = medium;
        spin_lock_init(&priv->lock);
 
-
        /* set base + irq for this device (irq not allocated so far) */
 
        dev->irq = 0;
@@ -955,22 +967,18 @@ static int ibmlana_probe(struct net_device *dev)
        if (!priv->base) {
                printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
                startslot = slot + 1;
-               release_region(iobase, IBM_LANA_IORANGE);
-               return -EBUSY;
+               rc = -EBUSY;
+               goto err_out_reg;
        }
 
-       /* make procfs entries */
-       mca_set_adapter_name(slot, "IBM LAN Adapter/A");
-       mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
-
-       mca_mark_as_used(slot);
+       mca_device_set_name(mdev, ibmlana_adapter_names[mdev->index]);
+       mca_device_set_claim(mdev, 1);
 
        /* set methods */
 
        dev->open = ibmlana_open;
        dev->stop = ibmlana_close;
        dev->hard_start_xmit = ibmlana_tx;
-       dev->do_ioctl = NULL;
        dev->set_multicast_list = ibmlana_set_multicast_list;
        dev->flags |= IFF_MULTICAST;
 
@@ -996,6 +1004,35 @@ static int ibmlana_probe(struct net_device *dev)
 
        startslot = slot + 1;
 
+       rc = register_netdev(dev);
+       if (rc)
+               goto err_out_claimed;
+
+       dev_set_drvdata(kdev, dev);
+       return 0;
+
+err_out_claimed:
+       mca_device_set_claim(mdev, 0);
+       iounmap(priv->base);
+err_out_reg:
+       release_region(iobase, IBM_LANA_IORANGE);
+err_out:
+       free_netdev(dev);
+       return rc;
+}
+
+static int ibmlana_remove_one(struct device *kdev)
+{
+       struct mca_device *mdev = to_mca_device(kdev);
+       struct net_device *dev = dev_get_drvdata(kdev);
+       ibmlana_priv *priv = netdev_priv(dev);
+
+       unregister_netdev(dev);
+       /*DeinitBoard(dev); */
+       release_region(dev->base_addr, IBM_LANA_IORANGE);
+       mca_device_set_claim(mdev, 0);
+       iounmap(priv->base);
+       free_netdev(dev);
        return 0;
 }
 
@@ -1003,66 +1040,31 @@ static int ibmlana_probe(struct net_device *dev)
  * modularization support
  * ------------------------------------------------------------------------ */
 
-#ifdef MODULE
-
-#define DEVMAX 5
-
-static struct net_device *moddevs[DEVMAX];
-static int irq;
-static int io;
-
-module_param(irq, int, 0);
-module_param(io, int, 0);
+module_param_named(irq, ibmlana_irq, int, 0);
+module_param_named(io, ibmlana_io, int, 0);
 MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
 MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
 MODULE_LICENSE("GPL");
 
-int init_module(void)
-{
-       int z;
+static struct mca_driver ibmlana_driver = {
+       .id_table = ibmlana_adapter_ids,
+       .driver = {
+               .name   = "ibmlana",
+               .bus    = &mca_bus_type,
+               .probe  = ibmlana_init_one,
+               .remove = ibmlana_remove_one,
+       },
+};
 
-       startslot = 0;
-       for (z = 0; z < DEVMAX; z++) {
-               struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
-               if (!dev)
-                       break;
-               dev->irq = irq;
-               dev->base_addr = io;
-               if (ibmlana_probe(dev)) {
-                       free_netdev(dev);
-                       break;
-               }
-               if (register_netdev(dev)) {
-                       ibmlana_priv *priv = netdev_priv(dev);
-                       release_region(dev->base_addr, IBM_LANA_IORANGE);
-                       mca_mark_as_unused(priv->slot);
-                       mca_set_adapter_name(priv->slot, "");
-                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       iounmap(priv->base);
-                       free_netdev(dev);
-                       break;
-               }
-               moddevs[z] = dev;
-       }
-       return (z > 0) ? 0 : -EIO;
+static int __init ibmlana_init_module(void)
+{
+       return mca_register_driver(&ibmlana_driver);
 }
 
-void cleanup_module(void)
+static void __exit ibmlana_cleanup_module(void)
 {
-       int z;
-       for (z = 0; z < DEVMAX; z++) {
-               struct net_device *dev = moddevs[z];
-               if (dev) {
-                       ibmlana_priv *priv = netdev_priv(dev);
-                       unregister_netdev(dev);
-                       /*DeinitBoard(dev); */
-                       release_region(dev->base_addr, IBM_LANA_IORANGE);
-                       mca_mark_as_unused(priv->slot);
-                       mca_set_adapter_name(priv->slot, "");
-                       mca_set_adapter_procfn(priv->slot, NULL, NULL);
-                       iounmap(priv->base);
-                       free_netdev(dev);
-               }
-       }
+       mca_unregister_driver(&ibmlana_driver);
 }
-#endif                         /* MODULE */
+
+module_init(ibmlana_init_module);
+module_exit(ibmlana_cleanup_module);
diff --git a/drivers/net/igb/Makefile b/drivers/net/igb/Makefile
new file mode 100644 (file)
index 0000000..1927b3f
--- /dev/null
@@ -0,0 +1,37 @@
+################################################################################
+#
+# Intel 82575 PCI-Express Ethernet Linux driver
+# Copyright(c) 1999 - 2007 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:
+# Linux NICS <linux.nics@intel.com>
+# e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+################################################################################
+
+#
+# Makefile for the Intel(R) 82575 PCI-Express ethernet driver
+#
+
+obj-$(CONFIG_IGB) += igb.o
+
+igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
+           e1000_mac.o e1000_nvm.o e1000_phy.o
+
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
new file mode 100644 (file)
index 0000000..cda3ec8
--- /dev/null
@@ -0,0 +1,1269 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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
+
+*******************************************************************************/
+
+/* e1000_82575
+ * e1000_82576
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "e1000_mac.h"
+#include "e1000_82575.h"
+
+static s32  igb_get_invariants_82575(struct e1000_hw *);
+static s32  igb_acquire_phy_82575(struct e1000_hw *);
+static void igb_release_phy_82575(struct e1000_hw *);
+static s32  igb_acquire_nvm_82575(struct e1000_hw *);
+static void igb_release_nvm_82575(struct e1000_hw *);
+static s32  igb_check_for_link_82575(struct e1000_hw *);
+static s32  igb_get_cfg_done_82575(struct e1000_hw *);
+static s32  igb_init_hw_82575(struct e1000_hw *);
+static s32  igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
+static s32  igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
+static void igb_rar_set_82575(struct e1000_hw *, u8 *, u32);
+static s32  igb_reset_hw_82575(struct e1000_hw *);
+static s32  igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
+static s32  igb_setup_copper_link_82575(struct e1000_hw *);
+static s32  igb_setup_fiber_serdes_link_82575(struct e1000_hw *);
+static s32  igb_write_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16);
+static void igb_clear_hw_cntrs_82575(struct e1000_hw *);
+static s32  igb_acquire_swfw_sync_82575(struct e1000_hw *, u16);
+static s32  igb_configure_pcs_link_82575(struct e1000_hw *);
+static s32  igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *, u16 *,
+                                                u16 *);
+static s32  igb_get_phy_id_82575(struct e1000_hw *);
+static void igb_release_swfw_sync_82575(struct e1000_hw *, u16);
+static bool igb_sgmii_active_82575(struct e1000_hw *);
+static s32  igb_reset_init_script_82575(struct e1000_hw *);
+static s32  igb_read_mac_addr_82575(struct e1000_hw *);
+
+
+struct e1000_dev_spec_82575 {
+       bool sgmii_active;
+};
+
+static s32 igb_get_invariants_82575(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       struct e1000_mac_info *mac = &hw->mac;
+       struct e1000_dev_spec_82575 *dev_spec;
+       u32 eecd;
+       s32 ret_val;
+       u16 size;
+       u32 ctrl_ext = 0;
+
+       switch (hw->device_id) {
+       case E1000_DEV_ID_82575EB_COPPER:
+       case E1000_DEV_ID_82575EB_FIBER_SERDES:
+       case E1000_DEV_ID_82575GB_QUAD_COPPER:
+               mac->type = e1000_82575;
+               break;
+       default:
+               return -E1000_ERR_MAC_INIT;
+               break;
+       }
+
+       /* MAC initialization */
+       hw->dev_spec_size = sizeof(struct e1000_dev_spec_82575);
+
+       /* Device-specific structure allocation */
+       hw->dev_spec = kzalloc(hw->dev_spec_size, GFP_KERNEL);
+
+       if (!hw->dev_spec)
+               return -ENOMEM;
+
+       dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+
+       /* Set media type */
+       /*
+        * The 82575 uses bits 22:23 for link mode. The mode can be changed
+        * based on the EEPROM. We cannot rely upon device ID. There
+        * is no distinguishable difference between fiber and internal
+        * SerDes mode on the 82575. There can be an external PHY attached
+        * on the SGMII interface. For this, we'll set sgmii_active to true.
+        */
+       phy->media_type = e1000_media_type_copper;
+       dev_spec->sgmii_active = false;
+
+       ctrl_ext = rd32(E1000_CTRL_EXT);
+       if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) ==
+           E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) {
+               hw->phy.media_type = e1000_media_type_internal_serdes;
+               ctrl_ext |= E1000_CTRL_I2C_ENA;
+       } else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) {
+               dev_spec->sgmii_active = true;
+               ctrl_ext |= E1000_CTRL_I2C_ENA;
+       } else {
+               ctrl_ext &= ~E1000_CTRL_I2C_ENA;
+       }
+       wr32(E1000_CTRL_EXT, ctrl_ext);
+
+       /* Set mta register count */
+       mac->mta_reg_count = 128;
+       /* Set rar entry count */
+       mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
+       /* Set if part includes ASF firmware */
+       mac->asf_firmware_present = true;
+       /* Set if manageability features are enabled. */
+       mac->arc_subsystem_valid =
+               (rd32(E1000_FWSM) & E1000_FWSM_MODE_MASK)
+                       ? true : false;
+
+       /* physical interface link setup */
+       mac->ops.setup_physical_interface =
+               (hw->phy.media_type == e1000_media_type_copper)
+                       ? igb_setup_copper_link_82575
+                       : igb_setup_fiber_serdes_link_82575;
+
+       /* NVM initialization */
+       eecd = rd32(E1000_EECD);
+
+       nvm->opcode_bits        = 8;
+       nvm->delay_usec         = 1;
+       switch (nvm->override) {
+       case e1000_nvm_override_spi_large:
+               nvm->page_size    = 32;
+               nvm->address_bits = 16;
+               break;
+       case e1000_nvm_override_spi_small:
+               nvm->page_size    = 8;
+               nvm->address_bits = 8;
+               break;
+       default:
+               nvm->page_size    = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
+               nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8;
+               break;
+       }
+
+       nvm->type = e1000_nvm_eeprom_spi;
+
+       size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
+                    E1000_EECD_SIZE_EX_SHIFT);
+
+       /*
+        * Added to a constant, "size" becomes the left-shift value
+        * for setting word_size.
+        */
+       size += NVM_WORD_SIZE_BASE_SHIFT;
+       nvm->word_size = 1 << size;
+
+       /* setup PHY parameters */
+       if (phy->media_type != e1000_media_type_copper) {
+               phy->type = e1000_phy_none;
+               return 0;
+       }
+
+       phy->autoneg_mask        = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+       phy->reset_delay_us      = 100;
+
+       /* PHY function pointers */
+       if (igb_sgmii_active_82575(hw)) {
+               phy->ops.reset_phy          = igb_phy_hw_reset_sgmii_82575;
+               phy->ops.read_phy_reg       = igb_read_phy_reg_sgmii_82575;
+               phy->ops.write_phy_reg      = igb_write_phy_reg_sgmii_82575;
+       } else {
+               phy->ops.reset_phy          = igb_phy_hw_reset;
+               phy->ops.read_phy_reg       = igb_read_phy_reg_igp;
+               phy->ops.write_phy_reg      = igb_write_phy_reg_igp;
+       }
+
+       /* Set phy->phy_addr and phy->id. */
+       ret_val = igb_get_phy_id_82575(hw);
+       if (ret_val)
+               return ret_val;
+
+       /* Verify phy id and set remaining function pointers */
+       switch (phy->id) {
+       case M88E1111_I_PHY_ID:
+               phy->type                   = e1000_phy_m88;
+               phy->ops.get_phy_info       = igb_get_phy_info_m88;
+               phy->ops.get_cable_length   = igb_get_cable_length_m88;
+               phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
+               break;
+       case IGP03E1000_E_PHY_ID:
+               phy->type                   = e1000_phy_igp_3;
+               phy->ops.get_phy_info       = igb_get_phy_info_igp;
+               phy->ops.get_cable_length   = igb_get_cable_length_igp_2;
+               phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_igp;
+               phy->ops.set_d0_lplu_state  = igb_set_d0_lplu_state_82575;
+               phy->ops.set_d3_lplu_state  = igb_set_d3_lplu_state;
+               break;
+       default:
+               return -E1000_ERR_PHY;
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_acquire_phy_82575 - Acquire rights to access PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire access rights to the correct PHY.  This is a
+ *  function pointer entry point called by the api module.
+ **/
+static s32 igb_acquire_phy_82575(struct e1000_hw *hw)
+{
+       u16 mask;
+
+       mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+
+       return igb_acquire_swfw_sync_82575(hw, mask);
+}
+
+/**
+ *  e1000_release_phy_82575 - Release rights to access PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  A wrapper to release access rights to the correct PHY.  This is a
+ *  function pointer entry point called by the api module.
+ **/
+static void igb_release_phy_82575(struct e1000_hw *hw)
+{
+       u16 mask;
+
+       mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+       igb_release_swfw_sync_82575(hw, mask);
+}
+
+/**
+ *  e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the PHY register at offset using the serial gigabit media independent
+ *  interface and stores the retrieved information in data.
+ **/
+static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
+                                         u16 *data)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       u32 i, i2ccmd = 0;
+
+       if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
+               hw_dbg(hw, "PHY Address %u is out of range\n", offset);
+               return -E1000_ERR_PARAM;
+       }
+
+       /*
+        * Set up Op-code, Phy Address, and register address in the I2CCMD
+        * register.  The MAC will take care of interfacing with the
+        * PHY to retrieve the desired data.
+        */
+       i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+                 (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
+                 (E1000_I2CCMD_OPCODE_READ));
+
+       wr32(E1000_I2CCMD, i2ccmd);
+
+       /* Poll the ready bit to see if the I2C read completed */
+       for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+               udelay(50);
+               i2ccmd = rd32(E1000_I2CCMD);
+               if (i2ccmd & E1000_I2CCMD_READY)
+                       break;
+       }
+       if (!(i2ccmd & E1000_I2CCMD_READY)) {
+               hw_dbg(hw, "I2CCMD Read did not complete\n");
+               return -E1000_ERR_PHY;
+       }
+       if (i2ccmd & E1000_I2CCMD_ERROR) {
+               hw_dbg(hw, "I2CCMD Error bit set\n");
+               return -E1000_ERR_PHY;
+       }
+
+       /* Need to byte-swap the 16-bit value. */
+       *data = ((i2ccmd >> 8) & 0x00FF) | ((i2ccmd << 8) & 0xFF00);
+
+       return 0;
+}
+
+/**
+ *  e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Writes the data to PHY register at the offset using the serial gigabit
+ *  media independent interface.
+ **/
+static s32 igb_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
+                                          u16 data)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       u32 i, i2ccmd = 0;
+       u16 phy_data_swapped;
+
+       if (offset > E1000_MAX_SGMII_PHY_REG_ADDR) {
+               hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+               return -E1000_ERR_PARAM;
+       }
+
+       /* Swap the data bytes for the I2C interface */
+       phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
+
+       /*
+        * Set up Op-code, Phy Address, and register address in the I2CCMD
+        * register.  The MAC will take care of interfacing with the
+        * PHY to retrieve the desired data.
+        */
+       i2ccmd = ((offset << E1000_I2CCMD_REG_ADDR_SHIFT) |
+                 (phy->addr << E1000_I2CCMD_PHY_ADDR_SHIFT) |
+                 E1000_I2CCMD_OPCODE_WRITE |
+                 phy_data_swapped);
+
+       wr32(E1000_I2CCMD, i2ccmd);
+
+       /* Poll the ready bit to see if the I2C read completed */
+       for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
+               udelay(50);
+               i2ccmd = rd32(E1000_I2CCMD);
+               if (i2ccmd & E1000_I2CCMD_READY)
+                       break;
+       }
+       if (!(i2ccmd & E1000_I2CCMD_READY)) {
+               hw_dbg(hw, "I2CCMD Write did not complete\n");
+               return -E1000_ERR_PHY;
+       }
+       if (i2ccmd & E1000_I2CCMD_ERROR) {
+               hw_dbg(hw, "I2CCMD Error bit set\n");
+               return -E1000_ERR_PHY;
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_get_phy_id_82575 - Retreive PHY addr and id
+ *  @hw: pointer to the HW structure
+ *
+ *  Retreives the PHY address and ID for both PHY's which do and do not use
+ *  sgmi interface.
+ **/
+static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32  ret_val = 0;
+       u16 phy_id;
+
+       /*
+        * For SGMII PHYs, we try the list of possible addresses until
+        * we find one that works.  For non-SGMII PHYs
+        * (e.g. integrated copper PHYs), an address of 1 should
+        * work.  The result of this function should mean phy->phy_addr
+        * and phy->id are set correctly.
+        */
+       if (!(igb_sgmii_active_82575(hw))) {
+               phy->addr = 1;
+               ret_val = igb_get_phy_id(hw);
+               goto out;
+       }
+
+       /*
+        * The address field in the I2CCMD register is 3 bits and 0 is invalid.
+        * Therefore, we need to test 1-7
+        */
+       for (phy->addr = 1; phy->addr < 8; phy->addr++) {
+               ret_val = igb_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id);
+               if (ret_val == 0) {
+                       hw_dbg(hw, "Vendor ID 0x%08X read at address %u\n",
+                                 phy_id,
+                                 phy->addr);
+                       /*
+                        * At the time of this writing, The M88 part is
+                        * the only supported SGMII PHY product.
+                        */
+                       if (phy_id == M88_VENDOR)
+                               break;
+               } else {
+                       hw_dbg(hw, "PHY address %u was unreadable\n",
+                                 phy->addr);
+               }
+       }
+
+       /* A valid PHY type couldn't be found. */
+       if (phy->addr == 8) {
+               phy->addr = 0;
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+
+       ret_val = igb_get_phy_id(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_hw_reset_sgmii_82575 - Performs a PHY reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Resets the PHY using the serial gigabit media independent interface.
+ **/
+static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *hw)
+{
+       s32 ret_val;
+
+       /*
+        * This isn't a true "hard" reset, but is the only reset
+        * available to us at this time.
+        */
+
+       hw_dbg(hw, "Soft resetting SGMII attached PHY...\n");
+
+       /*
+        * SFP documentation requires the following to configure the SPF module
+        * to work on SGMII.  No further documentation is given.
+        */
+       ret_val = hw->phy.ops.write_phy_reg(hw, 0x1B, 0x8084);
+       if (ret_val)
+               goto out;
+
+       ret_val = igb_phy_sw_reset(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state
+ *  @hw: pointer to the HW structure
+ *  @active: true to enable LPLU, false to disable
+ *
+ *  Sets the LPLU D0 state according to the active flag.  When
+ *  activating LPLU this function also disables smart speed
+ *  and vice versa.  LPLU will not be activated unless the
+ *  device autonegotiation advertisement meets standards of
+ *  either 10 or 10/100 or 10/100/1000 at all duplexes.
+ *  This is a function pointer entry point only called by
+ *  PHY setup routines.
+ **/
+static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+                                          &data);
+       if (ret_val)
+               goto out;
+
+       if (active) {
+               data |= IGP02E1000_PM_D0_LPLU;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             IGP02E1000_PHY_POWER_MGMT,
+                                             data);
+               if (ret_val)
+                       goto out;
+
+               /* When LPLU is enabled, we should disable SmartSpeed */
+               ret_val = hw->phy.ops.read_phy_reg(hw,
+                                            IGP01E1000_PHY_PORT_CONFIG,
+                                            &data);
+               data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             IGP01E1000_PHY_PORT_CONFIG,
+                                             data);
+               if (ret_val)
+                       goto out;
+       } else {
+               data &= ~IGP02E1000_PM_D0_LPLU;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             IGP02E1000_PHY_POWER_MGMT,
+                                             data);
+               /*
+                * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+                * during Dx states where the power conservation is most
+                * important.  During driver activity we should enable
+                * SmartSpeed, so performance is maintained.
+                */
+               if (phy->smart_speed == e1000_smart_speed_on) {
+                       ret_val = hw->phy.ops.read_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    &data);
+                       if (ret_val)
+                               goto out;
+
+                       data |= IGP01E1000_PSCFR_SMART_SPEED;
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    data);
+                       if (ret_val)
+                               goto out;
+               } else if (phy->smart_speed == e1000_smart_speed_off) {
+                       ret_val = hw->phy.ops.read_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    &data);
+                       if (ret_val)
+                               goto out;
+
+                       data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    data);
+                       if (ret_val)
+                               goto out;
+               }
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_acquire_nvm_82575 - Request for access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire the necessary semaphores for exclussive access to the EEPROM.
+ *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
+ *  Return successful if access grant bit set, else clear the request for
+ *  EEPROM access and return -E1000_ERR_NVM (-1).
+ **/
+static s32 igb_acquire_nvm_82575(struct e1000_hw *hw)
+{
+       s32 ret_val;
+
+       ret_val = igb_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+       if (ret_val)
+               goto out;
+
+       ret_val = igb_acquire_nvm(hw);
+
+       if (ret_val)
+               igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_release_nvm_82575 - Release exclusive access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
+ *  then release the semaphores acquired.
+ **/
+static void igb_release_nvm_82575(struct e1000_hw *hw)
+{
+       igb_release_nvm(hw);
+       igb_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
+}
+
+/**
+ *  e1000_acquire_swfw_sync_82575 - Acquire SW/FW semaphore
+ *  @hw: pointer to the HW structure
+ *  @mask: specifies which semaphore to acquire
+ *
+ *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
+ *  will also specify which port we're acquiring the lock for.
+ **/
+static s32 igb_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
+{
+       u32 swfw_sync;
+       u32 swmask = mask;
+       u32 fwmask = mask << 16;
+       s32 ret_val = 0;
+       s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
+
+       while (i < timeout) {
+               if (igb_get_hw_semaphore(hw)) {
+                       ret_val = -E1000_ERR_SWFW_SYNC;
+                       goto out;
+               }
+
+               swfw_sync = rd32(E1000_SW_FW_SYNC);
+               if (!(swfw_sync & (fwmask | swmask)))
+                       break;
+
+               /*
+                * Firmware currently using resource (fwmask)
+                * or other software thread using resource (swmask)
+                */
+               igb_put_hw_semaphore(hw);
+               mdelay(5);
+               i++;
+       }
+
+       if (i == timeout) {
+               hw_dbg(hw, "Can't access resource, SW_FW_SYNC timeout.\n");
+               ret_val = -E1000_ERR_SWFW_SYNC;
+               goto out;
+       }
+
+       swfw_sync |= swmask;
+       wr32(E1000_SW_FW_SYNC, swfw_sync);
+
+       igb_put_hw_semaphore(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_release_swfw_sync_82575 - Release SW/FW semaphore
+ *  @hw: pointer to the HW structure
+ *  @mask: specifies which semaphore to acquire
+ *
+ *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
+ *  will also specify which port we're releasing the lock for.
+ **/
+static void igb_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
+{
+       u32 swfw_sync;
+
+       while (igb_get_hw_semaphore(hw) != 0);
+       /* Empty */
+
+       swfw_sync = rd32(E1000_SW_FW_SYNC);
+       swfw_sync &= ~mask;
+       wr32(E1000_SW_FW_SYNC, swfw_sync);
+
+       igb_put_hw_semaphore(hw);
+}
+
+/**
+ *  e1000_get_cfg_done_82575 - Read config done bit
+ *  @hw: pointer to the HW structure
+ *
+ *  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
+ *  0.  If we were to return with error, EEPROM-less silicon
+ *  would not be able to be reset or change link.
+ **/
+static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
+{
+       s32 timeout = PHY_CFG_TIMEOUT;
+       s32 ret_val = 0;
+       u32 mask = E1000_NVM_CFG_DONE_PORT_0;
+
+       if (hw->bus.func == 1)
+               mask = E1000_NVM_CFG_DONE_PORT_1;
+
+       while (timeout) {
+               if (rd32(E1000_EEMNGCTL) & mask)
+                       break;
+               msleep(1);
+               timeout--;
+       }
+       if (!timeout)
+               hw_dbg(hw, "MNG configuration cycle has not completed.\n");
+
+       /* If EEPROM is not marked present, init the PHY manually */
+       if (((rd32(E1000_EECD) & E1000_EECD_PRES) == 0) &&
+           (hw->phy.type == e1000_phy_igp_3))
+               igb_phy_init_script_igp3(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_check_for_link_82575 - Check for link
+ *  @hw: pointer to the HW structure
+ *
+ *  If sgmii is enabled, then use the pcs register to determine link, otherwise
+ *  use the generic interface for determining link.
+ **/
+static s32 igb_check_for_link_82575(struct e1000_hw *hw)
+{
+       s32 ret_val;
+       u16 speed, duplex;
+
+       /* SGMII link check is done through the PCS register. */
+       if ((hw->phy.media_type != e1000_media_type_copper) ||
+           (igb_sgmii_active_82575(hw)))
+               ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
+                                                              &duplex);
+       else
+               ret_val = igb_check_for_copper_link(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
+ *  @hw: pointer to the HW structure
+ *  @speed: stores the current speed
+ *  @duplex: stores the current duplex
+ *
+ *  Using the physical coding sub-layer (PCS), retreive the current speed and
+ *  duplex, then store the values in the pointers provided.
+ **/
+static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
+                                               u16 *duplex)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       u32 pcs;
+
+       /* Set up defaults for the return values of this function */
+       mac->serdes_has_link = false;
+       *speed = 0;
+       *duplex = 0;
+
+       /*
+        * Read the PCS Status register for link state. For non-copper mode,
+        * the status register is not accurate. The PCS status register is
+        * used instead.
+        */
+       pcs = rd32(E1000_PCS_LSTAT);
+
+       /*
+        * The link up bit determines when link is up on autoneg. The sync ok
+        * gets set once both sides sync up and agree upon link. Stable link
+        * can be determined by checking for both link up and link sync ok
+        */
+       if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
+               mac->serdes_has_link = true;
+
+               /* Detect and store PCS speed */
+               if (pcs & E1000_PCS_LSTS_SPEED_1000) {
+                       *speed = SPEED_1000;
+               } else if (pcs & E1000_PCS_LSTS_SPEED_100) {
+                       *speed = SPEED_100;
+               } else {
+                       *speed = SPEED_10;
+               }
+
+               /* Detect and store PCS duplex */
+               if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) {
+                       *duplex = FULL_DUPLEX;
+               } else {
+                       *duplex = HALF_DUPLEX;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_rar_set_82575 - Set receive address register
+ *  @hw: pointer to the HW structure
+ *  @addr: pointer to the receive address
+ *  @index: receive address array register
+ *
+ *  Sets the receive address array register at index to the address passed
+ *  in by addr.
+ **/
+static void igb_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
+{
+       if (index < E1000_RAR_ENTRIES_82575)
+               igb_rar_set(hw, addr, index);
+
+       return;
+}
+
+/**
+ *  e1000_reset_hw_82575 - Reset hardware
+ *  @hw: pointer to the HW structure
+ *
+ *  This resets the hardware into a known state.  This is a
+ *  function pointer entry point called by the api module.
+ **/
+static s32 igb_reset_hw_82575(struct e1000_hw *hw)
+{
+       u32 ctrl, icr;
+       s32 ret_val;
+
+       /*
+        * Prevent the PCI-E bus from sticking if there is no TLP connection
+        * on the last TLP read/write transaction when MAC is reset.
+        */
+       ret_val = igb_disable_pcie_master(hw);
+       if (ret_val)
+               hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+
+       hw_dbg(hw, "Masking off all interrupts\n");
+       wr32(E1000_IMC, 0xffffffff);
+
+       wr32(E1000_RCTL, 0);
+       wr32(E1000_TCTL, E1000_TCTL_PSP);
+       wrfl();
+
+       msleep(10);
+
+       ctrl = rd32(E1000_CTRL);
+
+       hw_dbg(hw, "Issuing a global reset to MAC\n");
+       wr32(E1000_CTRL, ctrl | E1000_CTRL_RST);
+
+       ret_val = igb_get_auto_rd_done(hw);
+       if (ret_val) {
+               /*
+                * When auto config read does not complete, do not
+                * return with an error. This can happen in situations
+                * where there is no eeprom and prevents getting link.
+                */
+               hw_dbg(hw, "Auto Read Done did not complete\n");
+       }
+
+       /* If EEPROM is not present, run manual init scripts */
+       if ((rd32(E1000_EECD) & E1000_EECD_PRES) == 0)
+               igb_reset_init_script_82575(hw);
+
+       /* Clear any pending interrupt events. */
+       wr32(E1000_IMC, 0xffffffff);
+       icr = rd32(E1000_ICR);
+
+       igb_check_alt_mac_addr(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_init_hw_82575 - Initialize hardware
+ *  @hw: pointer to the HW structure
+ *
+ *  This inits the hardware readying it for operation.
+ **/
+static s32 igb_init_hw_82575(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val;
+       u16 i, rar_count = mac->rar_entry_count;
+
+       /* Initialize identification LED */
+       ret_val = igb_id_led_init(hw);
+       if (ret_val) {
+               hw_dbg(hw, "Error initializing identification LED\n");
+               /* This is not fatal and we should not stop init due to this */
+       }
+
+       /* Disabling VLAN filtering */
+       hw_dbg(hw, "Initializing the IEEE VLAN\n");
+       igb_clear_vfta(hw);
+
+       /* Setup the receive address */
+       igb_init_rx_addrs(hw, rar_count);
+       /* Zero out the Multicast HASH table */
+       hw_dbg(hw, "Zeroing the MTA\n");
+       for (i = 0; i < mac->mta_reg_count; i++)
+               array_wr32(E1000_MTA, i, 0);
+
+       /* Setup link and flow control */
+       ret_val = igb_setup_link(hw);
+
+       /*
+        * Clear all of the statistics registers (clear on read).  It is
+        * important that we do this after we have tried to establish link
+        * because the symbol error count will increment wildly if there
+        * is no link.
+        */
+       igb_clear_hw_cntrs_82575(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_setup_copper_link_82575 - Configure copper link settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Configures the link for auto-neg or forced speed and duplex.  Then we check
+ *  for link, once link is established calls to configure collision distance
+ *  and flow control are called.
+ **/
+static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
+{
+       u32 ctrl, led_ctrl;
+       s32  ret_val;
+       bool link;
+
+       ctrl = rd32(E1000_CTRL);
+       ctrl |= E1000_CTRL_SLU;
+       ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+       wr32(E1000_CTRL, ctrl);
+
+       switch (hw->phy.type) {
+       case e1000_phy_m88:
+               ret_val = igb_copper_link_setup_m88(hw);
+               break;
+       case e1000_phy_igp_3:
+               ret_val = igb_copper_link_setup_igp(hw);
+               /* Setup activity LED */
+               led_ctrl = rd32(E1000_LEDCTL);
+               led_ctrl &= IGP_ACTIVITY_LED_MASK;
+               led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
+               wr32(E1000_LEDCTL, led_ctrl);
+               break;
+       default:
+               ret_val = -E1000_ERR_PHY;
+               break;
+       }
+
+       if (ret_val)
+               goto out;
+
+       if (hw->mac.autoneg) {
+               /*
+                * Setup autoneg and flow control advertisement
+                * and perform autonegotiation.
+                */
+               ret_val = igb_copper_link_autoneg(hw);
+               if (ret_val)
+                       goto out;
+       } else {
+               /*
+                * PHY will be set to 10H, 10F, 100H or 100F
+                * depending on user settings.
+                */
+               hw_dbg(hw, "Forcing Speed and Duplex\n");
+               ret_val = igb_phy_force_speed_duplex(hw);
+               if (ret_val) {
+                       hw_dbg(hw, "Error Forcing Speed and Duplex\n");
+                       goto out;
+               }
+       }
+
+       ret_val = igb_configure_pcs_link_82575(hw);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Check link status. Wait up to 100 microseconds for link to become
+        * valid.
+        */
+       ret_val = igb_phy_has_link(hw,
+                                            COPPER_LINK_UP_LIMIT,
+                                            10,
+                                            &link);
+       if (ret_val)
+               goto out;
+
+       if (link) {
+               hw_dbg(hw, "Valid link established!!!\n");
+               /* Config the MAC and PHY after link is up */
+               igb_config_collision_dist(hw);
+               ret_val = igb_config_fc_after_link_up(hw);
+       } else {
+               hw_dbg(hw, "Unable to establish link!!!\n");
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_setup_fiber_serdes_link_82575 - Setup link for fiber/serdes
+ *  @hw: pointer to the HW structure
+ *
+ *  Configures speed and duplex for fiber and serdes links.
+ **/
+static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
+{
+       u32 reg;
+
+       /*
+        * On the 82575, SerDes loopback mode persists until it is
+        * explicitly turned off or a power cycle is performed.  A read to
+        * the register does not indicate its status.  Therefore, we ensure
+        * loopback mode is disabled during initialization.
+        */
+       wr32(E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
+
+       /* Force link up, set 1gb, set both sw defined pins */
+       reg = rd32(E1000_CTRL);
+       reg |= E1000_CTRL_SLU |
+              E1000_CTRL_SPD_1000 |
+              E1000_CTRL_FRCSPD |
+              E1000_CTRL_SWDPIN0 |
+              E1000_CTRL_SWDPIN1;
+       wr32(E1000_CTRL, reg);
+
+       /* Set switch control to serdes energy detect */
+       reg = rd32(E1000_CONNSW);
+       reg |= E1000_CONNSW_ENRGSRC;
+       wr32(E1000_CONNSW, reg);
+
+       /*
+        * New SerDes mode allows for forcing speed or autonegotiating speed
+        * at 1gb. Autoneg should be default set by most drivers. This is the
+        * mode that will be compatible with older link partners and switches.
+        * However, both are supported by the hardware and some drivers/tools.
+        */
+       reg = rd32(E1000_PCS_LCTL);
+
+       reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
+               E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
+
+       if (hw->mac.autoneg) {
+               /* Set PCS register for autoneg */
+               reg |= E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
+                      E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
+                      E1000_PCS_LCTL_AN_ENABLE |     /* Enable Autoneg */
+                      E1000_PCS_LCTL_AN_RESTART;     /* Restart autoneg */
+               hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
+       } else {
+               /* Set PCS register for forced speed */
+               reg |= E1000_PCS_LCTL_FLV_LINK_UP |   /* Force link up */
+                      E1000_PCS_LCTL_FSV_1000 |      /* Force 1000    */
+                      E1000_PCS_LCTL_FDV_FULL |      /* SerDes Full duplex */
+                      E1000_PCS_LCTL_FSD |           /* Force Speed */
+                      E1000_PCS_LCTL_FORCE_LINK;     /* Force Link */
+               hw_dbg(hw, "Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
+       }
+       wr32(E1000_PCS_LCTL, reg);
+
+       return 0;
+}
+
+/**
+ *  e1000_configure_pcs_link_82575 - Configure PCS link
+ *  @hw: pointer to the HW structure
+ *
+ *  Configure the physical coding sub-layer (PCS) link.  The PCS link is
+ *  only used on copper connections where the serialized gigabit media
+ *  independent interface (sgmii) is being used.  Configures the link
+ *  for auto-negotiation or forces speed/duplex.
+ **/
+static s32 igb_configure_pcs_link_82575(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       u32 reg = 0;
+
+       if (hw->phy.media_type != e1000_media_type_copper ||
+           !(igb_sgmii_active_82575(hw)))
+               goto out;
+
+       /* For SGMII, we need to issue a PCS autoneg restart */
+       reg = rd32(E1000_PCS_LCTL);
+
+       /* AN time out should be disabled for SGMII mode */
+       reg &= ~(E1000_PCS_LCTL_AN_TIMEOUT);
+
+       if (mac->autoneg) {
+               /* Make sure forced speed and force link are not set */
+               reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
+
+               /*
+                * The PHY should be setup prior to calling this function.
+                * All we need to do is restart autoneg and enable autoneg.
+                */
+               reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE;
+       } else {
+               /* Set PCS regiseter for forced speed */
+
+               /* Turn off bits for full duplex, speed, and autoneg */
+               reg &= ~(E1000_PCS_LCTL_FSV_1000 |
+                        E1000_PCS_LCTL_FSV_100 |
+                        E1000_PCS_LCTL_FDV_FULL |
+                        E1000_PCS_LCTL_AN_ENABLE);
+
+               /* Check for duplex first */
+               if (mac->forced_speed_duplex & E1000_ALL_FULL_DUPLEX)
+                       reg |= E1000_PCS_LCTL_FDV_FULL;
+
+               /* Now set speed */
+               if (mac->forced_speed_duplex & E1000_ALL_100_SPEED)
+                       reg |= E1000_PCS_LCTL_FSV_100;
+
+               /* Force speed and force link */
+               reg |= E1000_PCS_LCTL_FSD |
+                      E1000_PCS_LCTL_FORCE_LINK |
+                      E1000_PCS_LCTL_FLV_LINK_UP;
+
+               hw_dbg(hw,
+                      "Wrote 0x%08X to PCS_LCTL to configure forced link\n",
+                      reg);
+       }
+       wr32(E1000_PCS_LCTL, reg);
+
+out:
+       return 0;
+}
+
+/**
+ *  e1000_sgmii_active_82575 - Return sgmii state
+ *  @hw: pointer to the HW structure
+ *
+ *  82575 silicon has a serialized gigabit media independent interface (sgmii)
+ *  which can be enabled for use in the embedded applications.  Simply
+ *  return the current state of the sgmii interface.
+ **/
+static bool igb_sgmii_active_82575(struct e1000_hw *hw)
+{
+       struct e1000_dev_spec_82575 *dev_spec;
+       bool ret_val;
+
+       if (hw->mac.type != e1000_82575) {
+               ret_val = false;
+               goto out;
+       }
+
+       dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+
+       ret_val = dev_spec->sgmii_active;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_reset_init_script_82575 - Inits HW defaults after reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Inits recommended HW defaults after a reset when there is no EEPROM
+ *  detected. This is only for the 82575.
+ **/
+static s32 igb_reset_init_script_82575(struct e1000_hw *hw)
+{
+       if (hw->mac.type == e1000_82575) {
+               hw_dbg(hw, "Running reset init script for 82575\n");
+               /* SerDes configuration via SERDESCTRL */
+               igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x00, 0x0C);
+               igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x01, 0x78);
+               igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x1B, 0x23);
+               igb_write_8bit_ctrl_reg(hw, E1000_SCTL, 0x23, 0x15);
+
+               /* CCM configuration via CCMCTL register */
+               igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x14, 0x00);
+               igb_write_8bit_ctrl_reg(hw, E1000_CCMCTL, 0x10, 0x00);
+
+               /* PCIe lanes configuration */
+               igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x00, 0xEC);
+               igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x61, 0xDF);
+               igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x34, 0x05);
+               igb_write_8bit_ctrl_reg(hw, E1000_GIOCTL, 0x2F, 0x81);
+
+               /* PCIe PLL Configuration */
+               igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x02, 0x47);
+               igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x14, 0x00);
+               igb_write_8bit_ctrl_reg(hw, E1000_SCCTL, 0x10, 0x00);
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_read_mac_addr_82575 - Read device MAC address
+ *  @hw: pointer to the HW structure
+ **/
+static s32 igb_read_mac_addr_82575(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+
+       if (igb_check_alt_mac_addr(hw))
+               ret_val = igb_read_mac_addr(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the hardware counters by reading the counter registers.
+ **/
+static void igb_clear_hw_cntrs_82575(struct e1000_hw *hw)
+{
+       u32 temp;
+
+       igb_clear_hw_cntrs_base(hw);
+
+       temp = rd32(E1000_PRC64);
+       temp = rd32(E1000_PRC127);
+       temp = rd32(E1000_PRC255);
+       temp = rd32(E1000_PRC511);
+       temp = rd32(E1000_PRC1023);
+       temp = rd32(E1000_PRC1522);
+       temp = rd32(E1000_PTC64);
+       temp = rd32(E1000_PTC127);
+       temp = rd32(E1000_PTC255);
+       temp = rd32(E1000_PTC511);
+       temp = rd32(E1000_PTC1023);
+       temp = rd32(E1000_PTC1522);
+
+       temp = rd32(E1000_ALGNERRC);
+       temp = rd32(E1000_RXERRC);
+       temp = rd32(E1000_TNCRS);
+       temp = rd32(E1000_CEXTERR);
+       temp = rd32(E1000_TSCTC);
+       temp = rd32(E1000_TSCTFC);
+
+       temp = rd32(E1000_MGTPRC);
+       temp = rd32(E1000_MGTPDC);
+       temp = rd32(E1000_MGTPTC);
+
+       temp = rd32(E1000_IAC);
+       temp = rd32(E1000_ICRXOC);
+
+       temp = rd32(E1000_ICRXPTC);
+       temp = rd32(E1000_ICRXATC);
+       temp = rd32(E1000_ICTXPTC);
+       temp = rd32(E1000_ICTXATC);
+       temp = rd32(E1000_ICTXQEC);
+       temp = rd32(E1000_ICTXQMTC);
+       temp = rd32(E1000_ICRXDMTC);
+
+       temp = rd32(E1000_CBTMPC);
+       temp = rd32(E1000_HTDPMC);
+       temp = rd32(E1000_CBRMPC);
+       temp = rd32(E1000_RPTHC);
+       temp = rd32(E1000_HGPTC);
+       temp = rd32(E1000_HTCBDPC);
+       temp = rd32(E1000_HGORCL);
+       temp = rd32(E1000_HGORCH);
+       temp = rd32(E1000_HGOTCL);
+       temp = rd32(E1000_HGOTCH);
+       temp = rd32(E1000_LENERRS);
+
+       /* This register should not be read in copper configurations */
+       if (hw->phy.media_type == e1000_media_type_internal_serdes)
+               temp = rd32(E1000_SCVPC);
+}
+
+static struct e1000_mac_operations e1000_mac_ops_82575 = {
+       .reset_hw             = igb_reset_hw_82575,
+       .init_hw              = igb_init_hw_82575,
+       .check_for_link       = igb_check_for_link_82575,
+       .rar_set              = igb_rar_set_82575,
+       .read_mac_addr        = igb_read_mac_addr_82575,
+       .get_speed_and_duplex = igb_get_speed_and_duplex_copper,
+};
+
+static struct e1000_phy_operations e1000_phy_ops_82575 = {
+       .acquire_phy          = igb_acquire_phy_82575,
+       .get_cfg_done         = igb_get_cfg_done_82575,
+       .release_phy          = igb_release_phy_82575,
+};
+
+static struct e1000_nvm_operations e1000_nvm_ops_82575 = {
+       .acquire_nvm          = igb_acquire_nvm_82575,
+       .read_nvm             = igb_read_nvm_eerd,
+       .release_nvm          = igb_release_nvm_82575,
+       .write_nvm            = igb_write_nvm_spi,
+};
+
+const struct e1000_info e1000_82575_info = {
+       .get_invariants = igb_get_invariants_82575,
+       .mac_ops = &e1000_mac_ops_82575,
+       .phy_ops = &e1000_phy_ops_82575,
+       .nvm_ops = &e1000_nvm_ops_82575,
+};
+
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
new file mode 100644 (file)
index 0000000..6604d96
--- /dev/null
@@ -0,0 +1,150 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_82575_H_
+#define _E1000_82575_H_
+
+#define E1000_RAR_ENTRIES_82575   16
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT                     10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT                 2  /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF                0x02000000
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS          0x0A000000
+
+#define E1000_MRQC_ENABLE_RSS_4Q            0x00000002
+#define E1000_MRQC_RSS_FIELD_IPV4_UDP       0x00400000
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP       0x00800000
+#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX    0x01000000
+
+#define E1000_EICR_TX_QUEUE ( \
+    E1000_EICR_TX_QUEUE0 |    \
+    E1000_EICR_TX_QUEUE1 |    \
+    E1000_EICR_TX_QUEUE2 |    \
+    E1000_EICR_TX_QUEUE3)
+
+#define E1000_EICR_RX_QUEUE ( \
+    E1000_EICR_RX_QUEUE0 |    \
+    E1000_EICR_RX_QUEUE1 |    \
+    E1000_EICR_RX_QUEUE2 |    \
+    E1000_EICR_RX_QUEUE3)
+
+#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
+#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
+
+/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+       struct {
+               u64 pkt_addr;             /* Packet buffer address */
+               u64 hdr_addr;             /* Header buffer address */
+       } read;
+       struct {
+               struct {
+                       struct {
+                               u16 pkt_info;   /* RSS type, Packet type */
+                               u16 hdr_info;   /* Split Header,
+                                                * header buffer length */
+                       } lo_dword;
+                       union {
+                               u32 rss;          /* RSS Hash */
+                               struct {
+                                       u16 ip_id;    /* IP id */
+                                       u16 csum;     /* Packet Checksum */
+                               } csum_ip;
+                       } hi_dword;
+               } lower;
+               struct {
+                       u32 status_error;     /* ext status/error */
+                       u16 length;           /* Packet length */
+                       u16 vlan;             /* VLAN tag */
+               } upper;
+       } wb;  /* writeback */
+};
+
+#define E1000_RXDADV_HDRBUFLEN_MASK      0x7FE0
+#define E1000_RXDADV_HDRBUFLEN_SHIFT     5
+
+/* RSS Hash results */
+
+/* RSS Packet Types as indicated in the receive descriptor */
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+       struct {
+               u64 buffer_addr;    /* Address of descriptor's data buf */
+               u32 cmd_type_len;
+               u32 olinfo_status;
+       } read;
+       struct {
+               u64 rsvd;       /* Reserved */
+               u32 nxtseq_seed;
+               u32 status;
+       } wb;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_DTYP_CTXT    0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA    0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_IFCS    0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_DEXT    0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE     0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE     0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+
+/* Context descriptors */
+struct e1000_adv_tx_context_desc {
+       u32 vlan_macip_lens;
+       u32 seqnum_seed;
+       u32 type_tucmd_mlhl;
+       u32 mss_l4len_idx;
+};
+
+#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 */
+/* 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 */
+/* Adv ctxt IPSec SA IDX mask */
+/* Adv ctxt IPSec ESP len mask */
+
+/* Additional Transmit Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Tx Queue */
+/* Tx Queue Arbitration Priority 0=low, 1=high */
+
+/* Additional Receive Descriptor Control definitions */
+#define E1000_RXDCTL_QUEUE_ENABLE  0x02000000 /* Enable specific Rx Queue */
+
+/* Direct Cache Access (DCA) definitions */
+
+
+
+#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
+
+#endif
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
new file mode 100644 (file)
index 0000000..8da9ffe
--- /dev/null
@@ -0,0 +1,772 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_DEFINES_H_
+#define _E1000_DEFINES_H_
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define E1000_WUC_PME_EN     0x00000002 /* PME Enable */
+
+/* Wake Up Filter Control */
+#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define E1000_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define E1000_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define E1000_WUFC_MC   0x00000008 /* Directed Multicast Wakeup Enable */
+#define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+#define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
+#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+
+/* Wake Up Status */
+
+/* Wake Up Packet Length */
+
+/* Four Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128
+
+
+/* Extended Device Control */
+#define E1000_CTRL_EXT_GPI1_EN   0x00000002 /* Maps SDP5 to GPI1 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP4_DIR  0x00000100 /* Direction of SDP4 0=in 1=out */
+#define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES  0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_SGMII   0x00800000
+#define E1000_CTRL_EXT_EIAME          0x01000000
+#define E1000_CTRL_EXT_IRCA           0x00000001
+/* Interrupt delay cancellation */
+/* Driver loaded bit for FW */
+#define E1000_CTRL_EXT_DRV_LOAD       0x10000000
+/* Interrupt acknowledge Auto-mask */
+/* Clear Interrupt timers after IMS clear */
+/* packet buffer parity error detection enabled */
+/* descriptor FIFO parity error detection enable */
+#define E1000_CTRL_EXT_PBA_CLR        0x80000000 /* PBA Clear */
+#define E1000_I2CCMD_REG_ADDR_SHIFT   16
+#define E1000_I2CCMD_PHY_ADDR_SHIFT   24
+#define E1000_I2CCMD_OPCODE_READ      0x08000000
+#define E1000_I2CCMD_OPCODE_WRITE     0x00000000
+#define E1000_I2CCMD_READY            0x20000000
+#define E1000_I2CCMD_ERROR            0x80000000
+#define E1000_MAX_SGMII_PHY_REG_ADDR  255
+#define E1000_I2CCMD_PHY_TIMEOUT      200
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_UDPCS    0x10    /* UDP xsum caculated */
+#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
+#define E1000_RXD_STAT_DYNINT   0x800   /* Pkt caused INT via DYNINT */
+#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
+#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
+#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
+#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
+#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+
+#define E1000_RXDEXT_STATERR_CE    0x01000000
+#define E1000_RXDEXT_STATERR_SE    0x02000000
+#define E1000_RXDEXT_STATERR_SEQ   0x04000000
+#define E1000_RXDEXT_STATERR_CXE   0x10000000
+#define E1000_RXDEXT_STATERR_TCPE  0x20000000
+#define E1000_RXDEXT_STATERR_IPE   0x40000000
+#define E1000_RXDEXT_STATERR_RXE   0x80000000
+
+/* mask to determine if packets should be dropped due to frame errors */
+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
+    E1000_RXD_ERR_CE  |                \
+    E1000_RXD_ERR_SE  |                \
+    E1000_RXD_ERR_SEQ |                \
+    E1000_RXD_ERR_CXE |                \
+    E1000_RXD_ERR_RXE)
+
+/* Same mask, but for extended and packet split descriptors */
+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
+    E1000_RXDEXT_STATERR_CE  |            \
+    E1000_RXDEXT_STATERR_SE  |            \
+    E1000_RXDEXT_STATERR_SEQ |            \
+    E1000_RXDEXT_STATERR_CXE |            \
+    E1000_RXDEXT_STATERR_RXE)
+
+#define E1000_MRQC_RSS_FIELD_IPV4_TCP          0x00010000
+#define E1000_MRQC_RSS_FIELD_IPV4              0x00020000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX       0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6              0x00100000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP          0x00200000
+
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
+#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
+/* Enable Neighbor Discovery Filtering */
+#define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
+#define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
+/* Enable MAC address filtering */
+#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000
+/* Enable MNG packets to host memory */
+#define E1000_MANC_EN_MNG2HOST   0x00200000
+/* Enable IP address filtering */
+
+
+/* Receive Control */
+#define E1000_RCTL_EN             0x00000002    /* enable */
+#define E1000_RCTL_SBP            0x00000004    /* store bad packet */
+#define E1000_RCTL_UPE            0x00000008    /* unicast promiscuous enable */
+#define E1000_RCTL_MPE            0x00000010    /* multicast promiscuous enab */
+#define E1000_RCTL_LPE            0x00000020    /* long packet enable */
+#define E1000_RCTL_LBM_NO         0x00000000    /* no loopback mode */
+#define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
+#define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
+#define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
+#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_SZ_1024        0x00010000    /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
+#define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
+#define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
+#define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
+#define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
+
+/*
+ * Use byte values for the following shift parameters
+ * Usage:
+ *     psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE0_MASK) |
+ *                ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE1_MASK) |
+ *                ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
+ *                  E1000_PSRCTL_BSIZE2_MASK) |
+ *                ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
+ *                  E1000_PSRCTL_BSIZE3_MASK))
+ * where value0 = [128..16256],  default=256
+ *       value1 = [1024..64512], default=4096
+ *       value2 = [0..64512],    default=4096
+ *       value3 = [0..64512],    default=0
+ */
+
+#define E1000_PSRCTL_BSIZE0_MASK   0x0000007F
+#define E1000_PSRCTL_BSIZE1_MASK   0x00003F00
+#define E1000_PSRCTL_BSIZE2_MASK   0x003F0000
+#define E1000_PSRCTL_BSIZE3_MASK   0x3F000000
+
+#define E1000_PSRCTL_BSIZE0_SHIFT  7            /* Shift _right_ 7 */
+#define E1000_PSRCTL_BSIZE1_SHIFT  2            /* Shift _right_ 2 */
+#define E1000_PSRCTL_BSIZE2_SHIFT  6            /* Shift _left_ 6 */
+#define E1000_PSRCTL_BSIZE3_SHIFT 14            /* Shift _left_ 14 */
+
+/* SWFW_SYNC Definitions */
+#define E1000_SWFW_EEP_SM   0x1
+#define E1000_SWFW_PHY0_SM  0x2
+#define E1000_SWFW_PHY1_SM  0x4
+
+/* FACTPS Definitions */
+/* Device Control */
+#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
+#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
+#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL  0x00000300  /* Speed Select Mask */
+#define E1000_CTRL_SPD_100  0x00000100  /* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200  /* Force 1Gb */
+#define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
+#define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
+/* Defined polarity of Dock/Undock indication in SDP[0] */
+/* Reset both PHY ports, through PHYRST_N pin */
+/* enable link status from external LINK_0 and LINK_1 pins */
+#define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3  0x00200000  /* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
+#define E1000_CTRL_RST      0x04000000  /* Global reset */
+#define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
+#define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */
+/* Initiate an interrupt to manageability engine */
+#define E1000_CTRL_I2C_ENA  0x02000000  /* I2C enable */
+
+/* Bit definitions for the Management Data IO (MDIO) and Management Data
+ * Clock (MDC) pins in the Device Control Register.
+ */
+
+#define E1000_CONNSW_ENRGSRC             0x4
+#define E1000_PCS_LCTL_FLV_LINK_UP       1
+#define E1000_PCS_LCTL_FSV_100           2
+#define E1000_PCS_LCTL_FSV_1000          4
+#define E1000_PCS_LCTL_FDV_FULL          8
+#define E1000_PCS_LCTL_FSD               0x10
+#define E1000_PCS_LCTL_FORCE_LINK        0x20
+#define E1000_PCS_LCTL_AN_ENABLE         0x10000
+#define E1000_PCS_LCTL_AN_RESTART        0x20000
+#define E1000_PCS_LCTL_AN_TIMEOUT        0x40000
+
+#define E1000_PCS_LSTS_LINK_OK           1
+#define E1000_PCS_LSTS_SPEED_100         2
+#define E1000_PCS_LSTS_SPEED_1000        4
+#define E1000_PCS_LSTS_DUPLEX_FULL       8
+#define E1000_PCS_LSTS_SYNK_OK           0x10
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
+#define E1000_STATUS_FUNC_SHIFT 2
+#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
+#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
+#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
+/* Change in Dock/Undock state. Clear on write '0'. */
+/* Status of Master requests. */
+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
+/* BMC external code execution disabled */
+
+/* Constants used to intrepret the masked PCI-X bus speed. */
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+
+#define ADVERTISE_10_HALF                 0x0001
+#define ADVERTISE_10_FULL                 0x0002
+#define ADVERTISE_100_HALF                0x0004
+#define ADVERTISE_100_FULL                0x0008
+#define ADVERTISE_1000_HALF               0x0010 /* Not used, just FYI */
+#define ADVERTISE_1000_FULL               0x0020
+
+/* 1000/H is not supported, nor spec-compliant. */
+#define E1000_ALL_SPEED_DUPLEX (ADVERTISE_10_HALF  |  ADVERTISE_10_FULL | \
+                               ADVERTISE_100_HALF |  ADVERTISE_100_FULL | \
+                                                     ADVERTISE_1000_FULL)
+#define E1000_ALL_NOT_GIG      (ADVERTISE_10_HALF  |  ADVERTISE_10_FULL | \
+                               ADVERTISE_100_HALF |  ADVERTISE_100_FULL)
+#define E1000_ALL_100_SPEED    (ADVERTISE_100_HALF |  ADVERTISE_100_FULL)
+#define E1000_ALL_10_SPEED     (ADVERTISE_10_HALF  |  ADVERTISE_10_FULL)
+#define E1000_ALL_FULL_DUPLEX  (ADVERTISE_10_FULL  |  ADVERTISE_100_FULL | \
+                                                     ADVERTISE_1000_FULL)
+#define E1000_ALL_HALF_DUPLEX  (ADVERTISE_10_HALF  |  ADVERTISE_100_HALF)
+
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT   E1000_ALL_SPEED_DUPLEX
+
+/* LED Control */
+#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_LED_ON        0xE
+#define E1000_LEDCTL_MODE_LED_OFF       0xF
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
+#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
+#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+/* Extended desc bits for Linksec and timesync */
+
+/* Transmit Control */
+#define E1000_TCTL_EN     0x00000002    /* enable tx */
+#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
+#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
+#define E1000_TCTL_COLD   0x003ff000    /* collision distance */
+#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
+
+/* Transmit Arbitration Count */
+
+/* SerDes Control */
+#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
+
+/* Receive Checksum Control */
+#define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
+#define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
+#define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
+
+/* Header split receive */
+
+/* Collision related configuration parameters */
+#define E1000_COLLISION_THRESHOLD       15
+#define E1000_CT_SHIFT                  4
+#define E1000_COLLISION_DISTANCE        63
+#define E1000_COLD_SHIFT                12
+
+/* Ethertype field values */
+#define ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.3ac packet */
+
+#define MAX_JUMBO_FRAME_SIZE    0x3F00
+
+/* Extended Configuration Control and Size */
+#define E1000_PHY_CTRL_GBE_DISABLE        0x00000040
+
+/* PBA constants */
+#define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
+#define E1000_PBA_24K 0x0018
+#define E1000_PBA_34K 0x0022
+
+#define IFS_MAX       80
+#define IFS_MIN       40
+#define IFS_RATIO     4
+#define IFS_STEP      10
+#define MIN_NUM_XMITS 1000
+
+/* SW Semaphore Register */
+#define E1000_SWSM_SMBI         0x00000001 /* Driver Semaphore bit */
+#define E1000_SWSM_SWESMBI      0x00000002 /* FW Semaphore bit */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
+#define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
+#define E1000_ICR_LSC           0x00000004 /* Link Status Change */
+#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
+#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO           0x00000040 /* rx overrun */
+#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC          0x00000200 /* MDIO access complete */
+#define E1000_ICR_RXCFG         0x00000400 /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0       0x00000800 /* GP Int 0 */
+#define E1000_ICR_GPI_EN1       0x00001000 /* GP Int 1 */
+#define E1000_ICR_GPI_EN2       0x00002000 /* GP Int 2 */
+#define E1000_ICR_GPI_EN3       0x00004000 /* GP Int 3 */
+#define E1000_ICR_TXD_LOW       0x00008000
+#define E1000_ICR_SRPD          0x00010000
+#define E1000_ICR_ACK           0x00020000 /* Receive Ack frame */
+#define E1000_ICR_MNG           0x00040000 /* Manageability event */
+#define E1000_ICR_DOCK          0x00080000 /* Dock/Undock */
+/* If this bit asserted, the driver should claim the interrupt */
+#define E1000_ICR_INT_ASSERTED  0x80000000
+/* queue 0 Rx descriptor FIFO parity error */
+#define E1000_ICR_RXD_FIFO_PAR0 0x00100000
+/* queue 0 Tx descriptor FIFO parity error */
+#define E1000_ICR_TXD_FIFO_PAR0 0x00200000
+/* host arb read buffer parity error */
+#define E1000_ICR_HOST_ARB_PAR  0x00400000
+#define E1000_ICR_PB_PAR        0x00800000 /* packet buffer parity error */
+/* queue 1 Rx descriptor FIFO parity error */
+#define E1000_ICR_RXD_FIFO_PAR1 0x01000000
+/* queue 1 Tx descriptor FIFO parity error */
+#define E1000_ICR_TXD_FIFO_PAR1 0x02000000
+/* FW changed the status of DISSW bit in the FWSM */
+#define E1000_ICR_DSW           0x00000020
+/* LAN connected device generates an interrupt */
+#define E1000_ICR_PHYINT        0x00001000
+#define E1000_ICR_EPRST         0x00100000 /* ME handware reset occurs */
+
+/* Extended Interrupt Cause Read */
+#define E1000_EICR_RX_QUEUE0    0x00000001 /* Rx Queue 0 Interrupt */
+#define E1000_EICR_RX_QUEUE1    0x00000002 /* Rx Queue 1 Interrupt */
+#define E1000_EICR_RX_QUEUE2    0x00000004 /* Rx Queue 2 Interrupt */
+#define E1000_EICR_RX_QUEUE3    0x00000008 /* Rx Queue 3 Interrupt */
+#define E1000_EICR_TX_QUEUE0    0x00000100 /* Tx Queue 0 Interrupt */
+#define E1000_EICR_TX_QUEUE1    0x00000200 /* Tx Queue 1 Interrupt */
+#define E1000_EICR_TX_QUEUE2    0x00000400 /* Tx Queue 2 Interrupt */
+#define E1000_EICR_TX_QUEUE3    0x00000800 /* Tx Queue 3 Interrupt */
+#define E1000_EICR_TCP_TIMER    0x40000000 /* TCP Timer */
+#define E1000_EICR_OTHER        0x80000000 /* Interrupt Cause Active */
+/* TCP Timer */
+
+/*
+ * This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXT0   = Receiver Timer Interrupt (ring 0)
+ *   o TXDW   = Transmit Descriptor Written Back
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ *   o LSC    = Link Status Change
+ */
+#define IMS_ENABLE_MASK ( \
+    E1000_IMS_RXT0   |    \
+    E1000_IMS_TXDW   |    \
+    E1000_IMS_RXDMT0 |    \
+    E1000_IMS_RXSEQ  |    \
+    E1000_IMS_LSC)
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
+#define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
+#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+/* queue 0 Rx descriptor FIFO parity error */
+/* queue 0 Tx descriptor FIFO parity error */
+/* host arb read buffer parity error */
+/* packet buffer parity error */
+/* queue 1 Rx descriptor FIFO parity error */
+/* queue 1 Tx descriptor FIFO parity error */
+
+/* Extended Interrupt Mask Set */
+#define E1000_EIMS_TCP_TIMER    E1000_EICR_TCP_TIMER /* TCP Timer */
+#define E1000_EIMS_OTHER        E1000_EICR_OTHER   /* Interrupt Cause Active */
+
+/* Interrupt Cause Set */
+#define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
+#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+/* queue 0 Rx descriptor FIFO parity error */
+/* queue 0 Tx descriptor FIFO parity error */
+/* host arb read buffer parity error */
+/* packet buffer parity error */
+/* queue 1 Rx descriptor FIFO parity error */
+/* queue 1 Tx descriptor FIFO parity error */
+
+/* Extended Interrupt Cause Set */
+
+/* Transmit Descriptor Control */
+/* Enable the counting of descriptors still to be processed. */
+
+/* Flow Control Constants */
+#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
+#define FLOW_CONTROL_TYPE         0x8808
+
+/* 802.1q VLAN Packet Size */
+#define VLAN_TAG_SIZE              4    /* 802.3ac tag (not DMA'd) */
+#define E1000_VLAN_FILTER_TBL_SIZE 128  /* VLAN Filter Table (4096 bits) */
+
+/* Receive Address */
+/*
+ * Number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor.
+ * Technically, we have 16 spots.  However, we reserve one of these spots
+ * (RAR[15]) for our directed address used by controllers with
+ * manageability enabled, allowing us room for 15 multicast addresses.
+ */
+#define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+
+/* Error Codes */
+#define E1000_ERR_NVM      1
+#define E1000_ERR_PHY      2
+#define E1000_ERR_CONFIG   3
+#define E1000_ERR_PARAM    4
+#define E1000_ERR_MAC_INIT 5
+#define E1000_ERR_RESET   9
+#define E1000_ERR_MASTER_REQUESTS_PENDING 10
+#define E1000_ERR_HOST_INTERFACE_COMMAND 11
+#define E1000_BLK_PHY_RESET   12
+#define E1000_ERR_SWFW_SYNC 13
+#define E1000_NOT_IMPLEMENTED 14
+
+/* Loop limit on how long we wait for auto-negotiation to complete */
+#define COPPER_LINK_UP_LIMIT              10
+#define PHY_AUTO_NEG_LIMIT                45
+#define PHY_FORCE_LIMIT                   20
+/* Number of 100 microseconds we wait for PCI Express master disable */
+#define MASTER_DISABLE_TIMEOUT      800
+/* Number of milliseconds we wait for PHY configuration done after MAC reset */
+#define PHY_CFG_TIMEOUT             100
+/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */
+/* Number of milliseconds for NVM auto read done after MAC reset. */
+#define AUTO_READ_DONE_TIMEOUT      10
+
+/* Flow Control */
+#define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
+
+/* Transmit Configuration Word */
+#define E1000_TXCW_ANE        0x80000000        /* Auto-neg enable */
+
+/* Receive Configuration Word */
+
+/* PCI Express Control */
+#define E1000_GCR_RXD_NO_SNOOP          0x00000001
+#define E1000_GCR_RXDSCW_NO_SNOOP       0x00000002
+#define E1000_GCR_RXDSCR_NO_SNOOP       0x00000004
+#define E1000_GCR_TXD_NO_SNOOP          0x00000008
+#define E1000_GCR_TXDSCW_NO_SNOOP       0x00000010
+#define E1000_GCR_TXDSCR_NO_SNOOP       0x00000020
+
+#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP         | \
+                          E1000_GCR_RXDSCW_NO_SNOOP      | \
+                          E1000_GCR_RXDSCR_NO_SNOOP      | \
+                          E1000_GCR_TXD_NO_SNOOP         | \
+                          E1000_GCR_TXDSCW_NO_SNOOP      | \
+                          E1000_GCR_TXDSCR_NO_SNOOP)
+
+/* PHY Control Register */
+#define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
+#define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
+#define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
+#define MII_CR_SPEED_1000       0x0040
+#define MII_CR_SPEED_100        0x2000
+#define MII_CR_SPEED_10         0x0000
+
+/* PHY Status Register */
+#define MII_SR_LINK_STATUS       0x0004 /* Link Status 1 = link */
+#define MII_SR_AUTONEG_COMPLETE  0x0020 /* Auto Neg Complete */
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_10T_HD_CAPS      0x0020   /* 10T   Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS      0x0040   /* 10T   Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS    0x0080   /* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS    0x0100   /* 100TX Full Duplex Capable */
+#define NWAY_AR_PAUSE            0x0400   /* Pause operation desired */
+#define NWAY_AR_ASM_DIR          0x0800   /* Asymmetric Pause Direction bit */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_PAUSE          0x0400 /* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR        0x0800 /* LP Asymmetric Pause Direction bit */
+
+/* Autoneg Expansion Register */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_HD_CAPS         0x0100 /* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS         0x0200 /* Advertise 1000T FD capability  */
+                                       /* 0=DTE device */
+#define CR_1000T_MS_VALUE        0x0800 /* 1=Configure PHY as Master */
+                                       /* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE       0x1000 /* 1=Master/Slave manual config value */
+                                       /* 0=Automatic Master/Slave config */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */
+
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CONTROL      0x00 /* Control Register */
+#define PHY_STATUS       0x01 /* Status Regiser */
+#define PHY_ID1          0x02 /* Phy Id Reg (word 1) */
+#define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
+#define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
+
+/* NVM Control */
+#define E1000_EECD_SK        0x00000001 /* NVM Clock */
+#define E1000_EECD_CS        0x00000002 /* NVM Chip Select */
+#define E1000_EECD_DI        0x00000004 /* NVM Data In */
+#define E1000_EECD_DO        0x00000008 /* NVM Data Out */
+#define E1000_EECD_REQ       0x00000040 /* NVM Access Request */
+#define E1000_EECD_GNT       0x00000080 /* NVM Access Grant */
+#define E1000_EECD_PRES      0x00000100 /* NVM Present */
+/* NVM Addressing bits based on type 0=small, 1=large */
+#define E1000_EECD_ADDR_BITS 0x00000400
+#define E1000_NVM_GRANT_ATTEMPTS   1000 /* NVM # attempts to gain grant */
+#define E1000_EECD_AUTO_RD          0x00000200  /* NVM Auto Read done */
+#define E1000_EECD_SIZE_EX_MASK     0x00007800  /* NVM Size */
+#define E1000_EECD_SIZE_EX_SHIFT     11
+
+/* Offset to data in NVM read/write registers */
+#define E1000_NVM_RW_REG_DATA   16
+#define E1000_NVM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
+#define E1000_NVM_RW_REG_START  1    /* Start operation */
+#define E1000_NVM_RW_ADDR_SHIFT 2    /* Shift to the address bits */
+#define E1000_NVM_POLL_READ     0    /* Flag for polling for read complete */
+
+/* NVM Word Offsets */
+#define NVM_ID_LED_SETTINGS        0x0004
+/* For SERDES output amplitude adjustment. */
+#define NVM_INIT_CONTROL2_REG      0x000F
+#define NVM_INIT_CONTROL3_PORT_A   0x0024
+#define NVM_ALT_MAC_ADDR_PTR       0x0037
+#define NVM_CHECKSUM_REG           0x003F
+
+#define E1000_NVM_CFG_DONE_PORT_0  0x40000 /* MNG config cycle done */
+#define E1000_NVM_CFG_DONE_PORT_1  0x80000 /* ...for second port */
+
+/* Mask bits for fields in Word 0x0f of the NVM */
+#define NVM_WORD0F_PAUSE_MASK       0x3000
+#define NVM_WORD0F_ASM_DIR          0x2000
+
+/* Mask bits for fields in Word 0x1a of the NVM */
+
+/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */
+#define NVM_SUM                    0xBABA
+
+#define NVM_PBA_OFFSET_0           8
+#define NVM_PBA_OFFSET_1           9
+#define NVM_WORD_SIZE_BASE_SHIFT   6
+
+/* NVM Commands - Microwire */
+
+/* NVM Commands - SPI */
+#define NVM_MAX_RETRY_SPI          5000 /* Max wait of 5ms, for RDY signal */
+#define NVM_WRITE_OPCODE_SPI       0x02 /* NVM write opcode */
+#define NVM_A8_OPCODE_SPI          0x08 /* opcode bit-3 = address bit-8 */
+#define NVM_WREN_OPCODE_SPI        0x06 /* NVM set Write Enable latch */
+#define NVM_RDSR_OPCODE_SPI        0x05 /* NVM read Status register */
+
+/* SPI NVM Status Register */
+#define NVM_STATUS_RDY_SPI         0x01
+
+/* Word definitions for ID LED Settings */
+#define ID_LED_RESERVED_0000 0x0000
+#define ID_LED_RESERVED_FFFF 0xFFFF
+#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2  << 12) | \
+                             (ID_LED_OFF1_OFF2 <<  8) | \
+                             (ID_LED_DEF1_DEF2 <<  4) | \
+                             (ID_LED_DEF1_DEF2))
+#define ID_LED_DEF1_DEF2     0x1
+#define ID_LED_DEF1_ON2      0x2
+#define ID_LED_DEF1_OFF2     0x3
+#define ID_LED_ON1_DEF2      0x4
+#define ID_LED_ON1_ON2       0x5
+#define ID_LED_ON1_OFF2      0x6
+#define ID_LED_OFF1_DEF2     0x7
+#define ID_LED_OFF1_ON2      0x8
+#define ID_LED_OFF1_OFF2     0x9
+
+#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
+#define IGP_ACTIVITY_LED_ENABLE 0x0300
+#define IGP_LED3_MODE           0x07000000
+
+/* PCI/PCI-X/PCI-EX Config space */
+#define PCI_HEADER_TYPE_REGISTER     0x0E
+#define PCIE_LINK_STATUS             0x12
+
+#define PCI_HEADER_TYPE_MULTIFUNC    0x80
+#define PCIE_LINK_WIDTH_MASK         0x3F0
+#define PCIE_LINK_WIDTH_SHIFT        4
+
+#define PHY_REVISION_MASK      0xFFFFFFF0
+#define MAX_PHY_REG_ADDRESS    0x1F  /* 5 bit address bus (0-0x1F) */
+#define MAX_PHY_MULTI_PAGE_REG 0xF
+
+/* Bit definitions for valid PHY IDs. */
+/*
+ * I = Integrated
+ * E = External
+ */
+#define M88E1111_I_PHY_ID    0x01410CC0
+#define IGP03E1000_E_PHY_ID  0x02A80390
+#define M88_VENDOR           0x0141
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
+
+#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
+#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
+
+/* M88E1000 PHY Specific Control Register */
+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
+/* 1=CLK125 low, 0=CLK125 toggling */
+#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
+                                              /* Manual MDI configuration */
+#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
+/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
+#define M88E1000_PSCR_AUTO_X_1000T     0x0040
+/* Auto crossover enabled all speeds */
+#define M88E1000_PSCR_AUTO_X_MODE      0x0060
+/*
+ * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold
+ * 0=Normal 10BASE-T RX Threshold
+ */
+/* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800 /* 1=Assert CRS on Transmit */
+
+/* M88E1000 PHY Specific Status Register */
+#define M88E1000_PSSR_REV_POLARITY       0x0002 /* 1=Polarity reversed */
+#define M88E1000_PSSR_DOWNSHIFT          0x0020 /* 1=Downshifted */
+#define M88E1000_PSSR_MDIX               0x0040 /* 1=MDIX; 0=MDI */
+/*
+ * 0 = <50M
+ * 1 = 50-80M
+ * 2 = 80-110M
+ * 3 = 110-140M
+ * 4 = >140M
+ */
+#define M88E1000_PSSR_CABLE_LENGTH       0x0380
+#define M88E1000_PSSR_SPEED              0xC000 /* Speed, bits 14:15 */
+#define M88E1000_PSSR_1000MBS            0x8000 /* 10=1000Mbs */
+
+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
+
+/* M88E1000 Extended PHY Specific Control Register */
+/*
+ * 1 = Lost lock detect enabled.
+ * Will assert lost lock and bring
+ * link down if idle not seen
+ * within 1ms in 1000BASE-T
+ */
+/*
+ * Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master
+ */
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
+/*
+ * Number of times we will attempt to autonegotiate before downshifting if we
+ * are the slave
+ */
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
+#define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
+
+/* M88EC018 Rev 2 specific DownShift settings */
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
+
+/* MDI Control */
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE  0x04000000
+#define E1000_MDIC_OP_READ   0x08000000
+#define E1000_MDIC_READY     0x10000000
+#define E1000_MDIC_ERROR     0x40000000
+
+/* SerDes Control */
+#define E1000_GEN_CTL_READY             0x80000000
+#define E1000_GEN_CTL_ADDRESS_SHIFT     8
+#define E1000_GEN_POLL_TIMEOUT          640
+
+#endif
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
new file mode 100644 (file)
index 0000000..161fb68
--- /dev/null
@@ -0,0 +1,599 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_HW_H_
+#define _E1000_HW_H_
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "e1000_mac.h"
+#include "e1000_regs.h"
+#include "e1000_defines.h"
+
+struct e1000_hw;
+
+#define E1000_DEV_ID_82575EB_COPPER           0x10A7
+#define E1000_DEV_ID_82575EB_FIBER_SERDES     0x10A9
+#define E1000_DEV_ID_82575GB_QUAD_COPPER      0x10D6
+
+#define E1000_REVISION_2 2
+#define E1000_REVISION_4 4
+
+#define E1000_FUNC_1     1
+
+enum e1000_mac_type {
+       e1000_undefined = 0,
+       e1000_82575,
+       e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
+};
+
+enum e1000_media_type {
+       e1000_media_type_unknown = 0,
+       e1000_media_type_copper = 1,
+       e1000_media_type_fiber = 2,
+       e1000_media_type_internal_serdes = 3,
+       e1000_num_media_types
+};
+
+enum e1000_nvm_type {
+       e1000_nvm_unknown = 0,
+       e1000_nvm_none,
+       e1000_nvm_eeprom_spi,
+       e1000_nvm_eeprom_microwire,
+       e1000_nvm_flash_hw,
+       e1000_nvm_flash_sw
+};
+
+enum e1000_nvm_override {
+       e1000_nvm_override_none = 0,
+       e1000_nvm_override_spi_small,
+       e1000_nvm_override_spi_large,
+       e1000_nvm_override_microwire_small,
+       e1000_nvm_override_microwire_large
+};
+
+enum e1000_phy_type {
+       e1000_phy_unknown = 0,
+       e1000_phy_none,
+       e1000_phy_m88,
+       e1000_phy_igp,
+       e1000_phy_igp_2,
+       e1000_phy_gg82563,
+       e1000_phy_igp_3,
+       e1000_phy_ife,
+};
+
+enum e1000_bus_type {
+       e1000_bus_type_unknown = 0,
+       e1000_bus_type_pci,
+       e1000_bus_type_pcix,
+       e1000_bus_type_pci_express,
+       e1000_bus_type_reserved
+};
+
+enum e1000_bus_speed {
+       e1000_bus_speed_unknown = 0,
+       e1000_bus_speed_33,
+       e1000_bus_speed_66,
+       e1000_bus_speed_100,
+       e1000_bus_speed_120,
+       e1000_bus_speed_133,
+       e1000_bus_speed_2500,
+       e1000_bus_speed_5000,
+       e1000_bus_speed_reserved
+};
+
+enum e1000_bus_width {
+       e1000_bus_width_unknown = 0,
+       e1000_bus_width_pcie_x1,
+       e1000_bus_width_pcie_x2,
+       e1000_bus_width_pcie_x4 = 4,
+       e1000_bus_width_pcie_x8 = 8,
+       e1000_bus_width_32,
+       e1000_bus_width_64,
+       e1000_bus_width_reserved
+};
+
+enum e1000_1000t_rx_status {
+       e1000_1000t_rx_status_not_ok = 0,
+       e1000_1000t_rx_status_ok,
+       e1000_1000t_rx_status_undefined = 0xFF
+};
+
+enum e1000_rev_polarity {
+       e1000_rev_polarity_normal = 0,
+       e1000_rev_polarity_reversed,
+       e1000_rev_polarity_undefined = 0xFF
+};
+
+enum e1000_fc_type {
+       e1000_fc_none = 0,
+       e1000_fc_rx_pause,
+       e1000_fc_tx_pause,
+       e1000_fc_full,
+       e1000_fc_default = 0xFF
+};
+
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+       u64 buffer_addr; /* Address of the descriptor's data buffer */
+       u16 length;      /* Length of data DMAed into data buffer */
+       u16 csum;        /* Packet checksum */
+       u8  status;      /* Descriptor status */
+       u8  errors;      /* Descriptor Errors */
+       u16 special;
+};
+
+/* Receive Descriptor - Extended */
+union e1000_rx_desc_extended {
+       struct {
+               u64 buffer_addr;
+               u64 reserved;
+       } read;
+       struct {
+               struct {
+                       u32 mrq;              /* Multiple Rx Queues */
+                       union {
+                               u32 rss;            /* RSS Hash */
+                               struct {
+                                       u16 ip_id;  /* IP id */
+                                       u16 csum;   /* Packet Checksum */
+                               } csum_ip;
+                       } hi_dword;
+               } lower;
+               struct {
+                       u32 status_error;     /* ext status/error */
+                       u16 length;
+                       u16 vlan;             /* VLAN tag */
+               } upper;
+       } wb;  /* writeback */
+};
+
+#define MAX_PS_BUFFERS 4
+/* Receive Descriptor - Packet Split */
+union e1000_rx_desc_packet_split {
+       struct {
+               /* one buffer for protocol header(s), three data buffers */
+               u64 buffer_addr[MAX_PS_BUFFERS];
+       } read;
+       struct {
+               struct {
+                       u32 mrq;              /* Multiple Rx Queues */
+                       union {
+                               u32 rss;              /* RSS Hash */
+                               struct {
+                                       u16 ip_id;    /* IP id */
+                                       u16 csum;     /* Packet Checksum */
+                               } csum_ip;
+                       } hi_dword;
+               } lower;
+               struct {
+                       u32 status_error;     /* ext status/error */
+                       u16 length0;          /* length of buffer 0 */
+                       u16 vlan;             /* VLAN tag */
+               } middle;
+               struct {
+                       u16 header_status;
+                       u16 length[3];        /* length of buffers 1-3 */
+               } upper;
+               u64 reserved;
+       } wb; /* writeback */
+};
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+       u64 buffer_addr;      /* Address of the descriptor's data buffer */
+       union {
+               u32 data;
+               struct {
+                       u16 length;    /* Data buffer length */
+                       u8 cso;        /* Checksum offset */
+                       u8 cmd;        /* Descriptor control */
+               } flags;
+       } lower;
+       union {
+               u32 data;
+               struct {
+                       u8 status;     /* Descriptor status */
+                       u8 css;        /* Checksum start */
+                       u16 special;
+               } fields;
+       } upper;
+};
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+       union {
+               u32 ip_config;
+               struct {
+                       u8 ipcss;      /* IP checksum start */
+                       u8 ipcso;      /* IP checksum offset */
+                       u16 ipcse;     /* IP checksum end */
+               } ip_fields;
+       } lower_setup;
+       union {
+               u32 tcp_config;
+               struct {
+                       u8 tucss;      /* TCP checksum start */
+                       u8 tucso;      /* TCP checksum offset */
+                       u16 tucse;     /* TCP checksum end */
+               } tcp_fields;
+       } upper_setup;
+       u32 cmd_and_length;
+       union {
+               u32 data;
+               struct {
+                       u8 status;     /* Descriptor status */
+                       u8 hdr_len;    /* Header length */
+                       u16 mss;       /* Maximum segment size */
+               } fields;
+       } tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+       u64 buffer_addr;   /* Address of the descriptor's buffer address */
+       union {
+               u32 data;
+               struct {
+                       u16 length;    /* Data buffer length */
+                       u8 typ_len_ext;
+                       u8 cmd;
+               } flags;
+       } lower;
+       union {
+               u32 data;
+               struct {
+                       u8 status;     /* Descriptor status */
+                       u8 popts;      /* Packet Options */
+                       u16 special;
+               } fields;
+       } upper;
+};
+
+/* Statistics counters collected by the MAC */
+struct e1000_hw_stats {
+       u64 crcerrs;
+       u64 algnerrc;
+       u64 symerrs;
+       u64 rxerrc;
+       u64 mpc;
+       u64 scc;
+       u64 ecol;
+       u64 mcc;
+       u64 latecol;
+       u64 colc;
+       u64 dc;
+       u64 tncrs;
+       u64 sec;
+       u64 cexterr;
+       u64 rlec;
+       u64 xonrxc;
+       u64 xontxc;
+       u64 xoffrxc;
+       u64 xofftxc;
+       u64 fcruc;
+       u64 prc64;
+       u64 prc127;
+       u64 prc255;
+       u64 prc511;
+       u64 prc1023;
+       u64 prc1522;
+       u64 gprc;
+       u64 bprc;
+       u64 mprc;
+       u64 gptc;
+       u64 gorc;
+       u64 gotc;
+       u64 rnbc;
+       u64 ruc;
+       u64 rfc;
+       u64 roc;
+       u64 rjc;
+       u64 mgprc;
+       u64 mgpdc;
+       u64 mgptc;
+       u64 tor;
+       u64 tot;
+       u64 tpr;
+       u64 tpt;
+       u64 ptc64;
+       u64 ptc127;
+       u64 ptc255;
+       u64 ptc511;
+       u64 ptc1023;
+       u64 ptc1522;
+       u64 mptc;
+       u64 bptc;
+       u64 tsctc;
+       u64 tsctfc;
+       u64 iac;
+       u64 icrxptc;
+       u64 icrxatc;
+       u64 ictxptc;
+       u64 ictxatc;
+       u64 ictxqec;
+       u64 ictxqmtc;
+       u64 icrxdmtc;
+       u64 icrxoc;
+       u64 cbtmpc;
+       u64 htdpmc;
+       u64 cbrdpc;
+       u64 cbrmpc;
+       u64 rpthc;
+       u64 hgptc;
+       u64 htcbdpc;
+       u64 hgorc;
+       u64 hgotc;
+       u64 lenerrs;
+       u64 scvpc;
+       u64 hrmpc;
+};
+
+struct e1000_phy_stats {
+       u32 idle_errors;
+       u32 receive_errors;
+};
+
+struct e1000_host_mng_dhcp_cookie {
+       u32 signature;
+       u8  status;
+       u8  reserved0;
+       u16 vlan_id;
+       u32 reserved1;
+       u16 reserved2;
+       u8  reserved3;
+       u8  checksum;
+};
+
+/* Host Interface "Rev 1" */
+struct e1000_host_command_header {
+       u8 command_id;
+       u8 command_length;
+       u8 command_options;
+       u8 checksum;
+};
+
+#define E1000_HI_MAX_DATA_LENGTH     252
+struct e1000_host_command_info {
+       struct e1000_host_command_header command_header;
+       u8 command_data[E1000_HI_MAX_DATA_LENGTH];
+};
+
+/* Host Interface "Rev 2" */
+struct e1000_host_mng_command_header {
+       u8  command_id;
+       u8  checksum;
+       u16 reserved1;
+       u16 reserved2;
+       u16 command_length;
+};
+
+#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
+struct e1000_host_mng_command_info {
+       struct e1000_host_mng_command_header command_header;
+       u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
+};
+
+#include "e1000_mac.h"
+#include "e1000_phy.h"
+#include "e1000_nvm.h"
+
+struct e1000_mac_operations {
+       s32  (*check_for_link)(struct e1000_hw *);
+       s32  (*reset_hw)(struct e1000_hw *);
+       s32  (*init_hw)(struct e1000_hw *);
+       s32  (*setup_physical_interface)(struct e1000_hw *);
+       void (*rar_set)(struct e1000_hw *, u8 *, u32);
+       s32  (*read_mac_addr)(struct e1000_hw *);
+       s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
+};
+
+struct e1000_phy_operations {
+       s32  (*acquire_phy)(struct e1000_hw *);
+       s32  (*force_speed_duplex)(struct e1000_hw *);
+       s32  (*get_cfg_done)(struct e1000_hw *hw);
+       s32  (*get_cable_length)(struct e1000_hw *);
+       s32  (*get_phy_info)(struct e1000_hw *);
+       s32  (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
+       void (*release_phy)(struct e1000_hw *);
+       s32  (*reset_phy)(struct e1000_hw *);
+       s32  (*set_d0_lplu_state)(struct e1000_hw *, bool);
+       s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
+       s32  (*write_phy_reg)(struct e1000_hw *, u32, u16);
+};
+
+struct e1000_nvm_operations {
+       s32  (*acquire_nvm)(struct e1000_hw *);
+       s32  (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
+       void (*release_nvm)(struct e1000_hw *);
+       s32  (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
+};
+
+struct e1000_info {
+       s32 (*get_invariants)(struct e1000_hw *);
+       struct e1000_mac_operations *mac_ops;
+       struct e1000_phy_operations *phy_ops;
+       struct e1000_nvm_operations *nvm_ops;
+};
+
+extern const struct e1000_info e1000_82575_info;
+
+struct e1000_mac_info {
+       struct e1000_mac_operations ops;
+
+       u8 addr[6];
+       u8 perm_addr[6];
+
+       enum e1000_mac_type type;
+
+       u32 collision_delta;
+       u32 ledctl_default;
+       u32 ledctl_mode1;
+       u32 ledctl_mode2;
+       u32 mc_filter_type;
+       u32 tx_packet_delta;
+       u32 txcw;
+
+       u16 current_ifs_val;
+       u16 ifs_max_val;
+       u16 ifs_min_val;
+       u16 ifs_ratio;
+       u16 ifs_step_size;
+       u16 mta_reg_count;
+       u16 rar_entry_count;
+
+       u8  forced_speed_duplex;
+
+       bool adaptive_ifs;
+       bool arc_subsystem_valid;
+       bool asf_firmware_present;
+       bool autoneg;
+       bool autoneg_failed;
+       bool disable_av;
+       bool disable_hw_init_bits;
+       bool get_link_status;
+       bool ifs_params_forced;
+       bool in_ifs_mode;
+       bool report_tx_early;
+       bool serdes_has_link;
+       bool tx_pkt_filtering;
+};
+
+struct e1000_phy_info {
+       struct e1000_phy_operations ops;
+
+       enum e1000_phy_type type;
+
+       enum e1000_1000t_rx_status local_rx;
+       enum e1000_1000t_rx_status remote_rx;
+       enum e1000_ms_type ms_type;
+       enum e1000_ms_type original_ms_type;
+       enum e1000_rev_polarity cable_polarity;
+       enum e1000_smart_speed smart_speed;
+
+       u32 addr;
+       u32 id;
+       u32 reset_delay_us; /* in usec */
+       u32 revision;
+
+       enum e1000_media_type media_type;
+
+       u16 autoneg_advertised;
+       u16 autoneg_mask;
+       u16 cable_length;
+       u16 max_cable_length;
+       u16 min_cable_length;
+
+       u8 mdix;
+
+       bool disable_polarity_correction;
+       bool is_mdix;
+       bool polarity_correction;
+       bool reset_disable;
+       bool speed_downgraded;
+       bool autoneg_wait_to_complete;
+};
+
+struct e1000_nvm_info {
+       struct e1000_nvm_operations ops;
+
+       enum e1000_nvm_type type;
+       enum e1000_nvm_override override;
+
+       u32 flash_bank_size;
+       u32 flash_base_addr;
+
+       u16 word_size;
+       u16 delay_usec;
+       u16 address_bits;
+       u16 opcode_bits;
+       u16 page_size;
+};
+
+struct e1000_bus_info {
+       enum e1000_bus_type type;
+       enum e1000_bus_speed speed;
+       enum e1000_bus_width width;
+
+       u32 snoop;
+
+       u16 func;
+       u16 pci_cmd_word;
+};
+
+struct e1000_fc_info {
+       u32 high_water;     /* Flow control high-water mark */
+       u32 low_water;      /* Flow control low-water mark */
+       u16 pause_time;     /* Flow control pause timer */
+       bool send_xon;      /* Flow control send XON */
+       bool strict_ieee;   /* Strict IEEE mode */
+       enum e1000_fc_type type; /* Type of flow control */
+       enum e1000_fc_type original_type;
+};
+
+struct e1000_hw {
+       void *back;
+       void *dev_spec;
+
+       u8 __iomem *hw_addr;
+       u8 __iomem *flash_address;
+       unsigned long io_base;
+
+       struct e1000_mac_info  mac;
+       struct e1000_fc_info   fc;
+       struct e1000_phy_info  phy;
+       struct e1000_nvm_info  nvm;
+       struct e1000_bus_info  bus;
+       struct e1000_host_mng_dhcp_cookie mng_cookie;
+
+       u32 dev_spec_size;
+
+       u16 device_id;
+       u16 subsystem_vendor_id;
+       u16 subsystem_device_id;
+       u16 vendor_id;
+
+       u8  revision_id;
+};
+
+#ifdef DEBUG
+extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
+#define hw_dbg(hw, format, arg...) \
+       printk(KERN_DEBUG "%s: " format, igb_get_hw_dev_name(hw), ##arg)
+#else
+static inline int __attribute__ ((format (printf, 2, 3)))
+hw_dbg(struct e1000_hw *hw, const char *format, ...)
+{
+       return 0;
+}
+#endif
+
+#endif
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
new file mode 100644 (file)
index 0000000..3e84a3f
--- /dev/null
@@ -0,0 +1,1505 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 <linux/if_ether.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+
+#include "e1000_mac.h"
+
+#include "igb.h"
+
+static s32 igb_set_default_fc(struct e1000_hw *hw);
+static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
+static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
+
+/**
+ *  e1000_remove_device - Free device specific structure
+ *  @hw: pointer to the HW structure
+ *
+ *  If a device specific structure was allocated, this function will
+ *  free it.
+ **/
+void igb_remove_device(struct e1000_hw *hw)
+{
+       /* Freeing the dev_spec member of e1000_hw structure */
+       kfree(hw->dev_spec);
+}
+
+static void igb_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+       struct igb_adapter *adapter = hw->back;
+
+       pci_read_config_word(adapter->pdev, reg, value);
+}
+
+static s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
+{
+       struct igb_adapter *adapter = hw->back;
+       u16 cap_offset;
+
+       cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
+       if (!cap_offset)
+               return -E1000_ERR_CONFIG;
+
+       pci_read_config_word(adapter->pdev, cap_offset + reg, value);
+
+       return 0;
+}
+
+/**
+ *  e1000_get_bus_info_pcie - Get PCIe bus information
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines and stores the system bus information for a particular
+ *  network interface.  The following bus information is determined and stored:
+ *  bus speed, bus width, type (PCIe), and PCIe function.
+ **/
+s32 igb_get_bus_info_pcie(struct e1000_hw *hw)
+{
+       struct e1000_bus_info *bus = &hw->bus;
+       s32 ret_val;
+       u32 status;
+       u16 pcie_link_status, pci_header_type;
+
+       bus->type = e1000_bus_type_pci_express;
+       bus->speed = e1000_bus_speed_2500;
+
+       ret_val = igb_read_pcie_cap_reg(hw,
+                                         PCIE_LINK_STATUS,
+                                         &pcie_link_status);
+       if (ret_val)
+               bus->width = e1000_bus_width_unknown;
+       else
+               bus->width = (enum e1000_bus_width)((pcie_link_status &
+                                                    PCIE_LINK_WIDTH_MASK) >>
+                                                    PCIE_LINK_WIDTH_SHIFT);
+
+       igb_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);
+       if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) {
+               status = rd32(E1000_STATUS);
+               bus->func = (status & E1000_STATUS_FUNC_MASK)
+                           >> E1000_STATUS_FUNC_SHIFT;
+       } else {
+               bus->func = 0;
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_clear_vfta - Clear VLAN filter table
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the register array which contains the VLAN filter table by
+ *  setting all the values to 0.
+ **/
+void igb_clear_vfta(struct e1000_hw *hw)
+{
+       u32 offset;
+
+       for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+               array_wr32(E1000_VFTA, offset, 0);
+               wrfl();
+       }
+}
+
+/**
+ *  e1000_write_vfta - Write value to VLAN filter table
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset in VLAN filter table
+ *  @value: register value written to VLAN filter table
+ *
+ *  Writes value at the given offset in the register array which stores
+ *  the VLAN filter table.
+ **/
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
+{
+       array_wr32(E1000_VFTA, offset, value);
+       wrfl();
+}
+
+/**
+ *  e1000_init_rx_addrs - Initialize receive address's
+ *  @hw: pointer to the HW structure
+ *  @rar_count: receive address registers
+ *
+ *  Setups the receive address registers by setting the base receive address
+ *  register to the devices MAC address and clearing all the other receive
+ *  address registers to 0.
+ **/
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
+{
+       u32 i;
+
+       /* Setup the receive address */
+       hw_dbg(hw, "Programming MAC Address into RAR[0]\n");
+
+       hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
+
+       /* Zero out the other (rar_entry_count - 1) receive addresses */
+       hw_dbg(hw, "Clearing RAR[1-%u]\n", rar_count-1);
+       for (i = 1; i < rar_count; i++) {
+               array_wr32(E1000_RA, (i << 1), 0);
+               wrfl();
+               array_wr32(E1000_RA, ((i << 1) + 1), 0);
+               wrfl();
+       }
+}
+
+/**
+ *  e1000_check_alt_mac_addr - Check for alternate MAC addr
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks the nvm for an alternate MAC address.  An alternate MAC address
+ *  can be setup by pre-boot software and must be treated like a permanent
+ *  address and must override the actual permanent MAC address.  If an
+ *  alternate MAC address is fopund it is saved in the hw struct and
+ *  prgrammed into RAR0 and the cuntion returns success, otherwise the
+ *  fucntion returns an error.
+ **/
+s32 igb_check_alt_mac_addr(struct e1000_hw *hw)
+{
+       u32 i;
+       s32 ret_val = 0;
+       u16 offset, nvm_alt_mac_addr_offset, nvm_data;
+       u8 alt_mac_addr[ETH_ALEN];
+
+       ret_val = hw->nvm.ops.read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
+                                &nvm_alt_mac_addr_offset);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               goto out;
+       }
+
+       if (nvm_alt_mac_addr_offset == 0xFFFF) {
+               ret_val = -(E1000_NOT_IMPLEMENTED);
+               goto out;
+       }
+
+       if (hw->bus.func == E1000_FUNC_1)
+               nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16);
+
+       for (i = 0; i < ETH_ALEN; i += 2) {
+               offset = nvm_alt_mac_addr_offset + (i >> 1);
+               ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
+               if (ret_val) {
+                       hw_dbg(hw, "NVM Read Error\n");
+                       goto out;
+               }
+
+               alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
+               alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
+       }
+
+       /* if multicast bit is set, the alternate address will not be used */
+       if (alt_mac_addr[0] & 0x01) {
+               ret_val = -(E1000_NOT_IMPLEMENTED);
+               goto out;
+       }
+
+       for (i = 0; i < ETH_ALEN; i++)
+               hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];
+
+       hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_rar_set - Set receive address register
+ *  @hw: pointer to the HW structure
+ *  @addr: pointer to the receive address
+ *  @index: receive address array register
+ *
+ *  Sets the receive address array register at index to the address passed
+ *  in by addr.
+ **/
+void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
+{
+       u32 rar_low, rar_high;
+
+       /*
+        * HW expects these in little endian so we reverse the byte order
+        * from network order (big endian) to little endian
+        */
+       rar_low = ((u32) addr[0] |
+                  ((u32) addr[1] << 8) |
+                   ((u32) addr[2] << 16) | ((u32) addr[3] << 24));
+
+       rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));
+
+       if (!hw->mac.disable_av)
+               rar_high |= E1000_RAH_AV;
+
+       array_wr32(E1000_RA, (index << 1), rar_low);
+       array_wr32(E1000_RA, ((index << 1) + 1), rar_high);
+}
+
+/**
+ *  e1000_mta_set - Set multicast filter table address
+ *  @hw: pointer to the HW structure
+ *  @hash_value: determines the MTA register and bit to set
+ *
+ *  The multicast table address is a register array of 32-bit registers.
+ *  The hash_value is used to determine what register the bit is in, the
+ *  current value is read, the new bit is OR'd in and the new value is
+ *  written back into the register.
+ **/
+static void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
+{
+       u32 hash_bit, hash_reg, mta;
+
+       /*
+        * The MTA is a register array of 32-bit registers. It is
+        * treated like an array of (32*mta_reg_count) bits.  We want to
+        * set bit BitArray[hash_value]. So we figure out what register
+        * the bit is in, read it, OR in the new bit, then write
+        * back the new value.  The (hw->mac.mta_reg_count - 1) serves as a
+        * mask to bits 31:5 of the hash value which gives us the
+        * register we're modifying.  The hash bit within that register
+        * is determined by the lower 5 bits of the hash value.
+        */
+       hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+       hash_bit = hash_value & 0x1F;
+
+       mta = array_rd32(E1000_MTA, hash_reg);
+
+       mta |= (1 << hash_bit);
+
+       array_wr32(E1000_MTA, hash_reg, mta);
+       wrfl();
+}
+
+/**
+ *  e1000_update_mc_addr_list - Update Multicast addresses
+ *  @hw: pointer to the HW structure
+ *  @mc_addr_list: array of multicast addresses to program
+ *  @mc_addr_count: number of multicast addresses to program
+ *  @rar_used_count: the first RAR register free to program
+ *  @rar_count: total number of supported Receive Address Registers
+ *
+ *  Updates the Receive Address Registers and Multicast Table Array.
+ *  The caller must have a packed mc_addr_list of multicast addresses.
+ *  The parameter rar_count will usually be hw->mac.rar_entry_count
+ *  unless there are workarounds that change this.
+ **/
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+                              u8 *mc_addr_list, u32 mc_addr_count,
+                              u32 rar_used_count, u32 rar_count)
+{
+       u32 hash_value;
+       u32 i;
+
+       /*
+        * Load the first set of multicast addresses into the exact
+        * filters (RAR).  If there are not enough to fill the RAR
+        * array, clear the filters.
+        */
+       for (i = rar_used_count; i < rar_count; i++) {
+               if (mc_addr_count) {
+                       hw->mac.ops.rar_set(hw, mc_addr_list, i);
+                       mc_addr_count--;
+                       mc_addr_list += ETH_ALEN;
+               } else {
+                       array_wr32(E1000_RA, i << 1, 0);
+                       wrfl();
+                       array_wr32(E1000_RA, (i << 1) + 1, 0);
+                       wrfl();
+               }
+       }
+
+       /* Clear the old settings from the MTA */
+       hw_dbg(hw, "Clearing MTA\n");
+       for (i = 0; i < hw->mac.mta_reg_count; i++) {
+               array_wr32(E1000_MTA, i, 0);
+               wrfl();
+       }
+
+       /* Load any remaining multicast addresses into the hash table. */
+       for (; mc_addr_count > 0; mc_addr_count--) {
+               hash_value = igb_hash_mc_addr(hw, mc_addr_list);
+               hw_dbg(hw, "Hash value = 0x%03X\n", hash_value);
+               igb_mta_set(hw, hash_value);
+               mc_addr_list += ETH_ALEN;
+       }
+}
+
+/**
+ *  e1000_hash_mc_addr - Generate a multicast hash value
+ *  @hw: pointer to the HW structure
+ *  @mc_addr: pointer to a multicast address
+ *
+ *  Generates a multicast address hash value which is used to determine
+ *  the multicast filter table array address and new table value.  See
+ *  igb_mta_set()
+ **/
+static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
+{
+       u32 hash_value, hash_mask;
+       u8 bit_shift = 0;
+
+       /* Register count multiplied by bits per register */
+       hash_mask = (hw->mac.mta_reg_count * 32) - 1;
+
+       /*
+        * For a mc_filter_type of 0, bit_shift is the number of left-shifts
+        * where 0xFF would still fall within the hash mask.
+        */
+       while (hash_mask >> bit_shift != 0xFF)
+               bit_shift++;
+
+       /*
+        * The portion of the address that is used for the hash table
+        * is determined by the mc_filter_type setting.
+        * The algorithm is such that there is a total of 8 bits of shifting.
+        * The bit_shift for a mc_filter_type of 0 represents the number of
+        * left-shifts where the MSB of mc_addr[5] would still fall within
+        * the hash_mask.  Case 0 does this exactly.  Since there are a total
+        * of 8 bits of shifting, then mc_addr[4] will shift right the
+        * remaining number of bits. Thus 8 - bit_shift.  The rest of the
+        * cases are a variation of this algorithm...essentially raising the
+        * number of bits to shift mc_addr[5] left, while still keeping the
+        * 8-bit shifting total.
+        *
+        * For example, given the following Destination MAC Address and an
+        * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
+        * we can see that the bit_shift for case 0 is 4.  These are the hash
+        * values resulting from each mc_filter_type...
+        * [0] [1] [2] [3] [4] [5]
+        * 01  AA  00  12  34  56
+        * LSB                 MSB
+        *
+        * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
+        * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
+        * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
+        * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
+        */
+       switch (hw->mac.mc_filter_type) {
+       default:
+       case 0:
+               break;
+       case 1:
+               bit_shift += 1;
+               break;
+       case 2:
+               bit_shift += 2;
+               break;
+       case 3:
+               bit_shift += 4;
+               break;
+       }
+
+       hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
+                                 (((u16) mc_addr[5]) << bit_shift)));
+
+       return hash_value;
+}
+
+/**
+ *  e1000_clear_hw_cntrs_base - Clear base hardware counters
+ *  @hw: pointer to the HW structure
+ *
+ *  Clears the base hardware counters by reading the counter registers.
+ **/
+void igb_clear_hw_cntrs_base(struct e1000_hw *hw)
+{
+       u32 temp;
+
+       temp = rd32(E1000_CRCERRS);
+       temp = rd32(E1000_SYMERRS);
+       temp = rd32(E1000_MPC);
+       temp = rd32(E1000_SCC);
+       temp = rd32(E1000_ECOL);
+       temp = rd32(E1000_MCC);
+       temp = rd32(E1000_LATECOL);
+       temp = rd32(E1000_COLC);
+       temp = rd32(E1000_DC);
+       temp = rd32(E1000_SEC);
+       temp = rd32(E1000_RLEC);
+       temp = rd32(E1000_XONRXC);
+       temp = rd32(E1000_XONTXC);
+       temp = rd32(E1000_XOFFRXC);
+       temp = rd32(E1000_XOFFTXC);
+       temp = rd32(E1000_FCRUC);
+       temp = rd32(E1000_GPRC);
+       temp = rd32(E1000_BPRC);
+       temp = rd32(E1000_MPRC);
+       temp = rd32(E1000_GPTC);
+       temp = rd32(E1000_GORCL);
+       temp = rd32(E1000_GORCH);
+       temp = rd32(E1000_GOTCL);
+       temp = rd32(E1000_GOTCH);
+       temp = rd32(E1000_RNBC);
+       temp = rd32(E1000_RUC);
+       temp = rd32(E1000_RFC);
+       temp = rd32(E1000_ROC);
+       temp = rd32(E1000_RJC);
+       temp = rd32(E1000_TORL);
+       temp = rd32(E1000_TORH);
+       temp = rd32(E1000_TOTL);
+       temp = rd32(E1000_TOTH);
+       temp = rd32(E1000_TPR);
+       temp = rd32(E1000_TPT);
+       temp = rd32(E1000_MPTC);
+       temp = rd32(E1000_BPTC);
+}
+
+/**
+ *  e1000_check_for_copper_link - Check for link (Copper)
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks to see of the link status of the hardware has changed.  If a
+ *  change in link status has been detected, then we read the PHY registers
+ *  to get the current speed/duplex if link exists.
+ **/
+s32 igb_check_for_copper_link(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val;
+       bool link;
+
+       /*
+        * We only want to go out to the PHY registers to see if Auto-Neg
+        * has completed and/or if our link status has changed.  The
+        * get_link_status flag is set upon receiving a Link Status
+        * Change or Rx Sequence Error interrupt.
+        */
+       if (!mac->get_link_status) {
+               ret_val = 0;
+               goto out;
+       }
+
+       /*
+        * First we want to see if the MII Status Register reports
+        * link.  If so, then we want to get the current speed/duplex
+        * of the PHY.
+        */
+       ret_val = igb_phy_has_link(hw, 1, 0, &link);
+       if (ret_val)
+               goto out;
+
+       if (!link)
+               goto out; /* No link detected */
+
+       mac->get_link_status = false;
+
+       /*
+        * Check if there was DownShift, must be checked
+        * immediately after link-up
+        */
+       igb_check_downshift(hw);
+
+       /*
+        * If we are forcing speed/duplex, then we simply return since
+        * we have already determined whether we have link or not.
+        */
+       if (!mac->autoneg) {
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       /*
+        * Auto-Neg is enabled.  Auto Speed Detection takes care
+        * of MAC speed/duplex configuration.  So we only need to
+        * configure Collision Distance in the MAC.
+        */
+       igb_config_collision_dist(hw);
+
+       /*
+        * Configure Flow Control now that Auto-Neg has completed.
+        * First, we need to restore the desired flow control
+        * settings because we may have had to re-autoneg with a
+        * different link partner.
+        */
+       ret_val = igb_config_fc_after_link_up(hw);
+       if (ret_val)
+               hw_dbg(hw, "Error configuring flow control\n");
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_setup_link - Setup flow control and link settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Determines which flow control settings to use, then configures flow
+ *  control.  Calls the appropriate media-specific link configuration
+ *  function.  Assuming the adapter has a valid link partner, a valid link
+ *  should be established.  Assumes the hardware has previously been reset
+ *  and the transmitter and receiver are not enabled.
+ **/
+s32 igb_setup_link(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+
+       /*
+        * In the case of the phy reset being blocked, we already have a link.
+        * We do not need to set it up again.
+        */
+       if (igb_check_reset_block(hw))
+               goto out;
+
+       ret_val = igb_set_default_fc(hw);
+       if (ret_val)
+               goto out;
+
+       /*
+        * 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.
+        */
+       hw->fc.original_type = hw->fc.type;
+
+       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
+
+       /* Call the necessary media_type subroutine to configure the link. */
+       ret_val = hw->mac.ops.setup_physical_interface(hw);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Initialize the flow control address, type, and PAUSE timer
+        * registers to their default values.  This is done even if flow
+        * control is disabled, because it does not hurt anything to
+        * initialize these registers.
+        */
+       hw_dbg(hw,
+              "Initializing the Flow Control address, type and timer regs\n");
+       wr32(E1000_FCT, FLOW_CONTROL_TYPE);
+       wr32(E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+       wr32(E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
+
+       wr32(E1000_FCTTV, hw->fc.pause_time);
+
+       ret_val = igb_set_fc_watermarks(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_config_collision_dist - Configure collision distance
+ *  @hw: pointer to the HW structure
+ *
+ *  Configures the collision distance to the default value and is used
+ *  during link setup. Currently no func pointer exists and all
+ *  implementations are handled in the generic version of this function.
+ **/
+void igb_config_collision_dist(struct e1000_hw *hw)
+{
+       u32 tctl;
+
+       tctl = rd32(E1000_TCTL);
+
+       tctl &= ~E1000_TCTL_COLD;
+       tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+
+       wr32(E1000_TCTL, tctl);
+       wrfl();
+}
+
+/**
+ *  e1000_set_fc_watermarks - Set flow control high/low watermarks
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets the flow control high/low threshold (watermark) registers.  If
+ *  flow control XON frame transmission is enabled, then set XON frame
+ *  tansmission as well.
+ **/
+static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u32 fcrtl = 0, fcrth = 0;
+
+       /*
+        * Set the flow control receive threshold registers.  Normally,
+        * these registers will be set to a default threshold that may be
+        * adjusted later by the driver's runtime code.  However, if the
+        * ability to transmit pause frames is not enabled, then these
+        * registers will be set to 0.
+        */
+       if (hw->fc.type & e1000_fc_tx_pause) {
+               /*
+                * We need to set up the Receive Threshold high and low water
+                * marks as well as (optionally) enabling the transmission of
+                * XON frames.
+                */
+               fcrtl = hw->fc.low_water;
+               if (hw->fc.send_xon)
+                       fcrtl |= E1000_FCRTL_XONE;
+
+               fcrth = hw->fc.high_water;
+       }
+       wr32(E1000_FCRTL, fcrtl);
+       wr32(E1000_FCRTH, fcrth);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_set_default_fc - Set flow control default values
+ *  @hw: pointer to the HW structure
+ *
+ *  Read the EEPROM for the default values for flow control and store the
+ *  values.
+ **/
+static s32 igb_set_default_fc(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 nvm_data;
+
+       /*
+        * Read and store word 0x0F of the EEPROM. This word contains bits
+        * that determine the hardware's default PAUSE (flow control) mode,
+        * a bit that determines whether the HW defaults to enabling or
+        * disabling auto-negotiation, and the direction of the
+        * SW defined pins. If there is no SW over-ride of the flow
+        * control setting, then the variable hw->fc will
+        * be initialized based on a value in the EEPROM.
+        */
+       ret_val = hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL2_REG, 1,
+                                      &nvm_data);
+
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               goto out;
+       }
+
+       if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
+               hw->fc.type = e1000_fc_none;
+       else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
+                NVM_WORD0F_ASM_DIR)
+               hw->fc.type = e1000_fc_tx_pause;
+       else
+               hw->fc.type = e1000_fc_full;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_force_mac_fc - Force the MAC's flow control settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
+ *  device control register to reflect the adapter settings.  TFCE and RFCE
+ *  need to be explicitly set by software when a copper PHY is used because
+ *  autonegotiation is managed by the PHY rather than the MAC.  Software must
+ *  also configure these bits when link is forced on a fiber connection.
+ **/
+s32 igb_force_mac_fc(struct e1000_hw *hw)
+{
+       u32 ctrl;
+       s32 ret_val = 0;
+
+       ctrl = rd32(E1000_CTRL);
+
+       /*
+        * Because we didn't get link via the internal auto-negotiation
+        * mechanism (we either forced link or we got link via PHY
+        * auto-neg), we have to manually enable/disable transmit an
+        * receive flow control.
+        *
+        * The "Case" statement below enables/disable flow control
+        * according to the "hw->fc.type" parameter.
+        *
+        * The possible values of the "fc" parameter 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
+        *          frames but we do not receive pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) is enabled.
+        *  other:  No other values should be possible at this point.
+        */
+       hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
+
+       switch (hw->fc.type) {
+       case e1000_fc_none:
+               ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+               break;
+       case e1000_fc_rx_pause:
+               ctrl &= (~E1000_CTRL_TFCE);
+               ctrl |= E1000_CTRL_RFCE;
+               break;
+       case e1000_fc_tx_pause:
+               ctrl &= (~E1000_CTRL_RFCE);
+               ctrl |= E1000_CTRL_TFCE;
+               break;
+       case e1000_fc_full:
+               ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+               break;
+       default:
+               hw_dbg(hw, "Flow control param set incorrectly\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       wr32(E1000_CTRL, ctrl);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_config_fc_after_link_up - Configures flow control after link
+ *  @hw: pointer to the HW structure
+ *
+ *  Checks the status of auto-negotiation after link up to ensure that the
+ *  speed and duplex were not forced.  If the link needed to be forced, then
+ *  flow control needs to be forced also.  If auto-negotiation is enabled
+ *  and did not fail, then we configure flow control based on our link
+ *  partner.
+ **/
+s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val = 0;
+       u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
+       u16 speed, duplex;
+
+       /*
+        * Check for the case where we have fiber media and auto-neg failed
+        * so we had to force link.  In this case, we need to force the
+        * configuration of the MAC to match the "fc" parameter.
+        */
+       if (mac->autoneg_failed) {
+               if (hw->phy.media_type == e1000_media_type_fiber ||
+                   hw->phy.media_type == e1000_media_type_internal_serdes)
+                       ret_val = igb_force_mac_fc(hw);
+       } else {
+               if (hw->phy.media_type == e1000_media_type_copper)
+                       ret_val = igb_force_mac_fc(hw);
+       }
+
+       if (ret_val) {
+               hw_dbg(hw, "Error forcing flow control settings\n");
+               goto out;
+       }
+
+       /*
+        * Check for the case where we have copper media and auto-neg is
+        * enabled.  In this case, we need to check and see if Auto-Neg
+        * has completed, and if so, how the PHY and link partner has
+        * flow control configured.
+        */
+       if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
+               /*
+                * Read the MII Status Register and check to see if AutoNeg
+                * has completed.  We read this twice because this reg has
+                * some "sticky" (latched) bits.
+                */
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+                                                  &mii_status_reg);
+               if (ret_val)
+                       goto out;
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS,
+                                                  &mii_status_reg);
+               if (ret_val)
+                       goto out;
+
+               if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
+                       hw_dbg(hw, "Copper PHY and Auto Neg "
+                                "has not completed.\n");
+                       goto out;
+               }
+
+               /*
+                * The AutoNeg process has completed, so we now need to
+                * read both the Auto Negotiation Advertisement
+                * Register (Address 4) and the Auto_Negotiation Base
+                * Page Ability Register (Address 5) to determine how
+                * flow control was negotiated.
+                */
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                           &mii_nway_adv_reg);
+               if (ret_val)
+                       goto out;
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_LP_ABILITY,
+                                           &mii_nway_lp_ability_reg);
+               if (ret_val)
+                       goto out;
+
+               /*
+                * Two bits in the Auto Negotiation Advertisement Register
+                * (Address 4) and two bits in the Auto Negotiation Base
+                * Page Ability Register (Address 5) determine flow control
+                * for both the PHY and the link partner.  The following
+                * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
+                * 1999, describes these PAUSE resolution bits and how flow
+                * control is determined based upon these settings.
+                * NOTE:  DC = Don't Care
+                *
+                *   LOCAL DEVICE  |   LINK PARTNER
+                * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+                *-------|---------|-------|---------|--------------------
+                *   0   |    0    |  DC   |   DC    | e1000_fc_none
+                *   0   |    1    |   0   |   DC    | e1000_fc_none
+                *   0   |    1    |   1   |    0    | e1000_fc_none
+                *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                *   1   |    0    |   0   |   DC    | e1000_fc_none
+                *   1   |   DC    |   1   |   DC    | e1000_fc_full
+                *   1   |    1    |   0   |    0    | e1000_fc_none
+                *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                *
+                * Are both PAUSE bits set to 1?  If so, this implies
+                * Symmetric Flow Control is enabled at both ends.  The
+                * ASM_DIR bits are irrelevant per the spec.
+                *
+                * For Symmetric Flow Control:
+                *
+                *   LOCAL DEVICE  |   LINK PARTNER
+                * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                *-------|---------|-------|---------|--------------------
+                *   1   |   DC    |   1   |   DC    | E1000_fc_full
+                *
+                */
+               if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                   (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+                       /*
+                        * Now we need to check if the user selected RX ONLY
+                        * of pause frames.  In this case, we had to advertise
+                        * FULL flow control because we could not advertise RX
+                        * ONLY. Hence, we must now check to see if we need to
+                        * turn OFF  the TRANSMISSION of PAUSE frames.
+                        */
+                       if (hw->fc.original_type == e1000_fc_full) {
+                               hw->fc.type = e1000_fc_full;
+                               hw_dbg(hw, "Flow Control = FULL.\r\n");
+                       } else {
+                               hw->fc.type = e1000_fc_rx_pause;
+                               hw_dbg(hw, "Flow Control = "
+                                        "RX PAUSE frames only.\r\n");
+                       }
+               }
+               /*
+                * For receiving PAUSE frames ONLY.
+                *
+                *   LOCAL DEVICE  |   LINK PARTNER
+                * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                *-------|---------|-------|---------|--------------------
+                *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                */
+               else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                         (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                         (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                         (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+                       hw->fc.type = e1000_fc_tx_pause;
+                       hw_dbg(hw, "Flow Control = TX PAUSE frames only.\r\n");
+               }
+               /*
+                * For transmitting PAUSE frames ONLY.
+                *
+                *   LOCAL DEVICE  |   LINK PARTNER
+                * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                *-------|---------|-------|---------|--------------------
+                *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                */
+               else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                        (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                        !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                        (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+                       hw->fc.type = e1000_fc_rx_pause;
+                       hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
+               }
+               /*
+                * Per the IEEE spec, at this point flow control should be
+                * disabled.  However, we want to consider that we could
+                * be connected to a legacy switch that doesn't advertise
+                * desired flow control, but can be forced on the link
+                * partner.  So if we advertised no flow control, that is
+                * what we will resolve to.  If we advertised some kind of
+                * receive capability (Rx Pause Only or Full Flow Control)
+                * and the link partner advertised none, we will configure
+                * ourselves to enable Rx Flow Control only.  We can do
+                * this safely for two reasons:  If the link partner really
+                * didn't want flow control enabled, and we enable Rx, no
+                * harm done since we won't be receiving any PAUSE frames
+                * anyway.  If the intent on the link partner was to have
+                * flow control enabled, then by us enabling RX only, we
+                * can at least receive pause frames and process them.
+                * This is a good idea because in most cases, since we are
+                * predominantly a server NIC, more times than not we will
+                * be asked to delay transmission of packets than asking
+                * our link partner to pause transmission of frames.
+                */
+               else if ((hw->fc.original_type == e1000_fc_none ||
+                         hw->fc.original_type == e1000_fc_tx_pause) ||
+                        hw->fc.strict_ieee) {
+                       hw->fc.type = e1000_fc_none;
+                       hw_dbg(hw, "Flow Control = NONE.\r\n");
+               } else {
+                       hw->fc.type = e1000_fc_rx_pause;
+                       hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
+               }
+
+               /*
+                * Now we need to do one last check...  If we auto-
+                * negotiated to HALF DUPLEX, flow control should not be
+                * enabled per IEEE 802.3 spec.
+                */
+               ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
+               if (ret_val) {
+                       hw_dbg(hw, "Error getting link speed and duplex\n");
+                       goto out;
+               }
+
+               if (duplex == HALF_DUPLEX)
+                       hw->fc.type = e1000_fc_none;
+
+               /*
+                * Now we call a subroutine to actually force the MAC
+                * controller to use the correct flow control settings.
+                */
+               ret_val = igb_force_mac_fc(hw);
+               if (ret_val) {
+                       hw_dbg(hw, "Error forcing flow control settings\n");
+                       goto out;
+               }
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_get_speed_and_duplex_copper - Retreive current speed/duplex
+ *  @hw: pointer to the HW structure
+ *  @speed: stores the current speed
+ *  @duplex: stores the current duplex
+ *
+ *  Read the status register for the current speed/duplex and store the current
+ *  speed and duplex for copper connections.
+ **/
+s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
+                                     u16 *duplex)
+{
+       u32 status;
+
+       status = rd32(E1000_STATUS);
+       if (status & E1000_STATUS_SPEED_1000) {
+               *speed = SPEED_1000;
+               hw_dbg(hw, "1000 Mbs, ");
+       } else if (status & E1000_STATUS_SPEED_100) {
+               *speed = SPEED_100;
+               hw_dbg(hw, "100 Mbs, ");
+       } else {
+               *speed = SPEED_10;
+               hw_dbg(hw, "10 Mbs, ");
+       }
+
+       if (status & E1000_STATUS_FD) {
+               *duplex = FULL_DUPLEX;
+               hw_dbg(hw, "Full Duplex\n");
+       } else {
+               *duplex = HALF_DUPLEX;
+               hw_dbg(hw, "Half Duplex\n");
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_get_hw_semaphore - Acquire hardware semaphore
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire the HW semaphore to access the PHY or NVM
+ **/
+s32 igb_get_hw_semaphore(struct e1000_hw *hw)
+{
+       u32 swsm;
+       s32 ret_val = 0;
+       s32 timeout = hw->nvm.word_size + 1;
+       s32 i = 0;
+
+       /* Get the SW semaphore */
+       while (i < timeout) {
+               swsm = rd32(E1000_SWSM);
+               if (!(swsm & E1000_SWSM_SMBI))
+                       break;
+
+               udelay(50);
+               i++;
+       }
+
+       if (i == timeout) {
+               hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+               ret_val = -E1000_ERR_NVM;
+               goto out;
+       }
+
+       /* Get the FW semaphore. */
+       for (i = 0; i < timeout; i++) {
+               swsm = rd32(E1000_SWSM);
+               wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
+
+               /* Semaphore acquired if bit latched */
+               if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
+                       break;
+
+               udelay(50);
+       }
+
+       if (i == timeout) {
+               /* Release semaphores */
+               igb_put_hw_semaphore(hw);
+               hw_dbg(hw, "Driver can't access the NVM\n");
+               ret_val = -E1000_ERR_NVM;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_put_hw_semaphore - Release hardware semaphore
+ *  @hw: pointer to the HW structure
+ *
+ *  Release hardware semaphore used to access the PHY or NVM
+ **/
+void igb_put_hw_semaphore(struct e1000_hw *hw)
+{
+       u32 swsm;
+
+       swsm = rd32(E1000_SWSM);
+
+       swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+
+       wr32(E1000_SWSM, swsm);
+}
+
+/**
+ *  e1000_get_auto_rd_done - Check for auto read completion
+ *  @hw: pointer to the HW structure
+ *
+ *  Check EEPROM for Auto Read done bit.
+ **/
+s32 igb_get_auto_rd_done(struct e1000_hw *hw)
+{
+       s32 i = 0;
+       s32 ret_val = 0;
+
+
+       while (i < AUTO_READ_DONE_TIMEOUT) {
+               if (rd32(E1000_EECD) & E1000_EECD_AUTO_RD)
+                       break;
+               msleep(1);
+               i++;
+       }
+
+       if (i == AUTO_READ_DONE_TIMEOUT) {
+               hw_dbg(hw, "Auto read by HW from NVM has not completed.\n");
+               ret_val = -E1000_ERR_RESET;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_valid_led_default - Verify a valid default LED config
+ *  @hw: pointer to the HW structure
+ *  @data: pointer to the NVM (EEPROM)
+ *
+ *  Read the EEPROM for the current default LED configuration.  If the
+ *  LED configuration is not valid, set to a valid LED configuration.
+ **/
+static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
+{
+       s32 ret_val;
+
+       ret_val = hw->nvm.ops.read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               goto out;
+       }
+
+       if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
+               *data = ID_LED_DEFAULT;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_id_led_init -
+ *  @hw: pointer to the HW structure
+ *
+ **/
+s32 igb_id_led_init(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val;
+       const u32 ledctl_mask = 0x000000FF;
+       const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
+       const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
+       u16 data, i, temp;
+       const u16 led_mask = 0x0F;
+
+       ret_val = igb_valid_led_default(hw, &data);
+       if (ret_val)
+               goto out;
+
+       mac->ledctl_default = rd32(E1000_LEDCTL);
+       mac->ledctl_mode1 = mac->ledctl_default;
+       mac->ledctl_mode2 = mac->ledctl_default;
+
+       for (i = 0; i < 4; i++) {
+               temp = (data >> (i << 2)) & led_mask;
+               switch (temp) {
+               case ID_LED_ON1_DEF2:
+               case ID_LED_ON1_ON2:
+               case ID_LED_ON1_OFF2:
+                       mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
+                       mac->ledctl_mode1 |= ledctl_on << (i << 3);
+                       break;
+               case ID_LED_OFF1_DEF2:
+               case ID_LED_OFF1_ON2:
+               case ID_LED_OFF1_OFF2:
+                       mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
+                       mac->ledctl_mode1 |= ledctl_off << (i << 3);
+                       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 &= ~(ledctl_mask << (i << 3));
+                       mac->ledctl_mode2 |= ledctl_on << (i << 3);
+                       break;
+               case ID_LED_DEF1_OFF2:
+               case ID_LED_ON1_OFF2:
+               case ID_LED_OFF1_OFF2:
+                       mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
+                       mac->ledctl_mode2 |= ledctl_off << (i << 3);
+                       break;
+               default:
+                       /* Do nothing */
+                       break;
+               }
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_cleanup_led - Set LED config to default operation
+ *  @hw: pointer to the HW structure
+ *
+ *  Remove the current LED configuration and set the LED configuration
+ *  to the default value, saved from the EEPROM.
+ **/
+s32 igb_cleanup_led(struct e1000_hw *hw)
+{
+       wr32(E1000_LEDCTL, hw->mac.ledctl_default);
+       return 0;
+}
+
+/**
+ *  e1000_blink_led - Blink LED
+ *  @hw: pointer to the HW structure
+ *
+ *  Blink the led's which are set to be on.
+ **/
+s32 igb_blink_led(struct e1000_hw *hw)
+{
+       u32 ledctl_blink = 0;
+       u32 i;
+
+       if (hw->phy.media_type == e1000_media_type_fiber) {
+               /* always blink LED0 for PCI-E fiber */
+               ledctl_blink = E1000_LEDCTL_LED0_BLINK |
+                    (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
+       } else {
+               /*
+                * set the blink bit for each LED that's "on" (0x0E)
+                * in ledctl_mode2
+                */
+               ledctl_blink = hw->mac.ledctl_mode2;
+               for (i = 0; i < 4; i++)
+                       if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
+                           E1000_LEDCTL_MODE_LED_ON)
+                               ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
+                                                (i * 8));
+       }
+
+       wr32(E1000_LEDCTL, ledctl_blink);
+
+       return 0;
+}
+
+/**
+ *  e1000_led_off - Turn LED off
+ *  @hw: pointer to the HW structure
+ *
+ *  Turn LED off.
+ **/
+s32 igb_led_off(struct e1000_hw *hw)
+{
+       u32 ctrl;
+
+       switch (hw->phy.media_type) {
+       case e1000_media_type_fiber:
+               ctrl = rd32(E1000_CTRL);
+               ctrl |= E1000_CTRL_SWDPIN0;
+               ctrl |= E1000_CTRL_SWDPIO0;
+               wr32(E1000_CTRL, ctrl);
+               break;
+       case e1000_media_type_copper:
+               wr32(E1000_LEDCTL, hw->mac.ledctl_mode1);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+/**
+ *  e1000_disable_pcie_master - Disables PCI-express master access
+ *  @hw: pointer to the HW structure
+ *
+ *  Returns 0 (0) if successful, else returns -10
+ *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued
+ *  the master requests to be disabled.
+ *
+ *  Disables PCI-Express master access and verifies there are no pending
+ *  requests.
+ **/
+s32 igb_disable_pcie_master(struct e1000_hw *hw)
+{
+       u32 ctrl;
+       s32 timeout = MASTER_DISABLE_TIMEOUT;
+       s32 ret_val = 0;
+
+       if (hw->bus.type != e1000_bus_type_pci_express)
+               goto out;
+
+       ctrl = rd32(E1000_CTRL);
+       ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
+       wr32(E1000_CTRL, ctrl);
+
+       while (timeout) {
+               if (!(rd32(E1000_STATUS) &
+                     E1000_STATUS_GIO_MASTER_ENABLE))
+                       break;
+               udelay(100);
+               timeout--;
+       }
+
+       if (!timeout) {
+               hw_dbg(hw, "Master requests are pending.\n");
+               ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_reset_adaptive - Reset Adaptive Interframe Spacing
+ *  @hw: pointer to the HW structure
+ *
+ *  Reset the Adaptive Interframe Spacing throttle to default values.
+ **/
+void igb_reset_adaptive(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+
+       if (!mac->adaptive_ifs) {
+               hw_dbg(hw, "Not in Adaptive IFS mode!\n");
+               goto out;
+       }
+
+       if (!mac->ifs_params_forced) {
+               mac->current_ifs_val = 0;
+               mac->ifs_min_val = IFS_MIN;
+               mac->ifs_max_val = IFS_MAX;
+               mac->ifs_step_size = IFS_STEP;
+               mac->ifs_ratio = IFS_RATIO;
+       }
+
+       mac->in_ifs_mode = false;
+       wr32(E1000_AIT, 0);
+out:
+       return;
+}
+
+/**
+ *  e1000_update_adaptive - Update Adaptive Interframe Spacing
+ *  @hw: pointer to the HW structure
+ *
+ *  Update the Adaptive Interframe Spacing Throttle value based on the
+ *  time between transmitted packets and time between collisions.
+ **/
+void igb_update_adaptive(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+
+       if (!mac->adaptive_ifs) {
+               hw_dbg(hw, "Not in Adaptive IFS mode!\n");
+               goto out;
+       }
+
+       if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
+               if (mac->tx_packet_delta > MIN_NUM_XMITS) {
+                       mac->in_ifs_mode = true;
+                       if (mac->current_ifs_val < mac->ifs_max_val) {
+                               if (!mac->current_ifs_val)
+                                       mac->current_ifs_val = mac->ifs_min_val;
+                               else
+                                       mac->current_ifs_val +=
+                                               mac->ifs_step_size;
+                               wr32(E1000_AIT,
+                                               mac->current_ifs_val);
+                       }
+               }
+       } else {
+               if (mac->in_ifs_mode &&
+                   (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
+                       mac->current_ifs_val = 0;
+                       mac->in_ifs_mode = false;
+                       wr32(E1000_AIT, 0);
+               }
+       }
+out:
+       return;
+}
+
+/**
+ *  e1000_validate_mdi_setting - Verify MDI/MDIx settings
+ *  @hw: pointer to the HW structure
+ *
+ *  Verify that when not using auto-negotitation that MDI/MDIx is correctly
+ *  set, which is forced to MDI mode only.
+ **/
+s32 igb_validate_mdi_setting(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+
+       if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) {
+               hw_dbg(hw, "Invalid MDI setting detected\n");
+               hw->phy.mdix = 1;
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_write_8bit_ctrl_reg - Write a 8bit CTRL register
+ *  @hw: pointer to the HW structure
+ *  @reg: 32bit register offset such as E1000_SCTL
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Writes an address/data control type register.  There are several of these
+ *  and they all have the format address << 8 | data and bit 31 is polled for
+ *  completion.
+ **/
+s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
+                             u32 offset, u8 data)
+{
+       u32 i, regvalue = 0;
+       s32 ret_val = 0;
+
+       /* Set up the address and data */
+       regvalue = ((u32)data) | (offset << E1000_GEN_CTL_ADDRESS_SHIFT);
+       wr32(reg, regvalue);
+
+       /* Poll the ready bit to see if the MDI read completed */
+       for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) {
+               udelay(5);
+               regvalue = rd32(reg);
+               if (regvalue & E1000_GEN_CTL_READY)
+                       break;
+       }
+       if (!(regvalue & E1000_GEN_CTL_READY)) {
+               hw_dbg(hw, "Reg %08x did not indicate ready\n", reg);
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_enable_mng_pass_thru - Enable processing of ARP's
+ *  @hw: pointer to the HW structure
+ *
+ *  Verifies the hardware needs to allow ARPs to be processed by the host.
+ **/
+bool igb_enable_mng_pass_thru(struct e1000_hw *hw)
+{
+       u32 manc;
+       u32 fwsm, factps;
+       bool ret_val = false;
+
+       if (!hw->mac.asf_firmware_present)
+               goto out;
+
+       manc = rd32(E1000_MANC);
+
+       if (!(manc & E1000_MANC_RCV_TCO_EN) ||
+           !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
+               goto out;
+
+       if (hw->mac.arc_subsystem_valid) {
+               fwsm = rd32(E1000_FWSM);
+               factps = rd32(E1000_FACTPS);
+
+               if (!(factps & E1000_FACTPS_MNGCG) &&
+                   ((fwsm & E1000_FWSM_MODE_MASK) ==
+                    (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
+                       ret_val = true;
+                       goto out;
+               }
+       } else {
+               if ((manc & E1000_MANC_SMBUS_EN) &&
+                   !(manc & E1000_MANC_ASF_EN)) {
+                       ret_val = true;
+                       goto out;
+               }
+       }
+
+out:
+       return ret_val;
+}
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
new file mode 100644 (file)
index 0000000..326b659
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_MAC_H_
+#define _E1000_MAC_H_
+
+#include "e1000_hw.h"
+
+#include "e1000_phy.h"
+#include "e1000_nvm.h"
+#include "e1000_defines.h"
+
+/*
+ * Functions that should not be called directly from drivers but can be used
+ * by other files in this 'shared code'
+ */
+s32  igb_blink_led(struct e1000_hw *hw);
+s32  igb_check_for_copper_link(struct e1000_hw *hw);
+s32  igb_cleanup_led(struct e1000_hw *hw);
+s32  igb_config_fc_after_link_up(struct e1000_hw *hw);
+s32  igb_disable_pcie_master(struct e1000_hw *hw);
+s32  igb_force_mac_fc(struct e1000_hw *hw);
+s32  igb_get_auto_rd_done(struct e1000_hw *hw);
+s32  igb_get_bus_info_pcie(struct e1000_hw *hw);
+s32  igb_get_hw_semaphore(struct e1000_hw *hw);
+s32  igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
+                                      u16 *duplex);
+s32  igb_id_led_init(struct e1000_hw *hw);
+s32  igb_led_off(struct e1000_hw *hw);
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+                              u8 *mc_addr_list, u32 mc_addr_count,
+                              u32 rar_used_count, u32 rar_count);
+s32  igb_setup_link(struct e1000_hw *hw);
+s32  igb_validate_mdi_setting(struct e1000_hw *hw);
+s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
+                              u32 offset, u8 data);
+
+void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
+void igb_clear_vfta(struct e1000_hw *hw);
+void igb_config_collision_dist(struct e1000_hw *hw);
+void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
+void igb_put_hw_semaphore(struct e1000_hw *hw);
+void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
+s32  igb_check_alt_mac_addr(struct e1000_hw *hw);
+void igb_remove_device(struct e1000_hw *hw);
+void igb_reset_adaptive(struct e1000_hw *hw);
+void igb_update_adaptive(struct e1000_hw *hw);
+void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
+
+bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
+
+enum e1000_mng_mode {
+       e1000_mng_mode_none = 0,
+       e1000_mng_mode_asf,
+       e1000_mng_mode_pt,
+       e1000_mng_mode_ipmi,
+       e1000_mng_mode_host_if_only
+};
+
+#define E1000_FACTPS_MNGCG    0x20000000
+
+#define E1000_FWSM_MODE_MASK  0xE
+#define E1000_FWSM_MODE_SHIFT 1
+
+#define E1000_MNG_DHCP_COMMAND_TIMEOUT       10
+#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN    0x2
+
+#define E1000_HICR_EN              0x01  /* Enable bit - RO */
+/* Driver sets this bit when done to put command in RAM */
+#define E1000_HICR_C               0x02
+
+extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
+
+#endif
diff --git a/drivers/net/igb/e1000_nvm.c b/drivers/net/igb/e1000_nvm.c
new file mode 100644 (file)
index 0000000..2897106
--- /dev/null
@@ -0,0 +1,605 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 <linux/if_ether.h>
+#include <linux/delay.h>
+
+#include "e1000_mac.h"
+#include "e1000_nvm.h"
+
+/**
+ *  e1000_raise_eec_clk - Raise EEPROM clock
+ *  @hw: pointer to the HW structure
+ *  @eecd: pointer to the EEPROM
+ *
+ *  Enable/Raise the EEPROM clock bit.
+ **/
+static void igb_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
+{
+       *eecd = *eecd | E1000_EECD_SK;
+       wr32(E1000_EECD, *eecd);
+       wrfl();
+       udelay(hw->nvm.delay_usec);
+}
+
+/**
+ *  e1000_lower_eec_clk - Lower EEPROM clock
+ *  @hw: pointer to the HW structure
+ *  @eecd: pointer to the EEPROM
+ *
+ *  Clear/Lower the EEPROM clock bit.
+ **/
+static void igb_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
+{
+       *eecd = *eecd & ~E1000_EECD_SK;
+       wr32(E1000_EECD, *eecd);
+       wrfl();
+       udelay(hw->nvm.delay_usec);
+}
+
+/**
+ *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
+ *  @hw: pointer to the HW structure
+ *  @data: data to send to the EEPROM
+ *  @count: number of bits to shift out
+ *
+ *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
+ *  "data" parameter will be shifted out to the EEPROM one bit at a time.
+ *  In order to do this, "data" must be broken down into bits.
+ **/
+static void igb_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
+{
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       u32 eecd = rd32(E1000_EECD);
+       u32 mask;
+
+       mask = 0x01 << (count - 1);
+       if (nvm->type == e1000_nvm_eeprom_microwire)
+               eecd &= ~E1000_EECD_DO;
+       else if (nvm->type == e1000_nvm_eeprom_spi)
+               eecd |= E1000_EECD_DO;
+
+       do {
+               eecd &= ~E1000_EECD_DI;
+
+               if (data & mask)
+                       eecd |= E1000_EECD_DI;
+
+               wr32(E1000_EECD, eecd);
+               wrfl();
+
+               udelay(nvm->delay_usec);
+
+               igb_raise_eec_clk(hw, &eecd);
+               igb_lower_eec_clk(hw, &eecd);
+
+               mask >>= 1;
+       } while (mask);
+
+       eecd &= ~E1000_EECD_DI;
+       wr32(E1000_EECD, eecd);
+}
+
+/**
+ *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
+ *  @hw: pointer to the HW structure
+ *  @count: number of bits to shift in
+ *
+ *  In order to read a register from the EEPROM, we need to shift 'count' bits
+ *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
+ *  the EEPROM (setting the SK bit), and then reading the value of the data out
+ *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
+ *  always be clear.
+ **/
+static u16 igb_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
+{
+       u32 eecd;
+       u32 i;
+       u16 data;
+
+       eecd = rd32(E1000_EECD);
+
+       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+       data = 0;
+
+       for (i = 0; i < count; i++) {
+               data <<= 1;
+               igb_raise_eec_clk(hw, &eecd);
+
+               eecd = rd32(E1000_EECD);
+
+               eecd &= ~E1000_EECD_DI;
+               if (eecd & E1000_EECD_DO)
+                       data |= 1;
+
+               igb_lower_eec_clk(hw, &eecd);
+       }
+
+       return data;
+}
+
+/**
+ *  e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
+ *  @hw: pointer to the HW structure
+ *  @ee_reg: EEPROM flag for polling
+ *
+ *  Polls the EEPROM status bit for either read or write completion based
+ *  upon the value of 'ee_reg'.
+ **/
+static s32 igb_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
+{
+       u32 attempts = 100000;
+       u32 i, reg = 0;
+       s32 ret_val = -E1000_ERR_NVM;
+
+       for (i = 0; i < attempts; i++) {
+               if (ee_reg == E1000_NVM_POLL_READ)
+                       reg = rd32(E1000_EERD);
+               else
+                       reg = rd32(E1000_EEWR);
+
+               if (reg & E1000_NVM_RW_REG_DONE) {
+                       ret_val = 0;
+                       break;
+               }
+
+               udelay(5);
+       }
+
+       return ret_val;
+}
+
+/**
+ *  e1000_acquire_nvm - Generic request for access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
+ *  Return successful if access grant bit set, else clear the request for
+ *  EEPROM access and return -E1000_ERR_NVM (-1).
+ **/
+s32 igb_acquire_nvm(struct e1000_hw *hw)
+{
+       u32 eecd = rd32(E1000_EECD);
+       s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
+       s32 ret_val = 0;
+
+
+       wr32(E1000_EECD, eecd | E1000_EECD_REQ);
+       eecd = rd32(E1000_EECD);
+
+       while (timeout) {
+               if (eecd & E1000_EECD_GNT)
+                       break;
+               udelay(5);
+               eecd = rd32(E1000_EECD);
+               timeout--;
+       }
+
+       if (!timeout) {
+               eecd &= ~E1000_EECD_REQ;
+               wr32(E1000_EECD, eecd);
+               hw_dbg(hw, "Could not acquire NVM grant\n");
+               ret_val = -E1000_ERR_NVM;
+       }
+
+       return ret_val;
+}
+
+/**
+ *  e1000_standby_nvm - Return EEPROM to standby state
+ *  @hw: pointer to the HW structure
+ *
+ *  Return the EEPROM to a standby state.
+ **/
+static void igb_standby_nvm(struct e1000_hw *hw)
+{
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       u32 eecd = rd32(E1000_EECD);
+
+       if (nvm->type == e1000_nvm_eeprom_microwire) {
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+               wr32(E1000_EECD, eecd);
+               wrfl();
+               udelay(nvm->delay_usec);
+
+               igb_raise_eec_clk(hw, &eecd);
+
+               /* Select EEPROM */
+               eecd |= E1000_EECD_CS;
+               wr32(E1000_EECD, eecd);
+               wrfl();
+               udelay(nvm->delay_usec);
+
+               igb_lower_eec_clk(hw, &eecd);
+       } else if (nvm->type == e1000_nvm_eeprom_spi) {
+               /* Toggle CS to flush commands */
+               eecd |= E1000_EECD_CS;
+               wr32(E1000_EECD, eecd);
+               wrfl();
+               udelay(nvm->delay_usec);
+               eecd &= ~E1000_EECD_CS;
+               wr32(E1000_EECD, eecd);
+               wrfl();
+               udelay(nvm->delay_usec);
+       }
+}
+
+/**
+ *  e1000_stop_nvm - Terminate EEPROM command
+ *  @hw: pointer to the HW structure
+ *
+ *  Terminates the current command by inverting the EEPROM's chip select pin.
+ **/
+static void e1000_stop_nvm(struct e1000_hw *hw)
+{
+       u32 eecd;
+
+       eecd = rd32(E1000_EECD);
+       if (hw->nvm.type == e1000_nvm_eeprom_spi) {
+               /* Pull CS high */
+               eecd |= E1000_EECD_CS;
+               igb_lower_eec_clk(hw, &eecd);
+       } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
+               /* CS on Microcwire is active-high */
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+               wr32(E1000_EECD, eecd);
+               igb_raise_eec_clk(hw, &eecd);
+               igb_lower_eec_clk(hw, &eecd);
+       }
+}
+
+/**
+ *  e1000_release_nvm - Release exclusive access to EEPROM
+ *  @hw: pointer to the HW structure
+ *
+ *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
+ **/
+void igb_release_nvm(struct e1000_hw *hw)
+{
+       u32 eecd;
+
+       e1000_stop_nvm(hw);
+
+       eecd = rd32(E1000_EECD);
+       eecd &= ~E1000_EECD_REQ;
+       wr32(E1000_EECD, eecd);
+}
+
+/**
+ *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
+ *  @hw: pointer to the HW structure
+ *
+ *  Setups the EEPROM for reading and writing.
+ **/
+static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw)
+{
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       u32 eecd = rd32(E1000_EECD);
+       s32 ret_val = 0;
+       u16 timeout = 0;
+       u8 spi_stat_reg;
+
+
+       if (nvm->type == e1000_nvm_eeprom_microwire) {
+               /* Clear SK and DI */
+               eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
+               wr32(E1000_EECD, eecd);
+               /* Set CS */
+               eecd |= E1000_EECD_CS;
+               wr32(E1000_EECD, eecd);
+       } else if (nvm->type == e1000_nvm_eeprom_spi) {
+               /* Clear SK and CS */
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+               wr32(E1000_EECD, eecd);
+               udelay(1);
+               timeout = NVM_MAX_RETRY_SPI;
+
+               /*
+                * Read "Status Register" repeatedly until the LSB is cleared.
+                * The EEPROM will signal that the command has been completed
+                * by clearing bit 0 of the internal status register.  If it's
+                * not cleared within 'timeout', then error out.
+                */
+               while (timeout) {
+                       igb_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
+                                                hw->nvm.opcode_bits);
+                       spi_stat_reg = (u8)igb_shift_in_eec_bits(hw, 8);
+                       if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
+                               break;
+
+                       udelay(5);
+                       igb_standby_nvm(hw);
+                       timeout--;
+               }
+
+               if (!timeout) {
+                       hw_dbg(hw, "SPI NVM Status error\n");
+                       ret_val = -E1000_ERR_NVM;
+                       goto out;
+               }
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_read_nvm_eerd - Reads EEPROM using EERD register
+ *  @hw: pointer to the HW structure
+ *  @offset: offset of word in the EEPROM to read
+ *  @words: number of words to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM using the EERD register.
+ **/
+s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       u32 i, eerd = 0;
+       s32 ret_val = 0;
+
+       /*
+        * A check for invalid values:  offset too large, too many words,
+        * and not enough words.
+        */
+       if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+           (words == 0)) {
+               hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+               ret_val = -E1000_ERR_NVM;
+               goto out;
+       }
+
+       for (i = 0; i < words; i++) {
+               eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
+                      E1000_NVM_RW_REG_START;
+
+               wr32(E1000_EERD, eerd);
+               ret_val = igb_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
+               if (ret_val)
+                       break;
+
+               data[i] = (rd32(E1000_EERD) >>
+                          E1000_NVM_RW_REG_DATA);
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_write_nvm_spi - Write to EEPROM using SPI
+ *  @hw: pointer to the HW structure
+ *  @offset: offset within the EEPROM to be written to
+ *  @words: number of words to write
+ *  @data: 16 bit word(s) to be written to the EEPROM
+ *
+ *  Writes data to EEPROM at offset using SPI interface.
+ *
+ *  If e1000_update_nvm_checksum is not called after this function , the
+ *  EEPROM will most likley contain an invalid checksum.
+ **/
+s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+       struct e1000_nvm_info *nvm = &hw->nvm;
+       s32 ret_val;
+       u16 widx = 0;
+
+       /*
+        * A check for invalid values:  offset too large, too many words,
+        * and not enough words.
+        */
+       if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+           (words == 0)) {
+               hw_dbg(hw, "nvm parameter(s) out of bounds\n");
+               ret_val = -E1000_ERR_NVM;
+               goto out;
+       }
+
+       ret_val = hw->nvm.ops.acquire_nvm(hw);
+       if (ret_val)
+               goto out;
+
+       msleep(10);
+
+       while (widx < words) {
+               u8 write_opcode = NVM_WRITE_OPCODE_SPI;
+
+               ret_val = igb_ready_nvm_eeprom(hw);
+               if (ret_val)
+                       goto release;
+
+               igb_standby_nvm(hw);
+
+               /* Send the WRITE ENABLE command (8 bit opcode) */
+               igb_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
+                                        nvm->opcode_bits);
+
+               igb_standby_nvm(hw);
+
+               /*
+                * Some SPI eeproms use the 8th address bit embedded in the
+                * opcode
+                */
+               if ((nvm->address_bits == 8) && (offset >= 128))
+                       write_opcode |= NVM_A8_OPCODE_SPI;
+
+               /* Send the Write command (8-bit opcode + addr) */
+               igb_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
+               igb_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
+                                        nvm->address_bits);
+
+               /* Loop to allow for up to whole page write of eeprom */
+               while (widx < words) {
+                       u16 word_out = data[widx];
+                       word_out = (word_out >> 8) | (word_out << 8);
+                       igb_shift_out_eec_bits(hw, word_out, 16);
+                       widx++;
+
+                       if ((((offset + widx) * 2) % nvm->page_size) == 0) {
+                               igb_standby_nvm(hw);
+                               break;
+                       }
+               }
+       }
+
+       msleep(10);
+release:
+       hw->nvm.ops.release_nvm(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_read_part_num - Read device part number
+ *  @hw: pointer to the HW structure
+ *  @part_num: pointer to device part number
+ *
+ *  Reads the product board assembly (PBA) number from the EEPROM and stores
+ *  the value in part_num.
+ **/
+s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num)
+{
+       s32  ret_val;
+       u16 nvm_data;
+
+       ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               goto out;
+       }
+       *part_num = (u32)(nvm_data << 16);
+
+       ret_val = hw->nvm.ops.read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               goto out;
+       }
+       *part_num |= nvm_data;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_read_mac_addr - Read device MAC address
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the device MAC address from the EEPROM and stores the value.
+ *  Since devices with two ports use the same EEPROM, we increment the
+ *  last bit in the MAC address for the second port.
+ **/
+s32 igb_read_mac_addr(struct e1000_hw *hw)
+{
+       s32  ret_val = 0;
+       u16 offset, nvm_data, i;
+
+       for (i = 0; i < ETH_ALEN; i += 2) {
+               offset = i >> 1;
+               ret_val = hw->nvm.ops.read_nvm(hw, offset, 1, &nvm_data);
+               if (ret_val) {
+                       hw_dbg(hw, "NVM Read Error\n");
+                       goto out;
+               }
+               hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
+               hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
+       }
+
+       /* Flip last bit of mac address if we're on second port */
+       if (hw->bus.func == E1000_FUNC_1)
+               hw->mac.perm_addr[5] ^= 1;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               hw->mac.addr[i] = hw->mac.perm_addr[i];
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_validate_nvm_checksum - Validate EEPROM checksum
+ *  @hw: pointer to the HW structure
+ *
+ *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
+ *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
+ **/
+s32 igb_validate_nvm_checksum(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 checksum = 0;
+       u16 i, nvm_data;
+
+       for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
+               ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+               if (ret_val) {
+                       hw_dbg(hw, "NVM Read Error\n");
+                       goto out;
+               }
+               checksum += nvm_data;
+       }
+
+       if (checksum != (u16) NVM_SUM) {
+               hw_dbg(hw, "NVM Checksum Invalid\n");
+               ret_val = -E1000_ERR_NVM;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_update_nvm_checksum - Update EEPROM checksum
+ *  @hw: pointer to the HW structure
+ *
+ *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
+ *  up to the checksum.  Then calculates the EEPROM checksum and writes the
+ *  value to the EEPROM.
+ **/
+s32 igb_update_nvm_checksum(struct e1000_hw *hw)
+{
+       s32  ret_val;
+       u16 checksum = 0;
+       u16 i, nvm_data;
+
+       for (i = 0; i < NVM_CHECKSUM_REG; i++) {
+               ret_val = hw->nvm.ops.read_nvm(hw, i, 1, &nvm_data);
+               if (ret_val) {
+                       hw_dbg(hw, "NVM Read Error while updating checksum.\n");
+                       goto out;
+               }
+               checksum += nvm_data;
+       }
+       checksum = (u16) NVM_SUM - checksum;
+       ret_val = hw->nvm.ops.write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
+       if (ret_val)
+               hw_dbg(hw, "NVM Write Error while updating checksum.\n");
+
+out:
+       return ret_val;
+}
+
diff --git a/drivers/net/igb/e1000_nvm.h b/drivers/net/igb/e1000_nvm.h
new file mode 100644 (file)
index 0000000..1041c34
--- /dev/null
@@ -0,0 +1,40 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_NVM_H_
+#define _E1000_NVM_H_
+
+s32  igb_acquire_nvm(struct e1000_hw *hw);
+void igb_release_nvm(struct e1000_hw *hw);
+s32  igb_read_mac_addr(struct e1000_hw *hw);
+s32  igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
+s32  igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+s32  igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+s32  igb_validate_nvm_checksum(struct e1000_hw *hw);
+s32  igb_update_nvm_checksum(struct e1000_hw *hw);
+
+#endif
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
new file mode 100644 (file)
index 0000000..08a86b1
--- /dev/null
@@ -0,0 +1,1807 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 <linux/if_ether.h>
+#include <linux/delay.h>
+
+#include "e1000_mac.h"
+#include "e1000_phy.h"
+
+static s32  igb_get_phy_cfg_done(struct e1000_hw *hw);
+static void igb_release_phy(struct e1000_hw *hw);
+static s32  igb_acquire_phy(struct e1000_hw *hw);
+static s32  igb_phy_reset_dsp(struct e1000_hw *hw);
+static s32  igb_phy_setup_autoneg(struct e1000_hw *hw);
+static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
+                                              u16 *phy_ctrl);
+static s32  igb_wait_autoneg(struct e1000_hw *hw);
+
+/* Cable length tables */
+static const u16 e1000_m88_cable_length_table[] =
+       { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
+#define M88E1000_CABLE_LENGTH_TABLE_SIZE \
+               (sizeof(e1000_m88_cable_length_table) / \
+                sizeof(e1000_m88_cable_length_table[0]))
+
+static const u16 e1000_igp_2_cable_length_table[] =
+    { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
+      0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
+      6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
+      21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
+      40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
+      60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
+      83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
+      104, 109, 114, 118, 121, 124};
+#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
+               (sizeof(e1000_igp_2_cable_length_table) / \
+                sizeof(e1000_igp_2_cable_length_table[0]))
+
+/**
+ *  e1000_check_reset_block - Check if PHY reset is blocked
+ *  @hw: pointer to the HW structure
+ *
+ *  Read the PHY management control register and check whether a PHY reset
+ *  is blocked.  If a reset is not blocked return 0, otherwise
+ *  return E1000_BLK_PHY_RESET (12).
+ **/
+s32 igb_check_reset_block(struct e1000_hw *hw)
+{
+       u32 manc;
+
+       manc = rd32(E1000_MANC);
+
+       return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
+              E1000_BLK_PHY_RESET : 0;
+}
+
+/**
+ *  e1000_get_phy_id - Retrieve the PHY ID and revision
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the PHY registers and stores the PHY ID and possibly the PHY
+ *  revision in the hardware structure.
+ **/
+s32 igb_get_phy_id(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val = 0;
+       u16 phy_id;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID1, &phy_id);
+       if (ret_val)
+               goto out;
+
+       phy->id = (u32)(phy_id << 16);
+       udelay(20);
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_ID2, &phy_id);
+       if (ret_val)
+               goto out;
+
+       phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
+       phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_reset_dsp - Reset PHY DSP
+ *  @hw: pointer to the HW structure
+ *
+ *  Reset the digital signal processor.
+ **/
+static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
+{
+       s32 ret_val;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1);
+       if (ret_val)
+               goto out;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_read_phy_reg_mdic - Read MDI control register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Reads the MDI control regsiter in the PHY at offset and stores the
+ *  information read to data.
+ **/
+static s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       u32 i, mdic = 0;
+       s32 ret_val = 0;
+
+       if (offset > MAX_PHY_REG_ADDRESS) {
+               hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+               ret_val = -E1000_ERR_PARAM;
+               goto out;
+       }
+
+       /*
+        * Set up Op-code, Phy Address, and register offset in the MDI
+        * Control register.  The MAC will take care of interfacing with the
+        * PHY to retrieve the desired data.
+        */
+       mdic = ((offset << E1000_MDIC_REG_SHIFT) |
+               (phy->addr << E1000_MDIC_PHY_SHIFT) |
+               (E1000_MDIC_OP_READ));
+
+       wr32(E1000_MDIC, mdic);
+
+       /*
+        * Poll the ready bit to see if the MDI read completed
+        * Increasing the time out as testing showed failures with
+        * the lower time out
+        */
+       for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+               udelay(50);
+               mdic = rd32(E1000_MDIC);
+               if (mdic & E1000_MDIC_READY)
+                       break;
+       }
+       if (!(mdic & E1000_MDIC_READY)) {
+               hw_dbg(hw, "MDI Read did not complete\n");
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+       if (mdic & E1000_MDIC_ERROR) {
+               hw_dbg(hw, "MDI Error\n");
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+       *data = (u16) mdic;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_write_phy_reg_mdic - Write MDI control register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write to register at offset
+ *
+ *  Writes data to MDI control register in the PHY at offset.
+ **/
+static s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       u32 i, mdic = 0;
+       s32 ret_val = 0;
+
+       if (offset > MAX_PHY_REG_ADDRESS) {
+               hw_dbg(hw, "PHY Address %d is out of range\n", offset);
+               ret_val = -E1000_ERR_PARAM;
+               goto out;
+       }
+
+       /*
+        * Set up Op-code, Phy Address, and register offset in the MDI
+        * Control register.  The MAC will take care of interfacing with the
+        * PHY to retrieve the desired data.
+        */
+       mdic = (((u32)data) |
+               (offset << E1000_MDIC_REG_SHIFT) |
+               (phy->addr << E1000_MDIC_PHY_SHIFT) |
+               (E1000_MDIC_OP_WRITE));
+
+       wr32(E1000_MDIC, mdic);
+
+       /*
+        * Poll the ready bit to see if the MDI read completed
+        * Increasing the time out as testing showed failures with
+        * the lower time out
+        */
+       for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+               udelay(50);
+               mdic = rd32(E1000_MDIC);
+               if (mdic & E1000_MDIC_READY)
+                       break;
+       }
+       if (!(mdic & E1000_MDIC_READY)) {
+               hw_dbg(hw, "MDI Write did not complete\n");
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+       if (mdic & E1000_MDIC_ERROR) {
+               hw_dbg(hw, "MDI Error\n");
+               ret_val = -E1000_ERR_PHY;
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_read_phy_reg_igp - Read igp 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
+ *  semaphores before exiting.
+ **/
+s32 igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       s32 ret_val;
+
+       ret_val = igb_acquire_phy(hw);
+       if (ret_val)
+               goto out;
+
+       if (offset > MAX_PHY_MULTI_PAGE_REG) {
+               ret_val = igb_write_phy_reg_mdic(hw,
+                                                  IGP01E1000_PHY_PAGE_SELECT,
+                                                  (u16)offset);
+               if (ret_val) {
+                       igb_release_phy(hw);
+                       goto out;
+               }
+       }
+
+       ret_val = igb_read_phy_reg_mdic(hw,
+                                         MAX_PHY_REG_ADDRESS & offset,
+                                         data);
+
+       igb_release_phy(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_write_phy_reg_igp - Write igp 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 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       s32 ret_val;
+
+       ret_val = igb_acquire_phy(hw);
+       if (ret_val)
+               goto out;
+
+       if (offset > MAX_PHY_MULTI_PAGE_REG) {
+               ret_val = igb_write_phy_reg_mdic(hw,
+                                                  IGP01E1000_PHY_PAGE_SELECT,
+                                                  (u16)offset);
+               if (ret_val) {
+                       igb_release_phy(hw);
+                       goto out;
+               }
+       }
+
+       ret_val = igb_write_phy_reg_mdic(hw,
+                                          MAX_PHY_REG_ADDRESS & offset,
+                                          data);
+
+       igb_release_phy(hw);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets up MDI/MDI-X and polarity for m88 PHY's.  If necessary, transmit clock
+ *  and downshift values are set also.
+ **/
+s32 igb_copper_link_setup_m88(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data;
+
+       if (phy->reset_disable) {
+               ret_val = 0;
+               goto out;
+       }
+
+       /* Enable CRS on TX. This must be set for half-duplex operation. */
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+       /*
+        * Options:
+        *   MDI/MDI-X = 0 (default)
+        *   0 - Auto for all speeds
+        *   1 - MDI mode
+        *   2 - MDI-X mode
+        *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+        */
+       phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+       switch (phy->mdix) {
+       case 1:
+               phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+               break;
+       case 2:
+               phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+               break;
+       case 3:
+               phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+               break;
+       case 0:
+       default:
+               phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+               break;
+       }
+
+       /*
+        * Options:
+        *   disable_polarity_correction = 0 (default)
+        *       Automatic Correction for Reversed Cable Polarity
+        *   0 - Disabled
+        *   1 - Enabled
+        */
+       phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+       if (phy->disable_polarity_correction == 1)
+               phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                           phy_data);
+       if (ret_val)
+               goto out;
+
+       if (phy->revision < E1000_REVISION_4) {
+               /*
+                * Force TX_CLK in the Extended PHY Specific Control Register
+                * to 25MHz clock.
+                */
+               ret_val = hw->phy.ops.read_phy_reg(hw,
+                                            M88E1000_EXT_PHY_SPEC_CTRL,
+                                            &phy_data);
+               if (ret_val)
+                       goto out;
+
+               phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+               if ((phy->revision == E1000_REVISION_2) &&
+                   (phy->id == M88E1111_I_PHY_ID)) {
+                       /* 82573L PHY - set the downshift counter to 5x. */
+                       phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK;
+                       phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
+               } else {
+                       /* Configure Master and Slave downshift values */
+                       phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                                     M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+                       phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                                    M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+               }
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                            M88E1000_EXT_PHY_SPEC_CTRL,
+                                            phy_data);
+               if (ret_val)
+                       goto out;
+       }
+
+       /* Commit the changes. */
+       ret_val = igb_phy_sw_reset(hw);
+       if (ret_val) {
+               hw_dbg(hw, "Error committing the PHY changes\n");
+               goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_copper_link_setup_igp - Setup igp PHY's for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for
+ *  igp PHY's.
+ **/
+s32 igb_copper_link_setup_igp(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+
+       if (phy->reset_disable) {
+               ret_val = 0;
+               goto out;
+       }
+
+       ret_val = hw->phy.ops.reset_phy(hw);
+       if (ret_val) {
+               hw_dbg(hw, "Error resetting the PHY.\n");
+               goto out;
+       }
+
+       /* Wait 15ms for MAC to configure PHY from NVM settings. */
+       msleep(15);
+
+       /*
+        * The NVM settings will configure LPLU in D3 for
+        * non-IGP1 PHYs.
+        */
+       if (phy->type == e1000_phy_igp) {
+               /* disable lplu d3 during driver init */
+               if (hw->phy.ops.set_d3_lplu_state)
+                       ret_val = hw->phy.ops.set_d3_lplu_state(hw, false);
+               if (ret_val) {
+                       hw_dbg(hw, "Error Disabling LPLU D3\n");
+                       goto out;
+               }
+       }
+
+       /* disable lplu d0 during driver init */
+       ret_val = hw->phy.ops.set_d0_lplu_state(hw, false);
+       if (ret_val) {
+               hw_dbg(hw, "Error Disabling LPLU D0\n");
+               goto out;
+       }
+       /* Configure mdi-mdix settings */
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data);
+       if (ret_val)
+               goto out;
+
+       data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+
+       switch (phy->mdix) {
+       case 1:
+               data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+               break;
+       case 2:
+               data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
+               break;
+       case 0:
+       default:
+               data |= IGP01E1000_PSCR_AUTO_MDIX;
+               break;
+       }
+       ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data);
+       if (ret_val)
+               goto out;
+
+       /* set auto-master slave resolution settings */
+       if (hw->mac.autoneg) {
+               /*
+                * when autonegotiation advertisement is only 1000Mbps then we
+                * should disable SmartSpeed and enable Auto MasterSlave
+                * resolution as hardware default.
+                */
+               if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
+                       /* Disable SmartSpeed */
+                       ret_val = hw->phy.ops.read_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    &data);
+                       if (ret_val)
+                               goto out;
+
+                       data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    data);
+                       if (ret_val)
+                               goto out;
+
+                       /* Set auto Master/Slave resolution process */
+                       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL,
+                                                          &data);
+                       if (ret_val)
+                               goto out;
+
+                       data &= ~CR_1000T_MS_ENABLE;
+                       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL,
+                                                           data);
+                       if (ret_val)
+                               goto out;
+               }
+
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_CTRL, &data);
+               if (ret_val)
+                       goto out;
+
+               /* load defaults for future use */
+               phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ?
+                       ((data & CR_1000T_MS_VALUE) ?
+                       e1000_ms_force_master :
+                       e1000_ms_force_slave) :
+                       e1000_ms_auto;
+
+               switch (phy->ms_type) {
+               case e1000_ms_force_master:
+                       data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+                       break;
+               case e1000_ms_force_slave:
+                       data |= CR_1000T_MS_ENABLE;
+                       data &= ~(CR_1000T_MS_VALUE);
+                       break;
+               case e1000_ms_auto:
+                       data &= ~CR_1000T_MS_ENABLE;
+               default:
+                       break;
+               }
+               ret_val = hw->phy.ops.write_phy_reg(hw, PHY_1000T_CTRL, data);
+               if (ret_val)
+                       goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_copper_link_autoneg - Setup/Enable autoneg for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Performs initial bounds checking on autoneg advertisement parameter, then
+ *  configure to advertise the full capability.  Setup the PHY to autoneg
+ *  and restart the negotiation process between the link partner.  If
+ *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
+ **/
+s32 igb_copper_link_autoneg(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_ctrl;
+
+       /*
+        * Perform some bounds checking on the autoneg advertisement
+        * parameter.
+        */
+       phy->autoneg_advertised &= phy->autoneg_mask;
+
+       /*
+        * If autoneg_advertised is zero, we assume it was not defaulted
+        * by the calling code so we set to advertise full capability.
+        */
+       if (phy->autoneg_advertised == 0)
+               phy->autoneg_advertised = phy->autoneg_mask;
+
+       hw_dbg(hw, "Reconfiguring auto-neg advertisement params\n");
+       ret_val = igb_phy_setup_autoneg(hw);
+       if (ret_val) {
+               hw_dbg(hw, "Error Setting up Auto-Negotiation\n");
+               goto out;
+       }
+       hw_dbg(hw, "Restarting Auto-Neg\n");
+
+       /*
+        * Restart auto-negotiation by setting the Auto Neg Enable bit and
+        * the Auto Neg Restart bit in the PHY control register.
+        */
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+       if (ret_val)
+               goto out;
+
+       phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Does the user want to wait for Auto-Neg to complete here, or
+        * check at a later time (for example, callback routine).
+        */
+       if (phy->autoneg_wait_to_complete) {
+               ret_val = igb_wait_autoneg(hw);
+               if (ret_val) {
+                       hw_dbg(hw, "Error while waiting for "
+                                "autoneg to complete\n");
+                       goto out;
+               }
+       }
+
+       hw->mac.get_link_status = true;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_setup_autoneg - Configure PHY for auto-negotiation
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the MII auto-neg advertisement register and/or the 1000T control
+ *  register and if the PHY is already setup for auto-negotiation, then
+ *  return successful.  Otherwise, setup advertisement and flow control to
+ *  the appropriate values for the wanted auto-negotiation.
+ **/
+static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 mii_autoneg_adv_reg;
+       u16 mii_1000t_ctrl_reg = 0;
+
+       phy->autoneg_advertised &= phy->autoneg_mask;
+
+       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                          &mii_autoneg_adv_reg);
+       if (ret_val)
+               goto out;
+
+       if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
+               /* Read the MII 1000Base-T Control Register (Address 9). */
+               ret_val = hw->phy.ops.read_phy_reg(hw,
+                                           PHY_1000T_CTRL,
+                                           &mii_1000t_ctrl_reg);
+               if (ret_val)
+                       goto out;
+       }
+
+       /*
+        * Need to parse both autoneg_advertised and fc and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+
+       /*
+        * First we clear all the 10/100 mb speed bits in the Auto-Neg
+        * Advertisement Register (Address 4) and the 1000 mb speed bits in
+        * the  1000Base-T Control Register (Address 9).
+        */
+       mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS |
+                                NWAY_AR_100TX_HD_CAPS |
+                                NWAY_AR_10T_FD_CAPS   |
+                                NWAY_AR_10T_HD_CAPS);
+       mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
+
+       hw_dbg(hw, "autoneg_advertised %x\n", phy->autoneg_advertised);
+
+       /* Do we want to advertise 10 Mb Half Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
+               hw_dbg(hw, "Advertise 10mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
+       }
+
+       /* Do we want to advertise 10 Mb Full Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
+               hw_dbg(hw, "Advertise 10mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Half Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
+               hw_dbg(hw, "Advertise 100mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Full Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
+               hw_dbg(hw, "Advertise 100mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
+       }
+
+       /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
+       if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
+               hw_dbg(hw, "Advertise 1000mb Half duplex request denied!\n");
+
+       /* Do we want to advertise 1000 Mb Full Duplex? */
+       if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
+               hw_dbg(hw, "Advertise 1000mb Full duplex\n");
+               mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
+       }
+
+       /*
+        * Check for a software override of the flow control settings, and
+        * setup the PHY advertisement registers accordingly.  If
+        * auto-negotiation is enabled, then software will have to set the
+        * "PAUSE" bits to the correct value in the Auto-Negotiation
+        * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
+        * negotiation.
+        *
+        * The possible values of the "fc" parameter 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.
+        *  other:  No software override.  The flow control configuration
+        *          in the EEPROM is used.
+        */
+       switch (hw->fc.type) {
+       case e1000_fc_none:
+               /*
+                * Flow control (RX & TX) is completely disabled by a
+                * software over-ride.
+                */
+               mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_rx_pause:
+               /*
+                * RX Flow control is enabled, and TX Flow control is
+                * disabled, by a software over-ride.
+                *
+                * 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
+                * (in e1000_config_fc_after_link_up) we will disable the
+                * hw's ability to send PAUSE frames.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_tx_pause:
+               /*
+                * TX Flow control is enabled, and RX Flow control is
+                * disabled, by a software over-ride.
+                */
+               mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
+               mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
+               break;
+       case e1000_fc_full:
+               /*
+                * Flow control (both RX and TX) is enabled by a software
+                * over-ride.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       default:
+               hw_dbg(hw, "Flow control param set incorrectly\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_AUTONEG_ADV,
+                                           mii_autoneg_adv_reg);
+       if (ret_val)
+               goto out;
+
+       hw_dbg(hw, "Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+       if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             PHY_1000T_CTRL,
+                                             mii_1000t_ctrl_reg);
+               if (ret_val)
+                       goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp 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 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data;
+       bool link;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+       if (ret_val)
+               goto out;
+
+       igb_phy_force_speed_duplex_setup(hw, &phy_data);
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
+        * forced whenever speed and duplex are forced.
+        */
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+       phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                           phy_data);
+       if (ret_val)
+               goto out;
+
+       hw_dbg(hw, "IGP PSCR: %X\n", phy_data);
+
+       udelay(1);
+
+       if (phy->autoneg_wait_to_complete) {
+               hw_dbg(hw,
+                      "Waiting for forced speed/duplex link on IGP phy.\n");
+
+               ret_val = igb_phy_has_link(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 = igb_phy_has_link(hw,
+                                                    PHY_FORCE_LIMIT,
+                                                    100000,
+                                                    &link);
+               if (ret_val)
+                       goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 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.  Resets the PHY to commit the
+ *  changes.  If time expires while waiting for link up, we reset the DSP.
+ *  After reset, TX_CLK and CRS on TX must be set.  Return successful upon
+ *  successful completion, else return corresponding error code.
+ **/
+s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data;
+       bool link;
+
+       /*
+        * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
+        * forced whenever speed and duplex are forced.
+        */
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                           phy_data);
+       if (ret_val)
+               goto out;
+
+       hw_dbg(hw, "M88E1000 PSCR: %X\n", phy_data);
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+       if (ret_val)
+               goto out;
+
+       igb_phy_force_speed_duplex_setup(hw, &phy_data);
+
+       /* Reset the phy to commit changes. */
+       phy_data |= MII_CR_RESET;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+       if (ret_val)
+               goto out;
+
+       udelay(1);
+
+       if (phy->autoneg_wait_to_complete) {
+               hw_dbg(hw,
+                      "Waiting for forced speed/duplex link on M88 phy.\n");
+
+               ret_val = igb_phy_has_link(hw,
+                                                    PHY_FORCE_LIMIT,
+                                                    100000,
+                                                    &link);
+               if (ret_val)
+                       goto out;
+
+               if (!link) {
+                       /*
+                        * We didn't get link.
+                        * Reset the DSP and cross our fingers.
+                        */
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                     M88E1000_PHY_PAGE_SELECT,
+                                                     0x001d);
+                       if (ret_val)
+                               goto out;
+                       ret_val = igb_phy_reset_dsp(hw);
+                       if (ret_val)
+                               goto out;
+               }
+
+               /* Try once more */
+               ret_val = igb_phy_has_link(hw, PHY_FORCE_LIMIT,
+                                            100000, &link);
+               if (ret_val)
+                       goto out;
+       }
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Resetting the phy means we need to re-force TX_CLK in the
+        * Extended PHY Specific Control Register to 25MHz clock from
+        * the reset value of 2.5MHz.
+        */
+       phy_data |= M88E1000_EPSCR_TX_CLK_25;
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                           phy_data);
+       if (ret_val)
+               goto out;
+
+       /*
+        * In addition, we must re-enable CRS on Tx for both half and full
+        * duplex.
+        */
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+       ret_val = hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                           phy_data);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
+ *  @hw: pointer to the HW structure
+ *  @phy_ctrl: pointer to current value of PHY_CONTROL
+ *
+ *  Forces speed and duplex on the PHY by doing the following: disable flow
+ *  control, force speed/duplex on the MAC, disable auto speed detection,
+ *  disable auto-negotiation, configure duplex, configure speed, configure
+ *  the collision distance, write configuration to CTRL register.  The
+ *  caller must write to the PHY_CONTROL register for these settings to
+ *  take affect.
+ **/
+static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
+                                              u16 *phy_ctrl)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       u32 ctrl;
+
+       /* Turn off flow control when forcing speed/duplex */
+       hw->fc.type = e1000_fc_none;
+
+       /* Force speed/duplex on the mac */
+       ctrl = rd32(E1000_CTRL);
+       ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+       ctrl &= ~E1000_CTRL_SPD_SEL;
+
+       /* Disable Auto Speed Detection */
+       ctrl &= ~E1000_CTRL_ASDE;
+
+       /* Disable autoneg on the phy */
+       *phy_ctrl &= ~MII_CR_AUTO_NEG_EN;
+
+       /* Forcing Full or Half Duplex? */
+       if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) {
+               ctrl &= ~E1000_CTRL_FD;
+               *phy_ctrl &= ~MII_CR_FULL_DUPLEX;
+               hw_dbg(hw, "Half Duplex\n");
+       } else {
+               ctrl |= E1000_CTRL_FD;
+               *phy_ctrl |= MII_CR_FULL_DUPLEX;
+               hw_dbg(hw, "Full Duplex\n");
+       }
+
+       /* Forcing 10mb or 100mb? */
+       if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
+               ctrl |= E1000_CTRL_SPD_100;
+               *phy_ctrl |= MII_CR_SPEED_100;
+               *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
+               hw_dbg(hw, "Forcing 100mb\n");
+       } else {
+               ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
+               *phy_ctrl |= MII_CR_SPEED_10;
+               *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
+               hw_dbg(hw, "Forcing 10mb\n");
+       }
+
+       igb_config_collision_dist(hw);
+
+       wr32(E1000_CTRL, ctrl);
+}
+
+/**
+ *  e1000_set_d3_lplu_state - Sets low power link up state for D3
+ *  @hw: pointer to the HW structure
+ *  @active: boolean used to enable/disable lplu
+ *
+ *  Success returns 0, Failure returns 1
+ *
+ *  The low power link up (lplu) state is set to the power management level D3
+ *  and SmartSpeed is disabled when active is true, else clear lplu for D3
+ *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
+ *  is used during Dx states where the power conservation is most important.
+ *  During driver activity, SmartSpeed should be enabled so performance is
+ *  maintained.
+ **/
+s32 igb_set_d3_lplu_state(struct e1000_hw *hw, bool active)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
+                                          &data);
+       if (ret_val)
+               goto out;
+
+       if (!active) {
+               data &= ~IGP02E1000_PM_D3_LPLU;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                            IGP02E1000_PHY_POWER_MGMT,
+                                            data);
+               if (ret_val)
+                       goto out;
+               /*
+                * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+                * during Dx states where the power conservation is most
+                * important.  During driver activity we should enable
+                * SmartSpeed, so performance is maintained.
+                */
+               if (phy->smart_speed == e1000_smart_speed_on) {
+                       ret_val = hw->phy.ops.read_phy_reg(hw,
+                                                   IGP01E1000_PHY_PORT_CONFIG,
+                                                   &data);
+                       if (ret_val)
+                               goto out;
+
+                       data |= IGP01E1000_PSCFR_SMART_SPEED;
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    data);
+                       if (ret_val)
+                               goto out;
+               } else if (phy->smart_speed == e1000_smart_speed_off) {
+                       ret_val = hw->phy.ops.read_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    &data);
+                       if (ret_val)
+                               goto out;
+
+                       data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+                       ret_val = hw->phy.ops.write_phy_reg(hw,
+                                                    IGP01E1000_PHY_PORT_CONFIG,
+                                                    data);
+                       if (ret_val)
+                               goto out;
+               }
+       } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) ||
+                  (phy->autoneg_advertised == E1000_ALL_NOT_GIG) ||
+                  (phy->autoneg_advertised == E1000_ALL_10_SPEED)) {
+               data |= IGP02E1000_PM_D3_LPLU;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             IGP02E1000_PHY_POWER_MGMT,
+                                             data);
+               if (ret_val)
+                       goto out;
+
+               /* When LPLU is enabled, we should disable SmartSpeed */
+               ret_val = hw->phy.ops.read_phy_reg(hw,
+                                            IGP01E1000_PHY_PORT_CONFIG,
+                                            &data);
+               if (ret_val)
+                       goto out;
+
+               data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                             IGP01E1000_PHY_PORT_CONFIG,
+                                             data);
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_check_downshift - Checks whether a downshift in speed occured
+ *  @hw: pointer to the HW structure
+ *
+ *  Success returns 0, Failure returns 1
+ *
+ *  A downshift is detected by querying the PHY link health.
+ **/
+s32 igb_check_downshift(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data, offset, mask;
+
+       switch (phy->type) {
+       case e1000_phy_m88:
+       case e1000_phy_gg82563:
+               offset  = M88E1000_PHY_SPEC_STATUS;
+               mask    = M88E1000_PSSR_DOWNSHIFT;
+               break;
+       case e1000_phy_igp_2:
+       case e1000_phy_igp:
+       case e1000_phy_igp_3:
+               offset  = IGP01E1000_PHY_LINK_HEALTH;
+               mask    = IGP01E1000_PLHR_SS_DOWNGRADE;
+               break;
+       default:
+               /* speed downshift not supported */
+               phy->speed_downgraded = false;
+               ret_val = 0;
+               goto out;
+       }
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, offset, &phy_data);
+
+       if (!ret_val)
+               phy->speed_downgraded = (phy_data & mask) ? true : false;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_check_polarity_m88 - 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.
+ **/
+static s32 igb_check_polarity_m88(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data);
+
+       if (!ret_val)
+               phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY)
+                                     ? e1000_rev_polarity_reversed
+                                     : e1000_rev_polarity_normal;
+
+       return ret_val;
+}
+
+/**
+ *  e1000_check_polarity_igp - 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 port status register, and the
+ *  current speed (since there is no polarity at 100Mbps).
+ **/
+static s32 igb_check_polarity_igp(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data, offset, mask;
+
+       /*
+        * Polarity is determined based on the speed of
+        * our connection.
+        */
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                          &data);
+       if (ret_val)
+               goto out;
+
+       if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
+           IGP01E1000_PSSR_SPEED_1000MBPS) {
+               offset  = IGP01E1000_PHY_PCS_INIT_REG;
+               mask    = IGP01E1000_PHY_POLARITY_MASK;
+       } else {
+               /*
+                * This really only applies to 10Mbps since
+                * there is no polarity for 100Mbps (always 0).
+                */
+               offset  = IGP01E1000_PHY_PORT_STATUS;
+               mask    = IGP01E1000_PSSR_POLARITY_REVERSED;
+       }
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, offset, &data);
+
+       if (!ret_val)
+               phy->cable_polarity = (data & mask)
+                                     ? e1000_rev_polarity_reversed
+                                     : e1000_rev_polarity_normal;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_wait_autoneg - Wait for auto-neg compeletion
+ *  @hw: pointer to the HW structure
+ *
+ *  Waits for auto-negotiation to complete or for the auto-negotiation time
+ *  limit to expire, which ever happens first.
+ **/
+static s32 igb_wait_autoneg(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 i, phy_status;
+
+       /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
+       for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+               if (ret_val)
+                       break;
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+               if (ret_val)
+                       break;
+               if (phy_status & MII_SR_AUTONEG_COMPLETE)
+                       break;
+               msleep(100);
+       }
+
+       /*
+        * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
+        * has completed.
+        */
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_has_link - Polls PHY for link
+ *  @hw: pointer to the HW structure
+ *  @iterations: number of times to poll for link
+ *  @usec_interval: delay between polling attempts
+ *  @success: pointer to whether polling was successful or not
+ *
+ *  Polls the PHY status register for link, 'iterations' number of times.
+ **/
+s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
+                              u32 usec_interval, bool *success)
+{
+       s32 ret_val = 0;
+       u16 i, phy_status;
+
+       for (i = 0; i < iterations; i++) {
+               /*
+                * Some PHYs require the PHY_STATUS register to be read
+                * twice due to the link bit being sticky.  No harm doing
+                * it across the board.
+                */
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+               if (ret_val)
+                       break;
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_STATUS, &phy_status);
+               if (ret_val)
+                       break;
+               if (phy_status & MII_SR_LINK_STATUS)
+                       break;
+               if (usec_interval >= 1000)
+                       mdelay(usec_interval/1000);
+               else
+                       udelay(usec_interval);
+       }
+
+       *success = (i < iterations) ? true : false;
+
+       return ret_val;
+}
+
+/**
+ *  e1000_get_cable_length_m88 - Determine cable length for m88 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the PHY specific status register to retrieve the cable length
+ *  information.  The cable length is determined by averaging the minimum and
+ *  maximum values to get the "average" cable length.  The m88 PHY has four
+ *  possible cable length values, which are:
+ *     Register Value          Cable Length
+ *     0                       < 50 meters
+ *     1                       50 - 80 meters
+ *     2                       80 - 110 meters
+ *     3                       110 - 140 meters
+ *     4                       > 140 meters
+ **/
+s32 igb_get_cable_length_m88(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data, index;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+               M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+       phy->min_cable_length = e1000_m88_cable_length_table[index];
+       phy->max_cable_length = e1000_m88_cable_length_table[index+1];
+
+       phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  The automatic gain control (agc) normalizes the amplitude of the
+ *  received signal, adjusting for the attenuation produced by the
+ *  cable.  By reading the AGC registers, which reperesent the
+ *  cobination of course and fine gain value, the value can be put
+ *  into a lookup table to obtain the approximate cable length
+ *  for each channel.
+ **/
+s32 igb_get_cable_length_igp_2(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val = 0;
+       u16 phy_data, i, agc_value = 0;
+       u16 cur_agc_index, max_agc_index = 0;
+       u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1;
+       u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
+                                                        {IGP02E1000_PHY_AGC_A,
+                                                         IGP02E1000_PHY_AGC_B,
+                                                         IGP02E1000_PHY_AGC_C,
+                                                         IGP02E1000_PHY_AGC_D};
+
+       /* Read the AGC registers for all channels */
+       for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
+               ret_val = hw->phy.ops.read_phy_reg(hw, agc_reg_array[i],
+                                                  &phy_data);
+               if (ret_val)
+                       goto out;
+
+               /*
+                * Getting bits 15:9, which represent the combination of
+                * course and fine gain values.  The result is a number
+                * that can be put into the lookup table to obtain the
+                * approximate cable length.
+                */
+               cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
+                               IGP02E1000_AGC_LENGTH_MASK;
+
+               /* Array index bound check. */
+               if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) ||
+                   (cur_agc_index == 0)) {
+                       ret_val = -E1000_ERR_PHY;
+                       goto out;
+               }
+
+               /* Remove min & max AGC values from calculation. */
+               if (e1000_igp_2_cable_length_table[min_agc_index] >
+                   e1000_igp_2_cable_length_table[cur_agc_index])
+                       min_agc_index = cur_agc_index;
+               if (e1000_igp_2_cable_length_table[max_agc_index] <
+                   e1000_igp_2_cable_length_table[cur_agc_index])
+                       max_agc_index = cur_agc_index;
+
+               agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
+       }
+
+       agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
+                     e1000_igp_2_cable_length_table[max_agc_index]);
+       agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
+
+       /* Calculate cable length with the error range of +/- 10 meters. */
+       phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
+                                (agc_value - IGP02E1000_AGC_RANGE) : 0;
+       phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE;
+
+       phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_get_phy_info_m88 - Retrieve PHY information
+ *  @hw: pointer to the HW structure
+ *
+ *  Valid for only copper links.  Read the PHY status register (sticky read)
+ *  to verify that link is up.  Read the PHY special control register to
+ *  determine the polarity and 10base-T extended distance.  Read the PHY
+ *  special status register to determine MDI/MDIx and current speed.  If
+ *  speed is 1000, then determine cable length, local and remote receiver.
+ **/
+s32 igb_get_phy_info_m88(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32  ret_val;
+       u16 phy_data;
+       bool link;
+
+       if (hw->phy.media_type != e1000_media_type_copper) {
+               hw_dbg(hw, "Phy info is only valid for copper media\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       ret_val = igb_phy_has_link(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;
+       }
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL)
+                                  ? true
+                                  : false;
+
+       ret_val = igb_check_polarity_m88(hw);
+       if (ret_val)
+               goto out;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                          &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false;
+
+       if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
+               ret_val = hw->phy.ops.get_cable_length(hw);
+               if (ret_val)
+                       goto out;
+
+               ret_val = hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
+                                                  &phy_data);
+               if (ret_val)
+                       goto out;
+
+               phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
+                               ? e1000_1000t_rx_status_ok
+                               : e1000_1000t_rx_status_not_ok;
+
+               phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS)
+                                ? e1000_1000t_rx_status_ok
+                                : e1000_1000t_rx_status_not_ok;
+       } else {
+               /* Set values to "undefined" */
+               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_phy_info_igp - Retrieve igp 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 igb_get_phy_info_igp(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+       bool link;
+
+       ret_val = igb_phy_has_link(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 = igb_check_polarity_igp(hw);
+       if (ret_val)
+               goto out;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                          &data);
+       if (ret_val)
+               goto out;
+
+       phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? true : false;
+
+       if ((data & IGP01E1000_PSSR_SPEED_MASK) ==
+           IGP01E1000_PSSR_SPEED_1000MBPS) {
+               ret_val = hw->phy.ops.get_cable_length(hw);
+               if (ret_val)
+                       goto out;
+
+               ret_val = hw->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_phy_sw_reset - PHY software reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Does a software reset of the PHY by reading the PHY control register and
+ *  setting/write the control register reset bit to the PHY.
+ **/
+s32 igb_phy_sw_reset(struct e1000_hw *hw)
+{
+       s32 ret_val;
+       u16 phy_ctrl;
+
+       ret_val = hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_ctrl);
+       if (ret_val)
+               goto out;
+
+       phy_ctrl |= MII_CR_RESET;
+       ret_val = hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_ctrl);
+       if (ret_val)
+               goto out;
+
+       udelay(1);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_hw_reset - PHY hardware reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Verify the reset block is not blocking us from resetting.  Acquire
+ *  semaphore (if necessary) and read/set/write the device control reset
+ *  bit in the PHY.  Wait the appropriate delay time for the device to
+ *  reset and relase the semaphore (if necessary).
+ **/
+s32 igb_phy_hw_reset(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32  ret_val;
+       u32 ctrl;
+
+       ret_val = igb_check_reset_block(hw);
+       if (ret_val) {
+               ret_val = 0;
+               goto out;
+       }
+
+       ret_val = igb_acquire_phy(hw);
+       if (ret_val)
+               goto out;
+
+       ctrl = rd32(E1000_CTRL);
+       wr32(E1000_CTRL, ctrl | E1000_CTRL_PHY_RST);
+       wrfl();
+
+       udelay(phy->reset_delay_us);
+
+       wr32(E1000_CTRL, ctrl);
+       wrfl();
+
+       udelay(150);
+
+       igb_release_phy(hw);
+
+       ret_val = igb_get_phy_cfg_done(hw);
+
+out:
+       return ret_val;
+}
+
+/* Internal function pointers */
+
+/**
+ *  e1000_get_phy_cfg_done - Generic PHY configuration done
+ *  @hw: pointer to the HW structure
+ *
+ *  Return success if silicon family did not implement a family specific
+ *  get_cfg_done function.
+ **/
+static s32 igb_get_phy_cfg_done(struct e1000_hw *hw)
+{
+       if (hw->phy.ops.get_cfg_done)
+               return hw->phy.ops.get_cfg_done(hw);
+
+       return 0;
+}
+
+/**
+ *  e1000_release_phy - Generic release PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Return if silicon family does not require a semaphore when accessing the
+ *  PHY.
+ **/
+static void igb_release_phy(struct e1000_hw *hw)
+{
+       if (hw->phy.ops.release_phy)
+               hw->phy.ops.release_phy(hw);
+}
+
+/**
+ *  e1000_acquire_phy - Generic acquire PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Return success if silicon family does not require a semaphore when
+ *  accessing the PHY.
+ **/
+static s32 igb_acquire_phy(struct e1000_hw *hw)
+{
+       if (hw->phy.ops.acquire_phy)
+               return hw->phy.ops.acquire_phy(hw);
+
+       return 0;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
+ *  @hw: pointer to the HW structure
+ *
+ *  When the silicon family has not implemented a forced speed/duplex
+ *  function for the PHY, simply return 0.
+ **/
+s32 igb_phy_force_speed_duplex(struct e1000_hw *hw)
+{
+       if (hw->phy.ops.force_speed_duplex)
+               return hw->phy.ops.force_speed_duplex(hw);
+
+       return 0;
+}
+
+/**
+ *  e1000_phy_init_script_igp3 - Inits the IGP3 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Initializes a Intel Gigabit PHY3 when an EEPROM is not present.
+ **/
+s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
+{
+       hw_dbg(hw, "Running IGP 3 PHY init script\n");
+
+       /* PHY init IGP 3 */
+       /* Enable rise/fall, 10-mode work in class-A */
+       hw->phy.ops.write_phy_reg(hw, 0x2F5B, 0x9018);
+       /* Remove all caps from Replica path filter */
+       hw->phy.ops.write_phy_reg(hw, 0x2F52, 0x0000);
+       /* Bias trimming for ADC, AFE and Driver (Default) */
+       hw->phy.ops.write_phy_reg(hw, 0x2FB1, 0x8B24);
+       /* Increase Hybrid poly bias */
+       hw->phy.ops.write_phy_reg(hw, 0x2FB2, 0xF8F0);
+       /* Add 4% to TX amplitude in Giga mode */
+       hw->phy.ops.write_phy_reg(hw, 0x2010, 0x10B0);
+       /* Disable trimming (TTT) */
+       hw->phy.ops.write_phy_reg(hw, 0x2011, 0x0000);
+       /* Poly DC correction to 94.6% + 2% for all channels */
+       hw->phy.ops.write_phy_reg(hw, 0x20DD, 0x249A);
+       /* ABS DC correction to 95.9% */
+       hw->phy.ops.write_phy_reg(hw, 0x20DE, 0x00D3);
+       /* BG temp curve trim */
+       hw->phy.ops.write_phy_reg(hw, 0x28B4, 0x04CE);
+       /* Increasing ADC OPAMP stage 1 currents to max */
+       hw->phy.ops.write_phy_reg(hw, 0x2F70, 0x29E4);
+       /* Force 1000 ( required for enabling PHY regs configuration) */
+       hw->phy.ops.write_phy_reg(hw, 0x0000, 0x0140);
+       /* Set upd_freq to 6 */
+       hw->phy.ops.write_phy_reg(hw, 0x1F30, 0x1606);
+       /* Disable NPDFE */
+       hw->phy.ops.write_phy_reg(hw, 0x1F31, 0xB814);
+       /* Disable adaptive fixed FFE (Default) */
+       hw->phy.ops.write_phy_reg(hw, 0x1F35, 0x002A);
+       /* Enable FFE hysteresis */
+       hw->phy.ops.write_phy_reg(hw, 0x1F3E, 0x0067);
+       /* Fixed FFE for short cable lengths */
+       hw->phy.ops.write_phy_reg(hw, 0x1F54, 0x0065);
+       /* Fixed FFE for medium cable lengths */
+       hw->phy.ops.write_phy_reg(hw, 0x1F55, 0x002A);
+       /* Fixed FFE for long cable lengths */
+       hw->phy.ops.write_phy_reg(hw, 0x1F56, 0x002A);
+       /* Enable Adaptive Clip Threshold */
+       hw->phy.ops.write_phy_reg(hw, 0x1F72, 0x3FB0);
+       /* AHT reset limit to 1 */
+       hw->phy.ops.write_phy_reg(hw, 0x1F76, 0xC0FF);
+       /* Set AHT master delay to 127 msec */
+       hw->phy.ops.write_phy_reg(hw, 0x1F77, 0x1DEC);
+       /* Set scan bits for AHT */
+       hw->phy.ops.write_phy_reg(hw, 0x1F78, 0xF9EF);
+       /* Set AHT Preset bits */
+       hw->phy.ops.write_phy_reg(hw, 0x1F79, 0x0210);
+       /* Change integ_factor of channel A to 3 */
+       hw->phy.ops.write_phy_reg(hw, 0x1895, 0x0003);
+       /* Change prop_factor of channels BCD to 8 */
+       hw->phy.ops.write_phy_reg(hw, 0x1796, 0x0008);
+       /* Change cg_icount + enable integbp for channels BCD */
+       hw->phy.ops.write_phy_reg(hw, 0x1798, 0xD008);
+       /*
+        * Change cg_icount + enable integbp + change prop_factor_master
+        * to 8 for channel A
+        */
+       hw->phy.ops.write_phy_reg(hw, 0x1898, 0xD918);
+       /* Disable AHT in Slave mode on channel A */
+       hw->phy.ops.write_phy_reg(hw, 0x187A, 0x0800);
+       /*
+        * Enable LPLU and disable AN to 1000 in non-D0a states,
+        * Enable SPD+B2B
+        */
+       hw->phy.ops.write_phy_reg(hw, 0x0019, 0x008D);
+       /* Enable restart AN on an1000_dis change */
+       hw->phy.ops.write_phy_reg(hw, 0x001B, 0x2080);
+       /* Enable wh_fifo read clock in 10/100 modes */
+       hw->phy.ops.write_phy_reg(hw, 0x0014, 0x0045);
+       /* Restart AN, Speed selection is 1000 */
+       hw->phy.ops.write_phy_reg(hw, 0x0000, 0x1340);
+
+       return 0;
+}
+
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
new file mode 100644 (file)
index 0000000..8f8fe0a
--- /dev/null
@@ -0,0 +1,98 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_PHY_H_
+#define _E1000_PHY_H_
+
+enum e1000_ms_type {
+       e1000_ms_hw_default = 0,
+       e1000_ms_force_master,
+       e1000_ms_force_slave,
+       e1000_ms_auto
+};
+
+enum e1000_smart_speed {
+       e1000_smart_speed_default = 0,
+       e1000_smart_speed_on,
+       e1000_smart_speed_off
+};
+
+s32  igb_check_downshift(struct e1000_hw *hw);
+s32  igb_check_reset_block(struct e1000_hw *hw);
+s32  igb_copper_link_autoneg(struct e1000_hw *hw);
+s32  igb_phy_force_speed_duplex(struct e1000_hw *hw);
+s32  igb_copper_link_setup_igp(struct e1000_hw *hw);
+s32  igb_copper_link_setup_m88(struct e1000_hw *hw);
+s32  igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
+s32  igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
+s32  igb_get_cable_length_m88(struct e1000_hw *hw);
+s32  igb_get_cable_length_igp_2(struct e1000_hw *hw);
+s32  igb_get_phy_id(struct e1000_hw *hw);
+s32  igb_get_phy_info_igp(struct e1000_hw *hw);
+s32  igb_get_phy_info_m88(struct e1000_hw *hw);
+s32  igb_phy_sw_reset(struct e1000_hw *hw);
+s32  igb_phy_hw_reset(struct e1000_hw *hw);
+s32  igb_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
+s32  igb_set_d3_lplu_state(struct e1000_hw *hw, bool active);
+s32  igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
+s32  igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
+                               u32 usec_interval, bool *success);
+s32  igb_phy_init_script_igp3(struct e1000_hw *hw);
+
+/* IGP01E1000 Specific Registers */
+#define IGP01E1000_PHY_PORT_CONFIG        0x10 /* Port Config */
+#define IGP01E1000_PHY_PORT_STATUS        0x11 /* Status */
+#define IGP01E1000_PHY_PORT_CTRL          0x12 /* Control */
+#define IGP01E1000_PHY_LINK_HEALTH        0x13 /* PHY Link Health */
+#define IGP02E1000_PHY_POWER_MGMT         0x19 /* Power Management */
+#define IGP01E1000_PHY_PAGE_SELECT        0x1F /* Page Select */
+#define IGP01E1000_PHY_PCS_INIT_REG       0x00B4
+#define IGP01E1000_PHY_POLARITY_MASK      0x0078
+#define IGP01E1000_PSCR_AUTO_MDIX         0x1000
+#define IGP01E1000_PSCR_FORCE_MDI_MDIX    0x2000 /* 0=MDI, 1=MDIX */
+#define IGP01E1000_PSCFR_SMART_SPEED      0x0080
+
+/* Enable flexible speed on link-up */
+#define IGP02E1000_PM_D0_LPLU             0x0002 /* For D0a states */
+#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_SPEED_MASK        0xC000
+#define IGP01E1000_PSSR_SPEED_1000MBPS    0xC000
+#define IGP02E1000_PHY_CHANNEL_NUM        4
+#define IGP02E1000_PHY_AGC_A              0x11B1
+#define IGP02E1000_PHY_AGC_B              0x12B1
+#define IGP02E1000_PHY_AGC_C              0x14B1
+#define IGP02E1000_PHY_AGC_D              0x18B1
+#define IGP02E1000_AGC_LENGTH_SHIFT       9   /* Course - 15:13, Fine - 12:9 */
+#define IGP02E1000_AGC_LENGTH_MASK        0x7F
+#define IGP02E1000_AGC_RANGE              15
+
+#define E1000_CABLE_LENGTH_UNDEFINED      0xFF
+
+#endif
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
new file mode 100644 (file)
index 0000000..ff187b7
--- /dev/null
@@ -0,0 +1,270 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 _E1000_REGS_H_
+#define _E1000_REGS_H_
+
+#define E1000_CTRL     0x00000  /* Device Control - RW */
+#define E1000_STATUS   0x00008  /* Device Status - RO */
+#define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
+#define E1000_EERD     0x00014  /* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
+#define E1000_MDIC     0x00020  /* MDI Control - RW */
+#define E1000_SCTL     0x00024  /* SerDes Control - RW */
+#define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
+#define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
+#define E1000_FCT      0x00030  /* Flow Control Type - RW */
+#define E1000_CONNSW   0x00034  /* Copper/Fiber switch control - RW */
+#define E1000_VET      0x00038  /* VLAN Ether Type - RW */
+#define E1000_ICR      0x000C0  /* Interrupt Cause Read - R/clr */
+#define E1000_ITR      0x000C4  /* Interrupt Throttling Rate - RW */
+#define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
+#define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
+#define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
+#define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
+#define E1000_RCTL     0x00100  /* RX Control - RW */
+#define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
+#define E1000_EICR     0x01580  /* Ext. Interrupt Cause Read - R/clr */
+#define E1000_EITR(_n) (0x01680 + (0x4 * (_n)))
+#define E1000_EICS     0x01520  /* Ext. Interrupt Cause Set - W0 */
+#define E1000_EIMS     0x01524  /* Ext. Interrupt Mask Set/Read - RW */
+#define E1000_EIMC     0x01528  /* Ext. Interrupt Mask Clear - WO */
+#define E1000_EIAC     0x0152C  /* Ext. Interrupt Auto Clear - RW */
+#define E1000_EIAM     0x01530  /* Ext. Interrupt Ack Auto Clear Mask - RW */
+#define E1000_TCTL     0x00400  /* TX Control - RW */
+#define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */
+#define E1000_TIPG     0x00410  /* TX Inter-packet gap -RW */
+#define E1000_AIT      0x00458  /* Adaptive Interframe Spacing Throttle - RW */
+#define E1000_LEDCTL   0x00E00  /* LED Control - RW */
+#define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
+#define E1000_PBS      0x01008  /* Packet Buffer Size */
+#define E1000_EEMNGCTL 0x01010  /* MNG EEprom Control */
+#define E1000_EEWR     0x0102C  /* EEPROM Write Register - RW */
+#define E1000_I2CCMD   0x01028  /* SFPI2C Command Register - RW */
+#define E1000_FRTIMER  0x01048  /* Free Running Timer - RW */
+#define E1000_TCPTIMER 0x0104C  /* TCP Timer - RW */
+#define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
+#define E1000_RDFPCQ(_n)  (0x02430 + (0x4 * (_n)))
+#define E1000_FCRTV    0x02460  /* Flow Control Refresh Timer Value - RW */
+/* Split and Replication RX Control - RW */
+/*
+ * Convenience macros
+ *
+ * Note: "_n" is the queue number of the register to be written to.
+ *
+ * Example usage:
+ * E1000_RDBAL_REG(current_rx_queue)
+ */
+#define E1000_RDBAL(_n)   ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) \
+                                   : (0x0C000 + ((_n) * 0x40)))
+#define E1000_RDBAH(_n)   ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) \
+                                   : (0x0C004 + ((_n) * 0x40)))
+#define E1000_RDLEN(_n)   ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) \
+                                   : (0x0C008 + ((_n) * 0x40)))
+#define E1000_SRRCTL(_n)  ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) \
+                                   : (0x0C00C + ((_n) * 0x40)))
+#define E1000_RDH(_n)     ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) \
+                                   : (0x0C010 + ((_n) * 0x40)))
+#define E1000_RDT(_n)     ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) \
+                                   : (0x0C018 + ((_n) * 0x40)))
+#define E1000_RXDCTL(_n)  ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) \
+                                   : (0x0C028 + ((_n) * 0x40)))
+#define E1000_TDBAL(_n)   ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) \
+                                   : (0x0E000 + ((_n) * 0x40)))
+#define E1000_TDBAH(_n)   ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) \
+                                   : (0x0E004 + ((_n) * 0x40)))
+#define E1000_TDLEN(_n)   ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) \
+                                   : (0x0E008 + ((_n) * 0x40)))
+#define E1000_TDH(_n)     ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) \
+                                   : (0x0E010 + ((_n) * 0x40)))
+#define E1000_TDT(_n)     ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) \
+                                   : (0x0E018 + ((_n) * 0x40)))
+#define E1000_TXDCTL(_n)  ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \
+                                   : (0x0E028 + ((_n) * 0x40)))
+#define E1000_TARC(_n)    (0x03840 + (_n << 8))
+#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8))
+#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
+#define E1000_TDWBAL(_n)  ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \
+                                   : (0x0E038 + ((_n) * 0x40)))
+#define E1000_TDWBAH(_n)  ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \
+                                   : (0x0E03C + ((_n) * 0x40)))
+#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
+#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
+#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
+#define E1000_DTXCTL   0x03590  /* DMA TX Control - RW */
+#define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
+#define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
+#define E1000_RXERRC   0x0400C  /* Receive Error Count - R/clr */
+#define E1000_MPC      0x04010  /* Missed Packet Count - R/clr */
+#define E1000_SCC      0x04014  /* Single Collision Count - R/clr */
+#define E1000_ECOL     0x04018  /* Excessive Collision Count - R/clr */
+#define E1000_MCC      0x0401C  /* Multiple Collision Count - R/clr */
+#define E1000_LATECOL  0x04020  /* Late Collision Count - R/clr */
+#define E1000_COLC     0x04028  /* Collision Count - R/clr */
+#define E1000_DC       0x04030  /* Defer Count - R/clr */
+#define E1000_TNCRS    0x04034  /* TX-No CRS - R/clr */
+#define E1000_SEC      0x04038  /* Sequence Error Count - R/clr */
+#define E1000_CEXTERR  0x0403C  /* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC     0x04040  /* Receive Length Error Count - R/clr */
+#define E1000_XONRXC   0x04048  /* XON RX Count - R/clr */
+#define E1000_XONTXC   0x0404C  /* XON TX Count - R/clr */
+#define E1000_XOFFRXC  0x04050  /* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC  0x04054  /* XOFF TX Count - R/clr */
+#define E1000_FCRUC    0x04058  /* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64    0x0405C  /* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127   0x04060  /* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255   0x04064  /* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511   0x04068  /* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023  0x0406C  /* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522  0x04070  /* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC     0x04074  /* Good Packets RX Count - R/clr */
+#define E1000_BPRC     0x04078  /* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC     0x0407C  /* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC     0x04080  /* Good Packets TX Count - R/clr */
+#define E1000_GORCL    0x04088  /* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH    0x0408C  /* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL    0x04090  /* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH    0x04094  /* Good Octets TX Count High - R/clr */
+#define E1000_RNBC     0x040A0  /* RX No Buffers Count - R/clr */
+#define E1000_RUC      0x040A4  /* RX Undersize Count - R/clr */
+#define E1000_RFC      0x040A8  /* RX Fragment Count - R/clr */
+#define E1000_ROC      0x040AC  /* RX Oversize Count - R/clr */
+#define E1000_RJC      0x040B0  /* RX Jabber Count - R/clr */
+#define E1000_MGTPRC   0x040B4  /* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC   0x040B8  /* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC   0x040BC  /* Management Packets TX Count - R/clr */
+#define E1000_TORL     0x040C0  /* Total Octets RX Low - R/clr */
+#define E1000_TORH     0x040C4  /* Total Octets RX High - R/clr */
+#define E1000_TOTL     0x040C8  /* Total Octets TX Low - R/clr */
+#define E1000_TOTH     0x040CC  /* Total Octets TX High - R/clr */
+#define E1000_TPR      0x040D0  /* Total Packets RX - R/clr */
+#define E1000_TPT      0x040D4  /* Total Packets TX - R/clr */
+#define E1000_PTC64    0x040D8  /* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127   0x040DC  /* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255   0x040E0  /* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511   0x040E4  /* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023  0x040E8  /* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522  0x040EC  /* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC     0x040F0  /* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_IAC      0x04100  /* Interrupt Assertion Count */
+/* Interrupt Cause Rx Packet Timer Expire Count */
+#define E1000_ICRXPTC  0x04104
+/* Interrupt Cause Rx Absolute Timer Expire Count */
+#define E1000_ICRXATC  0x04108
+/* Interrupt Cause Tx Packet Timer Expire Count */
+#define E1000_ICTXPTC  0x0410C
+/* Interrupt Cause Tx Absolute Timer Expire Count */
+#define E1000_ICTXATC  0x04110
+/* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQEC  0x04118
+/* Interrupt Cause Tx Queue Minimum Threshold Count */
+#define E1000_ICTXQMTC 0x0411C
+/* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+#define E1000_ICRXDMTC 0x04120
+#define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
+#define E1000_PCS_CFG0    0x04200  /* PCS Configuration 0 - RW */
+#define E1000_PCS_LCTL    0x04208  /* PCS Link Control - RW */
+#define E1000_PCS_LSTAT   0x0420C  /* PCS Link Status - RO */
+#define E1000_CBTMPC      0x0402C  /* Circuit Breaker TX Packet Count */
+#define E1000_HTDPMC      0x0403C  /* Host Transmit Discarded Packets */
+#define E1000_CBRMPC      0x040FC  /* Circuit Breaker RX Packet Count */
+#define E1000_RPTHC       0x04104  /* Rx Packets To Host */
+#define E1000_HGPTC       0x04118  /* Host Good Packets TX Count */
+#define E1000_HTCBDPC     0x04124  /* Host TX Circuit Breaker Dropped Count */
+#define E1000_HGORCL      0x04128  /* Host Good Octets Received Count Low */
+#define E1000_HGORCH      0x0412C  /* Host Good Octets Received Count High */
+#define E1000_HGOTCL      0x04130  /* Host Good Octets Transmit Count Low */
+#define E1000_HGOTCH      0x04134  /* Host Good Octets Transmit Count High */
+#define E1000_LENERRS     0x04138  /* Length Errors Count */
+#define E1000_SCVPC       0x04228  /* SerDes/SGMII Code Violation Pkt Count */
+#define E1000_PCS_ANADV   0x04218  /* AN advertisement - RW */
+#define E1000_PCS_LPAB    0x0421C  /* Link Partner Ability - RW */
+#define E1000_PCS_NPTX    0x04220  /* AN Next Page Transmit - RW */
+#define E1000_PCS_LPABNP  0x04224  /* Link Partner Ability Next Page - RW */
+#define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
+#define E1000_RLPML    0x05004  /* RX Long Packet Max Length */
+#define E1000_RFCTL    0x05008  /* Receive Filter Control*/
+#define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
+#define E1000_RA       0x05400  /* Receive Address - RW Array */
+#define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
+#define E1000_VMD_CTL  0x0581C  /* VMDq Control - RW */
+#define E1000_WUC      0x05800  /* Wakeup Control - RW */
+#define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
+#define E1000_WUS      0x05810  /* Wakeup Status - RO */
+#define E1000_MANC     0x05820  /* Management Control - RW */
+#define E1000_IPAV     0x05838  /* IP Address Valid - RW */
+#define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
+#define E1000_HOST_IF  0x08800  /* Host Interface */
+
+#define E1000_MANC2H      0x05860 /* Management Control To Host - RW */
+#define E1000_SW_FW_SYNC  0x05B5C /* Software-Firmware Synchronization - RW */
+#define E1000_CCMCTL      0x05B48 /* CCM Control Register */
+#define E1000_GIOCTL      0x05B44 /* GIO Analog Control Register */
+#define E1000_SCCTL       0x05B4C /* PCIc PLL Configuration Register */
+#define E1000_FACTPS    0x05B30 /* Function Active and Power State to MNG */
+#define E1000_SWSM      0x05B50 /* SW Semaphore */
+#define E1000_FWSM      0x05B54 /* FW Semaphore */
+#define E1000_HICR      0x08F00 /* Host Inteface Control */
+
+/* RSS registers */
+#define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
+#define E1000_IMIR(_i)      (0x05A80 + ((_i) * 4))  /* Immediate Interrupt */
+#define E1000_IMIREXT(_i)   (0x05AA0 + ((_i) * 4))  /* Immediate Interrupt Ext*/
+#define E1000_IMIRVP    0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
+/* MSI-X Allocation Register (_i) - RW */
+#define E1000_MSIXBM(_i)    (0x01600 + ((_i) * 4))
+/* MSI-X Table entry addr low reg 0 - RW */
+#define E1000_MSIXTADD(_i)  (0x0C000 + ((_i) * 0x10))
+/* MSI-X Table entry addr upper reg 0 - RW */
+#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
+/* MSI-X Table entry message reg 0 - RW */
+#define E1000_MSIXTMSG(_i)  (0x0C008 + ((_i) * 0x10))
+/* MSI-X Table entry vector ctrl reg 0 - RW */
+#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
+/* Redirection Table - RW Array */
+#define E1000_RETA(_i)  (0x05C00 + ((_i) * 4))
+#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
+
+#define E1000_REGISTER(a, reg) reg
+
+#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
+#define rd32(reg) (readl(hw->hw_addr + reg))
+#define wrfl() ((void)rd32(E1000_STATUS))
+
+#define array_wr32(reg, offset, value) \
+       (writel(value, hw->hw_addr + reg + ((offset) << 2)))
+#define array_rd32(reg, offset) \
+       (readl(hw->hw_addr + reg + ((offset) << 2)))
+
+#endif
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
new file mode 100644 (file)
index 0000000..6b2e7d3
--- /dev/null
@@ -0,0 +1,300 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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
+
+*******************************************************************************/
+
+
+/* Linux PRO/1000 Ethernet Driver main header file */
+
+#ifndef _IGB_H_
+#define _IGB_H_
+
+#include "e1000_mac.h"
+#include "e1000_82575.h"
+
+struct igb_adapter;
+
+/* Interrupt defines */
+#define IGB_MAX_TX_CLEAN 72
+
+#define IGB_MIN_DYN_ITR 3000
+#define IGB_MAX_DYN_ITR 96000
+#define IGB_START_ITR 6000
+
+#define IGB_DYN_ITR_PACKET_THRESHOLD 2
+#define IGB_DYN_ITR_LENGTH_LOW 200
+#define IGB_DYN_ITR_LENGTH_HIGH 1000
+
+/* TX/RX descriptor defines */
+#define IGB_DEFAULT_TXD                  256
+#define IGB_MIN_TXD                       80
+#define IGB_MAX_TXD                     4096
+
+#define IGB_DEFAULT_RXD                  256
+#define IGB_MIN_RXD                       80
+#define IGB_MAX_RXD                     4096
+
+#define IGB_DEFAULT_ITR                    3 /* dynamic */
+#define IGB_MAX_ITR_USECS              10000
+#define IGB_MIN_ITR_USECS                 10
+
+/* Transmit and receive queues */
+#define IGB_MAX_RX_QUEUES                  4
+
+/* RX descriptor control thresholds.
+ * PTHRESH - MAC will consider prefetch if it has fewer than this number of
+ *           descriptors available in its onboard memory.
+ *           Setting this to 0 disables RX descriptor prefetch.
+ * HTHRESH - MAC will only prefetch if there are at least this many descriptors
+ *           available in host memory.
+ *           If PTHRESH is 0, this should also be 0.
+ * WTHRESH - RX descriptor writeback threshold - MAC will delay writing back
+ *           descriptors until either it has this many to write back, or the
+ *           ITR timer expires.
+ */
+#define IGB_RX_PTHRESH                    16
+#define IGB_RX_HTHRESH                     8
+#define IGB_RX_WTHRESH                     1
+
+/* this is the size past which hardware will drop packets when setting LPE=0 */
+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
+
+/* Supported Rx Buffer Sizes */
+#define IGB_RXBUFFER_128   128    /* Used for packet split */
+#define IGB_RXBUFFER_256   256    /* Used for packet split */
+#define IGB_RXBUFFER_512   512
+#define IGB_RXBUFFER_1024  1024
+#define IGB_RXBUFFER_2048  2048
+#define IGB_RXBUFFER_4096  4096
+#define IGB_RXBUFFER_8192  8192
+#define IGB_RXBUFFER_16384 16384
+
+/* Packet Buffer allocations */
+
+
+/* How many Tx Descriptors do we need to call netif_wake_queue ? */
+#define IGB_TX_QUEUE_WAKE      16
+/* How many Rx Buffers do we bundle into one write to the hardware ? */
+#define IGB_RX_BUFFER_WRITE    16      /* Must be power of 2 */
+
+#define AUTO_ALL_MODES            0
+#define IGB_EEPROM_APME         0x0400
+
+#ifndef IGB_MASTER_SLAVE
+/* Switch to override PHY master/slave setting */
+#define IGB_MASTER_SLAVE       e1000_ms_hw_default
+#endif
+
+#define IGB_MNG_VLAN_NONE -1
+
+/* wrapper around a pointer to a socket buffer,
+ * so a DMA handle can be stored along with the buffer */
+struct igb_buffer {
+       struct sk_buff *skb;
+       dma_addr_t dma;
+       union {
+               /* TX */
+               struct {
+                       unsigned long time_stamp;
+                       u32 length;
+               };
+               /* RX */
+               struct {
+                       struct page *page;
+                       u64 page_dma;
+               };
+       };
+};
+
+struct igb_queue_stats {
+       u64 packets;
+       u64 bytes;
+};
+
+struct igb_ring {
+       struct igb_adapter *adapter; /* backlink */
+       void *desc;                  /* descriptor ring memory */
+       dma_addr_t dma;              /* phys address of the ring */
+       unsigned int size;           /* length of desc. ring in bytes */
+       unsigned int count;          /* number of desc. in the ring */
+       u16 next_to_use;
+       u16 next_to_clean;
+       u16 head;
+       u16 tail;
+       struct igb_buffer *buffer_info; /* array of buffer info structs */
+
+       u32 eims_value;
+       u32 itr_val;
+       u16 itr_register;
+       u16 cpu;
+
+       unsigned int total_bytes;
+       unsigned int total_packets;
+
+       union {
+               /* TX */
+               struct {
+                       spinlock_t tx_clean_lock;
+                       spinlock_t tx_lock;
+                       bool detect_tx_hung;
+               };
+               /* RX */
+               struct {
+                       /* arrays of page information for packet split */
+                       struct sk_buff *pending_skb;
+                       int pending_skb_page;
+                       int no_itr_adjust;
+                       struct igb_queue_stats rx_stats;
+                       struct napi_struct napi;
+               };
+       };
+
+       char name[IFNAMSIZ + 5];
+};
+
+#define IGB_DESC_UNUSED(R) \
+       ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+       (R)->next_to_clean - (R)->next_to_use - 1)
+
+#define E1000_RX_DESC_ADV(R, i)            \
+       (&(((union e1000_adv_rx_desc *)((R).desc))[i]))
+#define E1000_TX_DESC_ADV(R, i)            \
+       (&(((union e1000_adv_tx_desc *)((R).desc))[i]))
+#define E1000_TX_CTXTDESC_ADV(R, i)        \
+       (&(((struct e1000_adv_tx_context_desc *)((R).desc))[i]))
+#define E1000_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
+#define E1000_TX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_tx_desc)
+#define E1000_RX_DESC(R, i)            E1000_GET_DESC(R, i, e1000_rx_desc)
+
+/* board specific private data structure */
+
+struct igb_adapter {
+       struct timer_list watchdog_timer;
+       struct timer_list phy_info_timer;
+       struct vlan_group *vlgrp;
+       u16 mng_vlan_id;
+       u32 bd_number;
+       u32 rx_buffer_len;
+       u32 wol;
+       u32 en_mng_pt;
+       u16 link_speed;
+       u16 link_duplex;
+       unsigned int total_tx_bytes;
+       unsigned int total_tx_packets;
+       unsigned int total_rx_bytes;
+       unsigned int total_rx_packets;
+       /* Interrupt Throttle Rate */
+       u32 itr;
+       u32 itr_setting;
+       u16 tx_itr;
+       u16 rx_itr;
+       int set_itr;
+
+       struct work_struct reset_task;
+       struct work_struct watchdog_task;
+       bool fc_autoneg;
+       u8  tx_timeout_factor;
+       struct timer_list blink_timer;
+       unsigned long led_status;
+
+       /* TX */
+       struct igb_ring *tx_ring;      /* One per active queue */
+       unsigned int restart_queue;
+       unsigned long tx_queue_len;
+       u32 txd_cmd;
+       u32 gotc;
+       u64 gotc_old;
+       u64 tpt_old;
+       u64 colc_old;
+       u32 tx_timeout_count;
+
+       /* RX */
+       struct igb_ring *rx_ring;      /* One per active queue */
+       int num_tx_queues;
+       int num_rx_queues;
+
+       u64 hw_csum_err;
+       u64 hw_csum_good;
+       u64 rx_hdr_split;
+       u32 alloc_rx_buff_failed;
+       bool rx_csum;
+       u32 gorc;
+       u64 gorc_old;
+       u16 rx_ps_hdr_size;
+       u32 max_frame_size;
+       u32 min_frame_size;
+
+       /* OS defined structs */
+       struct net_device *netdev;
+       struct napi_struct napi;
+       struct pci_dev *pdev;
+       struct net_device_stats net_stats;
+
+       /* structs defined in e1000_hw.h */
+       struct e1000_hw hw;
+       struct e1000_hw_stats stats;
+       struct e1000_phy_info phy_info;
+       struct e1000_phy_stats phy_stats;
+
+       u32 test_icr;
+       struct igb_ring test_tx_ring;
+       struct igb_ring test_rx_ring;
+
+       int msg_enable;
+       struct msix_entry *msix_entries;
+       u32 eims_enable_mask;
+
+       /* to not mess up cache alignment, always add to the bottom */
+       unsigned long state;
+       unsigned int msi_enabled;
+
+       u32 eeprom_wol;
+};
+
+enum e1000_state_t {
+       __IGB_TESTING,
+       __IGB_RESETTING,
+       __IGB_DOWN
+};
+
+enum igb_boards {
+       board_82575,
+};
+
+extern char igb_driver_name[];
+extern char igb_driver_version[];
+
+extern char *igb_get_hw_dev_name(struct e1000_hw *hw);
+extern int igb_up(struct igb_adapter *);
+extern void igb_down(struct igb_adapter *);
+extern void igb_reinit_locked(struct igb_adapter *);
+extern void igb_reset(struct igb_adapter *);
+extern int igb_set_spd_dplx(struct igb_adapter *, u16);
+extern int igb_setup_tx_resources(struct igb_adapter *, struct igb_ring *);
+extern int igb_setup_rx_resources(struct igb_adapter *, struct igb_ring *);
+extern void igb_update_stats(struct igb_adapter *);
+extern void igb_set_ethtool_ops(struct net_device *);
+
+#endif /* _IGB_H_ */
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
new file mode 100644 (file)
index 0000000..f69721e
--- /dev/null
@@ -0,0 +1,1927 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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
+
+*******************************************************************************/
+
+/* ethtool support for igb */
+
+#include <linux/vmalloc.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/ethtool.h>
+
+#include "igb.h"
+
+struct igb_stats {
+       char stat_string[ETH_GSTRING_LEN];
+       int sizeof_stat;
+       int stat_offset;
+};
+
+#define IGB_STAT(m) sizeof(((struct igb_adapter *)0)->m), \
+                     offsetof(struct igb_adapter, m)
+static const struct igb_stats igb_gstrings_stats[] = {
+       { "rx_packets", IGB_STAT(stats.gprc) },
+       { "tx_packets", IGB_STAT(stats.gptc) },
+       { "rx_bytes", IGB_STAT(stats.gorc) },
+       { "tx_bytes", IGB_STAT(stats.gotc) },
+       { "rx_broadcast", IGB_STAT(stats.bprc) },
+       { "tx_broadcast", IGB_STAT(stats.bptc) },
+       { "rx_multicast", IGB_STAT(stats.mprc) },
+       { "tx_multicast", IGB_STAT(stats.mptc) },
+       { "rx_errors", IGB_STAT(net_stats.rx_errors) },
+       { "tx_errors", IGB_STAT(net_stats.tx_errors) },
+       { "tx_dropped", IGB_STAT(net_stats.tx_dropped) },
+       { "multicast", IGB_STAT(stats.mprc) },
+       { "collisions", IGB_STAT(stats.colc) },
+       { "rx_length_errors", IGB_STAT(net_stats.rx_length_errors) },
+       { "rx_over_errors", IGB_STAT(net_stats.rx_over_errors) },
+       { "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_missed_errors", IGB_STAT(stats.mpc) },
+       { "tx_aborted_errors", IGB_STAT(stats.ecol) },
+       { "tx_carrier_errors", IGB_STAT(stats.tncrs) },
+       { "tx_fifo_errors", IGB_STAT(net_stats.tx_fifo_errors) },
+       { "tx_heartbeat_errors", IGB_STAT(net_stats.tx_heartbeat_errors) },
+       { "tx_window_errors", IGB_STAT(stats.latecol) },
+       { "tx_abort_late_coll", IGB_STAT(stats.latecol) },
+       { "tx_deferred_ok", IGB_STAT(stats.dc) },
+       { "tx_single_coll_ok", IGB_STAT(stats.scc) },
+       { "tx_multi_coll_ok", IGB_STAT(stats.mcc) },
+       { "tx_timeout_count", IGB_STAT(tx_timeout_count) },
+       { "tx_restart_queue", IGB_STAT(restart_queue) },
+       { "rx_long_length_errors", IGB_STAT(stats.roc) },
+       { "rx_short_length_errors", IGB_STAT(stats.ruc) },
+       { "rx_align_errors", IGB_STAT(stats.algnerrc) },
+       { "tx_tcp_seg_good", IGB_STAT(stats.tsctc) },
+       { "tx_tcp_seg_failed", IGB_STAT(stats.tsctfc) },
+       { "rx_flow_control_xon", IGB_STAT(stats.xonrxc) },
+       { "rx_flow_control_xoff", IGB_STAT(stats.xoffrxc) },
+       { "tx_flow_control_xon", IGB_STAT(stats.xontxc) },
+       { "tx_flow_control_xoff", IGB_STAT(stats.xofftxc) },
+       { "rx_long_byte_count", IGB_STAT(stats.gorc) },
+       { "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
+       { "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
+       { "rx_header_split", IGB_STAT(rx_hdr_split) },
+       { "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
+       { "tx_smbus", IGB_STAT(stats.mgptc) },
+       { "rx_smbus", IGB_STAT(stats.mgprc) },
+       { "dropped_smbus", IGB_STAT(stats.mgpdc) },
+};
+
+#define IGB_QUEUE_STATS_LEN \
+       ((((((struct igb_adapter *)netdev->priv)->num_rx_queues > 1) ? \
+         ((struct igb_adapter *)netdev->priv)->num_rx_queues : 0) + \
+        (((((struct igb_adapter *)netdev->priv)->num_tx_queues > 1) ? \
+         ((struct igb_adapter *)netdev->priv)->num_tx_queues : 0))) * \
+       (sizeof(struct igb_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)
+static const char igb_gstrings_test[][ETH_GSTRING_LEN] = {
+       "Register test  (offline)", "Eeprom test    (offline)",
+       "Interrupt test (offline)", "Loopback test  (offline)",
+       "Link test   (on/offline)"
+};
+#define IGB_TEST_LEN sizeof(igb_gstrings_test) / ETH_GSTRING_LEN
+
+static int igb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (hw->phy.media_type == e1000_media_type_copper) {
+
+               ecmd->supported = (SUPPORTED_10baseT_Half |
+                                  SUPPORTED_10baseT_Full |
+                                  SUPPORTED_100baseT_Half |
+                                  SUPPORTED_100baseT_Full |
+                                  SUPPORTED_1000baseT_Full|
+                                  SUPPORTED_Autoneg |
+                                  SUPPORTED_TP);
+               ecmd->advertising = ADVERTISED_TP;
+
+               if (hw->mac.autoneg == 1) {
+                       ecmd->advertising |= ADVERTISED_Autoneg;
+                       /* the e1000 autoneg seems to match ethtool nicely */
+                       ecmd->advertising |= hw->phy.autoneg_advertised;
+               }
+
+               ecmd->port = PORT_TP;
+               ecmd->phy_address = hw->phy.addr;
+       } else {
+               ecmd->supported   = (SUPPORTED_1000baseT_Full |
+                                    SUPPORTED_FIBRE |
+                                    SUPPORTED_Autoneg);
+
+               ecmd->advertising = (ADVERTISED_1000baseT_Full |
+                                    ADVERTISED_FIBRE |
+                                    ADVERTISED_Autoneg);
+
+               ecmd->port = PORT_FIBRE;
+       }
+
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       if (rd32(E1000_STATUS) & E1000_STATUS_LU) {
+
+               adapter->hw.mac.ops.get_speed_and_duplex(hw,
+                                       &adapter->link_speed,
+                                       &adapter->link_duplex);
+               ecmd->speed = adapter->link_speed;
+
+               /* unfortunately FULL_DUPLEX != DUPLEX_FULL
+                *          and HALF_DUPLEX != DUPLEX_HALF */
+
+               if (adapter->link_duplex == FULL_DUPLEX)
+                       ecmd->duplex = DUPLEX_FULL;
+               else
+                       ecmd->duplex = DUPLEX_HALF;
+       } else {
+               ecmd->speed = -1;
+               ecmd->duplex = -1;
+       }
+
+       ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
+                        hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+       return 0;
+}
+
+static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       /* When SoL/IDER sessions are active, autoneg/speed/duplex
+        * cannot be changed */
+       if (igb_check_reset_block(hw)) {
+               dev_err(&adapter->pdev->dev, "Cannot change link "
+                       "characteristics when SoL/IDER is active.\n");
+               return -EINVAL;
+       }
+
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (ecmd->autoneg == AUTONEG_ENABLE) {
+               hw->mac.autoneg = 1;
+               if (hw->phy.media_type == e1000_media_type_fiber)
+                       hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
+                                                    ADVERTISED_FIBRE |
+                                                    ADVERTISED_Autoneg;
+               else
+                       hw->phy.autoneg_advertised = ecmd->advertising |
+                                                    ADVERTISED_TP |
+                                                    ADVERTISED_Autoneg;
+               ecmd->advertising = hw->phy.autoneg_advertised;
+       } else
+               if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+                       clear_bit(__IGB_RESETTING, &adapter->state);
+                       return -EINVAL;
+               }
+
+       /* reset the link */
+
+       if (netif_running(adapter->netdev)) {
+               igb_down(adapter);
+               igb_up(adapter);
+       } else
+               igb_reset(adapter);
+
+       clear_bit(__IGB_RESETTING, &adapter->state);
+       return 0;
+}
+
+static void igb_get_pauseparam(struct net_device *netdev,
+                              struct ethtool_pauseparam *pause)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       pause->autoneg =
+               (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
+
+       if (hw->fc.type == e1000_fc_rx_pause)
+               pause->rx_pause = 1;
+       else if (hw->fc.type == e1000_fc_tx_pause)
+               pause->tx_pause = 1;
+       else if (hw->fc.type == e1000_fc_full) {
+               pause->rx_pause = 1;
+               pause->tx_pause = 1;
+       }
+}
+
+static int igb_set_pauseparam(struct net_device *netdev,
+                             struct ethtool_pauseparam *pause)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       int retval = 0;
+
+       adapter->fc_autoneg = pause->autoneg;
+
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (pause->rx_pause && pause->tx_pause)
+               hw->fc.type = e1000_fc_full;
+       else if (pause->rx_pause && !pause->tx_pause)
+               hw->fc.type = e1000_fc_rx_pause;
+       else if (!pause->rx_pause && pause->tx_pause)
+               hw->fc.type = e1000_fc_tx_pause;
+       else if (!pause->rx_pause && !pause->tx_pause)
+               hw->fc.type = e1000_fc_none;
+
+       hw->fc.original_type = hw->fc.type;
+
+       if (adapter->fc_autoneg == AUTONEG_ENABLE) {
+               if (netif_running(adapter->netdev)) {
+                       igb_down(adapter);
+                       igb_up(adapter);
+               } else
+                       igb_reset(adapter);
+       } else
+               retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
+                         igb_setup_link(hw) : igb_force_mac_fc(hw));
+
+       clear_bit(__IGB_RESETTING, &adapter->state);
+       return retval;
+}
+
+static u32 igb_get_rx_csum(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       return adapter->rx_csum;
+}
+
+static int igb_set_rx_csum(struct net_device *netdev, u32 data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       adapter->rx_csum = data;
+
+       return 0;
+}
+
+static u32 igb_get_tx_csum(struct net_device *netdev)
+{
+       return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static int igb_set_tx_csum(struct net_device *netdev, u32 data)
+{
+       if (data)
+               netdev->features |= NETIF_F_HW_CSUM;
+       else
+               netdev->features &= ~NETIF_F_HW_CSUM;
+
+       return 0;
+}
+
+static int igb_set_tso(struct net_device *netdev, u32 data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       if (data)
+               netdev->features |= NETIF_F_TSO;
+       else
+               netdev->features &= ~NETIF_F_TSO;
+
+       if (data)
+               netdev->features |= NETIF_F_TSO6;
+       else
+               netdev->features &= ~NETIF_F_TSO6;
+
+       dev_info(&adapter->pdev->dev, "TSO is %s\n",
+                data ? "Enabled" : "Disabled");
+       return 0;
+}
+
+static u32 igb_get_msglevel(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       return adapter->msg_enable;
+}
+
+static void igb_set_msglevel(struct net_device *netdev, u32 data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       adapter->msg_enable = data;
+}
+
+static int igb_get_regs_len(struct net_device *netdev)
+{
+#define IGB_REGS_LEN 551
+       return IGB_REGS_LEN * sizeof(u32);
+}
+
+static void igb_get_regs(struct net_device *netdev,
+                        struct ethtool_regs *regs, void *p)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 *regs_buff = p;
+       u8 i;
+
+       memset(p, 0, IGB_REGS_LEN * sizeof(u32));
+
+       regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id;
+
+       /* General Registers */
+       regs_buff[0] = rd32(E1000_CTRL);
+       regs_buff[1] = rd32(E1000_STATUS);
+       regs_buff[2] = rd32(E1000_CTRL_EXT);
+       regs_buff[3] = rd32(E1000_MDIC);
+       regs_buff[4] = rd32(E1000_SCTL);
+       regs_buff[5] = rd32(E1000_CONNSW);
+       regs_buff[6] = rd32(E1000_VET);
+       regs_buff[7] = rd32(E1000_LEDCTL);
+       regs_buff[8] = rd32(E1000_PBA);
+       regs_buff[9] = rd32(E1000_PBS);
+       regs_buff[10] = rd32(E1000_FRTIMER);
+       regs_buff[11] = rd32(E1000_TCPTIMER);
+
+       /* NVM Register */
+       regs_buff[12] = rd32(E1000_EECD);
+
+       /* Interrupt */
+       regs_buff[13] = rd32(E1000_EICR);
+       regs_buff[14] = rd32(E1000_EICS);
+       regs_buff[15] = rd32(E1000_EIMS);
+       regs_buff[16] = rd32(E1000_EIMC);
+       regs_buff[17] = rd32(E1000_EIAC);
+       regs_buff[18] = rd32(E1000_EIAM);
+       regs_buff[19] = rd32(E1000_ICR);
+       regs_buff[20] = rd32(E1000_ICS);
+       regs_buff[21] = rd32(E1000_IMS);
+       regs_buff[22] = rd32(E1000_IMC);
+       regs_buff[23] = rd32(E1000_IAC);
+       regs_buff[24] = rd32(E1000_IAM);
+       regs_buff[25] = rd32(E1000_IMIRVP);
+
+       /* Flow Control */
+       regs_buff[26] = rd32(E1000_FCAL);
+       regs_buff[27] = rd32(E1000_FCAH);
+       regs_buff[28] = rd32(E1000_FCTTV);
+       regs_buff[29] = rd32(E1000_FCRTL);
+       regs_buff[30] = rd32(E1000_FCRTH);
+       regs_buff[31] = rd32(E1000_FCRTV);
+
+       /* Receive */
+       regs_buff[32] = rd32(E1000_RCTL);
+       regs_buff[33] = rd32(E1000_RXCSUM);
+       regs_buff[34] = rd32(E1000_RLPML);
+       regs_buff[35] = rd32(E1000_RFCTL);
+       regs_buff[36] = rd32(E1000_MRQC);
+       regs_buff[37] = rd32(E1000_VMD_CTL);
+
+       /* Transmit */
+       regs_buff[38] = rd32(E1000_TCTL);
+       regs_buff[39] = rd32(E1000_TCTL_EXT);
+       regs_buff[40] = rd32(E1000_TIPG);
+       regs_buff[41] = rd32(E1000_DTXCTL);
+
+       /* Wake Up */
+       regs_buff[42] = rd32(E1000_WUC);
+       regs_buff[43] = rd32(E1000_WUFC);
+       regs_buff[44] = rd32(E1000_WUS);
+       regs_buff[45] = rd32(E1000_IPAV);
+       regs_buff[46] = rd32(E1000_WUPL);
+
+       /* MAC */
+       regs_buff[47] = rd32(E1000_PCS_CFG0);
+       regs_buff[48] = rd32(E1000_PCS_LCTL);
+       regs_buff[49] = rd32(E1000_PCS_LSTAT);
+       regs_buff[50] = rd32(E1000_PCS_ANADV);
+       regs_buff[51] = rd32(E1000_PCS_LPAB);
+       regs_buff[52] = rd32(E1000_PCS_NPTX);
+       regs_buff[53] = rd32(E1000_PCS_LPABNP);
+
+       /* Statistics */
+       regs_buff[54] = adapter->stats.crcerrs;
+       regs_buff[55] = adapter->stats.algnerrc;
+       regs_buff[56] = adapter->stats.symerrs;
+       regs_buff[57] = adapter->stats.rxerrc;
+       regs_buff[58] = adapter->stats.mpc;
+       regs_buff[59] = adapter->stats.scc;
+       regs_buff[60] = adapter->stats.ecol;
+       regs_buff[61] = adapter->stats.mcc;
+       regs_buff[62] = adapter->stats.latecol;
+       regs_buff[63] = adapter->stats.colc;
+       regs_buff[64] = adapter->stats.dc;
+       regs_buff[65] = adapter->stats.tncrs;
+       regs_buff[66] = adapter->stats.sec;
+       regs_buff[67] = adapter->stats.htdpmc;
+       regs_buff[68] = adapter->stats.rlec;
+       regs_buff[69] = adapter->stats.xonrxc;
+       regs_buff[70] = adapter->stats.xontxc;
+       regs_buff[71] = adapter->stats.xoffrxc;
+       regs_buff[72] = adapter->stats.xofftxc;
+       regs_buff[73] = adapter->stats.fcruc;
+       regs_buff[74] = adapter->stats.prc64;
+       regs_buff[75] = adapter->stats.prc127;
+       regs_buff[76] = adapter->stats.prc255;
+       regs_buff[77] = adapter->stats.prc511;
+       regs_buff[78] = adapter->stats.prc1023;
+       regs_buff[79] = adapter->stats.prc1522;
+       regs_buff[80] = adapter->stats.gprc;
+       regs_buff[81] = adapter->stats.bprc;
+       regs_buff[82] = adapter->stats.mprc;
+       regs_buff[83] = adapter->stats.gptc;
+       regs_buff[84] = adapter->stats.gorc;
+       regs_buff[86] = adapter->stats.gotc;
+       regs_buff[88] = adapter->stats.rnbc;
+       regs_buff[89] = adapter->stats.ruc;
+       regs_buff[90] = adapter->stats.rfc;
+       regs_buff[91] = adapter->stats.roc;
+       regs_buff[92] = adapter->stats.rjc;
+       regs_buff[93] = adapter->stats.mgprc;
+       regs_buff[94] = adapter->stats.mgpdc;
+       regs_buff[95] = adapter->stats.mgptc;
+       regs_buff[96] = adapter->stats.tor;
+       regs_buff[98] = adapter->stats.tot;
+       regs_buff[100] = adapter->stats.tpr;
+       regs_buff[101] = adapter->stats.tpt;
+       regs_buff[102] = adapter->stats.ptc64;
+       regs_buff[103] = adapter->stats.ptc127;
+       regs_buff[104] = adapter->stats.ptc255;
+       regs_buff[105] = adapter->stats.ptc511;
+       regs_buff[106] = adapter->stats.ptc1023;
+       regs_buff[107] = adapter->stats.ptc1522;
+       regs_buff[108] = adapter->stats.mptc;
+       regs_buff[109] = adapter->stats.bptc;
+       regs_buff[110] = adapter->stats.tsctc;
+       regs_buff[111] = adapter->stats.iac;
+       regs_buff[112] = adapter->stats.rpthc;
+       regs_buff[113] = adapter->stats.hgptc;
+       regs_buff[114] = adapter->stats.hgorc;
+       regs_buff[116] = adapter->stats.hgotc;
+       regs_buff[118] = adapter->stats.lenerrs;
+       regs_buff[119] = adapter->stats.scvpc;
+       regs_buff[120] = adapter->stats.hrmpc;
+
+       /* These should probably be added to e1000_regs.h instead */
+       #define E1000_PSRTYPE_REG(_i) (0x05480 + ((_i) * 4))
+       #define E1000_RAL(_i)         (0x05400 + ((_i) * 8))
+       #define E1000_RAH(_i)         (0x05404 + ((_i) * 8))
+       #define E1000_IP4AT_REG(_i)   (0x05840 + ((_i) * 8))
+       #define E1000_IP6AT_REG(_i)   (0x05880 + ((_i) * 4))
+       #define E1000_WUPM_REG(_i)    (0x05A00 + ((_i) * 4))
+       #define E1000_FFMT_REG(_i)    (0x09000 + ((_i) * 8))
+       #define E1000_FFVT_REG(_i)    (0x09800 + ((_i) * 8))
+       #define E1000_FFLT_REG(_i)    (0x05F00 + ((_i) * 8))
+
+       for (i = 0; i < 4; i++)
+               regs_buff[121 + i] = rd32(E1000_SRRCTL(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[125 + i] = rd32(E1000_PSRTYPE_REG(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[129 + i] = rd32(E1000_RDBAL(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[133 + i] = rd32(E1000_RDBAH(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[137 + i] = rd32(E1000_RDLEN(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[141 + i] = rd32(E1000_RDH(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[145 + i] = rd32(E1000_RDT(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[149 + i] = rd32(E1000_RXDCTL(i));
+
+       for (i = 0; i < 10; i++)
+               regs_buff[153 + i] = rd32(E1000_EITR(i));
+       for (i = 0; i < 8; i++)
+               regs_buff[163 + i] = rd32(E1000_IMIR(i));
+       for (i = 0; i < 8; i++)
+               regs_buff[171 + i] = rd32(E1000_IMIREXT(i));
+       for (i = 0; i < 16; i++)
+               regs_buff[179 + i] = rd32(E1000_RAL(i));
+       for (i = 0; i < 16; i++)
+               regs_buff[195 + i] = rd32(E1000_RAH(i));
+
+       for (i = 0; i < 4; i++)
+               regs_buff[211 + i] = rd32(E1000_TDBAL(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[215 + i] = rd32(E1000_TDBAH(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[219 + i] = rd32(E1000_TDLEN(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[223 + i] = rd32(E1000_TDH(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[227 + i] = rd32(E1000_TDT(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[231 + i] = rd32(E1000_TXDCTL(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[235 + i] = rd32(E1000_TDWBAL(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[239 + i] = rd32(E1000_TDWBAH(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[243 + i] = rd32(E1000_DCA_TXCTRL(i));
+
+       for (i = 0; i < 4; i++)
+               regs_buff[247 + i] = rd32(E1000_IP4AT_REG(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[251 + i] = rd32(E1000_IP6AT_REG(i));
+       for (i = 0; i < 32; i++)
+               regs_buff[255 + i] = rd32(E1000_WUPM_REG(i));
+       for (i = 0; i < 128; i++)
+               regs_buff[287 + i] = rd32(E1000_FFMT_REG(i));
+       for (i = 0; i < 128; i++)
+               regs_buff[415 + i] = rd32(E1000_FFVT_REG(i));
+       for (i = 0; i < 4; i++)
+               regs_buff[543 + i] = rd32(E1000_FFLT_REG(i));
+
+       regs_buff[547] = rd32(E1000_TDFH);
+       regs_buff[548] = rd32(E1000_TDFT);
+       regs_buff[549] = rd32(E1000_TDFHS);
+       regs_buff[550] = rd32(E1000_TDFPC);
+
+}
+
+static int igb_get_eeprom_len(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       return adapter->hw.nvm.word_size * 2;
+}
+
+static int igb_get_eeprom(struct net_device *netdev,
+                         struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u16 *eeprom_buff;
+       int first_word, last_word;
+       int ret_val = 0;
+       u16 i;
+
+       if (eeprom->len == 0)
+               return -EINVAL;
+
+       eeprom->magic = hw->vendor_id | (hw->device_id << 16);
+
+       first_word = eeprom->offset >> 1;
+       last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+       eeprom_buff = kmalloc(sizeof(u16) *
+                       (last_word - first_word + 1), GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       if (hw->nvm.type == e1000_nvm_eeprom_spi)
+               ret_val = hw->nvm.ops.read_nvm(hw, first_word,
+                                           last_word - first_word + 1,
+                                           eeprom_buff);
+       else {
+               for (i = 0; i < last_word - first_word + 1; i++) {
+                       ret_val = hw->nvm.ops.read_nvm(hw, first_word + i, 1,
+                                                   &eeprom_buff[i]);
+                       if (ret_val)
+                               break;
+               }
+       }
+
+       /* Device's eeprom is always little-endian, word addressable */
+       for (i = 0; i < last_word - first_word + 1; i++)
+               le16_to_cpus(&eeprom_buff[i]);
+
+       memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),
+                       eeprom->len);
+       kfree(eeprom_buff);
+
+       return ret_val;
+}
+
+static int igb_set_eeprom(struct net_device *netdev,
+                         struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u16 *eeprom_buff;
+       void *ptr;
+       int max_len, first_word, last_word, ret_val = 0;
+       u16 i;
+
+       if (eeprom->len == 0)
+               return -EOPNOTSUPP;
+
+       if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+               return -EFAULT;
+
+       max_len = hw->nvm.word_size * 2;
+
+       first_word = eeprom->offset >> 1;
+       last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+       eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+       if (!eeprom_buff)
+               return -ENOMEM;
+
+       ptr = (void *)eeprom_buff;
+
+       if (eeprom->offset & 1) {
+               /* need read/modify/write of first changed EEPROM word */
+               /* only the second byte of the word is being modified */
+               ret_val = hw->nvm.ops.read_nvm(hw, first_word, 1,
+                                           &eeprom_buff[0]);
+               ptr++;
+       }
+       if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
+               /* need read/modify/write of last changed EEPROM word */
+               /* only the first byte of the word is being modified */
+               ret_val = hw->nvm.ops.read_nvm(hw, last_word, 1,
+                                  &eeprom_buff[last_word - first_word]);
+       }
+
+       /* Device's eeprom is always little-endian, word addressable */
+       for (i = 0; i < last_word - first_word + 1; i++)
+               le16_to_cpus(&eeprom_buff[i]);
+
+       memcpy(ptr, bytes, eeprom->len);
+
+       for (i = 0; i < last_word - first_word + 1; i++)
+               eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
+
+       ret_val = hw->nvm.ops.write_nvm(hw, first_word,
+                                    last_word - first_word + 1, eeprom_buff);
+
+       /* Update the checksum over the first part of the EEPROM if needed
+        * and flush shadow RAM for 82573 controllers */
+       if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG)))
+               igb_update_nvm_checksum(hw);
+
+       kfree(eeprom_buff);
+       return ret_val;
+}
+
+static void igb_get_drvinfo(struct net_device *netdev,
+                           struct ethtool_drvinfo *drvinfo)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       char firmware_version[32];
+       u16 eeprom_data;
+
+       strncpy(drvinfo->driver,  igb_driver_name, 32);
+       strncpy(drvinfo->version, igb_driver_version, 32);
+
+       /* EEPROM image version # is reported as firmware version # for
+        * 82575 controllers */
+       adapter->hw.nvm.ops.read_nvm(&adapter->hw, 5, 1, &eeprom_data);
+       sprintf(firmware_version, "%d.%d-%d",
+               (eeprom_data & 0xF000) >> 12,
+               (eeprom_data & 0x0FF0) >> 4,
+               eeprom_data & 0x000F);
+
+       strncpy(drvinfo->fw_version, firmware_version, 32);
+       strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+       drvinfo->n_stats = IGB_STATS_LEN;
+       drvinfo->testinfo_len = IGB_TEST_LEN;
+       drvinfo->regdump_len = igb_get_regs_len(netdev);
+       drvinfo->eedump_len = igb_get_eeprom_len(netdev);
+}
+
+static void igb_get_ringparam(struct net_device *netdev,
+                             struct ethtool_ringparam *ring)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct igb_ring *tx_ring = adapter->tx_ring;
+       struct igb_ring *rx_ring = adapter->rx_ring;
+
+       ring->rx_max_pending = IGB_MAX_RXD;
+       ring->tx_max_pending = IGB_MAX_TXD;
+       ring->rx_mini_max_pending = 0;
+       ring->rx_jumbo_max_pending = 0;
+       ring->rx_pending = rx_ring->count;
+       ring->tx_pending = tx_ring->count;
+       ring->rx_mini_pending = 0;
+       ring->rx_jumbo_pending = 0;
+}
+
+static int igb_set_ringparam(struct net_device *netdev,
+                            struct ethtool_ringparam *ring)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct igb_buffer *old_buf;
+       struct igb_buffer *old_rx_buf;
+       void *old_desc;
+       int i, err;
+       u32 new_rx_count, new_tx_count, old_size;
+       dma_addr_t old_dma;
+
+       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+               return -EINVAL;
+
+       new_rx_count = max(ring->rx_pending, (u32)IGB_MIN_RXD);
+       new_rx_count = min(new_rx_count, (u32)IGB_MAX_RXD);
+       new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
+
+       new_tx_count = max(ring->tx_pending, (u32)IGB_MIN_TXD);
+       new_tx_count = min(new_tx_count, (u32)IGB_MAX_TXD);
+       new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
+
+       if ((new_tx_count == adapter->tx_ring->count) &&
+           (new_rx_count == adapter->rx_ring->count)) {
+               /* nothing to do */
+               return 0;
+       }
+
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+
+       if (netif_running(adapter->netdev))
+               igb_down(adapter);
+
+       /*
+        * We can't just free everything and then setup again,
+        * because the ISRs in MSI-X mode get passed pointers
+        * to the tx and rx ring structs.
+        */
+       if (new_tx_count != adapter->tx_ring->count) {
+               for (i = 0; i < adapter->num_tx_queues; i++) {
+                       /* Save existing descriptor ring */
+                       old_buf = adapter->tx_ring[i].buffer_info;
+                       old_desc = adapter->tx_ring[i].desc;
+                       old_size = adapter->tx_ring[i].size;
+                       old_dma = adapter->tx_ring[i].dma;
+                       /* Try to allocate a new one */
+                       adapter->tx_ring[i].buffer_info = NULL;
+                       adapter->tx_ring[i].desc = NULL;
+                       adapter->tx_ring[i].count = new_tx_count;
+                       err = igb_setup_tx_resources(adapter,
+                                               &adapter->tx_ring[i]);
+                       if (err) {
+                               /* Restore the old one so at least
+                                  the adapter still works, even if
+                                  we failed the request */
+                               adapter->tx_ring[i].buffer_info = old_buf;
+                               adapter->tx_ring[i].desc = old_desc;
+                               adapter->tx_ring[i].size = old_size;
+                               adapter->tx_ring[i].dma = old_dma;
+                               goto err_setup;
+                       }
+                       /* Free the old buffer manually */
+                       vfree(old_buf);
+                       pci_free_consistent(adapter->pdev, old_size,
+                                           old_desc, old_dma);
+               }
+       }
+
+       if (new_rx_count != adapter->rx_ring->count) {
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+
+                       old_rx_buf = adapter->rx_ring[i].buffer_info;
+                       old_desc = adapter->rx_ring[i].desc;
+                       old_size = adapter->rx_ring[i].size;
+                       old_dma = adapter->rx_ring[i].dma;
+
+                       adapter->rx_ring[i].buffer_info = NULL;
+                       adapter->rx_ring[i].desc = NULL;
+                       adapter->rx_ring[i].dma = 0;
+                       adapter->rx_ring[i].count = new_rx_count;
+                       err = igb_setup_rx_resources(adapter,
+                                                    &adapter->rx_ring[i]);
+                       if (err) {
+                               adapter->rx_ring[i].buffer_info = old_rx_buf;
+                               adapter->rx_ring[i].desc = old_desc;
+                               adapter->rx_ring[i].size = old_size;
+                               adapter->rx_ring[i].dma = old_dma;
+                               goto err_setup;
+                       }
+
+                       vfree(old_rx_buf);
+                       pci_free_consistent(adapter->pdev, old_size, old_desc,
+                                           old_dma);
+               }
+       }
+
+       err = 0;
+err_setup:
+       if (netif_running(adapter->netdev))
+               igb_up(adapter);
+
+       clear_bit(__IGB_RESETTING, &adapter->state);
+       return err;
+}
+
+/* ethtool register test data */
+struct igb_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 0x100 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 register test */
+static struct igb_reg_test reg_test_82575[] = {
+       { E1000_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { E1000_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+       { E1000_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
+       { E1000_VET, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { E1000_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+       { E1000_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { E1000_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+       /* Enable all four RX queues before testing. */
+       { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+       /* RDH is read-only for 82575, only test RDT. */
+       { E1000_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+       { E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
+       { E1000_FCRTH, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
+       { E1000_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+       { E1000_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
+       { E1000_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+       { E1000_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { E1000_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+       { E1000_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+       { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
+       { E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
+       { E1000_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
+       { E1000_TXCW, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
+       { E1000_RA, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+       { E1000_RA, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
+       { E1000_MTA, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { 0, 0, 0, 0 }
+};
+
+static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
+                            int reg, u32 mask, u32 write)
+{
+       u32 pat, val;
+       u32 _test[] =
+               {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+       for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
+               writel((_test[pat] & write), (adapter->hw.hw_addr + reg));
+               val = readl(adapter->hw.hw_addr + reg);
+               if (val != (_test[pat] & write & mask)) {
+                       dev_err(&adapter->pdev->dev, "pattern test reg %04X "
+                               "failed: got 0x%08X expected 0x%08X\n",
+                               reg, val, (_test[pat] & write & mask));
+                       *data = reg;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
+                             int reg, u32 mask, u32 write)
+{
+       u32 val;
+       writel((write & mask), (adapter->hw.hw_addr + reg));
+       val = readl(adapter->hw.hw_addr + reg);
+       if ((write & mask) != (val & mask)) {
+               dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:"
+                       " got 0x%08X expected 0x%08X\n", reg,
+                       (val & mask), (write & mask));
+               *data = reg;
+               return 1;
+       }
+       return 0;
+}
+
+#define REG_PATTERN_TEST(reg, mask, write) \
+       do { \
+               if (reg_pattern_test(adapter, data, reg, mask, write)) \
+                       return 1; \
+       } while (0)
+
+#define REG_SET_AND_CHECK(reg, mask, write) \
+       do { \
+               if (reg_set_and_check(adapter, data, reg, mask, write)) \
+                       return 1; \
+       } while (0)
+
+static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct igb_reg_test *test;
+       u32 value, before, after;
+       u32 i, toggle;
+
+       toggle = 0x7FFFF3FF;
+       test = reg_test_82575;
+
+       /* 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 writable on newer MACs.
+        */
+       before = rd32(E1000_STATUS);
+       value = (rd32(E1000_STATUS) & toggle);
+       wr32(E1000_STATUS, toggle);
+       after = rd32(E1000_STATUS) & toggle;
+       if (value != after) {
+               dev_err(&adapter->pdev->dev, "failed STATUS register test "
+                       "got: 0x%08X expected: 0x%08X\n", after, value);
+               *data = 1;
+               return 1;
+       }
+       /* restore previous status */
+       wr32(E1000_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 * 0x100),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case SET_READ_TEST:
+                               REG_SET_AND_CHECK(test->reg + (i * 0x100),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case WRITE_NO_TEST:
+                               writel(test->write,
+                                   (adapter->hw.hw_addr + test->reg)
+                                       + (i * 0x100));
+                               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 igb_eeprom_test(struct igb_adapter *adapter, u64 *data)
+{
+       u16 temp;
+       u16 checksum = 0;
+       u16 i;
+
+       *data = 0;
+       /* Read and add up the contents of the EEPROM */
+       for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
+               if ((adapter->hw.nvm.ops.read_nvm(&adapter->hw, i, 1, &temp))
+                   < 0) {
+                       *data = 1;
+                       break;
+               }
+               checksum += temp;
+       }
+
+       /* If Checksum is not Correct return error else test passed */
+       if ((checksum != (u16) NVM_SUM) && !(*data))
+               *data = 2;
+
+       return *data;
+}
+
+static irqreturn_t igb_test_intr(int irq, void *data)
+{
+       struct net_device *netdev = (struct net_device *) data;
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       adapter->test_icr |= rd32(E1000_ICR);
+
+       return IRQ_HANDLED;
+}
+
+static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       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->msi_enabled) {
+               shared_int = false;
+               if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
+                       *data = 1;
+                       return -1;
+               }
+       } else if (!request_irq(irq, &igb_test_intr, IRQF_PROBE_SHARED,
+                               netdev->name, netdev)) {
+               shared_int = false;
+       } else if (request_irq(irq, &igb_test_intr, IRQF_SHARED,
+                netdev->name, netdev)) {
+               *data = 1;
+               return -1;
+       }
+       dev_info(&adapter->pdev->dev, "testing %s interrupt\n",
+               (shared_int ? "shared" : "unshared"));
+
+       /* Disable all the interrupts */
+       wr32(E1000_IMC, 0xFFFFFFFF);
+       msleep(10);
+
+       /* Test each interrupt */
+       for (; i < 10; i++) {
+               /* Interrupt to test */
+               mask = 1 << i;
+
+               if (!shared_int) {
+                       /* Disable 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 posted to the bus, the
+                        * test failed.
+                        */
+                       adapter->test_icr = 0;
+                       wr32(E1000_IMC, ~mask & 0x00007FFF);
+                       wr32(E1000_ICS, ~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;
+               wr32(E1000_IMS, mask);
+               wr32(E1000_ICS, 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;
+                       wr32(E1000_IMC, ~mask & 0x00007FFF);
+                       wr32(E1000_ICS, ~mask & 0x00007FFF);
+                       msleep(10);
+
+                       if (adapter->test_icr) {
+                               *data = 5;
+                               break;
+                       }
+               }
+       }
+
+       /* Disable all the interrupts */
+       wr32(E1000_IMC, 0xFFFFFFFF);
+       msleep(10);
+
+       /* Unhook test interrupt handler */
+       free_irq(irq, netdev);
+
+       return *data;
+}
+
+static void igb_free_desc_rings(struct igb_adapter *adapter)
+{
+       struct igb_ring *tx_ring = &adapter->test_tx_ring;
+       struct igb_ring *rx_ring = &adapter->test_rx_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       int i;
+
+       if (tx_ring->desc && tx_ring->buffer_info) {
+               for (i = 0; i < tx_ring->count; i++) {
+                       struct igb_buffer *buf = &(tx_ring->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->buffer_info) {
+               for (i = 0; i < rx_ring->count; i++) {
+                       struct igb_buffer *buf = &(rx_ring->buffer_info[i]);
+                       if (buf->dma)
+                               pci_unmap_single(pdev, buf->dma,
+                                                IGB_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->buffer_info);
+       tx_ring->buffer_info = NULL;
+       kfree(rx_ring->buffer_info);
+       rx_ring->buffer_info = NULL;
+
+       return;
+}
+
+static int igb_setup_desc_rings(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct igb_ring *tx_ring = &adapter->test_tx_ring;
+       struct igb_ring *rx_ring = &adapter->test_rx_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       u32 rctl;
+       int i, ret_val;
+
+       /* Setup Tx descriptor ring and Tx buffers */
+
+       if (!tx_ring->count)
+               tx_ring->count = IGB_DEFAULT_TXD;
+
+       tx_ring->buffer_info = kcalloc(tx_ring->count,
+                                      sizeof(struct igb_buffer),
+                                      GFP_KERNEL);
+       if (!tx_ring->buffer_info) {
+               ret_val = 1;
+               goto err_nomem;
+       }
+
+       tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
+       tx_ring->size = ALIGN(tx_ring->size, 4096);
+       tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+                                            &tx_ring->dma);
+       if (!tx_ring->desc) {
+               ret_val = 2;
+               goto err_nomem;
+       }
+       tx_ring->next_to_use = tx_ring->next_to_clean = 0;
+
+       wr32(E1000_TDBAL(0),
+                       ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
+       wr32(E1000_TDBAH(0), ((u64) tx_ring->dma >> 32));
+       wr32(E1000_TDLEN(0),
+                       tx_ring->count * sizeof(struct e1000_tx_desc));
+       wr32(E1000_TDH(0), 0);
+       wr32(E1000_TDT(0), 0);
+       wr32(E1000_TCTL,
+                       E1000_TCTL_PSP | E1000_TCTL_EN |
+                       E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
+                       E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
+
+       for (i = 0; i < tx_ring->count; i++) {
+               struct e1000_tx_desc *tx_desc = E1000_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->buffer_info[i].skb = skb;
+               tx_ring->buffer_info[i].length = skb->len;
+               tx_ring->buffer_info[i].dma =
+                       pci_map_single(pdev, skb->data, skb->len,
+                                      PCI_DMA_TODEVICE);
+               tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma);
+               tx_desc->lower.data = cpu_to_le32(skb->len);
+               tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
+                                                  E1000_TXD_CMD_IFCS |
+                                                  E1000_TXD_CMD_RS);
+               tx_desc->upper.data = 0;
+       }
+
+       /* Setup Rx descriptor ring and Rx buffers */
+
+       if (!rx_ring->count)
+               rx_ring->count = IGB_DEFAULT_RXD;
+
+       rx_ring->buffer_info = kcalloc(rx_ring->count,
+                                      sizeof(struct igb_buffer),
+                                      GFP_KERNEL);
+       if (!rx_ring->buffer_info) {
+               ret_val = 4;
+               goto err_nomem;
+       }
+
+       rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
+       rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+                                            &rx_ring->dma);
+       if (!rx_ring->desc) {
+               ret_val = 5;
+               goto err_nomem;
+       }
+       rx_ring->next_to_use = rx_ring->next_to_clean = 0;
+
+       rctl = rd32(E1000_RCTL);
+       wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
+       wr32(E1000_RDBAL(0),
+                       ((u64) rx_ring->dma & 0xFFFFFFFF));
+       wr32(E1000_RDBAH(0),
+                       ((u64) rx_ring->dma >> 32));
+       wr32(E1000_RDLEN(0), rx_ring->size);
+       wr32(E1000_RDH(0), 0);
+       wr32(E1000_RDT(0), 0);
+       rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
+               E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+               (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+       wr32(E1000_RCTL, rctl);
+       wr32(E1000_SRRCTL(0), 0);
+
+       for (i = 0; i < rx_ring->count; i++) {
+               struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i);
+               struct sk_buff *skb;
+
+               skb = alloc_skb(IGB_RXBUFFER_2048 + NET_IP_ALIGN,
+                               GFP_KERNEL);
+               if (!skb) {
+                       ret_val = 6;
+                       goto err_nomem;
+               }
+               skb_reserve(skb, NET_IP_ALIGN);
+               rx_ring->buffer_info[i].skb = skb;
+               rx_ring->buffer_info[i].dma =
+                       pci_map_single(pdev, skb->data, IGB_RXBUFFER_2048,
+                                      PCI_DMA_FROMDEVICE);
+               rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);
+               memset(skb->data, 0x00, skb->len);
+       }
+
+       return 0;
+
+err_nomem:
+       igb_free_desc_rings(adapter);
+       return ret_val;
+}
+
+static void igb_phy_disable_receiver(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       /* Write out to PHY registers 29 and 30 to disable the Receiver. */
+       hw->phy.ops.write_phy_reg(hw, 29, 0x001F);
+       hw->phy.ops.write_phy_reg(hw, 30, 0x8FFC);
+       hw->phy.ops.write_phy_reg(hw, 29, 0x001A);
+       hw->phy.ops.write_phy_reg(hw, 30, 0x8FF0);
+}
+
+static int igb_integrated_phy_loopback(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl_reg = 0;
+       u32 stat_reg = 0;
+
+       hw->mac.autoneg = false;
+
+       if (hw->phy.type == e1000_phy_m88) {
+               /* Auto-MDI/MDIX Off */
+               hw->phy.ops.write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
+               /* reset to update Auto-MDI/MDIX */
+               hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, 0x9140);
+               /* autoneg off */
+               hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, 0x8140);
+       }
+
+       ctrl_reg = rd32(E1000_CTRL);
+
+       /* force 1000, set loopback */
+       hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, 0x4140);
+
+       /* Now set up the MAC to the same speed/duplex as the PHY. */
+       ctrl_reg = rd32(E1000_CTRL);
+       ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
+       ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
+                    E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
+                    E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
+                    E1000_CTRL_FD);     /* Force Duplex to FULL */
+
+       if (hw->phy.media_type == e1000_media_type_copper &&
+           hw->phy.type == e1000_phy_m88)
+               ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
+       else {
+               /* Set the ILOS bit on the fiber Nic if half duplex link is
+                * detected. */
+               stat_reg = rd32(E1000_STATUS);
+               if ((stat_reg & E1000_STATUS_FD) == 0)
+                       ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
+       }
+
+       wr32(E1000_CTRL, ctrl_reg);
+
+       /* Disable the receiver on the PHY so when a cable is plugged in, the
+        * PHY does not begin to autoneg when a cable is reconnected to the NIC.
+        */
+       if (hw->phy.type == e1000_phy_m88)
+               igb_phy_disable_receiver(adapter);
+
+       udelay(500);
+
+       return 0;
+}
+
+static int igb_set_phy_loopback(struct igb_adapter *adapter)
+{
+       return igb_integrated_phy_loopback(adapter);
+}
+
+static int igb_setup_loopback_test(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 rctl;
+
+       if (hw->phy.media_type == e1000_media_type_fiber ||
+           hw->phy.media_type == e1000_media_type_internal_serdes) {
+               rctl = rd32(E1000_RCTL);
+               rctl |= E1000_RCTL_LBM_TCVR;
+               wr32(E1000_RCTL, rctl);
+               return 0;
+       } else if (hw->phy.media_type == e1000_media_type_copper) {
+               return igb_set_phy_loopback(adapter);
+       }
+
+       return 7;
+}
+
+static void igb_loopback_cleanup(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 rctl;
+       u16 phy_reg;
+
+       rctl = rd32(E1000_RCTL);
+       rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
+       wr32(E1000_RCTL, rctl);
+
+       hw->mac.autoneg = true;
+       hw->phy.ops.read_phy_reg(hw, PHY_CONTROL, &phy_reg);
+       if (phy_reg & MII_CR_LOOPBACK) {
+               phy_reg &= ~MII_CR_LOOPBACK;
+               hw->phy.ops.write_phy_reg(hw, PHY_CONTROL, phy_reg);
+               igb_phy_sw_reset(hw);
+       }
+}
+
+static void igb_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 igb_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 igb_run_loopback_test(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct igb_ring *tx_ring = &adapter->test_tx_ring;
+       struct igb_ring *rx_ring = &adapter->test_rx_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       int i, j, k, l, lc, good_cnt;
+       int ret_val = 0;
+       unsigned long time;
+
+       wr32(E1000_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++) { /* loop count loop */
+               for (i = 0; i < 64; i++) { /* send the packets */
+                       igb_create_lbtest_frame(tx_ring->buffer_info[k].skb,
+                                               1024);
+                       pci_dma_sync_single_for_device(pdev,
+                               tx_ring->buffer_info[k].dma,
+                               tx_ring->buffer_info[k].length,
+                               PCI_DMA_TODEVICE);
+                       k++;
+                       if (k == tx_ring->count)
+                               k = 0;
+               }
+               wr32(E1000_TDT(0), k);
+               msleep(200);
+               time = jiffies; /* set the start time for the receive */
+               good_cnt = 0;
+               do { /* receive the sent packets */
+                       pci_dma_sync_single_for_cpu(pdev,
+                                       rx_ring->buffer_info[l].dma,
+                                       IGB_RXBUFFER_2048,
+                                       PCI_DMA_FROMDEVICE);
+
+                       ret_val = igb_check_lbtest_frame(
+                                            rx_ring->buffer_info[l].skb, 1024);
+                       if (!ret_val)
+                               good_cnt++;
+                       l++;
+                       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 = 13; /* ret_val is the same as mis-compare */
+                       break;
+               }
+               if (jiffies >= (time + 20)) {
+                       ret_val = 14; /* error code for time out error */
+                       break;
+               }
+       } /* end loop count loop */
+       return ret_val;
+}
+
+static int igb_loopback_test(struct igb_adapter *adapter, u64 *data)
+{
+       /* PHY loopback cannot be performed if SoL/IDER
+        * sessions are active */
+       if (igb_check_reset_block(&adapter->hw)) {
+               dev_err(&adapter->pdev->dev,
+                       "Cannot do PHY loopback test "
+                       "when SoL/IDER is active.\n");
+               *data = 0;
+               goto out;
+       }
+       *data = igb_setup_desc_rings(adapter);
+       if (*data)
+               goto out;
+       *data = igb_setup_loopback_test(adapter);
+       if (*data)
+               goto err_loopback;
+       *data = igb_run_loopback_test(adapter);
+       igb_loopback_cleanup(adapter);
+
+err_loopback:
+       igb_free_desc_rings(adapter);
+out:
+       return *data;
+}
+
+static int igb_link_test(struct igb_adapter *adapter, u64 *data)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       *data = 0;
+       if (hw->phy.media_type == e1000_media_type_internal_serdes) {
+               int i = 0;
+               hw->mac.serdes_has_link = false;
+
+               /* On some blade server designs, link establishment
+                * could take as long as 2-3 minutes */
+               do {
+                       hw->mac.ops.check_for_link(&adapter->hw);
+                       if (hw->mac.serdes_has_link)
+                               return *data;
+                       msleep(20);
+               } while (i++ < 3750);
+
+               *data = 1;
+       } else {
+               hw->mac.ops.check_for_link(&adapter->hw);
+               if (hw->mac.autoneg)
+                       msleep(4000);
+
+               if (!(rd32(E1000_STATUS) &
+                     E1000_STATUS_LU))
+                       *data = 1;
+       }
+       return *data;
+}
+
+static void igb_diag_test(struct net_device *netdev,
+                         struct ethtool_test *eth_test, u64 *data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       u16 autoneg_advertised;
+       u8 forced_speed_duplex, autoneg;
+       bool if_running = netif_running(netdev);
+
+       set_bit(__IGB_TESTING, &adapter->state);
+       if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+               /* Offline tests */
+
+               /* save speed, duplex, autoneg settings */
+               autoneg_advertised = adapter->hw.phy.autoneg_advertised;
+               forced_speed_duplex = adapter->hw.mac.forced_speed_duplex;
+               autoneg = adapter->hw.mac.autoneg;
+
+               dev_info(&adapter->pdev->dev, "offline testing starting\n");
+
+               /* Link test performed before hardware reset so autoneg doesn't
+                * interfere with test result */
+               if (igb_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
+                       igb_reset(adapter);
+
+               if (igb_reg_test(adapter, &data[0]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               igb_reset(adapter);
+               if (igb_eeprom_test(adapter, &data[1]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               igb_reset(adapter);
+               if (igb_intr_test(adapter, &data[2]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               igb_reset(adapter);
+               if (igb_loopback_test(adapter, &data[3]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               /* restore speed, duplex, autoneg settings */
+               adapter->hw.phy.autoneg_advertised = autoneg_advertised;
+               adapter->hw.mac.forced_speed_duplex = forced_speed_duplex;
+               adapter->hw.mac.autoneg = autoneg;
+
+               /* force this routine to wait until autoneg complete/timeout */
+               adapter->hw.phy.autoneg_wait_to_complete = true;
+               igb_reset(adapter);
+               adapter->hw.phy.autoneg_wait_to_complete = false;
+
+               clear_bit(__IGB_TESTING, &adapter->state);
+               if (if_running)
+                       dev_open(netdev);
+       } else {
+               dev_info(&adapter->pdev->dev, "online testing starting\n");
+               /* Online tests */
+               if (igb_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(__IGB_TESTING, &adapter->state);
+       }
+       msleep_interruptible(4 * 1000);
+}
+
+static int igb_wol_exclusion(struct igb_adapter *adapter,
+                            struct ethtool_wolinfo *wol)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       int retval = 1; /* fail by default */
+
+       switch (hw->device_id) {
+       case E1000_DEV_ID_82575GB_QUAD_COPPER:
+               /* WoL not supported */
+               wol->supported = 0;
+               break;
+       case E1000_DEV_ID_82575EB_FIBER_SERDES:
+               /* Wake events not supported on port B */
+               if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) {
+                       wol->supported = 0;
+                       break;
+               }
+               /* return success for non excluded adapter ports */
+               retval = 0;
+               break;
+       default:
+               /* dual port cards only support WoL on port A from now on
+                * unless it was enabled in the eeprom for port B
+                * so exclude FUNC_1 ports from having WoL enabled */
+               if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1 &&
+                   !adapter->eeprom_wol) {
+                       wol->supported = 0;
+                       break;
+               }
+
+               retval = 0;
+       }
+
+       return retval;
+}
+
+static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       wol->supported = WAKE_UCAST | WAKE_MCAST |
+                        WAKE_BCAST | WAKE_MAGIC;
+       wol->wolopts = 0;
+
+       /* this function will set ->supported = 0 and return 1 if wol is not
+        * supported by this hardware */
+       if (igb_wol_exclusion(adapter, wol))
+               return;
+
+       /* apply any specific unsupported masks here */
+       switch (adapter->hw.device_id) {
+       default:
+               break;
+       }
+
+       if (adapter->wol & E1000_WUFC_EX)
+               wol->wolopts |= WAKE_UCAST;
+       if (adapter->wol & E1000_WUFC_MC)
+               wol->wolopts |= WAKE_MCAST;
+       if (adapter->wol & E1000_WUFC_BC)
+               wol->wolopts |= WAKE_BCAST;
+       if (adapter->wol & E1000_WUFC_MAG)
+               wol->wolopts |= WAKE_MAGIC;
+
+       return;
+}
+
+static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+               return -EOPNOTSUPP;
+
+       if (igb_wol_exclusion(adapter, wol))
+               return wol->wolopts ? -EOPNOTSUPP : 0;
+
+       switch (hw->device_id) {
+       default:
+               break;
+       }
+
+       /* these settings will always override what we currently have */
+       adapter->wol = 0;
+
+       if (wol->wolopts & WAKE_UCAST)
+               adapter->wol |= E1000_WUFC_EX;
+       if (wol->wolopts & WAKE_MCAST)
+               adapter->wol |= E1000_WUFC_MC;
+       if (wol->wolopts & WAKE_BCAST)
+               adapter->wol |= E1000_WUFC_BC;
+       if (wol->wolopts & WAKE_MAGIC)
+               adapter->wol |= E1000_WUFC_MAG;
+
+       return 0;
+}
+
+/* toggle LED 4 times per second = 2 "blinks" per second */
+#define IGB_ID_INTERVAL                (HZ/4)
+
+/* bit defines for adapter->led_status */
+#define IGB_LED_ON             0
+
+static int igb_phys_id(struct net_device *netdev, u32 data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
+               data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
+
+       igb_blink_led(hw);
+       msleep_interruptible(data * 1000);
+
+       igb_led_off(hw);
+       clear_bit(IGB_LED_ON, &adapter->led_status);
+       igb_cleanup_led(hw);
+
+       return 0;
+}
+
+static int igb_set_coalesce(struct net_device *netdev,
+                           struct ethtool_coalesce *ec)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
+           ((ec->rx_coalesce_usecs > 3) &&
+            (ec->rx_coalesce_usecs < IGB_MIN_ITR_USECS)) ||
+           (ec->rx_coalesce_usecs == 2))
+               return -EINVAL;
+
+       /* convert to rate of irq's per second */
+       if (ec->rx_coalesce_usecs <= 3)
+               adapter->itr_setting = ec->rx_coalesce_usecs;
+       else
+               adapter->itr_setting = (1000000 / ec->rx_coalesce_usecs);
+
+       if (netif_running(netdev))
+               igb_reinit_locked(adapter);
+
+       return 0;
+}
+
+static int igb_get_coalesce(struct net_device *netdev,
+                           struct ethtool_coalesce *ec)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       if (adapter->itr_setting <= 3)
+               ec->rx_coalesce_usecs = adapter->itr_setting;
+       else
+               ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
+
+       return 0;
+}
+
+
+static int igb_nway_reset(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       if (netif_running(netdev))
+               igb_reinit_locked(adapter);
+       return 0;
+}
+
+static int igb_get_sset_count(struct net_device *netdev, int sset)
+{
+       switch (sset) {
+       case ETH_SS_STATS:
+               return IGB_STATS_LEN;
+       case ETH_SS_TEST:
+               return IGB_TEST_LEN;
+       default:
+               return -ENOTSUPP;
+       }
+}
+
+static void igb_get_ethtool_stats(struct net_device *netdev,
+                                 struct ethtool_stats *stats, u64 *data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       u64 *queue_stat;
+       int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
+       int j;
+       int i;
+
+       igb_update_stats(adapter);
+       for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
+               char *p = (char *)adapter+igb_gstrings_stats[i].stat_offset;
+               data[i] = (igb_gstrings_stats[i].sizeof_stat ==
+                       sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+       }
+       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++)
+                       data[i + k] = queue_stat[k];
+               i += k;
+       }
+}
+
+static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       u8 *p = data;
+       int i;
+
+       switch (stringset) {
+       case ETH_SS_TEST:
+               memcpy(data, *igb_gstrings_test,
+                       IGB_TEST_LEN*ETH_GSTRING_LEN);
+               break;
+       case ETH_SS_STATS:
+               for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
+                       memcpy(p, igb_gstrings_stats[i].stat_string,
+                              ETH_GSTRING_LEN);
+                       p += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < adapter->num_tx_queues; i++) {
+                       sprintf(p, "tx_queue_%u_packets", i);
+                       p += ETH_GSTRING_LEN;
+                       sprintf(p, "tx_queue_%u_bytes", i);
+                       p += ETH_GSTRING_LEN;
+               }
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       sprintf(p, "rx_queue_%u_packets", i);
+                       p += ETH_GSTRING_LEN;
+                       sprintf(p, "rx_queue_%u_bytes", i);
+                       p += ETH_GSTRING_LEN;
+               }
+/*             BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
+               break;
+       }
+}
+
+static struct ethtool_ops igb_ethtool_ops = {
+       .get_settings           = igb_get_settings,
+       .set_settings           = igb_set_settings,
+       .get_drvinfo            = igb_get_drvinfo,
+       .get_regs_len           = igb_get_regs_len,
+       .get_regs               = igb_get_regs,
+       .get_wol                = igb_get_wol,
+       .set_wol                = igb_set_wol,
+       .get_msglevel           = igb_get_msglevel,
+       .set_msglevel           = igb_set_msglevel,
+       .nway_reset             = igb_nway_reset,
+       .get_link               = ethtool_op_get_link,
+       .get_eeprom_len         = igb_get_eeprom_len,
+       .get_eeprom             = igb_get_eeprom,
+       .set_eeprom             = igb_set_eeprom,
+       .get_ringparam          = igb_get_ringparam,
+       .set_ringparam          = igb_set_ringparam,
+       .get_pauseparam         = igb_get_pauseparam,
+       .set_pauseparam         = igb_set_pauseparam,
+       .get_rx_csum            = igb_get_rx_csum,
+       .set_rx_csum            = igb_set_rx_csum,
+       .get_tx_csum            = igb_get_tx_csum,
+       .set_tx_csum            = igb_set_tx_csum,
+       .get_sg                 = ethtool_op_get_sg,
+       .set_sg                 = ethtool_op_set_sg,
+       .get_tso                = ethtool_op_get_tso,
+       .set_tso                = igb_set_tso,
+       .self_test              = igb_diag_test,
+       .get_strings            = igb_get_strings,
+       .phys_id                = igb_phys_id,
+       .get_sset_count         = igb_get_sset_count,
+       .get_ethtool_stats      = igb_get_ethtool_stats,
+       .get_coalesce           = igb_get_coalesce,
+       .set_coalesce           = igb_set_coalesce,
+};
+
+void igb_set_ethtool_ops(struct net_device *netdev)
+{
+       SET_ETHTOOL_OPS(netdev, &igb_ethtool_ops);
+}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
new file mode 100644 (file)
index 0000000..f3c144d
--- /dev/null
@@ -0,0 +1,4138 @@
+/*******************************************************************************
+
+  Intel(R) Gigabit Ethernet Linux driver
+  Copyright(c) 2007 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 <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/netdevice.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+
+#include "igb.h"
+
+#define DRV_VERSION "1.0.8-k2"
+char igb_driver_name[] = "igb";
+char igb_driver_version[] = DRV_VERSION;
+static const char igb_driver_string[] =
+                               "Intel(R) Gigabit Ethernet Network Driver";
+static const char igb_copyright[] = "Copyright (c) 2007 Intel Corporation.";
+
+
+static const struct e1000_info *igb_info_tbl[] = {
+       [board_82575] = &e1000_82575_info,
+};
+
+static struct pci_device_id igb_pci_tbl[] = {
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
+       /* required last entry */
+       {0, }
+};
+
+MODULE_DEVICE_TABLE(pci, igb_pci_tbl);
+
+void igb_reset(struct igb_adapter *);
+static int igb_setup_all_tx_resources(struct igb_adapter *);
+static int igb_setup_all_rx_resources(struct igb_adapter *);
+static void igb_free_all_tx_resources(struct igb_adapter *);
+static void igb_free_all_rx_resources(struct igb_adapter *);
+static void igb_free_tx_resources(struct igb_adapter *, struct igb_ring *);
+static void igb_free_rx_resources(struct igb_adapter *, struct igb_ring *);
+void igb_update_stats(struct igb_adapter *);
+static int igb_probe(struct pci_dev *, const struct pci_device_id *);
+static void __devexit igb_remove(struct pci_dev *pdev);
+static int igb_sw_init(struct igb_adapter *);
+static int igb_open(struct net_device *);
+static int igb_close(struct net_device *);
+static void igb_configure_tx(struct igb_adapter *);
+static void igb_configure_rx(struct igb_adapter *);
+static void igb_setup_rctl(struct igb_adapter *);
+static void igb_clean_all_tx_rings(struct igb_adapter *);
+static void igb_clean_all_rx_rings(struct igb_adapter *);
+static void igb_clean_tx_ring(struct igb_adapter *, struct igb_ring *);
+static void igb_clean_rx_ring(struct igb_adapter *, struct igb_ring *);
+static void igb_set_multi(struct net_device *);
+static void igb_update_phy_info(unsigned long);
+static void igb_watchdog(unsigned long);
+static void igb_watchdog_task(struct work_struct *);
+static int igb_xmit_frame_ring_adv(struct sk_buff *, struct net_device *,
+                                 struct igb_ring *);
+static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *);
+static struct net_device_stats *igb_get_stats(struct net_device *);
+static int igb_change_mtu(struct net_device *, int);
+static int igb_set_mac(struct net_device *, void *);
+static irqreturn_t igb_intr(int irq, void *);
+static irqreturn_t igb_intr_msi(int irq, void *);
+static irqreturn_t igb_msix_other(int irq, void *);
+static irqreturn_t igb_msix_rx(int irq, void *);
+static irqreturn_t igb_msix_tx(int irq, void *);
+static int igb_clean_rx_ring_msix(struct napi_struct *, int);
+static bool igb_clean_tx_irq(struct igb_adapter *, struct igb_ring *);
+static int igb_clean(struct napi_struct *, int);
+static bool igb_clean_rx_irq_adv(struct igb_adapter *,
+                                struct igb_ring *, int *, int);
+static void igb_alloc_rx_buffers_adv(struct igb_adapter *,
+                                    struct igb_ring *, int);
+static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
+static void igb_tx_timeout(struct net_device *);
+static void igb_reset_task(struct work_struct *);
+static void igb_vlan_rx_register(struct net_device *, struct vlan_group *);
+static void igb_vlan_rx_add_vid(struct net_device *, u16);
+static void igb_vlan_rx_kill_vid(struct net_device *, u16);
+static void igb_restore_vlan(struct igb_adapter *);
+
+static int igb_suspend(struct pci_dev *, pm_message_t);
+#ifdef CONFIG_PM
+static int igb_resume(struct pci_dev *);
+#endif
+static void igb_shutdown(struct pci_dev *);
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/* for netdump / net console */
+static void igb_netpoll(struct net_device *);
+#endif
+
+static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
+                    pci_channel_state_t);
+static pci_ers_result_t igb_io_slot_reset(struct pci_dev *);
+static void igb_io_resume(struct pci_dev *);
+
+static struct pci_error_handlers igb_err_handler = {
+       .error_detected = igb_io_error_detected,
+       .slot_reset = igb_io_slot_reset,
+       .resume = igb_io_resume,
+};
+
+
+static struct pci_driver igb_driver = {
+       .name     = igb_driver_name,
+       .id_table = igb_pci_tbl,
+       .probe    = igb_probe,
+       .remove   = __devexit_p(igb_remove),
+#ifdef CONFIG_PM
+       /* Power Managment Hooks */
+       .suspend  = igb_suspend,
+       .resume   = igb_resume,
+#endif
+       .shutdown = igb_shutdown,
+       .err_handler = &igb_err_handler
+};
+
+MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
+MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+#ifdef DEBUG
+/**
+ * igb_get_hw_dev_name - return device name string
+ * used by hardware layer to print debugging information
+ **/
+char *igb_get_hw_dev_name(struct e1000_hw *hw)
+{
+       struct igb_adapter *adapter = hw->back;
+       return adapter->netdev->name;
+}
+#endif
+
+/**
+ * igb_init_module - Driver Registration Routine
+ *
+ * igb_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ **/
+static int __init igb_init_module(void)
+{
+       int ret;
+       printk(KERN_INFO "%s - version %s\n",
+              igb_driver_string, igb_driver_version);
+
+       printk(KERN_INFO "%s\n", igb_copyright);
+
+       ret = pci_register_driver(&igb_driver);
+       return ret;
+}
+
+module_init(igb_init_module);
+
+/**
+ * igb_exit_module - Driver Exit Cleanup Routine
+ *
+ * igb_exit_module is called just before the driver is removed
+ * from memory.
+ **/
+static void __exit igb_exit_module(void)
+{
+       pci_unregister_driver(&igb_driver);
+}
+
+module_exit(igb_exit_module);
+
+/**
+ * igb_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one ring per queue at run-time since we don't know the
+ * number of queues at compile-time.
+ **/
+static int igb_alloc_queues(struct igb_adapter *adapter)
+{
+       int i;
+
+       adapter->tx_ring = kcalloc(adapter->num_tx_queues,
+                                  sizeof(struct igb_ring), GFP_KERNEL);
+       if (!adapter->tx_ring)
+               return -ENOMEM;
+
+       adapter->rx_ring = kcalloc(adapter->num_rx_queues,
+                                  sizeof(struct igb_ring), GFP_KERNEL);
+       if (!adapter->rx_ring) {
+               kfree(adapter->tx_ring);
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               struct igb_ring *ring = &(adapter->rx_ring[i]);
+               ring->adapter = adapter;
+               ring->itr_register = E1000_ITR;
+
+               if (!ring->napi.poll)
+                       netif_napi_add(adapter->netdev, &ring->napi, igb_clean,
+                                      adapter->napi.weight /
+                                      adapter->num_rx_queues);
+       }
+       return 0;
+}
+
+#define IGB_N0_QUEUE -1
+static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
+                             int tx_queue, int msix_vector)
+{
+       u32 msixbm = 0;
+       struct e1000_hw *hw = &adapter->hw;
+               /* The 82575 assigns vectors using a bitmask, which matches the
+                  bitmask for the EICR/EIMS/EIMC registers.  To assign one
+                  or more queues to a vector, we write the appropriate bits
+                  into the MSIXBM register for that vector. */
+               if (rx_queue > IGB_N0_QUEUE) {
+                       msixbm = E1000_EICR_RX_QUEUE0 << rx_queue;
+                       adapter->rx_ring[rx_queue].eims_value = msixbm;
+               }
+               if (tx_queue > IGB_N0_QUEUE) {
+                       msixbm |= E1000_EICR_TX_QUEUE0 << tx_queue;
+                       adapter->tx_ring[tx_queue].eims_value =
+                                 E1000_EICR_TX_QUEUE0 << tx_queue;
+               }
+               array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
+}
+
+/**
+ * igb_configure_msix - Configure MSI-X hardware
+ *
+ * igb_configure_msix sets up the hardware to properly
+ * generate MSI-X interrupts.
+ **/
+static void igb_configure_msix(struct igb_adapter *adapter)
+{
+       u32 tmp;
+       int i, vector = 0;
+       struct e1000_hw *hw = &adapter->hw;
+
+       adapter->eims_enable_mask = 0;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct igb_ring *tx_ring = &adapter->tx_ring[i];
+               igb_assign_vector(adapter, IGB_N0_QUEUE, i, vector++);
+               adapter->eims_enable_mask |= tx_ring->eims_value;
+               if (tx_ring->itr_val)
+                       writel(1000000000 / (tx_ring->itr_val * 256),
+                              hw->hw_addr + tx_ring->itr_register);
+               else
+                       writel(1, hw->hw_addr + tx_ring->itr_register);
+       }
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               struct igb_ring *rx_ring = &adapter->rx_ring[i];
+               igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
+               adapter->eims_enable_mask |= rx_ring->eims_value;
+               if (rx_ring->itr_val)
+                       writel(1000000000 / (rx_ring->itr_val * 256),
+                              hw->hw_addr + rx_ring->itr_register);
+               else
+                       writel(1, hw->hw_addr + rx_ring->itr_register);
+       }
+
+
+       /* set vector for other causes, i.e. link changes */
+               array_wr32(E1000_MSIXBM(0), vector++,
+                                     E1000_EIMS_OTHER);
+
+               /* disable IAM for ICR interrupt bits */
+               wr32(E1000_IAM, 0);
+
+               tmp = rd32(E1000_CTRL_EXT);
+               /* enable MSI-X PBA support*/
+               tmp |= E1000_CTRL_EXT_PBA_CLR;
+
+               /* Auto-Mask interrupts upon ICR read. */
+               tmp |= E1000_CTRL_EXT_EIAME;
+               tmp |= E1000_CTRL_EXT_IRCA;
+
+               wr32(E1000_CTRL_EXT, tmp);
+               adapter->eims_enable_mask |= E1000_EIMS_OTHER;
+
+       wrfl();
+}
+
+/**
+ * igb_request_msix - Initialize MSI-X interrupts
+ *
+ * igb_request_msix allocates MSI-X vectors and requests interrupts from the
+ * kernel.
+ **/
+static int igb_request_msix(struct igb_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int i, err = 0, vector = 0;
+
+       vector = 0;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct igb_ring *ring = &(adapter->tx_ring[i]);
+               sprintf(ring->name, "%s-tx%d", netdev->name, i);
+               err = request_irq(adapter->msix_entries[vector].vector,
+                                 &igb_msix_tx, 0, ring->name,
+                                 &(adapter->tx_ring[i]));
+               if (err)
+                       goto out;
+               ring->itr_register = E1000_EITR(0) + (vector << 2);
+               ring->itr_val = adapter->itr;
+               vector++;
+       }
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               struct igb_ring *ring = &(adapter->rx_ring[i]);
+               if (strlen(netdev->name) < (IFNAMSIZ - 5))
+                       sprintf(ring->name, "%s-rx%d", netdev->name, i);
+               else
+                       memcpy(ring->name, netdev->name, IFNAMSIZ);
+               err = request_irq(adapter->msix_entries[vector].vector,
+                                 &igb_msix_rx, 0, ring->name,
+                                 &(adapter->rx_ring[i]));
+               if (err)
+                       goto out;
+               ring->itr_register = E1000_EITR(0) + (vector << 2);
+               ring->itr_val = adapter->itr;
+               vector++;
+       }
+
+       err = request_irq(adapter->msix_entries[vector].vector,
+                         &igb_msix_other, 0, netdev->name, netdev);
+       if (err)
+               goto out;
+
+       adapter->napi.poll = igb_clean_rx_ring_msix;
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               adapter->rx_ring[i].napi.poll = adapter->napi.poll;
+       igb_configure_msix(adapter);
+       return 0;
+out:
+       return err;
+}
+
+static void igb_reset_interrupt_capability(struct igb_adapter *adapter)
+{
+       if (adapter->msix_entries) {
+               pci_disable_msix(adapter->pdev);
+               kfree(adapter->msix_entries);
+               adapter->msix_entries = NULL;
+       } else if (adapter->msi_enabled)
+               pci_disable_msi(adapter->pdev);
+       return;
+}
+
+
+/**
+ * igb_set_interrupt_capability - set MSI or MSI-X if supported
+ *
+ * Attempt to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static void igb_set_interrupt_capability(struct igb_adapter *adapter)
+{
+       int err;
+       int numvecs, i;
+
+       numvecs = adapter->num_tx_queues + adapter->num_rx_queues + 1;
+       adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry),
+                                       GFP_KERNEL);
+       if (!adapter->msix_entries)
+               goto msi_only;
+
+       for (i = 0; i < numvecs; i++)
+               adapter->msix_entries[i].entry = i;
+
+       err = pci_enable_msix(adapter->pdev,
+                             adapter->msix_entries,
+                             numvecs);
+       if (err == 0)
+               return;
+
+       igb_reset_interrupt_capability(adapter);
+
+       /* If we can't do MSI-X, try MSI */
+msi_only:
+       adapter->num_rx_queues = 1;
+       if (!pci_enable_msi(adapter->pdev))
+               adapter->msi_enabled = 1;
+       return;
+}
+
+/**
+ * igb_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
+static int igb_request_irq(struct igb_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct e1000_hw *hw = &adapter->hw;
+       int err = 0;
+
+       if (adapter->msix_entries) {
+               err = igb_request_msix(adapter);
+               if (!err) {
+                       struct e1000_hw *hw = &adapter->hw;
+                       /* enable IAM, auto-mask,
+                        * DO NOT USE EIAME or IAME in legacy mode */
+                       wr32(E1000_IAM, IMS_ENABLE_MASK);
+                       goto request_done;
+               }
+               /* fall back to MSI */
+               igb_reset_interrupt_capability(adapter);
+               if (!pci_enable_msi(adapter->pdev))
+                       adapter->msi_enabled = 1;
+               igb_free_all_tx_resources(adapter);
+               igb_free_all_rx_resources(adapter);
+               adapter->num_rx_queues = 1;
+               igb_alloc_queues(adapter);
+       }
+       if (adapter->msi_enabled) {
+               err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
+                                 netdev->name, netdev);
+               if (!err)
+                       goto request_done;
+               /* fall back to legacy interrupts */
+               igb_reset_interrupt_capability(adapter);
+               adapter->msi_enabled = 0;
+       }
+
+       err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
+                         netdev->name, netdev);
+
+       if (err) {
+               dev_err(&adapter->pdev->dev, "Error %d getting interrupt\n",
+                       err);
+               goto request_done;
+       }
+
+       /* enable IAM, auto-mask */
+       wr32(E1000_IAM, IMS_ENABLE_MASK);
+
+request_done:
+       return err;
+}
+
+static void igb_free_irq(struct igb_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       if (adapter->msix_entries) {
+               int vector = 0, i;
+
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       free_irq(adapter->msix_entries[vector++].vector,
+                               &(adapter->tx_ring[i]));
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       free_irq(adapter->msix_entries[vector++].vector,
+                               &(adapter->rx_ring[i]));
+
+               free_irq(adapter->msix_entries[vector++].vector, netdev);
+               return;
+       }
+
+       free_irq(adapter->pdev->irq, netdev);
+}
+
+/**
+ * igb_irq_disable - Mask off interrupt generation on the NIC
+ * @adapter: board private structure
+ **/
+static void igb_irq_disable(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (adapter->msix_entries) {
+               wr32(E1000_EIMC, ~0);
+               wr32(E1000_EIAC, 0);
+       }
+       wr32(E1000_IMC, ~0);
+       wrfl();
+       synchronize_irq(adapter->pdev->irq);
+}
+
+/**
+ * igb_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ **/
+static void igb_irq_enable(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (adapter->msix_entries) {
+               wr32(E1000_EIMS,
+                               adapter->eims_enable_mask);
+               wr32(E1000_EIAC,
+                               adapter->eims_enable_mask);
+               wr32(E1000_IMS, E1000_IMS_LSC);
+       } else
+       wr32(E1000_IMS, IMS_ENABLE_MASK);
+}
+
+static void igb_update_mng_vlan(struct igb_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       u16 vid = adapter->hw.mng_cookie.vlan_id;
+       u16 old_vid = adapter->mng_vlan_id;
+       if (adapter->vlgrp) {
+               if (!vlan_group_get_device(adapter->vlgrp, vid)) {
+                       if (adapter->hw.mng_cookie.status &
+                               E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
+                               igb_vlan_rx_add_vid(netdev, vid);
+                               adapter->mng_vlan_id = vid;
+                       } else
+                               adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
+
+                       if ((old_vid != (u16)IGB_MNG_VLAN_NONE) &&
+                                       (vid != old_vid) &&
+                           !vlan_group_get_device(adapter->vlgrp, old_vid))
+                               igb_vlan_rx_kill_vid(netdev, old_vid);
+               } else
+                       adapter->mng_vlan_id = vid;
+       }
+}
+
+/**
+ * igb_release_hw_control - release control of the h/w to f/w
+ * @adapter: address of board private structure
+ *
+ * igb_release_hw_control resets CTRL_EXT:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means that the
+ * driver is no longer loaded.
+ *
+ **/
+static void igb_release_hw_control(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl_ext;
+
+       /* Let firmware take over control of h/w */
+       ctrl_ext = rd32(E1000_CTRL_EXT);
+       wr32(E1000_CTRL_EXT,
+                       ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+}
+
+
+/**
+ * igb_get_hw_control - get control of the h/w from f/w
+ * @adapter: address of board private structure
+ *
+ * igb_get_hw_control sets CTRL_EXT:DRV_LOAD bit.
+ * For ASF and Pass Through versions of f/w this means that
+ * the driver is loaded.
+ *
+ **/
+static void igb_get_hw_control(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl_ext;
+
+       /* Let firmware know the driver has taken over */
+       ctrl_ext = rd32(E1000_CTRL_EXT);
+       wr32(E1000_CTRL_EXT,
+                       ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+}
+
+static void igb_init_manageability(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (adapter->en_mng_pt) {
+               u32 manc2h = rd32(E1000_MANC2H);
+               u32 manc = rd32(E1000_MANC);
+
+               /* disable hardware interception of ARP */
+               manc &= ~(E1000_MANC_ARP_EN);
+
+               /* enable receiving management packets to the host */
+               /* this will probably generate destination unreachable messages
+                * from the host OS, but the packets will be handled on SMBUS */
+               manc |= E1000_MANC_EN_MNG2HOST;
+#define E1000_MNG2HOST_PORT_623 (1 << 5)
+#define E1000_MNG2HOST_PORT_664 (1 << 6)
+               manc2h |= E1000_MNG2HOST_PORT_623;
+               manc2h |= E1000_MNG2HOST_PORT_664;
+               wr32(E1000_MANC2H, manc2h);
+
+               wr32(E1000_MANC, manc);
+       }
+}
+
+static void igb_release_manageability(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (adapter->en_mng_pt) {
+               u32 manc = rd32(E1000_MANC);
+
+               /* re-enable hardware interception of ARP */
+               manc |= E1000_MANC_ARP_EN;
+               manc &= ~E1000_MANC_EN_MNG2HOST;
+
+               /* don't explicitly have to mess with MANC2H since
+                * MANC has an enable disable that gates MANC2H */
+
+               /* XXX stop the hardware watchdog ? */
+               wr32(E1000_MANC, manc);
+       }
+}
+
+/**
+ * igb_configure - configure the hardware for RX and TX
+ * @adapter: private board structure
+ **/
+static void igb_configure(struct igb_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int i;
+
+       igb_get_hw_control(adapter);
+       igb_set_multi(netdev);
+
+       igb_restore_vlan(adapter);
+       igb_init_manageability(adapter);
+
+       igb_configure_tx(adapter);
+       igb_setup_rctl(adapter);
+       igb_configure_rx(adapter);
+       /* call IGB_DESC_UNUSED which always leaves
+        * at least 1 descriptor unused to make sure
+        * next_to_use != next_to_clean */
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               struct igb_ring *ring = &adapter->rx_ring[i];
+               igb_alloc_rx_buffers_adv(adapter, ring, IGB_DESC_UNUSED(ring));
+       }
+
+
+       adapter->tx_queue_len = netdev->tx_queue_len;
+}
+
+
+/**
+ * igb_up - Open the interface and prepare it to handle traffic
+ * @adapter: board private structure
+ **/
+
+int igb_up(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       int i;
+
+       /* hardware has been reset, we need to reload some things */
+       igb_configure(adapter);
+
+       clear_bit(__IGB_DOWN, &adapter->state);
+
+       napi_enable(&adapter->napi);
+
+       if (adapter->msix_entries) {
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       napi_enable(&adapter->rx_ring[i].napi);
+               igb_configure_msix(adapter);
+       }
+
+       /* Clear any pending interrupts. */
+       rd32(E1000_ICR);
+       igb_irq_enable(adapter);
+
+       /* Fire a link change interrupt to start the watchdog. */
+       wr32(E1000_ICS, E1000_ICS_LSC);
+       return 0;
+}
+
+void igb_down(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       u32 tctl, rctl;
+       int i;
+
+       /* signal that we're down so the interrupt handler does not
+        * reschedule our watchdog timer */
+       set_bit(__IGB_DOWN, &adapter->state);
+
+       /* disable receives in the hardware */
+       rctl = rd32(E1000_RCTL);
+       wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
+       /* flush and sleep below */
+
+       netif_stop_queue(netdev);
+
+       /* disable transmits in the hardware */
+       tctl = rd32(E1000_TCTL);
+       tctl &= ~E1000_TCTL_EN;
+       wr32(E1000_TCTL, tctl);
+       /* flush both disables and wait for them to finish */
+       wrfl();
+       msleep(10);
+
+       napi_disable(&adapter->napi);
+
+       if (adapter->msix_entries)
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       napi_disable(&adapter->rx_ring[i].napi);
+       igb_irq_disable(adapter);
+
+       del_timer_sync(&adapter->watchdog_timer);
+       del_timer_sync(&adapter->phy_info_timer);
+
+       netdev->tx_queue_len = adapter->tx_queue_len;
+       netif_carrier_off(netdev);
+       adapter->link_speed = 0;
+       adapter->link_duplex = 0;
+
+       igb_reset(adapter);
+       igb_clean_all_tx_rings(adapter);
+       igb_clean_all_rx_rings(adapter);
+}
+
+void igb_reinit_locked(struct igb_adapter *adapter)
+{
+       WARN_ON(in_interrupt());
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+       igb_down(adapter);
+       igb_up(adapter);
+       clear_bit(__IGB_RESETTING, &adapter->state);
+}
+
+void igb_reset(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct e1000_fc_info *fc = &adapter->hw.fc;
+       u32 pba = 0, tx_space, min_tx_space, min_rx_space;
+       u16 hwm;
+
+       /* Repartition Pba for greater than 9k mtu
+        * To take effect CTRL.RST is required.
+        */
+       pba = E1000_PBA_34K;
+
+       if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
+               /* adjust PBA for jumbo frames */
+               wr32(E1000_PBA, pba);
+
+               /* To maintain wire speed transmits, the Tx FIFO should be
+                * large enough to accommodate two full transmit packets,
+                * rounded up to the next 1KB and expressed in KB.  Likewise,
+                * the Rx FIFO should be large enough to accommodate at least
+                * one full receive packet and is similarly rounded up and
+                * expressed in KB. */
+               pba = rd32(E1000_PBA);
+               /* upper 16 bits has Tx packet buffer allocation size in KB */
+               tx_space = pba >> 16;
+               /* lower 16 bits has Rx packet buffer allocation size in KB */
+               pba &= 0xffff;
+               /* the tx fifo also stores 16 bytes of information about the tx
+                * but don't include ethernet FCS because hardware appends it */
+               min_tx_space = (adapter->max_frame_size +
+                               sizeof(struct e1000_tx_desc) -
+                               ETH_FCS_LEN) * 2;
+               min_tx_space = ALIGN(min_tx_space, 1024);
+               min_tx_space >>= 10;
+               /* software strips receive CRC, so leave room for it */
+               min_rx_space = adapter->max_frame_size;
+               min_rx_space = ALIGN(min_rx_space, 1024);
+               min_rx_space >>= 10;
+
+               /* If current Tx allocation is less than the min Tx FIFO size,
+                * and the min Tx FIFO size is less than the current Rx FIFO
+                * allocation, take space away from current Rx allocation */
+               if (tx_space < min_tx_space &&
+                   ((min_tx_space - tx_space) < pba)) {
+                       pba = pba - (min_tx_space - tx_space);
+
+                       /* if short on rx space, rx wins and must trump tx
+                        * adjustment */
+                       if (pba < min_rx_space)
+                               pba = min_rx_space;
+               }
+       }
+       wr32(E1000_PBA, pba);
+
+       /* flow control settings */
+       /* The high water mark must be low enough to fit one 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, or
+        * - the full Rx FIFO size minus one full frame */
+       hwm = min(((pba << 10) * 9 / 10),
+                 ((pba << 10) - adapter->max_frame_size));
+
+       fc->high_water = hwm & 0xFFF8;  /* 8-byte granularity */
+       fc->low_water = fc->high_water - 8;
+       fc->pause_time = 0xFFFF;
+       fc->send_xon = 1;
+       fc->type = fc->original_type;
+
+       /* Allow time for pending master requests to run */
+       adapter->hw.mac.ops.reset_hw(&adapter->hw);
+       wr32(E1000_WUC, 0);
+
+       if (adapter->hw.mac.ops.init_hw(&adapter->hw))
+               dev_err(&adapter->pdev->dev, "Hardware Error\n");
+
+       igb_update_mng_vlan(adapter);
+
+       /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
+       wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
+
+       igb_reset_adaptive(&adapter->hw);
+       adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+       igb_release_manageability(adapter);
+}
+
+/**
+ * igb_probe - Device Initialization Routine
+ * @pdev: PCI device information struct
+ * @ent: entry in igb_pci_tbl
+ *
+ * Returns 0 on success, negative on failure
+ *
+ * igb_probe initializes an adapter identified by a pci_dev structure.
+ * The OS initialization, configuring of the adapter private structure,
+ * and a hardware reset occur.
+ **/
+static int __devinit igb_probe(struct pci_dev *pdev,
+                              const struct pci_device_id *ent)
+{
+       struct net_device *netdev;
+       struct igb_adapter *adapter;
+       struct e1000_hw *hw;
+       const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
+       unsigned long mmio_start, mmio_len;
+       static int cards_found;
+       int i, err, pci_using_dac;
+       u16 eeprom_data = 0;
+       u16 eeprom_apme_mask = IGB_EEPROM_APME;
+       u32 part_num;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       pci_using_dac = 0;
+       err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+       if (!err) {
+               err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               if (!err)
+                       pci_using_dac = 1;
+       } else {
+               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               if (err) {
+                       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       if (err) {
+                               dev_err(&pdev->dev, "No usable DMA "
+                                       "configuration, aborting\n");
+                               goto err_dma;
+                       }
+               }
+       }
+
+       err = pci_request_regions(pdev, igb_driver_name);
+       if (err)
+               goto err_pci_reg;
+
+       pci_set_master(pdev);
+
+       err = -ENOMEM;
+       netdev = alloc_etherdev(sizeof(struct igb_adapter));
+       if (!netdev)
+               goto err_alloc_etherdev;
+
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+
+       pci_set_drvdata(pdev, netdev);
+       adapter = netdev_priv(netdev);
+       adapter->netdev = netdev;
+       adapter->pdev = pdev;
+       hw = &adapter->hw;
+       hw->back = adapter;
+       adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+
+       mmio_start = pci_resource_start(pdev, 0);
+       mmio_len = pci_resource_len(pdev, 0);
+
+       err = -EIO;
+       adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+       if (!adapter->hw.hw_addr)
+               goto err_ioremap;
+
+       netdev->open = &igb_open;
+       netdev->stop = &igb_close;
+       netdev->get_stats = &igb_get_stats;
+       netdev->set_multicast_list = &igb_set_multi;
+       netdev->set_mac_address = &igb_set_mac;
+       netdev->change_mtu = &igb_change_mtu;
+       netdev->do_ioctl = &igb_ioctl;
+       igb_set_ethtool_ops(netdev);
+       netdev->tx_timeout = &igb_tx_timeout;
+       netdev->watchdog_timeo = 5 * HZ;
+       netif_napi_add(netdev, &adapter->napi, igb_clean, 64);
+       netdev->vlan_rx_register = igb_vlan_rx_register;
+       netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
+       netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       netdev->poll_controller = igb_netpoll;
+#endif
+       netdev->hard_start_xmit = &igb_xmit_frame_adv;
+
+       strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
+
+       netdev->mem_start = mmio_start;
+       netdev->mem_end = mmio_start + mmio_len;
+
+       adapter->bd_number = cards_found;
+
+       /* PCI config space info */
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->revision_id = pdev->revision;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_device_id = pdev->subsystem_device;
+
+       /* setup the private structure */
+       hw->back = adapter;
+       /* Copy the default MAC, PHY and NVM function pointers */
+       memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
+       memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
+       memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops));
+       /* Initialize skew-specific constants */
+       err = ei->get_invariants(hw);
+       if (err)
+               goto err_hw_init;
+
+       err = igb_sw_init(adapter);
+       if (err)
+               goto err_sw_init;
+
+       igb_get_bus_info_pcie(hw);
+
+       hw->phy.autoneg_wait_to_complete = false;
+       hw->mac.adaptive_ifs = true;
+
+       /* Copper options */
+       if (hw->phy.media_type == e1000_media_type_copper) {
+               hw->phy.mdix = AUTO_ALL_MODES;
+               hw->phy.disable_polarity_correction = false;
+               hw->phy.ms_type = e1000_ms_hw_default;
+       }
+
+       if (igb_check_reset_block(hw))
+               dev_info(&pdev->dev,
+                       "PHY reset is blocked due to SOL/IDER session.\n");
+
+       netdev->features = NETIF_F_SG |
+                          NETIF_F_HW_CSUM |
+                          NETIF_F_HW_VLAN_TX |
+                          NETIF_F_HW_VLAN_RX |
+                          NETIF_F_HW_VLAN_FILTER;
+
+       netdev->features |= NETIF_F_TSO;
+
+       netdev->features |= NETIF_F_TSO6;
+       if (pci_using_dac)
+               netdev->features |= NETIF_F_HIGHDMA;
+
+       netdev->features |= NETIF_F_LLTX;
+       adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
+
+       /* before reading the NVM, reset the controller to put the device in a
+        * known good starting state */
+       hw->mac.ops.reset_hw(hw);
+
+       /* make sure the NVM is good */
+       if (igb_validate_nvm_checksum(hw) < 0) {
+               dev_err(&pdev->dev, "The NVM Checksum Is Not Valid\n");
+               err = -EIO;
+               goto err_eeprom;
+       }
+
+       /* copy the MAC address out of the NVM */
+       if (hw->mac.ops.read_mac_addr(hw))
+               dev_err(&pdev->dev, "NVM Read Error\n");
+
+       memcpy(netdev->dev_addr, hw->mac.addr, netdev->addr_len);
+       memcpy(netdev->perm_addr, hw->mac.addr, netdev->addr_len);
+
+       if (!is_valid_ether_addr(netdev->perm_addr)) {
+               dev_err(&pdev->dev, "Invalid MAC Address\n");
+               err = -EIO;
+               goto err_eeprom;
+       }
+
+       init_timer(&adapter->watchdog_timer);
+       adapter->watchdog_timer.function = &igb_watchdog;
+       adapter->watchdog_timer.data = (unsigned long) adapter;
+
+       init_timer(&adapter->phy_info_timer);
+       adapter->phy_info_timer.function = &igb_update_phy_info;
+       adapter->phy_info_timer.data = (unsigned long) adapter;
+
+       INIT_WORK(&adapter->reset_task, igb_reset_task);
+       INIT_WORK(&adapter->watchdog_task, igb_watchdog_task);
+
+       /* Initialize link & ring properties that are user-changeable */
+       adapter->tx_ring->count = 256;
+       for (i = 0; i < adapter->num_tx_queues; i++)
+               adapter->tx_ring[i].count = adapter->tx_ring->count;
+       adapter->rx_ring->count = 256;
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               adapter->rx_ring[i].count = adapter->rx_ring->count;
+
+       adapter->fc_autoneg = true;
+       hw->mac.autoneg = true;
+       hw->phy.autoneg_advertised = 0x2f;
+
+       hw->fc.original_type = e1000_fc_default;
+       hw->fc.type = e1000_fc_default;
+
+       adapter->itr_setting = 3;
+       adapter->itr = IGB_START_ITR;
+
+       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
+        */
+
+       if (hw->bus.func == 0 ||
+           hw->device_id == E1000_DEV_ID_82575EB_COPPER)
+               hw->nvm.ops.read_nvm(hw, NVM_INIT_CONTROL3_PORT_A, 1,
+                                    &eeprom_data);
+
+       if (eeprom_data & eeprom_apme_mask)
+               adapter->eeprom_wol |= E1000_WUFC_MAG;
+
+       /* now that we have the eeprom settings, apply the special cases where
+        * the eeprom may be wrong or the board simply won't support wake on
+        * lan on a particular port */
+       switch (pdev->device) {
+       case E1000_DEV_ID_82575GB_QUAD_COPPER:
+               adapter->eeprom_wol = 0;
+               break;
+       case E1000_DEV_ID_82575EB_FIBER_SERDES:
+               /* Wake events only supported on port A for dual fiber
+                * regardless of eeprom setting */
+               if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
+                       adapter->eeprom_wol = 0;
+               break;
+       }
+
+       /* initialize the wol settings based on the eeprom settings */
+       adapter->wol = adapter->eeprom_wol;
+
+       /* reset the hardware with the new settings */
+       igb_reset(adapter);
+
+       /* let the f/w know that the h/w is now under the control of the
+        * driver. */
+       igb_get_hw_control(adapter);
+
+       /* tell the stack to leave us alone until igb_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;
+
+       dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
+       /* print bus type/speed/width info */
+       dev_info(&pdev->dev,
+                "%s: (PCIe:%s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+                netdev->name,
+                ((hw->bus.speed == e1000_bus_speed_2500)
+                 ? "2.5Gb/s" : "unknown"),
+                ((hw->bus.width == e1000_bus_width_pcie_x4)
+                 ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
+                 ? "Width x1" : "unknown"),
+                netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+                netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+
+       igb_read_part_num(hw, &part_num);
+       dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name,
+               (part_num >> 8), (part_num & 0xff));
+
+       dev_info(&pdev->dev,
+               "Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
+               adapter->msix_entries ? "MSI-X" :
+               adapter->msi_enabled ? "MSI" : "legacy",
+               adapter->num_rx_queues, adapter->num_tx_queues);
+
+       cards_found++;
+       return 0;
+
+err_register:
+       igb_release_hw_control(adapter);
+err_eeprom:
+       if (!igb_check_reset_block(hw))
+               hw->phy.ops.reset_phy(hw);
+
+       if (hw->flash_address)
+               iounmap(hw->flash_address);
+
+       igb_remove_device(hw);
+       kfree(adapter->tx_ring);
+       kfree(adapter->rx_ring);
+err_sw_init:
+err_hw_init:
+       iounmap(hw->hw_addr);
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       pci_release_regions(pdev);
+err_pci_reg:
+err_dma:
+       pci_disable_device(pdev);
+       return err;
+}
+
+/**
+ * igb_remove - Device Removal Routine
+ * @pdev: PCI device information struct
+ *
+ * igb_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.  The could be caused by a
+ * Hot-Plug event, or because the driver is going to be removed from
+ * memory.
+ **/
+static void __devexit igb_remove(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       /* flush_scheduled work may reschedule our watchdog task, so
+        * explicitly disable watchdog tasks from being rescheduled  */
+       set_bit(__IGB_DOWN, &adapter->state);
+       del_timer_sync(&adapter->watchdog_timer);
+       del_timer_sync(&adapter->phy_info_timer);
+
+       flush_scheduled_work();
+
+
+       igb_release_manageability(adapter);
+
+       /* Release control of h/w to f/w.  If f/w is AMT enabled, this
+        * would have already happened in close and is redundant. */
+       igb_release_hw_control(adapter);
+
+       unregister_netdev(netdev);
+
+       if (!igb_check_reset_block(&adapter->hw))
+               adapter->hw.phy.ops.reset_phy(&adapter->hw);
+
+       igb_remove_device(&adapter->hw);
+       igb_reset_interrupt_capability(adapter);
+
+       kfree(adapter->tx_ring);
+       kfree(adapter->rx_ring);
+
+       iounmap(adapter->hw.hw_addr);
+       if (adapter->hw.flash_address)
+               iounmap(adapter->hw.flash_address);
+       pci_release_regions(pdev);
+
+       free_netdev(netdev);
+
+       pci_disable_device(pdev);
+}
+
+/**
+ * igb_sw_init - Initialize general software structures (struct igb_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * igb_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+static int __devinit igb_sw_init(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+
+       pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
+
+       adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+       adapter->rx_ps_hdr_size = 0; /* disable packet split */
+       adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+       adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+
+       /* Number of supported queues. */
+       /* Having more queues than CPUs doesn't make sense. */
+       adapter->num_tx_queues = 1;
+       adapter->num_rx_queues = min(IGB_MAX_RX_QUEUES, num_online_cpus());
+
+       igb_set_interrupt_capability(adapter);
+
+       if (igb_alloc_queues(adapter)) {
+               dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+               return -ENOMEM;
+       }
+
+       /* Explicitly disable IRQ since the NIC can be in any state. */
+       igb_irq_disable(adapter);
+
+       set_bit(__IGB_DOWN, &adapter->state);
+       return 0;
+}
+
+/**
+ * igb_open - Called when a network interface is made active
+ * @netdev: network interface device structure
+ *
+ * Returns 0 on success, negative value on failure
+ *
+ * The open entry point is called when a network interface is made
+ * active by the system (IFF_UP).  At this point all resources needed
+ * for transmit and receive operations are allocated, the interrupt
+ * handler is registered with the OS, the watchdog timer is started,
+ * and the stack is notified that the interface is ready.
+ **/
+static int igb_open(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       int err;
+       int i;
+
+       /* disallow open during test */
+       if (test_bit(__IGB_TESTING, &adapter->state))
+               return -EBUSY;
+
+       /* allocate transmit descriptors */
+       err = igb_setup_all_tx_resources(adapter);
+       if (err)
+               goto err_setup_tx;
+
+       /* allocate receive descriptors */
+       err = igb_setup_all_rx_resources(adapter);
+       if (err)
+               goto err_setup_rx;
+
+       /* e1000_power_up_phy(adapter); */
+
+       adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
+       if ((adapter->hw.mng_cookie.status &
+            E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
+               igb_update_mng_vlan(adapter);
+
+       /* before we allocate an interrupt, we must be ready to handle it.
+        * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
+        * as soon as we call pci_request_irq, so we have to setup our
+        * clean_rx handler before we do so.  */
+       igb_configure(adapter);
+
+       err = igb_request_irq(adapter);
+       if (err)
+               goto err_req_irq;
+
+       /* From here on the code is the same as igb_up() */
+       clear_bit(__IGB_DOWN, &adapter->state);
+
+       napi_enable(&adapter->napi);
+       if (adapter->msix_entries)
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       napi_enable(&adapter->rx_ring[i].napi);
+
+       igb_irq_enable(adapter);
+
+       /* Clear any pending interrupts. */
+       rd32(E1000_ICR);
+       /* Fire a link status change interrupt to start the watchdog. */
+       wr32(E1000_ICS, E1000_ICS_LSC);
+
+       return 0;
+
+err_req_irq:
+       igb_release_hw_control(adapter);
+       /* e1000_power_down_phy(adapter); */
+       igb_free_all_rx_resources(adapter);
+err_setup_rx:
+       igb_free_all_tx_resources(adapter);
+err_setup_tx:
+       igb_reset(adapter);
+
+       return err;
+}
+
+/**
+ * igb_close - Disables a network interface
+ * @netdev: network interface device structure
+ *
+ * Returns 0, this is not allowed to fail
+ *
+ * The close entry point is called when an interface is de-activated
+ * by the OS.  The hardware is still under the driver's control, but
+ * needs to be disabled.  A global MAC reset is issued to stop the
+ * hardware, and all transmit and receive resources are freed.
+ **/
+static int igb_close(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
+       igb_down(adapter);
+
+       igb_free_irq(adapter);
+
+       igb_free_all_tx_resources(adapter);
+       igb_free_all_rx_resources(adapter);
+
+       /* kill manageability vlan ID if supported, but not if a vlan with
+        * the same ID is registered on the host OS (let 8021q kill it) */
+       if ((adapter->hw.mng_cookie.status &
+                         E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
+            !(adapter->vlgrp &&
+              vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
+               igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+
+       return 0;
+}
+
+/**
+ * igb_setup_tx_resources - allocate Tx resources (Descriptors)
+ * @adapter: board private structure
+ * @tx_ring: tx descriptor ring (for a specific queue) to setup
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int igb_setup_tx_resources(struct igb_adapter *adapter,
+                          struct igb_ring *tx_ring)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int size;
+
+       size = sizeof(struct igb_buffer) * tx_ring->count;
+       tx_ring->buffer_info = vmalloc(size);
+       if (!tx_ring->buffer_info)
+               goto err;
+       memset(tx_ring->buffer_info, 0, size);
+
+       /* round up to nearest 4K */
+       tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc)
+                       + sizeof(u32);
+       tx_ring->size = ALIGN(tx_ring->size, 4096);
+
+       tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+                                            &tx_ring->dma);
+
+       if (!tx_ring->desc)
+               goto err;
+
+       tx_ring->adapter = adapter;
+       tx_ring->next_to_use = 0;
+       tx_ring->next_to_clean = 0;
+       spin_lock_init(&tx_ring->tx_clean_lock);
+       spin_lock_init(&tx_ring->tx_lock);
+       return 0;
+
+err:
+       vfree(tx_ring->buffer_info);
+       dev_err(&adapter->pdev->dev,
+               "Unable to allocate memory for the transmit descriptor ring\n");
+       return -ENOMEM;
+}
+
+/**
+ * igb_setup_all_tx_resources - wrapper to allocate Tx resources
+ *                               (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
+{
+       int i, err = 0;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+               if (err) {
+                       dev_err(&adapter->pdev->dev,
+                               "Allocation for Tx Queue %u failed\n", i);
+                       for (i--; i >= 0; i--)
+                               igb_free_tx_resources(adapter,
+                                                       &adapter->tx_ring[i]);
+                       break;
+               }
+       }
+
+       return err;
+}
+
+/**
+ * igb_configure_tx - Configure transmit Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Tx unit of the MAC after a reset.
+ **/
+static void igb_configure_tx(struct igb_adapter *adapter)
+{
+       u64 tdba, tdwba;
+       struct e1000_hw *hw = &adapter->hw;
+       u32 tctl;
+       u32 txdctl, txctrl;
+       int i;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               struct igb_ring *ring = &(adapter->tx_ring[i]);
+
+               wr32(E1000_TDLEN(i),
+                               ring->count * sizeof(struct e1000_tx_desc));
+               tdba = ring->dma;
+               wr32(E1000_TDBAL(i),
+                               tdba & 0x00000000ffffffffULL);
+               wr32(E1000_TDBAH(i), tdba >> 32);
+
+               tdwba = ring->dma + ring->count * sizeof(struct e1000_tx_desc);
+               tdwba |= 1; /* enable head wb */
+               wr32(E1000_TDWBAL(i),
+                               tdwba & 0x00000000ffffffffULL);
+               wr32(E1000_TDWBAH(i), tdwba >> 32);
+
+               ring->head = E1000_TDH(i);
+               ring->tail = E1000_TDT(i);
+               writel(0, hw->hw_addr + ring->tail);
+               writel(0, hw->hw_addr + ring->head);
+               txdctl = rd32(E1000_TXDCTL(i));
+               txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+               wr32(E1000_TXDCTL(i), txdctl);
+
+               /* Turn off Relaxed Ordering on head write-backs.  The
+                * writebacks MUST be delivered in order or it will
+                * completely screw up our bookeeping.
+                */
+               txctrl = rd32(E1000_DCA_TXCTRL(i));
+               txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
+               wr32(E1000_DCA_TXCTRL(i), txctrl);
+       }
+
+
+
+       /* Use the default values for the Tx Inter Packet Gap (IPG) timer */
+
+       /* Program the Transmit Control Register */
+
+       tctl = rd32(E1000_TCTL);
+       tctl &= ~E1000_TCTL_CT;
+       tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
+               (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+
+       igb_config_collision_dist(hw);
+
+       /* Setup Transmit Descriptor Settings for eop descriptor */
+       adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_RS;
+
+       /* Enable transmits */
+       tctl |= E1000_TCTL_EN;
+
+       wr32(E1000_TCTL, tctl);
+}
+
+/**
+ * igb_setup_rx_resources - allocate Rx resources (Descriptors)
+ * @adapter: board private structure
+ * @rx_ring:    rx descriptor ring (for a specific queue) to setup
+ *
+ * Returns 0 on success, negative on failure
+ **/
+
+int igb_setup_rx_resources(struct igb_adapter *adapter,
+                          struct igb_ring *rx_ring)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       int size, desc_len;
+
+       size = sizeof(struct igb_buffer) * rx_ring->count;
+       rx_ring->buffer_info = vmalloc(size);
+       if (!rx_ring->buffer_info)
+               goto err;
+       memset(rx_ring->buffer_info, 0, size);
+
+       desc_len = sizeof(union e1000_adv_rx_desc);
+
+       /* Round up to nearest 4K */
+       rx_ring->size = rx_ring->count * desc_len;
+       rx_ring->size = ALIGN(rx_ring->size, 4096);
+
+       rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+                                            &rx_ring->dma);
+
+       if (!rx_ring->desc)
+               goto err;
+
+       rx_ring->next_to_clean = 0;
+       rx_ring->next_to_use = 0;
+       rx_ring->pending_skb = NULL;
+
+       rx_ring->adapter = adapter;
+       /* FIXME: do we want to setup ring->napi->poll here? */
+       rx_ring->napi.poll = adapter->napi.poll;
+
+       return 0;
+
+err:
+       vfree(rx_ring->buffer_info);
+       dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
+               "the receive descriptor ring\n");
+       return -ENOMEM;
+}
+
+/**
+ * igb_setup_all_rx_resources - wrapper to allocate Rx resources
+ *                               (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
+{
+       int i, err = 0;
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               err = igb_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+               if (err) {
+                       dev_err(&adapter->pdev->dev,
+                               "Allocation for Rx Queue %u failed\n", i);
+                       for (i--; i >= 0; i--)
+                               igb_free_rx_resources(adapter,
+                                                       &adapter->rx_ring[i]);
+                       break;
+               }
+       }
+
+       return err;
+}
+
+/**
+ * igb_setup_rctl - configure the receive control registers
+ * @adapter: Board private structure
+ **/
+static void igb_setup_rctl(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 rctl;
+       u32 srrctl = 0;
+       int i;
+
+       rctl = rd32(E1000_RCTL);
+
+       rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+
+       rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
+               E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+               (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
+
+       /* disable the stripping of CRC because it breaks
+        * BMC firmware connected over SMBUS
+       rctl |= E1000_RCTL_SECRC;
+       */
+
+       rctl &= ~E1000_RCTL_SBP;
+
+       if (adapter->netdev->mtu <= ETH_DATA_LEN)
+               rctl &= ~E1000_RCTL_LPE;
+       else
+               rctl |= E1000_RCTL_LPE;
+       if (adapter->rx_buffer_len <= IGB_RXBUFFER_2048) {
+               /* Setup buffer sizes */
+               rctl &= ~E1000_RCTL_SZ_4096;
+               rctl |= E1000_RCTL_BSEX;
+               switch (adapter->rx_buffer_len) {
+               case IGB_RXBUFFER_256:
+                       rctl |= E1000_RCTL_SZ_256;
+                       rctl &= ~E1000_RCTL_BSEX;
+                       break;
+               case IGB_RXBUFFER_512:
+                       rctl |= E1000_RCTL_SZ_512;
+                       rctl &= ~E1000_RCTL_BSEX;
+                       break;
+               case IGB_RXBUFFER_1024:
+                       rctl |= E1000_RCTL_SZ_1024;
+                       rctl &= ~E1000_RCTL_BSEX;
+                       break;
+               case IGB_RXBUFFER_2048:
+               default:
+                       rctl |= E1000_RCTL_SZ_2048;
+                       rctl &= ~E1000_RCTL_BSEX;
+                       break;
+               case IGB_RXBUFFER_4096:
+                       rctl |= E1000_RCTL_SZ_4096;
+                       break;
+               case IGB_RXBUFFER_8192:
+                       rctl |= E1000_RCTL_SZ_8192;
+                       break;
+               case IGB_RXBUFFER_16384:
+                       rctl |= E1000_RCTL_SZ_16384;
+                       break;
+               }
+       } else {
+               rctl &= ~E1000_RCTL_BSEX;
+               srrctl = adapter->rx_buffer_len >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+       }
+
+       /* 82575 and greater support packet-split where the protocol
+        * header is placed in skb->data and the packet data is
+        * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
+        * In the case of a non-split, skb->data is linearly filled,
+        * followed by the page buffers.  Therefore, skb->data is
+        * sized to hold the largest protocol header.
+        */
+       /* allocations using alloc_page take too long for regular MTU
+        * so only enable packet split for jumbo frames */
+       if (rctl & E1000_RCTL_LPE) {
+               adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
+               srrctl = adapter->rx_ps_hdr_size <<
+                        E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
+               /* buffer size is ALWAYS one page */
+               srrctl |= PAGE_SIZE >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+               srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
+       } else {
+               adapter->rx_ps_hdr_size = 0;
+               srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
+       }
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               wr32(E1000_SRRCTL(i), srrctl);
+
+       wr32(E1000_RCTL, rctl);
+}
+
+/**
+ * igb_configure_rx - Configure receive Unit after Reset
+ * @adapter: board private structure
+ *
+ * Configure the Rx unit of the MAC after a reset.
+ **/
+static void igb_configure_rx(struct igb_adapter *adapter)
+{
+       u64 rdba;
+       struct e1000_hw *hw = &adapter->hw;
+       u32 rctl, rxcsum;
+       u32 rxdctl;
+       int i;
+
+       /* disable receives while setting up the descriptors */
+       rctl = rd32(E1000_RCTL);
+       wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
+       wrfl();
+       mdelay(10);
+
+       if (adapter->itr_setting > 3)
+               wr32(E1000_ITR,
+                               1000000000 / (adapter->itr * 256));
+
+       /* 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++) {
+               struct igb_ring *ring = &(adapter->rx_ring[i]);
+               rdba = ring->dma;
+               wr32(E1000_RDBAL(i),
+                               rdba & 0x00000000ffffffffULL);
+               wr32(E1000_RDBAH(i), rdba >> 32);
+               wr32(E1000_RDLEN(i),
+                              ring->count * sizeof(union e1000_adv_rx_desc));
+
+               ring->head = E1000_RDH(i);
+               ring->tail = E1000_RDT(i);
+               writel(0, hw->hw_addr + ring->tail);
+               writel(0, hw->hw_addr + ring->head);
+
+               rxdctl = rd32(E1000_RXDCTL(i));
+               rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
+               rxdctl &= 0xFFF00000;
+               rxdctl |= IGB_RX_PTHRESH;
+               rxdctl |= IGB_RX_HTHRESH << 8;
+               rxdctl |= IGB_RX_WTHRESH << 16;
+               wr32(E1000_RXDCTL(i), rxdctl);
+       }
+
+       if (adapter->num_rx_queues > 1) {
+               u32 random[10];
+               u32 mrqc;
+               u32 j, shift;
+               union e1000_reta {
+                       u32 dword;
+                       u8  bytes[4];
+               } reta;
+
+               get_random_bytes(&random[0], 40);
+
+               shift = 6;
+               for (j = 0; j < (32 * 4); j++) {
+                       reta.bytes[j & 3] =
+                               (j % adapter->num_rx_queues) << shift;
+                       if ((j & 3) == 3)
+                               writel(reta.dword,
+                                      hw->hw_addr + E1000_RETA(0) + (j & ~3));
+               }
+               mrqc = E1000_MRQC_ENABLE_RSS_4Q;
+
+               /* Fill out hash function seeds */
+               for (j = 0; j < 10; j++)
+                       array_wr32(E1000_RSSRK(0), j, random[j]);
+
+               mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+                        E1000_MRQC_RSS_FIELD_IPV4_TCP);
+               mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
+                        E1000_MRQC_RSS_FIELD_IPV6_TCP);
+               mrqc |= (E1000_MRQC_RSS_FIELD_IPV4_UDP |
+                        E1000_MRQC_RSS_FIELD_IPV6_UDP);
+               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 {
+               /* Enable Receive Checksum Offload for TCP and UDP */
+               rxcsum = rd32(E1000_RXCSUM);
+               if (adapter->rx_csum) {
+                       rxcsum |= E1000_RXCSUM_TUOFL;
+
+                       /* Enable IPv4 payload checksum for UDP fragments
+                        * Must be used in conjunction with packet-split. */
+                       if (adapter->rx_ps_hdr_size)
+                               rxcsum |= E1000_RXCSUM_IPPCSE;
+               } else {
+                       rxcsum &= ~E1000_RXCSUM_TUOFL;
+                       /* don't need to clear IPPCSE as it defaults to 0 */
+               }
+               wr32(E1000_RXCSUM, rxcsum);
+       }
+
+       if (adapter->vlgrp)
+               wr32(E1000_RLPML,
+                               adapter->max_frame_size + VLAN_TAG_SIZE);
+       else
+               wr32(E1000_RLPML, adapter->max_frame_size);
+
+       /* Enable Receives */
+       wr32(E1000_RCTL, rctl);
+}
+
+/**
+ * igb_free_tx_resources - Free Tx Resources per Queue
+ * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
+ *
+ * Free all transmit software resources
+ **/
+static void igb_free_tx_resources(struct igb_adapter *adapter,
+                                 struct igb_ring *tx_ring)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       igb_clean_tx_ring(adapter, tx_ring);
+
+       vfree(tx_ring->buffer_info);
+       tx_ring->buffer_info = NULL;
+
+       pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+       tx_ring->desc = NULL;
+}
+
+/**
+ * igb_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
+static void igb_free_all_tx_resources(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_tx_queues; i++)
+               igb_free_tx_resources(adapter, &adapter->tx_ring[i]);
+}
+
+static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
+                                          struct igb_buffer *buffer_info)
+{
+       if (buffer_info->dma) {
+               pci_unmap_page(adapter->pdev,
+                               buffer_info->dma,
+                               buffer_info->length,
+                               PCI_DMA_TODEVICE);
+               buffer_info->dma = 0;
+       }
+       if (buffer_info->skb) {
+               dev_kfree_skb_any(buffer_info->skb);
+               buffer_info->skb = NULL;
+       }
+       buffer_info->time_stamp = 0;
+       /* buffer_info must be completely set up in the transmit path */
+}
+
+/**
+ * igb_clean_tx_ring - Free Tx Buffers
+ * @adapter: board private structure
+ * @tx_ring: ring to be cleaned
+ **/
+static void igb_clean_tx_ring(struct igb_adapter *adapter,
+                             struct igb_ring *tx_ring)
+{
+       struct igb_buffer *buffer_info;
+       unsigned long size;
+       unsigned int i;
+
+       if (!tx_ring->buffer_info)
+               return;
+       /* Free all the Tx ring sk_buffs */
+
+       for (i = 0; i < tx_ring->count; i++) {
+               buffer_info = &tx_ring->buffer_info[i];
+               igb_unmap_and_free_tx_resource(adapter, buffer_info);
+       }
+
+       size = sizeof(struct igb_buffer) * tx_ring->count;
+       memset(tx_ring->buffer_info, 0, size);
+
+       /* Zero out the descriptor ring */
+
+       memset(tx_ring->desc, 0, tx_ring->size);
+
+       tx_ring->next_to_use = 0;
+       tx_ring->next_to_clean = 0;
+
+       writel(0, adapter->hw.hw_addr + tx_ring->head);
+       writel(0, adapter->hw.hw_addr + tx_ring->tail);
+}
+
+/**
+ * igb_clean_all_tx_rings - Free Tx Buffers for all queues
+ * @adapter: board private structure
+ **/
+static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_tx_queues; i++)
+               igb_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+}
+
+/**
+ * igb_free_rx_resources - Free Rx Resources
+ * @adapter: board private structure
+ * @rx_ring: ring to clean the resources from
+ *
+ * Free all receive software resources
+ **/
+static void igb_free_rx_resources(struct igb_adapter *adapter,
+                                 struct igb_ring *rx_ring)
+{
+       struct pci_dev *pdev = adapter->pdev;
+
+       igb_clean_rx_ring(adapter, rx_ring);
+
+       vfree(rx_ring->buffer_info);
+       rx_ring->buffer_info = NULL;
+
+       pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+
+       rx_ring->desc = NULL;
+}
+
+/**
+ * igb_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+static void igb_free_all_rx_resources(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               igb_free_rx_resources(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * igb_clean_rx_ring - Free Rx Buffers per Queue
+ * @adapter: board private structure
+ * @rx_ring: ring to free buffers from
+ **/
+static void igb_clean_rx_ring(struct igb_adapter *adapter,
+                             struct igb_ring *rx_ring)
+{
+       struct igb_buffer *buffer_info;
+       struct pci_dev *pdev = adapter->pdev;
+       unsigned long size;
+       unsigned int i;
+
+       if (!rx_ring->buffer_info)
+               return;
+       /* Free all the Rx ring sk_buffs */
+       for (i = 0; i < rx_ring->count; i++) {
+               buffer_info = &rx_ring->buffer_info[i];
+               if (buffer_info->dma) {
+                       if (adapter->rx_ps_hdr_size)
+                               pci_unmap_single(pdev, buffer_info->dma,
+                                                adapter->rx_ps_hdr_size,
+                                                PCI_DMA_FROMDEVICE);
+                       else
+                               pci_unmap_single(pdev, buffer_info->dma,
+                                                adapter->rx_buffer_len,
+                                                PCI_DMA_FROMDEVICE);
+                       buffer_info->dma = 0;
+               }
+
+               if (buffer_info->skb) {
+                       dev_kfree_skb(buffer_info->skb);
+                       buffer_info->skb = NULL;
+               }
+               if (buffer_info->page) {
+                       pci_unmap_page(pdev, buffer_info->page_dma,
+                                      PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                       put_page(buffer_info->page);
+                       buffer_info->page = NULL;
+                       buffer_info->page_dma = 0;
+               }
+       }
+
+       /* there also may be some cached data from a chained receive */
+       if (rx_ring->pending_skb) {
+               dev_kfree_skb(rx_ring->pending_skb);
+               rx_ring->pending_skb = NULL;
+       }
+
+       size = sizeof(struct igb_buffer) * rx_ring->count;
+       memset(rx_ring->buffer_info, 0, size);
+
+       /* Zero out the descriptor ring */
+       memset(rx_ring->desc, 0, rx_ring->size);
+
+       rx_ring->next_to_clean = 0;
+       rx_ring->next_to_use = 0;
+
+       writel(0, adapter->hw.hw_addr + rx_ring->head);
+       writel(0, adapter->hw.hw_addr + rx_ring->tail);
+}
+
+/**
+ * igb_clean_all_rx_rings - Free Rx Buffers for all queues
+ * @adapter: board private structure
+ **/
+static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
+{
+       int i;
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               igb_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * igb_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igb_set_mac(struct net_device *netdev, void *p)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
+
+       adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+
+       return 0;
+}
+
+/**
+ * igb_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ **/
+static void igb_set_multi(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       struct e1000_mac_info *mac = &hw->mac;
+       struct dev_mc_list *mc_ptr;
+       u8  *mta_list;
+       u32 rctl;
+       int i;
+
+       /* Check for Promiscuous and All Multicast modes */
+
+       rctl = rd32(E1000_RCTL);
+
+       if (netdev->flags & IFF_PROMISC)
+               rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
+       else if (netdev->flags & IFF_ALLMULTI) {
+               rctl |= E1000_RCTL_MPE;
+               rctl &= ~E1000_RCTL_UPE;
+       } else
+               rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+
+       wr32(E1000_RCTL, rctl);
+
+       if (!netdev->mc_count) {
+               /* nothing to program, so clear mc list */
+               igb_update_mc_addr_list(hw, NULL, 0, 1,
+                                         mac->rar_entry_count);
+               return;
+       }
+
+       mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
+       if (!mta_list)
+               return;
+
+       /* The shared function expects a packed array of only addresses. */
+       mc_ptr = netdev->mc_list;
+
+       for (i = 0; i < netdev->mc_count; i++) {
+               if (!mc_ptr)
+                       break;
+               memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
+               mc_ptr = mc_ptr->next;
+       }
+       igb_update_mc_addr_list(hw, mta_list, i, 1, mac->rar_entry_count);
+       kfree(mta_list);
+}
+
+/* Need to wait a few seconds after link up to get diagnostic information from
+ * the phy */
+static void igb_update_phy_info(unsigned long data)
+{
+       struct igb_adapter *adapter = (struct igb_adapter *) data;
+       adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+}
+
+/**
+ * igb_watchdog - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void igb_watchdog(unsigned long data)
+{
+       struct igb_adapter *adapter = (struct igb_adapter *)data;
+       /* Do the rest outside of interrupt context */
+       schedule_work(&adapter->watchdog_task);
+}
+
+static void igb_watchdog_task(struct work_struct *work)
+{
+       struct igb_adapter *adapter = container_of(work,
+                                       struct igb_adapter, watchdog_task);
+       struct e1000_hw *hw = &adapter->hw;
+
+       struct net_device *netdev = adapter->netdev;
+       struct igb_ring *tx_ring = adapter->tx_ring;
+       struct e1000_mac_info *mac = &adapter->hw.mac;
+       u32 link;
+       s32 ret_val;
+
+       if ((netif_carrier_ok(netdev)) &&
+           (rd32(E1000_STATUS) & E1000_STATUS_LU))
+               goto link_up;
+
+       ret_val = hw->mac.ops.check_for_link(&adapter->hw);
+       if ((ret_val == E1000_ERR_PHY) &&
+           (hw->phy.type == e1000_phy_igp_3) &&
+           (rd32(E1000_CTRL) &
+            E1000_PHY_CTRL_GBE_DISABLE))
+               dev_info(&adapter->pdev->dev,
+                        "Gigabit has been disabled, downgrading speed\n");
+
+       if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
+           !(rd32(E1000_TXCW) & E1000_TXCW_ANE))
+               link = mac->serdes_has_link;
+       else
+               link = rd32(E1000_STATUS) &
+                                     E1000_STATUS_LU;
+
+       if (link) {
+               if (!netif_carrier_ok(netdev)) {
+                       u32 ctrl;
+                       hw->mac.ops.get_speed_and_duplex(&adapter->hw,
+                                                  &adapter->link_speed,
+                                                  &adapter->link_duplex);
+
+                       ctrl = rd32(E1000_CTRL);
+                       dev_info(&adapter->pdev->dev,
+                                "NIC Link is Up %d Mbps %s, "
+                                "Flow Control: %s\n",
+                                adapter->link_speed,
+                                adapter->link_duplex == FULL_DUPLEX ?
+                                "Full Duplex" : "Half Duplex",
+                                ((ctrl & E1000_CTRL_TFCE) && (ctrl &
+                                E1000_CTRL_RFCE)) ? "RX/TX" : ((ctrl &
+                                E1000_CTRL_RFCE) ? "RX" : ((ctrl &
+                                E1000_CTRL_TFCE) ? "TX" : "None")));
+
+                       /* tweak tx_queue_len according to speed/duplex and
+                        * adjust the timeout factor */
+                       netdev->tx_queue_len = adapter->tx_queue_len;
+                       adapter->tx_timeout_factor = 1;
+                       switch (adapter->link_speed) {
+                       case SPEED_10:
+                               netdev->tx_queue_len = 10;
+                               adapter->tx_timeout_factor = 14;
+                               break;
+                       case SPEED_100:
+                               netdev->tx_queue_len = 100;
+                               /* maybe add some timeout factor ? */
+                               break;
+                       }
+
+                       netif_carrier_on(netdev);
+                       netif_wake_queue(netdev);
+
+                       if (!test_bit(__IGB_DOWN, &adapter->state))
+                               mod_timer(&adapter->phy_info_timer,
+                                         round_jiffies(jiffies + 2 * HZ));
+               }
+       } else {
+               if (netif_carrier_ok(netdev)) {
+                       adapter->link_speed = 0;
+                       adapter->link_duplex = 0;
+                       dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
+                       netif_carrier_off(netdev);
+                       netif_stop_queue(netdev);
+                       if (!test_bit(__IGB_DOWN, &adapter->state))
+                               mod_timer(&adapter->phy_info_timer,
+                                         round_jiffies(jiffies + 2 * HZ));
+               }
+       }
+
+link_up:
+       igb_update_stats(adapter);
+
+       mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
+       adapter->tpt_old = adapter->stats.tpt;
+       mac->collision_delta = adapter->stats.colc - adapter->colc_old;
+       adapter->colc_old = adapter->stats.colc;
+
+       adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
+       adapter->gorc_old = adapter->stats.gorc;
+       adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
+       adapter->gotc_old = adapter->stats.gotc;
+
+       igb_update_adaptive(&adapter->hw);
+
+       if (!netif_carrier_ok(netdev)) {
+               if (IGB_DESC_UNUSED(tx_ring) + 1 < tx_ring->count) {
+                       /* 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). */
+                       adapter->tx_timeout_count++;
+                       schedule_work(&adapter->reset_task);
+               }
+       }
+
+       /* Cause software interrupt to ensure rx ring is cleaned */
+       wr32(E1000_ICS, E1000_ICS_RXDMT0);
+
+       /* Force detection of hung controller every watchdog period */
+       tx_ring->detect_tx_hung = true;
+
+       /* Reset the timer */
+       if (!test_bit(__IGB_DOWN, &adapter->state))
+               mod_timer(&adapter->watchdog_timer,
+                         round_jiffies(jiffies + 2 * HZ));
+}
+
+enum latency_range {
+       lowest_latency = 0,
+       low_latency = 1,
+       bulk_latency = 2,
+       latency_invalid = 255
+};
+
+
+static void igb_lower_rx_eitr(struct igb_adapter *adapter,
+                             struct igb_ring *rx_ring)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       int new_val;
+
+       new_val = rx_ring->itr_val / 2;
+       if (new_val < IGB_MIN_DYN_ITR)
+               new_val = IGB_MIN_DYN_ITR;
+
+       if (new_val != rx_ring->itr_val) {
+               rx_ring->itr_val = new_val;
+               wr32(rx_ring->itr_register,
+                               1000000000 / (new_val * 256));
+       }
+}
+
+static void igb_raise_rx_eitr(struct igb_adapter *adapter,
+                             struct igb_ring *rx_ring)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       int new_val;
+
+       new_val = rx_ring->itr_val * 2;
+       if (new_val > IGB_MAX_DYN_ITR)
+               new_val = IGB_MAX_DYN_ITR;
+
+       if (new_val != rx_ring->itr_val) {
+               rx_ring->itr_val = new_val;
+               wr32(rx_ring->itr_register,
+                               1000000000 / (new_val * 256));
+       }
+}
+
+/**
+ * igb_update_itr - update the dynamic ITR value based on statistics
+ *      Stores a new ITR value based on packets and byte
+ *      counts during the last interrupt.  The advantage of per interrupt
+ *      computation is faster updates and more accurate ITR for the current
+ *      traffic pattern.  Constants in this function were computed
+ *      based on theoretical maximum wire speed and thresholds were set based
+ *      on testing data as well as attempting to minimize response time
+ *      while increasing bulk throughput.
+ *      this functionality is controlled by the InterruptThrottleRate module
+ *      parameter (see igb_param.c)
+ *      NOTE:  These calculations are only valid when operating in a single-
+ *             queue environment.
+ * @adapter: pointer to adapter
+ * @itr_setting: current adapter->itr
+ * @packets: the number of packets during this measurement interval
+ * @bytes: the number of bytes during this measurement interval
+ **/
+static unsigned int igb_update_itr(struct igb_adapter *adapter, u16 itr_setting,
+                                  int packets, int bytes)
+{
+       unsigned int retval = itr_setting;
+
+       if (packets == 0)
+               goto update_itr_done;
+
+       switch (itr_setting) {
+       case lowest_latency:
+               /* handle TSO and jumbo frames */
+               if (bytes/packets > 8000)
+                       retval = bulk_latency;
+               else if ((packets < 5) && (bytes > 512))
+                       retval = low_latency;
+               break;
+       case low_latency:  /* 50 usec aka 20000 ints/s */
+               if (bytes > 10000) {
+                       /* this if handles the TSO accounting */
+                       if (bytes/packets > 8000) {
+                               retval = bulk_latency;
+                       } else if ((packets < 10) || ((bytes/packets) > 1200)) {
+                               retval = bulk_latency;
+                       } else if ((packets > 35)) {
+                               retval = lowest_latency;
+                       }
+               } else if (bytes/packets > 2000) {
+                       retval = bulk_latency;
+               } else if (packets <= 2 && bytes < 512) {
+                       retval = lowest_latency;
+               }
+               break;
+       case bulk_latency: /* 250 usec aka 4000 ints/s */
+               if (bytes > 25000) {
+                       if (packets > 35)
+                               retval = low_latency;
+               } else if (bytes < 6000) {
+                       retval = low_latency;
+               }
+               break;
+       }
+
+update_itr_done:
+       return retval;
+}
+
+static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
+                       int rx_only)
+{
+       u16 current_itr;
+       u32 new_itr = adapter->itr;
+
+       /* for non-gigabit speeds, just fix the interrupt rate at 4000 */
+       if (adapter->link_speed != SPEED_1000) {
+               current_itr = 0;
+               new_itr = 4000;
+               goto set_itr_now;
+       }
+
+       adapter->rx_itr = igb_update_itr(adapter,
+                                   adapter->rx_itr,
+                                   adapter->rx_ring->total_packets,
+                                   adapter->rx_ring->total_bytes);
+       /* conservative mode (itr 3) eliminates the lowest_latency setting */
+       if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
+               adapter->rx_itr = low_latency;
+
+       if (!rx_only) {
+               adapter->tx_itr = igb_update_itr(adapter,
+                                           adapter->tx_itr,
+                                           adapter->tx_ring->total_packets,
+                                           adapter->tx_ring->total_bytes);
+               /* conservative mode (itr 3) eliminates the
+                * lowest_latency setting */
+               if (adapter->itr_setting == 3 &&
+                   adapter->tx_itr == lowest_latency)
+                       adapter->tx_itr = low_latency;
+
+               current_itr = max(adapter->rx_itr, adapter->tx_itr);
+       } else {
+               current_itr = adapter->rx_itr;
+       }
+
+       switch (current_itr) {
+       /* counts and packets in update_itr are dependent on these numbers */
+       case lowest_latency:
+               new_itr = 70000;
+               break;
+       case low_latency:
+               new_itr = 20000; /* aka hwitr = ~200 */
+               break;
+       case bulk_latency:
+               new_itr = 4000;
+               break;
+       default:
+               break;
+       }
+
+set_itr_now:
+       if (new_itr != adapter->itr) {
+               /* this attempts to bias the interrupt rate towards Bulk
+                * by adding intermediate steps when interrupt rate is
+                * increasing */
+               new_itr = new_itr > adapter->itr ?
+                            min(adapter->itr + (new_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
+                * we should between interrupts.  Instead, we write the ITR
+                * value at the beginning of the next interrupt so the timing
+                * ends up being correct.
+                */
+               adapter->itr = new_itr;
+               adapter->set_itr = 1;
+       }
+
+       return;
+}
+
+
+#define IGB_TX_FLAGS_CSUM              0x00000001
+#define IGB_TX_FLAGS_VLAN              0x00000002
+#define IGB_TX_FLAGS_TSO               0x00000004
+#define IGB_TX_FLAGS_IPV4              0x00000008
+#define IGB_TX_FLAGS_VLAN_MASK 0xffff0000
+#define IGB_TX_FLAGS_VLAN_SHIFT        16
+
+static inline int igb_tso_adv(struct igb_adapter *adapter,
+                             struct igb_ring *tx_ring,
+                             struct sk_buff *skb, u32 tx_flags, u8 *hdr_len)
+{
+       struct e1000_adv_tx_context_desc *context_desc;
+       unsigned int i;
+       int err;
+       struct igb_buffer *buffer_info;
+       u32 info = 0, tu_cmd = 0;
+       u32 mss_l4len_idx, l4len;
+       *hdr_len = 0;
+
+       if (skb_header_cloned(skb)) {
+               err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
+               if (err)
+                       return err;
+       }
+
+       l4len = tcp_hdrlen(skb);
+       *hdr_len += l4len;
+
+       if (skb->protocol == htons(ETH_P_IP)) {
+               struct iphdr *iph = ip_hdr(skb);
+               iph->tot_len = 0;
+               iph->check = 0;
+               tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
+                                                        iph->daddr, 0,
+                                                        IPPROTO_TCP,
+                                                        0);
+       } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
+               ipv6_hdr(skb)->payload_len = 0;
+               tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
+                                                      &ipv6_hdr(skb)->daddr,
+                                                      0, IPPROTO_TCP, 0);
+       }
+
+       i = tx_ring->next_to_use;
+
+       buffer_info = &tx_ring->buffer_info[i];
+       context_desc = E1000_TX_CTXTDESC_ADV(*tx_ring, i);
+       /* VLAN MACLEN IPLEN */
+       if (tx_flags & IGB_TX_FLAGS_VLAN)
+               info |= (tx_flags & IGB_TX_FLAGS_VLAN_MASK);
+       info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+       *hdr_len += skb_network_offset(skb);
+       info |= skb_network_header_len(skb);
+       *hdr_len += skb_network_header_len(skb);
+       context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+       /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
+       tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+       if (skb->protocol == htons(ETH_P_IP))
+               tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+       tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+
+       context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+
+       /* MSS L4LEN IDX */
+       mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
+       mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
+
+       /* Context index must be unique per ring.  Luckily, so is the interrupt
+        * mask value. */
+       mss_l4len_idx |= tx_ring->eims_value >> 4;
+
+       context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
+       context_desc->seqnum_seed = 0;
+
+       buffer_info->time_stamp = jiffies;
+       buffer_info->dma = 0;
+       i++;
+       if (i == tx_ring->count)
+               i = 0;
+
+       tx_ring->next_to_use = i;
+
+       return true;
+}
+
+static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
+                                       struct igb_ring *tx_ring,
+                                       struct sk_buff *skb, u32 tx_flags)
+{
+       struct e1000_adv_tx_context_desc *context_desc;
+       unsigned int i;
+       struct igb_buffer *buffer_info;
+       u32 info = 0, tu_cmd = 0;
+
+       if ((skb->ip_summed == CHECKSUM_PARTIAL) ||
+           (tx_flags & IGB_TX_FLAGS_VLAN)) {
+               i = tx_ring->next_to_use;
+               buffer_info = &tx_ring->buffer_info[i];
+               context_desc = E1000_TX_CTXTDESC_ADV(*tx_ring, i);
+
+               if (tx_flags & IGB_TX_FLAGS_VLAN)
+                       info |= (tx_flags & IGB_TX_FLAGS_VLAN_MASK);
+               info |= (skb_network_offset(skb) << E1000_ADVTXD_MACLEN_SHIFT);
+               if (skb->ip_summed == CHECKSUM_PARTIAL)
+                       info |= skb_network_header_len(skb);
+
+               context_desc->vlan_macip_lens = cpu_to_le32(info);
+
+               tu_cmd |= (E1000_TXD_CMD_DEXT | E1000_ADVTXD_DTYP_CTXT);
+
+               if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                       if (skb->protocol == htons(ETH_P_IP))
+                               tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
+                       if (skb->sk && (skb->sk->sk_protocol == IPPROTO_TCP))
+                               tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+               }
+
+               context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
+               context_desc->seqnum_seed = 0;
+               context_desc->mss_l4len_idx =
+                                         cpu_to_le32(tx_ring->eims_value >> 4);
+
+               buffer_info->time_stamp = jiffies;
+               buffer_info->dma = 0;
+
+               i++;
+               if (i == tx_ring->count)
+                       i = 0;
+               tx_ring->next_to_use = i;
+
+               return true;
+       }
+
+
+       return false;
+}
+
+#define IGB_MAX_TXD_PWR        16
+#define IGB_MAX_DATA_PER_TXD   (1<<IGB_MAX_TXD_PWR)
+
+static inline int igb_tx_map_adv(struct igb_adapter *adapter,
+                                struct igb_ring *tx_ring,
+                                struct sk_buff *skb)
+{
+       struct igb_buffer *buffer_info;
+       unsigned int len = skb_headlen(skb);
+       unsigned int count = 0, i;
+       unsigned int f;
+
+       i = tx_ring->next_to_use;
+
+       buffer_info = &tx_ring->buffer_info[i];
+       BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
+       buffer_info->length = len;
+       /* set time_stamp *before* dma to help avoid a possible race */
+       buffer_info->time_stamp = jiffies;
+       buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len,
+                                         PCI_DMA_TODEVICE);
+       count++;
+       i++;
+       if (i == tx_ring->count)
+               i = 0;
+
+       for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
+               struct skb_frag_struct *frag;
+
+               frag = &skb_shinfo(skb)->frags[f];
+               len = frag->size;
+
+               buffer_info = &tx_ring->buffer_info[i];
+               BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
+               buffer_info->length = len;
+               buffer_info->time_stamp = jiffies;
+               buffer_info->dma = pci_map_page(adapter->pdev,
+                                               frag->page,
+                                               frag->page_offset,
+                                               len,
+                                               PCI_DMA_TODEVICE);
+
+               count++;
+               i++;
+               if (i == tx_ring->count)
+                       i = 0;
+       }
+
+       i = (i == 0) ? tx_ring->count - 1 : i - 1;
+       tx_ring->buffer_info[i].skb = skb;
+
+       return count;
+}
+
+static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
+                                   struct igb_ring *tx_ring,
+                                   int tx_flags, int count, u32 paylen,
+                                   u8 hdr_len)
+{
+       union e1000_adv_tx_desc *tx_desc = NULL;
+       struct igb_buffer *buffer_info;
+       u32 olinfo_status = 0, cmd_type_len;
+       unsigned int i;
+
+       cmd_type_len = (E1000_ADVTXD_DTYP_DATA | E1000_ADVTXD_DCMD_IFCS |
+                       E1000_ADVTXD_DCMD_DEXT);
+
+       if (tx_flags & IGB_TX_FLAGS_VLAN)
+               cmd_type_len |= E1000_ADVTXD_DCMD_VLE;
+
+       if (tx_flags & IGB_TX_FLAGS_TSO) {
+               cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
+
+               /* insert tcp checksum */
+               olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+
+               /* insert ip checksum */
+               if (tx_flags & IGB_TX_FLAGS_IPV4)
+                       olinfo_status |= E1000_TXD_POPTS_IXSM << 8;
+
+       } else if (tx_flags & IGB_TX_FLAGS_CSUM) {
+               olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
+       }
+
+       if (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+                       IGB_TX_FLAGS_VLAN))
+               olinfo_status |= tx_ring->eims_value >> 4;
+
+       olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
+
+       i = tx_ring->next_to_use;
+       while (count--) {
+               buffer_info = &tx_ring->buffer_info[i];
+               tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
+               tx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma);
+               tx_desc->read.cmd_type_len =
+                       cpu_to_le32(cmd_type_len | buffer_info->length);
+               tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
+               i++;
+               if (i == tx_ring->count)
+                       i = 0;
+       }
+
+       tx_desc->read.cmd_type_len |= cpu_to_le32(adapter->txd_cmd);
+       /* Force memory writes to complete before letting h/w
+        * know there are new descriptors to fetch.  (Only
+        * applicable for weak-ordered memory model archs,
+        * such as IA-64). */
+       wmb();
+
+       tx_ring->next_to_use = i;
+       writel(i, adapter->hw.hw_addr + tx_ring->tail);
+       /* we need this if more than one processor can write to our tail
+        * at a time, it syncronizes IO on IA64/Altix systems */
+       mmiowb();
+}
+
+static int __igb_maybe_stop_tx(struct net_device *netdev,
+                              struct igb_ring *tx_ring, int size)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       netif_stop_queue(netdev);
+       /* Herbert's original patch had:
+        *  smp_mb__after_netif_stop_queue();
+        * but since that doesn't exist yet, just open code it. */
+       smp_mb();
+
+       /* We need to check again in a case another CPU has just
+        * made room available. */
+       if (IGB_DESC_UNUSED(tx_ring) < size)
+               return -EBUSY;
+
+       /* A reprieve! */
+       netif_start_queue(netdev);
+       ++adapter->restart_queue;
+       return 0;
+}
+
+static int igb_maybe_stop_tx(struct net_device *netdev,
+                            struct igb_ring *tx_ring, int size)
+{
+       if (IGB_DESC_UNUSED(tx_ring) >= size)
+               return 0;
+       return __igb_maybe_stop_tx(netdev, tx_ring, size);
+}
+
+#define TXD_USE_COUNT(S) (((S) >> (IGB_MAX_TXD_PWR)) + 1)
+
+static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
+                                  struct net_device *netdev,
+                                  struct igb_ring *tx_ring)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       unsigned int tx_flags = 0;
+       unsigned int len;
+       unsigned long irq_flags;
+       u8 hdr_len = 0;
+       int tso = 0;
+
+       len = skb_headlen(skb);
+
+       if (test_bit(__IGB_DOWN, &adapter->state)) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (skb->len <= 0) {
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
+       }
+
+       if (!spin_trylock_irqsave(&tx_ring->tx_lock, irq_flags))
+               /* Collision - tell upper layer to requeue */
+               return NETDEV_TX_LOCKED;
+
+       /* need: 1 descriptor per page,
+        *       + 2 desc gap to keep tail from touching head,
+        *       + 1 desc for skb->data,
+        *       + 1 desc for context descriptor,
+        * otherwise try next time */
+       if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
+               /* this is a hard error */
+               spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
+               return NETDEV_TX_BUSY;
+       }
+
+       if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+               tx_flags |= IGB_TX_FLAGS_VLAN;
+               tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
+       }
+
+       tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
+                                             &hdr_len) : 0;
+
+       if (tso < 0) {
+               dev_kfree_skb_any(skb);
+               spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
+               return NETDEV_TX_OK;
+       }
+
+       if (tso)
+               tx_flags |= IGB_TX_FLAGS_TSO;
+       else if (igb_tx_csum_adv(adapter, tx_ring, skb, tx_flags))
+                       if (skb->ip_summed == CHECKSUM_PARTIAL)
+                               tx_flags |= IGB_TX_FLAGS_CSUM;
+
+       if (skb->protocol == htons(ETH_P_IP))
+               tx_flags |= IGB_TX_FLAGS_IPV4;
+
+       igb_tx_queue_adv(adapter, tx_ring, tx_flags,
+                        igb_tx_map_adv(adapter, tx_ring, skb),
+                        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);
+
+       spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
+       return NETDEV_TX_OK;
+}
+
+static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct igb_ring *tx_ring = &adapter->tx_ring[0];
+
+       /* This goes back to the question of how to logically map a tx queue
+        * to a flow.  Right now, performance is impacted slightly negatively
+        * if using multiple tx queues.  If the stack breaks away from a
+        * single qdisc implementation, we can look at this again. */
+       return (igb_xmit_frame_ring_adv(skb, netdev, tx_ring));
+}
+
+/**
+ * igb_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ **/
+static void igb_tx_timeout(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       /* Do the reset outside of interrupt context */
+       adapter->tx_timeout_count++;
+       schedule_work(&adapter->reset_task);
+       wr32(E1000_EICS, adapter->eims_enable_mask &
+               ~(E1000_EIMS_TCP_TIMER | E1000_EIMS_OTHER));
+}
+
+static void igb_reset_task(struct work_struct *work)
+{
+       struct igb_adapter *adapter;
+       adapter = container_of(work, struct igb_adapter, reset_task);
+
+       igb_reinit_locked(adapter);
+}
+
+/**
+ * igb_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ **/
+static struct net_device_stats *
+igb_get_stats(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       /* only return the current stats */
+       return &adapter->net_stats;
+}
+
+/**
+ * igb_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int igb_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+
+       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+           (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+               dev_err(&adapter->pdev->dev, "Invalid MTU setting\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");
+               return -EINVAL;
+       }
+
+       while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
+               msleep(1);
+       /* igb_down has a dependency on max_frame_size */
+       adapter->max_frame_size = max_frame;
+       if (netif_running(netdev))
+               igb_down(adapter);
+
+       /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
+        * means we reserve 2 more, this pushes us to allocate from the next
+        * larger slab size.
+        * i.e. RXBUFFER_2048 --> size-4096 slab
+        */
+
+       if (max_frame <= IGB_RXBUFFER_256)
+               adapter->rx_buffer_len = IGB_RXBUFFER_256;
+       else if (max_frame <= IGB_RXBUFFER_512)
+               adapter->rx_buffer_len = IGB_RXBUFFER_512;
+       else if (max_frame <= IGB_RXBUFFER_1024)
+               adapter->rx_buffer_len = IGB_RXBUFFER_1024;
+       else if (max_frame <= IGB_RXBUFFER_2048)
+               adapter->rx_buffer_len = IGB_RXBUFFER_2048;
+       else
+               adapter->rx_buffer_len = IGB_RXBUFFER_4096;
+       /* adjust allocation if LPE protects us, and we aren't using SBP */
+       if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
+            (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
+               adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
+
+       dev_info(&adapter->pdev->dev, "changing MTU from %d to %d\n",
+                netdev->mtu, new_mtu);
+       netdev->mtu = new_mtu;
+
+       if (netif_running(netdev))
+               igb_up(adapter);
+       else
+               igb_reset(adapter);
+
+       clear_bit(__IGB_RESETTING, &adapter->state);
+
+       return 0;
+}
+
+/**
+ * igb_update_stats - Update the board statistics counters
+ * @adapter: board private structure
+ **/
+
+void igb_update_stats(struct igb_adapter *adapter)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       struct pci_dev *pdev = adapter->pdev;
+       u16 phy_tmp;
+
+#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF
+
+       /*
+        * Prevent stats update while adapter is being reset, or if the pci
+        * connection is down.
+        */
+       if (adapter->link_speed == 0)
+               return;
+       if (pci_channel_offline(pdev))
+               return;
+
+       adapter->stats.crcerrs += rd32(E1000_CRCERRS);
+       adapter->stats.gprc += rd32(E1000_GPRC);
+       adapter->stats.gorc += rd32(E1000_GORCL);
+       rd32(E1000_GORCH); /* clear GORCL */
+       adapter->stats.bprc += rd32(E1000_BPRC);
+       adapter->stats.mprc += rd32(E1000_MPRC);
+       adapter->stats.roc += rd32(E1000_ROC);
+
+       adapter->stats.prc64 += rd32(E1000_PRC64);
+       adapter->stats.prc127 += rd32(E1000_PRC127);
+       adapter->stats.prc255 += rd32(E1000_PRC255);
+       adapter->stats.prc511 += rd32(E1000_PRC511);
+       adapter->stats.prc1023 += rd32(E1000_PRC1023);
+       adapter->stats.prc1522 += rd32(E1000_PRC1522);
+       adapter->stats.symerrs += rd32(E1000_SYMERRS);
+       adapter->stats.sec += rd32(E1000_SEC);
+
+       adapter->stats.mpc += rd32(E1000_MPC);
+       adapter->stats.scc += rd32(E1000_SCC);
+       adapter->stats.ecol += rd32(E1000_ECOL);
+       adapter->stats.mcc += rd32(E1000_MCC);
+       adapter->stats.latecol += rd32(E1000_LATECOL);
+       adapter->stats.dc += rd32(E1000_DC);
+       adapter->stats.rlec += rd32(E1000_RLEC);
+       adapter->stats.xonrxc += rd32(E1000_XONRXC);
+       adapter->stats.xontxc += rd32(E1000_XONTXC);
+       adapter->stats.xoffrxc += rd32(E1000_XOFFRXC);
+       adapter->stats.xofftxc += rd32(E1000_XOFFTXC);
+       adapter->stats.fcruc += rd32(E1000_FCRUC);
+       adapter->stats.gptc += rd32(E1000_GPTC);
+       adapter->stats.gotc += rd32(E1000_GOTCL);
+       rd32(E1000_GOTCH); /* clear GOTCL */
+       adapter->stats.rnbc += rd32(E1000_RNBC);
+       adapter->stats.ruc += rd32(E1000_RUC);
+       adapter->stats.rfc += rd32(E1000_RFC);
+       adapter->stats.rjc += rd32(E1000_RJC);
+       adapter->stats.tor += rd32(E1000_TORH);
+       adapter->stats.tot += rd32(E1000_TOTH);
+       adapter->stats.tpr += rd32(E1000_TPR);
+
+       adapter->stats.ptc64 += rd32(E1000_PTC64);
+       adapter->stats.ptc127 += rd32(E1000_PTC127);
+       adapter->stats.ptc255 += rd32(E1000_PTC255);
+       adapter->stats.ptc511 += rd32(E1000_PTC511);
+       adapter->stats.ptc1023 += rd32(E1000_PTC1023);
+       adapter->stats.ptc1522 += rd32(E1000_PTC1522);
+
+       adapter->stats.mptc += rd32(E1000_MPTC);
+       adapter->stats.bptc += rd32(E1000_BPTC);
+
+       /* used for adaptive IFS */
+
+       hw->mac.tx_packet_delta = rd32(E1000_TPT);
+       adapter->stats.tpt += hw->mac.tx_packet_delta;
+       hw->mac.collision_delta = rd32(E1000_COLC);
+       adapter->stats.colc += hw->mac.collision_delta;
+
+       adapter->stats.algnerrc += rd32(E1000_ALGNERRC);
+       adapter->stats.rxerrc += rd32(E1000_RXERRC);
+       adapter->stats.tncrs += rd32(E1000_TNCRS);
+       adapter->stats.tsctc += rd32(E1000_TSCTC);
+       adapter->stats.tsctfc += rd32(E1000_TSCTFC);
+
+       adapter->stats.iac += rd32(E1000_IAC);
+       adapter->stats.icrxoc += rd32(E1000_ICRXOC);
+       adapter->stats.icrxptc += rd32(E1000_ICRXPTC);
+       adapter->stats.icrxatc += rd32(E1000_ICRXATC);
+       adapter->stats.ictxptc += rd32(E1000_ICTXPTC);
+       adapter->stats.ictxatc += rd32(E1000_ICTXATC);
+       adapter->stats.ictxqec += rd32(E1000_ICTXQEC);
+       adapter->stats.ictxqmtc += rd32(E1000_ICTXQMTC);
+       adapter->stats.icrxdmtc += rd32(E1000_ICRXDMTC);
+
+       /* Fill out the OS statistics structure */
+       adapter->net_stats.multicast = adapter->stats.mprc;
+       adapter->net_stats.collisions = adapter->stats.colc;
+
+       /* Rx Errors */
+
+       /* RLEC on some newer hardware can be incorrect so build
+       * 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 +
+               adapter->stats.cexterr;
+       adapter->net_stats.rx_length_errors = adapter->stats.ruc +
+                                             adapter->stats.roc;
+       adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
+       adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
+       adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
+
+       /* Tx Errors */
+       adapter->net_stats.tx_errors = adapter->stats.ecol +
+                                      adapter->stats.latecol;
+       adapter->net_stats.tx_aborted_errors = adapter->stats.ecol;
+       adapter->net_stats.tx_window_errors = adapter->stats.latecol;
+       adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs;
+
+       /* Tx Dropped needs to be maintained elsewhere */
+
+       /* Phy Stats */
+       if (hw->phy.media_type == e1000_media_type_copper) {
+               if ((adapter->link_speed == SPEED_1000) &&
+                  (!hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
+                                             &phy_tmp))) {
+                       phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
+                       adapter->phy_stats.idle_errors += phy_tmp;
+               }
+       }
+
+       /* Management Stats */
+       adapter->stats.mgptc += rd32(E1000_MGTPTC);
+       adapter->stats.mgprc += rd32(E1000_MGTPRC);
+       adapter->stats.mgpdc += rd32(E1000_MGTPDC);
+}
+
+
+static irqreturn_t igb_msix_other(int irq, void *data)
+{
+       struct net_device *netdev = data;
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 eicr;
+       /* disable interrupts from the "other" bit, avoid re-entry */
+       wr32(E1000_EIMC, E1000_EIMS_OTHER);
+
+       eicr = rd32(E1000_EICR);
+
+       if (eicr & E1000_EIMS_OTHER) {
+               u32 icr = rd32(E1000_ICR);
+               /* reading ICR causes bit 31 of EICR to be cleared */
+               if (!(icr & E1000_ICR_LSC))
+                       goto no_link_interrupt;
+               hw->mac.get_link_status = 1;
+               /* guard against interrupt when we're going down */
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       mod_timer(&adapter->watchdog_timer, jiffies + 1);
+       }
+
+no_link_interrupt:
+       wr32(E1000_IMS, E1000_IMS_LSC);
+       wr32(E1000_EIMS, E1000_EIMS_OTHER);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t igb_msix_tx(int irq, void *data)
+{
+       struct igb_ring *tx_ring = data;
+       struct igb_adapter *adapter = tx_ring->adapter;
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (!tx_ring->itr_val)
+               wr32(E1000_EIMC, tx_ring->eims_value);
+
+       tx_ring->total_bytes = 0;
+       tx_ring->total_packets = 0;
+       if (!igb_clean_tx_irq(adapter, tx_ring))
+               /* Ring was not completely cleaned, so fire another interrupt */
+               wr32(E1000_EICS, tx_ring->eims_value);
+
+       if (!tx_ring->itr_val)
+               wr32(E1000_EIMS, tx_ring->eims_value);
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t igb_msix_rx(int irq, void *data)
+{
+       struct igb_ring *rx_ring = data;
+       struct igb_adapter *adapter = rx_ring->adapter;
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (!rx_ring->itr_val)
+               wr32(E1000_EIMC, rx_ring->eims_value);
+
+       if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) {
+               rx_ring->total_bytes = 0;
+               rx_ring->total_packets = 0;
+               rx_ring->no_itr_adjust = 0;
+               __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
+       } else {
+               if (!rx_ring->no_itr_adjust) {
+                       igb_lower_rx_eitr(adapter, rx_ring);
+                       rx_ring->no_itr_adjust = 1;
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+
+/**
+ * igb_intr_msi - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t igb_intr_msi(int irq, void *data)
+{
+       struct net_device *netdev = data;
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct napi_struct *napi = &adapter->napi;
+       struct e1000_hw *hw = &adapter->hw;
+       /* read ICR disables interrupts using IAM */
+       u32 icr = rd32(E1000_ICR);
+
+       /* Write the ITR value calculated at the end of the
+        * previous interrupt.
+        */
+       if (adapter->set_itr) {
+               wr32(E1000_ITR,
+                       1000000000 / (adapter->itr * 256));
+               adapter->set_itr = 0;
+       }
+
+       /* read ICR disables interrupts using IAM */
+       if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+               hw->mac.get_link_status = 1;
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       mod_timer(&adapter->watchdog_timer, jiffies + 1);
+       }
+
+       if (netif_rx_schedule_prep(netdev, napi)) {
+               adapter->tx_ring->total_bytes = 0;
+               adapter->tx_ring->total_packets = 0;
+               adapter->rx_ring->total_bytes = 0;
+               adapter->rx_ring->total_packets = 0;
+               __netif_rx_schedule(netdev, napi);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * igb_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t igb_intr(int irq, void *data)
+{
+       struct net_device *netdev = data;
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct napi_struct *napi = &adapter->napi;
+       struct e1000_hw *hw = &adapter->hw;
+       /* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
+        * need for the IMC write */
+       u32 icr = rd32(E1000_ICR);
+       u32 eicr = 0;
+       if (!icr)
+               return IRQ_NONE;  /* Not our interrupt */
+
+       /* Write the ITR value calculated at the end of the
+        * previous interrupt.
+        */
+       if (adapter->set_itr) {
+               wr32(E1000_ITR,
+                       1000000000 / (adapter->itr * 256));
+               adapter->set_itr = 0;
+       }
+
+       /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
+        * not set, then the adapter didn't send an interrupt */
+       if (!(icr & E1000_ICR_INT_ASSERTED))
+               return IRQ_NONE;
+
+       eicr = rd32(E1000_EICR);
+
+       if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
+               hw->mac.get_link_status = 1;
+               /* guard against interrupt when we're going down */
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       mod_timer(&adapter->watchdog_timer, jiffies + 1);
+       }
+
+       if (netif_rx_schedule_prep(netdev, napi)) {
+               adapter->tx_ring->total_bytes = 0;
+               adapter->rx_ring->total_bytes = 0;
+               adapter->tx_ring->total_packets = 0;
+               adapter->rx_ring->total_packets = 0;
+               __netif_rx_schedule(netdev, napi);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * igb_clean - NAPI Rx polling callback
+ * @adapter: board private structure
+ **/
+static int igb_clean(struct napi_struct *napi, int budget)
+{
+       struct igb_adapter *adapter = container_of(napi, struct igb_adapter,
+                                                  napi);
+       struct net_device *netdev = adapter->netdev;
+       int tx_clean_complete = 1, work_done = 0;
+       int i;
+
+       /* Must NOT use netdev_priv macro here. */
+       adapter = netdev->priv;
+
+       /* Keep link state information with original netdev */
+       if (!netif_carrier_ok(netdev))
+               goto quit_polling;
+
+       /* igb_clean is called per-cpu.  This lock protects tx_ring[i] from
+        * being cleaned by multiple cpus simultaneously.  A failure obtaining
+        * the lock means tx_ring[i] is currently being cleaned anyway. */
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               if (spin_trylock(&adapter->tx_ring[i].tx_clean_lock)) {
+                       tx_clean_complete &= igb_clean_tx_irq(adapter,
+                                                       &adapter->tx_ring[i]);
+                       spin_unlock(&adapter->tx_ring[i].tx_clean_lock);
+               }
+       }
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i], &work_done,
+                                    adapter->rx_ring[i].napi.weight);
+
+       /* If no Tx and not enough Rx work done, exit the polling mode */
+       if ((tx_clean_complete && (work_done < budget)) ||
+           !netif_running(netdev)) {
+quit_polling:
+               if (adapter->itr_setting & 3)
+                       igb_set_itr(adapter, E1000_ITR, false);
+               netif_rx_complete(netdev, napi);
+               if (!test_bit(__IGB_DOWN, &adapter->state))
+                       igb_irq_enable(adapter);
+               return 0;
+       }
+
+       return 1;
+}
+
+static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
+{
+       struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
+       struct igb_adapter *adapter = rx_ring->adapter;
+       struct e1000_hw *hw = &adapter->hw;
+       struct net_device *netdev = adapter->netdev;
+       int work_done = 0;
+
+       /* Keep link state information with original netdev */
+       if (!netif_carrier_ok(netdev))
+               goto quit_polling;
+
+       igb_clean_rx_irq_adv(adapter, rx_ring, &work_done, budget);
+
+
+       /* If not enough Rx work done, exit the polling mode */
+       if ((work_done == 0) || !netif_running(netdev)) {
+quit_polling:
+               netif_rx_complete(netdev, napi);
+
+               wr32(E1000_EIMS, rx_ring->eims_value);
+               if ((adapter->itr_setting & 3) && !rx_ring->no_itr_adjust &&
+                   (rx_ring->total_packets > IGB_DYN_ITR_PACKET_THRESHOLD)) {
+                       int mean_size = rx_ring->total_bytes /
+                                       rx_ring->total_packets;
+                       if (mean_size < IGB_DYN_ITR_LENGTH_LOW)
+                               igb_raise_rx_eitr(adapter, rx_ring);
+                       else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
+                               igb_lower_rx_eitr(adapter, rx_ring);
+               }
+               return 0;
+       }
+
+       return 1;
+}
+/**
+ * igb_clean_tx_irq - Reclaim resources after transmit completes
+ * @adapter: board private structure
+ * returns true if ring is completely cleaned
+ **/
+static bool igb_clean_tx_irq(struct igb_adapter *adapter,
+                                 struct igb_ring *tx_ring)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct e1000_hw *hw = &adapter->hw;
+       struct e1000_tx_desc *tx_desc;
+       struct igb_buffer *buffer_info;
+       struct sk_buff *skb;
+       unsigned int i;
+       u32 head, oldhead;
+       unsigned int count = 0;
+       bool cleaned = false;
+       bool retval = true;
+       unsigned int total_bytes = 0, total_packets = 0;
+
+       rmb();
+       head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
+                                + tx_ring->count);
+       head = le32_to_cpu(head);
+       i = tx_ring->next_to_clean;
+       while (1) {
+               while (i != head) {
+                       cleaned = true;
+                       tx_desc = E1000_TX_DESC(*tx_ring, i);
+                       buffer_info = &tx_ring->buffer_info[i];
+                       skb = buffer_info->skb;
+
+                       if (skb) {
+                               unsigned int segs, bytecount;
+                               /* gso_segs is currently only valid for tcp */
+                               segs = skb_shinfo(skb)->gso_segs ?: 1;
+                               /* multiply data chunks by size of headers */
+                               bytecount = ((segs - 1) * skb_headlen(skb)) +
+                                           skb->len;
+                               total_packets += segs;
+                               total_bytes += bytecount;
+                       }
+
+                       igb_unmap_and_free_tx_resource(adapter, buffer_info);
+                       tx_desc->upper.data = 0;
+
+                       i++;
+                       if (i == tx_ring->count)
+                               i = 0;
+
+                       count++;
+                       if (count == IGB_MAX_TX_CLEAN) {
+                               retval = false;
+                               goto done_cleaning;
+                       }
+               }
+               oldhead = head;
+               rmb();
+               head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
+                                        + tx_ring->count);
+               head = le32_to_cpu(head);
+               if (head == oldhead)
+                       goto done_cleaning;
+       }  /* while (1) */
+
+done_cleaning:
+       tx_ring->next_to_clean = i;
+
+       if (unlikely(cleaned &&
+                    netif_carrier_ok(netdev) &&
+                    IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
+               /* Make sure that anybody stopping the queue after this
+                * sees the new next_to_clean.
+                */
+               smp_mb();
+               if (netif_queue_stopped(netdev) &&
+                   !(test_bit(__IGB_DOWN, &adapter->state))) {
+                       netif_wake_queue(netdev);
+                       ++adapter->restart_queue;
+               }
+       }
+
+       if (tx_ring->detect_tx_hung) {
+               /* Detect a transmit hang in hardware, this serializes the
+                * check with the clearing of time_stamp and movement of i */
+               tx_ring->detect_tx_hung = false;
+               if (tx_ring->buffer_info[i].time_stamp &&
+                   time_after(jiffies, tx_ring->buffer_info[i].time_stamp +
+                              (adapter->tx_timeout_factor * HZ))
+                   && !(rd32(E1000_STATUS) &
+                        E1000_STATUS_TXOFF)) {
+
+                       tx_desc = E1000_TX_DESC(*tx_ring, i);
+                       /* detected Tx unit hang */
+                       dev_err(&adapter->pdev->dev,
+                               "Detected Tx Unit Hang\n"
+                               "  Tx Queue             <%lu>\n"
+                               "  TDH                  <%x>\n"
+                               "  TDT                  <%x>\n"
+                               "  next_to_use          <%x>\n"
+                               "  next_to_clean        <%x>\n"
+                               "  head (WB)            <%x>\n"
+                               "buffer_info[next_to_clean]\n"
+                               "  time_stamp           <%lx>\n"
+                               "  jiffies              <%lx>\n"
+                               "  desc.status          <%x>\n",
+                               (unsigned long)((tx_ring - adapter->tx_ring) /
+                                       sizeof(struct igb_ring)),
+                               readl(adapter->hw.hw_addr + tx_ring->head),
+                               readl(adapter->hw.hw_addr + tx_ring->tail),
+                               tx_ring->next_to_use,
+                               tx_ring->next_to_clean,
+                               head,
+                               tx_ring->buffer_info[i].time_stamp,
+                               jiffies,
+                               tx_desc->upper.fields.status);
+                       netif_stop_queue(netdev);
+               }
+       }
+       tx_ring->total_bytes += total_bytes;
+       tx_ring->total_packets += total_packets;
+       adapter->net_stats.tx_bytes += total_bytes;
+       adapter->net_stats.tx_packets += total_packets;
+       return retval;
+}
+
+
+/**
+ * igb_receive_skb - helper function to handle rx indications
+ * @adapter: board private structure
+ * @status: descriptor status field as written by hardware
+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
+ * @skb: pointer to sk_buff to be indicated to stack
+ **/
+static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan,
+                           struct sk_buff *skb)
+{
+       if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
+               vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+                                        le16_to_cpu(vlan) &
+                                        E1000_RXD_SPC_VLAN_MASK);
+       else
+               netif_receive_skb(skb);
+}
+
+
+static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
+                                      u32 status_err, struct sk_buff *skb)
+{
+       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)
+               return;
+       /* TCP/UDP checksum error bit is set */
+       if (status_err &
+           (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+               /* 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;
+
+       adapter->hw_csum_good++;
+}
+
+static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
+                                     struct igb_ring *rx_ring,
+                                     int *work_done, int budget)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+       union e1000_adv_rx_desc *rx_desc , *next_rxd;
+       struct igb_buffer *buffer_info , *next_buffer;
+       struct sk_buff *skb;
+       unsigned int i, j;
+       u32 length, hlen, staterr;
+       bool cleaned = false;
+       int cleaned_count = 0;
+       unsigned int total_bytes = 0, total_packets = 0;
+
+       i = rx_ring->next_to_clean;
+       rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
+       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+
+       while (staterr & E1000_RXD_STAT_DD) {
+               if (*work_done >= budget)
+                       break;
+               (*work_done)++;
+               buffer_info = &rx_ring->buffer_info[i];
+
+               /* HW will not DMA in data larger than the given buffer, even
+                * if it parses the (NFS, of course) header to be larger.  In
+                * that case, it fills the header buffer and spills the rest
+                * into the page.
+                */
+               hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info &
+                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT);
+               if (hlen > adapter->rx_ps_hdr_size)
+                       hlen = adapter->rx_ps_hdr_size;
+
+               length = le16_to_cpu(rx_desc->wb.upper.length);
+               cleaned = true;
+               cleaned_count++;
+
+               if (rx_ring->pending_skb != NULL) {
+                       skb = rx_ring->pending_skb;
+                       rx_ring->pending_skb = NULL;
+                       j = rx_ring->pending_skb_page;
+               } else {
+                       skb = buffer_info->skb;
+                       prefetch(skb->data - NET_IP_ALIGN);
+                       buffer_info->skb = NULL;
+                       if (hlen) {
+                               pci_unmap_single(pdev, buffer_info->dma,
+                                                adapter->rx_ps_hdr_size +
+                                                  NET_IP_ALIGN,
+                                                PCI_DMA_FROMDEVICE);
+                               skb_put(skb, hlen);
+                       } else {
+                               pci_unmap_single(pdev, buffer_info->dma,
+                                                adapter->rx_buffer_len +
+                                                  NET_IP_ALIGN,
+                                                PCI_DMA_FROMDEVICE);
+                               skb_put(skb, length);
+                               goto send_up;
+                       }
+                       j = 0;
+               }
+
+               while (length) {
+                       pci_unmap_page(pdev, buffer_info->page_dma,
+                               PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                       buffer_info->page_dma = 0;
+                       skb_fill_page_desc(skb, j, buffer_info->page,
+                                               0, length);
+                       buffer_info->page = NULL;
+
+                       skb->len += length;
+                       skb->data_len += length;
+                       skb->truesize += length;
+                       rx_desc->wb.upper.status_error = 0;
+                       if (staterr & E1000_RXD_STAT_EOP)
+                               break;
+
+                       j++;
+                       cleaned_count++;
+                       i++;
+                       if (i == rx_ring->count)
+                               i = 0;
+
+                       buffer_info = &rx_ring->buffer_info[i];
+                       rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
+                       staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+                       length = le16_to_cpu(rx_desc->wb.upper.length);
+                       if (!(staterr & E1000_RXD_STAT_DD)) {
+                               rx_ring->pending_skb = skb;
+                               rx_ring->pending_skb_page = j;
+                               goto out;
+                       }
+               }
+send_up:
+               pskb_trim(skb, skb->len - 4);
+               i++;
+               if (i == rx_ring->count)
+                       i = 0;
+               next_rxd = E1000_RX_DESC_ADV(*rx_ring, i);
+               prefetch(next_rxd);
+               next_buffer = &rx_ring->buffer_info[i];
+
+               if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
+                       dev_kfree_skb_irq(skb);
+                       goto next_desc;
+               }
+               rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
+
+               total_bytes += skb->len;
+               total_packets++;
+
+               igb_rx_checksum_adv(adapter, staterr, skb);
+
+               skb->protocol = eth_type_trans(skb, netdev);
+
+               igb_receive_skb(adapter, staterr, rx_desc->wb.upper.vlan, skb);
+
+               netdev->last_rx = jiffies;
+
+next_desc:
+               rx_desc->wb.upper.status_error = 0;
+
+               /* return some buffers to hardware, one at a time is too slow */
+               if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
+                       igb_alloc_rx_buffers_adv(adapter, rx_ring,
+                                                cleaned_count);
+                       cleaned_count = 0;
+               }
+
+               /* use prefetched values */
+               rx_desc = next_rxd;
+               buffer_info = next_buffer;
+
+               staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+       }
+out:
+       rx_ring->next_to_clean = i;
+       cleaned_count = IGB_DESC_UNUSED(rx_ring);
+
+       if (cleaned_count)
+               igb_alloc_rx_buffers_adv(adapter, rx_ring, cleaned_count);
+
+       rx_ring->total_packets += total_packets;
+       rx_ring->total_bytes += total_bytes;
+       rx_ring->rx_stats.packets += total_packets;
+       rx_ring->rx_stats.bytes += total_bytes;
+       adapter->net_stats.rx_bytes += total_bytes;
+       adapter->net_stats.rx_packets += total_packets;
+       return cleaned;
+}
+
+
+/**
+ * igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
+ * @adapter: address of board private structure
+ **/
+static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
+                                    struct igb_ring *rx_ring,
+                                    int cleaned_count)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+       union e1000_adv_rx_desc *rx_desc;
+       struct igb_buffer *buffer_info;
+       struct sk_buff *skb;
+       unsigned int i;
+
+       i = rx_ring->next_to_use;
+       buffer_info = &rx_ring->buffer_info[i];
+
+       while (cleaned_count--) {
+               rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
+
+               if (adapter->rx_ps_hdr_size && !buffer_info->page) {
+                       buffer_info->page = alloc_page(GFP_ATOMIC);
+                       if (!buffer_info->page) {
+                               adapter->alloc_rx_buff_failed++;
+                               goto no_buffers;
+                       }
+                       buffer_info->page_dma =
+                               pci_map_page(pdev,
+                                            buffer_info->page,
+                                            0, PAGE_SIZE,
+                                            PCI_DMA_FROMDEVICE);
+               }
+
+               if (!buffer_info->skb) {
+                       int bufsz;
+
+                       if (adapter->rx_ps_hdr_size)
+                               bufsz = adapter->rx_ps_hdr_size;
+                       else
+                               bufsz = adapter->rx_buffer_len;
+                       bufsz += NET_IP_ALIGN;
+                       skb = netdev_alloc_skb(netdev, bufsz);
+
+                       if (!skb) {
+                               adapter->alloc_rx_buff_failed++;
+                               goto no_buffers;
+                       }
+
+                       /* Make buffer alignment 2 beyond a 16 byte boundary
+                        * this will result in a 16 byte aligned IP header after
+                        * the 14 byte MAC header is removed
+                        */
+                       skb_reserve(skb, NET_IP_ALIGN);
+
+                       buffer_info->skb = skb;
+                       buffer_info->dma = pci_map_single(pdev, skb->data,
+                                                         bufsz,
+                                                         PCI_DMA_FROMDEVICE);
+
+               }
+               /* Refresh the desc even if buffer_addrs didn't change because
+                * each write-back erases this info. */
+               if (adapter->rx_ps_hdr_size) {
+                       rx_desc->read.pkt_addr =
+                            cpu_to_le64(buffer_info->page_dma);
+                       rx_desc->read.hdr_addr = cpu_to_le64(buffer_info->dma);
+               } else {
+                       rx_desc->read.pkt_addr =
+                            cpu_to_le64(buffer_info->dma);
+                       rx_desc->read.hdr_addr = 0;
+               }
+
+               i++;
+               if (i == rx_ring->count)
+                       i = 0;
+               buffer_info = &rx_ring->buffer_info[i];
+       }
+
+no_buffers:
+       if (rx_ring->next_to_use != i) {
+               rx_ring->next_to_use = i;
+               if (i == 0)
+                       i = (rx_ring->count - 1);
+               else
+                       i--;
+
+               /* Force memory writes to complete before letting h/w
+                * know there are new descriptors to fetch.  (Only
+                * applicable for weak-ordered memory model archs,
+                * such as IA-64). */
+               wmb();
+               writel(i, adapter->hw.hw_addr + rx_ring->tail);
+       }
+}
+
+/**
+ * igb_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ **/
+static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct mii_ioctl_data *data = if_mii(ifr);
+
+       if (adapter->hw.phy.media_type != e1000_media_type_copper)
+               return -EOPNOTSUPP;
+
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               data->phy_id = adapter->hw.phy.addr;
+               break;
+       case SIOCGMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               if (adapter->hw.phy.ops.read_phy_reg(&adapter->hw,
+                                                    data->reg_num
+                                                    & 0x1F, &data->val_out))
+                       return -EIO;
+               break;
+       case SIOCSMIIREG:
+       default:
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+/**
+ * igb_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ **/
+static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+       switch (cmd) {
+       case SIOCGMIIPHY:
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               return igb_mii_ioctl(netdev, ifr, cmd);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static void igb_vlan_rx_register(struct net_device *netdev,
+                                struct vlan_group *grp)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl, rctl;
+
+       igb_irq_disable(adapter);
+       adapter->vlgrp = grp;
+
+       if (grp) {
+               /* enable VLAN tag insert/strip */
+               ctrl = rd32(E1000_CTRL);
+               ctrl |= E1000_CTRL_VME;
+               wr32(E1000_CTRL, ctrl);
+
+               /* enable VLAN receive filtering */
+               rctl = rd32(E1000_RCTL);
+               rctl |= E1000_RCTL_VFE;
+               rctl &= ~E1000_RCTL_CFIEN;
+               wr32(E1000_RCTL, rctl);
+               igb_update_mng_vlan(adapter);
+               wr32(E1000_RLPML,
+                               adapter->max_frame_size + VLAN_TAG_SIZE);
+       } else {
+               /* disable VLAN tag insert/strip */
+               ctrl = rd32(E1000_CTRL);
+               ctrl &= ~E1000_CTRL_VME;
+               wr32(E1000_CTRL, ctrl);
+
+               /* disable VLAN filtering */
+               rctl = rd32(E1000_RCTL);
+               rctl &= ~E1000_RCTL_VFE;
+               wr32(E1000_RCTL, rctl);
+               if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) {
+                       igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+                       adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
+               }
+               wr32(E1000_RLPML,
+                               adapter->max_frame_size);
+       }
+
+       if (!test_bit(__IGB_DOWN, &adapter->state))
+               igb_irq_enable(adapter);
+}
+
+static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 vfta, index;
+
+       if ((adapter->hw.mng_cookie.status &
+            E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
+           (vid == adapter->mng_vlan_id))
+               return;
+       /* add VID to filter table */
+       index = (vid >> 5) & 0x7F;
+       vfta = array_rd32(E1000_VFTA, index);
+       vfta |= (1 << (vid & 0x1F));
+       igb_write_vfta(&adapter->hw, index, vfta);
+}
+
+static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 vfta, index;
+
+       igb_irq_disable(adapter);
+       vlan_group_set_device(adapter->vlgrp, vid, NULL);
+
+       if (!test_bit(__IGB_DOWN, &adapter->state))
+               igb_irq_enable(adapter);
+
+       if ((adapter->hw.mng_cookie.status &
+            E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
+           (vid == adapter->mng_vlan_id)) {
+               /* release control to f/w */
+               igb_release_hw_control(adapter);
+               return;
+       }
+
+       /* remove VID from filter table */
+       index = (vid >> 5) & 0x7F;
+       vfta = array_rd32(E1000_VFTA, index);
+       vfta &= ~(1 << (vid & 0x1F));
+       igb_write_vfta(&adapter->hw, index, vfta);
+}
+
+static void igb_restore_vlan(struct igb_adapter *adapter)
+{
+       igb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+
+       if (adapter->vlgrp) {
+               u16 vid;
+               for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+                       if (!vlan_group_get_device(adapter->vlgrp, vid))
+                               continue;
+                       igb_vlan_rx_add_vid(adapter->netdev, vid);
+               }
+       }
+}
+
+int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
+{
+       struct e1000_mac_info *mac = &adapter->hw.mac;
+
+       mac->autoneg = 0;
+
+       /* Fiber NICs only allow 1000 gbps Full duplex */
+       if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
+               spddplx != (SPEED_1000 + DUPLEX_FULL)) {
+               dev_err(&adapter->pdev->dev,
+                       "Unsupported Speed/Duplex configuration\n");
+               return -EINVAL;
+       }
+
+       switch (spddplx) {
+       case SPEED_10 + DUPLEX_HALF:
+               mac->forced_speed_duplex = ADVERTISE_10_HALF;
+               break;
+       case SPEED_10 + DUPLEX_FULL:
+               mac->forced_speed_duplex = ADVERTISE_10_FULL;
+               break;
+       case SPEED_100 + DUPLEX_HALF:
+               mac->forced_speed_duplex = ADVERTISE_100_HALF;
+               break;
+       case SPEED_100 + DUPLEX_FULL:
+               mac->forced_speed_duplex = ADVERTISE_100_FULL;
+               break;
+       case SPEED_1000 + DUPLEX_FULL:
+               mac->autoneg = 1;
+               adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
+               break;
+       case SPEED_1000 + DUPLEX_HALF: /* not supported */
+       default:
+               dev_err(&adapter->pdev->dev,
+                       "Unsupported Speed/Duplex configuration\n");
+               return -EINVAL;
+       }
+       return 0;
+}
+
+
+static int igb_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 ctrl, ctrl_ext, rctl, status;
+       u32 wufc = adapter->wol;
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev)) {
+               WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
+               igb_down(adapter);
+               igb_free_irq(adapter);
+       }
+
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+#endif
+
+       status = rd32(E1000_STATUS);
+       if (status & E1000_STATUS_LU)
+               wufc &= ~E1000_WUFC_LNKC;
+
+       if (wufc) {
+               igb_setup_rctl(adapter);
+               igb_set_multi(netdev);
+
+               /* turn on all-multi mode if wake on multicast is enabled */
+               if (wufc & E1000_WUFC_MC) {
+                       rctl = rd32(E1000_RCTL);
+                       rctl |= E1000_RCTL_MPE;
+                       wr32(E1000_RCTL, rctl);
+               }
+
+               ctrl = rd32(E1000_CTRL);
+               /* advertise wake from D3Cold */
+               #define E1000_CTRL_ADVD3WUC 0x00100000
+               /* phy power management enable */
+               #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
+               ctrl |= E1000_CTRL_ADVD3WUC;
+               wr32(E1000_CTRL, ctrl);
+
+               if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
+                  adapter->hw.phy.media_type ==
+                                       e1000_media_type_internal_serdes) {
+                       /* keep the laser running in D3 */
+                       ctrl_ext = rd32(E1000_CTRL_EXT);
+                       ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
+                       wr32(E1000_CTRL_EXT, ctrl_ext);
+               }
+
+               /* Allow time for pending master requests to run */
+               igb_disable_pcie_master(&adapter->hw);
+
+               wr32(E1000_WUC, E1000_WUC_PME_EN);
+               wr32(E1000_WUFC, wufc);
+               pci_enable_wake(pdev, PCI_D3hot, 1);
+               pci_enable_wake(pdev, PCI_D3cold, 1);
+       } else {
+               wr32(E1000_WUC, 0);
+               wr32(E1000_WUFC, 0);
+               pci_enable_wake(pdev, PCI_D3hot, 0);
+               pci_enable_wake(pdev, PCI_D3cold, 0);
+       }
+
+       igb_release_manageability(adapter);
+
+       /* make sure adapter isn't asleep if manageability is enabled */
+       if (adapter->en_mng_pt) {
+               pci_enable_wake(pdev, PCI_D3hot, 1);
+               pci_enable_wake(pdev, PCI_D3cold, 1);
+       }
+
+       /* Release control of h/w to f/w.  If f/w is AMT enabled, this
+        * would have already happened in close and is redundant. */
+       igb_release_hw_control(adapter);
+
+       pci_disable_device(pdev);
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int igb_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       err = pci_enable_device(pdev);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "igb: Cannot enable PCI device from suspend\n");
+               return err;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       if (netif_running(netdev)) {
+               err = igb_request_irq(adapter);
+               if (err)
+                       return err;
+       }
+
+       /* e1000_power_up_phy(adapter); */
+
+       igb_reset(adapter);
+       wr32(E1000_WUS, ~0);
+
+       igb_init_manageability(adapter);
+
+       if (netif_running(netdev))
+               igb_up(adapter);
+
+       netif_device_attach(netdev);
+
+       /* let the f/w know that the h/w is now under the control of the
+        * driver. */
+       igb_get_hw_control(adapter);
+
+       return 0;
+}
+#endif
+
+static void igb_shutdown(struct pci_dev *pdev)
+{
+       igb_suspend(pdev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void igb_netpoll(struct net_device *netdev)
+{
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       int i;
+       int work_done = 0;
+
+       igb_irq_disable(adapter);
+       for (i = 0; i < adapter->num_tx_queues; i++)
+               igb_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+
+       for (i = 0; i < adapter->num_rx_queues; i++)
+               igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i],
+                                    &work_done,
+                                    adapter->rx_ring[i].napi.weight);
+
+       igb_irq_enable(adapter);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * igb_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t igb_io_error_detected(struct pci_dev *pdev,
+                                             pci_channel_state_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev))
+               igb_down(adapter);
+       pci_disable_device(pdev);
+
+       /* Request a slot slot reset. */
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+/**
+ * igb_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot. Implementation
+ * resembles the first-half of the igb_resume routine.
+ */
+static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+
+       if (pci_enable_device(pdev)) {
+               dev_err(&pdev->dev,
+                       "Cannot re-enable PCI device after reset.\n");
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       igb_reset(adapter);
+       wr32(E1000_WUS, ~0);
+
+       return PCI_ERS_RESULT_RECOVERED;
+}
+
+/**
+ * igb_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells us that
+ * its OK to resume normal operation. Implementation resembles the
+ * second-half of the igb_resume routine.
+ */
+static void igb_io_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       igb_init_manageability(adapter);
+
+       if (netif_running(netdev)) {
+               if (igb_up(adapter)) {
+                       dev_err(&pdev->dev, "igb_up failed after reset\n");
+                       return;
+               }
+       }
+
+       netif_device_attach(netdev);
+
+       /* let the f/w know that the h/w is now under the control of the
+        * driver. */
+       igb_get_hw_control(adapter);
+
+}
+
+/* igb_main.c */
index 50f0c17451b10cccbafbb77d7c03bc55d9a70f91..5e5d9b527ed10b6a98aec3b58bd04968e8ee3efb 100644 (file)
@@ -34,9 +34,9 @@
         IPG_AC_DMA | IPG_AC_FIFO | IPG_AC_NETWORK | IPG_AC_HOST | \
         IPG_AC_AUTO_INIT)
 
-#define ipg_w32(val32,reg)     iowrite32((val32), ioaddr + (reg))
-#define ipg_w16(val16,reg)     iowrite16((val16), ioaddr + (reg))
-#define ipg_w8(val8,reg)       iowrite8((val8), ioaddr + (reg))
+#define ipg_w32(val32, reg)    iowrite32((val32), ioaddr + (reg))
+#define ipg_w16(val16, reg)    iowrite16((val16), ioaddr + (reg))
+#define ipg_w8(val8, reg)      iowrite8((val8), ioaddr + (reg))
 
 #define ipg_r32(reg)           ioread32(ioaddr + (reg))
 #define ipg_r16(reg)           ioread16(ioaddr + (reg))
@@ -51,24 +51,25 @@ enum {
 #define DRV_NAME       "ipg"
 
 MODULE_AUTHOR("IC Plus Corp. 2003");
-MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver "
-                  DrvVer);
+MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver");
 MODULE_LICENSE("GPL");
 
-//variable record -- index by leading revision/length
-//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
+/*
+ * Variable record -- index by leading revision/length
+ * Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
+ */
 static unsigned short DefaultPhyParam[] = {
-       // 11/12/03 IP1000A v1-3 rev=0x40
+       /* 11/12/03 IP1000A v1-3 rev=0x40 */
        /*--------------------------------------------------------------------------
        (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
                                 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
                                 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
          --------------------------------------------------------------------------*/
-       // 12/17/03 IP1000A v1-4 rev=0x40
+       /* 12/17/03 IP1000A v1-4 rev=0x40 */
        (0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
            0x0000,
        30, 0x005e, 9, 0x0700,
-       // 01/09/04 IP1000A v1-5 rev=0x41
+       /* 01/09/04 IP1000A v1-5 rev=0x41 */
        (0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
            0x0000,
        30, 0x005e, 9, 0x0700,
@@ -188,7 +189,7 @@ static void send_end(void __iomem *ioaddr, u8 phyctrlpolarity)
                phyctrlpolarity) & IPG_PC_RSVD_MASK, PHY_CTRL);
 }
 
-static u16 read_phy_bit(void __iomem * ioaddr, u8 phyctrlpolarity)
+static u16 read_phy_bit(void __iomem *ioaddr, u8 phyctrlpolarity)
 {
        u16 bit_data;
 
@@ -205,7 +206,7 @@ static u16 read_phy_bit(void __iomem * ioaddr, u8 phyctrlpolarity)
  * Read a register from the Physical Layer device located
  * on the IPG NIC, using the IPG PHYCTRL register.
  */
-static int mdio_read(struct net_device * dev, int phy_id, int phy_reg)
+static int mdio_read(struct net_device *dev, int phy_id, int phy_reg)
 {
        void __iomem *ioaddr = ipg_ioaddr(dev);
        /*
@@ -374,7 +375,6 @@ static void mdio_write(struct net_device *dev, int phy_id, int phy_reg, int val)
        }
 }
 
-/* Set LED_Mode JES20040127EEPROM */
 static void ipg_set_led_mode(struct net_device *dev)
 {
        struct ipg_nic_private *sp = netdev_priv(dev);
@@ -384,19 +384,18 @@ static void ipg_set_led_mode(struct net_device *dev)
        mode = ipg_r32(ASIC_CTRL);
        mode &= ~(IPG_AC_LED_MODE_BIT_1 | IPG_AC_LED_MODE | IPG_AC_LED_SPEED);
 
-       if ((sp->LED_Mode & 0x03) > 1)
+       if ((sp->led_mode & 0x03) > 1)
                mode |= IPG_AC_LED_MODE_BIT_1;  /* Write Asic Control Bit 29 */
 
-       if ((sp->LED_Mode & 0x01) == 1)
+       if ((sp->led_mode & 0x01) == 1)
                mode |= IPG_AC_LED_MODE;        /* Write Asic Control Bit 14 */
 
-       if ((sp->LED_Mode & 0x08) == 8)
+       if ((sp->led_mode & 0x08) == 8)
                mode |= IPG_AC_LED_SPEED;       /* Write Asic Control Bit 27 */
 
        ipg_w32(mode, ASIC_CTRL);
 }
 
-/* Set PHYSet JES20040127EEPROM */
 static void ipg_set_phy_set(struct net_device *dev)
 {
        struct ipg_nic_private *sp = netdev_priv(dev);
@@ -405,7 +404,7 @@ static void ipg_set_phy_set(struct net_device *dev)
 
        physet = ipg_r8(PHY_SET);
        physet &= ~(IPG_PS_MEM_LENB9B | IPG_PS_MEM_LEN9 | IPG_PS_NON_COMPDET);
-       physet |= ((sp->LED_Mode & 0x70) >> 4);
+       physet |= ((sp->led_mode & 0x70) >> 4);
        ipg_w8(physet, PHY_SET);
 }
 
@@ -415,7 +414,7 @@ static int ipg_reset(struct net_device *dev, u32 resetflags)
         * register as specified by the 'resetflags' input
         * parameter.
         */
-       void __iomem *ioaddr = ipg_ioaddr(dev); //JES20040127EEPROM:
+       void __iomem *ioaddr = ipg_ioaddr(dev);
        unsigned int timeout_count = 0;
 
        IPG_DEBUG_MSG("_reset\n");
@@ -430,10 +429,10 @@ static int ipg_reset(struct net_device *dev, u32 resetflags)
                if (++timeout_count > IPG_AC_RESET_TIMEOUT)
                        return -ETIME;
        }
-       /* Set LED Mode in Asic Control JES20040127EEPROM */
+       /* Set LED Mode in Asic Control */
        ipg_set_led_mode(dev);
 
-       /* Set PHYSet Register Value JES20040127EEPROM */
+       /* Set PHYSet Register Value */
        ipg_set_phy_set(dev);
        return 0;
 }
@@ -551,7 +550,7 @@ static int ipg_config_autoneg(struct net_device *dev)
                printk("\n");
        } else {
                /* Configure IPG for half duplex operation. */
-               printk(KERN_INFO "%s: setting half duplex, "
+               printk(KERN_INFO "%s: setting half duplex, "
                       "no TX flow control, no RX flow control.\n", dev->name);
 
                mac_ctrl_val &= ~IPG_MC_DUPLEX_SELECT_FD &
@@ -736,7 +735,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
 
        skb = netdev_alloc_skb(dev, IPG_RXSUPPORT_SIZE + NET_IP_ALIGN);
        if (!skb) {
-               sp->RxBuff[entry] = NULL;
+               sp->rx_buff[entry] = NULL;
                return -ENOMEM;
        }
 
@@ -749,7 +748,7 @@ static int ipg_get_rxbuff(struct net_device *dev, int entry)
        skb->dev = dev;
 
        /* Save the address of the sk_buff structure. */
-       sp->RxBuff[entry] = skb;
+       sp->rx_buff[entry] = skb;
 
        rxfd->frag_info = cpu_to_le64(pci_map_single(sp->pdev, skb->data,
                sp->rx_buf_sz, PCI_DMA_FROMDEVICE));
@@ -772,12 +771,12 @@ static int init_rfdlist(struct net_device *dev)
        for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
                struct ipg_rx *rxfd = sp->rxd + i;
 
-               if (sp->RxBuff[i]) {
+               if (sp->rx_buff[i]) {
                        pci_unmap_single(sp->pdev,
                                le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
                                sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-                       IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
-                       sp->RxBuff[i] = NULL;
+                       dev_kfree_skb_irq(sp->rx_buff[i]);
+                       sp->rx_buff[i] = NULL;
                }
 
                /* Clear out the RFS field. */
@@ -828,9 +827,9 @@ static void init_tfdlist(struct net_device *dev)
 
                txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);
 
-               if (sp->TxBuff[i]) {
-                       IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
-                       sp->TxBuff[i] = NULL;
+               if (sp->tx_buff[i]) {
+                       dev_kfree_skb_irq(sp->tx_buff[i]);
+                       sp->tx_buff[i] = NULL;
                }
 
                txfd->next_desc = cpu_to_le64(sp->txd_map +
@@ -847,7 +846,7 @@ static void init_tfdlist(struct net_device *dev)
        ipg_w32((u32) sp->txd_map, TFD_LIST_PTR_0);
        ipg_w32(0x00000000, TFD_LIST_PTR_1);
 
-       sp->ResetCurrentTFD = 1;
+       sp->reset_current_tfd = 1;
 }
 
 /*
@@ -865,7 +864,7 @@ static void ipg_nic_txfree(struct net_device *dev)
        dirty = sp->tx_dirty % IPG_TFDLIST_LENGTH;
 
        for (released = 0; released < pending; released++) {
-               struct sk_buff *skb = sp->TxBuff[dirty];
+               struct sk_buff *skb = sp->tx_buff[dirty];
                struct ipg_tx *txfd = sp->txd + dirty;
 
                IPG_DEBUG_MSG("TFC = %16.16lx\n", (unsigned long) txfd->tfc);
@@ -884,9 +883,9 @@ static void ipg_nic_txfree(struct net_device *dev)
                                le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
                                skb->len, PCI_DMA_TODEVICE);
 
-                       IPG_DEV_KFREE_SKB(skb);
+                       dev_kfree_skb_irq(skb);
 
-                       sp->TxBuff[dirty] = NULL;
+                       sp->tx_buff[dirty] = NULL;
                }
                dirty = (dirty + 1) % IPG_TFDLIST_LENGTH;
        }
@@ -1059,7 +1058,7 @@ static int ipg_nic_rxrestore(struct net_device *dev)
                unsigned int entry = dirty % IPG_RFDLIST_LENGTH;
 
                /* rx_copybreak may poke hole here and there. */
-               if (sp->RxBuff[entry])
+               if (sp->rx_buff[entry])
                        continue;
 
                /* Generate a new receive buffer to replace the
@@ -1083,22 +1082,22 @@ static int ipg_nic_rxrestore(struct net_device *dev)
 #ifdef JUMBO_FRAME
 
 /* use jumboindex and jumbosize to control jumbo frame status
  initial status is jumboindex=-1 and jumbosize=0
  1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
  2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving
  3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump
-                previous receiving and need to continue dumping the current one
-*/
* initial status is jumboindex=-1 and jumbosize=0
* 1. jumboindex = -1 and jumbosize=0 : previous jumbo frame has been done.
* 2. jumboindex != -1 and jumbosize != 0 : jumbo frame is not over size and receiving
* 3. jumboindex = -1 and jumbosize != 0 : jumbo frame is over size, already dump
*               previous receiving and need to continue dumping the current one
+ */
 enum {
-       NormalPacket,
-       ErrorPacket
+       NORMAL_PACKET,
+       ERROR_PACKET
 };
 
 enum {
-       Frame_NoStart_NoEnd     = 0,
-       Frame_WithStart         = 1,
-       Frame_WithEnd           = 10,
-       Frame_WithStart_WithEnd = 11
+       FRAME_NO_START_NO_END   = 0,
+       FRAME_WITH_START                = 1,
+       FRAME_WITH_END          = 10,
+       FRAME_WITH_START_WITH_END = 11
 };
 
 inline void ipg_nic_rx_free_skb(struct net_device *dev)
@@ -1106,14 +1105,14 @@ inline void ipg_nic_rx_free_skb(struct net_device *dev)
        struct ipg_nic_private *sp = netdev_priv(dev);
        unsigned int entry = sp->rx_current % IPG_RFDLIST_LENGTH;
 
-       if (sp->RxBuff[entry]) {
+       if (sp->rx_buff[entry]) {
                struct ipg_rx *rxfd = sp->rxd + entry;
 
                pci_unmap_single(sp->pdev,
                        le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
                        sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-               IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
-               sp->RxBuff[entry] = NULL;
+               dev_kfree_skb_irq(sp->rx_buff[entry]);
+               sp->rx_buff[entry] = NULL;
        }
 }
 
@@ -1121,12 +1120,12 @@ inline int ipg_nic_rx_check_frame_type(struct net_device *dev)
 {
        struct ipg_nic_private *sp = netdev_priv(dev);
        struct ipg_rx *rxfd = sp->rxd + (sp->rx_current % IPG_RFDLIST_LENGTH);
-       int type = Frame_NoStart_NoEnd;
+       int type = FRAME_NO_START_NO_END;
 
        if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMESTART)
-               type += Frame_WithStart;
+               type += FRAME_WITH_START;
        if (le64_to_cpu(rxfd->rfs) & IPG_RFS_FRAMEEND)
-               type += Frame_WithEnd;
+               type += FRAME_WITH_END;
        return type;
 }
 
@@ -1175,43 +1174,43 @@ inline int ipg_nic_rx_check_error(struct net_device *dev)
                 * buffer since it is erroneous and we will
                 * not pass it to higher layer processes.
                 */
-               if (sp->RxBuff[entry]) {
+               if (sp->rx_buff[entry]) {
                        pci_unmap_single(sp->pdev,
                                le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
                                sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
-                       IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
-                       sp->RxBuff[entry] = NULL;
+                       dev_kfree_skb_irq(sp->rx_buff[entry]);
+                       sp->rx_buff[entry] = NULL;
                }
-               return ErrorPacket;
+               return ERROR_PACKET;
        }
-       return NormalPacket;
+       return NORMAL_PACKET;
 }
 
 static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
                                          struct ipg_nic_private *sp,
                                          struct ipg_rx *rxfd, unsigned entry)
 {
-       struct SJumbo *jumbo = &sp->Jumbo;
+       struct ipg_jumbo *jumbo = &sp->jumbo;
        struct sk_buff *skb;
        int framelen;
 
-       if (jumbo->FoundStart) {
-               IPG_DEV_KFREE_SKB(jumbo->skb);
-               jumbo->FoundStart = 0;
-               jumbo->CurrentSize = 0;
+       if (jumbo->found_start) {
+               dev_kfree_skb_irq(jumbo->skb);
+               jumbo->found_start = 0;
+               jumbo->current_size = 0;
                jumbo->skb = NULL;
        }
 
-       // 1: found error, 0 no error
-       if (ipg_nic_rx_check_error(dev) != NormalPacket)
+       /* 1: found error, 0 no error */
+       if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
                return;
 
-       skb = sp->RxBuff[entry];
+       skb = sp->rx_buff[entry];
        if (!skb)
                return;
 
-       // accept this frame and send to upper layer
+       /* accept this frame and send to upper layer */
        framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
        if (framelen > IPG_RXFRAG_SIZE)
                framelen = IPG_RXFRAG_SIZE;
@@ -1221,39 +1220,39 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev,
        skb->ip_summed = CHECKSUM_NONE;
        netif_rx(skb);
        dev->last_rx = jiffies;
-       sp->RxBuff[entry] = NULL;
+       sp->rx_buff[entry] = NULL;
 }
 
 static void ipg_nic_rx_with_start(struct net_device *dev,
                                  struct ipg_nic_private *sp,
                                  struct ipg_rx *rxfd, unsigned entry)
 {
-       struct SJumbo *jumbo = &sp->Jumbo;
+       struct ipg_jumbo *jumbo = &sp->jumbo;
        struct pci_dev *pdev = sp->pdev;
        struct sk_buff *skb;
 
-       // 1: found error, 0 no error
-       if (ipg_nic_rx_check_error(dev) != NormalPacket)
+       /* 1: found error, 0 no error */
+       if (ipg_nic_rx_check_error(dev) != NORMAL_PACKET)
                return;
 
-       // accept this frame and send to upper layer
-       skb = sp->RxBuff[entry];
+       /* accept this frame and send to upper layer */
+       skb = sp->rx_buff[entry];
        if (!skb)
                return;
 
-       if (jumbo->FoundStart)
-               IPG_DEV_KFREE_SKB(jumbo->skb);
+       if (jumbo->found_start)
+               dev_kfree_skb_irq(jumbo->skb);
 
        pci_unmap_single(pdev, le64_to_cpu(rxfd->frag_info & ~IPG_RFI_FRAGLEN),
                         sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
        skb_put(skb, IPG_RXFRAG_SIZE);
 
-       jumbo->FoundStart = 1;
-       jumbo->CurrentSize = IPG_RXFRAG_SIZE;
+       jumbo->found_start = 1;
+       jumbo->current_size = IPG_RXFRAG_SIZE;
        jumbo->skb = skb;
 
-       sp->RxBuff[entry] = NULL;
+       sp->rx_buff[entry] = NULL;
        dev->last_rx = jiffies;
 }
 
@@ -1261,27 +1260,27 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
                                struct ipg_nic_private *sp,
                                struct ipg_rx *rxfd, unsigned entry)
 {
-       struct SJumbo *jumbo = &sp->Jumbo;
+       struct ipg_jumbo *jumbo = &sp->jumbo;
 
-       //1: found error, 0 no error
-       if (ipg_nic_rx_check_error(dev) == NormalPacket) {
-               struct sk_buff *skb = sp->RxBuff[entry];
+       /* 1: found error, 0 no error */
+       if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
+               struct sk_buff *skb = sp->rx_buff[entry];
 
                if (!skb)
                        return;
 
-               if (jumbo->FoundStart) {
+               if (jumbo->found_start) {
                        int framelen, endframelen;
 
                        framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
 
-                       endframeLen = framelen - jumbo->CurrentSize;
+                       endframeLen = framelen - jumbo->current_size;
                        /*
                        if (framelen > IPG_RXFRAG_SIZE)
                                framelen=IPG_RXFRAG_SIZE;
                         */
                        if (framelen > IPG_RXSUPPORT_SIZE)
-                               IPG_DEV_KFREE_SKB(jumbo->skb);
+                               dev_kfree_skb_irq(jumbo->skb);
                        else {
                                memcpy(skb_put(jumbo->skb, endframeLen),
                                       skb->data, endframeLen);
@@ -1295,15 +1294,15 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
                }
 
                dev->last_rx = jiffies;
-               jumbo->FoundStart = 0;
-               jumbo->CurrentSize = 0;
+               jumbo->found_start = 0;
+               jumbo->current_size = 0;
                jumbo->skb = NULL;
 
                ipg_nic_rx_free_skb(dev);
        } else {
-               IPG_DEV_KFREE_SKB(jumbo->skb);
-               jumbo->FoundStart = 0;
-               jumbo->CurrentSize = 0;
+               dev_kfree_skb_irq(jumbo->skb);
+               jumbo->found_start = 0;
+               jumbo->current_size = 0;
                jumbo->skb = NULL;
        }
 }
@@ -1312,16 +1311,16 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
                                       struct ipg_nic_private *sp,
                                       struct ipg_rx *rxfd, unsigned entry)
 {
-       struct SJumbo *jumbo = &sp->Jumbo;
+       struct ipg_jumbo *jumbo = &sp->jumbo;
 
-       //1: found error, 0 no error
-       if (ipg_nic_rx_check_error(dev) == NormalPacket) {
-               struct sk_buff *skb = sp->RxBuff[entry];
+       /* 1: found error, 0 no error */
+       if (ipg_nic_rx_check_error(dev) == NORMAL_PACKET) {
+               struct sk_buff *skb = sp->rx_buff[entry];
 
                if (skb) {
-                       if (jumbo->FoundStart) {
-                               jumbo->CurrentSize += IPG_RXFRAG_SIZE;
-                               if (jumbo->CurrentSize <= IPG_RXSUPPORT_SIZE) {
+                       if (jumbo->found_start) {
+                               jumbo->current_size += IPG_RXFRAG_SIZE;
+                               if (jumbo->current_size <= IPG_RXSUPPORT_SIZE) {
                                        memcpy(skb_put(jumbo->skb,
                                                       IPG_RXFRAG_SIZE),
                                               skb->data, IPG_RXFRAG_SIZE);
@@ -1331,9 +1330,9 @@ static void ipg_nic_rx_no_start_no_end(struct net_device *dev,
                        ipg_nic_rx_free_skb(dev);
                }
        } else {
-               IPG_DEV_KFREE_SKB(jumbo->skb);
-               jumbo->FoundStart = 0;
-               jumbo->CurrentSize = 0;
+               dev_kfree_skb_irq(jumbo->skb);
+               jumbo->found_start = 0;
+               jumbo->current_size = 0;
                jumbo->skb = NULL;
        }
 }
@@ -1355,16 +1354,16 @@ static int ipg_nic_rx(struct net_device *dev)
                        break;
 
                switch (ipg_nic_rx_check_frame_type(dev)) {
-               case Frame_WithStart_WithEnd:
+               case FRAME_WITH_START_WITH_END:
                        ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry);
                        break;
-               case Frame_WithStart:
+               case FRAME_WITH_START:
                        ipg_nic_rx_with_start(dev, tp, rxfd, entry);
                        break;
-               case Frame_WithEnd:
+               case FRAME_WITH_END:
                        ipg_nic_rx_with_end(dev, tp, rxfd, entry);
                        break;
-               case Frame_NoStart_NoEnd:
+               case FRAME_NO_START_NO_END:
                        ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry);
                        break;
                }
@@ -1403,7 +1402,7 @@ static int ipg_nic_rx(struct net_device *dev)
 
        for (i = 0; i < IPG_MAXRFDPROCESS_COUNT; i++, curr++) {
                unsigned int entry = curr % IPG_RFDLIST_LENGTH;
-               struct sk_buff *skb = sp->RxBuff[entry];
+               struct sk_buff *skb = sp->rx_buff[entry];
                unsigned int framelen;
 
                rxfd = sp->rxd + entry;
@@ -1472,7 +1471,7 @@ static int ipg_nic_rx(struct net_device *dev)
                                        le64_to_cpu(info) & ~IPG_RFI_FRAGLEN,
                                        sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
-                               IPG_DEV_KFREE_SKB(skb);
+                               dev_kfree_skb_irq(skb);
                        }
                } else {
 
@@ -1484,35 +1483,13 @@ static int ipg_nic_rx(struct net_device *dev)
                        /* Set the buffer's protocol field to Ethernet. */
                        skb->protocol = eth_type_trans(skb, dev);
 
-                       /* If the frame contains an IP/TCP/UDP frame,
-                        * determine if upper layer must check IP/TCP/UDP
-                        * checksums.
-                        *
-                        * NOTE: DO NOT RELY ON THE TCP/UDP CHECKSUM
-                        *       VERIFICATION FOR SILICON REVISIONS B3
-                        *       AND EARLIER!
-                        *
-                        if ((le64_to_cpu(rxfd->rfs &
-                            (IPG_RFS_TCPDETECTED | IPG_RFS_UDPDETECTED |
-                             IPG_RFS_IPDETECTED))) &&
-                           !(le64_to_cpu(rxfd->rfs &
-                             (IPG_RFS_TCPERROR | IPG_RFS_UDPERROR |
-                              IPG_RFS_IPERROR)))) {
-                                * Indicate IP checksums were performed
-                                * by the IPG.
-                                *
-                               skb->ip_summed = CHECKSUM_UNNECESSARY;
-                        } else
+                       /* The IPG encountered an error with (or
+                        * there were no) IP/TCP/UDP checksums.
+                        * This may or may not indicate an invalid
+                        * IP/TCP/UDP frame was received. Let the
+                        * upper layer decide.
                         */
-                        {
-                               /* The IPG encountered an error with (or
-                                * there were no) IP/TCP/UDP checksums.
-                                * This may or may not indicate an invalid
-                                * IP/TCP/UDP frame was received. Let the
-                                * upper layer decide.
-                                */
-                               skb->ip_summed = CHECKSUM_NONE;
-                       }
+                       skb->ip_summed = CHECKSUM_NONE;
 
                        /* Hand off frame for higher layer processing.
                         * The function netif_rx() releases the sk_buff
@@ -1527,7 +1504,7 @@ static int ipg_nic_rx(struct net_device *dev)
                }
 
                /* Assure RX buffer is not reused by IPG. */
-               sp->RxBuff[entry] = NULL;
+               sp->rx_buff[entry] = NULL;
        }
 
        /*
@@ -1561,15 +1538,15 @@ static int ipg_nic_rx(struct net_device *dev)
                 * buffer since it is erroneous and we will
                 * not pass it to higher layer processes.
                 */
-               if (sp->RxBuff[entry]) {
+               if (sp->rx_buff[entry]) {
                        pci_unmap_single(sp->pdev,
                                le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
                                sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-                       IPG_DEV_KFREE_SKB(sp->RxBuff[entry]);
+                       dev_kfree_skb_irq(sp->rx_buff[entry]);
                }
 
                /* Assure RX buffer is not reused by IPG. */
-               sp->RxBuff[entry] = NULL;
+               sp->rx_buff[entry] = NULL;
        }
 
        sp->rx_current = curr;
@@ -1735,11 +1712,11 @@ static void ipg_rx_clear(struct ipg_nic_private *sp)
        unsigned int i;
 
        for (i = 0; i < IPG_RFDLIST_LENGTH; i++) {
-               if (sp->RxBuff[i]) {
+               if (sp->rx_buff[i]) {
                        struct ipg_rx *rxfd = sp->rxd + i;
 
-                       IPG_DEV_KFREE_SKB(sp->RxBuff[i]);
-                       sp->RxBuff[i] = NULL;
+                       dev_kfree_skb_irq(sp->rx_buff[i]);
+                       sp->rx_buff[i] = NULL;
                        pci_unmap_single(sp->pdev,
                                le64_to_cpu(rxfd->frag_info) & ~IPG_RFI_FRAGLEN,
                                sp->rx_buf_sz, PCI_DMA_FROMDEVICE);
@@ -1752,16 +1729,16 @@ static void ipg_tx_clear(struct ipg_nic_private *sp)
        unsigned int i;
 
        for (i = 0; i < IPG_TFDLIST_LENGTH; i++) {
-               if (sp->TxBuff[i]) {
+               if (sp->tx_buff[i]) {
                        struct ipg_tx *txfd = sp->txd + i;
 
                        pci_unmap_single(sp->pdev,
                                le64_to_cpu(txfd->frag_info) & ~IPG_TFI_FRAGLEN,
-                               sp->TxBuff[i]->len, PCI_DMA_TODEVICE);
+                               sp->tx_buff[i]->len, PCI_DMA_TODEVICE);
 
-                       IPG_DEV_KFREE_SKB(sp->TxBuff[i]);
+                       dev_kfree_skb_irq(sp->tx_buff[i]);
 
-                       sp->TxBuff[i] = NULL;
+                       sp->tx_buff[i] = NULL;
                }
        }
 }
@@ -1832,9 +1809,9 @@ static int ipg_nic_open(struct net_device *dev)
 
 #ifdef JUMBO_FRAME
        /* initialize JUMBO Frame control variable */
-       sp->Jumbo.FoundStart = 0;
-       sp->Jumbo.CurrentSize = 0;
-       sp->Jumbo.skb = 0;
+       sp->jumbo.found_start = 0;
+       sp->jumbo.current_size = 0;
+       sp->jumbo.skb = 0;
        dev->mtu = IPG_TXFRAG_SIZE;
 #endif
 
@@ -1909,14 +1886,14 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (sp->tenmbpsmode)
                netif_stop_queue(dev);
 
-       if (sp->ResetCurrentTFD) {
-               sp->ResetCurrentTFD = 0;
+       if (sp->reset_current_tfd) {
+               sp->reset_current_tfd = 0;
                entry = 0;
        }
 
        txfd = sp->txd + entry;
 
-       sp->TxBuff[entry] = skb;
+       sp->tx_buff[entry] = skb;
 
        /* Clear all TFC fields, except TFDDONE. */
        txfd->tfc = cpu_to_le64(IPG_TFC_TFDDONE);
@@ -2029,7 +2006,6 @@ static void ipg_set_phy_default_param(unsigned char rev,
        }
 }
 
-/* JES20040127EEPROM */
 static int read_eeprom(struct net_device *dev, int eep_addr)
 {
        void __iomem *ioaddr = ipg_ioaddr(dev);
@@ -2096,9 +2072,9 @@ static int ipg_hw_init(struct net_device *dev)
        unsigned int i;
        int rc;
 
-       /* Read/Write and Reset EEPROM Value Jesse20040128EEPROM_VALUE */
+       /* Read/Write and Reset EEPROM Value */
        /* Read LED Mode Configuration from EEPROM */
-       sp->LED_Mode = read_eeprom(dev, 6);
+       sp->led_mode = read_eeprom(dev, 6);
 
        /* Reset all functions within the IPG. Do not assert
         * RST_OUT as not compatible with some PHYs.
@@ -2202,7 +2178,7 @@ static struct ethtool_ops ipg_ethtool_ops = {
        .nway_reset   = ipg_nway_reset,
 };
 
-static void ipg_remove(struct pci_dev *pdev)
+static void __devexit ipg_remove(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct ipg_nic_private *sp = netdev_priv(dev);
index d5d092c9d0afb0fa29479b7405fe8bb0eeb97c01..cda53887d4db0ac84371a638db66807c88e82e67 100644 (file)
@@ -1,20 +1,8 @@
 /*
- *
- * ipg.h
- *
  * Include file for Gigabit Ethernet device driver for Network
  * Interface Cards (NICs) utilizing the Tamarack Microelectronics
  * Inc. IPG Gigabit or Triple Speed Ethernet Media Access
  * Controller.
- *
- * Craig Rich
- * Sundance Technology, Inc.
- * 1485 Saratoga Avenue
- * Suite 200
- * San Jose, CA 95129
- * 408 873 4117
- * www.sundanceti.com
- * craig_rich@sundanceti.com
  */
 #ifndef __LINUX_IPG_H
 #define __LINUX_IPG_H
 #include <linux/skbuff.h>
 #include <linux/version.h>
 #include <asm/bitops.h>
-/*#include <asm/spinlock.h>*/
-
-#define DrvVer "2.09d"
-
-#define IPG_DEV_KFREE_SKB(skb) dev_kfree_skb_irq(skb)
 
 /*
  *     Constants
@@ -68,7 +51,7 @@
 /* I/O register offsets. */
 enum ipg_regs {
        DMA_CTRL                = 0x00,
-       RX_DMA_STATUS           = 0x08, // Unused + reserved
+       RX_DMA_STATUS           = 0x08, /* Unused + reserved */
        TFD_LIST_PTR_0          = 0x10,
        TFD_LIST_PTR_1          = 0x14,
        TX_DMA_BURST_THRESH     = 0x18,
@@ -81,22 +64,22 @@ enum ipg_regs {
        RX_DMA_POLL_PERIOD      = 0x26,
        DEBUG_CTRL              = 0x2c,
        ASIC_CTRL               = 0x30,
-       FIFO_CTRL               = 0x38, // Unused
+       FIFO_CTRL               = 0x38, /* Unused */
        FLOW_OFF_THRESH         = 0x3c,
        FLOW_ON_THRESH          = 0x3e,
        EEPROM_DATA             = 0x48,
        EEPROM_CTRL             = 0x4a,
-       EXPROM_ADDR             = 0x4c, // Unused
-       EXPROM_DATA             = 0x50, // Unused
-       WAKE_EVENT              = 0x51, // Unused
-       COUNTDOWN               = 0x54, // Unused
+       EXPROM_ADDR             = 0x4c, /* Unused */
+       EXPROM_DATA             = 0x50, /* Unused */
+       WAKE_EVENT              = 0x51, /* Unused */
+       COUNTDOWN               = 0x54, /* Unused */
        INT_STATUS_ACK          = 0x5a,
        INT_ENABLE              = 0x5c,
-       INT_STATUS              = 0x5e, // Unused
+       INT_STATUS              = 0x5e, /* Unused */
        TX_STATUS               = 0x60,
        MAC_CTRL                = 0x6c,
-       VLAN_TAG                = 0x70, // Unused
-       PHY_SET                 = 0x75, // JES20040127EEPROM
+       VLAN_TAG                = 0x70, /* Unused */
+       PHY_SET                 = 0x75,
        PHY_CTRL                = 0x76,
        STATION_ADDRESS_0       = 0x78,
        STATION_ADDRESS_1       = 0x7a,
@@ -107,11 +90,11 @@ enum ipg_regs {
        HASHTABLE_1             = 0x90,
        RMON_STATISTICS_MASK    = 0x98,
        STATISTICS_MASK         = 0x9c,
-       RX_JUMBO_FRAMES         = 0xbc, // Unused
-       TCP_CHECKSUM_ERRORS     = 0xc0, // Unused
-       IP_CHECKSUM_ERRORS      = 0xc2, // Unused
-       UDP_CHECKSUM_ERRORS     = 0xc4, // Unused
-       TX_JUMBO_FRAMES         = 0xf4  // Unused
+       RX_JUMBO_FRAMES         = 0xbc, /* Unused */
+       TCP_CHECKSUM_ERRORS     = 0xc0, /* Unused */
+       IP_CHECKSUM_ERRORS      = 0xc2, /* Unused */
+       UDP_CHECKSUM_ERRORS     = 0xc4, /* Unused */
+       TX_JUMBO_FRAMES         = 0xf4  /* Unused */
 };
 
 /* Ethernet MIB statistic register offsets. */
@@ -329,7 +312,7 @@ enum ipg_regs {
 #define IPG_RM_RECEIVEMULTICASTHASH     0x10
 #define IPG_RM_RECEIVEIPMULTICAST       0x20
 
-/* PhySet JES20040127EEPROM*/
+/* PhySet */
 #define IPG_PS_MEM_LENB9B               0x01
 #define IPG_PS_MEM_LEN9                 0x02
 #define IPG_PS_NON_COMPDET              0x04
@@ -386,8 +369,8 @@ enum ipg_regs {
 #define IPG_AC_RST_OUT                  0x01000000
 #define IPG_AC_INT_REQUEST              0x02000000
 #define IPG_AC_RESET_BUSY               0x04000000
-#define IPG_AC_LED_SPEED                0x08000000     //JES20040127EEPROM
-#define IPG_AC_LED_MODE_BIT_1           0x20000000     //JES20040127EEPROM
+#define IPG_AC_LED_SPEED                0x08000000
+#define IPG_AC_LED_MODE_BIT_1           0x20000000
 
 /* EepromCtrl */
 #define IPG_EC_RSVD_MASK                0x83FF
@@ -490,38 +473,34 @@ enum ipg_regs {
  *     Tune
  */
 
-/* Miscellaneous Constants. */
-#define   TRUE  1
-#define   FALSE 0
-
 /* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS append on TX. */
-#define         IPG_APPEND_FCS_ON_TX         TRUE
+#define         IPG_APPEND_FCS_ON_TX         1
 
 /* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS strip on RX. */
-#define         IPG_STRIP_FCS_ON_RX          TRUE
+#define         IPG_STRIP_FCS_ON_RX          1
 
 /* Assign IPG_DROP_ON_RX_ETH_ERRORS > 0 to drop RX frames with
  * Ethernet errors.
  */
-#define         IPG_DROP_ON_RX_ETH_ERRORS    TRUE
+#define         IPG_DROP_ON_RX_ETH_ERRORS    1
 
 /* Assign IPG_INSERT_MANUAL_VLAN_TAG > 0 to insert VLAN tags manually
  * (via TFC).
  */
-#define                IPG_INSERT_MANUAL_VLAN_TAG   FALSE
+#define                IPG_INSERT_MANUAL_VLAN_TAG   0
 
 /* Assign IPG_ADD_IPCHECKSUM_ON_TX > 0 for auto IP checksum on TX. */
-#define         IPG_ADD_IPCHECKSUM_ON_TX     FALSE
+#define         IPG_ADD_IPCHECKSUM_ON_TX     0
 
 /* Assign IPG_ADD_TCPCHECKSUM_ON_TX > 0 for auto TCP checksum on TX.
  * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
  */
-#define         IPG_ADD_TCPCHECKSUM_ON_TX    FALSE
+#define         IPG_ADD_TCPCHECKSUM_ON_TX    0
 
 /* Assign IPG_ADD_UDPCHECKSUM_ON_TX > 0 for auto UDP checksum on TX.
  * DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
  */
-#define         IPG_ADD_UDPCHECKSUM_ON_TX    FALSE
+#define         IPG_ADD_UDPCHECKSUM_ON_TX    0
 
 /* If inserting VLAN tags manually, assign the IPG_MANUAL_VLAN_xx
  * constants as desired.
@@ -611,7 +590,7 @@ enum ipg_regs {
  * Define larger if expecting jumbo frames.
  */
 #ifdef JUMBO_FRAME
-//IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash
+/* IPG_TXFRAG_SIZE must <= 0x2b00, or TX will crash */
 #define                IPG_TXFRAG_SIZE         JUMBO_FRAME_SIZE
 #endif
 
@@ -619,7 +598,7 @@ enum ipg_regs {
  * Define larger if expecting jumbo frames.
  */
 #ifdef JUMBO_FRAME
-//4088=4096-8
+/* 4088 = 4096 - 8 */
 #define                IPG_RXFRAG_SIZE         __IPG_RXFRAG_SIZE
 #define     IPG_RXSUPPORT_SIZE   IPG_MAX_RXFRAME_SIZE
 #else
@@ -647,9 +626,9 @@ enum ipg_regs {
 #define                IPG_MINUSEDRFDSTOFREE   0x80
 
 /* specify the jumbo frame maximum size
- * per unit is 0x600 (the RxBuffer size that one RFD can carry)
+ * per unit is 0x600 (the rx_buffer size that one RFD can carry)
  */
-#define     MAX_JUMBOSIZE              0x8     // max is 12K
+#define     MAX_JUMBOSIZE              0x8     /* max is 12K */
 
 /* Key register values loaded at driver start up. */
 
@@ -753,8 +732,7 @@ enum ipg_regs {
  * Miscellaneous macros.
  */
 
-/* Marco for printing debug statements.
-#  define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " ## args) */
+/* Marco for printing debug statements. */
 #ifdef IPG_DEBUG
 #  define IPG_DEBUG_MSG(args...)
 #  define IPG_DDEBUG_MSG(args...) printk(KERN_DEBUG "IPG: " args)
@@ -789,11 +767,12 @@ struct ipg_rx {
        __le64 frag_info;
 };
 
-struct SJumbo {
-       int FoundStart;
-       int CurrentSize;
+struct ipg_jumbo {
+       int found_start;
+       int current_size;
        struct sk_buff *skb;
 };
+
 /* Structure of IPG NIC specific data. */
 struct ipg_nic_private {
        void __iomem *ioaddr;
@@ -801,15 +780,14 @@ struct ipg_nic_private {
        struct ipg_rx *rxd;
        dma_addr_t txd_map;
        dma_addr_t rxd_map;
-       struct sk_buff *TxBuff[IPG_TFDLIST_LENGTH];
-       struct sk_buff *RxBuff[IPG_RFDLIST_LENGTH];
+       struct sk_buff *tx_buff[IPG_TFDLIST_LENGTH];
+       struct sk_buff *rx_buff[IPG_RFDLIST_LENGTH];
        unsigned int tx_current;
        unsigned int tx_dirty;
        unsigned int rx_current;
        unsigned int rx_dirty;
-// Add by Grace 2005/05/19
 #ifdef JUMBO_FRAME
-       struct SJumbo Jumbo;
+       struct ipg_jumbo jumbo;
 #endif
        unsigned int rx_buf_sz;
        struct pci_dev *pdev;
@@ -818,13 +796,12 @@ struct ipg_nic_private {
        spinlock_t lock;
        int tenmbpsmode;
 
-       /*Jesse20040128EEPROM_VALUE */
-       u16 LED_Mode;
+       u16 led_mode;
        u16 station_addr[3];    /* Station Address in EEPROM Reg 0x10..0x12 */
 
        struct mutex            mii_mutex;
        struct mii_if_info      mii_if;
-       int ResetCurrentTFD;
+       int reset_current_tfd;
 #ifdef IPG_DEBUG
        int RFDlistendCount;
        int RFDListCheckedCount;
index 65806956728afa95e832d0bcd37e036d1f634eb0..ce816ba9c40dad35ada98f33feeb7dfa57faf1a9 100644 (file)
@@ -190,147 +190,6 @@ config KS959_DONGLE
          To compile it as a module, choose M here: the module will be called
          ks959-sir.
 
-comment "Old SIR device drivers"
-
-config IRPORT_SIR
-       tristate "IrPORT (IrDA serial driver)"
-       depends on IRDA && BROKEN_ON_SMP
-       ---help---
-         Say Y here if you want to build support for the IrPORT IrDA device
-         driver.  To compile it as a module, choose M here: the module will be
-         called irport. IrPORT can be used instead of IrTTY and sometimes
-         this can be better.  One example is if your IrDA port does not
-         have echo-canceling, which will work OK with IrPORT since this
-         driver is working in half-duplex mode only.  You don't need to use
-         irattach with IrPORT, but you just insert it the same way as FIR
-         drivers (insmod irport io=0x3e8 irq=11).  Notice that IrPORT is a
-         SIR device driver which means that speed is limited to 115200 bps.
-
-         If unsure, say Y.
-
-comment "Old Serial dongle support"
-
-config DONGLE_OLD
-       bool "Old Serial dongle support"
-       depends on IRPORT_SIR && BROKEN_ON_SMP
-       help
-         Say Y here if you have an infrared device that connects to your
-         computer's serial port. These devices are called dongles. Then say Y
-         or M to the driver for your particular dongle below.
-
-         Note that the answer to this question won't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about serial dongles.
-
-config ESI_DONGLE_OLD
-       tristate "ESI JetEye PC dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Extended Systems
-         JetEye PC dongle.  To compile it as a module, choose M here.  The ESI
-         dongle attaches to the normal 9-pin serial port connector, and can
-         currently only be used by IrTTY.  To activate support for ESI
-         dongles you will have to start irattach like this:
-         "irattach -d esi".
-
-config ACTISYS_DONGLE_OLD
-       tristate "ACTiSYS IR-220L and IR220L+ dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the ACTiSYS IR-220L and
-         IR220L+ dongles.  To compile it as a module, choose M here.  The
-         ACTiSYS dongles attaches to the normal 9-pin serial port connector,
-         and can currently only be used by IrTTY.  To activate support for
-         ACTiSYS dongles you will have to start irattach like this:
-         "irattach -d actisys" or "irattach -d actisys+".
-
-config TEKRAM_DONGLE_OLD
-       tristate "Tekram IrMate 210B dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Tekram IrMate 210B
-         dongle.  To compile it as a module, choose M here.  The Tekram dongle
-         attaches to the normal 9-pin serial port connector, and can
-         currently only be used by IrTTY.  To activate support for Tekram
-         dongles you will have to start irattach like this:
-         "irattach -d tekram".
-
-config GIRBIL_DONGLE_OLD
-       tristate "Greenwich GIrBIL dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Greenwich GIrBIL
-         dongle.  To compile it as a module, choose M here.  The Greenwich
-         dongle attaches to the normal 9-pin serial port connector, and can
-         currently only be used by IrTTY.  To activate support for Greenwich
-         dongles you will have to insert "irattach -d girbil" in the
-         /etc/irda/drivers script.
-
-config LITELINK_DONGLE_OLD
-       tristate "Parallax LiteLink dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Parallax Litelink
-         dongle.  To compile it as a module, choose M here.  The Parallax
-         dongle attaches to the normal 9-pin serial port connector, and can
-         currently only be used by IrTTY.  To activate support for Parallax
-         dongles you will have to start irattach like this:
-         "irattach -d litelink".
-
-config MCP2120_DONGLE_OLD
-       tristate "Microchip MCP2120"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Microchip MCP2120
-         dongle.  To compile it as a module, choose M here.  The MCP2120 dongle
-         attaches to the normal 9-pin serial port connector, and can
-         currently only be used by IrTTY.  To activate support for MCP2120
-         dongles you will have to insert "irattach -d mcp2120" in the
-         /etc/irda/drivers script.
-
-         You must build this dongle yourself.  For more information see:
-         <http://www.eyetap.org/~tangf/irda_sir_linux.html>
-
-config OLD_BELKIN_DONGLE_OLD
-       tristate "Old Belkin dongle"
-       depends on DONGLE_OLD && IRDA
-       help
-         Say Y here if you want to build support for the Adaptec Airport 1000
-         and 2000 dongles.  To compile it as a module, choose M here: the module
-         will be called old_belkin.  Some information is contained in the
-         comments at the top of <file:drivers/net/irda/old_belkin.c>.
-
-config ACT200L_DONGLE_OLD
-       tristate "ACTiSYS IR-200L dongle (EXPERIMENTAL)"
-       depends on DONGLE_OLD && EXPERIMENTAL && IRDA
-       help
-         Say Y here if you want to build support for the ACTiSYS IR-200L
-         dongle.  To compile it as a module, choose M here.  The ACTiSYS
-         IR-200L dongle attaches to the normal 9-pin serial port connector,
-         and can currently only be used by IrTTY. To activate support for
-         ACTiSYS IR-200L dongles you will have to start irattach like this:
-         "irattach -d act200l".
-
-config MA600_DONGLE_OLD
-       tristate "Mobile Action MA600 dongle (EXPERIMENTAL)"
-       depends on DONGLE_OLD && EXPERIMENTAL && IRDA
-       ---help---
-         Say Y here if you want to build support for the Mobile Action MA600
-         dongle.  To compile it as a module, choose M here. The MA600 dongle
-         attaches to the normal 9-pin serial port connector, and can
-         currently only be tested on IrCOMM.  To activate support for MA600
-         dongles you will have to insert "irattach -d ma600" in the
-         /etc/irda/drivers script.  Note: irutils 0.9.15 requires no
-         modification. irutils 0.9.9 needs modification. For more
-         information, download the following tar gzip file.
-
-         There is a pre-compiled module on
-         <http://engsvr.ust.hk/~eetwl95/ma600.html>
-
-config EP7211_IR
-       tristate "EP7211 I/R support"
-       depends on DONGLE_OLD && ARCH_EP7211 && IRDA
-
 comment "FIR device drivers"
 
 config USB_IRDA
index fefbb590908165b720a5607514dd5fd449fae6d4..5d20fde32a246fd41081594e6559239b60c4bf23 100644 (file)
@@ -5,8 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-# Old SIR drivers 
-obj-$(CONFIG_IRPORT_SIR)       +=              irport.o
 # FIR drivers
 obj-$(CONFIG_USB_IRDA)         += irda-usb.o
 obj-$(CONFIG_SIGMATEL_FIR)     += stir4200.o
@@ -20,21 +18,10 @@ obj-$(CONFIG_VLSI_FIR)              += vlsi_ir.o
 obj-$(CONFIG_VIA_FIR)          += via-ircc.o
 obj-$(CONFIG_PXA_FICP)         += pxaficp_ir.o
 obj-$(CONFIG_MCS_FIR)          += mcs7780.o
-# Old dongle drivers for old SIR drivers
-obj-$(CONFIG_ESI_DONGLE_OLD)           += esi.o
-obj-$(CONFIG_TEKRAM_DONGLE_OLD)        += tekram.o
-obj-$(CONFIG_ACTISYS_DONGLE_OLD)       += actisys.o
-obj-$(CONFIG_GIRBIL_DONGLE_OLD)        += girbil.o
-obj-$(CONFIG_LITELINK_DONGLE_OLD)      += litelink.o
-obj-$(CONFIG_OLD_BELKIN_DONGLE_OLD)    += old_belkin.o
-obj-$(CONFIG_MCP2120_DONGLE_OLD)       += mcp2120.o
-obj-$(CONFIG_ACT200L_DONGLE_OLD)       += act200l.o
-obj-$(CONFIG_MA600_DONGLE_OLD) += ma600.o
-obj-$(CONFIG_EP7211_IR)                += ep7211_ir.o
 obj-$(CONFIG_AU1000_FIR)       += au1k_ir.o
-# New SIR drivers
+# SIR drivers
 obj-$(CONFIG_IRTTY_SIR)                += irtty-sir.o  sir-dev.o
-# New dongles drivers for new SIR drivers
+# dongle drivers for SIR drivers
 obj-$(CONFIG_ESI_DONGLE)       += esi-sir.o
 obj-$(CONFIG_TEKRAM_DONGLE)    += tekram-sir.o
 obj-$(CONFIG_ACTISYS_DONGLE)   += actisys-sir.o
diff --git a/drivers/net/irda/act200l.c b/drivers/net/irda/act200l.c
deleted file mode 100644 (file)
index 756cd44..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-/*********************************************************************
- *
- * Filename:      act200l.c
- * Version:       0.8
- * Description:   Implementation for the ACTiSYS ACT-IR200L dongle
- * Status:        Experimental.
- * Author:        SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
- * Created at:    Fri Aug  3 17:35:42 2001
- * Modified at:   Fri Aug 17 10:22:40 2001
- * Modified by:   SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>
- *
- *     Copyright (c) 2001 SHIMIZU Takuya, All Rights Reserved.
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of
- *     the License, or (at your option) any later version.
- *
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-static int  act200l_reset(struct irda_task *task);
-static void act200l_open(dongle_t *self, struct qos_info *qos);
-static void act200l_close(dongle_t *self);
-static int  act200l_change_speed(struct irda_task *task);
-
-/* Regsiter 0: Control register #1 */
-#define ACT200L_REG0    0x00
-#define ACT200L_TXEN    0x01 /* Enable transmitter */
-#define ACT200L_RXEN    0x02 /* Enable receiver */
-
-/* Register 1: Control register #2 */
-#define ACT200L_REG1    0x10
-#define ACT200L_LODB    0x01 /* Load new baud rate count value */
-#define ACT200L_WIDE    0x04 /* Expand the maximum allowable pulse */
-
-/* Register 4: Output Power register */
-#define ACT200L_REG4    0x40
-#define ACT200L_OP0     0x01 /* Enable LED1C output */
-#define ACT200L_OP1     0x02 /* Enable LED2C output */
-#define ACT200L_BLKR    0x04
-
-/* Register 5: Receive Mode register */
-#define ACT200L_REG5    0x50
-#define ACT200L_RWIDL   0x01 /* fixed 1.6us pulse mode */
-
-/* Register 6: Receive Sensitivity register #1 */
-#define ACT200L_REG6    0x60
-#define ACT200L_RS0     0x01 /* receive threshold bit 0 */
-#define ACT200L_RS1     0x02 /* receive threshold bit 1 */
-
-/* Register 7: Receive Sensitivity register #2 */
-#define ACT200L_REG7    0x70
-#define ACT200L_ENPOS   0x04 /* Ignore the falling edge */
-
-/* Register 8,9: Baud Rate Dvider register #1,#2 */
-#define ACT200L_REG8    0x80
-#define ACT200L_REG9    0x90
-
-#define ACT200L_2400    0x5f
-#define ACT200L_9600    0x17
-#define ACT200L_19200   0x0b
-#define ACT200L_38400   0x05
-#define ACT200L_57600   0x03
-#define ACT200L_115200  0x01
-
-/* Register 13: Control register #3 */
-#define ACT200L_REG13   0xd0
-#define ACT200L_SHDW    0x01 /* Enable access to shadow registers */
-
-/* Register 15: Status register */
-#define ACT200L_REG15   0xf0
-
-/* Register 21: Control register #4 */
-#define ACT200L_REG21   0x50
-#define ACT200L_EXCK    0x02 /* Disable clock output driver */
-#define ACT200L_OSCL    0x04 /* oscillator in low power, medium accuracy mode */
-
-static struct dongle_reg dongle = {
-       .type = IRDA_ACT200L_DONGLE,
-       .open = act200l_open,
-       .close = act200l_close,
-       .reset = act200l_reset,
-       .change_speed = act200l_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init act200l_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit act200l_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void act200l_open(dongle_t *self, struct qos_info *qos)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       /* Power on the dongle */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-       /* Set the speeds we can accept */
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x03;
-}
-
-static void act200l_close(dongle_t *self)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       /* Power off the dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function act200l_change_speed (dev, speed)
- *
- *    Set the speed for the ACTiSYS ACT-IR200L type dongle.
- *
- */
-static int act200l_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       __u8 control[3];
-       int ret = 0;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       self->speed_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               if (irda_task_execute(self, act200l_reset, NULL, task,
-                               (void *) speed))
-               {
-                       /* Dongle need more time to reset */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
-                       /* Give reset 1 sec to finish */
-                       ret = msecs_to_jiffies(1000);
-               }
-               break;
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), resetting dongle timed out!\n",
-                            __FUNCTION__);
-               ret = -1;
-               break;
-       case IRDA_TASK_CHILD_DONE:
-               /* Clear DTR and set RTS to enter command mode */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-
-               switch (speed) {
-               case 9600:
-               default:
-                       control[0] = ACT200L_REG8 |  (ACT200L_9600       & 0x0f);
-                       control[1] = ACT200L_REG9 | ((ACT200L_9600 >> 4) & 0x0f);
-                       break;
-               case 19200:
-                       control[0] = ACT200L_REG8 |  (ACT200L_19200       & 0x0f);
-                       control[1] = ACT200L_REG9 | ((ACT200L_19200 >> 4) & 0x0f);
-                       break;
-               case 38400:
-                       control[0] = ACT200L_REG8 |  (ACT200L_38400       & 0x0f);
-                       control[1] = ACT200L_REG9 | ((ACT200L_38400 >> 4) & 0x0f);
-                       break;
-               case 57600:
-                       control[0] = ACT200L_REG8 |  (ACT200L_57600       & 0x0f);
-                       control[1] = ACT200L_REG9 | ((ACT200L_57600 >> 4) & 0x0f);
-                       break;
-               case 115200:
-                       control[0] = ACT200L_REG8 |  (ACT200L_115200       & 0x0f);
-                       control[1] = ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f);
-                       break;
-               }
-               control[2] = ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE;
-
-               /* Write control bytes */
-               self->write(self->dev, control, 3);
-               irda_task_next_state(task, IRDA_TASK_WAIT);
-               ret = msecs_to_jiffies(5);
-               break;
-       case IRDA_TASK_WAIT:
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-/*
- * Function act200l_reset (driver)
- *
- *    Reset the ACTiSYS ACT-IR200L type dongle.
- */
-static int act200l_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u8 control[9] = {
-               ACT200L_REG15,
-               ACT200L_REG13 | ACT200L_SHDW,
-               ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL,
-               ACT200L_REG13,
-               ACT200L_REG7  | ACT200L_ENPOS,
-               ACT200L_REG6  | ACT200L_RS0  | ACT200L_RS1,
-               ACT200L_REG5  | ACT200L_RWIDL,
-               ACT200L_REG4  | ACT200L_OP0  | ACT200L_OP1 | ACT200L_BLKR,
-               ACT200L_REG0  | ACT200L_TXEN | ACT200L_RXEN
-       };
-       int ret = 0;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       self->reset_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Power on the dongle */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-               ret = msecs_to_jiffies(50);
-               break;
-       case IRDA_TASK_WAIT1:
-               /* Reset the dongle : set RTS low for 25 ms */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-               ret = msecs_to_jiffies(50);
-               break;
-       case IRDA_TASK_WAIT2:
-               /* Clear DTR and set RTS to enter command mode */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-
-               /* Write control bytes */
-               self->write(self->dev, control, 9);
-               irda_task_next_state(task, IRDA_TASK_WAIT3);
-               ret = msecs_to_jiffies(15);
-               break;
-       case IRDA_TASK_WAIT3:
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("SHIMIZU Takuya <tshimizu@ga2.so-net.ne.jp>");
-MODULE_DESCRIPTION("ACTiSYS ACT-IR200L dongle driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-10"); /* IRDA_ACT200L_DONGLE */
-
-/*
- * Function init_module (void)
- *
- *    Initialize ACTiSYS ACT-IR200L module
- *
- */
-module_init(act200l_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup ACTiSYS ACT-IR200L module
- *
- */
-module_exit(act200l_cleanup);
diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c
deleted file mode 100644 (file)
index ae0b80a..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      actisys.c
- * Version:       1.0
- * Description:   Implementation for the ACTiSYS IR-220L and IR-220L+ 
- *                dongles
- * Status:        Beta.
- * Authors:       Dag Brattli <dagb@cs.uit.no> (initially)
- *               Jean Tourrilhes <jt@hpl.hp.com> (new version)
- * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Fri Dec 17 09:10:43 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
- *     Copyright (c) 1999 Jean Tourrilhes
- *      
- *     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.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-/*
- * Changelog
- *
- * 0.8 -> 0.9999 - Jean
- *     o New initialisation procedure : much safer and correct
- *     o New procedure the change speed : much faster and simpler
- *     o Other cleanups & comments
- *     Thanks to Lichen Wang @ Actisys for his excellent help...
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-/* 
- * Define the timing of the pulses we send to the dongle (to reset it, and
- * to toggle speeds). Basically, the limit here is the propagation speed of
- * the signals through the serial port, the dongle being much faster.  Any
- * serial port support 115 kb/s, so we are sure that pulses 8.5 us wide can
- * go through cleanly . If you are on the wild side, you can try to lower
- * this value (Actisys recommended me 2 us, and 0 us work for me on a P233!)
- */
-#define MIN_DELAY 10   /* 10 us to be on the conservative side */
-
-static int  actisys_change_speed(struct irda_task *task);
-static int  actisys_reset(struct irda_task *task);
-static void actisys_open(dongle_t *self, struct qos_info *qos);
-static void actisys_close(dongle_t *self);
-
-/* These are the baudrates supported, in the order available */
-/* Note : the 220L doesn't support 38400, but we will fix that below */
-static __u32 baud_rates[] = { 9600, 19200, 57600, 115200, 38400 };
-#define MAX_SPEEDS 5
-
-static struct dongle_reg dongle = {
-       .type = IRDA_ACTISYS_DONGLE,
-       .open = actisys_open,
-       .close = actisys_close,
-       .reset = actisys_reset,
-       .change_speed = actisys_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static struct dongle_reg dongle_plus = {
-       .type = IRDA_ACTISYS_PLUS_DONGLE,
-       .open = actisys_open,
-       .close = actisys_close,
-       .reset = actisys_reset,
-       .change_speed = actisys_change_speed,
-       .owner = THIS_MODULE,
-};
-
-/*
- * Function actisys_change_speed (task)
- *
- *     There is two model of Actisys dongle we are dealing with,
- * the 220L and 220L+. At this point, only irattach knows with
- * kind the user has requested (it was an argument on irattach
- * command line).
- *     So, we register a dongle of each sort and let irattach
- * pick the right one...
- */
-static int __init actisys_init(void)
-{
-       int ret;
-
-       /* First, register an Actisys 220L dongle */
-       ret = irda_device_register_dongle(&dongle);
-       if (ret < 0)
-               return ret;
-       /* Now, register an Actisys 220L+ dongle */
-       ret = irda_device_register_dongle(&dongle_plus);
-       if (ret < 0) {
-               irda_device_unregister_dongle(&dongle);
-               return ret;
-       }       
-       return 0;
-}
-
-static void __exit actisys_cleanup(void)
-{
-       /* We have to remove both dongles */
-       irda_device_unregister_dongle(&dongle);
-       irda_device_unregister_dongle(&dongle_plus);
-}
-
-static void actisys_open(dongle_t *self, struct qos_info *qos)
-{
-       /* Power on the dongle */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-       /* Set the speeds we can accept */
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-
-       /* Remove support for 38400 if this is not a 220L+ dongle */
-       if (self->issue->type == IRDA_ACTISYS_DONGLE)
-               qos->baud_rate.bits &= ~IR_38400;
-       
-       qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
-}
-
-static void actisys_close(dongle_t *self)
-{
-       /* Power off the dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function actisys_change_speed (task)
- *
- *    Change speed of the ACTiSYS IR-220L and IR-220L+ type IrDA dongles.
- *    To cycle through the available baud rates, pulse RTS low for a few us.
- *
- *     First, we reset the dongle to always start from a known state.
- *     Then, we cycle through the speeds by pulsing RTS low and then up.
- *     The dongle allow us to pulse quite fast, se we can set speed in one go,
- * which is must faster ( < 100 us) and less complex than what is found
- * in some other dongle drivers...
- *     Note that even if the new speed is the same as the current speed,
- * we reassert the speed. This make sure that things are all right,
- * and it's fast anyway...
- *     By the way, this function will work for both type of dongles,
- * because the additional speed is at the end of the sequence...
- */
-static int actisys_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;      /* Target speed */
-       int ret = 0;
-       int i = 0;
-
-        IRDA_DEBUG(4, "%s(), speed=%d (was %d)\n", __FUNCTION__, speed, 
-                  self->speed);
-
-       /* Go to a known state by reseting the dongle */
-
-       /* Reset the dongle : set DTR low for 10 us */
-       self->set_dtr_rts(self->dev, FALSE, TRUE);
-       udelay(MIN_DELAY);
-
-       /* Go back to normal mode (we are now at 9600 b/s) */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-       /* 
-        * Now, we can set the speed requested. Send RTS pulses until we
-         * reach the target speed 
-        */
-       for (i=0; i<MAX_SPEEDS; i++) {
-               if (speed == baud_rates[i]) {
-                       self->speed = baud_rates[i];
-                       break;
-               }
-               /* Make sure previous pulse is finished */
-               udelay(MIN_DELAY);
-
-               /* Set RTS low for 10 us */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-               udelay(MIN_DELAY);
-
-               /* Set RTS high for 10 us */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-       }
-
-       /* Check if life is sweet... */
-       if (i >= MAX_SPEEDS)
-               ret = -1;  /* This should not happen */
-
-       /* Basta lavoro, on se casse d'ici... */
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return ret;
-}
-
-/*
- * Function actisys_reset (task)
- *
- *      Reset the Actisys type dongle. Warning, this function must only be
- *      called with a process context!
- *
- * We need to do two things in this function :
- *     o first make sure that the dongle is in a state where it can operate
- *     o second put the dongle in a know state
- *
- *     The dongle is powered of the RTS and DTR lines. In the dongle, there
- * is a big capacitor to accommodate the current spikes. This capacitor
- * takes a least 50 ms to be charged. In theory, the Bios set those lines
- * up, so by the time we arrive here we should be set. It doesn't hurt
- * to be on the conservative side, so we will wait...
- *     Then, we set the speed to 9600 b/s to get in a known state (see in
- * change_speed for details). It is needed because the IrDA stack
- * has tried to set the speed immediately after our first return,
- * so before we can be sure the dongle is up and running.
- */
-static int actisys_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       int ret = 0;
-
-       IRDA_ASSERT(task != NULL, return -1;);
-
-       self->reset_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Set both DTR & RTS to power up the dongle */
-               /* In theory redundant with power up in actisys_open() */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               
-               /* Sleep 50 ms to make sure capacitor is charged */
-               ret = msecs_to_jiffies(50);
-               irda_task_next_state(task, IRDA_TASK_WAIT);
-               break;
-       case IRDA_TASK_WAIT:                    
-               /* Reset the dongle : set DTR low for 10 us */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-               udelay(MIN_DELAY);
-
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-       
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               self->speed = 9600;     /* That's the default */
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no> - Jean Tourrilhes <jt@hpl.hp.com>");
-MODULE_DESCRIPTION("ACTiSYS IR-220L and IR-220L+ dongle driver");      
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-2"); /* IRDA_ACTISYS_DONGLE */
-MODULE_ALIAS("irda-dongle-3"); /* IRDA_ACTISYS_PLUS_DONGLE */
-
-               
-/*
- * Function init_module (void)
- *
- *    Initialize Actisys module
- *
- */
-module_init(actisys_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup Actisys module
- *
- */
-module_exit(actisys_cleanup);
diff --git a/drivers/net/irda/ep7211_ir.c b/drivers/net/irda/ep7211_ir.c
deleted file mode 100644 (file)
index 4cba38f..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * IR port driver for the Cirrus Logic EP7211 processor.
- *
- * Copyright 2001, Blue Mug Inc.  All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#define MIN_DELAY 25      /* 15 us, but wait a little more to be sure */
-#define MAX_DELAY 10000   /* 1 ms */
-
-static void ep7211_ir_open(dongle_t *self, struct qos_info *qos);
-static void ep7211_ir_close(dongle_t *self);
-static int  ep7211_ir_change_speed(struct irda_task *task);
-static int  ep7211_ir_reset(struct irda_task *task);
-
-static DEFINE_SPINLOCK(ep7211_lock);
-
-static struct dongle_reg dongle = {
-       .type = IRDA_EP7211_IR,
-       .open = ep7211_ir_open,
-       .close = ep7211_ir_close,
-       .reset = ep7211_ir_reset,
-       .change_speed = ep7211_ir_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
-{
-       unsigned int syscon1, flags;
-
-       spin_lock_irqsave(&ep7211_lock, flags);
-
-       /* Turn on the SIR encoder. */
-       syscon1 = clps_readl(SYSCON1);
-       syscon1 |= SYSCON1_SIREN;
-       clps_writel(syscon1, SYSCON1);
-
-       /* XXX: We should disable modem status interrupts on the first
-               UART (interrupt #14). */
-
-       spin_unlock_irqrestore(&ep7211_lock, flags);
-}
-
-static void ep7211_ir_close(dongle_t *self)
-{
-       unsigned int syscon1, flags;
-
-       spin_lock_irqsave(&ep7211_lock, flags);
-
-       /* Turn off the SIR encoder. */
-       syscon1 = clps_readl(SYSCON1);
-       syscon1 &= ~SYSCON1_SIREN;
-       clps_writel(syscon1, SYSCON1);
-
-       /* XXX: If we've disabled the modem status interrupts, we should
-               reset them back to their original state. */
-
-       spin_unlock_irqrestore(&ep7211_lock, flags);
-}
-
-/*
- * Function ep7211_ir_change_speed (task)
- *
- *    Change speed of the EP7211 I/R port. We don't really have to do anything
- *    for the EP7211 as long as the rate is being changed at the serial port
- *    level.
- */
-static int ep7211_ir_change_speed(struct irda_task *task)
-{
-       irda_task_next_state(task, IRDA_TASK_DONE);
-       return 0;
-}
-
-/*
- * Function ep7211_ir_reset (task)
- *
- *      Reset the EP7211 I/R. We don't really have to do anything.
- *
- */
-static int ep7211_ir_reset(struct irda_task *task)
-{
-       irda_task_next_state(task, IRDA_TASK_DONE);
-       return 0;
-}
-
-/*
- * Function ep7211_ir_init(void)
- *
- *    Initialize EP7211 I/R module
- *
- */
-static int __init ep7211_ir_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-/*
- * Function ep7211_ir_cleanup(void)
- *
- *    Cleanup EP7211 I/R module
- *
- */
-static void __exit ep7211_ir_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-MODULE_AUTHOR("Jon McClintock <jonm@bluemug.com>");
-MODULE_DESCRIPTION("EP7211 I/R driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-8"); /* IRDA_EP7211_IR */
-               
-module_init(ep7211_ir_init);
-module_exit(ep7211_ir_cleanup);
diff --git a/drivers/net/irda/esi.c b/drivers/net/irda/esi.c
deleted file mode 100644 (file)
index d3a61af..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      esi.c
- * Version:       1.5
- * Description:   Driver for the Extended Systems JetEye PC dongle
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Feb 21 18:54:38 1998
- * Modified at:   Fri Dec 17 09:14:04 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1999 Dag Brattli, <dagb@cs.uit.no>,
- *     Copyright (c) 1998 Thomas Davis, <ratbert@radiks.net>,
- *     All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-static void esi_open(dongle_t *self, struct qos_info *qos);
-static void esi_close(dongle_t *self);
-static int  esi_change_speed(struct irda_task *task);
-static int  esi_reset(struct irda_task *task);
-
-static struct dongle_reg dongle = {
-       .type = IRDA_ESI_DONGLE,
-       .open = esi_open,
-       .close = esi_close,
-       .reset = esi_reset,
-       .change_speed = esi_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init esi_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit esi_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void esi_open(dongle_t *self, struct qos_info *qos)
-{
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_115200;
-       qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
-}
-
-static void esi_close(dongle_t *dongle)
-{              
-       /* Power off dongle */
-       dongle->set_dtr_rts(dongle->dev, FALSE, FALSE);
-}
-
-/*
- * Function esi_change_speed (task)
- *
- *    Set the speed for the Extended Systems JetEye PC ESI-9680 type dongle
- *
- */
-static int esi_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       int dtr, rts;
-       
-       switch (speed) {
-       case 19200:
-               dtr = TRUE;
-               rts = FALSE;
-               break;
-       case 115200:
-               dtr = rts = TRUE;
-               break;
-       case 9600:
-       default:
-               dtr = FALSE;
-               rts = TRUE;
-               break;
-       }
-
-       /* Change speed of dongle */
-       self->set_dtr_rts(self->dev, dtr, rts);
-       self->speed = speed;
-
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-/*
- * Function esi_reset (task)
- *
- *    Reset dongle;
- *
- */
-static int esi_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("Extended Systems JetEye PC dongle driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-1"); /* IRDA_ESI_DONGLE */
-
-/*
- * Function init_module (void)
- *
- *    Initialize ESI module
- *
- */
-module_init(esi_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup ESI module
- *
- */
-module_exit(esi_cleanup);
-
diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c
deleted file mode 100644 (file)
index 1f57391..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      girbil.c
- * Version:       1.2
- * Description:   Implementation for the Greenwich GIrBIL dongle
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Feb  6 21:02:33 1999
- * Modified at:   Fri Dec 17 09:13:20 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-static int  girbil_reset(struct irda_task *task);
-static void girbil_open(dongle_t *self, struct qos_info *qos);
-static void girbil_close(dongle_t *self);
-static int  girbil_change_speed(struct irda_task *task);
-
-/* Control register 1 */
-#define GIRBIL_TXEN    0x01 /* Enable transmitter */
-#define GIRBIL_RXEN    0x02 /* Enable receiver */
-#define GIRBIL_ECAN    0x04 /* Cancel self emmited data */
-#define GIRBIL_ECHO    0x08 /* Echo control characters */
-
-/* LED Current Register (0x2) */
-#define GIRBIL_HIGH    0x20
-#define GIRBIL_MEDIUM  0x21
-#define GIRBIL_LOW     0x22
-
-/* Baud register (0x3) */
-#define GIRBIL_2400    0x30
-#define GIRBIL_4800    0x31    
-#define GIRBIL_9600    0x32
-#define GIRBIL_19200   0x33
-#define GIRBIL_38400   0x34    
-#define GIRBIL_57600   0x35    
-#define GIRBIL_115200  0x36
-
-/* Mode register (0x4) */
-#define GIRBIL_IRDA    0x40
-#define GIRBIL_ASK     0x41
-
-/* Control register 2 (0x5) */
-#define GIRBIL_LOAD    0x51 /* Load the new baud rate value */
-
-static struct dongle_reg dongle = {
-       .type = IRDA_GIRBIL_DONGLE,
-       .open = girbil_open,
-       .close = girbil_close,
-       .reset = girbil_reset,
-       .change_speed = girbil_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init girbil_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit girbil_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void girbil_open(dongle_t *self, struct qos_info *qos)
-{
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x03;
-}
-
-static void girbil_close(dongle_t *self)
-{
-       /* Power off dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function girbil_change_speed (dev, speed)
- *
- *    Set the speed for the Girbil type dongle.
- *
- */
-static int girbil_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       __u8 control[2];
-       int ret = 0;
-
-       self->speed_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Need to reset the dongle and go to 9600 bps before
-                   programming */
-               if (irda_task_execute(self, girbil_reset, NULL, task, 
-                                     (void *) speed))
-               {
-                       /* Dongle need more time to reset */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
-                       /* Give reset 1 sec to finish */
-                       ret = msecs_to_jiffies(1000);
-               }
-               break;
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), resetting dongle timed out!\n",
-                            __FUNCTION__);
-               ret = -1;
-               break;
-       case IRDA_TASK_CHILD_DONE:
-               /* Set DTR and Clear RTS to enter command mode */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-
-               switch (speed) {
-               case 9600:
-               default:
-                       control[0] = GIRBIL_9600;
-                       break;
-               case 19200:
-                       control[0] = GIRBIL_19200;
-                       break;
-               case 34800:
-                       control[0] = GIRBIL_38400;
-                       break;
-               case 57600:
-                       control[0] = GIRBIL_57600;
-                       break;
-               case 115200:
-                       control[0] = GIRBIL_115200;
-                       break;
-               }
-               control[1] = GIRBIL_LOAD;
-               
-               /* Write control bytes */
-               self->write(self->dev, control, 2);
-               irda_task_next_state(task, IRDA_TASK_WAIT);
-               ret = msecs_to_jiffies(100);
-               break;
-       case IRDA_TASK_WAIT:
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-/*
- * Function girbil_reset (driver)
- *
- *      This function resets the girbil dongle.
- *
- *      Algorithm:
- *       0. set RTS, and wait at least 5 ms 
- *        1. clear RTS 
- */
-static int girbil_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
-       int ret = 0;
-
-       self->reset_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Reset dongle */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-               /* Sleep at least 5 ms */
-               ret = msecs_to_jiffies(20);
-               break;
-       case IRDA_TASK_WAIT1:
-               /* Set DTR and clear RTS to enter command mode */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-               ret = msecs_to_jiffies(20);
-               break;
-       case IRDA_TASK_WAIT2:
-               /* Write control byte */
-               self->write(self->dev, &control, 1);
-               irda_task_next_state(task, IRDA_TASK_WAIT3);
-               ret = msecs_to_jiffies(20);
-               break;
-       case IRDA_TASK_WAIT3:
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-4"); /* IRDA_GIRBIL_DONGLE */
-       
-/*
- * Function init_module (void)
- *
- *    Initialize Girbil module
- *
- */
-module_init(girbil_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup Girbil module
- *
- */
-module_exit(girbil_cleanup);
-
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
deleted file mode 100644 (file)
index c79caa5..0000000
+++ /dev/null
@@ -1,1123 +0,0 @@
-/*********************************************************************
- * 
- * Filename:     irport.c
- * Version:      1.0
- * Description:   Half duplex serial port SIR driver for IrDA. 
- * Status:       Experimental.
- * Author:       Dag Brattli <dagb@cs.uit.no>
- * Created at:   Sun Aug  3 13:49:59 1997
- * Modified at:   Fri Jan 28 20:22:38 2000
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * Sources:      serial.c by Linus Torvalds 
- * 
- *     Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved.
- *     Copyright (c) 2000-2003 Jean Tourrilhes, All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
- *
- *     This driver is ment to be a small half duplex serial driver to be
- *     used for IR-chipsets that has a UART (16550) compatibility mode. 
- *     Eventually it will replace irtty, because of irtty has some 
- *     problems that is hard to get around when we don't have control
- *     over the serial driver. This driver may also be used by FIR 
- *     drivers to handle SIR mode for them.
- *
- ********************************************************************/
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/skbuff.h>
-#include <linux/serial_reg.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/wrapper.h>
-#include "irport.h"
-
-#define IO_EXTENT 8
-
-/* 
- * Currently you'll need to set these values using insmod like this:
- * insmod irport io=0x3e8 irq=11
- */
-static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
-static unsigned int irq[] = { 0, 0, 0, 0 };
-
-static unsigned int qos_mtt_bits = 0x03;
-
-static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
-static char *driver_name = "irport";
-
-static inline void irport_write_wakeup(struct irport_cb *self);
-static inline int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
-static inline void irport_receive(struct irport_cb *self);
-
-static int  irport_net_ioctl(struct net_device *dev, struct ifreq *rq, 
-                            int cmd);
-static inline int  irport_is_receiving(struct irport_cb *self);
-static int  irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
-static int  irport_raw_write(struct net_device *dev, __u8 *buf, int len);
-static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
-static int irport_change_speed_complete(struct irda_task *task);
-static void irport_timeout(struct net_device *dev);
-
-static irqreturn_t irport_interrupt(int irq, void *dev_id);
-static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev);
-static void irport_change_speed(void *priv, __u32 speed);
-static int irport_net_open(struct net_device *dev);
-static int irport_net_close(struct net_device *dev);
-
-static struct irport_cb *
-irport_open(int i, unsigned int iobase, unsigned int irq)
-{
-       struct net_device *dev;
-       struct irport_cb *self;
-
-       IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
-
-       /* Lock the port that we need */
-       if (!request_region(iobase, IO_EXTENT, driver_name)) {
-               IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
-                          __FUNCTION__, iobase);
-               goto err_out1;
-       }
-
-       /*
-        *  Allocate new instance of the driver
-        */
-       dev = alloc_irdadev(sizeof(struct irport_cb));
-       if (!dev) {
-               IRDA_ERROR("%s(), can't allocate memory for "
-                          "irda device!\n", __FUNCTION__);
-               goto err_out2;
-       }
-
-       self = dev->priv;
-       spin_lock_init(&self->lock);
-
-       /* Need to store self somewhere */
-       dev_self[i] = self;
-       self->priv = self;
-       self->index = i;
-
-       /* Initialize IO */
-       self->io.sir_base  = iobase;
-        self->io.sir_ext   = IO_EXTENT;
-        self->io.irq       = irq;
-        self->io.fifo_size = 16;               /* 16550A and compatible */
-
-       /* Initialize QoS for this device */
-       irda_init_max_qos_capabilies(&self->qos);
-       
-       self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-               IR_115200;
-
-       self->qos.min_turn_time.bits = qos_mtt_bits;
-       irda_qos_bits_to_value(&self->qos);
-       
-       /* Bootstrap ZeroCopy Rx */
-       self->rx_buff.truesize = IRDA_SKB_MAX_MTU;
-       self->rx_buff.skb = __dev_alloc_skb(self->rx_buff.truesize,
-                                           GFP_KERNEL);
-       if (self->rx_buff.skb == NULL) {
-               IRDA_ERROR("%s(), can't allocate memory for "
-                          "receive buffer!\n", __FUNCTION__);
-               goto err_out3;
-       }
-       skb_reserve(self->rx_buff.skb, 1);
-       self->rx_buff.head = self->rx_buff.skb->data;
-       /* No need to memset the buffer, unless you are really pedantic */
-
-       /* Finish setup the Rx buffer descriptor */
-       self->rx_buff.in_frame = FALSE;
-       self->rx_buff.state = OUTSIDE_FRAME;
-       self->rx_buff.data = self->rx_buff.head;
-
-       /* Specify how much memory we want */
-       self->tx_buff.truesize = 4000;
-       
-       /* Allocate memory if needed */
-       if (self->tx_buff.truesize > 0) {
-               self->tx_buff.head = kzalloc(self->tx_buff.truesize,
-                                                     GFP_KERNEL);
-               if (self->tx_buff.head == NULL) {
-                       IRDA_ERROR("%s(), can't allocate memory for "
-                                  "transmit buffer!\n", __FUNCTION__);
-                       goto err_out4;
-               }
-       }       
-       self->tx_buff.data = self->tx_buff.head;
-
-       self->netdev = dev;
-
-       /* May be overridden by piggyback drivers */
-       self->interrupt    = irport_interrupt;
-       self->change_speed = irport_change_speed;
-
-       /* Override the network functions we need to use */
-       dev->hard_start_xmit = irport_hard_xmit;
-       dev->tx_timeout      = irport_timeout;
-       dev->watchdog_timeo  = HZ;  /* Allow time enough for speed change */
-       dev->open            = irport_net_open;
-       dev->stop            = irport_net_close;
-       dev->get_stats       = irport_net_get_stats;
-       dev->do_ioctl        = irport_net_ioctl;
-
-       /* Make ifconfig display some details */
-       dev->base_addr = iobase;
-       dev->irq = irq;
-
-       if (register_netdev(dev)) {
-               IRDA_ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
-               goto err_out5;
-       }
-       IRDA_MESSAGE("IrDA: Registered device %s (irport io=0x%X irq=%d)\n",
-               dev->name, iobase, irq);
-
-       return self;
- err_out5:
-       kfree(self->tx_buff.head);
- err_out4:
-       kfree_skb(self->rx_buff.skb);
- err_out3:
-       free_netdev(dev);
-       dev_self[i] = NULL;
- err_out2:
-       release_region(iobase, IO_EXTENT);
- err_out1:
-       return NULL;
-}
-
-static int irport_close(struct irport_cb *self)
-{
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       /* We are not using any dongle anymore! */
-       if (self->dongle)
-               irda_device_dongle_cleanup(self->dongle);
-       self->dongle = NULL;
-       
-       /* Remove netdevice */
-       unregister_netdev(self->netdev);
-
-       /* Release the IO-port that this driver is using */
-       IRDA_DEBUG(0 , "%s(), Releasing Region %03x\n", 
-                  __FUNCTION__, self->io.sir_base);
-       release_region(self->io.sir_base, self->io.sir_ext);
-
-       kfree(self->tx_buff.head);
-       
-       if (self->rx_buff.skb)
-               kfree_skb(self->rx_buff.skb);
-       self->rx_buff.skb = NULL;
-       
-       /* Remove ourselves */
-       dev_self[self->index] = NULL;
-       free_netdev(self->netdev);
-       
-       return 0;
-}
-
-static void irport_stop(struct irport_cb *self)
-{
-       int iobase;
-
-       iobase = self->io.sir_base;
-
-       /* We can't lock, we may be called from a FIR driver - Jean II */
-
-       /* We are not transmitting any more */
-       self->transmitting = 0;
-
-       /* Reset UART */
-       outb(0, iobase+UART_MCR);
-       
-       /* Turn off interrupts */
-       outb(0, iobase+UART_IER);
-}
-
-static void irport_start(struct irport_cb *self)
-{
-       int iobase;
-
-       iobase = self->io.sir_base;
-
-       irport_stop(self);
-       
-       /* We can't lock, we may be called from a FIR driver - Jean II */
-
-       /* Initialize UART */
-       outb(UART_LCR_WLEN8, iobase+UART_LCR);  /* Reset DLAB */
-       outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
-       
-       /* Turn on interrups */
-       outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
-}
-
-/*
- * Function irport_get_fcr (speed)
- *
- *    Compute value of fcr
- *
- */
-static inline unsigned int irport_get_fcr(__u32 speed)
-{
-       unsigned int fcr;    /* FIFO control reg */
-
-       /* Enable fifos */
-       fcr = UART_FCR_ENABLE_FIFO;
-
-       /* 
-        * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-        * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-        * about this timeout since it will always be fast enough. 
-        */
-       if (speed < 38400)
-               fcr |= UART_FCR_TRIGGER_1;
-       else 
-               //fcr |= UART_FCR_TRIGGER_14;
-               fcr |= UART_FCR_TRIGGER_8;
-
-       return(fcr);
-}
-/*
- * Function irport_change_speed (self, speed)
- *
- *    Set speed of IrDA port to specified baudrate
- *
- * This function should be called with irq off and spin-lock.
- */
-static void irport_change_speed(void *priv, __u32 speed)
-{
-       struct irport_cb *self = (struct irport_cb *) priv;
-       int iobase; 
-       unsigned int fcr;    /* FIFO control reg */
-       unsigned int lcr;    /* Line control reg */
-       int divisor;
-
-       IRDA_ASSERT(self != NULL, return;);
-       IRDA_ASSERT(speed != 0, return;);
-
-       IRDA_DEBUG(1, "%s(), Setting speed to: %d - iobase=%#x\n",
-                   __FUNCTION__, speed, self->io.sir_base);
-
-       /* We can't lock, we may be called from a FIR driver - Jean II */
-
-       iobase = self->io.sir_base;
-       
-       /* Update accounting for new speed */
-       self->io.speed = speed;
-
-       /* Turn off interrupts */
-       outb(0, iobase+UART_IER); 
-
-       divisor = SPEED_MAX/speed;
-       
-       /* Get proper fifo configuration */
-       fcr = irport_get_fcr(speed);
-
-       /* IrDA ports use 8N1 */
-       lcr = UART_LCR_WLEN8;
-       
-       outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
-       outb(divisor & 0xff,      iobase+UART_DLL); /* Set speed */
-       outb(divisor >> 8,        iobase+UART_DLM);
-       outb(lcr,                 iobase+UART_LCR); /* Set 8N1  */
-       outb(fcr,                 iobase+UART_FCR); /* Enable FIFO's */
-
-       /* Turn on interrups */
-       /* This will generate a fatal interrupt storm.
-        * People calling us will do that properly - Jean II */
-       //outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
-}
-
-/*
- * Function __irport_change_speed (instance, state, param)
- *
- *    State machine for changing speed of the device. We do it this way since
- *    we cannot use schedule_timeout() when we are in interrupt context
- *
- */
-static int __irport_change_speed(struct irda_task *task)
-{
-       struct irport_cb *self;
-       __u32 speed = (__u32) task->param;
-       unsigned long flags = 0;
-       int wasunlocked = 0;
-       int ret = 0;
-
-       IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies); 
-
-       self = (struct irport_cb *) task->instance;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       /* Locking notes : this function may be called from irq context with
-        * spinlock, via irport_write_wakeup(), or from non-interrupt without
-        * spinlock (from the task timer). Yuck !
-        * This is ugly, and unsafe is the spinlock is not already acquired.
-        * This will be fixed when irda-task get rewritten.
-        * Jean II */
-       if (!spin_is_locked(&self->lock)) {
-               spin_lock_irqsave(&self->lock, flags);
-               wasunlocked = 1;
-       }
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-       case IRDA_TASK_WAIT:
-               /* Are we ready to change speed yet? */
-               if (self->tx_buff.len > 0) {
-                       task->state = IRDA_TASK_WAIT;
-
-                       /* Try again later */
-                       ret = msecs_to_jiffies(20);
-                       break;
-               }
-
-               if (self->dongle)
-                       irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
-               else
-                       irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
-               break;
-       case IRDA_TASK_CHILD_INIT:
-               /* Go to default speed */
-               self->change_speed(self->priv, 9600);
-
-               /* Change speed of dongle */
-               if (irda_task_execute(self->dongle,
-                                     self->dongle->issue->change_speed, 
-                                     NULL, task, (void *) speed))
-               {
-                       /* Dongle need more time to change its speed */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
-                       /* Give dongle 1 sec to finish */
-                       ret = msecs_to_jiffies(1000);
-               } else
-                       /* Child finished immediately */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
-               break;
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), changing speed of dongle timed out!\n", __FUNCTION__);
-               ret = -1;               
-               break;
-       case IRDA_TASK_CHILD_DONE:
-               /* Finally we are ready to change the speed */
-               self->change_speed(self->priv, speed);
-               
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               ret = -1;
-               break;
-       }
-       /* Put stuff in the state we found them - Jean II */
-       if(wasunlocked) {
-               spin_unlock_irqrestore(&self->lock, flags);
-       }
-
-       return ret;
-}
-
-/*
- * Function irport_change_speed_complete (task)
- *
- *    Called when the change speed operation completes
- *
- */
-static int irport_change_speed_complete(struct irda_task *task)
-{
-       struct irport_cb *self;
-
-       IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
-
-       self = (struct irport_cb *) task->instance;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-       IRDA_ASSERT(self->netdev != NULL, return -1;);
-
-       /* Finished changing speed, so we are not busy any longer */
-       /* Signal network layer so it can try to send the frame */
-
-       netif_wake_queue(self->netdev);
-       
-       return 0;
-}
-
-/*
- * Function irport_timeout (struct net_device *dev)
- *
- *    The networking layer thinks we timed out.
- *
- */
-
-static void irport_timeout(struct net_device *dev)
-{
-       struct irport_cb *self;
-       int iobase;
-       int iir, lsr;
-       unsigned long flags;
-
-       self = (struct irport_cb *) dev->priv;
-       IRDA_ASSERT(self != NULL, return;);
-       iobase = self->io.sir_base;
-       
-       IRDA_WARNING("%s: transmit timed out, jiffies = %ld, trans_start = %ld\n",
-               dev->name, jiffies, dev->trans_start);
-       spin_lock_irqsave(&self->lock, flags);
-
-       /* Debug what's happening... */
-
-       /* Get interrupt status */
-       lsr = inb(iobase+UART_LSR);
-       /* Read interrupt register */
-       iir = inb(iobase+UART_IIR);
-       IRDA_DEBUG(0, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", 
-                  __FUNCTION__, iir, lsr, iobase);
-
-       IRDA_DEBUG(0, "%s(), transmitting=%d, remain=%d, done=%td\n",
-                  __FUNCTION__, self->transmitting, self->tx_buff.len,
-                  self->tx_buff.data - self->tx_buff.head);
-
-       /* Now, restart the port */
-       irport_start(self);
-       self->change_speed(self->priv, self->io.speed);
-       /* This will re-enable irqs */
-       outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
-       dev->trans_start = jiffies;
-       spin_unlock_irqrestore(&self->lock, flags);
-
-       netif_wake_queue(dev);
-}
-/*
- * Function irport_wait_hw_transmitter_finish ()
- *
- *    Wait for the real end of HW transmission
- *
- * The UART is a strict FIFO, and we get called only when we have finished
- * pushing data to the FIFO, so the maximum amount of time we must wait
- * is only for the FIFO to drain out.
- *
- * We use a simple calibrated loop. We may need to adjust the loop
- * delay (udelay) to balance I/O traffic and latency. And we also need to
- * adjust the maximum timeout.
- * It would probably be better to wait for the proper interrupt,
- * but it doesn't seem to be available.
- *
- * We can't use jiffies or kernel timers because :
- * 1) We are called from the interrupt handler, which disable softirqs,
- * so jiffies won't be increased
- * 2) Jiffies granularity is usually very coarse (10ms), and we don't
- * want to wait that long to detect stuck hardware.
- * Jean II
- */
-
-static void irport_wait_hw_transmitter_finish(struct irport_cb *self)
-{
-       int iobase;
-       int count = 1000;       /* 1 ms */
-       
-       iobase = self->io.sir_base;
-
-       /* Calibrated busy loop */
-       while((count-- > 0) && !(inb(iobase+UART_LSR) & UART_LSR_TEMT))
-               udelay(1);
-
-       if(count == 0)
-               IRDA_DEBUG(0, "%s(): stuck transmitter\n", __FUNCTION__);
-}
-
-/*
- * Function irport_hard_start_xmit (struct sk_buff *skb, struct net_device *dev)
- *
- *    Transmits the current frame until FIFO is full, then
- *    waits until the next transmitt interrupt, and continues until the
- *    frame is transmitted.
- */
-static int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct irport_cb *self;
-       unsigned long flags;
-       int iobase;
-       s32 speed;
-
-       IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
-
-       IRDA_ASSERT(dev != NULL, return 0;);
-       
-       self = (struct irport_cb *) dev->priv;
-       IRDA_ASSERT(self != NULL, return 0;);
-
-       iobase = self->io.sir_base;
-
-       netif_stop_queue(dev);
-
-       /* Make sure tests & speed change are atomic */
-       spin_lock_irqsave(&self->lock, flags);
-
-       /* Check if we need to change the speed */
-       speed = irda_get_next_speed(skb);
-       if ((speed != self->io.speed) && (speed != -1)) {
-               /* Check for empty frame */
-               if (!skb->len) {
-                       /*
-                        * We send frames one by one in SIR mode (no
-                        * pipelining), so at this point, if we were sending
-                        * a previous frame, we just received the interrupt
-                        * telling us it is finished (UART_IIR_THRI).
-                        * Therefore, waiting for the transmitter to really
-                        * finish draining the fifo won't take too long.
-                        * And the interrupt handler is not expected to run.
-                        * - Jean II */
-                       irport_wait_hw_transmitter_finish(self);
-                       /* Better go there already locked - Jean II */
-                       irda_task_execute(self, __irport_change_speed, 
-                                         irport_change_speed_complete, 
-                                         NULL, (void *) speed);
-                       dev->trans_start = jiffies;
-                       spin_unlock_irqrestore(&self->lock, flags);
-                       dev_kfree_skb(skb);
-                       return 0;
-               } else
-                       self->new_speed = speed;
-       }
-
-       /* Init tx buffer */
-       self->tx_buff.data = self->tx_buff.head;
-
-        /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
-       self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
-                                          self->tx_buff.truesize);
-       
-       self->stats.tx_bytes += self->tx_buff.len;
-
-       /* We are transmitting */
-       self->transmitting = 1;
-
-       /* Turn on transmit finished interrupt. Will fire immediately!  */
-       outb(UART_IER_THRI, iobase+UART_IER); 
-
-       dev->trans_start = jiffies;
-       spin_unlock_irqrestore(&self->lock, flags);
-
-       dev_kfree_skb(skb);
-       
-       return 0;
-}
-        
-/*
- * Function irport_write (driver)
- *
- *    Fill Tx FIFO with transmit data
- *
- * Called only from irport_write_wakeup()
- */
-static inline int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
-{
-       int actual = 0;
-
-       /* Fill FIFO with current frame */
-       while ((actual < fifo_size) && (actual < len)) {
-               /* Transmit next byte */
-               outb(buf[actual], iobase+UART_TX);
-
-               actual++;
-       }
-        
-       return actual;
-}
-
-/*
- * Function irport_write_wakeup (tty)
- *
- *    Called by the driver when there's room for more data.  If we have
- *    more packets to send, we send them here.
- *
- * Called only from irport_interrupt()
- * Make sure this function is *not* called while we are receiving,
- * otherwise we will reset fifo and loose data :-(
- */
-static inline void irport_write_wakeup(struct irport_cb *self)
-{
-       int actual = 0;
-       int iobase;
-       unsigned int fcr;
-
-       IRDA_ASSERT(self != NULL, return;);
-
-       IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
-
-       iobase = self->io.sir_base;
-
-       /* Finished with frame?  */
-       if (self->tx_buff.len > 0)  {
-               /* Write data left in transmit buffer */
-               actual = irport_write(iobase, self->io.fifo_size, 
-                                     self->tx_buff.data, self->tx_buff.len);
-               self->tx_buff.data += actual;
-               self->tx_buff.len  -= actual;
-       } else {
-               /* 
-                *  Now serial buffer is almost free & we can start 
-                *  transmission of another packet. But first we must check
-                *  if we need to change the speed of the hardware
-                */
-               if (self->new_speed) {
-                       irport_wait_hw_transmitter_finish(self);
-                       irda_task_execute(self, __irport_change_speed, 
-                                         irport_change_speed_complete, 
-                                         NULL, (void *) self->new_speed);
-                       self->new_speed = 0;
-               } else {
-                       /* Tell network layer that we want more frames */
-                       netif_wake_queue(self->netdev);
-               }
-               self->stats.tx_packets++;
-
-               /* 
-                * Reset Rx FIFO to make sure that all reflected transmit data
-                * is discarded. This is needed for half duplex operation
-                */
-               fcr = irport_get_fcr(self->io.speed);
-               fcr |= UART_FCR_CLEAR_RCVR;
-               outb(fcr, iobase+UART_FCR);
-
-               /* Finished transmitting */
-               self->transmitting = 0;
-
-               /* Turn on receive interrupts */
-               outb(UART_IER_RDI, iobase+UART_IER);
-
-               IRDA_DEBUG(1, "%s() : finished Tx\n", __FUNCTION__);
-       }
-}
-
-/*
- * Function irport_receive (self)
- *
- *    Receive one frame from the infrared port
- *
- * Called only from irport_interrupt()
- */
-static inline void irport_receive(struct irport_cb *self) 
-{
-       int boguscount = 0;
-       int iobase;
-
-       IRDA_ASSERT(self != NULL, return;);
-
-       iobase = self->io.sir_base;
-
-       /*  
-        * Receive all characters in Rx FIFO, unwrap and unstuff them. 
-         * async_unwrap_char will deliver all found frames  
-        */
-       do {
-               async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
-                                 inb(iobase+UART_RX));
-
-               /* Make sure we don't stay here too long */
-               if (boguscount++ > 32) {
-                       IRDA_DEBUG(2,"%s(), breaking!\n", __FUNCTION__);
-                       break;
-               }
-       } while (inb(iobase+UART_LSR) & UART_LSR_DR);   
-}
-
-/*
- * Function irport_interrupt (irq, dev_id)
- *
- *    Interrupt handler
- */
-static irqreturn_t irport_interrupt(int irq, void *dev_id) 
-{
-       struct net_device *dev = dev_id;
-       struct irport_cb *self;
-       int boguscount = 0;
-       int iobase;
-       int iir, lsr;
-       int handled = 0;
-
-       self = dev->priv;
-
-       spin_lock(&self->lock);
-
-       iobase = self->io.sir_base;
-
-       /* Cut'n'paste interrupt routine from serial.c
-        * This version try to minimise latency and I/O operations.
-        * Simplified and modified to enforce half duplex operation.
-        * - Jean II */
-
-       /* Check status even is iir reg is cleared, more robust and
-        * eliminate a read on the I/O bus - Jean II */
-       do {
-               /* Get interrupt status ; Clear interrupt */
-               lsr = inb(iobase+UART_LSR);
-               
-               /* Are we receiving or transmitting ? */
-               if(!self->transmitting) {
-                       /* Received something ? */
-                       if (lsr & UART_LSR_DR)
-                               irport_receive(self);
-               } else {
-                       /* Room in Tx fifo ? */
-                       if (lsr & (UART_LSR_THRE | UART_LSR_TEMT))
-                               irport_write_wakeup(self);
-               }
-
-               /* A bit hackish, but working as expected... Jean II */
-               if(lsr & (UART_LSR_THRE | UART_LSR_TEMT | UART_LSR_DR))
-                       handled = 1;
-
-               /* Make sure we don't stay here to long */
-               if (boguscount++ > 10) {
-                       IRDA_WARNING("%s() irq handler looping : lsr=%02x\n",
-                                    __FUNCTION__, lsr);
-                       break;
-               }
-
-               /* Read interrupt register */
-               iir = inb(iobase+UART_IIR);
-
-               /* Enable this debug only when no other options and at low
-                * bit rates, otherwise it may cause Rx overruns (lsr=63).
-                * - Jean II */
-               IRDA_DEBUG(6, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", 
-                           __FUNCTION__, iir, lsr, iobase);
-
-               /* As long as interrupt pending... */
-       } while ((iir & UART_IIR_NO_INT) == 0);
-
-       spin_unlock(&self->lock);
-       return IRQ_RETVAL(handled);
-}
-
-/*
- * Function irport_net_open (dev)
- *
- *    Network device is taken up. Usually this is done by "ifconfig irda0 up" 
- *   
- */
-static int irport_net_open(struct net_device *dev)
-{
-       struct irport_cb *self;
-       int iobase;
-       char hwname[16];
-       unsigned long flags;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct irport_cb *) dev->priv;
-
-       iobase = self->io.sir_base;
-
-       if (request_irq(self->io.irq, self->interrupt, 0, dev->name, 
-                       (void *) dev)) {
-               IRDA_DEBUG(0, "%s(), unable to allocate irq=%d\n",
-                          __FUNCTION__, self->io.irq);
-               return -EAGAIN;
-       }
-
-       spin_lock_irqsave(&self->lock, flags);
-       /* Init uart */
-       irport_start(self);
-       /* Set 9600 bauds per default, including at the dongle */
-       irda_task_execute(self, __irport_change_speed, 
-                         irport_change_speed_complete, 
-                         NULL, (void *) 9600);
-       spin_unlock_irqrestore(&self->lock, flags);
-
-
-       /* Give self a hardware name */
-       sprintf(hwname, "SIR @ 0x%03x", self->io.sir_base);
-
-       /* 
-        * Open new IrLAP layer instance, now that everything should be
-        * initialized properly 
-        */
-       self->irlap = irlap_open(dev, &self->qos, hwname);
-
-       /* Ready to play! */
-
-       netif_start_queue(dev);
-
-       return 0;
-}
-
-/*
- * Function irport_net_close (self)
- *
- *    Network device is taken down. Usually this is done by 
- *    "ifconfig irda0 down" 
- */
-static int irport_net_close(struct net_device *dev)
-{
-       struct irport_cb *self;
-       int iobase;
-       unsigned long flags;
-
-       IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
-
-       IRDA_ASSERT(dev != NULL, return -1;);
-       self = (struct irport_cb *) dev->priv;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       iobase = self->io.sir_base;
-
-       /* Stop device */
-       netif_stop_queue(dev);
-       
-       /* Stop and remove instance of IrLAP */
-       if (self->irlap)
-               irlap_close(self->irlap);
-       self->irlap = NULL;
-
-       spin_lock_irqsave(&self->lock, flags);
-       irport_stop(self);
-       spin_unlock_irqrestore(&self->lock, flags);
-
-       free_irq(self->io.irq, dev);
-
-       return 0;
-}
-
-/*
- * Function irport_is_receiving (self)
- *
- *    Returns true is we are currently receiving data
- *
- */
-static inline int irport_is_receiving(struct irport_cb *self)
-{
-       return (self->rx_buff.state != OUTSIDE_FRAME);
-}
-
-/*
- * Function irport_set_dtr_rts (tty, dtr, rts)
- *
- *    This function can be used by dongles etc. to set or reset the status
- *    of the dtr and rts lines
- */
-static int irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
-{
-       struct irport_cb *self = dev->priv;
-       int iobase;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       iobase = self->io.sir_base;
-
-       if (dtr)
-               dtr = UART_MCR_DTR;
-       if (rts)
-               rts = UART_MCR_RTS;
-
-       outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
-
-       return 0;
-}
-
-static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
-{
-       struct irport_cb *self = (struct irport_cb *) dev->priv;
-       int actual = 0;
-       int iobase;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       iobase = self->io.sir_base;
-
-       /* Tx FIFO should be empty! */
-       if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-               IRDA_DEBUG( 0, "%s(), failed, fifo not empty!\n", __FUNCTION__);
-               return -1;
-       }
-        
-       /* Fill FIFO with current frame */
-       while (actual < len) {
-               /* Transmit next byte */
-               outb(buf[actual], iobase+UART_TX);
-               actual++;
-       }
-
-       return actual;
-}
-
-/*
- * Function irport_net_ioctl (dev, rq, cmd)
- *
- *    Process IOCTL commands for this device
- *
- */
-static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-       struct if_irda_req *irq = (struct if_irda_req *) rq;
-       struct irport_cb *self;
-       dongle_t *dongle;
-       unsigned long flags;
-       int ret = 0;
-
-       IRDA_ASSERT(dev != NULL, return -1;);
-
-       self = dev->priv;
-
-       IRDA_ASSERT(self != NULL, return -1;);
-
-       IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
-       
-       switch (cmd) {
-       case SIOCSBANDWIDTH: /* Set bandwidth */
-               if (!capable(CAP_NET_ADMIN))
-                       ret = -EPERM;
-                else
-                       irda_task_execute(self, __irport_change_speed, NULL, 
-                                         NULL, (void *) irq->ifr_baudrate);
-               break;
-       case SIOCSDONGLE: /* Set dongle */
-               if (!capable(CAP_NET_ADMIN)) {
-                       ret = -EPERM;
-                       break;
-               }
-
-               /* Locking :
-                * irda_device_dongle_init() can't be locked.
-                * irda_task_execute() doesn't need to be locked.
-                * Jean II
-                */
-
-               /* Initialize dongle */
-               dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
-               if (!dongle)
-                       break;
-               
-               dongle->set_mode    = NULL;
-               dongle->read        = NULL;
-               dongle->write       = irport_raw_write;
-               dongle->set_dtr_rts = irport_set_dtr_rts;
-               
-               /* Now initialize the dongle!  */
-               dongle->issue->open(dongle, &self->qos);
-               
-               /* Reset dongle */
-               irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
-                                 NULL);        
-
-               /* Make dongle available to driver only now to avoid
-                * race conditions - Jean II */
-               self->dongle = dongle;
-               break;
-       case SIOCSMEDIABUSY: /* Set media busy */
-               if (!capable(CAP_NET_ADMIN)) {
-                       ret = -EPERM;
-                       break;
-               }
-
-               irda_device_set_media_busy(self->netdev, TRUE);
-               break;
-       case SIOCGRECEIVING: /* Check if we are receiving right now */
-               irq->ifr_receiving = irport_is_receiving(self);
-               break;
-       case SIOCSDTRRTS:
-               if (!capable(CAP_NET_ADMIN)) {
-                       ret = -EPERM;
-                       break;
-               }
-
-               /* No real need to lock... */
-               spin_lock_irqsave(&self->lock, flags);
-               irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
-               spin_unlock_irqrestore(&self->lock, flags);
-               break;
-       default:
-               ret = -EOPNOTSUPP;
-       }
-       
-       return ret;
-}
-
-static struct net_device_stats *irport_net_get_stats(struct net_device *dev)
-{
-       struct irport_cb *self = (struct irport_cb *) dev->priv;
-       
-       return &self->stats;
-}
-
-static int __init irport_init(void)
-{
-       int i;
-
-       for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) {
-               if (irport_open(i, io[i], irq[i]) != NULL)
-                       return 0;
-       }
-       /* 
-        * Maybe something failed, but we can still be usable for FIR drivers 
-        */
-       return 0;
-}
-
-/*
- * Function irport_cleanup ()
- *
- *    Close all configured ports
- *
- */
-static void __exit irport_cleanup(void)
-{
-       int i;
-
-        IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
-
-       for (i=0; i < ARRAY_SIZE(dev_self); i++) {
-               if (dev_self[i])
-                       irport_close(dev_self[i]);
-       }
-}
-
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "Base I/O addresses");
-module_param_array(irq, int, NULL, 0);
-MODULE_PARM_DESC(irq, "IRQ lines");
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
-MODULE_LICENSE("GPL");
-
-module_init(irport_init);
-module_exit(irport_cleanup);
-
diff --git a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h
deleted file mode 100644 (file)
index 66fc243..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      irport.h
- * Version:       0.1
- * Description:   Serial driver for IrDA
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sun Aug  3 13:49:59 1997
- * Modified at:   Fri Jan 14 10:21:10 2000
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1997, 1998-2000 Dag Brattli <dagb@cs.uit.no>
- *     All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#ifndef IRPORT_H
-#define IRPORT_H
-
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-
-#include <net/irda/irda_device.h>
-
-#define SPEED_DEFAULT 9600
-#define SPEED_MAX     115200
-
-/*
- * These are the supported serial types.
- */
-#define PORT_UNKNOWN    0
-#define PORT_8250       1
-#define PORT_16450      2
-#define PORT_16550      3
-#define PORT_16550A     4
-#define PORT_CIRRUS     5
-#define PORT_16650      6
-#define PORT_MAX        6  
-
-#define FRAME_MAX_SIZE 2048
-
-struct irport_cb {
-       struct net_device *netdev; /* Yes! we are some kind of netdevice */
-       struct net_device_stats stats;
-
-       struct irlap_cb *irlap;    /* The link layer we are attached to */
-
-       chipio_t io;               /* IrDA controller information */
-       iobuff_t tx_buff;          /* Transmit buffer */
-       iobuff_t rx_buff;          /* Receive buffer */
-
-       struct qos_info qos;       /* QoS capabilities for this device */
-       dongle_t *dongle;          /* Dongle driver */
-
-       __u32 flags;               /* Interface flags */
-       __u32 new_speed;
-       int mode;
-       int index;                 /* Instance index */
-       int transmitting;          /* Are we transmitting ? */
-
-       spinlock_t lock;           /* For serializing operations */
-
-       /* For piggyback drivers */
-       void *priv;                
-       void (*change_speed)(void *priv, __u32 speed);
-       irqreturn_t (*interrupt)(int irq, void *dev_id);
-};
-
-#endif /* IRPORT_H */
diff --git a/drivers/net/irda/litelink.c b/drivers/net/irda/litelink.c
deleted file mode 100644 (file)
index 7db1143..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      litelink.c
- * Version:       1.1
- * Description:   Driver for the Parallax LiteLink dongle
- * Status:        Stable
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Fri May  7 12:50:33 1999
- * Modified at:   Fri Dec 17 09:14:23 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-#define MIN_DELAY 25      /* 15 us, but wait a little more to be sure */
-#define MAX_DELAY 10000   /* 1 ms */
-
-static void litelink_open(dongle_t *self, struct qos_info *qos);
-static void litelink_close(dongle_t *self);
-static int  litelink_change_speed(struct irda_task *task);
-static int  litelink_reset(struct irda_task *task);
-
-/* These are the baudrates supported */
-static __u32 baud_rates[] = { 115200, 57600, 38400, 19200, 9600 };
-
-static struct dongle_reg dongle = {
-       .type = IRDA_LITELINK_DONGLE,
-       .open = litelink_open,
-       .close = litelink_close,
-       .reset = litelink_reset,
-       .change_speed = litelink_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init litelink_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit litelink_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void litelink_open(dongle_t *self, struct qos_info *qos)
-{
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x7f; /* Needs 0.01 ms */
-}
-
-static void litelink_close(dongle_t *self)
-{
-       /* Power off dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function litelink_change_speed (task)
- *
- *    Change speed of the Litelink dongle. To cycle through the available 
- *    baud rates, pulse RTS low for a few ms.  
- */
-static int litelink_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-        int i;
-       
-       /* Clear RTS to reset dongle */
-       self->set_dtr_rts(self->dev, TRUE, FALSE);
-
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-
-       /* Go back to normal mode */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-       
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-       
-       /* Cycle through avaiable baudrates until we reach the correct one */
-       for (i=0; i<5 && baud_rates[i] != speed; i++) {
-               /* Set DTR, clear RTS */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-               
-               /* Sleep a minimum of 15 us */
-               udelay(MIN_DELAY);
-               
-               /* Set DTR, Set RTS */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               
-               /* Sleep a minimum of 15 us */
-               udelay(MIN_DELAY);
-        }
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-/*
- * Function litelink_reset (task)
- *
- *      Reset the Litelink type dongle.
- *
- */
-static int litelink_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-
-       /* Power on dongle */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-
-       /* Clear RTS to reset dongle */
-       self->set_dtr_rts(self->dev, TRUE, FALSE);
-
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-
-       /* Go back to normal mode */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-       
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-
-       /* This dongles speed defaults to 115200 bps */
-       self->speed = 115200;
-
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("Parallax Litelink dongle driver"); 
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-5"); /* IRDA_LITELINK_DONGLE */
-               
-/*
- * Function init_module (void)
- *
- *    Initialize Litelink module
- *
- */
-module_init(litelink_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup Litelink module
- *
- */
-module_exit(litelink_cleanup);
diff --git a/drivers/net/irda/ma600.c b/drivers/net/irda/ma600.c
deleted file mode 100644 (file)
index f5e6836..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      ma600.c
- * Version:       0.1
- * Description:   Implementation of the MA600 dongle
- * Status:        Experimental.
- * Author:        Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95
- * Created at:    Sat Jun 10 20:02:35 2000
- * Modified at:   
- * Modified by:   
- *
- * Note: very thanks to Mr. Maru Wang <maru@mobileaction.com.tw> for providing 
- *       information on the MA600 dongle
- * 
- *     Copyright (c) 2000 Leung, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
- *     
- ********************************************************************/
-
-/* define this macro for release version */
-//#define NDEBUG
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-#ifndef NDEBUG
-       #undef IRDA_DEBUG
-       #define IRDA_DEBUG(n, args...) (printk(KERN_DEBUG args))
-
-       #undef ASSERT
-       #define ASSERT(expr, func) \
-       if(!(expr)) { \
-               printk( "Assertion failed! %s,%s,%s,line=%d\n",\
-               #expr,__FILE__,__FUNCTION__,__LINE__); \
-               func}
-#endif
-
-/* convert hex value to ascii hex */
-static const char hexTbl[] = "0123456789ABCDEF";
-
-
-static void ma600_open(dongle_t *self, struct qos_info *qos);
-static void ma600_close(dongle_t *self);
-static int  ma600_change_speed(struct irda_task *task);
-static int  ma600_reset(struct irda_task *task);
-
-/* control byte for MA600 */
-#define MA600_9600     0x00
-#define MA600_19200    0x01
-#define MA600_38400    0x02
-#define MA600_57600    0x03
-#define MA600_115200   0x04
-#define MA600_DEV_ID1  0x05
-#define MA600_DEV_ID2  0x06
-#define MA600_2400     0x08
-
-static struct dongle_reg dongle = {
-       .type = IRDA_MA600_DONGLE,
-       .open = ma600_open,
-       .close = ma600_close,
-       .reset = ma600_reset,
-       .change_speed = ma600_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init ma600_init(void)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit ma600_cleanup(void)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-       irda_device_unregister_dongle(&dongle);
-}
-
-/*
-       Power on:
-               (0) Clear RTS and DTR for 1 second
-               (1) Set RTS and DTR for 1 second
-               (2) 9600 bps now
-       Note: assume RTS, DTR are clear before
-*/
-static void ma600_open(dongle_t *self, struct qos_info *qos)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400
-                               |IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x01;         /* Needs at least 1 ms */       
-       irda_qos_bits_to_value(qos);
-
-       //self->set_dtr_rts(self->dev, FALSE, FALSE);
-       // should wait 1 second
-
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-       // should wait 1 second
-}
-
-static void ma600_close(dongle_t *self)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       /* Power off dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-static __u8 get_control_byte(__u32 speed)
-{
-       __u8 byte;
-
-       switch (speed) {
-       default:
-       case 115200:
-               byte = MA600_115200;
-               break;
-       case 57600:
-               byte = MA600_57600;
-               break;
-       case 38400:
-               byte = MA600_38400;
-               break;
-       case 19200:
-               byte = MA600_19200;
-               break;
-       case 9600:
-               byte = MA600_9600;
-               break;
-       case 2400:
-               byte = MA600_2400;
-               break;
-       }
-
-       return byte;
-}
-
-/*
- * Function ma600_change_speed (dev, state, speed)
- *
- *    Set the speed for the MA600 type dongle. Warning, this 
- *    function must be called with a process context!
- *
- *    Algorithm
- *    1. Reset
- *    2. clear RTS, set DTR and wait for 1ms
- *    3. send Control Byte to the MA600 through TXD to set new baud rate
- *       wait until the stop bit of Control Byte is sent (for 9600 baud rate, 
- *       it takes about 10 msec)
- *    4. set RTS, set DTR (return to NORMAL Operation)
- *    5. wait at least 10 ms, new setting (baud rate, etc) takes effect here 
- *       after
- */
-static int ma600_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       static __u8 byte;
-       __u8 byte_echo;
-       int ret = 0;
-       
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       ASSERT(task != NULL, return -1;);
-
-       if (self->speed_task && self->speed_task != task) {
-               IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__);
-               return msecs_to_jiffies(10);
-       } else {
-               self->speed_task = task;
-       }
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-       case IRDA_TASK_CHILD_INIT:
-               /* 
-                * Need to reset the dongle and go to 9600 bps before
-                 * programming 
-                */
-               if (irda_task_execute(self, ma600_reset, NULL, task, 
-                                     (void *) speed)) {
-                       /* Dongle need more time to reset */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-       
-                       /* give 1 second to finish */
-                       ret = msecs_to_jiffies(1000);
-               } else {
-                       irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
-               }
-               break;
-
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), resetting dongle timed out!\n",
-                            __FUNCTION__);
-               ret = -1;
-               break;
-
-       case IRDA_TASK_CHILD_DONE:
-               /* Set DTR, Clear RTS */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-       
-               ret = msecs_to_jiffies(1);              /* Sleep 1 ms */
-               irda_task_next_state(task, IRDA_TASK_WAIT);
-               break;
-
-       case IRDA_TASK_WAIT:
-               speed = (__u32) task->param;
-               byte = get_control_byte(speed);
-
-               /* Write control byte */
-               self->write(self->dev, &byte, sizeof(byte));
-               
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-
-               /* Wait at least 10 ms */
-               ret = msecs_to_jiffies(15);
-               break;
-
-       case IRDA_TASK_WAIT1:
-               /* Read control byte echo */
-               self->read(self->dev, &byte_echo, sizeof(byte_echo));
-
-               if(byte != byte_echo) {
-                       /* if control byte != echo, I don't know what to do */
-                       printk(KERN_WARNING "%s() control byte written != read!\n", __FUNCTION__);
-                       printk(KERN_WARNING "control byte = 0x%c%c\n", 
-                              hexTbl[(byte>>4)&0x0f], hexTbl[byte&0x0f]);
-                       printk(KERN_WARNING "byte echo = 0x%c%c\n", 
-                              hexTbl[(byte_echo>>4) & 0x0f], 
-                              hexTbl[byte_echo & 0x0f]);
-               #ifndef NDEBUG
-               } else {
-                       IRDA_DEBUG(2, "%s() control byte write read OK\n", __FUNCTION__);
-               #endif
-               }
-
-               /* Set DTR, Set RTS */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-
-               /* Wait at least 10 ms */
-               ret = msecs_to_jiffies(10);
-               break;
-
-       case IRDA_TASK_WAIT2:
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               break;
-
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-/*
- * Function ma600_reset (driver)
- *
- *      This function resets the ma600 dongle. Warning, this function 
- *      must be called with a process context!! 
- *
- *      Algorithm:
- *       0. DTR=0, RTS=1 and wait 10 ms
- *       1. DTR=1, RTS=1 and wait 10 ms
- *        2. 9600 bps now
- */
-int ma600_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       int ret = 0;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       ASSERT(task != NULL, return -1;);
-
-       if (self->reset_task && self->reset_task != task) {
-               IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__);
-               return msecs_to_jiffies(10);
-       } else
-               self->reset_task = task;
-       
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Clear DTR and Set RTS */
-               self->set_dtr_rts(self->dev, FALSE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-               ret = msecs_to_jiffies(10);             /* Sleep 10 ms */
-               break;
-       case IRDA_TASK_WAIT1:
-               /* Set DTR and RTS */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-               ret = msecs_to_jiffies(10);             /* Sleep 10 ms */
-               break;
-       case IRDA_TASK_WAIT2:
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);             
-               self->reset_task = NULL;
-               ret = -1;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("Leung <95Etwl@alumni.ee.ust.hk> http://www.engsvr.ust/~eetwl95");
-MODULE_DESCRIPTION("MA600 dongle driver version 0.1");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-11"); /* IRDA_MA600_DONGLE */
-               
-/*
- * Function init_module (void)
- *
- *    Initialize MA600 module
- *
- */
-module_init(ma600_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup MA600 module
- *
- */
-module_exit(ma600_cleanup);
-
diff --git a/drivers/net/irda/mcp2120.c b/drivers/net/irda/mcp2120.c
deleted file mode 100644 (file)
index 5e6199e..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*********************************************************************
- *            
- *    
- * Filename:      mcp2120.c
- * Version:       1.0
- * Description:   Implementation for the MCP2120 (Microchip)
- * Status:        Experimental.
- * Author:        Felix Tang (tangf@eyetap.org)
- * Created at:    Sun Mar 31 19:32:12 EST 2002
- * Based on code by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 2002 Felix Tang, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-static int  mcp2120_reset(struct irda_task *task);
-static void mcp2120_open(dongle_t *self, struct qos_info *qos);
-static void mcp2120_close(dongle_t *self);
-static int  mcp2120_change_speed(struct irda_task *task);
-
-#define MCP2120_9600    0x87
-#define MCP2120_19200   0x8B
-#define MCP2120_38400   0x85
-#define MCP2120_57600   0x83
-#define MCP2120_115200  0x81
-
-#define MCP2120_COMMIT  0x11
-
-static struct dongle_reg dongle = {
-       .type = IRDA_MCP2120_DONGLE,
-       .open = mcp2120_open,
-       .close = mcp2120_close,
-       .reset = mcp2120_reset,
-       .change_speed = mcp2120_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init mcp2120_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit mcp2120_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void mcp2120_open(dongle_t *self, struct qos_info *qos)
-{
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x01;
-}
-
-static void mcp2120_close(dongle_t *self)
-{
-       /* Power off dongle */
-        /* reset and inhibit mcp2120 */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-       //self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function mcp2120_change_speed (dev, speed)
- *
- *    Set the speed for the MCP2120.
- *
- */
-static int mcp2120_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       __u8 control[2];
-       int ret = 0;
-
-       self->speed_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               /* Need to reset the dongle and go to 9600 bps before
-                   programming */
-                //printk("Dmcp2120_change_speed irda_task_init\n");
-               if (irda_task_execute(self, mcp2120_reset, NULL, task, 
-                                     (void *) speed))
-               {
-                       /* Dongle need more time to reset */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
-                       /* Give reset 1 sec to finish */
-                       ret = msecs_to_jiffies(1000);
-               }
-               break;
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), resetting dongle timed out!\n",
-                            __FUNCTION__);
-               ret = -1;
-               break;
-       case IRDA_TASK_CHILD_DONE:
-               /* Set DTR to enter command mode */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-                udelay(500);
-
-               switch (speed) {
-               case 9600:
-               default:
-                       control[0] = MCP2120_9600;
-                        //printk("mcp2120 9600\n");
-                       break;
-               case 19200:
-                       control[0] = MCP2120_19200;
-                        //printk("mcp2120 19200\n");
-                       break;
-               case 34800:
-                       control[0] = MCP2120_38400;
-                        //printk("mcp2120 38400\n");
-                       break;
-               case 57600:
-                       control[0] = MCP2120_57600;
-                        //printk("mcp2120 57600\n");
-                       break;
-               case 115200:
-                        control[0] = MCP2120_115200;
-                        //printk("mcp2120 115200\n");
-                       break;
-               }
-               control[1] = MCP2120_COMMIT;
-       
-               /* Write control bytes */
-                self->write(self->dev, control, 2);
-                irda_task_next_state(task, IRDA_TASK_WAIT);
-               ret = msecs_to_jiffies(100);
-                //printk("mcp2120_change_speed irda_child_done\n");
-               break;
-       case IRDA_TASK_WAIT:
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, FALSE, FALSE);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-                //printk("mcp2120_change_speed irda_task_wait\n");
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-/*
- * Function mcp2120_reset (driver)
- *
- *      This function resets the mcp2120 dongle.
- *      
- *      Info: -set RTS to reset mcp2120
- *            -set DTR to set mcp2120 software command mode
- *            -mcp2120 defaults to 9600 baud after reset
- *
- *      Algorithm:
- *      0. Set RTS to reset mcp2120.
- *      1. Clear RTS and wait for device reset timer of 30 ms (max).
- *      
- */
-
-
-static int mcp2120_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       int ret = 0;
-
-       self->reset_task = task;
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-                //printk("mcp2120_reset irda_task_init\n");
-               /* Reset dongle by setting RTS*/
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-               ret = msecs_to_jiffies(50);
-               break;
-       case IRDA_TASK_WAIT1:
-                //printk("mcp2120_reset irda_task_wait1\n");
-                /* clear RTS and wait for at least 30 ms. */
-               self->set_dtr_rts(self->dev, FALSE, FALSE);
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-               ret = msecs_to_jiffies(50);
-               break;
-       case IRDA_TASK_WAIT2:
-                //printk("mcp2120_reset irda_task_wait2\n");
-               /* Go back to normal mode */
-               self->set_dtr_rts(self->dev, FALSE, FALSE);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("Felix Tang <tangf@eyetap.org>");
-MODULE_DESCRIPTION("Microchip MCP2120");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-9"); /* IRDA_MCP2120_DONGLE */
-       
-/*
- * Function init_module (void)
- *
- *    Initialize MCP2120 module
- *
- */
-module_init(mcp2120_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup MCP2120 module
- *
- */
-module_exit(mcp2120_cleanup);
diff --git a/drivers/net/irda/old_belkin.c b/drivers/net/irda/old_belkin.c
deleted file mode 100644 (file)
index 26f81fd..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      old_belkin.c
- * Version:       1.1
- * Description:   Driver for the Belkin (old) SmartBeam dongle
- * Status:        Experimental...
- * Author:        Jean Tourrilhes <jt@hpl.hp.com>
- * Created at:    22/11/99
- * Modified at:   Fri Dec 17 09:13:32 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1999 Jean Tourrilhes, All Rights Reserved.
- *     
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- * 
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *     GNU General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License 
- *     along with this program; if not, write to the Free Software 
- *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
- *     MA 02111-1307 USA
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-/*
- * Belkin is selling a dongle called the SmartBeam.
- * In fact, there is two hardware version of this dongle, of course with
- * the same name and looking the exactly same (grrr...).
- * I guess that I've got the old one, because inside I don't have
- * a jumper for IrDA/ASK...
- *
- * As far as I can make it from info on their web site, the old dongle 
- * support only 9600 b/s, which make our life much simpler as far as
- * the driver is concerned, but you might not like it very much ;-)
- * The new SmartBeam does 115 kb/s, and I've not tested it...
- *
- * Belkin claim that the correct driver for the old dongle (in Windows)
- * is the generic Parallax 9500a driver, but the Linux LiteLink driver
- * fails for me (probably because Linux-IrDA doesn't rate fallback),
- * so I created this really dumb driver...
- *
- * In fact, this driver doesn't do much. The only thing it does is to
- * prevent Linux-IrDA to use any other speed than 9600 b/s ;-) This
- * driver is called "old_belkin" so that when the new SmartBeam is supported
- * its driver can be called "belkin" instead of "new_belkin".
- *
- * Note : this driver was written without any info/help from Belkin,
- * so a lot of info here might be totally wrong. Blame me ;-)
- */
-
-/* Let's guess */
-#define MIN_DELAY 25      /* 15 us, but wait a little more to be sure */
-
-static void old_belkin_open(dongle_t *self, struct qos_info *qos);
-static void old_belkin_close(dongle_t *self);
-static int  old_belkin_change_speed(struct irda_task *task);
-static int  old_belkin_reset(struct irda_task *task);
-
-/* These are the baudrates supported */
-/* static __u32 baud_rates[] = { 9600 }; */
-
-static struct dongle_reg dongle = {
-       .type = IRDA_OLD_BELKIN_DONGLE,
-       .open = old_belkin_open,
-       .close = old_belkin_close,
-       .reset = old_belkin_reset,
-       .change_speed = old_belkin_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init old_belkin_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit old_belkin_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void old_belkin_open(dongle_t *self, struct qos_info *qos)
-{
-       /* Not too fast, please... */
-       qos->baud_rate.bits &= IR_9600;
-       /* Needs at least 10 ms (totally wild guess, can do probably better) */
-       qos->min_turn_time.bits = 0x01;
-}
-
-static void old_belkin_close(dongle_t *self)
-{
-       /* Power off dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-}
-
-/*
- * Function old_belkin_change_speed (task)
- *
- *    With only one speed available, not much to do...
- */
-static int old_belkin_change_speed(struct irda_task *task)
-{
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-/*
- * Function old_belkin_reset (task)
- *
- *      Reset the Old-Belkin type dongle.
- *
- */
-static int old_belkin_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-
-       /* Power on dongle */
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-       /* Sleep a minimum of 15 us */
-       udelay(MIN_DELAY);
-
-       /* This dongles speed "defaults" to 9600 bps ;-) */
-       self->speed = 9600;
-
-       irda_task_next_state(task, IRDA_TASK_DONE);
-
-       return 0;
-}
-
-MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>");
-MODULE_DESCRIPTION("Belkin (old) SmartBeam dongle driver");    
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-7"); /* IRDA_OLD_BELKIN_DONGLE */
-
-/*
- * Function init_module (void)
- *
- *    Initialize Old-Belkin module
- *
- */
-module_init(old_belkin_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup Old-Belkin module
- *
- */
-module_exit(old_belkin_cleanup);
index 7e7b5828214a89fa12e587f3b3fc0a31aa27e54b..1f26da761e9f0067ca49450f31d48cad23cf6317 100644 (file)
@@ -1505,22 +1505,13 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self)
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id)
+static irqreturn_t smsc_ircc_interrupt(int dummy, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
-       struct smsc_ircc_cb *self;
+       struct net_device *dev = dev_id;
+       struct smsc_ircc_cb *self = netdev_priv(dev);
        int iobase, iir, lcra, lsr;
        irqreturn_t ret = IRQ_NONE;
 
-       if (dev == NULL) {
-               printk(KERN_WARNING "%s: irq %d for unknown device.\n",
-                      driver_name, irq);
-               goto irq_ret;
-       }
-
-       self = netdev_priv(dev);
-       IRDA_ASSERT(self != NULL, return IRQ_NONE;);
-
        /* Serialise the interrupt handler in various CPUs, stop Tx path */
        spin_lock(&self->lock);
 
@@ -1565,7 +1556,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id)
 
  irq_ret_unlock:
        spin_unlock(&self->lock);
- irq_ret:
+
        return ret;
 }
 
diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c
deleted file mode 100644 (file)
index 9bfd244..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      tekram.c
- * Version:       1.2
- * Description:   Implementation of the Tekram IrMate IR-210B dongle
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Wed Oct 21 20:02:35 1998
- * Modified at:   Fri Dec 17 09:13:09 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
- *      
- *     This program is free software; you can redistribute it and/or 
- *     modify it under the terms of the GNU General Public License as 
- *     published by the Free Software Foundation; either version 2 of 
- *     the License, or (at your option) any later version.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irda_device.h>
-
-static void tekram_open(dongle_t *self, struct qos_info *qos);
-static void tekram_close(dongle_t *self);
-static int  tekram_change_speed(struct irda_task *task);
-static int  tekram_reset(struct irda_task *task);
-
-#define TEKRAM_115200 0x00
-#define TEKRAM_57600  0x01
-#define TEKRAM_38400  0x02
-#define TEKRAM_19200  0x03
-#define TEKRAM_9600   0x04
-
-#define TEKRAM_PW     0x10 /* Pulse select bit */
-
-static struct dongle_reg dongle = {
-       .type = IRDA_TEKRAM_DONGLE,
-       .open  = tekram_open,
-       .close = tekram_close,
-       .reset = tekram_reset,
-       .change_speed = tekram_change_speed,
-       .owner = THIS_MODULE,
-};
-
-static int __init tekram_init(void)
-{
-       return irda_device_register_dongle(&dongle);
-}
-
-static void __exit tekram_cleanup(void)
-{
-       irda_device_unregister_dongle(&dongle);
-}
-
-static void tekram_open(dongle_t *self, struct qos_info *qos)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-       qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */      
-       irda_qos_bits_to_value(qos);
-}
-
-static void tekram_close(dongle_t *self)
-{
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       /* Power off dongle */
-       self->set_dtr_rts(self->dev, FALSE, FALSE);
-
-       if (self->reset_task)
-               irda_task_delete(self->reset_task);
-       if (self->speed_task)
-               irda_task_delete(self->speed_task);
-}
-
-/*
- * Function tekram_change_speed (dev, state, speed)
- *
- *    Set the speed for the Tekram IRMate 210 type dongle. Warning, this 
- *    function must be called with a process context!
- *
- *    Algorithm
- *    1. clear DTR 
- *    2. set RTS, and wait at least 7 us
- *    3. send Control Byte to the IR-210 through TXD to set new baud rate
- *       wait until the stop bit of Control Byte is sent (for 9600 baud rate, 
- *       it takes about 100 msec)
- *    5. clear RTS (return to NORMAL Operation)
- *    6. wait at least 50 us, new setting (baud rate, etc) takes effect here 
- *       after
- */
-static int tekram_change_speed(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       __u32 speed = (__u32) task->param;
-       __u8 byte;
-       int ret = 0;
-       
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       IRDA_ASSERT(task != NULL, return -1;);
-
-       if (self->speed_task && self->speed_task != task) {
-               IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ );
-               return msecs_to_jiffies(10);
-       } else
-               self->speed_task = task;
-
-       switch (speed) {
-       default:
-       case 9600:
-               byte = TEKRAM_PW|TEKRAM_9600;
-               break;
-       case 19200:
-               byte = TEKRAM_PW|TEKRAM_19200;
-               break;
-       case 38400:
-               byte = TEKRAM_PW|TEKRAM_38400;
-               break;
-       case 57600:
-               byte = TEKRAM_PW|TEKRAM_57600;
-               break;
-       case 115200:
-               byte = TEKRAM_115200;
-               break;
-       }
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-       case IRDA_TASK_CHILD_INIT:              
-               /* 
-                * Need to reset the dongle and go to 9600 bps before
-                 * programming 
-                */
-               if (irda_task_execute(self, tekram_reset, NULL, task, 
-                                     (void *) speed))
-               {
-                       /* Dongle need more time to reset */
-                       irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
-                       /* Give reset 1 sec to finish */
-                       ret = msecs_to_jiffies(1000);
-               } else
-                       irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
-               break;
-       case IRDA_TASK_CHILD_WAIT:
-               IRDA_WARNING("%s(), resetting dongle timed out!\n",
-                            __FUNCTION__);
-               ret = -1;
-               break;
-       case IRDA_TASK_CHILD_DONE:
-               /* Set DTR, Clear RTS */
-               self->set_dtr_rts(self->dev, TRUE, FALSE);
-       
-               /* Wait at least 7us */
-               udelay(14);
-
-               /* Write control byte */
-               self->write(self->dev, &byte, 1);
-               
-               irda_task_next_state(task, IRDA_TASK_WAIT);
-
-               /* Wait at least 100 ms */
-               ret = msecs_to_jiffies(150);
-               break;
-       case IRDA_TASK_WAIT:
-               /* Set DTR, Set RTS */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->speed_task = NULL;
-               ret = -1;
-               break;
-       }
-       return ret;
-}
-
-/*
- * Function tekram_reset (driver)
- *
- *      This function resets the tekram dongle. Warning, this function 
- *      must be called with a process context!! 
- *
- *      Algorithm:
- *       0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
- *        1. clear RTS 
- *        2. set DTR, and wait at least 1 ms 
- *        3. clear DTR to SPACE state, wait at least 50 us for further 
- *         operation
- */
-int tekram_reset(struct irda_task *task)
-{
-       dongle_t *self = (dongle_t *) task->instance;
-       int ret = 0;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
-
-       IRDA_ASSERT(task != NULL, return -1;);
-
-       if (self->reset_task && self->reset_task != task) {
-               IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__ );
-               return msecs_to_jiffies(10);
-       } else
-               self->reset_task = task;
-       
-       /* Power off dongle */
-       //self->set_dtr_rts(self->dev, FALSE, FALSE);
-       self->set_dtr_rts(self->dev, TRUE, TRUE);
-
-       switch (task->state) {
-       case IRDA_TASK_INIT:
-               irda_task_next_state(task, IRDA_TASK_WAIT1);
-
-               /* Sleep 50 ms */
-               ret = msecs_to_jiffies(50);
-               break;
-       case IRDA_TASK_WAIT1:
-               /* Clear DTR, Set RTS */
-               self->set_dtr_rts(self->dev, FALSE, TRUE); 
-
-               irda_task_next_state(task, IRDA_TASK_WAIT2);
-               
-               /* Should sleep 1 ms */
-               ret = msecs_to_jiffies(1);
-               break;
-       case IRDA_TASK_WAIT2:
-               /* Set DTR, Set RTS */
-               self->set_dtr_rts(self->dev, TRUE, TRUE);
-       
-               /* Wait at least 50 us */
-               udelay(75);
-
-               irda_task_next_state(task, IRDA_TASK_DONE);
-               self->reset_task = NULL;
-               break;
-       default:
-               IRDA_ERROR("%s(), unknown state %d\n",
-                          __FUNCTION__, task->state);
-               irda_task_next_state(task, IRDA_TASK_DONE);             
-               self->reset_task = NULL;
-               ret = -1;
-       }
-       return ret;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("irda-dongle-0"); /* IRDA_TEKRAM_DONGLE */
-               
-/*
- * Function init_module (void)
- *
- *    Initialize Tekram module
- *
- */
-module_init(tekram_init);
-
-/*
- * Function cleanup_module (void)
- *
- *    Cleanup Tekram module
- *
- */
-module_exit(tekram_cleanup);
index 126ec7c8680ea176a156be4c4aca2cc16bcb66f5..58e128784585a41b9c80410eaf46500e40a337ba 100644 (file)
@@ -1346,19 +1346,13 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase)
  *    An interrupt from the chip has arrived. Time to do some work
  *
  */
-static irqreturn_t via_ircc_interrupt(int irq, void *dev_id)
+static irqreturn_t via_ircc_interrupt(int dummy, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
-       struct via_ircc_cb *self;
+       struct net_device *dev = dev_id;
+       struct via_ircc_cb *self = dev->priv;
        int iobase;
        u8 iHostIntType, iRxIntType, iTxIntType;
 
-       if (!dev) {
-               IRDA_WARNING("%s: irq %d for unknown device.\n", driver_name,
-                            irq);
-               return IRQ_NONE;
-       }
-       self = (struct via_ircc_cb *) dev->priv;
        iobase = self->io.fir_base;
        spin_lock(&self->lock);
        iHostIntType = GetHostStatus(iobase);
index 2c6367ace3cd9a5a4f3b17c70d2c0e69845150f1..80a8b98882255177a24b719909b2de1603a73477 100644 (file)
@@ -45,6 +45,8 @@ static boolean_t ixgb_link_reset(struct ixgb_hw *hw);
 
 static void ixgb_optics_reset(struct ixgb_hw *hw);
 
+static void ixgb_optics_reset_bcm(struct ixgb_hw *hw);
+
 static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
 
 static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
@@ -90,10 +92,20 @@ static uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
        ASSERT(!(ctrl_reg & IXGB_CTRL0_RST));
 #endif
 
-       if (hw->phy_type == ixgb_phy_type_txn17401) {
-               ixgb_optics_reset(hw);
+       if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID) {
+               ctrl_reg =  /* Enable interrupt from XFP and SerDes */
+                          IXGB_CTRL1_GPI0_EN |
+                          IXGB_CTRL1_SDP6_DIR |
+                          IXGB_CTRL1_SDP7_DIR |
+                          IXGB_CTRL1_SDP6 |
+                          IXGB_CTRL1_SDP7;
+               IXGB_WRITE_REG(hw, CTRL1, ctrl_reg);
+               ixgb_optics_reset_bcm(hw);
        }
 
+       if (hw->phy_type == ixgb_phy_type_txn17401)
+               ixgb_optics_reset(hw);
+
        return ctrl_reg;
 }
 
@@ -253,6 +265,10 @@ ixgb_identify_phy(struct ixgb_hw *hw)
                break;
        }
 
+       /* update phy type for sun specific board */
+       if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID)
+               phy_type = ixgb_phy_type_bcm;
+
        return (phy_type);
 }
 
@@ -1225,3 +1241,65 @@ ixgb_optics_reset(struct ixgb_hw *hw)
 
        return;
 }
+
+/******************************************************************************
+ * Resets the 10GbE optics module for Sun variant NIC.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+
+#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG         0xC803
+#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL     0x0164
+#define   IXGB_BCM8704_USER_CTRL_REG                0xC800
+#define   IXGB_BCM8704_USER_CTRL_REG_VAL            0x7FBF
+#define   IXGB_BCM8704_USER_DEV3_ADDR               0x0003
+#define   IXGB_SUN_PHY_ADDRESS                      0x0000
+#define   IXGB_SUN_PHY_RESET_DELAY                     305
+
+static void
+ixgb_optics_reset_bcm(struct ixgb_hw *hw)
+{
+       u32 ctrl = IXGB_READ_REG(hw, CTRL0);
+       ctrl &= ~IXGB_CTRL0_SDP2;
+       ctrl |= IXGB_CTRL0_SDP3;
+       IXGB_WRITE_REG(hw, CTRL0, ctrl);
+
+       /* SerDes needs extra delay */
+       msleep(IXGB_SUN_PHY_RESET_DELAY);
+
+       /* Broadcom 7408L configuration */
+       /* Reference clock config */
+       ixgb_write_phy_reg(hw,
+                          IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
+                          IXGB_SUN_PHY_ADDRESS,
+                          IXGB_BCM8704_USER_DEV3_ADDR,
+                          IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL);
+       /*  we must read the registers twice */
+       ixgb_read_phy_reg(hw,
+                         IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
+                         IXGB_SUN_PHY_ADDRESS,
+                         IXGB_BCM8704_USER_DEV3_ADDR);
+       ixgb_read_phy_reg(hw,
+                         IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
+                         IXGB_SUN_PHY_ADDRESS,
+                         IXGB_BCM8704_USER_DEV3_ADDR);
+
+       ixgb_write_phy_reg(hw,
+                          IXGB_BCM8704_USER_CTRL_REG,
+                          IXGB_SUN_PHY_ADDRESS,
+                          IXGB_BCM8704_USER_DEV3_ADDR,
+                          IXGB_BCM8704_USER_CTRL_REG_VAL);
+       ixgb_read_phy_reg(hw,
+                         IXGB_BCM8704_USER_CTRL_REG,
+                         IXGB_SUN_PHY_ADDRESS,
+                         IXGB_BCM8704_USER_DEV3_ADDR);
+       ixgb_read_phy_reg(hw,
+                         IXGB_BCM8704_USER_CTRL_REG,
+                         IXGB_SUN_PHY_ADDRESS,
+                         IXGB_BCM8704_USER_DEV3_ADDR);
+
+       /* SerDes needs extra delay */
+       msleep(IXGB_SUN_PHY_RESET_DELAY);
+
+       return;
+}
index af5643324ee3ee854da86e0110e969e3b9118c74..4f176ff2b786dd06e1cd951e9c2b99b8e6c04476 100644 (file)
@@ -44,7 +44,8 @@ typedef enum {
        ixgb_phy_type_g6005,    /* 850nm, MM fiber, XPAK transceiver */
        ixgb_phy_type_g6104,    /* 1310nm, SM fiber, XPAK transceiver */
        ixgb_phy_type_txn17201, /* 850nm, MM fiber, XPAK transceiver */
-       ixgb_phy_type_txn17401  /* 1310nm, SM fiber, XENPAK transceiver */
+       ixgb_phy_type_txn17401, /* 1310nm, SM fiber, XENPAK transceiver */
+       ixgb_phy_type_bcm       /* SUN specific board */
 } ixgb_phy_type;
 
 /* XPAK transceiver vendors, for the SR adapters */
@@ -534,12 +535,12 @@ typedef enum {
  * in which case the structure must be packed in some compiler-specific
  * manner. */
 struct ixgb_rx_desc {
-       uint64_t buff_addr;
-       uint16_t length;
-       uint16_t reserved;
+       __le64 buff_addr;
+       __le16 length;
+       __le16 reserved;
        uint8_t status;
        uint8_t errors;
-       uint16_t special;
+       __le16 special;
 };
 
 #define IXGB_RX_DESC_STATUS_DD    0x01
@@ -567,11 +568,11 @@ struct ixgb_rx_desc {
  * in which case the structure must be packed in some compiler-specific
  * manner. */
 struct ixgb_tx_desc {
-       uint64_t buff_addr;
-       uint32_t cmd_type_len;
+       __le64 buff_addr;
+       __le32 cmd_type_len;
        uint8_t status;
        uint8_t popts;
-       uint16_t vlan;
+       __le16 vlan;
 };
 
 #define IXGB_TX_DESC_LENGTH_MASK    0x000FFFFF
@@ -596,14 +597,14 @@ struct ixgb_tx_desc {
 struct ixgb_context_desc {
        uint8_t ipcss;
        uint8_t ipcso;
-       uint16_t ipcse;
+       __le16 ipcse;
        uint8_t tucss;
        uint8_t tucso;
-       uint16_t tucse;
-       uint32_t cmd_type_len;
+       __le16 tucse;
+       __le32 cmd_type_len;
        uint8_t status;
        uint8_t hdr_len;
-       uint16_t mss;
+       __le16 mss;
 };
 
 #define IXGB_CONTEXT_DESC_CMD_TCP 0x01000000
index 4376e7e8fbef275c4b2efe407fcfce9feaf08d17..180d20e793a5d9b5c1ab129319265c0207594203 100644 (file)
@@ -35,7 +35,8 @@
 
 #define INTEL_VENDOR_ID             0x8086
 #define INTEL_SUBVENDOR_ID          0x8086
-
+#define SUN_VENDOR_ID               0x108E
+#define SUN_SUBVENDOR_ID            0x108E
 
 #define IXGB_DEVICE_ID_82597EX      0x1048   
 #define IXGB_DEVICE_ID_82597EX_SR   0x1A48   
@@ -46,6 +47,7 @@
 #define IXGB_DEVICE_ID_82597EX_CX4   0x109E
 #define IXGB_SUBDEVICE_ID_A00C  0xA00C
 #define IXGB_SUBDEVICE_ID_A01C  0xA01C
+#define IXGB_SUBDEVICE_ID_7036  0x7036
 
 #endif /* #ifndef _IXGB_IDS_H_ */
 /* End of File */
index 4f63839051b05ca2d282e8e62dd0419713d0e124..269e6f805f472bc7232a55cad0518a16884fdbb0 100644 (file)
@@ -36,7 +36,7 @@ static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION            "1.0.126-k2"DRIVERNAPI
+#define DRV_VERSION            "1.0.126-k4"DRIVERNAPI
 const char ixgb_driver_version[] = DRV_VERSION;
 static const char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
 
@@ -212,9 +212,11 @@ static void
 ixgb_irq_enable(struct ixgb_adapter *adapter)
 {
        if(atomic_dec_and_test(&adapter->irq_sem)) {
-               IXGB_WRITE_REG(&adapter->hw, IMS,
-                              IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
-                              IXGB_INT_LSC);
+               u32 val = IXGB_INT_RXT0 | IXGB_INT_RXDMT0 |
+                         IXGB_INT_TXDW | IXGB_INT_LSC;
+               if (adapter->hw.subsystem_vendor_id == SUN_SUBVENDOR_ID)
+                       val |= IXGB_INT_GPI0;
+               IXGB_WRITE_REG(&adapter->hw, IMS, val);
                IXGB_WRITE_FLUSH(&adapter->hw);
        }
 }
index bc51432b8d266cd20bd4e18bba1524433d349dcb..a021a6e72641ef179b5e09764a9ad3fa59f2cebe 100644 (file)
@@ -234,14 +234,10 @@ enum ixbge_state_t {
 };
 
 enum ixgbe_boards {
-       board_82598AF,
-       board_82598EB,
-       board_82598AT,
+       board_82598,
 };
 
-extern struct ixgbe_info ixgbe_82598AF_info;
-extern struct ixgbe_info ixgbe_82598EB_info;
-extern struct ixgbe_info ixgbe_82598AT_info;
+extern struct ixgbe_info ixgbe_82598_info;
 
 extern char ixgbe_driver_name[];
 extern const char ixgbe_driver_version[];
index 4d64673164ca5e580cfd4cf74d4556d8b4cf73e7..6321b059ce132f2e7c252f4856754a501262c381 100644 (file)
@@ -50,8 +50,6 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
                                            bool autoneg,
                                            bool autoneg_wait_to_complete);
 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
-                                        bool *link_up);
 static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
                                               bool autoneg,
                                               bool autoneg_wait_to_complete);
@@ -64,6 +62,28 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
        hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES;
        hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES;
 
+       /* PHY ops are filled in by default properly for Fiber only */
+       if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
+               hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
+               hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
+               hw->mac.ops.get_link_settings =
+                               &ixgbe_get_copper_link_settings_82598;
+
+               /* Call PHY identify routine to get the phy type */
+               ixgbe_identify_phy(hw);
+
+               switch (hw->phy.type) {
+               case ixgbe_phy_tn:
+                       hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
+                       hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
+                       hw->phy.ops.setup_link_speed =
+                                       &ixgbe_setup_tnx_phy_link_speed;
+                       break;
+               default:
+                       break;
+               }
+       }
+
        return 0;
 }
 
@@ -206,6 +226,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
                autoc_reg |= hw->mac.link_mode_select;
 
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+               IXGBE_WRITE_FLUSH(hw);
                msleep(50);
        }
 
@@ -314,7 +335,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
                 * ixgbe_hw This will write the AUTOC register based on the new
                 * stored values
                 */
-               hw->phy.ops.setup(hw);
+               hw->mac.ops.setup_link(hw);
        }
 
        return status;
@@ -332,72 +353,18 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
  **/
 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
 {
-       s32 status;
-       u32 speed = 0;
-       bool link_up = false;
-
-       /* Set up MAC */
-       hw->phy.ops.setup(hw);
+       s32 status = 0;
 
        /* Restart autonegotiation on PHY */
-       status = hw->phy.ops.setup(hw);
-
-       /* Synchronize MAC to PHY speed */
-       if (status == 0)
-               status = hw->phy.ops.check(hw, &speed, &link_up);
-
-       return status;
-}
+       if (hw->phy.ops.setup_link)
+               status = hw->phy.ops.setup_link(hw);
 
-/**
- *  ixgbe_check_copper_link_82598 - Syncs MAC & PHY link settings
- *  @hw: pointer to hardware structure
- *  @speed: pointer to link speed
- *  @link_up: true if link is up, false otherwise
- *
- *  Reads the mac link, phy link, and synchronizes the MAC to PHY.
- **/
-static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed,
-                                        bool *link_up)
-{
-       s32 status;
-       u32 phy_speed = 0;
-       bool phy_link = false;
+       /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+       hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+       hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
 
-       /* This is the speed and link the MAC is set at */
-       hw->phy.ops.check(hw, speed, link_up);
-
-       /*
-        * Check current speed and link status of the PHY register.
-        * This is a vendor specific register and may have to
-        * be changed for other copper PHYs.
-        */
-       status = hw->phy.ops.check(hw, &phy_speed, &phy_link);
-
-       if ((status == 0) && (phy_link)) {
-               /*
-                * Check current link status of the MACs link's register
-                * matches that of the speed in the PHY register
-                */
-               if (*speed != phy_speed) {
-                       /*
-                        * The copper PHY requires 82598 attach type to be XAUI
-                        * for 10G and BX for 1G
-                        */
-                       hw->mac.link_attach_type =
-                               (IXGBE_AUTOC_10G_XAUI | IXGBE_AUTOC_1G_BX);
-
-                       /* Synchronize the MAC speed to the PHY speed */
-                       status = hw->phy.ops.setup_speed(hw, phy_speed, false,
-                                                         false);
-                       if (status == 0)
-                               hw->phy.ops.check(hw, speed, link_up);
-                       else
-                               status = IXGBE_ERR_LINK_SETUP;
-               }
-       } else {
-               *link_up = phy_link;
-       }
+       /* Set up MAC */
+       hw->mac.ops.setup_link(hw);
 
        return status;
 }
@@ -415,16 +382,19 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
                                               bool autoneg,
                                               bool autoneg_wait_to_complete)
 {
-       s32 status;
-       bool link_up = 0;
+       s32 status = 0;
 
        /* Setup the PHY according to input speed */
-       status = hw->phy.ops.setup_speed(hw, speed, autoneg,
-                                         autoneg_wait_to_complete);
+       if (hw->phy.ops.setup_link_speed)
+               status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+                                               autoneg_wait_to_complete);
+
+       /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
+       hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
+       hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
 
-       /* Synchronize MAC to PHY speed */
-       if (status == 0)
-               status = hw->phy.ops.check(hw, &speed, &link_up);
+       /* Set up MAC */
+       hw->mac.ops.setup_link(hw);
 
        return status;
 }
@@ -542,47 +512,15 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
 static struct ixgbe_mac_operations mac_ops_82598 = {
        .reset                  = &ixgbe_reset_hw_82598,
        .get_media_type         = &ixgbe_get_media_type_82598,
+       .setup_link             = &ixgbe_setup_mac_link_82598,
+       .check_link             = &ixgbe_check_mac_link_82598,
+       .setup_link_speed       = &ixgbe_setup_mac_link_speed_82598,
+       .get_link_settings      = &ixgbe_get_link_settings_82598,
 };
 
-static struct ixgbe_phy_operations phy_ops_82598EB = {
-       .setup                  = &ixgbe_setup_copper_link_82598,
-       .check                  = &ixgbe_check_copper_link_82598,
-       .setup_speed            = &ixgbe_setup_copper_link_speed_82598,
-       .get_settings           = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598EB_info = {
-       .mac                    = ixgbe_mac_82598EB,
-       .get_invariants         = &ixgbe_get_invariants_82598,
-       .mac_ops                = &mac_ops_82598,
-       .phy_ops                = &phy_ops_82598EB,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AT = {
-       .setup                  = &ixgbe_setup_tnx_phy_link,
-       .check                  = &ixgbe_check_tnx_phy_link,
-       .setup_speed            = &ixgbe_setup_tnx_phy_link_speed,
-       .get_settings           = &ixgbe_get_copper_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AT_info = {
-       .mac                    = ixgbe_mac_82598EB,
-       .get_invariants         = &ixgbe_get_invariants_82598,
-       .mac_ops                = &mac_ops_82598,
-       .phy_ops                = &phy_ops_82598AT,
-};
-
-static struct ixgbe_phy_operations phy_ops_82598AF = {
-       .setup                  = &ixgbe_setup_mac_link_82598,
-       .check                  = &ixgbe_check_mac_link_82598,
-       .setup_speed            = &ixgbe_setup_mac_link_speed_82598,
-       .get_settings           = &ixgbe_get_link_settings_82598,
-};
-
-struct ixgbe_info ixgbe_82598AF_info = {
+struct ixgbe_info ixgbe_82598_info = {
        .mac                    = ixgbe_mac_82598EB,
        .get_invariants         = &ixgbe_get_invariants_82598,
        .mac_ops                = &mac_ops_82598,
-       .phy_ops                = &phy_ops_82598AF,
 };
 
index 512e3b22ed08e9e790b25707b92035fe74d567d3..7fd6aeb1b02151791c6d1a1a433247938d0f3b3e 100644 (file)
@@ -74,7 +74,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
        ixgbe_clear_vfta(hw);
 
        /* Set up link */
-       hw->phy.ops.setup(hw);
+       hw->mac.ops.setup_link(hw);
 
        /* Clear statistics registers */
        ixgbe_clear_hw_cntrs(hw);
@@ -83,6 +83,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
        ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
        ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS;
        IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
+       IXGBE_WRITE_FLUSH(hw);
 
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
@@ -297,6 +298,7 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
        IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+       IXGBE_WRITE_FLUSH(hw);
 
        return 0;
 }
@@ -314,6 +316,7 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
        IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+       IXGBE_WRITE_FLUSH(hw);
 
        return 0;
 }
@@ -496,6 +499,7 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
        /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */
        swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);
        IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);
+       IXGBE_WRITE_FLUSH(hw);
 }
 
 /**
@@ -950,7 +954,7 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
        u32 rmcs_reg;
 
        if (packetbuf_num < 0 || packetbuf_num > 7)
-               hw_dbg(hw, "Invalid packet buffer number [%d], expected range"
+               hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
                       "is 0-7\n", packetbuf_num);
 
        frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
@@ -1132,7 +1136,7 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
 }
 
 /**
- *  ixgbe_read_analog_reg8- Reads 8 bit 82598 Atlas analog register
+ *  ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
  *  @hw: pointer to hardware structure
  *  @reg: analog register to read
  *  @val: read value
@@ -1154,7 +1158,7 @@ s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
 }
 
 /**
- *  ixgbe_write_analog_reg8- Writes 8 bit Atlas analog register
+ *  ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
  *  @hw: pointer to hardware structure
  *  @reg: atlas register to write
  *  @val: value to write
index a4e576a0c5435c3f16eccab1b7d7e35ade2ccb12..36353447716ddeedbe75095a7f3ee1c96f1ebd03 100644 (file)
@@ -96,8 +96,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
                ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
                 ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
                 (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN \
-       sizeof(ixgbe_gstrings_stats) / sizeof(struct ixgbe_stats)
+#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
 #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
 
 static int ixgbe_get_settings(struct net_device *netdev,
index a4265bc1cebb7162fbbdcbc59ffd2590f292fc9e..3732dd6c4b2a81fe5de5ed2883f51f082aa9b897 100644 (file)
@@ -54,9 +54,7 @@ static const char ixgbe_copyright[] =
         "Copyright (c) 1999-2007 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
-       [board_82598AF]                 = &ixgbe_82598AF_info,
-       [board_82598EB]                 = &ixgbe_82598EB_info,
-       [board_82598AT]                 = &ixgbe_82598AT_info,
+       [board_82598]                   = &ixgbe_82598_info,
 };
 
 /* ixgbe_pci_tbl - PCI Device ID Table
@@ -69,13 +67,13 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = {
  */
 static struct pci_device_id ixgbe_pci_tbl[] = {
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT),
-        board_82598AF },
+        board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
-        board_82598AF },
+        board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT),
-        board_82598AT },
+        board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
-        board_82598EB },
+        board_82598 },
 
        /* required last entry */
        {0, }
@@ -734,7 +732,7 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter, u32 *num_rx_queues)
 {
        struct net_device *netdev = adapter->netdev;
        int flags, err;
-       irqreturn_t(*handler) (int, void *) = &ixgbe_intr;
+       irq_handler_t handler = ixgbe_intr;
 
        flags = IRQF_SHARED;
 
@@ -1570,8 +1568,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
                dev_err(&pdev->dev, "HW Init failed\n");
                return -EIO;
        }
-       if (hw->phy.ops.setup_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
-                                  false)) {
+       if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
+                                        false)) {
                dev_err(&pdev->dev, "Link Speed setup failed\n");
                return -EIO;
        }
@@ -2038,7 +2036,7 @@ static void ixgbe_watchdog(unsigned long data)
        bool link_up;
        u32 link_speed = 0;
 
-       adapter->hw.phy.ops.check(&adapter->hw, &(link_speed), &link_up);
+       adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
 
        if (link_up) {
                if (!netif_carrier_ok(netdev)) {
@@ -2108,7 +2106,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                l4len = tcp_hdrlen(skb);
                *hdr_len += l4len;
 
-               if (skb->protocol == ntohs(ETH_P_IP)) {
+               if (skb->protocol == htons(ETH_P_IP)) {
                        struct iphdr *iph = ip_hdr(skb);
                        iph->tot_len = 0;
                        iph->check = 0;
@@ -2149,7 +2147,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
                                    IXGBE_ADVTXD_DTYP_CTXT);
 
-               if (skb->protocol == ntohs(ETH_P_IP))
+               if (skb->protocol == htons(ETH_P_IP))
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
                type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_L4T_TCP;
                context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
@@ -2204,7 +2202,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                                    IXGBE_ADVTXD_DTYP_CTXT);
 
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
-                       if (skb->protocol == ntohs(ETH_P_IP))
+                       if (skb->protocol == htons(ETH_P_IP))
                                type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
 
                        if (skb->sk->sk_protocol == IPPROTO_TCP)
@@ -2404,7 +2402,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT);
        }
 
-       if (skb->protocol == ntohs(ETH_P_IP))
+       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);
@@ -2606,7 +2604,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 
        /* Setup hw api */
        memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
-       memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
 
        err = ii->get_invariants(hw);
        if (err)
index 199e8f670f3a589cd50a680cdcc2869263e4b36a..aa3ea72e678e5d6c849de43db2419eba217d6fe5 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "ixgbe_type.h"
 
-s32 ixgbe_init_shared_code_phy(struct ixgbe_hw *hw);
 s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
 s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
 s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
index fdcde16a2a9987c0e9e504e74ddc5e6db8648039..1ad7cb9c25a84a0e934e565fb084ffdf17ecb4cc 100644 (file)
 struct ixgbe_legacy_tx_desc {
        u64 buffer_addr;       /* Address of the descriptor's data buffer */
        union {
-               u32 data;
+               __le32 data;
                struct {
-                       u16 length;    /* Data buffer length */
+                       __le16 length;    /* Data buffer length */
                        u8 cso; /* Checksum offset */
                        u8 cmd; /* Descriptor control */
                } flags;
        } lower;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 css; /* Checksum start */
-                       u16 vlan;
+                       __le16 vlan;
                } fields;
        } upper;
 };
@@ -1023,61 +1023,61 @@ struct ixgbe_legacy_tx_desc {
 /* Transmit Descriptor - Advanced */
 union ixgbe_adv_tx_desc {
        struct {
-               u64 buffer_addr;       /* Address of descriptor's data buf */
-               u32 cmd_type_len;
-               u32 olinfo_status;
+               __le64 buffer_addr;       /* Address of descriptor's data buf */
+               __le32 cmd_type_len;
+               __le32 olinfo_status;
        } read;
        struct {
-               u64 rsvd;       /* Reserved */
-               u32 nxtseq_seed;
-               u32 status;
+               __le64 rsvd;       /* Reserved */
+               __le32 nxtseq_seed;
+               __le32 status;
        } wb;
 };
 
 /* Receive Descriptor - Legacy */
 struct ixgbe_legacy_rx_desc {
-       u64 buffer_addr; /* Address of the descriptor's data buffer */
-       u16 length;      /* Length of data DMAed into data buffer */
+       __le64 buffer_addr; /* Address of the descriptor's data buffer */
+       __le16 length;      /* Length of data DMAed into data buffer */
        u16 csum;        /* Packet checksum */
        u8 status;       /* Descriptor status */
        u8 errors;       /* Descriptor Errors */
-       u16 vlan;
+       __le16 vlan;
 };
 
 /* Receive Descriptor - Advanced */
 union ixgbe_adv_rx_desc {
        struct {
-               u64 pkt_addr; /* Packet buffer address */
-               u64 hdr_addr; /* Header buffer address */
+               __le64 pkt_addr; /* Packet buffer address */
+               __le64 hdr_addr; /* Header buffer address */
        } read;
        struct {
                struct {
                        struct {
-                               u16 pkt_info; /* RSS type, Packet type */
-                               u16 hdr_info; /* Split Header, header len */
+                               __le16 pkt_info; /* RSS type, Packet type */
+                               __le16 hdr_info; /* Split Header, header len */
                        } lo_dword;
                        union {
-                               u32 rss; /* RSS Hash */
+                               __le32 rss; /* RSS Hash */
                                struct {
-                                       u16 ip_id; /* IP id */
+                                       __le16 ip_id; /* IP id */
                                        u16 csum; /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error; /* ext status/error */
-                       u16 length; /* Packet length */
-                       u16 vlan; /* VLAN tag */
+                       __le32 status_error; /* ext status/error */
+                       __le16 length; /* Packet length */
+                       __le16 vlan; /* VLAN tag */
                } upper;
        } wb;  /* writeback */
 };
 
 /* Context descriptors */
 struct ixgbe_adv_tx_context_desc {
-       u32 vlan_macip_lens;
-       u32 seqnum_seed;
-       u32 type_tucmd_mlhl;
-       u32 mss_l4len_idx;
+       __le32 vlan_macip_lens;
+       __le32 seqnum_seed;
+       __le32 type_tucmd_mlhl;
+       __le32 mss_l4len_idx;
 };
 
 /* Adv Transmit Descriptor Config Masks */
@@ -1244,13 +1244,16 @@ struct ixgbe_hw;
 struct ixgbe_mac_operations {
        s32 (*reset)(struct ixgbe_hw *);
        enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+       s32 (*setup_link)(struct ixgbe_hw *);
+       s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+       s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
+       s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
 };
 
 struct ixgbe_phy_operations {
-       s32 (*setup)(struct ixgbe_hw *);
-       s32 (*check)(struct ixgbe_hw *, u32 *, bool *);
-       s32 (*setup_speed)(struct ixgbe_hw *, u32, bool, bool);
-       s32 (*get_settings)(struct ixgbe_hw *, u32 *, bool *);
+       s32 (*setup_link)(struct ixgbe_hw *);
+       s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
+       s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
 };
 
 struct ixgbe_mac_info {
@@ -1267,7 +1270,6 @@ struct ixgbe_mac_info {
        bool                            link_settings_loaded;
 };
 
-
 struct ixgbe_eeprom_info {
        enum ixgbe_eeprom_type          type;
        u16                             word_size;
@@ -1290,7 +1292,6 @@ struct ixgbe_info {
        enum ixgbe_mac_type             mac;
        s32                             (*get_invariants)(struct ixgbe_hw *);
        struct ixgbe_mac_operations     *mac_ops;
-       struct ixgbe_phy_operations     *phy_ops;
 };
 
 struct ixgbe_hw {
index fa147cd5d68c07e2b8e434ffad5db9c55891b58d..f2a6e713224153bb5e6861aebce481089d227597 100644 (file)
@@ -64,8 +64,6 @@ struct pcpu_lstats {
        unsigned long bytes;
 };
 
-#define LOOPBACK_OVERHEAD (128 + MAX_HEADER + 16 + 16)
-
 /* KISS: just allocate small chunks and copy bits.
  *
  * So, in fact, this is documentation, explaining what we expect
index c5095ecd8b116a5eea41ff799c27bf415c5bd597..591a7e4220c75058d7f1361d36f60d61274e10af 100644 (file)
@@ -1144,14 +1144,13 @@ i596_handle_CU_completion(struct net_device *dev,
 }
 
 static irqreturn_t
-i596_interrupt (int irq, void *dev_instance) {
-       struct net_device *dev = (struct net_device *) dev_instance;
-       struct i596_private *lp;
+i596_interrupt(int irq, void *dev_instance)
+{
+       struct net_device *dev = dev_instance;
+       struct i596_private *lp = dev->priv;
        unsigned short status, ack_cmd = 0;
        int frames_in = 0;
 
-       lp = (struct i596_private *) dev->priv;
-
        /*
         * The 82596 examines the command, performs the required action,
         * and then clears the SCB command word.
index a19b5958cee949e89548bbb50acf7768ac44de2f..2a66e5b7cebcbc0217b9bef6aad9b434f9d62242 100644 (file)
@@ -289,7 +289,7 @@ struct net_device * __init mac89x0_probe(int unit)
        err = register_netdev(dev);
        if (err)
                goto out1;
-       return 0;
+       return NULL;
 out1:
        nubus_writew(0, dev->base_addr + ADD_PORT);
 out:
index 95ebe72f320f0ee1cb9ec1c17b8fb661b527f3d1..451acdca2a214a97068b46f597930b25d2e05f87 100644 (file)
@@ -409,7 +409,7 @@ static inline void mace_clean_rings(struct mace_data *mp)
 
     /* free some skb's */
     for (i = 0; i < N_RX_RING; ++i) {
-       if (mp->rx_bufs[i] != 0) {
+       if (mp->rx_bufs[i] != NULL) {
            dev_kfree_skb(mp->rx_bufs[i]);
            mp->rx_bufs[i] = NULL;
        }
@@ -441,7 +441,7 @@ static int mace_open(struct net_device *dev)
     cp = mp->rx_cmds;
     for (i = 0; i < N_RX_RING - 1; ++i) {
        skb = dev_alloc_skb(RX_BUFLEN + 2);
-       if (skb == 0) {
+       if (!skb) {
            data = dummy_buf;
        } else {
            skb_reserve(skb, 2);        /* so IP header lands on 4-byte bdry */
@@ -903,7 +903,7 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
        out_le16(&cp->command, DBDMA_STOP);
        /* got a packet, have a look at it */
        skb = mp->rx_bufs[i];
-       if (skb == 0) {
+       if (!skb) {
            ++dev->stats.rx_dropped;
        } else if (nb > 8) {
            data = skb->data;
@@ -953,9 +953,9 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id)
            break;
        cp = mp->rx_cmds + i;
        skb = mp->rx_bufs[i];
-       if (skb == 0) {
+       if (!skb) {
            skb = dev_alloc_skb(RX_BUFLEN + 2);
-           if (skb != 0) {
+           if (skb) {
                skb_reserve(skb, 2);
                mp->rx_bufs[i] = skb;
            }
index e8dc2f44fec960d9d3b58127699e5a4ed9eee838..6ef6b8b39e71dd5001d1f87c5bc3753ba045b790 100644 (file)
@@ -73,8 +73,6 @@ static void macvlan_broadcast(struct sk_buff *skb,
        for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
                hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
                        dev = vlan->dev;
-                       if (unlikely(!(dev->flags & IFF_UP)))
-                               continue;
 
                        nskb = skb_clone(skb, GFP_ATOMIC);
                        if (nskb == NULL) {
@@ -215,6 +213,29 @@ static int macvlan_stop(struct net_device *dev)
        return 0;
 }
 
+static int macvlan_set_mac_address(struct net_device *dev, void *p)
+{
+       struct macvlan_dev *vlan = netdev_priv(dev);
+       struct net_device *lowerdev = vlan->lowerdev;
+       struct sockaddr *addr = p;
+       int err;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (!(dev->flags & IFF_UP))
+               goto out;
+
+       err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN);
+       if (err < 0)
+               return err;
+       dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+
+out:
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       return 0;
+}
+
 static void macvlan_change_rx_flags(struct net_device *dev, int change)
 {
        struct macvlan_dev *vlan = netdev_priv(dev);
@@ -302,6 +323,7 @@ static void macvlan_setup(struct net_device *dev)
        dev->stop               = macvlan_stop;
        dev->change_mtu         = macvlan_change_mtu;
        dev->change_rx_flags    = macvlan_change_rx_flags;
+       dev->set_mac_address    = macvlan_set_mac_address;
        dev->set_multicast_list = macvlan_set_multicast_list;
        dev->hard_start_xmit    = macvlan_hard_start_xmit;
        dev->destructor         = free_netdev;
@@ -353,7 +375,7 @@ static void macvlan_transfer_operstate(struct net_device *dev)
                if (!netif_carrier_ok(dev))
                        netif_carrier_on(dev);
        } else {
-               if (netif_carrier_ok(lowerdev))
+               if (netif_carrier_ok(dev))
                        netif_carrier_off(dev);
        }
 }
index c90958f6d3fe8a807976c79a8a1734b186969f1d..cead81e80f0c84dfcc443e0eb1466f09664f0f71 100644 (file)
@@ -185,7 +185,7 @@ struct myri10ge_priv {
        dma_addr_t fw_stats_bus;
        struct pci_dev *pdev;
        int msi_enabled;
-       __be32 link_state;
+       u32 link_state;
        unsigned int rdma_tags_available;
        int intr_coal_delay;
        __be32 __iomem *intr_coal_delay_ptr;
@@ -576,7 +576,7 @@ static int myri10ge_adopt_running_firmware(struct myri10ge_priv *mgp)
        int status;
 
        /* find running firmware header */
-       hdr_offset = ntohl(__raw_readl(mgp->sram + MCP_HEADER_PTR_OFFSET));
+       hdr_offset = swab32(readl(mgp->sram + MCP_HEADER_PTR_OFFSET));
 
        if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > mgp->sram_size) {
                dev_err(dev, "Running firmware has bad header offset (%d)\n",
@@ -1053,7 +1053,10 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
                rx_frags[0].size -= MXGEFW_PAD;
                len -= MXGEFW_PAD;
                lro_receive_frags(&mgp->rx_done.lro_mgr, rx_frags,
-                                 len, len, (void *)(unsigned long)csum, csum);
+                                 len, len,
+                                /* opaque, will come back in get_frag_header */
+                                 (void *)(__force unsigned long)csum,
+                                 csum);
                return 1;
        }
 
@@ -1431,7 +1434,7 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
 };
 
 #define MYRI10GE_NET_STATS_LEN      21
-#define MYRI10GE_STATS_LEN  sizeof(myri10ge_gstrings_stats) / ETH_GSTRING_LEN
+#define MYRI10GE_STATS_LEN     ARRAY_SIZE(myri10ge_gstrings_stats)
 
 static void
 myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
@@ -1786,7 +1789,8 @@ myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
        struct iphdr *iph;
        u8 *va = page_address(frag->page) + frag->page_offset;
        unsigned long ll_hlen;
-       __wsum csum = (__wsum) (unsigned long)priv;
+       /* passed opaque through lro_receive_frags() */
+       __wsum csum = (__force __wsum) (unsigned long)priv;
 
        /* find the mac header, aborting if not IPv4 */
 
@@ -1967,7 +1971,7 @@ static int myri10ge_open(struct net_device *dev)
                goto abort_with_rings;
        }
 
-       mgp->link_state = htonl(~0U);
+       mgp->link_state = ~0U;
        mgp->rdma_tags_available = 15;
 
        lro_mgr = &mgp->rx_done.lro_mgr;
index 5ffbb88916473d45e6e60d1d3b57b22ec3651ee5..31e047dd7bb349d7e38d394c02e6a041f6ee29df 100644 (file)
@@ -306,9 +306,11 @@ static ssize_t show_remote_ip(struct netconsole_target *nt, char *buf)
 
 static ssize_t show_local_mac(struct netconsole_target *nt, char *buf)
 {
+       struct net_device *dev = nt->np.dev;
+
        DECLARE_MAC_BUF(mac);
        return snprintf(buf, PAGE_SIZE, "%s\n",
-                       print_mac(mac, nt->np.local_mac));
+                       print_mac(mac, dev->dev_addr));
 }
 
 static ssize_t show_remote_mac(struct netconsole_target *nt, char *buf)
@@ -667,7 +669,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
        struct netconsole_target *nt;
        struct net_device *dev = ptr;
 
-       if (!(event == NETDEV_CHANGEADDR || event == NETDEV_CHANGENAME))
+       if (!(event == NETDEV_CHANGENAME))
                goto done;
 
        spin_lock_irqsave(&target_list_lock, flags);
@@ -675,10 +677,6 @@ static int netconsole_netdev_event(struct notifier_block *this,
                netconsole_target_get(nt);
                if (nt->np.dev == dev) {
                        switch (event) {
-                       case NETDEV_CHANGEADDR:
-                               memcpy(nt->np.local_mac, dev->dev_addr, ETH_ALEN);
-                               break;
-
                        case NETDEV_CHANGENAME:
                                strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
                                break;
index a8f63c47b3cd5bcf5cf41826e078cffa7c7c2767..2bc5eaae141fd083a19e4d80c08add20d2d2ee5b 100644 (file)
 #define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
 extern struct workqueue_struct *netxen_workq;
 
-/* 
- * normalize a 64MB crb address to 32MB PCI window 
+/*
+ * normalize a 64MB crb address to 32MB PCI window
  * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1
  */
 #define NETXEN_CRB_NORMAL(reg) \
@@ -736,11 +736,11 @@ struct netxen_skb_frag {
        (config_word) &= ~__tmask;      \
        (config_word) |= (((__tvalue) << (start)) & __tmask); \
 }
-       
+
 #define _netxen_clear_bits(config_word, start, bits) {\
        unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start));  \
        (config_word) &= ~__tmask; \
-}              
+}
 
 /*    Following defines are for the state of the buffers    */
 #define        NETXEN_BUFFER_FREE      0
@@ -879,7 +879,7 @@ struct netxen_dummy_dma {
 
 struct netxen_adapter {
        struct netxen_hardware_context ahw;
-       
+
        struct netxen_adapter *master;
        struct net_device *netdev;
        struct pci_dev *pdev;
@@ -898,7 +898,7 @@ struct netxen_adapter {
        u32 curr_window;
 
        u32 cmd_producer;
-       u32 *cmd_consumer;
+       __le32 *cmd_consumer;
 
        u32 last_cmd_consumer;
        u32 max_tx_desc_count;
@@ -916,7 +916,7 @@ struct netxen_adapter {
        u32 temp;
 
        struct netxen_adapter_stats stats;
-       
+
        u16 portno;
        u16 link_speed;
        u16 link_duplex;
@@ -1018,14 +1018,8 @@ 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);
 int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter);
-int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter);
 void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter);
 void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter);
-void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port,
-                                long enable);
-void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port,
-                                 long enable);
 int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                            __u32 * readval);
 int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
@@ -1048,7 +1042,6 @@ int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
                           int len);
 void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
                                 unsigned long off, int data);
-int netxen_nic_erase_pxe(struct netxen_adapter *adapter);
 
 /* Functions from netxen_nic_init.c */
 void netxen_free_adapter_offload(struct netxen_adapter *adapter);
@@ -1057,9 +1050,9 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
 int netxen_load_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);
-int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, 
+int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
                                u8 *bytes, size_t size);
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, 
+int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
                                u8 *bytes, size_t size);
 int netxen_flash_unlock(struct netxen_adapter *adapter);
 int netxen_backup_crbinit(struct netxen_adapter *adapter);
@@ -1067,15 +1060,10 @@ int netxen_flash_erase_secondary(struct netxen_adapter *adapter);
 int netxen_flash_erase_primary(struct netxen_adapter *adapter);
 void netxen_halt_pegs(struct netxen_adapter *adapter);
 
-int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data);
 int netxen_rom_se(struct netxen_adapter *adapter, int addr);
-int netxen_do_rom_se(struct netxen_adapter *adapter, int addr);
 
 /* Functions from netxen_nic_isr.c */
 int netxen_nic_link_ok(struct netxen_adapter *adapter);
-void netxen_nic_isr_other(struct netxen_adapter *adapter);
-void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link);
-void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable);
 void netxen_initialize_adapter_sw(struct netxen_adapter *adapter);
 void netxen_initialize_adapter_hw(struct netxen_adapter *adapter);
 void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
@@ -1092,8 +1080,6 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
                            u32 ringid);
-void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx,
-                                u32 ringid);
 int netxen_process_cmd_ring(unsigned long data);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
 void netxen_nic_set_multi(struct net_device *netdev);
@@ -1209,7 +1195,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
                                int *valp);
index cfb847b0cae3e44d9ead99eb2b49492954f22e33..7a876f4b8db24f27a9ad67f20a809a3b7b8584a0 100644 (file)
@@ -86,7 +86,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = {
        "Link_Test_on_offline"
 };
 
-#define NETXEN_NIC_TEST_LEN sizeof(netxen_nic_gstrings_test) / ETH_GSTRING_LEN
+#define NETXEN_NIC_TEST_LEN    ARRAY_SIZE(netxen_nic_gstrings_test)
 
 #define NETXEN_NIC_REGS_COUNT 42
 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32))
@@ -423,11 +423,11 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (eeprom->len == 0)
                return -EINVAL;
 
-       eeprom->magic = (adapter->pdev)->vendor | 
+       eeprom->magic = (adapter->pdev)->vendor |
                        ((adapter->pdev)->device << 16);
        offset = eeprom->offset;
 
-       ret = netxen_rom_fast_read_words(adapter, offset, bytes, 
+       ret = netxen_rom_fast_read_words(adapter, offset, bytes,
                                                eeprom->len);
        if (ret < 0)
                return ret;
@@ -453,16 +453,16 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                                netxen_nic_driver_name);
                        return ret;
                }
-               printk(KERN_INFO "%s: flash unlocked. \n", 
+               printk(KERN_INFO "%s: flash unlocked. \n",
                        netxen_nic_driver_name);
                last_schedule_time = jiffies;
                ret = netxen_flash_erase_secondary(adapter);
                if (ret != FLASH_SUCCESS) {
-                       printk(KERN_ERR "%s: Flash erase failed.\n", 
+                       printk(KERN_ERR "%s: Flash erase failed.\n",
                                netxen_nic_driver_name);
                        return ret;
                }
-               printk(KERN_INFO "%s: secondary flash erased successfully.\n", 
+               printk(KERN_INFO "%s: secondary flash erased successfully.\n",
                        netxen_nic_driver_name);
                flash_start = 1;
                return 0;
@@ -471,7 +471,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (offset == NETXEN_BOOTLD_START) {
                ret = netxen_flash_erase_primary(adapter);
                if (ret != FLASH_SUCCESS) {
-                       printk(KERN_ERR "%s: Flash erase failed.\n", 
+                       printk(KERN_ERR "%s: Flash erase failed.\n",
                                netxen_nic_driver_name);
                        return ret;
                }
@@ -483,16 +483,16 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
                if (ret != FLASH_SUCCESS)
                        return ret;
 
-               printk(KERN_INFO "%s: primary flash erased successfully\n", 
+               printk(KERN_INFO "%s: primary flash erased successfully\n",
                        netxen_nic_driver_name);
 
                ret = netxen_backup_crbinit(adapter);
                if (ret != FLASH_SUCCESS) {
-                       printk(KERN_ERR "%s: CRBinit backup failed.\n", 
+                       printk(KERN_ERR "%s: CRBinit backup failed.\n",
                                netxen_nic_driver_name);
                        return ret;
                }
-               printk(KERN_INFO "%s: CRBinit backup done.\n", 
+               printk(KERN_INFO "%s: CRBinit backup done.\n",
                        netxen_nic_driver_name);
                ready_to_flash = 1;
        }
@@ -570,7 +570,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
                else
                        pause->tx_pause = !(netxen_xg_get_xg1_mask(val));
        } else {
-               printk(KERN_ERR"%s: Unknown board type: %x\n", 
+               printk(KERN_ERR"%s: Unknown board type: %x\n",
                                netxen_nic_driver_name, adapter->ahw.board_type);
        }
 }
@@ -589,7 +589,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                /* set flow control */
                netxen_nic_read_w0(adapter,
                                        NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
-               
+
                if (pause->rx_pause)
                        netxen_gb_rx_flowctl(val);
                else
@@ -642,10 +642,10 @@ 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);                     
+               netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
        } else {
                printk(KERN_ERR "%s: Unknown board type: %x\n",
-                               netxen_nic_driver_name, 
+                               netxen_nic_driver_name,
                                adapter->ahw.board_type);
        }
        return 0;
index 2c19b8df98fab06c205d26afbf513b019856e670..01355701bf8ecb9701d2f2d4b46186b774d1bf82 100644 (file)
@@ -33,7 +33,6 @@
 
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
-#define DEFINE_GLOBAL_RECV_CRB
 #include "netxen_nic_phan_reg.h"
 
 
@@ -161,7 +160,7 @@ struct netxen_recv_crb recv_crb_registers[] = {
            },
            /* Jumbo frames */
            {
-           /* crb_rcv_producer_offset: */                  
+           /* crb_rcv_producer_offset: */
            NETXEN_NIC_REG(0x1f8),
            /* crb_rcv_consumer_offset: */
            NETXEN_NIC_REG(0x1fc),
@@ -210,7 +209,7 @@ struct netxen_recv_crb recv_crb_registers[] = {
            },
            /* Jumbo frames */
            {
-           /* crb_rcv_producer_offset: */ 
+           /* crb_rcv_producer_offset: */
            NETXEN_NIC_REG(0x23c),
            /* crb_rcv_consumer_offset: */
            NETXEN_NIC_REG(0x240),
@@ -244,12 +243,15 @@ struct netxen_recv_crb recv_crb_registers[] = {
        },
 };
 
-u64 ctx_addr_sig_regs[][3] = {
+static u64 ctx_addr_sig_regs[][3] = {
        {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)},
        {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)},
        {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)},
        {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)}
 };
+#define CRB_CTX_ADDR_REG_LO(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][0])
+#define CRB_CTX_ADDR_REG_HI(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][2])
+#define CRB_CTX_SIGNATURE_REG(FUNC_ID)         (ctx_addr_sig_regs[FUNC_ID][1])
 
 
 /*  PCI Windowing for DDR regions.  */
@@ -279,8 +281,8 @@ u64 ctx_addr_sig_regs[][3] = {
 
 #define NETXEN_NIC_WINDOW_MARGIN 0x100000
 
-unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                                       unsigned long long addr);
+static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
+                                              unsigned long long addr);
 void netxen_free_hw_resources(struct netxen_adapter *adapter);
 
 int netxen_nic_set_mac(struct net_device *netdev, void *p)
@@ -417,7 +419,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
        adapter->ctx_desc->cmd_consumer_offset =
            cpu_to_le64(adapter->ctx_desc_phys_addr +
                        sizeof(struct netxen_ring_ctx));
-       adapter->cmd_consumer = (uint32_t *) (((char *)addr) +
+       adapter->cmd_consumer = (__le32 *) (((char *)addr) +
                                              sizeof(struct netxen_ring_ctx));
 
        addr = netxen_alloc(adapter->ahw.pdev,
@@ -584,35 +586,35 @@ int netxen_is_flash_supported(struct netxen_adapter *adapter)
 }
 
 static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
-                                 int size, u32 * buf)
+                                 int size, __le32 * buf)
 {
        int i, addr;
-       u32 *ptr32;
+       __le32 *ptr32;
+       u32 v;
 
        addr = base;
        ptr32 = buf;
        for (i = 0; i < size / sizeof(u32); i++) {
-               if (netxen_rom_fast_read(adapter, addr, ptr32) == -1)
+               if (netxen_rom_fast_read(adapter, addr, &v) == -1)
                        return -1;
-               *ptr32 = cpu_to_le32(*ptr32);
+               *ptr32 = cpu_to_le32(v);
                ptr32++;
                addr += sizeof(u32);
        }
        if ((char *)buf + size > (char *)ptr32) {
-               u32 local;
-
-               if (netxen_rom_fast_read(adapter, addr, &local) == -1)
+               __le32 local;
+               if (netxen_rom_fast_read(adapter, addr, &v) == -1)
                        return -1;
-               local = cpu_to_le32(local);
+               local = cpu_to_le32(v);
                memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
        }
 
        return 0;
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
 {
-       u32 *pmac = (u32 *) & mac[0];
+       __le32 *pmac = (__le32 *) & mac[0];
 
        if (netxen_get_flash_block(adapter,
                                   NETXEN_USER_START +
@@ -621,7 +623,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
                                   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
                return -1;
        }
-       if (*mac == ~0ULL) {
+       if (*mac == cpu_to_le64(~0ULL)) {
                if (netxen_get_flash_block(adapter,
                                           NETXEN_USER_START_OLD +
                                           offsetof(struct netxen_user_old_info,
@@ -629,7 +631,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[])
                                           FLASH_NUM_PORTS * sizeof(u64),
                                           pmac) == -1)
                        return -1;
-               if (*mac == ~0ULL)
+               if (*mac == cpu_to_le64(~0ULL))
                        return -1;
        }
        return 0;
@@ -664,7 +666,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
                                        NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3));
                        break;
                default:
-                       printk(KERN_INFO "Changing the window for PCI function"
+                       printk(KERN_INFO "Changing the window for PCI function "
                                        "%d\n", adapter->ahw.pci_func);
                        offset = PCI_OFFSET_SECOND_RANGE(adapter,
                                        NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW));
@@ -886,11 +888,10 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
        netxen_nic_pci_change_crbwindow(adapter, 1);
 }
 
-int netxen_pci_set_window_warning_count = 0;
+static int netxen_pci_set_window_warning_count;
 
-unsigned long
-netxen_nic_pci_set_window(struct netxen_adapter *adapter,
-                         unsigned long long addr)
+static  unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter,
+                                               unsigned long long addr)
 {
        static int ddr_mn_window = -1;
        static int qdr_sn_window = -1;
@@ -952,16 +953,18 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter,
        return addr;
 }
 
+#if 0
 int
 netxen_nic_erase_pxe(struct netxen_adapter *adapter)
 {
        if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) {
-               printk(KERN_ERR "%s: erase pxe failed\n", 
+               printk(KERN_ERR "%s: erase pxe failed\n",
                        netxen_nic_driver_name);
                return -1;
        }
        return 0;
 }
+#endif  /*  0  */
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 {
@@ -1036,9 +1039,9 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
        new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
        if (physical_port[adapter->portnum] == 0)
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, 
+               netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
                                new_mtu);
-       else 
+       else
                netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
                                new_mtu);
        return 0;
index 245bf13c7ba2a5bbcc009be9fc34f35256a31344..a3ea1dd98c41562ed9b9f790279f7185584fc506 100644 (file)
@@ -235,7 +235,7 @@ typedef enum {
        ((config_word) |= 1 << 0)
 #define netxen_xg_set_xg1_mask(config_word)    \
        ((config_word) |= 1 << 3)
-               
+
 #define netxen_xg_get_xg0_mask(config_word)    \
        _netxen_crb_get_bit((config_word), 0)
 #define netxen_xg_get_xg1_mask(config_word)    \
@@ -273,7 +273,7 @@ typedef enum {
        _netxen_crb_get_bit((config_word), 4)
 #define netxen_gb_get_gb3_mask(config_word)    \
        _netxen_crb_get_bit((config_word), 6)
-       
+
 #define netxen_gb_unset_gb0_mask(config_word)  \
        ((config_word) &= ~(1 << 0))
 #define netxen_gb_unset_gb1_mask(config_word)  \
@@ -437,7 +437,7 @@ typedef enum {
 
 /*
  * NIU GB Drop CRC Register
- * 
+ *
  * Bit 0 : drop_gb0 => 1:drop pkts with bad CRCs, 0:pass them on
  * Bit 1 : drop_gb1 => 1:drop pkts with bad CRCs, 0:pass them on
  * Bit 2 : drop_gb2 => 1:drop pkts with bad CRCs, 0:pass them on
@@ -480,7 +480,7 @@ typedef enum {
 
 /*
  * MAC Control Register
- * 
+ *
  * Bit 0-1   : id_pool0
  * Bit 2     : enable_xtnd0
  * Bit 4-5   : id_pool1
@@ -515,20 +515,16 @@ typedef enum {
                ((config) |= (((val) & 0x0f) << 28))
 
 /* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 
+int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                                    netxen_niu_prom_mode_t mode);
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
                                       netxen_niu_prom_mode_t mode);
 
-/* get/set the MAC address for a given MAC */
-int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
-                          netxen_ethernet_macaddr_t * addr);
+/* set the MAC address for a given MAC */
 int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
                           netxen_ethernet_macaddr_t addr);
 
-/* XG versons */
-int netxen_niu_xg_macaddr_get(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);
 
index 485ff93989109360f6db7d2607e0892c029146e0..9e38bcb3fba9ac7fe1d25f28015cbd231d4a936e 100644 (file)
@@ -54,13 +54,17 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
 
 #define NETXEN_NIC_XDMA_RESET 0x8000ff
 
-static inline void
-netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
-                           unsigned long off, int *data)
+static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+                                       uint32_t ctx, uint32_t ringid);
+
+#if 0
+static void netxen_nic_locked_write_reg(struct netxen_adapter *adapter,
+                                       unsigned long off, int *data)
 {
        void __iomem *addr = pci_base_offset(adapter, off);
        writel(*data, addr);
 }
+#endif  /*  0  */
 
 static void crb_addr_transform_setup(void)
 {
@@ -255,7 +259,7 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
  * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB
  * address to external PCI CRB address.
  */
-u32 netxen_decode_crb_addr(u32 addr)
+static u32 netxen_decode_crb_addr(u32 addr)
 {
        int i;
        u32 base_addr, offset, pci_base;
@@ -282,7 +286,7 @@ static long rom_max_timeout = 100;
 static long rom_lock_timeout = 10000;
 static long rom_write_timeout = 700;
 
-static inline int rom_lock(struct netxen_adapter *adapter)
+static int rom_lock(struct netxen_adapter *adapter)
 {
        int iter;
        u32 done = 0;
@@ -312,7 +316,7 @@ static inline int rom_lock(struct netxen_adapter *adapter)
        return 0;
 }
 
-int netxen_wait_rom_done(struct netxen_adapter *adapter)
+static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 {
        long timeout = 0;
        long done = 0;
@@ -329,7 +333,7 @@ int netxen_wait_rom_done(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline int netxen_rom_wren(struct netxen_adapter *adapter)
+static int netxen_rom_wren(struct netxen_adapter *adapter)
 {
        /* Set write enable latch in ROM status register */
        netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
@@ -341,15 +345,15 @@ static inline int netxen_rom_wren(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
-                                          unsigned int addr)
+static unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter,
+                                   unsigned int addr)
 {
        unsigned int data = 0xdeaddead;
        data = netxen_nic_reg_read(adapter, addr);
        return data;
 }
 
-static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
+static int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
 {
        netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE,
                             M25P_INSTR_RDSR);
@@ -359,7 +363,7 @@ static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter)
        return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
 }
 
-static inline void netxen_rom_unlock(struct netxen_adapter *adapter)
+static void netxen_rom_unlock(struct netxen_adapter *adapter)
 {
        u32 val;
 
@@ -368,7 +372,7 @@ static inline void netxen_rom_unlock(struct netxen_adapter *adapter)
 
 }
 
-int netxen_rom_wip_poll(struct netxen_adapter *adapter)
+static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
 {
        long timeout = 0;
        long wip = 1;
@@ -385,8 +389,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
-                                   int data)
+static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
+                            int data)
 {
        if (netxen_rom_wren(adapter)) {
                return -1;
@@ -404,8 +408,8 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
        return netxen_rom_wip_poll(adapter);
 }
 
-static inline int
-do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
+static int do_rom_fast_read(struct netxen_adapter *adapter,
+                           int addr, int *valp)
 {
        cond_resched();
 
@@ -427,18 +431,18 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
        return 0;
 }
 
-static inline int 
-do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
-                       u8 *bytes, size_t size)
+static int do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
+                                 u8 *bytes, size_t size)
 {
        int addridx;
        int ret = 0;
 
        for (addridx = addr; addridx < (addr + size); addridx += 4) {
-               ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
+               int v;
+               ret = do_rom_fast_read(adapter, addridx, &v);
                if (ret != 0)
                        break;
-               *(int *)bytes = cpu_to_le32(*(int *)bytes);
+               *(__le32 *)bytes = cpu_to_le32(v);
                bytes += 4;
        }
 
@@ -446,7 +450,7 @@ do_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
 }
 
 int
-netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, 
+netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
                                u8 *bytes, size_t size)
 {
        int ret;
@@ -473,6 +477,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
        return ret;
 }
 
+#if 0
 int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
 {
        int ret = 0;
@@ -484,9 +489,10 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data)
        netxen_rom_unlock(adapter);
        return ret;
 }
+#endif  /*  0  */
 
-static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, 
-                                               int addr, u8 *bytes, size_t size)
+static int do_rom_fast_write_words(struct netxen_adapter *adapter,
+                                  int addr, u8 *bytes, size_t size)
 {
        int addridx = addr;
        int ret = 0;
@@ -496,11 +502,11 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
                int timeout = 0;
                int data;
 
-               data = le32_to_cpu((*(u32*)bytes));
+               data = le32_to_cpu((*(__le32*)bytes));
                ret = do_rom_fast_write(adapter, addridx, data);
                if (ret < 0)
                        return ret;
-                       
+
                while(1) {
                        int data1;
 
@@ -513,7 +519,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
 
                        if (timeout++ >= rom_write_timeout) {
                                if (last_attempt++ < 4) {
-                                       ret = do_rom_fast_write(adapter, 
+                                       ret = do_rom_fast_write(adapter,
                                                                addridx, data);
                                        if (ret < 0)
                                                return ret;
@@ -533,7 +539,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter,
        return ret;
 }
 
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, 
+int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
                                        u8 *bytes, size_t size)
 {
        int ret = 0;
@@ -548,7 +554,7 @@ int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
        return ret;
 }
 
-int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
+static int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
 {
        int ret;
 
@@ -557,7 +563,7 @@ int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
                return ret;
 
        netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
-       netxen_crb_writelit_adapter(adapter, 
+       netxen_crb_writelit_adapter(adapter,
                                        NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
 
        ret = netxen_wait_rom_done(adapter);
@@ -567,7 +573,7 @@ int netxen_rom_wrsr(struct netxen_adapter *adapter, int data)
        return netxen_rom_wip_poll(adapter);
 }
 
-int netxen_rom_rdsr(struct netxen_adapter *adapter)
+static int netxen_rom_rdsr(struct netxen_adapter *adapter)
 {
        int ret;
 
@@ -587,7 +593,7 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter)
        char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
 
        if (!buffer)
-               return -ENOMEM; 
+               return -ENOMEM;
        /* unlock sector 63 */
        val = netxen_rom_rdsr(adapter);
        val = val & 0xe3;
@@ -600,12 +606,12 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter)
                goto out_kfree;
 
        /* copy  sector 0 to sector 63 */
-       ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START, 
+       ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
                                        buffer, NETXEN_FLASH_SECTOR_SIZE);
        if (ret != FLASH_SUCCESS)
                goto out_kfree;
 
-       ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START, 
+       ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
                                        buffer, NETXEN_FLASH_SECTOR_SIZE);
        if (ret != FLASH_SUCCESS)
                goto out_kfree;
@@ -632,7 +638,7 @@ out_kfree:
        return ret;
 }
 
-int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
+static int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
 {
        netxen_rom_wren(adapter);
        netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
@@ -646,16 +652,16 @@ int netxen_do_rom_se(struct netxen_adapter *adapter, int addr)
        return netxen_rom_wip_poll(adapter);
 }
 
-void check_erased_flash(struct netxen_adapter *adapter, int addr)
+static void check_erased_flash(struct netxen_adapter *adapter, int addr)
 {
        int i;
        int val;
        int count = 0, erased_errors = 0;
        int range;
 
-       range = (addr == NETXEN_USER_START) ? 
+       range = (addr == NETXEN_USER_START) ?
                NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
-       
+
        for (i = addr; i < range; i += 4) {
                netxen_rom_fast_read(adapter, i, &val);
                if (val != 0xffffffff)
@@ -682,8 +688,8 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr)
        return ret;
 }
 
-int
-netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end)
+static int netxen_flash_erase_sections(struct netxen_adapter *adapter,
+                                      int start, int end)
 {
        int ret = FLASH_SUCCESS;
        int i;
@@ -990,7 +996,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline int netxen_nic_check_temp(struct netxen_adapter *adapter)
+static int netxen_nic_check_temp(struct netxen_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
        uint32_t temp, temp_state, temp_val;
@@ -1064,9 +1070,8 @@ void netxen_watchdog_task(struct work_struct *work)
  * and if the number of receives exceeds RX_BUFFERS_REFILL, then we
  * invoke the routine to send more rx buffers to the Phantom...
  */
-void
-netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
-                  struct status_desc *desc)
+static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
+                              struct status_desc *desc)
 {
        struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
@@ -1103,8 +1108,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
                }
                if (buffer->lro_current_frags != buffer->lro_expected_frags) {
                        if (buffer->lro_expected_frags != 0) {
-                               printk("LRO: (refhandle:%x) recv frag."
-                                      "wait for last. flags: %x expected:%d"
+                               printk("LRO: (refhandle:%x) recv frag. "
+                                      "wait for last. flags: %x expected:%d "
                                       "have:%d\n", index,
                                       netxen_get_sts_desc_lro_last_frag(desc),
                                       buffer->lro_expected_frags,
@@ -1458,8 +1463,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
        }
 }
 
-void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
-                                uint32_t ringid)
+static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+                                       uint32_t ctx, uint32_t ringid)
 {
        struct pci_dev *pdev = adapter->ahw.pdev;
        struct sk_buff *skb;
@@ -1491,7 +1496,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx,
                count++;        /* now there should be no failure */
                pdesc = &rcv_desc->desc_head[producer];
                skb_reserve(skb, 2);
-               /* 
+               /*
                 * This will be setup when we receive the
                 * buffer after it has been filled
                 * skb->dev = netdev;
index b2de6b6c2a7f1f2dc32a0414b823a272c10a1473..48a404aa66ceebc859a3851167f556fd4ca54f26 100644 (file)
@@ -48,7 +48,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
        /* total packets received   */
        stats->rx_packets = adapter->stats.no_rcv;
        /* total packets transmitted    */
-       stats->tx_packets = adapter->stats.xmitedframes + 
+       stats->tx_packets = adapter->stats.xmitedframes +
                adapter->stats.xmitfinished;
        /* total bytes received     */
        stats->rx_bytes = adapter->stats.rxbytes;
@@ -66,7 +66,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
        return stats;
 }
 
-void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link)
+static void netxen_indicate_link_status(struct netxen_adapter *adapter,
+                                       u32 link)
 {
        struct net_device *netdev = adapter->netdev;
 
@@ -76,13 +77,14 @@ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link)
                netif_carrier_off(netdev);
 }
 
+#if 0
 void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
 {
        __u32 int_src;
 
        /*  This should clear the interrupt source */
        if (adapter->phy_read)
-               adapter->phy_read(adapter, 
+               adapter->phy_read(adapter,
                                  NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
                                  &int_src);
        if (int_src == 0) {
@@ -111,7 +113,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
                DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n");
 
                if (adapter->phy_read
-                   && adapter->phy_read(adapter, 
+                   && adapter->phy_read(adapter,
                                         NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
                                         &status) == 0) {
                        if (netxen_get_phy_int_link_status_changed(int_src)) {
@@ -125,7 +127,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
                                               netxen_nic_driver_name,
                                               adapter->netdev->name);
                                }
-                               netxen_indicate_link_status(adapter, 
+                               netxen_indicate_link_status(adapter,
                                                            netxen_get_phy_link
                                                            (status));
                        }
@@ -134,8 +136,9 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable)
        if (adapter->enable_phy_interrupts)
                adapter->enable_phy_interrupts(adapter);
 }
+#endif  /*  0  */
 
-void netxen_nic_isr_other(struct netxen_adapter *adapter)
+static void netxen_nic_isr_other(struct netxen_adapter *adapter)
 {
        int portno = adapter->portnum;
        u32 val, linkup, qg_linksup;
index 263b55e36c7a1b0d477bfd6e1e3892fb54097bcc..9737eae5ef111f265345e1747d008cad953fb7db 100644 (file)
@@ -89,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
 struct workqueue_struct *netxen_workq;
 static void netxen_watchdog(unsigned long);
 
-static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
-                                                       uint32_t crb_producer)
+static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
+                                          uint32_t crb_producer)
 {
        switch (adapter->portnum) {
                case 0:
@@ -118,8 +118,8 @@ static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter
        }
 }
 
-static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
-                                                       u32 crb_consumer)
+static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
+                                          u32 crb_consumer)
 {
        switch (adapter->portnum) {
                case 0:
@@ -148,7 +148,6 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter
 }
 
 #define        ADAPTER_LIST_SIZE 12
-int netxen_cards_found;
 
 static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
@@ -278,7 +277,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        struct netxen_recv_context *recv_ctx = NULL;
        struct netxen_rcv_desc_ctx *rcv_desc = NULL;
        struct netxen_cmd_buffer *cmd_buf_arr = NULL;
-       u64 mac_addr[FLASH_NUM_PORTS + 1];
+       __le64 mac_addr[FLASH_NUM_PORTS + 1];
        int valid_mac = 0;
        u32 val;
        int pci_func_id = PCI_FUNC(pdev->devfn);
@@ -287,7 +286,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        printk(KERN_INFO "%s \n", netxen_nic_driver_string);
 
        if (pdev->class != 0x020000) {
-               printk(KERN_ERR"NetXen function %d, class %x will not"
+               printk(KERN_ERR"NetXen function %d, class %x will not "
                                "be enabled.\n",pci_func_id, pdev->class);
                return -ENODEV;
        }
@@ -351,12 +350,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                first_page_group_start = 0;
                first_page_group_end   = 0;
        } else {
-               err = -EIO; 
+               err = -EIO;
                goto err_out_free_netdev;
        }
 
-       if (((mem_ptr0 == 0UL) && (mem_len == NETXEN_PCI_128MB_SIZE)) ||
-                       (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) {
+       if ((!mem_ptr0 && mem_len == NETXEN_PCI_128MB_SIZE) ||
+                       !mem_ptr1 || !mem_ptr2) {
                DPRINTK(ERR,
                        "Cannot remap adapter memory aborting.:"
                        "0 -> %p, 1 -> %p, 2 -> %p\n",
@@ -411,7 +410,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->open               = netxen_nic_open;
        netdev->stop               = netxen_nic_close;
        netdev->hard_start_xmit    = netxen_nic_xmit_frame;
-       netdev->get_stats          = netxen_nic_get_stats;      
+       netdev->get_stats          = netxen_nic_get_stats;
        netdev->set_multicast_list = netxen_nic_set_multi;
        netdev->set_mac_address    = netxen_nic_set_mac;
        netdev->change_mtu         = netxen_nic_change_mtu;
@@ -458,8 +457,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
        if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) ||
-                       (adapter->ahw.boardcfg.board_type == 
-                        NETXEN_BRDTYPE_P2_SB31_2G)) 
+                       (adapter->ahw.boardcfg.board_type ==
+                        NETXEN_BRDTYPE_P2_SB31_2G))
                adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
        else
                adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS;
@@ -511,7 +510,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                            vmalloc(RCV_BUFFSIZE);
 
                        if (rcv_desc->rx_buf_arr == NULL) {
-                               printk(KERN_ERR "%s: Could not allocate"
+                               printk(KERN_ERR "%s: Could not allocate "
                                       "rcv_desc->rx_buf_arr memory:%d\n",
                                       netxen_nic_driver_name,
                                       (int)RCV_BUFFSIZE);
@@ -584,9 +583,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        if (adapter->portnum == 0) {
                err = netxen_initialize_adapter_offload(adapter);
-               if (err) 
+               if (err)
                        goto err_out_free_rx_buffer;
-               val = readl(NETXEN_CRB_NORMALIZE(adapter, 
+               val = readl(NETXEN_CRB_NORMALIZE(adapter,
                                        NETXEN_CAM_RAM(0x1fc)));
                if (val == 0x55555555) {
                    /* This is the first boot after power up */
@@ -620,7 +619,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                /*
                 * Tell the hardware our version number.
                 */
-               i = (_NETXEN_NIC_LINUX_MAJOR << 16) 
+               i = (_NETXEN_NIC_LINUX_MAJOR << 16)
                        | ((_NETXEN_NIC_LINUX_MINOR << 8))
                        | (_NETXEN_NIC_LINUX_SUBVERSION);
                writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION));
@@ -660,7 +659,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        break;
 
                case NETXEN_NIC_XGBE:
-                       printk(KERN_INFO "%s: XGbE board initialized\n", 
+                       printk(KERN_INFO "%s: XGbE board initialized\n",
                                        netxen_nic_driver_name);
                        break;
        }
@@ -931,7 +930,7 @@ static int netxen_nic_close(struct net_device *netdev)
                        buffrag++;
                        if (buffrag->dma) {
                                pci_unmap_page(adapter->pdev, buffrag->dma,
-                                              buffrag->length, 
+                                              buffrag->length,
                                               PCI_DMA_TODEVICE);
                                buffrag->dma = 0ULL;
                        }
@@ -981,7 +980,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        }
 
        if (frag_count > MAX_BUFFERS_PER_CMD) {
-               printk("%s: %s netxen_nic_xmit_frame: frag_count (%d)"
+               printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) "
                       "too large, can handle only %d frags\n",
                       netxen_nic_driver_name, netdev->name,
                       frag_count, MAX_BUFFERS_PER_CMD);
@@ -1195,7 +1194,7 @@ static void netxen_tx_timeout(struct net_device *netdev)
 
 static void netxen_tx_timeout_task(struct work_struct *work)
 {
-       struct netxen_adapter *adapter = 
+       struct netxen_adapter *adapter =
                container_of(work, struct netxen_adapter, tx_timeout_task);
 
        printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
@@ -1338,7 +1337,7 @@ static struct pci_driver netxen_driver = {
 
 static int __init netxen_init_module(void)
 {
-       if ((netxen_workq = create_singlethread_workqueue("netxen")) == 0)
+       if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
                return -ENOMEM;
 
        return pci_register_driver(&netxen_driver);
index d04ecb77d08c5bd92c96475465ba4bf0fc3a9d89..1c852a76c80d6bc352f1caf191bc4ae599163261 100644 (file)
@@ -40,7 +40,7 @@
 
 static long phy_lock_timeout = 100000000;
 
-static inline int phy_lock(struct netxen_adapter *adapter)
+static int phy_lock(struct netxen_adapter *adapter)
 {
        int i;
        int done = 0, timeout = 0;
@@ -68,14 +68,14 @@ static inline int phy_lock(struct netxen_adapter *adapter)
        return 0;
 }
 
-static inline int phy_unlock(struct netxen_adapter *adapter)
+static int phy_unlock(struct netxen_adapter *adapter)
 {
        readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK)));
 
        return 0;
 }
 
-/* 
+/*
  * netxen_niu_gbe_phy_read - read a register from the GbE PHY via
  * mii management interface.
  *
@@ -88,7 +88,7 @@ static inline int phy_unlock(struct netxen_adapter *adapter)
  *       -1 on error
  *
  */
-int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, 
+int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                                __u32 * readval)
 {
        long timeout = 0;
@@ -171,7 +171,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
        return result;
 }
 
-/* 
+/*
  * netxen_niu_gbe_phy_write - write a register to the GbE PHY via
  * mii management interface.
  *
@@ -184,7 +184,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
  *       -1 on error
  *
  */
-int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, 
+int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
                                __u32 val)
 {
        long timeout = 0;
@@ -275,7 +275,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
        netxen_set_phy_int_speed_changed(enable);
 
        if (0 !=
-           netxen_niu_gbe_phy_write(adapter, 
+           netxen_niu_gbe_phy_write(adapter,
                                     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE,
                                     enable))
                result = -EIO;
@@ -300,17 +300,19 @@ int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter)
        return result;
 }
 
+#if 0
 int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter)
 {
        netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1);
        return 0;
 }
+#endif  /*  0  */
 
-int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
+static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
 {
        int result = 0;
        if (0 !=
-           netxen_niu_gbe_phy_write(adapter, 
+           netxen_niu_gbe_phy_write(adapter,
                                     NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS,
                                     -EIO))
                result = -EIO;
@@ -318,12 +320,12 @@ int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
        return result;
 }
 
-/* 
+/*
  * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC
  *
  */
-void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
-                                int port, long enable)
+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),
@@ -342,9 +344,9 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *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. 
+               /*
+                * 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),
@@ -357,11 +359,11 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
                printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
 }
 
-/* 
+/*
  * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC
  */
-void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
-                                 int port, long enable)
+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),
@@ -380,9 +382,9 @@ void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *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. 
+               /*
+                * 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),
@@ -464,7 +466,8 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
        return 0;
 }
 
-/* 
+#if 0
+/*
  * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts
  * @param enable 0 means don't enable the port
  *              1 means enable (or re-enable) the port
@@ -544,8 +547,8 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
                                                                    port,
                                                                    enable);
                                } else {
-                                       printk(KERN_ERR PFX "ERROR reading"
-                                              "PHY status. Illegal speed.\n");
+                                       printk(KERN_ERR PFX "ERROR reading "
+                                              "PHY status. Invalid speed.\n");
                                        result = -1;
                                }
                        } else {
@@ -559,13 +562,14 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter,
        }
        return result;
 }
+#endif  /*  0  */
 
 /*
  * Return the current station MAC address.
  * Note that the passed-in value must already be in network byte order.
  */
-int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
-                          netxen_ethernet_macaddr_t * addr)
+static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
+                                 netxen_ethernet_macaddr_t * addr)
 {
        u32 stationhigh;
        u32 stationlow;
@@ -619,7 +623,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
                    (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
                        return -2;
 
-               netxen_niu_macaddr_get(adapter, 
+               netxen_niu_macaddr_get(adapter,
                                       (netxen_ethernet_macaddr_t *) mac_addr);
                if (memcmp(mac_addr, addr, 6) == 0)
                        break;
@@ -636,6 +640,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
        return 0;
 }
 
+#if 0
 /* Enable a GbE interface */
 int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
                               int port, netxen_niu_gbe_ifmode_t mode)
@@ -713,6 +718,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter,
                return -EIO;
        return 0;
 }
+#endif  /*  0  */
 
 /* Disable a GbE interface */
 int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
@@ -747,7 +753,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 }
 
 /* Set promiscuous mode for a GbE interface */
-int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, 
+int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                                    netxen_niu_prom_mode_t mode)
 {
        __u32 reg;
@@ -853,6 +859,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
        return 0;
 }
 
+#if 0
 /*
  * Return the current station MAC address.
  * Note that the passed-in value must already be in network byte order.
@@ -883,6 +890,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
 
        return 0;
 }
+#endif  /*  0  */
 
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
                                       netxen_niu_prom_mode_t mode)
index 10fe6fafa6f6cee24c92fdf69e1fca3806fc7540..ffa3b7215ce8eb3dd909da585b4f93b89c50a1a7 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 - 2006 NetXen, Inc.
  * All rights reserved.
- * 
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  * MA  02111-1307, USA.
- * 
+ *
  * The full GNU General Public License is included in this distribution
  * in the file called LICENSE.
- * 
+ *
  * Contact Information:
  *    info@netxen.com
  * NetXen,
@@ -30,7 +30,7 @@
 #ifndef __NIC_PHAN_REG_H_
 #define __NIC_PHAN_REG_H_
 
-/* 
+/*
  * CRB Registers or queue message done only at initialization time.
  */
 #define NIC_CRB_BASE               NETXEN_CAM_RAM(0x200)
@@ -165,14 +165,7 @@ struct netxen_recv_crb {
        u32 crb_status_ring_size;
 };
 
-#if defined(DEFINE_GLOBAL_RECV_CRB)
-#else
 extern struct netxen_recv_crb recv_crb_registers[];
-extern u64 ctx_addr_sig_regs[][3];
-#endif                         /* DEFINE_GLOBAL_RECEIVE_CRB */
-#define CRB_CTX_ADDR_REG_LO(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][0])
-#define CRB_CTX_ADDR_REG_HI(FUNC_ID)           (ctx_addr_sig_regs[FUNC_ID][2])
-#define CRB_CTX_SIGNATURE_REG(FUNC_ID)         (ctx_addr_sig_regs[FUNC_ID][1])
 
 /*
  * Temperature control.
index 5f6beabf2d179d71e399d85a0f75af84c36b189a..2fe14b0c5c67956e05f01b69d54ebb7d7a194509 100644 (file)
@@ -7588,12 +7588,10 @@ static void __devinit niu_assign_netdev_ops(struct net_device *dev)
 static void __devinit niu_device_announce(struct niu *np)
 {
        struct net_device *dev = np->dev;
-       int i;
+       DECLARE_MAC_BUF(mac);
 
-       pr_info("%s: NIU Ethernet ", dev->name);
-       for (i = 0; i < 6; i++)
-               printk("%2.2x%c", dev->dev_addr[i],
-                      i == 5 ? '\n' : ':');
+       pr_info("%s: NIU Ethernet %s\n",
+               dev->name, print_mac(mac, dev->dev_addr));
 
        pr_info("%s: Port type[%s] mode[%s:%s] XCVR[%s] phy[%s]\n",
                dev->name,
index ea71f6d82661b1aebc3a481d9d51806dbf77420d..b42c05f84be15d78d59600362f7e8f8f5e0837d0 100644 (file)
@@ -611,8 +611,7 @@ static inline int rx_refill(struct net_device *ndev, gfp_t gfp)
        return i ? 0 : -ENOMEM;
 }
 
-static void FASTCALL(rx_refill_atomic(struct net_device *ndev));
-static void fastcall rx_refill_atomic(struct net_device *ndev)
+static void rx_refill_atomic(struct net_device *ndev)
 {
        rx_refill(ndev, GFP_ATOMIC);
 }
@@ -633,8 +632,7 @@ static inline void clear_rx_desc(struct ns83820 *dev, unsigned i)
        build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
 }
 
-static void FASTCALL(phy_intr(struct net_device *ndev));
-static void fastcall phy_intr(struct net_device *ndev)
+static void phy_intr(struct net_device *ndev)
 {
        struct ns83820 *dev = PRIV(ndev);
        static const char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
@@ -832,8 +830,7 @@ static void ns83820_cleanup_rx(struct ns83820 *dev)
        }
 }
 
-static void FASTCALL(ns83820_rx_kick(struct net_device *ndev));
-static void fastcall ns83820_rx_kick(struct net_device *ndev)
+static void ns83820_rx_kick(struct net_device *ndev)
 {
        struct ns83820 *dev = PRIV(ndev);
        /*if (nr_rx_empty(dev) >= NR_RX_DESC/4)*/ {
@@ -854,8 +851,7 @@ static void fastcall ns83820_rx_kick(struct net_device *ndev)
 /* rx_irq
  *
  */
-static void FASTCALL(rx_irq(struct net_device *ndev));
-static void fastcall rx_irq(struct net_device *ndev)
+static void rx_irq(struct net_device *ndev)
 {
        struct ns83820 *dev = PRIV(ndev);
        struct rx_info *info = &dev->rx_info;
index 816a59e801b2bbd26bc590ee66c57a8e67a004c0..bb88a41b759103e5601b22a4831f81f225513245 100644 (file)
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <net/checksum.h>
+#include <linux/inet_lro.h>
 
 #include <asm/irq.h>
 #include <asm/firmware.h>
+#include <asm/pasemi_dma.h>
 
 #include "pasemi_mac.h"
 
 
 
 /* Must be a power of two */
-#define RX_RING_SIZE 4096
+#define RX_RING_SIZE 2048
 #define TX_RING_SIZE 4096
 
+#define LRO_MAX_AGGR 64
+
 #define DEFAULT_MSG_ENABLE       \
        (NETIF_MSG_DRV          | \
         NETIF_MSG_PROBE        | \
         NETIF_MSG_RX_ERR       | \
         NETIF_MSG_TX_ERR)
 
-#define TX_RING(mac, num)      ((mac)->tx->ring[(num) & (TX_RING_SIZE-1)])
-#define TX_RING_INFO(mac, num) ((mac)->tx->ring_info[(num) & (TX_RING_SIZE-1)])
-#define RX_RING(mac, num)      ((mac)->rx->ring[(num) & (RX_RING_SIZE-1)])
-#define RX_RING_INFO(mac, num) ((mac)->rx->ring_info[(num) & (RX_RING_SIZE-1)])
-#define RX_BUFF(mac, num)      ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
+#define TX_DESC(tx, num)       ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)])
+#define TX_DESC_INFO(tx, num)  ((tx)->ring_info[(num) & (TX_RING_SIZE-1)])
+#define RX_DESC(rx, num)       ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)])
+#define RX_DESC_INFO(rx, num)  ((rx)->ring_info[(num) & (RX_RING_SIZE-1)])
+#define RX_BUFF(rx, num)       ((rx)->buffers[(num) & (RX_RING_SIZE-1)])
 
 #define RING_USED(ring)                (((ring)->next_to_fill - (ring)->next_to_clean) \
                                 & ((ring)->size - 1))
@@ -88,8 +92,6 @@ static int debug = -1;        /* -1 == use DEFAULT_MSG_ENABLE as value */
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
-static struct pasdma_status *dma_status;
-
 static int translation_enabled(void)
 {
 #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
@@ -99,32 +101,78 @@ static int translation_enabled(void)
 #endif
 }
 
-static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
-                         unsigned int val)
+static void write_iob_reg(unsigned int reg, unsigned int val)
 {
-       out_le32(mac->iob_regs+reg, val);
+       pasemi_write_iob_reg(reg, val);
 }
 
-static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
+static unsigned int read_mac_reg(const struct pasemi_mac *mac, unsigned int reg)
 {
-       return in_le32(mac->regs+reg);
+       return pasemi_read_mac_reg(mac->dma_if, reg);
 }
 
-static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
+static void write_mac_reg(const struct pasemi_mac *mac, unsigned int reg,
                          unsigned int val)
 {
-       out_le32(mac->regs+reg, val);
+       pasemi_write_mac_reg(mac->dma_if, reg, val);
 }
 
-static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
+static unsigned int read_dma_reg(unsigned int reg)
 {
-       return in_le32(mac->dma_regs+reg);
+       return pasemi_read_dma_reg(reg);
 }
 
-static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
-                         unsigned int val)
+static void write_dma_reg(unsigned int reg, unsigned int val)
+{
+       pasemi_write_dma_reg(reg, val);
+}
+
+static struct pasemi_mac_rxring *rx_ring(const struct pasemi_mac *mac)
 {
-       out_le32(mac->dma_regs+reg, val);
+       return mac->rx;
+}
+
+static struct pasemi_mac_txring *tx_ring(const struct pasemi_mac *mac)
+{
+       return mac->tx;
+}
+
+static inline void prefetch_skb(const struct sk_buff *skb)
+{
+       const void *d = skb;
+
+       prefetch(d);
+       prefetch(d+64);
+       prefetch(d+128);
+       prefetch(d+192);
+}
+
+static int mac_to_intf(struct pasemi_mac *mac)
+{
+       struct pci_dev *pdev = mac->pdev;
+       u32 tmp;
+       int nintf, off, i, j;
+       int devfn = pdev->devfn;
+
+       tmp = read_dma_reg(PAS_DMA_CAP_IFI);
+       nintf = (tmp & PAS_DMA_CAP_IFI_NIN_M) >> PAS_DMA_CAP_IFI_NIN_S;
+       off = (tmp & PAS_DMA_CAP_IFI_IOFF_M) >> PAS_DMA_CAP_IFI_IOFF_S;
+
+       /* IOFF contains the offset to the registers containing the
+        * DMA interface-to-MAC-pci-id mappings, and NIN contains number
+        * of total interfaces. Each register contains 4 devfns.
+        * Just do a linear search until we find the devfn of the MAC
+        * we're trying to look up.
+        */
+
+       for (i = 0; i < (nintf+3)/4; i++) {
+               tmp = read_dma_reg(off+4*i);
+               for (j = 0; j < 4; j++) {
+                       if (((tmp >> (8*j)) & 0xff) == devfn)
+                               return i*4 + j;
+               }
+       }
+       return -1;
 }
 
 static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -161,7 +209,6 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
                return -ENOENT;
        }
 
-
        if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0],
                   &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) {
                dev_warn(&pdev->dev,
@@ -174,21 +221,51 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
        return 0;
 }
 
+static int get_skb_hdr(struct sk_buff *skb, void **iphdr,
+                      void **tcph, u64 *hdr_flags, void *data)
+{
+       u64 macrx = (u64) data;
+       unsigned int ip_len;
+       struct iphdr *iph;
+
+       /* IPv4 header checksum failed */
+       if ((macrx & XCT_MACRX_HTY_M) != XCT_MACRX_HTY_IPV4_OK)
+               return -1;
+
+       /* non tcp packet */
+       skb_reset_network_header(skb);
+       iph = ip_hdr(skb);
+       if (iph->protocol != IPPROTO_TCP)
+               return -1;
+
+       ip_len = ip_hdrlen(skb);
+       skb_set_transport_header(skb, ip_len);
+       *tcph = tcp_hdr(skb);
+
+       /* check if ip header and tcp header are complete */
+       if (iph->tot_len < ip_len + tcp_hdrlen(skb))
+               return -1;
+
+       *hdr_flags = LRO_IPV4 | LRO_TCP;
+       *iphdr = iph;
+
+       return 0;
+}
+
 static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac,
+                                   const int nfrags,
                                    struct sk_buff *skb,
-                                   dma_addr_t *dmas)
+                                   const dma_addr_t *dmas)
 {
        int f;
-       int nfrags = skb_shinfo(skb)->nr_frags;
+       struct pci_dev *pdev = mac->dma_pdev;
 
-       pci_unmap_single(mac->dma_pdev, dmas[0], skb_headlen(skb),
-                        PCI_DMA_TODEVICE);
+       pci_unmap_single(pdev, dmas[0], skb_headlen(skb), PCI_DMA_TODEVICE);
 
        for (f = 0; f < nfrags; f++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
 
-               pci_unmap_page(mac->dma_pdev, dmas[f+1], frag->size,
-                              PCI_DMA_TODEVICE);
+               pci_unmap_page(pdev, dmas[f+1], frag->size, PCI_DMA_TODEVICE);
        }
        dev_kfree_skb_irq(skb);
 
@@ -198,17 +275,21 @@ static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac,
        return (nfrags + 3) & ~1;
 }
 
-static int pasemi_mac_setup_rx_resources(struct net_device *dev)
+static int pasemi_mac_setup_rx_resources(const struct net_device *dev)
 {
        struct pasemi_mac_rxring *ring;
        struct pasemi_mac *mac = netdev_priv(dev);
-       int chan_id = mac->dma_rxch;
+       int chno;
        unsigned int cfg;
 
-       ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+       ring = pasemi_dma_alloc_chan(RXCHAN, sizeof(struct pasemi_mac_rxring),
+                                    offsetof(struct pasemi_mac_rxring, chan));
 
-       if (!ring)
-               goto out_ring;
+       if (!ring) {
+               dev_err(&mac->pdev->dev, "Can't allocate RX channel\n");
+               goto out_chan;
+       }
+       chno = ring->chan.chno;
 
        spin_lock_init(&ring->lock);
 
@@ -220,85 +301,80 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
                goto out_ring_info;
 
        /* Allocate descriptors */
-       ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
-                                       RX_RING_SIZE * sizeof(u64),
-                                       &ring->dma, GFP_KERNEL);
-
-       if (!ring->ring)
+       if (pasemi_dma_alloc_ring(&ring->chan, RX_RING_SIZE))
                goto out_ring_desc;
 
-       memset(ring->ring, 0, RX_RING_SIZE * sizeof(u64));
-
        ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev,
                                           RX_RING_SIZE * sizeof(u64),
                                           &ring->buf_dma, GFP_KERNEL);
        if (!ring->buffers)
-               goto out_buffers;
+               goto out_ring_desc;
 
        memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64));
 
-       write_dma_reg(mac, PAS_DMA_RXCHAN_BASEL(chan_id), PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma));
+       write_dma_reg(PAS_DMA_RXCHAN_BASEL(chno),
+                     PAS_DMA_RXCHAN_BASEL_BRBL(ring->chan.ring_dma));
 
-       write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id),
-                          PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
-                          PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
+       write_dma_reg(PAS_DMA_RXCHAN_BASEU(chno),
+                     PAS_DMA_RXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32) |
+                     PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
 
        cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
 
        if (translation_enabled())
                cfg |= PAS_DMA_RXCHAN_CFG_CTR;
 
-       write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg);
+       write_dma_reg(PAS_DMA_RXCHAN_CFG(chno), cfg);
 
-       write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
-                          PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
+       write_dma_reg(PAS_DMA_RXINT_BASEL(mac->dma_if),
+                     PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
 
-       write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if),
-                          PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) |
-                          PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
+       write_dma_reg(PAS_DMA_RXINT_BASEU(mac->dma_if),
+                     PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) |
+                     PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
 
-       cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
+       cfg = PAS_DMA_RXINT_CFG_DHL(2) | PAS_DMA_RXINT_CFG_L2 |
              PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
              PAS_DMA_RXINT_CFG_HEN;
 
        if (translation_enabled())
                cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR;
 
-       write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
+       write_dma_reg(PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
 
        ring->next_to_fill = 0;
        ring->next_to_clean = 0;
-
-       snprintf(ring->irq_name, sizeof(ring->irq_name),
-                "%s rx", dev->name);
+       ring->mac = mac;
        mac->rx = ring;
 
        return 0;
 
-out_buffers:
-       dma_free_coherent(&mac->dma_pdev->dev,
-                         RX_RING_SIZE * sizeof(u64),
-                         mac->rx->ring, mac->rx->dma);
 out_ring_desc:
        kfree(ring->ring_info);
 out_ring_info:
-       kfree(ring);
-out_ring:
+       pasemi_dma_free_chan(&ring->chan);
+out_chan:
        return -ENOMEM;
 }
 
-
-static int pasemi_mac_setup_tx_resources(struct net_device *dev)
+static struct pasemi_mac_txring *
+pasemi_mac_setup_tx_resources(const struct net_device *dev)
 {
        struct pasemi_mac *mac = netdev_priv(dev);
        u32 val;
-       int chan_id = mac->dma_txch;
        struct pasemi_mac_txring *ring;
        unsigned int cfg;
+       int chno;
+
+       ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_txring),
+                                    offsetof(struct pasemi_mac_txring, chan));
 
-       ring = kzalloc(sizeof(*ring), GFP_KERNEL);
-       if (!ring)
-               goto out_ring;
+       if (!ring) {
+               dev_err(&mac->pdev->dev, "Can't allocate TX channel\n");
+               goto out_chan;
+       }
+
+       chno = ring->chan.chno;
 
        spin_lock_init(&ring->lock);
 
@@ -309,20 +385,15 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
                goto out_ring_info;
 
        /* Allocate descriptors */
-       ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
-                                       TX_RING_SIZE * sizeof(u64),
-                                       &ring->dma, GFP_KERNEL);
-       if (!ring->ring)
+       if (pasemi_dma_alloc_ring(&ring->chan, TX_RING_SIZE))
                goto out_ring_desc;
 
-       memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64));
-
-       write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id),
-                          PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
-       val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
+       write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno),
+                     PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma));
+       val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32);
        val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3);
 
-       write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
+       write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val);
 
        cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
              PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
@@ -332,71 +403,64 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
        if (translation_enabled())
                cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
 
-       write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg);
+       write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg);
 
        ring->next_to_fill = 0;
        ring->next_to_clean = 0;
+       ring->mac = mac;
 
-       snprintf(ring->irq_name, sizeof(ring->irq_name),
-                "%s tx", dev->name);
-       mac->tx = ring;
-
-       return 0;
+       return ring;
 
 out_ring_desc:
        kfree(ring->ring_info);
 out_ring_info:
-       kfree(ring);
-out_ring:
-       return -ENOMEM;
+       pasemi_dma_free_chan(&ring->chan);
+out_chan:
+       return NULL;
 }
 
-static void pasemi_mac_free_tx_resources(struct net_device *dev)
+static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac)
 {
-       struct pasemi_mac *mac = netdev_priv(dev);
+       struct pasemi_mac_txring *txring = tx_ring(mac);
        unsigned int i, j;
        struct pasemi_mac_buffer *info;
        dma_addr_t dmas[MAX_SKB_FRAGS+1];
-       int freed;
+       int freed, nfrags;
        int start, limit;
 
-       start = mac->tx->next_to_clean;
-       limit = mac->tx->next_to_fill;
+       start = txring->next_to_clean;
+       limit = txring->next_to_fill;
 
        /* Compensate for when fill has wrapped and clean has not */
        if (start > limit)
                limit += TX_RING_SIZE;
 
        for (i = start; i < limit; i += freed) {
-               info = &TX_RING_INFO(mac, i+1);
+               info = &txring->ring_info[(i+1) & (TX_RING_SIZE-1)];
                if (info->dma && info->skb) {
-                       for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++)
-                               dmas[j] = TX_RING_INFO(mac, i+1+j).dma;
-                       freed = pasemi_mac_unmap_tx_skb(mac, info->skb, dmas);
+                       nfrags = skb_shinfo(info->skb)->nr_frags;
+                       for (j = 0; j <= nfrags; j++)
+                               dmas[j] = txring->ring_info[(i+1+j) &
+                                               (TX_RING_SIZE-1)].dma;
+                       freed = pasemi_mac_unmap_tx_skb(mac, nfrags,
+                                                       info->skb, dmas);
                } else
                        freed = 2;
        }
 
-       for (i = 0; i < TX_RING_SIZE; i++)
-               TX_RING(mac, i) = 0;
-
-       dma_free_coherent(&mac->dma_pdev->dev,
-                         TX_RING_SIZE * sizeof(u64),
-                         mac->tx->ring, mac->tx->dma);
+       kfree(txring->ring_info);
+       pasemi_dma_free_chan(&txring->chan);
 
-       kfree(mac->tx->ring_info);
-       kfree(mac->tx);
-       mac->tx = NULL;
 }
 
-static void pasemi_mac_free_rx_resources(struct net_device *dev)
+static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac)
 {
-       struct pasemi_mac *mac = netdev_priv(dev);
+       struct pasemi_mac_rxring *rx = rx_ring(mac);
        unsigned int i;
        struct pasemi_mac_buffer *info;
 
        for (i = 0; i < RX_RING_SIZE; i++) {
-               info = &RX_RING_INFO(mac, i);
+               info = &RX_DESC_INFO(rx, i);
                if (info->skb && info->dma) {
                        pci_unmap_single(mac->dma_pdev,
                                         info->dma,
@@ -409,45 +473,38 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
        }
 
        for (i = 0; i < RX_RING_SIZE; i++)
-               RX_RING(mac, i) = 0;
-
-       dma_free_coherent(&mac->dma_pdev->dev,
-                         RX_RING_SIZE * sizeof(u64),
-                         mac->rx->ring, mac->rx->dma);
+               RX_DESC(rx, i) = 0;
 
        dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
-                         mac->rx->buffers, mac->rx->buf_dma);
+                         rx_ring(mac)->buffers, rx_ring(mac)->buf_dma);
 
-       kfree(mac->rx->ring_info);
-       kfree(mac->rx);
+       kfree(rx_ring(mac)->ring_info);
+       pasemi_dma_free_chan(&rx_ring(mac)->chan);
        mac->rx = NULL;
 }
 
-static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
+static void pasemi_mac_replenish_rx_ring(const struct net_device *dev,
+                                        const int limit)
 {
-       struct pasemi_mac *mac = netdev_priv(dev);
+       const struct pasemi_mac *mac = netdev_priv(dev);
+       struct pasemi_mac_rxring *rx = rx_ring(mac);
        int fill, count;
 
        if (limit <= 0)
                return;
 
-       fill = mac->rx->next_to_fill;
+       fill = rx_ring(mac)->next_to_fill;
        for (count = 0; count < limit; count++) {
-               struct pasemi_mac_buffer *info = &RX_RING_INFO(mac, fill);
-               u64 *buff = &RX_BUFF(mac, fill);
+               struct pasemi_mac_buffer *info = &RX_DESC_INFO(rx, fill);
+               u64 *buff = &RX_BUFF(rx, fill);
                struct sk_buff *skb;
                dma_addr_t dma;
 
                /* Entry in use? */
                WARN_ON(*buff);
 
-               /* skb might still be in there for recycle on short receives */
-               if (info->skb)
-                       skb = info->skb;
-               else {
-                       skb = dev_alloc_skb(BUF_SIZE);
-                       skb_reserve(skb, LOCAL_SKB_ALIGN);
-               }
+               skb = dev_alloc_skb(BUF_SIZE);
+               skb_reserve(skb, LOCAL_SKB_ALIGN);
 
                if (unlikely(!skb))
                        break;
@@ -469,94 +526,108 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
 
        wmb();
 
-       write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count);
+       write_dma_reg(PAS_DMA_RXINT_INCR(mac->dma_if), count);
 
-       mac->rx->next_to_fill = (mac->rx->next_to_fill + count) &
+       rx_ring(mac)->next_to_fill = (rx_ring(mac)->next_to_fill + count) &
                                (RX_RING_SIZE - 1);
 }
 
-static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
+static void pasemi_mac_restart_rx_intr(const struct pasemi_mac *mac)
 {
+       struct pasemi_mac_rxring *rx = rx_ring(mac);
        unsigned int reg, pcnt;
        /* Re-enable packet count interrupts: finally
         * ack the packet count interrupt we got in rx_intr.
         */
 
-       pcnt = *mac->rx_status & PAS_STATUS_PCNT_M;
+       pcnt = *rx->chan.status & PAS_STATUS_PCNT_M;
 
        reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
 
-       write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
+       if (*rx->chan.status & PAS_STATUS_TIMER)
+               reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
+
+       write_iob_reg(PAS_IOB_DMA_RXCH_RESET(mac->rx->chan.chno), reg);
 }
 
-static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
+static void pasemi_mac_restart_tx_intr(const struct pasemi_mac *mac)
 {
        unsigned int reg, pcnt;
 
        /* Re-enable packet count interrupts */
-       pcnt = *mac->tx_status & PAS_STATUS_PCNT_M;
+       pcnt = *tx_ring(mac)->chan.status & PAS_STATUS_PCNT_M;
 
        reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
 
-       write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+       write_iob_reg(PAS_IOB_DMA_TXCH_RESET(tx_ring(mac)->chan.chno), reg);
 }
 
 
-static inline void pasemi_mac_rx_error(struct pasemi_mac *mac, u64 macrx)
+static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac,
+                                      const u64 macrx)
 {
        unsigned int rcmdsta, ccmdsta;
+       struct pasemi_dmachan *chan = &rx_ring(mac)->chan;
 
        if (!netif_msg_rx_err(mac))
                return;
 
-       rcmdsta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
-       ccmdsta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+       rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+       ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno));
 
        printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n",
-               macrx, *mac->rx_status);
+               macrx, *chan->status);
 
        printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n",
                rcmdsta, ccmdsta);
 }
 
-static inline void pasemi_mac_tx_error(struct pasemi_mac *mac, u64 mactx)
+static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac,
+                                      const u64 mactx)
 {
        unsigned int cmdsta;
+       struct pasemi_dmachan *chan = &tx_ring(mac)->chan;
 
        if (!netif_msg_tx_err(mac))
                return;
 
-       cmdsta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
+       cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno));
 
        printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\
-               "tx status 0x%016lx\n", mactx, *mac->tx_status);
+               "tx status 0x%016lx\n", mactx, *chan->status);
 
        printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta);
 }
 
-static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
+static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx,
+                              const int limit)
 {
+       const struct pasemi_dmachan *chan = &rx->chan;
+       struct pasemi_mac *mac = rx->mac;
+       struct pci_dev *pdev = mac->dma_pdev;
        unsigned int n;
-       int count;
+       int count, buf_index, tot_bytes, packets;
        struct pasemi_mac_buffer *info;
        struct sk_buff *skb;
        unsigned int len;
-       u64 macrx;
+       u64 macrx, eval;
        dma_addr_t dma;
-       int buf_index;
-       u64 eval;
 
-       spin_lock(&mac->rx->lock);
+       tot_bytes = 0;
+       packets = 0;
 
-       n = mac->rx->next_to_clean;
+       spin_lock(&rx->lock);
 
-       prefetch(&RX_RING(mac, n));
+       n = rx->next_to_clean;
+
+       prefetch(&RX_DESC(rx, n));
 
        for (count = 0; count < limit; count++) {
-               macrx = RX_RING(mac, n);
+               macrx = RX_DESC(rx, n);
+               prefetch(&RX_DESC(rx, n+4));
 
                if ((macrx & XCT_MACRX_E) ||
-                   (*mac->rx_status & PAS_STATUS_ERROR))
+                   (*chan->status & PAS_STATUS_ERROR))
                        pasemi_mac_rx_error(mac, macrx);
 
                if (!(macrx & XCT_MACRX_O))
@@ -566,21 +637,21 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                BUG_ON(!(macrx & XCT_MACRX_RR_8BRES));
 
-               eval = (RX_RING(mac, n+1) & XCT_RXRES_8B_EVAL_M) >>
+               eval = (RX_DESC(rx, n+1) & XCT_RXRES_8B_EVAL_M) >>
                        XCT_RXRES_8B_EVAL_S;
                buf_index = eval-1;
 
-               dma = (RX_RING(mac, n+2) & XCT_PTR_ADDR_M);
-               info = &RX_RING_INFO(mac, buf_index);
+               dma = (RX_DESC(rx, n+2) & XCT_PTR_ADDR_M);
+               info = &RX_DESC_INFO(rx, buf_index);
 
                skb = info->skb;
 
-               prefetch(skb);
-               prefetch(&skb->data_len);
+               prefetch_skb(skb);
 
                len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
 
-               pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
+               pci_unmap_single(pdev, dma, BUF_SIZE-LOCAL_SKB_ALIGN,
+                                PCI_DMA_FROMDEVICE);
 
                if (macrx & XCT_MACRX_CRC) {
                        /* CRC error flagged */
@@ -590,26 +661,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                        goto next;
                }
 
-               if (len < 256) {
-                       struct sk_buff *new_skb;
-
-                       new_skb = netdev_alloc_skb(mac->netdev,
-                                                  len + LOCAL_SKB_ALIGN);
-                       if (new_skb) {
-                               skb_reserve(new_skb, LOCAL_SKB_ALIGN);
-                               memcpy(new_skb->data, skb->data, len);
-                               /* save the skb in buffer_info as good */
-                               skb = new_skb;
-                       }
-                       /* else just continue with the old one */
-               } else
-                       info->skb = NULL;
-
+               info->skb = NULL;
                info->dma = 0;
 
-               /* Don't include CRC */
-               skb_put(skb, len-4);
-
                if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                        skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
@@ -617,41 +671,49 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                } else
                        skb->ip_summed = CHECKSUM_NONE;
 
-               mac->netdev->stats.rx_bytes += len;
-               mac->netdev->stats.rx_packets++;
+               packets++;
+               tot_bytes += len;
+
+               /* Don't include CRC */
+               skb_put(skb, len-4);
 
                skb->protocol = eth_type_trans(skb, mac->netdev);
-               netif_receive_skb(skb);
+               lro_receive_skb(&mac->lro_mgr, skb, (void *)macrx);
 
 next:
-               RX_RING(mac, n) = 0;
-               RX_RING(mac, n+1) = 0;
+               RX_DESC(rx, n) = 0;
+               RX_DESC(rx, n+1) = 0;
 
                /* Need to zero it out since hardware doesn't, since the
                 * replenish loop uses it to tell when it's done.
                 */
-               RX_BUFF(mac, buf_index) = 0;
+               RX_BUFF(rx, buf_index) = 0;
 
                n += 4;
        }
 
        if (n > RX_RING_SIZE) {
                /* Errata 5971 workaround: L2 target of headers */
-               write_iob_reg(mac, PAS_IOB_COM_PKTHDRCNT, 0);
+               write_iob_reg(PAS_IOB_COM_PKTHDRCNT, 0);
                n &= (RX_RING_SIZE-1);
        }
 
-       mac->rx->next_to_clean = n;
+       rx_ring(mac)->next_to_clean = n;
+
+       lro_flush_all(&mac->lro_mgr);
 
        /* Increase is in number of 16-byte entries, and since each descriptor
         * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with
         * count*2.
         */
-       write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), count << 1);
+       write_dma_reg(PAS_DMA_RXCHAN_INCR(mac->rx->chan.chno), count << 1);
 
        pasemi_mac_replenish_rx_ring(mac->netdev, count);
 
-       spin_unlock(&mac->rx->lock);
+       mac->netdev->stats.rx_bytes += tot_bytes;
+       mac->netdev->stats.rx_packets += packets;
+
+       spin_unlock(&rx_ring(mac)->lock);
 
        return count;
 }
@@ -659,8 +721,10 @@ next:
 /* Can't make this too large or we blow the kernel stack limits */
 #define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS)
 
-static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
+static int pasemi_mac_clean_tx(struct pasemi_mac_txring *txring)
 {
+       struct pasemi_dmachan *chan = &txring->chan;
+       struct pasemi_mac *mac = txring->mac;
        int i, j;
        unsigned int start, descr_count, buf_count, batch_limit;
        unsigned int ring_limit;
@@ -668,14 +732,18 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
        unsigned long flags;
        struct sk_buff *skbs[TX_CLEAN_BATCHSIZE];
        dma_addr_t dmas[TX_CLEAN_BATCHSIZE][MAX_SKB_FRAGS+1];
+       int nf[TX_CLEAN_BATCHSIZE];
+       int nr_frags;
 
        total_count = 0;
        batch_limit = TX_CLEAN_BATCHSIZE;
 restart:
-       spin_lock_irqsave(&mac->tx->lock, flags);
+       spin_lock_irqsave(&txring->lock, flags);
+
+       start = txring->next_to_clean;
+       ring_limit = txring->next_to_fill;
 
-       start = mac->tx->next_to_clean;
-       ring_limit = mac->tx->next_to_fill;
+       prefetch(&TX_DESC_INFO(txring, start+1).skb);
 
        /* Compensate for when fill has wrapped but clean has not */
        if (start > ring_limit)
@@ -687,41 +755,45 @@ restart:
        for (i = start;
             descr_count < batch_limit && i < ring_limit;
             i += buf_count) {
-               u64 mactx = TX_RING(mac, i);
+               u64 mactx = TX_DESC(txring, i);
                struct sk_buff *skb;
 
+               skb = TX_DESC_INFO(txring, i+1).skb;
+               nr_frags = TX_DESC_INFO(txring, i).dma;
+
                if ((mactx  & XCT_MACTX_E) ||
-                   (*mac->tx_status & PAS_STATUS_ERROR))
+                   (*chan->status & PAS_STATUS_ERROR))
                        pasemi_mac_tx_error(mac, mactx);
 
                if (unlikely(mactx & XCT_MACTX_O))
                        /* Not yet transmitted */
                        break;
 
-               skb = TX_RING_INFO(mac, i+1).skb;
-               skbs[descr_count] = skb;
-
-               buf_count = 2 + skb_shinfo(skb)->nr_frags;
-               for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++)
-                       dmas[descr_count][j] = TX_RING_INFO(mac, i+1+j).dma;
-
-               TX_RING(mac, i) = 0;
-               TX_RING(mac, i+1) = 0;
-
+               buf_count = 2 + nr_frags;
                /* Since we always fill with an even number of entries, make
                 * sure we skip any unused one at the end as well.
                 */
                if (buf_count & 1)
                        buf_count++;
+
+               for (j = 0; j <= nr_frags; j++)
+                       dmas[descr_count][j] = TX_DESC_INFO(txring, i+1+j).dma;
+
+               skbs[descr_count] = skb;
+               nf[descr_count] = nr_frags;
+
+               TX_DESC(txring, i) = 0;
+               TX_DESC(txring, i+1) = 0;
+
                descr_count++;
        }
-       mac->tx->next_to_clean = i & (TX_RING_SIZE-1);
+       txring->next_to_clean = i & (TX_RING_SIZE-1);
 
-       spin_unlock_irqrestore(&mac->tx->lock, flags);
+       spin_unlock_irqrestore(&txring->lock, flags);
        netif_wake_queue(mac->netdev);
 
        for (i = 0; i < descr_count; i++)
-               pasemi_mac_unmap_tx_skb(mac, skbs[i], dmas[i]);
+               pasemi_mac_unmap_tx_skb(mac, nf[i], skbs[i], dmas[i]);
 
        total_count += descr_count;
 
@@ -735,11 +807,13 @@ restart:
 
 static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
 {
-       struct net_device *dev = data;
-       struct pasemi_mac *mac = netdev_priv(dev);
+       const struct pasemi_mac_rxring *rxring = data;
+       struct pasemi_mac *mac = rxring->mac;
+       struct net_device *dev = mac->netdev;
+       const struct pasemi_dmachan *chan = &rxring->chan;
        unsigned int reg;
 
-       if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
+       if (!(*chan->status & PAS_STATUS_CAUSE_M))
                return IRQ_NONE;
 
        /* Don't reset packet count so it won't fire again but clear
@@ -747,45 +821,77 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
         */
 
        reg = 0;
-       if (*mac->rx_status & PAS_STATUS_SOFT)
+       if (*chan->status & PAS_STATUS_SOFT)
                reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
-       if (*mac->rx_status & PAS_STATUS_ERROR)
+       if (*chan->status & PAS_STATUS_ERROR)
                reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
-       if (*mac->rx_status & PAS_STATUS_TIMER)
-               reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
 
        netif_rx_schedule(dev, &mac->napi);
 
-       write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
+       write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg);
 
        return IRQ_HANDLED;
 }
 
-static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
+#define TX_CLEAN_INTERVAL HZ
+
+static void pasemi_mac_tx_timer(unsigned long data)
 {
-       struct net_device *dev = data;
-       struct pasemi_mac *mac = netdev_priv(dev);
-       unsigned int reg, pcnt;
+       struct pasemi_mac_txring *txring = (struct pasemi_mac_txring *)data;
+       struct pasemi_mac *mac = txring->mac;
 
-       if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
-               return IRQ_NONE;
+       pasemi_mac_clean_tx(txring);
+
+       mod_timer(&txring->clean_timer, jiffies + TX_CLEAN_INTERVAL);
 
-       pasemi_mac_clean_tx(mac);
+       pasemi_mac_restart_tx_intr(mac);
+}
 
-       pcnt = *mac->tx_status & PAS_STATUS_PCNT_M;
+static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
+{
+       struct pasemi_mac_txring *txring = data;
+       const struct pasemi_dmachan *chan = &txring->chan;
+       struct pasemi_mac *mac = txring->mac;
+       unsigned int reg;
 
-       reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
+       if (!(*chan->status & PAS_STATUS_CAUSE_M))
+               return IRQ_NONE;
 
-       if (*mac->tx_status & PAS_STATUS_SOFT)
+       reg = 0;
+
+       if (*chan->status & PAS_STATUS_SOFT)
                reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
-       if (*mac->tx_status & PAS_STATUS_ERROR)
+       if (*chan->status & PAS_STATUS_ERROR)
                reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
 
-       write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+       mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2);
+
+       netif_rx_schedule(mac->netdev, &mac->napi);
+
+       if (reg)
+               write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg);
 
        return IRQ_HANDLED;
 }
 
+static void pasemi_mac_intf_disable(struct pasemi_mac *mac)
+{
+       unsigned int flags;
+
+       flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
+       flags &= ~PAS_MAC_CFG_PCFG_PE;
+       write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
+}
+
+static void pasemi_mac_intf_enable(struct pasemi_mac *mac)
+{
+       unsigned int flags;
+
+       flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
+       flags |= PAS_MAC_CFG_PCFG_PE;
+       write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
+}
+
 static void pasemi_adjust_link(struct net_device *dev)
 {
        struct pasemi_mac *mac = netdev_priv(dev);
@@ -801,11 +907,14 @@ static void pasemi_adjust_link(struct net_device *dev)
                        printk(KERN_INFO "%s: Link is down.\n", dev->name);
 
                netif_carrier_off(dev);
+               pasemi_mac_intf_disable(mac);
                mac->link = 0;
 
                return;
-       } else
+       } else {
+               pasemi_mac_intf_enable(mac);
                netif_carrier_on(dev);
+       }
 
        flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
        new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
@@ -897,15 +1006,14 @@ err:
 static int pasemi_mac_open(struct net_device *dev)
 {
        struct pasemi_mac *mac = netdev_priv(dev);
-       int base_irq;
        unsigned int flags;
        int ret;
 
        /* enable rx section */
-       write_dma_reg(mac, PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
+       write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
 
        /* enable tx section */
-       write_dma_reg(mac, PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
+       write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
 
        flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
                PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
@@ -913,62 +1021,59 @@ static int pasemi_mac_open(struct net_device *dev)
 
        write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
 
-       write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
-                          PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
+       ret = pasemi_mac_setup_rx_resources(dev);
+       if (ret)
+               goto out_rx_resources;
 
-       write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
-                          PAS_IOB_DMA_TXCH_CFG_CNTTH(128));
+       mac->tx = pasemi_mac_setup_tx_resources(dev);
 
-       /* Clear out any residual packet count state from firmware */
-       pasemi_mac_restart_rx_intr(mac);
-       pasemi_mac_restart_tx_intr(mac);
+       if (!mac->tx)
+               goto out_tx_ring;
 
-       /* 0xffffff is max value, about 16ms */
-       write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG,
-                          PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
+       /* 0x3ff with 33MHz clock is about 31us */
+       write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG,
+                     PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff));
 
-       ret = pasemi_mac_setup_rx_resources(dev);
-       if (ret)
-               goto out_rx_resources;
+       write_iob_reg(PAS_IOB_DMA_RXCH_CFG(mac->rx->chan.chno),
+                     PAS_IOB_DMA_RXCH_CFG_CNTTH(256));
 
-       ret = pasemi_mac_setup_tx_resources(dev);
-       if (ret)
-               goto out_tx_resources;
+       write_iob_reg(PAS_IOB_DMA_TXCH_CFG(mac->tx->chan.chno),
+                     PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
 
        write_mac_reg(mac, PAS_MAC_IPC_CHNL,
-                          PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) |
-                          PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch));
+                     PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) |
+                     PAS_MAC_IPC_CHNL_BCH(mac->rx->chan.chno));
 
        /* enable rx if */
-       write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
-                          PAS_DMA_RXINT_RCMDSTA_EN |
-                          PAS_DMA_RXINT_RCMDSTA_DROPS_M |
-                          PAS_DMA_RXINT_RCMDSTA_BP |
-                          PAS_DMA_RXINT_RCMDSTA_OO |
-                          PAS_DMA_RXINT_RCMDSTA_BT);
+       write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
+                     PAS_DMA_RXINT_RCMDSTA_EN |
+                     PAS_DMA_RXINT_RCMDSTA_DROPS_M |
+                     PAS_DMA_RXINT_RCMDSTA_BP |
+                     PAS_DMA_RXINT_RCMDSTA_OO |
+                     PAS_DMA_RXINT_RCMDSTA_BT);
 
        /* enable rx channel */
-       write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
-                          PAS_DMA_RXCHAN_CCMDSTA_EN |
-                          PAS_DMA_RXCHAN_CCMDSTA_DU |
-                          PAS_DMA_RXCHAN_CCMDSTA_OD |
-                          PAS_DMA_RXCHAN_CCMDSTA_FD |
-                          PAS_DMA_RXCHAN_CCMDSTA_DT);
+       pasemi_dma_start_chan(&rx_ring(mac)->chan, PAS_DMA_RXCHAN_CCMDSTA_DU |
+                                                  PAS_DMA_RXCHAN_CCMDSTA_OD |
+                                                  PAS_DMA_RXCHAN_CCMDSTA_FD |
+                                                  PAS_DMA_RXCHAN_CCMDSTA_DT);
 
        /* enable tx channel */
-       write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
-                          PAS_DMA_TXCHAN_TCMDSTA_EN |
-                          PAS_DMA_TXCHAN_TCMDSTA_SZ |
-                          PAS_DMA_TXCHAN_TCMDSTA_DB |
-                          PAS_DMA_TXCHAN_TCMDSTA_DE |
-                          PAS_DMA_TXCHAN_TCMDSTA_DA);
+       pasemi_dma_start_chan(&tx_ring(mac)->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ |
+                                                  PAS_DMA_TXCHAN_TCMDSTA_DB |
+                                                  PAS_DMA_TXCHAN_TCMDSTA_DE |
+                                                  PAS_DMA_TXCHAN_TCMDSTA_DA);
 
        pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE);
 
-       write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), RX_RING_SIZE>>1);
+       write_dma_reg(PAS_DMA_RXCHAN_INCR(rx_ring(mac)->chan.chno),
+                     RX_RING_SIZE>>1);
+
+       /* Clear out any residual packet count state from firmware */
+       pasemi_mac_restart_rx_intr(mac);
+       pasemi_mac_restart_tx_intr(mac);
 
-       flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
-               PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
+       flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
 
        if (mac->type == MAC_TYPE_GMAC)
                flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
@@ -979,55 +1084,63 @@ static int pasemi_mac_open(struct net_device *dev)
        write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
 
        ret = pasemi_mac_phy_init(dev);
-       /* Some configs don't have PHYs (XAUI etc), so don't complain about
-        * failed init due to -ENODEV.
-        */
-       if (ret && ret != -ENODEV)
-               dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
+       if (ret) {
+               /* Since we won't get link notification, just enable RX */
+               pasemi_mac_intf_enable(mac);
+               if (mac->type == MAC_TYPE_GMAC) {
+                       /* Warn for missing PHY on SGMII (1Gig) ports */
+                       dev_warn(&mac->pdev->dev,
+                                "PHY init failed: %d.\n", ret);
+                       dev_warn(&mac->pdev->dev,
+                                "Defaulting to 1Gbit full duplex\n");
+               }
+       }
 
        netif_start_queue(dev);
        napi_enable(&mac->napi);
 
-       /* Interrupts are a bit different for our DMA controller: While
-        * it's got one a regular PCI device header, the interrupt there
-        * is really the base of the range it's using. Each tx and rx
-        * channel has it's own interrupt source.
-        */
-
-       base_irq = virq_to_hw(mac->dma_pdev->irq);
+       snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx",
+                dev->name);
 
-       mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch);
-       mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch);
-
-       ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
-                         mac->tx->irq_name, dev);
+       ret = request_irq(mac->tx->chan.irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
+                         mac->tx_irq_name, mac->tx);
        if (ret) {
                dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
-                       base_irq + mac->dma_txch, ret);
+                       mac->tx->chan.irq, ret);
                goto out_tx_int;
        }
 
-       ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
-                         mac->rx->irq_name, dev);
+       snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx",
+                dev->name);
+
+       ret = request_irq(mac->rx->chan.irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
+                         mac->rx_irq_name, mac->rx);
        if (ret) {
                dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
-                       base_irq + 20 + mac->dma_rxch, ret);
+                       mac->rx->chan.irq, ret);
                goto out_rx_int;
        }
 
        if (mac->phydev)
                phy_start(mac->phydev);
 
+       init_timer(&mac->tx->clean_timer);
+       mac->tx->clean_timer.function = pasemi_mac_tx_timer;
+       mac->tx->clean_timer.data = (unsigned long)mac->tx;
+       mac->tx->clean_timer.expires = jiffies+HZ;
+       add_timer(&mac->tx->clean_timer);
+
        return 0;
 
 out_rx_int:
-       free_irq(mac->tx_irq, dev);
+       free_irq(mac->tx->chan.irq, mac->tx);
 out_tx_int:
        napi_disable(&mac->napi);
        netif_stop_queue(dev);
-       pasemi_mac_free_tx_resources(dev);
-out_tx_resources:
-       pasemi_mac_free_rx_resources(dev);
+out_tx_ring:
+       if (mac->tx)
+               pasemi_mac_free_tx_resources(mac);
+       pasemi_mac_free_rx_resources(mac);
 out_rx_resources:
 
        return ret;
@@ -1040,46 +1153,53 @@ static int pasemi_mac_close(struct net_device *dev)
        struct pasemi_mac *mac = netdev_priv(dev);
        unsigned int sta;
        int retries;
+       int rxch, txch;
+
+       rxch = rx_ring(mac)->chan.chno;
+       txch = tx_ring(mac)->chan.chno;
 
        if (mac->phydev) {
                phy_stop(mac->phydev);
                phy_disconnect(mac->phydev);
        }
 
+       del_timer_sync(&mac->tx->clean_timer);
+
        netif_stop_queue(dev);
        napi_disable(&mac->napi);
 
-       sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+       sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
        if (sta & (PAS_DMA_RXINT_RCMDSTA_BP |
                      PAS_DMA_RXINT_RCMDSTA_OO |
                      PAS_DMA_RXINT_RCMDSTA_BT))
                printk(KERN_DEBUG "pasemi_mac: rcmdsta error: 0x%08x\n", sta);
 
-       sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+       sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
        if (sta & (PAS_DMA_RXCHAN_CCMDSTA_DU |
                     PAS_DMA_RXCHAN_CCMDSTA_OD |
                     PAS_DMA_RXCHAN_CCMDSTA_FD |
                     PAS_DMA_RXCHAN_CCMDSTA_DT))
                printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta);
 
-       sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
-       if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ |
-                     PAS_DMA_TXCHAN_TCMDSTA_DB |
-                     PAS_DMA_TXCHAN_TCMDSTA_DE |
-                     PAS_DMA_TXCHAN_TCMDSTA_DA))
+       sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch));
+       if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | PAS_DMA_TXCHAN_TCMDSTA_DB |
+                     PAS_DMA_TXCHAN_TCMDSTA_DE | PAS_DMA_TXCHAN_TCMDSTA_DA))
                printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta);
 
        /* Clean out any pending buffers */
-       pasemi_mac_clean_tx(mac);
-       pasemi_mac_clean_rx(mac, RX_RING_SIZE);
+       pasemi_mac_clean_tx(tx_ring(mac));
+       pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE);
 
        /* Disable interface */
-       write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST);
-       write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST);
-       write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST);
+       write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch),
+                     PAS_DMA_TXCHAN_TCMDSTA_ST);
+       write_dma_reg( PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
+                     PAS_DMA_RXINT_RCMDSTA_ST);
+       write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch),
+                     PAS_DMA_RXCHAN_CCMDSTA_ST);
 
        for (retries = 0; retries < MAX_RETRIES; retries++) {
-               sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
+               sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(rxch));
                if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT))
                        break;
                cond_resched();
@@ -1089,7 +1209,7 @@ static int pasemi_mac_close(struct net_device *dev)
                dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
 
        for (retries = 0; retries < MAX_RETRIES; retries++) {
-               sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+               sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch));
                if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT))
                        break;
                cond_resched();
@@ -1099,7 +1219,7 @@ static int pasemi_mac_close(struct net_device *dev)
                dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
 
        for (retries = 0; retries < MAX_RETRIES; retries++) {
-               sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+               sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
                if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT))
                        break;
                cond_resched();
@@ -1112,16 +1232,16 @@ static int pasemi_mac_close(struct net_device *dev)
         * stopping, since you can't disable when active.
         */
 
-       write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0);
-       write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0);
-       write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
+       write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 0);
+       write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), 0);
+       write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
 
-       free_irq(mac->tx_irq, dev);
-       free_irq(mac->rx_irq, dev);
+       free_irq(mac->tx->chan.irq, mac->tx);
+       free_irq(mac->rx->chan.irq, mac->rx);
 
        /* Free resources */
-       pasemi_mac_free_rx_resources(dev);
-       pasemi_mac_free_tx_resources(dev);
+       pasemi_mac_free_rx_resources(mac);
+       pasemi_mac_free_tx_resources(mac);
 
        return 0;
 }
@@ -1135,6 +1255,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        unsigned int map_size[MAX_SKB_FRAGS+1];
        unsigned long flags;
        int i, nfrags;
+       int fill;
 
        dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD;
 
@@ -1178,10 +1299,12 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 
        mactx = dflags | XCT_MACTX_LLEN(skb->len);
 
-       txring = mac->tx;
+       txring = tx_ring(mac);
 
        spin_lock_irqsave(&txring->lock, flags);
 
+       fill = txring->next_to_fill;
+
        /* Avoid stepping on the same cache line that the DMA controller
         * is currently about to send, so leave at least 8 words available.
         * Total free space needed is mactx + fragments + 8
@@ -1192,13 +1315,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
                goto out_err;
        }
 
-       TX_RING(mac, txring->next_to_fill) = mactx;
-       txring->next_to_fill++;
-       TX_RING_INFO(mac, txring->next_to_fill).skb = skb;
+       TX_DESC(txring, fill) = mactx;
+       TX_DESC_INFO(txring, fill).dma = nfrags;
+       fill++;
+       TX_DESC_INFO(txring, fill).skb = skb;
        for (i = 0; i <= nfrags; i++) {
-               TX_RING(mac, txring->next_to_fill+i) =
-               XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
-               TX_RING_INFO(mac, txring->next_to_fill+i).dma = map[i];
+               TX_DESC(txring, fill+i) =
+                       XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
+               TX_DESC_INFO(txring, fill+i).dma = map[i];
        }
 
        /* We have to add an even number of 8-byte entries to the ring
@@ -1208,15 +1332,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
        if (nfrags & 1)
                nfrags++;
 
-       txring->next_to_fill = (txring->next_to_fill + nfrags + 1) &
-                               (TX_RING_SIZE-1);
+       txring->next_to_fill = (fill + nfrags + 1) & (TX_RING_SIZE-1);
 
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
        spin_unlock_irqrestore(&txring->lock, flags);
 
-       write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), (nfrags+2) >> 1);
+       write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), (nfrags+2) >> 1);
 
        return NETDEV_TX_OK;
 
@@ -1232,7 +1355,7 @@ out_err_nolock:
 
 static void pasemi_mac_set_rx_mode(struct net_device *dev)
 {
-       struct pasemi_mac *mac = netdev_priv(dev);
+       const struct pasemi_mac *mac = netdev_priv(dev);
        unsigned int flags;
 
        flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
@@ -1253,88 +1376,21 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget)
        struct net_device *dev = mac->netdev;
        int pkts;
 
-       pasemi_mac_clean_tx(mac);
-       pkts = pasemi_mac_clean_rx(mac, budget);
+       pasemi_mac_clean_tx(tx_ring(mac));
+       pkts = pasemi_mac_clean_rx(rx_ring(mac), budget);
        if (pkts < budget) {
                /* all done, no more packets present */
                netif_rx_complete(dev, napi);
 
                pasemi_mac_restart_rx_intr(mac);
+               pasemi_mac_restart_tx_intr(mac);
        }
        return pkts;
 }
 
-static void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
-{
-       struct device_node *dn;
-       void __iomem *ret;
-
-       dn = pci_device_to_OF_node(p);
-       if (!dn)
-               goto fallback;
-
-       ret = of_iomap(dn, index);
-       if (!ret)
-               goto fallback;
-
-       return ret;
-fallback:
-       /* This is hardcoded and ugly, but we have some firmware versions
-        * that don't provide the register space in the device tree. Luckily
-        * they are at well-known locations so we can just do the math here.
-        */
-       return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
-}
-
-static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
-{
-       struct resource res;
-       struct device_node *dn;
-       int err;
-
-       mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
-       if (!mac->dma_pdev) {
-               dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
-               return -ENODEV;
-       }
-
-       mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
-       if (!mac->iob_pdev) {
-               dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
-               return -ENODEV;
-       }
-
-       mac->regs = map_onedev(mac->pdev, 0);
-       mac->dma_regs = map_onedev(mac->dma_pdev, 0);
-       mac->iob_regs = map_onedev(mac->iob_pdev, 0);
-
-       if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
-               dev_err(&mac->pdev->dev, "Can't map registers\n");
-               return -ENODEV;
-       }
-
-       /* The dma status structure is located in the I/O bridge, and
-        * is cache coherent.
-        */
-       if (!dma_status) {
-               dn = pci_device_to_OF_node(mac->iob_pdev);
-               if (dn)
-                       err = of_address_to_resource(dn, 1, &res);
-               if (!dn || err) {
-                       /* Fallback for old firmware */
-                       res.start = 0xfd800000;
-                       res.end = res.start + 0x1000;
-               }
-               dma_status = __ioremap(res.start, res.end-res.start, 0);
-       }
-
-       return 0;
-}
-
 static int __devinit
 pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       static int index = 0;
        struct net_device *dev;
        struct pasemi_mac *mac;
        int err;
@@ -1362,20 +1418,46 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
 
-       dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG;
+       dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG |
+                       NETIF_F_HIGHDMA;
 
-       /* These should come out of the device tree eventually */
-       mac->dma_txch = index;
-       mac->dma_rxch = index;
+       mac->lro_mgr.max_aggr = LRO_MAX_AGGR;
+       mac->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
+       mac->lro_mgr.lro_arr = mac->lro_desc;
+       mac->lro_mgr.get_skb_header = get_skb_hdr;
+       mac->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
+       mac->lro_mgr.dev = mac->netdev;
+       mac->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+       mac->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
 
-       /* We probe GMAC before XAUI, but the DMA interfaces are
-        * in XAUI, GMAC order.
-        */
-       if (index < 4)
-               mac->dma_if = index + 2;
-       else
-               mac->dma_if = index - 4;
-       index++;
+
+       mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+       if (!mac->dma_pdev) {
+               dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
+               err = -ENODEV;
+               goto out;
+       }
+
+       mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+       if (!mac->iob_pdev) {
+               dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
+               err = -ENODEV;
+               goto out;
+       }
+
+       /* get mac addr from device tree */
+       if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) {
+               err = -ENODEV;
+               goto out;
+       }
+       memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));
+
+       mac->dma_if = mac_to_intf(mac);
+       if (mac->dma_if < 0) {
+               dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
+               err = -ENODEV;
+               goto out;
+       }
 
        switch (pdev->device) {
        case 0xa005:
@@ -1389,25 +1471,14 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out;
        }
 
-       /* get mac addr from device tree */
-       if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) {
-               err = -ENODEV;
-               goto out;
-       }
-       memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));
-
        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;
 
-       err = pasemi_mac_map_regs(mac);
        if (err)
                goto out;
 
-       mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
-       mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
-
        mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
        /* Enable most messages by default */
@@ -1420,11 +1491,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        err);
                goto out;
        } else if netif_msg_probe(mac)
-               printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, "
-                      "hw addr %s\n",
+               printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %s\n",
                       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
-                      mac->dma_if, mac->dma_txch, mac->dma_rxch,
-                      print_mac(mac_buf, dev->dev_addr));
+                      mac->dma_if, print_mac(mac_buf, dev->dev_addr));
 
        return err;
 
@@ -1433,12 +1502,6 @@ out:
                pci_dev_put(mac->iob_pdev);
        if (mac->dma_pdev)
                pci_dev_put(mac->dma_pdev);
-       if (mac->dma_regs)
-               iounmap(mac->dma_regs);
-       if (mac->iob_regs)
-               iounmap(mac->iob_regs);
-       if (mac->regs)
-               iounmap(mac->regs);
 
        free_netdev(dev);
 out_disable_device:
@@ -1463,9 +1526,8 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev)
        pci_dev_put(mac->dma_pdev);
        pci_dev_put(mac->iob_pdev);
 
-       iounmap(mac->regs);
-       iounmap(mac->dma_regs);
-       iounmap(mac->iob_regs);
+       pasemi_dma_free_chan(&mac->tx->chan);
+       pasemi_dma_free_chan(&mac->rx->chan);
 
        pci_set_drvdata(pdev, NULL);
        free_netdev(netdev);
@@ -1489,12 +1551,16 @@ static struct pci_driver pasemi_mac_driver = {
 static void __exit pasemi_mac_cleanup_module(void)
 {
        pci_unregister_driver(&pasemi_mac_driver);
-       __iounmap(dma_status);
-       dma_status = NULL;
 }
 
 int pasemi_mac_init_module(void)
 {
+       int err;
+
+       err = pasemi_dma_init();
+       if (err)
+               return err;
+
        return pci_register_driver(&pasemi_mac_driver);
 }
 
index 60368df72634cc3931399b9b6c57e38b82a279a7..8bee2a664c83760d12a897eb4230331f6e99c229 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/phy.h>
 
+#define MAX_LRO_DESCRIPTORS 8
+
 struct pasemi_mac_txring {
+       struct pasemi_dmachan chan; /* Must be first */
        spinlock_t       lock;
-       u64             *ring;
-       dma_addr_t       dma;
        unsigned int     size;
        unsigned int     next_to_fill;
        unsigned int     next_to_clean;
        struct pasemi_mac_buffer *ring_info;
-       char             irq_name[10];  /* "eth%d tx" */
+       struct pasemi_mac *mac; /* Needed in intr handler */
+       struct timer_list clean_timer;
 };
 
 struct pasemi_mac_rxring {
+       struct pasemi_dmachan chan; /* Must be first */
        spinlock_t       lock;
-       u64             *ring;  /* RX channel descriptor ring */
-       dma_addr_t       dma;
        u64             *buffers;       /* RX interface buffer ring */
        dma_addr_t       buf_dma;
        unsigned int     size;
        unsigned int     next_to_fill;
        unsigned int     next_to_clean;
        struct pasemi_mac_buffer *ring_info;
-       char             irq_name[10];  /* "eth%d rx" */
+       struct pasemi_mac *mac; /* Needed in intr handler */
 };
 
 struct pasemi_mac {
        struct net_device *netdev;
-       void __iomem *regs;
-       void __iomem *dma_regs;
-       void __iomem *iob_regs;
        struct pci_dev *pdev;
        struct pci_dev *dma_pdev;
        struct pci_dev *iob_pdev;
        struct phy_device *phydev;
        struct napi_struct napi;
 
-       /* Pointer to the cacheable per-channel status registers */
-       u64     *rx_status;
-       u64     *tx_status;
-
        u8              type;
 #define MAC_TYPE_GMAC  1
 #define MAC_TYPE_XAUI  2
-       u32     dma_txch;
        u32     dma_if;
-       u32     dma_rxch;
 
        u8              mac_addr[6];
 
+       struct net_lro_mgr      lro_mgr;
+       struct net_lro_desc     lro_desc[MAX_LRO_DESCRIPTORS];
        struct timer_list       rxtimer;
+       unsigned int            lro_max_aggr;
 
        struct pasemi_mac_txring *tx;
        struct pasemi_mac_rxring *rx;
-       unsigned long   tx_irq;
-       unsigned long   rx_irq;
+       char            tx_irq_name[10];                /* "eth%d tx" */
+       char            rx_irq_name[10];                /* "eth%d rx" */
        int     link;
        int     speed;
        int     duplex;
@@ -95,11 +90,8 @@ struct pasemi_mac_buffer {
 };
 
 
-/* status register layout in IOB region, at 0xfb800000 */
-struct pasdma_status {
-       u64 rx_sta[64];
-       u64 tx_sta[20];
-};
+/* PCI register offsets and formats */
+
 
 /* MAC CFG register offsets */
 enum {
@@ -173,333 +165,4 @@ enum {
 #define PAS_MAC_IPC_CHNL_BCH(x)                (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \
                                         PAS_MAC_IPC_CHNL_BCH_M)
 
-/* All these registers live in the PCI configuration space for the DMA PCI
- * device. Use the normal PCI config access functions for them.
- */
-enum {
-       PAS_DMA_COM_TXCMD = 0x100,      /* Transmit Command Register  */
-       PAS_DMA_COM_TXSTA = 0x104,      /* Transmit Status Register   */
-       PAS_DMA_COM_RXCMD = 0x108,      /* Receive Command Register   */
-       PAS_DMA_COM_RXSTA = 0x10c,      /* Receive Status Register    */
-};
-#define PAS_DMA_COM_TXCMD_EN   0x00000001 /* enable */
-#define PAS_DMA_COM_TXSTA_ACT  0x00000001 /* active */
-#define PAS_DMA_COM_RXCMD_EN   0x00000001 /* enable */
-#define PAS_DMA_COM_RXSTA_ACT  0x00000001 /* active */
-
-
-/* Per-interface and per-channel registers */
-#define _PAS_DMA_RXINT_STRIDE          0x20
-#define PAS_DMA_RXINT_RCMDSTA(i)       (0x200+(i)*_PAS_DMA_RXINT_STRIDE)
-#define    PAS_DMA_RXINT_RCMDSTA_EN    0x00000001
-#define    PAS_DMA_RXINT_RCMDSTA_ST    0x00000002
-#define    PAS_DMA_RXINT_RCMDSTA_MBT   0x00000008
-#define    PAS_DMA_RXINT_RCMDSTA_MDR   0x00000010
-#define    PAS_DMA_RXINT_RCMDSTA_MOO   0x00000020
-#define    PAS_DMA_RXINT_RCMDSTA_MBP   0x00000040
-#define    PAS_DMA_RXINT_RCMDSTA_BT    0x00000800
-#define    PAS_DMA_RXINT_RCMDSTA_DR    0x00001000
-#define    PAS_DMA_RXINT_RCMDSTA_OO    0x00002000
-#define    PAS_DMA_RXINT_RCMDSTA_BP    0x00004000
-#define    PAS_DMA_RXINT_RCMDSTA_TB    0x00008000
-#define    PAS_DMA_RXINT_RCMDSTA_ACT   0x00010000
-#define    PAS_DMA_RXINT_RCMDSTA_DROPS_M       0xfffe0000
-#define    PAS_DMA_RXINT_RCMDSTA_DROPS_S       17
-#define PAS_DMA_RXINT_CFG(i)           (0x204+(i)*_PAS_DMA_RXINT_STRIDE)
-#define    PAS_DMA_RXINT_CFG_RBP       0x80000000
-#define    PAS_DMA_RXINT_CFG_ITRR      0x40000000
-#define    PAS_DMA_RXINT_CFG_DHL_M     0x07000000
-#define    PAS_DMA_RXINT_CFG_DHL_S     24
-#define    PAS_DMA_RXINT_CFG_DHL(x)    (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
-                                        PAS_DMA_RXINT_CFG_DHL_M)
-#define    PAS_DMA_RXINT_CFG_ITR       0x00400000
-#define    PAS_DMA_RXINT_CFG_LW                0x00200000
-#define    PAS_DMA_RXINT_CFG_L2                0x00100000
-#define    PAS_DMA_RXINT_CFG_HEN       0x00080000
-#define    PAS_DMA_RXINT_CFG_WIF       0x00000002
-#define    PAS_DMA_RXINT_CFG_WIL       0x00000001
-
-#define PAS_DMA_RXINT_INCR(i)          (0x210+(i)*_PAS_DMA_RXINT_STRIDE)
-#define    PAS_DMA_RXINT_INCR_INCR_M   0x0000ffff
-#define    PAS_DMA_RXINT_INCR_INCR_S   0
-#define    PAS_DMA_RXINT_INCR_INCR(x)  ((x) & 0x0000ffff)
-#define PAS_DMA_RXINT_BASEL(i)         (0x218+(i)*_PAS_DMA_RXINT_STRIDE)
-#define    PAS_DMA_RXINT_BASEL_BRBL(x) ((x) & ~0x3f)
-#define PAS_DMA_RXINT_BASEU(i)         (0x21c+(i)*_PAS_DMA_RXINT_STRIDE)
-#define    PAS_DMA_RXINT_BASEU_BRBH(x) ((x) & 0xfff)
-#define    PAS_DMA_RXINT_BASEU_SIZ_M   0x3fff0000      /* # of cache lines worth of buffer ring */
-#define    PAS_DMA_RXINT_BASEU_SIZ_S   16              /* 0 = 16K */
-#define    PAS_DMA_RXINT_BASEU_SIZ(x)  (((x) << PAS_DMA_RXINT_BASEU_SIZ_S) & \
-                                        PAS_DMA_RXINT_BASEU_SIZ_M)
-
-
-#define _PAS_DMA_TXCHAN_STRIDE 0x20    /* Size per channel             */
-#define _PAS_DMA_TXCHAN_TCMDSTA        0x300   /* Command / Status             */
-#define _PAS_DMA_TXCHAN_CFG    0x304   /* Configuration                */
-#define _PAS_DMA_TXCHAN_DSCRBU 0x308   /* Descriptor BU Allocation     */
-#define _PAS_DMA_TXCHAN_INCR   0x310   /* Descriptor increment         */
-#define _PAS_DMA_TXCHAN_CNT    0x314   /* Descriptor count/offset      */
-#define _PAS_DMA_TXCHAN_BASEL  0x318   /* Descriptor ring base (low)   */
-#define _PAS_DMA_TXCHAN_BASEU  0x31c   /*                      (high)  */
-#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
-#define    PAS_DMA_TXCHAN_TCMDSTA_EN   0x00000001      /* Enabled */
-#define    PAS_DMA_TXCHAN_TCMDSTA_ST   0x00000002      /* Stop interface */
-#define    PAS_DMA_TXCHAN_TCMDSTA_ACT  0x00010000      /* Active */
-#define    PAS_DMA_TXCHAN_TCMDSTA_SZ   0x00000800
-#define    PAS_DMA_TXCHAN_TCMDSTA_DB   0x00000400
-#define    PAS_DMA_TXCHAN_TCMDSTA_DE   0x00000200
-#define    PAS_DMA_TXCHAN_TCMDSTA_DA   0x00000100
-#define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
-#define    PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000      /* Type = interface */
-#define    PAS_DMA_TXCHAN_CFG_TATTR_M  0x0000003c
-#define    PAS_DMA_TXCHAN_CFG_TATTR_S  2
-#define    PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
-                                        PAS_DMA_TXCHAN_CFG_TATTR_M)
-#define    PAS_DMA_TXCHAN_CFG_WT_M     0x000001c0
-#define    PAS_DMA_TXCHAN_CFG_WT_S     6
-#define    PAS_DMA_TXCHAN_CFG_WT(x)    (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
-                                        PAS_DMA_TXCHAN_CFG_WT_M)
-#define    PAS_DMA_TXCHAN_CFG_TRD      0x00010000      /* translate data */
-#define    PAS_DMA_TXCHAN_CFG_TRR      0x00008000      /* translate rings */
-#define    PAS_DMA_TXCHAN_CFG_UP       0x00004000      /* update tx descr when sent */
-#define    PAS_DMA_TXCHAN_CFG_CL       0x00002000      /* Clean last line */
-#define    PAS_DMA_TXCHAN_CFG_CF       0x00001000      /* Clean first line */
-#define PAS_DMA_TXCHAN_INCR(c)    (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
-#define PAS_DMA_TXCHAN_BASEL(c)   (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
-#define    PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
-#define    PAS_DMA_TXCHAN_BASEL_BRBL_S 0
-#define    PAS_DMA_TXCHAN_BASEL_BRBL(x)        (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
-                                        PAS_DMA_TXCHAN_BASEL_BRBL_M)
-#define PAS_DMA_TXCHAN_BASEU(c)   (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
-#define    PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
-#define    PAS_DMA_TXCHAN_BASEU_BRBH_S 0
-#define    PAS_DMA_TXCHAN_BASEU_BRBH(x)        (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
-                                        PAS_DMA_TXCHAN_BASEU_BRBH_M)
-/* # of cache lines worth of buffer ring */
-#define    PAS_DMA_TXCHAN_BASEU_SIZ_M  0x3fff0000
-#define    PAS_DMA_TXCHAN_BASEU_SIZ_S  16              /* 0 = 16K */
-#define    PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
-                                        PAS_DMA_TXCHAN_BASEU_SIZ_M)
-
-#define _PAS_DMA_RXCHAN_STRIDE 0x20    /* Size per channel             */
-#define _PAS_DMA_RXCHAN_CCMDSTA        0x800   /* Command / Status             */
-#define _PAS_DMA_RXCHAN_CFG    0x804   /* Configuration                */
-#define _PAS_DMA_RXCHAN_INCR   0x810   /* Descriptor increment         */
-#define _PAS_DMA_RXCHAN_CNT    0x814   /* Descriptor count/offset      */
-#define _PAS_DMA_RXCHAN_BASEL  0x818   /* Descriptor ring base (low)   */
-#define _PAS_DMA_RXCHAN_BASEU  0x81c   /*                      (high)  */
-#define PAS_DMA_RXCHAN_CCMDSTA(c) (0x800+(c)*_PAS_DMA_RXCHAN_STRIDE)
-#define    PAS_DMA_RXCHAN_CCMDSTA_EN   0x00000001      /* Enabled */
-#define    PAS_DMA_RXCHAN_CCMDSTA_ST   0x00000002      /* Stop interface */
-#define    PAS_DMA_RXCHAN_CCMDSTA_ACT  0x00010000      /* Active */
-#define    PAS_DMA_RXCHAN_CCMDSTA_DU   0x00020000
-#define    PAS_DMA_RXCHAN_CCMDSTA_OD   0x00002000
-#define    PAS_DMA_RXCHAN_CCMDSTA_FD   0x00001000
-#define    PAS_DMA_RXCHAN_CCMDSTA_DT   0x00000800
-#define PAS_DMA_RXCHAN_CFG(c)     (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE)
-#define    PAS_DMA_RXCHAN_CFG_CTR      0x00000400
-#define    PAS_DMA_RXCHAN_CFG_HBU_M    0x00000380
-#define    PAS_DMA_RXCHAN_CFG_HBU_S    7
-#define    PAS_DMA_RXCHAN_CFG_HBU(x)   (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \
-                                        PAS_DMA_RXCHAN_CFG_HBU_M)
-#define PAS_DMA_RXCHAN_INCR(c)    (0x810+(c)*_PAS_DMA_RXCHAN_STRIDE)
-#define PAS_DMA_RXCHAN_BASEL(c)   (0x818+(c)*_PAS_DMA_RXCHAN_STRIDE)
-#define    PAS_DMA_RXCHAN_BASEL_BRBL_M 0xffffffc0
-#define    PAS_DMA_RXCHAN_BASEL_BRBL_S 0
-#define    PAS_DMA_RXCHAN_BASEL_BRBL(x)        (((x) << PAS_DMA_RXCHAN_BASEL_BRBL_S) & \
-                                        PAS_DMA_RXCHAN_BASEL_BRBL_M)
-#define PAS_DMA_RXCHAN_BASEU(c)   (0x81c+(c)*_PAS_DMA_RXCHAN_STRIDE)
-#define    PAS_DMA_RXCHAN_BASEU_BRBH_M 0x00000fff
-#define    PAS_DMA_RXCHAN_BASEU_BRBH_S 0
-#define    PAS_DMA_RXCHAN_BASEU_BRBH(x)        (((x) << PAS_DMA_RXCHAN_BASEU_BRBH_S) & \
-                                        PAS_DMA_RXCHAN_BASEU_BRBH_M)
-/* # of cache lines worth of buffer ring */
-#define    PAS_DMA_RXCHAN_BASEU_SIZ_M  0x3fff0000
-#define    PAS_DMA_RXCHAN_BASEU_SIZ_S  16              /* 0 = 16K */
-#define    PAS_DMA_RXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_RXCHAN_BASEU_SIZ_S) & \
-                                        PAS_DMA_RXCHAN_BASEU_SIZ_M)
-
-#define    PAS_STATUS_PCNT_M           0x000000000000ffffull
-#define    PAS_STATUS_PCNT_S           0
-#define    PAS_STATUS_DCNT_M           0x00000000ffff0000ull
-#define    PAS_STATUS_DCNT_S           16
-#define    PAS_STATUS_BPCNT_M          0x0000ffff00000000ull
-#define    PAS_STATUS_BPCNT_S          32
-#define    PAS_STATUS_CAUSE_M          0xf000000000000000ull
-#define    PAS_STATUS_TIMER            0x1000000000000000ull
-#define    PAS_STATUS_ERROR            0x2000000000000000ull
-#define    PAS_STATUS_SOFT             0x4000000000000000ull
-#define    PAS_STATUS_INT              0x8000000000000000ull
-
-#define PAS_IOB_COM_PKTHDRCNT          0x120
-#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_M     0x0fff0000
-#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_S     16
-#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_M     0x00000fff
-#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_S     0
-
-#define PAS_IOB_DMA_RXCH_CFG(i)                (0x1100 + (i)*4)
-#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_M                0x00000fff
-#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_S                0
-#define    PAS_IOB_DMA_RXCH_CFG_CNTTH(x)       (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
-                                                PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
-#define PAS_IOB_DMA_TXCH_CFG(i)                (0x1200 + (i)*4)
-#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_M                0x00000fff
-#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_S                0
-#define    PAS_IOB_DMA_TXCH_CFG_CNTTH(x)       (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
-                                                PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
-#define PAS_IOB_DMA_RXCH_STAT(i)       (0x1300 + (i)*4)
-#define    PAS_IOB_DMA_RXCH_STAT_INTGEN        0x00001000
-#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_M      0x00000fff
-#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_S      0
-#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL(x)     (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
-                                                PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
-#define PAS_IOB_DMA_TXCH_STAT(i)       (0x1400 + (i)*4)
-#define    PAS_IOB_DMA_TXCH_STAT_INTGEN        0x00001000
-#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_M      0x00000fff
-#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_S      0
-#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL(x)     (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
-                                                PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
-#define PAS_IOB_DMA_RXCH_RESET(i)      (0x1500 + (i)*4)
-#define    PAS_IOB_DMA_RXCH_RESET_PCNT_M       0xffff0000
-#define    PAS_IOB_DMA_RXCH_RESET_PCNT_S       16
-#define    PAS_IOB_DMA_RXCH_RESET_PCNT(x)      (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
-                                                PAS_IOB_DMA_RXCH_RESET_PCNT_M)
-#define    PAS_IOB_DMA_RXCH_RESET_PCNTRST      0x00000020
-#define    PAS_IOB_DMA_RXCH_RESET_DCNTRST      0x00000010
-#define    PAS_IOB_DMA_RXCH_RESET_TINTC                0x00000008
-#define    PAS_IOB_DMA_RXCH_RESET_DINTC                0x00000004
-#define    PAS_IOB_DMA_RXCH_RESET_SINTC                0x00000002
-#define    PAS_IOB_DMA_RXCH_RESET_PINTC                0x00000001
-#define PAS_IOB_DMA_TXCH_RESET(i)      (0x1600 + (i)*4)
-#define    PAS_IOB_DMA_TXCH_RESET_PCNT_M       0xffff0000
-#define    PAS_IOB_DMA_TXCH_RESET_PCNT_S       16
-#define    PAS_IOB_DMA_TXCH_RESET_PCNT(x)      (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
-                                                PAS_IOB_DMA_TXCH_RESET_PCNT_M)
-#define    PAS_IOB_DMA_TXCH_RESET_PCNTRST      0x00000020
-#define    PAS_IOB_DMA_TXCH_RESET_DCNTRST      0x00000010
-#define    PAS_IOB_DMA_TXCH_RESET_TINTC                0x00000008
-#define    PAS_IOB_DMA_TXCH_RESET_DINTC                0x00000004
-#define    PAS_IOB_DMA_TXCH_RESET_SINTC                0x00000002
-#define    PAS_IOB_DMA_TXCH_RESET_PINTC                0x00000001
-
-#define PAS_IOB_DMA_COM_TIMEOUTCFG             0x1700
-#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M   0x00ffffff
-#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S   0
-#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x)  (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
-                                                PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
-
-/* Transmit descriptor fields */
-#define        XCT_MACTX_T             0x8000000000000000ull
-#define        XCT_MACTX_ST            0x4000000000000000ull
-#define XCT_MACTX_NORES                0x0000000000000000ull
-#define XCT_MACTX_8BRES                0x1000000000000000ull
-#define XCT_MACTX_24BRES       0x2000000000000000ull
-#define XCT_MACTX_40BRES       0x3000000000000000ull
-#define XCT_MACTX_I            0x0800000000000000ull
-#define XCT_MACTX_O            0x0400000000000000ull
-#define XCT_MACTX_E            0x0200000000000000ull
-#define XCT_MACTX_VLAN_M       0x0180000000000000ull
-#define XCT_MACTX_VLAN_NOP     0x0000000000000000ull
-#define XCT_MACTX_VLAN_REMOVE  0x0080000000000000ull
-#define XCT_MACTX_VLAN_INSERT   0x0100000000000000ull
-#define XCT_MACTX_VLAN_REPLACE  0x0180000000000000ull
-#define XCT_MACTX_CRC_M                0x0060000000000000ull
-#define XCT_MACTX_CRC_NOP      0x0000000000000000ull
-#define XCT_MACTX_CRC_INSERT   0x0020000000000000ull
-#define XCT_MACTX_CRC_PAD      0x0040000000000000ull
-#define XCT_MACTX_CRC_REPLACE  0x0060000000000000ull
-#define XCT_MACTX_SS           0x0010000000000000ull
-#define XCT_MACTX_LLEN_M       0x00007fff00000000ull
-#define XCT_MACTX_LLEN_S       32ull
-#define XCT_MACTX_LLEN(x)      ((((long)(x)) << XCT_MACTX_LLEN_S) & \
-                                XCT_MACTX_LLEN_M)
-#define XCT_MACTX_IPH_M                0x00000000f8000000ull
-#define XCT_MACTX_IPH_S                27ull
-#define XCT_MACTX_IPH(x)       ((((long)(x)) << XCT_MACTX_IPH_S) & \
-                                XCT_MACTX_IPH_M)
-#define XCT_MACTX_IPO_M                0x0000000007c00000ull
-#define XCT_MACTX_IPO_S                22ull
-#define XCT_MACTX_IPO(x)       ((((long)(x)) << XCT_MACTX_IPO_S) & \
-                                XCT_MACTX_IPO_M)
-#define XCT_MACTX_CSUM_M       0x0000000000000060ull
-#define XCT_MACTX_CSUM_NOP     0x0000000000000000ull
-#define XCT_MACTX_CSUM_TCP     0x0000000000000040ull
-#define XCT_MACTX_CSUM_UDP     0x0000000000000060ull
-#define XCT_MACTX_V6           0x0000000000000010ull
-#define XCT_MACTX_C            0x0000000000000004ull
-#define XCT_MACTX_AL2          0x0000000000000002ull
-
-/* Receive descriptor fields */
-#define        XCT_MACRX_T             0x8000000000000000ull
-#define        XCT_MACRX_ST            0x4000000000000000ull
-#define XCT_MACRX_RR_M         0x3000000000000000ull
-#define XCT_MACRX_RR_NORES     0x0000000000000000ull
-#define XCT_MACRX_RR_8BRES     0x1000000000000000ull
-#define XCT_MACRX_O            0x0400000000000000ull
-#define XCT_MACRX_E            0x0200000000000000ull
-#define XCT_MACRX_FF           0x0100000000000000ull
-#define XCT_MACRX_PF           0x0080000000000000ull
-#define XCT_MACRX_OB           0x0040000000000000ull
-#define XCT_MACRX_OD           0x0020000000000000ull
-#define XCT_MACRX_FS           0x0010000000000000ull
-#define XCT_MACRX_NB_M         0x000fc00000000000ull
-#define XCT_MACRX_NB_S         46ULL
-#define XCT_MACRX_NB(x)                ((((long)(x)) << XCT_MACRX_NB_S) & \
-                                XCT_MACRX_NB_M)
-#define XCT_MACRX_LLEN_M       0x00003fff00000000ull
-#define XCT_MACRX_LLEN_S       32ULL
-#define XCT_MACRX_LLEN(x)      ((((long)(x)) << XCT_MACRX_LLEN_S) & \
-                                XCT_MACRX_LLEN_M)
-#define XCT_MACRX_CRC          0x0000000080000000ull
-#define XCT_MACRX_LEN_M                0x0000000060000000ull
-#define XCT_MACRX_LEN_TOOSHORT 0x0000000020000000ull
-#define XCT_MACRX_LEN_BELOWMIN 0x0000000040000000ull
-#define XCT_MACRX_LEN_TRUNC    0x0000000060000000ull
-#define XCT_MACRX_CAST_M       0x0000000018000000ull
-#define XCT_MACRX_CAST_UNI     0x0000000000000000ull
-#define XCT_MACRX_CAST_MULTI   0x0000000008000000ull
-#define XCT_MACRX_CAST_BROAD   0x0000000010000000ull
-#define XCT_MACRX_CAST_PAUSE   0x0000000018000000ull
-#define XCT_MACRX_VLC_M                0x0000000006000000ull
-#define XCT_MACRX_FM           0x0000000001000000ull
-#define XCT_MACRX_HTY_M                0x0000000000c00000ull
-#define XCT_MACRX_HTY_IPV4_OK  0x0000000000000000ull
-#define XCT_MACRX_HTY_IPV6     0x0000000000400000ull
-#define XCT_MACRX_HTY_IPV4_BAD 0x0000000000800000ull
-#define XCT_MACRX_HTY_NONIP    0x0000000000c00000ull
-#define XCT_MACRX_IPP_M                0x00000000003f0000ull
-#define XCT_MACRX_IPP_S                16
-#define XCT_MACRX_CSUM_M       0x000000000000ffffull
-#define XCT_MACRX_CSUM_S       0
-
-#define XCT_PTR_T              0x8000000000000000ull
-#define XCT_PTR_LEN_M          0x7ffff00000000000ull
-#define XCT_PTR_LEN_S          44
-#define XCT_PTR_LEN(x)         ((((long)(x)) << XCT_PTR_LEN_S) & \
-                                XCT_PTR_LEN_M)
-#define XCT_PTR_ADDR_M         0x00000fffffffffffull
-#define XCT_PTR_ADDR_S         0
-#define XCT_PTR_ADDR(x)                ((((long)(x)) << XCT_PTR_ADDR_S) & \
-                                XCT_PTR_ADDR_M)
-
-/* Receive interface 8byte result fields */
-#define XCT_RXRES_8B_L4O_M     0xff00000000000000ull
-#define XCT_RXRES_8B_L4O_S     56
-#define XCT_RXRES_8B_RULE_M    0x00ffff0000000000ull
-#define XCT_RXRES_8B_RULE_S    40
-#define XCT_RXRES_8B_EVAL_M    0x000000ffff000000ull
-#define XCT_RXRES_8B_EVAL_S    24
-#define XCT_RXRES_8B_HTYPE_M   0x0000000000f00000ull
-#define XCT_RXRES_8B_HASH_M    0x00000000000fffffull
-#define XCT_RXRES_8B_HASH_S    0
-
-/* Receive interface buffer fields */
-#define XCT_RXB_LEN_M          0x0ffff00000000000ull
-#define XCT_RXB_LEN_S          44
-#define XCT_RXB_LEN(x)         ((((long)(x)) << XCT_PTR_LEN_S) & XCT_PTR_LEN_M)
-#define XCT_RXB_ADDR_M         0x00000fffffffffffull
-#define XCT_RXB_ADDR_S         0
-#define XCT_RXB_ADDR(x)                ((((long)(x)) << XCT_PTR_ADDR_S) & XCT_PTR_ADDR_M)
-
-
 #endif /* PASEMI_MAC_H */
index 8d910a372f89ae9d5e64ce85791a17bbab0eba53..6d342f6c14f643a67a8ee6d78429a1480828f32f 100644 (file)
@@ -1040,15 +1040,13 @@ void ei_tx_timeout(struct net_device *dev)
 
        /* Ugly but a reset can be slow, yet must be protected */
                
-       disable_irq_nosync(dev->irq);
-       spin_lock(&ei_local->page_lock);
+       spin_lock_irqsave(&ei_local->page_lock, flags);
                
        /* Try to restart the card.  Perhaps the user has fixed something. */
        ei_reset_8390(dev);
        AX88190_init(dev, 1);
                
-       spin_unlock(&ei_local->page_lock);
-       enable_irq(dev->irq);
+       spin_unlock_irqrestore(&ei_local->page_lock, flags);
        netif_wake_queue(dev);
 }
     
@@ -1085,9 +1083,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
         *      Slow phase with lock held.
         */
         
-       disable_irq_nosync(dev->irq);
-       
-       spin_lock(&ei_local->page_lock);
+       spin_lock_irqsave(&ei_local->page_lock, flags);
        
        ei_local->irqlock = 1;
 
@@ -1125,8 +1121,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
                ei_local->irqlock = 0;
                netif_stop_queue(dev);
                outb_p(ENISR_ALL, e8390_base + EN0_IMR);
-               spin_unlock(&ei_local->page_lock);
-               enable_irq(dev->irq);
+               spin_unlock_irqrestore(&ei_local->page_lock, flags);
                ei_local->stat.tx_errors++;
                return 1;
        }
@@ -1172,8 +1167,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
        ei_local->irqlock = 0;
        outb_p(ENISR_ALL, e8390_base + EN0_IMR);
        
-       spin_unlock(&ei_local->page_lock);
-       enable_irq(dev->irq);
+       spin_unlock_irqrestore(&ei_local->page_lock, flags);
 
        dev_kfree_skb (skb);
        ei_local->stat.tx_bytes += send_length;
index 8c719b4df54401a0f95388d2285e918fe743e76f..949c6df74c97d18eeada6281d3d2e25f4449fa27 100644 (file)
@@ -731,18 +731,13 @@ module_exit(exit_fmvj18x_cs);
 
 /*====================================================================*/
 
-static irqreturn_t fjn_interrupt(int irq, void *dev_id)
+static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
 {
     struct net_device *dev = dev_id;
     local_info_t *lp = netdev_priv(dev);
     kio_addr_t ioaddr;
     unsigned short tx_stat, rx_stat;
 
-    if (lp == NULL) {
-        printk(KERN_NOTICE "fjn_interrupt(): irq %d for "
-              "unknown device.\n", irq);
-        return IRQ_NONE;
-    }
     ioaddr = dev->base_addr;
 
     /* avoid multiple interrupts */
index 51bbd582f16c2ef40b0d508127d5bb39eb8ea39d..9ba56aa26a1b2326f8a684b1c68166297e781185 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
+#include <linux/log2.h>
 #include "../8390.h"
 
 #include <pcmcia/cs_types.h>
@@ -1484,8 +1485,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
        window_size = 32 * 1024;
 
     /* Make sure it's a power of two.  */
-    while ((window_size & (window_size - 1)) != 0)
-       window_size += window_size & ~(window_size - 1);
+    window_size = roundup_pow_of_two(window_size);
 
     /* Allocate a memory window */
     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
index 90498ffe26f284427b599a2430db3b8941314c54..c4b74e9fed205ffcedbfc5f30728f19dd888aa86 100644 (file)
@@ -137,7 +137,7 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = {
        "Loopback test  (offline)"
 };
 
-#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN)
+#define PCNET32_TEST_LEN       ARRAY_SIZE(pcnet32_gstrings_test)
 
 #define PCNET32_NUM_REGS 136
 
index 57c98669984db34dbc921216e7256a0dec8e8f40..fee3d7b1febaa715e6ba9ab09893a154f9426601 100644 (file)
@@ -106,6 +106,7 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n"
 #include <linux/if_plip.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
+#include <linux/completion.h>
 #include <linux/parport.h>
 #include <linux/bitops.h>
 
@@ -114,7 +115,6 @@ static const char version[] = "NET3 PLIP version 2.4-parport gniibe@mri.co.jp\n"
 #include <asm/system.h>
 #include <asm/irq.h>
 #include <asm/byteorder.h>
-#include <asm/semaphore.h>
 
 /* Maximum number of devices to support. */
 #define PLIP_MAX  8
@@ -221,7 +221,7 @@ struct net_local {
        int should_relinquish;
        spinlock_t lock;
        atomic_t kill_timer;
-       struct semaphore killed_timer_sem;
+       struct completion killed_timer_cmp;
 };
 
 static inline void enable_parport_interrupts (struct net_device *dev)
@@ -385,7 +385,7 @@ plip_timer_bh(struct work_struct *work)
                schedule_delayed_work(&nl->timer, 1);
        }
        else {
-               up (&nl->killed_timer_sem);
+               complete(&nl->killed_timer_cmp);
        }
 }
 
@@ -1112,9 +1112,9 @@ plip_close(struct net_device *dev)
 
        if (dev->irq == -1)
        {
-               init_MUTEX_LOCKED (&nl->killed_timer_sem);
+               init_completion(&nl->killed_timer_cmp);
                atomic_set (&nl->kill_timer, 1);
-               down (&nl->killed_timer_sem);
+               wait_for_completion(&nl->killed_timer_cmp);
        }
 
 #ifdef NOTDEF
index eb98b661efbafd03f51996a41f4839eada5b03b8..034c1c650bcba4a0b2ef1e7949d994b0a2e3b5ef 100644 (file)
@@ -206,7 +206,7 @@ static void z_comp_reset(void *arg)
  *     Returns the length of the compressed packet, or 0 if the
  *     packet is incompressible.
  */
-int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
+static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
               int isize, int osize)
 {
        struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
@@ -435,7 +435,7 @@ static void z_decomp_reset(void *arg)
  * bug, so we return DECOMP_FATALERROR for them in order to turn off
  * compression, even though they are detected by inspecting the input.
  */
-int z_decompress(void *arg, unsigned char *ibuf, int isize,
+static int z_decompress(void *arg, unsigned char *ibuf, int isize,
                 unsigned char *obuf, int osize)
 {
        struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
index 4f690378bb77119f58eb3c18bbfb7ecf88fbf004..4dc5b4b7a561b102e537ef85205b9ab72da334cc 100644 (file)
@@ -1871,7 +1871,7 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
  * complete packet, or we get to the sequence number for a fragment
  * which hasn't arrived but might still do so.
  */
-struct sk_buff *
+static struct sk_buff *
 ppp_mp_reconstruct(struct ppp *ppp)
 {
        u32 seq = ppp->nextseq;
index f0c6a1926a02970c9a5573f97276c217d87157bb..0d80fa54671963a002540d29eefdcaf042c7aa8d 100644 (file)
@@ -42,9 +42,9 @@
 #include <linux/if_ppp.h>
 #include <linux/ppp_channel.h>
 #include <linux/spinlock.h>
+#include <linux/completion.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include <asm/semaphore.h>
 
 #define PPP_VERSION    "2.4.2"
 
@@ -70,7 +70,7 @@ struct syncppp {
        struct tasklet_struct tsk;
 
        atomic_t        refcnt;
-       struct semaphore dead_sem;
+       struct completion dead_cmp;
        struct ppp_channel chan;        /* interface to generic ppp layer */
 };
 
@@ -195,7 +195,7 @@ static struct syncppp *sp_get(struct tty_struct *tty)
 static void sp_put(struct syncppp *ap)
 {
        if (atomic_dec_and_test(&ap->refcnt))
-               up(&ap->dead_sem);
+               complete(&ap->dead_cmp);
 }
 
 /*
@@ -225,7 +225,7 @@ ppp_sync_open(struct tty_struct *tty)
        tasklet_init(&ap->tsk, ppp_sync_process, (unsigned long) ap);
 
        atomic_set(&ap->refcnt, 1);
-       init_MUTEX_LOCKED(&ap->dead_sem);
+       init_completion(&ap->dead_cmp);
 
        ap->chan.private = ap;
        ap->chan.ops = &sync_ops;
@@ -273,7 +273,7 @@ ppp_sync_close(struct tty_struct *tty)
         * by the time it returns.
         */
        if (!atomic_dec_and_test(&ap->refcnt))
-               down(&ap->dead_sem);
+               wait_for_completion(&ap->dead_cmp);
        tasklet_kill(&ap->tsk);
 
        ppp_unregister_channel(&ap->chan);
@@ -560,7 +560,7 @@ static void ppp_sync_process(unsigned long arg)
  * Procedures for encapsulation and framing.
  */
 
-struct sk_buff*
+static struct sk_buff*
 ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
 {
        int proto;
index a005d8f4c38e545e80237abbcb83cdba34e161e3..ac0ac98b19cda96aa3be88a9483e145d6aae5531 100644 (file)
@@ -989,6 +989,7 @@ out:
 }
 
 static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(pppoe_hash_lock)
 {
        loff_t l = *pos;
 
@@ -1022,6 +1023,7 @@ out:
 }
 
 static void pppoe_seq_stop(struct seq_file *seq, void *v)
+       __releases(pppoe_hash_lock)
 {
        read_unlock_bh(&pppoe_hash_lock);
 }
index a7556cd2df7939cbfd37fb3c1e57e8c9e82632dc..1b51bb668d39ac2fb6ecb8b44a3797f06556eea3 100644 (file)
@@ -2489,7 +2489,7 @@ static void __exit pppol2tp_exit(void)
 module_init(pppol2tp_init);
 module_exit(pppol2tp_exit);
 
-MODULE_AUTHOR("Martijn van Oosterhout <kleptog@svana.org>,"
+MODULE_AUTHOR("Martijn van Oosterhout <kleptog@svana.org>, "
              "James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("PPP over L2TP over UDP");
 MODULE_LICENSE("GPL");
index cf0774de6c4154fbf46956deaa0fc420a22358f9..a6aeb9d6044336dc7f64b1c828791ba640bab3c9 100644 (file)
@@ -540,20 +540,12 @@ static void eeprom_readword(struct ql3_adapter *qdev,
        fm93c56a_deselect(qdev);
 }
 
-static void ql_swap_mac_addr(u8 * macAddress)
-{
-#ifdef __BIG_ENDIAN
-       u8 temp;
-       temp = macAddress[0];
-       macAddress[0] = macAddress[1];
-       macAddress[1] = temp;
-       temp = macAddress[2];
-       macAddress[2] = macAddress[3];
-       macAddress[3] = temp;
-       temp = macAddress[4];
-       macAddress[4] = macAddress[5];
-       macAddress[5] = temp;
-#endif
+static void ql_set_mac_addr(struct net_device *ndev, u16 *addr)
+{
+       __le16 *p = (__le16 *)ndev->dev_addr;
+       p[0] = cpu_to_le16(addr[0]);
+       p[1] = cpu_to_le16(addr[1]);
+       p[2] = cpu_to_le16(addr[2]);
 }
 
 static int ql_get_nvram_params(struct ql3_adapter *qdev)
@@ -590,18 +582,6 @@ static int ql_get_nvram_params(struct ql3_adapter *qdev)
                return -1;
        }
 
-       /*
-        * We have a problem with endianness for the MAC addresses
-        * and the two 8-bit values version, and numPorts.  We
-        * have to swap them on big endian systems.
-        */
-       ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn0.macAddress);
-       ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn1.macAddress);
-       ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn2.macAddress);
-       ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn3.macAddress);
-       pEEPROMData = (u16 *) & qdev->nvram_data.version;
-       *pEEPROMData = le16_to_cpu(*pEEPROMData);
-
        spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
        return checksum;
 }
@@ -711,7 +691,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev,
        if (ql_wait_for_mii_ready(qdev)) {
                if (netif_msg_link(qdev))
                        printk(KERN_WARNING PFX
-                              "%s: Timed out waiting for management port to"
+                              "%s: Timed out waiting for management port to "
                               "get free before issuing command.\n",
                               qdev->ndev->name);
                return -1;
@@ -3035,7 +3015,7 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev)
                    LS_64BITS(qdev->shadow_reg_phy_addr);
 
                qdev->prsp_producer_index =
-                   (u32 *) (((u8 *) qdev->preq_consumer_index) + 8);
+                   (__le32 *) (((u8 *) qdev->preq_consumer_index) + 8);
                qdev->rsp_producer_index_phy_addr_high =
                    qdev->req_consumer_index_phy_addr_high;
                qdev->rsp_producer_index_phy_addr_low =
@@ -3215,7 +3195,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev)
        ql_write_page1_reg(qdev, &hmem_regs->reqLength, NUM_REQ_Q_ENTRIES);
 
        /* Response Queue Registers */
-       *((u16 *) (qdev->prsp_producer_index)) = 0;
+       *((__le16 *) (qdev->prsp_producer_index)) = 0;
        qdev->rsp_consumer_index = 0;
        qdev->rsp_current = qdev->rsp_q_virt_addr;
 
@@ -3548,7 +3528,7 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
                       qdev->ndev->name,value);
                break;
        }
-       qdev->numPorts = qdev->nvram_data.numPorts;
+       qdev->numPorts = qdev->nvram_data.version_and_numPorts >> 8;
 }
 
 static void ql_display_dev_info(struct net_device *ndev)
@@ -4051,12 +4031,10 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
        /* Validate and set parameters */
        if (qdev->mac_index) {
                ndev->mtu = qdev->nvram_data.macCfg_port1.etherMtu_mac ;
-               memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn2.macAddress,
-                      ETH_ALEN);
+               ql_set_mac_addr(ndev, qdev->nvram_data.funcCfg_fn2.macAddress);
        } else {
                ndev->mtu = qdev->nvram_data.macCfg_port0.etherMtu_mac ;
-               memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn0.macAddress,
-                      ETH_ALEN);
+               ql_set_mac_addr(ndev, qdev->nvram_data.funcCfg_fn0.macAddress);
        }
        memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
 
index d0ffb30ef371a10d91732a446dc5a7ac4a4a1e40..58a086fddec69f1e88407dada260eab2ca11ef72 100644 (file)
@@ -50,7 +50,7 @@ struct ob_mac_iocb_req {
 #define OB_3032MAC_IOCB_REQ_UC 0x01
        u8 reserved0;
 
-       __le32 transaction_id;
+       u32 transaction_id;     /* opaque for hardware */
        __le16 data_len;
        u8 ip_hdr_off;
        u8 ip_hdr_len;
@@ -86,7 +86,7 @@ struct ob_mac_iocb_rsp {
 #define OB_MAC_IOCB_RSP_I   0x01
 
        __le16 reserved0;
-       __le32 transaction_id;
+       u32 transaction_id;     /* opaque for hardware */
        __le32 reserved1;
        __le32 reserved2;
 };
@@ -953,8 +953,8 @@ struct eeprom_bios_cfg {
  */
 struct eeprom_function_cfg {
        u8 reserved[30];
-       u8 macAddress[6];
-       u8 macAddressSecondary[6];
+       u16 macAddress[3];
+       u16 macAddressSecondary[3];
 
        u16 subsysVendorId;
        u16 subsysDeviceId;
@@ -965,8 +965,7 @@ struct eeprom_function_cfg {
  */
 struct eeprom_data {
        u8 asicId[4];
-       u8 version;
-       u8 numPorts;
+       u16 version_and_numPorts; /* together to avoid endianness crap */
        u16 boardId;
 
 #define EEPROM_BOARDID_STR_SIZE   16
@@ -1056,31 +1055,31 @@ struct eeprom_data {
  */
 struct lrg_buf_q_entry {
 
-       u32 addr0_lower;
+       __le32 addr0_lower;
 #define IAL_LAST_ENTRY 0x00000001
 #define IAL_CONT_ENTRY 0x00000002
 #define IAL_FLAG_MASK  0x00000003
-       u32 addr0_upper;
-       u32 addr1_lower;
-       u32 addr1_upper;
-       u32 addr2_lower;
-       u32 addr2_upper;
-       u32 addr3_lower;
-       u32 addr3_upper;
-       u32 addr4_lower;
-       u32 addr4_upper;
-       u32 addr5_lower;
-       u32 addr5_upper;
-       u32 addr6_lower;
-       u32 addr6_upper;
-       u32 addr7_lower;
-       u32 addr7_upper;
+       __le32 addr0_upper;
+       __le32 addr1_lower;
+       __le32 addr1_upper;
+       __le32 addr2_lower;
+       __le32 addr2_upper;
+       __le32 addr3_lower;
+       __le32 addr3_upper;
+       __le32 addr4_lower;
+       __le32 addr4_upper;
+       __le32 addr5_lower;
+       __le32 addr5_upper;
+       __le32 addr6_lower;
+       __le32 addr6_upper;
+       __le32 addr7_lower;
+       __le32 addr7_upper;
 
 };
 
 struct bufq_addr_element {
-       u32 addr_low;
-       u32 addr_high;
+       __le32 addr_low;
+       __le32 addr_high;
 };
 
 #define QL_NO_RESET                    0
@@ -1116,9 +1115,9 @@ struct ql_rcv_buf_cb {
 #define MAX_OAL_CNT ((MAX_SKB_FRAGS-1)/4 + 1)
 
 struct oal_entry {
-       u32 dma_lo;
-       u32 dma_hi;
-       u32 len;
+       __le32 dma_lo;
+       __le32 dma_hi;
+       __le32 len;
 #define OAL_LAST_ENTRY   0x80000000    /* Last valid buffer in list. */
 #define OAL_CONT_ENTRY   0x40000000    /* points to an OAL. (continuation) */
 };
@@ -1223,7 +1222,7 @@ struct ql3_adapter {
        struct net_rsp_iocb *rsp_current;
        u16 rsp_consumer_index;
        u16 reserved_06;
-       volatile u32 *prsp_producer_index;
+       volatile __le32 *prsp_producer_index;
        u32 rsp_producer_index_phy_addr_high;
        u32 rsp_producer_index_phy_addr_low;
 
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
new file mode 100644 (file)
index 0000000..2334f4e
--- /dev/null
@@ -0,0 +1,1096 @@
+/*
+ * RDC R6040 Fast Ethernet MAC support
+ *
+ * Copyright (C) 2004 Sten Wang <sten.wang@rdc.com.tw>
+ * Copyright (C) 2007
+ *     Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
+ *     Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/crc32.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/uaccess.h>
+
+#include <asm/processor.h>
+
+#define DRV_NAME       "r6040"
+#define DRV_VERSION    "0.16"
+#define DRV_RELDATE    "10Nov2007"
+
+/* PHY CHIP Address */
+#define PHY1_ADDR      1       /* For MAC1 */
+#define PHY2_ADDR      2       /* For MAC2 */
+#define PHY_MODE       0x3100  /* PHY CHIP Register 0 */
+#define PHY_CAP                0x01E1  /* PHY CHIP Register 4 */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT     (6000 * HZ / 1000)
+#define TIMER_WUT      (jiffies + HZ * 1)/* timer wakeup time : 1 second */
+
+/* RDC MAC I/O Size */
+#define R6040_IO_SIZE  256
+
+/* MAX RDC MAC */
+#define MAX_MAC                2
+
+/* MAC registers */
+#define MCR0           0x00    /* Control register 0 */
+#define MCR1           0x04    /* Control register 1 */
+#define  MAC_RST       0x0001  /* Reset the MAC */
+#define MBCR           0x08    /* Bus control */
+#define MT_ICR         0x0C    /* TX interrupt control */
+#define MR_ICR         0x10    /* RX interrupt control */
+#define MTPR           0x14    /* TX poll command register */
+#define MR_BSR         0x18    /* RX buffer size */
+#define MR_DCR         0x1A    /* RX descriptor control */
+#define MLSR           0x1C    /* Last status */
+#define MMDIO          0x20    /* MDIO control register */
+#define  MDIO_WRITE    0x4000  /* MDIO write */
+#define  MDIO_READ     0x2000  /* MDIO read */
+#define MMRD           0x24    /* MDIO read data register */
+#define MMWD           0x28    /* MDIO write data register */
+#define MTD_SA0                0x2C    /* TX descriptor start address 0 */
+#define MTD_SA1                0x30    /* TX descriptor start address 1 */
+#define MRD_SA0                0x34    /* RX descriptor start address 0 */
+#define MRD_SA1                0x38    /* RX descriptor start address 1 */
+#define MISR           0x3C    /* Status register */
+#define MIER           0x40    /* INT enable register */
+#define  MSK_INT       0x0000  /* Mask off interrupts */
+#define ME_CISR                0x44    /* Event counter INT status */
+#define ME_CIER                0x48    /* Event counter INT enable  */
+#define MR_CNT         0x50    /* Successfully received packet counter */
+#define ME_CNT0                0x52    /* Event counter 0 */
+#define ME_CNT1                0x54    /* Event counter 1 */
+#define ME_CNT2                0x56    /* Event counter 2 */
+#define ME_CNT3                0x58    /* Event counter 3 */
+#define MT_CNT         0x5A    /* Successfully transmit packet counter */
+#define ME_CNT4                0x5C    /* Event counter 4 */
+#define MP_CNT         0x5E    /* Pause frame counter register */
+#define MAR0           0x60    /* Hash table 0 */
+#define MAR1           0x62    /* Hash table 1 */
+#define MAR2           0x64    /* Hash table 2 */
+#define MAR3           0x66    /* Hash table 3 */
+#define MID_0L         0x68    /* Multicast address MID0 Low */
+#define MID_0M         0x6A    /* Multicast address MID0 Medium */
+#define MID_0H         0x6C    /* Multicast address MID0 High */
+#define MID_1L         0x70    /* MID1 Low */
+#define MID_1M         0x72    /* MID1 Medium */
+#define MID_1H         0x74    /* MID1 High */
+#define MID_2L         0x78    /* MID2 Low */
+#define MID_2M         0x7A    /* MID2 Medium */
+#define MID_2H         0x7C    /* MID2 High */
+#define MID_3L         0x80    /* MID3 Low */
+#define MID_3M         0x82    /* MID3 Medium */
+#define MID_3H         0x84    /* MID3 High */
+#define PHY_CC         0x88    /* PHY status change configuration register */
+#define PHY_ST         0x8A    /* PHY status register */
+#define MAC_SM         0xAC    /* MAC status machine */
+#define MAC_ID         0xBE    /* Identifier register */
+
+#define TX_DCNT                0x80    /* TX descriptor count */
+#define RX_DCNT                0x80    /* RX descriptor count */
+#define MAX_BUF_SIZE   0x600
+#define RX_DESC_SIZE   (RX_DCNT * sizeof(struct r6040_descriptor))
+#define TX_DESC_SIZE   (TX_DCNT * sizeof(struct r6040_descriptor))
+#define MBCR_DEFAULT   0x012A  /* MAC Bus Control Register */
+#define MCAST_MAX      4       /* Max number multicast addresses to filter */
+
+/* PHY settings */
+#define ICPLUS_PHY_ID  0x0243
+
+MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>,"
+       "Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>,"
+       "Florian Fainelli <florian@openwrt.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver");
+
+#define RX_INT                         0x0001
+#define TX_INT                         0x0010
+#define RX_NO_DESC_INT                 0x0002
+#define INT_MASK                 (RX_INT | TX_INT)
+
+struct r6040_descriptor {
+       u16     status, len;            /* 0-3 */
+       __le32  buf;                    /* 4-7 */
+       __le32  ndesc;                  /* 8-B */
+       u32     rev1;                   /* C-F */
+       char    *vbufp;                 /* 10-13 */
+       struct r6040_descriptor *vndescp;       /* 14-17 */
+       struct sk_buff *skb_ptr;        /* 18-1B */
+       u32     rev2;                   /* 1C-1F */
+} __attribute__((aligned(32)));
+
+struct r6040_private {
+       spinlock_t lock;                /* driver lock */
+       struct timer_list timer;
+       struct pci_dev *pdev;
+       struct r6040_descriptor *rx_insert_ptr;
+       struct r6040_descriptor *rx_remove_ptr;
+       struct r6040_descriptor *tx_insert_ptr;
+       struct r6040_descriptor *tx_remove_ptr;
+       struct r6040_descriptor *rx_ring;
+       struct r6040_descriptor *tx_ring;
+       dma_addr_t rx_ring_dma;
+       dma_addr_t tx_ring_dma;
+       u16     tx_free_desc, rx_free_desc, phy_addr, phy_mode;
+       u16     mcr0, mcr1;
+       u16     switch_sig;
+       struct net_device *dev;
+       struct mii_if_info mii_if;
+       struct napi_struct napi;
+       struct net_device_stats stats;
+       u16     napi_rx_running;
+       void __iomem *base;
+};
+
+static char version[] __devinitdata = KERN_INFO DRV_NAME
+       ": RDC R6040 NAPI net driver,"
+       "version "DRV_VERSION " (" DRV_RELDATE ")\n";
+
+static int phy_table[] = { PHY1_ADDR, PHY2_ADDR };
+
+/* Read a word data from PHY Chip */
+static int phy_read(void __iomem *ioaddr, int phy_addr, int reg)
+{
+       int limit = 2048;
+       u16 cmd;
+
+       iowrite16(MDIO_READ + reg + (phy_addr << 8), ioaddr + MMDIO);
+       /* Wait for the read bit to be cleared */
+       while (limit--) {
+               cmd = ioread16(ioaddr + MMDIO);
+               if (cmd & MDIO_READ)
+                       break;
+       }
+
+       return ioread16(ioaddr + MMRD);
+}
+
+/* Write a word data from PHY Chip */
+static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val)
+{
+       int limit = 2048;
+       u16 cmd;
+
+       iowrite16(val, ioaddr + MMWD);
+       /* Write the command to the MDIO bus */
+       iowrite16(MDIO_WRITE + reg + (phy_addr << 8), ioaddr + MMDIO);
+       /* Wait for the write bit to be cleared */
+       while (limit--) {
+               cmd = ioread16(ioaddr + MMDIO);
+               if (cmd & MDIO_WRITE)
+                       break;
+       }
+}
+
+static int mdio_read(struct net_device *dev, int mii_id, int reg)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+
+       return (phy_read(ioaddr, lp->phy_addr, reg));
+}
+
+static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+
+       phy_write(ioaddr, lp->phy_addr, reg, val);
+}
+
+static void r6040_tx_timeout(struct net_device *dev)
+{
+       struct r6040_private *priv = netdev_priv(dev);
+
+       disable_irq(dev->irq);
+       napi_disable(&priv->napi);
+       spin_lock(&priv->lock);
+       dev->stats.tx_errors++;
+       spin_unlock(&priv->lock);
+
+       netif_stop_queue(dev);
+}
+
+/* Allocate skb buffer for rx descriptor */
+static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
+{
+       struct r6040_descriptor *descptr;
+       void __iomem *ioaddr = lp->base;
+
+       descptr = lp->rx_insert_ptr;
+       while (lp->rx_free_desc < RX_DCNT) {
+               descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
+
+               if (!descptr->skb_ptr)
+                       break;
+               descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
+                       descptr->skb_ptr->data,
+                       MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
+               descptr->status = 0x8000;
+               descptr = descptr->vndescp;
+               lp->rx_free_desc++;
+               /* Trigger RX DMA */
+               iowrite16(lp->mcr0 | 0x0002, ioaddr);
+       }
+       lp->rx_insert_ptr = descptr;
+}
+
+
+static struct net_device_stats *r6040_get_stats(struct net_device *dev)
+{
+       struct r6040_private *priv = netdev_priv(dev);
+       void __iomem *ioaddr = priv->base;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
+       priv->stats.multicast += ioread8(ioaddr + ME_CNT0);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return &priv->stats;
+}
+
+/* Stop RDC MAC and Free the allocated resource */
+static void r6040_down(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       struct pci_dev *pdev = lp->pdev;
+       int i;
+       int limit = 2048;
+       u16 *adrp;
+       u16 cmd;
+
+       /* Stop MAC */
+       iowrite16(MSK_INT, ioaddr + MIER);      /* Mask Off Interrupt */
+       iowrite16(MAC_RST, ioaddr + MCR1);      /* Reset RDC MAC */
+       while (limit--) {
+               cmd = ioread16(ioaddr + MCR1);
+               if (cmd & 0x1)
+                       break;
+       }
+
+       /* Restore MAC Address to MIDx */
+       adrp = (u16 *) dev->dev_addr;
+       iowrite16(adrp[0], ioaddr + MID_0L);
+       iowrite16(adrp[1], ioaddr + MID_0M);
+       iowrite16(adrp[2], ioaddr + MID_0H);
+       free_irq(dev->irq, dev);
+       /* Free RX buffer */
+       for (i = 0; i < RX_DCNT; i++) {
+               if (lp->rx_insert_ptr->skb_ptr) {
+                       pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                       dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
+                       lp->rx_insert_ptr->skb_ptr = NULL;
+               }
+               lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
+       }
+
+       /* Free TX buffer */
+       for (i = 0; i < TX_DCNT; i++) {
+               if (lp->tx_insert_ptr->skb_ptr) {
+                       pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+                               MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+                       dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
+                       lp->rx_insert_ptr->skb_ptr = NULL;
+               }
+               lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
+       }
+
+       /* Free Descriptor memory */
+       pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
+       pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
+}
+
+static int r6040_close(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+
+       /* deleted timer */
+       del_timer_sync(&lp->timer);
+
+       spin_lock_irq(&lp->lock);
+       netif_stop_queue(dev);
+       r6040_down(dev);
+       spin_unlock_irq(&lp->lock);
+
+       return 0;
+}
+
+/* Status of PHY CHIP */
+static int phy_mode_chk(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       int phy_dat;
+
+       /* PHY Link Status Check */
+       phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+       if (!(phy_dat & 0x4))
+               phy_dat = 0x8000;       /* Link Failed, full duplex */
+
+       /* PHY Chip Auto-Negotiation Status */
+       phy_dat = phy_read(ioaddr, lp->phy_addr, 1);
+       if (phy_dat & 0x0020) {
+               /* Auto Negotiation Mode */
+               phy_dat = phy_read(ioaddr, lp->phy_addr, 5);
+               phy_dat &= phy_read(ioaddr, lp->phy_addr, 4);
+               if (phy_dat & 0x140)
+                       /* Force full duplex */
+                       phy_dat = 0x8000;
+               else
+                       phy_dat = 0;
+       } else {
+               /* Force Mode */
+               phy_dat = phy_read(ioaddr, lp->phy_addr, 0);
+               if (phy_dat & 0x100)
+                       phy_dat = 0x8000;
+               else
+                       phy_dat = 0x0000;
+       }
+
+       return phy_dat;
+};
+
+static void r6040_set_carrier(struct mii_if_info *mii)
+{
+       if (phy_mode_chk(mii->dev)) {
+               /* autoneg is off: Link is always assumed to be up */
+               if (!netif_carrier_ok(mii->dev))
+                       netif_carrier_on(mii->dev);
+       } else
+               phy_mode_chk(mii->dev);
+}
+
+static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       struct mii_ioctl_data *data = if_mii(rq);
+       int rc;
+
+       if (!netif_running(dev))
+               return -EINVAL;
+       spin_lock_irq(&lp->lock);
+       rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL);
+       spin_unlock_irq(&lp->lock);
+       r6040_set_carrier(&lp->mii_if);
+       return rc;
+}
+
+static int r6040_rx(struct net_device *dev, int limit)
+{
+       struct r6040_private *priv = netdev_priv(dev);
+       int count;
+       void __iomem *ioaddr = priv->base;
+       u16 err;
+
+       for (count = 0; count < limit; ++count) {
+               struct r6040_descriptor *descptr = priv->rx_remove_ptr;
+               struct sk_buff *skb_ptr;
+
+               /* Disable RX interrupt */
+               iowrite16(ioread16(ioaddr + MIER) & (~RX_INT), ioaddr + MIER);
+               descptr = priv->rx_remove_ptr;
+
+               /* Check for errors */
+               err = ioread16(ioaddr + MLSR);
+               if (err & 0x0400) priv->stats.rx_errors++;
+               /* RX FIFO over-run */
+               if (err & 0x8000) priv->stats.rx_fifo_errors++;
+               /* RX descriptor unavailable */
+               if (err & 0x0080) priv->stats.rx_frame_errors++;
+               /* Received packet with length over buffer lenght */
+               if (err & 0x0020) priv->stats.rx_over_errors++;
+               /* Received packet with too long or short */
+               if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++;
+               /* Received packet with CRC errors */
+               if (err & 0x0004) {
+                       spin_lock(&priv->lock);
+                       priv->stats.rx_crc_errors++;
+                       spin_unlock(&priv->lock);
+               }
+
+               while (priv->rx_free_desc) {
+                       /* No RX packet */
+                       if (descptr->status & 0x8000)
+                               break;
+                       skb_ptr = descptr->skb_ptr;
+                       if (!skb_ptr) {
+                               printk(KERN_ERR "%s: Inconsistent RX"
+                                       "descriptor chain\n",
+                                       dev->name);
+                               break;
+                       }
+                       descptr->skb_ptr = NULL;
+                       skb_ptr->dev = priv->dev;
+                       /* Do not count the CRC */
+                       skb_put(skb_ptr, descptr->len - 4);
+                       pci_unmap_single(priv->pdev, descptr->buf,
+                               MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                       skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev);
+                       /* Send to upper layer */
+                       netif_receive_skb(skb_ptr);
+                       dev->last_rx = jiffies;
+                       priv->dev->stats.rx_packets++;
+                       priv->dev->stats.rx_bytes += descptr->len;
+                       /* To next descriptor */
+                       descptr = descptr->vndescp;
+                       priv->rx_free_desc--;
+               }
+               priv->rx_remove_ptr = descptr;
+       }
+       /* Allocate new RX buffer */
+       if (priv->rx_free_desc < RX_DCNT)
+               rx_buf_alloc(priv, priv->dev);
+
+       return count;
+}
+
+static void r6040_tx(struct net_device *dev)
+{
+       struct r6040_private *priv = netdev_priv(dev);
+       struct r6040_descriptor *descptr;
+       void __iomem *ioaddr = priv->base;
+       struct sk_buff *skb_ptr;
+       u16 err;
+
+       spin_lock(&priv->lock);
+       descptr = priv->tx_remove_ptr;
+       while (priv->tx_free_desc < TX_DCNT) {
+               /* Check for errors */
+               err = ioread16(ioaddr + MLSR);
+
+               if (err & 0x0200) priv->stats.rx_fifo_errors++;
+               if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++;
+
+               if (descptr->status & 0x8000)
+                       break; /* Not complte */
+               skb_ptr = descptr->skb_ptr;
+               pci_unmap_single(priv->pdev, descptr->buf,
+                       skb_ptr->len, PCI_DMA_TODEVICE);
+               /* Free buffer */
+               dev_kfree_skb_irq(skb_ptr);
+               descptr->skb_ptr = NULL;
+               /* To next descriptor */
+               descptr = descptr->vndescp;
+               priv->tx_free_desc++;
+       }
+       priv->tx_remove_ptr = descptr;
+
+       if (priv->tx_free_desc)
+               netif_wake_queue(dev);
+       spin_unlock(&priv->lock);
+}
+
+static int r6040_poll(struct napi_struct *napi, int budget)
+{
+       struct r6040_private *priv =
+               container_of(napi, struct r6040_private, napi);
+       struct net_device *dev = priv->dev;
+       void __iomem *ioaddr = priv->base;
+       int work_done;
+
+       work_done = r6040_rx(dev, budget);
+
+       if (work_done < budget) {
+               netif_rx_complete(dev, napi);
+               /* Enable RX interrupt */
+               iowrite16(ioread16(ioaddr + MIER) | RX_INT, ioaddr + MIER);
+       }
+       return work_done;
+}
+
+/* The RDC interrupt handler. */
+static irqreturn_t r6040_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       u16 status;
+       int handled = 1;
+
+       /* Mask off RDC MAC interrupt */
+       iowrite16(MSK_INT, ioaddr + MIER);
+       /* Read MISR status and clear */
+       status = ioread16(ioaddr + MISR);
+
+       if (status == 0x0000 || status == 0xffff)
+               return IRQ_NONE;
+
+       /* RX interrupt request */
+       if (status & 0x01) {
+               netif_rx_schedule(dev, &lp->napi);
+               iowrite16(TX_INT, ioaddr + MIER);
+       }
+
+       /* TX interrupt request */
+       if (status & 0x10)
+               r6040_tx(dev);
+
+       return IRQ_RETVAL(handled);
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void r6040_poll_controller(struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       r6040_interrupt(dev->irq, dev);
+       enable_irq(dev->irq);
+}
+#endif
+
+static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
+                                dma_addr_t desc_dma, int size)
+{
+       struct r6040_descriptor *desc = desc_ring;
+       dma_addr_t mapping = desc_dma;
+
+       while (size-- > 0) {
+               mapping += sizeof(sizeof(*desc));
+               desc->ndesc = cpu_to_le32(mapping);
+               desc->vndescp = desc + 1;
+               desc++;
+       }
+       desc--;
+       desc->ndesc = cpu_to_le32(desc_dma);
+       desc->vndescp = desc_ring;
+}
+
+/* Init RDC MAC */
+static void r6040_up(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+
+       /* Initialize */
+       lp->tx_free_desc = TX_DCNT;
+       lp->rx_free_desc = 0;
+       /* Init descriptor */
+       lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
+       lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
+       /* Init TX descriptor */
+       r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
+
+       /* Init RX descriptor */
+       r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
+
+       /* Allocate buffer for RX descriptor */
+       rx_buf_alloc(lp, dev);
+
+       /*
+        * TX and RX descriptor start registers.
+        * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1.
+        */
+       iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
+       iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
+
+       iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
+       iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+
+       /* Buffer Size Register */
+       iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
+       /* Read the PHY ID */
+       lp->switch_sig = phy_read(ioaddr, 0, 2);
+
+       if (lp->switch_sig  == ICPLUS_PHY_ID) {
+               phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */
+               lp->phy_mode = 0x8000;
+       } else {
+               /* PHY Mode Check */
+               phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP);
+               phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE);
+
+               if (PHY_MODE == 0x3100)
+                       lp->phy_mode = phy_mode_chk(dev);
+               else
+                       lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
+       }
+       /* MAC Bus Control Register */
+       iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
+
+       /* MAC TX/RX Enable */
+       lp->mcr0 |= lp->phy_mode;
+       iowrite16(lp->mcr0, ioaddr);
+
+       /* set interrupt waiting time and packet numbers */
+       iowrite16(0x0F06, ioaddr + MT_ICR);
+       iowrite16(0x0F06, ioaddr + MR_ICR);
+
+       /* improve performance (by RDC guys) */
+       phy_write(ioaddr, 30, 17, (phy_read(ioaddr, 30, 17) | 0x4000));
+       phy_write(ioaddr, 30, 17, ~((~phy_read(ioaddr, 30, 17)) | 0x2000));
+       phy_write(ioaddr, 0, 19, 0x0000);
+       phy_write(ioaddr, 0, 30, 0x01F0);
+
+       /* Interrupt Mask Register */
+       iowrite16(INT_MASK, ioaddr + MIER);
+}
+
+/*
+  A periodic timer routine
+       Polling PHY Chip Link Status
+*/
+static void r6040_timer(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       u16 phy_mode;
+
+       /* Polling PHY Chip Status */
+       if (PHY_MODE == 0x3100)
+               phy_mode = phy_mode_chk(dev);
+       else
+               phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0;
+
+       if (phy_mode != lp->phy_mode) {
+               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 */
+       lp->timer.expires = TIMER_WUT;
+       add_timer(&lp->timer);
+}
+
+/* Read/set MAC address routines */
+static void r6040_mac_address(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       u16 *adrp;
+
+       /* MAC operation register */
+       iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */
+       iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */
+       iowrite16(0, ioaddr + MAC_SM);
+       udelay(5000);
+
+       /* Restore MAC Address */
+       adrp = (u16 *) dev->dev_addr;
+       iowrite16(adrp[0], ioaddr + MID_0L);
+       iowrite16(adrp[1], ioaddr + MID_0M);
+       iowrite16(adrp[2], ioaddr + MID_0H);
+}
+
+static int r6040_open(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       int ret;
+
+       /* Request IRQ and Register interrupt handler */
+       ret = request_irq(dev->irq, &r6040_interrupt,
+               IRQF_SHARED, dev->name, dev);
+       if (ret)
+               return ret;
+
+       /* Set MAC address */
+       r6040_mac_address(dev);
+
+       /* Allocate Descriptor memory */
+       lp->rx_ring =
+               pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma);
+       if (!lp->rx_ring)
+               return -ENOMEM;
+
+       lp->tx_ring =
+               pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma);
+       if (!lp->tx_ring) {
+               pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
+                                    lp->rx_ring_dma);
+               return -ENOMEM;
+       }
+
+       r6040_up(dev);
+
+       napi_enable(&lp->napi);
+       netif_start_queue(dev);
+
+       if (lp->switch_sig != ICPLUS_PHY_ID) {
+               /* set and active a timer process */
+               init_timer(&lp->timer);
+               lp->timer.expires = TIMER_WUT;
+               lp->timer.data = (unsigned long)dev;
+               lp->timer.function = &r6040_timer;
+               add_timer(&lp->timer);
+       }
+       return 0;
+}
+
+static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       struct r6040_descriptor *descptr;
+       void __iomem *ioaddr = lp->base;
+       unsigned long flags;
+       int ret = NETDEV_TX_OK;
+
+       /* Critical Section */
+       spin_lock_irqsave(&lp->lock, flags);
+
+       /* TX resource check */
+       if (!lp->tx_free_desc) {
+               spin_unlock_irqrestore(&lp->lock, flags);
+               netif_stop_queue(dev);
+               printk(KERN_ERR DRV_NAME ": no tx descriptor\n");
+               ret = NETDEV_TX_BUSY;
+               return ret;
+       }
+
+       /* Statistic Counter */
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += skb->len;
+       /* Set TX descriptor & Transmit it */
+       lp->tx_free_desc--;
+       descptr = lp->tx_insert_ptr;
+       if (skb->len < MISR)
+               descptr->len = MISR;
+       else
+               descptr->len = skb->len;
+
+       descptr->skb_ptr = skb;
+       descptr->buf = cpu_to_le32(pci_map_single(lp->pdev,
+               skb->data, skb->len, PCI_DMA_TODEVICE));
+       descptr->status = 0x8000;
+       /* Trigger the MAC to check the TX descriptor */
+       iowrite16(0x01, ioaddr + MTPR);
+       lp->tx_insert_ptr = descptr->vndescp;
+
+       /* If no tx resource, stop */
+       if (!lp->tx_free_desc)
+               netif_stop_queue(dev);
+
+       dev->trans_start = jiffies;
+       spin_unlock_irqrestore(&lp->lock, flags);
+       return ret;
+}
+
+static void r6040_multicast_list(struct net_device *dev)
+{
+       struct r6040_private *lp = netdev_priv(dev);
+       void __iomem *ioaddr = lp->base;
+       u16 *adrp;
+       u16 reg;
+       unsigned long flags;
+       struct dev_mc_list *dmi = dev->mc_list;
+       int i;
+
+       /* MAC Address */
+       adrp = (u16 *)dev->dev_addr;
+       iowrite16(adrp[0], ioaddr + MID_0L);
+       iowrite16(adrp[1], ioaddr + MID_0M);
+       iowrite16(adrp[2], ioaddr + MID_0H);
+
+       /* Promiscous Mode */
+       spin_lock_irqsave(&lp->lock, flags);
+
+       /* Clear AMCP & PROM bits */
+       reg = ioread16(ioaddr) & ~0x0120;
+       if (dev->flags & IFF_PROMISC) {
+               reg |= 0x0020;
+               lp->mcr0 |= 0x0020;
+       }
+       /* Too many multicast addresses
+        * accept all traffic */
+       else if ((dev->mc_count > MCAST_MAX)
+               || (dev->flags & IFF_ALLMULTI))
+               reg |= 0x0020;
+
+       iowrite16(reg, ioaddr);
+       spin_unlock_irqrestore(&lp->lock, flags);
+
+       /* Build the hash table */
+       if (dev->mc_count > MCAST_MAX) {
+               u16 hash_table[4];
+               u32 crc;
+
+               for (i = 0; i < 4; i++)
+                       hash_table[i] = 0;
+
+               for (i = 0; i < dev->mc_count; i++) {
+                       char *addrs = dmi->dmi_addr;
+
+                       dmi = dmi->next;
+
+                       if (!(*addrs & 1))
+                               continue;
+
+                       crc = ether_crc_le(6, addrs);
+                       crc >>= 26;
+                       hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
+               }
+               /* Write the index of the hash table */
+               for (i = 0; i < 4; i++)
+                       iowrite16(hash_table[i] << 14, ioaddr + MCR1);
+               /* Fill the MAC hash tables with their values */
+               iowrite16(hash_table[0], ioaddr + MAR0);
+               iowrite16(hash_table[1], ioaddr + MAR1);
+               iowrite16(hash_table[2], ioaddr + MAR2);
+               iowrite16(hash_table[3], ioaddr + MAR3);
+       }
+       /* Multicast Address 1~4 case */
+       for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) {
+               adrp = (u16 *)dmi->dmi_addr;
+               iowrite16(adrp[0], ioaddr + MID_1L + 8*i);
+               iowrite16(adrp[1], ioaddr + MID_1M + 8*i);
+               iowrite16(adrp[2], ioaddr + MID_1H + 8*i);
+               dmi = dmi->next;
+       }
+       for (i = dev->mc_count; i < MCAST_MAX; i++) {
+               iowrite16(0xffff, ioaddr + MID_0L + 8*i);
+               iowrite16(0xffff, ioaddr + MID_0M + 8*i);
+               iowrite16(0xffff, ioaddr + MID_0H + 8*i);
+       }
+}
+
+static void netdev_get_drvinfo(struct net_device *dev,
+                       struct ethtool_drvinfo *info)
+{
+       struct r6040_private *rp = netdev_priv(dev);
+
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(rp->pdev));
+}
+
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct r6040_private *rp = netdev_priv(dev);
+       int rc;
+
+       spin_lock_irq(&rp->lock);
+       rc = mii_ethtool_gset(&rp->mii_if, cmd);
+       spin_unlock_irq(&rp->lock);
+
+       return rc;
+}
+
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct r6040_private *rp = netdev_priv(dev);
+       int rc;
+
+       spin_lock_irq(&rp->lock);
+       rc = mii_ethtool_sset(&rp->mii_if, cmd);
+       spin_unlock_irq(&rp->lock);
+       r6040_set_carrier(&rp->mii_if);
+
+       return rc;
+}
+
+static u32 netdev_get_link(struct net_device *dev)
+{
+       struct r6040_private *rp = netdev_priv(dev);
+
+       return mii_link_ok(&rp->mii_if);
+}
+
+static struct ethtool_ops netdev_ethtool_ops = {
+       .get_drvinfo            = netdev_get_drvinfo,
+       .get_settings           = netdev_get_settings,
+       .set_settings           = netdev_set_settings,
+       .get_link               = netdev_get_link,
+};
+
+static int __devinit r6040_init_one(struct pci_dev *pdev,
+                                        const struct pci_device_id *ent)
+{
+       struct net_device *dev;
+       struct r6040_private *lp;
+       void __iomem *ioaddr;
+       int err, io_size = R6040_IO_SIZE;
+       static int card_idx = -1;
+       int bar = 0;
+       long pioaddr;
+       u16 *adrp;
+
+       printk(KERN_INFO "%s\n", version);
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       /* this should always be supported */
+       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+               printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
+                               "not supported by the card\n");
+               return -ENODEV;
+       }
+       if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+               printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses"
+                               "not supported by the card\n");
+               return -ENODEV;
+       }
+
+       /* IO Size check */
+       if (pci_resource_len(pdev, 0) < io_size) {
+               printk(KERN_ERR "Insufficient PCI resources, aborting\n");
+               return -EIO;
+       }
+
+       pioaddr = pci_resource_start(pdev, 0);  /* IO map base address */
+       pci_set_master(pdev);
+
+       dev = alloc_etherdev(sizeof(struct r6040_private));
+       if (!dev) {
+               printk(KERN_ERR "Failed to allocate etherdev\n");
+               return -ENOMEM;
+       }
+       SET_NETDEV_DEV(dev, &pdev->dev);
+       lp = netdev_priv(dev);
+       lp->pdev = pdev;
+
+       if (pci_request_regions(pdev, DRV_NAME)) {
+               printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n");
+               err = -ENODEV;
+               goto err_out_disable;
+       }
+
+       ioaddr = pci_iomap(pdev, bar, io_size);
+       if (!ioaddr) {
+               printk(KERN_ERR "ioremap failed for device %s\n",
+                       pci_name(pdev));
+               return -EIO;
+       }
+
+       /* Init system & device */
+       lp->base = ioaddr;
+       dev->irq = pdev->irq;
+
+       spin_lock_init(&lp->lock);
+       pci_set_drvdata(pdev, dev);
+
+       /* Set MAC address */
+       card_idx++;
+
+       adrp = (u16 *)dev->dev_addr;
+       adrp[0] = ioread16(ioaddr + MID_0L);
+       adrp[1] = ioread16(ioaddr + MID_0M);
+       adrp[2] = ioread16(ioaddr + MID_0H);
+
+       /* Link new device into r6040_root_dev */
+       lp->pdev = pdev;
+
+       /* Init RDC private data */
+       lp->mcr0 = 0x1002;
+       lp->phy_addr = phy_table[card_idx];
+       lp->switch_sig = 0;
+
+       /* The RDC-specific entries in the device structure. */
+       dev->open = &r6040_open;
+       dev->hard_start_xmit = &r6040_start_xmit;
+       dev->stop = &r6040_close;
+       dev->get_stats = r6040_get_stats;
+       dev->set_multicast_list = &r6040_multicast_list;
+       dev->do_ioctl = &r6040_ioctl;
+       dev->ethtool_ops = &netdev_ethtool_ops;
+       dev->tx_timeout = &r6040_tx_timeout;
+       dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       dev->poll_controller = r6040_poll_controller;
+#endif
+       netif_napi_add(dev, &lp->napi, r6040_poll, 64);
+       lp->mii_if.dev = dev;
+       lp->mii_if.mdio_read = mdio_read;
+       lp->mii_if.mdio_write = mdio_write;
+       lp->mii_if.phy_id = lp->phy_addr;
+       lp->mii_if.phy_id_mask = 0x1f;
+       lp->mii_if.reg_num_mask = 0x1f;
+
+       /* Register net device. After this dev->name assign */
+       err = register_netdev(dev);
+       if (err) {
+               printk(KERN_ERR DRV_NAME ": Failed to register net device\n");
+               goto err_out_res;
+       }
+       return 0;
+
+err_out_res:
+       pci_release_regions(pdev);
+err_out_disable:
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+       free_netdev(dev);
+
+       return err;
+}
+
+static void __devexit r6040_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       unregister_netdev(dev);
+       pci_release_regions(pdev);
+       free_netdev(dev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+
+static struct pci_device_id r6040_pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_RDC, 0x6040) },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, r6040_pci_tbl);
+
+static struct pci_driver r6040_driver = {
+       .name           = DRV_NAME,
+       .id_table       = r6040_pci_tbl,
+       .probe          = r6040_init_one,
+       .remove         = __devexit_p(r6040_remove_one),
+};
+
+
+static int __init r6040_init(void)
+{
+       return pci_register_driver(&r6040_driver);
+}
+
+
+static void __exit r6040_cleanup(void)
+{
+       pci_unregister_driver(&r6040_driver);
+}
+
+module_init(r6040_init);
+module_exit(r6040_cleanup);
index 55a590ab1e1700936fb451f36543d69b08889f03..3dd8f1342f70c58eb83ffb01cbb0f40576666076 100644 (file)
@@ -877,7 +877,7 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx)
                               dev->name);
                        goto drop;
                case E_FLG_SYN_ERR:
-                       printk(KERN_WARNING "%s: Flag sync. lost during"
+                       printk(KERN_WARNING "%s: Flag sync. lost during "
                               "packet\n", dev->name);
                        goto drop;
                case E_RX_INV_BUF:
index f25264f2638e1c4baceef68128fb412069f4f1c6..2109508c047ae060a8df1ee061b5acb7420c8c41 100644 (file)
@@ -723,11 +723,17 @@ struct XENA_dev_config {
        u64 rmac_cfg_key;
 #define RMAC_CFG_KEY(val)               vBIT(val,0,16)
 
-#define MAX_MAC_ADDRESSES           16
-#define MAX_MC_ADDRESSES            32 /* Multicast addresses */
-#define MAC_MAC_ADDR_START_OFFSET   0
-#define MAC_MC_ADDR_START_OFFSET    16
-#define MAC_MC_ALL_MC_ADDR_OFFSET   63 /* enables all multicast pkts */
+#define S2IO_MAC_ADDR_START_OFFSET     0
+
+#define S2IO_XENA_MAX_MC_ADDRESSES     64      /* multicast addresses */
+#define S2IO_HERC_MAX_MC_ADDRESSES     256
+
+#define S2IO_XENA_MAX_MAC_ADDRESSES    16
+#define S2IO_HERC_MAX_MAC_ADDRESSES    64
+
+#define S2IO_XENA_MC_ADDR_START_OFFSET 16
+#define S2IO_HERC_MC_ADDR_START_OFFSET 64
+
        u64 rmac_addr_cmd_mem;
 #define RMAC_ADDR_CMD_MEM_WE                    s2BIT(7)
 #define RMAC_ADDR_CMD_MEM_RD                    0
index f2ba944e035ec4ffa6718d3767f9224c5ace39d5..5fab7d7b5d74a430dd9e72870ba347fa38d07f47 100644 (file)
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.17"
+#define DRV_VERSION "2.0.26.15-2"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -335,10 +335,9 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
        {"mc_err_cnt"}
 };
 
-#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
-#define S2IO_ENHANCED_STAT_LEN sizeof(ethtool_enhanced_stats_keys)/ \
-                                       ETH_GSTRING_LEN
-#define S2IO_DRIVER_STAT_LEN sizeof(ethtool_driver_stats_keys)/ ETH_GSTRING_LEN
+#define S2IO_XENA_STAT_LEN     ARRAY_SIZE(ethtool_xena_stats_keys)
+#define S2IO_ENHANCED_STAT_LEN ARRAY_SIZE(ethtool_enhanced_stats_keys)
+#define S2IO_DRIVER_STAT_LEN   ARRAY_SIZE(ethtool_driver_stats_keys)
 
 #define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN )
 #define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN )
@@ -346,7 +345,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
 #define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN )
 #define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN )
 
-#define S2IO_TEST_LEN  sizeof(s2io_gstrings) / ETH_GSTRING_LEN
+#define S2IO_TEST_LEN  ARRAY_SIZE(s2io_gstrings)
 #define S2IO_STRINGS_LEN       S2IO_TEST_LEN * ETH_GSTRING_LEN
 
 #define S2IO_TIMER_CONF(timer, handle, arg, exp)               \
@@ -369,12 +368,19 @@ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr)
 static void s2io_vlan_rx_register(struct net_device *dev,
                                        struct vlan_group *grp)
 {
+       int i;
        struct s2io_nic *nic = dev->priv;
-       unsigned long flags;
+       unsigned long flags[MAX_TX_FIFOS];
+       struct mac_info *mac_control = &nic->mac_control;
+       struct config_param *config = &nic->config;
+
+       for (i = 0; i < config->tx_fifo_num; i++)
+               spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]);
 
-       spin_lock_irqsave(&nic->tx_lock, flags);
        nic->vlgrp = grp;
-       spin_unlock_irqrestore(&nic->tx_lock, flags);
+       for (i = config->tx_fifo_num - 1; i >= 0; i--)
+               spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock,
+                               flags[i]);
 }
 
 /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
@@ -566,6 +572,21 @@ static int init_shared_mem(struct s2io_nic *nic)
                return -EINVAL;
        }
 
+       size = 0;
+       for (i = 0; i < config->tx_fifo_num; i++) {
+               size = config->tx_cfg[i].fifo_len;
+               /*
+                * Legal values are from 2 to 8192
+                */
+               if (size < 2) {
+                       DBG_PRINT(ERR_DBG, "s2io: Invalid fifo len (%d)", size);
+                       DBG_PRINT(ERR_DBG, "for fifo %d\n", i);
+                       DBG_PRINT(ERR_DBG, "s2io: Legal values for fifo len"
+                               "are 2 to 8192\n");
+                       return -EINVAL;
+               }
+       }
+
        lst_size = (sizeof(struct TxD) * config->max_txds);
        lst_per_page = PAGE_SIZE / lst_size;
 
@@ -640,10 +661,14 @@ static int init_shared_mem(struct s2io_nic *nic)
                }
        }
 
-       nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
-       if (!nic->ufo_in_band_v)
-               return -ENOMEM;
-        mem_allocated += (size * sizeof(u64));
+       for (i = 0; i < config->tx_fifo_num; i++) {
+               size = config->tx_cfg[i].fifo_len;
+               mac_control->fifos[i].ufo_in_band_v
+                       = kcalloc(size, sizeof(u64), GFP_KERNEL);
+               if (!mac_control->fifos[i].ufo_in_band_v)
+                       return -ENOMEM;
+               mem_allocated += (size * sizeof(u64));
+       }
 
        /* Allocation and initialization of RXDs in Rings */
        size = 0;
@@ -830,7 +855,6 @@ static int init_shared_mem(struct s2io_nic *nic)
 static void free_shared_mem(struct s2io_nic *nic)
 {
        int i, j, blk_cnt, size;
-       u32 ufo_size = 0;
        void *tmp_v_addr;
        dma_addr_t tmp_p_addr;
        struct mac_info *mac_control;
@@ -851,7 +875,6 @@ static void free_shared_mem(struct s2io_nic *nic)
        lst_per_page = PAGE_SIZE / lst_size;
 
        for (i = 0; i < config->tx_fifo_num; i++) {
-               ufo_size += config->tx_cfg[i].fifo_len;
                page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
                                                        lst_per_page);
                for (j = 0; j < page_num; j++) {
@@ -941,18 +964,21 @@ static void free_shared_mem(struct s2io_nic *nic)
                }
        }
 
+       for (i = 0; i < nic->config.tx_fifo_num; i++) {
+               if (mac_control->fifos[i].ufo_in_band_v) {
+                       nic->mac_control.stats_info->sw_stat.mem_freed
+                               += (config->tx_cfg[i].fifo_len * sizeof(u64));
+                       kfree(mac_control->fifos[i].ufo_in_band_v);
+               }
+       }
+
        if (mac_control->stats_mem) {
+               nic->mac_control.stats_info->sw_stat.mem_freed +=
+                       mac_control->stats_mem_sz;
                pci_free_consistent(nic->pdev,
                                    mac_control->stats_mem_sz,
                                    mac_control->stats_mem,
                                    mac_control->stats_mem_phy);
-               nic->mac_control.stats_info->sw_stat.mem_freed +=
-                       mac_control->stats_mem_sz;
-       }
-       if (nic->ufo_in_band_v) {
-               kfree(nic->ufo_in_band_v);
-               nic->mac_control.stats_info->sw_stat.mem_freed
-                       += (ufo_size * sizeof(u64));
        }
 }
 
@@ -1052,9 +1078,68 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
        return mode;
 }
 
+/**
+ *  init_tti - Initialization transmit traffic interrupt scheme
+ *  @nic: device private variable
+ *  @link: link status (UP/DOWN) used to enable/disable continuous
+ *  transmit interrupts
+ *  Description: The function configures transmit traffic interrupts
+ *  Return Value:  SUCCESS on success and
+ *  '-1' on failure
+ */
+
+int init_tti(struct s2io_nic *nic, int link)
+{
+       struct XENA_dev_config __iomem *bar0 = nic->bar0;
+       register u64 val64 = 0;
+       int i;
+       struct config_param *config;
+
+       config = &nic->config;
+
+       for (i = 0; i < config->tx_fifo_num; i++) {
+               /*
+                * TTI Initialization. Default Tx timer gets us about
+                * 250 interrupts per sec. Continuous interrupts are enabled
+                * by default.
+                */
+               if (nic->device_type == XFRAME_II_DEVICE) {
+                       int count = (nic->config.bus_speed * 125)/2;
+                       val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
+               } else
+                       val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
+
+               val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
+                               TTI_DATA1_MEM_TX_URNG_B(0x10) |
+                               TTI_DATA1_MEM_TX_URNG_C(0x30) |
+                               TTI_DATA1_MEM_TX_TIMER_AC_EN;
+
+               if (use_continuous_tx_intrs && (link == LINK_UP))
+                       val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
+               writeq(val64, &bar0->tti_data1_mem);
+
+               val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
+                               TTI_DATA2_MEM_TX_UFC_B(0x20) |
+                               TTI_DATA2_MEM_TX_UFC_C(0x40) |
+                               TTI_DATA2_MEM_TX_UFC_D(0x80);
+
+               writeq(val64, &bar0->tti_data2_mem);
+
+               val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD |
+                               TTI_CMD_MEM_OFFSET(i);
+               writeq(val64, &bar0->tti_command_mem);
+
+               if (wait_for_cmd_complete(&bar0->tti_command_mem,
+                       TTI_CMD_MEM_STROBE_NEW_CMD, S2IO_BIT_RESET) != SUCCESS)
+                       return FAILURE;
+       }
+
+       return SUCCESS;
+}
+
 /**
  *  init_nic - Initialization of hardware
- *  @nic: device peivate variable
+ *  @nic: device private variable
  *  Description: The function sequentially configures every block
  *  of the H/W from their reset values.
  *  Return Value:  SUCCESS on success and
@@ -1159,9 +1244,9 @@ static int init_nic(struct s2io_nic *nic)
 
        for (i = 0, j = 0; i < config->tx_fifo_num; i++) {
                val64 |=
-                   vBIT(config->tx_cfg[i].fifo_len - 1, ((i * 32) + 19),
+                   vBIT(config->tx_cfg[i].fifo_len - 1, ((j * 32) + 19),
                         13) | vBIT(config->tx_cfg[i].fifo_priority,
-                                   ((i * 32) + 5), 3);
+                                   ((j * 32) + 5), 3);
 
                if (i == (config->tx_fifo_num - 1)) {
                        if (i % 2 == 0)
@@ -1172,17 +1257,25 @@ static int init_nic(struct s2io_nic *nic)
                case 1:
                        writeq(val64, &bar0->tx_fifo_partition_0);
                        val64 = 0;
+                       j = 0;
                        break;
                case 3:
                        writeq(val64, &bar0->tx_fifo_partition_1);
                        val64 = 0;
+                       j = 0;
                        break;
                case 5:
                        writeq(val64, &bar0->tx_fifo_partition_2);
                        val64 = 0;
+                       j = 0;
                        break;
                case 7:
                        writeq(val64, &bar0->tx_fifo_partition_3);
+                       val64 = 0;
+                       j = 0;
+                       break;
+               default:
+                       j++;
                        break;
                }
        }
@@ -1268,11 +1361,11 @@ static int init_nic(struct s2io_nic *nic)
 
        /*
         * Filling Tx round robin registers
-        * as per the number of FIFOs
+        * as per the number of FIFOs for equal scheduling priority
         */
        switch (config->tx_fifo_num) {
        case 1:
-               val64 = 0x0000000000000000ULL;
+               val64 = 0x0;
                writeq(val64, &bar0->tx_w_round_robin_0);
                writeq(val64, &bar0->tx_w_round_robin_1);
                writeq(val64, &bar0->tx_w_round_robin_2);
@@ -1280,87 +1373,78 @@ static int init_nic(struct s2io_nic *nic)
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 2:
-               val64 = 0x0000010000010000ULL;
+               val64 = 0x0001000100010001ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0100000100000100ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0001000001000001ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0000010000010000ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0100000000000000ULL;
+               val64 = 0x0001000100000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 3:
-               val64 = 0x0001000102000001ULL;
+               val64 = 0x0001020001020001ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0001020000010001ULL;
+               val64 = 0x0200010200010200ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0200000100010200ULL;
+               val64 = 0x0102000102000102ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0001000102000001ULL;
+               val64 = 0x0001020001020001ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0001020000000000ULL;
+               val64 = 0x0200010200000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 4:
-               val64 = 0x0001020300010200ULL;
+               val64 = 0x0001020300010203ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0100000102030001ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0200010000010203ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0001020001000001ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0203000100000000ULL;
+               val64 = 0x0001020300000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 5:
-               val64 = 0x0001000203000102ULL;
+               val64 = 0x0001020304000102ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0001020001030004ULL;
+               val64 = 0x0304000102030400ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0001000203000102ULL;
+               val64 = 0x0102030400010203ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0001020001030004ULL;
+               val64 = 0x0400010203040001ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0001000000000000ULL;
+               val64 = 0x0203040000000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 6:
-               val64 = 0x0001020304000102ULL;
+               val64 = 0x0001020304050001ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0304050001020001ULL;
+               val64 = 0x0203040500010203ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0203000100000102ULL;
+               val64 = 0x0405000102030405ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0304000102030405ULL;
+               val64 = 0x0001020304050001ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0001000200000000ULL;
+               val64 = 0x0203040500000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 7:
-               val64 = 0x0001020001020300ULL;
+               val64 = 0x0001020304050600ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0102030400010203ULL;
+               val64 = 0x0102030405060001ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0405060001020001ULL;
+               val64 = 0x0203040506000102ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0304050000010200ULL;
+               val64 = 0x0304050600010203ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0102030000000000ULL;
+               val64 = 0x0405060000000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        case 8:
-               val64 = 0x0001020300040105ULL;
+               val64 = 0x0001020304050607ULL;
                writeq(val64, &bar0->tx_w_round_robin_0);
-               val64 = 0x0200030106000204ULL;
                writeq(val64, &bar0->tx_w_round_robin_1);
-               val64 = 0x0103000502010007ULL;
                writeq(val64, &bar0->tx_w_round_robin_2);
-               val64 = 0x0304010002060500ULL;
                writeq(val64, &bar0->tx_w_round_robin_3);
-               val64 = 0x0103020400000000ULL;
+               val64 = 0x0001020300000000ULL;
                writeq(val64, &bar0->tx_w_round_robin_4);
                break;
        }
@@ -1537,58 +1621,14 @@ static int init_nic(struct s2io_nic *nic)
            MAC_RX_LINK_UTIL_VAL(rmac_util_period);
        writeq(val64, &bar0->mac_link_util);
 
-
        /*
         * Initializing the Transmit and Receive Traffic Interrupt
         * Scheme.
         */
-       /*
-        * TTI Initialization. Default Tx timer gets us about
-        * 250 interrupts per sec. Continuous interrupts are enabled
-        * by default.
-        */
-       if (nic->device_type == XFRAME_II_DEVICE) {
-               int count = (nic->config.bus_speed * 125)/2;
-               val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
-       } else {
-
-               val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
-       }
-       val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
-           TTI_DATA1_MEM_TX_URNG_B(0x10) |
-           TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN;
-               if (use_continuous_tx_intrs)
-                       val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
-       writeq(val64, &bar0->tti_data1_mem);
-
-       val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
-           TTI_DATA2_MEM_TX_UFC_B(0x20) |
-           TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80);
-       writeq(val64, &bar0->tti_data2_mem);
-
-       val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD;
-       writeq(val64, &bar0->tti_command_mem);
 
-       /*
-        * Once the operation completes, the Strobe bit of the command
-        * register will be reset. We poll for this particular condition
-        * We wait for a maximum of 500ms for the operation to complete,
-        * if it's not complete by then we return error.
-        */
-       time = 0;
-       while (TRUE) {
-               val64 = readq(&bar0->tti_command_mem);
-               if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) {
-                       break;
-               }
-               if (time > 10) {
-                       DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n",
-                                 dev->name);
-                       return -ENODEV;
-               }
-               msleep(50);
-               time++;
-       }
+       /* Initialize TTI */
+       if (SUCCESS != init_tti(nic, nic->last_link_state))
+               return -ENODEV;
 
        /* RTI Initialization */
        if (nic->device_type == XFRAME_II_DEVICE) {
@@ -2242,7 +2282,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \
        u16 j, frg_cnt;
 
        txds = txdlp;
-       if (txds->Host_Control == (u64)(long)nic->ufo_in_band_v) {
+       if (txds->Host_Control == (u64)(long)fifo_data->ufo_in_band_v) {
                pci_unmap_single(nic->pdev, (dma_addr_t)
                        txds->Buffer_Pointer, sizeof(u64),
                        PCI_DMA_TODEVICE);
@@ -2297,6 +2337,8 @@ static void free_tx_buffers(struct s2io_nic *nic)
        config = &nic->config;
 
        for (i = 0; i < config->tx_fifo_num; i++) {
+               unsigned long flags;
+               spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags);
                for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
                        txdp = (struct TxD *) \
                        mac_control->fifos[i].list_info[j].list_virt_addr;
@@ -2313,6 +2355,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
                          dev->name, cnt, i);
                mac_control->fifos[i].tx_curr_get_info.offset = 0;
                mac_control->fifos[i].tx_curr_put_info.offset = 0;
+               spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock, flags);
        }
 }
 
@@ -2933,8 +2976,12 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
        struct tx_curr_get_info get_info, put_info;
        struct sk_buff *skb;
        struct TxD *txdlp;
+       unsigned long flags = 0;
        u8 err_mask;
 
+       if (!spin_trylock_irqsave(&fifo_data->tx_lock, flags))
+                       return;
+
        get_info = fifo_data->tx_curr_get_info;
        memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info));
        txdlp = (struct TxD *) fifo_data->list_info[get_info.offset].
@@ -2983,6 +3030,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 
                skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
                if (skb == NULL) {
+                       spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
                        DBG_PRINT(ERR_DBG, "%s: Null skb ",
                        __FUNCTION__);
                        DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
@@ -3003,10 +3051,10 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
                    get_info.offset;
        }
 
-       spin_lock(&nic->tx_lock);
        if (netif_queue_stopped(dev))
                netif_wake_queue(dev);
-       spin_unlock(&nic->tx_lock);
+
+       spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
 }
 
 /**
@@ -3376,6 +3424,9 @@ static void s2io_reset(struct s2io_nic * sp)
        /* Set swapper to enable I/O register access */
        s2io_set_swapper(sp);
 
+       /* restore mac_addr entries */
+       do_s2io_restore_unicast_mc(sp);
+
        /* Restore the MSIX table entries from local variables */
        restore_xmsi_data(sp);
 
@@ -3434,9 +3485,6 @@ static void s2io_reset(struct s2io_nic * sp)
                writeq(val64, &bar0->pcc_err_reg);
        }
 
-       /* restore the previously assigned mac address */
-       do_s2io_prog_unicast(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr);
-
        sp->device_enabled_once = FALSE;
 }
 
@@ -3773,7 +3821,7 @@ static int s2io_test_msi(struct s2io_nic *sp)
 
        if (!sp->msi_detected) {
                /* MSI(X) test failed, go back to INTx mode */
-               DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated"
+               DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated "
                        "using MSI(X) during test\n", sp->dev->name,
                        pci_name(pdev));
 
@@ -3921,6 +3969,9 @@ hw_init_failed:
 static int s2io_close(struct net_device *dev)
 {
        struct s2io_nic *sp = dev->priv;
+       struct config_param *config = &sp->config;
+       u64 tmp64;
+       int offset;
 
        /* Return if the device is already closed               *
        *  Can happen when s2io_card_up failed in change_mtu    *
@@ -3929,6 +3980,14 @@ static int s2io_close(struct net_device *dev)
                return 0;
 
        netif_stop_queue(dev);
+
+       /* delete all populated mac entries */
+       for (offset = 1; offset < config->max_mc_addr; offset++) {
+               tmp64 = do_s2io_read_unicast_mc(sp, offset);
+               if (tmp64 != S2IO_DISABLE_MAC_ENTRY)
+                       do_s2io_delete_unicast_mc(sp, tmp64);
+       }
+
        /* Reset card, kill tasklet and free Tx and Rx buffers. */
        s2io_card_down(sp);
 
@@ -3955,9 +4014,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        register u64 val64;
        struct TxD *txdp;
        struct TxFIFO_element __iomem *tx_fifo;
-       unsigned long flags;
+       unsigned long flags = 0;
        u16 vlan_tag = 0;
        int vlan_priority = 0;
+       struct fifo_info *fifo = NULL;
        struct mac_info *mac_control;
        struct config_param *config;
        int offload_type;
@@ -3972,13 +4032,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
                dev_kfree_skb_any(skb);
                return 0;
-}
+       }
 
-       spin_lock_irqsave(&sp->tx_lock, flags);
        if (!is_s2io_card_up(sp)) {
                DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
                          dev->name);
-               spin_unlock_irqrestore(&sp->tx_lock, flags);
                dev_kfree_skb(skb);
                return 0;
        }
@@ -3991,19 +4049,20 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                queue = config->fifo_mapping[vlan_priority];
        }
 
-       put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset;
-       get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset;
-       txdp = (struct TxD *) mac_control->fifos[queue].list_info[put_off].
-               list_virt_addr;
+       fifo = &mac_control->fifos[queue];
+       spin_lock_irqsave(&fifo->tx_lock, flags);
+       put_off = (u16) fifo->tx_curr_put_info.offset;
+       get_off = (u16) fifo->tx_curr_get_info.offset;
+       txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr;
 
-       queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1;
+       queue_len = fifo->tx_curr_put_info.fifo_len + 1;
        /* Avoid "put" pointer going beyond "get" pointer */
        if (txdp->Host_Control ||
                   ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
                DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n");
                netif_stop_queue(dev);
                dev_kfree_skb(skb);
-               spin_unlock_irqrestore(&sp->tx_lock, flags);
+               spin_unlock_irqrestore(&fifo->tx_lock, flags);
                return 0;
        }
 
@@ -4019,7 +4078,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
        txdp->Control_1 |= TXD_LIST_OWN_XENA;
-       txdp->Control_2 |= config->tx_intr_type;
+       txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no);
 
        if (sp->vlgrp && vlan_tx_tag_present(skb)) {
                txdp->Control_2 |= TXD_VLAN_ENABLE;
@@ -4036,15 +4095,15 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
                txdp->Control_1 |= TXD_BUFFER0_SIZE(8);
 #ifdef __BIG_ENDIAN
-               sp->ufo_in_band_v[put_off] =
+               fifo->ufo_in_band_v[put_off] =
                                (u64)skb_shinfo(skb)->ip6_frag_id;
 #else
-               sp->ufo_in_band_v[put_off] =
+               fifo->ufo_in_band_v[put_off] =
                                (u64)skb_shinfo(skb)->ip6_frag_id << 32;
 #endif
-               txdp->Host_Control = (unsigned long)sp->ufo_in_band_v;
+               txdp->Host_Control = (unsigned long)fifo->ufo_in_band_v;
                txdp->Buffer_Pointer = pci_map_single(sp->pdev,
-                                       sp->ufo_in_band_v,
+                                       fifo->ufo_in_band_v,
                                        sizeof(u64), PCI_DMA_TODEVICE);
                if((txdp->Buffer_Pointer == 0) ||
                        (txdp->Buffer_Pointer == DMA_ERROR_CODE))
@@ -4084,7 +4143,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                frg_cnt++; /* as Txd0 was used for inband header */
 
        tx_fifo = mac_control->tx_FIFO_start[queue];
-       val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr;
+       val64 = fifo->list_info[put_off].list_phy_addr;
        writeq(val64, &tx_fifo->TxDL_Pointer);
 
        val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST |
@@ -4097,9 +4156,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        mmiowb();
 
        put_off++;
-       if (put_off == mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1)
+       if (put_off == fifo->tx_curr_put_info.fifo_len + 1)
                put_off = 0;
-       mac_control->fifos[queue].tx_curr_put_info.offset = put_off;
+       fifo->tx_curr_put_info.offset = put_off;
 
        /* Avoid "put" pointer going beyond "get" pointer */
        if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
@@ -4111,7 +4170,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
        dev->trans_start = jiffies;
-       spin_unlock_irqrestore(&sp->tx_lock, flags);
+       spin_unlock_irqrestore(&fifo->tx_lock, flags);
 
        return 0;
 pci_map_failed:
@@ -4119,7 +4178,7 @@ pci_map_failed:
        netif_stop_queue(dev);
        stats->mem_freed += skb->truesize;
        dev_kfree_skb(skb);
-       spin_unlock_irqrestore(&sp->tx_lock, flags);
+       spin_unlock_irqrestore(&fifo->tx_lock, flags);
        return 0;
 }
 
@@ -4729,8 +4788,9 @@ static void s2io_set_multicast(struct net_device *dev)
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
        u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
            0xfeffffffffffULL;
-       u64 dis_addr = 0xffffffffffffULL, mac_addr = 0;
+       u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, mac_addr = 0;
        void __iomem *add;
+       struct config_param *config = &sp->config;
 
        if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) {
                /*  Enable all Multicast addresses */
@@ -4740,7 +4800,7 @@ static void s2io_set_multicast(struct net_device *dev)
                       &bar0->rmac_addr_data1_mem);
                val64 = RMAC_ADDR_CMD_MEM_WE |
                    RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-                   RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET);
+                   RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1);
                writeq(val64, &bar0->rmac_addr_cmd_mem);
                /* Wait till command completes */
                wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
@@ -4748,7 +4808,7 @@ static void s2io_set_multicast(struct net_device *dev)
                                        S2IO_BIT_RESET);
 
                sp->m_cast_flg = 1;
-               sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET;
+               sp->all_multi_pos = config->max_mc_addr - 1;
        } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) {
                /*  Disable all Multicast addresses */
                writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
@@ -4817,7 +4877,7 @@ static void s2io_set_multicast(struct net_device *dev)
        /*  Update individual M_CAST address list */
        if ((!sp->m_cast_flg) && dev->mc_count) {
                if (dev->mc_count >
-                   (MAX_ADDRS_SUPPORTED - MAC_MC_ADDR_START_OFFSET - 1)) {
+                   (config->max_mc_addr - config->max_mac_addr)) {
                        DBG_PRINT(ERR_DBG, "%s: No more Rx filters ",
                                  dev->name);
                        DBG_PRINT(ERR_DBG, "can be added, please enable ");
@@ -4837,7 +4897,7 @@ static void s2io_set_multicast(struct net_device *dev)
                        val64 = RMAC_ADDR_CMD_MEM_WE |
                            RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
                            RMAC_ADDR_CMD_MEM_OFFSET
-                           (MAC_MC_ADDR_START_OFFSET + i);
+                           (config->mc_start_offset + i);
                        writeq(val64, &bar0->rmac_addr_cmd_mem);
 
                        /* Wait for command completes */
@@ -4869,7 +4929,7 @@ static void s2io_set_multicast(struct net_device *dev)
                        val64 = RMAC_ADDR_CMD_MEM_WE |
                            RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
                            RMAC_ADDR_CMD_MEM_OFFSET
-                           (i + MAC_MC_ADDR_START_OFFSET);
+                           (i + config->mc_start_offset);
                        writeq(val64, &bar0->rmac_addr_cmd_mem);
 
                        /* Wait for command completes */
@@ -4885,8 +4945,78 @@ static void s2io_set_multicast(struct net_device *dev)
        }
 }
 
-/* add unicast MAC address to CAM */
-static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off)
+/* read from CAM unicast & multicast addresses and store it in
+ * def_mac_addr structure
+ */
+void do_s2io_store_unicast_mc(struct s2io_nic *sp)
+{
+       int offset;
+       u64 mac_addr = 0x0;
+       struct config_param *config = &sp->config;
+
+       /* store unicast & multicast mac addresses */
+       for (offset = 0; offset < config->max_mc_addr; offset++) {
+               mac_addr = do_s2io_read_unicast_mc(sp, offset);
+               /* if read fails disable the entry */
+               if (mac_addr == FAILURE)
+                       mac_addr = S2IO_DISABLE_MAC_ENTRY;
+               do_s2io_copy_mac_addr(sp, offset, mac_addr);
+       }
+}
+
+/* restore unicast & multicast MAC to CAM from def_mac_addr structure */
+static void do_s2io_restore_unicast_mc(struct s2io_nic *sp)
+{
+       int offset;
+       struct config_param *config = &sp->config;
+       /* restore unicast mac address */
+       for (offset = 0; offset < config->max_mac_addr; offset++)
+               do_s2io_prog_unicast(sp->dev,
+                       sp->def_mac_addr[offset].mac_addr);
+
+       /* restore multicast mac address */
+       for (offset = config->mc_start_offset;
+               offset < config->max_mc_addr; offset++)
+               do_s2io_add_mc(sp, sp->def_mac_addr[offset].mac_addr);
+}
+
+/* add a multicast MAC address to CAM */
+static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr)
+{
+       int i;
+       u64 mac_addr = 0;
+       struct config_param *config = &sp->config;
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               mac_addr <<= 8;
+               mac_addr |= addr[i];
+       }
+       if ((0ULL == mac_addr) || (mac_addr == S2IO_DISABLE_MAC_ENTRY))
+               return SUCCESS;
+
+       /* check if the multicast mac already preset in CAM */
+       for (i = config->mc_start_offset; i < config->max_mc_addr; i++) {
+               u64 tmp64;
+               tmp64 = do_s2io_read_unicast_mc(sp, i);
+               if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */
+                       break;
+
+               if (tmp64 == mac_addr)
+                       return SUCCESS;
+       }
+       if (i == config->max_mc_addr) {
+               DBG_PRINT(ERR_DBG,
+                       "CAM full no space left for multicast MAC\n");
+               return FAILURE;
+       }
+       /* Update the internal structure with this new mac address */
+       do_s2io_copy_mac_addr(sp, i, mac_addr);
+
+       return (do_s2io_add_mac(sp, mac_addr, i));
+}
+
+/* add MAC address to CAM */
+static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off)
 {
        u64 val64;
        struct XENA_dev_config __iomem *bar0 = sp->bar0;
@@ -4903,15 +5033,62 @@ static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off)
        if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
                S2IO_BIT_RESET)) {
-               DBG_PRINT(INFO_DBG, "add_mac_addr failed\n");
+               DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
                return FAILURE;
        }
        return SUCCESS;
 }
+/* deletes a specified unicast/multicast mac entry from CAM */
+static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr)
+{
+       int offset;
+       u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, tmp64;
+       struct config_param *config = &sp->config;
+
+       for (offset = 1;
+               offset < config->max_mc_addr; offset++) {
+               tmp64 = do_s2io_read_unicast_mc(sp, offset);
+               if (tmp64 == addr) {
+                       /* disable the entry by writing  0xffffffffffffULL */
+                       if (do_s2io_add_mac(sp, dis_addr, offset) ==  FAILURE)
+                               return FAILURE;
+                       /* store the new mac list from CAM */
+                       do_s2io_store_unicast_mc(sp);
+                       return SUCCESS;
+               }
+       }
+       DBG_PRINT(ERR_DBG, "MAC address 0x%llx not found in CAM\n",
+                       (unsigned long long)addr);
+       return FAILURE;
+}
+
+/* read mac entries from CAM */
+static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
+{
+       u64 tmp64 = 0xffffffffffff0000ULL, val64;
+       struct XENA_dev_config __iomem *bar0 = sp->bar0;
+
+       /* read mac addr */
+       val64 =
+               RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
+               RMAC_ADDR_CMD_MEM_OFFSET(offset);
+       writeq(val64, &bar0->rmac_addr_cmd_mem);
+
+       /* Wait till command completes */
+       if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
+               RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
+               S2IO_BIT_RESET)) {
+               DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n");
+               return FAILURE;
+       }
+       tmp64 = readq(&bar0->rmac_addr_data0_mem);
+       return (tmp64 >> 16);
+}
 
 /**
  * s2io_set_mac_addr driver entry point
  */
+
 static int s2io_set_mac_addr(struct net_device *dev, void *p)
 {
        struct sockaddr *addr = p;
@@ -4924,7 +5101,6 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p)
        /* store the MAC address in CAM */
        return (do_s2io_prog_unicast(dev, dev->dev_addr));
 }
-
 /**
  *  do_s2io_prog_unicast - Programs the Xframe mac address
  *  @dev : pointer to the device structure.
@@ -4934,11 +5110,14 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p)
  *  Return value: SUCCESS on success and an appropriate (-)ve integer
  *  as defined in errno.h file on failure.
  */
+
 static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
 {
        struct s2io_nic *sp = dev->priv;
        register u64 mac_addr = 0, perm_addr = 0;
        int i;
+       u64 tmp64;
+       struct config_param *config = &sp->config;
 
        /*
        * Set the new MAC address as the new unicast filter and reflect this
@@ -4956,9 +5135,26 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr)
        if (mac_addr == perm_addr)
                return SUCCESS;
 
+       /* check if the mac already preset in CAM */
+       for (i = 1; i < config->max_mac_addr; i++) {
+               tmp64 = do_s2io_read_unicast_mc(sp, i);
+               if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */
+                       break;
+
+               if (tmp64 == mac_addr) {
+                       DBG_PRINT(INFO_DBG,
+                       "MAC addr:0x%llx already present in CAM\n",
+                       (unsigned long long)mac_addr);
+                       return SUCCESS;
+               }
+       }
+       if (i == config->max_mac_addr) {
+               DBG_PRINT(ERR_DBG, "CAM full no space left for Unicast MAC\n");
+               return FAILURE;
+       }
        /* Update the internal structure with this new mac address */
-       do_s2io_copy_mac_addr(sp, 0, mac_addr);
-       return (do_s2io_add_unicast(sp, mac_addr, 0));
+       do_s2io_copy_mac_addr(sp, i, mac_addr);
+       return (do_s2io_add_mac(sp, mac_addr, i));
 }
 
 /**
@@ -6721,7 +6917,7 @@ static int s2io_add_isr(struct s2io_nic * sp)
                                /* If either data or addr is zero print it */
                                if(!(sp->msix_info[i].addr &&
                                        sp->msix_info[i].data)) {
-                                       DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx"
+                                       DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx "
                                                "Data:0x%lx\n",sp->desc[i],
                                                (unsigned long long)
                                                sp->msix_info[i].addr,
@@ -6739,7 +6935,7 @@ static int s2io_add_isr(struct s2io_nic * sp)
                                /* If either data or addr is zero print it */
                                if(!(sp->msix_info[i].addr &&
                                        sp->msix_info[i].data)) {
-                                       DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx"
+                                       DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx "
                                                "Data:0x%lx\n",sp->desc[i],
                                                (unsigned long long)
                                                sp->msix_info[i].addr,
@@ -6848,10 +7044,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
        if (do_io)
                s2io_reset(sp);
 
-       spin_lock_irqsave(&sp->tx_lock, flags);
        /* Free all Tx buffers */
        free_tx_buffers(sp);
-       spin_unlock_irqrestore(&sp->tx_lock, flags);
 
        /* Free all Rx buffers */
        spin_lock_irqsave(&sp->rx_lock, flags);
@@ -7263,6 +7457,7 @@ static void s2io_link(struct s2io_nic * sp, int link)
        struct net_device *dev = (struct net_device *) sp->dev;
 
        if (link != sp->last_link_state) {
+               init_tti(sp, link);
                if (link == LINK_DOWN) {
                        DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
                        netif_carrier_off(dev);
@@ -7315,12 +7510,18 @@ static void s2io_init_pci(struct s2io_nic * sp)
 
 static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
 {
-       if ( tx_fifo_num > 8) {
-               DBG_PRINT(ERR_DBG, "s2io: Requested number of Tx fifos not "
-                        "supported\n");
-               DBG_PRINT(ERR_DBG, "s2io: Default to 8 Tx fifos\n");
-               tx_fifo_num = 8;
+       if ((tx_fifo_num > MAX_TX_FIFOS) ||
+               (tx_fifo_num < FIFO_DEFAULT_NUM)) {
+               DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos "
+                       "(%d) not supported\n", tx_fifo_num);
+               tx_fifo_num =
+                       ((tx_fifo_num > MAX_TX_FIFOS)? MAX_TX_FIFOS :
+                       ((tx_fifo_num < FIFO_DEFAULT_NUM) ? FIFO_DEFAULT_NUM :
+                       tx_fifo_num));
+               DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num);
+               DBG_PRINT(ERR_DBG, "tx fifos\n");
        }
+
        if ( rx_ring_num > 8) {
                DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not "
                         "supported\n");
@@ -7355,7 +7556,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
 /**
  * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS
  * or Traffic class respectively.
- * @nic: device peivate variable
+ * @nic: device private variable
  * Description: The function configures the receive steering to
  * desired receive ring.
  * Return Value:  SUCCESS on success and
@@ -7652,7 +7853,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
         */
        bar0 = sp->bar0;
        val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
-           RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET);
+           RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET);
        writeq(val64, &bar0->rmac_addr_cmd_mem);
        wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET);
@@ -7672,6 +7873,20 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN);
        memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN);
 
+       /* initialize number of multicast & unicast MAC entries variables */
+       if (sp->device_type == XFRAME_I_DEVICE) {
+               config->max_mc_addr = S2IO_XENA_MAX_MC_ADDRESSES;
+               config->max_mac_addr = S2IO_XENA_MAX_MAC_ADDRESSES;
+               config->mc_start_offset = S2IO_XENA_MC_ADDR_START_OFFSET;
+       } else if (sp->device_type == XFRAME_II_DEVICE) {
+               config->max_mc_addr = S2IO_HERC_MAX_MC_ADDRESSES;
+               config->max_mac_addr = S2IO_HERC_MAX_MAC_ADDRESSES;
+               config->mc_start_offset = S2IO_HERC_MC_ADDR_START_OFFSET;
+       }
+
+       /* store mac addresses from CAM to s2io_nic structure */
+       do_s2io_store_unicast_mc(sp);
+
         /* Store the values of the MSIX table in the s2io_nic structure */
        store_xmsi_data(sp);
        /* reset Nic and bring it to known state */
@@ -7685,7 +7900,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->state = 0;
 
        /* Initialize spinlocks */
-       spin_lock_init(&sp->tx_lock);
+       for (i = 0; i < sp->config.tx_fifo_num; i++)
+               spin_lock_init(&mac_control->fifos[i].tx_lock);
 
        if (!napi)
                spin_lock_init(&sp->put_lock);
index cc1797a071aa0822617efa6b96f03a3795d1a25c..9f6016c6f135a1fc9c7336bf8fd0df4ebba98b76 100644 (file)
@@ -31,6 +31,7 @@
 #define SUCCESS 0
 #define FAILURE -1
 #define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL
+#define S2IO_DISABLE_MAC_ENTRY 0xFFFFFFFFFFFFULL
 #define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100
 #define S2IO_BIT_RESET 1
 #define S2IO_BIT_SET 2
@@ -359,6 +360,8 @@ struct stat_block {
 #define MAX_TX_FIFOS 8
 #define MAX_RX_RINGS 8
 
+#define FIFO_DEFAULT_NUM       1
+
 #define MAX_RX_DESC_1  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
 #define MAX_RX_DESC_2  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
 #define MAX_RX_DESC_3  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
@@ -458,6 +461,9 @@ struct config_param {
 #define MAX_MTU_JUMBO               (MAX_PYLD_JUMBO+18)
 #define MAX_MTU_JUMBO_VLAN          (MAX_PYLD_JUMBO+22)
        u16 bus_speed;
+       int max_mc_addr;        /* xena=64 herc=256 */
+       int max_mac_addr;       /* xena=16 herc=64 */
+       int mc_start_offset;    /* xena=16 herc=64 */
 };
 
 /* Structure representing MAC Addrs */
@@ -715,8 +721,14 @@ struct fifo_info {
         */
        struct tx_curr_get_info tx_curr_get_info;
 
+       /* Per fifo lock */
+       spinlock_t tx_lock;
+
+       /* Per fifo UFO in band structure */
+       u64 *ufo_in_band_v;
+
        struct s2io_nic *nic;
-};
+} ____cacheline_aligned;
 
 /* Information related to the Tx and Rx FIFOs and Rings of Xena
  * is maintained in this structure.
@@ -826,7 +838,7 @@ struct s2io_nic {
 #define MAX_MAC_SUPPORTED   16
 #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED
 
-       struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED];
+       struct mac_addr def_mac_addr[256];
 
        struct net_device_stats stats;
        int high_dma_flag;
@@ -844,7 +856,6 @@ struct s2io_nic {
 
        atomic_t rx_bufs_left[MAX_RX_RINGS];
 
-       spinlock_t tx_lock;
        spinlock_t put_lock;
 
 #define PROMISC     1
@@ -853,7 +864,7 @@ struct s2io_nic {
 #define MAX_ADDRS_SUPPORTED 64
        u16 usr_addr_count;
        u16 mc_addr_count;
-       struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED];
+       struct usr_addr usr_addrs[256];
 
        u16 m_cast_flg;
        u16 all_multi_pos;
@@ -911,7 +922,6 @@ struct s2io_nic {
        volatile unsigned long state;
        spinlock_t      rx_lock;
        u64             general_int_mask;
-       u64 *ufo_in_band_v;
 #define VPD_STRING_LEN 80
        u8  product_name[VPD_STRING_LEN];
        u8  serial_num[VPD_STRING_LEN];
@@ -1066,6 +1076,12 @@ static int s2io_add_isr(struct s2io_nic * sp);
 static void s2io_rem_isr(struct s2io_nic * sp);
 
 static void restore_xmsi_data(struct s2io_nic *nic);
+static void do_s2io_store_unicast_mc(struct s2io_nic *sp);
+static void do_s2io_restore_unicast_mc(struct s2io_nic *sp);
+static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset);
+static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr);
+static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset);
+static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr);
 
 static int
 s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro,
index ff4056310356a8e04b2b33634d1098e474347b2c..78994ede0cb0666945dc3d35e1061b1cc3cc8aee 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
-#include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
@@ -53,14 +52,27 @@ static char *sgiseeqstr = "SGI Seeq8003";
                            sp->tx_old + (SEEQ_TX_BUFFERS - 1) - sp->tx_new : \
                            sp->tx_old - sp->tx_new - 1)
 
+#define VIRT_TO_DMA(sp, v) ((sp)->srings_dma +                                 \
+                                 (dma_addr_t)((unsigned long)(v) -            \
+                                              (unsigned long)((sp)->rx_desc)))
+
+/* Copy frames shorter than rx_copybreak, otherwise pass on up in
+ * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
+ */
+static int rx_copybreak = 100;
+
+#define PAD_SIZE    (128 - sizeof(struct hpc_dma_desc) - sizeof(void *))
+
 struct sgiseeq_rx_desc {
        volatile struct hpc_dma_desc rdma;
-       volatile signed int buf_vaddr;
+       u8 padding[PAD_SIZE];
+       struct sk_buff *skb;
 };
 
 struct sgiseeq_tx_desc {
        volatile struct hpc_dma_desc tdma;
-       volatile signed int buf_vaddr;
+       u8 padding[PAD_SIZE];
+       struct sk_buff *skb;
 };
 
 /*
@@ -96,6 +108,18 @@ struct sgiseeq_private {
        spinlock_t tx_lock;
 };
 
+static inline void dma_sync_desc_cpu(struct net_device *dev, void *addr)
+{
+       dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+                      DMA_FROM_DEVICE);
+}
+
+static inline void dma_sync_desc_dev(struct net_device *dev, void *addr)
+{
+       dma_cache_sync(dev->dev.parent, addr, sizeof(struct sgiseeq_rx_desc),
+                      DMA_TO_DEVICE);
+}
+
 static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
 {
        hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
@@ -163,35 +187,55 @@ static int seeq_init_ring(struct net_device *dev)
 
        /* Setup tx ring. */
        for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
-               if (!sp->tx_desc[i].tdma.pbuf) {
-                       unsigned long buffer;
-
-                       buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
-                       if (!buffer)
-                               return -ENOMEM;
-                       sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
-                       sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer);
-               }
                sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT;
+               dma_sync_desc_dev(dev, &sp->tx_desc[i]);
        }
 
        /* And now the rx ring. */
        for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
-               if (!sp->rx_desc[i].rdma.pbuf) {
-                       unsigned long buffer;
+               if (!sp->rx_desc[i].skb) {
+                       dma_addr_t dma_addr;
+                       struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ);
 
-                       buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
-                       if (!buffer)
+                       if (skb == NULL)
                                return -ENOMEM;
-                       sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
-                       sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer);
+                       skb_reserve(skb, 2);
+                       dma_addr = dma_map_single(dev->dev.parent,
+                                                 skb->data - 2,
+                                                 PKT_BUF_SZ, DMA_FROM_DEVICE);
+                       sp->rx_desc[i].skb = skb;
+                       sp->rx_desc[i].rdma.pbuf = dma_addr;
                }
                sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT;
+               dma_sync_desc_dev(dev, &sp->rx_desc[i]);
        }
        sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR;
+       dma_sync_desc_dev(dev, &sp->rx_desc[i - 1]);
        return 0;
 }
 
+static void seeq_purge_ring(struct net_device *dev)
+{
+       struct sgiseeq_private *sp = netdev_priv(dev);
+       int i;
+
+       /* clear tx ring. */
+       for (i = 0; i < SEEQ_TX_BUFFERS; i++) {
+               if (sp->tx_desc[i].skb) {
+                       dev_kfree_skb(sp->tx_desc[i].skb);
+                       sp->tx_desc[i].skb = NULL;
+               }
+       }
+
+       /* And now the rx ring. */
+       for (i = 0; i < SEEQ_RX_BUFFERS; i++) {
+               if (sp->rx_desc[i].skb) {
+                       dev_kfree_skb(sp->rx_desc[i].skb);
+                       sp->rx_desc[i].skb = NULL;
+               }
+       }
+}
+
 #ifdef DEBUG
 static struct sgiseeq_private *gpriv;
 static struct net_device *gdev;
@@ -258,8 +302,8 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
                sregs->tstat = TSTAT_INIT_SEEQ;
        }
 
-       hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
-       hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
+       hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc);
+       hregs->tx_ndptr = VIRT_TO_DMA(sp, sp->tx_desc);
 
        seeq_go(sp, hregs, sregs);
        return 0;
@@ -283,69 +327,90 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp,
                                    struct sgiseeq_regs *sregs)
 {
        if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) {
-               hregs->rx_ndptr = CPHYSADDR(sp->rx_desc + sp->rx_new);
+               hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc + sp->rx_new);
                seeq_go(sp, hregs, sregs);
        }
 }
 
-#define for_each_rx(rd, sp) for((rd) = &(sp)->rx_desc[(sp)->rx_new]; \
-                               !((rd)->rdma.cntinfo & HPCDMA_OWN); \
-                               (rd) = &(sp)->rx_desc[(sp)->rx_new])
-
 static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp,
                              struct hpc3_ethregs *hregs,
                              struct sgiseeq_regs *sregs)
 {
        struct sgiseeq_rx_desc *rd;
        struct sk_buff *skb = NULL;
+       struct sk_buff *newskb;
        unsigned char pkt_status;
-       unsigned char *pkt_pointer = NULL;
        int len = 0;
        unsigned int orig_end = PREV_RX(sp->rx_new);
 
        /* Service every received packet. */
-       for_each_rx(rd, sp) {
+       rd = &sp->rx_desc[sp->rx_new];
+       dma_sync_desc_cpu(dev, rd);
+       while (!(rd->rdma.cntinfo & HPCDMA_OWN)) {
                len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3;
-               pkt_pointer = (unsigned char *)(long)rd->buf_vaddr;
-               pkt_status = pkt_pointer[len + 2];
-
+               dma_unmap_single(dev->dev.parent, rd->rdma.pbuf,
+                                PKT_BUF_SZ, DMA_FROM_DEVICE);
+               pkt_status = rd->skb->data[len];
                if (pkt_status & SEEQ_RSTAT_FIG) {
                        /* Packet is OK. */
-                       skb = dev_alloc_skb(len + 2);
-
-                       if (skb) {
-                               skb_reserve(skb, 2);
-                               skb_put(skb, len);
-
-                               /* Copy out of kseg1 to avoid silly cache flush. */
-                               skb_copy_to_linear_data(skb, pkt_pointer + 2, len);
-                               skb->protocol = eth_type_trans(skb, dev);
-
-                               /* We don't want to receive our own packets */
-                               if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) {
+                       /* We don't want to receive our own packets */
+                       if (memcmp(rd->skb->data + 6, dev->dev_addr, ETH_ALEN)) {
+                               if (len > rx_copybreak) {
+                                       skb = rd->skb;
+                                       newskb = netdev_alloc_skb(dev, PKT_BUF_SZ);
+                                       if (!newskb) {
+                                               newskb = skb;
+                                               skb = NULL;
+                                               goto memory_squeeze;
+                                       }
+                                       skb_reserve(newskb, 2);
+                               } else {
+                                       skb = netdev_alloc_skb(dev, len + 2);
+                                       if (skb) {
+                                               skb_reserve(skb, 2);
+                                               skb_copy_to_linear_data(skb, rd->skb->data, len);
+                                       }
+                                       newskb = rd->skb;
+                               }
+memory_squeeze:
+                               if (skb) {
+                                       skb_put(skb, len);
+                                       skb->protocol = eth_type_trans(skb, dev);
                                        netif_rx(skb);
                                        dev->last_rx = jiffies;
                                        dev->stats.rx_packets++;
                                        dev->stats.rx_bytes += len;
                                } else {
-                                       /* Silently drop my own packets */
-                                       dev_kfree_skb_irq(skb);
+                                       printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
+                                               dev->name);
+                                       dev->stats.rx_dropped++;
                                }
                        } else {
-                               printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
-                                       dev->name);
-                               dev->stats.rx_dropped++;
+                               /* Silently drop my own packets */
+                               newskb = rd->skb;
                        }
                } else {
                        record_rx_errors(dev, pkt_status);
+                       newskb = rd->skb;
                }
+               rd->skb = newskb;
+               rd->rdma.pbuf = dma_map_single(dev->dev.parent,
+                                              newskb->data - 2,
+                                              PKT_BUF_SZ, DMA_FROM_DEVICE);
 
                /* Return the entry to the ring pool. */
                rd->rdma.cntinfo = RCNTINFO_INIT;
                sp->rx_new = NEXT_RX(sp->rx_new);
+               dma_sync_desc_dev(dev, rd);
+               rd = &sp->rx_desc[sp->rx_new];
+               dma_sync_desc_cpu(dev, rd);
        }
+       dma_sync_desc_cpu(dev, &sp->rx_desc[orig_end]);
        sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR);
+       dma_sync_desc_dev(dev, &sp->rx_desc[orig_end]);
+       dma_sync_desc_cpu(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
        sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR;
+       dma_sync_desc_dev(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]);
        rx_maybe_restart(sp, hregs, sregs);
 }
 
@@ -358,20 +423,29 @@ static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp,
        }
 }
 
-static inline void kick_tx(struct sgiseeq_tx_desc *td,
+static inline void kick_tx(struct net_device *dev,
+                          struct sgiseeq_private *sp,
                           struct hpc3_ethregs *hregs)
 {
+       struct sgiseeq_tx_desc *td;
+       int i = sp->tx_old;
+
        /* If the HPC aint doin nothin, and there are more packets
         * with ETXD cleared and XIU set we must make very certain
         * that we restart the HPC else we risk locking up the
         * adapter.  The following code is only safe iff the HPCDMA
         * is not active!
         */
+       td = &sp->tx_desc[i];
+       dma_sync_desc_cpu(dev, td);
        while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
-             (HPCDMA_XIU | HPCDMA_ETXD))
-               td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext);
+             (HPCDMA_XIU | HPCDMA_ETXD)) {
+               i = NEXT_TX(i);
+               td = &sp->tx_desc[i];
+               dma_sync_desc_cpu(dev, td);
+       }
        if (td->tdma.cntinfo & HPCDMA_XIU) {
-               hregs->tx_ndptr = CPHYSADDR(td);
+               hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
                hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
        }
 }
@@ -400,11 +474,12 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
        for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
                td = &sp->tx_desc[j];
 
+               dma_sync_desc_cpu(dev, td);
                if (!(td->tdma.cntinfo & (HPCDMA_XIU)))
                        break;
                if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
                        if (!(status & HPC3_ETXCTRL_ACTIVE)) {
-                               hregs->tx_ndptr = CPHYSADDR(td);
+                               hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
                                hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
                        }
                        break;
@@ -413,6 +488,11 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp
                sp->tx_old = NEXT_TX(sp->tx_old);
                td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE);
                td->tdma.cntinfo |= HPCDMA_EOX;
+               if (td->skb) {
+                       dev_kfree_skb_any(td->skb);
+                       td->skb = NULL;
+               }
+               dma_sync_desc_dev(dev, td);
        }
 }
 
@@ -480,6 +560,7 @@ static int sgiseeq_close(struct net_device *dev)
        /* Shutdown the Seeq. */
        reset_hpc3_and_seeq(sp->hregs, sregs);
        free_irq(irq, dev);
+       seeq_purge_ring(dev);
 
        return 0;
 }
@@ -506,16 +587,22 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct hpc3_ethregs *hregs = sp->hregs;
        unsigned long flags;
        struct sgiseeq_tx_desc *td;
-       int skblen, len, entry;
+       int len, entry;
 
        spin_lock_irqsave(&sp->tx_lock, flags);
 
        /* Setup... */
-       skblen = skb->len;
-       len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
+       len = skb->len;
+       if (len < ETH_ZLEN) {
+               if (skb_padto(skb, ETH_ZLEN))
+                       return 0;
+               len = ETH_ZLEN;
+       }
+
        dev->stats.tx_bytes += len;
        entry = sp->tx_new;
        td = &sp->tx_desc[entry];
+       dma_sync_desc_cpu(dev, td);
 
        /* Create entry.  There are so many races with adding a new
         * descriptor to the chain:
@@ -530,25 +617,27 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
         *    entry and the HPC got to the end of the chain before we
         *    added this new entry and restarted it.
         */
-       skb_copy_from_linear_data(skb, (char *)(long)td->buf_vaddr, skblen);
-       if (len != skblen)
-               memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen);
+       td->skb = skb;
+       td->tdma.pbuf = dma_map_single(dev->dev.parent, skb->data,
+                                      len, DMA_TO_DEVICE);
        td->tdma.cntinfo = (len & HPCDMA_BCNT) |
                           HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX;
+       dma_sync_desc_dev(dev, td);
        if (sp->tx_old != sp->tx_new) {
                struct sgiseeq_tx_desc *backend;
 
                backend = &sp->tx_desc[PREV_TX(sp->tx_new)];
+               dma_sync_desc_cpu(dev, backend);
                backend->tdma.cntinfo &= ~HPCDMA_EOX;
+               dma_sync_desc_dev(dev, backend);
        }
        sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
 
        /* Maybe kick the HPC back into motion. */
        if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
-               kick_tx(&sp->tx_desc[sp->tx_old], hregs);
+               kick_tx(dev, sp, hregs);
 
        dev->trans_start = jiffies;
-       dev_kfree_skb(skb);
 
        if (!TX_BUFFS_AVAIL(sp))
                netif_stop_queue(dev);
@@ -586,33 +675,41 @@ static void sgiseeq_set_multicast(struct net_device *dev)
                sgiseeq_reset(dev);
 }
 
-static inline void setup_tx_ring(struct sgiseeq_tx_desc *buf, int nbufs)
+static inline void setup_tx_ring(struct net_device *dev,
+                                struct sgiseeq_tx_desc *buf,
+                                int nbufs)
 {
+       struct sgiseeq_private *sp = netdev_priv(dev);
        int i = 0;
 
        while (i < (nbufs - 1)) {
-               buf[i].tdma.pnext = CPHYSADDR(buf + i + 1);
+               buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
                buf[i].tdma.pbuf = 0;
+               dma_sync_desc_dev(dev, &buf[i]);
                i++;
        }
-       buf[i].tdma.pnext = CPHYSADDR(buf);
+       buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf);
+       dma_sync_desc_dev(dev, &buf[i]);
 }
 
-static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
+static inline void setup_rx_ring(struct net_device *dev,
+                                struct sgiseeq_rx_desc *buf,
+                                int nbufs)
 {
+       struct sgiseeq_private *sp = netdev_priv(dev);
        int i = 0;
 
        while (i < (nbufs - 1)) {
-               buf[i].rdma.pnext = CPHYSADDR(buf + i + 1);
+               buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf + i + 1);
                buf[i].rdma.pbuf = 0;
+               dma_sync_desc_dev(dev, &buf[i]);
                i++;
        }
        buf[i].rdma.pbuf = 0;
-       buf[i].rdma.pnext = CPHYSADDR(buf);
+       buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf);
+       dma_sync_desc_dev(dev, &buf[i]);
 }
 
-#define ALIGNED(x)  ((((unsigned long)(x)) + 0xf) & ~(0xf))
-
 static int __init sgiseeq_probe(struct platform_device *pdev)
 {
        struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
@@ -621,7 +718,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
        unsigned int irq = pd->irq;
        struct sgiseeq_private *sp;
        struct net_device *dev;
-       int err, i;
+       int err;
        DECLARE_MAC_BUF(mac);
 
        dev = alloc_etherdev(sizeof (struct sgiseeq_private));
@@ -635,7 +732,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
        sp = netdev_priv(dev);
 
        /* Make private data page aligned */
-       sr = dma_alloc_coherent(&pdev->dev, sizeof(*sp->srings),
+       sr = dma_alloc_noncoherent(&pdev->dev, sizeof(*sp->srings),
                                &sp->srings_dma, GFP_KERNEL);
        if (!sr) {
                printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n");
@@ -647,8 +744,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
        sp->tx_desc = sp->srings->txvector;
 
        /* A couple calculations now, saves many cycles later. */
-       setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
-       setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
+       setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS);
+       setup_tx_ring(dev, sp->tx_desc, SEEQ_TX_BUFFERS);
 
        memcpy(dev->dev_addr, pd->mac, ETH_ALEN);
 
@@ -716,8 +813,8 @@ static int __exit sgiseeq_remove(struct platform_device *pdev)
        struct sgiseeq_private *sp = netdev_priv(dev);
 
        unregister_netdev(dev);
-       dma_free_coherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
-                         sp->srings_dma);
+       dma_free_noncoherent(&pdev->dev, sizeof(*sp->srings), sp->srings,
+                            sp->srings_dma);
        free_netdev(dev);
        platform_set_drvdata(pdev, NULL);
 
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
deleted file mode 100644 (file)
index 228f650..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- *                     Simple traffic shaper for Linux NET3.
- *
- *     (c) Copyright 1996 Alan Cox <alan@redhat.com>, All Rights Reserved.
- *                             http://www.redhat.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.
- *
- *     Neither Alan Cox nor CymruNet Ltd. admit liability nor provide
- *     warranty for any of this software. This material is provided
- *     "AS-IS" and at no charge.
- *
- *
- *     Algorithm:
- *
- *     Queue Frame:
- *             Compute time length of frame at regulated speed
- *             Add frame to queue at appropriate point
- *             Adjust time length computation for followup frames
- *             Any frame that falls outside of its boundaries is freed
- *
- *     We work to the following constants
- *
- *             SHAPER_QLEN     Maximum queued frames
- *             SHAPER_LATENCY  Bounding latency on a frame. Leaving this latency
- *                             window drops the frame. This stops us queueing
- *                             frames for a long time and confusing a remote
- *                             host.
- *             SHAPER_MAXSLIP  Maximum time a priority frame may jump forward.
- *                             That bounds the penalty we will inflict on low
- *                             priority traffic.
- *             SHAPER_BURST    Time range we call "now" in order to reduce
- *                             system load. The more we make this the burstier
- *                             the behaviour, the better local performance you
- *                             get through packet clustering on routers and the
- *                             worse the remote end gets to judge rtts.
- *
- *     This is designed to handle lower speed links ( < 200K/second or so). We
- *     run off a 100-150Hz base clock typically. This gives us a resolution at
- *     200Kbit/second of about 2Kbit or 256 bytes. Above that our timer
- *     resolution may start to cause much more burstiness in the traffic. We
- *     could avoid a lot of that by calling kick_shaper() at the end of the
- *     tied device transmissions. If you run above about 100K second you
- *     may need to tune the supposed speed rate for the right values.
- *
- *     BUGS:
- *             Downing the interface under the shaper before the shaper
- *             will render your machine defunct. Don't for now shape over
- *             PPP or SLIP therefore!
- *             This will be fixed in BETA4
- *
- * Update History :
- *
- *              bh_atomic() SMP races fixes and rewritten the locking code to
- *              be SMP safe and irq-mask friendly.
- *              NOTE: we can't use start_bh_atomic() in kick_shaper()
- *              because it's going to be recalled from an irq handler,
- *              and synchronize_bh() is a nono if called from irq context.
- *                                             1999  Andrea Arcangeli
- *
- *              Device statistics (tx_pakets, tx_bytes,
- *              tx_drops: queue_over_time and collisions: max_queue_exceded)
- *                               1999/06/18 Jordi Murgo <savage@apostols.org>
- *
- *             Use skb->cb for private data.
- *                              2000/03 Andi Kleen
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/init.h>
-#include <linux/if_shaper.h>
-#include <linux/jiffies.h>
-
-#include <net/dst.h>
-#include <net/arp.h>
-#include <net/net_namespace.h>
-
-struct shaper_cb {
-       unsigned long   shapeclock;             /* Time it should go out */
-       unsigned long   shapestamp;             /* Stamp for shaper    */
-       __u32           shapelatency;           /* Latency on frame */
-       __u32           shapelen;               /* Frame length in clocks */
-       __u16           shapepend;              /* Pending */
-};
-#define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb))
-
-static int sh_debug;           /* Debug flag */
-
-#define SHAPER_BANNER  "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n"
-
-static void shaper_kick(struct shaper *sh);
-
-/*
- *     Compute clocks on a buffer
- */
-
-static int shaper_clocks(struct shaper *shaper, struct sk_buff *skb)
-{
-       int t=skb->len/shaper->bytespertick;
-       return t;
-}
-
-/*
- *     Set the speed of a shaper. We compute this in bytes per tick since
- *     thats how the machine wants to run. Quoted input is in bits per second
- *     as is traditional (note not BAUD). We assume 8 bit bytes.
- */
-
-static void shaper_setspeed(struct shaper *shaper, int bitspersec)
-{
-       shaper->bitspersec=bitspersec;
-       shaper->bytespertick=(bitspersec/HZ)/8;
-       if(!shaper->bytespertick)
-               shaper->bytespertick++;
-}
-
-/*
- *     Throw a frame at a shaper.
- */
-
-
-static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct shaper *shaper = dev->priv;
-       struct sk_buff *ptr;
-
-       spin_lock(&shaper->lock);
-       ptr=shaper->sendq.prev;
-
-       /*
-        *      Set up our packet details
-        */
-
-       SHAPERCB(skb)->shapelatency=0;
-       SHAPERCB(skb)->shapeclock=shaper->recovery;
-       if(time_before(SHAPERCB(skb)->shapeclock, jiffies))
-               SHAPERCB(skb)->shapeclock=jiffies;
-       skb->priority=0;        /* short term bug fix */
-       SHAPERCB(skb)->shapestamp=jiffies;
-
-       /*
-        *      Time slots for this packet.
-        */
-
-       SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb);
-
-       {
-               struct sk_buff *tmp;
-               /*
-                *      Up our shape clock by the time pending on the queue
-                *      (Should keep this in the shaper as a variable..)
-                */
-               for(tmp=skb_peek(&shaper->sendq); tmp!=NULL &&
-                       tmp!=(struct sk_buff *)&shaper->sendq; tmp=tmp->next)
-                       SHAPERCB(skb)->shapeclock+=SHAPERCB(tmp)->shapelen;
-               /*
-                *      Queue over time. Spill packet.
-                */
-               if(time_after(SHAPERCB(skb)->shapeclock,jiffies + SHAPER_LATENCY)) {
-                       dev_kfree_skb(skb);
-                       dev->stats.tx_dropped++;
-               } else
-                       skb_queue_tail(&shaper->sendq, skb);
-       }
-
-       if(sh_debug)
-               printk("Frame queued.\n");
-       if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN)
-       {
-               ptr=skb_dequeue(&shaper->sendq);
-                dev_kfree_skb(ptr);
-                dev->stats.collisions++;
-       }
-       shaper_kick(shaper);
-       spin_unlock(&shaper->lock);
-       return 0;
-}
-
-/*
- *     Transmit from a shaper
- */
-
-static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb)
-{
-       struct sk_buff *newskb=skb_clone(skb, GFP_ATOMIC);
-       if(sh_debug)
-               printk("Kick frame on %p\n",newskb);
-       if(newskb)
-       {
-               newskb->dev=shaper->dev;
-               newskb->priority=2;
-               if(sh_debug)
-                       printk("Kick new frame to %s, %d\n",
-                               shaper->dev->name,newskb->priority);
-               dev_queue_xmit(newskb);
-
-                shaper->dev->stats.tx_bytes += skb->len;
-               shaper->dev->stats.tx_packets++;
-
-                if(sh_debug)
-                       printk("Kicked new frame out.\n");
-               dev_kfree_skb(skb);
-       }
-}
-
-/*
- *     Timer handler for shaping clock
- */
-
-static void shaper_timer(unsigned long data)
-{
-       struct shaper *shaper = (struct shaper *)data;
-
-       spin_lock(&shaper->lock);
-       shaper_kick(shaper);
-       spin_unlock(&shaper->lock);
-}
-
-/*
- *     Kick a shaper queue and try and do something sensible with the
- *     queue.
- */
-
-static void shaper_kick(struct shaper *shaper)
-{
-       struct sk_buff *skb;
-
-       /*
-        *      Walk the list (may be empty)
-        */
-
-       while((skb=skb_peek(&shaper->sendq))!=NULL)
-       {
-               /*
-                *      Each packet due to go out by now (within an error
-                *      of SHAPER_BURST) gets kicked onto the link
-                */
-
-               if(sh_debug)
-                       printk("Clock = %ld, jiffies = %ld\n", SHAPERCB(skb)->shapeclock, jiffies);
-               if(time_before_eq(SHAPERCB(skb)->shapeclock, jiffies + SHAPER_BURST))
-               {
-                       /*
-                        *      Pull the frame and get interrupts back on.
-                        */
-
-                       skb_unlink(skb, &shaper->sendq);
-                       if (shaper->recovery <
-                           SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen)
-                               shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen;
-                       /*
-                        *      Pass on to the physical target device via
-                        *      our low level packet thrower.
-                        */
-
-                       SHAPERCB(skb)->shapepend=0;
-                       shaper_queue_xmit(shaper, skb); /* Fire */
-               }
-               else
-                       break;
-       }
-
-       /*
-        *      Next kick.
-        */
-
-       if(skb!=NULL)
-               mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock);
-}
-
-
-/*
- *     Bring the interface up. We just disallow this until a
- *     bind.
- */
-
-static int shaper_open(struct net_device *dev)
-{
-       struct shaper *shaper=dev->priv;
-
-       /*
-        *      Can't open until attached.
-        *      Also can't open until speed is set, or we'll get
-        *      a division by zero.
-        */
-
-       if(shaper->dev==NULL)
-               return -ENODEV;
-       if(shaper->bitspersec==0)
-               return -EINVAL;
-       return 0;
-}
-
-/*
- *     Closing a shaper flushes the queues.
- */
-
-static int shaper_close(struct net_device *dev)
-{
-       struct shaper *shaper=dev->priv;
-       struct sk_buff *skb;
-
-       while ((skb = skb_dequeue(&shaper->sendq)) != NULL)
-               dev_kfree_skb(skb);
-
-       spin_lock_bh(&shaper->lock);
-       shaper_kick(shaper);
-       spin_unlock_bh(&shaper->lock);
-
-       del_timer_sync(&shaper->timer);
-       return 0;
-}
-
-/*
- *     Revectored calls. We alter the parameters and call the functions
- *     for our attached device. This enables us to bandwidth allocate after
- *     ARP and other resolutions and not before.
- */
-
-static int shaper_header(struct sk_buff *skb, struct net_device *dev,
-                        unsigned short type,
-                        const void *daddr, const void *saddr, unsigned len)
-{
-       struct shaper *sh=dev->priv;
-       int v;
-       if(sh_debug)
-               printk("Shaper header\n");
-       skb->dev = sh->dev;
-       v = dev_hard_header(skb, sh->dev, type, daddr, saddr, len);
-       skb->dev = dev;
-       return v;
-}
-
-static int shaper_rebuild_header(struct sk_buff *skb)
-{
-       struct shaper *sh=skb->dev->priv;
-       struct net_device *dev=skb->dev;
-       int v;
-       if(sh_debug)
-               printk("Shaper rebuild header\n");
-       skb->dev=sh->dev;
-       v = sh->dev->header_ops->rebuild(skb);
-       skb->dev=dev;
-       return v;
-}
-
-#if 0
-static int shaper_cache(struct neighbour *neigh, struct hh_cache *hh)
-{
-       struct shaper *sh=neigh->dev->priv;
-       struct net_device *tmp;
-       int ret;
-       if(sh_debug)
-               printk("Shaper header cache bind\n");
-       tmp=neigh->dev;
-       neigh->dev=sh->dev;
-       ret=sh->hard_header_cache(neigh,hh);
-       neigh->dev=tmp;
-       return ret;
-}
-
-static void shaper_cache_update(struct hh_cache *hh, struct net_device *dev,
-       unsigned char *haddr)
-{
-       struct shaper *sh=dev->priv;
-       if(sh_debug)
-               printk("Shaper cache update\n");
-       sh->header_cache_update(hh, sh->dev, haddr);
-}
-#endif
-
-#ifdef CONFIG_INET
-
-static int shaper_neigh_setup(struct neighbour *n)
-{
-#ifdef CONFIG_INET
-       if (n->nud_state == NUD_NONE) {
-               n->ops = &arp_broken_ops;
-               n->output = n->ops->output;
-       }
-#endif
-       return 0;
-}
-
-static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
-{
-#ifdef CONFIG_INET
-       if (p->tbl->family == AF_INET) {
-               p->neigh_setup = shaper_neigh_setup;
-               p->ucast_probes = 0;
-               p->mcast_probes = 0;
-       }
-#endif
-       return 0;
-}
-
-#else /* !(CONFIG_INET) */
-
-static int shaper_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
-{
-       return 0;
-}
-
-#endif
-
-static const struct header_ops shaper_ops = {
-       .create  = shaper_header,
-       .rebuild = shaper_rebuild_header,
-};
-
-static int shaper_attach(struct net_device *shdev, struct shaper *sh, struct net_device *dev)
-{
-       sh->dev = dev;
-       sh->get_stats=dev->get_stats;
-
-       shdev->neigh_setup = shaper_neigh_setup_dev;
-       shdev->hard_header_len=dev->hard_header_len;
-       shdev->type=dev->type;
-       shdev->addr_len=dev->addr_len;
-       shdev->mtu=dev->mtu;
-       sh->bitspersec=0;
-       return 0;
-}
-
-static int shaper_ioctl(struct net_device *dev,  struct ifreq *ifr, int cmd)
-{
-       struct shaperconf *ss= (struct shaperconf *)&ifr->ifr_ifru;
-       struct shaper *sh=dev->priv;
-
-       if(ss->ss_cmd == SHAPER_SET_DEV || ss->ss_cmd == SHAPER_SET_SPEED)
-       {
-               if(!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-       }
-
-       switch(ss->ss_cmd)
-       {
-               case SHAPER_SET_DEV:
-               {
-                       struct net_device *them=__dev_get_by_name(&init_net, ss->ss_name);
-                       if(them==NULL)
-                               return -ENODEV;
-                       if(sh->dev)
-                               return -EBUSY;
-                       return shaper_attach(dev,dev->priv, them);
-               }
-               case SHAPER_GET_DEV:
-                       if(sh->dev==NULL)
-                               return -ENODEV;
-                       strcpy(ss->ss_name, sh->dev->name);
-                       return 0;
-               case SHAPER_SET_SPEED:
-                       shaper_setspeed(sh,ss->ss_speed);
-                       return 0;
-               case SHAPER_GET_SPEED:
-                       ss->ss_speed=sh->bitspersec;
-                       return 0;
-               default:
-                       return -EINVAL;
-       }
-}
-
-static void shaper_init_priv(struct net_device *dev)
-{
-       struct shaper *sh = dev->priv;
-
-       skb_queue_head_init(&sh->sendq);
-       init_timer(&sh->timer);
-       sh->timer.function=shaper_timer;
-       sh->timer.data=(unsigned long)sh;
-       spin_lock_init(&sh->lock);
-}
-
-/*
- *     Add a shaper device to the system
- */
-
-static void __init shaper_setup(struct net_device *dev)
-{
-       /*
-        *      Set up the shaper.
-        */
-
-       shaper_init_priv(dev);
-
-       dev->open               = shaper_open;
-       dev->stop               = shaper_close;
-       dev->hard_start_xmit    = shaper_start_xmit;
-       dev->set_multicast_list = NULL;
-
-       /*
-        *      Intialise the packet queues
-        */
-
-       /*
-        *      Handlers for when we attach to a device.
-        */
-
-       dev->neigh_setup        = shaper_neigh_setup_dev;
-       dev->do_ioctl           = shaper_ioctl;
-       dev->hard_header_len    = 0;
-       dev->type               = ARPHRD_ETHER; /* initially */
-       dev->set_mac_address    = NULL;
-       dev->mtu                = 1500;
-       dev->addr_len           = 0;
-       dev->tx_queue_len       = 10;
-       dev->flags              = 0;
-}
-
-static int shapers = 1;
-#ifdef MODULE
-
-module_param(shapers, int, 0);
-MODULE_PARM_DESC(shapers, "Traffic shaper: maximum number of shapers");
-
-#else /* MODULE */
-
-static int __init set_num_shapers(char *str)
-{
-       shapers = simple_strtol(str, NULL, 0);
-       return 1;
-}
-
-__setup("shapers=", set_num_shapers);
-
-#endif /* MODULE */
-
-static struct net_device **devs;
-
-static unsigned int shapers_registered = 0;
-
-static int __init shaper_init(void)
-{
-       int i;
-       size_t alloc_size;
-       struct net_device *dev;
-       char name[IFNAMSIZ];
-
-       if (shapers < 1)
-               return -ENODEV;
-
-       alloc_size = sizeof(*dev) * shapers;
-       devs = kzalloc(alloc_size, GFP_KERNEL);
-       if (!devs)
-               return -ENOMEM;
-
-       for (i = 0; i < shapers; i++) {
-
-               snprintf(name, IFNAMSIZ, "shaper%d", i);
-               dev = alloc_netdev(sizeof(struct shaper), name,
-                                  shaper_setup);
-               if (!dev)
-                       break;
-
-               if (register_netdev(dev)) {
-                       free_netdev(dev);
-                       break;
-               }
-
-               devs[i] = dev;
-               shapers_registered++;
-       }
-
-       if (!shapers_registered) {
-               kfree(devs);
-               devs = NULL;
-       }
-
-       return (shapers_registered ? 0 : -ENODEV);
-}
-
-static void __exit shaper_exit (void)
-{
-       int i;
-
-       for (i = 0; i < shapers_registered; i++) {
-               if (devs[i]) {
-                       unregister_netdev(devs[i]);
-                       free_netdev(devs[i]);
-               }
-       }
-
-       kfree(devs);
-       devs = NULL;
-}
-
-module_init(shaper_init);
-module_exit(shaper_exit);
-MODULE_LICENSE("GPL");
-
index 0857d2c88aa08fd963f26e23fe1b8f5fe1a7bd94..ec95e493ac1c2ec45ee716cac4510c7b15ae1193 100644 (file)
@@ -419,7 +419,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
 
        i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
        if(i){
-               printk(KERN_ERR "sis900.c: architecture does not support"
+               printk(KERN_ERR "sis900.c: architecture does not support "
                        "32bit PCI busmaster DMA\n");
                return i;
        }
@@ -1667,7 +1667,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
                /* something strange happened !!! */
                if (status & HIBERR) {
                        if(netif_msg_intr(sis_priv))
-                               printk(KERN_INFO "%s: Abnormal interrupt,"
+                               printk(KERN_INFO "%s: Abnormal interrupt, "
                                        "status %#8.8x.\n", net_dev->name, status);
                        break;
                }
@@ -1820,7 +1820,7 @@ refill_rx_ring:
                                 * how the hardware will react to this kind
                                 * of degenerated buffer */
                                if (netif_msg_rx_err(sis_priv))
-                                       printk(KERN_INFO "%s: Memory squeeze,"
+                                       printk(KERN_INFO "%s: Memory squeeze, "
                                                "deferring packet.\n",
                                                net_dev->name);
                                net_dev->stats.rx_dropped++;
index 0a6f67a7a3952bb57c5bd246fa8f5d902777799d..fde45083eb7bde5da608745cd4d4db4d2977f020 100644 (file)
@@ -82,7 +82,7 @@ PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id,
 
 
 /* defines *******************************************************************/
-#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0]))
+#define ID_TABLE_SIZE  ARRAY_SIZE(IdTable)
 
 
 /* global variables **********************************************************/
index b36dd9ac6b29c34f7637cb2c3e361260f29cc3bc..876bb2158fa6e2d7c43f2637a9ed3dd81e4cf5ef 100644 (file)
@@ -383,23 +383,11 @@ int Level)                /* Initialization level */
                        SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
 
                        SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("CounterOffset struct size (%d) differs from"
+                                          ("CounterOffset struct size (%d) differs from "
                                                "SK_PNMI_MAX_IDX (%d)\n",
                                                SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
                }
 
-               if (SK_PNMI_MAX_IDX !=
-                       (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
-                       
-                       SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
-
-                       SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
-                                          ("StatAddr table size (%d) differs from "
-                                               "SK_PNMI_MAX_IDX (%d)\n",
-                                               (sizeof(StatAddr) /
-                                                (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
-                                                SK_PNMI_MAX_IDX));
-               }
 #endif /* SK_PNMI_CHECK */
                break;
 
index 3e7aa49afd00565e8a10a13b07c5fd98d6f44f64..e5ee6d63ba4e68fff30e4ff3e41452a4e7d0472d 100644 (file)
@@ -892,7 +892,7 @@ int         Port)           /* Which port should be checked */
         */
        RxCts = 0;
 
-       for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(SkGeRxRegs); i++) {
                
                (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp);
                
index 438f424e63611ca73f372aa74207713507d34bb5..8a430a36654705fdc5fba5be36b20d3342db5aa4 100644 (file)
@@ -1746,7 +1746,7 @@ static void queue_llc_rx(struct s_smc *smc, SMbuf *mb)
        DB_GEN("queue_llc_rx: mb = %x",(void *)mb,0,4) ;
        smc->os.hwm.queued_rx_frames++ ;
        mb->sm_next = (SMbuf *)NULL ;
-       if (smc->os.hwm.llc_rx_pipe == 0) {
+       if (smc->os.hwm.llc_rx_pipe == NULL) {
                smc->os.hwm.llc_rx_pipe = mb ;
        }
        else {
@@ -1786,7 +1786,7 @@ static void queue_txd_mb(struct s_smc *smc, SMbuf *mb)
        DB_GEN("_rx: queue_txd_mb = %x",(void *)mb,0,4) ;
        smc->os.hwm.queued_txd_mb++ ;
        mb->sm_next = (SMbuf *)NULL ;
-       if (smc->os.hwm.txd_tx_pipe == 0) {
+       if (smc->os.hwm.txd_tx_pipe == NULL) {
                smc->os.hwm.txd_tx_pipe = mb ;
        }
        else {
index ced2c8f76be711f773881d1718405a9367752762..ffbfb1b79f97360975cd8da31d198591fde55037 100644 (file)
@@ -712,7 +712,7 @@ void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
                        smc->mib.priv.fddiPRIVECF_Reply_Rx++ ;
                        DB_SMT("SMT: received ECF reply from %s\n",
                                addr_to_string(&sm->smt_source),0) ;
-                       if (sm_to_para(smc,sm,SMT_P_ECHODATA) == 0) {
+                       if (sm_to_para(smc,sm,SMT_P_ECHODATA) == NULL) {
                                DB_SMT("SMT: ECHODATA missing\n",0,0) ;
                                break ;
                        }
index bc15940ce1bc8ed74ba8127df49f0599d2262c48..626190eb91e7ba567ea3c35ef9d26dac2aaf9b7e 100644 (file)
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.20"
+#define DRV_VERSION            "1.21"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -64,7 +64,6 @@
 #define RX_LE_BYTES            (RX_LE_SIZE*sizeof(struct sky2_rx_le))
 #define RX_MAX_PENDING         (RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING         RX_MAX_PENDING
-#define RX_SKB_ALIGN           8
 
 #define TX_RING_SIZE           512
 #define TX_DEF_PENDING         (TX_RING_SIZE - 1)
@@ -135,6 +134,8 @@ static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
        { 0 }
 };
 
@@ -548,6 +549,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 
        case CHIP_ID_YUKON_EC_U:
        case CHIP_ID_YUKON_EX:
+       case CHIP_ID_YUKON_SUPR:
                pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
 
                /* select page 3 to access LED control register */
@@ -714,23 +716,33 @@ static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
 {
        struct net_device *dev = hw->dev[port];
 
-       if (dev->mtu <= ETH_DATA_LEN)
-               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                            TX_JUMBO_DIS | TX_STFW_ENA);
+       if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
+             hw->chip_rev != CHIP_REV_YU_EX_A0) ||
+            hw->chip_id == CHIP_ID_YUKON_FE_P ||
+            hw->chip_id == CHIP_ID_YUKON_SUPR) {
+               /* Yukon-Extreme B0 and further Extreme devices */
+               /* enable Store & Forward mode for TX */
 
-       else if (hw->chip_id != CHIP_ID_YUKON_EC_U)
-               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                            TX_STFW_ENA | TX_JUMBO_ENA);
-       else {
-               /* set Tx GMAC FIFO Almost Empty Threshold */
-               sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
-                            (ECU_JUMBO_WM << 16) | ECU_AE_THR);
+               if (dev->mtu <= ETH_DATA_LEN)
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                                    TX_JUMBO_DIS | TX_STFW_ENA);
 
-               sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
-                            TX_JUMBO_ENA | TX_STFW_DIS);
+               else
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+                                    TX_JUMBO_ENA| TX_STFW_ENA);
+       } else {
+               if (dev->mtu <= ETH_DATA_LEN)
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
+               else {
+                       /* set Tx GMAC FIFO Almost Empty Threshold */
+                       sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+                                    (ECU_JUMBO_WM << 16) | ECU_AE_THR);
 
-               /* Can't do offload because of lack of store/forward */
-               dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
+                       sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+
+                       /* Can't do offload because of lack of store/forward */
+                       dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
+               }
        }
 }
 
@@ -1174,24 +1186,32 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp
 /*
  * Allocate an skb for receiving. If the MTU is large enough
  * make the skb non-linear with a fragment list of pages.
- *
- * It appears the hardware has a bug in the FIFO logic that
- * cause it to hang if the FIFO gets overrun and the receive buffer
- * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
- * aligned except if slab debugging is enabled.
  */
 static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
 {
        struct sk_buff *skb;
-       unsigned long p;
        int i;
 
-       skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN);
-       if (!skb)
-               goto nomem;
-
-       p = (unsigned long) skb->data;
-       skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
+       if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) {
+               unsigned char *start;
+               /*
+                * Workaround for a bug in FIFO that cause hang
+                * if the FIFO if the receive buffer is not 64 byte aligned.
+                * The buffer returned from netdev_alloc_skb is
+                * aligned except if slab debugging is enabled.
+                */
+               skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8);
+               if (!skb)
+                       goto nomem;
+               start = PTR_ALIGN(skb->data, 8);
+               skb_reserve(skb, start - skb->data);
+       } else {
+               skb = netdev_alloc_skb(sky2->netdev,
+                                      sky2->rx_data_size + NET_IP_ALIGN);
+               if (!skb)
+                       goto nomem;
+               skb_reserve(skb, NET_IP_ALIGN);
+       }
 
        for (i = 0; i < sky2->rx_nfrags; i++) {
                struct page *page = alloc_page(GFP_ATOMIC);
@@ -1227,7 +1247,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
        struct sky2_hw *hw = sky2->hw;
        struct rx_ring_info *re;
        unsigned rxq = rxqaddr[sky2->port];
-       unsigned i, size, space, thresh;
+       unsigned i, size, thresh;
 
        sky2->rx_put = sky2->rx_next = 0;
        sky2_qset(hw, rxq);
@@ -1254,28 +1274,18 @@ static int sky2_rx_start(struct sky2_port *sky2)
        /* Stopping point for hardware truncation */
        thresh = (size - 8) / sizeof(u32);
 
-       /* Account for overhead of skb - to avoid order > 0 allocation */
-       space = SKB_DATA_ALIGN(size) + NET_SKB_PAD
-               + sizeof(struct skb_shared_info);
-
-       sky2->rx_nfrags = space >> PAGE_SHIFT;
+       sky2->rx_nfrags = size >> PAGE_SHIFT;
        BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr));
 
-       if (sky2->rx_nfrags != 0) {
-               /* Compute residue after pages */
-               space = sky2->rx_nfrags << PAGE_SHIFT;
+       /* Compute residue after pages */
+       size -= sky2->rx_nfrags << PAGE_SHIFT;
 
-               if (space < size)
-                       size -= space;
-               else
-                       size = 0;
+       /* Optimize to handle small packets and headers */
+       if (size < copybreak)
+               size = copybreak;
+       if (size < ETH_HLEN)
+               size = ETH_HLEN;
 
-               /* Optimize to handle small packets and headers */
-               if (size < copybreak)
-                       size = copybreak;
-               if (size < ETH_HLEN)
-                       size = ETH_HLEN;
-       }
        sky2->rx_data_size = size;
 
        /* Fill Rx ring */
@@ -2663,6 +2673,7 @@ static u32 sky2_mhz(const struct sky2_hw *hw)
        case CHIP_ID_YUKON_EC:
        case CHIP_ID_YUKON_EC_U:
        case CHIP_ID_YUKON_EX:
+       case CHIP_ID_YUKON_SUPR:
                return 125;
 
        case CHIP_ID_YUKON_FE:
@@ -2746,6 +2757,15 @@ static int __devinit sky2_init(struct sky2_hw *hw)
                        | SKY2_HW_AUTO_TX_SUM
                        | SKY2_HW_ADV_POWER_CTL;
                break;
+
+       case CHIP_ID_YUKON_SUPR:
+               hw->flags = SKY2_HW_GIGABIT
+                       | SKY2_HW_NEWER_PHY
+                       | SKY2_HW_NEW_LE
+                       | SKY2_HW_AUTO_TX_SUM
+                       | SKY2_HW_ADV_POWER_CTL;
+               break;
+
        default:
                dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
                        hw->chip_id);
@@ -2816,7 +2836,8 @@ static void sky2_reset(struct sky2_hw *hw)
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
                sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
 
-               if (hw->chip_id == CHIP_ID_YUKON_EX)
+               if (hw->chip_id == CHIP_ID_YUKON_EX ||
+                   hw->chip_id == CHIP_ID_YUKON_SUPR)
                        sky2_write16(hw, SK_REG(i, GMAC_CTRL),
                                     GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
                                     | GMC_BYP_RETR_ON);
index ffe9b8a50a1b75943d1d9b9fec9a07a917b2e71b..2bced1a0898f45a1b08bb60d941c938619d7c7e0 100644 (file)
@@ -425,12 +425,13 @@ enum {
 
 /*     B2_CHIP_ID               8 bit  Chip Identification Number */
 enum {
-       CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
-       CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
-       CHIP_ID_YUKON_EX   = 0xb5, /* Chip ID for YUKON-2 Extreme */
-       CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
-       CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
-       CHIP_ID_YUKON_FE_P = 0xb8, /* Chip ID for YUKON-2 FE+ */
+       CHIP_ID_YUKON_XL   = 0xb3, /* YUKON-2 XL */
+       CHIP_ID_YUKON_EC_U = 0xb4, /* YUKON-2 EC Ultra */
+       CHIP_ID_YUKON_EX   = 0xb5, /* YUKON-2 Extreme */
+       CHIP_ID_YUKON_EC   = 0xb6, /* YUKON-2 EC */
+       CHIP_ID_YUKON_FE   = 0xb7, /* YUKON-2 FE */
+       CHIP_ID_YUKON_FE_P = 0xb8, /* YUKON-2 FE+ */
+       CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
 };
 enum yukon_ec_rev {
        CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
index 0adab709ab68ecdfa2c56dc0367736681369b2ea..d640c0f5470be3bf315c5f53a5d37274a2afdbce 100644 (file)
@@ -174,7 +174,7 @@ put16(unsigned char *cp, unsigned short x)
 
 
 /* Encode a number */
-unsigned char *
+static unsigned char *
 encode(unsigned char *cp, unsigned short n)
 {
        if(n >= 256 || n == 0){
@@ -199,7 +199,7 @@ pull16(unsigned char **cpp)
 }
 
 /* Decode a number */
-long
+static long
 decode(unsigned char **cpp)
 {
        register int x;
@@ -233,6 +233,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize,
        register unsigned char *cp = new_seq;
        struct iphdr *ip;
        struct tcphdr *th, *oth;
+       __sum16 csum;
 
 
        /*
@@ -428,7 +429,7 @@ found:
        /* Grab the cksum before we overwrite it below.  Then update our
         * state with this packet's header.
         */
-       deltaA = ntohs(th->check);
+       csum = th->check;
        memcpy(&cs->cs_ip,ip,20);
        memcpy(&cs->cs_tcp,th,20);
        /* We want to use the original packet as our compressed packet.
@@ -449,7 +450,8 @@ found:
                *cpp = ocp;
                *cp++ = changes;
        }
-       cp = put16(cp,(short)deltaA);   /* Write TCP checksum */
+       *(__sum16 *)cp = csum;
+       cp += 2;
 /* deltaS is now the size of the change section of the compressed header */
        memcpy(cp,new_seq,deltaS);      /* Write list of deltas */
        memcpy(cp+deltaS,icp+hlen,isize-hlen);
@@ -519,10 +521,8 @@ slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize)
        thp = &cs->cs_tcp;
        ip = &cs->cs_ip;
 
-       if((x = pull16(&cp)) == -1) {   /* Read the TCP checksum */
-               goto bad;
-        }
-       thp->check = htons(x);
+       thp->check = *(__sum16 *)cp;
+       cp += 2;
 
        thp->psh = (changes & TCP_PUSH_BIT) ? 1 : 0;
 /*
index 251a3ce376ac60828fea0389b97316c649b6adcc..5a55ede352f4bc79dbceb5ee73bc2a6c0afb59d6 100644 (file)
  * Fixes:
  *             Alan Cox        :       Sanity checks and avoid tx overruns.
  *                                     Has a new sl->mtu field.
- *             Alan Cox        :       Found cause of overrun. ifconfig sl0 mtu upwards.
- *                                     Driver now spots this and grows/shrinks its buffers(hack!).
- *                                     Memory leak if you run out of memory setting up a slip driver fixed.
+ *             Alan Cox        :       Found cause of overrun. ifconfig sl0
+ *                                     mtu upwards. Driver now spots this
+ *                                     and grows/shrinks its buffers(hack!).
+ *                                     Memory leak if you run out of memory
+ *                                     setting up a slip driver fixed.
  *             Matt Dillon     :       Printable slip (borrowed from NET2E)
  *     Pauline Middelink       :       Slip driver fixes.
  *             Alan Cox        :       Honours the old SL_COMPRESSED flag
@@ -29,7 +31,8 @@
  *                                      buffering from 4096 to 256 bytes.
  *                                      Improving SLIP response time.
  *                                      CONFIG_SLIP_MODE_SLIP6.
- *                                      ifconfig sl? up & down now works correctly.
+ *                                      ifconfig sl? up & down now works
+ *                                     correctly.
  *                                     Modularization.
  *              Alan Cox        :       Oops - fix AX.25 buffer lengths
  *      Dmitry Gorodchanin      :       Even more cleanups. Preserve CSLIP
  *                                     device entries, just reg./unreg. them
  *                                     as they are needed.  We kfree() them
  *                                     at module cleanup.
- *                                     With MODULE-loading ``insmod'', user can
- *                                     issue parameter:   slip_maxdev=1024
- *                                     (Or how much he/she wants.. Default is 256)
- * *   Stanislav Voronyi       :       Slip line checking, with ideas taken
- *                                     from multislip BSDI driver which was written
- *                                     by Igor Chechik, RELCOM Corp. Only algorithms
- *                                     have been ported to Linux SLIP driver.
+ *                                     With MODULE-loading ``insmod'', user
+ *                                     can issue parameter:  slip_maxdev=1024
+ *                                     (Or how much he/she wants.. Default
+ *                                     is 256)
+ *     Stanislav Voronyi       :       Slip line checking, with ideas taken
+ *                                     from multislip BSDI driver which was
+ *                                     written by Igor Chechik, RELCOM Corp.
+ *                                     Only algorithms have been ported to
+ *                                     Linux SLIP driver.
  *     Vitaly E. Lavrov        :       Sane behaviour on tty hangup.
- *     Alexey Kuznetsov        :       Cleanup interfaces to tty&netdevice modules.
+ *     Alexey Kuznetsov        :       Cleanup interfaces to tty & netdevice
+ *                                     modules.
  */
 
 #define SL_CHECK_TRANSMIT
@@ -99,7 +105,7 @@ static void slip_unesc6(struct slip *sl, unsigned char c);
 #ifdef CONFIG_SLIP_SMART
 static void sl_keepalive(unsigned long sls);
 static void sl_outfill(unsigned long sls);
-static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd);
+static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 #endif
 
 /********************************
@@ -117,15 +123,14 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd);
    Allocate channel buffers.
  */
 
-static int
-sl_alloc_bufs(struct slip *sl, int mtu)
+static int sl_alloc_bufs(struct slip *sl, int mtu)
 {
        int err = -ENOBUFS;
        unsigned long len;
-       char * rbuff = NULL;
-       char * xbuff = NULL;
+       char *rbuff = NULL;
+       char *xbuff = NULL;
 #ifdef SL_INCLUDE_CSLIP
-       char * cbuff = NULL;
+       char *cbuff = NULL;
        struct slcompress *slcomp = NULL;
 #endif
 
@@ -195,8 +200,7 @@ err_exit:
 }
 
 /* Free a SLIP channel buffers. */
-static void
-sl_free_bufs(struct slip *sl)
+static void sl_free_bufs(struct slip *sl)
 {
        /* Free all SLIP frame buffers. */
        kfree(xchg(&sl->rbuff, NULL));
@@ -248,7 +252,6 @@ static int sl_realloc_bufs(struct slip *sl, int mtu)
                }
                goto done;
        }
-
        spin_lock_bh(&sl->lock);
 
        err = -ENODEV;
@@ -298,23 +301,20 @@ done:
 
 
 /* Set the "sending" flag.  This must be atomic hence the set_bit. */
-static inline void
-sl_lock(struct slip *sl)
+static inline void sl_lock(struct slip *sl)
 {
        netif_stop_queue(sl->dev);
 }
 
 
 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
-static inline void
-sl_unlock(struct slip *sl)
+static inline void sl_unlock(struct slip *sl)
 {
        netif_wake_queue(sl->dev);
 }
 
 /* Send one completely decapsulated IP datagram to the IP layer. */
-static void
-sl_bump(struct slip *sl)
+static void sl_bump(struct slip *sl)
 {
        struct sk_buff *skb;
        int count;
@@ -322,22 +322,22 @@ sl_bump(struct slip *sl)
        count = sl->rcount;
 #ifdef SL_INCLUDE_CSLIP
        if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
-               unsigned char c;
-               if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
+               unsigned char c = sl->rbuff[0];
+               if (c & SL_TYPE_COMPRESSED_TCP) {
                        /* ignore compressed packets when CSLIP is off */
                        if (!(sl->mode & SL_MODE_CSLIP)) {
                                printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name);
                                return;
                        }
-                       /* make sure we've reserved enough space for uncompress to use */
+                       /* make sure we've reserved enough space for uncompress
+                          to use */
                        if (count + 80 > sl->buffsize) {
                                sl->rx_over_errors++;
                                return;
                        }
                        count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
-                       if (count <= 0) {
+                       if (count <= 0)
                                return;
-                       }
                } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
                        if (!(sl->mode & SL_MODE_CSLIP)) {
                                /* turn on header compression */
@@ -346,33 +346,31 @@ sl_bump(struct slip *sl)
                                printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name);
                        }
                        sl->rbuff[0] &= 0x4f;
-                       if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
+                       if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0)
                                return;
-                       }
                }
        }
 #endif  /* SL_INCLUDE_CSLIP */
 
-       sl->rx_bytes+=count;
+       sl->rx_bytes += count;
 
        skb = dev_alloc_skb(count);
-       if (skb == NULL)  {
+       if (skb == NULL) {
                printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name);
                sl->rx_dropped++;
                return;
        }
        skb->dev = sl->dev;
-       memcpy(skb_put(skb,count), sl->rbuff, count);
+       memcpy(skb_put(skb, count), sl->rbuff, count);
        skb_reset_mac_header(skb);
-       skb->protocol=htons(ETH_P_IP);
+       skb->protocol = htons(ETH_P_IP);
        netif_rx(skb);
        sl->dev->last_rx = jiffies;
        sl->rx_packets++;
 }
 
 /* Encapsulate one IP datagram and stuff into a TTY queue. */
-static void
-sl_encaps(struct slip *sl, unsigned char *icp, int len)
+static void sl_encaps(struct slip *sl, unsigned char *icp, int len)
 {
        unsigned char *p;
        int actual, count;
@@ -386,12 +384,11 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len)
 
        p = icp;
 #ifdef SL_INCLUDE_CSLIP
-       if (sl->mode & SL_MODE_CSLIP)  {
+       if (sl->mode & SL_MODE_CSLIP)
                len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
-       }
 #endif
 #ifdef CONFIG_SLIP_MODE_SLIP6
-       if(sl->mode & SL_MODE_SLIP6)
+       if (sl->mode & SL_MODE_SLIP6)
                count = slip_esc6(p, (unsigned char *) sl->xbuff, len);
        else
 #endif
@@ -425,12 +422,12 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len)
 static void slip_write_wakeup(struct tty_struct *tty)
 {
        int actual;
-       struct slip *sl = (struct slip *) tty->disc_data;
+       struct slip *sl = tty->disc_data;
 
        /* First make sure we're connected. */
-       if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) {
+       if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
                return;
-       }
+
        if (sl->xleft <= 0)  {
                /* Now serial buffer is almost free & we can start
                 * transmission of another packet */
@@ -463,15 +460,15 @@ static void sl_tx_timeout(struct net_device *dev)
                        /* 20 sec timeout not reached */
                        goto out;
                }
-               printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
-                      (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
-                      "bad line quality" : "driver error");
+               printk(KERN_WARNING "%s: transmit timed out, %s?\n",
+                       dev->name,
+                       (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
+                               "bad line quality" : "driver error");
                sl->xleft = 0;
                sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
                sl_unlock(sl);
 #endif
        }
-
 out:
        spin_unlock(&sl->lock);
 }
@@ -484,7 +481,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
        struct slip *sl = netdev_priv(dev);
 
        spin_lock(&sl->lock);
-       if (!netif_running(dev))  {
+       if (!netif_running(dev)) {
                spin_unlock(&sl->lock);
                printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name);
                dev_kfree_skb(skb);
@@ -497,7 +494,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        sl_lock(sl);
-       sl->tx_bytes+=skb->len;
+       sl->tx_bytes += skb->len;
        sl_encaps(sl, skb->data, skb->len);
        spin_unlock(&sl->lock);
 
@@ -536,7 +533,7 @@ static int sl_open(struct net_device *dev)
 {
        struct slip *sl = netdev_priv(dev);
 
-       if (sl->tty==NULL)
+       if (sl->tty == NULL)
                return -ENODEV;
 
        sl->flags &= (1 << SLF_INUSE);
@@ -657,20 +654,19 @@ static void sl_setup(struct net_device *dev)
  * in parallel
  */
 
-static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
+static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
+                                                       char *fp, int count)
 {
-       struct slip *sl = (struct slip *) tty->disc_data;
+       struct slip *sl = tty->disc_data;
 
-       if (!sl || sl->magic != SLIP_MAGIC ||
-           !netif_running(sl->dev))
+       if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
                return;
 
        /* Read the characters out of the buffer */
        while (count--) {
                if (fp && *fp++) {
-                       if (!test_and_set_bit(SLF_ERROR, &sl->flags))  {
+                       if (!test_and_set_bit(SLF_ERROR, &sl->flags))
                                sl->rx_errors++;
-                       }
                        cp++;
                        continue;
                }
@@ -688,7 +684,6 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch
  ************************************/
 
 /* Collect hanged up channels */
-
 static void sl_sync(void)
 {
        int i;
@@ -696,21 +691,21 @@ static void sl_sync(void)
        struct slip       *sl;
 
        for (i = 0; i < slip_maxdev; i++) {
-               if ((dev = slip_devs[i]) == NULL)
+               dev = slip_devs[i];
+               if (dev == NULL)
                        break;
 
                sl = netdev_priv(dev);
                if (sl->tty || sl->leased)
                        continue;
-               if (dev->flags&IFF_UP)
+               if (dev->flags & IFF_UP)
                        dev_close(dev);
        }
 }
 
 
 /* Find a free SLIP channel, and link in this `tty' line. */
-static struct slip *
-sl_alloc(dev_t line)
+static struct slip *sl_alloc(dev_t line)
 {
        int i;
        int sel = -1;
@@ -805,15 +800,15 @@ sl_alloc(dev_t line)
        spin_lock_init(&sl->lock);
        sl->mode        = SL_MODE_DEFAULT;
 #ifdef CONFIG_SLIP_SMART
-       init_timer(&sl->keepalive_timer);       /* initialize timer_list struct */
-       sl->keepalive_timer.data=(unsigned long)sl;
-       sl->keepalive_timer.function=sl_keepalive;
+       /* initialize timer_list struct */
+       init_timer(&sl->keepalive_timer);
+       sl->keepalive_timer.data = (unsigned long)sl;
+       sl->keepalive_timer.function = sl_keepalive;
        init_timer(&sl->outfill_timer);
-       sl->outfill_timer.data=(unsigned long)sl;
-       sl->outfill_timer.function=sl_outfill;
+       sl->outfill_timer.data = (unsigned long)sl;
+       sl->outfill_timer.function = sl_outfill;
 #endif
        slip_devs[i] = dev;
-
        return sl;
 }
 
@@ -832,7 +827,7 @@ static int slip_open(struct tty_struct *tty)
        struct slip *sl;
        int err;
 
-       if(!capable(CAP_NET_ADMIN))
+       if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
        /* RTnetlink lock is misused here to serialize concurrent
@@ -844,7 +839,7 @@ static int slip_open(struct tty_struct *tty)
        /* Collect hanged up channels. */
        sl_sync();
 
-       sl = (struct slip *) tty->disc_data;
+       sl = tty->disc_data;
 
        err = -EEXIST;
        /* First make sure we're not already connected. */
@@ -853,7 +848,8 @@ static int slip_open(struct tty_struct *tty)
 
        /* OK.  Find a free SLIP channel to use. */
        err = -ENFILE;
-       if ((sl = sl_alloc(tty_devnum(tty))) == NULL)
+       sl = sl_alloc(tty_devnum(tty));
+       if (sl == NULL)
                goto err_exit;
 
        sl->tty = tty;
@@ -863,23 +859,25 @@ static int slip_open(struct tty_struct *tty)
 
        if (!test_bit(SLF_INUSE, &sl->flags)) {
                /* Perform the low-level SLIP initialization. */
-               if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0)
+               err = sl_alloc_bufs(sl, SL_MTU);
+               if (err)
                        goto err_free_chan;
 
                set_bit(SLF_INUSE, &sl->flags);
 
-               if ((err = register_netdevice(sl->dev)))
+               err = register_netdevice(sl->dev);
+               if (err)
                        goto err_free_bufs;
        }
 
 #ifdef CONFIG_SLIP_SMART
        if (sl->keepalive) {
-               sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
-               add_timer (&sl->keepalive_timer);
+               sl->keepalive_timer.expires = jiffies + sl->keepalive * HZ;
+               add_timer(&sl->keepalive_timer);
        }
        if (sl->outfill) {
-               sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
-               add_timer (&sl->outfill_timer);
+               sl->outfill_timer.expires = jiffies + sl->outfill * HZ;
+               add_timer(&sl->outfill_timer);
        }
 #endif
 
@@ -928,10 +926,9 @@ err_exit:
  * This means flushing out any pending queues, and then returning. This
  * call is serialized against other ldisc functions.
  */
-static void
-slip_close(struct tty_struct *tty)
+static void slip_close(struct tty_struct *tty)
 {
-       struct slip *sl = (struct slip *) tty->disc_data;
+       struct slip *sl = tty->disc_data;
 
        /* First make sure we're connected. */
        if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty)
@@ -955,8 +952,7 @@ slip_close(struct tty_struct *tty)
   *                    STANDARD SLIP ENCAPSULATION                      *
   ************************************************************************/
 
-static int
-slip_esc(unsigned char *s, unsigned char *d, int len)
+static int slip_esc(unsigned char *s, unsigned char *d, int len)
 {
        unsigned char *ptr = d;
        unsigned char c;
@@ -975,16 +971,16 @@ slip_esc(unsigned char *s, unsigned char *d, int len)
         */
 
        while (len-- > 0) {
-               switch(c = *s++) {
-                case END:
+               switch (c = *s++) {
+               case END:
                        *ptr++ = ESC;
                        *ptr++ = ESC_END;
                        break;
-                case ESC:
+               case ESC:
                        *ptr++ = ESC;
                        *ptr++ = ESC_ESC;
                        break;
-                default:
+               default:
                        *ptr++ = c;
                        break;
                }
@@ -996,33 +992,31 @@ slip_esc(unsigned char *s, unsigned char *d, int len)
 static void slip_unesc(struct slip *sl, unsigned char s)
 {
 
-       switch(s) {
-        case END:
+       switch (s) {
+       case END:
 #ifdef CONFIG_SLIP_SMART
                /* drop keeptest bit = VSV */
                if (test_bit(SLF_KEEPTEST, &sl->flags))
                        clear_bit(SLF_KEEPTEST, &sl->flags);
 #endif
 
-               if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))  {
+               if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
+                                                       && (sl->rcount > 2))
                        sl_bump(sl);
-               }
                clear_bit(SLF_ESCAPE, &sl->flags);
                sl->rcount = 0;
                return;
 
-        case ESC:
+       case ESC:
                set_bit(SLF_ESCAPE, &sl->flags);
                return;
-        case ESC_ESC:
-               if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))  {
+       case ESC_ESC:
+               if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
                        s = ESC;
-               }
                break;
-        case ESC_END:
-               if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))  {
+       case ESC_END:
+               if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
                        s = END;
-               }
                break;
        }
        if (!test_bit(SLF_ERROR, &sl->flags))  {
@@ -1041,8 +1035,7 @@ static void slip_unesc(struct slip *sl, unsigned char s)
  *                      6 BIT SLIP ENCAPSULATION                       *
  ************************************************************************/
 
-int
-slip_esc6(unsigned char *s, unsigned char *d, int len)
+static int slip_esc6(unsigned char *s, unsigned char *d, int len)
 {
        unsigned char *ptr = d;
        unsigned char c;
@@ -1079,8 +1072,7 @@ slip_esc6(unsigned char *s, unsigned char *d, int len)
        return ptr - d;
 }
 
-void
-slip_unesc6(struct slip *sl, unsigned char s)
+static void slip_unesc6(struct slip *sl, unsigned char s)
 {
        unsigned char c;
 
@@ -1091,13 +1083,13 @@ slip_unesc6(struct slip *sl, unsigned char s)
                        clear_bit(SLF_KEEPTEST, &sl->flags);
 #endif
 
-               if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))  {
+               if (!test_and_clear_bit(SLF_ERROR, &sl->flags)
+                                                       && (sl->rcount > 2))
                        sl_bump(sl);
-               }
                sl->rcount = 0;
                sl->xbits = 0;
                sl->xdata = 0;
-       } else if (s >= 0x30 && s < 0x70) {
+       } else if (s >= 0x30 && s < 0x70) {
                sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
                sl->xbits += 6;
                if (sl->xbits >= 8) {
@@ -1112,24 +1104,24 @@ slip_unesc6(struct slip *sl, unsigned char s)
                                set_bit(SLF_ERROR, &sl->flags);
                        }
                }
-       }
+       }
 }
 #endif /* CONFIG_SLIP_MODE_SLIP6 */
 
 /* Perform I/O control on an active SLIP channel. */
-static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
+static int slip_ioctl(struct tty_struct *tty, struct file *file,
+                                       unsigned int cmd, unsigned long arg)
 {
-       struct slip *sl = (struct slip *) tty->disc_data;
+       struct slip *sl = tty->disc_data;
        unsigned int tmp;
        int __user *p = (int __user *)arg;
 
        /* First make sure we're connected. */
-       if (!sl || sl->magic != SLIP_MAGIC) {
+       if (!sl || sl->magic != SLIP_MAGIC)
                return -EINVAL;
-       }
 
-       switch(cmd) {
-        case SIOCGIFNAME:
+       switch (cmd) {
+       case SIOCGIFNAME:
                tmp = strlen(sl->dev->name) + 1;
                if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
                        return -EFAULT;
@@ -1144,34 +1136,31 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                if (get_user(tmp, p))
                        return -EFAULT;
 #ifndef SL_INCLUDE_CSLIP
-               if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE))  {
+               if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE))
                        return -EINVAL;
-               }
 #else
                if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) ==
-                   (SL_MODE_ADAPTIVE | SL_MODE_CSLIP))  {
+                   (SL_MODE_ADAPTIVE | SL_MODE_CSLIP))
                        /* return -EINVAL; */
                        tmp &= ~SL_MODE_ADAPTIVE;
-               }
 #endif
 #ifndef CONFIG_SLIP_MODE_SLIP6
-               if (tmp & SL_MODE_SLIP6)  {
+               if (tmp & SL_MODE_SLIP6)
                        return -EINVAL;
-               }
 #endif
                sl->mode = tmp;
-               sl->dev->type = ARPHRD_SLIP+sl->mode;
+               sl->dev->type = ARPHRD_SLIP + sl->mode;
                return 0;
 
-        case SIOCSIFHWADDR:
+       case SIOCSIFHWADDR:
                return -EINVAL;
 
 #ifdef CONFIG_SLIP_SMART
        /* VSV changes start here */
-        case SIOCSKEEPALIVE:
+       case SIOCSKEEPALIVE:
                if (get_user(tmp, p))
                        return -EFAULT;
-                if (tmp > 255) /* max for unchar */
+               if (tmp > 255) /* max for unchar */
                        return -EINVAL;
 
                spin_lock_bh(&sl->lock);
@@ -1179,40 +1168,42 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
                        spin_unlock_bh(&sl->lock);
                        return -ENODEV;
                }
-               if ((sl->keepalive = (unchar) tmp) != 0) {
-                       mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
+               sl->keepalive = (u8)tmp;
+               if (sl->keepalive != 0) {
+                       mod_timer(&sl->keepalive_timer,
+                                       jiffies + sl->keepalive * HZ);
                        set_bit(SLF_KEEPTEST, &sl->flags);
-                } else {
-                        del_timer (&sl->keepalive_timer);
-               }
+               } else
+                       del_timer(&sl->keepalive_timer);
                spin_unlock_bh(&sl->lock);
                return 0;
 
-        case SIOCGKEEPALIVE:
+       case SIOCGKEEPALIVE:
                if (put_user(sl->keepalive, p))
                        return -EFAULT;
                return 0;
 
-        case SIOCSOUTFILL:
+       case SIOCSOUTFILL:
                if (get_user(tmp, p))
                        return -EFAULT;
-                if (tmp > 255) /* max for unchar */
+               if (tmp > 255) /* max for unchar */
                        return -EINVAL;
                spin_lock_bh(&sl->lock);
                if (!sl->tty) {
                        spin_unlock_bh(&sl->lock);
                        return -ENODEV;
                }
-                if ((sl->outfill = (unchar) tmp) != 0){
-                       mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
+               sl->outfill = (u8)tmp;
+               if (sl->outfill != 0) {
+                       mod_timer(&sl->outfill_timer,
+                                               jiffies + sl->outfill * HZ);
                        set_bit(SLF_OUTWAIT, &sl->flags);
-               } else {
-                        del_timer (&sl->outfill_timer);
-               }
+               } else
+                       del_timer(&sl->outfill_timer);
                spin_unlock_bh(&sl->lock);
-                return 0;
+               return 0;
 
-        case SIOCGOUTFILL:
+       case SIOCGOUTFILL:
                if (put_user(sl->outfill, p))
                        return -EFAULT;
                return 0;
@@ -1229,7 +1220,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm
    to allow get/set outfill/keepalive parameter
    by ifconfig                                 */
 
-static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
+static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct slip *sl = netdev_priv(dev);
        unsigned long *p = (unsigned long *)&rq->ifr_ifru;
@@ -1244,58 +1235,61 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
                return -ENODEV;
        }
 
-       switch(cmd){
-        case SIOCSKEEPALIVE:
+       switch (cmd) {
+       case SIOCSKEEPALIVE:
                /* max for unchar */
-                if ((unsigned)*p > 255) {
+               if ((unsigned)*p > 255) {
                        spin_unlock_bh(&sl->lock);
                        return -EINVAL;
                }
-               sl->keepalive = (unchar) *p;
+               sl->keepalive = (u8)*p;
                if (sl->keepalive != 0) {
-                       sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
-                       mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
+                       sl->keepalive_timer.expires =
+                                               jiffies + sl->keepalive * HZ;
+                       mod_timer(&sl->keepalive_timer,
+                                               jiffies + sl->keepalive * HZ);
                        set_bit(SLF_KEEPTEST, &sl->flags);
-                } else {
-                        del_timer(&sl->keepalive_timer);
-               }
+               } else
+                       del_timer(&sl->keepalive_timer);
                break;
 
-        case SIOCGKEEPALIVE:
+       case SIOCGKEEPALIVE:
                *p = sl->keepalive;
                break;
 
-        case SIOCSOUTFILL:
-                if ((unsigned)*p > 255) { /* max for unchar */
+       case SIOCSOUTFILL:
+               if ((unsigned)*p > 255) { /* max for unchar */
                        spin_unlock_bh(&sl->lock);
                        return -EINVAL;
                }
-                if ((sl->outfill = (unchar)*p) != 0){
-                       mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
+               sl->outfill = (u8)*p;
+               if (sl->outfill != 0) {
+                       mod_timer(&sl->outfill_timer,
+                                               jiffies + sl->outfill * HZ);
                        set_bit(SLF_OUTWAIT, &sl->flags);
-               } else {
-                        del_timer (&sl->outfill_timer);
-               }
-                break;
+               } else
+                       del_timer(&sl->outfill_timer);
+               break;
 
-        case SIOCGOUTFILL:
+       case SIOCGOUTFILL:
                *p = sl->outfill;
                break;
 
-        case SIOCSLEASE:
+       case SIOCSLEASE:
                /* Resolve race condition, when ioctl'ing hanged up
                   and opened by another process device.
                 */
-               if (sl->tty != current->signal->tty && sl->pid != current->pid) {
+               if (sl->tty != current->signal->tty &&
+                                               sl->pid != current->pid) {
                        spin_unlock_bh(&sl->lock);
                        return -EPERM;
                }
                sl->leased = 0;
-                if (*p)
+               if (*p)
                        sl->leased = 1;
-                break;
+               break;
 
-        case SIOCGLEASE:
+       case SIOCGLEASE:
                *p = sl->leased;
        };
        spin_unlock_bh(&sl->lock);
@@ -1327,7 +1321,7 @@ static int __init slip_init(void)
               " (6 bit encapsulation enabled)"
 #endif
               ".\n",
-              SLIP_VERSION, slip_maxdev );
+              SLIP_VERSION, slip_maxdev);
 #if defined(SL_INCLUDE_CSLIP)
        printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California.\n");
 #endif
@@ -1335,14 +1329,16 @@ static int __init slip_init(void)
        printk(KERN_INFO "SLIP linefill/keepalive option.\n");
 #endif
 
-       slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL);
+       slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev,
+                                                               GFP_KERNEL);
        if (!slip_devs) {
-               printk(KERN_ERR "SLIP: Can't allocate slip devices array!  Uaargh! (-> No SLIP available)\n");
+               printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n");
                return -ENOMEM;
        }
 
        /* Fill in our line protocol discipline, and register it */
-       if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)  {
+       status = tty_register_ldisc(N_SLIP, &sl_ldisc);
+       if (status != 0) {
                printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status);
                kfree(slip_devs);
        }
@@ -1402,10 +1398,9 @@ static void __exit slip_exit(void)
        kfree(slip_devs);
        slip_devs = NULL;
 
-       if ((i = tty_unregister_ldisc(N_SLIP)))
-       {
+       i = tty_unregister_ldisc(N_SLIP);
+       if (i != 0)
                printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
-       }
 }
 
 module_init(slip_init);
@@ -1419,17 +1414,15 @@ module_exit(slip_exit);
 
 static void sl_outfill(unsigned long sls)
 {
-       struct slip *sl=(struct slip *)sls;
+       struct slip *sl = (struct slip *)sls;
 
        spin_lock(&sl->lock);
 
        if (sl->tty == NULL)
                goto out;
 
-       if(sl->outfill)
-       {
-               if( test_bit(SLF_OUTWAIT, &sl->flags) )
-               {
+       if (sl->outfill) {
+               if (test_bit(SLF_OUTWAIT, &sl->flags)) {
                        /* no packets were transmitted, do outfill */
 #ifdef CONFIG_SLIP_MODE_SLIP6
                        unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END;
@@ -1437,13 +1430,11 @@ static void sl_outfill(unsigned long sls)
                        unsigned char s = END;
 #endif
                        /* put END into tty queue. Is it right ??? */
-                       if (!netif_queue_stopped(sl->dev))
-                       {
+                       if (!netif_queue_stopped(sl->dev)) {
                                /* if device busy no outfill */
                                sl->tty->driver->write(sl->tty, &s, 1);
                        }
-               }
-               else
+               } else
                        set_bit(SLF_OUTWAIT, &sl->flags);
 
                mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ);
@@ -1454,31 +1445,29 @@ out:
 
 static void sl_keepalive(unsigned long sls)
 {
-       struct slip *sl=(struct slip *)sls;
+       struct slip *sl = (struct slip *)sls;
 
        spin_lock(&sl->lock);
 
        if (sl->tty == NULL)
                goto out;
 
-       if( sl->keepalive)
-       {
-               if(test_bit(SLF_KEEPTEST, &sl->flags))
-               {
+       if (sl->keepalive) {
+               if (test_bit(SLF_KEEPTEST, &sl->flags)) {
                        /* keepalive still high :(, we must hangup */
-                       if( sl->outfill ) /* outfill timer must be deleted too */
+                       if (sl->outfill)
+                               /* outfill timer must be deleted too */
                                (void)del_timer(&sl->outfill_timer);
                        printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
-                       tty_hangup(sl->tty); /* this must hangup tty & close slip */
+                       /* this must hangup tty & close slip */
+                       tty_hangup(sl->tty);
                        /* I think we need not something else */
                        goto out;
-               }
-               else
+               } else
                        set_bit(SLF_KEEPTEST, &sl->flags);
 
                mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ);
        }
-
 out:
        spin_unlock(&sl->lock);
 }
index cb2698de51909ecff7efa491a267547874860a3c..de67744c4a2a1f1cf960e80a8cd0ec309db36e58 100644 (file)
@@ -906,7 +906,7 @@ static int __init smc_probe(struct net_device *dev, int ioaddr)
        SMC_SELECT_BANK(1);
        base_address_register = inw( ioaddr + BASE );
        if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) )  {
-               printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)."
+               printk(CARDNAME ": IOADDR %x doesn't match configuration (%x). "
                        "Probably not a SMC chip\n",
                        ioaddr, base_address_register >> 3 & 0x3E0 );
                /* well, the base address register didn't match.  Must not have
index 0a6186d4a48efba7869ce3a95bc6ab07bd439c08..7d5561b8241cb3aa730c3902e7b2b05158b3ee13 100644 (file)
@@ -1596,9 +1596,7 @@ static const struct ethtool_ops ethtool_ops = {
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct netdev_private *np = netdev_priv(dev);
-       void __iomem *ioaddr = np->base;
        int rc;
-       int i;
 
        if (!netif_running(dev))
                return -EINVAL;
@@ -1606,30 +1604,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        spin_lock_irq(&np->lock);
        rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL);
        spin_unlock_irq(&np->lock);
-       switch (cmd) {
-               case SIOCDEVPRIVATE:
-               for (i=0; i<TX_RING_SIZE; i++) {
-                       printk(KERN_DEBUG "%02x %08llx %08x %08x(%02x) %08x %08x\n", i,
-                               (unsigned long long)(np->tx_ring_dma + i*sizeof(*np->tx_ring)),
-                               le32_to_cpu(np->tx_ring[i].next_desc),
-                               le32_to_cpu(np->tx_ring[i].status),
-                               (le32_to_cpu(np->tx_ring[i].status) >> 2)
-                                       & 0xff,
-                               le32_to_cpu(np->tx_ring[i].frag[0].addr),
-                               le32_to_cpu(np->tx_ring[i].frag[0].length));
-               }
-               printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n",
-                       ioread32(np->base + TxListPtr),
-                       netif_queue_stopped(dev));
-               printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n",
-                       np->cur_tx, np->cur_tx % TX_RING_SIZE,
-                       np->dirty_tx, np->dirty_tx % TX_RING_SIZE);
-               printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx);
-               printk(KERN_DEBUG "cur_task=%d\n", np->cur_task);
-               printk(KERN_DEBUG "TxStatus=%04x\n", ioread16(ioaddr + TxStatus));
-                       return 0;
-       }
-
 
        return rc;
 }
index 68872142530b5e5a7807157c0b8e539494e62a1b..97212799c513a8f64b5ab6ecef5f366d886a3aa8 100644 (file)
@@ -758,6 +758,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
 {
        int entry, drops, work_done = 0;
        u32 done;
+       __sum16 csum;
 
        if (netif_msg_rx_status(gp))
                printk(KERN_DEBUG "%s: rx interrupt, done: %d, rx_new: %d\n",
@@ -769,7 +770,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
        for (;;) {
                struct gem_rxd *rxd = &gp->init_block->rxd[entry];
                struct sk_buff *skb;
-               u64 status = cpu_to_le64(rxd->status_word);
+               u64 status = le64_to_cpu(rxd->status_word);
                dma_addr_t dma_addr;
                int len;
 
@@ -811,7 +812,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
                        goto next;
                }
 
-               dma_addr = cpu_to_le64(rxd->buffer);
+               dma_addr = le64_to_cpu(rxd->buffer);
                if (len > RX_COPY_THRESHOLD) {
                        struct sk_buff *new_skb;
 
@@ -853,7 +854,8 @@ static int gem_rx(struct gem *gp, int work_to_do)
                        skb = copy_skb;
                }
 
-               skb->csum = ntohs((status & RXDCTRL_TCPCSUM) ^ 0xffff);
+               csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff);
+               skb->csum = csum_unfold(csum);
                skb->ip_summed = CHECKSUM_COMPLETE;
                skb->protocol = eth_type_trans(skb, gp->dev);
 
@@ -3054,7 +3056,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        netif_carrier_off(dev);
 
        gp->regs = ioremap(gemreg_base, gemreg_len);
-       if (gp->regs == 0UL) {
+       if (!gp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
                err = -EIO;
index 76d760acc9e27e737bb9ed6a2f887e1e42005bc3..f7a02917ce5ec31fb1735c144cb30a48665e7615 100644 (file)
  * DMA mappings for a transmitted packet.
  */
 struct gem_txd {
-       u64     control_word;
-       u64     buffer;
+       __le64  control_word;
+       __le64  buffer;
 };
 
 #define TXDCTRL_BUFSZ  0x0000000000007fffULL   /* Buffer Size          */
@@ -863,8 +863,8 @@ struct gem_txd {
  * by the host driver just as in the TX descriptor case above.
  */
 struct gem_rxd {
-       u64     status_word;
-       u64     buffer;
+       __le64  status_word;
+       __le64  buffer;
 };
 
 #define RXDCTRL_TCPCSUM        0x000000000000ffffULL   /* TCP Pseudo-CSUM      */
index 9cc13dd8a82182cd2718ebf01d9c45fc255e9610..b4e7f30ea4e8c1d9d186ee91b55c41925136bb9d 100644 (file)
@@ -194,21 +194,21 @@ static u32 sbus_hme_read32(void __iomem *reg)
 
 static void sbus_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr)
 {
-       rxd->rx_addr = addr;
+       rxd->rx_addr = (__force hme32)addr;
        wmb();
-       rxd->rx_flags = flags;
+       rxd->rx_flags = (__force hme32)flags;
 }
 
 static void sbus_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr)
 {
-       txd->tx_addr = addr;
+       txd->tx_addr = (__force hme32)addr;
        wmb();
-       txd->tx_flags = flags;
+       txd->tx_flags = (__force hme32)flags;
 }
 
-static u32 sbus_hme_read_desc32(u32 *p)
+static u32 sbus_hme_read_desc32(hme32 *p)
 {
-       return *p;
+       return (__force u32)*p;
 }
 
 static void pci_hme_write32(void __iomem *reg, u32 val)
@@ -223,21 +223,21 @@ static u32 pci_hme_read32(void __iomem *reg)
 
 static void pci_hme_write_rxd(struct happy_meal_rxd *rxd, u32 flags, u32 addr)
 {
-       rxd->rx_addr = cpu_to_le32(addr);
+       rxd->rx_addr = (__force hme32)cpu_to_le32(addr);
        wmb();
-       rxd->rx_flags = cpu_to_le32(flags);
+       rxd->rx_flags = (__force hme32)cpu_to_le32(flags);
 }
 
 static void pci_hme_write_txd(struct happy_meal_txd *txd, u32 flags, u32 addr)
 {
-       txd->tx_addr = cpu_to_le32(addr);
+       txd->tx_addr = (__force hme32)cpu_to_le32(addr);
        wmb();
-       txd->tx_flags = cpu_to_le32(flags);
+       txd->tx_flags = (__force hme32)cpu_to_le32(flags);
 }
 
-static u32 pci_hme_read_desc32(u32 *p)
+static u32 pci_hme_read_desc32(hme32 *p)
 {
-       return cpu_to_le32p(p);
+       return le32_to_cpup((__le32 *)p);
 }
 
 #define hme_write32(__hp, __reg, __val) \
@@ -266,16 +266,16 @@ static u32 pci_hme_read_desc32(u32 *p)
 #define hme_read32(__hp, __reg) \
        sbus_readl(__reg)
 #define hme_write_rxd(__hp, __rxd, __flags, __addr) \
-do {   (__rxd)->rx_addr = (__addr); \
+do {   (__rxd)->rx_addr = (__force hme32)(u32)(__addr); \
        wmb(); \
-       (__rxd)->rx_flags = (__flags); \
+       (__rxd)->rx_flags = (__force hme32)(u32)(__flags); \
 } while(0)
 #define hme_write_txd(__hp, __txd, __flags, __addr) \
-do {   (__txd)->tx_addr = (__addr); \
+do {   (__txd)->tx_addr = (__force hme32)(u32)(__addr); \
        wmb(); \
-       (__txd)->tx_flags = (__flags); \
+       (__txd)->tx_flags = (__force hme32)(u32)(__flags); \
 } while(0)
-#define hme_read_desc32(__hp, __p)     (*(__p))
+#define hme_read_desc32(__hp, __p)     ((__force u32)(hme32)*(__p))
 #define hme_dma_map(__hp, __ptr, __size, __dir) \
        sbus_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
 #define hme_dma_unmap(__hp, __addr, __size, __dir) \
@@ -291,16 +291,19 @@ do {      (__txd)->tx_addr = (__addr); \
 #define hme_read32(__hp, __reg) \
        readl(__reg)
 #define hme_write_rxd(__hp, __rxd, __flags, __addr) \
-do {   (__rxd)->rx_addr = cpu_to_le32(__addr); \
+do {   (__rxd)->rx_addr = (__force hme32)cpu_to_le32(__addr); \
        wmb(); \
-       (__rxd)->rx_flags = cpu_to_le32(__flags); \
+       (__rxd)->rx_flags = (__force hme32)cpu_to_le32(__flags); \
 } while(0)
 #define hme_write_txd(__hp, __txd, __flags, __addr) \
-do {   (__txd)->tx_addr = cpu_to_le32(__addr); \
+do {   (__txd)->tx_addr = (__force hme32)cpu_to_le32(__addr); \
        wmb(); \
-       (__txd)->tx_flags = cpu_to_le32(__flags); \
+       (__txd)->tx_flags = (__force hme32)cpu_to_le32(__flags); \
 } while(0)
-#define hme_read_desc32(__hp, __p)     cpu_to_le32p(__p)
+static inline u32 hme_read_desc32(struct happy_meal *hp, hme32 *p)
+{
+       return le32_to_cpup((__le32 *)p);
+}
 #define hme_dma_map(__hp, __ptr, __size, __dir) \
        pci_map_single((__hp)->happy_dev, (__ptr), (__size), (__dir))
 #define hme_dma_unmap(__hp, __addr, __size, __dir) \
@@ -2075,7 +2078,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
                }
 
                /* This card is _fucking_ hot... */
-               skb->csum = ntohs(csum ^ 0xffff);
+               skb->csum = csum_unfold(~(__force __sum16)htons(csum));
                skb->ip_summed = CHECKSUM_COMPLETE;
 
                RXD(("len=%d csum=%4x]", len, csum));
@@ -3057,7 +3060,7 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
                goto err_out_clear_quattro;
        }
 
-       if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == 0) {
+       if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == NULL) {
                printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
                goto err_out_free_res;
        }
index 90f446db9ba21cac02d0f2fec0c5bf8ad8c3e650..4da5539fac7b3032f4b1f911a06705cfd2ca0132 100644 (file)
  * Always write the address first before setting the ownership
  * bits to avoid races with the hardware scanning the ring.
  */
+typedef u32 __bitwise__ hme32;
+
 struct happy_meal_rxd {
-       u32 rx_flags;
-       u32 rx_addr;
+       hme32 rx_flags;
+       hme32 rx_addr;
 };
 
 #define RXFLAG_OWN         0x80000000 /* 1 = hardware, 0 = software */
@@ -313,8 +315,8 @@ struct happy_meal_rxd {
 #define RXFLAG_CSUM        0x0000ffff /* HW computed checksum       */
 
 struct happy_meal_txd {
-       u32 tx_flags;
-       u32 tx_addr;
+       hme32 tx_flags;
+       hme32 tx_addr;
 };
 
 #define TXFLAG_OWN         0x80000000 /* 1 = hardware, 0 = software */
@@ -400,7 +402,7 @@ struct happy_meal {
        struct hmeal_init_block  *happy_block;  /* RX and TX descriptors (CPU addr)  */
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
-       u32 (*read_desc32)(u32 *);
+       u32 (*read_desc32)(hme32 *);
        void (*write_txd)(struct happy_meal_txd *, u32, u32);
        void (*write_rxd)(struct happy_meal_rxd *, u32, u32);
        u32 (*dma_map)(void *, void *, long, int);
index ff1028a597df1b34860d53cffcf33c02e8d7c845..4a0035f7a842471df9e39e0dfd8bef3d896b24cc 100644 (file)
@@ -1149,6 +1149,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
        struct vnet *vp;
        const u64 *rmac;
        int len, i, err, switch_port;
+       DECLARE_MAC_BUF(mac);
 
        print_version();
 
@@ -1213,12 +1214,9 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev,
 
        dev_set_drvdata(&vdev->dev, port);
 
-       printk(KERN_INFO "%s: PORT ( remote-mac ", vp->dev->name);
-       for (i = 0; i < 6; i++)
-               printk("%2.2x%c", port->raddr[i], i == 5 ? ' ' : ':');
-       if (switch_port)
-               printk("switch-port ");
-       printk(")\n");
+       printk(KERN_INFO "%s: PORT ( remote-mac %s%s )\n",
+              vp->dev->name, print_mac(mac, port->raddr),
+              switch_port ? " switch-port" : "");
 
        vio_port_up(&port->vio);
 
index 21230c97b2a0fc7513af353faf8a42c5781602e8..17585e5eed5379c2299f85f92a3956768850161e 100644 (file)
@@ -621,7 +621,7 @@ err:
 static void __init bdx_firmware_endianess(void)
 {
        int i;
-       for (i = 0; i < sizeof(s_firmLoad) / sizeof(u32); i++)
+       for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++)
                s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
 }
 
@@ -2174,8 +2174,7 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
        strlcat(drvinfo->bus_info, pci_name(priv->pdev),
                sizeof(drvinfo->bus_info));
 
-       drvinfo->n_stats = ((priv->stats_flag) ?
-                           (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) : 0);
+       drvinfo->n_stats = ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0);
        drvinfo->testinfo_len = 0;
        drvinfo->regdump_len = 0;
        drvinfo->eedump_len = 0;
@@ -2375,10 +2374,9 @@ static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 static int bdx_get_stats_count(struct net_device *netdev)
 {
        struct bdx_priv *priv = netdev->priv;
-       BDX_ASSERT(sizeof(bdx_stat_names) / ETH_GSTRING_LEN
+       BDX_ASSERT(ARRAY_SIZE(bdx_stat_names)
                   != sizeof(struct bdx_stats) / sizeof(u64));
-       return ((priv->stats_flag) ? (sizeof(bdx_stat_names) / ETH_GSTRING_LEN)
-               : 0);
+       return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0);
 }
 
 /*
index 22eb7c8c1a256fc4a48a4c29b27f946b01fc6386..db606b603884530aa0f433c56a4d080f0e0c6714 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.86"
-#define DRV_MODULE_RELDATE     "November 9, 2007"
+#define DRV_MODULE_VERSION     "3.87"
+#define DRV_MODULE_RELDATE     "December 20, 2007"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -1602,68 +1602,113 @@ static void tg3_link_report(struct tg3 *tp)
                       (tp->link_config.active_duplex == DUPLEX_FULL ?
                        "full" : "half"));
 
-               printk(KERN_INFO PFX "%s: Flow control is %s for TX and "
-                      "%s for RX.\n",
+               printk(KERN_INFO PFX
+                      "%s: Flow control is %s for TX and %s for RX.\n",
                       tp->dev->name,
-                      (tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "on" : "off",
-                      (tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "on" : "off");
+                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
+                      "on" : "off",
+                      (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
+                      "on" : "off");
        }
 }
 
-static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
+static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
 {
-       u32 new_tg3_flags = 0;
-       u32 old_rx_mode = tp->rx_mode;
-       u32 old_tx_mode = tp->tx_mode;
+       u16 miireg;
 
-       if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) {
+       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+               miireg = ADVERTISE_PAUSE_CAP;
+       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+               miireg = ADVERTISE_PAUSE_ASYM;
+       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+               miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+       else
+               miireg = 0;
 
-               /* Convert 1000BaseX flow control bits to 1000BaseT
-                * bits before resolving flow control.
-                */
-               if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
-                       local_adv &= ~(ADVERTISE_PAUSE_CAP |
-                                      ADVERTISE_PAUSE_ASYM);
-                       remote_adv &= ~(LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
-
-                       if (local_adv & ADVERTISE_1000XPAUSE)
-                               local_adv |= ADVERTISE_PAUSE_CAP;
-                       if (local_adv & ADVERTISE_1000XPSE_ASYM)
-                               local_adv |= ADVERTISE_PAUSE_ASYM;
-                       if (remote_adv & LPA_1000XPAUSE)
-                               remote_adv |= LPA_PAUSE_CAP;
-                       if (remote_adv & LPA_1000XPAUSE_ASYM)
-                               remote_adv |= LPA_PAUSE_ASYM;
-               }
-
-               if (local_adv & ADVERTISE_PAUSE_CAP) {
-                       if (local_adv & ADVERTISE_PAUSE_ASYM) {
-                               if (remote_adv & LPA_PAUSE_CAP)
-                                       new_tg3_flags |=
-                                               (TG3_FLAG_RX_PAUSE |
-                                               TG3_FLAG_TX_PAUSE);
-                               else if (remote_adv & LPA_PAUSE_ASYM)
-                                       new_tg3_flags |=
-                                               (TG3_FLAG_RX_PAUSE);
-                       } else {
-                               if (remote_adv & LPA_PAUSE_CAP)
-                                       new_tg3_flags |=
-                                               (TG3_FLAG_RX_PAUSE |
-                                               TG3_FLAG_TX_PAUSE);
-                       }
-               } else if (local_adv & ADVERTISE_PAUSE_ASYM) {
-                       if ((remote_adv & LPA_PAUSE_CAP) &&
-                       (remote_adv & LPA_PAUSE_ASYM))
-                               new_tg3_flags |= TG3_FLAG_TX_PAUSE;
+       return miireg;
+}
+
+static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
+{
+       u16 miireg;
+
+       if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
+               miireg = ADVERTISE_1000XPAUSE;
+       else if (flow_ctrl & TG3_FLOW_CTRL_TX)
+               miireg = ADVERTISE_1000XPSE_ASYM;
+       else if (flow_ctrl & TG3_FLOW_CTRL_RX)
+               miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
+       else
+               miireg = 0;
+
+       return miireg;
+}
+
+static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
+{
+       u8 cap = 0;
+
+       if (lcladv & ADVERTISE_PAUSE_CAP) {
+               if (lcladv & ADVERTISE_PAUSE_ASYM) {
+                       if (rmtadv & LPA_PAUSE_CAP)
+                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                       else if (rmtadv & LPA_PAUSE_ASYM)
+                               cap = TG3_FLOW_CTRL_RX;
+               } else {
+                       if (rmtadv & LPA_PAUSE_CAP)
+                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+               }
+       } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
+               if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
+                       cap = TG3_FLOW_CTRL_TX;
+       }
+
+       return cap;
+}
+
+static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
+{
+       u8 cap = 0;
+
+       if (lcladv & ADVERTISE_1000XPAUSE) {
+               if (lcladv & ADVERTISE_1000XPSE_ASYM) {
+                       if (rmtadv & LPA_1000XPAUSE)
+                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
+                       else if (rmtadv & LPA_1000XPAUSE_ASYM)
+                               cap = TG3_FLOW_CTRL_RX;
+               } else {
+                       if (rmtadv & LPA_1000XPAUSE)
+                               cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
                }
+       } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
+               if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
+                       cap = TG3_FLOW_CTRL_TX;
+       }
 
-               tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
-               tp->tg3_flags |= new_tg3_flags;
+       return cap;
+}
+
+static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
+{
+       u8 new_tg3_flags = 0;
+       u32 old_rx_mode = tp->rx_mode;
+       u32 old_tx_mode = tp->tx_mode;
+
+       if (tp->link_config.autoneg == AUTONEG_ENABLE &&
+           (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
+               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
+                       new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv,
+                                                                  remote_adv);
+               else
+                       new_tg3_flags = tg3_resolve_flowctrl_1000T(local_adv,
+                                                                  remote_adv);
        } else {
-               new_tg3_flags = tp->tg3_flags;
+               new_tg3_flags = tp->link_config.flowctrl;
        }
 
-       if (new_tg3_flags & TG3_FLAG_RX_PAUSE)
+       tp->link_config.active_flowctrl = new_tg3_flags;
+
+       if (new_tg3_flags & TG3_FLOW_CTRL_RX)
                tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
@@ -1672,7 +1717,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv
                tw32_f(MAC_RX_MODE, tp->rx_mode);
        }
 
-       if (new_tg3_flags & TG3_FLAG_TX_PAUSE)
+       if (new_tg3_flags & TG3_FLOW_CTRL_TX)
                tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
        else
                tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
@@ -1752,7 +1797,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                                ~(ADVERTISED_1000baseT_Half |
                                  ADVERTISED_1000baseT_Full);
 
-               new_adv = (ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+               new_adv = ADVERTISE_CSMA;
                if (tp->link_config.advertising & ADVERTISED_10baseT_Half)
                        new_adv |= ADVERTISE_10HALF;
                if (tp->link_config.advertising & ADVERTISED_10baseT_Full)
@@ -1761,6 +1806,9 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                        new_adv |= ADVERTISE_100HALF;
                if (tp->link_config.advertising & ADVERTISED_100baseT_Full)
                        new_adv |= ADVERTISE_100FULL;
+
+               new_adv |= tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
+
                tg3_writephy(tp, MII_ADVERTISE, new_adv);
 
                if (tp->link_config.advertising &
@@ -1780,9 +1828,11 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                        tg3_writephy(tp, MII_TG3_CTRL, 0);
                }
        } else {
+               new_adv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
+               new_adv |= ADVERTISE_CSMA;
+
                /* Asking for a specific link mode. */
                if (tp->link_config.speed == SPEED_1000) {
-                       new_adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
                        tg3_writephy(tp, MII_ADVERTISE, new_adv);
 
                        if (tp->link_config.duplex == DUPLEX_FULL)
@@ -1793,11 +1843,7 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                            tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
                                new_adv |= (MII_TG3_CTRL_AS_MASTER |
                                            MII_TG3_CTRL_ENABLE_AS_MASTER);
-                       tg3_writephy(tp, MII_TG3_CTRL, new_adv);
                } else {
-                       tg3_writephy(tp, MII_TG3_CTRL, 0);
-
-                       new_adv = ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP;
                        if (tp->link_config.speed == SPEED_100) {
                                if (tp->link_config.duplex == DUPLEX_FULL)
                                        new_adv |= ADVERTISE_100FULL;
@@ -1810,7 +1856,11 @@ static void tg3_phy_copper_begin(struct tg3 *tp)
                                        new_adv |= ADVERTISE_10HALF;
                        }
                        tg3_writephy(tp, MII_ADVERTISE, new_adv);
+
+                       new_adv = 0;
                }
+
+               tg3_writephy(tp, MII_TG3_CTRL, new_adv);
        }
 
        if (tp->link_config.autoneg == AUTONEG_DISABLE &&
@@ -1926,10 +1976,44 @@ static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask)
        return 1;
 }
 
+static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv)
+{
+       u32 curadv, reqadv;
+
+       if (tg3_readphy(tp, MII_ADVERTISE, lcladv))
+               return 1;
+
+       curadv = *lcladv & (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+       reqadv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
+
+       if (tp->link_config.active_duplex == DUPLEX_FULL) {
+               if (curadv != reqadv)
+                       return 0;
+
+               if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)
+                       tg3_readphy(tp, MII_LPA, rmtadv);
+       } else {
+               /* Reprogram the advertisement register, even if it
+                * does not affect the current link.  If the link
+                * gets renegotiated in the future, we can save an
+                * additional renegotiation cycle by advertising
+                * it correctly in the first place.
+                */
+               if (curadv != reqadv) {
+                       *lcladv &= ~(ADVERTISE_PAUSE_CAP |
+                                    ADVERTISE_PAUSE_ASYM);
+                       tg3_writephy(tp, MII_ADVERTISE, *lcladv | reqadv);
+               }
+       }
+
+       return 1;
+}
+
 static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
 {
        int current_link_up;
        u32 bmsr, dummy;
+       u32 lcl_adv, rmt_adv;
        u16 current_speed;
        u8 current_duplex;
        int i, err;
@@ -2072,56 +2156,35 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset)
                        udelay(10);
                }
 
-               if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-                       if (bmcr & BMCR_ANENABLE) {
-                               current_link_up = 1;
+               lcl_adv = 0;
+               rmt_adv = 0;
 
-                               /* Force autoneg restart if we are exiting
-                                * low power mode.
-                                */
-                               if (!tg3_copper_is_advertising_all(tp,
-                                               tp->link_config.advertising))
-                                       current_link_up = 0;
-                       } else {
-                               current_link_up = 0;
+               tp->link_config.active_speed = current_speed;
+               tp->link_config.active_duplex = current_duplex;
+
+               if (tp->link_config.autoneg == AUTONEG_ENABLE) {
+                       if ((bmcr & BMCR_ANENABLE) &&
+                           tg3_copper_is_advertising_all(tp,
+                                               tp->link_config.advertising)) {
+                               if (tg3_adv_1000T_flowctrl_ok(tp, &lcl_adv,
+                                                                 &rmt_adv))
+                                       current_link_up = 1;
                        }
                } else {
                        if (!(bmcr & BMCR_ANENABLE) &&
                            tp->link_config.speed == current_speed &&
-                           tp->link_config.duplex == current_duplex) {
+                           tp->link_config.duplex == current_duplex &&
+                           tp->link_config.flowctrl ==
+                           tp->link_config.active_flowctrl) {
                                current_link_up = 1;
-                       } else {
-                               current_link_up = 0;
                        }
                }
 
-               tp->link_config.active_speed = current_speed;
-               tp->link_config.active_duplex = current_duplex;
+               if (current_link_up == 1 &&
+                   tp->link_config.active_duplex == DUPLEX_FULL)
+                       tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
        }
 
-       if (current_link_up == 1 &&
-           (tp->link_config.active_duplex == DUPLEX_FULL) &&
-           (tp->link_config.autoneg == AUTONEG_ENABLE)) {
-               u32 local_adv, remote_adv;
-
-               if (tg3_readphy(tp, MII_ADVERTISE, &local_adv))
-                       local_adv = 0;
-               local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-
-               if (tg3_readphy(tp, MII_LPA, &remote_adv))
-                       remote_adv = 0;
-
-               remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
-
-               /* If we are not advertising full pause capability,
-                * something is wrong.  Bring the link down and reconfigure.
-                */
-               if (local_adv != ADVERTISE_PAUSE_CAP) {
-                       current_link_up = 0;
-               } else {
-                       tg3_setup_flow_control(tp, local_adv, remote_adv);
-               }
-       }
 relink:
        if (current_link_up == 0 || tp->link_config.phy_is_low_power) {
                u32 tmp;
@@ -2270,6 +2333,7 @@ struct tg3_fiber_aneginfo {
 static int tg3_fiber_aneg_smachine(struct tg3 *tp,
                                   struct tg3_fiber_aneginfo *ap)
 {
+       u16 flowctrl;
        unsigned long delta;
        u32 rx_cfg_reg;
        int ret;
@@ -2369,7 +2433,12 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
 
        case ANEG_STATE_ABILITY_DETECT_INIT:
                ap->flags &= ~(MR_TOGGLE_TX);
-               ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1);
+               ap->txconfig = ANEG_CFG_FD;
+               flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
+               if (flowctrl & ADVERTISE_1000XPAUSE)
+                       ap->txconfig |= ANEG_CFG_PS1;
+               if (flowctrl & ADVERTISE_1000XPSE_ASYM)
+                       ap->txconfig |= ANEG_CFG_PS2;
                tw32(MAC_TX_AUTO_NEG, ap->txconfig);
                tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
                tw32_f(MAC_MODE, tp->mac_mode);
@@ -2515,7 +2584,7 @@ static int tg3_fiber_aneg_smachine(struct tg3 *tp,
        return ret;
 }
 
-static int fiber_autoneg(struct tg3 *tp, u32 *flags)
+static int fiber_autoneg(struct tg3 *tp, u32 *txflags, u32 *rxflags)
 {
        int res = 0;
        struct tg3_fiber_aneginfo aninfo;
@@ -2549,7 +2618,8 @@ static int fiber_autoneg(struct tg3 *tp, u32 *flags)
        tw32_f(MAC_MODE, tp->mac_mode);
        udelay(40);
 
-       *flags = aninfo.flags;
+       *txflags = aninfo.txconfig;
+       *rxflags = aninfo.flags;
 
        if (status == ANEG_DONE &&
            (aninfo.flags & (MR_AN_COMPLETE | MR_LINK_OK |
@@ -2611,6 +2681,7 @@ static void tg3_init_bcm8002(struct tg3 *tp)
 
 static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
 {
+       u16 flowctrl;
        u32 sg_dig_ctrl, sg_dig_status;
        u32 serdes_cfg, expected_sg_dig_ctrl;
        int workaround, port_a;
@@ -2636,7 +2707,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
        sg_dig_ctrl = tr32(SG_DIG_CTRL);
 
        if (tp->link_config.autoneg != AUTONEG_ENABLE) {
-               if (sg_dig_ctrl & (1 << 31)) {
+               if (sg_dig_ctrl & SG_DIG_USING_HW_AUTONEG) {
                        if (workaround) {
                                u32 val = serdes_cfg;
 
@@ -2646,7 +2717,8 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
                                        val |= 0x4010000;
                                tw32_f(MAC_SERDES_CFG, val);
                        }
-                       tw32_f(SG_DIG_CTRL, 0x01388400);
+
+                       tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
                }
                if (mac_status & MAC_STATUS_PCS_SYNCED) {
                        tg3_setup_flow_control(tp, 0, 0);
@@ -2656,13 +2728,13 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
        }
 
        /* Want auto-negotiation.  */
-       expected_sg_dig_ctrl = 0x81388400;
+       expected_sg_dig_ctrl = SG_DIG_USING_HW_AUTONEG | SG_DIG_COMMON_SETUP;
 
-       /* Pause capability */
-       expected_sg_dig_ctrl |= (1 << 11);
-
-       /* Asymettric pause */
-       expected_sg_dig_ctrl |= (1 << 12);
+       flowctrl = tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
+       if (flowctrl & ADVERTISE_1000XPAUSE)
+               expected_sg_dig_ctrl |= SG_DIG_PAUSE_CAP;
+       if (flowctrl & ADVERTISE_1000XPSE_ASYM)
+               expected_sg_dig_ctrl |= SG_DIG_ASYM_PAUSE;
 
        if (sg_dig_ctrl != expected_sg_dig_ctrl) {
                if ((tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
@@ -2677,7 +2749,7 @@ static int tg3_setup_fiber_hw_autoneg(struct tg3 *tp, u32 mac_status)
 restart_autoneg:
                if (workaround)
                        tw32_f(MAC_SERDES_CFG, serdes_cfg | 0xc011000);
-               tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | (1 << 30));
+               tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl | SG_DIG_SOFT_RESET);
                udelay(5);
                tw32_f(SG_DIG_CTRL, expected_sg_dig_ctrl);
 
@@ -2688,22 +2760,25 @@ restart_autoneg:
                sg_dig_status = tr32(SG_DIG_STATUS);
                mac_status = tr32(MAC_STATUS);
 
-               if ((sg_dig_status & (1 << 1)) &&
+               if ((sg_dig_status & SG_DIG_AUTONEG_COMPLETE) &&
                    (mac_status & MAC_STATUS_PCS_SYNCED)) {
-                       u32 local_adv, remote_adv;
+                       u32 local_adv = 0, remote_adv = 0;
+
+                       if (sg_dig_ctrl & SG_DIG_PAUSE_CAP)
+                               local_adv |= ADVERTISE_1000XPAUSE;
+                       if (sg_dig_ctrl & SG_DIG_ASYM_PAUSE)
+                               local_adv |= ADVERTISE_1000XPSE_ASYM;
 
-                       local_adv = ADVERTISE_PAUSE_CAP;
-                       remote_adv = 0;
-                       if (sg_dig_status & (1 << 19))
-                               remote_adv |= LPA_PAUSE_CAP;
-                       if (sg_dig_status & (1 << 20))
-                               remote_adv |= LPA_PAUSE_ASYM;
+                       if (sg_dig_status & SG_DIG_PARTNER_PAUSE_CAPABLE)
+                               remote_adv |= LPA_1000XPAUSE;
+                       if (sg_dig_status & SG_DIG_PARTNER_ASYM_PAUSE)
+                               remote_adv |= LPA_1000XPAUSE_ASYM;
 
                        tg3_setup_flow_control(tp, local_adv, remote_adv);
                        current_link_up = 1;
                        tp->serdes_counter = 0;
                        tp->tg3_flags2 &= ~TG3_FLG2_PARALLEL_DETECT;
-               } else if (!(sg_dig_status & (1 << 1))) {
+               } else if (!(sg_dig_status & SG_DIG_AUTONEG_COMPLETE)) {
                        if (tp->serdes_counter)
                                tp->serdes_counter--;
                        else {
@@ -2718,7 +2793,7 @@ restart_autoneg:
                                        tw32_f(MAC_SERDES_CFG, val);
                                }
 
-                               tw32_f(SG_DIG_CTRL, 0x01388400);
+                               tw32_f(SG_DIG_CTRL, SG_DIG_COMMON_SETUP);
                                udelay(40);
 
                                /* Link parallel detection - link is up */
@@ -2754,18 +2829,21 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
                goto out;
 
        if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-               u32 flags;
+               u32 txflags, rxflags;
                int i;
 
-               if (fiber_autoneg(tp, &flags)) {
-                       u32 local_adv, remote_adv;
+               if (fiber_autoneg(tp, &txflags, &rxflags)) {
+                       u32 local_adv = 0, remote_adv = 0;
+
+                       if (txflags & ANEG_CFG_PS1)
+                               local_adv |= ADVERTISE_1000XPAUSE;
+                       if (txflags & ANEG_CFG_PS2)
+                               local_adv |= ADVERTISE_1000XPSE_ASYM;
 
-                       local_adv = ADVERTISE_PAUSE_CAP;
-                       remote_adv = 0;
-                       if (flags & MR_LP_ADV_SYM_PAUSE)
-                               remote_adv |= LPA_PAUSE_CAP;
-                       if (flags & MR_LP_ADV_ASYM_PAUSE)
-                               remote_adv |= LPA_PAUSE_ASYM;
+                       if (rxflags & MR_LP_ADV_SYM_PAUSE)
+                               remote_adv |= LPA_1000XPAUSE;
+                       if (rxflags & MR_LP_ADV_ASYM_PAUSE)
+                               remote_adv |= LPA_1000XPAUSE_ASYM;
 
                        tg3_setup_flow_control(tp, local_adv, remote_adv);
 
@@ -2789,6 +2867,8 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status)
                    !(mac_status & MAC_STATUS_RCVD_CFG))
                        current_link_up = 1;
        } else {
+               tg3_setup_flow_control(tp, 0, 0);
+
                /* Forcing 1000FD link up. */
                current_link_up = 1;
 
@@ -2812,9 +2892,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
        int current_link_up;
        int i;
 
-       orig_pause_cfg =
-               (tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
-                                 TG3_FLAG_TX_PAUSE));
+       orig_pause_cfg = tp->link_config.active_flowctrl;
        orig_active_speed = tp->link_config.active_speed;
        orig_active_duplex = tp->link_config.active_duplex;
 
@@ -2903,9 +2981,7 @@ static int tg3_setup_fiber_phy(struct tg3 *tp, int force_reset)
                        netif_carrier_off(tp->dev);
                tg3_link_report(tp);
        } else {
-               u32 now_pause_cfg =
-                       tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
-                                        TG3_FLAG_TX_PAUSE);
+               u32 now_pause_cfg = tp->link_config.active_flowctrl;
                if (orig_pause_cfg != now_pause_cfg ||
                    orig_active_speed != tp->link_config.active_speed ||
                    orig_active_duplex != tp->link_config.active_duplex)
@@ -2921,6 +2997,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
        u32 bmsr, bmcr;
        u16 current_speed;
        u8 current_duplex;
+       u32 local_adv, remote_adv;
 
        tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
        tw32_f(MAC_MODE, tp->mac_mode);
@@ -2954,7 +3031,8 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
        err |= tg3_readphy(tp, MII_BMCR, &bmcr);
 
        if ((tp->link_config.autoneg == AUTONEG_ENABLE) && !force_reset &&
-           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT)) {
+           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT) &&
+            tp->link_config.flowctrl == tp->link_config.active_flowctrl) {
                /* do nothing, just check for link up at the end */
        } else if (tp->link_config.autoneg == AUTONEG_ENABLE) {
                u32 adv, new_adv;
@@ -2965,8 +3043,7 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                                  ADVERTISE_1000XPSE_ASYM |
                                  ADVERTISE_SLCT);
 
-               /* Always advertise symmetric PAUSE just like copper */
-               new_adv |= ADVERTISE_1000XPAUSE;
+               new_adv |= tg3_advert_flowctrl_1000X(tp->link_config.flowctrl);
 
                if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
                        new_adv |= ADVERTISE_1000XHALF;
@@ -3037,8 +3114,11 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                else
                        current_duplex = DUPLEX_HALF;
 
+               local_adv = 0;
+               remote_adv = 0;
+
                if (bmcr & BMCR_ANENABLE) {
-                       u32 local_adv, remote_adv, common;
+                       u32 common;
 
                        err |= tg3_readphy(tp, MII_ADVERTISE, &local_adv);
                        err |= tg3_readphy(tp, MII_LPA, &remote_adv);
@@ -3049,15 +3129,15 @@ static int tg3_setup_fiber_mii_phy(struct tg3 *tp, int force_reset)
                                        current_duplex = DUPLEX_FULL;
                                else
                                        current_duplex = DUPLEX_HALF;
-
-                               tg3_setup_flow_control(tp, local_adv,
-                                                      remote_adv);
                        }
                        else
                                current_link_up = 0;
                }
        }
 
+       if (current_link_up == 1 && current_duplex == DUPLEX_FULL)
+               tg3_setup_flow_control(tp, local_adv, remote_adv);
+
        tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
        if (tp->link_config.active_duplex == DUPLEX_HALF)
                tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
@@ -8569,8 +8649,16 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
        struct tg3 *tp = netdev_priv(dev);
 
        epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
-       epause->rx_pause = (tp->tg3_flags & TG3_FLAG_RX_PAUSE) != 0;
-       epause->tx_pause = (tp->tg3_flags & TG3_FLAG_TX_PAUSE) != 0;
+
+       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX)
+               epause->rx_pause = 1;
+       else
+               epause->rx_pause = 0;
+
+       if (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX)
+               epause->tx_pause = 1;
+       else
+               epause->tx_pause = 0;
 }
 
 static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
@@ -8590,13 +8678,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
        else
                tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
        if (epause->rx_pause)
-               tp->tg3_flags |= TG3_FLAG_RX_PAUSE;
+               tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
        else
-               tp->tg3_flags &= ~TG3_FLAG_RX_PAUSE;
+               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
        if (epause->tx_pause)
-               tp->tg3_flags |= TG3_FLAG_TX_PAUSE;
+               tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
        else
-               tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE;
+               tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
 
        if (netif_running(dev)) {
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -12361,9 +12449,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        unsigned long tg3reg_base, tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
-       int i, err, pm_cap;
+       int err, pm_cap;
        char str[40];
        u64 dma_mask, persist_dma_mask;
+       DECLARE_MAC_BUF(mac);
 
        if (tg3_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -12586,7 +12675,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                tg3reg_len = pci_resource_len(pdev, 2);
 
                tp->aperegs = ioremap_nocache(tg3reg_base, tg3reg_len);
-               if (tp->aperegs == 0UL) {
+               if (!tp->aperegs) {
                        printk(KERN_ERR PFX "Cannot map APE registers, "
                               "aborting.\n");
                        err = -ENOMEM;
@@ -12630,6 +12719,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        /* flow control autonegotiation is default behavior */
        tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+       tp->link_config.flowctrl = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 
        tg3_init_coal(tp);
 
@@ -12642,7 +12732,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_apeunmap;
        }
 
-       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ",
+       printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] "
+              "(%s) %s Ethernet %s\n",
               dev->name,
               tp->board_part_number,
               tp->pci_chip_rev_id,
@@ -12650,11 +12741,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               tg3_bus_string(tp, str),
               ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" :
                ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" :
-                "10/100/1000Base-T")));
-
-       for (i = 0; i < 6; i++)
-               printk("%2.2x%c", dev->dev_addr[i],
-                      i == 5 ? '\n' : ':');
+                "10/100/1000Base-T")),
+              print_mac(mac, dev->dev_addr));
 
        printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] "
               "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n",
index da18fb2207126810a8b1f74faf1e26cb36393d55..3938eb35ce8cd479507131b3673ffa5e77dd8d96 100644 (file)
 #define  SG_DIG_FIBER_MODE              0x00008000
 #define  SG_DIG_REMOTE_FAULT_MASK       0x00006000
 #define  SG_DIG_PAUSE_MASK              0x00001800
+#define  SG_DIG_PAUSE_CAP               0x00000800
+#define  SG_DIG_ASYM_PAUSE              0x00001000
 #define  SG_DIG_GBIC_ENABLE             0x00000400
 #define  SG_DIG_CHECK_END_ENABLE        0x00000200
 #define  SG_DIG_SGMII_AUTONEG_TIMER     0x00000100
 #define  SG_DIG_AUTONEG_LOW_ENABLE      0x00000004
 #define  SG_DIG_REMOTE_LOOPBACK                 0x00000002
 #define  SG_DIG_LOOPBACK                0x00000001
+#define  SG_DIG_COMMON_SETUP (SG_DIG_CRC16_CLEAR_N | \
+                             SG_DIG_LOCAL_DUPLEX_STATUS | \
+                             SG_DIG_LOCAL_LINK_STATUS | \
+                             (0x2 << SG_DIG_SPEED_STATUS_SHIFT) | \
+                             SG_DIG_FIBER_MODE | SG_DIG_GBIC_ENABLE)
 #define SG_DIG_STATUS                  0x000005b4
 #define  SG_DIG_CRC16_BUS_MASK          0xffff0000
 #define  SG_DIG_PARTNER_FAULT_MASK      0x00600000 /* If !MRADV_CRC16_SELECT */
@@ -2103,13 +2110,18 @@ struct tg3_link_config {
        u16                             speed;
        u8                              duplex;
        u8                              autoneg;
+       u8                              flowctrl;
+#define TG3_FLOW_CTRL_TX               0x01
+#define TG3_FLOW_CTRL_RX               0x02
 
        /* Describes what we actually have. */
-       u16                             active_speed;
+       u8                              active_flowctrl;
+
        u8                              active_duplex;
 #define SPEED_INVALID          0xffff
 #define DUPLEX_INVALID         0xff
 #define AUTONEG_INVALID                0xff
+       u16                             active_speed;
 
        /* When we go in and out of low power mode we need
         * to swap with this state.
@@ -2337,8 +2349,6 @@ struct tg3 {
 #define TG3_FLAG_EEPROM_WRITE_PROT     0x00001000
 #define TG3_FLAG_NVRAM                 0x00002000
 #define TG3_FLAG_NVRAM_BUFFERED                0x00004000
-#define TG3_FLAG_RX_PAUSE              0x00008000
-#define TG3_FLAG_TX_PAUSE              0x00010000
 #define TG3_FLAG_PCIX_MODE             0x00020000
 #define TG3_FLAG_PCI_HIGH_SPEED                0x00040000
 #define TG3_FLAG_PCI_32BIT             0x00080000
index 74c1f0f189f54f227f760661e3798c9e8cd5b137..e7b4adc5c4e79d3ed3faee86b992669b895c56e3 100644 (file)
@@ -357,7 +357,7 @@ static int __devinit olympic_init(struct net_device *dev)
 
        if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { 
                t=jiffies;
-               while (!readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE) { 
+               while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) {
                        schedule() ; 
                        if(time_after(jiffies, t + 2*HZ)) {
                                printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; 
@@ -671,7 +671,7 @@ static int olympic_open(struct net_device *dev)
 
        writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */
        for(i=0;i<OLYMPIC_TX_RING_SIZE;i++) 
-               olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef;
+               olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef);
 
        olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
        olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
@@ -897,7 +897,7 @@ static void olympic_freemem(struct net_device *dev)
                        dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
                        olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
                }
-               if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
+               if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) {
                        pci_unmap_single(olympic_priv->pdev, 
                        le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
                        olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
@@ -983,7 +983,7 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id)
                                        le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), 
                                        olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
                                dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
-                               olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef;
+                               olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef);
                                olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
                        }
                        netif_wake_queue(dev);
@@ -1432,7 +1432,7 @@ static void olympic_arb_cmd(struct net_device *dev)
                        buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length))); 
                        memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;
                        next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next)); 
-               } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + ntohs(next_ptr)));
+               } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr)));
 
                mac_frame->protocol = tr_type_trans(mac_frame, dev);
 
index 2fc59c9974681de7845613e633ba6d9a8f2dc552..c91956310fb2d358230edb3069f3ae81cafb66cf 100644 (file)
 /* xxxx These structures are all little endian in hardware. */
 
 struct olympic_tx_desc {
-       u32 buffer;
-       u32 status_length;
+       __le32 buffer;
+       __le32 status_length;
 };
 
 struct olympic_tx_status {
-       u32 status;
+       __le32 status;
 };
 
 struct olympic_rx_desc {
-       u32 buffer;
-       u32 res_length; 
+       __le32 buffer;
+       __le32 res_length; 
 };
 
 struct olympic_rx_status {
-       u32 fragmentcnt_framelen;
-       u32 status_buffercnt;
+       __le32 fragmentcnt_framelen;
+       __le32 status_buffercnt;
 };
 /* xxxx END These structures are all little endian in hardware. */
 /* xxxx There may be more, but I'm pretty sure about these */
 
 struct mac_receive_buffer {
-       u16 next ; 
+       __le16 next ; 
        u8 padding ; 
        u8 frame_status ;
-       u16 buffer_length ; 
+       __le16 buffer_length ; 
        u8 frame_data ; 
 };
 
index 93da3a36cde8915922579b2ba26f91a571361388..8909050b8ea7e57cda3efce74c181082bf09d3d9 100644 (file)
@@ -2310,7 +2310,7 @@ static irqreturn_t smctr_interrupt(int irq, void *dev_id)
                                                 && (tp->acb_head->subcmd
                                                 == RW_TRC_STATUS_BLOCK))
                                         {
-                                                if(tp->ptr_bcn_type != 0)
+                                                if(tp->ptr_bcn_type)
                                                 {
                                                         *(tp->ptr_bcn_type)
                                                                 = (__u32)((SBlock *)tp->misc_command_data)->BCN_Type;
@@ -2980,7 +2980,7 @@ static int smctr_load_firmware(struct net_device *dev)
                 return (UCODE_PRESENT);
 
         /* Verify the firmware exists and is there in the right amount. */
-        if((tp->ptr_ucode == 0L)
+        if (!tp->ptr_ucode
                 || (*(tp->ptr_ucode + UCODE_VERSION_OFFSET) < UCODE_VERSION))
         {
                 return (UCODE_NOT_PRESENT);
index 6e8b18a3b3ccbd366f7608632627a6f1eace9b57..6c6fc325c8f96856a7a511a17b163bce3b54d5ab 100644 (file)
@@ -4168,7 +4168,7 @@ de4x5_bad_srom(struct de4x5_private *lp)
 {
     int i, status = 0;
 
-    for (i=0; i<sizeof(enet_det)/ETH_ALEN; i++) {
+    for (i = 0; i < ARRAY_SIZE(enet_det); i++) {
        if (!de4x5_strncmp((char *)&lp->srom, (char *)&enet_det[i], 3) &&
            !de4x5_strncmp((char *)&lp->srom+0x10, (char *)&enet_det[i], 3)) {
            if (i == 0) {
@@ -4188,7 +4188,7 @@ de4x5_strncmp(char *a, char *b, int n)
 {
     int ret=0;
 
-    for (;n && !ret;n--) {
+    for (;n && !ret; n--) {
        ret = *a++ - *b++;
     }
 
index f8b8c71187a076f426b40833f5631d9445c9fdf0..46339f6bcd004b9ca6b443cad05df2c82742cf32 100644 (file)
@@ -292,17 +292,6 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
        return count;
 }
 
-static inline size_t iov_total(const struct iovec *iv, unsigned long count)
-{
-       unsigned long i;
-       size_t len;
-
-       for (i = 0, len = 0; i < count; i++)
-               len += iv[i].iov_len;
-
-       return len;
-}
-
 static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
                              unsigned long count, loff_t pos)
 {
@@ -313,7 +302,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);
 
-       return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
+       return tun_get_user(tun, (struct iovec *) iv, iov_length(iv, count));
 }
 
 /* Put packet to the user space buffer */
@@ -364,7 +353,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
 
        DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
 
-       len = iov_total(iv, count);
+       len = iov_length(iv, count);
        if (len < 0)
                return -EINVAL;
 
@@ -517,7 +506,7 @@ static int tun_set_iff(struct file *file, struct ifreq *ifr)
                /* Be promiscuous by default to maintain previous behaviour. */
                tun->if_flags = IFF_PROMISC;
                /* Generate random Ethernet address. */
-               *(u16 *)tun->dev_addr = htons(0x00FF);
+               *(__be16 *)tun->dev_addr = htons(0x00FF);
                get_random_bytes(tun->dev_addr + sizeof(u16), 4);
                memset(tun->chr_filter, 0, sizeof tun->chr_filter);
 
index abac7db3819eac943df7497b86735482a63170ca..73d6ac9406b3d4b8f5523bd8010e1a8db95f914b 100644 (file)
@@ -3614,9 +3614,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
 
        ugeth_vdbg("%s: IN", __FUNCTION__);
 
-       if (!ugeth)
-               return IRQ_NONE;
-
        uccf = ugeth->uccf;
        ug_info = ugeth->ug_info;
 
index 1ffdd106f4c49a898f61f8a6d5be98da4c1a4d95..633a511d6cb671151aa7c62e8bbf796f828f09d5 100644 (file)
@@ -101,17 +101,16 @@ static void dm_write_async_callback(struct urb *urb)
        usb_free_urb(urb);
 }
 
-static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
+static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value,
+                                 u16 length, void *data)
 {
        struct usb_ctrlrequest *req;
        struct urb *urb;
        int status;
 
-       devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
-
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb) {
-               deverr(dev, "Error allocating URB in dm_write_async!");
+               deverr(dev, "Error allocating URB in dm_write_async_helper!");
                return;
        }
 
@@ -123,8 +122,8 @@ static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
        }
 
        req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
-       req->bRequest = DM_WRITE_REGS;
-       req->wValue = 0;
+       req->bRequest = length ? DM_WRITE_REGS : DM_WRITE_REG;
+       req->wValue = cpu_to_le16(value);
        req->wIndex = cpu_to_le16(reg);
        req->wLength = cpu_to_le16(length);
 
@@ -142,45 +141,19 @@ static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
        }
 }
 
-static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
-       struct usb_ctrlrequest *req;
-       struct urb *urb;
-       int status;
+       devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length);
 
+       dm_write_async_helper(dev, reg, 0, length, data);
+}
+
+static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value)
+{
        devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x",
               reg, value);
 
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (!urb) {
-               deverr(dev, "Error allocating URB in dm_write_async!");
-               return;
-       }
-
-       req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
-       if (!req) {
-               deverr(dev, "Failed to allocate memory for control request");
-               usb_free_urb(urb);
-               return;
-       }
-
-       req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
-       req->bRequest = DM_WRITE_REG;
-       req->wValue = cpu_to_le16(value);
-       req->wIndex = cpu_to_le16(reg);
-       req->wLength = 0;
-
-       usb_fill_control_urb(urb, dev->udev,
-                            usb_sndctrlpipe(dev->udev, 0),
-                            (void *)req, NULL, 0, dm_write_async_callback, req);
-
-       status = usb_submit_urb(urb, GFP_ATOMIC);
-       if (status < 0) {
-               deverr(dev, "Error submitting the control message: status=%d",
-                      status);
-               kfree(req);
-               usb_free_urb(urb);
-       }
+       dm_write_async_helper(dev, reg, value, 0, NULL);
 }
 
 static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, u16 *value)
index 07263cd93f9cfdf57f95ecccb61511cdce683f1d..87c180b563d36dc6623c52df7a5fb2111e8155c1 100644 (file)
@@ -1338,7 +1338,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
                                if (debug > 2 &&
                                    ioread8(ioaddr+ChipCmd) & CmdTxOn)
                                        printk(KERN_WARNING "%s: "
-                                              "rhine_interrupt() Tx engine"
+                                              "rhine_interrupt() Tx engine "
                                               "still on.\n", dev->name);
                        }
                        rhine_tx(dev);
index 12dae8e24844a6ed0ee92ffb650cb731175ee5f6..cf27bf40d36eefe7285b67e9884bc87bbdee9af2 100644 (file)
@@ -1498,9 +1498,9 @@ do_bottom_half_rx(struct fst_card_info *card)
  *      Dev_id is our fst_card_info pointer
  */
 static irqreturn_t
-fst_intr(int irq, void *dev_id)
+fst_intr(int dummy, void *dev_id)
 {
-       struct fst_card_info *card;
+       struct fst_card_info *card = dev_id;
        struct fst_port_info *port;
        int rdidx;              /* Event buffer indices */
        int wridx;
@@ -1509,17 +1509,12 @@ fst_intr(int irq, void *dev_id)
        unsigned int do_card_interrupt;
        unsigned int int_retry_count;
 
-       if ((card = dev_id) == NULL) {
-               dbg(DBG_INTR, "intr: spurious %d\n", irq);
-               return IRQ_NONE;
-       }
-
        /*
         * Check to see if the interrupt was for this card
         * return if not
         * Note that the call to clear the interrupt is important
         */
-       dbg(DBG_INTR, "intr: %d %p\n", irq, card);
+       dbg(DBG_INTR, "intr: %d %p\n", card->irq, card);
        if (card->state != FST_RUNNING) {
                printk_err
                    ("Interrupt received for card %d in a non running state (%d)\n",
index 3caeb528eacea2f247820a6e2f65e181c54f9e2e..519e1550e2e785fb99349b676f13a83bb497336e 100644 (file)
@@ -42,7 +42,7 @@ static inline struct ppp_state* state(hdlc_device *hdlc)
 static int ppp_open(struct net_device *dev)
 {
        hdlc_device *hdlc = dev_to_hdlc(dev);
-       void *old_ioctl;
+       int (*old_ioctl)(struct net_device *, struct ifreq *, int);
        int result;
 
        dev->priv = &state(hdlc)->syncppp_ptr;
index 1a69a9aaa9b95fae17ffc077a1d8100dd612f414..8895394e60062071fc986a7b0acd4218fdbe3ef4 100644 (file)
@@ -59,7 +59,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
        raw_hdlc_proto new_settings;
        hdlc_device *hdlc = dev_to_hdlc(dev);
        int result;
-       void *old_ch_mtu;
+       int (*old_ch_mtu)(struct net_device *, int);
        int old_qlen;
 
        switch (ifr->ifr_settings.type) {
index 37c52e1317504a5e1a7a0e87ca53a47c7daf697b..6635ecef36e5096702035bfb3af8da662a3caab4 100644 (file)
@@ -491,13 +491,13 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
                     int pos;
                     int timeout = 500000;
 
-                    if(xc.data == 0x0){
+                    if (!xc.data) {
                             ret = -EINVAL;
                             break;
                     }
 
                     data = kmalloc(xc.len, GFP_KERNEL);
-                    if(data == 0x0){
+                    if (!data) {
                             printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name);
                             ret = -ENOMEM;
                             break;
@@ -1643,7 +1643,7 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
          * just allocate an skb buff and continue.
          */
         
-        if(skb == 0x0){
+        if (!skb) {
             nsb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
             if (nsb) {
                 sc->lmc_rxq[i] = nsb;
index c9c878cd5c72725e6bbc44df92b599afef466b3b..8aa461c941ce903680372cdd25feb12f374c4e72 100644 (file)
@@ -1219,10 +1219,6 @@ lmc_t1_watchdog (lmc_softc_t * const sc)
 static void
 lmc_set_protocol (lmc_softc_t * const sc, lmc_ctl_t * ctl)
 {
-  if (ctl == 0)
-    {
-      sc->ictl.keepalive_onoff = LMC_CTL_ON;
-
-      return;
-    }
+       if (!ctl)
+               sc->ictl.keepalive_onoff = LMC_CTL_ON;
 }
index 426c0678d9830c2725f2802009ab37d0e29ff405..85315758198d901d9e2fdb02bbd185f5d878c156 100644 (file)
@@ -208,7 +208,7 @@ void lmc_proto_close(lmc_softc_t *sc) /*FOLD00*/
     lmc_trace(sc->lmc_device, "lmc_proto_close out");
 }
 
-unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
+__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
 {
     lmc_trace(sc->lmc_device, "lmc_proto_type in");
     switch(sc->if_type){
index 080a5577334982519068f86d7939d50a384a880e..ccaa69e8b3c73d5665c614ffc4e4b6b851423b31 100644 (file)
@@ -8,7 +8,7 @@ void lmc_proto_reopen(lmc_softc_t *sc);
 int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd);
 void lmc_proto_open(lmc_softc_t *sc);
 void lmc_proto_close(lmc_softc_t *sc);
-unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
+__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
 void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb);
 int lmc_skb_rawpackets(char *buf, char **start, off_t offset, int len, int unused);
 
index 99fee2f1d0195d19bf399a35ea58014c34f4c8a5..57914fbd41d370c15df6c2a9531a069a77731166 100644 (file)
@@ -2365,17 +2365,17 @@ static void falc_intr(pc300_t * card)
 
 static irqreturn_t cpc_intr(int irq, void *dev_id)
 {
-       pc300_t *card;
+       pc300_t *card = dev_id;
        volatile ucchar plx_status;
 
-       if ((card = (pc300_t *) dev_id) == 0) {
+       if (!card) {
 #ifdef PC300_DEBUG_INTR
                printk("cpc_intr: spurious intr %d\n", irq);
 #endif
                return IRQ_NONE;                /* spurious intr */
        }
 
-       if (card->hw.rambase == 0) {
+       if (!card->hw.rambase) {
 #ifdef PC300_DEBUG_INTR
                printk("cpc_intr: spurious intr2 %d\n", irq);
 #endif
@@ -3648,7 +3648,7 @@ static void __devexit cpc_remove_one(struct pci_dev *pdev)
 {
        pc300_t *card = pci_get_drvdata(pdev);
 
-       if (card->hw.rambase != 0) {
+       if (card->hw.rambase) {
                int i;
 
                /* Disable interrupts on the PCI bridge */
index e24a7b095dd6921208c3dab48a59d9a327eed0d3..63abfd72542d118c7a8b93f25cbd5ed3098337ca 100644 (file)
@@ -313,7 +313,7 @@ static int cpc_tty_open(struct tty_struct *tty, struct file *flip)
        if (cpc_tty->num_open == 0) { /* first open of this tty */
                if (!cpc_tty_area[port].buf_tx){
                        cpc_tty_area[port].buf_tx = kmalloc(CPC_TTY_MAX_MTU,GFP_KERNEL);
-                       if (cpc_tty_area[port].buf_tx == 0){
+                       if (!cpc_tty_area[port].buf_tx) {
                                CPC_TTY_DBG("%s: error in memory allocation\n",cpc_tty->name);
                                return -ENOMEM;
                        }
@@ -678,7 +678,7 @@ static void cpc_tty_rx_work(struct work_struct *work)
                for (j=0; j < CPC_TTY_NPORTS; j++) {
                        cpc_tty = &cpc_tty_area[port];
                
-                       if ((buf=cpc_tty->buf_rx.first) != 0) {
+                       if ((buf=cpc_tty->buf_rx.first) != NULL) {
                                if (cpc_tty->tty) {
                                        ld = tty_ldisc_ref(cpc_tty->tty);
                                        if (ld) {
@@ -784,7 +784,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                } 
                
                new = kmalloc(rx_len + sizeof(st_cpc_rx_buf), GFP_ATOMIC);
-               if (new == 0) {
+               if (!new) {
                        cpc_tty_rx_disc_frame(pc300chan);
                        continue;
                }
@@ -863,7 +863,7 @@ void cpc_tty_receive(pc300dev_t *pc300dev)
                        } 
                        new->size = rx_len;
                        new->next = NULL;
-                       if (cpc_tty->buf_rx.first == 0) {
+                       if (cpc_tty->buf_rx.first == NULL) {
                                cpc_tty->buf_rx.first = new;
                                cpc_tty->buf_rx.last = new;
                        } else {
@@ -891,7 +891,7 @@ static void cpc_tty_tx_work(struct work_struct *work)
 
        CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name);
        
-       if ((tty = cpc_tty->tty) == 0) { 
+       if ((tty = cpc_tty->tty) == NULL) { 
                CPC_TTY_DBG("%s: the interface is not opened\n",cpc_tty->name);
                return; 
        }
@@ -1027,7 +1027,7 @@ void cpc_tty_unregister_service(pc300dev_t *pc300dev)
        ulong flags;
        int res;
 
-       if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == 0) { 
+       if ((cpc_tty= (st_cpc_tty_area *) pc300dev->cpc_tty) == NULL) {
                CPC_TTY_DBG("%s: interface is not TTY\n", pc300dev->dev->name);
                return; 
        }
index 2e8b5c2de887c13c42f04df22175d312fa084568..15d5c58e57bcf5a170958afd69e9e57b960cc453 100644 (file)
@@ -391,8 +391,8 @@ sbni_probe1( struct net_device  *dev,  unsigned long  ioaddr,  int  irq )
        spin_lock_init( &nl->lock );
 
        /* store MAC address (generate if that isn't known) */
-       *(u16 *)dev->dev_addr = htons( 0x00ff );
-       *(u32 *)(dev->dev_addr + 2) = htonl( 0x01000000 |
+       *(__be16 *)dev->dev_addr = htons( 0x00ff );
+       *(__be32 *)(dev->dev_addr + 2) = htonl( 0x01000000 |
                ( (mac[num]  ?  mac[num]  :  (u32)((long)dev->priv)) & 0x00ffffff) );
 
        /* store link settings (speed, receive level ) */
index 05df0a345b609744f243d1bbafcd05bbbe0e7d9f..73e2f278093220e4bd3f8f5094c9ab55a1d190f5 100644 (file)
@@ -867,7 +867,7 @@ static void sdla_receive(struct net_device *dev)
        spin_unlock_irqrestore(&sdla_lock, flags);
 }
 
-static irqreturn_t sdla_isr(int irq, void *dev_id)
+static irqreturn_t sdla_isr(int dummy, void *dev_id)
 {
        struct net_device     *dev;
        struct frad_local *flp;
@@ -879,7 +879,8 @@ static irqreturn_t sdla_isr(int irq, void *dev_id)
 
        if (!flp->initialized)
        {
-               printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", dev->name, irq);
+               printk(KERN_WARNING "%s: irq %d for uninitialized device.\n",
+                      dev->name, dev->irq);
                return IRQ_NONE;
        }
 
index 8e320b76ae0ee49dee1b3598320081fd2af3e792..d4aab8a28b61bd097c7c1123472b335c79944de2 100644 (file)
@@ -715,7 +715,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
        }
 
        for (i = 0; i < sizeof(firmware); i += 4)
-               writel(htonl(*(u32*)(firmware + i)), mem + PDM_OFFSET + i);
+               writel(ntohl(*(__be32*)(firmware + i)), mem + PDM_OFFSET + i);
 
        for (i = 0; i < ports; i++)
                writel(card->status_address +
@@ -743,7 +743,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev,
        }while (time_after(timeout, jiffies));
 
        if (!stat) {
-               printk(KERN_WARNING "wanXL %s: timeout while initializing card"
+               printk(KERN_WARNING "wanXL %s: timeout while initializing card "
                       "firmware\n", pci_name(pdev));
                wanxl_pci_remove_one(pdev);
                return -ENODEV;
index 2c08c0a5a0df0221b561a4dc5ce6f45e0d8de583..f372960904b21a6d7364a8e5e70785878290341e 100644 (file)
@@ -545,6 +545,62 @@ config USB_ZD1201
          To compile this driver as a module, choose M here: the
          module will be called zd1201.
 
+config RTL8180
+       tristate "Realtek 8180/8185 PCI support"
+       depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
+       select EEPROM_93CX6
+       ---help---
+         This is a driver for RTL8180 and RTL8185 based cards.
+         These are PCI based chips found in cards such as:
+
+         (RTL8185 802.11g)
+         A-Link WL54PC
+
+         (RTL8180 802.11b)
+         Belkin F5D6020 v3
+         Belkin F5D6020 v3
+         Dlink DWL-610
+         Dlink DWL-510
+         Netgear MA521
+         Level-One WPC-0101
+         Acer Aspire 1357 LMi
+         VCTnet PC-11B1
+         Ovislink AirLive WL-1120PCM
+         Mentor WL-PCI
+         Linksys WPC11 v4
+         TrendNET TEW-288PI
+         D-Link DWL-520 Rev D
+         Repotec RP-WP7126
+         TP-Link TL-WN250/251
+         Zonet ZEW1000
+         Longshine LCS-8031-R
+         HomeLine HLW-PCC200
+         GigaFast WF721-AEX
+         Planet WL-3553
+         Encore ENLWI-PCI1-NT
+         TrendNET TEW-266PC
+         Gigabyte GN-WLMR101
+         Siemens-fujitsu Amilo D1840W
+         Edimax EW-7126
+         PheeNet WL-11PCIR
+         Tonze PC-2100T
+         Planet WL-8303
+         Dlink DWL-650 v M1
+         Edimax EW-7106
+         Q-Tec 770WC
+         Topcom Skyr@cer 4011b
+         Roper FreeLan 802.11b (edition 2004)
+         Wistron Neweb Corp CB-200B
+         Pentagram HorNET
+         QTec 775WC
+         TwinMOS Booming B Series
+         Micronet SP906BB
+         Sweex LC700010
+         Surecom EP-9428
+         Safecom SWLCR-1100
+
+         Thanks to Realtek for their support!
+
 config RTL8187
        tristate "Realtek 8187 USB support"
        depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
@@ -648,6 +704,23 @@ config P54_PCI
 
          If you choose to build a module, it'll be called p54pci.
 
+config ATH5K
+       tristate "Atheros 5xxx wireless cards support"
+       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       ---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.
+
 source "drivers/net/wireless/iwlwifi/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/bcm43xx/Kconfig"
index 6f32b53ee1283c5847aca504485bb6ac2a7e0977..6af7b158624ec07797998e93e2ce25653e6aad64 100644 (file)
@@ -47,14 +47,20 @@ obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
 obj-$(CONFIG_USB_ZD1201)       += zd1201.o
 obj-$(CONFIG_LIBERTAS)         += libertas/
 
+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
+
+obj-$(CONFIG_RTL8180)  += rtl8180.o
 obj-$(CONFIG_RTL8187)  += rtl8187.o
 
 obj-$(CONFIG_ADM8211)  += adm8211.o
 
-obj-$(CONFIG_IWLWIFI)  += iwlwifi/
+obj-$(CONFIG_IWL3945)  += iwlwifi/
+obj-$(CONFIG_IWL4965)  += iwlwifi/
 obj-$(CONFIG_RT2X00)   += rt2x00/
 
 obj-$(CONFIG_P54_COMMON)       += p54common.o
 obj-$(CONFIG_P54_USB)          += p54usb.o
 obj-$(CONFIG_P54_PCI)          += p54pci.o
+
+obj-$(CONFIG_ATH5K)    += ath5k/
index 5bf7913aadda051f59f76bd76768576b31f74d6f..79796186713e5af59aaa6d172d7f67301ecc03f5 100644 (file)
@@ -104,7 +104,7 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
        if (!priv->eeprom)
                return -ENOMEM;
 
-       eeprom_93cx6_multiread(&eeprom, 0, (__le16 __force *)priv->eeprom, words);
+       eeprom_93cx6_multiread(&eeprom, 0, (__le16 *)priv->eeprom, words);
 
        cr49 = le16_to_cpu(priv->eeprom->cr49);
        priv->rf_type = (cr49 >> 3) & 0x7;
@@ -1312,7 +1312,8 @@ static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        return 0;
 }
 
-static int adm8211_config_interface(struct ieee80211_hw *dev, int if_id,
+static int adm8211_config_interface(struct ieee80211_hw *dev,
+                                   struct ieee80211_vif *vif,
                                    struct ieee80211_if_conf *conf)
 {
        struct adm8211_priv *priv = dev->priv;
@@ -1867,9 +1868,9 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
                goto err_iounmap;
        }
 
-       *(u32 *)perm_addr = le32_to_cpu((__force __le32)ADM8211_CSR_READ(PAR0));
-       *(u16 *)&perm_addr[4] =
-               le16_to_cpu((__force __le16)ADM8211_CSR_READ(PAR1) & 0xFFFF);
+       *(__le32 *)perm_addr = cpu_to_le32(ADM8211_CSR_READ(PAR0));
+       *(__le16 *)&perm_addr[4] =
+               cpu_to_le16(ADM8211_CSR_READ(PAR1) & 0xFFFF);
 
        if (!is_valid_ether_addr(perm_addr)) {
                printk(KERN_WARNING "%s (adm8211): Invalid hwaddr in EEPROM!\n",
index 074055e18c5c510d879fafc903e9f65b27fae752..932d6b1c9d0bad70b45a285faafedd602426c5e1 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/crypto.h>
 #include <asm/io.h>
 #include <asm/system.h>
+#include <asm/unaligned.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -500,140 +501,143 @@ typedef struct {
 /* This structure came from an email sent to me from an engineer at
    aironet for inclusion into this driver */
 typedef struct {
-       u16 len;
-       u16 kindex;
+       __le16 len;
+       __le16 kindex;
        u8 mac[ETH_ALEN];
-       u16 klen;
+       __le16 klen;
        u8 key[16];
 } WepKeyRid;
 
 /* These structures are from the Aironet's PC4500 Developers Manual */
 typedef struct {
-       u16 len;
+       __le16 len;
        u8 ssid[32];
 } Ssid;
 
 typedef struct {
-       u16 len;
+       __le16 len;
        Ssid ssids[3];
 } SsidRid;
 
 typedef struct {
-        u16 len;
-        u16 modulation;
-#define MOD_DEFAULT 0
-#define MOD_CCK 1
-#define MOD_MOK 2
+        __le16 len;
+        __le16 modulation;
+#define MOD_DEFAULT cpu_to_le16(0)
+#define MOD_CCK cpu_to_le16(1)
+#define MOD_MOK cpu_to_le16(2)
 } ModulationRid;
 
 typedef struct {
-       u16 len; /* sizeof(ConfigRid) */
-       u16 opmode; /* operating mode */
-#define MODE_STA_IBSS 0
-#define MODE_STA_ESS 1
-#define MODE_AP 2
-#define MODE_AP_RPTR 3
-#define MODE_ETHERNET_HOST (0<<8) /* rx payloads converted */
-#define MODE_LLC_HOST (1<<8) /* rx payloads left as is */
-#define MODE_AIRONET_EXTEND (1<<9) /* enable Aironet extenstions */
-#define MODE_AP_INTERFACE (1<<10) /* enable ap interface extensions */
-#define MODE_ANTENNA_ALIGN (1<<11) /* enable antenna alignment */
-#define MODE_ETHER_LLC (1<<12) /* enable ethernet LLC */
-#define MODE_LEAF_NODE (1<<13) /* enable leaf node bridge */
-#define MODE_CF_POLLABLE (1<<14) /* enable CF pollable */
-#define MODE_MIC (1<<15) /* enable MIC */
-       u16 rmode; /* receive mode */
-#define RXMODE_BC_MC_ADDR 0
-#define RXMODE_BC_ADDR 1 /* ignore multicasts */
-#define RXMODE_ADDR 2 /* ignore multicast and broadcast */
-#define RXMODE_RFMON 3 /* wireless monitor mode */
-#define RXMODE_RFMON_ANYBSS 4
-#define RXMODE_LANMON 5 /* lan style monitor -- data packets only */
-#define RXMODE_DISABLE_802_3_HEADER (1<<8) /* disables 802.3 header on rx */
-#define RXMODE_NORMALIZED_RSSI (1<<9) /* return normalized RSSI */
-       u16 fragThresh;
-       u16 rtsThres;
+       __le16 len; /* sizeof(ConfigRid) */
+       __le16 opmode; /* operating mode */
+#define MODE_STA_IBSS cpu_to_le16(0)
+#define MODE_STA_ESS cpu_to_le16(1)
+#define MODE_AP cpu_to_le16(2)
+#define MODE_AP_RPTR cpu_to_le16(3)
+#define MODE_CFG_MASK cpu_to_le16(0xff)
+#define MODE_ETHERNET_HOST cpu_to_le16(0<<8) /* rx payloads converted */
+#define MODE_LLC_HOST cpu_to_le16(1<<8) /* rx payloads left as is */
+#define MODE_AIRONET_EXTEND cpu_to_le16(1<<9) /* enable Aironet extenstions */
+#define MODE_AP_INTERFACE cpu_to_le16(1<<10) /* enable ap interface extensions */
+#define MODE_ANTENNA_ALIGN cpu_to_le16(1<<11) /* enable antenna alignment */
+#define MODE_ETHER_LLC cpu_to_le16(1<<12) /* enable ethernet LLC */
+#define MODE_LEAF_NODE cpu_to_le16(1<<13) /* enable leaf node bridge */
+#define MODE_CF_POLLABLE cpu_to_le16(1<<14) /* enable CF pollable */
+#define MODE_MIC cpu_to_le16(1<<15) /* enable MIC */
+       __le16 rmode; /* receive mode */
+#define RXMODE_BC_MC_ADDR cpu_to_le16(0)
+#define RXMODE_BC_ADDR cpu_to_le16(1) /* ignore multicasts */
+#define RXMODE_ADDR cpu_to_le16(2) /* ignore multicast and broadcast */
+#define RXMODE_RFMON cpu_to_le16(3) /* wireless monitor mode */
+#define RXMODE_RFMON_ANYBSS cpu_to_le16(4)
+#define RXMODE_LANMON cpu_to_le16(5) /* lan style monitor -- data packets only */
+#define RXMODE_MASK cpu_to_le16(255)
+#define RXMODE_DISABLE_802_3_HEADER cpu_to_le16(1<<8) /* disables 802.3 header on rx */
+#define RXMODE_FULL_MASK (RXMODE_MASK | RXMODE_DISABLE_802_3_HEADER)
+#define RXMODE_NORMALIZED_RSSI cpu_to_le16(1<<9) /* return normalized RSSI */
+       __le16 fragThresh;
+       __le16 rtsThres;
        u8 macAddr[ETH_ALEN];
        u8 rates[8];
-       u16 shortRetryLimit;
-       u16 longRetryLimit;
-       u16 txLifetime; /* in kusec */
-       u16 rxLifetime; /* in kusec */
-       u16 stationary;
-       u16 ordering;
-       u16 u16deviceType; /* for overriding device type */
-       u16 cfpRate;
-       u16 cfpDuration;
-       u16 _reserved1[3];
+       __le16 shortRetryLimit;
+       __le16 longRetryLimit;
+       __le16 txLifetime; /* in kusec */
+       __le16 rxLifetime; /* in kusec */
+       __le16 stationary;
+       __le16 ordering;
+       __le16 u16deviceType; /* for overriding device type */
+       __le16 cfpRate;
+       __le16 cfpDuration;
+       __le16 _reserved1[3];
        /*---------- Scanning/Associating ----------*/
-       u16 scanMode;
-#define SCANMODE_ACTIVE 0
-#define SCANMODE_PASSIVE 1
-#define SCANMODE_AIROSCAN 2
-       u16 probeDelay; /* in kusec */
-       u16 probeEnergyTimeout; /* in kusec */
-        u16 probeResponseTimeout;
-       u16 beaconListenTimeout;
-       u16 joinNetTimeout;
-       u16 authTimeout;
-       u16 authType;
-#define AUTH_OPEN 0x1
-#define AUTH_ENCRYPT 0x101
-#define AUTH_SHAREDKEY 0x102
-#define AUTH_ALLOW_UNENCRYPTED 0x200
-       u16 associationTimeout;
-       u16 specifiedApTimeout;
-       u16 offlineScanInterval;
-       u16 offlineScanDuration;
-       u16 linkLossDelay;
-       u16 maxBeaconLostTime;
-       u16 refreshInterval;
-#define DISABLE_REFRESH 0xFFFF
-       u16 _reserved1a[1];
+       __le16 scanMode;
+#define SCANMODE_ACTIVE cpu_to_le16(0)
+#define SCANMODE_PASSIVE cpu_to_le16(1)
+#define SCANMODE_AIROSCAN cpu_to_le16(2)
+       __le16 probeDelay; /* in kusec */
+       __le16 probeEnergyTimeout; /* in kusec */
+        __le16 probeResponseTimeout;
+       __le16 beaconListenTimeout;
+       __le16 joinNetTimeout;
+       __le16 authTimeout;
+       __le16 authType;
+#define AUTH_OPEN cpu_to_le16(0x1)
+#define AUTH_ENCRYPT cpu_to_le16(0x101)
+#define AUTH_SHAREDKEY cpu_to_le16(0x102)
+#define AUTH_ALLOW_UNENCRYPTED cpu_to_le16(0x200)
+       __le16 associationTimeout;
+       __le16 specifiedApTimeout;
+       __le16 offlineScanInterval;
+       __le16 offlineScanDuration;
+       __le16 linkLossDelay;
+       __le16 maxBeaconLostTime;
+       __le16 refreshInterval;
+#define DISABLE_REFRESH cpu_to_le16(0xFFFF)
+       __le16 _reserved1a[1];
        /*---------- Power save operation ----------*/
-       u16 powerSaveMode;
-#define POWERSAVE_CAM 0
-#define POWERSAVE_PSP 1
-#define POWERSAVE_PSPCAM 2
-       u16 sleepForDtims;
-       u16 listenInterval;
-       u16 fastListenInterval;
-       u16 listenDecay;
-       u16 fastListenDelay;
-       u16 _reserved2[2];
+       __le16 powerSaveMode;
+#define POWERSAVE_CAM cpu_to_le16(0)
+#define POWERSAVE_PSP cpu_to_le16(1)
+#define POWERSAVE_PSPCAM cpu_to_le16(2)
+       __le16 sleepForDtims;
+       __le16 listenInterval;
+       __le16 fastListenInterval;
+       __le16 listenDecay;
+       __le16 fastListenDelay;
+       __le16 _reserved2[2];
        /*---------- Ap/Ibss config items ----------*/
-       u16 beaconPeriod;
-       u16 atimDuration;
-       u16 hopPeriod;
-       u16 channelSet;
-       u16 channel;
-       u16 dtimPeriod;
-       u16 bridgeDistance;
-       u16 radioID;
+       __le16 beaconPeriod;
+       __le16 atimDuration;
+       __le16 hopPeriod;
+       __le16 channelSet;
+       __le16 channel;
+       __le16 dtimPeriod;
+       __le16 bridgeDistance;
+       __le16 radioID;
        /*---------- Radio configuration ----------*/
-       u16 radioType;
-#define RADIOTYPE_DEFAULT 0
-#define RADIOTYPE_802_11 1
-#define RADIOTYPE_LEGACY 2
+       __le16 radioType;
+#define RADIOTYPE_DEFAULT cpu_to_le16(0)
+#define RADIOTYPE_802_11 cpu_to_le16(1)
+#define RADIOTYPE_LEGACY cpu_to_le16(2)
        u8 rxDiversity;
        u8 txDiversity;
-       u16 txPower;
+       __le16 txPower;
 #define TXPOWER_DEFAULT 0
-       u16 rssiThreshold;
+       __le16 rssiThreshold;
 #define RSSI_DEFAULT 0
-        u16 modulation;
-#define PREAMBLE_AUTO 0
-#define PREAMBLE_LONG 1
-#define PREAMBLE_SHORT 2
-       u16 preamble;
-       u16 homeProduct;
-       u16 radioSpecific;
+        __le16 modulation;
+#define PREAMBLE_AUTO cpu_to_le16(0)
+#define PREAMBLE_LONG cpu_to_le16(1)
+#define PREAMBLE_SHORT cpu_to_le16(2)
+       __le16 preamble;
+       __le16 homeProduct;
+       __le16 radioSpecific;
        /*---------- Aironet Extensions ----------*/
        u8 nodeName[16];
-       u16 arlThreshold;
-       u16 arlDecay;
-       u16 arlDelay;
-       u16 _reserved4[1];
+       __le16 arlThreshold;
+       __le16 arlDecay;
+       __le16 arlDelay;
+       __le16 _reserved4[1];
        /*---------- Aironet Extensions ----------*/
        u8 magicAction;
 #define MAGIC_ACTION_STSCHG 1
@@ -643,34 +647,34 @@ typedef struct {
 #define MAGIC_SWITCH_TO_PSP (0<<10)
 #define MAGIC_STAY_IN_CAM (1<<10)
        u8 magicControl;
-       u16 autoWake;
+       __le16 autoWake;
 } ConfigRid;
 
 typedef struct {
-       u16 len;
+       __le16 len;
        u8 mac[ETH_ALEN];
-       u16 mode;
-       u16 errorCode;
-       u16 sigQuality;
-       u16 SSIDlen;
+       __le16 mode;
+       __le16 errorCode;
+       __le16 sigQuality;
+       __le16 SSIDlen;
        char SSID[32];
        char apName[16];
        u8 bssid[4][ETH_ALEN];
-       u16 beaconPeriod;
-       u16 dimPeriod;
-       u16 atimDuration;
-       u16 hopPeriod;
-       u16 channelSet;
-       u16 channel;
-       u16 hopsToBackbone;
-       u16 apTotalLoad;
-       u16 generatedLoad;
-       u16 accumulatedArl;
-       u16 signalQuality;
-       u16 currentXmitRate;
-       u16 apDevExtensions;
-       u16 normalizedSignalStrength;
-       u16 shortPreamble;
+       __le16 beaconPeriod;
+       __le16 dimPeriod;
+       __le16 atimDuration;
+       __le16 hopPeriod;
+       __le16 channelSet;
+       __le16 channel;
+       __le16 hopsToBackbone;
+       __le16 apTotalLoad;
+       __le16 generatedLoad;
+       __le16 accumulatedArl;
+       __le16 signalQuality;
+       __le16 currentXmitRate;
+       __le16 apDevExtensions;
+       __le16 normalizedSignalStrength;
+       __le16 shortPreamble;
        u8 apIP[4];
        u8 noisePercent; /* Noise percent in last second */
        u8 noisedBm; /* Noise dBm in last second */
@@ -678,9 +682,9 @@ typedef struct {
        u8 noiseAvedBm; /* Noise dBm in last minute */
        u8 noiseMaxPercent; /* Highest noise percent in last minute */
        u8 noiseMaxdBm; /* Highest noise dbm in last minute */
-       u16 load;
+       __le16 load;
        u8 carrier[4];
-       u16 assocStatus;
+       __le16 assocStatus;
 #define STAT_NOPACKETS 0
 #define STAT_NOCARRIERSET 10
 #define STAT_GOTCARRIERSET 11
@@ -705,82 +709,82 @@ typedef struct {
 } StatusRid;
 
 typedef struct {
-       u16 len;
-       u16 spacer;
-       u32 vals[100];
+       __le16 len;
+       __le16 spacer;
+       __le32 vals[100];
 } StatsRid;
 
 
 typedef struct {
-       u16 len;
+       __le16 len;
        u8 ap[4][ETH_ALEN];
 } APListRid;
 
 typedef struct {
-       u16 len;
+       __le16 len;
        char oui[3];
        char zero;
-       u16 prodNum;
+       __le16 prodNum;
        char manName[32];
        char prodName[16];
        char prodVer[8];
        char factoryAddr[ETH_ALEN];
        char aironetAddr[ETH_ALEN];
-       u16 radioType;
-       u16 country;
+       __le16 radioType;
+       __le16 country;
        char callid[ETH_ALEN];
        char supportedRates[8];
        char rxDiversity;
        char txDiversity;
-       u16 txPowerLevels[8];
-       u16 hardVer;
-       u16 hardCap;
-       u16 tempRange;
-       u16 softVer;
-       u16 softSubVer;
-       u16 interfaceVer;
-       u16 softCap;
-       u16 bootBlockVer;
-       u16 requiredHard;
-       u16 extSoftCap;
+       __le16 txPowerLevels[8];
+       __le16 hardVer;
+       __le16 hardCap;
+       __le16 tempRange;
+       __le16 softVer;
+       __le16 softSubVer;
+       __le16 interfaceVer;
+       __le16 softCap;
+       __le16 bootBlockVer;
+       __le16 requiredHard;
+       __le16 extSoftCap;
 } CapabilityRid;
 
 
 /* Only present on firmware >= 5.30.17 */
 typedef struct {
-  u16 unknown[4];
+  __le16 unknown[4];
   u8 fixed[12]; /* WLAN management frame */
   u8 iep[624];
 } BSSListRidExtra;
 
 typedef struct {
-  u16 len;
-  u16 index; /* First is 0 and 0xffff means end of list */
+  __le16 len;
+  __le16 index; /* First is 0 and 0xffff means end of list */
 #define RADIO_FH 1 /* Frequency hopping radio type */
 #define RADIO_DS 2 /* Direct sequence radio type */
 #define RADIO_TMA 4 /* Proprietary radio used in old cards (2500) */
-  u16 radioType;
+  __le16 radioType;
   u8 bssid[ETH_ALEN]; /* Mac address of the BSS */
   u8 zero;
   u8 ssidLen;
   u8 ssid[32];
-  u16 dBm;
-#define CAP_ESS (1<<0)
-#define CAP_IBSS (1<<1)
-#define CAP_PRIVACY (1<<4)
-#define CAP_SHORTHDR (1<<5)
-  u16 cap;
-  u16 beaconInterval;
+  __le16 dBm;
+#define CAP_ESS cpu_to_le16(1<<0)
+#define CAP_IBSS cpu_to_le16(1<<1)
+#define CAP_PRIVACY cpu_to_le16(1<<4)
+#define CAP_SHORTHDR cpu_to_le16(1<<5)
+  __le16 cap;
+  __le16 beaconInterval;
   u8 rates[8]; /* Same as rates for config rid */
   struct { /* For frequency hopping only */
-    u16 dwell;
+    __le16 dwell;
     u8 hopSet;
     u8 hopPattern;
     u8 hopIndex;
     u8 fill;
   } fh;
-  u16 dsChannel;
-  u16 atimWindow;
+  __le16 dsChannel;
+  __le16 atimWindow;
 
   /* Only present on firmware >= 5.30.17 */
   BSSListRidExtra extra;
@@ -811,7 +815,7 @@ typedef struct {
 } MICRid;
 
 typedef struct {
-       u16 typelen;
+       __be16 typelen;
 
        union {
            u8 snap[8];
@@ -823,8 +827,8 @@ typedef struct {
                u8 fieldtype[2];
            } llc;
        } u;
-       u32 mic;
-       u32 seq;
+       __be32 mic;
+       __be32 seq;
 } MICBuffer;
 
 typedef struct {
@@ -943,7 +947,7 @@ typedef struct {
        int position;   // current position (byte offset) in message
        union {
                u8  d8[4];
-               u32 d32;
+               __be32 d32;
        } part; // saves partial message word across update() calls
 } emmh32_context;
 
@@ -1100,11 +1104,11 @@ static void enable_interrupts(struct airo_info*);
 static void disable_interrupts(struct airo_info*);
 static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp);
 static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap);
-static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
+static int aux_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
                        int whichbap);
-static int fast_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen,
+static int fast_bap_read(struct airo_info*, __le16 *pu16Dst, int bytelen,
                         int whichbap);
-static int bap_write(struct airo_info*, const u16 *pu16Src, int bytelen,
+static int bap_write(struct airo_info*, const __le16 *pu16Src, int bytelen,
                     int whichbap);
 static int PC4500_accessrid(struct airo_info*, u16 rid, u16 accmd);
 static int PC4500_readrid(struct airo_info*, u16 rid, void *pBuf, int len, int lock);
@@ -1187,7 +1191,7 @@ struct airo_info {
 #define JOB_WSTATS     8
 #define JOB_SCAN_RESULTS  9
        unsigned long jobs;
-       int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen,
+       int (*bap_read)(struct airo_info*, __le16 *pu16Dst, int bytelen,
                        int whichbap);
        unsigned short *flash;
        tdsRssiEntry *rssi;
@@ -1235,8 +1239,9 @@ struct airo_info {
        BSSListElement *networks;
 };
 
-static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen,
-                          int whichbap) {
+static inline int bap_read(struct airo_info *ai, __le16 *pu16Dst, int bytelen,
+                          int whichbap)
+{
        return ai->bap_read(ai, pu16Dst, bytelen, whichbap);
 }
 
@@ -1635,7 +1640,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
                crypto_cipher_encrypt_one(tfm, plain, plain);
                cipher = plain;
                for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
-                       context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
+                       context->coeff[i++] = ntohl(*(__be32 *)&cipher[j]);
                        j += 4;
                }
        }
@@ -1668,12 +1673,12 @@ static void emmh32_update(emmh32_context *context, u8 *pOctets, int len)
                        context->position++;
                        len--;
                } while (byte_position < 4);
-               MIC_ACCUM(htonl(context->part.d32));
+               MIC_ACCUM(ntohl(context->part.d32));
        }
 
        /* deal with full 32-bit words */
        while (len >= 4) {
-               MIC_ACCUM(htonl(*(u32 *)pOctets));
+               MIC_ACCUM(ntohl(*(__be32 *)pOctets));
                context->position += 4;
                pOctets += 4;
                len -= 4;
@@ -1706,7 +1711,7 @@ static void emmh32_final(emmh32_context *context, u8 digest[4])
        byte_position = context->position & 3;
        if (byte_position) {
                /* have a partial word in part to deal with */
-               val = htonl(context->part.d32);
+               val = ntohl(context->part.d32);
                MIC_ACCUM(val & mask32[byte_position]); /* zero empty bytes */
        }
 
@@ -1726,8 +1731,8 @@ static void emmh32_final(emmh32_context *context, u8 digest[4])
 }
 
 static int readBSSListRid(struct airo_info *ai, int first,
-                     BSSListRid *list) {
-       int rc;
+                     BSSListRid *list)
+{
        Cmd cmd;
        Resp rsp;
 
@@ -1744,75 +1749,43 @@ static int readBSSListRid(struct airo_info *ai, int first,
                schedule_timeout_uninterruptible(3 * HZ);
                ai->list_bss_task = NULL;
        }
-       rc = PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
+       return PC4500_readrid(ai, first ? ai->bssListFirst : ai->bssListNext,
                            list, ai->bssListRidLen, 1);
-
-       list->len = le16_to_cpu(list->len);
-       list->index = le16_to_cpu(list->index);
-       list->radioType = le16_to_cpu(list->radioType);
-       list->cap = le16_to_cpu(list->cap);
-       list->beaconInterval = le16_to_cpu(list->beaconInterval);
-       list->fh.dwell = le16_to_cpu(list->fh.dwell);
-       list->dsChannel = le16_to_cpu(list->dsChannel);
-       list->atimWindow = le16_to_cpu(list->atimWindow);
-       list->dBm = le16_to_cpu(list->dBm);
-       return rc;
 }
 
-static int readWepKeyRid(struct airo_info*ai, WepKeyRid *wkr, int temp, int lock) {
-       int rc = PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
+static int readWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int temp, int lock)
+{
+       return PC4500_readrid(ai, temp ? RID_WEP_TEMP : RID_WEP_PERM,
                                wkr, sizeof(*wkr), lock);
-
-       wkr->len = le16_to_cpu(wkr->len);
-       wkr->kindex = le16_to_cpu(wkr->kindex);
-       wkr->klen = le16_to_cpu(wkr->klen);
-       return rc;
 }
-/* In the writeXXXRid routines we copy the rids so that we don't screwup
- * the originals when we endian them... */
-static int writeWepKeyRid(struct airo_info*ai, WepKeyRid *pwkr, int perm, int lock) {
-       int rc;
-       WepKeyRid wkr = *pwkr;
 
-       wkr.len = cpu_to_le16(wkr.len);
-       wkr.kindex = cpu_to_le16(wkr.kindex);
-       wkr.klen = cpu_to_le16(wkr.klen);
-       rc = PC4500_writerid(ai, RID_WEP_TEMP, &wkr, sizeof(wkr), lock);
-       if (rc!=SUCCESS) airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
+static int writeWepKeyRid(struct airo_info *ai, WepKeyRid *wkr, int perm, int lock)
+{
+       int rc;
+       rc = PC4500_writerid(ai, RID_WEP_TEMP, wkr, sizeof(*wkr), lock);
+       if (rc!=SUCCESS)
+               airo_print_err(ai->dev->name, "WEP_TEMP set %x", rc);
        if (perm) {
-               rc = PC4500_writerid(ai, RID_WEP_PERM, &wkr, sizeof(wkr), lock);
-               if (rc!=SUCCESS) {
+               rc = PC4500_writerid(ai, RID_WEP_PERM, wkr, sizeof(*wkr), lock);
+               if (rc!=SUCCESS)
                        airo_print_err(ai->dev->name, "WEP_PERM set %x", rc);
-               }
        }
        return rc;
 }
 
-static int readSsidRid(struct airo_info*ai, SsidRid *ssidr) {
-       int i;
-       int rc = PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
-
-       ssidr->len = le16_to_cpu(ssidr->len);
-       for(i = 0; i < 3; i++) {
-               ssidr->ssids[i].len = le16_to_cpu(ssidr->ssids[i].len);
-       }
-       return rc;
+static int readSsidRid(struct airo_info*ai, SsidRid *ssidr)
+{
+       return PC4500_readrid(ai, RID_SSID, ssidr, sizeof(*ssidr), 1);
 }
-static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock) {
-       int rc;
-       int i;
-       SsidRid ssidr = *pssidr;
 
-       ssidr.len = cpu_to_le16(ssidr.len);
-       for(i = 0; i < 3; i++) {
-               ssidr.ssids[i].len = cpu_to_le16(ssidr.ssids[i].len);
-       }
-       rc = PC4500_writerid(ai, RID_SSID, &ssidr, sizeof(ssidr), lock);
-       return rc;
+static int writeSsidRid(struct airo_info*ai, SsidRid *pssidr, int lock)
+{
+       return PC4500_writerid(ai, RID_SSID, pssidr, sizeof(*pssidr), lock);
 }
-static int readConfigRid(struct airo_info*ai, int lock) {
+
+static int readConfigRid(struct airo_info *ai, int lock)
+{
        int rc;
-       u16 *s;
        ConfigRid cfg;
 
        if (ai->config.len)
@@ -1822,24 +1795,12 @@ static int readConfigRid(struct airo_info*ai, int lock) {
        if (rc != SUCCESS)
                return rc;
 
-       for(s = &cfg.len; s <= &cfg.rtsThres; s++) *s = le16_to_cpu(*s);
-
-       for(s = &cfg.shortRetryLimit; s <= &cfg.radioType; s++)
-               *s = le16_to_cpu(*s);
-
-       for(s = &cfg.txPower; s <= &cfg.radioSpecific; s++)
-               *s = le16_to_cpu(*s);
-
-       for(s = &cfg.arlThreshold; s <= &cfg._reserved4[0]; s++)
-               *s = cpu_to_le16(*s);
-
-       for(s = &cfg.autoWake; s <= &cfg.autoWake; s++)
-               *s = cpu_to_le16(*s);
-
        ai->config = cfg;
        return SUCCESS;
 }
-static inline void checkThrottle(struct airo_info *ai) {
+
+static inline void checkThrottle(struct airo_info *ai)
+{
        int i;
 /* Old hardware had a limit on encryption speed */
        if (ai->config.authType != AUTH_OPEN && maxencrypt) {
@@ -1850,8 +1811,9 @@ static inline void checkThrottle(struct airo_info *ai) {
                }
        }
 }
-static int writeConfigRid(struct airo_info*ai, int lock) {
-       u16 *s;
+
+static int writeConfigRid(struct airo_info *ai, int lock)
+{
        ConfigRid cfgr;
 
        if (!test_bit (FLAG_COMMIT, &ai->flags))
@@ -1862,70 +1824,37 @@ static int writeConfigRid(struct airo_info*ai, int lock) {
        checkThrottle(ai);
        cfgr = ai->config;
 
-       if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)
+       if ((cfgr.opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
                set_bit(FLAG_ADHOC, &ai->flags);
        else
                clear_bit(FLAG_ADHOC, &ai->flags);
 
-       for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
-
-       for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
-               *s = cpu_to_le16(*s);
-
-       for(s = &cfgr.txPower; s <= &cfgr.radioSpecific; s++)
-               *s = cpu_to_le16(*s);
-
-       for(s = &cfgr.arlThreshold; s <= &cfgr._reserved4[0]; s++)
-               *s = cpu_to_le16(*s);
-
-       for(s = &cfgr.autoWake; s <= &cfgr.autoWake; s++)
-               *s = cpu_to_le16(*s);
-
        return PC4500_writerid( ai, RID_CONFIG, &cfgr, sizeof(cfgr), lock);
 }
-static int readStatusRid(struct airo_info*ai, StatusRid *statr, int lock) {
-       int rc = PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
-       u16 *s;
 
-       statr->len = le16_to_cpu(statr->len);
-       for(s = &statr->mode; s <= &statr->SSIDlen; s++) *s = le16_to_cpu(*s);
-
-       for(s = &statr->beaconPeriod; s <= &statr->shortPreamble; s++)
-               *s = le16_to_cpu(*s);
-       statr->load = le16_to_cpu(statr->load);
-       statr->assocStatus = le16_to_cpu(statr->assocStatus);
-       return rc;
+static int readStatusRid(struct airo_info *ai, StatusRid *statr, int lock)
+{
+       return PC4500_readrid(ai, RID_STATUS, statr, sizeof(*statr), lock);
 }
-static int readAPListRid(struct airo_info*ai, APListRid *aplr) {
-       int rc =  PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
-       aplr->len = le16_to_cpu(aplr->len);
-       return rc;
+
+static int readAPListRid(struct airo_info *ai, APListRid *aplr)
+{
+       return PC4500_readrid(ai, RID_APLIST, aplr, sizeof(*aplr), 1);
 }
-static int writeAPListRid(struct airo_info*ai, APListRid *aplr, int lock) {
-       int rc;
-       aplr->len = cpu_to_le16(aplr->len);
-       rc = PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
-       return rc;
+
+static int writeAPListRid(struct airo_info *ai, APListRid *aplr, int lock)
+{
+       return PC4500_writerid(ai, RID_APLIST, aplr, sizeof(*aplr), lock);
 }
-static int readCapabilityRid(struct airo_info*ai, CapabilityRid *capr, int lock) {
-       int rc = PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
-       u16 *s;
 
-       capr->len = le16_to_cpu(capr->len);
-       capr->prodNum = le16_to_cpu(capr->prodNum);
-       capr->radioType = le16_to_cpu(capr->radioType);
-       capr->country = le16_to_cpu(capr->country);
-       for(s = &capr->txPowerLevels[0]; s <= &capr->requiredHard; s++)
-               *s = le16_to_cpu(*s);
-       return rc;
+static int readCapabilityRid(struct airo_info *ai, CapabilityRid *capr, int lock)
+{
+       return PC4500_readrid(ai, RID_CAPABILITIES, capr, sizeof(*capr), lock);
 }
-static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
-       int rc = PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
-       u32 *i;
 
-       sr->len = le16_to_cpu(sr->len);
-       for(i = &sr->vals[0]; i <= &sr->vals[99]; i++) *i = le32_to_cpu(*i);
-       return rc;
+static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock)
+{
+       return PC4500_readrid(ai, rid, sr, sizeof(*sr), lock);
 }
 
 static void try_auto_wep(struct airo_info *ai)
@@ -2026,13 +1955,14 @@ static int mpi_send_packet (struct net_device *dev)
 {
        struct sk_buff *skb;
        unsigned char *buffer;
-       s16 len, *payloadLen;
+       s16 len;
+       __le16 *payloadLen;
        struct airo_info *ai = dev->priv;
        u8 *sendbuf;
 
        /* get a packet to send */
 
-       if ((skb = skb_dequeue(&ai->txq)) == 0) {
+       if ((skb = skb_dequeue(&ai->txq)) == NULL) {
                airo_print_err(dev->name,
                        "%s: Dequeue'd zero in send_packet()",
                        __FUNCTION__);
@@ -2059,7 +1989,7 @@ static int mpi_send_packet (struct net_device *dev)
        memcpy((char *)ai->txfids[0].virtual_host_addr,
                (char *)&wifictlhdr8023, sizeof(wifictlhdr8023));
 
-       payloadLen = (s16 *)(ai->txfids[0].virtual_host_addr +
+       payloadLen = (__le16 *)(ai->txfids[0].virtual_host_addr +
                sizeof(wifictlhdr8023));
        sendbuf = ai->txfids[0].virtual_host_addr +
                sizeof(wifictlhdr8023) + 2 ;
@@ -2069,7 +1999,7 @@ static int mpi_send_packet (struct net_device *dev)
         * we don't need to account for it in the length
         */
        if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled &&
-               (ntohs(((u16 *)buffer)[6]) != 0x888E)) {
+               (ntohs(((__be16 *)buffer)[6]) != 0x888E)) {
                MICBuffer pMic;
 
                if (encapsulate(ai, (etherHead *)buffer, &pMic, len - sizeof(etherHead)) != SUCCESS)
@@ -2104,7 +2034,7 @@ static int mpi_send_packet (struct net_device *dev)
 
 static void get_tx_error(struct airo_info *ai, s32 fid)
 {
-       u16 status;
+       __le16 status;
 
        if (fid < 0)
                status = ((WifiCtlHdr *)ai->txfids[0].virtual_host_addr)->ctlhdr.status;
@@ -2135,7 +2065,7 @@ static void get_tx_error(struct airo_info *ai, s32 fid)
                /* Faster to skip over useless data than to do
                 * another bap_setup(). We are at offset 0x6 and
                 * need to go to 0x18 and read 6 bytes - Jean II */
-               bap_read(ai, (u16 *) junk, 0x18, BAP0);
+               bap_read(ai, (__le16 *) junk, 0x18, BAP0);
 
                /* Copy 802.11 dest address.
                 * We use the 802.11 header because the frame may
@@ -2289,9 +2219,10 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
        return 0;
 }
 
-static void airo_read_stats(struct airo_info *ai) {
+static void airo_read_stats(struct airo_info *ai)
+{
        StatsRid stats_rid;
-       u32 *vals = stats_rid.vals;
+       __le32 *vals = stats_rid.vals;
 
        clear_bit(JOB_STATS, &ai->jobs);
        if (ai->power.event) {
@@ -2301,20 +2232,23 @@ static void airo_read_stats(struct airo_info *ai) {
        readStatsRid(ai, &stats_rid, RID_STATS, 0);
        up(&ai->sem);
 
-       ai->stats.rx_packets = vals[43] + vals[44] + vals[45];
-       ai->stats.tx_packets = vals[39] + vals[40] + vals[41];
-       ai->stats.rx_bytes = vals[92];
-       ai->stats.tx_bytes = vals[91];
-       ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4];
-       ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors;
-       ai->stats.multicast = vals[43];
-       ai->stats.collisions = vals[89];
+       ai->stats.rx_packets = le32_to_cpu(vals[43]) + le32_to_cpu(vals[44]) +
+                              le32_to_cpu(vals[45]);
+       ai->stats.tx_packets = le32_to_cpu(vals[39]) + le32_to_cpu(vals[40]) +
+                              le32_to_cpu(vals[41]);
+       ai->stats.rx_bytes = le32_to_cpu(vals[92]);
+       ai->stats.tx_bytes = le32_to_cpu(vals[91]);
+       ai->stats.rx_errors = le32_to_cpu(vals[0]) + le32_to_cpu(vals[2]) +
+                             le32_to_cpu(vals[3]) + le32_to_cpu(vals[4]);
+       ai->stats.tx_errors = le32_to_cpu(vals[42]) + ai->stats.tx_fifo_errors;
+       ai->stats.multicast = le32_to_cpu(vals[43]);
+       ai->stats.collisions = le32_to_cpu(vals[89]);
 
        /* detailed rx_errors: */
-       ai->stats.rx_length_errors = vals[3];
-       ai->stats.rx_crc_errors = vals[4];
-       ai->stats.rx_frame_errors = vals[2];
-       ai->stats.rx_fifo_errors = vals[0];
+       ai->stats.rx_length_errors = le32_to_cpu(vals[3]);
+       ai->stats.rx_crc_errors = le32_to_cpu(vals[4]);
+       ai->stats.rx_frame_errors = le32_to_cpu(vals[2]);
+       ai->stats.rx_fifo_errors = le32_to_cpu(vals[0]);
 }
 
 static struct net_device_stats *airo_get_stats(struct net_device *dev)
@@ -2801,8 +2735,9 @@ static int airo_test_wpa_capable(struct airo_info *ai)
        if (status != SUCCESS) return 0;
 
        /* Only firmware versions 5.30.17 or better can do WPA */
-       if ((cap_rid.softVer > 0x530)
-         || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) {
+       if (le16_to_cpu(cap_rid.softVer) > 0x530
+         || (le16_to_cpu(cap_rid.softVer) == 0x530
+             && le16_to_cpu(cap_rid.softSubVer) >= 17)) {
                airo_print_info("", "WPA is supported.");
                return 1;
        }
@@ -3037,14 +2972,14 @@ static void airo_process_scan_results (struct airo_info *ai) {
 
        /* Try to read the first entry of the scan result */
        rc = PC4500_readrid(ai, ai->bssListFirst, &bss, ai->bssListRidLen, 0);
-       if((rc) || (bss.index == 0xffff)) {
+       if((rc) || (bss.index == cpu_to_le16(0xffff))) {
                /* No scan results */
                goto out;
        }
 
        /* Read and parse all entries */
        tmp_net = NULL;
-       while((!rc) && (bss.index != 0xffff)) {
+       while((!rc) && (bss.index != cpu_to_le16(0xffff))) {
                /* Grab a network off the free list */
                if (!list_empty(&ai->network_free_list)) {
                        tmp_net = list_entry(ai->network_free_list.next,
@@ -3177,8 +3112,24 @@ static int airo_thread(void *data) {
        return 0;
 }
 
-static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
-       struct net_device *dev = (struct net_device *)dev_id;
+static int header_len(__le16 ctl)
+{
+       u16 fc = le16_to_cpu(ctl);
+       switch (fc & 0xc) {
+       case 4:
+               if ((fc & 0xe0) == 0xc0)
+                       return 10;      /* one-address control packet */
+               return 16;      /* two-address control packet */
+       case 8:
+               if ((fc & 0x300) == 0x300)
+                       return 30;      /* WDS packet */
+       }
+       return 24;
+}
+
+static irqreturn_t airo_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
        u16 status;
        u16 fid;
        struct airo_info *apriv = dev->priv;
@@ -3281,19 +3232,20 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                /* Check to see if there is something to receive */
                if ( status & EV_RX  ) {
                        struct sk_buff *skb = NULL;
-                       u16 fc, len, hdrlen = 0;
+                       __le16 fc, v;
+                       u16 len, hdrlen = 0;
 #pragma pack(1)
                        struct {
-                               u16 status, len;
+                               __le16 status, len;
                                u8 rssi[2];
                                u8 rate;
                                u8 freq;
-                               u16 tmp[4];
+                               __le16 tmp[4];
                        } hdr;
 #pragma pack()
                        u16 gap;
-                       u16 tmpbuf[4];
-                       u16 *buffer;
+                       __le16 tmpbuf[4];
+                       __le16 *buffer;
 
                        if (test_bit(FLAG_MPI,&apriv->flags)) {
                                if (test_bit(FLAG_802_11, &apriv->flags))
@@ -3309,7 +3261,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                        /* Get the packet length */
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
                                bap_setup (apriv, fid, 4, BAP0);
-                               bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0);
+                               bap_read (apriv, (__le16*)&hdr, sizeof(hdr), BAP0);
                                /* Bad CRC. Ignore packet */
                                if (le16_to_cpu(hdr.status) & 2)
                                        hdr.len = 0;
@@ -3317,7 +3269,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                                        hdr.len = 0;
                        } else {
                                bap_setup (apriv, fid, 0x36, BAP0);
-                               bap_read (apriv, (u16*)&hdr.len, 2, BAP0);
+                               bap_read (apriv, &hdr.len, 2, BAP0);
                        }
                        len = le16_to_cpu(hdr.len);
 
@@ -3329,23 +3281,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                                goto badrx;
 
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
-                               bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0);
-                               fc = le16_to_cpu(fc);
-                               switch (fc & 0xc) {
-                                       case 4:
-                                               if ((fc & 0xe0) == 0xc0)
-                                                       hdrlen = 10;
-                                               else
-                                                       hdrlen = 16;
-                                               break;
-                                       case 8:
-                                               if ((fc&0x300)==0x300){
-                                                       hdrlen = 30;
-                                                       break;
-                                               }
-                                       default:
-                                               hdrlen = 24;
-                               }
+                               bap_read (apriv, &fc, sizeof(fc), BAP0);
+                               hdrlen = header_len(fc);
                        } else
                                hdrlen = ETH_ALEN * 2;
 
@@ -3355,15 +3292,15 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                                goto badrx;
                        }
                        skb_reserve(skb, 2); /* This way the IP header is aligned */
-                       buffer = (u16*)skb_put (skb, len + hdrlen);
+                       buffer = (__le16*)skb_put (skb, len + hdrlen);
                        if (test_bit(FLAG_802_11, &apriv->flags)) {
                                buffer[0] = fc;
                                bap_read (apriv, buffer + 1, hdrlen - 2, BAP0);
                                if (hdrlen == 24)
                                        bap_read (apriv, tmpbuf, 6, BAP0);
 
-                               bap_read (apriv, &gap, sizeof(gap), BAP0);
-                               gap = le16_to_cpu(gap);
+                               bap_read (apriv, &v, sizeof(v), BAP0);
+                               gap = le16_to_cpu(v);
                                if (gap) {
                                        if (gap <= 8) {
                                                bap_read (apriv, tmpbuf, gap, BAP0);
@@ -3377,7 +3314,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id) {
                                MICBuffer micbuf;
                                bap_read (apriv, buffer, ETH_ALEN*2, BAP0);
                                if (apriv->micstats.enabled) {
-                                       bap_read (apriv,(u16*)&micbuf,sizeof(micbuf),BAP0);
+                                       bap_read (apriv,(__le16*)&micbuf,sizeof(micbuf),BAP0);
                                        if (ntohs(micbuf.typelen) > 0x05DC)
                                                bap_setup (apriv, fid, 0x44, BAP0);
                                        else {
@@ -3405,7 +3342,7 @@ badrx:
                                if (!test_bit(FLAG_802_11, &apriv->flags)) {
                                        sa = (char*)buffer + 6;
                                        bap_setup (apriv, fid, 8, BAP0);
-                                       bap_read (apriv, (u16*)hdr.rssi, 2, BAP0);
+                                       bap_read (apriv, (__le16*)hdr.rssi, 2, BAP0);
                                } else
                                        sa = (char*)buffer + 10;
                                wstats.qual = hdr.rssi[0];
@@ -3676,14 +3613,15 @@ void mpi_receive_802_11 (struct airo_info *ai)
 {
        RxFid rxd;
        struct sk_buff *skb = NULL;
-       u16 fc, len, hdrlen = 0;
+       u16 len, hdrlen = 0;
+       __le16 fc;
 #pragma pack(1)
        struct {
-               u16 status, len;
+               __le16 status, len;
                u8 rssi[2];
                u8 rate;
                u8 freq;
-               u16 tmp[4];
+               __le16 tmp[4];
        } hdr;
 #pragma pack()
        u16 gap;
@@ -3706,23 +3644,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
        if (len == 0)
                goto badrx;
 
-       memcpy ((char *)&fc, ptr, sizeof(fc));
-       fc = le16_to_cpu(fc);
-       switch (fc & 0xc) {
-               case 4:
-                       if ((fc & 0xe0) == 0xc0)
-                               hdrlen = 10;
-                       else
-                               hdrlen = 16;
-                       break;
-               case 8:
-                       if ((fc&0x300)==0x300){
-                               hdrlen = 30;
-                               break;
-                       }
-               default:
-                       hdrlen = 24;
-       }
+       fc = get_unaligned((__le16 *)ptr);
+       hdrlen = header_len(fc);
 
        skb = dev_alloc_skb( len + hdrlen + 2 );
        if ( !skb ) {
@@ -3734,9 +3657,8 @@ void mpi_receive_802_11 (struct airo_info *ai)
        ptr += hdrlen;
        if (hdrlen == 24)
                ptr += 6;
-       memcpy ((char *)&gap, ptr, sizeof(gap));
-       ptr += sizeof(gap);
-       gap = le16_to_cpu(gap);
+       gap = le16_to_cpu(get_unaligned((__le16 *)ptr));
+       ptr += sizeof(__le16);
        if (gap) {
                if (gap <= 8)
                        ptr += gap;
@@ -3788,7 +3710,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
        int status;
        int i;
        SsidRid mySsid;
-       u16 lastindex;
+       __le16 lastindex;
        WepKeyRid wkr;
        int rc;
 
@@ -3850,7 +3772,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
                else {
                        kfree(ai->rssi);
                        ai->rssi = NULL;
-                       if (cap_rid.softCap & 8)
+                       if (cap_rid.softCap & cpu_to_le16(8))
                                ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
                        else
                                airo_print_warn(ai->dev->name, "unknown received signal "
@@ -3860,8 +3782,9 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
                ai->config.authType = AUTH_OPEN;
                ai->config.modulation = MOD_CCK;
 
-               if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1) &&
-                   (micsetup(ai) == SUCCESS)) {
+               if (le16_to_cpu(cap_rid.len) >= sizeof(cap_rid) &&
+                   (cap_rid.extSoftCap & cpu_to_le16(1)) &&
+                   micsetup(ai) == SUCCESS) {
                        ai->config.opmode |= MODE_MIC;
                        set_bit(FLAG_MIC_CAPABLE, &ai->flags);
                }
@@ -3897,13 +3820,13 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
        if ( ssids[0] ) {
                int i;
                for( i = 0; i < 3 && ssids[i]; i++ ) {
-                       mySsid.ssids[i].len = strlen(ssids[i]);
-                       if ( mySsid.ssids[i].len > 32 )
-                               mySsid.ssids[i].len = 32;
-                       memcpy(mySsid.ssids[i].ssid, ssids[i],
-                              mySsid.ssids[i].len);
+                       size_t len = strlen(ssids[i]);
+                       if (len > 32)
+                               len = 32;
+                       mySsid.ssids[i].len = cpu_to_le16(len);
+                       memcpy(mySsid.ssids[i].ssid, ssids[i], len);
                }
-               mySsid.len = sizeof(mySsid);
+               mySsid.len = cpu_to_le16(sizeof(mySsid));
        }
 
        status = writeConfigRid(ai, lock);
@@ -3923,7 +3846,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
        rc = readWepKeyRid(ai, &wkr, 1, lock);
        if (rc == SUCCESS) do {
                lastindex = wkr.kindex;
-               if (wkr.kindex == 0xffff) {
+               if (wkr.kindex == cpu_to_le16(0xffff)) {
                        ai->defindex = wkr.mac[0];
                }
                rc = readWepKeyRid(ai, &wkr, 0, lock);
@@ -4038,7 +3961,7 @@ static u16 aux_setup(struct airo_info *ai, u16 page,
 }
 
 /* requires call to bap_setup() first */
-static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
+static int aux_bap_read(struct airo_info *ai, __le16 *pu16Dst,
                        int bytelen, int whichbap)
 {
        u16 len;
@@ -4075,7 +3998,7 @@ static int aux_bap_read(struct airo_info *ai, u16 *pu16Dst,
 
 
 /* requires call to bap_setup() first */
-static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
+static int fast_bap_read(struct airo_info *ai, __le16 *pu16Dst,
                         int bytelen, int whichbap)
 {
        bytelen = (bytelen + 1) & (~1); // round up to even value
@@ -4087,7 +4010,7 @@ static int fast_bap_read(struct airo_info *ai, u16 *pu16Dst,
 }
 
 /* requires call to bap_setup() first */
-static int bap_write(struct airo_info *ai, const u16 *pu16Src,
+static int bap_write(struct airo_info *ai, const __le16 *pu16Src,
                     int bytelen, int whichbap)
 {
        bytelen = (bytelen + 1) & (~1); // round up to even value
@@ -4163,7 +4086,7 @@ static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, in
                // read the rid length field
                bap_read(ai, pBuf, 2, BAP1);
                // length for remaining part of rid
-               len = min(len, (int)le16_to_cpu(*(u16*)pBuf)) - 2;
+               len = min(len, (int)le16_to_cpu(*(__le16*)pBuf)) - 2;
 
                if ( len <= 2 ) {
                        airo_print_err(ai->dev->name,
@@ -4173,7 +4096,7 @@ static int PC4500_readrid(struct airo_info *ai, u16 rid, void *pBuf, int len, in
                        goto done;
                }
                // read remainder of the rid
-               rc = bap_read(ai, ((u16*)pBuf)+1, len, BAP1);
+               rc = bap_read(ai, ((__le16*)pBuf)+1, len, BAP1);
        }
 done:
        if (lock)
@@ -4189,7 +4112,7 @@ static int PC4500_writerid(struct airo_info *ai, u16 rid,
        u16 status;
        int rc = SUCCESS;
 
-       *(u16*)pBuf = cpu_to_le16((u16)len);
+       *(__le16*)pBuf = cpu_to_le16((u16)len);
 
        if (lock) {
                if (down_interruptible(&ai->sem))
@@ -4263,7 +4186,7 @@ static u16 transmit_allocate(struct airo_info *ai, int lenPayload, int raw)
        Cmd cmd;
        Resp rsp;
        u16 txFid;
-       u16 txControl;
+       __le16 txControl;
 
        cmd.cmd = CMD_ALLOCATETX;
        cmd.parm0 = lenPayload;
@@ -4317,7 +4240,7 @@ done:
    Make sure the BAP1 spinlock is held when this is called. */
 static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 {
-       u16 payloadLen;
+       __le16 payloadLen;
        Cmd cmd;
        Resp rsp;
        int miclen = 0;
@@ -4333,7 +4256,7 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
        len -= ETH_ALEN * 2;
 
        if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && 
-           (ntohs(((u16 *)pPacket)[6]) != 0x888E)) {
+           (ntohs(((__be16 *)pPacket)[6]) != 0x888E)) {
                if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS)
                        return ERROR;
                miclen = sizeof(pMic);
@@ -4345,10 +4268,10 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
         * we have to subtract the 12 bytes for the addresses off */
        payloadLen = cpu_to_le16(len + miclen);
        bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
-       bap_write(ai, (const u16*)pPacket, sizeof(etherHead), BAP1);
+       bap_write(ai, (__le16*)pPacket, sizeof(etherHead), BAP1);
        if (miclen)
-               bap_write(ai, (const u16*)&pMic, miclen, BAP1);
-       bap_write(ai, (const u16*)(pPacket + sizeof(etherHead)), len, BAP1);
+               bap_write(ai, (__le16*)&pMic, miclen, BAP1);
+       bap_write(ai, (__le16*)(pPacket + sizeof(etherHead)), len, BAP1);
        // issue the transmit command
        memset( &cmd, 0, sizeof( cmd ) );
        cmd.cmd = CMD_TRANSMIT;
@@ -4360,35 +4283,17 @@ static int transmit_802_3_packet(struct airo_info *ai, int len, char *pPacket)
 
 static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
 {
-       u16 fc, payloadLen;
+       __le16 fc, payloadLen;
        Cmd cmd;
        Resp rsp;
        int hdrlen;
-       struct {
-               u8 addr4[ETH_ALEN];
-               u16 gaplen;
-               u8 gap[6];
-       } gap;
+       static u8 tail[(30-10) + 2 + 6] = {[30-10] = 6};
+       /* padding of header to full size + le16 gaplen (6) + gaplen bytes */
        u16 txFid = len;
        len >>= 16;
-       gap.gaplen = 6;
 
-       fc = le16_to_cpu(*(const u16*)pPacket);
-       switch (fc & 0xc) {
-               case 4:
-                       if ((fc & 0xe0) == 0xc0)
-                               hdrlen = 10;
-                       else
-                               hdrlen = 16;
-                       break;
-               case 8:
-                       if ((fc&0x300)==0x300){
-                               hdrlen = 30;
-                               break;
-                       }
-               default:
-                       hdrlen = 24;
-       }
+       fc = *(__le16*)pPacket;
+       hdrlen = header_len(fc);
 
        if (len < hdrlen) {
                airo_print_warn(ai->dev->name, "Short packet %d", len);
@@ -4403,11 +4308,10 @@ static int transmit_802_11_packet(struct airo_info *ai, int len, char *pPacket)
        payloadLen = cpu_to_le16(len-hdrlen);
        bap_write(ai, &payloadLen, sizeof(payloadLen),BAP1);
        if (bap_setup(ai, txFid, 0x0014, BAP1) != SUCCESS) return ERROR;
-       bap_write(ai, (const u16*)pPacket, hdrlen, BAP1);
-       bap_write(ai, hdrlen == 30 ?
-               (const u16*)&gap.gaplen : (const u16*)&gap, 38 - hdrlen, BAP1);
+       bap_write(ai, (__le16 *)pPacket, hdrlen, BAP1);
+       bap_write(ai, (__le16 *)(tail + (hdrlen - 10)), 38 - hdrlen, BAP1);
 
-       bap_write(ai, (const u16*)(pPacket + hdrlen), len - hdrlen, BAP1);
+       bap_write(ai, (__le16 *)(pPacket + hdrlen), len - hdrlen, BAP1);
        // issue the transmit command
        memset( &cmd, 0, sizeof( cmd ) );
        cmd.cmd = CMD_TRANSMIT;
@@ -4722,13 +4626,15 @@ static ssize_t proc_write( struct file *file,
        return len;
 }
 
-static int proc_status_open( struct inode *inode, struct file *file ) {
+static int proc_status_open(struct inode *inode, struct file *file)
+{
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
        struct airo_info *apriv = dev->priv;
        CapabilityRid cap_rid;
        StatusRid status_rid;
+       u16 mode;
        int i;
 
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
@@ -4742,16 +4648,18 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
        readStatusRid(apriv, &status_rid, 1);
        readCapabilityRid(apriv, &cap_rid, 1);
 
+       mode = le16_to_cpu(status_rid.mode);
+
         i = sprintf(data->rbuffer, "Status: %s%s%s%s%s%s%s%s%s\n",
-                    status_rid.mode & 1 ? "CFG ": "",
-                    status_rid.mode & 2 ? "ACT ": "",
-                    status_rid.mode & 0x10 ? "SYN ": "",
-                    status_rid.mode & 0x20 ? "LNK ": "",
-                    status_rid.mode & 0x40 ? "LEAP ": "",
-                    status_rid.mode & 0x80 ? "PRIV ": "",
-                    status_rid.mode & 0x100 ? "KEY ": "",
-                    status_rid.mode & 0x200 ? "WEP ": "",
-                    status_rid.mode & 0x8000 ? "ERR ": "");
+                    mode & 1 ? "CFG ": "",
+                    mode & 2 ? "ACT ": "",
+                    mode & 0x10 ? "SYN ": "",
+                    mode & 0x20 ? "LNK ": "",
+                    mode & 0x40 ? "LEAP ": "",
+                    mode & 0x80 ? "PRIV ": "",
+                    mode & 0x100 ? "KEY ": "",
+                    mode & 0x200 ? "WEP ": "",
+                    mode & 0x8000 ? "ERR ": "");
        sprintf( data->rbuffer+i, "Mode: %x\n"
                 "Signal Strength: %d\n"
                 "Signal Quality: %d\n"
@@ -4764,24 +4672,24 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
                 "Radio type: %x\nCountry: %x\nHardware Version: %x\n"
                 "Software Version: %x\nSoftware Subversion: %x\n"
                 "Boot block version: %x\n",
-                (int)status_rid.mode,
-                (int)status_rid.normalizedSignalStrength,
-                (int)status_rid.signalQuality,
-                (int)status_rid.SSIDlen,
+                le16_to_cpu(status_rid.mode),
+                le16_to_cpu(status_rid.normalizedSignalStrength),
+                le16_to_cpu(status_rid.signalQuality),
+                le16_to_cpu(status_rid.SSIDlen),
                 status_rid.SSID,
                 status_rid.apName,
-                (int)status_rid.channel,
-                (int)status_rid.currentXmitRate/2,
+                le16_to_cpu(status_rid.channel),
+                le16_to_cpu(status_rid.currentXmitRate) / 2,
                 version,
                 cap_rid.prodName,
                 cap_rid.manName,
                 cap_rid.prodVer,
-                cap_rid.radioType,
-                cap_rid.country,
-                cap_rid.hardVer,
-                (int)cap_rid.softVer,
-                (int)cap_rid.softSubVer,
-                (int)cap_rid.bootBlockVer );
+                le16_to_cpu(cap_rid.radioType),
+                le16_to_cpu(cap_rid.country),
+                le16_to_cpu(cap_rid.hardVer),
+                le16_to_cpu(cap_rid.softVer),
+                le16_to_cpu(cap_rid.softSubVer),
+                le16_to_cpu(cap_rid.bootBlockVer));
        data->readlen = strlen( data->rbuffer );
        return 0;
 }
@@ -4801,14 +4709,16 @@ static int proc_stats_open( struct inode *inode, struct file *file ) {
 
 static int proc_stats_rid_open( struct inode *inode,
                                struct file *file,
-                               u16 rid ) {
+                               u16 rid )
+{
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
        struct airo_info *apriv = dev->priv;
        StatsRid stats;
        int i, j;
-       u32 *vals = stats.vals;
+       __le32 *vals = stats.vals;
+       int len = le16_to_cpu(stats.len);
 
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -4821,17 +4731,17 @@ static int proc_stats_rid_open( struct inode *inode,
        readStatsRid(apriv, &stats, rid, 1);
 
         j = 0;
-       for(i=0; statsLabels[i]!=(char *)-1 &&
-                   i*4<stats.len; i++){
+       for(i=0; statsLabels[i]!=(char *)-1 && i*4<len; i++) {
                if (!statsLabels[i]) continue;
                if (j+strlen(statsLabels[i])+16>4096) {
                        airo_print_warn(apriv->dev->name,
                               "Potentially disasterous buffer overflow averted!");
                        break;
                }
-               j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i], vals[i]);
+               j+=sprintf(data->rbuffer+j, "%s: %u\n", statsLabels[i],
+                               le32_to_cpu(vals[i]));
        }
-       if (i*4>=stats.len){
+       if (i*4 >= len) {
                airo_print_warn(apriv->dev->name, "Got a short rid");
        }
        data->readlen = j;
@@ -4856,7 +4766,14 @@ static int airo_config_commit(struct net_device *dev,
                              struct iw_request_info *info, void *zwrq,
                              char *extra);
 
-static void proc_config_on_close( struct inode *inode, struct file *file ) {
+static inline int sniffing_mode(struct airo_info *ai)
+{
+       return le16_to_cpu(ai->config.rmode & RXMODE_MASK) >=
+               le16_to_cpu(RXMODE_RFMON);
+}
+
+static void proc_config_on_close(struct inode *inode, struct file *file)
+{
        struct proc_data *data = file->private_data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
@@ -4873,16 +4790,16 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
 /*** Mode processing */
                if ( !strncmp( line, "Mode: ", 6 ) ) {
                        line += 6;
-                       if ((ai->config.rmode & 0xff) >= RXMODE_RFMON)
-                                       set_bit (FLAG_RESET, &ai->flags);
-                       ai->config.rmode &= 0xfe00;
+                       if (sniffing_mode(ai))
+                               set_bit (FLAG_RESET, &ai->flags);
+                       ai->config.rmode &= ~RXMODE_FULL_MASK;
                        clear_bit (FLAG_802_11, &ai->flags);
-                       ai->config.opmode &= 0xFF00;
+                       ai->config.opmode &= ~MODE_CFG_MASK;
                        ai->config.scanMode = SCANMODE_ACTIVE;
                        if ( line[0] == 'a' ) {
-                               ai->config.opmode |= 0;
+                               ai->config.opmode |= MODE_STA_IBSS;
                        } else {
-                               ai->config.opmode |= 1;
+                               ai->config.opmode |= MODE_STA_ESS;
                                if ( line[0] == 'r' ) {
                                        ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
                                        ai->config.scanMode = SCANMODE_PASSIVE;
@@ -4948,7 +4865,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 9;
                        v = get_dec_u16(line, &i, i+3);
                        if ( v != -1 ) {
-                               ai->config.channelSet = (u16)v;
+                               ai->config.channelSet = cpu_to_le16(v);
                                set_bit (FLAG_COMMIT, &ai->flags);
                        }
                } else if ( !strncmp( line, "XmitPower: ", 11 ) ) {
@@ -4956,20 +4873,20 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 11;
                        v = get_dec_u16(line, &i, i+3);
                        if ( v != -1 ) {
-                               ai->config.txPower = (u16)v;
+                               ai->config.txPower = cpu_to_le16(v);
                                set_bit (FLAG_COMMIT, &ai->flags);
                        }
                } else if ( !strncmp( line, "WEP: ", 5 ) ) {
                        line += 5;
                        switch( line[0] ) {
                        case 's':
-                               ai->config.authType = (u16)AUTH_SHAREDKEY;
+                               ai->config.authType = AUTH_SHAREDKEY;
                                break;
                        case 'e':
-                               ai->config.authType = (u16)AUTH_ENCRYPT;
+                               ai->config.authType = AUTH_ENCRYPT;
                                break;
                        default:
-                               ai->config.authType = (u16)AUTH_OPEN;
+                               ai->config.authType = AUTH_OPEN;
                                break;
                        }
                        set_bit (FLAG_COMMIT, &ai->flags);
@@ -4979,7 +4896,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 16;
                        v = get_dec_u16(line, &i, 3);
                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
-                       ai->config.longRetryLimit = (u16)v;
+                       ai->config.longRetryLimit = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "ShortRetryLimit: ", 17 ) ) {
                        int v, i = 0;
@@ -4987,7 +4904,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 17;
                        v = get_dec_u16(line, &i, 3);
                        v = (v<0) ? 0 : ((v>255) ? 255 : v);
-                       ai->config.shortRetryLimit = (u16)v;
+                       ai->config.shortRetryLimit = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "RTSThreshold: ", 14 ) ) {
                        int v, i = 0;
@@ -4995,7 +4912,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 14;
                        v = get_dec_u16(line, &i, 4);
                        v = (v<0) ? 0 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
-                       ai->config.rtsThres = (u16)v;
+                       ai->config.rtsThres = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "TXMSDULifetime: ", 16 ) ) {
                        int v, i = 0;
@@ -5003,7 +4920,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 16;
                        v = get_dec_u16(line, &i, 5);
                        v = (v<0) ? 0 : v;
-                       ai->config.txLifetime = (u16)v;
+                       ai->config.txLifetime = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "RXMSDULifetime: ", 16 ) ) {
                        int v, i = 0;
@@ -5011,7 +4928,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        line += 16;
                        v = get_dec_u16(line, &i, 5);
                        v = (v<0) ? 0 : v;
-                       ai->config.rxLifetime = (u16)v;
+                       ai->config.rxLifetime = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if ( !strncmp( line, "TXDiversity: ", 13 ) ) {
                        ai->config.txDiversity =
@@ -5030,7 +4947,7 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
                        v = get_dec_u16(line, &i, 4);
                        v = (v<256) ? 256 : ((v>AIRO_DEF_MTU) ? AIRO_DEF_MTU : v);
                        v = v & 0xfffe; /* Make sure its even */
-                       ai->config.fragThresh = (u16)v;
+                       ai->config.fragThresh = cpu_to_le16(v);
                        set_bit (FLAG_COMMIT, &ai->flags);
                } else if (!strncmp(line, "Modulation: ", 12)) {
                        line += 12;
@@ -5057,8 +4974,9 @@ static void proc_config_on_close( struct inode *inode, struct file *file ) {
        airo_config_commit(dev, NULL, NULL, NULL);
 }
 
-static char *get_rmode(u16 mode) {
-        switch(mode&0xff) {
+static char *get_rmode(__le16 mode)
+{
+        switch(mode & RXMODE_MASK) {
         case RXMODE_RFMON:  return "rfmon";
         case RXMODE_RFMON_ANYBSS:  return "yna (any) bss rfmon";
         case RXMODE_LANMON:  return "lanmon";
@@ -5066,12 +4984,14 @@ static char *get_rmode(u16 mode) {
         return "ESS";
 }
 
-static int proc_config_open( struct inode *inode, struct file *file ) {
+static int proc_config_open(struct inode *inode, struct file *file)
+{
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
        struct airo_info *ai = dev->priv;
        int i;
+       __le16 mode;
 
        if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
                return -ENOMEM;
@@ -5090,6 +5010,7 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
 
        readConfigRid(ai, 1);
 
+       mode = ai->config.opmode & MODE_CFG_MASK;
        i = sprintf( data->rbuffer,
                     "Mode: %s\n"
                     "Radio: %s\n"
@@ -5098,15 +5019,16 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
                     "DataRates: %d %d %d %d %d %d %d %d\n"
                     "Channel: %d\n"
                     "XmitPower: %d\n",
-                    (ai->config.opmode & 0xFF) == 0 ? "adhoc" :
-                    (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode):
-                    (ai->config.opmode & 0xFF) == 2 ? "AP" :
-                    (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error",
+                    mode == MODE_STA_IBSS ? "adhoc" :
+                    mode == MODE_STA_ESS ? get_rmode(ai->config.rmode):
+                    mode == MODE_AP ? "AP" :
+                    mode == MODE_AP_RPTR ? "AP RPTR" : "Error",
                     test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on",
                     ai->config.nodeName,
-                    ai->config.powerSaveMode == 0 ? "CAM" :
-                    ai->config.powerSaveMode == 1 ? "PSP" :
-                    ai->config.powerSaveMode == 2 ? "PSPCAM" : "Error",
+                    ai->config.powerSaveMode == POWERSAVE_CAM ? "CAM" :
+                    ai->config.powerSaveMode == POWERSAVE_PSP ? "PSP" :
+                    ai->config.powerSaveMode == POWERSAVE_PSPCAM ? "PSPCAM" :
+                    "Error",
                     (int)ai->config.rates[0],
                     (int)ai->config.rates[1],
                     (int)ai->config.rates[2],
@@ -5115,8 +5037,8 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
                     (int)ai->config.rates[5],
                     (int)ai->config.rates[6],
                     (int)ai->config.rates[7],
-                    (int)ai->config.channelSet,
-                    (int)ai->config.txPower
+                    le16_to_cpu(ai->config.channelSet),
+                    le16_to_cpu(ai->config.txPower)
                );
        sprintf( data->rbuffer + i,
                 "LongRetryLimit: %d\n"
@@ -5130,19 +5052,19 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
                 "WEP: %s\n"
                 "Modulation: %s\n"
                 "Preamble: %s\n",
-                (int)ai->config.longRetryLimit,
-                (int)ai->config.shortRetryLimit,
-                (int)ai->config.rtsThres,
-                (int)ai->config.txLifetime,
-                (int)ai->config.rxLifetime,
+                le16_to_cpu(ai->config.longRetryLimit),
+                le16_to_cpu(ai->config.shortRetryLimit),
+                le16_to_cpu(ai->config.rtsThres),
+                le16_to_cpu(ai->config.txLifetime),
+                le16_to_cpu(ai->config.rxLifetime),
                 ai->config.txDiversity == 1 ? "left" :
                 ai->config.txDiversity == 2 ? "right" : "both",
                 ai->config.rxDiversity == 1 ? "left" :
                 ai->config.rxDiversity == 2 ? "right" : "both",
-                (int)ai->config.fragThresh,
+                le16_to_cpu(ai->config.fragThresh),
                 ai->config.authType == AUTH_ENCRYPT ? "encrypt" :
                 ai->config.authType == AUTH_SHAREDKEY ? "shared" : "open",
-                ai->config.modulation == 0 ? "default" :
+                ai->config.modulation == MOD_DEFAULT ? "default" :
                 ai->config.modulation == MOD_CCK ? "cck" :
                 ai->config.modulation == MOD_MOK ? "mok" : "error",
                 ai->config.preamble == PREAMBLE_AUTO ? "auto" :
@@ -5153,34 +5075,38 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
        return 0;
 }
 
-static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
+static void proc_SSID_on_close(struct inode *inode, struct file *file)
+{
        struct proc_data *data = (struct proc_data *)file->private_data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
        struct airo_info *ai = dev->priv;
        SsidRid SSID_rid;
        int i;
-       int offset = 0;
+       char *p = data->wbuffer;
+       char *end = p + data->writelen;
 
-       if ( !data->writelen ) return;
+       if (!data->writelen)
+               return;
 
-       memset( &SSID_rid, 0, sizeof( SSID_rid ) );
+       *end = '\n'; /* sentinel; we have space for it */
 
-       for( i = 0; i < 3; i++ ) {
-               int j;
-               for( j = 0; j+offset < data->writelen && j < 32 &&
-                            data->wbuffer[offset+j] != '\n'; j++ ) {
-                       SSID_rid.ssids[i].ssid[j] = data->wbuffer[offset+j];
-               }
-               if ( j == 0 ) break;
-               SSID_rid.ssids[i].len = j;
-               offset += j;
-               while( data->wbuffer[offset] != '\n' &&
-                      offset < data->writelen ) offset++;
-               offset++;
+       memset(&SSID_rid, 0, sizeof(SSID_rid));
+
+       for (i = 0; i < 3 && p < end; i++) {
+               int j = 0;
+               /* copy up to 32 characters from this line */
+               while (*p != '\n' && j < 32)
+                       SSID_rid.ssids[i].ssid[j++] = *p++;
+               if (j == 0)
+                       break;
+               SSID_rid.ssids[i].len = cpu_to_le16(j);
+               /* skip to the beginning of the next line */
+               while (*p++ != '\n')
+                       ;
        }
        if (i)
-               SSID_rid.len = sizeof(SSID_rid);
+               SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
        disable_MAC(ai, 1);
        writeSsidRid(ai, &SSID_rid, 1);
        enable_MAC(ai, 1);
@@ -5204,7 +5130,7 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) {
        if ( !data->writelen ) return;
 
        memset( &APList_rid, 0, sizeof(APList_rid) );
-       APList_rid.len = sizeof(APList_rid);
+       APList_rid.len = cpu_to_le16(sizeof(APList_rid));
 
        for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
                int j;
@@ -5244,39 +5170,40 @@ static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
 static int get_wep_key(struct airo_info *ai, u16 index) {
        WepKeyRid wkr;
        int rc;
-       u16 lastindex;
+       __le16 lastindex;
 
        rc = readWepKeyRid(ai, &wkr, 1, 1);
        if (rc == SUCCESS) do {
                lastindex = wkr.kindex;
-               if (wkr.kindex == index) {
+               if (wkr.kindex == cpu_to_le16(index)) {
                        if (index == 0xffff) {
                                return wkr.mac[0];
                        }
-                       return wkr.klen;
+                       return le16_to_cpu(wkr.klen);
                }
                readWepKeyRid(ai, &wkr, 0, 1);
-       } while(lastindex != wkr.kindex);
+       } while (lastindex != wkr.kindex);
        return -1;
 }
 
 static int set_wep_key(struct airo_info *ai, u16 index,
-                      const char *key, u16 keylen, int perm, int lock ) {
+                      const char *key, u16 keylen, int perm, int lock )
+{
        static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
        WepKeyRid wkr;
 
        memset(&wkr, 0, sizeof(wkr));
        if (keylen == 0) {
 // We are selecting which key to use
-               wkr.len = sizeof(wkr);
-               wkr.kindex = 0xffff;
+               wkr.len = cpu_to_le16(sizeof(wkr));
+               wkr.kindex = cpu_to_le16(0xffff);
                wkr.mac[0] = (char)index;
                if (perm) ai->defindex = (char)index;
        } else {
 // We are actually setting the key
-               wkr.len = sizeof(wkr);
-               wkr.kindex = index;
-               wkr.klen = keylen;
+               wkr.len = cpu_to_le16(sizeof(wkr));
+               wkr.kindex = cpu_to_le16(index);
+               wkr.klen = cpu_to_le16(keylen);
                memcpy( wkr.key, key, keylen );
                memcpy( wkr.mac, macaddr, ETH_ALEN );
        }
@@ -5328,14 +5255,15 @@ static void proc_wepkey_on_close( struct inode *inode, struct file *file ) {
        set_wep_key(ai, index, key, i/3, 1, 1);
 }
 
-static int proc_wepkey_open( struct inode *inode, struct file *file ) {
+static int proc_wepkey_open( struct inode *inode, struct file *file )
+{
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
        struct airo_info *ai = dev->priv;
        char *ptr;
        WepKeyRid wkr;
-       u16 lastindex;
+       __le16 lastindex;
        int j=0;
        int rc;
 
@@ -5361,12 +5289,13 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
        rc = readWepKeyRid(ai, &wkr, 1, 1);
        if (rc == SUCCESS) do {
                lastindex = wkr.kindex;
-               if (wkr.kindex == 0xffff) {
+               if (wkr.kindex == cpu_to_le16(0xffff)) {
                        j += sprintf(ptr+j, "Tx key = %d\n",
                                     (int)wkr.mac[0]);
                } else {
                        j += sprintf(ptr+j, "Key %d set with length = %d\n",
-                                    (int)wkr.kindex, (int)wkr.klen);
+                                    le16_to_cpu(wkr.kindex),
+                                    le16_to_cpu(wkr.klen));
                }
                readWepKeyRid(ai, &wkr, 0, 1);
        } while((lastindex != wkr.kindex) && (j < 180-30));
@@ -5375,7 +5304,8 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
        return 0;
 }
 
-static int proc_SSID_open( struct inode *inode, struct file *file ) {
+static int proc_SSID_open(struct inode *inode, struct file *file)
+{
        struct proc_data *data;
        struct proc_dir_entry *dp = PDE(inode);
        struct net_device *dev = dp->data;
@@ -5393,7 +5323,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
        }
        data->writelen = 0;
        data->maxwritelen = 33*3;
-       if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
+       /* allocate maxwritelen + 1; we'll want a sentinel */
+       if ((data->wbuffer = kzalloc(33*3 + 1, GFP_KERNEL)) == NULL) {
                kfree (data->rbuffer);
                kfree (file->private_data);
                return -ENOMEM;
@@ -5402,14 +5333,15 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
 
        readSsidRid(ai, &SSID_rid);
        ptr = data->rbuffer;
-       for( i = 0; i < 3; i++ ) {
+       for (i = 0; i < 3; i++) {
                int j;
-               if ( !SSID_rid.ssids[i].len ) break;
-               for( j = 0; j < 32 &&
-                            j < SSID_rid.ssids[i].len &&
-                            SSID_rid.ssids[i].ssid[j]; j++ ) {
+               size_t len = le16_to_cpu(SSID_rid.ssids[i].len);
+               if (!len)
+                       break;
+               if (len > 32)
+                       len = 32;
+               for (j = 0; j < len && SSID_rid.ssids[i].ssid[j]; j++)
                        *ptr++ = SSID_rid.ssids[i].ssid[j];
-               }
                *ptr++ = '\n';
        }
        *ptr = '\0';
@@ -5505,14 +5437,14 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
            Since it is a rare condition, we'll just live with it, otherwise
            we have to add a spin lock... */
        rc = readBSSListRid(ai, doLoseSync, &BSSList_rid);
-       while(rc == 0 && BSSList_rid.index != 0xffff) {
+       while(rc == 0 && BSSList_rid.index != cpu_to_le16(0xffff)) {
                ptr += sprintf(ptr, "%s %*s rssi = %d",
                               print_mac(mac, BSSList_rid.bssid),
                                (int)BSSList_rid.ssidLen,
                                BSSList_rid.ssid,
-                               (int)BSSList_rid.dBm);
+                               le16_to_cpu(BSSList_rid.dBm));
                ptr += sprintf(ptr, " channel = %d %s %s %s %s\n",
-                               (int)BSSList_rid.dsChannel,
+                               le16_to_cpu(BSSList_rid.dsChannel),
                                BSSList_rid.cap & CAP_ESS ? "ESS" : "",
                                BSSList_rid.cap & CAP_IBSS ? "adhoc" : "",
                                BSSList_rid.cap & CAP_PRIVACY ? "wep" : "",
@@ -5780,21 +5712,27 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm)
 static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid)
 {
        int quality = 0;
+       u16 sq;
 
-       if ((status_rid->mode & 0x3f) == 0x3f && (cap_rid->hardCap & 8)) {
-               if (memcmp(cap_rid->prodName, "350", 3))
-                       if (status_rid->signalQuality > 0x20)
-                               quality = 0;
-                       else
-                               quality = 0x20 - status_rid->signalQuality;
+       if ((status_rid->mode & cpu_to_le16(0x3f)) != cpu_to_le16(0x3f))
+               return 0;
+
+       if (!(cap_rid->hardCap & cpu_to_le16(8)))
+               return 0;
+
+       sq = le16_to_cpu(status_rid->signalQuality);
+       if (memcmp(cap_rid->prodName, "350", 3))
+               if (sq > 0x20)
+                       quality = 0;
                else
-                       if (status_rid->signalQuality > 0xb0)
-                               quality = 0;
-                       else if (status_rid->signalQuality < 0x10)
-                               quality = 0xa0;
-                       else
-                               quality = 0xb0 - status_rid->signalQuality;
-       }
+                       quality = 0x20 - sq;
+       else
+               if (sq > 0xb0)
+                       quality = 0;
+               else if (sq < 0x10)
+                       quality = 0xa0;
+               else
+                       quality = 0xb0 - sq;
        return quality;
 }
 
@@ -5852,7 +5790,7 @@ static int airo_set_freq(struct net_device *dev,
                } else {
                        readConfigRid(local, 1);
                        /* Yes ! We can set it !!! */
-                       local->config.channelSet = (u16) channel;
+                       local->config.channelSet = cpu_to_le16(channel);
                        set_bit (FLAG_COMMIT, &local->flags);
                }
        }
@@ -5873,12 +5811,12 @@ static int airo_get_freq(struct net_device *dev,
        int ch;
 
        readConfigRid(local, 1);
-       if ((local->config.opmode & 0xFF) == MODE_STA_ESS)
+       if ((local->config.opmode & MODE_CFG_MASK) == MODE_STA_ESS)
                status_rid.channel = local->config.channelSet;
        else
                readStatusRid(local, &status_rid, 1);
 
-       ch = (int)status_rid.channel;
+       ch = le16_to_cpu(status_rid.channel);
        if((ch > 0) && (ch < 15)) {
                fwrq->m = frequency_list[ch - 1] * 100000;
                fwrq->e = 1;
@@ -5925,9 +5863,9 @@ static int airo_set_essid(struct net_device *dev,
                memset(SSID_rid.ssids[index].ssid, 0,
                       sizeof(SSID_rid.ssids[index].ssid));
                memcpy(SSID_rid.ssids[index].ssid, extra, dwrq->length);
-               SSID_rid.ssids[index].len = dwrq->length;
+               SSID_rid.ssids[index].len = cpu_to_le16(dwrq->length);
        }
-       SSID_rid.len = sizeof(SSID_rid);
+       SSID_rid.len = cpu_to_le16(sizeof(SSID_rid));
        /* Write it to the card */
        disable_MAC(local, 1);
        writeSsidRid(local, &SSID_rid, 1);
@@ -5954,11 +5892,11 @@ static int airo_get_essid(struct net_device *dev,
         * get the relevant SSID from the SSID list... */
 
        /* Get the current SSID */
-       memcpy(extra, status_rid.SSID, status_rid.SSIDlen);
+       memcpy(extra, status_rid.SSID, le16_to_cpu(status_rid.SSIDlen));
        /* If none, we may want to get the one that was set */
 
        /* Push it out ! */
-       dwrq->length = status_rid.SSIDlen;
+       dwrq->length = le16_to_cpu(status_rid.SSIDlen);
        dwrq->flags = 1; /* active */
 
        return 0;
@@ -5992,7 +5930,7 @@ static int airo_set_wap(struct net_device *dev,
                up(&local->sem);
        } else {
                memset(&APList_rid, 0, sizeof(APList_rid));
-               APList_rid.len = sizeof(APList_rid);
+               APList_rid.len = cpu_to_le16(sizeof(APList_rid));
                memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
                disable_MAC(local, 1);
                writeAPListRid(local, &APList_rid, 1);
@@ -6148,7 +6086,7 @@ static int airo_get_rate(struct net_device *dev,
 
        readStatusRid(local, &status_rid, 1);
 
-       vwrq->value = status_rid.currentXmitRate * 500000;
+       vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000;
        /* If more than one rate, set auto */
        readConfigRid(local, 1);
        vwrq->fixed = (local->config.rates[1] == 0);
@@ -6174,7 +6112,7 @@ static int airo_set_rts(struct net_device *dev,
                return -EINVAL;
        }
        readConfigRid(local, 1);
-       local->config.rtsThres = rthr;
+       local->config.rtsThres = cpu_to_le16(rthr);
        set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
@@ -6192,7 +6130,7 @@ static int airo_get_rts(struct net_device *dev,
        struct airo_info *local = dev->priv;
 
        readConfigRid(local, 1);
-       vwrq->value = local->config.rtsThres;
+       vwrq->value = le16_to_cpu(local->config.rtsThres);
        vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
        vwrq->fixed = 1;
 
@@ -6218,7 +6156,7 @@ static int airo_set_frag(struct net_device *dev,
        }
        fthr &= ~0x1;   /* Get an even value - is it really needed ??? */
        readConfigRid(local, 1);
-       local->config.fragThresh = (u16)fthr;
+       local->config.fragThresh = cpu_to_le16(fthr);
        set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
@@ -6236,7 +6174,7 @@ static int airo_get_frag(struct net_device *dev,
        struct airo_info *local = dev->priv;
 
        readConfigRid(local, 1);
-       vwrq->value = local->config.fragThresh;
+       vwrq->value = le16_to_cpu(local->config.fragThresh);
        vwrq->disabled = (vwrq->value >= AIRO_DEF_MTU);
        vwrq->fixed = 1;
 
@@ -6256,42 +6194,42 @@ static int airo_set_mode(struct net_device *dev,
        int reset = 0;
 
        readConfigRid(local, 1);
-       if ((local->config.rmode & 0xff) >= RXMODE_RFMON)
+       if (sniffing_mode(local))
                reset = 1;
 
        switch(*uwrq) {
                case IW_MODE_ADHOC:
-                       local->config.opmode &= 0xFF00;
+                       local->config.opmode &= ~MODE_CFG_MASK;
                        local->config.opmode |= MODE_STA_IBSS;
-                       local->config.rmode &= 0xfe00;
+                       local->config.rmode &= ~RXMODE_FULL_MASK;
                        local->config.scanMode = SCANMODE_ACTIVE;
                        clear_bit (FLAG_802_11, &local->flags);
                        break;
                case IW_MODE_INFRA:
-                       local->config.opmode &= 0xFF00;
+                       local->config.opmode &= ~MODE_CFG_MASK;
                        local->config.opmode |= MODE_STA_ESS;
-                       local->config.rmode &= 0xfe00;
+                       local->config.rmode &= ~RXMODE_FULL_MASK;
                        local->config.scanMode = SCANMODE_ACTIVE;
                        clear_bit (FLAG_802_11, &local->flags);
                        break;
                case IW_MODE_MASTER:
-                       local->config.opmode &= 0xFF00;
+                       local->config.opmode &= ~MODE_CFG_MASK;
                        local->config.opmode |= MODE_AP;
-                       local->config.rmode &= 0xfe00;
+                       local->config.rmode &= ~RXMODE_FULL_MASK;
                        local->config.scanMode = SCANMODE_ACTIVE;
                        clear_bit (FLAG_802_11, &local->flags);
                        break;
                case IW_MODE_REPEAT:
-                       local->config.opmode &= 0xFF00;
+                       local->config.opmode &= ~MODE_CFG_MASK;
                        local->config.opmode |= MODE_AP_RPTR;
-                       local->config.rmode &= 0xfe00;
+                       local->config.rmode &= ~RXMODE_FULL_MASK;
                        local->config.scanMode = SCANMODE_ACTIVE;
                        clear_bit (FLAG_802_11, &local->flags);
                        break;
                case IW_MODE_MONITOR:
-                       local->config.opmode &= 0xFF00;
+                       local->config.opmode &= ~MODE_CFG_MASK;
                        local->config.opmode |= MODE_STA_ESS;
-                       local->config.rmode &= 0xfe00;
+                       local->config.rmode &= ~RXMODE_FULL_MASK;
                        local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER;
                        local->config.scanMode = SCANMODE_PASSIVE;
                        set_bit (FLAG_802_11, &local->flags);
@@ -6319,7 +6257,7 @@ static int airo_get_mode(struct net_device *dev,
 
        readConfigRid(local, 1);
        /* If not managed, assume it's ad-hoc */
-       switch (local->config.opmode & 0xFF) {
+       switch (local->config.opmode & MODE_CFG_MASK) {
                case MODE_STA_ESS:
                        *uwrq = IW_MODE_INFRA;
                        break;
@@ -6336,6 +6274,13 @@ static int airo_get_mode(struct net_device *dev,
        return 0;
 }
 
+static inline int valid_index(CapabilityRid *p, int index)
+{
+       if (index < 0)
+               return 0;
+       return index < (p->softCap & cpu_to_le16(0x80) ? 4 : 1);
+}
+
 /*------------------------------------------------------------------*/
 /*
  * Wireless Handler : set Encryption Key
@@ -6348,12 +6293,12 @@ static int airo_set_encode(struct net_device *dev,
        struct airo_info *local = dev->priv;
        CapabilityRid cap_rid;          /* Card capability info */
        int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
-       u16 currentAuthType = local->config.authType;
+       __le16 currentAuthType = local->config.authType;
 
        /* Is WEP supported ? */
        readCapabilityRid(local, &cap_rid, 1);
        /* Older firmware doesn't support this...
-       if(!(cap_rid.softCap & 2)) {
+       if(!(cap_rid.softCap & cpu_to_le16(2))) {
                return -EOPNOTSUPP;
        } */
        readConfigRid(local, 1);
@@ -6373,7 +6318,7 @@ static int airo_set_encode(struct net_device *dev,
                        return -EINVAL;
                }
                /* Check the index (none -> use current) */
-               if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4:1)))
+               if (!valid_index(&cap_rid, index))
                        index = current_index;
                /* Set the length */
                if (dwrq->length > MIN_KEY_SIZE)
@@ -6403,13 +6348,12 @@ static int airo_set_encode(struct net_device *dev,
        } else {
                /* Do we want to just set the transmit key index ? */
                int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-               if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
+               if (valid_index(&cap_rid, index)) {
                        set_wep_key(local, index, NULL, 0, perm, 1);
                } else
                        /* Don't complain if only change the mode */
-                       if(!dwrq->flags & IW_ENCODE_MODE) {
+                       if (!(dwrq->flags & IW_ENCODE_MODE))
                                return -EINVAL;
-                       }
        }
        /* Read the flags */
        if(dwrq->flags & IW_ENCODE_DISABLED)
@@ -6439,7 +6383,7 @@ static int airo_get_encode(struct net_device *dev,
 
        /* Is it supported ? */
        readCapabilityRid(local, &cap_rid, 1);
-       if(!(cap_rid.softCap & 2)) {
+       if(!(cap_rid.softCap & cpu_to_le16(2))) {
                return -EOPNOTSUPP;
        }
        readConfigRid(local, 1);
@@ -6461,7 +6405,7 @@ static int airo_get_encode(struct net_device *dev,
        memset(extra, 0, 16);
 
        /* Which key do we want ? -1 -> tx index */
-       if ((index < 0) || (index >= ((cap_rid.softCap & 0x80) ? 4 : 1)))
+       if (!valid_index(&cap_rid, index))
                index = get_wep_key(local, 0xffff);
        dwrq->flags |= index + 1;
        /* Copy the key to the user buffer */
@@ -6486,14 +6430,14 @@ static int airo_set_encodeext(struct net_device *dev,
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        CapabilityRid cap_rid;          /* Card capability info */
        int perm = ( encoding->flags & IW_ENCODE_TEMP ? 0 : 1 );
-       u16 currentAuthType = local->config.authType;
+       __le16 currentAuthType = local->config.authType;
        int idx, key_len, alg = ext->alg, set_key = 1;
        wep_key_t key;
 
        /* Is WEP supported ? */
        readCapabilityRid(local, &cap_rid, 1);
        /* Older firmware doesn't support this...
-       if(!(cap_rid.softCap & 2)) {
+       if(!(cap_rid.softCap & cpu_to_le16(2))) {
                return -EOPNOTSUPP;
        } */
        readConfigRid(local, 1);
@@ -6501,7 +6445,7 @@ static int airo_set_encodeext(struct net_device *dev,
        /* Determine and validate the key index */
        idx = encoding->flags & IW_ENCODE_INDEX;
        if (idx) {
-               if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
+               if (!valid_index(&cap_rid, idx - 1))
                        return -EINVAL;
                idx--;
        } else
@@ -6575,7 +6519,7 @@ static int airo_get_encodeext(struct net_device *dev,
 
        /* Is it supported ? */
        readCapabilityRid(local, &cap_rid, 1);
-       if(!(cap_rid.softCap & 2)) {
+       if(!(cap_rid.softCap & cpu_to_le16(2))) {
                return -EOPNOTSUPP;
        }
        readConfigRid(local, 1);
@@ -6586,7 +6530,7 @@ static int airo_get_encodeext(struct net_device *dev,
 
        idx = encoding->flags & IW_ENCODE_INDEX;
        if (idx) {
-               if (idx < 1 || idx > ((cap_rid.softCap & 0x80) ? 4:1))
+               if (!valid_index(&cap_rid, idx - 1))
                        return -EINVAL;
                idx--;
        } else
@@ -6632,7 +6576,7 @@ static int airo_set_auth(struct net_device *dev,
 {
        struct airo_info *local = dev->priv;
        struct iw_param *param = &wrqu->param;
-       u16 currentAuthType = local->config.authType;
+       __le16 currentAuthType = local->config.authType;
 
        switch (param->flags & IW_AUTH_INDEX) {
        case IW_AUTH_WPA_VERSION:
@@ -6700,7 +6644,7 @@ static int airo_get_auth(struct net_device *dev,
 {
        struct airo_info *local = dev->priv;
        struct iw_param *param = &wrqu->param;
-       u16 currentAuthType = local->config.authType;
+       __le16 currentAuthType = local->config.authType;
 
        switch (param->flags & IW_AUTH_INDEX) {
        case IW_AUTH_DROP_UNENCRYPTED:
@@ -6751,6 +6695,7 @@ static int airo_set_txpow(struct net_device *dev,
        CapabilityRid cap_rid;          /* Card capability info */
        int i;
        int rc = -EINVAL;
+       __le16 v = cpu_to_le16(vwrq->value);
 
        readCapabilityRid(local, &cap_rid, 1);
 
@@ -6764,9 +6709,9 @@ static int airo_set_txpow(struct net_device *dev,
        }
        clear_bit (FLAG_RADIO_OFF, &local->flags);
        for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++)
-               if ((vwrq->value==cap_rid.txPowerLevels[i])) {
+               if (v == cap_rid.txPowerLevels[i]) {
                        readConfigRid(local, 1);
-                       local->config.txPower = vwrq->value;
+                       local->config.txPower = v;
                        set_bit (FLAG_COMMIT, &local->flags);
                        rc = -EINPROGRESS;      /* Call commit handler */
                        break;
@@ -6786,7 +6731,7 @@ static int airo_get_txpow(struct net_device *dev,
        struct airo_info *local = dev->priv;
 
        readConfigRid(local, 1);
-       vwrq->value = local->config.txPower;
+       vwrq->value = le16_to_cpu(local->config.txPower);
        vwrq->fixed = 1;        /* No power control */
        vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags);
        vwrq->flags = IW_TXPOW_MWATT;
@@ -6811,20 +6756,21 @@ static int airo_set_retry(struct net_device *dev,
        }
        readConfigRid(local, 1);
        if(vwrq->flags & IW_RETRY_LIMIT) {
+               __le16 v = cpu_to_le16(vwrq->value);
                if(vwrq->flags & IW_RETRY_LONG)
-                       local->config.longRetryLimit = vwrq->value;
+                       local->config.longRetryLimit = v;
                else if (vwrq->flags & IW_RETRY_SHORT)
-                       local->config.shortRetryLimit = vwrq->value;
+                       local->config.shortRetryLimit = v;
                else {
                        /* No modifier : set both */
-                       local->config.longRetryLimit = vwrq->value;
-                       local->config.shortRetryLimit = vwrq->value;
+                       local->config.longRetryLimit = v;
+                       local->config.shortRetryLimit = v;
                }
                set_bit (FLAG_COMMIT, &local->flags);
                rc = -EINPROGRESS;              /* Call commit handler */
        }
        if(vwrq->flags & IW_RETRY_LIFETIME) {
-               local->config.txLifetime = vwrq->value / 1024;
+               local->config.txLifetime = cpu_to_le16(vwrq->value / 1024);
                set_bit (FLAG_COMMIT, &local->flags);
                rc = -EINPROGRESS;              /* Call commit handler */
        }
@@ -6848,14 +6794,14 @@ static int airo_get_retry(struct net_device *dev,
        /* Note : by default, display the min retry number */
        if((vwrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
                vwrq->flags = IW_RETRY_LIFETIME;
-               vwrq->value = (int)local->config.txLifetime * 1024;
+               vwrq->value = le16_to_cpu(local->config.txLifetime) * 1024;
        } else if((vwrq->flags & IW_RETRY_LONG)) {
                vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-               vwrq->value = (int)local->config.longRetryLimit;
+               vwrq->value = le16_to_cpu(local->config.longRetryLimit);
        } else {
                vwrq->flags = IW_RETRY_LIMIT;
-               vwrq->value = (int)local->config.shortRetryLimit;
-               if((int)local->config.shortRetryLimit != (int)local->config.longRetryLimit)
+               vwrq->value = le16_to_cpu(local->config.shortRetryLimit);
+               if(local->config.shortRetryLimit != local->config.longRetryLimit)
                        vwrq->flags |= IW_RETRY_SHORT;
        }
 
@@ -6936,16 +6882,17 @@ static int airo_get_range(struct net_device *dev,
        range->min_frag = 256;
        range->max_frag = AIRO_DEF_MTU;
 
-       if(cap_rid.softCap & 2) {
+       if(cap_rid.softCap & cpu_to_le16(2)) {
                // WEP: RC4 40 bits
                range->encoding_size[0] = 5;
                // RC4 ~128 bits
-               if (cap_rid.softCap & 0x100) {
+               if (cap_rid.softCap & cpu_to_le16(0x100)) {
                        range->encoding_size[1] = 13;
                        range->num_encoding_sizes = 2;
                } else
                        range->num_encoding_sizes = 1;
-               range->max_encoding_tokens = (cap_rid.softCap & 0x80) ? 4 : 1;
+               range->max_encoding_tokens =
+                       cap_rid.softCap & cpu_to_le16(0x80) ? 4 : 1;
        } else {
                range->num_encoding_sizes = 0;
                range->max_encoding_tokens = 0;
@@ -6960,7 +6907,7 @@ static int airo_get_range(struct net_device *dev,
 
        /* Transmit Power - values are in mW */
        for(i = 0 ; i < 8 ; i++) {
-               range->txpower[i] = cap_rid.txPowerLevels[i];
+               range->txpower[i] = le16_to_cpu(cap_rid.txPowerLevels[i]);
                if(range->txpower[i] == 0)
                        break;
        }
@@ -6999,38 +6946,37 @@ static int airo_set_power(struct net_device *dev,
 
        readConfigRid(local, 1);
        if (vwrq->disabled) {
-               if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
+               if (sniffing_mode(local))
                        return -EINVAL;
-               }
                local->config.powerSaveMode = POWERSAVE_CAM;
-               local->config.rmode &= 0xFF00;
+               local->config.rmode &= ~RXMODE_MASK;
                local->config.rmode |= RXMODE_BC_MC_ADDR;
                set_bit (FLAG_COMMIT, &local->flags);
                return -EINPROGRESS;            /* Call commit handler */
        }
        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-               local->config.fastListenDelay = (vwrq->value + 500) / 1024;
+               local->config.fastListenDelay = cpu_to_le16((vwrq->value + 500) / 1024);
                local->config.powerSaveMode = POWERSAVE_PSPCAM;
                set_bit (FLAG_COMMIT, &local->flags);
        } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) {
-               local->config.fastListenInterval = local->config.listenInterval = (vwrq->value + 500) / 1024;
+               local->config.fastListenInterval =
+               local->config.listenInterval =
+                       cpu_to_le16((vwrq->value + 500) / 1024);
                local->config.powerSaveMode = POWERSAVE_PSPCAM;
                set_bit (FLAG_COMMIT, &local->flags);
        }
        switch (vwrq->flags & IW_POWER_MODE) {
                case IW_POWER_UNICAST_R:
-                       if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
+                       if (sniffing_mode(local))
                                return -EINVAL;
-                       }
-                       local->config.rmode &= 0xFF00;
+                       local->config.rmode &= ~RXMODE_MASK;
                        local->config.rmode |= RXMODE_ADDR;
                        set_bit (FLAG_COMMIT, &local->flags);
                        break;
                case IW_POWER_ALL_R:
-                       if ((local->config.rmode & 0xFF) >= RXMODE_RFMON) {
+                       if (sniffing_mode(local))
                                return -EINVAL;
-                       }
-                       local->config.rmode &= 0xFF00;
+                       local->config.rmode &= ~RXMODE_MASK;
                        local->config.rmode |= RXMODE_BC_MC_ADDR;
                        set_bit (FLAG_COMMIT, &local->flags);
                case IW_POWER_ON:
@@ -7054,20 +7000,20 @@ static int airo_get_power(struct net_device *dev,
                          char *extra)
 {
        struct airo_info *local = dev->priv;
-       int mode;
+       __le16 mode;
 
        readConfigRid(local, 1);
        mode = local->config.powerSaveMode;
        if ((vwrq->disabled = (mode == POWERSAVE_CAM)))
                return 0;
        if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-               vwrq->value = (int)local->config.fastListenDelay * 1024;
+               vwrq->value = le16_to_cpu(local->config.fastListenDelay) * 1024;
                vwrq->flags = IW_POWER_TIMEOUT;
        } else {
-               vwrq->value = (int)local->config.fastListenInterval * 1024;
+               vwrq->value = le16_to_cpu(local->config.fastListenInterval) * 1024;
                vwrq->flags = IW_POWER_PERIOD;
        }
-       if ((local->config.rmode & 0xFF) == RXMODE_ADDR)
+       if ((local->config.rmode & RXMODE_MASK) == RXMODE_ADDR)
                vwrq->flags |= IW_POWER_UNICAST_R;
        else
                vwrq->flags |= IW_POWER_ALL_R;
@@ -7087,7 +7033,8 @@ static int airo_set_sens(struct net_device *dev,
        struct airo_info *local = dev->priv;
 
        readConfigRid(local, 1);
-       local->config.rssiThreshold = vwrq->disabled ? RSSI_DEFAULT : vwrq->value;
+       local->config.rssiThreshold =
+               cpu_to_le16(vwrq->disabled ? RSSI_DEFAULT : vwrq->value);
        set_bit (FLAG_COMMIT, &local->flags);
 
        return -EINPROGRESS;            /* Call commit handler */
@@ -7105,7 +7052,7 @@ static int airo_get_sens(struct net_device *dev,
        struct airo_info *local = dev->priv;
 
        readConfigRid(local, 1);
-       vwrq->value = local->config.rssiThreshold;
+       vwrq->value = le16_to_cpu(local->config.rssiThreshold);
        vwrq->disabled = (vwrq->value == 0);
        vwrq->fixed = 1;
 
@@ -7130,26 +7077,28 @@ static int airo_get_aplist(struct net_device *dev,
        int loseSync = capable(CAP_NET_ADMIN) ? 1: -1;
 
        for (i = 0; i < IW_MAX_AP; i++) {
+               u16 dBm;
                if (readBSSListRid(local, loseSync, &BSSList))
                        break;
                loseSync = 0;
                memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN);
                address[i].sa_family = ARPHRD_ETHER;
+               dBm = le16_to_cpu(BSSList.dBm);
                if (local->rssi) {
-                       qual[i].level = 0x100 - BSSList.dBm;
-                       qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm );
+                       qual[i].level = 0x100 - dBm;
+                       qual[i].qual = airo_dbm_to_pct(local->rssi, dBm);
                        qual[i].updated = IW_QUAL_QUAL_UPDATED
                                        | IW_QUAL_LEVEL_UPDATED
                                        | IW_QUAL_DBM;
                } else {
-                       qual[i].level = (BSSList.dBm + 321) / 2;
+                       qual[i].level = (dBm + 321) / 2;
                        qual[i].qual = 0;
                        qual[i].updated = IW_QUAL_QUAL_INVALID
                                        | IW_QUAL_LEVEL_UPDATED
                                        | IW_QUAL_DBM;
                }
                qual[i].noise = local->wstats.qual.noise;
-               if (BSSList.index == 0xffff)
+               if (BSSList.index == cpu_to_le16(0xffff))
                        break;
        }
        if (!i) {
@@ -7240,10 +7189,11 @@ static inline char *airo_translate_scan(struct net_device *dev,
 {
        struct airo_info *ai = dev->priv;
        struct iw_event         iwe;            /* Temporary buffer */
-       u16                     capabilities;
+       __le16                  capabilities;
        char *                  current_val;    /* For rates */
        int                     i;
        char *          buf;
+       u16 dBm;
 
        /* First entry *MUST* be the AP MAC address */
        iwe.cmd = SIOCGIWAP;
@@ -7263,7 +7213,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
 
        /* Add mode */
        iwe.cmd = SIOCGIWMODE;
-       capabilities = le16_to_cpu(bss->cap);
+       capabilities = bss->cap;
        if(capabilities & (CAP_ESS | CAP_IBSS)) {
                if(capabilities & CAP_ESS)
                        iwe.u.mode = IW_MODE_MASTER;
@@ -7282,16 +7232,18 @@ static inline char *airo_translate_scan(struct net_device *dev,
        iwe.u.freq.e = 1;
        current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
 
+       dBm = le16_to_cpu(bss->dBm);
+
        /* Add quality statistics */
        iwe.cmd = IWEVQUAL;
        if (ai->rssi) {
-               iwe.u.qual.level = 0x100 - bss->dBm;
-               iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm );
+               iwe.u.qual.level = 0x100 - dBm;
+               iwe.u.qual.qual = airo_dbm_to_pct(ai->rssi, dBm);
                iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
                                | IW_QUAL_LEVEL_UPDATED
                                | IW_QUAL_DBM;
        } else {
-               iwe.u.qual.level = (bss->dBm + 321) / 2;
+               iwe.u.qual.level = (dBm + 321) / 2;
                iwe.u.qual.qual = 0;
                iwe.u.qual.updated = IW_QUAL_QUAL_INVALID
                                | IW_QUAL_LEVEL_UPDATED
@@ -7670,7 +7622,7 @@ static void airo_read_wireless_stats(struct airo_info *local)
        StatusRid status_rid;
        StatsRid stats_rid;
        CapabilityRid cap_rid;
-       u32 *vals = stats_rid.vals;
+       __le32 *vals = stats_rid.vals;
 
        /* Get stats out of the card */
        clear_bit(JOB_WSTATS, &local->jobs);
@@ -7684,18 +7636,22 @@ static void airo_read_wireless_stats(struct airo_info *local)
        up(&local->sem);
 
        /* The status */
-       local->wstats.status = status_rid.mode;
+       local->wstats.status = le16_to_cpu(status_rid.mode);
 
        /* Signal quality and co */
        if (local->rssi) {
-               local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality );
+               local->wstats.qual.level =
+                       airo_rssi_to_dbm(local->rssi,
+                                        le16_to_cpu(status_rid.sigQuality));
                /* normalizedSignalStrength appears to be a percentage */
-               local->wstats.qual.qual = status_rid.normalizedSignalStrength;
+               local->wstats.qual.qual =
+                       le16_to_cpu(status_rid.normalizedSignalStrength);
        } else {
-               local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2;
+               local->wstats.qual.level =
+                       (le16_to_cpu(status_rid.normalizedSignalStrength) + 321) / 2;
                local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid);
        }
-       if (status_rid.len >= 124) {
+       if (le16_to_cpu(status_rid.len) >= 124) {
                local->wstats.qual.noise = 0x100 - status_rid.noisedBm;
                local->wstats.qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
        } else {
@@ -7705,12 +7661,15 @@ static void airo_read_wireless_stats(struct airo_info *local)
 
        /* Packets discarded in the wireless adapter due to wireless
         * specific problems */
-       local->wstats.discard.nwid = vals[56] + vals[57] + vals[58];/* SSID Mismatch */
-       local->wstats.discard.code = vals[6];/* RxWepErr */
-       local->wstats.discard.fragment = vals[30];
-       local->wstats.discard.retries = vals[10];
-       local->wstats.discard.misc = vals[1] + vals[32];
-       local->wstats.miss.beacon = vals[34];
+       local->wstats.discard.nwid = le32_to_cpu(vals[56]) +
+                                    le32_to_cpu(vals[57]) +
+                                    le32_to_cpu(vals[58]); /* SSID Mismatch */
+       local->wstats.discard.code = le32_to_cpu(vals[6]);/* RxWepErr */
+       local->wstats.discard.fragment = le32_to_cpu(vals[30]);
+       local->wstats.discard.retries = le32_to_cpu(vals[10]);
+       local->wstats.discard.misc = le32_to_cpu(vals[1]) +
+                                    le32_to_cpu(vals[32]);
+       local->wstats.miss.beacon = le32_to_cpu(vals[34]);
 }
 
 static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev)
@@ -7896,7 +7855,7 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
                if (test_bit(FLAG_MIC_CAPABLE, &ai->flags))
                        cfg->opmode |= MODE_MIC;
 
-               if ((cfg->opmode & 0xFF) == MODE_STA_IBSS)
+               if ((cfg->opmode & MODE_CFG_MASK) == MODE_STA_IBSS)
                        set_bit (FLAG_ADHOC, &ai->flags);
                else
                        clear_bit (FLAG_ADHOC, &ai->flags);
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
new file mode 100644 (file)
index 0000000..321641f
--- /dev/null
@@ -0,0 +1,2 @@
+ath5k-objs             = base.o hw.o regdom.o initvals.o phy.o debug.o
+obj-$(CONFIG_ATH5K)    += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
new file mode 100644 (file)
index 0000000..c79066b
--- /dev/null
@@ -0,0 +1,1173 @@
+/*
+ * 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
+
+/* Set this to 1 to disable regulatory domain restrictions for channel tests.
+ * WARNING: This is for debuging only and has side effects (eg. scan takes too
+ * long and results timeouts). It's also illegal to tune to some of the
+ * supported frequencies in some countries, so use this at your own risk,
+ * you've been warned. */
+#define CHAN_DEBUG     0
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <net/mac80211.h>
+
+#include "hw.h"
+#include "regdom.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__)
+
+/*
+ * Some tuneable values (these should be changeable by the user)
+ */
+#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                  60
+#define AR5K_TUNE_DEFAULT_TXPOWER              30
+#define AR5K_TUNE_TPC_TXPOWER                  true
+#define AR5K_TUNE_ANT_DIVERSITY                        true
+#define AR5K_TUNE_HWTXTRIES                    4
+
+/* 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_RF5413     = 3,
+};
+
+/*
+ * Common silicon revision/version values
+ */
+
+enum ath5k_srev_type {
+       AR5K_VERSION_VER,
+       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_VER_AR5210   0x00
+#define AR5K_SREV_VER_AR5311   0x10
+#define AR5K_SREV_VER_AR5311A  0x20
+#define AR5K_SREV_VER_AR5311B  0x30
+#define AR5K_SREV_VER_AR5211   0x40
+#define AR5K_SREV_VER_AR5212   0x50
+#define AR5K_SREV_VER_AR5213   0x55
+#define AR5K_SREV_VER_AR5213A  0x59
+#define AR5K_SREV_VER_AR2424   0xa0
+#define AR5K_SREV_VER_AR5424   0xa3
+#define AR5K_SREV_VER_AR5413   0xa4
+#define AR5K_SREV_VER_AR5414   0xa5
+#define AR5K_SREV_VER_AR5416   0xc0    /* ? */
+#define AR5K_SREV_VER_AR5418   0xca
+
+#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_2112     0x40
+#define AR5K_SREV_RAD_2112A    0x45
+#define AR5K_SREV_RAD_SC1      0x63    /* Found on 5413/5414 */
+#define AR5K_SREV_RAD_SC2      0xa2    /* Found on 2424/5424 */
+#define AR5K_SREV_RAD_5133     0xc0    /* MIMO found on 5418 */
+
+/* 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_vendor_mode {
+       MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1,
+       MODE_ATHEROS_TURBOG
+};
+
+/* Number of supported mac80211 enum ieee80211_phymode modes by this driver */
+#define NUM_DRIVER_MODES       3
+
+/* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
+#define AR5K_SET_SHORT_PREAMBLE 0x04
+
+#define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2)
+#define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
+
+/****************\
+  TX DEFINITIONS
+\****************/
+
+/*
+ * Tx Descriptor
+ */
+struct ath5k_tx_status {
+       u16     ts_seqnum;
+       u16     ts_tstamp;
+       u8      ts_status;
+       u8      ts_rate;
+       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_BACKOFF_DISABLE          0x0020  /* Disable random post-backoff */
+#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0040  /* Enable ready time expiry policy (?)*/
+#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0080  /* Enable backoff while bursting */
+#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x0100  /* Disable backoff while bursting */
+#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x0200  /* 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.
+ * These are not fully used inside OpenHAL yet
+ */
+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[(_r)]) & 0x3f) << (_v))     \
+)
+
+#define AR5K_TXPOWER_CCK(_r, _v)       (                       \
+       (ah->ah_txpower.txp_rates[(_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 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)
+
+struct ath5k_mib_stats {
+       u32     ackrcv_bad;
+       u32     rts_bad;
+       u32     rts_good;
+       u32     fcs_bad;
+       u32     beacons;
+};
+
+
+
+
+/**************************\
+ 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)
+
+
+
+/********************\
+  COMMON DEFINITIONS
+\********************/
+
+/*
+ * Atheros descriptor
+ */
+struct ath5k_desc {
+       u32     ds_link;
+       u32     ds_data;
+       u32     ds_ctl0;
+       u32     ds_ctl1;
+       u32     ds_hw[4];
+
+       union {
+               struct ath5k_rx_status rx;
+               struct ath5k_tx_status tx;
+       } ds_us;
+
+#define ds_rxstat ds_us.rx
+#define ds_txstat ds_us.tx
+
+} __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+]*/
+
+#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 in OpenHAL (ar5211.c/ar5212.c
+ * for reset_tx_queue). Also see struct struct ieee80211_channel.
+ */
+#define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0)
+#define IS_CHAN_B(_c)  ((_c.val & CHANNEL_B) != 0)
+
+/*
+ * The following structure will be used to map 2GHz channels to
+ * 5GHz Atheros channels.
+ */
+struct ath5k_athchan_2ghz {
+       u32     a2_flags;
+       u16     a2_athchan;
+};
+
+/*
+ * Rate definitions
+ * TODO: Clean them up or move them on mac80211 -most of these infos are
+ *      used by the rate control algorytm on MadWiFi.
+ */
+
+/* Max number of rates on the rate table and what it seems
+ * Atheros hardware supports */
+#define AR5K_MAX_RATES 32
+
+/**
+ * struct ath5k_rate - rate structure
+ * @valid: is this a valid rate for the current mode
+ * @modulation: respective mac80211 modulation
+ * @rate_kbps: rate in kbit/s
+ * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
+ *     &struct ath5k_rx_status.rs_rate and on TX on
+ *     &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
+ *     up to 32 rates, indexed by 1-32. This means we really only need
+ *     6 bits for the rate_code.
+ * @dot11_rate: respective IEEE-802.11 rate value
+ * @control_rate: index of rate assumed to be used to send control frames.
+ *     This can be used to set override the value on the rate duration
+ *     registers. This is only useful if we can override in the harware at
+ *     what rate we want to send control frames at. Note that IEEE-802.11
+ *     Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
+ *     should send ACK/CTS, if we change this value we can be breaking
+ *     the spec.
+ *
+ * This structure 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.
+ *
+ * On RX after the &struct ath5k_desc is parsed by the appropriate
+ * ah_proc_rx_desc() the respective hardware rate value is set in
+ * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
+ * &struct ath5k_tx_status.ts_rate which is later used to setup the
+ * &struct ath5k_desc correctly. This is the hardware rate map we are
+ * aware of:
+ *
+ * rate_code   1       2       3       4       5       6       7       8
+ * rate_kbps   3000    1000    ?       ?       ?       2000    500     48000
+ *
+ * rate_code   9       10      11      12      13      14      15      16
+ * 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    ?       ?       ?       ?       ?
+ *
+ */
+struct ath5k_rate {
+       u8      valid;
+       u32     modulation;
+       u16     rate_kbps;
+       u8      rate_code;
+       u8      dot11_rate;
+       u8      control_rate;
+};
+
+/* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
+struct ath5k_rate_table {
+       u16     rate_count;
+       u8      rate_code_to_index[AR5K_MAX_RATES];     /* Back-mapping */
+       struct ath5k_rate rates[AR5K_MAX_RATES];
+};
+
+/*
+ * Rate tables...
+ */
+#define AR5K_RATES_11A { 8, {                                  \
+       255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0,     \
+       7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255,     \
+       255, 255, 255, 255, 255, 255, 255, 255 }, {             \
+       { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 },           \
+       { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 },            \
+       { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 },          \
+       { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 },           \
+       { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 },           \
+       { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 },           \
+       { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 },            \
+       { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } }         \
+}
+
+#define AR5K_RATES_11B { 4, {                                          \
+       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,     \
+       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,     \
+       3, 2, 1, 0, 255, 255, 255, 255 }, {                             \
+       { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 },    \
+       { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 },  \
+       { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 },  \
+       { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } }        \
+}
+
+#define AR5K_RATES_11G { 12, {                                 \
+       255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4,    \
+       11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255,    \
+       3, 2, 1, 0, 255, 255, 255, 255 }, {                     \
+       { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 },              \
+       { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 },            \
+       { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 },           \
+       { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 },  \
+       { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 },    \
+       { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 },    \
+       { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 },   \
+       { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 },   \
+       { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 },    \
+       { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 },   \
+       { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 },    \
+       { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
+}
+
+#define AR5K_RATES_TURBO { 8, {                                        \
+       255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0,     \
+       7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255,     \
+       255, 255, 255, 255, 255, 255, 255, 255 }, {             \
+       { 1, MODULATION_TURBO, 6000, 11, 140, 0 },      \
+       { 1, MODULATION_TURBO, 9000, 15, 18, 0 },       \
+       { 1, MODULATION_TURBO, 12000, 10, 152, 2 },     \
+       { 1, MODULATION_TURBO, 18000, 14, 36, 2 },      \
+       { 1, MODULATION_TURBO, 24000, 9, 176, 4 },      \
+       { 1, MODULATION_TURBO, 36000, 13, 72, 4 },      \
+       { 1, MODULATION_TURBO, 48000, 8, 96, 4 },       \
+       { 1, MODULATION_TURBO, 54000, 12, 108, 4 } }    \
+}
+
+#define AR5K_RATES_XR { 12, {                                  \
+       255, 3, 1, 255, 255, 255, 2, 0, 10, 8, 6, 4,            \
+       11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255,    \
+       255, 255, 255, 255, 255, 255, 255, 255 }, {             \
+       { 1, MODULATION_XR, 500, 7, 129, 0 },           \
+       { 1, MODULATION_XR, 1000, 2, 139, 1 },          \
+       { 1, MODULATION_XR, 2000, 6, 150, 2 },          \
+       { 1, MODULATION_XR, 3000, 1, 150, 3 },          \
+       { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 },   \
+       { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 },    \
+       { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 },  \
+       { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 },   \
+       { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 },   \
+       { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 },   \
+       { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 },    \
+       { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
+}
+
+/*
+ * 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)
+
+
+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,
+};
+
+/*
+ * 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: ??
+ * @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: Seems to be 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_RX     = 0x00000001, /* Not common */
+       AR5K_INT_RXDESC = 0x00000002,
+       AR5K_INT_RXNOFRM = 0x00000008,
+       AR5K_INT_RXEOL  = 0x00000010,
+       AR5K_INT_RXORN  = 0x00000020,
+       AR5K_INT_TX     = 0x00000040, /* Not common */
+       AR5K_INT_TXDESC = 0x00000080,
+       AR5K_INT_TXURN  = 0x00000800,
+       AR5K_INT_MIB    = 0x00001000,
+       AR5K_INT_RXPHY  = 0x00004000,
+       AR5K_INT_RXKCM  = 0x00008000,
+       AR5K_INT_SWBA   = 0x00010000,
+       AR5K_INT_BMISS  = 0x00040000,
+       AR5K_INT_BNR    = 0x00100000, /* Not common */
+       AR5K_INT_GPIO   = 0x01000000,
+       AR5K_INT_FATAL  = 0x40000000, /* Not common */
+       AR5K_INT_GLOBAL = 0x80000000,
+
+       AR5K_INT_COMMON  = AR5K_INT_RXNOFRM
+                       | AR5K_INT_RXDESC
+                       | AR5K_INT_RXEOL
+                       | AR5K_INT_RXORN
+                       | AR5K_INT_TXURN
+                       | AR5K_INT_TXDESC
+                       | AR5K_INT_MIB
+                       | AR5K_INT_RXPHY
+                       | AR5K_INT_RXKCM
+                       | AR5K_INT_SWBA
+                       | AR5K_INT_BMISS
+                       | AR5K_INT_GPIO,
+       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
+ * d80211).
+ */
+#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 OpenHAL so most of these don't work yet...
+ */
+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 */
+};
+
+struct ath5k_capabilities {
+       /*
+        * Supported PHY modes
+        * (ie. CHANNEL_A, CHANNEL_B, ...)
+        */
+       DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES);
+
+       /*
+        * Frequency range (without regulation restrictions)
+        */
+       struct {
+               u16     range_2ghz_min;
+               u16     range_2ghz_max;
+               u16     range_5ghz_min;
+               u16     range_5ghz_max;
+       } cap_range;
+
+       /*
+        * Active regulation domain settings
+        */
+       struct {
+               enum ath5k_regdom reg_current;
+               enum ath5k_regdom reg_hw;
+       } cap_regdomain;
+
+       /*
+        * 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
+
+struct ath5k_hw {
+       u32                     ah_magic;
+
+       struct ath5k_softc      *ah_sc;
+       void __iomem            *ah_iobase;
+
+       enum ath5k_int          ah_imr;
+
+       enum ieee80211_if_types 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;
+       enum ath5k_rfgain       ah_rf_gain;
+
+       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 / creating.
+        * This is passed by mac80211 on config_interface() and cached here for
+        * use in resets */
+       u8                      ah_bssid[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_rf_banks;
+       size_t                  ah_rf_banks_size;
+       struct ath5k_gain       ah_gain;
+       u32                     ah_offset[AR5K_MAX_RF_BANKS];
+
+       struct {
+               u16             txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
+               u16             txp_rates[AR5K_MAX_RATES];
+               s16             txp_min;
+               s16             txp_max;
+               bool            txp_tpc;
+               s16             txp_ofdm;
+       } 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_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);
+       bool (*ah_setup_xtx_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 *);
+       int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *);
+};
+
+/*
+ * Prototypes
+ */
+
+/* General Functions */
+extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set);
+/* Attach/Detach Functions */
+extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
+extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode);
+extern void ath5k_hw_detach(struct ath5k_hw *ah);
+/* Reset Functions */
+extern int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types 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(struct ath5k_hw *ah);
+extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
+extern u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah);
+extern void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr);
+extern int ath5k_hw_tx_start(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_tx_buf(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_put_tx_buf(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_intr(struct ath5k_hw *ah, enum ath5k_int new_mask);
+/* EEPROM access functions */
+extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain);
+/* 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_pcu_recv(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_filterindex(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 related 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_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
+extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ath5k_mib_stats *statistics);
+/* 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_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue, const struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
+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 u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
+extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
+/* Hardware Descriptor Functions */
+extern int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags);
+/* GPIO Functions */
+extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
+extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
+extern int ath5k_hw_set_gpio_input(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);
+/* Regulatory Domain/Channels Setup */
+extern u16 ath5k_get_regdomain(struct ath5k_hw *ah);
+/* Misc functions */
+extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
+
+
+/* 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(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
+extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
+extern int ath5k_hw_set_rfgain_opt(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_phy_disable(struct ath5k_hw *ah);
+/* 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_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+/* TX power setup */
+extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
+
+
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+       return ioread32(ah->ah_iobase + reg);
+}
+
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+       iowrite32(val, ah->ah_iobase + reg);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
new file mode 100644 (file)
index 0000000..72bcf32
--- /dev/null
@@ -0,0 +1,2974 @@
+/*-
+ * 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/version.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/if.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"
+
+/* unaligned little endian access */
+#define LE_READ_2(_p) (le16_to_cpu(get_unaligned((__le16 *)(_p))))
+#define LE_READ_4(_p) (le32_to_cpu(get_unaligned((__le32 *)(_p))))
+
+enum {
+       ATH_LED_TX,
+       ATH_LED_RX,
+};
+
+static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
+
+
+/******************\
+* 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.1.1 (EXPERIMENTAL)");
+
+
+/* Known PCI ids */
+static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
+       { 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 }, /* 5424 Condor (PCI-E)*/
+       { PCI_VDEVICE(ATHEROS, 0x0023), .driver_data = AR5K_AR5212 }, /* 5416 */
+       { PCI_VDEVICE(ATHEROS, 0x0024), .driver_data = AR5K_AR5212 }, /* 5418 */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
+
+/* Known SREVs */
+static struct ath5k_srev_name srev_names[] = {
+       { "5210",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5210 },
+       { "5311",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311 },
+       { "5311A",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311A },
+       { "5311B",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311B },
+       { "5211",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5211 },
+       { "5212",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5212 },
+       { "5213",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5213 },
+       { "5213A",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5213A },
+       { "2424",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2424 },
+       { "5424",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5424 },
+       { "5413",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5413 },
+       { "5414",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5414 },
+       { "5416",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5416 },
+       { "5418",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5418 },
+       { "xxxxx",      AR5K_VERSION_VER,       AR5K_SREV_UNKNOWN },
+       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
+       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
+       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
+       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
+       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
+       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
+       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
+       { "SChip",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_SC1 },
+       { "SChip",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_SC2 },
+       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
+       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
+};
+
+/*
+ * 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_drv_id = {
+       .name           = "ath5k_pci",
+       .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,
+               struct ieee80211_tx_control *ctl);
+static int ath5k_reset(struct ieee80211_hw *hw);
+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,
+               struct ieee80211_conf *conf);
+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,
+               const u8 *local_addr, const u8 *addr,
+               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_reset_tsf(struct ieee80211_hw *hw);
+static int ath5k_beacon_update(struct ieee80211_hw *hw,
+               struct sk_buff *skb,
+               struct ieee80211_tx_control *ctl);
+
+static 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,
+       .reset_tsf      = ath5k_reset_tsf,
+       .beacon_update  = ath5k_beacon_update,
+};
+
+/*
+ * 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_rates(struct ieee80211_rate *rates,
+                               const struct ath5k_rate_table *rt,
+                               unsigned int max);
+static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channels,
+                               unsigned int mode,
+                               unsigned int max);
+static int     ath5k_getchannels(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,
+                               struct ieee80211_tx_control *ctl);
+
+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(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);
+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,
+                               struct ieee80211_tx_control *ctl);
+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 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);
+/* LED functions */
+static void    ath5k_led_off(unsigned long data);
+static void    ath5k_led_blink(struct ath5k_softc *sc,
+                               unsigned int on,
+                               unsigned int off);
+static void    ath5k_led_event(struct ath5k_softc *sc,
+                               int event);
+
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+       int ret;
+
+       ath5k_debug_init();
+
+       ret = pci_register_driver(&ath5k_pci_drv_id);
+       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_drv_id);
+
+       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 & 0xff) < srev_names[i + 1].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_32BIT_MASK);
+       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;
+       hw->extra_tx_headroom = 2;
+       hw->channel_change_time = 5000;
+       /* these names are misleading */
+       hw->max_rssi = -110; /* signal in dBm */
+       hw->max_noise = -110; /* noise in dBm */
+       hw->max_signal = 100; /* we will provide a percentage based on rssi */
+       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 = IEEE80211_IF_TYPE_STA;
+       mutex_init(&sc->lock);
+       spin_lock_init(&sc->rxbuflock);
+       spin_lock_init(&sc->txbuflock);
+
+       /* Set private data */
+       pci_set_drvdata(pdev, hw);
+
+       /* Enable msi for devices that support it */
+       pci_enable_msi(pdev);
+
+       /* 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;
+       }
+
+       /* 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_VER,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(MODE_IEEE80211A, 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(MODE_IEEE80211B, 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:
+       pci_disable_msi(pdev);
+       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_disable_msi(pdev);
+       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;
+
+       if (test_bit(ATH_STAT_LEDSOFT, sc->status))
+               ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
+
+       ath5k_stop_hw(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;
+       struct ath5k_hw *ah = sc->ah;
+       int i, err;
+
+       err = pci_set_power_state(pdev, PCI_D0);
+       if (err)
+               return err;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       pci_restore_state(pdev);
+       /*
+        * Suspend/Resume resets the PCI configuration space, so we have to
+        * re-disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state
+        */
+       pci_write_config_byte(pdev, 0x41, 0);
+
+       ath5k_init(sc);
+       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+               ath5k_hw_set_gpio_output(ah, sc->led_pin);
+               ath5k_hw_set_gpio(ah, sc->led_pin, 0);
+       }
+
+       /*
+        * Reset the key cache since some parts do not
+        * reset the contents on initial power up or resume.
+        *
+        * FIXME: This may need to be revisited when mac80211 becomes
+        *        aware of suspend/resume.
+        */
+       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+               ath5k_hw_reset_key(ah, i);
+
+       return 0;
+}
+#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];
+       unsigned int i;
+       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.
+        */
+       if (ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0))
+               __set_bit(ATH_STAT_MRRETRY, sc->status);
+
+       /*
+        * Reset the key cache since some parts do not
+        * reset the contents on initial power up.
+        */
+       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+               ath5k_hw_reset_key(ah, i);
+
+       /*
+        * 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_getchannels(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(MODE_IEEE80211A, ah->ah_modes))
+               ath5k_setcurmode(sc, MODE_IEEE80211A);
+       else
+               ath5k_setcurmode(sc, MODE_IEEE80211B);
+
+       /*
+        * 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);
+       setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
+       setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc);
+
+       sc->led_on = 0; /* low true */
+       /*
+        * Auto-enable soft led processing for IBM cards and for
+        * 5211 minipci cards.
+        */
+       if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
+                       pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
+               __set_bit(ATH_STAT_LEDSOFT, sc->status);
+               sc->led_pin = 0;
+       }
+       /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
+       if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
+               __set_bit(ATH_STAT_LEDSOFT, sc->status);
+               sc->led_pin = 0;
+       }
+       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+               ath5k_hw_set_gpio_output(ah, sc->led_pin);
+               ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
+       }
+
+       ath5k_hw_get_lladdr(ah, mac);
+       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;
+       }
+
+       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);
+
+       /*
+        * 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_rates(struct ieee80211_rate *rates,
+               const struct ath5k_rate_table *rt,
+               unsigned int max)
+{
+       unsigned int i, count;
+
+       if (rt == NULL)
+               return 0;
+
+       for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) {
+               if (!rt->rates[i].valid)
+                       continue;
+               rates->rate = rt->rates[i].rate_kbps / 100;
+               rates->val = rt->rates[i].rate_code;
+               rates->flags = rt->rates[i].modulation;
+               rates++;
+               count++;
+               max--;
+       }
+
+       return count;
+}
+
+static unsigned int
+ath5k_copy_channels(struct ath5k_hw *ah,
+               struct ieee80211_channel *channels,
+               unsigned int mode,
+               unsigned int max)
+{
+       static const struct { unsigned int mode, mask, chan; } map[] = {
+               [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A },
+               [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T },
+               [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B },
+               [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G },
+               [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG },
+       };
+       static const struct ath5k_regchannel chans_2ghz[] =
+               IEEE80211_CHANNELS_2GHZ;
+       static const struct ath5k_regchannel chans_5ghz[] =
+               IEEE80211_CHANNELS_5GHZ;
+       const struct ath5k_regchannel *chans;
+       enum ath5k_regdom dmn;
+       unsigned int i, count, size, chfreq, all, f, ch;
+
+       if (!test_bit(mode, ah->ah_modes))
+               return 0;
+
+       all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1;
+
+       switch (mode) {
+       case MODE_IEEE80211A:
+       case MODE_ATHEROS_TURBO:
+               /* 1..220, but 2GHz frequencies are filtered by check_channel */
+               size = all ? 220 : ARRAY_SIZE(chans_5ghz);
+               chans = chans_5ghz;
+               dmn = ath5k_regdom2flag(ah->ah_regdomain,
+                               IEEE80211_CHANNELS_5GHZ_MIN);
+               chfreq = CHANNEL_5GHZ;
+               break;
+       case MODE_IEEE80211B:
+       case MODE_IEEE80211G:
+       case MODE_ATHEROS_TURBOG:
+               size = all ? 26 : ARRAY_SIZE(chans_2ghz);
+               chans = chans_2ghz;
+               dmn = ath5k_regdom2flag(ah->ah_regdomain,
+                               IEEE80211_CHANNELS_2GHZ_MIN);
+               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 = all ? i + 1 : chans[i].chan;
+               f = ath5k_ieee2mhz(ch);
+               /* Check if channel is supported by the chipset */
+               if (!ath5k_channel_ok(ah, f, chfreq))
+                       continue;
+
+               /* Match regulation domain */
+               if (!all && !(IEEE80211_DMN(chans[i].domain) &
+                                                       IEEE80211_DMN(dmn)))
+                       continue;
+
+               if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode)
+                       continue;
+
+               /* Write channel and increment counter */
+               channels->chan = ch;
+               channels->freq = f;
+               channels->val = map[mode].chan;
+               channels++;
+               count++;
+               max--;
+       }
+
+       return count;
+}
+
+/* Only tries to register modes our EEPROM says it can support */
+#define REGISTER_MODE(m) do { \
+       ret = ath5k_register_mode(hw, m); \
+       if (ret) \
+               return ret; \
+} while (0) \
+
+static inline int
+ath5k_register_mode(struct ieee80211_hw *hw, u8 m)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ieee80211_hw_mode *modes = sc->modes;
+       unsigned int i;
+       int ret;
+
+       if (!test_bit(m, sc->ah->ah_capabilities.cap_mode))
+               return 0;
+
+       for (i = 0; i < NUM_DRIVER_MODES; i++) {
+               if (modes[i].mode != m || !modes[i].num_channels)
+                       continue;
+               ret = ieee80211_register_hwmode(hw, &modes[i]);
+               if (ret) {
+                       ATH5K_ERR(sc, "can't register hwmode %u\n", m);
+                       return ret;
+               }
+               return 0;
+       }
+       BUG();
+}
+
+static int
+ath5k_getchannels(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       struct ieee80211_hw_mode *modes = sc->modes;
+       unsigned int i, max_r, max_c;
+       int ret;
+
+       BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
+
+       /* The order here does not matter */
+       modes[0].mode = MODE_IEEE80211G;
+       modes[1].mode = MODE_IEEE80211B;
+       modes[2].mode = MODE_IEEE80211A;
+
+       max_r = ARRAY_SIZE(sc->rates);
+       max_c = ARRAY_SIZE(sc->channels);
+
+       for (i = 0; i < NUM_DRIVER_MODES; i++) {
+               struct ieee80211_hw_mode *mode = &modes[i];
+               const struct ath5k_rate_table *hw_rates;
+
+               if (i == 0) {
+                       modes[0].rates  = sc->rates;
+                       modes->channels = sc->channels;
+               } else {
+                       struct ieee80211_hw_mode *prev_mode = &modes[i-1];
+                       int prev_num_r  = prev_mode->num_rates;
+                       int prev_num_c  = prev_mode->num_channels;
+                       mode->rates     = &prev_mode->rates[prev_num_r];
+                       mode->channels  = &prev_mode->channels[prev_num_c];
+               }
+
+               hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
+               mode->num_rates    = ath5k_copy_rates(mode->rates, hw_rates,
+                       max_r);
+               mode->num_channels = ath5k_copy_channels(ah, mode->channels,
+                       mode->mode, max_c);
+               max_r -= mode->num_rates;
+               max_c -= mode->num_channels;
+       }
+
+       /* We try to register all modes this driver supports. We don't bother
+        * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts
+        * for that as per mac80211. Then, REGISTER_MODE() will will actually
+        * check the eeprom reading for more reliable capability information.
+        * Order matters here as per mac80211's latest preference. This will
+        * all hopefullly soon go away. */
+
+       REGISTER_MODE(MODE_IEEE80211G);
+       if (ah->ah_version != AR5K_AR5212)
+               REGISTER_MODE(MODE_IEEE80211B);
+       REGISTER_MODE(MODE_IEEE80211A);
+
+       ath5k_debug_dump_modes(sc, modes);
+
+       return ret;
+}
+
+/*
+ * 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.
+ */
+static int
+ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+{
+       struct ath5k_hw *ah = sc->ah;
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n",
+               sc->curchan->chan, sc->curchan->freq,
+               chan->chan, chan->freq);
+
+       if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) {
+               /*
+                * 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.
+                */
+               ath5k_hw_set_intr(ah, 0);       /* disable interrupts */
+               ath5k_txq_cleanup(sc);          /* clear pending tx frames */
+               ath5k_rx_stop(sc);              /* turn off frame recv */
+               ret = ath5k_hw_reset(ah, sc->opmode, chan, true);
+               if (ret) {
+                       ATH5K_ERR(sc, "%s: unable to reset channel %u "
+                               "(%u Mhz)\n", __func__, chan->chan, chan->freq);
+                       return ret;
+               }
+               sc->curchan = chan;
+               ath5k_hw_set_txpower_limit(sc->ah, 0);
+
+               /*
+                * Re-enable rx framework.
+                */
+               ret = ath5k_rx_start(sc);
+               if (ret) {
+                       ATH5K_ERR(sc, "%s: unable to restart recv logic\n",
+                                       __func__);
+                       return ret;
+               }
+
+               /*
+                * Change channels and update the h/w rate map
+                * if we're switching; e.g. 11a to 11b/g.
+                *
+                * XXX needed?
+                */
+/*             ath5k_chan_change(sc, chan); */
+
+               ath5k_beacon_config(sc);
+               /*
+                * Re-enable interrupts.
+                */
+               ath5k_hw_set_intr(ah, sc->imask);
+       }
+
+       return 0;
+}
+
+static void
+ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
+{
+       if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) {
+               /* from Atheros NDIS driver, w/ permission */
+               static const struct {
+                       u16 rate;       /* tx/rx 802.11 rate */
+                       u16 timeOn;     /* LED on time (ms) */
+                       u16 timeOff;    /* LED off time (ms) */
+               } blinkrates[] = {
+                       { 108,  40,  10 },
+                       {  96,  44,  11 },
+                       {  72,  50,  13 },
+                       {  48,  57,  14 },
+                       {  36,  67,  16 },
+                       {  24,  80,  20 },
+                       {  22, 100,  25 },
+                       {  18, 133,  34 },
+                       {  12, 160,  40 },
+                       {  10, 200,  50 },
+                       {   6, 240,  58 },
+                       {   4, 267,  66 },
+                       {   2, 400, 100 },
+                       {   0, 500, 130 }
+               };
+               const struct ath5k_rate_table *rt =
+                               ath5k_hw_get_rate_table(sc->ah, mode);
+               unsigned int i, j;
+
+               BUG_ON(rt == NULL);
+
+               memset(sc->hwmap, 0, sizeof(sc->hwmap));
+               for (i = 0; i < 32; i++) {
+                       u8 ix = rt->rate_code_to_index[i];
+                       if (ix == 0xff) {
+                               sc->hwmap[i].ledon = msecs_to_jiffies(500);
+                               sc->hwmap[i].ledoff = msecs_to_jiffies(130);
+                               continue;
+                       }
+                       sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
+                       if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation ==
+                                       IEEE80211_RATE_OFDM)
+                               sc->hwmap[i].txflags |=
+                                               IEEE80211_RADIOTAP_F_SHORTPRE;
+                       /* receive frames include FCS */
+                       sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
+                                       IEEE80211_RADIOTAP_F_FCS;
+                       /* setup blink rate table to avoid per-packet lookup */
+                       for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++)
+                               if (blinkrates[j].rate == /* XXX why 7f? */
+                                               (rt->rates[ix].dot11_rate&0x7f))
+                                       break;
+
+                       sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].
+                                       timeOn);
+                       sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].
+                                       timeOff);
+               }
+       }
+
+       sc->curmode = mode;
+}
+
+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);
+}
+
+
+
+
+/***************\
+* Buffers setup *
+\***************/
+
+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 (likely(skb == NULL)) {
+               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 (unlikely(skb == NULL)) {
+                       ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+                                       sc->rxbufsize + sc->cachelsz - 1);
+                       return -ENOMEM;
+               }
+               /*
+                * 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);
+
+               bf->skb = skb;
+               bf->skbaddr = pci_map_single(sc->pdev,
+                       skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+               if (unlikely(pci_dma_mapping_error(bf->skbaddr))) {
+                       ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+                       dev_kfree_skb(skb);
+                       bf->skb = NULL;
+                       return -ENOMEM;
+               }
+       }
+
+       /*
+        * 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;
+       ath5k_hw_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 ieee80211_tx_control *ctl)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq *txq = sc->txq;
+       struct ath5k_desc *ds = bf->desc;
+       struct sk_buff *skb = bf->skb;
+       unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
+       int ret;
+
+       flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
+       bf->ctl = *ctl;
+       /* XXX endianness */
+       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+
+       if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
+               flags |= AR5K_TXDESC_NOACK;
+
+       pktlen = skb->len + FCS_LEN;
+
+       if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
+               keyidx = ctl->key_idx;
+               pktlen += ctl->icv_len;
+       }
+
+       ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
+               ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
+               (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0);
+       if (ret)
+               goto err_unmap;
+
+       ds->ds_link = 0;
+       ds->ds_data = bf->skbaddr;
+
+       spin_lock_bh(&txq->lock);
+       list_add_tail(&bf->list, &txq->q);
+       sc->tx_stats.data[txq->qnum].len++;
+       if (txq->link == NULL) /* is this first packet? */
+               ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr);
+       else /* no, so only link it */
+               *txq->link = bf->daddr;
+
+       txq->link = &ds->ds_link;
+       ath5k_hw_tx_start(ah, txq->qnum);
+       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_txbuf_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 == IEEE80211_IF_TYPE_AP) {
+               /*
+                * 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 == IEEE80211_IF_TYPE_IBSS) {
+               /*
+                * 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_setup_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, !sc->ah->ah_proc_tx_desc(sc->ah,
+                                       bf->desc));
+
+               ath5k_txbuf_free(sc, bf);
+
+               spin_lock_bh(&sc->txbuflock);
+               sc->tx_stats.data[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_tx_buf(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_tx_buf(ah,
+                                                       sc->txqs[i].qnum),
+                                       sc->txqs[i].link);
+                       }
+       }
+       ieee80211_start_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_put_rx_buf(ah, bf->daddr);
+       ath5k_hw_start_rx(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_pcu_recv(ah);     /* disable PCU */
+       ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
+       ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
+       mdelay(3);                      /* 3ms is long enough for 1 frame */
+
+       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 ieee80211_hdr *hdr = (void *)skb->data;
+       unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb);
+
+       if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) &&
+                       ds->ds_rxstat.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. */
+       if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
+                       !(ds->ds_rxstat.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_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb)
+{
+       u32 hw_tu;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+       if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) ==
+               IEEE80211_FTYPE_MGMT &&
+           (mgmt->frame_control & IEEE80211_FCTL_STYPE) ==
+               IEEE80211_STYPE_BEACON &&
+           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 might
+                * have updated the TSF, check if we need to update timers.
+                */
+               hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah));
+               if (hw_tu >= sc->nexttbtt) {
+                       ath5k_beacon_update_timers(sc,
+                               mgmt->u.beacon.timestamp);
+                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                               "detected HW merge from received beacon\n");
+               }
+       }
+}
+
+
+static void
+ath5k_tasklet_rx(unsigned long data)
+{
+       struct ieee80211_rx_status rxs = {};
+       struct sk_buff *skb;
+       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_buf *bf;
+       struct ath5k_desc *ds;
+       u16 len;
+       u8 stat;
+       int ret;
+       int hdrlen;
+       int pad;
+
+       spin_lock(&sc->rxbuflock);
+       do {
+               if (unlikely(list_empty(&sc->rxbuf))) {
+                       ATH5K_WARN(sc, "empty rx buf pool\n");
+                       break;
+               }
+               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+               BUG_ON(bf->skb == NULL);
+               skb = bf->skb;
+               ds = bf->desc;
+
+               /* TODO only one segment */
+               pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
+                               sc->desc_len, PCI_DMA_FROMDEVICE);
+
+               if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */
+                       break;
+
+               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds);
+               if (unlikely(ret == -EINPROGRESS))
+                       break;
+               else if (unlikely(ret)) {
+                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
+                       return;
+               }
+
+               if (unlikely(ds->ds_rxstat.rs_more)) {
+                       ATH5K_WARN(sc, "unsupported jumbo\n");
+                       goto next;
+               }
+
+               stat = ds->ds_rxstat.rs_status;
+               if (unlikely(stat)) {
+                       if (stat & AR5K_RXERR_PHY)
+                               goto next;
+                       if (stat & 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 (ds->ds_rxstat.rs_keyix ==
+                                               AR5K_RXKEYIX_INVALID &&
+                                               !(stat & AR5K_RXERR_CRC))
+                                       goto accept;
+                       }
+                       if (stat & AR5K_RXERR_MIC) {
+                               rxs.flag |= RX_FLAG_MMIC_ERROR;
+                               goto accept;
+                       }
+
+                       /* let crypto-error packets fall through in MNTR */
+                       if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
+                                       sc->opmode != IEEE80211_IF_TYPE_MNTR)
+                               goto next;
+               }
+accept:
+               len = ds->ds_rxstat.rs_datalen;
+               pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len,
+                               PCI_DMA_FROMDEVICE);
+               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+                               PCI_DMA_FROMDEVICE);
+               bf->skb = NULL;
+
+               skb_put(skb, len);
+
+               /*
+                * the hardware adds a padding to 4 byte boundaries between
+                * the header and the payload data if the header length is
+                * not multiples of 4 - remove it
+                */
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               if (hdrlen & 3) {
+                       pad = hdrlen % 4;
+                       memmove(skb->data + pad, skb->data, hdrlen);
+                       skb_pull(skb, pad);
+               }
+
+               /*
+                * 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.
+                */
+               rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp);
+               rxs.flag |= RX_FLAG_TSFT;
+
+               rxs.freq = sc->curchan->freq;
+               rxs.channel = sc->curchan->chan;
+               rxs.phymode = sc->curmode;
+
+               /*
+                * signal quality:
+                * the names here are misleading and the usage of these
+                * values by iwconfig makes it even worse
+                */
+               /* noise floor in dBm, from the last noise calibration */
+               rxs.noise = sc->ah->ah_noise_floor;
+               /* signal level in dBm */
+               rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi;
+               /*
+                * "signal" is actually displayed as Link Quality by iwconfig
+                * we provide a percentage based on rssi (assuming max rssi 64)
+                */
+               rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64;
+
+               rxs.antenna = ds->ds_rxstat.rs_antenna;
+               rxs.rate = ds->ds_rxstat.rs_rate;
+               rxs.flag |= ath5k_rx_decrypted(sc, ds, skb);
+
+               ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
+
+               /* check beacons in IBSS mode */
+               if (sc->opmode == IEEE80211_IF_TYPE_IBSS)
+                       ath5k_check_ibss_hw_merge(sc, skb);
+
+               __ieee80211_rx(sc->hw, skb, &rxs);
+               sc->led_rxrate = ds->ds_rxstat.rs_rate;
+               ath5k_led_event(sc, ATH_LED_RX);
+next:
+               list_move_tail(&bf->list, &sc->rxbuf);
+       } while (ath5k_rxbuf_setup(sc, bf) == 0);
+       spin_unlock(&sc->rxbuflock);
+}
+
+
+
+
+/*************\
+* TX Handling *
+\*************/
+
+static void
+ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+{
+       struct ieee80211_tx_status txs = {};
+       struct ath5k_buf *bf, *bf0;
+       struct ath5k_desc *ds;
+       struct sk_buff *skb;
+       int ret;
+
+       spin_lock(&txq->lock);
+       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+               ds = bf->desc;
+
+               /* TODO only one segment */
+               pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
+                               sc->desc_len, PCI_DMA_FROMDEVICE);
+               ret = sc->ah->ah_proc_tx_desc(sc->ah, ds);
+               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;
+               bf->skb = NULL;
+               pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
+                               PCI_DMA_TODEVICE);
+
+               txs.control = bf->ctl;
+               txs.retry_count = ds->ds_txstat.ts_shortretry +
+                       ds->ds_txstat.ts_longretry / 6;
+               if (unlikely(ds->ds_txstat.ts_status)) {
+                       sc->ll_stats.dot11ACKFailureCount++;
+                       if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY)
+                               txs.excessive_retries = 1;
+                       else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT)
+                               txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
+               } else {
+                       txs.flags |= IEEE80211_TX_STATUS_ACK;
+                       txs.ack_signal = ds->ds_txstat.ts_rssi;
+               }
+
+               ieee80211_tx_status(sc->hw, skb, &txs);
+               sc->tx_stats.data[txq->qnum].count++;
+
+               spin_lock(&sc->txbuflock);
+               sc->tx_stats.data[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);
+
+       ath5k_led_event(sc, ATH_LED_TX);
+}
+
+
+
+
+/*****************\
+* Beacon handling *
+\*****************/
+
+/*
+ * Setup the beacon frame for transmit.
+ */
+static int
+ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
+               struct ieee80211_tx_control *ctl)
+{
+       struct sk_buff *skb = bf->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(bf->skbaddr)) {
+               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
+               return -EIO;
+       }
+
+       ds = bf->desc;
+
+       flags = AR5K_TXDESC_NOACK;
+       if (sc->opmode == IEEE80211_IF_TYPE_IBSS && 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;
+       }
+
+       ds->ds_data = bf->skbaddr;
+       ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN,
+                       ieee80211_get_hdrlen_from_skb(skb),
+                       AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 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 usually called from interrupt context (ath5k_intr())
+ * but also from ath5k_beacon_config() in IBSS mode which in turn
+ * can be called from a tasklet and user context
+ */
+static void
+ath5k_beacon_send(struct ath5k_softc *sc)
+{
+       struct ath5k_buf *bf = sc->bbuf;
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
+
+       if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
+                       sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
+               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_PROC,
+                       "missed %u consecutive beacons\n", sc->bmisscount);
+               if (sc->bmisscount > 3) {               /* NB: 3 is a guess */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+                               "stuck beacon time (%u missed)\n",
+                               sc->bmisscount);
+                       tasklet_schedule(&sc->restq);
+               }
+               return;
+       }
+       if (unlikely(sc->bmisscount != 0)) {
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
+                       "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 */
+       }
+       pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len,
+                       PCI_DMA_TODEVICE);
+
+       ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
+       ath5k_hw_tx_start(ah, sc->bhalq);
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "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 HW merge 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",
+               bc_tsf, 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
+ *
+ * When operating in station mode we want to receive a BMISS interrupt when we
+ * stop seeing beacons from the AP we've associated with so we can look for
+ * another AP to associate with.
+ *
+ * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
+ * interrupts to detect HW merges only.
+ *
+ * AP mode is missing.
+ */
+static void
+ath5k_beacon_config(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+
+       ath5k_hw_set_intr(ah, 0);
+       sc->bmisscount = 0;
+
+       if (sc->opmode == IEEE80211_IF_TYPE_STA) {
+               sc->imask |= AR5K_INT_BMISS;
+       } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
+               /*
+                * 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 HW merges (automatic TSF updates).
+                */
+               ath5k_beaconq_config(sc);
+
+               sc->imask |= AR5K_INT_SWBA;
+
+               if (ath5k_hw_hasveol(ah))
+                       ath5k_beacon_send(sc);
+       }
+       /* TODO else AP */
+
+       ath5k_hw_set_intr(ah, sc->imask);
+}
+
+
+/********************\
+* Interrupt handling *
+\********************/
+
+static int
+ath5k_init(struct ath5k_softc *sc)
+{
+       int ret;
+
+       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.chan;
+       ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
+               goto done;
+       }
+       /*
+        * This is needed only to setup initial state
+        * but it's best done after a reset.
+        */
+       ath5k_hw_set_txpower_limit(sc->ah, 0);
+
+       /*
+        * Setup the hardware after reset: the key cache
+        * is filled as needed and 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.
+        */
+       ret = ath5k_rx_start(sc);
+       if (ret)
+               goto done;
+
+       /*
+        * Enable interrupts.
+        */
+       sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
+               AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+
+       ath5k_hw_set_intr(sc->ah, sc->imask);
+       /* Set ack to be sent at low bit-rates */
+       ath5k_hw_set_ack_bitrate_high(sc->ah, false);
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+
+       ret = 0;
+done:
+       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)) {
+               if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+                       del_timer_sync(&sc->led_tim);
+                       ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
+                       __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
+               }
+               ath5k_hw_set_intr(ah, 0);
+       }
+       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);
+       mutex_unlock(&sc->lock);
+
+       del_timer_sync(&sc->calib_tim);
+
+       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 {
+               /*
+                * Figure out the reason(s) for the interrupt.  Note
+                * that get_isr 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.
+                */
+               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);
+               status &= sc->imask; /* discard unasked for bits */
+               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) {
+                               /*
+                               * Software beacon alert--time to send a beacon.
+                               * Handle beacon transmission directly; deferring
+                               * this is too slow to meet timing constraints
+                               * under load.
+                               *
+                               * In IBSS mode we use this interrupt just to
+                               * keep track of the next TBTT (target beacon
+                               * transmission time) in order to detect hardware
+                               * merges (TSF updates).
+                               */
+                               if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
+                                        /* XXX: only if VEOL suppported */
+                                       u64 tsf = ath5k_hw_get_tsf64(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), tsf);
+                               } else {
+                                       ath5k_beacon_send(sc);
+                               }
+                       }
+                       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_RX)
+                               tasklet_schedule(&sc->rxtq);
+                       if (status & AR5K_INT_TX)
+                               tasklet_schedule(&sc->txtq);
+                       if (status & AR5K_INT_BMISS) {
+                       }
+                       if (status & AR5K_INT_MIB) {
+                               /* TODO */
+                       }
+               }
+       } 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(sc->hw);
+}
+
+/*
+ * 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",
+               sc->curchan->chan, sc->curchan->val);
+
+       if (ath5k_hw_get_rf_gain(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(sc->hw);
+       }
+       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
+               ATH5K_ERR(sc, "calibration of channel %u failed\n",
+                               sc->curchan->chan);
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+}
+
+
+
+/***************\
+* LED functions *
+\***************/
+
+static void
+ath5k_led_off(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+
+       if (test_bit(ATH_STAT_LEDENDBLINK, sc->status))
+               __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
+       else {
+               __set_bit(ATH_STAT_LEDENDBLINK, sc->status);
+               ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+               mod_timer(&sc->led_tim, jiffies + sc->led_off);
+       }
+}
+
+/*
+ * Blink the LED according to the specified on/off times.
+ */
+static void
+ath5k_led_blink(struct ath5k_softc *sc, unsigned int on,
+               unsigned int off)
+{
+       ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off);
+       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+       __set_bit(ATH_STAT_LEDBLINKING, sc->status);
+       __clear_bit(ATH_STAT_LEDENDBLINK, sc->status);
+       sc->led_off = off;
+       mod_timer(&sc->led_tim, jiffies + on);
+}
+
+static void
+ath5k_led_event(struct ath5k_softc *sc, int event)
+{
+       if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status)))
+               return;
+       if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status)))
+               return; /* don't interrupt active blink */
+       switch (event) {
+       case ATH_LED_TX:
+               ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon,
+                       sc->hwmap[sc->led_txrate].ledoff);
+               break;
+       case ATH_LED_RX:
+               ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon,
+                       sc->hwmap[sc->led_rxrate].ledoff);
+               break;
+       }
+}
+
+
+
+
+/********************\
+* Mac80211 functions *
+\********************/
+
+static int
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+                       struct ieee80211_tx_control *ctl)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_buf *bf;
+       unsigned long flags;
+       int hdrlen;
+       int pad;
+
+       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
+
+       if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
+               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);
+       if (hdrlen & 3) {
+               pad = hdrlen % 4;
+               if (skb_headroom(skb) < pad) {
+                       ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
+                               " headroom to pad %d\n", hdrlen, pad);
+                       return -1;
+               }
+               skb_push(skb, pad);
+               memmove(skb->data, skb->data+pad, hdrlen);
+       }
+
+       sc->led_txrate = ctl->tx_rate;
+
+       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, ctl->queue);
+               return -1;
+       }
+       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, ctl)) {
+               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);
+               dev_kfree_skb_any(skb);
+               return 0;
+       }
+
+       return 0;
+}
+
+static int
+ath5k_reset(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
+       /*
+        * Convert to a hw channel description with the flags
+        * constrained to reflect the current operating mode.
+        */
+       sc->curchan = hw->conf.chan;
+
+       ath5k_hw_set_intr(ah, 0);
+       ath5k_txq_cleanup(sc);
+       ath5k_rx_stop(sc);
+
+       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
+       if (unlikely(ret)) {
+               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
+               goto err;
+       }
+       ath5k_hw_set_txpower_limit(sc->ah, 0);
+
+       ret = ath5k_rx_start(sc);
+       if (unlikely(ret)) {
+               ATH5K_ERR(sc, "can't start recv logic\n");
+               goto err;
+       }
+       /*
+        * 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 started by ath5k_beacon_config */
+
+       ieee80211_wake_queues(hw);
+
+       return 0;
+err:
+       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 IEEE80211_IF_TYPE_STA:
+       case IEEE80211_IF_TYPE_IBSS:
+       case IEEE80211_IF_TYPE_MNTR:
+               sc->opmode = conf->type;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto end;
+       }
+       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;
+
+       mutex_lock(&sc->lock);
+       if (sc->vif != conf->vif)
+               goto end;
+
+       sc->vif = NULL;
+end:
+       mutex_unlock(&sc->lock);
+}
+
+static int
+ath5k_config(struct ieee80211_hw *hw,
+                       struct ieee80211_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       sc->bintval = conf->beacon_int;
+       ath5k_setcurmode(sc, conf->phymode);
+
+       return ath5k_chan_set(sc, conf->chan);
+}
+
+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;
+
+       /* Set to a reasonable value. Note that this will
+        * be set to mac80211's value at ath5k_config(). */
+       sc->bintval = 1000;
+       mutex_lock(&sc->lock);
+       if (sc->vif != vif) {
+               ret = -EIO;
+               goto unlock;
+       }
+       if (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);
+       }
+       mutex_unlock(&sc->lock);
+
+       return ath5k_reset(hw);
+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 = LE_READ_4(mclist->dmi_addr + 0);
+                       pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+                       val = LE_READ_4(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 == IEEE80211_IF_TYPE_MNTR)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+       if (sc->opmode != IEEE80211_IF_TYPE_STA)
+               rfilt |= AR5K_RX_FILTER_PROBEREQ;
+       if (sc->opmode != IEEE80211_IF_TYPE_AP &&
+               test_bit(ATH_STAT_PROMISC, sc->status))
+               rfilt |= AR5K_RX_FILTER_PROM;
+       if (sc->opmode == IEEE80211_IF_TYPE_STA ||
+               sc->opmode == IEEE80211_IF_TYPE_IBSS) {
+               rfilt |= AR5K_RX_FILTER_BEACON;
+       }
+
+       /* 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,
+               const u8 *local_addr, const u8 *addr,
+               struct ieee80211_key_conf *key)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret = 0;
+
+       switch(key->alg) {
+       case ALG_WEP:
+               break;
+       case ALG_TKIP:
+       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, addr);
+               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;
+               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:
+       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;
+
+       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_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 == IEEE80211_IF_TYPE_IBSS)
+               ath5k_beacon_update_timers(sc, 0);
+       else
+               ath5k_hw_reset_tsf(sc->ah);
+}
+
+static int
+ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+                       struct ieee80211_tx_control *ctl)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret;
+
+       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
+
+       mutex_lock(&sc->lock);
+
+       if (sc->opmode != IEEE80211_IF_TYPE_IBSS) {
+               ret = -EIO;
+               goto end;
+       }
+
+       ath5k_txbuf_free(sc, sc->bbuf);
+       sc->bbuf->skb = skb;
+       ret = ath5k_beacon_setup(sc, sc->bbuf, ctl);
+       if (ret)
+               sc->bbuf->skb = NULL;
+       else
+               ath5k_beacon_config(sc);
+
+end:
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
new file mode 100644 (file)
index 0000000..8287ae7
--- /dev/null
@@ -0,0 +1,179 @@
+/*-
+ * 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 "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;  /* tx 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 */
+       struct ieee80211_tx_control ctl;
+};
+
+/*
+ * 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;
+};
+
+#if CHAN_DEBUG
+#define ATH_CHAN_MAX   (26+26+26+200+200)
+#else
+#define ATH_CHAN_MAX   (14+14+14+252+20)       /* XXX what's the max? */
+#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 */
+       struct ieee80211_tx_queue_stats tx_stats;
+       struct ieee80211_low_level_stats ll_stats;
+       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
+       struct ieee80211_hw_mode modes[NUM_DRIVER_MODES];
+       struct ieee80211_channel channels[ATH_CHAN_MAX];
+       struct ieee80211_rate   rates[AR5K_MAX_RATES * NUM_DRIVER_MODES];
+       enum ieee80211_if_types opmode;
+       struct ath5k_hw         *ah;            /* Atheros HW */
+
+#if ATH5K_DEBUG
+       struct ath5k_dbg_info   debug;          /* debug info */
+#endif
+
+       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, 6);
+#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_LEDBLINKING   3               /* LED blink operation active */
+#define ATH_STAT_LEDENDBLINK   4               /* finish LED blink operation */
+#define ATH_STAT_LEDSOFT       5               /* enable LED gpio status */
+
+       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;
+
+       struct {
+               u8      rxflags;        /* radiotap rx flags */
+               u8      txflags;        /* radiotap tx flags */
+               u16     ledon;          /* softled on time */
+               u16     ledoff;         /* softled off time */
+       } hwmap[32];                            /* h/w rate ix mappings */
+
+       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 */
+                               led_off;        /* off time for current blink */
+       struct timer_list       led_tim;        /* led off timer */
+       u8                      led_rxrate;     /* current rx rate for LED */
+       u8                      led_txrate;     /* current tx rate for LED */
+
+       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 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_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 */
+};
+
+#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/debug.c b/drivers/net/wireless/ath5k/debug.c
new file mode 100644 (file)
index 0000000..4ba649e
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * 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.
+ */
+
+#include "debug.h"
+#include "base.h"
+
+static unsigned int ath5k_debug;
+module_param_named(debug, ath5k_debug, uint, 0);
+
+
+#if 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 {
+       char *name;
+       int addr;
+};
+
+#define REG_STRUCT_INIT(r) { #r, r }
+
+/* just a few random registers, might want to add more */
+static 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_CPCORN),
+       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) ? &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) ? &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 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: TSF */
+
+static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       char buf[100];
+       snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
+       return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
+}
+
+static ssize_t write_file_tsf(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       if (strncmp(userbuf, "reset", 5) == 0) {
+               ath5k_hw_reset_tsf(sc->ah);
+               printk(KERN_INFO "debugfs reset TSF\n");
+       }
+       return count;
+}
+
+static const struct file_operations fops_tsf = {
+       .read = read_file_tsf,
+       .write = write_file_tsf,
+       .open = ath5k_debugfs_open,
+       .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[1000];
+       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", 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;
+
+       if (strncmp(userbuf, "disable", 7) == 0) {
+               AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+               printk(KERN_INFO "debugfs disable beacons\n");
+       } else if (strncmp(userbuf, "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,
+};
+
+
+/* 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_u32("debug",
+                       0666, sc->debug.debugfs_phydir, &sc->debug.level);
+
+       sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
+                               sc->debug.debugfs_phydir,
+                               sc, &fops_registers);
+
+       sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
+                               sc->debug.debugfs_phydir,
+                               sc, &fops_tsf);
+
+       sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
+                               sc->debug.debugfs_phydir,
+                               sc, &fops_beacon);
+
+       sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
+                               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_tsf);
+       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_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes)
+{
+       unsigned int m, i;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES)))
+               return;
+
+       for (m = 0; m < NUM_DRIVER_MODES; m++) {
+               printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m,
+                               modes[m].num_channels, modes[m].num_rates);
+               printk(KERN_DEBUG " channels:\n");
+               for (i = 0; i < modes[m].num_channels; i++)
+                       printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
+                                       modes[m].channels[i].chan,
+                                       modes[m].channels[i].freq,
+                                       modes[m].channels[i].val,
+                                       modes[m].channels[i].flag);
+               printk(KERN_DEBUG " rates:\n");
+               for (i = 0; i < modes[m].num_rates; i++)
+                       printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
+                                       modes[m].rates[i].rate,
+                                       modes[m].rates[i].val,
+                                       modes[m].rates[i].flags,
+                                       modes[m].rates[i].val2);
+       }
+}
+
+static inline void
+ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done)
+{
+       struct ath5k_desc *ds = bf->desc;
+
+       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, ds->ds_ctl0, ds->ds_ctl1,
+               ds->ds_hw[0], ds->ds_hw[1],
+               !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
+}
+
+void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
+{
+       struct ath5k_desc *ds;
+       struct ath5k_buf *bf;
+       int status;
+
+       if (likely(!(sc->debug.level &
+           (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
+               return;
+
+       printk(KERN_DEBUG "rx queue %x, link %p\n",
+               ath5k_hw_get_rx_buf(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);
+               if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
+                       ath5k_debug_printrxbuf(bf, status == 0);
+       }
+       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, int done)
+{
+       struct ath5k_desc *ds = bf->desc;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+               return;
+
+       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, ds->ds_ctl0, ds->ds_ctl1,
+               ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
+               !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
+}
+
+#endif /* if ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
new file mode 100644 (file)
index 0000000..2b491cb
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * 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
+
+/* set this to 1 for debugging output */
+#ifndef ATH5K_DEBUG
+#define ATH5K_DEBUG    0
+#endif
+
+struct ath5k_softc;
+struct ath5k_hw;
+struct ieee80211_hw_mode;
+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_tsf;
+       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_BEACON_PROC: beacon ISR proc
+ * @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_DUMPMODES: dump modes
+ * @ATH5K_DEBUG_TRACE: trace function calls
+ * @ATH5K_DEBUG_FATAL: fatal errors
+ * @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_BEACON_PROC = 0x00000020,
+       ATH5K_DEBUG_CALIBRATE   = 0x00000100,
+       ATH5K_DEBUG_TXPOWER     = 0x00000200,
+       ATH5K_DEBUG_LED         = 0x00000400,
+       ATH5K_DEBUG_DUMP_RX     = 0x00001000,
+       ATH5K_DEBUG_DUMP_TX     = 0x00002000,
+       ATH5K_DEBUG_DUMPMODES   = 0x00004000,
+       ATH5K_DEBUG_TRACE       = 0x00010000,
+       ATH5K_DEBUG_FATAL       = 0x80000000,
+       ATH5K_DEBUG_ANY         = 0xffffffff
+};
+
+#if 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_modes(struct ath5k_softc *sc,
+                       struct ieee80211_hw_mode *modes);
+
+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, int done);
+
+#else /* no debugging */
+
+#define ATH5K_TRACE(_sc) /* empty */
+
+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_modes(struct ath5k_softc *sc,
+                       struct ieee80211_hw_mode *modes) {}
+
+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, int done) {}
+
+#endif /* if ATH5K_DEBUG */
+
+#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
new file mode 100644 (file)
index 0000000..3a4bf40
--- /dev/null
@@ -0,0 +1,4351 @@
+ /*
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007 Matthew W. S. Bell  <mentor@madwifi.org>
+ * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2007 Pavel Roskin <proski@gnu.org>
+ * Copyright (c) 2007 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.
+ *
+ */
+
+/*
+ * HW related functions for Atheros Wireless LAN devices.
+ */
+
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#include "reg.h"
+#include "base.h"
+#include "debug.h"
+
+/*Rate tables*/
+static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
+static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B;
+static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G;
+static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO;
+static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR;
+
+/*Prototypes*/
+static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
+static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
+static int ath5k_hw_setup_4word_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);
+static bool ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
+       unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
+       unsigned int);
+static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
+static int ath5k_hw_setup_2word_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);
+static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
+static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *, struct ath5k_desc *);
+static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *, struct ath5k_desc *);
+static int ath5k_hw_get_capabilities(struct ath5k_hw *);
+
+static int ath5k_eeprom_init(struct ath5k_hw *);
+static int ath5k_eeprom_read_mac(struct ath5k_hw *, u8 *);
+
+static int ath5k_hw_enable_pspoll(struct ath5k_hw *, u8 *, u16);
+static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
+
+/*
+ * Enable to overwrite the country code (use "00" for debug)
+ */
+#if 0
+#define COUNTRYCODE "00"
+#endif
+
+/*******************\
+  General Functions
+\*******************/
+
+/*
+ * Functions used internaly
+ */
+
+static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
+{
+       return turbo == true ? (usec * 80) : (usec * 40);
+}
+
+static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
+{
+       return turbo == true ? (clock / 80) : (clock / 40);
+}
+
+/*
+ * Check if a register write has been completed
+ */
+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 == true) && (data & flag))
+                       break;
+               else if ((data & flag) == val)
+                       break;
+               udelay(15);
+       }
+
+       return (i <= 0) ? -EAGAIN : 0;
+}
+
+
+/***************************************\
+       Attach/Detach Functions
+\***************************************/
+
+/*
+ * Check if the device is supported and initialize the needed structs
+ */
+struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
+{
+       struct ath5k_hw *ah;
+       u8 mac[ETH_ALEN];
+       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
+        */
+
+       /* Get reg domain from eeprom */
+       ath5k_get_regdomain(ah);
+
+       ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
+       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 revision based on the pci id
+        */
+       ah->ah_version = mac_version;
+
+       /*Fill the ath5k_hw struct with the needed functions*/
+       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_tx_desc = ath5k_hw_setup_4word_tx_desc;
+               ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
+               ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
+       } else {
+               ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
+               ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
+               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_new_rx_status;
+       else if (ah->ah_version <= AR5K_AR5211)
+               ah->ah_proc_rx_desc = ath5k_hw_proc_old_rx_status;
+
+       /* Bring device out of sleep and reset it's units */
+       ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, 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);
+
+       if (ah->ah_version == AR5K_AR5210)
+               ah->ah_radio_2ghz_revision = 0;
+       else
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                               CHANNEL_2GHZ);
+
+       /* Return on unsuported chips (unsupported eeprom etc) */
+       if(srev >= AR5K_SREV_VER_AR5416){
+               ATH5K_ERR(sc, "Device not yet supported.\n");
+               ret = -ENODEV;
+               goto err_free;
+       }
+
+       /* Identify single chip solutions */
+       if((srev <= AR5K_SREV_VER_AR5414) &&
+       (srev >= AR5K_SREV_VER_AR2424)) {
+               ah->ah_single_chip = true;
+       } else {
+               ah->ah_single_chip = false;
+       }
+
+       /* Single chip radio */
+       if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
+               ah->ah_radio_2ghz_revision = 0;
+
+       /* Identify the radio chip*/
+       if (ah->ah_version == AR5K_AR5210) {
+               ah->ah_radio = AR5K_RF5110;
+       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
+               ah->ah_radio = AR5K_RF5111;
+       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
+               ah->ah_radio = AR5K_RF5112;
+       } else {
+               ah->ah_radio = AR5K_RF5413;
+       }
+
+       ah->ah_phy = AR5K_PHY(0);
+
+       /*
+        * Get card capabilities, values, ...
+        */
+
+       ret = ath5k_eeprom_init(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to init EEPROM\n");
+               goto err_free;
+       }
+
+       /* Get misc capabilities */
+       ret = ath5k_hw_get_capabilities(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
+                       sc->pdev->device);
+               goto err_free;
+       }
+
+       /* Get MAC address */
+       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_free;
+       }
+
+       ath5k_hw_set_lladdr(ah, mac);
+       /* 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_set_rfgain_opt(ah);
+
+       return ah;
+err_free:
+       kfree(ah);
+err:
+       return ERR_PTR(ret);
+}
+
+/*
+ * Bring up MAC + PHY Chips
+ */
+static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+{
+       u32 turbo, mode, clock;
+       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;
+                       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);
+       }
+
+       /* ...reset chipset and PCI device */
+       if (ah->ah_single_chip == false && ath5k_hw_nic_reset(ah,
+                               AR5K_RESET_CTL_CHIP | AR5K_RESET_CTL_PCI)) {
+               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n");
+               return -EIO;
+       }
+
+       if (ah->ah_version == AR5K_AR5210)
+               udelay(2300);
+
+       /* ...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) {
+               /* ...set the PHY operating mode */
+               ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+               udelay(300);
+
+               ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
+               ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
+       }
+
+       return 0;
+}
+
+/*
+ * Get the rate table for a specific operation mode
+ */
+const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah,
+               unsigned int mode)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (!test_bit(mode, ah->ah_capabilities.cap_mode))
+               return NULL;
+
+       /* Get rate tables */
+       switch (mode) {
+       case MODE_IEEE80211A:
+               return &ath5k_rt_11a;
+       case MODE_ATHEROS_TURBO:
+               return &ath5k_rt_turbo;
+       case MODE_IEEE80211B:
+               return &ath5k_rt_11b;
+       case MODE_IEEE80211G:
+               return &ath5k_rt_11g;
+       case MODE_ATHEROS_TURBOG:
+               return &ath5k_rt_xr;
+       }
+
+       return NULL;
+}
+
+/*
+ * Free the ath5k_hw struct
+ */
+void ath5k_hw_detach(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_rf_banks != NULL)
+               kfree(ah->ah_rf_banks);
+
+       /* assume interrupts are down */
+       kfree(ah);
+}
+
+/****************************\
+  Reset function and helpers
+\****************************/
+
+/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the OFDM timings for the AR5212 upon reset. This is a helper for
+ * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
+ * depending on the bandwidth of the channel.
+ *
+ */
+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->val & CHANNEL_OFDM))
+               BUG();
+
+       /* Seems there are two PLLs, one for baseband sampling and one
+        * for tuning. Tuning basebands are 40 MHz or 80MHz when in
+        * turbo. */
+       clock = channel->val & CHANNEL_TURBO ? 80 : 40;
+       coef_scaled = ((5 * (clock << 24)) / 2) /
+       channel->freq;
+
+       for (coef_exp = 31; coef_exp > 0; coef_exp--)
+               if ((coef_scaled >> coef_exp) & 0x1)
+                       break;
+
+       if (!coef_exp)
+               return -EINVAL;
+
+       coef_exp = 14 - (coef_exp - 24);
+       coef_man = coef_scaled +
+               (1 << (24 - coef_exp - 1));
+       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;
+}
+
+/**
+ * ath5k_hw_write_rate_duration - set rate duration during hw resets
+ *
+ * @ah: the &struct ath5k_hw
+ * @driver_mode: one of enum ieee80211_phymode or our one of our own
+ *     vendor modes
+ *
+ * Write the rate duration table for the current mode upon hw reset. This
+ * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
+ * an ACK timeout for the hardware for the current mode for each rate. The
+ * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
+ * and 11Mbps) have another register for the short preamble ACK timeout
+ * calculation.
+ *
+ */
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
+       unsigned int driver_mode)
+{
+       struct ath5k_softc *sc = ah->ah_sc;
+       const struct ath5k_rate_table *rt;
+       unsigned int i;
+
+       /* Get rate table for the current operating mode */
+       rt = ath5k_hw_get_rate_table(ah,
+               driver_mode);
+
+       /* Write rate duration table */
+       for (i = 0; i < rt->rate_count; i++) {
+               const struct ath5k_rate *rate, *control_rate;
+               u32 reg;
+               u16 tx_time;
+
+               rate = &rt->rates[i];
+               control_rate = &rt->rates[rate->control_rate];
+
+               /* Set ACK timeout */
+               reg = AR5K_RATE_DUR(rate->rate_code);
+
+               /* 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 = ieee80211_generic_frame_duration(sc->hw,
+                       sc->vif, 10, control_rate->rate_kbps/100);
+
+               ath5k_hw_reg_write(ah, tx_time, reg);
+
+               if (!HAS_SHPREAMBLE(i))
+                       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));
+       }
+}
+
+/*
+ * Main reset function
+ */
+int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
+       struct ieee80211_channel *channel, bool change_channel)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 data, s_seq, s_ant, s_led[3];
+       unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       s_seq = 0;
+       s_ant = 0;
+       ee_mode = 0;
+       freq = 0;
+       mode = 0;
+
+       /*
+        * Save some registers before a reset
+        */
+       /*DCU/Antenna selection not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+               if (change_channel == true) {
+                       /* Seq number for queue 0 -do this for all queues ? */
+                       s_seq = ath5k_hw_reg_read(ah,
+                                       AR5K_QUEUE_DFS_SEQNUM(0));
+                       /*Default antenna*/
+                       s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+               }
+       }
+
+       /*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);
+
+       if (change_channel == true && ah->ah_rf_banks != NULL)
+               ath5k_hw_get_rf_gain(ah);
+
+
+       /*Wakeup the device*/
+       ret = ath5k_hw_nic_wakeup(ah, channel->val, false);
+       if (ret)
+               return ret;
+
+       /*
+        * Initialize operating mode
+        */
+       ah->ah_op_mode = op_mode;
+
+       /*
+        * 5111/5112 Settings
+        * 5210 only comes with RF5110
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               if (ah->ah_radio != AR5K_RF5111 &&
+                       ah->ah_radio != AR5K_RF5112 &&
+                       ah->ah_radio != AR5K_RF5413) {
+                       ATH5K_ERR(ah->ah_sc,
+                               "invalid phy radio: %u\n", ah->ah_radio);
+                       return -EINVAL;
+               }
+
+               switch (channel->val & CHANNEL_MODES) {
+               case CHANNEL_A:
+                       mode = AR5K_INI_VAL_11A;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       driver_mode = MODE_IEEE80211A;
+                       break;
+               case CHANNEL_G:
+                       mode = AR5K_INI_VAL_11G;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       driver_mode = MODE_IEEE80211G;
+                       break;
+               case CHANNEL_B:
+                       mode = AR5K_INI_VAL_11B;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+                       driver_mode = MODE_IEEE80211B;
+                       break;
+               case CHANNEL_T:
+                       mode = AR5K_INI_VAL_11A_TURBO;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       driver_mode = MODE_ATHEROS_TURBO;
+                       break;
+               /*Is this ok on 5211 too ?*/
+               case CHANNEL_TG:
+                       mode = AR5K_INI_VAL_11G_TURBO;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       driver_mode = MODE_ATHEROS_TURBOG;
+                       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_INI_VAL_XR;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       driver_mode = MODE_IEEE80211A;
+                       break;
+               default:
+                       ATH5K_ERR(ah->ah_sc,
+                               "invalid channel: %d\n", channel->freq);
+                       return -EINVAL;
+               }
+
+               /* PHY access enable */
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+
+       }
+
+       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(ah, freq);
+               if (ret)
+                       return ret;
+
+               mdelay(1);
+
+               /*
+                * Write some more initial register settings
+                */
+               if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */
+                       ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
+
+                       if (channel->val == CHANNEL_G)
+                               ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */
+                       else
+                               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83));
+
+                       ath5k_hw_reg_write(ah, 0x000001b5, 0xa228); /* 0x000009b5 */
+                       ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
+                       ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
+                       ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
+                       ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
+               }
+
+               /* Fix for first revision of the RF5112 RF chipset */
+               if (ah->ah_radio >= AR5K_RF5112 &&
+                               ah->ah_radio_5ghz_revision <
+                               AR5K_SREV_RAD_5112A) {
+                       ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+                                       AR5K_PHY_CCKTXCTL);
+                       if (channel->val & CHANNEL_5GHZ)
+                               data = 0xffb81020;
+                       else
+                               data = 0xffb80d20;
+                       ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+               }
+
+               /*
+                * Set TX power (FIXME)
+                */
+               ret = ath5k_hw_txpower(ah, channel, 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, driver_mode);
+
+               /*
+                * Write RF registers
+                * TODO:Does this work on 5211 (5111) ?
+                */
+               ret = ath5k_hw_rfregs(ah, channel, mode);
+               if (ret)
+                       return ret;
+
+               /*
+                * Configure additional registers
+                */
+
+               /* Write OFDM timings on 5212*/
+               if (ah->ah_version == AR5K_AR5212 &&
+                       channel->val & 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 (driver_mode == MODE_IEEE80211B)
+                               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+                       else
+                               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+               }
+
+               /*
+                * Set channel and calibrate the PHY
+                */
+               ret = ath5k_hw_channel(ah, channel);
+               if (ret)
+                       return ret;
+
+               /* Set antenna mode */
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
+                       ah->ah_antenna[ee_mode][0], 0xfffffc06);
+
+               /*
+                * 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;
+               }
+
+               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);
+
+               /* Commit values from EEPROM */
+               if (ah->ah_radio == AR5K_RF5111)
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+                           AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+                       AR5K_PHY(0x5a));
+
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
+                       (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
+                       0xffffc07f);
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
+                       (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
+                       0xfffc0fff);
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
+                       (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
+                       ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
+                       0xffff0000);
+
+               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(0x0d));
+
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
+                       ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
+                       (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
+               AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
+
+               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]);
+
+               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]);
+
+       } else {
+               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) {
+               ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
+               ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
+       }
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+       ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
+       ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
+
+       /*
+        * Misc
+        */
+       /* XXX: add ah->aid once mac80211 gives this to us */
+       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+
+       ath5k_hw_set_opmode(ah);
+       /*PISR/SISR Not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
+               /* If we later allow tuning for this, store into sc structure */
+               data = AR5K_TUNE_RSSI_THRES |
+                       AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
+               ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
+       }
+
+       /*
+        * Set Rx/Tx DMA Configuration
+        *(passing dma size not available on 5210)
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR,
+                               AR5K_DMASIZE_512B | AR5K_TXCFG_DMASIZE);
+               AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW,
+                               AR5K_DMASIZE_512B);
+       }
+
+       /*
+        * Enable the PHY and wait until completion
+        */
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+
+       /*
+        * 5111/5112 Specific
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+                       AR5K_PHY_RX_DELAY_M;
+               data = (channel->val & CHANNEL_CCK) ?
+                       ((data << 2) / 22) : (data / 10);
+
+               udelay(100 + data);
+       } else {
+               mdelay(1);
+       }
+
+       /*
+        * Enable calibration and wait until completion
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                               AR5K_PHY_AGCCTL_CAL);
+
+       if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_CAL, 0, false)) {
+               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
+                       channel->freq);
+               return -EAGAIN;
+       }
+
+       ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
+       if (ret)
+               return ret;
+
+       ah->ah_calibration = false;
+
+       /* A and G modes can use QAM modulation which requires enabling
+        * I and Q calibration. Don't bother in B mode. */
+       if (!(driver_mode == MODE_IEEE80211B)) {
+               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);
+       }
+
+       /*
+        * Reset queues and start beacon timers at the end of the reset routine
+        */
+       for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
+               /*No QCU on 5210*/
+               if (ah->ah_version != AR5K_AR5210)
+                       AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), 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;
+               }
+       }
+
+       /* Pre-enable interrupts on 5211/5212*/
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
+                               AR5K_INT_FATAL);
+
+       /*
+        * Set RF kill flags if supported by the device (read from the EEPROM)
+        * Disable gpio_intr for now since it results system hang.
+        * TODO: Handle this in ath5k_intr
+        */
+#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
+
+       /*
+        * Set the 32MHz reference clock on 5212 phy clock sleep register
+        */
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, 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);
+               ath5k_hw_reg_write(ah, ah->ah_radio == AR5K_RF5111 ?
+                       AR5K_PHY_SPENDING_RF5111 : AR5K_PHY_SPENDING_RF5112,
+                       AR5K_PHY_SPENDING);
+       }
+
+       /*
+        * Disable beacons and reset the register
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
+                       AR5K_BEACON_RESET_TSF);
+
+       return 0;
+}
+
+/*
+ * 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_CHIP;
+               mask &= AR5K_RESET_CTL_CHIP;
+       } 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;
+}
+
+/*
+ * Power management functions
+ */
+
+/*
+ * 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;
+
+       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 == true)
+                       ath5k_hw_reg_write(ah,
+                               AR5K_SLEEP_CTL_SLE | sleep_duration,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_FULL_SLEEP:
+               if (set_chip == true)
+                       ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_AWAKE:
+               if (set_chip == false)
+                       goto commit;
+
+               ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
+                               AR5K_SLEEP_CTL);
+
+               for (i = 5000; 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, AR5K_SLEEP_CTL_SLE_WAKE,
+                               AR5K_SLEEP_CTL);
+               }
+
+               /* Fail if the chip didn't wake up */
+               if (i <= 0)
+                       return -EIO;
+
+               staid &= ~AR5K_STA_ID1_PWR_SV;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+commit:
+       ah->ah_power_mode = mode;
+       ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/***********************\
+  DMA Related Functions
+\***********************/
+
+/*
+ * Receive functions
+ */
+
+/*
+ * Start DMA receive
+ */
+void ath5k_hw_start_rx(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
+}
+
+/*
+ * Stop DMA receive
+ */
+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 = 2000; i > 0 &&
+                       (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
+                       i--)
+               udelay(10);
+
+       return i ? 0 : -EBUSY;
+}
+
+/*
+ * Get the address of the RX Descriptor
+ */
+u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
+{
+       return ath5k_hw_reg_read(ah, AR5K_RXDP);
+}
+
+/*
+ * Set the address of the RX Descriptor
+ */
+void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*TODO:Shouldn't we check if RX is enabled first ?*/
+       ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
+}
+
+/*
+ * Transmit functions
+ */
+
+/*
+ * Start DMA transmit for a specific queue
+ * (see also QCU/DCU functions)
+ */
+int ath5k_hw_tx_start(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);
+       } 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;
+}
+
+/*
+ * Stop DMA transmit for a specific queue
+ * (see also QCU/DCU functions)
+ */
+int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+{
+       unsigned int i = 100;
+       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);
+       } 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);
+
+               /* Clear register */
+               ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
+       }
+
+       /* TODO: Check for success else return error */
+       return 0;
+}
+
+/*
+ * Get the address of the TX Descriptor for a specific queue
+ * (see also QCU/DCU functions)
+ */
+u32 ath5k_hw_get_tx_buf(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);
+}
+
+/*
+ * Set the address of the TX Descriptor for a specific queue
+ * (see also QCU/DCU functions)
+ */
+int ath5k_hw_put_tx_buf(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;
+}
+
+/*
+ * Update tx trigger level
+ */
+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_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
+
+       /*TODO: Boundary check on trigger_level*/
+       trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
+                       AR5K_TXCFG_TXFULL);
+
+       if (increase == false) {
+               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_intr(ah, imr);
+
+       return ret;
+}
+
+/*
+ * Interrupt handling
+ */
+
+/*
+ * Check if we have pending interrupts
+ */
+bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_INTPEND);
+}
+
+/*
+ * Get interrupt mask (ISR)
+ */
+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 the Read-And-Clear shadow register
+                * Note: PISR/SISR Not available on 5210
+                */
+               data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
+       }
+
+       /*
+        * Get abstract interrupt mask (driver-compatible)
+        */
+       *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
+
+       if (unlikely(data == AR5K_INT_NOCARD))
+               return -ENODEV;
+
+       if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
+               *interrupt_mask |= AR5K_INT_RX;
+
+       if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
+               | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
+               *interrupt_mask |= AR5K_INT_TX;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               /*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;
+       }
+
+       /*
+        * 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 successfull assoc + some jiffies.
+        */
+#if 0
+       interrupt_mask &= ~AR5K_INT_BMISS;
+#endif
+
+       /*
+        * In case we didn't handle anything,
+        * print the register value.
+        */
+       if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
+               ATH5K_PRINTF("0x%08x\n", data);
+
+       return 0;
+}
+
+/*
+ * Set interrupt mask
+ */
+enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
+{
+       enum ath5k_int old_mask, int_mask;
+
+       /*
+        * Disable card interrupts to prevent any race conditions
+        * (they will be re-enabled afterwards).
+        */
+       ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
+
+       old_mask = ah->ah_imr;
+
+       /*
+        * Add additional, chipset-dependent interrupt mask flags
+        * and write them to the IMR (interrupt mask register).
+        */
+       int_mask = new_mask & AR5K_INT_COMMON;
+
+       if (new_mask & AR5K_INT_RX)
+               int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
+                       AR5K_IMR_RXDESC;
+
+       if (new_mask & AR5K_INT_TX)
+               int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
+                       AR5K_IMR_TXURN;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               if (new_mask & AR5K_INT_FATAL) {
+                       int_mask |= AR5K_IMR_HIUERR;
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
+                                       AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
+               }
+       }
+
+       ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
+
+       /* Store new interrupt mask */
+       ah->ah_imr = new_mask;
+
+       /* ..re-enable interrupts */
+       ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
+
+       return old_mask;
+}
+
+
+/*************************\
+  EEPROM access functions
+\*************************/
+
+/*
+ * 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;
+}
+
+/*
+ * Write to eeprom - currently disabled, use at your own risk
+ */
+static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
+{
+#if 0
+       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);
+       } else {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+                               AR5K_EEPROM_CMD_RESET);
+       }
+
+       /*
+        * Write data to data register
+        */
+
+       if (ah->ah_version == AR5K_AR5210) {
+               ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
+       } else {
+               ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
+               ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+                               AR5K_EEPROM_CMD_WRITE);
+       }
+
+       /*
+        * Check status
+        */
+
+       for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
+               status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
+               if (status & AR5K_EEPROM_STAT_WRDONE) {
+                       if (status & AR5K_EEPROM_STAT_WRERR)
+                               return EIO;
+                       return 0;
+               }
+               udelay(15);
+       }
+#endif
+       ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
+       return -EIO;
+}
+
+/*
+ * Translate binary channel representation in EEPROM to frequency
+ */
+static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
+{
+       u16 val;
+
+       if (bin == AR5K_EEPROM_CHANNEL_DIS)
+               return bin;
+
+       if (mode == AR5K_EEPROM_MODE_11A) {
+               if (ah->ah_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 (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
+                       val = bin + 2300;
+               else
+                       val = bin + 2400;
+       }
+
+       return val;
+}
+
+/*
+ * 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_ant_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) | 0x1;
+       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 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;
+
+       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_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_6 &&
+           mode == AR5K_EEPROM_MODE_11G)
+               ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/*
+ * Initialize eeprom & capabilities structs
+ */
+static int ath5k_eeprom_init(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       unsigned int mode, i;
+       int ret;
+       u32 offset;
+       u16 val;
+
+       /* Initial TX thermal adjustment values */
+       ee->ee_tx_clip = 4;
+       ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
+       ee->ee_gain_select = 1;
+
+       /*
+        * 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);
+       }
+
+       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;
+       }
+
+       /*
+        * Get conformance test limit values
+        */
+       offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
+       ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
+
+       for (i = 0; i < ee->ee_ctls; i++) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_ctl[i] = (val >> 8) & 0xff;
+               ee->ee_ctl[i + 1] = val & 0xff;
+       }
+
+       /*
+        * Get values for 802.11a (5GHz)
+        */
+       mode = AR5K_EEPROM_MODE_11A;
+
+       ee->ee_turbo_max_power[mode] =
+                       AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
+
+       offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
+
+       ret = ath5k_eeprom_read_ants(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       AR5K_EEPROM_READ(offset++, val);
+       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
+       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(offset++, 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;
+
+       ret = ath5k_eeprom_read_modes(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_margin_tx_rx[mode] = val & 0x3f;
+       }
+
+       /*
+        * Get values for 802.11b (2.4GHz)
+        */
+       mode = AR5K_EEPROM_MODE_11B;
+       offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
+
+       ret = ath5k_eeprom_read_ants(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       AR5K_EEPROM_READ(offset++, val);
+       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
+       ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
+       ee->ee_db[mode][1]              = val & 0x7;
+
+       ret = ath5k_eeprom_read_modes(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_cal_pier[mode][0] =
+                       ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
+               ee->ee_cal_pier[mode][1] =
+                       ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
+
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_cal_pier[mode][2] =
+                       ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
+       }
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+               ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+
+       /*
+        * Get values for 802.11g (2.4GHz)
+        */
+       mode = AR5K_EEPROM_MODE_11G;
+       offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
+
+       ret = ath5k_eeprom_read_ants(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       AR5K_EEPROM_READ(offset++, val);
+       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
+       ee->ee_ob[mode][1]              = (val >> 4) & 0x7;
+       ee->ee_db[mode][1]              = val & 0x7;
+
+       ret = ath5k_eeprom_read_modes(ah, &offset, mode);
+       if (ret)
+               return ret;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_cal_pier[mode][0] =
+                       ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
+               ee->ee_cal_pier[mode][1] =
+                       ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
+
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_turbo_max_power[mode] = val & 0x7f;
+               ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
+
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_cal_pier[mode][2] =
+                       ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+
+               AR5K_EEPROM_READ(offset++, 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(offset++, val);
+                       ee->ee_cck_ofdm_gain_delta = val & 0xff;
+               }
+       }
+
+       /*
+        * Read 5GHz EEPROM channels
+        */
+
+       return 0;
+}
+
+/*
+ * Read the MAC address from eeprom
+ */
+static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+       u8 mac_d[ETH_ALEN];
+       u32 total, offset;
+       u16 data;
+       int octet, ret;
+
+       memset(mac, 0, ETH_ALEN);
+       memset(mac_d, 0, ETH_ALEN);
+
+       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;
+       }
+
+       memcpy(mac, mac_d, ETH_ALEN);
+
+       if (!total || total == 3 * 0xffff)
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Read/Write regulatory domain
+ */
+static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write,
+       enum ath5k_regdom *regdomain)
+{
+       u16 ee_regdomain;
+
+       /* Read current value */
+       if (write != true) {
+               ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain;
+               *regdomain = ath5k_regdom_to_ieee(ee_regdomain);
+               return true;
+       }
+
+       ee_regdomain = ath5k_regdom_from_ieee(*regdomain);
+
+       /* Try to write a new value */
+       if (ah->ah_capabilities.cap_eeprom.ee_protect &
+                       AR5K_EEPROM_PROTECT_WR_128_191)
+               return false;
+       if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0)
+               return false;
+
+       ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
+
+       return true;
+}
+
+/*
+ * Use the above to write a new regulatory domain
+ */
+int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain)
+{
+       enum ath5k_regdom ieee_regdomain;
+
+       ieee_regdomain = ath5k_regdom_to_ieee(regdomain);
+
+       if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true)
+               return 0;
+
+       return -EIO;
+}
+
+/*
+ * Fill the capabilities struct
+ */
+static int ath5k_hw_get_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(MODE_IEEE80211A, ah->ah_capabilities.cap_mode);
+               __set_bit(MODE_ATHEROS_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)) {
+                       ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
+                       ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
+
+                       /* Set supported modes */
+                       __set_bit(MODE_IEEE80211A,
+                                       ah->ah_capabilities.cap_mode);
+                       __set_bit(MODE_ATHEROS_TURBO,
+                                       ah->ah_capabilities.cap_mode);
+                       if (ah->ah_version == AR5K_AR5212)
+                               __set_bit(MODE_ATHEROS_TURBOG,
+                                               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_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
+                       ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
+
+                       if (AR5K_EEPROM_HDR_11B(ee_header))
+                               __set_bit(MODE_IEEE80211B,
+                                               ah->ah_capabilities.cap_mode);
+
+                       if (AR5K_EEPROM_HDR_11G(ee_header))
+                               __set_bit(MODE_IEEE80211G,
+                                               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;
+}
+
+/*********************************\
+  Protocol Control Unit Functions
+\*********************************/
+
+/*
+ * Set Operation mode
+ */
+int ath5k_hw_set_opmode(struct ath5k_hw *ah)
+{
+       u32 pcu_reg, beacon_reg, low_id, high_id;
+
+       pcu_reg = 0;
+       beacon_reg = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (ah->ah_op_mode) {
+       case IEEE80211_IF_TYPE_IBSS:
+               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
+                       (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               beacon_reg |= AR5K_BCR_ADHOC;
+               break;
+
+       case IEEE80211_IF_TYPE_AP:
+               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
+                       (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               beacon_reg |= AR5K_BCR_AP;
+               break;
+
+       case IEEE80211_IF_TYPE_STA:
+               pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
+                       (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_PWR_SV : 0);
+       case IEEE80211_IF_TYPE_MNTR:
+               pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
+                       (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;
+}
+
+/*
+ * BSSID Functions
+ */
+
+/*
+ * Get station id
+ */
+void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       memcpy(mac, ah->ah_sta_id, ETH_ALEN);
+}
+
+/*
+ * Set station id
+ */
+int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
+{
+       u32 low_id, high_id;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Set new station ID */
+       memcpy(ah->ah_sta_id, mac, ETH_ALEN);
+
+       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, high_id, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/*
+ * Set BSSID
+ */
+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, 0xfffffff, AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, 0xfffffff, 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 - set common bits we should listen to
+ *
+ * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode every bit matters. In AP
+ * mode with a single BSS every bit matters as well. In AP mode with
+ * multiple BSSes not every bit matters.
+ *
+ * @ah: the &struct ath5k_hw
+ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
+ *
+ * Note that this is a simple filter and *does* not filter out all
+ * relevant frames. Some non-relevant frames will get through, probability
+ * jocks are welcomed to compute.
+ *
+ * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
+ * computing the set of:
+ *
+ *     ~ ( MAC XOR BSSID )
+ *
+ * When you do this you are essentially computing the common bits. Later it
+ * is assumed the harware will "and" (&) the BSSID mask with the MAC address
+ * to obtain the relevant bits which should match on the destination frame.
+ *
+ * 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);
+
+       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;
+}
+
+/*
+ * Receive start/stop functions
+ */
+
+/*
+ * Start receive on PCU
+ */
+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);
+}
+
+/*
+ * Stop receive on PCU
+ */
+void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/*
+ * RX Filter functions
+ */
+
+/*
+ * 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_filterindex(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;
+}
+
+/*
+ * Get current rx filter
+ */
+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;
+}
+
+/*
+ * Set rx filter
+ */
+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*/
+       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 related functions
+ */
+
+/*
+ * Get a 32bit TSF
+ */
+u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+}
+
+/*
+ * Get the full 64bit 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);
+}
+
+/*
+ * Force a TSF reset
+ */
+void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
+}
+
+/*
+ * 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 IEEE80211_IF_TYPE_STA:
+               if (ah->ah_version == AR5K_AR5210) {
+                       timer1 = 0xffffffff;
+                       timer2 = 0xffffffff;
+               } else {
+                       timer1 = 0x0000ffff;
+                       timer2 = 0x0007ffff;
+               }
+               break;
+
+       default:
+               timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
+               timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
+       }
+
+       timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
+
+       /*
+        * Set the beacon register and enable all timers.
+        * (next beacon, DMA beacon, software beacon, ATIM window time)
+        */
+       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);
+
+       ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
+                       AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
+               AR5K_BEACON);
+}
+
+#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
+
+/*
+ * Update mib counters (statistics)
+ */
+void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
+               struct ath5k_mib_stats *statistics)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /* Read-And-Clear */
+       statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
+       statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
+       statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
+       statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
+       statistics->beacons += 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);
+       }
+}
+
+/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
+ *
+ * @ah: the &struct ath5k_hw
+ * @high: determines if to use low bit rate or now
+ */
+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
+ */
+
+/*
+ * Set ACK timeout on PCU
+ */
+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;
+}
+
+/*
+ * Read the ACK timeout from PCU
+ */
+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);
+}
+
+/*
+ * Set CTS timeout on PCU
+ */
+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;
+}
+
+/*
+ * Read CTS timeout from PCU
+ */
+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);
+}
+
+/*
+ * Key table (WEP) functions
+ */
+
+int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
+{
+       unsigned int i;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+
+       /* Set NULL encryption on non-5210*/
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(entry));
+
+       return 0;
+}
+
+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;
+}
+
+int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
+               const struct ieee80211_key_conf *key, const u8 *mac)
+{
+       unsigned int i;
+       __le32 key_v[5] = {};
+       u32 keytype;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* key->keylen comes in from mac80211 in bytes */
+
+       if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
+               return -EOPNOTSUPP;
+
+       switch (key->keylen) {
+       /* WEP 40-bit   = 40-bit  entered key + 24 bit IV = 64-bit */
+       case 40 / 8:
+               memcpy(&key_v[0], key->key, 5);
+               keytype = AR5K_KEYTABLE_TYPE_40;
+               break;
+
+       /* WEP 104-bit  = 104-bit entered key + 24-bit IV = 128-bit */
+       case 104 / 8:
+               memcpy(&key_v[0], &key->key[0], 6);
+               memcpy(&key_v[2], &key->key[6], 6);
+               memcpy(&key_v[4], &key->key[12], 1);
+               keytype = AR5K_KEYTABLE_TYPE_104;
+               break;
+       /* WEP 128-bit  = 128-bit entered key + 24 bit IV = 152-bit */
+       case 128 / 8:
+               memcpy(&key_v[0], &key->key[0], 6);
+               memcpy(&key_v[2], &key->key[6], 6);
+               memcpy(&key_v[4], &key->key[12], 4);
+               keytype = AR5K_KEYTABLE_TYPE_128;
+               break;
+
+       default:
+               return -EINVAL; /* shouldn't happen */
+       }
+
+       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));
+
+       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 (unlikely(mac == NULL)) {
+               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;
+}
+
+
+/********************************************\
+Queue Control Unit, DFS Control Unit Functions
+\********************************************/
+
+/*
+ * 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_setup_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;
+}
+
+/*
+ * Setup a transmit queue
+ */
+int ath5k_hw_setup_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;
+}
+
+/*
+ * Get properties for a specific 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 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 params for a transmit queue
+ */
+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 == true ?
+                       AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
+                       AR5K_SLOT_TIME);
+               /* Set ACK_CTS timeout */
+               ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+                       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 == true ?
+                       AR5K_INIT_TRANSMIT_LATENCY_TURBO :
+                       AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
+               /* Set IFS0 */
+               if (ah->ah_turbo == true)
+                        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 == true ?
+                       AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
+                       AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
+               /* Set PHY register 0x9844 (??) */
+               ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+                       (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
+                       (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
+                       AR5K_PHY(17));
+               /* Set Frame Control Register */
+               ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
+                       (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 == true) {
+               /* 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
+                */
+               ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
+                       AR5K_QUEUE_MISC(queue));
+
+               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)
+                       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_TXE);
+               }
+
+               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 |
+                               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);
+
+                       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));
+                       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 |
+                               AR5K_QCU_MISC_CBREXP_BCN);
+
+                       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);
+                       break;
+
+               case AR5K_TX_QUEUE_DATA:
+               default:
+                       break;
+               }
+
+               /*
+                * 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);
+
+
+               /* Update secondary interrupt mask registers */
+               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;
+
+               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);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
+                       AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
+       }
+
+       return 0;
+}
+
+/*
+ * Get number of pending frames
+ * for a specific queue [5211+]
+ */
+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int 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 false;
+
+       /* XXX: How about AR5K_CFG_TXCNT ? */
+       if (ah->ah_version == AR5K_AR5210)
+               return false;
+
+       return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
+}
+
+/*
+ * Set slot time
+ */
+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;
+}
+
+/*
+ * Get slot time
+ */
+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;
+}
+
+
+/******************************\
+ Hardware Descriptor Functions
+\******************************/
+
+/*
+ * TX Descriptor
+ */
+
+/*
+ * Initialize the 2-word tx 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_desc *tx_desc;
+       unsigned int buff_len;
+
+       tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
+
+       /*
+        * 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 status descriptor */
+       memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status));
+
+       /* Initialize control descriptor */
+       tx_desc->tx_control_0 = 0;
+       tx_desc->tx_control_1 = 0;
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+       if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+       buff_len = pkt_len - FCS_LEN;
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if(type == AR5K_PKT_TYPE_BEACON)
+               buff_len = roundup(buff_len, 4);
+
+       if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_desc->tx_control_1 = buff_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_desc->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_desc->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_desc->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_desc->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_desc->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_desc->tx_control_0 |=
+                       AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_desc->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_desc->tx_control_1 |= rtscts_duration &
+                               AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
+
+       return 0;
+}
+
+/*
+ * Initialize the 4-word tx 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_desc *tx_desc;
+       struct ath5k_hw_tx_status *tx_status;
+       unsigned int buff_len;
+
+       ATH5K_TRACE(ah->ah_sc);
+       tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
+       tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
+
+       /*
+        * 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 status descriptor */
+       memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status));
+
+       /* Initialize control descriptor */
+       tx_desc->tx_control_0 = 0;
+       tx_desc->tx_control_1 = 0;
+       tx_desc->tx_control_2 = 0;
+       tx_desc->tx_control_3 = 0;
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+       if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+       buff_len = pkt_len - FCS_LEN;
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if(type == AR5K_PKT_TYPE_BEACON)
+               buff_len = roundup(buff_len, 4);
+
+       if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+
+       tx_desc->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_desc->tx_control_1 |= AR5K_REG_SM(type,
+                                       AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
+       tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
+                                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
+       tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+
+#define _TX_FLAGS(_c, _flag)                   \
+       if (flags & AR5K_TXDESC_##_flag)        \
+               tx_desc->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_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_desc->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_desc->tx_control_2 |= rtscts_duration &
+                               AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
+               tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
+                               AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
+       }
+
+       return 0;
+}
+
+/*
+ * Initialize a 4-word multirate tx descriptor on 5212
+ */
+static bool
+ath5k_hw_setup_xr_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_desc *tx_desc;
+
+       /*
+        * 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_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
+
+#define _XTX_TRIES(_n)                                                 \
+       if (tx_tries##_n) {                                             \
+               tx_desc->tx_control_2 |=                                \
+                   AR5K_REG_SM(tx_tries##_n,                           \
+                   AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
+               tx_desc->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 true;
+       }
+
+       return false;
+}
+
+/*
+ * 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_hw_tx_status *tx_status;
+       struct ath5k_hw_2w_tx_desc *tx_desc;
+
+       tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
+       tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[0];
+
+       /* 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
+        */
+       desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       /*TODO: desc->ds_us.tx.ts_virtcol + test*/
+       desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       desc->ds_us.tx.ts_antenna = 1;
+       desc->ds_us.tx.ts_status = 0;
+       desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0,
+               AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+
+       if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess a tx descriptor on 5212
+ */
+static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc)
+{
+       struct ath5k_hw_tx_status *tx_status;
+       struct ath5k_hw_4w_tx_desc *tx_desc;
+
+       ATH5K_TRACE(ah->ah_sc);
+       tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
+       tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
+
+       /* 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
+        */
+       desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
+               AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
+       desc->ds_us.tx.ts_status = 0;
+
+       switch (AR5K_REG_MS(tx_status->tx_status_1,
+                       AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
+       case 0:
+               desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+               break;
+       case 1:
+               desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
+               desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+               break;
+       case 2:
+               desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
+               desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
+               break;
+       case 3:
+               desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
+               desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
+               break;
+       }
+
+       if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * RX Descriptor
+ */
+
+/*
+ * Initialize an rx descriptor
+ */
+int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+                       u32 size, unsigned int flags)
+{
+       struct ath5k_rx_desc *rx_desc;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_desc = (struct ath5k_rx_desc *)&desc->ds_ctl0;
+
+       /*
+        *Clear ds_hw
+        * 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->ds_hw, 0, sizeof(desc->ds_hw));
+
+       /*Initialize rx descriptor*/
+       rx_desc->rx_control_0 = 0;
+       rx_desc->rx_control_1 = 0;
+
+       /* Setup descriptor */
+       rx_desc->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
+       if (unlikely(rx_desc->rx_control_1 != size))
+               return -EINVAL;
+
+       if (flags & AR5K_RXDESC_INTREQ)
+               rx_desc->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5210/5211
+ */
+static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc)
+{
+       struct ath5k_hw_old_rx_status *rx_status;
+
+       rx_status = (struct ath5k_hw_old_rx_status *)&desc->ds_hw[0];
+
+       /* No frame received / not ready */
+       if (unlikely((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_DONE)
+                               == 0))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
+               AR5K_OLD_RX_DESC_STATUS0_DATA_LEN;
+       desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE);
+       desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
+               AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA;
+       desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
+               AR5K_OLD_RX_DESC_STATUS0_MORE;
+       desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       desc->ds_us.rx.rs_status = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                       AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if ((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK)
+                       == 0) {
+               if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_FIFO;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR) {
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
+                       desc->ds_us.rx.rs_phyerr =
+                               AR5K_REG_MS(rx_status->rx_status_1,
+                                       AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5212
+ */
+static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc)
+{
+       struct ath5k_hw_new_rx_status *rx_status;
+       struct ath5k_hw_rx_error *rx_err;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_status = (struct ath5k_hw_new_rx_status *)&desc->ds_hw[0];
+
+       /* Overlay on error */
+       rx_err = (struct ath5k_hw_rx_error *)&desc->ds_hw[0];
+
+       /* No frame received / not ready */
+       if (unlikely((rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_DONE)
+                               == 0))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
+               AR5K_NEW_RX_DESC_STATUS0_DATA_LEN;
+       desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE);
+       desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
+               AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA;
+       desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
+               AR5K_NEW_RX_DESC_STATUS0_MORE;
+       desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       desc->ds_us.rx.rs_status = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                               AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if ((rx_status->rx_status_1 &
+                       AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
+               if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR) {
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
+                       desc->ds_us.rx.rs_phyerr =
+                               AR5K_REG_MS(rx_err->rx_error_1,
+                                       AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
+
+               if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR)
+                       desc->ds_us.rx.rs_status |= AR5K_RXERR_MIC;
+       }
+
+       return 0;
+}
+
+
+/****************\
+  GPIO Functions
+\****************/
+
+/*
+ * 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 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;
+}
+
+/*
+ * 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;
+}
+
+/*
+ * 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);
+}
+
+
+/*********************************\
+ Regulatory Domain/Channels Setup
+\*********************************/
+
+u16 ath5k_get_regdomain(struct ath5k_hw *ah)
+{
+       u16 regdomain;
+       enum ath5k_regdom ieee_regdomain;
+#ifdef COUNTRYCODE
+       u16 code;
+#endif
+
+       ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain);
+       ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
+
+#ifdef COUNTRYCODE
+       /*
+        * Get the regulation domain by country code. This will ignore
+        * the settings found in the EEPROM.
+        */
+       code = ieee80211_name2countrycode(COUNTRYCODE);
+       ieee_regdomain = ieee80211_countrycode2regdomain(code);
+#endif
+
+       regdomain = ath5k_regdom_from_ieee(ieee_regdomain);
+       ah->ah_capabilities.cap_regdomain.reg_current = regdomain;
+
+       return regdomain;
+}
+
+
+/****************\
+  Misc functions
+\****************/
+
+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;
+}
+
+static 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;
+}
+
+static 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/hw.h b/drivers/net/wireless/ath5k/hw.h
new file mode 100644 (file)
index 0000000..d9a7c09
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007 Matthew W. S. Bell  <mentor@madwifi.org>
+ * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * 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 <linux/delay.h>
+
+/*
+ * Gain settings
+ */
+
+enum ath5k_rfgain {
+       AR5K_RFGAIN_INACTIVE = 0,
+       AR5K_RFGAIN_READ_REQUESTED,
+       AR5K_RFGAIN_NEED_CHANGE,
+};
+
+#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
+#define AR5K_GAIN_PARAM_TX_CLIP                        0
+#define AR5K_GAIN_PARAM_PD_90                  1
+#define AR5K_GAIN_PARAM_PD_84                  2
+#define AR5K_GAIN_PARAM_GAIN_SEL               3
+#define AR5K_GAIN_PARAM_MIX_ORN                        0
+#define AR5K_GAIN_PARAM_PD_138                 1
+#define AR5K_GAIN_PARAM_PD_137                 2
+#define AR5K_GAIN_PARAM_PD_136                 3
+#define AR5K_GAIN_PARAM_PD_132                 4
+#define AR5K_GAIN_PARAM_PD_131                 5
+#define AR5K_GAIN_PARAM_PD_130                 6
+#define AR5K_GAIN_CHECK_ADJUST(_g)             \
+       ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+       s16                             gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+       s32                             gos_gain;
+};
+
+struct ath5k_gain {
+       u32                     g_step_idx;
+       u32                     g_current;
+       u32                     g_target;
+       u32                     g_low;
+       u32                     g_high;
+       u32                     g_f_corr;
+       u32                     g_active;
+       const struct ath5k_gain_opt_step        *g_step;
+};
+
+
+/*
+ * HW SPECIFIC STRUCTS
+ */
+
+/* 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_MAX_CHAN           10
+#define AR5K_EEPROM_N_PCDAC            11
+#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_XPD_PER_CHANNEL  4
+#define AR5K_EEPROM_N_XPD0_POINTS      4
+#define AR5K_EEPROM_N_XPD3_POINTS      3
+#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
+
+/* Struct to hold EEPROM calibration data */
+struct ath5k_eeprom_info {
+       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_cck_ofdm_gain_delta;
+       u16     ee_cck_ofdm_power_delta;
+       u16     ee_scaled_cck_delta;
+
+       /* Used for tx thermal adjustment (eeprom_init, rfregs) */
+       u16     ee_tx_clip;
+       u16     ee_pwd_84;
+       u16     ee_pwd_90;
+       u16     ee_gain_select;
+
+       /* 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_ant_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];
+
+       /* Unused */
+       u16     ee_false_detect[AR5K_EEPROM_N_MODES];
+       u16     ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN];
+       u16     ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/
+
+       /* Conformance test limits (Unused) */
+       u16     ee_ctls;
+       u16     ee_ctl[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];
+};
+
+/*
+ * Internal RX/TX descriptor structures
+ * (rX: reserved fields possibily used by future versions of the ar5k chipset)
+ */
+
+struct ath5k_rx_desc {
+       u32     rx_control_0; /* RX control word 0 */
+
+#define AR5K_DESC_RX_CTL0                      0x00000000
+
+       u32     rx_control_1; /* RX control word 1 */
+
+#define AR5K_DESC_RX_CTL1_BUF_LEN              0x00000fff
+#define AR5K_DESC_RX_CTL1_INTREQ               0x00002000
+} __packed;
+
+/*
+ * 5210/5211 rx status descriptor
+ */
+struct ath5k_hw_old_rx_status {
+       u32     rx_status_0; /* RX status word 0 */
+
+#define AR5K_OLD_RX_DESC_STATUS0_DATA_LEN              0x00000fff
+#define AR5K_OLD_RX_DESC_STATUS0_MORE                  0x00001000
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE          0x00078000
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE_S                15
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL                0x07f80000
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL_S      19
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA       0x38000000
+#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA_S     27
+
+       u32     rx_status_1; /* RX status word 1 */
+
+#define AR5K_OLD_RX_DESC_STATUS1_DONE                  0x00000001
+#define AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK      0x00000002
+#define AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR             0x00000004
+#define AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN          0x00000008
+#define AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR     0x00000010
+#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR             0x000000e0
+#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR_S           5
+#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID       0x00000100
+#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX             0x00007e00
+#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_S           9
+#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP     0x0fff8000
+#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S   15
+#define AR5K_OLD_RX_DESC_STATUS1_KEY_CACHE_MISS                0x10000000
+} __packed;
+
+/*
+ * 5212 rx status descriptor
+ */
+struct ath5k_hw_new_rx_status {
+       u32     rx_status_0; /* RX status word 0 */
+
+#define AR5K_NEW_RX_DESC_STATUS0_DATA_LEN              0x00000fff
+#define AR5K_NEW_RX_DESC_STATUS0_MORE                  0x00001000
+#define AR5K_NEW_RX_DESC_STATUS0_DECOMP_CRC_ERROR      0x00002000
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE          0x000f8000
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE_S                15
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL                0x0ff00000
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL_S      20
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA       0xf0000000
+#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA_S     28
+
+       u32     rx_status_1; /* RX status word 1 */
+
+#define AR5K_NEW_RX_DESC_STATUS1_DONE                  0x00000001
+#define AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK      0x00000002
+#define AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR             0x00000004
+#define AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR     0x00000008
+#define AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR             0x00000010
+#define AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR             0x00000020
+#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID       0x00000100
+#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX             0x0000fe00
+#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_S           9
+#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP     0x7fff0000
+#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S   16
+#define AR5K_NEW_RX_DESC_STATUS1_KEY_CACHE_MISS                0x80000000
+} __packed;
+
+struct ath5k_hw_rx_error {
+       u32     rx_error_0; /* RX error word 0 */
+
+#define AR5K_RX_DESC_ERROR0                    0x00000000
+
+       u32     rx_error_1; /* RX error word 1 */
+
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE     0x0000ff00
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S   8
+} __packed;
+
+#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
+
+struct ath5k_hw_2w_tx_desc {
+       u32     tx_control_0; /* TX control word 0 */
+
+#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
+
+       u32     tx_control_1; /* TX control word 1 */
+
+#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 ?]*/
+} __packed;
+
+#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 4-word tx control descriptor
+ */
+struct ath5k_hw_4w_tx_desc {
+       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 */
+
+#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
+
+       u32     tx_status_1; /* TX status word 1 */
+
+#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
+} __packed;
+
+
+/*
+ * AR5K REGISTER ACCESS
+ */
+
+/*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
+
+/*#define AR5K_REG_READ(_reg)  ath5k_hw_reg_read(ah, _reg)
+
+#define AR5K_REG_WRITE(_reg, _val)     ath5k_hw_reg_write(ah, _val, _reg)*/
+
+#define AR5K_REG_SM(_val, _flags)                                      \
+       (((_val) << _flags##_S) & (_flags))
+
+#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)
+
+#define AR5K_PHY_WRITE(ah, _reg, _val)                                 \
+       ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
+
+#define AR5K_PHY_READ(ah, _reg)                                        \
+       ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
+
+#define AR5K_REG_WAIT(_i) do {                                         \
+       if (_i % 64)                                                    \
+               udelay(1);                                              \
+} while (0)
+
+#define AR5K_EEPROM_READ(_o, _v) do {                                  \
+       if ((ret = ath5k_hw_eeprom_read(ah, (_o), &(_v))) != 0) \
+               return (ret);                                           \
+} while (0)
+
+#define AR5K_EEPROM_READ_HDR(_o, _v)                                   \
+       AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);        \
+
+/* Read status of selected 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)
+
+#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)
+
+/*
+ * Initial register values
+ */
+
+/*
+ * Common initial register values
+ */
+#define AR5K_INIT_MODE                         CHANNEL_B
+
+#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_CARR_SENSE_EN                        1
+#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_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_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_TOPS                         8
+#define AR5K_INIT_RXNOFRM                      8
+#define AR5K_INIT_RPGTO                                0
+#define AR5K_INIT_TXNOFRM                      0
+#define AR5K_INIT_BEACON_PERIOD                        65535
+#define AR5K_INIT_TIM_OFFSET                   0
+#define AR5K_INIT_BEACON_EN                    0
+#define AR5K_INIT_RESET_TSF                    0
+
+#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)                                      \
+)
+#define AR5K_INIT_BEACON_CONTROL               (                       \
+       (AR5K_INIT_RESET_TSF << 24) | (AR5K_INIT_BEACON_EN << 23) |     \
+       (AR5K_INIT_TIM_OFFSET << 16) | (AR5K_INIT_BEACON_PERIOD)        \
+)
+
+/*
+ * Non-common initial register values which have to be loaded into the
+ * card at boot time and after each reset.
+ */
+
+/* Register dumps are done per operation mode */
+#define AR5K_INI_RFGAIN_5GHZ           0
+#define AR5K_INI_RFGAIN_2GHZ           1
+
+#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
+
+#define AR5K_RF5111_INI_RF_MAX_BANKS   AR5K_MAX_RF_BANKS
+#define AR5K_RF5112_INI_RF_MAX_BANKS   AR5K_MAX_RF_BANKS
+
+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;
+}
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
new file mode 100644 (file)
index 0000000..2c22f1d
--- /dev/null
@@ -0,0 +1,1347 @@
+/*
+ * Initial register settings functions
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007 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 "base.h"
+#include "reg.h"
+
+/*
+ * MAC/PHY REGISTERS
+ */
+
+
+/*
+ * 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,            AR5K_INIT_TOPS },
+       { AR5K_RXNOFRM,         AR5K_INIT_RXNOFRM },
+       { AR5K_RPGTO,           AR5K_INIT_RPGTO },
+       { AR5K_TXNOFRM,         AR5K_INIT_TXNOFRM },
+       { 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
+ * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ?
+ * Maybe 5211 supports OFDM-only g but we need to test it !
+ */
+static const struct ath5k_ini_mode ar5211_ini_mode[] = {
+       { AR5K_TXCFG,
+       /*        a           aTurbo      b             */
+               { 0x00000015, 0x00000015, 0x0000001d } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
+               { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
+       { AR5K_DCU_GBL_IFS_SLOT,
+               { 0x00000168, 0x000001e0, 0x000001b8 } },
+       { AR5K_DCU_GBL_IFS_SIFS,
+               { 0x00000230, 0x000001e0, 0x000000b0 } },
+       { AR5K_DCU_GBL_IFS_EIFS,
+               { 0x00000d98, 0x00001180, 0x00001f48 } },
+       { AR5K_DCU_GBL_IFS_MISC,
+               { 0x0000a0e0, 0x00014068, 0x00005880 } },
+       { AR5K_TIME_OUT,
+               { 0x04000400, 0x08000800, 0x20003000 } },
+       { AR5K_USEC_5211,
+               { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } },
+       { AR5K_PHY_TURBO,
+               { 0x00000000, 0x00000003, 0x00000000 } },
+       { AR5K_PHY(8),
+               { 0x02020200, 0x02020200, 0x02010200 } },
+       { AR5K_PHY(9),
+               { 0x00000e0e, 0x00000e0e, 0x00000707 } },
+       { AR5K_PHY(10),
+               { 0x0a020001, 0x0a020001, 0x05010000 } },
+       { AR5K_PHY(13),
+               { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+               { 0x00000007, 0x00000007, 0x0000000b } },
+       { AR5K_PHY(17),
+               { 0x1372169c, 0x137216a5, 0x137216a8 } },
+       { AR5K_PHY(18),
+               { 0x0018ba67, 0x0018ba67, 0x0018ba69 } },
+       { AR5K_PHY(20),
+               { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+       { AR5K_PHY_SIG,
+               { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } },
+       { AR5K_PHY_AGCCOARSE,
+               { 0x31375d5e, 0x31375d5e, 0x313a5d5e } },
+       { AR5K_PHY_AGCCTL,
+               { 0x0000bd10, 0x0000bd10, 0x0000bd38 } },
+       { AR5K_PHY_NF,
+               { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY_RX_DELAY,
+               { 0x00002710, 0x00002710, 0x0000157c } },
+       { AR5K_PHY(70),
+               { 0x00000190, 0x00000190, 0x00000084 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+               { 0x6fe01020, 0x6fe01020, 0x6fe00920 } },
+       { AR5K_PHY_PCDAC_TXPOWER_BASE_5211,
+               { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } },
+       { AR5K_RF_BUFFER_CONTROL_4,
+               { 0x00000010, 0x00000014, 0x00000010 } },
+};
+
+/* Initial register settings for AR5212 */
+static const struct ath5k_ini ar5212_ini[] = {
+       { 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 },
+       { AR5K_DCU_TX_FILTER,   0x00000000 },
+       /* Unknown table */
+       { 0x1078, 0x00000000 },
+       { 0x10b8, 0x00000000 },
+       { 0x10f8, 0x00000000 },
+       { 0x1138, 0x00000000 },
+       { 0x1178, 0x00000000 },
+       { 0x11b8, 0x00000000 },
+       { 0x11f8, 0x00000000 },
+       { 0x1238, 0x00000000 },
+       { 0x1278, 0x00000000 },
+       { 0x12b8, 0x00000000 },
+       { 0x12f8, 0x00000000 },
+       { 0x1338, 0x00000000 },
+       { 0x1378, 0x00000000 },
+       { 0x13b8, 0x00000000 },
+       { 0x13f8, 0x00000000 },
+       { 0x1438, 0x00000000 },
+       { 0x1478, 0x00000000 },
+       { 0x14b8, 0x00000000 },
+       { 0x14f8, 0x00000000 },
+       { 0x1538, 0x00000000 },
+       { 0x1578, 0x00000000 },
+       { 0x15b8, 0x00000000 },
+       { 0x15f8, 0x00000000 },
+       { 0x1638, 0x00000000 },
+       { 0x1678, 0x00000000 },
+       { 0x16b8, 0x00000000 },
+       { 0x16f8, 0x00000000 },
+       { 0x1738, 0x00000000 },
+       { 0x1778, 0x00000000 },
+       { 0x17b8, 0x00000000 },
+       { 0x17f8, 0x00000000 },
+       { 0x103c, 0x00000000 },
+       { 0x107c, 0x00000000 },
+       { 0x10bc, 0x00000000 },
+       { 0x10fc, 0x00000000 },
+       { 0x113c, 0x00000000 },
+       { 0x117c, 0x00000000 },
+       { 0x11bc, 0x00000000 },
+       { 0x11fc, 0x00000000 },
+       { 0x123c, 0x00000000 },
+       { 0x127c, 0x00000000 },
+       { 0x12bc, 0x00000000 },
+       { 0x12fc, 0x00000000 },
+       { 0x133c, 0x00000000 },
+       { 0x137c, 0x00000000 },
+       { 0x13bc, 0x00000000 },
+       { 0x13fc, 0x00000000 },
+       { 0x143c, 0x00000000 },
+       { 0x147c, 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_RSSI_THR,      0x00000000 },*/ /* Found on SuperAG cards */
+       { AR5K_BEACON_5211,     0x00000000 },   /* Found on SuperAG cards */
+       { AR5K_CFP_PERIOD_5211, 0x00000000 },   /* Found on SuperAG cards */
+       { AR5K_TIMER0_5211,     0x00000030 },   /* Found on SuperAG cards */
+       { AR5K_TIMER1_5211,     0x0007ffff },   /* Found on SuperAG cards */
+       { AR5K_TIMER2_5211,     0x01ffffff },   /* Found on SuperAG cards */
+       { AR5K_TIMER3_5211,     0x00000031 },   /* Found on SuperAG cards */
+       { AR5K_CFP_DUR_5211,    0x00000000 },   /* Found on SuperAG cards */
+       { AR5K_RX_FILTER_5211,  0x00000000 },
+       { AR5K_DIAG_SW_5211,    0x00000000 },
+       { AR5K_ADDAC_TEST,      0x00000000 },
+       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
+       { 0x8080, 0x00000000 },
+       /*{ 0x805c, 0xffffc7ff },*/ /* Old value */
+       { 0x805c, 0x000fc78f },
+       { AR5K_NAV_5211,        0x00000000 },   /* Not found on recent */
+       { AR5K_RTS_OK_5211,     0x00000000 },   /* dumps but it makes  */
+       { AR5K_RTS_FAIL_5211,   0x00000000 },   /* sense to reset counters */
+       { AR5K_ACK_FAIL_5211,   0x00000000 },   /* since pcu registers */
+       { AR5K_FCS_FAIL_5211,   0x00000000 },   /* are skiped during chan*/
+       { AR5K_BEACON_CNT_5211, 0x00000000 },   /* change */
+       { AR5K_XRMODE,          0x2a82301a },
+       { AR5K_XRDELAY,         0x05dc01e0 },
+       { AR5K_XRTIMEOUT,       0x1f402710 },
+       { AR5K_XRCHIRP,         0x01f40000 },
+       { AR5K_XRSTOMP,         0x00001e1c },
+       { AR5K_SLEEP0,          0x0002aaaa },   /* Found on SuperAG cards */
+       { AR5K_SLEEP1,          0x02005555 },   /* Found on SuperAG cards */
+       { AR5K_SLEEP2,          0x00000000 },   /* Found on SuperAG cards */
+       { 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 },
+       { 0x80fc, 0x00000088 },
+       { 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 },
+       { 0x8100, 0x00010002},
+       { AR5K_TSF_PARM,        0x00000001 },
+       { 0x8108, 0x000000c0 },
+       { AR5K_PHY_ERR_FIL,     0x00000000 },
+       { 0x8110, 0x00000168 },
+       { 0x8114, 0x00000000 },
+       /* Some kind of table
+        * also notice ...03<-02<-01<-00) */
+       { 0x87c0, 0x03020100 },
+       { 0x87c4, 0x07060504 },
+       { 0x87c8, 0x0b0a0908 },
+       { 0x87cc, 0x0f0e0d0c },
+       { 0x87d0, 0x13121110 },
+       { 0x87d4, 0x17161514 },
+       { 0x87d8, 0x1b1a1918 },
+       { 0x87dc, 0x1f1e1d1c },
+       /* loop ? */
+       { 0x87e0, 0x03020100 },
+       { 0x87e4, 0x07060504 },
+       { 0x87e8, 0x0b0a0908 },
+       { 0x87ec, 0x0f0e0d0c },
+       { 0x87f0, 0x13121110 },
+       { 0x87f4, 0x17161514 },
+       { 0x87f8, 0x1b1a1918 },
+       { 0x87fc, 0x1f1e1d1c },
+       /* PHY registers */
+       /*{ AR5K_PHY_AGC, 0x00000000 },*/
+       { AR5K_PHY(3),  0xad848e19 },
+       { AR5K_PHY(4),  0x7d28e000 },
+       { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
+       { AR5K_PHY_ACT, 0x00000000 },
+       /*{ AR5K_PHY(11), 0x00022ffe },*/
+       /*{ AR5K_PHY(15), 0x00020100 },*/
+       { AR5K_PHY(16), 0x206a017a },
+       /*{ AR5K_PHY(19), 0x1284613c },*/
+       { AR5K_PHY(21), 0x00000859 },
+       { AR5K_PHY(64), 0x00000000 },
+       { AR5K_PHY(65), 0x00000000 },
+       { AR5K_PHY(66), 0x00000000 },
+       { AR5K_PHY(67), 0x00800000 },
+       { AR5K_PHY(68), 0x00000001 },
+       /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
+       { AR5K_PHY(71), 0x00000c80 },
+       { AR5K_PHY_IQ,  0x05100000 },
+       { AR5K_PHY(74), 0x00000001 },
+       { AR5K_PHY(75), 0x00000004 },
+       { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
+       { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
+       { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
+       /*{ AR5K_PHY(80), 0x00000004 },*/
+       { AR5K_PHY(82), 0x9280b212 },
+       { AR5K_PHY_RADAR, 0x5d50e188 },
+       /*{ AR5K_PHY(86), 0x000000ff },*/
+       { AR5K_PHY(87), 0x004b6a8e },
+       { AR5K_PHY(90), 0x000003ce },
+       { AR5K_PHY(92), 0x192fb515 },
+       /*{ AR5K_PHY(93), 0x00000000 },*/
+       { AR5K_PHY(94), 0x00000001 },
+       { AR5K_PHY(95), 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 },*/ /* Old value */
+       { AR5K_PHY(647), 0x1483800a },
+       { AR5K_PHY(648), 0x01831061 },
+       { 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 },
+       /*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
+};
+
+/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
+static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
+       { AR5K_PHY(640),
+       /*        a/XR        aTurbo      b           g (DYN)     gTurbo */
+               { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
+       { AR5K_PHY(0),
+               { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+               { 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(9),
+               { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(17),
+               { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+       { AR5K_PHY_AGCCTL,
+               { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
+       { AR5K_PHY_NF,
+               { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY(26),
+               { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+       { AR5K_PHY(70),
+               { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+       { AR5K_PHY(73),
+               { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+       { 0xa230,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
+/* New dump pending */
+static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
+       { AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
+       /*        a/XR        aTurbo      b           g (DYN)     gTurbo */
+               { 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
+       { AR5K_TXCFG,
+               { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+       { AR5K_USEC_5211,
+               { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+       { AR5K_PHY(10),
+               { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY(13),
+               { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+               { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY(18),
+               { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+       { AR5K_PHY(20),
+               { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+               { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+               { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+       { AR5K_PHY(27),
+               { 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 } },
+       { 0xa21c,
+               { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+       { AR5K_DCU_FP,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_AGC,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(11),
+               { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
+       { AR5K_PHY(15),
+               { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
+       { AR5K_PHY(19),
+               { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
+       { AR5K_PHY_PAPD_PROBE,
+               { 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } },
+       { AR5K_PHY(80),
+               { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
+       { AR5K_PHY(86),
+               { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
+       { AR5K_PHY(93),
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_SPENDING,
+               { 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
+       { AR5K_PHY_CCKTXCTL,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(642),
+               { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { 0xa23c,
+               { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
+/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */
+static const struct ath5k_ini_mode ar5212_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(10),
+               { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY(13),
+               { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+               { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY(18),
+               { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+       { AR5K_PHY(20),
+               { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+               { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+               { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+       { AR5K_PHY(27),
+               { 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(642),
+               { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+               { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+       { 0xa21c,
+               { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+       { AR5K_DCU_FP,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_AGC,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(11),
+               { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
+       { AR5K_PHY(15),
+               { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
+       { AR5K_PHY(19),
+               { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
+       { AR5K_PHY_PAPD_PROBE,
+               { 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } },
+       { AR5K_PHY(80),
+               { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
+       { AR5K_PHY(86),
+               { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
+       { AR5K_PHY(93),
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa228,
+               { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
+       { 0xa23c,
+               { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+};
+
+/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
+/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
+ * minor tweaking based on dumps from other chips */
+static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*        a/XR        aTurbo      b           g           gTurbo */
+               { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+               { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY(10),
+               { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY(13),
+               { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+               { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY(18),
+               { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+       { AR5K_PHY(20),
+               { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+       { AR5K_PHY_SIG,
+               { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+               { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+       { AR5K_PHY(27),
+               { 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(642),
+               { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+               { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+       { 0xa21c,
+               { 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 } },
+       { AR5K_DCU_FP,
+               { 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } },
+       { 0x4068,
+               { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+       { 0x8060,
+               { 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } },
+       { 0x809c,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x80a0,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8118,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x811c,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8120,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8124,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8128,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x812c,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8130,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8134,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8138,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x813c,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0x8140,
+               { 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } },
+       { 0x8144,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_AGC,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(11),
+               { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
+       { AR5K_PHY(15),
+               { 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } },
+       { AR5K_PHY(19),
+               { 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } },
+       { AR5K_PHY_SCR,
+               { 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } },
+       { AR5K_PHY_SLMT,
+               { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+       { AR5K_PHY_SCAL,
+               { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+       { AR5K_PHY(86),
+               { 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } },
+       { AR5K_PHY(96),
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(97),
+               { 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } },
+       { AR5K_PHY(104),
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(120),
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(121),
+               { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
+       { AR5K_PHY(122),
+               { 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } },
+       { AR5K_PHY(123),
+               { 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } },
+       { AR5K_PHY_SCLOCK,
+               { 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } },
+       { AR5K_PHY_SDELAY,
+               { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
+       { AR5K_PHY_SPENDING,
+               { 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } },
+       { 0xa228,
+               { 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } },
+       { 0xa23c,
+               { 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
+       { 0xa24c,
+               { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 0xa250,
+               { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
+       { 0xa254,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa258,
+               { 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
+       { 0xa25c,
+               { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
+       { 0xa260,
+               { 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
+       { 0xa264,
+               { 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
+       { 0xa268,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa26c,
+               { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
+       { 0xa270,
+               { 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
+       { 0xa274,
+               { 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
+       { 0xa278,
+               { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
+       { 0xa27c,
+               { 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
+       { 0xa338,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa33c,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa340,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa344,
+               { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0xa348,
+               { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
+       { 0xa34c,
+               { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
+       { 0xa350,
+               { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
+       { 0xa354,
+               { 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
+       { 0xa358,
+               { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
+       { 0xa35c,
+               { 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
+       { 0xa360,
+               { 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
+       { 0xa364,
+               { 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
+       { 0xa368,
+               { 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
+       { 0xa36c,
+               { 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
+       { 0xa370,
+               { 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
+       { 0xa374,
+               { 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
+       { 0xa378,
+               { 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
+       { 0xa37c,
+               { 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
+       { 0xa380,
+               { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
+       { 0xa384,
+               { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 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),
+                                       ar5212_ini, change_channel);
+
+               /* Second set of mode-specific settings */
+               if (ah->ah_radio == AR5K_RF5111){
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
+                                       ar5212_rf5111_ini_mode_end, mode);
+                       /* Baseband gain table */
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_bbgain),
+                                       rf5111_ini_bbgain, change_channel);
+               } else if (ah->ah_radio == AR5K_RF5112){
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
+                                       ar5212_rf5112_ini_mode_end, mode);
+                       /* Baseband gain table */
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+               } else if (ah->ah_radio == AR5K_RF5413){
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5413_ini_mode_end),
+                                       rf5413_ini_mode_end, mode);
+                       /* Baseband gain table */
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+               }
+       /* For AR5211 */
+       } else if (ah->ah_version == AR5K_AR5211) {
+
+               if(mode > 2){ /* AR5K_INI_VAL_11B */
+                       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/phy.c b/drivers/net/wireless/ath5k/phy.c
new file mode 100644 (file)
index 0000000..b959417
--- /dev/null
@@ -0,0 +1,2071 @@
+/*
+ * PHY functions
+ *
+ * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007 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 <linux/delay.h>
+
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
+
+/* Struct to hold initial RF register values (RF Banks) */
+struct ath5k_ini_rf {
+       u8      rf_bank;        /* check out ath5k_reg.h */
+       u16     rf_register;    /* register address */
+       u32     rf_value[5];    /* register value for different modes (above) */
+};
+
+/*
+ * 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)] */
+};
+
+struct ath5k_gain_opt {
+       u32                     go_default;
+       u32                     go_steps_count;
+       const struct ath5k_gain_opt_step        go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/* RF5111 mode-specific init registers */
+static const struct ath5k_ini_rf rfregs_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 } },
+};
+
+/* 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 } },
+};
+
+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 }
+       }
+};
+
+/* RF5112 mode-specific init registers */
+static const struct ath5k_ini_rf rfregs_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 } },
+};
+
+/* RF5112A mode-specific init registers */
+static const struct ath5k_ini_rf rfregs_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,
+           { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+       { 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,
+           { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+       { 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,
+           { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
+       { 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,
+           { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
+       { 6, 0x989c,
+           { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
+       { 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 } },
+};
+
+
+static const struct ath5k_ini_rf rfregs_2112a[] = {
+       { 1, AR5K_RF_BUFFER_CONTROL_4,
+       /*         mode b       mode g    mode gTurbo */
+               { 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, AR5K_RF_BUFFER_CONTROL_3,
+               { 0x03060408, 0x03060408, 0x03070408 } },
+       { 3, AR5K_RF_BUFFER_CONTROL_6,
+               { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x0a000000, 0x0a000000, 0x0a000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00800000, 0x00800000, 0x00800000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00010000, 0x00010000, 0x00010000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00180000, 0x00180000, 0x00180000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x006e0000, 0x006e0000, 0x006e0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00c70000, 0x00c70000, 0x00c70000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x004b0000, 0x004b0000, 0x004b0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x04480000, 0x04480000, 0x04480000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00e40000, 0x00e40000, 0x00e40000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x043f0000, 0x043f0000, 0x043f0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x02190000, 0x02190000, 0x02190000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00240000, 0x00240000, 0x00240000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00b40000, 0x00b40000, 0x00b40000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00990000, 0x00990000, 0x00990000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00500000, 0x00500000, 0x00500000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0xc0320000, 0xc0320000, 0xc0320000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x01740000, 0x01740000, 0x01740000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x86280000, 0x86280000, 0x86280000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x31840000, 0x31840000, 0x31840000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00f20080, 0x00f20080, 0x00f20080 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00070019, 0x00070019, 0x00070019 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x000000b2, 0x000000b2, 0x000000b2 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00b02184, 0x00b02184, 0x00b02184 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x004125a4, 0x004125a4, 0x004125a4 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x00119220, 0x00119220, 0x00119220 } },
+       { 6, AR5K_RF_BUFFER,
+               { 0x001a4800, 0x001a4800, 0x001a4800 } },
+       { 6, AR5K_RF_BUFFER_CONTROL_5,
+               { 0x000b0230, 0x000b0230, 0x000b0230 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000094, 0x00000094, 0x00000094 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000091, 0x00000091, 0x00000091 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000012, 0x00000012, 0x00000012 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000080, 0x00000080, 0x00000080 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x000000d9, 0x000000d9, 0x000000d9 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000060, 0x00000060, 0x00000060 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x000000f0, 0x000000f0, 0x000000f0 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x000000a2, 0x000000a2, 0x000000a2 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x00000052, 0x00000052, 0x00000052 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x000000d4, 0x000000d4, 0x000000d4 } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x000014cc, 0x000014cc, 0x000014cc } },
+       { 7, AR5K_RF_BUFFER,
+               { 0x0000048c, 0x0000048c, 0x0000048c } },
+       { 7, AR5K_RF_BUFFER_CONTROL_1,
+               { 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RF5413/5414 mode-specific init registers */
+static const struct ath5k_ini_rf rfregs_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, 0x005100a0, 0x005100a0, 0x005100a0 } },
+       { 6, 0x989c,
+           { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
+       { 6, 0x989c,
+           { 0x00000001, 0x00000001, 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, 0x00003600 } },
+       { 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 } },
+};
+
+
+/* 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 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 } },
+};
+
+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 },
+       }
+};
+
+/*
+ * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
+ */
+static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
+               u32 first, u32 col, bool set)
+{
+       u32 mask, entry, last, data, shift, position;
+       s32 left;
+       int i;
+
+       data = 0;
+
+       if (rf == NULL)
+               /* should not happen */
+               return 0;
+
+       if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
+               ATH5K_PRINTF("invalid values at offset %u\n", offset);
+               return 0;
+       }
+
+       entry = ((first - 1) / 8) + offset;
+       position = (first - 1) % 8;
+
+       if (set == true)
+               data = ath5k_hw_bitswap(reg, bits);
+
+       for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
+               last = (position + left > 8) ? 8 : position + left;
+               mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
+
+               if (set == true) {
+                       rf[entry] &= ~mask;
+                       rf[entry] |= ((data << position) << (col * 8)) & mask;
+                       data >>= (8 - position);
+               } else {
+                       data = (((rf[entry] & mask) >> (col * 8)) >> position)
+                               << shift;
+                       shift += last - position;
+               }
+
+               left -= 8 - position;
+       }
+
+       data = set == true ? 1 : ath5k_hw_bitswap(data, bits);
+
+       return data;
+}
+
+static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
+{
+       u32 mix, step;
+       u32 *rf;
+
+       if (ah->ah_rf_banks == NULL)
+               return 0;
+
+       rf = ah->ah_rf_banks;
+       ah->ah_gain.g_f_corr = 0;
+
+       if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
+               return 0;
+
+       step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
+       mix = ah->ah_gain.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;
+}
+
+static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
+{
+       u32 step, mix, level[4];
+       u32 *rf;
+
+       if (ah->ah_rf_banks == NULL)
+               return false;
+
+       rf = ah->ah_rf_banks;
+
+       if (ah->ah_radio == AR5K_RF5111) {
+               step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
+                               false);
+               level[0] = 0;
+               level[1] = (step == 0x3f) ? 0x32 : step + 4;
+               level[2] = (step != 0x3f) ? 0x40 : level[0];
+               level[3] = level[2] + 0x32;
+
+               ah->ah_gain.g_high = level[3] -
+                       (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+               ah->ah_gain.g_low = level[0] +
+                       (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+       } else {
+               mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
+                               false);
+               level[0] = level[2] = 0;
+
+               if (mix == 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]);
+}
+
+static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
+{
+       const struct ath5k_gain_opt *go;
+       int ret = 0;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               go = &rfgain_opt_5111;
+               break;
+       case AR5K_RF5112:
+       case AR5K_RF5413: /* ??? */
+               go = &rfgain_opt_5112;
+               break;
+       default:
+               return 0;
+       }
+
+       ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+               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;
+                               ah->ah_gain.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 -
+                           ah->ah_gain.g_step->gos_gain);
+
+               ret = 1;
+               goto done;
+       }
+
+       if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+               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;
+                               ah->ah_gain.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 -
+                           ah->ah_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;
+}
+
+/*
+ * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
+ */
+static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 *rf;
+       const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
+       unsigned int i;
+       int obdb = -1, bank = -1;
+       u32 ee_mode;
+
+       AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
+
+       rf = ah->ah_rf_banks;
+
+       /* Copy values to modify them */
+       for (i = 0; i < rf_size; i++) {
+               if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
+                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       return -EINVAL;
+               }
+
+               if (bank != rfregs_5111[i].rf_bank) {
+                       bank = rfregs_5111[i].rf_bank;
+                       ah->ah_offset[bank] = i;
+               }
+
+               rf[i] = rfregs_5111[i].rf_value[mode];
+       }
+
+       /* Modify bank 0 */
+       if (channel->val & CHANNEL_2GHZ) {
+               if (channel->val & CHANNEL_CCK)
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+               else
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+               obdb = 0;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
+                               ee->ee_ob[ee_mode][obdb], 3, 119, 0, true))
+                       return -EINVAL;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
+                               ee->ee_ob[ee_mode][obdb], 3, 122, 0, true))
+                       return -EINVAL;
+
+               obdb = 1;
+       /* Modify bank 6 */
+       } else {
+               /* For 11a, Turbo and XR */
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               obdb =   channel->freq >= 5725 ? 3 :
+                       (channel->freq >= 5500 ? 2 :
+                       (channel->freq >= 5260 ? 1 :
+                        (channel->freq > 4000 ? 0 : -1)));
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_pwd_84, 1, 51, 3, true))
+                       return -EINVAL;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_pwd_90, 1, 45, 3, true))
+                       return -EINVAL;
+       }
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                       !ee->ee_xpd[ee_mode], 1, 95, 0, true))
+               return -EINVAL;
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                       ee->ee_x_gain[ee_mode], 4, 96, 0, true))
+               return -EINVAL;
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
+                       ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
+               return -EINVAL;
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
+                       ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true))
+               return -EINVAL;
+
+       /* Modify bank 7 */
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
+                       ee->ee_i_gain[ee_mode], 6, 29, 0, true))
+               return -EINVAL;
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
+                       ee->ee_xpd[ee_mode], 1, 4, 0, true))
+               return -EINVAL;
+
+       /* Write RF values */
+       for (i = 0; i < rf_size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register);
+       }
+
+       return 0;
+}
+
+/*
+ * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
+ */
+static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, unsigned int mode)
+{
+       const struct ath5k_ini_rf *rf_ini;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 *rf;
+       unsigned int rf_size, i;
+       int obdb = -1, bank = -1;
+       u32 ee_mode;
+
+       AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
+
+       rf = ah->ah_rf_banks;
+
+       if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
+               && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){
+               rf_ini = rfregs_2112a;
+               rf_size = ARRAY_SIZE(rfregs_5112a);
+               if (mode < 2) {
+                       ATH5K_ERR(ah->ah_sc,"invalid channel mode: %i\n",mode);
+                       return -EINVAL;
+               }
+               mode = mode - 2; /*no a/turboa modes for 2112*/
+       } else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+               rf_ini = rfregs_5112a;
+               rf_size = ARRAY_SIZE(rfregs_5112a);
+       } else {
+               rf_ini = rfregs_5112;
+               rf_size = ARRAY_SIZE(rfregs_5112);
+       }
+
+       /* Copy values to modify them */
+       for (i = 0; i < rf_size; i++) {
+               if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
+                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       return -EINVAL;
+               }
+
+               if (bank != rf_ini[i].rf_bank) {
+                       bank = rf_ini[i].rf_bank;
+                       ah->ah_offset[bank] = i;
+               }
+
+               rf[i] = rf_ini[i].rf_value[mode];
+       }
+
+       /* Modify bank 6 */
+       if (channel->val & CHANNEL_2GHZ) {
+               if (channel->val & CHANNEL_OFDM)
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+               else
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+               obdb = 0;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_ob[ee_mode][obdb], 3, 287, 0, true))
+                       return -EINVAL;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_ob[ee_mode][obdb], 3, 290, 0, true))
+                       return -EINVAL;
+       } else {
+               /* For 11a, Turbo and XR */
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               obdb = channel->freq >= 5725 ? 3 :
+                   (channel->freq >= 5500 ? 2 :
+                       (channel->freq >= 5260 ? 1 :
+                           (channel->freq > 4000 ? 0 : -1)));
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
+                       return -EINVAL;
+
+               if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                               ee->ee_ob[ee_mode][obdb], 3, 282, 0, true))
+                       return -EINVAL;
+       }
+
+       ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+           ee->ee_x_gain[ee_mode], 2, 270, 0, true);
+       ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+           ee->ee_x_gain[ee_mode], 2, 257, 0, true);
+
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
+                       ee->ee_xpd[ee_mode], 1, 302, 0, true))
+               return -EINVAL;
+
+       /* Modify bank 7 */
+       if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
+                       ee->ee_i_gain[ee_mode], 6, 14, 0, true))
+               return -EINVAL;
+
+       /* Write RF values */
+       for (i = 0; i < rf_size; i++)
+               ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+
+       return 0;
+}
+
+/*
+ * Initialize RF5413/5414
+ */
+static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, unsigned int mode)
+{
+       const struct ath5k_ini_rf *rf_ini;
+       u32 *rf;
+       unsigned int rf_size, i;
+       int bank = -1;
+
+       AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
+
+       rf = ah->ah_rf_banks;
+
+       rf_ini = rfregs_5413;
+       rf_size = ARRAY_SIZE(rfregs_5413);
+
+       /* Copy values to modify them */
+       for (i = 0; i < rf_size; i++) {
+               if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
+                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       return -EINVAL;
+               }
+
+               if (bank != rf_ini[i].rf_bank) {
+                       bank = rf_ini[i].rf_bank;
+                       ah->ah_offset[bank] = i;
+               }
+
+               rf[i] = rf_ini[i].rf_value[mode];
+       }
+
+       /*
+        * After compairing dumps from different cards
+        * we get the same RF_BUFFER settings (diff returns
+        * 0 lines). It seems that RF_BUFFER settings are static
+        * and are written unmodified (no EEPROM stuff
+        * is used because calibration data would be
+        * different between different cards and would result
+        * different RF_BUFFER settings)
+        */
+
+       /* Write RF values */
+       for (i = 0; i < rf_size; i++)
+               ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
+
+       return 0;
+}
+
+/*
+ * Initialize RF
+ */
+int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               unsigned int mode)
+{
+       int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
+       int ret;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               ah->ah_rf_banks_size = sizeof(rfregs_5111);
+               func = ath5k_hw_rf5111_rfregs;
+               break;
+       case AR5K_RF5112:
+               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+                       ah->ah_rf_banks_size = sizeof(rfregs_5112a);
+               else
+                       ah->ah_rf_banks_size = sizeof(rfregs_5112);
+               func = ath5k_hw_rf5112_rfregs;
+               break;
+       case AR5K_RF5413:
+               ah->ah_rf_banks_size = sizeof(rfregs_5413);
+               func = ath5k_hw_rf5413_rfregs;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (ah->ah_rf_banks == NULL) {
+               /* XXX do extra checks? */
+               ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
+               if (ah->ah_rf_banks == NULL) {
+                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+
+       ret = func(ah, channel, mode);
+       if (!ret)
+               ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
+
+       return ret;
+}
+
+int ath5k_hw_rfgain(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_RF5413:
+               ath5k_rfg = rfgain_5413;
+               size = ARRAY_SIZE(rfgain_5413);
+               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;
+}
+
+enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
+{
+       u32 data, type;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
+                       ah->ah_version <= AR5K_AR5211)
+               return AR5K_RFGAIN_INACTIVE;
+
+       if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
+               goto done;
+
+       data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+
+       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 (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
+                       ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
+
+               if (ah->ah_radio >= AR5K_RF5112) {
+                       ath5k_hw_rfregs_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;
+               }
+
+               if (ath5k_hw_rfregs_gain_readback(ah) &&
+                               AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+                               ath5k_hw_rfregs_gain_adjust(ah))
+                       ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
+       }
+
+done:
+       return ah->ah_rf_gain;
+}
+
+int ath5k_hw_set_rfgain_opt(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_step =
+                   &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 35;
+               ah->ah_gain.g_active = 1;
+               break;
+       case AR5K_RF5112:
+       case AR5K_RF5413: /* ??? */
+               ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+               ah->ah_gain.g_step =
+                   &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 85;
+               ah->ah_gain.g_active = 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       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((channel->chan - 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 = channel->chan;
+       u32 data0, data1, clock;
+       int ret;
+
+       /*
+        * Set the channel on the RF5111 radio
+        */
+       data0 = data1 = 0;
+
+       if (channel->val & CHANNEL_2GHZ) {
+               /* Map 2GHz channel to 5GHz Atheros channel ID */
+               ret = ath5k_hw_rf5111_chan2athchan(channel->chan,
+                               &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->freq;
+
+       /*
+        * Set the channel on the RF5112 or newer
+        */
+       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 % 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;
+       }
+
+       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 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
+        * (don't care about regulation restrictions at this point)
+        */
+       if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min ||
+           channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) &&
+           (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min ||
+           channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) {
+               ATH5K_ERR(ah->ah_sc,
+                       "channel out of supported range (%u MHz)\n",
+                       channel->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;
+       default:
+               ret = ath5k_hw_rf5112_channel(ah, channel);
+               break;
+       }
+
+       if (ret)
+               return ret;
+
+       ah->ah_current_channel.freq = channel->freq;
+       ah->ah_current_channel.val = channel->val;
+       ah->ah_turbo = channel->val == 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
+ *
+ */
+int
+ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
+{
+       int ret;
+       unsigned int i;
+       s32 noise_floor;
+
+       /*
+        * Enable noise floor calibration and wait until completion
+        */
+       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 ret;
+       }
+
+       /* 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 -EIO;
+       }
+
+       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);
+
+       udelay(2300);
+
+       /*
+        * 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->freq);
+               return ret;
+       }
+
+       ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
+       if (ret)
+               return ret;
+
+       /*
+        * 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
+ */
+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;
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_calibration == false ||
+                       ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
+               goto done;
+
+       ah->ah_calibration = false;
+
+       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 >> 6;
+
+       if (i_coffd == 0 || q_coffd == 0)
+               goto done;
+
+       i_coff = ((-iq_corr) / i_coffd) & 0x3f;
+       q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f;
+
+       /* Commit new IQ 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));
+
+done:
+       ath5k_hw_noise_floor_calibration(ah, channel->freq);
+
+       /* Request RF gain */
+       if (channel->val & CHANNEL_5GHZ) {
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
+                       AR5K_PHY_PAPD_PROBE_TXPOWER) |
+                       AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
+               ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
+       }
+
+       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
+ */
+
+/*
+ * Initialize the tx power table (not fully implemented)
+ */
+static void ath5k_txpower_table(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, s16 max_power)
+{
+       unsigned int i, min, max, n;
+       u16 txpower, *rates;
+
+       rates = ah->ah_txpower.txp_rates;
+
+       txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
+       if (max_power > txpower)
+               txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
+                   AR5K_TUNE_MAX_TXPOWER : max_power;
+
+       for (i = 0; i < AR5K_MAX_RATES; i++)
+               rates[i] = txpower;
+
+       /* XXX setup target powers by rate */
+
+       ah->ah_txpower.txp_min = rates[7];
+       ah->ah_txpower.txp_max = rates[0];
+       ah->ah_txpower.txp_ofdm = rates[0];
+
+       /* Calculate the power table */
+       n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac);
+       min = AR5K_EEPROM_PCDAC_START;
+       max = AR5K_EEPROM_PCDAC_STOP;
+       for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
+               ah->ah_txpower.txp_pcdac[i] =
+#ifdef notyet
+               min + ((i * (max - min)) / n);
+#else
+               min;
+#endif
+}
+
+/*
+ * Set transmition power
+ */
+int /*O.K. - txpower_table is unimplemented so this doesn't work*/
+ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               unsigned int txpower)
+{
+       bool tpc = ah->ah_txpower.txp_tpc;
+       unsigned int i;
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (txpower > AR5K_TUNE_MAX_TXPOWER) {
+               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+               return -EINVAL;
+       }
+
+       /* Reset TX power values */
+       memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+       ah->ah_txpower.txp_tpc = tpc;
+
+       /* Initialize TX power table */
+       ath5k_txpower_table(ah, channel, txpower);
+
+       /*
+        * Write TX power values
+        */
+       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+               ath5k_hw_reg_write(ah,
+                       ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) |
+                       (((ah->ah_txpower.txp_pcdac[(i << 1)    ] << 8) | 0xff) & 0xffff),
+                       AR5K_PHY_PCDAC_TXPOWER(i));
+       }
+
+       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);
+
+       if (ah->ah_txpower.txp_tpc == true)
+               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
+                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+       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, unsigned int power)
+{
+       /*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", power);
+
+       return ath5k_hw_txpower(ah, channel, power);
+}
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
new file mode 100644 (file)
index 0000000..2f41c83
--- /dev/null
@@ -0,0 +1,1987 @@
+/*
+ * Copyright (c) 2007 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2007 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
+ */
+
+
+
+/*====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
+
+/*
+ * 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 values (?) */
+#define AR5K_CFG_ADHOC         0x00000020      /* [5211+] */
+#define AR5K_CFG_PHY_OK                0x00000100      /* [5211+] */
+#define AR5K_CFG_EEBS          0x00000200      /* EEPROM is busy */
+#define        AR5K_CFG_CLKGD          0x00000400      /* Clock gated (?) */
+#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      /* [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 */
+#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_TXE   0x00000400      /* Enable jumbo frames transmition (?) [5211+] */
+#define AR5K_TXCFG_RTSRND      0x00001000      /* [5211+] */
+#define AR5K_TXCFG_FRMPAD_DIS  0x00002000      /* [5211+] */
+#define AR5K_TXCFG_RDY_DIS     0x00004000      /* [5211+] */
+
+/*
+ * Receive configuration register
+ */
+#define AR5K_RXCFG             0x0034                  /* Register Address */
+#define AR5K_RXCFG_SDMAMW      0x00000007      /* DMA size */
+#define AR5K_RXCFG_SDMAMW_S    0
+#define        AR5K_RXCFG_DEF_ANTENNA  0x00000008      /* Default antenna */
+#define AR5K_RXCFG_ZLFDMA      0x00000010      /* Zero-length DMA */
+#define AR5K_RXCFG_JUMBO_RXE   0x00000020      /* Enable jumbo frames reception (?) [5211+] */
+#define AR5K_RXCFG_JUMBO_WRAP  0x00000040      /* Wrap jumbo frames (?) [5211+] */
+
+/*
+ * 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
+#define AR5K_MIBC_FMC          0x00000002      /* Freeze Mib Counters (?) */
+#define AR5K_MIBC_CMC          0x00000004      /* Clean Mib Counters (?) */
+#define AR5K_MIBC_MCS          0x00000008
+
+/*
+ * Timeout prescale register
+ */
+#define AR5K_TOPS              0x0044
+#define        AR5K_TOPS_M             0x0000ffff      /* [5211+] (?) */
+
+/*
+ * Receive timeout register (no frame received)
+ */
+#define AR5K_RXNOFRM           0x0048
+#define        AR5K_RXNOFRM_M          0x000003ff      /* [5211+] (?) */
+
+/*
+ * Transmit timeout register (no frame sent)
+ */
+#define AR5K_TXNOFRM           0x004c
+#define        AR5K_TXNOFRM_M          0x000003ff      /* [5211+] (?) */
+#define        AR5K_TXNOFRM_QCU        0x000ffc00      /* [5211+] (?) */
+
+/*
+ * Receive frame gap timeout register
+ */
+#define AR5K_RPGTO             0x0050
+#define AR5K_RPGTO_M           0x000003ff      /* [5211+] (?) */
+
+/*
+ * Receive frame count limit register
+ */
+#define AR5K_RFCNT             0x0054
+#define AR5K_RFCNT_M           0x0000001f      /* [5211+] (?) */
+#define AR5K_RFCNT_RFCL                0x0000000f      /* [5210] */
+
+/*
+ * Misc settings register
+ */
+#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)
+ */
+#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
+#define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
+#define AR5K_ISR_BRSSI         0x00020000
+#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      /* [5210] */
+#define AR5K_ISR_RXCHIRP       0x00200000      /* [5212+] */
+#define AR5K_ISR_SSERR         0x00200000      /* [5210] */
+#define AR5K_ISR_DPERR         0x00400000      /* [5210] */
+#define AR5K_ISR_TIM           0x00800000      /* [5210] */
+#define AR5K_ISR_BCNMISC       0x00800000      /* [5212+] */
+#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill)*/
+#define AR5K_ISR_QCBRORN       0x02000000      /* CBR overrun (?)  [5211+] */
+#define AR5K_ISR_QCBRURN       0x04000000      /* CBR underrun (?) [5211+] */
+#define AR5K_ISR_QTRIG         0x08000000      /* [5211+] */
+
+/*
+ * Secondary status registers [5211+] (0 - 4)
+ *
+ * I guess from the names that these give the status for each
+ * queue, that's why only masks are defined here, haven't got
+ * any info about them (couldn't find them anywhere in ar5k code).
+ */
+#define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
+#define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+
+#define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
+#define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+
+#define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
+#define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define        AR5K_SISR2_MCABT        0x00100000
+#define        AR5K_SISR2_SSERR        0x00200000
+#define        AR5K_SISR2_DPERR        0x00400000
+#define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* [5212+] */
+#define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* [5212+] */
+#define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* [5212+] */
+#define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
+
+#define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
+#define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+
+#define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
+#define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+
+/*
+ * 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
+#define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
+#define AR5K_IMR_RXKCM         0x00008000
+#define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
+#define AR5K_IMR_BRSSI         0x00020000
+#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      /* [5210] */
+#define AR5K_IMR_RXCHIRP       0x00200000      /* [5212+]*/
+#define AR5K_IMR_SSERR         0x00200000      /* [5210] */
+#define AR5K_IMR_DPERR         0x00400000      /* [5210] */
+#define AR5K_IMR_TIM           0x00800000      /* [5211+] */
+#define AR5K_IMR_BCNMISC       0x00800000      /* [5212+] */
+#define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
+#define AR5K_IMR_QCBRORN       0x02000000      /* CBR overrun (?) [5211+] */
+#define AR5K_IMR_QCBRURN       0x04000000      /* CBR underrun (?) [5211+] */
+#define AR5K_IMR_QTRIG         0x08000000      /* [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
+#define        AR5K_SIMR2_SSERR        0x00200000
+#define        AR5K_SIMR2_DPERR        0x00400000
+#define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* [5212+] */
+#define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* [5212+] */
+#define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* [5212+] */
+#define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
+
+#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
+
+
+/*
+ * Decompression mask registers [5212+]
+ */
+#define AR5K_DCM_ADDR          0x0400          /*Decompression mask address (?)*/
+#define AR5K_DCM_DATA          0x0404          /*Decompression mask data (?)*/
+
+/*
+ * Decompression configuration registers [5212+]
+ */
+#define AR5K_DCCFG             0x0420
+
+/*
+ * Compression configuration registers [5212+]
+ */
+#define AR5K_CCFG              0x0600
+#define AR5K_CCFG_CUP          0x0604
+
+/*
+ * 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_CPCORN            0x0620          /* Compression performance overrun (?) */
+
+
+/*
+ * 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.
+ *
+ * TODO: Boundary checking on macros (here?)
+ */
+
+/*
+ * 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_DURATION    0x00ffffff      /* Ready time duration mask */
+#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               /* Time 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            0x00000020      /* CBR expired (normal queue) */
+#define        AR5K_QCU_MISC_CBREXP_BCN        0x00000040      /* CBR expired (beacon queue) */
+#define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Beacons enabled */
+#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR threshold enabled (?) */
+#define        AR5K_QCU_MISC_TXE               0x00000200      /* TXE reset when RDYTIME enalbed (?) */
+#define        AR5K_QCU_MISC_CBR               0x00000400      /* CBR threshold reset (?) */
+#define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU reset (?) */
+#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
+
+/*
+ * QCU compression buffer configuration register [5212+]
+ */
+#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_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+]
+ *
+ * For some of the registers i couldn't find in the code
+ * (only backoff stuff is there realy) i tried to match the
+ * names with 802.11e parameters etc, so i guess VIRTCOL here
+ * means Virtual Collision and HCFPOLL means Hybrid Coordination
+ * factor Poll (CF- Poll). 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           0x000007ff      /* Mask for backoff setting (?) */
+#define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
+#define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll (?) */
+#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_MODIFIED  1
+#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    2
+#define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Beacon enable (?) */
+#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
+#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 policy (?) */
+#define        AR5K_DCU_MISC_BLOWN_IFS_POLICY  0x00800000
+#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_DFS_SEQNUM(_q)       AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+
+/*
+ * DCU global IFS SIFS registers
+ */
+#define AR5K_DCU_GBL_IFS_SIFS  0x1030
+#define AR5K_DCU_GBL_IFS_SIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS slot interval registers
+ */
+#define AR5K_DCU_GBL_IFS_SLOT  0x1070
+#define AR5K_DCU_GBL_IFS_SLOT_M        0x0000ffff
+
+/*
+ * DCU global IFS EIFS registers
+ */
+#define AR5K_DCU_GBL_IFS_EIFS  0x10b0
+#define AR5K_DCU_GBL_IFS_EIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS misc registers
+ */
+#define AR5K_DCU_GBL_IFS_MISC                  0x10f0                  /* Register Address */
+#define        AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE        0x00000007
+#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
+#define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000
+
+/*
+ * DCU frame prefetch control register
+ */
+#define AR5K_DCU_FP            0x1230
+
+/*
+ * 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 register
+ */
+#define AR5K_DCU_TX_FILTER     0x1038
+
+/*
+ * 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
+ *
+ * 4 and 8 are not used in 5211/5212 and
+ * 2 means "baseband reset" on 5211/5212.
+ */
+#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) */
+#define AR5K_RESET_CTL_CHIP    (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA |      \
+                               AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY)
+
+/*
+ * 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
+#define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
+
+/*
+ * Interrupt pending register
+ */
+#define AR5K_INTPEND   0x4008
+#define AR5K_INTPEND_M 0x00000001
+
+/*
+ * Sleep force register
+ */
+#define AR5K_SFR       0x400c
+#define AR5K_SFR_M     0x00000001
+
+/*
+ * PCI configuration register
+ */
+#define AR5K_PCICFG                    0x4010                  /* Register Address */
+#define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
+#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_SL_INPEN           0x00002800      /* 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
+#define AR5K_PCICFG_LEDBLINK_S         20
+#define AR5K_PCICFG_LEDSLOW            0x00800000      /* Slow led blink rate (?) [5211+] */
+#define AR5K_PCICFG_LEDSTATE                           \
+       (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
+       AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
+
+/*
+ * "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 off (?) */
+#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is on */
+#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
+
+
+
+/*====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
+
+/*
+ * 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_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
+#define AR5K_EEPROM_REG_DOMAIN         0x00bf  /* EEPROM regdom */
+#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
+#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
+
+#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_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz (?) */
+#define AR5K_EEPROM_HDR_RFKILL(_v)     (((_v) >> 14) & 0x1)    /* Device has RFKill support */
+
+#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)  ((int8_t)(((_v) >> 8) & 0xff))
+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)  ((int8_t)((_v) & 0xff))
+
+/* 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 */
+
+/* [3.1 - 3.3] */
+#define AR5K_EEPROM_OBDB0_2GHZ         0x00ec
+#define AR5K_EEPROM_OBDB1_2GHZ         0x00ed
+
+/* Misc values available since EEPROM 4.0 */
+#define AR5K_EEPROM_MISC0              0x00c4
+#define AR5K_EEPROM_EARSTART(_v)       ((_v) & 0xfff)
+#define AR5K_EEPROM_EEMAP(_v)          (((_v) >> 14) & 0x3)
+#define AR5K_EEPROM_MISC1              0x00c5
+#define AR5K_EEPROM_TARGET_PWRSTART(_v)        ((_v) & 0xfff)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)        (((_v) >> 14) & 0x1)
+
+/*
+ * 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
+
+
+
+/*
+ * 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 (MAC address in lower 32 bits)
+ */
+#define AR5K_STA_ID0   0x8000
+
+/*
+ * Second station id register (MAC address in upper 16 bits)
+ */
+#define AR5K_STA_ID1                   0x8004                  /* Register Address */
+#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+] */
+
+/*
+ * 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
+#define AR5K_USEC_1_S                  0
+#define AR5K_USEC_32                   0x00003f80
+#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
+#define AR5K_BEACON_5211       0x8020
+#define AR5K_BEACON            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_BEACON_5210 : AR5K_BEACON_5211)
+#define AR5K_BEACON_PERIOD     0x0000ffff
+#define AR5K_BEACON_PERIOD_S   0
+#define AR5K_BEACON_TIM                0x007f0000
+#define AR5K_BEACON_TIM_S      16
+#define AR5K_BEACON_ENABLE     0x00800000
+#define AR5K_BEACON_RESET_TSF  0x01000000
+
+/*
+ * 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
+ * TODO: Get these out of ar5xxx.h on ath5k
+ */
+#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
+#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
+#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
+#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_5211        0x00000200      /* Scrambler seed (?) */
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400
+#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
+#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
+#define AR5K_DIAG_SW_OBSPT_S           18
+
+/*
+ * 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
+ */
+#define AR5K_LAST_TSTP 0x8080
+
+/*
+ * ADDAC test register [5211+]
+ */
+#define AR5K_ADDAC_TEST        0x8054
+#define AR5K_ADDAC_TEST_TXCONT 0x00000001
+
+/*
+ * Default antenna register [5211+]
+ */
+#define AR5K_DEFAULT_ANTENNA   0x8058
+
+
+
+/*
+ * 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===*/
+
+/*
+ * XR (eXtended Range) mode register
+ */
+#define AR5K_XRMODE                    0x80c0
+#define        AR5K_XRMODE_POLL_TYPE_M         0x0000003f
+#define        AR5K_XRMODE_POLL_TYPE_S         0
+#define        AR5K_XRMODE_POLL_SUBTYPE_M      0x0000003c
+#define        AR5K_XRMODE_POLL_SUBTYPE_S      2
+#define        AR5K_XRMODE_POLL_WAIT_ALL       0x00000080
+#define        AR5K_XRMODE_SIFS_DELAY          0x000fff00
+#define        AR5K_XRMODE_FRAME_HOLD_M        0xfff00000
+#define        AR5K_XRMODE_FRAME_HOLD_S        20
+
+/*
+ * XR delay register
+ */
+#define AR5K_XRDELAY                   0x80c4
+#define AR5K_XRDELAY_SLOT_DELAY_M      0x0000ffff
+#define AR5K_XRDELAY_SLOT_DELAY_S      0
+#define AR5K_XRDELAY_CHIRP_DELAY_M     0xffff0000
+#define AR5K_XRDELAY_CHIRP_DELAY_S     16
+
+/*
+ * XR timeout register
+ */
+#define AR5K_XRTIMEOUT                 0x80c8
+#define AR5K_XRTIMEOUT_CHIRP_M         0x0000ffff
+#define AR5K_XRTIMEOUT_CHIRP_S         0
+#define AR5K_XRTIMEOUT_POLL_M          0xffff0000
+#define AR5K_XRTIMEOUT_POLL_S          16
+
+/*
+ * XR chirp register
+ */
+#define AR5K_XRCHIRP                   0x80cc
+#define AR5K_XRCHIRP_SEND              0x00000001
+#define AR5K_XRCHIRP_GAP               0xffff0000
+
+/*
+ * XR stomp register
+ */
+#define AR5K_XRSTOMP                   0x80d0
+#define AR5K_XRSTOMP_TX                        0x00000001
+#define AR5K_XRSTOMP_RX_ABORT          0x00000002
+#define AR5K_XRSTOMP_RSSI_THRES                0x0000ff00
+
+/*
+ * First enhanced sleep register
+ */
+#define AR5K_SLEEP0                    0x80d4
+#define AR5K_SLEEP0_NEXT_DTIM          0x0007ffff
+#define AR5K_SLEEP0_NEXT_DTIM_S                0
+#define AR5K_SLEEP0_ASSUME_DTIM                0x00080000
+#define AR5K_SLEEP0_ENH_SLEEP_EN       0x00100000
+#define AR5K_SLEEP0_CABTO              0xff000000
+#define AR5K_SLEEP0_CABTO_S            24
+
+/*
+ * Second enhanced sleep register
+ */
+#define AR5K_SLEEP1                    0x80d8
+#define AR5K_SLEEP1_NEXT_TIM           0x0007ffff
+#define AR5K_SLEEP1_NEXT_TIM_S         0
+#define AR5K_SLEEP1_BEACON_TO          0xff000000
+#define AR5K_SLEEP1_BEACON_TO_S                24
+
+/*
+ * Third enhanced sleep register
+ */
+#define AR5K_SLEEP2                    0x80dc
+#define AR5K_SLEEP2_TIM_PER            0x0000ffff
+#define AR5K_SLEEP2_TIM_PER_S          0
+#define AR5K_SLEEP2_DTIM_PER           0xffff0000
+#define AR5K_SLEEP2_DTIM_PER_S         16
+
+/*
+ * BSSID mask registers
+ */
+#define AR5K_BSS_IDM0                  0x80e0
+#define AR5K_BSS_IDM1                  0x80e4
+
+/*
+ * TX power control (TPC) register
+ */
+#define AR5K_TXPC                      0x80e8
+#define AR5K_TXPC_ACK_M                        0x0000003f
+#define AR5K_TXPC_ACK_S                        0
+#define AR5K_TXPC_CTS_M                        0x00003f00
+#define AR5K_TXPC_CTS_S                        8
+#define AR5K_TXPC_CHIRP_M              0x003f0000
+#define AR5K_TXPC_CHIRP_S              22
+
+/*
+ * Profile count registers
+ */
+#define AR5K_PROFCNT_TX                        0x80ec
+#define AR5K_PROFCNT_RX                        0x80f0
+#define AR5K_PROFCNT_RXCLR             0x80f4
+#define AR5K_PROFCNT_CYCLE             0x80f8
+
+/*
+ * TSF parameter register
+ */
+#define AR5K_TSF_PARM                  0x8104
+#define AR5K_TSF_PARM_INC_M            0x000000ff
+#define AR5K_TSF_PARM_INC_S            0
+
+/*
+ * PHY error filter register
+ */
+#define AR5K_PHY_ERR_FIL               0x810c
+#define AR5K_PHY_ERR_FIL_RADAR         0x00000020
+#define AR5K_PHY_ERR_FIL_OFDM          0x00020000
+#define AR5K_PHY_ERR_FIL_CCK           0x02000000
+
+/*
+ * Rate duration register
+ */
+#define AR5K_RATE_DUR_BASE             0x8700
+#define AR5K_RATE_DUR(_n)              (AR5K_RATE_DUR_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
+
+/* 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 register
+ */
+#define        AR5K_PHY_BASE                   0x9800
+#define        AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
+#define AR5K_PHY_SHIFT_2GHZ            0x00004007
+#define AR5K_PHY_SHIFT_5GHZ            0x00000007
+
+/*
+ * 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
+#define        AR5K_PHY_TURBO_MODE             0x00000001
+#define        AR5K_PHY_TURBO_SHORT            0x00000002
+
+/*
+ * PHY agility command register
+ */
+#define        AR5K_PHY_AGC                    0x9808
+#define        AR5K_PHY_AGC_DISABLE            0x08000000
+
+/*
+ * PHY timing register [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
+#define        AR5K_PHY_ACT_ENABLE             0x00000001
+#define        AR5K_PHY_ACT_DISABLE            0x00000002
+
+/*
+ * PHY signal register
+ */
+#define        AR5K_PHY_SIG                    0x9858
+#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000
+#define        AR5K_PHY_SIG_FIRSTEP_S          12
+#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000
+#define        AR5K_PHY_SIG_FIRPWR_S           18
+
+/*
+ * PHY coarse agility control register
+ */
+#define        AR5K_PHY_AGCCOARSE              0x985c
+#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80
+#define        AR5K_PHY_AGCCOARSE_LO_S         7
+#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000
+#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 */
+
+/*
+ * PHY noise floor status register
+ */
+#define AR5K_PHY_NF                    0x9864
+#define AR5K_PHY_NF_M                  0x000001ff
+#define AR5K_PHY_NF_ACTIVE             0x00000100
+#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))
+
+/*
+ * 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 sleep registers [5112+]
+ */
+#define AR5K_PHY_SCR                   0x9870
+#define AR5K_PHY_SCR_32MHZ             0x0000001f
+#define AR5K_PHY_SLMT                  0x9874
+#define AR5K_PHY_SLMT_32MHZ            0x0000007f
+#define AR5K_PHY_SCAL                  0x9878
+#define AR5K_PHY_SCAL_32MHZ            0x0000000e
+
+/*
+ * PHY PLL (Phase Locked Loop) control register
+ */
+#define        AR5K_PHY_PLL                    0x987c
+#define        AR5K_PHY_PLL_20MHZ              0x13    /* For half rate (?) [5111+] */
+#define        AR5K_PHY_PLL_40MHZ_5211         0x18    /* For 802.11a */
+#define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
+#define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
+                                       AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
+#define        AR5K_PHY_PLL_44MHZ_5211         0x19    /* For 802.11b/g */
+#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
+
+/*
+ * RF Buffer register
+ *
+ * There are some special control registers on the RF chip
+ * that hold 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 buffer register and
+ * then 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 sent such data packets during rf initialization and channel change
+ * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
+ *
+ * The data packets we send during initializadion are inside ath5k_ini_rf
+ * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
+ * We use *rfregs functions to modify them  acording to current operation
+ * mode and eeprom values and pass them all together to the chip.
+ *
+ * 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.
+ *
+ * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+#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
+
+/*
+ * PHY receiver delay register [5111+]
+ */
+#define        AR5K_PHY_RX_DELAY               0x9914
+#define        AR5K_PHY_RX_DELAY_M             0x00003fff
+
+/*
+ * PHY timing I(nphase) Q(adrature) control 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
+#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S   12
+#define        AR5K_PHY_IQ_RUN                 0x00010000      /* Run i/q calibration */
+
+
+/*
+ * PHY PAPD probe register [5111+ (?)]
+ * Is this only present in 5212 ?
+ * Because it's always 0 in 5211 initialization code
+ */
+#define        AR5K_PHY_PAPD_PROBE             0x9930
+#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_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
+#define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
+/*---[5110/5111]---*/
+#define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000
+#define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000
+#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 radar detection register [5111+]
+ */
+#define        AR5K_PHY_RADAR                  0x9954
+
+/* Radar enable                        ........ ........ ........ .......1 */
+#define        AR5K_PHY_RADAR_ENABLE           0x00000001
+#define        AR5K_PHY_RADAR_DISABLE          0x00000000
+#define        AR5K_PHY_RADAR_ENABLE_S         0
+
+/* This is the value found on the card  .1.111.1 .1.1.... 111....1 1...1...
+at power on. */
+#define        AR5K_PHY_RADAR_PWONDEF_AR5213   0x5d50e188
+
+/* This is the value found on the card         .1.1.111 ..11...1 .1...1.1 1...11.1
+after DFS is enabled */
+#define        AR5K_PHY_RADAR_ENABLED_AR5213   0x5731458d
+
+/* Finite Impulse Response (FIR) filter .1111111 ........ ........ ........
+ * power out threshold.
+ * 7-bits, standard power range {0..127} in 1/2 dBm units. */
+#define AR5K_PHY_RADAR_FIRPWROUTTHR            0x7f000000
+#define AR5K_PHY_RADAR_FIRPWROUTTHR_S  24
+
+/* Radar RSSI/SNR threshold.           ........ 111111.. ........ ........
+ * 6-bits, dBm range {0..63} in dBm units. */
+#define AR5K_PHY_RADAR_RADARRSSITHR            0x00fc0000
+#define AR5K_PHY_RADAR_RADARRSSITHR_S  18
+
+/* Pulse height threshold              ........ ......11 1111.... ........
+ * 6-bits, dBm range {0..63} in dBm units. */
+#define AR5K_PHY_RADAR_PULSEHEIGHTTHR   0x0003f000
+#define AR5K_PHY_RADAR_PULSEHEIGHTTHR_S        12
+
+/* Pulse RSSI/SNR threshold            ........ ........ ....1111 11......
+ * 6-bits, dBm range {0..63} in dBm units. */
+#define AR5K_PHY_RADAR_PULSERSSITHR            0x00000fc0
+#define AR5K_PHY_RADAR_PULSERSSITHR_S  6
+
+/* Inband threshold                    ........ ........ ........ ..11111.
+ * 5-bits, units unknown {0..31} (? MHz ?) */
+#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e
+#define AR5K_PHY_RADAR_INBANDTHR_S     1
+
+/*
+ * PHY antenna switch table registers [5110]
+ */
+#define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
+#define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
+
+/*
+ * 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
+#define AR5K_PHY_SPENDING_RF5111       0x00000018
+#define AR5K_PHY_SPENDING_RF5112       0x00000014
+
+/*
+ * Misc PHY/radio registers [5110 - 5111]
+ */
+#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 PCDAC TX power table
+ */
+#define        AR5K_PHY_PCDAC_TXPOWER_BASE_5211        0xa180
+#define AR5K_PHY_PCDAC_TXPOWER_BASE_5413       0xa280
+#define AR5K_PHY_PCDAC_TXPOWER_BASE    (ah->ah_radio >= AR5K_RF5413 ? \
+                                       AR5K_PHY_PCDAC_TXPOWER_BASE_5413 :\
+                                       AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
+#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 mask*/
+#define AR5K_PHY_MODE_MOD_OFDM         0
+#define AR5K_PHY_MODE_MOD_CCK          1
+#define AR5K_PHY_MODE_FREQ             0x00000002      /* Freq mode mask */
+#define        AR5K_PHY_MODE_FREQ_5GHZ         0
+#define        AR5K_PHY_MODE_FREQ_2GHZ         2
+#define AR5K_PHY_MODE_MOD_DYN          0x00000004      /* Dynamic OFDM/CCK mode mask [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      /* [5112+] */
+
+/*
+ * PHY CCK transmit control register [5111+ (?)]
+ */
+#define AR5K_PHY_CCKTXCTL              0xa204
+#define AR5K_PHY_CCKTXCTL_WORLD                0x00000000
+#define AR5K_PHY_CCKTXCTL_JAPAN                0x00000010
+
+/*
+ * 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
diff --git a/drivers/net/wireless/ath5k/regdom.c b/drivers/net/wireless/ath5k/regdom.c
new file mode 100644 (file)
index 0000000..e851957
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
+ *
+ * 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.
+ */
+
+/*
+ * Basic regulation domain extensions for the IEEE 802.11 stack
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "regdom.h"
+
+static const struct ath5k_regdommap {
+       enum ath5k_regdom dmn;
+       enum ath5k_regdom dmn5;
+       enum ath5k_regdom dmn2;
+} r_map[] = {
+       { DMN_DEFAULT,          DMN_DEBUG,      DMN_DEBUG },
+       { DMN_NULL_WORLD,       DMN_NULL,       DMN_WORLD },
+       { DMN_NULL_ETSIB,       DMN_NULL,       DMN_ETSIB },
+       { DMN_NULL_ETSIC,       DMN_NULL,       DMN_ETSIC },
+       { DMN_FCC1_FCCA,        DMN_FCC1,       DMN_FCCA },
+       { DMN_FCC1_WORLD,       DMN_FCC1,       DMN_WORLD },
+       { DMN_FCC2_FCCA,        DMN_FCC2,       DMN_FCCA },
+       { DMN_FCC2_WORLD,       DMN_FCC2,       DMN_WORLD },
+       { DMN_FCC2_ETSIC,       DMN_FCC2,       DMN_ETSIC },
+       { DMN_FRANCE_NULL,      DMN_ETSI3,      DMN_ETSI3 },
+       { DMN_FCC3_FCCA,        DMN_FCC3,       DMN_WORLD },
+       { DMN_ETSI1_WORLD,      DMN_ETSI1,      DMN_WORLD },
+       { DMN_ETSI3_ETSIA,      DMN_ETSI3,      DMN_WORLD },
+       { DMN_ETSI2_WORLD,      DMN_ETSI2,      DMN_WORLD },
+       { DMN_ETSI3_WORLD,      DMN_ETSI3,      DMN_WORLD },
+       { DMN_ETSI4_WORLD,      DMN_ETSI4,      DMN_WORLD },
+       { DMN_ETSI4_ETSIC,      DMN_ETSI4,      DMN_ETSIC },
+       { DMN_ETSI5_WORLD,      DMN_ETSI5,      DMN_WORLD },
+       { DMN_ETSI6_WORLD,      DMN_ETSI6,      DMN_WORLD },
+       { DMN_ETSI_NULL,        DMN_ETSI1,      DMN_ETSI1 },
+       { DMN_MKK1_MKKA,        DMN_MKK1,       DMN_MKKA },
+       { DMN_MKK1_MKKB,        DMN_MKK1,       DMN_MKKA },
+       { DMN_APL4_WORLD,       DMN_APL4,       DMN_WORLD },
+       { DMN_MKK2_MKKA,        DMN_MKK2,       DMN_MKKA },
+       { DMN_APL_NULL,         DMN_APL1,       DMN_NULL },
+       { DMN_APL2_WORLD,       DMN_APL2,       DMN_WORLD },
+       { DMN_APL2_APLC,        DMN_APL2,       DMN_WORLD },
+       { DMN_APL3_WORLD,       DMN_APL3,       DMN_WORLD },
+       { DMN_MKK1_FCCA,        DMN_MKK1,       DMN_FCCA },
+       { DMN_APL2_APLD,        DMN_APL2,       DMN_APLD },
+       { DMN_MKK1_MKKA1,       DMN_MKK1,       DMN_MKKA },
+       { DMN_MKK1_MKKA2,       DMN_MKK1,       DMN_MKKA },
+       { DMN_APL1_WORLD,       DMN_APL1,       DMN_WORLD },
+       { DMN_APL1_FCCA,        DMN_APL1,       DMN_FCCA },
+       { DMN_APL1_APLA,        DMN_APL1,       DMN_WORLD },
+       { DMN_APL1_ETSIC,       DMN_APL1,       DMN_ETSIC },
+       { DMN_APL2_ETSIC,       DMN_APL2,       DMN_ETSIC },
+       { DMN_APL5_WORLD,       DMN_APL5,       DMN_WORLD },
+       { DMN_WOR0_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR1_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR2_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR3_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR4_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR5_ETSIC,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR01_WORLD,      DMN_WORLD,      DMN_WORLD },
+       { DMN_WOR02_WORLD,      DMN_WORLD,      DMN_WORLD },
+       { DMN_EU1_WORLD,        DMN_ETSI1,      DMN_WORLD },
+       { DMN_WOR9_WORLD,       DMN_WORLD,      DMN_WORLD },
+       { DMN_WORA_WORLD,       DMN_WORLD,      DMN_WORLD },
+};
+
+enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(r_map); i++) {
+               if (r_map[i].dmn == dmn) {
+                       if (mhz >= 2000 && mhz <= 3000)
+                               return r_map[i].dmn2;
+                       if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN &&
+                                       mhz <= IEEE80211_CHANNELS_5GHZ_MAX)
+                               return r_map[i].dmn5;
+               }
+       }
+
+       return DMN_DEBUG;
+}
+
+u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee)
+{
+       u32 regdomain = (u32)ieee;
+
+       /*
+        * Use the default regulation domain if the value is empty
+        * or not supported by the net80211 regulation code.
+        */
+       if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) ==
+                       DMN_DEBUG)
+               return (u16)AR5K_TUNE_REGDOMAIN;
+
+       /* It is supported, just return the value */
+       return regdomain;
+}
+
+enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain)
+{
+       enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain;
+
+       return ieee;
+}
+
diff --git a/drivers/net/wireless/ath5k/regdom.h b/drivers/net/wireless/ath5k/regdom.h
new file mode 100644 (file)
index 0000000..f7d3c66
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.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.
+ */
+
+#ifndef _IEEE80211_REGDOMAIN_H_
+#define _IEEE80211_REGDOMAIN_H_
+
+#include <linux/types.h>
+
+/* Default regulation domain if stored value EEPROM value is invalid */
+#define AR5K_TUNE_REGDOMAIN    DMN_FCC2_FCCA   /* Canada */
+#define AR5K_TUNE_CTRY         CTRY_DEFAULT
+
+
+enum ath5k_regdom {
+       DMN_DEFAULT             = 0x00,
+       DMN_NULL_WORLD          = 0x03,
+       DMN_NULL_ETSIB          = 0x07,
+       DMN_NULL_ETSIC          = 0x08,
+       DMN_FCC1_FCCA           = 0x10,
+       DMN_FCC1_WORLD          = 0x11,
+       DMN_FCC2_FCCA           = 0x20,
+       DMN_FCC2_WORLD          = 0x21,
+       DMN_FCC2_ETSIC          = 0x22,
+       DMN_FRANCE_NULL         = 0x31,
+       DMN_FCC3_FCCA           = 0x3A,
+       DMN_ETSI1_WORLD         = 0x37,
+       DMN_ETSI3_ETSIA         = 0x32,
+       DMN_ETSI2_WORLD         = 0x35,
+       DMN_ETSI3_WORLD         = 0x36,
+       DMN_ETSI4_WORLD         = 0x30,
+       DMN_ETSI4_ETSIC         = 0x38,
+       DMN_ETSI5_WORLD         = 0x39,
+       DMN_ETSI6_WORLD         = 0x34,
+       DMN_ETSI_NULL           = 0x33,
+       DMN_MKK1_MKKA           = 0x40,
+       DMN_MKK1_MKKB           = 0x41,
+       DMN_APL4_WORLD          = 0x42,
+       DMN_MKK2_MKKA           = 0x43,
+       DMN_APL_NULL            = 0x44,
+       DMN_APL2_WORLD          = 0x45,
+       DMN_APL2_APLC           = 0x46,
+       DMN_APL3_WORLD          = 0x47,
+       DMN_MKK1_FCCA           = 0x48,
+       DMN_APL2_APLD           = 0x49,
+       DMN_MKK1_MKKA1          = 0x4A,
+       DMN_MKK1_MKKA2          = 0x4B,
+       DMN_APL1_WORLD          = 0x52,
+       DMN_APL1_FCCA           = 0x53,
+       DMN_APL1_APLA           = 0x54,
+       DMN_APL1_ETSIC          = 0x55,
+       DMN_APL2_ETSIC          = 0x56,
+       DMN_APL5_WORLD          = 0x58,
+       DMN_WOR0_WORLD          = 0x60,
+       DMN_WOR1_WORLD          = 0x61,
+       DMN_WOR2_WORLD          = 0x62,
+       DMN_WOR3_WORLD          = 0x63,
+       DMN_WOR4_WORLD          = 0x64,
+       DMN_WOR5_ETSIC          = 0x65,
+       DMN_WOR01_WORLD         = 0x66,
+       DMN_WOR02_WORLD         = 0x67,
+       DMN_EU1_WORLD           = 0x68,
+       DMN_WOR9_WORLD          = 0x69,
+       DMN_WORA_WORLD          = 0x6A,
+
+       DMN_APL1                = 0xf0000001,
+       DMN_APL2                = 0xf0000002,
+       DMN_APL3                = 0xf0000004,
+       DMN_APL4                = 0xf0000008,
+       DMN_APL5                = 0xf0000010,
+       DMN_ETSI1               = 0xf0000020,
+       DMN_ETSI2               = 0xf0000040,
+       DMN_ETSI3               = 0xf0000080,
+       DMN_ETSI4               = 0xf0000100,
+       DMN_ETSI5               = 0xf0000200,
+       DMN_ETSI6               = 0xf0000400,
+       DMN_ETSIA               = 0xf0000800,
+       DMN_ETSIB               = 0xf0001000,
+       DMN_ETSIC               = 0xf0002000,
+       DMN_FCC1                = 0xf0004000,
+       DMN_FCC2                = 0xf0008000,
+       DMN_FCC3                = 0xf0010000,
+       DMN_FCCA                = 0xf0020000,
+       DMN_APLD                = 0xf0040000,
+       DMN_MKK1                = 0xf0080000,
+       DMN_MKK2                = 0xf0100000,
+       DMN_MKKA                = 0xf0200000,
+       DMN_NULL                = 0xf0400000,
+       DMN_WORLD               = 0xf0800000,
+       DMN_DEBUG               = 0xf1000000    /* used for debugging */
+};
+
+#define IEEE80211_DMN(_d)      ((_d) & ~0xf0000000)
+
+enum ath5k_countrycode {
+       CTRY_DEFAULT            = 0,   /* Default domain (NA) */
+       CTRY_ALBANIA            = 8,   /* Albania */
+       CTRY_ALGERIA            = 12,  /* Algeria */
+       CTRY_ARGENTINA          = 32,  /* Argentina */
+       CTRY_ARMENIA            = 51,  /* Armenia */
+       CTRY_AUSTRALIA          = 36,  /* Australia */
+       CTRY_AUSTRIA            = 40,  /* Austria */
+       CTRY_AZERBAIJAN         = 31,  /* Azerbaijan */
+       CTRY_BAHRAIN            = 48,  /* Bahrain */
+       CTRY_BELARUS            = 112, /* Belarus */
+       CTRY_BELGIUM            = 56,  /* Belgium */
+       CTRY_BELIZE             = 84,  /* Belize */
+       CTRY_BOLIVIA            = 68,  /* Bolivia */
+       CTRY_BRAZIL             = 76,  /* Brazil */
+       CTRY_BRUNEI_DARUSSALAM  = 96,  /* Brunei Darussalam */
+       CTRY_BULGARIA           = 100, /* Bulgaria */
+       CTRY_CANADA             = 124, /* Canada */
+       CTRY_CHILE              = 152, /* Chile */
+       CTRY_CHINA              = 156, /* People's Republic of China */
+       CTRY_COLOMBIA           = 170, /* Colombia */
+       CTRY_COSTA_RICA         = 188, /* Costa Rica */
+       CTRY_CROATIA            = 191, /* Croatia */
+       CTRY_CYPRUS             = 196, /* Cyprus */
+       CTRY_CZECH              = 203, /* Czech Republic */
+       CTRY_DENMARK            = 208, /* Denmark */
+       CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
+       CTRY_ECUADOR            = 218, /* Ecuador */
+       CTRY_EGYPT              = 818, /* Egypt */
+       CTRY_EL_SALVADOR        = 222, /* El Salvador */
+       CTRY_ESTONIA            = 233, /* Estonia */
+       CTRY_FAEROE_ISLANDS     = 234, /* Faeroe Islands */
+       CTRY_FINLAND            = 246, /* Finland */
+       CTRY_FRANCE             = 250, /* France */
+       CTRY_FRANCE2            = 255, /* France2 */
+       CTRY_GEORGIA            = 268, /* Georgia */
+       CTRY_GERMANY            = 276, /* Germany */
+       CTRY_GREECE             = 300, /* Greece */
+       CTRY_GUATEMALA          = 320, /* Guatemala */
+       CTRY_HONDURAS           = 340, /* Honduras */
+       CTRY_HONG_KONG          = 344, /* Hong Kong S.A.R., P.R.C. */
+       CTRY_HUNGARY            = 348, /* Hungary */
+       CTRY_ICELAND            = 352, /* Iceland */
+       CTRY_INDIA              = 356, /* India */
+       CTRY_INDONESIA          = 360, /* Indonesia */
+       CTRY_IRAN               = 364, /* Iran */
+       CTRY_IRAQ               = 368, /* Iraq */
+       CTRY_IRELAND            = 372, /* Ireland */
+       CTRY_ISRAEL             = 376, /* Israel */
+       CTRY_ITALY              = 380, /* Italy */
+       CTRY_JAMAICA            = 388, /* Jamaica */
+       CTRY_JAPAN              = 392, /* Japan */
+       CTRY_JAPAN1             = 393, /* Japan (JP1) */
+       CTRY_JAPAN2             = 394, /* Japan (JP0) */
+       CTRY_JAPAN3             = 395, /* Japan (JP1-1) */
+       CTRY_JAPAN4             = 396, /* Japan (JE1) */
+       CTRY_JAPAN5             = 397, /* Japan (JE2) */
+       CTRY_JORDAN             = 400, /* Jordan */
+       CTRY_KAZAKHSTAN         = 398, /* Kazakhstan */
+       CTRY_KENYA              = 404, /* Kenya */
+       CTRY_KOREA_NORTH        = 408, /* North Korea */
+       CTRY_KOREA_ROC          = 410, /* South Korea */
+       CTRY_KOREA_ROC2         = 411, /* South Korea */
+       CTRY_KUWAIT             = 414, /* Kuwait */
+       CTRY_LATVIA             = 428, /* Latvia */
+       CTRY_LEBANON            = 422, /* Lebanon */
+       CTRY_LIBYA              = 434, /* Libya */
+       CTRY_LIECHTENSTEIN      = 438, /* Liechtenstein */
+       CTRY_LITHUANIA          = 440, /* Lithuania */
+       CTRY_LUXEMBOURG         = 442, /* Luxembourg */
+       CTRY_MACAU              = 446, /* Macau */
+       CTRY_MACEDONIA          = 807, /* Republic of Macedonia */
+       CTRY_MALAYSIA           = 458, /* Malaysia */
+       CTRY_MEXICO             = 484, /* Mexico */
+       CTRY_MONACO             = 492, /* Principality of Monaco */
+       CTRY_MOROCCO            = 504, /* Morocco */
+       CTRY_NETHERLANDS        = 528, /* Netherlands */
+       CTRY_NEW_ZEALAND        = 554, /* New Zealand */
+       CTRY_NICARAGUA          = 558, /* Nicaragua */
+       CTRY_NORWAY             = 578, /* Norway */
+       CTRY_OMAN               = 512, /* Oman */
+       CTRY_PAKISTAN           = 586, /* Islamic Republic of Pakistan */
+       CTRY_PANAMA             = 591, /* Panama */
+       CTRY_PARAGUAY           = 600, /* Paraguay */
+       CTRY_PERU               = 604, /* Peru */
+       CTRY_PHILIPPINES        = 608, /* Republic of the Philippines */
+       CTRY_POLAND             = 616, /* Poland */
+       CTRY_PORTUGAL           = 620, /* Portugal */
+       CTRY_PUERTO_RICO        = 630, /* Puerto Rico */
+       CTRY_QATAR              = 634, /* Qatar */
+       CTRY_ROMANIA            = 642, /* Romania */
+       CTRY_RUSSIA             = 643, /* Russia */
+       CTRY_SAUDI_ARABIA       = 682, /* Saudi Arabia */
+       CTRY_SINGAPORE          = 702, /* Singapore */
+       CTRY_SLOVAKIA           = 703, /* Slovak Republic */
+       CTRY_SLOVENIA           = 705, /* Slovenia */
+       CTRY_SOUTH_AFRICA       = 710, /* South Africa */
+       CTRY_SPAIN              = 724, /* Spain */
+       CTRY_SRI_LANKA          = 728, /* Sri Lanka */
+       CTRY_SWEDEN             = 752, /* Sweden */
+       CTRY_SWITZERLAND        = 756, /* Switzerland */
+       CTRY_SYRIA              = 760, /* Syria */
+       CTRY_TAIWAN             = 158, /* Taiwan */
+       CTRY_THAILAND           = 764, /* Thailand */
+       CTRY_TRINIDAD_Y_TOBAGO  = 780, /* Trinidad y Tobago */
+       CTRY_TUNISIA            = 788, /* Tunisia */
+       CTRY_TURKEY             = 792, /* Turkey */
+       CTRY_UAE                = 784, /* U.A.E. */
+       CTRY_UKRAINE            = 804, /* Ukraine */
+       CTRY_UNITED_KINGDOM     = 826, /* United Kingdom */
+       CTRY_UNITED_STATES      = 840, /* United States */
+       CTRY_URUGUAY            = 858, /* Uruguay */
+       CTRY_UZBEKISTAN         = 860, /* Uzbekistan */
+       CTRY_VENEZUELA          = 862, /* Venezuela */
+       CTRY_VIET_NAM           = 704, /* Viet Nam */
+       CTRY_YEMEN              = 887, /* Yemen */
+       CTRY_ZIMBABWE           = 716, /* Zimbabwe */
+};
+
+#define IEEE80211_CHANNELS_2GHZ_MIN    2412    /* 2GHz channel 1 */
+#define IEEE80211_CHANNELS_2GHZ_MAX    2732    /* 2GHz channel 26 */
+#define IEEE80211_CHANNELS_5GHZ_MIN    5005    /* 5GHz channel 1 */
+#define IEEE80211_CHANNELS_5GHZ_MAX    6100    /* 5GHz channel 220 */
+
+struct ath5k_regchannel {
+       u16 chan;
+       enum ath5k_regdom domain;
+       u32 mode;
+};
+
+#define IEEE80211_CHANNELS_2GHZ {                                      \
+/*2412*/ {   1, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2417*/ {   2, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2422*/ {   3, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2427*/ {   4, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2432*/ {   5, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2437*/ {   6, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2442*/ {   7, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2447*/ {   8, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2452*/ {   9, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2457*/ {  10, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2462*/ {  11, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2467*/ {  12, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2472*/ {  13, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM },                  \
+                                                                       \
+/*2432*/ {   5, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2437*/ {   6, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO },   \
+/*2442*/ {   7, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM },                 \
+                                                                       \
+/*2412*/ {   1, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2417*/ {   2, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2422*/ {   3, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2427*/ {   4, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2432*/ {   5, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2437*/ {   6, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO },   \
+/*2442*/ {   7, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2447*/ {   8, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2452*/ {   9, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2457*/ {  10, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2462*/ {  11, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2467*/ {  12, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2472*/ {  13, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM },                 \
+                                                                       \
+/*2412*/ {   1, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2417*/ {   2, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2422*/ {   3, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2427*/ {   4, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2432*/ {   5, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2437*/ {   6, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO },    \
+/*2442*/ {   7, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2447*/ {   8, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2452*/ {   9, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2457*/ {  10, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2462*/ {  11, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+                                                                       \
+/*2412*/ {   1, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2417*/ {   2, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2422*/ {   3, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2427*/ {   4, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2432*/ {   5, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2437*/ {   6, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2442*/ {   7, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2447*/ {   8, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2452*/ {   9, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2457*/ {  10, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2462*/ {  11, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2467*/ {  12, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2472*/ {  13, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM },                  \
+/*2484*/ {  14, DMN_MKKA, CHANNEL_CCK },                               \
+                                                                       \
+/*2412*/ {   1, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2417*/ {   2, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2422*/ {   3, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2427*/ {   4, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2432*/ {   5, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2437*/ {   6, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO },   \
+/*2442*/ {   7, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2447*/ {   8, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2452*/ {   9, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2457*/ {  10, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2462*/ {  11, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2467*/ {  12, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+/*2472*/ {  13, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM },                 \
+}
+
+#define IEEE80211_CHANNELS_5GHZ {                      \
+/*5745*/ { 149, DMN_APL1, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_APL1, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_APL1, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_APL1, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_APL1, CHANNEL_OFDM },              \
+                                                       \
+/*5745*/ { 149, DMN_APL2, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_APL2, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_APL2, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_APL2, CHANNEL_OFDM },              \
+                                                       \
+/*5280*/ {  56, DMN_APL3, CHANNEL_OFDM },              \
+/*5300*/ {  60, DMN_APL3, CHANNEL_OFDM },              \
+/*5320*/ {  64, DMN_APL3, CHANNEL_OFDM },              \
+/*5745*/ { 149, DMN_APL3, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_APL3, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_APL3, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_APL3, CHANNEL_OFDM },              \
+                                                       \
+/*5180*/ {  36, DMN_APL4, CHANNEL_OFDM },              \
+/*5200*/ {  40, DMN_APL4, CHANNEL_OFDM },              \
+/*5220*/ {  44, DMN_APL4, CHANNEL_OFDM },              \
+/*5240*/ {  48, DMN_APL4, CHANNEL_OFDM },              \
+/*5745*/ { 149, DMN_APL4, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_APL4, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_APL4, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_APL4, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_APL4, CHANNEL_OFDM },              \
+                                                       \
+/*5745*/ { 149, DMN_APL5, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_APL5, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_APL5, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_APL5, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_APL5, CHANNEL_OFDM },              \
+                                                       \
+/*5180*/ {  36, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5260*/ {  52, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5280*/ {  56, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5300*/ {  60, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5320*/ {  64, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5500*/ { 100, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5520*/ { 104, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5540*/ { 108, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5560*/ { 112, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5580*/ { 116, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5600*/ { 120, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5620*/ { 124, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5640*/ { 128, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5660*/ { 132, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5680*/ { 136, DMN_ETSI1, CHANNEL_OFDM },             \
+/*5700*/ { 140, DMN_ETSI1, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_ETSI2, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI2, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI2, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI2, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5260*/ {  52, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5280*/ {  56, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5300*/ {  60, DMN_ETSI3, CHANNEL_OFDM },             \
+/*5320*/ {  64, DMN_ETSI3, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5260*/ {  52, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5280*/ {  56, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5300*/ {  60, DMN_ETSI4, CHANNEL_OFDM },             \
+/*5320*/ {  64, DMN_ETSI4, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_ETSI5, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI5, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI5, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI5, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5260*/ {  52, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5280*/ {  56, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5500*/ { 100, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5520*/ { 104, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5540*/ { 108, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5560*/ { 112, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5580*/ { 116, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5600*/ { 120, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5620*/ { 124, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5640*/ { 128, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5660*/ { 132, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5680*/ { 136, DMN_ETSI6, CHANNEL_OFDM },             \
+/*5700*/ { 140, DMN_ETSI6, CHANNEL_OFDM },             \
+                                                       \
+/*5180*/ {  36, DMN_FCC1, CHANNEL_OFDM },              \
+/*5200*/ {  40, DMN_FCC1, CHANNEL_OFDM },              \
+/*5210*/ {  42, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5220*/ {  44, DMN_FCC1, CHANNEL_OFDM },              \
+/*5240*/ {  48, DMN_FCC1, CHANNEL_OFDM },              \
+/*5250*/ {  50, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5260*/ {  52, DMN_FCC1, CHANNEL_OFDM },              \
+/*5280*/ {  56, DMN_FCC1, CHANNEL_OFDM },              \
+/*5290*/ {  58, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5300*/ {  60, DMN_FCC1, CHANNEL_OFDM },              \
+/*5320*/ {  64, DMN_FCC1, CHANNEL_OFDM },              \
+/*5745*/ { 149, DMN_FCC1, CHANNEL_OFDM },              \
+/*5760*/ { 152, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5765*/ { 153, DMN_FCC1, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_FCC1, CHANNEL_OFDM },              \
+/*5800*/ { 160, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5805*/ { 161, DMN_FCC1, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_FCC1, CHANNEL_OFDM },              \
+                                                       \
+/*5180*/ {  36, DMN_FCC2, CHANNEL_OFDM },              \
+/*5200*/ {  40, DMN_FCC2, CHANNEL_OFDM },              \
+/*5220*/ {  44, DMN_FCC2, CHANNEL_OFDM },              \
+/*5240*/ {  48, DMN_FCC2, CHANNEL_OFDM },              \
+/*5260*/ {  52, DMN_FCC2, CHANNEL_OFDM },              \
+/*5280*/ {  56, DMN_FCC2, CHANNEL_OFDM },              \
+/*5300*/ {  60, DMN_FCC2, CHANNEL_OFDM },              \
+/*5320*/ {  64, DMN_FCC2, CHANNEL_OFDM },              \
+/*5745*/ { 149, DMN_FCC2, CHANNEL_OFDM },              \
+/*5765*/ { 153, DMN_FCC2, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_FCC2, CHANNEL_OFDM },              \
+/*5805*/ { 161, DMN_FCC2, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_FCC2, CHANNEL_OFDM },              \
+                                                       \
+/*5180*/ {  36, DMN_FCC3, CHANNEL_OFDM },              \
+/*5200*/ {  40, DMN_FCC3, CHANNEL_OFDM },              \
+/*5210*/ {  42, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5220*/ {  44, DMN_FCC3, CHANNEL_OFDM },              \
+/*5240*/ {  48, DMN_FCC3, CHANNEL_OFDM },              \
+/*5250*/ {  50, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5260*/ {  52, DMN_FCC3, CHANNEL_OFDM },              \
+/*5280*/ {  56, DMN_FCC3, CHANNEL_OFDM },              \
+/*5290*/ {  58, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5300*/ {  60, DMN_FCC3, CHANNEL_OFDM },              \
+/*5320*/ {  64, DMN_FCC3, CHANNEL_OFDM },              \
+/*5500*/ { 100, DMN_FCC3, CHANNEL_OFDM },              \
+/*5520*/ { 104, DMN_FCC3, CHANNEL_OFDM },              \
+/*5540*/ { 108, DMN_FCC3, CHANNEL_OFDM },              \
+/*5560*/ { 112, DMN_FCC3, CHANNEL_OFDM },              \
+/*5580*/ { 116, DMN_FCC3, CHANNEL_OFDM },              \
+/*5600*/ { 120, DMN_FCC3, CHANNEL_OFDM },              \
+/*5620*/ { 124, DMN_FCC3, CHANNEL_OFDM },              \
+/*5640*/ { 128, DMN_FCC3, CHANNEL_OFDM },              \
+/*5660*/ { 132, DMN_FCC3, CHANNEL_OFDM },              \
+/*5680*/ { 136, DMN_FCC3, CHANNEL_OFDM },              \
+/*5700*/ { 140, DMN_FCC3, CHANNEL_OFDM },              \
+/*5745*/ { 149, DMN_FCC3, CHANNEL_OFDM },              \
+/*5760*/ { 152, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5765*/ { 153, DMN_FCC3, CHANNEL_OFDM },              \
+/*5785*/ { 157, DMN_FCC3, CHANNEL_OFDM },              \
+/*5800*/ { 160, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO },        \
+/*5805*/ { 161, DMN_FCC3, CHANNEL_OFDM },              \
+/*5825*/ { 165, DMN_FCC3, CHANNEL_OFDM },              \
+                                                       \
+/*5170*/ {  34, DMN_MKK1, CHANNEL_OFDM },              \
+/*5190*/ {  38, DMN_MKK1, CHANNEL_OFDM },              \
+/*5210*/ {  42, DMN_MKK1, CHANNEL_OFDM },              \
+/*5230*/ {  46, DMN_MKK1, CHANNEL_OFDM },              \
+                                                       \
+/*5040*/ {   8, DMN_MKK2, CHANNEL_OFDM },              \
+/*5060*/ {  12, DMN_MKK2, CHANNEL_OFDM },              \
+/*5080*/ {  16, DMN_MKK2, CHANNEL_OFDM },              \
+/*5170*/ {  34, DMN_MKK2, CHANNEL_OFDM },              \
+/*5190*/ {  38, DMN_MKK2, CHANNEL_OFDM },              \
+/*5210*/ {  42, DMN_MKK2, CHANNEL_OFDM },              \
+/*5230*/ {  46, DMN_MKK2, CHANNEL_OFDM },              \
+                                                       \
+/*5180*/ {  36, DMN_WORLD, CHANNEL_OFDM },             \
+/*5200*/ {  40, DMN_WORLD, CHANNEL_OFDM },             \
+/*5220*/ {  44, DMN_WORLD, CHANNEL_OFDM },             \
+/*5240*/ {  48, DMN_WORLD, CHANNEL_OFDM },             \
+}
+
+enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom, u16);
+u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee);
+enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain);
+
+#endif
index 059ce3f07dba1bafe91eccaf4a68a9be26f367eb..63ec7a70ee7658aeb282797b7b0f8940611ede2f 100644 (file)
@@ -1759,9 +1759,8 @@ static int atmel_set_encode(struct net_device *dev,
                        priv->default_key = index;
                } else
                        /* Don't complain if only change the mode */
-                       if (!dwrq->flags & IW_ENCODE_MODE) {
+                       if (!(dwrq->flags & IW_ENCODE_MODE))
                                return -EINVAL;
-                       }
        }
        /* Read the flags */
        if (dwrq->flags & IW_ENCODE_DISABLED) {
@@ -2676,9 +2675,9 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 }
 
 struct auth_body {
-       u16 alg;
-       u16 trans_seq;
-       u16 status;
+       __le16 alg;
+       __le16 trans_seq;
+       __le16 status;
        u8 el_id;
        u8 chall_text_len;
        u8 chall_text[253];
@@ -2713,9 +2712,9 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid)
                u8 SSID[MAX_SSID_LENGTH];
                u8 scan_type;
                u8 channel;
-               u16 BSS_type;
-               u16 min_channel_time;
-               u16 max_channel_time;
+               __le16 BSS_type;
+               __le16 min_channel_time;
+               __le16 max_channel_time;
                u8 options;
                u8 SSID_size;
        } cmd;
@@ -2758,7 +2757,7 @@ static void join(struct atmel_private *priv, int type)
                u8 SSID[MAX_SSID_LENGTH];
                u8 BSS_type; /* this is a short in a scan command - weird */
                u8 channel;
-               u16 timeout;
+               __le16 timeout;
                u8 SSID_size;
                u8 reserved;
        } cmd;
@@ -2863,8 +2862,8 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc)
        int bodysize;
        struct ieee80211_hdr_4addr header;
        struct ass_req_format {
-               u16 capability;
-               u16 listen_interval;
+               __le16 capability;
+               __le16 listen_interval;
                u8 ap[6]; /* nothing after here directly accessible */
                u8 ssid_el_id;
                u8 ssid_len;
@@ -3085,9 +3084,9 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
 {
        struct ass_resp_format {
-               u16 capability;
-               u16 status;
-               u16 ass_id;
+               __le16 capability;
+               __le16 status;
+               __le16 ass_id;
                u8 el_id;
                u8 length;
                u8 rates[4];
@@ -3294,9 +3293,9 @@ static void atmel_management_frame(struct atmel_private *priv,
                   never let an engineer loose with a data structure design. */
                {
                        struct beacon_format {
-                               u64 timestamp;
-                               u16 interval;
-                               u16 capability;
+                               __le64 timestamp;
+                               __le16 interval;
+                               __le16 capability;
                                u8 ssid_el_id;
                                u8 ssid_length;
                                /* ssid here */
index fdbc351ac333fa8fe61a2134f4e30f221084274b..1a2141dabdc7a533cb9382773b674ddbe7a270bd 100644 (file)
@@ -61,6 +61,16 @@ config B43_PCMCIA
 
          If unsure, say N.
 
+config B43_NPHY
+       bool "Pre IEEE 802.11n support (BROKEN)"
+       depends on B43 && EXPERIMENTAL && BROKEN
+       ---help---
+         Support for the IEEE 802.11n draft.
+
+         THIS IS BROKEN AND DOES NOT WORK YET.
+
+         SAY N.
+
 # This config option automatically enables b43 LEDS support,
 # if it's possible.
 config B43_LEDS
@@ -83,51 +93,3 @@ config B43_DEBUG
 
          Say Y, if you want to find out why the driver does not
          work for you.
-
-config B43_DMA
-       bool
-       depends on B43
-config B43_PIO
-       bool
-       depends on B43
-
-choice
-       prompt "Broadcom 43xx data transfer mode"
-       depends on B43
-       default B43_DMA_AND_PIO_MODE
-
-config B43_DMA_AND_PIO_MODE
-       bool "DMA + PIO"
-       select B43_DMA
-       select B43_PIO
-       ---help---
-         Include both, Direct Memory Access (DMA) and Programmed I/O (PIO)
-         data transfer modes.
-         The actually used mode is selectable through the module
-         parameter "pio". If the module parameter is pio=0, DMA is used.
-         Otherwise PIO is used. DMA is default.
-
-         If unsure, choose this option.
-
-config B43_DMA_MODE
-       bool "DMA (Direct Memory Access) only"
-       select B43_DMA
-       ---help---
-         Only include Direct Memory Access (DMA).
-         This reduces the size of the driver module, by omitting the PIO code.
-
-config B43_PIO_MODE
-       bool "PIO (Programmed I/O) only"
-       select B43_PIO
-       ---help---
-         Only include Programmed I/O (PIO).
-         This reduces the size of the driver module, by omitting the DMA code.
-         Please note that PIO transfers are slow (compared to DMA).
-
-         Also note that not all devices of the 43xx series support PIO.
-         The 4306 (Apple Airport Extreme and others) supports PIO, while
-         the 4318 is known to _not_ support PIO.
-
-         Only use PIO, if DMA does not work for you.
-
-endchoice
index 485e59e2dfabc2c5104fbb61f7cddd19481b743b..ac1329dba04581317c306791c1b5b465dd0a2dba 100644 (file)
@@ -1,20 +1,16 @@
-# b43 core
 b43-y                          += main.o
 b43-y                          += tables.o
+b43-y                          += tables_nphy.o
 b43-y                          += phy.o
+b43-y                          += nphy.o
 b43-y                          += sysfs.o
 b43-y                          += xmit.o
 b43-y                          += lo.o
-# b43 RFKILL button support
+b43-y                          += wa.o
+b43-y                          += dma.o
 b43-$(CONFIG_B43_RFKILL)       += rfkill.o
-# b43 LED support
 b43-$(CONFIG_B43_LEDS)         += leds.o
-# b43 PCMCIA support
 b43-$(CONFIG_B43_PCMCIA)       += pcmcia.o
-# b43 debugging
 b43-$(CONFIG_B43_DEBUG)                += debugfs.o
-# b43 DMA and PIO
-b43-$(CONFIG_B43_DMA)          += dma.o
-b43-$(CONFIG_B43_PIO)          += pio.o
 
 obj-$(CONFIG_B43)              += b43.o
index 7b6fc1ab2b904fc607273d8d67946d159107d871..32a24f5c4fa61c5a0ce26364a79a032487e4435d 100644 (file)
@@ -35,8 +35,8 @@
 #define B43_MMIO_DMA4_IRQ_MASK         0x44
 #define B43_MMIO_DMA5_REASON           0x48
 #define B43_MMIO_DMA5_IRQ_MASK         0x4C
-#define B43_MMIO_MACCTL                        0x120
-#define B43_MMIO_STATUS2_BITFIELD      0x124
+#define B43_MMIO_MACCTL                        0x120   /* MAC control */
+#define B43_MMIO_MACCMD                        0x124   /* MAC command */
 #define B43_MMIO_GEN_IRQ_REASON                0x128
 #define B43_MMIO_GEN_IRQ_MASK          0x12C
 #define B43_MMIO_RAM_CONTROL           0x130
@@ -50,6 +50,9 @@
 #define B43_MMIO_XMITSTAT_1            0x174
 #define B43_MMIO_REV3PLUS_TSF_LOW      0x180   /* core rev >= 3 only */
 #define B43_MMIO_REV3PLUS_TSF_HIGH     0x184   /* core rev >= 3 only */
+#define B43_MMIO_TSF_CFP_REP           0x188
+#define B43_MMIO_TSF_CFP_START         0x18C
+#define B43_MMIO_TSF_CFP_MAXDUR                0x190
 
 /* 32-bit DMA */
 #define B43_MMIO_DMA32_BASE0           0x200
 #define B43_MMIO_DMA64_BASE3           0x2C0
 #define B43_MMIO_DMA64_BASE4           0x300
 #define B43_MMIO_DMA64_BASE5           0x340
-/* PIO */
-#define B43_MMIO_PIO1_BASE             0x300
-#define B43_MMIO_PIO2_BASE             0x310
-#define B43_MMIO_PIO3_BASE             0x320
-#define B43_MMIO_PIO4_BASE             0x330
 
 #define B43_MMIO_PHY_VER               0x3E0
 #define B43_MMIO_PHY_RADIO             0x3E2
@@ -88,6 +86,8 @@
 #define B43_MMIO_RADIO_HWENABLED_LO    0x49A
 #define B43_MMIO_GPIO_CONTROL          0x49C
 #define B43_MMIO_GPIO_MASK             0x49E
+#define B43_MMIO_TSF_CFP_START_LOW     0x604
+#define B43_MMIO_TSF_CFP_START_HIGH    0x606
 #define B43_MMIO_TSF_0                 0x632   /* core rev < 3 only */
 #define B43_MMIO_TSF_1                 0x634   /* core rev < 3 only */
 #define B43_MMIO_TSF_2                 0x636   /* core rev < 3 only */
@@ -170,14 +170,17 @@ enum {
 #define B43_SHM_SH_SLOTT               0x0010  /* Slot time */
 #define B43_SHM_SH_DTIMPER             0x0012  /* DTIM period */
 #define B43_SHM_SH_NOSLPZNATDTIM       0x004C  /* NOSLPZNAT DTIM */
-/* SHM_SHARED beacon variables */
+/* SHM_SHARED beacon/AP variables */
 #define B43_SHM_SH_BTL0                        0x0018  /* Beacon template length 0 */
 #define B43_SHM_SH_BTL1                        0x001A  /* Beacon template length 1 */
 #define B43_SHM_SH_BTSFOFF             0x001C  /* Beacon TSF offset */
 #define B43_SHM_SH_TIMBPOS             0x001E  /* TIM B position in beacon */
+#define B43_SHM_SH_DTIMP               0x0012  /* DTIP period */
+#define B43_SHM_SH_MCASTCOOKIE         0x00A8  /* Last bcast/mcast frame ID */
 #define B43_SHM_SH_SFFBLIM             0x0044  /* Short frame fallback retry limit */
 #define B43_SHM_SH_LFFBLIM             0x0046  /* Long frame fallback retry limit */
 #define B43_SHM_SH_BEACPHYCTL          0x0054  /* Beacon PHY TX control word (see PHY TX control) */
+#define B43_SHM_SH_EXTNPHYCTL          0x00B0  /* Extended bytes for beacon PHY control (N) */
 /* SHM_SHARED ACK/CTS control */
 #define B43_SHM_SH_ACKCTSPHYCTL                0x0022  /* ACK/CTS PHY control word (see PHY TX control) */
 /* SHM_SHARED probe response variables */
@@ -321,17 +324,29 @@ enum {
 #define B43_MACCTL_DISCPMQ             0x40000000      /* Discard Power Management Queue */
 #define B43_MACCTL_GMODE               0x80000000      /* G Mode */
 
-/* 802.11 core specific TM State Low flags */
+/* MAC Command bitfield */
+#define B43_MACCMD_BEACON0_VALID       0x00000001      /* Beacon 0 in template RAM is busy/valid */
+#define B43_MACCMD_BEACON1_VALID       0x00000002      /* Beacon 1 in template RAM is busy/valid */
+#define B43_MACCMD_DFQ_VALID           0x00000004      /* Directed frame queue valid (IBSS PS mode, ATIM) */
+#define B43_MACCMD_CCA                 0x00000008      /* Clear channel assessment */
+#define B43_MACCMD_BGNOISE             0x00000010      /* Background noise */
+
+/* 802.11 core specific TM State Low (SSB_TMSLOW) flags */
 #define B43_TMSLOW_GMODE               0x20000000      /* G Mode Enable */
-#define B43_TMSLOW_PLLREFSEL           0x00200000      /* PLL Frequency Reference Select */
+#define B43_TMSLOW_PHYCLKSPEED         0x00C00000      /* PHY clock speed mask (N-PHY only) */
+#define  B43_TMSLOW_PHYCLKSPEED_40MHZ  0x00000000      /* 40 MHz PHY */
+#define  B43_TMSLOW_PHYCLKSPEED_80MHZ  0x00400000      /* 80 MHz PHY */
+#define  B43_TMSLOW_PHYCLKSPEED_160MHZ 0x00800000      /* 160 MHz PHY */
+#define B43_TMSLOW_PLLREFSEL           0x00200000      /* PLL Frequency Reference Select (rev >= 5) */
 #define B43_TMSLOW_MACPHYCLKEN         0x00100000      /* MAC PHY Clock Control Enable (rev >= 5) */
 #define B43_TMSLOW_PHYRESET            0x00080000      /* PHY Reset */
 #define B43_TMSLOW_PHYCLKEN            0x00040000      /* PHY Clock Enable */
 
-/* 802.11 core specific TM State High flags */
+/* 802.11 core specific TM State High (SSB_TMSHIGH) flags */
+#define B43_TMSHIGH_DUALBAND_PHY       0x00080000      /* Dualband PHY available */
 #define B43_TMSHIGH_FCLOCK             0x00040000      /* Fast Clock Available (rev >= 5) */
-#define B43_TMSHIGH_APHY               0x00020000      /* A-PHY available (rev >= 5) */
-#define B43_TMSHIGH_GPHY               0x00010000      /* G-PHY available (rev >= 5) */
+#define B43_TMSHIGH_HAVE_5GHZ_PHY      0x00020000      /* 5 GHz PHY available (rev >= 5) */
+#define B43_TMSHIGH_HAVE_2GHZ_PHY      0x00010000      /* 2.4 GHz PHY available (rev >= 5) */
 
 /* Generic-Interrupt reasons. */
 #define B43_IRQ_MAC_SUSPENDED          0x00000001
@@ -393,6 +408,8 @@ enum {
 #define B43_DEFAULT_SHORT_RETRY_LIMIT  7
 #define B43_DEFAULT_LONG_RETRY_LIMIT   4
 
+#define B43_PHY_TX_BADNESS_LIMIT       1000
+
 /* Max size of a security key */
 #define B43_SEC_KEYSIZE                        16
 /* Security algorithms. */
@@ -462,7 +479,6 @@ struct b43_phy {
        u16 radio_ver;          /* Radio version */
        u8 radio_rev;           /* Radio revision */
 
-       bool locked;            /* Only used in b43_phy_{un}lock() */
        bool dyn_tssi_tbl;      /* tssi2dbm is kmalloc()ed. */
 
        /* ACI (adjacent channel interference) flags. */
@@ -499,11 +515,6 @@ struct b43_phy {
        s16 lna_gain;           /* LNA */
        s16 pga_gain;           /* PGA */
 
-       /* PHY lock for core.rev < 3
-        * This lock is only used by b43_phy_{un}lock()
-        */
-       spinlock_t lock;
-
        /* Desired TX power level (in dBm).
         * This is set by the user and adjusted in b43_phy_xmitpower(). */
        u8 power_level;
@@ -514,9 +525,7 @@ struct b43_phy {
        struct b43_bbatt bbatt;
        struct b43_rfatt rfatt;
        u8 tx_control;          /* B43_TXCTL_XXX */
-#ifdef CONFIG_B43_DEBUG
-       bool manual_txpower_control;    /* Manual TX-power control enabled? */
-#endif
+
        /* Hardware Power Control enabled? */
        bool hardware_power_control;
 
@@ -544,6 +553,26 @@ struct b43_phy {
        u16 lofcal;
 
        u16 initval;            //FIXME rename?
+
+       /* PHY TX errors counter. */
+       atomic_t txerr_cnt;
+
+       /* The device does address auto increment for the OFDM tables.
+        * We cache the previously used address here and omit the address
+        * write on the next table access, if possible. */
+       u16 ofdmtab_addr; /* The address currently set in hardware. */
+       enum { /* The last data flow direction. */
+               B43_OFDMTAB_DIRECTION_UNKNOWN = 0,
+               B43_OFDMTAB_DIRECTION_READ,
+               B43_OFDMTAB_DIRECTION_WRITE,
+       } ofdmtab_addr_direction;
+
+#if B43_DEBUG
+       /* Manual TX-power control enabled? */
+       bool manual_txpower_control;
+       /* PHY registers locked by b43_phy_lock()? */
+       bool phy_locked;
+#endif /* B43_DEBUG */
 };
 
 /* Data structures for DMA transmission, per 80211 core. */
@@ -559,14 +588,6 @@ struct b43_dma {
        struct b43_dmaring *rx_ring3;   /* only available on core.rev < 5 */
 };
 
-/* Data structures for PIO transmission, per 80211 core. */
-struct b43_pio {
-       struct b43_pioqueue *queue0;
-       struct b43_pioqueue *queue1;
-       struct b43_pioqueue *queue2;
-       struct b43_pioqueue *queue3;
-};
-
 /* Context information for a noise calculation (Link Quality). */
 struct b43_noise_calculation {
        u8 channel_at_start;
@@ -599,18 +620,18 @@ struct b43_wl {
        /* Pointer to the ieee80211 hardware data structure */
        struct ieee80211_hw *hw;
 
-       spinlock_t irq_lock;
        struct mutex mutex;
+       spinlock_t irq_lock;
+       /* Lock for LEDs access. */
        spinlock_t leds_lock;
+       /* Lock for SHM access. */
+       spinlock_t shm_lock;
 
        /* We can only have one operating interface (802.11 core)
         * at a time. General information about this interface follows.
         */
 
-       /* Opaque ID of the operating interface from the ieee80211
-        * subsystem. Do not modify.
-        */
-       int if_id;
+       struct ieee80211_vif *vif;
        /* The MAC address of the operating interface. */
        u8 mac_addr[ETH_ALEN];
        /* Current BSSID */
@@ -634,18 +655,33 @@ struct b43_wl {
        /* List of all wireless devices on this chip */
        struct list_head devlist;
        u8 nr_devs;
+
+       bool radiotap_enabled;
+
+       /* The beacon we are currently using (AP or IBSS mode).
+        * This beacon stuff is protected by the irq_lock. */
+       struct sk_buff *current_beacon;
+       bool beacon0_uploaded;
+       bool beacon1_uploaded;
+};
+
+/* In-memory representation of a cached microcode file. */
+struct b43_firmware_file {
+       const char *filename;
+       const struct firmware *data;
 };
 
 /* Pointers to the firmware data and meta information about it. */
 struct b43_firmware {
        /* Microcode */
-       const struct firmware *ucode;
+       struct b43_firmware_file ucode;
        /* PCM code */
-       const struct firmware *pcm;
+       struct b43_firmware_file pcm;
        /* Initial MMIO values for the firmware */
-       const struct firmware *initvals;
+       struct b43_firmware_file initvals;
        /* Initial MMIO values for the firmware, band-specific */
-       const struct firmware *initvals_band;
+       struct b43_firmware_file initvals_band;
+
        /* Firmware revision */
        u16 rev;
        /* Firmware patchlevel */
@@ -683,21 +719,17 @@ struct b43_wldev {
        /* Saved init status for handling suspend. */
        int suspend_init_status;
 
-       bool __using_pio;       /* Internal, use b43_using_pio(). */
        bool bad_frames_preempt;        /* Use "Bad Frames Preemption" (default off) */
-       bool reg124_set_0x4;    /* Some variable to keep track of IRQ stuff. */
+       bool dfq_valid;         /* Directed frame queue valid (IBSS PS mode, ATIM) */
        bool short_preamble;    /* TRUE, if short preamble is enabled. */
        bool short_slot;        /* TRUE, if short slot timing is enabled. */
        bool radio_hw_enable;   /* saved state of radio hardware enabled state */
 
        /* PHY/Radio device. */
        struct b43_phy phy;
-       union {
-               /* DMA engines. */
-               struct b43_dma dma;
-               /* PIO engines. */
-               struct b43_pio pio;
-       };
+
+       /* DMA engines. */
+       struct b43_dma dma;
 
        /* Various statistics about the physical device. */
        struct b43_stats stats;
@@ -732,9 +764,6 @@ struct b43_wldev {
        u8 max_nr_keys;
        struct b43_key key[58];
 
-       /* Cached beacon template while uploading the template. */
-       struct sk_buff *cached_beacon;
-
        /* Firmware data */
        struct b43_firmware fw;
 
@@ -752,28 +781,6 @@ static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
        return hw->priv;
 }
 
-/* Helper function, which returns a boolean.
- * TRUE, if PIO is used; FALSE, if DMA is used.
- */
-#if defined(CONFIG_B43_DMA) && defined(CONFIG_B43_PIO)
-static inline int b43_using_pio(struct b43_wldev *dev)
-{
-       return dev->__using_pio;
-}
-#elif defined(CONFIG_B43_DMA)
-static inline int b43_using_pio(struct b43_wldev *dev)
-{
-       return 0;
-}
-#elif defined(CONFIG_B43_PIO)
-static inline int b43_using_pio(struct b43_wldev *dev)
-{
-       return 1;
-}
-#else
-# error "Using neither DMA nor PIO? Confused..."
-#endif
-
 static inline struct b43_wldev *dev_to_b43_wldev(struct device *dev)
 {
        struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
index ef0075d9f9cb81b323425baf56b18fd5523ac067..e38ed0fe72e9c3978bdf1499d6c299c07e84854d 100644 (file)
@@ -34,7 +34,6 @@
 #include "main.h"
 #include "debugfs.h"
 #include "dma.h"
-#include "pio.h"
 #include "xmit.h"
 
 
@@ -223,8 +222,6 @@ out:
 static int txpower_g_write_file(struct b43_wldev *dev,
                                const char *buf, size_t count)
 {
-       unsigned long phy_flags;
-
        if (dev->phy.type != B43_PHYTYPE_G)
                return -ENODEV;
        if ((count >= 4) && (memcmp(buf, "auto", 4) == 0)) {
@@ -248,12 +245,12 @@ static int txpower_g_write_file(struct b43_wldev *dev,
                        dev->phy.tx_control |= B43_TXCTL_PA2DB;
                if (pa3db)
                        dev->phy.tx_control |= B43_TXCTL_PA3DB;
-               b43_phy_lock(dev, phy_flags);
+               b43_phy_lock(dev);
                b43_radio_lock(dev);
                b43_set_txpower_g(dev, &dev->phy.bbatt,
                                  &dev->phy.rfatt, dev->phy.tx_control);
                b43_radio_unlock(dev);
-               b43_phy_unlock(dev, phy_flags);
+               b43_phy_unlock(dev);
        }
 
        return 0;
@@ -352,7 +349,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
        struct b43_wldev *dev;
        struct b43_debugfs_fops *dfops;
        struct b43_dfs_file *dfile;
-       ssize_t ret;
+       ssize_t uninitialized_var(ret);
        char *buf;
        const size_t bufsize = 1024 * 128;
        const size_t buforder = get_order(bufsize);
index 5e8f8ac0f1dda1f2b38f26f13145fef370a95b00..3e73d2a523aa98563ada01db749da1ccaaa7b5a5 100644 (file)
@@ -37,6 +37,8 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+
 
 /* 32bit DMA ops. */
 static
@@ -165,7 +167,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
        addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
        addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
            >> SSB_DMA_TRANSLATION_SHIFT;
-       addrhi |= ssb_dma_translation(ring->dev->dev);
+       addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
        if (slot == ring->nr_slots - 1)
                ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
        if (start)
@@ -315,26 +317,24 @@ static struct b43_dmaring *priority_to_txring(struct b43_wldev *dev,
        case 3:
                ring = dev->dma.tx_ring0;
                break;
-       case 4:
-               ring = dev->dma.tx_ring4;
-               break;
-       case 5:
-               ring = dev->dma.tx_ring5;
-               break;
        }
 
        return ring;
 }
 
-/* Bcm43xx-ring to mac80211-queue mapping */
+/* b43-ring to mac80211-queue mapping */
 static inline int txring_to_priority(struct b43_dmaring *ring)
 {
-       static const u8 idx_to_prio[] = { 3, 2, 1, 0, 4, 5, };
+       static const u8 idx_to_prio[] = { 3, 2, 1, 0, };
+       unsigned int index;
 
 /*FIXME: have only one queue, for now */
        return 0;
 
-       return idx_to_prio[ring->index];
+       index = ring->index;
+       if (B43_WARN_ON(index >= ARRAY_SIZE(idx_to_prio)))
+               index = 0;
+       return idx_to_prio[index];
 }
 
 u16 b43_dmacontroller_base(int dma64bit, int controller_idx)
@@ -426,9 +426,21 @@ static inline
 static int alloc_ringmemory(struct b43_dmaring *ring)
 {
        struct device *dev = ring->dev->dev->dev;
-
+       gfp_t flags = GFP_KERNEL;
+
+       /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
+        * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing
+        * has shown that 4K is sufficient for the latter as long as the buffer
+        * does not cross an 8K boundary.
+        *
+        * For unknown reasons - possibly a hardware error - the BCM4311 rev
+        * 02, which uses 64-bit DMA, needs the ring buffer in very low memory,
+        * which accounts for the GFP_DMA flag below.
+        */
+       if (ring->dma64)
+               flags |= GFP_DMA;
        ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
-                                           &(ring->dmabase), GFP_KERNEL);
+                                           &(ring->dmabase), flags);
        if (!ring->descbase) {
                b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
                return -ENOMEM;
@@ -483,7 +495,7 @@ int b43_dmacontroller_rx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
        return 0;
 }
 
-/* Reset the RX DMA channel */
+/* Reset the TX DMA channel */
 int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64)
 {
        int i;
@@ -647,7 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA64_TXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | trans);
+                                     | (trans << 1));
                } else {
                        u32 ringbase = (u32) (ring->dmabase);
 
@@ -680,8 +692,9 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA64_RXRINGHI,
                                      ((ringbase >> 32) &
                                       ~SSB_DMA_TRANSLATION_MASK)
-                                     | trans);
-                       b43_dma_write(ring, B43_DMA64_RXINDEX, 200);
+                                     | (trans << 1));
+                       b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots *
+                                     sizeof(struct b43_dmadesc64));
                } else {
                        u32 ringbase = (u32) (ring->dmabase);
 
@@ -695,11 +708,12 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
                        b43_dma_write(ring, B43_DMA32_RXRING,
                                      (ringbase & ~SSB_DMA_TRANSLATION_MASK)
                                      | trans);
-                       b43_dma_write(ring, B43_DMA32_RXINDEX, 200);
+                       b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots *
+                                     sizeof(struct b43_dmadesc32));
                }
        }
 
-      out:
+out:
        return err;
 }
 
@@ -793,7 +807,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                goto err_kfree_ring;
        if (for_tx) {
                ring->txhdr_cache = kcalloc(nr_slots,
-                                           sizeof(struct b43_txhdr_fw4),
+                                           b43_txhdr_size(dev),
                                            GFP_KERNEL);
                if (!ring->txhdr_cache)
                        goto err_kfree_meta;
@@ -801,22 +815,21 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                /* test for ability to dma to txhdr_cache */
                dma_test = dma_map_single(dev->dev->dev,
                                          ring->txhdr_cache,
-                                         sizeof(struct b43_txhdr_fw4),
+                                         b43_txhdr_size(dev),
                                          DMA_TO_DEVICE);
 
                if (dma_mapping_error(dma_test)) {
                        /* ugh realloc */
                        kfree(ring->txhdr_cache);
                        ring->txhdr_cache = kcalloc(nr_slots,
-                                                   sizeof(struct
-                                                          b43_txhdr_fw4),
+                                                   b43_txhdr_size(dev),
                                                    GFP_KERNEL | GFP_DMA);
                        if (!ring->txhdr_cache)
                                goto err_kfree_meta;
 
                        dma_test = dma_map_single(dev->dev->dev,
                                                  ring->txhdr_cache,
-                                                 sizeof(struct b43_txhdr_fw4),
+                                                 b43_txhdr_size(dev),
                                                  DMA_TO_DEVICE);
 
                        if (dma_mapping_error(dma_test))
@@ -824,7 +837,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                }
 
                dma_unmap_single(dev->dev->dev,
-                                dma_test, sizeof(struct b43_txhdr_fw4),
+                                dma_test, b43_txhdr_size(dev),
                                 DMA_TO_DEVICE);
        }
 
@@ -901,11 +914,7 @@ static void b43_destroy_dmaring(struct b43_dmaring *ring)
 
 void b43_dma_free(struct b43_wldev *dev)
 {
-       struct b43_dma *dma;
-
-       if (b43_using_pio(dev))
-               return;
-       dma = &dev->dma;
+       struct b43_dma *dma = &dev->dma;
 
        b43_destroy_dmaring(dma->rx_ring3);
        dma->rx_ring3 = NULL;
@@ -940,16 +949,11 @@ int b43_dma_init(struct b43_wldev *dev)
 
        err = ssb_dma_set_mask(dev->dev, dmamask);
        if (err) {
-#ifdef B43_PIO
-               b43warn(dev->wl, "DMA for this device not supported. "
-                       "Falling back to PIO\n");
-               dev->__using_pio = 1;
-               return -EAGAIN;
-#else
-               b43err(dev->wl, "DMA for this device not supported and "
-                      "no PIO support compiled in\n");
+               b43err(dev->wl, "The machine/kernel does not support "
+                      "the required DMA mask (0x%08X%08X)\n",
+                      (unsigned int)((dmamask & 0xFFFFFFFF00000000ULL) >> 32),
+                      (unsigned int)(dmamask & 0x00000000FFFFFFFFULL));
                return -EOPNOTSUPP;
-#endif
        }
 
        err = -ENOMEM;
@@ -1038,26 +1042,30 @@ static u16 generate_cookie(struct b43_dmaring *ring, int slot)
         * in the lower 12 bits.
         * Note that the cookie must never be 0, as this
         * is a special value used in RX path.
+        * It can also not be 0xFFFF because that is special
+        * for multicast frames.
         */
        switch (ring->index) {
        case 0:
-               cookie = 0xA000;
+               cookie = 0x1000;
                break;
        case 1:
-               cookie = 0xB000;
+               cookie = 0x2000;
                break;
        case 2:
-               cookie = 0xC000;
+               cookie = 0x3000;
                break;
        case 3:
-               cookie = 0xD000;
+               cookie = 0x4000;
                break;
        case 4:
-               cookie = 0xE000;
+               cookie = 0x5000;
                break;
        case 5:
-               cookie = 0xF000;
+               cookie = 0x6000;
                break;
+       default:
+               B43_WARN_ON(1);
        }
        B43_WARN_ON(slot & ~0x0FFF);
        cookie |= (u16) slot;
@@ -1073,22 +1081,22 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
        struct b43_dmaring *ring = NULL;
 
        switch (cookie & 0xF000) {
-       case 0xA000:
+       case 0x1000:
                ring = dma->tx_ring0;
                break;
-       case 0xB000:
+       case 0x2000:
                ring = dma->tx_ring1;
                break;
-       case 0xC000:
+       case 0x3000:
                ring = dma->tx_ring2;
                break;
-       case 0xD000:
+       case 0x4000:
                ring = dma->tx_ring3;
                break;
-       case 0xE000:
+       case 0x5000:
                ring = dma->tx_ring4;
                break;
-       case 0xF000:
+       case 0x6000:
                ring = dma->tx_ring5;
                break;
        default:
@@ -1112,6 +1120,8 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        struct b43_dmadesc_meta *meta;
        struct b43_dmadesc_meta *meta_hdr;
        struct sk_buff *bounce_skb;
+       u16 cookie;
+       size_t hdrsize = b43_txhdr_size(ring->dev);
 
 #define SLOTS_PER_PACKET  2
        B43_WARN_ON(skb_shinfo(skb)->nr_frags);
@@ -1121,17 +1131,17 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
        desc = ops->idx2desc(ring, slot, &meta_hdr);
        memset(meta_hdr, 0, sizeof(*meta_hdr));
 
-       header = &(ring->txhdr_cache[slot * sizeof(struct b43_txhdr_fw4)]);
+       header = &(ring->txhdr_cache[slot * hdrsize]);
+       cookie = generate_cookie(ring, slot);
        b43_generate_txhdr(ring->dev, header,
-                          skb->data, skb->len, ctl,
-                          generate_cookie(ring, slot));
+                          skb->data, skb->len, ctl, cookie);
 
        meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
-                                          sizeof(struct b43_txhdr_fw4), 1);
+                                          hdrsize, 1);
        if (dma_mapping_error(meta_hdr->dmaaddr))
                return -EIO;
        ops->fill_descriptor(ring, desc, meta_hdr->dmaaddr,
-                            sizeof(struct b43_txhdr_fw4), 1, 0, 0);
+                            hdrsize, 1, 0, 0);
 
        /* Get a slot for the payload. */
        slot = request_slot(ring);
@@ -1164,16 +1174,22 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 
        ops->fill_descriptor(ring, desc, meta->dmaaddr, skb->len, 0, 1, 1);
 
+       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+               /* Tell the firmware about the cookie of the last
+                * mcast frame, so it can clear the more-data bit in it. */
+               b43_shm_write16(ring->dev, B43_SHM_SHARED,
+                               B43_SHM_SH_MCASTCOOKIE, cookie);
+       }
        /* Now transfer the whole frame. */
        wmb();
        ops->poke_tx(ring, next_slot(ring, slot));
        return 0;
 
-      out_free_bounce:
+out_free_bounce:
        dev_kfree_skb_any(skb);
-      out_unmap_hdr:
+out_unmap_hdr:
        unmap_descbuffer(ring, meta_hdr->dmaaddr,
-                        sizeof(struct b43_txhdr_fw4), 1);
+                        hdrsize, 1);
        return err;
 }
 
@@ -1202,10 +1218,27 @@ int b43_dma_tx(struct b43_wldev *dev,
               struct sk_buff *skb, struct ieee80211_tx_control *ctl)
 {
        struct b43_dmaring *ring;
+       struct ieee80211_hdr *hdr;
        int err = 0;
        unsigned long flags;
 
-       ring = priority_to_txring(dev, ctl->queue);
+       if (unlikely(skb->len < 2 + 2 + 6)) {
+               /* Too short, this can't be a valid frame. */
+               return -EINVAL;
+       }
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       if (ctl->flags & IEEE80211_TXCTL_SEND_AFTER_DTIM) {
+               /* The multicast ring will be sent after the DTIM */
+               ring = dev->dma.tx_ring4;
+               /* Set the more-data bit. Ucode will clear it on
+                * the last frame for us. */
+               hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+       } else {
+               /* Decide by priority where to put this frame. */
+               ring = priority_to_txring(dev, ctl->queue);
+       }
+
        spin_lock_irqsave(&ring->lock, flags);
        B43_WARN_ON(!ring->tx);
        if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) {
@@ -1233,7 +1266,7 @@ int b43_dma_tx(struct b43_wldev *dev,
                        b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index);
                }
        }
-      out_unlock:
+out_unlock:
        spin_unlock_irqrestore(&ring->lock, flags);
 
        return err;
@@ -1265,7 +1298,7 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
                                         1);
                else
                        unmap_descbuffer(ring, meta->dmaaddr,
-                                        sizeof(struct b43_txhdr_fw4), 1);
+                                        b43_txhdr_size(dev), 1);
 
                if (meta->is_last_fragment) {
                        B43_WARN_ON(!meta->skb);
index 3eed185be72552194cab5a1f0c6f8f13e21b1a16..58db03ac536e596e060e94815a0fb0bfbe87d0c0 100644 (file)
@@ -170,8 +170,6 @@ struct b43_dmadesc_generic {
 #define B43_DMA0_RX_BUFFERSIZE (2304 + 100)
 #define B43_DMA3_RX_BUFFERSIZE 16
 
-#ifdef CONFIG_B43_DMA
-
 struct sk_buff;
 struct b43_private;
 struct b43_txstatus;
@@ -286,52 +284,4 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
 
 void b43_dma_rx(struct b43_dmaring *ring);
 
-#else /* CONFIG_B43_DMA */
-
-static inline int b43_dma_init(struct b43_wldev *dev)
-{
-       return 0;
-}
-static inline void b43_dma_free(struct b43_wldev *dev)
-{
-}
-static inline
-    int b43_dmacontroller_rx_reset(struct b43_wldev *dev,
-                                  u16 dmacontroller_mmio_base, int dma64)
-{
-       return 0;
-}
-static inline
-    int b43_dmacontroller_tx_reset(struct b43_wldev *dev,
-                                  u16 dmacontroller_mmio_base, int dma64)
-{
-       return 0;
-}
-static inline
-    void b43_dma_get_tx_stats(struct b43_wldev *dev,
-                             struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline
-    int b43_dma_tx(struct b43_wldev *dev,
-                  struct sk_buff *skb, struct ieee80211_tx_control *ctl)
-{
-       return 0;
-}
-static inline
-    void b43_dma_handle_txstatus(struct b43_wldev *dev,
-                                const struct b43_txstatus *status)
-{
-}
-static inline void b43_dma_rx(struct b43_dmaring *ring)
-{
-}
-static inline void b43_dma_tx_suspend(struct b43_wldev *dev)
-{
-}
-static inline void b43_dma_tx_resume(struct b43_wldev *dev)
-{
-}
-
-#endif /* CONFIG_B43_DMA */
 #endif /* B43_DMA_H_ */
index 6c0e2b9f7760d90633071aa9daf54c4115081cc5..4b590d8c65ff08317fc6405546545e64bc104115 100644 (file)
@@ -4,7 +4,7 @@
   LED control
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-  Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -190,10 +190,10 @@ void b43_leds_init(struct b43_wldev *dev)
        enum b43_led_behaviour behaviour;
        bool activelow;
 
-       sprom[0] = bus->sprom.r1.gpio0;
-       sprom[1] = bus->sprom.r1.gpio1;
-       sprom[2] = bus->sprom.r1.gpio2;
-       sprom[3] = bus->sprom.r1.gpio3;
+       sprom[0] = bus->sprom.gpio0;
+       sprom[1] = bus->sprom.gpio1;
+       sprom[2] = bus->sprom.gpio2;
+       sprom[3] = bus->sprom.gpio3;
 
        for (i = 0; i < 4; i++) {
                if (sprom[i] == 0xFF) {
index b14a1753a0d7a7e1f0770d00aef2b3e80bbec26b..d890f366a23b76a021a18807238c54fdf09b9d31 100644 (file)
@@ -5,7 +5,7 @@
   G PHY LO (LocalOscillator) Measuring and Control routines
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-  Copyright (c) 2005, 2006 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005, 2006 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -264,8 +264,8 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
                rfover |= pga;
                rfover |= lna;
                rfover |= trsw_rx;
-               if ((dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) &&
-                   phy->rev > 6)
+               if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
+                   && phy->rev > 6)
                        rfover |= B43_PHY_RFOVERVAL_EXTLNA;
 
                b43_phy_write(dev, B43_PHY_PGACTL, 0xE300);
@@ -555,20 +555,20 @@ struct lo_g_saved_values {
        u16 phy_extg_01;
        u16 phy_dacctl_hwpctl;
        u16 phy_dacctl;
-       u16 phy_base_14;
+       u16 phy_cck_14;
        u16 phy_hpwr_tssictl;
        u16 phy_analogover;
        u16 phy_analogoverval;
        u16 phy_rfover;
        u16 phy_rfoverval;
        u16 phy_classctl;
-       u16 phy_base_3E;
+       u16 phy_cck_3E;
        u16 phy_crs0;
        u16 phy_pgactl;
-       u16 phy_base_2A;
+       u16 phy_cck_2A;
        u16 phy_syncctl;
-       u16 phy_base_30;
-       u16 phy_base_06;
+       u16 phy_cck_30;
+       u16 phy_cck_06;
 
        /* Radio registers */
        u16 radio_43;
@@ -588,7 +588,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
                sav->phy_lo_mask = b43_phy_read(dev, B43_PHY_LO_MASK);
                sav->phy_extg_01 = b43_phy_read(dev, B43_PHY_EXTG(0x01));
                sav->phy_dacctl_hwpctl = b43_phy_read(dev, B43_PHY_DACCTL);
-               sav->phy_base_14 = b43_phy_read(dev, B43_PHY_BASE(0x14));
+               sav->phy_cck_14 = b43_phy_read(dev, B43_PHY_CCK(0x14));
                sav->phy_hpwr_tssictl = b43_phy_read(dev, B43_PHY_HPWR_TSSICTL);
 
                b43_phy_write(dev, B43_PHY_HPWR_TSSICTL,
@@ -600,14 +600,14 @@ static void lo_measure_setup(struct b43_wldev *dev,
                b43_phy_write(dev, B43_PHY_DACCTL,
                              b43_phy_read(dev, B43_PHY_DACCTL)
                              | 0x40);
-               b43_phy_write(dev, B43_PHY_BASE(0x14),
-                             b43_phy_read(dev, B43_PHY_BASE(0x14))
+               b43_phy_write(dev, B43_PHY_CCK(0x14),
+                             b43_phy_read(dev, B43_PHY_CCK(0x14))
                              | 0x200);
        }
        if (phy->type == B43_PHYTYPE_B &&
            phy->radio_ver == 0x2050 && phy->radio_rev < 6) {
-               b43_phy_write(dev, B43_PHY_BASE(0x16), 0x410);
-               b43_phy_write(dev, B43_PHY_BASE(0x17), 0x820);
+               b43_phy_write(dev, B43_PHY_CCK(0x16), 0x410);
+               b43_phy_write(dev, B43_PHY_CCK(0x17), 0x820);
        }
        if (!lo->rebuild && b43_has_hardware_pctl(phy))
                lo_read_power_vector(dev);
@@ -618,7 +618,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
                sav->phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER);
                sav->phy_rfoverval = b43_phy_read(dev, B43_PHY_RFOVERVAL);
                sav->phy_classctl = b43_phy_read(dev, B43_PHY_CLASSCTL);
-               sav->phy_base_3E = b43_phy_read(dev, B43_PHY_BASE(0x3E));
+               sav->phy_cck_3E = b43_phy_read(dev, B43_PHY_CCK(0x3E));
                sav->phy_crs0 = b43_phy_read(dev, B43_PHY_CRS0);
 
                b43_phy_write(dev, B43_PHY_CLASSCTL,
@@ -634,7 +634,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
                              & 0xFFFC);
                if (phy->type == B43_PHYTYPE_G) {
                        if ((phy->rev >= 7) &&
-                           (sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) {
+                           (sprom->boardflags_lo & B43_BFL_EXTLNA)) {
                                b43_phy_write(dev, B43_PHY_RFOVER, 0x933);
                        } else {
                                b43_phy_write(dev, B43_PHY_RFOVER, 0x133);
@@ -642,14 +642,14 @@ static void lo_measure_setup(struct b43_wldev *dev,
                } else {
                        b43_phy_write(dev, B43_PHY_RFOVER, 0);
                }
-               b43_phy_write(dev, B43_PHY_BASE(0x3E), 0);
+               b43_phy_write(dev, B43_PHY_CCK(0x3E), 0);
        }
        sav->reg_3F4 = b43_read16(dev, 0x3F4);
        sav->reg_3E2 = b43_read16(dev, 0x3E2);
        sav->radio_43 = b43_radio_read16(dev, 0x43);
        sav->radio_7A = b43_radio_read16(dev, 0x7A);
        sav->phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL);
-       sav->phy_base_2A = b43_phy_read(dev, B43_PHY_BASE(0x2A));
+       sav->phy_cck_2A = b43_phy_read(dev, B43_PHY_CCK(0x2A));
        sav->phy_syncctl = b43_phy_read(dev, B43_PHY_SYNCCTL);
        sav->phy_dacctl = b43_phy_read(dev, B43_PHY_DACCTL);
 
@@ -658,10 +658,10 @@ static void lo_measure_setup(struct b43_wldev *dev,
                sav->radio_52 &= 0x00F0;
        }
        if (phy->type == B43_PHYTYPE_B) {
-               sav->phy_base_30 = b43_phy_read(dev, B43_PHY_BASE(0x30));
-               sav->phy_base_06 = b43_phy_read(dev, B43_PHY_BASE(0x06));
-               b43_phy_write(dev, B43_PHY_BASE(0x30), 0x00FF);
-               b43_phy_write(dev, B43_PHY_BASE(0x06), 0x3F3F);
+               sav->phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30));
+               sav->phy_cck_06 = b43_phy_read(dev, B43_PHY_CCK(0x06));
+               b43_phy_write(dev, B43_PHY_CCK(0x30), 0x00FF);
+               b43_phy_write(dev, B43_PHY_CCK(0x06), 0x3F3F);
        } else {
                b43_write16(dev, 0x3E2, b43_read16(dev, 0x3E2)
                            | 0x8000);
@@ -670,7 +670,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
                    & 0xF000);
 
        tmp =
-           (phy->type == B43_PHYTYPE_G) ? B43_PHY_LO_MASK : B43_PHY_BASE(0x2E);
+           (phy->type == B43_PHYTYPE_G) ? B43_PHY_LO_MASK : B43_PHY_CCK(0x2E);
        b43_phy_write(dev, tmp, 0x007F);
 
        tmp = sav->phy_syncctl;
@@ -678,26 +678,26 @@ static void lo_measure_setup(struct b43_wldev *dev,
        tmp = sav->radio_7A;
        b43_radio_write16(dev, 0x007A, tmp & 0xFFF0);
 
-       b43_phy_write(dev, B43_PHY_BASE(0x2A), 0x8A3);
+       b43_phy_write(dev, B43_PHY_CCK(0x2A), 0x8A3);
        if (phy->type == B43_PHYTYPE_G ||
            (phy->type == B43_PHYTYPE_B &&
             phy->radio_ver == 0x2050 && phy->radio_rev >= 6)) {
-               b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x1003);
+               b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1003);
        } else
-               b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x0802);
+               b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802);
        if (phy->rev >= 2)
                b43_dummy_transmission(dev);
        b43_radio_selectchannel(dev, 6, 0);
        b43_radio_read16(dev, 0x51);    /* dummy read */
        if (phy->type == B43_PHYTYPE_G)
-               b43_phy_write(dev, B43_PHY_BASE(0x2F), 0);
+               b43_phy_write(dev, B43_PHY_CCK(0x2F), 0);
        if (lo->rebuild)
                lo_measure_txctl_values(dev);
        if (phy->type == B43_PHYTYPE_G && phy->rev >= 3) {
                b43_phy_write(dev, B43_PHY_LO_MASK, 0xC078);
        } else {
                if (phy->type == B43_PHYTYPE_B)
-                       b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8078);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8078);
                else
                        b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
        }
@@ -732,17 +732,17 @@ static void lo_measure_restore(struct b43_wldev *dev,
        }
        if (phy->type == B43_PHYTYPE_G) {
                if (phy->rev >= 3)
-                       b43_phy_write(dev, B43_PHY_BASE(0x2E), 0xC078);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2E), 0xC078);
                else
-                       b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8078);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8078);
                if (phy->rev >= 2)
-                       b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x0202);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x0202);
                else
-                       b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x0101);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x0101);
        }
        b43_write16(dev, 0x3F4, sav->reg_3F4);
        b43_phy_write(dev, B43_PHY_PGACTL, sav->phy_pgactl);
-       b43_phy_write(dev, B43_PHY_BASE(0x2A), sav->phy_base_2A);
+       b43_phy_write(dev, B43_PHY_CCK(0x2A), sav->phy_cck_2A);
        b43_phy_write(dev, B43_PHY_SYNCCTL, sav->phy_syncctl);
        b43_phy_write(dev, B43_PHY_DACCTL, sav->phy_dacctl);
        b43_radio_write16(dev, 0x43, sav->radio_43);
@@ -755,8 +755,8 @@ static void lo_measure_restore(struct b43_wldev *dev,
        b43_write16(dev, 0x3E2, sav->reg_3E2);
        if (phy->type == B43_PHYTYPE_B &&
            phy->radio_ver == 0x2050 && phy->radio_rev <= 5) {
-               b43_phy_write(dev, B43_PHY_BASE(0x30), sav->phy_base_30);
-               b43_phy_write(dev, B43_PHY_BASE(0x06), sav->phy_base_06);
+               b43_phy_write(dev, B43_PHY_CCK(0x30), sav->phy_cck_30);
+               b43_phy_write(dev, B43_PHY_CCK(0x06), sav->phy_cck_06);
        }
        if (phy->rev >= 2) {
                b43_phy_write(dev, B43_PHY_ANALOGOVER, sav->phy_analogover);
@@ -765,7 +765,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
                b43_phy_write(dev, B43_PHY_CLASSCTL, sav->phy_classctl);
                b43_phy_write(dev, B43_PHY_RFOVER, sav->phy_rfover);
                b43_phy_write(dev, B43_PHY_RFOVERVAL, sav->phy_rfoverval);
-               b43_phy_write(dev, B43_PHY_BASE(0x3E), sav->phy_base_3E);
+               b43_phy_write(dev, B43_PHY_CCK(0x3E), sav->phy_cck_3E);
                b43_phy_write(dev, B43_PHY_CRS0, sav->phy_crs0);
        }
        if (b43_has_hardware_pctl(phy)) {
@@ -773,7 +773,7 @@ static void lo_measure_restore(struct b43_wldev *dev,
                b43_phy_write(dev, B43_PHY_LO_MASK, tmp);
                b43_phy_write(dev, B43_PHY_EXTG(0x01), sav->phy_extg_01);
                b43_phy_write(dev, B43_PHY_DACCTL, sav->phy_dacctl_hwpctl);
-               b43_phy_write(dev, B43_PHY_BASE(0x14), sav->phy_base_14);
+               b43_phy_write(dev, B43_PHY_CCK(0x14), sav->phy_cck_14);
                b43_phy_write(dev, B43_PHY_HPWR_TSSICTL, sav->phy_hpwr_tssictl);
        }
        b43_radio_selectchannel(dev, sav->old_channel, 1);
index 1c93b4f4bfe37abd7f65b7687a945652d337ead0..88d2c15d3fbeccc5332cf55e3582a71e5174e3ef 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43 wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
-  Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -46,7 +46,6 @@
 #include "debugfs.h"
 #include "phy.h"
 #include "dma.h"
-#include "pio.h"
 #include "sysfs.h"
 #include "xmit.h"
 #include "lo.h"
@@ -58,31 +57,12 @@ MODULE_AUTHOR("Stefano Brivio");
 MODULE_AUTHOR("Michael Buesch");
 MODULE_LICENSE("GPL");
 
-extern char *nvram_get(char *name);
-
-#if defined(CONFIG_B43_DMA) && defined(CONFIG_B43_PIO)
-static int modparam_pio;
-module_param_named(pio, modparam_pio, int, 0444);
-MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
-#elif defined(CONFIG_B43_DMA)
-# define modparam_pio  0
-#elif defined(CONFIG_B43_PIO)
-# define modparam_pio  1
-#endif
 
 static int modparam_bad_frames_preempt;
 module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
 MODULE_PARM_DESC(bad_frames_preempt,
                 "enable(1) / disable(0) Bad Frames Preemption");
 
-static int modparam_short_retry = B43_DEFAULT_SHORT_RETRY_LIMIT;
-module_param_named(short_retry, modparam_short_retry, int, 0444);
-MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
-
-static int modparam_long_retry = B43_DEFAULT_LONG_RETRY_LIMIT;
-module_param_named(long_retry, modparam_long_retry, int, 0444);
-MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
-
 static char modparam_fwpostfix[16];
 module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444);
 MODULE_PARM_DESC(fwpostfix, "Postfix for the .fw files to load.");
@@ -101,6 +81,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
+       SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
        SSB_DEVTABLE_END
 };
 
@@ -150,7 +132,7 @@ static struct ieee80211_rate __b43_ratetable[] = {
                .power_level    = 0xFF,                         \
                .antenna_max    = 0xFF,                         \
        }
-static struct ieee80211_channel b43_bg_chantable[] = {
+static struct ieee80211_channel b43_2ghz_chantable[] = {
        CHANTAB_ENT(1, 2412),
        CHANTAB_ENT(2, 2417),
        CHANTAB_ENT(3, 2422),
@@ -166,9 +148,10 @@ static struct ieee80211_channel b43_bg_chantable[] = {
        CHANTAB_ENT(13, 2472),
        CHANTAB_ENT(14, 2484),
 };
+#define b43_2ghz_chantable_size        ARRAY_SIZE(b43_2ghz_chantable)
 
-#define b43_bg_chantable_size  ARRAY_SIZE(b43_bg_chantable)
-static struct ieee80211_channel b43_a_chantable[] = {
+#if 0
+static struct ieee80211_channel b43_5ghz_chantable[] = {
        CHANTAB_ENT(36, 5180),
        CHANTAB_ENT(40, 5200),
        CHANTAB_ENT(44, 5220),
@@ -183,8 +166,8 @@ static struct ieee80211_channel b43_a_chantable[] = {
        CHANTAB_ENT(161, 5805),
        CHANTAB_ENT(165, 5825),
 };
-
-#define b43_a_chantable_size   ARRAY_SIZE(b43_a_chantable)
+#define b43_5ghz_chantable_size        ARRAY_SIZE(b43_5ghz_chantable)
+#endif
 
 static void b43_wireless_core_exit(struct b43_wldev *dev);
 static int b43_wireless_core_init(struct b43_wldev *dev);
@@ -269,13 +252,12 @@ static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
        b43_write32(dev, B43_MMIO_RAM_DATA, val);
 }
 
-static inline
-    void b43_shm_control_word(struct b43_wldev *dev, u16 routing, u16 offset)
+static inline void b43_shm_control_word(struct b43_wldev *dev,
+                                       u16 routing, u16 offset)
 {
        u32 control;
 
        /* "offset" is the WORD offset. */
-
        control = routing;
        control <<= 16;
        control |= offset;
@@ -284,8 +266,11 @@ static inline
 
 u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
 {
+       struct b43_wl *wl = dev->wl;
+       unsigned long flags;
        u32 ret;
 
+       spin_lock_irqsave(&wl->shm_lock, flags);
        if (routing == B43_SHM_SHARED) {
                B43_WARN_ON(offset & 0x0001);
                if (offset & 0x0003) {
@@ -296,20 +281,25 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
                        b43_shm_control_word(dev, routing, (offset >> 2) + 1);
                        ret |= b43_read16(dev, B43_MMIO_SHM_DATA);
 
-                       return ret;
+                       goto out;
                }
                offset >>= 2;
        }
        b43_shm_control_word(dev, routing, offset);
        ret = b43_read32(dev, B43_MMIO_SHM_DATA);
+out:
+       spin_unlock_irqrestore(&wl->shm_lock, flags);
 
        return ret;
 }
 
 u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
 {
+       struct b43_wl *wl = dev->wl;
+       unsigned long flags;
        u16 ret;
 
+       spin_lock_irqsave(&wl->shm_lock, flags);
        if (routing == B43_SHM_SHARED) {
                B43_WARN_ON(offset & 0x0001);
                if (offset & 0x0003) {
@@ -317,55 +307,63 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset)
                        b43_shm_control_word(dev, routing, offset >> 2);
                        ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);
 
-                       return ret;
+                       goto out;
                }
                offset >>= 2;
        }
        b43_shm_control_word(dev, routing, offset);
        ret = b43_read16(dev, B43_MMIO_SHM_DATA);
+out:
+       spin_unlock_irqrestore(&wl->shm_lock, flags);
 
        return ret;
 }
 
 void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
 {
+       struct b43_wl *wl = dev->wl;
+       unsigned long flags;
+
+       spin_lock_irqsave(&wl->shm_lock, flags);
        if (routing == B43_SHM_SHARED) {
                B43_WARN_ON(offset & 0x0001);
                if (offset & 0x0003) {
                        /* Unaligned access */
                        b43_shm_control_word(dev, routing, offset >> 2);
-                       mmiowb();
                        b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED,
                                    (value >> 16) & 0xffff);
-                       mmiowb();
                        b43_shm_control_word(dev, routing, (offset >> 2) + 1);
-                       mmiowb();
                        b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff);
-                       return;
+                       goto out;
                }
                offset >>= 2;
        }
        b43_shm_control_word(dev, routing, offset);
-       mmiowb();
        b43_write32(dev, B43_MMIO_SHM_DATA, value);
+out:
+       spin_unlock_irqrestore(&wl->shm_lock, flags);
 }
 
 void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
 {
+       struct b43_wl *wl = dev->wl;
+       unsigned long flags;
+
+       spin_lock_irqsave(&wl->shm_lock, flags);
        if (routing == B43_SHM_SHARED) {
                B43_WARN_ON(offset & 0x0001);
                if (offset & 0x0003) {
                        /* Unaligned access */
                        b43_shm_control_word(dev, routing, offset >> 2);
-                       mmiowb();
                        b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
-                       return;
+                       goto out;
                }
                offset >>= 2;
        }
        b43_shm_control_word(dev, routing, offset);
-       mmiowb();
        b43_write16(dev, B43_MMIO_SHM_DATA, value);
+out:
+       spin_unlock_irqrestore(&wl->shm_lock, flags);
 }
 
 /* Read HostFlags */
@@ -1012,9 +1010,8 @@ static void b43_jssi_write(struct b43_wldev *dev, u32 jssi)
 static void b43_generate_noise_sample(struct b43_wldev *dev)
 {
        b43_jssi_write(dev, 0x7F7F7F7F);
-       b43_write32(dev, B43_MMIO_STATUS2_BITFIELD,
-                   b43_read32(dev, B43_MMIO_STATUS2_BITFIELD)
-                   | (1 << 4));
+       b43_write32(dev, B43_MMIO_MACCMD,
+                   b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE);
        B43_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel);
 }
 
@@ -1100,18 +1097,18 @@ static void handle_irq_tbtt_indication(struct b43_wldev *dev)
                if (1 /*FIXME: the last PSpoll frame was sent successfully */ )
                        b43_power_saving_ctl_bits(dev, 0);
        }
-       dev->reg124_set_0x4 = 0;
        if (b43_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS))
-               dev->reg124_set_0x4 = 1;
+               dev->dfq_valid = 1;
 }
 
 static void handle_irq_atim_end(struct b43_wldev *dev)
 {
-       if (!dev->reg124_set_0x4 /*FIXME rename this variable */ )
-               return;
-       b43_write32(dev, B43_MMIO_STATUS2_BITFIELD,
-                   b43_read32(dev, B43_MMIO_STATUS2_BITFIELD)
-                   | 0x4);
+       if (dev->dfq_valid) {
+               b43_write32(dev, B43_MMIO_MACCMD,
+                           b43_read32(dev, B43_MMIO_MACCMD)
+                           | B43_MACCMD_DFQ_VALID);
+               dev->dfq_valid = 0;
+       }
 }
 
 static void handle_irq_pmq(struct b43_wldev *dev)
@@ -1166,15 +1163,59 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
                                      u16 ram_offset,
                                      u16 shm_size_offset, u8 rate)
 {
-       int len;
-       const u8 *data;
+       unsigned int i, len, variable_len;
+       const struct ieee80211_mgmt *bcn;
+       const u8 *ie;
+       bool tim_found = 0;
 
-       B43_WARN_ON(!dev->cached_beacon);
-       len = min((size_t) dev->cached_beacon->len,
+       bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
+       len = min((size_t) dev->wl->current_beacon->len,
                  0x200 - sizeof(struct b43_plcp_hdr6));
-       data = (const u8 *)(dev->cached_beacon->data);
-       b43_write_template_common(dev, data,
+
+       b43_write_template_common(dev, (const u8 *)bcn,
                                  len, ram_offset, shm_size_offset, rate);
+
+       /* Find the position of the TIM and the DTIM_period value
+        * and write them to SHM. */
+       ie = bcn->u.beacon.variable;
+       variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
+       for (i = 0; i < variable_len - 2; ) {
+               uint8_t ie_id, ie_len;
+
+               ie_id = ie[i];
+               ie_len = ie[i + 1];
+               if (ie_id == 5) {
+                       u16 tim_position;
+                       u16 dtim_period;
+                       /* This is the TIM Information Element */
+
+                       /* Check whether the ie_len is in the beacon data range. */
+                       if (variable_len < ie_len + 2 + i)
+                               break;
+                       /* A valid TIM is at least 4 bytes long. */
+                       if (ie_len < 4)
+                               break;
+                       tim_found = 1;
+
+                       tim_position = sizeof(struct b43_plcp_hdr6);
+                       tim_position += offsetof(struct ieee80211_mgmt, u.beacon.variable);
+                       tim_position += i;
+
+                       dtim_period = ie[i + 3];
+
+                       b43_shm_write16(dev, B43_SHM_SHARED,
+                                       B43_SHM_SH_TIMBPOS, tim_position);
+                       b43_shm_write16(dev, B43_SHM_SHARED,
+                                       B43_SHM_SH_DTIMPER, dtim_period);
+                       break;
+               }
+               i += ie_len + 2;
+       }
+       if (!tim_found) {
+               b43warn(dev->wl, "Did not find a valid TIM IE in "
+                       "the beacon template packet. AP or IBSS operation "
+                       "may be broken.\n");
+       }
 }
 
 static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
@@ -1187,7 +1228,7 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
        plcp.data = 0;
        b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
        dur = ieee80211_generic_frame_duration(dev->wl->hw,
-                                              dev->wl->if_id, size,
+                                              dev->wl->vif, size,
                                               B43_RATE_TO_BASE100KBPS(rate));
        /* Write PLCP in two parts and timing for packet transfer */
        tmp = le32_to_cpu(plcp.data);
@@ -1202,40 +1243,43 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
  * 2) Patching duration field
  * 3) Stripping TIM
  */
-static u8 *b43_generate_probe_resp(struct b43_wldev *dev,
-                                  u16 * dest_size, u8 rate)
+static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
+                                         u16 *dest_size, u8 rate)
 {
        const u8 *src_data;
        u8 *dest_data;
        u16 src_size, elem_size, src_pos, dest_pos;
        __le16 dur;
        struct ieee80211_hdr *hdr;
+       size_t ie_start;
 
-       B43_WARN_ON(!dev->cached_beacon);
-       src_size = dev->cached_beacon->len;
-       src_data = (const u8 *)dev->cached_beacon->data;
+       src_size = dev->wl->current_beacon->len;
+       src_data = (const u8 *)dev->wl->current_beacon->data;
 
-       if (unlikely(src_size < 0x24)) {
-               b43dbg(dev->wl, "b43_generate_probe_resp: " "invalid beacon\n");
+       /* Get the start offset of the variable IEs in the packet. */
+       ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
+       B43_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt, u.beacon.variable));
+
+       if (B43_WARN_ON(src_size < ie_start))
                return NULL;
-       }
 
        dest_data = kmalloc(src_size, GFP_ATOMIC);
        if (unlikely(!dest_data))
                return NULL;
 
-       /* 0x24 is offset of first variable-len Information-Element
-        * in beacon frame.
-        */
-       memcpy(dest_data, src_data, 0x24);
-       src_pos = dest_pos = 0x24;
-       for (; src_pos < src_size - 2; src_pos += elem_size) {
+       /* Copy the static data and all Information Elements, except the TIM. */
+       memcpy(dest_data, src_data, ie_start);
+       src_pos = ie_start;
+       dest_pos = ie_start;
+       for ( ; src_pos < src_size - 2; src_pos += elem_size) {
                elem_size = src_data[src_pos + 1] + 2;
-               if (src_data[src_pos] != 0x05) {        /* TIM */
-                       memcpy(dest_data + dest_pos, src_data + src_pos,
-                              elem_size);
-                       dest_pos += elem_size;
+               if (src_data[src_pos] == 5) {
+                       /* This is the TIM. */
+                       continue;
                }
+               memcpy(dest_data + dest_pos, src_data + src_pos,
+                      elem_size);
+               dest_pos += elem_size;
        }
        *dest_size = dest_pos;
        hdr = (struct ieee80211_hdr *)dest_data;
@@ -1244,7 +1288,7 @@ static u8 *b43_generate_probe_resp(struct b43_wldev *dev,
        hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                         IEEE80211_STYPE_PROBE_RESP);
        dur = ieee80211_generic_frame_duration(dev->wl->hw,
-                                              dev->wl->if_id, *dest_size,
+                                              dev->wl->vif, *dest_size,
                                               B43_RATE_TO_BASE100KBPS(rate));
        hdr->duration_id = dur;
 
@@ -1255,11 +1299,10 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev,
                                          u16 ram_offset,
                                          u16 shm_size_offset, u8 rate)
 {
-       u8 *probe_resp_data;
+       const u8 *probe_resp_data;
        u16 size;
 
-       B43_WARN_ON(!dev->cached_beacon);
-       size = dev->cached_beacon->len;
+       size = dev->wl->current_beacon->len;
        probe_resp_data = b43_generate_probe_resp(dev, &size, rate);
        if (unlikely(!probe_resp_data))
                return;
@@ -1278,39 +1321,21 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev,
        kfree(probe_resp_data);
 }
 
-static int b43_refresh_cached_beacon(struct b43_wldev *dev,
-                                    struct sk_buff *beacon)
-{
-       if (dev->cached_beacon)
-               kfree_skb(dev->cached_beacon);
-       dev->cached_beacon = beacon;
-
-       return 0;
-}
-
-static void b43_update_templates(struct b43_wldev *dev)
+/* Asynchronously update the packet templates in template RAM.
+ * Locking: Requires wl->irq_lock to be locked. */
+static void b43_update_templates(struct b43_wl *wl, struct sk_buff *beacon)
 {
-       u32 status;
-
-       B43_WARN_ON(!dev->cached_beacon);
+       /* This is the top half of the ansynchronous beacon update.
+        * The bottom half is the beacon IRQ.
+        * Beacon update must be asynchronous to avoid sending an
+        * invalid beacon. This can happen for example, if the firmware
+        * transmits a beacon while we are updating it. */
 
-       b43_write_beacon_template(dev, 0x68, 0x18, B43_CCK_RATE_1MB);
-       b43_write_beacon_template(dev, 0x468, 0x1A, B43_CCK_RATE_1MB);
-       b43_write_probe_resp_template(dev, 0x268, 0x4A, B43_CCK_RATE_11MB);
-
-       status = b43_read32(dev, B43_MMIO_STATUS2_BITFIELD);
-       status |= 0x03;
-       b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
-}
-
-static void b43_refresh_templates(struct b43_wldev *dev, struct sk_buff *beacon)
-{
-       int err;
-
-       err = b43_refresh_cached_beacon(dev, beacon);
-       if (unlikely(err))
-               return;
-       b43_update_templates(dev);
+       if (wl->current_beacon)
+               dev_kfree_skb_any(wl->current_beacon);
+       wl->current_beacon = beacon;
+       wl->beacon0_uploaded = 0;
+       wl->beacon1_uploaded = 0;
 }
 
 static void b43_set_ssid(struct b43_wldev *dev, const u8 * ssid, u8 ssid_len)
@@ -1346,33 +1371,34 @@ static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
 
 static void handle_irq_beacon(struct b43_wldev *dev)
 {
-       u32 status;
+       struct b43_wl *wl = dev->wl;
+       u32 cmd;
 
-       if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
+       if (!b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
                return;
 
-       dev->irq_savedstate &= ~B43_IRQ_BEACON;
-       status = b43_read32(dev, B43_MMIO_STATUS2_BITFIELD);
+       /* This is the bottom half of the asynchronous beacon update. */
 
-       if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) {
-               /* ACK beacon IRQ. */
-               b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
-               dev->irq_savedstate |= B43_IRQ_BEACON;
-               if (dev->cached_beacon)
-                       kfree_skb(dev->cached_beacon);
-               dev->cached_beacon = NULL;
-               return;
-       }
-       if (!(status & 0x1)) {
-               b43_write_beacon_template(dev, 0x68, 0x18, B43_CCK_RATE_1MB);
-               status |= 0x1;
-               b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
+       cmd = b43_read32(dev, B43_MMIO_MACCMD);
+       if (!(cmd & B43_MACCMD_BEACON0_VALID)) {
+               if (!wl->beacon0_uploaded) {
+                       b43_write_beacon_template(dev, 0x68, 0x18,
+                                                 B43_CCK_RATE_1MB);
+                       b43_write_probe_resp_template(dev, 0x268, 0x4A,
+                                                     B43_CCK_RATE_11MB);
+                       wl->beacon0_uploaded = 1;
+               }
+               cmd |= B43_MACCMD_BEACON0_VALID;
        }
-       if (!(status & 0x2)) {
-               b43_write_beacon_template(dev, 0x468, 0x1A, B43_CCK_RATE_1MB);
-               status |= 0x2;
-               b43_write32(dev, B43_MMIO_STATUS2_BITFIELD, status);
+       if (!(cmd & B43_MACCMD_BEACON1_VALID)) {
+               if (!wl->beacon1_uploaded) {
+                       b43_write_beacon_template(dev, 0x468, 0x1A,
+                                                 B43_CCK_RATE_1MB);
+                       wl->beacon1_uploaded = 1;
+               }
+               cmd |= B43_MACCMD_BEACON1_VALID;
        }
+       b43_write32(dev, B43_MMIO_MACCMD, cmd);
 }
 
 static void handle_irq_ucode_debug(struct b43_wldev *dev)
@@ -1402,8 +1428,17 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
        if (unlikely(reason & B43_IRQ_MAC_TXERR))
                b43err(dev->wl, "MAC transmission error\n");
 
-       if (unlikely(reason & B43_IRQ_PHY_TXERR))
+       if (unlikely(reason & B43_IRQ_PHY_TXERR)) {
                b43err(dev->wl, "PHY transmission error\n");
+               rmb();
+               if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) {
+                       atomic_set(&dev->phy.txerr_cnt,
+                                  B43_PHY_TX_BADNESS_LIMIT);
+                       b43err(dev->wl, "Too many PHY TX errors, "
+                                       "restarting the controller\n");
+                       b43_controller_restart(dev, "PHY TX errors");
+               }
+       }
 
        if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK |
                                          B43_DMAIRQ_NONFATALMASK))) {
@@ -1445,20 +1480,12 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
                handle_irq_noise(dev);
 
        /* Check the DMA reason registers for received data. */
-       if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
-               if (b43_using_pio(dev))
-                       b43_pio_rx(dev->pio.queue0);
-               else
-                       b43_dma_rx(dev->dma.rx_ring0);
-       }
+       if (dma_reason[0] & B43_DMAIRQ_RX_DONE)
+               b43_dma_rx(dev->dma.rx_ring0);
+       if (dma_reason[3] & B43_DMAIRQ_RX_DONE)
+               b43_dma_rx(dev->dma.rx_ring3);
        B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
        B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
-       if (dma_reason[3] & B43_DMAIRQ_RX_DONE) {
-               if (b43_using_pio(dev))
-                       b43_pio_rx(dev->pio.queue3);
-               else
-                       b43_dma_rx(dev->dma.rx_ring3);
-       }
        B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
        B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
 
@@ -1470,29 +1497,8 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
        spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 }
 
-static void pio_irq_workaround(struct b43_wldev *dev, u16 base, int queueidx)
-{
-       u16 rxctl;
-
-       rxctl = b43_read16(dev, base + B43_PIO_RXCTL);
-       if (rxctl & B43_PIO_RXCTL_DATAAVAILABLE)
-               dev->dma_reason[queueidx] |= B43_DMAIRQ_RX_DONE;
-       else
-               dev->dma_reason[queueidx] &= ~B43_DMAIRQ_RX_DONE;
-}
-
 static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
 {
-       if (b43_using_pio(dev) &&
-           (dev->dev->id.revision < 3) &&
-           (!(reason & B43_IRQ_PIO_WORKAROUND))) {
-               /* Apply a PIO specific workaround to the dma_reasons */
-               pio_irq_workaround(dev, B43_MMIO_PIO1_BASE, 0);
-               pio_irq_workaround(dev, B43_MMIO_PIO2_BASE, 1);
-               pio_irq_workaround(dev, B43_MMIO_PIO3_BASE, 2);
-               pio_irq_workaround(dev, B43_MMIO_PIO4_BASE, 3);
-       }
-
        b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
 
        b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
@@ -1551,54 +1557,73 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
        return ret;
 }
 
+static void do_release_fw(struct b43_firmware_file *fw)
+{
+       release_firmware(fw->data);
+       fw->data = NULL;
+       fw->filename = NULL;
+}
+
 static void b43_release_firmware(struct b43_wldev *dev)
 {
-       release_firmware(dev->fw.ucode);
-       dev->fw.ucode = NULL;
-       release_firmware(dev->fw.pcm);
-       dev->fw.pcm = NULL;
-       release_firmware(dev->fw.initvals);
-       dev->fw.initvals = NULL;
-       release_firmware(dev->fw.initvals_band);
-       dev->fw.initvals_band = NULL;
+       do_release_fw(&dev->fw.ucode);
+       do_release_fw(&dev->fw.pcm);
+       do_release_fw(&dev->fw.initvals);
+       do_release_fw(&dev->fw.initvals_band);
 }
 
-static void b43_print_fw_helptext(struct b43_wl *wl)
+static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
 {
-       b43err(wl, "You must go to "
+       const char *text;
+
+       text = "You must go to "
               "http://linuxwireless.org/en/users/Drivers/b43#devicefirmware "
-              "and download the correct firmware (version 4).\n");
+              "and download the latest firmware (version 4).\n";
+       if (error)
+               b43err(wl, text);
+       else
+               b43warn(wl, text);
 }
 
 static int do_request_fw(struct b43_wldev *dev,
                         const char *name,
-                        const struct firmware **fw)
+                        struct b43_firmware_file *fw)
 {
        char path[sizeof(modparam_fwpostfix) + 32];
+       const struct firmware *blob;
        struct b43_fw_header *hdr;
        u32 size;
        int err;
 
-       if (!name)
+       if (!name) {
+               /* Don't fetch anything. Free possibly cached firmware. */
+               do_release_fw(fw);
                return 0;
+       }
+       if (fw->filename) {
+               if (strcmp(fw->filename, name) == 0)
+                       return 0; /* Already have this fw. */
+               /* Free the cached firmware first. */
+               do_release_fw(fw);
+       }
 
        snprintf(path, ARRAY_SIZE(path),
                 "b43%s/%s.fw",
                 modparam_fwpostfix, name);
-       err = request_firmware(fw, path, dev->dev->dev);
+       err = request_firmware(&blob, path, dev->dev->dev);
        if (err) {
                b43err(dev->wl, "Firmware file \"%s\" not found "
                       "or load failed.\n", path);
                return err;
        }
-       if ((*fw)->size < sizeof(struct b43_fw_header))
+       if (blob->size < sizeof(struct b43_fw_header))
                goto err_format;
-       hdr = (struct b43_fw_header *)((*fw)->data);
+       hdr = (struct b43_fw_header *)(blob->data);
        switch (hdr->type) {
        case B43_FW_TYPE_UCODE:
        case B43_FW_TYPE_PCM:
                size = be32_to_cpu(hdr->size);
-               if (size != (*fw)->size - sizeof(struct b43_fw_header))
+               if (size != blob->size - sizeof(struct b43_fw_header))
                        goto err_format;
                /* fallthrough */
        case B43_FW_TYPE_IV:
@@ -1609,10 +1634,15 @@ static int do_request_fw(struct b43_wldev *dev,
                goto err_format;
        }
 
-       return err;
+       fw->data = blob;
+       fw->filename = name;
+
+       return 0;
 
 err_format:
        b43err(dev->wl, "Firmware file \"%s\" format error.\n", path);
+       release_firmware(blob);
+
        return -EPROTO;
 }
 
@@ -1624,90 +1654,101 @@ static int b43_request_firmware(struct b43_wldev *dev)
        u32 tmshigh;
        int err;
 
+       /* Get microcode */
        tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
-       if (!fw->ucode) {
+       if ((rev >= 5) && (rev <= 10))
+               filename = "ucode5";
+       else if ((rev >= 11) && (rev <= 12))
+               filename = "ucode11";
+       else if (rev >= 13)
+               filename = "ucode13";
+       else
+               goto err_no_ucode;
+       err = do_request_fw(dev, filename, &fw->ucode);
+       if (err)
+               goto err_load;
+
+       /* Get PCM code */
+       if ((rev >= 5) && (rev <= 10))
+               filename = "pcm5";
+       else if (rev >= 11)
+               filename = NULL;
+       else
+               goto err_no_pcm;
+       err = do_request_fw(dev, filename, &fw->pcm);
+       if (err)
+               goto err_load;
+
+       /* Get initvals */
+       switch (dev->phy.type) {
+       case B43_PHYTYPE_A:
+               if ((rev >= 5) && (rev <= 10)) {
+                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
+                               filename = "a0g1initvals5";
+                       else
+                               filename = "a0g0initvals5";
+               } else
+                       goto err_no_initvals;
+               break;
+       case B43_PHYTYPE_G:
                if ((rev >= 5) && (rev <= 10))
-                       filename = "ucode5";
-               else if ((rev >= 11) && (rev <= 12))
-                       filename = "ucode11";
+                       filename = "b0g0initvals5";
                else if (rev >= 13)
-                       filename = "ucode13";
+                       filename = "lp0initvals13";
                else
-                       goto err_no_ucode;
-               err = do_request_fw(dev, filename, &fw->ucode);
-               if (err)
-                       goto err_load;
+                       goto err_no_initvals;
+               break;
+       case B43_PHYTYPE_N:
+               if ((rev >= 11) && (rev <= 12))
+                       filename = "n0initvals11";
+               else
+                       goto err_no_initvals;
+               break;
+       default:
+               goto err_no_initvals;
        }
-       if (!fw->pcm) {
+       err = do_request_fw(dev, filename, &fw->initvals);
+       if (err)
+               goto err_load;
+
+       /* Get bandswitch initvals */
+       switch (dev->phy.type) {
+       case B43_PHYTYPE_A:
+               if ((rev >= 5) && (rev <= 10)) {
+                       if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
+                               filename = "a0g1bsinitvals5";
+                       else
+                               filename = "a0g0bsinitvals5";
+               } else if (rev >= 11)
+                       filename = NULL;
+               else
+                       goto err_no_initvals;
+               break;
+       case B43_PHYTYPE_G:
                if ((rev >= 5) && (rev <= 10))
-                       filename = "pcm5";
+                       filename = "b0g0bsinitvals5";
                else if (rev >= 11)
                        filename = NULL;
                else
-                       goto err_no_pcm;
-               err = do_request_fw(dev, filename, &fw->pcm);
-               if (err)
-                       goto err_load;
-       }
-       if (!fw->initvals) {
-               switch (dev->phy.type) {
-               case B43_PHYTYPE_A:
-                       if ((rev >= 5) && (rev <= 10)) {
-                               if (tmshigh & B43_TMSHIGH_GPHY)
-                                       filename = "a0g1initvals5";
-                               else
-                                       filename = "a0g0initvals5";
-                       } else
-                               goto err_no_initvals;
-                       break;
-               case B43_PHYTYPE_G:
-                       if ((rev >= 5) && (rev <= 10))
-                               filename = "b0g0initvals5";
-                       else if (rev >= 13)
-                               filename = "lp0initvals13";
-                       else
-                               goto err_no_initvals;
-                       break;
-               default:
                        goto err_no_initvals;
-               }
-               err = do_request_fw(dev, filename, &fw->initvals);
-               if (err)
-                       goto err_load;
-       }
-       if (!fw->initvals_band) {
-               switch (dev->phy.type) {
-               case B43_PHYTYPE_A:
-                       if ((rev >= 5) && (rev <= 10)) {
-                               if (tmshigh & B43_TMSHIGH_GPHY)
-                                       filename = "a0g1bsinitvals5";
-                               else
-                                       filename = "a0g0bsinitvals5";
-                       } else if (rev >= 11)
-                               filename = NULL;
-                       else
-                               goto err_no_initvals;
-                       break;
-               case B43_PHYTYPE_G:
-                       if ((rev >= 5) && (rev <= 10))
-                               filename = "b0g0bsinitvals5";
-                       else if (rev >= 11)
-                               filename = NULL;
-                       else
-                               goto err_no_initvals;
-                       break;
-               default:
+               break;
+       case B43_PHYTYPE_N:
+               if ((rev >= 11) && (rev <= 12))
+                       filename = "n0bsinitvals11";
+               else
                        goto err_no_initvals;
-               }
-               err = do_request_fw(dev, filename, &fw->initvals_band);
-               if (err)
-                       goto err_load;
+               break;
+       default:
+               goto err_no_initvals;
        }
+       err = do_request_fw(dev, filename, &fw->initvals_band);
+       if (err)
+               goto err_load;
 
        return 0;
 
 err_load:
-       b43_print_fw_helptext(dev->wl);
+       b43_print_fw_helptext(dev->wl, 1);
        goto error;
 
 err_no_ucode:
@@ -1737,22 +1778,33 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        const __be32 *data;
        unsigned int i, len;
        u16 fwrev, fwpatch, fwdate, fwtime;
-       u32 tmp;
+       u32 tmp, macctl;
        int err = 0;
 
+       /* Jump the microcode PSM to offset 0 */
+       macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       B43_WARN_ON(macctl & B43_MACCTL_PSM_RUN);
+       macctl |= B43_MACCTL_PSM_JMP0;
+       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+       /* Zero out all microcode PSM registers and shared memory. */
+       for (i = 0; i < 64; i++)
+               b43_shm_write16(dev, B43_SHM_SCRATCH, i, 0);
+       for (i = 0; i < 4096; i += 2)
+               b43_shm_write16(dev, B43_SHM_SHARED, i, 0);
+
        /* Upload Microcode. */
-       data = (__be32 *) (dev->fw.ucode->data + hdr_len);
-       len = (dev->fw.ucode->size - hdr_len) / sizeof(__be32);
+       data = (__be32 *) (dev->fw.ucode.data->data + hdr_len);
+       len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32);
        b43_shm_control_word(dev, B43_SHM_UCODE | B43_SHM_AUTOINC_W, 0x0000);
        for (i = 0; i < len; i++) {
                b43_write32(dev, B43_MMIO_SHM_DATA, be32_to_cpu(data[i]));
                udelay(10);
        }
 
-       if (dev->fw.pcm) {
+       if (dev->fw.pcm.data) {
                /* Upload PCM data. */
-               data = (__be32 *) (dev->fw.pcm->data + hdr_len);
-               len = (dev->fw.pcm->size - hdr_len) / sizeof(__be32);
+               data = (__be32 *) (dev->fw.pcm.data->data + hdr_len);
+               len = (dev->fw.pcm.data->size - hdr_len) / sizeof(__be32);
                b43_shm_control_word(dev, B43_SHM_HW, 0x01EA);
                b43_write32(dev, B43_MMIO_SHM_DATA, 0x00004000);
                /* No need for autoinc bit in SHM_HW */
@@ -1764,9 +1816,12 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        }
 
        b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
-       b43_write32(dev, B43_MMIO_MACCTL,
-                   B43_MACCTL_PSM_RUN |
-                   B43_MACCTL_IHR_ENABLED | B43_MACCTL_INFRA);
+
+       /* Start the microcode PSM */
+       macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       macctl &= ~B43_MACCTL_PSM_JMP0;
+       macctl |= B43_MACCTL_PSM_RUN;
+       b43_write32(dev, B43_MMIO_MACCTL, macctl);
 
        /* Wait for the microcode to load and respond */
        i = 0;
@@ -1775,13 +1830,17 @@ static int b43_upload_microcode(struct b43_wldev *dev)
                if (tmp == B43_IRQ_MAC_SUSPENDED)
                        break;
                i++;
-               if (i >= 50) {
+               if (i >= 20) {
                        b43err(dev->wl, "Microcode not responding\n");
-                       b43_print_fw_helptext(dev->wl);
+                       b43_print_fw_helptext(dev->wl, 1);
                        err = -ENODEV;
-                       goto out;
+                       goto error;
+               }
+               msleep_interruptible(50);
+               if (signal_pending(current)) {
+                       err = -EINTR;
+                       goto error;
                }
-               udelay(10);
        }
        b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);       /* dummy read */
 
@@ -1795,10 +1854,9 @@ static int b43_upload_microcode(struct b43_wldev *dev)
                b43err(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from "
                       "binary drivers older than version 4.x is unsupported. "
                       "You must upgrade your firmware files.\n");
-               b43_print_fw_helptext(dev->wl);
-               b43_write32(dev, B43_MMIO_MACCTL, 0);
+               b43_print_fw_helptext(dev->wl, 1);
                err = -EOPNOTSUPP;
-               goto out;
+               goto error;
        }
        b43dbg(dev->wl, "Loading firmware version %u.%u "
               "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
@@ -1809,7 +1867,20 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        dev->fw.rev = fwrev;
        dev->fw.patch = fwpatch;
 
-      out:
+       if (b43_is_old_txhdr_format(dev)) {
+               b43warn(dev->wl, "You are using an old firmware image. "
+                       "Support for old firmware will be removed in July 2008.\n");
+               b43_print_fw_helptext(dev->wl, 0);
+       }
+
+       return 0;
+
+error:
+       macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       macctl &= ~B43_MACCTL_PSM_RUN;
+       macctl |= B43_MACCTL_PSM_JMP0;
+       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+
        return err;
 }
 
@@ -1869,7 +1940,7 @@ static int b43_write_initvals(struct b43_wldev *dev,
 
 err_format:
        b43err(dev->wl, "Initial Values Firmware file-format error.\n");
-       b43_print_fw_helptext(dev->wl);
+       b43_print_fw_helptext(dev->wl, 1);
 
        return -EPROTO;
 }
@@ -1883,19 +1954,19 @@ static int b43_upload_initvals(struct b43_wldev *dev)
        size_t count;
        int err;
 
-       hdr = (const struct b43_fw_header *)(fw->initvals->data);
-       ivals = (const struct b43_iv *)(fw->initvals->data + hdr_len);
+       hdr = (const struct b43_fw_header *)(fw->initvals.data->data);
+       ivals = (const struct b43_iv *)(fw->initvals.data->data + hdr_len);
        count = be32_to_cpu(hdr->size);
        err = b43_write_initvals(dev, ivals, count,
-                                fw->initvals->size - hdr_len);
+                                fw->initvals.data->size - hdr_len);
        if (err)
                goto out;
-       if (fw->initvals_band) {
-               hdr = (const struct b43_fw_header *)(fw->initvals_band->data);
-               ivals = (const struct b43_iv *)(fw->initvals_band->data + hdr_len);
+       if (fw->initvals_band.data) {
+               hdr = (const struct b43_fw_header *)(fw->initvals_band.data->data);
+               ivals = (const struct b43_iv *)(fw->initvals_band.data->data + hdr_len);
                count = be32_to_cpu(hdr->size);
                err = b43_write_initvals(dev, ivals, count,
-                                        fw->initvals_band->size - hdr_len);
+                                        fw->initvals_band.data->size - hdr_len);
                if (err)
                        goto out;
        }
@@ -1932,7 +2003,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
                mask |= 0x0180;
                set |= 0x0180;
        }
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
                b43_write16(dev, B43_MMIO_GPIO_MASK,
                            b43_read16(dev, B43_MMIO_GPIO_MASK)
                            | 0x0200);
@@ -2102,6 +2173,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
        switch (dev->phy.type) {
        case B43_PHYTYPE_A:
        case B43_PHYTYPE_G:
+       case B43_PHYTYPE_N:
                b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
                b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
                b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
@@ -2131,13 +2203,19 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
 
        switch (antenna) {
        case B43_ANTENNA0:
-               ant |= B43_TX4_PHY_ANT0;
+               ant |= B43_TXH_PHY_ANT0;
                break;
        case B43_ANTENNA1:
-               ant |= B43_TX4_PHY_ANT1;
+               ant |= B43_TXH_PHY_ANT1;
+               break;
+       case B43_ANTENNA2:
+               ant |= B43_TXH_PHY_ANT2;
+               break;
+       case B43_ANTENNA3:
+               ant |= B43_TXH_PHY_ANT3;
                break;
        case B43_ANTENNA_AUTO:
-               ant |= B43_TX4_PHY_ANTLAST;
+               ant |= B43_TXH_PHY_ANT01AUTO;
                break;
        default:
                B43_WARN_ON(1);
@@ -2147,15 +2225,15 @@ static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
 
        /* For Beacons */
        tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
-       tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;
+       tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, tmp);
        /* For ACK/CTS */
        tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL);
-       tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;
+       tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, tmp);
        /* For Probe Resposes */
        tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL);
-       tmp = (tmp & ~B43_TX4_PHY_ANT) | ant;
+       tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, tmp);
 }
 
@@ -2174,11 +2252,15 @@ static int b43_chip_init(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
        int err, tmp;
-       u32 value32;
+       u32 value32, macctl;
        u16 value16;
 
-       b43_write32(dev, B43_MMIO_MACCTL,
-                   B43_MACCTL_PSM_JMP0 | B43_MACCTL_IHR_ENABLED);
+       /* Initialize the MAC control */
+       macctl = B43_MACCTL_IHR_ENABLED | B43_MACCTL_SHM_ENABLED;
+       if (dev->phy.gmode)
+               macctl |= B43_MACCTL_GMODE;
+       macctl |= B43_MACCTL_INFRA;
+       b43_write32(dev, B43_MMIO_MACCTL, macctl);
 
        err = b43_request_firmware(dev);
        if (err)
@@ -2223,14 +2305,6 @@ static int b43_chip_init(struct b43_wldev *dev)
        b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
                    | B43_MACCTL_INFRA);
 
-       if (b43_using_pio(dev)) {
-               b43_write32(dev, 0x0210, 0x00000100);
-               b43_write32(dev, 0x0230, 0x00000100);
-               b43_write32(dev, 0x0250, 0x00000100);
-               b43_write32(dev, 0x0270, 0x00000100);
-               b43_shm_write16(dev, B43_SHM_SHARED, 0x0034, 0x0000);
-       }
-
        /* Probe Response Timeout value */
        /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */
        b43_shm_write16(dev, B43_SHM_SHARED, 0x0074, 0x0000);
@@ -2292,9 +2366,11 @@ static void b43_periodic_every60sec(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
 
+       if (phy->type != B43_PHYTYPE_G)
+               return;
        if (!b43_has_hardware_pctl(phy))
                b43_lo_g_ctl_mark_all_unused(dev);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
                b43_mac_suspend(dev);
                b43_calc_nrssi_slope(dev);
                if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) {
@@ -2346,6 +2422,9 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
        }
        b43_phy_xmitpower(dev); //FIXME: unless scanning?
        //TODO for APHY (temperature?)
+
+       atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+       wmb();
 }
 
 static void do_periodic_work(struct b43_wldev *dev)
@@ -2403,32 +2482,42 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev)
        queue_delayed_work(dev->wl->hw->workqueue, work, 0);
 }
 
-/* Validate access to the chip (SHM) */
+/* Check if communication with the device works correctly. */
 static int b43_validate_chipaccess(struct b43_wldev *dev)
 {
-       u32 value;
-       u32 shm_backup;
+       u32 v, backup;
 
-       shm_backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);
-       b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);
-       if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
-               goto error;
+       backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);
+
+       /* Check for read/write and endianness problems. */
        b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);
        if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0x55AAAA55)
                goto error;
-       b43_shm_write32(dev, B43_SHM_SHARED, 0, shm_backup);
-
-       value = b43_read32(dev, B43_MMIO_MACCTL);
-       if ((value | B43_MACCTL_GMODE) !=
-           (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))
+       b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);
+       if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
                goto error;
 
-       value = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
-       if (value)
+       b43_shm_write32(dev, B43_SHM_SHARED, 0, backup);
+
+       if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) {
+               /* The 32bit register shadows the two 16bit registers
+                * with update sideeffects. Validate this. */
+               b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
+               b43_write32(dev, B43_MMIO_TSF_CFP_START, 0xCCCCBBBB);
+               if (b43_read16(dev, B43_MMIO_TSF_CFP_START_LOW) != 0xBBBB)
+                       goto error;
+               if (b43_read16(dev, B43_MMIO_TSF_CFP_START_HIGH) != 0xCCCC)
+                       goto error;
+       }
+       b43_write32(dev, B43_MMIO_TSF_CFP_START, 0);
+
+       v = b43_read32(dev, B43_MMIO_MACCTL);
+       v |= B43_MACCTL_GMODE;
+       if (v != (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))
                goto error;
 
        return 0;
-      error:
+error:
        b43err(dev->wl, "Failed to validate the chipaccess\n");
        return -ENODEV;
 }
@@ -2491,40 +2580,35 @@ static int b43_rng_init(struct b43_wl *wl)
        return err;
 }
 
-static int b43_tx(struct ieee80211_hw *hw,
-                 struct sk_buff *skb, struct ieee80211_tx_control *ctl)
+static int b43_op_tx(struct ieee80211_hw *hw,
+                    struct sk_buff *skb,
+                    struct ieee80211_tx_control *ctl)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
        int err = -ENODEV;
-       unsigned long flags;
 
        if (unlikely(!dev))
                goto out;
        if (unlikely(b43_status(dev) < B43_STAT_STARTED))
                goto out;
        /* DMA-TX is done without a global lock. */
-       if (b43_using_pio(dev)) {
-               spin_lock_irqsave(&wl->irq_lock, flags);
-               err = b43_pio_tx(dev, skb, ctl);
-               spin_unlock_irqrestore(&wl->irq_lock, flags);
-       } else
-               err = b43_dma_tx(dev, skb, ctl);
-      out:
+       err = b43_dma_tx(dev, skb, ctl);
+out:
        if (unlikely(err))
                return NETDEV_TX_BUSY;
        return NETDEV_TX_OK;
 }
 
-static int b43_conf_tx(struct ieee80211_hw *hw,
-                      int queue,
-                      const struct ieee80211_tx_queue_params *params)
+static int b43_op_conf_tx(struct ieee80211_hw *hw,
+                         int queue,
+                         const struct ieee80211_tx_queue_params *params)
 {
        return 0;
 }
 
-static int b43_get_tx_stats(struct ieee80211_hw *hw,
-                           struct ieee80211_tx_queue_stats *stats)
+static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
+                              struct ieee80211_tx_queue_stats *stats)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
@@ -2535,19 +2619,16 @@ static int b43_get_tx_stats(struct ieee80211_hw *hw,
                goto out;
        spin_lock_irqsave(&wl->irq_lock, flags);
        if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
-               if (b43_using_pio(dev))
-                       b43_pio_get_tx_stats(dev, stats);
-               else
-                       b43_dma_get_tx_stats(dev, stats);
+               b43_dma_get_tx_stats(dev, stats);
                err = 0;
        }
        spin_unlock_irqrestore(&wl->irq_lock, flags);
-      out:
+out:
        return err;
 }
 
-static int b43_get_stats(struct ieee80211_hw *hw,
-                        struct ieee80211_low_level_stats *stats)
+static int b43_op_get_stats(struct ieee80211_hw *hw,
+                           struct ieee80211_low_level_stats *stats)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        unsigned long flags;
@@ -2686,8 +2767,36 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode)
        return err;
 }
 
-static int b43_antenna_from_ieee80211(u8 antenna)
+/* Check if the use of the antenna that ieee80211 told us to
+ * use is possible. This will fall back to DEFAULT.
+ * "antenna_nr" is the antenna identifier we got from ieee80211. */
+u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
+                                 u8 antenna_nr)
+{
+       u8 antenna_mask;
+
+       if (antenna_nr == 0) {
+               /* Zero means "use default antenna". That's always OK. */
+               return 0;
+       }
+
+       /* Get the mask of available antennas. */
+       if (dev->phy.gmode)
+               antenna_mask = dev->dev->bus->sprom.ant_available_bg;
+       else
+               antenna_mask = dev->dev->bus->sprom.ant_available_a;
+
+       if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
+               /* This antenna is not available. Fall back to default. */
+               return 0;
+       }
+
+       return antenna_nr;
+}
+
+static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
 {
+       antenna = b43_ieee80211_antenna_sanitize(dev, antenna);
        switch (antenna) {
        case 0:         /* default/diversity */
                return B43_ANTENNA_DEFAULT;
@@ -2695,26 +2804,26 @@ static int b43_antenna_from_ieee80211(u8 antenna)
                return B43_ANTENNA0;
        case 2:         /* Antenna 1 */
                return B43_ANTENNA1;
+       case 3:         /* Antenna 2 */
+               return B43_ANTENNA2;
+       case 4:         /* Antenna 3 */
+               return B43_ANTENNA3;
        default:
                return B43_ANTENNA_DEFAULT;
        }
 }
 
-static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
        struct b43_phy *phy;
        unsigned long flags;
        unsigned int new_phymode = 0xFFFF;
-       int antenna_tx;
-       int antenna_rx;
+       int antenna;
        int err = 0;
        u32 savedirqs;
 
-       antenna_tx = b43_antenna_from_ieee80211(conf->antenna_sel_tx);
-       antenna_rx = b43_antenna_from_ieee80211(conf->antenna_sel_rx);
-
        mutex_lock(&wl->mutex);
 
        /* Switch the PHY mode (if necessary). */
@@ -2764,6 +2873,8 @@ static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
                        b43_short_slot_timing_disable(dev);
        }
 
+       dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+
        /* Adjust the desired TX power level. */
        if (conf->power_level != 0) {
                if (conf->power_level != phy->power_level) {
@@ -2773,8 +2884,10 @@ static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        }
 
        /* Antennas for RX and management frame TX. */
-       b43_mgmtframe_txantenna(dev, antenna_tx);
-       b43_set_rx_antenna(dev, antenna_rx);
+       antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
+       b43_mgmtframe_txantenna(dev, antenna);
+       antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
+       b43_set_rx_antenna(dev, antenna);
 
        /* Update templates for AP mode. */
        if (b43_is_mode(wl, IEEE80211_IF_TYPE_AP))
@@ -2805,23 +2918,30 @@ static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
        return err;
 }
 
-static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                           const u8 *local_addr, const u8 *addr,
                           struct ieee80211_key_conf *key)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
-       struct b43_wldev *dev = wl->current_dev;
+       struct b43_wldev *dev;
        unsigned long flags;
        u8 algorithm;
        u8 index;
-       int err = -EINVAL;
+       int err;
        DECLARE_MAC_BUF(mac);
 
        if (modparam_nohwcrypt)
                return -ENOSPC; /* User disabled HW-crypto */
 
-       if (!dev)
-               return -ENODEV;
+       mutex_lock(&wl->mutex);
+       spin_lock_irqsave(&wl->irq_lock, flags);
+
+       dev = wl->current_dev;
+       err = -ENODEV;
+       if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
+               goto out_unlock;
+
+       err = -EINVAL;
        switch (key->alg) {
        case ALG_WEP:
                if (key->keylen == 5)
@@ -2837,20 +2957,11 @@ static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                break;
        default:
                B43_WARN_ON(1);
-               goto out;
+               goto out_unlock;
        }
-
        index = (u8) (key->keyidx);
        if (index > 3)
-               goto out;
-
-       mutex_lock(&wl->mutex);
-       spin_lock_irqsave(&wl->irq_lock, flags);
-
-       if (b43_status(dev) < B43_STAT_INITIALIZED) {
-               err = -ENODEV;
                goto out_unlock;
-       }
 
        switch (cmd) {
        case SET_KEY:
@@ -2896,7 +3007,6 @@ static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 out_unlock:
        spin_unlock_irqrestore(&wl->irq_lock, flags);
        mutex_unlock(&wl->mutex);
-out:
        if (!err) {
                b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
                       "mac: %s\n",
@@ -2906,9 +3016,9 @@ out:
        return err;
 }
 
-static void b43_configure_filter(struct ieee80211_hw *hw,
-                                unsigned int changed, unsigned int *fflags,
-                                int mc_count, struct dev_addr_list *mc_list)
+static void b43_op_configure_filter(struct ieee80211_hw *hw,
+                                   unsigned int changed, unsigned int *fflags,
+                                   int mc_count, struct dev_addr_list *mc_list)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
@@ -2943,8 +3053,9 @@ static void b43_configure_filter(struct ieee80211_hw *hw,
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 }
 
-static int b43_config_interface(struct ieee80211_hw *hw,
-                               int if_id, struct ieee80211_if_conf *conf)
+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;
@@ -2954,7 +3065,7 @@ static int b43_config_interface(struct ieee80211_hw *hw,
                return -ENODEV;
        mutex_lock(&wl->mutex);
        spin_lock_irqsave(&wl->irq_lock, flags);
-       B43_WARN_ON(wl->if_id != if_id);
+       B43_WARN_ON(wl->vif != vif);
        if (conf->bssid)
                memcpy(wl->bssid, conf->bssid, ETH_ALEN);
        else
@@ -2964,7 +3075,7 @@ static int b43_config_interface(struct ieee80211_hw *hw,
                        B43_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP);
                        b43_set_ssid(dev, conf->ssid, conf->ssid_len);
                        if (conf->beacon)
-                               b43_refresh_templates(dev, conf->beacon);
+                               b43_update_templates(wl, conf->beacon);
                }
                b43_write_mac_bssid_templates(dev);
        }
@@ -3067,9 +3178,15 @@ static int b43_phy_versioning(struct b43_wldev *dev)
                        unsupported = 1;
                break;
        case B43_PHYTYPE_G:
-               if (phy_rev > 8)
+               if (phy_rev > 9)
                        unsupported = 1;
                break;
+#ifdef CONFIG_B43_NPHY
+       case B43_PHYTYPE_N:
+               if (phy_rev > 1)
+                       unsupported = 1;
+               break;
+#endif
        default:
                unsupported = 1;
        };
@@ -3092,14 +3209,15 @@ static int b43_phy_versioning(struct b43_wldev *dev)
                        tmp = 0x5205017F;
        } else {
                b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
-               tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH);
-               tmp <<= 16;
+               tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
                b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID);
-               tmp |= b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
+               tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16;
        }
        radio_manuf = (tmp & 0x00000FFF);
        radio_ver = (tmp & 0x0FFFF000) >> 12;
        radio_rev = (tmp & 0xF0000000) >> 28;
+       if (radio_manuf != 0x17F /* Broadcom */)
+               unsupported = 1;
        switch (phy_type) {
        case B43_PHYTYPE_A:
                if (radio_ver != 0x2060)
@@ -3117,6 +3235,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
                if (radio_ver != 0x2050)
                        unsupported = 1;
                break;
+       case B43_PHYTYPE_N:
+               if (radio_ver != 0x2055)
+                       unsupported = 1;
+               break;
        default:
                B43_WARN_ON(1);
        }
@@ -3149,9 +3271,6 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev,
        memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
        memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
 
-       /* Flags */
-       phy->locked = 0;
-
        phy->aci_enable = 0;
        phy->aci_wlan_automatic = 0;
        phy->aci_hw_rssi = 0;
@@ -3178,17 +3297,22 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev,
        phy->lofcal = 0xFFFF;
        phy->initval = 0xFFFF;
 
-       spin_lock_init(&phy->lock);
        phy->interfmode = B43_INTERFMODE_NONE;
        phy->channel = 0xFF;
 
        phy->hardware_power_control = !!modparam_hwpctl;
+
+       /* PHY TX errors counter. */
+       atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
+
+       /* OFDM-table address caching. */
+       phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_UNKNOWN;
 }
 
 static void setup_struct_wldev_for_init(struct b43_wldev *dev)
 {
-       /* Flags */
-       dev->reg124_set_0x4 = 0;
+       dev->dfq_valid = 0;
+
        /* Assume the radio is enabled. If it's not enabled, the state will
         * immediately get fixed on the first periodic work run. */
        dev->radio_hw_enable = 1;
@@ -3214,13 +3338,13 @@ static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
        struct ssb_sprom *sprom = &dev->dev->bus->sprom;
        u32 hf;
 
-       if (!(sprom->r1.boardflags_lo & B43_BFL_BTCOEXIST))
+       if (!(sprom->boardflags_lo & B43_BFL_BTCOEXIST))
                return;
        if (dev->phy.type != B43_PHYTYPE_B && !dev->phy.gmode)
                return;
 
        hf = b43_hf_read(dev);
-       if (sprom->r1.boardflags_lo & B43_BFL_BTCMOD)
+       if (sprom->boardflags_lo & B43_BFL_BTCMOD)
                hf |= B43_HF_BTCOEXALT;
        else
                hf |= B43_HF_BTCOEX;
@@ -3259,20 +3383,42 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
+/* Write the short and long frame retry limit values. */
+static void b43_set_retry_limits(struct b43_wldev *dev,
+                                unsigned int short_retry,
+                                unsigned int long_retry)
+{
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
+                       short_retry);
+       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
+                       long_retry);
+}
+
 /* Shutdown a wireless core */
 /* Locking: wl->mutex */
 static void b43_wireless_core_exit(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
+       u32 macctl;
 
        B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
        if (b43_status(dev) != B43_STAT_INITIALIZED)
                return;
        b43_set_status(dev, B43_STAT_UNINIT);
 
+       /* Stop the microcode PSM. */
+       macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       macctl &= ~B43_MACCTL_PSM_RUN;
+       macctl |= B43_MACCTL_PSM_JMP0;
+       b43_write32(dev, B43_MMIO_MACCTL, macctl);
+
        b43_leds_exit(dev);
        b43_rng_exit(dev->wl);
-       b43_pio_free(dev);
        b43_dma_free(dev);
        b43_chip_exit(dev);
        b43_radio_turn_off(dev, 1);
@@ -3281,6 +3427,11 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
                kfree(phy->tssi2dbm);
        kfree(phy->lo_control);
        phy->lo_control = NULL;
+       if (dev->wl->current_beacon) {
+               dev_kfree_skb_any(dev->wl->current_beacon);
+               dev->wl->current_beacon = NULL;
+       }
+
        ssb_device_disable(dev->dev, 0);
        ssb_bus_may_powerdown(dev->dev->bus);
 }
@@ -3335,7 +3486,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
                hf |= B43_HF_SYMW;
                if (phy->rev == 1)
                        hf |= B43_HF_GDCW;
-               if (sprom->r1.boardflags_lo & B43_BFL_PACTRL)
+               if (sprom->boardflags_lo & B43_BFL_PACTRL)
                        hf |= B43_HF_OFDMPABOOST;
        } else if (phy->type == B43_PHYTYPE_B) {
                hf |= B43_HF_SYMW;
@@ -3344,15 +3495,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        }
        b43_hf_write(dev, hf);
 
-       /* Short/Long Retry Limit.
-        * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter.
-        */
-       tmp = limit_value(modparam_short_retry, 0, 0xF);
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT, tmp);
-       tmp = limit_value(modparam_long_retry, 0, 0xF);
-       b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT, tmp);
-
+       b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
+                            B43_DEFAULT_LONG_RETRY_LIMIT);
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3);
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_LFFBLIM, 2);
 
@@ -3373,17 +3517,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
        /* Maximum Contention Window */
        b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
 
-       do {
-               if (b43_using_pio(dev)) {
-                       err = b43_pio_init(dev);
-               } else {
-                       err = b43_dma_init(dev);
-                       if (!err)
-                               b43_qos_init(dev);
-               }
-       } while (err == -EAGAIN);
+       err = b43_dma_init(dev);
        if (err)
                goto err_chip_exit;
+       b43_qos_init(dev);
 
 //FIXME
 #if 1
@@ -3421,8 +3558,8 @@ out:
        return err;
 }
 
-static int b43_add_interface(struct ieee80211_hw *hw,
-                            struct ieee80211_if_init_conf *conf)
+static int b43_op_add_interface(struct ieee80211_hw *hw,
+                               struct ieee80211_if_init_conf *conf)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
@@ -3445,7 +3582,7 @@ static int b43_add_interface(struct ieee80211_hw *hw,
 
        dev = wl->current_dev;
        wl->operating = 1;
-       wl->if_id = conf->if_id;
+       wl->vif = conf->vif;
        wl->if_type = conf->type;
        memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
 
@@ -3461,8 +3598,8 @@ static int b43_add_interface(struct ieee80211_hw *hw,
        return err;
 }
 
-static void b43_remove_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_if_init_conf *conf)
+static void b43_op_remove_interface(struct ieee80211_hw *hw,
+                                   struct ieee80211_if_init_conf *conf)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
@@ -3473,7 +3610,8 @@ static void b43_remove_interface(struct ieee80211_hw *hw,
        mutex_lock(&wl->mutex);
 
        B43_WARN_ON(!wl->operating);
-       B43_WARN_ON(wl->if_id != conf->if_id);
+       B43_WARN_ON(wl->vif != conf->vif);
+       wl->vif = NULL;
 
        wl->operating = 0;
 
@@ -3486,7 +3624,7 @@ static void b43_remove_interface(struct ieee80211_hw *hw,
        mutex_unlock(&wl->mutex);
 }
 
-static int b43_start(struct ieee80211_hw *hw)
+static int b43_op_start(struct ieee80211_hw *hw)
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
@@ -3521,7 +3659,7 @@ static int b43_start(struct ieee80211_hw *hw)
        return err;
 }
 
-static void b43_stop(struct ieee80211_hw *hw)
+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;
@@ -3535,19 +3673,76 @@ static void b43_stop(struct ieee80211_hw *hw)
        mutex_unlock(&wl->mutex);
 }
 
+static int b43_op_set_retry_limit(struct ieee80211_hw *hw,
+                                 u32 short_retry_limit, u32 long_retry_limit)
+{
+       struct b43_wl *wl = hw_to_b43_wl(hw);
+       struct b43_wldev *dev;
+       int err = 0;
+
+       mutex_lock(&wl->mutex);
+       dev = wl->current_dev;
+       if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) {
+               err = -ENODEV;
+               goto out_unlock;
+       }
+       b43_set_retry_limits(dev, short_retry_limit, long_retry_limit);
+out_unlock:
+       mutex_unlock(&wl->mutex);
+
+       return err;
+}
+
+static int b43_op_beacon_set_tim(struct ieee80211_hw *hw, int aid, int set)
+{
+       struct b43_wl *wl = hw_to_b43_wl(hw);
+       struct sk_buff *beacon;
+       unsigned long flags;
+
+       /* We could modify the existing beacon and set the aid bit in
+        * the TIM field, but that would probably require resizing and
+        * moving of data within the beacon template.
+        * Simply request a new beacon and let mac80211 do the hard work. */
+       beacon = ieee80211_beacon_get(hw, wl->vif, NULL);
+       if (unlikely(!beacon))
+               return -ENOMEM;
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       b43_update_templates(wl, beacon);
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+
+       return 0;
+}
+
+static int b43_op_ibss_beacon_update(struct ieee80211_hw *hw,
+                                    struct sk_buff *beacon,
+                                    struct ieee80211_tx_control *ctl)
+{
+       struct b43_wl *wl = hw_to_b43_wl(hw);
+       unsigned long flags;
+
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       b43_update_templates(wl, beacon);
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+
+       return 0;
+}
+
 static const struct ieee80211_ops b43_hw_ops = {
-       .tx = b43_tx,
-       .conf_tx = b43_conf_tx,
-       .add_interface = b43_add_interface,
-       .remove_interface = b43_remove_interface,
-       .config = b43_dev_config,
-       .config_interface = b43_config_interface,
-       .configure_filter = b43_configure_filter,
-       .set_key = b43_dev_set_key,
-       .get_stats = b43_get_stats,
-       .get_tx_stats = b43_get_tx_stats,
-       .start = b43_start,
-       .stop = b43_stop,
+       .tx                     = b43_op_tx,
+       .conf_tx                = b43_op_conf_tx,
+       .add_interface          = b43_op_add_interface,
+       .remove_interface       = b43_op_remove_interface,
+       .config                 = b43_op_config,
+       .config_interface       = b43_op_config_interface,
+       .configure_filter       = b43_op_configure_filter,
+       .set_key                = b43_op_set_key,
+       .get_stats              = b43_op_get_stats,
+       .get_tx_stats           = b43_op_get_tx_stats,
+       .start                  = b43_op_start,
+       .stop                   = b43_op_stop,
+       .set_retry_limit        = b43_op_set_retry_limit,
+       .set_tim                = b43_op_beacon_set_tim,
+       .beacon_update          = b43_op_ibss_beacon_update,
 };
 
 /* Hard-reset the chip. Do not call this directly.
@@ -3592,72 +3787,30 @@ static void b43_chip_reset(struct work_struct *work)
 }
 
 static int b43_setup_modes(struct b43_wldev *dev,
-                          int have_aphy, int have_bphy, int have_gphy)
+                          bool have_2ghz_phy, bool have_5ghz_phy)
 {
        struct ieee80211_hw *hw = dev->wl->hw;
        struct ieee80211_hw_mode *mode;
        struct b43_phy *phy = &dev->phy;
-       int cnt = 0;
        int err;
 
-/*FIXME: Don't tell ieee80211 about an A-PHY, because we currently don't support A-PHY. */
-       have_aphy = 0;
-
-       phy->possible_phymodes = 0;
-       for (; 1; cnt++) {
-               if (have_aphy) {
-                       B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
-                       mode = &phy->hwmodes[cnt];
-
-                       mode->mode = MODE_IEEE80211A;
-                       mode->num_channels = b43_a_chantable_size;
-                       mode->channels = b43_a_chantable;
-                       mode->num_rates = b43_a_ratetable_size;
-                       mode->rates = b43_a_ratetable;
-                       err = ieee80211_register_hwmode(hw, mode);
-                       if (err)
-                               return err;
-
-                       phy->possible_phymodes |= B43_PHYMODE_A;
-                       have_aphy = 0;
-                       continue;
-               }
-               if (have_bphy) {
-                       B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
-                       mode = &phy->hwmodes[cnt];
-
-                       mode->mode = MODE_IEEE80211B;
-                       mode->num_channels = b43_bg_chantable_size;
-                       mode->channels = b43_bg_chantable;
-                       mode->num_rates = b43_b_ratetable_size;
-                       mode->rates = b43_b_ratetable;
-                       err = ieee80211_register_hwmode(hw, mode);
-                       if (err)
-                               return err;
-
-                       phy->possible_phymodes |= B43_PHYMODE_B;
-                       have_bphy = 0;
-                       continue;
-               }
-               if (have_gphy) {
-                       B43_WARN_ON(cnt >= B43_MAX_PHYHWMODES);
-                       mode = &phy->hwmodes[cnt];
-
-                       mode->mode = MODE_IEEE80211G;
-                       mode->num_channels = b43_bg_chantable_size;
-                       mode->channels = b43_bg_chantable;
-                       mode->num_rates = b43_g_ratetable_size;
-                       mode->rates = b43_g_ratetable;
-                       err = ieee80211_register_hwmode(hw, mode);
-                       if (err)
-                               return err;
-
-                       phy->possible_phymodes |= B43_PHYMODE_G;
-                       have_gphy = 0;
-                       continue;
-               }
-               break;
-       }
+       /* XXX: This function will go away soon, when mac80211
+        *      band stuff is rewritten. So this is just a hack.
+        *      For now we always claim GPHY mode, as there is no
+        *      support for NPHY and APHY in the device, yet.
+        *      This assumption is OK, as any B, N or A PHY will already
+        *      have died a horrible sanity check death earlier. */
+
+       mode = &phy->hwmodes[0];
+       mode->mode = MODE_IEEE80211G;
+       mode->num_channels = b43_2ghz_chantable_size;
+       mode->channels = b43_2ghz_chantable;
+       mode->num_rates = b43_g_ratetable_size;
+       mode->rates = b43_g_ratetable;
+       err = ieee80211_register_hwmode(hw, mode);
+       if (err)
+               return err;
+       phy->possible_phymodes |= B43_PHYMODE_G;
 
        return 0;
 }
@@ -3675,7 +3828,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
        struct ssb_bus *bus = dev->dev->bus;
        struct pci_dev *pdev = bus->host_pci;
        int err;
-       int have_aphy = 0, have_bphy = 0, have_gphy = 0;
+       bool have_2ghz_phy = 0, have_5ghz_phy = 0;
        u32 tmp;
 
        /* Do NOT do any device initialization here.
@@ -3695,17 +3848,12 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
                u32 tmshigh;
 
                tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
-               have_aphy = !!(tmshigh & B43_TMSHIGH_APHY);
-               have_gphy = !!(tmshigh & B43_TMSHIGH_GPHY);
-               if (!have_aphy && !have_gphy)
-                       have_bphy = 1;
-       } else if (dev->dev->id.revision == 4) {
-               have_gphy = 1;
-               have_aphy = 1;
+               have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
+               have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
        } else
-               have_bphy = 1;
+               B43_WARN_ON(1);
 
-       dev->phy.gmode = (have_gphy || have_bphy);
+       dev->phy.gmode = have_2ghz_phy;
        tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
        b43_wireless_core_reset(dev, tmp);
 
@@ -3717,31 +3865,34 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
            (pdev->device != 0x4312 &&
             pdev->device != 0x4319 && pdev->device != 0x4324)) {
                /* No multiband support. */
-               have_aphy = 0;
-               have_bphy = 0;
-               have_gphy = 0;
+               have_2ghz_phy = 0;
+               have_5ghz_phy = 0;
                switch (dev->phy.type) {
                case B43_PHYTYPE_A:
-                       have_aphy = 1;
-                       break;
-               case B43_PHYTYPE_B:
-                       have_bphy = 1;
+                       have_5ghz_phy = 1;
                        break;
                case B43_PHYTYPE_G:
-                       have_gphy = 1;
+               case B43_PHYTYPE_N:
+                       have_2ghz_phy = 1;
                        break;
                default:
                        B43_WARN_ON(1);
                }
        }
-       dev->phy.gmode = (have_gphy || have_bphy);
+       if (dev->phy.type == B43_PHYTYPE_A) {
+               /* FIXME */
+               b43err(wl, "IEEE 802.11a devices are unsupported\n");
+               err = -EOPNOTSUPP;
+               goto err_powerdown;
+       }
+       dev->phy.gmode = have_2ghz_phy;
        tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0;
        b43_wireless_core_reset(dev, tmp);
 
        err = b43_validate_chipaccess(dev);
        if (err)
                goto err_powerdown;
-       err = b43_setup_modes(dev, have_aphy, have_bphy, have_gphy);
+       err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy);
        if (err)
                goto err_powerdown;
 
@@ -3812,8 +3963,6 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
        tasklet_init(&wldev->isr_tasklet,
                     (void (*)(unsigned long))b43_interrupt_tasklet,
                     (unsigned long)wldev);
-       if (modparam_pio)
-               wldev->__using_pio = 1;
        INIT_LIST_HEAD(&wldev->list);
 
        err = b43_wireless_core_attach(wldev);
@@ -3838,20 +3987,10 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
        /* boardflags workarounds */
        if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
            bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74)
-               bus->sprom.r1.boardflags_lo |= B43_BFL_BTCOEXIST;
+               bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST;
        if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
            bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40)
-               bus->sprom.r1.boardflags_lo |= B43_BFL_PACTRL;
-
-       /* Handle case when gain is not set in sprom */
-       if (bus->sprom.r1.antenna_gain_a == 0xFF)
-               bus->sprom.r1.antenna_gain_a = 2;
-       if (bus->sprom.r1.antenna_gain_bg == 0xFF)
-               bus->sprom.r1.antenna_gain_bg = 2;
-
-       /* Convert Antennagain values to Q5.2 */
-       bus->sprom.r1.antenna_gain_a <<= 2;
-       bus->sprom.r1.antenna_gain_bg <<= 2;
+               bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
 }
 
 static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
@@ -3878,16 +4017,17 @@ static int b43_wireless_init(struct ssb_device *dev)
        }
 
        /* fill hw info */
-       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
+       hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
+                   IEEE80211_HW_RX_INCLUDES_FCS;
        hw->max_signal = 100;
        hw->max_rssi = -110;
        hw->max_noise = -110;
        hw->queues = 1;         /* FIXME: hardware has more queues */
        SET_IEEE80211_DEV(hw, dev->dev);
-       if (is_valid_ether_addr(sprom->r1.et1mac))
-               SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac);
+       if (is_valid_ether_addr(sprom->et1mac))
+               SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
        else
-               SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac);
+               SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
 
        /* Get and initialize struct b43_wl */
        wl = hw_to_b43_wl(hw);
@@ -3895,6 +4035,7 @@ static int b43_wireless_init(struct ssb_device *dev)
        wl->hw = hw;
        spin_lock_init(&wl->irq_lock);
        spin_lock_init(&wl->leds_lock);
+       spin_lock_init(&wl->shm_lock);
        mutex_init(&wl->mutex);
        INIT_LIST_HEAD(&wl->devlist);
 
index 08e2e56e48f493ddd9ade9f66992606819f5a1b1..2d52d9de93052ecf82d775d7ccf1a05fd8cdf0d8 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43 wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                     Stefano Brivio <st3@riseup.net>
+                     Stefano Brivio <stefano.brivio@polimi.it>
                      Michael Buesch <mb@bu3sch.de>
                      Danny van Dyk <kugelfang@gentoo.org>
                      Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -84,6 +84,9 @@ static inline int b43_is_ofdm_rate(int rate)
        return !b43_is_cck_rate(rate);
 }
 
+u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
+                                 u8 antenna_nr);
+
 void b43_tsf_read(struct b43_wldev *dev, u64 * tsf);
 void b43_tsf_write(struct b43_wldev *dev, u64 tsf);
 
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c
new file mode 100644 (file)
index 0000000..705131e
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n PHY support
+
+  Copyright (c) 2008 Michael Buesch <mb@bu3sch.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, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include "b43.h"
+#include "nphy.h"
+#include "tables_nphy.h"
+
+#include <linux/delay.h>
+
+
+void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
+{//TODO
+}
+
+void b43_nphy_xmitpower(struct b43_wldev *dev)
+{//TODO
+}
+
+static void b43_chantab_radio_upload(struct b43_wldev *dev,
+                                    const struct b43_nphy_channeltab_entry *e)
+{
+       b43_radio_write16(dev, B2055_PLL_REF, e->radio_pll_ref);
+       b43_radio_write16(dev, B2055_RF_PLLMOD0, e->radio_rf_pllmod0);
+       b43_radio_write16(dev, B2055_RF_PLLMOD1, e->radio_rf_pllmod1);
+       b43_radio_write16(dev, B2055_VCO_CAPTAIL, e->radio_vco_captail);
+       b43_radio_write16(dev, B2055_VCO_CAL1, e->radio_vco_cal1);
+       b43_radio_write16(dev, B2055_VCO_CAL2, e->radio_vco_cal2);
+       b43_radio_write16(dev, B2055_PLL_LFC1, e->radio_pll_lfc1);
+       b43_radio_write16(dev, B2055_PLL_LFR1, e->radio_pll_lfr1);
+       b43_radio_write16(dev, B2055_PLL_LFC2, e->radio_pll_lfc2);
+       b43_radio_write16(dev, B2055_LGBUF_CENBUF, e->radio_lgbuf_cenbuf);
+       b43_radio_write16(dev, B2055_LGEN_TUNE1, e->radio_lgen_tune1);
+       b43_radio_write16(dev, B2055_LGEN_TUNE2, e->radio_lgen_tune2);
+       b43_radio_write16(dev, B2055_C1_LGBUF_ATUNE, e->radio_c1_lgbuf_atune);
+       b43_radio_write16(dev, B2055_C1_LGBUF_GTUNE, e->radio_c1_lgbuf_gtune);
+       b43_radio_write16(dev, B2055_C1_RX_RFR1, e->radio_c1_rx_rfr1);
+       b43_radio_write16(dev, B2055_C1_TX_PGAPADTN, e->radio_c1_tx_pgapadtn);
+       b43_radio_write16(dev, B2055_C1_TX_MXBGTRIM, e->radio_c1_tx_mxbgtrim);
+       b43_radio_write16(dev, B2055_C2_LGBUF_ATUNE, e->radio_c2_lgbuf_atune);
+       b43_radio_write16(dev, B2055_C2_LGBUF_GTUNE, e->radio_c2_lgbuf_gtune);
+       b43_radio_write16(dev, B2055_C2_RX_RFR1, e->radio_c2_rx_rfr1);
+       b43_radio_write16(dev, B2055_C2_TX_PGAPADTN, e->radio_c2_tx_pgapadtn);
+       b43_radio_write16(dev, B2055_C2_TX_MXBGTRIM, e->radio_c2_tx_mxbgtrim);
+}
+
+static void b43_chantab_phy_upload(struct b43_wldev *dev,
+                                  const struct b43_nphy_channeltab_entry *e)
+{
+       b43_phy_write(dev, B43_NPHY_BW1A, e->phy_bw1a);
+       b43_phy_write(dev, B43_NPHY_BW2, e->phy_bw2);
+       b43_phy_write(dev, B43_NPHY_BW3, e->phy_bw3);
+       b43_phy_write(dev, B43_NPHY_BW4, e->phy_bw4);
+       b43_phy_write(dev, B43_NPHY_BW5, e->phy_bw5);
+       b43_phy_write(dev, B43_NPHY_BW6, e->phy_bw6);
+}
+
+static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
+{
+       //TODO
+}
+
+/* Tune the hardware to a new channel. Don't call this directly.
+ * Use b43_radio_selectchannel() */
+int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel)
+{
+       const struct b43_nphy_channeltab_entry *tabent;
+
+       tabent = b43_nphy_get_chantabent(dev, channel);
+       if (!tabent)
+               return -ESRCH;
+
+       //FIXME enable/disable band select upper20 in RXCTL
+       if (0 /*FIXME 5Ghz*/)
+               b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x20);
+       else
+               b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, 0x50);
+       b43_chantab_radio_upload(dev, tabent);
+       udelay(50);
+       b43_radio_write16(dev, B2055_VCO_CAL10, 5);
+       b43_radio_write16(dev, B2055_VCO_CAL10, 45);
+       b43_radio_write16(dev, B2055_VCO_CAL10, 65);
+       udelay(300);
+       if (0 /*FIXME 5Ghz*/)
+               b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
+       else
+               b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
+       b43_chantab_phy_upload(dev, tabent);
+       b43_nphy_tx_power_fix(dev);
+
+       return 0;
+}
+
+static void b43_radio_init2055_pre(struct b43_wldev *dev)
+{
+       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+                    ~B43_NPHY_RFCTL_CMD_PORFORCE);
+       b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+                   B43_NPHY_RFCTL_CMD_CHIP0PU |
+                   B43_NPHY_RFCTL_CMD_OEPORFORCE);
+       b43_phy_set(dev, B43_NPHY_RFCTL_CMD,
+                   B43_NPHY_RFCTL_CMD_PORFORCE);
+}
+
+static void b43_radio_init2055_post(struct b43_wldev *dev)
+{
+       struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+       struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
+       int i;
+       u16 val;
+
+       b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
+       msleep(1);
+       if ((sprom->revision != 4) || !(sprom->boardflags_hi & 0x0002)) {
+               if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
+                   (binfo->type != 0x46D) ||
+                   (binfo->rev < 0x41)) {
+                       b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
+                       b43_radio_mask(dev, B2055_C1_RX_BB_REG, 0x7F);
+                       msleep(1);
+               }
+       }
+       b43_radio_maskset(dev, B2055_RRCCAL_NOPTSEL, 0x3F, 0x2C);
+       msleep(1);
+       b43_radio_write16(dev, B2055_CAL_MISC, 0x3C);
+       msleep(1);
+       b43_radio_mask(dev, B2055_CAL_MISC, 0xFFBE);
+       msleep(1);
+       b43_radio_set(dev, B2055_CAL_LPOCTL, 0x80);
+       msleep(1);
+       b43_radio_set(dev, B2055_CAL_MISC, 0x1);
+       msleep(1);
+       b43_radio_set(dev, B2055_CAL_MISC, 0x40);
+       msleep(1);
+       for (i = 0; i < 100; i++) {
+               val = b43_radio_read16(dev, B2055_CAL_COUT2);
+               if (val & 0x80)
+                       break;
+               udelay(10);
+       }
+       msleep(1);
+       b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F);
+       msleep(1);
+       b43_radio_selectchannel(dev, dev->phy.channel, 0);
+       b43_radio_write16(dev, B2055_C1_RX_BB_LPF, 0x9);
+       b43_radio_write16(dev, B2055_C2_RX_BB_LPF, 0x9);
+       b43_radio_write16(dev, B2055_C1_RX_BB_MIDACHP, 0x83);
+       b43_radio_write16(dev, B2055_C2_RX_BB_MIDACHP, 0x83);
+}
+
+/* Initialize a Broadcom 2055 N-radio */
+static void b43_radio_init2055(struct b43_wldev *dev)
+{
+       b43_radio_init2055_pre(dev);
+       if (b43_status(dev) < B43_STAT_INITIALIZED)
+               b2055_upload_inittab(dev, 0, 1);
+       else
+               b2055_upload_inittab(dev, 0/*FIXME on 5ghz band*/, 0);
+       b43_radio_init2055_post(dev);
+}
+
+void b43_nphy_radio_turn_on(struct b43_wldev *dev)
+{
+       b43_radio_init2055(dev);
+}
+
+void b43_nphy_radio_turn_off(struct b43_wldev *dev)
+{
+       b43_phy_mask(dev, B43_NPHY_RFCTL_CMD,
+                    ~B43_NPHY_RFCTL_CMD_EN);
+}
+
+#define ntab_upload(dev, offset, data) do { \
+               unsigned int i;                                         \
+               for (i = 0; i < (offset##_SIZE); i++)                   \
+                       b43_ntab_write(dev, (offset) + i, (data)[i]);   \
+       } while (0)
+
+/* Upload the N-PHY tables. */
+static void b43_nphy_tables_init(struct b43_wldev *dev)
+{
+       /* Static tables */
+       ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
+       ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
+       ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
+       ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
+       ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
+       ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
+       ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
+       ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
+       ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
+       ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
+       ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
+       ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
+       ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
+       ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
+
+       /* Volatile tables */
+       ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
+       ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
+       ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
+       ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
+       ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
+       ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
+       ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
+       ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
+       ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
+       ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
+       ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
+       ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
+}
+
+static void b43_nphy_workarounds(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+       unsigned int i;
+
+       b43_phy_set(dev, B43_NPHY_IQFLIP,
+                   B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
+       //FIXME the following condition is different in the specs.
+       if (1 /* FIXME band is 2.4GHz */) {
+               b43_phy_set(dev, B43_NPHY_CLASSCTL,
+                           B43_NPHY_CLASSCTL_CCKEN);
+       } else {
+               b43_phy_mask(dev, B43_NPHY_CLASSCTL,
+                            ~B43_NPHY_CLASSCTL_CCKEN);
+       }
+       b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
+       b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8);
+
+       /* Fixup some tables */
+       b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800);
+       b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800);
+
+       b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
+       b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
+       b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
+       b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
+
+       //TODO set RF sequence
+
+       /* Set narrowband clip threshold */
+       b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66);
+       b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66);
+
+       /* Set wideband clip 2 threshold */
+       b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES,
+                       ~B43_NPHY_C1_CLIPWBTHRES_CLIP2,
+                       21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT);
+       b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
+                       ~B43_NPHY_C2_CLIPWBTHRES_CLIP2,
+                       21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT);
+
+       /* Set Clip 2 detect */
+       b43_phy_set(dev, B43_NPHY_C1_CGAINI,
+                   B43_NPHY_C1_CGAINI_CL2DETECT);
+       b43_phy_set(dev, B43_NPHY_C2_CGAINI,
+                   B43_NPHY_C2_CGAINI_CL2DETECT);
+
+       if (0 /*FIXME*/) {
+               /* Set dwell lengths */
+               b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43);
+               b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43);
+               b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9);
+               b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9);
+
+               /* Set gain backoff */
+               b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
+                               ~B43_NPHY_C1_CGAINI_GAINBKOFF,
+                               1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT);
+               b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
+                               ~B43_NPHY_C2_CGAINI_GAINBKOFF,
+                               1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT);
+
+               /* Set HPVGA2 index */
+               b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN,
+                               ~B43_NPHY_C1_INITGAIN_HPVGA2,
+                               6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT);
+               b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN,
+                               ~B43_NPHY_C2_INITGAIN_HPVGA2,
+                               6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT);
+
+               //FIXME verify that the specs really mean to use autoinc here.
+               for (i = 0; i < 3; i++)
+                       b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673);
+       }
+
+       /* Set minimum gain value */
+       b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN,
+                       ~B43_NPHY_C1_MINGAIN,
+                       23 << B43_NPHY_C1_MINGAIN_SHIFT);
+       b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN,
+                       ~B43_NPHY_C2_MINGAIN,
+                       23 << B43_NPHY_C2_MINGAIN_SHIFT);
+
+       if (phy->rev < 2) {
+               b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
+                            ~B43_NPHY_SCRAM_SIGCTL_SCM);
+       }
+
+       /* Set phase track alpha and beta */
+       b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
+       b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
+       b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
+       b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
+       b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
+       b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
+}
+
+static void b43_nphy_reset_cca(struct b43_wldev *dev)
+{
+       u16 bbcfg;
+
+       ssb_write32(dev->dev, SSB_TMSLOW,
+                   ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC);
+       bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
+       b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA);
+       b43_phy_write(dev, B43_NPHY_BBCFG,
+                     bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
+       ssb_write32(dev->dev, SSB_TMSLOW,
+                   ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC);
+}
+
+enum b43_nphy_rf_sequence {
+       B43_RFSEQ_RX2TX,
+       B43_RFSEQ_TX2RX,
+       B43_RFSEQ_RESET2RX,
+       B43_RFSEQ_UPDATE_GAINH,
+       B43_RFSEQ_UPDATE_GAINL,
+       B43_RFSEQ_UPDATE_GAINU,
+};
+
+static void b43_nphy_force_rf_sequence(struct b43_wldev *dev,
+                                      enum b43_nphy_rf_sequence seq)
+{
+       static const u16 trigger[] = {
+               [B43_RFSEQ_RX2TX]               = B43_NPHY_RFSEQTR_RX2TX,
+               [B43_RFSEQ_TX2RX]               = B43_NPHY_RFSEQTR_TX2RX,
+               [B43_RFSEQ_RESET2RX]            = B43_NPHY_RFSEQTR_RST2RX,
+               [B43_RFSEQ_UPDATE_GAINH]        = B43_NPHY_RFSEQTR_UPGH,
+               [B43_RFSEQ_UPDATE_GAINL]        = B43_NPHY_RFSEQTR_UPGL,
+               [B43_RFSEQ_UPDATE_GAINU]        = B43_NPHY_RFSEQTR_UPGU,
+       };
+       int i;
+
+       B43_WARN_ON(seq >= ARRAY_SIZE(trigger));
+
+       b43_phy_set(dev, B43_NPHY_RFSEQMODE,
+                   B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER);
+       b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]);
+       for (i = 0; i < 200; i++) {
+               if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq]))
+                       goto ok;
+               msleep(1);
+       }
+       b43err(dev->wl, "RF sequence status timeout\n");
+ok:
+       b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
+                    ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER));
+}
+
+static void b43_nphy_bphy_init(struct b43_wldev *dev)
+{
+       unsigned int i;
+       u16 val;
+
+       val = 0x1E1F;
+       for (i = 0; i < 14; i++) {
+               b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val);
+               val -= 0x202;
+       }
+       val = 0x3E3F;
+       for (i = 0; i < 16; i++) {
+               b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val);
+               val -= 0x202;
+       }
+       b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
+}
+
+/* RSSI Calibration */
+static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type)
+{
+       //TODO
+}
+
+int b43_phy_initn(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+       u16 tmp;
+
+       //TODO: Spectral management
+       b43_nphy_tables_init(dev);
+
+       /* Clear all overrides */
+       b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
+       b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
+       b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
+                    ~(B43_NPHY_RFSEQMODE_CAOVER |
+                      B43_NPHY_RFSEQMODE_TROVER));
+       b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);
+
+       tmp = (phy->rev < 2) ? 64 : 59;
+       b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
+                       ~B43_NPHY_BPHY_CTL3_SCALE,
+                       tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
+
+       b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
+       b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
+
+       b43_phy_write(dev, B43_NPHY_TXREALFD, 184);
+       b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200);
+       b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80);
+       b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511);
+
+       //TODO MIMO-Config
+       //TODO Update TX/RX chain
+
+       if (phy->rev < 2) {
+               b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
+               b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
+       }
+       b43_nphy_workarounds(dev);
+       b43_nphy_reset_cca(dev);
+
+       ssb_write32(dev->dev, SSB_TMSLOW,
+                   ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN);
+       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
+       b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
+
+       b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */
+       //TODO read core1/2 clip1 thres regs
+
+       if (1 /* FIXME Band is 2.4GHz */)
+               b43_nphy_bphy_init(dev);
+       //TODO disable TX power control
+       //TODO Fix the TX power settings
+       //TODO Init periodic calibration with reason 3
+       b43_nphy_rssi_cal(dev, 2);
+       b43_nphy_rssi_cal(dev, 0);
+       b43_nphy_rssi_cal(dev, 1);
+       //TODO get TX gain
+       //TODO init superswitch
+       //TODO calibrate LO
+       //TODO idle TSSI TX pctl
+       //TODO TX power control power setup
+       //TODO table writes
+       //TODO TX power control coefficients
+       //TODO enable TX power control
+       //TODO control antenna selection
+       //TODO init radar detection
+       //TODO reset channel if changed
+
+       b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
+       return 0;
+}
diff --git a/drivers/net/wireless/b43/nphy.h b/drivers/net/wireless/b43/nphy.h
new file mode 100644 (file)
index 0000000..5d95118
--- /dev/null
@@ -0,0 +1,932 @@
+#ifndef B43_NPHY_H_
+#define B43_NPHY_H_
+
+#include "phy.h"
+
+
+/* N-PHY registers. */
+
+#define B43_NPHY_BBCFG                         B43_PHY_N(0x001) /* BB config */
+#define  B43_NPHY_BBCFG_RSTCCA                 0x4000 /* Reset CCA */
+#define  B43_NPHY_BBCFG_RSTRX                  0x8000 /* Reset RX */
+#define B43_NPHY_CHANNEL                       B43_PHY_N(0x005) /* Channel */
+#define B43_NPHY_TXERR                         B43_PHY_N(0x007) /* TX error */
+#define B43_NPHY_BANDCTL                       B43_PHY_N(0x009) /* Band control */
+#define  B43_NPHY_BANDCTL_5GHZ                 0x0001 /* Use the 5GHz band */
+#define B43_NPHY_4WI_ADDR                      B43_PHY_N(0x00B) /* Four-wire bus address */
+#define B43_NPHY_4WI_DATAHI                    B43_PHY_N(0x00C) /* Four-wire bus data high */
+#define B43_NPHY_4WI_DATALO                    B43_PHY_N(0x00D) /* Four-wire bus data low */
+#define B43_NPHY_BIST_STAT0                    B43_PHY_N(0x00E) /* Built-in self test status 0 */
+#define B43_NPHY_BIST_STAT1                    B43_PHY_N(0x00F) /* Built-in self test status 1 */
+
+#define B43_NPHY_C1_DESPWR                     B43_PHY_N(0x018) /* Core 1 desired power */
+#define B43_NPHY_C1_CCK_DESPWR                 B43_PHY_N(0x019) /* Core 1 CCK desired power */
+#define B43_NPHY_C1_BCLIPBKOFF                 B43_PHY_N(0x01A) /* Core 1 barely clip backoff */
+#define B43_NPHY_C1_CCK_BCLIPBKOFF             B43_PHY_N(0x01B) /* Core 1 CCK barely clip backoff */
+#define B43_NPHY_C1_CGAINI                     B43_PHY_N(0x01C) /* Core 1 compute gain info */
+#define  B43_NPHY_C1_CGAINI_GAINBKOFF          0x001F /* Gain backoff */
+#define  B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT    0
+#define  B43_NPHY_C1_CGAINI_CLIPGBKOFF         0x03E0 /* Clip gain backoff */
+#define  B43_NPHY_C1_CGAINI_CLIPGBKOFF_SHIFT   5
+#define  B43_NPHY_C1_CGAINI_GAINSTEP           0x1C00 /* Gain step */
+#define  B43_NPHY_C1_CGAINI_GAINSTEP_SHIFT     10
+#define  B43_NPHY_C1_CGAINI_CL2DETECT          0x2000 /* Clip 2 detect mask */
+#define B43_NPHY_C1_CCK_CGAINI                 B43_PHY_N(0x01D) /* Core 1 CCK compute gain info */
+#define  B43_NPHY_C1_CCK_CGAINI_GAINBKOFF      0x001F /* Gain backoff */
+#define  B43_NPHY_C1_CCK_CGAINI_CLIPGBKOFF     0x01E0 /* CCK barely clip gain backoff */
+#define B43_NPHY_C1_MINMAX_GAIN                        B43_PHY_N(0x01E) /* Core 1 min/max gain */
+#define  B43_NPHY_C1_MINGAIN                   0x00FF /* Minimum gain */
+#define  B43_NPHY_C1_MINGAIN_SHIFT             0
+#define  B43_NPHY_C1_MAXGAIN                   0xFF00 /* Maximum gain */
+#define  B43_NPHY_C1_MAXGAIN_SHIFT             8
+#define B43_NPHY_C1_CCK_MINMAX_GAIN            B43_PHY_N(0x01F) /* Core 1 CCK min/max gain */
+#define  B43_NPHY_C1_CCK_MINGAIN               0x00FF /* Minimum gain */
+#define  B43_NPHY_C1_CCK_MINGAIN_SHIFT         0
+#define  B43_NPHY_C1_CCK_MAXGAIN               0xFF00 /* Maximum gain */
+#define  B43_NPHY_C1_CCK_MAXGAIN_SHIFT         8
+#define B43_NPHY_C1_INITGAIN                   B43_PHY_N(0x020) /* Core 1 initial gain code */
+#define  B43_NPHY_C1_INITGAIN_EXTLNA           0x0001 /* External LNA index */
+#define  B43_NPHY_C1_INITGAIN_LNA              0x0006 /* LNA index */
+#define  B43_NPHY_C1_INITGAIN_LNAIDX_SHIFT     1
+#define  B43_NPHY_C1_INITGAIN_HPVGA1           0x0078 /* HPVGA1 index */
+#define  B43_NPHY_C1_INITGAIN_HPVGA1_SHIFT     3
+#define  B43_NPHY_C1_INITGAIN_HPVGA2           0x0F80 /* HPVGA2 index */
+#define  B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT     7
+#define  B43_NPHY_C1_INITGAIN_TRRX             0x1000 /* TR RX index */
+#define  B43_NPHY_C1_INITGAIN_TRTX             0x2000 /* TR TX index */
+#define B43_NPHY_C1_CLIP1_HIGAIN               B43_PHY_N(0x021) /* Core 1 clip1 high gain code */
+#define B43_NPHY_C1_CLIP1_MEDGAIN              B43_PHY_N(0x022) /* Core 1 clip1 medium gain code */
+#define B43_NPHY_C1_CLIP1_LOGAIN               B43_PHY_N(0x023) /* Core 1 clip1 low gain code */
+#define B43_NPHY_C1_CLIP2_GAIN                 B43_PHY_N(0x024) /* Core 1 clip2 gain code */
+#define B43_NPHY_C1_FILTERGAIN                 B43_PHY_N(0x025) /* Core 1 filter gain */
+#define B43_NPHY_C1_LPF_QHPF_BW                        B43_PHY_N(0x026) /* Core 1 LPF Q HP F bandwidth */
+#define B43_NPHY_C1_CLIPWBTHRES                        B43_PHY_N(0x027) /* Core 1 clip wideband threshold */
+#define  B43_NPHY_C1_CLIPWBTHRES_CLIP2         0x003F /* Clip 2 */
+#define  B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT   0
+#define  B43_NPHY_C1_CLIPWBTHRES_CLIP1         0x0FC0 /* Clip 1 */
+#define  B43_NPHY_C1_CLIPWBTHRES_CLIP1_SHIFT   6
+#define B43_NPHY_C1_W1THRES                    B43_PHY_N(0x028) /* Core 1 W1 threshold */
+#define B43_NPHY_C1_EDTHRES                    B43_PHY_N(0x029) /* Core 1 ED threshold */
+#define B43_NPHY_C1_SMSIGTHRES                 B43_PHY_N(0x02A) /* Core 1 small sig threshold */
+#define B43_NPHY_C1_NBCLIPTHRES                        B43_PHY_N(0x02B) /* Core 1 NB clip threshold */
+#define B43_NPHY_C1_CLIP1THRES                 B43_PHY_N(0x02C) /* Core 1 clip1 threshold */
+#define B43_NPHY_C1_CLIP2THRES                 B43_PHY_N(0x02D) /* Core 1 clip2 threshold */
+
+#define B43_NPHY_C2_DESPWR                     B43_PHY_N(0x02E) /* Core 2 desired power */
+#define B43_NPHY_C2_CCK_DESPWR                 B43_PHY_N(0x02F) /* Core 2 CCK desired power */
+#define B43_NPHY_C2_BCLIPBKOFF                 B43_PHY_N(0x030) /* Core 2 barely clip backoff */
+#define B43_NPHY_C2_CCK_BCLIPBKOFF             B43_PHY_N(0x031) /* Core 2 CCK barely clip backoff */
+#define B43_NPHY_C2_CGAINI                     B43_PHY_N(0x032) /* Core 2 compute gain info */
+#define  B43_NPHY_C2_CGAINI_GAINBKOFF          0x001F /* Gain backoff */
+#define  B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT    0
+#define  B43_NPHY_C2_CGAINI_CLIPGBKOFF         0x03E0 /* Clip gain backoff */
+#define  B43_NPHY_C2_CGAINI_CLIPGBKOFF_SHIFT   5
+#define  B43_NPHY_C2_CGAINI_GAINSTEP           0x1C00 /* Gain step */
+#define  B43_NPHY_C2_CGAINI_GAINSTEP_SHIFT     10
+#define  B43_NPHY_C2_CGAINI_CL2DETECT          0x2000 /* Clip 2 detect mask */
+#define B43_NPHY_C2_CCK_CGAINI                 B43_PHY_N(0x033) /* Core 2 CCK compute gain info */
+#define  B43_NPHY_C2_CCK_CGAINI_GAINBKOFF      0x001F /* Gain backoff */
+#define  B43_NPHY_C2_CCK_CGAINI_CLIPGBKOFF     0x01E0 /* CCK barely clip gain backoff */
+#define B43_NPHY_C2_MINMAX_GAIN                        B43_PHY_N(0x034) /* Core 2 min/max gain */
+#define  B43_NPHY_C2_MINGAIN                   0x00FF /* Minimum gain */
+#define  B43_NPHY_C2_MINGAIN_SHIFT             0
+#define  B43_NPHY_C2_MAXGAIN                   0xFF00 /* Maximum gain */
+#define  B43_NPHY_C2_MAXGAIN_SHIFT             8
+#define B43_NPHY_C2_CCK_MINMAX_GAIN            B43_PHY_N(0x035) /* Core 2 CCK min/max gain */
+#define  B43_NPHY_C2_CCK_MINGAIN               0x00FF /* Minimum gain */
+#define  B43_NPHY_C2_CCK_MINGAIN_SHIFT         0
+#define  B43_NPHY_C2_CCK_MAXGAIN               0xFF00 /* Maximum gain */
+#define  B43_NPHY_C2_CCK_MAXGAIN_SHIFT         8
+#define B43_NPHY_C2_INITGAIN                   B43_PHY_N(0x036) /* Core 2 initial gain code */
+#define  B43_NPHY_C2_INITGAIN_EXTLNA           0x0001 /* External LNA index */
+#define  B43_NPHY_C2_INITGAIN_LNA              0x0006 /* LNA index */
+#define  B43_NPHY_C2_INITGAIN_LNAIDX_SHIFT     1
+#define  B43_NPHY_C2_INITGAIN_HPVGA1           0x0078 /* HPVGA1 index */
+#define  B43_NPHY_C2_INITGAIN_HPVGA1_SHIFT     3
+#define  B43_NPHY_C2_INITGAIN_HPVGA2           0x0F80 /* HPVGA2 index */
+#define  B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT     7
+#define  B43_NPHY_C2_INITGAIN_TRRX             0x1000 /* TR RX index */
+#define  B43_NPHY_C2_INITGAIN_TRTX             0x2000 /* TR TX index */
+#define B43_NPHY_C2_CLIP1_HIGAIN               B43_PHY_N(0x037) /* Core 2 clip1 high gain code */
+#define B43_NPHY_C2_CLIP1_MEDGAIN              B43_PHY_N(0x038) /* Core 2 clip1 medium gain code */
+#define B43_NPHY_C2_CLIP1_LOGAIN               B43_PHY_N(0x039) /* Core 2 clip1 low gain code */
+#define B43_NPHY_C2_CLIP2_GAIN                 B43_PHY_N(0x03A) /* Core 2 clip2 gain code */
+#define B43_NPHY_C2_FILTERGAIN                 B43_PHY_N(0x03B) /* Core 2 filter gain */
+#define B43_NPHY_C2_LPF_QHPF_BW                        B43_PHY_N(0x03C) /* Core 2 LPF Q HP F bandwidth */
+#define B43_NPHY_C2_CLIPWBTHRES                        B43_PHY_N(0x03D) /* Core 2 clip wideband threshold */
+#define  B43_NPHY_C2_CLIPWBTHRES_CLIP2         0x003F /* Clip 2 */
+#define  B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT   0
+#define  B43_NPHY_C2_CLIPWBTHRES_CLIP1         0x0FC0 /* Clip 1 */
+#define  B43_NPHY_C2_CLIPWBTHRES_CLIP1_SHIFT   6
+#define B43_NPHY_C2_W1THRES                    B43_PHY_N(0x03E) /* Core 2 W1 threshold */
+#define B43_NPHY_C2_EDTHRES                    B43_PHY_N(0x03F) /* Core 2 ED threshold */
+#define B43_NPHY_C2_SMSIGTHRES                 B43_PHY_N(0x040) /* Core 2 small sig threshold */
+#define B43_NPHY_C2_NBCLIPTHRES                        B43_PHY_N(0x041) /* Core 2 NB clip threshold */
+#define B43_NPHY_C2_CLIP1THRES                 B43_PHY_N(0x042) /* Core 2 clip1 threshold */
+#define B43_NPHY_C2_CLIP2THRES                 B43_PHY_N(0x043) /* Core 2 clip2 threshold */
+
+#define B43_NPHY_CRS_THRES1                    B43_PHY_N(0x044) /* CRS threshold 1 */
+#define B43_NPHY_CRS_THRES2                    B43_PHY_N(0x045) /* CRS threshold 2 */
+#define B43_NPHY_CRS_THRES3                    B43_PHY_N(0x046) /* CRS threshold 3 */
+#define B43_NPHY_CRSCTL                                B43_PHY_N(0x047) /* CRS control */
+#define B43_NPHY_DCFADDR                       B43_PHY_N(0x048) /* DC filter address */
+#define B43_NPHY_RXF20_NUM0                    B43_PHY_N(0x049) /* RX filter 20 numerator 0 */
+#define B43_NPHY_RXF20_NUM1                    B43_PHY_N(0x04A) /* RX filter 20 numerator 1 */
+#define B43_NPHY_RXF20_NUM2                    B43_PHY_N(0x04B) /* RX filter 20 numerator 2 */
+#define B43_NPHY_RXF20_DENOM0                  B43_PHY_N(0x04C) /* RX filter 20 denominator 0 */
+#define B43_NPHY_RXF20_DENOM1                  B43_PHY_N(0x04D) /* RX filter 20 denominator 1 */
+#define B43_NPHY_RXF20_NUM10                   B43_PHY_N(0x04E) /* RX filter 20 numerator 10 */
+#define B43_NPHY_RXF20_NUM11                   B43_PHY_N(0x04F) /* RX filter 20 numerator 11 */
+#define B43_NPHY_RXF20_NUM12                   B43_PHY_N(0x050) /* RX filter 20 numerator 12 */
+#define B43_NPHY_RXF20_DENOM10                 B43_PHY_N(0x051) /* RX filter 20 denominator 10 */
+#define B43_NPHY_RXF20_DENOM11                 B43_PHY_N(0x052) /* RX filter 20 denominator 11 */
+#define B43_NPHY_RXF40_NUM0                    B43_PHY_N(0x053) /* RX filter 40 numerator 0 */
+#define B43_NPHY_RXF40_NUM1                    B43_PHY_N(0x054) /* RX filter 40 numerator 1 */
+#define B43_NPHY_RXF40_NUM2                    B43_PHY_N(0x055) /* RX filter 40 numerator 2 */
+#define B43_NPHY_RXF40_DENOM0                  B43_PHY_N(0x056) /* RX filter 40 denominator 0 */
+#define B43_NPHY_RXF40_DENOM1                  B43_PHY_N(0x057) /* RX filter 40 denominator 1 */
+#define B43_NPHY_RXF40_NUM10                   B43_PHY_N(0x058) /* RX filter 40 numerator 10 */
+#define B43_NPHY_RXF40_NUM11                   B43_PHY_N(0x059) /* RX filter 40 numerator 11 */
+#define B43_NPHY_RXF40_NUM12                   B43_PHY_N(0x05A) /* RX filter 40 numerator 12 */
+#define B43_NPHY_RXF40_DENOM10                 B43_PHY_N(0x05B) /* RX filter 40 denominator 10 */
+#define B43_NPHY_RXF40_DENOM11                 B43_PHY_N(0x05C) /* RX filter 40 denominator 11 */
+#define B43_NPHY_PPROC_RSTLEN                  B43_PHY_N(0x060) /* Packet processing reset length */
+#define B43_NPHY_INITCARR_DLEN                 B43_PHY_N(0x061) /* Initial carrier detection length */
+#define B43_NPHY_CLIP1CARR_DLEN                        B43_PHY_N(0x062) /* Clip1 carrier detection length */
+#define B43_NPHY_CLIP2CARR_DLEN                        B43_PHY_N(0x063) /* Clip2 carrier detection length */
+#define B43_NPHY_INITGAIN_SLEN                 B43_PHY_N(0x064) /* Initial gain settle length */
+#define B43_NPHY_CLIP1GAIN_SLEN                        B43_PHY_N(0x065) /* Clip1 gain settle length */
+#define B43_NPHY_CLIP2GAIN_SLEN                        B43_PHY_N(0x066) /* Clip2 gain settle length */
+#define B43_NPHY_PACKGAIN_SLEN                 B43_PHY_N(0x067) /* Packet gain settle length */
+#define B43_NPHY_CARRSRC_TLEN                  B43_PHY_N(0x068) /* Carrier search timeout length */
+#define B43_NPHY_TISRC_TLEN                    B43_PHY_N(0x069) /* Timing search timeout length */
+#define B43_NPHY_ENDROP_TLEN                   B43_PHY_N(0x06A) /* Energy drop timeout length */
+#define B43_NPHY_CLIP1_NBDWELL_LEN             B43_PHY_N(0x06B) /* Clip1 NB dwell length */
+#define B43_NPHY_CLIP2_NBDWELL_LEN             B43_PHY_N(0x06C) /* Clip2 NB dwell length */
+#define B43_NPHY_W1CLIP1_DWELL_LEN             B43_PHY_N(0x06D) /* W1 clip1 dwell length */
+#define B43_NPHY_W1CLIP2_DWELL_LEN             B43_PHY_N(0x06E) /* W1 clip2 dwell length */
+#define B43_NPHY_W2CLIP1_DWELL_LEN             B43_PHY_N(0x06F) /* W2 clip1 dwell length */
+#define B43_NPHY_PLOAD_CSENSE_EXTLEN           B43_PHY_N(0x070) /* Payload carrier sense extension length */
+#define B43_NPHY_EDROP_CSENSE_EXTLEN           B43_PHY_N(0x071) /* Energy drop carrier sense extension length */
+#define B43_NPHY_TABLE_ADDR                    B43_PHY_N(0x072) /* Table address */
+#define B43_NPHY_TABLE_DATALO                  B43_PHY_N(0x073) /* Table data low */
+#define B43_NPHY_TABLE_DATAHI                  B43_PHY_N(0x074) /* Table data high */
+#define B43_NPHY_WWISE_LENIDX                  B43_PHY_N(0x075) /* WWiSE length index */
+#define B43_NPHY_TGNSYNC_LENIDX                        B43_PHY_N(0x076) /* TGNsync length index */
+#define B43_NPHY_TXMACIF_HOLDOFF               B43_PHY_N(0x077) /* TX MAC IF Hold off */
+#define B43_NPHY_RFCTL_CMD                     B43_PHY_N(0x078) /* RF control (command) */
+#define  B43_NPHY_RFCTL_CMD_START              0x0001 /* Start sequence */
+#define  B43_NPHY_RFCTL_CMD_RXTX               0x0002 /* RX/TX */
+#define  B43_NPHY_RFCTL_CMD_CORESEL            0x0038 /* Core select */
+#define  B43_NPHY_RFCTL_CMD_CORESEL_SHIFT      3
+#define  B43_NPHY_RFCTL_CMD_PORFORCE           0x0040 /* POR force */
+#define  B43_NPHY_RFCTL_CMD_OEPORFORCE         0x0080 /* OE POR force */
+#define  B43_NPHY_RFCTL_CMD_RXEN               0x0100 /* RX enable */
+#define  B43_NPHY_RFCTL_CMD_TXEN               0x0200 /* TX enable */
+#define  B43_NPHY_RFCTL_CMD_CHIP0PU            0x0400 /* Chip0 PU */
+#define  B43_NPHY_RFCTL_CMD_EN                 0x0800 /* Radio enabled */
+#define  B43_NPHY_RFCTL_CMD_SEQENCORE          0xF000 /* Seq en core */
+#define  B43_NPHY_RFCTL_CMD_SEQENCORE_SHIFT    12
+#define B43_NPHY_RFCTL_RSSIO1                  B43_PHY_N(0x07A) /* RF control (RSSI others 1) */
+#define  B43_NPHY_RFCTL_RSSIO1_RXPD            0x0001 /* RX PD */
+#define  B43_NPHY_RFCTL_RSSIO1_TXPD            0x0002 /* TX PD */
+#define  B43_NPHY_RFCTL_RSSIO1_PAPD            0x0004 /* PA PD */
+#define  B43_NPHY_RFCTL_RSSIO1_RSSICTL         0x0030 /* RSSI control */
+#define  B43_NPHY_RFCTL_RSSIO1_LPFBW           0x00C0 /* LPF bandwidth */
+#define  B43_NPHY_RFCTL_RSSIO1_HPFBWHI         0x0100 /* HPF bandwidth high */
+#define  B43_NPHY_RFCTL_RSSIO1_HIQDISCO                0x0200 /* HIQ dis core */
+#define B43_NPHY_RFCTL_RXG1                    B43_PHY_N(0x07B) /* RF control (RX gain 1) */
+#define B43_NPHY_RFCTL_TXG1                    B43_PHY_N(0x07C) /* RF control (TX gain 1) */
+#define B43_NPHY_RFCTL_RSSIO2                  B43_PHY_N(0x07D) /* RF control (RSSI others 2) */
+#define  B43_NPHY_RFCTL_RSSIO2_RXPD            0x0001 /* RX PD */
+#define  B43_NPHY_RFCTL_RSSIO2_TXPD            0x0002 /* TX PD */
+#define  B43_NPHY_RFCTL_RSSIO2_PAPD            0x0004 /* PA PD */
+#define  B43_NPHY_RFCTL_RSSIO2_RSSICTL         0x0030 /* RSSI control */
+#define  B43_NPHY_RFCTL_RSSIO2_LPFBW           0x00C0 /* LPF bandwidth */
+#define  B43_NPHY_RFCTL_RSSIO2_HPFBWHI         0x0100 /* HPF bandwidth high */
+#define  B43_NPHY_RFCTL_RSSIO2_HIQDISCO                0x0200 /* HIQ dis core */
+#define B43_NPHY_RFCTL_RXG2                    B43_PHY_N(0x07E) /* RF control (RX gain 2) */
+#define B43_NPHY_RFCTL_TXG2                    B43_PHY_N(0x07F) /* RF control (TX gain 2) */
+#define B43_NPHY_RFCTL_RSSIO3                  B43_PHY_N(0x080) /* RF control (RSSI others 3) */
+#define  B43_NPHY_RFCTL_RSSIO3_RXPD            0x0001 /* RX PD */
+#define  B43_NPHY_RFCTL_RSSIO3_TXPD            0x0002 /* TX PD */
+#define  B43_NPHY_RFCTL_RSSIO3_PAPD            0x0004 /* PA PD */
+#define  B43_NPHY_RFCTL_RSSIO3_RSSICTL         0x0030 /* RSSI control */
+#define  B43_NPHY_RFCTL_RSSIO3_LPFBW           0x00C0 /* LPF bandwidth */
+#define  B43_NPHY_RFCTL_RSSIO3_HPFBWHI         0x0100 /* HPF bandwidth high */
+#define  B43_NPHY_RFCTL_RSSIO3_HIQDISCO                0x0200 /* HIQ dis core */
+#define B43_NPHY_RFCTL_RXG3                    B43_PHY_N(0x081) /* RF control (RX gain 3) */
+#define B43_NPHY_RFCTL_TXG3                    B43_PHY_N(0x082) /* RF control (TX gain 3) */
+#define B43_NPHY_RFCTL_RSSIO4                  B43_PHY_N(0x083) /* RF control (RSSI others 4) */
+#define  B43_NPHY_RFCTL_RSSIO4_RXPD            0x0001 /* RX PD */
+#define  B43_NPHY_RFCTL_RSSIO4_TXPD            0x0002 /* TX PD */
+#define  B43_NPHY_RFCTL_RSSIO4_PAPD            0x0004 /* PA PD */
+#define  B43_NPHY_RFCTL_RSSIO4_RSSICTL         0x0030 /* RSSI control */
+#define  B43_NPHY_RFCTL_RSSIO4_LPFBW           0x00C0 /* LPF bandwidth */
+#define  B43_NPHY_RFCTL_RSSIO4_HPFBWHI         0x0100 /* HPF bandwidth high */
+#define  B43_NPHY_RFCTL_RSSIO4_HIQDISCO                0x0200 /* HIQ dis core */
+#define B43_NPHY_RFCTL_RXG4                    B43_PHY_N(0x084) /* RF control (RX gain 4) */
+#define B43_NPHY_RFCTL_TXG4                    B43_PHY_N(0x085) /* RF control (TX gain 4) */
+#define B43_NPHY_C1_TXIQ_COMP_OFF              B43_PHY_N(0x087) /* Core 1 TX I/Q comp offset */
+#define B43_NPHY_C2_TXIQ_COMP_OFF              B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */
+#define B43_NPHY_C1_TXCTL                      B43_PHY_N(0x08B) /* Core 1 TX control */
+#define B43_NPHY_C2_TXCTL                      B43_PHY_N(0x08C) /* Core 2 TX control */
+#define B43_NPHY_SCRAM_SIGCTL                  B43_PHY_N(0x090) /* Scram signal control */
+#define  B43_NPHY_SCRAM_SIGCTL_INITST          0x007F /* Initial state value */
+#define  B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT    0
+#define  B43_NPHY_SCRAM_SIGCTL_SCM             0x0080 /* Scram control mode */
+#define  B43_NPHY_SCRAM_SIGCTL_SICE            0x0100 /* Scram index control enable */
+#define  B43_NPHY_SCRAM_SIGCTL_START           0xFE00 /* Scram start bit */
+#define  B43_NPHY_SCRAM_SIGCTL_START_SHIFT     9
+#define B43_NPHY_RFCTL_INTC1                   B43_PHY_N(0x091) /* RF control (intc 1) */
+#define B43_NPHY_RFCTL_INTC2                   B43_PHY_N(0x092) /* RF control (intc 2) */
+#define B43_NPHY_RFCTL_INTC3                   B43_PHY_N(0x093) /* RF control (intc 3) */
+#define B43_NPHY_RFCTL_INTC4                   B43_PHY_N(0x094) /* RF control (intc 4) */
+#define B43_NPHY_NRDTO_WWISE                   B43_PHY_N(0x095) /* # datatones WWiSE */
+#define B43_NPHY_NRDTO_TGNSYNC                 B43_PHY_N(0x096) /* # datatones TGNsync */
+#define B43_NPHY_SIGFMOD_WWISE                 B43_PHY_N(0x097) /* Signal field mod WWiSE */
+#define B43_NPHY_LEG_SIGFMOD_11N               B43_PHY_N(0x098) /* Legacy signal field mod 11n */
+#define B43_NPHY_HT_SIGFMOD_11N                        B43_PHY_N(0x099) /* HT signal field mod 11n */
+#define B43_NPHY_C1_RXIQ_COMPA0                        B43_PHY_N(0x09A) /* Core 1 RX I/Q comp A0 */
+#define B43_NPHY_C1_RXIQ_COMPB0                        B43_PHY_N(0x09B) /* Core 1 RX I/Q comp B0 */
+#define B43_NPHY_C2_RXIQ_COMPA1                        B43_PHY_N(0x09C) /* Core 2 RX I/Q comp A1 */
+#define B43_NPHY_C2_RXIQ_COMPB1                        B43_PHY_N(0x09D) /* Core 2 RX I/Q comp B1 */
+#define B43_NPHY_RXCTL                         B43_PHY_N(0x0A0) /* RX control */
+#define  B43_NPHY_RXCTL_BSELU20                        0x0010 /* Band select upper 20 */
+#define  B43_NPHY_RXCTL_RIFSEN                 0x0080 /* RIFS enable */
+#define B43_NPHY_RFSEQMODE                     B43_PHY_N(0x0A1) /* RF seq mode */
+#define  B43_NPHY_RFSEQMODE_CAOVER             0x0001 /* Core active override */
+#define  B43_NPHY_RFSEQMODE_TROVER             0x0002 /* Trigger override */
+#define B43_NPHY_RFSEQCA                       B43_PHY_N(0x0A2) /* RF seq core active */
+#define  B43_NPHY_RFSEQCA_TXEN                 0x000F /* TX enable */
+#define  B43_NPHY_RFSEQCA_TXEN_SHIFT           0
+#define  B43_NPHY_RFSEQCA_RXEN                 0x00F0 /* RX enable */
+#define  B43_NPHY_RFSEQCA_RXEN_SHIFT           4
+#define  B43_NPHY_RFSEQCA_TXDIS                        0x0F00 /* TX disable */
+#define  B43_NPHY_RFSEQCA_TXDIS_SHIFT          8
+#define  B43_NPHY_RFSEQCA_RXDIS                        0xF000 /* RX disable */
+#define  B43_NPHY_RFSEQCA_RXDIS_SHIFT          12
+#define B43_NPHY_RFSEQTR                       B43_PHY_N(0x0A3) /* RF seq trigger */
+#define  B43_NPHY_RFSEQTR_RX2TX                        0x0001 /* RX2TX */
+#define  B43_NPHY_RFSEQTR_TX2RX                        0x0002 /* TX2RX */
+#define  B43_NPHY_RFSEQTR_UPGH                 0x0004 /* Update gain H */
+#define  B43_NPHY_RFSEQTR_UPGL                 0x0008 /* Update gain L */
+#define  B43_NPHY_RFSEQTR_UPGU                 0x0010 /* Update gain U */
+#define  B43_NPHY_RFSEQTR_RST2RX               0x0020 /* Reset to RX */
+#define B43_NPHY_RFSEQST                       B43_PHY_N(0x0A4) /* RF seq status. Values same as trigger. */
+#define B43_NPHY_AFECTL_OVER                   B43_PHY_N(0x0A5) /* AFE control override */
+#define B43_NPHY_AFECTL_C1                     B43_PHY_N(0x0A6) /* AFE control core 1 */
+#define B43_NPHY_AFECTL_C2                     B43_PHY_N(0x0A7) /* AFE control core 2 */
+#define B43_NPHY_AFECTL_C3                     B43_PHY_N(0x0A8) /* AFE control core 3 */
+#define B43_NPHY_AFECTL_C4                     B43_PHY_N(0x0A9) /* AFE control core 4 */
+#define B43_NPHY_AFECTL_DACGAIN1               B43_PHY_N(0x0AA) /* AFE control DAC gain 1 */
+#define B43_NPHY_AFECTL_DACGAIN2               B43_PHY_N(0x0AB) /* AFE control DAC gain 2 */
+#define B43_NPHY_AFECTL_DACGAIN3               B43_PHY_N(0x0AC) /* AFE control DAC gain 3 */
+#define B43_NPHY_AFECTL_DACGAIN4               B43_PHY_N(0x0AD) /* AFE control DAC gain 4 */
+#define B43_NPHY_STR_ADDR1                     B43_PHY_N(0x0AE) /* STR address 1 */
+#define B43_NPHY_STR_ADDR2                     B43_PHY_N(0x0AF) /* STR address 2 */
+#define B43_NPHY_CLASSCTL                      B43_PHY_N(0x0B0) /* Classifier control */
+#define  B43_NPHY_CLASSCTL_CCKEN               0x0001 /* CCK enable */
+#define  B43_NPHY_CLASSCTL_OFDMEN              0x0002 /* OFDM enable */
+#define  B43_NPHY_CLASSCTL_WAITEDEN            0x0004 /* Waited enable */
+#define B43_NPHY_IQFLIP                                B43_PHY_N(0x0B1) /* I/Q flip */
+#define  B43_NPHY_IQFLIP_ADC1                  0x0001 /* ADC1 */
+#define  B43_NPHY_IQFLIP_ADC2                  0x0010 /* ADC2 */
+#define B43_NPHY_SISO_SNR_THRES                        B43_PHY_N(0x0B2) /* SISO SNR threshold */
+#define B43_NPHY_SIGMA_N_MULT                  B43_PHY_N(0x0B3) /* Sigma N multiplier */
+#define B43_NPHY_TXMACDELAY                    B43_PHY_N(0x0B4) /* TX MAC delay */
+#define B43_NPHY_TXFRAMEDELAY                  B43_PHY_N(0x0B5) /* TX frame delay */
+#define B43_NPHY_MLPARM                                B43_PHY_N(0x0B6) /* ML parameters */
+#define B43_NPHY_MLCTL                         B43_PHY_N(0x0B7) /* ML control */
+#define B43_NPHY_WWISE_20NCYCDAT               B43_PHY_N(0x0B8) /* WWiSE 20 N cyc data */
+#define B43_NPHY_WWISE_40NCYCDAT               B43_PHY_N(0x0B9) /* WWiSE 40 N cyc data */
+#define B43_NPHY_TGNSYNC_20NCYCDAT             B43_PHY_N(0x0BA) /* TGNsync 20 N cyc data */
+#define B43_NPHY_TGNSYNC_40NCYCDAT             B43_PHY_N(0x0BB) /* TGNsync 40 N cyc data */
+#define B43_NPHY_INITSWIZP                     B43_PHY_N(0x0BC) /* Initial swizzle pattern */
+#define B43_NPHY_TXTAILCNT                     B43_PHY_N(0x0BD) /* TX tail count value */
+#define B43_NPHY_BPHY_CTL1                     B43_PHY_N(0x0BE) /* B PHY control 1 */
+#define B43_NPHY_BPHY_CTL2                     B43_PHY_N(0x0BF) /* B PHY control 2 */
+#define  B43_NPHY_BPHY_CTL2_LUT                        0x001F /* LUT index */
+#define  B43_NPHY_BPHY_CTL2_LUT_SHIFT          0
+#define  B43_NPHY_BPHY_CTL2_MACDEL             0x7FE0 /* MAC delay */
+#define  B43_NPHY_BPHY_CTL2_MACDEL_SHIFT       5
+#define B43_NPHY_IQLOCAL_CMD                   B43_PHY_N(0x0C0) /* I/Q LO cal command */
+#define  B43_NPHY_IQLOCAL_CMD_EN               0x8000
+#define B43_NPHY_IQLOCAL_CMDNNUM               B43_PHY_N(0x0C1) /* I/Q LO cal command N num */
+#define B43_NPHY_IQLOCAL_CMDGCTL               B43_PHY_N(0x0C2) /* I/Q LO cal command G control */
+#define B43_NPHY_SAMP_CMD                      B43_PHY_N(0x0C3) /* Sample command */
+#define  B43_NPHY_SAMP_CMD_STOP                        0x0002 /* Stop */
+#define B43_NPHY_SAMP_LOOPCNT                  B43_PHY_N(0x0C4) /* Sample loop count */
+#define B43_NPHY_SAMP_WAITCNT                  B43_PHY_N(0x0C5) /* Sample wait count */
+#define B43_NPHY_SAMP_DEPCNT                   B43_PHY_N(0x0C6) /* Sample depth count */
+#define B43_NPHY_SAMP_STAT                     B43_PHY_N(0x0C7) /* Sample status */
+#define B43_NPHY_GPIO_LOOEN                    B43_PHY_N(0x0C8) /* GPIO low out enable */
+#define B43_NPHY_GPIO_HIOEN                    B43_PHY_N(0x0C9) /* GPIO high out enable */
+#define B43_NPHY_GPIO_SEL                      B43_PHY_N(0x0CA) /* GPIO select */
+#define B43_NPHY_GPIO_CLKCTL                   B43_PHY_N(0x0CB) /* GPIO clock control */
+#define B43_NPHY_TXF_20CO_AS0                  B43_PHY_N(0x0CC) /* TX filter 20 coeff A stage 0 */
+#define B43_NPHY_TXF_20CO_AS1                  B43_PHY_N(0x0CD) /* TX filter 20 coeff A stage 1 */
+#define B43_NPHY_TXF_20CO_AS2                  B43_PHY_N(0x0CE) /* TX filter 20 coeff A stage 2 */
+#define B43_NPHY_TXF_20CO_B32S0                        B43_PHY_N(0x0CF) /* TX filter 20 coeff B32 stage 0 */
+#define B43_NPHY_TXF_20CO_B1S0                 B43_PHY_N(0x0D0) /* TX filter 20 coeff B1 stage 0 */
+#define B43_NPHY_TXF_20CO_B32S1                        B43_PHY_N(0x0D1) /* TX filter 20 coeff B32 stage 1 */
+#define B43_NPHY_TXF_20CO_B1S1                 B43_PHY_N(0x0D2) /* TX filter 20 coeff B1 stage 1 */
+#define B43_NPHY_TXF_20CO_B32S2                        B43_PHY_N(0x0D3) /* TX filter 20 coeff B32 stage 2 */
+#define B43_NPHY_TXF_20CO_B1S2                 B43_PHY_N(0x0D4) /* TX filter 20 coeff B1 stage 2 */
+#define B43_NPHY_SIGFLDTOL                     B43_PHY_N(0x0D5) /* Signal fld tolerance */
+#define B43_NPHY_TXSERFLD                      B43_PHY_N(0x0D6) /* TX service field */
+#define B43_NPHY_AFESEQ_RX2TX_PUD              B43_PHY_N(0x0D7) /* AFE seq RX2TX power up/down delay */
+#define B43_NPHY_AFESEQ_TX2RX_PUD              B43_PHY_N(0x0D8) /* AFE seq TX2RX power up/down delay */
+#define B43_NPHY_TGNSYNC_SCRAMI0               B43_PHY_N(0x0D9) /* TGNsync scram init 0 */
+#define B43_NPHY_TGNSYNC_SCRAMI1               B43_PHY_N(0x0DA) /* TGNsync scram init 1 */
+#define B43_NPHY_INITSWIZPATTLEG               B43_PHY_N(0x0DB) /* Initial swizzle pattern leg */
+#define B43_NPHY_BPHY_CTL3                     B43_PHY_N(0x0DC) /* B PHY control 3 */
+#define  B43_NPHY_BPHY_CTL3_SCALE              0x00FF /* Scale */
+#define  B43_NPHY_BPHY_CTL3_SCALE_SHIFT                0
+#define  B43_NPHY_BPHY_CTL3_FSC                        0xFF00 /* Frame start count value */
+#define  B43_NPHY_BPHY_CTL3_FSC_SHIFT          8
+#define B43_NPHY_BPHY_CTL4                     B43_PHY_N(0x0DD) /* B PHY control 4 */
+#define B43_NPHY_C1_TXBBMULT                   B43_PHY_N(0x0DE) /* Core 1 TX BB multiplier */
+#define B43_NPHY_C2_TXBBMULT                   B43_PHY_N(0x0DF) /* Core 2 TX BB multiplier */
+#define B43_NPHY_TXF_40CO_AS0                  B43_PHY_N(0x0E1) /* TX filter 40 coeff A stage 0 */
+#define B43_NPHY_TXF_40CO_AS1                  B43_PHY_N(0x0E2) /* TX filter 40 coeff A stage 1 */
+#define B43_NPHY_TXF_40CO_AS2                  B43_PHY_N(0x0E3) /* TX filter 40 coeff A stage 2 */
+#define B43_NPHY_TXF_40CO_B32S0                        B43_PHY_N(0x0E4) /* TX filter 40 coeff B32 stage 0 */
+#define B43_NPHY_TXF_40CO_B1S0                 B43_PHY_N(0x0E5) /* TX filter 40 coeff B1 stage 0 */
+#define B43_NPHY_TXF_40CO_B32S1                        B43_PHY_N(0x0E6) /* TX filter 40 coeff B32 stage 1 */
+#define B43_NPHY_TXF_40CO_B1S1                 B43_PHY_N(0x0E7) /* TX filter 40 coeff B1 stage 1 */
+#define B43_NPHY_TXF_40CO_B32S2                        B43_PHY_N(0x0E8) /* TX filter 40 coeff B32 stage 2 */
+#define B43_NPHY_TXF_40CO_B1S2                 B43_PHY_N(0x0E9) /* TX filter 40 coeff B1 stage 2 */
+#define B43_NPHY_BIST_STAT2                    B43_PHY_N(0x0EA) /* BIST status 2 */
+#define B43_NPHY_BIST_STAT3                    B43_PHY_N(0x0EB) /* BIST status 3 */
+#define B43_NPHY_RFCTL_OVER                    B43_PHY_N(0x0EC) /* RF control override */
+#define B43_NPHY_MIMOCFG                       B43_PHY_N(0x0ED) /* MIMO config */
+#define  B43_NPHY_MIMOCFG_GFMIX                        0x0004 /* Greenfield or mixed mode */
+#define  B43_NPHY_MIMOCFG_AUTO                 0x0100 /* Greenfield/mixed mode auto */
+#define B43_NPHY_RADAR_BLNKCTL                 B43_PHY_N(0x0EE) /* Radar blank control */
+#define B43_NPHY_A0RADAR_FIFOCTL               B43_PHY_N(0x0EF) /* Antenna 0 radar FIFO control */
+#define B43_NPHY_A1RADAR_FIFOCTL               B43_PHY_N(0x0F0) /* Antenna 1 radar FIFO control */
+#define B43_NPHY_A0RADAR_FIFODAT               B43_PHY_N(0x0F1) /* Antenna 0 radar FIFO data */
+#define B43_NPHY_A1RADAR_FIFODAT               B43_PHY_N(0x0F2) /* Antenna 1 radar FIFO data */
+#define B43_NPHY_RADAR_THRES0                  B43_PHY_N(0x0F3) /* Radar threshold 0 */
+#define B43_NPHY_RADAR_THRES1                  B43_PHY_N(0x0F4) /* Radar threshold 1 */
+#define B43_NPHY_RADAR_THRES0R                 B43_PHY_N(0x0F5) /* Radar threshold 0R */
+#define B43_NPHY_RADAR_THRES1R                 B43_PHY_N(0x0F6) /* Radar threshold 1R */
+#define B43_NPHY_CSEN_20IN40_DLEN              B43_PHY_N(0x0F7) /* Carrier sense 20 in 40 dwell length */
+#define B43_NPHY_RFCTL_LUT_TRSW_LO1            B43_PHY_N(0x0F8) /* RF control LUT TRSW lower 1 */
+#define B43_NPHY_RFCTL_LUT_TRSW_UP1            B43_PHY_N(0x0F9) /* RF control LUT TRSW upper 1 */
+#define B43_NPHY_RFCTL_LUT_TRSW_LO2            B43_PHY_N(0x0FA) /* RF control LUT TRSW lower 2 */
+#define B43_NPHY_RFCTL_LUT_TRSW_UP2            B43_PHY_N(0x0FB) /* RF control LUT TRSW upper 2 */
+#define B43_NPHY_RFCTL_LUT_TRSW_LO3            B43_PHY_N(0x0FC) /* RF control LUT TRSW lower 3 */
+#define B43_NPHY_RFCTL_LUT_TRSW_UP3            B43_PHY_N(0x0FD) /* RF control LUT TRSW upper 3 */
+#define B43_NPHY_RFCTL_LUT_TRSW_LO4            B43_PHY_N(0x0FE) /* RF control LUT TRSW lower 4 */
+#define B43_NPHY_RFCTL_LUT_TRSW_UP4            B43_PHY_N(0x0FF) /* RF control LUT TRSW upper 4 */
+#define B43_NPHY_RFCTL_LUT_LNAPA1              B43_PHY_N(0x100) /* RF control LUT LNA PA 1 */
+#define B43_NPHY_RFCTL_LUT_LNAPA2              B43_PHY_N(0x101) /* RF control LUT LNA PA 2 */
+#define B43_NPHY_RFCTL_LUT_LNAPA3              B43_PHY_N(0x102) /* RF control LUT LNA PA 3 */
+#define B43_NPHY_RFCTL_LUT_LNAPA4              B43_PHY_N(0x103) /* RF control LUT LNA PA 4 */
+#define B43_NPHY_TGNSYNC_CRCM0                 B43_PHY_N(0x104) /* TGNsync CRC mask 0 */
+#define B43_NPHY_TGNSYNC_CRCM1                 B43_PHY_N(0x105) /* TGNsync CRC mask 1 */
+#define B43_NPHY_TGNSYNC_CRCM2                 B43_PHY_N(0x106) /* TGNsync CRC mask 2 */
+#define B43_NPHY_TGNSYNC_CRCM3                 B43_PHY_N(0x107) /* TGNsync CRC mask 3 */
+#define B43_NPHY_TGNSYNC_CRCM4                 B43_PHY_N(0x108) /* TGNsync CRC mask 4 */
+#define B43_NPHY_CRCPOLY                       B43_PHY_N(0x109) /* CRC polynomial */
+#define B43_NPHY_SIGCNT                                B43_PHY_N(0x10A) /* # sig count */
+#define B43_NPHY_SIGSTARTBIT_CTL               B43_PHY_N(0x10B) /* Sig start bit control */
+#define B43_NPHY_CRCPOLY_ORDER                 B43_PHY_N(0x10C) /* CRC polynomial order */
+#define B43_NPHY_RFCTL_CST0                    B43_PHY_N(0x10D) /* RF control core swap table 0 */
+#define B43_NPHY_RFCTL_CST1                    B43_PHY_N(0x10E) /* RF control core swap table 1 */
+#define B43_NPHY_RFCTL_CST2O                   B43_PHY_N(0x10F) /* RF control core swap table 2 + others */
+#define B43_NPHY_BPHY_CTL5                     B43_PHY_N(0x111) /* B PHY control 5 */
+#define B43_NPHY_RFSEQ_LPFBW                   B43_PHY_N(0x112) /* RF seq LPF bandwidth */
+#define B43_NPHY_TSSIBIAS1                     B43_PHY_N(0x114) /* TSSI bias val 1 */
+#define B43_NPHY_TSSIBIAS2                     B43_PHY_N(0x115) /* TSSI bias val 2 */
+#define  B43_NPHY_TSSIBIAS_BIAS                        0x00FF /* Bias */
+#define  B43_NPHY_TSSIBIAS_BIAS_SHIFT          0
+#define  B43_NPHY_TSSIBIAS_VAL                 0xFF00 /* Value */
+#define  B43_NPHY_TSSIBIAS_VAL_SHIFT           8
+#define B43_NPHY_ESTPWR1                       B43_PHY_N(0x118) /* Estimated power 1 */
+#define B43_NPHY_ESTPWR2                       B43_PHY_N(0x119) /* Estimated power 2 */
+#define  B43_NPHY_ESTPWR_PWR                   0x00FF /* Estimated power */
+#define  B43_NPHY_ESTPWR_PWR_SHIFT             0
+#define  B43_NPHY_ESTPWR_VALID                 0x0100 /* Estimated power valid */
+#define B43_NPHY_TSSI_MAXTXFDT                 B43_PHY_N(0x11C) /* TSSI max TX frame delay time */
+#define  B43_NPHY_TSSI_MAXTXFDT_VAL            0x00FF /* max TX frame delay time */
+#define  B43_NPHY_TSSI_MAXTXFDT_VAL_SHIFT      0
+#define B43_NPHY_TSSI_MAXTDT                   B43_PHY_N(0x11D) /* TSSI max TSSI delay time */
+#define  B43_NPHY_TSSI_MAXTDT_VAL              0x00FF /* max TSSI delay time */
+#define  B43_NPHY_TSSI_MAXTDT_VAL_SHIFT                0
+#define B43_NPHY_ITSSI1                                B43_PHY_N(0x11E) /* TSSI idle 1 */
+#define B43_NPHY_ITSSI2                                B43_PHY_N(0x11F) /* TSSI idle 2 */
+#define  B43_NPHY_ITSSI_VAL                    0x00FF /* Idle TSSI */
+#define  B43_NPHY_ITSSI_VAL_SHIFT              0
+#define B43_NPHY_TSSIMODE                      B43_PHY_N(0x122) /* TSSI mode */
+#define  B43_NPHY_TSSIMODE_EN                  0x0001 /* TSSI enable */
+#define  B43_NPHY_TSSIMODE_PDEN                        0x0002 /* Power det enable */
+#define B43_NPHY_RXMACIFM                      B43_PHY_N(0x123) /* RX Macif mode */
+#define B43_NPHY_CRSIT_COCNT_LO                        B43_PHY_N(0x124) /* CRS idle time CRS-on count (low) */
+#define B43_NPHY_CRSIT_COCNT_HI                        B43_PHY_N(0x125) /* CRS idle time CRS-on count (high) */
+#define B43_NPHY_CRSIT_MTCNT_LO                        B43_PHY_N(0x126) /* CRS idle time measure time count (low) */
+#define B43_NPHY_CRSIT_MTCNT_HI                        B43_PHY_N(0x127) /* CRS idle time measure time count (high) */
+#define B43_NPHY_SAMTWC                                B43_PHY_N(0x128) /* Sample tail wait count */
+#define B43_NPHY_IQEST_CMD                     B43_PHY_N(0x129) /* I/Q estimate command */
+#define  B43_NPHY_IQEST_CMD_START              0x0001 /* Start */
+#define  B43_NPHY_IQEST_CMD_MODE               0x0002 /* Mode */
+#define B43_NPHY_IQEST_WT                      B43_PHY_N(0x12A) /* I/Q estimate wait time */
+#define  B43_NPHY_IQEST_WT_VAL                 0x00FF /* Wait time */
+#define  B43_NPHY_IQEST_WT_VAL_SHIFT           0
+#define B43_NPHY_IQEST_SAMCNT                  B43_PHY_N(0x12B) /* I/Q estimate sample count */
+#define B43_NPHY_IQEST_IQACC_LO0               B43_PHY_N(0x12C) /* I/Q estimate I/Q acc lo 0 */
+#define B43_NPHY_IQEST_IQACC_HI0               B43_PHY_N(0x12D) /* I/Q estimate I/Q acc hi 0 */
+#define B43_NPHY_IQEST_IPACC_LO0               B43_PHY_N(0x12E) /* I/Q estimate I power acc lo 0 */
+#define B43_NPHY_IQEST_IPACC_HI0               B43_PHY_N(0x12F) /* I/Q estimate I power acc hi 0 */
+#define B43_NPHY_IQEST_QPACC_LO0               B43_PHY_N(0x130) /* I/Q estimate Q power acc lo 0 */
+#define B43_NPHY_IQEST_QPACC_HI0               B43_PHY_N(0x131) /* I/Q estimate Q power acc hi 0 */
+#define B43_NPHY_IQEST_IQACC_LO1               B43_PHY_N(0x134) /* I/Q estimate I/Q acc lo 1 */
+#define B43_NPHY_IQEST_IQACC_HI1               B43_PHY_N(0x135) /* I/Q estimate I/Q acc hi 1 */
+#define B43_NPHY_IQEST_IPACC_LO1               B43_PHY_N(0x136) /* I/Q estimate I power acc lo 1 */
+#define B43_NPHY_IQEST_IPACC_HI1               B43_PHY_N(0x137) /* I/Q estimate I power acc hi 1 */
+#define B43_NPHY_IQEST_QPACC_LO1               B43_PHY_N(0x138) /* I/Q estimate Q power acc lo 1 */
+#define B43_NPHY_IQEST_QPACC_HI1               B43_PHY_N(0x139) /* I/Q estimate Q power acc hi 1 */
+#define B43_NPHY_MIMO_CRSTXEXT                 B43_PHY_N(0x13A) /* MIMO PHY CRS TX extension */
+#define B43_NPHY_PWRDET1                       B43_PHY_N(0x13B) /* Power det 1 */
+#define B43_NPHY_PWRDET2                       B43_PHY_N(0x13C) /* Power det 2 */
+#define B43_NPHY_MAXRSSI_DTIME                 B43_PHY_N(0x13F) /* RSSI max RSSI delay time */
+#define B43_NPHY_PIL_DW0                       B43_PHY_N(0x141) /* Pilot data weight 0 */
+#define B43_NPHY_PIL_DW1                       B43_PHY_N(0x142) /* Pilot data weight 1 */
+#define B43_NPHY_PIL_DW2                       B43_PHY_N(0x143) /* Pilot data weight 2 */
+#define  B43_NPHY_PIL_DW_BPSK                  0x000F /* BPSK */
+#define  B43_NPHY_PIL_DW_BPSK_SHIFT            0
+#define  B43_NPHY_PIL_DW_QPSK                  0x00F0 /* QPSK */
+#define  B43_NPHY_PIL_DW_QPSK_SHIFT            4
+#define  B43_NPHY_PIL_DW_16QAM                 0x0F00 /* 16-QAM */
+#define  B43_NPHY_PIL_DW_16QAM_SHIFT           8
+#define  B43_NPHY_PIL_DW_64QAM                 0xF000 /* 64-QAM */
+#define  B43_NPHY_PIL_DW_64QAM_SHIFT           12
+#define B43_NPHY_FMDEM_CFG                     B43_PHY_N(0x144) /* FM demodulation config */
+#define B43_NPHY_PHASETR_A0                    B43_PHY_N(0x145) /* Phase track alpha 0 */
+#define B43_NPHY_PHASETR_A1                    B43_PHY_N(0x146) /* Phase track alpha 1 */
+#define B43_NPHY_PHASETR_A2                    B43_PHY_N(0x147) /* Phase track alpha 2 */
+#define B43_NPHY_PHASETR_B0                    B43_PHY_N(0x148) /* Phase track beta 0 */
+#define B43_NPHY_PHASETR_B1                    B43_PHY_N(0x149) /* Phase track beta 1 */
+#define B43_NPHY_PHASETR_B2                    B43_PHY_N(0x14A) /* Phase track beta 2 */
+#define B43_NPHY_PHASETR_CHG0                  B43_PHY_N(0x14B) /* Phase track change 0 */
+#define B43_NPHY_PHASETR_CHG1                  B43_PHY_N(0x14C) /* Phase track change 1 */
+#define B43_NPHY_PHASETW_OFF                   B43_PHY_N(0x14D) /* Phase track offset */
+#define B43_NPHY_RFCTL_DBG                     B43_PHY_N(0x14E) /* RF control debug */
+#define B43_NPHY_CCK_SHIFTB_REF                        B43_PHY_N(0x150) /* CCK shiftbits reference var */
+#define B43_NPHY_OVER_DGAIN0                   B43_PHY_N(0x152) /* Override digital gain 0 */
+#define B43_NPHY_OVER_DGAIN1                   B43_PHY_N(0x153) /* Override digital gain 1 */
+#define  B43_NPHY_OVER_DGAIN_FDGV              0x0007 /* Force digital gain value */
+#define  B43_NPHY_OVER_DGAIN_FDGV_SHIFT                0
+#define  B43_NPHY_OVER_DGAIN_FDGEN             0x0008 /* Force digital gain enable */
+#define  B43_NPHY_OVER_DGAIN_CCKDGECV          0xFF00 /* CCK digital gain enable count value */
+#define  B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT    8
+#define B43_NPHY_BIST_STAT4                    B43_PHY_N(0x156) /* BIST status 4 */
+#define B43_NPHY_RADAR_MAL                     B43_PHY_N(0x157) /* Radar MA length */
+#define B43_NPHY_RADAR_SRCCTL                  B43_PHY_N(0x158) /* Radar search control */
+#define B43_NPHY_VLD_DTSIG                     B43_PHY_N(0x159) /* VLD data tones sig */
+#define B43_NPHY_VLD_DTDAT                     B43_PHY_N(0x15A) /* VLD data tones data */
+#define B43_NPHY_C1_BPHY_RXIQCA0               B43_PHY_N(0x15B) /* Core 1 B PHY RX I/Q comp A0 */
+#define B43_NPHY_C1_BPHY_RXIQCB0               B43_PHY_N(0x15C) /* Core 1 B PHY RX I/Q comp B0 */
+#define B43_NPHY_C2_BPHY_RXIQCA1               B43_PHY_N(0x15D) /* Core 2 B PHY RX I/Q comp A1 */
+#define B43_NPHY_C2_BPHY_RXIQCB1               B43_PHY_N(0x15E) /* Core 2 B PHY RX I/Q comp B1 */
+#define B43_NPHY_FREQGAIN0                     B43_PHY_N(0x160) /* Frequency gain 0 */
+#define B43_NPHY_FREQGAIN1                     B43_PHY_N(0x161) /* Frequency gain 1 */
+#define B43_NPHY_FREQGAIN2                     B43_PHY_N(0x162) /* Frequency gain 2 */
+#define B43_NPHY_FREQGAIN3                     B43_PHY_N(0x163) /* Frequency gain 3 */
+#define B43_NPHY_FREQGAIN4                     B43_PHY_N(0x164) /* Frequency gain 4 */
+#define B43_NPHY_FREQGAIN5                     B43_PHY_N(0x165) /* Frequency gain 5 */
+#define B43_NPHY_FREQGAIN6                     B43_PHY_N(0x166) /* Frequency gain 6 */
+#define B43_NPHY_FREQGAIN7                     B43_PHY_N(0x167) /* Frequency gain 7 */
+#define B43_NPHY_FREQGAIN_BYPASS               B43_PHY_N(0x168) /* Frequency gain bypass */
+#define B43_NPHY_TRLOSS                                B43_PHY_N(0x169) /* TR loss value */
+#define B43_NPHY_C1_ADCCLIP                    B43_PHY_N(0x16A) /* Core 1 ADC clip */
+#define B43_NPHY_C2_ADCCLIP                    B43_PHY_N(0x16B) /* Core 2 ADC clip */
+#define B43_NPHY_LTRN_OFFGAIN                  B43_PHY_N(0x16F) /* LTRN offset gain */
+#define B43_NPHY_LTRN_OFF                      B43_PHY_N(0x170) /* LTRN offset */
+#define B43_NPHY_NRDATAT_WWISE20SIG            B43_PHY_N(0x171) /* # data tones WWiSE 20 sig */
+#define B43_NPHY_NRDATAT_WWISE40SIG            B43_PHY_N(0x172) /* # data tones WWiSE 40 sig */
+#define B43_NPHY_NRDATAT_TGNSYNC20SIG          B43_PHY_N(0x173) /* # data tones TGNsync 20 sig */
+#define B43_NPHY_NRDATAT_TGNSYNC40SIG          B43_PHY_N(0x174) /* # data tones TGNsync 40 sig */
+#define B43_NPHY_WWISE_CRCM0                   B43_PHY_N(0x175) /* WWiSE CRC mask 0 */
+#define B43_NPHY_WWISE_CRCM1                   B43_PHY_N(0x176) /* WWiSE CRC mask 1 */
+#define B43_NPHY_WWISE_CRCM2                   B43_PHY_N(0x177) /* WWiSE CRC mask 2 */
+#define B43_NPHY_WWISE_CRCM3                   B43_PHY_N(0x178) /* WWiSE CRC mask 3 */
+#define B43_NPHY_WWISE_CRCM4                   B43_PHY_N(0x179) /* WWiSE CRC mask 4 */
+#define B43_NPHY_CHANEST_CDDSH                 B43_PHY_N(0x17A) /* Channel estimate CDD shift */
+#define B43_NPHY_HTAGC_WCNT                    B43_PHY_N(0x17B) /* HT ADC wait counters */
+#define B43_NPHY_SQPARM                                B43_PHY_N(0x17C) /* SQ params */
+#define B43_NPHY_MCSDUP6M                      B43_PHY_N(0x17D) /* MCS dup 6M */
+#define B43_NPHY_NDATAT_DUP40                  B43_PHY_N(0x17E) /* # data tones dup 40 */
+#define B43_NPHY_DUP40_TGNSYNC_CYCD            B43_PHY_N(0x17F) /* Dup40 TGNsync cycle data */
+#define B43_NPHY_DUP40_GFBL                    B43_PHY_N(0x180) /* Dup40 GF format BL address */
+#define B43_NPHY_DUP40_BL                      B43_PHY_N(0x181) /* Dup40 format BL address */
+#define B43_NPHY_LEGDUP_FTA                    B43_PHY_N(0x182) /* Legacy dup frm table address */
+#define B43_NPHY_PACPROC_DBG                   B43_PHY_N(0x183) /* Packet processing debug */
+#define B43_NPHY_PIL_CYC1                      B43_PHY_N(0x184) /* Pilot cycle counter 1 */
+#define B43_NPHY_PIL_CYC2                      B43_PHY_N(0x185) /* Pilot cycle counter 2 */
+#define B43_NPHY_TXF_20CO_S0A1                 B43_PHY_N(0x186) /* TX filter 20 coeff stage 0 A1 */
+#define B43_NPHY_TXF_20CO_S0A2                 B43_PHY_N(0x187) /* TX filter 20 coeff stage 0 A2 */
+#define B43_NPHY_TXF_20CO_S1A1                 B43_PHY_N(0x188) /* TX filter 20 coeff stage 1 A1 */
+#define B43_NPHY_TXF_20CO_S1A2                 B43_PHY_N(0x189) /* TX filter 20 coeff stage 1 A2 */
+#define B43_NPHY_TXF_20CO_S2A1                 B43_PHY_N(0x18A) /* TX filter 20 coeff stage 2 A1 */
+#define B43_NPHY_TXF_20CO_S2A2                 B43_PHY_N(0x18B) /* TX filter 20 coeff stage 2 A2 */
+#define B43_NPHY_TXF_20CO_S0B1                 B43_PHY_N(0x18C) /* TX filter 20 coeff stage 0 B1 */
+#define B43_NPHY_TXF_20CO_S0B2                 B43_PHY_N(0x18D) /* TX filter 20 coeff stage 0 B2 */
+#define B43_NPHY_TXF_20CO_S0B3                 B43_PHY_N(0x18E) /* TX filter 20 coeff stage 0 B3 */
+#define B43_NPHY_TXF_20CO_S1B1                 B43_PHY_N(0x18F) /* TX filter 20 coeff stage 1 B1 */
+#define B43_NPHY_TXF_20CO_S1B2                 B43_PHY_N(0x190) /* TX filter 20 coeff stage 1 B2 */
+#define B43_NPHY_TXF_20CO_S1B3                 B43_PHY_N(0x191) /* TX filter 20 coeff stage 1 B3 */
+#define B43_NPHY_TXF_20CO_S2B1                 B43_PHY_N(0x192) /* TX filter 20 coeff stage 2 B1 */
+#define B43_NPHY_TXF_20CO_S2B2                 B43_PHY_N(0x193) /* TX filter 20 coeff stage 2 B2 */
+#define B43_NPHY_TXF_20CO_S2B3                 B43_PHY_N(0x194) /* TX filter 20 coeff stage 2 B3 */
+#define B43_NPHY_TXF_40CO_S0A1                 B43_PHY_N(0x195) /* TX filter 40 coeff stage 0 A1 */
+#define B43_NPHY_TXF_40CO_S0A2                 B43_PHY_N(0x196) /* TX filter 40 coeff stage 0 A2 */
+#define B43_NPHY_TXF_40CO_S1A1                 B43_PHY_N(0x197) /* TX filter 40 coeff stage 1 A1 */
+#define B43_NPHY_TXF_40CO_S1A2                 B43_PHY_N(0x198) /* TX filter 40 coeff stage 1 A2 */
+#define B43_NPHY_TXF_40CO_S2A1                 B43_PHY_N(0x199) /* TX filter 40 coeff stage 2 A1 */
+#define B43_NPHY_TXF_40CO_S2A2                 B43_PHY_N(0x19A) /* TX filter 40 coeff stage 2 A2 */
+#define B43_NPHY_TXF_40CO_S0B1                 B43_PHY_N(0x19B) /* TX filter 40 coeff stage 0 B1 */
+#define B43_NPHY_TXF_40CO_S0B2                 B43_PHY_N(0x19C) /* TX filter 40 coeff stage 0 B2 */
+#define B43_NPHY_TXF_40CO_S0B3                 B43_PHY_N(0x19D) /* TX filter 40 coeff stage 0 B3 */
+#define B43_NPHY_TXF_40CO_S1B1                 B43_PHY_N(0x19E) /* TX filter 40 coeff stage 1 B1 */
+#define B43_NPHY_TXF_40CO_S1B2                 B43_PHY_N(0x19F) /* TX filter 40 coeff stage 1 B2 */
+#define B43_NPHY_TXF_40CO_S1B3                 B43_PHY_N(0x1A0) /* TX filter 40 coeff stage 1 B3 */
+#define B43_NPHY_TXF_40CO_S2B1                 B43_PHY_N(0x1A1) /* TX filter 40 coeff stage 2 B1 */
+#define B43_NPHY_TXF_40CO_S2B2                 B43_PHY_N(0x1A2) /* TX filter 40 coeff stage 2 B2 */
+#define B43_NPHY_TXF_40CO_S2B3                 B43_PHY_N(0x1A3) /* TX filter 40 coeff stage 2 B3 */
+#define B43_NPHY_RSSIMC_0I_RSSI_X              B43_PHY_N(0x1A4) /* RSSI multiplication coefficient 0 I RSSI X */
+#define B43_NPHY_RSSIMC_0I_RSSI_Y              B43_PHY_N(0x1A5) /* RSSI multiplication coefficient 0 I RSSI Y */
+#define B43_NPHY_RSSIMC_0I_RSSI_Z              B43_PHY_N(0x1A6) /* RSSI multiplication coefficient 0 I RSSI Z */
+#define B43_NPHY_RSSIMC_0I_TBD                 B43_PHY_N(0x1A7) /* RSSI multiplication coefficient 0 I TBD */
+#define B43_NPHY_RSSIMC_0I_PWRDET              B43_PHY_N(0x1A8) /* RSSI multiplication coefficient 0 I power det */
+#define B43_NPHY_RSSIMC_0I_TSSI                        B43_PHY_N(0x1A9) /* RSSI multiplication coefficient 0 I TSSI */
+#define B43_NPHY_RSSIMC_0Q_RSSI_X              B43_PHY_N(0x1AA) /* RSSI multiplication coefficient 0 Q RSSI X */
+#define B43_NPHY_RSSIMC_0Q_RSSI_Y              B43_PHY_N(0x1AB) /* RSSI multiplication coefficient 0 Q RSSI Y */
+#define B43_NPHY_RSSIMC_0Q_RSSI_Z              B43_PHY_N(0x1AC) /* RSSI multiplication coefficient 0 Q RSSI Z */
+#define B43_NPHY_RSSIMC_0Q_TBD                 B43_PHY_N(0x1AD) /* RSSI multiplication coefficient 0 Q TBD */
+#define B43_NPHY_RSSIMC_0Q_PWRDET              B43_PHY_N(0x1AE) /* RSSI multiplication coefficient 0 Q power det */
+#define B43_NPHY_RSSIMC_0Q_TSSI                        B43_PHY_N(0x1AF) /* RSSI multiplication coefficient 0 Q TSSI */
+#define B43_NPHY_RSSIMC_1I_RSSI_X              B43_PHY_N(0x1B0) /* RSSI multiplication coefficient 1 I RSSI X */
+#define B43_NPHY_RSSIMC_1I_RSSI_Y              B43_PHY_N(0x1B1) /* RSSI multiplication coefficient 1 I RSSI Y */
+#define B43_NPHY_RSSIMC_1I_RSSI_Z              B43_PHY_N(0x1B2) /* RSSI multiplication coefficient 1 I RSSI Z */
+#define B43_NPHY_RSSIMC_1I_TBD                 B43_PHY_N(0x1B3) /* RSSI multiplication coefficient 1 I TBD */
+#define B43_NPHY_RSSIMC_1I_PWRDET              B43_PHY_N(0x1B4) /* RSSI multiplication coefficient 1 I power det */
+#define B43_NPHY_RSSIMC_1I_TSSI                        B43_PHY_N(0x1B5) /* RSSI multiplication coefficient 1 I TSSI */
+#define B43_NPHY_RSSIMC_1Q_RSSI_X              B43_PHY_N(0x1B6) /* RSSI multiplication coefficient 1 Q RSSI X */
+#define B43_NPHY_RSSIMC_1Q_RSSI_Y              B43_PHY_N(0x1B7) /* RSSI multiplication coefficient 1 Q RSSI Y */
+#define B43_NPHY_RSSIMC_1Q_RSSI_Z              B43_PHY_N(0x1B8) /* RSSI multiplication coefficient 1 Q RSSI Z */
+#define B43_NPHY_RSSIMC_1Q_TBD                 B43_PHY_N(0x1B9) /* RSSI multiplication coefficient 1 Q TBD */
+#define B43_NPHY_RSSIMC_1Q_PWRDET              B43_PHY_N(0x1BA) /* RSSI multiplication coefficient 1 Q power det */
+#define B43_NPHY_RSSIMC_1Q_TSSI                        B43_PHY_N(0x1BB) /* RSSI multiplication coefficient 1 Q TSSI */
+#define B43_NPHY_SAMC_WCNT                     B43_PHY_N(0x1BC) /* Sample collect wait counter */
+#define B43_NPHY_PTHROUGH_CNT                  B43_PHY_N(0x1BD) /* Pass-through counter */
+#define B43_NPHY_LTRN_OFF_G20L                 B43_PHY_N(0x1C4) /* LTRN offset gain 20L */
+#define B43_NPHY_LTRN_OFF_20L                  B43_PHY_N(0x1C5) /* LTRN offset 20L */
+#define B43_NPHY_LTRN_OFF_G20U                 B43_PHY_N(0x1C6) /* LTRN offset gain 20U */
+#define B43_NPHY_LTRN_OFF_20U                  B43_PHY_N(0x1C7) /* LTRN offset 20U */
+#define B43_NPHY_DSSSCCK_GAINSL                        B43_PHY_N(0x1C8) /* DSSS/CCK gain settle length */
+#define B43_NPHY_GPIO_LOOUT                    B43_PHY_N(0x1C9) /* GPIO low out */
+#define B43_NPHY_GPIO_HIOUT                    B43_PHY_N(0x1CA) /* GPIO high out */
+#define B43_NPHY_CRS_CHECK                     B43_PHY_N(0x1CB) /* CRS check */
+#define B43_NPHY_ML_LOGSS_RAT                  B43_PHY_N(0x1CC) /* ML/logss ratio */
+#define B43_NPHY_DUPSCALE                      B43_PHY_N(0x1CD) /* Dup scale */
+#define B43_NPHY_BW1A                          B43_PHY_N(0x1CE) /* BW 1A */
+#define B43_NPHY_BW2                           B43_PHY_N(0x1CF) /* BW 2 */
+#define B43_NPHY_BW3                           B43_PHY_N(0x1D0) /* BW 3 */
+#define B43_NPHY_BW4                           B43_PHY_N(0x1D1) /* BW 4 */
+#define B43_NPHY_BW5                           B43_PHY_N(0x1D2) /* BW 5 */
+#define B43_NPHY_BW6                           B43_PHY_N(0x1D3) /* BW 6 */
+#define B43_NPHY_COALEN0                       B43_PHY_N(0x1D4) /* Coarse length 0 */
+#define B43_NPHY_COALEN1                       B43_PHY_N(0x1D5) /* Coarse length 1 */
+#define B43_NPHY_CRSTHRES_1U                   B43_PHY_N(0x1D6) /* CRS threshold 1 U */
+#define B43_NPHY_CRSTHRES_2U                   B43_PHY_N(0x1D7) /* CRS threshold 2 U */
+#define B43_NPHY_CRSTHRES_3U                   B43_PHY_N(0x1D8) /* CRS threshold 3 U */
+#define B43_NPHY_CRSCTL_U                      B43_PHY_N(0x1D9) /* CRS control U */
+#define B43_NPHY_CRSTHRES_1L                   B43_PHY_N(0x1DA) /* CRS threshold 1 L */
+#define B43_NPHY_CRSTHRES_2L                   B43_PHY_N(0x1DB) /* CRS threshold 2 L */
+#define B43_NPHY_CRSTHRES_3L                   B43_PHY_N(0x1DC) /* CRS threshold 3 L */
+#define B43_NPHY_CRSCTL_L                      B43_PHY_N(0x1DD) /* CRS control L */
+#define B43_NPHY_STRA_1U                       B43_PHY_N(0x1DE) /* STR address 1 U */
+#define B43_NPHY_STRA_2U                       B43_PHY_N(0x1DF) /* STR address 2 U */
+#define B43_NPHY_STRA_1L                       B43_PHY_N(0x1E0) /* STR address 1 L */
+#define B43_NPHY_STRA_2L                       B43_PHY_N(0x1E1) /* STR address 2 L */
+#define B43_NPHY_CRSCHECK1                     B43_PHY_N(0x1E2) /* CRS check 1 */
+#define B43_NPHY_CRSCHECK2                     B43_PHY_N(0x1E3) /* CRS check 2 */
+#define B43_NPHY_CRSCHECK3                     B43_PHY_N(0x1E4) /* CRS check 3 */
+#define B43_NPHY_JMPSTP0                       B43_PHY_N(0x1E5) /* Jump step 0 */
+#define B43_NPHY_JMPSTP1                       B43_PHY_N(0x1E6) /* Jump step 1 */
+#define B43_NPHY_TXPCTL_CMD                    B43_PHY_N(0x1E7) /* TX power control command */
+#define  B43_NPHY_TXPCTL_CMD_INIT              0x007F /* Init */
+#define  B43_NPHY_TXPCTL_CMD_INIT_SHIFT                0
+#define  B43_NPHY_TXPCTL_CMD_COEFF             0x2000 /* Power control coefficients */
+#define  B43_NPHY_TXPCTL_CMD_HWPCTLEN          0x4000 /* Hardware TX power control enable */
+#define  B43_NPHY_TXPCTL_CMD_PCTLEN            0x8000 /* TX power control enable */
+#define B43_NPHY_TXPCTL_N                      B43_PHY_N(0x1E8) /* TX power control N num */
+#define  B43_NPHY_TXPCTL_N_TSSID               0x00FF /* N TSSI delay */
+#define  B43_NPHY_TXPCTL_N_TSSID_SHIFT         0
+#define  B43_NPHY_TXPCTL_N_NPTIL2              0x0700 /* N PT integer log2 */
+#define  B43_NPHY_TXPCTL_N_NPTIL2_SHIFT                8
+#define B43_NPHY_TXPCTL_ITSSI                  B43_PHY_N(0x1E9) /* TX power control idle TSSI */
+#define  B43_NPHY_TXPCTL_ITSSI_0               0x003F /* Idle TSSI 0 */
+#define  B43_NPHY_TXPCTL_ITSSI_0_SHIFT         0
+#define  B43_NPHY_TXPCTL_ITSSI_1               0x3F00 /* Idle TSSI 1 */
+#define  B43_NPHY_TXPCTL_ITSSI_1_SHIFT         8
+#define  B43_NPHY_TXPCTL_ITSSI_BINF            0x8000 /* Raw TSSI offset bin format */
+#define B43_NPHY_TXPCTL_TPWR                   B43_PHY_N(0x1EA) /* TX power control target power */
+#define  B43_NPHY_TXPCTL_TPWR_0                        0x00FF /* Power 0 */
+#define  B43_NPHY_TXPCTL_TPWR_0_SHIFT          0
+#define  B43_NPHY_TXPCTL_TPWR_1                        0xFF00 /* Power 1 */
+#define  B43_NPHY_TXPCTL_TPWR_1_SHIFT          8
+#define B43_NPHY_TXPCTL_BIDX                   B43_PHY_N(0x1EB) /* TX power control base index */
+#define  B43_NPHY_TXPCTL_BIDX_0                        0x007F /* uC base index 0 */
+#define  B43_NPHY_TXPCTL_BIDX_0_SHIFT          0
+#define  B43_NPHY_TXPCTL_BIDX_1                        0x7F00 /* uC base index 1 */
+#define  B43_NPHY_TXPCTL_BIDX_1_SHIFT          8
+#define  B43_NPHY_TXPCTL_BIDX_LOAD             0x8000 /* Load base index */
+#define B43_NPHY_TXPCTL_PIDX                   B43_PHY_N(0x1EC) /* TX power control power index */
+#define  B43_NPHY_TXPCTL_PIDX_0                        0x007F /* uC power index 0 */
+#define  B43_NPHY_TXPCTL_PIDX_0_SHIFT          0
+#define  B43_NPHY_TXPCTL_PIDX_1                        0x7F00 /* uC power index 1 */
+#define  B43_NPHY_TXPCTL_PIDX_1_SHIFT          8
+#define B43_NPHY_C1_TXPCTL_STAT                        B43_PHY_N(0x1ED) /* Core 1 TX power control status */
+#define B43_NPHY_C2_TXPCTL_STAT                        B43_PHY_N(0x1EE) /* Core 2 TX power control status */
+#define  B43_NPHY_TXPCTL_STAT_EST              0x00FF /* Estimated power */
+#define  B43_NPHY_TXPCTL_STAT_EST_SHIFT                0
+#define  B43_NPHY_TXPCTL_STAT_BIDX             0x7F00 /* Base index */
+#define  B43_NPHY_TXPCTL_STAT_BIDX_SHIFT       8
+#define  B43_NPHY_TXPCTL_STAT_ESTVALID         0x8000 /* Estimated power valid */
+#define B43_NPHY_SMALLSGS_LEN                  B43_PHY_N(0x1EF) /* Small sig gain settle length */
+#define B43_NPHY_PHYSTAT_GAIN0                 B43_PHY_N(0x1F0) /* PHY stats gain info 0 */
+#define B43_NPHY_PHYSTAT_GAIN1                 B43_PHY_N(0x1F1) /* PHY stats gain info 1 */
+#define B43_NPHY_PHYSTAT_FREQEST               B43_PHY_N(0x1F2) /* PHY stats frequency estimate */
+#define B43_NPHY_PHYSTAT_ADVRET                        B43_PHY_N(0x1F3) /* PHY stats ADV retard */
+#define B43_NPHY_PHYLB_MODE                    B43_PHY_N(0x1F4) /* PHY loopback mode */
+#define B43_NPHY_TONE_MIDX20_1                 B43_PHY_N(0x1F5) /* Tone map index 20/1 */
+#define B43_NPHY_TONE_MIDX20_2                 B43_PHY_N(0x1F6) /* Tone map index 20/2 */
+#define B43_NPHY_TONE_MIDX20_3                 B43_PHY_N(0x1F7) /* Tone map index 20/3 */
+#define B43_NPHY_TONE_MIDX40_1                 B43_PHY_N(0x1F8) /* Tone map index 40/1 */
+#define B43_NPHY_TONE_MIDX40_2                 B43_PHY_N(0x1F9) /* Tone map index 40/2 */
+#define B43_NPHY_TONE_MIDX40_3                 B43_PHY_N(0x1FA) /* Tone map index 40/3 */
+#define B43_NPHY_TONE_MIDX40_4                 B43_PHY_N(0x1FB) /* Tone map index 40/4 */
+#define B43_NPHY_PILTONE_MIDX1                 B43_PHY_N(0x1FC) /* Pilot tone map index 1 */
+#define B43_NPHY_PILTONE_MIDX2                 B43_PHY_N(0x1FD) /* Pilot tone map index 2 */
+#define B43_NPHY_PILTONE_MIDX3                 B43_PHY_N(0x1FE) /* Pilot tone map index 3 */
+#define B43_NPHY_TXRIFS_FRDEL                  B43_PHY_N(0x1FF) /* TX RIFS frame delay */
+#define B43_NPHY_AFESEQ_RX2TX_PUD_40M          B43_PHY_N(0x200) /* AFE seq rx2tx power up/down delay 40M */
+#define B43_NPHY_AFESEQ_TX2RX_PUD_40M          B43_PHY_N(0x201) /* AFE seq tx2rx power up/down delay 40M */
+#define B43_NPHY_AFESEQ_RX2TX_PUD_20M          B43_PHY_N(0x202) /* AFE seq rx2tx power up/down delay 20M */
+#define B43_NPHY_AFESEQ_TX2RX_PUD_20M          B43_PHY_N(0x203) /* AFE seq tx2rx power up/down delay 20M */
+#define B43_NPHY_RX_SIGCTL                     B43_PHY_N(0x204) /* RX signal control */
+#define B43_NPHY_RXPIL_CYCNT0                  B43_PHY_N(0x205) /* RX pilot cycle counter 0 */
+#define B43_NPHY_RXPIL_CYCNT1                  B43_PHY_N(0x206) /* RX pilot cycle counter 1 */
+#define B43_NPHY_RXPIL_CYCNT2                  B43_PHY_N(0x207) /* RX pilot cycle counter 2 */
+#define B43_NPHY_AFESEQ_RX2TX_PUD_10M          B43_PHY_N(0x208) /* AFE seq rx2tx power up/down delay 10M */
+#define B43_NPHY_AFESEQ_TX2RX_PUD_10M          B43_PHY_N(0x209) /* AFE seq tx2rx power up/down delay 10M */
+#define B43_NPHY_DSSSCCK_CRSEXTL               B43_PHY_N(0x20A) /* DSSS/CCK CRS extension length */
+#define B43_NPHY_ML_LOGSS_RATSLOPE             B43_PHY_N(0x20B) /* ML/logss ratio slope */
+#define B43_NPHY_RIFS_SRCTL                    B43_PHY_N(0x20C) /* RIFS search timeout length */
+#define B43_NPHY_TXREALFD                      B43_PHY_N(0x20D) /* TX real frame delay */
+#define B43_NPHY_HPANT_SWTHRES                 B43_PHY_N(0x20E) /* High power antenna switch threshold */
+#define B43_NPHY_EDCRS_ASSTHRES0               B43_PHY_N(0x210) /* ED CRS assert threshold 0 */
+#define B43_NPHY_EDCRS_ASSTHRES1               B43_PHY_N(0x211) /* ED CRS assert threshold 1 */
+#define B43_NPHY_EDCRS_DEASSTHRES0             B43_PHY_N(0x212) /* ED CRS deassert threshold 0 */
+#define B43_NPHY_EDCRS_DEASSTHRES1             B43_PHY_N(0x213) /* ED CRS deassert threshold 1 */
+#define B43_NPHY_STR_WTIME20U                  B43_PHY_N(0x214) /* STR wait time 20U */
+#define B43_NPHY_STR_WTIME20L                  B43_PHY_N(0x215) /* STR wait time 20L */
+#define B43_NPHY_TONE_MIDX657M                 B43_PHY_N(0x216) /* Tone map index 657M */
+#define B43_NPHY_HTSIGTONES                    B43_PHY_N(0x217) /* HT signal tones */
+#define B43_NPHY_RSSI1                         B43_PHY_N(0x219) /* RSSI value 1 */
+#define B43_NPHY_RSSI2                         B43_PHY_N(0x21A) /* RSSI value 2 */
+#define B43_NPHY_CHAN_ESTHANG                  B43_PHY_N(0x21D) /* Channel estimate hang */
+#define B43_NPHY_FINERX2_CGC                   B43_PHY_N(0x221) /* Fine RX 2 clock gate control */
+#define  B43_NPHY_FINERX2_CGC_DECGC            0x0008 /* Decode gated clocks */
+#define B43_NPHY_TXPCTL_INIT                   B43_PHY_N(0x222) /* TX power controll init */
+#define  B43_NPHY_TXPCTL_INIT_PIDXI1           0x00FF /* Power index init 1 */
+#define  B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT     0
+
+
+
+/* Broadcom 2055 radio registers */
+
+#define B2055_GEN_SPARE                        0x00 /* GEN spare */
+#define B2055_SP_PINPD                 0x02 /* SP PIN PD */
+#define B2055_C1_SP_RSSI               0x03 /* SP RSSI Core 1 */
+#define B2055_C1_SP_PDMISC             0x04 /* SP PD MISC Core 1 */
+#define B2055_C2_SP_RSSI               0x05 /* SP RSSI Core 2 */
+#define B2055_C2_SP_PDMISC             0x06 /* SP PD MISC Core 2 */
+#define B2055_C1_SP_RXGC1              0x07 /* SP RX GC1 Core 1 */
+#define B2055_C1_SP_RXGC2              0x08 /* SP RX GC2 Core 1 */
+#define B2055_C2_SP_RXGC1              0x09 /* SP RX GC1 Core 2 */
+#define B2055_C2_SP_RXGC2              0x0A /* SP RX GC2 Core 2 */
+#define B2055_C1_SP_LPFBWSEL           0x0B /* SP LPF BW select Core 1 */
+#define B2055_C2_SP_LPFBWSEL           0x0C /* SP LPF BW select Core 2 */
+#define B2055_C1_SP_TXGC1              0x0D /* SP TX GC1 Core 1 */
+#define B2055_C1_SP_TXGC2              0x0E /* SP TX GC2 Core 1 */
+#define B2055_C2_SP_TXGC1              0x0F /* SP TX GC1 Core 2 */
+#define B2055_C2_SP_TXGC2              0x10 /* SP TX GC2 Core 2 */
+#define B2055_MASTER1                  0x11 /* Master control 1 */
+#define B2055_MASTER2                  0x12 /* Master control 2 */
+#define B2055_PD_LGEN                  0x13 /* PD LGEN */
+#define B2055_PD_PLLTS                 0x14 /* PD PLL TS */
+#define B2055_C1_PD_LGBUF              0x15 /* PD Core 1 LGBUF */
+#define B2055_C1_PD_TX                 0x16 /* PD Core 1 TX */
+#define B2055_C1_PD_RXTX               0x17 /* PD Core 1 RXTX */
+#define B2055_C1_PD_RSSIMISC           0x18 /* PD Core 1 RSSI MISC */
+#define B2055_C2_PD_LGBUF              0x19 /* PD Core 2 LGBUF */
+#define B2055_C2_PD_TX                 0x1A /* PD Core 2 TX */
+#define B2055_C2_PD_RXTX               0x1B /* PD Core 2 RXTX */
+#define B2055_C2_PD_RSSIMISC           0x1C /* PD Core 2 RSSI MISC */
+#define B2055_PWRDET_LGEN              0x1D /* PWRDET LGEN */
+#define B2055_C1_PWRDET_LGBUF          0x1E /* PWRDET LGBUF Core 1 */
+#define B2055_C1_PWRDET_RXTX           0x1F /* PWRDET RXTX Core 1 */
+#define B2055_C2_PWRDET_LGBUF          0x20 /* PWRDET LGBUF Core 2 */
+#define B2055_C2_PWRDET_RXTX           0x21 /* PWRDET RXTX Core 2 */
+#define B2055_RRCCAL_CS                        0x22 /* RRCCAL Control spare */
+#define B2055_RRCCAL_NOPTSEL           0x23 /* RRCCAL N OPT SEL */
+#define B2055_CAL_MISC                 0x24 /* CAL MISC */
+#define B2055_CAL_COUT                 0x25 /* CAL Counter out */
+#define B2055_CAL_COUT2                        0x26 /* CAL Counter out 2 */
+#define B2055_CAL_CVARCTL              0x27 /* CAL CVAR Control */
+#define B2055_CAL_RVARCTL              0x28 /* CAL RVAR Control */
+#define B2055_CAL_LPOCTL               0x29 /* CAL LPO Control */
+#define B2055_CAL_TS                   0x2A /* CAL TS */
+#define B2055_CAL_RCCALRTS             0x2B /* CAL RCCAL READ TS */
+#define B2055_CAL_RCALRTS              0x2C /* CAL RCAL READ TS */
+#define B2055_PADDRV                   0x2D /* PAD driver */
+#define B2055_XOCTL1                   0x2E /* XO Control 1 */
+#define B2055_XOCTL2                   0x2F /* XO Control 2 */
+#define B2055_XOREGUL                  0x30 /* XO Regulator */
+#define B2055_XOMISC                   0x31 /* XO misc */
+#define B2055_PLL_LFC1                 0x32 /* PLL LF C1 */
+#define B2055_PLL_CALVTH               0x33 /* PLL CAL VTH */
+#define B2055_PLL_LFC2                 0x34 /* PLL LF C2 */
+#define B2055_PLL_REF                  0x35 /* PLL reference */
+#define B2055_PLL_LFR1                 0x36 /* PLL LF R1 */
+#define B2055_PLL_PFDCP                        0x37 /* PLL PFD CP */
+#define B2055_PLL_IDAC_CPOPAMP         0x38 /* PLL IDAC CPOPAMP */
+#define B2055_PLL_CPREG                        0x39 /* PLL CP Regulator */
+#define B2055_PLL_RCAL                 0x3A /* PLL RCAL */
+#define B2055_RF_PLLMOD0               0x3B /* RF PLL MOD0 */
+#define B2055_RF_PLLMOD1               0x3C /* RF PLL MOD1 */
+#define B2055_RF_MMDIDAC1              0x3D /* RF MMD IDAC 1 */
+#define B2055_RF_MMDIDAC0              0x3E /* RF MMD IDAC 0 */
+#define B2055_RF_MMDSP                 0x3F /* RF MMD spare */
+#define B2055_VCO_CAL1                 0x40 /* VCO cal 1 */
+#define B2055_VCO_CAL2                 0x41 /* VCO cal 2 */
+#define B2055_VCO_CAL3                 0x42 /* VCO cal 3 */
+#define B2055_VCO_CAL4                 0x43 /* VCO cal 4 */
+#define B2055_VCO_CAL5                 0x44 /* VCO cal 5 */
+#define B2055_VCO_CAL6                 0x45 /* VCO cal 6 */
+#define B2055_VCO_CAL7                 0x46 /* VCO cal 7 */
+#define B2055_VCO_CAL8                 0x47 /* VCO cal 8 */
+#define B2055_VCO_CAL9                 0x48 /* VCO cal 9 */
+#define B2055_VCO_CAL10                        0x49 /* VCO cal 10 */
+#define B2055_VCO_CAL11                        0x4A /* VCO cal 11 */
+#define B2055_VCO_CAL12                        0x4B /* VCO cal 12 */
+#define B2055_VCO_CAL13                        0x4C /* VCO cal 13 */
+#define B2055_VCO_CAL14                        0x4D /* VCO cal 14 */
+#define B2055_VCO_CAL15                        0x4E /* VCO cal 15 */
+#define B2055_VCO_CAL16                        0x4F /* VCO cal 16 */
+#define B2055_VCO_KVCO                 0x50 /* VCO KVCO */
+#define B2055_VCO_CAPTAIL              0x51 /* VCO CAP TAIL */
+#define B2055_VCO_IDACVCO              0x52 /* VCO IDAC VCO */
+#define B2055_VCO_REG                  0x53 /* VCO Regulator */
+#define B2055_PLL_RFVTH                        0x54 /* PLL RF VTH */
+#define B2055_LGBUF_CENBUF             0x55 /* LGBUF CEN BUF */
+#define B2055_LGEN_TUNE1               0x56 /* LGEN tune 1 */
+#define B2055_LGEN_TUNE2               0x57 /* LGEN tune 2 */
+#define B2055_LGEN_IDAC1               0x58 /* LGEN IDAC 1 */
+#define B2055_LGEN_IDAC2               0x59 /* LGEN IDAC 2 */
+#define B2055_LGEN_BIASC               0x5A /* LGEN BIAS counter */
+#define B2055_LGEN_BIASIDAC            0x5B /* LGEN BIAS IDAC */
+#define B2055_LGEN_RCAL                        0x5C /* LGEN RCAL */
+#define B2055_LGEN_DIV                 0x5D /* LGEN div */
+#define B2055_LGEN_SPARE2              0x5E /* LGEN spare 2 */
+#define B2055_C1_LGBUF_ATUNE           0x5F /* Core 1 LGBUF A tune */
+#define B2055_C1_LGBUF_GTUNE           0x60 /* Core 1 LGBUF G tune */
+#define B2055_C1_LGBUF_DIV             0x61 /* Core 1 LGBUF div */
+#define B2055_C1_LGBUF_AIDAC           0x62 /* Core 1 LGBUF A IDAC */
+#define B2055_C1_LGBUF_GIDAC           0x63 /* Core 1 LGBUF G IDAC */
+#define B2055_C1_LGBUF_IDACFO          0x64 /* Core 1 LGBUF IDAC filter override */
+#define B2055_C1_LGBUF_SPARE           0x65 /* Core 1 LGBUF spare */
+#define B2055_C1_RX_RFSPC1             0x66 /* Core 1 RX RF SPC1 */
+#define B2055_C1_RX_RFR1               0x67 /* Core 1 RX RF reg 1 */
+#define B2055_C1_RX_RFR2               0x68 /* Core 1 RX RF reg 2 */
+#define B2055_C1_RX_RFRCAL             0x69 /* Core 1 RX RF RCAL */
+#define B2055_C1_RX_BB_BLCMP           0x6A /* Core 1 RX Baseband BUFI LPF CMP */
+#define B2055_C1_RX_BB_LPF             0x6B /* Core 1 RX Baseband LPF */
+#define B2055_C1_RX_BB_MIDACHP         0x6C /* Core 1 RX Baseband MIDAC High-pass */
+#define B2055_C1_RX_BB_VGA1IDAC                0x6D /* Core 1 RX Baseband VGA1 IDAC */
+#define B2055_C1_RX_BB_VGA2IDAC                0x6E /* Core 1 RX Baseband VGA2 IDAC */
+#define B2055_C1_RX_BB_VGA3IDAC                0x6F /* Core 1 RX Baseband VGA3 IDAC */
+#define B2055_C1_RX_BB_BUFOCTL         0x70 /* Core 1 RX Baseband BUFO Control */
+#define B2055_C1_RX_BB_RCCALCTL                0x71 /* Core 1 RX Baseband RCCAL Control */
+#define B2055_C1_RX_BB_RSSICTL1                0x72 /* Core 1 RX Baseband RSSI Control 1 */
+#define B2055_C1_RX_BB_RSSICTL2                0x73 /* Core 1 RX Baseband RSSI Control 2 */
+#define B2055_C1_RX_BB_RSSICTL3                0x74 /* Core 1 RX Baseband RSSI Control 3 */
+#define B2055_C1_RX_BB_RSSICTL4                0x75 /* Core 1 RX Baseband RSSI Control 4 */
+#define B2055_C1_RX_BB_RSSICTL5                0x76 /* Core 1 RX Baseband RSSI Control 5 */
+#define B2055_C1_RX_BB_REG             0x77 /* Core 1 RX Baseband Regulator */
+#define B2055_C1_RX_BB_SPARE1          0x78 /* Core 1 RX Baseband spare 1 */
+#define B2055_C1_RX_TXBBRCAL           0x79 /* Core 1 RX TX BB RCAL */
+#define B2055_C1_TX_RF_SPGA            0x7A /* Core 1 TX RF SGM PGA */
+#define B2055_C1_TX_RF_SPAD            0x7B /* Core 1 TX RF SGM PAD */
+#define B2055_C1_TX_RF_CNTPGA1         0x7C /* Core 1 TX RF counter PGA 1 */
+#define B2055_C1_TX_RF_CNTPAD1         0x7D /* Core 1 TX RF counter PAD 1 */
+#define B2055_C1_TX_RF_PGAIDAC         0x7E /* Core 1 TX RF PGA IDAC */
+#define B2055_C1_TX_PGAPADTN           0x7F /* Core 1 TX PGA PAD TN */
+#define B2055_C1_TX_PADIDAC1           0x80 /* Core 1 TX PAD IDAC 1 */
+#define B2055_C1_TX_PADIDAC2           0x81 /* Core 1 TX PAD IDAC 2 */
+#define B2055_C1_TX_MXBGTRIM           0x82 /* Core 1 TX MX B/G TRIM */
+#define B2055_C1_TX_RF_RCAL            0x83 /* Core 1 TX RF RCAL */
+#define B2055_C1_TX_RF_PADTSSI1                0x84 /* Core 1 TX RF PAD TSSI1 */
+#define B2055_C1_TX_RF_PADTSSI2                0x85 /* Core 1 TX RF PAD TSSI2 */
+#define B2055_C1_TX_RF_SPARE           0x86 /* Core 1 TX RF spare */
+#define B2055_C1_TX_RF_IQCAL1          0x87 /* Core 1 TX RF I/Q CAL 1 */
+#define B2055_C1_TX_RF_IQCAL2          0x88 /* Core 1 TX RF I/Q CAL 2 */
+#define B2055_C1_TXBB_RCCAL            0x89 /* Core 1 TXBB RC CAL Control */
+#define B2055_C1_TXBB_LPF1             0x8A /* Core 1 TXBB LPF 1 */
+#define B2055_C1_TX_VOSCNCL            0x8B /* Core 1 TX VOS CNCL */
+#define B2055_C1_TX_LPF_MXGMIDAC       0x8C /* Core 1 TX LPF MXGM IDAC */
+#define B2055_C1_TX_BB_MXGM            0x8D /* Core 1 TX BB MXGM */
+#define B2055_C2_LGBUF_ATUNE           0x8E /* Core 2 LGBUF A tune */
+#define B2055_C2_LGBUF_GTUNE           0x8F /* Core 2 LGBUF G tune */
+#define B2055_C2_LGBUF_DIV             0x90 /* Core 2 LGBUF div */
+#define B2055_C2_LGBUF_AIDAC           0x91 /* Core 2 LGBUF A IDAC */
+#define B2055_C2_LGBUF_GIDAC           0x92 /* Core 2 LGBUF G IDAC */
+#define B2055_C2_LGBUF_IDACFO          0x93 /* Core 2 LGBUF IDAC filter override */
+#define B2055_C2_LGBUF_SPARE           0x94 /* Core 2 LGBUF spare */
+#define B2055_C2_RX_RFSPC1             0x95 /* Core 2 RX RF SPC1 */
+#define B2055_C2_RX_RFR1               0x96 /* Core 2 RX RF reg 1 */
+#define B2055_C2_RX_RFR2               0x97 /* Core 2 RX RF reg 2 */
+#define B2055_C2_RX_RFRCAL             0x98 /* Core 2 RX RF RCAL */
+#define B2055_C2_RX_BB_BLCMP           0x99 /* Core 2 RX Baseband BUFI LPF CMP */
+#define B2055_C2_RX_BB_LPF             0x9A /* Core 2 RX Baseband LPF */
+#define B2055_C2_RX_BB_MIDACHP         0x9B /* Core 2 RX Baseband MIDAC High-pass */
+#define B2055_C2_RX_BB_VGA1IDAC                0x9C /* Core 2 RX Baseband VGA1 IDAC */
+#define B2055_C2_RX_BB_VGA2IDAC                0x9D /* Core 2 RX Baseband VGA2 IDAC */
+#define B2055_C2_RX_BB_VGA3IDAC                0x9E /* Core 2 RX Baseband VGA3 IDAC */
+#define B2055_C2_RX_BB_BUFOCTL         0x9F /* Core 2 RX Baseband BUFO Control */
+#define B2055_C2_RX_BB_RCCALCTL                0xA0 /* Core 2 RX Baseband RCCAL Control */
+#define B2055_C2_RX_BB_RSSICTL1                0xA1 /* Core 2 RX Baseband RSSI Control 1 */
+#define B2055_C2_RX_BB_RSSICTL2                0xA2 /* Core 2 RX Baseband RSSI Control 2 */
+#define B2055_C2_RX_BB_RSSICTL3                0xA3 /* Core 2 RX Baseband RSSI Control 3 */
+#define B2055_C2_RX_BB_RSSICTL4                0xA4 /* Core 2 RX Baseband RSSI Control 4 */
+#define B2055_C2_RX_BB_RSSICTL5                0xA5 /* Core 2 RX Baseband RSSI Control 5 */
+#define B2055_C2_RX_BB_REG             0xA6 /* Core 2 RX Baseband Regulator */
+#define B2055_C2_RX_BB_SPARE1          0xA7 /* Core 2 RX Baseband spare 1 */
+#define B2055_C2_RX_TXBBRCAL           0xA8 /* Core 2 RX TX BB RCAL */
+#define B2055_C2_TX_RF_SPGA            0xA9 /* Core 2 TX RF SGM PGA */
+#define B2055_C2_TX_RF_SPAD            0xAA /* Core 2 TX RF SGM PAD */
+#define B2055_C2_TX_RF_CNTPGA1         0xAB /* Core 2 TX RF counter PGA 1 */
+#define B2055_C2_TX_RF_CNTPAD1         0xAC /* Core 2 TX RF counter PAD 1 */
+#define B2055_C2_TX_RF_PGAIDAC         0xAD /* Core 2 TX RF PGA IDAC */
+#define B2055_C2_TX_PGAPADTN           0xAE /* Core 2 TX PGA PAD TN */
+#define B2055_C2_TX_PADIDAC1           0xAF /* Core 2 TX PAD IDAC 1 */
+#define B2055_C2_TX_PADIDAC2           0xB0 /* Core 2 TX PAD IDAC 2 */
+#define B2055_C2_TX_MXBGTRIM           0xB1 /* Core 2 TX MX B/G TRIM */
+#define B2055_C2_TX_RF_RCAL            0xB2 /* Core 2 TX RF RCAL */
+#define B2055_C2_TX_RF_PADTSSI1                0xB3 /* Core 2 TX RF PAD TSSI1 */
+#define B2055_C2_TX_RF_PADTSSI2                0xB4 /* Core 2 TX RF PAD TSSI2 */
+#define B2055_C2_TX_RF_SPARE           0xB5 /* Core 2 TX RF spare */
+#define B2055_C2_TX_RF_IQCAL1          0xB6 /* Core 2 TX RF I/Q CAL 1 */
+#define B2055_C2_TX_RF_IQCAL2          0xB7 /* Core 2 TX RF I/Q CAL 2 */
+#define B2055_C2_TXBB_RCCAL            0xB8 /* Core 2 TXBB RC CAL Control */
+#define B2055_C2_TXBB_LPF1             0xB9 /* Core 2 TXBB LPF 1 */
+#define B2055_C2_TX_VOSCNCL            0xBA /* Core 2 TX VOS CNCL */
+#define B2055_C2_TX_LPF_MXGMIDAC       0xBB /* Core 2 TX LPF MXGM IDAC */
+#define B2055_C2_TX_BB_MXGM            0xBC /* Core 2 TX BB MXGM */
+#define B2055_PRG_GCHP21               0xBD /* PRG GC HPVGA23 21 */
+#define B2055_PRG_GCHP22               0xBE /* PRG GC HPVGA23 22 */
+#define B2055_PRG_GCHP23               0xBF /* PRG GC HPVGA23 23 */
+#define B2055_PRG_GCHP24               0xC0 /* PRG GC HPVGA23 24 */
+#define B2055_PRG_GCHP25               0xC1 /* PRG GC HPVGA23 25 */
+#define B2055_PRG_GCHP26               0xC2 /* PRG GC HPVGA23 26 */
+#define B2055_PRG_GCHP27               0xC3 /* PRG GC HPVGA23 27 */
+#define B2055_PRG_GCHP28               0xC4 /* PRG GC HPVGA23 28 */
+#define B2055_PRG_GCHP29               0xC5 /* PRG GC HPVGA23 29 */
+#define B2055_PRG_GCHP30               0xC6 /* PRG GC HPVGA23 30 */
+#define B2055_C1_LNA_GAINBST           0xCD /* Core 1 LNA GAINBST */
+#define B2055_C1_B0NB_RSSIVCM          0xD2 /* Core 1 B0 narrow-band RSSI VCM */
+#define B2055_C1_GENSPARE2             0xD6 /* Core 1 GEN spare 2 */
+#define B2055_C2_LNA_GAINBST           0xD9 /* Core 2 LNA GAINBST */
+#define B2055_C2_B0NB_RSSIVCM          0xDE /* Core 2 B0 narrow-band RSSI VCM */
+#define B2055_C2_GENSPARE2             0xE2 /* Core 2 GEN spare 2 */
+
+
+
+struct b43_wldev;
+
+int b43_phy_initn(struct b43_wldev *dev);
+
+void b43_nphy_radio_turn_on(struct b43_wldev *dev);
+void b43_nphy_radio_turn_off(struct b43_wldev *dev);
+
+int b43_nphy_selectchannel(struct b43_wldev *dev, u8 channel);
+
+void b43_nphy_xmitpower(struct b43_wldev *dev);
+void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna);
+
+#endif /* B43_NPHY_H_ */
index 7ff091e69f056f00a5b741746ea4ffc61972a95b..71507b260b6d2fd5e1befb0eddee486db109034e 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43 wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-  Copyright (c) 2005, 2006 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch>
 
 #include "b43.h"
 #include "phy.h"
+#include "nphy.h"
 #include "main.h"
 #include "tables.h"
 #include "lo.h"
+#include "wa.h"
+
 
 static const s8 b43_tssi2dbm_b_table[] = {
        0x4D, 0x4C, 0x4B, 0x4A,
@@ -225,42 +228,30 @@ static void b43_shm_clear_tssi(struct b43_wldev *dev)
        }
 }
 
-void b43_raw_phy_lock(struct b43_wldev *dev)
+/* Lock the PHY registers against concurrent access from the microcode.
+ * This lock is nonrecursive. */
+void b43_phy_lock(struct b43_wldev *dev)
 {
-       struct b43_phy *phy = &dev->phy;
-
-       B43_WARN_ON(!irqs_disabled());
-
-       /* We had a check for MACCTL==0 here, but I think that doesn't
-        * make sense, as MACCTL is never 0 when this is called.
-        *      --mb */
-       B43_WARN_ON(b43_read32(dev, B43_MMIO_MACCTL) == 0);
+#if B43_DEBUG
+       B43_WARN_ON(dev->phy.phy_locked);
+       dev->phy.phy_locked = 1;
+#endif
+       B43_WARN_ON(dev->dev->id.revision < 3);
 
-       if (dev->dev->id.revision < 3) {
-               b43_mac_suspend(dev);
-               spin_lock(&phy->lock);
-       } else {
-               if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
-                       b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
-       }
-       phy->locked = 1;
+       if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
+               b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
 }
 
-void b43_raw_phy_unlock(struct b43_wldev *dev)
+void b43_phy_unlock(struct b43_wldev *dev)
 {
-       struct b43_phy *phy = &dev->phy;
+#if B43_DEBUG
+       B43_WARN_ON(!dev->phy.phy_locked);
+       dev->phy.phy_locked = 0;
+#endif
+       B43_WARN_ON(dev->dev->id.revision < 3);
 
-       B43_WARN_ON(!irqs_disabled());
-       if (dev->dev->id.revision < 3) {
-               if (phy->locked) {
-                       spin_unlock(&phy->lock);
-                       b43_mac_enable(dev);
-               }
-       } else {
-               if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
-                       b43_power_saving_ctl_bits(dev, 0);
-       }
-       phy->locked = 0;
+       if (!b43_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
+               b43_power_saving_ctl_bits(dev, 0);
 }
 
 /* Different PHYs require different register routing flags.
@@ -271,15 +262,30 @@ static inline u16 adjust_phyreg_for_phytype(struct b43_phy *phy,
 {
        if (phy->type == B43_PHYTYPE_A) {
                /* OFDM registers are base-registers for the A-PHY. */
-               offset &= ~B43_PHYROUTE_OFDM_GPHY;
+               if ((offset & B43_PHYROUTE) == B43_PHYROUTE_OFDM_GPHY) {
+                       offset &= ~B43_PHYROUTE;
+                       offset |= B43_PHYROUTE_BASE;
+               }
        }
-       if (offset & B43_PHYROUTE_EXT_GPHY) {
+
+#if B43_DEBUG
+       if ((offset & B43_PHYROUTE) == B43_PHYROUTE_EXT_GPHY) {
                /* Ext-G registers are only available on G-PHYs */
                if (phy->type != B43_PHYTYPE_G) {
-                       b43dbg(dev->wl, "EXT-G PHY access at "
-                              "0x%04X on %u type PHY\n", offset, phy->type);
+                       b43err(dev->wl, "Invalid EXT-G PHY access at "
+                              "0x%04X on PHY type %u\n", offset, phy->type);
+                       dump_stack();
                }
        }
+       if ((offset & B43_PHYROUTE) == B43_PHYROUTE_N_BMODE) {
+               /* N-BMODE registers are only available on N-PHYs */
+               if (phy->type != B43_PHYTYPE_N) {
+                       b43err(dev->wl, "Invalid N-BMODE PHY access at "
+                              "0x%04X on PHY type %u\n", offset, phy->type);
+                       dump_stack();
+               }
+       }
+#endif /* B43_DEBUG */
 
        return offset;
 }
@@ -299,11 +305,26 @@ void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val)
 
        offset = adjust_phyreg_for_phytype(phy, offset, dev);
        b43_write16(dev, B43_MMIO_PHY_CONTROL, offset);
-       mmiowb();
        b43_write16(dev, B43_MMIO_PHY_DATA, val);
 }
 
-static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower);
+void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
+{
+       b43_phy_write(dev, offset,
+                     b43_phy_read(dev, offset) & mask);
+}
+
+void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set)
+{
+       b43_phy_write(dev, offset,
+                     b43_phy_read(dev, offset) | set);
+}
+
+void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
+{
+       b43_phy_write(dev, offset,
+                     (b43_phy_read(dev, offset) & mask) | set);
+}
 
 /* Adjust the transmission power output (G-PHY) */
 void b43_set_txpower_g(struct b43_wldev *dev,
@@ -763,366 +784,96 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
        b43_shm_clear_tssi(dev);
 }
 
-static void b43_phy_agcsetup(struct b43_wldev *dev)
-{
-       struct b43_phy *phy = &dev->phy;
-       u16 offset = 0x0000;
-
-       if (phy->rev == 1)
-               offset = 0x4C00;
-
-       b43_ofdmtab_write16(dev, offset, 0, 0x00FE);
-       b43_ofdmtab_write16(dev, offset, 1, 0x000D);
-       b43_ofdmtab_write16(dev, offset, 2, 0x0013);
-       b43_ofdmtab_write16(dev, offset, 3, 0x0019);
-
-       if (phy->rev == 1) {
-               b43_ofdmtab_write16(dev, 0x1800, 0, 0x2710);
-               b43_ofdmtab_write16(dev, 0x1801, 0, 0x9B83);
-               b43_ofdmtab_write16(dev, 0x1802, 0, 0x9B83);
-               b43_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D);
-               b43_phy_write(dev, 0x0455, 0x0004);
-       }
-
-       b43_phy_write(dev, 0x04A5, (b43_phy_read(dev, 0x04A5)
-                                   & 0x00FF) | 0x5700);
-       b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A)
-                                   & 0xFF80) | 0x000F);
-       b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A)
-                                   & 0xC07F) | 0x2B80);
-       b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
-                                   & 0xF0FF) | 0x0300);
-
-       b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A)
-                         | 0x0008);
-
-       b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
-                                   & 0xFFF0) | 0x0008);
-       b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1)
-                                   & 0xF0FF) | 0x0600);
-       b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
-                                   & 0xF0FF) | 0x0700);
-       b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0)
-                                   & 0xF0FF) | 0x0100);
-
-       if (phy->rev == 1) {
-               b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2)
-                                           & 0xFFF0) | 0x0007);
-       }
-
-       b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488)
-                                   & 0xFF00) | 0x001C);
-       b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488)
-                                   & 0xC0FF) | 0x0200);
-       b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496)
-                                   & 0xFF00) | 0x001C);
-       b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489)
-                                   & 0xFF00) | 0x0020);
-       b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489)
-                                   & 0xC0FF) | 0x0200);
-       b43_phy_write(dev, 0x0482, (b43_phy_read(dev, 0x0482)
-                                   & 0xFF00) | 0x002E);
-       b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496)
-                                   & 0x00FF) | 0x1A00);
-       b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481)
-                                   & 0xFF00) | 0x0028);
-       b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481)
-                                   & 0x00FF) | 0x2C00);
-
-       if (phy->rev == 1) {
-               b43_phy_write(dev, 0x0430, 0x092B);
-               b43_phy_write(dev, 0x041B, (b43_phy_read(dev, 0x041B)
-                                           & 0xFFE1) | 0x0002);
-       } else {
-               b43_phy_write(dev, 0x041B, b43_phy_read(dev, 0x041B)
-                             & 0xFFE1);
-               b43_phy_write(dev, 0x041F, 0x287A);
-               b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420)
-                                           & 0xFFF0) | 0x0004);
-       }
-
-       if (phy->rev >= 6) {
-               b43_phy_write(dev, 0x0422, 0x287A);
-               b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420)
-                                           & 0x0FFF) | 0x3000);
-       }
-
-       b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8)
-                                   & 0x8080) | 0x7874);
-       b43_phy_write(dev, 0x048E, 0x1C00);
-
-       offset = 0x0800;
-       if (phy->rev == 1) {
-               offset = 0x5400;
-               b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB)
-                                           & 0xF0FF) | 0x0600);
-               b43_phy_write(dev, 0x048B, 0x005E);
-               b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C)
-                                           & 0xFF00) | 0x001E);
-               b43_phy_write(dev, 0x048D, 0x0002);
-       }
-       b43_ofdmtab_write16(dev, offset, 0, 0x00);
-       b43_ofdmtab_write16(dev, offset, 1, 0x07);
-       b43_ofdmtab_write16(dev, offset, 2, 0x10);
-       b43_ofdmtab_write16(dev, offset, 3, 0x1C);
-
-       if (phy->rev >= 6) {
-               b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426)
-                             & 0xFFFC);
-               b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426)
-                             & 0xEFFF);
-       }
-}
-
-static void b43_phy_setupg(struct b43_wldev *dev)
+static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable)
 {
-       struct ssb_bus *bus = dev->dev->bus;
-       struct b43_phy *phy = &dev->phy;
-       u16 i;
-
-       B43_WARN_ON(phy->type != B43_PHYTYPE_G);
-       if (phy->rev == 1) {
-               b43_phy_write(dev, 0x0406, 0x4F19);
-               b43_phy_write(dev, B43_PHY_G_CRS,
-                             (b43_phy_read(dev, B43_PHY_G_CRS) & 0xFC3F) |
-                             0x0340);
-               b43_phy_write(dev, 0x042C, 0x005A);
-               b43_phy_write(dev, 0x0427, 0x001A);
-
-               for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x5800, i,
-                                           b43_tab_finefreqg[i]);
-               for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg1[i]);
-               for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x2000, i, b43_tab_rotor[i]);
-       } else {
-               /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
-               b43_nrssi_hw_write(dev, 0xBA98, (s16) 0x7654);
-
-               if (phy->rev == 2) {
-                       b43_phy_write(dev, 0x04C0, 0x1861);
-                       b43_phy_write(dev, 0x04C1, 0x0271);
-               } else if (phy->rev > 2) {
-                       b43_phy_write(dev, 0x04C0, 0x0098);
-                       b43_phy_write(dev, 0x04C1, 0x0070);
-                       b43_phy_write(dev, 0x04C9, 0x0080);
-               }
-               b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x800);
-
-               for (i = 0; i < 64; i++)
-                       b43_ofdmtab_write16(dev, 0x4000, i, i);
-               for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg2[i]);
-       }
-
-       if (phy->rev <= 2)
-               for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1400, i,
-                                           b43_tab_noisescaleg1[i]);
-       else if ((phy->rev >= 7) && (b43_phy_read(dev, 0x0449) & 0x0200))
-               for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1400, i,
-                                           b43_tab_noisescaleg3[i]);
-       else
-               for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1400, i,
-                                           b43_tab_noisescaleg2[i]);
-
-       if (phy->rev == 2)
-               for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x5000, i,
-                                           b43_tab_sigmasqr1[i]);
-       else if ((phy->rev > 2) && (phy->rev <= 8))
-               for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x5000, i,
-                                           b43_tab_sigmasqr2[i]);
-
-       if (phy->rev == 1) {
-               for (i = 0; i < B43_TAB_RETARD_SIZE; i++)
-                       b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]);
-               for (i = 4; i < 20; i++)
-                       b43_ofdmtab_write16(dev, 0x5400, i, 0x0020);
-               b43_phy_agcsetup(dev);
-
-               if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-                   (bus->boardinfo.type == SSB_BOARD_BU4306) &&
-                   (bus->boardinfo.rev == 0x17))
-                       return;
-
-               b43_ofdmtab_write16(dev, 0x5001, 0, 0x0002);
-               b43_ofdmtab_write16(dev, 0x5002, 0, 0x0001);
-       } else {
-               for (i = 0; i < 0x20; i++)
-                       b43_ofdmtab_write16(dev, 0x1000, i, 0x0820);
-               b43_phy_agcsetup(dev);
-               b43_phy_read(dev, 0x0400);      /* dummy read */
-               b43_phy_write(dev, 0x0403, 0x1000);
-               b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F);
-               b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014);
-
-               if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-                   (bus->boardinfo.type == SSB_BOARD_BU4306) &&
-                   (bus->boardinfo.rev == 0x17))
-                       return;
-
-               b43_ofdmtab_write16(dev, 0x0401, 0, 0x0002);
-               b43_ofdmtab_write16(dev, 0x0402, 0, 0x0001);
-       }
-}
-
-/* Initialize the noisescaletable for APHY */
-static void b43_phy_init_noisescaletbl(struct b43_wldev *dev)
-{
-       struct b43_phy *phy = &dev->phy;
        int i;
 
-       for (i = 0; i < 12; i++) {
-               if (phy->rev == 2)
-                       b43_ofdmtab_write16(dev, 0x1400, i, 0x6767);
+       if (dev->phy.rev < 3) {
+               if (enable)
+                       for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8);
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_WRSSI, i, 0xFFF8);
+                       }
                else
-                       b43_ofdmtab_write16(dev, 0x1400, i, 0x2323);
-       }
-       if (phy->rev == 2)
-               b43_ofdmtab_write16(dev, 0x1400, i, 0x6700);
-       else
-               b43_ofdmtab_write16(dev, 0x1400, i, 0x2300);
-       for (i = 0; i < 11; i++) {
-               if (phy->rev == 2)
-                       b43_ofdmtab_write16(dev, 0x1400, i, 0x6767);
+                       for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) {
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]);
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]);
+                       }
+       } else {
+               if (enable)
+                       for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++)
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_WRSSI, i, 0x0820);
                else
-                       b43_ofdmtab_write16(dev, 0x1400, i, 0x2323);
+                       for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++)
+                               b43_ofdmtab_write16(dev,
+                                       B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]);
        }
-       if (phy->rev == 2)
-               b43_ofdmtab_write16(dev, 0x1400, i, 0x0067);
-       else
-               b43_ofdmtab_write16(dev, 0x1400, i, 0x0023);
 }
 
-static void b43_phy_setupa(struct b43_wldev *dev)
+static void b43_phy_ww(struct b43_wldev *dev)
 {
-       struct b43_phy *phy = &dev->phy;
-       u16 i;
-
-       B43_WARN_ON(phy->type != B43_PHYTYPE_A);
-       switch (phy->rev) {
-       case 2:
-               b43_phy_write(dev, 0x008E, 0x3800);
-               b43_phy_write(dev, 0x0035, 0x03FF);
-               b43_phy_write(dev, 0x0036, 0x0400);
-
-               b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051);
-
-               b43_phy_write(dev, 0x001C, 0x0FF9);
-               b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F);
-               b43_ofdmtab_write16(dev, 0x3C0C, 0, 0x07BF);
-               b43_radio_write16(dev, 0x0002, 0x07BF);
-
-               b43_phy_write(dev, 0x0024, 0x4680);
-               b43_phy_write(dev, 0x0020, 0x0003);
-               b43_phy_write(dev, 0x001D, 0x0F40);
-               b43_phy_write(dev, 0x001F, 0x1C00);
-
-               b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A)
-                                           & 0x00FF) | 0x0400);
-               b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B)
-                             & 0xFBFF);
-               b43_phy_write(dev, 0x008E, 0x58C1);
-
-               b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F);
-               b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F);
-               b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A);
-               b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030);
-               b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A);
-
-               b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0000, 1, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0000, 2, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0000, 3, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0000, 4, 0x0015);
-               b43_ofdmtab_write16(dev, 0x0000, 5, 0x0015);
-               b43_ofdmtab_write16(dev, 0x0000, 6, 0x0019);
-
-               b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003);
-               b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003);
-               b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007);
-
-               for (i = 0; i < 16; i++)
-                       b43_ofdmtab_write16(dev, 0x4000, i, (0x8 + i) & 0x000F);
-
-               b43_ofdmtab_write16(dev, 0x3003, 0, 0x1044);
-               b43_ofdmtab_write16(dev, 0x3004, 0, 0x7201);
-               b43_ofdmtab_write16(dev, 0x3006, 0, 0x0040);
-               b43_ofdmtab_write16(dev, 0x3001, 0,
-                                   (b43_ofdmtab_read16(dev, 0x3001, 0) &
-                                    0x0010) | 0x0008);
-
-               for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x5800, i,
-                                           b43_tab_finefreqa[i]);
-               for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++)
-                       b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea2[i]);
-               for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)
-                       b43_ofdmtab_write32(dev, 0x2000, i, b43_tab_rotor[i]);
-               b43_phy_init_noisescaletbl(dev);
-               for (i = 0; i < B43_TAB_RETARD_SIZE; i++)
-                       b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]);
-               break;
-       case 3:
-               for (i = 0; i < 64; i++)
-                       b43_ofdmtab_write16(dev, 0x4000, i, i);
-
-               b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051);
-
-               b43_phy_write(dev, 0x001C, 0x0FF9);
-               b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F);
-               b43_radio_write16(dev, 0x0002, 0x07BF);
-
-               b43_phy_write(dev, 0x0024, 0x4680);
-               b43_phy_write(dev, 0x0020, 0x0003);
-               b43_phy_write(dev, 0x001D, 0x0F40);
-               b43_phy_write(dev, 0x001F, 0x1C00);
-               b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A)
-                                           & 0x00FF) | 0x0400);
-
-               b43_ofdmtab_write16(dev, 0x3000, 1,
-                                   (b43_ofdmtab_read16(dev, 0x3000, 1)
-                                    & 0x0010) | 0x0008);
-               for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) {
-                       b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea3[i]);
-               }
-               b43_phy_init_noisescaletbl(dev);
-               for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) {
-                       b43_ofdmtab_write16(dev, 0x5000, i,
-                                           b43_tab_sigmasqr1[i]);
-               }
-
-               b43_phy_write(dev, 0x0003, 0x1808);
-
-               b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F);
-               b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F);
-               b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A);
-               b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030);
-               b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A);
-
-               b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0001, 0, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0002, 0, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0003, 0, 0x0013);
-               b43_ofdmtab_write16(dev, 0x0004, 0, 0x0015);
-               b43_ofdmtab_write16(dev, 0x0005, 0, 0x0015);
-               b43_ofdmtab_write16(dev, 0x0006, 0, 0x0019);
-
-               b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003);
-               b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003);
-               b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007);
+       u16 b, curr_s, best_s = 0xFFFF;
+       int i;
 
-               b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F);
-               b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014);
-               break;
-       default:
-               B43_WARN_ON(1);
+       b43_phy_write(dev, B43_PHY_CRS0,
+               b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN);
+       b43_phy_write(dev, B43_PHY_OFDM(0x1B),
+               b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000);
+       b43_phy_write(dev, B43_PHY_OFDM(0x82),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300);
+       b43_radio_write16(dev, 0x0009,
+               b43_radio_read16(dev, 0x0009) | 0x0080);
+       b43_radio_write16(dev, 0x0012,
+               (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002);
+       b43_wa_initgains(dev);
+       b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5);
+       b = b43_phy_read(dev, B43_PHY_PWRDOWN);
+       b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005);
+       b43_radio_write16(dev, 0x0004,
+               b43_radio_read16(dev, 0x0004) | 0x0004);
+       for (i = 0x10; i <= 0x20; i++) {
+               b43_radio_write16(dev, 0x0013, i);
+               curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF;
+               if (!curr_s) {
+                       best_s = 0x0000;
+                       break;
+               } else if (curr_s >= 0x0080)
+                       curr_s = 0x0100 - curr_s;
+               if (curr_s < best_s)
+                       best_s = curr_s;
        }
+       b43_phy_write(dev, B43_PHY_PWRDOWN, b);
+       b43_radio_write16(dev, 0x0004,
+               b43_radio_read16(dev, 0x0004) & 0xFFFB);
+       b43_radio_write16(dev, 0x0013, best_s);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC);
+       b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80);
+       b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00);
+       b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0);
+       b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0);
+       b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF);
+       b43_phy_write(dev, B43_PHY_OFDM(0xBB),
+               (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053);
+       b43_phy_write(dev, B43_PHY_OFDM61,
+               (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120);
+       b43_phy_write(dev, B43_PHY_OFDM(0x13),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000);
+       b43_phy_write(dev, B43_PHY_OFDM(0x14),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017);
+       for (i = 0; i < 6; i++)
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013);
+       b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030);
+       b43_phy_write(dev, B43_PHY_CRS0,
+               b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
 }
 
 /* Initialize APHY. This is also called for the GPHY in some cases. */
@@ -1130,64 +881,54 @@ static void b43_phy_inita(struct b43_wldev *dev)
 {
        struct ssb_bus *bus = dev->dev->bus;
        struct b43_phy *phy = &dev->phy;
-       u16 tval;
 
        might_sleep();
 
-       if (phy->type == B43_PHYTYPE_A) {
-               b43_phy_setupa(dev);
-       } else {
-               b43_phy_setupg(dev);
-               if (phy->gmode &&
-                   (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL))
-                       b43_phy_write(dev, 0x046E, 0x03CF);
-               return;
+       if (phy->rev >= 6) {
+               if (phy->type == B43_PHYTYPE_A)
+                       b43_phy_write(dev, B43_PHY_OFDM(0x1B),
+                               b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000);
+               if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
+                       b43_phy_write(dev, B43_PHY_ENCORE,
+                               b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010);
+               else
+                       b43_phy_write(dev, B43_PHY_ENCORE,
+                               b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010);
        }
 
-       b43_phy_write(dev, B43_PHY_A_CRS,
-                     (b43_phy_read(dev, B43_PHY_A_CRS) & 0xF83C) | 0x0340);
-       b43_phy_write(dev, 0x0034, 0x0001);
+       b43_wa_all(dev);
 
-       //TODO: RSSI AGC
-       b43_phy_write(dev, B43_PHY_A_CRS,
-                     b43_phy_read(dev, B43_PHY_A_CRS) | (1 << 14));
-       b43_radio_init2060(dev);
+       if (phy->type == B43_PHYTYPE_A) {
+               if (phy->gmode && (phy->rev < 3))
+                       b43_phy_write(dev, 0x0034,
+                               b43_phy_read(dev, 0x0034) | 0x0001);
+               b43_phy_rssiagc(dev, 0);
 
-       if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-           ((bus->boardinfo.type == SSB_BOARD_BU4306) ||
-            (bus->boardinfo.type == SSB_BOARD_BU4309))) {
-               if (phy->lofcal == 0xFFFF) {
-                       //TODO: LOF Cal
-                       b43_radio_set_tx_iq(dev);
-               } else
-                       b43_radio_write16(dev, 0x001E, phy->lofcal);
-       }
+               b43_phy_write(dev, B43_PHY_CRS0,
+                       b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN);
 
-       b43_phy_write(dev, 0x007A, 0xF111);
+               b43_radio_init2060(dev);
 
-       if (phy->cur_idle_tssi == 0) {
-               b43_radio_write16(dev, 0x0019, 0x0000);
-               b43_radio_write16(dev, 0x0017, 0x0020);
-
-               tval = b43_ofdmtab_read16(dev, 0x3001, 0);
-               if (phy->rev == 1) {
-                       b43_ofdmtab_write16(dev, 0x3001, 0,
-                                           (b43_ofdmtab_read16(dev, 0x3001, 0)
-                                            & 0xFF87)
-                                           | 0x0058);
-               } else {
-                       b43_ofdmtab_write16(dev, 0x3001, 0,
-                                           (b43_ofdmtab_read16(dev, 0x3001, 0)
-                                            & 0xFFC3)
-                                           | 0x002C);
+               if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
+                   ((bus->boardinfo.type == SSB_BOARD_BU4306) ||
+                    (bus->boardinfo.type == SSB_BOARD_BU4309))) {
+                       ; //TODO: A PHY LO
                }
-               b43_dummy_transmission(dev);
-               phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_A_PCTL);
-               b43_ofdmtab_write16(dev, 0x3001, 0, tval);
 
-               b43_radio_set_txpower_a(dev, 0x0018);
+               if (phy->rev >= 3)
+                       b43_phy_ww(dev);
+
+               hardware_pctl_init_aphy(dev);
+
+               //TODO: radar detection
+       }
+
+       if ((phy->type == B43_PHYTYPE_G) &&
+           (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
+               b43_phy_write(dev, B43_PHY_OFDM(0x6E),
+                                 (b43_phy_read(dev, B43_PHY_OFDM(0x6E))
+                                  & 0xE000) | 0x3CF);
        }
-       b43_shm_clear_tssi(dev);
 }
 
 static void b43_phy_initb2(struct b43_wldev *dev)
@@ -1286,7 +1027,7 @@ static void b43_phy_initb4(struct b43_wldev *dev)
        if (phy->radio_ver == 0x2050)
                b43_phy_write(dev, 0x002A, 0x88C2);
        b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
                b43_calc_nrssi_slope(dev);
                b43_calc_nrssi_threshold(dev);
        }
@@ -1433,7 +1174,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
                b43_radio_write16(dev, 0x5A, 0x88);
                b43_radio_write16(dev, 0x5B, 0x6B);
                b43_radio_write16(dev, 0x5C, 0x0F);
-               if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_ALTIQ) {
+               if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
                        b43_radio_write16(dev, 0x5D, 0xFA);
                        b43_radio_write16(dev, 0x5E, 0xD8);
                } else {
@@ -1525,7 +1266,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
                b43_phy_write(dev, 0x0062, 0x0007);
                b43_radio_init2050(dev);
                b43_lo_g_measure(dev);
-               if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) {
+               if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) {
                        b43_calc_nrssi_slope(dev);
                        b43_calc_nrssi_threshold(dev);
                }
@@ -1552,14 +1293,14 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
                backup_phy[4] = b43_phy_read(dev, B43_PHY_ANALOGOVER);
                backup_phy[5] = b43_phy_read(dev, B43_PHY_ANALOGOVERVAL);
        }
-       backup_phy[6] = b43_phy_read(dev, B43_PHY_BASE(0x5A));
-       backup_phy[7] = b43_phy_read(dev, B43_PHY_BASE(0x59));
-       backup_phy[8] = b43_phy_read(dev, B43_PHY_BASE(0x58));
-       backup_phy[9] = b43_phy_read(dev, B43_PHY_BASE(0x0A));
-       backup_phy[10] = b43_phy_read(dev, B43_PHY_BASE(0x03));
+       backup_phy[6] = b43_phy_read(dev, B43_PHY_CCK(0x5A));
+       backup_phy[7] = b43_phy_read(dev, B43_PHY_CCK(0x59));
+       backup_phy[8] = b43_phy_read(dev, B43_PHY_CCK(0x58));
+       backup_phy[9] = b43_phy_read(dev, B43_PHY_CCK(0x0A));
+       backup_phy[10] = b43_phy_read(dev, B43_PHY_CCK(0x03));
        backup_phy[11] = b43_phy_read(dev, B43_PHY_LO_MASK);
        backup_phy[12] = b43_phy_read(dev, B43_PHY_LO_CTL);
-       backup_phy[13] = b43_phy_read(dev, B43_PHY_BASE(0x2B));
+       backup_phy[13] = b43_phy_read(dev, B43_PHY_CCK(0x2B));
        backup_phy[14] = b43_phy_read(dev, B43_PHY_PGACTL);
        backup_phy[15] = b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
        backup_bband = phy->bbatt.att;
@@ -1601,12 +1342,12 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
                      (b43_phy_read(dev, B43_PHY_RFOVERVAL)
                       & 0xFFCF) | 0x10);
 
-       b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0780);
-       b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810);
-       b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D);
+       b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0780);
+       b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
+       b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
 
-       b43_phy_write(dev, B43_PHY_BASE(0x0A),
-                     b43_phy_read(dev, B43_PHY_BASE(0x0A)) | 0x2000);
+       b43_phy_write(dev, B43_PHY_CCK(0x0A),
+                     b43_phy_read(dev, B43_PHY_CCK(0x0A)) | 0x2000);
        if (phy->rev != 1) {    /* Not in specs, but needed to prevent PPC machine check */
                b43_phy_write(dev, B43_PHY_ANALOGOVER,
                              b43_phy_read(dev, B43_PHY_ANALOGOVER) | 0x0004);
@@ -1614,8 +1355,8 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
                              b43_phy_read(dev,
                                           B43_PHY_ANALOGOVERVAL) & 0xFFFB);
        }
-       b43_phy_write(dev, B43_PHY_BASE(0x03),
-                     (b43_phy_read(dev, B43_PHY_BASE(0x03))
+       b43_phy_write(dev, B43_PHY_CCK(0x03),
+                     (b43_phy_read(dev, B43_PHY_CCK(0x03))
                       & 0xFF9F) | 0x40);
 
        if (phy->radio_rev == 8) {
@@ -1633,11 +1374,11 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
                b43_phy_write(dev, B43_PHY_LO_MASK, 0x8020);
        b43_phy_write(dev, B43_PHY_LO_CTL, 0);
 
-       b43_phy_write(dev, B43_PHY_BASE(0x2B),
-                     (b43_phy_read(dev, B43_PHY_BASE(0x2B))
+       b43_phy_write(dev, B43_PHY_CCK(0x2B),
+                     (b43_phy_read(dev, B43_PHY_CCK(0x2B))
                       & 0xFFC0) | 0x01);
-       b43_phy_write(dev, B43_PHY_BASE(0x2B),
-                     (b43_phy_read(dev, B43_PHY_BASE(0x2B))
+       b43_phy_write(dev, B43_PHY_CCK(0x2B),
+                     (b43_phy_read(dev, B43_PHY_CCK(0x2B))
                       & 0xC0FF) | 0x800);
 
        b43_phy_write(dev, B43_PHY_RFOVER,
@@ -1645,7 +1386,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
        b43_phy_write(dev, B43_PHY_RFOVERVAL,
                      b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF);
 
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
                if (phy->rev >= 7) {
                        b43_phy_write(dev, B43_PHY_RFOVER,
                                      b43_phy_read(dev, B43_PHY_RFOVER)
@@ -1708,14 +1449,14 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
                b43_phy_write(dev, B43_PHY_ANALOGOVER, backup_phy[4]);
                b43_phy_write(dev, B43_PHY_ANALOGOVERVAL, backup_phy[5]);
        }
-       b43_phy_write(dev, B43_PHY_BASE(0x5A), backup_phy[6]);
-       b43_phy_write(dev, B43_PHY_BASE(0x59), backup_phy[7]);
-       b43_phy_write(dev, B43_PHY_BASE(0x58), backup_phy[8]);
-       b43_phy_write(dev, B43_PHY_BASE(0x0A), backup_phy[9]);
-       b43_phy_write(dev, B43_PHY_BASE(0x03), backup_phy[10]);
+       b43_phy_write(dev, B43_PHY_CCK(0x5A), backup_phy[6]);
+       b43_phy_write(dev, B43_PHY_CCK(0x59), backup_phy[7]);
+       b43_phy_write(dev, B43_PHY_CCK(0x58), backup_phy[8]);
+       b43_phy_write(dev, B43_PHY_CCK(0x0A), backup_phy[9]);
+       b43_phy_write(dev, B43_PHY_CCK(0x03), backup_phy[10]);
        b43_phy_write(dev, B43_PHY_LO_MASK, backup_phy[11]);
        b43_phy_write(dev, B43_PHY_LO_CTL, backup_phy[12]);
-       b43_phy_write(dev, B43_PHY_BASE(0x2B), backup_phy[13]);
+       b43_phy_write(dev, B43_PHY_CCK(0x2B), backup_phy[13]);
        b43_phy_write(dev, B43_PHY_PGACTL, backup_phy[14]);
 
        b43_phy_set_baseband_attenuation(dev, backup_bband);
@@ -1807,26 +1548,26 @@ static void b43_phy_initg(struct b43_wldev *dev)
                                          | phy->lo_control->tx_bias);
                }
                if (phy->rev >= 6) {
-                       b43_phy_write(dev, B43_PHY_BASE(0x36),
-                                     (b43_phy_read(dev, B43_PHY_BASE(0x36))
+                       b43_phy_write(dev, B43_PHY_CCK(0x36),
+                                     (b43_phy_read(dev, B43_PHY_CCK(0x36))
                                       & 0x0FFF) | (phy->lo_control->
                                                    tx_bias << 12));
                }
-               if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL)
-                       b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8075);
+               if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+                       b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
                else
-                       b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x807F);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
                if (phy->rev < 2)
-                       b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x101);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x101);
                else
-                       b43_phy_write(dev, B43_PHY_BASE(0x2F), 0x202);
+                       b43_phy_write(dev, B43_PHY_CCK(0x2F), 0x202);
        }
        if (phy->gmode || phy->rev >= 2) {
                b43_lo_g_adjust(dev);
                b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
        }
 
-       if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) {
+       if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
                /* The specs state to update the NRSSI LT with
                 * the value 0x7FFFFFFF here. I think that is some weird
                 * compiler optimization in the original driver.
@@ -1995,7 +1736,6 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
                        int rfatt_delta, bbatt_delta;
                        int rfatt, bbatt;
                        u8 tx_control;
-                       unsigned long phylock_flags;
 
                        tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x0058);
                        v0 = (s8) (tmp & 0x00FF);
@@ -2036,16 +1776,15 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
                        estimated_pwr =
                            b43_phy_estimate_power_out(dev, average);
 
-                       max_pwr = dev->dev->bus->sprom.r1.maxpwr_bg;
-                       if ((dev->dev->bus->sprom.r1.
-                            boardflags_lo & B43_BFL_PACTRL)
-                           && (phy->type == B43_PHYTYPE_G))
+                       max_pwr = dev->dev->bus->sprom.maxpwr_bg;
+                       if ((dev->dev->bus->sprom.boardflags_lo
+                           & B43_BFL_PACTRL) && (phy->type == B43_PHYTYPE_G))
                                max_pwr -= 0x3;
                        if (unlikely(max_pwr <= 0)) {
                                b43warn(dev->wl,
                                        "Invalid max-TX-power value in SPROM.\n");
                                max_pwr = 60;   /* fake it */
-                               dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr;
+                               dev->dev->bus->sprom.maxpwr_bg = max_pwr;
                        }
 
                        /*TODO:
@@ -2103,7 +1842,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
                                                    B43_TXCTL_TXMIX;
                                                rfatt += 2;
                                                bbatt += 2;
-                                       } else if (dev->dev->bus->sprom.r1.
+                                       } else if (dev->dev->bus->sprom.
                                                   boardflags_lo &
                                                   B43_BFL_PACTRL) {
                                                bbatt += 4 * (rfatt - 2);
@@ -2127,15 +1866,18 @@ void b43_phy_xmitpower(struct b43_wldev *dev)
                        phy->bbatt.att = bbatt;
 
                        /* Adjust the hardware */
-                       b43_phy_lock(dev, phylock_flags);
+                       b43_phy_lock(dev);
                        b43_radio_lock(dev);
                        b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt,
                                          phy->tx_control);
                        b43_lo_g_ctl_mark_cur_used(dev);
                        b43_radio_unlock(dev);
-                       b43_phy_unlock(dev, phylock_flags);
+                       b43_phy_unlock(dev);
                        break;
                }
+       case B43_PHYTYPE_N:
+               b43_nphy_xmitpower(dev);
+               break;
        default:
                B43_WARN_ON(1);
        }
@@ -2179,13 +1921,13 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev)
        s8 *dyn_tssi2dbm;
 
        if (phy->type == B43_PHYTYPE_A) {
-               pab0 = (s16) (dev->dev->bus->sprom.r1.pa1b0);
-               pab1 = (s16) (dev->dev->bus->sprom.r1.pa1b1);
-               pab2 = (s16) (dev->dev->bus->sprom.r1.pa1b2);
+               pab0 = (s16) (dev->dev->bus->sprom.pa1b0);
+               pab1 = (s16) (dev->dev->bus->sprom.pa1b1);
+               pab2 = (s16) (dev->dev->bus->sprom.pa1b2);
        } else {
-               pab0 = (s16) (dev->dev->bus->sprom.r1.pa0b0);
-               pab1 = (s16) (dev->dev->bus->sprom.r1.pa0b1);
-               pab2 = (s16) (dev->dev->bus->sprom.r1.pa0b2);
+               pab0 = (s16) (dev->dev->bus->sprom.pa0b0);
+               pab1 = (s16) (dev->dev->bus->sprom.pa0b1);
+               pab2 = (s16) (dev->dev->bus->sprom.pa0b2);
        }
 
        if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) {
@@ -2198,17 +1940,17 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev)
            pab0 != -1 && pab1 != -1 && pab2 != -1) {
                /* The pabX values are set in SPROM. Use them. */
                if (phy->type == B43_PHYTYPE_A) {
-                       if ((s8) dev->dev->bus->sprom.r1.itssi_a != 0 &&
-                           (s8) dev->dev->bus->sprom.r1.itssi_a != -1)
+                       if ((s8) dev->dev->bus->sprom.itssi_a != 0 &&
+                           (s8) dev->dev->bus->sprom.itssi_a != -1)
                                phy->tgt_idle_tssi =
-                                   (s8) (dev->dev->bus->sprom.r1.itssi_a);
+                                   (s8) (dev->dev->bus->sprom.itssi_a);
                        else
                                phy->tgt_idle_tssi = 62;
                } else {
-                       if ((s8) dev->dev->bus->sprom.r1.itssi_bg != 0 &&
-                           (s8) dev->dev->bus->sprom.r1.itssi_bg != -1)
+                       if ((s8) dev->dev->bus->sprom.itssi_bg != 0 &&
+                           (s8) dev->dev->bus->sprom.itssi_bg != -1)
                                phy->tgt_idle_tssi =
-                                   (s8) (dev->dev->bus->sprom.r1.itssi_bg);
+                                   (s8) (dev->dev->bus->sprom.itssi_bg);
                        else
                                phy->tgt_idle_tssi = 62;
                }
@@ -2255,41 +1997,44 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev)
 int b43_phy_init(struct b43_wldev *dev)
 {
        struct b43_phy *phy = &dev->phy;
-       int err = -ENODEV;
+       bool unsupported = 0;
+       int err = 0;
 
        switch (phy->type) {
        case B43_PHYTYPE_A:
-               if (phy->rev == 2 || phy->rev == 3) {
+               if (phy->rev == 2 || phy->rev == 3)
                        b43_phy_inita(dev);
-                       err = 0;
-               }
+               else
+                       unsupported = 1;
                break;
        case B43_PHYTYPE_B:
                switch (phy->rev) {
                case 2:
                        b43_phy_initb2(dev);
-                       err = 0;
                        break;
                case 4:
                        b43_phy_initb4(dev);
-                       err = 0;
                        break;
                case 5:
                        b43_phy_initb5(dev);
-                       err = 0;
                        break;
                case 6:
                        b43_phy_initb6(dev);
-                       err = 0;
                        break;
+               default:
+                       unsupported = 1;
                }
                break;
        case B43_PHYTYPE_G:
                b43_phy_initg(dev);
-               err = 0;
                break;
+       case B43_PHYTYPE_N:
+               err = b43_phy_initn(dev);
+               break;
+       default:
+               unsupported = 1;
        }
-       if (err)
+       if (unsupported)
                b43err(dev->wl, "Unknown PHYTYPE found\n");
 
        return err;
@@ -2392,6 +2137,9 @@ void b43_set_rx_antenna(struct b43_wldev *dev, int antenna)
                    << B43_PHY_BBANDCFG_RXANT_SHIFT;
                b43_phy_write(dev, B43_PHY_CCKBBANDCFG, tmp);
                break;
+       case B43_PHYTYPE_N:
+               b43_nphy_set_rxantenna(dev, antenna);
+               break;
        default:
                B43_WARN_ON(1);
        }
@@ -2421,6 +2169,7 @@ void b43_radio_lock(struct b43_wldev *dev)
        u32 macctl;
 
        macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK);
        macctl |= B43_MACCTL_RADIOLOCK;
        b43_write32(dev, B43_MMIO_MACCTL, macctl);
        /* Commit the write and wait for the device
@@ -2437,6 +2186,7 @@ void b43_radio_unlock(struct b43_wldev *dev)
        b43_read16(dev, B43_MMIO_PHY_VER);
        /* unlock */
        macctl = b43_read32(dev, B43_MMIO_MACCTL);
+       B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK));
        macctl &= ~B43_MACCTL_RADIOLOCK;
        b43_write32(dev, B43_MMIO_MACCTL, macctl);
 }
@@ -2445,9 +2195,12 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset)
 {
        struct b43_phy *phy = &dev->phy;
 
+       /* Offset 1 is a 32-bit register. */
+       B43_WARN_ON(offset == 1);
+
        switch (phy->type) {
        case B43_PHYTYPE_A:
-               offset |= 0x0040;
+               offset |= 0x40;
                break;
        case B43_PHYTYPE_B:
                if (phy->radio_ver == 0x2053) {
@@ -2463,6 +2216,14 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset)
        case B43_PHYTYPE_G:
                offset |= 0x80;
                break;
+       case B43_PHYTYPE_N:
+               offset |= 0x100;
+               break;
+       case B43_PHYTYPE_LP:
+               /* No adjustment required. */
+               break;
+       default:
+               B43_WARN_ON(1);
        }
 
        b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset);
@@ -2471,11 +2232,31 @@ u16 b43_radio_read16(struct b43_wldev *dev, u16 offset)
 
 void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val)
 {
+       /* Offset 1 is a 32-bit register. */
+       B43_WARN_ON(offset == 1);
+
        b43_write16(dev, B43_MMIO_RADIO_CONTROL, offset);
-       mmiowb();
        b43_write16(dev, B43_MMIO_RADIO_DATA_LOW, val);
 }
 
+void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask)
+{
+       b43_radio_write16(dev, offset,
+                         b43_radio_read16(dev, offset) & mask);
+}
+
+void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set)
+{
+       b43_radio_write16(dev, offset,
+                         b43_radio_read16(dev, offset) | set);
+}
+
+void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set)
+{
+       b43_radio_write16(dev, offset,
+                         (b43_radio_read16(dev, offset) & mask) | set);
+}
+
 static void b43_set_all_gains(struct b43_wldev *dev,
                              s16 first, s16 second, s16 third)
 {
@@ -2605,12 +2386,11 @@ u8 b43_radio_aci_scan(struct b43_wldev * dev)
        u8 ret[13];
        unsigned int channel = phy->channel;
        unsigned int i, j, start, end;
-       unsigned long phylock_flags;
 
        if (!((phy->type == B43_PHYTYPE_G) && (phy->rev > 0)))
                return 0;
 
-       b43_phy_lock(dev, phylock_flags);
+       b43_phy_lock(dev);
        b43_radio_lock(dev);
        b43_phy_write(dev, 0x0802, b43_phy_read(dev, 0x0802) & 0xFFFC);
        b43_phy_write(dev, B43_PHY_G_CRS,
@@ -2639,7 +2419,7 @@ u8 b43_radio_aci_scan(struct b43_wldev * dev)
                        ret[j] = 1;
        }
        b43_radio_unlock(dev);
-       b43_phy_unlock(dev, phylock_flags);
+       b43_phy_unlock(dev);
 
        return ret[channel - 1];
 }
@@ -3114,7 +2894,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev)
                        if (phy->radio_ver != 0x2050)
                                return;
                        if (!
-                           (dev->dev->bus->sprom.r1.
+                           (dev->dev->bus->sprom.
                             boardflags_lo & B43_BFL_RSSI))
                                return;
 
@@ -3145,7 +2925,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev)
                }
        case B43_PHYTYPE_G:
                if (!phy->gmode ||
-                   !(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) {
+                   !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
                        tmp16 = b43_nrssi_hw_read(dev, 0x20);
                        if (tmp16 >= 0x20)
                                tmp16 -= 0x40;
@@ -3667,7 +3447,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev,
                }
 
                if ((phy->rev < 7) ||
-                   !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) {
+                   !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
                        if (phy_register == B43_PHY_RFOVER) {
                                return 0x1B3;
                        } else if (phy_register == B43_PHY_RFOVERVAL) {
@@ -3707,7 +3487,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev,
                }
        } else {
                if ((phy->rev < 7) ||
-                   !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) {
+                   !(sprom->boardflags_lo & B43_BFL_EXTLNA)) {
                        if (phy_register == B43_PHY_RFOVER) {
                                return 0x1B3;
                        } else if (phy_register == B43_PHY_RFOVERVAL) {
@@ -3757,10 +3537,10 @@ struct init2050_saved_values {
        u16 radio_52;
        /* PHY registers */
        u16 phy_pgactl;
-       u16 phy_base_5A;
-       u16 phy_base_59;
-       u16 phy_base_58;
-       u16 phy_base_30;
+       u16 phy_cck_5A;
+       u16 phy_cck_59;
+       u16 phy_cck_58;
+       u16 phy_cck_30;
        u16 phy_rfover;
        u16 phy_rfoverval;
        u16 phy_analogover;
@@ -3788,15 +3568,15 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
        sav.radio_51 = b43_radio_read16(dev, 0x51);
        sav.radio_52 = b43_radio_read16(dev, 0x52);
        sav.phy_pgactl = b43_phy_read(dev, B43_PHY_PGACTL);
-       sav.phy_base_5A = b43_phy_read(dev, B43_PHY_BASE(0x5A));
-       sav.phy_base_59 = b43_phy_read(dev, B43_PHY_BASE(0x59));
-       sav.phy_base_58 = b43_phy_read(dev, B43_PHY_BASE(0x58));
+       sav.phy_cck_5A = b43_phy_read(dev, B43_PHY_CCK(0x5A));
+       sav.phy_cck_59 = b43_phy_read(dev, B43_PHY_CCK(0x59));
+       sav.phy_cck_58 = b43_phy_read(dev, B43_PHY_CCK(0x58));
 
        if (phy->type == B43_PHYTYPE_B) {
-               sav.phy_base_30 = b43_phy_read(dev, B43_PHY_BASE(0x30));
+               sav.phy_cck_30 = b43_phy_read(dev, B43_PHY_CCK(0x30));
                sav.reg_3EC = b43_read16(dev, 0x3EC);
 
-               b43_phy_write(dev, B43_PHY_BASE(0x30), 0xFF);
+               b43_phy_write(dev, B43_PHY_CCK(0x30), 0xFF);
                b43_write16(dev, 0x3EC, 0x3F3F);
        } else if (phy->gmode || phy->rev >= 2) {
                sav.phy_rfover = b43_phy_read(dev, B43_PHY_RFOVER);
@@ -3847,8 +3627,8 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                b43_write16(dev, 0x03E6, 0x0122);
        } else {
                if (phy->analog >= 2) {
-                       b43_phy_write(dev, B43_PHY_BASE(0x03),
-                                     (b43_phy_read(dev, B43_PHY_BASE(0x03))
+                       b43_phy_write(dev, B43_PHY_CCK(0x03),
+                                     (b43_phy_read(dev, B43_PHY_CCK(0x03))
                                       & 0xFFBF) | 0x40);
                }
                b43_write16(dev, B43_MMIO_CHANNEL_EXT,
@@ -3865,7 +3645,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                                                   LPD(0, 1, 1)));
        }
        b43_phy_write(dev, B43_PHY_PGACTL, 0xBFAF);
-       b43_phy_write(dev, B43_PHY_BASE(0x2B), 0x1403);
+       b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x1403);
        if (phy->gmode || phy->rev >= 2) {
                b43_phy_write(dev, B43_PHY_RFOVERVAL,
                              radio2050_rfover_val(dev, B43_PHY_RFOVERVAL,
@@ -3881,12 +3661,12 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                b43_radio_write16(dev, 0x43, (b43_radio_read16(dev, 0x43)
                                              & 0xFFF0) | 0x0009);
        }
-       b43_phy_write(dev, B43_PHY_BASE(0x58), 0);
+       b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
 
        for (i = 0; i < 16; i++) {
-               b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0480);
-               b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810);
-               b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D);
+               b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0480);
+               b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
+               b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
                if (phy->gmode || phy->rev >= 2) {
                        b43_phy_write(dev, B43_PHY_RFOVERVAL,
                                      radio2050_rfover_val(dev,
@@ -3912,7 +3692,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
                udelay(20);
                tmp1 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
-               b43_phy_write(dev, B43_PHY_BASE(0x58), 0);
+               b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
                if (phy->gmode || phy->rev >= 2) {
                        b43_phy_write(dev, B43_PHY_RFOVERVAL,
                                      radio2050_rfover_val(dev,
@@ -3923,7 +3703,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
        }
        udelay(10);
 
-       b43_phy_write(dev, B43_PHY_BASE(0x58), 0);
+       b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
        tmp1++;
        tmp1 >>= 9;
 
@@ -3932,9 +3712,9 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                b43_radio_write16(dev, 0x78, radio78);
                udelay(10);
                for (j = 0; j < 16; j++) {
-                       b43_phy_write(dev, B43_PHY_BASE(0x5A), 0x0D80);
-                       b43_phy_write(dev, B43_PHY_BASE(0x59), 0xC810);
-                       b43_phy_write(dev, B43_PHY_BASE(0x58), 0x000D);
+                       b43_phy_write(dev, B43_PHY_CCK(0x5A), 0x0D80);
+                       b43_phy_write(dev, B43_PHY_CCK(0x59), 0xC810);
+                       b43_phy_write(dev, B43_PHY_CCK(0x58), 0x000D);
                        if (phy->gmode || phy->rev >= 2) {
                                b43_phy_write(dev, B43_PHY_RFOVERVAL,
                                              radio2050_rfover_val(dev,
@@ -3963,7 +3743,7 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
                        b43_phy_write(dev, B43_PHY_PGACTL, 0xFFF0);
                        udelay(10);
                        tmp2 += b43_phy_read(dev, B43_PHY_LO_LEAKAGE);
-                       b43_phy_write(dev, B43_PHY_BASE(0x58), 0);
+                       b43_phy_write(dev, B43_PHY_CCK(0x58), 0);
                        if (phy->gmode || phy->rev >= 2) {
                                b43_phy_write(dev, B43_PHY_RFOVERVAL,
                                              radio2050_rfover_val(dev,
@@ -3984,16 +3764,16 @@ u16 b43_radio_init2050(struct b43_wldev *dev)
        b43_radio_write16(dev, 0x51, sav.radio_51);
        b43_radio_write16(dev, 0x52, sav.radio_52);
        b43_radio_write16(dev, 0x43, sav.radio_43);
-       b43_phy_write(dev, B43_PHY_BASE(0x5A), sav.phy_base_5A);
-       b43_phy_write(dev, B43_PHY_BASE(0x59), sav.phy_base_59);
-       b43_phy_write(dev, B43_PHY_BASE(0x58), sav.phy_base_58);
+       b43_phy_write(dev, B43_PHY_CCK(0x5A), sav.phy_cck_5A);
+       b43_phy_write(dev, B43_PHY_CCK(0x59), sav.phy_cck_59);
+       b43_phy_write(dev, B43_PHY_CCK(0x58), sav.phy_cck_58);
        b43_write16(dev, 0x3E6, sav.reg_3E6);
        if (phy->analog != 0)
                b43_write16(dev, 0x3F4, sav.reg_3F4);
        b43_phy_write(dev, B43_PHY_SYNCCTL, sav.phy_syncctl);
        b43_synth_pu_workaround(dev, phy->channel);
        if (phy->type == B43_PHYTYPE_B) {
-               b43_phy_write(dev, B43_PHY_BASE(0x30), sav.phy_base_30);
+               b43_phy_write(dev, B43_PHY_CCK(0x30), sav.phy_cck_30);
                b43_write16(dev, 0x3EC, sav.reg_3EC);
        } else if (phy->gmode) {
                b43_write16(dev, B43_MMIO_PHY_RADIO,
@@ -4103,7 +3883,8 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
        struct b43_phy *phy = &dev->phy;
        u16 r8, tmp;
        u16 freq;
-       u16 channelcookie;
+       u16 channelcookie, savedcookie;
+       int err = 0;
 
        if (channel == 0xFF) {
                switch (phy->type) {
@@ -4114,6 +3895,10 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
                case B43_PHYTYPE_G:
                        channel = B43_DEFAULT_CHANNEL_BG;
                        break;
+               case B43_PHYTYPE_N:
+                       //FIXME check if we are on 2.4GHz or 5GHz and set a default channel.
+                       channel = 1;
+                       break;
                default:
                        B43_WARN_ON(1);
                }
@@ -4123,13 +3908,18 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
         * firmware from sending ghost packets.
         */
        channelcookie = channel;
-       if (phy->type == B43_PHYTYPE_A)
+       if (0 /*FIXME on 5Ghz */)
                channelcookie |= 0x100;
+       //FIXME set 40Mhz flag if required
+       savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN);
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie);
 
-       if (phy->type == B43_PHYTYPE_A) {
-               if (channel > 200)
-                       return -EINVAL;
+       switch (phy->type) {
+       case B43_PHYTYPE_A:
+               if (channel > 200) {
+                       err = -EINVAL;
+                       goto out;
+               }
                freq = channel2freq_a(channel);
 
                r8 = b43_radio_read16(dev, 0x0008);
@@ -4176,9 +3966,12 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
                b43_radio_set_tx_iq(dev);
                //TODO: TSSI2dbm workaround
                b43_phy_xmitpower(dev); //FIXME correct?
-       } else {
-               if ((channel < 1) || (channel > 14))
-                       return -EINVAL;
+               break;
+       case B43_PHYTYPE_G:
+               if ((channel < 1) || (channel > 14)) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                if (synthetic_pu_workaround)
                        b43_synth_pu_workaround(dev, channel);
@@ -4186,7 +3979,7 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
                b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
 
                if (channel == 14) {
-                       if (dev->dev->bus->sprom.r1.country_code ==
+                       if (dev->dev->bus->sprom.country_code ==
                            SSB_SPROM1CCODE_JAPAN)
                                b43_hf_write(dev,
                                             b43_hf_read(dev) & ~B43_HF_ACPR);
@@ -4201,110 +3994,25 @@ int b43_radio_selectchannel(struct b43_wldev *dev,
                                    b43_read16(dev, B43_MMIO_CHANNEL_EXT)
                                    & 0xF7BF);
                }
+               break;
+       case B43_PHYTYPE_N:
+               err = b43_nphy_selectchannel(dev, channel);
+               if (err)
+                       goto out;
+               break;
+       default:
+               B43_WARN_ON(1);
        }
 
        phy->channel = channel;
        /* Wait for the radio to tune to the channel and stabilize. */
        msleep(8);
-
-       return 0;
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */
-static u16 b43_get_txgain_base_band(u16 txpower)
-{
-       u16 ret;
-
-       B43_WARN_ON(txpower > 63);
-
-       if (txpower >= 54)
-               ret = 2;
-       else if (txpower >= 49)
-               ret = 4;
-       else if (txpower >= 44)
-               ret = 5;
-       else
-               ret = 6;
-
-       return ret;
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */
-static u16 b43_get_txgain_freq_power_amp(u16 txpower)
-{
-       u16 ret;
-
-       B43_WARN_ON(txpower > 63);
-
-       if (txpower >= 32)
-               ret = 0;
-       else if (txpower >= 25)
-               ret = 1;
-       else if (txpower >= 20)
-               ret = 2;
-       else if (txpower >= 12)
-               ret = 3;
-       else
-               ret = 4;
-
-       return ret;
-}
-
-/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */
-static u16 b43_get_txgain_dac(u16 txpower)
-{
-       u16 ret;
-
-       B43_WARN_ON(txpower > 63);
-
-       if (txpower >= 54)
-               ret = txpower - 53;
-       else if (txpower >= 49)
-               ret = txpower - 42;
-       else if (txpower >= 44)
-               ret = txpower - 37;
-       else if (txpower >= 32)
-               ret = txpower - 32;
-       else if (txpower >= 25)
-               ret = txpower - 20;
-       else if (txpower >= 20)
-               ret = txpower - 13;
-       else if (txpower >= 12)
-               ret = txpower - 8;
-       else
-               ret = txpower;
-
-       return ret;
-}
-
-static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower)
-{
-       struct b43_phy *phy = &dev->phy;
-       u16 pamp, base, dac, t;
-
-       txpower = limit_value(txpower, 0, 63);
-
-       pamp = b43_get_txgain_freq_power_amp(txpower);
-       pamp <<= 5;
-       pamp &= 0x00E0;
-       b43_phy_write(dev, 0x0019, pamp);
-
-       base = b43_get_txgain_base_band(txpower);
-       base &= 0x000F;
-       b43_phy_write(dev, 0x0017, base | 0x0020);
-
-       t = b43_ofdmtab_read16(dev, 0x3000, 1);
-       t &= 0x0007;
-
-       dac = b43_get_txgain_dac(txpower);
-       dac <<= 3;
-       dac |= t;
-
-       b43_ofdmtab_write16(dev, 0x3000, 1, dac);
-
-       phy->txpwr_offset = txpower;
-
-       //TODO: FuncPlaceholder (Adjust BB loft cancel)
+out:
+       if (err) {
+               b43_shm_write16(dev, B43_SHM_SHARED,
+                               B43_SHM_SH_CHAN, savedcookie);
+       }
+       return err;
 }
 
 void b43_radio_turn_on(struct b43_wldev *dev)
@@ -4344,6 +4052,9 @@ void b43_radio_turn_on(struct b43_wldev *dev)
                err |= b43_radio_selectchannel(dev, channel, 0);
                B43_WARN_ON(err);
                break;
+       case B43_PHYTYPE_N:
+               b43_nphy_radio_turn_on(dev);
+               break;
        default:
                B43_WARN_ON(1);
        }
@@ -4357,13 +4068,17 @@ void b43_radio_turn_off(struct b43_wldev *dev, bool force)
        if (!phy->radio_on && !force)
                return;
 
-       if (phy->type == B43_PHYTYPE_A) {
+       switch (phy->type) {
+       case B43_PHYTYPE_N:
+               b43_nphy_radio_turn_off(dev);
+               break;
+       case B43_PHYTYPE_A:
                b43_radio_write16(dev, 0x0004, 0x00FF);
                b43_radio_write16(dev, 0x0005, 0x00FB);
                b43_phy_write(dev, 0x0010, b43_phy_read(dev, 0x0010) | 0x0008);
                b43_phy_write(dev, 0x0011, b43_phy_read(dev, 0x0011) | 0x0008);
-       }
-       if (phy->type == B43_PHYTYPE_G && dev->dev->id.revision >= 5) {
+               break;
+       case B43_PHYTYPE_G: {
                u16 rfover, rfoverval;
 
                rfover = b43_phy_read(dev, B43_PHY_RFOVER);
@@ -4375,7 +4090,10 @@ void b43_radio_turn_off(struct b43_wldev *dev, bool force)
                }
                b43_phy_write(dev, B43_PHY_RFOVER, rfover | 0x008C);
                b43_phy_write(dev, B43_PHY_RFOVERVAL, rfoverval & 0xFF73);
-       } else
-               b43_phy_write(dev, 0x0015, 0xAA00);
+               break;
+       }
+       default:
+               B43_WARN_ON(1);
+       }
        phy->radio_on = 0;
 }
index c64d74504fc0ad29021bd415471f03f0b4c2b7e0..6d165d8221757d98a957072d133c7683d7f66b3c 100644 (file)
@@ -9,14 +9,21 @@ struct b43_phy;
 /*** PHY Registers ***/
 
 /* Routing */
-#define B43_PHYROUTE_OFDM_GPHY         0x400
-#define B43_PHYROUTE_EXT_GPHY          0x800
-
-/* Base registers. */
-#define B43_PHY_BASE(reg)              (reg)
-/* OFDM (A) registers of a G-PHY */
+#define B43_PHYROUTE                   0x0C00 /* PHY register routing bits mask */
+#define  B43_PHYROUTE_BASE             0x0000 /* Base registers */
+#define  B43_PHYROUTE_OFDM_GPHY                0x0400 /* OFDM register routing for G-PHYs */
+#define  B43_PHYROUTE_EXT_GPHY         0x0800 /* Extended G-PHY registers */
+#define  B43_PHYROUTE_N_BMODE          0x0C00 /* N-PHY BMODE registers */
+
+/* CCK (B-PHY) registers. */
+#define B43_PHY_CCK(reg)               ((reg) | B43_PHYROUTE_BASE)
+/* N-PHY registers. */
+#define B43_PHY_N(reg)                 ((reg) | B43_PHYROUTE_BASE)
+/* N-PHY BMODE registers. */
+#define B43_PHY_N_BMODE(reg)           ((reg) | B43_PHYROUTE_N_BMODE)
+/* OFDM (A-PHY) registers. */
 #define B43_PHY_OFDM(reg)              ((reg) | B43_PHYROUTE_OFDM_GPHY)
-/* Extended G-PHY registers */
+/* Extended G-PHY registers. */
 #define B43_PHY_EXTG(reg)              ((reg) | B43_PHYROUTE_EXT_GPHY)
 
 /* OFDM (A) PHY Registers */
@@ -25,10 +32,13 @@ struct b43_phy;
 #define  B43_PHY_BBANDCFG_RXANT                0x180   /* RX Antenna selection */
 #define  B43_PHY_BBANDCFG_RXANT_SHIFT  7
 #define B43_PHY_PWRDOWN                        B43_PHY_OFDM(0x03)      /* Powerdown */
-#define B43_PHY_CRSTHRES1              B43_PHY_OFDM(0x06)      /* CRS Threshold 1 */
+#define B43_PHY_CRSTHRES1_R1           B43_PHY_OFDM(0x06)      /* CRS Threshold 1 (phy.rev 1 only) */
 #define B43_PHY_LNAHPFCTL              B43_PHY_OFDM(0x1C)      /* LNA/HPF control */
+#define B43_PHY_LPFGAINCTL             B43_PHY_OFDM(0x20)      /* LPF Gain control */
 #define B43_PHY_ADIVRELATED            B43_PHY_OFDM(0x27)      /* FIXME rename */
 #define B43_PHY_CRS0                   B43_PHY_OFDM(0x29)
+#define  B43_PHY_CRS0_EN               0x4000
+#define B43_PHY_PEAK_COUNT             B43_PHY_OFDM(0x30)
 #define B43_PHY_ANTDWELL               B43_PHY_OFDM(0x2B)      /* Antenna dwell */
 #define  B43_PHY_ANTDWELL_AUTODIV1     0x0100  /* Automatic RX diversity start antenna */
 #define B43_PHY_ENCORE                 B43_PHY_OFDM(0x49)      /* "Encore" (RangeMax / BroadRange) */
@@ -37,6 +47,7 @@ struct b43_phy;
 #define B43_PHY_OFDM61                 B43_PHY_OFDM(0x61)      /* FIXME rename */
 #define  B43_PHY_OFDM61_10             0x0010  /* FIXME rename */
 #define B43_PHY_IQBAL                  B43_PHY_OFDM(0x69)      /* I/Q balance */
+#define B43_PHY_BBTXDC_BIAS            B43_PHY_OFDM(0x6B)      /* Baseband TX DC bias */
 #define B43_PHY_OTABLECTL              B43_PHY_OFDM(0x72)      /* OFDM table control (see below) */
 #define  B43_PHY_OTABLEOFF             0x03FF  /* OFDM table offset (see below) */
 #define  B43_PHY_OTABLENR              0xFC00  /* OFDM table number (see below) */
@@ -44,6 +55,9 @@ struct b43_phy;
 #define B43_PHY_OTABLEI                        B43_PHY_OFDM(0x73)      /* OFDM table data I */
 #define B43_PHY_OTABLEQ                        B43_PHY_OFDM(0x74)      /* OFDM table data Q */
 #define B43_PHY_HPWR_TSSICTL           B43_PHY_OFDM(0x78)      /* Hardware power TSSI control */
+#define B43_PHY_ADCCTL                 B43_PHY_OFDM(0x7A)      /* ADC control */
+#define B43_PHY_IDLE_TSSI              B43_PHY_OFDM(0x7B)
+#define B43_PHY_A_TEMP_SENSE           B43_PHY_OFDM(0x7C)      /* A PHY temperature sense */
 #define B43_PHY_NRSSITHRES             B43_PHY_OFDM(0x8A)      /* NRSSI threshold */
 #define B43_PHY_ANTWRSETT              B43_PHY_OFDM(0x8C)      /* Antenna WR settle */
 #define  B43_PHY_ANTWRSETT_ARXDIV      0x2000  /* Automatic RX diversity enabled */
@@ -54,33 +68,35 @@ struct b43_phy;
 #define B43_PHY_N1N2GAIN               B43_PHY_OFDM(0xA2)
 #define B43_PHY_CLIPTHRES              B43_PHY_OFDM(0xA3)
 #define B43_PHY_CLIPN1P2THRES          B43_PHY_OFDM(0xA4)
+#define B43_PHY_CCKSHIFTBITS_WA                B43_PHY_OFDM(0xA5)      /* CCK shiftbits workaround, FIXME rename */
+#define B43_PHY_CCKSHIFTBITS           B43_PHY_OFDM(0xA7)      /* FIXME rename */
 #define B43_PHY_DIVSRCHIDX             B43_PHY_OFDM(0xA8)      /* Divider search gain/index */
 #define B43_PHY_CLIPP2THRES            B43_PHY_OFDM(0xA9)
 #define B43_PHY_CLIPP3THRES            B43_PHY_OFDM(0xAA)
 #define B43_PHY_DIVP1P2GAIN            B43_PHY_OFDM(0xAB)
 #define B43_PHY_DIVSRCHGAINBACK                B43_PHY_OFDM(0xAD)      /* Divider search gain back */
 #define B43_PHY_DIVSRCHGAINCHNG                B43_PHY_OFDM(0xAE)      /* Divider search gain change */
-#define B43_PHY_CRSTHRES1_R1           B43_PHY_OFDM(0xC0)      /* CRS Threshold 1 (rev 1 only) */
-#define B43_PHY_CRSTHRES2_R1           B43_PHY_OFDM(0xC1)      /* CRS Threshold 2 (rev 1 only) */
+#define B43_PHY_CRSTHRES1              B43_PHY_OFDM(0xC0)      /* CRS Threshold 1 (phy.rev >= 2 only) */
+#define B43_PHY_CRSTHRES2              B43_PHY_OFDM(0xC1)      /* CRS Threshold 2 (phy.rev >= 2 only) */
 #define B43_PHY_TSSIP_LTBASE           B43_PHY_OFDM(0x380)     /* TSSI power lookup table base */
 #define B43_PHY_DC_LTBASE              B43_PHY_OFDM(0x3A0)     /* DC lookup table base */
 #define B43_PHY_GAIN_LTBASE            B43_PHY_OFDM(0x3C0)     /* Gain lookup table base */
 
 /* CCK (B) PHY Registers */
-#define B43_PHY_VERSION_CCK            B43_PHY_BASE(0x00)      /* Versioning register for B-PHY */
-#define B43_PHY_CCKBBANDCFG            B43_PHY_BASE(0x01)      /* Contains antenna 0/1 control bit */
-#define B43_PHY_PGACTL                 B43_PHY_BASE(0x15)      /* PGA control */
+#define B43_PHY_VERSION_CCK            B43_PHY_CCK(0x00)       /* Versioning register for B-PHY */
+#define B43_PHY_CCKBBANDCFG            B43_PHY_CCK(0x01)       /* Contains antenna 0/1 control bit */
+#define B43_PHY_PGACTL                 B43_PHY_CCK(0x15)       /* PGA control */
 #define  B43_PHY_PGACTL_LPF            0x1000  /* Low pass filter (?) */
 #define  B43_PHY_PGACTL_LOWBANDW       0x0040  /* Low bandwidth flag */
 #define  B43_PHY_PGACTL_UNKNOWN                0xEFA0
-#define B43_PHY_FBCTL1                 B43_PHY_BASE(0x18)      /* Frequency bandwidth control 1 */
-#define B43_PHY_ITSSI                  B43_PHY_BASE(0x29)      /* Idle TSSI */
-#define B43_PHY_LO_LEAKAGE             B43_PHY_BASE(0x2D)      /* Measured LO leakage */
-#define B43_PHY_ENERGY                 B43_PHY_BASE(0x33)      /* Energy */
-#define B43_PHY_SYNCCTL                        B43_PHY_BASE(0x35)
-#define B43_PHY_FBCTL2                 B43_PHY_BASE(0x38)      /* Frequency bandwidth control 2 */
-#define B43_PHY_DACCTL                 B43_PHY_BASE(0x60)      /* DAC control */
-#define B43_PHY_RCCALOVER              B43_PHY_BASE(0x78)      /* RC calibration override */
+#define B43_PHY_FBCTL1                 B43_PHY_CCK(0x18)       /* Frequency bandwidth control 1 */
+#define B43_PHY_ITSSI                  B43_PHY_CCK(0x29)       /* Idle TSSI */
+#define B43_PHY_LO_LEAKAGE             B43_PHY_CCK(0x2D)       /* Measured LO leakage */
+#define B43_PHY_ENERGY                 B43_PHY_CCK(0x33)       /* Energy */
+#define B43_PHY_SYNCCTL                        B43_PHY_CCK(0x35)
+#define B43_PHY_FBCTL2                 B43_PHY_CCK(0x38)       /* Frequency bandwidth control 2 */
+#define B43_PHY_DACCTL                 B43_PHY_CCK(0x60)       /* DAC control */
+#define B43_PHY_RCCALOVER              B43_PHY_CCK(0x78)       /* RC calibration override */
 
 /* Extended G-PHY Registers */
 #define B43_PHY_CLASSCTL               B43_PHY_EXTG(0x02)      /* Classify control */
@@ -125,13 +141,14 @@ struct b43_phy;
 #define B43_OFDMTAB_DC                 B43_OFDMTAB(0x0E, 7)
 #define B43_OFDMTAB_PWRDYN2            B43_OFDMTAB(0x0E, 12)
 #define B43_OFDMTAB_LNAGAIN            B43_OFDMTAB(0x0E, 13)
-//TODO
+#define B43_OFDMTAB_UNKNOWN_0F         B43_OFDMTAB(0x0F, 0)    //TODO rename
+#define B43_OFDMTAB_UNKNOWN_APHY       B43_OFDMTAB(0x0F, 7)    //TODO rename
 #define B43_OFDMTAB_LPFGAIN            B43_OFDMTAB(0x0F, 12)
 #define B43_OFDMTAB_RSSI               B43_OFDMTAB(0x10, 0)
-//TODO
+#define B43_OFDMTAB_UNKNOWN_11         B43_OFDMTAB(0x11, 4)    //TODO rename
 #define B43_OFDMTAB_AGC1_R1            B43_OFDMTAB(0x13, 0)
-#define B43_OFDMTAB_GAINX_R1           B43_OFDMTAB(0x14, 0)    //TODO rename
-#define B43_OFDMTAB_MINSIGSQ           B43_OFDMTAB(0x14, 1)
+#define B43_OFDMTAB_GAINX_R1           B43_OFDMTAB(0x14, 0)    //TODO remove!
+#define B43_OFDMTAB_MINSIGSQ           B43_OFDMTAB(0x14, 0)
 #define B43_OFDMTAB_AGC3_R1            B43_OFDMTAB(0x15, 0)
 #define B43_OFDMTAB_WRSSI_R1           B43_OFDMTAB(0x15, 4)
 #define B43_OFDMTAB_TSSI               B43_OFDMTAB(0x15, 0)
@@ -163,6 +180,8 @@ enum {
        B43_ANTENNA1,           /* Antenna 0 */
        B43_ANTENNA_AUTO1,      /* Automatic, starting with antenna 1 */
        B43_ANTENNA_AUTO0,      /* Automatic, starting with antenna 0 */
+       B43_ANTENNA2,
+       B43_ANTENNA3 = 8,
 
        B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
        B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
@@ -182,21 +201,21 @@ enum {
 #define B43_PHYVER_TYPE_SHIFT          8
 #define B43_PHYVER_VERSION             0x00FF
 
-void b43_raw_phy_lock(struct b43_wldev *dev);
-#define b43_phy_lock(dev, flags) \
-       do {                                    \
-               local_irq_save(flags);          \
-               b43_raw_phy_lock(dev);  \
-       } while (0)
-void b43_raw_phy_unlock(struct b43_wldev *dev);
-#define b43_phy_unlock(dev, flags) \
-       do {                                    \
-               b43_raw_phy_unlock(dev);        \
-               local_irq_restore(flags);       \
-       } while (0)
+void b43_phy_lock(struct b43_wldev *dev);
+void b43_phy_unlock(struct b43_wldev *dev);
+
 
+/* Read a value from a PHY register */
 u16 b43_phy_read(struct b43_wldev *dev, u16 offset);
+/* Write a value to a PHY register */
 void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val);
+/* Mask a PHY register with a mask */
+void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
+/* OR a PHY register with a bitmap */
+void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
+/* Mask and OR a PHY register with a mask and bitmap */
+void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
+
 
 int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev);
 
@@ -260,8 +279,18 @@ extern const u8 b43_radio_channel_codes_bg[];
 void b43_radio_lock(struct b43_wldev *dev);
 void b43_radio_unlock(struct b43_wldev *dev);
 
+
+/* Read a value from a 16bit radio register */
 u16 b43_radio_read16(struct b43_wldev *dev, u16 offset);
+/* Write a value to a 16bit radio register */
 void b43_radio_write16(struct b43_wldev *dev, u16 offset, u16 val);
+/* Mask a 16bit radio register with a mask */
+void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
+/* OR a 16bit radio register with a bitmap */
+void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
+/* Mask and OR a PHY register with a mask and bitmap */
+void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
+
 
 u16 b43_radio_init2050(struct b43_wldev *dev);
 void b43_radio_init2060(struct b43_wldev *dev);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
deleted file mode 100644 (file)
index 67752a2..0000000
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
-
-  Broadcom B43 wireless driver
-
-  PIO Transmission
-
-  Copyright (c) 2005 Michael Buesch <mb@bu3sch.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, write to
-  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
-  Boston, MA 02110-1301, USA.
-
-*/
-
-#include "b43.h"
-#include "pio.h"
-#include "main.h"
-#include "xmit.h"
-
-#include <linux/delay.h>
-
-static void tx_start(struct b43_pioqueue *queue)
-{
-       b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_INIT);
-}
-
-static void tx_octet(struct b43_pioqueue *queue, u8 octet)
-{
-       if (queue->need_workarounds) {
-               b43_pio_write(queue, B43_PIO_TXDATA, octet);
-               b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_WRITELO);
-       } else {
-               b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_WRITELO);
-               b43_pio_write(queue, B43_PIO_TXDATA, octet);
-       }
-}
-
-static u16 tx_get_next_word(const u8 * txhdr,
-                           const u8 * packet,
-                           size_t txhdr_size, unsigned int *pos)
-{
-       const u8 *source;
-       unsigned int i = *pos;
-       u16 ret;
-
-       if (i < txhdr_size) {
-               source = txhdr;
-       } else {
-               source = packet;
-               i -= txhdr_size;
-       }
-       ret = le16_to_cpu(*((__le16 *)(source + i)));
-       *pos += 2;
-
-       return ret;
-}
-
-static void tx_data(struct b43_pioqueue *queue,
-                   u8 * txhdr, const u8 * packet, unsigned int octets)
-{
-       u16 data;
-       unsigned int i = 0;
-
-       if (queue->need_workarounds) {
-               data = tx_get_next_word(txhdr, packet,
-                                       sizeof(struct b43_txhdr_fw4), &i);
-               b43_pio_write(queue, B43_PIO_TXDATA, data);
-       }
-       b43_pio_write(queue, B43_PIO_TXCTL,
-                     B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI);
-       while (i < octets - 1) {
-               data = tx_get_next_word(txhdr, packet,
-                                       sizeof(struct b43_txhdr_fw4), &i);
-               b43_pio_write(queue, B43_PIO_TXDATA, data);
-       }
-       if (octets % 2)
-               tx_octet(queue,
-                        packet[octets - sizeof(struct b43_txhdr_fw4) - 1]);
-}
-
-static void tx_complete(struct b43_pioqueue *queue, struct sk_buff *skb)
-{
-       if (queue->need_workarounds) {
-               b43_pio_write(queue, B43_PIO_TXDATA, skb->data[skb->len - 1]);
-               b43_pio_write(queue, B43_PIO_TXCTL,
-                             B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_COMPLETE);
-       } else {
-               b43_pio_write(queue, B43_PIO_TXCTL, B43_PIO_TXCTL_COMPLETE);
-       }
-}
-
-static u16 generate_cookie(struct b43_pioqueue *queue,
-                          struct b43_pio_txpacket *packet)
-{
-       u16 cookie = 0x0000;
-       u16 packetindex;
-
-       /* We use the upper 4 bits for the PIO
-        * controller ID and the lower 12 bits
-        * for the packet index (in the cache).
-        */
-       switch (queue->mmio_base) {
-       case B43_MMIO_PIO1_BASE:
-               break;
-       case B43_MMIO_PIO2_BASE:
-               cookie = 0x1000;
-               break;
-       case B43_MMIO_PIO3_BASE:
-               cookie = 0x2000;
-               break;
-       case B43_MMIO_PIO4_BASE:
-               cookie = 0x3000;
-               break;
-       default:
-               B43_WARN_ON(1);
-       }
-       packetindex = packet->index;
-       B43_WARN_ON(packetindex & ~0x0FFF);
-       cookie |= (u16) packetindex;
-
-       return cookie;
-}
-
-static
-struct b43_pioqueue *parse_cookie(struct b43_wldev *dev,
-                                 u16 cookie, struct b43_pio_txpacket **packet)
-{
-       struct b43_pio *pio = &dev->pio;
-       struct b43_pioqueue *queue = NULL;
-       int packetindex;
-
-       switch (cookie & 0xF000) {
-       case 0x0000:
-               queue = pio->queue0;
-               break;
-       case 0x1000:
-               queue = pio->queue1;
-               break;
-       case 0x2000:
-               queue = pio->queue2;
-               break;
-       case 0x3000:
-               queue = pio->queue3;
-               break;
-       default:
-               B43_WARN_ON(1);
-       }
-       packetindex = (cookie & 0x0FFF);
-       B43_WARN_ON(!(packetindex >= 0 && packetindex < B43_PIO_MAXTXPACKETS));
-       *packet = &(queue->tx_packets_cache[packetindex]);
-
-       return queue;
-}
-
-union txhdr_union {
-       struct b43_txhdr_fw4 txhdr_fw4;
-};
-
-static void pio_tx_write_fragment(struct b43_pioqueue *queue,
-                                 struct sk_buff *skb,
-                                 struct b43_pio_txpacket *packet,
-                                 size_t txhdr_size)
-{
-       union txhdr_union txhdr_data;
-       u8 *txhdr = NULL;
-       unsigned int octets;
-
-       txhdr = (u8 *) (&txhdr_data.txhdr_fw4);
-
-       B43_WARN_ON(skb_shinfo(skb)->nr_frags);
-       b43_generate_txhdr(queue->dev,
-                          txhdr, skb->data, skb->len,
-                          &packet->txstat.control,
-                          generate_cookie(queue, packet));
-
-       tx_start(queue);
-       octets = skb->len + txhdr_size;
-       if (queue->need_workarounds)
-               octets--;
-       tx_data(queue, txhdr, (u8 *) skb->data, octets);
-       tx_complete(queue, skb);
-}
-
-static void free_txpacket(struct b43_pio_txpacket *packet)
-{
-       struct b43_pioqueue *queue = packet->queue;
-
-       if (packet->skb)
-               dev_kfree_skb_any(packet->skb);
-       list_move(&packet->list, &queue->txfree);
-       queue->nr_txfree++;
-}
-
-static int pio_tx_packet(struct b43_pio_txpacket *packet)
-{
-       struct b43_pioqueue *queue = packet->queue;
-       struct sk_buff *skb = packet->skb;
-       u16 octets;
-
-       octets = (u16) skb->len + sizeof(struct b43_txhdr_fw4);
-       if (queue->tx_devq_size < octets) {
-               b43warn(queue->dev->wl, "PIO queue too small. "
-                       "Dropping packet.\n");
-               /* Drop it silently (return success) */
-               free_txpacket(packet);
-               return 0;
-       }
-       B43_WARN_ON(queue->tx_devq_packets > B43_PIO_MAXTXDEVQPACKETS);
-       B43_WARN_ON(queue->tx_devq_used > queue->tx_devq_size);
-       /* Check if there is sufficient free space on the device
-        * TX queue. If not, return and let the TX tasklet
-        * retry later.
-        */
-       if (queue->tx_devq_packets == B43_PIO_MAXTXDEVQPACKETS)
-               return -EBUSY;
-       if (queue->tx_devq_used + octets > queue->tx_devq_size)
-               return -EBUSY;
-       /* Now poke the device. */
-       pio_tx_write_fragment(queue, skb, packet, sizeof(struct b43_txhdr_fw4));
-
-       /* Account for the packet size.
-        * (We must not overflow the device TX queue)
-        */
-       queue->tx_devq_packets++;
-       queue->tx_devq_used += octets;
-
-       /* Transmission started, everything ok, move the
-        * packet to the txrunning list.
-        */
-       list_move_tail(&packet->list, &queue->txrunning);
-
-       return 0;
-}
-
-static void tx_tasklet(unsigned long d)
-{
-       struct b43_pioqueue *queue = (struct b43_pioqueue *)d;
-       struct b43_wldev *dev = queue->dev;
-       unsigned long flags;
-       struct b43_pio_txpacket *packet, *tmp_packet;
-       int err;
-       u16 txctl;
-
-       spin_lock_irqsave(&dev->wl->irq_lock, flags);
-       if (queue->tx_frozen)
-               goto out_unlock;
-       txctl = b43_pio_read(queue, B43_PIO_TXCTL);
-       if (txctl & B43_PIO_TXCTL_SUSPEND)
-               goto out_unlock;
-
-       list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
-               /* Try to transmit the packet. This can fail, if
-                * the device queue is full. In case of failure, the
-                * packet is left in the txqueue.
-                * If transmission succeed, the packet is moved to txrunning.
-                * If it is impossible to transmit the packet, it
-                * is dropped.
-                */
-               err = pio_tx_packet(packet);
-               if (err)
-                       break;
-       }
-      out_unlock:
-       spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
-}
-
-static void setup_txqueues(struct b43_pioqueue *queue)
-{
-       struct b43_pio_txpacket *packet;
-       int i;
-
-       queue->nr_txfree = B43_PIO_MAXTXPACKETS;
-       for (i = 0; i < B43_PIO_MAXTXPACKETS; i++) {
-               packet = &(queue->tx_packets_cache[i]);
-
-               packet->queue = queue;
-               INIT_LIST_HEAD(&packet->list);
-               packet->index = i;
-
-               list_add(&packet->list, &queue->txfree);
-       }
-}
-
-static
-struct b43_pioqueue *b43_setup_pioqueue(struct b43_wldev *dev,
-                                       u16 pio_mmio_base)
-{
-       struct b43_pioqueue *queue;
-       u16 qsize;
-
-       queue = kzalloc(sizeof(*queue), GFP_KERNEL);
-       if (!queue)
-               goto out;
-
-       queue->dev = dev;
-       queue->mmio_base = pio_mmio_base;
-       queue->need_workarounds = (dev->dev->id.revision < 3);
-
-       INIT_LIST_HEAD(&queue->txfree);
-       INIT_LIST_HEAD(&queue->txqueue);
-       INIT_LIST_HEAD(&queue->txrunning);
-       tasklet_init(&queue->txtask, tx_tasklet, (unsigned long)queue);
-
-       b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
-                   & ~B43_MACCTL_BE);
-
-       qsize = b43_read16(dev, queue->mmio_base + B43_PIO_TXQBUFSIZE);
-       if (qsize == 0) {
-               b43err(dev->wl, "This card does not support PIO "
-                      "operation mode. Please use DMA mode "
-                      "(module parameter pio=0).\n");
-               goto err_freequeue;
-       }
-       if (qsize <= B43_PIO_TXQADJUST) {
-               b43err(dev->wl, "PIO tx device-queue too small (%u)\n", qsize);
-               goto err_freequeue;
-       }
-       qsize -= B43_PIO_TXQADJUST;
-       queue->tx_devq_size = qsize;
-
-       setup_txqueues(queue);
-
-      out:
-       return queue;
-
-      err_freequeue:
-       kfree(queue);
-       queue = NULL;
-       goto out;
-}
-
-static void cancel_transfers(struct b43_pioqueue *queue)
-{
-       struct b43_pio_txpacket *packet, *tmp_packet;
-
-       tasklet_disable(&queue->txtask);
-
-       list_for_each_entry_safe(packet, tmp_packet, &queue->txrunning, list)
-           free_txpacket(packet);
-       list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list)
-           free_txpacket(packet);
-}
-
-static void b43_destroy_pioqueue(struct b43_pioqueue *queue)
-{
-       if (!queue)
-               return;
-
-       cancel_transfers(queue);
-       kfree(queue);
-}
-
-void b43_pio_free(struct b43_wldev *dev)
-{
-       struct b43_pio *pio;
-
-       if (!b43_using_pio(dev))
-               return;
-       pio = &dev->pio;
-
-       b43_destroy_pioqueue(pio->queue3);
-       pio->queue3 = NULL;
-       b43_destroy_pioqueue(pio->queue2);
-       pio->queue2 = NULL;
-       b43_destroy_pioqueue(pio->queue1);
-       pio->queue1 = NULL;
-       b43_destroy_pioqueue(pio->queue0);
-       pio->queue0 = NULL;
-}
-
-int b43_pio_init(struct b43_wldev *dev)
-{
-       struct b43_pio *pio = &dev->pio;
-       struct b43_pioqueue *queue;
-       int err = -ENOMEM;
-
-       queue = b43_setup_pioqueue(dev, B43_MMIO_PIO1_BASE);
-       if (!queue)
-               goto out;
-       pio->queue0 = queue;
-
-       queue = b43_setup_pioqueue(dev, B43_MMIO_PIO2_BASE);
-       if (!queue)
-               goto err_destroy0;
-       pio->queue1 = queue;
-
-       queue = b43_setup_pioqueue(dev, B43_MMIO_PIO3_BASE);
-       if (!queue)
-               goto err_destroy1;
-       pio->queue2 = queue;
-
-       queue = b43_setup_pioqueue(dev, B43_MMIO_PIO4_BASE);
-       if (!queue)
-               goto err_destroy2;
-       pio->queue3 = queue;
-
-       if (dev->dev->id.revision < 3)
-               dev->irq_savedstate |= B43_IRQ_PIO_WORKAROUND;
-
-       b43dbg(dev->wl, "PIO initialized\n");
-       err = 0;
-      out:
-       return err;
-
-      err_destroy2:
-       b43_destroy_pioqueue(pio->queue2);
-       pio->queue2 = NULL;
-      err_destroy1:
-       b43_destroy_pioqueue(pio->queue1);
-       pio->queue1 = NULL;
-      err_destroy0:
-       b43_destroy_pioqueue(pio->queue0);
-       pio->queue0 = NULL;
-       goto out;
-}
-
-int b43_pio_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl)
-{
-       struct b43_pioqueue *queue = dev->pio.queue1;
-       struct b43_pio_txpacket *packet;
-
-       B43_WARN_ON(queue->tx_suspended);
-       B43_WARN_ON(list_empty(&queue->txfree));
-
-       packet = list_entry(queue->txfree.next, struct b43_pio_txpacket, list);
-       packet->skb = skb;
-
-       memset(&packet->txstat, 0, sizeof(packet->txstat));
-       memcpy(&packet->txstat.control, ctl, sizeof(*ctl));
-
-       list_move_tail(&packet->list, &queue->txqueue);
-       queue->nr_txfree--;
-       queue->nr_tx_packets++;
-       B43_WARN_ON(queue->nr_txfree >= B43_PIO_MAXTXPACKETS);
-
-       tasklet_schedule(&queue->txtask);
-
-       return 0;
-}
-
-void b43_pio_handle_txstatus(struct b43_wldev *dev,
-                            const struct b43_txstatus *status)
-{
-       struct b43_pioqueue *queue;
-       struct b43_pio_txpacket *packet;
-
-       queue = parse_cookie(dev, status->cookie, &packet);
-       if (B43_WARN_ON(!queue))
-               return;
-
-       queue->tx_devq_packets--;
-       queue->tx_devq_used -=
-           (packet->skb->len + sizeof(struct b43_txhdr_fw4));
-
-       if (status->acked) {
-               packet->txstat.flags |= IEEE80211_TX_STATUS_ACK;
-       } else {
-               if (!(packet->txstat.control.flags & IEEE80211_TXCTL_NO_ACK))
-                       packet->txstat.excessive_retries = 1;
-       }
-       if (status->frame_count == 0) {
-               /* The frame was not transmitted at all. */
-               packet->txstat.retry_count = 0;
-       } else
-               packet->txstat.retry_count = status->frame_count - 1;
-       ieee80211_tx_status_irqsafe(dev->wl->hw, packet->skb,
-                                   &(packet->txstat));
-       packet->skb = NULL;
-
-       free_txpacket(packet);
-       /* If there are packets on the txqueue, poke the tasklet
-        * to transmit them.
-        */
-       if (!list_empty(&queue->txqueue))
-               tasklet_schedule(&queue->txtask);
-}
-
-void b43_pio_get_tx_stats(struct b43_wldev *dev,
-                         struct ieee80211_tx_queue_stats *stats)
-{
-       struct b43_pio *pio = &dev->pio;
-       struct b43_pioqueue *queue;
-       struct ieee80211_tx_queue_stats_data *data;
-
-       queue = pio->queue1;
-       data = &(stats->data[0]);
-       data->len = B43_PIO_MAXTXPACKETS - queue->nr_txfree;
-       data->limit = B43_PIO_MAXTXPACKETS;
-       data->count = queue->nr_tx_packets;
-}
-
-static void pio_rx_error(struct b43_pioqueue *queue,
-                        int clear_buffers, const char *error)
-{
-       int i;
-
-       b43err(queue->dev->wl, "PIO RX error: %s\n", error);
-       b43_pio_write(queue, B43_PIO_RXCTL, B43_PIO_RXCTL_READY);
-       if (clear_buffers) {
-               B43_WARN_ON(queue->mmio_base != B43_MMIO_PIO1_BASE);
-               for (i = 0; i < 15; i++) {
-                       /* Dummy read. */
-                       b43_pio_read(queue, B43_PIO_RXDATA);
-               }
-       }
-}
-
-void b43_pio_rx(struct b43_pioqueue *queue)
-{
-       __le16 preamble[21] = { 0 };
-       struct b43_rxhdr_fw4 *rxhdr;
-       u16 tmp, len;
-       u32 macstat;
-       int i, preamble_readwords;
-       struct sk_buff *skb;
-
-       tmp = b43_pio_read(queue, B43_PIO_RXCTL);
-       if (!(tmp & B43_PIO_RXCTL_DATAAVAILABLE))
-               return;
-       b43_pio_write(queue, B43_PIO_RXCTL, B43_PIO_RXCTL_DATAAVAILABLE);
-
-       for (i = 0; i < 10; i++) {
-               tmp = b43_pio_read(queue, B43_PIO_RXCTL);
-               if (tmp & B43_PIO_RXCTL_READY)
-                       goto data_ready;
-               udelay(10);
-       }
-       b43dbg(queue->dev->wl, "PIO RX timed out\n");
-       return;
-data_ready:
-
-       len = b43_pio_read(queue, B43_PIO_RXDATA);
-       if (unlikely(len > 0x700)) {
-               pio_rx_error(queue, 0, "len > 0x700");
-               return;
-       }
-       if (unlikely(len == 0 && queue->mmio_base != B43_MMIO_PIO4_BASE)) {
-               pio_rx_error(queue, 0, "len == 0");
-               return;
-       }
-       preamble[0] = cpu_to_le16(len);
-       if (queue->mmio_base == B43_MMIO_PIO4_BASE)
-               preamble_readwords = 14 / sizeof(u16);
-       else
-               preamble_readwords = 18 / sizeof(u16);
-       for (i = 0; i < preamble_readwords; i++) {
-               tmp = b43_pio_read(queue, B43_PIO_RXDATA);
-               preamble[i + 1] = cpu_to_le16(tmp);
-       }
-       rxhdr = (struct b43_rxhdr_fw4 *)preamble;
-       macstat = le32_to_cpu(rxhdr->mac_status);
-       if (macstat & B43_RX_MAC_FCSERR) {
-               pio_rx_error(queue,
-                            (queue->mmio_base == B43_MMIO_PIO1_BASE),
-                            "Frame FCS error");
-               return;
-       }
-       if (queue->mmio_base == B43_MMIO_PIO4_BASE) {
-               /* We received an xmit status. */
-               struct b43_hwtxstatus *hw;
-
-               hw = (struct b43_hwtxstatus *)(preamble + 1);
-               b43_handle_hwtxstatus(queue->dev, hw);
-
-               return;
-       }
-
-       skb = dev_alloc_skb(len);
-       if (unlikely(!skb)) {
-               pio_rx_error(queue, 1, "OOM");
-               return;
-       }
-       skb_put(skb, len);
-       for (i = 0; i < len - 1; i += 2) {
-               tmp = b43_pio_read(queue, B43_PIO_RXDATA);
-               *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp);
-       }
-       if (len % 2) {
-               tmp = b43_pio_read(queue, B43_PIO_RXDATA);
-               skb->data[len - 1] = (tmp & 0x00FF);
-/* The specs say the following is required, but
- * it is wrong and corrupts the PLCP. If we don't do
- * this, the PLCP seems to be correct. So ifdef it out for now.
- */
-#if 0
-               if (rxflags2 & B43_RXHDR_FLAGS2_TYPE2FRAME)
-                       skb->data[2] = (tmp & 0xFF00) >> 8;
-               else
-                       skb->data[0] = (tmp & 0xFF00) >> 8;
-#endif
-       }
-       b43_rx(queue->dev, skb, rxhdr);
-}
-
-void b43_pio_tx_suspend(struct b43_pioqueue *queue)
-{
-       b43_power_saving_ctl_bits(queue->dev, B43_PS_AWAKE);
-       b43_pio_write(queue, B43_PIO_TXCTL, b43_pio_read(queue, B43_PIO_TXCTL)
-                     | B43_PIO_TXCTL_SUSPEND);
-}
-
-void b43_pio_tx_resume(struct b43_pioqueue *queue)
-{
-       b43_pio_write(queue, B43_PIO_TXCTL, b43_pio_read(queue, B43_PIO_TXCTL)
-                     & ~B43_PIO_TXCTL_SUSPEND);
-       b43_power_saving_ctl_bits(queue->dev, 0);
-       tasklet_schedule(&queue->txtask);
-}
-
-void b43_pio_freeze_txqueues(struct b43_wldev *dev)
-{
-       struct b43_pio *pio;
-
-       B43_WARN_ON(!b43_using_pio(dev));
-       pio = &dev->pio;
-       pio->queue0->tx_frozen = 1;
-       pio->queue1->tx_frozen = 1;
-       pio->queue2->tx_frozen = 1;
-       pio->queue3->tx_frozen = 1;
-}
-
-void b43_pio_thaw_txqueues(struct b43_wldev *dev)
-{
-       struct b43_pio *pio;
-
-       B43_WARN_ON(!b43_using_pio(dev));
-       pio = &dev->pio;
-       pio->queue0->tx_frozen = 0;
-       pio->queue1->tx_frozen = 0;
-       pio->queue2->tx_frozen = 0;
-       pio->queue3->tx_frozen = 0;
-       if (!list_empty(&pio->queue0->txqueue))
-               tasklet_schedule(&pio->queue0->txtask);
-       if (!list_empty(&pio->queue1->txqueue))
-               tasklet_schedule(&pio->queue1->txtask);
-       if (!list_empty(&pio->queue2->txqueue))
-               tasklet_schedule(&pio->queue2->txtask);
-       if (!list_empty(&pio->queue3->txqueue))
-               tasklet_schedule(&pio->queue3->txtask);
-}
diff --git a/drivers/net/wireless/b43/pio.h b/drivers/net/wireless/b43/pio.h
deleted file mode 100644 (file)
index 3488f24..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-#ifndef B43_PIO_H_
-#define B43_PIO_H_
-
-#include "b43.h"
-
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/skbuff.h>
-
-#define B43_PIO_TXCTL          0x00
-#define B43_PIO_TXDATA         0x02
-#define B43_PIO_TXQBUFSIZE             0x04
-#define B43_PIO_RXCTL          0x08
-#define B43_PIO_RXDATA         0x0A
-
-#define B43_PIO_TXCTL_WRITELO  (1 << 0)
-#define B43_PIO_TXCTL_WRITEHI  (1 << 1)
-#define B43_PIO_TXCTL_COMPLETE (1 << 2)
-#define B43_PIO_TXCTL_INIT             (1 << 3)
-#define B43_PIO_TXCTL_SUSPEND  (1 << 7)
-
-#define B43_PIO_RXCTL_DATAAVAILABLE    (1 << 0)
-#define B43_PIO_RXCTL_READY            (1 << 1)
-
-/* PIO constants */
-#define B43_PIO_MAXTXDEVQPACKETS       31
-#define B43_PIO_TXQADJUST              80
-
-/* PIO tuning knobs */
-#define B43_PIO_MAXTXPACKETS   256
-
-#ifdef CONFIG_B43_PIO
-
-struct b43_pioqueue;
-struct b43_xmitstatus;
-
-struct b43_pio_txpacket {
-       struct b43_pioqueue *queue;
-       struct sk_buff *skb;
-       struct ieee80211_tx_status txstat;
-       struct list_head list;
-       u16 index; /* Index in the tx_packets_cache */
-};
-
-struct b43_pioqueue {
-       struct b43_wldev *dev;
-       u16 mmio_base;
-
-       bool tx_suspended;
-       bool tx_frozen;
-       bool need_workarounds;  /* Workarounds needed for core.rev < 3 */
-
-       /* Adjusted size of the device internal TX buffer. */
-       u16 tx_devq_size;
-       /* Used octets of the device internal TX buffer. */
-       u16 tx_devq_used;
-       /* Used packet slots in the device internal TX buffer. */
-       u8 tx_devq_packets;
-       /* Packets from the txfree list can
-        * be taken on incoming TX requests.
-        */
-       struct list_head txfree;
-       unsigned int nr_txfree;
-       /* Packets on the txqueue are queued,
-        * but not completely written to the chip, yet.
-        */
-       struct list_head txqueue;
-       /* Packets on the txrunning queue are completely
-        * posted to the device. We are waiting for the txstatus.
-        */
-       struct list_head txrunning;
-       /* Total number or packets sent.
-        * (This counter can obviously wrap).
-        */
-       unsigned int nr_tx_packets;
-       struct tasklet_struct txtask;
-       struct b43_pio_txpacket tx_packets_cache[B43_PIO_MAXTXPACKETS];
-};
-
-static inline u16 b43_pio_read(struct b43_pioqueue *queue, u16 offset)
-{
-       return b43_read16(queue->dev, queue->mmio_base + offset);
-}
-
-static inline
-    void b43_pio_write(struct b43_pioqueue *queue, u16 offset, u16 value)
-{
-       b43_write16(queue->dev, queue->mmio_base + offset, value);
-       mmiowb();
-}
-
-int b43_pio_init(struct b43_wldev *dev);
-void b43_pio_free(struct b43_wldev *dev);
-
-int b43_pio_tx(struct b43_wldev *dev,
-              struct sk_buff *skb, struct ieee80211_tx_control *ctl);
-void b43_pio_handle_txstatus(struct b43_wldev *dev,
-                            const struct b43_txstatus *status);
-void b43_pio_get_tx_stats(struct b43_wldev *dev,
-                         struct ieee80211_tx_queue_stats *stats);
-void b43_pio_rx(struct b43_pioqueue *queue);
-
-/* Suspend TX queue in hardware. */
-void b43_pio_tx_suspend(struct b43_pioqueue *queue);
-void b43_pio_tx_resume(struct b43_pioqueue *queue);
-/* Suspend (freeze) the TX tasklet (software level). */
-void b43_pio_freeze_txqueues(struct b43_wldev *dev);
-void b43_pio_thaw_txqueues(struct b43_wldev *dev);
-
-#else /* CONFIG_B43_PIO */
-
-static inline int b43_pio_init(struct b43_wldev *dev)
-{
-       return 0;
-}
-static inline void b43_pio_free(struct b43_wldev *dev)
-{
-}
-static inline
-    int b43_pio_tx(struct b43_wldev *dev,
-                  struct sk_buff *skb, struct ieee80211_tx_control *ctl)
-{
-       return 0;
-}
-static inline
-    void b43_pio_handle_txstatus(struct b43_wldev *dev,
-                                const struct b43_txstatus *status)
-{
-}
-static inline
-    void b43_pio_get_tx_stats(struct b43_wldev *dev,
-                             struct ieee80211_tx_queue_stats *stats)
-{
-}
-static inline void b43_pio_rx(struct b43_pioqueue *queue)
-{
-}
-static inline void b43_pio_tx_suspend(struct b43_pioqueue *queue)
-{
-}
-static inline void b43_pio_tx_resume(struct b43_pioqueue *queue)
-{
-}
-static inline void b43_pio_freeze_txqueues(struct b43_wldev *dev)
-{
-}
-static inline void b43_pio_thaw_txqueues(struct b43_wldev *dev)
-{
-}
-
-#endif /* CONFIG_B43_PIO */
-#endif /* B43_PIO_H_ */
index 15a87183a572612b68b39169b3ac85278d35426b..3f5ea06bf13cb0ea5c20d4ba2b6899a3d48e5b10 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43 wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-  Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2006, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -229,7 +229,7 @@ const u16 b43_tab_noisea2[] = {
 };
 
 const u16 b43_tab_noisea3[] = {
-       0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
+       0x5E5E, 0x5E5E, 0x5E5E, 0x3F48,
        0x4C4C, 0x4C4C, 0x4C4C, 0x2D36,
 };
 
@@ -243,6 +243,26 @@ const u16 b43_tab_noiseg2[] = {
        0x0000, 0x0000, 0x0000, 0x0000,
 };
 
+const u16 b43_tab_noisescalea2[] = {
+       0x6767, 0x6767, 0x6767, 0x6767, /* 0 */
+       0x6767, 0x6767, 0x6767, 0x6767,
+       0x6767, 0x6767, 0x6767, 0x6767,
+       0x6767, 0x6700, 0x6767, 0x6767,
+       0x6767, 0x6767, 0x6767, 0x6767, /* 16 */
+       0x6767, 0x6767, 0x6767, 0x6767,
+       0x6767, 0x6767, 0x0067,
+};
+
+const u16 b43_tab_noisescalea3[] = {
+       0x2323, 0x2323, 0x2323, 0x2323, /* 0 */
+       0x2323, 0x2323, 0x2323, 0x2323,
+       0x2323, 0x2323, 0x2323, 0x2323,
+       0x2323, 0x2300, 0x2323, 0x2323,
+       0x2323, 0x2323, 0x2323, 0x2323, /* 16 */
+       0x2323, 0x2323, 0x2323, 0x2323,
+       0x2323, 0x2323, 0x0023,
+};
+
 const u16 b43_tab_noisescaleg1[] = {
        0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */
        0x2F2D, 0x2A2A, 0x2527, 0x1F21,
@@ -254,7 +274,7 @@ const u16 b43_tab_noisescaleg1[] = {
 };
 
 const u16 b43_tab_noisescaleg2[] = {
-       0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */
+       0xD8DD, 0xCBD4, 0xBCC0, 0xB6B7, /* 0 */
        0xB2B0, 0xADAD, 0xA7A9, 0x9FA1,
        0x969B, 0x9195, 0x8F8F, 0x8A8A,
        0x8A8A, 0x8A00, 0x8A8A, 0x8F8A,
@@ -307,6 +327,28 @@ const u16 b43_tab_sigmasqr2[] = {
        0x00DE,
 };
 
+const u16 b43_tab_rssiagc1[] = {
+       0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, /* 0 */
+       0xFFF8, 0xFFF9, 0xFFFC, 0xFFFE,
+       0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8,
+       0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8,
+};
+
+const u16 b43_tab_rssiagc2[] = {
+       0x0820, 0x0820, 0x0920, 0x0C38, /* 0 */
+       0x0820, 0x0820, 0x0820, 0x0820,
+       0x0820, 0x0820, 0x0920, 0x0A38,
+       0x0820, 0x0820, 0x0820, 0x0820,
+       0x0820, 0x0820, 0x0920, 0x0A38, /* 16 */
+       0x0820, 0x0820, 0x0820, 0x0820,
+       0x0820, 0x0820, 0x0920, 0x0A38,
+       0x0820, 0x0820, 0x0820, 0x0820,
+       0x0820, 0x0820, 0x0920, 0x0A38, /* 32 */
+       0x0820, 0x0820, 0x0820, 0x0820,
+       0x0820, 0x0820, 0x0920, 0x0A38,
+       0x0820, 0x0820, 0x0820, 0x0820,
+};
+
 static inline void assert_sizes(void)
 {
        BUILD_BUG_ON(B43_TAB_ROTOR_SIZE != ARRAY_SIZE(b43_tab_rotor));
@@ -317,36 +359,73 @@ static inline void assert_sizes(void)
        BUILD_BUG_ON(B43_TAB_NOISEA3_SIZE != ARRAY_SIZE(b43_tab_noisea3));
        BUILD_BUG_ON(B43_TAB_NOISEG1_SIZE != ARRAY_SIZE(b43_tab_noiseg1));
        BUILD_BUG_ON(B43_TAB_NOISEG2_SIZE != ARRAY_SIZE(b43_tab_noiseg2));
-       BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE !=
+       BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE !=
+                    ARRAY_SIZE(b43_tab_noisescalea2));
+       BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE !=
+                    ARRAY_SIZE(b43_tab_noisescalea3));
+       BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE !=
                     ARRAY_SIZE(b43_tab_noisescaleg1));
-       BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE !=
+       BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE !=
                     ARRAY_SIZE(b43_tab_noisescaleg2));
-       BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE !=
+       BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE !=
                     ARRAY_SIZE(b43_tab_noisescaleg3));
        BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr1));
        BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr2));
+       BUILD_BUG_ON(B43_TAB_RSSIAGC1_SIZE != ARRAY_SIZE(b43_tab_rssiagc1));
+       BUILD_BUG_ON(B43_TAB_RSSIAGC2_SIZE != ARRAY_SIZE(b43_tab_rssiagc2));
 }
 
 u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset)
 {
-       assert_sizes();
+       struct b43_phy *phy = &dev->phy;
+       u16 addr;
+
+       addr = table + offset;
+       if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
+           (addr - 1 != phy->ofdmtab_addr)) {
+               /* The hardware has a different address in memory. Update it. */
+               b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
+               phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
+       }
+       phy->ofdmtab_addr = addr;
 
-       b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset);
        return b43_phy_read(dev, B43_PHY_OTABLEI);
+
+       /* Some compiletime assertions... */
+       assert_sizes();
 }
 
 void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table,
                         u16 offset, u16 value)
 {
-       b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset);
+       struct b43_phy *phy = &dev->phy;
+       u16 addr;
+
+       addr = table + offset;
+       if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
+           (addr - 1 != phy->ofdmtab_addr)) {
+               /* The hardware has a different address in memory. Update it. */
+               b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
+               phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
+       }
+       phy->ofdmtab_addr = addr;
        b43_phy_write(dev, B43_PHY_OTABLEI, value);
 }
 
 u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
 {
+       struct b43_phy *phy = &dev->phy;
        u32 ret;
+       u16 addr;
 
-       b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset);
+       addr = table + offset;
+       if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_READ) ||
+           (addr - 1 != phy->ofdmtab_addr)) {
+               /* The hardware has a different address in memory. Update it. */
+               b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
+               phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_READ;
+       }
+       phy->ofdmtab_addr = addr;
        ret = b43_phy_read(dev, B43_PHY_OTABLEQ);
        ret <<= 16;
        ret |= b43_phy_read(dev, B43_PHY_OTABLEI);
@@ -357,7 +436,18 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset)
 void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table,
                         u16 offset, u32 value)
 {
-       b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset);
+       struct b43_phy *phy = &dev->phy;
+       u16 addr;
+
+       addr = table + offset;
+       if ((phy->ofdmtab_addr_direction != B43_OFDMTAB_DIRECTION_WRITE) ||
+           (addr - 1 != phy->ofdmtab_addr)) {
+               /* The hardware has a different address in memory. Update it. */
+               b43_phy_write(dev, B43_PHY_OTABLECTL, addr);
+               phy->ofdmtab_addr_direction = B43_OFDMTAB_DIRECTION_WRITE;
+       }
+       phy->ofdmtab_addr = addr;
+
        b43_phy_write(dev, B43_PHY_OTABLEI, value);
        b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16));
 }
index 64635d7b518c3e9500d08193fc2190ecaa44a407..80e73c7cbac5695c4b1620a9f729d4ca652dad37 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef B43_TABLES_H_
 #define B43_TABLES_H_
 
-#define B43_TAB_ROTOR_SIZE             53
+#define B43_TAB_ROTOR_SIZE     53
 extern const u32 b43_tab_rotor[];
-#define B43_TAB_RETARD_SIZE            53
+#define B43_TAB_RETARD_SIZE    53
 extern const u32 b43_tab_retard[];
 #define B43_TAB_FINEFREQA_SIZE 256
 extern const u16 b43_tab_finefreqa[];
@@ -17,12 +17,18 @@ extern const u16 b43_tab_noisea3[];
 extern const u16 b43_tab_noiseg1[];
 #define B43_TAB_NOISEG2_SIZE   8
 extern const u16 b43_tab_noiseg2[];
-#define B43_TAB_NOISESCALEG_SIZE       27
+#define B43_TAB_NOISESCALE_SIZE        27
+extern const u16 b43_tab_noisescalea2[];
+extern const u16 b43_tab_noisescalea3[];
 extern const u16 b43_tab_noisescaleg1[];
 extern const u16 b43_tab_noisescaleg2[];
 extern const u16 b43_tab_noisescaleg3[];
 #define B43_TAB_SIGMASQR_SIZE  53
 extern const u16 b43_tab_sigmasqr1[];
 extern const u16 b43_tab_sigmasqr2[];
+#define B43_TAB_RSSIAGC1_SIZE  16
+extern const u16 b43_tab_rssiagc1[];
+#define B43_TAB_RSSIAGC2_SIZE  48
+extern const u16 b43_tab_rssiagc2[];
 
 #endif /* B43_TABLES_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
new file mode 100644 (file)
index 0000000..2aa5755
--- /dev/null
@@ -0,0 +1,2476 @@
+/*
+
+  Broadcom B43 wireless driver
+  IEEE 802.11n PHY and radio device data tables
+
+  Copyright (c) 2008 Michael Buesch <mb@bu3sch.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, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "tables_nphy.h"
+#include "phy.h"
+#include "nphy.h"
+
+
+struct b2055_inittab_entry {
+       /* Value to write if we use the 5GHz band. */
+       u16 ghz5;
+       /* Value to write if we use the 2.4GHz band. */
+       u16 ghz2;
+       /* Flags */
+       u8 flags;
+#define B2055_INITTAB_ENTRY_OK 0x01
+#define B2055_INITTAB_UPLOAD   0x02
+};
+#define UPLOAD         .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD
+#define NOUPLOAD       .flags = B2055_INITTAB_ENTRY_OK
+
+static const struct b2055_inittab_entry b2055_inittab [] = {
+  [B2055_SP_PINPD]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C2_SP_RSSI]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_SP_PDMISC]         = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, },
+  [B2055_C1_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C1_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C2_SP_RXGC1]          = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, },
+  [B2055_C2_SP_RXGC2]          = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, },
+  [B2055_C1_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_SP_LPFBWSEL]       = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C1_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_C2_SP_TXGC1]          = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, },
+  [B2055_C2_SP_TXGC2]          = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, },
+  [B2055_MASTER1]              = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, },
+  [B2055_MASTER2]              = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_PD_LGEN]              = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PD_PLLTS]             = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, },
+  [B2055_C1_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_LGBUF]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_TX]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RXTX]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_PD_RSSIMISC]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PWRDET_LGEN]          = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C1_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C1_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_C2_PWRDET_LGBUF]      = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_C2_PWRDET_RXTX]       = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, },
+  [B2055_RRCCAL_CS]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_RRCCAL_NOPTSEL]       = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, },
+  [B2055_CAL_MISC]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_COUT2]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_CVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RVARCTL]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_LPOCTL]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_TS]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCCALRTS]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_CAL_RCALRTS]          = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PADDRV]               = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_XOCTL1]               = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, },
+  [B2055_XOCTL2]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_XOREGUL]              = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_XOMISC]               = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PLL_LFC1]             = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_PLL_CALVTH]           = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, },
+  [B2055_PLL_LFC2]             = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_PLL_REF]              = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, },
+  [B2055_PLL_LFR1]             = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, },
+  [B2055_PLL_PFDCP]            = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, },
+  [B2055_PLL_IDAC_CPOPAMP]     = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_PLL_CPREG]            = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, },
+  [B2055_PLL_RCAL]             = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_RF_PLLMOD0]           = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, },
+  [B2055_RF_PLLMOD1]           = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, },
+  [B2055_RF_MMDIDAC1]          = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, },
+  [B2055_RF_MMDIDAC0]          = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_RF_MMDSP]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL1]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL2]             = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL3]             = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
+  [B2055_VCO_CAL4]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL5]             = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, },
+  [B2055_VCO_CAL6]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL7]             = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, },
+  [B2055_VCO_CAL8]             = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, },
+  [B2055_VCO_CAL9]             = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
+  [B2055_VCO_CAL10]            = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_VCO_CAL11]            = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_VCO_CAL12]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL13]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL14]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL15]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_CAL16]            = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_VCO_KVCO]             = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_CAPTAIL]          = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_VCO_IDACVCO]          = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_VCO_REG]              = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, },
+  [B2055_PLL_RFVTH]            = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, },
+  [B2055_LGBUF_CENBUF]         = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, },
+  [B2055_LGEN_TUNE1]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_TUNE2]           = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, },
+  [B2055_LGEN_IDAC1]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_IDAC2]           = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_LGEN_BIASC]           = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_LGEN_BIASIDAC]                = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, },
+  [B2055_LGEN_RCAL]            = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_LGEN_DIV]             = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_LGEN_SPARE2]          = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, },
+  [B2055_C1_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C1_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C1_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C1_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C1_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C1_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C1_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C1_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C1_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C1_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C1_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C1_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C1_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C1_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C1_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C1_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C1_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C1_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C1_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C1_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C1_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C1_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C1_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_ATUNE]       = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, },
+  [B2055_C2_LGBUF_GTUNE]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_DIV]         = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_AIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, },
+  [B2055_C2_LGBUF_GIDAC]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_LGBUF_IDACFO]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LGBUF_SPARE]       = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, },
+  [B2055_C2_RX_RFSPC1]         = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, },
+  [B2055_C2_RX_RFR1]           = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_RX_RFR2]           = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, },
+  [B2055_C2_RX_RFRCAL]         = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_RX_BB_BLCMP]       = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, },
+  [B2055_C2_RX_BB_LPF]         = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_RX_BB_MIDACHP]     = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_VGA1IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA2IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_VGA3IDAC]    = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_BUFOCTL]     = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_RX_BB_RCCALCTL]    = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL1]    = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL2]    = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL3]    = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL4]    = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, },
+  [B2055_C2_RX_BB_RSSICTL5]    = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, },
+  [B2055_C2_RX_BB_REG]         = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, },
+  [B2055_C2_RX_BB_SPARE1]      = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_RX_TXBBRCAL]       = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPGA]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPAD]                = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPGA1]     = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, },
+  [B2055_C2_TX_RF_CNTPAD1]     = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, },
+  [B2055_C2_TX_RF_PGAIDAC]     = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, },
+  [B2055_C2_TX_PGAPADTN]       = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, },
+  [B2055_C2_TX_PADIDAC1]       = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, },
+  [B2055_C2_TX_PADIDAC2]       = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, },
+  [B2055_C2_TX_MXBGTRIM]       = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [B2055_C2_TX_RF_RCAL]                = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI1]    = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_PADTSSI2]    = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, },
+  [B2055_C2_TX_RF_SPARE]       = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, },
+  [B2055_C2_TX_RF_IQCAL1]      = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, },
+  [B2055_C2_TX_RF_IQCAL2]      = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, },
+  [B2055_C2_TXBB_RCCAL]                = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_TXBB_LPF1]         = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, },
+  [B2055_C2_TX_VOSCNCL]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_TX_LPF_MXGMIDAC]   = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, },
+  [B2055_C2_TX_BB_MXGM]                = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_PRG_GCHP21]           = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, },
+  [B2055_PRG_GCHP22]           = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, },
+  [B2055_PRG_GCHP23]           = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, },
+  [B2055_PRG_GCHP24]           = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, },
+  [B2055_PRG_GCHP25]           = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, },
+  [B2055_PRG_GCHP26]           = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, },
+  [B2055_PRG_GCHP27]           = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
+  [B2055_PRG_GCHP28]           = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, },
+  [B2055_PRG_GCHP29]           = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, },
+  [B2055_PRG_GCHP30]           = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, },
+  [0xC7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xC9]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCE]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xCF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD1]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C1_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xD3]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD4]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD5]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C1_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD7]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xD8]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_LNA_GAINBST]       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDA]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDB]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDC]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xDD]                       = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, },
+  [B2055_C2_B0NB_RSSIVCM]      = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, },
+  [0xDF]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE0]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [0xE1]                       = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+  [B2055_C2_GENSPARE2]         = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, },
+};
+
+
+void b2055_upload_inittab(struct b43_wldev *dev,
+                         bool ghz5, bool ignore_uploadflag)
+{
+       const struct b2055_inittab_entry *e;
+       unsigned int i;
+       u16 value;
+
+       for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) {
+               e = &(b2055_inittab[i]);
+               if (!(e->flags & B2055_INITTAB_ENTRY_OK))
+                       continue;
+               if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) {
+                       if (ghz5)
+                               value = e->ghz5;
+                       else
+                               value = e->ghz2;
+                       b43_radio_write16(dev, i, value);
+               }
+       }
+}
+
+
+#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \
+                 r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \
+       .radio_pll_ref          = r0,   \
+       .radio_rf_pllmod0       = r1,   \
+       .radio_rf_pllmod1       = r2,   \
+       .radio_vco_captail      = r3,   \
+       .radio_vco_cal1         = r4,   \
+       .radio_vco_cal2         = r5,   \
+       .radio_pll_lfc1         = r6,   \
+       .radio_pll_lfr1         = r7,   \
+       .radio_pll_lfc2         = r8,   \
+       .radio_lgbuf_cenbuf     = r9,   \
+       .radio_lgen_tune1       = r10,  \
+       .radio_lgen_tune2       = r11,  \
+       .radio_c1_lgbuf_atune   = r12,  \
+       .radio_c1_lgbuf_gtune   = r13,  \
+       .radio_c1_rx_rfr1       = r14,  \
+       .radio_c1_tx_pgapadtn   = r15,  \
+       .radio_c1_tx_mxbgtrim   = r16,  \
+       .radio_c2_lgbuf_atune   = r17,  \
+       .radio_c2_lgbuf_gtune   = r18,  \
+       .radio_c2_rx_rfr1       = r19,  \
+       .radio_c2_tx_pgapadtn   = r20,  \
+       .radio_c2_tx_mxbgtrim   = r21
+
+#define PHYREGS(r0, r1, r2, r3, r4, r5)        \
+       .phy_bw1a       = r0,           \
+       .phy_bw2        = r1,           \
+       .phy_bw3        = r2,           \
+       .phy_bw4        = r3,           \
+       .phy_bw5        = r4,           \
+       .phy_bw6        = r5
+
+static const struct b43_nphy_channeltab_entry b43_nphy_channeltab[] = {
+  {    .channel                = 184,
+       .freq                   = 4920, /* MHz */
+       .unk2                   = 3280,
+       RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602),
+  },
+  {    .channel                = 186,
+       .freq                   = 4930, /* MHz */
+       .unk2                   = 3287,
+       RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502),
+  },
+  {    .channel                = 188,
+       .freq                   = 4940, /* MHz */
+       .unk2                   = 3293,
+       RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402),
+  },
+  {    .channel                = 190,
+       .freq                   = 4950, /* MHz */
+       .unk2                   = 3300,
+       RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302),
+  },
+  {    .channel                = 192,
+       .freq                   = 4960, /* MHz */
+       .unk2                   = 3307,
+       RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202),
+  },
+  {    .channel                = 194,
+       .freq                   = 4970, /* MHz */
+       .unk2                   = 3313,
+       RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102),
+  },
+  {    .channel                = 196,
+       .freq                   = 4980, /* MHz */
+       .unk2                   = 3320,
+       RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02),
+  },
+  {    .channel                = 198,
+       .freq                   = 4990, /* MHz */
+       .unk2                   = 3327,
+       RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02),
+  },
+  {    .channel                = 200,
+       .freq                   = 5000, /* MHz */
+       .unk2                   = 3333,
+       RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02),
+  },
+  {    .channel                = 202,
+       .freq                   = 5010, /* MHz */
+       .unk2                   = 3340,
+       RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02),
+  },
+  {    .channel                = 204,
+       .freq                   = 5020, /* MHz */
+       .unk2                   = 3347,
+       RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02),
+  },
+  {    .channel                = 206,
+       .freq                   = 5030, /* MHz */
+       .unk2                   = 3353,
+       RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02),
+  },
+  {    .channel                = 208,
+       .freq                   = 5040, /* MHz */
+       .unk2                   = 3360,
+       RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902),
+  },
+  {    .channel                = 210,
+       .freq                   = 5050, /* MHz */
+       .unk2                   = 3367,
+       RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F,
+                 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F),
+       PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802),
+  },
+  {    .channel                = 212,
+       .freq                   = 5060, /* MHz */
+       .unk2                   = 3373,
+       RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+       PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702),
+  },
+  {    .channel                = 214,
+       .freq                   = 5070, /* MHz */
+       .unk2                   = 3380,
+       RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F,
+                 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E),
+       PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602),
+  },
+  {    .channel                = 216,
+       .freq                   = 5080, /* MHz */
+       .unk2                   = 3387,
+       RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+       PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502),
+  },
+  {    .channel                = 218,
+       .freq                   = 5090, /* MHz */
+       .unk2                   = 3393,
+       RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D),
+       PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402),
+  },
+  {    .channel                = 220,
+       .freq                   = 5100, /* MHz */
+       .unk2                   = 3400,
+       RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+       PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302),
+  },
+  {    .channel                = 222,
+       .freq                   = 5110, /* MHz */
+       .unk2                   = 3407,
+       RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F,
+                 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D),
+       PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202),
+  },
+  {    .channel                = 224,
+       .freq                   = 5120, /* MHz */
+       .unk2                   = 3413,
+       RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+       PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102),
+  },
+  {    .channel                = 226,
+       .freq                   = 5130, /* MHz */
+       .unk2                   = 3420,
+       RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F,
+                 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C),
+       PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002),
+  },
+  {    .channel                = 228,
+       .freq                   = 5140, /* MHz */
+       .unk2                   = 3427,
+       RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E,
+                 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B),
+       PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01),
+  },
+  {    .channel                = 32,
+       .freq                   = 5160, /* MHz */
+       .unk2                   = 3440,
+       RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+       PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01),
+  },
+  {    .channel                = 34,
+       .freq                   = 5170, /* MHz */
+       .unk2                   = 3447,
+       RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D,
+                 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A),
+       PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01),
+  },
+  {    .channel                = 36,
+       .freq                   = 5180, /* MHz */
+       .unk2                   = 3453,
+       RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+       PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01),
+  },
+  {    .channel                = 38,
+       .freq                   = 5190, /* MHz */
+       .unk2                   = 3460,
+       RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A,
+                 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C,
+                 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89),
+       PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01),
+  },
+  {    .channel                = 40,
+       .freq                   = 5200, /* MHz */
+       .unk2                   = 3467,
+       RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+       PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901),
+  },
+  {    .channel                = 42,
+       .freq                   = 5210, /* MHz */
+       .unk2                   = 3473,
+       RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B,
+                 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89),
+       PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801),
+  },
+  {    .channel                = 44,
+       .freq                   = 5220, /* MHz */
+       .unk2                   = 3480,
+       RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+       PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701),
+  },
+  {    .channel                = 46,
+       .freq                   = 5230, /* MHz */
+       .unk2                   = 3487,
+       RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A,
+                 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A,
+                 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88),
+       PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601),
+  },
+  {    .channel                = 48,
+       .freq                   = 5240, /* MHz */
+       .unk2                   = 3493,
+       RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+       PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501),
+  },
+  {    .channel                = 50,
+       .freq                   = 5250, /* MHz */
+       .unk2                   = 3500,
+       RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A,
+                 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87),
+       PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401),
+  },
+  {    .channel                = 52,
+       .freq                   = 5260, /* MHz */
+       .unk2                   = 3507,
+       RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+       PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301),
+  },
+  {    .channel                = 54,
+       .freq                   = 5270, /* MHz */
+       .unk2                   = 3513,
+       RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A,
+                 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09,
+                 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87),
+       PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201),
+  },
+  {    .channel                = 56,
+       .freq                   = 5280, /* MHz */
+       .unk2                   = 3520,
+       RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+       PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101),
+  },
+  {    .channel                = 58,
+       .freq                   = 5290, /* MHz */
+       .unk2                   = 3527,
+       RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08,
+                 0x86, 0x99, 0x00, 0x08, 0x08, 0x86),
+       PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001),
+  },
+  {    .channel                = 60,
+       .freq                   = 5300, /* MHz */
+       .unk2                   = 3533,
+       RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+       PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001),
+  },
+  {    .channel                = 62,
+       .freq                   = 5310, /* MHz */
+       .unk2                   = 3540,
+       RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A,
+                 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07,
+                 0x85, 0x99, 0x00, 0x08, 0x07, 0x85),
+       PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01),
+  },
+  {    .channel                = 64,
+       .freq                   = 5320, /* MHz */
+       .unk2                   = 3547,
+       RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+       PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01),
+  },
+  {    .channel                = 66,
+       .freq                   = 5330, /* MHz */
+       .unk2                   = 3553,
+       RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07,
+                 0x84, 0x88, 0x00, 0x07, 0x07, 0x84),
+       PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01),
+  },
+  {    .channel                = 68,
+       .freq                   = 5340, /* MHz */
+       .unk2                   = 3560,
+       RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+       PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01),
+  },
+  {    .channel                = 70,
+       .freq                   = 5350, /* MHz */
+       .unk2                   = 3567,
+       RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A,
+                 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06,
+                 0x84, 0x88, 0x00, 0x07, 0x06, 0x84),
+       PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01),
+  },
+  {    .channel                = 72,
+       .freq                   = 5360, /* MHz */
+       .unk2                   = 3573,
+       RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+       PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01),
+  },
+  {    .channel                = 74,
+       .freq                   = 5370, /* MHz */
+       .unk2                   = 3580,
+       RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05,
+                 0x83, 0x77, 0x00, 0x06, 0x05, 0x83),
+       PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901),
+  },
+  {    .channel                = 76,
+       .freq                   = 5380, /* MHz */
+       .unk2                   = 3587,
+       RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+       PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801),
+  },
+  {    .channel                = 78,
+       .freq                   = 5390, /* MHz */
+       .unk2                   = 3593,
+       RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A,
+                 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04,
+                 0x82, 0x77, 0x00, 0x06, 0x04, 0x82),
+       PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701),
+  },
+  {    .channel                = 80,
+       .freq                   = 5400, /* MHz */
+       .unk2                   = 3600,
+       RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+       PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601),
+  },
+  {    .channel                = 82,
+       .freq                   = 5410, /* MHz */
+       .unk2                   = 3607,
+       RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04,
+                 0x81, 0x66, 0x00, 0x05, 0x04, 0x81),
+       PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501),
+  },
+  {    .channel                = 84,
+       .freq                   = 5420, /* MHz */
+       .unk2                   = 3613,
+       RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+       PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501),
+  },
+  {    .channel                = 86,
+       .freq                   = 5430, /* MHz */
+       .unk2                   = 3620,
+       RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A,
+                 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03,
+                 0x80, 0x66, 0x00, 0x05, 0x03, 0x80),
+       PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401),
+  },
+  {    .channel                = 88,
+       .freq                   = 5440, /* MHz */
+       .unk2                   = 3627,
+       RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+       PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301),
+  },
+  {    .channel                = 90,
+       .freq                   = 5450, /* MHz */
+       .unk2                   = 3633,
+       RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02,
+                 0x80, 0x55, 0x00, 0x04, 0x02, 0x80),
+       PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201),
+  },
+  {    .channel                = 92,
+       .freq                   = 5460, /* MHz */
+       .unk2                   = 3640,
+       RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+       PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101),
+  },
+  {    .channel                = 94,
+       .freq                   = 5470, /* MHz */
+       .unk2                   = 3647,
+       RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A,
+                 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01,
+                 0x80, 0x55, 0x00, 0x04, 0x01, 0x80),
+       PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001),
+  },
+  {    .channel                = 96,
+       .freq                   = 5480, /* MHz */
+       .unk2                   = 3653,
+       RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01),
+  },
+  {    .channel                = 98,
+       .freq                   = 5490, /* MHz */
+       .unk2                   = 3660,
+       RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01),
+  },
+  {    .channel                = 100,
+       .freq                   = 5500, /* MHz */
+       .unk2                   = 3667,
+       RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01),
+  },
+  {    .channel                = 102,
+       .freq                   = 5510, /* MHz */
+       .unk2                   = 3673,
+       RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A,
+                 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00,
+                 0x80, 0x44, 0x00, 0x03, 0x00, 0x80),
+       PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01),
+  },
+  {    .channel                = 104,
+       .freq                   = 5520, /* MHz */
+       .unk2                   = 3680,
+       RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01),
+  },
+  {    .channel                = 106,
+       .freq                   = 5530, /* MHz */
+       .unk2                   = 3687,
+       RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01),
+  },
+  {    .channel                = 108,
+       .freq                   = 5540, /* MHz */
+       .unk2                   = 3693,
+       RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01),
+  },
+  {    .channel                = 110,
+       .freq                   = 5550, /* MHz */
+       .unk2                   = 3700,
+       RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A,
+                 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00,
+                 0x80, 0x33, 0x00, 0x02, 0x00, 0x80),
+       PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901),
+  },
+  {    .channel                = 112,
+       .freq                   = 5560, /* MHz */
+       .unk2                   = 3707,
+       RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801),
+  },
+  {    .channel                = 114,
+       .freq                   = 5570, /* MHz */
+       .unk2                   = 3713,
+       RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701),
+  },
+  {    .channel                = 116,
+       .freq                   = 5580, /* MHz */
+       .unk2                   = 3720,
+       RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701),
+  },
+  {    .channel                = 118,
+       .freq                   = 5590, /* MHz */
+       .unk2                   = 3727,
+       RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A,
+                 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00,
+                 0x80, 0x22, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601),
+  },
+  {    .channel                = 120,
+       .freq                   = 5600, /* MHz */
+       .unk2                   = 3733,
+       RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501),
+  },
+  {    .channel                = 122,
+       .freq                   = 5610, /* MHz */
+       .unk2                   = 3740,
+       RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00,
+                 0x80, 0x11, 0x00, 0x01, 0x00, 0x80),
+       PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401),
+  },
+  {    .channel                = 124,
+       .freq                   = 5620, /* MHz */
+       .unk2                   = 3747,
+       RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301),
+  },
+  {    .channel                = 126,
+       .freq                   = 5630, /* MHz */
+       .unk2                   = 3753,
+       RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A,
+                 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
+                 0x80, 0x11, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201),
+  },
+  {    .channel                = 128,
+       .freq                   = 5640, /* MHz */
+       .unk2                   = 3760,
+       RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201),
+  },
+  {    .channel                = 130,
+       .freq                   = 5650, /* MHz */
+       .unk2                   = 3767,
+       RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101),
+  },
+  {    .channel                = 132,
+       .freq                   = 5660, /* MHz */
+       .unk2                   = 3773,
+       RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001),
+  },
+  {    .channel                = 134,
+       .freq                   = 5670, /* MHz */
+       .unk2                   = 3780,
+       RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01),
+  },
+  {    .channel                = 136,
+       .freq                   = 5680, /* MHz */
+       .unk2                   = 3787,
+       RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01),
+  },
+  {    .channel                = 138,
+       .freq                   = 5690, /* MHz */
+       .unk2                   = 3793,
+       RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01),
+  },
+  {    .channel                = 140,
+       .freq                   = 5700, /* MHz */
+       .unk2                   = 3800,
+       RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01),
+  },
+  {    .channel                = 142,
+       .freq                   = 5710, /* MHz */
+       .unk2                   = 3807,
+       RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01),
+  },
+  {    .channel                = 144,
+       .freq                   = 5720, /* MHz */
+       .unk2                   = 3813,
+       RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {    .channel                = 145,
+       .freq                   = 5725, /* MHz */
+       .unk2                   = 3817,
+       RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01),
+  },
+  {    .channel                = 146,
+       .freq                   = 5730, /* MHz */
+       .unk2                   = 3820,
+       RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01),
+  },
+  {    .channel                = 147,
+       .freq                   = 5735, /* MHz */
+       .unk2                   = 3823,
+       RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01),
+  },
+  {    .channel                = 148,
+       .freq                   = 5740, /* MHz */
+       .unk2                   = 3827,
+       RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901),
+  },
+  {    .channel                = 149,
+       .freq                   = 5745, /* MHz */
+       .unk2                   = 3830,
+       RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901),
+  },
+  {    .channel                = 150,
+       .freq                   = 5750, /* MHz */
+       .unk2                   = 3833,
+       RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901),
+  },
+  {    .channel                = 151,
+       .freq                   = 5755, /* MHz */
+       .unk2                   = 3837,
+       RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801),
+  },
+  {    .channel                = 152,
+       .freq                   = 5760, /* MHz */
+       .unk2                   = 3840,
+       RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801),
+  },
+  {    .channel                = 153,
+       .freq                   = 5765, /* MHz */
+       .unk2                   = 3843,
+       RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801),
+  },
+  {    .channel                = 154,
+       .freq                   = 5770, /* MHz */
+       .unk2                   = 3847,
+       RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701),
+  },
+  {    .channel                = 155,
+       .freq                   = 5775, /* MHz */
+       .unk2                   = 3850,
+       RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701),
+  },
+  {    .channel                = 156,
+       .freq                   = 5780, /* MHz */
+       .unk2                   = 3853,
+       RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601),
+  },
+  {    .channel                = 157,
+       .freq                   = 5785, /* MHz */
+       .unk2                   = 3857,
+       RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601),
+  },
+  {    .channel                = 158,
+       .freq                   = 5790, /* MHz */
+       .unk2                   = 3860,
+       RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601),
+  },
+  {    .channel                = 159,
+       .freq                   = 5795, /* MHz */
+       .unk2                   = 3863,
+       RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501),
+  },
+  {    .channel                = 160,
+       .freq                   = 5800, /* MHz */
+       .unk2                   = 3867,
+       RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501),
+  },
+  {    .channel                = 161,
+       .freq                   = 5805, /* MHz */
+       .unk2                   = 3870,
+       RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401),
+  },
+  {    .channel                = 162,
+       .freq                   = 5810, /* MHz */
+       .unk2                   = 3873,
+       RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401),
+  },
+  {    .channel                = 163,
+       .freq                   = 5815, /* MHz */
+       .unk2                   = 3877,
+       RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401),
+  },
+  {    .channel                = 164,
+       .freq                   = 5820, /* MHz */
+       .unk2                   = 3880,
+       RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301),
+  },
+  {    .channel                = 165,
+       .freq                   = 5825, /* MHz */
+       .unk2                   = 3883,
+       RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301),
+  },
+  {    .channel                = 166,
+       .freq                   = 5830, /* MHz */
+       .unk2                   = 3887,
+       RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201),
+  },
+  {    .channel                = 168,
+       .freq                   = 5840, /* MHz */
+       .unk2                   = 3893,
+       RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201),
+  },
+  {    .channel                = 170,
+       .freq                   = 5850, /* MHz */
+       .unk2                   = 3900,
+       RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101),
+  },
+  {    .channel                = 172,
+       .freq                   = 5860, /* MHz */
+       .unk2                   = 3907,
+       RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001),
+  },
+  {    .channel                = 174,
+       .freq                   = 5870, /* MHz */
+       .unk2                   = 3913,
+       RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01),
+  },
+  {    .channel                = 176,
+       .freq                   = 5880, /* MHz */
+       .unk2                   = 3920,
+       RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01),
+  },
+  {    .channel                = 178,
+       .freq                   = 5890, /* MHz */
+       .unk2                   = 3927,
+       RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01),
+  },
+  {    .channel                = 180,
+       .freq                   = 5900, /* MHz */
+       .unk2                   = 3933,
+       RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01),
+  },
+  {    .channel                = 182,
+       .freq                   = 5910, /* MHz */
+       .unk2                   = 3940,
+       RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A,
+                 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0x80, 0x00, 0x00, 0x00, 0x00, 0x80),
+       PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01),
+  },
+  {    .channel                = 1,
+       .freq                   = 2412, /* MHz */
+       .unk2                   = 3216,
+       RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C,
+                 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80),
+       PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304),
+  },
+  {    .channel                = 2,
+       .freq                   = 2417, /* MHz */
+       .unk2                   = 3223,
+       RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80),
+       PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104),
+  },
+  {    .channel                = 3,
+       .freq                   = 2422, /* MHz */
+       .unk2                   = 3229,
+       RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+       PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04),
+  },
+  {    .channel                = 4,
+       .freq                   = 2427, /* MHz */
+       .unk2                   = 3236,
+       RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A,
+                 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80),
+       PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04),
+  },
+  {    .channel                = 5,
+       .freq                   = 2432, /* MHz */
+       .unk2                   = 3243,
+       RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09,
+                 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80),
+       PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04),
+  },
+  {    .channel                = 6,
+       .freq                   = 2437, /* MHz */
+       .unk2                   = 3249,
+       RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08,
+                 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80),
+       PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804),
+  },
+  {    .channel                = 7,
+       .freq                   = 2442, /* MHz */
+       .unk2                   = 3256,
+       RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07,
+                 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80),
+       PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604),
+  },
+  {    .channel                = 8,
+       .freq                   = 2447, /* MHz */
+       .unk2                   = 3263,
+       RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06,
+                 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80),
+       PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404),
+  },
+  {    .channel                = 9,
+       .freq                   = 2452, /* MHz */
+       .unk2                   = 3269,
+       RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06,
+                 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80),
+       PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104),
+  },
+  {    .channel                = 10,
+       .freq                   = 2457, /* MHz */
+       .unk2                   = 3276,
+       RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05,
+                 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80),
+       PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04),
+  },
+  {    .channel                = 11,
+       .freq                   = 2462, /* MHz */
+       .unk2                   = 3283,
+       RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04,
+                 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80),
+       PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04),
+  },
+  {    .channel                = 12,
+       .freq                   = 2467, /* MHz */
+       .unk2                   = 3289,
+       RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03,
+                 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80),
+       PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04),
+  },
+  {    .channel                = 13,
+       .freq                   = 2472, /* MHz */
+       .unk2                   = 3296,
+       RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03,
+                 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80),
+       PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904),
+  },
+  {    .channel                = 14,
+       .freq                   = 2484, /* MHz */
+       .unk2                   = 3312,
+       RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15,
+                 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01,
+                 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80),
+       PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404),
+  },
+};
+
+const struct b43_nphy_channeltab_entry *
+b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel)
+{
+       const struct b43_nphy_channeltab_entry *e;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) {
+               e = &(b43_nphy_channeltab[i]);
+               if (e->channel == channel)
+                       return e;
+       }
+
+       return NULL;
+}
+
+
+const u8 b43_ntab_adjustpower0[] = {
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+       0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
+       0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
+       0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
+       0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
+       0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
+       0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
+       0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
+       0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
+       0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
+       0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
+       0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
+       0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
+       0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
+       0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+};
+
+const u8 b43_ntab_adjustpower1[] = {
+       0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+       0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
+       0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
+       0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
+       0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
+       0x0A, 0x0A, 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0B,
+       0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
+       0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
+       0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
+       0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
+       0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
+       0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
+       0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
+       0x1A, 0x1A, 0x1A, 0x1A, 0x1B, 0x1B, 0x1B, 0x1B,
+       0x1C, 0x1C, 0x1C, 0x1C, 0x1D, 0x1D, 0x1D, 0x1D,
+       0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
+};
+
+const u16 b43_ntab_bdi[] = {
+       0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2,
+};
+
+const u32 b43_ntab_channelest[] = {
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x44444444, 0x44444444, 0x44444444, 0x44444444,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+       0x10101010, 0x10101010, 0x10101010, 0x10101010,
+};
+
+const u8 b43_ntab_estimatepowerlt0[] = {
+       0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
+       0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
+       0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
+       0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
+       0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29,
+       0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21,
+       0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
+       0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
+};
+
+const u8 b43_ntab_estimatepowerlt1[] = {
+       0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
+       0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
+       0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
+       0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
+       0x30, 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29,
+       0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21,
+       0x20, 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19,
+       0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
+};
+
+const u8 b43_ntab_framelookup[] = {
+       0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16,
+       0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E,
+       0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A,
+       0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A,
+};
+
+const u32 b43_ntab_framestruct[] = {
+       0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
+       0x09804506, 0x00100030, 0x09804507, 0x00100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004A0C, 0x00100008, 0x01000A0D, 0x00100028,
+       0x0980450E, 0x00100038, 0x0980450F, 0x00100038,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000A04, 0x00100000, 0x11008A05, 0x00100020,
+       0x1980C506, 0x00100030, 0x21810506, 0x00100030,
+       0x21810506, 0x00100030, 0x01800504, 0x00100030,
+       0x11808505, 0x00100030, 0x29814507, 0x01100030,
+       0x00000A04, 0x00100000, 0x11008A05, 0x00100020,
+       0x21810506, 0x00100030, 0x21810506, 0x00100030,
+       0x29814507, 0x01100030, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
+       0x1980C50E, 0x00100038, 0x2181050E, 0x00100038,
+       0x2181050E, 0x00100038, 0x0180050C, 0x00100038,
+       0x1180850D, 0x00100038, 0x2981450F, 0x01100038,
+       0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
+       0x2181050E, 0x00100038, 0x2181050E, 0x00100038,
+       0x2981450F, 0x01100038, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
+       0x1980C506, 0x00100030, 0x1980C506, 0x00100030,
+       0x11808504, 0x00100030, 0x3981CA05, 0x00100030,
+       0x29814507, 0x01100030, 0x00000000, 0x00000000,
+       0x10008A04, 0x00100000, 0x3981CA05, 0x00100030,
+       0x1980C506, 0x00100030, 0x29814507, 0x01100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004A0C, 0x00100008, 0x01000A0D, 0x00100028,
+       0x1980C50E, 0x00100038, 0x1980C50E, 0x00100038,
+       0x1180850C, 0x00100038, 0x3981CA0D, 0x00100038,
+       0x2981450F, 0x01100038, 0x00000000, 0x00000000,
+       0x10008A0C, 0x00100008, 0x3981CA0D, 0x00100038,
+       0x1980C50E, 0x00100038, 0x2981450F, 0x01100038,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x02001405, 0x00100040,
+       0x0B004A06, 0x01900060, 0x13008A06, 0x01900060,
+       0x13008A06, 0x01900060, 0x43020A04, 0x00100060,
+       0x1B00CA05, 0x00100060, 0x23010A07, 0x01500060,
+       0x40021404, 0x00100000, 0x1A00D405, 0x00100040,
+       0x13008A06, 0x01900060, 0x13008A06, 0x01900060,
+       0x23010A07, 0x01500060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x00100010, 0x0200140D, 0x00100050,
+       0x0B004A0E, 0x01900070, 0x13008A0E, 0x01900070,
+       0x13008A0E, 0x01900070, 0x43020A0C, 0x00100070,
+       0x1B00CA0D, 0x00100070, 0x23010A0F, 0x01500070,
+       0x4002140C, 0x00100010, 0x1A00D40D, 0x00100050,
+       0x13008A0E, 0x01900070, 0x13008A0E, 0x01900070,
+       0x23010A0F, 0x01500070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x50029404, 0x00100000, 0x32019405, 0x00100040,
+       0x0B004A06, 0x01900060, 0x0B004A06, 0x01900060,
+       0x5B02CA04, 0x00100060, 0x3B01D405, 0x00100060,
+       0x23010A07, 0x01500060, 0x00000000, 0x00000000,
+       0x5802D404, 0x00100000, 0x3B01D405, 0x00100060,
+       0x0B004A06, 0x01900060, 0x23010A07, 0x01500060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x5002940C, 0x00100010, 0x3201940D, 0x00100050,
+       0x0B004A0E, 0x01900070, 0x0B004A0E, 0x01900070,
+       0x5B02CA0C, 0x00100070, 0x3B01D40D, 0x00100070,
+       0x23010A0F, 0x01500070, 0x00000000, 0x00000000,
+       0x5802D40C, 0x00100010, 0x3B01D40D, 0x00100070,
+       0x0B004A0E, 0x01900070, 0x23010A0F, 0x01500070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x000F4800, 0x62031405, 0x00100040,
+       0x53028A06, 0x01900060, 0x53028A07, 0x01900060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x000F4810, 0x6203140D, 0x00100050,
+       0x53028A0E, 0x01900070, 0x53028A0F, 0x01900070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
+       0x1980C50E, 0x00100038, 0x2181050E, 0x00100038,
+       0x2181050E, 0x00100038, 0x0180050C, 0x00100038,
+       0x1180850D, 0x00100038, 0x1181850D, 0x00100038,
+       0x2981450F, 0x01100038, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000A0C, 0x00100008, 0x11008A0D, 0x00100028,
+       0x2181050E, 0x00100038, 0x2181050E, 0x00100038,
+       0x1181850D, 0x00100038, 0x2981450F, 0x01100038,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
+       0x0180C506, 0x00100030, 0x0180C506, 0x00100030,
+       0x2180C50C, 0x00100030, 0x49820A0D, 0x0016A130,
+       0x41824A0D, 0x0016A130, 0x2981450F, 0x01100030,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x2000CA0C, 0x00100000, 0x49820A0D, 0x0016A130,
+       0x1980C50E, 0x00100030, 0x41824A0D, 0x0016A130,
+       0x2981450F, 0x01100030, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x00100010, 0x0200140D, 0x00100050,
+       0x0B004A0E, 0x01900070, 0x13008A0E, 0x01900070,
+       0x13008A0E, 0x01900070, 0x43020A0C, 0x00100070,
+       0x1B00CA0D, 0x00100070, 0x1B014A0D, 0x00100070,
+       0x23010A0F, 0x01500070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x00100010, 0x1A00D40D, 0x00100050,
+       0x13008A0E, 0x01900070, 0x13008A0E, 0x01900070,
+       0x1B014A0D, 0x00100070, 0x23010A0F, 0x01500070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x50029404, 0x00100000, 0x32019405, 0x00100040,
+       0x03004A06, 0x01900060, 0x03004A06, 0x01900060,
+       0x6B030A0C, 0x00100060, 0x4B02140D, 0x0016A160,
+       0x4302540D, 0x0016A160, 0x23010A0F, 0x01500060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x6B03140C, 0x00100060, 0x4B02140D, 0x0016A160,
+       0x0B004A0E, 0x01900060, 0x4302540D, 0x0016A160,
+       0x23010A0F, 0x01500060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x1A00D405, 0x00100040,
+       0x53028A06, 0x01900060, 0x5B02CA06, 0x01900060,
+       0x5B02CA06, 0x01900060, 0x43020A04, 0x00100060,
+       0x1B00CA05, 0x00100060, 0x53028A07, 0x0190C060,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x00100010, 0x1A00D40D, 0x00100050,
+       0x53028A0E, 0x01900070, 0x5B02CA0E, 0x01900070,
+       0x5B02CA0E, 0x01900070, 0x43020A0C, 0x00100070,
+       0x1B00CA0D, 0x00100070, 0x53028A0F, 0x0190C070,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x40021404, 0x00100000, 0x1A00D405, 0x00100040,
+       0x5B02CA06, 0x01900060, 0x5B02CA06, 0x01900060,
+       0x53028A07, 0x0190C060, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x4002140C, 0x00100010, 0x1A00D40D, 0x00100050,
+       0x5B02CA0E, 0x01900070, 0x5B02CA0E, 0x01900070,
+       0x53028A0F, 0x0190C070, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+const u32 b43_ntab_gainctl0[] = {
+       0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
+       0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
+       0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
+       0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
+       0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
+       0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
+       0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
+       0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
+       0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
+       0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
+       0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
+       0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
+       0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
+       0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
+       0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
+       0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
+       0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
+       0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
+       0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
+       0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
+       0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
+       0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
+       0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
+       0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
+       0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
+       0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
+       0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
+       0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
+       0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
+       0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
+       0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
+       0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+};
+
+const u32 b43_ntab_gainctl1[] = {
+       0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
+       0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
+       0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
+       0x00730C39, 0x00720D39, 0x00710E38, 0x00700F38,
+       0x006F0037, 0x006E0137, 0x006D0236, 0x006C0336,
+       0x006B0435, 0x006A0535, 0x00690634, 0x00680734,
+       0x00670833, 0x00660933, 0x00650A32, 0x00640B32,
+       0x00630C31, 0x00620D31, 0x00610E30, 0x00600F30,
+       0x005F002F, 0x005E012F, 0x005D022E, 0x005C032E,
+       0x005B042D, 0x005A052D, 0x0059062C, 0x0058072C,
+       0x0057082B, 0x0056092B, 0x00550A2A, 0x00540B2A,
+       0x00530C29, 0x00520D29, 0x00510E28, 0x00500F28,
+       0x004F0027, 0x004E0127, 0x004D0226, 0x004C0326,
+       0x004B0425, 0x004A0525, 0x00490624, 0x00480724,
+       0x00470823, 0x00460923, 0x00450A22, 0x00440B22,
+       0x00430C21, 0x00420D21, 0x00410E20, 0x00400F20,
+       0x003F001F, 0x003E011F, 0x003D021E, 0x003C031E,
+       0x003B041D, 0x003A051D, 0x0039061C, 0x0038071C,
+       0x0037081B, 0x0036091B, 0x00350A1A, 0x00340B1A,
+       0x00330C19, 0x00320D19, 0x00310E18, 0x00300F18,
+       0x002F0017, 0x002E0117, 0x002D0216, 0x002C0316,
+       0x002B0415, 0x002A0515, 0x00290614, 0x00280714,
+       0x00270813, 0x00260913, 0x00250A12, 0x00240B12,
+       0x00230C11, 0x00220D11, 0x00210E10, 0x00200F10,
+       0x001F000F, 0x001E010F, 0x001D020E, 0x001C030E,
+       0x001B040D, 0x001A050D, 0x0019060C, 0x0018070C,
+       0x0017080B, 0x0016090B, 0x00150A0A, 0x00140B0A,
+       0x00130C09, 0x00120D09, 0x00110E08, 0x00100F08,
+       0x000F0007, 0x000E0107, 0x000D0206, 0x000C0306,
+       0x000B0405, 0x000A0505, 0x00090604, 0x00080704,
+       0x00070803, 0x00060903, 0x00050A02, 0x00040B02,
+       0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
+};
+
+const u32 b43_ntab_intlevel[] = {
+       0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46,
+       0x00C1188D, 0x080024D2, 0x00000070,
+};
+
+const u32 b43_ntab_iqlt0[] = {
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+};
+
+const u32 b43_ntab_iqlt1[] = {
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+       0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
+};
+
+const u16 b43_ntab_loftlt0[] = {
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103,
+};
+
+const u16 b43_ntab_loftlt1[] = {
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
+       0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
+       0x0002, 0x0103,
+};
+
+const u8 b43_ntab_mcs[] = {
+       0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C,
+       0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C,
+       0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C,
+       0xC0, 0xC8, 0xCA, 0xD0, 0xD2, 0xD9, 0xDA, 0xDC,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x01, 0x02, 0x04, 0x08, 0x09, 0x0A, 0x0C,
+       0x10, 0x11, 0x12, 0x14, 0x18, 0x19, 0x1A, 0x1C,
+       0x20, 0x21, 0x22, 0x24, 0x40, 0x41, 0x42, 0x44,
+       0x48, 0x49, 0x4A, 0x4C, 0x50, 0x51, 0x52, 0x54,
+       0x58, 0x59, 0x5A, 0x5C, 0x60, 0x61, 0x62, 0x64,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const u32 b43_ntab_noisevar10[] = {
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+};
+
+const u32 b43_ntab_noisevar11[] = {
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+       0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
+};
+
+const u16 b43_ntab_pilot[] = {
+       0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08,
+       0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5,
+       0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82,
+       0xFFA0, 0xFF28, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+       0xFF82, 0xFFA0, 0xFF28, 0xFF0A, 0xFFFF, 0xFFFF,
+       0xFFFF, 0xFFFF, 0xF83F, 0xFA1F, 0xFA97, 0xFAB5,
+       0xF2BD, 0xF0BF, 0xFFFF, 0xFFFF, 0xF017, 0xF815,
+       0xF215, 0xF095, 0xF035, 0xF01D, 0xFFFF, 0xFFFF,
+       0xFF08, 0xFF02, 0xFF80, 0xFF20, 0xFF08, 0xFF02,
+       0xFF80, 0xFF20, 0xF01F, 0xF817, 0xFA15, 0xF295,
+       0xF0B5, 0xF03D, 0xFFFF, 0xFFFF, 0xF82A, 0xFA0A,
+       0xFA82, 0xFAA0, 0xF2A8, 0xF0AA, 0xFFFF, 0xFFFF,
+       0xF002, 0xF800, 0xF200, 0xF080, 0xF020, 0xF008,
+       0xFFFF, 0xFFFF, 0xF00A, 0xF802, 0xFA00, 0xF280,
+       0xF0A0, 0xF028, 0xFFFF, 0xFFFF,
+};
+
+const u32 b43_ntab_pilotlt[] = {
+       0x76540123, 0x62407351, 0x76543201, 0x76540213,
+       0x76540123, 0x76430521,
+};
+
+const u32 b43_ntab_tdi20a0[] = {
+       0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0,
+       0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D,
+       0x00020301, 0x00030504, 0x00040708, 0x0005090B,
+       0x00064B8E, 0x00095291, 0x000A5494, 0x000B9718,
+       0x000C9927, 0x000D9B2A, 0x000EDD2E, 0x000FDF31,
+       0x000101B4, 0x000243B7, 0x000345BB, 0x000447BE,
+       0x00058982, 0x00068C05, 0x00099309, 0x000A950C,
+       0x000BD78F, 0x000CD992, 0x000DDB96, 0x000F1D99,
+       0x00005FA8, 0x0001422C, 0x0002842F, 0x00038632,
+       0x00048835, 0x0005CA38, 0x0006CCBC, 0x0009D3BF,
+       0x000B1603, 0x000C1806, 0x000D1A0A, 0x000E1C0D,
+       0x000F5E10, 0x00008093, 0x00018297, 0x0002C49A,
+       0x0003C680, 0x0004C880, 0x00060B00, 0x00070D00,
+       0x00000000, 0x00000000, 0x00000000,
+};
+
+const u32 b43_ntab_tdi20a1[] = {
+       0x00014B26, 0x00028D29, 0x000393AD, 0x00049630,
+       0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D,
+       0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B,
+       0x0000488E, 0x00018B91, 0x0002D214, 0x0003D418,
+       0x0004D6A7, 0x000618AA, 0x00071AAE, 0x0009DCB1,
+       0x000B1EB4, 0x000C0137, 0x000D033B, 0x000E053E,
+       0x000F4702, 0x00008905, 0x00020C09, 0x0003128C,
+       0x0004148F, 0x00051712, 0x00065916, 0x00091B19,
+       0x000A1D28, 0x000B5F2C, 0x000C41AF, 0x000D43B2,
+       0x000E85B5, 0x000F87B8, 0x0000C9BC, 0x00024CBF,
+       0x00035303, 0x00045506, 0x0005978A, 0x0006998D,
+       0x00095B90, 0x000A5D93, 0x000B9F97, 0x000C821A,
+       0x000D8400, 0x000EC600, 0x000FC800, 0x00010A00,
+       0x00000000, 0x00000000, 0x00000000,
+};
+
+const u32 b43_ntab_tdi40a0[] = {
+       0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2,
+       0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C,
+       0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2,
+       0x00056447, 0x00072DD0, 0x0008B6DA, 0x000A02E3,
+       0x000B8C6C, 0x000D15F6, 0x0011E484, 0x0013AE0D,
+       0x00153717, 0x00168320, 0x00180CA9, 0x00199633,
+       0x001B6548, 0x001CEED1, 0x001EB7DB, 0x0000C3E4,
+       0x00024D6D, 0x000416F7, 0x0005A585, 0x00076F0F,
+       0x0008F818, 0x000A4421, 0x000BCDAB, 0x000D9734,
+       0x00122649, 0x0013EFD2, 0x001578DC, 0x0016C4E5,
+       0x00184E6E, 0x001A17F8, 0x001BA686, 0x001D3010,
+       0x001EF999, 0x00010522, 0x00028EAC, 0x00045835,
+       0x0005E74A, 0x0007B0D3, 0x00093A5D, 0x000A85E6,
+       0x000C0F6F, 0x000DD8F9, 0x00126787, 0x00143111,
+       0x0015BA9A, 0x00170623, 0x00188FAD, 0x001A5936,
+       0x001BE84B, 0x001DB1D4, 0x001F3B5E, 0x000146E7,
+       0x00031070, 0x000499FA, 0x00062888, 0x0007F212,
+       0x00097B9B, 0x000AC7A4, 0x000C50AE, 0x000E1A37,
+       0x0012A94C, 0x001472D5, 0x0015FC5F, 0x00174868,
+       0x0018D171, 0x001A9AFB, 0x001C2989, 0x001DF313,
+       0x001F7C9C, 0x000188A5, 0x000351AF, 0x0004DB38,
+       0x0006AA4D, 0x000833D7, 0x0009BD60, 0x000B0969,
+       0x000C9273, 0x000E5BFC, 0x00132A8A, 0x0014B414,
+       0x00163D9D, 0x001789A6, 0x001912B0, 0x001ADC39,
+       0x001C6BCE, 0x001E34D8, 0x001FBE61, 0x0001CA6A,
+       0x00039374, 0x00051CFD, 0x0006EC0B, 0x00087515,
+       0x0009FE9E, 0x000B4AA7, 0x000CD3B1, 0x000E9D3A,
+       0x00000000, 0x00000000,
+};
+
+const u32 b43_ntab_tdi40a1[] = {
+       0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD,
+       0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07,
+       0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D,
+       0x00155C37, 0x0016EACB, 0x00187454, 0x001A3DDE,
+       0x001B89E7, 0x001D12F0, 0x001F1CFA, 0x00016B88,
+       0x00033492, 0x0004BE1B, 0x00060A24, 0x0007D32E,
+       0x00095D38, 0x000AEC4C, 0x000C7555, 0x000E3EDF,
+       0x00124AE8, 0x001413F1, 0x0015A37B, 0x00172C89,
+       0x0018B593, 0x001A419C, 0x001BCB25, 0x001D942F,
+       0x001F63B9, 0x0001AD4D, 0x00037657, 0x0004C260,
+       0x00068BE9, 0x000814F3, 0x0009A47C, 0x000B2D8A,
+       0x000CB694, 0x000E429D, 0x00128C26, 0x001455B0,
+       0x0015E4BA, 0x00176E4E, 0x0018F758, 0x001A8361,
+       0x001C0CEA, 0x001DD674, 0x001FA57D, 0x0001EE8B,
+       0x0003B795, 0x0005039E, 0x0006CD27, 0x000856B1,
+       0x0009E5C6, 0x000B6F4F, 0x000CF859, 0x000E8462,
+       0x00130DEB, 0x00149775, 0x00162603, 0x0017AF8C,
+       0x00193896, 0x001AC49F, 0x001C4E28, 0x001E17B2,
+       0x0000A6C7, 0x00023050, 0x0003F9DA, 0x00054563,
+       0x00070EEC, 0x00089876, 0x000A2704, 0x000BB08D,
+       0x000D3A17, 0x001185A0, 0x00134F29, 0x0014D8B3,
+       0x001667C8, 0x0017F151, 0x00197ADB, 0x001B0664,
+       0x001C8FED, 0x001E5977, 0x0000E805, 0x0002718F,
+       0x00043B18, 0x000586A1, 0x0007502B, 0x0008D9B4,
+       0x000A68C9, 0x000BF252, 0x000DBBDC, 0x0011C7E5,
+       0x001390EE, 0x00151A78, 0x0016A906, 0x00183290,
+       0x0019BC19, 0x001B4822, 0x001CD12C, 0x001E9AB5,
+       0x00000000, 0x00000000,
+};
+
+const u32 b43_ntab_tdtrn[] = {
+       0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6,
+       0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68,
+       0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52,
+       0x0C380000, 0x12F6FE52, 0xFE36F592, 0xEE680050,
+       0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6,
+       0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68,
+       0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52,
+       0x0C380000, 0x12F6FE52, 0xFE36F592, 0xEE680050,
+       0x05E305E3, 0x004DEF0C, 0xF5F3FE47, 0xFE611246,
+       0x00000BC7, 0xFE611246, 0xF5F3FE47, 0x004DEF0C,
+       0x05E305E3, 0xEF0C004D, 0xFE47F5F3, 0x1246FE61,
+       0x0BC70000, 0x1246FE61, 0xFE47F5F3, 0xEF0C004D,
+       0x05E305E3, 0x004DEF0C, 0xF5F3FE47, 0xFE611246,
+       0x00000BC7, 0xFE611246, 0xF5F3FE47, 0x004DEF0C,
+       0x05E305E3, 0xEF0C004D, 0xFE47F5F3, 0x1246FE61,
+       0x0BC70000, 0x1246FE61, 0xFE47F5F3, 0xEF0C004D,
+       0xFA58FA58, 0xF895043B, 0xFF4C09C0, 0xFBC6FFA8,
+       0xFB84F384, 0x0798F6F9, 0x05760122, 0x058409F6,
+       0x0B500000, 0x05B7F542, 0x08860432, 0x06DDFEE7,
+       0xFB84F384, 0xF9D90664, 0xF7E8025C, 0x00FFF7BD,
+       0x05A805A8, 0xF7BD00FF, 0x025CF7E8, 0x0664F9D9,
+       0xF384FB84, 0xFEE706DD, 0x04320886, 0xF54205B7,
+       0x00000B50, 0x09F60584, 0x01220576, 0xF6F90798,
+       0xF384FB84, 0xFFA8FBC6, 0x09C0FF4C, 0x043BF895,
+       0x02D402D4, 0x07DE0270, 0xFC96079C, 0xF90AFE94,
+       0xFE00FF2C, 0x02D4065D, 0x092A0096, 0x0014FBB8,
+       0xFD2CFD2C, 0x076AFB3C, 0x0096F752, 0xF991FD87,
+       0xFB2C0200, 0xFEB8F960, 0x08E0FC96, 0x049802A8,
+       0xFD2CFD2C, 0x02A80498, 0xFC9608E0, 0xF960FEB8,
+       0x0200FB2C, 0xFD87F991, 0xF7520096, 0xFB3C076A,
+       0xFD2CFD2C, 0xFBB80014, 0x0096092A, 0x065D02D4,
+       0xFF2CFE00, 0xFE94F90A, 0x079CFC96, 0x027007DE,
+       0x02D402D4, 0x027007DE, 0x079CFC96, 0xFE94F90A,
+       0xFF2CFE00, 0x065D02D4, 0x0096092A, 0xFBB80014,
+       0xFD2CFD2C, 0xFB3C076A, 0xF7520096, 0xFD87F991,
+       0x0200FB2C, 0xF960FEB8, 0xFC9608E0, 0x02A80498,
+       0xFD2CFD2C, 0x049802A8, 0x08E0FC96, 0xFEB8F960,
+       0xFB2C0200, 0xF991FD87, 0x0096F752, 0x076AFB3C,
+       0xFD2CFD2C, 0x0014FBB8, 0x092A0096, 0x02D4065D,
+       0xFE00FF2C, 0xF90AFE94, 0xFC96079C, 0x07DE0270,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x062A0000, 0xFEFA0759, 0x08B80908, 0xF396FC2D,
+       0xF9D6045C, 0xFC4EF608, 0xF748F596, 0x07B207BF,
+       0x062A062A, 0xF84EF841, 0xF748F596, 0x03B209F8,
+       0xF9D6045C, 0x0C6A03D3, 0x08B80908, 0x0106F8A7,
+       0x062A0000, 0xFEFAF8A7, 0x08B8F6F8, 0xF39603D3,
+       0xF9D6FBA4, 0xFC4E09F8, 0xF7480A6A, 0x07B2F841,
+       0x062AF9D6, 0xF84E07BF, 0xF7480A6A, 0x03B2F608,
+       0xF9D6FBA4, 0x0C6AFC2D, 0x08B8F6F8, 0x01060759,
+       0x062A0000, 0xFEFA0759, 0x08B80908, 0xF396FC2D,
+       0xF9D6045C, 0xFC4EF608, 0xF748F596, 0x07B207BF,
+       0x062A062A, 0xF84EF841, 0xF748F596, 0x03B209F8,
+       0xF9D6045C, 0x0C6A03D3, 0x08B80908, 0x0106F8A7,
+       0x062A0000, 0xFEFAF8A7, 0x08B8F6F8, 0xF39603D3,
+       0xF9D6FBA4, 0xFC4E09F8, 0xF7480A6A, 0x07B2F841,
+       0x062AF9D6, 0xF84E07BF, 0xF7480A6A, 0x03B2F608,
+       0xF9D6FBA4, 0x0C6AFC2D, 0x08B8F6F8, 0x01060759,
+       0x061C061C, 0xFF30009D, 0xFFB21141, 0xFD87FB54,
+       0xF65DFE59, 0x02EEF99E, 0x0166F03C, 0xFFF809B6,
+       0x000008A4, 0x000AF42B, 0x00EFF577, 0xFA840BF2,
+       0xFC02FF51, 0x08260F67, 0xFFF0036F, 0x0842F9C3,
+       0x00000000, 0x063DF7BE, 0xFC910010, 0xF099F7DA,
+       0x00AF03FE, 0xF40E057C, 0x0A89FF11, 0x0BD5FFF6,
+       0xF75C0000, 0xF64A0008, 0x0FC4FE9A, 0x0662FD12,
+       0x01A709A3, 0x04AC0279, 0xEEBF004E, 0xFF6300D0,
+       0xF9E4F9E4, 0x00D0FF63, 0x004EEEBF, 0x027904AC,
+       0x09A301A7, 0xFD120662, 0xFE9A0FC4, 0x0008F64A,
+       0x0000F75C, 0xFFF60BD5, 0xFF110A89, 0x057CF40E,
+       0x03FE00AF, 0xF7DAF099, 0x0010FC91, 0xF7BE063D,
+       0x00000000, 0xF9C30842, 0x036FFFF0, 0x0F670826,
+       0xFF51FC02, 0x0BF2FA84, 0xF57700EF, 0xF42B000A,
+       0x08A40000, 0x09B6FFF8, 0xF03C0166, 0xF99E02EE,
+       0xFE59F65D, 0xFB54FD87, 0x1141FFB2, 0x009DFF30,
+       0x05E30000, 0xFF060705, 0x085408A0, 0xF425FC59,
+       0xFA1D042A, 0xFC78F67A, 0xF7ACF60E, 0x075A0766,
+       0x05E305E3, 0xF8A6F89A, 0xF7ACF60E, 0x03880986,
+       0xFA1D042A, 0x0BDB03A7, 0x085408A0, 0x00FAF8FB,
+       0x05E30000, 0xFF06F8FB, 0x0854F760, 0xF42503A7,
+       0xFA1DFBD6, 0xFC780986, 0xF7AC09F2, 0x075AF89A,
+       0x05E3FA1D, 0xF8A60766, 0xF7AC09F2, 0x0388F67A,
+       0xFA1DFBD6, 0x0BDBFC59, 0x0854F760, 0x00FA0705,
+       0x05E30000, 0xFF060705, 0x085408A0, 0xF425FC59,
+       0xFA1D042A, 0xFC78F67A, 0xF7ACF60E, 0x075A0766,
+       0x05E305E3, 0xF8A6F89A, 0xF7ACF60E, 0x03880986,
+       0xFA1D042A, 0x0BDB03A7, 0x085408A0, 0x00FAF8FB,
+       0x05E30000, 0xFF06F8FB, 0x0854F760, 0xF42503A7,
+       0xFA1DFBD6, 0xFC780986, 0xF7AC09F2, 0x075AF89A,
+       0x05E3FA1D, 0xF8A60766, 0xF7AC09F2, 0x0388F67A,
+       0xFA1DFBD6, 0x0BDBFC59, 0x0854F760, 0x00FA0705,
+       0xFA58FA58, 0xF8F0FE00, 0x0448073D, 0xFDC9FE46,
+       0xF9910258, 0x089D0407, 0xFD5CF71A, 0x02AFFDE0,
+       0x083E0496, 0xFF5A0740, 0xFF7AFD97, 0x00FE01F1,
+       0x0009082E, 0xFA94FF75, 0xFECDF8EA, 0xFFB0F693,
+       0xFD2CFA58, 0x0433FF16, 0xFBA405DD, 0xFA610341,
+       0x06A606CB, 0x0039FD2D, 0x0677FA97, 0x01FA05E0,
+       0xF896003E, 0x075A068B, 0x012CFC3E, 0xFA23F98D,
+       0xFC7CFD43, 0xFF90FC0D, 0x01C10982, 0x00C601D6,
+       0xFD2CFD2C, 0x01D600C6, 0x098201C1, 0xFC0DFF90,
+       0xFD43FC7C, 0xF98DFA23, 0xFC3E012C, 0x068B075A,
+       0x003EF896, 0x05E001FA, 0xFA970677, 0xFD2D0039,
+       0x06CB06A6, 0x0341FA61, 0x05DDFBA4, 0xFF160433,
+       0xFA58FD2C, 0xF693FFB0, 0xF8EAFECD, 0xFF75FA94,
+       0x082E0009, 0x01F100FE, 0xFD97FF7A, 0x0740FF5A,
+       0x0496083E, 0xFDE002AF, 0xF71AFD5C, 0x0407089D,
+       0x0258F991, 0xFE46FDC9, 0x073D0448, 0xFE00F8F0,
+       0xFD2CFD2C, 0xFCE00500, 0xFC09FDDC, 0xFE680157,
+       0x04C70571, 0xFC3AFF21, 0xFCD70228, 0x056D0277,
+       0x0200FE00, 0x0022F927, 0xFE3C032B, 0xFC44FF3C,
+       0x03E9FBDB, 0x04570313, 0x04C9FF5C, 0x000D03B8,
+       0xFA580000, 0xFBE900D2, 0xF9D0FE0B, 0x0125FDF9,
+       0x042501BF, 0x0328FA2B, 0xFFA902F0, 0xFA250157,
+       0x0200FE00, 0x03740438, 0xFF0405FD, 0x030CFE52,
+       0x0037FB39, 0xFF6904C5, 0x04F8FD23, 0xFD31FC1B,
+       0xFD2CFD2C, 0xFC1BFD31, 0xFD2304F8, 0x04C5FF69,
+       0xFB390037, 0xFE52030C, 0x05FDFF04, 0x04380374,
+       0xFE000200, 0x0157FA25, 0x02F0FFA9, 0xFA2B0328,
+       0x01BF0425, 0xFDF90125, 0xFE0BF9D0, 0x00D2FBE9,
+       0x0000FA58, 0x03B8000D, 0xFF5C04C9, 0x03130457,
+       0xFBDB03E9, 0xFF3CFC44, 0x032BFE3C, 0xF9270022,
+       0xFE000200, 0x0277056D, 0x0228FCD7, 0xFF21FC3A,
+       0x057104C7, 0x0157FE68, 0xFDDCFC09, 0x0500FCE0,
+       0xFD2CFD2C, 0x0500FCE0, 0xFDDCFC09, 0x0157FE68,
+       0x057104C7, 0xFF21FC3A, 0x0228FCD7, 0x0277056D,
+       0xFE000200, 0xF9270022, 0x032BFE3C, 0xFF3CFC44,
+       0xFBDB03E9, 0x03130457, 0xFF5C04C9, 0x03B8000D,
+       0x0000FA58, 0x00D2FBE9, 0xFE0BF9D0, 0xFDF90125,
+       0x01BF0425, 0xFA2B0328, 0x02F0FFA9, 0x0157FA25,
+       0xFE000200, 0x04380374, 0x05FDFF04, 0xFE52030C,
+       0xFB390037, 0x04C5FF69, 0xFD2304F8, 0xFC1BFD31,
+       0xFD2CFD2C, 0xFD31FC1B, 0x04F8FD23, 0xFF6904C5,
+       0x0037FB39, 0x030CFE52, 0xFF0405FD, 0x03740438,
+       0x0200FE00, 0xFA250157, 0xFFA902F0, 0x0328FA2B,
+       0x042501BF, 0x0125FDF9, 0xF9D0FE0B, 0xFBE900D2,
+       0xFA580000, 0x000D03B8, 0x04C9FF5C, 0x04570313,
+       0x03E9FBDB, 0xFC44FF3C, 0xFE3C032B, 0x0022F927,
+       0x0200FE00, 0x056D0277, 0xFCD70228, 0xFC3AFF21,
+       0x04C70571, 0xFE680157, 0xFC09FDDC, 0xFCE00500,
+       0x05A80000, 0xFF1006BE, 0x0800084A, 0xF49CFC7E,
+       0xFA580400, 0xFC9CF6DA, 0xF800F672, 0x0710071C,
+       0x05A805A8, 0xF8F0F8E4, 0xF800F672, 0x03640926,
+       0xFA580400, 0x0B640382, 0x0800084A, 0x00F0F942,
+       0x05A80000, 0xFF10F942, 0x0800F7B6, 0xF49C0382,
+       0xFA58FC00, 0xFC9C0926, 0xF800098E, 0x0710F8E4,
+       0x05A8FA58, 0xF8F0071C, 0xF800098E, 0x0364F6DA,
+       0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE,
+       0x05A80000, 0xFF1006BE, 0x0800084A, 0xF49CFC7E,
+       0xFA580400, 0xFC9CF6DA, 0xF800F672, 0x0710071C,
+       0x05A805A8, 0xF8F0F8E4, 0xF800F672, 0x03640926,
+       0xFA580400, 0x0B640382, 0x0800084A, 0x00F0F942,
+       0x05A80000, 0xFF10F942, 0x0800F7B6, 0xF49C0382,
+       0xFA58FC00, 0xFC9C0926, 0xF800098E, 0x0710F8E4,
+       0x05A8FA58, 0xF8F0071C, 0xF800098E, 0x0364F6DA,
+       0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE,
+};
+
+const u32 b43_ntab_tmap[] = {
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0xF1111110, 0x11111111, 0x11F11111, 0x00000111,
+       0x11000000, 0x1111F111, 0x11111111, 0x111111F1,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x000AA888,
+       0x88880000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0xA1111110, 0x11111111, 0x11C11111, 0x00000111,
+       0x11000000, 0x1111A111, 0x11111111, 0x111111A1,
+       0xA2222220, 0x22222222, 0x22C22222, 0x00000222,
+       0x22000000, 0x2222A222, 0x22222222, 0x222222A2,
+       0xF1111110, 0x11111111, 0x11F11111, 0x00011111,
+       0x11110000, 0x1111F111, 0x11111111, 0x111111F1,
+       0xA8AA88A0, 0xA88888A8, 0xA8A8A88A, 0x00088AAA,
+       0xAAAA0000, 0xA8A8AA88, 0xA88AAAAA, 0xAAAA8A8A,
+       0xAAA8AAA0, 0x8AAA8AAA, 0xAA8A8A8A, 0x000AAA88,
+       0x8AAA0000, 0xAAA8A888, 0x8AA88A8A, 0x8A88A888,
+       0x08080A00, 0x0A08080A, 0x080A0A08, 0x00080808,
+       0x080A0000, 0x080A0808, 0x080A0808, 0x0A0A0A08,
+       0xA0A0A0A0, 0x80A0A080, 0x8080A0A0, 0x00008080,
+       0x80A00000, 0x80A080A0, 0xA080A0A0, 0x8080A0A0,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x99999000, 0x9B9B99BB, 0x9BB99999, 0x9999B9B9,
+       0x9B99BB90, 0x9BBBBB9B, 0x9B9B9BB9, 0x00000999,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00AAA888,
+       0x22000000, 0x2222B222, 0x22222222, 0x222222B2,
+       0xB2222220, 0x22222222, 0x22D22222, 0x00000222,
+       0x11000000, 0x1111A111, 0x11111111, 0x111111A1,
+       0xA1111110, 0x11111111, 0x11C11111, 0x00000111,
+       0x33000000, 0x3333B333, 0x33333333, 0x333333B3,
+       0xB3333330, 0x33333333, 0x33D33333, 0x00000333,
+       0x22000000, 0x2222A222, 0x22222222, 0x222222A2,
+       0xA2222220, 0x22222222, 0x22C22222, 0x00000222,
+       0x99B99B00, 0x9B9B99BB, 0x9BB99999, 0x9999B9B9,
+       0x9B99BB99, 0x9BBBBB9B, 0x9B9B9BB9, 0x00000999,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA88, 0x8AAAAA8A, 0x8A8A8AA8, 0x08AAA888,
+       0x22222200, 0x2222F222, 0x22222222, 0x222222F2,
+       0x22222222, 0x22222222, 0x22F22222, 0x00000222,
+       0x11000000, 0x1111F111, 0x11111111, 0x11111111,
+       0xF1111111, 0x11111111, 0x11F11111, 0x01111111,
+       0xBB9BB900, 0xB9B9BB99, 0xB99BBBBB, 0xBBBB9B9B,
+       0xB9BB99BB, 0xB99999B9, 0xB9B9B99B, 0x00000BBB,
+       0xAA000000, 0xA8A8AA88, 0xA88AAAAA, 0xAAAA8A8A,
+       0xA8AA88AA, 0xA88888A8, 0xA8A8A88A, 0x0A888AAA,
+       0xAA000000, 0xA8A8AA88, 0xA88AAAAA, 0xAAAA8A8A,
+       0xA8AA88A0, 0xA88888A8, 0xA8A8A88A, 0x00000AAA,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0xBBBBBB00, 0x999BBBBB, 0x9BB99B9B, 0xB9B9B9BB,
+       0xB9B99BBB, 0xB9B9B9BB, 0xB9BB9B99, 0x00000999,
+       0x8A000000, 0xAA88A888, 0xA88888AA, 0xA88A8A88,
+       0xA88AA88A, 0x88A8AAAA, 0xA8AA8AAA, 0x0888A88A,
+       0x0B0B0B00, 0x090B0B0B, 0x0B090B0B, 0x0909090B,
+       0x09090B0B, 0x09090B0B, 0x09090B09, 0x00000909,
+       0x0A000000, 0x0A080808, 0x080A080A, 0x080A0A08,
+       0x080A080A, 0x0808080A, 0x0A0A0A08, 0x0808080A,
+       0xB0B0B000, 0x9090B0B0, 0x90B09090, 0xB0B0B090,
+       0xB0B090B0, 0x90B0B0B0, 0xB0B09090, 0x00000090,
+       0x80000000, 0xA080A080, 0xA08080A0, 0xA0808080,
+       0xA080A080, 0x80A0A0A0, 0xA0A080A0, 0x00A0A0A0,
+       0x22000000, 0x2222F222, 0x22222222, 0x222222F2,
+       0xF2222220, 0x22222222, 0x22F22222, 0x00000222,
+       0x11000000, 0x1111F111, 0x11111111, 0x111111F1,
+       0xF1111110, 0x11111111, 0x11F11111, 0x00000111,
+       0x33000000, 0x3333F333, 0x33333333, 0x333333F3,
+       0xF3333330, 0x33333333, 0x33F33333, 0x00000333,
+       0x22000000, 0x2222F222, 0x22222222, 0x222222F2,
+       0xF2222220, 0x22222222, 0x22F22222, 0x00000222,
+       0x99000000, 0x9B9B99BB, 0x9BB99999, 0x9999B9B9,
+       0x9B99BB90, 0x9BBBBB9B, 0x9B9B9BB9, 0x00000999,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x88888000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00AAA888,
+       0x88A88A00, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA88, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA88, 0x8AAAAA8A, 0x8A8A8AA8, 0x08AAA888,
+       0x11000000, 0x1111A111, 0x11111111, 0x111111A1,
+       0xA1111110, 0x11111111, 0x11C11111, 0x00000111,
+       0x11000000, 0x1111A111, 0x11111111, 0x111111A1,
+       0xA1111110, 0x11111111, 0x11C11111, 0x00000111,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
+       0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static inline void assert_ntab_array_sizes(void)
+{
+#undef check
+#define check(table, size)     \
+       BUILD_BUG_ON(ARRAY_SIZE(b43_ntab_##table) != B43_NTAB_##size##_SIZE)
+
+       check(adjustpower0, C0_ADJPLT);
+       check(adjustpower1, C1_ADJPLT);
+       check(bdi, BDI);
+       check(channelest, CHANEST);
+       check(estimatepowerlt0, C0_ESTPLT);
+       check(estimatepowerlt1, C1_ESTPLT);
+       check(framelookup, FRAMELT);
+       check(framestruct, FRAMESTRUCT);
+       check(gainctl0, C0_GAINCTL);
+       check(gainctl1, C1_GAINCTL);
+       check(intlevel, INTLEVEL);
+       check(iqlt0, C0_IQLT);
+       check(iqlt1, C1_IQLT);
+       check(loftlt0, C0_LOFEEDTH);
+       check(loftlt1, C1_LOFEEDTH);
+       check(mcs, MCS);
+       check(noisevar10, NOISEVAR10);
+       check(noisevar11, NOISEVAR11);
+       check(pilot, PILOT);
+       check(pilotlt, PILOTLT);
+       check(tdi20a0, TDI20A0);
+       check(tdi20a1, TDI20A1);
+       check(tdi40a0, TDI40A0);
+       check(tdi40a1, TDI40A1);
+       check(tdtrn, TDTRN);
+       check(tmap, TMAP);
+
+#undef check
+}
+
+void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
+{
+       u32 type;
+
+       type = offset & B43_NTAB_TYPEMASK;
+       offset &= 0xFFFF;
+
+       switch (type) {
+       case B43_NTAB_8BIT:
+               B43_WARN_ON(value & ~0xFF);
+               b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
+               break;
+       case B43_NTAB_16BIT:
+               B43_WARN_ON(value & ~0xFFFF);
+               b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value);
+               break;
+       case B43_NTAB_32BIT:
+               b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
+               b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16);
+               b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value & 0xFFFF);
+               break;
+       default:
+               B43_WARN_ON(1);
+       }
+
+       return;
+
+       /* Some compiletime assertions... */
+       assert_ntab_array_sizes();
+}
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
new file mode 100644 (file)
index 0000000..4d498b0
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef B43_TABLES_NPHY_H_
+#define B43_TABLES_NPHY_H_
+
+#include <linux/types.h>
+
+
+struct b43_nphy_channeltab_entry {
+       /* The channel number */
+       u8 channel;
+       /* Radio register values on channelswitch */
+       u8 radio_pll_ref;
+       u8 radio_rf_pllmod0;
+       u8 radio_rf_pllmod1;
+       u8 radio_vco_captail;
+       u8 radio_vco_cal1;
+       u8 radio_vco_cal2;
+       u8 radio_pll_lfc1;
+       u8 radio_pll_lfr1;
+       u8 radio_pll_lfc2;
+       u8 radio_lgbuf_cenbuf;
+       u8 radio_lgen_tune1;
+       u8 radio_lgen_tune2;
+       u8 radio_c1_lgbuf_atune;
+       u8 radio_c1_lgbuf_gtune;
+       u8 radio_c1_rx_rfr1;
+       u8 radio_c1_tx_pgapadtn;
+       u8 radio_c1_tx_mxbgtrim;
+       u8 radio_c2_lgbuf_atune;
+       u8 radio_c2_lgbuf_gtune;
+       u8 radio_c2_rx_rfr1;
+       u8 radio_c2_tx_pgapadtn;
+       u8 radio_c2_tx_mxbgtrim;
+       /* PHY register values on channelswitch */
+       u16 phy_bw1a;
+       u16 phy_bw2;
+       u16 phy_bw3;
+       u16 phy_bw4;
+       u16 phy_bw5;
+       u16 phy_bw6;
+       /* The channel frequency in MHz */
+       u16 freq;
+       /* An unknown value */
+       u16 unk2;
+};
+
+
+struct b43_wldev;
+
+/* Upload the default register value table.
+ * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
+ * table is uploaded. If "ignore_uploadflag" is true, we upload any value
+ * and ignore the "UPLOAD" flag. */
+void b2055_upload_inittab(struct b43_wldev *dev,
+                         bool ghz5, bool ignore_uploadflag);
+
+
+/* Get the NPHY Channel Switch Table entry for a channel number.
+ * Returns NULL on failure to find an entry. */
+const struct b43_nphy_channeltab_entry *
+b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
+
+
+/* The N-PHY tables. */
+
+#define B43_NTAB_TYPEMASK              0xF0000000
+#define B43_NTAB_8BIT                  0x10000000
+#define B43_NTAB_16BIT                 0x20000000
+#define B43_NTAB_32BIT                 0x30000000
+#define B43_NTAB8(table, offset)       (((table) << 10) | (offset) | B43_NTAB_8BIT)
+#define B43_NTAB16(table, offset)      (((table) << 10) | (offset) | B43_NTAB_16BIT)
+#define B43_NTAB32(table, offset)      (((table) << 10) | (offset) | B43_NTAB_32BIT)
+
+/* Static N-PHY tables */
+#define B43_NTAB_FRAMESTRUCT           B43_NTAB32(0x0A, 0x000) /* Frame Struct Table */
+#define B43_NTAB_FRAMESTRUCT_SIZE      832
+#define B43_NTAB_FRAMELT               B43_NTAB8 (0x18, 0x000) /* Frame Lookup Table */
+#define B43_NTAB_FRAMELT_SIZE          32
+#define B43_NTAB_TMAP                  B43_NTAB32(0x0C, 0x000) /* T Map Table */
+#define B43_NTAB_TMAP_SIZE             448
+#define B43_NTAB_TDTRN                 B43_NTAB32(0x0E, 0x000) /* TDTRN Table */
+#define B43_NTAB_TDTRN_SIZE            704
+#define B43_NTAB_INTLEVEL              B43_NTAB32(0x0D, 0x000) /* Int Level Table */
+#define B43_NTAB_INTLEVEL_SIZE         7
+#define B43_NTAB_PILOT                 B43_NTAB16(0x0B, 0x000) /* Pilot Table */
+#define B43_NTAB_PILOT_SIZE            88
+#define B43_NTAB_PILOTLT               B43_NTAB32(0x14, 0x000) /* Pilot Lookup Table */
+#define B43_NTAB_PILOTLT_SIZE          6
+#define B43_NTAB_TDI20A0               B43_NTAB32(0x13, 0x080) /* TDI Table 20 Antenna 0 */
+#define B43_NTAB_TDI20A0_SIZE          55
+#define B43_NTAB_TDI20A1               B43_NTAB32(0x13, 0x100) /* TDI Table 20 Antenna 1 */
+#define B43_NTAB_TDI20A1_SIZE          55
+#define B43_NTAB_TDI40A0               B43_NTAB32(0x13, 0x280) /* TDI Table 40 Antenna 0 */
+#define B43_NTAB_TDI40A0_SIZE          110
+#define B43_NTAB_TDI40A1               B43_NTAB32(0x13, 0x300) /* TDI Table 40 Antenna 1 */
+#define B43_NTAB_TDI40A1_SIZE          110
+#define B43_NTAB_BDI                   B43_NTAB16(0x15, 0x000) /* BDI Table */
+#define B43_NTAB_BDI_SIZE              6
+#define B43_NTAB_CHANEST               B43_NTAB32(0x16, 0x000) /* Channel Estimate Table */
+#define B43_NTAB_CHANEST_SIZE          96
+#define B43_NTAB_MCS                   B43_NTAB8 (0x12, 0x000) /* MCS Table */
+#define B43_NTAB_MCS_SIZE              128
+
+/* Volatile N-PHY tables */
+#define B43_NTAB_NOISEVAR10            B43_NTAB32(0x10, 0x000) /* Noise Var Table 10 */
+#define B43_NTAB_NOISEVAR10_SIZE       256
+#define B43_NTAB_NOISEVAR11            B43_NTAB32(0x10, 0x080) /* Noise Var Table 11 */
+#define B43_NTAB_NOISEVAR11_SIZE       256
+#define B43_NTAB_C0_ESTPLT             B43_NTAB8 (0x1A, 0x000) /* Estimate Power Lookup Table Core 0 */
+#define B43_NTAB_C0_ESTPLT_SIZE                64
+#define B43_NTAB_C1_ESTPLT             B43_NTAB8 (0x1B, 0x000) /* Estimate Power Lookup Table Core 1 */
+#define B43_NTAB_C1_ESTPLT_SIZE                64
+#define B43_NTAB_C0_ADJPLT             B43_NTAB8 (0x1A, 0x040) /* Adjust Power Lookup Table Core 0 */
+#define B43_NTAB_C0_ADJPLT_SIZE                128
+#define B43_NTAB_C1_ADJPLT             B43_NTAB8 (0x1B, 0x040) /* Adjust Power Lookup Table Core 1 */
+#define B43_NTAB_C1_ADJPLT_SIZE                128
+#define B43_NTAB_C0_GAINCTL            B43_NTAB32(0x1A, 0x0C0) /* Gain Control Lookup Table Core 0 */
+#define B43_NTAB_C0_GAINCTL_SIZE       128
+#define B43_NTAB_C1_GAINCTL            B43_NTAB32(0x1B, 0x0C0) /* Gain Control Lookup Table Core 1 */
+#define B43_NTAB_C1_GAINCTL_SIZE       128
+#define B43_NTAB_C0_IQLT               B43_NTAB32(0x1A, 0x140) /* IQ Lookup Table Core 0 */
+#define B43_NTAB_C0_IQLT_SIZE          128
+#define B43_NTAB_C1_IQLT               B43_NTAB32(0x1B, 0x140) /* IQ Lookup Table Core 1 */
+#define B43_NTAB_C1_IQLT_SIZE          128
+#define B43_NTAB_C0_LOFEEDTH           B43_NTAB16(0x1A, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 0 */
+#define B43_NTAB_C0_LOFEEDTH_SIZE      128
+#define B43_NTAB_C1_LOFEEDTH           B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
+#define B43_NTAB_C1_LOFEEDTH_SIZE      128
+
+void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
+
+extern const u8 b43_ntab_adjustpower0[];
+extern const u8 b43_ntab_adjustpower1[];
+extern const u16 b43_ntab_bdi[];
+extern const u32 b43_ntab_channelest[];
+extern const u8 b43_ntab_estimatepowerlt0[];
+extern const u8 b43_ntab_estimatepowerlt1[];
+extern const u8 b43_ntab_framelookup[];
+extern const u32 b43_ntab_framestruct[];
+extern const u32 b43_ntab_gainctl0[];
+extern const u32 b43_ntab_gainctl1[];
+extern const u32 b43_ntab_intlevel[];
+extern const u32 b43_ntab_iqlt0[];
+extern const u32 b43_ntab_iqlt1[];
+extern const u16 b43_ntab_loftlt0[];
+extern const u16 b43_ntab_loftlt1[];
+extern const u8 b43_ntab_mcs[];
+extern const u32 b43_ntab_noisevar10[];
+extern const u32 b43_ntab_noisevar11[];
+extern const u16 b43_ntab_pilot[];
+extern const u32 b43_ntab_pilotlt[];
+extern const u32 b43_ntab_tdi20a0[];
+extern const u32 b43_ntab_tdi20a1[];
+extern const u32 b43_ntab_tdi40a0[];
+extern const u32 b43_ntab_tdi40a1[];
+extern const u32 b43_ntab_tdtrn[];
+extern const u32 b43_ntab_tmap[];
+
+
+#endif /* B43_TABLES_NPHY_H_ */
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
new file mode 100644 (file)
index 0000000..e632125
--- /dev/null
@@ -0,0 +1,674 @@
+/*
+
+  Broadcom B43 wireless driver
+
+  PHY workarounds.
+
+  Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
+  Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.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, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#include "b43.h"
+#include "main.h"
+#include "tables.h"
+#include "phy.h"
+#include "wa.h"
+
+static void b43_wa_papd(struct b43_wldev *dev)
+{
+       u16 backup;
+
+       backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0);
+       b43_dummy_transmission(dev);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup);
+}
+
+static void b43_wa_auxclipthr(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800);
+}
+
+static void b43_wa_afcdac(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, 0x0035, 0x03FF);
+       b43_phy_write(dev, 0x0036, 0x0400);
+}
+
+static void b43_wa_txdc_offset(struct b43_wldev *dev)
+{
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051);
+}
+
+void b43_wa_initgains(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9);
+       b43_phy_write(dev, B43_PHY_LPFGAINCTL,
+               b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F);
+       if (phy->rev <= 2)
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF);
+       b43_radio_write16(dev, 0x0002, 0x1FBF);
+
+       b43_phy_write(dev, 0x0024, 0x4680);
+       b43_phy_write(dev, 0x0020, 0x0003);
+       b43_phy_write(dev, 0x001D, 0x0F40);
+       b43_phy_write(dev, 0x001F, 0x1C00);
+       if (phy->rev <= 3)
+               b43_phy_write(dev, 0x002A,
+                       (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400);
+       else if (phy->rev == 5) {
+               b43_phy_write(dev, 0x002A,
+                       (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00);
+               b43_phy_write(dev, 0x00CC, 0x2121);
+       }
+       if (phy->rev >= 3)
+               b43_phy_write(dev, 0x00BA, 0x3ED5);
+}
+
+static void b43_wa_divider(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100);
+       b43_phy_write(dev, 0x008E, 0x58C1);
+}
+
+static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */
+{
+       if (dev->phy.rev <= 2) {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7);
+       } else {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25);
+       }
+}
+
+static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */
+{
+       int i;
+
+       if (0 /* FIXME: For APHY.rev=2 this might be needed */) {
+               for (i = 0; i < 8; i++)
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8);
+               for (i = 8; i < 16; i++)
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8);
+       } else {
+               for (i = 0; i < 64; i++)
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i);
+       }
+}
+
+static void b43_wa_analog(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+       u16 ofdmrev;
+
+       ofdmrev = b43_phy_read(dev, B43_PHY_VERSION_OFDM) & B43_PHYVER_VERSION;
+       if (ofdmrev > 2) {
+               if (phy->type == B43_PHYTYPE_A)
+                       b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808);
+               else
+                       b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000);
+       } else {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040);
+       }
+}
+
+static void b43_wa_dac(struct b43_wldev *dev)
+{
+       if (dev->phy.analog == 1)
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
+                       (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008);
+       else
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1,
+                       (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010);
+}
+
+static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */
+{
+       int i;
+
+       if (dev->phy.type == B43_PHYTYPE_A)
+               for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++)
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]);
+       else
+               for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++)
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]);
+}
+
+static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */
+{
+       struct b43_phy *phy = &dev->phy;
+       int i;
+
+       if (phy->type == B43_PHYTYPE_A) {
+               if (phy->rev == 2)
+                       for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]);
+               else
+                       for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]);
+       } else {
+               if (phy->rev == 1)
+                       for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]);
+               else
+                       for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]);
+       }
+}
+
+static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */
+{
+       int i;
+
+       for (i = 0; i < B43_TAB_ROTOR_SIZE; i++)
+               b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]);
+}
+
+static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */
+{
+       struct b43_phy *phy = &dev->phy;
+       int i;
+
+       if (phy->type == B43_PHYTYPE_A) {
+               if (phy->rev <= 1)
+                       for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                                       i, 0);
+               else if (phy->rev == 2)
+                       for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                                       i, b43_tab_noisescalea2[i]);
+               else if (phy->rev == 3)
+                       for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                                       i, b43_tab_noisescalea3[i]);
+               else
+                       for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                                       i, b43_tab_noisescaleg3[i]);
+       } else {
+               if (phy->rev >= 6) {
+                       if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN)
+                               for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                                       b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                               i, b43_tab_noisescaleg3[i]);
+                       else
+                               for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                                       b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                               i, b43_tab_noisescaleg2[i]);
+               } else {
+                       for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++)
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE,
+                                                       i, b43_tab_noisescaleg1[i]);
+               }
+       }
+}
+
+static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */
+{
+       int i;
+
+       for (i = 0; i < B43_TAB_RETARD_SIZE; i++)
+                       b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD,
+                               i, b43_tab_retard[i]);
+}
+
+static void b43_wa_txlna_gain(struct b43_wldev *dev)
+{
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000);
+}
+
+static void b43_wa_crs_reset(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, 0x002C, 0x0064);
+}
+
+static void b43_wa_2060txlna_gain(struct b43_wldev *dev)
+{
+       b43_hf_write(dev, b43_hf_read(dev) |
+                        B43_HF_2060W);
+}
+
+static void b43_wa_lms(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, 0x0055,
+               (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004);
+}
+
+static void b43_wa_mixedsignal(struct b43_wldev *dev)
+{
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3);
+}
+
+static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */
+{
+       struct b43_phy *phy = &dev->phy;
+       int i;
+       const u16 *tab;
+
+       if (phy->type == B43_PHYTYPE_A) {
+               tab = b43_tab_sigmasqr1;
+       } else if (phy->type == B43_PHYTYPE_G) {
+               tab = b43_tab_sigmasqr2;
+       } else {
+               B43_WARN_ON(1);
+               return;
+       }
+
+       for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ,
+                                       i, tab[i]);
+       }
+}
+
+static void b43_wa_iqadc(struct b43_wldev *dev)
+{
+       if (dev->phy.analog == 4)
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0,
+                       b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000);
+}
+
+static void b43_wa_crs_ed(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       if (phy->rev == 1) {
+               b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x4F19);
+       } else if (phy->rev == 2) {
+               b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x1861);
+               b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0271);
+               b43_phy_write(dev, B43_PHY_ANTDWELL,
+                                 b43_phy_read(dev, B43_PHY_ANTDWELL)
+                                 | 0x0800);
+       } else {
+               b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x0098);
+               b43_phy_write(dev, B43_PHY_CRSTHRES2, 0x0070);
+               b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080);
+               b43_phy_write(dev, B43_PHY_ANTDWELL,
+                                 b43_phy_read(dev, B43_PHY_ANTDWELL)
+                                 | 0x0800);
+       }
+}
+
+static void b43_wa_crs_thr(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, B43_PHY_CRS0,
+                       (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000);
+}
+
+static void b43_wa_crs_blank(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A);
+}
+
+static void b43_wa_cck_shiftbits(struct b43_wldev *dev)
+{
+       b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026);
+}
+
+static void b43_wa_wrssi_offset(struct b43_wldev *dev)
+{
+       int i;
+
+       if (dev->phy.rev == 1) {
+               for (i = 0; i < 16; i++) {
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1,
+                                               i, 0x0020);
+               }
+       } else {
+               for (i = 0; i < 32; i++) {
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI,
+                                               i, 0x0820);
+               }
+       }
+}
+
+static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev)
+{
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20);
+}
+
+static void b43_wa_altagc(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       if (phy->rev == 1) {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D);
+               b43_phy_write(dev, B43_PHY_LMS, 4);
+       } else {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25);
+       }
+
+       b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA,
+               (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700);
+       b43_phy_write(dev, B43_PHY_OFDM(0x1A),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F);
+       b43_phy_write(dev, B43_PHY_OFDM(0x1A),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80);
+       b43_phy_write(dev, B43_PHY_ANTWRSETT,
+               (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300);
+       b43_radio_write16(dev, 0x7A,
+               b43_radio_read16(dev, 0x7A) | 0x0008);
+       b43_phy_write(dev, B43_PHY_N1P1GAIN,
+               (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008);
+       b43_phy_write(dev, B43_PHY_P1P2GAIN,
+               (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600);
+       b43_phy_write(dev, B43_PHY_N1N2GAIN,
+               (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700);
+       b43_phy_write(dev, B43_PHY_N1P1GAIN,
+               (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100);
+       if (phy->rev == 1) {
+               b43_phy_write(dev, B43_PHY_N1N2GAIN,
+                                 (b43_phy_read(dev, B43_PHY_N1N2GAIN)
+                                  & ~0x000F) | 0x0007);
+       }
+       b43_phy_write(dev, B43_PHY_OFDM(0x88),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C);
+       b43_phy_write(dev, B43_PHY_OFDM(0x88),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200);
+       b43_phy_write(dev, B43_PHY_OFDM(0x96),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C);
+       b43_phy_write(dev, B43_PHY_OFDM(0x89),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020);
+       b43_phy_write(dev, B43_PHY_OFDM(0x89),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200);
+       b43_phy_write(dev, B43_PHY_OFDM(0x82),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E);
+       b43_phy_write(dev, B43_PHY_OFDM(0x96),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00);
+       b43_phy_write(dev, B43_PHY_OFDM(0x81),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028);
+       b43_phy_write(dev, B43_PHY_OFDM(0x81),
+               (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00);
+       if (phy->rev == 1) {
+               b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B);
+               b43_phy_write(dev, B43_PHY_OFDM(0x1B),
+                       (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002);
+       } else {
+               b43_phy_write(dev, B43_PHY_OFDM(0x1B),
+                       b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E);
+               b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A);
+               b43_phy_write(dev, B43_PHY_LPFGAINCTL,
+                       (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004);
+               if (phy->rev >= 6) {
+                       b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A);
+                       b43_phy_write(dev, B43_PHY_LPFGAINCTL,
+                               (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000);
+               }
+       }
+       b43_phy_write(dev, B43_PHY_DIVSRCHIDX,
+               (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x8080) | 0x7874);
+       b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00);
+       if (phy->rev == 1) {
+               b43_phy_write(dev, B43_PHY_DIVP1P2GAIN,
+                       (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600);
+               b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E);
+               b43_phy_write(dev, B43_PHY_ANTWRSETT,
+                       (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E);
+               b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28);
+       } else {
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28);
+       }
+       if (phy->rev >= 6) {
+               b43_phy_write(dev, B43_PHY_OFDM(0x26),
+                       b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003);
+               b43_phy_write(dev, B43_PHY_OFDM(0x26),
+                       b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000);
+       }
+       b43_phy_read(dev, B43_PHY_VERSION_OFDM); /* Dummy read */
+}
+
+static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */
+{
+       b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480);
+}
+
+static void b43_wa_cpll_nonpilot(struct b43_wldev *dev)
+{
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0);
+       b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0);
+}
+
+static void b43_wa_rssi_adc(struct b43_wldev *dev)
+{
+       if (dev->phy.analog == 4)
+               b43_phy_write(dev, 0x00DC, 0x7454);
+}
+
+static void b43_wa_boards_a(struct b43_wldev *dev)
+{
+       struct ssb_bus *bus = dev->dev->bus;
+
+       if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
+           bus->boardinfo.type == SSB_BOARD_BU4306 &&
+           bus->boardinfo.rev < 0x30) {
+               b43_phy_write(dev, 0x0010, 0xE000);
+               b43_phy_write(dev, 0x0013, 0x0140);
+               b43_phy_write(dev, 0x0014, 0x0280);
+       } else {
+               if (bus->boardinfo.type == SSB_BOARD_MP4318 &&
+                   bus->boardinfo.rev < 0x20) {
+                       b43_phy_write(dev, 0x0013, 0x0210);
+                       b43_phy_write(dev, 0x0014, 0x0840);
+               } else {
+                       b43_phy_write(dev, 0x0013, 0x0140);
+                       b43_phy_write(dev, 0x0014, 0x0280);
+               }
+               if (dev->phy.rev <= 4)
+                       b43_phy_write(dev, 0x0010, 0xE000);
+               else
+                       b43_phy_write(dev, 0x0010, 0x2000);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039);
+               b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040);
+       }
+}
+
+static void b43_wa_boards_g(struct b43_wldev *dev)
+{
+       struct ssb_bus *bus = dev->dev->bus;
+       struct b43_phy *phy = &dev->phy;
+
+       if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM ||
+           bus->boardinfo.type != SSB_BOARD_BU4306 ||
+           bus->boardinfo.rev != 0x17) {
+               if (phy->rev < 2) {
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002);
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001);
+               } else {
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002);
+                       b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001);
+                       if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
+                           (phy->rev >= 7)) {
+                               b43_phy_write(dev, B43_PHY_EXTG(0x11),
+                                       b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000);
+                               b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002);
+                       }
+               }
+       }
+       if (bus->sprom.boardflags_lo & B43_BFL_FEM) {
+               b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120);
+               b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480);
+       }
+}
+
+void b43_wa_all(struct b43_wldev *dev)
+{
+       struct b43_phy *phy = &dev->phy;
+
+       if (phy->type == B43_PHYTYPE_A) {
+               switch (phy->rev) {
+               case 2:
+                       b43_wa_papd(dev);
+                       b43_wa_auxclipthr(dev);
+                       b43_wa_afcdac(dev);
+                       b43_wa_txdc_offset(dev);
+                       b43_wa_initgains(dev);
+                       b43_wa_divider(dev);
+                       b43_wa_gt(dev);
+                       b43_wa_rssi_lt(dev);
+                       b43_wa_analog(dev);
+                       b43_wa_dac(dev);
+                       b43_wa_fft(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_rt(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_art(dev);
+                       b43_wa_txlna_gain(dev);
+                       b43_wa_crs_reset(dev);
+                       b43_wa_2060txlna_gain(dev);
+                       b43_wa_lms(dev);
+                       break;
+               case 3:
+                       b43_wa_papd(dev);
+                       b43_wa_mixedsignal(dev);
+                       b43_wa_rssi_lt(dev);
+                       b43_wa_txdc_offset(dev);
+                       b43_wa_initgains(dev);
+                       b43_wa_dac(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_msst(dev);
+                       b43_wa_analog(dev);
+                       b43_wa_gt(dev);
+                       b43_wa_txpuoff_rxpuon(dev);
+                       b43_wa_txlna_gain(dev);
+                       break;
+               case 5:
+                       b43_wa_iqadc(dev);
+               case 6:
+                       b43_wa_papd(dev);
+                       b43_wa_rssi_lt(dev);
+                       b43_wa_txdc_offset(dev);
+                       b43_wa_initgains(dev);
+                       b43_wa_dac(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_msst(dev);
+                       b43_wa_analog(dev);
+                       b43_wa_gt(dev);
+                       b43_wa_txpuoff_rxpuon(dev);
+                       b43_wa_txlna_gain(dev);
+                       break;
+               case 7:
+                       b43_wa_iqadc(dev);
+                       b43_wa_papd(dev);
+                       b43_wa_rssi_lt(dev);
+                       b43_wa_txdc_offset(dev);
+                       b43_wa_initgains(dev);
+                       b43_wa_dac(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_msst(dev);
+                       b43_wa_analog(dev);
+                       b43_wa_gt(dev);
+                       b43_wa_txpuoff_rxpuon(dev);
+                       b43_wa_txlna_gain(dev);
+                       b43_wa_rssi_adc(dev);
+               default:
+                       B43_WARN_ON(1);
+               }
+               b43_wa_boards_a(dev);
+       } else if (phy->type == B43_PHYTYPE_G) {
+               switch (phy->rev) {
+               case 1://XXX review rev1
+                       b43_wa_crs_ed(dev);
+                       b43_wa_crs_thr(dev);
+                       b43_wa_crs_blank(dev);
+                       b43_wa_cck_shiftbits(dev);
+                       b43_wa_fft(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_rt(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_art(dev);
+                       b43_wa_wrssi_offset(dev);
+                       b43_wa_altagc(dev);
+                       break;
+               case 2:
+               case 6:
+               case 7:
+               case 8:
+               case 9:
+                       b43_wa_tr_ltov(dev);
+                       b43_wa_crs_ed(dev);
+                       b43_wa_rssi_lt(dev);
+                       b43_wa_nft(dev);
+                       b43_wa_nst(dev);
+                       b43_wa_msst(dev);
+                       b43_wa_wrssi_offset(dev);
+                       b43_wa_altagc(dev);
+                       b43_wa_analog(dev);
+                       b43_wa_txpuoff_rxpuon(dev);
+                       break;
+               default:
+                       B43_WARN_ON(1);
+               }
+               b43_wa_boards_g(dev);
+       } else { /* No N PHY support so far */
+               B43_WARN_ON(1);
+       }
+
+       b43_wa_cpll_nonpilot(dev);
+}
diff --git a/drivers/net/wireless/b43/wa.h b/drivers/net/wireless/b43/wa.h
new file mode 100644 (file)
index 0000000..e163c5e
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef B43_WA_H_
+#define B43_WA_H_
+
+void b43_wa_initgains(struct b43_wldev *dev);
+void b43_wa_all(struct b43_wldev *dev);
+
+#endif /* B43_WA_H_ */
index 3307ba1856b17ce36d0740784524a8a3ba7d3562..3fc53e8b4416092c26a2f2bbb7ead93b4ecda98b 100644 (file)
@@ -5,7 +5,7 @@
   Transmission (TX/RX) related functions.
 
   Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
-  Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (C) 2005, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -30,7 +30,7 @@
 #include "xmit.h"
 #include "phy.h"
 #include "dma.h"
-#include "pio.h"
+
 
 /* Extract the bitrate out of a CCK PLCP header. */
 static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp)
@@ -177,13 +177,15 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
        return 0;
 }
 
-static void generate_txhdr_fw4(struct b43_wldev *dev,
-                              struct b43_txhdr_fw4 *txhdr,
-                              const unsigned char *fragment_data,
-                              unsigned int fragment_len,
-                              const struct ieee80211_tx_control *txctl,
-                              u16 cookie)
+/* Generate a TX data header. */
+void b43_generate_txhdr(struct b43_wldev *dev,
+                       u8 *_txhdr,
+                       const unsigned char *fragment_data,
+                       unsigned int fragment_len,
+                       const struct ieee80211_tx_control *txctl,
+                       u16 cookie)
 {
+       struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
        const struct b43_phy *phy = &dev->phy;
        const struct ieee80211_hdr *wlhdr =
            (const struct ieee80211_hdr *)fragment_data;
@@ -221,7 +223,7 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
        } else {
                int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb);
                txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
-                                                                dev->wl->if_id,
+                                                                txctl->vif,
                                                                 fragment_len,
                                                                 fbrate_base100kbps);
        }
@@ -241,23 +243,30 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
                plcp_fragment_len += txctl->icv_len;
 
                key_idx = b43_kidx_to_fw(dev, key_idx);
-               mac_ctl |= (key_idx << B43_TX4_MAC_KEYIDX_SHIFT) &
-                          B43_TX4_MAC_KEYIDX;
-               mac_ctl |= (key->algorithm << B43_TX4_MAC_KEYALG_SHIFT) &
-                          B43_TX4_MAC_KEYALG;
+               mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
+                          B43_TXH_MAC_KEYIDX;
+               mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
+                          B43_TXH_MAC_KEYALG;
                wlhdr_len = ieee80211_get_hdrlen(fctl);
                iv_len = min((size_t) txctl->iv_len,
                             ARRAY_SIZE(txhdr->iv));
                memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
        }
-       b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp),
-                             plcp_fragment_len, rate);
+       if (b43_is_old_txhdr_format(dev)) {
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
+                                     plcp_fragment_len, rate);
+       } else {
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->new_format.plcp),
+                                     plcp_fragment_len, rate);
+       }
        b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->plcp_fb),
                              plcp_fragment_len, rate_fb);
 
        /* Extra Frame Types */
        if (rate_fb_ofdm)
-               extra_ft |= B43_TX4_EFT_FBOFDM;
+               extra_ft |= B43_TXH_EFT_FB_OFDM;
+       else
+               extra_ft |= B43_TXH_EFT_FB_CCK;
 
        /* Set channel radio code. Note that the micrcode ORs 0x100 to
         * this value before comparing it to the value in SHM, if this
@@ -267,18 +276,27 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
 
        /* PHY TX Control word */
        if (rate_ofdm)
-               phy_ctl |= B43_TX4_PHY_OFDM;
+               phy_ctl |= B43_TXH_PHY_ENC_OFDM;
+       else
+               phy_ctl |= B43_TXH_PHY_ENC_CCK;
        if (dev->short_preamble)
-               phy_ctl |= B43_TX4_PHY_SHORTPRMBL;
-       switch (txctl->antenna_sel_tx) {
-       case 0:
-               phy_ctl |= B43_TX4_PHY_ANTLAST;
+               phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
+
+       switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
+       case 0: /* Default */
+               phy_ctl |= B43_TXH_PHY_ANT01AUTO;
+               break;
+       case 1: /* Antenna 0 */
+               phy_ctl |= B43_TXH_PHY_ANT0;
                break;
-       case 1:
-               phy_ctl |= B43_TX4_PHY_ANT0;
+       case 2: /* Antenna 1 */
+               phy_ctl |= B43_TXH_PHY_ANT1;
                break;
-       case 2:
-               phy_ctl |= B43_TX4_PHY_ANT1;
+       case 3: /* Antenna 2 */
+               phy_ctl |= B43_TXH_PHY_ANT2;
+               break;
+       case 4: /* Antenna 3 */
+               phy_ctl |= B43_TXH_PHY_ANT3;
                break;
        default:
                B43_WARN_ON(1);
@@ -286,14 +304,16 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
 
        /* MAC control */
        if (!(txctl->flags & IEEE80211_TXCTL_NO_ACK))
-               mac_ctl |= B43_TX4_MAC_ACK;
+               mac_ctl |= B43_TXH_MAC_ACK;
        if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
              ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)))
-               mac_ctl |= B43_TX4_MAC_HWSEQ;
+               mac_ctl |= B43_TXH_MAC_HWSEQ;
        if (txctl->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
-               mac_ctl |= B43_TX4_MAC_STMSDU;
+               mac_ctl |= B43_TXH_MAC_STMSDU;
        if (phy->type == B43_PHYTYPE_A)
-               mac_ctl |= B43_TX4_MAC_5GHZ;
+               mac_ctl |= B43_TXH_MAC_5GHZ;
+       if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+               mac_ctl |= B43_TXH_MAC_LONGFRAME;
 
        /* Generate the RTS or CTS-to-self frame */
        if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
@@ -302,6 +322,7 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
                struct ieee80211_hdr *hdr;
                int rts_rate, rts_rate_fb;
                int rts_rate_ofdm, rts_rate_fb_ofdm;
+               struct b43_plcp_hdr6 *plcp;
 
                rts_rate = txctl->rts_cts_rate;
                rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
@@ -309,59 +330,84 @@ static void generate_txhdr_fw4(struct b43_wldev *dev,
                rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
 
                if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
-                       ieee80211_ctstoself_get(dev->wl->hw, dev->wl->if_id,
+                       struct ieee80211_cts *cts;
+
+                       if (b43_is_old_txhdr_format(dev)) {
+                               cts = (struct ieee80211_cts *)
+                                       (txhdr->old_format.rts_frame);
+                       } else {
+                               cts = (struct ieee80211_cts *)
+                                       (txhdr->new_format.rts_frame);
+                       }
+                       ieee80211_ctstoself_get(dev->wl->hw, txctl->vif,
                                                fragment_data, fragment_len,
-                                               txctl,
-                                               (struct ieee80211_cts *)(txhdr->
-                                                                        rts_frame));
-                       mac_ctl |= B43_TX4_MAC_SENDCTS;
+                                               txctl, cts);
+                       mac_ctl |= B43_TXH_MAC_SENDCTS;
                        len = sizeof(struct ieee80211_cts);
                } else {
-                       ieee80211_rts_get(dev->wl->hw, dev->wl->if_id,
-                                         fragment_data, fragment_len, txctl,
-                                         (struct ieee80211_rts *)(txhdr->
-                                                                  rts_frame));
-                       mac_ctl |= B43_TX4_MAC_SENDRTS;
+                       struct ieee80211_rts *rts;
+
+                       if (b43_is_old_txhdr_format(dev)) {
+                               rts = (struct ieee80211_rts *)
+                                       (txhdr->old_format.rts_frame);
+                       } else {
+                               rts = (struct ieee80211_rts *)
+                                       (txhdr->new_format.rts_frame);
+                       }
+                       ieee80211_rts_get(dev->wl->hw, txctl->vif,
+                                         fragment_data, fragment_len,
+                                         txctl, rts);
+                       mac_ctl |= B43_TXH_MAC_SENDRTS;
                        len = sizeof(struct ieee80211_rts);
                }
                len += FCS_LEN;
-               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->
-                                                              rts_plcp), len,
-                                     rts_rate);
-               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->
-                                                              rts_plcp_fb),
+
+               /* Generate the PLCP headers for the RTS/CTS frame */
+               if (b43_is_old_txhdr_format(dev))
+                       plcp = &txhdr->old_format.rts_plcp;
+               else
+                       plcp = &txhdr->new_format.rts_plcp;
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
+                                     len, rts_rate);
+               plcp = &txhdr->rts_plcp_fb;
+               b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)plcp,
                                      len, rts_rate_fb);
-               hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame);
+
+               if (b43_is_old_txhdr_format(dev)) {
+                       hdr = (struct ieee80211_hdr *)
+                               (&txhdr->old_format.rts_frame);
+               } else {
+                       hdr = (struct ieee80211_hdr *)
+                               (&txhdr->new_format.rts_frame);
+               }
                txhdr->rts_dur_fb = hdr->duration_id;
+
                if (rts_rate_ofdm) {
-                       extra_ft |= B43_TX4_EFT_RTSOFDM;
+                       extra_ft |= B43_TXH_EFT_RTS_OFDM;
                        txhdr->phy_rate_rts =
                            b43_plcp_get_ratecode_ofdm(rts_rate);
-               } else
+               } else {
+                       extra_ft |= B43_TXH_EFT_RTS_CCK;
                        txhdr->phy_rate_rts =
                            b43_plcp_get_ratecode_cck(rts_rate);
+               }
                if (rts_rate_fb_ofdm)
-                       extra_ft |= B43_TX4_EFT_RTSFBOFDM;
-               mac_ctl |= B43_TX4_MAC_LONGFRAME;
+                       extra_ft |= B43_TXH_EFT_RTSFB_OFDM;
+               else
+                       extra_ft |= B43_TXH_EFT_RTSFB_CCK;
        }
 
        /* Magic cookie */
-       txhdr->cookie = cpu_to_le16(cookie);
+       if (b43_is_old_txhdr_format(dev))
+               txhdr->old_format.cookie = cpu_to_le16(cookie);
+       else
+               txhdr->new_format.cookie = cpu_to_le16(cookie);
 
        /* Apply the bitfields */
        txhdr->mac_ctl = cpu_to_le32(mac_ctl);
        txhdr->phy_ctl = cpu_to_le16(phy_ctl);
        txhdr->extra_ft = extra_ft;
-}
 
-void b43_generate_txhdr(struct b43_wldev *dev,
-                       u8 * txhdr,
-                       const unsigned char *fragment_data,
-                       unsigned int fragment_len,
-                       const struct ieee80211_tx_control *txctl, u16 cookie)
-{
-       generate_txhdr_fw4(dev, (struct b43_txhdr_fw4 *)txhdr,
-                          fragment_data, fragment_len, txctl, cookie);
 }
 
 static s8 b43_rssi_postprocess(struct b43_wldev *dev,
@@ -384,7 +430,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
                        else
                                tmp -= 3;
                } else {
-                       if (dev->dev->bus->sprom.r1.
+                       if (dev->dev->bus->sprom.
                            boardflags_lo & B43_BFL_RSSI) {
                                if (in_rssi > 63)
                                        in_rssi = 63;
@@ -488,7 +534,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
        }
        wlhdr = (struct ieee80211_hdr *)(skb->data);
        fctl = le16_to_cpu(wlhdr->frame_control);
-       skb_trim(skb, skb->len - FCS_LEN);
 
        if (macstat & B43_RX_MAC_DEC) {
                unsigned int keyidx;
@@ -525,7 +570,24 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
        else
                status.rate = b43_plcp_get_bitrate_cck(plcp);
        status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
-       status.mactime = mactime;
+
+       /*
+        * If monitors are present get full 64-bit timestamp. This
+        * code assumes we get to process the packet within 16 bits
+        * of timestamp, i.e. about 65 milliseconds after the PHY
+        * received the first symbol.
+        */
+       if (dev->wl->radiotap_enabled) {
+               u16 low_mactime_now;
+
+               b43_tsf_read(dev, &status.mactime);
+               low_mactime_now = status.mactime;
+               status.mactime = status.mactime & ~0xFFFFULL;
+               status.mactime += mactime;
+               if (low_mactime_now <= mactime)
+                       status.mactime -= 0x10000;
+               status.flag |= RX_FLAG_TSFT;
+       }
 
        chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
        switch (chanstat & B43_RX_CHAN_PHYTYPE) {
@@ -586,10 +648,7 @@ void b43_handle_txstatus(struct b43_wldev *dev,
                        dev->wl->ieee_stats.dot11RTSSuccessCount++;
        }
 
-       if (b43_using_pio(dev))
-               b43_pio_handle_txstatus(dev, status);
-       else
-               b43_dma_handle_txstatus(dev, status);
+       b43_dma_handle_txstatus(dev, status);
 }
 
 /* Handle TX status report as received through DMA/PIO queues */
@@ -618,19 +677,13 @@ void b43_handle_hwtxstatus(struct b43_wldev *dev,
 /* Stop any TX operation on the device (suspend the hardware queues) */
 void b43_tx_suspend(struct b43_wldev *dev)
 {
-       if (b43_using_pio(dev))
-               b43_pio_freeze_txqueues(dev);
-       else
-               b43_dma_tx_suspend(dev);
+       b43_dma_tx_suspend(dev);
 }
 
 /* Resume any TX operation on the device (resume the hardware queues) */
 void b43_tx_resume(struct b43_wldev *dev)
 {
-       if (b43_using_pio(dev))
-               b43_pio_thaw_txqueues(dev);
-       else
-               b43_dma_tx_resume(dev);
+       b43_dma_tx_resume(dev);
 }
 
 #if 0
index 6dc079382f7f105300806e502d148a0b1a86cf9a..ca2a2ab8654c5d7102e07e7c5698d89c536b7680 100644 (file)
@@ -19,68 +19,160 @@ _b43_declare_plcp_hdr(6);
 #undef _b43_declare_plcp_hdr
 
 /* TX header for v4 firmware */
-struct b43_txhdr_fw4 {
-       __le32 mac_ctl;         /* MAC TX control */
-       __le16 mac_frame_ctl;   /* Copy of the FrameControl field */
+struct b43_txhdr {
+       __le32 mac_ctl;                 /* MAC TX control */
+       __le16 mac_frame_ctl;           /* Copy of the FrameControl field */
        __le16 tx_fes_time_norm;        /* TX FES Time Normal */
-       __le16 phy_ctl;         /* PHY TX control */
-       __le16 phy_ctl_0;       /* Unused */
-       __le16 phy_ctl_1;       /* Unused */
-       __le16 phy_ctl_rts_0;   /* Unused */
-       __le16 phy_ctl_rts_1;   /* Unused */
-       __u8 phy_rate;          /* PHY rate */
-       __u8 phy_rate_rts;      /* PHY rate for RTS/CTS */
-       __u8 extra_ft;          /* Extra Frame Types */
-       __u8 chan_radio_code;   /* Channel Radio Code */
-       __u8 iv[16];            /* Encryption IV */
-       __u8 tx_receiver[6];    /* TX Frame Receiver address */
-       __le16 tx_fes_time_fb;  /* TX FES Time Fallback */
-       struct b43_plcp_hdr6 rts_plcp_fb;       /* RTS fallback PLCP */
-       __le16 rts_dur_fb;      /* RTS fallback duration */
-       struct b43_plcp_hdr6 plcp_fb;   /* Fallback PLCP */
-       __le16 dur_fb;          /* Fallback duration */
-       __le16 mm_dur_time;     /* Unused */
-       __le16 mm_dur_time_fb;  /* Unused */
-       __le32 time_stamp;      /* Timestamp */
-        PAD_BYTES(2);
-       __le16 cookie;          /* TX frame cookie */
-       __le16 tx_status;       /* TX status */
-       struct b43_plcp_hdr6 rts_plcp;  /* RTS PLCP */
-       __u8 rts_frame[16];     /* The RTS frame (if used) */
-        PAD_BYTES(2);
-       struct b43_plcp_hdr6 plcp;      /* Main PLCP */
+       __le16 phy_ctl;                 /* PHY TX control */
+       __le16 phy_ctl1;                /* PHY TX control word 1 */
+       __le16 phy_ctl1_fb;             /* PHY TX control word 1 for fallback rates */
+       __le16 phy_ctl1_rts;            /* PHY TX control word 1 RTS */
+       __le16 phy_ctl1_rts_fb;         /* PHY TX control word 1 RTS for fallback rates */
+       __u8 phy_rate;                  /* PHY rate */
+       __u8 phy_rate_rts;              /* PHY rate for RTS/CTS */
+       __u8 extra_ft;                  /* Extra Frame Types */
+       __u8 chan_radio_code;           /* Channel Radio Code */
+       __u8 iv[16];                    /* Encryption IV */
+       __u8 tx_receiver[6];            /* TX Frame Receiver address */
+       __le16 tx_fes_time_fb;          /* TX FES Time Fallback */
+       struct b43_plcp_hdr6 rts_plcp_fb; /* RTS fallback PLCP header */
+       __le16 rts_dur_fb;              /* RTS fallback duration */
+       struct b43_plcp_hdr6 plcp_fb;   /* Fallback PLCP header */
+       __le16 dur_fb;                  /* Fallback duration */
+       __le16 mimo_modelen;            /* MIMO mode length */
+       __le16 mimo_ratelen_fb;         /* MIMO fallback rate length */
+       __le32 timeout;                 /* Timeout */
+
+       union {
+               /* The new r410 format. */
+               struct {
+                       __le16 mimo_antenna;            /* MIMO antenna select */
+                       __le16 preload_size;            /* Preload size */
+                       PAD_BYTES(2);
+                       __le16 cookie;                  /* TX frame cookie */
+                       __le16 tx_status;               /* TX status */
+                       struct b43_plcp_hdr6 rts_plcp;  /* RTS PLCP header */
+                       __u8 rts_frame[16];             /* The RTS frame (if used) */
+                       PAD_BYTES(2);
+                       struct b43_plcp_hdr6 plcp;      /* Main PLCP header */
+               } new_format __attribute__ ((__packed__));
+
+               /* The old r351 format. */
+               struct {
+                       PAD_BYTES(2);
+                       __le16 cookie;                  /* TX frame cookie */
+                       __le16 tx_status;               /* TX status */
+                       struct b43_plcp_hdr6 rts_plcp;  /* RTS PLCP header */
+                       __u8 rts_frame[16];             /* The RTS frame (if used) */
+                       PAD_BYTES(2);
+                       struct b43_plcp_hdr6 plcp;      /* Main PLCP header */
+               } old_format __attribute__ ((__packed__));
+
+       } __attribute__ ((__packed__));
 } __attribute__ ((__packed__));
 
 /* MAC TX control */
-#define B43_TX4_MAC_KEYIDX             0x0FF00000      /* Security key index */
-#define B43_TX4_MAC_KEYIDX_SHIFT       20
-#define B43_TX4_MAC_KEYALG             0x00070000      /* Security key algorithm */
-#define B43_TX4_MAC_KEYALG_SHIFT       16
-#define B43_TX4_MAC_LIFETIME   0x00001000
-#define B43_TX4_MAC_FRAMEBURST 0x00000800
-#define B43_TX4_MAC_SENDCTS            0x00000400
-#define B43_TX4_MAC_AMPDU              0x00000300
-#define B43_TX4_MAC_AMPDU_SHIFT        8
-#define B43_TX4_MAC_5GHZ               0x00000080
-#define B43_TX4_MAC_IGNPMQ             0x00000020
-#define B43_TX4_MAC_HWSEQ              0x00000010      /* Use Hardware Sequence Number */
-#define B43_TX4_MAC_STMSDU             0x00000008      /* Start MSDU */
-#define B43_TX4_MAC_SENDRTS            0x00000004
-#define B43_TX4_MAC_LONGFRAME  0x00000002
-#define B43_TX4_MAC_ACK                0x00000001
+#define B43_TXH_MAC_USEFBR             0x10000000 /* Use fallback rate for this AMPDU */
+#define B43_TXH_MAC_KEYIDX             0x0FF00000 /* Security key index */
+#define B43_TXH_MAC_KEYIDX_SHIFT       20
+#define B43_TXH_MAC_KEYALG             0x00070000 /* Security key algorithm */
+#define B43_TXH_MAC_KEYALG_SHIFT       16
+#define B43_TXH_MAC_AMIC               0x00008000 /* AMIC */
+#define B43_TXH_MAC_RIFS               0x00004000 /* Use RIFS */
+#define B43_TXH_MAC_LIFETIME           0x00002000 /* Lifetime */
+#define B43_TXH_MAC_FRAMEBURST         0x00001000 /* Frameburst */
+#define B43_TXH_MAC_SENDCTS            0x00000800 /* Send CTS-to-self */
+#define B43_TXH_MAC_AMPDU              0x00000600 /* AMPDU status */
+#define  B43_TXH_MAC_AMPDU_MPDU                0x00000000 /* Regular MPDU, not an AMPDU */
+#define  B43_TXH_MAC_AMPDU_FIRST       0x00000200 /* First MPDU or AMPDU */
+#define  B43_TXH_MAC_AMPDU_INTER       0x00000400 /* Intermediate MPDU or AMPDU */
+#define  B43_TXH_MAC_AMPDU_LAST                0x00000600 /* Last (or only) MPDU of AMPDU */
+#define B43_TXH_MAC_40MHZ              0x00000100 /* Use 40 MHz bandwidth */
+#define B43_TXH_MAC_5GHZ               0x00000080 /* 5GHz band */
+#define B43_TXH_MAC_DFCS               0x00000040 /* DFCS */
+#define B43_TXH_MAC_IGNPMQ             0x00000020 /* Ignore PMQ */
+#define B43_TXH_MAC_HWSEQ              0x00000010 /* Use Hardware Sequence Number */
+#define B43_TXH_MAC_STMSDU             0x00000008 /* Start MSDU */
+#define B43_TXH_MAC_SENDRTS            0x00000004 /* Send RTS */
+#define B43_TXH_MAC_LONGFRAME          0x00000002 /* Long frame */
+#define B43_TXH_MAC_ACK                        0x00000001 /* Immediate ACK */
 
 /* Extra Frame Types */
-#define B43_TX4_EFT_FBOFDM             0x0001  /* Data frame fallback rate type */
-#define B43_TX4_EFT_RTSOFDM            0x0004  /* RTS/CTS rate type */
-#define B43_TX4_EFT_RTSFBOFDM  0x0010  /* RTS/CTS fallback rate type */
+#define B43_TXH_EFT_FB                 0x03 /* Data frame fallback encoding */
+#define  B43_TXH_EFT_FB_CCK            0x00 /* CCK */
+#define  B43_TXH_EFT_FB_OFDM           0x01 /* OFDM */
+#define  B43_TXH_EFT_FB_EWC            0x02 /* EWC */
+#define  B43_TXH_EFT_FB_N              0x03 /* N */
+#define B43_TXH_EFT_RTS                        0x0C /* RTS/CTS encoding */
+#define  B43_TXH_EFT_RTS_CCK           0x00 /* CCK */
+#define  B43_TXH_EFT_RTS_OFDM          0x04 /* OFDM */
+#define  B43_TXH_EFT_RTS_EWC           0x08 /* EWC */
+#define  B43_TXH_EFT_RTS_N             0x0C /* N */
+#define B43_TXH_EFT_RTSFB              0x30 /* RTS/CTS fallback encoding */
+#define  B43_TXH_EFT_RTSFB_CCK         0x00 /* CCK */
+#define  B43_TXH_EFT_RTSFB_OFDM                0x10 /* OFDM */
+#define  B43_TXH_EFT_RTSFB_EWC         0x20 /* EWC */
+#define  B43_TXH_EFT_RTSFB_N           0x30 /* N */
 
 /* PHY TX control word */
-#define B43_TX4_PHY_OFDM               0x0001  /* Data frame rate type */
-#define B43_TX4_PHY_SHORTPRMBL 0x0010  /* Use short preamble */
-#define B43_TX4_PHY_ANT                0x03C0  /* Antenna selection */
-#define  B43_TX4_PHY_ANT0              0x0000  /* Use antenna 0 */
-#define  B43_TX4_PHY_ANT1              0x0100  /* Use antenna 1 */
-#define  B43_TX4_PHY_ANTLAST   0x0300  /* Use last used antenna */
+#define B43_TXH_PHY_ENC                        0x0003 /* Data frame encoding */
+#define  B43_TXH_PHY_ENC_CCK           0x0000 /* CCK */
+#define  B43_TXH_PHY_ENC_OFDM          0x0001 /* OFDM */
+#define  B43_TXH_PHY_ENC_EWC           0x0002 /* EWC */
+#define  B43_TXH_PHY_ENC_N             0x0003 /* N */
+#define B43_TXH_PHY_SHORTPRMBL         0x0010 /* Use short preamble */
+#define B43_TXH_PHY_ANT                        0x03C0 /* Antenna selection */
+#define  B43_TXH_PHY_ANT0              0x0000 /* Use antenna 0 */
+#define  B43_TXH_PHY_ANT1              0x0040 /* Use antenna 1 */
+#define  B43_TXH_PHY_ANT01AUTO         0x00C0 /* Use antenna 0/1 auto */
+#define  B43_TXH_PHY_ANT2              0x0100 /* Use antenna 2 */
+#define  B43_TXH_PHY_ANT3              0x0200 /* Use antenna 3 */
+#define B43_TXH_PHY_TXPWR              0xFC00 /* TX power */
+#define B43_TXH_PHY_TXPWR_SHIFT                10
+
+/* PHY TX control word 1 */
+#define B43_TXH_PHY1_BW                        0x0007 /* Bandwidth */
+#define  B43_TXH_PHY1_BW_10            0x0000 /* 10 MHz */
+#define  B43_TXH_PHY1_BW_10U           0x0001 /* 10 MHz upper */
+#define  B43_TXH_PHY1_BW_20            0x0002 /* 20 MHz */
+#define  B43_TXH_PHY1_BW_20U           0x0003 /* 20 MHz upper */
+#define  B43_TXH_PHY1_BW_40            0x0004 /* 40 MHz */
+#define  B43_TXH_PHY1_BW_40DUP         0x0005 /* 50 MHz duplicate */
+#define B43_TXH_PHY1_MODE              0x0038 /* Mode */
+#define  B43_TXH_PHY1_MODE_SISO                0x0000 /* SISO */
+#define  B43_TXH_PHY1_MODE_CDD         0x0008 /* CDD */
+#define  B43_TXH_PHY1_MODE_STBC                0x0010 /* STBC */
+#define  B43_TXH_PHY1_MODE_SDM         0x0018 /* SDM */
+#define B43_TXH_PHY1_CRATE             0x0700 /* Coding rate */
+#define  B43_TXH_PHY1_CRATE_1_2                0x0000 /* 1/2 */
+#define  B43_TXH_PHY1_CRATE_2_3                0x0100 /* 2/3 */
+#define  B43_TXH_PHY1_CRATE_3_4                0x0200 /* 3/4 */
+#define  B43_TXH_PHY1_CRATE_4_5                0x0300 /* 4/5 */
+#define  B43_TXH_PHY1_CRATE_5_6                0x0400 /* 5/6 */
+#define  B43_TXH_PHY1_CRATE_7_8                0x0600 /* 7/8 */
+#define B43_TXH_PHY1_MODUL             0x3800 /* Modulation scheme */
+#define  B43_TXH_PHY1_MODUL_BPSK       0x0000 /* BPSK */
+#define  B43_TXH_PHY1_MODUL_QPSK       0x0800 /* QPSK */
+#define  B43_TXH_PHY1_MODUL_QAM16      0x1000 /* QAM16 */
+#define  B43_TXH_PHY1_MODUL_QAM64      0x1800 /* QAM64 */
+#define  B43_TXH_PHY1_MODUL_QAM256     0x2000 /* QAM256 */
+
+
+/* r351 firmware compatibility stuff. */
+static inline
+bool b43_is_old_txhdr_format(struct b43_wldev *dev)
+{
+       return (dev->fw.rev <= 351);
+}
+
+static inline
+size_t b43_txhdr_size(struct b43_wldev *dev)
+{
+       if (b43_is_old_txhdr_format(dev))
+               return 100 + sizeof(struct b43_plcp_hdr6);
+       return 104 + sizeof(struct b43_plcp_hdr6);
+}
+
 
 void b43_generate_txhdr(struct b43_wldev *dev,
                        u8 * txhdr,
index 7e23ec23fc98b9b26d2a02d6b1f4f53c3bed5d05..6745579ba96dc74ab813cb9409f01d6b0e701e25 100644 (file)
@@ -34,6 +34,22 @@ config B43LEGACY_PCICORE_AUTOSELECT
        select SSB_DRIVER_PCICORE
        default y
 
+# LED support
+# This config option automatically enables b43legacy LEDS support,
+# if it's possible.
+config B43LEGACY_LEDS
+       bool
+       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
+       bool
+       depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY)
+       default y
+
 config B43LEGACY_DEBUG
        bool "Broadcom 43xx-legacy debugging"
        depends on B43LEGACY
index ec3a2482bbad26d922ba7f360401001548fe4cef..80cdb73bd140c4b42a37d464ce8f676211c5f612 100644 (file)
@@ -1,14 +1,19 @@
-obj-$(CONFIG_B43LEGACY) += b43legacy.o
-b43legacy-obj-$(CONFIG_B43LEGACY_DEBUG) += debugfs.o
+# b43legacy core
+b43legacy-y                            += main.o
+b43legacy-y                            += ilt.o
+b43legacy-y                            += phy.o
+b43legacy-y                            += radio.o
+b43legacy-y                            += sysfs.o
+b43legacy-y                            += xmit.o
+# b43 RFKILL button support
+b43legacy-$(CONFIG_B43LEGACY_RFKILL)   += rfkill.o
+# b43legacy LED support
+b43legacy-$(CONFIG_B43LEGACY_LEDS)     += leds.o
+# b43legacy debugging
+b43legacy-$(CONFIG_B43LEGACY_DEBUG)    += debugfs.o
+# b43legacy DMA and PIO
+b43legacy-$(CONFIG_B43LEGACY_DMA)      += dma.o
+b43legacy-$(CONFIG_B43LEGACY_PIO)      += pio.o
 
-b43legacy-obj-$(CONFIG_B43LEGACY_DMA) += dma.o
-b43legacy-obj-$(CONFIG_B43LEGACY_PIO) += pio.o
+obj-$(CONFIG_B43LEGACY)                        += b43legacy.o
 
-b43legacy-objs := main.o \
-               ilt.o \
-               leds.o \
-               phy.o \
-               radio.o \
-               sysfs.o \
-               xmit.o \
-               $(b43legacy-obj-y)
index afe145cec06757c70844e2c967ae4c946acc21b7..93419adb925e41454bf369e944eb536b3581ceb6 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "debugfs.h"
 #include "leds.h"
+#include "rfkill.h"
 #include "phy.h"
 
 
 #define B43legacy_DEFAULT_SHORT_RETRY_LIMIT    7
 #define B43legacy_DEFAULT_LONG_RETRY_LIMIT     4
 
+#define B43legacy_PHY_TX_BADNESS_LIMIT         1000
+
 /* Max size of a security key */
 #define B43legacy_SEC_KEYSIZE          16
 /* Security algorithms. */
@@ -412,7 +415,6 @@ struct b43legacy_phy {
        u8 calibrated:1;
        u8 radio_rev;           /* Radio revision */
 
-       bool locked;            /* Only used in b43legacy_phy_{un}lock() */
        bool dyn_tssi_tbl;      /* tssi2dbm is kmalloc()ed. */
 
        /* ACI (adjacent channel interference) flags. */
@@ -455,11 +457,6 @@ struct b43legacy_phy {
        s16 lna_gain;           /* LNA */
        s16 pga_gain;           /* PGA */
 
-       /* PHY lock for core.rev < 3
-        * This lock is only used by b43legacy_phy_{un}lock()
-        */
-       spinlock_t lock;
-
        /* Desired TX power level (in dBm). This is set by the user and
         * adjusted in b43legacy_phy_xmitpower(). */
        u8 power_level;
@@ -483,9 +480,6 @@ struct b43legacy_phy {
                u16 txpwr_offset;
        };
 
-#ifdef CONFIG_B43LEGACY_DEBUG
-       bool manual_txpower_control; /* Manual TX-power control enabled? */
-#endif
        /* Current Interference Mitigation mode */
        int interfmode;
        /* Stack of saved values from the Interference Mitigation code.
@@ -510,6 +504,16 @@ struct b43legacy_phy {
        u16 lofcal;
 
        u16 initval;
+
+       /* PHY TX errors counter. */
+       atomic_t txerr_cnt;
+
+#if B43legacy_DEBUG
+       /* Manual TX-power control enabled? */
+       bool manual_txpower_control;
+       /* PHY registers locked by b43legacy_phy_lock()? */
+       bool phy_locked;
+#endif /* B43legacy_DEBUG */
 };
 
 /* Data structures for DMA transmission, per 80211 core. */
@@ -571,10 +575,7 @@ struct b43legacy_wl {
         * at a time. General information about this interface follows.
         */
 
-       /* Opaque ID of the operating interface from the ieee80211
-        * subsystem. Do not modify.
-        */
-       int if_id;
+       struct ieee80211_vif *vif;
        /* MAC address (can be NULL). */
        u8 mac_addr[ETH_ALEN];
        /* Current BSSID (can be NULL). */
@@ -592,9 +593,14 @@ struct b43legacy_wl {
        u8 rng_initialized;
        char rng_name[30 + 1];
 
+       /* The RF-kill button */
+       struct b43legacy_rfkill rfkill;
+
        /* List of all wireless devices on this chip */
        struct list_head devlist;
        u8 nr_devs;
+
+       bool radiotap_enabled;
 };
 
 /* Pointers to the firmware data and meta information about it. */
@@ -663,8 +669,11 @@ struct b43legacy_wldev {
        /* Various statistics about the physical device. */
        struct b43legacy_stats stats;
 
-#define B43legacy_NR_LEDS              4
-       struct b43legacy_led leds[B43legacy_NR_LEDS];
+       /* The device LEDs. */
+       struct b43legacy_led led_tx;
+       struct b43legacy_led led_rx;
+       struct b43legacy_led led_assoc;
+       struct b43legacy_led led_radio;
 
        /* Reason code of the last interrupt. */
        u32 irq_reason;
index 619b4534ef09b24a9c1512106c2002c83ad7354e..03ce0821a60eb86e9f327675c9069bc1b64ecb1b 100644 (file)
@@ -209,7 +209,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
        struct b43legacy_wldev *dev;
        struct b43legacy_debugfs_fops *dfops;
        struct b43legacy_dfs_file *dfile;
-       ssize_t ret = 0;
+       ssize_t uninitialized_var(ret);
        char *buf;
        const size_t bufsize = 1024 * 128;
        const size_t buforder = get_order(bufsize);
index 247fc780ffdbda62d934c39d45b329b3dca45432..a849078aea699e144354d4b68bcedb30d1b75877 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
+                    Stefano Brivio <stefano.brivio@polimi.it>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
                     Andreas Jaggi <andreas.jaggi@waterwave.ch>
index a584ea810502f8289fd961798e849e484581a26d..cacb786d97136498f645e10859cd7e9af8df4fee 100644 (file)
@@ -1,13 +1,13 @@
 /*
 
-  Broadcom B43legacy wireless driver
+  Broadcom B43 wireless driver
+  LED control
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
-                    Michael Buesch <mb@bu3sch.de>
-                    Danny van Dyk <kugelfang@gentoo.org>
-                    Andreas Jaggi <andreas.jaggi@waterwave.ch>
-  Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net>
+  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
+  Copyright (c) 2005-2007 Michael Buesch <mb@bu3sch.de>
+  Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
+  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
 
   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 "leds.h"
 #include "b43legacy.h"
-#include "main.h"
-
-static void b43legacy_led_changestate(struct b43legacy_led *led)
-{
-       struct b43legacy_wldev *dev = led->dev;
-       const int index = led->index;
-       u16 ledctl;
+#include "leds.h"
 
-       B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS));
-       B43legacy_WARN_ON(!led->blink_interval);
-       ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
-       ledctl ^= (1 << index);
-       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl);
-}
 
-static void b43legacy_led_blink(unsigned long d)
+static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index,
+                           bool activelow)
 {
-       struct b43legacy_led *led = (struct b43legacy_led *)d;
-       struct b43legacy_wldev *dev = led->dev;
+       struct b43legacy_wl *wl = dev->wl;
        unsigned long flags;
+       u16 ctl;
 
-       spin_lock_irqsave(&dev->wl->leds_lock, flags);
-       if (led->blink_interval) {
-               b43legacy_led_changestate(led);
-               mod_timer(&led->blink_timer, jiffies + led->blink_interval);
-       }
-       spin_unlock_irqrestore(&dev->wl->leds_lock, flags);
+       spin_lock_irqsave(&wl->leds_lock, flags);
+       ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
+       if (activelow)
+               ctl &= ~(1 << led_index);
+       else
+               ctl |= (1 << led_index);
+       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
+       spin_unlock_irqrestore(&wl->leds_lock, flags);
 }
 
-static void b43legacy_led_blink_start(struct b43legacy_led *led,
-                                     unsigned long interval)
+static void b43legacy_led_turn_off(struct b43legacy_wldev *dev, u8 led_index,
+                            bool activelow)
 {
-       if (led->blink_interval)
-               return;
-       led->blink_interval = interval;
-       b43legacy_led_changestate(led);
-       led->blink_timer.expires = jiffies + interval;
-       add_timer(&led->blink_timer);
+       struct b43legacy_wl *wl = dev->wl;
+       unsigned long flags;
+       u16 ctl;
+
+       spin_lock_irqsave(&wl->leds_lock, flags);
+       ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
+       if (activelow)
+               ctl |= (1 << led_index);
+       else
+               ctl &= ~(1 << led_index);
+       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl);
+       spin_unlock_irqrestore(&wl->leds_lock, flags);
 }
 
-static void b43legacy_led_blink_stop(struct b43legacy_led *led, int sync)
+/* Callback from the LED subsystem. */
+static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
+                                  enum led_brightness brightness)
 {
+       struct b43legacy_led *led = container_of(led_dev, struct b43legacy_led,
+                                   led_dev);
        struct b43legacy_wldev *dev = led->dev;
-       const int index = led->index;
-       u16 ledctl;
+       bool radio_enabled;
 
-       if (!led->blink_interval)
-               return;
-       if (unlikely(sync))
-               del_timer_sync(&led->blink_timer);
-       else
-               del_timer(&led->blink_timer);
-       led->blink_interval = 0;
+       /* Checking the radio-enabled status here is slightly racy,
+        * but we want to avoid the locking overhead and we don't care
+        * whether the LED has the wrong state for a second. */
+       radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);
 
-       /* Make sure the LED is turned off. */
-       B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS));
-       ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
-       if (led->activelow)
-               ledctl |= (1 << index);
+       if (brightness == LED_OFF || !radio_enabled)
+               b43legacy_led_turn_off(dev, led->index, led->activelow);
        else
-               ledctl &= ~(1 << index);
-       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl);
+               b43legacy_led_turn_on(dev, led->index, led->activelow);
 }
 
-static void b43legacy_led_init_hardcoded(struct b43legacy_wldev *dev,
-                                        struct b43legacy_led *led,
-                                        int led_index)
+static int b43legacy_register_led(struct b43legacy_wldev *dev,
+                                 struct b43legacy_led *led,
+                                 const char *name, char *default_trigger,
+                                 u8 led_index, bool activelow)
 {
-       struct ssb_bus *bus = dev->dev->bus;
+       int err;
+
+       b43legacy_led_turn_off(dev, led_index, activelow);
+       if (led->dev)
+               return -EEXIST;
+       if (!default_trigger)
+               return -EINVAL;
+       led->dev = dev;
+       led->index = led_index;
+       led->activelow = activelow;
+       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 = b43legacy_led_brightness_set;
+
+       err = led_classdev_register(dev->dev->dev, &led->led_dev);
+       if (err) {
+               b43legacywarn(dev->wl, "LEDs: Failed to register %s\n", name);
+               led->dev = NULL;
+               return err;
+       }
+       return 0;
+}
 
-       /* This function is called, if the behaviour (and activelow)
-        * information for a LED is missing in the SPROM.
-        * We hardcode the behaviour values for various devices here.
-        * Note that the B43legacy_LED_TEST_XXX behaviour values can
-        * be used to figure out which led is mapped to which index.
-        */
+static void b43legacy_unregister_led(struct b43legacy_led *led)
+{
+       if (!led->dev)
+               return;
+       led_classdev_unregister(&led->led_dev);
+       b43legacy_led_turn_off(led->dev, led->index, led->activelow);
+       led->dev = NULL;
+}
+
+static void b43legacy_map_led(struct b43legacy_wldev *dev,
+                       u8 led_index,
+                       enum b43legacy_led_behaviour behaviour,
+                       bool activelow)
+{
+       struct ieee80211_hw *hw = dev->wl->hw;
+       char name[B43legacy_LED_MAX_NAME_LEN + 1];
 
-       switch (led_index) {
-       case 0:
-               led->behaviour = B43legacy_LED_ACTIVITY;
-               led->activelow = 1;
-               if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
-                       led->behaviour = B43legacy_LED_RADIO_ALL;
+       /* Map the b43 specific LED behaviour value to the
+        * generic LED triggers. */
+       switch (behaviour) {
+       case B43legacy_LED_INACTIVE:
                break;
-       case 1:
-               led->behaviour = B43legacy_LED_RADIO_B;
-               if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
-                       led->behaviour = B43legacy_LED_ASSOC;
+       case B43legacy_LED_OFF:
+               b43legacy_led_turn_off(dev, led_index, activelow);
                break;
-       case 2:
-               led->behaviour = B43legacy_LED_RADIO_A;
+       case B43legacy_LED_ON:
+               b43legacy_led_turn_on(dev, led_index, activelow);
                break;
-       case 3:
-               led->behaviour = B43legacy_LED_OFF;
+       case B43legacy_LED_ACTIVITY:
+       case B43legacy_LED_TRANSFER:
+       case B43legacy_LED_APTRANSFER:
+               snprintf(name, sizeof(name),
+                        "b43legacy-%s:tx", wiphy_name(hw->wiphy));
+               b43legacy_register_led(dev, &dev->led_tx, name,
+                                ieee80211_get_tx_led_name(hw),
+                                led_index, activelow);
+               snprintf(name, sizeof(name),
+                        "b43legacy-%s:rx", wiphy_name(hw->wiphy));
+               b43legacy_register_led(dev, &dev->led_rx, name,
+                                ieee80211_get_rx_led_name(hw),
+                                led_index, activelow);
+               break;
+       case B43legacy_LED_RADIO_ALL:
+       case B43legacy_LED_RADIO_A:
+       case B43legacy_LED_RADIO_B:
+       case B43legacy_LED_MODE_BG:
+               snprintf(name, sizeof(name),
+                        "b43legacy-%s:radio", wiphy_name(hw->wiphy));
+               b43legacy_register_led(dev, &dev->led_radio, name,
+                                b43legacy_rfkill_led_name(dev),
+                                led_index, activelow);
+               /* Sync the RF-kill LED state with the switch state. */
+               if (dev->radio_hw_enable)
+                       b43legacy_led_turn_on(dev, led_index, activelow);
+               break;
+       case B43legacy_LED_WEIRD:
+       case B43legacy_LED_ASSOC:
+               snprintf(name, sizeof(name),
+                        "b43legacy-%s:assoc", wiphy_name(hw->wiphy));
+               b43legacy_register_led(dev, &dev->led_assoc, name,
+                                ieee80211_get_assoc_led_name(hw),
+                                led_index, activelow);
                break;
        default:
-               B43legacy_BUG_ON(1);
+               b43legacywarn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n",
+                       behaviour);
+               break;
        }
 }
 
-int b43legacy_leds_init(struct b43legacy_wldev *dev)
+void b43legacy_leds_init(struct b43legacy_wldev *dev)
 {
-       struct b43legacy_led *led;
+       struct ssb_bus *bus = dev->dev->bus;
        u8 sprom[4];
        int i;
-
-       sprom[0] = dev->dev->bus->sprom.r1.gpio0;
-       sprom[1] = dev->dev->bus->sprom.r1.gpio1;
-       sprom[2] = dev->dev->bus->sprom.r1.gpio2;
-       sprom[3] = dev->dev->bus->sprom.r1.gpio3;
-
-       for (i = 0; i < B43legacy_NR_LEDS; i++) {
-               led = &(dev->leds[i]);
-               led->index = i;
-               led->dev = dev;
-               setup_timer(&led->blink_timer,
-                           b43legacy_led_blink,
-                           (unsigned long)led);
-
-               if (sprom[i] == 0xFF)
-                       b43legacy_led_init_hardcoded(dev, led, i);
-               else {
-                       led->behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR;
-                       led->activelow = !!(sprom[i] &
-                                          B43legacy_LED_ACTIVELOW);
+       enum b43legacy_led_behaviour behaviour;
+       bool activelow;
+
+       sprom[0] = bus->sprom.gpio0;
+       sprom[1] = bus->sprom.gpio1;
+       sprom[2] = bus->sprom.gpio2;
+       sprom[3] = bus->sprom.gpio3;
+
+       for (i = 0; i < 4; i++) {
+               if (sprom[i] == 0xFF) {
+                       /* There is no LED information in the SPROM
+                        * for this LED. Hardcode it here. */
+                       activelow = 0;
+                       switch (i) {
+                       case 0:
+                               behaviour = B43legacy_LED_ACTIVITY;
+                               activelow = 1;
+                               if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
+                                       behaviour = B43legacy_LED_RADIO_ALL;
+                               break;
+                       case 1:
+                               behaviour = B43legacy_LED_RADIO_B;
+                               if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
+                                       behaviour = B43legacy_LED_ASSOC;
+                               break;
+                       case 2:
+                               behaviour = B43legacy_LED_RADIO_A;
+                               break;
+                       case 3:
+                               behaviour = B43legacy_LED_OFF;
+                               break;
+                       default:
+                               B43legacy_WARN_ON(1);
+                               return;
+                       }
+               } else {
+                       behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR;
+                       activelow = !!(sprom[i] & B43legacy_LED_ACTIVELOW);
                }
+               b43legacy_map_led(dev, i, behaviour, activelow);
        }
-
-       return 0;
 }
 
 void b43legacy_leds_exit(struct b43legacy_wldev *dev)
 {
-       struct b43legacy_led *led;
-       int i;
-
-       for (i = 0; i < B43legacy_NR_LEDS; i++) {
-               led = &(dev->leds[i]);
-               b43legacy_led_blink_stop(led, 1);
-       }
-       b43legacy_leds_switch_all(dev, 0);
-}
-
-void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity)
-{
-       struct b43legacy_led *led;
-       struct b43legacy_phy *phy = &dev->phy;
-       const int transferring = (jiffies - dev->stats.last_tx)
-                                 < B43legacy_LED_XFER_THRES;
-       int i;
-       int turn_on;
-       unsigned long interval = 0;
-       u16 ledctl;
-       unsigned long flags;
-       bool radio_enabled = (phy->radio_on && dev->radio_hw_enable);
-
-       spin_lock_irqsave(&dev->wl->leds_lock, flags);
-       ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
-       for (i = 0; i < B43legacy_NR_LEDS; i++) {
-               led = &(dev->leds[i]);
-
-               turn_on = 0;
-               switch (led->behaviour) {
-               case B43legacy_LED_INACTIVE:
-                       continue;
-               case B43legacy_LED_OFF:
-                       break;
-               case B43legacy_LED_ON:
-                       turn_on = 1;
-                       break;
-               case B43legacy_LED_ACTIVITY:
-                       turn_on = activity;
-                       break;
-               case B43legacy_LED_RADIO_ALL:
-                       turn_on = radio_enabled;
-                       break;
-               case B43legacy_LED_RADIO_A:
-                       break;
-               case B43legacy_LED_RADIO_B:
-                       turn_on = radio_enabled;
-                       break;
-               case B43legacy_LED_MODE_BG:
-                       if (phy->type == B43legacy_PHYTYPE_G && radio_enabled)
-                               turn_on = 1;
-                       break;
-               case B43legacy_LED_TRANSFER:
-                       if (transferring)
-                               b43legacy_led_blink_start(led,
-                                               B43legacy_LEDBLINK_MEDIUM);
-                       else
-                               b43legacy_led_blink_stop(led, 0);
-                       continue;
-               case B43legacy_LED_APTRANSFER:
-                       if (b43legacy_is_mode(dev->wl,
-                                               IEEE80211_IF_TYPE_AP)) {
-                               if (transferring) {
-                                       interval = B43legacy_LEDBLINK_FAST;
-                                       turn_on = 1;
-                               }
-                       } else {
-                               turn_on = 1;
-                               if (transferring)
-                                       interval = B43legacy_LEDBLINK_FAST;
-                               else
-                                       turn_on = 0;
-                       }
-                       if (turn_on)
-                               b43legacy_led_blink_start(led, interval);
-                       else
-                               b43legacy_led_blink_stop(led, 0);
-                       continue;
-               case B43legacy_LED_WEIRD:
-                       break;
-               case B43legacy_LED_ASSOC:
-                       turn_on = 1;
-#ifdef CONFIG_B43LEGACY_DEBUG
-               case B43legacy_LED_TEST_BLINKSLOW:
-                       b43legacy_led_blink_start(led, B43legacy_LEDBLINK_SLOW);
-                       continue;
-               case B43legacy_LED_TEST_BLINKMEDIUM:
-                       b43legacy_led_blink_start(led,
-                                                  B43legacy_LEDBLINK_MEDIUM);
-                       continue;
-               case B43legacy_LED_TEST_BLINKFAST:
-                       b43legacy_led_blink_start(led, B43legacy_LEDBLINK_FAST);
-                       continue;
-#endif /* CONFIG_B43LEGACY_DEBUG */
-               default:
-                       B43legacy_BUG_ON(1);
-               };
-
-               if (led->activelow)
-                       turn_on = !turn_on;
-               if (turn_on)
-                       ledctl |= (1 << i);
-               else
-                       ledctl &= ~(1 << i);
-       }
-       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl);
-       spin_unlock_irqrestore(&dev->wl->leds_lock, flags);
-}
-
-void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on)
-{
-       struct b43legacy_led *led;
-       u16 ledctl;
-       int i;
-       int bit_on;
-       unsigned long flags;
-
-       spin_lock_irqsave(&dev->wl->leds_lock, flags);
-       ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL);
-       for (i = 0; i < B43legacy_NR_LEDS; i++) {
-               led = &(dev->leds[i]);
-               if (led->behaviour == B43legacy_LED_INACTIVE)
-                       continue;
-               if (on)
-                       bit_on = led->activelow ? 0 : 1;
-               else
-                       bit_on = led->activelow ? 1 : 0;
-               if (bit_on)
-                       ledctl |= (1 << i);
-               else
-                       ledctl &= ~(1 << i);
-       }
-       b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl);
-       spin_unlock_irqrestore(&dev->wl->leds_lock, flags);
+       b43legacy_unregister_led(&dev->led_tx);
+       b43legacy_unregister_led(&dev->led_rx);
+       b43legacy_unregister_led(&dev->led_assoc);
+       b43legacy_unregister_led(&dev->led_radio);
 }
index b989f503e68421d2b2d5e9a8fd9789e60bcb8ef9..82167a90088f51a109dd3a8394b54931986cc25a 100644 (file)
@@ -1,30 +1,33 @@
 #ifndef B43legacy_LEDS_H_
 #define B43legacy_LEDS_H_
 
+struct b43legacy_wldev;
+
+#ifdef CONFIG_B43LEGACY_LEDS
+
 #include <linux/types.h>
-#include <linux/timer.h>
+#include <linux/leds.h>
 
 
+#define B43legacy_LED_MAX_NAME_LEN     31
+
 struct b43legacy_led {
-       u8 behaviour;
-       bool activelow;
-       /* Index in the "leds" array in b43legacy_wldev */
-       u8 index;
        struct b43legacy_wldev *dev;
-       struct timer_list blink_timer;
-       unsigned long blink_interval;
+       /* The LED class device */
+       struct led_classdev led_dev;
+       /* The index number of the LED. */
+       u8 index;
+       /* If activelow is true, the LED is ON if the
+        * bit is switched off. */
+       bool activelow;
+       /* The unique name string for this LED device. */
+       char name[B43legacy_LED_MAX_NAME_LEN + 1];
 };
 
-/* Delay between state changes when blinking in jiffies */
-#define B43legacy_LEDBLINK_SLOW                (HZ / 1)
-#define B43legacy_LEDBLINK_MEDIUM      (HZ / 4)
-#define B43legacy_LEDBLINK_FAST                (HZ / 8)
-
-#define B43legacy_LED_XFER_THRES       (HZ / 100)
-
 #define B43legacy_LED_BEHAVIOUR                0x7F
 #define B43legacy_LED_ACTIVELOW                0x80
-enum { /* LED behaviour values */
+/* LED behaviour values */
+enum b43legacy_led_behaviour {
        B43legacy_LED_OFF,
        B43legacy_LED_ON,
        B43legacy_LED_ACTIVITY,
@@ -37,20 +40,24 @@ enum { /* LED behaviour values */
        B43legacy_LED_WEIRD,
        B43legacy_LED_ASSOC,
        B43legacy_LED_INACTIVE,
-
-       /* Behaviour values for testing.
-        * With these values it is easier to figure out
-        * the real behaviour of leds, in case the SPROM
-        * is missing information.
-        */
-       B43legacy_LED_TEST_BLINKSLOW,
-       B43legacy_LED_TEST_BLINKMEDIUM,
-       B43legacy_LED_TEST_BLINKFAST,
 };
 
-int b43legacy_leds_init(struct b43legacy_wldev *dev);
+void b43legacy_leds_init(struct b43legacy_wldev *dev);
 void b43legacy_leds_exit(struct b43legacy_wldev *dev);
-void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity);
-void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on);
+
+#else /* CONFIG_B43EGACY_LEDS */
+/* LED support disabled */
+
+struct b43legacy_led {
+       /* empty */
+};
+
+static inline void b43legacy_leds_init(struct b43legacy_wldev *dev)
+{
+}
+static inline void b43legacy_leds_exit(struct b43legacy_wldev *dev)
+{
+}
+#endif /* CONFIG_B43LEGACY_LEDS */
 
 #endif /* B43legacy_LEDS_H_ */
index 32d5e1785bda6d6ace56935fa56e0bdfda9611ea..4ed4243feeaa7cf659910b40e8f6bccbdbe8c2db 100644 (file)
@@ -3,7 +3,7 @@
  *  Broadcom B43legacy wireless driver
  *
  *  Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
- *  Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
+ *  Copyright (c) 2005-2007 Stefano Brivio <stefano.brivio@polimi.it>
  *  Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
  *  Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
  *  Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -75,18 +75,6 @@ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
 MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames"
                 " Preemption");
 
-static int modparam_short_retry = B43legacy_DEFAULT_SHORT_RETRY_LIMIT;
-module_param_named(short_retry, modparam_short_retry, int, 0444);
-MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)");
-
-static int modparam_long_retry = B43legacy_DEFAULT_LONG_RETRY_LIMIT;
-module_param_named(long_retry, modparam_long_retry, int, 0444);
-MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)");
-
-static int modparam_noleds;
-module_param_named(noleds, modparam_noleds, int, 0444);
-MODULE_PARM_DESC(noleds, "Turn off all LED activity");
-
 static char modparam_fwpostfix[16];
 module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444);
 MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load.");
@@ -988,7 +976,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
        plcp.data = 0;
        b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
        dur = ieee80211_generic_frame_duration(dev->wl->hw,
-                                              dev->wl->if_id,
+                                              dev->wl->vif,
                                               size,
                                               B43legacy_RATE_TO_100KBPS(rate));
        /* Write PLCP in two parts and timing for packet transfer */
@@ -1054,7 +1042,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
        hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                         IEEE80211_STYPE_PROBE_RESP);
        dur = ieee80211_generic_frame_duration(dev->wl->hw,
-                                              dev->wl->if_id,
+                                              dev->wl->vif,
                                               *dest_size,
                                               B43legacy_RATE_TO_100KBPS(rate));
        hdr->duration_id = dur;
@@ -1217,7 +1205,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
        u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
        u32 merged_dma_reason = 0;
        int i;
-       int activity = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&dev->wl->irq_lock, flags);
@@ -1234,8 +1221,15 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
        if (unlikely(reason & B43legacy_IRQ_MAC_TXERR))
                b43legacyerr(dev->wl, "MAC transmission error\n");
 
-       if (unlikely(reason & B43legacy_IRQ_PHY_TXERR))
+       if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) {
                b43legacyerr(dev->wl, "PHY transmission error\n");
+               rmb();
+               if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) {
+                       b43legacyerr(dev->wl, "Too many PHY TX errors, "
+                                             "restarting the controller\n");
+                       b43legacy_controller_restart(dev, "PHY TX errors");
+               }
+       }
 
        if (unlikely(merged_dma_reason & (B43legacy_DMAIRQ_FATALMASK |
                                          B43legacy_DMAIRQ_NONFATALMASK))) {
@@ -1281,7 +1275,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
                        b43legacy_pio_rx(dev->pio.queue0);
                else
                        b43legacy_dma_rx(dev->dma.rx_ring0);
-               /* We intentionally don't set "activity" to 1, here. */
        }
        B43legacy_WARN_ON(dma_reason[1] & B43legacy_DMAIRQ_RX_DONE);
        B43legacy_WARN_ON(dma_reason[2] & B43legacy_DMAIRQ_RX_DONE);
@@ -1290,20 +1283,13 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
                        b43legacy_pio_rx(dev->pio.queue3);
                else
                        b43legacy_dma_rx(dev->dma.rx_ring3);
-               activity = 1;
        }
        B43legacy_WARN_ON(dma_reason[4] & B43legacy_DMAIRQ_RX_DONE);
        B43legacy_WARN_ON(dma_reason[5] & B43legacy_DMAIRQ_RX_DONE);
 
-       if (reason & B43legacy_IRQ_TX_OK) {
+       if (reason & B43legacy_IRQ_TX_OK)
                handle_irq_transmit_status(dev);
-               activity = 1;
-               /* TODO: In AP mode, this also causes sending of powersave
-                        responses. */
-       }
 
-       if (!modparam_noleds)
-               b43legacy_leds_update(dev, activity);
        b43legacy_interrupt_enable(dev, dev->irq_savedstate);
        mmiowb();
        spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
@@ -1755,7 +1741,6 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
                          B43legacy_MMIO_STATUS_BITFIELD)
                          & 0xFFFF3FFF);
 
-       b43legacy_leds_switch_all(dev, 0);
        b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
                          b43legacy_read16(dev,
                          B43legacy_MMIO_GPIO_MASK)
@@ -1767,7 +1752,7 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev)
                mask |= 0x0060;
                set |= 0x0060;
        }
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_PACTRL) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) {
                b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK,
                                  b43legacy_read16(dev,
                                  B43legacy_MMIO_GPIO_MASK)
@@ -1811,6 +1796,7 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
 {
        dev->mac_suspended--;
        B43legacy_WARN_ON(dev->mac_suspended < 0);
+       B43legacy_WARN_ON(irqs_disabled());
        if (dev->mac_suspended == 0) {
                b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD,
                                  b43legacy_read32(dev,
@@ -1822,6 +1808,11 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
                b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
                b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
                b43legacy_power_saving_ctl_bits(dev, -1, -1);
+
+               /* Re-enable IRQs. */
+               spin_lock_irq(&dev->wl->irq_lock);
+               b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+               spin_unlock_irq(&dev->wl->irq_lock);
        }
 }
 
@@ -1831,20 +1822,31 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
        int i;
        u32 tmp;
 
+       might_sleep();
+       B43legacy_WARN_ON(irqs_disabled());
        B43legacy_WARN_ON(dev->mac_suspended < 0);
+
        if (dev->mac_suspended == 0) {
+               /* 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);
+               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_STATUS_BITFIELD,
                                  b43legacy_read32(dev,
                                  B43legacy_MMIO_STATUS_BITFIELD)
                                  & ~B43legacy_SBF_MAC_ENABLED);
                b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
-               for (i = 10000; i; i--) {
+               for (i = 40; i; i--) {
                        tmp = b43legacy_read32(dev,
                                               B43legacy_MMIO_GEN_IRQ_REASON);
                        if (tmp & B43legacy_IRQ_MAC_SUSPENDED)
                                goto out;
-                       udelay(1);
+                       msleep(1);
                }
                b43legacyerr(dev->wl, "MAC suspend failed\n");
        }
@@ -1989,27 +1991,10 @@ static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev,
                              B43legacy_SHM_SH_PRPHYCTL, tmp);
 }
 
-/* Returns TRUE, if the radio is enabled in hardware. */
-static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
-{
-       if (dev->phy.rev >= 3) {
-               if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
-                     & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
-                       return 1;
-       } else {
-               if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO)
-                   & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK)
-                       return 1;
-       }
-       return 0;
-}
-
 /* This is the opposite of b43legacy_chip_init() */
 static void b43legacy_chip_exit(struct b43legacy_wldev *dev)
 {
-       b43legacy_radio_turn_off(dev);
-       if (!modparam_noleds)
-               b43legacy_leds_exit(dev);
+       b43legacy_radio_turn_off(dev, 1);
        b43legacy_gpio_cleanup(dev);
        /* firmware is released later */
 }
@@ -2039,9 +2024,10 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
        err = b43legacy_gpio_init(dev);
        if (err)
                goto out; /* firmware is released later */
+
        err = b43legacy_upload_initvals(dev);
        if (err)
-               goto err_gpio_cleanup;
+               goto err_gpio_clean;
        b43legacy_radio_turn_on(dev);
 
        b43legacy_write16(dev, 0x03E6, 0x0000);
@@ -2113,14 +2099,17 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
        b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,
                          dev->dev->bus->chipco.fast_pwrup_delay);
 
+       /* PHY TX errors counter. */
+       atomic_set(&phy->txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT);
+
        B43legacy_WARN_ON(err != 0);
        b43legacydbg(dev->wl, "Chip initialized\n");
 out:
        return err;
 
 err_radio_off:
-       b43legacy_radio_turn_off(dev);
-err_gpio_cleanup:
+       b43legacy_radio_turn_off(dev, 1);
+err_gpio_clean:
        b43legacy_gpio_cleanup(dev);
        goto out;
 }
@@ -2140,7 +2129,7 @@ static void b43legacy_periodic_every120sec(struct b43legacy_wldev *dev)
 static void b43legacy_periodic_every60sec(struct b43legacy_wldev *dev)
 {
        b43legacy_phy_lo_mark_all_unused(dev);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) {
                b43legacy_mac_suspend(dev);
                b43legacy_calc_nrssi_slope(dev);
                b43legacy_mac_enable(dev);
@@ -2156,20 +2145,9 @@ static void b43legacy_periodic_every30sec(struct b43legacy_wldev *dev)
 static void b43legacy_periodic_every15sec(struct b43legacy_wldev *dev)
 {
        b43legacy_phy_xmitpower(dev); /* FIXME: unless scanning? */
-}
-
-static void b43legacy_periodic_every1sec(struct b43legacy_wldev *dev)
-{
-       bool radio_hw_enable;
 
-       /* check if radio hardware enabled status changed */
-       radio_hw_enable = b43legacy_is_hw_radio_enabled(dev);
-       if (unlikely(dev->radio_hw_enable != radio_hw_enable)) {
-               dev->radio_hw_enable = radio_hw_enable;
-               b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n",
-                      (radio_hw_enable) ? "enabled" : "disabled");
-               b43legacy_leds_update(dev, 0);
-       }
+       atomic_set(&dev->phy.txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT);
+       wmb();
 }
 
 static void do_periodic_work(struct b43legacy_wldev *dev)
@@ -2177,94 +2155,45 @@ static void do_periodic_work(struct b43legacy_wldev *dev)
        unsigned int state;
 
        state = dev->periodic_state;
-       if (state % 120 == 0)
+       if (state % 8 == 0)
                b43legacy_periodic_every120sec(dev);
-       if (state % 60 == 0)
+       if (state % 4 == 0)
                b43legacy_periodic_every60sec(dev);
-       if (state % 30 == 0)
+       if (state % 2 == 0)
                b43legacy_periodic_every30sec(dev);
-       if (state % 15 == 0)
-               b43legacy_periodic_every15sec(dev);
-       b43legacy_periodic_every1sec(dev);
+       b43legacy_periodic_every15sec(dev);
 }
 
-/* Estimate a "Badness" value based on the periodic work
- * state-machine state. "Badness" is worse (bigger), if the
- * periodic work will take longer.
+/* Periodic work locking policy:
+ *     The whole periodic work handler is protected by
+ *     wl->mutex. If another lock is needed somewhere in the
+ *     pwork callchain, it's aquired in-place, where it's needed.
  */
-static int estimate_periodic_work_badness(unsigned int state)
-{
-       int badness = 0;
-
-       if (state % 120 == 0) /* every 120 sec */
-               badness += 10;
-       if (state % 60 == 0) /* every 60 sec */
-               badness += 5;
-       if (state % 30 == 0) /* every 30 sec */
-               badness += 1;
-       if (state % 15 == 0) /* every 15 sec */
-               badness += 1;
-
-#define BADNESS_LIMIT  4
-       return badness;
-}
-
 static void b43legacy_periodic_work_handler(struct work_struct *work)
 {
-       struct b43legacy_wldev *dev =
-                            container_of(work, struct b43legacy_wldev,
-                            periodic_work.work);
-       unsigned long flags;
+       struct b43legacy_wldev *dev = container_of(work, struct b43legacy_wldev,
+                                            periodic_work.work);
+       struct b43legacy_wl *wl = dev->wl;
        unsigned long delay;
-       u32 savedirqs = 0;
-       int badness;
 
-       mutex_lock(&dev->wl->mutex);
+       mutex_lock(&wl->mutex);
 
        if (unlikely(b43legacy_status(dev) != B43legacy_STAT_STARTED))
                goto out;
        if (b43legacy_debug(dev, B43legacy_DBG_PWORK_STOP))
                goto out_requeue;
 
-       badness = estimate_periodic_work_badness(dev->periodic_state);
-       if (badness > BADNESS_LIMIT) {
-               spin_lock_irqsave(&dev->wl->irq_lock, flags);
-               /* Suspend TX as we don't want to transmit packets while
-                * we recalibrate the hardware. */
-               b43legacy_tx_suspend(dev);
-               savedirqs = b43legacy_interrupt_disable(dev,
-                                                         B43legacy_IRQ_ALL);
-               /* Periodic work will take a long time, so we want it to
-                * be preemtible and release the spinlock. */
-               spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
-               b43legacy_synchronize_irq(dev);
-
-               do_periodic_work(dev);
+       do_periodic_work(dev);
 
-               spin_lock_irqsave(&dev->wl->irq_lock, flags);
-               b43legacy_interrupt_enable(dev, savedirqs);
-               b43legacy_tx_resume(dev);
-               mmiowb();
-               spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
-       } else {
-               /* Take the global driver lock. This will lock any operation. */
-               spin_lock_irqsave(&dev->wl->irq_lock, flags);
-
-               do_periodic_work(dev);
-
-               mmiowb();
-               spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
-       }
        dev->periodic_state++;
 out_requeue:
        if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST))
                delay = msecs_to_jiffies(50);
        else
-               delay = round_jiffies_relative(HZ);
-       queue_delayed_work(dev->wl->hw->workqueue,
-                          &dev->periodic_work, delay);
+               delay = round_jiffies_relative(HZ * 15);
+       queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
 out:
-       mutex_unlock(&dev->wl->mutex);
+       mutex_unlock(&wl->mutex);
 }
 
 static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev)
@@ -2366,9 +2295,9 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
        return err;
 }
 
-static int b43legacy_tx(struct ieee80211_hw *hw,
-                       struct sk_buff *skb,
-                       struct ieee80211_tx_control *ctl)
+static int b43legacy_op_tx(struct ieee80211_hw *hw,
+                          struct sk_buff *skb,
+                          struct ieee80211_tx_control *ctl)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -2392,15 +2321,15 @@ out:
        return NETDEV_TX_OK;
 }
 
-static int b43legacy_conf_tx(struct ieee80211_hw *hw,
-                            int queue,
-                            const struct ieee80211_tx_queue_params *params)
+static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,
+                               int queue,
+                               const struct ieee80211_tx_queue_params *params)
 {
        return 0;
 }
 
-static int b43legacy_get_tx_stats(struct ieee80211_hw *hw,
-                                 struct ieee80211_tx_queue_stats *stats)
+static int b43legacy_op_get_tx_stats(struct ieee80211_hw *hw,
+                                    struct ieee80211_tx_queue_stats *stats)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -2422,8 +2351,8 @@ out:
        return err;
 }
 
-static int b43legacy_get_stats(struct ieee80211_hw *hw,
-                              struct ieee80211_low_level_stats *stats)
+static int b43legacy_op_get_stats(struct ieee80211_hw *hw,
+                                 struct ieee80211_low_level_stats *stats)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        unsigned long flags;
@@ -2572,8 +2501,8 @@ static int b43legacy_antenna_from_ieee80211(u8 antenna)
        }
 }
 
-static int b43legacy_dev_config(struct ieee80211_hw *hw,
-                               struct ieee80211_conf *conf)
+static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
+                                  struct ieee80211_conf *conf)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev;
@@ -2634,6 +2563,8 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw,
                        b43legacy_short_slot_timing_disable(dev);
        }
 
+       dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+
        /* Adjust the desired TX power level. */
        if (conf->power_level != 0) {
                if (conf->power_level != phy->power_level) {
@@ -2660,7 +2591,7 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw,
                                              " physically off. Press the"
                                              " button to turn it on.\n");
                } else {
-                       b43legacy_radio_turn_off(dev);
+                       b43legacy_radio_turn_off(dev, 0);
                        b43legacyinfo(dev->wl, "Radio turned off by"
                                      " software\n");
                }
@@ -2676,37 +2607,11 @@ out_unlock_mutex:
        return err;
 }
 
-static int b43legacy_dev_set_key(struct ieee80211_hw *hw,
-                                enum set_key_cmd cmd,
-                                const u8 *local_addr, const u8 *addr,
-                                struct ieee80211_key_conf *key)
-{
-       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-       struct b43legacy_wldev *dev = wl->current_dev;
-       unsigned long flags;
-       int err = -EOPNOTSUPP;
-       DECLARE_MAC_BUF(mac);
-
-       if (!dev)
-               return -ENODEV;
-       mutex_lock(&wl->mutex);
-       spin_lock_irqsave(&wl->irq_lock, flags);
-
-       if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
-               err = -ENODEV;
-       }
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       mutex_unlock(&wl->mutex);
-       b43legacydbg(wl, "Using software based encryption for "
-                    "mac: %s\n", print_mac(mac, addr));
-       return err;
-}
-
-static void b43legacy_configure_filter(struct ieee80211_hw *hw,
-                                      unsigned int changed,
-                                      unsigned int *fflags,
-                                      int mc_count,
-                                      struct dev_addr_list *mc_list)
+static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
+                                         unsigned int changed,
+                                         unsigned int *fflags,
+                                         int mc_count,
+                                         struct dev_addr_list *mc_list)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -2741,9 +2646,9 @@ static void b43legacy_configure_filter(struct ieee80211_hw *hw,
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 }
 
-static int b43legacy_config_interface(struct ieee80211_hw *hw,
-                                     int if_id,
-                                     struct ieee80211_if_conf *conf)
+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;
@@ -2753,7 +2658,7 @@ static int b43legacy_config_interface(struct ieee80211_hw *hw,
                return -ENODEV;
        mutex_lock(&wl->mutex);
        spin_lock_irqsave(&wl->irq_lock, flags);
-       B43legacy_WARN_ON(wl->if_id != if_id);
+       B43legacy_WARN_ON(wl->vif != vif);
        if (conf->bssid)
                memcpy(wl->bssid, conf->bssid, ETH_ALEN);
        else
@@ -2942,8 +2847,6 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev,
        memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
        memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
 
-       /* Flags */
-       phy->locked = 0;
        /* Assume the radio is enabled. If it's not enabled, the state will
         * immediately get fixed on the first periodic work run. */
        dev->radio_hw_enable = 1;
@@ -2976,7 +2879,6 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev,
        phy->lofcal = 0xFFFF;
        phy->initval = 0xFFFF;
 
-       spin_lock_init(&phy->lock);
        phy->interfmode = B43legacy_INTERFMODE_NONE;
        phy->channel = 0xFF;
 }
@@ -3029,6 +2931,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
+/* Write the short and long frame retry limit values. */
+static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
+                                      unsigned int short_retry,
+                                      unsigned int long_retry)
+{
+       /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+        * the chip-internal counter. */
+       short_retry = min(short_retry, (unsigned int)0xF);
+       long_retry = min(long_retry, (unsigned int)0xF);
+
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
+       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
+}
+
 /* Shutdown a wireless core */
 /* Locking: wl->mutex */
 static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
@@ -3047,11 +2963,12 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev)
        cancel_work_sync(&dev->restart_work);
        mutex_lock(&wl->mutex);
 
+       b43legacy_leds_exit(dev);
        b43legacy_rng_exit(dev->wl);
        b43legacy_pio_free(dev);
        b43legacy_dma_free(dev);
        b43legacy_chip_exit(dev);
-       b43legacy_radio_turn_off(dev);
+       b43legacy_radio_turn_off(dev, 1);
        b43legacy_switch_analog(dev, 0);
        if (phy->dyn_tssi_tbl)
                kfree(phy->tssi2dbm);
@@ -3093,7 +3010,6 @@ static void prepare_phy_data_for_init(struct b43legacy_wldev *dev)
 
        /* Flags */
        phy->calibrated = 0;
-       phy->locked = 0;
 
        if (phy->_lo_pairs)
                memset(phy->_lo_pairs, 0,
@@ -3153,7 +3069,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
                hf |= B43legacy_HF_SYMW;
                if (phy->rev == 1)
                        hf |= B43legacy_HF_GDCW;
-               if (sprom->r1.boardflags_lo & B43legacy_BFL_PACTRL)
+               if (sprom->boardflags_lo & B43legacy_BFL_PACTRL)
                        hf |= B43legacy_HF_OFDMPABOOST;
        } else if (phy->type == B43legacy_PHYTYPE_B) {
                hf |= B43legacy_HF_SYMW;
@@ -3162,16 +3078,9 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
        }
        b43legacy_hf_write(dev, hf);
 
-       /* Short/Long Retry Limit.
-        * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing
-        * the chip-internal counter.
-        */
-       tmp = limit_value(modparam_short_retry, 0, 0xF);
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS,
-                             0x0006, tmp);
-       tmp = limit_value(modparam_long_retry, 0, 0xF);
-       b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS,
-                             0x0007, tmp);
+       b43legacy_set_retry_limits(dev,
+                                  B43legacy_DEFAULT_SHORT_RETRY_LIMIT,
+                                  B43legacy_DEFAULT_LONG_RETRY_LIMIT);
 
        b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
                              0x0044, 3);
@@ -3223,6 +3132,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev)
 
        b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED);
 
+       b43legacy_leds_init(dev);
 out:
        return err;
 
@@ -3239,8 +3149,8 @@ err_kfree_lo_control:
        return err;
 }
 
-static int b43legacy_add_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_if_init_conf *conf)
+static int b43legacy_op_add_interface(struct ieee80211_hw *hw,
+                                     struct ieee80211_if_init_conf *conf)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev;
@@ -3263,7 +3173,7 @@ static int b43legacy_add_interface(struct ieee80211_hw *hw,
 
        dev = wl->current_dev;
        wl->operating = 1;
-       wl->if_id = conf->if_id;
+       wl->vif = conf->vif;
        wl->if_type = conf->type;
        memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
 
@@ -3279,8 +3189,8 @@ static int b43legacy_add_interface(struct ieee80211_hw *hw,
        return err;
 }
 
-static void b43legacy_remove_interface(struct ieee80211_hw *hw,
-                                      struct ieee80211_if_init_conf *conf)
+static void b43legacy_op_remove_interface(struct ieee80211_hw *hw,
+                                         struct ieee80211_if_init_conf *conf)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
@@ -3291,7 +3201,8 @@ static void b43legacy_remove_interface(struct ieee80211_hw *hw,
        mutex_lock(&wl->mutex);
 
        B43legacy_WARN_ON(!wl->operating);
-       B43legacy_WARN_ON(wl->if_id != conf->if_id);
+       B43legacy_WARN_ON(wl->vif != conf->vif);
+       wl->vif = NULL;
 
        wl->operating = 0;
 
@@ -3304,13 +3215,17 @@ static void b43legacy_remove_interface(struct ieee80211_hw *hw,
        mutex_unlock(&wl->mutex);
 }
 
-static int b43legacy_start(struct ieee80211_hw *hw)
+static int b43legacy_op_start(struct ieee80211_hw *hw)
 {
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
        int did_init = 0;
        int err = 0;
 
+       /* First register RFkill.
+        * LEDs that are registered later depend on it. */
+       b43legacy_rfkill_init(dev);
+
        mutex_lock(&wl->mutex);
 
        if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
@@ -3335,11 +3250,13 @@ out_mutex_unlock:
        return err;
 }
 
-static void b43legacy_stop(struct ieee80211_hw *hw)
+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);
+
        mutex_lock(&wl->mutex);
        if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
                b43legacy_wireless_core_stop(dev);
@@ -3347,20 +3264,41 @@ static void b43legacy_stop(struct ieee80211_hw *hw)
        mutex_unlock(&wl->mutex);
 }
 
+static int b43legacy_op_set_retry_limit(struct ieee80211_hw *hw,
+                                       u32 short_retry_limit,
+                                       u32 long_retry_limit)
+{
+       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
+       struct b43legacy_wldev *dev;
+       int err = 0;
+
+       mutex_lock(&wl->mutex);
+       dev = wl->current_dev;
+       if (unlikely(!dev ||
+                    (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) {
+               err = -ENODEV;
+               goto out_unlock;
+       }
+       b43legacy_set_retry_limits(dev, short_retry_limit, long_retry_limit);
+out_unlock:
+       mutex_unlock(&wl->mutex);
+
+       return err;
+}
 
 static const struct ieee80211_ops b43legacy_hw_ops = {
-       .tx = b43legacy_tx,
-       .conf_tx = b43legacy_conf_tx,
-       .add_interface = b43legacy_add_interface,
-       .remove_interface = b43legacy_remove_interface,
-       .config = b43legacy_dev_config,
-       .config_interface = b43legacy_config_interface,
-       .set_key = b43legacy_dev_set_key,
-       .configure_filter = b43legacy_configure_filter,
-       .get_stats = b43legacy_get_stats,
-       .get_tx_stats = b43legacy_get_tx_stats,
-       .start = b43legacy_start,
-       .stop = b43legacy_stop,
+       .tx                     = b43legacy_op_tx,
+       .conf_tx                = b43legacy_op_conf_tx,
+       .add_interface          = b43legacy_op_add_interface,
+       .remove_interface       = b43legacy_op_remove_interface,
+       .config                 = b43legacy_op_dev_config,
+       .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_retry_limit        = b43legacy_op_set_retry_limit,
 };
 
 /* Hard-reset the chip. Do not call this directly.
@@ -3498,18 +3436,13 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)
        else
                have_bphy = 1;
 
-       /* Initialize LEDs structs. */
-       err = b43legacy_leds_init(dev);
-       if (err)
-               goto err_powerdown;
-
        dev->phy.gmode = (have_gphy || have_bphy);
        tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0;
        b43legacy_wireless_core_reset(dev, tmp);
 
        err = b43legacy_phy_versioning(dev);
        if (err)
-               goto err_leds_exit;
+               goto err_powerdown;
        /* Check if this device supports multiband. */
        if (!pdev ||
            (pdev->device != 0x4312 &&
@@ -3535,17 +3468,17 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)
 
        err = b43legacy_validate_chipaccess(dev);
        if (err)
-               goto err_leds_exit;
+               goto err_powerdown;
        err = b43legacy_setup_modes(dev, have_bphy, have_gphy);
        if (err)
-               goto err_leds_exit;
+               goto err_powerdown;
 
        /* Now set some default "current_dev" */
        if (!wl->current_dev)
                wl->current_dev = dev;
        INIT_WORK(&dev->restart_work, b43legacy_chip_reset);
 
-       b43legacy_radio_turn_off(dev);
+       b43legacy_radio_turn_off(dev, 1);
        b43legacy_switch_analog(dev, 0);
        ssb_device_disable(dev->dev, 0);
        ssb_bus_may_powerdown(bus);
@@ -3553,8 +3486,6 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev)
 out:
        return err;
 
-err_leds_exit:
-       b43legacy_leds_exit(dev);
 err_powerdown:
        ssb_bus_may_powerdown(bus);
        return err;
@@ -3637,12 +3568,7 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus)
        if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
            bus->boardinfo.type == 0x4E &&
            bus->boardinfo.rev > 0x40)
-               bus->sprom.r1.boardflags_lo |= B43legacy_BFL_PACTRL;
-
-       /* Convert Antennagain values to Q5.2 */
-       if (bus->sprom.r1.antenna_gain_bg == 0xFF)
-               bus->sprom.r1.antenna_gain_bg = 2; /* if unset, use 2 dBm */
-       bus->sprom.r1.antenna_gain_bg <<= 2;
+               bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
 }
 
 static void b43legacy_wireless_exit(struct ssb_device *dev,
@@ -3677,10 +3603,10 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
        hw->max_noise = -110;
        hw->queues = 1; /* FIXME: hardware has more queues */
        SET_IEEE80211_DEV(hw, dev->dev);
-       if (is_valid_ether_addr(sprom->r1.et1mac))
-               SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac);
+       if (is_valid_ether_addr(sprom->et1mac))
+               SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
        else
-               SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac);
+               SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
 
        /* Get and initialize struct b43legacy_wl */
        wl = hw_to_b43legacy_wl(hw);
index 68435c50d8e07fd05f1e3993501f19520ee6fc67..1f0e2e379b02cd5c11aeccd7daa84f70444a6055 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-  Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (c) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (c) 2005  Danny van Dyk <kugelfang@gentoo.org>
   Copyright (c) 2005  Andreas Jaggi <andreas.jaggi@waterwave.ch>
index 491e518e4aebe91f4683d434f42ac62defcf776b..c16febbdbf5d7da9023ec33b855bc198bd4ac206 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
+                    Stefano Brivio <stefano.brivio@polimi.it>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
      Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -91,40 +91,36 @@ void b43legacy_voluntary_preempt(void)
 #endif /* CONFIG_PREEMPT */
 }
 
-void b43legacy_raw_phy_lock(struct b43legacy_wldev *dev)
+/* Lock the PHY registers against concurrent access from the microcode.
+ * This lock is nonrecursive. */
+void b43legacy_phy_lock(struct b43legacy_wldev *dev)
 {
-       struct b43legacy_phy *phy = &dev->phy;
+#if B43legacy_DEBUG
+       B43legacy_WARN_ON(dev->phy.phy_locked);
+       dev->phy.phy_locked = 1;
+#endif
 
-       B43legacy_WARN_ON(!irqs_disabled());
-       if (b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD) == 0) {
-               phy->locked = 0;
-               return;
-       }
        if (dev->dev->id.revision < 3) {
                b43legacy_mac_suspend(dev);
-               spin_lock(&phy->lock);
        } else {
                if (!b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
                        b43legacy_power_saving_ctl_bits(dev, -1, 1);
        }
-       phy->locked = 1;
 }
 
-void b43legacy_raw_phy_unlock(struct b43legacy_wldev *dev)
+void b43legacy_phy_unlock(struct b43legacy_wldev *dev)
 {
-       struct b43legacy_phy *phy = &dev->phy;
+#if B43legacy_DEBUG
+       B43legacy_WARN_ON(!dev->phy.phy_locked);
+       dev->phy.phy_locked = 0;
+#endif
 
-       B43legacy_WARN_ON(!irqs_disabled());
        if (dev->dev->id.revision < 3) {
-               if (phy->locked) {
-                       spin_unlock(&phy->lock);
-                       b43legacy_mac_enable(dev);
-               }
+               b43legacy_mac_enable(dev);
        } else {
                if (!b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_AP))
                        b43legacy_power_saving_ctl_bits(dev, -1, -1);
        }
-       phy->locked = 0;
 }
 
 u16 b43legacy_phy_read(struct b43legacy_wldev *dev, u16 offset)
@@ -441,7 +437,7 @@ static void b43legacy_phy_inita(struct b43legacy_wldev *dev)
        might_sleep();
 
        b43legacy_phy_setupg(dev);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_PACTRL)
+       if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL)
                b43legacy_phy_write(dev, 0x046E, 0x03CF);
 }
 
@@ -543,7 +539,7 @@ static void b43legacy_phy_initb4(struct b43legacy_wldev *dev)
        if (phy->radio_ver == 0x2050)
                b43legacy_phy_write(dev, 0x002A, 0x88C2);
        b43legacy_radio_set_txpower_bg(dev, 0xFFFF, 0xFFFF, 0xFFFF);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) {
                b43legacy_calc_nrssi_slope(dev);
                b43legacy_calc_nrssi_threshold(dev);
        }
@@ -699,7 +695,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev)
                b43legacy_radio_write16(dev, 0x005A, 0x0088);
                b43legacy_radio_write16(dev, 0x005B, 0x006B);
                b43legacy_radio_write16(dev, 0x005C, 0x000F);
-               if (dev->dev->bus->sprom.r1.boardflags_lo & 0x8000) {
+               if (dev->dev->bus->sprom.boardflags_lo & 0x8000) {
                        b43legacy_radio_write16(dev, 0x005D, 0x00FA);
                        b43legacy_radio_write16(dev, 0x005E, 0x00D8);
                } else {
@@ -797,7 +793,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev)
                b43legacy_phy_write(dev, 0x0062, 0x0007);
                b43legacy_radio_init2050(dev);
                b43legacy_phy_lo_g_measure(dev);
-               if (dev->dev->bus->sprom.r1.boardflags_lo &
+               if (dev->dev->bus->sprom.boardflags_lo &
                    B43legacy_BFL_RSSI) {
                        b43legacy_calc_nrssi_slope(dev);
                        b43legacy_calc_nrssi_threshold(dev);
@@ -921,7 +917,7 @@ static void b43legacy_calc_loopback_gain(struct b43legacy_wldev *dev)
                            b43legacy_phy_read(dev, 0x0811) | 0x0100);
        b43legacy_phy_write(dev, 0x0812,
                            b43legacy_phy_read(dev, 0x0812) & 0xCFFF);
-       if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_EXTLNA) {
+       if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_EXTLNA) {
                if (phy->rev >= 7) {
                        b43legacy_phy_write(dev, 0x0811,
                                            b43legacy_phy_read(dev, 0x0811)
@@ -1072,7 +1068,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
                        b43legacy_phy_write(dev, 0x0036,
                                            (b43legacy_phy_read(dev, 0x0036)
                                             & 0x0FFF) | (phy->txctl2 << 12));
-               if (dev->dev->bus->sprom.r1.boardflags_lo &
+               if (dev->dev->bus->sprom.boardflags_lo &
                    B43legacy_BFL_PACTRL)
                        b43legacy_phy_write(dev, 0x002E, 0x8075);
                else
@@ -1087,7 +1083,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev)
                b43legacy_phy_write(dev, 0x080F, 0x8078);
        }
 
-       if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI)) {
+       if (!(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI)) {
                /* The specs state to update the NRSSI LT with
                 * the value 0x7FFFFFFF here. I think that is some weird
                 * compiler optimization in the original driver.
@@ -1789,7 +1785,6 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
        s16 baseband_att_delta;
        s16 radio_attenuation;
        s16 baseband_attenuation;
-       unsigned long phylock_flags;
 
        if (phy->savedpctlreg == 0xFFFF)
                return;
@@ -1838,9 +1833,9 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
 
        estimated_pwr = b43legacy_phy_estimate_power_out(dev, average);
 
-       max_pwr = dev->dev->bus->sprom.r1.maxpwr_bg;
+       max_pwr = dev->dev->bus->sprom.maxpwr_bg;
 
-       if ((dev->dev->bus->sprom.r1.boardflags_lo
+       if ((dev->dev->bus->sprom.boardflags_lo
             & B43legacy_BFL_PACTRL) &&
            (phy->type == B43legacy_PHYTYPE_G))
                max_pwr -= 0x3;
@@ -1848,7 +1843,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
                b43legacywarn(dev->wl, "Invalid max-TX-power value in SPROM."
                        "\n");
                max_pwr = 74; /* fake it */
-               dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr;
+               dev->dev->bus->sprom.maxpwr_bg = max_pwr;
        }
 
        /* Use regulatory information to get the maximum power.
@@ -1858,7 +1853,8 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
         * and 1.5 dBm (a safety factor??). The result is in Q5.2 format
         * which accounts for the factor of 4 */
 #define REG_MAX_PWR 20
-       max_pwr = min(REG_MAX_PWR * 4 - dev->dev->bus->sprom.r1.antenna_gain_bg
+       max_pwr = min(REG_MAX_PWR * 4
+                     - dev->dev->bus->sprom.antenna_gain.ghz24.a0
                      - 0x6, max_pwr);
 
        /* find the desired power in Q5.2 - power_level is in dBm
@@ -1918,7 +1914,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
                                txpower = 3;
                                radio_attenuation += 2;
                                baseband_attenuation += 2;
-                       } else if (dev->dev->bus->sprom.r1.boardflags_lo
+                       } else if (dev->dev->bus->sprom.boardflags_lo
                                   & B43legacy_BFL_PACTRL) {
                                baseband_attenuation += 4 *
                                                     (radio_attenuation - 2);
@@ -1943,13 +1939,13 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev)
        phy->bbatt = baseband_attenuation;
 
        /* Adjust the hardware */
-       b43legacy_phy_lock(dev, phylock_flags);
+       b43legacy_phy_lock(dev);
        b43legacy_radio_lock(dev);
        b43legacy_radio_set_txpower_bg(dev, baseband_attenuation,
                                       radio_attenuation, txpower);
        b43legacy_phy_lo_mark_current_used(dev);
        b43legacy_radio_unlock(dev);
-       b43legacy_phy_unlock(dev, phylock_flags);
+       b43legacy_phy_unlock(dev);
 }
 
 static inline
@@ -2000,9 +1996,9 @@ int b43legacy_phy_init_tssi2dbm_table(struct b43legacy_wldev *dev)
 
        B43legacy_WARN_ON(!(phy->type == B43legacy_PHYTYPE_B ||
                          phy->type == B43legacy_PHYTYPE_G));
-       pab0 = (s16)(dev->dev->bus->sprom.r1.pa0b0);
-       pab1 = (s16)(dev->dev->bus->sprom.r1.pa0b1);
-       pab2 = (s16)(dev->dev->bus->sprom.r1.pa0b2);
+       pab0 = (s16)(dev->dev->bus->sprom.pa0b0);
+       pab1 = (s16)(dev->dev->bus->sprom.pa0b1);
+       pab2 = (s16)(dev->dev->bus->sprom.pa0b2);
 
        if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) {
                phy->idle_tssi = 0x34;
@@ -2013,9 +2009,10 @@ int b43legacy_phy_init_tssi2dbm_table(struct b43legacy_wldev *dev)
        if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
            pab0 != -1 && pab1 != -1 && pab2 != -1) {
                /* The pabX values are set in SPROM. Use them. */
-               if ((s8)dev->dev->bus->sprom.r1.itssi_bg != 0 &&
-                   (s8)dev->dev->bus->sprom.r1.itssi_bg != -1)
-                       phy->idle_tssi = (s8)(dev->dev->bus->sprom.r1.itssi_bg);
+               if ((s8)dev->dev->bus->sprom.itssi_bg != 0 &&
+                   (s8)dev->dev->bus->sprom.itssi_bg != -1)
+                       phy->idle_tssi = (s8)(dev->dev->bus->sprom.
+                                         itssi_bg);
                else
                        phy->idle_tssi = 62;
                dyn_tssi2dbm = kmalloc(64, GFP_KERNEL);
index f11b4271714c1ad2e52b71bae36ba7b5a4bfc55c..ecbe409f9a9435dfe360d07a9b7ff0c2f67ebc32 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
+                    Stefano Brivio <stefano.brivio@polimi.it>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
                     Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -171,18 +171,8 @@ void b43legacy_put_attenuation_into_ranges(int *_bbatt, int *_rfatt);
 
 struct b43legacy_wldev;
 
-void b43legacy_raw_phy_lock(struct b43legacy_wldev *dev);
-#define b43legacy_phy_lock(bcm, flags)                 \
-       do {                                    \
-               local_irq_save(flags);          \
-               b43legacy_raw_phy_lock(bcm);    \
-       } while (0)
-void b43legacy_raw_phy_unlock(struct b43legacy_wldev *dev);
-#define b43legacy_phy_unlock(bcm, flags)       \
-       do {                                    \
-               b43legacy_raw_phy_unlock(bcm);  \
-               local_irq_restore(flags);       \
-       } while (0)
+void b43legacy_phy_lock(struct b43legacy_wldev *dev);
+void b43legacy_phy_unlock(struct b43legacy_wldev *dev);
 
 /* Card uses the loopback gain stuff */
 #define has_loopback_gain(phy)                  \
index a361dee664af59ebe7922955f23c6c0b379da3f4..318a270cf9b424d5b12fac7a6086c4f9b7f7ea3e 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
+                    Stefano Brivio <stefano.brivio@polimi.it>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
                     Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -92,6 +92,7 @@ void b43legacy_radio_lock(struct b43legacy_wldev *dev)
        u32 status;
 
        status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+       B43legacy_WARN_ON(status & B43legacy_SBF_RADIOREG_LOCK);
        status |= B43legacy_SBF_RADIOREG_LOCK;
        b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
        mmiowb();
@@ -104,6 +105,7 @@ void b43legacy_radio_unlock(struct b43legacy_wldev *dev)
 
        b43legacy_read16(dev, B43legacy_MMIO_PHY_VER); /* dummy read */
        status = b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD);
+       B43legacy_WARN_ON(!(status & B43legacy_SBF_RADIOREG_LOCK));
        status &= ~B43legacy_SBF_RADIOREG_LOCK;
        b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, status);
        mmiowb();
@@ -284,12 +286,11 @@ u8 b43legacy_radio_aci_scan(struct b43legacy_wldev *dev)
        unsigned int j;
        unsigned int start;
        unsigned int end;
-       unsigned long phylock_flags;
 
        if (!((phy->type == B43legacy_PHYTYPE_G) && (phy->rev > 0)))
                return 0;
 
-       b43legacy_phy_lock(dev, phylock_flags);
+       b43legacy_phy_lock(dev);
        b43legacy_radio_lock(dev);
        b43legacy_phy_write(dev, 0x0802,
                            b43legacy_phy_read(dev, 0x0802) & 0xFFFC);
@@ -323,7 +324,7 @@ u8 b43legacy_radio_aci_scan(struct b43legacy_wldev *dev)
                        ret[j] = 1;
        }
        b43legacy_radio_unlock(dev);
-       b43legacy_phy_unlock(dev, phylock_flags);
+       b43legacy_phy_unlock(dev);
 
        return ret[channel - 1];
 }
@@ -827,7 +828,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev)
        case B43legacy_PHYTYPE_B: {
                if (phy->radio_ver != 0x2050)
                        return;
-               if (!(dev->dev->bus->sprom.r1.boardflags_lo &
+               if (!(dev->dev->bus->sprom.boardflags_lo &
                    B43legacy_BFL_RSSI))
                        return;
 
@@ -857,7 +858,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev)
        }
        case B43legacy_PHYTYPE_G:
                if (!phy->gmode ||
-                   !(dev->dev->bus->sprom.r1.boardflags_lo &
+                   !(dev->dev->bus->sprom.boardflags_lo &
                    B43legacy_BFL_RSSI)) {
                        tmp16 = b43legacy_nrssi_hw_read(dev, 0x20);
                        if (tmp16 >= 0x20)
@@ -1406,7 +1407,7 @@ static u16 b43legacy_get_812_value(struct b43legacy_wldev *dev, u8 lpd)
        if (!phy->gmode)
                return 0;
        if (!has_loopback_gain(phy)) {
-               if (phy->rev < 7 || !(dev->dev->bus->sprom.r1.boardflags_lo
+               if (phy->rev < 7 || !(dev->dev->bus->sprom.boardflags_lo
                    & B43legacy_BFL_EXTLNA)) {
                        switch (lpd) {
                        case LPD(0, 1, 1):
@@ -1459,7 +1460,7 @@ static u16 b43legacy_get_812_value(struct b43legacy_wldev *dev, u8 lpd)
                }
 
                loop_or = (loop << 8) | extern_lna_control;
-               if (phy->rev >= 7 && dev->dev->bus->sprom.r1.boardflags_lo
+               if (phy->rev >= 7 && dev->dev->bus->sprom.boardflags_lo
                    & B43legacy_BFL_EXTLNA) {
                        if (extern_lna_control)
                                loop_or |= 0x8000;
@@ -1550,7 +1551,7 @@ u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev)
                                            b43legacy_get_812_value(dev,
                                            LPD(0, 1, 1)));
                        if (phy->rev < 7 ||
-                           !(dev->dev->bus->sprom.r1.boardflags_lo
+                           !(dev->dev->bus->sprom.boardflags_lo
                            & B43legacy_BFL_EXTLNA))
                                b43legacy_phy_write(dev, 0x0811, 0x01B3);
                        else
@@ -1786,7 +1787,7 @@ int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev,
                          channel2freq_bg(channel));
 
        if (channel == 14) {
-               if (dev->dev->bus->sprom.r1.country_code == 5)   /* JAPAN) */
+               if (dev->dev->bus->sprom.country_code == 5)   /* JAPAN) */
                        b43legacy_shm_write32(dev, B43legacy_SHM_SHARED,
                                              B43legacy_UCODEFLAGS_OFFSET,
                                              b43legacy_shm_read32(dev,
@@ -2113,21 +2114,25 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev)
                B43legacy_BUG_ON(1);
        }
        phy->radio_on = 1;
-       b43legacy_leds_update(dev, 0);
 }
 
-void b43legacy_radio_turn_off(struct b43legacy_wldev *dev)
+void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force)
 {
        struct b43legacy_phy *phy = &dev->phy;
 
+       if (!phy->radio_on && !force)
+               return;
+
        if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) {
                u16 rfover, rfoverval;
 
                rfover = b43legacy_phy_read(dev, B43legacy_PHY_RFOVER);
                rfoverval = b43legacy_phy_read(dev, B43legacy_PHY_RFOVERVAL);
-               phy->radio_off_context.rfover = rfover;
-               phy->radio_off_context.rfoverval = rfoverval;
-               phy->radio_off_context.valid = 1;
+               if (!force) {
+                       phy->radio_off_context.rfover = rfover;
+                       phy->radio_off_context.rfoverval = rfoverval;
+                       phy->radio_off_context.valid = 1;
+               }
                b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C);
                b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL,
                                    rfoverval & 0xFF73);
@@ -2135,7 +2140,6 @@ void b43legacy_radio_turn_off(struct b43legacy_wldev *dev)
                b43legacy_phy_write(dev, 0x0015, 0xAA00);
        phy->radio_on = 0;
        b43legacydbg(dev->wl, "Radio initialized\n");
-       b43legacy_leds_update(dev, 0);
 }
 
 void b43legacy_radio_clear_tssi(struct b43legacy_wldev *dev)
index 6c6a203439e196663ed6f65bdde60c80d50ab066..ec4de2811c52db0d460c549d5f98e74113a266db 100644 (file)
@@ -3,7 +3,7 @@
   Broadcom B43legacy wireless driver
 
   Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
-                    Stefano Brivio <st3@riseup.net>
+                    Stefano Brivio <stefano.brivio@polimi.it>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
                     Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -61,7 +61,7 @@ void b43legacy_radio_write16(struct b43legacy_wldev *dev, u16 offset, u16 val);
 u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev);
 
 void b43legacy_radio_turn_on(struct b43legacy_wldev *dev);
-void b43legacy_radio_turn_off(struct b43legacy_wldev *dev);
+void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force);
 
 int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, u8 channel,
                                  int synthetic_pu_workaround);
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
new file mode 100644 (file)
index 0000000..d178dfb
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+
+  Broadcom B43 wireless driver
+  RFKILL support
+
+  Copyright (c) 2007 Michael Buesch <mb@bu3sch.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, write to
+  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
+  Boston, MA 02110-1301, USA.
+
+*/
+
+#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)
+{
+       if (dev->phy.rev >= 3) {
+               if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
+                     & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK))
+                       return 1;
+       } else {
+               if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO)
+                   & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK)
+                       return 1;
+       }
+       return 0;
+}
+
+/* The poll callback for the hardware button. */
+static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
+{
+       struct b43legacy_wldev *dev = poll_dev->private;
+       struct b43legacy_wl *wl = dev->wl;
+       bool enabled;
+       bool report_change = 0;
+
+       mutex_lock(&wl->mutex);
+       if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {
+               mutex_unlock(&wl->mutex);
+               return;
+       }
+       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_ON:
+               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)
+                       b43legacy_radio_turn_on(dev);
+               break;
+       case RFKILL_STATE_OFF:
+               if (dev->phy.radio_on)
+                       b43legacy_radio_turn_off(dev, 0);
+               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_ON;
+       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;
+       }
+
+       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;
+}
+
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h
new file mode 100644 (file)
index 0000000..11150a8
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef B43legacy_RFKILL_H_
+#define B43legacy_RFKILL_H_
+
+struct b43legacy_wldev;
+
+#ifdef CONFIG_B43LEGACY_RFKILL
+
+#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 */
+
+#endif /* B43legacy_RFKILL_H_ */
index fa1e65687a63c65f541452dcff9a848e12ba89b1..e20c552442d53892bef644b8d4485dcc66972851 100644 (file)
@@ -5,7 +5,7 @@
   Transmission (TX/RX) related functions.
 
   Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
-  Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
+  Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it>
   Copyright (C) 2005, 2006 Michael Buesch <mb@bu3sch.de>
   Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
   Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
@@ -223,7 +223,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
        } else {
                int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb);
                txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
-                                                        dev->wl->if_id,
+                                                        txctl->vif,
                                                         fragment_len,
                                                         fbrate_base100kbps);
        }
@@ -290,6 +290,8 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
                mac_ctl |= B43legacy_TX4_MAC_STMSDU;
        if (rate_fb_ofdm)
                mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
+       if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT)
+               mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
 
        /* Generate the RTS or CTS-to-self frame */
        if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) ||
@@ -310,7 +312,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
 
                if (txctl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) {
                        ieee80211_ctstoself_get(dev->wl->hw,
-                                               dev->wl->if_id,
+                                               txctl->vif,
                                                fragment_data,
                                                fragment_len, txctl,
                                                (struct ieee80211_cts *)
@@ -319,7 +321,7 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
                        len = sizeof(struct ieee80211_cts);
                } else {
                        ieee80211_rts_get(dev->wl->hw,
-                                         dev->wl->if_id,
+                                         txctl->vif,
                                          fragment_data, fragment_len, txctl,
                                          (struct ieee80211_rts *)
                                          (txhdr->rts_frame));
@@ -335,7 +337,6 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev,
                                            len, rts_rate_fb);
                hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame);
                txhdr->rts_dur_fb = hdr->duration_id;
-               mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
        }
 
        /* Magic cookie */
@@ -378,7 +379,7 @@ static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev,
                        else
                                tmp -= 3;
                } else {
-                       if (dev->dev->bus->sprom.r1.boardflags_lo
+                       if (dev->dev->bus->sprom.boardflags_lo
                            & B43legacy_BFL_RSSI) {
                                if (in_rssi > 63)
                                        in_rssi = 63;
@@ -531,7 +532,24 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
        else
                status.rate = b43legacy_plcp_get_bitrate_cck(plcp);
        status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
-       status.mactime = mactime;
+
+       /*
+        * If monitors are present get full 64-bit timestamp. This
+        * code assumes we get to process the packet within 16 bits
+        * of timestamp, i.e. about 65 milliseconds after the PHY
+        * received the first symbol.
+        */
+       if (dev->wl->radiotap_enabled) {
+               u16 low_mactime_now;
+
+               b43legacy_tsf_read(dev, &status.mactime);
+               low_mactime_now = status.mactime;
+               status.mactime = status.mactime & ~0xFFFFULL;
+               status.mactime += mactime;
+               if (low_mactime_now <= mactime)
+                       status.mactime -= 0x10000;
+               status.flag |= RX_FLAG_TSFT;
+       }
 
        chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
                  B43legacy_RX_CHAN_ID_SHIFT;
index ce397e4284f4e450656315eb0a38e8444a79ed25..0159701e845638de2062859864c8b4b224642c9e 100644 (file)
@@ -1,12 +1,15 @@
 config BCM43XX
-       tristate "Broadcom BCM43xx wireless support"
+       tristate "Broadcom BCM43xx wireless support (DEPRECATED)"
        depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
        select WIRELESS_EXT
        select FW_LOADER
        select HW_RANDOM
        ---help---
-         This is an experimental driver for the Broadcom 43xx wireless chip,
-         found in the Apple Airport Extreme and various other devices.
+         This is an experimental driver for the Broadcom 43xx wireless
+         chip, found in the Apple Airport Extreme and various other
+         devices.  This driver is deprecated and will be removed
+         from the kernel in the near future.  It has been replaced
+         by the b43 and b43legacy drivers.
 
 config BCM43XX_DEBUG
        bool "Broadcom BCM43xx debugging (RECOMMENDED)"
index 5fdbf24d2443118880586f9c30cc2ab9c46ec741..2ebd2edf5862ad438ccb08ca956e1c286b1b0696 100644 (file)
@@ -481,9 +481,9 @@ struct bcm43xx_dmaring;
 struct bcm43xx_pioqueue;
 
 struct bcm43xx_initval {
-       u16 offset;
-       u16 size;
-       u32 value;
+       __be16 offset;
+       __be16 size;
+       __be32 value;
 } __attribute__((__packed__));
 
 /* Values for bcm430x_sprominfo.locale */
index 45683437a98d9d7de55ff22a9942a5be5cf08c76..b96a325b6ec87ff5fc70d94f3741e48235216545 100644 (file)
@@ -793,27 +793,27 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
 
        /* il0macaddr */
        value = sprom[BCM43xx_SPROM_IL0MACADDR + 0];
-       *(((u16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.il0macaddr) + 0) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_IL0MACADDR + 1];
-       *(((u16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.il0macaddr) + 1) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_IL0MACADDR + 2];
-       *(((u16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.il0macaddr) + 2) = cpu_to_be16(value);
 
        /* et0macaddr */
        value = sprom[BCM43xx_SPROM_ET0MACADDR + 0];
-       *(((u16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et0macaddr) + 0) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_ET0MACADDR + 1];
-       *(((u16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et0macaddr) + 1) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_ET0MACADDR + 2];
-       *(((u16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et0macaddr) + 2) = cpu_to_be16(value);
 
        /* et1macaddr */
        value = sprom[BCM43xx_SPROM_ET1MACADDR + 0];
-       *(((u16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et1macaddr) + 0) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_ET1MACADDR + 1];
-       *(((u16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et1macaddr) + 1) = cpu_to_be16(value);
        value = sprom[BCM43xx_SPROM_ET1MACADDR + 2];
-       *(((u16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
+       *(((__be16 *)bcm->sprom.et1macaddr) + 2) = cpu_to_be16(value);
 
        /* ethernet phy settings */
        value = sprom[BCM43xx_SPROM_ETHPHY];
@@ -1059,7 +1059,7 @@ void bcm43xx_dummy_transmission(struct bcm43xx_private *bcm)
 }
 
 static void key_write(struct bcm43xx_private *bcm,
-                     u8 index, u8 algorithm, const u16 *key)
+                     u8 index, u8 algorithm, const __le16 *key)
 {
        unsigned int i, basic_wep = 0;
        u32 offset;
@@ -1077,7 +1077,7 @@ static void key_write(struct bcm43xx_private *bcm,
        /* Write key payload, 8 little endian words */
        offset = bcm->security_offset + (index * BCM43xx_SEC_KEYSIZE);
        for (i = 0; i < (BCM43xx_SEC_KEYSIZE / sizeof(u16)); i++) {
-               value = cpu_to_le16(key[i]);
+               value = le16_to_cpu(key[i]);
                bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED,
                                    offset + (i * 2), value);
  
@@ -1091,7 +1091,7 @@ static void key_write(struct bcm43xx_private *bcm,
 }
 
 static void keymac_write(struct bcm43xx_private *bcm,
-                        u8 index, const u32 *addr)
+                        u8 index, const __be32 *addr)
 {
        /* for keys 0-3 there is no associated mac address */
        if (index < 4)
@@ -1102,11 +1102,11 @@ static void keymac_write(struct bcm43xx_private *bcm,
                bcm43xx_shm_write32(bcm,
                                    BCM43xx_SHM_HWMAC,
                                    index * 2,
-                                   cpu_to_be32(*addr));
+                                   be32_to_cpu(*addr));
                bcm43xx_shm_write16(bcm,
                                    BCM43xx_SHM_HWMAC,
                                    (index * 2) + 1,
-                                   cpu_to_be16(*((u16 *)(addr + 1))));
+                                   be16_to_cpu(*((__be16 *)(addr + 1))));
        } else {
                if (index < 8) {
                        TODO(); /* Put them in the macaddress filter */
@@ -1133,8 +1133,8 @@ static int bcm43xx_key_write(struct bcm43xx_private *bcm,
                return -EINVAL;
 
        memcpy(key, _key, key_len);
-       key_write(bcm, index, algorithm, (const u16 *)key);
-       keymac_write(bcm, index, (const u32 *)mac_addr);
+       key_write(bcm, index, algorithm, (const __le16 *)key);
+       keymac_write(bcm, index, (const __be32 *)mac_addr);
 
        bcm->key[index].algorithm = algorithm;
 
@@ -1143,7 +1143,7 @@ static int bcm43xx_key_write(struct bcm43xx_private *bcm,
 
 static void bcm43xx_clear_keys(struct bcm43xx_private *bcm)
 {
-       static const u32 zero_mac[2] = { 0 };
+       static const __be32 zero_mac[2] = { 0 };
        unsigned int i,j, nr_keys = 54;
        u16 offset;
 
@@ -2011,11 +2011,11 @@ err_noinitval:
 static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
 {
        struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
-       const u32 *data;
+       const __be32 *data;
        unsigned int i, len;
 
        /* Upload Microcode. */
-       data = (u32 *)(phy->ucode->data);
+       data = (__be32 *)(phy->ucode->data);
        len = phy->ucode->size / sizeof(u32);
        bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
        for (i = 0; i < len; i++) {
@@ -2025,7 +2025,7 @@ static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
        }
 
        /* Upload PCM data. */
-       data = (u32 *)(phy->pcm->data);
+       data = (__be32 *)(phy->pcm->data);
        len = phy->pcm->size / sizeof(u32);
        bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
        bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
index c60c1743ea067d4b7535bc62ec331b1b63ba33fc..76ab109cd2db8cb08a4e52acb4c75881429d0ed8 100644 (file)
@@ -68,7 +68,7 @@ static u16 tx_get_next_word(struct bcm43xx_txhdr *txhdr,
                source = packet;
                i -= sizeof(*txhdr);
        }
-       ret = le16_to_cpu( *((u16 *)(source + i)) );
+       ret = le16_to_cpu( *((__le16 *)(source + i)) );
        *pos += 2;
 
        return ret;
@@ -526,7 +526,7 @@ static void pio_rx_error(struct bcm43xx_pioqueue *queue,
 
 void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
 {
-       u16 preamble[21] = { 0 };
+       __le16 preamble[21] = { 0 };
        struct bcm43xx_rxhdr *rxhdr;
        u16 tmp, len, rxflags2;
        int i, preamble_readwords;
@@ -601,7 +601,7 @@ data_ready:
        skb_put(skb, len);
        for (i = 0; i < len - 1; i += 2) {
                tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
-               *((u16 *)(skb->data + i)) = cpu_to_le16(tmp);
+               *((__le16 *)(skb->data + i)) = cpu_to_le16(tmp);
        }
        if (len % 2) {
                tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
index 3e2462671690ac24169b436d4c16df288d07abf3..f79fe11f9e81e8422ffe375eb9db08495383c212 100644 (file)
@@ -122,10 +122,10 @@ static void bcm43xx_generate_plcp_hdr(struct bcm43xx_plcp_hdr4 *plcp,
        __u8 *raw = plcp->raw;
 
        if (ofdm_modulation) {
-               *data = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
+               u32 val = bcm43xx_plcp_get_ratecode_ofdm(bitrate);
                assert(!(octets & 0xF000));
-               *data |= (octets << 5);
-               *data = cpu_to_le32(*data);
+               val |= (octets << 5);
+               *data = cpu_to_le32(val);
        } else {
                u32 plen;
 
index cc1ee7f4f5f873dd26a44617eccc4962fe26a78a..d6b9362a3d5cd00f2d046f2afa86b071841b799c 100644 (file)
@@ -5,52 +5,52 @@
 #include <net/ieee80211_crypt.h>
 
 struct hostap_ieee80211_mgmt {
-       u16 frame_control;
-       u16 duration;
+       __le16 frame_control;
+       __le16 duration;
        u8 da[6];
        u8 sa[6];
        u8 bssid[6];
-       u16 seq_ctrl;
+       __le16 seq_ctrl;
        union {
                struct {
-                       u16 auth_alg;
-                       u16 auth_transaction;
-                       u16 status_code;
+                       __le16 auth_alg;
+                       __le16 auth_transaction;
+                       __le16 status_code;
                        /* possibly followed by Challenge text */
                        u8 variable[0];
                } __attribute__ ((packed)) auth;
                struct {
-                       u16 reason_code;
+                       __le16 reason_code;
                } __attribute__ ((packed)) deauth;
                struct {
-                       u16 capab_info;
-                       u16 listen_interval;
+                       __le16 capab_info;
+                       __le16 listen_interval;
                        /* followed by SSID and Supported rates */
                        u8 variable[0];
                } __attribute__ ((packed)) assoc_req;
                struct {
-                       u16 capab_info;
-                       u16 status_code;
-                       u16 aid;
+                       __le16 capab_info;
+                       __le16 status_code;
+                       __le16 aid;
                        /* followed by Supported rates */
                        u8 variable[0];
                } __attribute__ ((packed)) assoc_resp, reassoc_resp;
                struct {
-                       u16 capab_info;
-                       u16 listen_interval;
+                       __le16 capab_info;
+                       __le16 listen_interval;
                        u8 current_ap[6];
                        /* followed by SSID and Supported rates */
                        u8 variable[0];
                } __attribute__ ((packed)) reassoc_req;
                struct {
-                       u16 reason_code;
+                       __le16 reason_code;
                } __attribute__ ((packed)) disassoc;
                struct {
                } __attribute__ ((packed)) probe_req;
                struct {
                        u8 timestamp[8];
-                       u16 beacon_int;
-                       u16 capab_info;
+                       __le16 beacon_int;
+                       __le16 capab_info;
                        /* followed by some of SSID, Supported rates,
                         * FH Params, DS Params, CF Params, IBSS Params, TIM */
                        u8 variable[0];
index ef084df3d48eb87d78204c014795b75a7970467e..49978bdb4324df1b9a49c71d9a1cead05b48059d 100644 (file)
@@ -1039,7 +1039,7 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
                memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
        } else {
-               u16 len;
+               __be16 len;
                /* Leave Ethernet header part of hdr and full payload */
                skb_pull(skb, hdrlen);
                len = htons(skb->len);
index 6bbdb76b32df5420f687107af1e42560664a609b..ad040a3bb8a716d467c7d17f646dc5edfb392eec 100644 (file)
@@ -258,7 +258,7 @@ static void ap_handle_timer(unsigned long data)
                                 sta->addr, ap->tx_callback_poll);
        } else {
                int deauth = sta->timeout_next == STA_DEAUTH;
-               u16 resp;
+               __le16 resp;
                PDEBUG(DEBUG_AP, "%s: sending %s info to STA %s"
                       "(last=%lu, jiffies=%lu)\n",
                       local->dev->name,
@@ -300,13 +300,13 @@ void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
                            int resend)
 {
        u8 addr[ETH_ALEN];
-       u16 resp;
+       __le16 resp;
        int i;
 
        PDEBUG(DEBUG_AP, "%s: Deauthenticate all stations\n", dev->name);
        memset(addr, 0xff, ETH_ALEN);
 
-       resp = __constant_cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
+       resp = cpu_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
 
        /* deauth message sent; try to resend it few times; the message is
         * broadcast, so it may be delayed until next DTIM; there is not much
@@ -462,7 +462,7 @@ void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
 int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac)
 {
        struct sta_info *sta;
-       u16 resp;
+       __le16 resp;
 
        spin_lock_bh(&ap->sta_table_lock);
        sta = ap_get_sta(ap, mac);
@@ -628,7 +628,8 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
        struct ap_data *ap = data;
        struct net_device *dev = ap->local->dev;
        struct ieee80211_hdr_4addr *hdr;
-       u16 fc, *pos, auth_alg, auth_transaction, status;
+       u16 fc, auth_alg, auth_transaction, status;
+       __le16 *pos;
        struct sta_info *sta = NULL;
        char *txt = NULL;
        DECLARE_MAC_BUF(mac);
@@ -649,7 +650,7 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
                return;
        }
 
-       pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
+       pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        auth_alg = le16_to_cpu(*pos++);
        auth_transaction = le16_to_cpu(*pos++);
        status = le16_to_cpu(*pos++);
@@ -698,7 +699,8 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
        struct ap_data *ap = data;
        struct net_device *dev = ap->local->dev;
        struct ieee80211_hdr_4addr *hdr;
-       u16 fc, *pos, status;
+       u16 fc, status;
+       __le16 *pos;
        struct sta_info *sta = NULL;
        char *txt = NULL;
        DECLARE_MAC_BUF(mac);
@@ -736,7 +738,7 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
                goto done;
        }
 
-       pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
+       pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        pos++;
        status = le16_to_cpu(*pos++);
        if (status == WLAN_STATUS_SUCCESS) {
@@ -1298,7 +1300,8 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        struct ap_data *ap = local->ap;
        char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
        int len, olen;
-       u16 auth_alg, auth_transaction, status_code, *pos;
+       u16 auth_alg, auth_transaction, status_code;
+       __le16 *pos;
        u16 resp = WLAN_STATUS_SUCCESS, fc;
        struct sta_info *sta = NULL;
        struct ieee80211_crypt_data *crypt;
@@ -1332,7 +1335,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                crypt = local->crypt[idx];
        }
 
-       pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
+       pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        auth_alg = __le16_to_cpu(*pos);
        pos++;
        auth_transaction = __le16_to_cpu(*pos);
@@ -1465,7 +1468,7 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        }
 
  fail:
-       pos = (u16 *) body;
+       pos = (__le16 *) body;
        *pos = cpu_to_le16(auth_alg);
        pos++;
        *pos = cpu_to_le16(auth_transaction + 1);
@@ -1510,7 +1513,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char body[12], *p, *lpos;
        int len, left;
-       u16 *pos;
+       __le16 *pos;
        u16 resp = WLAN_STATUS_SUCCESS;
        struct sta_info *sta = NULL;
        int send_deauth = 0;
@@ -1540,7 +1543,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        atomic_inc(&sta->users);
        spin_unlock_bh(&local->ap->sta_table_lock);
 
-       pos = (u16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
+       pos = (__le16 *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        sta->capability = __le16_to_cpu(*pos);
        pos++; left -= 2;
        sta->listen_interval = __le16_to_cpu(*pos);
@@ -1636,25 +1639,24 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        }
 
  fail:
-       pos = (u16 *) body;
+       pos = (__le16 *) body;
 
        if (send_deauth) {
-               *pos = __constant_cpu_to_le16(
-                       WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
+               *pos = cpu_to_le16(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
                pos++;
        } else {
                /* FIX: CF-Pollable and CF-PollReq should be set to match the
                 * values in beacons/probe responses */
                /* FIX: how about privacy and WEP? */
                /* capability */
-               *pos = __constant_cpu_to_le16(WLAN_CAPABILITY_ESS);
+               *pos = cpu_to_le16(WLAN_CAPABILITY_ESS);
                pos++;
 
                /* status_code */
-               *pos = __cpu_to_le16(resp);
+               *pos = cpu_to_le16(resp);
                pos++;
 
-               *pos = __cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
+               *pos = cpu_to_le16((sta && sta->aid > 0 ? sta->aid : 0) |
                                     BIT(14) | BIT(15)); /* AID */
                pos++;
 
@@ -1681,7 +1683,7 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                                0x96 : 0x16;
                        (*lpos)++;
                }
-               pos = (u16 *) p;
+               pos = (__le16 *) p;
        }
 
        prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
@@ -1718,7 +1720,8 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
        int len;
-       u16 reason_code, *pos;
+       u16 reason_code;
+       __le16 *pos;
        struct sta_info *sta = NULL;
        DECLARE_MAC_BUF(mac);
 
@@ -1729,8 +1732,8 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
                return;
        }
 
-       pos = (u16 *) body;
-       reason_code = __le16_to_cpu(*pos);
+       pos = (__le16 *) body;
+       reason_code = le16_to_cpu(*pos);
 
        PDEBUG(DEBUG_AP, "%s: deauthentication: %s len=%d, "
               "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len,
@@ -1760,7 +1763,8 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
        int len;
-       u16 reason_code, *pos;
+       u16 reason_code;
+       __le16 *pos;
        struct sta_info *sta = NULL;
        DECLARE_MAC_BUF(mac);
 
@@ -1771,8 +1775,8 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
                return;
        }
 
-       pos = (u16 *) body;
-       reason_code = __le16_to_cpu(*pos);
+       pos = (__le16 *) body;
+       reason_code = le16_to_cpu(*pos);
 
        PDEBUG(DEBUG_AP, "%s: disassociation: %s len=%d, "
               "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len,
@@ -1817,7 +1821,7 @@ static void ap_handle_dropped_data(local_info_t *local,
 {
        struct net_device *dev = local->dev;
        struct sta_info *sta;
-       u16 reason;
+       __le16 reason;
 
        spin_lock_bh(&local->ap->sta_table_lock);
        sta = ap_get_sta(local->ap, hdr->addr2);
@@ -1831,8 +1835,7 @@ static void ap_handle_dropped_data(local_info_t *local,
                return;
        }
 
-       reason = __constant_cpu_to_le16(
-               WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
+       reason = cpu_to_le16(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
        prism2_send_mgmt(dev, IEEE80211_FTYPE_MGMT |
                         ((sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) ?
                          IEEE80211_STYPE_DEAUTH : IEEE80211_STYPE_DISASSOC),
@@ -1892,7 +1895,7 @@ static void handle_pspoll(local_info_t *local,
                return;
        }
 
-       aid = __le16_to_cpu(hdr->duration_id);
+       aid = le16_to_cpu(hdr->duration_id);
        if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) {
                PDEBUG(DEBUG_PS, "   PSPOLL and AID[15:14] not set\n");
                return;
@@ -1998,7 +2001,8 @@ static void handle_beacon(local_info_t *local, struct sk_buff *skb,
        struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
        char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
        int len, left;
-       u16 *pos, beacon_int, capability;
+       u16 beacon_int, capability;
+       __le16 *pos;
        char *ssid = NULL;
        unsigned char *supp_rates = NULL;
        int ssid_len = 0, supp_rates_len = 0;
@@ -2013,16 +2017,16 @@ static void handle_beacon(local_info_t *local, struct sk_buff *skb,
                return;
        }
 
-       pos = (u16 *) body;
+       pos = (__le16 *) body;
        left = len;
 
        /* Timestamp (8 octets) */
        pos += 4; left -= 8;
        /* Beacon interval (2 octets) */
-       beacon_int = __le16_to_cpu(*pos);
+       beacon_int = le16_to_cpu(*pos);
        pos++; left -= 2;
        /* Capability information (2 octets) */
-       capability = __le16_to_cpu(*pos);
+       capability = le16_to_cpu(*pos);
        pos++; left -= 2;
 
        if (local->ap->ap_policy != AP_OTHER_AP_EVEN_IBSS &&
index 517f8984514411bfddb0c602df00599bcdeb011c..b470c743c2d1923d5214fe0507ebb6d3fbf3aba2 100644 (file)
 
 struct hfa384x_comp_ident
 {
-       u16 id;
-       u16 variant;
-       u16 major;
-       u16 minor;
+       __le16 id;
+       __le16 variant;
+       __le16 major;
+       __le16 minor;
 } __attribute__ ((packed));
 
 #define HFA384X_COMP_ID_PRI 0x15
@@ -200,33 +200,33 @@ struct hfa384x_comp_ident
 
 struct hfa384x_sup_range
 {
-       u16 role;
-       u16 id;
-       u16 variant;
-       u16 bottom;
-       u16 top;
+       __le16 role;
+       __le16 id;
+       __le16 variant;
+       __le16 bottom;
+       __le16 top;
 } __attribute__ ((packed));
 
 
 struct hfa384x_build_id
 {
-       u16 pri_seq;
-       u16 sec_seq;
+       __le16 pri_seq;
+       __le16 sec_seq;
 } __attribute__ ((packed));
 
 /* FD01 - Download Buffer */
 struct hfa384x_rid_download_buffer
 {
-       u16 page;
-       u16 offset;
-       u16 length;
+       __le16 page;
+       __le16 offset;
+       __le16 length;
 } __attribute__ ((packed));
 
 /* BSS connection quality (RID FD43 range, RID FD51 dBm-normalized) */
 struct hfa384x_comms_quality {
-       u16 comm_qual; /* 0 .. 92 */
-       u16 signal_level; /* 27 .. 154 */
-       u16 noise_level; /* 27 .. 154 */
+       __le16 comm_qual; /* 0 .. 92 */
+       __le16 signal_level; /* 27 .. 154 */
+       __le16 noise_level; /* 27 .. 154 */
 } __attribute__ ((packed));
 
 
index 877d3bdd37a077239045fd522e8fc2af0c8c645e..07593803065ae142277cc33b276c0e64e9a7e339 100644 (file)
@@ -845,15 +845,13 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
                                         0x4b801a17),
        PCMCIA_MFC_DEVICE_PROD_ID12(0, "SanDisk", "ConnectPlus",
                                    0x7a954bd9, 0x74be00c6),
-       PCMCIA_DEVICE_PROD_ID1234(
+       PCMCIA_DEVICE_PROD_ID123(
                "Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P",
-               "Eval-RevA",
-               0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e),
+               0x4b801a17, 0x6345a0bf, 0xc9049a39),
        /* D-Link DWL-650 Rev. P1; manfid 0x000b, 0x7110 */
-       PCMCIA_DEVICE_PROD_ID1234(
+       PCMCIA_DEVICE_PROD_ID123(
                "D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10",
-               "A3",
-               0x1a424a1c, 0x6ea57632, 0xdd97a26b, 0x56b21f52),
+               0x1a424a1c, 0x6ea57632, 0xdd97a26b),
        PCMCIA_DEVICE_PROD_ID123(
                "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02",
                0xe6ec52ce, 0x08649af2, 0x4b74baa0),
@@ -890,10 +888,9 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
        PCMCIA_DEVICE_PROD_ID123(
                "corega", "WL PCCL-11", "ISL37300P",
                0xa21501a, 0x59868926, 0xc9049a39),
-       PCMCIA_DEVICE_PROD_ID1234(
+       PCMCIA_DEVICE_PROD_ID123(
                "The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P",
-               "RevA",
-               0xa5f472c2, 0x9c05598d, 0xc9049a39, 0x57a66194),
+               0xa5f472c2, 0x9c05598d, 0xc9049a39),
        PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
index c7678e67697dc435ebf721f13b253058aafb1bf0..89d3849abfe002f67a53ea2ea4111625f7e6358e 100644 (file)
@@ -100,7 +100,7 @@ static int hfa384x_from_aux(struct net_device *dev, unsigned int addr, int len,
 
 #ifdef PRISM2_PCI
        {
-               u16 *pos = (u16 *) buf;
+               __le16 *pos = (__le16 *) buf;
                while (len > 0) {
                        *pos++ = HFA384X_INW_DATA(HFA384X_AUXDATA_OFF);
                        len -= 2;
@@ -131,7 +131,7 @@ static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
 
 #ifdef PRISM2_PCI
        {
-               u16 *pos = (u16 *) buf;
+               __le16 *pos = (__le16 *) buf;
                while (len > 0) {
                        HFA384X_OUTW_DATA(*pos++, HFA384X_AUXDATA_OFF);
                        len -= 2;
@@ -147,7 +147,7 @@ static int hfa384x_to_aux(struct net_device *dev, unsigned int addr, int len,
 
 static int prism2_pda_ok(u8 *buf)
 {
-       u16 *pda = (u16 *) buf;
+       __le16 *pda = (__le16 *) buf;
        int pos;
        u16 len, pdr;
 
@@ -544,9 +544,9 @@ static int prism2_download_nonvolatile(local_info_t *local,
        struct net_device *dev = local->dev;
        int ret = 0, i;
        struct {
-               u16 page;
-               u16 offset;
-               u16 len;
+               __le16 page;
+               __le16 offset;
+               __le16 len;
        } dlbuffer;
        u32 bufaddr;
 
@@ -565,14 +565,12 @@ static int prism2_download_nonvolatile(local_info_t *local,
                goto out;
        }
 
-       dlbuffer.page = le16_to_cpu(dlbuffer.page);
-       dlbuffer.offset = le16_to_cpu(dlbuffer.offset);
-       dlbuffer.len = le16_to_cpu(dlbuffer.len);
-
        printk(KERN_DEBUG "Download buffer: %d bytes at 0x%04x:0x%04x\n",
-              dlbuffer.len, dlbuffer.page, dlbuffer.offset);
+              le16_to_cpu(dlbuffer.len),
+              le16_to_cpu(dlbuffer.page),
+              le16_to_cpu(dlbuffer.offset));
 
-       bufaddr = (dlbuffer.page << 7) + dlbuffer.offset;
+       bufaddr = (le16_to_cpu(dlbuffer.page) << 7) + le16_to_cpu(dlbuffer.offset);
 
        local->hw_downloading = 1;
 
index c592641e914e695d99aa1e408acae2501ca03496..7be68db6f3008db478943cafe61a04706a0b6271 100644 (file)
@@ -1075,7 +1075,7 @@ static int prism2_setup_rids(struct net_device *dev)
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 tmp;
+       __le16 tmp;
        int ret = 0;
 
        iface = netdev_priv(dev);
@@ -1084,11 +1084,11 @@ static int prism2_setup_rids(struct net_device *dev)
        hostap_set_word(dev, HFA384X_RID_TICKTIME, 2000);
 
        if (!local->fw_ap) {
-               tmp = hostap_get_porttype(local);
-               ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp);
+               u16 tmp1 = hostap_get_porttype(local);
+               ret = hostap_set_word(dev, HFA384X_RID_CNFPORTTYPE, tmp1);
                if (ret) {
                        printk("%s: Port type setting to %d failed\n",
-                              dev->name, tmp);
+                              dev->name, tmp1);
                        goto fail;
                }
        }
@@ -1117,7 +1117,7 @@ static int prism2_setup_rids(struct net_device *dev)
                ret = -EINVAL;
                goto fail;
        }
-       local->channel_mask = __le16_to_cpu(tmp);
+       local->channel_mask = le16_to_cpu(tmp);
 
        if (local->channel < 1 || local->channel > 14 ||
            !(local->channel_mask & (1 << (local->channel - 1)))) {
@@ -1852,7 +1852,7 @@ static int prism2_tx_80211(struct sk_buff *skb, struct net_device *dev)
        tx_control = local->tx_control;
        if (meta->tx_cb_idx) {
                tx_control |= HFA384X_TX_CTRL_TX_OK;
-               txdesc.sw_support = cpu_to_le16(meta->tx_cb_idx);
+               txdesc.sw_support = cpu_to_le32(meta->tx_cb_idx);
        }
        txdesc.tx_control = cpu_to_le16(tx_control);
        txdesc.tx_rate = meta->rate;
@@ -2190,7 +2190,7 @@ static void hostap_tx_callback(local_info_t *local,
                return;
        }
 
-       sw_support = le16_to_cpu(txdesc->sw_support);
+       sw_support = le32_to_cpu(txdesc->sw_support);
 
        spin_lock(&local->lock);
        cb = local->tx_callback;
@@ -2448,18 +2448,16 @@ static void prism2_info(local_info_t *local)
                goto out;
        }
 
-       le16_to_cpus(&info.len);
-       le16_to_cpus(&info.type);
-       left = (info.len - 1) * 2;
+       left = (le16_to_cpu(info.len) - 1) * 2;
 
-       if (info.len & 0x8000 || info.len == 0 || left > 2060) {
+       if (info.len & cpu_to_le16(0x8000) || info.len == 0 || left > 2060) {
                /* data register seems to give 0x8000 in some error cases even
                 * though busy bit is not set in offset register;
                 * in addition, length must be at least 1 due to type field */
                spin_unlock(&local->baplock);
                printk(KERN_DEBUG "%s: Received info frame with invalid "
-                      "length 0x%04x (type 0x%04x)\n", dev->name, info.len,
-                      info.type);
+                      "length 0x%04x (type 0x%04x)\n", dev->name,
+                      le16_to_cpu(info.len), le16_to_cpu(info.type));
                goto out;
        }
 
@@ -2476,8 +2474,8 @@ static void prism2_info(local_info_t *local)
        {
                spin_unlock(&local->baplock);
                printk(KERN_WARNING "%s: Info frame read failed (fid=0x%04x, "
-                      "len=0x%04x, type=0x%04x\n",
-                      dev->name, fid, info.len, info.type);
+                      "len=0x%04x, type=0x%04x\n", dev->name, fid,
+                      le16_to_cpu(info.len), le16_to_cpu(info.type));
                dev_kfree_skb(skb);
                goto out;
        }
@@ -2624,7 +2622,7 @@ static void prism2_check_magic(local_info_t *local)
 /* Called only from hardware IRQ */
 static irqreturn_t prism2_interrupt(int irq, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
+       struct net_device *dev = dev_id;
        struct hostap_interface *iface;
        local_info_t *local;
        int events = 0;
index 636f4b2382ea0c978d62b9d79e1d8cf2c24d5794..7cd3fb79230e51d12f5b226049e64a474d562eb3 100644 (file)
@@ -303,7 +303,7 @@ static void prism2_info_hostscanresults(local_info_t *local,
        int i, result_size, copy_len, new_count;
        struct hfa384x_hostscan_result *results, *prev;
        unsigned long flags;
-       u16 *pos;
+       __le16 *pos;
        u8 *ptr;
 
        wake_up_interruptible(&local->hostscan_wq);
@@ -314,7 +314,7 @@ static void prism2_info_hostscanresults(local_info_t *local,
                return;
        }
 
-       pos = (u16 *) buf;
+       pos = (__le16 *) buf;
        copy_len = result_size = le16_to_cpu(*pos);
        if (result_size == 0) {
                printk(KERN_DEBUG "%s: invalid result_size (0) in "
@@ -373,7 +373,7 @@ void hostap_info_process(local_info_t *local, struct sk_buff *skb)
        buf = skb->data + sizeof(*info);
        left = skb->len - sizeof(*info);
 
-       switch (info->type) {
+       switch (le16_to_cpu(info->type)) {
        case HFA384X_INFO_COMMTALLIES:
                prism2_info_commtallies(local, buf, left);
                break;
@@ -395,7 +395,8 @@ void hostap_info_process(local_info_t *local, struct sk_buff *skb)
 #ifndef PRISM2_NO_DEBUG
        default:
                PDEBUG(DEBUG_EXTRA, "%s: INFO - len=%d type=0x%04x\n",
-                      local->dev->name, info->len, info->type);
+                      local->dev->name, le16_to_cpu(info->len),
+                      le16_to_cpu(info->type));
                PDEBUG(DEBUG_EXTRA, "Unknown info frame:");
                for (i = 0; i < (left < 100 ? left : 100); i++)
                        PDEBUG2(DEBUG_EXTRA, " %02x", buf[i]);
index d8f5efcfcab96915d0f41ecfb22958ba556a3936..0ca0bfeb0ada33d44501ab4051d7d12b8007d53e 100644 (file)
@@ -84,7 +84,7 @@ static int prism2_get_datarates(struct net_device *dev, u8 *rates)
        if (len < 2)
                return 0;
 
-       val = le16_to_cpu(*(u16 *) buf); /* string length */
+       val = le16_to_cpu(*(__le16 *) buf); /* string length */
 
        if (len - 2 < val || val > 10)
                return 0;
@@ -496,7 +496,7 @@ static int prism2_ioctl_giwsens(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 val;
+       __le16 val;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -506,7 +506,7 @@ static int prism2_ioctl_giwsens(struct net_device *dev,
            0)
                return -EINVAL;
 
-       sens->value = __le16_to_cpu(val);
+       sens->value = le16_to_cpu(val);
        sens->fixed = 1;
 
        return 0;
@@ -561,17 +561,17 @@ static int prism2_ioctl_siwrts(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 val;
+       __le16 val;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        if (rts->disabled)
-               val = __constant_cpu_to_le16(2347);
+               val = cpu_to_le16(2347);
        else if (rts->value < 0 || rts->value > 2347)
                return -EINVAL;
        else
-               val = __cpu_to_le16(rts->value);
+               val = cpu_to_le16(rts->value);
 
        if (local->func->set_rid(dev, HFA384X_RID_RTSTHRESHOLD, &val, 2) ||
            local->func->reset_port(dev))
@@ -588,7 +588,7 @@ static int prism2_ioctl_giwrts(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 val;
+       __le16 val;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -597,7 +597,7 @@ static int prism2_ioctl_giwrts(struct net_device *dev,
            0)
                return -EINVAL;
 
-       rts->value = __le16_to_cpu(val);
+       rts->value = le16_to_cpu(val);
        rts->disabled = (rts->value == 2347);
        rts->fixed = 1;
 
@@ -611,17 +611,17 @@ static int prism2_ioctl_siwfrag(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 val;
+       __le16 val;
 
        iface = netdev_priv(dev);
        local = iface->local;
 
        if (rts->disabled)
-               val = __constant_cpu_to_le16(2346);
+               val = cpu_to_le16(2346);
        else if (rts->value < 256 || rts->value > 2346)
                return -EINVAL;
        else
-               val = __cpu_to_le16(rts->value & ~0x1); /* even numbers only */
+               val = cpu_to_le16(rts->value & ~0x1); /* even numbers only */
 
        local->fragm_threshold = rts->value & ~0x1;
        if (local->func->set_rid(dev, HFA384X_RID_FRAGMENTATIONTHRESHOLD, &val,
@@ -638,7 +638,7 @@ static int prism2_ioctl_giwfrag(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 val;
+       __le16 val;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -647,7 +647,7 @@ static int prism2_ioctl_giwfrag(struct net_device *dev,
                                 &val, 2, 1) < 0)
                return -EINVAL;
 
-       rts->value = __le16_to_cpu(val);
+       rts->value = le16_to_cpu(val);
        rts->disabled = (rts->value == 2346);
        rts->fixed = 1;
 
@@ -718,8 +718,8 @@ static int prism2_ioctl_siwap(struct net_device *dev,
        if (local->host_roaming == 1 && local->iw_mode == IW_MODE_INFRA) {
                struct hfa384x_scan_request scan_req;
                memset(&scan_req, 0, sizeof(scan_req));
-               scan_req.channel_list = __constant_cpu_to_le16(0x3fff);
-               scan_req.txrate = __constant_cpu_to_le16(HFA384X_RATES_1MBPS);
+               scan_req.channel_list = cpu_to_le16(0x3fff);
+               scan_req.txrate = cpu_to_le16(HFA384X_RATES_1MBPS);
                if (local->func->set_rid(dev, HFA384X_RID_SCANREQUEST,
                                         &scan_req, sizeof(scan_req))) {
                        printk(KERN_DEBUG "%s: ScanResults request failed - "
@@ -812,7 +812,7 @@ static int prism2_ioctl_giwnickn(struct net_device *dev,
 
        len = local->func->get_rid(dev, HFA384X_RID_CNFOWNNAME,
                                   &name, MAX_NAME_LEN + 2, 0);
-       val = __le16_to_cpu(*(u16 *) name);
+       val = le16_to_cpu(*(__le16 *) name);
        if (len > MAX_NAME_LEN + 2 || len < 0 || val > MAX_NAME_LEN)
                return -EOPNOTSUPP;
 
@@ -963,7 +963,7 @@ static int prism2_ioctl_giwessid(struct net_device *dev,
                memset(ssid, 0, sizeof(ssid));
                len = local->func->get_rid(dev, HFA384X_RID_CURRENTSSID,
                                           &ssid, MAX_SSID_LEN + 2, 0);
-               val = __le16_to_cpu(*(u16 *) ssid);
+               val = le16_to_cpu(*(__le16 *) ssid);
                if (len > MAX_SSID_LEN + 2 || len < 0 || val > MAX_SSID_LEN) {
                        return -EOPNOTSUPP;
                }
@@ -1089,6 +1089,9 @@ static int prism2_ioctl_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;
 
+       if (local->sta_fw_ver >= PRISM2_FW_VER(1,3,1))
+               range->scan_capa = IW_SCAN_CAPA_ESSID;
+
        return 0;
 }
 
@@ -1316,7 +1319,7 @@ static int prism2_ioctl_giwpower(struct net_device *dev,
 #else /* PRISM2_NO_STATION_MODES */
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 enable, mcast;
+       __le16 enable, mcast;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -1325,7 +1328,7 @@ static int prism2_ioctl_giwpower(struct net_device *dev,
            < 0)
                return -EINVAL;
 
-       if (!__le16_to_cpu(enable)) {
+       if (!le16_to_cpu(enable)) {
                rrq->disabled = 1;
                return 0;
        }
@@ -1333,29 +1336,29 @@ static int prism2_ioctl_giwpower(struct net_device *dev,
        rrq->disabled = 0;
 
        if ((rrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
-               u16 timeout;
+               __le16 timeout;
                if (local->func->get_rid(dev,
                                         HFA384X_RID_CNFPMHOLDOVERDURATION,
                                         &timeout, 2, 1) < 0)
                        return -EINVAL;
 
                rrq->flags = IW_POWER_TIMEOUT;
-               rrq->value = __le16_to_cpu(timeout) * 1024;
+               rrq->value = le16_to_cpu(timeout) * 1024;
        } else {
-               u16 period;
+               __le16 period;
                if (local->func->get_rid(dev, HFA384X_RID_CNFMAXSLEEPDURATION,
                                         &period, 2, 1) < 0)
                        return -EINVAL;
 
                rrq->flags = IW_POWER_PERIOD;
-               rrq->value = __le16_to_cpu(period) * 1024;
+               rrq->value = le16_to_cpu(period) * 1024;
        }
 
        if (local->func->get_rid(dev, HFA384X_RID_CNFMULTICASTRECEIVE, &mcast,
                                 2, 1) < 0)
                return -EINVAL;
 
-       if (__le16_to_cpu(mcast))
+       if (le16_to_cpu(mcast))
                rrq->flags |= IW_POWER_ALL_R;
        else
                rrq->flags |= IW_POWER_UNICAST_R;
@@ -1432,7 +1435,7 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       u16 shortretry, longretry, lifetime, altretry;
+       __le16 shortretry, longretry, lifetime, altretry;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -1445,15 +1448,11 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
                                 &lifetime, 2, 1) < 0)
                return -EINVAL;
 
-       le16_to_cpus(&shortretry);
-       le16_to_cpus(&longretry);
-       le16_to_cpus(&lifetime);
-
        rrq->disabled = 0;
 
        if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
                rrq->flags = IW_RETRY_LIFETIME;
-               rrq->value = lifetime * 1024;
+               rrq->value = le16_to_cpu(lifetime) * 1024;
        } else {
                if (local->manual_retry_count >= 0) {
                        rrq->flags = IW_RETRY_LIMIT;
@@ -1465,10 +1464,10 @@ static int prism2_ioctl_giwretry(struct net_device *dev,
                                rrq->value = local->manual_retry_count;
                } else if ((rrq->flags & IW_RETRY_LONG)) {
                        rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
-                       rrq->value = longretry;
+                       rrq->value = le16_to_cpu(longretry);
                } else {
                        rrq->flags = IW_RETRY_LIMIT;
-                       rrq->value = shortretry;
+                       rrq->value = le16_to_cpu(shortretry);
                        if (shortretry != longretry)
                                rrq->flags |= IW_RETRY_SHORT;
                }
@@ -3098,7 +3097,7 @@ static int prism2_set_genericelement(struct net_device *dev, u8 *elem,
        if (buf == NULL)
                return -ENOMEM;
 
-       *((u16 *) buf) = cpu_to_le16(len);
+       *((__le16 *) buf) = cpu_to_le16(len);
        memcpy(buf + 2, elem, len);
 
        kfree(local->generic_elem);
@@ -3758,7 +3757,7 @@ static int prism2_ioctl_siwmlme(struct net_device *dev,
        struct hostap_interface *iface = netdev_priv(dev);
        local_info_t *local = iface->local;
        struct iw_mlme *mlme = (struct iw_mlme *) extra;
-       u16 reason;
+       __le16 reason;
 
        reason = cpu_to_le16(mlme->reason_code);
 
@@ -3780,7 +3779,7 @@ static int prism2_ioctl_siwmlme(struct net_device *dev,
 static int prism2_ioctl_mlme(local_info_t *local,
                             struct prism2_hostapd_param *param)
 {
-       u16 reason;
+       __le16 reason;
 
        reason = cpu_to_le16(param->u.mlme.reason_code);
        switch (param->u.mlme.cmd) {
index 17c58e9bdad51178583f5d5844805e52f463415a..20d387f6658c4817010e9bf196020f1221257446 100644 (file)
@@ -296,7 +296,7 @@ int hostap_tx_callback_unregister(local_info_t *local, u16 idx)
 int hostap_set_word(struct net_device *dev, int rid, u16 val)
 {
        struct hostap_interface *iface;
-       u16 tmp = cpu_to_le16(val);
+       __le16 tmp = cpu_to_le16(val);
        iface = netdev_priv(dev);
        return iface->local->func->set_rid(dev, rid, &tmp, 2);
 }
@@ -1095,15 +1095,15 @@ int prism2_sta_deauth(local_info_t *local, u16 reason)
 {
        union iwreq_data wrqu;
        int ret;
+       __le16 val = cpu_to_le16(reason);
 
        if (local->iw_mode != IW_MODE_INFRA ||
            memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 ||
            memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0)
                return 0;
 
-       reason = cpu_to_le16(reason);
        ret = prism2_sta_send_mgmt(local, local->bssid, IEEE80211_STYPE_DEAUTH,
-                                  (u8 *) &reason, 2);
+                                  (u8 *) &val, 2);
        memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
        wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL);
        return ret;
index fc876ba185721533649f6fa3a31565afdd7e117c..3a874fc621d386a3c7ccfb160c54d443ec2c664d 100644 (file)
@@ -128,8 +128,8 @@ static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
 #define HFA384X_INB(a) hfa384x_inb_debug(dev, (a))
 #define HFA384X_OUTW(v,a) hfa384x_outw_debug(dev, (a), (v))
 #define HFA384X_INW(a) hfa384x_inw_debug(dev, (a))
-#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), cpu_to_le16((v)))
-#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw_debug(dev, (a)))
+#define HFA384X_OUTW_DATA(v,a) hfa384x_outw_debug(dev, (a), le16_to_cpu((v)))
+#define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw_debug(dev, (a)))
 
 #else /* PRISM2_IO_DEBUG */
 
@@ -173,8 +173,8 @@ static inline u16 hfa384x_inw(struct net_device *dev, int a)
 #define HFA384X_INB(a) hfa384x_inb(dev, (a))
 #define HFA384X_OUTW(v,a) hfa384x_outw(dev, (a), (v))
 #define HFA384X_INW(a) hfa384x_inw(dev, (a))
-#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), cpu_to_le16((v)))
-#define HFA384X_INW_DATA(a) (u16) le16_to_cpu(hfa384x_inw(dev, (a)))
+#define HFA384X_OUTW_DATA(v,a) hfa384x_outw(dev, (a), le16_to_cpu((v)))
+#define HFA384X_INW_DATA(a) cpu_to_le16(hfa384x_inw(dev, (a)))
 
 #endif /* PRISM2_IO_DEBUG */
 
@@ -183,10 +183,10 @@ static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
                            int len)
 {
        u16 d_off;
-       u16 *pos;
+       __le16 *pos;
 
        d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
-       pos = (u16 *) buf;
+       pos = (__le16 *) buf;
 
        for ( ; len > 1; len -= 2)
                *pos++ = HFA384X_INW_DATA(d_off);
@@ -201,10 +201,10 @@ static int hfa384x_from_bap(struct net_device *dev, u16 bap, void *buf,
 static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
 {
        u16 d_off;
-       u16 *pos;
+       __le16 *pos;
 
        d_off = (bap == 1) ? HFA384X_DATA1_OFF : HFA384X_DATA0_OFF;
-       pos = (u16 *) buf;
+       pos = (__le16 *) buf;
 
        for ( ; len > 1; len -= 2)
                HFA384X_OUTW_DATA(*pos++, d_off);
index e6516a186d0eadc2a752ac26fa32fb49dec20c5a..15445bce2ac7f2eccc2cc4b262674c72de843a10 100644 (file)
@@ -39,20 +39,20 @@ struct linux_wlan_ng_prism_hdr {
 } __attribute__ ((packed));
 
 struct linux_wlan_ng_cap_hdr {
-       u32 version;
-       u32 length;
-       u64 mactime;
-       u64 hosttime;
-       u32 phytype;
-       u32 channel;
-       u32 datarate;
-       u32 antenna;
-       u32 priority;
-       u32 ssi_type;
-       s32 ssi_signal;
-       s32 ssi_noise;
-       u32 preamble;
-       u32 encoding;
+       __be32 version;
+       __be32 length;
+       __be64 mactime;
+       __be64 hosttime;
+       __be32 phytype;
+       __be32 channel;
+       __be32 datarate;
+       __be32 antenna;
+       __be32 priority;
+       __be32 ssi_type;
+       __be32 ssi_signal;
+       __be32 ssi_noise;
+       __be32 preamble;
+       __be32 encoding;
 } __attribute__ ((packed));
 
 #define LWNG_CAP_DID_BASE   (4 | (1 << 6)) /* section 4, group 1 */
@@ -60,28 +60,28 @@ struct linux_wlan_ng_cap_hdr {
 
 struct hfa384x_rx_frame {
        /* HFA384X RX frame descriptor */
-       u16 status; /* HFA384X_RX_STATUS_ flags */
-       u32 time; /* timestamp, 1 microsecond resolution */
+       __le16 status; /* HFA384X_RX_STATUS_ flags */
+       __le32 time; /* timestamp, 1 microsecond resolution */
        u8 silence; /* 27 .. 154; seems to be 0 */
        u8 signal; /* 27 .. 154 */
        u8 rate; /* 10, 20, 55, or 110 */
        u8 rxflow;
-       u32 reserved;
+       __le32 reserved;
 
        /* 802.11 */
-       u16 frame_control;
-       u16 duration_id;
+       __le16 frame_control;
+       __le16 duration_id;
        u8 addr1[6];
        u8 addr2[6];
        u8 addr3[6];
-       u16 seq_ctrl;
+       __le16 seq_ctrl;
        u8 addr4[6];
-       u16 data_len;
+       __le16 data_len;
 
        /* 802.3 */
        u8 dst_addr[6];
        u8 src_addr[6];
-       u16 len;
+       __be16 len;
 
        /* followed by frame data; max 2304 bytes */
 } __attribute__ ((packed));
@@ -89,28 +89,28 @@ struct hfa384x_rx_frame {
 
 struct hfa384x_tx_frame {
        /* HFA384X TX frame descriptor */
-       u16 status; /* HFA384X_TX_STATUS_ flags */
-       u16 reserved1;
-       u16 reserved2;
-       u32 sw_support;
+       __le16 status; /* HFA384X_TX_STATUS_ flags */
+       __le16 reserved1;
+       __le16 reserved2;
+       __le32 sw_support;
        u8 retry_count; /* not yet implemented */
        u8 tx_rate; /* Host AP only; 0 = firmware, or 10, 20, 55, 110 */
-       u16 tx_control; /* HFA384X_TX_CTRL_ flags */
+       __le16 tx_control; /* HFA384X_TX_CTRL_ flags */
 
        /* 802.11 */
-       u16 frame_control; /* parts not used */
-       u16 duration_id;
+       __le16 frame_control; /* parts not used */
+       __le16 duration_id;
        u8 addr1[6];
        u8 addr2[6]; /* filled by firmware */
        u8 addr3[6];
-       u16 seq_ctrl; /* filled by firmware */
+       __le16 seq_ctrl; /* filled by firmware */
        u8 addr4[6];
-       u16 data_len;
+       __le16 data_len;
 
        /* 802.3 */
        u8 dst_addr[6];
        u8 src_addr[6];
-       u16 len;
+       __be16 len;
 
        /* followed by frame data; max 2304 bytes */
 } __attribute__ ((packed));
@@ -118,8 +118,8 @@ struct hfa384x_tx_frame {
 
 struct hfa384x_rid_hdr
 {
-       u16 len;
-       u16 rid;
+       __le16 len;
+       __le16 rid;
 } __attribute__ ((packed));
 
 
@@ -130,78 +130,78 @@ struct hfa384x_rid_hdr
 #define HFA384X_LEVEL_TO_dBm_sign(v) (v) * 100 / 255 - 100
 
 struct hfa384x_scan_request {
-       u16 channel_list;
-       u16 txrate; /* HFA384X_RATES_* */
+       __le16 channel_list;
+       __le16 txrate; /* HFA384X_RATES_* */
 } __attribute__ ((packed));
 
 struct hfa384x_hostscan_request {
-       u16 channel_list;
-       u16 txrate;
-       u16 target_ssid_len;
+       __le16 channel_list;
+       __le16 txrate;
+       __le16 target_ssid_len;
        u8 target_ssid[32];
 } __attribute__ ((packed));
 
 struct hfa384x_join_request {
        u8 bssid[6];
-       u16 channel;
+       __le16 channel;
 } __attribute__ ((packed));
 
 struct hfa384x_info_frame {
-       u16 len;
-       u16 type;
+       __le16 len;
+       __le16 type;
 } __attribute__ ((packed));
 
 struct hfa384x_comm_tallies {
-       u16 tx_unicast_frames;
-       u16 tx_multicast_frames;
-       u16 tx_fragments;
-       u16 tx_unicast_octets;
-       u16 tx_multicast_octets;
-       u16 tx_deferred_transmissions;
-       u16 tx_single_retry_frames;
-       u16 tx_multiple_retry_frames;
-       u16 tx_retry_limit_exceeded;
-       u16 tx_discards;
-       u16 rx_unicast_frames;
-       u16 rx_multicast_frames;
-       u16 rx_fragments;
-       u16 rx_unicast_octets;
-       u16 rx_multicast_octets;
-       u16 rx_fcs_errors;
-       u16 rx_discards_no_buffer;
-       u16 tx_discards_wrong_sa;
-       u16 rx_discards_wep_undecryptable;
-       u16 rx_message_in_msg_fragments;
-       u16 rx_message_in_bad_msg_fragments;
+       __le16 tx_unicast_frames;
+       __le16 tx_multicast_frames;
+       __le16 tx_fragments;
+       __le16 tx_unicast_octets;
+       __le16 tx_multicast_octets;
+       __le16 tx_deferred_transmissions;
+       __le16 tx_single_retry_frames;
+       __le16 tx_multiple_retry_frames;
+       __le16 tx_retry_limit_exceeded;
+       __le16 tx_discards;
+       __le16 rx_unicast_frames;
+       __le16 rx_multicast_frames;
+       __le16 rx_fragments;
+       __le16 rx_unicast_octets;
+       __le16 rx_multicast_octets;
+       __le16 rx_fcs_errors;
+       __le16 rx_discards_no_buffer;
+       __le16 tx_discards_wrong_sa;
+       __le16 rx_discards_wep_undecryptable;
+       __le16 rx_message_in_msg_fragments;
+       __le16 rx_message_in_bad_msg_fragments;
 } __attribute__ ((packed));
 
 struct hfa384x_comm_tallies32 {
-       u32 tx_unicast_frames;
-       u32 tx_multicast_frames;
-       u32 tx_fragments;
-       u32 tx_unicast_octets;
-       u32 tx_multicast_octets;
-       u32 tx_deferred_transmissions;
-       u32 tx_single_retry_frames;
-       u32 tx_multiple_retry_frames;
-       u32 tx_retry_limit_exceeded;
-       u32 tx_discards;
-       u32 rx_unicast_frames;
-       u32 rx_multicast_frames;
-       u32 rx_fragments;
-       u32 rx_unicast_octets;
-       u32 rx_multicast_octets;
-       u32 rx_fcs_errors;
-       u32 rx_discards_no_buffer;
-       u32 tx_discards_wrong_sa;
-       u32 rx_discards_wep_undecryptable;
-       u32 rx_message_in_msg_fragments;
-       u32 rx_message_in_bad_msg_fragments;
+       __le32 tx_unicast_frames;
+       __le32 tx_multicast_frames;
+       __le32 tx_fragments;
+       __le32 tx_unicast_octets;
+       __le32 tx_multicast_octets;
+       __le32 tx_deferred_transmissions;
+       __le32 tx_single_retry_frames;
+       __le32 tx_multiple_retry_frames;
+       __le32 tx_retry_limit_exceeded;
+       __le32 tx_discards;
+       __le32 rx_unicast_frames;
+       __le32 rx_multicast_frames;
+       __le32 rx_fragments;
+       __le32 rx_unicast_octets;
+       __le32 rx_multicast_octets;
+       __le32 rx_fcs_errors;
+       __le32 rx_discards_no_buffer;
+       __le32 tx_discards_wrong_sa;
+       __le32 rx_discards_wep_undecryptable;
+       __le32 rx_message_in_msg_fragments;
+       __le32 rx_message_in_bad_msg_fragments;
 } __attribute__ ((packed));
 
 struct hfa384x_scan_result_hdr {
-       u16 reserved;
-       u16 scan_reason;
+       __le16 reserved;
+       __le16 scan_reason;
 #define HFA384X_SCAN_IN_PROGRESS 0 /* no results available yet */
 #define HFA384X_SCAN_HOST_INITIATED 1
 #define HFA384X_SCAN_FIRMWARE_INITIATED 2
@@ -211,30 +211,30 @@ struct hfa384x_scan_result_hdr {
 #define HFA384X_SCAN_MAX_RESULTS 32
 
 struct hfa384x_scan_result {
-       u16 chid;
-       u16 anl;
-       u16 sl;
+       __le16 chid;
+       __le16 anl;
+       __le16 sl;
        u8 bssid[6];
-       u16 beacon_interval;
-       u16 capability;
-       u16 ssid_len;
+       __le16 beacon_interval;
+       __le16 capability;
+       __le16 ssid_len;
        u8 ssid[32];
        u8 sup_rates[10];
-       u16 rate;
+       __le16 rate;
 } __attribute__ ((packed));
 
 struct hfa384x_hostscan_result {
-       u16 chid;
-       u16 anl;
-       u16 sl;
+       __le16 chid;
+       __le16 anl;
+       __le16 sl;
        u8 bssid[6];
-       u16 beacon_interval;
-       u16 capability;
-       u16 ssid_len;
+       __le16 beacon_interval;
+       __le16 capability;
+       __le16 ssid_len;
        u8 ssid[32];
        u8 sup_rates[10];
-       u16 rate;
-       u16 atim;
+       __le16 rate;
+       __le16 atim;
 } __attribute__ ((packed));
 
 struct comm_tallies_sums {
index fc6cdd8086c1b2c49da2d7857682cda1870ee3e1..2ab107f457937b96b339711d6c7eaa6ffa8f79c0 100644 (file)
@@ -2509,9 +2509,9 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
 
        ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
-       ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */
+       ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr)); /* total hdr+data */
 
-       ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL;
+       ipw_rt->rt_hdr.it_present = cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
 
        ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM;
 
@@ -2558,7 +2558,7 @@ static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
 #ifdef CONFIG_IPW2100_MONITOR
                return 0;
 #else
-               switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
+               switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
                case IEEE80211_FTYPE_MGMT:
                case IEEE80211_FTYPE_CTL:
                        return 0;
@@ -2677,7 +2677,7 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv)
 #endif
                        if (stats.len < sizeof(struct ieee80211_hdr_3addr))
                                break;
-                       switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
+                       switch (WLAN_FC_GET_TYPE(le16_to_cpu(u->rx_data.header.frame_ctl))) {
                        case IEEE80211_FTYPE_MGMT:
                                ieee80211_rx_mgt(priv->ieee,
                                                 &u->rx_data.header, &stats);
@@ -6591,8 +6591,7 @@ static const long ipw2100_frequencies[] = {
        2472, 2484
 };
 
-#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
-                    sizeof(ipw2100_frequencies[0]))
+#define FREQ_COUNT     ARRAY_SIZE(ipw2100_frequencies)
 
 static const long ipw2100_rates_11b[] = {
        1000000,
@@ -7796,7 +7795,7 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
 {
        struct ipw2100_priv *priv = ieee80211_priv(dev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
-       u16 reason;
+       __le16 reason;
 
        reason = cpu_to_le16(mlme->reason_code);
 
index 003f73f89efa66bda431e3322b1b2b35eb5dbf7e..3e6ad7b92c8316e488ca20575c1146aea6e10063 100644 (file)
@@ -2352,27 +2352,13 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
 static int ipw_send_associate(struct ipw_priv *priv,
                              struct ipw_associate *associate)
 {
-       struct ipw_associate tmp_associate;
-
        if (!priv || !associate) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
 
-       memcpy(&tmp_associate, associate, sizeof(*associate));
-       tmp_associate.policy_support =
-           cpu_to_le16(tmp_associate.policy_support);
-       tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
-       tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
-       tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
-       tmp_associate.listen_interval =
-           cpu_to_le16(tmp_associate.listen_interval);
-       tmp_associate.beacon_interval =
-           cpu_to_le16(tmp_associate.beacon_interval);
-       tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
-
-       return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(tmp_associate),
-                               &tmp_associate);
+       return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(*associate),
+                               associate);
 }
 
 static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -2403,14 +2389,13 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
 
 static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
 {
+       __le32 v = cpu_to_le32(phy_off);
        if (!priv) {
                IPW_ERROR("Invalid args\n");
                return -1;
        }
 
-       phy_off = cpu_to_le32(phy_off);
-       return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off),
-                               &phy_off);
+       return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(v), &v);
 }
 
 static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
@@ -2499,7 +2484,7 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
 
 static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
 {
-       u32 param;
+       __le32 param;
 
        if (!priv) {
                IPW_ERROR("Invalid args\n");
@@ -2510,17 +2495,16 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
         * level */
        switch (mode) {
        case IPW_POWER_BATTERY:
-               param = IPW_POWER_INDEX_3;
+               param = cpu_to_le32(IPW_POWER_INDEX_3);
                break;
        case IPW_POWER_AC:
-               param = IPW_POWER_MODE_CAM;
+               param = cpu_to_le32(IPW_POWER_MODE_CAM);
                break;
        default:
-               param = mode;
+               param = cpu_to_le32(mode);
                break;
        }
 
-       param = cpu_to_le32(param);
        return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
                                &param);
 }
@@ -2654,13 +2638,13 @@ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
 static void ipw_eeprom_init_sram(struct ipw_priv *priv)
 {
        int i;
-       u16 *eeprom = (u16 *) priv->eeprom;
+       __le16 *eeprom = (__le16 *) priv->eeprom;
 
        IPW_DEBUG_TRACE(">>\n");
 
        /* read entire contents of eeprom into private buffer */
        for (i = 0; i < 128; i++)
-               eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
+               eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));
 
        /*
           If the data looks correct, then copy it to our private
@@ -3040,17 +3024,17 @@ static void ipw_arc_release(struct ipw_priv *priv)
 }
 
 struct fw_chunk {
-       u32 address;
-       u32 length;
+       __le32 address;
+       __le32 length;
 };
 
 static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
 {
        int rc = 0, i, addr;
        u8 cr = 0;
-       u16 *image;
+       __le16 *image;
 
-       image = (u16 *) data;
+       image = (__le16 *) data;
 
        IPW_DEBUG_TRACE(">> \n");
 
@@ -3097,7 +3081,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
        /* load new ipw uCode */
        for (i = 0; i < len / 2; i++)
                ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
-                               cpu_to_le16(image[i]));
+                               le16_to_cpu(image[i]));
 
        /* enable DINO */
        ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
@@ -3116,11 +3100,11 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
 
        if (cr & DINO_RXFIFO_DATA) {
                /* alive_command_responce size is NOT multiple of 4 */
-               u32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
+               __le32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];
 
                for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
                        response_buffer[i] =
-                           le32_to_cpu(ipw_read_reg32(priv,
+                           cpu_to_le32(ipw_read_reg32(priv,
                                                       IPW_BASEBAND_RX_FIFO_READ));
                memcpy(&priv->dino_alive, response_buffer,
                       sizeof(priv->dino_alive));
@@ -4170,7 +4154,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
        priv->last_missed_beacons = priv->missed_beacons;
        if (priv->assoc_request.beacon_interval) {
                missed_beacons_percent = missed_beacons_delta *
-                   (HZ * priv->assoc_request.beacon_interval) /
+                   (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /
                    (IPW_STATS_INTERVAL * 10);
        } else {
                missed_beacons_percent = 0;
@@ -4396,9 +4380,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                       struct ipw_rx_notification *notif)
 {
        DECLARE_MAC_BUF(mac);
+       u16 size = le16_to_cpu(notif->size);
        notif->size = le16_to_cpu(notif->size);
 
-       IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
+       IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
 
        switch (notif->subtype) {
        case HOST_NOTIFICATION_STATUS_ASSOCIATED:{
@@ -4433,9 +4418,9 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                                                   workqueue,
                                                                   &priv->
                                                                   adhoc_check,
-                                                                  priv->
+                                                                  le16_to_cpu(priv->
                                                                   assoc_request.
-                                                                  beacon_interval);
+                                                                  beacon_interval));
                                                break;
                                        }
 
@@ -4453,20 +4438,17 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                                if ((sizeof
                                                     (struct
                                                      ieee80211_assoc_response)
-                                                    <= notif->size)
-                                                   && (notif->size <= 2314)) {
+                                                    <= size)
+                                                   && (size <= 2314)) {
                                                        struct
                                                        ieee80211_rx_stats
                                                            stats = {
-                                                               .len =
-                                                                   notif->
-                                                                   size - 1,
+                                                               .len = size - 1,
                                                        };
 
                                                        IPW_DEBUG_QOS
                                                            ("QoS Associate "
-                                                            "size %d\n",
-                                                            notif->size);
+                                                            "size %d\n", size);
                                                        ieee80211_rx_mgt(priv->
                                                                         ieee,
                                                                         (struct
@@ -4671,20 +4653,20 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        struct notif_channel_result *x =
                            &notif->u.channel_result;
 
-                       if (notif->size == sizeof(*x)) {
+                       if (size == sizeof(*x)) {
                                IPW_DEBUG_SCAN("Scan result for channel %d\n",
                                               x->channel_num);
                        } else {
                                IPW_DEBUG_SCAN("Scan result of wrong size %d "
                                               "(should be %zd)\n",
-                                              notif->size, sizeof(*x));
+                                              size, sizeof(*x));
                        }
                        break;
                }
 
        case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{
                        struct notif_scan_complete *x = &notif->u.scan_complete;
-                       if (notif->size == sizeof(*x)) {
+                       if (size == sizeof(*x)) {
                                IPW_DEBUG_SCAN
                                    ("Scan completed: type %d, %d channels, "
                                     "%d status\n", x->scan_type,
@@ -4692,7 +4674,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        } else {
                                IPW_ERROR("Scan completed of wrong size %d "
                                          "(should be %zd)\n",
-                                         notif->size, sizeof(*x));
+                                         size, sizeof(*x));
                        }
 
                        priv->status &=
@@ -4758,13 +4740,13 @@ static void ipw_rx_notification(struct ipw_priv *priv,
        case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
                        struct notif_frag_length *x = &notif->u.frag_len;
 
-                       if (notif->size == sizeof(*x))
+                       if (size == sizeof(*x))
                                IPW_ERROR("Frag length: %d\n",
                                          le16_to_cpu(x->frag_length));
                        else
                                IPW_ERROR("Frag length of wrong size %d "
                                          "(should be %zd)\n",
-                                         notif->size, sizeof(*x));
+                                         size, sizeof(*x));
                        break;
                }
 
@@ -4772,7 +4754,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        struct notif_link_deterioration *x =
                            &notif->u.link_deterioration;
 
-                       if (notif->size == sizeof(*x)) {
+                       if (size == sizeof(*x)) {
                                IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
                                        "link deterioration: type %d, cnt %d\n",
                                        x->silence_notification_type,
@@ -4782,7 +4764,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                        } else {
                                IPW_ERROR("Link Deterioration of wrong size %d "
                                          "(should be %zd)\n",
-                                         notif->size, sizeof(*x));
+                                         size, sizeof(*x));
                        }
                        break;
                }
@@ -4798,10 +4780,10 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
        case HOST_NOTIFICATION_STATUS_BEACON_STATE:{
                        struct notif_beacon_state *x = &notif->u.beacon_state;
-                       if (notif->size != sizeof(*x)) {
+                       if (size != sizeof(*x)) {
                                IPW_ERROR
                                    ("Beacon state of wrong size %d (should "
-                                    "be %zd)\n", notif->size, sizeof(*x));
+                                    "be %zd)\n", size, sizeof(*x));
                                break;
                        }
 
@@ -4816,7 +4798,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
        case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{
                        struct notif_tgi_tx_key *x = &notif->u.tgi_tx_key;
-                       if (notif->size == sizeof(*x)) {
+                       if (size == sizeof(*x)) {
                                IPW_ERROR("TGi Tx Key: state 0x%02x sec type "
                                          "0x%02x station %d\n",
                                          x->key_state, x->security_type,
@@ -4826,14 +4808,14 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
                        IPW_ERROR
                            ("TGi Tx Key of wrong size %d (should be %zd)\n",
-                            notif->size, sizeof(*x));
+                            size, sizeof(*x));
                        break;
                }
 
        case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{
                        struct notif_calibration *x = &notif->u.calibration;
 
-                       if (notif->size == sizeof(*x)) {
+                       if (size == sizeof(*x)) {
                                memcpy(&priv->calib, x, sizeof(*x));
                                IPW_DEBUG_INFO("TODO: Calibration\n");
                                break;
@@ -4841,12 +4823,12 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
                        IPW_ERROR
                            ("Calibration of wrong size %d (should be %zd)\n",
-                            notif->size, sizeof(*x));
+                            size, sizeof(*x));
                        break;
                }
 
        case HOST_NOTIFICATION_NOISE_STATS:{
-                       if (notif->size == sizeof(u32)) {
+                       if (size == sizeof(u32)) {
                                priv->exp_avg_noise =
                                    exponential_average(priv->exp_avg_noise,
                                    (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),
@@ -4856,14 +4838,14 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 
                        IPW_ERROR
                            ("Noise stat is wrong size %d (should be %zd)\n",
-                            notif->size, sizeof(u32));
+                            size, sizeof(u32));
                        break;
                }
 
        default:
                IPW_DEBUG_NOTIF("Unknown notification: "
                                "subtype=%d,flags=0x%2x,size=%d\n",
-                               notif->subtype, notif->flags, notif->size);
+                               notif->subtype, notif->flags, size);
        }
 }
 
@@ -6048,7 +6030,7 @@ static void ipw_adhoc_check(void *data)
        }
 
        queue_delayed_work(priv->workqueue, &priv->adhoc_check,
-                          priv->assoc_request.beacon_interval);
+                          le16_to_cpu(priv->assoc_request.beacon_interval));
 }
 
 static void ipw_bg_adhoc_check(struct work_struct *work)
@@ -6767,7 +6749,7 @@ static int ipw_wx_set_mlme(struct net_device *dev,
 {
        struct ipw_priv *priv = ieee80211_priv(dev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
-       u16 reason;
+       __le16 reason;
 
        reason = cpu_to_le16(mlme->reason_code);
 
@@ -6904,7 +6886,7 @@ static int ipw_qos_activate(struct ipw_priv *priv,
                burst_duration = ipw_qos_get_burst_duration(priv);
                for (i = 0; i < QOS_QUEUE_NUM; i++)
                        qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
-                           (u16)burst_duration;
+                           cpu_to_le16(burst_duration);
        } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
                if (type == IEEE_B) {
                        IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
@@ -6936,20 +6918,11 @@ static int ipw_qos_activate(struct ipw_priv *priv,
                        burst_duration = ipw_qos_get_burst_duration(priv);
                        for (i = 0; i < QOS_QUEUE_NUM; i++)
                                qos_parameters[QOS_PARAM_SET_ACTIVE].
-                                   tx_op_limit[i] = (u16)burst_duration;
+                                   tx_op_limit[i] = cpu_to_le16(burst_duration);
                }
        }
 
        IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
-       for (i = 0; i < 3; i++) {
-               int j;
-               for (j = 0; j < QOS_QUEUE_NUM; j++) {
-                       qos_parameters[i].cw_min[j] = cpu_to_le16(qos_parameters[i].cw_min[j]);
-                       qos_parameters[i].cw_max[j] = cpu_to_le16(qos_parameters[i].cw_max[j]);
-                       qos_parameters[i].tx_op_limit[j] = cpu_to_le16(qos_parameters[i].tx_op_limit[j]);
-               }
-       }
-
        err = ipw_send_qos_params_command(priv,
                                          (struct ieee80211_qos_parameters *)
                                          &(qos_parameters[0]));
@@ -7300,7 +7273,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
                priv->assoc_request.auth_type = AUTH_OPEN;
 
        if (priv->ieee->wpa_ie_len) {
-               priv->assoc_request.policy_support = 0x02;      /* RSN active */
+               priv->assoc_request.policy_support = cpu_to_le16(0x02); /* RSN active */
                ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
                                 priv->ieee->wpa_ie_len);
        }
@@ -7317,7 +7290,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
        else if (network->mode & priv->ieee->mode & IEEE_B)
                priv->assoc_request.ieee_mode = IPW_B_MODE;
 
-       priv->assoc_request.capability = network->capability;
+       priv->assoc_request.capability = cpu_to_le16(network->capability);
        if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
            && !(priv->config & CFG_PREAMBLE_LONG)) {
                priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
@@ -7326,13 +7299,13 @@ static int ipw_associate_network(struct ipw_priv *priv,
 
                /* Clear the short preamble if we won't be supporting it */
                priv->assoc_request.capability &=
-                   ~WLAN_CAPABILITY_SHORT_PREAMBLE;
+                   ~cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
        }
 
        /* Clear capability bits that aren't used in Ad Hoc */
        if (priv->ieee->iw_mode == IW_MODE_ADHOC)
                priv->assoc_request.capability &=
-                   ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+                   ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
        IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
                        "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
@@ -7354,7 +7327,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
                        '1' + priv->ieee->sec.active_key : '.',
                        priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
 
-       priv->assoc_request.beacon_interval = network->beacon_interval;
+       priv->assoc_request.beacon_interval = cpu_to_le16(network->beacon_interval);
        if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&
            (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {
                priv->assoc_request.assoc_type = HC_IBSS_START;
@@ -7365,21 +7338,21 @@ static int ipw_associate_network(struct ipw_priv *priv,
                        priv->assoc_request.assoc_type = HC_REASSOCIATE;
                else
                        priv->assoc_request.assoc_type = HC_ASSOCIATE;
-               priv->assoc_request.assoc_tsf_msw = network->time_stamp[1];
-               priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
+               priv->assoc_request.assoc_tsf_msw = cpu_to_le32(network->time_stamp[1]);
+               priv->assoc_request.assoc_tsf_lsw = cpu_to_le32(network->time_stamp[0]);
        }
 
        memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
 
        if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
                memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
-               priv->assoc_request.atim_window = network->atim_window;
+               priv->assoc_request.atim_window = cpu_to_le16(network->atim_window);
        } else {
                memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
                priv->assoc_request.atim_window = 0;
        }
 
-       priv->assoc_request.listen_interval = network->listen_interval;
+       priv->assoc_request.listen_interval = cpu_to_le16(network->listen_interval);
 
        err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
        if (err) {
@@ -7768,11 +7741,11 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
 
        ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        ipw_rt->rt_hdr.it_pad = 0;      /* always good to zero */
-       ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr);      /* total header+data */
+       ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr)); /* total header+data */
 
        /* Big bitfield of all the fields we provide in radiotap */
-       ipw_rt->rt_hdr.it_present =
-           ((1 << IEEE80211_RADIOTAP_TSFT) |
+       ipw_rt->rt_hdr.it_present = cpu_to_le32(
+            (1 << IEEE80211_RADIOTAP_TSFT) |
             (1 << IEEE80211_RADIOTAP_FLAGS) |
             (1 << IEEE80211_RADIOTAP_RATE) |
             (1 << IEEE80211_RADIOTAP_CHANNEL) |
@@ -7801,7 +7774,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
                    cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
        } else {                /* 802.11g */
                ipw_rt->rt_chbitmask =
-                   (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
+                   cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
        }
 
        /* set the rate in multiples of 500k/s */
@@ -7982,14 +7955,14 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
 
        ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
        ipw_rt->rt_hdr.it_pad = 0;      /* always good to zero */
-       ipw_rt->rt_hdr.it_len = sizeof(*ipw_rt);        /* total header+data */
+       ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt));   /* total header+data */
 
        /* Set the size of the skb to the size of the frame */
-       skb_put(skb, ipw_rt->rt_hdr.it_len + len);
+       skb_put(skb, sizeof(*ipw_rt) + len);
 
        /* Big bitfield of all the fields we provide in radiotap */
-       ipw_rt->rt_hdr.it_present =
-           ((1 << IEEE80211_RADIOTAP_TSFT) |
+       ipw_rt->rt_hdr.it_present = cpu_to_le32(
+            (1 << IEEE80211_RADIOTAP_TSFT) |
             (1 << IEEE80211_RADIOTAP_FLAGS) |
             (1 << IEEE80211_RADIOTAP_RATE) |
             (1 << IEEE80211_RADIOTAP_CHANNEL) |
@@ -8018,7 +7991,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
                    cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
        } else {                /* 802.11g */
                ipw_rt->rt_chbitmask =
-                   (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
+                   cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
        }
 
        /* set the rate in multiples of 500k/s */
@@ -8912,6 +8885,8 @@ static int ipw_wx_get_range(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;
 
+       range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;
+
        IPW_DEBUG_WX("GET Range\n");
        return 0;
 }
@@ -10348,7 +10323,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
                        tfd->u.data.chunk_ptr[i] =
                            cpu_to_le32(pci_map_single
                                        (priv->pci_dev, skb->data,
-                                        tfd->u.data.chunk_len[i],
+                                        remaining_bytes,
                                         PCI_DMA_TODEVICE));
 
                        tfd->u.data.num_chunks =
@@ -10443,24 +10418,24 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
                rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
                rt_hdr->it_pad = 0;
                rt_hdr->it_present = 0; /* after all, it's just an idea */
-               rt_hdr->it_present |=  (1 << IEEE80211_RADIOTAP_CHANNEL);
+               rt_hdr->it_present |=  cpu_to_le32(1 << IEEE80211_RADIOTAP_CHANNEL);
 
-               *(u16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
+               *(__le16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
                        ieee80211chan2mhz(priv->channel));
                if (priv->channel > 14)         /* 802.11a */
-                       *(u16*)skb_put(dst, sizeof(u16)) =
+                       *(__le16*)skb_put(dst, sizeof(u16)) =
                                cpu_to_le16(IEEE80211_CHAN_OFDM |
                                             IEEE80211_CHAN_5GHZ);
                else if (priv->ieee->mode == IEEE_B) /* 802.11b */
-                       *(u16*)skb_put(dst, sizeof(u16)) =
+                       *(__le16*)skb_put(dst, sizeof(u16)) =
                                cpu_to_le16(IEEE80211_CHAN_CCK |
                                             IEEE80211_CHAN_2GHZ);
                else            /* 802.11g */
-                       *(u16*)skb_put(dst, sizeof(u16)) =
+                       *(__le16*)skb_put(dst, sizeof(u16)) =
                                cpu_to_le16(IEEE80211_CHAN_OFDM |
                                 IEEE80211_CHAN_2GHZ);
 
-               rt_hdr->it_len = dst->len;
+               rt_hdr->it_len = cpu_to_le16(dst->len);
 
                skb_copy_from_linear_data(src, skb_put(dst, len), len);
 
@@ -10873,9 +10848,9 @@ static void shim__set_security(struct net_device *dev,
 #if 0
        if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&
            (((priv->assoc_request.capability &
-              WLAN_CAPABILITY_PRIVACY) && !sec->enabled) ||
+              cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && !sec->enabled) ||
             (!(priv->assoc_request.capability &
-               WLAN_CAPABILITY_PRIVACY) && sec->enabled))) {
+               cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && sec->enabled))) {
                IPW_DEBUG_ASSOC("Disassociating due to capability "
                                "change.\n");
                ipw_disassociate(priv);
index bec8e37a17380fa31da5aae7fad50b271cde31ae..fdc187e0769d7829180aaa9641f8624cbddafe80 100644 (file)
@@ -267,25 +267,25 @@ enum connection_manager_assoc_states {
 #define CW_MIN_CCK           31
 #define CW_MAX_CCK           1023
 
-#define QOS_TX0_CW_MIN_OFDM      CW_MIN_OFDM
-#define QOS_TX1_CW_MIN_OFDM      CW_MIN_OFDM
-#define QOS_TX2_CW_MIN_OFDM      ( (CW_MIN_OFDM + 1) / 2 - 1 )
-#define QOS_TX3_CW_MIN_OFDM      ( (CW_MIN_OFDM + 1) / 4 - 1 )
-
-#define QOS_TX0_CW_MIN_CCK       CW_MIN_CCK
-#define QOS_TX1_CW_MIN_CCK       CW_MIN_CCK
-#define QOS_TX2_CW_MIN_CCK       ( (CW_MIN_CCK + 1) / 2 - 1 )
-#define QOS_TX3_CW_MIN_CCK       ( (CW_MIN_CCK + 1) / 4 - 1 )
-
-#define QOS_TX0_CW_MAX_OFDM      CW_MAX_OFDM
-#define QOS_TX1_CW_MAX_OFDM      CW_MAX_OFDM
-#define QOS_TX2_CW_MAX_OFDM      CW_MIN_OFDM
-#define QOS_TX3_CW_MAX_OFDM      ( (CW_MIN_OFDM + 1) / 2 - 1 )
-
-#define QOS_TX0_CW_MAX_CCK       CW_MAX_CCK
-#define QOS_TX1_CW_MAX_CCK       CW_MAX_CCK
-#define QOS_TX2_CW_MAX_CCK       CW_MIN_CCK
-#define QOS_TX3_CW_MAX_CCK       ( (CW_MIN_CCK + 1) / 2 - 1 )
+#define QOS_TX0_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define QOS_TX1_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define QOS_TX2_CW_MIN_OFDM      cpu_to_le16((CW_MIN_OFDM + 1)/2 - 1)
+#define QOS_TX3_CW_MIN_OFDM      cpu_to_le16((CW_MIN_OFDM + 1)/4 - 1)
+
+#define QOS_TX0_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
+#define QOS_TX1_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
+#define QOS_TX2_CW_MIN_CCK       cpu_to_le16((CW_MIN_CCK + 1)/2 - 1)
+#define QOS_TX3_CW_MIN_CCK       cpu_to_le16((CW_MIN_CCK + 1)/4 - 1)
+
+#define QOS_TX0_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
+#define QOS_TX1_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
+#define QOS_TX2_CW_MAX_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define QOS_TX3_CW_MAX_OFDM      cpu_to_le16((CW_MIN_OFDM + 1)/2 - 1)
+
+#define QOS_TX0_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
+#define QOS_TX1_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
+#define QOS_TX2_CW_MAX_CCK       cpu_to_le16(CW_MIN_CCK)
+#define QOS_TX3_CW_MAX_CCK       cpu_to_le16((CW_MIN_CCK + 1)/2 - 1)
 
 #define QOS_TX0_AIFS            (3 - QOS_AIFSN_MIN_VALUE)
 #define QOS_TX1_AIFS            (7 - QOS_AIFSN_MIN_VALUE)
@@ -299,33 +299,33 @@ enum connection_manager_assoc_states {
 
 #define QOS_TX0_TXOP_LIMIT_CCK          0
 #define QOS_TX1_TXOP_LIMIT_CCK          0
-#define QOS_TX2_TXOP_LIMIT_CCK          6016
-#define QOS_TX3_TXOP_LIMIT_CCK          3264
+#define QOS_TX2_TXOP_LIMIT_CCK          cpu_to_le16(6016)
+#define QOS_TX3_TXOP_LIMIT_CCK          cpu_to_le16(3264)
 
 #define QOS_TX0_TXOP_LIMIT_OFDM      0
 #define QOS_TX1_TXOP_LIMIT_OFDM      0
-#define QOS_TX2_TXOP_LIMIT_OFDM      3008
-#define QOS_TX3_TXOP_LIMIT_OFDM      1504
+#define QOS_TX2_TXOP_LIMIT_OFDM      cpu_to_le16(3008)
+#define QOS_TX3_TXOP_LIMIT_OFDM      cpu_to_le16(1504)
 
-#define DEF_TX0_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX1_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX2_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX3_CW_MIN_OFDM      CW_MIN_OFDM
+#define DEF_TX0_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define DEF_TX1_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define DEF_TX2_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
+#define DEF_TX3_CW_MIN_OFDM      cpu_to_le16(CW_MIN_OFDM)
 
-#define DEF_TX0_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX1_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX2_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX3_CW_MIN_CCK       CW_MIN_CCK
+#define DEF_TX0_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
+#define DEF_TX1_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
+#define DEF_TX2_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
+#define DEF_TX3_CW_MIN_CCK       cpu_to_le16(CW_MIN_CCK)
 
-#define DEF_TX0_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX1_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX2_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX3_CW_MAX_OFDM      CW_MAX_OFDM
+#define DEF_TX0_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
+#define DEF_TX1_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
+#define DEF_TX2_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
+#define DEF_TX3_CW_MAX_OFDM      cpu_to_le16(CW_MAX_OFDM)
 
-#define DEF_TX0_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX1_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX2_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX3_CW_MAX_CCK       CW_MAX_CCK
+#define DEF_TX0_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
+#define DEF_TX1_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
+#define DEF_TX2_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
+#define DEF_TX3_CW_MAX_CCK       cpu_to_le16(CW_MAX_CCK)
 
 #define DEF_TX0_AIFS            0
 #define DEF_TX1_AIFS            0
@@ -388,18 +388,18 @@ struct clx2_queue {
 } __attribute__ ((packed));
 
 struct machdr32 {
-       u16 frame_ctl;
+       __le16 frame_ctl;
        u16 duration;           // watch out for endians!
        u8 addr1[MACADRR_BYTE_LEN];
        u8 addr2[MACADRR_BYTE_LEN];
        u8 addr3[MACADRR_BYTE_LEN];
        u16 seq_ctrl;           // more endians!
        u8 addr4[MACADRR_BYTE_LEN];
-       u16 qos_ctrl;
+       __le16 qos_ctrl;
 } __attribute__ ((packed));
 
 struct machdr30 {
-       u16 frame_ctl;
+       __le16 frame_ctl;
        u16 duration;           // watch out for endians!
        u8 addr1[MACADRR_BYTE_LEN];
        u8 addr2[MACADRR_BYTE_LEN];
@@ -409,17 +409,17 @@ struct machdr30 {
 } __attribute__ ((packed));
 
 struct machdr26 {
-       u16 frame_ctl;
+       __le16 frame_ctl;
        u16 duration;           // watch out for endians!
        u8 addr1[MACADRR_BYTE_LEN];
        u8 addr2[MACADRR_BYTE_LEN];
        u8 addr3[MACADRR_BYTE_LEN];
        u16 seq_ctrl;           // more endians!
-       u16 qos_ctrl;
+       __le16 qos_ctrl;
 } __attribute__ ((packed));
 
 struct machdr24 {
-       u16 frame_ctl;
+       __le16 frame_ctl;
        u16 duration;           // watch out for endians!
        u8 addr1[MACADRR_BYTE_LEN];
        u8 addr2[MACADRR_BYTE_LEN];
@@ -466,15 +466,15 @@ struct tfd_command {
 
 struct tfd_data {
        /* Header */
-       u32 work_area_ptr;
+       __le32 work_area_ptr;
        u8 station_number;      /* 0 for BSS */
        u8 reserved1;
-       u16 reserved2;
+       __le16 reserved2;
 
        /* Tx Parameters */
        u8 cmd_id;
        u8 seq_num;
-       u16 len;
+       __le16 len;
        u8 priority;
        u8 tx_flags;
        u8 tx_flags_ext;
@@ -482,11 +482,11 @@ struct tfd_data {
        u8 wepkey[DCT_WEP_KEY_FIELD_LENGTH];
        u8 rate;
        u8 antenna;
-       u16 next_packet_duration;
-       u16 next_frag_len;
-       u16 back_off_counter;   //////txop;
+       __le16 next_packet_duration;
+       __le16 next_frag_len;
+       __le16 back_off_counter;        //////txop;
        u8 retrylimit;
-       u16 cwcurrent;
+       __le16 cwcurrent;
        u8 reserved3;
 
        /* 802.11 MAC Header */
@@ -498,9 +498,9 @@ struct tfd_data {
        } tfd;
 
        /* Payload DMA info */
-       u32 num_chunks;
-       u32 chunk_ptr[NUM_TFD_CHUNKS];
-       u16 chunk_len[NUM_TFD_CHUNKS];
+       __le32 num_chunks;
+       __le32 chunk_ptr[NUM_TFD_CHUNKS];
+       __le16 chunk_len[NUM_TFD_CHUNKS];
 } __attribute__ ((packed));
 
 struct txrx_control_flags {
@@ -547,14 +547,14 @@ struct clx2_tx_queue {
 // Used for passing to driver number of successes and failures per rate
 struct rate_histogram {
        union {
-               u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-               u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-               u32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
        } success;
        union {
-               u32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-               u32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-               u32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
        } failed;
 } __attribute__ ((packed));
 
@@ -602,13 +602,13 @@ struct notif_scan_complete {
 } __attribute__ ((packed));
 
 struct notif_frag_length {
-       u16 frag_length;
-       u16 reserved;
+       __le16 frag_length;
+       __le16 reserved;
 } __attribute__ ((packed));
 
 struct notif_beacon_state {
-       u32 state;
-       u32 number;
+       __le32 state;
+       __le32 number;
 } __attribute__ ((packed));
 
 struct notif_tgi_tx_key {
@@ -627,7 +627,7 @@ struct notif_link_deterioration {
        u8 modulation;
        struct rate_histogram histogram;
        u8 silence_notification_type;   /* SILENCE_OVER/UNDER_THRESH */
-       u16 silence_count;
+       __le16 silence_count;
 } __attribute__ ((packed));
 
 struct notif_association {
@@ -645,14 +645,14 @@ struct notif_calibration {
 } __attribute__ ((packed));
 
 struct notif_noise {
-       u32 value;
+       __le32 value;
 } __attribute__ ((packed));
 
 struct ipw_rx_notification {
        u8 reserved[8];
        u8 subtype;
        u8 flags;
-       u16 size;
+       __le16 size;
        union {
                struct notif_association assoc;
                struct notif_authenticate auth;
@@ -669,7 +669,7 @@ struct ipw_rx_notification {
 } __attribute__ ((packed));
 
 struct ipw_rx_frame {
-       u32 reserved1;
+       __le32 reserved1;
        u8 parent_tsf[4];       // fw_use[0] is boolean for OUR_TSF_IS_GREATER
        u8 received_channel;    // The channel that this frame was received on.
        // Note that for .11b this does not have to be
@@ -680,14 +680,14 @@ struct ipw_rx_frame {
        u8 rssi;
        u8 agc;
        u8 rssi_dbm;
-       u16 signal;
-       u16 noise;
+       __le16 signal;
+       __le16 noise;
        u8 antennaAndPhy;
        u8 control;             // control bit should be on in bg
        u8 rtscts_rate;         // rate of rts or cts (in rts cts sequence rate
        // is identical)
        u8 rtscts_seen;         // 0x1 RTS seen ; 0x2 CTS seen
-       u16 length;
+       __le16 length;
        u8 data[0];
 } __attribute__ ((packed));
 
@@ -827,14 +827,14 @@ struct ipw_tgi_tx_key {
        u8 station_index;
        u8 flags;
        u8 key[16];
-       u32 tx_counter[2];
+       __le32 tx_counter[2];
 } __attribute__ ((packed));
 
 #define IPW_SCAN_CHANNELS 54
 
 struct ipw_scan_request {
        u8 scan_type;
-       u16 dwell_time;
+       __le16 dwell_time;
        u8 channels_list[IPW_SCAN_CHANNELS];
        u8 channels_reserved[3];
 } __attribute__ ((packed));
@@ -849,11 +849,11 @@ enum {
 };
 
 struct ipw_scan_request_ext {
-       u32 full_scan_index;
+       __le32 full_scan_index;
        u8 channels_list[IPW_SCAN_CHANNELS];
        u8 scan_type[IPW_SCAN_CHANNELS / 2];
        u8 reserved;
-       u16 dwell_time[IPW_SCAN_TYPES];
+       __le16 dwell_time[IPW_SCAN_TYPES];
 } __attribute__ ((packed));
 
 static inline u8 ipw_get_scan_type(struct ipw_scan_request_ext *scan, u8 index)
@@ -881,20 +881,20 @@ struct ipw_associate {
        u8 auth_type:4, auth_key:4;
        u8 assoc_type;
        u8 reserved;
-       u16 policy_support;
+       __le16 policy_support;
        u8 preamble_length;
        u8 ieee_mode;
        u8 bssid[ETH_ALEN];
-       u32 assoc_tsf_msw;
-       u32 assoc_tsf_lsw;
-       u16 capability;
-       u16 listen_interval;
-       u16 beacon_interval;
+       __le32 assoc_tsf_msw;
+       __le32 assoc_tsf_lsw;
+       __le16 capability;
+       __le16 listen_interval;
+       __le16 beacon_interval;
        u8 dest[ETH_ALEN];
-       u16 atim_window;
+       __le16 atim_window;
        u8 smr;
        u8 reserved1;
-       u16 reserved2;
+       __le16 reserved2;
 } __attribute__ ((packed));
 
 struct ipw_supported_rates {
@@ -906,13 +906,13 @@ struct ipw_supported_rates {
 } __attribute__ ((packed));
 
 struct ipw_rts_threshold {
-       u16 rts_threshold;
-       u16 reserved;
+       __le16 rts_threshold;
+       __le16 reserved;
 } __attribute__ ((packed));
 
 struct ipw_frag_threshold {
-       u16 frag_threshold;
-       u16 reserved;
+       __le16 frag_threshold;
+       __le16 reserved;
 } __attribute__ ((packed));
 
 struct ipw_retry_limit {
@@ -931,7 +931,7 @@ struct ipw_dino_config {
 struct ipw_aironet_info {
        u8 id;
        u8 length;
-       u16 reserved;
+       __le16 reserved;
 } __attribute__ ((packed));
 
 struct ipw_rx_key {
@@ -977,12 +977,12 @@ struct ipw_tx_power {
 struct ipw_rsn_capabilities {
        u8 id;
        u8 length;
-       u16 version;
+       __le16 version;
 } __attribute__ ((packed));
 
 struct ipw_sensitivity_calib {
-       u16 beacon_rssi_raw;
-       u16 reserved;
+       __le16 beacon_rssi_raw;
+       __le16 reserved;
 } __attribute__ ((packed));
 
 /**
@@ -1156,8 +1156,8 @@ struct ipw_rt_hdr {
        u64 rt_tsf;      /* TSF */
        u8 rt_flags;    /* radiotap packet flags */
        u8 rt_rate;     /* rate in 500kb/s */
-       u16 rt_channel; /* channel in mhz */
-       u16 rt_chbitmask;       /* channel bitfield */
+       __le16 rt_channel;      /* channel in mhz */
+       __le16 rt_chbitmask;    /* channel bitfield */
        s8 rt_dbmsignal;        /* signal in dbM, kluged to signed */
        s8 rt_dbmnoise;
        u8 rt_antenna;  /* antenna number */
@@ -1759,7 +1759,7 @@ enum {
 #define HC_IBSS_RECONF    4
 #define HC_DISASSOC_QUIET 5
 
-#define HC_QOS_SUPPORT_ASSOC  0x01
+#define HC_QOS_SUPPORT_ASSOC  cpu_to_le16(0x01)
 
 #define IPW_RATE_CAPABILITIES 1
 #define IPW_RATE_CONNECT      0
index 8d52a26c248ae72ffe1a10249da91bb00338b442..d1af938b9aa661f5e90e998aa9abe43c323bf7e0 100644 (file)
@@ -1,24 +1,64 @@
-config IWLWIFI
-       bool "Intel Wireless WiFi Link Drivers"
+config IWL4965
+       tristate "Intel Wireless WiFi 4965AGN"
        depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
        select FW_LOADER
-       default n
        ---help---
-         Select to enable drivers based on the iwlwifi project.  This
-         project provides a common foundation for Intel's wireless
-         drivers designed to use the mac80211 subsystem.
-
-         See <file:Documentation/networking/README.iwlwifi> for
-         information on the capabilities currently enabled in this
-         driver and for tips for debugging issues and problems.
-
-config IWLWIFI_DEBUG
-       bool "Enable full debugging output in iwlwifi drivers"
-       depends on IWLWIFI
-       default y
+         Select to build the driver supporting the:
+
+         Intel Wireless WiFi Link 4965AGN
+
+         This driver uses the kernel's mac80211 subsystem.
+
+         In order to use this driver, you will need a microcode (uCode)
+         image for it. You can obtain the microcode from:
+
+                 <http://intellinuxwireless.org/>.
+
+         The microcode is typically installed in /lib/firmware. You can
+         look in the hotplug script /etc/hotplug/firmware.agent to
+         determine which directory FIRMWARE_DIR is set to when the script
+         runs.
+
+         If you want to compile the driver as a module ( = code which can be
+         inserted in and remvoed from the running kernel whenever you want),
+         say M here and read <file:Documentation/kbuild/modules.txt>.  The
+         module will be called iwl4965.ko.
+
+config IWL4965_QOS
+       bool "Enable Wireless QoS in iwl4965 driver"
+       depends on IWL4965
        ---help---
-         This option will enable debug tracing output for the iwlwifi
-         drivers.
+         This option will enable wireless quality of service (QoS) for the
+         iwl4965 driver.
+
+config IWL4965_HT
+       bool "Enable 802.11n HT features in iwl4965 driver"
+       depends on EXPERIMENTAL
+       depends on IWL4965 && IWL4965_QOS
+       depends on n
+       ---help---
+         This option enables IEEE 802.11n High Throughput features
+         for the iwl4965 driver.
+
+config IWL4965_SPECTRUM_MEASUREMENT
+       bool "Enable Spectrum Measurement in iwl4965 driver"
+       depends on IWL4965
+       ---help---
+         This option will enable spectrum measurement for the iwl4965 driver.
+
+config IWL4965_SENSITIVITY
+       bool "Enable Sensitivity Calibration in iwl4965 driver"
+       depends on IWL4965
+       ---help---
+         This option will enable sensitivity calibration for the iwl4965
+         driver.
+
+config IWL4965_DEBUG
+       bool "Enable full debugging output in iwl4965 driver"
+       depends on IWL4965
+       ---help---
+         This option will enable debug tracing output for the iwl4965
+         driver.
 
          This will result in the kernel module being ~100k larger.  You can
          control which debug output is sent to the kernel log by setting the
@@ -33,96 +73,74 @@ config IWLWIFI_DEBUG
                  % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
 
          You can find the list of debug mask values in:
-                 drivers/net/wireless/mac80211/iwlwifi/iwl-debug.h
+                 drivers/net/wireless/iwlwifi/iwl-4965-debug.h
 
          If this is your first time using this driver, you should say Y here
          as the debug information can assist others in helping you resolve
          any problems you may encounter.
 
-config IWLWIFI_SENSITIVITY
-       bool "Enable Sensitivity Calibration in iwlwifi drivers"
-       depends on IWLWIFI
-       default y
-       ---help---
-         This option will enable sensitivity calibration for the iwlwifi
-         drivers.
-
-config IWLWIFI_SPECTRUM_MEASUREMENT
-       bool "Enable Spectrum Measurement in iwlwifi drivers"
-       depends on IWLWIFI
-       default y
-       ---help---
-         This option will enable spectrum measurement for the iwlwifi drivers.
-
-config IWLWIFI_QOS
-       bool "Enable Wireless QoS in iwlwifi drivers"
-       depends on IWLWIFI
-       default y
-       ---help---
-         This option will enable wireless quality of service (QoS) for the
-         iwlwifi drivers.
-
-config IWLWIFI_HT
-       bool "Enable 802.11n HT features in iwlwifi drivers"
-       depends on EXPERIMENTAL
-       depends on IWLWIFI && MAC80211_HT
-       default n
-       ---help---
-         This option enables IEEE 802.11n High Throughput features
-         for the iwlwifi drivers.
-
-config IWL4965
-       tristate "Intel Wireless WiFi 4965AGN"
-       depends on m && IWLWIFI && EXPERIMENTAL
-       default m
+config IWL3945
+       tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
+       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select FW_LOADER
        ---help---
          Select to build the driver supporting the:
 
-         Intel Wireless WiFi Link 4965AGN
+         Intel PRO/Wireless 3945ABG/BG Network Connection
 
          This driver uses the kernel's mac80211 subsystem.
 
-         See <file:Documentation/networking/README.iwlwifi> for
-         information on the capabilities currently enabled in this
-         driver and for tips for debugging any issues or problems.
-
          In order to use this driver, you will need a microcode (uCode)
          image for it. You can obtain the microcode from:
 
                  <http://intellinuxwireless.org/>.
 
-         See the above referenced README.iwlwifi for information on where
-         to install the microcode images.
+         The microcode is typically installed in /lib/firmware. You can
+         look in the hotplug script /etc/hotplug/firmware.agent to
+         determine which directory FIRMWARE_DIR is set to when the script
+         runs.
 
          If you want to compile the driver as a module ( = code which can be
          inserted in and remvoed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
-         module will be called iwl4965.ko.
+         module will be called iwl3945.ko.
 
-config IWL3945
-       tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
-       depends on m && IWLWIFI && EXPERIMENTAL
-       default m
+config IWL3945_QOS
+       bool "Enable Wireless QoS in iwl3945 driver"
+       depends on IWL3945
        ---help---
-         Select to build the driver supporting the:
+         This option will enable wireless quality of service (QoS) for the
+         iwl3945 driver.
 
-         Intel PRO/Wireless 3945ABG/BG Network Connection
+config IWL3945_SPECTRUM_MEASUREMENT
+       bool "Enable Spectrum Measurement in iwl3945 drivers"
+       depends on IWL3945
+       ---help---
+         This option will enable spectrum measurement for the iwl3945 driver.
 
-         This driver uses the kernel's mac80211 subsystem.
+config IWL3945_DEBUG
+       bool "Enable full debugging output in iwl3945 driver"
+       depends on IWL3945
+       ---help---
+         This option will enable debug tracing output for the iwl3945
+         driver.
+
+         This will result in the kernel module being ~100k larger.  You can
+         control which debug output is sent to the kernel log by setting the
+         value in
 
-         See <file:Documentation/networking/README.iwlwifi> for
-         information on the capabilities currently enabled in this
-         driver and for tips for debugging any issues or problems.
+                 /sys/bus/pci/drivers/${DRIVER}/debug_level
 
-         In order to use this driver, you will need a microcode (uCode)
-         image for it. You can obtain the microcode from:
+         This entry will only exist if this option is enabled.
 
-                 <http://intellinuxwireless.org/>.
+         To set a value, simply echo an 8-byte hex value to the same file:
+
+                 % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
 
-         See the above referenced README.iwlwifi for information on where
-         to install the microcode images.
+         You can find the list of debug mask values in:
+                 drivers/net/wireless/iwlwifi/iwl-3945-debug.h
+
+         If this is your first time using this driver, you should say Y here
+         as the debug information can assist others in helping you resolve
+         any problems you may encounter.
 
-         If you want to compile the driver as a module ( = code which can be
-         inserted in and remvoed from the running kernel whenever you want),
-         say M here and read <file:Documentation/kbuild/modules.txt>.  The
-         module will be called iwl3945.ko.
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h
new file mode 100644 (file)
index 0000000..46bb2c7
--- /dev/null
@@ -0,0 +1,1728 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ *
+ * 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.GPL.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * 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 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.
+ *
+ *****************************************************************************/
+/*
+ * Please use this file (iwl-3945-commands.h) only for uCode API definitions.
+ * Please use iwl-3945-hw.h for hardware-related definitions.
+ * Please use iwl-3945.h for driver implementation definitions.
+ */
+
+#ifndef __iwl_3945_commands_h__
+#define __iwl_3945_commands_h__
+
+enum {
+       REPLY_ALIVE = 0x1,
+       REPLY_ERROR = 0x2,
+
+       /* RXON and QOS commands */
+       REPLY_RXON = 0x10,
+       REPLY_RXON_ASSOC = 0x11,
+       REPLY_QOS_PARAM = 0x13,
+       REPLY_RXON_TIMING = 0x14,
+
+       /* Multi-Station support */
+       REPLY_ADD_STA = 0x18,
+       REPLY_REMOVE_STA = 0x19,        /* not used */
+       REPLY_REMOVE_ALL_STA = 0x1a,    /* not used */
+
+       /* RX, TX, LEDs */
+       REPLY_3945_RX = 0x1b,           /* 3945 only */
+       REPLY_TX = 0x1c,
+       REPLY_RATE_SCALE = 0x47,        /* 3945 only */
+       REPLY_LEDS_CMD = 0x48,
+       REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
+
+       /* 802.11h related */
+       RADAR_NOTIFICATION = 0x70,      /* not used */
+       REPLY_QUIET_CMD = 0x71,         /* not used */
+       REPLY_CHANNEL_SWITCH = 0x72,
+       CHANNEL_SWITCH_NOTIFICATION = 0x73,
+       REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
+       SPECTRUM_MEASURE_NOTIFICATION = 0x75,
+
+       /* Power Management */
+       POWER_TABLE_CMD = 0x77,
+       PM_SLEEP_NOTIFICATION = 0x7A,
+       PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
+
+       /* Scan commands and notifications */
+       REPLY_SCAN_CMD = 0x80,
+       REPLY_SCAN_ABORT_CMD = 0x81,
+       SCAN_START_NOTIFICATION = 0x82,
+       SCAN_RESULTS_NOTIFICATION = 0x83,
+       SCAN_COMPLETE_NOTIFICATION = 0x84,
+
+       /* IBSS/AP commands */
+       BEACON_NOTIFICATION = 0x90,
+       REPLY_TX_BEACON = 0x91,
+       WHO_IS_AWAKE_NOTIFICATION = 0x94,       /* not used */
+
+       /* Miscellaneous commands */
+       QUIET_NOTIFICATION = 0x96,              /* not used */
+       REPLY_TX_PWR_TABLE_CMD = 0x97,
+       MEASURE_ABORT_NOTIFICATION = 0x99,      /* not used */
+
+       /* Bluetooth device coexistance config command */
+       REPLY_BT_CONFIG = 0x9b,
+
+       /* Statistics */
+       REPLY_STATISTICS_CMD = 0x9c,
+       STATISTICS_NOTIFICATION = 0x9d,
+
+       /* RF-KILL commands and notifications */
+       REPLY_CARD_STATE_CMD = 0xa0,
+       CARD_STATE_NOTIFICATION = 0xa1,
+
+       /* Missed beacons notification */
+       MISSED_BEACONS_NOTIFICATION = 0xa2,
+
+       REPLY_MAX = 0xff
+};
+
+/******************************************************************************
+ * (0)
+ * Commonly used structures and definitions:
+ * Command header, txpower
+ *
+ *****************************************************************************/
+
+/* iwl3945_cmd_header flags value */
+#define IWL_CMD_FAILED_MSK 0x40
+
+/**
+ * struct iwl3945_cmd_header
+ *
+ * This header format appears in the beginning of each command sent from the
+ * driver, and each response/notification received from uCode.
+ */
+struct iwl3945_cmd_header {
+       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
+       u8 flags;       /* IWL_CMD_* */
+       /*
+        * The driver sets up the sequence number to values of its chosing.
+        * uCode does not use this value, but passes it back to the driver
+        * when sending the response to each driver-originated command, so
+        * the driver can match the response to the command.  Since the values
+        * don't get used by uCode, the driver may set up an arbitrary format.
+        *
+        * There is one exception:  uCode sets bit 15 when it originates
+        * the response/notification, i.e. when the response/notification
+        * is not a direct response to a command sent by the driver.  For
+        * example, uCode issues REPLY_3945_RX when it sends a received frame
+        * to the driver; it is not a direct response to any driver command.
+        *
+        * The Linux driver uses the following format:
+        *
+        *  0:7    index/position within Tx queue
+        *  8:13   Tx queue selection
+        * 14:14   driver sets this to indicate command is in the 'huge'
+        *         storage at the end of the command buffers, i.e. scan cmd
+        * 15:15   uCode sets this in uCode-originated response/notification
+        */
+       __le16 sequence;
+
+       /* command or response/notification data follows immediately */
+       u8 data[0];
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_tx_power
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Each entry contains two values:
+ * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
+ *     linear value that multiplies the output of the digital signal processor,
+ *     before being sent to the analog radio.
+ * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
+ *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
+ */
+struct iwl3945_tx_power {
+       u8 tx_gain;             /* gain for analog radio */
+       u8 dsp_atten;           /* gain for DSP */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_power_per_rate
+ *
+ * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl3945_power_per_rate {
+       u8 rate;                /* plcp */
+       struct iwl3945_tx_power tpc;
+       u8 reserved;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (0a)
+ * Alive and Error Commands & Responses:
+ *
+ *****************************************************************************/
+
+#define UCODE_VALID_OK __constant_cpu_to_le32(0x1)
+#define INITIALIZE_SUBTYPE    (9)
+
+/*
+ * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
+ *
+ * uCode issues this "initialize alive" notification once the initialization
+ * uCode image has completed its work, and is ready to load the runtime image.
+ * This is the *first* "alive" notification that the driver will receive after
+ * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
+ *
+ * See comments documenting "BSM" (bootstrap state machine).
+ */
+struct iwl3945_init_alive_resp {
+       u8 ucode_minor;
+       u8 ucode_major;
+       __le16 reserved1;
+       u8 sw_rev[8];
+       u8 ver_type;
+       u8 ver_subtype;                 /* "9" for initialize alive */
+       __le16 reserved2;
+       __le32 log_event_table_ptr;
+       __le32 error_event_table_ptr;
+       __le32 timestamp;
+       __le32 is_valid;
+} __attribute__ ((packed));
+
+
+/**
+ * REPLY_ALIVE = 0x1 (response only, not a command)
+ *
+ * uCode issues this "alive" notification once the runtime image is ready
+ * to receive commands from the driver.  This is the *second* "alive"
+ * notification that the driver will receive after rebooting uCode;
+ * this "alive" is indicated by subtype field != 9.
+ *
+ * See comments documenting "BSM" (bootstrap state machine).
+ *
+ * This response includes two pointers to structures within the device's
+ * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
+ *
+ * 1)  log_event_table_ptr indicates base of the event log.  This traces
+ *     a 256-entry history of uCode execution within a circular buffer.
+ *
+ * 2)  error_event_table_ptr indicates base of the error log.  This contains
+ *     information about any uCode error that occurs.
+ *
+ * The Linux driver can print both logs to the system log when a uCode error
+ * occurs.
+ */
+struct iwl3945_alive_resp {
+       u8 ucode_minor;
+       u8 ucode_major;
+       __le16 reserved1;
+       u8 sw_rev[8];
+       u8 ver_type;
+       u8 ver_subtype;                 /* not "9" for runtime alive */
+       __le16 reserved2;
+       __le32 log_event_table_ptr;     /* SRAM address for event log */
+       __le32 error_event_table_ptr;   /* SRAM address for error log */
+       __le32 timestamp;
+       __le32 is_valid;
+} __attribute__ ((packed));
+
+union tsf {
+       u8 byte[8];
+       __le16 word[4];
+       __le32 dw[2];
+};
+
+/*
+ * REPLY_ERROR = 0x2 (response only, not a command)
+ */
+struct iwl3945_error_resp {
+       __le32 error_type;
+       u8 cmd_id;
+       u8 reserved1;
+       __le16 bad_cmd_seq_num;
+       __le16 reserved2;
+       __le32 error_info;
+       union tsf timestamp;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (1)
+ * RXON Commands & Responses:
+ *
+ *****************************************************************************/
+
+/*
+ * Rx config defines & structure
+ */
+/* rx_config device types  */
+enum {
+       RXON_DEV_TYPE_AP = 1,
+       RXON_DEV_TYPE_ESS = 3,
+       RXON_DEV_TYPE_IBSS = 4,
+       RXON_DEV_TYPE_SNIFFER = 6,
+};
+
+/* rx_config flags */
+/* band & modulation selection */
+#define RXON_FLG_BAND_24G_MSK           __constant_cpu_to_le32(1 << 0)
+#define RXON_FLG_CCK_MSK                __constant_cpu_to_le32(1 << 1)
+/* auto detection enable */
+#define RXON_FLG_AUTO_DETECT_MSK        __constant_cpu_to_le32(1 << 2)
+/* TGg protection when tx */
+#define RXON_FLG_TGG_PROTECT_MSK        __constant_cpu_to_le32(1 << 3)
+/* cck short slot & preamble */
+#define RXON_FLG_SHORT_SLOT_MSK          __constant_cpu_to_le32(1 << 4)
+#define RXON_FLG_SHORT_PREAMBLE_MSK     __constant_cpu_to_le32(1 << 5)
+/* antenna selection */
+#define RXON_FLG_DIS_DIV_MSK            __constant_cpu_to_le32(1 << 7)
+#define RXON_FLG_ANT_SEL_MSK            __constant_cpu_to_le32(0x0f00)
+#define RXON_FLG_ANT_A_MSK              __constant_cpu_to_le32(1 << 8)
+#define RXON_FLG_ANT_B_MSK              __constant_cpu_to_le32(1 << 9)
+/* radar detection enable */
+#define RXON_FLG_RADAR_DETECT_MSK       __constant_cpu_to_le32(1 << 12)
+#define RXON_FLG_TGJ_NARROW_BAND_MSK    __constant_cpu_to_le32(1 << 13)
+/* rx response to host with 8-byte TSF
+* (according to ON_AIR deassertion) */
+#define RXON_FLG_TSF2HOST_MSK           __constant_cpu_to_le32(1 << 15)
+
+/* rx_config filter flags */
+/* accept all data frames */
+#define RXON_FILTER_PROMISC_MSK         __constant_cpu_to_le32(1 << 0)
+/* pass control & management to host */
+#define RXON_FILTER_CTL2HOST_MSK        __constant_cpu_to_le32(1 << 1)
+/* accept multi-cast */
+#define RXON_FILTER_ACCEPT_GRP_MSK      __constant_cpu_to_le32(1 << 2)
+/* don't decrypt uni-cast frames */
+#define RXON_FILTER_DIS_DECRYPT_MSK     __constant_cpu_to_le32(1 << 3)
+/* don't decrypt multi-cast frames */
+#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4)
+/* STA is associated */
+#define RXON_FILTER_ASSOC_MSK           __constant_cpu_to_le32(1 << 5)
+/* transfer to host non bssid beacons in associated state */
+#define RXON_FILTER_BCON_AWARE_MSK      __constant_cpu_to_le32(1 << 6)
+
+/**
+ * REPLY_RXON = 0x10 (command, has simple generic response)
+ *
+ * RXON tunes the radio tuner to a service channel, and sets up a number
+ * of parameters that are used primarily for Rx, but also for Tx operations.
+ *
+ * NOTE:  When tuning to a new channel, driver must set the
+ *        RXON_FILTER_ASSOC_MSK to 0.  This will clear station-dependent
+ *        info within the device, including the station tables, tx retry
+ *        rate tables, and txpower tables.  Driver must build a new station
+ *        table and txpower table before transmitting anything on the RXON
+ *        channel.
+ *
+ * NOTE:  All RXONs wipe clean the internal txpower table.  Driver must
+ *        issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
+ *        regardless of whether RXON_FILTER_ASSOC_MSK is set.
+ */
+struct iwl3945_rxon_cmd {
+       u8 node_addr[6];
+       __le16 reserved1;
+       u8 bssid_addr[6];
+       __le16 reserved2;
+       u8 wlap_bssid_addr[6];
+       __le16 reserved3;
+       u8 dev_type;
+       u8 air_propagation;
+       __le16 reserved4;
+       u8 ofdm_basic_rates;
+       u8 cck_basic_rates;
+       __le16 assoc_id;
+       __le32 flags;
+       __le32 filter_flags;
+       __le16 channel;
+       __le16 reserved5;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl3945_rxon_assoc_cmd {
+       __le32 flags;
+       __le32 filter_flags;
+       u8 ofdm_basic_rates;
+       u8 cck_basic_rates;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
+ */
+struct iwl3945_rxon_time_cmd {
+       union tsf timestamp;
+       __le16 beacon_interval;
+       __le16 atim_window;
+       __le32 beacon_init_val;
+       __le16 listen_interval;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
+ */
+struct iwl3945_channel_switch_cmd {
+       u8 band;
+       u8 expect_beacon;
+       __le16 channel;
+       __le32 rxon_flags;
+       __le32 rxon_filter_flags;
+       __le32 switch_time;
+       struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+/*
+ * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
+ */
+struct iwl3945_csa_notification {
+       __le16 band;
+       __le16 channel;
+       __le32 status;          /* 0 - OK, 1 - fail */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (2)
+ * Quality-of-Service (QOS) Commands & Responses:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
+ * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
+ *
+ * @cw_min: Contention window, start value in numbers of slots.
+ *          Should be a power-of-2, minus 1.  Device's default is 0x0f.
+ * @cw_max: Contention window, max value in numbers of slots.
+ *          Should be a power-of-2, minus 1.  Device's default is 0x3f.
+ * @aifsn:  Number of slots in Arbitration Interframe Space (before
+ *          performing random backoff timing prior to Tx).  Device default 1.
+ * @edca_txop:  Length of Tx opportunity, in uSecs.  Device default is 0.
+ *
+ * Device will automatically increase contention window by (2*CW) + 1 for each
+ * transmission retry.  Device uses cw_max as a bit mask, ANDed with new CW
+ * value, to cap the CW value.
+ */
+struct iwl3945_ac_qos {
+       __le16 cw_min;
+       __le16 cw_max;
+       u8 aifsn;
+       u8 reserved1;
+       __le16 edca_txop;
+} __attribute__ ((packed));
+
+/* QoS flags defines */
+#define QOS_PARAM_FLG_UPDATE_EDCA_MSK  __constant_cpu_to_le32(0x01)
+#define QOS_PARAM_FLG_TGN_MSK          __constant_cpu_to_le32(0x02)
+#define QOS_PARAM_FLG_TXOP_TYPE_MSK    __constant_cpu_to_le32(0x10)
+
+/* Number of Access Categories (AC) (EDCA), queues 0..3 */
+#define AC_NUM                4
+
+/*
+ * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
+ *
+ * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
+ * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
+ */
+struct iwl3945_qosparam_cmd {
+       __le32 qos_flags;
+       struct iwl3945_ac_qos ac[AC_NUM];
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (3)
+ * Add/Modify Stations Commands & Responses:
+ *
+ *****************************************************************************/
+/*
+ * Multi station support
+ */
+
+/* Special, dedicated locations within device's station table */
+#define        IWL_AP_ID               0
+#define IWL_MULTICAST_ID       1
+#define        IWL_STA_ID              2
+#define        IWL3945_BROADCAST_ID    24
+#define IWL3945_STATION_COUNT  25
+
+#define        IWL_STATION_COUNT       32      /* MAX(3945,4965)*/
+#define        IWL_INVALID_STATION     255
+
+#define STA_FLG_TX_RATE_MSK            __constant_cpu_to_le32(1 << 2);
+#define STA_FLG_PWR_SAVE_MSK           __constant_cpu_to_le32(1 << 8);
+
+/* Use in mode field.  1: modify existing entry, 0: add new station entry */
+#define STA_CONTROL_MODIFY_MSK         0x01
+
+/* key flags __le16*/
+#define STA_KEY_FLG_ENCRYPT_MSK        __constant_cpu_to_le16(0x7)
+#define STA_KEY_FLG_NO_ENC     __constant_cpu_to_le16(0x0)
+#define STA_KEY_FLG_WEP                __constant_cpu_to_le16(0x1)
+#define STA_KEY_FLG_CCMP       __constant_cpu_to_le16(0x2)
+#define STA_KEY_FLG_TKIP       __constant_cpu_to_le16(0x3)
+
+#define STA_KEY_FLG_KEYID_POS  8
+#define STA_KEY_FLG_INVALID    __constant_cpu_to_le16(0x0800)
+
+/* Flags indicate whether to modify vs. don't change various station params */
+#define        STA_MODIFY_KEY_MASK             0x01
+#define        STA_MODIFY_TID_DISABLE_TX       0x02
+#define        STA_MODIFY_TX_RATE_MSK          0x04
+
+/*
+ * Antenna masks:
+ * bit14:15 01 B inactive, A active
+ *          10 B active, A inactive
+ *          11 Both active
+ */
+#define RATE_MCS_ANT_A_POS     14
+#define RATE_MCS_ANT_B_POS     15
+#define RATE_MCS_ANT_A_MSK     0x4000
+#define RATE_MCS_ANT_B_MSK     0x8000
+#define RATE_MCS_ANT_AB_MSK    0xc000
+
+struct iwl3945_keyinfo {
+       __le16 key_flags;
+       u8 tkip_rx_tsc_byte2;   /* TSC[2] for key mix ph1 detection */
+       u8 reserved1;
+       __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
+       __le16 reserved2;
+       u8 key[16];             /* 16-byte unicast decryption key */
+} __attribute__ ((packed));
+
+/**
+ * struct sta_id_modify
+ * @addr[ETH_ALEN]: station's MAC address
+ * @sta_id: index of station in uCode's station table
+ * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
+ *
+ * Driver selects unused table index when adding new station,
+ * or the index to a pre-existing station entry when modifying that station.
+ * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
+ *
+ * modify_mask flags select which parameters to modify vs. leave alone.
+ */
+struct sta_id_modify {
+       u8 addr[ETH_ALEN];
+       __le16 reserved1;
+       u8 sta_id;
+       u8 modify_mask;
+       __le16 reserved2;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_ADD_STA = 0x18 (command)
+ *
+ * The device contains an internal table of per-station information,
+ * with info on security keys, aggregation parameters, and Tx rates for
+ * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
+ * 3945 uses REPLY_RATE_SCALE to set up rate tables).
+ *
+ * REPLY_ADD_STA sets up the table entry for one station, either creating
+ * a new entry, or modifying a pre-existing one.
+ *
+ * NOTE:  RXON command (without "associated" bit set) wipes the station table
+ *        clean.  Moving into RF_KILL state does this also.  Driver must set up
+ *        new station table before transmitting anything on the RXON channel
+ *        (except active scans or active measurements; those commands carry
+ *        their own txpower/rate setup data).
+ *
+ *        When getting started on a new channel, driver must set up the
+ *        IWL_BROADCAST_ID entry (last entry in the table).  For a client
+ *        station in a BSS, once an AP is selected, driver sets up the AP STA
+ *        in the IWL_AP_ID entry (1st entry in the table).  BROADCAST and AP
+ *        are all that are needed for a BSS client station.  If the device is
+ *        used as AP, or in an IBSS network, driver must set up station table
+ *        entries for all STAs in network, starting with index IWL_STA_ID.
+ */
+struct iwl3945_addsta_cmd {
+       u8 mode;                /* 1: modify existing, 0: add new station */
+       u8 reserved[3];
+       struct sta_id_modify sta;
+       struct iwl3945_keyinfo key;
+       __le32 station_flags;           /* STA_FLG_* */
+       __le32 station_flags_msk;       /* STA_FLG_* */
+
+       /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+        * corresponding to bit (e.g. bit 5 controls TID 5).
+        * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+       __le16 tid_disable_tx;
+
+       __le16 rate_n_flags;
+
+       /* TID for which to add block-ack support.
+        * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+       u8 add_immediate_ba_tid;
+
+       /* TID for which to remove block-ack support.
+        * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+       u8 remove_immediate_ba_tid;
+
+       /* Starting Sequence Number for added block-ack support.
+        * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+       __le16 add_immediate_ba_ssn;
+} __attribute__ ((packed));
+
+#define ADD_STA_SUCCESS_MSK            0x1
+#define ADD_STA_NO_ROOM_IN_TABLE       0x2
+#define ADD_STA_NO_BLOCK_ACK_RESOURCE  0x4
+/*
+ * REPLY_ADD_STA = 0x18 (response)
+ */
+struct iwl3945_add_sta_resp {
+       u8 status;      /* ADD_STA_* */
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (4)
+ * Rx Responses:
+ *
+ *****************************************************************************/
+
+struct iwl3945_rx_frame_stats {
+       u8 phy_count;
+       u8 id;
+       u8 rssi;
+       u8 agc;
+       __le16 sig_avg;
+       __le16 noise_diff;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl3945_rx_frame_hdr {
+       __le16 channel;
+       __le16 phy_flags;
+       u8 reserved1;
+       u8 rate;
+       __le16 len;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+#define        RX_RES_STATUS_NO_CRC32_ERROR    __constant_cpu_to_le32(1 << 0)
+#define        RX_RES_STATUS_NO_RXE_OVERFLOW   __constant_cpu_to_le32(1 << 1)
+
+#define        RX_RES_PHY_FLAGS_BAND_24_MSK    __constant_cpu_to_le16(1 << 0)
+#define        RX_RES_PHY_FLAGS_MOD_CCK_MSK            __constant_cpu_to_le16(1 << 1)
+#define        RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK     __constant_cpu_to_le16(1 << 2)
+#define        RX_RES_PHY_FLAGS_NARROW_BAND_MSK        __constant_cpu_to_le16(1 << 3)
+#define        RX_RES_PHY_FLAGS_ANTENNA_MSK            __constant_cpu_to_le16(0xf0)
+
+#define        RX_RES_STATUS_SEC_TYPE_MSK      (0x7 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_NONE     (0x0 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_WEP      (0x1 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_CCMP     (0x2 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_TKIP     (0x3 << 8)
+
+#define        RX_RES_STATUS_DECRYPT_TYPE_MSK  (0x3 << 11)
+#define        RX_RES_STATUS_NOT_DECRYPT       (0x0 << 11)
+#define        RX_RES_STATUS_DECRYPT_OK        (0x3 << 11)
+#define        RX_RES_STATUS_BAD_ICV_MIC       (0x1 << 11)
+#define        RX_RES_STATUS_BAD_KEY_TTAK      (0x2 << 11)
+
+struct iwl3945_rx_frame_end {
+       __le32 status;
+       __le64 timestamp;
+       __le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE:  DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl3945_rx_frame {
+       struct iwl3945_rx_frame_stats stats;
+       struct iwl3945_rx_frame_hdr hdr;
+       struct iwl3945_rx_frame_end end;
+} __attribute__ ((packed));
+
+/* Fixed (non-configurable) rx data from phy */
+#define RX_PHY_FLAGS_ANTENNAE_OFFSET           (4)
+#define RX_PHY_FLAGS_ANTENNAE_MASK             (0x70)
+#define IWL_AGC_DB_MASK        (0x3f80)        /* MASK(7,13) */
+#define IWL_AGC_DB_POS         (7)
+struct iwl4965_rx_non_cfg_phy {
+       __le16 ant_selection;   /* ant A bit 4, ant B bit 5, ant C bit 6 */
+       __le16 agc_info;        /* agc code 0:6, agc dB 7:13, reserved 14:15 */
+       u8 rssi_info[6];        /* we use even entries, 0/2/4 for A/B/C rssi */
+       u8 pad[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_4965_RX = 0xc3 (response only, not a command)
+ * Used only for legacy (non 11n) frames.
+ */
+#define RX_RES_PHY_CNT 14
+struct iwl4965_rx_phy_res {
+       u8 non_cfg_phy_cnt;     /* non configurable DSP phy data byte count */
+       u8 cfg_phy_cnt;         /* configurable DSP phy data byte count */
+       u8 stat_id;             /* configurable DSP phy data set ID */
+       u8 reserved1;
+       __le64 timestamp;       /* TSF at on air rise */
+       __le32 beacon_time_stamp; /* beacon at on-air rise */
+       __le16 phy_flags;       /* general phy flags: band, modulation, ... */
+       __le16 channel;         /* channel number */
+       __le16 non_cfg_phy[RX_RES_PHY_CNT];     /* upto 14 phy entries */
+       __le32 reserved2;
+       __le32 rate_n_flags;
+       __le16 byte_count;              /* frame's byte-count */
+       __le16 reserved3;
+} __attribute__ ((packed));
+
+struct iwl4965_rx_mpdu_res_start {
+       __le16 byte_count;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (5)
+ * Tx Commands & Responses:
+ *
+ * Driver must place each REPLY_TX command into one of the prioritized Tx
+ * queues in host DRAM, shared between driver and device.  When the device's
+ * Tx scheduler and uCode are preparing to transmit, the device pulls the
+ * Tx command over the PCI bus via one of the device's Tx DMA channels,
+ * to fill an internal FIFO from which data will be transmitted.
+ *
+ * uCode handles all timing and protocol related to control frames
+ * (RTS/CTS/ACK), based on flags in the Tx command.
+ *
+ * uCode handles retrying Tx when an ACK is expected but not received.
+ * This includes trying lower data rates than the one requested in the Tx
+ * command, as set up by the REPLY_RATE_SCALE (for 3945) or
+ * REPLY_TX_LINK_QUALITY_CMD (4965).
+ *
+ * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
+ * This command must be executed after every RXON command, before Tx can occur.
+ *****************************************************************************/
+
+/* REPLY_TX Tx flags field */
+
+/* 1: Use Request-To-Send protocol before this frame.
+ * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
+#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1)
+
+/* 1: Transmit Clear-To-Send to self before this frame.
+ * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
+ * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
+#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2)
+
+/* 1: Expect ACK from receiving station
+ * 0: Don't expect ACK (MAC header's duration field s/b 0)
+ * Set this for unicast frames, but not broadcast/multicast. */
+#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3)
+
+/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
+ *    Tx command's initial_rate_index indicates first rate to try;
+ *    uCode walks through table for additional Tx attempts.
+ * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
+ *    This rate will be used for all Tx attempts; it will not be scaled. */
+#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4)
+
+/* 1: Expect immediate block-ack.
+ * Set when Txing a block-ack request frame.  Also set TX_CMD_FLG_ACK_MSK. */
+#define TX_CMD_FLG_IMM_BA_RSP_MASK  __constant_cpu_to_le32(1 << 6)
+
+/* 1: Frame requires full Tx-Op protection.
+ * Set this if either RTS or CTS Tx Flag gets set. */
+#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7)
+
+/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
+ * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
+#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00)
+#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8)
+#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9)
+
+/* 1: Ignore Bluetooth priority for this frame.
+ * 0: Delay Tx until Bluetooth device is done (normal usage). */
+#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12)
+
+/* 1: uCode overrides sequence control field in MAC header.
+ * 0: Driver provides sequence control field in MAC header.
+ * Set this for management frames, non-QOS data frames, non-unicast frames,
+ * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
+#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13)
+
+/* 1: This frame is non-last MPDU; more fragments are coming.
+ * 0: Last fragment, or not using fragmentation. */
+#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14)
+
+/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
+ * 0: No TSF required in outgoing frame.
+ * Set this for transmitting beacons and probe responses. */
+#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16)
+
+/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
+ *    alignment of frame's payload data field.
+ * 0: No pad
+ * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
+ * field (but not both).  Driver must align frame data (i.e. data following
+ * MAC header) to DWORD boundary. */
+#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20)
+
+/* HCCA-AP - disable duration overwriting. */
+#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25)
+
+/*
+ * TX command security control
+ */
+#define TX_CMD_SEC_WEP         0x01
+#define TX_CMD_SEC_CCM         0x02
+#define TX_CMD_SEC_TKIP                0x03
+#define TX_CMD_SEC_MSK         0x03
+#define TX_CMD_SEC_SHIFT       6
+#define TX_CMD_SEC_KEY128      0x08
+
+/*
+ * REPLY_TX = 0x1c (command)
+ */
+struct iwl3945_tx_cmd {
+       /*
+        * MPDU byte count:
+        * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+        * + 8 byte IV for CCM or TKIP (not used for WEP)
+        * + Data payload
+        * + 8-byte MIC (not used for CCM/WEP)
+        * NOTE:  Does not include Tx command bytes, post-MAC pad bytes,
+        *        MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+        * Range: 14-2342 bytes.
+        */
+       __le16 len;
+
+       /*
+        * MPDU or MSDU byte count for next frame.
+        * Used for fragmentation and bursting, but not 11n aggregation.
+        * Same as "len", but for next frame.  Set to 0 if not applicable.
+        */
+       __le16 next_frame_len;
+
+       __le32 tx_flags;        /* TX_CMD_FLG_* */
+
+       u8 rate;
+
+       /* Index of recipient station in uCode's station table */
+       u8 sta_id;
+       u8 tid_tspec;
+       u8 sec_ctl;
+       u8 key[16];
+       union {
+               u8 byte[8];
+               __le16 word[4];
+               __le32 dw[2];
+       } tkip_mic;
+       __le32 next_frame_info;
+       union {
+               __le32 life_time;
+               __le32 attempt;
+       } stop_time;
+       u8 supp_rates[2];
+       u8 rts_retry_limit;     /*byte 50 */
+       u8 data_retry_limit;    /*byte 51 */
+       union {
+               __le16 pm_frame_timeout;
+               __le16 attempt_duration;
+       } timeout;
+
+       /*
+        * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+        * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+        */
+       __le16 driver_txop;
+
+       /*
+        * MAC header goes here, followed by 2 bytes padding if MAC header
+        * length is 26 or 30 bytes, followed by payload data
+        */
+       u8 payload[0];
+       struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/* TX command response is sent after *all* transmission attempts.
+ *
+ * NOTES:
+ *
+ * TX_STATUS_FAIL_NEXT_FRAG
+ *
+ * If the fragment flag in the MAC header for the frame being transmitted
+ * is set and there is insufficient time to transmit the next frame, the
+ * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
+ *
+ * TX_STATUS_FIFO_UNDERRUN
+ *
+ * Indicates the host did not provide bytes to the FIFO fast enough while
+ * a TX was in progress.
+ *
+ * TX_STATUS_FAIL_MGMNT_ABORT
+ *
+ * This status is only possible if the ABORT ON MGMT RX parameter was
+ * set to true with the TX command.
+ *
+ * If the MSB of the status parameter is set then an abort sequence is
+ * required.  This sequence consists of the host activating the TX Abort
+ * control line, and then waiting for the TX Abort command response.  This
+ * indicates that a the device is no longer in a transmit state, and that the
+ * command FIFO has been cleared.  The host must then deactivate the TX Abort
+ * control line.  Receiving is still allowed in this case.
+ */
+enum {
+       TX_STATUS_SUCCESS = 0x01,
+       TX_STATUS_DIRECT_DONE = 0x02,
+       TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
+       TX_STATUS_FAIL_LONG_LIMIT = 0x83,
+       TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
+       TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
+       TX_STATUS_FAIL_NEXT_FRAG = 0x86,
+       TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
+       TX_STATUS_FAIL_DEST_PS = 0x88,
+       TX_STATUS_FAIL_ABORTED = 0x89,
+       TX_STATUS_FAIL_BT_RETRY = 0x8a,
+       TX_STATUS_FAIL_STA_INVALID = 0x8b,
+       TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
+       TX_STATUS_FAIL_TID_DISABLE = 0x8d,
+       TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
+       TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
+       TX_STATUS_FAIL_TX_LOCKED = 0x90,
+       TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
+};
+
+#define        TX_PACKET_MODE_REGULAR          0x0000
+#define        TX_PACKET_MODE_BURST_SEQ        0x0100
+#define        TX_PACKET_MODE_BURST_FIRST      0x0200
+
+enum {
+       TX_POWER_PA_NOT_ACTIVE = 0x0,
+};
+
+enum {
+       TX_STATUS_MSK = 0x000000ff,     /* bits 0:7 */
+       TX_STATUS_DELAY_MSK = 0x00000040,
+       TX_STATUS_ABORT_MSK = 0x00000080,
+       TX_PACKET_MODE_MSK = 0x0000ff00,        /* bits 8:15 */
+       TX_FIFO_NUMBER_MSK = 0x00070000,        /* bits 16:18 */
+       TX_RESERVED = 0x00780000,       /* bits 19:22 */
+       TX_POWER_PA_DETECT_MSK = 0x7f800000,    /* bits 23:30 */
+       TX_ABORT_REQUIRED_MSK = 0x80000000,     /* bits 31:31 */
+};
+
+/*
+ * REPLY_TX = 0x1c (response)
+ */
+struct iwl3945_tx_resp {
+       u8 failure_rts;
+       u8 failure_frame;
+       u8 bt_kill_count;
+       u8 rate;
+       __le32 wireless_media_time;
+       __le32 status;          /* TX status */
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
+ */
+struct iwl3945_txpowertable_cmd {
+       u8 band;                /* 0: 5 GHz, 1: 2.4 GHz */
+       u8 reserved;
+       __le16 channel;
+       struct iwl3945_power_per_rate power[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+struct iwl3945_rate_scaling_info {
+       __le16 rate_n_flags;
+       u8 try_cnt;
+       u8 next_rate_index;
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
+ *
+ * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
+ *
+ * NOTE: The table of rates passed to the uCode via the
+ * RATE_SCALE command sets up the corresponding order of
+ * rates used for all related commands, including rate
+ * masks, etc.
+ *
+ * For example, if you set 9MB (PLCP 0x0f) as the first
+ * rate in the rate table, the bit mask for that rate
+ * when passed through ofdm_basic_rates on the REPLY_RXON
+ * command would be bit 0 (1 << 0)
+ */
+struct iwl3945_rate_scaling_cmd {
+       u8 table_id;
+       u8 reserved[3];
+       struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
+ *
+ * 3945 and 4965 support hardware handshake with Bluetooth device on
+ * same platform.  Bluetooth device alerts wireless device when it will Tx;
+ * wireless device can delay or kill its own Tx to accomodate.
+ */
+struct iwl3945_bt_cmd {
+       u8 flags;
+       u8 lead_time;
+       u8 max_kill;
+       u8 reserved;
+       __le32 kill_ack_mask;
+       __le32 kill_cts_mask;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (6)
+ * Spectrum Management (802.11h) Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/*
+ * Spectrum Management
+ */
+#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK         | \
+                                RXON_FILTER_CTL2HOST_MSK        | \
+                                RXON_FILTER_ACCEPT_GRP_MSK      | \
+                                RXON_FILTER_DIS_DECRYPT_MSK     | \
+                                RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
+                                RXON_FILTER_ASSOC_MSK           | \
+                                RXON_FILTER_BCON_AWARE_MSK)
+
+struct iwl3945_measure_channel {
+       __le32 duration;        /* measurement duration in extended beacon
+                                * format */
+       u8 channel;             /* channel to measure */
+       u8 type;                /* see enum iwl3945_measure_type */
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
+ */
+struct iwl3945_spectrum_cmd {
+       __le16 len;             /* number of bytes starting from token */
+       u8 token;               /* token id */
+       u8 id;                  /* measurement id -- 0 or 1 */
+       u8 origin;              /* 0 = TGh, 1 = other, 2 = TGk */
+       u8 periodic;            /* 1 = periodic */
+       __le16 path_loss_timeout;
+       __le32 start_time;      /* start time in extended beacon format */
+       __le32 reserved2;
+       __le32 flags;           /* rxon flags */
+       __le32 filter_flags;    /* rxon filter flags */
+       __le16 channel_count;   /* minimum 1, maximum 10 */
+       __le16 reserved3;
+       struct iwl3945_measure_channel channels[10];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
+ */
+struct iwl3945_spectrum_resp {
+       u8 token;
+       u8 id;                  /* id of the prior command replaced, or 0xff */
+       __le16 status;          /* 0 - command will be handled
+                                * 1 - cannot handle (conflicts with another
+                                *     measurement) */
+} __attribute__ ((packed));
+
+enum iwl3945_measurement_state {
+       IWL_MEASUREMENT_START = 0,
+       IWL_MEASUREMENT_STOP = 1,
+};
+
+enum iwl3945_measurement_status {
+       IWL_MEASUREMENT_OK = 0,
+       IWL_MEASUREMENT_CONCURRENT = 1,
+       IWL_MEASUREMENT_CSA_CONFLICT = 2,
+       IWL_MEASUREMENT_TGH_CONFLICT = 3,
+       /* 4-5 reserved */
+       IWL_MEASUREMENT_STOPPED = 6,
+       IWL_MEASUREMENT_TIMEOUT = 7,
+       IWL_MEASUREMENT_PERIODIC_FAILED = 8,
+};
+
+#define NUM_ELEMENTS_IN_HISTOGRAM 8
+
+struct iwl3945_measurement_histogram {
+       __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
+       __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM];  /* in 1usec counts */
+} __attribute__ ((packed));
+
+/* clear channel availability counters */
+struct iwl3945_measurement_cca_counters {
+       __le32 ofdm;
+       __le32 cck;
+} __attribute__ ((packed));
+
+enum iwl3945_measure_type {
+       IWL_MEASURE_BASIC = (1 << 0),
+       IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
+       IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
+       IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
+       IWL_MEASURE_FRAME = (1 << 4),
+       /* bits 5:6 are reserved */
+       IWL_MEASURE_IDLE = (1 << 7),
+};
+
+/*
+ * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
+ */
+struct iwl3945_spectrum_notification {
+       u8 id;                  /* measurement id -- 0 or 1 */
+       u8 token;
+       u8 channel_index;       /* index in measurement channel list */
+       u8 state;               /* 0 - start, 1 - stop */
+       __le32 start_time;      /* lower 32-bits of TSF */
+       u8 band;                /* 0 - 5.2GHz, 1 - 2.4GHz */
+       u8 channel;
+       u8 type;                /* see enum iwl3945_measurement_type */
+       u8 reserved1;
+       /* NOTE:  cca_ofdm, cca_cck, basic_type, and histogram are only only
+        * valid if applicable for measurement type requested. */
+       __le32 cca_ofdm;        /* cca fraction time in 40Mhz clock periods */
+       __le32 cca_cck;         /* cca fraction time in 44Mhz clock periods */
+       __le32 cca_time;        /* channel load time in usecs */
+       u8 basic_type;          /* 0 - bss, 1 - ofdm preamble, 2 -
+                                * unidentified */
+       u8 reserved2[3];
+       struct iwl3945_measurement_histogram histogram;
+       __le32 stop_time;       /* lower 32-bits of TSF */
+       __le32 status;          /* see iwl3945_measurement_status */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (7)
+ * Power Management Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl3945_powertable_cmd - Power Table Command
+ * @flags: See below:
+ *
+ * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
+ *
+ * PM allow:
+ *   bit 0 - '0' Driver not allow power management
+ *           '1' Driver allow PM (use rest of parameters)
+ * uCode send sleep notifications:
+ *   bit 1 - '0' Don't send sleep notification
+ *           '1' send sleep notification (SEND_PM_NOTIFICATION)
+ * Sleep over DTIM
+ *   bit 2 - '0' PM have to walk up every DTIM
+ *           '1' PM could sleep over DTIM till listen Interval.
+ * PCI power managed
+ *   bit 3 - '0' (PCI_LINK_CTRL & 0x1)
+ *           '1' !(PCI_LINK_CTRL & 0x1)
+ * Force sleep Modes
+ *   bit 31/30- '00' use both mac/xtal sleeps
+ *              '01' force Mac sleep
+ *              '10' force xtal sleep
+ *              '11' Illegal set
+ *
+ * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
+ * ucode assume sleep over DTIM is allowed and we don't need to wakeup
+ * for every DTIM.
+ */
+#define IWL_POWER_VEC_SIZE 5
+
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK       __constant_cpu_to_le32(1 << 0)
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK          __constant_cpu_to_le32(1 << 2)
+#define IWL_POWER_PCI_PM_MSK                   __constant_cpu_to_le32(1 << 3)
+struct iwl3945_powertable_cmd {
+       __le32 flags;
+       __le32 rx_data_timeout;
+       __le32 tx_data_timeout;
+       __le32 sleep_interval[IWL_POWER_VEC_SIZE];
+} __attribute__((packed));
+
+/*
+ * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
+ * 3945 and 4965 identical.
+ */
+struct iwl3945_sleep_notification {
+       u8 pm_sleep_mode;
+       u8 pm_wakeup_src;
+       __le16 reserved;
+       __le32 sleep_time;
+       __le32 tsf_low;
+       __le32 bcon_timer;
+} __attribute__ ((packed));
+
+/* Sleep states.  3945 and 4965 identical. */
+enum {
+       IWL_PM_NO_SLEEP = 0,
+       IWL_PM_SLP_MAC = 1,
+       IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
+       IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
+       IWL_PM_SLP_PHY = 4,
+       IWL_PM_SLP_REPENT = 5,
+       IWL_PM_WAKEUP_BY_TIMER = 6,
+       IWL_PM_WAKEUP_BY_DRIVER = 7,
+       IWL_PM_WAKEUP_BY_RFKILL = 8,
+       /* 3 reserved */
+       IWL_PM_NUM_OF_MODES = 12,
+};
+
+/*
+ * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
+ */
+#define CARD_STATE_CMD_DISABLE 0x00    /* Put card to sleep */
+#define CARD_STATE_CMD_ENABLE  0x01    /* Wake up card */
+#define CARD_STATE_CMD_HALT    0x02    /* Power down permanently */
+struct iwl3945_card_state_cmd {
+       __le32 status;          /* CARD_STATE_CMD_* request new power state */
+} __attribute__ ((packed));
+
+/*
+ * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
+ */
+struct iwl3945_card_state_notif {
+       __le32 flags;
+} __attribute__ ((packed));
+
+#define HW_CARD_DISABLED   0x01
+#define SW_CARD_DISABLED   0x02
+#define RF_CARD_DISABLED   0x04
+#define RXON_CARD_DISABLED 0x10
+
+struct iwl3945_ct_kill_config {
+       __le32   reserved;
+       __le32   critical_temperature_M;
+       __le32   critical_temperature_R;
+}  __attribute__ ((packed));
+
+/******************************************************************************
+ * (8)
+ * Scan Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl3945_scan_channel - entry in REPLY_SCAN_CMD channel table
+ *
+ * One for each channel in the scan list.
+ * Each channel can independently select:
+ * 1)  SSID for directed active scans
+ * 2)  Txpower setting (for rate specified within Tx command)
+ * 3)  How long to stay on-channel (behavior may be modified by quiet_time,
+ *     quiet_plcp_th, good_CRC_th)
+ *
+ * To avoid uCode errors, make sure the following are true (see comments
+ * under struct iwl3945_scan_cmd about max_out_time and quiet_time):
+ * 1)  If using passive_dwell (i.e. passive_dwell != 0):
+ *     active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
+ * 2)  quiet_time <= active_dwell
+ * 3)  If restricting off-channel time (i.e. max_out_time !=0):
+ *     passive_dwell < max_out_time
+ *     active_dwell < max_out_time
+ */
+struct iwl3945_scan_channel {
+       /*
+        * type is defined as:
+        * 0:0 1 = active, 0 = passive
+        * 1:4 SSID direct bit map; if a bit is set, then corresponding
+        *     SSID IE is transmitted in probe request.
+        * 5:7 reserved
+        */
+       u8 type;
+       u8 channel;     /* band is selected by iwl3945_scan_cmd "flags" field */
+       struct iwl3945_tx_power tpc;
+       __le16 active_dwell;    /* in 1024-uSec TU (time units), typ 5-50 */
+       __le16 passive_dwell;   /* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_ssid_ie - directed scan network information element
+ *
+ * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
+ * in struct iwl3945_scan_channel; each channel may select different ssids from
+ * among the 4 entries.  SSID IEs get transmitted in reverse order of entry.
+ */
+struct iwl3945_ssid_ie {
+       u8 id;
+       u8 len;
+       u8 ssid[32];
+} __attribute__ ((packed));
+
+#define PROBE_OPTION_MAX        0x4
+#define TX_CMD_LIFE_TIME_INFINITE      __constant_cpu_to_le32(0xFFFFFFFF)
+#define IWL_GOOD_CRC_TH                __constant_cpu_to_le16(1)
+#define IWL_MAX_SCAN_SIZE 1024
+
+/*
+ * REPLY_SCAN_CMD = 0x80 (command)
+ *
+ * The hardware scan command is very powerful; the driver can set it up to
+ * maintain (relatively) normal network traffic while doing a scan in the
+ * background.  The max_out_time and suspend_time control the ratio of how
+ * long the device stays on an associated network channel ("service channel")
+ * vs. how long it's away from the service channel, tuned to other channels
+ * for scanning.
+ *
+ * max_out_time is the max time off-channel (in usec), and suspend_time
+ * is how long (in "extended beacon" format) that the scan is "suspended"
+ * after returning to the service channel.  That is, suspend_time is the
+ * time that we stay on the service channel, doing normal work, between
+ * scan segments.  The driver may set these parameters differently to support
+ * scanning when associated vs. not associated, and light vs. heavy traffic
+ * loads when associated.
+ *
+ * After receiving this command, the device's scan engine does the following;
+ *
+ * 1)  Sends SCAN_START notification to driver
+ * 2)  Checks to see if it has time to do scan for one channel
+ * 3)  Sends NULL packet, with power-save (PS) bit set to 1,
+ *     to tell AP that we're going off-channel
+ * 4)  Tunes to first channel in scan list, does active or passive scan
+ * 5)  Sends SCAN_RESULT notification to driver
+ * 6)  Checks to see if it has time to do scan on *next* channel in list
+ * 7)  Repeats 4-6 until it no longer has time to scan the next channel
+ *     before max_out_time expires
+ * 8)  Returns to service channel
+ * 9)  Sends NULL packet with PS=0 to tell AP that we're back
+ * 10) Stays on service channel until suspend_time expires
+ * 11) Repeats entire process 2-10 until list is complete
+ * 12) Sends SCAN_COMPLETE notification
+ *
+ * For fast, efficient scans, the scan command also has support for staying on
+ * a channel for just a short time, if doing active scanning and getting no
+ * responses to the transmitted probe request.  This time is controlled by
+ * quiet_time, and the number of received packets below which a channel is
+ * considered "quiet" is controlled by quiet_plcp_threshold.
+ *
+ * For active scanning on channels that have regulatory restrictions against
+ * blindly transmitting, the scan can listen before transmitting, to make sure
+ * that there is already legitimate activity on the channel.  If enough
+ * packets are cleanly received on the channel (controlled by good_CRC_th,
+ * typical value 1), the scan engine starts transmitting probe requests.
+ *
+ * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
+ *
+ * To avoid uCode errors, see timing restrictions described under
+ * struct iwl3945_scan_channel.
+ */
+struct iwl3945_scan_cmd {
+       __le16 len;
+       u8 reserved0;
+       u8 channel_count;       /* # channels in channel list */
+       __le16 quiet_time;      /* dwell only this # millisecs on quiet channel
+                                * (only for active scan) */
+       __le16 quiet_plcp_th;   /* quiet chnl is < this # pkts (typ. 1) */
+       __le16 good_CRC_th;     /* passive -> active promotion threshold */
+       __le16 reserved1;
+       __le32 max_out_time;    /* max usec to be away from associated (service)
+                                * channel */
+       __le32 suspend_time;    /* pause scan this long (in "extended beacon
+                                * format") when returning to service channel:
+                                * 3945; 31:24 # beacons, 19:0 additional usec,
+                                * 4965; 31:22 # beacons, 21:0 additional usec.
+                                */
+       __le32 flags;           /* RXON_FLG_* */
+       __le32 filter_flags;    /* RXON_FILTER_* */
+
+       /* For active scans (set to all-0s for passive scans).
+        * Does not include payload.  Must specify Tx rate; no rate scaling. */
+       struct iwl3945_tx_cmd tx_cmd;
+
+       /* For directed active scans (set to all-0s otherwise) */
+       struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX];
+
+       /*
+        * Probe request frame, followed by channel list.
+        *
+        * Size of probe request frame is specified by byte count in tx_cmd.
+        * Channel list follows immediately after probe request frame.
+        * Number of channels in list is specified by channel_count.
+        * Each channel in list is of type:
+        *
+        * struct iwl3945_scan_channel channels[0];
+        *
+        * NOTE:  Only one band of channels can be scanned per pass.  You
+        * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+        * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+        * before requesting another scan.
+        */
+       u8 data[0];
+} __attribute__ ((packed));
+
+/* Can abort will notify by complete notification with abort status. */
+#define CAN_ABORT_STATUS       __constant_cpu_to_le32(0x1)
+/* complete notification statuses */
+#define ABORT_STATUS            0x2
+
+/*
+ * REPLY_SCAN_CMD = 0x80 (response)
+ */
+struct iwl3945_scanreq_notification {
+       __le32 status;          /* 1: okay, 2: cannot fulfill request */
+} __attribute__ ((packed));
+
+/*
+ * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
+ */
+struct iwl3945_scanstart_notification {
+       __le32 tsf_low;
+       __le32 tsf_high;
+       __le32 beacon_timer;
+       u8 channel;
+       u8 band;
+       u8 reserved[2];
+       __le32 status;
+} __attribute__ ((packed));
+
+#define  SCAN_OWNER_STATUS 0x1;
+#define  MEASURE_OWNER_STATUS 0x2;
+
+#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
+/*
+ * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
+ */
+struct iwl3945_scanresults_notification {
+       u8 channel;
+       u8 band;
+       u8 reserved[2];
+       __le32 tsf_low;
+       __le32 tsf_high;
+       __le32 statistics[NUMBER_OF_STATISTICS];
+} __attribute__ ((packed));
+
+/*
+ * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
+ */
+struct iwl3945_scancomplete_notification {
+       u8 scanned_channels;
+       u8 status;
+       u8 reserved;
+       u8 last_channel;
+       __le32 tsf_low;
+       __le32 tsf_high;
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (9)
+ * IBSS/AP Commands and Notifications:
+ *
+ *****************************************************************************/
+
+/*
+ * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
+ */
+struct iwl3945_beacon_notif {
+       struct iwl3945_tx_resp beacon_notify_hdr;
+       __le32 low_tsf;
+       __le32 high_tsf;
+       __le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
+ */
+struct iwl3945_tx_beacon_cmd {
+       struct iwl3945_tx_cmd tx;
+       __le16 tim_idx;
+       u8 tim_size;
+       u8 reserved1;
+       struct ieee80211_hdr frame[0];  /* beacon frame */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (10)
+ * Statistics Commands and Notifications:
+ *
+ *****************************************************************************/
+
+#define IWL_TEMP_CONVERT 260
+
+#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
+
+/* Used for passing to driver number of successes and failures per rate */
+struct rate_histogram {
+       union {
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+       } success;
+       union {
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+       } failed;
+} __attribute__ ((packed));
+
+/* statistics command response */
+
+struct statistics_rx_phy {
+       __le32 ina_cnt;
+       __le32 fina_cnt;
+       __le32 plcp_err;
+       __le32 crc32_err;
+       __le32 overrun_err;
+       __le32 early_overrun_err;
+       __le32 crc32_good;
+       __le32 false_alarm_cnt;
+       __le32 fina_sync_err_cnt;
+       __le32 sfd_timeout;
+       __le32 fina_timeout;
+       __le32 unresponded_rts;
+       __le32 rxe_frame_limit_overrun;
+       __le32 sent_ack_cnt;
+       __le32 sent_cts_cnt;
+} __attribute__ ((packed));
+
+struct statistics_rx_non_phy {
+       __le32 bogus_cts;       /* CTS received when not expecting CTS */
+       __le32 bogus_ack;       /* ACK received when not expecting ACK */
+       __le32 non_bssid_frames;        /* number of frames with BSSID that
+                                        * doesn't belong to the STA BSSID */
+       __le32 filtered_frames; /* count frames that were dumped in the
+                                * filtering process */
+       __le32 non_channel_beacons;     /* beacons with our bss id but not on
+                                        * our serving channel */
+} __attribute__ ((packed));
+
+struct statistics_rx {
+       struct statistics_rx_phy ofdm;
+       struct statistics_rx_phy cck;
+       struct statistics_rx_non_phy general;
+} __attribute__ ((packed));
+
+struct statistics_tx {
+       __le32 preamble_cnt;
+       __le32 rx_detected_cnt;
+       __le32 bt_prio_defer_cnt;
+       __le32 bt_prio_kill_cnt;
+       __le32 few_bytes_cnt;
+       __le32 cts_timeout;
+       __le32 ack_timeout;
+       __le32 expected_ack_cnt;
+       __le32 actual_ack_cnt;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+       __le32 burst_check;
+       __le32 burst_count;
+       __le32 reserved[4];
+} __attribute__ ((packed));
+
+struct statistics_div {
+       __le32 tx_on_a;
+       __le32 tx_on_b;
+       __le32 exec_time;
+       __le32 probe_time;
+} __attribute__ ((packed));
+
+struct statistics_general {
+       __le32 temperature;
+       struct statistics_dbg dbg;
+       __le32 sleep_time;
+       __le32 slots_out;
+       __le32 slots_idle;
+       __le32 ttl_timestamp;
+       struct statistics_div div;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_STATISTICS_CMD = 0x9c,
+ * 3945 and 4965 identical.
+ *
+ * This command triggers an immediate response containing uCode statistics.
+ * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
+ *
+ * If the CLEAR_STATS configuration flag is set, uCode will clear its
+ * internal copy of the statistics (counters) after issuing the response.
+ * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
+ *
+ * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
+ * STATISTICS_NOTIFICATIONs after received beacons (see below).  This flag
+ * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
+ */
+#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
+#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
+struct iwl3945_statistics_cmd {
+       __le32 configuration_flags;     /* IWL_STATS_CONF_* */
+} __attribute__ ((packed));
+
+/*
+ * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
+ *
+ * By default, uCode issues this notification after receiving a beacon
+ * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
+ * REPLY_STATISTICS_CMD 0x9c, above.
+ *
+ * Statistics counters continue to increment beacon after beacon, but are
+ * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
+ * 0x9c with CLEAR_STATS bit set (see above).
+ *
+ * uCode also issues this notification during scans.  uCode clears statistics
+ * appropriately so that each notification contains statistics for only the
+ * one channel that has just been scanned.
+ */
+#define STATISTICS_REPLY_FLG_BAND_24G_MSK         __constant_cpu_to_le32(0x2)
+#define STATISTICS_REPLY_FLG_FAT_MODE_MSK         __constant_cpu_to_le32(0x8)
+struct iwl3945_notif_statistics {
+       __le32 flag;
+       struct statistics_rx rx;
+       struct statistics_tx tx;
+       struct statistics_general general;
+} __attribute__ ((packed));
+
+
+/*
+ * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
+ */
+/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
+ * then this notification will be sent. */
+#define CONSECUTIVE_MISSED_BCONS_TH 20
+
+struct iwl3945_missed_beacon_notif {
+       __le32 consequtive_missed_beacons;
+       __le32 total_missed_becons;
+       __le32 num_expected_beacons;
+       __le32 num_recvd_beacons;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (11)
+ * Rx Calibration Commands:
+ *
+ *****************************************************************************/
+
+#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
+#define HD_TABLE_SIZE  (11)
+
+struct iwl3945_sensitivity_cmd {
+       __le16 control;
+       __le16 table[HD_TABLE_SIZE];
+} __attribute__ ((packed));
+
+struct iwl3945_calibration_cmd {
+       u8 opCode;
+       u8 flags;
+       __le16 reserved;
+       s8 diff_gain_a;
+       s8 diff_gain_b;
+       s8 diff_gain_c;
+       u8 reserved1;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (12)
+ * Miscellaneous Commands:
+ *
+ *****************************************************************************/
+
+/*
+ * LEDs Command & Response
+ * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
+ *
+ * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
+ * this command turns it on or off, or sets up a periodic blinking cycle.
+ */
+struct iwl3945_led_cmd {
+       __le32 interval;        /* "interval" in uSec */
+       u8 id;                  /* 1: Activity, 2: Link, 3: Tech */
+       u8 off;                 /* # intervals off while blinking;
+                                * "0", with >0 "on" value, turns LED on */
+       u8 on;                  /* # intervals on while blinking;
+                                * "0", regardless of "off", turns LED off */
+       u8 reserved;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (13)
+ * Union of all expected notifications/responses:
+ *
+ *****************************************************************************/
+
+struct iwl3945_rx_packet {
+       __le32 len;
+       struct iwl3945_cmd_header hdr;
+       union {
+               struct iwl3945_alive_resp alive_frame;
+               struct iwl3945_rx_frame rx_frame;
+               struct iwl3945_tx_resp tx_resp;
+               struct iwl3945_spectrum_notification spectrum_notif;
+               struct iwl3945_csa_notification csa_notif;
+               struct iwl3945_error_resp err_resp;
+               struct iwl3945_card_state_notif card_state_notif;
+               struct iwl3945_beacon_notif beacon_status;
+               struct iwl3945_add_sta_resp add_sta;
+               struct iwl3945_sleep_notification sleep_notif;
+               struct iwl3945_spectrum_resp spectrum;
+               struct iwl3945_notif_statistics stats;
+               __le32 status;
+               u8 raw[0];
+       } u;
+} __attribute__ ((packed));
+
+#define IWL_RX_FRAME_SIZE        (4 + sizeof(struct iwl3945_rx_frame))
+
+#endif                         /* __iwl3945_3945_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h
new file mode 100644 (file)
index 0000000..f853c6b
--- /dev/null
@@ -0,0 +1,152 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * 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:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#ifndef __iwl3945_debug_h__
+#define __iwl3945_debug_h__
+
+#ifdef CONFIG_IWL3945_DEBUG
+extern u32 iwl3945_debug_level;
+#define IWL_DEBUG(level, fmt, args...) \
+do { if (iwl3945_debug_level & (level)) \
+  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+
+#define IWL_DEBUG_LIMIT(level, fmt, args...) \
+do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \
+  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+#else
+static inline void IWL_DEBUG(int level, const char *fmt, ...)
+{
+}
+static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
+{
+}
+#endif                         /* CONFIG_IWL3945_DEBUG */
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IWL_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
+ * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/iwl/debug_level
+ *
+ * you simply need to add your entry to the iwl3945_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/iwl then you do not have
+ * CONFIG_IWL3945_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IWL_DL_INFO          (1 << 0)
+#define IWL_DL_MAC80211      (1 << 1)
+#define IWL_DL_HOST_COMMAND  (1 << 2)
+#define IWL_DL_STATE         (1 << 3)
+
+#define IWL_DL_RADIO         (1 << 7)
+#define IWL_DL_POWER         (1 << 8)
+#define IWL_DL_TEMP          (1 << 9)
+
+#define IWL_DL_NOTIF         (1 << 10)
+#define IWL_DL_SCAN          (1 << 11)
+#define IWL_DL_ASSOC         (1 << 12)
+#define IWL_DL_DROP          (1 << 13)
+
+#define IWL_DL_TXPOWER       (1 << 14)
+
+#define IWL_DL_AP            (1 << 15)
+
+#define IWL_DL_FW            (1 << 16)
+#define IWL_DL_RF_KILL       (1 << 17)
+#define IWL_DL_FW_ERRORS     (1 << 18)
+
+#define IWL_DL_LED           (1 << 19)
+
+#define IWL_DL_RATE          (1 << 20)
+
+#define IWL_DL_CALIB         (1 << 21)
+#define IWL_DL_WEP           (1 << 22)
+#define IWL_DL_TX            (1 << 23)
+#define IWL_DL_RX            (1 << 24)
+#define IWL_DL_ISR           (1 << 25)
+#define IWL_DL_HT            (1 << 26)
+#define IWL_DL_IO            (1 << 27)
+#define IWL_DL_11H           (1 << 28)
+
+#define IWL_DL_STATS         (1 << 29)
+#define IWL_DL_TX_REPLY      (1 << 30)
+#define IWL_DL_QOS           (1 << 31)
+
+#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
+#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
+#define IWL_DEBUG_INFO(f, a...)    IWL_DEBUG(IWL_DL_INFO, f, ## a)
+
+#define IWL_DEBUG_MAC80211(f, a...)     IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_TEMP(f, a...)   IWL_DEBUG(IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(f, a...)   IWL_DEBUG(IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(f, a...)     IWL_DEBUG(IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(f, a...)     IWL_DEBUG(IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(f, a...)    IWL_DEBUG(IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(f, a...)    IWL_DEBUG(IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
+#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
+       IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(f, a...)  IWL_DEBUG(IWL_DL_11H, f, ## a)
+
+#endif
index fb5f0649f4f6498cc26668a4278522cb8412831a..6e0187393af473f01df67b9a7817bca1371bf9e6 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral Public License as
+ * 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
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+/*
+ * Please use this file (iwl-3945-hw.h) only for hardware-related definitions.
+ * Please use iwl-3945-commands.h for uCode API definitions.
+ * Please use iwl-3945.h for driver implementation definitions.
+ */
 
 #ifndef __iwl_3945_hw__
 #define __iwl_3945_hw__
 
-#define IWL_RX_BUF_SIZE 3000
-/* card static random access memory (SRAM) for processor data and instructs */
+/*
+ * uCode queue management definitions ...
+ * Queue #4 is the command queue for 3945 and 4965.
+ */
+#define IWL_CMD_QUEUE_NUM       4
+
+/* Tx rates */
+#define IWL_CCK_RATES 4
+#define IWL_OFDM_RATES 8
+#define IWL_HT_RATES 0
+#define IWL_MAX_RATES  (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+
+/* Time constants */
+#define SHORT_SLOT_TIME 9
+#define LONG_SLOT_TIME 20
+
+/* RSSI to dBm */
+#define IWL_RSSI_OFFSET        95
+
+/*
+ * EEPROM related constants, enums, and structures.
+ */
+
+/*
+ * EEPROM access time values:
+ *
+ * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
+ *   then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
+ *   CSR_EEPROM_REG_BIT_CMD (0x2).
+ * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
+ * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
+ * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
+ */
+#define IWL_EEPROM_ACCESS_TIMEOUT      5000 /* uSec */
+#define IWL_EEPROM_ACCESS_DELAY                10   /* uSec */
+
+/*
+ * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags.
+ *
+ * IBSS and/or AP operation is allowed *only* on those channels with
+ * (VALID && IBSS && ACTIVE && !RADAR).  This restriction is in place because
+ * RADAR detection is not supported by the 3945 driver, but is a
+ * requirement for establishing a new network for legal operation on channels
+ * requiring RADAR detection or restricting ACTIVE scanning.
+ *
+ * NOTE:  "WIDE" flag indicates that 20 MHz channel is supported;
+ *        3945 does not support FAT 40 MHz-wide channels.
+ *
+ * NOTE:  Using a channel inappropriately will result in a uCode error!
+ */
+enum {
+       EEPROM_CHANNEL_VALID = (1 << 0),        /* usable for this SKU/geo */
+       EEPROM_CHANNEL_IBSS = (1 << 1),         /* usable as an IBSS channel */
+       /* Bit 2 Reserved */
+       EEPROM_CHANNEL_ACTIVE = (1 << 3),       /* active scanning allowed */
+       EEPROM_CHANNEL_RADAR = (1 << 4),        /* radar detection required */
+       EEPROM_CHANNEL_WIDE = (1 << 5),         /* 20 MHz channel okay */
+       EEPROM_CHANNEL_NARROW = (1 << 6),       /* 10 MHz channel (not used) */
+       EEPROM_CHANNEL_DFS = (1 << 7),  /* dynamic freq selection candidate */
+};
+
+/* SKU Capabilities */
+#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE                (1 << 0)
+#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
+#define EEPROM_SKU_CAP_OP_MODE_MRC                      (1 << 7)
+
+/* *regulatory* channel data from eeprom, one for each channel */
+struct iwl3945_eeprom_channel {
+       u8 flags;               /* flags copied from EEPROM */
+       s8 max_power_avg;       /* max power (dBm) on this chnl, limit 31 */
+} __attribute__ ((packed));
+
+/*
+ * Mapping of a Tx power level, at factory calibration temperature,
+ *   to a radio/DSP gain table index.
+ * One for each of 5 "sample" power levels in each band.
+ * v_det is measured at the factory, using the 3945's built-in power amplifier
+ *   (PA) output voltage detector.  This same detector is used during Tx of
+ *   long packets in normal operation to provide feedback as to proper output
+ *   level.
+ * Data copied from EEPROM.
+ * DO NOT ALTER THIS STRUCTURE!!!
+ */
+struct iwl3945_eeprom_txpower_sample {
+       u8 gain_index;          /* index into power (gain) setup table ... */
+       s8 power;               /* ... for this pwr level for this chnl group */
+       u16 v_det;              /* PA output voltage */
+} __attribute__ ((packed));
+
+/*
+ * Mappings of Tx power levels -> nominal radio/DSP gain table indexes.
+ * One for each channel group (a.k.a. "band") (1 for BG, 4 for A).
+ * Tx power setup code interpolates between the 5 "sample" power levels
+ *    to determine the nominal setup for a requested power level.
+ * Data copied from EEPROM.
+ * DO NOT ALTER THIS STRUCTURE!!!
+ */
+struct iwl3945_eeprom_txpower_group {
+       struct iwl3945_eeprom_txpower_sample samples[5];  /* 5 power levels */
+       s32 a, b, c, d, e;      /* coefficients for voltage->power
+                                * formula (signed) */
+       s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on
+                                * frequency (signed) */
+       s8 saturation_power;    /* highest power possible by h/w in this
+                                * band */
+       u8 group_channel;       /* "representative" channel # in this band */
+       s16 temperature;        /* h/w temperature at factory calib this band
+                                * (signed) */
+} __attribute__ ((packed));
+
+/*
+ * Temperature-based Tx-power compensation data, not band-specific.
+ * These coefficients are use to modify a/b/c/d/e coeffs based on
+ *   difference between current temperature and factory calib temperature.
+ * Data copied from EEPROM.
+ */
+struct iwl3945_eeprom_temperature_corr {
+       u32 Ta;
+       u32 Tb;
+       u32 Tc;
+       u32 Td;
+       u32 Te;
+} __attribute__ ((packed));
+
+/*
+ * EEPROM map
+ */
+struct iwl3945_eeprom {
+       u8 reserved0[16];
+#define EEPROM_DEVICE_ID                    (2*0x08)   /* 2 bytes */
+       u16 device_id;  /* abs.ofs: 16 */
+       u8 reserved1[2];
+#define EEPROM_PMC                          (2*0x0A)   /* 2 bytes */
+       u16 pmc;                /* abs.ofs: 20 */
+       u8 reserved2[20];
+#define EEPROM_MAC_ADDRESS                  (2*0x15)   /* 6  bytes */
+       u8 mac_address[6];      /* abs.ofs: 42 */
+       u8 reserved3[58];
+#define EEPROM_BOARD_REVISION               (2*0x35)   /* 2  bytes */
+       u16 board_revision;     /* abs.ofs: 106 */
+       u8 reserved4[11];
+#define EEPROM_BOARD_PBA_NUMBER             (2*0x3B+1) /* 9  bytes */
+       u8 board_pba_number[9]; /* abs.ofs: 119 */
+       u8 reserved5[8];
+#define EEPROM_VERSION                      (2*0x44)   /* 2  bytes */
+       u16 version;            /* abs.ofs: 136 */
+#define EEPROM_SKU_CAP                      (2*0x45)   /* 1  bytes */
+       u8 sku_cap;             /* abs.ofs: 138 */
+#define EEPROM_LEDS_MODE                    (2*0x45+1) /* 1  bytes */
+       u8 leds_mode;           /* abs.ofs: 139 */
+#define EEPROM_OEM_MODE                     (2*0x46)   /* 2  bytes */
+       u16 oem_mode;
+#define EEPROM_WOWLAN_MODE                  (2*0x47)   /* 2  bytes */
+       u16 wowlan_mode;        /* abs.ofs: 142 */
+#define EEPROM_LEDS_TIME_INTERVAL           (2*0x48)   /* 2  bytes */
+       u16 leds_time_interval; /* abs.ofs: 144 */
+#define EEPROM_LEDS_OFF_TIME                (2*0x49)   /* 1  bytes */
+       u8 leds_off_time;       /* abs.ofs: 146 */
+#define EEPROM_LEDS_ON_TIME                 (2*0x49+1) /* 1  bytes */
+       u8 leds_on_time;        /* abs.ofs: 147 */
+#define EEPROM_ALMGOR_M_VERSION             (2*0x4A)   /* 1  bytes */
+       u8 almgor_m_version;    /* abs.ofs: 148 */
+#define EEPROM_ANTENNA_SWITCH_TYPE          (2*0x4A+1) /* 1  bytes */
+       u8 antenna_switch_type; /* abs.ofs: 149 */
+       u8 reserved6[42];
+#define EEPROM_REGULATORY_SKU_ID            (2*0x60)   /* 4  bytes */
+       u8 sku_id[4];           /* abs.ofs: 192 */
+
+/*
+ * Per-channel regulatory data.
+ *
+ * Each channel that *might* be supported by 3945 or 4965 has a fixed location
+ * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
+ * txpower (MSB).
+ *
+ * Entries immediately below are for 20 MHz channel width.  FAT (40 MHz)
+ * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
+ *
+ * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
+ */
+#define EEPROM_REGULATORY_BAND_1            (2*0x62)   /* 2  bytes */
+       u16 band_1_count;       /* abs.ofs: 196 */
+#define EEPROM_REGULATORY_BAND_1_CHANNELS   (2*0x63)   /* 28 bytes */
+       struct iwl3945_eeprom_channel band_1_channels[14];  /* abs.ofs: 196 */
+
+/*
+ * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
+ * 5.0 GHz channels 7, 8, 11, 12, 16
+ * (4915-5080MHz) (none of these is ever supported)
+ */
+#define EEPROM_REGULATORY_BAND_2            (2*0x71)   /* 2  bytes */
+       u16 band_2_count;       /* abs.ofs: 226 */
+#define EEPROM_REGULATORY_BAND_2_CHANNELS   (2*0x72)   /* 26 bytes */
+       struct iwl3945_eeprom_channel band_2_channels[13];  /* abs.ofs: 228 */
+
+/*
+ * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
+ * (5170-5320MHz)
+ */
+#define EEPROM_REGULATORY_BAND_3            (2*0x7F)   /* 2  bytes */
+       u16 band_3_count;       /* abs.ofs: 254 */
+#define EEPROM_REGULATORY_BAND_3_CHANNELS   (2*0x80)   /* 24 bytes */
+       struct iwl3945_eeprom_channel band_3_channels[12];  /* abs.ofs: 256 */
+
+/*
+ * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+ * (5500-5700MHz)
+ */
+#define EEPROM_REGULATORY_BAND_4            (2*0x8C)   /* 2  bytes */
+       u16 band_4_count;       /* abs.ofs: 280 */
+#define EEPROM_REGULATORY_BAND_4_CHANNELS   (2*0x8D)   /* 22 bytes */
+       struct iwl3945_eeprom_channel band_4_channels[11];  /* abs.ofs: 282 */
+
+/*
+ * 5.7 GHz channels 145, 149, 153, 157, 161, 165
+ * (5725-5825MHz)
+ */
+#define EEPROM_REGULATORY_BAND_5            (2*0x98)   /* 2  bytes */
+       u16 band_5_count;       /* abs.ofs: 304 */
+#define EEPROM_REGULATORY_BAND_5_CHANNELS   (2*0x99)   /* 12 bytes */
+       struct iwl3945_eeprom_channel band_5_channels[6];  /* abs.ofs: 306 */
+
+       u8 reserved9[194];
+
+/*
+ * 3945 Txpower calibration data.
+ */
+#define EEPROM_TXPOWER_CALIB_GROUP0 0x200
+#define EEPROM_TXPOWER_CALIB_GROUP1 0x240
+#define EEPROM_TXPOWER_CALIB_GROUP2 0x280
+#define EEPROM_TXPOWER_CALIB_GROUP3 0x2c0
+#define EEPROM_TXPOWER_CALIB_GROUP4 0x300
+#define IWL_NUM_TX_CALIB_GROUPS 5
+       struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS];
+/* abs.ofs: 512 */
+#define EEPROM_CALIB_TEMPERATURE_CORRECT 0x340
+       struct iwl3945_eeprom_temperature_corr corrections;  /* abs.ofs: 832 */
+       u8 reserved16[172];     /* fill out to full 1024 byte block */
+} __attribute__ ((packed));
+
+#define IWL_EEPROM_IMAGE_SIZE 1024
+
+/* End of EEPROM */
+
+
+#include "iwl-3945-commands.h"
+
+#define PCI_LINK_CTRL      0x0F0
+#define PCI_POWER_SOURCE   0x0C8
+#define PCI_REG_WUM8       0x0E8
+#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
+
+/*=== CSR (control and status registers) ===*/
+#define CSR_BASE    (0x000)
+
+#define CSR_SW_VER              (CSR_BASE+0x000)
+#define CSR_HW_IF_CONFIG_REG    (CSR_BASE+0x000) /* hardware interface config */
+#define CSR_INT_COALESCING      (CSR_BASE+0x004) /* accum ints, 32-usec units */
+#define CSR_INT                 (CSR_BASE+0x008) /* host interrupt status/ack */
+#define CSR_INT_MASK            (CSR_BASE+0x00c) /* host interrupt enable */
+#define CSR_FH_INT_STATUS       (CSR_BASE+0x010) /* busmaster int status/ack*/
+#define CSR_GPIO_IN             (CSR_BASE+0x018) /* read external chip pins */
+#define CSR_RESET               (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
+#define CSR_GP_CNTRL            (CSR_BASE+0x024)
+
+/*
+ * Hardware revision info
+ * Bit fields:
+ * 31-8:  Reserved
+ *  7-4:  Type of device:  0x0 = 4965, 0xd = 3945
+ *  3-2:  Revision step:  0 = A, 1 = B, 2 = C, 3 = D
+ *  1-0:  "Dash" value, as in A-1, etc.
+ */
+#define CSR_HW_REV              (CSR_BASE+0x028)
+
+/* EEPROM reads */
+#define CSR_EEPROM_REG          (CSR_BASE+0x02c)
+#define CSR_EEPROM_GP           (CSR_BASE+0x030)
+#define CSR_GP_UCODE           (CSR_BASE+0x044)
+#define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
+#define CSR_UCODE_DRV_GP1_SET   (CSR_BASE+0x058)
+#define CSR_UCODE_DRV_GP1_CLR   (CSR_BASE+0x05c)
+#define CSR_UCODE_DRV_GP2       (CSR_BASE+0x060)
+#define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
+
+/* Analog phase-lock-loop configuration (3945 only)
+ * Set bit 24. */
+#define CSR_ANA_PLL_CFG         (CSR_BASE+0x20c)
+
+/* Bits for CSR_HW_IF_CONFIG_REG */
+#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB         (0x00000100)
+#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM         (0x00000200)
+#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC            (0x00000400)
+#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE         (0x00000800)
+#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
+#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
+#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM     (0x00200000)
+
+/* 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_FH_TX        (1 << 27) /* Tx DMA FH_INT[1:0] */
+#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
+#define CSR_INT_BIT_RF_KILL      (1 << 7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
+#define CSR_INT_BIT_CT_KILL      (1 << 6)  /* Critical temp (chip too hot) rfkill */
+#define CSR_INT_BIT_SW_RX        (1 << 3)  /* Rx, command responses, 3945 */
+#define CSR_INT_BIT_WAKEUP       (1 << 1)  /* NIC controller waking up (pwr mgmt) */
+#define CSR_INT_BIT_ALIVE        (1 << 0)  /* uCode interrupts once it initializes */
+
+#define CSR_INI_SET_MASK       (CSR_INT_BIT_FH_RX   | \
+                                CSR_INT_BIT_HW_ERR  | \
+                                CSR_INT_BIT_FH_TX   | \
+                                CSR_INT_BIT_SW_ERR  | \
+                                CSR_INT_BIT_RF_KILL | \
+                                CSR_INT_BIT_SW_RX   | \
+                                CSR_INT_BIT_WAKEUP  | \
+                                CSR_INT_BIT_ALIVE)
+
+/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
+#define CSR_FH_INT_BIT_ERR       (1 << 31) /* Error */
+#define CSR_FH_INT_BIT_HI_PRIOR  (1 << 30) /* High priority Rx, bypass coalescing */
+#define CSR_FH_INT_BIT_RX_CHNL2  (1 << 18) /* Rx channel 2 (3945 only) */
+#define CSR_FH_INT_BIT_RX_CHNL1  (1 << 17) /* Rx channel 1 */
+#define CSR_FH_INT_BIT_RX_CHNL0  (1 << 16) /* Rx channel 0 */
+#define CSR_FH_INT_BIT_TX_CHNL6  (1 << 6)  /* Tx channel 6 (3945 only) */
+#define CSR_FH_INT_BIT_TX_CHNL1  (1 << 1)  /* Tx channel 1 */
+#define CSR_FH_INT_BIT_TX_CHNL0  (1 << 0)  /* Tx channel 0 */
+
+#define CSR_FH_INT_RX_MASK     (CSR_FH_INT_BIT_HI_PRIOR | \
+                                CSR_FH_INT_BIT_RX_CHNL2 | \
+                                CSR_FH_INT_BIT_RX_CHNL1 | \
+                                CSR_FH_INT_BIT_RX_CHNL0)
+
+#define CSR_FH_INT_TX_MASK     (CSR_FH_INT_BIT_TX_CHNL6 | \
+                                CSR_FH_INT_BIT_TX_CHNL1 | \
+                                CSR_FH_INT_BIT_TX_CHNL0)
+
+
+/* RESET */
+#define CSR_RESET_REG_FLAG_NEVO_RESET                (0x00000001)
+#define CSR_RESET_REG_FLAG_FORCE_NMI                 (0x00000002)
+#define CSR_RESET_REG_FLAG_SW_RESET                  (0x00000080)
+#define CSR_RESET_REG_FLAG_MASTER_DISABLED           (0x00000100)
+#define CSR_RESET_REG_FLAG_STOP_MASTER               (0x00000200)
+
+/* GP (general purpose) CONTROL */
+#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY        (0x00000001)
+#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE              (0x00000004)
+#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ         (0x00000008)
+#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP         (0x00000010)
+
+#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN           (0x00000001)
+
+#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE         (0x07000000)
+#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE         (0x04000000)
+#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW          (0x08000000)
+
+
+/* EEPROM REG */
+#define CSR_EEPROM_REG_READ_VALID_MSK  (0x00000001)
+#define CSR_EEPROM_REG_BIT_CMD         (0x00000002)
+
+/* EEPROM GP */
+#define CSR_EEPROM_GP_VALID_MSK                (0x00000006)
+#define CSR_EEPROM_GP_BAD_SIGNATURE    (0x00000000)
+#define CSR_EEPROM_GP_IF_OWNER_MSK     (0x00000180)
+
+/* UCODE DRV GP */
+#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP             (0x00000001)
+#define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
+#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
+#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT      (0x00000008)
+
+/* GPIO */
+#define CSR_GPIO_IN_BIT_AUX_POWER                   (0x00000200)
+#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC                (0x00000000)
+#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC          CSR_GPIO_IN_BIT_AUX_POWER
+
+/* GI Chicken Bits */
+#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
+#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER  (0x20000000)
+
+/* CSR_ANA_PLL_CFG */
+#define CSR_ANA_PLL_CFG_SH             (0x00880300)
+
+/*=== HBUS (Host-side Bus) ===*/
+#define HBUS_BASE      (0x400)
+
+/*
+ * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
+ * structures, error log, event log, verifying uCode load).
+ * First write to address register, then read from or write to data register
+ * to complete the job.  Once the address register is set up, accesses to
+ * data registers auto-increment the address by one dword.
+ * Bit usage for address registers (read or write):
+ *  0-31:  memory address within device
+ */
+#define HBUS_TARG_MEM_RADDR     (HBUS_BASE+0x00c)
+#define HBUS_TARG_MEM_WADDR     (HBUS_BASE+0x010)
+#define HBUS_TARG_MEM_WDAT      (HBUS_BASE+0x018)
+#define HBUS_TARG_MEM_RDAT      (HBUS_BASE+0x01c)
+
+/*
+ * Registers for accessing device's internal peripheral registers
+ * (e.g. SCD, BSM, etc.).  First write to address register,
+ * then read from or write to data register to complete the job.
+ * Bit usage for address registers (read or write):
+ *  0-15:  register address (offset) within device
+ * 24-25:  (# bytes - 1) to read or write (e.g. 3 for dword)
+ */
+#define HBUS_TARG_PRPH_WADDR    (HBUS_BASE+0x044)
+#define HBUS_TARG_PRPH_RADDR    (HBUS_BASE+0x048)
+#define HBUS_TARG_PRPH_WDAT     (HBUS_BASE+0x04c)
+#define HBUS_TARG_PRPH_RDAT     (HBUS_BASE+0x050)
+
+/*
+ * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
+ * Indicates index to next TFD that driver will fill (1 past latest filled).
+ * Bit usage:
+ *  0-7:  queue write index
+ * 11-8:  queue selector
+ */
+#define HBUS_TARG_WRPTR         (HBUS_BASE+0x060)
+
+/* SCD (3945 Tx Frame Scheduler) */
+#define SCD_BASE                        (CSR_BASE + 0x2E00)
+
+#define SCD_MODE_REG                    (SCD_BASE + 0x000)
+#define SCD_ARASTAT_REG                 (SCD_BASE + 0x004)
+#define SCD_TXFACT_REG                  (SCD_BASE + 0x010)
+#define SCD_TXF4MF_REG                  (SCD_BASE + 0x014)
+#define SCD_TXF5MF_REG                  (SCD_BASE + 0x020)
+#define SCD_SBYP_MODE_1_REG             (SCD_BASE + 0x02C)
+#define SCD_SBYP_MODE_2_REG             (SCD_BASE + 0x030)
+
+/*=== FH (data Flow Handler) ===*/
+#define FH_BASE     (0x800)
+
+#define FH_CBCC_TABLE           (FH_BASE+0x140)
+#define FH_TFDB_TABLE           (FH_BASE+0x180)
+#define FH_RCSR_TABLE           (FH_BASE+0x400)
+#define FH_RSSR_TABLE           (FH_BASE+0x4c0)
+#define FH_TCSR_TABLE           (FH_BASE+0x500)
+#define FH_TSSR_TABLE           (FH_BASE+0x680)
+
+/* TFDB (Transmit Frame Buffer Descriptor) */
+#define FH_TFDB(_channel, buf) \
+       (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
+#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
+       (FH_TFDB_TABLE + 0x50 * _channel)
+/* CBCC _channel is [0,2] */
+#define FH_CBCC(_channel)           (FH_CBCC_TABLE+(_channel)*0x8)
+#define FH_CBCC_CTRL(_channel)      (FH_CBCC(_channel)+0x00)
+#define FH_CBCC_BASE(_channel)      (FH_CBCC(_channel)+0x04)
+
+/* RCSR _channel is [0,2] */
+#define FH_RCSR(_channel)           (FH_RCSR_TABLE+(_channel)*0x40)
+#define FH_RCSR_CONFIG(_channel)    (FH_RCSR(_channel)+0x00)
+#define FH_RCSR_RBD_BASE(_channel)  (FH_RCSR(_channel)+0x04)
+#define FH_RCSR_WPTR(_channel)      (FH_RCSR(_channel)+0x20)
+#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
+
+#define FH_RSCSR_CHNL0_WPTR        (FH_RCSR_WPTR(0))
+
+/* RSSR */
+#define FH_RSSR_CTRL            (FH_RSSR_TABLE+0x000)
+#define FH_RSSR_STATUS          (FH_RSSR_TABLE+0x004)
+/* TCSR */
+#define FH_TCSR(_channel)           (FH_TCSR_TABLE+(_channel)*0x20)
+#define FH_TCSR_CONFIG(_channel)    (FH_TCSR(_channel)+0x00)
+#define FH_TCSR_CREDIT(_channel)    (FH_TCSR(_channel)+0x04)
+#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
+/* TSSR */
+#define FH_TSSR_CBB_BASE        (FH_TSSR_TABLE+0x000)
+#define FH_TSSR_MSG_CONFIG      (FH_TSSR_TABLE+0x008)
+#define FH_TSSR_TX_STATUS       (FH_TSSR_TABLE+0x010)
+
+
+/* DBM */
+
+#define ALM_FH_SRVC_CHNL                            (6)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE     (20)
+#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH      (4)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN    (0x08000000)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE        (0x80000000)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE           (0x20000000)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128         (0x01000000)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST         (0x00001000)
+
+#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH               (0x00000000)
+
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF              (0x00000000)
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER           (0x00000001)
+
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
+
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD           (0x00200000)
+
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT            (0x00000000)
+
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
+#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
+
+#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID          (0x00004000)
+
+#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR           (0x00000001)
+
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON      (0xFF000000)
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON      (0x00FF0000)
+
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B    (0x00000400)
+
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON       (0x00000100)
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON       (0x00000080)
+
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH     (0x00000020)
+#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH           (0x00000005)
+
+#define ALM_TB_MAX_BYTES_COUNT      (0xFFF0)
+
+#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
+       ((1LU << _channel) << 24)
+#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
+       ((1LU << _channel) << 16)
+
+#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
+       (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
+        ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
+#define PCI_CFG_REV_ID_BIT_BASIC_SKU                (0x40)     /* bit 6    */
+#define PCI_CFG_REV_ID_BIT_RTP                      (0x80)     /* bit 7    */
+
+#define TFD_QUEUE_MIN           0
+#define TFD_QUEUE_MAX           6
+#define TFD_QUEUE_SIZE_MAX      (256)
+
+#define IWL_NUM_SCAN_RATES         (2)
+
+#define IWL_DEFAULT_TX_RETRY  15
+
+/*********************************************/
+
+#define RFD_SIZE                              4
+#define NUM_TFD_CHUNKS                        4
+
+#define RX_QUEUE_SIZE                         256
+#define RX_QUEUE_MASK                         255
+#define RX_QUEUE_SIZE_LOG                     8
+
+#define U32_PAD(n)             ((4-(n))&0x3)
+
+#define TFD_CTL_COUNT_SET(n)       (n << 24)
+#define TFD_CTL_COUNT_GET(ctl)     ((ctl >> 24) & 7)
+#define TFD_CTL_PAD_SET(n)         (n << 28)
+#define TFD_CTL_PAD_GET(ctl)       (ctl >> 28)
+
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
+#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
+                             sizeof(struct iwl3945_cmd_meta))
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Sizes and addresses for instruction and data memory (SRAM) in
+ * 3945's embedded processor.  Driver access is via HBUS_TARG_MEM_* regs. */
+#define RTC_INST_LOWER_BOUND                   (0x000000)
 #define ALM_RTC_INST_UPPER_BOUND               (0x014000)
+
+#define RTC_DATA_LOWER_BOUND                   (0x800000)
 #define ALM_RTC_DATA_UPPER_BOUND               (0x808000)
 
 #define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
 #define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
 
-#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
 #define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE
 #define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE
+
+/* Size of uCode instruction memory in bootstrap state machine */
+#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE
+
 #define IWL_MAX_NUM_QUEUES     8
 
-static inline int iwl_hw_valid_rtc_data_addr(u32 addr)
+static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
 {
        return (addr >= RTC_DATA_LOWER_BOUND) &&
               (addr < ALM_RTC_DATA_UPPER_BOUND);
 }
 
-/* Base physical address of iwl_shared is provided to FH_TSSR_CBB_BASE
- * and &iwl_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
-struct iwl_shared {
+/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE
+ * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */
+struct iwl3945_shared {
        __le32 tx_base_ptr[8];
        __le32 rx_read_ptr[3];
 } __attribute__ ((packed));
 
-struct iwl_tfd_frame_data {
+struct iwl3945_tfd_frame_data {
        __le32 addr;
        __le32 len;
 } __attribute__ ((packed));
 
-struct iwl_tfd_frame {
+struct iwl3945_tfd_frame {
        __le32 control_flags;
-       struct iwl_tfd_frame_data pa[4];
+       struct iwl3945_tfd_frame_data pa[4];
        u8 reserved[28];
 } __attribute__ ((packed));
 
-static inline u8 iwl_hw_get_rate(__le16 rate_n_flags)
+static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags)
 {
        return le16_to_cpu(rate_n_flags) & 0xFF;
 }
 
-static inline u16 iwl_hw_get_rate_n_flags(__le16 rate_n_flags)
+static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags)
 {
        return le16_to_cpu(rate_n_flags);
 }
 
-static inline __le16 iwl_hw_set_rate_n_flags(u8 rate, u16 flags)
+static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags)
 {
        return cpu_to_le16((u16)rate|flags);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
new file mode 100644 (file)
index 0000000..75e20d0
--- /dev/null
@@ -0,0 +1,431 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * 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:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#ifndef __iwl3945_io_h__
+#define __iwl3945_io_h__
+
+#include <linux/io.h>
+
+#include "iwl-3945-debug.h"
+
+/*
+ * IO, register, and NIC memory access functions
+ *
+ * NOTE on naming convention and macro usage for these
+ *
+ * A single _ prefix before a an access function means that no state
+ * check or debug information is printed when that function is called.
+ *
+ * A double __ prefix before an access function means that state is checked
+ * and the current line number is printed in addition to any other debug output.
+ *
+ * The non-prefixed name is the #define that maps the caller into a
+ * #define that provides the caller's __LINE__ to the double prefix version.
+ *
+ * If you wish to call the function without any debug or state checking,
+ * you should use the single _ prefix version (as is used by dependent IO
+ * routines, for example _iwl3945_read_direct32 calls the non-check version of
+ * _iwl3945_read32.)
+ *
+ * These declarations are *extremely* useful in quickly isolating code deltas
+ * which result in misconfiguring of the hardware I/O.  In combination with
+ * git-bisect and the IO debug level you can quickly determine the specific
+ * commit which breaks the IO sequence to the hardware.
+ *
+ */
+
+#define _iwl3945_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *iwl,
+                                u32 ofs, u32 val)
+{
+       IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
+       _iwl3945_write32(iwl, ofs, val);
+}
+#define iwl3945_write32(iwl, ofs, val) \
+       __iwl3945_write32(__FILE__, __LINE__, iwl, ofs, val)
+#else
+#define iwl3945_write32(iwl, ofs, val) _iwl3945_write32(iwl, ofs, val)
+#endif
+
+#define _iwl3945_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
+#ifdef CONFIG_IWL3945_DEBUG
+static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *iwl, u32 ofs)
+{
+       IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
+       return _iwl3945_read32(iwl, ofs);
+}
+#define iwl3945_read32(iwl, ofs) __iwl3945_read32(__FILE__, __LINE__, iwl, ofs)
+#else
+#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
+#endif
+
+static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr,
+                               u32 bits, u32 mask, int timeout)
+{
+       int i = 0;
+
+       do {
+               if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask))
+                       return i;
+               mdelay(10);
+               i += 10;
+       } while (i < timeout);
+
+       return -ETIMEDOUT;
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline int __iwl3945_poll_bit(const char *f, u32 l,
+                                struct iwl3945_priv *priv, u32 addr,
+                                u32 bits, u32 mask, int timeout)
+{
+       int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
+       if (unlikely(ret  == -ETIMEDOUT))
+               IWL_DEBUG_IO
+                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n",
+                    addr, bits, mask, f, l);
+       else
+               IWL_DEBUG_IO
+                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n",
+                    addr, bits, mask, ret, f, l);
+       return ret;
+}
+#define iwl3945_poll_bit(iwl, addr, bits, mask, timeout) \
+       __iwl3945_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
+#else
+#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t)
+#endif
+
+static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
+{
+       _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_set_bit(const char *f, u32 l,
+                                struct iwl3945_priv *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl3945_read32(priv, reg) | mask;
+       IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+       _iwl3945_write32(priv, reg, val);
+}
+#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m)
+#else
+#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m)
+#endif
+
+static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask)
+{
+       _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_clear_bit(const char *f, u32 l,
+                                  struct iwl3945_priv *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl3945_read32(priv, reg) & ~mask;
+       IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+       _iwl3945_write32(priv, reg, val);
+}
+#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m)
+#else
+#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m)
+#endif
+
+static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
+{
+       int ret;
+       u32 gp_ctl;
+
+#ifdef CONFIG_IWL3945_DEBUG
+       if (atomic_read(&priv->restrict_refcnt))
+               return 0;
+#endif
+       if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
+           test_bit(STATUS_RF_KILL_SW, &priv->status)) {
+               IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
+                       "wakes up NIC\n");
+
+               /* 10 msec allows time for NIC to complete its data save */
+               gp_ctl = _iwl3945_read32(priv, CSR_GP_CNTRL);
+               if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
+                       IWL_DEBUG_RF_KILL("Wait for complete power-down, "
+                               "gpctl = 0x%08x\n", gp_ctl);
+                       mdelay(10);
+               } else
+                       IWL_DEBUG_RF_KILL("power-down complete, "
+                                         "gpctl = 0x%08x\n", gp_ctl);
+       }
+
+       /* this bit wakes up the NIC */
+       _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
+                          CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
+                          (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+                           CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+       if (ret < 0) {
+               IWL_ERROR("MAC is in deep sleep!\n");
+               return -EIO;
+       }
+
+#ifdef CONFIG_IWL3945_DEBUG
+       atomic_inc(&priv->restrict_refcnt);
+#endif
+       return 0;
+}
+
+#ifdef CONFIG_IWL3945_DEBUG
+static inline int __iwl3945_grab_nic_access(const char *f, u32 l,
+                                              struct iwl3945_priv *priv)
+{
+       if (atomic_read(&priv->restrict_refcnt))
+               IWL_DEBUG_INFO("Grabbing access while already held at "
+                              "line %d.\n", l);
+
+       IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
+       return _iwl3945_grab_nic_access(priv);
+}
+#define iwl3945_grab_nic_access(priv) \
+       __iwl3945_grab_nic_access(__FILE__, __LINE__, priv)
+#else
+#define iwl3945_grab_nic_access(priv) \
+       _iwl3945_grab_nic_access(priv)
+#endif
+
+static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv)
+{
+#ifdef CONFIG_IWL3945_DEBUG
+       if (atomic_dec_and_test(&priv->restrict_refcnt))
+#endif
+               _iwl3945_clear_bit(priv, CSR_GP_CNTRL,
+                              CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_release_nic_access(const char *f, u32 l,
+                                           struct iwl3945_priv *priv)
+{
+       if (atomic_read(&priv->restrict_refcnt) <= 0)
+               IWL_ERROR("Release unheld nic access at line %d.\n", l);
+
+       IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
+       _iwl3945_release_nic_access(priv);
+}
+#define iwl3945_release_nic_access(priv) \
+       __iwl3945_release_nic_access(__FILE__, __LINE__, priv)
+#else
+#define iwl3945_release_nic_access(priv) \
+       _iwl3945_release_nic_access(priv)
+#endif
+
+static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg)
+{
+       return _iwl3945_read32(priv, reg);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline u32 __iwl3945_read_direct32(const char *f, u32 l,
+                                       struct iwl3945_priv *priv, u32 reg)
+{
+       u32 value = _iwl3945_read_direct32(priv, reg);
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from %s %d\n", f, l);
+       IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
+                    f, l);
+       return value;
+}
+#define iwl3945_read_direct32(priv, reg) \
+       __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg)
+#else
+#define iwl3945_read_direct32 _iwl3945_read_direct32
+#endif
+
+static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv,
+                                        u32 reg, u32 value)
+{
+       _iwl3945_write32(priv, reg, value);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static void __iwl3945_write_direct32(u32 line,
+                                  struct iwl3945_priv *priv, u32 reg, u32 value)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       _iwl3945_write_direct32(priv, reg, value);
+}
+#define iwl3945_write_direct32(priv, reg, value) \
+       __iwl3945_write_direct32(__LINE__, priv, reg, value)
+#else
+#define iwl3945_write_direct32 _iwl3945_write_direct32
+#endif
+
+static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv,
+                                              u32 reg, u32 len, u32 *values)
+{
+       u32 count = sizeof(u32);
+
+       if ((priv != NULL) && (values != NULL)) {
+               for (; 0 < len; len -= count, reg += count, values++)
+                       _iwl3945_write_direct32(priv, reg, *values);
+       }
+}
+
+static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv,
+                                          u32 addr, u32 mask, int timeout)
+{
+       int i = 0;
+
+       do {
+               if ((_iwl3945_read_direct32(priv, addr) & mask) == mask)
+                       return i;
+               mdelay(10);
+               i += 10;
+       } while (i < timeout);
+
+       return -ETIMEDOUT;
+}
+
+#ifdef CONFIG_IWL3945_DEBUG
+static inline int __iwl3945_poll_direct_bit(const char *f, u32 l,
+                                           struct iwl3945_priv *priv,
+                                           u32 addr, u32 mask, int timeout)
+{
+       int ret  = _iwl3945_poll_direct_bit(priv, addr, mask, timeout);
+
+       if (unlikely(ret == -ETIMEDOUT))
+               IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
+                            "timedout - %s %d\n", addr, mask, f, l);
+       else
+               IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
+                            "- %s %d\n", addr, mask, ret, f, l);
+       return ret;
+}
+#define iwl3945_poll_direct_bit(iwl, addr, mask, timeout) \
+       __iwl3945_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
+#else
+#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit
+#endif
+
+static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg)
+{
+       _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+       return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       return _iwl3945_read_prph(priv, reg);
+}
+
+#define iwl3945_read_prph(priv, reg) \
+       __iwl3945_read_prph(__LINE__, priv, reg)
+#else
+#define iwl3945_read_prph _iwl3945_read_prph
+#endif
+
+static inline void _iwl3945_write_prph(struct iwl3945_priv *priv,
+                                            u32 addr, u32 val)
+{
+       _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
+                             ((addr & 0x0000FFFF) | (3 << 24)));
+       _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
+}
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv,
+                                             u32 addr, u32 val)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access from line %d\n", line);
+       _iwl3945_write_prph(priv, addr, val);
+}
+
+#define iwl3945_write_prph(priv, addr, val) \
+       __iwl3945_write_prph(__LINE__, priv, addr, val);
+#else
+#define iwl3945_write_prph _iwl3945_write_prph
+#endif
+
+#define _iwl3945_set_bits_prph(priv, reg, mask) \
+       _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask))
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv,
+                                       u32 reg, u32 mask)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+
+       _iwl3945_set_bits_prph(priv, reg, mask);
+}
+#define iwl3945_set_bits_prph(priv, reg, mask) \
+       __iwl3945_set_bits_prph(__LINE__, priv, reg, mask)
+#else
+#define iwl3945_set_bits_prph _iwl3945_set_bits_prph
+#endif
+
+#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
+       _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits))
+
+#ifdef CONFIG_IWL3945_DEBUG
+static inline void __iwl3945_set_bits_mask_prph(u32 line,
+               struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       _iwl3945_set_bits_mask_prph(priv, reg, bits, mask);
+}
+#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \
+       __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
+#else
+#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph
+#endif
+
+static inline void iwl3945_clear_bits_prph(struct iwl3945_priv
+                                                *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl3945_read_prph(priv, reg);
+       _iwl3945_write_prph(priv, reg, (val & ~mask));
+}
+
+static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr)
+{
+       iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+       return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+}
+
+static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val)
+{
+       iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+       iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+}
+
+static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr,
+                                         u32 len, u32 *values)
+{
+       iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+       for (; 0 < len; len -= sizeof(u32), values++)
+               iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+}
+#endif
index c48b1b537d2b412fa5ccbc8cf1f156e911d44908..80d31ae51e774e168a8ed69c60073fad1f708b2d 100644 (file)
 
 #include <linux/workqueue.h>
 
-#define IWL 3945
-
 #include "../net/mac80211/ieee80211_rate.h"
 
-#include "iwlwifi.h"
+#include "iwl-3945.h"
 
 #define RS_NAME "iwl-3945-rs"
 
-struct iwl_rate_scale_data {
+struct iwl3945_rate_scale_data {
        u64 data;
        s32 success_counter;
        s32 success_ratio;
@@ -54,7 +52,7 @@ struct iwl_rate_scale_data {
        unsigned long stamp;
 };
 
-struct iwl_rate_scale_priv {
+struct iwl3945_rs_sta {
        spinlock_t lock;
        s32 *expected_tpt;
        unsigned long last_partial_flush;
@@ -67,31 +65,31 @@ struct iwl_rate_scale_priv {
        u8 start_rate;
        u8 ibss_sta_added;
        struct timer_list rate_scale_flush;
-       struct iwl_rate_scale_data win[IWL_RATE_COUNT];
+       struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
 };
 
-static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = {
        7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
 };
 
-static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = {
        7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
 };
 
-static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
 };
 
-static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
+static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = {
        7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-struct iwl_tpt_entry {
+struct iwl3945_tpt_entry {
        s8 min_rssi;
        u8 index;
 };
 
-static struct iwl_tpt_entry iwl_tpt_table_a[] = {
+static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = {
        {-60, IWL_RATE_54M_INDEX},
        {-64, IWL_RATE_48M_INDEX},
        {-72, IWL_RATE_36M_INDEX},
@@ -102,7 +100,7 @@ static struct iwl_tpt_entry iwl_tpt_table_a[] = {
        {-89, IWL_RATE_6M_INDEX}
 };
 
-static struct iwl_tpt_entry iwl_tpt_table_b[] = {
+static struct iwl3945_tpt_entry iwl3945_tpt_table_b[] = {
        {-86, IWL_RATE_11M_INDEX},
        {-88, IWL_RATE_5M_INDEX},
        {-90, IWL_RATE_2M_INDEX},
@@ -110,7 +108,7 @@ static struct iwl_tpt_entry iwl_tpt_table_b[] = {
 
 };
 
-static struct iwl_tpt_entry iwl_tpt_table_g[] = {
+static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
        {-60, IWL_RATE_54M_INDEX},
        {-64, IWL_RATE_48M_INDEX},
        {-68, IWL_RATE_36M_INDEX},
@@ -131,30 +129,30 @@ static struct iwl_tpt_entry iwl_tpt_table_g[] = {
 #define IWL_RATE_MIN_SUCCESS_TH       8
 #define IWL_RATE_DECREASE_TH       1920
 
-static u8 iwl_get_rate_index_by_rssi(s32 rssi, u8 mode)
+static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode)
 {
        u32 index = 0;
        u32 table_size = 0;
-       struct iwl_tpt_entry *tpt_table = NULL;
+       struct iwl3945_tpt_entry *tpt_table = NULL;
 
        if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL))
                rssi = IWL_MIN_RSSI_VAL;
 
        switch (mode) {
        case MODE_IEEE80211G:
-               tpt_table = iwl_tpt_table_g;
-               table_size = ARRAY_SIZE(iwl_tpt_table_g);
+               tpt_table = iwl3945_tpt_table_g;
+               table_size = ARRAY_SIZE(iwl3945_tpt_table_g);
                break;
 
        case MODE_IEEE80211A:
-               tpt_table = iwl_tpt_table_a;
-               table_size = ARRAY_SIZE(iwl_tpt_table_a);
+               tpt_table = iwl3945_tpt_table_a;
+               table_size = ARRAY_SIZE(iwl3945_tpt_table_a);
                break;
 
        default:
        case MODE_IEEE80211B:
-               tpt_table = iwl_tpt_table_b;
-               table_size = ARRAY_SIZE(iwl_tpt_table_b);
+               tpt_table = iwl3945_tpt_table_b;
+               table_size = ARRAY_SIZE(iwl3945_tpt_table_b);
                break;
        }
 
@@ -166,7 +164,7 @@ static u8 iwl_get_rate_index_by_rssi(s32 rssi, u8 mode)
        return tpt_table[index].index;
 }
 
-static void iwl_clear_window(struct iwl_rate_scale_data *window)
+static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window)
 {
        window->data = 0;
        window->success_counter = 0;
@@ -177,13 +175,13 @@ static void iwl_clear_window(struct iwl_rate_scale_data *window)
 }
 
 /**
- * iwl_rate_scale_flush_windows - flush out the rate scale windows
+ * iwl3945_rate_scale_flush_windows - flush out the rate scale windows
  *
  * Returns the number of windows that have gathered data but were
  * not flushed.  If there were any that were not flushed, then
  * reschedule the rate flushing routine.
  */
-static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv)
+static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
 {
        int unflushed = 0;
        int i;
@@ -195,19 +193,19 @@ static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv)
         * since we flushed, clear out the gathered statistics
         */
        for (i = 0; i < IWL_RATE_COUNT; i++) {
-               if (!rs_priv->win[i].counter)
+               if (!rs_sta->win[i].counter)
                        continue;
 
-               spin_lock_irqsave(&rs_priv->lock, flags);
-               if (time_after(jiffies, rs_priv->win[i].stamp +
+               spin_lock_irqsave(&rs_sta->lock, flags);
+               if (time_after(jiffies, rs_sta->win[i].stamp +
                               IWL_RATE_WIN_FLUSH)) {
                        IWL_DEBUG_RATE("flushing %d samples of rate "
                                       "index %d\n",
-                                      rs_priv->win[i].counter, i);
-                       iwl_clear_window(&rs_priv->win[i]);
+                                      rs_sta->win[i].counter, i);
+                       iwl3945_clear_window(&rs_sta->win[i]);
                } else
                        unflushed++;
-               spin_unlock_irqrestore(&rs_priv->lock, flags);
+               spin_unlock_irqrestore(&rs_sta->lock, flags);
        }
 
        return unflushed;
@@ -216,30 +214,30 @@ static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv)
 #define IWL_RATE_FLUSH_MAX              5000   /* msec */
 #define IWL_RATE_FLUSH_MIN              50     /* msec */
 
-static void iwl_bg_rate_scale_flush(unsigned long data)
+static void iwl3945_bg_rate_scale_flush(unsigned long data)
 {
-       struct iwl_rate_scale_priv *rs_priv = (void *)data;
+       struct iwl3945_rs_sta *rs_sta = (void *)data;
        int unflushed = 0;
        unsigned long flags;
        u32 packet_count, duration, pps;
 
        IWL_DEBUG_RATE("enter\n");
 
-       unflushed = iwl_rate_scale_flush_windows(rs_priv);
+       unflushed = iwl3945_rate_scale_flush_windows(rs_sta);
 
-       spin_lock_irqsave(&rs_priv->lock, flags);
+       spin_lock_irqsave(&rs_sta->lock, flags);
 
-       rs_priv->flush_pending = 0;
+       rs_sta->flush_pending = 0;
 
        /* Number of packets Rx'd since last time this timer ran */
-       packet_count = (rs_priv->tx_packets - rs_priv->last_tx_packets) + 1;
+       packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1;
 
-       rs_priv->last_tx_packets = rs_priv->tx_packets + 1;
+       rs_sta->last_tx_packets = rs_sta->tx_packets + 1;
 
        if (unflushed) {
                duration =
-                   jiffies_to_msecs(jiffies - rs_priv->last_partial_flush);
-/*              duration = jiffies_to_msecs(rs_priv->flush_time); */
+                   jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);
+/*              duration = jiffies_to_msecs(rs_sta->flush_time); */
 
                IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
                               packet_count, duration);
@@ -257,36 +255,36 @@ static void iwl_bg_rate_scale_flush(unsigned long data)
                } else
                        duration = IWL_RATE_FLUSH_MAX;
 
-               rs_priv->flush_time = msecs_to_jiffies(duration);
+               rs_sta->flush_time = msecs_to_jiffies(duration);
 
                IWL_DEBUG_RATE("new flush period: %d msec ave %d\n",
                               duration, packet_count);
 
-               mod_timer(&rs_priv->rate_scale_flush, jiffies +
-                         rs_priv->flush_time);
+               mod_timer(&rs_sta->rate_scale_flush, jiffies +
+                         rs_sta->flush_time);
 
-               rs_priv->last_partial_flush = jiffies;
+               rs_sta->last_partial_flush = jiffies;
        }
 
        /* If there weren't any unflushed entries, we don't schedule the timer
         * to run again */
 
-       rs_priv->last_flush = jiffies;
+       rs_sta->last_flush = jiffies;
 
-       spin_unlock_irqrestore(&rs_priv->lock, flags);
+       spin_unlock_irqrestore(&rs_sta->lock, flags);
 
        IWL_DEBUG_RATE("leave\n");
 }
 
 /**
- * iwl_collect_tx_data - Update the success/failure sliding window
+ * iwl3945_collect_tx_data - Update the success/failure sliding window
  *
  * We keep a sliding window of the last 64 packets transmitted
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static void iwl_collect_tx_data(struct iwl_rate_scale_priv *rs_priv,
-                               struct iwl_rate_scale_data *window,
+static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
+                               struct iwl3945_rate_scale_data *window,
                                int success, int retries)
 {
        unsigned long flags;
@@ -297,7 +295,7 @@ static void iwl_collect_tx_data(struct iwl_rate_scale_priv *rs_priv,
        }
 
        while (retries--) {
-               spin_lock_irqsave(&rs_priv->lock, flags);
+               spin_lock_irqsave(&rs_sta->lock, flags);
 
                /* If we have filled up the window then subtract one from the
                 * success counter if the high-bit is counting toward
@@ -325,7 +323,7 @@ static void iwl_collect_tx_data(struct iwl_rate_scale_priv *rs_priv,
                /* Tag this window as having been updated */
                window->stamp = jiffies;
 
-               spin_unlock_irqrestore(&rs_priv->lock, flags);
+               spin_unlock_irqrestore(&rs_sta->lock, flags);
        }
 }
 
@@ -362,7 +360,7 @@ static void *rs_alloc(struct ieee80211_local *local)
        return local->hw.priv;
 }
 
-/* rate scale requires free function to be implmented */
+/* rate scale requires free function to be implemented */
 static void rs_free(void *priv)
 {
        return;
@@ -375,49 +373,49 @@ static void rs_clear(void *priv)
 
 static void *rs_alloc_sta(void *priv, gfp_t gfp)
 {
-       struct iwl_rate_scale_priv *rs_priv;
+       struct iwl3945_rs_sta *rs_sta;
        int i;
 
        IWL_DEBUG_RATE("enter\n");
 
-       rs_priv = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp);
-       if (!rs_priv) {
+       rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
+       if (!rs_sta) {
                IWL_DEBUG_RATE("leave: ENOMEM\n");
                return NULL;
        }
 
-       spin_lock_init(&rs_priv->lock);
+       spin_lock_init(&rs_sta->lock);
 
-       rs_priv->start_rate = IWL_RATE_INVALID;
+       rs_sta->start_rate = IWL_RATE_INVALID;
 
        /* default to just 802.11b */
-       rs_priv->expected_tpt = iwl_expected_tpt_b;
+       rs_sta->expected_tpt = iwl3945_expected_tpt_b;
 
-       rs_priv->last_partial_flush = jiffies;
-       rs_priv->last_flush = jiffies;
-       rs_priv->flush_time = IWL_RATE_FLUSH;
-       rs_priv->last_tx_packets = 0;
-       rs_priv->ibss_sta_added = 0;
+       rs_sta->last_partial_flush = jiffies;
+       rs_sta->last_flush = jiffies;
+       rs_sta->flush_time = IWL_RATE_FLUSH;
+       rs_sta->last_tx_packets = 0;
+       rs_sta->ibss_sta_added = 0;
 
-       init_timer(&rs_priv->rate_scale_flush);
-       rs_priv->rate_scale_flush.data = (unsigned long)rs_priv;
-       rs_priv->rate_scale_flush.function = &iwl_bg_rate_scale_flush;
+       init_timer(&rs_sta->rate_scale_flush);
+       rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
+       rs_sta->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush;
 
        for (i = 0; i < IWL_RATE_COUNT; i++)
-               iwl_clear_window(&rs_priv->win[i]);
+               iwl3945_clear_window(&rs_sta->win[i]);
 
        IWL_DEBUG_RATE("leave\n");
 
-       return rs_priv;
+       return rs_sta;
 }
 
 static void rs_free_sta(void *priv, void *priv_sta)
 {
-       struct iwl_rate_scale_priv *rs_priv = priv_sta;
+       struct iwl3945_rs_sta *rs_sta = priv_sta;
 
        IWL_DEBUG_RATE("enter\n");
-       del_timer_sync(&rs_priv->rate_scale_flush);
-       kfree(rs_priv);
+       del_timer_sync(&rs_sta->rate_scale_flush);
+       kfree(rs_sta);
        IWL_DEBUG_RATE("leave\n");
 }
 
@@ -427,9 +425,9 @@ static void rs_free_sta(void *priv, void *priv_sta)
  * for A and B mode we need to overright prev
  * value
  */
-static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
+static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
 {
-       int next_rate = iwl_get_prev_ieee_rate(rate);
+       int next_rate = iwl3945_get_prev_ieee_rate(rate);
 
        switch (priv->phymode) {
        case MODE_IEEE80211A:
@@ -451,7 +449,7 @@ static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
 /**
  * rs_tx_status - Update rate control values based on Tx results
  *
- * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by
+ * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
  * the hardware for each rate.
  */
 static void rs_tx_status(void *priv_rate,
@@ -464,9 +462,9 @@ static void rs_tx_status(void *priv_rate,
        unsigned long flags;
        struct sta_info *sta;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct iwl_rate_scale_priv *rs_priv;
+       struct iwl3945_rs_sta *rs_sta;
 
        IWL_DEBUG_RATE("enter\n");
 
@@ -487,9 +485,9 @@ static void rs_tx_status(void *priv_rate,
                return;
        }
 
-       rs_priv = (void *)sta->rate_ctrl_priv;
+       rs_sta = (void *)sta->rate_ctrl_priv;
 
-       rs_priv->tx_packets++;
+       rs_sta->tx_packets++;
 
        scale_rate_index = first_index;
        last_index = first_index;
@@ -516,8 +514,8 @@ static void rs_tx_status(void *priv_rate,
 
                /* Update this rate accounting for as many retries
                 * as was used for it (per current_count) */
-               iwl_collect_tx_data(rs_priv,
-                                   &rs_priv->win[scale_rate_index],
+               iwl3945_collect_tx_data(rs_sta,
+                                   &rs_sta->win[scale_rate_index],
                                    0, current_count);
                IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
                               scale_rate_index, current_count);
@@ -535,25 +533,25 @@ static void rs_tx_status(void *priv_rate,
                       last_index,
                       (tx_resp->flags & IEEE80211_TX_STATUS_ACK) ?
                       "success" : "failure");
-       iwl_collect_tx_data(rs_priv,
-                           &rs_priv->win[last_index],
+       iwl3945_collect_tx_data(rs_sta,
+                           &rs_sta->win[last_index],
                            tx_resp->flags & IEEE80211_TX_STATUS_ACK, 1);
 
        /* We updated the rate scale window -- if its been more than
         * flush_time since the last run, schedule the flush
         * again */
-       spin_lock_irqsave(&rs_priv->lock, flags);
+       spin_lock_irqsave(&rs_sta->lock, flags);
 
-       if (!rs_priv->flush_pending &&
-           time_after(jiffies, rs_priv->last_partial_flush +
-                      rs_priv->flush_time)) {
+       if (!rs_sta->flush_pending &&
+           time_after(jiffies, rs_sta->last_partial_flush +
+                      rs_sta->flush_time)) {
 
-               rs_priv->flush_pending = 1;
-               mod_timer(&rs_priv->rate_scale_flush,
-                         jiffies + rs_priv->flush_time);
+               rs_sta->flush_pending = 1;
+               mod_timer(&rs_sta->rate_scale_flush,
+                         jiffies + rs_sta->flush_time);
        }
 
-       spin_unlock_irqrestore(&rs_priv->lock, flags);
+       spin_unlock_irqrestore(&rs_sta->lock, flags);
 
        sta_info_put(sta);
 
@@ -562,29 +560,13 @@ static void rs_tx_status(void *priv_rate,
        return;
 }
 
-static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local
-                                                 *local)
-{
-       struct ieee80211_hw_mode *mode = local->oper_hw_mode;
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       return &mode->rates[0];
-}
-
-static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
+static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
                                 u8 index, u16 rate_mask, int phymode)
 {
        u8 high = IWL_RATE_INVALID;
        u8 low = IWL_RATE_INVALID;
 
-       /* 802.11A walks to the next literal adjascent rate in
+       /* 802.11A walks to the next literal adjacent rate in
         * the rate table */
        if (unlikely(phymode == MODE_IEEE80211A)) {
                int i;
@@ -613,10 +595,10 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
 
        low = index;
        while (low != IWL_RATE_INVALID) {
-               if (rs_priv->tgg)
-                       low = iwl_rates[low].prev_rs_tgg;
+               if (rs_sta->tgg)
+                       low = iwl3945_rates[low].prev_rs_tgg;
                else
-                       low = iwl_rates[low].prev_rs;
+                       low = iwl3945_rates[low].prev_rs;
                if (low == IWL_RATE_INVALID)
                        break;
                if (rate_mask & (1 << low))
@@ -626,10 +608,10 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
 
        high = index;
        while (high != IWL_RATE_INVALID) {
-               if (rs_priv->tgg)
-                       high = iwl_rates[high].next_rs_tgg;
+               if (rs_sta->tgg)
+                       high = iwl3945_rates[high].next_rs_tgg;
                else
-                       high = iwl_rates[high].next_rs;
+                       high = iwl3945_rates[high].next_rs;
                if (high == IWL_RATE_INVALID)
                        break;
                if (rate_mask & (1 << high))
@@ -656,17 +638,16 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv,
  * rate table and must reference the driver allocated rate table
  *
  */
-static struct ieee80211_rate *rs_get_rate(void *priv_rate,
-                                         struct net_device *dev,
-                                         struct sk_buff *skb,
-                                         struct rate_control_extra *extra)
+static void rs_get_rate(void *priv_rate, struct net_device *dev,
+                       struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                       struct rate_selection *sel)
 {
        u8 low = IWL_RATE_INVALID;
        u8 high = IWL_RATE_INVALID;
        u16 high_low;
        int index;
-       struct iwl_rate_scale_priv *rs_priv;
-       struct iwl_rate_scale_data *window = NULL;
+       struct iwl3945_rs_sta *rs_sta;
+       struct iwl3945_rate_scale_data *window = NULL;
        int current_tpt = IWL_INVALID_VALUE;
        int low_tpt = IWL_INVALID_VALUE;
        int high_tpt = IWL_INVALID_VALUE;
@@ -677,31 +658,24 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct sta_info *sta;
        u16 fc, rate_mask;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RATE("enter\n");
 
-       memset(extra, 0, sizeof(*extra));
+       sta = sta_info_get(local, hdr->addr1);
 
+       /* Send management frames and broadcast/multicast 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))) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               IWL_DEBUG_RATE("leave: lowest rate (not data or is "
-                              "multicast)\n");
-
-               return iwl_get_lowest_rate(local);
-       }
-
-       sta = sta_info_get(local, hdr->addr1);
-       if (!sta || !sta->rate_ctrl_priv) {
+       if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
+           is_multicast_ether_addr(hdr->addr1) ||
+           !sta || !sta->rate_ctrl_priv) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
                if (sta)
                        sta_info_put(sta);
-               return NULL;
+               return;
        }
 
        rate_mask = sta->supp_rates;
@@ -710,37 +684,37 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
        if (priv->phymode == (u8) MODE_IEEE80211A)
                rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
 
-       rs_priv = (void *)sta->rate_ctrl_priv;
+       rs_sta = (void *)sta->rate_ctrl_priv;
 
        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
-           !rs_priv->ibss_sta_added) {
-               u8 sta_id = iwl_hw_find_station(priv, hdr->addr1);
+           !rs_sta->ibss_sta_added) {
+               u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
 
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE("LQ: ADD station %s\n",
                                       print_mac(mac, hdr->addr1));
-                       sta_id = iwl_add_station(priv,
+                       sta_id = iwl3945_add_station(priv,
                                    hdr->addr1, 0, CMD_ASYNC);
                }
                if (sta_id != IWL_INVALID_STATION)
-                       rs_priv->ibss_sta_added = 1;
+                       rs_sta->ibss_sta_added = 1;
        }
 
-       spin_lock_irqsave(&rs_priv->lock, flags);
+       spin_lock_irqsave(&rs_sta->lock, flags);
 
-       if (rs_priv->start_rate != IWL_RATE_INVALID) {
-               index = rs_priv->start_rate;
-               rs_priv->start_rate = IWL_RATE_INVALID;
+       if (rs_sta->start_rate != IWL_RATE_INVALID) {
+               index = rs_sta->start_rate;
+               rs_sta->start_rate = IWL_RATE_INVALID;
        }
 
-       window = &(rs_priv->win[index]);
+       window = &(rs_sta->win[index]);
 
        fail_count = window->counter - window->success_counter;
 
        if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
             (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
                window->average_tpt = IWL_INVALID_VALUE;
-               spin_unlock_irqrestore(&rs_priv->lock, flags);
+               spin_unlock_irqrestore(&rs_sta->lock, flags);
 
                IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
                               "counter: %d, success_counter: %d, "
@@ -748,27 +722,27 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
                               index,
                               window->counter,
                               window->success_counter,
-                              rs_priv->expected_tpt ? "not " : "");
+                              rs_sta->expected_tpt ? "not " : "");
                goto out;
 
        }
 
        window->average_tpt = ((window->success_ratio *
-                               rs_priv->expected_tpt[index] + 64) / 128);
+                               rs_sta->expected_tpt[index] + 64) / 128);
        current_tpt = window->average_tpt;
 
-       high_low = iwl_get_adjacent_rate(rs_priv, index, rate_mask,
+       high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask,
                                         local->hw.conf.phymode);
        low = high_low & 0xff;
        high = (high_low >> 8) & 0xff;
 
        if (low != IWL_RATE_INVALID)
-               low_tpt = rs_priv->win[low].average_tpt;
+               low_tpt = rs_sta->win[low].average_tpt;
 
        if (high != IWL_RATE_INVALID)
-               high_tpt = rs_priv->win[high].average_tpt;
+               high_tpt = rs_sta->win[high].average_tpt;
 
-       spin_unlock_irqrestore(&rs_priv->lock, flags);
+       spin_unlock_irqrestore(&rs_sta->lock, flags);
 
        scale_action = 1;
 
@@ -846,7 +820,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
 
        IWL_DEBUG_RATE("leave: %d\n", index);
 
-       return &priv->ieee_rates[index];
+       sel->rate = &priv->ieee_rates[index];
 }
 
 static struct rate_control_ops rs_ops = {
@@ -862,11 +836,11 @@ static struct rate_control_ops rs_ops = {
        .free_sta = rs_free_sta,
 };
 
-int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
+int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct iwl_priv *priv = hw->priv;
-       struct iwl_rate_scale_priv *rs_priv;
+       struct iwl3945_priv *priv = hw->priv;
+       struct iwl3945_rs_sta *rs_sta;
        struct sta_info *sta;
        unsigned long flags;
        int count = 0, i;
@@ -884,28 +858,29 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
                return sprintf(buf, "station %d not found\n", sta_id);
        }
 
-       rs_priv = (void *)sta->rate_ctrl_priv;
-       spin_lock_irqsave(&rs_priv->lock, flags);
+       rs_sta = (void *)sta->rate_ctrl_priv;
+       spin_lock_irqsave(&rs_sta->lock, flags);
        i = IWL_RATE_54M_INDEX;
        while (1) {
                u64 mask;
                int j;
 
                count +=
-                   sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2);
+                   sprintf(&buf[count], " %2dMbs: ", iwl3945_rates[i].ieee / 2);
 
                mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
                for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
                        buf[count++] =
-                           (rs_priv->win[i].data & mask) ? '1' : '0';
+                           (rs_sta->win[i].data & mask) ? '1' : '0';
 
-               samples += rs_priv->win[i].counter;
-               good += rs_priv->win[i].success_counter;
-               success += rs_priv->win[i].success_counter * iwl_rates[i].ieee;
+               samples += rs_sta->win[i].counter;
+               good += rs_sta->win[i].success_counter;
+               success += rs_sta->win[i].success_counter *
+                                               iwl3945_rates[i].ieee;
 
-               if (rs_priv->win[i].stamp) {
+               if (rs_sta->win[i].stamp) {
                        int delta =
-                           jiffies_to_msecs(now - rs_priv->win[i].stamp);
+                           jiffies_to_msecs(now - rs_sta->win[i].stamp);
 
                        if (delta > max_time)
                                max_time = delta;
@@ -914,18 +889,18 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
                } else
                        buf[count++] = '\n';
 
-               j = iwl_get_prev_ieee_rate(i);
+               j = iwl3945_get_prev_ieee_rate(i);
                if (j == i)
                        break;
                i = j;
        }
-       spin_unlock_irqrestore(&rs_priv->lock, flags);
+       spin_unlock_irqrestore(&rs_sta->lock, flags);
        sta_info_put(sta);
 
        /* Display the average rate of all samples taken.
         *
         * NOTE:  We multiple # of samples by 2 since the IEEE measurement
-        * added from iwl_rates is actually 2X the rate */
+        * added from iwl3945_rates is actually 2X the rate */
        if (samples)
                count += sprintf(
                        &buf[count],
@@ -939,13 +914,13 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
        return count;
 }
 
-void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
+void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        s32 rssi = 0;
        unsigned long flags;
        struct ieee80211_local *local = hw_to_local(hw);
-       struct iwl_rate_scale_priv *rs_priv;
+       struct iwl3945_rs_sta *rs_sta;
        struct sta_info *sta;
 
        IWL_DEBUG_RATE("enter\n");
@@ -965,33 +940,33 @@ void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
                return;
        }
 
-       rs_priv = (void *)sta->rate_ctrl_priv;
+       rs_sta = (void *)sta->rate_ctrl_priv;
 
-       spin_lock_irqsave(&rs_priv->lock, flags);
+       spin_lock_irqsave(&rs_sta->lock, flags);
 
-       rs_priv->tgg = 0;
+       rs_sta->tgg = 0;
        switch (priv->phymode) {
        case MODE_IEEE80211G:
                if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
-                       rs_priv->tgg = 1;
-                       rs_priv->expected_tpt = iwl_expected_tpt_g_prot;
+                       rs_sta->tgg = 1;
+                       rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
                } else
-                       rs_priv->expected_tpt = iwl_expected_tpt_g;
+                       rs_sta->expected_tpt = iwl3945_expected_tpt_g;
                break;
 
        case MODE_IEEE80211A:
-               rs_priv->expected_tpt = iwl_expected_tpt_a;
+               rs_sta->expected_tpt = iwl3945_expected_tpt_a;
                break;
 
        default:
                IWL_WARNING("Invalid phymode.  Defaulting to 802.11b\n");
        case MODE_IEEE80211B:
-               rs_priv->expected_tpt = iwl_expected_tpt_b;
+               rs_sta->expected_tpt = iwl3945_expected_tpt_b;
                break;
        }
 
        sta_info_put(sta);
-       spin_unlock_irqrestore(&rs_priv->lock, flags);
+       spin_unlock_irqrestore(&rs_sta->lock, flags);
 
        rssi = priv->last_rx_rssi;
        if (rssi == 0)
@@ -999,19 +974,20 @@ void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 
        IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
 
-       rs_priv->start_rate = iwl_get_rate_index_by_rssi(rssi, priv->phymode);
+       rs_sta->start_rate =
+                       iwl3945_get_rate_index_by_rssi(rssi, priv->phymode);
 
        IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
-                      "%d (plcp 0x%x)\n", rssi, rs_priv->start_rate,
-                      iwl_rates[rs_priv->start_rate].plcp);
+                      "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
+                      iwl3945_rates[rs_sta->start_rate].plcp);
 }
 
-void iwl_rate_control_register(struct ieee80211_hw *hw)
+void iwl3945_rate_control_register(struct ieee80211_hw *hw)
 {
        ieee80211_rate_control_register(&rs_ops);
 }
 
-void iwl_rate_control_unregister(struct ieee80211_hw *hw)
+void iwl3945_rate_control_unregister(struct ieee80211_hw *hw)
 {
        ieee80211_rate_control_unregister(&rs_ops);
 }
index bec4d3ffca1d033c36e0888108c365777821da4b..d5e9220f871d41b32c4fb7d7880aecf4ab62ed42 100644 (file)
@@ -27,9 +27,9 @@
 #ifndef __iwl_3945_rs_h__
 #define __iwl_3945_rs_h__
 
-struct iwl_rate_info {
-       u8 plcp;
-       u8 ieee;
+struct iwl3945_rate_info {
+       u8 plcp;                /* uCode API:  IWL_RATE_6M_PLCP, etc. */
+       u8 ieee;                /* MAC header:  IWL_RATE_6M_IEEE, etc. */
        u8 prev_ieee;           /* previous rate in IEEE speeds */
        u8 next_ieee;           /* next rate in IEEE speeds */
        u8 prev_rs;             /* previous rate used in rs algo */
@@ -38,9 +38,12 @@ struct iwl_rate_info {
        u8 next_rs_tgg;         /* next rate used in TGG rs algo */
         u8 table_rs_index;     /* index in rate scale table cmd */
         u8 prev_table_rs;      /* prev in rate table cmd */
-
 };
 
+/*
+ * These serve as indexes into
+ * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
+ */
 enum {
        IWL_RATE_1M_INDEX = 0,
        IWL_RATE_2M_INDEX,
@@ -83,19 +86,20 @@ enum {
 };
 
 /* #define vs. enum to keep from defaulting to 'large integer' */
-#define        IWL_RATE_6M_MASK   (1<<IWL_RATE_6M_INDEX)
-#define        IWL_RATE_9M_MASK   (1<<IWL_RATE_9M_INDEX)
-#define        IWL_RATE_12M_MASK  (1<<IWL_RATE_12M_INDEX)
-#define        IWL_RATE_18M_MASK  (1<<IWL_RATE_18M_INDEX)
-#define        IWL_RATE_24M_MASK  (1<<IWL_RATE_24M_INDEX)
-#define        IWL_RATE_36M_MASK  (1<<IWL_RATE_36M_INDEX)
-#define        IWL_RATE_48M_MASK  (1<<IWL_RATE_48M_INDEX)
-#define        IWL_RATE_54M_MASK  (1<<IWL_RATE_54M_INDEX)
-#define        IWL_RATE_1M_MASK   (1<<IWL_RATE_1M_INDEX)
-#define        IWL_RATE_2M_MASK   (1<<IWL_RATE_2M_INDEX)
-#define        IWL_RATE_5M_MASK   (1<<IWL_RATE_5M_INDEX)
-#define        IWL_RATE_11M_MASK  (1<<IWL_RATE_11M_INDEX)
-
+#define        IWL_RATE_6M_MASK   (1 << IWL_RATE_6M_INDEX)
+#define        IWL_RATE_9M_MASK   (1 << IWL_RATE_9M_INDEX)
+#define        IWL_RATE_12M_MASK  (1 << IWL_RATE_12M_INDEX)
+#define        IWL_RATE_18M_MASK  (1 << IWL_RATE_18M_INDEX)
+#define        IWL_RATE_24M_MASK  (1 << IWL_RATE_24M_INDEX)
+#define        IWL_RATE_36M_MASK  (1 << IWL_RATE_36M_INDEX)
+#define        IWL_RATE_48M_MASK  (1 << IWL_RATE_48M_INDEX)
+#define        IWL_RATE_54M_MASK  (1 << IWL_RATE_54M_INDEX)
+#define        IWL_RATE_1M_MASK   (1 << IWL_RATE_1M_INDEX)
+#define        IWL_RATE_2M_MASK   (1 << IWL_RATE_2M_INDEX)
+#define        IWL_RATE_5M_MASK   (1 << IWL_RATE_5M_INDEX)
+#define        IWL_RATE_11M_MASK  (1 << IWL_RATE_11M_INDEX)
+
+/* 3945 uCode API values for (legacy) bit rates, both OFDM and CCK */
 enum {
        IWL_RATE_6M_PLCP = 13,
        IWL_RATE_9M_PLCP = 15,
@@ -111,6 +115,7 @@ enum {
        IWL_RATE_11M_PLCP = 110,
 };
 
+/* MAC header values for bit rates */
 enum {
        IWL_RATE_6M_IEEE = 12,
        IWL_RATE_9M_IEEE = 18,
@@ -152,18 +157,18 @@ enum {
        (IWL_OFDM_BASIC_RATES_MASK | \
         IWL_CCK_BASIC_RATES_MASK)
 
-#define IWL_RATES_MASK ((1<<IWL_RATE_COUNT)-1)
+#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
 
 #define IWL_INVALID_VALUE    -1
 
 #define IWL_MIN_RSSI_VAL                 -100
 #define IWL_MAX_RSSI_VAL                    0
 
-extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT];
 
-static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
+static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
 {
-       u8 rate = iwl_rates[rate_index].prev_ieee;
+       u8 rate = iwl3945_rates[rate_index].prev_ieee;
 
        if (rate == IWL_RATE_INVALID)
                rate = rate_index;
@@ -171,40 +176,40 @@ static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
 }
 
 /**
- * iwl_fill_rs_info - Fill an output text buffer with the rate representation
+ * iwl3945_fill_rs_info - Fill an output text buffer with the rate representation
  *
  * NOTE:  This is provided as a quick mechanism for a user to visualize
- * the performance of the rate control alogirthm and is not meant to be
+ * the performance of the rate control algorithm and is not meant to be
  * parsed software.
  */
-extern int iwl_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
+extern int iwl3945_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
 
 /**
- * iwl_rate_scale_init - Initialize the rate scale table based on assoc info
+ * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
  *
- * The specific througput table used is based on the type of network
+ * The specific throughput table used is based on the type of network
  * the associated with, including A, B, G, and G w/ TGG protection
  */
-extern void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
 
 /**
- * iwl_rate_control_register - Register the rate control algorithm callbacks
+ * iwl3945_rate_control_register - Register the rate control algorithm callbacks
  *
  * Since the rate control algorithm is hardware specific, there is no need
  * or reason to place it as a stand alone module.  The driver can call
- * iwl_rate_control_register in order to register the rate control callbacks
+ * iwl3945_rate_control_register in order to register the rate control callbacks
  * with the mac80211 subsystem.  This should be performed prior to calling
  * ieee80211_register_hw
  *
  */
-extern void iwl_rate_control_register(struct ieee80211_hw *hw);
+extern void iwl3945_rate_control_register(struct ieee80211_hw *hw);
 
 /**
- * iwl_rate_control_unregister - Unregister the rate control callbacks
+ * iwl3945_rate_control_unregister - Unregister the rate control callbacks
  *
  * This should be called after calling ieee80211_unregister_hw, but before
  * the driver is unloaded.
  */
-extern void iwl_rate_control_unregister(struct ieee80211_hw *hw);
+extern void iwl3945_rate_control_unregister(struct ieee80211_hw *hw);
 
 #endif
index 3a45fe99a83e72c4a3786787e347e12f4a480103..76c4ed1135f272dd587e2ce44aa597689ad1e65f 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/firmware.h>
-#include <net/mac80211.h>
-
 #include <linux/etherdevice.h>
+#include <asm/unaligned.h>
+#include <net/mac80211.h>
 
-#define IWL 3945
-
-#include "iwlwifi.h"
-#include "iwl-helpers.h"
 #include "iwl-3945.h"
+#include "iwl-helpers.h"
 #include "iwl-3945-rs.h"
 
 #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
@@ -66,7 +63,7 @@
  * maps to IWL_RATE_INVALID
  *
  */
-const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
        IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),    /*  1mbps */
        IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),          /*  2mbps */
        IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
@@ -81,12 +78,12 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
        IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
 };
 
-/* 1 = enable the iwl_disable_events() function */
+/* 1 = enable the iwl3945_disable_events() function */
 #define IWL_EVT_DISABLE (0)
 #define IWL_EVT_DISABLE_SIZE (1532/32)
 
 /**
- * iwl_disable_events - Disable selected events in uCode event log
+ * iwl3945_disable_events - Disable selected events in uCode event log
  *
  * Disable an event by writing "1"s into "disable"
  *   bitmap in SRAM.  Bit position corresponds to Event # (id/type).
@@ -94,9 +91,9 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
  * Use for only special debugging.  This function is just a placeholder as-is,
  *   you'll need to provide the special bits! ...
  *   ... and set IWL_EVT_DISABLE to 1. */
-void iwl_disable_events(struct iwl_priv *priv)
+void iwl3945_disable_events(struct iwl3945_priv *priv)
 {
-       int rc;
+       int ret;
        int i;
        u32 base;               /* SRAM address of event log header */
        u32 disable_ptr;        /* SRAM address of event-disable bitmap array */
@@ -152,32 +149,31 @@ void iwl_disable_events(struct iwl_priv *priv)
        };
 
        base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-       if (!iwl_hw_valid_rtc_data_addr(base)) {
+       if (!iwl3945_hw_valid_rtc_data_addr(base)) {
                IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
                return;
        }
 
-       rc = iwl_grab_restricted_access(priv);
-       if (rc) {
+       ret = iwl3945_grab_nic_access(priv);
+       if (ret) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
-       disable_ptr = iwl_read_restricted_mem(priv, base + (4 * sizeof(u32)));
-       array_size = iwl_read_restricted_mem(priv, base + (5 * sizeof(u32)));
-       iwl_release_restricted_access(priv);
+       disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
+       array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
+       iwl3945_release_nic_access(priv);
 
        if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
                IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n",
                               disable_ptr);
-               rc = iwl_grab_restricted_access(priv);
+               ret = iwl3945_grab_nic_access(priv);
                for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
-                       iwl_write_restricted_mem(priv,
-                                                disable_ptr +
-                                                (i * sizeof(u32)),
-                                                evt_disable[i]);
+                       iwl3945_write_targ_mem(priv,
+                                          disable_ptr + (i * sizeof(u32)),
+                                          evt_disable[i]);
 
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
        } else {
                IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
                IWL_DEBUG_INFO("  by writing \"1\"s into disable bitmap\n");
@@ -198,7 +194,7 @@ void iwl_disable_events(struct iwl_priv *priv)
  * IWL_ANTENNA_MAIN      - Force MAIN antenna
  * IWL_ANTENNA_AUX       - Force AUX antenna
  */
-__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
 {
        switch (priv->antenna) {
        case IWL_ANTENNA_DIVERSITY:
@@ -230,11 +226,11 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
  *
  *****************************************************************************/
 
-void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
        IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
-                    (int)sizeof(struct iwl_notif_statistics),
+                    (int)sizeof(struct iwl3945_notif_statistics),
                     le32_to_cpu(pkt->len));
 
        memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
@@ -242,15 +238,107 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        priv->last_statistics_time = jiffies;
 }
 
-static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data,
-                                  struct iwl_rx_mem_buffer *rxb,
-                                  struct ieee80211_rx_status *stats,
-                                  u16 phy_flags)
+void iwl3945_add_radiotap(struct iwl3945_priv *priv, struct sk_buff *skb,
+                         struct iwl3945_rx_frame_hdr *rx_hdr,
+                         struct ieee80211_rx_status *stats)
+{
+       /* First cache any information we need before we overwrite
+        * the information provided in the skb from the hardware */
+       s8 signal = stats->ssi;
+       s8 noise = 0;
+       int rate = stats->rate;
+       u64 tsf = stats->mactime;
+       __le16 phy_flags_hw = rx_hdr->phy_flags;
+
+       struct iwl3945_rt_rx_hdr {
+               struct ieee80211_radiotap_header rt_hdr;
+               __le64 rt_tsf;          /* TSF */
+               u8 rt_flags;            /* radiotap packet flags */
+               u8 rt_rate;             /* rate in 500kb/s */
+               __le16 rt_channelMHz;   /* channel in MHz */
+               __le16 rt_chbitmask;    /* channel bitfield */
+               s8 rt_dbmsignal;        /* signal in dBm, kluged to signed */
+               s8 rt_dbmnoise;
+               u8 rt_antenna;          /* antenna number */
+       } __attribute__ ((packed)) *iwl3945_rt;
+
+       if (skb_headroom(skb) < sizeof(*iwl3945_rt)) {
+               if (net_ratelimit())
+                       printk(KERN_ERR "not enough headroom [%d] for "
+                              "radiotap head [%zd]\n",
+                              skb_headroom(skb), sizeof(*iwl3945_rt));
+               return;
+       }
+
+       /* put radiotap header in front of 802.11 header and data */
+       iwl3945_rt = (void *)skb_push(skb, sizeof(*iwl3945_rt));
+
+       /* initialise radiotap header */
+       iwl3945_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+       iwl3945_rt->rt_hdr.it_pad = 0;
+
+       /* total header + data */
+       put_unaligned(cpu_to_le16(sizeof(*iwl3945_rt)),
+                     &iwl3945_rt->rt_hdr.it_len);
+
+       /* Indicate all the fields we add to the radiotap header */
+       put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
+                                 (1 << IEEE80211_RADIOTAP_FLAGS) |
+                                 (1 << IEEE80211_RADIOTAP_RATE) |
+                                 (1 << IEEE80211_RADIOTAP_CHANNEL) |
+                                 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+                                 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
+                                 (1 << IEEE80211_RADIOTAP_ANTENNA)),
+                     &iwl3945_rt->rt_hdr.it_present);
+
+       /* Zero the flags, we'll add to them as we go */
+       iwl3945_rt->rt_flags = 0;
+
+       put_unaligned(cpu_to_le64(tsf), &iwl3945_rt->rt_tsf);
+
+       iwl3945_rt->rt_dbmsignal = signal;
+       iwl3945_rt->rt_dbmnoise = noise;
+
+       /* Convert the channel frequency and set the flags */
+       put_unaligned(cpu_to_le16(stats->freq), &iwl3945_rt->rt_channelMHz);
+       if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
+                                         IEEE80211_CHAN_5GHZ),
+                             &iwl3945_rt->rt_chbitmask);
+       else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK |
+                                         IEEE80211_CHAN_2GHZ),
+                             &iwl3945_rt->rt_chbitmask);
+       else    /* 802.11g */
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
+                                         IEEE80211_CHAN_2GHZ),
+                             &iwl3945_rt->rt_chbitmask);
+
+       rate = iwl3945_rate_index_from_plcp(rate);
+       if (rate == -1)
+               iwl3945_rt->rt_rate = 0;
+       else
+               iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee;
+
+       /* antenna number */
+       iwl3945_rt->rt_antenna =
+               le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
+
+       /* set the preamble flag if we have it */
+       if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
+               iwl3945_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+       stats->flag |= RX_FLAG_RADIOTAP;
+}
+
+static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
+                                  struct iwl3945_rx_mem_buffer *rxb,
+                                  struct ieee80211_rx_status *stats)
 {
        struct ieee80211_hdr *hdr;
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-       struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
-       struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);
+       struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
+       struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
+       struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
        short len = le16_to_cpu(rx_hdr->len);
 
        /* We received data from the HW, so stop the watchdog */
@@ -265,15 +353,6 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data,
                    ("Dropping packet while interface is not open.\n");
                return;
        }
-       if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-               if (iwl_param_hwcrypto)
-                       iwl_set_decrypted_flag(priv, rxb->skb,
-                                              le32_to_cpu(rx_end->status),
-                                              stats);
-               iwl_handle_data_packet_monitor(priv, rxb, IWL_RX_DATA(pkt),
-                                              len, stats, phy_flags);
-               return;
-       }
 
        skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt);
        /* Set the size of the skb to the size of the frame */
@@ -281,23 +360,27 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data,
 
        hdr = (void *)rxb->skb->data;
 
-       if (iwl_param_hwcrypto)
-               iwl_set_decrypted_flag(priv, rxb->skb,
+       if (iwl3945_param_hwcrypto)
+               iwl3945_set_decrypted_flag(priv, rxb->skb,
                                       le32_to_cpu(rx_end->status), stats);
 
+       if (priv->add_radiotap)
+               iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats);
+
        ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
        rxb->skb = NULL;
 }
 
-static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+
+static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
+                               struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
-       struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
-       struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
+       struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
+       struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
        struct ieee80211_hdr *header;
-       u16 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
        u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
        u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
        struct ieee80211_rx_status stats = {
@@ -327,7 +410,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
        }
 
        if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-               iwl3945_handle_data_packet(priv, 1, rxb, &stats, phy_flags);
+               iwl3945_handle_data_packet(priv, 1, rxb, &stats);
                return;
        }
 
@@ -351,14 +434,14 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
         * Calculate stats.signal (quality indicator in %) based on SNR. */
        if (rx_stats_noise_diff) {
                snr = rx_stats_sig_avg / rx_stats_noise_diff;
-               stats.noise = stats.ssi - iwl_calc_db_from_ratio(snr);
-               stats.signal = iwl_calc_sig_qual(stats.ssi, stats.noise);
+               stats.noise = stats.ssi - iwl3945_calc_db_from_ratio(snr);
+               stats.signal = iwl3945_calc_sig_qual(stats.ssi, stats.noise);
 
        /* If noise info not available, calculate signal quality indicator (%)
         *   using just the dBm signal level. */
        } else {
                stats.noise = priv->last_rx_noise;
-               stats.signal = iwl_calc_sig_qual(stats.ssi, 0);
+               stats.signal = iwl3945_calc_sig_qual(stats.ssi, 0);
        }
 
 
@@ -368,24 +451,24 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
 
        stats.freq = ieee80211chan2mhz(stats.channel);
 
-       /* can be covered by iwl_report_frame() in most cases */
+       /* can be covered by iwl3945_report_frame() in most cases */
 /*      IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */
 
        header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
 
-       network_packet = iwl_is_network_packet(priv, header);
+       network_packet = iwl3945_is_network_packet(priv, header);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & IWL_DL_STATS && net_ratelimit())
+#ifdef CONFIG_IWL3945_DEBUG
+       if (iwl3945_debug_level & IWL_DL_STATS && net_ratelimit())
                IWL_DEBUG_STATS
                    ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n",
                     network_packet ? '*' : ' ',
                     stats.channel, stats.ssi, stats.ssi,
                     stats.ssi, stats.rate);
 
-       if (iwl_debug_level & (IWL_DL_RX))
+       if (iwl3945_debug_level & (IWL_DL_RX))
                /* Set "1" to report good data frames in groups of 100 */
-               iwl_report_frame(priv, pkt, header, 1);
+               iwl3945_report_frame(priv, pkt, header, 1);
 #endif
 
        if (network_packet) {
@@ -437,15 +520,20 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
                        break;
 
                        /*
-                        * TODO: There is no callback function from upper
-                        * stack to inform us when associated status. this
-                        * work around to sniff assoc_resp management frame
-                        * and finish the association process.
+                        * TODO: Use the new callback function from
+                        * mac80211 instead of sniffing these packets.
                         */
                case IEEE80211_STYPE_ASSOC_RESP:
                case IEEE80211_STYPE_REASSOC_RESP:{
                                struct ieee80211_mgmt *mgnt =
                                    (struct ieee80211_mgmt *)header;
+
+                               /* We have just associated, give some
+                                * time for the 4-way handshake if
+                                * any. Don't start scan too early. */
+                               priv->next_scan_jiffies = jiffies +
+                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+
                                priv->assoc_id = (~((1 << 15) | (1 << 14)) &
                                                  le16_to_cpu(mgnt->u.
                                                              assoc_resp.aid));
@@ -474,7 +562,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
                        }
                }
 
-               iwl3945_handle_data_packet(priv, 0, rxb, &stats, phy_flags);
+               iwl3945_handle_data_packet(priv, 0, rxb, &stats);
                break;
 
        case IEEE80211_FTYPE_CTL:
@@ -485,25 +573,24 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
                DECLARE_MAC_BUF(mac2);
                DECLARE_MAC_BUF(mac3);
 
-               if (unlikely(is_duplicate_packet(priv, header)))
+               if (unlikely(iwl3945_is_duplicate_packet(priv, header)))
                        IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
                                       print_mac(mac1, header->addr1),
                                       print_mac(mac2, header->addr2),
                                       print_mac(mac3, header->addr3));
                else
-                       iwl3945_handle_data_packet(priv, 1, rxb, &stats,
-                                                  phy_flags);
+                       iwl3945_handle_data_packet(priv, 1, rxb, &stats);
                break;
        }
        }
 }
 
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
+int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
                                 dma_addr_t addr, u16 len)
 {
        int count;
        u32 pad;
-       struct iwl_tfd_frame *tfd = (struct iwl_tfd_frame *)ptr;
+       struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
 
        count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
        pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
@@ -526,14 +613,14 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
 }
 
 /**
- * iwl_hw_txq_free_tfd - Free one TFD, those at index [txq->q.last_used]
+ * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr]
  *
  * Does NOT advance any indexes
  */
-int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
 {
-       struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
-       struct iwl_tfd_frame *bd = &bd_tmp[txq->q.last_used];
+       struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
+       struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
        struct pci_dev *dev = priv->pci_dev;
        int i;
        int counter;
@@ -556,19 +643,19 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        for (i = 1; i < counter; i++) {
                pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
                                 le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
-               if (txq->txb[txq->q.last_used].skb[0]) {
-                       struct sk_buff *skb = txq->txb[txq->q.last_used].skb[0];
-                       if (txq->txb[txq->q.last_used].skb[0]) {
+               if (txq->txb[txq->q.read_ptr].skb[0]) {
+                       struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
+                       if (txq->txb[txq->q.read_ptr].skb[0]) {
                                /* Can be called from interrupt context */
                                dev_kfree_skb_any(skb);
-                               txq->txb[txq->q.last_used].skb[0] = NULL;
+                               txq->txb[txq->q.read_ptr].skb[0] = NULL;
                        }
                }
        }
        return 0;
 }
 
-u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
+u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
 {
        int i;
        int ret = IWL_INVALID_STATION;
@@ -592,11 +679,11 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
 }
 
 /**
- * iwl_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
+ * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
  *
 */
-void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
-                             struct iwl_cmd *cmd,
+void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
+                             struct iwl3945_cmd *cmd,
                              struct ieee80211_tx_control *ctrl,
                              struct ieee80211_hdr *hdr, int sta_id, int tx_id)
 {
@@ -609,7 +696,7 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
        __le32 tx_flags;
        u16 fc = le16_to_cpu(hdr->frame_control);
 
-       rate = iwl_rates[rate_index].plcp;
+       rate = iwl3945_rates[rate_index].plcp;
        tx_flags = cmd->cmd.tx.tx_flags;
 
        /* We need to figure out how to get the sta->supp_rates while
@@ -676,10 +763,10 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
                       cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
 }
 
-u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 {
        unsigned long flags_spin;
-       struct iwl_station_entry *station;
+       struct iwl3945_station_entry *station;
 
        if (sta_id == IWL_INVALID_STATION)
                return IWL_INVALID_STATION;
@@ -694,34 +781,19 @@ 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_station(priv, &station->sta, flags);
+       iwl3945_send_add_station(priv, &station->sta, flags);
        IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
                        sta_id, tx_rate);
        return sta_id;
 }
 
-void iwl_hw_card_show_info(struct iwl_priv *priv)
-{
-       IWL_DEBUG_INFO("3945ABG HW Version %u.%u.%u\n",
-                      ((priv->eeprom.board_revision >> 8) & 0x0F),
-                      ((priv->eeprom.board_revision >> 8) >> 4),
-                      (priv->eeprom.board_revision & 0x00FF));
-
-       IWL_DEBUG_INFO("3945ABG PBA Number %.*s\n",
-                      (int)sizeof(priv->eeprom.board_pba_number),
-                      priv->eeprom.board_pba_number);
-
-       IWL_DEBUG_INFO("EEPROM_ANTENNA_SWITCH_TYPE is 0x%02X\n",
-                      priv->eeprom.antenna_switch_type);
-}
-
-static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
+static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
 {
        int rc;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
@@ -733,23 +805,23 @@ static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
                rc = pci_read_config_dword(priv->pci_dev,
                                PCI_POWER_SOURCE, &val);
                if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
-                       iwl_set_bits_mask_restricted_reg(priv, APMG_PS_CTRL_REG,
+                       iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                        APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                        ~APMG_PS_CTRL_MSK_PWR_SRC);
-                       iwl_release_restricted_access(priv);
+                       iwl3945_release_nic_access(priv);
 
-                       iwl_poll_bit(priv, CSR_GPIO_IN,
+                       iwl3945_poll_bit(priv, CSR_GPIO_IN,
                                     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
                                     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
                } else
-                       iwl_release_restricted_access(priv);
+                       iwl3945_release_nic_access(priv);
        } else {
-               iwl_set_bits_mask_restricted_reg(priv, APMG_PS_CTRL_REG,
+               iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                                ~APMG_PS_CTRL_MSK_PWR_SRC);
 
-               iwl_release_restricted_access(priv);
-               iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
+               iwl3945_release_nic_access(priv);
+               iwl3945_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);
@@ -757,24 +829,24 @@ static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
        return rc;
 }
 
-static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
 {
        int rc;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       iwl_write_restricted(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
-       iwl_write_restricted(priv, FH_RCSR_RPTR_ADDR(0),
+       iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
+       iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
                             priv->hw_setting.shared_phys +
-                            offsetof(struct iwl_shared, rx_read_ptr[0]));
-       iwl_write_restricted(priv, FH_RCSR_WPTR(0), 0);
-       iwl_write_restricted(priv, FH_RCSR_CONFIG(0),
+                            offsetof(struct iwl3945_shared, rx_read_ptr[0]));
+       iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
+       iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
                ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
@@ -785,44 +857,44 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
 
        /* fake read to flush all prev I/O */
-       iwl_read_restricted(priv, FH_RSSR_CTRL);
+       iwl3945_read_direct32(priv, FH_RSSR_CTRL);
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-static int iwl3945_tx_reset(struct iwl_priv *priv)
+static int iwl3945_tx_reset(struct iwl3945_priv *priv)
 {
        int rc;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
        /* bypass mode */
-       iwl_write_restricted_reg(priv, SCD_MODE_REG, 0x2);
+       iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
 
        /* RA 0 is active */
-       iwl_write_restricted_reg(priv, SCD_ARASTAT_REG, 0x01);
+       iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
 
        /* all 6 fifo are active */
-       iwl_write_restricted_reg(priv, SCD_TXFACT_REG, 0x3f);
+       iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
 
-       iwl_write_restricted_reg(priv, SCD_SBYP_MODE_1_REG, 0x010000);
-       iwl_write_restricted_reg(priv, SCD_SBYP_MODE_2_REG, 0x030002);
-       iwl_write_restricted_reg(priv, SCD_TXF4MF_REG, 0x000004);
-       iwl_write_restricted_reg(priv, SCD_TXF5MF_REG, 0x000005);
+       iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
+       iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
+       iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
+       iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
 
-       iwl_write_restricted(priv, FH_TSSR_CBB_BASE,
+       iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
                             priv->hw_setting.shared_phys);
 
-       iwl_write_restricted(priv, FH_TSSR_MSG_CONFIG,
+       iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
@@ -831,7 +903,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -842,12 +914,12 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
  *
  * Destroys all DMA structures and initialize them again
  */
-static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
+static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
 {
        int rc;
        int txq_id, slots_num;
 
-       iwl_hw_txq_ctx_free(priv);
+       iwl3945_hw_txq_ctx_free(priv);
 
        /* Tx CMD queue */
        rc = iwl3945_tx_reset(priv);
@@ -858,7 +930,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
        for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
                slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
                                TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+               rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
                                txq_id);
                if (rc) {
                        IWL_ERROR("Tx %d queue init failed\n", txq_id);
@@ -869,26 +941,26 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
        return rc;
 
  error:
-       iwl_hw_txq_ctx_free(priv);
+       iwl3945_hw_txq_ctx_free(priv);
        return rc;
 }
 
-int iwl_hw_nic_init(struct iwl_priv *priv)
+int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
 {
        u8 rev_id;
        int rc;
        unsigned long flags;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl3945_rx_queue *rxq = &priv->rxq;
 
-       iwl_power_init_handle(priv);
+       iwl3945_power_init_handle(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24));
-       iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+       iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24));
+       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
                    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 
-       iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-       rc = iwl_poll_bit(priv, CSR_GP_CNTRL,
+       iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
        if (rc < 0) {
@@ -897,18 +969,18 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
                return rc;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
-       iwl_write_restricted_reg(priv, APMG_CLK_EN_REG,
+       iwl3945_write_prph(priv, APMG_CLK_EN_REG,
                                 APMG_CLK_VAL_DMA_CLK_RQT |
                                 APMG_CLK_VAL_BSM_CLK_RQT);
        udelay(20);
-       iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG,
+       iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                                    APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Determine HW type */
@@ -924,25 +996,17 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
                IWL_DEBUG_INFO("RTP type \n");
        else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
                IWL_DEBUG_INFO("ALM-MB type\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB);
        } else {
                IWL_DEBUG_INFO("ALM-MM type\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM);
        }
 
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Initialize the EEPROM */
-       rc = iwl_eeprom_init(priv);
-       if (rc)
-               return rc;
-
-       spin_lock_irqsave(&priv->lock, flags);
        if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
                IWL_DEBUG_INFO("SKU OP mode is mrc\n");
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC);
        } else
                IWL_DEBUG_INFO("SKU OP mode is basic\n");
@@ -950,24 +1014,24 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
        if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
                IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
                               priv->eeprom.board_revision);
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
        } else {
                IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
                               priv->eeprom.board_revision);
-               iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
                              CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
        }
 
        if (priv->eeprom.almgor_m_version <= 1) {
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
                IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
                               priv->eeprom.almgor_m_version);
        } else {
                IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
                               priv->eeprom.almgor_m_version);
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                            CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -980,15 +1044,15 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        /* Allocate the RX queue, or reset if it is already allocated */
        if (!rxq->bd) {
-               rc = iwl_rx_queue_alloc(priv);
+               rc = iwl3945_rx_queue_alloc(priv);
                if (rc) {
                        IWL_ERROR("Unable to initialize Rx queue\n");
                        return -ENOMEM;
                }
        } else
-               iwl_rx_queue_reset(priv, rxq);
+               iwl3945_rx_queue_reset(priv, rxq);
 
-       iwl_rx_replenish(priv);
+       iwl3945_rx_replenish(priv);
 
        iwl3945_rx_init(priv, rxq);
 
@@ -996,16 +1060,16 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        /* Look at using this instead:
        rxq->need_update = 1;
-       iwl_rx_queue_update_write_ptr(priv, rxq);
+       iwl3945_rx_queue_update_write_ptr(priv, rxq);
        */
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
-       iwl_write_restricted(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
-       iwl_release_restricted_access(priv);
+       iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
+       iwl3945_release_nic_access(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1019,49 +1083,49 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 }
 
 /**
- * iwl_hw_txq_ctx_free - Free TXQ Context
+ * iwl3945_hw_txq_ctx_free - Free TXQ Context
  *
  * Destroy all TX DMA queues and structures
  */
-void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
+void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
 {
        int txq_id;
 
        /* Tx queues */
        for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
-               iwl_tx_queue_free(priv, &priv->txq[txq_id]);
+               iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
 }
 
-void iwl_hw_txq_ctx_stop(struct iwl_priv *priv)
+void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
 {
        int queue;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (iwl_grab_restricted_access(priv)) {
+       if (iwl3945_grab_nic_access(priv)) {
                spin_unlock_irqrestore(&priv->lock, flags);
-               iwl_hw_txq_ctx_free(priv);
+               iwl3945_hw_txq_ctx_free(priv);
                return;
        }
 
        /* stop SCD */
-       iwl_write_restricted_reg(priv, SCD_MODE_REG, 0);
+       iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
 
        /* reset TFD queues */
        for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
-               iwl_write_restricted(priv, FH_TCSR_CONFIG(queue), 0x0);
-               iwl_poll_restricted_bit(priv, FH_TSSR_TX_STATUS,
+               iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
+               iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
                                ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
                                1000);
        }
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_hw_txq_ctx_free(priv);
+       iwl3945_hw_txq_ctx_free(priv);
 }
 
-int iwl_hw_nic_stop_master(struct iwl_priv *priv)
+int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
 {
        int rc = 0;
        u32 reg_val;
@@ -1070,16 +1134,16 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv)
        spin_lock_irqsave(&priv->lock, flags);
 
        /* set stop master bit */
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+       iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-       reg_val = iwl_read32(priv, CSR_GP_CNTRL);
+       reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
 
        if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
            (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
                IWL_DEBUG_INFO("Card in power save, master is already "
                               "stopped\n");
        else {
-               rc = iwl_poll_bit(priv, CSR_RESET,
+               rc = iwl3945_poll_bit(priv, CSR_RESET,
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED,
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
                if (rc < 0) {
@@ -1094,47 +1158,47 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv)
        return rc;
 }
 
-int iwl_hw_nic_reset(struct iwl_priv *priv)
+int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
 {
        int rc;
        unsigned long flags;
 
-       iwl_hw_nic_stop_master(priv);
+       iwl3945_hw_nic_stop_master(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
-       rc = iwl_poll_bit(priv, CSR_GP_CNTRL,
+       rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (!rc) {
-               iwl_write_restricted_reg(priv, APMG_CLK_CTRL_REG,
+               iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
                                         APMG_CLK_VAL_BSM_CLK_RQT);
 
                udelay(10);
 
-               iwl_set_bit(priv, CSR_GP_CNTRL,
+               iwl3945_set_bit(priv, CSR_GP_CNTRL,
                            CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
-               iwl_write_restricted_reg(priv, APMG_RTC_INT_MSK_REG, 0x0);
-               iwl_write_restricted_reg(priv, APMG_RTC_INT_STT_REG,
+               iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+               iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG,
                                        0xFFFFFFFF);
 
                /* enable DMA */
-               iwl_write_restricted_reg(priv, APMG_CLK_EN_REG,
+               iwl3945_write_prph(priv, APMG_CLK_EN_REG,
                                         APMG_CLK_VAL_DMA_CLK_RQT |
                                         APMG_CLK_VAL_BSM_CLK_RQT);
                udelay(10);
 
-               iwl_set_bits_restricted_reg(priv, APMG_PS_CTRL_REG,
+               iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_RESET_REQ);
                udelay(5);
-               iwl_clear_bits_restricted_reg(priv, APMG_PS_CTRL_REG,
+               iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_RESET_REQ);
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
        }
 
        /* Clear the 'host command active' bit... */
@@ -1147,41 +1211,43 @@ int iwl_hw_nic_reset(struct iwl_priv *priv)
 }
 
 /**
- * iwl_hw_reg_adjust_power_by_temp - return index delta into power gain settings table
- */
-static int iwl_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
+ * iwl3945_hw_reg_adjust_power_by_temp
+ * return index delta into power gain settings table
+*/
+static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
 {
        return (new_reading - old_reading) * (-11) / 100;
 }
 
 /**
- * iwl_hw_reg_temp_out_of_range - Keep temperature in sane range
+ * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range
  */
-static inline int iwl_hw_reg_temp_out_of_range(int temperature)
+static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
 {
        return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
 }
 
-int iwl_hw_get_temperature(struct iwl_priv *priv)
+int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
 {
-       return iwl_read32(priv, CSR_UCODE_DRV_GP2);
+       return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
 }
 
 /**
- * iwl_hw_reg_txpower_get_temperature - get current temperature by reading from NIC
- */
-static int iwl_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
+ * iwl3945_hw_reg_txpower_get_temperature
+ * get the current temperature by reading from NIC
+*/
+static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
 {
        int temperature;
 
-       temperature = iwl_hw_get_temperature(priv);
+       temperature = iwl3945_hw_get_temperature(priv);
 
        /* driver's okay range is -260 to +25.
         *   human readable okay range is 0 to +285 */
        IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
 
        /* handle insane temp reading */
-       if (iwl_hw_reg_temp_out_of_range(temperature)) {
+       if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
                IWL_ERROR("Error bad temperature value  %d\n", temperature);
 
                /* if really really hot(?),
@@ -1206,11 +1272,11 @@ static int iwl_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
  * records new temperature in tx_mgr->temperature.
  * replaces tx_mgr->last_temperature *only* if calib needed
  *    (assumes caller will actually do the calibration!). */
-static int is_temp_calib_needed(struct iwl_priv *priv)
+static int is_temp_calib_needed(struct iwl3945_priv *priv)
 {
        int temp_diff;
 
-       priv->temperature = iwl_hw_reg_txpower_get_temperature(priv);
+       priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
        temp_diff = priv->temperature - priv->last_temperature;
 
        /* get absolute value */
@@ -1242,7 +1308,7 @@ static int is_temp_calib_needed(struct iwl_priv *priv)
 
 /* radio and DSP power table, each step is 1/2 dB.
  * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */
-static struct iwl_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = {
+static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = {
        {
         {251, 127},            /* 2.4 GHz, highest power */
         {251, 127},
@@ -1403,7 +1469,7 @@ static struct iwl_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = {
         {3, 120} }             /* 5.x GHz, lowest power */
 };
 
-static inline u8 iwl_hw_reg_fix_power_index(int index)
+static inline u8 iwl3945_hw_reg_fix_power_index(int index)
 {
        if (index < 0)
                return 0;
@@ -1416,17 +1482,17 @@ static inline u8 iwl_hw_reg_fix_power_index(int index)
 #define REG_RECALIB_PERIOD (60)
 
 /**
- * iwl_hw_reg_set_scan_power - Set Tx power for scan probe requests
+ * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests
  *
  * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
  * or 6 Mbit (OFDM) rates.
  */
-static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
+static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
                               s32 rate_index, const s8 *clip_pwrs,
-                              struct iwl_channel_info *ch_info,
+                              struct iwl3945_channel_info *ch_info,
                               int band_index)
 {
-       struct iwl_scan_power_info *scan_power_info;
+       struct iwl3945_scan_power_info *scan_power_info;
        s8 power;
        u8 power_index;
 
@@ -1462,7 +1528,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
         *   of the table. */
 
        /* don't exceed table bounds for "real" setting */
-       power_index = iwl_hw_reg_fix_power_index(power_index);
+       power_index = iwl3945_hw_reg_fix_power_index(power_index);
 
        scan_power_info->power_table_index = power_index;
        scan_power_info->tpc.tx_gain =
@@ -1472,21 +1538,21 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index,
 }
 
 /**
- * iwl_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
  *
  * Configures power settings for all rates for the current channel,
  * using values from channel info struct, and send to NIC
  */
-int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
+int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
 {
        int rate_idx, i;
-       const struct iwl_channel_info *ch_info = NULL;
-       struct iwl_txpowertable_cmd txpower = {
+       const struct iwl3945_channel_info *ch_info = NULL;
+       struct iwl3945_txpowertable_cmd txpower = {
                .channel = priv->active_rxon.channel,
        };
 
        txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1;
-       ch_info = iwl_get_channel_info(priv,
+       ch_info = iwl3945_get_channel_info(priv,
                                       priv->phymode,
                                       le16_to_cpu(priv->active_rxon.channel));
        if (!ch_info) {
@@ -1508,7 +1574,7 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
             rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
 
                txpower.power[i].tpc = ch_info->power_info[i].tpc;
-               txpower.power[i].rate = iwl_rates[rate_idx].plcp;
+               txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
                IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
                                le16_to_cpu(txpower.channel),
@@ -1521,7 +1587,7 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
        for (rate_idx = IWL_FIRST_CCK_RATE;
             rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) {
                txpower.power[i].tpc = ch_info->power_info[i].tpc;
-               txpower.power[i].rate = iwl_rates[rate_idx].plcp;
+               txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
                IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
                                le16_to_cpu(txpower.channel),
@@ -1531,13 +1597,13 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
                                txpower.power[i].rate);
        }
 
-       return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
-                       sizeof(struct iwl_txpowertable_cmd), &txpower);
+       return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
+                       sizeof(struct iwl3945_txpowertable_cmd), &txpower);
 
 }
 
 /**
- * iwl_hw_reg_set_new_power - Configures power tables at new levels
+ * iwl3945_hw_reg_set_new_power - Configures power tables at new levels
  * @ch_info: Channel to update.  Uses power_info.requested_power.
  *
  * Replace requested_power and base_power_index ch_info fields for
@@ -1552,10 +1618,10 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
  *      properly fill out the scan powers, and actual h/w gain settings,
  *      and send changes to NIC
  */
-static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
-                            struct iwl_channel_info *ch_info)
+static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
+                            struct iwl3945_channel_info *ch_info)
 {
-       struct iwl_channel_power_info *power_info;
+       struct iwl3945_channel_power_info *power_info;
        int power_changed = 0;
        int i;
        const s8 *clip_pwrs;
@@ -1595,7 +1661,7 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
                    ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
                    requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF;
 
-               /* do all CCK rates' iwl_channel_power_info structures */
+               /* do all CCK rates' iwl3945_channel_power_info structures */
                for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) {
                        power_info->requested_power = power;
                        power_info->base_power_index =
@@ -1609,13 +1675,13 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv,
 }
 
 /**
- * iwl_hw_reg_get_ch_txpower_limit - returns new power limit for channel
+ * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel
  *
  * NOTE: Returned power limit may be less (but not more) than requested,
  *      based strictly on regulatory (eeprom and spectrum mgt) limitations
  *      (no consideration for h/w clipping limitations).
  */
-static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
+static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
 {
        s8 max_power;
 
@@ -1634,7 +1700,7 @@ static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
 }
 
 /**
- * iwl_hw_reg_comp_txpower_temp - Compensate for temperature
+ * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature
  *
  * Compensate txpower settings of *all* channels for temperature.
  * This only accounts for the difference between current temperature
@@ -1643,9 +1709,9 @@ static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
  *
  * If RxOn is "associated", this sends the new Txpower to NIC!
  */
-static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
+static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
 {
-       struct iwl_channel_info *ch_info = NULL;
+       struct iwl3945_channel_info *ch_info = NULL;
        int delta_index;
        const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
        u8 a_band;
@@ -1666,7 +1732,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
 
                /* get power index adjustment based on curr and factory
                 * temps */
-               delta_index = iwl_hw_reg_adjust_power_by_temp(temperature,
+               delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
                                                              ref_temp);
 
                /* set tx power value for all rates, OFDM and CCK */
@@ -1679,7 +1745,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
                        power_idx += delta_index;
 
                        /* stay within table range */
-                       power_idx = iwl_hw_reg_fix_power_index(power_idx);
+                       power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
                        ch_info->power_info[rate_index].
                            power_table_index = (u8) power_idx;
                        ch_info->power_info[rate_index].tpc =
@@ -1694,19 +1760,19 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
                        s32 actual_index = (scan_tbl_index == 0) ?
                            IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
-                       iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
+                       iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
                                           actual_index, clip_pwrs,
                                           ch_info, a_band);
                }
        }
 
        /* send Txpower command for current channel to ucode */
-       return iwl_hw_reg_send_txpower(priv);
+       return iwl3945_hw_reg_send_txpower(priv);
 }
 
-int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
+int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
 {
-       struct iwl_channel_info *ch_info;
+       struct iwl3945_channel_info *ch_info;
        s8 max_power;
        u8 a_band;
        u8 i;
@@ -1728,26 +1794,26 @@ int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
 
                /* find minimum power of all user and regulatory constraints
                 *    (does not consider h/w clipping limitations) */
-               max_power = iwl_hw_reg_get_ch_txpower_limit(ch_info);
+               max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info);
                max_power = min(power, max_power);
                if (max_power != ch_info->curr_txpow) {
                        ch_info->curr_txpow = max_power;
 
                        /* this considers the h/w clipping limitations */
-                       iwl_hw_reg_set_new_power(priv, ch_info);
+                       iwl3945_hw_reg_set_new_power(priv, ch_info);
                }
        }
 
        /* update txpower settings for all channels,
         *   send to NIC if associated. */
        is_temp_calib_needed(priv);
-       iwl_hw_reg_comp_txpower_temp(priv);
+       iwl3945_hw_reg_comp_txpower_temp(priv);
 
        return 0;
 }
 
 /* will add 3945 channel switch cmd handling later */
-int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
 {
        return 0;
 }
@@ -1762,26 +1828,26 @@ int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel)
  *     -- send new set of gain settings to NIC
  * NOTE:  This should continue working, even when we're not associated,
  *   so we can keep our internal table of scan powers current. */
-void iwl3945_reg_txpower_periodic(struct iwl_priv *priv)
+void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
 {
        /* This will kick in the "brute force"
-        * iwl_hw_reg_comp_txpower_temp() below */
+        * iwl3945_hw_reg_comp_txpower_temp() below */
        if (!is_temp_calib_needed(priv))
                goto reschedule;
 
        /* Set up a new set of temp-adjusted TxPowers, send to NIC.
         * This is based *only* on current temperature,
         * ignoring any previous power measurements */
-       iwl_hw_reg_comp_txpower_temp(priv);
+       iwl3945_hw_reg_comp_txpower_temp(priv);
 
  reschedule:
        queue_delayed_work(priv->workqueue,
                           &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ);
 }
 
-void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
+static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
+       struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
                                             thermal_periodic.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -1793,7 +1859,7 @@ void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
 }
 
 /**
- * iwl_hw_reg_get_ch_grp_index - find the channel-group index (0-4)
+ * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4)
  *                                for the channel.
  *
  * This function is used when initializing channel-info structs.
@@ -1803,10 +1869,10 @@ void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
  *      on A-band, EEPROM's "group frequency" entries represent the top
  *      channel in each group 1-4.  Group 5 All B/G channels are in group 0.
  */
-static u16 iwl_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
-                                      const struct iwl_channel_info *ch_info)
+static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
+                                      const struct iwl3945_channel_info *ch_info)
 {
-       struct iwl_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
+       struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
        u8 group;
        u16 group_index = 0;    /* based on factory calib frequencies */
        u8 grp_channel;
@@ -1832,20 +1898,20 @@ static u16 iwl_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
 }
 
 /**
- * iwl_hw_reg_get_matched_power_index - Interpolate to get nominal index
+ * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index
  *
  * Interpolate to get nominal (i.e. at factory calibration temperature) index
  *   into radio/DSP gain settings table for requested power.
  */
-static int iwl_hw_reg_get_matched_power_index(struct iwl_priv *priv,
+static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
                                       s8 requested_power,
                                       s32 setting_index, s32 *new_index)
 {
-       const struct iwl_eeprom_txpower_group *chnl_grp = NULL;
+       const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
        s32 index0, index1;
        s32 power = 2 * requested_power;
        s32 i;
-       const struct iwl_eeprom_txpower_sample *samples;
+       const struct iwl3945_eeprom_txpower_sample *samples;
        s32 gains0, gains1;
        s32 res;
        s32 denominator;
@@ -1885,11 +1951,11 @@ static int iwl_hw_reg_get_matched_power_index(struct iwl_priv *priv,
        return 0;
 }
 
-static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv)
+static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
 {
        u32 i;
        s32 rate_index;
-       const struct iwl_eeprom_txpower_group *group;
+       const struct iwl3945_eeprom_txpower_group *group;
 
        IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
 
@@ -1965,10 +2031,10 @@ static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv)
  *
  * This does *not* write values to NIC, just sets up our internal table.
  */
-int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
+int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
 {
-       struct iwl_channel_info *ch_info = NULL;
-       struct iwl_channel_power_info *pwr_info;
+       struct iwl3945_channel_info *ch_info = NULL;
+       struct iwl3945_channel_power_info *pwr_info;
        int delta_index;
        u8 rate_index;
        u8 scan_tbl_index;
@@ -1981,10 +2047,10 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
 
        /* save temperature reference,
         *   so we can determine next time to calibrate */
-       temperature = iwl_hw_reg_txpower_get_temperature(priv);
+       temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
        priv->last_temperature = temperature;
 
-       iwl_hw_reg_init_channel_groups(priv);
+       iwl3945_hw_reg_init_channel_groups(priv);
 
        /* initialize Tx power info for each and every channel, 2.4 and 5.x */
        for (i = 0, ch_info = priv->channel_info; i < priv->channel_count;
@@ -1995,14 +2061,14 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
 
                /* find this channel's channel group (*not* "band") index */
                ch_info->group_index =
-                       iwl_hw_reg_get_ch_grp_index(priv, ch_info);
+                       iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
 
                /* Get this chnlgrp's rate->max/clip-powers table */
                clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
 
                /* calculate power index *adjustment* value according to
                 *  diff between current temperature and factory temperature */
-               delta_index = iwl_hw_reg_adjust_power_by_temp(temperature,
+               delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
                                priv->eeprom.groups[ch_info->group_index].
                                temperature);
 
@@ -2025,7 +2091,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
 
                        /* get base (i.e. at factory-measured temperature)
                         *    power table index for this rate's power */
-                       rc = iwl_hw_reg_get_matched_power_index(priv, pwr,
+                       rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr,
                                                         ch_info->group_index,
                                                         &power_idx);
                        if (rc) {
@@ -2038,9 +2104,9 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                        power_idx += delta_index;
 
                        /* stay within range of gain table */
-                       power_idx = iwl_hw_reg_fix_power_index(power_idx);
+                       power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
 
-                       /* fill 1 OFDM rate's iwl_channel_power_info struct */
+                       /* fill 1 OFDM rate's iwl3945_channel_power_info struct */
                        pwr_info->requested_power = pwr;
                        pwr_info->power_table_index = (u8) power_idx;
                        pwr_info->tpc.tx_gain =
@@ -2059,11 +2125,11 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                        IWL_CCK_FROM_OFDM_INDEX_DIFF;
 
                /* stay within table range */
-               pwr_index = iwl_hw_reg_fix_power_index(pwr_index);
+               pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index);
                gain = power_gain_table[a_band][pwr_index].tx_gain;
                dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten;
 
-               /* fill each CCK rate's iwl_channel_power_info structure
+               /* fill each CCK rate's iwl3945_channel_power_info structure
                 * NOTE:  All CCK-rate Txpwrs are the same for a given chnl!
                 * NOTE:  CCK rates start at end of OFDM rates! */
                for (rate_index = 0;
@@ -2081,7 +2147,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
                        s32 actual_index = (scan_tbl_index == 0) ?
                                IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
-                       iwl_hw_reg_set_scan_power(priv, scan_tbl_index,
+                       iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
                                actual_index, clip_pwrs, ch_info, a_band);
                }
        }
@@ -2089,66 +2155,66 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
        return 0;
 }
 
-int iwl_hw_rxq_stop(struct iwl_priv *priv)
+int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
 {
        int rc;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       iwl_write_restricted(priv, FH_RCSR_CONFIG(0), 0);
-       rc = iwl_poll_restricted_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000);
+       iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
+       rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000);
        if (rc < 0)
                IWL_ERROR("Can't stop Rx DMA.\n");
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
 {
        int rc;
        unsigned long flags;
        int txq_id = txq->q.id;
 
-       struct iwl_shared *shared_data = priv->hw_setting.shared_virt;
+       struct iwl3945_shared *shared_data = priv->hw_setting.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_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
-       iwl_write_restricted(priv, FH_CBCC_CTRL(txq_id), 0);
-       iwl_write_restricted(priv, FH_CBCC_BASE(txq_id), 0);
+       iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
+       iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
 
-       iwl_write_restricted(priv, FH_TCSR_CONFIG(txq_id),
+       iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        /* fake read to flush all prev. writes */
-       iwl_read32(priv, FH_TSSR_CBB_BASE);
+       iwl3945_read32(priv, FH_TSSR_CBB_BASE);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-int iwl_hw_get_rx_read(struct iwl_priv *priv)
+int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
 {
-       struct iwl_shared *shared_data = priv->hw_setting.shared_virt;
+       struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
 
        return le32_to_cpu(shared_data->rx_read_ptr[0]);
 }
@@ -2156,22 +2222,22 @@ int iwl_hw_get_rx_read(struct iwl_priv *priv)
 /**
  * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
  */
-int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
+int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
 {
        int rc, i, index, prev_index;
-       struct iwl_rate_scaling_cmd rate_cmd = {
+       struct iwl3945_rate_scaling_cmd rate_cmd = {
                .reserved = {0, 0, 0},
        };
-       struct iwl_rate_scaling_info *table = rate_cmd.table;
+       struct iwl3945_rate_scaling_info *table = rate_cmd.table;
 
-       for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) {
-               index = iwl_rates[i].table_rs_index;
+       for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) {
+               index = iwl3945_rates[i].table_rs_index;
 
                table[index].rate_n_flags =
-                       iwl_hw_set_rate_n_flags(iwl_rates[i].plcp, 0);
+                       iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
                table[index].try_cnt = priv->retry_rate;
-               prev_index = iwl_get_prev_ieee_rate(i);
-               table[index].next_rate_index = iwl_rates[prev_index].table_rs_index;
+               prev_index = iwl3945_get_prev_ieee_rate(i);
+               table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
        }
 
        switch (priv->phymode) {
@@ -2180,14 +2246,14 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
                /* If one of the following CCK rates is used,
                 * have it fall back to the 6M OFDM rate */
                for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
-                       table[i].next_rate_index = iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
+                       table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
 
                /* Don't fall back to CCK rates */
                table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
 
                /* Don't drop out of OFDM rates */
                table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
-                   iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
+                   iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
                break;
 
        case MODE_IEEE80211B:
@@ -2195,7 +2261,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
                /* If an OFDM rate is used, have it fall back to the
                 * 1M CCK rates */
                for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
-                       table[i].next_rate_index = iwl_rates[IWL_FIRST_CCK_RATE].table_rs_index;
+                       table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
 
                /* CCK shouldn't fall back to OFDM... */
                table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
@@ -2208,25 +2274,26 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
 
        /* Update the rate scaling for control frame Tx */
        rate_cmd.table_id = 0;
-       rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+       rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
                              &rate_cmd);
        if (rc)
                return rc;
 
        /* Update the rate scaling for data frame Tx */
        rate_cmd.table_id = 1;
-       return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
+       return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
                                &rate_cmd);
 }
 
-int iwl_hw_set_hw_setting(struct iwl_priv *priv)
+/* Called when initializing driver */
+int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
 {
        memset((void *)&priv->hw_setting, 0,
-              sizeof(struct iwl_driver_hw_info));
+              sizeof(struct iwl3945_driver_hw_info));
 
        priv->hw_setting.shared_virt =
            pci_alloc_consistent(priv->pci_dev,
-                                sizeof(struct iwl_shared),
+                                sizeof(struct iwl3945_shared),
                                 &priv->hw_setting.shared_phys);
 
        if (!priv->hw_setting.shared_virt) {
@@ -2236,31 +2303,31 @@ int iwl_hw_set_hw_setting(struct iwl_priv *priv)
        }
 
        priv->hw_setting.ac_queue_count = AC_NUM;
-       priv->hw_setting.rx_buffer_size = IWL_RX_BUF_SIZE;
-       priv->hw_setting.tx_cmd_len = sizeof(struct iwl_tx_cmd);
+       priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE;
+       priv->hw_setting.max_pkt_size = 2342;
+       priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
        priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
        priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
-       priv->hw_setting.cck_flag = 0;
        priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
        priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
        return 0;
 }
 
-unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
-                         struct iwl_frame *frame, u8 rate)
+unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+                         struct iwl3945_frame *frame, u8 rate)
 {
-       struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+       struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
        unsigned int frame_size;
 
-       tx_beacon_cmd = (struct iwl_tx_beacon_cmd *)&frame->u;
+       tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
        memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
        tx_beacon_cmd->tx.sta_id = IWL3945_BROADCAST_ID;
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
-       frame_size = iwl_fill_beacon_frame(priv,
+       frame_size = iwl3945_fill_beacon_frame(priv,
                                tx_beacon_cmd->frame,
-                               BROADCAST_ADDR,
+                               iwl3945_broadcast_addr,
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 
        BUG_ON(frame_size > MAX_MPDU_SIZE);
@@ -2277,35 +2344,43 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
        tx_beacon_cmd->tx.supp_rates[1] =
                (IWL_CCK_BASIC_RATES_MASK & 0xF);
 
-       return (sizeof(struct iwl_tx_beacon_cmd) + frame_size);
+       return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size);
 }
 
-void iwl_hw_rx_handler_setup(struct iwl_priv *priv)
+void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
 {
        priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
 }
 
-void iwl_hw_setup_deferred_work(struct iwl_priv *priv)
+void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
 {
        INIT_DELAYED_WORK(&priv->thermal_periodic,
                          iwl3945_bg_reg_txpower_periodic);
 }
 
-void iwl_hw_cancel_deferred_work(struct iwl_priv *priv)
+void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
 {
        cancel_delayed_work(&priv->thermal_periodic);
 }
 
-struct pci_device_id iwl_hw_card_ids[] = {
-       {0x8086, 0x4222, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {0x8086, 0x4227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+struct pci_device_id iwl3945_hw_card_ids[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4222)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4227)},
        {0}
 };
 
-inline int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv)
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism.  Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
 {
-       _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+       _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
        return 0;
 }
 
-MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
+MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);
index 813902e9f8c2fb096804c39befaeefae2dc03146..20b925f57e355f2bd5fb36b1884aa5359ecf0d95 100644 (file)
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
+/*
+ * Please use this file (iwl-3945.h) for driver implementation definitions.
+ * Please use iwl-3945-commands.h for uCode API definitions.
+ * Please use iwl-3945-hw.h for hardware-related definitions.
+ */
 
 #ifndef __iwl_3945_h__
 #define __iwl_3945_h__
 
+#include <linux/pci.h> /* for struct pci_device_id */
+#include <linux/kernel.h>
+#include <net/ieee80211_radiotap.h>
+
+/* Hardware specific file defines the PCI IDs table for that hardware module */
+extern struct pci_device_id iwl3945_hw_card_ids[];
+
+#define DRV_NAME       "iwl3945"
+#include "iwl-3945-hw.h"
+#include "iwl-prph.h"
+#include "iwl-3945-debug.h"
+
+/* Default noise level to report when noise measurement is not available.
+ *   This may be because we're:
+ *   1)  Not associated (4965, no beacon statistics being sent to driver)
+ *   2)  Scanning (noise measurement does not apply to associated channel)
+ *   3)  Receiving CCK (3945 delivers noise info only for OFDM frames)
+ * Use default noise value of -127 ... this is below the range of measurable
+ *   Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user.
+ *   Also, -127 works better than 0 when averaging frames with/without
+ *   noise info (e.g. averaging might be done in app); measured dBm values are
+ *   always negative ... using a negative value as the default keeps all
+ *   averages within an s8's (used in some apps) range of negative values. */
+#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
+
+/* Module parameters accessible from iwl-*.c */
+extern int iwl3945_param_hwcrypto;
+extern int iwl3945_param_queues_num;
+
+enum iwl3945_antenna {
+       IWL_ANTENNA_DIVERSITY,
+       IWL_ANTENNA_MAIN,
+       IWL_ANTENNA_AUX
+};
+
+/*
+ * RTS threshold here is total size [2347] minus 4 FCS bytes
+ * Per spec:
+ *   a value of 0 means RTS on all data/management packets
+ *   a value > max MSDU size means no RTS
+ * else RTS for data/management frames where MPDU is larger
+ *   than RTS value.
+ */
+#define IWL_RX_BUF_SIZE           3000U
+#define DEFAULT_RTS_THRESHOLD     2347U
+#define MIN_RTS_THRESHOLD         0U
+#define MAX_RTS_THRESHOLD         2347U
+#define MAX_MSDU_SIZE            2304U
+#define MAX_MPDU_SIZE            2346U
+#define DEFAULT_BEACON_INTERVAL   100U
+#define        DEFAULT_SHORT_RETRY_LIMIT 7U
+#define        DEFAULT_LONG_RETRY_LIMIT  4U
+
+struct iwl3945_rx_mem_buffer {
+       dma_addr_t dma_addr;
+       struct sk_buff *skb;
+       struct list_head list;
+};
+
+/*
+ * Generic queue structure
+ *
+ * Contains common data for Rx and Tx queues
+ */
+struct iwl3945_queue {
+       int n_bd;              /* number of BDs in this queue */
+       int write_ptr;       /* 1-st empty entry (index) host_w*/
+       int read_ptr;         /* last used entry (index) host_r*/
+       dma_addr_t dma_addr;   /* physical addr for BD's */
+       int n_window;          /* safe queue window */
+       u32 id;
+       int low_mark;          /* low watermark, resume queue if free
+                               * space more than this */
+       int high_mark;         /* high watermark, stop queue if free
+                               * space less than this */
+} __attribute__ ((packed));
+
+#define MAX_NUM_OF_TBS          (20)
+
+/* One for each TFD */
+struct iwl3945_tx_info {
+       struct ieee80211_tx_status status;
+       struct sk_buff *skb[MAX_NUM_OF_TBS];
+};
+
+/**
+ * struct iwl3945_tx_queue - Tx Queue for DMA
+ * @q: generic Rx/Tx queue descriptor
+ * @bd: base of circular buffer of TFDs
+ * @cmd: array of command/Tx buffers
+ * @dma_addr_cmd: physical address of cmd/tx buffer array
+ * @txb: array of per-TFD driver data
+ * @need_update: indicates need to update read/write index
+ *
+ * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
+ * descriptors) and required locking structures.
+ */
+struct iwl3945_tx_queue {
+       struct iwl3945_queue q;
+       struct iwl3945_tfd_frame *bd;
+       struct iwl3945_cmd *cmd;
+       dma_addr_t dma_addr_cmd;
+       struct iwl3945_tx_info *txb;
+       int need_update;
+       int active;
+};
+
+#define IWL_NUM_SCAN_RATES         (2)
+
+struct iwl3945_channel_tgd_info {
+       u8 type;
+       s8 max_power;
+};
+
+struct iwl3945_channel_tgh_info {
+       s64 last_radar_time;
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl3945_channel_power_info {
+       struct iwl3945_tx_power tpc;    /* actual radio and DSP gain settings */
+       s8 power_table_index;   /* actual (compenst'd) index into gain table */
+       s8 base_power_index;    /* gain index for power at factory temp. */
+       s8 requested_power;     /* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl3945_scan_power_info {
+       struct iwl3945_tx_power tpc;    /* actual radio and DSP gain settings */
+       s8 power_table_index;   /* actual (compenst'd) index into gain table */
+       s8 requested_power;     /* scan pwr (dBm) requested for chnl/rate */
+};
+
+/*
+ * One for each channel, holds all channel setup data
+ * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
+ *     with one another!
+ */
+#define IWL4965_MAX_RATE (33)
+
+struct iwl3945_channel_info {
+       struct iwl3945_channel_tgd_info tgd;
+       struct iwl3945_channel_tgh_info tgh;
+       struct iwl3945_eeprom_channel eeprom;   /* EEPROM regulatory limit */
+       struct iwl3945_eeprom_channel fat_eeprom;       /* EEPROM regulatory limit for
+                                                * FAT channel */
+
+       u8 channel;       /* channel number */
+       u8 flags;         /* flags copied from EEPROM */
+       s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
+       s8 curr_txpow;    /* (dBm) regulatory/spectrum/user (not h/w) */
+       s8 min_power;     /* always 0 */
+       s8 scan_power;    /* (dBm) regul. eeprom, direct scans, any rate */
+
+       u8 group_index;   /* 0-4, maps channel to group1/2/3/4/5 */
+       u8 band_index;    /* 0-4, maps channel to band1/2/3/4/5 */
+       u8 phymode;       /* MODE_IEEE80211{A,B,G} */
+
+       /* Radio/DSP gain settings for each "normal" data Tx rate.
+        * These include, in addition to RF and DSP gain, a few fields for
+        *   remembering/modifying gain settings (indexes). */
+       struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
+
+       /* Radio/DSP gain settings for each scan rate, for directed scans. */
+       struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
+
+struct iwl3945_clip_group {
+       /* maximum power level to prevent clipping for each rate, derived by
+        *   us from this band's saturation power in EEPROM */
+       const s8 clip_powers[IWL_MAX_RATES];
+};
+
+#include "iwl-3945-rs.h"
+
+#define IWL_TX_FIFO_AC0        0
+#define IWL_TX_FIFO_AC1        1
+#define IWL_TX_FIFO_AC2        2
+#define IWL_TX_FIFO_AC3        3
+#define IWL_TX_FIFO_HCCA_1     5
+#define IWL_TX_FIFO_HCCA_2     6
+#define IWL_TX_FIFO_NONE       7
+
+/* Minimum number of queues. MAX_NUM is defined in hw specific files */
+#define IWL_MIN_NUM_QUEUES     4
+
+/* Power management (not Tx power) structures */
+
+struct iwl3945_power_vec_entry {
+       struct iwl3945_powertable_cmd cmd;
+       u8 no_dtim;
+};
+#define IWL_POWER_RANGE_0  (0)
+#define IWL_POWER_RANGE_1  (1)
+
+#define IWL_POWER_MODE_CAM     0x00    /* Continuously Aware Mode, always on */
+#define IWL_POWER_INDEX_3      0x03
+#define IWL_POWER_INDEX_5      0x05
+#define IWL_POWER_AC           0x06
+#define IWL_POWER_BATTERY      0x07
+#define IWL_POWER_LIMIT                0x07
+#define IWL_POWER_MASK         0x0F
+#define IWL_POWER_ENABLED      0x10
+#define IWL_POWER_LEVEL(x)     ((x) & IWL_POWER_MASK)
+
+struct iwl3945_power_mgr {
+       spinlock_t lock;
+       struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC];
+       struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC];
+       u8 active_index;
+       u32 dtim_val;
+};
+
+#define IEEE80211_DATA_LEN              2304
+#define IEEE80211_4ADDR_LEN             30
+#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+struct iwl3945_frame {
+       union {
+               struct ieee80211_hdr frame;
+               struct iwl3945_tx_beacon_cmd beacon;
+               u8 raw[IEEE80211_FRAME_LEN];
+               u8 cmd[360];
+       } u;
+       struct list_head list;
+};
+
+#define SEQ_TO_QUEUE(x)  ((x >> 8) & 0xbf)
+#define QUEUE_TO_SEQ(x)  ((x & 0xbf) << 8)
+#define SEQ_TO_INDEX(x) (x & 0xff)
+#define INDEX_TO_SEQ(x) (x & 0xff)
+#define SEQ_HUGE_FRAME  (0x4000)
+#define SEQ_RX_FRAME    __constant_cpu_to_le16(0x8000)
+#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
+#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
+
+enum {
+       /* CMD_SIZE_NORMAL = 0, */
+       CMD_SIZE_HUGE = (1 << 0),
+       /* CMD_SYNC = 0, */
+       CMD_ASYNC = (1 << 1),
+       /* CMD_NO_SKB = 0, */
+       CMD_WANT_SKB = (1 << 2),
+};
+
+struct iwl3945_cmd;
+struct iwl3945_priv;
+
+struct iwl3945_cmd_meta {
+       struct iwl3945_cmd_meta *source;
+       union {
+               struct sk_buff *skb;
+               int (*callback)(struct iwl3945_priv *priv,
+                               struct iwl3945_cmd *cmd, struct sk_buff *skb);
+       } __attribute__ ((packed)) u;
+
+       /* The CMD_SIZE_HUGE flag bit indicates that the command
+        * structure is stored at the end of the shared queue memory. */
+       u32 flags;
+
+} __attribute__ ((packed));
+
+/**
+ * struct iwl3945_cmd
+ *
+ * For allocation of the command and tx queues, this establishes the overall
+ * size of the largest command we send to uCode, except for a scan command
+ * (which is relatively huge; space is allocated separately).
+ */
+struct iwl3945_cmd {
+       struct iwl3945_cmd_meta meta;
+       struct iwl3945_cmd_header hdr;
+       union {
+               struct iwl3945_addsta_cmd addsta;
+               struct iwl3945_led_cmd led;
+               u32 flags;
+               u8 val8;
+               u16 val16;
+               u32 val32;
+               struct iwl3945_bt_cmd bt;
+               struct iwl3945_rxon_time_cmd rxon_time;
+               struct iwl3945_powertable_cmd powertable;
+               struct iwl3945_qosparam_cmd qosparam;
+               struct iwl3945_tx_cmd tx;
+               struct iwl3945_tx_beacon_cmd tx_beacon;
+               struct iwl3945_rxon_assoc_cmd rxon_assoc;
+               u8 *indirect;
+               u8 payload[360];
+       } __attribute__ ((packed)) cmd;
+} __attribute__ ((packed));
+
+struct iwl3945_host_cmd {
+       u8 id;
+       u16 len;
+       struct iwl3945_cmd_meta meta;
+       const void *data;
+};
+
+#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \
+                             sizeof(struct iwl3945_cmd_meta))
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
+
+/**
+ * struct iwl3945_rx_queue - Rx queue
+ * @processed: Internal index to last handled Rx packet
+ * @read: Shared index to newest available Rx buffer
+ * @write: Shared index to oldest written Rx packet
+ * @free_count: Number of pre-allocated buffers in rx_free
+ * @rx_free: list of free SKBs for use
+ * @rx_used: List of Rx buffers with no SKB
+ * @need_update: flag to indicate we need to update read/write index
+ *
+ * NOTE:  rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers
+ */
+struct iwl3945_rx_queue {
+       __le32 *bd;
+       dma_addr_t dma_addr;
+       struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
+       struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE];
+       u32 processed;
+       u32 read;
+       u32 write;
+       u32 free_count;
+       struct list_head rx_free;
+       struct list_head rx_used;
+       int need_update;
+       spinlock_t lock;
+};
+
+#define IWL_SUPPORTED_RATES_IE_LEN         8
+
+#define SCAN_INTERVAL 100
+
+#define MAX_A_CHANNELS  252
+#define MIN_A_CHANNELS  7
+
+#define MAX_B_CHANNELS  14
+#define MIN_B_CHANNELS  1
+
+#define STATUS_HCMD_ACTIVE     0       /* host command in progress */
+#define STATUS_INT_ENABLED     1
+#define STATUS_RF_KILL_HW      2
+#define STATUS_RF_KILL_SW      3
+#define STATUS_INIT            4
+#define STATUS_ALIVE           5
+#define STATUS_READY           6
+#define STATUS_TEMPERATURE     7
+#define STATUS_GEO_CONFIGURED  8
+#define STATUS_EXIT_PENDING    9
+#define STATUS_IN_SUSPEND      10
+#define STATUS_STATISTICS      11
+#define STATUS_SCANNING                12
+#define STATUS_SCAN_ABORTING   13
+#define STATUS_SCAN_HW         14
+#define STATUS_POWER_PMI       15
+#define STATUS_FW_ERROR                16
+#define STATUS_CONF_PENDING    17
+
+#define MAX_TID_COUNT        9
+
+#define IWL_INVALID_RATE     0xFF
+#define IWL_INVALID_VALUE    -1
+
+struct iwl3945_tid_data {
+       u16 seq_number;
+};
+
+struct iwl3945_hw_key {
+       enum ieee80211_key_alg alg;
+       int keylen;
+       u8 key[32];
+};
+
+union iwl3945_ht_rate_supp {
+       u16 rates;
+       struct {
+               u8 siso_rate;
+               u8 mimo_rate;
+       };
+};
+
+#ifdef CONFIG_IWL3945_QOS
+
+union iwl3945_qos_capabity {
+       struct {
+               u8 edca_count:4;        /* bit 0-3 */
+               u8 q_ack:1;             /* bit 4 */
+               u8 queue_request:1;     /* bit 5 */
+               u8 txop_request:1;      /* bit 6 */
+               u8 reserved:1;          /* bit 7 */
+       } q_AP;
+       struct {
+               u8 acvo_APSD:1;         /* bit 0 */
+               u8 acvi_APSD:1;         /* bit 1 */
+               u8 ac_bk_APSD:1;        /* bit 2 */
+               u8 ac_be_APSD:1;        /* bit 3 */
+               u8 q_ack:1;             /* bit 4 */
+               u8 max_len:2;           /* bit 5-6 */
+               u8 more_data_ack:1;     /* bit 7 */
+       } q_STA;
+       u8 val;
+};
+
+/* QoS structures */
+struct iwl3945_qos_info {
+       int qos_enable;
+       int qos_active;
+       union iwl3945_qos_capabity qos_cap;
+       struct iwl3945_qosparam_cmd def_qos_parm;
+};
+#endif /*CONFIG_IWL3945_QOS */
+
+#define STA_PS_STATUS_WAKE             0
+#define STA_PS_STATUS_SLEEP            1
+
+struct iwl3945_station_entry {
+       struct iwl3945_addsta_cmd sta;
+       struct iwl3945_tid_data tid[MAX_TID_COUNT];
+       union {
+               struct {
+                       u8 rate;
+                       u8 flags;
+               } s;
+               u16 rate_n_flags;
+       } current_rate;
+       u8 used;
+       u8 ps_status;
+       struct iwl3945_hw_key keyinfo;
+};
+
+/* one for each uCode image (inst/data, boot/init/runtime) */
+struct fw_desc {
+       void *v_addr;           /* access by driver */
+       dma_addr_t p_addr;      /* access by card's busmaster DMA */
+       u32 len;                /* bytes */
+};
+
+/* uCode file layout */
+struct iwl3945_ucode {
+       __le32 ver;             /* major/minor/subminor */
+       __le32 inst_size;       /* bytes of runtime instructions */
+       __le32 data_size;       /* bytes of runtime data */
+       __le32 init_size;       /* bytes of initialization instructions */
+       __le32 init_data_size;  /* bytes of initialization data */
+       __le32 boot_size;       /* bytes of bootstrap instructions */
+       u8 data[0];             /* data in same order as "size" elements */
+};
+
+#define IWL_IBSS_MAC_HASH_SIZE 32
+
+struct iwl3945_ibss_seq {
+       u8 mac[ETH_ALEN];
+       u16 seq_num;
+       u16 frag_num;
+       unsigned long packet_time;
+       struct list_head list;
+};
+
+/**
+ * struct iwl3945_driver_hw_info
+ * @max_txq_num: Max # Tx queues supported
+ * @ac_queue_count: # Tx queues for EDCA Access Categories (AC)
+ * @tx_cmd_len: Size of Tx command (but not including frame itself)
+ * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
+ * @rx_buf_size:
+ * @max_pkt_size:
+ * @max_rxq_log: Log-base-2 of max_rxq_size
+ * @max_stations:
+ * @bcast_sta_id:
+ * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
+ * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
+ */
+struct iwl3945_driver_hw_info {
+       u16 max_txq_num;
+       u16 ac_queue_count;
+       u16 tx_cmd_len;
+       u16 max_rxq_size;
+       u32 rx_buf_size;
+       u32 max_pkt_size;
+       u16 max_rxq_log;
+       u8  max_stations;
+       u8  bcast_sta_id;
+       void *shared_virt;
+       dma_addr_t shared_phys;
+};
+
+#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\
+                      x->u.rx_frame.stats.payload + \
+                      x->u.rx_frame.stats.phy_count))
+#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\
+                      IWL_RX_HDR(x)->payload + \
+                      le16_to_cpu(IWL_RX_HDR(x)->len)))
+#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
+#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
+
+
+/******************************************************************************
+ *
+ * Functions implemented in iwl-base.c which are forward declared here
+ * for use by iwl-*.c
+ *
+ *****************************************************************************/
+struct iwl3945_addsta_cmd;
+extern int iwl3945_send_add_station(struct iwl3945_priv *priv,
+                               struct iwl3945_addsta_cmd *sta, u8 flags);
+extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid,
+                         int is_ap, u8 flags);
+extern int iwl3945_is_network_packet(struct iwl3945_priv *priv,
+                                struct ieee80211_hdr *header);
+extern int iwl3945_power_init_handle(struct iwl3945_priv *priv);
+extern int iwl3945_eeprom_init(struct iwl3945_priv *priv);
+#ifdef CONFIG_IWL3945_DEBUG
+extern void iwl3945_report_frame(struct iwl3945_priv *priv,
+                            struct iwl3945_rx_packet *pkt,
+                            struct ieee80211_hdr *header, int group100);
+#else
+static inline void iwl3945_report_frame(struct iwl3945_priv *priv,
+                                   struct iwl3945_rx_packet *pkt,
+                                   struct ieee80211_hdr *header,
+                                   int group100) {}
+#endif
+extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv,
+                                          struct iwl3945_rx_mem_buffer *rxb,
+                                          void *data, short len,
+                                          struct ieee80211_rx_status *stats,
+                                          u16 phy_flags);
+extern int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv,
+                                      struct ieee80211_hdr *header);
+extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv);
+extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv,
+                              struct iwl3945_rx_queue *rxq);
+extern int iwl3945_calc_db_from_ratio(int sig_ratio);
+extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
+extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
+                            struct iwl3945_tx_queue *txq, int count, u32 id);
+extern void iwl3945_rx_replenish(void *data);
+extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
+extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len,
+                           const void *data);
+extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv,
+               struct iwl3945_host_cmd *cmd);
+extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
+                                       struct ieee80211_hdr *hdr,
+                                       const u8 *dest, int left);
+extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv,
+                                        struct iwl3945_rx_queue *q);
+extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv);
+extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
+                                  u32 decrypt_res,
+                                  struct ieee80211_rx_status *stats);
+extern const u8 iwl3945_broadcast_addr[ETH_ALEN];
+
+/*
+ * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
+ * call this... todo... fix that.
+*/
+extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id,
+                          u16 tx_rate, u8 flags);
+
+/******************************************************************************
+ *
+ * Functions implemented in iwl-[34]*.c which are forward declared here
+ * for use by iwl-base.c
+ *
+ * NOTE:  The implementation of these functions are hardware specific
+ * which is why they are in the hardware specific files (vs. iwl-base.c)
+ *
+ * Naming convention --
+ * iwl3945_         <-- Its part of iwlwifi (should be changed to iwl3945_)
+ * iwl3945_hw_      <-- Hardware specific (implemented in iwl-XXXX.c by all HW)
+ * iwlXXXX_     <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
+ * iwl3945_bg_      <-- Called from work queue context
+ * iwl3945_mac_     <-- mac80211 callback
+ *
+ ****************************************************************************/
+extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv);
+extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv);
+extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv);
+extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv);
+extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv);
+extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv);
+extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv);
+extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv);
+extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv);
+extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv);
+extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd,
+                                       dma_addr_t addr, u16 len);
+extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq);
+extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv);
+extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv,
+                               struct iwl3945_tx_queue *txq);
+extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
+                                struct iwl3945_frame *frame, u8 rate);
+extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv);
+extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
+                                    struct iwl3945_cmd *cmd,
+                                    struct ieee80211_tx_control *ctrl,
+                                    struct ieee80211_hdr *hdr,
+                                    int sta_id, int tx_id);
+extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv);
+extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power);
+extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv,
+                                struct iwl3945_rx_mem_buffer *rxb);
+extern void iwl3945_disable_events(struct iwl3945_priv *priv);
+extern int iwl4965_get_temperature(const struct iwl3945_priv *priv);
+
+/**
+ * iwl3945_hw_find_station - Find station id for a given BSSID
+ * @bssid: MAC address of station ID to find
+ *
+ * NOTE:  This should not be hardware specific but the code has
+ * not yet been merged into a single common layer for managing the
+ * station tables.
+ */
+extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid);
+
+extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel);
+
 /*
  * Forward declare iwl-3945.c functions for iwl-base.c
  */
-extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv);
-extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
-extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
-extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
-extern void iwl3945_bg_reg_txpower_periodic(struct work_struct *work);
-extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
+extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv);
+extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv);
+extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv);
+extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv);
+extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv);
+extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id,
                 u16 tx_rate, u8 flags);
+
+
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
+
+enum {
+       MEASUREMENT_READY = (1 << 0),
+       MEASUREMENT_ACTIVE = (1 << 1),
+};
+
+#endif
+
+struct iwl3945_priv {
+
+       /* ieee device used by generic ieee processing code */
+       struct ieee80211_hw *hw;
+       struct ieee80211_channel *ieee_channels;
+       struct ieee80211_rate *ieee_rates;
+
+       /* temporary frame storage list */
+       struct list_head free_frames;
+       int frames_count;
+
+       u8 phymode;
+       int alloc_rxb_skb;
+       bool add_radiotap;
+
+       void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
+                                      struct iwl3945_rx_mem_buffer *rxb);
+
+       const struct ieee80211_hw_mode *modes;
+
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
+       /* spectrum measurement report caching */
+       struct iwl3945_spectrum_notification measure_report;
+       u8 measurement_status;
+#endif
+       /* ucode beacon time */
+       u32 ucode_beacon_time;
+
+       /* we allocate array of iwl3945_channel_info for NIC's valid channels.
+        *    Access via channel # using indirect index array */
+       struct iwl3945_channel_info *channel_info;      /* channel info array */
+       u8 channel_count;       /* # of channels */
+
+       /* each calibration channel group in the EEPROM has a derived
+        * clip setting for each rate. */
+       const struct iwl3945_clip_group clip_groups[5];
+
+       /* thermal calibration */
+       s32 temperature;        /* degrees Kelvin */
+       s32 last_temperature;
+
+       /* Scan related variables */
+       unsigned long last_scan_jiffies;
+       unsigned long next_scan_jiffies;
+       unsigned long scan_start;
+       unsigned long scan_pass_start;
+       unsigned long scan_start_tsf;
+       int scan_bands;
+       int one_direct_scan;
+       u8 direct_ssid_len;
+       u8 direct_ssid[IW_ESSID_MAX_SIZE];
+       struct iwl3945_scan_cmd *scan;
+       u8 only_active_channel;
+
+       /* spinlock */
+       spinlock_t lock;        /* protect general shared data */
+       spinlock_t hcmd_lock;   /* protect hcmd */
+       struct mutex mutex;
+
+       /* basic pci-network driver stuff */
+       struct pci_dev *pci_dev;
+
+       /* pci hardware address support */
+       void __iomem *hw_base;
+
+       /* uCode images, save to reload in case of failure */
+       struct fw_desc ucode_code;      /* runtime inst */
+       struct fw_desc ucode_data;      /* runtime data original */
+       struct fw_desc ucode_data_backup;       /* runtime data save/restore */
+       struct fw_desc ucode_init;      /* initialization inst */
+       struct fw_desc ucode_init_data; /* initialization data */
+       struct fw_desc ucode_boot;      /* bootstrap inst */
+
+
+       struct iwl3945_rxon_time_cmd rxon_timing;
+
+       /* We declare this const so it can only be
+        * changed via explicit cast within the
+        * routines that actually update the physical
+        * hardware */
+       const struct iwl3945_rxon_cmd active_rxon;
+       struct iwl3945_rxon_cmd staging_rxon;
+
+       int error_recovering;
+       struct iwl3945_rxon_cmd recovery_rxon;
+
+       /* 1st responses from initialize and runtime uCode images.
+        * 4965's initialize alive response contains some calibration data. */
+       struct iwl3945_init_alive_resp card_alive_init;
+       struct iwl3945_alive_resp card_alive;
+
+#ifdef LED
+       /* LED related variables */
+       struct iwl3945_activity_blink activity;
+       unsigned long led_packets;
+       int led_state;
+#endif
+
+       u16 active_rate;
+       u16 active_rate_basic;
+
+       u8 call_post_assoc_from_beacon;
+       u8 assoc_station_added;
+       /* Rate scaling data */
+       s8 data_retry_limit;
+       u8 retry_rate;
+
+       wait_queue_head_t wait_command_queue;
+
+       int activity_timer_active;
+
+       /* Rx and Tx DMA processing queues */
+       struct iwl3945_rx_queue rxq;
+       struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES];
+
+       unsigned long status;
+       u32 config;
+
+       int last_rx_rssi;       /* From Rx packet statisitics */
+       int last_rx_noise;      /* From beacon statistics */
+
+       struct iwl3945_power_mgr power_data;
+
+       struct iwl3945_notif_statistics statistics;
+       unsigned long last_statistics_time;
+
+       /* context information */
+       u8 essid[IW_ESSID_MAX_SIZE];
+       u8 essid_len;
+       u16 rates_mask;
+
+       u32 power_mode;
+       u32 antenna;
+       u8 bssid[ETH_ALEN];
+       u16 rts_threshold;
+       u8 mac_addr[ETH_ALEN];
+
+       /*station table variables */
+       spinlock_t sta_lock;
+       int num_stations;
+       struct iwl3945_station_entry stations[IWL_STATION_COUNT];
+
+       /* Indication if ieee80211_ops->open has been called */
+       int is_open;
+
+       u8 mac80211_registered;
+       int is_abg;
+
+       u32 notif_missed_beacons;
+
+       /* Rx'd packet timing information */
+       u32 last_beacon_time;
+       u64 last_tsf;
+
+       /* Duplicate packet detection */
+       u16 last_seq_num;
+       u16 last_frag_num;
+       unsigned long last_packet_time;
+
+       /* Hash table for finding stations in IBSS network */
+       struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
+
+       /* eeprom */
+       struct iwl3945_eeprom eeprom;
+
+       int iw_mode;
+
+       struct sk_buff *ibss_beacon;
+
+       /* Last Rx'd beacon timestamp */
+       u32 timestamp0;
+       u32 timestamp1;
+       u16 beacon_int;
+       struct iwl3945_driver_hw_info hw_setting;
+       struct ieee80211_vif *vif;
+
+       /* Current association information needed to configure the
+        * hardware */
+       u16 assoc_id;
+       u16 assoc_capability;
+       u8 ps_mode;
+
+#ifdef CONFIG_IWL3945_QOS
+       struct iwl3945_qos_info qos_data;
+#endif /*CONFIG_IWL3945_QOS */
+
+       struct workqueue_struct *workqueue;
+
+       struct work_struct up;
+       struct work_struct restart;
+       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;
+       struct work_struct report_work;
+       struct work_struct request_scan;
+       struct work_struct beacon_update;
+
+       struct tasklet_struct irq_tasklet;
+
+       struct delayed_work init_alive_start;
+       struct delayed_work alive_start;
+       struct delayed_work activity_timer;
+       struct delayed_work thermal_periodic;
+       struct delayed_work gather_stats;
+       struct delayed_work scan_check;
+       struct delayed_work post_associate;
+
+#define IWL_DEFAULT_TX_POWER 0x0F
+       s8 user_txpower_limit;
+       s8 max_channel_txpower_limit;
+
+#ifdef CONFIG_PM
+       u32 pm_state[16];
+#endif
+
+#ifdef CONFIG_IWL3945_DEBUG
+       /* debugging info */
+       u32 framecnt_to_us;
+       atomic_t restrict_refcnt;
+#endif
+};                             /*iwl3945_priv */
+
+static inline int iwl3945_is_associated(struct iwl3945_priv *priv)
+{
+       return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+}
+
+static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info)
+{
+       if (ch_info == NULL)
+               return 0;
+       return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
+}
+
+static inline int is_channel_narrow(const struct iwl3945_channel_info *ch_info)
+{
+       return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0;
+}
+
+static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
+{
+       return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
+}
+
+static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
+{
+       return ch_info->phymode == MODE_IEEE80211A;
+}
+
+static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
+{
+       return ((ch_info->phymode == MODE_IEEE80211B) ||
+               (ch_info->phymode == MODE_IEEE80211G));
+}
+
+static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
+{
+       return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
+}
+
+static inline int is_channel_ibss(const struct iwl3945_channel_info *ch)
+{
+       return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
+}
+
+static inline int iwl3945_rate_index_from_plcp(int plcp)
+{
+       int i;
+
+       for (i = 0; i < IWL_RATE_COUNT; i++)
+               if (iwl3945_rates[i].plcp == plcp)
+                       return i;
+       return -1;
+}
+
+extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
+       const struct iwl3945_priv *priv, int phymode, u16 channel);
+
+/* Requires full declaration of iwl3945_priv before including */
+#include "iwl-3945-io.h"
+
 #endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
new file mode 100644 (file)
index 0000000..f3470c8
--- /dev/null
@@ -0,0 +1,2651 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ *
+ * 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.GPL.
+ *
+ * Contact Information:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
+ * 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 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.
+ *
+ *****************************************************************************/
+/*
+ * Please use this file (iwl-4965-commands.h) only for uCode API definitions.
+ * Please use iwl-4965-hw.h for hardware-related definitions.
+ * Please use iwl-4965.h for driver implementation definitions.
+ */
+
+#ifndef __iwl4965_commands_h__
+#define __iwl4965_commands_h__
+
+enum {
+       REPLY_ALIVE = 0x1,
+       REPLY_ERROR = 0x2,
+
+       /* RXON and QOS commands */
+       REPLY_RXON = 0x10,
+       REPLY_RXON_ASSOC = 0x11,
+       REPLY_QOS_PARAM = 0x13,
+       REPLY_RXON_TIMING = 0x14,
+
+       /* Multi-Station support */
+       REPLY_ADD_STA = 0x18,
+       REPLY_REMOVE_STA = 0x19,        /* not used */
+       REPLY_REMOVE_ALL_STA = 0x1a,    /* not used */
+
+       /* RX, TX, LEDs */
+       REPLY_TX = 0x1c,
+       REPLY_RATE_SCALE = 0x47,        /* 3945 only */
+       REPLY_LEDS_CMD = 0x48,
+       REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
+
+       /* 802.11h related */
+       RADAR_NOTIFICATION = 0x70,      /* not used */
+       REPLY_QUIET_CMD = 0x71,         /* not used */
+       REPLY_CHANNEL_SWITCH = 0x72,
+       CHANNEL_SWITCH_NOTIFICATION = 0x73,
+       REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
+       SPECTRUM_MEASURE_NOTIFICATION = 0x75,
+
+       /* Power Management */
+       POWER_TABLE_CMD = 0x77,
+       PM_SLEEP_NOTIFICATION = 0x7A,
+       PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
+
+       /* Scan commands and notifications */
+       REPLY_SCAN_CMD = 0x80,
+       REPLY_SCAN_ABORT_CMD = 0x81,
+       SCAN_START_NOTIFICATION = 0x82,
+       SCAN_RESULTS_NOTIFICATION = 0x83,
+       SCAN_COMPLETE_NOTIFICATION = 0x84,
+
+       /* IBSS/AP commands */
+       BEACON_NOTIFICATION = 0x90,
+       REPLY_TX_BEACON = 0x91,
+       WHO_IS_AWAKE_NOTIFICATION = 0x94,       /* not used */
+
+       /* Miscellaneous commands */
+       QUIET_NOTIFICATION = 0x96,              /* not used */
+       REPLY_TX_PWR_TABLE_CMD = 0x97,
+       MEASURE_ABORT_NOTIFICATION = 0x99,      /* not used */
+
+       /* Bluetooth device coexistance config command */
+       REPLY_BT_CONFIG = 0x9b,
+
+       /* Statistics */
+       REPLY_STATISTICS_CMD = 0x9c,
+       STATISTICS_NOTIFICATION = 0x9d,
+
+       /* RF-KILL commands and notifications */
+       REPLY_CARD_STATE_CMD = 0xa0,
+       CARD_STATE_NOTIFICATION = 0xa1,
+
+       /* Missed beacons notification */
+       MISSED_BEACONS_NOTIFICATION = 0xa2,
+
+       REPLY_CT_KILL_CONFIG_CMD = 0xa4,
+       SENSITIVITY_CMD = 0xa8,
+       REPLY_PHY_CALIBRATION_CMD = 0xb0,
+       REPLY_RX_PHY_CMD = 0xc0,
+       REPLY_RX_MPDU_CMD = 0xc1,
+       REPLY_4965_RX = 0xc3,
+       REPLY_COMPRESSED_BA = 0xc5,
+       REPLY_MAX = 0xff
+};
+
+/******************************************************************************
+ * (0)
+ * Commonly used structures and definitions:
+ * Command header, rate_n_flags, txpower
+ *
+ *****************************************************************************/
+
+/* iwl4965_cmd_header flags value */
+#define IWL_CMD_FAILED_MSK 0x40
+
+/**
+ * struct iwl4965_cmd_header
+ *
+ * This header format appears in the beginning of each command sent from the
+ * driver, and each response/notification received from uCode.
+ */
+struct iwl4965_cmd_header {
+       u8 cmd;         /* Command ID:  REPLY_RXON, etc. */
+       u8 flags;       /* IWL_CMD_* */
+       /*
+        * The driver sets up the sequence number to values of its chosing.
+        * uCode does not use this value, but passes it back to the driver
+        * when sending the response to each driver-originated command, so
+        * the driver can match the response to the command.  Since the values
+        * don't get used by uCode, the driver may set up an arbitrary format.
+        *
+        * There is one exception:  uCode sets bit 15 when it originates
+        * the response/notification, i.e. when the response/notification
+        * is not a direct response to a command sent by the driver.  For
+        * example, uCode issues REPLY_3945_RX when it sends a received frame
+        * to the driver; it is not a direct response to any driver command.
+        *
+        * The Linux driver uses the following format:
+        *
+        *  0:7    index/position within Tx queue
+        *  8:13   Tx queue selection
+        * 14:14   driver sets this to indicate command is in the 'huge'
+        *         storage at the end of the command buffers, i.e. scan cmd
+        * 15:15   uCode sets this in uCode-originated response/notification
+        */
+       __le16 sequence;
+
+       /* command or response/notification data follows immediately */
+       u8 data[0];
+} __attribute__ ((packed));
+
+/**
+ * 4965 rate_n_flags bit fields
+ *
+ * rate_n_flags format is used in following 4965 commands:
+ *  REPLY_4965_RX (response only)
+ *  REPLY_TX (both command and response)
+ *  REPLY_TX_LINK_QUALITY_CMD
+ *
+ * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"):
+ *  2-0:  0)   6 Mbps
+ *        1)  12 Mbps
+ *        2)  18 Mbps
+ *        3)  24 Mbps
+ *        4)  36 Mbps
+ *        5)  48 Mbps
+ *        6)  54 Mbps
+ *        7)  60 Mbps
+ *
+ *    3:  0)  Single stream (SISO)
+ *        1)  Dual stream (MIMO)
+ *
+ *    5:  Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data
+ *
+ * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"):
+ *  3-0:  0xD)   6 Mbps
+ *        0xF)   9 Mbps
+ *        0x5)  12 Mbps
+ *        0x7)  18 Mbps
+ *        0x9)  24 Mbps
+ *        0xB)  36 Mbps
+ *        0x1)  48 Mbps
+ *        0x3)  54 Mbps
+ *
+ * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"):
+ *  3-0:   10)  1 Mbps
+ *         20)  2 Mbps
+ *         55)  5.5 Mbps
+ *        110)  11 Mbps
+ */
+#define RATE_MCS_CODE_MSK 0x7
+#define RATE_MCS_MIMO_POS 3
+#define RATE_MCS_MIMO_MSK 0x8
+#define RATE_MCS_HT_DUP_POS 5
+#define RATE_MCS_HT_DUP_MSK 0x20
+
+/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */
+#define RATE_MCS_FLAGS_POS 8
+#define RATE_MCS_HT_POS 8
+#define RATE_MCS_HT_MSK 0x100
+
+/* Bit 9: (1) CCK, (0) OFDM.  HT (bit 8) must be "0" for this bit to be valid */
+#define RATE_MCS_CCK_POS 9
+#define RATE_MCS_CCK_MSK 0x200
+
+/* Bit 10: (1) Use Green Field preamble */
+#define RATE_MCS_GF_POS 10
+#define RATE_MCS_GF_MSK 0x400
+
+/* Bit 11: (1) Use 40Mhz FAT chnl width, (0) use 20 MHz legacy chnl width */
+#define RATE_MCS_FAT_POS 11
+#define RATE_MCS_FAT_MSK 0x800
+
+/* Bit 12: (1) Duplicate data on both 20MHz chnls.  FAT (bit 11) must be set. */
+#define RATE_MCS_DUP_POS 12
+#define RATE_MCS_DUP_MSK 0x1000
+
+/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */
+#define RATE_MCS_SGI_POS 13
+#define RATE_MCS_SGI_MSK 0x2000
+
+/**
+ * rate_n_flags Tx antenna masks (4965 has 2 transmitters):
+ * bit14:15 01 B inactive, A active
+ *          10 B active, A inactive
+ *          11 Both active
+ */
+#define RATE_MCS_ANT_A_POS     14
+#define RATE_MCS_ANT_B_POS     15
+#define RATE_MCS_ANT_A_MSK     0x4000
+#define RATE_MCS_ANT_B_MSK     0x8000
+#define RATE_MCS_ANT_AB_MSK    0xc000
+
+
+/**
+ * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD
+ *
+ * Scan uses only one transmitter, so only one analog/dsp gain pair is needed.
+ */
+struct iwl4965_tx_power {
+       u8 tx_gain;             /* gain for analog radio */
+       u8 dsp_atten;           /* gain for DSP */
+} __attribute__ ((packed));
+
+#define POWER_TABLE_NUM_ENTRIES                        33
+#define POWER_TABLE_NUM_HT_OFDM_ENTRIES                32
+#define POWER_TABLE_CCK_ENTRY                  32
+
+/**
+ * union iwl4965_tx_power_dual_stream
+ *
+ * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ * Use __le32 version (struct tx_power_dual_stream) when building command.
+ *
+ * Driver provides radio gain and DSP attenuation settings to device in pairs,
+ * one value for each transmitter chain.  The first value is for transmitter A,
+ * second for transmitter B.
+ *
+ * For SISO bit rates, both values in a pair should be identical.
+ * For MIMO rates, one value may be different from the other,
+ * in order to balance the Tx output between the two transmitters.
+ *
+ * See more details in doc for TXPOWER in iwl-4965-hw.h.
+ */
+union iwl4965_tx_power_dual_stream {
+       struct {
+               u8 radio_tx_gain[2];
+               u8 dsp_predis_atten[2];
+       } s;
+       u32 dw;
+};
+
+/**
+ * struct tx_power_dual_stream
+ *
+ * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ *
+ * Same format as iwl_tx_power_dual_stream, but __le32
+ */
+struct tx_power_dual_stream {
+       __le32 dw;
+} __attribute__ ((packed));
+
+/**
+ * struct iwl4965_tx_power_db
+ *
+ * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
+ */
+struct iwl4965_tx_power_db {
+       struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (0a)
+ * Alive and Error Commands & Responses:
+ *
+ *****************************************************************************/
+
+#define UCODE_VALID_OK __constant_cpu_to_le32(0x1)
+#define INITIALIZE_SUBTYPE    (9)
+
+/*
+ * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
+ *
+ * uCode issues this "initialize alive" notification once the initialization
+ * uCode image has completed its work, and is ready to load the runtime image.
+ * This is the *first* "alive" notification that the driver will receive after
+ * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
+ *
+ * See comments documenting "BSM" (bootstrap state machine).
+ *
+ * For 4965, this notification contains important calibration data for
+ * calculating txpower settings:
+ *
+ * 1)  Power supply voltage indication.  The voltage sensor outputs higher
+ *     values for lower voltage, and vice versa.
+ *
+ * 2)  Temperature measurement parameters, for each of two channel widths
+ *     (20 MHz and 40 MHz) supported by the radios.  Temperature sensing
+ *     is done via one of the receiver chains, and channel width influences
+ *     the results.
+ *
+ * 3)  Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation,
+ *     for each of 5 frequency ranges.
+ */
+struct iwl4965_init_alive_resp {
+       u8 ucode_minor;
+       u8 ucode_major;
+       __le16 reserved1;
+       u8 sw_rev[8];
+       u8 ver_type;
+       u8 ver_subtype;         /* "9" for initialize alive */
+       __le16 reserved2;
+       __le32 log_event_table_ptr;
+       __le32 error_event_table_ptr;
+       __le32 timestamp;
+       __le32 is_valid;
+
+       /* calibration values from "initialize" uCode */
+       __le32 voltage;         /* signed, higher value is lower voltage */
+       __le32 therm_r1[2];     /* signed, 1st for normal, 2nd for FAT channel*/
+       __le32 therm_r2[2];     /* signed */
+       __le32 therm_r3[2];     /* signed */
+       __le32 therm_r4[2];     /* signed */
+       __le32 tx_atten[5][2];  /* signed MIMO gain comp, 5 freq groups,
+                                * 2 Tx chains */
+} __attribute__ ((packed));
+
+
+/**
+ * REPLY_ALIVE = 0x1 (response only, not a command)
+ *
+ * uCode issues this "alive" notification once the runtime image is ready
+ * to receive commands from the driver.  This is the *second* "alive"
+ * notification that the driver will receive after rebooting uCode;
+ * this "alive" is indicated by subtype field != 9.
+ *
+ * See comments documenting "BSM" (bootstrap state machine).
+ *
+ * This response includes two pointers to structures within the device's
+ * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging:
+ *
+ * 1)  log_event_table_ptr indicates base of the event log.  This traces
+ *     a 256-entry history of uCode execution within a circular buffer.
+ *     Its header format is:
+ *
+ *     __le32 log_size;     log capacity (in number of entries)
+ *     __le32 type;         (1) timestamp with each entry, (0) no timestamp
+ *     __le32 wraps;        # times uCode has wrapped to top of circular buffer
+ *      __le32 write_index;  next circular buffer entry that uCode would fill
+ *
+ *     The header is followed by the circular buffer of log entries.  Entries
+ *     with timestamps have the following format:
+ *
+ *     __le32 event_id;     range 0 - 1500
+ *     __le32 timestamp;    low 32 bits of TSF (of network, if associated)
+ *     __le32 data;         event_id-specific data value
+ *
+ *     Entries without timestamps contain only event_id and data.
+ *
+ * 2)  error_event_table_ptr indicates base of the error log.  This contains
+ *     information about any uCode error that occurs.  For 4965, the format
+ *     of the error log is:
+ *
+ *     __le32 valid;        (nonzero) valid, (0) log is empty
+ *     __le32 error_id;     type of error
+ *     __le32 pc;           program counter
+ *     __le32 blink1;       branch link
+ *     __le32 blink2;       branch link
+ *     __le32 ilink1;       interrupt link
+ *     __le32 ilink2;       interrupt link
+ *     __le32 data1;        error-specific data
+ *     __le32 data2;        error-specific data
+ *     __le32 line;         source code line of error
+ *     __le32 bcon_time;    beacon timer
+ *     __le32 tsf_low;      network timestamp function timer
+ *     __le32 tsf_hi;       network timestamp function timer
+ *
+ * The Linux driver can print both logs to the system log when a uCode error
+ * occurs.
+ */
+struct iwl4965_alive_resp {
+       u8 ucode_minor;
+       u8 ucode_major;
+       __le16 reserved1;
+       u8 sw_rev[8];
+       u8 ver_type;
+       u8 ver_subtype;                 /* not "9" for runtime alive */
+       __le16 reserved2;
+       __le32 log_event_table_ptr;     /* SRAM address for event log */
+       __le32 error_event_table_ptr;   /* SRAM address for error log */
+       __le32 timestamp;
+       __le32 is_valid;
+} __attribute__ ((packed));
+
+
+union tsf {
+       u8 byte[8];
+       __le16 word[4];
+       __le32 dw[2];
+};
+
+/*
+ * REPLY_ERROR = 0x2 (response only, not a command)
+ */
+struct iwl4965_error_resp {
+       __le32 error_type;
+       u8 cmd_id;
+       u8 reserved1;
+       __le16 bad_cmd_seq_num;
+       __le32 error_info;
+       union tsf timestamp;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (1)
+ * RXON Commands & Responses:
+ *
+ *****************************************************************************/
+
+/*
+ * Rx config defines & structure
+ */
+/* rx_config device types  */
+enum {
+       RXON_DEV_TYPE_AP = 1,
+       RXON_DEV_TYPE_ESS = 3,
+       RXON_DEV_TYPE_IBSS = 4,
+       RXON_DEV_TYPE_SNIFFER = 6,
+};
+
+
+#define RXON_RX_CHAIN_DRIVER_FORCE_MSK         __constant_cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_VALID_MSK                        __constant_cpu_to_le16(0x7 << 1)
+#define RXON_RX_CHAIN_VALID_POS                        (1)
+#define RXON_RX_CHAIN_FORCE_SEL_MSK            __constant_cpu_to_le16(0x7 << 4)
+#define RXON_RX_CHAIN_FORCE_SEL_POS            (4)
+#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK       __constant_cpu_to_le16(0x7 << 7)
+#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS       (7)
+#define RXON_RX_CHAIN_CNT_MSK                  __constant_cpu_to_le16(0x3 << 10)
+#define RXON_RX_CHAIN_CNT_POS                  (10)
+#define RXON_RX_CHAIN_MIMO_CNT_MSK             __constant_cpu_to_le16(0x3 << 12)
+#define RXON_RX_CHAIN_MIMO_CNT_POS             (12)
+#define RXON_RX_CHAIN_MIMO_FORCE_MSK           __constant_cpu_to_le16(0x1 << 14)
+#define RXON_RX_CHAIN_MIMO_FORCE_POS           (14)
+
+/* rx_config flags */
+/* band & modulation selection */
+#define RXON_FLG_BAND_24G_MSK           __constant_cpu_to_le32(1 << 0)
+#define RXON_FLG_CCK_MSK                __constant_cpu_to_le32(1 << 1)
+/* auto detection enable */
+#define RXON_FLG_AUTO_DETECT_MSK        __constant_cpu_to_le32(1 << 2)
+/* TGg protection when tx */
+#define RXON_FLG_TGG_PROTECT_MSK        __constant_cpu_to_le32(1 << 3)
+/* cck short slot & preamble */
+#define RXON_FLG_SHORT_SLOT_MSK          __constant_cpu_to_le32(1 << 4)
+#define RXON_FLG_SHORT_PREAMBLE_MSK     __constant_cpu_to_le32(1 << 5)
+/* antenna selection */
+#define RXON_FLG_DIS_DIV_MSK            __constant_cpu_to_le32(1 << 7)
+#define RXON_FLG_ANT_SEL_MSK            __constant_cpu_to_le32(0x0f00)
+#define RXON_FLG_ANT_A_MSK              __constant_cpu_to_le32(1 << 8)
+#define RXON_FLG_ANT_B_MSK              __constant_cpu_to_le32(1 << 9)
+/* radar detection enable */
+#define RXON_FLG_RADAR_DETECT_MSK       __constant_cpu_to_le32(1 << 12)
+#define RXON_FLG_TGJ_NARROW_BAND_MSK    __constant_cpu_to_le32(1 << 13)
+/* rx response to host with 8-byte TSF
+* (according to ON_AIR deassertion) */
+#define RXON_FLG_TSF2HOST_MSK           __constant_cpu_to_le32(1 << 15)
+
+
+/* HT flags */
+#define RXON_FLG_CTRL_CHANNEL_LOC_POS          (22)
+#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK       __constant_cpu_to_le32(0x1 << 22)
+
+#define RXON_FLG_HT_OPERATING_MODE_POS         (23)
+
+#define RXON_FLG_HT_PROT_MSK                   __constant_cpu_to_le32(0x1 << 23)
+#define RXON_FLG_FAT_PROT_MSK                  __constant_cpu_to_le32(0x2 << 23)
+
+#define RXON_FLG_CHANNEL_MODE_POS              (25)
+#define RXON_FLG_CHANNEL_MODE_MSK              __constant_cpu_to_le32(0x3 << 25)
+#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK      __constant_cpu_to_le32(0x1 << 25)
+#define RXON_FLG_CHANNEL_MODE_MIXED_MSK                __constant_cpu_to_le32(0x2 << 25)
+
+/* rx_config filter flags */
+/* accept all data frames */
+#define RXON_FILTER_PROMISC_MSK         __constant_cpu_to_le32(1 << 0)
+/* pass control & management to host */
+#define RXON_FILTER_CTL2HOST_MSK        __constant_cpu_to_le32(1 << 1)
+/* accept multi-cast */
+#define RXON_FILTER_ACCEPT_GRP_MSK      __constant_cpu_to_le32(1 << 2)
+/* don't decrypt uni-cast frames */
+#define RXON_FILTER_DIS_DECRYPT_MSK     __constant_cpu_to_le32(1 << 3)
+/* don't decrypt multi-cast frames */
+#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4)
+/* STA is associated */
+#define RXON_FILTER_ASSOC_MSK           __constant_cpu_to_le32(1 << 5)
+/* transfer to host non bssid beacons in associated state */
+#define RXON_FILTER_BCON_AWARE_MSK      __constant_cpu_to_le32(1 << 6)
+
+/**
+ * REPLY_RXON = 0x10 (command, has simple generic response)
+ *
+ * RXON tunes the radio tuner to a service channel, and sets up a number
+ * of parameters that are used primarily for Rx, but also for Tx operations.
+ *
+ * NOTE:  When tuning to a new channel, driver must set the
+ *        RXON_FILTER_ASSOC_MSK to 0.  This will clear station-dependent
+ *        info within the device, including the station tables, tx retry
+ *        rate tables, and txpower tables.  Driver must build a new station
+ *        table and txpower table before transmitting anything on the RXON
+ *        channel.
+ *
+ * NOTE:  All RXONs wipe clean the internal txpower table.  Driver must
+ *        issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10),
+ *        regardless of whether RXON_FILTER_ASSOC_MSK is set.
+ */
+struct iwl4965_rxon_cmd {
+       u8 node_addr[6];
+       __le16 reserved1;
+       u8 bssid_addr[6];
+       __le16 reserved2;
+       u8 wlap_bssid_addr[6];
+       __le16 reserved3;
+       u8 dev_type;
+       u8 air_propagation;
+       __le16 rx_chain;
+       u8 ofdm_basic_rates;
+       u8 cck_basic_rates;
+       __le16 assoc_id;
+       __le32 flags;
+       __le32 filter_flags;
+       __le16 channel;
+       u8 ofdm_ht_single_stream_basic_rates;
+       u8 ofdm_ht_dual_stream_basic_rates;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
+ */
+struct iwl4965_rxon_assoc_cmd {
+       __le32 flags;
+       __le32 filter_flags;
+       u8 ofdm_basic_rates;
+       u8 cck_basic_rates;
+       u8 ofdm_ht_single_stream_basic_rates;
+       u8 ofdm_ht_dual_stream_basic_rates;
+       __le16 rx_chain_select_flags;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
+ */
+struct iwl4965_rxon_time_cmd {
+       union tsf timestamp;
+       __le16 beacon_interval;
+       __le16 atim_window;
+       __le32 beacon_init_val;
+       __le16 listen_interval;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
+ */
+struct iwl4965_channel_switch_cmd {
+       u8 band;
+       u8 expect_beacon;
+       __le16 channel;
+       __le32 rxon_flags;
+       __le32 rxon_filter_flags;
+       __le32 switch_time;
+       struct iwl4965_tx_power_db tx_power;
+} __attribute__ ((packed));
+
+/*
+ * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
+ */
+struct iwl4965_csa_notification {
+       __le16 band;
+       __le16 channel;
+       __le32 status;          /* 0 - OK, 1 - fail */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (2)
+ * Quality-of-Service (QOS) Commands & Responses:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM
+ * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd
+ *
+ * @cw_min: Contention window, start value in numbers of slots.
+ *          Should be a power-of-2, minus 1.  Device's default is 0x0f.
+ * @cw_max: Contention window, max value in numbers of slots.
+ *          Should be a power-of-2, minus 1.  Device's default is 0x3f.
+ * @aifsn:  Number of slots in Arbitration Interframe Space (before
+ *          performing random backoff timing prior to Tx).  Device default 1.
+ * @edca_txop:  Length of Tx opportunity, in uSecs.  Device default is 0.
+ *
+ * Device will automatically increase contention window by (2*CW) + 1 for each
+ * transmission retry.  Device uses cw_max as a bit mask, ANDed with new CW
+ * value, to cap the CW value.
+ */
+struct iwl4965_ac_qos {
+       __le16 cw_min;
+       __le16 cw_max;
+       u8 aifsn;
+       u8 reserved1;
+       __le16 edca_txop;
+} __attribute__ ((packed));
+
+/* QoS flags defines */
+#define QOS_PARAM_FLG_UPDATE_EDCA_MSK  __constant_cpu_to_le32(0x01)
+#define QOS_PARAM_FLG_TGN_MSK          __constant_cpu_to_le32(0x02)
+#define QOS_PARAM_FLG_TXOP_TYPE_MSK    __constant_cpu_to_le32(0x10)
+
+/* Number of Access Categories (AC) (EDCA), queues 0..3 */
+#define AC_NUM                4
+
+/*
+ * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
+ *
+ * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs
+ * 0: Background, 1: Best Effort, 2: Video, 3: Voice.
+ */
+struct iwl4965_qosparam_cmd {
+       __le32 qos_flags;
+       struct iwl4965_ac_qos ac[AC_NUM];
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (3)
+ * Add/Modify Stations Commands & Responses:
+ *
+ *****************************************************************************/
+/*
+ * Multi station support
+ */
+
+/* Special, dedicated locations within device's station table */
+#define        IWL_AP_ID               0
+#define IWL_MULTICAST_ID       1
+#define        IWL_STA_ID              2
+#define IWL4965_BROADCAST_ID   31
+#define        IWL4965_STATION_COUNT   32
+
+#define        IWL_STATION_COUNT       32      /* MAX(3945,4965)*/
+#define        IWL_INVALID_STATION     255
+
+#define STA_FLG_PWR_SAVE_MSK           __constant_cpu_to_le32(1 << 8);
+#define STA_FLG_RTS_MIMO_PROT_MSK      __constant_cpu_to_le32(1 << 17)
+#define STA_FLG_AGG_MPDU_8US_MSK       __constant_cpu_to_le32(1 << 18)
+#define STA_FLG_MAX_AGG_SIZE_POS       (19)
+#define STA_FLG_MAX_AGG_SIZE_MSK       __constant_cpu_to_le32(3 << 19)
+#define STA_FLG_FAT_EN_MSK             __constant_cpu_to_le32(1 << 21)
+#define STA_FLG_MIMO_DIS_MSK           __constant_cpu_to_le32(1 << 22)
+#define STA_FLG_AGG_MPDU_DENSITY_POS   (23)
+#define STA_FLG_AGG_MPDU_DENSITY_MSK   __constant_cpu_to_le32(7 << 23)
+
+/* Use in mode field.  1: modify existing entry, 0: add new station entry */
+#define STA_CONTROL_MODIFY_MSK         0x01
+
+/* key flags __le16*/
+#define STA_KEY_FLG_ENCRYPT_MSK        __constant_cpu_to_le16(0x7)
+#define STA_KEY_FLG_NO_ENC     __constant_cpu_to_le16(0x0)
+#define STA_KEY_FLG_WEP                __constant_cpu_to_le16(0x1)
+#define STA_KEY_FLG_CCMP       __constant_cpu_to_le16(0x2)
+#define STA_KEY_FLG_TKIP       __constant_cpu_to_le16(0x3)
+
+#define STA_KEY_FLG_KEYID_POS  8
+#define STA_KEY_FLG_INVALID    __constant_cpu_to_le16(0x0800)
+
+/* Flags indicate whether to modify vs. don't change various station params */
+#define        STA_MODIFY_KEY_MASK             0x01
+#define        STA_MODIFY_TID_DISABLE_TX       0x02
+#define        STA_MODIFY_TX_RATE_MSK          0x04
+#define STA_MODIFY_ADDBA_TID_MSK       0x08
+#define STA_MODIFY_DELBA_TID_MSK       0x10
+
+/* Receiver address (actually, Rx station's index into station table),
+ * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
+#define BUILD_RAxTID(sta_id, tid)      (((sta_id) << 4) + (tid))
+
+struct iwl4965_keyinfo {
+       __le16 key_flags;
+       u8 tkip_rx_tsc_byte2;   /* TSC[2] for key mix ph1 detection */
+       u8 reserved1;
+       __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
+       __le16 reserved2;
+       u8 key[16];             /* 16-byte unicast decryption key */
+} __attribute__ ((packed));
+
+/**
+ * struct sta_id_modify
+ * @addr[ETH_ALEN]: station's MAC address
+ * @sta_id: index of station in uCode's station table
+ * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change
+ *
+ * Driver selects unused table index when adding new station,
+ * or the index to a pre-existing station entry when modifying that station.
+ * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP).
+ *
+ * modify_mask flags select which parameters to modify vs. leave alone.
+ */
+struct sta_id_modify {
+       u8 addr[ETH_ALEN];
+       __le16 reserved1;
+       u8 sta_id;
+       u8 modify_mask;
+       __le16 reserved2;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_ADD_STA = 0x18 (command)
+ *
+ * The device contains an internal table of per-station information,
+ * with info on security keys, aggregation parameters, and Tx rates for
+ * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD,
+ * 3945 uses REPLY_RATE_SCALE to set up rate tables).
+ *
+ * REPLY_ADD_STA sets up the table entry for one station, either creating
+ * a new entry, or modifying a pre-existing one.
+ *
+ * NOTE:  RXON command (without "associated" bit set) wipes the station table
+ *        clean.  Moving into RF_KILL state does this also.  Driver must set up
+ *        new station table before transmitting anything on the RXON channel
+ *        (except active scans or active measurements; those commands carry
+ *        their own txpower/rate setup data).
+ *
+ *        When getting started on a new channel, driver must set up the
+ *        IWL_BROADCAST_ID entry (last entry in the table).  For a client
+ *        station in a BSS, once an AP is selected, driver sets up the AP STA
+ *        in the IWL_AP_ID entry (1st entry in the table).  BROADCAST and AP
+ *        are all that are needed for a BSS client station.  If the device is
+ *        used as AP, or in an IBSS network, driver must set up station table
+ *        entries for all STAs in network, starting with index IWL_STA_ID.
+ */
+struct iwl4965_addsta_cmd {
+       u8 mode;                /* 1: modify existing, 0: add new station */
+       u8 reserved[3];
+       struct sta_id_modify sta;
+       struct iwl4965_keyinfo key;
+       __le32 station_flags;           /* STA_FLG_* */
+       __le32 station_flags_msk;       /* STA_FLG_* */
+
+       /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
+        * corresponding to bit (e.g. bit 5 controls TID 5).
+        * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
+       __le16 tid_disable_tx;
+
+       __le16  reserved1;
+
+       /* TID for which to add block-ack support.
+        * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+       u8 add_immediate_ba_tid;
+
+       /* TID for which to remove block-ack support.
+        * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
+       u8 remove_immediate_ba_tid;
+
+       /* Starting Sequence Number for added block-ack support.
+        * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
+       __le16 add_immediate_ba_ssn;
+
+       __le32 reserved2;
+} __attribute__ ((packed));
+
+#define ADD_STA_SUCCESS_MSK            0x1
+#define ADD_STA_NO_ROOM_IN_TABLE       0x2
+#define ADD_STA_NO_BLOCK_ACK_RESOURCE  0x4
+#define ADD_STA_MODIFY_NON_EXIST_STA   0x8
+/*
+ * REPLY_ADD_STA = 0x18 (response)
+ */
+struct iwl4965_add_sta_resp {
+       u8 status;      /* ADD_STA_* */
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (4)
+ * Rx Responses:
+ *
+ *****************************************************************************/
+
+struct iwl4965_rx_frame_stats {
+       u8 phy_count;
+       u8 id;
+       u8 rssi;
+       u8 agc;
+       __le16 sig_avg;
+       __le16 noise_diff;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct iwl4965_rx_frame_hdr {
+       __le16 channel;
+       __le16 phy_flags;
+       u8 reserved1;
+       u8 rate;
+       __le16 len;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+#define        RX_RES_STATUS_NO_CRC32_ERROR    __constant_cpu_to_le32(1 << 0)
+#define        RX_RES_STATUS_NO_RXE_OVERFLOW   __constant_cpu_to_le32(1 << 1)
+
+#define        RX_RES_PHY_FLAGS_BAND_24_MSK    __constant_cpu_to_le16(1 << 0)
+#define        RX_RES_PHY_FLAGS_MOD_CCK_MSK            __constant_cpu_to_le16(1 << 1)
+#define        RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK     __constant_cpu_to_le16(1 << 2)
+#define        RX_RES_PHY_FLAGS_NARROW_BAND_MSK        __constant_cpu_to_le16(1 << 3)
+#define        RX_RES_PHY_FLAGS_ANTENNA_MSK            __constant_cpu_to_le16(0xf0)
+
+#define        RX_RES_STATUS_SEC_TYPE_MSK      (0x7 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_NONE     (0x0 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_WEP      (0x1 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_CCMP     (0x2 << 8)
+#define        RX_RES_STATUS_SEC_TYPE_TKIP     (0x3 << 8)
+
+#define        RX_RES_STATUS_DECRYPT_TYPE_MSK  (0x3 << 11)
+#define        RX_RES_STATUS_NOT_DECRYPT       (0x0 << 11)
+#define        RX_RES_STATUS_DECRYPT_OK        (0x3 << 11)
+#define        RX_RES_STATUS_BAD_ICV_MIC       (0x1 << 11)
+#define        RX_RES_STATUS_BAD_KEY_TTAK      (0x2 << 11)
+
+struct iwl4965_rx_frame_end {
+       __le32 status;
+       __le64 timestamp;
+       __le32 beacon_timestamp;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_3945_RX = 0x1b (response only, not a command)
+ *
+ * NOTE:  DO NOT dereference from casts to this structure
+ * It is provided only for calculating minimum data set size.
+ * The actual offsets of the hdr and end are dynamic based on
+ * stats.phy_count
+ */
+struct iwl4965_rx_frame {
+       struct iwl4965_rx_frame_stats stats;
+       struct iwl4965_rx_frame_hdr hdr;
+       struct iwl4965_rx_frame_end end;
+} __attribute__ ((packed));
+
+/* Fixed (non-configurable) rx data from phy */
+#define RX_PHY_FLAGS_ANTENNAE_OFFSET           (4)
+#define RX_PHY_FLAGS_ANTENNAE_MASK             (0x70)
+#define IWL_AGC_DB_MASK        (0x3f80)        /* MASK(7,13) */
+#define IWL_AGC_DB_POS         (7)
+struct iwl4965_rx_non_cfg_phy {
+       __le16 ant_selection;   /* ant A bit 4, ant B bit 5, ant C bit 6 */
+       __le16 agc_info;        /* agc code 0:6, agc dB 7:13, reserved 14:15 */
+       u8 rssi_info[6];        /* we use even entries, 0/2/4 for A/B/C rssi */
+       u8 pad[0];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_4965_RX = 0xc3 (response only, not a command)
+ * Used only for legacy (non 11n) frames.
+ */
+#define RX_RES_PHY_CNT 14
+struct iwl4965_rx_phy_res {
+       u8 non_cfg_phy_cnt;     /* non configurable DSP phy data byte count */
+       u8 cfg_phy_cnt;         /* configurable DSP phy data byte count */
+       u8 stat_id;             /* configurable DSP phy data set ID */
+       u8 reserved1;
+       __le64 timestamp;       /* TSF at on air rise */
+       __le32 beacon_time_stamp; /* beacon at on-air rise */
+       __le16 phy_flags;       /* general phy flags: band, modulation, ... */
+       __le16 channel;         /* channel number */
+       __le16 non_cfg_phy[RX_RES_PHY_CNT];     /* upto 14 phy entries */
+       __le32 reserved2;
+       __le32 rate_n_flags;    /* RATE_MCS_* */
+       __le16 byte_count;      /* frame's byte-count */
+       __le16 reserved3;
+} __attribute__ ((packed));
+
+struct iwl4965_rx_mpdu_res_start {
+       __le16 byte_count;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (5)
+ * Tx Commands & Responses:
+ *
+ * Driver must place each REPLY_TX command into one of the prioritized Tx
+ * queues in host DRAM, shared between driver and device (see comments for
+ * SCD registers and Tx/Rx Queues).  When the device's Tx scheduler and uCode
+ * are preparing to transmit, the device pulls the Tx command over the PCI
+ * bus via one of the device's Tx DMA channels, to fill an internal FIFO
+ * from which data will be transmitted.
+ *
+ * uCode handles all timing and protocol related to control frames
+ * (RTS/CTS/ACK), based on flags in the Tx command.  uCode and Tx scheduler
+ * handle reception of block-acks; uCode updates the host driver via
+ * REPLY_COMPRESSED_BA (4965).
+ *
+ * uCode handles retrying Tx when an ACK is expected but not received.
+ * This includes trying lower data rates than the one requested in the Tx
+ * command, as set up by the REPLY_RATE_SCALE (for 3945) or
+ * REPLY_TX_LINK_QUALITY_CMD (4965).
+ *
+ * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
+ * This command must be executed after every RXON command, before Tx can occur.
+ *****************************************************************************/
+
+/* REPLY_TX Tx flags field */
+
+/* 1: Use Request-To-Send protocol before this frame.
+ * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
+#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1)
+
+/* 1: Transmit Clear-To-Send to self before this frame.
+ * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
+ * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
+#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2)
+
+/* 1: Expect ACK from receiving station
+ * 0: Don't expect ACK (MAC header's duration field s/b 0)
+ * Set this for unicast frames, but not broadcast/multicast. */
+#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3)
+
+/* For 4965:
+ * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
+ *    Tx command's initial_rate_index indicates first rate to try;
+ *    uCode walks through table for additional Tx attempts.
+ * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
+ *    This rate will be used for all Tx attempts; it will not be scaled. */
+#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4)
+
+/* 1: Expect immediate block-ack.
+ * Set when Txing a block-ack request frame.  Also set TX_CMD_FLG_ACK_MSK. */
+#define TX_CMD_FLG_IMM_BA_RSP_MASK  __constant_cpu_to_le32(1 << 6)
+
+/* 1: Frame requires full Tx-Op protection.
+ * Set this if either RTS or CTS Tx Flag gets set. */
+#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7)
+
+/* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
+ * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
+#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00)
+#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8)
+#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9)
+
+/* 1: Ignore Bluetooth priority for this frame.
+ * 0: Delay Tx until Bluetooth device is done (normal usage). */
+#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12)
+
+/* 1: uCode overrides sequence control field in MAC header.
+ * 0: Driver provides sequence control field in MAC header.
+ * Set this for management frames, non-QOS data frames, non-unicast frames,
+ * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
+#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13)
+
+/* 1: This frame is non-last MPDU; more fragments are coming.
+ * 0: Last fragment, or not using fragmentation. */
+#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14)
+
+/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
+ * 0: No TSF required in outgoing frame.
+ * Set this for transmitting beacons and probe responses. */
+#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16)
+
+/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
+ *    alignment of frame's payload data field.
+ * 0: No pad
+ * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
+ * field (but not both).  Driver must align frame data (i.e. data following
+ * MAC header) to DWORD boundary. */
+#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20)
+
+/* HCCA-AP - disable duration overwriting. */
+#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25)
+
+
+/*
+ * TX command security control
+ */
+#define TX_CMD_SEC_WEP         0x01
+#define TX_CMD_SEC_CCM         0x02
+#define TX_CMD_SEC_TKIP                0x03
+#define TX_CMD_SEC_MSK         0x03
+#define TX_CMD_SEC_SHIFT       6
+#define TX_CMD_SEC_KEY128      0x08
+
+/*
+ * 4965 uCode updates these Tx attempt count values in host DRAM.
+ * Used for managing Tx retries when expecting block-acks.
+ * Driver should set these fields to 0.
+ */
+struct iwl4965_dram_scratch {
+       u8 try_cnt;             /* Tx attempts */
+       u8 bt_kill_cnt;         /* Tx attempts blocked by Bluetooth device */
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX = 0x1c (command)
+ */
+struct iwl4965_tx_cmd {
+       /*
+        * MPDU byte count:
+        * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
+        * + 8 byte IV for CCM or TKIP (not used for WEP)
+        * + Data payload
+        * + 8-byte MIC (not used for CCM/WEP)
+        * NOTE:  Does not include Tx command bytes, post-MAC pad bytes,
+        *        MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
+        * Range: 14-2342 bytes.
+        */
+       __le16 len;
+
+       /*
+        * MPDU or MSDU byte count for next frame.
+        * Used for fragmentation and bursting, but not 11n aggregation.
+        * Same as "len", but for next frame.  Set to 0 if not applicable.
+        */
+       __le16 next_frame_len;
+
+       __le32 tx_flags;        /* TX_CMD_FLG_* */
+
+       /* 4965's uCode may modify this field of the Tx command (in host DRAM!).
+        * Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */
+       struct iwl4965_dram_scratch scratch;
+
+       /* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */
+       __le32 rate_n_flags;    /* RATE_MCS_* */
+
+       /* Index of destination station in uCode's station table */
+       u8 sta_id;
+
+       /* Type of security encryption:  CCM or TKIP */
+       u8 sec_ctl;             /* TX_CMD_SEC_* */
+
+       /*
+        * Index into rate table (see REPLY_TX_LINK_QUALITY_CMD) for initial
+        * Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set.  Normally "0" for
+        * data frames, this field may be used to selectively reduce initial
+        * rate (via non-0 value) for special frames (e.g. management), while
+        * still supporting rate scaling for all frames.
+        */
+       u8 initial_rate_index;
+       u8 reserved;
+       u8 key[16];
+       __le16 next_frame_flags;
+       __le16 reserved2;
+       union {
+               __le32 life_time;
+               __le32 attempt;
+       } stop_time;
+
+       /* Host DRAM physical address pointer to "scratch" in this command.
+        * Must be dword aligned.  "0" in dram_lsb_ptr disables usage. */
+       __le32 dram_lsb_ptr;
+       u8 dram_msb_ptr;
+
+       u8 rts_retry_limit;     /*byte 50 */
+       u8 data_retry_limit;    /*byte 51 */
+       u8 tid_tspec;
+       union {
+               __le16 pm_frame_timeout;
+               __le16 attempt_duration;
+       } timeout;
+
+       /*
+        * Duration of EDCA burst Tx Opportunity, in 32-usec units.
+        * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
+        */
+       __le16 driver_txop;
+
+       /*
+        * MAC header goes here, followed by 2 bytes padding if MAC header
+        * length is 26 or 30 bytes, followed by payload data
+        */
+       u8 payload[0];
+       struct ieee80211_hdr hdr[0];
+} __attribute__ ((packed));
+
+/* TX command response is sent after *all* transmission attempts.
+ *
+ * NOTES:
+ *
+ * TX_STATUS_FAIL_NEXT_FRAG
+ *
+ * If the fragment flag in the MAC header for the frame being transmitted
+ * is set and there is insufficient time to transmit the next frame, the
+ * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
+ *
+ * TX_STATUS_FIFO_UNDERRUN
+ *
+ * Indicates the host did not provide bytes to the FIFO fast enough while
+ * a TX was in progress.
+ *
+ * TX_STATUS_FAIL_MGMNT_ABORT
+ *
+ * This status is only possible if the ABORT ON MGMT RX parameter was
+ * set to true with the TX command.
+ *
+ * If the MSB of the status parameter is set then an abort sequence is
+ * required.  This sequence consists of the host activating the TX Abort
+ * control line, and then waiting for the TX Abort command response.  This
+ * indicates that a the device is no longer in a transmit state, and that the
+ * command FIFO has been cleared.  The host must then deactivate the TX Abort
+ * control line.  Receiving is still allowed in this case.
+ */
+enum {
+       TX_STATUS_SUCCESS = 0x01,
+       TX_STATUS_DIRECT_DONE = 0x02,
+       TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
+       TX_STATUS_FAIL_LONG_LIMIT = 0x83,
+       TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
+       TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
+       TX_STATUS_FAIL_NEXT_FRAG = 0x86,
+       TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
+       TX_STATUS_FAIL_DEST_PS = 0x88,
+       TX_STATUS_FAIL_ABORTED = 0x89,
+       TX_STATUS_FAIL_BT_RETRY = 0x8a,
+       TX_STATUS_FAIL_STA_INVALID = 0x8b,
+       TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
+       TX_STATUS_FAIL_TID_DISABLE = 0x8d,
+       TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
+       TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
+       TX_STATUS_FAIL_TX_LOCKED = 0x90,
+       TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
+};
+
+#define        TX_PACKET_MODE_REGULAR          0x0000
+#define        TX_PACKET_MODE_BURST_SEQ        0x0100
+#define        TX_PACKET_MODE_BURST_FIRST      0x0200
+
+enum {
+       TX_POWER_PA_NOT_ACTIVE = 0x0,
+};
+
+enum {
+       TX_STATUS_MSK = 0x000000ff,     /* bits 0:7 */
+       TX_STATUS_DELAY_MSK = 0x00000040,
+       TX_STATUS_ABORT_MSK = 0x00000080,
+       TX_PACKET_MODE_MSK = 0x0000ff00,        /* bits 8:15 */
+       TX_FIFO_NUMBER_MSK = 0x00070000,        /* bits 16:18 */
+       TX_RESERVED = 0x00780000,       /* bits 19:22 */
+       TX_POWER_PA_DETECT_MSK = 0x7f800000,    /* bits 23:30 */
+       TX_ABORT_REQUIRED_MSK = 0x80000000,     /* bits 31:31 */
+};
+
+/* *******************************
+ * TX aggregation status
+ ******************************* */
+
+enum {
+       AGG_TX_STATE_TRANSMITTED = 0x00,
+       AGG_TX_STATE_UNDERRUN_MSK = 0x01,
+       AGG_TX_STATE_BT_PRIO_MSK = 0x02,
+       AGG_TX_STATE_FEW_BYTES_MSK = 0x04,
+       AGG_TX_STATE_ABORT_MSK = 0x08,
+       AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10,
+       AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20,
+       AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40,
+       AGG_TX_STATE_SCD_QUERY_MSK = 0x80,
+       AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100,
+       AGG_TX_STATE_RESPONSE_MSK = 0x1ff,
+       AGG_TX_STATE_DUMP_TX_MSK = 0x200,
+       AGG_TX_STATE_DELAY_TX_MSK = 0x400
+};
+
+#define AGG_TX_STATE_LAST_SENT_MSK \
+(AGG_TX_STATE_LAST_SENT_TTL_MSK | \
+ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
+ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
+
+/* # tx attempts for first frame in aggregation */
+#define AGG_TX_STATE_TRY_CNT_POS 12
+#define AGG_TX_STATE_TRY_CNT_MSK 0xf000
+
+/* Command ID and sequence number of Tx command for this frame */
+#define AGG_TX_STATE_SEQ_NUM_POS 16
+#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000
+
+/*
+ * REPLY_TX = 0x1c (response)
+ *
+ * This response may be in one of two slightly different formats, indicated
+ * by the frame_count field:
+ *
+ * 1)  No aggregation (frame_count == 1).  This reports Tx results for
+ *     a single frame.  Multiple attempts, at various bit rates, may have
+ *     been made for this frame.
+ *
+ * 2)  Aggregation (frame_count > 1).  This reports Tx results for
+ *     2 or more frames that used block-acknowledge.  All frames were
+ *     transmitted at same rate.  Rate scaling may have been used if first
+ *     frame in this new agg block failed in previous agg block(s).
+ *
+ *     Note that, for aggregation, ACK (block-ack) status is not delivered here;
+ *     block-ack has not been received by the time the 4965 records this status.
+ *     This status relates to reasons the tx might have been blocked or aborted
+ *     within the sending station (this 4965), rather than whether it was
+ *     received successfully by the destination station.
+ */
+struct iwl4965_tx_resp {
+       u8 frame_count;         /* 1 no aggregation, >1 aggregation */
+       u8 bt_kill_count;       /* # blocked by bluetooth (unused for agg) */
+       u8 failure_rts;         /* # failures due to unsuccessful RTS */
+       u8 failure_frame;       /* # failures due to no ACK (unused for agg) */
+
+       /* For non-agg:  Rate at which frame was successful.
+        * For agg:  Rate at which all frames were transmitted. */
+       __le32 rate_n_flags;    /* RATE_MCS_*  */
+
+       /* For non-agg:  RTS + CTS + frame tx attempts time + ACK.
+        * For agg:  RTS + CTS + aggregation tx time + block-ack time. */
+       __le16 wireless_media_time;     /* uSecs */
+
+       __le16 reserved;
+       __le32 pa_power1;       /* RF power amplifier measurement (not used) */
+       __le32 pa_power2;
+
+       /*
+        * For non-agg:  frame status TX_STATUS_*
+        * For agg:  status of 1st frame, AGG_TX_STATE_*; other frame status
+        *           fields follow this one, up to frame_count.
+        *           Bit fields:
+        *           11- 0:  AGG_TX_STATE_* status code
+        *           15-12:  Retry count for 1st frame in aggregation (retries
+        *                   occur if tx failed for this frame when it was a
+        *                   member of a previous aggregation block).  If rate
+        *                   scaling is used, retry count indicates the rate
+        *                   table entry used for all frames in the new agg.
+        *           31-16:  Sequence # for this frame's Tx cmd (not SSN!)
+        */
+       __le32 status;  /* TX status (for aggregation status of 1st frame) */
+} __attribute__ ((packed));
+
+/*
+ * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command)
+ *
+ * Reports Block-Acknowledge from recipient station
+ */
+struct iwl4965_compressed_ba_resp {
+       __le32 sta_addr_lo32;
+       __le16 sta_addr_hi16;
+       __le16 reserved;
+
+       /* Index of recipient (BA-sending) station in uCode's station table */
+       u8 sta_id;
+       u8 tid;
+       __le16 ba_seq_ctl;
+       __le32 ba_bitmap0;
+       __le32 ba_bitmap1;
+       __le16 scd_flow;
+       __le16 scd_ssn;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
+ *
+ * See details under "TXPOWER" in iwl-4965-hw.h.
+ */
+struct iwl4965_txpowertable_cmd {
+       u8 band;                /* 0: 5 GHz, 1: 2.4 GHz */
+       u8 reserved;
+       __le16 channel;
+       struct iwl4965_tx_power_db tx_power;
+} __attribute__ ((packed));
+
+/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
+#define  LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK   (1 << 0)
+
+/* # of EDCA prioritized tx fifos */
+#define  LINK_QUAL_AC_NUM AC_NUM
+
+/* # entries in rate scale table to support Tx retries */
+#define  LINK_QUAL_MAX_RETRY_NUM 16
+
+/* Tx antenna selection values */
+#define  LINK_QUAL_ANT_A_MSK (1 << 0)
+#define  LINK_QUAL_ANT_B_MSK (1 << 1)
+#define  LINK_QUAL_ANT_MSK   (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK)
+
+
+/**
+ * struct iwl4965_link_qual_general_params
+ *
+ * Used in REPLY_TX_LINK_QUALITY_CMD
+ */
+struct iwl4965_link_qual_general_params {
+       u8 flags;
+
+       /* No entries at or above this (driver chosen) index contain MIMO */
+       u8 mimo_delimiter;
+
+       /* Best single antenna to use for single stream (legacy, SISO). */
+       u8 single_stream_ant_msk;       /* LINK_QUAL_ANT_* */
+
+       /* Best antennas to use for MIMO (unused for 4965, assumes both). */
+       u8 dual_stream_ant_msk;         /* LINK_QUAL_ANT_* */
+
+       /*
+        * If driver needs to use different initial rates for different
+        * EDCA QOS access categories (as implemented by tx fifos 0-3),
+        * this table will set that up, by indicating the indexes in the
+        * rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start.
+        * Otherwise, driver should set all entries to 0.
+        *
+        * Entry usage:
+        * 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice
+        * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3.
+        */
+       u8 start_rate_index[LINK_QUAL_AC_NUM];
+} __attribute__ ((packed));
+
+/**
+ * struct iwl4965_link_qual_agg_params
+ *
+ * Used in REPLY_TX_LINK_QUALITY_CMD
+ */
+struct iwl4965_link_qual_agg_params {
+
+       /* Maximum number of uSec in aggregation.
+        * Driver should set this to 4000 (4 milliseconds). */
+       __le16 agg_time_limit;
+
+       /*
+        * Number of Tx retries allowed for a frame, before that frame will
+        * no longer be considered for the start of an aggregation sequence
+        * (scheduler will then try to tx it as single frame).
+        * Driver should set this to 3.
+        */
+       u8 agg_dis_start_th;
+
+       /*
+        * Maximum number of frames in aggregation.
+        * 0 = no limit (default).  1 = no aggregation.
+        * Other values = max # frames in aggregation.
+        */
+       u8 agg_frame_cnt_limit;
+
+       __le32 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response)
+ *
+ * For 4965 only; 3945 uses REPLY_RATE_SCALE.
+ *
+ * Each station in the 4965's internal station table has its own table of 16
+ * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when
+ * an ACK is not received.  This command replaces the entire table for
+ * one station.
+ *
+ * NOTE:  Station must already be in 4965's station table.  Use REPLY_ADD_STA.
+ *
+ * The rate scaling procedures described below work well.  Of course, other
+ * procedures are possible, and may work better for particular environments.
+ *
+ *
+ * FILLING THE RATE TABLE
+ *
+ * Given a particular initial rate and mode, as determined by the rate
+ * scaling algorithm described below, the Linux driver uses the following
+ * formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the
+ * Link Quality command:
+ *
+ *
+ * 1)  If using High-throughput (HT) (SISO or MIMO) initial rate:
+ *     a) Use this same initial rate for first 3 entries.
+ *     b) Find next lower available rate using same mode (SISO or MIMO),
+ *        use for next 3 entries.  If no lower rate available, switch to
+ *        legacy mode (no FAT channel, no MIMO, no short guard interval).
+ *     c) If using MIMO, set command's mimo_delimiter to number of entries
+ *        using MIMO (3 or 6).
+ *     d) After trying 2 HT rates, switch to legacy mode (no FAT channel,
+ *        no MIMO, no short guard interval), at the next lower bit rate
+ *        (e.g. if second HT bit rate was 54, try 48 legacy), and follow
+ *        legacy procedure for remaining table entries.
+ *
+ * 2)  If using legacy initial rate:
+ *     a) Use the initial rate for only one entry.
+ *     b) For each following entry, reduce the rate to next lower available
+ *        rate, until reaching the lowest available rate.
+ *     c) When reducing rate, also switch antenna selection.
+ *     d) Once lowest available rate is reached, repeat this rate until
+ *        rate table is filled (16 entries), switching antenna each entry.
+ *
+ *
+ * ACCUMULATING HISTORY
+ *
+ * The rate scaling algorithm for 4965, as implemented in Linux driver, uses
+ * two sets of frame Tx success history:  One for the current/active modulation
+ * mode, and one for a speculative/search mode that is being attempted.  If the
+ * speculative mode turns out to be more effective (i.e. actual transfer
+ * rate is better), then the driver continues to use the speculative mode
+ * as the new current active mode.
+ *
+ * Each history set contains, separately for each possible rate, data for a
+ * sliding window of the 62 most recent tx attempts at that rate.  The data
+ * includes a shifting bitmap of success(1)/failure(0), and sums of successful
+ * and attempted frames, from which the driver can additionally calculate a
+ * success ratio (success / attempted) and number of failures
+ * (attempted - success), and control the size of the window (attempted).
+ * The driver uses the bit map to remove successes from the success sum, as
+ * the oldest tx attempts fall out of the window.
+ *
+ * When the 4965 makes multiple tx attempts for a given frame, each attempt
+ * might be at a different rate, and have different modulation characteristics
+ * (e.g. antenna, fat channel, short guard interval), as set up in the rate
+ * scaling table in the Link Quality command.  The driver must determine
+ * which rate table entry was used for each tx attempt, to determine which
+ * rate-specific history to update, and record only those attempts that
+ * match the modulation characteristics of the history set.
+ *
+ * When using block-ack (aggregation), all frames are transmitted at the same
+ * rate, since there is no per-attempt acknowledgement from the destination
+ * station.  The Tx response struct iwl_tx_resp indicates the Tx rate in
+ * rate_n_flags field.  After receiving a block-ack, the driver can update
+ * history for the entire block all at once.
+ *
+ *
+ * FINDING BEST STARTING RATE:
+ *
+ * When working with a selected initial modulation mode (see below), the
+ * driver attempts to find a best initial rate.  The initial rate is the
+ * first entry in the Link Quality command's rate table.
+ *
+ * 1)  Calculate actual throughput (success ratio * expected throughput, see
+ *     table below) for current initial rate.  Do this only if enough frames
+ *     have been attempted to make the value meaningful:  at least 6 failed
+ *     tx attempts, or at least 8 successes.  If not enough, don't try rate
+ *     scaling yet.
+ *
+ * 2)  Find available rates adjacent to current initial rate.  Available means:
+ *     a)  supported by hardware &&
+ *     b)  supported by association &&
+ *     c)  within any constraints selected by user
+ *
+ * 3)  Gather measured throughputs for adjacent rates.  These might not have
+ *     enough history to calculate a throughput.  That's okay, we might try
+ *     using one of them anyway!
+ *
+ * 4)  Try decreasing rate if, for current rate:
+ *     a)  success ratio is < 15% ||
+ *     b)  lower adjacent rate has better measured throughput ||
+ *     c)  higher adjacent rate has worse throughput, and lower is unmeasured
+ *
+ *     As a sanity check, if decrease was determined above, leave rate
+ *     unchanged if:
+ *     a)  lower rate unavailable
+ *     b)  success ratio at current rate > 85% (very good)
+ *     c)  current measured throughput is better than expected throughput
+ *         of lower rate (under perfect 100% tx conditions, see table below)
+ *
+ * 5)  Try increasing rate if, for current rate:
+ *     a)  success ratio is < 15% ||
+ *     b)  both adjacent rates' throughputs are unmeasured (try it!) ||
+ *     b)  higher adjacent rate has better measured throughput ||
+ *     c)  lower adjacent rate has worse throughput, and higher is unmeasured
+ *
+ *     As a sanity check, if increase was determined above, leave rate
+ *     unchanged if:
+ *     a)  success ratio at current rate < 70%.  This is not particularly
+ *         good performance; higher rate is sure to have poorer success.
+ *
+ * 6)  Re-evaluate the rate after each tx frame.  If working with block-
+ *     acknowledge, history and statistics may be calculated for the entire
+ *     block (including prior history that fits within the history windows),
+ *     before re-evaluation.
+ *
+ * FINDING BEST STARTING MODULATION MODE:
+ *
+ * After working with a modulation mode for a "while" (and doing rate scaling),
+ * the driver searches for a new initial mode in an attempt to improve
+ * throughput.  The "while" is measured by numbers of attempted frames:
+ *
+ * For legacy mode, search for new mode after:
+ *   480 successful frames, or 160 failed frames
+ * For high-throughput modes (SISO or MIMO), search for new mode after:
+ *   4500 successful frames, or 400 failed frames
+ *
+ * Mode switch possibilities are (3 for each mode):
+ *
+ * For legacy:
+ *   Change antenna, try SISO (if HT association), try MIMO (if HT association)
+ * For SISO:
+ *   Change antenna, try MIMO, try shortened guard interval (SGI)
+ * For MIMO:
+ *   Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI)
+ *
+ * When trying a new mode, use the same bit rate as the old/current mode when
+ * trying antenna switches and shortened guard interval.  When switching to
+ * SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate
+ * for which the expected throughput (under perfect conditions) is about the
+ * same or slightly better than the actual measured throughput delivered by
+ * the old/current mode.
+ *
+ * Actual throughput can be estimated by multiplying the expected throughput
+ * by the success ratio (successful / attempted tx frames).  Frame size is
+ * not considered in this calculation; it assumes that frame size will average
+ * out to be fairly consistent over several samples.  The following are
+ * metric values for expected throughput assuming 100% success ratio.
+ * Only G band has support for CCK rates:
+ *
+ *           RATE:  1    2    5   11    6   9   12   18   24   36   48   54   60
+ *
+ *              G:  7   13   35   58   40  57   72   98  121  154  177  186  186
+ *              A:  0    0    0    0   40  57   72   98  121  154  177  186  186
+ *     SISO 20MHz:  0    0    0    0   42  42   76  102  124  159  183  193  202
+ * SGI SISO 20MHz:  0    0    0    0   46  46   82  110  132  168  192  202  211
+ *     MIMO 20MHz:  0    0    0    0   74  74  123  155  179  214  236  244  251
+ * SGI MIMO 20MHz:  0    0    0    0   81  81  131  164  188  222  243  251  257
+ *     SISO 40MHz:  0    0    0    0   77  77  127  160  184  220  242  250  257
+ * SGI SISO 40MHz:  0    0    0    0   83  83  135  169  193  229  250  257  264
+ *     MIMO 40MHz:  0    0    0    0  123 123  182  214  235  264  279  285  289
+ * SGI MIMO 40MHz:  0    0    0    0  131 131  191  222  242  270  284  289  293
+ *
+ * After the new mode has been tried for a short while (minimum of 6 failed
+ * frames or 8 successful frames), compare success ratio and actual throughput
+ * estimate of the new mode with the old.  If either is better with the new
+ * mode, continue to use the new mode.
+ *
+ * Continue comparing modes until all 3 possibilities have been tried.
+ * If moving from legacy to HT, try all 3 possibilities from the new HT
+ * mode.  After trying all 3, a best mode is found.  Continue to use this mode
+ * for the longer "while" described above (e.g. 480 successful frames for
+ * legacy), and then repeat the search process.
+ *
+ */
+struct iwl4965_link_quality_cmd {
+
+       /* Index of destination/recipient station in uCode's station table */
+       u8 sta_id;
+       u8 reserved1;
+       __le16 control;         /* not used */
+       struct iwl4965_link_qual_general_params general_params;
+       struct iwl4965_link_qual_agg_params agg_params;
+
+       /*
+        * Rate info; when using rate-scaling, Tx command's initial_rate_index
+        * specifies 1st Tx rate attempted, via index into this table.
+        * 4965 works its way through table when retrying Tx.
+        */
+       struct {
+               __le32 rate_n_flags;    /* RATE_MCS_*, IWL_RATE_* */
+       } rs_table[LINK_QUAL_MAX_RETRY_NUM];
+       __le32 reserved2;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
+ *
+ * 3945 and 4965 support hardware handshake with Bluetooth device on
+ * same platform.  Bluetooth device alerts wireless device when it will Tx;
+ * wireless device can delay or kill its own Tx to accomodate.
+ */
+struct iwl4965_bt_cmd {
+       u8 flags;
+       u8 lead_time;
+       u8 max_kill;
+       u8 reserved;
+       __le32 kill_ack_mask;
+       __le32 kill_cts_mask;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (6)
+ * Spectrum Management (802.11h) Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/*
+ * Spectrum Management
+ */
+#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK         | \
+                                RXON_FILTER_CTL2HOST_MSK        | \
+                                RXON_FILTER_ACCEPT_GRP_MSK      | \
+                                RXON_FILTER_DIS_DECRYPT_MSK     | \
+                                RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
+                                RXON_FILTER_ASSOC_MSK           | \
+                                RXON_FILTER_BCON_AWARE_MSK)
+
+struct iwl4965_measure_channel {
+       __le32 duration;        /* measurement duration in extended beacon
+                                * format */
+       u8 channel;             /* channel to measure */
+       u8 type;                /* see enum iwl4965_measure_type */
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
+ */
+struct iwl4965_spectrum_cmd {
+       __le16 len;             /* number of bytes starting from token */
+       u8 token;               /* token id */
+       u8 id;                  /* measurement id -- 0 or 1 */
+       u8 origin;              /* 0 = TGh, 1 = other, 2 = TGk */
+       u8 periodic;            /* 1 = periodic */
+       __le16 path_loss_timeout;
+       __le32 start_time;      /* start time in extended beacon format */
+       __le32 reserved2;
+       __le32 flags;           /* rxon flags */
+       __le32 filter_flags;    /* rxon filter flags */
+       __le16 channel_count;   /* minimum 1, maximum 10 */
+       __le16 reserved3;
+       struct iwl4965_measure_channel channels[10];
+} __attribute__ ((packed));
+
+/*
+ * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
+ */
+struct iwl4965_spectrum_resp {
+       u8 token;
+       u8 id;                  /* id of the prior command replaced, or 0xff */
+       __le16 status;          /* 0 - command will be handled
+                                * 1 - cannot handle (conflicts with another
+                                *     measurement) */
+} __attribute__ ((packed));
+
+enum iwl4965_measurement_state {
+       IWL_MEASUREMENT_START = 0,
+       IWL_MEASUREMENT_STOP = 1,
+};
+
+enum iwl4965_measurement_status {
+       IWL_MEASUREMENT_OK = 0,
+       IWL_MEASUREMENT_CONCURRENT = 1,
+       IWL_MEASUREMENT_CSA_CONFLICT = 2,
+       IWL_MEASUREMENT_TGH_CONFLICT = 3,
+       /* 4-5 reserved */
+       IWL_MEASUREMENT_STOPPED = 6,
+       IWL_MEASUREMENT_TIMEOUT = 7,
+       IWL_MEASUREMENT_PERIODIC_FAILED = 8,
+};
+
+#define NUM_ELEMENTS_IN_HISTOGRAM 8
+
+struct iwl4965_measurement_histogram {
+       __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
+       __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM];  /* in 1usec counts */
+} __attribute__ ((packed));
+
+/* clear channel availability counters */
+struct iwl4965_measurement_cca_counters {
+       __le32 ofdm;
+       __le32 cck;
+} __attribute__ ((packed));
+
+enum iwl4965_measure_type {
+       IWL_MEASURE_BASIC = (1 << 0),
+       IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
+       IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
+       IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
+       IWL_MEASURE_FRAME = (1 << 4),
+       /* bits 5:6 are reserved */
+       IWL_MEASURE_IDLE = (1 << 7),
+};
+
+/*
+ * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
+ */
+struct iwl4965_spectrum_notification {
+       u8 id;                  /* measurement id -- 0 or 1 */
+       u8 token;
+       u8 channel_index;       /* index in measurement channel list */
+       u8 state;               /* 0 - start, 1 - stop */
+       __le32 start_time;      /* lower 32-bits of TSF */
+       u8 band;                /* 0 - 5.2GHz, 1 - 2.4GHz */
+       u8 channel;
+       u8 type;                /* see enum iwl4965_measurement_type */
+       u8 reserved1;
+       /* NOTE:  cca_ofdm, cca_cck, basic_type, and histogram are only only
+        * valid if applicable for measurement type requested. */
+       __le32 cca_ofdm;        /* cca fraction time in 40Mhz clock periods */
+       __le32 cca_cck;         /* cca fraction time in 44Mhz clock periods */
+       __le32 cca_time;        /* channel load time in usecs */
+       u8 basic_type;          /* 0 - bss, 1 - ofdm preamble, 2 -
+                                * unidentified */
+       u8 reserved2[3];
+       struct iwl4965_measurement_histogram histogram;
+       __le32 stop_time;       /* lower 32-bits of TSF */
+       __le32 status;          /* see iwl4965_measurement_status */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (7)
+ * Power Management Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl4965_powertable_cmd - Power Table Command
+ * @flags: See below:
+ *
+ * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
+ *
+ * PM allow:
+ *   bit 0 - '0' Driver not allow power management
+ *           '1' Driver allow PM (use rest of parameters)
+ * uCode send sleep notifications:
+ *   bit 1 - '0' Don't send sleep notification
+ *           '1' send sleep notification (SEND_PM_NOTIFICATION)
+ * Sleep over DTIM
+ *   bit 2 - '0' PM have to walk up every DTIM
+ *           '1' PM could sleep over DTIM till listen Interval.
+ * PCI power managed
+ *   bit 3 - '0' (PCI_LINK_CTRL & 0x1)
+ *           '1' !(PCI_LINK_CTRL & 0x1)
+ * Force sleep Modes
+ *   bit 31/30- '00' use both mac/xtal sleeps
+ *              '01' force Mac sleep
+ *              '10' force xtal sleep
+ *              '11' Illegal set
+ *
+ * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
+ * ucode assume sleep over DTIM is allowed and we don't need to wakeup
+ * for every DTIM.
+ */
+#define IWL_POWER_VEC_SIZE 5
+
+#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK       __constant_cpu_to_le16(1 << 0)
+#define IWL_POWER_SLEEP_OVER_DTIM_MSK          __constant_cpu_to_le16(1 << 2)
+#define IWL_POWER_PCI_PM_MSK                   __constant_cpu_to_le16(1 << 3)
+
+struct iwl4965_powertable_cmd {
+       __le16 flags;
+       u8 keep_alive_seconds;
+       u8 debug_flags;
+       __le32 rx_data_timeout;
+       __le32 tx_data_timeout;
+       __le32 sleep_interval[IWL_POWER_VEC_SIZE];
+       __le32 keep_alive_beacons;
+} __attribute__ ((packed));
+
+/*
+ * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
+ * 3945 and 4965 identical.
+ */
+struct iwl4965_sleep_notification {
+       u8 pm_sleep_mode;
+       u8 pm_wakeup_src;
+       __le16 reserved;
+       __le32 sleep_time;
+       __le32 tsf_low;
+       __le32 bcon_timer;
+} __attribute__ ((packed));
+
+/* Sleep states.  3945 and 4965 identical. */
+enum {
+       IWL_PM_NO_SLEEP = 0,
+       IWL_PM_SLP_MAC = 1,
+       IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
+       IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
+       IWL_PM_SLP_PHY = 4,
+       IWL_PM_SLP_REPENT = 5,
+       IWL_PM_WAKEUP_BY_TIMER = 6,
+       IWL_PM_WAKEUP_BY_DRIVER = 7,
+       IWL_PM_WAKEUP_BY_RFKILL = 8,
+       /* 3 reserved */
+       IWL_PM_NUM_OF_MODES = 12,
+};
+
+/*
+ * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
+ */
+#define CARD_STATE_CMD_DISABLE 0x00    /* Put card to sleep */
+#define CARD_STATE_CMD_ENABLE  0x01    /* Wake up card */
+#define CARD_STATE_CMD_HALT    0x02    /* Power down permanently */
+struct iwl4965_card_state_cmd {
+       __le32 status;          /* CARD_STATE_CMD_* request new power state */
+} __attribute__ ((packed));
+
+/*
+ * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
+ */
+struct iwl4965_card_state_notif {
+       __le32 flags;
+} __attribute__ ((packed));
+
+#define HW_CARD_DISABLED   0x01
+#define SW_CARD_DISABLED   0x02
+#define RF_CARD_DISABLED   0x04
+#define RXON_CARD_DISABLED 0x10
+
+struct iwl4965_ct_kill_config {
+       __le32   reserved;
+       __le32   critical_temperature_M;
+       __le32   critical_temperature_R;
+}  __attribute__ ((packed));
+
+/******************************************************************************
+ * (8)
+ * Scan Commands, Responses, Notifications:
+ *
+ *****************************************************************************/
+
+/**
+ * struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table
+ *
+ * One for each channel in the scan list.
+ * Each channel can independently select:
+ * 1)  SSID for directed active scans
+ * 2)  Txpower setting (for rate specified within Tx command)
+ * 3)  How long to stay on-channel (behavior may be modified by quiet_time,
+ *     quiet_plcp_th, good_CRC_th)
+ *
+ * To avoid uCode errors, make sure the following are true (see comments
+ * under struct iwl4965_scan_cmd about max_out_time and quiet_time):
+ * 1)  If using passive_dwell (i.e. passive_dwell != 0):
+ *     active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
+ * 2)  quiet_time <= active_dwell
+ * 3)  If restricting off-channel time (i.e. max_out_time !=0):
+ *     passive_dwell < max_out_time
+ *     active_dwell < max_out_time
+ */
+struct iwl4965_scan_channel {
+       /*
+        * type is defined as:
+        * 0:0 1 = active, 0 = passive
+        * 1:4 SSID direct bit map; if a bit is set, then corresponding
+        *     SSID IE is transmitted in probe request.
+        * 5:7 reserved
+        */
+       u8 type;
+       u8 channel;     /* band is selected by iwl4965_scan_cmd "flags" field */
+       struct iwl4965_tx_power tpc;
+       __le16 active_dwell;    /* in 1024-uSec TU (time units), typ 5-50 */
+       __le16 passive_dwell;   /* in 1024-uSec TU (time units), typ 20-500 */
+} __attribute__ ((packed));
+
+/**
+ * struct iwl4965_ssid_ie - directed scan network information element
+ *
+ * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
+ * in struct iwl4965_scan_channel; each channel may select different ssids from
+ * among the 4 entries.  SSID IEs get transmitted in reverse order of entry.
+ */
+struct iwl4965_ssid_ie {
+       u8 id;
+       u8 len;
+       u8 ssid[32];
+} __attribute__ ((packed));
+
+#define PROBE_OPTION_MAX        0x4
+#define TX_CMD_LIFE_TIME_INFINITE      __constant_cpu_to_le32(0xFFFFFFFF)
+#define IWL_GOOD_CRC_TH                __constant_cpu_to_le16(1)
+#define IWL_MAX_SCAN_SIZE 1024
+
+/*
+ * REPLY_SCAN_CMD = 0x80 (command)
+ *
+ * The hardware scan command is very powerful; the driver can set it up to
+ * maintain (relatively) normal network traffic while doing a scan in the
+ * background.  The max_out_time and suspend_time control the ratio of how
+ * long the device stays on an associated network channel ("service channel")
+ * vs. how long it's away from the service channel, i.e. tuned to other channels
+ * for scanning.
+ *
+ * max_out_time is the max time off-channel (in usec), and suspend_time
+ * is how long (in "extended beacon" format) that the scan is "suspended"
+ * after returning to the service channel.  That is, suspend_time is the
+ * time that we stay on the service channel, doing normal work, between
+ * scan segments.  The driver may set these parameters differently to support
+ * scanning when associated vs. not associated, and light vs. heavy traffic
+ * loads when associated.
+ *
+ * After receiving this command, the device's scan engine does the following;
+ *
+ * 1)  Sends SCAN_START notification to driver
+ * 2)  Checks to see if it has time to do scan for one channel
+ * 3)  Sends NULL packet, with power-save (PS) bit set to 1,
+ *     to tell AP that we're going off-channel
+ * 4)  Tunes to first channel in scan list, does active or passive scan
+ * 5)  Sends SCAN_RESULT notification to driver
+ * 6)  Checks to see if it has time to do scan on *next* channel in list
+ * 7)  Repeats 4-6 until it no longer has time to scan the next channel
+ *     before max_out_time expires
+ * 8)  Returns to service channel
+ * 9)  Sends NULL packet with PS=0 to tell AP that we're back
+ * 10) Stays on service channel until suspend_time expires
+ * 11) Repeats entire process 2-10 until list is complete
+ * 12) Sends SCAN_COMPLETE notification
+ *
+ * For fast, efficient scans, the scan command also has support for staying on
+ * a channel for just a short time, if doing active scanning and getting no
+ * responses to the transmitted probe request.  This time is controlled by
+ * quiet_time, and the number of received packets below which a channel is
+ * considered "quiet" is controlled by quiet_plcp_threshold.
+ *
+ * For active scanning on channels that have regulatory restrictions against
+ * blindly transmitting, the scan can listen before transmitting, to make sure
+ * that there is already legitimate activity on the channel.  If enough
+ * packets are cleanly received on the channel (controlled by good_CRC_th,
+ * typical value 1), the scan engine starts transmitting probe requests.
+ *
+ * Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
+ *
+ * To avoid uCode errors, see timing restrictions described under
+ * struct iwl4965_scan_channel.
+ */
+struct iwl4965_scan_cmd {
+       __le16 len;
+       u8 reserved0;
+       u8 channel_count;       /* # channels in channel list */
+       __le16 quiet_time;      /* dwell only this # millisecs on quiet channel
+                                * (only for active scan) */
+       __le16 quiet_plcp_th;   /* quiet chnl is < this # pkts (typ. 1) */
+       __le16 good_CRC_th;     /* passive -> active promotion threshold */
+       __le16 rx_chain;        /* RXON_RX_CHAIN_* */
+       __le32 max_out_time;    /* max usec to be away from associated (service)
+                                * channel */
+       __le32 suspend_time;    /* pause scan this long (in "extended beacon
+                                * format") when returning to service chnl:
+                                * 3945; 31:24 # beacons, 19:0 additional usec,
+                                * 4965; 31:22 # beacons, 21:0 additional usec.
+                                */
+       __le32 flags;           /* RXON_FLG_* */
+       __le32 filter_flags;    /* RXON_FILTER_* */
+
+       /* For active scans (set to all-0s for passive scans).
+        * Does not include payload.  Must specify Tx rate; no rate scaling. */
+       struct iwl4965_tx_cmd tx_cmd;
+
+       /* For directed active scans (set to all-0s otherwise) */
+       struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX];
+
+       /*
+        * Probe request frame, followed by channel list.
+        *
+        * Size of probe request frame is specified by byte count in tx_cmd.
+        * Channel list follows immediately after probe request frame.
+        * Number of channels in list is specified by channel_count.
+        * Each channel in list is of type:
+        *
+        * struct iwl4965_scan_channel channels[0];
+        *
+        * NOTE:  Only one band of channels can be scanned per pass.  You
+        * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
+        * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
+        * before requesting another scan.
+        */
+       u8 data[0];
+} __attribute__ ((packed));
+
+/* Can abort will notify by complete notification with abort status. */
+#define CAN_ABORT_STATUS       __constant_cpu_to_le32(0x1)
+/* complete notification statuses */
+#define ABORT_STATUS            0x2
+
+/*
+ * REPLY_SCAN_CMD = 0x80 (response)
+ */
+struct iwl4965_scanreq_notification {
+       __le32 status;          /* 1: okay, 2: cannot fulfill request */
+} __attribute__ ((packed));
+
+/*
+ * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
+ */
+struct iwl4965_scanstart_notification {
+       __le32 tsf_low;
+       __le32 tsf_high;
+       __le32 beacon_timer;
+       u8 channel;
+       u8 band;
+       u8 reserved[2];
+       __le32 status;
+} __attribute__ ((packed));
+
+#define  SCAN_OWNER_STATUS 0x1;
+#define  MEASURE_OWNER_STATUS 0x2;
+
+#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
+/*
+ * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
+ */
+struct iwl4965_scanresults_notification {
+       u8 channel;
+       u8 band;
+       u8 reserved[2];
+       __le32 tsf_low;
+       __le32 tsf_high;
+       __le32 statistics[NUMBER_OF_STATISTICS];
+} __attribute__ ((packed));
+
+/*
+ * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
+ */
+struct iwl4965_scancomplete_notification {
+       u8 scanned_channels;
+       u8 status;
+       u8 reserved;
+       u8 last_channel;
+       __le32 tsf_low;
+       __le32 tsf_high;
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (9)
+ * IBSS/AP Commands and Notifications:
+ *
+ *****************************************************************************/
+
+/*
+ * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
+ */
+struct iwl4965_beacon_notif {
+       struct iwl4965_tx_resp beacon_notify_hdr;
+       __le32 low_tsf;
+       __le32 high_tsf;
+       __le32 ibss_mgr_status;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
+ */
+struct iwl4965_tx_beacon_cmd {
+       struct iwl4965_tx_cmd tx;
+       __le16 tim_idx;
+       u8 tim_size;
+       u8 reserved1;
+       struct ieee80211_hdr frame[0];  /* beacon frame */
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (10)
+ * Statistics Commands and Notifications:
+ *
+ *****************************************************************************/
+
+#define IWL_TEMP_CONVERT 260
+
+#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
+
+/* Used for passing to driver number of successes and failures per rate */
+struct rate_histogram {
+       union {
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+       } success;
+       union {
+               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
+               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
+               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
+       } failed;
+} __attribute__ ((packed));
+
+/* statistics command response */
+
+struct statistics_rx_phy {
+       __le32 ina_cnt;
+       __le32 fina_cnt;
+       __le32 plcp_err;
+       __le32 crc32_err;
+       __le32 overrun_err;
+       __le32 early_overrun_err;
+       __le32 crc32_good;
+       __le32 false_alarm_cnt;
+       __le32 fina_sync_err_cnt;
+       __le32 sfd_timeout;
+       __le32 fina_timeout;
+       __le32 unresponded_rts;
+       __le32 rxe_frame_limit_overrun;
+       __le32 sent_ack_cnt;
+       __le32 sent_cts_cnt;
+       __le32 sent_ba_rsp_cnt;
+       __le32 dsp_self_kill;
+       __le32 mh_format_err;
+       __le32 re_acq_main_rssi_sum;
+       __le32 reserved3;
+} __attribute__ ((packed));
+
+struct statistics_rx_ht_phy {
+       __le32 plcp_err;
+       __le32 overrun_err;
+       __le32 early_overrun_err;
+       __le32 crc32_good;
+       __le32 crc32_err;
+       __le32 mh_format_err;
+       __le32 agg_crc32_good;
+       __le32 agg_mpdu_cnt;
+       __le32 agg_cnt;
+       __le32 reserved2;
+} __attribute__ ((packed));
+
+struct statistics_rx_non_phy {
+       __le32 bogus_cts;       /* CTS received when not expecting CTS */
+       __le32 bogus_ack;       /* ACK received when not expecting ACK */
+       __le32 non_bssid_frames;        /* number of frames with BSSID that
+                                        * doesn't belong to the STA BSSID */
+       __le32 filtered_frames; /* count frames that were dumped in the
+                                * filtering process */
+       __le32 non_channel_beacons;     /* beacons with our bss id but not on
+                                        * our serving channel */
+       __le32 channel_beacons; /* beacons with our bss id and in our
+                                * serving channel */
+       __le32 num_missed_bcon; /* number of missed beacons */
+       __le32 adc_rx_saturation_time;  /* count in 0.8us units the time the
+                                        * ADC was in saturation */
+       __le32 ina_detection_search_time;/* total time (in 0.8us) searched
+                                         * for INA */
+       __le32 beacon_silence_rssi_a;   /* RSSI silence after beacon frame */
+       __le32 beacon_silence_rssi_b;   /* RSSI silence after beacon frame */
+       __le32 beacon_silence_rssi_c;   /* RSSI silence after beacon frame */
+       __le32 interference_data_flag;  /* flag for interference data
+                                        * availability. 1 when data is
+                                        * available. */
+       __le32 channel_load;            /* counts RX Enable time in uSec */
+       __le32 dsp_false_alarms;        /* DSP false alarm (both OFDM
+                                        * and CCK) counter */
+       __le32 beacon_rssi_a;
+       __le32 beacon_rssi_b;
+       __le32 beacon_rssi_c;
+       __le32 beacon_energy_a;
+       __le32 beacon_energy_b;
+       __le32 beacon_energy_c;
+} __attribute__ ((packed));
+
+struct statistics_rx {
+       struct statistics_rx_phy ofdm;
+       struct statistics_rx_phy cck;
+       struct statistics_rx_non_phy general;
+       struct statistics_rx_ht_phy ofdm_ht;
+} __attribute__ ((packed));
+
+struct statistics_tx_non_phy_agg {
+       __le32 ba_timeout;
+       __le32 ba_reschedule_frames;
+       __le32 scd_query_agg_frame_cnt;
+       __le32 scd_query_no_agg;
+       __le32 scd_query_agg;
+       __le32 scd_query_mismatch;
+       __le32 frame_not_ready;
+       __le32 underrun;
+       __le32 bt_prio_kill;
+       __le32 rx_ba_rsp_cnt;
+       __le32 reserved2;
+       __le32 reserved3;
+} __attribute__ ((packed));
+
+struct statistics_tx {
+       __le32 preamble_cnt;
+       __le32 rx_detected_cnt;
+       __le32 bt_prio_defer_cnt;
+       __le32 bt_prio_kill_cnt;
+       __le32 few_bytes_cnt;
+       __le32 cts_timeout;
+       __le32 ack_timeout;
+       __le32 expected_ack_cnt;
+       __le32 actual_ack_cnt;
+       __le32 dump_msdu_cnt;
+       __le32 burst_abort_next_frame_mismatch_cnt;
+       __le32 burst_abort_missing_next_frame_cnt;
+       __le32 cts_timeout_collision;
+       __le32 ack_or_ba_timeout_collision;
+       struct statistics_tx_non_phy_agg agg;
+} __attribute__ ((packed));
+
+struct statistics_dbg {
+       __le32 burst_check;
+       __le32 burst_count;
+       __le32 reserved[4];
+} __attribute__ ((packed));
+
+struct statistics_div {
+       __le32 tx_on_a;
+       __le32 tx_on_b;
+       __le32 exec_time;
+       __le32 probe_time;
+       __le32 reserved1;
+       __le32 reserved2;
+} __attribute__ ((packed));
+
+struct statistics_general {
+       __le32 temperature;
+       __le32 temperature_m;
+       struct statistics_dbg dbg;
+       __le32 sleep_time;
+       __le32 slots_out;
+       __le32 slots_idle;
+       __le32 ttl_timestamp;
+       struct statistics_div div;
+       __le32 rx_enable_counter;
+       __le32 reserved1;
+       __le32 reserved2;
+       __le32 reserved3;
+} __attribute__ ((packed));
+
+/*
+ * REPLY_STATISTICS_CMD = 0x9c,
+ * 3945 and 4965 identical.
+ *
+ * This command triggers an immediate response containing uCode statistics.
+ * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
+ *
+ * If the CLEAR_STATS configuration flag is set, uCode will clear its
+ * internal copy of the statistics (counters) after issuing the response.
+ * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
+ *
+ * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
+ * STATISTICS_NOTIFICATIONs after received beacons (see below).  This flag
+ * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
+ */
+#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
+#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
+struct iwl4965_statistics_cmd {
+       __le32 configuration_flags;     /* IWL_STATS_CONF_* */
+} __attribute__ ((packed));
+
+/*
+ * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
+ *
+ * By default, uCode issues this notification after receiving a beacon
+ * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
+ * REPLY_STATISTICS_CMD 0x9c, above.
+ *
+ * Statistics counters continue to increment beacon after beacon, but are
+ * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
+ * 0x9c with CLEAR_STATS bit set (see above).
+ *
+ * uCode also issues this notification during scans.  uCode clears statistics
+ * appropriately so that each notification contains statistics for only the
+ * one channel that has just been scanned.
+ */
+#define STATISTICS_REPLY_FLG_BAND_24G_MSK         __constant_cpu_to_le32(0x2)
+#define STATISTICS_REPLY_FLG_FAT_MODE_MSK         __constant_cpu_to_le32(0x8)
+struct iwl4965_notif_statistics {
+       __le32 flag;
+       struct statistics_rx rx;
+       struct statistics_tx tx;
+       struct statistics_general general;
+} __attribute__ ((packed));
+
+
+/*
+ * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
+ */
+/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
+ * then this notification will be sent. */
+#define CONSECUTIVE_MISSED_BCONS_TH 20
+
+struct iwl4965_missed_beacon_notif {
+       __le32 consequtive_missed_beacons;
+       __le32 total_missed_becons;
+       __le32 num_expected_beacons;
+       __le32 num_recvd_beacons;
+} __attribute__ ((packed));
+
+
+/******************************************************************************
+ * (11)
+ * Rx Calibration Commands:
+ *
+ * With the uCode used for open source drivers, most Tx calibration (except
+ * for Tx Power) and most Rx calibration is done by uCode during the
+ * "initialize" phase of uCode boot.  Driver must calibrate only:
+ *
+ * 1)  Tx power (depends on temperature), described elsewhere
+ * 2)  Receiver gain balance (optimize MIMO, and detect disconnected antennas)
+ * 3)  Receiver sensitivity (to optimize signal detection)
+ *
+ *****************************************************************************/
+
+/**
+ * SENSITIVITY_CMD = 0xa8 (command, has simple generic response)
+ *
+ * This command sets up the Rx signal detector for a sensitivity level that
+ * is high enough to lock onto all signals within the associated network,
+ * but low enough to ignore signals that are below a certain threshold, so as
+ * not to have too many "false alarms".  False alarms are signals that the
+ * Rx DSP tries to lock onto, but then discards after determining that they
+ * are noise.
+ *
+ * The optimum number of false alarms is between 5 and 50 per 200 TUs
+ * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e.
+ * time listening, not transmitting).  Driver must adjust sensitivity so that
+ * the ratio of actual false alarms to actual Rx time falls within this range.
+ *
+ * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each
+ * received beacon.  These provide information to the driver to analyze the
+ * sensitivity.  Don't analyze statistics that come in from scanning, or any
+ * other non-associated-network source.  Pertinent statistics include:
+ *
+ * From "general" statistics (struct statistics_rx_non_phy):
+ *
+ * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level)
+ *   Measure of energy of desired signal.  Used for establishing a level
+ *   below which the device does not detect signals.
+ *
+ * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB)
+ *   Measure of background noise in silent period after beacon.
+ *
+ * channel_load
+ *   uSecs of actual Rx time during beacon period (varies according to
+ *   how much time was spent transmitting).
+ *
+ * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately:
+ *
+ * false_alarm_cnt
+ *   Signal locks abandoned early (before phy-level header).
+ *
+ * plcp_err
+ *   Signal locks abandoned late (during phy-level header).
+ *
+ * NOTE:  Both false_alarm_cnt and plcp_err increment monotonically from
+ *        beacon to beacon, i.e. each value is an accumulation of all errors
+ *        before and including the latest beacon.  Values will wrap around to 0
+ *        after counting up to 2^32 - 1.  Driver must differentiate vs.
+ *        previous beacon's values to determine # false alarms in the current
+ *        beacon period.
+ *
+ * Total number of false alarms = false_alarms + plcp_errs
+ *
+ * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd
+ * (notice that the start points for OFDM are at or close to settings for
+ * maximum sensitivity):
+ *
+ *                                             START  /  MIN  /  MAX
+ *   HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX          90   /   85  /  120
+ *   HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX     170   /  170  /  210
+ *   HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX         105   /  105  /  140
+ *   HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX     220   /  220  /  270
+ *
+ *   If actual rate of OFDM false alarms (+ plcp_errors) is too high
+ *   (greater than 50 for each 204.8 msecs listening), reduce sensitivity
+ *   by *adding* 1 to all 4 of the table entries above, up to the max for
+ *   each entry.  Conversely, if false alarm rate is too low (less than 5
+ *   for each 204.8 msecs listening), *subtract* 1 from each entry to
+ *   increase sensitivity.
+ *
+ * For CCK sensitivity, keep track of the following:
+ *
+ *   1).  20-beacon history of maximum background noise, indicated by
+ *        (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the
+ *        3 receivers.  For any given beacon, the "silence reference" is
+ *        the maximum of last 60 samples (20 beacons * 3 receivers).
+ *
+ *   2).  10-beacon history of strongest signal level, as indicated
+ *        by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers,
+ *        i.e. the strength of the signal through the best receiver at the
+ *        moment.  These measurements are "upside down", with lower values
+ *        for stronger signals, so max energy will be *minimum* value.
+ *
+ *        Then for any given beacon, the driver must determine the *weakest*
+ *        of the strongest signals; this is the minimum level that needs to be
+ *        successfully detected, when using the best receiver at the moment.
+ *        "Max cck energy" is the maximum (higher value means lower energy!)
+ *        of the last 10 minima.  Once this is determined, driver must add
+ *        a little margin by adding "6" to it.
+ *
+ *   3).  Number of consecutive beacon periods with too few false alarms.
+ *        Reset this to 0 at the first beacon period that falls within the
+ *        "good" range (5 to 50 false alarms per 204.8 milliseconds rx).
+ *
+ * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd
+ * (notice that the start points for CCK are at maximum sensitivity):
+ *
+ *                                             START  /  MIN  /  MAX
+ *   HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX         125   /  125  /  200
+ *   HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX     200   /  200  /  400
+ *   HD_MIN_ENERGY_CCK_DET_INDEX                100   /    0  /  100
+ *
+ *   If actual rate of CCK false alarms (+ plcp_errors) is too high
+ *   (greater than 50 for each 204.8 msecs listening), method for reducing
+ *   sensitivity is:
+ *
+ *   1)  *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX,
+ *       up to max 400.
+ *
+ *   2)  If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160,
+ *       sensitivity has been reduced a significant amount; bring it up to
+ *       a moderate 161.  Otherwise, *add* 3, up to max 200.
+ *
+ *   3)  a)  If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160,
+ *       sensitivity has been reduced only a moderate or small amount;
+ *       *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX,
+ *       down to min 0.  Otherwise (if gain has been significantly reduced),
+ *       don't change the HD_MIN_ENERGY_CCK_DET_INDEX value.
+ *
+ *       b)  Save a snapshot of the "silence reference".
+ *
+ *   If actual rate of CCK false alarms (+ plcp_errors) is too low
+ *   (less than 5 for each 204.8 msecs listening), method for increasing
+ *   sensitivity is used only if:
+ *
+ *   1a)  Previous beacon did not have too many false alarms
+ *   1b)  AND difference between previous "silence reference" and current
+ *        "silence reference" (prev - current) is 2 or more,
+ *   OR 2)  100 or more consecutive beacon periods have had rate of
+ *          less than 5 false alarms per 204.8 milliseconds rx time.
+ *
+ *   Method for increasing sensitivity:
+ *
+ *   1)  *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX,
+ *       down to min 125.
+ *
+ *   2)  *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX,
+ *       down to min 200.
+ *
+ *   3)  *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100.
+ *
+ *   If actual rate of CCK false alarms (+ plcp_errors) is within good range
+ *   (between 5 and 50 for each 204.8 msecs listening):
+ *
+ *   1)  Save a snapshot of the silence reference.
+ *
+ *   2)  If previous beacon had too many CCK false alarms (+ plcp_errors),
+ *       give some extra margin to energy threshold by *subtracting* 8
+ *       from value in HD_MIN_ENERGY_CCK_DET_INDEX.
+ *
+ *   For all cases (too few, too many, good range), make sure that the CCK
+ *   detection threshold (energy) is below the energy level for robust
+ *   detection over the past 10 beacon periods, the "Max cck energy".
+ *   Lower values mean higher energy; this means making sure that the value
+ *   in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy".
+ *
+ * Driver should set the following entries to fixed values:
+ *
+ *   HD_MIN_ENERGY_OFDM_DET_INDEX               100
+ *   HD_BARKER_CORR_TH_ADD_MIN_INDEX            190
+ *   HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX        390
+ *   HD_OFDM_ENERGY_TH_IN_INDEX                  62
+ */
+
+/*
+ * Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd)
+ */
+#define HD_TABLE_SIZE  (11)    /* number of entries */
+#define HD_MIN_ENERGY_CCK_DET_INDEX                 (0)        /* table indexes */
+#define HD_MIN_ENERGY_OFDM_DET_INDEX                (1)
+#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX          (2)
+#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX      (3)
+#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX      (4)
+#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX          (5)
+#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX      (6)
+#define HD_BARKER_CORR_TH_ADD_MIN_INDEX             (7)
+#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX         (8)
+#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX          (9)
+#define HD_OFDM_ENERGY_TH_IN_INDEX                  (10)
+
+/* Control field in struct iwl4965_sensitivity_cmd */
+#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE  __constant_cpu_to_le16(0)
+#define SENSITIVITY_CMD_CONTROL_WORK_TABLE     __constant_cpu_to_le16(1)
+
+/**
+ * struct iwl4965_sensitivity_cmd
+ * @control:  (1) updates working table, (0) updates default table
+ * @table:  energy threshold values, use HD_* as index into table
+ *
+ * Always use "1" in "control" to update uCode's working table and DSP.
+ */
+struct iwl4965_sensitivity_cmd {
+       __le16 control;                 /* always use "1" */
+       __le16 table[HD_TABLE_SIZE];    /* use HD_* as index */
+} __attribute__ ((packed));
+
+
+/**
+ * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
+ *
+ * This command sets the relative gains of 4965's 3 radio receiver chains.
+ *
+ * After the first association, driver should accumulate signal and noise
+ * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20
+ * beacons from the associated network (don't collect statistics that come
+ * in from scanning, or any other non-network source).
+ *
+ * DISCONNECTED ANTENNA:
+ *
+ * Driver should determine which antennas are actually connected, by comparing
+ * average beacon signal levels for the 3 Rx chains.  Accumulate (add) the
+ * following values over 20 beacons, one accumulator for each of the chains
+ * a/b/c, from struct statistics_rx_non_phy:
+ *
+ * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB)
+ *
+ * Find the strongest signal from among a/b/c.  Compare the other two to the
+ * strongest.  If any signal is more than 15 dB (times 20, unless you
+ * divide the accumulated values by 20) below the strongest, the driver
+ * considers that antenna to be disconnected, and should not try to use that
+ * antenna/chain for Rx or Tx.  If both A and B seem to be disconnected,
+ * driver should declare the stronger one as connected, and attempt to use it
+ * (A and B are the only 2 Tx chains!).
+ *
+ *
+ * RX BALANCE:
+ *
+ * Driver should balance the 3 receivers (but just the ones that are connected
+ * to antennas, see above) for gain, by comparing the average signal levels
+ * detected during the silence after each beacon (background noise).
+ * Accumulate (add) the following values over 20 beacons, one accumulator for
+ * each of the chains a/b/c, from struct statistics_rx_non_phy:
+ *
+ * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB)
+ *
+ * Find the weakest background noise level from among a/b/c.  This Rx chain
+ * will be the reference, with 0 gain adjustment.  Attenuate other channels by
+ * finding noise difference:
+ *
+ * (accum_noise[i] - accum_noise[reference]) / 30
+ *
+ * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB.
+ * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the
+ * driver should limit the difference results to a range of 0-3 (0-4.5 dB),
+ * and set bit 2 to indicate "reduce gain".  The value for the reference
+ * (weakest) chain should be "0".
+ *
+ * diff_gain_[abc] bit fields:
+ *   2: (1) reduce gain, (0) increase gain
+ * 1-0: amount of gain, units of 1.5 dB
+ */
+
+/* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */
+#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
+
+struct iwl4965_calibration_cmd {
+       u8 opCode;              /* PHY_CALIBRATE_DIFF_GAIN_CMD (7) */
+       u8 flags;               /* not used */
+       __le16 reserved;
+       s8 diff_gain_a;         /* see above */
+       s8 diff_gain_b;
+       s8 diff_gain_c;
+       u8 reserved1;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (12)
+ * Miscellaneous Commands:
+ *
+ *****************************************************************************/
+
+/*
+ * LEDs Command & Response
+ * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
+ *
+ * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
+ * this command turns it on or off, or sets up a periodic blinking cycle.
+ */
+struct iwl4965_led_cmd {
+       __le32 interval;        /* "interval" in uSec */
+       u8 id;                  /* 1: Activity, 2: Link, 3: Tech */
+       u8 off;                 /* # intervals off while blinking;
+                                * "0", with >0 "on" value, turns LED on */
+       u8 on;                  /* # intervals on while blinking;
+                                * "0", regardless of "off", turns LED off */
+       u8 reserved;
+} __attribute__ ((packed));
+
+/******************************************************************************
+ * (13)
+ * Union of all expected notifications/responses:
+ *
+ *****************************************************************************/
+
+struct iwl4965_rx_packet {
+       __le32 len;
+       struct iwl4965_cmd_header hdr;
+       union {
+               struct iwl4965_alive_resp alive_frame;
+               struct iwl4965_rx_frame rx_frame;
+               struct iwl4965_tx_resp tx_resp;
+               struct iwl4965_spectrum_notification spectrum_notif;
+               struct iwl4965_csa_notification csa_notif;
+               struct iwl4965_error_resp err_resp;
+               struct iwl4965_card_state_notif card_state_notif;
+               struct iwl4965_beacon_notif beacon_status;
+               struct iwl4965_add_sta_resp add_sta;
+               struct iwl4965_sleep_notification sleep_notif;
+               struct iwl4965_spectrum_resp spectrum;
+               struct iwl4965_notif_statistics stats;
+               struct iwl4965_compressed_ba_resp compressed_ba;
+               struct iwl4965_missed_beacon_notif missed_beacon;
+               __le32 status;
+               u8 raw[0];
+       } u;
+} __attribute__ ((packed));
+
+#define IWL_RX_FRAME_SIZE        (4 + sizeof(struct iwl4965_rx_frame))
+
+#endif                         /* __iwl4965_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h
new file mode 100644 (file)
index 0000000..36696bb
--- /dev/null
@@ -0,0 +1,152 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * 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:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#ifndef __iwl4965_debug_h__
+#define __iwl4965_debug_h__
+
+#ifdef CONFIG_IWL4965_DEBUG
+extern u32 iwl4965_debug_level;
+#define IWL_DEBUG(level, fmt, args...) \
+do { if (iwl4965_debug_level & (level)) \
+  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+
+#define IWL_DEBUG_LIMIT(level, fmt, args...) \
+do { if ((iwl4965_debug_level & (level)) && net_ratelimit()) \
+  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
+        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+#else
+static inline void IWL_DEBUG(int level, const char *fmt, ...)
+{
+}
+static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
+{
+}
+#endif                         /* CONFIG_IWL4965_DEBUG */
+
+/*
+ * To use the debug system;
+ *
+ * If you are defining a new debug classification, simply add it to the #define
+ * list here in the form of:
+ *
+ * #define IWL_DL_xxxx VALUE
+ *
+ * shifting value to the left one bit from the previous entry.  xxxx should be
+ * the name of the classification (for example, WEP)
+ *
+ * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
+ * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
+ * to send output to that classification.
+ *
+ * To add your debug level to the list of levels seen when you perform
+ *
+ * % cat /proc/net/iwl/debug_level
+ *
+ * you simply need to add your entry to the iwl4965_debug_levels array.
+ *
+ * If you do not see debug_level in /proc/net/iwl then you do not have
+ * CONFIG_IWL4965_DEBUG defined in your kernel configuration
+ *
+ */
+
+#define IWL_DL_INFO          (1 << 0)
+#define IWL_DL_MAC80211      (1 << 1)
+#define IWL_DL_HOST_COMMAND  (1 << 2)
+#define IWL_DL_STATE         (1 << 3)
+
+#define IWL_DL_RADIO         (1 << 7)
+#define IWL_DL_POWER         (1 << 8)
+#define IWL_DL_TEMP          (1 << 9)
+
+#define IWL_DL_NOTIF         (1 << 10)
+#define IWL_DL_SCAN          (1 << 11)
+#define IWL_DL_ASSOC         (1 << 12)
+#define IWL_DL_DROP          (1 << 13)
+
+#define IWL_DL_TXPOWER       (1 << 14)
+
+#define IWL_DL_AP            (1 << 15)
+
+#define IWL_DL_FW            (1 << 16)
+#define IWL_DL_RF_KILL       (1 << 17)
+#define IWL_DL_FW_ERRORS     (1 << 18)
+
+#define IWL_DL_LED           (1 << 19)
+
+#define IWL_DL_RATE          (1 << 20)
+
+#define IWL_DL_CALIB         (1 << 21)
+#define IWL_DL_WEP           (1 << 22)
+#define IWL_DL_TX            (1 << 23)
+#define IWL_DL_RX            (1 << 24)
+#define IWL_DL_ISR           (1 << 25)
+#define IWL_DL_HT            (1 << 26)
+#define IWL_DL_IO            (1 << 27)
+#define IWL_DL_11H           (1 << 28)
+
+#define IWL_DL_STATS         (1 << 29)
+#define IWL_DL_TX_REPLY      (1 << 30)
+#define IWL_DL_QOS           (1 << 31)
+
+#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
+#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
+#define IWL_DEBUG_INFO(f, a...)    IWL_DEBUG(IWL_DL_INFO, f, ## a)
+
+#define IWL_DEBUG_MAC80211(f, a...)     IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
+#define IWL_DEBUG_TEMP(f, a...)   IWL_DEBUG(IWL_DL_TEMP, f, ## a)
+#define IWL_DEBUG_SCAN(f, a...)   IWL_DEBUG(IWL_DL_SCAN, f, ## a)
+#define IWL_DEBUG_RX(f, a...)     IWL_DEBUG(IWL_DL_RX, f, ## a)
+#define IWL_DEBUG_TX(f, a...)     IWL_DEBUG(IWL_DL_TX, f, ## a)
+#define IWL_DEBUG_ISR(f, a...)    IWL_DEBUG(IWL_DL_ISR, f, ## a)
+#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
+#define IWL_DEBUG_WEP(f, a...)    IWL_DEBUG(IWL_DL_WEP, f, ## a)
+#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
+#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
+#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
+#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
+#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
+#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
+#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
+#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
+#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
+#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
+       IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
+#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
+#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
+#define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
+#define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
+#define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
+#define IWL_DEBUG_11H(f, a...)  IWL_DEBUG(IWL_DL_11H, f, ## a)
+
+#endif
index 99a19ef4c7433a9a8339cd352a37d7d7ec57abb1..ff71c09ab1a7f73d053e855ee17c2c3f03e8974f 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral Public License as
+ * 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
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *****************************************************************************/
+/*
+ * Please use this file (iwl-4965-hw.h) only for hardware-related definitions.
+ * Use iwl-4965-commands.h for uCode API definitions.
+ * Use iwl-4965.h for driver implementation definitions.
+ */
 
 #ifndef __iwl_4965_hw_h__
 #define __iwl_4965_hw_h__
 
-#define IWL_RX_BUF_SIZE (4 * 1024)
-#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+/*
+ * uCode queue management definitions ...
+ * Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4.
+ * The first queue used for block-ack aggregation is #7 (4965 only).
+ * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7.
+ */
+#define IWL_CMD_QUEUE_NUM       4
+#define IWL_CMD_FIFO_NUM        4
+#define IWL_BACK_QUEUE_FIRST_ID 7
+
+/* Tx rates */
+#define IWL_CCK_RATES 4
+#define IWL_OFDM_RATES 8
+#define IWL_HT_RATES 16
+#define IWL_MAX_RATES  (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
+
+/* Time constants */
+#define SHORT_SLOT_TIME 9
+#define LONG_SLOT_TIME 20
+
+/* RSSI to dBm */
+#define IWL_RSSI_OFFSET        44
+
+/*
+ * EEPROM related constants, enums, and structures.
+ */
+
+/*
+ * EEPROM access time values:
+ *
+ * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG,
+ *   then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit
+ *   CSR_EEPROM_REG_BIT_CMD (0x2).
+ * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1).
+ * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec.
+ * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG.
+ */
+#define IWL_EEPROM_ACCESS_TIMEOUT      5000 /* uSec */
+#define IWL_EEPROM_ACCESS_DELAY                10   /* uSec */
+
+/*
+ * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags.
+ *
+ * IBSS and/or AP operation is allowed *only* on those channels with
+ * (VALID && IBSS && ACTIVE && !RADAR).  This restriction is in place because
+ * RADAR detection is not supported by the 4965 driver, but is a
+ * requirement for establishing a new network for legal operation on channels
+ * requiring RADAR detection or restricting ACTIVE scanning.
+ *
+ * NOTE:  "WIDE" flag does not indicate anything about "FAT" 40 MHz channels.
+ *        It only indicates that 20 MHz channel use is supported; FAT channel
+ *        usage is indicated by a separate set of regulatory flags for each
+ *        FAT channel pair.
+ *
+ * NOTE:  Using a channel inappropriately will result in a uCode error!
+ */
+enum {
+       EEPROM_CHANNEL_VALID = (1 << 0),        /* usable for this SKU/geo */
+       EEPROM_CHANNEL_IBSS = (1 << 1),         /* usable as an IBSS channel */
+       /* Bit 2 Reserved */
+       EEPROM_CHANNEL_ACTIVE = (1 << 3),       /* active scanning allowed */
+       EEPROM_CHANNEL_RADAR = (1 << 4),        /* radar detection required */
+       EEPROM_CHANNEL_WIDE = (1 << 5),         /* 20 MHz channel okay */
+       EEPROM_CHANNEL_NARROW = (1 << 6),       /* 10 MHz channel (not used) */
+       EEPROM_CHANNEL_DFS = (1 << 7),  /* dynamic freq selection candidate */
+};
+
+/* SKU Capabilities */
+#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE                (1 << 0)
+#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
+
+/* *regulatory* channel data format in eeprom, one for each channel.
+ * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */
+struct iwl4965_eeprom_channel {
+       u8 flags;               /* EEPROM_CHANNEL_* flags copied from EEPROM */
+       s8 max_power_avg;       /* max power (dBm) on this chnl, limit 31 */
+} __attribute__ ((packed));
+
+/* 4965 has two radio transmitters (and 3 radio receivers) */
+#define EEPROM_TX_POWER_TX_CHAINS      (2)
+
+/* 4965 has room for up to 8 sets of txpower calibration data */
+#define EEPROM_TX_POWER_BANDS          (8)
+
+/* 4965 factory calibration measures txpower gain settings for
+ * each of 3 target output levels */
+#define EEPROM_TX_POWER_MEASUREMENTS   (3)
+
+/* 4965 driver does not work with txpower calibration version < 5.
+ * Look for this in calib_version member of struct iwl4965_eeprom. */
+#define EEPROM_TX_POWER_VERSION_NEW    (5)
+
+
+/*
+ * 4965 factory calibration data for one txpower level, on one channel,
+ * measured on one of the 2 tx chains (radio transmitter and associated
+ * antenna).  EEPROM contains:
+ *
+ * 1)  Temperature (degrees Celsius) of device when measurement was made.
+ *
+ * 2)  Gain table index used to achieve the target measurement power.
+ *     This refers to the "well-known" gain tables (see iwl-4965-hw.h).
+ *
+ * 3)  Actual measured output power, in half-dBm ("34" = 17 dBm).
+ *
+ * 4)  RF power amplifier detector level measurement (not used).
+ */
+struct iwl4965_eeprom_calib_measure {
+       u8 temperature;         /* Device temperature (Celsius) */
+       u8 gain_idx;            /* Index into gain table */
+       u8 actual_pow;          /* Measured RF output power, half-dBm */
+       s8 pa_det;              /* Power amp detector level (not used) */
+} __attribute__ ((packed));
+
+
+/*
+ * 4965 measurement set for one channel.  EEPROM contains:
+ *
+ * 1)  Channel number measured
+ *
+ * 2)  Measurements for each of 3 power levels for each of 2 radio transmitters
+ *     (a.k.a. "tx chains") (6 measurements altogether)
+ */
+struct iwl4965_eeprom_calib_ch_info {
+       u8 ch_num;
+       struct iwl4965_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS]
+               [EEPROM_TX_POWER_MEASUREMENTS];
+} __attribute__ ((packed));
+
+/*
+ * 4965 txpower subband info.
+ *
+ * For each frequency subband, EEPROM contains the following:
+ *
+ * 1)  First and last channels within range of the subband.  "0" values
+ *     indicate that this sample set is not being used.
+ *
+ * 2)  Sample measurement sets for 2 channels close to the range endpoints.
+ */
+struct iwl4965_eeprom_calib_subband_info {
+       u8 ch_from;     /* channel number of lowest channel in subband */
+       u8 ch_to;       /* channel number of highest channel in subband */
+       struct iwl4965_eeprom_calib_ch_info ch1;
+       struct iwl4965_eeprom_calib_ch_info ch2;
+} __attribute__ ((packed));
+
+
+/*
+ * 4965 txpower calibration info.  EEPROM contains:
+ *
+ * 1)  Factory-measured saturation power levels (maximum levels at which
+ *     tx power amplifier can output a signal without too much distortion).
+ *     There is one level for 2.4 GHz band and one for 5 GHz band.  These
+ *     values apply to all channels within each of the bands.
+ *
+ * 2)  Factory-measured power supply voltage level.  This is assumed to be
+ *     constant (i.e. same value applies to all channels/bands) while the
+ *     factory measurements are being made.
+ *
+ * 3)  Up to 8 sets of factory-measured txpower calibration values.
+ *     These are for different frequency ranges, since txpower gain
+ *     characteristics of the analog radio circuitry vary with frequency.
+ *
+ *     Not all sets need to be filled with data;
+ *     struct iwl4965_eeprom_calib_subband_info contains range of channels
+ *     (0 if unused) for each set of data.
+ */
+struct iwl4965_eeprom_calib_info {
+       u8 saturation_power24;  /* half-dBm (e.g. "34" = 17 dBm) */
+       u8 saturation_power52;  /* half-dBm */
+       s16 voltage;            /* signed */
+       struct iwl4965_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS];
+} __attribute__ ((packed));
+
+
+/*
+ * 4965 EEPROM map
+ */
+struct iwl4965_eeprom {
+       u8 reserved0[16];
+#define EEPROM_DEVICE_ID                    (2*0x08)   /* 2 bytes */
+       u16 device_id;          /* abs.ofs: 16 */
+       u8 reserved1[2];
+#define EEPROM_PMC                          (2*0x0A)   /* 2 bytes */
+       u16 pmc;                /* abs.ofs: 20 */
+       u8 reserved2[20];
+#define EEPROM_MAC_ADDRESS                  (2*0x15)   /* 6  bytes */
+       u8 mac_address[6];      /* abs.ofs: 42 */
+       u8 reserved3[58];
+#define EEPROM_BOARD_REVISION               (2*0x35)   /* 2  bytes */
+       u16 board_revision;     /* abs.ofs: 106 */
+       u8 reserved4[11];
+#define EEPROM_BOARD_PBA_NUMBER             (2*0x3B+1) /* 9  bytes */
+       u8 board_pba_number[9]; /* abs.ofs: 119 */
+       u8 reserved5[8];
+#define EEPROM_VERSION                      (2*0x44)   /* 2  bytes */
+       u16 version;            /* abs.ofs: 136 */
+#define EEPROM_SKU_CAP                      (2*0x45)   /* 1  bytes */
+       u8 sku_cap;             /* abs.ofs: 138 */
+#define EEPROM_LEDS_MODE                    (2*0x45+1) /* 1  bytes */
+       u8 leds_mode;           /* abs.ofs: 139 */
+#define EEPROM_OEM_MODE                     (2*0x46)   /* 2  bytes */
+       u16 oem_mode;
+#define EEPROM_WOWLAN_MODE                  (2*0x47)   /* 2  bytes */
+       u16 wowlan_mode;        /* abs.ofs: 142 */
+#define EEPROM_LEDS_TIME_INTERVAL           (2*0x48)   /* 2  bytes */
+       u16 leds_time_interval; /* abs.ofs: 144 */
+#define EEPROM_LEDS_OFF_TIME                (2*0x49)   /* 1  bytes */
+       u8 leds_off_time;       /* abs.ofs: 146 */
+#define EEPROM_LEDS_ON_TIME                 (2*0x49+1) /* 1  bytes */
+       u8 leds_on_time;        /* abs.ofs: 147 */
+#define EEPROM_ALMGOR_M_VERSION             (2*0x4A)   /* 1  bytes */
+       u8 almgor_m_version;    /* abs.ofs: 148 */
+#define EEPROM_ANTENNA_SWITCH_TYPE          (2*0x4A+1) /* 1  bytes */
+       u8 antenna_switch_type; /* abs.ofs: 149 */
+       u8 reserved6[8];
+#define EEPROM_4965_BOARD_REVISION          (2*0x4F)   /* 2 bytes */
+       u16 board_revision_4965;        /* abs.ofs: 158 */
+       u8 reserved7[13];
+#define EEPROM_4965_BOARD_PBA               (2*0x56+1) /* 9 bytes */
+       u8 board_pba_number_4965[9];    /* abs.ofs: 173 */
+       u8 reserved8[10];
+#define EEPROM_REGULATORY_SKU_ID            (2*0x60)   /* 4  bytes */
+       u8 sku_id[4];           /* abs.ofs: 192 */
+
+/*
+ * Per-channel regulatory data.
+ *
+ * Each channel that *might* be supported by 3945 or 4965 has a fixed location
+ * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
+ * txpower (MSB).
+ *
+ * Entries immediately below are for 20 MHz channel width.  FAT (40 MHz)
+ * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
+ *
+ * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
+ */
+#define EEPROM_REGULATORY_BAND_1            (2*0x62)   /* 2  bytes */
+       u16 band_1_count;       /* abs.ofs: 196 */
+#define EEPROM_REGULATORY_BAND_1_CHANNELS   (2*0x63)   /* 28 bytes */
+       struct iwl4965_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+
+/*
+ * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
+ * 5.0 GHz channels 7, 8, 11, 12, 16
+ * (4915-5080MHz) (none of these is ever supported)
+ */
+#define EEPROM_REGULATORY_BAND_2            (2*0x71)   /* 2  bytes */
+       u16 band_2_count;       /* abs.ofs: 226 */
+#define EEPROM_REGULATORY_BAND_2_CHANNELS   (2*0x72)   /* 26 bytes */
+       struct iwl4965_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */
+
+/*
+ * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
+ * (5170-5320MHz)
+ */
+#define EEPROM_REGULATORY_BAND_3            (2*0x7F)   /* 2  bytes */
+       u16 band_3_count;       /* abs.ofs: 254 */
+#define EEPROM_REGULATORY_BAND_3_CHANNELS   (2*0x80)   /* 24 bytes */
+       struct iwl4965_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */
+
+/*
+ * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+ * (5500-5700MHz)
+ */
+#define EEPROM_REGULATORY_BAND_4            (2*0x8C)   /* 2  bytes */
+       u16 band_4_count;       /* abs.ofs: 280 */
+#define EEPROM_REGULATORY_BAND_4_CHANNELS   (2*0x8D)   /* 22 bytes */
+       struct iwl4965_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */
+
+/*
+ * 5.7 GHz channels 145, 149, 153, 157, 161, 165
+ * (5725-5825MHz)
+ */
+#define EEPROM_REGULATORY_BAND_5            (2*0x98)   /* 2  bytes */
+       u16 band_5_count;       /* abs.ofs: 304 */
+#define EEPROM_REGULATORY_BAND_5_CHANNELS   (2*0x99)   /* 12 bytes */
+       struct iwl4965_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */
+
+       u8 reserved10[2];
+
+
+/*
+ * 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
+ *
+ * The channel listed is the center of the lower 20 MHz half of the channel.
+ * The overall center frequency is actually 2 channels (10 MHz) above that,
+ * and the upper half of each FAT channel is centered 4 channels (20 MHz) away
+ * from the lower half; e.g. the upper half of FAT channel 1 is channel 5,
+ * and the overall FAT channel width centers on channel 3.
+ *
+ * NOTE:  The RXON command uses 20 MHz channel numbers to specify the
+ *        control channel to which to tune.  RXON also specifies whether the
+ *        control channel is the upper or lower half of a FAT channel.
+ *
+ * NOTE:  4965 does not support FAT channels on 2.4 GHz.
+ */
+#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0)        /* 14 bytes */
+       struct iwl4965_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */
+       u8 reserved11[2];
+
+/*
+ * 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64),
+ * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
+ */
+#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8)        /* 22 bytes */
+       struct iwl4965_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */
+       u8 reserved12[6];
+
+/*
+ * 4965 driver requires txpower calibration format version 5 or greater.
+ * Driver does not work with txpower calibration version < 5.
+ * This value is simply a 16-bit number, no major/minor versions here.
+ */
+#define EEPROM_CALIB_VERSION_OFFSET            (2*0xB6)        /* 2 bytes */
+       u16 calib_version;      /* abs.ofs: 364 */
+       u8 reserved13[2];
+       u8 reserved14[96];      /* abs.ofs: 368 */
+
+/*
+ * 4965 Txpower calibration data.
+ */
+#define EEPROM_IWL_CALIB_TXPOWER_OFFSET        (2*0xE8)        /* 48  bytes */
+       struct iwl4965_eeprom_calib_info calib_info;    /* abs.ofs: 464 */
+
+       u8 reserved16[140];     /* fill out to full 1024 byte block */
+
+
+} __attribute__ ((packed));
+
+#define IWL_EEPROM_IMAGE_SIZE 1024
+
+/* End of EEPROM */
+
+#include "iwl-4965-commands.h"
+
+#define PCI_LINK_CTRL      0x0F0
+#define PCI_POWER_SOURCE   0x0C8
+#define PCI_REG_WUM8       0x0E8
+#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
+
+/*=== CSR (control and status registers) ===*/
+#define CSR_BASE    (0x000)
+
+#define CSR_SW_VER              (CSR_BASE+0x000)
+#define CSR_HW_IF_CONFIG_REG    (CSR_BASE+0x000) /* hardware interface config */
+#define CSR_INT_COALESCING      (CSR_BASE+0x004) /* accum ints, 32-usec units */
+#define CSR_INT                 (CSR_BASE+0x008) /* host interrupt status/ack */
+#define CSR_INT_MASK            (CSR_BASE+0x00c) /* host interrupt enable */
+#define CSR_FH_INT_STATUS       (CSR_BASE+0x010) /* busmaster int status/ack*/
+#define CSR_GPIO_IN             (CSR_BASE+0x018) /* read external chip pins */
+#define CSR_RESET               (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
+#define CSR_GP_CNTRL            (CSR_BASE+0x024)
+
+/*
+ * Hardware revision info
+ * Bit fields:
+ * 31-8:  Reserved
+ *  7-4:  Type of device:  0x0 = 4965, 0xd = 3945
+ *  3-2:  Revision step:  0 = A, 1 = B, 2 = C, 3 = D
+ *  1-0:  "Dash" value, as in A-1, etc.
+ *
+ * NOTE:  Revision step affects calculation of CCK txpower for 4965.
+ */
+#define CSR_HW_REV              (CSR_BASE+0x028)
+
+/* EEPROM reads */
+#define CSR_EEPROM_REG          (CSR_BASE+0x02c)
+#define CSR_EEPROM_GP           (CSR_BASE+0x030)
+#define CSR_GP_UCODE           (CSR_BASE+0x044)
+#define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
+#define CSR_UCODE_DRV_GP1_SET   (CSR_BASE+0x058)
+#define CSR_UCODE_DRV_GP1_CLR   (CSR_BASE+0x05c)
+#define CSR_UCODE_DRV_GP2       (CSR_BASE+0x060)
+#define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
+
+/*
+ * Indicates hardware rev, to determine CCK backoff for txpower calculation.
+ * Bit fields:
+ *  3-2:  0 = A, 1 = B, 2 = C, 3 = D step
+ */
+#define CSR_HW_REV_WA_REG      (CSR_BASE+0x22C)
+
+/* Hardware interface configuration bits */
+#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R      (0x00000010)
+#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER     (0x00000C00)
+#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI                (0x00000100)
+#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI      (0x00000200)
+#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
+
+/* 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_FH_TX        (1 << 27) /* Tx DMA FH_INT[1:0] */
+#define CSR_INT_BIT_MAC_CLK_ACTV (1 << 26) /* NIC controller's clock toggled on/off */
+#define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
+#define CSR_INT_BIT_RF_KILL      (1 << 7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
+#define CSR_INT_BIT_CT_KILL      (1 << 6)  /* Critical temp (chip too hot) rfkill */
+#define CSR_INT_BIT_SW_RX        (1 << 3)  /* Rx, command responses, 3945 */
+#define CSR_INT_BIT_WAKEUP       (1 << 1)  /* NIC controller waking up (pwr mgmt) */
+#define CSR_INT_BIT_ALIVE        (1 << 0)  /* uCode interrupts once it initializes */
+
+#define CSR_INI_SET_MASK       (CSR_INT_BIT_FH_RX   | \
+                                CSR_INT_BIT_HW_ERR  | \
+                                CSR_INT_BIT_FH_TX   | \
+                                CSR_INT_BIT_SW_ERR  | \
+                                CSR_INT_BIT_RF_KILL | \
+                                CSR_INT_BIT_SW_RX   | \
+                                CSR_INT_BIT_WAKEUP  | \
+                                CSR_INT_BIT_ALIVE)
+
+/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
+#define CSR_FH_INT_BIT_ERR       (1 << 31) /* Error */
+#define CSR_FH_INT_BIT_HI_PRIOR  (1 << 30) /* High priority Rx, bypass coalescing */
+#define CSR_FH_INT_BIT_RX_CHNL1  (1 << 17) /* Rx channel 1 */
+#define CSR_FH_INT_BIT_RX_CHNL0  (1 << 16) /* Rx channel 0 */
+#define CSR_FH_INT_BIT_TX_CHNL1  (1 << 1)  /* Tx channel 1 */
+#define CSR_FH_INT_BIT_TX_CHNL0  (1 << 0)  /* Tx channel 0 */
+
+#define CSR_FH_INT_RX_MASK     (CSR_FH_INT_BIT_HI_PRIOR | \
+                                CSR_FH_INT_BIT_RX_CHNL1 | \
+                                CSR_FH_INT_BIT_RX_CHNL0)
+
+#define CSR_FH_INT_TX_MASK     (CSR_FH_INT_BIT_TX_CHNL1 | \
+                                CSR_FH_INT_BIT_TX_CHNL0)
+
+
+/* RESET */
+#define CSR_RESET_REG_FLAG_NEVO_RESET                (0x00000001)
+#define CSR_RESET_REG_FLAG_FORCE_NMI                 (0x00000002)
+#define CSR_RESET_REG_FLAG_SW_RESET                  (0x00000080)
+#define CSR_RESET_REG_FLAG_MASTER_DISABLED           (0x00000100)
+#define CSR_RESET_REG_FLAG_STOP_MASTER               (0x00000200)
+
+/* GP (general purpose) CONTROL */
+#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY        (0x00000001)
+#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE              (0x00000004)
+#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ         (0x00000008)
+#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP         (0x00000010)
+
+#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN           (0x00000001)
+
+#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE         (0x07000000)
+#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE         (0x04000000)
+#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW          (0x08000000)
+
+
+/* EEPROM REG */
+#define CSR_EEPROM_REG_READ_VALID_MSK  (0x00000001)
+#define CSR_EEPROM_REG_BIT_CMD         (0x00000002)
+
+/* EEPROM GP */
+#define CSR_EEPROM_GP_VALID_MSK                (0x00000006)
+#define CSR_EEPROM_GP_BAD_SIGNATURE    (0x00000000)
+#define CSR_EEPROM_GP_IF_OWNER_MSK     (0x00000180)
+
+/* UCODE DRV GP */
+#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP             (0x00000001)
+#define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
+#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
+#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT      (0x00000008)
+
+/* GPIO */
+#define CSR_GPIO_IN_BIT_AUX_POWER                   (0x00000200)
+#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC                (0x00000000)
+#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC          CSR_GPIO_IN_BIT_AUX_POWER
+
+/* GI Chicken Bits */
+#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
+#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER  (0x20000000)
+
+/*=== HBUS (Host-side Bus) ===*/
+#define HBUS_BASE      (0x400)
+
+/*
+ * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM
+ * structures, error log, event log, verifying uCode load).
+ * First write to address register, then read from or write to data register
+ * to complete the job.  Once the address register is set up, accesses to
+ * data registers auto-increment the address by one dword.
+ * Bit usage for address registers (read or write):
+ *  0-31:  memory address within device
+ */
+#define HBUS_TARG_MEM_RADDR     (HBUS_BASE+0x00c)
+#define HBUS_TARG_MEM_WADDR     (HBUS_BASE+0x010)
+#define HBUS_TARG_MEM_WDAT      (HBUS_BASE+0x018)
+#define HBUS_TARG_MEM_RDAT      (HBUS_BASE+0x01c)
+
+/*
+ * Registers for accessing device's internal peripheral registers
+ * (e.g. SCD, BSM, etc.).  First write to address register,
+ * then read from or write to data register to complete the job.
+ * Bit usage for address registers (read or write):
+ *  0-15:  register address (offset) within device
+ * 24-25:  (# bytes - 1) to read or write (e.g. 3 for dword)
+ */
+#define HBUS_TARG_PRPH_WADDR    (HBUS_BASE+0x044)
+#define HBUS_TARG_PRPH_RADDR    (HBUS_BASE+0x048)
+#define HBUS_TARG_PRPH_WDAT     (HBUS_BASE+0x04c)
+#define HBUS_TARG_PRPH_RDAT     (HBUS_BASE+0x050)
+
+/*
+ * Per-Tx-queue write pointer (index, really!) (3945 and 4965).
+ * Driver sets this to indicate index to next TFD that driver will fill
+ * (1 past latest filled).
+ * Bit usage:
+ *  0-7:  queue write index (0-255)
+ * 11-8:  queue selector (0-15)
+ */
+#define HBUS_TARG_WRPTR         (HBUS_BASE+0x060)
+
+#define HBUS_TARG_MBX_C         (HBUS_BASE+0x030)
+
+#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED         (0x00000004)
+
+#define TFD_QUEUE_SIZE_MAX      (256)
+
+#define IWL_NUM_SCAN_RATES         (2)
+
+#define IWL_DEFAULT_TX_RETRY  15
+
+#define RX_QUEUE_SIZE                         256
+#define RX_QUEUE_MASK                         255
+#define RX_QUEUE_SIZE_LOG                     8
+
+#define TFD_TX_CMD_SLOTS 256
+#define TFD_CMD_SLOTS 32
+
+#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \
+                             sizeof(struct iwl4965_cmd_meta))
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+/* Size of one Rx buffer in host DRAM */
+#define IWL_RX_BUF_SIZE_4K (4 * 1024)
+#define IWL_RX_BUF_SIZE_8K (8 * 1024)
+
+/* Sizes and addresses for instruction and data memory (SRAM) in
+ * 4965's embedded processor.  Driver access is via HBUS_TARG_MEM_* regs. */
+#define RTC_INST_LOWER_BOUND                   (0x000000)
 #define KDR_RTC_INST_UPPER_BOUND               (0x018000)
+
+#define RTC_DATA_LOWER_BOUND                   (0x800000)
 #define KDR_RTC_DATA_UPPER_BOUND               (0x80A000)
+
 #define KDR_RTC_INST_SIZE    (KDR_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND)
 #define KDR_RTC_DATA_SIZE    (KDR_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND)
 
 #define IWL_MAX_INST_SIZE KDR_RTC_INST_SIZE
 #define IWL_MAX_DATA_SIZE KDR_RTC_DATA_SIZE
 
-static inline int iwl_hw_valid_rtc_data_addr(u32 addr)
+/* Size of uCode instruction memory in bootstrap state machine */
+#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE
+
+static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
 {
        return (addr >= RTC_DATA_LOWER_BOUND) &&
               (addr < KDR_RTC_DATA_UPPER_BOUND);
 }
 
-/********************* START TXPOWER *****************************************/
-enum {
-       HT_IE_EXT_CHANNEL_NONE = 0,
-       HT_IE_EXT_CHANNEL_ABOVE,
-       HT_IE_EXT_CHANNEL_INVALID,
-       HT_IE_EXT_CHANNEL_BELOW,
-       HT_IE_EXT_CHANNEL_MAX
-};
-
-enum {
-       CALIB_CH_GROUP_1 = 0,
-       CALIB_CH_GROUP_2 = 1,
-       CALIB_CH_GROUP_3 = 2,
-       CALIB_CH_GROUP_4 = 3,
-       CALIB_CH_GROUP_5 = 4,
-       CALIB_CH_GROUP_MAX
-};
+/********************* START TEMPERATURE *************************************/
 
-/* Temperature calibration offset is 3% 0C in Kelvin */
+/**
+ * 4965 temperature calculation.
+ *
+ * The driver must calculate the device temperature before calculating
+ * a txpower setting (amplifier gain is temperature dependent).  The
+ * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration
+ * values used for the life of the driver, and one of which (R4) is the
+ * real-time temperature indicator.
+ *
+ * uCode provides all 4 values to the driver via the "initialize alive"
+ * notification (see struct iwl4965_init_alive_resp).  After the runtime uCode
+ * image loads, uCode updates the R4 value via statistics notifications
+ * (see STATISTICS_NOTIFICATION), which occur after each received beacon
+ * when associated, or can be requested via REPLY_STATISTICS_CMD.
+ *
+ * NOTE:  uCode provides the R4 value as a 23-bit signed value.  Driver
+ *        must sign-extend to 32 bits before applying formula below.
+ *
+ * Formula:
+ *
+ * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8
+ *
+ * NOTE:  The basic formula is 259 * (R4-R2) / (R3-R1).  The 97/100 is
+ * an additional correction, which should be centered around 0 degrees
+ * Celsius (273 degrees Kelvin).  The 8 (3 percent of 273) compensates for
+ * centering the 97/100 correction around 0 degrees K.
+ *
+ * Add 273 to Kelvin value to find degrees Celsius, for comparing current
+ * temperature with factory-measured temperatures when calculating txpower
+ * settings.
+ */
 #define TEMPERATURE_CALIB_KELVIN_OFFSET 8
 #define TEMPERATURE_CALIB_A_VAL 259
 
+/* Limit range of calculated temperature to be between these Kelvin values */
 #define IWL_TX_POWER_TEMPERATURE_MIN  (263)
 #define IWL_TX_POWER_TEMPERATURE_MAX  (410)
 
@@ -109,228 +679,875 @@ enum {
        (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \
         ((t) > IWL_TX_POWER_TEMPERATURE_MAX))
 
-#define IWL_TX_POWER_ILLEGAL_TEMPERATURE (300)
+/********************* END TEMPERATURE ***************************************/
 
-#define IWL_TX_POWER_TEMPERATURE_DIFFERENCE (2)
+/********************* START TXPOWER *****************************************/
 
-#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6)
+/**
+ * 4965 txpower calculations rely on information from three sources:
+ *
+ *     1) EEPROM
+ *     2) "initialize" alive notification
+ *     3) statistics notifications
+ *
+ * EEPROM data consists of:
+ *
+ * 1)  Regulatory information (max txpower and channel usage flags) is provided
+ *     separately for each channel that can possibly supported by 4965.
+ *     40 MHz wide (.11n fat) channels are listed separately from 20 MHz
+ *     (legacy) channels.
+ *
+ *     See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom
+ *     for locations in EEPROM.
+ *
+ * 2)  Factory txpower calibration information is provided separately for
+ *     sub-bands of contiguous channels.  2.4GHz has just one sub-band,
+ *     but 5 GHz has several sub-bands.
+ *
+ *     In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided.
+ *
+ *     See struct iwl4965_eeprom_calib_info (and the tree of structures
+ *     contained within it) for format, and struct iwl4965_eeprom for
+ *     locations in EEPROM.
+ *
+ * "Initialization alive" notification (see struct iwl4965_init_alive_resp)
+ * consists of:
+ *
+ * 1)  Temperature calculation parameters.
+ *
+ * 2)  Power supply voltage measurement.
+ *
+ * 3)  Tx gain compensation to balance 2 transmitters for MIMO use.
+ *
+ * Statistics notifications deliver:
+ *
+ * 1)  Current values for temperature param R4.
+ */
+
+/**
+ * To calculate a txpower setting for a given desired target txpower, channel,
+ * modulation bit rate, and transmitter chain (4965 has 2 transmitters to
+ * support MIMO and transmit diversity), driver must do the following:
+ *
+ * 1)  Compare desired txpower vs. (EEPROM) regulatory limit for this channel.
+ *     Do not exceed regulatory limit; reduce target txpower if necessary.
+ *
+ *     If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31),
+ *     2 transmitters will be used simultaneously; driver must reduce the
+ *     regulatory limit by 3 dB (half-power) for each transmitter, so the
+ *     combined total output of the 2 transmitters is within regulatory limits.
+ *
+ *
+ * 2)  Compare target txpower vs. (EEPROM) saturation txpower *reduced by
+ *     backoff for this bit rate*.  Do not exceed (saturation - backoff[rate]);
+ *     reduce target txpower if necessary.
+ *
+ *     Backoff values below are in 1/2 dB units (equivalent to steps in
+ *     txpower gain tables):
+ *
+ *     OFDM 6 - 36 MBit:  10 steps (5 dB)
+ *     OFDM 48 MBit:      15 steps (7.5 dB)
+ *     OFDM 54 MBit:      17 steps (8.5 dB)
+ *     OFDM 60 MBit:      20 steps (10 dB)
+ *     CCK all rates:     10 steps (5 dB)
+ *
+ *     Backoff values apply to saturation txpower on a per-transmitter basis;
+ *     when using MIMO (2 transmitters), each transmitter uses the same
+ *     saturation level provided in EEPROM, and the same backoff values;
+ *     no reduction (such as with regulatory txpower limits) is required.
+ *
+ *     Saturation and Backoff values apply equally to 20 Mhz (legacy) channel
+ *     widths and 40 Mhz (.11n fat) channel widths; there is no separate
+ *     factory measurement for fat channels.
+ *
+ *     The result of this step is the final target txpower.  The rest of
+ *     the steps figure out the proper settings for the device to achieve
+ *     that target txpower.
+ *
+ *
+ * 3)  Determine (EEPROM) calibration subband for the target channel, by
+ *     comparing against first and last channels in each subband
+ *     (see struct iwl4965_eeprom_calib_subband_info).
+ *
+ *
+ * 4)  Linearly interpolate (EEPROM) factory calibration measurement sets,
+ *     referencing the 2 factory-measured (sample) channels within the subband.
+ *
+ *     Interpolation is based on difference between target channel's frequency
+ *     and the sample channels' frequencies.  Since channel numbers are based
+ *     on frequency (5 MHz between each channel number), this is equivalent
+ *     to interpolating based on channel number differences.
+ *
+ *     Note that the sample channels may or may not be the channels at the
+ *     edges of the subband.  The target channel may be "outside" of the
+ *     span of the sampled channels.
+ *
+ *     Driver may choose the pair (for 2 Tx chains) of measurements (see
+ *     struct iwl4965_eeprom_calib_ch_info) for which the actual measured
+ *     txpower comes closest to the desired txpower.  Usually, though,
+ *     the middle set of measurements is closest to the regulatory limits,
+ *     and is therefore a good choice for all txpower calculations (this
+ *     assumes that high accuracy is needed for maximizing legal txpower,
+ *     while lower txpower configurations do not need as much accuracy).
+ *
+ *     Driver should interpolate both members of the chosen measurement pair,
+ *     i.e. for both Tx chains (radio transmitters), unless the driver knows
+ *     that only one of the chains will be used (e.g. only one tx antenna
+ *     connected, but this should be unusual).  The rate scaling algorithm
+ *     switches antennas to find best performance, so both Tx chains will
+ *     be used (although only one at a time) even for non-MIMO transmissions.
+ *
+ *     Driver should interpolate factory values for temperature, gain table
+ *     index, and actual power.  The power amplifier detector values are
+ *     not used by the driver.
+ *
+ *     Sanity check:  If the target channel happens to be one of the sample
+ *     channels, the results should agree with the sample channel's
+ *     measurements!
+ *
+ *
+ * 5)  Find difference between desired txpower and (interpolated)
+ *     factory-measured txpower.  Using (interpolated) factory gain table index
+ *     (shown elsewhere) as a starting point, adjust this index lower to
+ *     increase txpower, or higher to decrease txpower, until the target
+ *     txpower is reached.  Each step in the gain table is 1/2 dB.
+ *
+ *     For example, if factory measured txpower is 16 dBm, and target txpower
+ *     is 13 dBm, add 6 steps to the factory gain index to reduce txpower
+ *     by 3 dB.
+ *
+ *
+ * 6)  Find difference between current device temperature and (interpolated)
+ *     factory-measured temperature for sub-band.  Factory values are in
+ *     degrees Celsius.  To calculate current temperature, see comments for
+ *     "4965 temperature calculation".
+ *
+ *     If current temperature is higher than factory temperature, driver must
+ *     increase gain (lower gain table index), and vice versa.
+ *
+ *     Temperature affects gain differently for different channels:
+ *
+ *     2.4 GHz all channels:  3.5 degrees per half-dB step
+ *     5 GHz channels 34-43:  4.5 degrees per half-dB step
+ *     5 GHz channels >= 44:  4.0 degrees per half-dB step
+ *
+ *     NOTE:  Temperature can increase rapidly when transmitting, especially
+ *            with heavy traffic at high txpowers.  Driver should update
+ *            temperature calculations often under these conditions to
+ *            maintain strong txpower in the face of rising temperature.
+ *
+ *
+ * 7)  Find difference between current power supply voltage indicator
+ *     (from "initialize alive") and factory-measured power supply voltage
+ *     indicator (EEPROM).
+ *
+ *     If the current voltage is higher (indicator is lower) than factory
+ *     voltage, gain should be reduced (gain table index increased) by:
+ *
+ *     (eeprom - current) / 7
+ *
+ *     If the current voltage is lower (indicator is higher) than factory
+ *     voltage, gain should be increased (gain table index decreased) by:
+ *
+ *     2 * (current - eeprom) / 7
+ *
+ *     If number of index steps in either direction turns out to be > 2,
+ *     something is wrong ... just use 0.
+ *
+ *     NOTE:  Voltage compensation is independent of band/channel.
+ *
+ *     NOTE:  "Initialize" uCode measures current voltage, which is assumed
+ *            to be constant after this initial measurement.  Voltage
+ *            compensation for txpower (number of steps in gain table)
+ *            may be calculated once and used until the next uCode bootload.
+ *
+ *
+ * 8)  If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31),
+ *     adjust txpower for each transmitter chain, so txpower is balanced
+ *     between the two chains.  There are 5 pairs of tx_atten[group][chain]
+ *     values in "initialize alive", one pair for each of 5 channel ranges:
+ *
+ *     Group 0:  5 GHz channel 34-43
+ *     Group 1:  5 GHz channel 44-70
+ *     Group 2:  5 GHz channel 71-124
+ *     Group 3:  5 GHz channel 125-200
+ *     Group 4:  2.4 GHz all channels
+ *
+ *     Add the tx_atten[group][chain] value to the index for the target chain.
+ *     The values are signed, but are in pairs of 0 and a non-negative number,
+ *     so as to reduce gain (if necessary) of the "hotter" channel.  This
+ *     avoids any need to double-check for regulatory compliance after
+ *     this step.
+ *
+ *
+ * 9)  If setting up for a CCK rate, lower the gain by adding a CCK compensation
+ *     value to the index:
+ *
+ *     Hardware rev B:  9 steps (4.5 dB)
+ *     Hardware rev C:  5 steps (2.5 dB)
+ *
+ *     Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG,
+ *     bits [3:2], 1 = B, 2 = C.
+ *
+ *     NOTE:  This compensation is in addition to any saturation backoff that
+ *            might have been applied in an earlier step.
+ *
+ *
+ * 10) Select the gain table, based on band (2.4 vs 5 GHz).
+ *
+ *     Limit the adjusted index to stay within the table!
+ *
+ *
+ * 11) Read gain table entries for DSP and radio gain, place into appropriate
+ *     location(s) in command (struct iwl4965_txpowertable_cmd).
+ */
 
+/* Limit range of txpower output target to be between these values */
 #define IWL_TX_POWER_TARGET_POWER_MIN       (0)        /* 0 dBm = 1 milliwatt */
 #define IWL_TX_POWER_TARGET_POWER_MAX      (16)        /* 16 dBm */
 
-/* timeout equivalent to 3 minutes */
-#define IWL_TX_POWER_TIMELIMIT_NOCALIB 1800000000
-
-#define IWL_TX_POWER_CCK_COMPENSATION (9)
-
-#define MIN_TX_GAIN_INDEX              (0)
-#define MIN_TX_GAIN_INDEX_52GHZ_EXT    (-9)
-#define MAX_TX_GAIN_INDEX_52GHZ                (98)
-#define MIN_TX_GAIN_52GHZ              (98)
-#define MAX_TX_GAIN_INDEX_24GHZ                (98)
-#define MIN_TX_GAIN_24GHZ              (98)
-#define MAX_TX_GAIN                    (0)
-#define MAX_TX_GAIN_52GHZ_EXT          (-9)
+/**
+ * When MIMO is used (2 transmitters operating simultaneously), driver should
+ * limit each transmitter to deliver a max of 3 dB below the regulatory limit
+ * for the device.  That is, use half power for each transmitter, so total
+ * txpower is within regulatory limits.
+ *
+ * The value "6" represents number of steps in gain table to reduce power 3 dB.
+ * Each step is 1/2 dB.
+ */
+#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6)
 
+/**
+ * CCK gain compensation.
+ *
+ * When calculating txpowers for CCK, after making sure that the target power
+ * is within regulatory and saturation limits, driver must additionally
+ * back off gain by adding these values to the gain table index.
+ *
+ * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG,
+ * bits [3:2], 1 = B, 2 = C.
+ */
+#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9)
+#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5)
+
+/*
+ * 4965 power supply voltage compensation for txpower
+ */
+#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V   (7)
+
+/**
+ * Gain tables.
+ *
+ * The following tables contain pair of values for setting txpower, i.e.
+ * gain settings for the output of the device's digital signal processor (DSP),
+ * and for the analog gain structure of the transmitter.
+ *
+ * Each entry in the gain tables represents a step of 1/2 dB.  Note that these
+ * are *relative* steps, not indications of absolute output power.  Output
+ * power varies with temperature, voltage, and channel frequency, and also
+ * requires consideration of average power (to satisfy regulatory constraints),
+ * and peak power (to avoid distortion of the output signal).
+ *
+ * Each entry contains two values:
+ * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
+ *     linear value that multiplies the output of the digital signal processor,
+ *     before being sent to the analog radio.
+ * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
+ *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
+ *
+ * EEPROM contains factory calibration data for txpower.  This maps actual
+ * measured txpower levels to gain settings in the "well known" tables
+ * below ("well-known" means here that both factory calibration *and* the
+ * driver work with the same table).
+ *
+ * There are separate tables for 2.4 GHz and 5 GHz bands.  The 5 GHz table
+ * has an extension (into negative indexes), in case the driver needs to
+ * boost power setting for high device temperatures (higher than would be
+ * present during factory calibration).  A 5 Ghz EEPROM index of "40"
+ * corresponds to the 49th entry in the table used by the driver.
+ */
+#define MIN_TX_GAIN_INDEX              (0)  /* highest gain, lowest idx, 2.4 */
+#define MIN_TX_GAIN_INDEX_52GHZ_EXT    (-9) /* highest gain, lowest idx, 5 */
+
+/**
+ * 2.4 GHz gain table
+ *
+ * Index    Dsp gain   Radio gain
+ *   0        110         0x3f      (highest gain)
+ *   1        104         0x3f
+ *   2         98         0x3f
+ *   3        110         0x3e
+ *   4        104         0x3e
+ *   5         98         0x3e
+ *   6        110         0x3d
+ *   7        104         0x3d
+ *   8         98         0x3d
+ *   9        110         0x3c
+ *  10        104         0x3c
+ *  11         98         0x3c
+ *  12        110         0x3b
+ *  13        104         0x3b
+ *  14         98         0x3b
+ *  15        110         0x3a
+ *  16        104         0x3a
+ *  17         98         0x3a
+ *  18        110         0x39
+ *  19        104         0x39
+ *  20         98         0x39
+ *  21        110         0x38
+ *  22        104         0x38
+ *  23         98         0x38
+ *  24        110         0x37
+ *  25        104         0x37
+ *  26         98         0x37
+ *  27        110         0x36
+ *  28        104         0x36
+ *  29         98         0x36
+ *  30        110         0x35
+ *  31        104         0x35
+ *  32         98         0x35
+ *  33        110         0x34
+ *  34        104         0x34
+ *  35         98         0x34
+ *  36        110         0x33
+ *  37        104         0x33
+ *  38         98         0x33
+ *  39        110         0x32
+ *  40        104         0x32
+ *  41         98         0x32
+ *  42        110         0x31
+ *  43        104         0x31
+ *  44         98         0x31
+ *  45        110         0x30
+ *  46        104         0x30
+ *  47         98         0x30
+ *  48        110          0x6
+ *  49        104          0x6
+ *  50         98          0x6
+ *  51        110          0x5
+ *  52        104          0x5
+ *  53         98          0x5
+ *  54        110          0x4
+ *  55        104          0x4
+ *  56         98          0x4
+ *  57        110          0x3
+ *  58        104          0x3
+ *  59         98          0x3
+ *  60        110          0x2
+ *  61        104          0x2
+ *  62         98          0x2
+ *  63        110          0x1
+ *  64        104          0x1
+ *  65         98          0x1
+ *  66        110          0x0
+ *  67        104          0x0
+ *  68         98          0x0
+ *  69         97            0
+ *  70         96            0
+ *  71         95            0
+ *  72         94            0
+ *  73         93            0
+ *  74         92            0
+ *  75         91            0
+ *  76         90            0
+ *  77         89            0
+ *  78         88            0
+ *  79         87            0
+ *  80         86            0
+ *  81         85            0
+ *  82         84            0
+ *  83         83            0
+ *  84         82            0
+ *  85         81            0
+ *  86         80            0
+ *  87         79            0
+ *  88         78            0
+ *  89         77            0
+ *  90         76            0
+ *  91         75            0
+ *  92         74            0
+ *  93         73            0
+ *  94         72            0
+ *  95         71            0
+ *  96         70            0
+ *  97         69            0
+ *  98         68            0
+ */
+
+/**
+ * 5 GHz gain table
+ *
+ * Index    Dsp gain   Radio gain
+ *  -9               123         0x3F      (highest gain)
+ *  -8               117         0x3F
+ *  -7        110         0x3F
+ *  -6        104         0x3F
+ *  -5         98         0x3F
+ *  -4        110         0x3E
+ *  -3        104         0x3E
+ *  -2         98         0x3E
+ *  -1        110         0x3D
+ *   0        104         0x3D
+ *   1         98         0x3D
+ *   2        110         0x3C
+ *   3        104         0x3C
+ *   4         98         0x3C
+ *   5        110         0x3B
+ *   6        104         0x3B
+ *   7         98         0x3B
+ *   8        110         0x3A
+ *   9        104         0x3A
+ *  10         98         0x3A
+ *  11        110         0x39
+ *  12        104         0x39
+ *  13         98         0x39
+ *  14        110         0x38
+ *  15        104         0x38
+ *  16         98         0x38
+ *  17        110         0x37
+ *  18        104         0x37
+ *  19         98         0x37
+ *  20        110         0x36
+ *  21        104         0x36
+ *  22         98         0x36
+ *  23        110         0x35
+ *  24        104         0x35
+ *  25         98         0x35
+ *  26        110         0x34
+ *  27        104         0x34
+ *  28         98         0x34
+ *  29        110         0x33
+ *  30        104         0x33
+ *  31         98         0x33
+ *  32        110         0x32
+ *  33        104         0x32
+ *  34         98         0x32
+ *  35        110         0x31
+ *  36        104         0x31
+ *  37         98         0x31
+ *  38        110         0x30
+ *  39        104         0x30
+ *  40         98         0x30
+ *  41        110         0x25
+ *  42        104         0x25
+ *  43         98         0x25
+ *  44        110         0x24
+ *  45        104         0x24
+ *  46         98         0x24
+ *  47        110         0x23
+ *  48        104         0x23
+ *  49         98         0x23
+ *  50        110         0x22
+ *  51        104         0x18
+ *  52         98         0x18
+ *  53        110         0x17
+ *  54        104         0x17
+ *  55         98         0x17
+ *  56        110         0x16
+ *  57        104         0x16
+ *  58         98         0x16
+ *  59        110         0x15
+ *  60        104         0x15
+ *  61         98         0x15
+ *  62        110         0x14
+ *  63        104         0x14
+ *  64         98         0x14
+ *  65        110         0x13
+ *  66        104         0x13
+ *  67         98         0x13
+ *  68        110         0x12
+ *  69        104         0x08
+ *  70         98         0x08
+ *  71        110         0x07
+ *  72        104         0x07
+ *  73         98         0x07
+ *  74        110         0x06
+ *  75        104         0x06
+ *  76         98         0x06
+ *  77        110         0x05
+ *  78        104         0x05
+ *  79         98         0x05
+ *  80        110         0x04
+ *  81        104         0x04
+ *  82         98         0x04
+ *  83        110         0x03
+ *  84        104         0x03
+ *  85         98         0x03
+ *  86        110         0x02
+ *  87        104         0x02
+ *  88         98         0x02
+ *  89        110         0x01
+ *  90        104         0x01
+ *  91         98         0x01
+ *  92        110         0x00
+ *  93        104         0x00
+ *  94         98         0x00
+ *  95         93         0x00
+ *  96         88         0x00
+ *  97         83         0x00
+ *  98         78         0x00
+ */
+
+
+/**
+ * Sanity checks and default values for EEPROM regulatory levels.
+ * If EEPROM values fall outside MIN/MAX range, use default values.
+ *
+ * Regulatory limits refer to the maximum average txpower allowed by
+ * regulatory agencies in the geographies in which the device is meant
+ * to be operated.  These limits are SKU-specific (i.e. geography-specific),
+ * and channel-specific; each channel has an individual regulatory limit
+ * listed in the EEPROM.
+ *
+ * Units are in half-dBm (i.e. "34" means 17 dBm).
+ */
 #define IWL_TX_POWER_DEFAULT_REGULATORY_24   (34)
 #define IWL_TX_POWER_DEFAULT_REGULATORY_52   (34)
 #define IWL_TX_POWER_REGULATORY_MIN          (0)
 #define IWL_TX_POWER_REGULATORY_MAX          (34)
+
+/**
+ * Sanity checks and default values for EEPROM saturation levels.
+ * If EEPROM values fall outside MIN/MAX range, use default values.
+ *
+ * Saturation is the highest level that the output power amplifier can produce
+ * without significant clipping distortion.  This is a "peak" power level.
+ * Different types of modulation (i.e. various "rates", and OFDM vs. CCK)
+ * require differing amounts of backoff, relative to their average power output,
+ * in order to avoid clipping distortion.
+ *
+ * Driver must make sure that it is violating neither the saturation limit,
+ * nor the regulatory limit, when calculating Tx power settings for various
+ * rates.
+ *
+ * Units are in half-dBm (i.e. "38" means 19 dBm).
+ */
 #define IWL_TX_POWER_DEFAULT_SATURATION_24   (38)
 #define IWL_TX_POWER_DEFAULT_SATURATION_52   (38)
 #define IWL_TX_POWER_SATURATION_MIN          (20)
 #define IWL_TX_POWER_SATURATION_MAX          (50)
 
-/* dv *0.4 = dt; so that 5 degrees temperature diff equals
- * 12.5 in voltage diff */
-#define IWL_TX_TEMPERATURE_UPDATE_LIMIT 9
-
-#define IWL_INVALID_CHANNEL                 (0xffffffff)
-#define IWL_TX_POWER_REGITRY_BIT            (2)
-
-#define MIN_IWL_TX_POWER_CALIB_DUR          (100)
-#define IWL_CCK_FROM_OFDM_POWER_DIFF        (-5)
-#define IWL_CCK_FROM_OFDM_INDEX_DIFF (9)
-
-/* Number of entries in the gain table */
-#define POWER_GAIN_NUM_ENTRIES 78
-#define TX_POW_MAX_SESSION_NUM 5
-/*  timeout equivalent to 3 minutes */
-#define TX_IWL_TIMELIMIT_NOCALIB 1800000000
-
-/* Kedron TX_CALIB_STATES */
-#define IWL_TX_CALIB_STATE_SEND_TX        0x00000001
-#define IWL_TX_CALIB_WAIT_TX_RESPONSE     0x00000002
-#define IWL_TX_CALIB_ENABLED              0x00000004
-#define IWL_TX_CALIB_XVT_ON               0x00000008
-#define IWL_TX_CALIB_TEMPERATURE_CORRECT  0x00000010
-#define IWL_TX_CALIB_WORKING_WITH_XVT     0x00000020
-#define IWL_TX_CALIB_XVT_PERIODICAL       0x00000040
-
-#define NUM_IWL_TX_CALIB_SETTINS 5     /* Number of tx correction groups */
-
-#define IWL_MIN_POWER_IN_VP_TABLE 1    /* 0.5dBm multiplied by 2 */
-#define IWL_MAX_POWER_IN_VP_TABLE 40   /* 20dBm - multiplied by 2 (because
-                                        * entries are for each 0.5dBm) */
-#define IWL_STEP_IN_VP_TABLE 1 /* 0.5dB - multiplied by 2 */
-#define IWL_NUM_POINTS_IN_VPTABLE \
-       (1 + IWL_MAX_POWER_IN_VP_TABLE - IWL_MIN_POWER_IN_VP_TABLE)
-
-#define MIN_TX_GAIN_INDEX         (0)
-#define MAX_TX_GAIN_INDEX_52GHZ   (98)
-#define MIN_TX_GAIN_52GHZ         (98)
-#define MAX_TX_GAIN_INDEX_24GHZ   (98)
-#define MIN_TX_GAIN_24GHZ         (98)
-#define MAX_TX_GAIN               (0)
-
-/* First and last channels of all groups */
+/**
+ * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance)
+ * and thermal Txpower calibration.
+ *
+ * When calculating txpower, driver must compensate for current device
+ * temperature; higher temperature requires higher gain.  Driver must calculate
+ * current temperature (see "4965 temperature calculation"), then compare vs.
+ * factory calibration temperature in EEPROM; if current temperature is higher
+ * than factory temperature, driver must *increase* gain by proportions shown
+ * in table below.  If current temperature is lower than factory, driver must
+ * *decrease* gain.
+ *
+ * Different frequency ranges require different compensation, as shown below.
+ */
+/* Group 0, 5.2 GHz ch 34-43:  4.5 degrees per 1/2 dB. */
 #define CALIB_IWL_TX_ATTEN_GR1_FCH 34
 #define CALIB_IWL_TX_ATTEN_GR1_LCH 43
+
+/* Group 1, 5.3 GHz ch 44-70:  4.0 degrees per 1/2 dB. */
 #define CALIB_IWL_TX_ATTEN_GR2_FCH 44
 #define CALIB_IWL_TX_ATTEN_GR2_LCH 70
+
+/* Group 2, 5.5 GHz ch 71-124:  4.0 degrees per 1/2 dB. */
 #define CALIB_IWL_TX_ATTEN_GR3_FCH 71
 #define CALIB_IWL_TX_ATTEN_GR3_LCH 124
+
+/* Group 3, 5.7 GHz ch 125-200:  4.0 degrees per 1/2 dB. */
 #define CALIB_IWL_TX_ATTEN_GR4_FCH 125
 #define CALIB_IWL_TX_ATTEN_GR4_LCH 200
+
+/* Group 4, 2.4 GHz all channels:  3.5 degrees per 1/2 dB. */
 #define CALIB_IWL_TX_ATTEN_GR5_FCH 1
 #define CALIB_IWL_TX_ATTEN_GR5_LCH 20
 
-
-union iwl_tx_power_dual_stream {
-       struct {
-               u8 radio_tx_gain[2];
-               u8 dsp_predis_atten[2];
-       } s;
-       u32 dw;
+enum {
+       CALIB_CH_GROUP_1 = 0,
+       CALIB_CH_GROUP_2 = 1,
+       CALIB_CH_GROUP_3 = 2,
+       CALIB_CH_GROUP_4 = 3,
+       CALIB_CH_GROUP_5 = 4,
+       CALIB_CH_GROUP_MAX
 };
 
 /********************* END TXPOWER *****************************************/
 
-/* HT flags */
-#define RXON_FLG_CTRL_CHANNEL_LOC_POS          (22)
-#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK       __constant_cpu_to_le32(0x1<<22)
-
-#define RXON_FLG_HT_OPERATING_MODE_POS         (23)
-
-#define RXON_FLG_HT_PROT_MSK                   __constant_cpu_to_le32(0x1<<23)
-#define RXON_FLG_FAT_PROT_MSK                  __constant_cpu_to_le32(0x2<<23)
-
-#define RXON_FLG_CHANNEL_MODE_POS              (25)
-#define RXON_FLG_CHANNEL_MODE_MSK              __constant_cpu_to_le32(0x3<<25)
-#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK      __constant_cpu_to_le32(0x1<<25)
-#define RXON_FLG_CHANNEL_MODE_MIXED_MSK                __constant_cpu_to_le32(0x2<<25)
-
-#define RXON_RX_CHAIN_DRIVER_FORCE_MSK         __constant_cpu_to_le16(0x1<<0)
-#define RXON_RX_CHAIN_VALID_MSK                        __constant_cpu_to_le16(0x7<<1)
-#define RXON_RX_CHAIN_VALID_POS                        (1)
-#define RXON_RX_CHAIN_FORCE_SEL_MSK            __constant_cpu_to_le16(0x7<<4)
-#define RXON_RX_CHAIN_FORCE_SEL_POS            (4)
-#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK       __constant_cpu_to_le16(0x7<<7)
-#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS       (7)
-#define RXON_RX_CHAIN_CNT_MSK                  __constant_cpu_to_le16(0x3<<10)
-#define RXON_RX_CHAIN_CNT_POS                  (10)
-#define RXON_RX_CHAIN_MIMO_CNT_MSK             __constant_cpu_to_le16(0x3<<12)
-#define RXON_RX_CHAIN_MIMO_CNT_POS             (12)
-#define RXON_RX_CHAIN_MIMO_FORCE_MSK           __constant_cpu_to_le16(0x1<<14)
-#define RXON_RX_CHAIN_MIMO_FORCE_POS           (14)
-
-
-#define MCS_DUP_6M_PLCP 0x20
-
-/* OFDM HT rate masks */
-/* ***************************************** */
-#define R_MCS_6M_MSK 0x1
-#define R_MCS_12M_MSK 0x2
-#define R_MCS_18M_MSK 0x4
-#define R_MCS_24M_MSK 0x8
-#define R_MCS_36M_MSK 0x10
-#define R_MCS_48M_MSK 0x20
-#define R_MCS_54M_MSK 0x40
-#define R_MCS_60M_MSK 0x80
-#define R_MCS_12M_DUAL_MSK 0x100
-#define R_MCS_24M_DUAL_MSK 0x200
-#define R_MCS_36M_DUAL_MSK 0x400
-#define R_MCS_48M_DUAL_MSK 0x800
-
-#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
-#define is_siso(tbl) (((tbl) == LQ_SISO))
-#define is_mimo(tbl) (((tbl) == LQ_MIMO))
-#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
-#define is_a_band(tbl) (((tbl) == LQ_A))
-#define is_g_and(tbl) (((tbl) == LQ_G))
-
+/****************************/
 /* Flow Handler Definitions */
+/****************************/
 
-/**********************/
-/*     Addresses      */
-/**********************/
-
+/**
+ * This I/O area is directly read/writable by driver (e.g. Linux uses writel())
+ * Addresses are offsets from device's PCI hardware base address.
+ */
 #define FH_MEM_LOWER_BOUND                   (0x1000)
 #define FH_MEM_UPPER_BOUND                   (0x1EF0)
 
-#define IWL_FH_REGS_LOWER_BOUND                     (0x1000)
-#define IWL_FH_REGS_UPPER_BOUND                     (0x2000)
-
+/**
+ * Keep-Warm (KW) buffer base address.
+ *
+ * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
+ * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency
+ * DRAM access when 4965 is Txing or Rxing.  The dummy accesses prevent host
+ * from going into a power-savings mode that would cause higher DRAM latency,
+ * and possible data over/under-runs, before all Tx/Rx is complete.
+ *
+ * Driver loads IWL_FH_KW_MEM_ADDR_REG with the physical address (bits 35:4)
+ * of the buffer, which must be 4K aligned.  Once this is set up, the 4965
+ * automatically invokes keep-warm accesses when normal accesses might not
+ * be sufficient to maintain fast DRAM response.
+ *
+ * Bit fields:
+ *  31-0:  Keep-warm buffer physical base address [35:4], must be 4K aligned
+ */
 #define IWL_FH_KW_MEM_ADDR_REG              (FH_MEM_LOWER_BOUND + 0x97C)
 
-/* CBBC Area - Circular buffers base address cache pointers table */
+
+/**
+ * TFD Circular Buffers Base (CBBC) addresses
+ *
+ * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
+ * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs)
+ * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04
+ * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte
+ * aligned (address bits 0-7 must be 0).
+ *
+ * Bit fields in each pointer register:
+ *  27-0: TFD CB physical base address [35:8], must be 256-byte aligned
+ */
 #define FH_MEM_CBBC_LOWER_BOUND              (FH_MEM_LOWER_BOUND + 0x9D0)
 #define FH_MEM_CBBC_UPPER_BOUND              (FH_MEM_LOWER_BOUND + 0xA10)
-/* queues 0 - 15 */
+
+/* Find TFD CB base pointer for given queue (range 0-15). */
 #define FH_MEM_CBBC_QUEUE(x)  (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4)
 
-/* RSCSR Area */
+
+/**
+ * Rx SRAM Control and Status Registers (RSCSR)
+ *
+ * These registers provide handshake between driver and 4965 for the Rx queue
+ * (this queue handles *all* command responses, notifications, Rx data, etc.
+ * sent from 4965 uCode to host driver).  Unlike Tx, there is only one Rx
+ * queue, and only one Rx DMA/FIFO channel.  Also unlike Tx, which can
+ * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer
+ * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1
+ * mapping between RBDs and RBs.
+ *
+ * Driver must allocate host DRAM memory for the following, and set the
+ * physical address of each into 4965 registers:
+ *
+ * 1)  Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256
+ *     entries (although any power of 2, up to 4096, is selectable by driver).
+ *     Each entry (1 dword) points to a receive buffer (RB) of consistent size
+ *     (typically 4K, although 8K or 16K are also selectable by driver).
+ *     Driver sets up RB size and number of RBDs in the CB via Rx config
+ *     register FH_MEM_RCSR_CHNL0_CONFIG_REG.
+ *
+ *     Bit fields within one RBD:
+ *     27-0:  Receive Buffer physical address bits [35:8], 256-byte aligned
+ *
+ *     Driver sets physical address [35:8] of base of RBD circular buffer
+ *     into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0].
+ *
+ * 2)  Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers
+ *     (RBs) have been filled, via a "write pointer", actually the index of
+ *     the RB's corresponding RBD within the circular buffer.  Driver sets
+ *     physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0].
+ *
+ *     Bit fields in lower dword of Rx status buffer (upper dword not used
+ *     by driver; see struct iwl4965_shared, val0):
+ *     31-12:  Not used by driver
+ *     11- 0:  Index of last filled Rx buffer descriptor
+ *             (4965 writes, driver reads this value)
+ *
+ * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
+ * enter pointers to these RBs into contiguous RBD circular buffer entries,
+ * and update the 4965's "write" index register, FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
+ *
+ * This "write" index corresponds to the *next* RBD that the driver will make
+ * available, i.e. one RBD past the tail of the ready-to-fill RBDs within
+ * the circular buffer.  This value should initially be 0 (before preparing any
+ * RBs), should be 8 after preparing the first 8 RBs (for example), and must
+ * wrap back to 0 at the end of the circular buffer (but don't wrap before
+ * "read" index has advanced past 1!  See below).
+ * NOTE:  4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
+ *
+ * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
+ * buffer), it updates the Rx status buffer in host DRAM, 2) described above,
+ * to tell the driver the index of the latest filled RBD.  The driver must
+ * read this "read" index from DRAM after receiving an Rx interrupt from 4965.
+ *
+ * The driver must also internally keep track of a third index, which is the
+ * next RBD to process.  When receiving an Rx interrupt, driver should process
+ * all filled but unprocessed RBs up to, but not including, the RB
+ * corresponding to the "read" index.  For example, if "read" index becomes "1",
+ * driver may process the RB pointed to by RBD 0.  Depending on volume of
+ * traffic, there may be many RBs to process.
+ *
+ * If read index == write index, 4965 thinks there is no room to put new data.
+ * Due to this, the maximum number of filled RBs is 255, instead of 256.  To
+ * be safe, make sure that there is a gap of at least 2 RBDs between "write"
+ * and "read" indexes; that is, make sure that there are no more than 254
+ * buffers waiting to be filled.
+ */
 #define FH_MEM_RSCSR_LOWER_BOUND       (FH_MEM_LOWER_BOUND + 0xBC0)
 #define FH_MEM_RSCSR_UPPER_BOUND       (FH_MEM_LOWER_BOUND + 0xC00)
 #define FH_MEM_RSCSR_CHNL0             (FH_MEM_RSCSR_LOWER_BOUND)
 
+/**
+ * Physical base address of 8-byte Rx Status buffer.
+ * Bit fields:
+ *  31-0: Rx status buffer physical base address [35:4], must 16-byte aligned.
+ */
 #define FH_RSCSR_CHNL0_STTS_WPTR_REG           (FH_MEM_RSCSR_CHNL0)
+
+/**
+ * Physical base address of Rx Buffer Descriptor Circular Buffer.
+ * Bit fields:
+ *  27-0:  RBD CD physical base address [35:8], must be 256-byte aligned.
+ */
 #define FH_RSCSR_CHNL0_RBDCB_BASE_REG          (FH_MEM_RSCSR_CHNL0 + 0x004)
+
+/**
+ * Rx write pointer (index, really!).
+ * Bit fields:
+ *  11-0:  Index of driver's most recent prepared-to-be-filled RBD, + 1.
+ *         NOTE:  For 256-entry circular buffer, use only bits [7:0].
+ */
 #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG          (FH_MEM_RSCSR_CHNL0 + 0x008)
+#define FH_RSCSR_CHNL0_WPTR        (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
+
 
-/* RCSR Area - Registers address map */
+/**
+ * Rx Config/Status Registers (RCSR)
+ * Rx Config Reg for channel 0 (only channel used)
+ *
+ * Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for
+ * normal operation (see bit fields).
+ *
+ * Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA.
+ * Driver should poll FH_MEM_RSSR_RX_STATUS_REG        for
+ * FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing.
+ *
+ * Bit fields:
+ * 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame,
+ *        '10' operate normally
+ * 29-24: reserved
+ * 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal),
+ *        min "5" for 32 RBDs, max "12" for 4096 RBDs.
+ * 19-18: reserved
+ * 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K,
+ *        '10' 12K, '11' 16K.
+ * 15-14: reserved
+ * 13-12: IRQ destination; '00' none, '01' host driver (normal operation)
+ * 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec)
+ *        typical value 0x10 (about 1/2 msec)
+ *  3- 0: reserved
+ */
 #define FH_MEM_RCSR_LOWER_BOUND      (FH_MEM_LOWER_BOUND + 0xC00)
 #define FH_MEM_RCSR_UPPER_BOUND      (FH_MEM_LOWER_BOUND + 0xCC0)
 #define FH_MEM_RCSR_CHNL0            (FH_MEM_RCSR_LOWER_BOUND)
 
 #define FH_MEM_RCSR_CHNL0_CONFIG_REG   (FH_MEM_RCSR_CHNL0)
 
-/* RSSR Area - Rx shared ctrl & status registers */
+#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK   (0x00000FF0) /* bit 4-11 */
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK     (0x00001000) /* bit 12 */
+#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000) /* bit 15 */
+#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK     (0x00030000) /* bits 16-17 */
+#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK   (0x00F00000) /* bits 20-23 */
+#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK  (0xC0000000) /* bits 30-31 */
+
+#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT  (20)
+#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT        (4)
+#define RX_RB_TIMEOUT  (0x10)
+
+#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL         (0x00000000)
+#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL     (0x40000000)
+#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL        (0x80000000)
+
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K    (0x00000000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K    (0x00010000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K   (0x00020000)
+#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K   (0x00030000)
+
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL       (0x00000000)
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL     (0x00001000)
+
+
+/**
+ * Rx Shared Status Registers (RSSR)
+ *
+ * After stopping Rx DMA channel (writing 0 to FH_MEM_RCSR_CHNL0_CONFIG_REG),
+ * driver must poll FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle.
+ *
+ * Bit fields:
+ *  24:  1 = Channel 0 is idle
+ *
+ * FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV contain
+ * default values that should not be altered by the driver.
+ */
 #define FH_MEM_RSSR_LOWER_BOUND                        (FH_MEM_LOWER_BOUND + 0xC40)
 #define FH_MEM_RSSR_UPPER_BOUND                (FH_MEM_LOWER_BOUND + 0xD00)
+
 #define FH_MEM_RSSR_SHARED_CTRL_REG            (FH_MEM_RSSR_LOWER_BOUND)
 #define FH_MEM_RSSR_RX_STATUS_REG      (FH_MEM_RSSR_LOWER_BOUND + 0x004)
 #define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV  (FH_MEM_RSSR_LOWER_BOUND + 0x008)
 
-/* TCSR */
-#define IWL_FH_TCSR_LOWER_BOUND  (IWL_FH_REGS_LOWER_BOUND + 0xD00)
-#define IWL_FH_TCSR_UPPER_BOUND  (IWL_FH_REGS_LOWER_BOUND + 0xE60)
+#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE      (0x01000000)
+
 
-#define IWL_FH_TCSR_CHNL_NUM                            (7)
+/**
+ * Transmit DMA Channel Control/Status Registers (TCSR)
+ *
+ * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
+ * supported in hardware (don't confuse these with the 16 Tx queues in DRAM,
+ * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes.
+ *
+ * To use a Tx DMA channel, driver must initialize its
+ * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl) with:
+ *
+ * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
+ * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL
+ *
+ * All other bits should be 0.
+ *
+ * Bit fields:
+ * 31-30: Tx DMA channel enable: '00' off/pause, '01' pause at end of frame,
+ *        '10' operate normally
+ * 29- 4: Reserved, set to "0"
+ *     3: Enable internal DMA requests (1, normal operation), disable (0)
+ *  2- 0: Reserved, set to "0"
+ */
+#define IWL_FH_TCSR_LOWER_BOUND  (FH_MEM_LOWER_BOUND + 0xD00)
+#define IWL_FH_TCSR_UPPER_BOUND  (FH_MEM_LOWER_BOUND + 0xE60)
+
+/* Find Control/Status reg for given Tx DMA/FIFO channel */
 #define IWL_FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \
        (IWL_FH_TCSR_LOWER_BOUND + 0x20 * _chnl)
 
-/* TSSR Area - Tx shared status registers */
-/* TSSR */
-#define IWL_FH_TSSR_LOWER_BOUND                (IWL_FH_REGS_LOWER_BOUND + 0xEA0)
-#define IWL_FH_TSSR_UPPER_BOUND                (IWL_FH_REGS_LOWER_BOUND + 0xEC0)
-
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG  (IWL_FH_TSSR_LOWER_BOUND + 0x008)
-#define IWL_FH_TSSR_TX_STATUS_REG      (IWL_FH_TSSR_LOWER_BOUND + 0x010)
-
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON     (0xFF000000)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON     (0x00FF0000)
+#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
+#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
 
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_64B    (0x00000000)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B   (0x00000400)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_256B   (0x00000800)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_512B   (0x00000C00)
+#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
+#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF        (0x40000000)
+#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
 
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON      (0x00000100)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON      (0x00000080)
+/**
+ * Tx Shared Status Registers (TSSR)
+ *
+ * After stopping Tx DMA channel (writing 0 to
+ * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl)), driver must poll
+ * IWL_FH_TSSR_TX_STATUS_REG until selected Tx channel is idle
+ * (channel's buffers empty | no pending requests).
+ *
+ * Bit fields:
+ * 31-24:  1 = Channel buffers empty (channel 7:0)
+ * 23-16:  1 = No pending requests (channel 7:0)
+ */
+#define IWL_FH_TSSR_LOWER_BOUND                (FH_MEM_LOWER_BOUND + 0xEA0)
+#define IWL_FH_TSSR_UPPER_BOUND                (FH_MEM_LOWER_BOUND + 0xEC0)
 
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH    (0x00000020)
-#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH          (0x00000005)
+#define IWL_FH_TSSR_TX_STATUS_REG      (IWL_FH_TSSR_LOWER_BOUND + 0x010)
 
 #define IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl)        \
        ((1 << (_chnl)) << 24)
@@ -341,147 +1558,347 @@ union iwl_tx_power_dual_stream {
        (IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \
        IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl))
 
-/* TCSR: tx_config register values */
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF              (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER           (0x00000001)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_ARC              (0x00000002)
-
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
-
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT           (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD          (0x00100000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD           (0x00200000)
-
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT            (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_ENDTFD           (0x00400000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_IFTFD            (0x00800000)
 
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF        (0x40000000)
-#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
-
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY          (0x00000000)
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT           (0x00002000)
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID          (0x00000003)
-
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR           (0x00000001)
-
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM              (20)
-#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX              (12)
-
-/* RCSR:  channel 0 rx_config register defines */
-#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK  (0xC0000000) /* bits 30-31 */
-#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK   (0x00F00000) /* bits 20-23 */
-#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK     (0x00030000) /* bits 16-17 */
-#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000) /* bit 15 */
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK     (0x00001000) /* bit 12 */
-#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK   (0x00000FF0) /* bit 4-11 */
-
-#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT       (20)
-#define FH_RCSR_RX_CONFIG_RB_SIZE_BITSHIFT                     (16)
-
-/* RCSR: rx_config register values */
-#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL         (0x00000000)
-#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL     (0x40000000)
-#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL        (0x80000000)
-
-#define IWL_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K    (0x00000000)
-
-/* RCSR channel 0 config register values */
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL       (0x00000000)
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL     (0x00001000)
-
-/* RSCSR: defs used in normal mode */
-#define FH_RSCSR_CHNL0_RBDCB_WPTR_MASK         (0x00000FFF)    /* bits 0-11 */
+/********************* START TX SCHEDULER *************************************/
 
+/**
+ * 4965 Tx Scheduler
+ *
+ * The Tx Scheduler selects the next frame to be transmitted, chosing TFDs
+ * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in
+ * host DRAM.  It steers each frame's Tx command (which contains the frame
+ * data) into one of up to 7 prioritized Tx DMA FIFO channels within the
+ * device.  A queue maps to only one (selectable by driver) Tx DMA channel,
+ * but one DMA channel may take input from several queues.
+ *
+ * Tx DMA channels have dedicated purposes.  For 4965, they are used as follows:
+ *
+ * 0 -- EDCA BK (background) frames, lowest priority
+ * 1 -- EDCA BE (best effort) frames, normal priority
+ * 2 -- EDCA VI (video) frames, higher priority
+ * 3 -- EDCA VO (voice) and management frames, highest priority
+ * 4 -- Commands (e.g. RXON, etc.)
+ * 5 -- HCCA short frames
+ * 6 -- HCCA long frames
+ * 7 -- not used by driver (device-internal only)
+ *
+ * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
+ * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to
+ * support 11n aggregation via EDCA DMA channels.
+ *
+ * The driver sets up each queue to work in one of two modes:
+ *
+ * 1)  Scheduler-Ack, in which the scheduler automatically supports a
+ *     block-ack (BA) window of up to 64 TFDs.  In this mode, each queue
+ *     contains TFDs for a unique combination of Recipient Address (RA)
+ *     and Traffic Identifier (TID), that is, traffic of a given
+ *     Quality-Of-Service (QOS) priority, destined for a single station.
+ *
+ *     In scheduler-ack mode, the scheduler keeps track of the Tx status of
+ *     each frame within the BA window, including whether it's been transmitted,
+ *     and whether it's been acknowledged by the receiving station.  The device
+ *     automatically processes block-acks received from the receiving STA,
+ *     and reschedules un-acked frames to be retransmitted (successful
+ *     Tx completion may end up being out-of-order).
+ *
+ *     The driver must maintain the queue's Byte Count table in host DRAM
+ *     (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode.
+ *     This mode does not support fragmentation.
+ *
+ * 2)  FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order.
+ *     The device may automatically retry Tx, but will retry only one frame
+ *     at a time, until receiving ACK from receiving station, or reaching
+ *     retry limit and giving up.
+ *
+ *     The command queue (#4) must use this mode!
+ *     This mode does not require use of the Byte Count table in host DRAM.
+ *
+ * Driver controls scheduler operation via 3 means:
+ * 1)  Scheduler registers
+ * 2)  Shared scheduler data base in internal 4956 SRAM
+ * 3)  Shared data in host DRAM
+ *
+ * Initialization:
+ *
+ * When loading, driver should allocate memory for:
+ * 1)  16 TFD circular buffers, each with space for (typically) 256 TFDs.
+ * 2)  16 Byte Count circular buffers in 16 KBytes contiguous memory
+ *     (1024 bytes for each queue).
+ *
+ * After receiving "Alive" response from uCode, driver must initialize
+ * the scheduler (especially for queue #4, the command queue, otherwise
+ * the driver can't issue commands!):
+ */
+
+/**
+ * Max Tx window size is the max number of contiguous TFDs that the scheduler
+ * can keep track of at one time when creating block-ack chains of frames.
+ * Note that "64" matches the number of ack bits in a block-ack packet.
+ * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
+ * SCD_CONTEXT_QUEUE_OFFSET(x) values.
+ */
 #define SCD_WIN_SIZE                           64
 #define SCD_FRAME_LIMIT                                64
 
-/* memory mapped registers */
+/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
 #define SCD_START_OFFSET               0xa02c00
 
+/*
+ * 4965 tells driver SRAM address for internal scheduler structs via this reg.
+ * Value is valid only after "Alive" response from uCode.
+ */
 #define SCD_SRAM_BASE_ADDR           (SCD_START_OFFSET + 0x0)
+
+/*
+ * Driver may need to update queue-empty bits after changing queue's
+ * write and read pointers (indexes) during (re-)initialization (i.e. when
+ * scheduler is not tracking what's happening).
+ * Bit fields:
+ * 31-16:  Write mask -- 1: update empty bit, 0: don't change empty bit
+ * 15-00:  Empty state, one for each queue -- 1: empty, 0: non-empty
+ * NOTE:  This register is not used by Linux driver.
+ */
 #define SCD_EMPTY_BITS               (SCD_START_OFFSET + 0x4)
+
+/*
+ * Physical base address of array of byte count (BC) circular buffers (CBs).
+ * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
+ * This register points to BC CB for queue 0, must be on 1024-byte boundary.
+ * Others are spaced by 1024 bytes.
+ * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
+ * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
+ * Bit fields:
+ * 25-00:  Byte Count CB physical address [35:10], must be 1024-byte aligned.
+ */
 #define SCD_DRAM_BASE_ADDR           (SCD_START_OFFSET + 0x10)
-#define SCD_AIT                      (SCD_START_OFFSET + 0x18)
+
+/*
+ * Enables any/all Tx DMA/FIFO channels.
+ * Scheduler generates requests for only the active channels.
+ * Set this to 0xff to enable all 8 channels (normal usage).
+ * Bit fields:
+ *  7- 0:  Enable (1), disable (0), one bit for each channel 0-7
+ */
 #define SCD_TXFACT                   (SCD_START_OFFSET + 0x1c)
+
+/* Mask to enable contiguous Tx DMA/FIFO channels between "lo" and "hi". */
+#define SCD_TXFACT_REG_TXFIFO_MASK(lo, hi) \
+       ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
+
+/*
+ * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
+ * Initialized and updated by driver as new TFDs are added to queue.
+ * NOTE:  If using Block Ack, index must correspond to frame's
+ *        Start Sequence Number; index = (SSN & 0xff)
+ * NOTE:  Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
+ */
 #define SCD_QUEUE_WRPTR(x)           (SCD_START_OFFSET + 0x24 + (x) * 4)
-#define SCD_QUEUE_RDPTR(x)           (SCD_START_OFFSET + 0x64 + (x) * 4)
-#define SCD_SETQUEUENUM              (SCD_START_OFFSET + 0xa4)
-#define SCD_SET_TXSTAT_TXED          (SCD_START_OFFSET + 0xa8)
-#define SCD_SET_TXSTAT_DONE          (SCD_START_OFFSET + 0xac)
-#define SCD_SET_TXSTAT_NOT_SCHD      (SCD_START_OFFSET + 0xb0)
-#define SCD_DECREASE_CREDIT          (SCD_START_OFFSET + 0xb4)
-#define SCD_DECREASE_SCREDIT         (SCD_START_OFFSET + 0xb8)
-#define SCD_LOAD_CREDIT              (SCD_START_OFFSET + 0xbc)
-#define SCD_LOAD_SCREDIT             (SCD_START_OFFSET + 0xc0)
-#define SCD_BAR                      (SCD_START_OFFSET + 0xc4)
-#define SCD_BAR_DW0                  (SCD_START_OFFSET + 0xc8)
-#define SCD_BAR_DW1                  (SCD_START_OFFSET + 0xcc)
-#define SCD_QUEUECHAIN_SEL           (SCD_START_OFFSET + 0xd0)
-#define SCD_QUERY_REQ                (SCD_START_OFFSET + 0xd8)
-#define SCD_QUERY_RES                (SCD_START_OFFSET + 0xdc)
-#define SCD_PENDING_FRAMES           (SCD_START_OFFSET + 0xe0)
-#define SCD_INTERRUPT_MASK           (SCD_START_OFFSET + 0xe4)
-#define SCD_INTERRUPT_THRESHOLD      (SCD_START_OFFSET + 0xe8)
-#define SCD_QUERY_MIN_FRAME_SIZE     (SCD_START_OFFSET + 0x100)
-#define SCD_QUEUE_STATUS_BITS(x)     (SCD_START_OFFSET + 0x104 + (x) * 4)
 
-/* SRAM structures */
-#define SCD_CONTEXT_DATA_OFFSET                        0x380
-#define SCD_TX_STTS_BITMAP_OFFSET              0x400
-#define SCD_TRANSLATE_TBL_OFFSET               0x500
-#define SCD_CONTEXT_QUEUE_OFFSET(x)    (SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-#define SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
-       ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
+/*
+ * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
+ * For FIFO mode, index indicates next frame to transmit.
+ * For Scheduler-ACK mode, index indicates first frame in Tx window.
+ * Initialized by driver, updated by scheduler.
+ */
+#define SCD_QUEUE_RDPTR(x)           (SCD_START_OFFSET + 0x64 + (x) * 4)
 
-#define SCD_TXFACT_REG_TXFIFO_MASK(lo, hi) \
-       ((1<<(hi))|((1<<(hi))-(1<<(lo))))
+/*
+ * Select which queues work in chain mode (1) vs. not (0).
+ * Use chain mode to build chains of aggregated frames.
+ * Bit fields:
+ * 31-16:  Reserved
+ * 15-00:  Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
+ * NOTE:  If driver sets up queue for chain mode, it should be also set up
+ *        Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
+ */
+#define SCD_QUEUECHAIN_SEL           (SCD_START_OFFSET + 0xd0)
 
+/*
+ * Select which queues interrupt driver when scheduler increments
+ * a queue's read pointer (index).
+ * Bit fields:
+ * 31-16:  Reserved
+ * 15-00:  Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
+ * NOTE:  This functionality is apparently a no-op; driver relies on interrupts
+ *        from Rx queue to read Tx command responses and update Tx queues.
+ */
+#define SCD_INTERRUPT_MASK           (SCD_START_OFFSET + 0xe4)
 
-#define SCD_MODE_REG_BIT_SEARCH_MODE           (1<<0)
-#define SCD_MODE_REG_BIT_SBYP_MODE             (1<<1)
+/*
+ * Queue search status registers.  One for each queue.
+ * Sets up queue mode and assigns queue to Tx DMA channel.
+ * Bit fields:
+ * 19-10: Write mask/enable bits for bits 0-9
+ *     9: Driver should init to "0"
+ *     8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
+ *        Driver should init to "1" for aggregation mode, or "0" otherwise.
+ *   7-6: Driver should init to "0"
+ *     5: Window Size Left; indicates whether scheduler can request
+ *        another TFD, based on window size, etc.  Driver should init
+ *        this bit to "1" for aggregation mode, or "0" for non-agg.
+ *   4-1: Tx FIFO to use (range 0-7).
+ *     0: Queue is active (1), not active (0).
+ * Other bits should be written as "0"
+ *
+ * NOTE:  If enabling Scheduler-ACK mode, chain mode should also be enabled
+ *        via SCD_QUEUECHAIN_SEL.
+ */
+#define SCD_QUEUE_STATUS_BITS(x)     (SCD_START_OFFSET + 0x104 + (x) * 4)
 
-#define SCD_TXFIFO_POS_TID                     (0)
-#define SCD_TXFIFO_POS_RA                      (4)
+/* Bit field positions */
 #define SCD_QUEUE_STTS_REG_POS_ACTIVE          (0)
 #define SCD_QUEUE_STTS_REG_POS_TXF             (1)
 #define SCD_QUEUE_STTS_REG_POS_WSL             (5)
 #define SCD_QUEUE_STTS_REG_POS_SCD_ACK         (8)
+
+/* Write masks */
 #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN      (10)
 #define SCD_QUEUE_STTS_REG_MSK                 (0x0007FC00)
 
-#define SCD_QUEUE_RA_TID_MAP_RATID_MSK         (0x01FF)
+/**
+ * 4965 internal SRAM structures for scheduler, shared with driver ...
+ *
+ * Driver should clear and initialize the following areas after receiving
+ * "Alive" response from 4965 uCode, i.e. after initial
+ * uCode load, or after a uCode load done for error recovery:
+ *
+ * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
+ * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
+ * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
+ *
+ * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
+ * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
+ * All OFFSET values must be added to this base address.
+ */
+
+/*
+ * Queue context.  One 8-byte entry for each of 16 queues.
+ *
+ * Driver should clear this entire area (size 0x80) to 0 after receiving
+ * "Alive" notification from uCode.  Additionally, driver should init
+ * each queue's entry as follows:
+ *
+ * LS Dword bit fields:
+ *  0-06:  Max Tx window size for Scheduler-ACK.  Driver should init to 64.
+ *
+ * MS Dword bit fields:
+ * 16-22:  Frame limit.  Driver should init to 10 (0xa).
+ *
+ * Driver should init all other bits to 0.
+ *
+ * Init must be done after driver receives "Alive" response from 4965 uCode,
+ * and when setting up queue for aggregation.
+ */
+#define SCD_CONTEXT_DATA_OFFSET                        0x380
+#define SCD_CONTEXT_QUEUE_OFFSET(x)    (SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
 
 #define SCD_QUEUE_CTX_REG1_WIN_SIZE_POS                (0)
 #define SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK                (0x0000007F)
-#define SCD_QUEUE_CTX_REG1_CREDIT_POS          (8)
-#define SCD_QUEUE_CTX_REG1_CREDIT_MSK          (0x00FFFF00)
-#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS    (24)
-#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK    (0xFF000000)
 #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS     (16)
 #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK     (0x007F0000)
 
-#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R      (0x00000010)
-#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER     (0x00000C00)
-#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI                (0x00000100)
-#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI      (0x00000200)
+/*
+ * Tx Status Bitmap
+ *
+ * Driver should clear this entire area (size 0x100) to 0 after receiving
+ * "Alive" notification from uCode.  Area is used only by device itself;
+ * no other support (besides clearing) is required from driver.
+ */
+#define SCD_TX_STTS_BITMAP_OFFSET              0x400
 
-static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+/*
+ * RAxTID to queue translation mapping.
+ *
+ * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
+ * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
+ * one QOS priority level destined for one station (for this wireless link,
+ * not final destination).  The SCD_TRANSLATE_TABLE area provides 16 16-bit
+ * mappings, one for each of the 16 queues.  If queue is not in Scheduler-ACK
+ * mode, the device ignores the mapping value.
+ *
+ * Bit fields, for each 16-bit map:
+ * 15-9:  Reserved, set to 0
+ *  8-4:  Index into device's station table for recipient station
+ *  3-0:  Traffic ID (tid), range 0-15
+ *
+ * Driver should clear this entire area (size 32 bytes) to 0 after receiving
+ * "Alive" notification from uCode.  To update a 16-bit map value, driver
+ * must read a dword-aligned value from device SRAM, replace the 16-bit map
+ * value of interest, and write the dword value back into device SRAM.
+ */
+#define SCD_TRANSLATE_TBL_OFFSET               0x500
+
+/* Find translation table dword to read/write for given queue */
+#define SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
+       ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
+
+#define SCD_TXFIFO_POS_TID                     (0)
+#define SCD_TXFIFO_POS_RA                      (4)
+#define SCD_QUEUE_RA_TID_MAP_RATID_MSK         (0x01FF)
+
+/*********************** END TX SCHEDULER *************************************/
+
+static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags)
 {
        return le32_to_cpu(rate_n_flags) & 0xFF;
 }
-static inline u16 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
+static inline u16 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags)
 {
        return le32_to_cpu(rate_n_flags) & 0xFFFF;
 }
-static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u16 flags)
+static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
 {
        return cpu_to_le32(flags|(u16)rate);
 }
 
-struct iwl_tfd_frame_data {
+
+/**
+ * Tx/Rx Queues
+ *
+ * Most communication between driver and 4965 is via queues of data buffers.
+ * For example, all commands that the driver issues to device's embedded
+ * controller (uCode) are via the command queue (one of the Tx queues).  All
+ * uCode command responses/replies/notifications, including Rx frames, are
+ * conveyed from uCode to driver via the Rx queue.
+ *
+ * Most support for these queues, including handshake support, resides in
+ * structures in host DRAM, shared between the driver and the device.  When
+ * allocating this memory, the driver must make sure that data written by
+ * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's
+ * cache memory), so DRAM and cache are consistent, and the device can
+ * immediately see changes made by the driver.
+ *
+ * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via
+ * up to 7 DMA channels (FIFOs).  Each Tx queue is supported by a circular array
+ * in DRAM containing 256 Transmit Frame Descriptors (TFDs).
+ */
+#define IWL4965_MAX_WIN_SIZE              64
+#define IWL4965_QUEUE_SIZE               256
+#define IWL4965_NUM_FIFOS                  7
+#define IWL_MAX_NUM_QUEUES                16
+
+
+/**
+ * struct iwl4965_tfd_frame_data
+ *
+ * Describes up to 2 buffers containing (contiguous) portions of a Tx frame.
+ * Each buffer must be on dword boundary.
+ * Up to 10 iwl_tfd_frame_data structures, describing up to 20 buffers,
+ * may be filled within a TFD (iwl_tfd_frame).
+ *
+ * Bit fields in tb1_addr:
+ * 31- 0: Tx buffer 1 address bits [31:0]
+ *
+ * Bit fields in val1:
+ * 31-16: Tx buffer 2 address bits [15:0]
+ * 15- 4: Tx buffer 1 length (bytes)
+ *  3- 0: Tx buffer 1 address bits [32:32]
+ *
+ * Bit fields in val2:
+ * 31-20: Tx buffer 2 length (bytes)
+ * 19- 0: Tx buffer 2 address bits [35:16]
+ */
+struct iwl4965_tfd_frame_data {
        __le32 tb1_addr;
 
        __le32 val1;
@@ -509,7 +1926,36 @@ struct iwl_tfd_frame_data {
 #define IWL_tb2_len_SYM val2
 } __attribute__ ((packed));
 
-struct iwl_tfd_frame {
+
+/**
+ * struct iwl4965_tfd_frame
+ *
+ * Transmit Frame Descriptor (TFD)
+ *
+ * 4965 supports up to 16 Tx queues resident in host DRAM.
+ * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM.
+ * Both driver and device share these circular buffers, each of which must be
+ * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes for 4965.
+ *
+ * Driver must indicate the physical address of the base of each
+ * circular buffer via the 4965's FH_MEM_CBBC_QUEUE registers.
+ *
+ * Each TFD contains pointer/size information for up to 20 data buffers
+ * in host DRAM.  These buffers collectively contain the (one) frame described
+ * by the TFD.  Each buffer must be a single contiguous block of memory within
+ * itself, but buffers may be scattered in host DRAM.  Each buffer has max size
+ * of (4K - 4).  The 4965 concatenates all of a TFD's buffers into a single
+ * Tx frame, up to 8 KBytes in size.
+ *
+ * Bit fields in the control dword (val0):
+ * 31-30: # dwords (0-3) of padding required at end of frame for 16-byte bound
+ *    29: reserved
+ * 28-24: # Transmit Buffer Descriptors in TFD
+ * 23- 0: reserved
+ *
+ * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
+ */
+struct iwl4965_tfd_frame {
        __le32 val0;
        /* __le32 rsvd1:24; */
        /* __le32 num_tbs:5; */
@@ -518,15 +1964,20 @@ struct iwl_tfd_frame {
 #define IWL_num_tbs_SYM val0
        /* __le32 rsvd2:1; */
        /* __le32 padding:2; */
-       struct iwl_tfd_frame_data pa[10];
+       struct iwl4965_tfd_frame_data pa[10];
        __le32 reserved;
 } __attribute__ ((packed));
 
-#define IWL4965_MAX_WIN_SIZE              64
-#define IWL4965_QUEUE_SIZE               256
-#define IWL4965_NUM_FIFOS                  7
-#define IWL_MAX_NUM_QUEUES                16
 
+/**
+ * struct iwl4965_queue_byte_cnt_entry
+ *
+ * Byte Count Table Entry
+ *
+ * Bit fields:
+ * 15-12: reserved
+ * 11- 0: total to-be-transmitted byte count of frame (does not include command)
+ */
 struct iwl4965_queue_byte_cnt_entry {
        __le16 val;
        /* __le16 byte_cnt:12; */
@@ -536,6 +1987,25 @@ struct iwl4965_queue_byte_cnt_entry {
        /* __le16 rsvd:4; */
 } __attribute__ ((packed));
 
+
+/**
+ * struct iwl4965_sched_queue_byte_cnt_tbl
+ *
+ * Byte Count table
+ *
+ * Each Tx queue uses a byte-count table containing 320 entries:
+ * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that
+ * duplicate the first 64 entries (to avoid wrap-around within a Tx window;
+ * max Tx window is 64 TFDs).
+ *
+ * When driver sets up a new TFD, it must also enter the total byte count
+ * of the frame to be transmitted into the corresponding entry in the byte
+ * count table for the chosen Tx queue.  If the TFD index is 0-63, the driver
+ * must duplicate the byte count entry in corresponding index 256-319.
+ *
+ * "dont_care" padding puts each byte count table on a 1024-byte boundary;
+ * 4965 assumes tables are separated by 1024 bytes.
+ */
 struct iwl4965_sched_queue_byte_cnt_tbl {
        struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL4965_QUEUE_SIZE +
                                                       IWL4965_MAX_WIN_SIZE];
@@ -544,9 +2014,31 @@ struct iwl4965_sched_queue_byte_cnt_tbl {
                     sizeof(__le16)];
 } __attribute__ ((packed));
 
-/* Base physical address of iwl_shared is provided to SCD_DRAM_BASE_ADDR
- * and &iwl_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */
-struct iwl_shared {
+
+/**
+ * struct iwl4965_shared - handshake area for Tx and Rx
+ *
+ * For convenience in allocating memory, this structure combines 2 areas of
+ * DRAM which must be shared between driver and 4965.  These do not need to
+ * be combined, if better allocation would result from keeping them separate:
+ *
+ * 1)  The Tx byte count tables occupy 1024 bytes each (16 KBytes total for
+ *     16 queues).  Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find
+ *     the first of these tables.  4965 assumes tables are 1024 bytes apart.
+ *
+ * 2)  The Rx status (val0 and val1) occupies only 8 bytes.  Driver uses
+ *     FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area.
+ *     Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD)
+ *     that has been filled by the 4965.
+ *
+ * Bit fields val0:
+ * 31-12:  Not used
+ * 11- 0:  Index of last filled Rx buffer descriptor (4965 writes, driver reads)
+ *
+ * Bit fields val1:
+ * 31- 0:  Not used
+ */
+struct iwl4965_shared {
        struct iwl4965_sched_queue_byte_cnt_tbl
         queues_byte_cnt_tbls[IWL_MAX_NUM_QUEUES];
        __le32 val0;
@@ -578,4 +2070,4 @@ struct iwl_shared {
        __le32 padding2;
 } __attribute__ ((packed));
 
-#endif /* __iwl_4965_hw_h__ */
+#endif /* __iwl4965_4965_hw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-io.h b/drivers/net/wireless/iwlwifi/iwl-4965-io.h
new file mode 100644 (file)
index 0000000..34a0b57
--- /dev/null
@@ -0,0 +1,431 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * 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:
+ * James P. Ketrenos <ipw2100-admin@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#ifndef __iwl4965_io_h__
+#define __iwl4965_io_h__
+
+#include <linux/io.h>
+
+#include "iwl-4965-debug.h"
+
+/*
+ * IO, register, and NIC memory access functions
+ *
+ * NOTE on naming convention and macro usage for these
+ *
+ * A single _ prefix before a an access function means that no state
+ * check or debug information is printed when that function is called.
+ *
+ * A double __ prefix before an access function means that state is checked
+ * and the current line number is printed in addition to any other debug output.
+ *
+ * The non-prefixed name is the #define that maps the caller into a
+ * #define that provides the caller's __LINE__ to the double prefix version.
+ *
+ * If you wish to call the function without any debug or state checking,
+ * you should use the single _ prefix version (as is used by dependent IO
+ * routines, for example _iwl4965_read_direct32 calls the non-check version of
+ * _iwl4965_read32.)
+ *
+ * These declarations are *extremely* useful in quickly isolating code deltas
+ * which result in misconfiguring of the hardware I/O.  In combination with
+ * git-bisect and the IO debug level you can quickly determine the specific
+ * commit which breaks the IO sequence to the hardware.
+ *
+ */
+
+#define _iwl4965_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *iwl,
+                                u32 ofs, u32 val)
+{
+       IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
+       _iwl4965_write32(iwl, ofs, val);
+}
+#define iwl4965_write32(iwl, ofs, val) \
+       __iwl4965_write32(__FILE__, __LINE__, iwl, ofs, val)
+#else
+#define iwl4965_write32(iwl, ofs, val) _iwl4965_write32(iwl, ofs, val)
+#endif
+
+#define _iwl4965_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
+#ifdef CONFIG_IWL4965_DEBUG
+static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *iwl, u32 ofs)
+{
+       IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
+       return _iwl4965_read32(iwl, ofs);
+}
+#define iwl4965_read32(iwl, ofs) __iwl4965_read32(__FILE__, __LINE__, iwl, ofs)
+#else
+#define iwl4965_read32(p, o) _iwl4965_read32(p, o)
+#endif
+
+static inline int _iwl4965_poll_bit(struct iwl4965_priv *priv, u32 addr,
+                               u32 bits, u32 mask, int timeout)
+{
+       int i = 0;
+
+       do {
+               if ((_iwl4965_read32(priv, addr) & mask) == (bits & mask))
+                       return i;
+               mdelay(10);
+               i += 10;
+       } while (i < timeout);
+
+       return -ETIMEDOUT;
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline int __iwl4965_poll_bit(const char *f, u32 l,
+                                struct iwl4965_priv *priv, u32 addr,
+                                u32 bits, u32 mask, int timeout)
+{
+       int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout);
+       if (unlikely(ret  == -ETIMEDOUT))
+               IWL_DEBUG_IO
+                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n",
+                    addr, bits, mask, f, l);
+       else
+               IWL_DEBUG_IO
+                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n",
+                    addr, bits, mask, ret, f, l);
+       return ret;
+}
+#define iwl4965_poll_bit(iwl, addr, bits, mask, timeout) \
+       __iwl4965_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
+#else
+#define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t)
+#endif
+
+static inline void _iwl4965_set_bit(struct iwl4965_priv *priv, u32 reg, u32 mask)
+{
+       _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) | mask);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_set_bit(const char *f, u32 l,
+                                struct iwl4965_priv *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl4965_read32(priv, reg) | mask;
+       IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+       _iwl4965_write32(priv, reg, val);
+}
+#define iwl4965_set_bit(p, r, m) __iwl4965_set_bit(__FILE__, __LINE__, p, r, m)
+#else
+#define iwl4965_set_bit(p, r, m) _iwl4965_set_bit(p, r, m)
+#endif
+
+static inline void _iwl4965_clear_bit(struct iwl4965_priv *priv, u32 reg, u32 mask)
+{
+       _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) & ~mask);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_clear_bit(const char *f, u32 l,
+                                  struct iwl4965_priv *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl4965_read32(priv, reg) & ~mask;
+       IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
+       _iwl4965_write32(priv, reg, val);
+}
+#define iwl4965_clear_bit(p, r, m) __iwl4965_clear_bit(__FILE__, __LINE__, p, r, m)
+#else
+#define iwl4965_clear_bit(p, r, m) _iwl4965_clear_bit(p, r, m)
+#endif
+
+static inline int _iwl4965_grab_nic_access(struct iwl4965_priv *priv)
+{
+       int ret;
+       u32 gp_ctl;
+
+#ifdef CONFIG_IWL4965_DEBUG
+       if (atomic_read(&priv->restrict_refcnt))
+               return 0;
+#endif
+       if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
+           test_bit(STATUS_RF_KILL_SW, &priv->status)) {
+               IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
+                       "wakes up NIC\n");
+
+               /* 10 msec allows time for NIC to complete its data save */
+               gp_ctl = _iwl4965_read32(priv, CSR_GP_CNTRL);
+               if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
+                       IWL_DEBUG_RF_KILL("Wait for complete power-down, "
+                               "gpctl = 0x%08x\n", gp_ctl);
+                       mdelay(10);
+               } else
+                       IWL_DEBUG_RF_KILL("power-down complete, "
+                                         "gpctl = 0x%08x\n", gp_ctl);
+       }
+
+       /* this bit wakes up the NIC */
+       _iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       ret = _iwl4965_poll_bit(priv, CSR_GP_CNTRL,
+                          CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
+                          (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+                           CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
+       if (ret < 0) {
+               IWL_ERROR("MAC is in deep sleep!\n");
+               return -EIO;
+       }
+
+#ifdef CONFIG_IWL4965_DEBUG
+       atomic_inc(&priv->restrict_refcnt);
+#endif
+       return 0;
+}
+
+#ifdef CONFIG_IWL4965_DEBUG
+static inline int __iwl4965_grab_nic_access(const char *f, u32 l,
+                                              struct iwl4965_priv *priv)
+{
+       if (atomic_read(&priv->restrict_refcnt))
+               IWL_DEBUG_INFO("Grabbing access while already held at "
+                              "line %d.\n", l);
+
+       IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l);
+       return _iwl4965_grab_nic_access(priv);
+}
+#define iwl4965_grab_nic_access(priv) \
+       __iwl4965_grab_nic_access(__FILE__, __LINE__, priv)
+#else
+#define iwl4965_grab_nic_access(priv) \
+       _iwl4965_grab_nic_access(priv)
+#endif
+
+static inline void _iwl4965_release_nic_access(struct iwl4965_priv *priv)
+{
+#ifdef CONFIG_IWL4965_DEBUG
+       if (atomic_dec_and_test(&priv->restrict_refcnt))
+#endif
+               _iwl4965_clear_bit(priv, CSR_GP_CNTRL,
+                              CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_release_nic_access(const char *f, u32 l,
+                                           struct iwl4965_priv *priv)
+{
+       if (atomic_read(&priv->restrict_refcnt) <= 0)
+               IWL_ERROR("Release unheld nic access at line %d.\n", l);
+
+       IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l);
+       _iwl4965_release_nic_access(priv);
+}
+#define iwl4965_release_nic_access(priv) \
+       __iwl4965_release_nic_access(__FILE__, __LINE__, priv)
+#else
+#define iwl4965_release_nic_access(priv) \
+       _iwl4965_release_nic_access(priv)
+#endif
+
+static inline u32 _iwl4965_read_direct32(struct iwl4965_priv *priv, u32 reg)
+{
+       return _iwl4965_read32(priv, reg);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline u32 __iwl4965_read_direct32(const char *f, u32 l,
+                                       struct iwl4965_priv *priv, u32 reg)
+{
+       u32 value = _iwl4965_read_direct32(priv, reg);
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from %s %d\n", f, l);
+       IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
+                    f, l);
+       return value;
+}
+#define iwl4965_read_direct32(priv, reg) \
+       __iwl4965_read_direct32(__FILE__, __LINE__, priv, reg)
+#else
+#define iwl4965_read_direct32 _iwl4965_read_direct32
+#endif
+
+static inline void _iwl4965_write_direct32(struct iwl4965_priv *priv,
+                                        u32 reg, u32 value)
+{
+       _iwl4965_write32(priv, reg, value);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static void __iwl4965_write_direct32(u32 line,
+                                  struct iwl4965_priv *priv, u32 reg, u32 value)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       _iwl4965_write_direct32(priv, reg, value);
+}
+#define iwl4965_write_direct32(priv, reg, value) \
+       __iwl4965_write_direct32(__LINE__, priv, reg, value)
+#else
+#define iwl4965_write_direct32 _iwl4965_write_direct32
+#endif
+
+static inline void iwl4965_write_reg_buf(struct iwl4965_priv *priv,
+                                              u32 reg, u32 len, u32 *values)
+{
+       u32 count = sizeof(u32);
+
+       if ((priv != NULL) && (values != NULL)) {
+               for (; 0 < len; len -= count, reg += count, values++)
+                       _iwl4965_write_direct32(priv, reg, *values);
+       }
+}
+
+static inline int _iwl4965_poll_direct_bit(struct iwl4965_priv *priv,
+                                          u32 addr, u32 mask, int timeout)
+{
+       int i = 0;
+
+       do {
+               if ((_iwl4965_read_direct32(priv, addr) & mask) == mask)
+                       return i;
+               mdelay(10);
+               i += 10;
+       } while (i < timeout);
+
+       return -ETIMEDOUT;
+}
+
+#ifdef CONFIG_IWL4965_DEBUG
+static inline int __iwl4965_poll_direct_bit(const char *f, u32 l,
+                                           struct iwl4965_priv *priv,
+                                           u32 addr, u32 mask, int timeout)
+{
+       int ret  = _iwl4965_poll_direct_bit(priv, addr, mask, timeout);
+
+       if (unlikely(ret == -ETIMEDOUT))
+               IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - "
+                            "timedout - %s %d\n", addr, mask, f, l);
+       else
+               IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
+                            "- %s %d\n", addr, mask, ret, f, l);
+       return ret;
+}
+#define iwl4965_poll_direct_bit(iwl, addr, mask, timeout) \
+       __iwl4965_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
+#else
+#define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit
+#endif
+
+static inline u32 _iwl4965_read_prph(struct iwl4965_priv *priv, u32 reg)
+{
+       _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+       return _iwl4965_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline u32 __iwl4965_read_prph(u32 line, struct iwl4965_priv *priv, u32 reg)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       return _iwl4965_read_prph(priv, reg);
+}
+
+#define iwl4965_read_prph(priv, reg) \
+       __iwl4965_read_prph(__LINE__, priv, reg)
+#else
+#define iwl4965_read_prph _iwl4965_read_prph
+#endif
+
+static inline void _iwl4965_write_prph(struct iwl4965_priv *priv,
+                                            u32 addr, u32 val)
+{
+       _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
+                             ((addr & 0x0000FFFF) | (3 << 24)));
+       _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
+}
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_write_prph(u32 line, struct iwl4965_priv *priv,
+                                             u32 addr, u32 val)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access from line %d\n", line);
+       _iwl4965_write_prph(priv, addr, val);
+}
+
+#define iwl4965_write_prph(priv, addr, val) \
+       __iwl4965_write_prph(__LINE__, priv, addr, val);
+#else
+#define iwl4965_write_prph _iwl4965_write_prph
+#endif
+
+#define _iwl4965_set_bits_prph(priv, reg, mask) \
+       _iwl4965_write_prph(priv, reg, (_iwl4965_read_prph(priv, reg) | mask))
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_set_bits_prph(u32 line, struct iwl4965_priv *priv,
+                                       u32 reg, u32 mask)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+
+       _iwl4965_set_bits_prph(priv, reg, mask);
+}
+#define iwl4965_set_bits_prph(priv, reg, mask) \
+       __iwl4965_set_bits_prph(__LINE__, priv, reg, mask)
+#else
+#define iwl4965_set_bits_prph _iwl4965_set_bits_prph
+#endif
+
+#define _iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \
+       _iwl4965_write_prph(priv, reg, ((_iwl4965_read_prph(priv, reg) & mask) | bits))
+
+#ifdef CONFIG_IWL4965_DEBUG
+static inline void __iwl4965_set_bits_mask_prph(u32 line,
+               struct iwl4965_priv *priv, u32 reg, u32 bits, u32 mask)
+{
+       if (!atomic_read(&priv->restrict_refcnt))
+               IWL_ERROR("Nic access not held from line %d\n", line);
+       _iwl4965_set_bits_mask_prph(priv, reg, bits, mask);
+}
+#define iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \
+       __iwl4965_set_bits_mask_prph(__LINE__, priv, reg, bits, mask)
+#else
+#define iwl4965_set_bits_mask_prph _iwl4965_set_bits_mask_prph
+#endif
+
+static inline void iwl4965_clear_bits_prph(struct iwl4965_priv
+                                                *priv, u32 reg, u32 mask)
+{
+       u32 val = _iwl4965_read_prph(priv, reg);
+       _iwl4965_write_prph(priv, reg, (val & ~mask));
+}
+
+static inline u32 iwl4965_read_targ_mem(struct iwl4965_priv *priv, u32 addr)
+{
+       iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+       return iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+}
+
+static inline void iwl4965_write_targ_mem(struct iwl4965_priv *priv, u32 addr, u32 val)
+{
+       iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+       iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+}
+
+static inline void iwl4965_write_targ_mem_buf(struct iwl4965_priv *priv, u32 addr,
+                                         u32 len, u32 *values)
+{
+       iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+       for (; 0 < len; len -= sizeof(u32), values++)
+               iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+}
+#endif
index 8dc78c0bf1ff26d5cff33c31e8e66399930ce225..d06462264147450bc1da86a5b21665058bab8c15 100644 (file)
 
 #include <linux/workqueue.h>
 
-#define IWL 4965
-
 #include "../net/mac80211/ieee80211_rate.h"
 
-#include "iwlwifi.h"
+#include "iwl-4965.h"
 #include "iwl-helpers.h"
 
 #define RS_NAME "iwl-4965-rs"
 #define IWL_NUMBER_TRY      1
 #define IWL_HT_NUMBER_TRY   3
 
-#define IWL_RATE_MAX_WINDOW            62
-#define IWL_RATE_HIGH_TH               10880
-#define IWL_RATE_MIN_FAILURE_TH                6
-#define IWL_RATE_MIN_SUCCESS_TH                8
-#define IWL_RATE_DECREASE_TH           1920
-#define IWL_RATE_INCREASE_TH            8960
-#define IWL_RATE_SCALE_FLUSH_INTVL   (2*HZ)        /*2 seconds */
+#define IWL_RATE_MAX_WINDOW            62      /* # tx in history window */
+#define IWL_RATE_MIN_FAILURE_TH                6       /* min failures to calc tpt */
+#define IWL_RATE_MIN_SUCCESS_TH                8       /* min successes to calc tpt */
+
+/* max time to accum history 2 seconds */
+#define IWL_RATE_SCALE_FLUSH_INTVL   (2*HZ)
 
 static u8 rs_ht_to_legacy[] = {
        IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
@@ -67,83 +64,109 @@ static u8 rs_ht_to_legacy[] = {
        IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
 };
 
-struct iwl_rate {
+struct iwl4965_rate {
        u32 rate_n_flags;
 } __attribute__ ((packed));
 
-struct iwl_rate_scale_data {
-       u64 data;
-       s32 success_counter;
-       s32 success_ratio;
-       s32 counter;
-       s32 average_tpt;
+/**
+ * struct iwl4965_rate_scale_data -- tx success history for one rate
+ */
+struct iwl4965_rate_scale_data {
+       u64 data;               /* bitmap of successful frames */
+       s32 success_counter;    /* number of frames successful */
+       s32 success_ratio;      /* per-cent * 128  */
+       s32 counter;            /* number of frames attempted */
+       s32 average_tpt;        /* success ratio * expected throughput */
        unsigned long stamp;
 };
 
-struct iwl_scale_tbl_info {
-       enum iwl_table_type lq_type;
-       enum iwl_antenna_type antenna_type;
-       u8 is_SGI;
-       u8 is_fat;
-       u8 is_dup;
-       u8 action;
-       s32 *expected_tpt;
-       struct iwl_rate current_rate;
-       struct iwl_rate_scale_data win[IWL_RATE_COUNT];
+/**
+ * struct iwl4965_scale_tbl_info -- tx params and success history for all rates
+ *
+ * There are two of these in struct iwl_rate_scale_priv,
+ * one for "active", and one for "search".
+ */
+struct iwl4965_scale_tbl_info {
+       enum iwl4965_table_type lq_type;
+       enum iwl4965_antenna_type antenna_type;
+       u8 is_SGI;      /* 1 = short guard interval */
+       u8 is_fat;      /* 1 = 40 MHz channel width */
+       u8 is_dup;      /* 1 = duplicated data streams */
+       u8 action;      /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
+       s32 *expected_tpt;      /* throughput metrics; expected_tpt_G, etc. */
+       struct iwl4965_rate current_rate;  /* rate_n_flags, uCode API format */
+       struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
 };
 
-struct iwl_rate_scale_priv {
-       u8 active_tbl;
-       u8 enable_counter;
-       u8 stay_in_tbl;
-       u8 search_better_tbl;
+/**
+ * struct iwl_rate_scale_priv -- driver's rate scaling private structure
+ *
+ * Pointer to this gets passed back and forth between driver and mac80211.
+ */
+struct iwl4965_lq_sta {
+       u8 active_tbl;          /* index of active table, range 0-1 */
+       u8 enable_counter;      /* indicates HT mode */
+       u8 stay_in_tbl;         /* 1: disallow, 0: allow search for new mode */
+       u8 search_better_tbl;   /* 1: currently trying alternate mode */
        s32 last_tpt;
+
+       /* The following determine when to search for a new mode */
        u32 table_count_limit;
-       u32 max_failure_limit;
-       u32 max_success_limit;
+       u32 max_failure_limit;  /* # failed frames before new search */
+       u32 max_success_limit;  /* # successful frames before new search */
        u32 table_count;
-       u32 total_failed;
-       u32 total_success;
-       u32 flush_timer;
-       u8 action_counter;
+       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 */
+
+       u8 action_counter;      /* # mode-switch actions tried */
        u8 antenna;
        u8 valid_antenna;
        u8 is_green;
        u8 is_dup;
        u8 phymode;
        u8 ibss_sta_added;
+
+       /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
        u32 supp_rates;
        u16 active_rate;
        u16 active_siso_rate;
        u16 active_mimo_rate;
        u16 active_rate_basic;
-       struct iwl_link_quality_cmd lq;
-       struct iwl_scale_tbl_info lq_info[LQ_SIZE];
+
+       struct iwl4965_link_quality_cmd lq;
+       struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct dentry *rs_sta_dbgfs_scale_table_file;
        struct dentry *rs_sta_dbgfs_stats_table_file;
-       struct iwl_rate dbg_fixed;
-       struct iwl_priv *drv;
+       struct iwl4965_rate dbg_fixed;
+       struct iwl4965_priv *drv;
 #endif
 };
 
-static void rs_rate_scale_perform(struct iwl_priv *priv,
+static void rs_rate_scale_perform(struct iwl4965_priv *priv,
                                   struct net_device *dev,
                                   struct ieee80211_hdr *hdr,
                                   struct sta_info *sta);
-static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
-                            struct iwl_rate *tx_mcs,
-                            struct iwl_link_quality_cmd *tbl);
+static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
+                            struct iwl4965_rate *tx_mcs,
+                            struct iwl4965_link_quality_cmd *tbl);
 
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
-                               struct iwl_rate *mcs, int index);
+static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
+                               struct iwl4965_rate *mcs, int index);
 #else
-static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
-                               struct iwl_rate *mcs, int index)
+static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
+                               struct iwl4965_rate *mcs, int index)
 {}
 #endif
+
+/*
+ * Expected throughput metrics for following rates:
+ * 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).
+ */
 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 };
@@ -184,36 +207,34 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
 };
 
-static int iwl_lq_sync_callback(struct iwl_priv *priv,
-                               struct iwl_cmd *cmd, struct sk_buff *skb)
+static int iwl4965_lq_sync_callback(struct iwl4965_priv *priv,
+                               struct iwl4965_cmd *cmd, struct sk_buff *skb)
 {
        /*We didn't cache the SKB; let the caller free it */
        return 1;
 }
 
-static inline u8 iwl_rate_get_rate(u32 rate_n_flags)
+static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags)
 {
        return (u8)(rate_n_flags & 0xFF);
 }
 
-static int rs_send_lq_cmd(struct iwl_priv *priv,
-                         struct iwl_link_quality_cmd *lq, u8 flags)
+static int rs_send_lq_cmd(struct iwl4965_priv *priv,
+                         struct iwl4965_link_quality_cmd *lq, u8 flags)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
        int i;
 #endif
-       int rc = -1;
-
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_TX_LINK_QUALITY_CMD,
-               .len = sizeof(struct iwl_link_quality_cmd),
+               .len = sizeof(struct iwl4965_link_quality_cmd),
                .meta.flags = flags,
                .data = lq,
        };
 
        if ((lq->sta_id == 0xFF) &&
            (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
-               return rc;
+               return -EINVAL;
 
        if (lq->sta_id == 0xFF)
                lq->sta_id = IWL_AP_ID;
@@ -222,23 +243,23 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
        IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n",
                       lq->general_params.single_stream_ant_msk,
                       lq->general_params.dual_stream_ant_msk);
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
        for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
                IWL_DEBUG_RATE("lq index %d 0x%X\n",
                                i, lq->rs_table[i].rate_n_flags);
 #endif
 
        if (flags & CMD_ASYNC)
-               cmd.meta.u.callback = iwl_lq_sync_callback;
+               cmd.meta.u.callback = iwl4965_lq_sync_callback;
 
-       if (iwl_is_associated(priv) && priv->assoc_station_added &&
+       if (iwl4965_is_associated(priv) && priv->assoc_station_added &&
            priv->lq_mngr.lq_ready)
-               rc = iwl_send_cmd(priv, &cmd);
+               return  iwl4965_send_cmd(priv, &cmd);
 
-       return rc;
+       return 0;
 }
 
-static int rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
+static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
 {
        window->data = 0;
        window->success_counter = 0;
@@ -246,29 +267,38 @@ static int rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
        window->counter = 0;
        window->average_tpt = IWL_INVALID_VALUE;
        window->stamp = 0;
-
-       return 0;
 }
 
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
+/**
+ * rs_collect_tx_data - Update the success/failure sliding window
+ *
+ * We keep a sliding window of the last 62 packets transmitted
+ * at this rate.  window->data contains the bitmask of successful
+ * packets.
+ */
+static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
                              int scale_index, s32 tpt, u32 status)
 {
-       int rc = 0;
-       struct iwl_rate_scale_data *window = NULL;
+       struct iwl4965_rate_scale_data *window = NULL;
        u64 mask;
        u8 win_size = IWL_RATE_MAX_WINDOW;
        s32 fail_count;
 
-       if (scale_index < 0)
-               return -1;
-
-       if (scale_index >= IWL_RATE_COUNT)
-               return -1;
+       if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
+               return -EINVAL;
 
+       /* Select data for current tx bit rate */
        window = &(windows[scale_index]);
 
+       /*
+        * Keep track of only the latest 62 tx frame attempts in this rate's
+        * history window; anything older isn't really relevant any more.
+        * If we have filled up the sliding window, drop the oldest attempt;
+        * if the oldest attempt (highest bit in bitmap) shows "success",
+        * subtract "1" from the success counter (this is the main reason
+        * we keep these bitmaps!).
+        */
        if (window->counter >= win_size) {
-
                window->counter = win_size - 1;
                mask = 1;
                mask = (mask << (win_size - 1));
@@ -278,7 +308,11 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
                }
        }
 
+       /* Increment frames-attempted counter */
        window->counter = window->counter + 1;
+
+       /* Shift bitmap by one frame (throw away oldest history),
+        * OR in "1", and increment "success" if this frame was successful. */
        mask = window->data;
        window->data = (mask << 1);
        if (status != 0) {
@@ -286,6 +320,7 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
                window->data |= 0x1;
        }
 
+       /* Calculate current success ratio, avoid divide-by-0! */
        if (window->counter > 0)
                window->success_ratio = 128 * (100 * window->success_counter)
                                        / window->counter;
@@ -294,37 +329,40 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
 
        fail_count = window->counter - window->success_counter;
 
+       /* Calculate average throughput, if we have enough history. */
        if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
            (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
                window->average_tpt = (window->success_ratio * tpt + 64) / 128;
        else
                window->average_tpt = IWL_INVALID_VALUE;
 
+       /* Tag this window as having been updated */
        window->stamp = jiffies;
 
-       return rc;
+       return 0;
 }
 
-int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate,
-                          struct iwl_scale_tbl_info *tbl,
+/*
+ * Fill uCode API rate_n_flags field, based on "search" or "active" table.
+ */
+static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
+                          struct iwl4965_scale_tbl_info *tbl,
                           int index, u8 use_green)
 {
-       int rc = 0;
-
        if (is_legacy(tbl->lq_type)) {
-               mcs_rate->rate_n_flags = iwl_rates[index].plcp;
+               mcs_rate->rate_n_flags = iwl4965_rates[index].plcp;
                if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
                        mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK;
 
        } else if (is_siso(tbl->lq_type)) {
                if (index > IWL_LAST_OFDM_RATE)
                        index = IWL_LAST_OFDM_RATE;
-                mcs_rate->rate_n_flags = iwl_rates[index].plcp_siso |
+                mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso |
                                          RATE_MCS_HT_MSK;
        } else {
                if (index > IWL_LAST_OFDM_RATE)
                        index = IWL_LAST_OFDM_RATE;
-               mcs_rate->rate_n_flags = iwl_rates[index].plcp_mimo |
+               mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo |
                                         RATE_MCS_HT_MSK;
        }
 
@@ -343,7 +381,7 @@ int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate,
        }
 
        if (is_legacy(tbl->lq_type))
-               return rc;
+               return;
 
        if (tbl->is_fat) {
                if (tbl->is_dup)
@@ -359,27 +397,31 @@ int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate,
                if (is_siso(tbl->lq_type))
                        mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK;
        }
-       return rc;
 }
 
-static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate,
-                                   int phymode, struct iwl_scale_tbl_info *tbl,
+/*
+ * Interpret uCode API's rate_n_flags format,
+ * fill "search" or "active" tx mode table.
+ */
+static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
+                                   int phymode, struct iwl4965_scale_tbl_info *tbl,
                                    int *rate_idx)
 {
        int index;
        u32 ant_msk;
 
-       index = iwl_rate_index_from_plcp(mcs_rate->rate_n_flags);
+       index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags);
 
        if (index  == IWL_RATE_INVALID) {
                *rate_idx = -1;
-               return -1;
+               return -EINVAL;
        }
-       tbl->is_SGI = 0;
+       tbl->is_SGI = 0;        /* default legacy setup */
        tbl->is_fat = 0;
        tbl->is_dup = 0;
-       tbl->antenna_type = ANT_BOTH;
+       tbl->antenna_type = ANT_BOTH;   /* default MIMO setup */
 
+       /* legacy rate format */
        if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
                ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
 
@@ -399,7 +441,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate,
                }
                *rate_idx = index;
 
-       } else if (iwl_rate_get_rate(mcs_rate->rate_n_flags)
+       /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */
+       } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
                                        <= IWL_RATE_SISO_60M_PLCP) {
                tbl->lq_type = LQ_SISO;
 
@@ -423,6 +466,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate,
                        tbl->is_dup = 1;
 
                *rate_idx = index;
+
+       /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */
        } else {
                tbl->lq_type = LQ_MIMO;
                if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
@@ -439,8 +484,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate,
        return 0;
 }
 
-static inline void rs_toggle_antenna(struct iwl_rate *new_rate,
-                                    struct iwl_scale_tbl_info *tbl)
+static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate,
+                                    struct iwl4965_scale_tbl_info *tbl)
 {
        if (tbl->antenna_type == ANT_AUX) {
                tbl->antenna_type = ANT_MAIN;
@@ -453,18 +498,15 @@ static inline void rs_toggle_antenna(struct iwl_rate *new_rate,
        }
 }
 
-static inline s8 rs_use_green(struct iwl_priv *priv)
+static inline u8 rs_use_green(struct iwl4965_priv *priv,
+                             struct ieee80211_conf *conf)
 {
-       s8 rc = 0;
-#ifdef CONFIG_IWLWIFI_HT
-       if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
-               return 0;
-
-       if ((priv->current_assoc_ht.is_green_field) &&
-           !(priv->current_assoc_ht.operating_mode & 0x4))
-               rc = 1;
-#endif /*CONFIG_IWLWIFI_HT */
-       return rc;
+#ifdef CONFIG_IWL4965_HT
+       return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
+               priv->current_ht_config.is_green_field &&
+               !priv->current_ht_config.non_GF_STA_present);
+#endif /* CONFIG_IWL4965_HT */
+       return 0;
 }
 
 /**
@@ -474,23 +516,24 @@ static inline s8 rs_use_green(struct iwl_priv *priv)
  * basic available rates.
  *
  */
-static void rs_get_supported_rates(struct iwl_rate_scale_priv *lq_data,
+static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
                                   struct ieee80211_hdr *hdr,
-                                  enum iwl_table_type rate_type,
+                                  enum iwl4965_table_type rate_type,
                                   u16 *data_rate)
 {
        if (is_legacy(rate_type))
-               *data_rate = lq_data->active_rate;
+               *data_rate = lq_sta->active_rate;
        else {
                if (is_siso(rate_type))
-                       *data_rate = lq_data->active_siso_rate;
+                       *data_rate = lq_sta->active_siso_rate;
                else
-                       *data_rate = lq_data->active_mimo_rate;
+                       *data_rate = lq_sta->active_mimo_rate;
        }
 
        if (hdr && is_multicast_ether_addr(hdr->addr1) &&
-           lq_data->active_rate_basic)
-               *data_rate = lq_data->active_rate_basic;
+           lq_sta->active_rate_basic) {
+               *data_rate = lq_sta->active_rate_basic;
+       }
 }
 
 static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
@@ -498,7 +541,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
        u8 high = IWL_RATE_INVALID;
        u8 low = IWL_RATE_INVALID;
 
-       /* 802.11A or ht walks to the next literal adjascent rate in
+       /* 802.11A or ht walks to the next literal adjacent rate in
         * the rate table */
        if (is_a_band(rate_type) || !is_legacy(rate_type)) {
                int i;
@@ -527,7 +570,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
 
        low = index;
        while (low != IWL_RATE_INVALID) {
-               low = iwl_rates[low].prev_rs;
+               low = iwl4965_rates[low].prev_rs;
                if (low == IWL_RATE_INVALID)
                        break;
                if (rate_mask & (1 << low))
@@ -537,7 +580,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
 
        high = index;
        while (high != IWL_RATE_INVALID) {
-               high = iwl_rates[high].next_rs;
+               high = iwl4965_rates[high].next_rs;
                if (high == IWL_RATE_INVALID)
                        break;
                if (rate_mask & (1 << high))
@@ -548,15 +591,15 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
        return (high << 8) | low;
 }
 
-static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
-                            struct iwl_scale_tbl_info *tbl, u8 scale_index,
-                            u8 ht_possible, struct iwl_rate *mcs_rate)
+static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
+                            struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
+                            u8 ht_possible, struct iwl4965_rate *mcs_rate)
 {
        s32 low;
        u16 rate_mask;
        u16 high_low;
        u8 switch_to_legacy = 0;
-       u8 is_green = lq_data->is_green;
+       u8 is_green = lq_sta->is_green;
 
        /* check if we need to switch from HT to legacy rates.
         * assumption is that mandatory rates (1Mbps or 6Mbps)
@@ -564,7 +607,7 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
        if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
                switch_to_legacy = 1;
                scale_index = rs_ht_to_legacy[scale_index];
-               if (lq_data->phymode == MODE_IEEE80211A)
+               if (lq_sta->phymode == MODE_IEEE80211A)
                        tbl->lq_type = LQ_A;
                else
                        tbl->lq_type = LQ_G;
@@ -577,22 +620,22 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
                tbl->is_SGI = 0;
        }
 
-       rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask);
+       rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, &rate_mask);
 
-       /* mask with station rate restriction */
+       /* Mask with station rate restriction */
        if (is_legacy(tbl->lq_type)) {
-               if (lq_data->phymode == (u8) MODE_IEEE80211A)
+               /* supp_rates has no CCK bits in A mode */
+               if (lq_sta->phymode == (u8) MODE_IEEE80211A)
                        rate_mask  = (u16)(rate_mask &
-                          (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
+                          (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
                else
-                       rate_mask = (u16)(rate_mask & lq_data->supp_rates);
+                       rate_mask = (u16)(rate_mask & lq_sta->supp_rates);
        }
 
-       /* if we did switched from HT to legacy check current rate */
-       if ((switch_to_legacy) &&
-           (rate_mask & (1 << scale_index))) {
+       /* If we switched from HT to legacy, check current rate */
+       if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
                rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
-               return 0;
+               return;
        }
 
        high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
@@ -602,29 +645,29 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
                rs_mcs_from_tbl(mcs_rate, tbl, low, is_green);
        else
                rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
-
-       return 0;
 }
 
-static void rs_tx_status(void *priv_rate,
-                        struct net_device *dev,
+/*
+ * mac80211 sends us Tx status
+ */
+static void rs_tx_status(void *priv_rate, struct net_device *dev,
                         struct sk_buff *skb,
                         struct ieee80211_tx_status *tx_resp)
 {
        int status;
        u8 retries;
        int rs_index, index = 0;
-       struct iwl_rate_scale_priv *lq;
-       struct iwl_link_quality_cmd *table;
+       struct iwl4965_lq_sta *lq_sta;
+       struct iwl4965_link_quality_cmd *table;
        struct sta_info *sta;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct iwl_rate_scale_data *window = NULL;
-       struct iwl_rate_scale_data *search_win = NULL;
-       struct iwl_rate tx_mcs;
-       struct iwl_scale_tbl_info tbl_type;
-       struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
+       struct iwl4965_rate_scale_data *window = NULL;
+       struct iwl4965_rate_scale_data *search_win = NULL;
+       struct iwl4965_rate tx_mcs;
+       struct iwl4965_scale_tbl_info tbl_type;
+       struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
        u8 active_index = 0;
        u16 fc = le16_to_cpu(hdr->frame_control);
        s32 tpt = 0;
@@ -648,27 +691,32 @@ static void rs_tx_status(void *priv_rate,
                return;
        }
 
-       lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
        if (!priv->lq_mngr.lq_ready)
                return;
 
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added)
+       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
+           !lq_sta->ibss_sta_added)
                return;
 
-       table = &lq->lq;
-       active_index = lq->active_tbl;
+       table = &lq_sta->lq;
+       active_index = lq_sta->active_tbl;
 
-       lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx);
-       if (!lq->antenna)
-               lq->antenna = lq->valid_antenna;
+       /* Get mac80211 antenna info */
+       lq_sta->antenna =
+               (lq_sta->valid_antenna & local->hw.conf.antenna_sel_tx);
+       if (!lq_sta->antenna)
+               lq_sta->antenna = lq_sta->valid_antenna;
 
-       lq->antenna = lq->valid_antenna;
-       curr_tbl = &(lq->lq_info[active_index]);
-       search_tbl = &(lq->lq_info[(1 - active_index)]);
-       window = (struct iwl_rate_scale_data *)
+       /* Ignore mac80211 antenna info for now */
+       lq_sta->antenna = lq_sta->valid_antenna;
+
+       curr_tbl = &(lq_sta->lq_info[active_index]);
+       search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
+       window = (struct iwl4965_rate_scale_data *)
            &(curr_tbl->win[0]);
-       search_win = (struct iwl_rate_scale_data *)
+       search_win = (struct iwl4965_rate_scale_data *)
            &(search_tbl->win[0]);
 
        tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
@@ -682,6 +730,14 @@ static void rs_tx_status(void *priv_rate,
                return;
        }
 
+       /*
+        * Ignore this Tx frame response if its initial rate doesn't match
+        * that of latest Link Quality command.  There may be stragglers
+        * from a previous Link Quality command, but we're no longer interested
+        * in those; they're either from the "active" mode while we're trying
+        * to check "search" mode, or a prior "search" mode after we've moved
+        * to a new "search" mode (which might become the new "active" mode).
+        */
        if (retries &&
            (tx_mcs.rate_n_flags !=
                                le32_to_cpu(table->rs_table[0].rate_n_flags))) {
@@ -692,12 +748,17 @@ static void rs_tx_status(void *priv_rate,
                return;
        }
 
+       /* Update frame history window with "failure" for each Tx retry. */
        while (retries) {
+               /* Look up the rate and other info used for each tx attempt.
+                * Each tx attempt steps one entry deeper in the rate table. */
                tx_mcs.rate_n_flags =
                    le32_to_cpu(table->rs_table[index].rate_n_flags);
                rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
                                          &tbl_type, &rs_index);
 
+               /* If type matches "search" table,
+                * add failure to "search" history */
                if ((tbl_type.lq_type == search_tbl->lq_type) &&
                    (tbl_type.antenna_type == search_tbl->antenna_type) &&
                    (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -705,8 +766,10 @@ static void rs_tx_status(void *priv_rate,
                                tpt = search_tbl->expected_tpt[rs_index];
                        else
                                tpt = 0;
-                       rs_collect_tx_data(search_win,
-                                           rs_index, tpt, 0);
+                       rs_collect_tx_data(search_win, rs_index, tpt, 0);
+
+               /* Else if type matches "current/active" table,
+                * add failure to "current/active" history */
                } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
                           (tbl_type.antenna_type == curr_tbl->antenna_type) &&
                           (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -716,13 +779,21 @@ static void rs_tx_status(void *priv_rate,
                                tpt = 0;
                        rs_collect_tx_data(window, rs_index, tpt, 0);
                }
-               if (lq->stay_in_tbl)
-                       lq->total_failed++;
+
+               /* If not searching for a new mode, increment failed counter
+                * ... this helps determine when to start searching again */
+               if (lq_sta->stay_in_tbl)
+                       lq_sta->total_failed++;
                --retries;
                index++;
 
        }
 
+       /*
+        * Find (by rate) the history window to update with final Tx attempt;
+        * if Tx was successful first try, use original rate,
+        * else look up the rate that was, finally, successful.
+        */
        if (!tx_resp->retry_count)
                tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
        else
@@ -732,11 +803,14 @@ static void rs_tx_status(void *priv_rate,
        rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
                                  &tbl_type, &rs_index);
 
+       /* Update frame history window with "success" if Tx got ACKed ... */
        if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
                status = 1;
        else
                status = 0;
 
+       /* If type matches "search" table,
+        * add final tx status to "search" history */
        if ((tbl_type.lq_type == search_tbl->lq_type) &&
            (tbl_type.antenna_type == search_tbl->antenna_type) &&
            (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -746,6 +820,9 @@ static void rs_tx_status(void *priv_rate,
                        tpt = 0;
                rs_collect_tx_data(search_win,
                                    rs_index, tpt, status);
+
+       /* Else if type matches "current/active" table,
+        * add final tx status to "current/active" history */
        } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
                   (tbl_type.antenna_type == curr_tbl->antenna_type) &&
                   (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -756,67 +833,77 @@ static void rs_tx_status(void *priv_rate,
                rs_collect_tx_data(window, rs_index, tpt, status);
        }
 
-       if (lq->stay_in_tbl) {
+       /* If not searching for new mode, increment success/failed counter
+        * ... these help determine when to start searching again */
+       if (lq_sta->stay_in_tbl) {
                if (status)
-                       lq->total_success++;
+                       lq_sta->total_success++;
                else
-                       lq->total_failed++;
+                       lq_sta->total_failed++;
        }
 
+       /* See if there's a better rate or modulation mode to try. */
        rs_rate_scale_perform(priv, dev, hdr, sta);
        sta_info_put(sta);
        return;
 }
 
 static u8 rs_is_ant_connected(u8 valid_antenna,
-                             enum iwl_antenna_type antenna_type)
+                             enum iwl4965_antenna_type antenna_type)
 {
        if (antenna_type == ANT_AUX)
                return ((valid_antenna & 0x2) ? 1:0);
        else if (antenna_type == ANT_MAIN)
                return ((valid_antenna & 0x1) ? 1:0);
-       else if (antenna_type == ANT_BOTH) {
-               if ((valid_antenna & 0x3) == 0x3)
-                       return 1;
-               else
-                       return 0;
-       }
+       else if (antenna_type == ANT_BOTH)
+               return ((valid_antenna & 0x3) == 0x3);
 
        return 1;
 }
 
 static u8 rs_is_other_ant_connected(u8 valid_antenna,
-                                   enum iwl_antenna_type antenna_type)
+                                   enum iwl4965_antenna_type antenna_type)
 {
        if (antenna_type == ANT_AUX)
-               return (rs_is_ant_connected(valid_antenna, ANT_MAIN));
+               return rs_is_ant_connected(valid_antenna, ANT_MAIN);
        else
-               return (rs_is_ant_connected(valid_antenna, ANT_AUX));
+               return rs_is_ant_connected(valid_antenna, ANT_AUX);
 
        return 0;
 }
 
+/*
+ * Begin a period of staying with a selected modulation mode.
+ * Set "stay_in_tbl" flag to prevent any mode switches.
+ * Set frame tx success limits according to legacy vs. high-throughput,
+ * and reset overall (spanning all rates) tx success history statistics.
+ * These control how long we stay using same modulation mode before
+ * searching for a new mode.
+ */
 static void rs_set_stay_in_table(u8 is_legacy,
-                                struct iwl_rate_scale_priv *lq_data)
+                                struct iwl4965_lq_sta *lq_sta)
 {
        IWL_DEBUG_HT("we are staying in the same table\n");
-       lq_data->stay_in_tbl = 1;
+       lq_sta->stay_in_tbl = 1;        /* only place this gets set */
        if (is_legacy) {
-               lq_data->table_count_limit = IWL_LEGACY_TABLE_COUNT;
-               lq_data->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
-               lq_data->max_success_limit = IWL_LEGACY_TABLE_COUNT;
+               lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT;
+               lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
+               lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT;
        } else {
-               lq_data->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
-               lq_data->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
-               lq_data->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
+               lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT;
+               lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT;
+               lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT;
        }
-       lq_data->table_count = 0;
-       lq_data->total_failed = 0;
-       lq_data->total_success = 0;
+       lq_sta->table_count = 0;
+       lq_sta->total_failed = 0;
+       lq_sta->total_success = 0;
 }
 
-static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data,
-                                     struct iwl_scale_tbl_info *tbl)
+/*
+ * Find correct throughput table for given mode of modulation
+ */
+static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
+                                     struct iwl4965_scale_tbl_info *tbl)
 {
        if (is_legacy(tbl->lq_type)) {
                if (!is_a_band(tbl->lq_type))
@@ -824,7 +911,7 @@ static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data,
                else
                        tbl->expected_tpt = expected_tpt_A;
        } else if (is_siso(tbl->lq_type)) {
-               if (tbl->is_fat && !lq_data->is_dup)
+               if (tbl->is_fat && !lq_sta->is_dup)
                        if (tbl->is_SGI)
                                tbl->expected_tpt = expected_tpt_siso40MHzSGI;
                        else
@@ -835,7 +922,7 @@ static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data,
                        tbl->expected_tpt = expected_tpt_siso20MHz;
 
        } else if (is_mimo(tbl->lq_type)) {
-               if (tbl->is_fat && !lq_data->is_dup)
+               if (tbl->is_fat && !lq_sta->is_dup)
                        if (tbl->is_SGI)
                                tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
                        else
@@ -848,18 +935,34 @@ static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data,
                tbl->expected_tpt = expected_tpt_G;
 }
 
-#ifdef CONFIG_IWLWIFI_HT
-static s32 rs_get_best_rate(struct iwl_priv *priv,
-                           struct iwl_rate_scale_priv *lq_data,
-                           struct iwl_scale_tbl_info *tbl,
+#ifdef CONFIG_IWL4965_HT
+/*
+ * Find starting rate for new "search" high-throughput mode of modulation.
+ * Goal is to find lowest expected rate (under perfect conditions) that is
+ * above the current measured throughput of "active" mode, to give new mode
+ * a fair chance to prove itself without too many challenges.
+ *
+ * This gets called when transitioning to more aggressive modulation
+ * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
+ * (i.e. MIMO to SISO).  When moving to MIMO, bit rate will typically need
+ * to decrease to match "active" throughput.  When moving from MIMO to SISO,
+ * bit rate will typically need to increase, but not if performance was bad.
+ */
+static s32 rs_get_best_rate(struct iwl4965_priv *priv,
+                           struct iwl4965_lq_sta *lq_sta,
+                           struct iwl4965_scale_tbl_info *tbl, /* "search" */
                            u16 rate_mask, s8 index, s8 rate)
 {
-       struct iwl_scale_tbl_info *active_tbl =
-           &(lq_data->lq_info[lq_data->active_tbl]);
-       s32 new_rate, high, low, start_hi;
+       /* "active" values */
+       struct iwl4965_scale_tbl_info *active_tbl =
+           &(lq_sta->lq_info[lq_sta->active_tbl]);
        s32 active_sr = active_tbl->win[index].success_ratio;
-       s32 *tpt_tbl = tbl->expected_tpt;
        s32 active_tpt = active_tbl->expected_tpt[index];
+
+       /* expected "search" throughput */
+       s32 *tpt_tbl = tbl->expected_tpt;
+
+       s32 new_rate, high, low, start_hi;
        u16 high_low;
 
        new_rate = high = low = start_hi = IWL_RATE_INVALID;
@@ -870,28 +973,60 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
                low = high_low & 0xff;
                high = (high_low >> 8) & 0xff;
 
-               if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) &&
+               /*
+                * Lower the "search" bit rate, to give new "search" mode
+                * approximately the same throughput as "active" if:
+                *
+                * 1) "Active" mode has been working modestly well (but not
+                *    great), and expected "search" throughput (under perfect
+                *    conditions) at candidate rate is above the actual
+                *    measured "active" throughput (but less than expected
+                *    "active" throughput under perfect conditions).
+                * OR
+                * 2) "Active" mode has been working perfectly or very well
+                *    and expected "search" throughput (under perfect
+                *    conditions) at candidate rate is above expected
+                *    "active" throughput (under perfect conditions).
+                */
+               if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
                     ((active_sr > IWL_RATE_DECREASE_TH) &&
                      (active_sr <= IWL_RATE_HIGH_TH) &&
                      (tpt_tbl[rate] <= active_tpt))) ||
                    ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
                     (tpt_tbl[rate] > active_tpt))) {
 
+                       /* (2nd or later pass)
+                        * If we've already tried to raise the rate, and are
+                        * now trying to lower it, use the higher rate. */
                        if (start_hi != IWL_RATE_INVALID) {
                                new_rate = start_hi;
                                break;
                        }
+
                        new_rate = rate;
+
+                       /* Loop again with lower rate */
                        if (low != IWL_RATE_INVALID)
                                rate = low;
+
+                       /* Lower rate not available, use the original */
                        else
                                break;
+
+               /* Else try to raise the "search" rate to match "active" */
                } else {
+                       /* (2nd or later pass)
+                        * If we've already tried to lower the rate, and are
+                        * now trying to raise it, use the lower rate. */
                        if (new_rate != IWL_RATE_INVALID)
                                break;
+
+                       /* Loop again with higher rate */
                        else if (high != IWL_RATE_INVALID) {
                                start_hi = high;
                                rate = high;
+
+                       /* Higher rate not available, use the original */
                        } else {
                                new_rate = rate;
                                break;
@@ -901,58 +1036,64 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
 
        return new_rate;
 }
-#endif                         /* CONFIG_IWLWIFI_HT */
+#endif                         /* CONFIG_IWL4965_HT */
 
 static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
 {
        return (rs_is_ant_connected(valid_antenna, ANT_BOTH));
 }
 
-static int rs_switch_to_mimo(struct iwl_priv *priv,
-                            struct iwl_rate_scale_priv *lq_data,
-                            struct iwl_scale_tbl_info *tbl, int index)
+/*
+ * Set up search table for MIMO
+ */
+static int rs_switch_to_mimo(struct iwl4965_priv *priv,
+                            struct iwl4965_lq_sta *lq_sta,
+                            struct ieee80211_conf *conf,
+                            struct sta_info *sta,
+                            struct iwl4965_scale_tbl_info *tbl, int index)
 {
-       int rc = -1;
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
        u16 rate_mask;
        s32 rate;
-       s8 is_green = lq_data->is_green;
+       s8 is_green = lq_sta->is_green;
 
-       if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
+       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
+           !sta->ht_info.ht_supported)
                return -1;
 
        IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
        tbl->lq_type = LQ_MIMO;
-       rs_get_supported_rates(lq_data, NULL, tbl->lq_type,
+       rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
                                &rate_mask);
 
-       if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
+       if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
                return -1;
 
-       if (!rs_is_both_ant_supp(lq_data->antenna))
+       /* Need both Tx chains/antennas to support MIMO */
+       if (!rs_is_both_ant_supp(lq_sta->antenna))
                return -1;
 
-       rc = 0;
-       tbl->is_dup = lq_data->is_dup;
+       tbl->is_dup = lq_sta->is_dup;
        tbl->action = 0;
-       if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
+       if (priv->current_ht_config.supported_chan_width
+           == IWL_CHANNEL_WIDTH_40MHZ)
                tbl->is_fat = 1;
        else
                tbl->is_fat = 0;
 
        if (tbl->is_fat) {
-               if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
+               if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
                        tbl->is_SGI = 1;
                else
                        tbl->is_SGI = 0;
-       } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY)
+       } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
                tbl->is_SGI = 1;
        else
                tbl->is_SGI = 0;
 
-       rs_get_expected_tpt_table(lq_data, tbl);
+       rs_get_expected_tpt_table(lq_sta, tbl);
 
-       rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index);
+       rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
 
        IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask);
        if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask))
@@ -961,43 +1102,49 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
 
        IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
                     tbl->current_rate.rate_n_flags, is_green);
-
-#endif                         /*CONFIG_IWLWIFI_HT */
-       return rc;
+       return 0;
+#else
+       return -1;
+#endif                         /*CONFIG_IWL4965_HT */
 }
 
-static int rs_switch_to_siso(struct iwl_priv *priv,
-                            struct iwl_rate_scale_priv *lq_data,
-                            struct iwl_scale_tbl_info *tbl, int index)
+/*
+ * Set up search table for SISO
+ */
+static int rs_switch_to_siso(struct iwl4965_priv *priv,
+                            struct iwl4965_lq_sta *lq_sta,
+                            struct ieee80211_conf *conf,
+                            struct sta_info *sta,
+                            struct iwl4965_scale_tbl_info *tbl, int index)
 {
-       int rc = -1;
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
        u16 rate_mask;
-       u8 is_green = lq_data->is_green;
+       u8 is_green = lq_sta->is_green;
        s32 rate;
 
        IWL_DEBUG_HT("LQ: try to switch to SISO\n");
-       if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht)
+       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
+           !sta->ht_info.ht_supported)
                return -1;
 
-       rc = 0;
-       tbl->is_dup = lq_data->is_dup;
+       tbl->is_dup = lq_sta->is_dup;
        tbl->lq_type = LQ_SISO;
        tbl->action = 0;
-       rs_get_supported_rates(lq_data, NULL, tbl->lq_type,
+       rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
                                &rate_mask);
 
-       if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ)
+       if (priv->current_ht_config.supported_chan_width
+           == IWL_CHANNEL_WIDTH_40MHZ)
                tbl->is_fat = 1;
        else
                tbl->is_fat = 0;
 
        if (tbl->is_fat) {
-               if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY)
+               if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
                        tbl->is_SGI = 1;
                else
                        tbl->is_SGI = 0;
-       } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY)
+       } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
                tbl->is_SGI = 1;
        else
                tbl->is_SGI = 0;
@@ -1005,8 +1152,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        if (is_green)
                tbl->is_SGI = 0;
 
-       rs_get_expected_tpt_table(lq_data, tbl);
-       rate = rs_get_best_rate(priv, lq_data, tbl, rate_mask, index, index);
+       rs_get_expected_tpt_table(lq_sta, tbl);
+       rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
 
        IWL_DEBUG_HT("LQ: get best rate %d mask %X\n", rate, rate_mask);
        if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
@@ -1017,23 +1164,30 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green);
        IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
                     tbl->current_rate.rate_n_flags, is_green);
+       return 0;
+#else
+       return -1;
 
-#endif                         /*CONFIG_IWLWIFI_HT */
-       return rc;
+#endif                         /*CONFIG_IWL4965_HT */
 }
 
-static int rs_move_legacy_other(struct iwl_priv *priv,
-                               struct iwl_rate_scale_priv *lq_data,
+/*
+ * Try to switch to new modulation mode from legacy
+ */
+static int rs_move_legacy_other(struct iwl4965_priv *priv,
+                               struct iwl4965_lq_sta *lq_sta,
+                               struct ieee80211_conf *conf,
+                               struct sta_info *sta,
                                int index)
 {
-       int rc = 0;
-       struct iwl_scale_tbl_info *tbl =
-           &(lq_data->lq_info[lq_data->active_tbl]);
-       struct iwl_scale_tbl_info *search_tbl =
-           &(lq_data->lq_info[(1 - lq_data->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));
+       int ret = 0;
+       struct iwl4965_scale_tbl_info *tbl =
+           &(lq_sta->lq_info[lq_sta->active_tbl]);
+       struct iwl4965_scale_tbl_info *search_tbl =
+           &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+       struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
+       u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
+                 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
        u8 start_action = tbl->action;
 
        for (; ;) {
@@ -1042,52 +1196,59 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
                        IWL_DEBUG_HT("LQ Legacy switch Antenna\n");
 
                        search_tbl->lq_type = LQ_NONE;
-                       lq_data->action_counter++;
+                       lq_sta->action_counter++;
+
+                       /* Don't change antenna if success has been great */
                        if (window->success_ratio >= IWL_RS_GOOD_RATIO)
                                break;
-                       if (!rs_is_other_ant_connected(lq_data->antenna,
+
+                       /* Don't change antenna if other one is not connected */
+                       if (!rs_is_other_ant_connected(lq_sta->antenna,
                                                        tbl->antenna_type))
                                break;
 
+                       /* Set up search table to try other antenna */
                        memcpy(search_tbl, tbl, sz);
 
                        rs_toggle_antenna(&(search_tbl->current_rate),
                                           search_tbl);
-                       rs_get_expected_tpt_table(lq_data, search_tbl);
-                       lq_data->search_better_tbl = 1;
+                       rs_get_expected_tpt_table(lq_sta, search_tbl);
+                       lq_sta->search_better_tbl = 1;
                        goto out;
 
                case IWL_LEGACY_SWITCH_SISO:
                        IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
+
+                       /* Set up search table to try SISO */
                        memcpy(search_tbl, tbl, sz);
                        search_tbl->lq_type = LQ_SISO;
                        search_tbl->is_SGI = 0;
                        search_tbl->is_fat = 0;
-                       rc = rs_switch_to_siso(priv, lq_data, search_tbl,
-                                              index);
-                       if (!rc) {
-                               lq_data->search_better_tbl = 1;
-                               lq_data->action_counter = 0;
-                       }
-                       if (!rc)
+                       ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret) {
+                               lq_sta->search_better_tbl = 1;
+                               lq_sta->action_counter = 0;
                                goto out;
+                       }
 
                        break;
                case IWL_LEGACY_SWITCH_MIMO:
                        IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
+
+                       /* Set up search table to try MIMO */
                        memcpy(search_tbl, tbl, sz);
                        search_tbl->lq_type = LQ_MIMO;
                        search_tbl->is_SGI = 0;
                        search_tbl->is_fat = 0;
                        search_tbl->antenna_type = ANT_BOTH;
-                       rc = rs_switch_to_mimo(priv, lq_data, search_tbl,
-                                              index);
-                       if (!rc) {
-                               lq_data->search_better_tbl = 1;
-                               lq_data->action_counter = 0;
-                       }
-                       if (!rc)
+                       ret = rs_switch_to_mimo(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret) {
+                               lq_sta->search_better_tbl = 1;
+                               lq_sta->action_counter = 0;
                                goto out;
+                       }
                        break;
                }
                tbl->action++;
@@ -1108,30 +1269,35 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
 
 }
 
-static int rs_move_siso_to_other(struct iwl_priv *priv,
-                                struct iwl_rate_scale_priv *lq_data,
+/*
+ * Try to switch to new modulation mode from SISO
+ */
+static int rs_move_siso_to_other(struct iwl4965_priv *priv,
+                                struct iwl4965_lq_sta *lq_sta,
+                                struct ieee80211_conf *conf,
+                                struct sta_info *sta,
                                 int index)
 {
-       int rc = -1;
-       u8 is_green = lq_data->is_green;
-       struct iwl_scale_tbl_info *tbl =
-           &(lq_data->lq_info[lq_data->active_tbl]);
-       struct iwl_scale_tbl_info *search_tbl =
-           &(lq_data->lq_info[(1 - lq_data->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));
+       int ret;
+       u8 is_green = lq_sta->is_green;
+       struct iwl4965_scale_tbl_info *tbl =
+           &(lq_sta->lq_info[lq_sta->active_tbl]);
+       struct iwl4965_scale_tbl_info *search_tbl =
+           &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+       struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
+       u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
+                 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
        u8 start_action = tbl->action;
 
        for (;;) {
-               lq_data->action_counter++;
+               lq_sta->action_counter++;
                switch (tbl->action) {
                case IWL_SISO_SWITCH_ANTENNA:
                        IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n");
                        search_tbl->lq_type = LQ_NONE;
                        if (window->success_ratio >= IWL_RS_GOOD_RATIO)
                                break;
-                       if (!rs_is_other_ant_connected(lq_data->antenna,
+                       if (!rs_is_other_ant_connected(lq_sta->antenna,
                                                       tbl->antenna_type))
                                break;
 
@@ -1139,7 +1305,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
                        search_tbl->action = IWL_SISO_SWITCH_MIMO;
                        rs_toggle_antenna(&(search_tbl->current_rate),
                                           search_tbl);
-                       lq_data->search_better_tbl = 1;
+                       lq_sta->search_better_tbl = 1;
 
                        goto out;
 
@@ -1150,13 +1316,12 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
                        search_tbl->is_SGI = 0;
                        search_tbl->is_fat = 0;
                        search_tbl->antenna_type = ANT_BOTH;
-                       rc = rs_switch_to_mimo(priv, lq_data, search_tbl,
-                                              index);
-                       if (!rc)
-                               lq_data->search_better_tbl = 1;
-
-                       if (!rc)
+                       ret = rs_switch_to_mimo(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret) {
+                               lq_sta->search_better_tbl = 1;
                                goto out;
+                       }
                        break;
                case IWL_SISO_SWITCH_GI:
                        IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n");
@@ -1168,17 +1333,17 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
                                search_tbl->is_SGI = 1;
                        else
                                break;
-                       lq_data->search_better_tbl = 1;
+                       lq_sta->search_better_tbl = 1;
                        if ((tbl->lq_type == LQ_SISO) &&
                            (tbl->is_SGI)) {
-                               s32 tpt = lq_data->last_tpt / 100;
+                               s32 tpt = lq_sta->last_tpt / 100;
                                if (((!tbl->is_fat) &&
                                     (tpt >= expected_tpt_siso20MHz[index])) ||
                                    ((tbl->is_fat) &&
                                     (tpt >= expected_tpt_siso40MHz[index])))
-                                       lq_data->search_better_tbl = 0;
+                                       lq_sta->search_better_tbl = 0;
                        }
-                       rs_get_expected_tpt_table(lq_data, search_tbl);
+                       rs_get_expected_tpt_table(lq_sta, search_tbl);
                        rs_mcs_from_tbl(&search_tbl->current_rate,
                                             search_tbl, index, is_green);
                        goto out;
@@ -1199,26 +1364,33 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
        return 0;
 }
 
-static int rs_move_mimo_to_other(struct iwl_priv *priv,
-                                struct iwl_rate_scale_priv *lq_data,
+/*
+ * Try to switch to new modulation mode from MIMO
+ */
+static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
+                                struct iwl4965_lq_sta *lq_sta,
+                                struct ieee80211_conf *conf,
+                                struct sta_info *sta,
                                 int index)
 {
-       int rc = -1;
-       s8 is_green = lq_data->is_green;
-       struct iwl_scale_tbl_info *tbl =
-           &(lq_data->lq_info[lq_data->active_tbl]);
-       struct iwl_scale_tbl_info *search_tbl =
-           &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
-       u32 sz = (sizeof(struct iwl_scale_tbl_info) -
-                 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
+       int ret;
+       s8 is_green = lq_sta->is_green;
+       struct iwl4965_scale_tbl_info *tbl =
+           &(lq_sta->lq_info[lq_sta->active_tbl]);
+       struct iwl4965_scale_tbl_info *search_tbl =
+           &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+       u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
+                 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
        u8 start_action = tbl->action;
 
        for (;;) {
-               lq_data->action_counter++;
+               lq_sta->action_counter++;
                switch (tbl->action) {
                case IWL_MIMO_SWITCH_ANTENNA_A:
                case IWL_MIMO_SWITCH_ANTENNA_B:
                        IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n");
+
+                       /* Set up new search table for SISO */
                        memcpy(search_tbl, tbl, sz);
                        search_tbl->lq_type = LQ_SISO;
                        search_tbl->is_SGI = 0;
@@ -1228,16 +1400,18 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
                        else
                                search_tbl->antenna_type = ANT_AUX;
 
-                       rc = rs_switch_to_siso(priv, lq_data, search_tbl,
-                                              index);
-                       if (!rc) {
-                               lq_data->search_better_tbl = 1;
+                       ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret) {
+                               lq_sta->search_better_tbl = 1;
                                goto out;
                        }
                        break;
 
                case IWL_MIMO_SWITCH_GI:
                        IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n");
+
+                       /* Set up new search table for MIMO */
                        memcpy(search_tbl, tbl, sz);
                        search_tbl->lq_type = LQ_MIMO;
                        search_tbl->antenna_type = ANT_BOTH;
@@ -1246,17 +1420,24 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
                                search_tbl->is_SGI = 0;
                        else
                                search_tbl->is_SGI = 1;
-                       lq_data->search_better_tbl = 1;
+                       lq_sta->search_better_tbl = 1;
+
+                       /*
+                        * 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->lq_type == LQ_MIMO) &&
                            (tbl->is_SGI)) {
-                               s32 tpt = lq_data->last_tpt / 100;
+                               s32 tpt = lq_sta->last_tpt / 100;
                                if (((!tbl->is_fat) &&
                                     (tpt >= expected_tpt_mimo20MHz[index])) ||
                                    ((tbl->is_fat) &&
                                     (tpt >= expected_tpt_mimo40MHz[index])))
-                                       lq_data->search_better_tbl = 0;
+                                       lq_sta->search_better_tbl = 0;
                        }
-                       rs_get_expected_tpt_table(lq_data, search_tbl);
+                       rs_get_expected_tpt_table(lq_sta, search_tbl);
                        rs_mcs_from_tbl(&search_tbl->current_rate,
                                             search_tbl, index, is_green);
                        goto out;
@@ -1279,43 +1460,71 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
 
 }
 
-static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data)
+/*
+ * Check whether we should continue using same modulation mode, or
+ * begin search for a new mode, based on:
+ * 1) # tx successes or failures while using this mode
+ * 2) # times calling this function
+ * 3) elapsed time in this mode (not used, for now)
+ */
+static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
 {
-       struct iwl_scale_tbl_info *tbl;
+       struct iwl4965_scale_tbl_info *tbl;
        int i;
        int active_tbl;
        int flush_interval_passed = 0;
 
-       active_tbl = lq_data->active_tbl;
+       active_tbl = lq_sta->active_tbl;
 
-       tbl = &(lq_data->lq_info[active_tbl]);
+       tbl = &(lq_sta->lq_info[active_tbl]);
 
-       if (lq_data->stay_in_tbl) {
+       /* If we've been disallowing search, see if we should now allow it */
+       if (lq_sta->stay_in_tbl) {
 
-               if (lq_data->flush_timer)
+               /* Elapsed time using current modulation mode */
+               if (lq_sta->flush_timer)
                        flush_interval_passed =
                            time_after(jiffies,
-                                      (unsigned long)(lq_data->flush_timer +
+                                      (unsigned long)(lq_sta->flush_timer +
                                        IWL_RATE_SCALE_FLUSH_INTVL));
 
+               /* For now, disable the elapsed time criterion */
                flush_interval_passed = 0;
-               if ((lq_data->total_failed > lq_data->max_failure_limit) ||
-                   (lq_data->total_success > lq_data->max_success_limit) ||
-                   ((!lq_data->search_better_tbl) && (lq_data->flush_timer)
+
+               /*
+                * Check if we should allow search for new modulation mode.
+                * If many frames have failed or succeeded, or we've used
+                * this same modulation for a long time, allow search, and
+                * reset history stats that keep track of whether we should
+                * allow a new search.  Also (below) reset all bitmaps and
+                * stats in active history.
+                */
+               if ((lq_sta->total_failed > lq_sta->max_failure_limit) ||
+                   (lq_sta->total_success > lq_sta->max_success_limit) ||
+                   ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer)
                     && (flush_interval_passed))) {
                        IWL_DEBUG_HT("LQ: stay is expired %d %d %d\n:",
-                                    lq_data->total_failed,
-                                    lq_data->total_success,
+                                    lq_sta->total_failed,
+                                    lq_sta->total_success,
                                     flush_interval_passed);
-                       lq_data->stay_in_tbl = 0;
-                       lq_data->total_failed = 0;
-                       lq_data->total_success = 0;
-                       lq_data->flush_timer = 0;
-               } else if (lq_data->table_count > 0) {
-                       lq_data->table_count++;
-                       if (lq_data->table_count >=
-                           lq_data->table_count_limit) {
-                               lq_data->table_count = 0;
+
+                       /* Allow search for new mode */
+                       lq_sta->stay_in_tbl = 0;        /* only place reset */
+                       lq_sta->total_failed = 0;
+                       lq_sta->total_success = 0;
+                       lq_sta->flush_timer = 0;
+
+               /*
+                * Else if we've used this modulation mode enough repetitions
+                * (regardless of elapsed time or success/failure), reset
+                * history bitmaps and rate-specific stats for all rates in
+                * active table.
+                */
+               } else {
+                       lq_sta->table_count++;
+                       if (lq_sta->table_count >=
+                           lq_sta->table_count_limit) {
+                               lq_sta->table_count = 0;
 
                                IWL_DEBUG_HT("LQ: stay in table clear win\n");
                                for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -1324,23 +1533,32 @@ static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data)
                        }
                }
 
-               if (!lq_data->stay_in_tbl) {
+               /* If transitioning to allow "search", reset all history
+                * bitmaps and stats in active table (this will become the new
+                * "search" table). */
+               if (!lq_sta->stay_in_tbl) {
                        for (i = 0; i < IWL_RATE_COUNT; i++)
                                rs_rate_scale_clear_window(&(tbl->win[i]));
                }
        }
 }
 
-static void rs_rate_scale_perform(struct iwl_priv *priv,
+/*
+ * Do rate scaling and search for new modulation mode.
+ */
+static void rs_rate_scale_perform(struct iwl4965_priv *priv,
                                  struct net_device *dev,
                                  struct ieee80211_hdr *hdr,
                                  struct sta_info *sta)
 {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hw *hw = local_to_hw(local);
+       struct ieee80211_conf *conf = &hw->conf;
        int low = IWL_RATE_INVALID;
        int high = IWL_RATE_INVALID;
        int index;
        int i;
-       struct iwl_rate_scale_data *window = NULL;
+       struct iwl4965_rate_scale_data *window = NULL;
        int current_tpt = IWL_INVALID_VALUE;
        int low_tpt = IWL_INVALID_VALUE;
        int high_tpt = IWL_INVALID_VALUE;
@@ -1348,10 +1566,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
        s8 scale_action = 0;
        u16 fc, rate_mask;
        u8 update_lq = 0;
-       struct iwl_rate_scale_priv *lq_data;
-       struct iwl_scale_tbl_info *tbl, *tbl1;
+       struct iwl4965_lq_sta *lq_sta;
+       struct iwl4965_scale_tbl_info *tbl, *tbl1;
        u16 rate_scale_index_msk = 0;
-       struct iwl_rate mcs_rate;
+       struct iwl4965_rate mcs_rate;
        u8 is_green = 0;
        u8 active_tbl = 0;
        u8 done_search = 0;
@@ -1374,34 +1592,42 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                IWL_DEBUG_RATE("still rate scaling not ready\n");
                return;
        }
-       lq_data = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
 
-       if (!lq_data->search_better_tbl)
-               active_tbl = lq_data->active_tbl;
+       /*
+        * Select rate-scale / modulation-mode table to work with in
+        * the rest of this function:  "search" if searching for better
+        * modulation mode, or "active" if doing rate scaling within a mode.
+        */
+       if (!lq_sta->search_better_tbl)
+               active_tbl = lq_sta->active_tbl;
        else
-               active_tbl = 1 - lq_data->active_tbl;
+               active_tbl = 1 - lq_sta->active_tbl;
 
-       tbl = &(lq_data->lq_info[active_tbl]);
-       is_green = lq_data->is_green;
+       tbl = &(lq_sta->lq_info[active_tbl]);
+       is_green = lq_sta->is_green;
 
+       /* current tx rate */
        index = sta->last_txrate;
 
        IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
                       tbl->lq_type);
 
-       rs_get_supported_rates(lq_data, hdr, tbl->lq_type,
+       /* rates available for this association, and for modulation mode */
+       rs_get_supported_rates(lq_sta, hdr, tbl->lq_type,
                                &rate_mask);
 
        IWL_DEBUG_RATE("mask 0x%04X \n", rate_mask);
 
        /* mask with station rate restriction */
        if (is_legacy(tbl->lq_type)) {
-               if (lq_data->phymode == (u8) MODE_IEEE80211A)
+               if (lq_sta->phymode == (u8) MODE_IEEE80211A)
+                       /* supp_rates has no CCK bits in A mode */
                        rate_scale_index_msk = (u16) (rate_mask &
-                               (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
+                               (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
                else
                        rate_scale_index_msk = (u16) (rate_mask &
-                                                     lq_data->supp_rates);
+                                                     lq_sta->supp_rates);
 
        } else
                rate_scale_index_msk = rate_mask;
@@ -1409,11 +1635,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
        if (!rate_scale_index_msk)
                rate_scale_index_msk = rate_mask;
 
+       /* If current rate is no longer supported on current association,
+        * or user changed preferences for rates, find a new supported rate. */
        if (index < 0 || !((1 << index) & rate_scale_index_msk)) {
                index = IWL_INVALID_VALUE;
                update_lq = 1;
 
-               /* get the lowest availabe rate */
+               /* get the highest available rate */
                for (i = 0; i <= IWL_RATE_COUNT; i++) {
                        if ((1 << i) & rate_scale_index_msk)
                                index = i;
@@ -1425,11 +1653,19 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                }
        }
 
+       /* Get expected throughput table and history window for current rate */
        if (!tbl->expected_tpt)
-               rs_get_expected_tpt_table(lq_data, tbl);
+               rs_get_expected_tpt_table(lq_sta, tbl);
 
        window = &(tbl->win[index]);
 
+       /*
+        * If there is not enough history to calculate actual average
+        * throughput, keep analyzing results of more tx frames, without
+        * changing rate or mode (bypass most of the rest of this function).
+        * Set up new rate table in uCode only if old rate is not supported
+        * in current association (use new rate found above).
+        */
        fail_count = window->counter - window->success_counter;
        if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
             (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
@@ -1437,82 +1673,118 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
                               "for index %d\n",
                               window->success_counter, window->counter, index);
+
+               /* Can't calculate this yet; not enough history */
                window->average_tpt = IWL_INVALID_VALUE;
-               rs_stay_in_table(lq_data);
+
+               /* Should we stay with this modulation mode,
+                * or search for a new one? */
+               rs_stay_in_table(lq_sta);
+
+               /* Set up new rate table in uCode, if needed */
                if (update_lq) {
                        rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-                       rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
-                       rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
+                       rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
+                       rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
                }
                goto out;
 
+       /* Else we have enough samples; calculate estimate of
+        * actual average throughput */
        } else
                window->average_tpt = ((window->success_ratio *
                                        tbl->expected_tpt[index] + 64) / 128);
 
-       if (lq_data->search_better_tbl) {
+       /* If we are searching for better modulation mode, check success. */
+       if (lq_sta->search_better_tbl) {
                int success_limit = IWL_RATE_SCALE_SWITCH;
 
+               /* If good success, continue using the "search" mode;
+                * no need to send new link quality command, since we're
+                * continuing to use the setup that we've been trying. */
                if ((window->success_ratio > success_limit) ||
-                   (window->average_tpt > lq_data->last_tpt)) {
+                   (window->average_tpt > lq_sta->last_tpt)) {
                        if (!is_legacy(tbl->lq_type)) {
                                IWL_DEBUG_HT("LQ: we are switching to HT"
                                             " rate suc %d current tpt %d"
                                             " old tpt %d\n",
                                             window->success_ratio,
                                             window->average_tpt,
-                                            lq_data->last_tpt);
-                               lq_data->enable_counter = 1;
+                                            lq_sta->last_tpt);
+                               lq_sta->enable_counter = 1;
                        }
-                       lq_data->active_tbl = active_tbl;
+                       /* Swap tables; "search" becomes "active" */
+                       lq_sta->active_tbl = active_tbl;
                        current_tpt = window->average_tpt;
+
+               /* Else poor success; go back to mode in "active" table */
                } else {
+                       /* Nullify "search" table */
                        tbl->lq_type = LQ_NONE;
-                       active_tbl = lq_data->active_tbl;
-                       tbl = &(lq_data->lq_info[active_tbl]);
 
-                       index = iwl_rate_index_from_plcp(
+                       /* Revert to "active" table */
+                       active_tbl = lq_sta->active_tbl;
+                       tbl = &(lq_sta->lq_info[active_tbl]);
+
+                       /* Revert to "active" rate and throughput info */
+                       index = iwl4965_rate_index_from_plcp(
                                tbl->current_rate.rate_n_flags);
+                       current_tpt = lq_sta->last_tpt;
 
+                       /* Need to set up a new rate table in uCode */
                        update_lq = 1;
-                       current_tpt = lq_data->last_tpt;
                        IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n");
                }
-               lq_data->search_better_tbl = 0;
-               done_search = 1;
+
+               /* Either way, we've made a decision; modulation mode
+                * search is done, allow rate adjustment next time. */
+               lq_sta->search_better_tbl = 0;
+               done_search = 1;        /* Don't switch modes below! */
                goto lq_update;
        }
 
+       /* (Else) not in search of better modulation mode, try for better
+        * starting rate, while staying in this mode. */
        high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
                                        tbl->lq_type);
        low = high_low & 0xff;
        high = (high_low >> 8) & 0xff;
 
+       /* Collect measured throughputs for current and adjacent rates */
        current_tpt = window->average_tpt;
-
        if (low != IWL_RATE_INVALID)
                low_tpt = tbl->win[low].average_tpt;
-
        if (high != IWL_RATE_INVALID)
                high_tpt = tbl->win[high].average_tpt;
 
-
+       /* Assume rate increase */
        scale_action = 1;
 
+       /* Too many failures, decrease rate */
        if ((window->success_ratio <= IWL_RATE_DECREASE_TH) ||
            (current_tpt == 0)) {
                IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
                scale_action = -1;
+
+       /* No throughput measured yet for adjacent rates; try increase. */
        } else if ((low_tpt == IWL_INVALID_VALUE) &&
                   (high_tpt == IWL_INVALID_VALUE))
                scale_action = 1;
+
+       /* Both adjacent throughputs are measured, but neither one has better
+        * throughput; we're using the best rate, don't change it! */
        else if ((low_tpt != IWL_INVALID_VALUE) &&
                 (high_tpt != IWL_INVALID_VALUE) &&
                 (low_tpt < current_tpt) &&
                 (high_tpt < current_tpt))
                scale_action = 0;
+
+       /* At least one adjacent rate's throughput is measured,
+        * and may have better performance. */
        else {
+               /* Higher adjacent rate's throughput is measured */
                if (high_tpt != IWL_INVALID_VALUE) {
+                       /* Higher rate has better throughput */
                        if (high_tpt > current_tpt)
                                scale_action = 1;
                        else {
@@ -1520,7 +1792,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                                    ("decrease rate because of high tpt\n");
                                scale_action = -1;
                        }
+
+               /* Lower adjacent rate's throughput is measured */
                } else if (low_tpt != IWL_INVALID_VALUE) {
+                       /* Lower rate has better throughput */
                        if (low_tpt > current_tpt) {
                                IWL_DEBUG_RATE
                                    ("decrease rate because of low tpt\n");
@@ -1530,23 +1805,30 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                }
        }
 
+       /* Sanity check; asked for decrease, but success rate or throughput
+        * has been good at old rate.  Don't change it. */
        if (scale_action == -1) {
                if ((low != IWL_RATE_INVALID) &&
                    ((window->success_ratio > IWL_RATE_HIGH_TH) ||
                     (current_tpt > (100 * tbl->expected_tpt[low]))))
                        scale_action = 0;
+
+       /* Sanity check; asked for increase, but success rate has not been great
+        * even at old rate, higher rate will be worse.  Don't change it. */
        } else if ((scale_action == 1) &&
                   (window->success_ratio < IWL_RATE_INCREASE_TH))
                scale_action = 0;
 
        switch (scale_action) {
        case -1:
+               /* Decrease starting rate, update uCode's rate table */
                if (low != IWL_RATE_INVALID) {
                        update_lq = 1;
                        index = low;
                }
                break;
        case 1:
+               /* Increase starting rate, update uCode's rate table */
                if (high != IWL_RATE_INVALID) {
                        update_lq = 1;
                        index = high;
@@ -1554,6 +1836,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
                break;
        case 0:
+               /* No change */
        default:
                break;
        }
@@ -1563,65 +1846,97 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                     index, scale_action, low, high, tbl->lq_type);
 
  lq_update:
+       /* Replace uCode's rate table for the destination station. */
        if (update_lq) {
                rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-               rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
-               rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
+               rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
+               rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
        }
-       rs_stay_in_table(lq_data);
 
-       if (!update_lq && !done_search && !lq_data->stay_in_tbl) {
-               lq_data->last_tpt = current_tpt;
+       /* Should we stay with this modulation mode, or search for a new one? */
+       rs_stay_in_table(lq_sta);
 
+       /*
+        * Search for new modulation mode if we're:
+        * 1)  Not changing rates right now
+        * 2)  Not just finishing up a search
+        * 3)  Allowing a new search
+        */
+       if (!update_lq && !done_search && !lq_sta->stay_in_tbl) {
+               /* Save current throughput to compare with "search" throughput*/
+               lq_sta->last_tpt = current_tpt;
+
+               /* Select a new "search" modulation mode to try.
+                * If one is found, set up the new "search" table. */
                if (is_legacy(tbl->lq_type))
-                       rs_move_legacy_other(priv, lq_data, index);
+                       rs_move_legacy_other(priv, lq_sta, conf, sta, index);
                else if (is_siso(tbl->lq_type))
-                       rs_move_siso_to_other(priv, lq_data, index);
+                       rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
                else
-                       rs_move_mimo_to_other(priv, lq_data, index);
+                       rs_move_mimo_to_other(priv, lq_sta, conf, sta, index);
 
-               if (lq_data->search_better_tbl) {
-                       tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
+               /* If new "search" mode was selected, set up in uCode table */
+               if (lq_sta->search_better_tbl) {
+                       /* Access the "search" table, clear its history. */
+                       tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
                        for (i = 0; i < IWL_RATE_COUNT; i++)
                                rs_rate_scale_clear_window(&(tbl->win[i]));
 
-                       index = iwl_rate_index_from_plcp(
+                       /* Use new "search" start rate */
+                       index = iwl4965_rate_index_from_plcp(
                                        tbl->current_rate.rate_n_flags);
 
                        IWL_DEBUG_HT("Switch current  mcs: %X index: %d\n",
                                     tbl->current_rate.rate_n_flags, index);
-                       rs_fill_link_cmd(lq_data, &tbl->current_rate,
-                                        &lq_data->lq);
-                       rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
+                       rs_fill_link_cmd(lq_sta, &tbl->current_rate,
+                                        &lq_sta->lq);
+                       rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
                }
-               tbl1 = &(lq_data->lq_info[lq_data->active_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),
+                * stay with best antenna legacy modulation for a while
+                * before next round of mode comparisons. */
+               tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
                if (is_legacy(tbl1->lq_type) &&
-#ifdef CONFIG_IWLWIFI_HT
-                   !priv->current_assoc_ht.is_ht &&
+#ifdef CONFIG_IWL4965_HT
+                  (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
 #endif
-                   (lq_data->action_counter >= 1)) {
-                       lq_data->action_counter = 0;
+                   (lq_sta->action_counter >= 1)) {
+                       lq_sta->action_counter = 0;
                        IWL_DEBUG_HT("LQ: STAY in legacy table\n");
-                       rs_set_stay_in_table(1, lq_data);
+                       rs_set_stay_in_table(1, lq_sta);
                }
 
-               if (lq_data->enable_counter &&
-                   (lq_data->action_counter >= IWL_ACTION_LIMIT)) {
-#ifdef CONFIG_IWLWIFI_HT_AGG
-                       if ((lq_data->last_tpt > TID_AGG_TPT_THREHOLD) &&
+               /* If we're in an HT mode, and all 3 mode switch actions
+                * 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)) {
+#ifdef CONFIG_IWL4965_HT_AGG
+                       /* If appropriate, set up aggregation! */
+                       if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) &&
                            (priv->lq_mngr.agg_ctrl.auto_agg)) {
                                priv->lq_mngr.agg_ctrl.tid_retry =
                                    TID_ALL_SPECIFIED;
                                schedule_work(&priv->agg_work);
                        }
-#endif /*CONFIG_IWLWIFI_HT_AGG */
-                       lq_data->action_counter = 0;
-                       rs_set_stay_in_table(0, lq_data);
+#endif /*CONFIG_IWL4965_HT_AGG */
+                       lq_sta->action_counter = 0;
+                       rs_set_stay_in_table(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_data->flush_timer))
-                       lq_data->flush_timer = jiffies;
+               if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer))
+                       lq_sta->flush_timer = jiffies;
        }
 
 out:
@@ -1632,7 +1947,7 @@ out:
        /* sta->txrate is an index to A mode rates which start
         * at IWL_FIRST_OFDM_RATE
         */
-       if (lq_data->phymode == (u8) MODE_IEEE80211A)
+       if (lq_sta->phymode == (u8) MODE_IEEE80211A)
                sta->txrate = i - IWL_FIRST_OFDM_RATE;
        else
                sta->txrate = i;
@@ -1641,38 +1956,39 @@ out:
 }
 
 
-static void rs_initialize_lq(struct iwl_priv *priv,
+static void rs_initialize_lq(struct iwl4965_priv *priv,
+                            struct ieee80211_conf *conf,
                             struct sta_info *sta)
 {
        int i;
-       struct iwl_rate_scale_priv *lq;
-       struct iwl_scale_tbl_info *tbl;
+       struct iwl4965_lq_sta *lq_sta;
+       struct iwl4965_scale_tbl_info *tbl;
        u8 active_tbl = 0;
        int rate_idx;
-       u8 use_green = rs_use_green(priv);
-       struct iwl_rate mcs_rate;
+       u8 use_green = rs_use_green(priv, conf);
+       struct iwl4965_rate mcs_rate;
 
        if (!sta || !sta->rate_ctrl_priv)
                goto out;
 
-       lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
        i = sta->last_txrate;
 
-       if ((lq->lq.sta_id == 0xff) &&
+       if ((lq_sta->lq.sta_id == 0xff) &&
            (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
                goto out;
 
-       if (!lq->search_better_tbl)
-               active_tbl = lq->active_tbl;
+       if (!lq_sta->search_better_tbl)
+               active_tbl = lq_sta->active_tbl;
        else
-               active_tbl = 1 - lq->active_tbl;
+               active_tbl = 1 - lq_sta->active_tbl;
 
-       tbl = &(lq->lq_info[active_tbl]);
+       tbl = &(lq_sta->lq_info[active_tbl]);
 
        if ((i < 0) || (i >= IWL_RATE_COUNT))
                i = 0;
 
-       mcs_rate.rate_n_flags = iwl_rates[i].plcp ;
+       mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ;
        mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK;
        mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
 
@@ -1686,114 +2002,95 @@ static void rs_initialize_lq(struct iwl_priv *priv,
 
        rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
        tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
-       rs_get_expected_tpt_table(lq, tbl);
-       rs_fill_link_cmd(lq, &mcs_rate, &lq->lq);
-       rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC);
+       rs_get_expected_tpt_table(lq_sta, tbl);
+       rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq);
+       rs_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
  out:
        return;
 }
 
-static struct ieee80211_rate *rs_get_lowest_rate(struct ieee80211_local
-                                                *local)
-{
-       struct ieee80211_hw_mode *mode = local->oper_hw_mode;
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       return &mode->rates[0];
-}
-
-static struct ieee80211_rate *rs_get_rate(void *priv_rate,
-                                              struct net_device *dev,
-                                              struct sk_buff *skb,
-                                              struct rate_control_extra
-                                              *extra)
+static void rs_get_rate(void *priv_rate, struct net_device *dev,
+                       struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                       struct rate_selection *sel)
 {
 
        int i;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_conf *conf = &local->hw.conf;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct sta_info *sta;
        u16 fc;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
-       struct iwl_rate_scale_priv *lq;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
+       struct iwl4965_lq_sta *lq_sta;
 
        IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
-       memset(extra, 0, sizeof(*extra));
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               return rs_get_lowest_rate(local);
-       }
-
        sta = sta_info_get(local, hdr->addr1);
 
-       if (!sta || !sta->rate_ctrl_priv) {
+       /* Send management frames and broadcast/multicast data using lowest
+        * rate. */
+       fc = le16_to_cpu(hdr->frame_control);
+       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
+           !sta || !sta->rate_ctrl_priv) {
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
                if (sta)
                        sta_info_put(sta);
-               return rs_get_lowest_rate(local);
+               return;
        }
 
-       lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
        i = sta->last_txrate;
 
-       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added) {
-               u8 sta_id = iwl_hw_find_station(priv, hdr->addr1);
+       if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
+           !lq_sta->ibss_sta_added) {
+               u8 sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
                DECLARE_MAC_BUF(mac);
 
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE("LQ: ADD station %s\n",
                                       print_mac(mac, hdr->addr1));
-                       sta_id = iwl_add_station(priv,
-                                                hdr->addr1, 0, CMD_ASYNC);
+                       sta_id = iwl4965_add_station_flags(priv, hdr->addr1,
+                                                       0, CMD_ASYNC, NULL);
                }
                if ((sta_id != IWL_INVALID_STATION)) {
-                       lq->lq.sta_id = sta_id;
-                       lq->lq.rs_table[0].rate_n_flags = 0;
-                       lq->ibss_sta_added = 1;
-                       rs_initialize_lq(priv, sta);
+                       lq_sta->lq.sta_id = sta_id;
+                       lq_sta->lq.rs_table[0].rate_n_flags = 0;
+                       lq_sta->ibss_sta_added = 1;
+                       rs_initialize_lq(priv, conf, sta);
                }
-               if (!lq->ibss_sta_added)
+               if (!lq_sta->ibss_sta_added)
                        goto done;
        }
 
  done:
+       if ((i < 0) || (i > IWL_RATE_COUNT)) {
+               sel->rate = rate_lowest(local, local->oper_hw_mode, sta);
+               return;
+       }
        sta_info_put(sta);
-       if ((i < 0) || (i > IWL_RATE_COUNT))
-               return rs_get_lowest_rate(local);
 
-       return &priv->ieee_rates[i];
+       sel->rate = &priv->ieee_rates[i];
 }
 
 static void *rs_alloc_sta(void *priv, gfp_t gfp)
 {
-       struct iwl_rate_scale_priv *crl;
+       struct iwl4965_lq_sta *lq_sta;
        int i, j;
 
        IWL_DEBUG_RATE("create station rate scale window\n");
 
-       crl = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp);
+       lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
 
-       if (crl == NULL)
+       if (lq_sta == NULL)
                return NULL;
-       crl->lq.sta_id = 0xff;
+       lq_sta->lq.sta_id = 0xff;
 
 
        for (j = 0; j < LQ_SIZE; j++)
                for (i = 0; i < IWL_RATE_COUNT; i++)
-                       rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
+                       rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
 
-       return crl;
+       return lq_sta;
 }
 
 static void rs_rate_init(void *priv_rate, void *priv_sta,
@@ -1801,16 +2098,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
                         struct sta_info *sta)
 {
        int i, j;
+       struct ieee80211_conf *conf = &local->hw.conf;
        struct ieee80211_hw_mode *mode = local->oper_hw_mode;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
-       struct iwl_rate_scale_priv *crl = priv_sta;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
+       struct iwl4965_lq_sta *lq_sta = priv_sta;
 
-       crl->flush_timer = 0;
-       crl->supp_rates = sta->supp_rates;
+       lq_sta->flush_timer = 0;
+       lq_sta->supp_rates = sta->supp_rates;
        sta->txrate = 3;
        for (j = 0; j < LQ_SIZE; j++)
                for (i = 0; i < IWL_RATE_COUNT; i++)
-                       rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
+                       rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
 
        IWL_DEBUG_RATE("rate scale global init\n");
        /* TODO: what is a good starting rate for STA? About middle? Maybe not
@@ -1818,9 +2116,9 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
         * previous packets? Need to have IEEE 802.1X auth succeed immediately
         * after assoc.. */
 
-       crl->ibss_sta_added = 0;
+       lq_sta->ibss_sta_added = 0;
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
-               u8 sta_id = iwl_hw_find_station(priv, sta->addr);
+               u8 sta_id = iwl4965_hw_find_station(priv, sta->addr);
                DECLARE_MAC_BUF(mac);
 
                /* for IBSS the call are from tasklet */
@@ -1830,77 +2128,89 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE("LQ: ADD station %s\n",
                                       print_mac(mac, sta->addr));
-                       sta_id = iwl_add_station(priv,
-                                                sta->addr, 0, CMD_ASYNC);
+                       sta_id = iwl4965_add_station_flags(priv, sta->addr,
+                                                       0, CMD_ASYNC, NULL);
                }
                if ((sta_id != IWL_INVALID_STATION)) {
-                       crl->lq.sta_id = sta_id;
-                       crl->lq.rs_table[0].rate_n_flags = 0;
+                       lq_sta->lq.sta_id = sta_id;
+                       lq_sta->lq.rs_table[0].rate_n_flags = 0;
                }
                /* FIXME: this is w/a remove it later */
                priv->assoc_station_added = 1;
        }
 
+       /* Find highest tx rate supported by hardware and destination station */
        for (i = 0; i < mode->num_rates; i++) {
                if ((sta->supp_rates & BIT(i)) &&
                    (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
                        sta->txrate = i;
        }
        sta->last_txrate = sta->txrate;
-       /* For MODE_IEEE80211A mode cck rate are at end
-        * rate table
-        */
+       /* For MODE_IEEE80211A, cck rates are at end of rate table */
        if (local->hw.conf.phymode == MODE_IEEE80211A)
                sta->last_txrate += IWL_FIRST_OFDM_RATE;
 
-       crl->is_dup = priv->is_dup;
-       crl->valid_antenna = priv->valid_antenna;
-       crl->antenna = priv->antenna;
-       crl->is_green = rs_use_green(priv);
-       crl->active_rate = priv->active_rate;
-       crl->active_rate &= ~(0x1000);
-       crl->active_rate_basic = priv->active_rate_basic;
-       crl->phymode = priv->phymode;
-#ifdef CONFIG_IWLWIFI_HT
-       crl->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1);
-       crl->active_siso_rate |= (priv->current_assoc_ht.supp_rates[0] & 0x1);
-       crl->active_siso_rate &= ~((u16)0x2);
-       crl->active_siso_rate = crl->active_siso_rate << IWL_FIRST_OFDM_RATE;
-
-       crl->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1);
-       crl->active_mimo_rate |= (priv->current_assoc_ht.supp_rates[1] & 0x1);
-       crl->active_mimo_rate &= ~((u16)0x2);
-       crl->active_mimo_rate = crl->active_mimo_rate << IWL_FIRST_OFDM_RATE;
-       IWL_DEBUG_HT("MIMO RATE 0x%X SISO MASK 0x%X\n", crl->active_siso_rate,
-                    crl->active_mimo_rate);
-#endif /*CONFIG_IWLWIFI_HT*/
+       lq_sta->is_dup = 0;
+       lq_sta->valid_antenna = priv->valid_antenna;
+       lq_sta->antenna = priv->antenna;
+       lq_sta->is_green = rs_use_green(priv, conf);
+       lq_sta->active_rate = priv->active_rate;
+       lq_sta->active_rate &= ~(0x1000);
+       lq_sta->active_rate_basic = priv->active_rate_basic;
+       lq_sta->phymode = priv->phymode;
+#ifdef CONFIG_IWL4965_HT
+       /*
+        * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
+        * supp_rates[] does not; shift to convert format, force 9 MBits off.
+        */
+       lq_sta->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0] << 1);
+       lq_sta->active_siso_rate |=
+                       (priv->current_ht_config.supp_mcs_set[0] & 0x1);
+       lq_sta->active_siso_rate &= ~((u16)0x2);
+       lq_sta->active_siso_rate =
+                       lq_sta->active_siso_rate << IWL_FIRST_OFDM_RATE;
+
+       /* Same here */
+       lq_sta->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1] << 1);
+       lq_sta->active_mimo_rate |=
+                       (priv->current_ht_config.supp_mcs_set[1] & 0x1);
+       lq_sta->active_mimo_rate &= ~((u16)0x2);
+       lq_sta->active_mimo_rate =
+                       lq_sta->active_mimo_rate << IWL_FIRST_OFDM_RATE;
+       IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n",
+                    lq_sta->active_siso_rate,
+                    lq_sta->active_mimo_rate);
+#endif /*CONFIG_IWL4965_HT*/
 #ifdef CONFIG_MAC80211_DEBUGFS
-       crl->drv = priv;
+       lq_sta->drv = priv;
 #endif
 
        if (priv->assoc_station_added)
                priv->lq_mngr.lq_ready = 1;
 
-       rs_initialize_lq(priv, sta);
+       rs_initialize_lq(priv, conf, sta);
 }
 
-static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
-                           struct iwl_rate *tx_mcs,
-                           struct iwl_link_quality_cmd *lq_cmd)
+static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
+                           struct iwl4965_rate *tx_mcs,
+                           struct iwl4965_link_quality_cmd *lq_cmd)
 {
        int index = 0;
        int rate_idx;
        int repeat_rate = 0;
        u8 ant_toggle_count = 0;
        u8 use_ht_possible = 1;
-       struct iwl_rate new_rate;
-       struct iwl_scale_tbl_info tbl_type = { 0 };
+       struct iwl4965_rate new_rate;
+       struct iwl4965_scale_tbl_info tbl_type = { 0 };
 
-       rs_dbgfs_set_mcs(lq_data, tx_mcs, index);
+       /* Override starting rate (index 0) if needed for debug purposes */
+       rs_dbgfs_set_mcs(lq_sta, tx_mcs, index);
 
-       rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode,
+       /* Interpret rate_n_flags */
+       rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode,
                                  &tbl_type, &rate_idx);
 
+       /* How many times should we repeat the initial rate? */
        if (is_legacy(tbl_type.lq_type)) {
                ant_toggle_count = 1;
                repeat_rate = IWL_NUMBER_TRY;
@@ -1909,19 +2219,27 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
 
        lq_cmd->general_params.mimo_delimiter =
                        is_mimo(tbl_type.lq_type) ? 1 : 0;
+
+       /* Fill 1st table entry (index 0) */
        lq_cmd->rs_table[index].rate_n_flags =
                        cpu_to_le32(tx_mcs->rate_n_flags);
        new_rate.rate_n_flags = tx_mcs->rate_n_flags;
 
        if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN))
-               lq_cmd->general_params.single_stream_ant_msk = 1;
+               lq_cmd->general_params.single_stream_ant_msk
+                       = LINK_QUAL_ANT_A_MSK;
        else
-               lq_cmd->general_params.single_stream_ant_msk = 2;
+               lq_cmd->general_params.single_stream_ant_msk
+                       = LINK_QUAL_ANT_B_MSK;
 
        index++;
        repeat_rate--;
 
+       /* Fill rest of rate table */
        while (index < LINK_QUAL_MAX_RETRY_NUM) {
+               /* Repeat initial/next rate.
+                * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
+                * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
                while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
                        if (is_legacy(tbl_type.lq_type)) {
                                if (ant_toggle_count <
@@ -1933,22 +2251,30 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
                                }
                        }
 
-                       rs_dbgfs_set_mcs(lq_data, &new_rate, index);
+                       /* Override next rate if needed for debug purposes */
+                       rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
+
+                       /* Fill next table entry */
                        lq_cmd->rs_table[index].rate_n_flags =
                                        cpu_to_le32(new_rate.rate_n_flags);
                        repeat_rate--;
                        index++;
                }
 
-               rs_get_tbl_info_from_mcs(&new_rate, lq_data->phymode, &tbl_type,
+               rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type,
                                                &rate_idx);
 
+               /* Indicate to uCode which entries might be MIMO.
+                * If initial rate was MIMO, this will finally end up
+                * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
                if (is_mimo(tbl_type.lq_type))
                        lq_cmd->general_params.mimo_delimiter = index;
 
-               rs_get_lower_rate(lq_data, &tbl_type, rate_idx,
+               /* Get next rate */
+               rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
                                  use_ht_possible, &new_rate);
 
+               /* How many times should we repeat the next rate? */
                if (is_legacy(tbl_type.lq_type)) {
                        if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
                                ant_toggle_count++;
@@ -1960,9 +2286,14 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
                } else
                        repeat_rate = IWL_HT_NUMBER_TRY;
 
+               /* Don't allow HT rates after next pass.
+                * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
                use_ht_possible = 0;
 
-               rs_dbgfs_set_mcs(lq_data, &new_rate, index);
+               /* Override next rate if needed for debug purposes */
+               rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
+
+               /* Fill next table entry */
                lq_cmd->rs_table[index].rate_n_flags =
                                cpu_to_le32(new_rate.rate_n_flags);
 
@@ -1987,27 +2318,27 @@ static void rs_free(void *priv_rate)
 
 static void rs_clear(void *priv_rate)
 {
-       struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *) priv_rate;
 
        IWL_DEBUG_RATE("enter\n");
 
        priv->lq_mngr.lq_ready = 0;
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        if (priv->lq_mngr.agg_ctrl.granted_ba)
                iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);
-#endif /*CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /*CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
        IWL_DEBUG_RATE("leave\n");
 }
 
 static void rs_free_sta(void *priv, void *priv_sta)
 {
-       struct iwl_rate_scale_priv *rs_priv = priv_sta;
+       struct iwl4965_lq_sta *lq_sta = priv_sta;
 
        IWL_DEBUG_RATE("enter\n");
-       kfree(rs_priv);
+       kfree(lq_sta);
        IWL_DEBUG_RATE("leave\n");
 }
 
@@ -2018,19 +2349,19 @@ static int open_file_generic(struct inode *inode, struct file *file)
        file->private_data = inode->i_private;
        return 0;
 }
-static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
-                               struct iwl_rate *mcs, int index)
+static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
+                               struct iwl4965_rate *mcs, int index)
 {
        u32 base_rate;
 
-       if (rs_priv->phymode == (u8) MODE_IEEE80211A)
+       if (lq_sta->phymode == (u8) MODE_IEEE80211A)
                base_rate = 0x800D;
        else
                base_rate = 0x820A;
 
-       if (rs_priv->dbg_fixed.rate_n_flags) {
+       if (lq_sta->dbg_fixed.rate_n_flags) {
                if (index < 12)
-                       mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
+                       mcs->rate_n_flags = lq_sta->dbg_fixed.rate_n_flags;
                else
                        mcs->rate_n_flags = base_rate;
                IWL_DEBUG_RATE("Fixed rate ON\n");
@@ -2043,7 +2374,7 @@ static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
 static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
                        const char __user *user_buf, size_t count, loff_t *ppos)
 {
-       struct iwl_rate_scale_priv *rs_priv = file->private_data;
+       struct iwl4965_lq_sta *lq_sta = file->private_data;
        char buf[64];
        int buf_size;
        u32 parsed_rate;
@@ -2054,20 +2385,20 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
                return -EFAULT;
 
        if (sscanf(buf, "%x", &parsed_rate) == 1)
-               rs_priv->dbg_fixed.rate_n_flags = parsed_rate;
+               lq_sta->dbg_fixed.rate_n_flags = parsed_rate;
        else
-               rs_priv->dbg_fixed.rate_n_flags = 0;
+               lq_sta->dbg_fixed.rate_n_flags = 0;
 
-       rs_priv->active_rate = 0x0FFF;
-       rs_priv->active_siso_rate = 0x1FD0;
-       rs_priv->active_mimo_rate = 0x1FD0;
+       lq_sta->active_rate = 0x0FFF;   /* 1 - 54 MBits, includes CCK */
+       lq_sta->active_siso_rate = 0x1FD0;      /* 6 - 60 MBits, no 9, no CCK */
+       lq_sta->active_mimo_rate = 0x1FD0;      /* 6 - 60 MBits, no 9, no CCK */
 
        IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
-               rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags);
+               lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags);
 
-       if (rs_priv->dbg_fixed.rate_n_flags) {
-               rs_fill_link_cmd(rs_priv, &rs_priv->dbg_fixed, &rs_priv->lq);
-               rs_send_lq_cmd(rs_priv->drv, &rs_priv->lq, CMD_ASYNC);
+       if (lq_sta->dbg_fixed.rate_n_flags) {
+               rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq);
+               rs_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
        }
 
        return count;
@@ -2080,38 +2411,38 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
        int desc = 0;
        int i = 0;
 
-       struct iwl_rate_scale_priv *rs_priv = file->private_data;
+       struct iwl4965_lq_sta *lq_sta = file->private_data;
 
-       desc += sprintf(buff+desc, "sta_id %d\n", rs_priv->lq.sta_id);
+       desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
        desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
-                       rs_priv->total_failed, rs_priv->total_success,
-                       rs_priv->active_rate);
+                       lq_sta->total_failed, lq_sta->total_success,
+                       lq_sta->active_rate);
        desc += sprintf(buff+desc, "fixed rate 0x%X\n",
-                       rs_priv->dbg_fixed.rate_n_flags);
+                       lq_sta->dbg_fixed.rate_n_flags);
        desc += sprintf(buff+desc, "general:"
                "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
-               rs_priv->lq.general_params.flags,
-               rs_priv->lq.general_params.mimo_delimiter,
-               rs_priv->lq.general_params.single_stream_ant_msk,
-               rs_priv->lq.general_params.dual_stream_ant_msk);
+               lq_sta->lq.general_params.flags,
+               lq_sta->lq.general_params.mimo_delimiter,
+               lq_sta->lq.general_params.single_stream_ant_msk,
+               lq_sta->lq.general_params.dual_stream_ant_msk);
 
        desc += sprintf(buff+desc, "agg:"
                        "time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
-                       le16_to_cpu(rs_priv->lq.agg_params.agg_time_limit),
-                       rs_priv->lq.agg_params.agg_dis_start_th,
-                       rs_priv->lq.agg_params.agg_frame_cnt_limit);
+                       le16_to_cpu(lq_sta->lq.agg_params.agg_time_limit),
+                       lq_sta->lq.agg_params.agg_dis_start_th,
+                       lq_sta->lq.agg_params.agg_frame_cnt_limit);
 
        desc += sprintf(buff+desc,
                        "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
-                       rs_priv->lq.general_params.start_rate_index[0],
-                       rs_priv->lq.general_params.start_rate_index[1],
-                       rs_priv->lq.general_params.start_rate_index[2],
-                       rs_priv->lq.general_params.start_rate_index[3]);
+                       lq_sta->lq.general_params.start_rate_index[0],
+                       lq_sta->lq.general_params.start_rate_index[1],
+                       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(rs_priv->lq.rs_table[i].rate_n_flags));
+                       i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
 
        return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
 }
@@ -2128,22 +2459,22 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
        int desc = 0;
        int i, j;
 
-       struct iwl_rate_scale_priv *rs_priv = file->private_data;
+       struct iwl4965_lq_sta *lq_sta = file->private_data;
        for (i = 0; i < LQ_SIZE; i++) {
                desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
                                "rate=0x%X\n",
-                               rs_priv->active_tbl == i?"*":"x",
-                               rs_priv->lq_info[i].lq_type,
-                               rs_priv->lq_info[i].is_SGI,
-                               rs_priv->lq_info[i].is_fat,
-                               rs_priv->lq_info[i].is_dup,
-                               rs_priv->lq_info[i].current_rate.rate_n_flags);
+                               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->lq_info[i].current_rate.rate_n_flags);
                for (j = 0; j < IWL_RATE_COUNT; j++) {
                        desc += sprintf(buff+desc,
-                                       "counter=%d success=%d %%=%d\n",
-                                       rs_priv->lq_info[i].win[j].counter,
-                                       rs_priv->lq_info[i].win[j].success_counter,
-                                       rs_priv->lq_info[i].win[j].success_ratio);
+                               "counter=%d success=%d %%=%d\n",
+                               lq_sta->lq_info[i].win[j].counter,
+                               lq_sta->lq_info[i].win[j].success_counter,
+                               lq_sta->lq_info[i].win[j].success_ratio);
                }
        }
        return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
@@ -2157,20 +2488,20 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
 static void rs_add_debugfs(void *priv, void *priv_sta,
                                        struct dentry *dir)
 {
-       struct iwl_rate_scale_priv *rs_priv = priv_sta;
-       rs_priv->rs_sta_dbgfs_scale_table_file =
+       struct iwl4965_lq_sta *lq_sta = priv_sta;
+       lq_sta->rs_sta_dbgfs_scale_table_file =
                debugfs_create_file("rate_scale_table", 0600, dir,
-                               rs_priv, &rs_sta_dbgfs_scale_table_ops);
-       rs_priv->rs_sta_dbgfs_stats_table_file =
+                               lq_sta, &rs_sta_dbgfs_scale_table_ops);
+       lq_sta->rs_sta_dbgfs_stats_table_file =
                debugfs_create_file("rate_stats_table", 0600, dir,
-                       rs_priv, &rs_sta_dbgfs_stats_table_ops);
+                       lq_sta, &rs_sta_dbgfs_stats_table_ops);
 }
 
 static void rs_remove_debugfs(void *priv, void *priv_sta)
 {
-       struct iwl_rate_scale_priv *rs_priv = priv_sta;
-       debugfs_remove(rs_priv->rs_sta_dbgfs_scale_table_file);
-       debugfs_remove(rs_priv->rs_sta_dbgfs_stats_table_file);
+       struct iwl4965_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);
 }
 #endif
 
@@ -2191,13 +2522,13 @@ static struct rate_control_ops rs_ops = {
 #endif
 };
 
-int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
+int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct iwl_priv *priv = hw->priv;
-       struct iwl_rate_scale_priv *rs_priv;
+       struct iwl4965_priv *priv = hw->priv;
+       struct iwl4965_lq_sta *lq_sta;
        struct sta_info *sta;
-       int count = 0, i;
+       int cnt = 0, i;
        u32 samples = 0, success = 0, good = 0;
        unsigned long now = jiffies;
        u32 max_time = 0;
@@ -2213,10 +2544,10 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
                return sprintf(buf, "station %d not found\n", sta_id);
        }
 
-       rs_priv = (void *)sta->rate_ctrl_priv;
+       lq_sta = (void *)sta->rate_ctrl_priv;
 
-       lq_type = rs_priv->lq_info[rs_priv->active_tbl].lq_type;
-       antenna = rs_priv->lq_info[rs_priv->active_tbl].antenna_type;
+       lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
+       antenna = lq_sta->lq_info[lq_sta->active_tbl].antenna_type;
 
        if (is_legacy(lq_type))
                i = IWL_RATE_54M_INDEX;
@@ -2225,35 +2556,35 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
        while (1) {
                u64 mask;
                int j;
-               int active = rs_priv->active_tbl;
+               int active = lq_sta->active_tbl;
 
-               count +=
-                   sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2);
+               cnt +=
+                   sprintf(&buf[cnt], " %2dMbs: ", iwl4965_rates[i].ieee / 2);
 
                mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
                for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
-                       buf[count++] =
-                               (rs_priv->lq_info[active].win[i].data & mask)
+                       buf[cnt++] =
+                               (lq_sta->lq_info[active].win[i].data & mask)
                                ? '1' : '0';
 
-               samples += rs_priv->lq_info[active].win[i].counter;
-               good += rs_priv->lq_info[active].win[i].success_counter;
-               success += rs_priv->lq_info[active].win[i].success_counter *
-                          iwl_rates[i].ieee;
+               samples += lq_sta->lq_info[active].win[i].counter;
+               good += lq_sta->lq_info[active].win[i].success_counter;
+               success += lq_sta->lq_info[active].win[i].success_counter *
+                          iwl4965_rates[i].ieee;
 
-               if (rs_priv->lq_info[active].win[i].stamp) {
+               if (lq_sta->lq_info[active].win[i].stamp) {
                        int delta =
                                   jiffies_to_msecs(now -
-                                  rs_priv->lq_info[active].win[i].stamp);
+                                  lq_sta->lq_info[active].win[i].stamp);
 
                        if (delta > max_time)
                                max_time = delta;
 
-                       count += sprintf(&buf[count], "%5dms\n", delta);
+                       cnt += sprintf(&buf[cnt], "%5dms\n", delta);
                } else
-                       buf[count++] = '\n';
+                       buf[cnt++] = '\n';
 
-               j = iwl_get_prev_ieee_rate(i);
+               j = iwl4965_get_prev_ieee_rate(i);
                if (j == i)
                        break;
                i = j;
@@ -2261,37 +2592,38 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
 
        /* Display the average rate of all samples taken.
         *
-        * NOTE:  We multiple # of samples by 2 since the IEEE measurement
-        * added from iwl_rates is actually 2X the rate */
+        * NOTE:  We multiply # of samples by 2 since the IEEE measurement
+        * added from iwl4965_rates is actually 2X the rate */
        if (samples)
-               count += sprintf(&buf[count],
+               cnt += sprintf(&buf[cnt],
                         "\nAverage rate is %3d.%02dMbs over last %4dms\n"
                         "%3d%% success (%d good packets over %d tries)\n",
                         success / (2 * samples), (success * 5 / samples) % 10,
                         max_time, good * 100 / samples, good, samples);
        else
-               count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n");
-       count += sprintf(&buf[count], "\nrate scale type %d anntena %d "
+               cnt += sprintf(&buf[cnt], "\nAverage rate: 0Mbs\n");
+
+       cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
                         "active_search %d rate index %d\n", lq_type, antenna,
-                        rs_priv->search_better_tbl, sta->last_txrate);
+                        lq_sta->search_better_tbl, sta->last_txrate);
 
        sta_info_put(sta);
-       return count;
+       return cnt;
 }
 
-void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
+void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
 
        priv->lq_mngr.lq_ready = 1;
 }
 
-void iwl_rate_control_register(struct ieee80211_hw *hw)
+void iwl4965_rate_control_register(struct ieee80211_hw *hw)
 {
        ieee80211_rate_control_register(&rs_ops);
 }
 
-void iwl_rate_control_unregister(struct ieee80211_hw *hw)
+void iwl4965_rate_control_unregister(struct ieee80211_hw *hw)
 {
        ieee80211_rate_control_unregister(&rs_ops);
 }
index c6325f72df68fc8545a52f3bcdf20171876c2741..55f707382787ff764db32fd7900cb9d13371201b 100644 (file)
 
 #include "iwl-4965.h"
 
-struct iwl_rate_info {
-       u8 plcp;
-       u8 plcp_siso;
-       u8 plcp_mimo;
-       u8 ieee;
+struct iwl4965_rate_info {
+       u8 plcp;        /* uCode API:  IWL_RATE_6M_PLCP, etc. */
+       u8 plcp_siso;   /* uCode API:  IWL_RATE_SISO_6M_PLCP, etc. */
+       u8 plcp_mimo;   /* uCode API:  IWL_RATE_MIMO_6M_PLCP, etc. */
+       u8 ieee;        /* MAC header:  IWL_RATE_6M_IEEE, etc. */
        u8 prev_ieee;    /* previous rate in IEEE speeds */
        u8 next_ieee;    /* next rate in IEEE speeds */
        u8 prev_rs;      /* previous rate used in rs algo */
@@ -42,6 +42,10 @@ struct iwl_rate_info {
        u8 next_rs_tgg;  /* next rate used in TGG rs algo */
 };
 
+/*
+ * These serve as indexes into
+ * struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
+ */
 enum {
        IWL_RATE_1M_INDEX = 0,
        IWL_RATE_2M_INDEX,
@@ -69,20 +73,21 @@ enum {
 };
 
 /* #define vs. enum to keep from defaulting to 'large integer' */
-#define        IWL_RATE_6M_MASK   (1<<IWL_RATE_6M_INDEX)
-#define        IWL_RATE_9M_MASK   (1<<IWL_RATE_9M_INDEX)
-#define        IWL_RATE_12M_MASK  (1<<IWL_RATE_12M_INDEX)
-#define        IWL_RATE_18M_MASK  (1<<IWL_RATE_18M_INDEX)
-#define        IWL_RATE_24M_MASK  (1<<IWL_RATE_24M_INDEX)
-#define        IWL_RATE_36M_MASK  (1<<IWL_RATE_36M_INDEX)
-#define        IWL_RATE_48M_MASK  (1<<IWL_RATE_48M_INDEX)
-#define        IWL_RATE_54M_MASK  (1<<IWL_RATE_54M_INDEX)
-#define IWL_RATE_60M_MASK  (1<<IWL_RATE_60M_INDEX)
-#define        IWL_RATE_1M_MASK   (1<<IWL_RATE_1M_INDEX)
-#define        IWL_RATE_2M_MASK   (1<<IWL_RATE_2M_INDEX)
-#define        IWL_RATE_5M_MASK   (1<<IWL_RATE_5M_INDEX)
-#define        IWL_RATE_11M_MASK  (1<<IWL_RATE_11M_INDEX)
-
+#define        IWL_RATE_6M_MASK   (1 << IWL_RATE_6M_INDEX)
+#define        IWL_RATE_9M_MASK   (1 << IWL_RATE_9M_INDEX)
+#define        IWL_RATE_12M_MASK  (1 << IWL_RATE_12M_INDEX)
+#define        IWL_RATE_18M_MASK  (1 << IWL_RATE_18M_INDEX)
+#define        IWL_RATE_24M_MASK  (1 << IWL_RATE_24M_INDEX)
+#define        IWL_RATE_36M_MASK  (1 << IWL_RATE_36M_INDEX)
+#define        IWL_RATE_48M_MASK  (1 << IWL_RATE_48M_INDEX)
+#define        IWL_RATE_54M_MASK  (1 << IWL_RATE_54M_INDEX)
+#define IWL_RATE_60M_MASK  (1 << IWL_RATE_60M_INDEX)
+#define        IWL_RATE_1M_MASK   (1 << IWL_RATE_1M_INDEX)
+#define        IWL_RATE_2M_MASK   (1 << IWL_RATE_2M_INDEX)
+#define        IWL_RATE_5M_MASK   (1 << IWL_RATE_5M_INDEX)
+#define        IWL_RATE_11M_MASK  (1 << IWL_RATE_11M_INDEX)
+
+/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */
 enum {
        IWL_RATE_6M_PLCP  = 13,
        IWL_RATE_9M_PLCP  = 15,
@@ -99,7 +104,7 @@ enum {
        IWL_RATE_11M_PLCP = 110,
 };
 
-/* OFDM HT rate plcp */
+/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
 enum {
        IWL_RATE_SISO_6M_PLCP = 0,
        IWL_RATE_SISO_12M_PLCP = 1,
@@ -121,6 +126,7 @@ enum {
        IWL_RATE_MIMO_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
 };
 
+/* MAC header values for bit rates */
 enum {
        IWL_RATE_6M_IEEE  = 12,
        IWL_RATE_9M_IEEE  = 18,
@@ -163,20 +169,15 @@ enum {
        (IWL_OFDM_BASIC_RATES_MASK | \
         IWL_CCK_BASIC_RATES_MASK)
 
-#define IWL_RATES_MASK ((1<<IWL_RATE_COUNT)-1)
+#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
 
 #define IWL_INVALID_VALUE    -1
 
 #define IWL_MIN_RSSI_VAL                 -100
 #define IWL_MAX_RSSI_VAL                    0
 
-#define IWL_LEGACY_SWITCH_ANTENNA      0
-#define IWL_LEGACY_SWITCH_SISO         1
-#define IWL_LEGACY_SWITCH_MIMO         2
-
-#define IWL_RS_GOOD_RATIO              12800
-
-#define IWL_ACTION_LIMIT               3
+/* These values specify how many Tx frame attempts before
+ * searching for a new modulation mode */
 #define IWL_LEGACY_FAILURE_LIMIT       160
 #define IWL_LEGACY_SUCCESS_LIMIT       480
 #define IWL_LEGACY_TABLE_COUNT         160
@@ -185,82 +186,104 @@ enum {
 #define IWL_NONE_LEGACY_SUCCESS_LIMIT  4500
 #define IWL_NONE_LEGACY_TABLE_COUNT    1500
 
-#define IWL_RATE_SCALE_SWITCH          (10880)
+/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
+#define IWL_RS_GOOD_RATIO              12800   /* 100% */
+#define IWL_RATE_SCALE_SWITCH          10880   /*  85% */
+#define IWL_RATE_HIGH_TH               10880   /*  85% */
+#define IWL_RATE_INCREASE_TH            8960   /*  70% */
+#define IWL_RATE_DECREASE_TH           1920    /*  15% */
 
+/* possible actions when in legacy mode */
+#define IWL_LEGACY_SWITCH_ANTENNA      0
+#define IWL_LEGACY_SWITCH_SISO         1
+#define IWL_LEGACY_SWITCH_MIMO         2
+
+/* possible actions when in siso mode */
 #define IWL_SISO_SWITCH_ANTENNA                0
 #define IWL_SISO_SWITCH_MIMO           1
 #define IWL_SISO_SWITCH_GI             2
 
+/* possible actions when in mimo mode */
 #define IWL_MIMO_SWITCH_ANTENNA_A      0
 #define IWL_MIMO_SWITCH_ANTENNA_B      1
 #define IWL_MIMO_SWITCH_GI             2
 
-#define LQ_SIZE                2
+#define IWL_ACTION_LIMIT               3       /* # possible actions */
+
+#define LQ_SIZE                2       /* 2 mode tables:  "Active" and "Search" */
 
-extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
+extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
 
-enum iwl_table_type {
+enum iwl4965_table_type {
        LQ_NONE,
-       LQ_G,
+       LQ_G,           /* legacy types */
        LQ_A,
-       LQ_SISO,
+       LQ_SISO,        /* high-throughput types */
        LQ_MIMO,
        LQ_MAX,
 };
 
-enum iwl_antenna_type {
+#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
+#define is_siso(tbl) (((tbl) == LQ_SISO))
+#define is_mimo(tbl) (((tbl) == LQ_MIMO))
+#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
+#define is_a_band(tbl) (((tbl) == LQ_A))
+#define is_g_and(tbl) (((tbl) == LQ_G))
+
+/* 4965 has 2 antennas/chains for Tx (but 3 for Rx) */
+enum iwl4965_antenna_type {
        ANT_NONE,
        ANT_MAIN,
        ANT_AUX,
        ANT_BOTH,
 };
 
-static inline u8 iwl_get_prev_ieee_rate(u8 rate_index)
+static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
 {
-       u8 rate = iwl_rates[rate_index].prev_ieee;
+       u8 rate = iwl4965_rates[rate_index].prev_ieee;
 
        if (rate == IWL_RATE_INVALID)
                rate = rate_index;
        return rate;
 }
 
-extern int iwl_rate_index_from_plcp(int plcp);
+extern int iwl4965_rate_index_from_plcp(int plcp);
 
 /**
- * iwl_fill_rs_info - Fill an output text buffer with the rate representation
+ * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
  *
  * NOTE:  This is provided as a quick mechanism for a user to visualize
- * the performance of the rate control alogirthm and is not meant to be
+ * the performance of the rate control algorithm and is not meant to be
  * parsed software.
  */
-extern int iwl_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
+extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
 
 /**
- * iwl_rate_scale_init - Initialize the rate scale table based on assoc info
+ * iwl4965_rate_scale_init - Initialize the rate scale table based on assoc info
  *
- * The specific througput table used is based on the type of network
+ * The specific throughput table used is based on the type of network
  * the associated with, including A, B, G, and G w/ TGG protection
  */
-extern void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+extern void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
 
 /**
- * iwl_rate_control_register - Register the rate control algorithm callbacks
+ * iwl4965_rate_control_register - Register the rate control algorithm callbacks
  *
  * Since the rate control algorithm is hardware specific, there is no need
  * or reason to place it as a stand alone module.  The driver can call
- * iwl_rate_control_register in order to register the rate control callbacks
+ * iwl4965_rate_control_register in order to register the rate control callbacks
  * with the mac80211 subsystem.  This should be performed prior to calling
  * ieee80211_register_hw
  *
  */
-extern void iwl_rate_control_register(struct ieee80211_hw *hw);
+extern void iwl4965_rate_control_register(struct ieee80211_hw *hw);
 
 /**
- * iwl_rate_control_unregister - Unregister the rate control callbacks
+ * iwl4965_rate_control_unregister - Unregister the rate control callbacks
  *
  * This should be called after calling ieee80211_unregister_hw, but before
  * the driver is unloaded.
  */
-extern void iwl_rate_control_unregister(struct ieee80211_hw *hw);
+extern void iwl4965_rate_control_unregister(struct ieee80211_hw *hw);
 
 #endif
index 891f90d2f019d9860cf2d5e554b5ec6052b762a6..04db34ba814be632871270d17d890bf6e3cacaf6 100644 (file)
 #include <linux/wireless.h>
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
+#include <asm/unaligned.h>
 
-#define IWL 4965
-
-#include "iwlwifi.h"
 #include "iwl-4965.h"
 #include "iwl-helpers.h"
 
+static void iwl4965_hw_card_show_info(struct iwl4965_priv *priv);
+
 #define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np)    \
        [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,      \
                                    IWL_RATE_SISO_##s##M_PLCP, \
@@ -63,7 +63,7 @@
  * maps to IWL_RATE_INVALID
  *
  */
-const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
+const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = {
        IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2),    /*  1mbps */
        IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5),          /*  2mbps */
        IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
@@ -85,16 +85,16 @@ static int is_fat_channel(__le32 rxon_flags)
                (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
 }
 
-static u8 is_single_stream(struct iwl_priv *priv)
+static u8 is_single_stream(struct iwl4965_priv *priv)
 {
-#ifdef CONFIG_IWLWIFI_HT
-       if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht ||
-           (priv->active_rate_ht[1] == 0) ||
+#ifdef CONFIG_IWL4965_HT
+       if (!priv->current_ht_config.is_ht ||
+           (priv->current_ht_config.supp_mcs_set[1] == 0) ||
            (priv->ps_mode == IWL_MIMO_PS_STATIC))
                return 1;
 #else
        return 1;
-#endif /*CONFIG_IWLWIFI_HT */
+#endif /*CONFIG_IWL4965_HT */
        return 0;
 }
 
@@ -104,7 +104,7 @@ static u8 is_single_stream(struct iwl_priv *priv)
  * MIMO (dual stream) requires at least 2, but works better with 3.
  * This does not determine *which* chains to use, just how many.
  */
-static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv,
+static int iwl4965_get_rx_chain_counter(struct iwl4965_priv *priv,
                                        u8 *idle_state, u8 *rx_state)
 {
        u8 is_single = is_single_stream(priv);
@@ -133,32 +133,32 @@ static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv,
        return 0;
 }
 
-int iwl_hw_rxq_stop(struct iwl_priv *priv)
+int iwl4965_hw_rxq_stop(struct iwl4965_priv *priv)
 {
        int rc;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       /* stop HW */
-       iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-       rc = iwl_poll_restricted_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
+       /* stop Rx DMA */
+       iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       rc = iwl4965_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
                                     (1 << 24), 1000);
        if (rc < 0)
                IWL_ERROR("Can't stop Rx DMA.\n");
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
+u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *addr)
 {
        int i;
        int start = 0;
@@ -190,104 +190,114 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr)
        return ret;
 }
 
-static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max)
+static int iwl4965_nic_set_pwr_src(struct iwl4965_priv *priv, int pwr_max)
 {
-       int rc = 0;
+       int ret;
        unsigned long flags;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
-       if (rc) {
+       ret = iwl4965_grab_nic_access(priv);
+       if (ret) {
                spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
+               return ret;
        }
 
        if (!pwr_max) {
                u32 val;
 
-               rc = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
+               ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
                                           &val);
 
                if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
-                       iwl_set_bits_mask_restricted_reg(
-                               priv, APMG_PS_CTRL_REG,
+                       iwl4965_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                ~APMG_PS_CTRL_MSK_PWR_SRC);
        } else
-               iwl_set_bits_mask_restricted_reg(
-                       priv, APMG_PS_CTRL_REG,
+               iwl4965_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                        APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                        ~APMG_PS_CTRL_MSK_PWR_SRC);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return rc;
+       return ret;
 }
 
-static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+static int iwl4965_rx_init(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq)
 {
        int rc;
        unsigned long flags;
+       unsigned int rb_size;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       /* stop HW */
-       iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+       if (iwl4965_param_amsdu_size_8K)
+               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
+       else
+               rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
+
+       /* Stop Rx DMA */
+       iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+
+       /* Reset driver's Rx queue write index */
+       iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
 
-       iwl_write_restricted(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
-       iwl_write_restricted(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
+       /* Tell device where to find RBD circular buffer in DRAM */
+       iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
                             rxq->dma_addr >> 8);
 
-       iwl_write_restricted(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
+       /* Tell device where in DRAM to update its Rx status */
+       iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
                             (priv->hw_setting.shared_phys +
-                             offsetof(struct iwl_shared, val0)) >> 4);
+                             offsetof(struct iwl4965_shared, val0)) >> 4);
 
-       iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
+       /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */
+       iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
                             FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
                             FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
-                            IWL_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K |
+                            rb_size |
                             /*0x10 << 4 | */
                             (RX_QUEUE_SIZE_LOG <<
                              FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT));
 
        /*
-        * iwl_write32(priv,CSR_INT_COAL_REG,0);
+        * iwl4965_write32(priv,CSR_INT_COAL_REG,0);
         */
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-static int iwl4965_kw_init(struct iwl_priv *priv)
+/* Tell 4965 where to find the "keep warm" buffer */
+static int iwl4965_kw_init(struct iwl4965_priv *priv)
 {
        unsigned long flags;
        int rc;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc)
                goto out;
 
-       iwl_write_restricted(priv, IWL_FH_KW_MEM_ADDR_REG,
+       iwl4965_write_direct32(priv, IWL_FH_KW_MEM_ADDR_REG,
                             priv->kw.dma_addr >> 4);
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 out:
        spin_unlock_irqrestore(&priv->lock, flags);
        return rc;
 }
 
-static int iwl4965_kw_alloc(struct iwl_priv *priv)
+static int iwl4965_kw_alloc(struct iwl4965_priv *priv)
 {
        struct pci_dev *dev = priv->pci_dev;
-       struct iwl_kw *kw = &priv->kw;
+       struct iwl4965_kw *kw = &priv->kw;
 
        kw->size = IWL4965_KW_SIZE;     /* TBW need set somewhere else */
        kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
@@ -300,14 +310,19 @@ static int iwl4965_kw_alloc(struct iwl_priv *priv)
 #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \
                            ? # x " " : "")
 
-int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode, u16 channel,
-                             const struct iwl_eeprom_channel *eeprom_ch,
+/**
+ * iwl4965_set_fat_chan_info - Copy fat channel info into driver's priv.
+ *
+ * Does not set up a command, or touch hardware.
+ */
+int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel,
+                             const struct iwl4965_eeprom_channel *eeprom_ch,
                              u8 fat_extension_channel)
 {
-       struct iwl_channel_info *ch_info;
+       struct iwl4965_channel_info *ch_info;
 
-       ch_info = (struct iwl_channel_info *)
-                       iwl_get_channel_info(priv, phymode, channel);
+       ch_info = (struct iwl4965_channel_info *)
+                       iwl4965_get_channel_info(priv, phymode, channel);
 
        if (!is_channel_valid(ch_info))
                return -1;
@@ -340,10 +355,13 @@ int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode, u16 channel,
        return 0;
 }
 
-static void iwl4965_kw_free(struct iwl_priv *priv)
+/**
+ * iwl4965_kw_free - Free the "keep warm" buffer
+ */
+static void iwl4965_kw_free(struct iwl4965_priv *priv)
 {
        struct pci_dev *dev = priv->pci_dev;
-       struct iwl_kw *kw = &priv->kw;
+       struct iwl4965_kw *kw = &priv->kw;
 
        if (kw->v_addr) {
                pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
@@ -358,7 +376,7 @@ static void iwl4965_kw_free(struct iwl_priv *priv)
  * @param priv
  * @return error code
  */
-static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
+static int iwl4965_txq_ctx_reset(struct iwl4965_priv *priv)
 {
        int rc = 0;
        int txq_id, slots_num;
@@ -366,9 +384,10 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
 
        iwl4965_kw_free(priv);
 
-       iwl_hw_txq_ctx_free(priv);
+       /* Free all tx/cmd queues and keep-warm buffer */
+       iwl4965_hw_txq_ctx_free(priv);
 
-       /* Tx CMD queue */
+       /* Alloc keep-warm buffer */
        rc = iwl4965_kw_alloc(priv);
        if (rc) {
                IWL_ERROR("Keep Warm allocation failed");
@@ -377,28 +396,31 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (unlikely(rc)) {
                IWL_ERROR("TX reset failed");
                spin_unlock_irqrestore(&priv->lock, flags);
                goto error_reset;
        }
 
-       iwl_write_restricted_reg(priv, SCD_TXFACT, 0);
-       iwl_release_restricted_access(priv);
+       /* Turn off all Tx DMA channels */
+       iwl4965_write_prph(priv, KDR_SCD_TXFACT, 0);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       /* Tell 4965 where to find the keep-warm buffer */
        rc = iwl4965_kw_init(priv);
        if (rc) {
                IWL_ERROR("kw_init failed\n");
                goto error_reset;
        }
 
-       /* Tx queue(s) */
+       /* Alloc and init all (default 16) Tx queues,
+        * including the command queue (#4) */
        for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) {
                slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
                                        TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
-               rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+               rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
                                       txq_id);
                if (rc) {
                        IWL_ERROR("Tx %d queue init failed\n", txq_id);
@@ -409,32 +431,32 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
        return rc;
 
  error:
-       iwl_hw_txq_ctx_free(priv);
+       iwl4965_hw_txq_ctx_free(priv);
  error_reset:
        iwl4965_kw_free(priv);
  error_kw:
        return rc;
 }
 
-int iwl_hw_nic_init(struct iwl_priv *priv)
+int iwl4965_hw_nic_init(struct iwl4965_priv *priv)
 {
        int rc;
        unsigned long flags;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl4965_rx_queue *rxq = &priv->rxq;
        u8 rev_id;
        u32 val;
        u8 val_link;
 
-       iwl_power_init_handle(priv);
+       iwl4965_power_init_handle(priv);
 
        /* nic_init */
        spin_lock_irqsave(&priv->lock, flags);
 
-       iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+       iwl4965_set_bit(priv, CSR_GIO_CHICKEN_BITS,
                    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
 
-       iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-       rc = iwl_poll_bit(priv, CSR_GP_CNTRL,
+       iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       rc = iwl4965_poll_bit(priv, CSR_GP_CNTRL,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
        if (rc < 0) {
@@ -443,26 +465,26 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
                return rc;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       iwl_read_restricted_reg(priv, APMG_CLK_CTRL_REG);
+       iwl4965_read_prph(priv, APMG_CLK_CTRL_REG);
 
-       iwl_write_restricted_reg(priv, APMG_CLK_CTRL_REG,
+       iwl4965_write_prph(priv, APMG_CLK_CTRL_REG,
                                 APMG_CLK_VAL_DMA_CLK_RQT |
                                 APMG_CLK_VAL_BSM_CLK_RQT);
-       iwl_read_restricted_reg(priv, APMG_CLK_CTRL_REG);
+       iwl4965_read_prph(priv, APMG_CLK_CTRL_REG);
 
        udelay(20);
 
-       iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG,
+       iwl4965_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                                    APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       iwl_release_restricted_access(priv);
-       iwl_write32(priv, CSR_INT_COALESCING, 512 / 32);
+       iwl4965_release_nic_access(priv);
+       iwl4965_write32(priv, CSR_INT_COALESCING, 512 / 32);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Determine HW type */
@@ -484,11 +506,6 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* Read the EEPROM */
-       rc = iwl_eeprom_init(priv);
-       if (rc)
-               return rc;
-
        if (priv->eeprom.calib_version < EEPROM_TX_POWER_VERSION_NEW) {
                IWL_ERROR("Older EEPROM detected!  Aborting.\n");
                return -EINVAL;
@@ -503,51 +520,53 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        /* set CSR_HW_CONFIG_REG for uCode use */
 
-       iwl_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R |
+       iwl4965_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R |
                    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
                    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc < 0) {
                spin_unlock_irqrestore(&priv->lock, flags);
                IWL_DEBUG_INFO("Failed to init the card\n");
                return rc;
        }
 
-       iwl_read_restricted_reg(priv, APMG_PS_CTRL_REG);
-       iwl_set_bits_restricted_reg(priv, APMG_PS_CTRL_REG,
+       iwl4965_read_prph(priv, APMG_PS_CTRL_REG);
+       iwl4965_set_bits_prph(priv, APMG_PS_CTRL_REG,
                                    APMG_PS_CTRL_VAL_RESET_REQ);
        udelay(5);
-       iwl_clear_bits_restricted_reg(priv, APMG_PS_CTRL_REG,
+       iwl4965_clear_bits_prph(priv, APMG_PS_CTRL_REG,
                                      APMG_PS_CTRL_VAL_RESET_REQ);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_hw_card_show_info(priv);
+       iwl4965_hw_card_show_info(priv);
 
        /* end nic_init */
 
        /* Allocate the RX queue, or reset if it is already allocated */
        if (!rxq->bd) {
-               rc = iwl_rx_queue_alloc(priv);
+               rc = iwl4965_rx_queue_alloc(priv);
                if (rc) {
                        IWL_ERROR("Unable to initialize Rx queue\n");
                        return -ENOMEM;
                }
        } else
-               iwl_rx_queue_reset(priv, rxq);
+               iwl4965_rx_queue_reset(priv, rxq);
 
-       iwl_rx_replenish(priv);
+       iwl4965_rx_replenish(priv);
 
        iwl4965_rx_init(priv, rxq);
 
        spin_lock_irqsave(&priv->lock, flags);
 
        rxq->need_update = 1;
-       iwl_rx_queue_update_write_ptr(priv, rxq);
+       iwl4965_rx_queue_update_write_ptr(priv, rxq);
 
        spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* Allocate and init all Tx and Command queues */
        rc = iwl4965_txq_ctx_reset(priv);
        if (rc)
                return rc;
@@ -563,7 +582,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
        return 0;
 }
 
-int iwl_hw_nic_stop_master(struct iwl_priv *priv)
+int iwl4965_hw_nic_stop_master(struct iwl4965_priv *priv)
 {
        int rc = 0;
        u32 reg_val;
@@ -572,16 +591,16 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv)
        spin_lock_irqsave(&priv->lock, flags);
 
        /* set stop master bit */
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+       iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
-       reg_val = iwl_read32(priv, CSR_GP_CNTRL);
+       reg_val = iwl4965_read32(priv, CSR_GP_CNTRL);
 
        if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
            (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
                IWL_DEBUG_INFO("Card in power save, master is already "
                               "stopped\n");
        else {
-               rc = iwl_poll_bit(priv, CSR_RESET,
+               rc = iwl4965_poll_bit(priv, CSR_RESET,
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED,
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
                if (rc < 0) {
@@ -596,65 +615,69 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv)
        return rc;
 }
 
-void iwl_hw_txq_ctx_stop(struct iwl_priv *priv)
+/**
+ * iwl4965_hw_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ */
+void iwl4965_hw_txq_ctx_stop(struct iwl4965_priv *priv)
 {
 
        int txq_id;
        unsigned long flags;
 
-       /* reset TFD queues */
+       /* Stop each Tx DMA channel, and wait for it to be idle */
        for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) {
                spin_lock_irqsave(&priv->lock, flags);
-               if (iwl_grab_restricted_access(priv)) {
+               if (iwl4965_grab_nic_access(priv)) {
                        spin_unlock_irqrestore(&priv->lock, flags);
                        continue;
                }
 
-               iwl_write_restricted(priv,
+               iwl4965_write_direct32(priv,
                                     IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
                                     0x0);
-               iwl_poll_restricted_bit(priv, IWL_FH_TSSR_TX_STATUS_REG,
+               iwl4965_poll_direct_bit(priv, IWL_FH_TSSR_TX_STATUS_REG,
                                        IWL_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE
                                        (txq_id), 200);
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
-       iwl_hw_txq_ctx_free(priv);
+       /* Deallocate memory for all Tx queues */
+       iwl4965_hw_txq_ctx_free(priv);
 }
 
-int iwl_hw_nic_reset(struct iwl_priv *priv)
+int iwl4965_hw_nic_reset(struct iwl4965_priv *priv)
 {
        int rc = 0;
        unsigned long flags;
 
-       iwl_hw_nic_stop_master(priv);
+       iwl4965_hw_nic_stop_master(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
        udelay(10);
 
-       iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
-       rc = iwl_poll_bit(priv, CSR_RESET,
+       iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+       rc = iwl4965_poll_bit(priv, CSR_RESET,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25);
 
        udelay(10);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (!rc) {
-               iwl_write_restricted_reg(priv, APMG_CLK_EN_REG,
+               iwl4965_write_prph(priv, APMG_CLK_EN_REG,
                                         APMG_CLK_VAL_DMA_CLK_RQT |
                                         APMG_CLK_VAL_BSM_CLK_RQT);
 
                udelay(10);
 
-               iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG,
+               iwl4965_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                                APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
        }
 
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -684,7 +707,7 @@ int iwl_hw_nic_reset(struct iwl_priv *priv)
  */
 static void iwl4965_bg_statistics_periodic(unsigned long data)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)data;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)data;
 
        queue_work(priv->workqueue, &priv->statistics_work);
 }
@@ -692,27 +715,27 @@ static void iwl4965_bg_statistics_periodic(unsigned long data)
 /**
  * iwl4965_bg_statistics_work - Send the statistics request to the hardware.
  *
- * This is queued by iwl_bg_statistics_periodic.
+ * This is queued by iwl4965_bg_statistics_periodic.
  */
 static void iwl4965_bg_statistics_work(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv,
                                             statistics_work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_send_statistics_request(priv);
+       iwl4965_send_statistics_request(priv);
        mutex_unlock(&priv->mutex);
 }
 
 #define CT_LIMIT_CONST         259
 #define TM_CT_KILL_THRESHOLD   110
 
-void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
+void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv)
 {
-       struct iwl_ct_kill_config cmd;
+       struct iwl4965_ct_kill_config cmd;
        u32 R1, R2, R3;
        u32 temp_th;
        u32 crit_temperature;
@@ -720,7 +743,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
        int rc = 0;
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -738,7 +761,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
 
        crit_temperature = ((temp_th * (R3-R1))/CT_LIMIT_CONST) + R2;
        cmd.critical_temperature_R =  cpu_to_le32(crit_temperature);
-       rc = iwl_send_cmd_pdu(priv,
+       rc = iwl4965_send_cmd_pdu(priv,
                              REPLY_CT_KILL_CONFIG_CMD, sizeof(cmd), &cmd);
        if (rc)
                IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
@@ -746,7 +769,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
                IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded\n");
 }
 
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
 
 /* "false alarms" are signals that our DSP tries to lock onto,
  *   but then determines that they are either noise, or transmissions
@@ -756,7 +779,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
  *   enough to receive all of our own network traffic, but not so
  *   high that our DSP gets too busy trying to lock onto non-network
  *   activity/noise. */
-static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
+static int iwl4965_sens_energy_cck(struct iwl4965_priv *priv,
                                   u32 norm_fa,
                                   u32 rx_enable_time,
                                   struct statistics_general_data *rx_info)
@@ -782,7 +805,7 @@ static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
        u32 false_alarms = norm_fa * 200 * 1024;
        u32 max_false_alarms = MAX_FA_CCK * rx_enable_time;
        u32 min_false_alarms = MIN_FA_CCK * rx_enable_time;
-       struct iwl_sensitivity_data *data = NULL;
+       struct iwl4965_sensitivity_data *data = NULL;
 
        data = &(priv->sensitivity_data);
 
@@ -792,11 +815,11 @@ static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
         * This is background noise, which may include transmissions from other
         *    networks, measured during silence before our network's beacon */
        silence_rssi_a = (u8)((rx_info->beacon_silence_rssi_a &
-                           ALL_BAND_FILTER)>>8);
+                           ALL_BAND_FILTER) >> 8);
        silence_rssi_b = (u8)((rx_info->beacon_silence_rssi_b &
-                           ALL_BAND_FILTER)>>8);
+                           ALL_BAND_FILTER) >> 8);
        silence_rssi_c = (u8)((rx_info->beacon_silence_rssi_c &
-                           ALL_BAND_FILTER)>>8);
+                           ALL_BAND_FILTER) >> 8);
 
        val = max(silence_rssi_b, silence_rssi_c);
        max_silence_rssi = max(silence_rssi_a, (u8) val);
@@ -947,7 +970,7 @@ static int iwl4965_sens_energy_cck(struct iwl_priv *priv,
 }
 
 
-static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
+static int iwl4965_sens_auto_corr_ofdm(struct iwl4965_priv *priv,
                                       u32 norm_fa,
                                       u32 rx_enable_time)
 {
@@ -955,7 +978,7 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
        u32 false_alarms = norm_fa * 200 * 1024;
        u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time;
        u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time;
-       struct iwl_sensitivity_data *data = NULL;
+       struct iwl4965_sensitivity_data *data = NULL;
 
        data = &(priv->sensitivity_data);
 
@@ -1012,22 +1035,22 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
        return 0;
 }
 
-static int iwl_sensitivity_callback(struct iwl_priv *priv,
-                                   struct iwl_cmd *cmd, struct sk_buff *skb)
+static int iwl4965_sensitivity_callback(struct iwl4965_priv *priv,
+                                   struct iwl4965_cmd *cmd, struct sk_buff *skb)
 {
        /* We didn't cache the SKB; let the caller free it */
        return 1;
 }
 
 /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
-static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
+static int iwl4965_sensitivity_write(struct iwl4965_priv *priv, u8 flags)
 {
        int rc = 0;
-       struct iwl_sensitivity_cmd cmd ;
-       struct iwl_sensitivity_data *data = NULL;
-       struct iwl_host_cmd cmd_out = {
+       struct iwl4965_sensitivity_cmd cmd ;
+       struct iwl4965_sensitivity_data *data = NULL;
+       struct iwl4965_host_cmd cmd_out = {
                .id = SENSITIVITY_CMD,
-               .len = sizeof(struct iwl_sensitivity_cmd),
+               .len = sizeof(struct iwl4965_sensitivity_cmd),
                .meta.flags = flags,
                .data = &cmd,
        };
@@ -1071,10 +1094,11 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
                        data->auto_corr_cck, data->auto_corr_cck_mrc,
                        data->nrg_th_cck);
 
+       /* Update uCode's "work" table, and copy it to DSP */
        cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
 
        if (flags & CMD_ASYNC)
-               cmd_out.meta.u.callback = iwl_sensitivity_callback;
+               cmd_out.meta.u.callback = iwl4965_sensitivity_callback;
 
        /* Don't send command to uCode if nothing has changed */
        if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]),
@@ -1087,7 +1111,7 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
        memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
               sizeof(u16)*HD_TABLE_SIZE);
 
-       rc = iwl_send_cmd(priv, &cmd_out);
+       rc = iwl4965_send_cmd(priv, &cmd_out);
        if (!rc) {
                IWL_DEBUG_CALIB("SENSITIVITY_CMD succeeded\n");
                return rc;
@@ -1096,11 +1120,11 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
        return 0;
 }
 
-void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
+void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, u8 force)
 {
        int rc = 0;
        int i;
-       struct iwl_sensitivity_data *data = NULL;
+       struct iwl4965_sensitivity_data *data = NULL;
 
        IWL_DEBUG_CALIB("Start iwl4965_init_sensitivity\n");
 
@@ -1110,7 +1134,7 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
 
        /* Clear driver's sensitivity algo data */
        data = &(priv->sensitivity_data);
-       memset(data, 0, sizeof(struct iwl_sensitivity_data));
+       memset(data, 0, sizeof(struct iwl4965_sensitivity_data));
 
        data->num_in_cck_no_fa = 0;
        data->nrg_curr_state = IWL_FA_TOO_MANY;
@@ -1154,21 +1178,21 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
 /* Reset differential Rx gains in NIC to prepare for chain noise calibration.
  * Called after every association, but this runs only once!
  *  ... once chain noise is calibrated the first time, it's good forever.  */
-void iwl4965_chain_noise_reset(struct iwl_priv *priv)
+void iwl4965_chain_noise_reset(struct iwl4965_priv *priv)
 {
-       struct iwl_chain_noise_data *data = NULL;
+       struct iwl4965_chain_noise_data *data = NULL;
        int rc = 0;
 
        data = &(priv->chain_noise_data);
-       if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
-               struct iwl_calibration_cmd cmd;
+       if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl4965_is_associated(priv)) {
+               struct iwl4965_calibration_cmd cmd;
 
                memset(&cmd, 0, sizeof(cmd));
                cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD;
                cmd.diff_gain_a = 0;
                cmd.diff_gain_b = 0;
                cmd.diff_gain_c = 0;
-               rc = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+               rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
                                 sizeof(cmd), &cmd);
                msleep(4);
                data->state = IWL_CHAIN_NOISE_ACCUMULATE;
@@ -1183,10 +1207,10 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv)
  * 1)  Which antennas are connected.
  * 2)  Differential rx gain settings to balance the 3 receivers.
  */
-static void iwl4965_noise_calibration(struct iwl_priv *priv,
-                                     struct iwl_notif_statistics *stat_resp)
+static void iwl4965_noise_calibration(struct iwl4965_priv *priv,
+                                     struct iwl4965_notif_statistics *stat_resp)
 {
-       struct iwl_chain_noise_data *data = NULL;
+       struct iwl4965_chain_noise_data *data = NULL;
        int rc = 0;
 
        u32 chain_noise_a;
@@ -1385,7 +1409,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
 
                /* Differential gain gets sent to uCode only once */
                if (!data->radio_write) {
-                       struct iwl_calibration_cmd cmd;
+                       struct iwl4965_calibration_cmd cmd;
                        data->radio_write = 1;
 
                        memset(&cmd, 0, sizeof(cmd));
@@ -1393,7 +1417,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
                        cmd.diff_gain_a = data->delta_gain_code[0];
                        cmd.diff_gain_b = data->delta_gain_code[1];
                        cmd.diff_gain_c = data->delta_gain_code[2];
-                       rc = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
+                       rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
                                              sizeof(cmd), &cmd);
                        if (rc)
                                IWL_DEBUG_CALIB("fail sending cmd "
@@ -1416,8 +1440,8 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
        return;
 }
 
-static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
-                                           struct iwl_notif_statistics *resp)
+static void iwl4965_sensitivity_calibration(struct iwl4965_priv *priv,
+                                           struct iwl4965_notif_statistics *resp)
 {
        int rc = 0;
        u32 rx_enable_time;
@@ -1427,7 +1451,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
        u32 bad_plcp_ofdm;
        u32 norm_fa_ofdm;
        u32 norm_fa_cck;
-       struct iwl_sensitivity_data *data = NULL;
+       struct iwl4965_sensitivity_data *data = NULL;
        struct statistics_rx_non_phy *rx_info = &(resp->rx.general);
        struct statistics_rx *statistics = &(resp->rx);
        unsigned long flags;
@@ -1435,7 +1459,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
 
        data = &(priv->sensitivity_data);
 
-       if (!iwl_is_associated(priv)) {
+       if (!iwl4965_is_associated(priv)) {
                IWL_DEBUG_CALIB("<< - not associated\n");
                return;
        }
@@ -1523,7 +1547,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
 
 static void iwl4965_bg_sensitivity_work(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv,
                        sensitivity_work);
 
        mutex_lock(&priv->mutex);
@@ -1549,11 +1573,11 @@ static void iwl4965_bg_sensitivity_work(struct work_struct *work)
        mutex_unlock(&priv->mutex);
        return;
 }
-#endif /*CONFIG_IWLWIFI_SENSITIVITY*/
+#endif /*CONFIG_IWL4965_SENSITIVITY*/
 
 static void iwl4965_bg_txpower_work(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv,
                        txpower_work);
 
        /* If a scan happened to start before we got here
@@ -1569,7 +1593,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
        /* Regardless of if we are assocaited, we must reconfigure the
         * TX power since frames can be sent on non-radar channels while
         * not associated */
-       iwl_hw_reg_send_txpower(priv);
+       iwl4965_hw_reg_send_txpower(priv);
 
        /* Update last_temperature to keep is_calib_needed from running
         * when it isn't needed... */
@@ -1581,24 +1605,31 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
 /*
  * Acquire priv->lock before calling this function !
  */
-static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index)
+static void iwl4965_set_wr_ptrs(struct iwl4965_priv *priv, int txq_id, u32 index)
 {
-       iwl_write_restricted(priv, HBUS_TARG_WRPTR,
+       iwl4965_write_direct32(priv, HBUS_TARG_WRPTR,
                             (index & 0xff) | (txq_id << 8));
-       iwl_write_restricted_reg(priv, SCD_QUEUE_RDPTR(txq_id), index);
+       iwl4965_write_prph(priv, KDR_SCD_QUEUE_RDPTR(txq_id), index);
 }
 
-/*
- * Acquire priv->lock before calling this function !
+/**
+ * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue
+ * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed
+ * @scd_retry: (1) Indicates queue will be used in aggregation mode
+ *
+ * NOTE:  Acquire priv->lock before calling this function !
  */
-static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
-                                       struct iwl_tx_queue *txq,
+static void iwl4965_tx_queue_set_status(struct iwl4965_priv *priv,
+                                       struct iwl4965_tx_queue *txq,
                                        int tx_fifo_id, int scd_retry)
 {
        int txq_id = txq->q.id;
+
+       /* Find out whether to activate Tx queue */
        int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0;
 
-       iwl_write_restricted_reg(priv, SCD_QUEUE_STATUS_BITS(txq_id),
+       /* Set up and activate */
+       iwl4965_write_prph(priv, KDR_SCD_QUEUE_STATUS_BITS(txq_id),
                                 (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
                                 (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) |
                                 (scd_retry << SCD_QUEUE_STTS_REG_POS_WSL) |
@@ -1608,7 +1639,7 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
        txq->sched_retry = scd_retry;
 
        IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n",
-                      active ? "Activete" : "Deactivate",
+                      active ? "Activate" : "Deactivate",
                       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
 }
 
@@ -1622,17 +1653,17 @@ static const u16 default_queue_to_tx_fifo[] = {
        IWL_TX_FIFO_HCCA_2
 };
 
-static inline void iwl4965_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
+static inline void iwl4965_txq_ctx_activate(struct iwl4965_priv *priv, int txq_id)
 {
        set_bit(txq_id, &priv->txq_ctx_active_msk);
 }
 
-static inline void iwl4965_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id)
+static inline void iwl4965_txq_ctx_deactivate(struct iwl4965_priv *priv, int txq_id)
 {
        clear_bit(txq_id, &priv->txq_ctx_active_msk);
 }
 
-int iwl4965_alive_notify(struct iwl_priv *priv)
+int iwl4965_alive_notify(struct iwl4965_priv *priv)
 {
        u32 a;
        int i = 0;
@@ -1641,45 +1672,55 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
        memset(&(priv->sensitivity_data), 0,
-              sizeof(struct iwl_sensitivity_data));
+              sizeof(struct iwl4965_sensitivity_data));
        memset(&(priv->chain_noise_data), 0,
-              sizeof(struct iwl_chain_noise_data));
+              sizeof(struct iwl4965_chain_noise_data));
        for (i = 0; i < NUM_RX_CHAINS; i++)
                priv->chain_noise_data.delta_gain_code[i] =
                                CHAIN_NOISE_DELTA_GAIN_INIT_VAL;
-#endif /* CONFIG_IWLWIFI_SENSITIVITY*/
-       rc = iwl_grab_restricted_access(priv);
+#endif /* CONFIG_IWL4965_SENSITIVITY*/
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       priv->scd_base_addr = iwl_read_restricted_reg(priv, SCD_SRAM_BASE_ADDR);
+       /* Clear 4965's internal Tx Scheduler data base */
+       priv->scd_base_addr = iwl4965_read_prph(priv, KDR_SCD_SRAM_BASE_ADDR);
        a = priv->scd_base_addr + SCD_CONTEXT_DATA_OFFSET;
        for (; a < priv->scd_base_addr + SCD_TX_STTS_BITMAP_OFFSET; a += 4)
-               iwl_write_restricted_mem(priv, a, 0);
+               iwl4965_write_targ_mem(priv, a, 0);
        for (; a < priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET; a += 4)
-               iwl_write_restricted_mem(priv, a, 0);
+               iwl4965_write_targ_mem(priv, a, 0);
        for (; a < sizeof(u16) * priv->hw_setting.max_txq_num; a += 4)
-               iwl_write_restricted_mem(priv, a, 0);
+               iwl4965_write_targ_mem(priv, a, 0);
 
-       iwl_write_restricted_reg(priv, SCD_DRAM_BASE_ADDR,
+       /* Tel 4965 where to find Tx byte count tables */
+       iwl4965_write_prph(priv, KDR_SCD_DRAM_BASE_ADDR,
                (priv->hw_setting.shared_phys +
-                offsetof(struct iwl_shared, queues_byte_cnt_tbls)) >> 10);
-       iwl_write_restricted_reg(priv, SCD_QUEUECHAIN_SEL, 0);
+                offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10);
 
-       /* initiate the queues */
+       /* Disable chain mode for all queues */
+       iwl4965_write_prph(priv, KDR_SCD_QUEUECHAIN_SEL, 0);
+
+       /* Initialize each Tx queue (including the command queue) */
        for (i = 0; i < priv->hw_setting.max_txq_num; i++) {
-               iwl_write_restricted_reg(priv, SCD_QUEUE_RDPTR(i), 0);
-               iwl_write_restricted(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
-               iwl_write_restricted_mem(priv, priv->scd_base_addr +
+
+               /* TFD circular buffer read/write indexes */
+               iwl4965_write_prph(priv, KDR_SCD_QUEUE_RDPTR(i), 0);
+               iwl4965_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
+
+               /* Max Tx Window size for Scheduler-ACK mode */
+               iwl4965_write_targ_mem(priv, priv->scd_base_addr +
                                        SCD_CONTEXT_QUEUE_OFFSET(i),
                                        (SCD_WIN_SIZE <<
                                        SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
                                        SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
-               iwl_write_restricted_mem(priv, priv->scd_base_addr +
+
+               /* Frame limit */
+               iwl4965_write_targ_mem(priv, priv->scd_base_addr +
                                        SCD_CONTEXT_QUEUE_OFFSET(i) +
                                        sizeof(u32),
                                        (SCD_FRAME_LIMIT <<
@@ -1687,87 +1728,98 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
                                        SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
 
        }
-       iwl_write_restricted_reg(priv, SCD_INTERRUPT_MASK,
+       iwl4965_write_prph(priv, KDR_SCD_INTERRUPT_MASK,
                                 (1 << priv->hw_setting.max_txq_num) - 1);
 
-       iwl_write_restricted_reg(priv, SCD_TXFACT,
+       /* Activate all Tx DMA/FIFO channels */
+       iwl4965_write_prph(priv, KDR_SCD_TXFACT,
                                 SCD_TXFACT_REG_TXFIFO_MASK(0, 7));
 
        iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);
-       /* map qos queues to fifos one-to-one */
+
+       /* Map each Tx/cmd queue to its corresponding fifo */
        for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
                int ac = default_queue_to_tx_fifo[i];
                iwl4965_txq_ctx_activate(priv, i);
                iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
        }
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-int iwl_hw_set_hw_setting(struct iwl_priv *priv)
+/**
+ * iwl4965_hw_set_hw_setting
+ *
+ * Called when initializing driver
+ */
+int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv)
 {
+       /* Allocate area for Tx byte count tables and Rx queue status */
        priv->hw_setting.shared_virt =
            pci_alloc_consistent(priv->pci_dev,
-                                sizeof(struct iwl_shared),
+                                sizeof(struct iwl4965_shared),
                                 &priv->hw_setting.shared_phys);
 
        if (!priv->hw_setting.shared_virt)
                return -1;
 
-       memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl_shared));
+       memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared));
 
-       priv->hw_setting.max_txq_num = iwl_param_queues_num;
+       priv->hw_setting.max_txq_num = iwl4965_param_queues_num;
        priv->hw_setting.ac_queue_count = AC_NUM;
-
-       priv->hw_setting.cck_flag = RATE_MCS_CCK_MSK;
-       priv->hw_setting.tx_cmd_len = sizeof(struct iwl_tx_cmd);
+       priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd);
        priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
        priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
-
+       if (iwl4965_param_amsdu_size_8K)
+               priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_8K;
+       else
+               priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_4K;
+       priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256;
        priv->hw_setting.max_stations = IWL4965_STATION_COUNT;
        priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID;
        return 0;
 }
 
 /**
- * iwl_hw_txq_ctx_free - Free TXQ Context
+ * iwl4965_hw_txq_ctx_free - Free TXQ Context
  *
  * Destroy all TX DMA queues and structures
  */
-void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
+void iwl4965_hw_txq_ctx_free(struct iwl4965_priv *priv)
 {
        int txq_id;
 
        /* Tx queues */
        for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++)
-               iwl_tx_queue_free(priv, &priv->txq[txq_id]);
+               iwl4965_tx_queue_free(priv, &priv->txq[txq_id]);
 
+       /* Keep-warm buffer */
        iwl4965_kw_free(priv);
 }
 
 /**
- * iwl_hw_txq_free_tfd -  Free one TFD, those at index [txq->q.last_used]
+ * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
  *
- * Does NOT advance any indexes
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
  */
-int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq)
 {
-       struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
-       struct iwl_tfd_frame *bd = &bd_tmp[txq->q.last_used];
+       struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0];
+       struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
        struct pci_dev *dev = priv->pci_dev;
        int i;
        int counter = 0;
        int index, is_odd;
 
-       /* classify bd */
+       /* Host command buffers stay mapped in memory, nothing to clean */
        if (txq->q.id == IWL_CMD_QUEUE_NUM)
-               /* nothing to cleanup after for host commands */
                return 0;
 
-       /* sanity check */
+       /* Sanity check on number of chunks */
        counter = IWL_GET_BITS(*bd, num_tbs);
        if (counter > MAX_NUM_OF_TBS) {
                IWL_ERROR("Too many chunks: %i\n", counter);
@@ -1775,8 +1827,8 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                return 0;
        }
 
-       /* unmap chunks if any */
-
+       /* Unmap chunks, if any.
+        * TFD info for odd chunks is different format than for even chunks. */
        for (i = 0; i < counter; i++) {
                index = i / 2;
                is_odd = i & 0x1;
@@ -1796,19 +1848,20 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                                         IWL_GET_BITS(bd->pa[index], tb1_len),
                                         PCI_DMA_TODEVICE);
 
-               if (txq->txb[txq->q.last_used].skb[i]) {
-                       struct sk_buff *skb = txq->txb[txq->q.last_used].skb[i];
+               /* Free SKB, if any, for this chunk */
+               if (txq->txb[txq->q.read_ptr].skb[i]) {
+                       struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
 
                        dev_kfree_skb(skb);
-                       txq->txb[txq->q.last_used].skb[i] = NULL;
+                       txq->txb[txq->q.read_ptr].skb[i] = NULL;
                }
        }
        return 0;
 }
 
-int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
+int iwl4965_hw_reg_set_txpower(struct iwl4965_priv *priv, s8 power)
 {
-       IWL_ERROR("TODO: Implement iwl_hw_reg_set_txpower!\n");
+       IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n");
        return -EINVAL;
 }
 
@@ -1830,6 +1883,17 @@ static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
        return 1;
 }
 
+/**
+ * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower
+ *
+ * Determines power supply voltage compensation for txpower calculations.
+ * Returns number of 1/2-dB steps to subtract from gain table index,
+ * to compensate for difference between power supply voltage during
+ * factory measurements, vs. current power supply voltage.
+ *
+ * Voltage indication is higher for lower voltage.
+ * Lower voltage requires more gain (lower gain table index).
+ */
 static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
                                            s32 current_voltage)
 {
@@ -1850,12 +1914,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
        return comp;
 }
 
-static const struct iwl_channel_info *
-iwl4965_get_channel_txpower_info(struct iwl_priv *priv, u8 phymode, u16 channel)
+static const struct iwl4965_channel_info *
+iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, u8 phymode, u16 channel)
 {
-       const struct iwl_channel_info *ch_info;
+       const struct iwl4965_channel_info *ch_info;
 
-       ch_info = iwl_get_channel_info(priv, phymode, channel);
+       ch_info = iwl4965_get_channel_info(priv, phymode, channel);
 
        if (!is_channel_valid(ch_info))
                return NULL;
@@ -1889,7 +1953,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel)
        return -1;
 }
 
-static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
+static u32 iwl4965_get_sub_band(const struct iwl4965_priv *priv, u32 channel)
 {
        s32 b = -1;
 
@@ -1917,15 +1981,23 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
        }
 }
 
-static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
-                                   struct iwl_eeprom_calib_ch_info *chan_info)
+/**
+ * iwl4965_interpolate_chan - Interpolate factory measurements for one channel
+ *
+ * Interpolates factory measurements from the two sample channels within a
+ * sub-band, to apply to channel of interest.  Interpolation is proportional to
+ * differences in channel frequencies, which is proportional to differences
+ * in channel number.
+ */
+static int iwl4965_interpolate_chan(struct iwl4965_priv *priv, u32 channel,
+                                   struct iwl4965_eeprom_calib_ch_info *chan_info)
 {
        s32 s = -1;
        u32 c;
        u32 m;
-       const struct iwl_eeprom_calib_measure *m1;
-       const struct iwl_eeprom_calib_measure *m2;
-       struct iwl_eeprom_calib_measure *omeas;
+       const struct iwl4965_eeprom_calib_measure *m1;
+       const struct iwl4965_eeprom_calib_measure *m2;
+       struct iwl4965_eeprom_calib_measure *omeas;
        u32 ch_i1;
        u32 ch_i2;
 
@@ -2000,7 +2072,7 @@ static s32 back_off_table[] = {
 
 /* Thermal compensation values for txpower for various frequency ranges ...
  *   ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */
-static struct iwl_txpower_comp_entry {
+static struct iwl4965_txpower_comp_entry {
        s32 degrees_per_05db_a;
        s32 degrees_per_05db_a_denom;
 } tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {
@@ -2250,9 +2322,9 @@ static const struct gain_entry gain_table[2][108] = {
         }
 };
 
-static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
+static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 channel,
                                    u8 is_fat, u8 ctrl_chan_high,
-                                   struct iwl_tx_power_db *tx_power_tbl)
+                                   struct iwl4965_tx_power_db *tx_power_tbl)
 {
        u8 saturation_power;
        s32 target_power;
@@ -2264,9 +2336,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
        s32 txatten_grp = CALIB_CH_GROUP_MAX;
        int i;
        int c;
-       const struct iwl_channel_info *ch_info = NULL;
-       struct iwl_eeprom_calib_ch_info ch_eeprom_info;
-       const struct iwl_eeprom_calib_measure *measurement;
+       const struct iwl4965_channel_info *ch_info = NULL;
+       struct iwl4965_eeprom_calib_ch_info ch_eeprom_info;
+       const struct iwl4965_eeprom_calib_measure *measurement;
        s16 voltage;
        s32 init_voltage;
        s32 voltage_compensation;
@@ -2405,7 +2477,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
        /* for each of 33 bit-rates (including 1 for CCK) */
        for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) {
                u8 is_mimo_rate;
-               union iwl_tx_power_dual_stream tx_power;
+               union iwl4965_tx_power_dual_stream tx_power;
 
                /* for mimo, reduce each chain's txpower by half
                 * (3dB, 6 steps), so total output power is regulatory
@@ -2502,14 +2574,14 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
 }
 
 /**
- * iwl_hw_reg_send_txpower - Configure the TXPOWER level user limit
+ * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit
  *
  * Uses the active RXON for channel, band, and characteristics (fat, high)
  * The power limit is taken from priv->user_txpower_limit.
  */
-int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
+int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv)
 {
-       struct iwl_txpowertable_cmd cmd = { 0 };
+       struct iwl4965_txpowertable_cmd cmd = { 0 };
        int rc = 0;
        u8 band = 0;
        u8 is_fat = 0;
@@ -2541,23 +2613,23 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv)
        if (rc)
                return rc;
 
-       rc = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd);
+       rc = iwl4965_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd);
        return rc;
 }
 
-int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel)
 {
        int rc;
        u8 band = 0;
        u8 is_fat = 0;
        u8 ctrl_chan_high = 0;
-       struct iwl_channel_switch_cmd cmd = { 0 };
-       const struct iwl_channel_info *ch_info;
+       struct iwl4965_channel_switch_cmd cmd = { 0 };
+       const struct iwl4965_channel_info *ch_info;
 
        band = ((priv->phymode == MODE_IEEE80211B) ||
                (priv->phymode == MODE_IEEE80211G));
 
-       ch_info = iwl_get_channel_info(priv, priv->phymode, channel);
+       ch_info = iwl4965_get_channel_info(priv, priv->phymode, channel);
 
        is_fat = is_fat_channel(priv->staging_rxon.flags);
 
@@ -2583,32 +2655,36 @@ int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel)
                return rc;
        }
 
-       rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
+       rc = iwl4965_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
        return rc;
 }
 
 #define RTS_HCCA_RETRY_LIMIT           3
 #define RTS_DFAULT_RETRY_LIMIT         60
 
-void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
-                             struct iwl_cmd *cmd,
+void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv,
+                             struct iwl4965_cmd *cmd,
                              struct ieee80211_tx_control *ctrl,
                              struct ieee80211_hdr *hdr, int sta_id,
                              int is_hcca)
 {
-       u8 rate;
+       struct iwl4965_tx_cmd *tx = &cmd->cmd.tx;
        u8 rts_retry_limit = 0;
        u8 data_retry_limit = 0;
-       __le32 tx_flags;
        u16 fc = le16_to_cpu(hdr->frame_control);
+       u8 rate_plcp;
+       u16 rate_flags = 0;
+       int rate_idx = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1);
 
-       tx_flags = cmd->cmd.tx.tx_flags;
-
-       rate = iwl_rates[ctrl->tx_rate].plcp;
+       rate_plcp = iwl4965_rates[rate_idx].plcp;
 
        rts_retry_limit = (is_hcca) ?
            RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;
 
+       if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
+               rate_flags |= RATE_MCS_CCK_MSK;
+
+
        if (ieee80211_is_probe_response(fc)) {
                data_retry_limit = 3;
                if (data_retry_limit < rts_retry_limit)
@@ -2619,44 +2695,56 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
        if (priv->data_retry_limit != -1)
                data_retry_limit = priv->data_retry_limit;
 
-       if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
+
+       if (ieee80211_is_data(fc)) {
+               tx->initial_rate_index = 0;
+               tx->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
+       } else {
                switch (fc & IEEE80211_FCTL_STYPE) {
                case IEEE80211_STYPE_AUTH:
                case IEEE80211_STYPE_DEAUTH:
                case IEEE80211_STYPE_ASSOC_REQ:
                case IEEE80211_STYPE_REASSOC_REQ:
-                       if (tx_flags & TX_CMD_FLG_RTS_MSK) {
-                               tx_flags &= ~TX_CMD_FLG_RTS_MSK;
-                               tx_flags |= TX_CMD_FLG_CTS_MSK;
+                       if (tx->tx_flags & TX_CMD_FLG_RTS_MSK) {
+                               tx->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
+                               tx->tx_flags |= TX_CMD_FLG_CTS_MSK;
                        }
                        break;
                default:
                        break;
                }
+
+               /* Alternate between antenna A and B for successive frames */
+               if (priv->use_ant_b_for_management_frame) {
+                       priv->use_ant_b_for_management_frame = 0;
+                       rate_flags |= RATE_MCS_ANT_B_MSK;
+               } else {
+                       priv->use_ant_b_for_management_frame = 1;
+                       rate_flags |= RATE_MCS_ANT_A_MSK;
+               }
        }
 
-       cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
-       cmd->cmd.tx.data_retry_limit = data_retry_limit;
-       cmd->cmd.tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, 0);
-       cmd->cmd.tx.tx_flags = tx_flags;
+       tx->rts_retry_limit = rts_retry_limit;
+       tx->data_retry_limit = data_retry_limit;
+       tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
 }
 
-int iwl_hw_get_rx_read(struct iwl_priv *priv)
+int iwl4965_hw_get_rx_read(struct iwl4965_priv *priv)
 {
-       struct iwl_shared *shared_data = priv->hw_setting.shared_virt;
+       struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt;
 
        return IWL_GET_BITS(*shared_data, rb_closed_stts_rb_num);
 }
 
-int iwl_hw_get_temperature(struct iwl_priv *priv)
+int iwl4965_hw_get_temperature(struct iwl4965_priv *priv)
 {
        return priv->temperature;
 }
 
-unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
-                         struct iwl_frame *frame, u8 rate)
+unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv,
+                         struct iwl4965_frame *frame, u8 rate)
 {
-       struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+       struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
        unsigned int frame_size;
 
        tx_beacon_cmd = &frame->u.beacon;
@@ -2665,9 +2753,9 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
        tx_beacon_cmd->tx.sta_id = IWL4965_BROADCAST_ID;
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
-       frame_size = iwl_fill_beacon_frame(priv,
+       frame_size = iwl4965_fill_beacon_frame(priv,
                                tx_beacon_cmd->frame,
-                               BROADCAST_ADDR,
+                               iwl4965_broadcast_addr,
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 
        BUG_ON(frame_size > MAX_MPDU_SIZE);
@@ -2675,53 +2763,59 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
 
        if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
                tx_beacon_cmd->tx.rate_n_flags =
-                       iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
+                       iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
        else
                tx_beacon_cmd->tx.rate_n_flags =
-                       iwl_hw_set_rate_n_flags(rate, 0);
+                       iwl4965_hw_set_rate_n_flags(rate, 0);
 
        tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
                                TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
        return (sizeof(*tx_beacon_cmd) + frame_size);
 }
 
-int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+/*
+ * Tell 4965 where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+int iwl4965_hw_tx_queue_init(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq)
 {
        int rc;
        unsigned long flags;
        int txq_id = txq->q.id;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
-       iwl_write_restricted(priv, FH_MEM_CBBC_QUEUE(txq_id),
+       /* Circular buffer (TFD queue in DRAM) physical base address */
+       iwl4965_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
                             txq->q.dma_addr >> 8);
-       iwl_write_restricted(
+
+       /* Enable DMA channel, using same id as for TFD queue */
+       iwl4965_write_direct32(
                priv, IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
                IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
                IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL);
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-static inline u8 iwl4965_get_dma_hi_address(dma_addr_t addr)
-{
-       return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0;
-}
-
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
+int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl4965_priv *priv, void *ptr,
                                 dma_addr_t addr, u16 len)
 {
        int index, is_odd;
-       struct iwl_tfd_frame *tfd = ptr;
+       struct iwl4965_tfd_frame *tfd = ptr;
        u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
 
+       /* Each TFD can point to a maximum 20 Tx buffers */
        if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) {
                IWL_ERROR("Error can not send more than %d chunks\n",
                          MAX_NUM_OF_TBS);
@@ -2734,7 +2828,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
        if (!is_odd) {
                tfd->pa[index].tb1_addr = cpu_to_le32(addr);
                IWL_SET_BITS(tfd->pa[index], tb1_addr_hi,
-                            iwl4965_get_dma_hi_address(addr));
+                            iwl_get_dma_hi_address(addr));
                IWL_SET_BITS(tfd->pa[index], tb1_len, len);
        } else {
                IWL_SET_BITS(tfd->pa[index], tb2_addr_lo16,
@@ -2748,7 +2842,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
        return 0;
 }
 
-void iwl_hw_card_show_info(struct iwl_priv *priv)
+static void iwl4965_hw_card_show_info(struct iwl4965_priv *priv)
 {
        u16 hw_version = priv->eeprom.board_revision_4965;
 
@@ -2763,32 +2857,41 @@ void iwl_hw_card_show_info(struct iwl_priv *priv)
 #define IWL_TX_CRC_SIZE                4
 #define IWL_TX_DELIMITER_SIZE  4
 
-int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
-                                  struct iwl_tx_queue *txq, u16 byte_cnt)
+/**
+ * iwl4965_tx_queue_update_wr_ptr - Set up entry in Tx byte-count array
+ */
+int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
+                                  struct iwl4965_tx_queue *txq, u16 byte_cnt)
 {
        int len;
        int txq_id = txq->q.id;
-       struct iwl_shared *shared_data = priv->hw_setting.shared_virt;
+       struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt;
 
        if (txq->need_update == 0)
                return 0;
 
        len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
 
+       /* Set up byte count within first 256 entries */
        IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                      tfd_offset[txq->q.first_empty], byte_cnt, len);
+                      tfd_offset[txq->q.write_ptr], byte_cnt, len);
 
-       if (txq->q.first_empty < IWL4965_MAX_WIN_SIZE)
+       /* If within first 64 entries, duplicate at end */
+       if (txq->q.write_ptr < IWL4965_MAX_WIN_SIZE)
                IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id].
-                       tfd_offset[IWL4965_QUEUE_SIZE + txq->q.first_empty],
+                       tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr],
                        byte_cnt, len);
 
        return 0;
 }
 
-/* Set up Rx receiver/antenna/chain usage in "staging" RXON image.
- * This should not be used for scan command ... it puts data in wrong place.  */
-void iwl4965_set_rxon_chain(struct iwl_priv *priv)
+/**
+ * iwl4965_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
+ *
+ * Selects how many and which Rx receivers/antennas/chains to use.
+ * This should not be used for scan command ... it puts data in wrong place.
+ */
+void iwl4965_set_rxon_chain(struct iwl4965_priv *priv)
 {
        u8 is_single = is_single_stream(priv);
        u8 idle_state, rx_state;
@@ -2819,19 +2922,19 @@ void iwl4965_set_rxon_chain(struct iwl_priv *priv)
        IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain);
 }
 
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
 /*
        get the traffic load value for tid
 */
-static u32 iwl4965_tl_get_load(struct iwl_priv *priv, u8 tid)
+static u32 iwl4965_tl_get_load(struct iwl4965_priv *priv, u8 tid)
 {
        u32 load = 0;
        u32 current_time = jiffies_to_msecs(jiffies);
        u32 time_diff;
        s32 index;
        unsigned long flags;
-       struct iwl_traffic_load *tid_ptr = NULL;
+       struct iwl4965_traffic_load *tid_ptr = NULL;
 
        if (tid >= TID_MAX_LOAD_COUNT)
                return 0;
@@ -2872,13 +2975,13 @@ static u32 iwl4965_tl_get_load(struct iwl_priv *priv, u8 tid)
        increment traffic load value for tid and also remove
        any old values if passed the certian time period
 */
-static void iwl4965_tl_add_packet(struct iwl_priv *priv, u8 tid)
+static void iwl4965_tl_add_packet(struct iwl4965_priv *priv, u8 tid)
 {
        u32 current_time = jiffies_to_msecs(jiffies);
        u32 time_diff;
        s32 index;
        unsigned long flags;
-       struct iwl_traffic_load *tid_ptr = NULL;
+       struct iwl4965_traffic_load *tid_ptr = NULL;
 
        if (tid >= TID_MAX_LOAD_COUNT)
                return;
@@ -2935,14 +3038,19 @@ enum HT_STATUS {
        BA_STATUS_ACTIVE,
 };
 
-static u8 iwl4964_tl_ba_avail(struct iwl_priv *priv)
+/**
+ * iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available
+ */
+static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv)
 {
        int i;
-       struct iwl_lq_mngr *lq;
+       struct iwl4965_lq_mngr *lq;
        u8 count = 0;
        u16 msk;
 
-       lq = (struct iwl_lq_mngr *)&(priv->lq_mngr);
+       lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr);
+
+       /* Find out how many agg queues are in use */
        for (i = 0; i < TID_MAX_LOAD_COUNT ; i++) {
                msk = 1 << i;
                if ((lq->agg_ctrl.granted_ba & msk) ||
@@ -2956,10 +3064,10 @@ static u8 iwl4964_tl_ba_avail(struct iwl_priv *priv)
        return 0;
 }
 
-static void iwl4965_ba_status(struct iwl_priv *priv,
+static void iwl4965_ba_status(struct iwl4965_priv *priv,
                              u8 tid, enum HT_STATUS status);
 
-static int iwl4965_perform_addba(struct iwl_priv *priv, u8 tid, u32 length,
+static int iwl4965_perform_addba(struct iwl4965_priv *priv, u8 tid, u32 length,
                                 u32 ba_timeout)
 {
        int rc;
@@ -2971,7 +3079,7 @@ static int iwl4965_perform_addba(struct iwl_priv *priv, u8 tid, u32 length,
        return rc;
 }
 
-static int iwl4965_perform_delba(struct iwl_priv *priv, u8 tid)
+static int iwl4965_perform_delba(struct iwl4965_priv *priv, u8 tid)
 {
        int rc;
 
@@ -2982,8 +3090,8 @@ static int iwl4965_perform_delba(struct iwl_priv *priv, u8 tid)
        return rc;
 }
 
-static void iwl4965_turn_on_agg_for_tid(struct iwl_priv *priv,
-                                       struct iwl_lq_mngr *lq,
+static void iwl4965_turn_on_agg_for_tid(struct iwl4965_priv *priv,
+                                       struct iwl4965_lq_mngr *lq,
                                        u8 auto_agg, u8 tid)
 {
        u32 tid_msk = (1 << tid);
@@ -3030,12 +3138,12 @@ static void iwl4965_turn_on_agg_for_tid(struct iwl_priv *priv,
        spin_unlock_irqrestore(&priv->lq_mngr.lock, flags);
 }
 
-static void iwl4965_turn_on_agg(struct iwl_priv *priv, u8 tid)
+static void iwl4965_turn_on_agg(struct iwl4965_priv *priv, u8 tid)
 {
-       struct iwl_lq_mngr *lq;
+       struct iwl4965_lq_mngr *lq;
        unsigned long flags;
 
-       lq = (struct iwl_lq_mngr *)&(priv->lq_mngr);
+       lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr);
 
        if ((tid < TID_MAX_LOAD_COUNT))
                iwl4965_turn_on_agg_for_tid(priv, lq, lq->agg_ctrl.auto_agg,
@@ -3055,13 +3163,13 @@ static void iwl4965_turn_on_agg(struct iwl_priv *priv, u8 tid)
 
 }
 
-void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid)
+void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid)
 {
        u32 tid_msk;
-       struct iwl_lq_mngr *lq;
+       struct iwl4965_lq_mngr *lq;
        unsigned long flags;
 
-       lq = (struct iwl_lq_mngr *)&(priv->lq_mngr);
+       lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr);
 
        if ((tid < TID_MAX_LOAD_COUNT)) {
                tid_msk = 1 << tid;
@@ -3084,14 +3192,17 @@ void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid)
        }
 }
 
-static void iwl4965_ba_status(struct iwl_priv *priv,
+/**
+ * iwl4965_ba_status - Update driver's link quality mgr with tid's HT status
+ */
+static void iwl4965_ba_status(struct iwl4965_priv *priv,
                                u8 tid, enum HT_STATUS status)
 {
-       struct iwl_lq_mngr *lq;
+       struct iwl4965_lq_mngr *lq;
        u32 tid_msk = (1 << tid);
        unsigned long flags;
 
-       lq = (struct iwl_lq_mngr *)&(priv->lq_mngr);
+       lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr);
 
        if ((tid >= TID_MAX_LOAD_COUNT))
                goto out;
@@ -3124,14 +3235,14 @@ static void iwl4965_ba_status(struct iwl_priv *priv,
 
 static void iwl4965_bg_agg_work(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv,
                                        agg_work);
 
        u32 tid;
        u32 retry_tid;
        u32 tid_msk;
        unsigned long flags;
-       struct iwl_lq_mngr *lq = (struct iwl_lq_mngr *)&(priv->lq_mngr);
+       struct iwl4965_lq_mngr *lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr);
 
        spin_lock_irqsave(&priv->lq_mngr.lock, flags);
        retry_tid = lq->agg_ctrl.tid_retry;
@@ -3154,90 +3265,13 @@ static void iwl4965_bg_agg_work(struct work_struct *work)
        spin_unlock_irqrestore(&priv->lq_mngr.lock, flags);
        return;
 }
-#endif /*CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
 
-int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd,
-                  u8 sta_id, dma_addr_t txcmd_phys,
-                  struct ieee80211_hdr *hdr, u8 hdr_len,
-                  struct ieee80211_tx_control *ctrl, void *sta_in)
+/* TODO: move this functionality to rate scaling */
+void iwl4965_tl_get_stats(struct iwl4965_priv *priv,
+                  struct ieee80211_hdr *hdr)
 {
-       struct iwl_tx_cmd cmd;
-       struct iwl_tx_cmd *tx = (struct iwl_tx_cmd *)&out_cmd->cmd.payload[0];
-       dma_addr_t scratch_phys;
-       u8 unicast = 0;
-       u8 is_data = 1;
-       u16 fc;
-       u16 rate_flags;
-       int rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1);
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       __le16 *qc;
-#endif /*CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
-
-       unicast = !is_multicast_ether_addr(hdr->addr1);
-
-       fc = le16_to_cpu(hdr->frame_control);
-       if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
-               is_data = 0;
-
-       memcpy(&cmd, &(out_cmd->cmd.tx), sizeof(struct iwl_tx_cmd));
-       memset(tx, 0, sizeof(struct iwl_tx_cmd));
-       memcpy(tx->hdr, hdr, hdr_len);
-
-       tx->len = cmd.len;
-       tx->driver_txop = cmd.driver_txop;
-       tx->stop_time.life_time = cmd.stop_time.life_time;
-       tx->tx_flags = cmd.tx_flags;
-       tx->sta_id = cmd.sta_id;
-       tx->tid_tspec = cmd.tid_tspec;
-       tx->timeout.pm_frame_timeout = cmd.timeout.pm_frame_timeout;
-       tx->next_frame_len = cmd.next_frame_len;
-
-       tx->sec_ctl = cmd.sec_ctl;
-       memcpy(&(tx->key[0]), &(cmd.key[0]), 16);
-       tx->tx_flags = cmd.tx_flags;
-
-       tx->rts_retry_limit = cmd.rts_retry_limit;
-       tx->data_retry_limit = cmd.data_retry_limit;
-
-       scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
-           offsetof(struct iwl_tx_cmd, scratch);
-       tx->dram_lsb_ptr = cpu_to_le32(scratch_phys);
-       tx->dram_msb_ptr = iwl4965_get_dma_hi_address(scratch_phys);
-
-       /* Hard coded to start at the highest retry fallback position
-        * until the 4965 specific rate control algorithm is tied in */
-       tx->initial_rate_index = LINK_QUAL_MAX_RETRY_NUM - 1;
-
-       /* Alternate between antenna A and B for successive frames */
-       if (priv->use_ant_b_for_management_frame) {
-               priv->use_ant_b_for_management_frame = 0;
-               rate_flags = RATE_MCS_ANT_B_MSK;
-       } else {
-               priv->use_ant_b_for_management_frame = 1;
-               rate_flags = RATE_MCS_ANT_A_MSK;
-       }
+       __le16 *qc = ieee80211_get_qos_ctrl(hdr);
 
-       if (!unicast || !is_data) {
-               if ((rate_index >= IWL_FIRST_CCK_RATE) &&
-                   (rate_index <= IWL_LAST_CCK_RATE))
-                       rate_flags |= RATE_MCS_CCK_MSK;
-       } else {
-               tx->initial_rate_index = 0;
-               tx->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
-       }
-
-       tx->rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[rate_index].plcp,
-                                               rate_flags);
-
-       if (ieee80211_is_back_request(fc))
-               tx->tx_flags |= TX_CMD_FLG_ACK_MSK |
-                       TX_CMD_FLG_IMM_BA_RSP_MASK;
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       qc = ieee80211_get_qos_ctrl(hdr);
        if (qc &&
            (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) {
                u8 tid = 0;
@@ -3255,11 +3289,11 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd,
                spin_unlock_irqrestore(&priv->lq_mngr.lock, flags);
                schedule_work(&priv->agg_work);
        }
-#endif
-#endif
-       return 0;
 }
 
+#endif /*CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
+
 /**
  * sign_extend - Sign extend a value using specified bit as sign-bit
  *
@@ -3282,7 +3316,7 @@ static s32 sign_extend(u32 oper, int index)
  *
  * A return of <0 indicates bogus data in the statistics
  */
-int iwl4965_get_temperature(const struct iwl_priv *priv)
+int iwl4965_get_temperature(const struct iwl4965_priv *priv)
 {
        s32 temperature;
        s32 vt;
@@ -3305,11 +3339,12 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
        }
 
        /*
-        * Temperature is only 23 bits so sign extend out to 32
+        * Temperature is only 23 bits, so sign extend out to 32.
         *
         * NOTE If we haven't received a statistics notification yet
         * with an updated temperature, use R4 provided to us in the
-        * ALIVE response. */
+        * "initialize" ALIVE response.
+        */
        if (!test_bit(STATUS_TEMPERATURE, &priv->status))
                vt = sign_extend(R4, 23);
        else
@@ -3349,7 +3384,7 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
  * Assumes caller will replace priv->last_temperature once calibration
  * executed.
  */
-static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
+static int iwl4965_is_temp_calib_needed(struct iwl4965_priv *priv)
 {
        int temp_diff;
 
@@ -3382,7 +3417,7 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
 /* Calculate noise level, based on measurements during network silence just
  *   before arriving beacon.  This measurement can be done only if we know
  *   exactly when to expect beacons, therefore only when we're associated. */
-static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
+static void iwl4965_rx_calc_noise(struct iwl4965_priv *priv)
 {
        struct statistics_rx_non_phy *rx_info
                                = &(priv->statistics.rx.general);
@@ -3419,9 +3454,9 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
                        priv->last_rx_noise);
 }
 
-void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+void iwl4965_hw_rx_statistics(struct iwl4965_priv *priv, struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        int change;
        s32 temp;
 
@@ -3448,7 +3483,7 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
            (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
                iwl4965_rx_calc_noise(priv);
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
                queue_work(priv->workqueue, &priv->sensitivity_work);
 #endif
        }
@@ -3483,12 +3518,117 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                queue_work(priv->workqueue, &priv->txpower_work);
 }
 
-static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
+static void iwl4965_add_radiotap(struct iwl4965_priv *priv,
+                                struct sk_buff *skb,
+                                struct iwl4965_rx_phy_res *rx_start,
+                                struct ieee80211_rx_status *stats,
+                                u32 ampdu_status)
+{
+       s8 signal = stats->ssi;
+       s8 noise = 0;
+       int rate = stats->rate;
+       u64 tsf = stats->mactime;
+       __le16 phy_flags_hw = rx_start->phy_flags;
+       struct iwl4965_rt_rx_hdr {
+               struct ieee80211_radiotap_header rt_hdr;
+               __le64 rt_tsf;          /* TSF */
+               u8 rt_flags;            /* radiotap packet flags */
+               u8 rt_rate;             /* rate in 500kb/s */
+               __le16 rt_channelMHz;   /* channel in MHz */
+               __le16 rt_chbitmask;    /* channel bitfield */
+               s8 rt_dbmsignal;        /* signal in dBm, kluged to signed */
+               s8 rt_dbmnoise;
+               u8 rt_antenna;          /* antenna number */
+       } __attribute__ ((packed)) *iwl4965_rt;
+
+       /* TODO: We won't have enough headroom for HT frames. Fix it later. */
+       if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
+               if (net_ratelimit())
+                       printk(KERN_ERR "not enough headroom [%d] for "
+                              "radiotap head [%zd]\n",
+                              skb_headroom(skb), sizeof(*iwl4965_rt));
+               return;
+       }
+
+       /* put radiotap header in front of 802.11 header and data */
+       iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
+
+       /* initialise radiotap header */
+       iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+       iwl4965_rt->rt_hdr.it_pad = 0;
+
+       /* total header + data */
+       put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)),
+                     &iwl4965_rt->rt_hdr.it_len);
+
+       /* Indicate all the fields we add to the radiotap header */
+       put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
+                                 (1 << IEEE80211_RADIOTAP_FLAGS) |
+                                 (1 << IEEE80211_RADIOTAP_RATE) |
+                                 (1 << IEEE80211_RADIOTAP_CHANNEL) |
+                                 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+                                 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
+                                 (1 << IEEE80211_RADIOTAP_ANTENNA)),
+                     &iwl4965_rt->rt_hdr.it_present);
+
+       /* Zero the flags, we'll add to them as we go */
+       iwl4965_rt->rt_flags = 0;
+
+       put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf);
+
+       iwl4965_rt->rt_dbmsignal = signal;
+       iwl4965_rt->rt_dbmnoise = noise;
+
+       /* Convert the channel frequency and set the flags */
+       put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
+       if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
+                                         IEEE80211_CHAN_5GHZ),
+                             &iwl4965_rt->rt_chbitmask);
+       else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK |
+                                         IEEE80211_CHAN_2GHZ),
+                             &iwl4965_rt->rt_chbitmask);
+       else    /* 802.11g */
+               put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
+                                         IEEE80211_CHAN_2GHZ),
+                             &iwl4965_rt->rt_chbitmask);
+
+       rate = iwl4965_rate_index_from_plcp(rate);
+       if (rate == -1)
+               iwl4965_rt->rt_rate = 0;
+       else
+               iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee;
+
+       /*
+        * "antenna number"
+        *
+        * It seems that the antenna field in the phy flags value
+        * is actually a bitfield. This is undefined by radiotap,
+        * it wants an actual antenna number but I always get "7"
+        * for most legacy frames I receive indicating that the
+        * same frame was received on all three RX chains.
+        *
+        * I think this field should be removed in favour of a
+        * new 802.11n radiotap field "RX chains" that is defined
+        * as a bitmask.
+        */
+       iwl4965_rt->rt_antenna =
+               le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
+
+       /* set the preamble flag if appropriate */
+       if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
+               iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+       stats->flag |= RX_FLAG_RADIOTAP;
+}
+
+static void iwl4965_handle_data_packet(struct iwl4965_priv *priv, int is_data,
                                       int include_phy,
-                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl4965_rx_mem_buffer *rxb,
                                       struct ieee80211_rx_status *stats)
 {
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
        struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
            (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
        struct ieee80211_hdr *hdr;
@@ -3524,9 +3664,8 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
                rx_start->byte_count = amsdu->byte_count;
                rx_end = (__le32 *) (((u8 *) hdr) + len);
        }
-       if (len > 2342 || len < 16) {
-               IWL_DEBUG_DROP("byte count out of range [16,2342]"
-                              " : %d\n", len);
+       if (len > priv->hw_setting.max_pkt_size || len < 16) {
+               IWL_WARNING("byte count out of range [16,4K] : %d\n", len);
                return;
        }
 
@@ -3544,26 +3683,21 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
                return;
        }
 
-       if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-               if (iwl_param_hwcrypto)
-                       iwl_set_decrypted_flag(priv, rxb->skb,
-                                              ampdu_status, stats);
-               iwl_handle_data_packet_monitor(priv, rxb, hdr, len, stats, 0);
-               return;
-       }
-
        stats->flag = 0;
        hdr = (struct ieee80211_hdr *)rxb->skb->data;
 
-       if (iwl_param_hwcrypto)
-               iwl_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats);
+       if (iwl4965_param_hwcrypto)
+               iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats);
+
+       if (priv->add_radiotap)
+               iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
 
        ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
        priv->alloc_rxb_skb--;
        rxb->skb = NULL;
 #ifdef LED
        priv->led_packets += len;
-       iwl_setup_activity_timer(priv);
+       iwl4965_setup_activity_timer(priv);
 #endif
 }
 
@@ -3601,7 +3735,7 @@ static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp)
        return (max_rssi - agc - IWL_RSSI_OFFSET);
 }
 
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
 
 /* Parsed Information Elements */
 struct ieee802_11_elems {
@@ -3673,9 +3807,37 @@ static int parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems)
 
        return 0;
 }
-#endif /* CONFIG_IWLWIFI_HT */
 
-static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
+void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, int mode)
+{
+       ht_info->cap = 0;
+       memset(ht_info->supp_mcs_set, 0, 16);
+
+       ht_info->ht_supported = 1;
+
+       if (mode == MODE_IEEE80211A) {
+               ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH;
+               ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40;
+               ht_info->supp_mcs_set[4] = 0x01;
+       }
+       ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
+       ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
+       ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS &
+                            (IWL_MIMO_PS_NONE << 2));
+       if (iwl4965_param_amsdu_size_8K) {
+               printk(KERN_DEBUG "iwl4965 in A-MSDU 8K support mode\n");
+               ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU;
+       }
+
+       ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
+       ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
+
+       ht_info->supp_mcs_set[0] = 0xFF;
+       ht_info->supp_mcs_set[1] = 0xFF;
+}
+#endif /* CONFIG_IWL4965_HT */
+
+static void iwl4965_sta_modify_ps_wake(struct iwl4965_priv *priv, int sta_id)
 {
        unsigned long flags;
 
@@ -3686,13 +3848,13 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 }
 
-static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
+static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *addr)
 {
        /* FIXME: need locking over ps_status ??? */
-       u8 sta_id = iwl_hw_find_station(priv, addr);
+       u8 sta_id = iwl4965_hw_find_station(priv, addr);
 
        if (sta_id != IWL_INVALID_STATION) {
                u8 sta_awake = priv->stations[sta_id].
@@ -3707,12 +3869,14 @@ static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
        }
 }
 
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+
 /* Called for REPLY_4965_RX (legacy ABG frames), or
  * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
-static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
+                               struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        /* Use phy data (Rx signal strength, etc.) contained within
         *   this rx packet for legacy frames,
         *   or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
@@ -3731,11 +3895,8 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                        (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
                        MODE_IEEE80211G : MODE_IEEE80211A,
                .antenna = 0,
-               .rate = iwl_hw_get_rate(rx_start->rate_n_flags),
+               .rate = iwl4965_hw_get_rate(rx_start->rate_n_flags),
                .flag = 0,
-#ifdef CONFIG_IWLWIFI_HT_AGG
-               .ordered = 0
-#endif /* CONFIG_IWLWIFI_HT_AGG */
        };
        u8 network_packet;
 
@@ -3794,32 +3955,32 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
         *   which are gathered only when associated, and indicate noise
         *   only for the associated network channel ...
         * Ignore these noise values while scanning (other channels) */
-       if (iwl_is_associated(priv) &&
+       if (iwl4965_is_associated(priv) &&
            !test_bit(STATUS_SCANNING, &priv->status)) {
                stats.noise = priv->last_rx_noise;
-               stats.signal = iwl_calc_sig_qual(stats.ssi, stats.noise);
+               stats.signal = iwl4965_calc_sig_qual(stats.ssi, stats.noise);
        } else {
                stats.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
-               stats.signal = iwl_calc_sig_qual(stats.ssi, 0);
+               stats.signal = iwl4965_calc_sig_qual(stats.ssi, 0);
        }
 
        /* Reset beacon noise level if not associated. */
-       if (!iwl_is_associated(priv))
+       if (!iwl4965_is_associated(priv))
                priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       /* TODO:  Parts of iwl_report_frame are broken for 4965 */
-       if (iwl_debug_level & (IWL_DL_RX))
+#ifdef CONFIG_IWL4965_DEBUG
+       /* TODO:  Parts of iwl4965_report_frame are broken for 4965 */
+       if (iwl4965_debug_level & (IWL_DL_RX))
                /* Set "1" to report good data frames in groups of 100 */
-               iwl_report_frame(priv, pkt, header, 1);
+               iwl4965_report_frame(priv, pkt, header, 1);
 
-       if (iwl_debug_level & (IWL_DL_RX | IWL_DL_STATS))
+       if (iwl4965_debug_level & (IWL_DL_RX | IWL_DL_STATS))
        IWL_DEBUG_RX("Rssi %d, noise %d, qual %d, TSF %lu\n",
                stats.ssi, stats.noise, stats.signal,
                 (long unsigned int)le64_to_cpu(rx_start->timestamp));
 #endif
 
-       network_packet = iwl_is_network_packet(priv, header);
+       network_packet = iwl4965_is_network_packet(priv, header);
        if (network_packet) {
                priv->last_rx_rssi = stats.ssi;
                priv->last_beacon_time =  priv->ucode_beacon_time;
@@ -3863,27 +4024,31 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                        break;
 
                        /*
-                        * TODO: There is no callback function from upper
-                        * stack to inform us when associated status. this
-                        * work around to sniff assoc_resp management frame
-                        * and finish the association process.
+                        * TODO: Use the new callback function from
+                        * mac80211 instead of sniffing these packets.
                         */
                case IEEE80211_STYPE_ASSOC_RESP:
                case IEEE80211_STYPE_REASSOC_RESP:
                        if (network_packet) {
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
                                u8 *pos = NULL;
                                struct ieee802_11_elems elems;
-#endif                         /*CONFIG_IWLWIFI_HT */
+#endif                         /*CONFIG_IWL4965_HT */
                                struct ieee80211_mgmt *mgnt =
                                        (struct ieee80211_mgmt *)header;
 
+                               /* We have just associated, give some
+                                * time for the 4-way handshake if
+                                * any. Don't start scan too early. */
+                               priv->next_scan_jiffies = jiffies +
+                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+
                                priv->assoc_id = (~((1 << 15) | (1 << 14))
                                        & le16_to_cpu(mgnt->u.assoc_resp.aid));
                                priv->assoc_capability =
                                        le16_to_cpu(
                                                mgnt->u.assoc_resp.capab_info);
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
                                pos = mgnt->u.assoc_resp.variable;
                                if (!parse_elems(pos,
                                                 len - (pos - (u8 *) mgnt),
@@ -3892,7 +4057,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                                            elems.ht_cap_param)
                                                break;
                                }
-#endif                         /*CONFIG_IWLWIFI_HT */
+#endif                         /*CONFIG_IWL4965_HT */
                                /* assoc_id is 0 no association */
                                if (!priv->assoc_id)
                                        break;
@@ -3907,7 +4072,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
 
                case IEEE80211_STYPE_PROBE_REQ:
                        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
-                           !iwl_is_associated(priv)) {
+                           !iwl4965_is_associated(priv)) {
                                DECLARE_MAC_BUF(mac1);
                                DECLARE_MAC_BUF(mac2);
                                DECLARE_MAC_BUF(mac3);
@@ -3924,7 +4089,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                break;
 
        case IEEE80211_FTYPE_CTL:
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
                switch (fc & IEEE80211_FCTL_STYPE) {
                case IEEE80211_STYPE_BACK_REQ:
                        IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
@@ -3935,7 +4100,6 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                        break;
                }
 #endif
-
                break;
 
        case IEEE80211_FTYPE_DATA: {
@@ -3953,7 +4117,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                                       print_mac(mac1, header->addr1),
                                       print_mac(mac2, header->addr2),
                                       print_mac(mac3, header->addr3));
-               else if (unlikely(is_duplicate_packet(priv, header)))
+               else if (unlikely(iwl4965_is_duplicate_packet(priv, header)))
                        IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
                                       print_mac(mac1, header->addr1),
                                       print_mac(mac2, header->addr2),
@@ -3971,22 +4135,22 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
 
 /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
  * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
-static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_rx_phy(struct iwl4965_priv *priv,
+                                   struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        priv->last_phy_res[0] = 1;
        memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
               sizeof(struct iwl4965_rx_phy_res));
 }
 
-static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv,
-                                          struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv,
+                                          struct iwl4965_rx_mem_buffer *rxb)
 
 {
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_missed_beacon_notif *missed_beacon;
+#ifdef CONFIG_IWL4965_SENSITIVITY
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_missed_beacon_notif *missed_beacon;
 
        missed_beacon = &pkt->u.missed_beacon;
        if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) {
@@ -3999,13 +4163,18 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv,
                if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)))
                        queue_work(priv->workqueue, &priv->sensitivity_work);
        }
-#endif /*CONFIG_IWLWIFI_SENSITIVITY*/
+#endif /*CONFIG_IWL4965_SENSITIVITY*/
 }
 
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
 
-static void iwl4965_set_tx_status(struct iwl_priv *priv, int txq_id, int idx,
+/**
+ * iwl4965_set_tx_status - Update driver's record of one Tx frame's status
+ *
+ * This will get sent to mac80211.
+ */
+static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx,
                                  u32 status, u32 retry_count, u32 rate)
 {
        struct ieee80211_tx_status *tx_status =
@@ -4017,24 +4186,34 @@ static void iwl4965_set_tx_status(struct iwl_priv *priv, int txq_id, int idx,
 }
 
 
-static void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv,
+/**
+ * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table
+ */
+static void iwl4965_sta_modify_enable_tid_tx(struct iwl4965_priv *priv,
                                         int sta_id, int tid)
 {
        unsigned long flags;
 
+       /* Remove "disable" flag, to enable Tx for this TID */
        spin_lock_irqsave(&priv->sta_lock, flags);
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
        priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 }
 
 
-static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
-                                                struct iwl_ht_agg *agg,
-                                                struct iwl_compressed_ba_resp*
+/**
+ * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack
+ *
+ * Go through block-ack's bitmap of ACK'd frames, update driver's record of
+ * ACK vs. not.  This gets sent to mac80211, then to rate scaling algo.
+ */
+static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv,
+                                                struct iwl4965_ht_agg *agg,
+                                                struct iwl4965_compressed_ba_resp*
                                                 ba_resp)
 
 {
@@ -4048,16 +4227,20 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
                IWL_ERROR("Received BA when not expected\n");
                return -EINVAL;
        }
+
+       /* Mark that the expected block-ack response arrived */
        agg->wait_for_ba = 0;
        IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->ba_seq_ctl);
-       sh = agg->start_idx - SEQ_TO_INDEX(ba_seq_ctl>>4);
-       if (sh < 0) /* tbw something is wrong with indeces */
+
+       /* Calculate shift to align block-ack bits with our Tx window bits */
+       sh = agg->start_idx - SEQ_TO_INDEX(ba_seq_ctl >> 4);
+       if (sh < 0) /* tbw something is wrong with indices */
                sh += 0x100;
 
-       /* don't use 64 bits for now */
+       /* don't use 64-bit values for now */
        bitmap0 = resp_bitmap0 >> sh;
        bitmap1 = resp_bitmap1 >> sh;
-       bitmap0 |= (resp_bitmap1 & ((1<<sh)|((1<<sh)-1))) << (32 - sh);
+       bitmap0 |= (resp_bitmap1 & ((1 << sh) | ((1 << sh) - 1))) << (32 - sh);
 
        if (agg->frame_count > (64 - sh)) {
                IWL_DEBUG_TX_REPLY("more frames than bitmap size");
@@ -4065,10 +4248,12 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
        }
 
        /* check for success or failure according to the
-        * transmitted bitmap and back bitmap */
+        * transmitted bitmap and block-ack bitmap */
        bitmap0 &= agg->bitmap0;
        bitmap1 &= agg->bitmap1;
 
+       /* For each frame attempted in aggregation,
+        * update driver's record of tx frame's status. */
        for (i = 0; i < agg->frame_count ; i++) {
                int idx = (agg->start_idx + i) & 0xff;
                ack = bitmap0 & (1 << i);
@@ -4084,20 +4269,36 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
        return 0;
 }
 
-static inline int iwl_queue_dec_wrap(int index, int n_bd)
+/**
+ * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (s/b power of 2)
+ */
+static inline int iwl4965_queue_dec_wrap(int index, int n_bd)
 {
        return (index == 0) ? n_bd - 1 : index - 1;
 }
 
-static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                          struct iwl_rx_mem_buffer *rxb)
+/**
+ * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
+ *
+ * Handles block-acknowledge notification from device, which reports success
+ * of frames sent via aggregation.
+ */
+static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv,
+                                          struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
        int index;
-       struct iwl_tx_queue *txq = NULL;
-       struct iwl_ht_agg *agg;
+       struct iwl4965_tx_queue *txq = NULL;
+       struct iwl4965_ht_agg *agg;
+
+       /* "flow" corresponds to Tx queue */
        u16 ba_resp_scd_flow = le16_to_cpu(ba_resp->scd_flow);
+
+       /* "ssn" is start of block-ack Tx window, corresponds to index
+        * (in Tx queue's circular buffer) of first TFD/frame in window */
        u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 
        if (ba_resp_scd_flow >= ARRAY_SIZE(priv->txq)) {
@@ -4107,9 +4308,11 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
 
        txq = &priv->txq[ba_resp_scd_flow];
        agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg;
-       index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
 
-       /* TODO: Need to get this copy more sefely - now good for debug */
+       /* Find index just before block-ack window */
+       index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
+
+       /* TODO: Need to get this copy more safely - now good for debug */
 /*
        {
        DECLARE_MAC_BUF(mac);
@@ -4132,23 +4335,36 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
                           agg->bitmap0);
        }
 */
+
+       /* Update driver's record of ACK vs. not for each frame in window */
        iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp);
-       /* releases all the TFDs until the SSN */
-       if (txq->q.last_used != (ba_resp_scd_ssn & 0xff))
-               iwl_tx_queue_reclaim(priv, ba_resp_scd_flow, index);
+
+       /* Release all TFDs before the SSN, i.e. all TFDs in front of
+        * block-ack window (we assume that they've been successfully
+        * transmitted ... if not, it's too late anyway). */
+       if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff))
+               iwl4965_tx_queue_reclaim(priv, ba_resp_scd_flow, index);
 
 }
 
 
-static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
+/**
+ * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration
+ */
+static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, u16 txq_id)
 {
-       iwl_write_restricted_reg(priv,
-               SCD_QUEUE_STATUS_BITS(txq_id),
+       /* Simply stop the queue, but don't change any configuration;
+        * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
+       iwl4965_write_prph(priv,
+               KDR_SCD_QUEUE_STATUS_BITS(txq_id),
                (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
                (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
 }
 
-static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
+/**
+ * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue
+ */
+static int iwl4965_tx_queue_set_q2ratid(struct iwl4965_priv *priv, u16 ra_tid,
                                        u16 txq_id)
 {
        u32 tbl_dw_addr;
@@ -4160,22 +4376,25 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
        tbl_dw_addr = priv->scd_base_addr +
                        SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
 
-       tbl_dw = iwl_read_restricted_mem(priv, tbl_dw_addr);
+       tbl_dw = iwl4965_read_targ_mem(priv, tbl_dw_addr);
 
        if (txq_id & 0x1)
                tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
        else
                tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
 
-       iwl_write_restricted_mem(priv, tbl_dw_addr, tbl_dw);
+       iwl4965_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
 
        return 0;
 }
 
 /**
- * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
+ * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue
+ *
+ * NOTE:  txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID,
+ *        i.e. it must be one of the higher queues used for aggregation
  */
-static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
+static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id,
                                       int tx_fifo, int sta_id, int tid,
                                       u16 ssn_idx)
 {
@@ -4189,43 +4408,48 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
 
        ra_tid = BUILD_RAxTID(sta_id, tid);
 
-       iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
+       /* Modify device's station table to Tx this TID */
+       iwl4965_sta_modify_enable_tid_tx(priv, sta_id, tid);
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
        }
 
+       /* Stop this Tx queue before configuring it */
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
 
+       /* Map receiver-address / traffic-ID to this queue */
        iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
 
+       /* Set this queue as a chain-building queue */
+       iwl4965_set_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id));
 
-       iwl_set_bits_restricted_reg(priv, SCD_QUEUECHAIN_SEL, (1<<txq_id));
-
-       priv->txq[txq_id].q.last_used = (ssn_idx & 0xff);
-       priv->txq[txq_id].q.first_empty = (ssn_idx & 0xff);
-
-       /* supposes that ssn_idx is valid (!= 0xFFF) */
+       /* Place first TFD at index corresponding to start sequence number.
+        * Assumes that ssn_idx is valid (!= 0xFFF) */
+       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
        iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
 
-       iwl_write_restricted_mem(priv,
+       /* Set up Tx window size and frame limit for this queue */
+       iwl4965_write_targ_mem(priv,
                        priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id),
                        (SCD_WIN_SIZE << SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
                        SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
 
-       iwl_write_restricted_mem(priv, priv->scd_base_addr +
+       iwl4965_write_targ_mem(priv, priv->scd_base_addr +
                        SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
                        (SCD_FRAME_LIMIT << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
                        & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
 
-       iwl_set_bits_restricted_reg(priv, SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl4965_set_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << 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_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -4234,7 +4458,7 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id,
 /**
  * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
  */
-static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
+static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
                                        u16 ssn_idx, u8 tx_fifo)
 {
        unsigned long flags;
@@ -4247,7 +4471,7 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                spin_unlock_irqrestore(&priv->lock, flags);
                return rc;
@@ -4255,56 +4479,50 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id,
 
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
 
-       iwl_clear_bits_restricted_reg(priv, SCD_QUEUECHAIN_SEL, (1 << txq_id));
+       iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id));
 
-       priv->txq[txq_id].q.last_used = (ssn_idx & 0xff);
-       priv->txq[txq_id].q.first_empty = (ssn_idx & 0xff);
+       priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+       priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
        /* supposes that ssn_idx is valid (!= 0xFFF) */
        iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
 
-       iwl_clear_bits_restricted_reg(priv, SCD_INTERRUPT_MASK, (1 << txq_id));
+       iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id));
        iwl4965_txq_ctx_deactivate(priv, txq_id);
        iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
 
-#endif/* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
-/*
- * RATE SCALE CODE
- */
-int iwl4965_init_hw_rates(struct iwl_priv *priv, struct ieee80211_rate *rates)
-{
-       return 0;
-}
-
+#endif/* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
 /**
  * iwl4965_add_station - Initialize a station's hardware rate table
  *
- * The uCode contains a table of fallback rates and retries per rate
+ * The uCode's station table contains a table of fallback rates
  * for automatic fallback during transmission.
  *
- * NOTE: This initializes the table for a single retry per data rate
- * which is not optimal.  Setting up an intelligent retry per rate
- * requires feedback from transmission, which isn't exposed through
- * rc80211_simple which is what this driver is currently using.
+ * NOTE: This sets up a default set of values.  These will be replaced later
+ *       if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
+ *       rc80211_simple.
  *
+ * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
+ *       calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
+ *       which requires station table entry to exist).
  */
-void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)
 {
        int i, r;
-       struct iwl_link_quality_cmd link_cmd = {
+       struct iwl4965_link_quality_cmd link_cmd = {
                .reserved1 = 0,
        };
        u16 rate_flags;
 
-       /* Set up the rate scaling to start at 54M and fallback
-        * all the way to 1M in IEEE order and then spin on IEEE */
+       /* Set up the rate scaling to start at selected rate, fall back
+        * all the way down to 1M in IEEE order, and then spin on 1M */
        if (is_ap)
                r = IWL_RATE_54M_INDEX;
        else if (priv->phymode == MODE_IEEE80211A)
@@ -4317,11 +4535,13 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
                if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
                        rate_flags |= RATE_MCS_CCK_MSK;
 
+               /* Use Tx antenna B only */
                rate_flags |= RATE_MCS_ANT_B_MSK;
                rate_flags &= ~RATE_MCS_ANT_A_MSK;
+
                link_cmd.rs_table[i].rate_n_flags =
-                       iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
-               r = iwl_get_prev_ieee_rate(r);
+                       iwl4965_hw_set_rate_n_flags(iwl4965_rates[r].plcp, rate_flags);
+               r = iwl4965_get_prev_ieee_rate(r);
        }
 
        link_cmd.general_params.single_stream_ant_msk = 2;
@@ -4332,18 +4552,18 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
        /* Update the rate scaling for control frame Tx to AP */
        link_cmd.sta_id = is_ap ? IWL_AP_ID : IWL4965_BROADCAST_ID;
 
-       iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
+       iwl4965_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
                         &link_cmd);
 }
 
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
 
-static u8 iwl_is_channel_extension(struct iwl_priv *priv, int phymode,
+static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, int phymode,
                                   u16 channel, u8 extension_chan_offset)
 {
-       const struct iwl_channel_info *ch_info;
+       const struct iwl4965_channel_info *ch_info;
 
-       ch_info = iwl_get_channel_info(priv, phymode, channel);
+       ch_info = iwl4965_get_channel_info(priv, phymode, channel);
        if (!is_channel_valid(ch_info))
                return 0;
 
@@ -4357,36 +4577,37 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, int phymode,
        return 0;
 }
 
-static u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
-                               const struct sta_ht_info *ht_info)
+static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv,
+                               struct ieee80211_ht_info *sta_ht_inf)
 {
+       struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
 
-       if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ)
+       if ((!iwl_ht_conf->is_ht) ||
+          (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
+          (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO))
                return 0;
 
-       if (ht_info->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ)
-               return 0;
-
-       if (ht_info->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO)
-               return 0;
+       if (sta_ht_inf) {
+               if ((!sta_ht_inf->ht_supported) ||
+                  (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))
+                       return 0;
+       }
 
-       /* no fat tx allowed on 2.4GHZ */
-       if (priv->phymode != MODE_IEEE80211A)
-               return 0;
-       return (iwl_is_channel_extension(priv, priv->phymode,
-                                        ht_info->control_channel,
-                                        ht_info->extension_chan_offset));
+       return (iwl4965_is_channel_extension(priv, priv->phymode,
+                                        iwl_ht_conf->control_channel,
+                                        iwl_ht_conf->extension_chan_offset));
 }
 
-void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info)
+void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info)
 {
-       struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+       struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon;
        u32 val;
 
        if (!ht_info->is_ht)
                return;
 
-       if (iwl_is_fat_tx_allowed(priv, ht_info))
+       /* Set up channel bandwidth:  20 MHz only, or 20/40 mixed if fat ok */
+       if (iwl4965_is_fat_tx_allowed(priv, NULL))
                rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK;
        else
                rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
@@ -4400,7 +4621,7 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info)
                return;
        }
 
-       /* Note: control channel is oposit to extension channel */
+       /* Note: control channel is opposite of extension channel */
        switch (ht_info->extension_chan_offset) {
        case IWL_EXT_CHANNEL_OFFSET_ABOVE:
                rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
@@ -4416,66 +4637,56 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info)
                break;
        }
 
-       val = ht_info->operating_mode;
+       val = ht_info->ht_protection;
 
        rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
 
-       priv->active_rate_ht[0] = ht_info->supp_rates[0];
-       priv->active_rate_ht[1] = ht_info->supp_rates[1];
        iwl4965_set_rxon_chain(priv);
 
        IWL_DEBUG_ASSOC("supported HT rate 0x%X %X "
                        "rxon flags 0x%X operation mode :0x%X "
                        "extension channel offset 0x%x "
                        "control chan %d\n",
-                       priv->active_rate_ht[0], priv->active_rate_ht[1],
-                       le32_to_cpu(rxon->flags), ht_info->operating_mode,
+                       ht_info->supp_mcs_set[0], ht_info->supp_mcs_set[1],
+                       le32_to_cpu(rxon->flags), ht_info->ht_protection,
                        ht_info->extension_chan_offset,
                        ht_info->control_channel);
        return;
 }
 
-void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index)
+void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index,
+                               struct ieee80211_ht_info *sta_ht_inf)
 {
        __le32 sta_flags;
-       struct sta_ht_info *ht_info = &priv->current_assoc_ht;
 
-       priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ;
-       if (!ht_info->is_ht)
+       if (!sta_ht_inf || !sta_ht_inf->ht_supported)
                goto done;
 
        sta_flags = priv->stations[index].sta.station_flags;
 
-       if (ht_info->tx_mimo_ps_mode == IWL_MIMO_PS_DYNAMIC)
+       if (((sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS >> 2))
+                                               == IWL_MIMO_PS_DYNAMIC)
                sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
        else
                sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK;
 
        sta_flags |= cpu_to_le32(
-               (u32)ht_info->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
+             (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
 
        sta_flags |= cpu_to_le32(
-               (u32)ht_info->mpdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
-
-       sta_flags &= (~STA_FLG_FAT_EN_MSK);
-       ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
-       ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_20MHZ;
+             (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
-       if (iwl_is_fat_tx_allowed(priv, ht_info)) {
+       if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf))
                sta_flags |= STA_FLG_FAT_EN_MSK;
-               ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_40MHZ;
-               if (ht_info->supported_chan_width == IWL_CHANNEL_WIDTH_40MHZ)
-                       ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_40MHZ;
-       }
-       priv->current_channel_width = ht_info->tx_chan_width;
+       else
+               sta_flags &= (~STA_FLG_FAT_EN_MSK);
+
        priv->stations[index].sta.station_flags = sta_flags;
  done:
        return;
 }
 
-#ifdef CONFIG_IWLWIFI_HT_AGG
-
-static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv,
+static void iwl4965_sta_modify_add_ba_tid(struct iwl4965_priv *priv,
                                          int sta_id, int tid, u16 ssn)
 {
        unsigned long flags;
@@ -4488,10 +4699,10 @@ static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv,
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 }
 
-static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv,
+static void iwl4965_sta_modify_del_ba_tid(struct iwl4965_priv *priv,
                                          int sta_id, int tid)
 {
        unsigned long flags;
@@ -4503,9 +4714,39 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv,
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+}
+
+int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
+                            enum ieee80211_ampdu_mlme_action action,
+                            const u8 *addr, u16 tid, u16 ssn)
+{
+       struct iwl4965_priv *priv = hw->priv;
+       int sta_id;
+       DECLARE_MAC_BUF(mac);
+
+       IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ",
+                       print_mac(mac, addr), tid);
+       sta_id = iwl4965_hw_find_station(priv, addr);
+       switch (action) {
+       case IEEE80211_AMPDU_RX_START:
+               IWL_DEBUG_HT("start Rx\n");
+               iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, ssn);
+               break;
+       case IEEE80211_AMPDU_RX_STOP:
+               IWL_DEBUG_HT("stop Rx\n");
+               iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid);
+               break;
+       default:
+               IWL_DEBUG_HT("unknown\n");
+               return -EINVAL;
+               break;
+       }
+       return 0;
 }
 
+#ifdef CONFIG_IWL4965_HT_AGG
+
 static const u16 default_tid_to_tx_fifo[] = {
        IWL_TX_FIFO_AC1,
        IWL_TX_FIFO_AC0,
@@ -4526,7 +4767,13 @@ static const u16 default_tid_to_tx_fifo[] = {
        IWL_TX_FIFO_AC3
 };
 
-static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
+/*
+ * Find first available (lowest unused) Tx Queue, mark it "active".
+ * Called only when finding queue for aggregation.
+ * Should never return anything < 7, because they should already
+ * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6).
+ */
+static int iwl4965_txq_ctx_activate_free(struct iwl4965_priv *priv)
 {
        int txq_id;
 
@@ -4536,55 +4783,65 @@ static int iwl_txq_ctx_activate_free(struct iwl_priv *priv)
        return -1;
 }
 
-int iwl_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid,
+int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid,
                            u16 *start_seq_num)
 {
 
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        int sta_id;
        int tx_fifo;
        int txq_id;
        int ssn = -1;
        unsigned long flags;
-       struct iwl_tid_data *tid_data;
+       struct iwl4965_tid_data *tid_data;
        DECLARE_MAC_BUF(mac);
 
+       /* Determine Tx DMA/FIFO channel for this Traffic ID */
        if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
                tx_fifo = default_tid_to_tx_fifo[tid];
        else
                return -EINVAL;
 
-       IWL_WARNING("iwl-AGG iwl_mac_ht_tx_agg_start on da=%s"
+       IWL_WARNING("iwl-AGG iwl4965_mac_ht_tx_agg_start on da=%s"
                    " tid=%d\n", print_mac(mac, da), tid);
 
-       sta_id = iwl_hw_find_station(priv, da);
+       /* Get index into station table */
+       sta_id = iwl4965_hw_find_station(priv, da);
        if (sta_id == IWL_INVALID_STATION)
                return -ENXIO;
 
-       txq_id = iwl_txq_ctx_activate_free(priv);
+       /* Find available Tx queue for aggregation */
+       txq_id = iwl4965_txq_ctx_activate_free(priv);
        if (txq_id == -1)
                return -ENXIO;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
        tid_data = &priv->stations[sta_id].tid[tid];
+
+       /* Get starting sequence number for 1st frame in block ack window.
+        * We'll use least signif byte as 1st frame's index into Tx queue. */
        ssn = SEQ_TO_SN(tid_data->seq_number);
        tid_data->agg.txq_id = txq_id;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
        *start_seq_num = ssn;
+
+       /* Update driver's link quality manager */
        iwl4965_ba_status(priv, tid, BA_STATUS_ACTIVE);
+
+       /* Set up and enable aggregation for selected Tx queue and FIFO */
        return iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo,
                                           sta_id, tid, ssn);
 }
 
 
-int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid,
+int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid,
                           int generator)
 {
 
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        int tx_fifo_id, txq_id, sta_id, ssn = -1;
-       struct iwl_tid_data *tid_data;
+       struct iwl4965_tid_data *tid_data;
        int rc;
        DECLARE_MAC_BUF(mac);
 
@@ -4598,7 +4855,7 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid,
        else
                return -EINVAL;
 
-       sta_id = iwl_hw_find_station(priv, da);
+       sta_id = iwl4965_hw_find_station(priv, da);
 
        if (sta_id == IWL_INVALID_STATION)
                return -ENXIO;
@@ -4613,45 +4870,18 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid,
                return rc;
 
        iwl4965_ba_status(priv, tid, BA_STATUS_INITIATOR_DELBA);
-       IWL_DEBUG_INFO("iwl_mac_ht_tx_agg_stop on da=%s tid=%d\n",
+       IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n",
                       print_mac(mac, da), tid);
 
        return 0;
 }
 
-int iwl_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da,
-                           u16 tid, u16 start_seq_num)
-{
-       struct iwl_priv *priv = hw->priv;
-       int sta_id;
-       DECLARE_MAC_BUF(mac);
 
-       IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_start on da=%s"
-                   " tid=%d\n", print_mac(mac, da), tid);
-       sta_id = iwl_hw_find_station(priv, da);
-       iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, start_seq_num);
-       return 0;
-}
-
-int iwl_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da,
-                          u16 tid, int generator)
-{
-       struct iwl_priv *priv = hw->priv;
-       int sta_id;
-       DECLARE_MAC_BUF(mac);
-
-       IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_stop on da=%s tid=%d\n",
-                   print_mac(mac, da), tid);
-       sta_id = iwl_hw_find_station(priv, da);
-       iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid);
-       return 0;
-}
-
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
 /* Set up 4965-specific Rx frame reply handlers */
-void iwl_hw_rx_handler_setup(struct iwl_priv *priv)
+void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv)
 {
        /* Legacy Rx frames */
        priv->rx_handlers[REPLY_4965_RX] = iwl4965_rx_reply_rx;
@@ -4663,57 +4893,66 @@ void iwl_hw_rx_handler_setup(struct iwl_priv *priv)
        priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
            iwl4965_rx_missed_beacon_notif;
 
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
-#endif /* CONFIG_IWLWIFI_AGG */
-#endif /* CONFIG_IWLWIFI */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 }
 
-void iwl_hw_setup_deferred_work(struct iwl_priv *priv)
+void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv)
 {
        INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
        INIT_WORK(&priv->statistics_work, iwl4965_bg_statistics_work);
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
        INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work);
 #endif
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        INIT_WORK(&priv->agg_work, iwl4965_bg_agg_work);
-#endif /* CONFIG_IWLWIFI_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
        init_timer(&priv->statistics_periodic);
        priv->statistics_periodic.data = (unsigned long)priv;
        priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
 }
 
-void iwl_hw_cancel_deferred_work(struct iwl_priv *priv)
+void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv)
 {
        del_timer_sync(&priv->statistics_periodic);
 
        cancel_delayed_work(&priv->init_alive_start);
 }
 
-struct pci_device_id iwl_hw_card_ids[] = {
-       {0x8086, 0x4229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       {0x8086, 0x4230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+struct pci_device_id iwl4965_hw_card_ids[] = {
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4229)},
+       {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4230)},
        {0}
 };
 
-int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv)
+/*
+ * 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
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv)
 {
        u16 count;
        int rc;
 
        for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
-               iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               /* Request semaphore */
+               iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG,
                        CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-               rc = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+
+               /* See if we got it */
+               rc = iwl4965_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
                                        CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
                                        CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
                                        EEPROM_SEM_TIMEOUT);
                if (rc >= 0) {
-                       IWL_DEBUG_IO("Aqcuired semaphore after %d tries.\n",
+                       IWL_DEBUG_IO("Acquired semaphore after %d tries.\n",
                                count+1);
                        return rc;
                }
@@ -4722,11 +4961,11 @@ int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv)
        return rc;
 }
 
-inline void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
 {
-       iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+       iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
                CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
 }
 
 
-MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
+MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids);
index 4c700812b45beae031e4f317e46668a56eb4c550..78bc148c9f7f4c9cc1566790c52ce25f742ae573 100644 (file)
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
+/*
+ * Please use this file (iwl-4965.h) for driver implementation definitions.
+ * Please use iwl-4965-commands.h for uCode API definitions.
+ * Please use iwl-4965-hw.h for hardware-related definitions.
+ */
+
 #ifndef __iwl_4965_h__
 #define __iwl_4965_h__
 
-struct iwl_priv;
-struct sta_ht_info;
+#include <linux/pci.h> /* for struct pci_device_id */
+#include <linux/kernel.h>
+#include <net/ieee80211_radiotap.h>
+
+/* Hardware specific file defines the PCI IDs table for that hardware module */
+extern struct pci_device_id iwl4965_hw_card_ids[];
+
+#define DRV_NAME        "iwl4965"
+#include "iwl-4965-hw.h"
+#include "iwl-prph.h"
+#include "iwl-4965-debug.h"
+
+/* Default noise level to report when noise measurement is not available.
+ *   This may be because we're:
+ *   1)  Not associated (4965, no beacon statistics being sent to driver)
+ *   2)  Scanning (noise measurement does not apply to associated channel)
+ *   3)  Receiving CCK (3945 delivers noise info only for OFDM frames)
+ * Use default noise value of -127 ... this is below the range of measurable
+ *   Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user.
+ *   Also, -127 works better than 0 when averaging frames with/without
+ *   noise info (e.g. averaging might be done in app); measured dBm values are
+ *   always negative ... using a negative value as the default keeps all
+ *   averages within an s8's (used in some apps) range of negative values. */
+#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
+
+/* Module parameters accessible from iwl-*.c */
+extern int iwl4965_param_hwcrypto;
+extern int iwl4965_param_queues_num;
+extern int iwl4965_param_amsdu_size_8K;
+
+enum iwl4965_antenna {
+       IWL_ANTENNA_DIVERSITY,
+       IWL_ANTENNA_MAIN,
+       IWL_ANTENNA_AUX
+};
+
+/*
+ * RTS threshold here is total size [2347] minus 4 FCS bytes
+ * Per spec:
+ *   a value of 0 means RTS on all data/management packets
+ *   a value > max MSDU size means no RTS
+ * else RTS for data/management frames where MPDU is larger
+ *   than RTS value.
+ */
+#define DEFAULT_RTS_THRESHOLD     2347U
+#define MIN_RTS_THRESHOLD         0U
+#define MAX_RTS_THRESHOLD         2347U
+#define MAX_MSDU_SIZE            2304U
+#define MAX_MPDU_SIZE            2346U
+#define DEFAULT_BEACON_INTERVAL   100U
+#define        DEFAULT_SHORT_RETRY_LIMIT 7U
+#define        DEFAULT_LONG_RETRY_LIMIT  4U
+
+struct iwl4965_rx_mem_buffer {
+       dma_addr_t dma_addr;
+       struct sk_buff *skb;
+       struct list_head list;
+};
+
+/*
+ * Generic queue structure
+ *
+ * Contains common data for Rx and Tx queues
+ */
+struct iwl4965_queue {
+       int n_bd;              /* number of BDs in this queue */
+       int write_ptr;       /* 1-st empty entry (index) host_w*/
+       int read_ptr;         /* last used entry (index) host_r*/
+       dma_addr_t dma_addr;   /* physical addr for BD's */
+       int n_window;          /* safe queue window */
+       u32 id;
+       int low_mark;          /* low watermark, resume queue if free
+                               * space more than this */
+       int high_mark;         /* high watermark, stop queue if free
+                               * space less than this */
+} __attribute__ ((packed));
+
+#define MAX_NUM_OF_TBS          (20)
+
+/* One for each TFD */
+struct iwl4965_tx_info {
+       struct ieee80211_tx_status status;
+       struct sk_buff *skb[MAX_NUM_OF_TBS];
+};
+
+/**
+ * struct iwl4965_tx_queue - Tx Queue for DMA
+ * @q: generic Rx/Tx queue descriptor
+ * @bd: base of circular buffer of TFDs
+ * @cmd: array of command/Tx buffers
+ * @dma_addr_cmd: physical address of cmd/tx buffer array
+ * @txb: array of per-TFD driver data
+ * @need_update: indicates need to update read/write index
+ * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
+ *
+ * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
+ * descriptors) and required locking structures.
+ */
+struct iwl4965_tx_queue {
+       struct iwl4965_queue q;
+       struct iwl4965_tfd_frame *bd;
+       struct iwl4965_cmd *cmd;
+       dma_addr_t dma_addr_cmd;
+       struct iwl4965_tx_info *txb;
+       int need_update;
+       int sched_retry;
+       int active;
+};
+
+#define IWL_NUM_SCAN_RATES         (2)
+
+struct iwl4965_channel_tgd_info {
+       u8 type;
+       s8 max_power;
+};
+
+struct iwl4965_channel_tgh_info {
+       s64 last_radar_time;
+};
+
+/* current Tx power values to use, one for each rate for each channel.
+ * requested power is limited by:
+ * -- regulatory EEPROM limits for this channel
+ * -- hardware capabilities (clip-powers)
+ * -- spectrum management
+ * -- user preference (e.g. iwconfig)
+ * when requested power is set, base power index must also be set. */
+struct iwl4965_channel_power_info {
+       struct iwl4965_tx_power tpc;    /* actual radio and DSP gain settings */
+       s8 power_table_index;   /* actual (compenst'd) index into gain table */
+       s8 base_power_index;    /* gain index for power at factory temp. */
+       s8 requested_power;     /* power (dBm) requested for this chnl/rate */
+};
+
+/* current scan Tx power values to use, one for each scan rate for each
+ * channel. */
+struct iwl4965_scan_power_info {
+       struct iwl4965_tx_power tpc;    /* actual radio and DSP gain settings */
+       s8 power_table_index;   /* actual (compenst'd) index into gain table */
+       s8 requested_power;     /* scan pwr (dBm) requested for chnl/rate */
+};
+
+/* For fat_extension_channel */
+enum {
+       HT_IE_EXT_CHANNEL_NONE = 0,
+       HT_IE_EXT_CHANNEL_ABOVE,
+       HT_IE_EXT_CHANNEL_INVALID,
+       HT_IE_EXT_CHANNEL_BELOW,
+       HT_IE_EXT_CHANNEL_MAX
+};
+
+/*
+ * One for each channel, holds all channel setup data
+ * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
+ *     with one another!
+ */
+#define IWL4965_MAX_RATE (33)
+
+struct iwl4965_channel_info {
+       struct iwl4965_channel_tgd_info tgd;
+       struct iwl4965_channel_tgh_info tgh;
+       struct iwl4965_eeprom_channel eeprom;     /* EEPROM regulatory limit */
+       struct iwl4965_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
+                                                  * FAT channel */
+
+       u8 channel;       /* channel number */
+       u8 flags;         /* flags copied from EEPROM */
+       s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
+       s8 curr_txpow;    /* (dBm) regulatory/spectrum/user (not h/w) limit */
+       s8 min_power;     /* always 0 */
+       s8 scan_power;    /* (dBm) regul. eeprom, direct scans, any rate */
+
+       u8 group_index;   /* 0-4, maps channel to group1/2/3/4/5 */
+       u8 band_index;    /* 0-4, maps channel to band1/2/3/4/5 */
+       u8 phymode;       /* MODE_IEEE80211{A,B,G} */
+
+       /* Radio/DSP gain settings for each "normal" data Tx rate.
+        * These include, in addition to RF and DSP gain, a few fields for
+        *   remembering/modifying gain settings (indexes). */
+       struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE];
+
+       /* FAT channel info */
+       s8 fat_max_power_avg;   /* (dBm) regul. eeprom, normal Tx, any rate */
+       s8 fat_curr_txpow;      /* (dBm) regulatory/spectrum/user (not h/w) */
+       s8 fat_min_power;       /* always 0 */
+       s8 fat_scan_power;      /* (dBm) eeprom, direct scans, any rate */
+       u8 fat_flags;           /* flags copied from EEPROM */
+       u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
+
+       /* Radio/DSP gain settings for each scan rate, for directed scans. */
+       struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
+};
+
+struct iwl4965_clip_group {
+       /* maximum power level to prevent clipping for each rate, derived by
+        *   us from this band's saturation power in EEPROM */
+       const s8 clip_powers[IWL_MAX_RATES];
+};
+
+#include "iwl-4965-rs.h"
+
+#define IWL_TX_FIFO_AC0        0
+#define IWL_TX_FIFO_AC1        1
+#define IWL_TX_FIFO_AC2        2
+#define IWL_TX_FIFO_AC3        3
+#define IWL_TX_FIFO_HCCA_1     5
+#define IWL_TX_FIFO_HCCA_2     6
+#define IWL_TX_FIFO_NONE       7
+
+/* Minimum number of queues. MAX_NUM is defined in hw specific files */
+#define IWL_MIN_NUM_QUEUES     4
+
+/* Power management (not Tx power) structures */
+
+struct iwl4965_power_vec_entry {
+       struct iwl4965_powertable_cmd cmd;
+       u8 no_dtim;
+};
+#define IWL_POWER_RANGE_0  (0)
+#define IWL_POWER_RANGE_1  (1)
+
+#define IWL_POWER_MODE_CAM     0x00    /* Continuously Aware Mode, always on */
+#define IWL_POWER_INDEX_3      0x03
+#define IWL_POWER_INDEX_5      0x05
+#define IWL_POWER_AC           0x06
+#define IWL_POWER_BATTERY      0x07
+#define IWL_POWER_LIMIT                0x07
+#define IWL_POWER_MASK         0x0F
+#define IWL_POWER_ENABLED      0x10
+#define IWL_POWER_LEVEL(x)     ((x) & IWL_POWER_MASK)
+
+struct iwl4965_power_mgr {
+       spinlock_t lock;
+       struct iwl4965_power_vec_entry pwr_range_0[IWL_POWER_AC];
+       struct iwl4965_power_vec_entry pwr_range_1[IWL_POWER_AC];
+       u8 active_index;
+       u32 dtim_val;
+};
+
+#define IEEE80211_DATA_LEN              2304
+#define IEEE80211_4ADDR_LEN             30
+#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+struct iwl4965_frame {
+       union {
+               struct ieee80211_hdr frame;
+               struct iwl4965_tx_beacon_cmd beacon;
+               u8 raw[IEEE80211_FRAME_LEN];
+               u8 cmd[360];
+       } u;
+       struct list_head list;
+};
+
+#define SEQ_TO_QUEUE(x)  ((x >> 8) & 0xbf)
+#define QUEUE_TO_SEQ(x)  ((x & 0xbf) << 8)
+#define SEQ_TO_INDEX(x) (x & 0xff)
+#define INDEX_TO_SEQ(x) (x & 0xff)
+#define SEQ_HUGE_FRAME  (0x4000)
+#define SEQ_RX_FRAME    __constant_cpu_to_le16(0x8000)
+#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
+#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
+#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
+
+enum {
+       /* CMD_SIZE_NORMAL = 0, */
+       CMD_SIZE_HUGE = (1 << 0),
+       /* CMD_SYNC = 0, */
+       CMD_ASYNC = (1 << 1),
+       /* CMD_NO_SKB = 0, */
+       CMD_WANT_SKB = (1 << 2),
+};
+
+struct iwl4965_cmd;
+struct iwl4965_priv;
+
+struct iwl4965_cmd_meta {
+       struct iwl4965_cmd_meta *source;
+       union {
+               struct sk_buff *skb;
+               int (*callback)(struct iwl4965_priv *priv,
+                               struct iwl4965_cmd *cmd, struct sk_buff *skb);
+       } __attribute__ ((packed)) u;
+
+       /* The CMD_SIZE_HUGE flag bit indicates that the command
+        * structure is stored at the end of the shared queue memory. */
+       u32 flags;
+
+} __attribute__ ((packed));
+
+/**
+ * struct iwl4965_cmd
+ *
+ * For allocation of the command and tx queues, this establishes the overall
+ * size of the largest command we send to uCode, except for a scan command
+ * (which is relatively huge; space is allocated separately).
+ */
+struct iwl4965_cmd {
+       struct iwl4965_cmd_meta meta;   /* driver data */
+       struct iwl4965_cmd_header hdr;  /* uCode API */
+       union {
+               struct iwl4965_addsta_cmd addsta;
+               struct iwl4965_led_cmd led;
+               u32 flags;
+               u8 val8;
+               u16 val16;
+               u32 val32;
+               struct iwl4965_bt_cmd bt;
+               struct iwl4965_rxon_time_cmd rxon_time;
+               struct iwl4965_powertable_cmd powertable;
+               struct iwl4965_qosparam_cmd qosparam;
+               struct iwl4965_tx_cmd tx;
+               struct iwl4965_tx_beacon_cmd tx_beacon;
+               struct iwl4965_rxon_assoc_cmd rxon_assoc;
+               u8 *indirect;
+               u8 payload[360];
+       } __attribute__ ((packed)) cmd;
+} __attribute__ ((packed));
+
+struct iwl4965_host_cmd {
+       u8 id;
+       u16 len;
+       struct iwl4965_cmd_meta meta;
+       const void *data;
+};
+
+#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \
+                             sizeof(struct iwl4965_cmd_meta))
+
+/*
+ * RX related structures and functions
+ */
+#define RX_FREE_BUFFERS 64
+#define RX_LOW_WATERMARK 8
+
+#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
+
+/**
+ * struct iwl4965_rx_queue - Rx queue
+ * @processed: Internal index to last handled Rx packet
+ * @read: Shared index to newest available Rx buffer
+ * @write: Shared index to oldest written Rx packet
+ * @free_count: Number of pre-allocated buffers in rx_free
+ * @rx_free: list of free SKBs for use
+ * @rx_used: List of Rx buffers with no SKB
+ * @need_update: flag to indicate we need to update read/write index
+ *
+ * NOTE:  rx_free and rx_used are used as a FIFO for iwl4965_rx_mem_buffers
+ */
+struct iwl4965_rx_queue {
+       __le32 *bd;
+       dma_addr_t dma_addr;
+       struct iwl4965_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
+       struct iwl4965_rx_mem_buffer *queue[RX_QUEUE_SIZE];
+       u32 processed;
+       u32 read;
+       u32 write;
+       u32 free_count;
+       struct list_head rx_free;
+       struct list_head rx_used;
+       int need_update;
+       spinlock_t lock;
+};
+
+#define IWL_SUPPORTED_RATES_IE_LEN         8
+
+#define SCAN_INTERVAL 100
+
+#define MAX_A_CHANNELS  252
+#define MIN_A_CHANNELS  7
+
+#define MAX_B_CHANNELS  14
+#define MIN_B_CHANNELS  1
+
+#define STATUS_HCMD_ACTIVE     0       /* host command in progress */
+#define STATUS_INT_ENABLED     1
+#define STATUS_RF_KILL_HW      2
+#define STATUS_RF_KILL_SW      3
+#define STATUS_INIT            4
+#define STATUS_ALIVE           5
+#define STATUS_READY           6
+#define STATUS_TEMPERATURE     7
+#define STATUS_GEO_CONFIGURED  8
+#define STATUS_EXIT_PENDING    9
+#define STATUS_IN_SUSPEND      10
+#define STATUS_STATISTICS      11
+#define STATUS_SCANNING                12
+#define STATUS_SCAN_ABORTING   13
+#define STATUS_SCAN_HW         14
+#define STATUS_POWER_PMI       15
+#define STATUS_FW_ERROR                16
+#define STATUS_CONF_PENDING    17
+
+#define MAX_TID_COUNT        9
+
+#define IWL_INVALID_RATE     0xFF
+#define IWL_INVALID_VALUE    -1
+
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
+/**
+ * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack
+ * @txq_id: Tx queue used for Tx attempt
+ * @frame_count: # frames attempted by Tx command
+ * @wait_for_ba: Expect block-ack before next Tx reply
+ * @start_idx: Index of 1st Transmit Frame Descriptor (TFD) in Tx window
+ * @bitmap0: Low order bitmap, one bit for each frame pending ACK in Tx window
+ * @bitmap1: High order, one bit for each frame pending ACK in Tx window
+ * @rate_n_flags: Rate at which Tx was attempted
+ *
+ * If REPLY_TX indicates that aggregation was attempted, driver must wait
+ * for block ack (REPLY_COMPRESSED_BA).  This struct stores tx reply info
+ * until block ack arrives.
+ */
+struct iwl4965_ht_agg {
+       u16 txq_id;
+       u16 frame_count;
+       u16 wait_for_ba;
+       u16 start_idx;
+       u32 bitmap0;
+       u32 bitmap1;
+       u32 rate_n_flags;
+};
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
+
+struct iwl4965_tid_data {
+       u16 seq_number;
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
+       struct iwl4965_ht_agg agg;
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
+};
+
+struct iwl4965_hw_key {
+       enum ieee80211_key_alg alg;
+       int keylen;
+       u8 key[32];
+};
+
+union iwl4965_ht_rate_supp {
+       u16 rates;
+       struct {
+               u8 siso_rate;
+               u8 mimo_rate;
+       };
+};
+
+#ifdef CONFIG_IWL4965_HT
+#define CFG_HT_RX_AMPDU_FACTOR_DEF  (0x3)
+#define CFG_HT_MPDU_DENSITY_2USEC   (0x5)
+#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC
+
+struct iwl_ht_info {
+       /* self configuration data */
+       u8 is_ht;
+       u8 supported_chan_width;
+       u16 tx_mimo_ps_mode;
+       u8 is_green_field;
+       u8 sgf;                 /* HT_SHORT_GI_* short guard interval */
+       u8 max_amsdu_size;
+       u8 ampdu_factor;
+       u8 mpdu_density;
+       u8 supp_mcs_set[16];
+       /* BSS related data */
+       u8 control_channel;
+       u8 extension_chan_offset;
+       u8 tx_chan_width;
+       u8 ht_protection;
+       u8 non_GF_STA_present;
+};
+#endif                         /*CONFIG_IWL4965_HT */
+
+#ifdef CONFIG_IWL4965_QOS
+
+union iwl4965_qos_capabity {
+       struct {
+               u8 edca_count:4;        /* bit 0-3 */
+               u8 q_ack:1;             /* bit 4 */
+               u8 queue_request:1;     /* bit 5 */
+               u8 txop_request:1;      /* bit 6 */
+               u8 reserved:1;          /* bit 7 */
+       } q_AP;
+       struct {
+               u8 acvo_APSD:1;         /* bit 0 */
+               u8 acvi_APSD:1;         /* bit 1 */
+               u8 ac_bk_APSD:1;        /* bit 2 */
+               u8 ac_be_APSD:1;        /* bit 3 */
+               u8 q_ack:1;             /* bit 4 */
+               u8 max_len:2;           /* bit 5-6 */
+               u8 more_data_ack:1;     /* bit 7 */
+       } q_STA;
+       u8 val;
+};
+
+/* QoS structures */
+struct iwl4965_qos_info {
+       int qos_enable;
+       int qos_active;
+       union iwl4965_qos_capabity qos_cap;
+       struct iwl4965_qosparam_cmd def_qos_parm;
+};
+#endif /*CONFIG_IWL4965_QOS */
+
+#define STA_PS_STATUS_WAKE             0
+#define STA_PS_STATUS_SLEEP            1
+
+struct iwl4965_station_entry {
+       struct iwl4965_addsta_cmd sta;
+       struct iwl4965_tid_data tid[MAX_TID_COUNT];
+       u8 used;
+       u8 ps_status;
+       struct iwl4965_hw_key keyinfo;
+};
+
+/* one for each uCode image (inst/data, boot/init/runtime) */
+struct fw_desc {
+       void *v_addr;           /* access by driver */
+       dma_addr_t p_addr;      /* access by card's busmaster DMA */
+       u32 len;                /* bytes */
+};
+
+/* uCode file layout */
+struct iwl4965_ucode {
+       __le32 ver;             /* major/minor/subminor */
+       __le32 inst_size;       /* bytes of runtime instructions */
+       __le32 data_size;       /* bytes of runtime data */
+       __le32 init_size;       /* bytes of initialization instructions */
+       __le32 init_data_size;  /* bytes of initialization data */
+       __le32 boot_size;       /* bytes of bootstrap instructions */
+       u8 data[0];             /* data in same order as "size" elements */
+};
+
+#define IWL_IBSS_MAC_HASH_SIZE 32
+
+struct iwl4965_ibss_seq {
+       u8 mac[ETH_ALEN];
+       u16 seq_num;
+       u16 frag_num;
+       unsigned long packet_time;
+       struct list_head list;
+};
+
+/**
+ * struct iwl4965_driver_hw_info
+ * @max_txq_num: Max # Tx queues supported
+ * @ac_queue_count: # Tx queues for EDCA Access Categories (AC)
+ * @tx_cmd_len: Size of Tx command (but not including frame itself)
+ * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
+ * @rx_buffer_size:
+ * @max_rxq_log: Log-base-2 of max_rxq_size
+ * @max_stations:
+ * @bcast_sta_id:
+ * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status
+ * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status
+ */
+struct iwl4965_driver_hw_info {
+       u16 max_txq_num;
+       u16 ac_queue_count;
+       u16 tx_cmd_len;
+       u16 max_rxq_size;
+       u32 rx_buf_size;
+       u32 max_pkt_size;
+       u16 max_rxq_log;
+       u8  max_stations;
+       u8  bcast_sta_id;
+       void *shared_virt;
+       dma_addr_t shared_phys;
+};
+
+#define HT_SHORT_GI_20MHZ_ONLY          (1 << 0)
+#define HT_SHORT_GI_40MHZ_ONLY          (1 << 1)
+
+
+#define IWL_RX_HDR(x) ((struct iwl4965_rx_frame_hdr *)(\
+                      x->u.rx_frame.stats.payload + \
+                      x->u.rx_frame.stats.phy_count))
+#define IWL_RX_END(x) ((struct iwl4965_rx_frame_end *)(\
+                      IWL_RX_HDR(x)->payload + \
+                      le16_to_cpu(IWL_RX_HDR(x)->len)))
+#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
+#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
+
+
+/******************************************************************************
+ *
+ * Functions implemented in iwl-base.c which are forward declared here
+ * for use by iwl-*.c
+ *
+ *****************************************************************************/
+struct iwl4965_addsta_cmd;
+extern int iwl4965_send_add_station(struct iwl4965_priv *priv,
+                               struct iwl4965_addsta_cmd *sta, u8 flags);
+extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr,
+                         int is_ap, u8 flags, void *ht_data);
+extern int iwl4965_is_network_packet(struct iwl4965_priv *priv,
+                                struct ieee80211_hdr *header);
+extern int iwl4965_power_init_handle(struct iwl4965_priv *priv);
+extern int iwl4965_eeprom_init(struct iwl4965_priv *priv);
+#ifdef CONFIG_IWL4965_DEBUG
+extern void iwl4965_report_frame(struct iwl4965_priv *priv,
+                            struct iwl4965_rx_packet *pkt,
+                            struct ieee80211_hdr *header, int group100);
+#else
+static inline void iwl4965_report_frame(struct iwl4965_priv *priv,
+                                   struct iwl4965_rx_packet *pkt,
+                                   struct ieee80211_hdr *header,
+                                   int group100) {}
+#endif
+extern void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv,
+                                          struct iwl4965_rx_mem_buffer *rxb,
+                                          void *data, short len,
+                                          struct ieee80211_rx_status *stats,
+                                          u16 phy_flags);
+extern int iwl4965_is_duplicate_packet(struct iwl4965_priv *priv,
+                                      struct ieee80211_hdr *header);
+extern int iwl4965_rx_queue_alloc(struct iwl4965_priv *priv);
+extern void iwl4965_rx_queue_reset(struct iwl4965_priv *priv,
+                              struct iwl4965_rx_queue *rxq);
+extern int iwl4965_calc_db_from_ratio(int sig_ratio);
+extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
+extern int iwl4965_tx_queue_init(struct iwl4965_priv *priv,
+                            struct iwl4965_tx_queue *txq, int count, u32 id);
+extern void iwl4965_rx_replenish(void *data);
+extern void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq);
+extern int iwl4965_send_cmd_pdu(struct iwl4965_priv *priv, u8 id, u16 len,
+                           const void *data);
+extern int __must_check iwl4965_send_cmd(struct iwl4965_priv *priv,
+               struct iwl4965_host_cmd *cmd);
+extern unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv,
+                                       struct ieee80211_hdr *hdr,
+                                       const u8 *dest, int left);
+extern int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv,
+                                        struct iwl4965_rx_queue *q);
+extern int iwl4965_send_statistics_request(struct iwl4965_priv *priv);
+extern void iwl4965_set_decrypted_flag(struct iwl4965_priv *priv, struct sk_buff *skb,
+                                  u32 decrypt_res,
+                                  struct ieee80211_rx_status *stats);
+extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
+
+extern const u8 iwl4965_broadcast_addr[ETH_ALEN];
+
+/*
+ * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
+ * call this... todo... fix that.
+*/
+extern u8 iwl4965_sync_station(struct iwl4965_priv *priv, int sta_id,
+                          u16 tx_rate, u8 flags);
+
+/******************************************************************************
+ *
+ * Functions implemented in iwl-[34]*.c which are forward declared here
+ * for use by iwl-base.c
+ *
+ * NOTE:  The implementation of these functions are hardware specific
+ * which is why they are in the hardware specific files (vs. iwl-base.c)
+ *
+ * Naming convention --
+ * iwl4965_         <-- Its part of iwlwifi (should be changed to iwl4965_)
+ * iwl4965_hw_      <-- Hardware specific (implemented in iwl-XXXX.c by all HW)
+ * iwlXXXX_     <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
+ * iwl4965_bg_      <-- Called from work queue context
+ * iwl4965_mac_     <-- mac80211 callback
+ *
+ ****************************************************************************/
+extern void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv);
+extern void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv);
+extern void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv);
+extern int iwl4965_hw_rxq_stop(struct iwl4965_priv *priv);
+extern int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv);
+extern int iwl4965_hw_nic_init(struct iwl4965_priv *priv);
+extern int iwl4965_hw_nic_stop_master(struct iwl4965_priv *priv);
+extern void iwl4965_hw_txq_ctx_free(struct iwl4965_priv *priv);
+extern void iwl4965_hw_txq_ctx_stop(struct iwl4965_priv *priv);
+extern int iwl4965_hw_nic_reset(struct iwl4965_priv *priv);
+extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl4965_priv *priv, void *tfd,
+                                       dma_addr_t addr, u16 len);
+extern int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq);
+extern int iwl4965_hw_get_temperature(struct iwl4965_priv *priv);
+extern int iwl4965_hw_tx_queue_init(struct iwl4965_priv *priv,
+                               struct iwl4965_tx_queue *txq);
+extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv,
+                                struct iwl4965_frame *frame, u8 rate);
+extern int iwl4965_hw_get_rx_read(struct iwl4965_priv *priv);
+extern void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv,
+                                    struct iwl4965_cmd *cmd,
+                                    struct ieee80211_tx_control *ctrl,
+                                    struct ieee80211_hdr *hdr,
+                                    int sta_id, int tx_id);
+extern int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv);
+extern int iwl4965_hw_reg_set_txpower(struct iwl4965_priv *priv, s8 power);
+extern void iwl4965_hw_rx_statistics(struct iwl4965_priv *priv,
+                                struct iwl4965_rx_mem_buffer *rxb);
+extern void iwl4965_disable_events(struct iwl4965_priv *priv);
+extern int iwl4965_get_temperature(const struct iwl4965_priv *priv);
+
+/**
+ * iwl4965_hw_find_station - Find station id for a given BSSID
+ * @bssid: MAC address of station ID to find
+ *
+ * NOTE:  This should not be hardware specific but the code has
+ * not yet been merged into a single common layer for managing the
+ * station tables.
+ */
+extern u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *bssid);
+
+extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel);
+extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index);
+
+struct iwl4965_priv;
 
 /*
  * Forward declare iwl-4965.c functions for iwl-base.c
  */
-extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv);
-extern void iwl_eeprom_release_semaphore(struct iwl_priv *priv);
+extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv);
+extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv);
 
-extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
-                                         struct iwl_tx_queue *txq,
+extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv,
+                                         struct iwl4965_tx_queue *txq,
                                          u16 byte_cnt);
-extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr,
+extern void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr,
                                int is_ap);
-extern void iwl4965_set_rxon_ht(struct iwl_priv *priv,
-                               struct sta_ht_info *ht_info);
-
-extern void iwl4965_set_rxon_chain(struct iwl_priv *priv);
-extern int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd,
-                         u8 sta_id, dma_addr_t txcmd_phys,
-                         struct ieee80211_hdr *hdr, u8 hdr_len,
-                         struct ieee80211_tx_control *ctrl, void *sta_in);
-extern int iwl4965_init_hw_rates(struct iwl_priv *priv,
-                                struct ieee80211_rate *rates);
-extern int iwl4965_alive_notify(struct iwl_priv *priv);
-extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
-extern void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index);
-
-extern void iwl4965_chain_noise_reset(struct iwl_priv *priv);
-extern void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags,
+extern void iwl4965_set_rxon_chain(struct iwl4965_priv *priv);
+extern int iwl4965_alive_notify(struct iwl4965_priv *priv);
+extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode);
+extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv);
+extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags,
                                     u8 force);
-extern int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode,
+extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode,
                                u16 channel,
-                               const struct iwl_eeprom_channel *eeprom_ch,
+                               const struct iwl4965_eeprom_channel *eeprom_ch,
                                u8 fat_extension_channel);
-extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
+extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv);
 
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
-extern int iwl_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da,
+#ifdef CONFIG_IWL4965_HT
+extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info,
+                                       int mode);
+extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv,
+                               struct iwl_ht_info *ht_info);
+extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index,
+                               struct ieee80211_ht_info *sta_ht_inf);
+extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
+                                   enum ieee80211_ampdu_mlme_action action,
+                                   const u8 *addr, u16 tid, u16 ssn);
+#ifdef CONFIG_IWL4965_HT_AGG
+extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da,
                                   u16 tid, u16 *start_seq_num);
-extern int iwl_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da,
-                                  u16 tid, u16 start_seq_num);
-extern int iwl_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da,
+extern int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da,
                                  u16 tid, int generator);
-extern int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da,
-                                 u16 tid, int generator);
-extern void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid);
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /*CONFIG_IWLWIFI_HT */
+extern void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid);
+extern void iwl4965_tl_get_stats(struct iwl4965_priv *priv,
+                               struct ieee80211_hdr *hdr);
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /*CONFIG_IWL4965_HT */
 /* Structures, enum, and defines specific to the 4965 */
 
 #define IWL4965_KW_SIZE 0x1000 /*4k */
 
-struct iwl_kw {
+struct iwl4965_kw {
        dma_addr_t dma_addr;
        void *v_addr;
        size_t size;
@@ -120,21 +833,9 @@ struct iwl_kw {
 #define NRG_NUM_PREV_STAT_L     20
 #define NUM_RX_CHAINS           (3)
 
-#define TX_POWER_IWL_ILLEGAL_VDET    -100000
 #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000
-#define TX_POWER_IWL_CLOSED_LOOP_MIN_POWER 18
-#define TX_POWER_IWL_CLOSED_LOOP_MAX_POWER 34
-#define TX_POWER_IWL_VDET_SLOPE_BELOW_NOMINAL 17
-#define TX_POWER_IWL_VDET_SLOPE_ABOVE_NOMINAL 20
-#define TX_POWER_IWL_NOMINAL_POWER            26
-#define TX_POWER_IWL_CLOSED_LOOP_ITERATION_LIMIT 1
-#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V       7
-#define TX_POWER_IWL_DEGREES_PER_VDET_CODE       11
-#define IWL_TX_POWER_MAX_NUM_PA_MEASUREMENTS 1
-#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9)
-#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5)
-
-struct iwl_traffic_load {
+
+struct iwl4965_traffic_load {
        unsigned long time_stamp;
        u32 packet_count[TID_QUEUE_MAX_SIZE];
        u8 queue_count;
@@ -142,8 +843,13 @@ struct iwl_traffic_load {
        u32 total;
 };
 
-#ifdef CONFIG_IWLWIFI_HT_AGG
-struct iwl_agg_control {
+#ifdef CONFIG_IWL4965_HT_AGG
+/**
+ * struct iwl4965_agg_control
+ * @requested_ba: bit map of tids requesting aggregation/block-ack
+ * @granted_ba: bit map of tids granted aggregation/block-ack
+ */
+struct iwl4965_agg_control {
        unsigned long next_retry;
        u32 wait_for_agg_status;
        u32 tid_retry;
@@ -152,13 +858,13 @@ struct iwl_agg_control {
        u8 auto_agg;
        u32 tid_traffic_load_threshold;
        u32 ba_timeout;
-       struct iwl_traffic_load traffic_load[TID_MAX_LOAD_COUNT];
+       struct iwl4965_traffic_load traffic_load[TID_MAX_LOAD_COUNT];
 };
-#endif                         /*CONFIG_IWLWIFI_HT_AGG */
+#endif                         /*CONFIG_IWL4965_HT_AGG */
 
-struct iwl_lq_mngr {
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       struct iwl_agg_control agg_ctrl;
+struct iwl4965_lq_mngr {
+#ifdef CONFIG_IWL4965_HT_AGG
+       struct iwl4965_agg_control agg_ctrl;
 #endif
        spinlock_t lock;
        s32 max_window_size;
@@ -179,22 +885,6 @@ struct iwl_lq_mngr {
 #define CAL_NUM_OF_BEACONS             20
 #define MAXIMUM_ALLOWED_PATHLOSS       15
 
-/* Param table within SENSITIVITY_CMD */
-#define HD_MIN_ENERGY_CCK_DET_INDEX                 (0)
-#define HD_MIN_ENERGY_OFDM_DET_INDEX                (1)
-#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX          (2)
-#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX      (3)
-#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX      (4)
-#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX          (5)
-#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX      (6)
-#define HD_BARKER_CORR_TH_ADD_MIN_INDEX             (7)
-#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX         (8)
-#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX          (9)
-#define HD_OFDM_ENERGY_TH_IN_INDEX                  (10)
-
-#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE  __constant_cpu_to_le16(0)
-#define SENSITIVITY_CMD_CONTROL_WORK_TABLE     __constant_cpu_to_le16(1)
-
 #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3
 
 #define MAX_FA_OFDM  50
@@ -222,8 +912,6 @@ struct iwl_lq_mngr {
 #define AUTO_CORR_STEP_CCK     3
 #define AUTO_CORR_MAX_TH_CCK   160
 
-#define NRG_ALG                0
-#define AUTO_CORR_ALG          1
 #define NRG_DIFF               2
 #define NRG_STEP_CCK           2
 #define NRG_MARGIN             8
@@ -239,24 +927,24 @@ struct iwl_lq_mngr {
 #define IN_BAND_FILTER                 0xFF
 #define MIN_AVERAGE_NOISE_MAX_VALUE    0xFFFFFFFF
 
-enum iwl_false_alarm_state {
+enum iwl4965_false_alarm_state {
        IWL_FA_TOO_MANY = 0,
        IWL_FA_TOO_FEW = 1,
        IWL_FA_GOOD_RANGE = 2,
 };
 
-enum iwl_chain_noise_state {
+enum iwl4965_chain_noise_state {
        IWL_CHAIN_NOISE_ALIVE = 0,  /* must be 0 */
        IWL_CHAIN_NOISE_ACCUMULATE = 1,
        IWL_CHAIN_NOISE_CALIBRATED = 2,
 };
 
-enum iwl_sensitivity_state {
+enum iwl4965_sensitivity_state {
        IWL_SENS_CALIB_ALLOWED = 0,
        IWL_SENS_CALIB_NEED_REINIT = 1,
 };
 
-enum iwl_calib_enabled_state {
+enum iwl4965_calib_enabled_state {
        IWL_CALIB_DISABLED = 0,  /* must be 0 */
        IWL_CALIB_ENABLED = 1,
 };
@@ -271,7 +959,7 @@ struct statistics_general_data {
 };
 
 /* Sensitivity calib data */
-struct iwl_sensitivity_data {
+struct iwl4965_sensitivity_data {
        u32 auto_corr_ofdm;
        u32 auto_corr_ofdm_mrc;
        u32 auto_corr_ofdm_x1;
@@ -300,7 +988,7 @@ struct iwl_sensitivity_data {
 };
 
 /* Chain noise (differential Rx gain) calib data */
-struct iwl_chain_noise_data {
+struct iwl4965_chain_noise_data {
        u8 state;
        u16 beacon_count;
        u32 chain_noise_a;
@@ -314,28 +1002,323 @@ struct iwl_chain_noise_data {
        u8 radio_write;
 };
 
-/* IWL4965 */
-#define RATE_MCS_CODE_MSK 0x7
-#define RATE_MCS_MIMO_POS 3
-#define RATE_MCS_MIMO_MSK 0x8
-#define RATE_MCS_HT_DUP_POS 5
-#define RATE_MCS_HT_DUP_MSK 0x20
-#define RATE_MCS_FLAGS_POS 8
-#define RATE_MCS_HT_POS 8
-#define RATE_MCS_HT_MSK 0x100
-#define RATE_MCS_CCK_POS 9
-#define RATE_MCS_CCK_MSK 0x200
-#define RATE_MCS_GF_POS 10
-#define RATE_MCS_GF_MSK 0x400
-
-#define RATE_MCS_FAT_POS 11
-#define RATE_MCS_FAT_MSK 0x800
-#define RATE_MCS_DUP_POS 12
-#define RATE_MCS_DUP_MSK 0x1000
-#define RATE_MCS_SGI_POS 13
-#define RATE_MCS_SGI_MSK 0x2000
-
-#define        EEPROM_SEM_TIMEOUT 10
-#define EEPROM_SEM_RETRY_LIMIT 1000
-
-#endif                         /* __iwl_4965_h__ */
+#define        EEPROM_SEM_TIMEOUT 10           /* milliseconds */
+#define EEPROM_SEM_RETRY_LIMIT 1000    /* number of attempts (not time) */
+
+
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+
+enum {
+       MEASUREMENT_READY = (1 << 0),
+       MEASUREMENT_ACTIVE = (1 << 1),
+};
+
+#endif
+
+struct iwl4965_priv {
+
+       /* ieee device used by generic ieee processing code */
+       struct ieee80211_hw *hw;
+       struct ieee80211_channel *ieee_channels;
+       struct ieee80211_rate *ieee_rates;
+
+       /* temporary frame storage list */
+       struct list_head free_frames;
+       int frames_count;
+
+       u8 phymode;
+       int alloc_rxb_skb;
+       bool add_radiotap;
+
+       void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv,
+                                      struct iwl4965_rx_mem_buffer *rxb);
+
+       const struct ieee80211_hw_mode *modes;
+
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+       /* spectrum measurement report caching */
+       struct iwl4965_spectrum_notification measure_report;
+       u8 measurement_status;
+#endif
+       /* ucode beacon time */
+       u32 ucode_beacon_time;
+
+       /* we allocate array of iwl4965_channel_info for NIC's valid channels.
+        *    Access via channel # using indirect index array */
+       struct iwl4965_channel_info *channel_info;      /* channel info array */
+       u8 channel_count;       /* # of channels */
+
+       /* each calibration channel group in the EEPROM has a derived
+        * clip setting for each rate. */
+       const struct iwl4965_clip_group clip_groups[5];
+
+       /* thermal calibration */
+       s32 temperature;        /* degrees Kelvin */
+       s32 last_temperature;
+
+       /* Scan related variables */
+       unsigned long last_scan_jiffies;
+       unsigned long next_scan_jiffies;
+       unsigned long scan_start;
+       unsigned long scan_pass_start;
+       unsigned long scan_start_tsf;
+       int scan_bands;
+       int one_direct_scan;
+       u8 direct_ssid_len;
+       u8 direct_ssid[IW_ESSID_MAX_SIZE];
+       struct iwl4965_scan_cmd *scan;
+       u8 only_active_channel;
+
+       /* spinlock */
+       spinlock_t lock;        /* protect general shared data */
+       spinlock_t hcmd_lock;   /* protect hcmd */
+       struct mutex mutex;
+
+       /* basic pci-network driver stuff */
+       struct pci_dev *pci_dev;
+
+       /* pci hardware address support */
+       void __iomem *hw_base;
+
+       /* uCode images, save to reload in case of failure */
+       struct fw_desc ucode_code;      /* runtime inst */
+       struct fw_desc ucode_data;      /* runtime data original */
+       struct fw_desc ucode_data_backup;       /* runtime data save/restore */
+       struct fw_desc ucode_init;      /* initialization inst */
+       struct fw_desc ucode_init_data; /* initialization data */
+       struct fw_desc ucode_boot;      /* bootstrap inst */
+
+
+       struct iwl4965_rxon_time_cmd rxon_timing;
+
+       /* We declare this const so it can only be
+        * changed via explicit cast within the
+        * routines that actually update the physical
+        * hardware */
+       const struct iwl4965_rxon_cmd active_rxon;
+       struct iwl4965_rxon_cmd staging_rxon;
+
+       int error_recovering;
+       struct iwl4965_rxon_cmd recovery_rxon;
+
+       /* 1st responses from initialize and runtime uCode images.
+        * 4965's initialize alive response contains some calibration data. */
+       struct iwl4965_init_alive_resp card_alive_init;
+       struct iwl4965_alive_resp card_alive;
+
+#ifdef LED
+       /* LED related variables */
+       struct iwl4965_activity_blink activity;
+       unsigned long led_packets;
+       int led_state;
+#endif
+
+       u16 active_rate;
+       u16 active_rate_basic;
+
+       u8 call_post_assoc_from_beacon;
+       u8 assoc_station_added;
+       u8 use_ant_b_for_management_frame;      /* Tx antenna selection */
+       u8 valid_antenna;       /* Bit mask of antennas actually connected */
+#ifdef CONFIG_IWL4965_SENSITIVITY
+       struct iwl4965_sensitivity_data sensitivity_data;
+       struct iwl4965_chain_noise_data chain_noise_data;
+       u8 start_calib;
+       __le16 sensitivity_tbl[HD_TABLE_SIZE];
+#endif /*CONFIG_IWL4965_SENSITIVITY*/
+
+#ifdef CONFIG_IWL4965_HT
+       struct iwl_ht_info current_ht_config;
+#endif
+       u8 last_phy_res[100];
+
+       /* Rate scaling data */
+       struct iwl4965_lq_mngr lq_mngr;
+
+       /* Rate scaling data */
+       s8 data_retry_limit;
+       u8 retry_rate;
+
+       wait_queue_head_t wait_command_queue;
+
+       int activity_timer_active;
+
+       /* Rx and Tx DMA processing queues */
+       struct iwl4965_rx_queue rxq;
+       struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES];
+       unsigned long txq_ctx_active_msk;
+       struct iwl4965_kw kw;   /* keep warm address */
+       u32 scd_base_addr;      /* scheduler sram base address */
+
+       unsigned long status;
+       u32 config;
+
+       int last_rx_rssi;       /* From Rx packet statisitics */
+       int last_rx_noise;      /* From beacon statistics */
+
+       struct iwl4965_power_mgr power_data;
+
+       struct iwl4965_notif_statistics statistics;
+       unsigned long last_statistics_time;
+
+       /* context information */
+       u8 essid[IW_ESSID_MAX_SIZE];
+       u8 essid_len;
+       u16 rates_mask;
+
+       u32 power_mode;
+       u32 antenna;
+       u8 bssid[ETH_ALEN];
+       u16 rts_threshold;
+       u8 mac_addr[ETH_ALEN];
+
+       /*station table variables */
+       spinlock_t sta_lock;
+       int num_stations;
+       struct iwl4965_station_entry stations[IWL_STATION_COUNT];
+
+       /* Indication if ieee80211_ops->open has been called */
+       int is_open;
+
+       u8 mac80211_registered;
+       int is_abg;
+
+       u32 notif_missed_beacons;
+
+       /* Rx'd packet timing information */
+       u32 last_beacon_time;
+       u64 last_tsf;
+
+       /* Duplicate packet detection */
+       u16 last_seq_num;
+       u16 last_frag_num;
+       unsigned long last_packet_time;
+
+       /* Hash table for finding stations in IBSS network */
+       struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
+
+       /* eeprom */
+       struct iwl4965_eeprom eeprom;
+
+       int iw_mode;
+
+       struct sk_buff *ibss_beacon;
+
+       /* Last Rx'd beacon timestamp */
+       u32 timestamp0;
+       u32 timestamp1;
+       u16 beacon_int;
+       struct iwl4965_driver_hw_info hw_setting;
+       struct ieee80211_vif *vif;
+
+       /* Current association information needed to configure the
+        * hardware */
+       u16 assoc_id;
+       u16 assoc_capability;
+       u8 ps_mode;
+
+#ifdef CONFIG_IWL4965_QOS
+       struct iwl4965_qos_info qos_data;
+#endif /*CONFIG_IWL4965_QOS */
+
+       struct workqueue_struct *workqueue;
+
+       struct work_struct up;
+       struct work_struct restart;
+       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;
+       struct work_struct report_work;
+       struct work_struct request_scan;
+       struct work_struct beacon_update;
+
+       struct tasklet_struct irq_tasklet;
+
+       struct delayed_work init_alive_start;
+       struct delayed_work alive_start;
+       struct delayed_work activity_timer;
+       struct delayed_work thermal_periodic;
+       struct delayed_work gather_stats;
+       struct delayed_work scan_check;
+       struct delayed_work post_associate;
+
+#define IWL_DEFAULT_TX_POWER 0x0F
+       s8 user_txpower_limit;
+       s8 max_channel_txpower_limit;
+
+#ifdef CONFIG_PM
+       u32 pm_state[16];
+#endif
+
+#ifdef CONFIG_IWL4965_DEBUG
+       /* debugging info */
+       u32 framecnt_to_us;
+       atomic_t restrict_refcnt;
+#endif
+
+       struct work_struct txpower_work;
+#ifdef CONFIG_IWL4965_SENSITIVITY
+       struct work_struct sensitivity_work;
+#endif
+       struct work_struct statistics_work;
+       struct timer_list statistics_periodic;
+
+#ifdef CONFIG_IWL4965_HT_AGG
+       struct work_struct agg_work;
+#endif
+};                             /*iwl4965_priv */
+
+static inline int iwl4965_is_associated(struct iwl4965_priv *priv)
+{
+       return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+}
+
+static inline int is_channel_valid(const struct iwl4965_channel_info *ch_info)
+{
+       if (ch_info == NULL)
+               return 0;
+       return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
+}
+
+static inline int is_channel_narrow(const struct iwl4965_channel_info *ch_info)
+{
+       return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0;
+}
+
+static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info)
+{
+       return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
+}
+
+static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info)
+{
+       return ch_info->phymode == MODE_IEEE80211A;
+}
+
+static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info)
+{
+       return ((ch_info->phymode == MODE_IEEE80211B) ||
+               (ch_info->phymode == MODE_IEEE80211G));
+}
+
+static inline int is_channel_passive(const struct iwl4965_channel_info *ch)
+{
+       return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
+}
+
+static inline int is_channel_ibss(const struct iwl4965_channel_info *ch)
+{
+       return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
+}
+
+extern const struct iwl4965_channel_info *iwl4965_get_channel_info(
+       const struct iwl4965_priv *priv, int phymode, u16 channel);
+
+/* Requires full declaration of iwl4965_priv before including */
+#include "iwl-4965-io.h"
+
+#endif                         /* __iwl4965_4965_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-channel.h b/drivers/net/wireless/iwlwifi/iwl-channel.h
deleted file mode 100644 (file)
index 023c3f2..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- *
- * 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:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-#ifndef __iwl_channel_h__
-#define __iwl_channel_h__
-
-#define IWL_NUM_SCAN_RATES         (2)
-
-struct iwl_channel_tgd_info {
-       u8 type;
-       s8 max_power;
-};
-
-struct iwl_channel_tgh_info {
-       s64 last_radar_time;
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl_channel_power_info {
-       struct iwl_tx_power tpc;        /* actual radio and DSP gain settings */
-       s8 power_table_index;   /* actual (compenst'd) index into gain table */
-       s8 base_power_index;    /* gain index for power at factory temp. */
-       s8 requested_power;     /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl_scan_power_info {
-       struct iwl_tx_power tpc;        /* actual radio and DSP gain settings */
-       s8 power_table_index;   /* actual (compenst'd) index into gain table */
-       s8 requested_power;     /* scan pwr (dBm) requested for chnl/rate */
-};
-
-/* Channel unlock period is 15 seconds. If no beacon or probe response
- * has been received within 15 seconds on a locked channel then the channel
- * remains locked. */
-#define TX_UNLOCK_PERIOD 15
-
-/* CSA lock period is 15 seconds.  If a CSA has been received on a channel in
- * the last 15 seconds, the channel is locked */
-#define CSA_LOCK_PERIOD 15
-/*
- * One for each channel, holds all channel setup data
- * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
- *     with one another!
- */
-#define IWL4965_MAX_RATE (33)
-
-struct iwl_channel_info {
-       struct iwl_channel_tgd_info tgd;
-       struct iwl_channel_tgh_info tgh;
-       struct iwl_eeprom_channel eeprom;       /* EEPROM regulatory limit */
-       struct iwl_eeprom_channel fat_eeprom;   /* EEPROM regulatory limit for
-                                                * FAT channel */
-
-       u8 channel;       /* channel number */
-       u8 flags;         /* flags copied from EEPROM */
-       s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
-       s8 curr_txpow;    /* (dBm) regulatory/spectrum/user (not h/w) */
-       s8 min_power;     /* always 0 */
-       s8 scan_power;    /* (dBm) regul. eeprom, direct scans, any rate */
-
-       u8 group_index;   /* 0-4, maps channel to group1/2/3/4/5 */
-       u8 band_index;    /* 0-4, maps channel to band1/2/3/4/5 */
-       u8 phymode;       /* MODE_IEEE80211{A,B,G} */
-
-       /* Radio/DSP gain settings for each "normal" data Tx rate.
-        * These include, in addition to RF and DSP gain, a few fields for
-        *   remembering/modifying gain settings (indexes). */
-       struct iwl_channel_power_info power_info[IWL4965_MAX_RATE];
-
-#if IWL == 4965
-       /* FAT channel info */
-       s8 fat_max_power_avg;   /* (dBm) regul. eeprom, normal Tx, any rate */
-       s8 fat_curr_txpow;      /* (dBm) regulatory/spectrum/user (not h/w) */
-       s8 fat_min_power;       /* always 0 */
-       s8 fat_scan_power;      /* (dBm) eeprom, direct scans, any rate */
-       u8 fat_flags;           /* flags copied from EEPROM */
-       u8 fat_extension_channel;
-#endif
-
-       /* Radio/DSP gain settings for each scan rate, for directed scans. */
-       struct iwl_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
-};
-
-struct iwl_clip_group {
-       /* maximum power level to prevent clipping for each rate, derived by
-        *   us from this band's saturation power in EEPROM */
-       const s8 clip_powers[IWL_MAX_RATES];
-};
-
-static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
-{
-       if (ch_info == NULL)
-               return 0;
-       return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0;
-}
-
-static inline int is_channel_narrow(const struct iwl_channel_info *ch_info)
-{
-       return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0;
-}
-
-static inline int is_channel_radar(const struct iwl_channel_info *ch_info)
-{
-       return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0;
-}
-
-static inline u8 is_channel_a_band(const struct iwl_channel_info *ch_info)
-{
-       return ch_info->phymode == MODE_IEEE80211A;
-}
-
-static inline u8 is_channel_bg_band(const struct iwl_channel_info *ch_info)
-{
-       return ((ch_info->phymode == MODE_IEEE80211B) ||
-               (ch_info->phymode == MODE_IEEE80211G));
-}
-
-static inline int is_channel_passive(const struct iwl_channel_info *ch)
-{
-       return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
-}
-
-static inline int is_channel_ibss(const struct iwl_channel_info *ch)
-{
-       return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0;
-}
-
-extern const struct iwl_channel_info *iwl_get_channel_info(
-       const struct iwl_priv *priv, int phymode, u16 channel);
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
deleted file mode 100644 (file)
index 9de8d7f..0000000
+++ /dev/null
@@ -1,1734 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral 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.GPL.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- * 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 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.
- *
- *****************************************************************************/
-
-#ifndef __iwl_commands_h__
-#define __iwl_commands_h__
-
-enum {
-       REPLY_ALIVE = 0x1,
-       REPLY_ERROR = 0x2,
-
-       /* RXON and QOS commands */
-       REPLY_RXON = 0x10,
-       REPLY_RXON_ASSOC = 0x11,
-       REPLY_QOS_PARAM = 0x13,
-       REPLY_RXON_TIMING = 0x14,
-
-       /* Multi-Station support */
-       REPLY_ADD_STA = 0x18,
-       REPLY_REMOVE_STA = 0x19,        /* not used */
-       REPLY_REMOVE_ALL_STA = 0x1a,    /* not used */
-
-       /* RX, TX, LEDs */
-#if IWL == 3945
-       REPLY_3945_RX = 0x1b,           /* 3945 only */
-#endif
-       REPLY_TX = 0x1c,
-       REPLY_RATE_SCALE = 0x47,        /* 3945 only */
-       REPLY_LEDS_CMD = 0x48,
-       REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */
-
-       /* 802.11h related */
-       RADAR_NOTIFICATION = 0x70,      /* not used */
-       REPLY_QUIET_CMD = 0x71,         /* not used */
-       REPLY_CHANNEL_SWITCH = 0x72,
-       CHANNEL_SWITCH_NOTIFICATION = 0x73,
-       REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74,
-       SPECTRUM_MEASURE_NOTIFICATION = 0x75,
-
-       /* Power Management */
-       POWER_TABLE_CMD = 0x77,
-       PM_SLEEP_NOTIFICATION = 0x7A,
-       PM_DEBUG_STATISTIC_NOTIFIC = 0x7B,
-
-       /* Scan commands and notifications */
-       REPLY_SCAN_CMD = 0x80,
-       REPLY_SCAN_ABORT_CMD = 0x81,
-       SCAN_START_NOTIFICATION = 0x82,
-       SCAN_RESULTS_NOTIFICATION = 0x83,
-       SCAN_COMPLETE_NOTIFICATION = 0x84,
-
-       /* IBSS/AP commands */
-       BEACON_NOTIFICATION = 0x90,
-       REPLY_TX_BEACON = 0x91,
-       WHO_IS_AWAKE_NOTIFICATION = 0x94,       /* not used */
-
-       /* Miscellaneous commands */
-       QUIET_NOTIFICATION = 0x96,              /* not used */
-       REPLY_TX_PWR_TABLE_CMD = 0x97,
-       MEASURE_ABORT_NOTIFICATION = 0x99,      /* not used */
-
-       /* BT config command */
-       REPLY_BT_CONFIG = 0x9b,
-
-       /* 4965 Statistics */
-       REPLY_STATISTICS_CMD = 0x9c,
-       STATISTICS_NOTIFICATION = 0x9d,
-
-       /* RF-KILL commands and notifications */
-       REPLY_CARD_STATE_CMD = 0xa0,
-       CARD_STATE_NOTIFICATION = 0xa1,
-
-       /* Missed beacons notification */
-       MISSED_BEACONS_NOTIFICATION = 0xa2,
-
-#if IWL == 4965
-       REPLY_CT_KILL_CONFIG_CMD = 0xa4,
-       SENSITIVITY_CMD = 0xa8,
-       REPLY_PHY_CALIBRATION_CMD = 0xb0,
-       REPLY_RX_PHY_CMD = 0xc0,
-       REPLY_RX_MPDU_CMD = 0xc1,
-       REPLY_4965_RX = 0xc3,
-       REPLY_COMPRESSED_BA = 0xc5,
-#endif
-       REPLY_MAX = 0xff
-};
-
-/******************************************************************************
- * (0)
- * Header
- *
- *****************************************************************************/
-
-#define IWL_CMD_FAILED_MSK 0x40
-
-struct iwl_cmd_header {
-       u8 cmd;
-       u8 flags;
-       /* We have 15 LSB to use as we please (MSB indicates
-        * a frame Rx'd from the HW).  We encode the following
-        * information into the sequence field:
-        *
-        *  0:7    index in fifo
-        *  8:13   fifo selection
-        * 14:14   bit indicating if this packet references the 'extra'
-        *         storage at the end of the memory queue
-        * 15:15   (Rx indication)
-        *
-        */
-       __le16 sequence;
-
-       /* command data follows immediately */
-       u8 data[0];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (0a)
- * Alive and Error Commands & Responses:
- *
- *****************************************************************************/
-
-#define UCODE_VALID_OK __constant_cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE    (9)
-
-/*
- * REPLY_ALIVE = 0x1 (response only, not a command)
- */
-struct iwl_alive_resp {
-       u8 ucode_minor;
-       u8 ucode_major;
-       __le16 reserved1;
-       u8 sw_rev[8];
-       u8 ver_type;
-       u8 ver_subtype;
-       __le16 reserved2;
-       __le32 log_event_table_ptr;
-       __le32 error_event_table_ptr;
-       __le32 timestamp;
-       __le32 is_valid;
-} __attribute__ ((packed));
-
-struct iwl_init_alive_resp {
-       u8 ucode_minor;
-       u8 ucode_major;
-       __le16 reserved1;
-       u8 sw_rev[8];
-       u8 ver_type;
-       u8 ver_subtype;
-       __le16 reserved2;
-       __le32 log_event_table_ptr;
-       __le32 error_event_table_ptr;
-       __le32 timestamp;
-       __le32 is_valid;
-
-#if IWL == 4965
-       /* calibration values from "initialize" uCode */
-       __le32 voltage;         /* signed */
-       __le32 therm_r1[2];     /* signed 1st for normal, 2nd for FAT channel */
-       __le32 therm_r2[2];     /* signed */
-       __le32 therm_r3[2];     /* signed */
-       __le32 therm_r4[2];     /* signed */
-       __le32 tx_atten[5][2];  /* signed MIMO gain comp, 5 freq groups,
-                                * 2 Tx chains */
-#endif
-} __attribute__ ((packed));
-
-union tsf {
-       u8 byte[8];
-       __le16 word[4];
-       __le32 dw[2];
-};
-
-/*
- * REPLY_ERROR = 0x2 (response only, not a command)
- */
-struct iwl_error_resp {
-       __le32 error_type;
-       u8 cmd_id;
-       u8 reserved1;
-       __le16 bad_cmd_seq_num;
-#if IWL == 3945
-       __le16 reserved2;
-#endif
-       __le32 error_info;
-       union tsf timestamp;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (1)
- * RXON Commands & Responses:
- *
- *****************************************************************************/
-
-/*
- * Rx config defines & structure
- */
-/* rx_config device types  */
-enum {
-       RXON_DEV_TYPE_AP = 1,
-       RXON_DEV_TYPE_ESS = 3,
-       RXON_DEV_TYPE_IBSS = 4,
-       RXON_DEV_TYPE_SNIFFER = 6,
-};
-
-/* rx_config flags */
-/* band & modulation selection */
-#define RXON_FLG_BAND_24G_MSK           __constant_cpu_to_le32(1 << 0)
-#define RXON_FLG_CCK_MSK                __constant_cpu_to_le32(1 << 1)
-/* auto detection enable */
-#define RXON_FLG_AUTO_DETECT_MSK        __constant_cpu_to_le32(1 << 2)
-/* TGg protection when tx */
-#define RXON_FLG_TGG_PROTECT_MSK        __constant_cpu_to_le32(1 << 3)
-/* cck short slot & preamble */
-#define RXON_FLG_SHORT_SLOT_MSK          __constant_cpu_to_le32(1 << 4)
-#define RXON_FLG_SHORT_PREAMBLE_MSK     __constant_cpu_to_le32(1 << 5)
-/* antenna selection */
-#define RXON_FLG_DIS_DIV_MSK            __constant_cpu_to_le32(1 << 7)
-#define RXON_FLG_ANT_SEL_MSK            __constant_cpu_to_le32(0x0f00)
-#define RXON_FLG_ANT_A_MSK              __constant_cpu_to_le32(1 << 8)
-#define RXON_FLG_ANT_B_MSK              __constant_cpu_to_le32(1 << 9)
-/* radar detection enable */
-#define RXON_FLG_RADAR_DETECT_MSK       __constant_cpu_to_le32(1 << 12)
-#define RXON_FLG_TGJ_NARROW_BAND_MSK    __constant_cpu_to_le32(1 << 13)
-/* rx response to host with 8-byte TSF
-* (according to ON_AIR deassertion) */
-#define RXON_FLG_TSF2HOST_MSK           __constant_cpu_to_le32(1 << 15)
-
-/* rx_config filter flags */
-/* accept all data frames */
-#define RXON_FILTER_PROMISC_MSK         __constant_cpu_to_le32(1 << 0)
-/* pass control & management to host */
-#define RXON_FILTER_CTL2HOST_MSK        __constant_cpu_to_le32(1 << 1)
-/* accept multi-cast */
-#define RXON_FILTER_ACCEPT_GRP_MSK      __constant_cpu_to_le32(1 << 2)
-/* don't decrypt uni-cast frames */
-#define RXON_FILTER_DIS_DECRYPT_MSK     __constant_cpu_to_le32(1 << 3)
-/* don't decrypt multi-cast frames */
-#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4)
-/* STA is associated */
-#define RXON_FILTER_ASSOC_MSK           __constant_cpu_to_le32(1 << 5)
-/* transfer to host non bssid beacons in associated state */
-#define RXON_FILTER_BCON_AWARE_MSK      __constant_cpu_to_le32(1 << 6)
-
-/*
- * REPLY_RXON = 0x10 (command, has simple generic response)
- */
-struct iwl_rxon_cmd {
-       u8 node_addr[6];
-       __le16 reserved1;
-       u8 bssid_addr[6];
-       __le16 reserved2;
-       u8 wlap_bssid_addr[6];
-       __le16 reserved3;
-       u8 dev_type;
-       u8 air_propagation;
-#if IWL == 3945
-       __le16 reserved4;
-#elif IWL == 4965
-       __le16 rx_chain;
-#endif
-       u8 ofdm_basic_rates;
-       u8 cck_basic_rates;
-       __le16 assoc_id;
-       __le32 flags;
-       __le32 filter_flags;
-       __le16 channel;
-#if IWL == 3945
-       __le16 reserved5;
-#elif IWL == 4965
-       u8 ofdm_ht_single_stream_basic_rates;
-       u8 ofdm_ht_dual_stream_basic_rates;
-#endif
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
- */
-struct iwl_rxon_assoc_cmd {
-       __le32 flags;
-       __le32 filter_flags;
-       u8 ofdm_basic_rates;
-       u8 cck_basic_rates;
-#if IWL == 4965
-       u8 ofdm_ht_single_stream_basic_rates;
-       u8 ofdm_ht_dual_stream_basic_rates;
-       __le16 rx_chain_select_flags;
-#endif
-       __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
- */
-struct iwl_rxon_time_cmd {
-       union tsf timestamp;
-       __le16 beacon_interval;
-       __le16 atim_window;
-       __le32 beacon_init_val;
-       __le16 listen_interval;
-       __le16 reserved;
-} __attribute__ ((packed));
-
-struct iwl_tx_power {
-       u8 tx_gain;             /* gain for analog radio */
-       u8 dsp_atten;           /* gain for DSP */
-} __attribute__ ((packed));
-
-#if IWL == 3945
-struct iwl_power_per_rate {
-       u8 rate;                /* plcp */
-       struct iwl_tx_power tpc;
-       u8 reserved;
-} __attribute__ ((packed));
-
-#elif IWL == 4965
-#define POWER_TABLE_NUM_ENTRIES                        33
-#define POWER_TABLE_NUM_HT_OFDM_ENTRIES                32
-#define POWER_TABLE_CCK_ENTRY                  32
-struct tx_power_dual_stream {
-       __le32 dw;
-} __attribute__ ((packed));
-
-struct iwl_tx_power_db {
-       struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
-} __attribute__ ((packed));
-#endif
-
-/*
- * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
- */
-struct iwl_channel_switch_cmd {
-       u8 band;
-       u8 expect_beacon;
-       __le16 channel;
-       __le32 rxon_flags;
-       __le32 rxon_filter_flags;
-       __le32 switch_time;
-#if IWL == 3945
-       struct iwl_power_per_rate power[IWL_MAX_RATES];
-#elif IWL == 4965
-       struct iwl_tx_power_db tx_power;
-#endif
-} __attribute__ ((packed));
-
-/*
- * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command)
- */
-struct iwl_csa_notification {
-       __le16 band;
-       __le16 channel;
-       __le32 status;          /* 0 - OK, 1 - fail */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (2)
- * Quality-of-Service (QOS) Commands & Responses:
- *
- *****************************************************************************/
-struct iwl_ac_qos {
-       __le16 cw_min;
-       __le16 cw_max;
-       u8 aifsn;
-       u8 reserved1;
-       __le16 edca_txop;
-} __attribute__ ((packed));
-
-/* QoS flags defines */
-#define QOS_PARAM_FLG_UPDATE_EDCA_MSK  __constant_cpu_to_le32(0x01)
-#define QOS_PARAM_FLG_TGN_MSK          __constant_cpu_to_le32(0x02)
-#define QOS_PARAM_FLG_TXOP_TYPE_MSK    __constant_cpu_to_le32(0x10)
-
-/*
- *  TXFIFO Queue number defines
- */
-/* number of Access categories (AC) (EDCA), queues 0..3 */
-#define AC_NUM                4
-
-/*
- * REPLY_QOS_PARAM = 0x13 (command, has simple generic response)
- */
-struct iwl_qosparam_cmd {
-       __le32 qos_flags;
-       struct iwl_ac_qos ac[AC_NUM];
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (3)
- * Add/Modify Stations Commands & Responses:
- *
- *****************************************************************************/
-/*
- * Multi station support
- */
-#define        IWL_AP_ID               0
-#define IWL_MULTICAST_ID       1
-#define        IWL_STA_ID              2
-
-#define        IWL3945_BROADCAST_ID    24
-#define IWL3945_STATION_COUNT  25
-
-#define IWL4965_BROADCAST_ID   31
-#define        IWL4965_STATION_COUNT   32
-
-#define        IWL_STATION_COUNT       32      /* MAX(3945,4965)*/
-#define        IWL_INVALID_STATION     255
-
-#if IWL == 3945
-#define STA_FLG_TX_RATE_MSK            __constant_cpu_to_le32(1<<2);
-#endif
-#define STA_FLG_PWR_SAVE_MSK           __constant_cpu_to_le32(1<<8);
-
-#define STA_CONTROL_MODIFY_MSK         0x01
-
-/* key flags __le16*/
-#define STA_KEY_FLG_ENCRYPT_MSK        __constant_cpu_to_le16(0x7)
-#define STA_KEY_FLG_NO_ENC     __constant_cpu_to_le16(0x0)
-#define STA_KEY_FLG_WEP                __constant_cpu_to_le16(0x1)
-#define STA_KEY_FLG_CCMP       __constant_cpu_to_le16(0x2)
-#define STA_KEY_FLG_TKIP       __constant_cpu_to_le16(0x3)
-
-#define STA_KEY_FLG_KEYID_POS  8
-#define STA_KEY_FLG_INVALID    __constant_cpu_to_le16(0x0800)
-
-/* modify flags  */
-#define        STA_MODIFY_KEY_MASK             0x01
-#define        STA_MODIFY_TID_DISABLE_TX       0x02
-#define        STA_MODIFY_TX_RATE_MSK          0x04
-#define STA_MODIFY_ADDBA_TID_MSK       0x08
-#define STA_MODIFY_DELBA_TID_MSK       0x10
-#define BUILD_RAxTID(sta_id, tid)      (((sta_id) << 4) + (tid))
-
-/*
- * Antenna masks:
- * bit14:15 01 B inactive, A active
- *          10 B active, A inactive
- *          11 Both active
- */
-#define RATE_MCS_ANT_A_POS     14
-#define RATE_MCS_ANT_B_POS     15
-#define RATE_MCS_ANT_A_MSK     0x4000
-#define RATE_MCS_ANT_B_MSK     0x8000
-#define RATE_MCS_ANT_AB_MSK    0xc000
-
-struct iwl_keyinfo {
-       __le16 key_flags;
-       u8 tkip_rx_tsc_byte2;   /* TSC[2] for key mix ph1 detection */
-       u8 reserved1;
-       __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */
-       __le16 reserved2;
-       u8 key[16];             /* 16-byte unicast decryption key */
-} __attribute__ ((packed));
-
-struct sta_id_modify {
-       u8 addr[ETH_ALEN];
-       __le16 reserved1;
-       u8 sta_id;
-       u8 modify_mask;
-       __le16 reserved2;
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (command)
- */
-struct iwl_addsta_cmd {
-       u8 mode;
-       u8 reserved[3];
-       struct sta_id_modify sta;
-       struct iwl_keyinfo key;
-       __le32 station_flags;
-       __le32 station_flags_msk;
-       __le16 tid_disable_tx;
-#if IWL == 3945
-       __le16 rate_n_flags;
-#else
-       __le16  reserved1;
-#endif
-       u8 add_immediate_ba_tid;
-       u8 remove_immediate_ba_tid;
-       __le16 add_immediate_ba_ssn;
-#if IWL == 4965
-       __le32 reserved2;
-#endif
-} __attribute__ ((packed));
-
-/*
- * REPLY_ADD_STA = 0x18 (response)
- */
-struct iwl_add_sta_resp {
-       u8 status;
-} __attribute__ ((packed));
-
-#define ADD_STA_SUCCESS_MSK              0x1
-
-/******************************************************************************
- * (4)
- * Rx Responses:
- *
- *****************************************************************************/
-
-struct iwl_rx_frame_stats {
-       u8 phy_count;
-       u8 id;
-       u8 rssi;
-       u8 agc;
-       __le16 sig_avg;
-       __le16 noise_diff;
-       u8 payload[0];
-} __attribute__ ((packed));
-
-struct iwl_rx_frame_hdr {
-       __le16 channel;
-       __le16 phy_flags;
-       u8 reserved1;
-       u8 rate;
-       __le16 len;
-       u8 payload[0];
-} __attribute__ ((packed));
-
-#define        RX_RES_STATUS_NO_CRC32_ERROR    __constant_cpu_to_le32(1 << 0)
-#define        RX_RES_STATUS_NO_RXE_OVERFLOW   __constant_cpu_to_le32(1 << 1)
-
-#define        RX_RES_PHY_FLAGS_BAND_24_MSK    __constant_cpu_to_le16(1 << 0)
-#define        RX_RES_PHY_FLAGS_MOD_CCK_MSK            __constant_cpu_to_le16(1 << 1)
-#define        RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK     __constant_cpu_to_le16(1 << 2)
-#define        RX_RES_PHY_FLAGS_NARROW_BAND_MSK        __constant_cpu_to_le16(1 << 3)
-#define        RX_RES_PHY_FLAGS_ANTENNA_MSK            __constant_cpu_to_le16(0xf0)
-
-#define        RX_RES_STATUS_SEC_TYPE_MSK      (0x7 << 8)
-#define        RX_RES_STATUS_SEC_TYPE_NONE     (0x0 << 8)
-#define        RX_RES_STATUS_SEC_TYPE_WEP      (0x1 << 8)
-#define        RX_RES_STATUS_SEC_TYPE_CCMP     (0x2 << 8)
-#define        RX_RES_STATUS_SEC_TYPE_TKIP     (0x3 << 8)
-
-#define        RX_RES_STATUS_DECRYPT_TYPE_MSK  (0x3 << 11)
-#define        RX_RES_STATUS_NOT_DECRYPT       (0x0 << 11)
-#define        RX_RES_STATUS_DECRYPT_OK        (0x3 << 11)
-#define        RX_RES_STATUS_BAD_ICV_MIC       (0x1 << 11)
-#define        RX_RES_STATUS_BAD_KEY_TTAK      (0x2 << 11)
-
-struct iwl_rx_frame_end {
-       __le32 status;
-       __le64 timestamp;
-       __le32 beacon_timestamp;
-} __attribute__ ((packed));
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE:  DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl_rx_frame {
-       struct iwl_rx_frame_stats stats;
-       struct iwl_rx_frame_hdr hdr;
-       struct iwl_rx_frame_end end;
-} __attribute__ ((packed));
-
-/* Fixed (non-configurable) rx data from phy */
-#define RX_PHY_FLAGS_ANTENNAE_OFFSET           (4)
-#define RX_PHY_FLAGS_ANTENNAE_MASK             (0x70)
-#define IWL_AGC_DB_MASK        (0x3f80)        /* MASK(7,13) */
-#define IWL_AGC_DB_POS         (7)
-struct iwl4965_rx_non_cfg_phy {
-       __le16 ant_selection;   /* ant A bit 4, ant B bit 5, ant C bit 6 */
-       __le16 agc_info;        /* agc code 0:6, agc dB 7:13, reserved 14:15 */
-       u8 rssi_info[6];        /* we use even entries, 0/2/4 for A/B/C rssi */
-       u8 pad[0];
-} __attribute__ ((packed));
-
-/*
- * REPLY_4965_RX = 0xc3 (response only, not a command)
- * Used only for legacy (non 11n) frames.
- */
-#define RX_RES_PHY_CNT 14
-struct iwl4965_rx_phy_res {
-       u8 non_cfg_phy_cnt;     /* non configurable DSP phy data byte count */
-       u8 cfg_phy_cnt;         /* configurable DSP phy data byte count */
-       u8 stat_id;             /* configurable DSP phy data set ID */
-       u8 reserved1;
-       __le64 timestamp;       /* TSF at on air rise */
-       __le32 beacon_time_stamp; /* beacon at on-air rise */
-       __le16 phy_flags;       /* general phy flags: band, modulation, ... */
-       __le16 channel;         /* channel number */
-       __le16 non_cfg_phy[RX_RES_PHY_CNT];     /* upto 14 phy entries */
-       __le32 reserved2;
-       __le32 rate_n_flags;
-       __le16 byte_count;              /* frame's byte-count */
-       __le16 reserved3;
-} __attribute__ ((packed));
-
-struct iwl4965_rx_mpdu_res_start {
-       __le16 byte_count;
-       __le16 reserved;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (5)
- * Tx Commands & Responses:
- *
- *****************************************************************************/
-
-/* Tx flags */
-#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1)
-#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2)
-#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3)
-#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4)
-#define TX_CMD_FLG_IMM_BA_RSP_MASK  __constant_cpu_to_le32(1 << 6)
-#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7)
-#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00)
-#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8)
-#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9)
-
-/* ucode ignores BT priority for this frame */
-#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12)
-
-/* ucode overrides sequence control */
-#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13)
-
-/* signal that this frame is non-last MPDU */
-#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14)
-
-/* calculate TSF in outgoing frame */
-#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16)
-
-/* activate TX calibration. */
-#define TX_CMD_FLG_CALIB_MSK __constant_cpu_to_le32(1 << 17)
-
-/* signals that 2 bytes pad was inserted
-   after the MAC header */
-#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20)
-
-/* HCCA-AP - disable duration overwriting. */
-#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25)
-
-/*
- * TX command security control
- */
-#define TX_CMD_SEC_WEP         0x01
-#define TX_CMD_SEC_CCM         0x02
-#define TX_CMD_SEC_TKIP                0x03
-#define TX_CMD_SEC_MSK         0x03
-#define TX_CMD_SEC_SHIFT       6
-#define TX_CMD_SEC_KEY128      0x08
-
-/*
- * TX command Frame life time
- */
-
-struct iwl_dram_scratch {
-       u8 try_cnt;
-       u8 bt_kill_cnt;
-       __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX = 0x1c (command)
- */
-struct iwl_tx_cmd {
-       __le16 len;
-       __le16 next_frame_len;
-       __le32 tx_flags;
-#if IWL == 3945
-       u8 rate;
-       u8 sta_id;
-       u8 tid_tspec;
-#elif IWL == 4965
-       struct iwl_dram_scratch scratch;
-       __le32 rate_n_flags;
-       u8 sta_id;
-#endif
-       u8 sec_ctl;
-#if IWL == 4965
-       u8 initial_rate_index;
-       u8 reserved;
-#endif
-       u8 key[16];
-#if IWL == 3945
-       union {
-               u8 byte[8];
-               __le16 word[4];
-               __le32 dw[2];
-       } tkip_mic;
-       __le32 next_frame_info;
-#elif IWL == 4965
-       __le16 next_frame_flags;
-       __le16 reserved2;
-#endif
-       union {
-               __le32 life_time;
-               __le32 attempt;
-       } stop_time;
-#if IWL == 3945
-       u8 supp_rates[2];
-#elif IWL == 4965
-       __le32 dram_lsb_ptr;
-       u8 dram_msb_ptr;
-#endif
-       u8 rts_retry_limit;     /*byte 50 */
-       u8 data_retry_limit;    /*byte 51 */
-#if IWL == 4965
-       u8 tid_tspec;
-#endif
-       union {
-               __le16 pm_frame_timeout;
-               __le16 attempt_duration;
-       } timeout;
-       __le16 driver_txop;
-       u8 payload[0];
-       struct ieee80211_hdr hdr[0];
-} __attribute__ ((packed));
-
-/* TX command response is sent after *all* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required.  This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response.  This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared.  The host must then deactivate the TX Abort
- * control line.  Receiving is still allowed in this case.
- */
-enum {
-       TX_STATUS_SUCCESS = 0x01,
-       TX_STATUS_DIRECT_DONE = 0x02,
-       TX_STATUS_FAIL_SHORT_LIMIT = 0x82,
-       TX_STATUS_FAIL_LONG_LIMIT = 0x83,
-       TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
-       TX_STATUS_FAIL_MGMNT_ABORT = 0x85,
-       TX_STATUS_FAIL_NEXT_FRAG = 0x86,
-       TX_STATUS_FAIL_LIFE_EXPIRE = 0x87,
-       TX_STATUS_FAIL_DEST_PS = 0x88,
-       TX_STATUS_FAIL_ABORTED = 0x89,
-       TX_STATUS_FAIL_BT_RETRY = 0x8a,
-       TX_STATUS_FAIL_STA_INVALID = 0x8b,
-       TX_STATUS_FAIL_FRAG_DROPPED = 0x8c,
-       TX_STATUS_FAIL_TID_DISABLE = 0x8d,
-       TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
-       TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
-       TX_STATUS_FAIL_TX_LOCKED = 0x90,
-       TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
-#define        TX_PACKET_MODE_REGULAR          0x0000
-#define        TX_PACKET_MODE_BURST_SEQ        0x0100
-#define        TX_PACKET_MODE_BURST_FIRST      0x0200
-
-enum {
-       TX_POWER_PA_NOT_ACTIVE = 0x0,
-};
-
-enum {
-       TX_STATUS_MSK = 0x000000ff,     /* bits 0:7 */
-       TX_STATUS_DELAY_MSK = 0x00000040,
-       TX_STATUS_ABORT_MSK = 0x00000080,
-       TX_PACKET_MODE_MSK = 0x0000ff00,        /* bits 8:15 */
-       TX_FIFO_NUMBER_MSK = 0x00070000,        /* bits 16:18 */
-       TX_RESERVED = 0x00780000,       /* bits 19:22 */
-       TX_POWER_PA_DETECT_MSK = 0x7f800000,    /* bits 23:30 */
-       TX_ABORT_REQUIRED_MSK = 0x80000000,     /* bits 31:31 */
-};
-
-/* *******************************
- * TX aggregation state
- ******************************* */
-
-enum {
-       AGG_TX_STATE_TRANSMITTED = 0x00,
-       AGG_TX_STATE_UNDERRUN_MSK = 0x01,
-       AGG_TX_STATE_BT_PRIO_MSK = 0x02,
-       AGG_TX_STATE_FEW_BYTES_MSK = 0x04,
-       AGG_TX_STATE_ABORT_MSK = 0x08,
-       AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10,
-       AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20,
-       AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40,
-       AGG_TX_STATE_SCD_QUERY_MSK = 0x80,
-       AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100,
-       AGG_TX_STATE_RESPONSE_MSK = 0x1ff,
-       AGG_TX_STATE_DUMP_TX_MSK = 0x200,
-       AGG_TX_STATE_DELAY_TX_MSK = 0x400
-};
-
-#define AGG_TX_STATE_LAST_SENT_MSK \
-(AGG_TX_STATE_LAST_SENT_TTL_MSK | \
- AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
- AGG_TX_STATE_LAST_SENT_BT_KILL_MSK)
-
-#define AGG_TX_STATE_TRY_CNT_POS 12
-#define AGG_TX_STATE_TRY_CNT_MSK 0xf000
-
-#define AGG_TX_STATE_SEQ_NUM_POS 16
-#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-#if IWL == 4965
-struct iwl_tx_resp {
-       u8 frame_count;         /* 1 no aggregation, >1 aggregation */
-       u8 bt_kill_count;
-       u8 failure_rts;
-       u8 failure_frame;
-       __le32 rate_n_flags;
-       __le16 wireless_media_time;
-       __le16 reserved;
-       __le32 pa_power1;
-       __le32 pa_power2;
-       __le32 status;  /* TX status (for aggregation status of 1st frame) */
-} __attribute__ ((packed));
-
-#elif IWL == 3945
-struct iwl_tx_resp {
-       u8 failure_rts;
-       u8 failure_frame;
-       u8 bt_kill_count;
-       u8 rate;
-       __le32 wireless_media_time;
-       __le32 status;  /* TX status (for aggregation status of 1st frame) */
-} __attribute__ ((packed));
-#endif
-
-/*
- * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command)
- */
-struct iwl_compressed_ba_resp {
-       __le32 sta_addr_lo32;
-       __le16 sta_addr_hi16;
-       __le16 reserved;
-       u8 sta_id;
-       u8 tid;
-       __le16 ba_seq_ctl;
-       __le32 ba_bitmap0;
-       __le32 ba_bitmap1;
-       __le16 scd_flow;
-       __le16 scd_ssn;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
- */
-struct iwl_txpowertable_cmd {
-       u8 band;                /* 0: 5 GHz, 1: 2.4 GHz */
-       u8 reserved;
-       __le16 channel;
-#if IWL == 3945
-       struct iwl_power_per_rate power[IWL_MAX_RATES];
-#elif IWL == 4965
-       struct iwl_tx_power_db tx_power;
-#endif
-} __attribute__ ((packed));
-
-#if IWL == 3945
-struct iwl_rate_scaling_info {
-       __le16 rate_n_flags;
-       u8 try_cnt;
-       u8 next_rate_index;
-} __attribute__ ((packed));
-
-/**
- * struct iwl_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1<<0)
- */
-struct iwl_rate_scaling_cmd {
-       u8 table_id;
-       u8 reserved[3];
-       struct iwl_rate_scaling_info table[IWL_MAX_RATES];
-} __attribute__ ((packed));
-
-#elif IWL == 4965
-
-/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
-#define  LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK   (1<<0)
-
-#define  LINK_QUAL_AC_NUM AC_NUM
-#define  LINK_QUAL_MAX_RETRY_NUM 16
-
-#define  LINK_QUAL_ANT_A_MSK (1<<0)
-#define  LINK_QUAL_ANT_B_MSK (1<<1)
-#define  LINK_QUAL_ANT_MSK   (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK)
-
-struct iwl_link_qual_general_params {
-       u8 flags;
-       u8 mimo_delimiter;
-       u8 single_stream_ant_msk;
-       u8 dual_stream_ant_msk;
-       u8 start_rate_index[LINK_QUAL_AC_NUM];
-} __attribute__ ((packed));
-
-struct iwl_link_qual_agg_params {
-       __le16 agg_time_limit;
-       u8 agg_dis_start_th;
-       u8 agg_frame_cnt_limit;
-       __le32 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response)
- */
-struct iwl_link_quality_cmd {
-       u8 sta_id;
-       u8 reserved1;
-       __le16 control;
-       struct iwl_link_qual_general_params general_params;
-       struct iwl_link_qual_agg_params agg_params;
-       struct {
-               __le32 rate_n_flags;
-       } rs_table[LINK_QUAL_MAX_RETRY_NUM];
-       __le32 reserved2;
-} __attribute__ ((packed));
-#endif
-
-/*
- * REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
- */
-struct iwl_bt_cmd {
-       u8 flags;
-       u8 lead_time;
-       u8 max_kill;
-       u8 reserved;
-       __le32 kill_ack_mask;
-       __le32 kill_cts_mask;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (6)
- * Spectrum Management (802.11h) Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/*
- * Spectrum Management
- */
-#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK         | \
-                                RXON_FILTER_CTL2HOST_MSK        | \
-                                RXON_FILTER_ACCEPT_GRP_MSK      | \
-                                RXON_FILTER_DIS_DECRYPT_MSK     | \
-                                RXON_FILTER_DIS_GRP_DECRYPT_MSK | \
-                                RXON_FILTER_ASSOC_MSK           | \
-                                RXON_FILTER_BCON_AWARE_MSK)
-
-struct iwl_measure_channel {
-       __le32 duration;        /* measurement duration in extended beacon
-                                * format */
-       u8 channel;             /* channel to measure */
-       u8 type;                /* see enum iwl_measure_type */
-       __le16 reserved;
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command)
- */
-struct iwl_spectrum_cmd {
-       __le16 len;             /* number of bytes starting from token */
-       u8 token;               /* token id */
-       u8 id;                  /* measurement id -- 0 or 1 */
-       u8 origin;              /* 0 = TGh, 1 = other, 2 = TGk */
-       u8 periodic;            /* 1 = periodic */
-       __le16 path_loss_timeout;
-       __le32 start_time;      /* start time in extended beacon format */
-       __le32 reserved2;
-       __le32 flags;           /* rxon flags */
-       __le32 filter_flags;    /* rxon filter flags */
-       __le16 channel_count;   /* minimum 1, maximum 10 */
-       __le16 reserved3;
-       struct iwl_measure_channel channels[10];
-} __attribute__ ((packed));
-
-/*
- * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response)
- */
-struct iwl_spectrum_resp {
-       u8 token;
-       u8 id;                  /* id of the prior command replaced, or 0xff */
-       __le16 status;          /* 0 - command will be handled
-                                * 1 - cannot handle (conflicts with another
-                                *     measurement) */
-} __attribute__ ((packed));
-
-enum iwl_measurement_state {
-       IWL_MEASUREMENT_START = 0,
-       IWL_MEASUREMENT_STOP = 1,
-};
-
-enum iwl_measurement_status {
-       IWL_MEASUREMENT_OK = 0,
-       IWL_MEASUREMENT_CONCURRENT = 1,
-       IWL_MEASUREMENT_CSA_CONFLICT = 2,
-       IWL_MEASUREMENT_TGH_CONFLICT = 3,
-       /* 4-5 reserved */
-       IWL_MEASUREMENT_STOPPED = 6,
-       IWL_MEASUREMENT_TIMEOUT = 7,
-       IWL_MEASUREMENT_PERIODIC_FAILED = 8,
-};
-
-#define NUM_ELEMENTS_IN_HISTOGRAM 8
-
-struct iwl_measurement_histogram {
-       __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */
-       __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM];  /* in 1usec counts */
-} __attribute__ ((packed));
-
-/* clear channel availability counters */
-struct iwl_measurement_cca_counters {
-       __le32 ofdm;
-       __le32 cck;
-} __attribute__ ((packed));
-
-enum iwl_measure_type {
-       IWL_MEASURE_BASIC = (1 << 0),
-       IWL_MEASURE_CHANNEL_LOAD = (1 << 1),
-       IWL_MEASURE_HISTOGRAM_RPI = (1 << 2),
-       IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3),
-       IWL_MEASURE_FRAME = (1 << 4),
-       /* bits 5:6 are reserved */
-       IWL_MEASURE_IDLE = (1 << 7),
-};
-
-/*
- * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command)
- */
-struct iwl_spectrum_notification {
-       u8 id;                  /* measurement id -- 0 or 1 */
-       u8 token;
-       u8 channel_index;       /* index in measurement channel list */
-       u8 state;               /* 0 - start, 1 - stop */
-       __le32 start_time;      /* lower 32-bits of TSF */
-       u8 band;                /* 0 - 5.2GHz, 1 - 2.4GHz */
-       u8 channel;
-       u8 type;                /* see enum iwl_measurement_type */
-       u8 reserved1;
-       /* NOTE:  cca_ofdm, cca_cck, basic_type, and histogram are only only
-        * valid if applicable for measurement type requested. */
-       __le32 cca_ofdm;        /* cca fraction time in 40Mhz clock periods */
-       __le32 cca_cck;         /* cca fraction time in 44Mhz clock periods */
-       __le32 cca_time;        /* channel load time in usecs */
-       u8 basic_type;          /* 0 - bss, 1 - ofdm preamble, 2 -
-                                * unidentified */
-       u8 reserved2[3];
-       struct iwl_measurement_histogram histogram;
-       __le32 stop_time;       /* lower 32-bits of TSF */
-       __le32 status;          /* see iwl_measurement_status */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (7)
- * Power Management Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-/**
- * struct iwl_powertable_cmd - Power Table Command
- * @flags: See below:
- *
- * POWER_TABLE_CMD = 0x77 (command, has simple generic response)
- *
- * PM allow:
- *   bit 0 - '0' Driver not allow power management
- *           '1' Driver allow PM (use rest of parameters)
- * uCode send sleep notifications:
- *   bit 1 - '0' Don't send sleep notification
- *           '1' send sleep notification (SEND_PM_NOTIFICATION)
- * Sleep over DTIM
- *   bit 2 - '0' PM have to walk up every DTIM
- *           '1' PM could sleep over DTIM till listen Interval.
- * PCI power managed
- *   bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- *           '1' !(PCI_LINK_CTRL & 0x1)
- * Force sleep Modes
- *   bit 31/30- '00' use both mac/xtal sleeps
- *              '01' force Mac sleep
- *              '10' force xtal sleep
- *              '11' Illegal set
- *
- * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then
- * ucode assume sleep over DTIM is allowed and we don't need to wakeup
- * for every DTIM.
- */
-#define IWL_POWER_VEC_SIZE 5
-
-
-#if IWL == 3945
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK       __constant_cpu_to_le32(1<<0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK          __constant_cpu_to_le32(1<<2)
-#define IWL_POWER_PCI_PM_MSK                   __constant_cpu_to_le32(1<<3)
-struct iwl_powertable_cmd {
-       __le32 flags;
-       __le32 rx_data_timeout;
-       __le32 tx_data_timeout;
-       __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __attribute__((packed));
-
-#elif IWL == 4965
-
-#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK       __constant_cpu_to_le16(1<<0)
-#define IWL_POWER_SLEEP_OVER_DTIM_MSK          __constant_cpu_to_le16(1<<2)
-#define IWL_POWER_PCI_PM_MSK                   __constant_cpu_to_le16(1<<3)
-
-struct iwl_powertable_cmd {
-       __le16 flags;
-       u8 keep_alive_seconds;
-       u8 debug_flags;
-       __le32 rx_data_timeout;
-       __le32 tx_data_timeout;
-       __le32 sleep_interval[IWL_POWER_VEC_SIZE];
-       __le32 keep_alive_beacons;
-} __attribute__ ((packed));
-#endif
-
-/*
- * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command)
- * 3945 and 4965 identical.
- */
-struct iwl_sleep_notification {
-       u8 pm_sleep_mode;
-       u8 pm_wakeup_src;
-       __le16 reserved;
-       __le32 sleep_time;
-       __le32 tsf_low;
-       __le32 bcon_timer;
-} __attribute__ ((packed));
-
-/* Sleep states.  3945 and 4965 identical. */
-enum {
-       IWL_PM_NO_SLEEP = 0,
-       IWL_PM_SLP_MAC = 1,
-       IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2,
-       IWL_PM_SLP_FULL_MAC_CARD_STATE = 3,
-       IWL_PM_SLP_PHY = 4,
-       IWL_PM_SLP_REPENT = 5,
-       IWL_PM_WAKEUP_BY_TIMER = 6,
-       IWL_PM_WAKEUP_BY_DRIVER = 7,
-       IWL_PM_WAKEUP_BY_RFKILL = 8,
-       /* 3 reserved */
-       IWL_PM_NUM_OF_MODES = 12,
-};
-
-/*
- * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response)
- */
-#define CARD_STATE_CMD_DISABLE 0x00    /* Put card to sleep */
-#define CARD_STATE_CMD_ENABLE  0x01    /* Wake up card */
-#define CARD_STATE_CMD_HALT    0x02    /* Power down permanently */
-struct iwl_card_state_cmd {
-       __le32 status;          /* CARD_STATE_CMD_* request new power state */
-} __attribute__ ((packed));
-
-/*
- * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command)
- */
-struct iwl_card_state_notif {
-       __le32 flags;
-} __attribute__ ((packed));
-
-#define HW_CARD_DISABLED   0x01
-#define SW_CARD_DISABLED   0x02
-#define RF_CARD_DISABLED   0x04
-#define RXON_CARD_DISABLED 0x10
-
-struct iwl_ct_kill_config {
-       __le32   reserved;
-       __le32   critical_temperature_M;
-       __le32   critical_temperature_R;
-}  __attribute__ ((packed));
-
-/******************************************************************************
- * (8)
- * Scan Commands, Responses, Notifications:
- *
- *****************************************************************************/
-
-struct iwl_scan_channel {
-       /* type is defined as:
-        * 0:0 active (0 - passive)
-        * 1:4 SSID direct
-        *     If 1 is set then corresponding SSID IE is transmitted in probe
-        * 5:7 reserved
-        */
-       u8 type;
-       u8 channel;
-       struct iwl_tx_power tpc;
-       __le16 active_dwell;
-       __le16 passive_dwell;
-} __attribute__ ((packed));
-
-struct iwl_ssid_ie {
-       u8 id;
-       u8 len;
-       u8 ssid[32];
-} __attribute__ ((packed));
-
-#define PROBE_OPTION_MAX        0x4
-#define TX_CMD_LIFE_TIME_INFINITE      __constant_cpu_to_le32(0xFFFFFFFF)
-#define IWL_GOOD_CRC_TH                __constant_cpu_to_le16(1)
-#define IWL_MAX_SCAN_SIZE 1024
-
-/*
- * REPLY_SCAN_CMD = 0x80 (command)
- */
-struct iwl_scan_cmd {
-       __le16 len;
-       u8 reserved0;
-       u8 channel_count;
-       __le16 quiet_time;     /* dwell only this long on quiet chnl
-                               * (active scan) */
-       __le16 quiet_plcp_th;  /* quiet chnl is < this # pkts (typ. 1) */
-       __le16 good_CRC_th;    /* passive -> active promotion threshold */
-#if IWL == 3945
-       __le16 reserved1;
-#elif IWL == 4965
-       __le16 rx_chain;
-#endif
-       __le32 max_out_time;   /* max usec to be out of associated (service)
-                               * chnl */
-       __le32 suspend_time;   /* pause scan this long when returning to svc
-                               * chnl.
-                               * 3945 -- 31:24 # beacons, 19:0 additional usec,
-                               * 4965 -- 31:22 # beacons, 21:0 additional usec.
-                               */
-       __le32 flags;
-       __le32 filter_flags;
-
-       struct iwl_tx_cmd tx_cmd;
-       struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
-
-       u8 data[0];
-       /*
-        * The channels start after the probe request payload and are of type:
-        *
-        * struct iwl_scan_channel channels[0];
-        *
-        * NOTE:  Only one band of channels can be scanned per pass.  You
-        * can not mix 2.4GHz channels and 5.2GHz channels and must
-        * request a scan multiple times (not concurrently)
-        *
-        */
-} __attribute__ ((packed));
-
-/* Can abort will notify by complete notification with abort status. */
-#define CAN_ABORT_STATUS       __constant_cpu_to_le32(0x1)
-/* complete notification statuses */
-#define ABORT_STATUS            0x2
-
-/*
- * REPLY_SCAN_CMD = 0x80 (response)
- */
-struct iwl_scanreq_notification {
-       __le32 status;          /* 1: okay, 2: cannot fulfill request */
-} __attribute__ ((packed));
-
-/*
- * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
- */
-struct iwl_scanstart_notification {
-       __le32 tsf_low;
-       __le32 tsf_high;
-       __le32 beacon_timer;
-       u8 channel;
-       u8 band;
-       u8 reserved[2];
-       __le32 status;
-} __attribute__ ((packed));
-
-#define  SCAN_OWNER_STATUS 0x1;
-#define  MEASURE_OWNER_STATUS 0x2;
-
-#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */
-/*
- * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
- */
-struct iwl_scanresults_notification {
-       u8 channel;
-       u8 band;
-       u8 reserved[2];
-       __le32 tsf_low;
-       __le32 tsf_high;
-       __le32 statistics[NUMBER_OF_STATISTICS];
-} __attribute__ ((packed));
-
-/*
- * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
- */
-struct iwl_scancomplete_notification {
-       u8 scanned_channels;
-       u8 status;
-       u8 reserved;
-       u8 last_channel;
-       __le32 tsf_low;
-       __le32 tsf_high;
-} __attribute__ ((packed));
-
-
-/******************************************************************************
- * (9)
- * IBSS/AP Commands and Notifications:
- *
- *****************************************************************************/
-
-/*
- * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
- */
-struct iwl_beacon_notif {
-       struct iwl_tx_resp beacon_notify_hdr;
-       __le32 low_tsf;
-       __le32 high_tsf;
-       __le32 ibss_mgr_status;
-} __attribute__ ((packed));
-
-/*
- * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
- */
-struct iwl_tx_beacon_cmd {
-       struct iwl_tx_cmd tx;
-       __le16 tim_idx;
-       u8 tim_size;
-       u8 reserved1;
-       struct ieee80211_hdr frame[0];  /* beacon frame */
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (10)
- * Statistics Commands and Notifications:
- *
- *****************************************************************************/
-
-#define IWL_TEMP_CONVERT 260
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
-
-/* Used for passing to driver number of successes and failures per rate */
-struct rate_histogram {
-       union {
-               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
-       } success;
-       union {
-               __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS];
-               __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS];
-               __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS];
-       } failed;
-} __attribute__ ((packed));
-
-/* statistics command response */
-
-struct statistics_rx_phy {
-       __le32 ina_cnt;
-       __le32 fina_cnt;
-       __le32 plcp_err;
-       __le32 crc32_err;
-       __le32 overrun_err;
-       __le32 early_overrun_err;
-       __le32 crc32_good;
-       __le32 false_alarm_cnt;
-       __le32 fina_sync_err_cnt;
-       __le32 sfd_timeout;
-       __le32 fina_timeout;
-       __le32 unresponded_rts;
-       __le32 rxe_frame_limit_overrun;
-       __le32 sent_ack_cnt;
-       __le32 sent_cts_cnt;
-#if IWL == 4965
-       __le32 sent_ba_rsp_cnt;
-       __le32 dsp_self_kill;
-       __le32 mh_format_err;
-       __le32 re_acq_main_rssi_sum;
-       __le32 reserved3;
-#endif
-} __attribute__ ((packed));
-
-#if IWL == 4965
-struct statistics_rx_ht_phy {
-       __le32 plcp_err;
-       __le32 overrun_err;
-       __le32 early_overrun_err;
-       __le32 crc32_good;
-       __le32 crc32_err;
-       __le32 mh_format_err;
-       __le32 agg_crc32_good;
-       __le32 agg_mpdu_cnt;
-       __le32 agg_cnt;
-       __le32 reserved2;
-} __attribute__ ((packed));
-#endif
-
-struct statistics_rx_non_phy {
-       __le32 bogus_cts;       /* CTS received when not expecting CTS */
-       __le32 bogus_ack;       /* ACK received when not expecting ACK */
-       __le32 non_bssid_frames;        /* number of frames with BSSID that
-                                        * doesn't belong to the STA BSSID */
-       __le32 filtered_frames; /* count frames that were dumped in the
-                                * filtering process */
-       __le32 non_channel_beacons;     /* beacons with our bss id but not on
-                                        * our serving channel */
-#if IWL == 4965
-       __le32 channel_beacons; /* beacons with our bss id and in our
-                                * serving channel */
-       __le32 num_missed_bcon; /* number of missed beacons */
-       __le32 adc_rx_saturation_time;  /* count in 0.8us units the time the
-                                        * ADC was in saturation */
-       __le32 ina_detection_search_time;/* total time (in 0.8us) searched
-                                         * for INA */
-       __le32 beacon_silence_rssi_a;   /* RSSI silence after beacon frame */
-       __le32 beacon_silence_rssi_b;   /* RSSI silence after beacon frame */
-       __le32 beacon_silence_rssi_c;   /* RSSI silence after beacon frame */
-       __le32 interference_data_flag;  /* flag for interference data
-                                        * availability. 1 when data is
-                                        * available. */
-       __le32 channel_load;    /* counts RX Enable time */
-       __le32 dsp_false_alarms;        /* DSP false alarm (both OFDM
-                                        * and CCK) counter */
-       __le32 beacon_rssi_a;
-       __le32 beacon_rssi_b;
-       __le32 beacon_rssi_c;
-       __le32 beacon_energy_a;
-       __le32 beacon_energy_b;
-       __le32 beacon_energy_c;
-#endif
-} __attribute__ ((packed));
-
-struct statistics_rx {
-       struct statistics_rx_phy ofdm;
-       struct statistics_rx_phy cck;
-       struct statistics_rx_non_phy general;
-#if IWL == 4965
-       struct statistics_rx_ht_phy ofdm_ht;
-#endif
-} __attribute__ ((packed));
-
-#if IWL == 4965
-struct statistics_tx_non_phy_agg {
-       __le32 ba_timeout;
-       __le32 ba_reschedule_frames;
-       __le32 scd_query_agg_frame_cnt;
-       __le32 scd_query_no_agg;
-       __le32 scd_query_agg;
-       __le32 scd_query_mismatch;
-       __le32 frame_not_ready;
-       __le32 underrun;
-       __le32 bt_prio_kill;
-       __le32 rx_ba_rsp_cnt;
-       __le32 reserved2;
-       __le32 reserved3;
-} __attribute__ ((packed));
-#endif
-
-struct statistics_tx {
-       __le32 preamble_cnt;
-       __le32 rx_detected_cnt;
-       __le32 bt_prio_defer_cnt;
-       __le32 bt_prio_kill_cnt;
-       __le32 few_bytes_cnt;
-       __le32 cts_timeout;
-       __le32 ack_timeout;
-       __le32 expected_ack_cnt;
-       __le32 actual_ack_cnt;
-#if IWL == 4965
-       __le32 dump_msdu_cnt;
-       __le32 burst_abort_next_frame_mismatch_cnt;
-       __le32 burst_abort_missing_next_frame_cnt;
-       __le32 cts_timeout_collision;
-       __le32 ack_or_ba_timeout_collision;
-       struct statistics_tx_non_phy_agg agg;
-#endif
-} __attribute__ ((packed));
-
-struct statistics_dbg {
-       __le32 burst_check;
-       __le32 burst_count;
-       __le32 reserved[4];
-} __attribute__ ((packed));
-
-struct statistics_div {
-       __le32 tx_on_a;
-       __le32 tx_on_b;
-       __le32 exec_time;
-       __le32 probe_time;
-#if IWL == 4965
-       __le32 reserved1;
-       __le32 reserved2;
-#endif
-} __attribute__ ((packed));
-
-struct statistics_general {
-       __le32 temperature;
-#if IWL == 4965
-       __le32 temperature_m;
-#endif
-       struct statistics_dbg dbg;
-       __le32 sleep_time;
-       __le32 slots_out;
-       __le32 slots_idle;
-       __le32 ttl_timestamp;
-       struct statistics_div div;
-#if IWL == 4965
-       __le32 rx_enable_counter;
-       __le32 reserved1;
-       __le32 reserved2;
-       __le32 reserved3;
-#endif
-} __attribute__ ((packed));
-
-/*
- * REPLY_STATISTICS_CMD = 0x9c,
- * 3945 and 4965 identical.
- *
- * This command triggers an immediate response containing uCode statistics.
- * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below.
- *
- * If the CLEAR_STATS configuration flag is set, uCode will clear its
- * internal copy of the statistics (counters) after issuing the response.
- * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below).
- *
- * If the DISABLE_NOTIF configuration flag is set, uCode will not issue
- * STATISTICS_NOTIFICATIONs after received beacons (see below).  This flag
- * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
- */
-#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */
-#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */
-struct iwl_statistics_cmd {
-       __le32 configuration_flags;     /* IWL_STATS_CONF_* */
-} __attribute__ ((packed));
-
-/*
- * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
- *
- * By default, uCode issues this notification after receiving a beacon
- * while associated.  To disable this behavior, set DISABLE_NOTIF flag in the
- * REPLY_STATISTICS_CMD 0x9c, above.
- *
- * Statistics counters continue to increment beacon after beacon, but are
- * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
- * 0x9c with CLEAR_STATS bit set (see above).
- *
- * uCode also issues this notification during scans.  uCode clears statistics
- * appropriately so that each notification contains statistics for only the
- * one channel that has just been scanned.
- */
-#define STATISTICS_REPLY_FLG_BAND_24G_MSK         __constant_cpu_to_le32(0x2)
-#define STATISTICS_REPLY_FLG_FAT_MODE_MSK         __constant_cpu_to_le32(0x8)
-struct iwl_notif_statistics {
-       __le32 flag;
-       struct statistics_rx rx;
-       struct statistics_tx tx;
-       struct statistics_general general;
-} __attribute__ ((packed));
-
-
-/*
- * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
- */
-/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row,
- * then this notification will be sent. */
-#define CONSECUTIVE_MISSED_BCONS_TH 20
-
-struct iwl_missed_beacon_notif {
-       __le32 consequtive_missed_beacons;
-       __le32 total_missed_becons;
-       __le32 num_expected_beacons;
-       __le32 num_recvd_beacons;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (11)
- * Rx Calibration Commands:
- *
- *****************************************************************************/
-
-#define PHY_CALIBRATE_DIFF_GAIN_CMD (7)
-#define HD_TABLE_SIZE  (11)
-
-struct iwl_sensitivity_cmd {
-       __le16 control;
-       __le16 table[HD_TABLE_SIZE];
-} __attribute__ ((packed));
-
-struct iwl_calibration_cmd {
-       u8 opCode;
-       u8 flags;
-       __le16 reserved;
-       s8 diff_gain_a;
-       s8 diff_gain_b;
-       s8 diff_gain_c;
-       u8 reserved1;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (12)
- * Miscellaneous Commands:
- *
- *****************************************************************************/
-
-/*
- * LEDs Command & Response
- * REPLY_LEDS_CMD = 0x48 (command, has simple generic response)
- *
- * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field),
- * this command turns it on or off, or sets up a periodic blinking cycle.
- */
-struct iwl_led_cmd {
-       __le32 interval;        /* "interval" in uSec */
-       u8 id;                  /* 1: Activity, 2: Link, 3: Tech */
-       u8 off;                 /* # intervals off while blinking;
-                                * "0", with >0 "on" value, turns LED on */
-       u8 on;                  /* # intervals on while blinking;
-                                * "0", regardless of "off", turns LED off */
-       u8 reserved;
-} __attribute__ ((packed));
-
-/******************************************************************************
- * (13)
- * Union of all expected notifications/responses:
- *
- *****************************************************************************/
-
-struct iwl_rx_packet {
-       __le32 len;
-       struct iwl_cmd_header hdr;
-       union {
-               struct iwl_alive_resp alive_frame;
-               struct iwl_rx_frame rx_frame;
-               struct iwl_tx_resp tx_resp;
-               struct iwl_spectrum_notification spectrum_notif;
-               struct iwl_csa_notification csa_notif;
-               struct iwl_error_resp err_resp;
-               struct iwl_card_state_notif card_state_notif;
-               struct iwl_beacon_notif beacon_status;
-               struct iwl_add_sta_resp add_sta;
-               struct iwl_sleep_notification sleep_notif;
-               struct iwl_spectrum_resp spectrum;
-               struct iwl_notif_statistics stats;
-#if IWL == 4965
-               struct iwl_compressed_ba_resp compressed_ba;
-               struct iwl_missed_beacon_notif missed_beacon;
-#endif
-               __le32 status;
-               u8 raw[0];
-       } u;
-} __attribute__ ((packed));
-
-#define IWL_RX_FRAME_SIZE        (4 + sizeof(struct iwl_rx_frame))
-
-#endif                         /* __iwl_commands_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
deleted file mode 100644 (file)
index 72318d7..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * 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:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_debug_h__
-#define __iwl_debug_h__
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-extern u32 iwl_debug_level;
-#define IWL_DEBUG(level, fmt, args...) \
-do { if (iwl_debug_level & (level)) \
-  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
-        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
-
-#define IWL_DEBUG_LIMIT(level, fmt, args...) \
-do { if ((iwl_debug_level & (level)) && net_ratelimit()) \
-  printk(KERN_ERR DRV_NAME": %c %s " fmt, \
-        in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
-#else
-static inline void IWL_DEBUG(int level, const char *fmt, ...)
-{
-}
-static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...)
-{
-}
-#endif                         /* CONFIG_IWLWIFI_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IWL_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry.  xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IWL_xxxx_DEBUG() macro definition for your
- * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/iwl/debug_level
- *
- * you simply need to add your entry to the iwl_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/iwl then you do not have
- * CONFIG_IWLWIFI_DEBUG defined in your kernel configuration
- *
- */
-
-#define IWL_DL_INFO          (1<<0)
-#define IWL_DL_MAC80211      (1<<1)
-#define IWL_DL_HOST_COMMAND  (1<<2)
-#define IWL_DL_STATE         (1<<3)
-
-#define IWL_DL_RADIO         (1<<7)
-#define IWL_DL_POWER         (1<<8)
-#define IWL_DL_TEMP          (1<<9)
-
-#define IWL_DL_NOTIF         (1<<10)
-#define IWL_DL_SCAN          (1<<11)
-#define IWL_DL_ASSOC         (1<<12)
-#define IWL_DL_DROP          (1<<13)
-
-#define IWL_DL_TXPOWER       (1<<14)
-
-#define IWL_DL_AP            (1<<15)
-
-#define IWL_DL_FW            (1<<16)
-#define IWL_DL_RF_KILL       (1<<17)
-#define IWL_DL_FW_ERRORS     (1<<18)
-
-#define IWL_DL_LED           (1<<19)
-
-#define IWL_DL_RATE          (1<<20)
-
-#define IWL_DL_CALIB         (1<<21)
-#define IWL_DL_WEP           (1<<22)
-#define IWL_DL_TX            (1<<23)
-#define IWL_DL_RX            (1<<24)
-#define IWL_DL_ISR           (1<<25)
-#define IWL_DL_HT            (1<<26)
-#define IWL_DL_IO            (1<<27)
-#define IWL_DL_11H           (1<<28)
-
-#define IWL_DL_STATS         (1<<29)
-#define IWL_DL_TX_REPLY      (1<<30)
-#define IWL_DL_QOS           (1<<31)
-
-#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
-#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
-#define IWL_DEBUG_INFO(f, a...)    IWL_DEBUG(IWL_DL_INFO, f, ## a)
-
-#define IWL_DEBUG_MAC80211(f, a...)     IWL_DEBUG(IWL_DL_MAC80211, f, ## a)
-#define IWL_DEBUG_TEMP(f, a...)   IWL_DEBUG(IWL_DL_TEMP, f, ## a)
-#define IWL_DEBUG_SCAN(f, a...)   IWL_DEBUG(IWL_DL_SCAN, f, ## a)
-#define IWL_DEBUG_RX(f, a...)     IWL_DEBUG(IWL_DL_RX, f, ## a)
-#define IWL_DEBUG_TX(f, a...)     IWL_DEBUG(IWL_DL_TX, f, ## a)
-#define IWL_DEBUG_ISR(f, a...)    IWL_DEBUG(IWL_DL_ISR, f, ## a)
-#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a)
-#define IWL_DEBUG_WEP(f, a...)    IWL_DEBUG(IWL_DL_WEP, f, ## a)
-#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a)
-#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a)
-#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a)
-#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a)
-#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a)
-#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a)
-#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
-#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
-#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
-#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
-       IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
-#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
-#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
-#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
-#define IWL_DEBUG_QOS(f, a...)   IWL_DEBUG(IWL_DL_QOS, f, ## a)
-#define IWL_DEBUG_RADIO(f, a...)  IWL_DEBUG(IWL_DL_RADIO, f, ## a)
-#define IWL_DEBUG_POWER(f, a...)  IWL_DEBUG(IWL_DL_POWER, f, ## a)
-#define IWL_DEBUG_11H(f, a...)  IWL_DEBUG(IWL_DL_11H, f, ## a)
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
deleted file mode 100644 (file)
index e473c97..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral 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.GPL.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- * 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 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.
- *
- *****************************************************************************/
-
-#ifndef __iwl_eeprom_h__
-#define __iwl_eeprom_h__
-
-/*
- * This file defines EEPROM related constants, enums, and inline functions.
- *
- */
-
-#define IWL_EEPROM_ACCESS_TIMEOUT      5000 /* uSec */
-#define IWL_EEPROM_ACCESS_DELAY                10   /* uSec */
-/* EEPROM field values */
-#define ANTENNA_SWITCH_NORMAL     0
-#define ANTENNA_SWITCH_INVERSE    1
-
-enum {
-       EEPROM_CHANNEL_VALID = (1 << 0),        /* usable for this SKU/geo */
-       EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */
-       /* Bit 2 Reserved */
-       EEPROM_CHANNEL_ACTIVE = (1 << 3),       /* active scanning allowed */
-       EEPROM_CHANNEL_RADAR = (1 << 4),        /* radar detection required */
-       EEPROM_CHANNEL_WIDE = (1 << 5),
-       EEPROM_CHANNEL_NARROW = (1 << 6),
-       EEPROM_CHANNEL_DFS = (1 << 7),  /* dynamic freq selection candidate */
-};
-
-/* EEPROM field lengths */
-#define EEPROM_BOARD_PBA_NUMBER_LENGTH                  11
-
-/* EEPROM field lengths */
-#define EEPROM_BOARD_PBA_NUMBER_LENGTH                  11
-#define EEPROM_REGULATORY_SKU_ID_LENGTH                 4
-#define EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH         14
-#define EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH         13
-#define EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH         12
-#define EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH         11
-#define EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH         6
-
-#if IWL == 3945
-#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \
-       EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH)
-#elif IWL == 4965
-#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH 7
-#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH 11
-#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \
-       EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH + \
-       EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH)
-#endif
-
-#define EEPROM_REGULATORY_NUMBER_OF_BANDS               5
-
-/* SKU Capabilities */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE                (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
-#define EEPROM_SKU_CAP_OP_MODE_MRC                      (1 << 7)
-
-/* *regulatory* channel data from eeprom, one for each channel */
-struct iwl_eeprom_channel {
-       u8 flags;               /* flags copied from EEPROM */
-       s8 max_power_avg;       /* max power (dBm) on this chnl, limit 31 */
-} __attribute__ ((packed));
-
-/*
- * Mapping of a Tx power level, at factory calibration temperature,
- *   to a radio/DSP gain table index.
- * One for each of 5 "sample" power levels in each band.
- * v_det is measured at the factory, using the 3945's built-in power amplifier
- *   (PA) output voltage detector.  This same detector is used during Tx of
- *   long packets in normal operation to provide feedback as to proper output
- *   level.
- * Data copied from EEPROM.
- */
-struct iwl_eeprom_txpower_sample {
-       u8 gain_index;          /* index into power (gain) setup table ... */
-       s8 power;               /* ... for this pwr level for this chnl group */
-       u16 v_det;              /* PA output voltage */
-} __attribute__ ((packed));
-
-/*
- * Mappings of Tx power levels -> nominal radio/DSP gain table indexes.
- * One for each channel group (a.k.a. "band") (1 for BG, 4 for A).
- * Tx power setup code interpolates between the 5 "sample" power levels
- *    to determine the nominal setup for a requested power level.
- * Data copied from EEPROM.
- * DO NOT ALTER THIS STRUCTURE!!!
- */
-struct iwl_eeprom_txpower_group {
-       struct iwl_eeprom_txpower_sample samples[5];    /* 5 power levels */
-       s32 a, b, c, d, e;      /* coefficients for voltage->power
-                                * formula (signed) */
-       s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on
-                                        * frequency (signed) */
-       s8 saturation_power;    /* highest power possible by h/w in this
-                                * band */
-       u8 group_channel;       /* "representative" channel # in this band */
-       s16 temperature;        /* h/w temperature at factory calib this band
-                                * (signed) */
-} __attribute__ ((packed));
-
-/*
- * Temperature-based Tx-power compensation data, not band-specific.
- * These coefficients are use to modify a/b/c/d/e coeffs based on
- *   difference between current temperature and factory calib temperature.
- * Data copied from EEPROM.
- */
-struct iwl_eeprom_temperature_corr {
-       u32 Ta;
-       u32 Tb;
-       u32 Tc;
-       u32 Td;
-       u32 Te;
-} __attribute__ ((packed));
-
-#if IWL == 4965
-#define EEPROM_TX_POWER_TX_CHAINS      (2)
-#define EEPROM_TX_POWER_BANDS          (8)
-#define EEPROM_TX_POWER_MEASUREMENTS   (3)
-#define EEPROM_TX_POWER_VERSION        (2)
-#define EEPROM_TX_POWER_VERSION_NEW    (5)
-
-struct iwl_eeprom_calib_measure {
-       u8 temperature;
-       u8 gain_idx;
-       u8 actual_pow;
-       s8 pa_det;
-} __attribute__ ((packed));
-
-struct iwl_eeprom_calib_ch_info {
-       u8 ch_num;
-       struct iwl_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS]
-               [EEPROM_TX_POWER_MEASUREMENTS];
-} __attribute__ ((packed));
-
-struct iwl_eeprom_calib_subband_info {
-       u8 ch_from;
-       u8 ch_to;
-       struct iwl_eeprom_calib_ch_info ch1;
-       struct iwl_eeprom_calib_ch_info ch2;
-} __attribute__ ((packed));
-
-struct iwl_eeprom_calib_info {
-       u8 saturation_power24;
-       u8 saturation_power52;
-       s16 voltage;            /* signed */
-       struct iwl_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS];
-} __attribute__ ((packed));
-
-#endif
-
-struct iwl_eeprom {
-       u8 reserved0[16];
-#define EEPROM_DEVICE_ID                    (2*0x08)   /* 2 bytes */
-       u16 device_id;  /* abs.ofs: 16 */
-       u8 reserved1[2];
-#define EEPROM_PMC                          (2*0x0A)   /* 2 bytes */
-       u16 pmc;                /* abs.ofs: 20 */
-       u8 reserved2[20];
-#define EEPROM_MAC_ADDRESS                  (2*0x15)   /* 6  bytes */
-       u8 mac_address[6];      /* abs.ofs: 42 */
-       u8 reserved3[58];
-#define EEPROM_BOARD_REVISION               (2*0x35)   /* 2  bytes */
-       u16 board_revision;     /* abs.ofs: 106 */
-       u8 reserved4[11];
-#define EEPROM_BOARD_PBA_NUMBER             (2*0x3B+1) /* 9  bytes */
-       u8 board_pba_number[9]; /* abs.ofs: 119 */
-       u8 reserved5[8];
-#define EEPROM_VERSION                      (2*0x44)   /* 2  bytes */
-       u16 version;            /* abs.ofs: 136 */
-#define EEPROM_SKU_CAP                      (2*0x45)   /* 1  bytes */
-       u8 sku_cap;             /* abs.ofs: 138 */
-#define EEPROM_LEDS_MODE                    (2*0x45+1) /* 1  bytes */
-       u8 leds_mode;           /* abs.ofs: 139 */
-#define EEPROM_OEM_MODE                     (2*0x46)   /* 2  bytes */
-       u16 oem_mode;
-#define EEPROM_WOWLAN_MODE                  (2*0x47)   /* 2  bytes */
-       u16 wowlan_mode;        /* abs.ofs: 142 */
-#define EEPROM_LEDS_TIME_INTERVAL           (2*0x48)   /* 2  bytes */
-       u16 leds_time_interval; /* abs.ofs: 144 */
-#define EEPROM_LEDS_OFF_TIME                (2*0x49)   /* 1  bytes */
-       u8 leds_off_time;       /* abs.ofs: 146 */
-#define EEPROM_LEDS_ON_TIME                 (2*0x49+1) /* 1  bytes */
-       u8 leds_on_time;        /* abs.ofs: 147 */
-#define EEPROM_ALMGOR_M_VERSION             (2*0x4A)   /* 1  bytes */
-       u8 almgor_m_version;    /* abs.ofs: 148 */
-#define EEPROM_ANTENNA_SWITCH_TYPE          (2*0x4A+1) /* 1  bytes */
-       u8 antenna_switch_type; /* abs.ofs: 149 */
-#if IWL == 3945
-       u8 reserved6[42];
-#else
-       u8 reserved6[8];
-#define EEPROM_4965_BOARD_REVISION          (2*0x4F)   /* 2 bytes */
-       u16 board_revision_4965;        /* abs.ofs: 158 */
-       u8 reserved7[13];
-#define EEPROM_4965_BOARD_PBA               (2*0x56+1) /* 9 bytes */
-       u8 board_pba_number_4965[9];    /* abs.ofs: 173 */
-       u8 reserved8[10];
-#endif
-#define EEPROM_REGULATORY_SKU_ID            (2*0x60)   /* 4  bytes */
-       u8 sku_id[4];           /* abs.ofs: 192 */
-#define EEPROM_REGULATORY_BAND_1            (2*0x62)   /* 2  bytes */
-       u16 band_1_count;       /* abs.ofs: 196 */
-#define EEPROM_REGULATORY_BAND_1_CHANNELS   (2*0x63)   /* 28 bytes */
-       struct iwl_eeprom_channel band_1_channels[14];  /* abs.ofs: 196 */
-#define EEPROM_REGULATORY_BAND_2            (2*0x71)   /* 2  bytes */
-       u16 band_2_count;       /* abs.ofs: 226 */
-#define EEPROM_REGULATORY_BAND_2_CHANNELS   (2*0x72)   /* 26 bytes */
-       struct iwl_eeprom_channel band_2_channels[13];  /* abs.ofs: 228 */
-#define EEPROM_REGULATORY_BAND_3            (2*0x7F)   /* 2  bytes */
-       u16 band_3_count;       /* abs.ofs: 254 */
-#define EEPROM_REGULATORY_BAND_3_CHANNELS   (2*0x80)   /* 24 bytes */
-       struct iwl_eeprom_channel band_3_channels[12];  /* abs.ofs: 256 */
-#define EEPROM_REGULATORY_BAND_4            (2*0x8C)   /* 2  bytes */
-       u16 band_4_count;       /* abs.ofs: 280 */
-#define EEPROM_REGULATORY_BAND_4_CHANNELS   (2*0x8D)   /* 22 bytes */
-       struct iwl_eeprom_channel band_4_channels[11];  /* abs.ofs: 282 */
-#define EEPROM_REGULATORY_BAND_5            (2*0x98)   /* 2  bytes */
-       u16 band_5_count;       /* abs.ofs: 304 */
-#define EEPROM_REGULATORY_BAND_5_CHANNELS   (2*0x99)   /* 12 bytes */
-       struct iwl_eeprom_channel band_5_channels[6];   /* abs.ofs: 306 */
-
-/* From here on out the EEPROM diverges between the 4965 and the 3945 */
-#if IWL == 3945
-
-       u8 reserved9[194];
-
-#define EEPROM_TXPOWER_CALIB_GROUP0 0x200
-#define EEPROM_TXPOWER_CALIB_GROUP1 0x240
-#define EEPROM_TXPOWER_CALIB_GROUP2 0x280
-#define EEPROM_TXPOWER_CALIB_GROUP3 0x2c0
-#define EEPROM_TXPOWER_CALIB_GROUP4 0x300
-#define IWL_NUM_TX_CALIB_GROUPS 5
-       struct iwl_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS];
-/* abs.ofs: 512 */
-#define EEPROM_CALIB_TEMPERATURE_CORRECT 0x340
-       struct iwl_eeprom_temperature_corr corrections; /* abs.ofs: 832 */
-       u8 reserved16[172];     /* fill out to full 1024 byte block */
-
-/* 4965AGN adds fat channel support */
-#elif IWL == 4965
-
-       u8 reserved10[2];
-#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0)        /* 14 bytes */
-       struct iwl_eeprom_channel band_24_channels[7];  /* abs.ofs: 320 */
-       u8 reserved11[2];
-#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8)        /* 22 bytes */
-       struct iwl_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */
-       u8 reserved12[6];
-#define EEPROM_CALIB_VERSION_OFFSET            (2*0xB6)        /* 2 bytes */
-       u16 calib_version;      /* abs.ofs: 364 */
-       u8 reserved13[2];
-#define EEPROM_SATURATION_POWER_OFFSET         (2*0xB8)        /* 2 bytes */
-       u16 satruation_power;   /* abs.ofs: 368 */
-       u8 reserved14[94];
-#define EEPROM_IWL_CALIB_TXPOWER_OFFSET        (2*0xE8)        /* 48  bytes */
-       struct iwl_eeprom_calib_info calib_info;        /* abs.ofs: 464 */
-
-       u8 reserved16[140];     /* fill out to full 1024 byte block */
-
-#endif
-
-} __attribute__ ((packed));
-
-#define IWL_EEPROM_IMAGE_SIZE 1024
-
-#endif
index e2a8d95ad9cd8a5eaa8e9beb13b807594d29a17d..cd2eb184831068c74d3318ab35681e326a6e849d 100644 (file)
@@ -252,4 +252,27 @@ static inline unsigned long elapsed_jiffies(unsigned long start,
        return end + (MAX_JIFFY_OFFSET - start);
 }
 
+static inline u8 iwl_get_dma_hi_address(dma_addr_t addr)
+{
+       return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0;
+}
+
+/* TODO: Move fw_desc functions to iwl-pci.ko */
+static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
+                                   struct fw_desc *desc)
+{
+       if (desc->v_addr)
+               pci_free_consistent(pci_dev, desc->len,
+                                   desc->v_addr, desc->p_addr);
+       desc->v_addr = NULL;
+       desc->len = 0;
+}
+
+static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
+                                   struct fw_desc *desc)
+{
+       desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr);
+       return (desc->v_addr != NULL) ? 0 : -ENOMEM;
+}
+
 #endif                         /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-hw.h b/drivers/net/wireless/iwlwifi/iwl-hw.h
deleted file mode 100644 (file)
index 1aa6fcd..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-/******************************************************************************
- *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral 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.GPL.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- * BSD LICENSE
- *
- * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
- * 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 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.
- *****************************************************************************/
-
-#ifndef        __iwlwifi_hw_h__
-#define __iwlwifi_hw_h__
-
-/*
- * This file defines hardware constants common to 3945 and 4965.
- *
- * Device-specific constants are defined in iwl-3945-hw.h and iwl-4965-hw.h,
- * although this file contains a few definitions for which the .c
- * implementation is the same for 3945 and 4965, except for the value of
- * a constant.
- *
- * uCode API constants are defined in iwl-commands.h.
- *
- * NOTE:  DO NOT PUT OS IMPLEMENTATION-SPECIFIC DECLARATIONS HERE
- *
- * The iwl-*hw.h (and files they include) files should remain OS/driver
- * implementation independent, declaring only the hardware interface.
- */
-
-/* uCode queue management definitions */
-#define IWL_CMD_QUEUE_NUM       4
-#define IWL_CMD_FIFO_NUM        4
-#define IWL_BACK_QUEUE_FIRST_ID 7
-
-/* Tx rates */
-#define IWL_CCK_RATES 4
-#define IWL_OFDM_RATES 8
-
-#if IWL == 3945
-#define IWL_HT_RATES 0
-#elif IWL == 4965
-#define IWL_HT_RATES 16
-#endif
-
-#define IWL_MAX_RATES  (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES)
-
-/* Time constants */
-#define SHORT_SLOT_TIME 9
-#define LONG_SLOT_TIME 20
-
-/* RSSI to dBm */
-#if IWL == 3945
-#define IWL_RSSI_OFFSET        95
-#elif IWL == 4965
-#define IWL_RSSI_OFFSET        44
-#endif
-
-#include "iwl-eeprom.h"
-#include "iwl-commands.h"
-
-#define PCI_LINK_CTRL      0x0F0
-#define PCI_POWER_SOURCE   0x0C8
-#define PCI_REG_WUM8       0x0E8
-#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT         (0x80000000)
-
-/*=== CSR (control and status registers) ===*/
-#define CSR_BASE    (0x000)
-
-#define CSR_SW_VER              (CSR_BASE+0x000)
-#define CSR_HW_IF_CONFIG_REG    (CSR_BASE+0x000) /* hardware interface config */
-#define CSR_INT_COALESCING      (CSR_BASE+0x004) /* accum ints, 32-usec units */
-#define CSR_INT                 (CSR_BASE+0x008) /* host interrupt status/ack */
-#define CSR_INT_MASK            (CSR_BASE+0x00c) /* host interrupt enable */
-#define CSR_FH_INT_STATUS       (CSR_BASE+0x010) /* busmaster int status/ack*/
-#define CSR_GPIO_IN             (CSR_BASE+0x018) /* read external chip pins */
-#define CSR_RESET               (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/
-#define CSR_GP_CNTRL            (CSR_BASE+0x024)
-#define CSR_HW_REV              (CSR_BASE+0x028)
-#define CSR_EEPROM_REG          (CSR_BASE+0x02c)
-#define CSR_EEPROM_GP           (CSR_BASE+0x030)
-#define CSR_GP_UCODE           (CSR_BASE+0x044)
-#define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
-#define CSR_UCODE_DRV_GP1_SET   (CSR_BASE+0x058)
-#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_CTL   (CSR_BASE+0x0A0)
-#define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
-#define CSR_ANA_PLL_CFG         (CSR_BASE+0x20c)
-#define CSR_HW_REV_WA_REG      (CSR_BASE+0x22C)
-
-/* HW I/F configuration */
-#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB         (0x00000100)
-#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM         (0x00000200)
-#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC            (0x00000400)
-#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE         (0x00000800)
-#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
-#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
-#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM     (0x00200000)
-
-/* 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_FH_TX        (1<<27) /* Tx DMA FH_INT[1:0] */
-#define CSR_INT_BIT_MAC_CLK_ACTV (1<<26) /* NIC controller's clock toggled on/off */
-#define CSR_INT_BIT_SW_ERR       (1<<25) /* uCode error */
-#define CSR_INT_BIT_RF_KILL      (1<<7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
-#define CSR_INT_BIT_CT_KILL      (1<<6)  /* Critical temp (chip too hot) rfkill */
-#define CSR_INT_BIT_SW_RX        (1<<3)  /* Rx, command responses, 3945 */
-#define CSR_INT_BIT_WAKEUP       (1<<1)  /* NIC controller waking up (pwr mgmt) */
-#define CSR_INT_BIT_ALIVE        (1<<0)  /* uCode interrupts once it initializes */
-
-#define CSR_INI_SET_MASK       (CSR_INT_BIT_FH_RX   | \
-                                CSR_INT_BIT_HW_ERR  | \
-                                CSR_INT_BIT_FH_TX   | \
-                                CSR_INT_BIT_SW_ERR  | \
-                                CSR_INT_BIT_RF_KILL | \
-                                CSR_INT_BIT_SW_RX   | \
-                                CSR_INT_BIT_WAKEUP  | \
-                                CSR_INT_BIT_ALIVE)
-
-/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
-#define CSR_FH_INT_BIT_ERR       (1<<31) /* Error */
-#define CSR_FH_INT_BIT_HI_PRIOR  (1<<30) /* High priority Rx, bypass coalescing */
-#define CSR_FH_INT_BIT_RX_CHNL2  (1<<18) /* Rx channel 2 (3945 only) */
-#define CSR_FH_INT_BIT_RX_CHNL1  (1<<17) /* Rx channel 1 */
-#define CSR_FH_INT_BIT_RX_CHNL0  (1<<16) /* Rx channel 0 */
-#define CSR_FH_INT_BIT_TX_CHNL6  (1<<6)  /* Tx channel 6 (3945 only) */
-#define CSR_FH_INT_BIT_TX_CHNL1  (1<<1)  /* Tx channel 1 */
-#define CSR_FH_INT_BIT_TX_CHNL0  (1<<0)  /* Tx channel 0 */
-
-#define CSR_FH_INT_RX_MASK     (CSR_FH_INT_BIT_HI_PRIOR | \
-                                CSR_FH_INT_BIT_RX_CHNL2 | \
-                                CSR_FH_INT_BIT_RX_CHNL1 | \
-                                CSR_FH_INT_BIT_RX_CHNL0)
-
-#define CSR_FH_INT_TX_MASK     (CSR_FH_INT_BIT_TX_CHNL6 | \
-                                CSR_FH_INT_BIT_TX_CHNL1 | \
-                                CSR_FH_INT_BIT_TX_CHNL0 )
-
-
-/* RESET */
-#define CSR_RESET_REG_FLAG_NEVO_RESET                (0x00000001)
-#define CSR_RESET_REG_FLAG_FORCE_NMI                 (0x00000002)
-#define CSR_RESET_REG_FLAG_SW_RESET                  (0x00000080)
-#define CSR_RESET_REG_FLAG_MASTER_DISABLED           (0x00000100)
-#define CSR_RESET_REG_FLAG_STOP_MASTER               (0x00000200)
-
-/* GP (general purpose) CONTROL */
-#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY        (0x00000001)
-#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE              (0x00000004)
-#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ         (0x00000008)
-#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP         (0x00000010)
-
-#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN           (0x00000001)
-
-#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE         (0x07000000)
-#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE         (0x04000000)
-#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW          (0x08000000)
-
-
-/* EEPROM REG */
-#define CSR_EEPROM_REG_READ_VALID_MSK  (0x00000001)
-#define CSR_EEPROM_REG_BIT_CMD         (0x00000002)
-
-/* EEPROM GP */
-#define CSR_EEPROM_GP_VALID_MSK                (0x00000006)
-#define CSR_EEPROM_GP_BAD_SIGNATURE    (0x00000000)
-#define CSR_EEPROM_GP_IF_OWNER_MSK     (0x00000180)
-
-/* UCODE DRV GP */
-#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP             (0x00000001)
-#define CSR_UCODE_SW_BIT_RFKILL                     (0x00000002)
-#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED           (0x00000004)
-#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT      (0x00000008)
-
-/* GPIO */
-#define CSR_GPIO_IN_BIT_AUX_POWER                   (0x00000200)
-#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC                (0x00000000)
-#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC          CSR_GPIO_IN_BIT_AUX_POWER
-
-/* GI Chicken Bits */
-#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX  (0x00800000)
-#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER  (0x20000000)
-
-/* CSR_ANA_PLL_CFG */
-#define CSR_ANA_PLL_CFG_SH             (0x00880300)
-
-#define CSR_LED_REG_TRUN_ON            (0x00000078)
-#define CSR_LED_REG_TRUN_OFF           (0x00000038)
-#define CSR_LED_BSM_CTRL_MSK           (0xFFFFFFDF)
-
-/* DRAM_INT_TBL_CTRL */
-#define CSR_DRAM_INT_TBL_CTRL_EN       (1<<31)
-#define CSR_DRAM_INT_TBL_CTRL_WRAP_CHK (1<<27)
-
-/*=== HBUS (Host-side Bus) ===*/
-#define HBUS_BASE      (0x400)
-
-#define HBUS_TARG_MEM_RADDR     (HBUS_BASE+0x00c)
-#define HBUS_TARG_MEM_WADDR     (HBUS_BASE+0x010)
-#define HBUS_TARG_MEM_WDAT      (HBUS_BASE+0x018)
-#define HBUS_TARG_MEM_RDAT      (HBUS_BASE+0x01c)
-#define HBUS_TARG_PRPH_WADDR    (HBUS_BASE+0x044)
-#define HBUS_TARG_PRPH_RADDR    (HBUS_BASE+0x048)
-#define HBUS_TARG_PRPH_WDAT     (HBUS_BASE+0x04c)
-#define HBUS_TARG_PRPH_RDAT     (HBUS_BASE+0x050)
-#define HBUS_TARG_WRPTR         (HBUS_BASE+0x060)
-
-#define HBUS_TARG_MBX_C         (HBUS_BASE+0x030)
-
-
-/* SCD (Scheduler) */
-#define SCD_BASE                        (CSR_BASE + 0x2E00)
-
-#define SCD_MODE_REG                    (SCD_BASE + 0x000)
-#define SCD_ARASTAT_REG                 (SCD_BASE + 0x004)
-#define SCD_TXFACT_REG                  (SCD_BASE + 0x010)
-#define SCD_TXF4MF_REG                  (SCD_BASE + 0x014)
-#define SCD_TXF5MF_REG                  (SCD_BASE + 0x020)
-#define SCD_SBYP_MODE_1_REG             (SCD_BASE + 0x02C)
-#define SCD_SBYP_MODE_2_REG             (SCD_BASE + 0x030)
-
-/*=== FH (data Flow Handler) ===*/
-#define FH_BASE     (0x800)
-
-#define FH_CBCC_TABLE           (FH_BASE+0x140)
-#define FH_TFDB_TABLE           (FH_BASE+0x180)
-#define FH_RCSR_TABLE           (FH_BASE+0x400)
-#define FH_RSSR_TABLE           (FH_BASE+0x4c0)
-#define FH_TCSR_TABLE           (FH_BASE+0x500)
-#define FH_TSSR_TABLE           (FH_BASE+0x680)
-
-/* TFDB (Transmit Frame Buffer Descriptor) */
-#define FH_TFDB(_channel, buf) \
-       (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28)
-#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \
-       (FH_TFDB_TABLE + 0x50 * _channel)
-/* CBCC _channel is [0,2] */
-#define FH_CBCC(_channel)           (FH_CBCC_TABLE+(_channel)*0x8)
-#define FH_CBCC_CTRL(_channel)      (FH_CBCC(_channel)+0x00)
-#define FH_CBCC_BASE(_channel)      (FH_CBCC(_channel)+0x04)
-
-/* RCSR _channel is [0,2] */
-#define FH_RCSR(_channel)           (FH_RCSR_TABLE+(_channel)*0x40)
-#define FH_RCSR_CONFIG(_channel)    (FH_RCSR(_channel)+0x00)
-#define FH_RCSR_RBD_BASE(_channel)  (FH_RCSR(_channel)+0x04)
-#define FH_RCSR_WPTR(_channel)      (FH_RCSR(_channel)+0x20)
-#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24)
-
-#if IWL == 3945
-#define FH_RSCSR_CHNL0_WPTR        (FH_RCSR_WPTR(0))
-#elif IWL == 4965
-#define FH_RSCSR_CHNL0_WPTR        (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)
-#endif
-
-/* RSSR */
-#define FH_RSSR_CTRL            (FH_RSSR_TABLE+0x000)
-#define FH_RSSR_STATUS          (FH_RSSR_TABLE+0x004)
-/* TCSR */
-#define FH_TCSR(_channel)           (FH_TCSR_TABLE+(_channel)*0x20)
-#define FH_TCSR_CONFIG(_channel)    (FH_TCSR(_channel)+0x00)
-#define FH_TCSR_CREDIT(_channel)    (FH_TCSR(_channel)+0x04)
-#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08)
-/* TSSR */
-#define FH_TSSR_CBB_BASE        (FH_TSSR_TABLE+0x000)
-#define FH_TSSR_MSG_CONFIG      (FH_TSSR_TABLE+0x008)
-#define FH_TSSR_TX_STATUS       (FH_TSSR_TABLE+0x010)
-/* 18 - reserved */
-
-/* card static random access memory (SRAM) for processor data and instructs */
-#define RTC_INST_LOWER_BOUND                   (0x000000)
-#define RTC_DATA_LOWER_BOUND                   (0x800000)
-
-
-/* DBM */
-
-#define ALM_FH_SRVC_CHNL                            (6)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE     (20)
-#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH      (4)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN    (0x08000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE        (0x80000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE           (0x20000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128         (0x01000000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST         (0x00001000)
-
-#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH               (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF              (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER           (0x00000001)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL    (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL     (0x00000008)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD           (0x00200000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT            (0x00000000)
-
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE            (0x00000000)
-#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE           (0x80000000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID          (0x00004000)
-
-#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR           (0x00000001)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON      (0xFF000000)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON      (0x00FF0000)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B    (0x00000400)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON       (0x00000100)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON       (0x00000080)
-
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH     (0x00000020)
-#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH           (0x00000005)
-
-#define ALM_TB_MAX_BYTES_COUNT      (0xFFF0)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \
-       ((1LU << _channel) << 24)
-#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \
-       ((1LU << _channel) << 16)
-
-#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \
-       (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \
-        ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel))
-#define PCI_CFG_REV_ID_BIT_BASIC_SKU                (0x40)     /* bit 6    */
-#define PCI_CFG_REV_ID_BIT_RTP                      (0x80)     /* bit 7    */
-
-#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED         (0x00000004)
-
-#define TFD_QUEUE_MIN           0
-#define TFD_QUEUE_MAX           6
-#define TFD_QUEUE_SIZE_MAX      (256)
-
-/* spectrum and channel data structures */
-#define IWL_NUM_SCAN_RATES         (2)
-
-#define IWL_SCAN_FLAG_24GHZ  (1<<0)
-#define IWL_SCAN_FLAG_52GHZ  (1<<1)
-#define IWL_SCAN_FLAG_ACTIVE (1<<2)
-#define IWL_SCAN_FLAG_DIRECT (1<<3)
-
-#define IWL_MAX_CMD_SIZE 1024
-
-#define IWL_DEFAULT_TX_RETRY  15
-#define IWL_MAX_TX_RETRY      16
-
-/*********************************************/
-
-#define RFD_SIZE                              4
-#define NUM_TFD_CHUNKS                        4
-
-#define RX_QUEUE_SIZE                         256
-#define RX_QUEUE_MASK                         255
-#define RX_QUEUE_SIZE_LOG                     8
-
-/* QoS  definitions */
-
-#define CW_MIN_OFDM          15
-#define CW_MAX_OFDM          1023
-#define CW_MIN_CCK           31
-#define CW_MAX_CCK           1023
-
-#define QOS_TX0_CW_MIN_OFDM      CW_MIN_OFDM
-#define QOS_TX1_CW_MIN_OFDM      CW_MIN_OFDM
-#define QOS_TX2_CW_MIN_OFDM      ((CW_MIN_OFDM + 1) / 2 - 1)
-#define QOS_TX3_CW_MIN_OFDM      ((CW_MIN_OFDM + 1) / 4 - 1)
-
-#define QOS_TX0_CW_MIN_CCK       CW_MIN_CCK
-#define QOS_TX1_CW_MIN_CCK       CW_MIN_CCK
-#define QOS_TX2_CW_MIN_CCK       ((CW_MIN_CCK + 1) / 2 - 1)
-#define QOS_TX3_CW_MIN_CCK       ((CW_MIN_CCK + 1) / 4 - 1)
-
-#define QOS_TX0_CW_MAX_OFDM      CW_MAX_OFDM
-#define QOS_TX1_CW_MAX_OFDM      CW_MAX_OFDM
-#define QOS_TX2_CW_MAX_OFDM      CW_MIN_OFDM
-#define QOS_TX3_CW_MAX_OFDM      ((CW_MIN_OFDM + 1) / 2 - 1)
-
-#define QOS_TX0_CW_MAX_CCK       CW_MAX_CCK
-#define QOS_TX1_CW_MAX_CCK       CW_MAX_CCK
-#define QOS_TX2_CW_MAX_CCK       CW_MIN_CCK
-#define QOS_TX3_CW_MAX_CCK       ((CW_MIN_CCK + 1) / 2 - 1)
-
-#define QOS_TX0_AIFS            3
-#define QOS_TX1_AIFS            7
-#define QOS_TX2_AIFS            2
-#define QOS_TX3_AIFS            2
-
-#define QOS_TX0_ACM             0
-#define QOS_TX1_ACM             0
-#define QOS_TX2_ACM             0
-#define QOS_TX3_ACM             0
-
-#define QOS_TX0_TXOP_LIMIT_CCK          0
-#define QOS_TX1_TXOP_LIMIT_CCK          0
-#define QOS_TX2_TXOP_LIMIT_CCK          6016
-#define QOS_TX3_TXOP_LIMIT_CCK          3264
-
-#define QOS_TX0_TXOP_LIMIT_OFDM      0
-#define QOS_TX1_TXOP_LIMIT_OFDM      0
-#define QOS_TX2_TXOP_LIMIT_OFDM      3008
-#define QOS_TX3_TXOP_LIMIT_OFDM      1504
-
-#define DEF_TX0_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX1_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX2_CW_MIN_OFDM      CW_MIN_OFDM
-#define DEF_TX3_CW_MIN_OFDM      CW_MIN_OFDM
-
-#define DEF_TX0_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX1_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX2_CW_MIN_CCK       CW_MIN_CCK
-#define DEF_TX3_CW_MIN_CCK       CW_MIN_CCK
-
-#define DEF_TX0_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX1_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX2_CW_MAX_OFDM      CW_MAX_OFDM
-#define DEF_TX3_CW_MAX_OFDM      CW_MAX_OFDM
-
-#define DEF_TX0_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX1_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX2_CW_MAX_CCK       CW_MAX_CCK
-#define DEF_TX3_CW_MAX_CCK       CW_MAX_CCK
-
-#define DEF_TX0_AIFS            (2)
-#define DEF_TX1_AIFS            (2)
-#define DEF_TX2_AIFS            (2)
-#define DEF_TX3_AIFS            (2)
-
-#define DEF_TX0_ACM             0
-#define DEF_TX1_ACM             0
-#define DEF_TX2_ACM             0
-#define DEF_TX3_ACM             0
-
-#define DEF_TX0_TXOP_LIMIT_CCK        0
-#define DEF_TX1_TXOP_LIMIT_CCK        0
-#define DEF_TX2_TXOP_LIMIT_CCK        0
-#define DEF_TX3_TXOP_LIMIT_CCK        0
-
-#define DEF_TX0_TXOP_LIMIT_OFDM       0
-#define DEF_TX1_TXOP_LIMIT_OFDM       0
-#define DEF_TX2_TXOP_LIMIT_OFDM       0
-#define DEF_TX3_TXOP_LIMIT_OFDM       0
-
-#define QOS_QOS_SETS                  3
-#define QOS_PARAM_SET_ACTIVE          0
-#define QOS_PARAM_SET_DEF_CCK         1
-#define QOS_PARAM_SET_DEF_OFDM        2
-
-#define CTRL_QOS_NO_ACK               (0x0020)
-#define DCT_FLAG_EXT_QOS_ENABLED      (0x10)
-
-#define U32_PAD(n)             ((4-(n))&0x3)
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-#define TFD_CTL_COUNT_SET(n)       (n<<24)
-#define TFD_CTL_COUNT_GET(ctl)     ((ctl>>24) & 7)
-#define TFD_CTL_PAD_SET(n)         (n<<28)
-#define TFD_CTL_PAD_GET(ctl)       (ctl>>28)
-
-#define TFD_TX_CMD_SLOTS 256
-#define TFD_CMD_SLOTS 32
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
-                             sizeof(struct iwl_cmd_meta))
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-#endif                         /* __iwlwifi_hw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
deleted file mode 100644 (file)
index 8a8b96f..0000000
+++ /dev/null
@@ -1,470 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project.
- *
- * 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:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_io_h__
-#define __iwl_io_h__
-
-#include <linux/io.h>
-
-#include "iwl-debug.h"
-
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * (in the case of *restricted calls) and the current line number is printed
- * in addition to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's __LINE__ to the double prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl_read_restricted calls the non-check version of
- * _iwl_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguring of the hardware I/O.  In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-#define _iwl_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *iwl,
-                                u32 ofs, u32 val)
-{
-       IWL_DEBUG_IO("write_direct32(0x%08X, 0x%08X) - %s %d\n",
-                    (u32) (ofs), (u32) (val), f, l);
-       _iwl_write32(iwl, ofs, val);
-}
-#define iwl_write32(iwl, ofs, val) \
-       __iwl_write32(__FILE__, __LINE__, iwl, ofs, val)
-#else
-#define iwl_write32(iwl, ofs, val) _iwl_write32(iwl, ofs, val)
-#endif
-
-#define _iwl_read32(iwl, ofs) readl((iwl)->hw_base + (ofs))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *iwl, u32 ofs)
-{
-       IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
-       return _iwl_read32(iwl, ofs);
-}
-#define iwl_read32(iwl, ofs) __iwl_read32(__FILE__, __LINE__, iwl, ofs)
-#else
-#define iwl_read32(p, o) _iwl_read32(p, o)
-#endif
-
-static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
-                               u32 bits, u32 mask, int timeout)
-{
-       int i = 0;
-
-       do {
-               if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
-                       return i;
-               mdelay(10);
-               i += 10;
-       } while (i < timeout);
-
-       return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_bit(const char *f, u32 l,
-                                struct iwl_priv *priv, u32 addr,
-                                u32 bits, u32 mask, int timeout)
-{
-       int rc = _iwl_poll_bit(priv, addr, bits, mask, timeout);
-       if (unlikely(rc == -ETIMEDOUT))
-               IWL_DEBUG_IO
-                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n",
-                    addr, bits, mask, f, l);
-       else
-               IWL_DEBUG_IO
-                   ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n",
-                    addr, bits, mask, rc, f, l);
-       return rc;
-}
-#define iwl_poll_bit(iwl, addr, bits, mask, timeout) \
-       __iwl_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout)
-#else
-#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
-       _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bit(const char *f, u32 l,
-                                struct iwl_priv *priv, u32 reg, u32 mask)
-{
-       u32 val = _iwl_read32(priv, reg) | mask;
-       IWL_DEBUG_IO("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)
-#else
-#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m)
-#endif
-
-static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
-       _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_clear_bit(const char *f, u32 l,
-                                  struct iwl_priv *priv, u32 reg, u32 mask)
-{
-       u32 val = _iwl_read32(priv, reg) & ~mask;
-       IWL_DEBUG_IO("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)
-#else
-#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m)
-#endif
-
-static inline int _iwl_grab_restricted_access(struct iwl_priv *priv)
-{
-       int rc;
-       u32 gp_ctl;
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (atomic_read(&priv->restrict_refcnt))
-               return 0;
-#endif
-       if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
-           test_bit(STATUS_RF_KILL_SW, &priv->status)) {
-               IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
-                       "wakes up NIC\n");
-
-               /* 10 msec allows time for NIC to complete its data save */
-               gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL);
-               if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
-                       IWL_DEBUG_RF_KILL("Wait for complete power-down, "
-                               "gpctl = 0x%08x\n", gp_ctl);
-                       mdelay(10);
-               } else
-                       IWL_DEBUG_RF_KILL("power-down complete, "
-                                         "gpctl = 0x%08x\n", gp_ctl);
-       }
-
-       /* this bit wakes up the NIC */
-       _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-       rc = _iwl_poll_bit(priv, CSR_GP_CNTRL,
-                          CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
-                          (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-                           CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50);
-       if (rc < 0) {
-               IWL_ERROR("MAC is in deep sleep!\n");
-               return -EIO;
-       }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       atomic_inc(&priv->restrict_refcnt);
-#endif
-       return 0;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_grab_restricted_access(const char *f, u32 l,
-                                              struct iwl_priv *priv)
-{
-       if (atomic_read(&priv->restrict_refcnt))
-               IWL_DEBUG_INFO("Grabbing access while already held at "
-                              "line %d.\n", l);
-
-       IWL_DEBUG_IO("grabbing restricted access - %s %d\n", f, l);
-
-       return _iwl_grab_restricted_access(priv);
-}
-#define iwl_grab_restricted_access(priv) \
-       __iwl_grab_restricted_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_grab_restricted_access(priv) \
-       _iwl_grab_restricted_access(priv)
-#endif
-
-static inline void _iwl_release_restricted_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);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_release_restricted_access(const char *f, u32 l,
-                                                  struct iwl_priv *priv)
-{
-       if (atomic_read(&priv->restrict_refcnt) <= 0)
-               IWL_ERROR("Release unheld restricted access at line %d.\n", l);
-
-       IWL_DEBUG_IO("releasing restricted access - %s %d\n", f, l);
-       _iwl_release_restricted_access(priv);
-}
-#define iwl_release_restricted_access(priv) \
-       __iwl_release_restricted_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_release_restricted_access(priv) \
-       _iwl_release_restricted_access(priv)
-#endif
-
-static inline u32 _iwl_read_restricted(struct iwl_priv *priv, u32 reg)
-{
-       return _iwl_read32(priv, reg);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_restricted(const char *f, u32 l,
-                                       struct iwl_priv *priv, u32 reg)
-{
-       u32 value = _iwl_read_restricted(priv, reg);
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from %s %d\n", f, l);
-       IWL_DEBUG_IO("read_restricted(0x%4X) = 0x%08x - %s %d \n", reg, value,
-                    f, l);
-       return value;
-}
-#define iwl_read_restricted(priv, reg) \
-       __iwl_read_restricted(__FILE__, __LINE__, priv, reg)
-#else
-#define iwl_read_restricted _iwl_read_restricted
-#endif
-
-static inline void _iwl_write_restricted(struct iwl_priv *priv,
-                                        u32 reg, u32 value)
-{
-       _iwl_write32(priv, reg, value);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void __iwl_write_restricted(u32 line,
-                                  struct iwl_priv *priv, u32 reg, u32 value)
-{
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from line %d\n", line);
-       _iwl_write_restricted(priv, reg, value);
-}
-#define iwl_write_restricted(priv, reg, value) \
-       __iwl_write_restricted(__LINE__, priv, reg, value)
-#else
-#define iwl_write_restricted _iwl_write_restricted
-#endif
-
-static inline void iwl_write_buffer_restricted(struct iwl_priv *priv,
-                                              u32 reg, u32 len, u32 *values)
-{
-       u32 count = sizeof(u32);
-
-       if ((priv != NULL) && (values != NULL)) {
-               for (; 0 < len; len -= count, reg += count, values++)
-                       _iwl_write_restricted(priv, reg, *values);
-       }
-}
-
-static inline int _iwl_poll_restricted_bit(struct iwl_priv *priv,
-                                          u32 addr, u32 mask, int timeout)
-{
-       int i = 0;
-
-       do {
-               if ((_iwl_read_restricted(priv, addr) & mask) == mask)
-                       return i;
-               mdelay(10);
-               i += 10;
-       } while (i < timeout);
-
-       return -ETIMEDOUT;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_restricted_bit(const char *f, u32 l,
-                                           struct iwl_priv *priv,
-                                           u32 addr, u32 mask, int timeout)
-{
-       int rc = _iwl_poll_restricted_bit(priv, addr, mask, timeout);
-
-       if (unlikely(rc == -ETIMEDOUT))
-               IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) - "
-                            "timedout - %s %d\n", addr, mask, f, l);
-       else
-               IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) = 0x%08X "
-                            "- %s %d\n", addr, mask, rc, f, l);
-       return rc;
-}
-#define iwl_poll_restricted_bit(iwl, addr, mask, timeout) \
-       __iwl_poll_restricted_bit(__FILE__, __LINE__, iwl, addr, mask, timeout)
-#else
-#define iwl_poll_restricted_bit _iwl_poll_restricted_bit
-#endif
-
-static inline u32 _iwl_read_restricted_reg(struct iwl_priv *priv, u32 reg)
-{
-       _iwl_write_restricted(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-       return _iwl_read_restricted(priv, HBUS_TARG_PRPH_RDAT);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_restricted_reg(u32 line,
-                                           struct iwl_priv *priv, u32 reg)
-{
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from line %d\n", line);
-       return _iwl_read_restricted_reg(priv, reg);
-}
-
-#define iwl_read_restricted_reg(priv, reg) \
-       __iwl_read_restricted_reg(__LINE__, priv, reg)
-#else
-#define iwl_read_restricted_reg _iwl_read_restricted_reg
-#endif
-
-static inline void _iwl_write_restricted_reg(struct iwl_priv *priv,
-                                            u32 addr, u32 val)
-{
-       _iwl_write_restricted(priv, HBUS_TARG_PRPH_WADDR,
-                             ((addr & 0x0000FFFF) | (3 << 24)));
-       _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write_restricted_reg(u32 line,
-                                             struct iwl_priv *priv,
-                                             u32 addr, u32 val)
-{
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from line %d\n", line);
-       _iwl_write_restricted_reg(priv, addr, val);
-}
-
-#define iwl_write_restricted_reg(priv, addr, val) \
-       __iwl_write_restricted_reg(__LINE__, priv, addr, val);
-#else
-#define iwl_write_restricted_reg _iwl_write_restricted_reg
-#endif
-
-#define _iwl_set_bits_restricted_reg(priv, reg, mask) \
-       _iwl_write_restricted_reg(priv, reg, \
-                                 (_iwl_read_restricted_reg(priv, reg) | mask))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_restricted_reg(u32 line, struct iwl_priv
-                                                *priv, u32 reg, u32 mask)
-{
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from line %d\n", line);
-       _iwl_set_bits_restricted_reg(priv, reg, mask);
-}
-#define iwl_set_bits_restricted_reg(priv, reg, mask) \
-       __iwl_set_bits_restricted_reg(__LINE__, priv, reg, mask)
-#else
-#define iwl_set_bits_restricted_reg _iwl_set_bits_restricted_reg
-#endif
-
-#define _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \
-       _iwl_write_restricted_reg( \
-           priv, reg, ((_iwl_read_restricted_reg(priv, reg) & mask) | bits))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_mask_restricted_reg(u32 line,
-               struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
-{
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERROR("Unrestricted access from line %d\n", line);
-       _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask);
-}
-
-#define iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \
-       __iwl_set_bits_mask_restricted_reg(__LINE__, priv, reg, bits, mask)
-#else
-#define iwl_set_bits_mask_restricted_reg _iwl_set_bits_mask_restricted_reg
-#endif
-
-static inline void iwl_clear_bits_restricted_reg(struct iwl_priv
-                                                *priv, u32 reg, u32 mask)
-{
-       u32 val = _iwl_read_restricted_reg(priv, reg);
-       _iwl_write_restricted_reg(priv, reg, (val & ~mask));
-}
-
-static inline u32 iwl_read_restricted_mem(struct iwl_priv *priv, u32 addr)
-{
-       iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, addr);
-       return iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
-}
-
-static inline void iwl_write_restricted_mem(struct iwl_priv *priv, u32 addr,
-                                           u32 val)
-{
-       iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
-       iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, val);
-}
-
-static inline void iwl_write_restricted_mems(struct iwl_priv *priv, u32 addr,
-                                            u32 len, u32 *values)
-{
-       iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr);
-       for (; 0 < len; len -= sizeof(u32), values++)
-               iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, *values);
-}
-
-static inline void iwl_write_restricted_regs(struct iwl_priv *priv, u32 reg,
-                                            u32 len, u8 *values)
-{
-       u32 reg_offset = reg;
-       u32 aligment = reg & 0x3;
-
-       /* write any non-dword-aligned stuff at the beginning */
-       if (len < sizeof(u32)) {
-               if ((aligment + len) <= sizeof(u32)) {
-                       u8 size;
-                       u32 value = 0;
-                       size = len - 1;
-                       memcpy(&value, values, len);
-                       reg_offset = (reg_offset & 0x0000FFFF);
-
-                       _iwl_write_restricted(priv,
-                                             HBUS_TARG_PRPH_WADDR,
-                                             (reg_offset | (size << 24)));
-                       _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT,
-                                             value);
-               }
-
-               return;
-       }
-
-       /* now write all the dword-aligned stuff */
-       for (; reg_offset < (reg + len);
-            reg_offset += sizeof(u32), values += sizeof(u32))
-               _iwl_write_restricted_reg(priv, reg_offset, *((u32 *) values));
-}
-
-#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-priv.h b/drivers/net/wireless/iwlwifi/iwl-priv.h
deleted file mode 100644 (file)
index 6b490d0..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
- *
- * 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:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_priv_h__
-#define __iwl_priv_h__
-
-#include <linux/workqueue.h>
-
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
-
-enum {
-       MEASUREMENT_READY = (1 << 0),
-       MEASUREMENT_ACTIVE = (1 << 1),
-};
-
-#endif
-
-struct iwl_priv {
-
-       /* ieee device used by generic ieee processing code */
-       struct ieee80211_hw *hw;
-       struct ieee80211_channel *ieee_channels;
-       struct ieee80211_rate *ieee_rates;
-
-       /* temporary frame storage list */
-       struct list_head free_frames;
-       int frames_count;
-
-       u8 phymode;
-       int alloc_rxb_skb;
-
-       void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb);
-
-       const struct ieee80211_hw_mode *modes;
-
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
-       /* spectrum measurement report caching */
-       struct iwl_spectrum_notification measure_report;
-       u8 measurement_status;
-#endif
-       /* ucode beacon time */
-       u32 ucode_beacon_time;
-
-       /* we allocate array of iwl_channel_info for NIC's valid channels.
-        *    Access via channel # using indirect index array */
-       struct iwl_channel_info *channel_info;  /* channel info array */
-       u8 channel_count;       /* # of channels */
-
-       /* each calibration channel group in the EEPROM has a derived
-        * clip setting for each rate. */
-       const struct iwl_clip_group clip_groups[5];
-
-       /* thermal calibration */
-       s32 temperature;        /* degrees Kelvin */
-       s32 last_temperature;
-
-       /* Scan related variables */
-       unsigned long last_scan_jiffies;
-       unsigned long scan_start;
-       unsigned long scan_pass_start;
-       unsigned long scan_start_tsf;
-       int scan_bands;
-       int one_direct_scan;
-       u8 direct_ssid_len;
-       u8 direct_ssid[IW_ESSID_MAX_SIZE];
-       struct iwl_scan_cmd *scan;
-       u8 only_active_channel;
-
-       /* spinlock */
-       spinlock_t lock;        /* protect general shared data */
-       spinlock_t hcmd_lock;   /* protect hcmd */
-       struct mutex mutex;
-
-       /* basic pci-network driver stuff */
-       struct pci_dev *pci_dev;
-
-       /* pci hardware address support */
-       void __iomem *hw_base;
-
-       /* uCode images, save to reload in case of failure */
-       struct fw_image_desc ucode_code;        /* runtime inst */
-       struct fw_image_desc ucode_data;        /* runtime data original */
-       struct fw_image_desc ucode_data_backup; /* runtime data save/restore */
-       struct fw_image_desc ucode_init;        /* initialization inst */
-       struct fw_image_desc ucode_init_data;   /* initialization data */
-       struct fw_image_desc ucode_boot;        /* bootstrap inst */
-
-
-       struct iwl_rxon_time_cmd rxon_timing;
-
-       /* We declare this const so it can only be
-        * changed via explicit cast within the
-        * routines that actually update the physical
-        * hardware */
-       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;
-
-#ifdef LED
-       /* LED related variables */
-       struct iwl_activity_blink activity;
-       unsigned long led_packets;
-       int led_state;
-#endif
-
-       u16 active_rate;
-       u16 active_rate_basic;
-
-       u8 call_post_assoc_from_beacon;
-       u8 assoc_station_added;
-#if IWL == 4965
-       u8 use_ant_b_for_management_frame;      /* Tx antenna selection */
-       /* HT variables */
-       u8 is_dup;
-       u8 is_ht_enabled;
-       u8 channel_width;       /* 0=20MHZ, 1=40MHZ */
-       u8 current_channel_width;
-       u8 valid_antenna;       /* Bit mask of antennas actually connected */
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
-       struct iwl_sensitivity_data sensitivity_data;
-       struct iwl_chain_noise_data chain_noise_data;
-       u8 start_calib;
-       __le16 sensitivity_tbl[HD_TABLE_SIZE];
-#endif /*CONFIG_IWLWIFI_SENSITIVITY*/
-
-#ifdef CONFIG_IWLWIFI_HT
-       struct sta_ht_info current_assoc_ht;
-#endif
-       u8 active_rate_ht[2];
-       u8 last_phy_res[100];
-
-       /* Rate scaling data */
-       struct iwl_lq_mngr lq_mngr;
-#endif
-
-       /* Rate scaling data */
-       s8 data_retry_limit;
-       u8 retry_rate;
-
-       wait_queue_head_t wait_command_queue;
-
-       int activity_timer_active;
-
-       /* Rx and Tx DMA processing queues */
-       struct iwl_rx_queue rxq;
-       struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES];
-#if IWL == 4965
-       unsigned long txq_ctx_active_msk;
-       struct iwl_kw kw;       /* keep warm address */
-       u32 scd_base_addr;      /* scheduler sram base address */
-#endif
-
-       unsigned long status;
-       u32 config;
-
-       int last_rx_rssi;       /* From Rx packet statisitics */
-       int last_rx_noise;      /* From beacon statistics */
-
-       struct iwl_power_mgr power_data;
-
-       struct iwl_notif_statistics statistics;
-       unsigned long last_statistics_time;
-
-       /* context information */
-       u8 essid[IW_ESSID_MAX_SIZE];
-       u8 essid_len;
-       u16 rates_mask;
-
-       u32 power_mode;
-       u32 antenna;
-       u8 bssid[ETH_ALEN];
-       u16 rts_threshold;
-       u8 mac_addr[ETH_ALEN];
-
-       /*station table variables */
-       spinlock_t sta_lock;
-       int num_stations;
-       struct iwl_station_entry stations[IWL_STATION_COUNT];
-
-       /* Indication if ieee80211_ops->open has been called */
-       int is_open;
-
-       u8 mac80211_registered;
-       int is_abg;
-
-       u32 notif_missed_beacons;
-
-       /* Rx'd packet timing information */
-       u32 last_beacon_time;
-       u64 last_tsf;
-
-       /* Duplicate packet detection */
-       u16 last_seq_num;
-       u16 last_frag_num;
-       unsigned long last_packet_time;
-       struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
-
-       /* eeprom */
-       struct iwl_eeprom eeprom;
-
-       int iw_mode;
-
-       struct sk_buff *ibss_beacon;
-
-       /* Last Rx'd beacon timestamp */
-       u32 timestamp0;
-       u32 timestamp1;
-       u16 beacon_int;
-       struct iwl_driver_hw_info hw_setting;
-       int interface_id;
-
-       /* Current association information needed to configure the
-        * hardware */
-       u16 assoc_id;
-       u16 assoc_capability;
-       u8 ps_mode;
-
-#ifdef CONFIG_IWLWIFI_QOS
-       struct iwl_qos_info qos_data;
-#endif /*CONFIG_IWLWIFI_QOS */
-
-       struct workqueue_struct *workqueue;
-
-       struct work_struct up;
-       struct work_struct restart;
-       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;
-       struct work_struct report_work;
-       struct work_struct request_scan;
-       struct work_struct beacon_update;
-
-       struct tasklet_struct irq_tasklet;
-
-       struct delayed_work init_alive_start;
-       struct delayed_work alive_start;
-       struct delayed_work activity_timer;
-       struct delayed_work thermal_periodic;
-       struct delayed_work gather_stats;
-       struct delayed_work scan_check;
-       struct delayed_work post_associate;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
-       s8 user_txpower_limit;
-       s8 max_channel_txpower_limit;
-       u32 cck_power_index_compensation;
-
-#ifdef CONFIG_PM
-       u32 pm_state[16];
-#endif
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       /* debugging info */
-       u32 framecnt_to_us;
-       atomic_t restrict_refcnt;
-#endif
-
-#if IWL == 4965
-       struct work_struct txpower_work;
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
-       struct work_struct sensitivity_work;
-#endif
-       struct work_struct statistics_work;
-       struct timer_list statistics_periodic;
-
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       struct work_struct agg_work;
-#endif
-
-#endif /* 4965 */
-};                             /*iwl_priv */
-
-#endif /* __iwl_priv_h__ */
index 0df41148eadc0b7ec3b983ae01f675efbabfe8da..4ba121634877ca268cb33f9bb116c1b09ef4a252 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2005 - 2007 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of version 2 of the GNU Geeral Public License as
+ * 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
 #ifndef        __iwl_prph_h__
 #define __iwl_prph_h__
 
-
+/*
+ * Registers in this file are internal, not PCI bus memory mapped.
+ * Driver accesses these via HBUS_TARG_PRPH_* registers.
+ */
 #define PRPH_BASE      (0x00000)
 #define PRPH_END       (0xFFFFF)
 
 #define BSM_SRAM_SIZE                  (1024) /* bytes */
 
 
+/* 3945 Tx scheduler registers */
+#define ALM_SCD_BASE                        (PRPH_BASE + 0x2E00)
+#define ALM_SCD_MODE_REG                    (ALM_SCD_BASE + 0x000)
+#define ALM_SCD_ARASTAT_REG                 (ALM_SCD_BASE + 0x004)
+#define ALM_SCD_TXFACT_REG                  (ALM_SCD_BASE + 0x010)
+#define ALM_SCD_TXF4MF_REG                  (ALM_SCD_BASE + 0x014)
+#define ALM_SCD_TXF5MF_REG                  (ALM_SCD_BASE + 0x020)
+#define ALM_SCD_SBYP_MODE_1_REG             (ALM_SCD_BASE + 0x02C)
+#define ALM_SCD_SBYP_MODE_2_REG             (ALM_SCD_BASE + 0x030)
+
+/*
+ * 4965 Tx Scheduler registers.
+ * Details are documented in iwl-4965-hw.h
+ */
+#define KDR_SCD_BASE           (PRPH_BASE + 0xa02c00)
+
+#define KDR_SCD_SRAM_BASE_ADDR         (KDR_SCD_BASE + 0x0)
+#define KDR_SCD_EMPTY_BITS             (KDR_SCD_BASE + 0x4)
+#define KDR_SCD_DRAM_BASE_ADDR         (KDR_SCD_BASE + 0x10)
+#define KDR_SCD_AIT                    (KDR_SCD_BASE + 0x18)
+#define KDR_SCD_TXFACT                 (KDR_SCD_BASE + 0x1c)
+#define KDR_SCD_QUEUE_WRPTR(x)         (KDR_SCD_BASE + 0x24 + (x) * 4)
+#define KDR_SCD_QUEUE_RDPTR(x)         (KDR_SCD_BASE + 0x64 + (x) * 4)
+#define KDR_SCD_SETQUEUENUM            (KDR_SCD_BASE + 0xa4)
+#define KDR_SCD_SET_TXSTAT_TXED        (KDR_SCD_BASE + 0xa8)
+#define KDR_SCD_SET_TXSTAT_DONE        (KDR_SCD_BASE + 0xac)
+#define KDR_SCD_SET_TXSTAT_NOT_SCHD    (KDR_SCD_BASE + 0xb0)
+#define KDR_SCD_DECREASE_CREDIT        (KDR_SCD_BASE + 0xb4)
+#define KDR_SCD_DECREASE_SCREDIT       (KDR_SCD_BASE + 0xb8)
+#define KDR_SCD_LOAD_CREDIT            (KDR_SCD_BASE + 0xbc)
+#define KDR_SCD_LOAD_SCREDIT           (KDR_SCD_BASE + 0xc0)
+#define KDR_SCD_BAR                    (KDR_SCD_BASE + 0xc4)
+#define KDR_SCD_BAR_DW0                (KDR_SCD_BASE + 0xc8)
+#define KDR_SCD_BAR_DW1                (KDR_SCD_BASE + 0xcc)
+#define KDR_SCD_QUEUECHAIN_SEL         (KDR_SCD_BASE + 0xd0)
+#define KDR_SCD_QUERY_REQ              (KDR_SCD_BASE + 0xd8)
+#define KDR_SCD_QUERY_RES              (KDR_SCD_BASE + 0xdc)
+#define KDR_SCD_PENDING_FRAMES         (KDR_SCD_BASE + 0xe0)
+#define KDR_SCD_INTERRUPT_MASK         (KDR_SCD_BASE + 0xe4)
+#define KDR_SCD_INTERRUPT_THRESHOLD    (KDR_SCD_BASE + 0xe8)
+#define KDR_SCD_QUERY_MIN_FRAME_SIZE   (KDR_SCD_BASE + 0x100)
+#define KDR_SCD_QUEUE_STATUS_BITS(x)   (KDR_SCD_BASE + 0x104 + (x) * 4)
+
+/* SP SCD */
+#define SHL_SCD_BASE                   (PRPH_BASE + 0xa02c00)
+
+#define SHL_SCD_AIT                    (SHL_SCD_BASE + 0x0c)
+#define SHL_SCD_TXFACT                 (SHL_SCD_BASE + 0x10)
+#define SHL_SCD_QUEUE_WRPTR(x)         (SHL_SCD_BASE + 0x18 + (x) * 4)
+#define SHL_SCD_QUEUE_RDPTR(x)         (SHL_SCD_BASE + 0x68 + (x) * 4)
+#define SHL_SCD_QUEUECHAIN_SEL         (SHL_SCD_BASE + 0xe8)
+#define SHL_SCD_AGGR_SEL              (SHL_SCD_BASE + 0x248)
+#define SHL_SCD_INTERRUPT_MASK         (SHL_SCD_BASE + 0x108)
+
 #endif                         /* __iwl_prph_h__ */
index 0b3ec7e4d93b30e4a78d7f5f674aafb4ba69a462..748ac1222abb908d2c18a79c35a389a393bab250 100644 (file)
  *
  *****************************************************************************/
 
-/*
- * NOTE:  This file (iwl-base.c) is used to build to multiple hardware targets
- * by defining IWL to either 3945 or 4965.  The Makefile used when building
- * the base targets will create base-3945.o and base-4965.o
- *
- * The eventual goal is to move as many of the #if IWL / #endif blocks out of
- * this file and into the hardware specific implementation files (iwl-XXXX.c)
- * and leave only the common (non #ifdef sprinkled) code in this file
- */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/version.h>
 
 #include <asm/div64.h>
 
-#define IWL 3945
-
-#include "iwlwifi.h"
 #include "iwl-3945.h"
 #include "iwl-helpers.h"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-u32 iwl_debug_level;
+#ifdef CONFIG_IWL3945_DEBUG
+u32 iwl3945_debug_level;
 #endif
 
+static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
+                                 struct iwl3945_tx_queue *txq);
+
 /******************************************************************************
  *
  * module boiler plate
@@ -73,13 +63,13 @@ u32 iwl_debug_level;
  ******************************************************************************/
 
 /* module parameters */
-int iwl_param_disable_hw_scan;
-int iwl_param_debug;
-int iwl_param_disable;      /* def: enable radio */
-int iwl_param_antenna;      /* def: 0 = both antennas (use diversity) */
-int iwl_param_hwcrypto;     /* def: using software encryption */
-int iwl_param_qos_enable = 1;
-int iwl_param_queues_num = IWL_MAX_NUM_QUEUES;
+static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */
+static int iwl3945_param_debug;    /* def: 0 = minimal debug log messages */
+static int iwl3945_param_disable;  /* def: 0 = enable radio */
+static int iwl3945_param_antenna;  /* def: 0 = both antennas (use diversity) */
+int iwl3945_param_hwcrypto;        /* def: 0 = use software encryption */
+static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */
+int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */
 
 /*
  * module name, copyright, version, etc.
@@ -89,19 +79,19 @@ int iwl_param_queues_num = IWL_MAX_NUM_QUEUES;
 #define DRV_DESCRIPTION        \
 "Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL3945_DEBUG
 #define VD "d"
 #else
 #define VD
 #endif
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 #define VS "s"
 #else
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "1.1.17k" VD VS
+#define IWLWIFI_VERSION "1.2.23k" VD VS
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -116,7 +106,7 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
-__le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
+static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
 {
        u16 fc = le16_to_cpu(hdr->frame_control);
        int hdr_len = ieee80211_get_hdrlen(fc);
@@ -126,8 +116,8 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
        return NULL;
 }
 
-static const struct ieee80211_hw_mode *iwl_get_hw_mode(
-               struct iwl_priv *priv, int mode)
+static const struct ieee80211_hw_mode *iwl3945_get_hw_mode(
+               struct iwl3945_priv *priv, int mode)
 {
        int i;
 
@@ -138,7 +128,7 @@ static const struct ieee80211_hw_mode *iwl_get_hw_mode(
        return NULL;
 }
 
-static int iwl_is_empty_essid(const char *essid, int essid_len)
+static int iwl3945_is_empty_essid(const char *essid, int essid_len)
 {
        /* Single white space is for Linksys APs */
        if (essid_len == 1 && essid[0] == ' ')
@@ -154,13 +144,13 @@ static int iwl_is_empty_essid(const char *essid, int essid_len)
        return 1;
 }
 
-static const char *iwl_escape_essid(const char *essid, u8 essid_len)
+static const char *iwl3945_escape_essid(const char *essid, u8 essid_len)
 {
        static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
        const char *s = essid;
        char *d = escaped;
 
-       if (iwl_is_empty_essid(essid, essid_len)) {
+       if (iwl3945_is_empty_essid(essid, essid_len)) {
                memcpy(escaped, "<hidden>", sizeof("<hidden>"));
                return escaped;
        }
@@ -178,10 +168,10 @@ static const char *iwl_escape_essid(const char *essid, u8 essid_len)
        return escaped;
 }
 
-static void iwl_print_hex_dump(int level, void *p, u32 len)
+static void iwl3945_print_hex_dump(int level, void *p, u32 len)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (!(iwl_debug_level & level))
+#ifdef CONFIG_IWL3945_DEBUG
+       if (!(iwl3945_debug_level & level))
                return;
 
        print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
@@ -194,24 +184,31 @@ static void iwl_print_hex_dump(int level, void *p, u32 len)
  *
  * Theory of operation
  *
- * A queue is a circular buffers with 'Read' and 'Write' pointers.
- * 2 empty entries always kept in the buffer to protect from overflow.
+ * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
+ * of buffer descriptors, each of which points to one or more data buffers for
+ * the device to read from or fill.  Driver and device exchange status of each
+ * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
+ * entries in each circular buffer, to protect against confusing empty and full
+ * queue states.
+ *
+ * The device reads or writes the data in the queues via the device's several
+ * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
  *
  * For Tx queue, there are low mark and high mark limits. If, after queuing
  * the packet for Tx, free space become < low mark, Tx queue stopped. When
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IWL operates with six queues, one receive queue in the device's
- * sram, one transmit queue for sending commands to the device firmware,
- * and four transmit queues for data.
+ * The 3945 operates with six queues:  One receive queue, one transmit queue
+ * (#4) for sending commands to the device firmware, and four transmit queues
+ * (#0-3) for data tx via EDCA.  An additional 2 HCCA queues are unused.
  ***************************************************/
 
-static int iwl_queue_space(const struct iwl_queue *q)
+static int iwl3945_queue_space(const struct iwl3945_queue *q)
 {
-       int s = q->last_used - q->first_empty;
+       int s = q->read_ptr - q->write_ptr;
 
-       if (q->last_used > q->first_empty)
+       if (q->read_ptr > q->write_ptr)
                s -= q->n_bd;
 
        if (s <= 0)
@@ -223,42 +220,55 @@ static int iwl_queue_space(const struct iwl_queue *q)
        return s;
 }
 
-/* XXX: n_bd must be power-of-two size */
-static inline int iwl_queue_inc_wrap(int index, int n_bd)
+/**
+ * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl3945_queue_inc_wrap(int index, int n_bd)
 {
        return ++index & (n_bd - 1);
 }
 
-/* XXX: n_bd must be power-of-two size */
-static inline int iwl_queue_dec_wrap(int index, int n_bd)
+/**
+ * iwl3945_queue_dec_wrap - increment queue index, wrap back to end
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl3945_queue_dec_wrap(int index, int n_bd)
 {
        return --index & (n_bd - 1);
 }
 
-static inline int x2_queue_used(const struct iwl_queue *q, int i)
+static inline int x2_queue_used(const struct iwl3945_queue *q, int i)
 {
-       return q->first_empty > q->last_used ?
-               (i >= q->last_used && i < q->first_empty) :
-               !(i < q->last_used && i >= q->first_empty);
+       return q->write_ptr > q->read_ptr ?
+               (i >= q->read_ptr && i < q->write_ptr) :
+               !(i < q->read_ptr && i >= q->write_ptr);
 }
 
-static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
+static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge)
 {
+       /* This is for scan command, the big buffer at end of command array */
        if (is_huge)
-               return q->n_window;
+               return q->n_window;     /* must be power of 2 */
 
+       /* Otherwise, use normal size buffers */
        return index & (q->n_window - 1);
 }
 
-static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
+/**
+ * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
+ */
+static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q,
                          int count, int slots_num, u32 id)
 {
        q->n_bd = count;
        q->n_window = slots_num;
        q->id = id;
 
-       /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
-        * and iwl_queue_dec_wrap are broken. */
+       /* count must be power-of-two size, otherwise iwl3945_queue_inc_wrap
+        * and iwl3945_queue_dec_wrap are broken. */
        BUG_ON(!is_power_of_2(count));
 
        /* slots_num must be power-of-two size, otherwise
@@ -273,27 +283,34 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
        if (q->high_mark < 2)
                q->high_mark = 2;
 
-       q->first_empty = q->last_used = 0;
+       q->write_ptr = q->read_ptr = 0;
 
        return 0;
 }
 
-static int iwl_tx_queue_alloc(struct iwl_priv *priv,
-                             struct iwl_tx_queue *txq, u32 id)
+/**
+ * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
+ */
+static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
+                             struct iwl3945_tx_queue *txq, u32 id)
 {
        struct pci_dev *dev = priv->pci_dev;
 
+       /* Driver private data, only for Tx (not command) queues,
+        * not shared with device. */
        if (id != IWL_CMD_QUEUE_NUM) {
                txq->txb = kmalloc(sizeof(txq->txb[0]) *
                                   TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
                if (!txq->txb) {
-                       IWL_ERROR("kmalloc for auxilary BD "
+                       IWL_ERROR("kmalloc for auxiliary BD "
                                  "structures failed\n");
                        goto error;
                }
        } else
                txq->txb = NULL;
 
+       /* Circular buffer of transmit frame descriptors (TFDs),
+        * shared with device */
        txq->bd = pci_alloc_consistent(dev,
                        sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
                        &txq->q.dma_addr);
@@ -316,24 +333,33 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
        return -ENOMEM;
 }
 
-int iwl_tx_queue_init(struct iwl_priv *priv,
-                     struct iwl_tx_queue *txq, int slots_num, u32 txq_id)
+/**
+ * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
+ */
+int iwl3945_tx_queue_init(struct iwl3945_priv *priv,
+                     struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id)
 {
        struct pci_dev *dev = priv->pci_dev;
        int len;
        int rc = 0;
 
-       /* alocate command space + one big command for scan since scan
-        * command is very huge the system will not have two scan at the
-        * same time */
-       len = sizeof(struct iwl_cmd) * slots_num;
+       /*
+        * Alloc buffer array for commands (Tx or other types of commands).
+        * For the command queue (#4), allocate command space + one big
+        * command for scan, since scan command is very huge; the system will
+        * not have two scans at the same time, so only one is needed.
+        * For data Tx queues (all other queues), no super-size command
+        * space is needed.
+        */
+       len = sizeof(struct iwl3945_cmd) * slots_num;
        if (txq_id == IWL_CMD_QUEUE_NUM)
                len +=  IWL_MAX_SCAN_SIZE;
        txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
        if (!txq->cmd)
                return -ENOMEM;
 
-       rc = iwl_tx_queue_alloc(priv, txq, txq_id);
+       /* Alloc driver data array and TFD circular buffer */
+       rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
        if (rc) {
                pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
 
@@ -342,26 +368,29 @@ int iwl_tx_queue_init(struct iwl_priv *priv,
        txq->need_update = 0;
 
        /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-        * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
+        * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */
        BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-       iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 
-       iwl_hw_tx_queue_init(priv, txq);
+       /* Initialize queue high/low-water, head/tail indexes */
+       iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+       /* Tell device where to find queue, enable DMA channel. */
+       iwl3945_hw_tx_queue_init(priv, txq);
 
        return 0;
 }
 
 /**
- * iwl_tx_queue_free - Deallocate DMA queue.
+ * iwl3945_tx_queue_free - Deallocate DMA queue.
  * @txq: Transmit queue to deallocate.
  *
  * Empty queue by removing and destroying all BD's.
- * Free all buffers.  txq itself is not freed.
- *
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
  */
-void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
 {
-       struct iwl_queue *q = &txq->q;
+       struct iwl3945_queue *q = &txq->q;
        struct pci_dev *dev = priv->pci_dev;
        int len;
 
@@ -369,44 +398,47 @@ void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                return;
 
        /* first, empty all BD's */
-       for (; q->first_empty != q->last_used;
-            q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd))
-               iwl_hw_txq_free_tfd(priv, txq);
+       for (; q->write_ptr != q->read_ptr;
+            q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd))
+               iwl3945_hw_txq_free_tfd(priv, txq);
 
-       len = sizeof(struct iwl_cmd) * q->n_window;
+       len = sizeof(struct iwl3945_cmd) * q->n_window;
        if (q->id == IWL_CMD_QUEUE_NUM)
                len += IWL_MAX_SCAN_SIZE;
 
+       /* De-alloc array of command/tx buffers */
        pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
 
-       /* free buffers belonging to queue itself */
+       /* De-alloc circular buffer of TFDs */
        if (txq->q.n_bd)
-               pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) *
+               pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) *
                                    txq->q.n_bd, txq->bd, txq->q.dma_addr);
 
+       /* De-alloc array of per-TFD driver data */
        if (txq->txb) {
                kfree(txq->txb);
                txq->txb = NULL;
        }
 
-       /* 0 fill whole structure */
+       /* 0-fill queue descriptor structure */
        memset(txq, 0, sizeof(*txq));
 }
 
-const u8 BROADCAST_ADDR[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
 /*************** STATION TABLE MANAGEMENT ****
- *
- * NOTE:  This needs to be overhauled to better synchronize between
- * how the iwl-4965.c is using iwl_hw_find_station vs. iwl-3945.c
- *
- * mac80211 should also be examined to determine if sta_info is duplicating
+ * mac80211 should be examined to determine if sta_info is duplicating
  * the functionality provided here
  */
 
 /**************************************************************/
-#if 0 /* temparary disable till we add real remove station */
-static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+#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 iwl3945_priv *priv, const u8 *addr, int is_ap)
 {
        int index = IWL_INVALID_STATION;
        int i;
@@ -442,7 +474,13 @@ out:
        return 0;
 }
 #endif
-static void iwl_clear_stations_table(struct iwl_priv *priv)
+
+/**
+ * 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 iwl3945_priv *priv)
 {
        unsigned long flags;
 
@@ -454,12 +492,14 @@ static void iwl_clear_stations_table(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-
-u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
+/**
+ * iwl3945_add_station - Add station to station tables in driver and device
+ */
+u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags)
 {
        int i;
        int index = IWL_INVALID_STATION;
-       struct iwl_station_entry *station;
+       struct iwl3945_station_entry *station;
        unsigned long flags_spin;
        DECLARE_MAC_BUF(mac);
        u8 rate;
@@ -482,7 +522,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
                                index = i;
                }
 
-       /* These twh conditions has the same outcome but keep them separate
+       /* 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);
@@ -500,30 +540,35 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
        station->used = 1;
        priv->num_stations++;
 
-       memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
+       /* 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;
 
-       rate = (priv->phymode == MODE_IEEE80211A) ? IWL_RATE_6M_PLCP :
-                               IWL_RATE_1M_PLCP | priv->hw_setting.cck_flag;
+       if (priv->phymode == MODE_IEEE80211A)
+               rate = IWL_RATE_6M_PLCP;
+       else
+               rate =  IWL_RATE_1M_PLCP;
 
        /* Turn on both antennas for the station... */
        station->sta.rate_n_flags =
-                       iwl_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
+                       iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
        station->current_rate.rate_n_flags =
                        le16_to_cpu(station->sta.rate_n_flags);
 
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-       iwl_send_add_station(priv, &station->sta, flags);
+
+       /* Add station to device's station table */
+       iwl3945_send_add_station(priv, &station->sta, flags);
        return index;
 
 }
 
 /*************** DRIVER STATUS FUNCTIONS   *****/
 
-static inline int iwl_is_ready(struct iwl_priv *priv)
+static inline int iwl3945_is_ready(struct iwl3945_priv *priv)
 {
        /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
         * set but EXIT_PENDING is not */
@@ -532,29 +577,29 @@ static inline int iwl_is_ready(struct iwl_priv *priv)
               !test_bit(STATUS_EXIT_PENDING, &priv->status);
 }
 
-static inline int iwl_is_alive(struct iwl_priv *priv)
+static inline int iwl3945_is_alive(struct iwl3945_priv *priv)
 {
        return test_bit(STATUS_ALIVE, &priv->status);
 }
 
-static inline int iwl_is_init(struct iwl_priv *priv)
+static inline int iwl3945_is_init(struct iwl3945_priv *priv)
 {
        return test_bit(STATUS_INIT, &priv->status);
 }
 
-static inline int iwl_is_rfkill(struct iwl_priv *priv)
+static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv)
 {
        return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
               test_bit(STATUS_RF_KILL_SW, &priv->status);
 }
 
-static inline int iwl_is_ready_rf(struct iwl_priv *priv)
+static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv)
 {
 
-       if (iwl_is_rfkill(priv))
+       if (iwl3945_is_rfkill(priv))
                return 0;
 
-       return iwl_is_ready(priv);
+       return iwl3945_is_ready(priv);
 }
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
@@ -613,7 +658,7 @@ static const char *get_cmd_string(u8 cmd)
 #define HOST_COMPLETE_TIMEOUT (HZ / 2)
 
 /**
- * iwl_enqueue_hcmd - enqueue a uCode command
+ * iwl3945_enqueue_hcmd - enqueue a uCode command
  * @priv: device private data point
  * @cmd: a point to the ucode command structure
  *
@@ -621,13 +666,13 @@ static const char *get_cmd_string(u8 cmd)
  * failed. On success, it turns the index (> 0) of command in the
  * command queue.
  */
-static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
 {
-       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
-       struct iwl_queue *q = &txq->q;
-       struct iwl_tfd_frame *tfd;
+       struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+       struct iwl3945_queue *q = &txq->q;
+       struct iwl3945_tfd_frame *tfd;
        u32 *control_flags;
-       struct iwl_cmd *out_cmd;
+       struct iwl3945_cmd *out_cmd;
        u32 idx;
        u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
        dma_addr_t phys_addr;
@@ -642,19 +687,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
               !(cmd->meta.flags & CMD_SIZE_HUGE));
 
-       if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+       if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
                IWL_ERROR("No space for Tx\n");
                return -ENOSPC;
        }
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
-       tfd = &txq->bd[q->first_empty];
+       tfd = &txq->bd[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
 
        control_flags = (u32 *) tfd;
 
-       idx = get_cmd_index(q, q->first_empty, cmd->meta.flags & CMD_SIZE_HUGE);
+       idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
        out_cmd = &txq->cmd[idx];
 
        out_cmd->hdr.cmd = cmd->id;
@@ -666,13 +711,13 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        out_cmd->hdr.flags = 0;
        out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
-                       INDEX_TO_SEQ(q->first_empty));
+                       INDEX_TO_SEQ(q->write_ptr));
        if (out_cmd->meta.flags & CMD_SIZE_HUGE)
                out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
 
        phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
-                       offsetof(struct iwl_cmd, hdr);
-       iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+                       offsetof(struct iwl3945_cmd, hdr);
+       iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
 
        pad = U32_PAD(cmd->len);
        count = TFD_CTL_COUNT_GET(*control_flags);
@@ -682,17 +727,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                     "%d bytes at %d[%d]:%d\n",
                     get_cmd_string(out_cmd->hdr.cmd),
                     out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
-                    fix_size, q->first_empty, idx, IWL_CMD_QUEUE_NUM);
+                    fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
 
        txq->need_update = 1;
-       q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd);
-       ret = iwl_tx_queue_update_write_ptr(priv, txq);
+
+       /* Increment and update queue's write index */
+       q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
+       ret = iwl3945_tx_queue_update_write_ptr(priv, txq);
 
        spin_unlock_irqrestore(&priv->hcmd_lock, flags);
        return ret ? ret : idx;
 }
 
-int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
 {
        int ret;
 
@@ -707,16 +754,16 @@ int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EBUSY;
 
-       ret = iwl_enqueue_hcmd(priv, cmd);
+       ret = iwl3945_enqueue_hcmd(priv, cmd);
        if (ret < 0) {
-               IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n",
+               IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
        }
        return 0;
 }
 
-int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
 {
        int cmd_idx;
        int ret;
@@ -738,10 +785,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        if (cmd->meta.flags & CMD_WANT_SKB)
                cmd->meta.source = &cmd->meta;
 
-       cmd_idx = iwl_enqueue_hcmd(priv, cmd);
+       cmd_idx = iwl3945_enqueue_hcmd(priv, cmd);
        if (cmd_idx < 0) {
                ret = cmd_idx;
-               IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n",
+               IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                goto out;
        }
@@ -785,7 +832,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
 cancel:
        if (cmd->meta.flags & CMD_WANT_SKB) {
-               struct iwl_cmd *qcmd;
+               struct iwl3945_cmd *qcmd;
 
                /* Cancel the CMD_WANT_SKB flag for the cmd in the
                 * TX cmd queue. Otherwise in case the cmd comes
@@ -804,47 +851,43 @@ out:
        return ret;
 }
 
-int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd)
 {
-       /* A command can not be asynchronous AND expect an SKB to be set. */
-       BUG_ON((cmd->meta.flags & CMD_ASYNC) &&
-              (cmd->meta.flags & CMD_WANT_SKB));
-
        if (cmd->meta.flags & CMD_ASYNC)
-               return iwl_send_cmd_async(priv, cmd);
+               return iwl3945_send_cmd_async(priv, cmd);
 
-       return iwl_send_cmd_sync(priv, cmd);
+       return iwl3945_send_cmd_sync(priv, cmd);
 }
 
-int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data)
+int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_host_cmd cmd = {
                .id = id,
                .len = len,
                .data = data,
        };
 
-       return iwl_send_cmd_sync(priv, &cmd);
+       return iwl3945_send_cmd_sync(priv, &cmd);
 }
 
-static int __must_check iwl_send_cmd_u32(struct iwl_priv *priv, u8 id, u32 val)
+static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_host_cmd cmd = {
                .id = id,
                .len = sizeof(val),
                .data = &val,
        };
 
-       return iwl_send_cmd_sync(priv, &cmd);
+       return iwl3945_send_cmd_sync(priv, &cmd);
 }
 
-int iwl_send_statistics_request(struct iwl_priv *priv)
+int iwl3945_send_statistics_request(struct iwl3945_priv *priv)
 {
-       return iwl_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
+       return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
 }
 
 /**
- * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
+ * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
  * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
  * @channel: Any channel valid for the requested phymode
 
@@ -853,9 +896,9 @@ int iwl_send_statistics_request(struct iwl_priv *priv)
  * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
  * in the staging RXON flag structure based on the phymode
  */
-static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel)
+static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel)
 {
-       if (!iwl_get_channel_info(priv, phymode, channel)) {
+       if (!iwl3945_get_channel_info(priv, phymode, channel)) {
                IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
                               channel, phymode);
                return -EINVAL;
@@ -879,13 +922,13 @@ static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel)
 }
 
 /**
- * iwl_check_rxon_cmd - validate RXON structure is valid
+ * iwl3945_check_rxon_cmd - validate RXON structure is valid
  *
  * NOTE:  This is really only useful during development and can eventually
  * be #ifdef'd out once the driver is stable and folks aren't actively
  * making changes
  */
-static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
+static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon)
 {
        int error = 0;
        int counter = 1;
@@ -951,21 +994,21 @@ static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
                            le16_to_cpu(rxon->channel));
 
        if (error) {
-               IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n");
+               IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n");
                return -1;
        }
        return 0;
 }
 
 /**
- * iwl_full_rxon_required - determine if RXON_ASSOC can be used in RXON commit
- * @priv: staging_rxon is comapred to active_rxon
+ * iwl3945_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * @priv: staging_rxon is compared to active_rxon
  *
- * If the RXON structure is changing sufficient to require a new
- * tune or to clear and reset the RXON_FILTER_ASSOC_MSK then return 1
- * to indicate a new tune is required.
+ * If the RXON structure is changing enough to require a new tune,
+ * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
+ * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
-static int iwl_full_rxon_required(struct iwl_priv *priv)
+static int iwl3945_full_rxon_required(struct iwl3945_priv *priv)
 {
 
        /* These items are only settable from the full RXON command */
@@ -1000,19 +1043,19 @@ static int iwl_full_rxon_required(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv)
 {
        int rc = 0;
-       struct iwl_rx_packet *res = NULL;
-       struct iwl_rxon_assoc_cmd rxon_assoc;
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_rx_packet *res = NULL;
+       struct iwl3945_rxon_assoc_cmd rxon_assoc;
+       struct iwl3945_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;
+       const struct iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon;
+       const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon;
 
        if ((rxon1->flags == rxon2->flags) &&
            (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1028,11 +1071,11 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv)
        rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
        rxon_assoc.reserved = 0;
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl3945_send_cmd_sync(priv, &cmd);
        if (rc)
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
                rc = -EIO;
@@ -1045,21 +1088,21 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv)
 }
 
 /**
- * iwl_commit_rxon - commit staging_rxon to hardware
+ * iwl3945_commit_rxon - commit staging_rxon to hardware
  *
- * The RXON command in staging_rxon is commited to the hardware and
+ * 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 iwl_commit_rxon(struct iwl_priv *priv)
+static int iwl3945_commit_rxon(struct iwl3945_priv *priv)
 {
        /* cast away the const for active_rxon in this function */
-       struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+       struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
        int rc = 0;
        DECLARE_MAC_BUF(mac);
 
-       if (!iwl_is_alive(priv))
+       if (!iwl3945_is_alive(priv))
                return -1;
 
        /* always get timestamp with Rx frame */
@@ -1070,17 +1113,17 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
            ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
        priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv);
 
-       rc = iwl_check_rxon_cmd(&priv->staging_rxon);
+       rc = iwl3945_check_rxon_cmd(&priv->staging_rxon);
        if (rc) {
                IWL_ERROR("Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
        }
 
        /* If we don't need to send a full RXON, we can use
-        * iwl_rxon_assoc_cmd which is used to reconfigure filter
+        * 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 (!iwl3945_full_rxon_required(priv)) {
+               rc = iwl3945_send_rxon_assoc(priv);
                if (rc) {
                        IWL_ERROR("Error setting RXON_ASSOC "
                                  "configuration (%d).\n", rc);
@@ -1096,13 +1139,13 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
         * 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) &&
+       if (iwl3945_is_associated(priv) &&
            (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
                IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                                     sizeof(struct iwl_rxon_cmd),
+               rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+                                     sizeof(struct iwl3945_rxon_cmd),
                                      &priv->active_rxon);
 
                /* If the mask clearing failed then we set
@@ -1125,8 +1168,8 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
                       print_mac(mac, priv->staging_rxon.bssid_addr));
 
        /* Apply the new configuration */
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                             sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+       rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON,
+                             sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon);
        if (rc) {
                IWL_ERROR("Error setting new configuration (%d).\n", rc);
                return rc;
@@ -1134,18 +1177,18 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
 
        memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 
-       iwl_clear_stations_table(priv);
+       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 = iwl_hw_reg_send_txpower(priv);
+       rc = iwl3945_hw_reg_send_txpower(priv);
        if (rc) {
                IWL_ERROR("Error setting Tx power (%d).\n", rc);
                return rc;
        }
 
        /* Add the broadcast address so we can send broadcast frames */
-       if (iwl_add_station(priv, BROADCAST_ADDR, 0, 0) ==
+       if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) ==
            IWL_INVALID_STATION) {
                IWL_ERROR("Error adding BROADCAST address for transmit.\n");
                return -EIO;
@@ -1153,9 +1196,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
 
        /* 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) &&
+       if (iwl3945_is_associated(priv) &&
            (priv->iw_mode == IEEE80211_IF_TYPE_STA))
-               if (iwl_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
+               if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
                    == IWL_INVALID_STATION) {
                        IWL_ERROR("Error adding AP address for transmit.\n");
                        return -EIO;
@@ -1172,9 +1215,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_send_bt_config(struct iwl_priv *priv)
+static int iwl3945_send_bt_config(struct iwl3945_priv *priv)
 {
-       struct iwl_bt_cmd bt_cmd = {
+       struct iwl3945_bt_cmd bt_cmd = {
                .flags = 3,
                .lead_time = 0xAA,
                .max_kill = 1,
@@ -1182,15 +1225,15 @@ static int iwl_send_bt_config(struct iwl_priv *priv)
                .kill_cts_mask = 0,
        };
 
-       return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-                               sizeof(struct iwl_bt_cmd), &bt_cmd);
+       return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+                               sizeof(struct iwl3945_bt_cmd), &bt_cmd);
 }
 
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+static int iwl3945_send_scan_abort(struct iwl3945_priv *priv)
 {
        int rc = 0;
-       struct iwl_rx_packet *res;
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_rx_packet *res;
+       struct iwl3945_host_cmd cmd = {
                .id = REPLY_SCAN_ABORT_CMD,
                .meta.flags = CMD_WANT_SKB,
        };
@@ -1203,13 +1246,13 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
                return 0;
        }
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl3945_send_cmd_sync(priv, &cmd);
        if (rc) {
                clear_bit(STATUS_SCAN_ABORTING, &priv->status);
                return rc;
        }
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
        if (res->u.status != CAN_ABORT_STATUS) {
                /* The scan abort will return 1 for success or
                 * 2 for "failure".  A failure condition can be
@@ -1227,8 +1270,8 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
        return rc;
 }
 
-static int iwl_card_state_sync_callback(struct iwl_priv *priv,
-                                       struct iwl_cmd *cmd,
+static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv,
+                                       struct iwl3945_cmd *cmd,
                                        struct sk_buff *skb)
 {
        return 1;
@@ -1237,16 +1280,16 @@ static int iwl_card_state_sync_callback(struct iwl_priv *priv,
 /*
  * CARD_STATE_CMD
  *
- * Use: Sets the internal card state to enable, disable, or halt
+ * Use: Sets the device's internal card state to enable, disable, or halt
  *
  * When in the 'enable' state the card operates as normal.
  * When in the 'disable' state, the card enters into a low power mode.
  * When in the 'halt' state, the card is shut down and must be fully
  * restarted to come back on.
  */
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_host_cmd cmd = {
                .id = REPLY_CARD_STATE_CMD,
                .len = sizeof(u32),
                .data = &flags,
@@ -1254,22 +1297,22 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
        };
 
        if (meta_flag & CMD_ASYNC)
-               cmd.meta.u.callback = iwl_card_state_sync_callback;
+               cmd.meta.u.callback = iwl3945_card_state_sync_callback;
 
-       return iwl_send_cmd(priv, &cmd);
+       return iwl3945_send_cmd(priv, &cmd);
 }
 
-static int iwl_add_sta_sync_callback(struct iwl_priv *priv,
-                                    struct iwl_cmd *cmd, struct sk_buff *skb)
+static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv,
+                                    struct iwl3945_cmd *cmd, struct sk_buff *skb)
 {
-       struct iwl_rx_packet *res = NULL;
+       struct iwl3945_rx_packet *res = NULL;
 
        if (!skb) {
                IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
                return 1;
        }
 
-       res = (struct iwl_rx_packet *)skb->data;
+       res = (struct iwl3945_rx_packet *)skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
                          res->hdr.flags);
@@ -1287,29 +1330,29 @@ static int iwl_add_sta_sync_callback(struct iwl_priv *priv,
        return 1;
 }
 
-int iwl_send_add_station(struct iwl_priv *priv,
-                        struct iwl_addsta_cmd *sta, u8 flags)
+int iwl3945_send_add_station(struct iwl3945_priv *priv,
+                        struct iwl3945_addsta_cmd *sta, u8 flags)
 {
-       struct iwl_rx_packet *res = NULL;
+       struct iwl3945_rx_packet *res = NULL;
        int rc = 0;
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_host_cmd cmd = {
                .id = REPLY_ADD_STA,
-               .len = sizeof(struct iwl_addsta_cmd),
+               .len = sizeof(struct iwl3945_addsta_cmd),
                .meta.flags = flags,
                .data = sta,
        };
 
        if (flags & CMD_ASYNC)
-               cmd.meta.u.callback = iwl_add_sta_sync_callback;
+               cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
        else
                cmd.meta.flags |= CMD_WANT_SKB;
 
-       rc = iwl_send_cmd(priv, &cmd);
+       rc = iwl3945_send_cmd(priv, &cmd);
 
        if (rc || (flags & CMD_ASYNC))
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
                          res->hdr.flags);
@@ -1334,7 +1377,7 @@ int iwl_send_add_station(struct iwl_priv *priv,
        return rc;
 }
 
-static int iwl_update_sta_key_info(struct iwl_priv *priv,
+static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv,
                                   struct ieee80211_key_conf *keyconf,
                                   u8 sta_id)
 {
@@ -1350,7 +1393,6 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv,
                break;
        case ALG_TKIP:
        case ALG_WEP:
-               return -EINVAL;
        default:
                return -EINVAL;
        }
@@ -1369,28 +1411,28 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv,
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
        IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+       iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
        return 0;
 }
 
-static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
+static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
-       memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
-       memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo));
+       memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
+       memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo));
        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("hwcrypto: clear ucode station key info\n");
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+       iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0);
        return 0;
 }
 
-static void iwl_clear_free_frames(struct iwl_priv *priv)
+static void iwl3945_clear_free_frames(struct iwl3945_priv *priv)
 {
        struct list_head *element;
 
@@ -1400,7 +1442,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
        while (!list_empty(&priv->free_frames)) {
                element = priv->free_frames.next;
                list_del(element);
-               kfree(list_entry(element, struct iwl_frame, list));
+               kfree(list_entry(element, struct iwl3945_frame, list));
                priv->frames_count--;
        }
 
@@ -1411,9 +1453,9 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
        }
 }
 
-static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
+static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv)
 {
-       struct iwl_frame *frame;
+       struct iwl3945_frame *frame;
        struct list_head *element;
        if (list_empty(&priv->free_frames)) {
                frame = kzalloc(sizeof(*frame), GFP_KERNEL);
@@ -1428,21 +1470,21 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
 
        element = priv->free_frames.next;
        list_del(element);
-       return list_entry(element, struct iwl_frame, list);
+       return list_entry(element, struct iwl3945_frame, list);
 }
 
-static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
+static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame)
 {
        memset(frame, 0, sizeof(*frame));
        list_add(&frame->list, &priv->free_frames);
 }
 
-unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
+unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
                                struct ieee80211_hdr *hdr,
                                const u8 *dest, int left)
 {
 
-       if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
+       if (!iwl3945_is_associated(priv) || !priv->ibss_beacon ||
            ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
             (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
                return 0;
@@ -1455,37 +1497,27 @@ unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static int iwl_rate_index_from_plcp(int plcp)
-{
-       int i = 0;
-
-       for (i = 0; i < IWL_RATE_COUNT; i++)
-               if (iwl_rates[i].plcp == plcp)
-                       return i;
-       return -1;
-}
-
-static u8 iwl_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
 {
        u8 i;
 
        for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
-            i = iwl_rates[i].next_ieee) {
+            i = iwl3945_rates[i].next_ieee) {
                if (rate_mask & (1 << i))
-                       return iwl_rates[i].plcp;
+                       return iwl3945_rates[i].plcp;
        }
 
        return IWL_RATE_INVALID;
 }
 
-static int iwl_send_beacon_cmd(struct iwl_priv *priv)
+static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv)
 {
-       struct iwl_frame *frame;
+       struct iwl3945_frame *frame;
        unsigned int frame_size;
        int rc;
        u8 rate;
 
-       frame = iwl_get_free_frame(priv);
+       frame = iwl3945_get_free_frame(priv);
 
        if (!frame) {
                IWL_ERROR("Could not obtain free frame buffer for beacon "
@@ -1494,22 +1526,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
        }
 
        if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
-               rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic &
+               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic &
                                                0xFF0);
                if (rate == IWL_INVALID_RATE)
                        rate = IWL_RATE_6M_PLCP;
        } else {
-               rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
+               rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
                if (rate == IWL_INVALID_RATE)
                        rate = IWL_RATE_1M_PLCP;
        }
 
-       frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
+       frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
 
-       rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+       rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
                              &frame->u.cmd[0]);
 
-       iwl_free_frame(priv, frame);
+       iwl3945_free_frame(priv, frame);
 
        return rc;
 }
@@ -1520,22 +1552,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
  *
  ******************************************************************************/
 
-static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac)
+static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac)
 {
        memcpy(mac, priv->eeprom.mac_address, 6);
 }
 
 /**
- * iwl_eeprom_init - read EEPROM contents
+ * iwl3945_eeprom_init - read EEPROM contents
  *
- * Load the EEPROM from adapter into priv->eeprom
+ * Load the EEPROM contents from adapter into priv->eeprom
  *
  * NOTE:  This routine uses the non-debug IO access functions.
  */
-int iwl_eeprom_init(struct iwl_priv *priv)
+int iwl3945_eeprom_init(struct iwl3945_priv *priv)
 {
-       u16 *e = (u16 *)&priv->eeprom;
-       u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
+       __le16 *e = (__le16 *)&priv->eeprom;
+       u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP);
        u32 r;
        int sz = sizeof(priv->eeprom);
        int rc;
@@ -1553,20 +1585,21 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                return -ENOENT;
        }
 
-       rc = iwl_eeprom_aqcuire_semaphore(priv);
+       /* Make sure driver (instead of uCode) is allowed to read EEPROM */
+       rc = iwl3945_eeprom_acquire_semaphore(priv);
        if (rc < 0) {
-               IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n");
+               IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
                return -ENOENT;
        }
 
        /* eeprom is an array of 16bit values */
        for (addr = 0; addr < sz; addr += sizeof(u16)) {
-               _iwl_write32(priv, CSR_EEPROM_REG, addr << 1);
-               _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
+               _iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1);
+               _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
 
                for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
                                        i += IWL_EEPROM_ACCESS_DELAY) {
-                       r = _iwl_read_restricted(priv, CSR_EEPROM_REG);
+                       r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG);
                        if (r & CSR_EEPROM_REG_READ_VALID_MSK)
                                break;
                        udelay(IWL_EEPROM_ACCESS_DELAY);
@@ -1576,7 +1609,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                        IWL_ERROR("Time out reading EEPROM[%d]", addr);
                        return -ETIMEDOUT;
                }
-               e[addr / 2] = le16_to_cpu(r >> 16);
+               e[addr / 2] = cpu_to_le16(r >> 16);
        }
 
        return 0;
@@ -1587,22 +1620,17 @@ int iwl_eeprom_init(struct iwl_priv *priv)
  * Misc. internal state and helper functions
  *
  ******************************************************************************/
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL3945_DEBUG
 
 /**
- * iwl_report_frame - dump frame to syslog during debug sessions
+ * iwl3945_report_frame - dump frame to syslog during debug sessions
  *
- * hack this function to show different aspects of received frames,
+ * You may hack this function to show different aspects of received frames,
  * including selective frame dumps.
  * group100 parameter selects whether to show 1 out of 100 good frames.
- *
- * TODO:  ieee80211_hdr stuff is common to 3945 and 4965, so frame type
- *        info output is okay, but some of this stuff (e.g. iwl_rx_frame_stats)
- *        is 3945-specific and gives bad output for 4965.  Need to split the
- *        functionality, keep common stuff here.
  */
-void iwl_report_frame(struct iwl_priv *priv,
-                     struct iwl_rx_packet *pkt,
+void iwl3945_report_frame(struct iwl3945_priv *priv,
+                     struct iwl3945_rx_packet *pkt,
                      struct ieee80211_hdr *header, int group100)
 {
        u32 to_us;
@@ -1624,9 +1652,9 @@ void iwl_report_frame(struct iwl_priv *priv,
        u8 agc;
        u16 sig_avg;
        u16 noise_diff;
-       struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
-       struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
-       struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);
+       struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
+       struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
+       struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
        u8 *data = IWL_RX_DATA(pkt);
 
        /* MAC header */
@@ -1702,11 +1730,11 @@ void iwl_report_frame(struct iwl_priv *priv,
                else
                        title = "Frame";
 
-               rate = iwl_rate_index_from_plcp(rate_sym);
+               rate = iwl3945_rate_index_from_plcp(rate_sym);
                if (rate == -1)
                        rate = 0;
                else
-                       rate = iwl_rates[rate].ieee / 2;
+                       rate = iwl3945_rates[rate].ieee / 2;
 
                /* print frame summary.
                 * MAC addresses show just the last byte (for brevity),
@@ -1728,25 +1756,25 @@ void iwl_report_frame(struct iwl_priv *priv,
                }
        }
        if (print_dump)
-               iwl_print_hex_dump(IWL_DL_RX, data, length);
+               iwl3945_print_hex_dump(IWL_DL_RX, data, length);
 }
 #endif
 
-static void iwl_unset_hw_setting(struct iwl_priv *priv)
+static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv)
 {
        if (priv->hw_setting.shared_virt)
                pci_free_consistent(priv->pci_dev,
-                                   sizeof(struct iwl_shared),
+                                   sizeof(struct iwl3945_shared),
                                    priv->hw_setting.shared_virt,
                                    priv->hw_setting.shared_phys);
 }
 
 /**
- * iwl_supported_rate_to_ie - fill in the supported rate in IE field
+ * iwl3945_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,
+static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
                                    u16 basic_rate, int *left)
 {
        u16 ret_rates = 0, bit;
@@ -1757,7 +1785,7 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
        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 |
+                       rates[*cnt] = iwl3945_rates[i].ieee |
                                ((bit & basic_rate) ? 0x80 : 0x00);
                        (*cnt)++;
                        (*left)--;
@@ -1771,9 +1799,9 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
 }
 
 /**
- * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
  */
-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
+static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv,
                              struct ieee80211_mgmt *frame,
                              int left, int is_direct)
 {
@@ -1789,9 +1817,9 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        len += 24;
 
        frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-       memcpy(frame->da, BROADCAST_ADDR, ETH_ALEN);
+       memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN);
        memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
-       memcpy(frame->bssid, BROADCAST_ADDR, ETH_ALEN);
+       memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN);
        frame->seq_ctrl = 0;
 
        /* fill in our indirect SSID IE */
@@ -1834,11 +1862,11 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
        cck_rates = IWL_CCK_RATES_MASK & active_rates;
-       ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+       ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
                        priv->active_rate_basic, &left);
        active_rates &= ~ret_rates;
 
-       ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+       ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
                                 priv->active_rate_basic, &left);
        active_rates &= ~ret_rates;
 
@@ -1855,7 +1883,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        /* ... fill it in... */
        *pos++ = WLAN_EID_EXT_SUPP_RATES;
        *pos = 0;
-       iwl_supported_rate_to_ie(pos, active_rates,
+       iwl3945_supported_rate_to_ie(pos, active_rates,
                                 priv->active_rate_basic, &left);
        if (*pos > 0)
                len += 2 + *pos;
@@ -1867,16 +1895,16 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
 /*
  * QoS  support
 */
-#ifdef CONFIG_IWLWIFI_QOS
-static int iwl_send_qos_params_command(struct iwl_priv *priv,
-                                      struct iwl_qosparam_cmd *qos)
+#ifdef CONFIG_IWL3945_QOS
+static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv,
+                                      struct iwl3945_qosparam_cmd *qos)
 {
 
-       return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
-                               sizeof(struct iwl_qosparam_cmd), qos);
+       return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM,
+                               sizeof(struct iwl3945_qosparam_cmd), qos);
 }
 
-static void iwl_reset_qos(struct iwl_priv *priv)
+static void iwl3945_reset_qos(struct iwl3945_priv *priv)
 {
        u16 cw_min = 15;
        u16 cw_max = 1023;
@@ -1963,13 +1991,10 @@ static void iwl_reset_qos(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force)
 {
        unsigned long flags;
 
-       if (priv == NULL)
-               return;
-
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
@@ -1990,16 +2015,16 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (force || iwl_is_associated(priv)) {
+       if (force || iwl3945_is_associated(priv)) {
                IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",
                              priv->qos_data.qos_active);
 
-               iwl_send_qos_params_command(priv,
+               iwl3945_send_qos_params_command(priv,
                                &(priv->qos_data.def_qos_parm));
        }
 }
 
-#endif /* CONFIG_IWLWIFI_QOS */
+#endif /* CONFIG_IWL3945_QOS */
 /*
  * Power management (not Tx power!) functions
  */
@@ -2017,7 +2042,7 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 
 /* default power management (not Tx power) table values */
 /* for tim  0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
+static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
@@ -2027,7 +2052,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
 };
 
 /* for tim > 10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
+static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
                 SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
@@ -2040,11 +2065,11 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
                 SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 };
 
-int iwl_power_init_handle(struct iwl_priv *priv)
+int iwl3945_power_init_handle(struct iwl3945_priv *priv)
 {
        int rc = 0, i;
-       struct iwl_power_mgr *pow_data;
-       int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;
+       struct iwl3945_power_mgr *pow_data;
+       int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC;
        u16 pci_pm;
 
        IWL_DEBUG_POWER("Initialize power \n");
@@ -2063,7 +2088,7 @@ int iwl_power_init_handle(struct iwl_priv *priv)
        if (rc != 0)
                return 0;
        else {
-               struct iwl_powertable_cmd *cmd;
+               struct iwl3945_powertable_cmd *cmd;
 
                IWL_DEBUG_POWER("adjust power command flags\n");
 
@@ -2079,15 +2104,15 @@ int iwl_power_init_handle(struct iwl_priv *priv)
        return rc;
 }
 
-static int iwl_update_power_cmd(struct iwl_priv *priv,
-                               struct iwl_powertable_cmd *cmd, u32 mode)
+static int iwl3945_update_power_cmd(struct iwl3945_priv *priv,
+                               struct iwl3945_powertable_cmd *cmd, u32 mode)
 {
        int rc = 0, i;
        u8 skip;
        u32 max_sleep = 0;
-       struct iwl_power_vec_entry *range;
+       struct iwl3945_power_vec_entry *range;
        u8 period = 0;
-       struct iwl_power_mgr *pow_data;
+       struct iwl3945_power_mgr *pow_data;
 
        if (mode > IWL_POWER_INDEX_5) {
                IWL_DEBUG_POWER("Error invalid power mode \n");
@@ -2100,7 +2125,7 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
        else
                range = &pow_data->pwr_range_1[1];
 
-       memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
+       memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd));
 
 #ifdef IWL_MAC80211_DISABLE
        if (priv->assoc_network != NULL) {
@@ -2143,14 +2168,14 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
        return rc;
 }
 
-static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
+static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode)
 {
-       u32 final_mode = mode;
+       u32 uninitialized_var(final_mode);
        int rc;
-       struct iwl_powertable_cmd cmd;
+       struct iwl3945_powertable_cmd cmd;
 
        /* If on battery, set to 3,
-        * if plugged into AC power, set to CAM ("continuosly aware mode"),
+        * if plugged into AC power, set to CAM ("continuously aware mode"),
         * else user level */
        switch (mode) {
        case IWL_POWER_BATTERY:
@@ -2164,9 +2189,9 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
                break;
        }
 
-       iwl_update_power_cmd(priv, &cmd, final_mode);
+       iwl3945_update_power_cmd(priv, &cmd, final_mode);
 
-       rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
+       rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
 
        if (final_mode == IWL_POWER_MODE_CAM)
                clear_bit(STATUS_POWER_PMI, &priv->status);
@@ -2176,7 +2201,7 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
        return rc;
 }
 
-int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
+int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
 {
        /* Filter incoming packets to determine if they are targeted toward
         * this network, discarding packets coming from ourselves */
@@ -2206,7 +2231,7 @@ int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
 
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
-const char *iwl_get_tx_fail_reason(u32 status)
+static const char *iwl3945_get_tx_fail_reason(u32 status)
 {
        switch (status & TX_STATUS_MSK) {
        case TX_STATUS_SUCCESS:
@@ -2233,11 +2258,11 @@ const char *iwl_get_tx_fail_reason(u32 status)
 }
 
 /**
- * iwl_scan_cancel - Cancel any currently executing HW scan
+ * iwl3945_scan_cancel - Cancel any currently executing HW scan
  *
  * NOTE: priv->mutex is not required before calling this function
  */
-static int iwl_scan_cancel(struct iwl_priv *priv)
+static int iwl3945_scan_cancel(struct iwl3945_priv *priv)
 {
        if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
                clear_bit(STATUS_SCANNING, &priv->status);
@@ -2260,17 +2285,17 @@ static int iwl_scan_cancel(struct iwl_priv *priv)
 }
 
 /**
- * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
+ * iwl3945_scan_cancel_timeout - Cancel any currently executing HW scan
  * @ms: amount of time to wait (in milliseconds) for scan to abort
  *
  * NOTE: priv->mutex must be held before calling this function
  */
-static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
+static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms)
 {
        unsigned long now = jiffies;
        int ret;
 
-       ret = iwl_scan_cancel(priv);
+       ret = iwl3945_scan_cancel(priv);
        if (ret && ms) {
                mutex_unlock(&priv->mutex);
                while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
@@ -2284,7 +2309,7 @@ static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
        return ret;
 }
 
-static void iwl_sequence_reset(struct iwl_priv *priv)
+static void iwl3945_sequence_reset(struct iwl3945_priv *priv)
 {
        /* Reset ieee stats */
 
@@ -2295,13 +2320,13 @@ static void iwl_sequence_reset(struct iwl_priv *priv)
        priv->last_frag_num = -1;
        priv->last_packet_time = 0;
 
-       iwl_scan_cancel(priv);
+       iwl3945_scan_cancel(priv);
 }
 
 #define MAX_UCODE_BEACON_INTERVAL      1024
 #define INTEL_CONN_LISTEN_INTERVAL     __constant_cpu_to_le16(0xA)
 
-static __le16 iwl_adjust_beacon_interval(u16 beacon_val)
+static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val)
 {
        u16 new_val = 0;
        u16 beacon_factor = 0;
@@ -2314,7 +2339,7 @@ static __le16 iwl_adjust_beacon_interval(u16 beacon_val)
        return cpu_to_le16(new_val);
 }
 
-static void iwl_setup_rxon_timing(struct iwl_priv *priv)
+static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv)
 {
        u64 interval_tm_unit;
        u64 tsf, result;
@@ -2344,14 +2369,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                        priv->rxon_timing.beacon_interval =
                                cpu_to_le16(beacon_int);
                        priv->rxon_timing.beacon_interval =
-                           iwl_adjust_beacon_interval(
+                           iwl3945_adjust_beacon_interval(
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
                }
 
                priv->rxon_timing.atim_window = 0;
        } else {
                priv->rxon_timing.beacon_interval =
-                       iwl_adjust_beacon_interval(conf->beacon_int);
+                       iwl3945_adjust_beacon_interval(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;
@@ -2370,14 +2395,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static int iwl_scan_initiate(struct iwl_priv *priv)
+static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
 {
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
                IWL_ERROR("APs don't scan.\n");
                return 0;
        }
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
                return -EIO;
        }
@@ -2404,9 +2429,9 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt)
 {
-       struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+       struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon;
 
        if (hw_decrypt)
                rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -2416,7 +2441,7 @@ static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
        return 0;
 }
 
-static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
+static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode)
 {
        if (phymode == MODE_IEEE80211A) {
                priv->staging_rxon.flags &=
@@ -2424,7 +2449,7 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
                      | RXON_FLG_CCK_MSK);
                priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
        } else {
-               /* Copied from iwl_bg_post_associate() */
+               /* Copied from iwl3945_bg_post_associate() */
                if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
                        priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
@@ -2440,11 +2465,11 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
 }
 
 /*
- * initilize rxon structure with default values fromm eeprom
+ * initialize rxon structure with default values from eeprom
  */
-static void iwl_connection_init_rx_config(struct iwl_priv *priv)
+static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv)
 {
-       const struct iwl_channel_info *ch_info;
+       const struct iwl3945_channel_info *ch_info;
 
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
@@ -2481,7 +2506,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
                priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
-       ch_info = iwl_get_channel_info(priv, priv->phymode,
+       ch_info = iwl3945_get_channel_info(priv, priv->phymode,
                                       le16_to_cpu(priv->staging_rxon.channel));
 
        if (!ch_info)
@@ -2501,7 +2526,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
        else
                priv->phymode = MODE_IEEE80211G;
 
-       iwl_set_flags_for_phymode(priv, priv->phymode);
+       iwl3945_set_flags_for_phymode(priv, priv->phymode);
 
        priv->staging_rxon.ofdm_basic_rates =
            (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -2509,15 +2534,12 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
            (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
 }
 
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
+static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode)
 {
-       if (!iwl_is_ready_rf(priv))
-               return -EAGAIN;
-
        if (mode == IEEE80211_IF_TYPE_IBSS) {
-               const struct iwl_channel_info *ch_info;
+               const struct iwl3945_channel_info *ch_info;
 
-               ch_info = iwl_get_channel_info(priv,
+               ch_info = iwl3945_get_channel_info(priv,
                        priv->phymode,
                        le16_to_cpu(priv->staging_rxon.channel));
 
@@ -2528,32 +2550,36 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
                }
        }
 
+       priv->iw_mode = mode;
+
+       iwl3945_connection_init_rx_config(priv);
+       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+
+       iwl3945_clear_stations_table(priv);
+
+       /* dont commit rxon if rf-kill is on*/
+       if (!iwl3945_is_ready_rf(priv))
+               return -EAGAIN;
+
        cancel_delayed_work(&priv->scan_check);
-       if (iwl_scan_cancel_timeout(priv, 100)) {
+       if (iwl3945_scan_cancel_timeout(priv, 100)) {
                IWL_WARNING("Aborted scan still in progress after 100ms\n");
                IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
                return -EAGAIN;
        }
 
-       priv->iw_mode = mode;
-
-       iwl_connection_init_rx_config(priv);
-       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
-       iwl_clear_stations_table(priv);
-
-       iwl_commit_rxon(priv);
+       iwl3945_commit_rxon(priv);
 
        return 0;
 }
 
-static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
+static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv,
                                      struct ieee80211_tx_control *ctl,
-                                     struct iwl_cmd *cmd,
+                                     struct iwl3945_cmd *cmd,
                                      struct sk_buff *skb_frag,
                                      int last_frag)
 {
-       struct iwl_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
+       struct iwl3945_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
 
        switch (keyinfo->alg) {
        case ALG_CCMP:
@@ -2596,8 +2622,8 @@ static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
 /*
  * handle build REPLY_TX command notification.
  */
-static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
-                                 struct iwl_cmd *cmd,
+static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
+                                 struct iwl3945_cmd *cmd,
                                  struct ieee80211_tx_control *ctrl,
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
@@ -2645,11 +2671,9 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
        if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
                if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
                    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
-                       cmd->cmd.tx.timeout.pm_frame_timeout =
-                               cpu_to_le16(3);
+                       cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
                else
-                       cmd->cmd.tx.timeout.pm_frame_timeout =
-                               cpu_to_le16(2);
+                       cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
        } else
                cmd->cmd.tx.timeout.pm_frame_timeout = 0;
 
@@ -2658,41 +2682,44 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
        cmd->cmd.tx.next_frame_len = 0;
 }
 
-static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+/**
+ * iwl3945_get_sta_id - Find station's index within station table
+ */
+static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr)
 {
        int sta_id;
        u16 fc = le16_to_cpu(hdr->frame_control);
 
-       /* If this frame is broadcast or not data then use the broadcast
-        * station id */
+       /* 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_setting.bcast_sta_id;
 
        switch (priv->iw_mode) {
 
-       /* If this frame is part of a BSS network (we're a station), then
-        * we use the AP's station id */
+       /* 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 IEEE80211_IF_TYPE_STA:
                return IWL_AP_ID;
 
        /* If we are an AP, then find the station, or use BCAST */
        case IEEE80211_IF_TYPE_AP:
-               sta_id = iwl_hw_find_station(priv, hdr->addr1);
+               sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
                return priv->hw_setting.bcast_sta_id;
 
-       /* If this frame is part of a IBSS network, then we use the
-        * target specific station id */
+       /* If this frame is going out to an IBSS network, find the station,
+        * or create a new station table entry */
        case IEEE80211_IF_TYPE_IBSS: {
                DECLARE_MAC_BUF(mac);
 
-               sta_id = iwl_hw_find_station(priv, hdr->addr1);
+               /* 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 = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
+               sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
 
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
@@ -2700,11 +2727,11 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                IWL_DEBUG_DROP("Station %s not in station map. "
                               "Defaulting to broadcast...\n",
                               print_mac(mac, hdr->addr1));
-               iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+               iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_setting.bcast_sta_id;
        }
        default:
-               IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode);
+               IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
                return priv->hw_setting.bcast_sta_id;
        }
 }
@@ -2712,18 +2739,18 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 /*
  * start REPLY_TX command process
  */
-static int iwl_tx_skb(struct iwl_priv *priv,
+static int iwl3945_tx_skb(struct iwl3945_priv *priv,
                      struct sk_buff *skb, struct ieee80211_tx_control *ctl)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_tfd_frame *tfd;
+       struct iwl3945_tfd_frame *tfd;
        u32 *control_flags;
        int txq_id = ctl->queue;
-       struct iwl_tx_queue *txq = NULL;
-       struct iwl_queue *q = NULL;
+       struct iwl3945_tx_queue *txq = NULL;
+       struct iwl3945_queue *q = NULL;
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
-       struct iwl_cmd *out_cmd = NULL;
+       struct iwl3945_cmd *out_cmd = NULL;
        u16 len, idx, len_org;
        u8 id, hdr_len, unicast;
        u8 sta_id;
@@ -2735,13 +2762,13 @@ static int iwl_tx_skb(struct iwl_priv *priv,
        int rc;
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (iwl_is_rfkill(priv)) {
+       if (iwl3945_is_rfkill(priv)) {
                IWL_DEBUG_DROP("Dropping - RF KILL\n");
                goto drop_unlock;
        }
 
-       if (!priv->interface_id) {
-               IWL_DEBUG_DROP("Dropping - !priv->interface_id\n");
+       if (!priv->vif) {
+               IWL_DEBUG_DROP("Dropping - !priv->vif\n");
                goto drop_unlock;
        }
 
@@ -2755,7 +2782,7 @@ static int iwl_tx_skb(struct iwl_priv *priv,
 
        fc = le16_to_cpu(hdr->frame_control);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL3945_DEBUG
        if (ieee80211_is_auth(fc))
                IWL_DEBUG_TX("Sending AUTH frame\n");
        else if (ieee80211_is_assoc_request(fc))
@@ -2764,16 +2791,19 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                IWL_DEBUG_TX("Sending REASSOC frame\n");
 #endif
 
-       if (!iwl_is_associated(priv) &&
+       /* drop all data frame if we are not associated */
+       if (!iwl3945_is_associated(priv) && !priv->assoc_id &&
            ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
-               IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+               IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
                goto drop_unlock;
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        hdr_len = ieee80211_get_hdrlen(fc);
-       sta_id = iwl_get_sta_id(priv, hdr);
+
+       /* Find (or create) index into station table for destination station */
+       sta_id = iwl3945_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
                DECLARE_MAC_BUF(mac);
 
@@ -2794,32 +2824,54 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                                __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
                seq_number += 0x10;
        }
+
+       /* Descriptor for chosen Tx queue */
        txq = &priv->txq[txq_id];
        q = &txq->q;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       tfd = &txq->bd[q->first_empty];
+       /* Set up first empty TFD within this queue's circular TFD buffer */
+       tfd = &txq->bd[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
        control_flags = (u32 *) tfd;
-       idx = get_cmd_index(q, q->first_empty, 0);
+       idx = get_cmd_index(q, q->write_ptr, 0);
 
-       memset(&(txq->txb[q->first_empty]), 0, sizeof(struct iwl_tx_info));
-       txq->txb[q->first_empty].skb[0] = skb;
-       memcpy(&(txq->txb[q->first_empty].status.control),
+       /* Set up driver data for this TFD */
+       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info));
+       txq->txb[q->write_ptr].skb[0] = skb;
+       memcpy(&(txq->txb[q->write_ptr].status.control),
               ctl, sizeof(struct ieee80211_tx_control));
+
+       /* Init first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = &txq->cmd[idx];
        memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
        memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+
+       /*
+        * Set up the Tx-command (not MAC!) header.
+        * Store the chosen Tx queue and TFD index within the sequence field;
+        * after Tx, uCode's Tx response will return this value so driver can
+        * locate the frame within the tx queue and do post-tx processing.
+        */
        out_cmd->hdr.cmd = REPLY_TX;
        out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
-                               INDEX_TO_SEQ(q->first_empty)));
-       /* copy frags header */
+                               INDEX_TO_SEQ(q->write_ptr)));
+
+       /* Copy MAC header from skb into command buffer */
        memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
 
-       /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */
+       /*
+        * Use the first empty entry in this queue's command buffer array
+        * to contain the Tx command and MAC header concatenated together
+        * (payload data will be in another buffer).
+        * Size of this varies, due to varying MAC header length.
+        * If end is not dword aligned, we'll have 2 extra bytes at the end
+        * of the MAC header (device reads on dword boundaries).
+        * We'll tell device about this padding later.
+        */
        len = priv->hw_setting.tx_cmd_len +
-               sizeof(struct iwl_cmd_header) + hdr_len;
+               sizeof(struct iwl3945_cmd_header) + hdr_len;
 
        len_org = len;
        len = (len + 3) & ~3;
@@ -2829,37 +2881,45 @@ static int iwl_tx_skb(struct iwl_priv *priv,
        else
                len_org = 0;
 
-       txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
-                    offsetof(struct iwl_cmd, hdr);
+       /* Physical address of this Tx command's header (not MAC header!),
+        * within command buffer array. */
+       txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx +
+                    offsetof(struct iwl3945_cmd, hdr);
 
-       iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+       /* Add buffer containing Tx command and MAC(!) header to TFD's
+        * first entry */
+       iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
        if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
-               iwl_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
+               iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
 
-       /* 802.11 null functions have no payload... */
+       /* Set up TFD's 2nd entry to point directly to remainder of skb,
+        * if any (802.11 null frames have no payload). */
        len = skb->len - hdr_len;
        if (len) {
                phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
                                           len, PCI_DMA_TODEVICE);
-               iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+               iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
        }
 
-       /* If there is no payload, then only one TFD is used */
        if (!len)
+               /* If there is no payload, then we use only one Tx buffer */
                *control_flags = TFD_CTL_COUNT_SET(1);
        else
+               /* Else use 2 buffers.
+                * Tell 3945 about any padding after MAC header */
                *control_flags = TFD_CTL_COUNT_SET(2) |
                        TFD_CTL_PAD_SET(U32_PAD(len));
 
+       /* Total # bytes to be transmitted */
        len = (u16)skb->len;
        out_cmd->cmd.tx.len = cpu_to_le16(len);
 
        /* TODO need this for burst mode later on */
-       iwl_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
+       iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
 
        /* set is_hcca to 0; it probably will never be implemented */
-       iwl_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
+       iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
 
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
        out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
@@ -2875,25 +2935,26 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                txq->need_update = 0;
        }
 
-       iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
+       iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
                           sizeof(out_cmd->cmd.tx));
 
-       iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
+       iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
                           ieee80211_get_hdrlen(fc));
 
-       q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd);
-       rc = iwl_tx_queue_update_write_ptr(priv, txq);
+       /* Tell device the write index *just past* this latest filled TFD */
+       q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd);
+       rc = iwl3945_tx_queue_update_write_ptr(priv, txq);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (rc)
                return rc;
 
-       if ((iwl_queue_space(q) < q->high_mark)
+       if ((iwl3945_queue_space(q) < q->high_mark)
            && priv->mac80211_registered) {
                if (wait_write_ptr) {
                        spin_lock_irqsave(&priv->lock, flags);
                        txq->need_update = 1;
-                       iwl_tx_queue_update_write_ptr(priv, txq);
+                       iwl3945_tx_queue_update_write_ptr(priv, txq);
                        spin_unlock_irqrestore(&priv->lock, flags);
                }
 
@@ -2908,13 +2969,13 @@ drop:
        return -1;
 }
 
-static void iwl_set_rate(struct iwl_priv *priv)
+static void iwl3945_set_rate(struct iwl3945_priv *priv)
 {
        const struct ieee80211_hw_mode *hw = NULL;
        struct ieee80211_rate *rate;
        int i;
 
-       hw = iwl_get_hw_mode(priv, priv->phymode);
+       hw = iwl3945_get_hw_mode(priv, priv->phymode);
        if (!hw) {
                IWL_ERROR("Failed to set rate: unable to get hw mode\n");
                return;
@@ -2932,7 +2993,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                if ((rate->val < IWL_RATE_COUNT) &&
                    (rate->flags & IEEE80211_RATE_SUPPORTED)) {
                        IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n",
-                                      rate->val, iwl_rates[rate->val].plcp,
+                                      rate->val, iwl3945_rates[rate->val].plcp,
                                       (rate->flags & IEEE80211_RATE_BASIC) ?
                                       "*" : "");
                        priv->active_rate |= (1 << rate->val);
@@ -2940,7 +3001,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                                priv->active_rate_basic |= (1 << rate->val);
                } else
                        IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n",
-                                      rate->val, iwl_rates[rate->val].plcp);
+                                      rate->val, iwl3945_rates[rate->val].plcp);
        }
 
        IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
@@ -2969,7 +3030,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
 
-static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
+static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
 {
        unsigned long flags;
 
@@ -2980,21 +3041,21 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
                          disable_radio ? "OFF" : "ON");
 
        if (disable_radio) {
-               iwl_scan_cancel(priv);
+               iwl3945_scan_cancel(priv);
                /* FIXME: This is a workaround for AP */
                if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
                        spin_lock_irqsave(&priv->lock, flags);
-                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_SW_BIT_RFKILL);
                        spin_unlock_irqrestore(&priv->lock, flags);
-                       iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
+                       iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
                        set_bit(STATUS_RF_KILL_SW, &priv->status);
                }
                return;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        clear_bit(STATUS_RF_KILL_SW, &priv->status);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -3003,9 +3064,9 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
        msleep(10);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_read32(priv, CSR_UCODE_DRV_GP1);
-       if (!iwl_grab_restricted_access(priv))
-               iwl_release_restricted_access(priv);
+       iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
+       if (!iwl3945_grab_nic_access(priv))
+               iwl3945_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
@@ -3018,7 +3079,7 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
        return;
 }
 
-void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
+void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
                            u32 decrypt_res, struct ieee80211_rx_status *stats)
 {
        u16 fc =
@@ -3050,97 +3111,9 @@ void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
        }
 }
 
-void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
-                                   void *data, short len,
-                                   struct ieee80211_rx_status *stats,
-                                   u16 phy_flags)
-{
-       struct iwl_rt_rx_hdr *iwl_rt;
-
-       /* First cache any information we need before we overwrite
-        * the information provided in the skb from the hardware */
-       s8 signal = stats->ssi;
-       s8 noise = 0;
-       int rate = stats->rate;
-       u64 tsf = stats->mactime;
-       __le16 phy_flags_hw = cpu_to_le16(phy_flags);
-
-       /* We received data from the HW, so stop the watchdog */
-       if (len > IWL_RX_BUF_SIZE - sizeof(*iwl_rt)) {
-               IWL_DEBUG_DROP("Dropping too large packet in monitor\n");
-               return;
-       }
-
-       /* copy the frame data to write after where the radiotap header goes */
-       iwl_rt = (void *)rxb->skb->data;
-       memmove(iwl_rt->payload, data, len);
-
-       iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
-       iwl_rt->rt_hdr.it_pad = 0; /* always good to zero */
-
-       /* total header + data */
-       iwl_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl_rt));
-
-       /* Set the size of the skb to the size of the frame */
-       skb_put(rxb->skb, sizeof(*iwl_rt) + len);
-
-       /* Big bitfield of all the fields we provide in radiotap */
-       iwl_rt->rt_hdr.it_present =
-           cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
-                       (1 << IEEE80211_RADIOTAP_FLAGS) |
-                       (1 << IEEE80211_RADIOTAP_RATE) |
-                       (1 << IEEE80211_RADIOTAP_CHANNEL) |
-                       (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
-                       (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
-                       (1 << IEEE80211_RADIOTAP_ANTENNA));
-
-       /* Zero the flags, we'll add to them as we go */
-       iwl_rt->rt_flags = 0;
-
-       iwl_rt->rt_tsf = cpu_to_le64(tsf);
-
-       /* Convert to dBm */
-       iwl_rt->rt_dbmsignal = signal;
-       iwl_rt->rt_dbmnoise = noise;
-
-       /* Convert the channel frequency and set the flags */
-       iwl_rt->rt_channelMHz = cpu_to_le16(stats->freq);
-       if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
-       else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
-       else    /* 802.11g */
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ));
-
-       rate = iwl_rate_index_from_plcp(rate);
-       if (rate == -1)
-               iwl_rt->rt_rate = 0;
-       else
-               iwl_rt->rt_rate = iwl_rates[rate].ieee;
-
-       /* antenna number */
-       iwl_rt->rt_antenna =
-               le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
-
-       /* set the preamble flag if we have it */
-       if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
-               iwl_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-
-       IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
-
-       stats->flag |= RX_FLAG_RADIOTAP;
-       ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
-       rxb->skb = NULL;
-}
-
-
 #define IWL_PACKET_RETRY_TIME HZ
 
-int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
+int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
 {
        u16 sc = le16_to_cpu(header->seq_ctrl);
        u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
@@ -3151,29 +3124,26 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
        switch (priv->iw_mode) {
        case IEEE80211_IF_TYPE_IBSS:{
                struct list_head *p;
-               struct iwl_ibss_seq *entry = NULL;
+               struct iwl3945_ibss_seq *entry = NULL;
                u8 *mac = header->addr2;
                int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
 
                __list_for_each(p, &priv->ibss_mac_hash[index]) {
-                       entry =
-                               list_entry(p, struct iwl_ibss_seq, list);
+                       entry = list_entry(p, struct iwl3945_ibss_seq, list);
                        if (!compare_ether_addr(entry->mac, mac))
                                break;
                }
                if (p == &priv->ibss_mac_hash[index]) {
                        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
                        if (!entry) {
-                               IWL_ERROR
-                                       ("Cannot malloc new mac entry\n");
+                               IWL_ERROR("Cannot malloc new mac entry\n");
                                return 0;
                        }
                        memcpy(entry->mac, mac, ETH_ALEN);
                        entry->seq_num = seq;
                        entry->frag_num = frag;
                        entry->packet_time = jiffies;
-                       list_add(&entry->list,
-                                &priv->ibss_mac_hash[index]);
+                       list_add(&entry->list, &priv->ibss_mac_hash[index]);
                        return 0;
                }
                last_seq = &entry->seq_num;
@@ -3207,7 +3177,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
        return 1;
 }
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 
 #include "iwl-spectrum.h"
 
@@ -3222,7 +3192,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
  * the lower 3 bytes is the time in usec within one beacon interval
  */
 
-static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
+static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval)
 {
        u32 quot;
        u32 rem;
@@ -3241,7 +3211,7 @@ static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
  * the same as HW timer counter counting down
  */
 
-static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
+static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
 {
        u32 base_low = base & BEACON_TIME_MASK_LOW;
        u32 addon_low = addon & BEACON_TIME_MASK_LOW;
@@ -3260,13 +3230,13 @@ static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
        return cpu_to_le32(res);
 }
 
-static int iwl_get_measurement(struct iwl_priv *priv,
+static int iwl3945_get_measurement(struct iwl3945_priv *priv,
                               struct ieee80211_measurement_params *params,
                               u8 type)
 {
-       struct iwl_spectrum_cmd spectrum;
-       struct iwl_rx_packet *res;
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_spectrum_cmd spectrum;
+       struct iwl3945_rx_packet *res;
+       struct iwl3945_host_cmd cmd = {
                .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
                .data = (void *)&spectrum,
                .meta.flags = CMD_WANT_SKB,
@@ -3276,9 +3246,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
        int spectrum_resp_status;
        int duration = le16_to_cpu(params->duration);
 
-       if (iwl_is_associated(priv))
+       if (iwl3945_is_associated(priv))
                add_time =
-                   iwl_usecs_to_beacons(
+                   iwl3945_usecs_to_beacons(
                        le64_to_cpu(params->start_time) - priv->last_tsf,
                        le16_to_cpu(priv->rxon_timing.beacon_interval));
 
@@ -3291,9 +3261,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
        cmd.len = sizeof(spectrum);
        spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
 
-       if (iwl_is_associated(priv))
+       if (iwl3945_is_associated(priv))
                spectrum.start_time =
-                   iwl_add_beacon_time(priv->last_beacon_time,
+                   iwl3945_add_beacon_time(priv->last_beacon_time,
                                add_time,
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
        else
@@ -3306,11 +3276,11 @@ static int iwl_get_measurement(struct iwl_priv *priv,
                spectrum.flags |= RXON_FLG_BAND_24G_MSK |
                    RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl3945_send_cmd_sync(priv, &cmd);
        if (rc)
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
                rc = -EIO;
@@ -3320,9 +3290,8 @@ static int iwl_get_measurement(struct iwl_priv *priv,
        switch (spectrum_resp_status) {
        case 0:         /* Command will be handled */
                if (res->u.spectrum.id != 0xff) {
-                       IWL_DEBUG_INFO
-                           ("Replaced existing measurement: %d\n",
-                            res->u.spectrum.id);
+                       IWL_DEBUG_INFO("Replaced existing measurement: %d\n",
+                                               res->u.spectrum.id);
                        priv->measurement_status &= ~MEASUREMENT_READY;
                }
                priv->measurement_status |= MEASUREMENT_ACTIVE;
@@ -3340,8 +3309,8 @@ static int iwl_get_measurement(struct iwl_priv *priv,
 }
 #endif
 
-static void iwl_txstatus_to_ieee(struct iwl_priv *priv,
-                                struct iwl_tx_info *tx_sta)
+static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv,
+                                struct iwl3945_tx_info *tx_sta)
 {
 
        tx_sta->status.ack_signal = 0;
@@ -3360,41 +3329,41 @@ static void iwl_txstatus_to_ieee(struct iwl_priv *priv,
 }
 
 /**
- * iwl_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC.
+ * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
  *
- * When FW advances 'R' index, all entries between old and
- * new 'R' index need to be reclaimed. As result, some free space
- * forms. If there is enough free space (> low mark), wake Tx queue.
+ * When FW advances 'R' index, all entries between old and new 'R' index
+ * need to be reclaimed. As result, some free space forms. If there is
+ * enough free space (> low mark), wake the stack that feeds us.
  */
-int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
+static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index)
 {
-       struct iwl_tx_queue *txq = &priv->txq[txq_id];
-       struct iwl_queue *q = &txq->q;
+       struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl3945_queue *q = &txq->q;
        int nfreed = 0;
 
        if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
                          "is out of range [0-%d] %d %d.\n", txq_id,
-                         index, q->n_bd, q->first_empty, q->last_used);
+                         index, q->n_bd, q->write_ptr, q->read_ptr);
                return 0;
        }
 
-       for (index = iwl_queue_inc_wrap(index, q->n_bd);
-               q->last_used != index;
-               q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) {
+       for (index = iwl3945_queue_inc_wrap(index, q->n_bd);
+               q->read_ptr != index;
+               q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) {
                if (txq_id != IWL_CMD_QUEUE_NUM) {
-                       iwl_txstatus_to_ieee(priv,
-                                       &(txq->txb[txq->q.last_used]));
-                       iwl_hw_txq_free_tfd(priv, txq);
+                       iwl3945_txstatus_to_ieee(priv,
+                                       &(txq->txb[txq->q.read_ptr]));
+                       iwl3945_hw_txq_free_tfd(priv, txq);
                } else if (nfreed > 1) {
                        IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
-                                       q->first_empty, q->last_used);
+                                       q->write_ptr, q->read_ptr);
                        queue_work(priv->workqueue, &priv->restart);
                }
                nfreed++;
        }
 
-       if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+       if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
                        (txq_id != IWL_CMD_QUEUE_NUM) &&
                        priv->mac80211_registered)
                ieee80211_wake_queue(priv->hw, txq_id);
@@ -3403,7 +3372,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
        return nfreed;
 }
 
-static int iwl_is_tx_success(u32 status)
+static int iwl3945_is_tx_success(u32 status)
 {
        return (status & 0xFF) == 0x1;
 }
@@ -3413,27 +3382,30 @@ static int iwl_is_tx_success(u32 status)
  * Generic RX handler implementations
  *
  ******************************************************************************/
-static void iwl_rx_reply_tx(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb)
+/**
+ * iwl3945_rx_reply_tx - Handle Tx response
+ */
+static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
+                           struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
-       struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
        struct ieee80211_tx_status *tx_status;
-       struct iwl_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->status);
 
        if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
                          "is out of range [0-%d] %d %d\n", txq_id,
-                         index, txq->q.n_bd, txq->q.first_empty,
-                         txq->q.last_used);
+                         index, txq->q.n_bd, txq->q.write_ptr,
+                         txq->q.read_ptr);
                return;
        }
 
-       tx_status = &(txq->txb[txq->q.last_used].status);
+       tx_status = &(txq->txb[txq->q.read_ptr].status);
 
        tx_status->retry_count = tx_resp->failure_frame;
        tx_status->queue_number = status;
@@ -3441,28 +3413,28 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv,
        tx_status->queue_length |= tx_resp->failure_rts;
 
        tx_status->flags =
-           iwl_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
+           iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
 
-       tx_status->control.tx_rate = iwl_rate_index_from_plcp(tx_resp->rate);
+       tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate);
 
        IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
-                       txq_id, iwl_get_tx_fail_reason(status), status,
+                       txq_id, iwl3945_get_tx_fail_reason(status), status,
                        tx_resp->rate, tx_resp->failure_frame);
 
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        if (index != -1)
-               iwl_tx_queue_reclaim(priv, txq_id, index);
+               iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
 
-static void iwl_rx_reply_alive(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
+                              struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_alive_resp *palive;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_alive_resp *palive;
        struct delayed_work *pwork;
 
        palive = &pkt->u.alive_frame;
@@ -3476,14 +3448,14 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
                IWL_DEBUG_INFO("Initialization Alive received.\n");
                memcpy(&priv->card_alive_init,
                       &pkt->u.alive_frame,
-                      sizeof(struct iwl_init_alive_resp));
+                      sizeof(struct iwl3945_init_alive_resp));
                pwork = &priv->init_alive_start;
        } else {
                IWL_DEBUG_INFO("Runtime Alive received.\n");
                memcpy(&priv->card_alive, &pkt->u.alive_frame,
-                      sizeof(struct iwl_alive_resp));
+                      sizeof(struct iwl3945_alive_resp));
                pwork = &priv->alive_start;
-               iwl_disable_events(priv);
+               iwl3945_disable_events(priv);
        }
 
        /* We delay the ALIVE response by 5ms to
@@ -3495,19 +3467,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
                IWL_WARNING("uCode did not respond OK.\n");
 }
 
-static void iwl_rx_reply_add_sta(struct iwl_priv *priv,
-                                struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv,
+                                struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
 
        IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
        return;
 }
 
-static void iwl_rx_reply_error(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_error(struct iwl3945_priv *priv,
+                              struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
 
        IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
                "seq 0x%04X ser 0x%08X\n",
@@ -3520,23 +3492,23 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
 
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
-static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
-       struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon;
+       struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif);
        IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
                      le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
        rxon->channel = csa->channel;
        priv->staging_rxon.channel = csa->channel;
 }
 
-static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv,
+                                         struct iwl3945_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif);
 
        if (!report->state) {
                IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
@@ -3549,35 +3521,35 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
 #endif
 }
 
-static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv,
+                                 struct iwl3945_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+#ifdef CONFIG_IWL3945_DEBUG
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif);
        IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
 #endif
 }
 
-static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv,
+                                            struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
        IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
                        "notification for %s:\n",
                        le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+       iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
 }
 
-static void iwl_bg_beacon_update(struct work_struct *work)
+static void iwl3945_bg_beacon_update(struct work_struct *work)
 {
-       struct iwl_priv *priv =
-               container_of(work, struct iwl_priv, beacon_update);
+       struct iwl3945_priv *priv =
+               container_of(work, struct iwl3945_priv, beacon_update);
        struct sk_buff *beacon;
 
        /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
-       beacon = ieee80211_beacon_get(priv->hw, priv->interface_id, NULL);
+       beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
 
        if (!beacon) {
                IWL_ERROR("update beacon failed\n");
@@ -3592,15 +3564,15 @@ static void iwl_bg_beacon_update(struct work_struct *work)
        priv->ibss_beacon = beacon;
        mutex_unlock(&priv->mutex);
 
-       iwl_send_beacon_cmd(priv);
+       iwl3945_send_beacon_cmd(priv);
 }
 
-static void iwl_rx_beacon_notif(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv,
+                               struct iwl3945_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_beacon_notif *beacon = &(pkt->u.beacon_status);
+#ifdef CONFIG_IWL3945_DEBUG
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
        u8 rate = beacon->beacon_notify_hdr.rate;
 
        IWL_DEBUG_RX("beacon status %x retries %d iss %d "
@@ -3618,25 +3590,25 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
 }
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl_rx_reply_scan(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv,
+                             struct iwl3945_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanreq_notification *notif =
-           (struct iwl_scanreq_notification *)pkt->u.raw;
+#ifdef CONFIG_IWL3945_DEBUG
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_scanreq_notification *notif =
+           (struct iwl3945_scanreq_notification *)pkt->u.raw;
 
        IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
 #endif
 }
 
 /* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv,
+                                   struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanstart_notification *notif =
-           (struct iwl_scanstart_notification *)pkt->u.raw;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_scanstart_notification *notif =
+           (struct iwl3945_scanstart_notification *)pkt->u.raw;
        priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
        IWL_DEBUG_SCAN("Scan start: "
                       "%d [802.11%s] "
@@ -3648,12 +3620,12 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
 }
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv,
+                                     struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanresults_notification *notif =
-           (struct iwl_scanresults_notification *)pkt->u.raw;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_scanresults_notification *notif =
+           (struct iwl3945_scanresults_notification *)pkt->u.raw;
 
        IWL_DEBUG_SCAN("Scan ch.res: "
                       "%d [802.11%s] "
@@ -3669,14 +3641,15 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
                                        (priv->last_scan_jiffies, jiffies)));
 
        priv->last_scan_jiffies = jiffies;
+       priv->next_scan_jiffies = 0;
 }
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
+                                      struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
 
        IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
                       scan_notif->scanned_channels,
@@ -3711,6 +3684,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
        }
 
        priv->last_scan_jiffies = jiffies;
+       priv->next_scan_jiffies = 0;
        IWL_DEBUG_INFO("Setting scan to off\n");
 
        clear_bit(STATUS_SCANNING, &priv->status);
@@ -3729,10 +3703,10 @@ reschedule:
 
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
-static void iwl_rx_card_state_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv,
+                                   struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
        unsigned long status = priv->status;
 
@@ -3740,7 +3714,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                          (flags & HW_CARD_DISABLED) ? "Kill" : "On",
                          (flags & SW_CARD_DISABLED) ? "Kill" : "On");
 
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        if (flags & HW_CARD_DISABLED)
@@ -3754,7 +3728,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
        else
                clear_bit(STATUS_RF_KILL_SW, &priv->status);
 
-       iwl_scan_cancel(priv);
+       iwl3945_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
             test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -3766,7 +3740,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 }
 
 /**
- * iwl_setup_rx_handlers - Initialize Rx handler callbacks
+ * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks
  *
  * Setup the RX handlers for each of the reply types sent from the uCode
  * to the host.
@@ -3774,61 +3748,58 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
  * This function chains into the hardware specific files for them to setup
  * any hardware specific handlers as well.
  */
-static void iwl_setup_rx_handlers(struct iwl_priv *priv)
+static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
 {
-       priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
-       priv->rx_handlers[REPLY_ADD_STA] = iwl_rx_reply_add_sta;
-       priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
-       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+       priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive;
+       priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta;
+       priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error;
+       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa;
        priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-           iwl_rx_spectrum_measure_notif;
-       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
+           iwl3945_rx_spectrum_measure_notif;
+       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif;
        priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
-           iwl_rx_pm_debug_statistics_notif;
-       priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
-
-       /* NOTE:  iwl_rx_statistics is different based on whether
-        * the build is for the 3945 or the 4965.  See the
-        * corresponding implementation in iwl-XXXX.c
-        *
-        * The same handler is used for both the REPLY to a
-        * discrete statistics request from the host as well as
-        * for the periodic statistics notification from the uCode
+           iwl3945_rx_pm_debug_statistics_notif;
+       priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif;
+
+       /*
+        * The same handler is used for both the REPLY to a discrete
+        * statistics request from the host as well as for the periodic
+        * statistics notifications (after received beacons) from the uCode.
         */
-       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_hw_rx_statistics;
-       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_hw_rx_statistics;
+       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
+       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
 
-       priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan;
-       priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif;
+       priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan;
+       priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif;
        priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
-           iwl_rx_scan_results_notif;
+           iwl3945_rx_scan_results_notif;
        priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
-           iwl_rx_scan_complete_notif;
-       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
-       priv->rx_handlers[REPLY_TX] = iwl_rx_reply_tx;
+           iwl3945_rx_scan_complete_notif;
+       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
+       priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
 
-       /* Setup hardware specific Rx handlers */
-       iwl_hw_rx_handler_setup(priv);
+       /* Set up hardware specific Rx handlers */
+       iwl3945_hw_rx_handler_setup(priv);
 }
 
 /**
- * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
+ * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
  * @rxb: Rx buffer to reclaim
  *
  * If an Rx buffer has an async callback associated with it the callback
  * will be executed.  The attached skb (if present) will only be freed
  * if the callback returns 1
  */
-static void iwl_tx_cmd_complete(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
+                               struct iwl3945_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        int huge = sequence & SEQ_HUGE_FRAME;
        int cmd_index;
-       struct iwl_cmd *cmd;
+       struct iwl3945_cmd *cmd;
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -3849,7 +3820,7 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
                   !cmd->meta.u.callback(priv, cmd, rxb->skb))
                rxb->skb = NULL;
 
-       iwl_tx_queue_reclaim(priv, txq_id, index);
+       iwl3945_tx_queue_reclaim(priv, txq_id, index);
 
        if (!(cmd->meta.flags & CMD_ASYNC)) {
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -3879,10 +3850,10 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  * The queue is empty (no good data) if WRITE = READ - 1, and is full if
  * WRITE = READ.
  *
- * During initialization the host sets up the READ queue position to the first
+ * During initialization, the host sets up the READ queue position to the first
  * INDEX position, and WRITE to the last (READ - 1 wrapped)
  *
- * When the firmware places a packet in a buffer it will advance the READ index
+ * When the firmware places a packet in a buffer, it will advance the READ index
  * and fire the RX interrupt.  The driver can then query the READ index and
  * process as many packets as possible, moving the WRITE index forward as it
  * resets the Rx queue buffers with new memory.
@@ -3890,8 +3861,8 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  * The management in the driver is as follows:
  * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
  *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
- *   to replensish the iwl->rxq->rx_free.
- * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
+ *   to replenish the iwl->rxq->rx_free.
+ * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the
  *   iwl->rxq is replenished and the READ INDEX is updated (updating the
  *   'processed' and 'read' driver indexes as well)
  * + A received packet is processed and handed to the kernel network stack,
@@ -3904,28 +3875,28 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  *
  * Driver sequence:
  *
- * iwl_rx_queue_alloc()       Allocates rx_free
- * iwl_rx_replenish()         Replenishes rx_free list from rx_used, and calls
- *                            iwl_rx_queue_restock
- * iwl_rx_queue_restock()     Moves available buffers from rx_free into Rx
+ * iwl3945_rx_queue_alloc()   Allocates rx_free
+ * iwl3945_rx_replenish()     Replenishes rx_free list from rx_used, and calls
+ *                            iwl3945_rx_queue_restock
+ * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx
  *                            queue, updates firmware pointers, and updates
  *                            the WRITE index.  If insufficient rx_free buffers
- *                            are available, schedules iwl_rx_replenish
+ *                            are available, schedules iwl3945_rx_replenish
  *
  * -- enable interrupts --
- * ISR - iwl_rx()             Detach iwl_rx_mem_buffers from pool up to the
+ * ISR - iwl3945_rx()         Detach iwl3945_rx_mem_buffers from pool up to the
  *                            READ INDEX, detaching the SKB from the pool.
  *                            Moves the packet buffer from queue to rx_used.
- *                            Calls iwl_rx_queue_restock to refill any empty
+ *                            Calls iwl3945_rx_queue_restock to refill any empty
  *                            slots.
  * ...
  *
  */
 
 /**
- * iwl_rx_queue_space - Return number of free slots available in queue.
+ * iwl3945_rx_queue_space - Return number of free slots available in queue.
  */
-static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
+static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q)
 {
        int s = q->read - q->write;
        if (s <= 0)
@@ -3938,15 +3909,9 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
 }
 
 /**
- * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- *
- * NOTE: This function has 3945 and 4965 specific code sections
- * but is declared in base due to the majority of the
- * implementation being the same (only a numeric constant is
- * different)
- *
+ * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue
  */
-int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
+int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q)
 {
        u32 reg = 0;
        int rc = 0;
@@ -3957,24 +3922,29 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
        if (q->need_update == 0)
                goto exit_unlock;
 
+       /* If power-saving is in use, make sure device is awake */
        if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
+                       iwl3945_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        goto exit_unlock;
                }
 
-               rc = iwl_grab_restricted_access(priv);
+               rc = iwl3945_grab_nic_access(priv);
                if (rc)
                        goto exit_unlock;
 
-               iwl_write_restricted(priv, FH_RSCSR_CHNL0_WPTR,
+               /* Device expects a multiple of 8 */
+               iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
                                     q->write & ~0x7);
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
+
+       /* Else device is assumed to be awake */
        } else
-               iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
+               /* Device expects a multiple of 8 */
+               iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
 
 
        q->need_update = 0;
@@ -3985,42 +3955,43 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
 }
 
 /**
- * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer pointer.
- *
- * NOTE: This function has 3945 and 4965 specific code paths in it.
+ * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
  */
-static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
+static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv,
                                          dma_addr_t dma_addr)
 {
        return cpu_to_le32((u32)dma_addr);
 }
 
 /**
- * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
+ * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool
  *
- * If there are slots in the RX queue that  need to be restocked,
+ * If there are slots in the RX queue that need to be restocked,
  * and we have free pre-allocated buffers, fill the ranks as much
- * as we can pulling from rx_free.
+ * as we can, pulling from rx_free.
  *
  * This moves the 'write' index forward to catch up with 'processed', and
  * also updates the memory address in the firmware to reference the new
  * target buffer.
  */
-int iwl_rx_queue_restock(struct iwl_priv *priv)
+static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv)
 {
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl3945_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
+       struct iwl3945_rx_mem_buffer *rxb;
        unsigned long flags;
        int write, rc;
 
        spin_lock_irqsave(&rxq->lock, flags);
        write = rxq->write & ~0x7;
-       while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+       while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+               /* Get next free Rx buffer, remove from free list */
                element = rxq->rx_free.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
                list_del(element);
-               rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+
+               /* Point to Rx buffer via next RBD in circular buffer */
+               rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr);
                rxq->queue[rxq->write] = rxb;
                rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
                rxq->free_count--;
@@ -4032,13 +4003,14 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
                queue_work(priv->workqueue, &priv->rx_replenish);
 
 
-       /* If we've added more space for the firmware to place data, tell it */
+       /* 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))
            || (abs(rxq->write - rxq->read) > 7)) {
                spin_lock_irqsave(&rxq->lock, flags);
                rxq->need_update = 1;
                spin_unlock_irqrestore(&rxq->lock, flags);
-               rc = iwl_rx_queue_update_write_ptr(priv, rxq);
+               rc = iwl3945_rx_queue_update_write_ptr(priv, rxq);
                if (rc)
                        return rc;
        }
@@ -4047,24 +4019,25 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
 }
 
 /**
- * iwl_rx_replensih - Move all used packet from rx_used to rx_free
+ * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free
  *
  * When moving to rx_free an SKB is allocated for the slot.
  *
- * Also restock the Rx queue via iwl_rx_queue_restock.
- * This is called as a scheduled work item (except for during intialization)
+ * Also restock the Rx queue via iwl3945_rx_queue_restock.
+ * This is called as a scheduled work item (except for during initialization)
  */
-void iwl_rx_replenish(void *data)
+static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
 {
-       struct iwl_priv *priv = data;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl3945_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
+       struct iwl3945_rx_mem_buffer *rxb;
        unsigned long flags;
        spin_lock_irqsave(&rxq->lock, flags);
        while (!list_empty(&rxq->rx_used)) {
                element = rxq->rx_used.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list);
+
+               /* Alloc a new receive buffer */
                rxb->skb =
                    alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
                if (!rxb->skb) {
@@ -4076,8 +4049,19 @@ void iwl_rx_replenish(void *data)
                         * more buffers it will schedule replenish */
                        break;
                }
+
+               /* If radiotap head is required, reserve some headroom here.
+                * The physical head count is a variable rx_stats->phy_count.
+                * We reserve 4 bytes here. Plus these extra bytes, the
+                * headroom of the physical head should be enough for the
+                * radiotap head that iwl3945 supported. See iwl3945_rt.
+                */
+               skb_reserve(rxb->skb, 4);
+
                priv->alloc_rxb_skb++;
                list_del(element);
+
+               /* Get physical address of RB/SKB */
                rxb->dma_addr =
                    pci_map_single(priv->pci_dev, rxb->skb->data,
                                   IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
@@ -4085,18 +4069,38 @@ void iwl_rx_replenish(void *data)
                rxq->free_count++;
        }
        spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
+/*
+ * this should be called while priv->lock is locked
+ */
+static void __iwl3945_rx_replenish(void *data)
+{
+       struct iwl3945_priv *priv = data;
+
+       iwl3945_rx_allocate(priv);
+       iwl3945_rx_queue_restock(priv);
+}
+
+
+void iwl3945_rx_replenish(void *data)
+{
+       struct iwl3945_priv *priv = data;
+       unsigned long flags;
+
+       iwl3945_rx_allocate(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_rx_queue_restock(priv);
+       iwl3945_rx_queue_restock(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
+ * 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
  * non NULL it is unmapped and freed
  */
-void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
 {
        int i;
        for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
@@ -4113,21 +4117,25 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        rxq->bd = NULL;
 }
 
-int iwl_rx_queue_alloc(struct iwl_priv *priv)
+int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv)
 {
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl3945_rx_queue *rxq = &priv->rxq;
        struct pci_dev *dev = priv->pci_dev;
        int i;
 
        spin_lock_init(&rxq->lock);
        INIT_LIST_HEAD(&rxq->rx_free);
        INIT_LIST_HEAD(&rxq->rx_used);
+
+       /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
        rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
        if (!rxq->bd)
                return -ENOMEM;
+
        /* Fill the rx_used queue with _all_ of the Rx buffers */
        for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
                list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+
        /* 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;
@@ -4136,7 +4144,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        return 0;
 }
 
-void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
 {
        unsigned long flags;
        int i;
@@ -4183,7 +4191,7 @@ static u8 ratio2dB[100] = {
 /* Calculates a relative dB value from a ratio of linear
  *   (i.e. not dB) signal levels.
  * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
-int iwl_calc_db_from_ratio(int sig_ratio)
+int iwl3945_calc_db_from_ratio(int sig_ratio)
 {
        /* Anything above 1000:1 just report as 60 dB */
        if (sig_ratio > 1000)
@@ -4209,7 +4217,7 @@ int iwl_calc_db_from_ratio(int sig_ratio)
 /* Calculate an indication of rx signal quality (a percentage, not dBm!).
  * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
  *   about formulas used below. */
-int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
+int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm)
 {
        int sig_qual;
        int degradation = PERFECT_RSSI - rssi_dbm;
@@ -4244,24 +4252,30 @@ int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
 }
 
 /**
- * iwl_rx_handle - Main entry function for receiving responses from the uCode
+ * iwl3945_rx_handle - Main entry function for receiving responses from uCode
  *
  * Uses the priv->rx_handlers callback function array to invoke
  * the appropriate handlers, including command responses,
  * frame-received notifications, and other notifications.
  */
-static void iwl_rx_handle(struct iwl_priv *priv)
+static void iwl3945_rx_handle(struct iwl3945_priv *priv)
 {
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl3945_rx_mem_buffer *rxb;
+       struct iwl3945_rx_packet *pkt;
+       struct iwl3945_rx_queue *rxq = &priv->rxq;
        u32 r, i;
        int reclaim;
        unsigned long flags;
+       u8 fill_rx = 0;
+       u32 count = 0;
 
-       r = iwl_hw_get_rx_read(priv);
+       /* uCode's read index (stored in shared DRAM) indicates the last Rx
+        * buffer that the driver may process (last buffer filled by ucode). */
+       r = iwl3945_hw_get_rx_read(priv);
        i = rxq->read;
 
+       if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+               fill_rx = 1;
        /* Rx interrupt, but nothing sent from uCode */
        if (i == r)
                IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
@@ -4269,7 +4283,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
        while (i != r) {
                rxb = rxq->queue[i];
 
-               /* If an RXB doesn't have a queue slot associated with it
+               /* If an RXB doesn't have a Rx queue slot associated with it,
                 * then a bug has been introduced in the queue refilling
                 * routines -- catch it here */
                BUG_ON(rxb == NULL);
@@ -4279,7 +4293,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
                                            IWL_RX_BUF_SIZE,
                                            PCI_DMA_FROMDEVICE);
-               pkt = (struct iwl_rx_packet *)rxb->skb->data;
+               pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
 
                /* Reclaim a command buffer only if this packet is a response
                 *   to a (driver-originated) command.
@@ -4293,7 +4307,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
 
                /* Based on type of command response or notification,
                 *   handle those that need handling via function in
-                *   rx_handlers table.  See iwl_setup_rx_handlers() */
+                *   rx_handlers table.  See iwl3945_setup_rx_handlers() */
                if (priv->rx_handlers[pkt->hdr.cmd]) {
                        IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
                                "r = %d, i = %d, %s, 0x%02x\n", r, i,
@@ -4308,11 +4322,11 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                }
 
                if (reclaim) {
-                       /* Invoke any callbacks, transfer the skb to caller,
-                        * and fire off the (possibly) blocking iwl_send_cmd()
+                       /* Invoke any callbacks, transfer the skb to caller, and
+                        * fire off the (possibly) blocking iwl3945_send_cmd()
                         * as we reclaim the driver command queue */
                        if (rxb && rxb->skb)
-                               iwl_tx_cmd_complete(priv, rxb);
+                               iwl3945_tx_cmd_complete(priv, rxb);
                        else
                                IWL_WARNING("Claim null rxb?\n");
                }
@@ -4332,15 +4346,28 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                list_add_tail(&rxb->list, &priv->rxq.rx_used);
                spin_unlock_irqrestore(&rxq->lock, flags);
                i = (i + 1) & RX_QUEUE_MASK;
+               /* If there are a lot of unused frames,
+                * restock the Rx queue so ucode won't assert. */
+               if (fill_rx) {
+                       count++;
+                       if (count >= 8) {
+                               priv->rxq.read = i;
+                               __iwl3945_rx_replenish(priv);
+                               count = 0;
+                       }
+               }
        }
 
        /* Backtrack one entry */
        priv->rxq.read = i;
-       iwl_rx_queue_restock(priv);
+       iwl3945_rx_queue_restock(priv);
 }
 
-int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv,
-                                 struct iwl_tx_queue *txq)
+/**
+ * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware
+ */
+static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv,
+                                 struct iwl3945_tx_queue *txq)
 {
        u32 reg = 0;
        int rc = 0;
@@ -4354,41 +4381,41 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv,
                /* wake up nic if it's powered down ...
                 * uCode will wake up, and interrupt us again, so next
                 * time we'll skip this part. */
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
                        IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
+                       iwl3945_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        return rc;
                }
 
                /* restore this queue's parameters in nic hardware. */
-               rc = iwl_grab_restricted_access(priv);
+               rc = iwl3945_grab_nic_access(priv);
                if (rc)
                        return rc;
-               iwl_write_restricted(priv, HBUS_TARG_WRPTR,
-                                    txq->q.first_empty | (txq_id << 8));
-               iwl_release_restricted_access(priv);
+               iwl3945_write_direct32(priv, HBUS_TARG_WRPTR,
+                                    txq->q.write_ptr | (txq_id << 8));
+               iwl3945_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). */
        } else
-               iwl_write32(priv, HBUS_TARG_WRPTR,
-                           txq->q.first_empty | (txq_id << 8));
+               iwl3945_write32(priv, HBUS_TARG_WRPTR,
+                           txq->q.write_ptr | (txq_id << 8));
 
        txq->need_update = 0;
 
        return rc;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
+#ifdef CONFIG_IWL3945_DEBUG
+static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon)
 {
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RADIO("RX CONFIG:\n");
-       iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+       iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
        IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
        IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
        IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
@@ -4405,24 +4432,24 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
 }
 #endif
 
-static void iwl_enable_interrupts(struct iwl_priv *priv)
+static void iwl3945_enable_interrupts(struct iwl3945_priv *priv)
 {
        IWL_DEBUG_ISR("Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &priv->status);
-       iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+       iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
 }
 
-static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv)
 {
        clear_bit(STATUS_INT_ENABLED, &priv->status);
 
        /* disable interrupts from uCode/NIC to host */
-       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+       iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* acknowledge/clear/reset any interrupts still pending
         * from uCode or flow handler (Rx/Tx DMA) */
-       iwl_write32(priv, CSR_INT, 0xffffffff);
-       iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
+       iwl3945_write32(priv, CSR_INT, 0xffffffff);
+       iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
        IWL_DEBUG_ISR("Disabled interrupts\n");
 }
 
@@ -4449,7 +4476,7 @@ static const char *desc_lookup(int i)
 #define ERROR_START_OFFSET  (1 * sizeof(u32))
 #define ERROR_ELEM_SIZE     (7 * sizeof(u32))
 
-static void iwl_dump_nic_error_log(struct iwl_priv *priv)
+static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv)
 {
        u32 i;
        u32 desc, time, count, base, data1;
@@ -4458,18 +4485,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
 
        base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
-       if (!iwl_hw_valid_rtc_data_addr(base)) {
+       if (!iwl3945_hw_valid_rtc_data_addr(base)) {
                IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
                return;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
-       count = iwl_read_restricted_mem(priv, base);
+       count = iwl3945_read_targ_mem(priv, base);
 
        if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
                IWL_ERROR("Start IWL Error Log Dump:\n");
@@ -4482,19 +4509,19 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
        for (i = ERROR_START_OFFSET;
             i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET;
             i += ERROR_ELEM_SIZE) {
-               desc = iwl_read_restricted_mem(priv, base + i);
+               desc = iwl3945_read_targ_mem(priv, base + i);
                time =
-                   iwl_read_restricted_mem(priv, base + i + 1 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32));
                blink1 =
-                   iwl_read_restricted_mem(priv, base + i + 2 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32));
                blink2 =
-                   iwl_read_restricted_mem(priv, base + i + 3 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32));
                ilink1 =
-                   iwl_read_restricted_mem(priv, base + i + 4 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32));
                ilink2 =
-                   iwl_read_restricted_mem(priv, base + i + 5 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32));
                data1 =
-                   iwl_read_restricted_mem(priv, base + i + 6 * sizeof(u32));
+                   iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32));
 
                IWL_ERROR
                    ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n",
@@ -4502,18 +4529,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
                     ilink1, ilink2, data1);
        }
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
 }
 
-#define EVENT_START_OFFSET  (4 * sizeof(u32))
+#define EVENT_START_OFFSET  (6 * sizeof(u32))
 
 /**
- * iwl_print_event_log - Dump error event log to syslog
+ * iwl3945_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl_grab_restricted_access() already obtained!
+ * NOTE: Must be called with iwl3945_grab_nic_access() already obtained!
  */
-static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx,
                                u32 num_events, u32 mode)
 {
        u32 i;
@@ -4537,21 +4564,21 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
        /* "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read_restricted_mem(priv, ptr);
+               ev = iwl3945_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
-               time = iwl_read_restricted_mem(priv, ptr);
+               time = iwl3945_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
                if (mode == 0)
                        IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
                else {
-                       data = iwl_read_restricted_mem(priv, ptr);
+                       data = iwl3945_read_targ_mem(priv, ptr);
                        ptr += sizeof(u32);
                        IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
                }
        }
 }
 
-static void iwl_dump_nic_event_log(struct iwl_priv *priv)
+static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv)
 {
        int rc;
        u32 base;       /* SRAM byte address of event log header */
@@ -4562,29 +4589,29 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv)
        u32 size;       /* # entries that we'll print */
 
        base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-       if (!iwl_hw_valid_rtc_data_addr(base)) {
+       if (!iwl3945_hw_valid_rtc_data_addr(base)) {
                IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
                return;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
        /* event log header */
-       capacity = iwl_read_restricted_mem(priv, base);
-       mode = iwl_read_restricted_mem(priv, base + (1 * sizeof(u32)));
-       num_wraps = iwl_read_restricted_mem(priv, base + (2 * sizeof(u32)));
-       next_entry = iwl_read_restricted_mem(priv, base + (3 * sizeof(u32)));
+       capacity = iwl3945_read_targ_mem(priv, base);
+       mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32)));
+       num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32)));
+       next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
        size = num_wraps ? capacity : next_entry;
 
        /* bail out if nothing in log */
        if (size == 0) {
                IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
                return;
        }
 
@@ -4594,31 +4621,31 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv)
        /* if uCode has wrapped back to top of log, start at the oldest entry,
         * i.e the next one that uCode would fill. */
        if (num_wraps)
-               iwl_print_event_log(priv, next_entry,
+               iwl3945_print_event_log(priv, next_entry,
                                    capacity - next_entry, mode);
 
        /* (then/else) start at top of log */
-       iwl_print_event_log(priv, 0, next_entry, mode);
+       iwl3945_print_event_log(priv, 0, next_entry, mode);
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 }
 
 /**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ * iwl3945_irq_handle_error - called for HW or SW error interrupt from card
  */
-static void iwl_irq_handle_error(struct iwl_priv *priv)
+static void iwl3945_irq_handle_error(struct iwl3945_priv *priv)
 {
-       /* Set the FW error flag -- cleared on iwl_down */
+       /* Set the FW error flag -- cleared on iwl3945_down */
        set_bit(STATUS_FW_ERROR, &priv->status);
 
        /* Cancel currently queued command. */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & IWL_DL_FW_ERRORS) {
-               iwl_dump_nic_error_log(priv);
-               iwl_dump_nic_event_log(priv);
-               iwl_print_rx_config_cmd(&priv->staging_rxon);
+#ifdef CONFIG_IWL3945_DEBUG
+       if (iwl3945_debug_level & IWL_DL_FW_ERRORS) {
+               iwl3945_dump_nic_error_log(priv);
+               iwl3945_dump_nic_event_log(priv);
+               iwl3945_print_rx_config_cmd(&priv->staging_rxon);
        }
 #endif
 
@@ -4632,7 +4659,7 @@ static void iwl_irq_handle_error(struct iwl_priv *priv)
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
                          "Restarting adapter due to uCode error.\n");
 
-               if (iwl_is_associated(priv)) {
+               if (iwl3945_is_associated(priv)) {
                        memcpy(&priv->recovery_rxon, &priv->active_rxon,
                               sizeof(priv->recovery_rxon));
                        priv->error_recovering = 1;
@@ -4641,16 +4668,16 @@ static void iwl_irq_handle_error(struct iwl_priv *priv)
        }
 }
 
-static void iwl_error_recovery(struct iwl_priv *priv)
+static void iwl3945_error_recovery(struct iwl3945_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);
+       iwl3945_commit_rxon(priv);
 
-       iwl_add_station(priv, priv->bssid, 1, 0);
+       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);
@@ -4658,12 +4685,12 @@ static void iwl_error_recovery(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl_irq_tasklet(struct iwl_priv *priv)
+static void iwl3945_irq_tasklet(struct iwl3945_priv *priv)
 {
        u32 inta, handled = 0;
        u32 inta_fh;
        unsigned long flags;
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL3945_DEBUG
        u32 inta_mask;
 #endif
 
@@ -4672,18 +4699,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
         *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
-       inta = iwl_read32(priv, CSR_INT);
-       iwl_write32(priv, CSR_INT, inta);
+       inta = iwl3945_read32(priv, CSR_INT);
+       iwl3945_write32(priv, CSR_INT, inta);
 
        /* Ack/clear/reset pending flow-handler (DMA) interrupts.
         * Any new interrupts that happen after this, either while we're
         * in this tasklet, or later, will show up in next ISR/tasklet. */
-       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-       iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+       inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
+       iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & IWL_DL_ISR) {
-               inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+#ifdef CONFIG_IWL3945_DEBUG
+       if (iwl3945_debug_level & IWL_DL_ISR) {
+               /* just for debug */
+               inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
                IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                              inta, inta_mask, inta_fh);
        }
@@ -4703,9 +4731,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                IWL_ERROR("Microcode HW error detected.  Restarting.\n");
 
                /* Tell the device to stop sending interrupts */
-               iwl_disable_interrupts(priv);
+               iwl3945_disable_interrupts(priv);
 
-               iwl_irq_handle_error(priv);
+               iwl3945_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
 
@@ -4714,8 +4742,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                return;
        }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & (IWL_DL_ISR)) {
+#ifdef CONFIG_IWL3945_DEBUG
+       if (iwl3945_debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
                if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
                        IWL_DEBUG_ISR("Microcode started or stopped.\n");
@@ -4731,7 +4759,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* HW RF KILL switch toggled (4965 only) */
        if (inta & CSR_INT_BIT_RF_KILL) {
                int hw_rf_kill = 0;
-               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+               if (!(iwl3945_read32(priv, CSR_GP_CNTRL) &
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                        hw_rf_kill = 1;
 
@@ -4761,20 +4789,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
                          inta);
-               iwl_irq_handle_error(priv);
+               iwl3945_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("Wakeup interrupt\n");
-               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[0]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[1]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[2]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[3]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[4]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+               iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]);
+               iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]);
 
                handled |= CSR_INT_BIT_WAKEUP;
        }
@@ -4783,19 +4811,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
         * 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)) {
-               iwl_rx_handle(priv);
+               iwl3945_rx_handle(priv);
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
 
        if (inta & CSR_INT_BIT_FH_TX) {
                IWL_DEBUG_ISR("Tx interrupt\n");
 
-               iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
-               if (!iwl_grab_restricted_access(priv)) {
-                       iwl_write_restricted(priv,
+               iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
+               if (!iwl3945_grab_nic_access(priv)) {
+                       iwl3945_write_direct32(priv,
                                             FH_TCSR_CREDIT
                                             (ALM_FH_SRVC_CHNL), 0x0);
-                       iwl_release_restricted_access(priv);
+                       iwl3945_release_nic_access(priv);
                }
                handled |= CSR_INT_BIT_FH_TX;
        }
@@ -4810,13 +4838,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        }
 
        /* Re-enable all interrupts */
-       iwl_enable_interrupts(priv);
+       iwl3945_enable_interrupts(priv);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & (IWL_DL_ISR)) {
-               inta = iwl_read32(priv, CSR_INT);
-               inta_mask = iwl_read32(priv, CSR_INT_MASK);
-               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+#ifdef CONFIG_IWL3945_DEBUG
+       if (iwl3945_debug_level & (IWL_DL_ISR)) {
+               inta = iwl3945_read32(priv, CSR_INT);
+               inta_mask = iwl3945_read32(priv, CSR_INT_MASK);
+               inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
                        "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
        }
@@ -4824,9 +4852,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static irqreturn_t iwl_isr(int irq, void *data)
+static irqreturn_t iwl3945_isr(int irq, void *data)
 {
-       struct iwl_priv *priv = data;
+       struct iwl3945_priv *priv = data;
        u32 inta, inta_mask;
        u32 inta_fh;
        if (!priv)
@@ -4838,12 +4866,12 @@ static irqreturn_t iwl_isr(int irq, void *data)
         *    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);
+       inta_mask = iwl3945_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl3945_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* Discover which interrupts are active/pending */
-       inta = iwl_read32(priv, CSR_INT);
-       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+       inta = iwl3945_read32(priv, CSR_INT);
+       inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS);
 
        /* Ignore interrupt if there's nothing in NIC to service.
         * This may be due to IRQ shared with another device,
@@ -4862,7 +4890,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                      inta, inta_mask, inta_fh);
 
-       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       /* iwl3945_irq_tasklet() will service interrupts and re-enable them */
        tasklet_schedule(&priv->irq_tasklet);
 unplugged:
        spin_unlock(&priv->lock);
@@ -4871,18 +4899,18 @@ unplugged:
 
  none:
        /* re-enable interrupts here since we don't have anything to service. */
-       iwl_enable_interrupts(priv);
+       iwl3945_enable_interrupts(priv);
        spin_unlock(&priv->lock);
        return IRQ_NONE;
 }
 
 /************************** EEPROM BANDS ****************************
  *
- * The iwl_eeprom_band definitions below provide the mapping from the
+ * The iwl3945_eeprom_band definitions below provide the mapping from the
  * EEPROM contents to the specific channel number supported for each
  * band.
  *
- * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
+ * For example, iwl3945_priv->eeprom.band_3_channels[4] from the band_3
  * definition below maps to physical channel 42 in the 5.2GHz spectrum.
  * The specific geography and calibration information for that channel
  * is contained in the eeprom map itself.
@@ -4908,58 +4936,58 @@ unplugged:
  *********************************************************************/
 
 /* 2.4 GHz */
-static const u8 iwl_eeprom_band_1[14] = {
+static const u8 iwl3945_eeprom_band_1[14] = {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
 };
 
 /* 5.2 GHz bands */
-static const u8 iwl_eeprom_band_2[] = {
+static const u8 iwl3945_eeprom_band_2[] = {    /* 4915-5080MHz */
        183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
 };
 
-static const u8 iwl_eeprom_band_3[] = {        /* 5205-5320MHz */
+static const u8 iwl3945_eeprom_band_3[] = {    /* 5170-5320MHz */
        34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
 };
 
-static const u8 iwl_eeprom_band_4[] = {        /* 5500-5700MHz */
+static const u8 iwl3945_eeprom_band_4[] = {    /* 5500-5700MHz */
        100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
 };
 
-static const u8 iwl_eeprom_band_5[] = {        /* 5725-5825MHz */
+static const u8 iwl3945_eeprom_band_5[] = {    /* 5725-5825MHz */
        145, 149, 153, 157, 161, 165
 };
 
-static void iwl_init_band_reference(const struct iwl_priv *priv, int band,
+static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band,
                                    int *eeprom_ch_count,
-                                   const struct iwl_eeprom_channel
+                                   const struct iwl3945_eeprom_channel
                                    **eeprom_ch_info,
                                    const u8 **eeprom_ch_index)
 {
        switch (band) {
        case 1:         /* 2.4GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
+               *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
                *eeprom_ch_info = priv->eeprom.band_1_channels;
-               *eeprom_ch_index = iwl_eeprom_band_1;
+               *eeprom_ch_index = iwl3945_eeprom_band_1;
                break;
-       case 2:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
+       case 2:         /* 4.9GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
                *eeprom_ch_info = priv->eeprom.band_2_channels;
-               *eeprom_ch_index = iwl_eeprom_band_2;
+               *eeprom_ch_index = iwl3945_eeprom_band_2;
                break;
        case 3:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
+               *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
                *eeprom_ch_info = priv->eeprom.band_3_channels;
-               *eeprom_ch_index = iwl_eeprom_band_3;
+               *eeprom_ch_index = iwl3945_eeprom_band_3;
                break;
-       case 4:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
+       case 4:         /* 5.5GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
                *eeprom_ch_info = priv->eeprom.band_4_channels;
-               *eeprom_ch_index = iwl_eeprom_band_4;
+               *eeprom_ch_index = iwl3945_eeprom_band_4;
                break;
-       case 5:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
+       case 5:         /* 5.7GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
                *eeprom_ch_info = priv->eeprom.band_5_channels;
-               *eeprom_ch_index = iwl_eeprom_band_5;
+               *eeprom_ch_index = iwl3945_eeprom_band_5;
                break;
        default:
                BUG();
@@ -4967,7 +4995,12 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, int band,
        }
 }
 
-const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
+/**
+ * iwl3945_get_channel_info - Find driver's private channel info
+ *
+ * Based on band and channel number.
+ */
+const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv,
                                                    int phymode, u16 channel)
 {
        int i;
@@ -4994,13 +5027,16 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
 #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
                            ? # x " " : "")
 
-static int iwl_init_channel_map(struct iwl_priv *priv)
+/**
+ * iwl3945_init_channel_map - Set up driver's info for all possible channels
+ */
+static int iwl3945_init_channel_map(struct iwl3945_priv *priv)
 {
        int eeprom_ch_count = 0;
        const u8 *eeprom_ch_index = NULL;
-       const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
+       const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL;
        int band, ch;
-       struct iwl_channel_info *ch_info;
+       struct iwl3945_channel_info *ch_info;
 
        if (priv->channel_count) {
                IWL_DEBUG_INFO("Channel map already initialized.\n");
@@ -5016,15 +5052,15 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
 
        priv->channel_count =
-           ARRAY_SIZE(iwl_eeprom_band_1) +
-           ARRAY_SIZE(iwl_eeprom_band_2) +
-           ARRAY_SIZE(iwl_eeprom_band_3) +
-           ARRAY_SIZE(iwl_eeprom_band_4) +
-           ARRAY_SIZE(iwl_eeprom_band_5);
+           ARRAY_SIZE(iwl3945_eeprom_band_1) +
+           ARRAY_SIZE(iwl3945_eeprom_band_2) +
+           ARRAY_SIZE(iwl3945_eeprom_band_3) +
+           ARRAY_SIZE(iwl3945_eeprom_band_4) +
+           ARRAY_SIZE(iwl3945_eeprom_band_5);
 
        IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
 
-       priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
+       priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) *
                                     priv->channel_count, GFP_KERNEL);
        if (!priv->channel_info) {
                IWL_ERROR("Could not allocate channel_info\n");
@@ -5039,7 +5075,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
         * what just in the EEPROM) */
        for (band = 1; band <= 5; band++) {
 
-               iwl_init_band_reference(priv, band, &eeprom_ch_count,
+               iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
                                        &eeprom_ch_info, &eeprom_ch_index);
 
                /* Loop through each band adding each of the channels */
@@ -5103,6 +5139,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
                }
        }
 
+       /* Set up txpower settings in driver for all channels */
        if (iwl3945_txpower_set_from_eeprom(priv))
                return -EIO;
 
@@ -5132,7 +5169,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode)
+static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode)
 {
        if (phymode == MODE_IEEE80211A)
                return IWL_ACTIVE_DWELL_TIME_52;
@@ -5140,14 +5177,14 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode)
                return IWL_ACTIVE_DWELL_TIME_24;
 }
 
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode)
+static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode)
 {
-       u16 active = iwl_get_active_dwell_time(priv, phymode);
+       u16 active = iwl3945_get_active_dwell_time(priv, phymode);
        u16 passive = (phymode != MODE_IEEE80211A) ?
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
 
-       if (iwl_is_associated(priv)) {
+       if (iwl3945_is_associated(priv)) {
                /* If we're associated, we clamp the maximum passive
                 * dwell time to be 98% of the beacon interval (minus
                 * 2 * channel tune time) */
@@ -5163,30 +5200,30 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode)
        return passive;
 }
 
-static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
+static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode,
                                     u8 is_active, u8 direct_mask,
-                                    struct iwl_scan_channel *scan_ch)
+                                    struct iwl3945_scan_channel *scan_ch)
 {
        const struct ieee80211_channel *channels = NULL;
        const struct ieee80211_hw_mode *hw_mode;
-       const struct iwl_channel_info *ch_info;
+       const struct iwl3945_channel_info *ch_info;
        u16 passive_dwell = 0;
        u16 active_dwell = 0;
        int added, i;
 
-       hw_mode = iwl_get_hw_mode(priv, phymode);
+       hw_mode = iwl3945_get_hw_mode(priv, phymode);
        if (!hw_mode)
                return 0;
 
        channels = hw_mode->channels;
 
-       active_dwell = iwl_get_active_dwell_time(priv, phymode);
-       passive_dwell = iwl_get_passive_dwell_time(priv, phymode);
+       active_dwell = iwl3945_get_active_dwell_time(priv, phymode);
+       passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode);
 
        for (i = 0, added = 0; i < hw_mode->num_channels; i++) {
                if (channels[i].chan ==
                    le16_to_cpu(priv->active_rxon.channel)) {
-                       if (iwl_is_associated(priv)) {
+                       if (iwl3945_is_associated(priv)) {
                                IWL_DEBUG_SCAN
                                    ("Skipping current channel %d\n",
                                     le16_to_cpu(priv->active_rxon.channel));
@@ -5197,7 +5234,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
 
                scan_ch->channel = channels[i].chan;
 
-               ch_info = iwl_get_channel_info(priv, phymode, scan_ch->channel);
+               ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
                        IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
                                       scan_ch->channel);
@@ -5219,7 +5256,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
                scan_ch->active_dwell = cpu_to_le16(active_dwell);
                scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
 
-               /* Set power levels to defaults */
+               /* Set txpower levels to defaults */
                scan_ch->tpc.dsp_atten = 110;
                /* scan_pwr_info->tpc.dsp_atten; */
 
@@ -5229,8 +5266,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
                else {
                        scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
                        /* NOTE: if we were doing 6Mb OFDM for scans we'd use
-                        * power level
-                        scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3;
+                        * power level:
+                        * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
                         */
                }
 
@@ -5248,7 +5285,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
        return added;
 }
 
-static void iwl_reset_channel_flag(struct iwl_priv *priv)
+static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv)
 {
        int i, j;
        for (i = 0; i < 3; i++) {
@@ -5258,13 +5295,13 @@ static void iwl_reset_channel_flag(struct iwl_priv *priv)
        }
 }
 
-static void iwl_init_hw_rates(struct iwl_priv *priv,
+static void iwl3945_init_hw_rates(struct iwl3945_priv *priv,
                              struct ieee80211_rate *rates)
 {
        int i;
 
        for (i = 0; i < IWL_RATE_COUNT; i++) {
-               rates[i].rate = iwl_rates[i].ieee * 5;
+               rates[i].rate = iwl3945_rates[i].ieee * 5;
                rates[i].val = i; /* Rate scaling will work on indexes */
                rates[i].val2 = i;
                rates[i].flags = IEEE80211_RATE_SUPPORTED;
@@ -5276,7 +5313,7 @@ static void iwl_init_hw_rates(struct iwl_priv *priv,
                         * If CCK 1M then set rate flag to CCK else CCK_2
                         * which is CCK | PREAMBLE2
                         */
-                       rates[i].flags |= (iwl_rates[i].plcp == 10) ?
+                       rates[i].flags |= (iwl3945_rates[i].plcp == 10) ?
                                IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2;
                }
 
@@ -5287,11 +5324,11 @@ static void iwl_init_hw_rates(struct iwl_priv *priv,
 }
 
 /**
- * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom
+ * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
  */
-static int iwl_init_geos(struct iwl_priv *priv)
+static int iwl3945_init_geos(struct iwl3945_priv *priv)
 {
-       struct iwl_channel_info *ch;
+       struct iwl3945_channel_info *ch;
        struct ieee80211_hw_mode *modes;
        struct ieee80211_channel *channels;
        struct ieee80211_channel *geo_ch;
@@ -5337,7 +5374,7 @@ static int iwl_init_geos(struct iwl_priv *priv)
 
        /* 5.2GHz channels start after the 2.4GHz channels */
        modes[A].mode = MODE_IEEE80211A;
-       modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
+       modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
        modes[A].rates = &rates[4];
        modes[A].num_rates = 8; /* just OFDM */
        modes[A].num_channels = 0;
@@ -5357,7 +5394,7 @@ static int iwl_init_geos(struct iwl_priv *priv)
        priv->ieee_channels = channels;
        priv->ieee_rates = rates;
 
-       iwl_init_hw_rates(priv, rates);
+       iwl3945_init_hw_rates(priv, rates);
 
        for (i = 0, geo_ch = channels; i < priv->channel_count; i++) {
                ch = &priv->channel_info[i];
@@ -5440,57 +5477,21 @@ static int iwl_init_geos(struct iwl_priv *priv)
  *
  ******************************************************************************/
 
-static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
 {
-       if (priv->ucode_code.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_code.len,
-                                   priv->ucode_code.v_addr,
-                                   priv->ucode_code.p_addr);
-               priv->ucode_code.v_addr = NULL;
-       }
-       if (priv->ucode_data.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_data.len,
-                                   priv->ucode_data.v_addr,
-                                   priv->ucode_data.p_addr);
-               priv->ucode_data.v_addr = NULL;
-       }
-       if (priv->ucode_data_backup.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_data_backup.len,
-                                   priv->ucode_data_backup.v_addr,
-                                   priv->ucode_data_backup.p_addr);
-               priv->ucode_data_backup.v_addr = NULL;
-       }
-       if (priv->ucode_init.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_init.len,
-                                   priv->ucode_init.v_addr,
-                                   priv->ucode_init.p_addr);
-               priv->ucode_init.v_addr = NULL;
-       }
-       if (priv->ucode_init_data.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_init_data.len,
-                                   priv->ucode_init_data.v_addr,
-                                   priv->ucode_init_data.p_addr);
-               priv->ucode_init_data.v_addr = NULL;
-       }
-       if (priv->ucode_boot.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_boot.len,
-                                   priv->ucode_boot.v_addr,
-                                   priv->ucode_boot.p_addr);
-               priv->ucode_boot.v_addr = NULL;
-       }
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
 }
 
 /**
- * iwl_verify_inst_full - verify runtime uCode image in card vs. host,
+ * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
  *     looking at all data.
  */
-static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
+static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len)
 {
        u32 val;
        u32 save_len = len;
@@ -5499,18 +5500,18 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+       iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
 
        errcnt = 0;
        for (; len > 0; len -= sizeof(u32), image++) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("uCode INST section is invalid at "
                                  "offset 0x%x, is 0x%x, s/b 0x%x\n",
@@ -5522,22 +5523,21 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
                }
        }
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        if (!errcnt)
-               IWL_DEBUG_INFO
-                   ("ucode image in INSTRUCTION memory is good\n");
+               IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n");
 
        return rc;
 }
 
 
 /**
- * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
+ * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host,
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len)
 {
        u32 val;
        int rc = 0;
@@ -5546,7 +5546,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc)
                return rc;
 
@@ -5554,9 +5554,9 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR,
+               iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR,
                        i + RTC_INST_LOWER_BOUND);
-               val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
 #if 0 /* Enable this if you want to see details */
                        IWL_ERROR("uCode INST section is invalid at "
@@ -5570,17 +5570,17 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
                }
        }
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        return rc;
 }
 
 
 /**
- * iwl_verify_ucode - determine which instruction image is in SRAM,
+ * iwl3945_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl_verify_ucode(struct iwl_priv *priv)
+static int iwl3945_verify_ucode(struct iwl3945_priv *priv)
 {
        __le32 *image;
        u32 len;
@@ -5589,7 +5589,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try bootstrap */
        image = (__le32 *)priv->ucode_boot.v_addr;
        len = priv->ucode_boot.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl3945_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
                return 0;
@@ -5598,7 +5598,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try initialize */
        image = (__le32 *)priv->ucode_init.v_addr;
        len = priv->ucode_init.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl3945_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
                return 0;
@@ -5607,7 +5607,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try runtime/protocol */
        image = (__le32 *)priv->ucode_code.v_addr;
        len = priv->ucode_code.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl3945_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
                return 0;
@@ -5615,18 +5615,19 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
 
        IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
 
-       /* Show first several data entries in instruction SRAM.
-        * Selection of bootstrap image is arbitrary. */
+       /* Since nothing seems to match, show first several data entries in
+        * instruction SRAM, so maybe visual inspection will give a clue.
+        * Selection of bootstrap image (vs. other images) is arbitrary. */
        image = (__le32 *)priv->ucode_boot.v_addr;
        len = priv->ucode_boot.len;
-       rc = iwl_verify_inst_full(priv, image, len);
+       rc = iwl3945_verify_inst_full(priv, image, len);
 
        return rc;
 }
 
 
 /* check contents of special bootstrap uCode SRAM */
-static int iwl_verify_bsm(struct iwl_priv *priv)
+static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
 {
        __le32 *image = priv->ucode_boot.v_addr;
        u32 len = priv->ucode_boot.len;
@@ -5636,11 +5637,11 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Begin verify bsm\n");
 
        /* verify BSM SRAM contents */
-       val = iwl_read_restricted_reg(priv, BSM_WR_DWCOUNT_REG);
+       val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
        for (reg = BSM_SRAM_LOWER_BOUND;
             reg < BSM_SRAM_LOWER_BOUND + len;
             reg += sizeof(u32), image ++) {
-               val = iwl_read_restricted_reg(priv, reg);
+               val = iwl3945_read_prph(priv, reg);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("BSM uCode verification failed at "
                                  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
@@ -5657,7 +5658,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
 }
 
 /**
- * iwl_load_bsm - Load bootstrap instructions
+ * iwl3945_load_bsm - Load bootstrap instructions
  *
  * BSM operation:
  *
@@ -5688,7 +5689,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
  * the runtime uCode instructions and the backup data cache into SRAM,
  * and re-launches the runtime uCode from where it left off.
  */
-static int iwl_load_bsm(struct iwl_priv *priv)
+static int iwl3945_load_bsm(struct iwl3945_priv *priv)
 {
        __le32 *image = priv->ucode_boot.v_addr;
        u32 len = priv->ucode_boot.len;
@@ -5708,8 +5709,8 @@ static int iwl_load_bsm(struct iwl_priv *priv)
                return -EINVAL;
 
        /* Tell bootstrap uCode where to find the "Initialize" uCode
-        *   in host DRAM ... bits 31:0 for 3945, bits 35:4 for 4965.
-        * NOTE:  iwl_initialize_alive_start() will replace these values,
+        *   in host DRAM ... host DRAM physical address bits 31:0 for 3945.
+        * NOTE:  iwl3945_initialize_alive_start() will replace these values,
         *        after the "initialize" uCode has run, to point to
         *        runtime/protocol instructions and backup data cache. */
        pinst = priv->ucode_init.p_addr;
@@ -5717,42 +5718,42 @@ static int iwl_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+       iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+       iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
 
        /* Fill BSM memory with bootstrap instructions */
        for (reg_offset = BSM_SRAM_LOWER_BOUND;
             reg_offset < BSM_SRAM_LOWER_BOUND + len;
             reg_offset += sizeof(u32), image++)
-               _iwl_write_restricted_reg(priv, reg_offset,
+               _iwl3945_write_prph(priv, reg_offset,
                                          le32_to_cpu(*image));
 
-       rc = iwl_verify_bsm(priv);
+       rc = iwl3945_verify_bsm(priv);
        if (rc) {
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
                return rc;
        }
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
-       iwl_write_restricted_reg(priv, BSM_WR_MEM_SRC_REG, 0x0);
-       iwl_write_restricted_reg(priv, BSM_WR_MEM_DST_REG,
+       iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+       iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG,
                                 RTC_INST_LOWER_BOUND);
-       iwl_write_restricted_reg(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+       iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
 
        /* Load bootstrap code into instruction SRAM now,
         *   to prepare to load "initialize" uCode */
-       iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG,
+       iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START);
 
        /* Wait for load of bootstrap uCode to finish */
        for (i = 0; i < 100; i++) {
-               done = iwl_read_restricted_reg(priv, BSM_WR_CTRL_REG);
+               done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG);
                if (!(done & BSM_WR_CTRL_REG_BIT_START))
                        break;
                udelay(10);
@@ -5766,29 +5767,29 @@ static int iwl_load_bsm(struct iwl_priv *priv)
 
        /* Enable future boot loads whenever power management unit triggers it
         *   (e.g. when powering back up after power-save shutdown) */
-       iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG,
+       iwl3945_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START_EN);
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        return 0;
 }
 
-static void iwl_nic_start(struct iwl_priv *priv)
+static void iwl3945_nic_start(struct iwl3945_priv *priv)
 {
        /* Remove all resets to allow NIC to operate */
-       iwl_write32(priv, CSR_RESET, 0);
+       iwl3945_write32(priv, CSR_RESET, 0);
 }
 
 /**
- * iwl_read_ucode - Read uCode images from disk file.
+ * iwl3945_read_ucode - Read uCode images from disk file.
  *
  * Copy into buffers for card to fetch via bus-mastering
  */
-static int iwl_read_ucode(struct iwl_priv *priv)
+static int iwl3945_read_ucode(struct iwl3945_priv *priv)
 {
-       struct iwl_ucode *ucode;
-       int rc = 0;
+       struct iwl3945_ucode *ucode;
+       int ret = 0;
        const struct firmware *ucode_raw;
        /* firmware file name contains uCode/driver compatibility version */
        const char *name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode";
@@ -5798,9 +5799,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
        /* Ask kernel firmware_class module to get the boot firmware off disk.
         * request_firmware() is synchronous, file is in memory on return. */
-       rc = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
-       if (rc < 0) {
-               IWL_ERROR("%s firmware file req failed: Reason %d\n", name, rc);
+       ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
+       if (ret < 0) {
+               IWL_ERROR("%s firmware file req failed: Reason %d\n",
+                               name, ret);
                goto error;
        }
 
@@ -5810,7 +5812,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        /* Make sure that we got at least our header! */
        if (ucode_raw->size < sizeof(*ucode)) {
                IWL_ERROR("File size way too small!\n");
-               rc = -EINVAL;
+               ret = -EINVAL;
                goto err_release;
        }
 
@@ -5825,16 +5827,11 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        boot_size = le32_to_cpu(ucode->boot_size);
 
        IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver);
-       IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n",
-                      inst_size);
-       IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n",
-                      data_size);
-       IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n",
-                      init_size);
-       IWL_DEBUG_INFO("f/w package hdr init data size = %u\n",
-                      init_data_size);
-       IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n",
-                      boot_size);
+       IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size);
+       IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size);
+       IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size);
+       IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size);
+       IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size);
 
        /* Verify size of file vs. image size info in file's header */
        if (ucode_raw->size < sizeof(*ucode) +
@@ -5843,43 +5840,40 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
                IWL_DEBUG_INFO("uCode file size %d too small\n",
                               (int)ucode_raw->size);
-               rc = -EINVAL;
+               ret = -EINVAL;
                goto err_release;
        }
 
        /* Verify that uCode images will fit in card's SRAM */
        if (inst_size > IWL_MAX_INST_SIZE) {
-               IWL_DEBUG_INFO("uCode instr len %d too large to fit in card\n",
-                              (int)inst_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+                              inst_size);
+               ret = -EINVAL;
                goto err_release;
        }
 
        if (data_size > IWL_MAX_DATA_SIZE) {
-               IWL_DEBUG_INFO("uCode data len %d too large to fit in card\n",
-                              (int)data_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+                              data_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (init_size > IWL_MAX_INST_SIZE) {
-               IWL_DEBUG_INFO
-                   ("uCode init instr len %d too large to fit in card\n",
-                    (int)init_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n",
+                               init_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (init_data_size > IWL_MAX_DATA_SIZE) {
-               IWL_DEBUG_INFO
-                   ("uCode init data len %d too large to fit in card\n",
-                    (int)init_data_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n",
+                               init_data_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (boot_size > IWL_MAX_BSM_SIZE) {
-               IWL_DEBUG_INFO
-                   ("uCode boot instr len %d too large to fit in bsm\n",
-                    (int)boot_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n",
+                               boot_size);
+               ret = -EINVAL;
                goto err_release;
        }
 
@@ -5889,66 +5883,54 @@ static int iwl_read_ucode(struct iwl_priv *priv)
         * 1) unmodified from disk
         * 2) backup cache for save/restore during power-downs */
        priv->ucode_code.len = inst_size;
-       priv->ucode_code.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_code.len,
-                                &(priv->ucode_code.p_addr));
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
 
        priv->ucode_data.len = data_size;
-       priv->ucode_data.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_data.len,
-                                &(priv->ucode_data.p_addr));
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
 
        priv->ucode_data_backup.len = data_size;
-       priv->ucode_data_backup.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_data_backup.len,
-                                &(priv->ucode_data_backup.p_addr));
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
 
+       if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
+           !priv->ucode_data_backup.v_addr)
+               goto err_pci_alloc;
 
        /* Initialization instructions and data */
-       priv->ucode_init.len = init_size;
-       priv->ucode_init.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_init.len,
-                                &(priv->ucode_init.p_addr));
-
-       priv->ucode_init_data.len = init_data_size;
-       priv->ucode_init_data.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_init_data.len,
-                                &(priv->ucode_init_data.p_addr));
+       if (init_size && init_data_size) {
+               priv->ucode_init.len = init_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
+
+               priv->ucode_init_data.len = init_data_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
+
+               if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
+                       goto err_pci_alloc;
+       }
 
        /* Bootstrap (instructions only, no data) */
-       priv->ucode_boot.len = boot_size;
-       priv->ucode_boot.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_boot.len,
-                                &(priv->ucode_boot.p_addr));
+       if (boot_size) {
+               priv->ucode_boot.len = boot_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
 
-       if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
-           !priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr ||
-           !priv->ucode_boot.v_addr || !priv->ucode_data_backup.v_addr)
-               goto err_pci_alloc;
+               if (!priv->ucode_boot.v_addr)
+                       goto err_pci_alloc;
+       }
 
        /* Copy images into buffers for card's bus-master reads ... */
 
        /* Runtime instructions (first block of data in file) */
        src = &ucode->data[0];
        len = priv->ucode_code.len;
-       IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %d\n",
-                      (int)len);
+       IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
        memcpy(priv->ucode_code.v_addr, src, len);
        IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
                priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
        /* Runtime data (2nd block)
-        * NOTE:  Copy into backup buffer will be done in iwl_up()  */
+        * NOTE:  Copy into backup buffer will be done in iwl3945_up()  */
        src = &ucode->data[inst_size];
        len = priv->ucode_data.len;
-       IWL_DEBUG_INFO("Copying (but not loading) uCode data len %d\n",
-                      (int)len);
+       IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
        memcpy(priv->ucode_data.v_addr, src, len);
        memcpy(priv->ucode_data_backup.v_addr, src, len);
 
@@ -5956,8 +5938,8 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        if (init_size) {
                src = &ucode->data[inst_size + data_size];
                len = priv->ucode_init.len;
-               IWL_DEBUG_INFO("Copying (but not loading) init instr len %d\n",
-                              (int)len);
+               IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
+                              len);
                memcpy(priv->ucode_init.v_addr, src, len);
        }
 
@@ -5983,19 +5965,19 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
  err_pci_alloc:
        IWL_ERROR("failed to allocate pci memory\n");
-       rc = -ENOMEM;
-       iwl_dealloc_ucode_pci(priv);
+       ret = -ENOMEM;
+       iwl3945_dealloc_ucode_pci(priv);
 
  err_release:
        release_firmware(ucode_raw);
 
  error:
-       return rc;
+       return ret;
 }
 
 
 /**
- * iwl_set_ucode_ptrs - Set uCode address location
+ * iwl3945_set_ucode_ptrs - Set uCode address location
  *
  * Tell initialization uCode where to find runtime uCode.
  *
@@ -6003,7 +5985,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
  * We need to replace them to load runtime uCode inst and data,
  * and to save runtime data when powering down.
  */
-static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
+static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv)
 {
        dma_addr_t pinst;
        dma_addr_t pdata;
@@ -6015,24 +5997,24 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
        pdata = priv->ucode_data_backup.p_addr;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_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_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+       iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
        /* Inst bytecount must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+       iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
 
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -6042,17 +6024,13 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
 }
 
 /**
- * iwl_init_alive_start - Called after REPLY_ALIVE notification receieved
+ * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received
  *
  * Called after REPLY_ALIVE notification received from "initialize" uCode.
  *
- * The 4965 "initialize" ALIVE reply contains calibration data for:
- *   Voltage, temperature, and MIMO tx gain correction, now stored in priv
- *   (3945 does not contain this data).
- *
  * Tell "initialize" uCode to go ahead and load the runtime uCode.
-*/
-static void iwl_init_alive_start(struct iwl_priv *priv)
+ */
+static void iwl3945_init_alive_start(struct iwl3945_priv *priv)
 {
        /* Check alive response for "valid" sign from uCode */
        if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
@@ -6065,7 +6043,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
        /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
         * This is a paranoid check, because we would not have gotten the
         * "initialize" alive if code weren't properly loaded.  */
-       if (iwl_verify_ucode(priv)) {
+       if (iwl3945_verify_ucode(priv)) {
                /* Runtime instruction load was bad;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
@@ -6076,7 +6054,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
         * load and launch runtime uCode, which will send us another "Alive"
         * notification. */
        IWL_DEBUG_INFO("Initialization Alive received.\n");
-       if (iwl_set_ucode_ptrs(priv)) {
+       if (iwl3945_set_ucode_ptrs(priv)) {
                /* Runtime instruction load won't happen;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
@@ -6090,11 +6068,11 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
 
 
 /**
- * iwl_alive_start - called after REPLY_ALIVE notification received
+ * iwl3945_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
- *                   Alive gets handled by iwl_init_alive_start()).
+ *                   Alive gets handled by iwl3945_init_alive_start()).
  */
-static void iwl_alive_start(struct iwl_priv *priv)
+static void iwl3945_alive_start(struct iwl3945_priv *priv)
 {
        int rc = 0;
        int thermal_spin = 0;
@@ -6112,30 +6090,30 @@ static void iwl_alive_start(struct iwl_priv *priv)
        /* Initialize uCode has loaded Runtime uCode ... verify inst image.
         * This is a paranoid check, because we would not have gotten the
         * "runtime" alive if code weren't properly loaded.  */
-       if (iwl_verify_ucode(priv)) {
+       if (iwl3945_verify_ucode(priv)) {
                /* Runtime instruction load was bad;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Bad runtime uCode load.\n");
                goto restart;
        }
 
-       iwl_clear_stations_table(priv);
+       iwl3945_clear_stations_table(priv);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl3945_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read rfkill status from adapter\n");
                return;
        }
 
-       rfkill = iwl_read_restricted_reg(priv, APMG_RFKILL_REG);
+       rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG);
        IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill);
-       iwl_release_restricted_access(priv);
+       iwl3945_release_nic_access(priv);
 
        if (rfkill & 0x1) {
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
                /* if rfkill is not on, then wait for thermal
                 * sensor in adapter to kick in */
-               while (iwl_hw_get_temperature(priv) == 0) {
+               while (iwl3945_hw_get_temperature(priv) == 0) {
                        thermal_spin++;
                        udelay(10);
                }
@@ -6146,68 +6124,49 @@ static void iwl_alive_start(struct iwl_priv *priv)
        } else
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
-       /* After the ALIVE response, we can process host commands */
+       /* 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);
 
-       rc = iwl_init_channel_map(priv);
+       rc = iwl3945_init_channel_map(priv);
        if (rc) {
                IWL_ERROR("initializing regulatory failed: %d\n", rc);
                return;
        }
 
-       iwl_init_geos(priv);
+       iwl3945_init_geos(priv);
+       iwl3945_reset_channel_flag(priv);
 
-       if (iwl_is_rfkill(priv))
+       if (iwl3945_is_rfkill(priv))
                return;
 
-       if (!priv->mac80211_registered) {
-               /* Unlock so any user space entry points can call back into
-                * the driver without a deadlock... */
-               mutex_unlock(&priv->mutex);
-               iwl_rate_control_register(priv->hw);
-               rc = ieee80211_register_hw(priv->hw);
-               priv->hw->conf.beacon_int = 100;
-               mutex_lock(&priv->mutex);
-
-               if (rc) {
-                       iwl_rate_control_unregister(priv->hw);
-                       IWL_ERROR("Failed to register network "
-                                 "device (error %d)\n", rc);
-                       return;
-               }
-
-               priv->mac80211_registered = 1;
-
-               iwl_reset_channel_flag(priv);
-       } else
-               ieee80211_start_queues(priv->hw);
+       ieee80211_start_queues(priv->hw);
 
        priv->active_rate = priv->rates_mask;
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-       iwl_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
+       iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
 
-       if (iwl_is_associated(priv)) {
-               struct iwl_rxon_cmd *active_rxon =
-                               (struct iwl_rxon_cmd *)(&priv->active_rxon);
+       if (iwl3945_is_associated(priv)) {
+               struct iwl3945_rxon_cmd *active_rxon =
+                               (struct iwl3945_rxon_cmd *)(&priv->active_rxon);
 
                memcpy(&priv->staging_rxon, &priv->active_rxon,
                       sizeof(priv->staging_rxon));
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               iwl_connection_init_rx_config(priv);
+               iwl3945_connection_init_rx_config(priv);
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
-       /* Configure BT coexistence */
-       iwl_send_bt_config(priv);
+       /* Configure Bluetooth device coexistence support */
+       iwl3945_send_bt_config(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwl_commit_rxon(priv);
+       iwl3945_commit_rxon(priv);
 
        /* At this point, the NIC is initialized and operational */
        priv->notif_missed_beacons = 0;
@@ -6216,9 +6175,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
        iwl3945_reg_txpower_periodic(priv);
 
        IWL_DEBUG_INFO("ALIVE processing complete.\n");
+       wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
-               iwl_error_recovery(priv);
+               iwl3945_error_recovery(priv);
 
        return;
 
@@ -6226,9 +6186,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
        queue_work(priv->workqueue, &priv->restart);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv);
+static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv);
 
-static void __iwl_down(struct iwl_priv *priv)
+static void __iwl3945_down(struct iwl3945_priv *priv)
 {
        unsigned long flags;
        int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -6241,7 +6201,7 @@ static void __iwl_down(struct iwl_priv *priv)
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-       iwl_clear_stations_table(priv);
+       iwl3945_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
        wake_up_interruptible_all(&priv->wait_command_queue);
@@ -6252,17 +6212,17 @@ static void __iwl_down(struct iwl_priv *priv)
                clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* stop and reset the on-board processor */
-       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+       iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 
        /* tell the device to stop sending interrupts */
-       iwl_disable_interrupts(priv);
+       iwl3945_disable_interrupts(priv);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
 
-       /* If we have not previously called iwl_init() then
+       /* If we have not previously called iwl3945_init() then
         * clear all bits but the RF Kill and SUSPEND bits and return */
-       if (!iwl_is_init(priv)) {
+       if (!iwl3945_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) <<
@@ -6284,51 +6244,50 @@ static void __iwl_down(struct iwl_priv *priv)
                                STATUS_FW_ERROR;
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_hw_txq_ctx_stop(priv);
-       iwl_hw_rxq_stop(priv);
+       iwl3945_hw_txq_ctx_stop(priv);
+       iwl3945_hw_rxq_stop(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl_grab_restricted_access(priv)) {
-               iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG,
+       if (!iwl3945_grab_nic_access(priv)) {
+               iwl3945_write_prph(priv, APMG_CLK_DIS_REG,
                                         APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_restricted_access(priv);
+               iwl3945_release_nic_access(priv);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        udelay(5);
 
-       iwl_hw_nic_stop_master(priv);
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-       iwl_hw_nic_reset(priv);
+       iwl3945_hw_nic_stop_master(priv);
+       iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       iwl3945_hw_nic_reset(priv);
 
  exit:
-       memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
+       memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp));
 
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
        priv->ibss_beacon = NULL;
 
        /* clear out any free frames */
-       iwl_clear_free_frames(priv);
+       iwl3945_clear_free_frames(priv);
 }
 
-static void iwl_down(struct iwl_priv *priv)
+static void iwl3945_down(struct iwl3945_priv *priv)
 {
        mutex_lock(&priv->mutex);
-       __iwl_down(priv);
+       __iwl3945_down(priv);
        mutex_unlock(&priv->mutex);
 
-       iwl_cancel_deferred_work(priv);
+       iwl3945_cancel_deferred_work(priv);
 }
 
 #define MAX_HW_RESTARTS 5
 
-static int __iwl_up(struct iwl_priv *priv)
+static int __iwl3945_up(struct iwl3945_priv *priv)
 {
-       DECLARE_MAC_BUF(mac);
        int rc, i;
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
@@ -6339,7 +6298,19 @@ static int __iwl_up(struct iwl_priv *priv)
        if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
                IWL_WARNING("Radio disabled by SW RF kill (module "
                            "parameter)\n");
-               return 0;
+               return -ENODEV;
+       }
+
+       /* If platform's RF_KILL switch is NOT set to KILL */
+       if (iwl3945_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_IN_SUSPEND, &priv->status)) {
+                       IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+                       return -ENODEV;
+               }
        }
 
        if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
@@ -6347,41 +6318,45 @@ static int __iwl_up(struct iwl_priv *priv)
                return -EIO;
        }
 
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
 
-       rc = iwl_hw_nic_init(priv);
+       rc = iwl3945_hw_nic_init(priv);
        if (rc) {
                IWL_ERROR("Unable to int nic\n");
                return rc;
        }
 
        /* make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        /* clear (again), then enable host interrupts */
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl_enable_interrupts(priv);
+       iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl3945_enable_interrupts(priv);
 
        /* really make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        /* Copy original ucode data image from disk into backup cache.
         * This will be used to initialize the on-board processor's
         * data SRAM for a clean start when the runtime program first loads. */
        memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
-                       priv->ucode_data.len);
+              priv->ucode_data.len);
+
+       /* We return success when we resume from suspend and rf_kill is on. */
+       if (test_bit(STATUS_RF_KILL_HW, &priv->status))
+               return 0;
 
        for (i = 0; i < MAX_HW_RESTARTS; i++) {
 
-               iwl_clear_stations_table(priv);
+               iwl3945_clear_stations_table(priv);
 
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
                 * prepare to load the "initialize" uCode */
-               rc = iwl_load_bsm(priv);
+               rc = iwl3945_load_bsm(priv);
 
                if (rc) {
                        IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
@@ -6389,14 +6364,7 @@ static int __iwl_up(struct iwl_priv *priv)
                }
 
                /* start card; "initialize" will load runtime ucode */
-               iwl_nic_start(priv);
-
-               /* MAC Address location in EEPROM same for 3945/4965 */
-               get_eeprom_mac(priv, priv->mac_addr);
-               IWL_DEBUG_INFO("MAC address: %s\n",
-                              print_mac(mac, priv->mac_addr));
-
-               SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+               iwl3945_nic_start(priv);
 
                IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
 
@@ -6404,7 +6372,7 @@ static int __iwl_up(struct iwl_priv *priv)
        }
 
        set_bit(STATUS_EXIT_PENDING, &priv->status);
-       __iwl_down(priv);
+       __iwl3945_down(priv);
 
        /* tried to restart and config the device for as long as our
         * patience could withstand */
@@ -6419,35 +6387,35 @@ static int __iwl_up(struct iwl_priv *priv)
  *
  *****************************************************************************/
 
-static void iwl_bg_init_alive_start(struct work_struct *data)
+static void iwl3945_bg_init_alive_start(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, init_alive_start.work);
+       struct iwl3945_priv *priv =
+           container_of(data, struct iwl3945_priv, init_alive_start.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_init_alive_start(priv);
+       iwl3945_init_alive_start(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_alive_start(struct work_struct *data)
+static void iwl3945_bg_alive_start(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, alive_start.work);
+       struct iwl3945_priv *priv =
+           container_of(data, struct iwl3945_priv, alive_start.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_alive_start(priv);
+       iwl3945_alive_start(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_rf_kill(struct work_struct *work)
+static void iwl3945_bg_rf_kill(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+       struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill);
 
        wake_up_interruptible(&priv->wait_command_queue);
 
@@ -6456,7 +6424,7 @@ static void iwl_bg_rf_kill(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_rfkill(priv)) {
+       if (!iwl3945_is_rfkill(priv)) {
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
                          "HW and/or SW RF Kill no longer active, restarting "
                          "device\n");
@@ -6477,10 +6445,10 @@ static void iwl_bg_rf_kill(struct work_struct *work)
 
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
-static void iwl_bg_scan_check(struct work_struct *data)
+static void iwl3945_bg_scan_check(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, scan_check.work);
+       struct iwl3945_priv *priv =
+           container_of(data, struct iwl3945_priv, scan_check.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
@@ -6493,22 +6461,22 @@ static void iwl_bg_scan_check(struct work_struct *data)
                          jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
 
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-                       iwl_send_scan_abort(priv);
+                       iwl3945_send_scan_abort(priv);
        }
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_request_scan(struct work_struct *data)
+static void iwl3945_bg_request_scan(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, request_scan);
-       struct iwl_host_cmd cmd = {
+       struct iwl3945_priv *priv =
+           container_of(data, struct iwl3945_priv, request_scan);
+       struct iwl3945_host_cmd cmd = {
                .id = REPLY_SCAN_CMD,
-               .len = sizeof(struct iwl_scan_cmd),
+               .len = sizeof(struct iwl3945_scan_cmd),
                .meta.flags = CMD_SIZE_HUGE,
        };
        int rc = 0;
-       struct iwl_scan_cmd *scan;
+       struct iwl3945_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
        u8 direct_mask;
        int phymode;
@@ -6517,7 +6485,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_ready(priv)) {
+       if (!iwl3945_is_ready(priv)) {
                IWL_WARNING("request scan called when driver not ready.\n");
                goto done;
        }
@@ -6546,7 +6514,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       if (iwl_is_rfkill(priv)) {
+       if (iwl3945_is_rfkill(priv)) {
                IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
                goto done;
        }
@@ -6562,7 +6530,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
        }
 
        if (!priv->scan) {
-               priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
+               priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) +
                                     IWL_MAX_SCAN_SIZE, GFP_KERNEL);
                if (!priv->scan) {
                        rc = -ENOMEM;
@@ -6570,12 +6538,12 @@ static void iwl_bg_request_scan(struct work_struct *data)
                }
        }
        scan = priv->scan;
-       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+       memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE);
 
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
        scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 
-       if (iwl_is_associated(priv)) {
+       if (iwl3945_is_associated(priv)) {
                u16 interval = 0;
                u32 extra;
                u32 suspend_time = 100;
@@ -6612,14 +6580,14 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (priv->one_direct_scan) {
                IWL_DEBUG_SCAN
                    ("Kicking off one direct scan for '%s'\n",
-                    iwl_escape_essid(priv->direct_ssid,
+                    iwl3945_escape_essid(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);
                direct_mask = 1;
-       } else if (!iwl_is_associated(priv) && priv->essid_len) {
+       } else if (!iwl3945_is_associated(priv) && priv->essid_len) {
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->essid_len;
                memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
@@ -6630,7 +6598,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
        /* We don't build a direct scan probe request; the uCode will do
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
-               iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
+               iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
                        IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
@@ -6666,23 +6634,23 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (direct_mask)
                IWL_DEBUG_SCAN
                    ("Initiating direct scan for %s.\n",
-                    iwl_escape_essid(priv->essid, priv->essid_len));
+                    iwl3945_escape_essid(priv->essid, priv->essid_len));
        else
                IWL_DEBUG_SCAN("Initiating indirect scan.\n");
 
        scan->channel_count =
-               iwl_get_channels_for_scan(
+               iwl3945_get_channels_for_scan(
                        priv, phymode, 1, /* active */
                        direct_mask,
                        (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
        cmd.len += le16_to_cpu(scan->tx_cmd.len) +
-           scan->channel_count * sizeof(struct iwl_scan_channel);
+           scan->channel_count * sizeof(struct iwl3945_scan_channel);
        cmd.data = scan;
        scan->len = cpu_to_le16(cmd.len);
 
        set_bit(STATUS_SCAN_HW, &priv->status);
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl3945_send_cmd_sync(priv, &cmd);
        if (rc)
                goto done;
 
@@ -6693,50 +6661,52 @@ static void iwl_bg_request_scan(struct work_struct *data)
        return;
 
  done:
-       /* inform mac80211 sacn aborted */
+       /* inform mac80211 scan aborted */
        queue_work(priv->workqueue, &priv->scan_completed);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_up(struct work_struct *data)
+static void iwl3945_bg_up(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
+       struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       __iwl_up(priv);
+       __iwl3945_up(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_restart(struct work_struct *data)
+static void iwl3945_bg_restart(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
+       struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl_down(priv);
+       iwl3945_down(priv);
        queue_work(priv->workqueue, &priv->up);
 }
 
-static void iwl_bg_rx_replenish(struct work_struct *data)
+static void iwl3945_bg_rx_replenish(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, rx_replenish);
+       struct iwl3945_priv *priv =
+           container_of(data, struct iwl3945_priv, rx_replenish);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_rx_replenish(priv);
+       iwl3945_rx_replenish(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_post_associate(struct work_struct *data)
+#define IWL_DELAY_NEXT_SCAN (HZ*2)
+
+static void iwl3945_bg_post_associate(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv,
+       struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
                                             post_associate.work);
 
        int rc = 0;
@@ -6758,20 +6728,20 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
-       if (!priv->interface_id || !priv->is_open) {
+       if (!priv->vif || !priv->is_open) {
                mutex_unlock(&priv->mutex);
                return;
        }
-       iwl_scan_cancel_timeout(priv, 200);
+       iwl3945_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);
+       iwl3945_commit_rxon(priv);
 
-       memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-       iwl_setup_rxon_timing(priv);
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+       memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+       iwl3945_setup_rxon_timing(priv);
+       rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                              sizeof(priv->rxon_timing), &priv->rxon_timing);
        if (rc)
                IWL_WARNING("REPLY_RXON_TIMING failed - "
@@ -6800,75 +6770,81 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        }
 
-       iwl_commit_rxon(priv);
+       iwl3945_commit_rxon(priv);
 
        switch (priv->iw_mode) {
        case IEEE80211_IF_TYPE_STA:
-               iwl_rate_scale_init(priv->hw, IWL_AP_ID);
+               iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
                break;
 
        case IEEE80211_IF_TYPE_IBSS:
 
                /* clear out the station table */
-               iwl_clear_stations_table(priv);
+               iwl3945_clear_stations_table(priv);
 
-               iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
-               iwl_add_station(priv, priv->bssid, 0, 0);
+               iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
+               iwl3945_add_station(priv, priv->bssid, 0, 0);
                iwl3945_sync_sta(priv, IWL_STA_ID,
                                 (priv->phymode == MODE_IEEE80211A)?
                                 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
                                 CMD_ASYNC);
-               iwl_rate_scale_init(priv->hw, IWL_STA_ID);
-               iwl_send_beacon_cmd(priv);
+               iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
+               iwl3945_send_beacon_cmd(priv);
 
                break;
 
        default:
                 IWL_ERROR("%s Should not be called in %d mode\n",
-                               __FUNCTION__, priv->iw_mode);
+                          __FUNCTION__, priv->iw_mode);
                break;
        }
 
-       iwl_sequence_reset(priv);
+       iwl3945_sequence_reset(priv);
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_activate_qos(priv, 0);
-#endif /* CONFIG_IWLWIFI_QOS */
+#ifdef CONFIG_IWL3945_QOS
+       iwl3945_activate_qos(priv, 0);
+#endif /* CONFIG_IWL3945_QOS */
+       /* we have just associated, don't start scan too early */
+       priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_abort_scan(struct work_struct *work)
+static void iwl3945_bg_abort_scan(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
-                                            abort_scan);
+       struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
 
-       if (!iwl_is_ready(priv))
+       if (!iwl3945_is_ready(priv))
                return;
 
        mutex_lock(&priv->mutex);
 
        set_bit(STATUS_SCAN_ABORTING, &priv->status);
-       iwl_send_scan_abort(priv);
+       iwl3945_send_scan_abort(priv);
 
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_scan_completed(struct work_struct *work)
+static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+
+static void iwl3945_bg_scan_completed(struct work_struct *work)
 {
-       struct iwl_priv *priv =
-           container_of(work, struct iwl_priv, scan_completed);
+       struct iwl3945_priv *priv =
+           container_of(work, struct iwl3945_priv, scan_completed);
 
        IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       if (test_bit(STATUS_CONF_PENDING, &priv->status))
+               iwl3945_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
+
        ieee80211_scan_completed(priv->hw);
 
        /* Since setting the TXPOWER may have been deferred while
         * performing the scan, fire one off */
        mutex_lock(&priv->mutex);
-       iwl_hw_reg_send_txpower(priv);
+       iwl3945_hw_reg_send_txpower(priv);
        mutex_unlock(&priv->mutex);
 }
 
@@ -6878,50 +6854,123 @@ static void iwl_bg_scan_completed(struct work_struct *work)
  *
  *****************************************************************************/
 
-static int iwl_mac_start(struct ieee80211_hw *hw)
+#define UCODE_READY_TIMEOUT    (2 * HZ)
+
+static int iwl3945_mac_start(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
+       int ret;
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       if (pci_enable_device(priv->pci_dev)) {
+               IWL_ERROR("Fail to pci_enable_device\n");
+               return -ENODEV;
+       }
+       pci_restore_state(priv->pci_dev);
+       pci_enable_msi(priv->pci_dev);
+
+       ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED,
+                         DRV_NAME, priv);
+       if (ret) {
+               IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
+               goto out_disable_msi;
+       }
+
        /* we should be verifying the device is ready to be opened */
        mutex_lock(&priv->mutex);
 
-       priv->is_open = 1;
+       memset(&priv->staging_rxon, 0, sizeof(struct iwl3945_rxon_cmd));
+       /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
+        * ucode filename and max sizes are card-specific. */
 
-       if (!iwl_is_rfkill(priv))
-               ieee80211_start_queues(priv->hw);
+       if (!priv->ucode_code.len) {
+               ret = iwl3945_read_ucode(priv);
+               if (ret) {
+                       IWL_ERROR("Could not read microcode: %d\n", ret);
+                       mutex_unlock(&priv->mutex);
+                       goto out_release_irq;
+               }
+       }
+
+       ret = __iwl3945_up(priv);
 
        mutex_unlock(&priv->mutex);
+
+       if (ret)
+               goto out_release_irq;
+
+       IWL_DEBUG_INFO("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,
+                       test_bit(STATUS_READY, &priv->status),
+                       UCODE_READY_TIMEOUT);
+       if (!ret) {
+               if (!test_bit(STATUS_READY, &priv->status)) {
+                       IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
+                                 jiffies_to_msecs(UCODE_READY_TIMEOUT));
+                       ret = -ETIMEDOUT;
+                       goto out_release_irq;
+               }
+       }
+
+       priv->is_open = 1;
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
+
+out_release_irq:
+       free_irq(priv->pci_dev->irq, priv);
+out_disable_msi:
+       pci_disable_msi(priv->pci_dev);
+       pci_disable_device(priv->pci_dev);
+       priv->is_open = 0;
+       IWL_DEBUG_MAC80211("leave - failed\n");
+       return ret;
 }
 
-static void iwl_mac_stop(struct ieee80211_hw *hw)
+static void iwl3945_mac_stop(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       if (!priv->is_open) {
+               IWL_DEBUG_MAC80211("leave - skip\n");
+               return;
+       }
 
-       mutex_lock(&priv->mutex);
-       /* stop mac, cancel any scan request and clear
-        * RXON_FILTER_ASSOC_MSK BIT
-        */
        priv->is_open = 0;
-       iwl_scan_cancel_timeout(priv, 100);
-       cancel_delayed_work(&priv->post_associate);
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
-       mutex_unlock(&priv->mutex);
+
+       if (iwl3945_is_ready_rf(priv)) {
+               /* stop mac, cancel any scan request and clear
+                * RXON_FILTER_ASSOC_MSK BIT
+                */
+               mutex_lock(&priv->mutex);
+               iwl3945_scan_cancel_timeout(priv, 100);
+               cancel_delayed_work(&priv->post_associate);
+               mutex_unlock(&priv->mutex);
+       }
+
+       iwl3945_down(priv);
+
+       flush_workqueue(priv->workqueue);
+       free_irq(priv->pci_dev->irq, priv);
+       pci_disable_msi(priv->pci_dev);
+       pci_save_state(priv->pci_dev);
+       pci_disable_device(priv->pci_dev);
 
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                      struct ieee80211_tx_control *ctl)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -6933,29 +6982,29 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
                     ctl->tx_rate);
 
-       if (iwl_tx_skb(priv, skb, ctl))
+       if (iwl3945_tx_skb(priv, skb, ctl))
                dev_kfree_skb_any(skb);
 
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
+static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
                                 struct ieee80211_if_init_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
        DECLARE_MAC_BUF(mac);
 
-       IWL_DEBUG_MAC80211("enter: id %d, type %d\n", conf->if_id, conf->type);
+       IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
 
-       if (priv->interface_id) {
-               IWL_DEBUG_MAC80211("leave - interface_id != 0\n");
+       if (priv->vif) {
+               IWL_DEBUG_MAC80211("leave - vif != NULL\n");
                return -EOPNOTSUPP;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->interface_id = conf->if_id;
+       priv->vif = conf->vif;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -6966,106 +7015,108 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
 
-       iwl_set_mode(priv, conf->type);
+       if (iwl3945_is_ready(priv))
+               iwl3945_set_mode(priv, conf->type);
 
-       IWL_DEBUG_MAC80211("leave\n");
        mutex_unlock(&priv->mutex);
 
+       IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
 /**
- * iwl_mac_config - mac80211 config callback
+ * 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 iwl_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
-       const struct iwl_channel_info *ch_info;
+       struct iwl3945_priv *priv = hw->priv;
+       const struct iwl3945_channel_info *ch_info;
        unsigned long flags;
+       int ret = 0;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
 
-       if (!iwl_is_ready(priv)) {
+       priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+
+       if (!iwl3945_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
-       /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
-        * what is exposed through include/ declrations */
-       if (unlikely(!iwl_param_disable_hw_scan &&
+       if (unlikely(!iwl3945_param_disable_hw_scan &&
                     test_bit(STATUS_SCANNING, &priv->status))) {
                IWL_DEBUG_MAC80211("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->phymode, conf->channel);
+       ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel);
        if (!is_channel_valid(ch_info)) {
                IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
                               conf->channel, conf->phymode);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
-               mutex_unlock(&priv->mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
-       iwl_set_rxon_channel(priv, conf->phymode, conf->channel);
+       iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel);
 
-       iwl_set_flags_for_phymode(priv, conf->phymode);
+       iwl3945_set_flags_for_phymode(priv, conf->phymode);
 
        /* 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);
+       iwl3945_set_rate(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
 #ifdef IEEE80211_CONF_CHANNEL_SWITCH
        if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
-               iwl_hw_channel_switch(priv, conf->channel);
-               mutex_unlock(&priv->mutex);
-               return 0;
+               iwl3945_hw_channel_switch(priv, conf->channel);
+               goto out;
        }
 #endif
 
-       iwl_radio_kill_sw(priv, !conf->radio_enabled);
+       iwl3945_radio_kill_sw(priv, !conf->radio_enabled);
 
        if (!conf->radio_enabled) {
                IWL_DEBUG_MAC80211("leave - radio disabled\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 
-       if (iwl_is_rfkill(priv)) {
+       if (iwl3945_is_rfkill(priv)) {
                IWL_DEBUG_MAC80211("leave - RF kill\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
-       iwl_set_rate(priv);
+       iwl3945_set_rate(priv);
 
        if (memcmp(&priv->active_rxon,
                   &priv->staging_rxon, sizeof(priv->staging_rxon)))
-               iwl_commit_rxon(priv);
+               iwl3945_commit_rxon(priv);
        else
                IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
 
        IWL_DEBUG_MAC80211("leave\n");
 
+out:
+       clear_bit(STATUS_CONF_PENDING, &priv->status);
        mutex_unlock(&priv->mutex);
-
-       return 0;
+       return ret;
 }
 
-static void iwl_config_ap(struct iwl_priv *priv)
+static void iwl3945_config_ap(struct iwl3945_priv *priv)
 {
        int rc = 0;
 
@@ -7077,12 +7128,12 @@ 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);
+               iwl3945_commit_rxon(priv);
 
                /* RXON Timing */
-               memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-               iwl_setup_rxon_timing(priv);
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+               memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd));
+               iwl3945_setup_rxon_timing(priv);
+               rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                                sizeof(priv->rxon_timing), &priv->rxon_timing);
                if (rc)
                        IWL_WARNING("REPLY_RXON_TIMING failed - "
@@ -7112,20 +7163,21 @@ 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);
-               iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
+               iwl3945_commit_rxon(priv);
+               iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0);
        }
-       iwl_send_beacon_cmd(priv);
+       iwl3945_send_beacon_cmd(priv);
 
        /* FIXME - we need to add code here to detect a totally new
         * configuration, reset the AP, unassoc, rxon timing, assoc,
         * clear sta table, add BCAST sta... */
 }
 
-static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
+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;
+       struct iwl3945_priv *priv = hw->priv;
        DECLARE_MAC_BUF(mac);
        unsigned long flags;
        int rc;
@@ -7142,9 +7194,11 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                return 0;
        }
 
+       if (!iwl3945_is_alive(priv))
+               return -EAGAIN;
+
        mutex_lock(&priv->mutex);
 
-       IWL_DEBUG_MAC80211("enter: interface id %d\n", if_id);
        if (conf->bssid)
                IWL_DEBUG_MAC80211("bssid: %s\n",
                                   print_mac(mac, conf->bssid));
@@ -7161,8 +7215,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                return 0;
        }
 
-       if (priv->interface_id != if_id) {
-               IWL_DEBUG_MAC80211("leave - interface_id != if_id\n");
+       if (priv->vif != vif) {
+               IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
                mutex_unlock(&priv->mutex);
                return 0;
        }
@@ -7180,11 +7234,14 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                priv->ibss_beacon = conf->beacon;
        }
 
+       if (iwl3945_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)) {
+               if (iwl3945_scan_cancel_timeout(priv, 100)) {
                        IWL_WARNING("Aborted scan still in progress "
                                    "after 100ms\n");
                        IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
@@ -7200,20 +7257,21 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 
                if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
-                       iwl_config_ap(priv);
+                       iwl3945_config_ap(priv);
                else {
-                       rc = iwl_commit_rxon(priv);
+                       rc = iwl3945_commit_rxon(priv);
                        if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
-                               iwl_add_station(priv,
+                               iwl3945_add_station(priv,
                                        priv->active_rxon.bssid_addr, 1, 0);
                }
 
        } else {
-               iwl_scan_cancel_timeout(priv, 100);
+               iwl3945_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwl3945_commit_rxon(priv);
        }
 
+ done:
        spin_lock_irqsave(&priv->lock, flags);
        if (!conf->ssid_len)
                memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
@@ -7229,34 +7287,35 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
        return 0;
 }
 
-static void iwl_configure_filter(struct ieee80211_hw *hw,
+static void iwl3945_configure_filter(struct ieee80211_hw *hw,
                                 unsigned int changed_flags,
                                 unsigned int *total_flags,
                                 int mc_count, struct dev_addr_list *mc_list)
 {
        /*
         * XXX: dummy
-        * see also iwl_connection_init_rx_config
+        * see also iwl3945_connection_init_rx_config
         */
        *total_flags = 0;
 }
 
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
                                     struct ieee80211_if_init_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
 
-       iwl_scan_cancel_timeout(priv, 100);
-       cancel_delayed_work(&priv->post_associate);
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
-
-       if (priv->interface_id == conf->if_id) {
-               priv->interface_id = 0;
+       if (iwl3945_is_ready_rf(priv)) {
+               iwl3945_scan_cancel_timeout(priv, 100);
+               cancel_delayed_work(&priv->post_associate);
+               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);
                memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
                priv->essid_len = 0;
@@ -7264,22 +7323,20 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
        mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211("leave\n");
-
 }
 
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 {
        int rc = 0;
        unsigned long flags;
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl3945_is_ready_rf(priv)) {
                rc = -EIO;
                IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
                goto out_unlock;
@@ -7291,17 +7348,21 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
                goto out_unlock;
        }
 
+       /* we don't schedule scan within next_scan_jiffies period */
+       if (priv->next_scan_jiffies &&
+                       time_after(priv->next_scan_jiffies, jiffies)) {
+               rc = -EAGAIN;
+               goto out_unlock;
+       }
        /* if we just finished scan ask for delay */
-       if (priv->last_scan_jiffies &&
-           time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
-                      jiffies)) {
+       if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
+                               IWL_DELAY_NEXT_SCAN, jiffies)) {
                rc = -EAGAIN;
                goto out_unlock;
        }
        if (len) {
-               IWL_DEBUG_SCAN("direct scan for  "
-                              "%s [%d]\n ",
-                              iwl_escape_essid(ssid, len), (int)len);
+               IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
+                              iwl3945_escape_essid(ssid, len), (int)len);
 
                priv->one_direct_scan = 1;
                priv->direct_ssid_len = (u8)
@@ -7310,7 +7371,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        } else
                priv->one_direct_scan = 0;
 
-       rc = iwl_scan_initiate(priv);
+       rc = iwl3945_scan_initiate(priv);
 
        IWL_DEBUG_MAC80211("leave\n");
 
@@ -7321,17 +7382,17 @@ out_unlock:
        return rc;
 }
 
-static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                           const u8 *local_addr, const u8 *addr,
                           struct ieee80211_key_conf *key)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        int rc = 0;
        u8 sta_id;
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_param_hwcrypto) {
+       if (!iwl3945_param_hwcrypto) {
                IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
                return -EOPNOTSUPP;
        }
@@ -7340,7 +7401,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                /* only support pairwise keys */
                return -EOPNOTSUPP;
 
-       sta_id = iwl_hw_find_station(priv, addr);
+       sta_id = iwl3945_hw_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
                DECLARE_MAC_BUF(mac);
 
@@ -7351,24 +7412,24 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        mutex_lock(&priv->mutex);
 
-       iwl_scan_cancel_timeout(priv, 100);
+       iwl3945_scan_cancel_timeout(priv, 100);
 
        switch (cmd) {
        case  SET_KEY:
-               rc = iwl_update_sta_key_info(priv, key, sta_id);
+               rc = iwl3945_update_sta_key_info(priv, key, sta_id);
                if (!rc) {
-                       iwl_set_rxon_hwcrypto(priv, 1);
-                       iwl_commit_rxon(priv);
+                       iwl3945_set_rxon_hwcrypto(priv, 1);
+                       iwl3945_commit_rxon(priv);
                        key->hw_key_idx = sta_id;
                        IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                }
                break;
        case DISABLE_KEY:
-               rc = iwl_clear_sta_key_info(priv, sta_id);
+               rc = iwl3945_clear_sta_key_info(priv, sta_id);
                if (!rc) {
-                       iwl_set_rxon_hwcrypto(priv, 0);
-                       iwl_commit_rxon(priv);
+                       iwl3945_set_rxon_hwcrypto(priv, 0);
+                       iwl3945_commit_rxon(priv);
                        IWL_DEBUG_MAC80211("disable hwcrypto key\n");
                }
                break;
@@ -7382,18 +7443,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return rc;
 }
 
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                           const struct ieee80211_tx_queue_params *params)
 {
-       struct iwl_priv *priv = hw->priv;
-#ifdef CONFIG_IWLWIFI_QOS
+       struct iwl3945_priv *priv = hw->priv;
+#ifdef CONFIG_IWL3945_QOS
        unsigned long flags;
        int q;
-#endif /* CONFIG_IWL_QOS */
+#endif /* CONFIG_IWL3945_QOS */
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7403,7 +7464,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                return 0;
        }
 
-#ifdef CONFIG_IWLWIFI_QOS
+#ifdef CONFIG_IWL3945_QOS
        if (!priv->qos_data.qos_enable) {
                priv->qos_data.qos_active = 0;
                IWL_DEBUG_MAC80211("leave - qos not enabled\n");
@@ -7426,30 +7487,30 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
 
        mutex_lock(&priv->mutex);
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
-               iwl_activate_qos(priv, 1);
-       else if (priv->assoc_id && iwl_is_associated(priv))
-               iwl_activate_qos(priv, 0);
+               iwl3945_activate_qos(priv, 1);
+       else if (priv->assoc_id && iwl3945_is_associated(priv))
+               iwl3945_activate_qos(priv, 0);
 
        mutex_unlock(&priv->mutex);
 
-#endif /*CONFIG_IWLWIFI_QOS */
+#endif /*CONFIG_IWL3945_QOS */
 
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
                                struct ieee80211_tx_queue_stats *stats)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        int i, avail;
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
+       struct iwl3945_tx_queue *txq;
+       struct iwl3945_queue *q;
        unsigned long flags;
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7459,7 +7520,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
        for (i = 0; i < AC_NUM; i++) {
                txq = &priv->txq[i];
                q = &txq->q;
-               avail = iwl_queue_space(q);
+               avail = iwl3945_queue_space(q);
 
                stats->data[i].len = q->n_window - avail;
                stats->data[i].limit = q->n_window - q->high_mark;
@@ -7473,7 +7534,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int iwl_mac_get_stats(struct ieee80211_hw *hw,
+static int iwl3945_mac_get_stats(struct ieee80211_hw *hw,
                             struct ieee80211_low_level_stats *stats)
 {
        IWL_DEBUG_MAC80211("enter\n");
@@ -7482,7 +7543,7 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw)
+static u64 iwl3945_mac_get_tsf(struct ieee80211_hw *hw)
 {
        IWL_DEBUG_MAC80211("enter\n");
        IWL_DEBUG_MAC80211("leave\n");
@@ -7490,16 +7551,16 @@ static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw)
        return 0;
 }
 
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_reset_qos(priv);
+#ifdef CONFIG_IWL3945_QOS
+       iwl3945_reset_qos(priv);
 #endif
        cancel_delayed_work(&priv->post_associate);
 
@@ -7522,13 +7583,19 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       if (!iwl3945_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211("leave - not ready\n");
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+
        /* we are restarting association process
         * clear RXON_FILTER_ASSOC_MSK bit
        */
        if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
-               iwl_scan_cancel_timeout(priv, 100);
+               iwl3945_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwl3945_commit_rxon(priv);
        }
 
        /* Per mac80211.h: This is only used in IBSS mode... */
@@ -7539,15 +7606,9 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
                return;
        }
 
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
        priv->only_active_channel = 0;
 
-       iwl_set_rate(priv);
+       iwl3945_set_rate(priv);
 
        mutex_unlock(&priv->mutex);
 
@@ -7555,16 +7616,16 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
 }
 
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                                 struct ieee80211_tx_control *control)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl3945_priv *priv = hw->priv;
        unsigned long flags;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl3945_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                mutex_unlock(&priv->mutex);
                return -EIO;
@@ -7588,8 +7649,8 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        IWL_DEBUG_MAC80211("leave\n");
        spin_unlock_irqrestore(&priv->lock, flags);
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_reset_qos(priv);
+#ifdef CONFIG_IWL3945_QOS
+       iwl3945_reset_qos(priv);
 #endif
 
        queue_work(priv->workqueue, &priv->post_associate.work);
@@ -7605,7 +7666,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
  *
  *****************************************************************************/
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL3945_DEBUG
 
 /*
  * The following adds a new attribute to the sysfs representation
@@ -7617,7 +7678,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
-       return sprintf(buf, "0x%08X\n", iwl_debug_level);
+       return sprintf(buf, "0x%08X\n", iwl3945_debug_level);
 }
 static ssize_t store_debug_level(struct device_driver *d,
                                 const char *buf, size_t count)
@@ -7630,7 +7691,7 @@ static ssize_t store_debug_level(struct device_driver *d,
                printk(KERN_INFO DRV_NAME
                       ": %s is not in hex or decimal form.\n", buf);
        else
-               iwl_debug_level = val;
+               iwl3945_debug_level = val;
 
        return strnlen(buf, count);
 }
@@ -7638,7 +7699,7 @@ static ssize_t store_debug_level(struct device_driver *d,
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
                   show_debug_level, store_debug_level);
 
-#endif /* CONFIG_IWLWIFI_DEBUG */
+#endif /* CONFIG_IWL3945_DEBUG */
 
 static ssize_t show_rf_kill(struct device *d,
                            struct device_attribute *attr, char *buf)
@@ -7649,7 +7710,7 @@ static ssize_t show_rf_kill(struct device *d,
         * 2 - HW based RF kill active
         * 3 - Both HW and SW based RF kill active
         */
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) |
                  (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0);
 
@@ -7660,10 +7721,10 @@ static ssize_t store_rf_kill(struct device *d,
                             struct device_attribute *attr,
                             const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
 
        mutex_lock(&priv->mutex);
-       iwl_radio_kill_sw(priv, buf[0] == '1');
+       iwl3945_radio_kill_sw(priv, buf[0] == '1');
        mutex_unlock(&priv->mutex);
 
        return count;
@@ -7674,12 +7735,12 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl3945_is_alive(priv))
                return -EAGAIN;
 
-       return sprintf(buf, "%d\n", iwl_hw_get_temperature(priv));
+       return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv));
 }
 
 static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
@@ -7688,15 +7749,15 @@ static ssize_t show_rs_window(struct device *d,
                              struct device_attribute *attr,
                              char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
-       return iwl_fill_rs_info(priv->hw, buf, IWL_AP_ID);
+       struct iwl3945_priv *priv = d->driver_data;
+       return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID);
 }
 static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, 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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        return sprintf(buf, "%d\n", priv->user_txpower_limit);
 }
 
@@ -7704,7 +7765,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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        char *p = (char *)buf;
        u32 val;
 
@@ -7713,7 +7774,7 @@ static ssize_t store_tx_power(struct device *d,
                printk(KERN_INFO DRV_NAME
                       ": %s is not in decimal form.\n", buf);
        else
-               iwl_hw_reg_set_txpower(priv, val);
+               iwl3945_hw_reg_set_txpower(priv, val);
 
        return count;
 }
@@ -7723,7 +7784,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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -7732,19 +7793,19 @@ 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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        u32 flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl3945_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
                                       flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
-                       iwl_commit_rxon(priv);
+                       iwl3945_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -7757,7 +7818,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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n",
                le32_to_cpu(priv->active_rxon.filter_flags));
@@ -7767,20 +7828,20 @@ 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 iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl3945_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing rxon.filter_flags = "
                                       "0x%04X\n", filter_flags);
                        priv->staging_rxon.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwl_commit_rxon(priv);
+                       iwl3945_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -7794,20 +7855,20 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 static ssize_t show_tune(struct device *d,
                         struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n",
                       (priv->phymode << 8) |
                        le16_to_cpu(priv->active_rxon.channel));
 }
 
-static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode);
+static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode);
 
 static ssize_t store_tune(struct device *d,
                          struct device_attribute *attr,
                          const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
        char *p = (char *)buf;
        u16 tune = simple_strtoul(p, &p, 0);
        u8 phymode = (tune >> 8) & 0xff;
@@ -7818,9 +7879,9 @@ static ssize_t store_tune(struct device *d,
        mutex_lock(&priv->mutex);
        if ((le16_to_cpu(priv->staging_rxon.channel) != channel) ||
            (priv->phymode != phymode)) {
-               const struct iwl_channel_info *ch_info;
+               const struct iwl3945_channel_info *ch_info;
 
-               ch_info = iwl_get_channel_info(priv, phymode, channel);
+               ch_info = iwl3945_get_channel_info(priv, phymode, channel);
                if (!ch_info) {
                        IWL_WARNING("Requested invalid phymode/channel "
                                    "combination: %d %d\n", phymode, channel);
@@ -7829,18 +7890,18 @@ static ssize_t store_tune(struct device *d,
                }
 
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl3945_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing phymode and "
                                       "rxon.channel = %d %d\n",
                                       phymode, channel);
 
-                       iwl_set_rxon_channel(priv, phymode, channel);
-                       iwl_set_flags_for_phymode(priv, phymode);
+                       iwl3945_set_rxon_channel(priv, phymode, channel);
+                       iwl3945_set_flags_for_phymode(priv, phymode);
 
-                       iwl_set_rate(priv);
-                       iwl_commit_rxon(priv);
+                       iwl3945_set_rate(priv);
+                       iwl3945_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -7850,13 +7911,13 @@ static ssize_t store_tune(struct device *d,
 
 static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune);
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
 
 static ssize_t show_measurement(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       struct iwl_spectrum_notification measure_report;
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_spectrum_notification measure_report;
        u32 size = sizeof(measure_report), len = 0, ofs = 0;
        u8 *data = (u8 *) & measure_report;
        unsigned long flags;
@@ -7888,7 +7949,7 @@ static ssize_t store_measurement(struct device *d,
                                 struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        struct ieee80211_measurement_params params = {
                .channel = le16_to_cpu(priv->active_rxon.channel),
                .start_time = cpu_to_le64(priv->last_tsf),
@@ -7914,19 +7975,19 @@ static ssize_t store_measurement(struct device *d,
 
        IWL_DEBUG_INFO("Invoking measurement of type %d on "
                       "channel %d (for '%s')\n", type, params.channel, buf);
-       iwl_get_measurement(priv, &params, type);
+       iwl3945_get_measurement(priv, &params, type);
 
        return count;
 }
 
 static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
                   show_measurement, store_measurement);
-#endif /* CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT */
+#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */
 
 static ssize_t show_rate(struct device *d,
                         struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        unsigned long flags;
        int i;
 
@@ -7937,13 +7998,13 @@ static ssize_t show_rate(struct device *d,
                i = priv->stations[IWL_STA_ID].current_rate.s.rate;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-       i = iwl_rate_index_from_plcp(i);
+       i = iwl3945_rate_index_from_plcp(i);
        if (i == -1)
                return sprintf(buf, "0\n");
 
        return sprintf(buf, "%d%s\n",
-                      (iwl_rates[i].ieee >> 1),
-                      (iwl_rates[i].ieee & 0x1) ? ".5" : "");
+                      (iwl3945_rates[i].ieee >> 1),
+                      (iwl3945_rates[i].ieee & 0x1) ? ".5" : "");
 }
 
 static DEVICE_ATTR(rate, S_IRUSR, show_rate, NULL);
@@ -7952,7 +8013,7 @@ static ssize_t store_retry_rate(struct device *d,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
 
        priv->retry_rate = simple_strtoul(buf, NULL, 0);
        if (priv->retry_rate <= 0)
@@ -7964,7 +8025,7 @@ static ssize_t store_retry_rate(struct device *d,
 static ssize_t show_retry_rate(struct device *d,
                               struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        return sprintf(buf, "%d", priv->retry_rate);
 }
 
@@ -7975,14 +8036,14 @@ static ssize_t store_power_level(struct device *d,
                                 struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        int rc;
        int mode;
 
        mode = simple_strtoul(buf, NULL, 0);
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_ready(priv)) {
+       if (!iwl3945_is_ready(priv)) {
                rc = -EAGAIN;
                goto out;
        }
@@ -7993,7 +8054,7 @@ static ssize_t store_power_level(struct device *d,
                mode |= IWL_POWER_ENABLED;
 
        if (mode != priv->power_mode) {
-               rc = iwl_send_power_mode(priv, IWL_POWER_LEVEL(mode));
+               rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode));
                if (rc) {
                        IWL_DEBUG_MAC80211("failed setting power mode.\n");
                        goto out;
@@ -8029,7 +8090,7 @@ static const s32 period_duration[] = {
 static ssize_t show_power_level(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        int level = IWL_POWER_LEVEL(priv->power_mode);
        char *p = buf;
 
@@ -8064,18 +8125,18 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
 static ssize_t show_channels(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
        int len = 0, i;
        struct ieee80211_channel *channels = NULL;
        const struct ieee80211_hw_mode *hw_mode = NULL;
        int count = 0;
 
-       if (!iwl_is_ready(priv))
+       if (!iwl3945_is_ready(priv))
                return -EAGAIN;
 
-       hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211G);
+       hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G);
        if (!hw_mode)
-               hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211B);
+               hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B);
        if (hw_mode) {
                channels = hw_mode->channels;
                count = hw_mode->num_channels;
@@ -8102,7 +8163,7 @@ static ssize_t show_channels(struct device *d,
                               flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
                               "active/passive" : "passive only");
 
-       hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211A);
+       hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A);
        if (hw_mode) {
                channels = hw_mode->channels;
                count = hw_mode->num_channels;
@@ -8138,17 +8199,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
 static ssize_t show_statistics(struct device *d,
                               struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       u32 size = sizeof(struct iwl_notif_statistics);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
+       u32 size = sizeof(struct iwl3945_notif_statistics);
        u32 len = 0, ofs = 0;
        u8 *data = (u8 *) & priv->statistics;
        int rc = 0;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl3945_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
-       rc = iwl_send_statistics_request(priv);
+       rc = iwl3945_send_statistics_request(priv);
        mutex_unlock(&priv->mutex);
 
        if (rc) {
@@ -8176,9 +8237,9 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
 static ssize_t show_antenna(struct device *d,
                            struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
 
-       if (!iwl_is_alive(priv))
+       if (!iwl3945_is_alive(priv))
                return -EAGAIN;
 
        return sprintf(buf, "%d\n", priv->antenna);
@@ -8189,7 +8250,7 @@ static ssize_t store_antenna(struct device *d,
                             const char *buf, size_t count)
 {
        int ant;
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl3945_priv *priv = dev_get_drvdata(d);
 
        if (count == 0)
                return 0;
@@ -8201,7 +8262,7 @@ static ssize_t store_antenna(struct device *d,
 
        if ((ant >= 0) && (ant <= 2)) {
                IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
-               priv->antenna = (enum iwl_antenna)ant;
+               priv->antenna = (enum iwl3945_antenna)ant;
        } else
                IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
 
@@ -8214,8 +8275,8 @@ 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;
-       if (!iwl_is_alive(priv))
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data;
+       if (!iwl3945_is_alive(priv))
                return -EAGAIN;
        return sprintf(buf, "0x%08x\n", (int)priv->status);
 }
@@ -8229,7 +8290,7 @@ static ssize_t dump_error_log(struct device *d,
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+               iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data);
 
        return strnlen(buf, count);
 }
@@ -8243,7 +8304,7 @@ static ssize_t dump_event_log(struct device *d,
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+               iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data);
 
        return strnlen(buf, count);
 }
@@ -8256,34 +8317,34 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
  *
  *****************************************************************************/
 
-static void iwl_setup_deferred_work(struct iwl_priv *priv)
+static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
 {
        priv->workqueue = create_workqueue(DRV_NAME);
 
        init_waitqueue_head(&priv->wait_command_queue);
 
-       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->scan_completed, iwl_bg_scan_completed);
-       INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
-       INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
-       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
-       INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
-       INIT_DELAYED_WORK(&priv->post_associate, iwl_bg_post_associate);
-       INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
-       INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
-       INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
-
-       iwl_hw_setup_deferred_work(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->scan_completed, iwl3945_bg_scan_completed);
+       INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+       INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
+       INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
+       INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
+       INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate);
+       INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
+       INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
+       INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
+
+       iwl3945_hw_setup_deferred_work(priv);
 
        tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-                    iwl_irq_tasklet, (unsigned long)priv);
+                    iwl3945_irq_tasklet, (unsigned long)priv);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
 {
-       iwl_hw_cancel_deferred_work(priv);
+       iwl3945_hw_cancel_deferred_work(priv);
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
@@ -8292,14 +8353,14 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->beacon_update);
 }
 
-static struct attribute *iwl_sysfs_entries[] = {
+static struct attribute *iwl3945_sysfs_entries[] = {
        &dev_attr_antenna.attr,
        &dev_attr_channels.attr,
        &dev_attr_dump_errors.attr,
        &dev_attr_dump_events.attr,
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
        &dev_attr_measurement.attr,
 #endif
        &dev_attr_power_level.attr,
@@ -8316,45 +8377,48 @@ static struct attribute *iwl_sysfs_entries[] = {
        NULL
 };
 
-static struct attribute_group iwl_attribute_group = {
+static struct attribute_group iwl3945_attribute_group = {
        .name = NULL,           /* put in device directory */
-       .attrs = iwl_sysfs_entries,
+       .attrs = iwl3945_sysfs_entries,
 };
 
-static struct ieee80211_ops iwl_hw_ops = {
-       .tx = iwl_mac_tx,
-       .start = iwl_mac_start,
-       .stop = iwl_mac_stop,
-       .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,
-       .get_stats = iwl_mac_get_stats,
-       .get_tx_stats = iwl_mac_get_tx_stats,
-       .conf_tx = iwl_mac_conf_tx,
-       .get_tsf = iwl_mac_get_tsf,
-       .reset_tsf = iwl_mac_reset_tsf,
-       .beacon_update = iwl_mac_beacon_update,
-       .hw_scan = iwl_mac_hw_scan
+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,
+       .configure_filter = iwl3945_configure_filter,
+       .set_key = iwl3945_mac_set_key,
+       .get_stats = iwl3945_mac_get_stats,
+       .get_tx_stats = iwl3945_mac_get_tx_stats,
+       .conf_tx = iwl3945_mac_conf_tx,
+       .get_tsf = iwl3945_mac_get_tsf,
+       .reset_tsf = iwl3945_mac_reset_tsf,
+       .beacon_update = iwl3945_mac_beacon_update,
+       .hw_scan = iwl3945_mac_hw_scan
 };
 
-static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int err = 0;
        u32 pci_id;
-       struct iwl_priv *priv;
+       struct iwl3945_priv *priv;
        struct ieee80211_hw *hw;
        int i;
+       DECLARE_MAC_BUF(mac);
 
-       if (iwl_param_disable_hw_scan) {
+       /* Disabling hardware scan means that mac80211 will perform scans
+        * "the hard way", rather than using device's scan. */
+       if (iwl3945_param_disable_hw_scan) {
                IWL_DEBUG_INFO("Disabling hw_scan\n");
-               iwl_hw_ops.hw_scan = NULL;
+               iwl3945_hw_ops.hw_scan = NULL;
        }
 
-       if ((iwl_param_queues_num > IWL_MAX_NUM_QUEUES) ||
-           (iwl_param_queues_num < IWL_MIN_NUM_QUEUES)) {
+       if ((iwl3945_param_queues_num > IWL_MAX_NUM_QUEUES) ||
+           (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) {
                IWL_ERROR("invalid queues_num, should be between %d and %d\n",
                          IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES);
                err = -EINVAL;
@@ -8363,7 +8427,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* mac80211 allocates memory for this device instance, including
         *   space for this driver's private structure */
-       hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwl_hw_ops);
+       hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops);
        if (hw == NULL) {
                IWL_ERROR("Can not allocate network device\n");
                err = -ENOMEM;
@@ -8378,9 +8442,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        priv->hw = hw;
 
        priv->pci_dev = pdev;
-       priv->antenna = (enum iwl_antenna)iwl_param_antenna;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       iwl_debug_level = iwl_param_debug;
+
+       /* Select antenna (may be helpful if only one antenna is connected) */
+       priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna;
+#ifdef CONFIG_IWL3945_DEBUG
+       iwl3945_debug_level = iwl3945_param_debug;
        atomic_set(&priv->restrict_refcnt, 0);
 #endif
        priv->retry_rate = 1;
@@ -8399,6 +8465,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Tell mac80211 our Tx characteristics */
        hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
 
+       /* 4 EDCA QOS priorities */
        hw->queues = 4;
 
        spin_lock_init(&priv->lock);
@@ -8419,7 +8486,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
 
-       iwl_clear_stations_table(priv);
+       /* Clear the driver's (not device's) station table */
+       iwl3945_clear_stations_table(priv);
 
        priv->data_retry_limit = -1;
        priv->ieee_channels = NULL;
@@ -8438,9 +8506,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        err = pci_request_regions(pdev, DRV_NAME);
        if (err)
                goto out_pci_disable_device;
+
        /* We disable the RETRY_TIMEOUT register (0x41) to keep
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, 0x41, 0x00);
+
        priv->hw_base = pci_iomap(pdev, 0, 0);
        if (!priv->hw_base) {
                err = -ENODEV;
@@ -8453,7 +8523,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* Initialize module parameter values here */
 
-       if (iwl_param_disable) {
+       /* Disable radio (SW RF KILL) via parameter when loading driver */
+       if (iwl3945_param_disable) {
                set_bit(STATUS_RF_KILL_SW, &priv->status);
                IWL_DEBUG_INFO("Radio disabled.\n");
        }
@@ -8488,78 +8559,82 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
               priv->is_abg ? "A" : "");
 
        /* Device-specific setup */
-       if (iwl_hw_set_hw_setting(priv)) {
+       if (iwl3945_hw_set_hw_setting(priv)) {
                IWL_ERROR("failed to set hw settings\n");
-               mutex_unlock(&priv->mutex);
                goto out_iounmap;
        }
 
-#ifdef CONFIG_IWLWIFI_QOS
-       if (iwl_param_qos_enable)
+#ifdef CONFIG_IWL3945_QOS
+       if (iwl3945_param_qos_enable)
                priv->qos_data.qos_enable = 1;
 
-       iwl_reset_qos(priv);
+       iwl3945_reset_qos(priv);
 
        priv->qos_data.qos_active = 0;
        priv->qos_data.qos_cap.val = 0;
-#endif /* CONFIG_IWLWIFI_QOS */
+#endif /* CONFIG_IWL3945_QOS */
 
-       iwl_set_rxon_channel(priv, MODE_IEEE80211G, 6);
-       iwl_setup_deferred_work(priv);
-       iwl_setup_rx_handlers(priv);
+       iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6);
+       iwl3945_setup_deferred_work(priv);
+       iwl3945_setup_rx_handlers(priv);
 
        priv->rates_mask = IWL_RATES_MASK;
        /* If power management is turned on, default to AC mode */
        priv->power_mode = IWL_POWER_AC;
        priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
 
-       pci_enable_msi(pdev);
+       iwl3945_disable_interrupts(priv);
 
-       err = request_irq(pdev->irq, iwl_isr, IRQF_SHARED, DRV_NAME, priv);
-       if (err) {
-               IWL_ERROR("Error allocating IRQ %d\n", pdev->irq);
-               goto out_disable_msi;
-       }
-
-       mutex_lock(&priv->mutex);
-
-       err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
+       err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group);
        if (err) {
                IWL_ERROR("failed to create sysfs device attributes\n");
-               mutex_unlock(&priv->mutex);
                goto out_release_irq;
        }
 
-       /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
-        * ucode filename and max sizes are card-specific. */
-       err = iwl_read_ucode(priv);
+       /* nic init */
+       iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+                    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+        iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+        err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
+                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+        if (err < 0) {
+                IWL_DEBUG_INFO("Failed to init the card\n");
+               goto out_remove_sysfs;
+        }
+       /* Read the EEPROM */
+       err = iwl3945_eeprom_init(priv);
        if (err) {
-               IWL_ERROR("Could not read microcode: %d\n", err);
-               mutex_unlock(&priv->mutex);
-               goto out_pci_alloc;
+               IWL_ERROR("Unable to init EEPROM\n");
+               goto out_remove_sysfs;
        }
+       /* MAC Address location in EEPROM same for 3945/4965 */
+       get_eeprom_mac(priv, priv->mac_addr);
+       IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
+       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_INFO("Queing UP work.\n");
+       iwl3945_rate_control_register(priv->hw);
+       err = ieee80211_register_hw(priv->hw);
+       if (err) {
+               IWL_ERROR("Failed to register network device (error %d)\n", err);
+               goto out_remove_sysfs;
+       }
 
-       queue_work(priv->workqueue, &priv->up);
+       priv->hw->conf.beacon_int = 100;
+       priv->mac80211_registered = 1;
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
 
        return 0;
 
- out_pci_alloc:
-       iwl_dealloc_ucode_pci(priv);
-
-       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
+ out_remove_sysfs:
+       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
  out_release_irq:
-       free_irq(pdev->irq, priv);
-
- out_disable_msi:
-       pci_disable_msi(pdev);
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
-       iwl_unset_hw_setting(priv);
+       iwl3945_unset_hw_setting(priv);
 
  out_iounmap:
        pci_iounmap(pdev, priv->hw_base);
@@ -8574,9 +8649,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        return err;
 }
 
-static void iwl_pci_remove(struct pci_dev *pdev)
+static void iwl3945_pci_remove(struct pci_dev *pdev)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl3945_priv *priv = pci_get_drvdata(pdev);
        struct list_head *p, *q;
        int i;
 
@@ -8587,43 +8662,41 @@ static void iwl_pci_remove(struct pci_dev *pdev)
 
        set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-       iwl_down(priv);
+       iwl3945_down(priv);
 
        /* Free MAC hash list for ADHOC */
        for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
                list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
                        list_del(p);
-                       kfree(list_entry(p, struct iwl_ibss_seq, list));
+                       kfree(list_entry(p, struct iwl3945_ibss_seq, list));
                }
        }
 
-       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
+       sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
-       iwl_dealloc_ucode_pci(priv);
+       iwl3945_dealloc_ucode_pci(priv);
 
        if (priv->rxq.bd)
-               iwl_rx_queue_free(priv, &priv->rxq);
-       iwl_hw_txq_ctx_free(priv);
+               iwl3945_rx_queue_free(priv, &priv->rxq);
+       iwl3945_hw_txq_ctx_free(priv);
 
-       iwl_unset_hw_setting(priv);
-       iwl_clear_stations_table(priv);
+       iwl3945_unset_hw_setting(priv);
+       iwl3945_clear_stations_table(priv);
 
        if (priv->mac80211_registered) {
                ieee80211_unregister_hw(priv->hw);
-               iwl_rate_control_unregister(priv->hw);
+               iwl3945_rate_control_unregister(priv->hw);
        }
 
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
 
-       /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
+       /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes
         * priv->workqueue... so we can't take down the workqueue
         * until now... */
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
 
-       free_irq(pdev->irq, priv);
-       pci_disable_msi(pdev);
        pci_iounmap(pdev, priv->hw_base);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -8642,93 +8715,31 @@ static void iwl_pci_remove(struct pci_dev *pdev)
 
 #ifdef CONFIG_PM
 
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl3945_priv *priv = pci_get_drvdata(pdev);
 
-       set_bit(STATUS_IN_SUSPEND, &priv->status);
-
-       /* Take down the device; powers it off, etc. */
-       iwl_down(priv);
-
-       if (priv->mac80211_registered)
-               ieee80211_stop_queues(priv->hw);
+       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 void iwl_resume(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       /* The following it a temporary work around due to the
-        * suspend / resume not fully initializing the NIC correctly.
-        * Without all of the following, resume will not attempt to take
-        * down the NIC (it shouldn't really need to) and will just try
-        * and bring the NIC back up.  However that fails during the
-        * ucode verification process.  This then causes iwl_down to be
-        * called *after* iwl_hw_nic_init() has succeeded -- which
-        * then lets the next init sequence succeed.  So, we've
-        * replicated all of that NIC init code here... */
-
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
-       iwl_hw_nic_init(priv);
-
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
-                   CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
-       /* tell the device to stop sending interrupts */
-       iwl_disable_interrupts(priv);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
-       if (!iwl_grab_restricted_access(priv)) {
-               iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_restricted_access(priv);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       udelay(5);
-
-       iwl_hw_nic_reset(priv);
-
-       /* Bring the device back up */
-       clear_bit(STATUS_IN_SUSPEND, &priv->status);
-       queue_work(priv->workqueue, &priv->up);
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
+static int iwl3945_pci_resume(struct pci_dev *pdev)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-       int err;
-
-       printk(KERN_INFO "Coming out of suspend...\n");
+       struct iwl3945_priv *priv = pci_get_drvdata(pdev);
 
        pci_set_power_state(pdev, PCI_D0);
-       err = pci_enable_device(pdev);
-       pci_restore_state(pdev);
 
-       /*
-        * Suspend/Resume resets the PCI configuration space, so we have to
-        * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
-        * from interfering with C3 CPU state. pci_restore_state won't help
-        * here since it only restores the first 64 bytes pci config header.
-        */
-       pci_write_config_byte(pdev, 0x41, 0x00);
-
-       iwl_resume(priv);
+       if (priv->is_open)
+               iwl3945_mac_start(priv->hw);
 
+       clear_bit(STATUS_IN_SUSPEND, &priv->status);
        return 0;
 }
 
@@ -8740,33 +8751,33 @@ static int iwl_pci_resume(struct pci_dev *pdev)
  *
  *****************************************************************************/
 
-static struct pci_driver iwl_driver = {
+static struct pci_driver iwl3945_driver = {
        .name = DRV_NAME,
-       .id_table = iwl_hw_card_ids,
-       .probe = iwl_pci_probe,
-       .remove = __devexit_p(iwl_pci_remove),
+       .id_table = iwl3945_hw_card_ids,
+       .probe = iwl3945_pci_probe,
+       .remove = __devexit_p(iwl3945_pci_remove),
 #ifdef CONFIG_PM
-       .suspend = iwl_pci_suspend,
-       .resume = iwl_pci_resume,
+       .suspend = iwl3945_pci_suspend,
+       .resume = iwl3945_pci_resume,
 #endif
 };
 
-static int __init iwl_init(void)
+static int __init iwl3945_init(void)
 {
 
        int ret;
        printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
        printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
-       ret = pci_register_driver(&iwl_driver);
+       ret = pci_register_driver(&iwl3945_driver);
        if (ret) {
                IWL_ERROR("Unable to initialize PCI module\n");
                return ret;
        }
-#ifdef CONFIG_IWLWIFI_DEBUG
-       ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level);
+#ifdef CONFIG_IWL3945_DEBUG
+       ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level);
        if (ret) {
                IWL_ERROR("Unable to create driver sysfs file\n");
-               pci_unregister_driver(&iwl_driver);
+               pci_unregister_driver(&iwl3945_driver);
                return ret;
        }
 #endif
@@ -8774,32 +8785,32 @@ static int __init iwl_init(void)
        return ret;
 }
 
-static void __exit iwl_exit(void)
+static void __exit iwl3945_exit(void)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level);
+#ifdef CONFIG_IWL3945_DEBUG
+       driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level);
 #endif
-       pci_unregister_driver(&iwl_driver);
+       pci_unregister_driver(&iwl3945_driver);
 }
 
-module_param_named(antenna, iwl_param_antenna, int, 0444);
+module_param_named(antenna, iwl3945_param_antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl_param_disable, int, 0444);
+module_param_named(disable, iwl3945_param_disable, int, 0444);
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
-module_param_named(hwcrypto, iwl_param_hwcrypto, int, 0444);
+module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444);
 MODULE_PARM_DESC(hwcrypto,
                 "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl_param_debug, int, 0444);
+module_param_named(debug, iwl3945_param_debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 
-module_param_named(queues_num, iwl_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl3945_param_queues_num, int, 0444);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
 
 /* QoS */
-module_param_named(qos_enable, iwl_param_qos_enable, int, 0444);
+module_param_named(qos_enable, iwl3945_param_qos_enable, int, 0444);
 MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
 
-module_exit(iwl_exit);
-module_init(iwl_init);
+module_exit(iwl3945_exit);
+module_init(iwl3945_init);
index 15a45f4717104300f201866ab535a52ad35c7133..c86da5cd1df19466fe230393a98e74e3475ede16 100644 (file)
  *
  *****************************************************************************/
 
-/*
- * NOTE:  This file (iwl-base.c) is used to build to multiple hardware targets
- * by defining IWL to either 3945 or 4965.  The Makefile used when building
- * the base targets will create base-3945.o and base-4965.o
- *
- * The eventual goal is to move as many of the #if IWL / #endif blocks out of
- * this file and into the hardware specific implementation files (iwl-XXXX.c)
- * and leave only the common (non #ifdef sprinkled) code in this file
- */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 
-#include <net/ieee80211_radiotap.h>
 #include <net/mac80211.h>
 
 #include <asm/div64.h>
 
-#define IWL 4965
-
-#include "iwlwifi.h"
 #include "iwl-4965.h"
 #include "iwl-helpers.h"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-u32 iwl_debug_level;
+#ifdef CONFIG_IWL4965_DEBUG
+u32 iwl4965_debug_level;
 #endif
 
+static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv,
+                                 struct iwl4965_tx_queue *txq);
+
 /******************************************************************************
  *
  * module boiler plate
@@ -73,13 +62,14 @@ u32 iwl_debug_level;
  ******************************************************************************/
 
 /* module parameters */
-int iwl_param_disable_hw_scan;
-int iwl_param_debug;
-int iwl_param_disable;      /* def: enable radio */
-int iwl_param_antenna;      /* def: 0 = both antennas (use diversity) */
-int iwl_param_hwcrypto;     /* def: using software encryption */
-int iwl_param_qos_enable = 1;
-int iwl_param_queues_num = IWL_MAX_NUM_QUEUES;
+static int iwl4965_param_disable_hw_scan; /* def: 0 = use 4965's h/w scan */
+static int iwl4965_param_debug;    /* def: 0 = minimal debug log messages */
+static int iwl4965_param_disable;  /* def: enable radio */
+static int iwl4965_param_antenna;  /* def: 0 = both antennas (use diversity) */
+int iwl4965_param_hwcrypto;        /* def: using software encryption */
+static int iwl4965_param_qos_enable = 1; /* def: 1 = use quality of service */
+int iwl4965_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 16 Tx queues */
+int iwl4965_param_amsdu_size_8K;   /* def: enable 8K amsdu size */
 
 /*
  * module name, copyright, version, etc.
@@ -88,19 +78,19 @@ int iwl_param_queues_num = IWL_MAX_NUM_QUEUES;
 
 #define DRV_DESCRIPTION        "Intel(R) Wireless WiFi Link 4965AGN driver for Linux"
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
 #define VD "d"
 #else
 #define VD
 #endif
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
 #define VS "s"
 #else
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "1.1.17k" VD VS
+#define IWLWIFI_VERSION "1.2.23k" VD VS
 #define DRV_COPYRIGHT  "Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -125,8 +115,8 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
        return NULL;
 }
 
-static const struct ieee80211_hw_mode *iwl_get_hw_mode(
-               struct iwl_priv *priv, int mode)
+static const struct ieee80211_hw_mode *iwl4965_get_hw_mode(
+               struct iwl4965_priv *priv, int mode)
 {
        int i;
 
@@ -137,7 +127,7 @@ static const struct ieee80211_hw_mode *iwl_get_hw_mode(
        return NULL;
 }
 
-static int iwl_is_empty_essid(const char *essid, int essid_len)
+static int iwl4965_is_empty_essid(const char *essid, int essid_len)
 {
        /* Single white space is for Linksys APs */
        if (essid_len == 1 && essid[0] == ' ')
@@ -153,13 +143,13 @@ static int iwl_is_empty_essid(const char *essid, int essid_len)
        return 1;
 }
 
-static const char *iwl_escape_essid(const char *essid, u8 essid_len)
+static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)
 {
        static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
        const char *s = essid;
        char *d = escaped;
 
-       if (iwl_is_empty_essid(essid, essid_len)) {
+       if (iwl4965_is_empty_essid(essid, essid_len)) {
                memcpy(escaped, "<hidden>", sizeof("<hidden>"));
                return escaped;
        }
@@ -177,10 +167,10 @@ static const char *iwl_escape_essid(const char *essid, u8 essid_len)
        return escaped;
 }
 
-static void iwl_print_hex_dump(int level, void *p, u32 len)
+static void iwl4965_print_hex_dump(int level, void *p, u32 len)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (!(iwl_debug_level & level))
+#ifdef CONFIG_IWL4965_DEBUG
+       if (!(iwl4965_debug_level & level))
                return;
 
        print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
@@ -193,24 +183,33 @@ static void iwl_print_hex_dump(int level, void *p, u32 len)
  *
  * Theory of operation
  *
- * A queue is a circular buffers with 'Read' and 'Write' pointers.
- * 2 empty entries always kept in the buffer to protect from overflow.
+ * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
+ * of buffer descriptors, each of which points to one or more data buffers for
+ * the device to read from or fill.  Driver and device exchange status of each
+ * queue via "read" and "write" pointers.  Driver keeps minimum of 2 empty
+ * entries in each circular buffer, to protect against confusing empty and full
+ * queue states.
+ *
+ * The device reads or writes the data in the queues via the device's several
+ * DMA/FIFO channels.  Each queue is mapped to a single DMA channel.
  *
  * For Tx queue, there are low mark and high mark limits. If, after queuing
  * the packet for Tx, free space become < low mark, Tx queue stopped. When
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IWL operates with six queues, one receive queue in the device's
- * sram, one transmit queue for sending commands to the device firmware,
- * and four transmit queues for data.
+ * The 4965 operates with up to 17 queues:  One receive queue, one transmit
+ * queue (#4) for sending commands to the device firmware, and 15 other
+ * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels.
+ *
+ * See more detailed info in iwl-4965-hw.h.
  ***************************************************/
 
-static int iwl_queue_space(const struct iwl_queue *q)
+static int iwl4965_queue_space(const struct iwl4965_queue *q)
 {
-       int s = q->last_used - q->first_empty;
+       int s = q->read_ptr - q->write_ptr;
 
-       if (q->last_used > q->first_empty)
+       if (q->read_ptr > q->write_ptr)
                s -= q->n_bd;
 
        if (s <= 0)
@@ -222,42 +221,55 @@ static int iwl_queue_space(const struct iwl_queue *q)
        return s;
 }
 
-/* XXX: n_bd must be power-of-two size */
-static inline int iwl_queue_inc_wrap(int index, int n_bd)
+/**
+ * iwl4965_queue_inc_wrap - increment queue index, wrap back to beginning
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl4965_queue_inc_wrap(int index, int n_bd)
 {
        return ++index & (n_bd - 1);
 }
 
-/* XXX: n_bd must be power-of-two size */
-static inline int iwl_queue_dec_wrap(int index, int n_bd)
+/**
+ * iwl4965_queue_dec_wrap - decrement queue index, wrap back to end
+ * @index -- current index
+ * @n_bd -- total number of entries in queue (must be power of 2)
+ */
+static inline int iwl4965_queue_dec_wrap(int index, int n_bd)
 {
        return --index & (n_bd - 1);
 }
 
-static inline int x2_queue_used(const struct iwl_queue *q, int i)
+static inline int x2_queue_used(const struct iwl4965_queue *q, int i)
 {
-       return q->first_empty > q->last_used ?
-               (i >= q->last_used && i < q->first_empty) :
-               !(i < q->last_used && i >= q->first_empty);
+       return q->write_ptr > q->read_ptr ?
+               (i >= q->read_ptr && i < q->write_ptr) :
+               !(i < q->read_ptr && i >= q->write_ptr);
 }
 
-static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
+static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge)
 {
+       /* This is for scan command, the big buffer at end of command array */
        if (is_huge)
-               return q->n_window;
+               return q->n_window;     /* must be power of 2 */
 
+       /* Otherwise, use normal size buffers */
        return index & (q->n_window - 1);
 }
 
-static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
+/**
+ * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes
+ */
+static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q,
                          int count, int slots_num, u32 id)
 {
        q->n_bd = count;
        q->n_window = slots_num;
        q->id = id;
 
-       /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
-        * and iwl_queue_dec_wrap are broken. */
+       /* count must be power-of-two size, otherwise iwl4965_queue_inc_wrap
+        * and iwl4965_queue_dec_wrap are broken. */
        BUG_ON(!is_power_of_2(count));
 
        /* slots_num must be power-of-two size, otherwise
@@ -272,27 +284,34 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
        if (q->high_mark < 2)
                q->high_mark = 2;
 
-       q->first_empty = q->last_used = 0;
+       q->write_ptr = q->read_ptr = 0;
 
        return 0;
 }
 
-static int iwl_tx_queue_alloc(struct iwl_priv *priv,
-                             struct iwl_tx_queue *txq, u32 id)
+/**
+ * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
+ */
+static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv,
+                             struct iwl4965_tx_queue *txq, u32 id)
 {
        struct pci_dev *dev = priv->pci_dev;
 
+       /* Driver private data, only for Tx (not command) queues,
+        * not shared with device. */
        if (id != IWL_CMD_QUEUE_NUM) {
                txq->txb = kmalloc(sizeof(txq->txb[0]) *
                                   TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
                if (!txq->txb) {
-                       IWL_ERROR("kmalloc for auxilary BD "
+                       IWL_ERROR("kmalloc for auxiliary BD "
                                  "structures failed\n");
                        goto error;
                }
        } else
                txq->txb = NULL;
 
+       /* Circular buffer of transmit frame descriptors (TFDs),
+        * shared with device */
        txq->bd = pci_alloc_consistent(dev,
                        sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX,
                        &txq->q.dma_addr);
@@ -315,24 +334,33 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
        return -ENOMEM;
 }
 
-int iwl_tx_queue_init(struct iwl_priv *priv,
-                     struct iwl_tx_queue *txq, int slots_num, u32 txq_id)
+/**
+ * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue
+ */
+int iwl4965_tx_queue_init(struct iwl4965_priv *priv,
+                     struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id)
 {
        struct pci_dev *dev = priv->pci_dev;
        int len;
        int rc = 0;
 
-       /* alocate command space + one big command for scan since scan
-        * command is very huge the system will not have two scan at the
-        * same time */
-       len = sizeof(struct iwl_cmd) * slots_num;
+       /*
+        * Alloc buffer array for commands (Tx or other types of commands).
+        * For the command queue (#4), allocate command space + one big
+        * command for scan, since scan command is very huge; the system will
+        * not have two scans at the same time, so only one is needed.
+        * For normal Tx queues (all other queues), no super-size command
+        * space is needed.
+        */
+       len = sizeof(struct iwl4965_cmd) * slots_num;
        if (txq_id == IWL_CMD_QUEUE_NUM)
                len +=  IWL_MAX_SCAN_SIZE;
        txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
        if (!txq->cmd)
                return -ENOMEM;
 
-       rc = iwl_tx_queue_alloc(priv, txq, txq_id);
+       /* Alloc driver data array and TFD circular buffer */
+       rc = iwl4965_tx_queue_alloc(priv, txq, txq_id);
        if (rc) {
                pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
 
@@ -341,26 +369,29 @@ int iwl_tx_queue_init(struct iwl_priv *priv,
        txq->need_update = 0;
 
        /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
-        * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
+        * iwl4965_queue_inc_wrap and iwl4965_queue_dec_wrap are broken. */
        BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-       iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 
-       iwl_hw_tx_queue_init(priv, txq);
+       /* Initialize queue's high/low-water marks, and head/tail indexes */
+       iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+       /* Tell device where to find queue */
+       iwl4965_hw_tx_queue_init(priv, txq);
 
        return 0;
 }
 
 /**
- * iwl_tx_queue_free - Deallocate DMA queue.
+ * iwl4965_tx_queue_free - Deallocate DMA queue.
  * @txq: Transmit queue to deallocate.
  *
  * Empty queue by removing and destroying all BD's.
- * Free all buffers.  txq itself is not freed.
- *
+ * Free all buffers.
+ * 0-fill, but do not free "txq" descriptor structure.
  */
-void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq)
 {
-       struct iwl_queue *q = &txq->q;
+       struct iwl4965_queue *q = &txq->q;
        struct pci_dev *dev = priv->pci_dev;
        int len;
 
@@ -368,45 +399,48 @@ void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                return;
 
        /* first, empty all BD's */
-       for (; q->first_empty != q->last_used;
-            q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd))
-               iwl_hw_txq_free_tfd(priv, txq);
+       for (; q->write_ptr != q->read_ptr;
+            q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd))
+               iwl4965_hw_txq_free_tfd(priv, txq);
 
-       len = sizeof(struct iwl_cmd) * q->n_window;
+       len = sizeof(struct iwl4965_cmd) * q->n_window;
        if (q->id == IWL_CMD_QUEUE_NUM)
                len += IWL_MAX_SCAN_SIZE;
 
+       /* De-alloc array of command/tx buffers */
        pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
 
-       /* free buffers belonging to queue itself */
+       /* De-alloc circular buffer of TFDs */
        if (txq->q.n_bd)
-               pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) *
+               pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) *
                                    txq->q.n_bd, txq->bd, txq->q.dma_addr);
 
+       /* De-alloc array of per-TFD driver data */
        if (txq->txb) {
                kfree(txq->txb);
                txq->txb = NULL;
        }
 
-       /* 0 fill whole structure */
+       /* 0-fill queue descriptor structure */
        memset(txq, 0, sizeof(*txq));
 }
 
-const u8 BROADCAST_ADDR[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
 /*************** STATION TABLE MANAGEMENT ****
- *
- * NOTE:  This needs to be overhauled to better synchronize between
- * how the iwl-4965.c is using iwl_hw_find_station vs. iwl-3945.c
- *
- * mac80211 should also be examined to determine if sta_info is duplicating
+ * mac80211 should be examined to determine if sta_info is duplicating
  * the functionality provided here
  */
 
 /**************************************************************/
 
-#if 0 /* temparary disable till we add real remove station */
-static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+#if 0 /* temporary disable till we add real remove station */
+/**
+ * iwl4965_remove_station - Remove driver's knowledge of station.
+ *
+ * NOTE:  This does not remove station from device's station table.
+ */
+static u8 iwl4965_remove_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)
 {
        int index = IWL_INVALID_STATION;
        int i;
@@ -443,7 +477,12 @@ out:
 }
 #endif
 
-static void iwl_clear_stations_table(struct iwl_priv *priv)
+/**
+ * iwl4965_clear_stations_table - Clear the driver's station table
+ *
+ * NOTE:  This does not clear or otherwise alter the device's station table.
+ */
+static void iwl4965_clear_stations_table(struct iwl4965_priv *priv)
 {
        unsigned long flags;
 
@@ -455,11 +494,15 @@ static void iwl_clear_stations_table(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 }
 
-u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
+/**
+ * iwl4965_add_station_flags - Add station to tables in driver and device
+ */
+u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr,
+                               int is_ap, u8 flags, void *ht_data)
 {
        int i;
        int index = IWL_INVALID_STATION;
-       struct iwl_station_entry *station;
+       struct iwl4965_station_entry *station;
        unsigned long flags_spin;
        DECLARE_MAC_BUF(mac);
 
@@ -482,8 +525,8 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
                }
 
 
-       /* These twh conditions has the same outcome but keep them separate
-         since they have different meaning */
+       /* These two conditions have the same outcome, but keep them separate
+         since they have different meanings */
        if (unlikely(index == IWL_INVALID_STATION)) {
                spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
                return index;
@@ -501,28 +544,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
        station->used = 1;
        priv->num_stations++;
 
-       memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd));
+       /* Set up the REPLY_ADD_STA command to send to device */
+       memset(&station->sta, 0, sizeof(struct iwl4965_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;
 
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
        /* BCAST station and IBSS stations do not work in HT mode */
        if (index != priv->hw_setting.bcast_sta_id &&
            priv->iw_mode != IEEE80211_IF_TYPE_IBSS)
-               iwl4965_set_ht_add_station(priv, index);
-#endif /*CONFIG_IWLWIFI_HT*/
+               iwl4965_set_ht_add_station(priv, index,
+                                (struct ieee80211_ht_info *) ht_data);
+#endif /*CONFIG_IWL4965_HT*/
 
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-       iwl_send_add_station(priv, &station->sta, flags);
+
+       /* Add station to device's station table */
+       iwl4965_send_add_station(priv, &station->sta, flags);
        return index;
 
 }
 
 /*************** DRIVER STATUS FUNCTIONS   *****/
 
-static inline int iwl_is_ready(struct iwl_priv *priv)
+static inline int iwl4965_is_ready(struct iwl4965_priv *priv)
 {
        /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
         * set but EXIT_PENDING is not */
@@ -531,29 +578,29 @@ static inline int iwl_is_ready(struct iwl_priv *priv)
               !test_bit(STATUS_EXIT_PENDING, &priv->status);
 }
 
-static inline int iwl_is_alive(struct iwl_priv *priv)
+static inline int iwl4965_is_alive(struct iwl4965_priv *priv)
 {
        return test_bit(STATUS_ALIVE, &priv->status);
 }
 
-static inline int iwl_is_init(struct iwl_priv *priv)
+static inline int iwl4965_is_init(struct iwl4965_priv *priv)
 {
        return test_bit(STATUS_INIT, &priv->status);
 }
 
-static inline int iwl_is_rfkill(struct iwl_priv *priv)
+static inline int iwl4965_is_rfkill(struct iwl4965_priv *priv)
 {
        return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
               test_bit(STATUS_RF_KILL_SW, &priv->status);
 }
 
-static inline int iwl_is_ready_rf(struct iwl_priv *priv)
+static inline int iwl4965_is_ready_rf(struct iwl4965_priv *priv)
 {
 
-       if (iwl_is_rfkill(priv))
+       if (iwl4965_is_rfkill(priv))
                return 0;
 
-       return iwl_is_ready(priv);
+       return iwl4965_is_ready(priv);
 }
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
@@ -618,7 +665,7 @@ static const char *get_cmd_string(u8 cmd)
 #define HOST_COMPLETE_TIMEOUT (HZ / 2)
 
 /**
- * iwl_enqueue_hcmd - enqueue a uCode command
+ * iwl4965_enqueue_hcmd - enqueue a uCode command
  * @priv: device private data point
  * @cmd: a point to the ucode command structure
  *
@@ -626,13 +673,13 @@ static const char *get_cmd_string(u8 cmd)
  * failed. On success, it turns the index (> 0) of command in the
  * command queue.
  */
-static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd)
 {
-       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
-       struct iwl_queue *q = &txq->q;
-       struct iwl_tfd_frame *tfd;
+       struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
+       struct iwl4965_queue *q = &txq->q;
+       struct iwl4965_tfd_frame *tfd;
        u32 *control_flags;
-       struct iwl_cmd *out_cmd;
+       struct iwl4965_cmd *out_cmd;
        u32 idx;
        u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
        dma_addr_t phys_addr;
@@ -645,19 +692,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
               !(cmd->meta.flags & CMD_SIZE_HUGE));
 
-       if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
+       if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) {
                IWL_ERROR("No space for Tx\n");
                return -ENOSPC;
        }
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
-       tfd = &txq->bd[q->first_empty];
+       tfd = &txq->bd[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
 
        control_flags = (u32 *) tfd;
 
-       idx = get_cmd_index(q, q->first_empty, cmd->meta.flags & CMD_SIZE_HUGE);
+       idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
        out_cmd = &txq->cmd[idx];
 
        out_cmd->hdr.cmd = cmd->id;
@@ -669,30 +716,34 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        out_cmd->hdr.flags = 0;
        out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
-                       INDEX_TO_SEQ(q->first_empty));
+                       INDEX_TO_SEQ(q->write_ptr));
        if (out_cmd->meta.flags & CMD_SIZE_HUGE)
                out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
 
        phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
-                       offsetof(struct iwl_cmd, hdr);
-       iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
+                       offsetof(struct iwl4965_cmd, hdr);
+       iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
 
        IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
                     "%d bytes at %d[%d]:%d\n",
                     get_cmd_string(out_cmd->hdr.cmd),
                     out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence),
-                    fix_size, q->first_empty, idx, IWL_CMD_QUEUE_NUM);
+                    fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM);
 
        txq->need_update = 1;
+
+       /* Set up entry in queue's byte count circular buffer */
        ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0);
-       q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd);
-       iwl_tx_queue_update_write_ptr(priv, txq);
+
+       /* Increment and update queue's write index */
+       q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd);
+       iwl4965_tx_queue_update_write_ptr(priv, txq);
 
        spin_unlock_irqrestore(&priv->hcmd_lock, flags);
        return ret ? ret : idx;
 }
 
-int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl4965_send_cmd_async(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd)
 {
        int ret;
 
@@ -707,16 +758,16 @@ int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return -EBUSY;
 
-       ret = iwl_enqueue_hcmd(priv, cmd);
+       ret = iwl4965_enqueue_hcmd(priv, cmd);
        if (ret < 0) {
-               IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n",
+               IWL_ERROR("Error sending %s: iwl4965_enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                return ret;
        }
        return 0;
 }
 
-int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+static int iwl4965_send_cmd_sync(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd)
 {
        int cmd_idx;
        int ret;
@@ -738,10 +789,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        if (cmd->meta.flags & CMD_WANT_SKB)
                cmd->meta.source = &cmd->meta;
 
-       cmd_idx = iwl_enqueue_hcmd(priv, cmd);
+       cmd_idx = iwl4965_enqueue_hcmd(priv, cmd);
        if (cmd_idx < 0) {
                ret = cmd_idx;
-               IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n",
+               IWL_ERROR("Error sending %s: iwl4965_enqueue_hcmd failed: %d\n",
                          get_cmd_string(cmd->id), ret);
                goto out;
        }
@@ -785,7 +836,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
 cancel:
        if (cmd->meta.flags & CMD_WANT_SKB) {
-               struct iwl_cmd *qcmd;
+               struct iwl4965_cmd *qcmd;
 
                /* Cancel the CMD_WANT_SKB flag for the cmd in the
                 * TX cmd queue. Otherwise in case the cmd comes
@@ -804,64 +855,75 @@ out:
        return ret;
 }
 
-int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
+int iwl4965_send_cmd(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd)
 {
-       /* A command can not be asynchronous AND expect an SKB to be set. */
-       BUG_ON((cmd->meta.flags & CMD_ASYNC) &&
-              (cmd->meta.flags & CMD_WANT_SKB));
-
        if (cmd->meta.flags & CMD_ASYNC)
-               return iwl_send_cmd_async(priv, cmd);
+               return iwl4965_send_cmd_async(priv, cmd);
 
-       return iwl_send_cmd_sync(priv, cmd);
+       return iwl4965_send_cmd_sync(priv, cmd);
 }
 
-int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data)
+int iwl4965_send_cmd_pdu(struct iwl4965_priv *priv, u8 id, u16 len, const void *data)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_host_cmd cmd = {
                .id = id,
                .len = len,
                .data = data,
        };
 
-       return iwl_send_cmd_sync(priv, &cmd);
+       return iwl4965_send_cmd_sync(priv, &cmd);
 }
 
-static int __must_check iwl_send_cmd_u32(struct iwl_priv *priv, u8 id, u32 val)
+static int __must_check iwl4965_send_cmd_u32(struct iwl4965_priv *priv, u8 id, u32 val)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_host_cmd cmd = {
                .id = id,
                .len = sizeof(val),
                .data = &val,
        };
 
-       return iwl_send_cmd_sync(priv, &cmd);
+       return iwl4965_send_cmd_sync(priv, &cmd);
 }
 
-int iwl_send_statistics_request(struct iwl_priv *priv)
+int iwl4965_send_statistics_request(struct iwl4965_priv *priv)
 {
-       return iwl_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
+       return iwl4965_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0);
 }
 
 /**
- * iwl_rxon_add_station - add station into station table.
+ * iwl4965_rxon_add_station - add station into station table.
  *
  * there is only one AP station with id= IWL_AP_ID
- * NOTE: mutex must be held before calling the this fnction
-*/
-static int iwl_rxon_add_station(struct iwl_priv *priv,
+ * NOTE: mutex must be held before calling this fnction
+ */
+static int iwl4965_rxon_add_station(struct iwl4965_priv *priv,
                                const u8 *addr, int is_ap)
 {
        u8 sta_id;
 
-       sta_id = iwl_add_station(priv, addr, is_ap, 0);
+       /* Add station to device's station table */
+#ifdef CONFIG_IWL4965_HT
+       struct ieee80211_conf *conf = &priv->hw->conf;
+       struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;
+
+       if ((is_ap) &&
+           (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
+           (priv->iw_mode == IEEE80211_IF_TYPE_STA))
+               sta_id = iwl4965_add_station_flags(priv, addr, is_ap,
+                                                  0, cur_ht_config);
+       else
+#endif /* CONFIG_IWL4965_HT */
+               sta_id = iwl4965_add_station_flags(priv, addr, is_ap,
+                                                  0, NULL);
+
+       /* Set up default rate scaling table in device's station table */
        iwl4965_add_station(priv, addr, is_ap);
 
        return sta_id;
 }
 
 /**
- * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
+ * iwl4965_set_rxon_channel - Set the phymode and channel values in staging RXON
  * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
  * @channel: Any channel valid for the requested phymode
 
@@ -870,9 +932,10 @@ static int iwl_rxon_add_station(struct iwl_priv *priv,
  * NOTE:  Does not commit to the hardware; it sets appropriate bit fields
  * in the staging RXON flag structure based on the phymode
  */
-static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel)
+static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode,
+                                u16 channel)
 {
-       if (!iwl_get_channel_info(priv, phymode, channel)) {
+       if (!iwl4965_get_channel_info(priv, phymode, channel)) {
                IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
                               channel, phymode);
                return -EINVAL;
@@ -896,13 +959,13 @@ static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel)
 }
 
 /**
- * iwl_check_rxon_cmd - validate RXON structure is valid
+ * iwl4965_check_rxon_cmd - validate RXON structure is valid
  *
  * NOTE:  This is really only useful during development and can eventually
  * be #ifdef'd out once the driver is stable and folks aren't actively
  * making changes
  */
-static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
+static int iwl4965_check_rxon_cmd(struct iwl4965_rxon_cmd *rxon)
 {
        int error = 0;
        int counter = 1;
@@ -962,21 +1025,21 @@ static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
                            le16_to_cpu(rxon->channel));
 
        if (error) {
-               IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n");
+               IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n");
                return -1;
        }
        return 0;
 }
 
 /**
- * iwl_full_rxon_required - determine if RXON_ASSOC can be used in RXON commit
- * @priv: staging_rxon is comapred to active_rxon
+ * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * @priv: staging_rxon is compared to active_rxon
  *
- * If the RXON structure is changing sufficient to require a new
- * tune or to clear and reset the RXON_FILTER_ASSOC_MSK then return 1
- * to indicate a new tune is required.
+ * If the RXON structure is changing enough to require a new tune,
+ * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
+ * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  */
-static int iwl_full_rxon_required(struct iwl_priv *priv)
+static int iwl4965_full_rxon_required(struct iwl4965_priv *priv)
 {
 
        /* These items are only settable from the full RXON command */
@@ -1016,19 +1079,19 @@ static int iwl_full_rxon_required(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_send_rxon_assoc(struct iwl_priv *priv)
+static int iwl4965_send_rxon_assoc(struct iwl4965_priv *priv)
 {
        int rc = 0;
-       struct iwl_rx_packet *res = NULL;
-       struct iwl_rxon_assoc_cmd rxon_assoc;
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_rx_packet *res = NULL;
+       struct iwl4965_rxon_assoc_cmd rxon_assoc;
+       struct iwl4965_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;
+       const struct iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon;
+       const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon;
 
        if ((rxon1->flags == rxon2->flags) &&
            (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1054,11 +1117,11 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv)
            priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
        rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl4965_send_cmd_sync(priv, &cmd);
        if (rc)
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n");
                rc = -EIO;
@@ -1071,37 +1134,37 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv)
 }
 
 /**
- * iwl_commit_rxon - commit staging_rxon to hardware
+ * iwl4965_commit_rxon - commit staging_rxon to hardware
  *
- * The RXON command in staging_rxon is commited to the hardware and
+ * 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 iwl_commit_rxon(struct iwl_priv *priv)
+static int iwl4965_commit_rxon(struct iwl4965_priv *priv)
 {
        /* cast away the const for active_rxon in this function */
-       struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+       struct iwl4965_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
        DECLARE_MAC_BUF(mac);
        int rc = 0;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl4965_is_alive(priv))
                return -1;
 
        /* always get timestamp with Rx frame */
        priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
 
-       rc = iwl_check_rxon_cmd(&priv->staging_rxon);
+       rc = iwl4965_check_rxon_cmd(&priv->staging_rxon);
        if (rc) {
                IWL_ERROR("Invalid RXON configuration.  Not committing.\n");
                return -EINVAL;
        }
 
        /* If we don't need to send a full RXON, we can use
-        * iwl_rxon_assoc_cmd which is used to reconfigure filter
+        * iwl4965_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 (!iwl4965_full_rxon_required(priv)) {
+               rc = iwl4965_send_rxon_assoc(priv);
                if (rc) {
                        IWL_ERROR("Error setting RXON_ASSOC "
                                  "configuration (%d).\n", rc);
@@ -1116,25 +1179,25 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
        /* station table will be cleared */
        priv->assoc_station_added = 0;
 
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
        priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
        if (!priv->error_recovering)
                priv->start_calib = 0;
 
        iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
-#endif /* CONFIG_IWLWIFI_SENSITIVITY */
+#endif /* CONFIG_IWL4965_SENSITIVITY */
 
        /* 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) &&
+       if (iwl4965_is_associated(priv) &&
            (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
                IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                                     sizeof(struct iwl_rxon_cmd),
+               rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON,
+                                     sizeof(struct iwl4965_rxon_cmd),
                                      &priv->active_rxon);
 
                /* If the mask clearing failed then we set
@@ -1157,35 +1220,35 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
                       print_mac(mac, priv->staging_rxon.bssid_addr));
 
        /* Apply the new configuration */
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                             sizeof(struct iwl_rxon_cmd), &priv->staging_rxon);
+       rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON,
+                             sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon);
        if (rc) {
                IWL_ERROR("Error setting new configuration (%d).\n", rc);
                return rc;
        }
 
-       iwl_clear_stations_table(priv);
+       iwl4965_clear_stations_table(priv);
 
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
        if (!priv->error_recovering)
                priv->start_calib = 0;
 
        priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT;
        iwl4965_init_sensitivity(priv, CMD_ASYNC, 1);
-#endif /* CONFIG_IWLWIFI_SENSITIVITY */
+#endif /* CONFIG_IWL4965_SENSITIVITY */
 
        memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 
        /* 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 = iwl_hw_reg_send_txpower(priv);
+       rc = iwl4965_hw_reg_send_txpower(priv);
        if (rc) {
                IWL_ERROR("Error setting Tx power (%d).\n", rc);
                return rc;
        }
 
        /* Add the broadcast address so we can send broadcast frames */
-       if (iwl_rxon_add_station(priv, BROADCAST_ADDR, 0) ==
+       if (iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0) ==
            IWL_INVALID_STATION) {
                IWL_ERROR("Error adding BROADCAST address for transmit.\n");
                return -EIO;
@@ -1193,9 +1256,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
 
        /* 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) &&
+       if (iwl4965_is_associated(priv) &&
            (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
-               if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
+               if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
                    == IWL_INVALID_STATION) {
                        IWL_ERROR("Error adding AP address for transmit.\n");
                        return -EIO;
@@ -1206,9 +1269,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_send_bt_config(struct iwl_priv *priv)
+static int iwl4965_send_bt_config(struct iwl4965_priv *priv)
 {
-       struct iwl_bt_cmd bt_cmd = {
+       struct iwl4965_bt_cmd bt_cmd = {
                .flags = 3,
                .lead_time = 0xAA,
                .max_kill = 1,
@@ -1216,15 +1279,15 @@ static int iwl_send_bt_config(struct iwl_priv *priv)
                .kill_cts_mask = 0,
        };
 
-       return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
-                               sizeof(struct iwl_bt_cmd), &bt_cmd);
+       return iwl4965_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+                               sizeof(struct iwl4965_bt_cmd), &bt_cmd);
 }
 
-static int iwl_send_scan_abort(struct iwl_priv *priv)
+static int iwl4965_send_scan_abort(struct iwl4965_priv *priv)
 {
        int rc = 0;
-       struct iwl_rx_packet *res;
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_rx_packet *res;
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_SCAN_ABORT_CMD,
                .meta.flags = CMD_WANT_SKB,
        };
@@ -1237,13 +1300,13 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
                return 0;
        }
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl4965_send_cmd_sync(priv, &cmd);
        if (rc) {
                clear_bit(STATUS_SCAN_ABORTING, &priv->status);
                return rc;
        }
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
        if (res->u.status != CAN_ABORT_STATUS) {
                /* The scan abort will return 1 for success or
                 * 2 for "failure".  A failure condition can be
@@ -1261,8 +1324,8 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
        return rc;
 }
 
-static int iwl_card_state_sync_callback(struct iwl_priv *priv,
-                                       struct iwl_cmd *cmd,
+static int iwl4965_card_state_sync_callback(struct iwl4965_priv *priv,
+                                       struct iwl4965_cmd *cmd,
                                        struct sk_buff *skb)
 {
        return 1;
@@ -1271,16 +1334,16 @@ static int iwl_card_state_sync_callback(struct iwl_priv *priv,
 /*
  * CARD_STATE_CMD
  *
- * Use: Sets the internal card state to enable, disable, or halt
+ * Use: Sets the device's internal card state to enable, disable, or halt
  *
  * When in the 'enable' state the card operates as normal.
  * When in the 'disable' state, the card enters into a low power mode.
  * When in the 'halt' state, the card is shut down and must be fully
  * restarted to come back on.
  */
-static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
+static int iwl4965_send_card_state(struct iwl4965_priv *priv, u32 flags, u8 meta_flag)
 {
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_CARD_STATE_CMD,
                .len = sizeof(u32),
                .data = &flags,
@@ -1288,22 +1351,22 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
        };
 
        if (meta_flag & CMD_ASYNC)
-               cmd.meta.u.callback = iwl_card_state_sync_callback;
+               cmd.meta.u.callback = iwl4965_card_state_sync_callback;
 
-       return iwl_send_cmd(priv, &cmd);
+       return iwl4965_send_cmd(priv, &cmd);
 }
 
-static int iwl_add_sta_sync_callback(struct iwl_priv *priv,
-                                    struct iwl_cmd *cmd, struct sk_buff *skb)
+static int iwl4965_add_sta_sync_callback(struct iwl4965_priv *priv,
+                                    struct iwl4965_cmd *cmd, struct sk_buff *skb)
 {
-       struct iwl_rx_packet *res = NULL;
+       struct iwl4965_rx_packet *res = NULL;
 
        if (!skb) {
                IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n");
                return 1;
        }
 
-       res = (struct iwl_rx_packet *)skb->data;
+       res = (struct iwl4965_rx_packet *)skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
                          res->hdr.flags);
@@ -1321,29 +1384,29 @@ static int iwl_add_sta_sync_callback(struct iwl_priv *priv,
        return 1;
 }
 
-int iwl_send_add_station(struct iwl_priv *priv,
-                        struct iwl_addsta_cmd *sta, u8 flags)
+int iwl4965_send_add_station(struct iwl4965_priv *priv,
+                        struct iwl4965_addsta_cmd *sta, u8 flags)
 {
-       struct iwl_rx_packet *res = NULL;
+       struct iwl4965_rx_packet *res = NULL;
        int rc = 0;
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_ADD_STA,
-               .len = sizeof(struct iwl_addsta_cmd),
+               .len = sizeof(struct iwl4965_addsta_cmd),
                .meta.flags = flags,
                .data = sta,
        };
 
        if (flags & CMD_ASYNC)
-               cmd.meta.u.callback = iwl_add_sta_sync_callback;
+               cmd.meta.u.callback = iwl4965_add_sta_sync_callback;
        else
                cmd.meta.flags |= CMD_WANT_SKB;
 
-       rc = iwl_send_cmd(priv, &cmd);
+       rc = iwl4965_send_cmd(priv, &cmd);
 
        if (rc || (flags & CMD_ASYNC))
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n",
                          res->hdr.flags);
@@ -1368,7 +1431,7 @@ int iwl_send_add_station(struct iwl_priv *priv,
        return rc;
 }
 
-static int iwl_update_sta_key_info(struct iwl_priv *priv,
+static int iwl4965_update_sta_key_info(struct iwl4965_priv *priv,
                                   struct ieee80211_key_conf *keyconf,
                                   u8 sta_id)
 {
@@ -1384,7 +1447,6 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv,
                break;
        case ALG_TKIP:
        case ALG_WEP:
-               return -EINVAL;
        default:
                return -EINVAL;
        }
@@ -1403,28 +1465,28 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv,
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
        IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
        return 0;
 }
 
-static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
+static int iwl4965_clear_sta_key_info(struct iwl4965_priv *priv, u8 sta_id)
 {
        unsigned long flags;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
-       memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
-       memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo));
+       memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key));
+       memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo));
        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("hwcrypto: clear ucode station key info\n");
-       iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+       iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
        return 0;
 }
 
-static void iwl_clear_free_frames(struct iwl_priv *priv)
+static void iwl4965_clear_free_frames(struct iwl4965_priv *priv)
 {
        struct list_head *element;
 
@@ -1434,7 +1496,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
        while (!list_empty(&priv->free_frames)) {
                element = priv->free_frames.next;
                list_del(element);
-               kfree(list_entry(element, struct iwl_frame, list));
+               kfree(list_entry(element, struct iwl4965_frame, list));
                priv->frames_count--;
        }
 
@@ -1445,9 +1507,9 @@ static void iwl_clear_free_frames(struct iwl_priv *priv)
        }
 }
 
-static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
+static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl4965_priv *priv)
 {
-       struct iwl_frame *frame;
+       struct iwl4965_frame *frame;
        struct list_head *element;
        if (list_empty(&priv->free_frames)) {
                frame = kzalloc(sizeof(*frame), GFP_KERNEL);
@@ -1462,21 +1524,21 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
 
        element = priv->free_frames.next;
        list_del(element);
-       return list_entry(element, struct iwl_frame, list);
+       return list_entry(element, struct iwl4965_frame, list);
 }
 
-static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
+static void iwl4965_free_frame(struct iwl4965_priv *priv, struct iwl4965_frame *frame)
 {
        memset(frame, 0, sizeof(*frame));
        list_add(&frame->list, &priv->free_frames);
 }
 
-unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
+unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv,
                                struct ieee80211_hdr *hdr,
                                const u8 *dest, int left)
 {
 
-       if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
+       if (!iwl4965_is_associated(priv) || !priv->ibss_beacon ||
            ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
             (priv->iw_mode != IEEE80211_IF_TYPE_AP)))
                return 0;
@@ -1489,10 +1551,11 @@ unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-int iwl_rate_index_from_plcp(int plcp)
+int iwl4965_rate_index_from_plcp(int plcp)
 {
        int i = 0;
 
+       /* 4965 HT rate format */
        if (plcp & RATE_MCS_HT_MSK) {
                i = (plcp & 0xff);
 
@@ -1506,35 +1569,37 @@ int iwl_rate_index_from_plcp(int plcp)
                if ((i >= IWL_FIRST_OFDM_RATE) &&
                    (i <= IWL_LAST_OFDM_RATE))
                        return i;
+
+       /* 4965 legacy rate format, search for match in table */
        } else {
-               for (i = 0; i < ARRAY_SIZE(iwl_rates); i++)
-                       if (iwl_rates[i].plcp == (plcp &0xFF))
+               for (i = 0; i < ARRAY_SIZE(iwl4965_rates); i++)
+                       if (iwl4965_rates[i].plcp == (plcp &0xFF))
                                return i;
        }
        return -1;
 }
 
-static u8 iwl_rate_get_lowest_plcp(int rate_mask)
+static u8 iwl4965_rate_get_lowest_plcp(int rate_mask)
 {
        u8 i;
 
        for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
-            i = iwl_rates[i].next_ieee) {
+            i = iwl4965_rates[i].next_ieee) {
                if (rate_mask & (1 << i))
-                       return iwl_rates[i].plcp;
+                       return iwl4965_rates[i].plcp;
        }
 
        return IWL_RATE_INVALID;
 }
 
-static int iwl_send_beacon_cmd(struct iwl_priv *priv)
+static int iwl4965_send_beacon_cmd(struct iwl4965_priv *priv)
 {
-       struct iwl_frame *frame;
+       struct iwl4965_frame *frame;
        unsigned int frame_size;
        int rc;
        u8 rate;
 
-       frame = iwl_get_free_frame(priv);
+       frame = iwl4965_get_free_frame(priv);
 
        if (!frame) {
                IWL_ERROR("Could not obtain free frame buffer for beacon "
@@ -1543,22 +1608,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
        }
 
        if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) {
-               rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic &
+               rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic &
                                                0xFF0);
                if (rate == IWL_INVALID_RATE)
                        rate = IWL_RATE_6M_PLCP;
        } else {
-               rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
+               rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
                if (rate == IWL_INVALID_RATE)
                        rate = IWL_RATE_1M_PLCP;
        }
 
-       frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate);
+       frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate);
 
-       rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
+       rc = iwl4965_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
                              &frame->u.cmd[0]);
 
-       iwl_free_frame(priv, frame);
+       iwl4965_free_frame(priv, frame);
 
        return rc;
 }
@@ -1569,22 +1634,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv)
  *
  ******************************************************************************/
 
-static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac)
+static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
 {
        memcpy(mac, priv->eeprom.mac_address, 6);
 }
 
 /**
- * iwl_eeprom_init - read EEPROM contents
+ * iwl4965_eeprom_init - read EEPROM contents
  *
- * Load the EEPROM from adapter into priv->eeprom
+ * Load the EEPROM contents from adapter into priv->eeprom
  *
  * NOTE:  This routine uses the non-debug IO access functions.
  */
-int iwl_eeprom_init(struct iwl_priv *priv)
+int iwl4965_eeprom_init(struct iwl4965_priv *priv)
 {
-       u16 *e = (u16 *)&priv->eeprom;
-       u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
+       __le16 *e = (__le16 *)&priv->eeprom;
+       u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
        u32 r;
        int sz = sizeof(priv->eeprom);
        int rc;
@@ -1602,20 +1667,21 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                return -ENOENT;
        }
 
-       rc = iwl_eeprom_aqcuire_semaphore(priv);
+       /* Make sure driver (instead of uCode) is allowed to read EEPROM */
+       rc = iwl4965_eeprom_acquire_semaphore(priv);
        if (rc < 0) {
-               IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n");
+               IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
                return -ENOENT;
        }
 
        /* eeprom is an array of 16bit values */
        for (addr = 0; addr < sz; addr += sizeof(u16)) {
-               _iwl_write32(priv, CSR_EEPROM_REG, addr << 1);
-               _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
+               _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1);
+               _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
 
                for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
                                        i += IWL_EEPROM_ACCESS_DELAY) {
-                       r = _iwl_read_restricted(priv, CSR_EEPROM_REG);
+                       r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG);
                        if (r & CSR_EEPROM_REG_READ_VALID_MSK)
                                break;
                        udelay(IWL_EEPROM_ACCESS_DELAY);
@@ -1626,12 +1692,12 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                        rc = -ETIMEDOUT;
                        goto done;
                }
-               e[addr / 2] = le16_to_cpu(r >> 16);
+               e[addr / 2] = cpu_to_le16(r >> 16);
        }
        rc = 0;
 
 done:
-       iwl_eeprom_release_semaphore(priv);
+       iwl4965_eeprom_release_semaphore(priv);
        return rc;
 }
 
@@ -1640,22 +1706,20 @@ done:
  * Misc. internal state and helper functions
  *
  ******************************************************************************/
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
 
 /**
- * iwl_report_frame - dump frame to syslog during debug sessions
+ * iwl4965_report_frame - dump frame to syslog during debug sessions
  *
- * hack this function to show different aspects of received frames,
+ * You may hack this function to show different aspects of received frames,
  * including selective frame dumps.
  * group100 parameter selects whether to show 1 out of 100 good frames.
  *
- * TODO:  ieee80211_hdr stuff is common to 3945 and 4965, so frame type
- *        info output is okay, but some of this stuff (e.g. iwl_rx_frame_stats)
- *        is 3945-specific and gives bad output for 4965.  Need to split the
- *        functionality, keep common stuff here.
+ * TODO:  This was originally written for 3945, need to audit for
+ *        proper operation with 4965.
  */
-void iwl_report_frame(struct iwl_priv *priv,
-                     struct iwl_rx_packet *pkt,
+void iwl4965_report_frame(struct iwl4965_priv *priv,
+                     struct iwl4965_rx_packet *pkt,
                      struct ieee80211_hdr *header, int group100)
 {
        u32 to_us;
@@ -1677,9 +1741,9 @@ void iwl_report_frame(struct iwl_priv *priv,
        u8 agc;
        u16 sig_avg;
        u16 noise_diff;
-       struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
-       struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
-       struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt);
+       struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
+       struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
+       struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
        u8 *data = IWL_RX_DATA(pkt);
 
        /* MAC header */
@@ -1755,11 +1819,11 @@ void iwl_report_frame(struct iwl_priv *priv,
                else
                        title = "Frame";
 
-               rate = iwl_rate_index_from_plcp(rate_sym);
+               rate = iwl4965_rate_index_from_plcp(rate_sym);
                if (rate == -1)
                        rate = 0;
                else
-                       rate = iwl_rates[rate].ieee / 2;
+                       rate = iwl4965_rates[rate].ieee / 2;
 
                /* print frame summary.
                 * MAC addresses show just the last byte (for brevity),
@@ -1781,25 +1845,25 @@ void iwl_report_frame(struct iwl_priv *priv,
                }
        }
        if (print_dump)
-               iwl_print_hex_dump(IWL_DL_RX, data, length);
+               iwl4965_print_hex_dump(IWL_DL_RX, data, length);
 }
 #endif
 
-static void iwl_unset_hw_setting(struct iwl_priv *priv)
+static void iwl4965_unset_hw_setting(struct iwl4965_priv *priv)
 {
        if (priv->hw_setting.shared_virt)
                pci_free_consistent(priv->pci_dev,
-                                   sizeof(struct iwl_shared),
+                                   sizeof(struct iwl4965_shared),
                                    priv->hw_setting.shared_virt,
                                    priv->hw_setting.shared_phys);
 }
 
 /**
- * iwl_supported_rate_to_ie - fill in the supported rate in IE field
+ * iwl4965_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,
+static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,
                                    u16 basic_rate, int *left)
 {
        u16 ret_rates = 0, bit;
@@ -1810,7 +1874,7 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
        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 |
+                       rates[*cnt] = iwl4965_rates[i].ieee |
                                ((bit & basic_rate) ? 0x80 : 0x00);
                        (*cnt)++;
                        (*left)--;
@@ -1823,22 +1887,25 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
        return ret_rates;
 }
 
-#ifdef CONFIG_IWLWIFI_HT
-void static iwl_set_ht_capab(struct ieee80211_hw *hw,
-                            struct ieee80211_ht_capability *ht_cap,
-                            u8 use_wide_chan);
+#ifdef CONFIG_IWL4965_HT
+void static iwl4965_set_ht_capab(struct ieee80211_hw *hw,
+                            struct ieee80211_ht_cap *ht_cap,
+                            u8 use_current_config);
 #endif
 
 /**
- * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ * iwl4965_fill_probe_req - fill in all required fields and IE for probe request
  */
-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
+static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv,
                              struct ieee80211_mgmt *frame,
                              int left, int is_direct)
 {
        int len = 0;
        u8 *pos = NULL;
-       u16 active_rates, ret_rates, cck_rates;
+       u16 active_rates, ret_rates, cck_rates, active_rate_basic;
+#ifdef CONFIG_IWL4965_HT
+       struct ieee80211_hw_mode *mode;
+#endif /* CONFIG_IWL4965_HT */
 
        /* Make sure there is enough space for the probe request,
         * two mandatory IEs and the data */
@@ -1848,9 +1915,9 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        len += 24;
 
        frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
-       memcpy(frame->da, BROADCAST_ADDR, ETH_ALEN);
+       memcpy(frame->da, iwl4965_broadcast_addr, ETH_ALEN);
        memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
-       memcpy(frame->bssid, BROADCAST_ADDR, ETH_ALEN);
+       memcpy(frame->bssid, iwl4965_broadcast_addr, ETH_ALEN);
        frame->seq_ctrl = 0;
 
        /* fill in our indirect SSID IE */
@@ -1888,17 +1955,19 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        *pos++ = WLAN_EID_SUPP_RATES;
        *pos = 0;
 
-       priv->active_rate = priv->rates_mask;
-       active_rates = priv->active_rate;
-       priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
+       /* 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,
-                       priv->active_rate_basic, &left);
+       ret_rates = iwl4965_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,
-                                priv->active_rate_basic, &left);
+       ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates,
+                                active_rate_basic, &left);
        active_rates &= ~ret_rates;
 
        len += 2 + *pos;
@@ -1914,25 +1983,22 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
        /* ... fill it in... */
        *pos++ = WLAN_EID_EXT_SUPP_RATES;
        *pos = 0;
-       iwl_supported_rate_to_ie(pos, active_rates,
-                                priv->active_rate_basic, &left);
+       iwl4965_supported_rate_to_ie(pos, active_rates,
+                                active_rate_basic, &left);
        if (*pos > 0)
                len += 2 + *pos;
 
-#ifdef CONFIG_IWLWIFI_HT
-       if (is_direct && priv->is_ht_enabled) {
-               u8 use_wide_chan = 1;
-
-               if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ)
-                       use_wide_chan = 0;
+#ifdef CONFIG_IWL4965_HT
+       mode = priv->hw->conf.mode;
+       if (mode->ht_info.ht_supported) {
                pos += (*pos) + 1;
                *pos++ = WLAN_EID_HT_CAPABILITY;
-               *pos++ = sizeof(struct ieee80211_ht_capability);
-               iwl_set_ht_capab(NULL, (struct ieee80211_ht_capability *)pos,
-                                use_wide_chan);
-               len += 2 + sizeof(struct ieee80211_ht_capability);
+               *pos++ = sizeof(struct ieee80211_ht_cap);
+               iwl4965_set_ht_capab(priv->hw,
+                               (struct ieee80211_ht_cap *)pos, 0);
+               len += 2 + sizeof(struct ieee80211_ht_cap);
        }
-#endif  /*CONFIG_IWLWIFI_HT */
+#endif  /*CONFIG_IWL4965_HT */
 
  fill_end:
        return (u16)len;
@@ -1941,16 +2007,16 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
 /*
  * QoS  support
 */
-#ifdef CONFIG_IWLWIFI_QOS
-static int iwl_send_qos_params_command(struct iwl_priv *priv,
-                                      struct iwl_qosparam_cmd *qos)
+#ifdef CONFIG_IWL4965_QOS
+static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv,
+                                      struct iwl4965_qosparam_cmd *qos)
 {
 
-       return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
-                               sizeof(struct iwl_qosparam_cmd), qos);
+       return iwl4965_send_cmd_pdu(priv, REPLY_QOS_PARAM,
+                               sizeof(struct iwl4965_qosparam_cmd), qos);
 }
 
-static void iwl_reset_qos(struct iwl_priv *priv)
+static void iwl4965_reset_qos(struct iwl4965_priv *priv)
 {
        u16 cw_min = 15;
        u16 cw_max = 1023;
@@ -2037,13 +2103,10 @@ static void iwl_reset_qos(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force)
 {
        unsigned long flags;
 
-       if (priv == NULL)
-               return;
-
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
@@ -2057,23 +2120,28 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
            !priv->qos_data.qos_cap.q_AP.txop_request)
                priv->qos_data.def_qos_parm.qos_flags |=
                        QOS_PARAM_FLG_TXOP_TYPE_MSK;
-
        if (priv->qos_data.qos_active)
                priv->qos_data.def_qos_parm.qos_flags |=
                        QOS_PARAM_FLG_UPDATE_EDCA_MSK;
 
+#ifdef CONFIG_IWL4965_HT
+       if (priv->current_ht_config.is_ht)
+               priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+#endif /* CONFIG_IWL4965_HT */
+
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (force || iwl_is_associated(priv)) {
-               IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n",
-                             priv->qos_data.qos_active);
+       if (force || iwl4965_is_associated(priv)) {
+               IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+                               priv->qos_data.qos_active,
+                               priv->qos_data.def_qos_parm.qos_flags);
 
-               iwl_send_qos_params_command(priv,
+               iwl4965_send_qos_params_command(priv,
                                &(priv->qos_data.def_qos_parm));
        }
 }
 
-#endif /* CONFIG_IWLWIFI_QOS */
+#endif /* CONFIG_IWL4965_QOS */
 /*
  * Power management (not Tx power!) functions
  */
@@ -2091,7 +2159,7 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 
 /* default power management (not Tx power) table values */
 /* for tim  0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
+static struct iwl4965_power_vec_entry range_0[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0},
@@ -2101,7 +2169,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
 };
 
 /* for tim > 10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
+static struct iwl4965_power_vec_entry range_1[IWL_POWER_AC] = {
        {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500),
                 SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
@@ -2114,11 +2182,11 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
                 SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
 };
 
-int iwl_power_init_handle(struct iwl_priv *priv)
+int iwl4965_power_init_handle(struct iwl4965_priv *priv)
 {
        int rc = 0, i;
-       struct iwl_power_mgr *pow_data;
-       int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;
+       struct iwl4965_power_mgr *pow_data;
+       int size = sizeof(struct iwl4965_power_vec_entry) * IWL_POWER_AC;
        u16 pci_pm;
 
        IWL_DEBUG_POWER("Initialize power \n");
@@ -2137,7 +2205,7 @@ int iwl_power_init_handle(struct iwl_priv *priv)
        if (rc != 0)
                return 0;
        else {
-               struct iwl_powertable_cmd *cmd;
+               struct iwl4965_powertable_cmd *cmd;
 
                IWL_DEBUG_POWER("adjust power command flags\n");
 
@@ -2153,15 +2221,15 @@ int iwl_power_init_handle(struct iwl_priv *priv)
        return rc;
 }
 
-static int iwl_update_power_cmd(struct iwl_priv *priv,
-                               struct iwl_powertable_cmd *cmd, u32 mode)
+static int iwl4965_update_power_cmd(struct iwl4965_priv *priv,
+                               struct iwl4965_powertable_cmd *cmd, u32 mode)
 {
        int rc = 0, i;
        u8 skip;
        u32 max_sleep = 0;
-       struct iwl_power_vec_entry *range;
+       struct iwl4965_power_vec_entry *range;
        u8 period = 0;
-       struct iwl_power_mgr *pow_data;
+       struct iwl4965_power_mgr *pow_data;
 
        if (mode > IWL_POWER_INDEX_5) {
                IWL_DEBUG_POWER("Error invalid power mode \n");
@@ -2174,7 +2242,7 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
        else
                range = &pow_data->pwr_range_1[1];
 
-       memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
+       memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd));
 
 #ifdef IWL_MAC80211_DISABLE
        if (priv->assoc_network != NULL) {
@@ -2217,14 +2285,14 @@ static int iwl_update_power_cmd(struct iwl_priv *priv,
        return rc;
 }
 
-static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
+static int iwl4965_send_power_mode(struct iwl4965_priv *priv, u32 mode)
 {
-       u32 final_mode = mode;
+       u32 uninitialized_var(final_mode);
        int rc;
-       struct iwl_powertable_cmd cmd;
+       struct iwl4965_powertable_cmd cmd;
 
        /* If on battery, set to 3,
-        * if plugged into AC power, set to CAM ("continuosly aware mode"),
+        * if plugged into AC power, set to CAM ("continuously aware mode"),
         * else user level */
        switch (mode) {
        case IWL_POWER_BATTERY:
@@ -2240,9 +2308,9 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
 
        cmd.keep_alive_beacons = 0;
 
-       iwl_update_power_cmd(priv, &cmd, final_mode);
+       iwl4965_update_power_cmd(priv, &cmd, final_mode);
 
-       rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
+       rc = iwl4965_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd);
 
        if (final_mode == IWL_POWER_MODE_CAM)
                clear_bit(STATUS_POWER_PMI, &priv->status);
@@ -2252,7 +2320,7 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode)
        return rc;
 }
 
-int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
+int iwl4965_is_network_packet(struct iwl4965_priv *priv, struct ieee80211_hdr *header)
 {
        /* Filter incoming packets to determine if they are targeted toward
         * this network, discarding packets coming from ourselves */
@@ -2282,7 +2350,7 @@ int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
 
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
-const char *iwl_get_tx_fail_reason(u32 status)
+static const char *iwl4965_get_tx_fail_reason(u32 status)
 {
        switch (status & TX_STATUS_MSK) {
        case TX_STATUS_SUCCESS:
@@ -2309,11 +2377,11 @@ const char *iwl_get_tx_fail_reason(u32 status)
 }
 
 /**
- * iwl_scan_cancel - Cancel any currently executing HW scan
+ * iwl4965_scan_cancel - Cancel any currently executing HW scan
  *
  * NOTE: priv->mutex is not required before calling this function
  */
-static int iwl_scan_cancel(struct iwl_priv *priv)
+static int iwl4965_scan_cancel(struct iwl4965_priv *priv)
 {
        if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
                clear_bit(STATUS_SCANNING, &priv->status);
@@ -2336,17 +2404,17 @@ static int iwl_scan_cancel(struct iwl_priv *priv)
 }
 
 /**
- * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
+ * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan
  * @ms: amount of time to wait (in milliseconds) for scan to abort
  *
  * NOTE: priv->mutex must be held before calling this function
  */
-static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
+static int iwl4965_scan_cancel_timeout(struct iwl4965_priv *priv, unsigned long ms)
 {
        unsigned long now = jiffies;
        int ret;
 
-       ret = iwl_scan_cancel(priv);
+       ret = iwl4965_scan_cancel(priv);
        if (ret && ms) {
                mutex_unlock(&priv->mutex);
                while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
@@ -2360,7 +2428,7 @@ static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
        return ret;
 }
 
-static void iwl_sequence_reset(struct iwl_priv *priv)
+static void iwl4965_sequence_reset(struct iwl4965_priv *priv)
 {
        /* Reset ieee stats */
 
@@ -2371,13 +2439,13 @@ static void iwl_sequence_reset(struct iwl_priv *priv)
        priv->last_frag_num = -1;
        priv->last_packet_time = 0;
 
-       iwl_scan_cancel(priv);
+       iwl4965_scan_cancel(priv);
 }
 
 #define MAX_UCODE_BEACON_INTERVAL      4096
 #define INTEL_CONN_LISTEN_INTERVAL     __constant_cpu_to_le16(0xA)
 
-static __le16 iwl_adjust_beacon_interval(u16 beacon_val)
+static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
 {
        u16 new_val = 0;
        u16 beacon_factor = 0;
@@ -2390,7 +2458,7 @@ static __le16 iwl_adjust_beacon_interval(u16 beacon_val)
        return cpu_to_le16(new_val);
 }
 
-static void iwl_setup_rxon_timing(struct iwl_priv *priv)
+static void iwl4965_setup_rxon_timing(struct iwl4965_priv *priv)
 {
        u64 interval_tm_unit;
        u64 tsf, result;
@@ -2420,14 +2488,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                        priv->rxon_timing.beacon_interval =
                                cpu_to_le16(beacon_int);
                        priv->rxon_timing.beacon_interval =
-                           iwl_adjust_beacon_interval(
+                           iwl4965_adjust_beacon_interval(
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
                }
 
                priv->rxon_timing.atim_window = 0;
        } else {
                priv->rxon_timing.beacon_interval =
-                       iwl_adjust_beacon_interval(conf->beacon_int);
+                       iwl4965_adjust_beacon_interval(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;
@@ -2446,14 +2514,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static int iwl_scan_initiate(struct iwl_priv *priv)
+static int iwl4965_scan_initiate(struct iwl4965_priv *priv)
 {
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
                IWL_ERROR("APs don't scan.\n");
                return 0;
        }
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl4965_is_ready_rf(priv)) {
                IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
                return -EIO;
        }
@@ -2480,9 +2548,9 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
        return 0;
 }
 
-static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
+static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt)
 {
-       struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
+       struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon;
 
        if (hw_decrypt)
                rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -2492,7 +2560,7 @@ static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt)
        return 0;
 }
 
-static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
+static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode)
 {
        if (phymode == MODE_IEEE80211A) {
                priv->staging_rxon.flags &=
@@ -2500,7 +2568,7 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
                      | RXON_FLG_CCK_MSK);
                priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
        } else {
-               /* Copied from iwl_bg_post_associate() */
+               /* Copied from iwl4965_bg_post_associate() */
                if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
                        priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
                else
@@ -2516,11 +2584,11 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode)
 }
 
 /*
- * initilize rxon structure with default values fromm eeprom
+ * initialize rxon structure with default values from eeprom
  */
-static void iwl_connection_init_rx_config(struct iwl_priv *priv)
+static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv)
 {
-       const struct iwl_channel_info *ch_info;
+       const struct iwl4965_channel_info *ch_info;
 
        memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
 
@@ -2557,7 +2625,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
                priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
 #endif
 
-       ch_info = iwl_get_channel_info(priv, priv->phymode,
+       ch_info = iwl4965_get_channel_info(priv, priv->phymode,
                                       le16_to_cpu(priv->staging_rxon.channel));
 
        if (!ch_info)
@@ -2577,7 +2645,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
        else
                priv->phymode = MODE_IEEE80211G;
 
-       iwl_set_flags_for_phymode(priv, priv->phymode);
+       iwl4965_set_flags_for_phymode(priv, priv->phymode);
 
        priv->staging_rxon.ofdm_basic_rates =
            (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -2593,15 +2661,12 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv)
        iwl4965_set_rxon_chain(priv);
 }
 
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
+static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode)
 {
-       if (!iwl_is_ready_rf(priv))
-               return -EAGAIN;
-
        if (mode == IEEE80211_IF_TYPE_IBSS) {
-               const struct iwl_channel_info *ch_info;
+               const struct iwl4965_channel_info *ch_info;
 
-               ch_info = iwl_get_channel_info(priv,
+               ch_info = iwl4965_get_channel_info(priv,
                        priv->phymode,
                        le16_to_cpu(priv->staging_rxon.channel));
 
@@ -2612,32 +2677,36 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode)
                }
        }
 
+       priv->iw_mode = mode;
+
+       iwl4965_connection_init_rx_config(priv);
+       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+
+       iwl4965_clear_stations_table(priv);
+
+       /* dont commit rxon if rf-kill is on*/
+       if (!iwl4965_is_ready_rf(priv))
+               return -EAGAIN;
+
        cancel_delayed_work(&priv->scan_check);
-       if (iwl_scan_cancel_timeout(priv, 100)) {
+       if (iwl4965_scan_cancel_timeout(priv, 100)) {
                IWL_WARNING("Aborted scan still in progress after 100ms\n");
                IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
                return -EAGAIN;
        }
 
-       priv->iw_mode = mode;
-
-       iwl_connection_init_rx_config(priv);
-       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
-       iwl_clear_stations_table(priv);
-
-       iwl_commit_rxon(priv);
+       iwl4965_commit_rxon(priv);
 
        return 0;
 }
 
-static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
+static void iwl4965_build_tx_cmd_hwcrypto(struct iwl4965_priv *priv,
                                      struct ieee80211_tx_control *ctl,
-                                     struct iwl_cmd *cmd,
+                                     struct iwl4965_cmd *cmd,
                                      struct sk_buff *skb_frag,
                                      int last_frag)
 {
-       struct iwl_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
+       struct iwl4965_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo;
 
        switch (keyinfo->alg) {
        case ALG_CCMP:
@@ -2680,8 +2749,8 @@ static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
 /*
  * handle build REPLY_TX command notification.
  */
-static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
-                                 struct iwl_cmd *cmd,
+static void iwl4965_build_tx_cmd_basic(struct iwl4965_priv *priv,
+                                 struct iwl4965_cmd *cmd,
                                  struct ieee80211_tx_control *ctrl,
                                  struct ieee80211_hdr *hdr,
                                  int is_unicast, u8 std_id)
@@ -2703,6 +2772,10 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
                tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
        }
 
+       if (ieee80211_is_back_request(fc))
+               tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
+
+
        cmd->cmd.tx.sta_id = std_id;
        if (ieee80211_get_morefrag(hdr))
                tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
@@ -2729,11 +2802,9 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
        if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
                if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
                    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
-                       cmd->cmd.tx.timeout.pm_frame_timeout =
-                               cpu_to_le16(3);
+                       cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
                else
-                       cmd->cmd.tx.timeout.pm_frame_timeout =
-                               cpu_to_le16(2);
+                       cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
        } else
                cmd->cmd.tx.timeout.pm_frame_timeout = 0;
 
@@ -2742,40 +2813,47 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv,
        cmd->cmd.tx.next_frame_len = 0;
 }
 
-static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+/**
+ * iwl4965_get_sta_id - Find station's index within station table
+ *
+ * If new IBSS station, create new entry in station table
+ */
+static int iwl4965_get_sta_id(struct iwl4965_priv *priv,
+                               struct ieee80211_hdr *hdr)
 {
        int sta_id;
        u16 fc = le16_to_cpu(hdr->frame_control);
        DECLARE_MAC_BUF(mac);
 
-       /* If this frame is broadcast or not data then use the broadcast
-        * station id */
+       /* 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_setting.bcast_sta_id;
 
        switch (priv->iw_mode) {
 
-       /* If this frame is part of a BSS network (we're a station), then
-        * we use the AP's station id */
+       /* 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 IEEE80211_IF_TYPE_STA:
                return IWL_AP_ID;
 
        /* If we are an AP, then find the station, or use BCAST */
        case IEEE80211_IF_TYPE_AP:
-               sta_id = iwl_hw_find_station(priv, hdr->addr1);
+               sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
                return priv->hw_setting.bcast_sta_id;
 
-       /* If this frame is part of a IBSS network, then we use the
-        * target specific station id */
+       /* If this frame is going out to an IBSS network, find the station,
+        * or create a new station table entry */
        case IEEE80211_IF_TYPE_IBSS:
-               sta_id = iwl_hw_find_station(priv, hdr->addr1);
+               sta_id = iwl4965_hw_find_station(priv, hdr->addr1);
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
 
-               sta_id = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
+               /* Create new station table entry */
+               sta_id = iwl4965_add_station_flags(priv, hdr->addr1,
+                                                  0, CMD_ASYNC, NULL);
 
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
@@ -2783,11 +2861,11 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                IWL_DEBUG_DROP("Station %s not in station map. "
                               "Defaulting to broadcast...\n",
                               print_mac(mac, hdr->addr1));
-               iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
+               iwl4965_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_setting.bcast_sta_id;
 
        default:
-               IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode);
+               IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
                return priv->hw_setting.bcast_sta_id;
        }
 }
@@ -2795,18 +2873,19 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
 /*
  * start REPLY_TX command process
  */
-static int iwl_tx_skb(struct iwl_priv *priv,
+static int iwl4965_tx_skb(struct iwl4965_priv *priv,
                      struct sk_buff *skb, struct ieee80211_tx_control *ctl)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_tfd_frame *tfd;
+       struct iwl4965_tfd_frame *tfd;
        u32 *control_flags;
        int txq_id = ctl->queue;
-       struct iwl_tx_queue *txq = NULL;
-       struct iwl_queue *q = NULL;
+       struct iwl4965_tx_queue *txq = NULL;
+       struct iwl4965_queue *q = NULL;
        dma_addr_t phys_addr;
        dma_addr_t txcmd_phys;
-       struct iwl_cmd *out_cmd = NULL;
+       dma_addr_t scratch_phys;
+       struct iwl4965_cmd *out_cmd = NULL;
        u16 len, idx, len_org;
        u8 id, hdr_len, unicast;
        u8 sta_id;
@@ -2818,13 +2897,13 @@ static int iwl_tx_skb(struct iwl_priv *priv,
        int rc;
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (iwl_is_rfkill(priv)) {
+       if (iwl4965_is_rfkill(priv)) {
                IWL_DEBUG_DROP("Dropping - RF KILL\n");
                goto drop_unlock;
        }
 
-       if (!priv->interface_id) {
-               IWL_DEBUG_DROP("Dropping - !priv->interface_id\n");
+       if (!priv->vif) {
+               IWL_DEBUG_DROP("Dropping - !priv->vif\n");
                goto drop_unlock;
        }
 
@@ -2838,7 +2917,7 @@ static int iwl_tx_skb(struct iwl_priv *priv,
 
        fc = le16_to_cpu(hdr->frame_control);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
        if (ieee80211_is_auth(fc))
                IWL_DEBUG_TX("Sending AUTH frame\n");
        else if (ieee80211_is_assoc_request(fc))
@@ -2847,16 +2926,19 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                IWL_DEBUG_TX("Sending REASSOC frame\n");
 #endif
 
-       if (!iwl_is_associated(priv) &&
+       /* drop all data frame if we are not associated */
+       if (!iwl4965_is_associated(priv) && !priv->assoc_id &&
            ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
-               IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
+               IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
                goto drop_unlock;
        }
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
        hdr_len = ieee80211_get_hdrlen(fc);
-       sta_id = iwl_get_sta_id(priv, hdr);
+
+       /* Find (or create) index into station table for destination station */
+       sta_id = iwl4965_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
                DECLARE_MAC_BUF(mac);
 
@@ -2876,40 +2958,62 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                        (hdr->seq_ctrl &
                                __constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
                seq_number += 0x10;
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
                /* aggregation is on for this <sta,tid> */
                if (ctl->flags & IEEE80211_TXCTL_HT_MPDU_AGG)
                        txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
        }
+
+       /* Descriptor for chosen Tx queue */
        txq = &priv->txq[txq_id];
        q = &txq->q;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       tfd = &txq->bd[q->first_empty];
+       /* Set up first empty TFD within this queue's circular TFD buffer */
+       tfd = &txq->bd[q->write_ptr];
        memset(tfd, 0, sizeof(*tfd));
        control_flags = (u32 *) tfd;
-       idx = get_cmd_index(q, q->first_empty, 0);
+       idx = get_cmd_index(q, q->write_ptr, 0);
 
-       memset(&(txq->txb[q->first_empty]), 0, sizeof(struct iwl_tx_info));
-       txq->txb[q->first_empty].skb[0] = skb;
-       memcpy(&(txq->txb[q->first_empty].status.control),
+       /* Set up driver data for this TFD */
+       memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info));
+       txq->txb[q->write_ptr].skb[0] = skb;
+       memcpy(&(txq->txb[q->write_ptr].status.control),
               ctl, sizeof(struct ieee80211_tx_control));
+
+       /* Set up first empty entry in queue's array of Tx/cmd buffers */
        out_cmd = &txq->cmd[idx];
        memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
        memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx));
+
+       /*
+        * Set up the Tx-command (not MAC!) header.
+        * Store the chosen Tx queue and TFD index within the sequence field;
+        * after Tx, uCode's Tx response will return this value so driver can
+        * locate the frame within the tx queue and do post-tx processing.
+        */
        out_cmd->hdr.cmd = REPLY_TX;
        out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
-                               INDEX_TO_SEQ(q->first_empty)));
-       /* copy frags header */
+                               INDEX_TO_SEQ(q->write_ptr)));
+
+       /* Copy MAC header from skb into command buffer */
        memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len);
 
-       /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */
+       /*
+        * Use the first empty entry in this queue's command buffer array
+        * to contain the Tx command and MAC header concatenated together
+        * (payload data will be in another buffer).
+        * Size of this varies, due to varying MAC header length.
+        * If end is not dword aligned, we'll have 2 extra bytes at the end
+        * of the MAC header (device reads on dword boundaries).
+        * We'll tell device about this padding later.
+        */
        len = priv->hw_setting.tx_cmd_len +
-               sizeof(struct iwl_cmd_header) + hdr_len;
+               sizeof(struct iwl4965_cmd_header) + hdr_len;
 
        len_org = len;
        len = (len + 3) & ~3;
@@ -2919,36 +3023,53 @@ static int iwl_tx_skb(struct iwl_priv *priv,
        else
                len_org = 0;
 
-       txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
-                    offsetof(struct iwl_cmd, hdr);
+       /* Physical address of this Tx command's header (not MAC header!),
+        * within command buffer array. */
+       txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl4965_cmd) * idx +
+                    offsetof(struct iwl4965_cmd, hdr);
 
-       iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
+       /* Add buffer containing Tx command and MAC(!) header to TFD's
+        * first entry */
+       iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);
 
        if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
-               iwl_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
+               iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0);
 
-       /* 802.11 null functions have no payload... */
+       /* Set up TFD's 2nd entry to point directly to remainder of skb,
+        * if any (802.11 null frames have no payload). */
        len = skb->len - hdr_len;
        if (len) {
                phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
                                           len, PCI_DMA_TODEVICE);
-               iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
+               iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len);
        }
 
+       /* Tell 4965 about any 2-byte padding after MAC header */
        if (len_org)
                out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
 
+       /* Total # bytes to be transmitted */
        len = (u16)skb->len;
        out_cmd->cmd.tx.len = cpu_to_le16(len);
 
        /* TODO need this for burst mode later on */
-       iwl_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
+       iwl4965_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id);
 
        /* set is_hcca to 0; it probably will never be implemented */
-       iwl_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
+       iwl4965_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0);
+
+       scratch_phys = txcmd_phys + sizeof(struct iwl4965_cmd_header) +
+               offsetof(struct iwl4965_tx_cmd, scratch);
+       out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys);
+       out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
+
+#ifdef CONFIG_IWL4965_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+       /* TODO: move this functionality to rate scaling */
+       iwl4965_tl_get_stats(priv, hdr);
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /*CONFIG_IWL4965_HT */
 
-       iwl4965_tx_cmd(priv, out_cmd, sta_id, txcmd_phys,
-                      hdr, hdr_len, ctl, NULL);
 
        if (!ieee80211_get_morefrag(hdr)) {
                txq->need_update = 1;
@@ -2961,27 +3082,29 @@ static int iwl_tx_skb(struct iwl_priv *priv,
                txq->need_update = 0;
        }
 
-       iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
+       iwl4965_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload,
                           sizeof(out_cmd->cmd.tx));
 
-       iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
+       iwl4965_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
                           ieee80211_get_hdrlen(fc));
 
+       /* Set up entry for this TFD in Tx byte-count array */
        iwl4965_tx_queue_update_wr_ptr(priv, txq, len);
 
-       q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd);
-       rc = iwl_tx_queue_update_write_ptr(priv, txq);
+       /* Tell device the write index *just past* this latest filled TFD */
+       q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd);
+       rc = iwl4965_tx_queue_update_write_ptr(priv, txq);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (rc)
                return rc;
 
-       if ((iwl_queue_space(q) < q->high_mark)
+       if ((iwl4965_queue_space(q) < q->high_mark)
            && priv->mac80211_registered) {
                if (wait_write_ptr) {
                        spin_lock_irqsave(&priv->lock, flags);
                        txq->need_update = 1;
-                       iwl_tx_queue_update_write_ptr(priv, txq);
+                       iwl4965_tx_queue_update_write_ptr(priv, txq);
                        spin_unlock_irqrestore(&priv->lock, flags);
                }
 
@@ -2996,13 +3119,13 @@ drop:
        return -1;
 }
 
-static void iwl_set_rate(struct iwl_priv *priv)
+static void iwl4965_set_rate(struct iwl4965_priv *priv)
 {
        const struct ieee80211_hw_mode *hw = NULL;
        struct ieee80211_rate *rate;
        int i;
 
-       hw = iwl_get_hw_mode(priv, priv->phymode);
+       hw = iwl4965_get_hw_mode(priv, priv->phymode);
        if (!hw) {
                IWL_ERROR("Failed to set rate: unable to get hw mode\n");
                return;
@@ -3020,7 +3143,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                if ((rate->val < IWL_RATE_COUNT) &&
                    (rate->flags & IEEE80211_RATE_SUPPORTED)) {
                        IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n",
-                                      rate->val, iwl_rates[rate->val].plcp,
+                                      rate->val, iwl4965_rates[rate->val].plcp,
                                       (rate->flags & IEEE80211_RATE_BASIC) ?
                                       "*" : "");
                        priv->active_rate |= (1 << rate->val);
@@ -3028,7 +3151,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                                priv->active_rate_basic |= (1 << rate->val);
                } else
                        IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n",
-                                      rate->val, iwl_rates[rate->val].plcp);
+                                      rate->val, iwl4965_rates[rate->val].plcp);
        }
 
        IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
@@ -3057,7 +3180,7 @@ static void iwl_set_rate(struct iwl_priv *priv)
                   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
 
-static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
+static void iwl4965_radio_kill_sw(struct iwl4965_priv *priv, int disable_radio)
 {
        unsigned long flags;
 
@@ -3068,21 +3191,21 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
                          disable_radio ? "OFF" : "ON");
 
        if (disable_radio) {
-               iwl_scan_cancel(priv);
+               iwl4965_scan_cancel(priv);
                /* FIXME: This is a workaround for AP */
                if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
                        spin_lock_irqsave(&priv->lock, flags);
-                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_SW_BIT_RFKILL);
                        spin_unlock_irqrestore(&priv->lock, flags);
-                       iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
+                       iwl4965_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
                        set_bit(STATUS_RF_KILL_SW, &priv->status);
                }
                return;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        clear_bit(STATUS_RF_KILL_SW, &priv->status);
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -3091,9 +3214,9 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
        msleep(10);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_read32(priv, CSR_UCODE_DRV_GP1);
-       if (!iwl_grab_restricted_access(priv))
-               iwl_release_restricted_access(priv);
+       iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
+       if (!iwl4965_grab_nic_access(priv))
+               iwl4965_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
@@ -3106,7 +3229,7 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
        return;
 }
 
-void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
+void iwl4965_set_decrypted_flag(struct iwl4965_priv *priv, struct sk_buff *skb,
                            u32 decrypt_res, struct ieee80211_rx_status *stats)
 {
        u16 fc =
@@ -3138,97 +3261,10 @@ void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
        }
 }
 
-void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb,
-                                   void *data, short len,
-                                   struct ieee80211_rx_status *stats,
-                                   u16 phy_flags)
-{
-       struct iwl_rt_rx_hdr *iwl_rt;
-
-       /* First cache any information we need before we overwrite
-        * the information provided in the skb from the hardware */
-       s8 signal = stats->ssi;
-       s8 noise = 0;
-       int rate = stats->rate;
-       u64 tsf = stats->mactime;
-       __le16 phy_flags_hw = cpu_to_le16(phy_flags);
-
-       /* We received data from the HW, so stop the watchdog */
-       if (len > IWL_RX_BUF_SIZE - sizeof(*iwl_rt)) {
-               IWL_DEBUG_DROP("Dropping too large packet in monitor\n");
-               return;
-       }
-
-       /* copy the frame data to write after where the radiotap header goes */
-       iwl_rt = (void *)rxb->skb->data;
-       memmove(iwl_rt->payload, data, len);
-
-       iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
-       iwl_rt->rt_hdr.it_pad = 0; /* always good to zero */
-
-       /* total header + data */
-       iwl_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl_rt));
-
-       /* Set the size of the skb to the size of the frame */
-       skb_put(rxb->skb, sizeof(*iwl_rt) + len);
-
-       /* Big bitfield of all the fields we provide in radiotap */
-       iwl_rt->rt_hdr.it_present =
-           cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
-                       (1 << IEEE80211_RADIOTAP_FLAGS) |
-                       (1 << IEEE80211_RADIOTAP_RATE) |
-                       (1 << IEEE80211_RADIOTAP_CHANNEL) |
-                       (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
-                       (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
-                       (1 << IEEE80211_RADIOTAP_ANTENNA));
-
-       /* Zero the flags, we'll add to them as we go */
-       iwl_rt->rt_flags = 0;
-
-       iwl_rt->rt_tsf = cpu_to_le64(tsf);
-
-       /* Convert to dBm */
-       iwl_rt->rt_dbmsignal = signal;
-       iwl_rt->rt_dbmnoise = noise;
-
-       /* Convert the channel frequency and set the flags */
-       iwl_rt->rt_channelMHz = cpu_to_le16(stats->freq);
-       if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
-       else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
-       else    /* 802.11g */
-               iwl_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ));
-
-       rate = iwl_rate_index_from_plcp(rate);
-       if (rate == -1)
-               iwl_rt->rt_rate = 0;
-       else
-               iwl_rt->rt_rate = iwl_rates[rate].ieee;
-
-       /* antenna number */
-       iwl_rt->rt_antenna =
-               le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
-
-       /* set the preamble flag if we have it */
-       if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
-               iwl_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
-
-       IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
-
-       stats->flag |= RX_FLAG_RADIOTAP;
-       ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
-       rxb->skb = NULL;
-}
-
 
 #define IWL_PACKET_RETRY_TIME HZ
 
-int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
+int iwl4965_is_duplicate_packet(struct iwl4965_priv *priv, struct ieee80211_hdr *header)
 {
        u16 sc = le16_to_cpu(header->seq_ctrl);
        u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
@@ -3239,29 +3275,26 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
        switch (priv->iw_mode) {
        case IEEE80211_IF_TYPE_IBSS:{
                struct list_head *p;
-               struct iwl_ibss_seq *entry = NULL;
+               struct iwl4965_ibss_seq *entry = NULL;
                u8 *mac = header->addr2;
                int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
 
                __list_for_each(p, &priv->ibss_mac_hash[index]) {
-                       entry =
-                               list_entry(p, struct iwl_ibss_seq, list);
+                       entry = list_entry(p, struct iwl4965_ibss_seq, list);
                        if (!compare_ether_addr(entry->mac, mac))
                                break;
                }
                if (p == &priv->ibss_mac_hash[index]) {
                        entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
                        if (!entry) {
-                               IWL_ERROR
-                                       ("Cannot malloc new mac entry\n");
+                               IWL_ERROR("Cannot malloc new mac entry\n");
                                return 0;
                        }
                        memcpy(entry->mac, mac, ETH_ALEN);
                        entry->seq_num = seq;
                        entry->frag_num = frag;
                        entry->packet_time = jiffies;
-                       list_add(&entry->list,
-                                &priv->ibss_mac_hash[index]);
+                       list_add(&entry->list, &priv->ibss_mac_hash[index]);
                        return 0;
                }
                last_seq = &entry->seq_num;
@@ -3295,7 +3328,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
        return 1;
 }
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
 
 #include "iwl-spectrum.h"
 
@@ -3310,7 +3343,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
  * the lower 3 bytes is the time in usec within one beacon interval
  */
 
-static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
+static u32 iwl4965_usecs_to_beacons(u32 usec, u32 beacon_interval)
 {
        u32 quot;
        u32 rem;
@@ -3329,7 +3362,7 @@ static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
  * the same as HW timer counter counting down
  */
 
-static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
+static __le32 iwl4965_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
 {
        u32 base_low = base & BEACON_TIME_MASK_LOW;
        u32 addon_low = addon & BEACON_TIME_MASK_LOW;
@@ -3348,13 +3381,13 @@ static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
        return cpu_to_le32(res);
 }
 
-static int iwl_get_measurement(struct iwl_priv *priv,
+static int iwl4965_get_measurement(struct iwl4965_priv *priv,
                               struct ieee80211_measurement_params *params,
                               u8 type)
 {
-       struct iwl_spectrum_cmd spectrum;
-       struct iwl_rx_packet *res;
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_spectrum_cmd spectrum;
+       struct iwl4965_rx_packet *res;
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
                .data = (void *)&spectrum,
                .meta.flags = CMD_WANT_SKB,
@@ -3364,9 +3397,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
        int spectrum_resp_status;
        int duration = le16_to_cpu(params->duration);
 
-       if (iwl_is_associated(priv))
+       if (iwl4965_is_associated(priv))
                add_time =
-                   iwl_usecs_to_beacons(
+                   iwl4965_usecs_to_beacons(
                        le64_to_cpu(params->start_time) - priv->last_tsf,
                        le16_to_cpu(priv->rxon_timing.beacon_interval));
 
@@ -3379,9 +3412,9 @@ static int iwl_get_measurement(struct iwl_priv *priv,
        cmd.len = sizeof(spectrum);
        spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
 
-       if (iwl_is_associated(priv))
+       if (iwl4965_is_associated(priv))
                spectrum.start_time =
-                   iwl_add_beacon_time(priv->last_beacon_time,
+                   iwl4965_add_beacon_time(priv->last_beacon_time,
                                add_time,
                                le16_to_cpu(priv->rxon_timing.beacon_interval));
        else
@@ -3394,11 +3427,11 @@ static int iwl_get_measurement(struct iwl_priv *priv,
                spectrum.flags |= RXON_FLG_BAND_24G_MSK |
                    RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
 
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl4965_send_cmd_sync(priv, &cmd);
        if (rc)
                return rc;
 
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data;
        if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
                rc = -EIO;
@@ -3428,8 +3461,8 @@ static int iwl_get_measurement(struct iwl_priv *priv,
 }
 #endif
 
-static void iwl_txstatus_to_ieee(struct iwl_priv *priv,
-                                struct iwl_tx_info *tx_sta)
+static void iwl4965_txstatus_to_ieee(struct iwl4965_priv *priv,
+                                struct iwl4965_tx_info *tx_sta)
 {
 
        tx_sta->status.ack_signal = 0;
@@ -3448,41 +3481,41 @@ static void iwl_txstatus_to_ieee(struct iwl_priv *priv,
 }
 
 /**
- * iwl_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC.
+ * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
  *
- * When FW advances 'R' index, all entries between old and
- * new 'R' index need to be reclaimed. As result, some free space
- * forms. If there is enough free space (> low mark), wake Tx queue.
+ * When FW advances 'R' index, all entries between old and new 'R' index
+ * need to be reclaimed. As result, some free space forms.  If there is
+ * enough free space (> low mark), wake the stack that feeds us.
  */
-int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
+int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index)
 {
-       struct iwl_tx_queue *txq = &priv->txq[txq_id];
-       struct iwl_queue *q = &txq->q;
+       struct iwl4965_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl4965_queue *q = &txq->q;
        int nfreed = 0;
 
        if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
                          "is out of range [0-%d] %d %d.\n", txq_id,
-                         index, q->n_bd, q->first_empty, q->last_used);
+                         index, q->n_bd, q->write_ptr, q->read_ptr);
                return 0;
        }
 
-       for (index = iwl_queue_inc_wrap(index, q->n_bd);
-               q->last_used != index;
-               q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) {
+       for (index = iwl4965_queue_inc_wrap(index, q->n_bd);
+               q->read_ptr != index;
+               q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) {
                if (txq_id != IWL_CMD_QUEUE_NUM) {
-                       iwl_txstatus_to_ieee(priv,
-                                       &(txq->txb[txq->q.last_used]));
-                       iwl_hw_txq_free_tfd(priv, txq);
+                       iwl4965_txstatus_to_ieee(priv,
+                                       &(txq->txb[txq->q.read_ptr]));
+                       iwl4965_hw_txq_free_tfd(priv, txq);
                } else if (nfreed > 1) {
                        IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
-                                       q->first_empty, q->last_used);
+                                       q->write_ptr, q->read_ptr);
                        queue_work(priv->workqueue, &priv->restart);
                }
                nfreed++;
        }
 
-       if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+       if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) &&
                        (txq_id != IWL_CMD_QUEUE_NUM) &&
                        priv->mac80211_registered)
                ieee80211_wake_queue(priv->hw, txq_id);
@@ -3491,7 +3524,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
        return nfreed;
 }
 
-static int iwl_is_tx_success(u32 status)
+static int iwl4965_is_tx_success(u32 status)
 {
        status &= TX_STATUS_MSK;
        return (status == TX_STATUS_SUCCESS)
@@ -3503,22 +3536,22 @@ static int iwl_is_tx_success(u32 status)
  * Generic RX handler implementations
  *
  ******************************************************************************/
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
 
-static inline int iwl_get_ra_sta_id(struct iwl_priv *priv,
+static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv,
                                    struct ieee80211_hdr *hdr)
 {
        if (priv->iw_mode == IEEE80211_IF_TYPE_STA)
                return IWL_AP_ID;
        else {
                u8 *da = ieee80211_get_DA(hdr);
-               return iwl_hw_find_station(priv, da);
+               return iwl4965_hw_find_station(priv, da);
        }
 }
 
-static struct ieee80211_hdr *iwl_tx_queue_get_hdr(
-       struct iwl_priv *priv, int txq_id, int idx)
+static struct ieee80211_hdr *iwl4965_tx_queue_get_hdr(
+       struct iwl4965_priv *priv, int txq_id, int idx)
 {
        if (priv->txq[txq_id].txb[idx].skb[0])
                return (struct ieee80211_hdr *)priv->txq[txq_id].
@@ -3526,16 +3559,20 @@ static struct ieee80211_hdr *iwl_tx_queue_get_hdr(
        return NULL;
 }
 
-static inline u32 iwl_get_scd_ssn(struct iwl_tx_resp *tx_resp)
+static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
 {
        __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
                                tx_resp->frame_count);
        return le32_to_cpu(*scd_ssn) & MAX_SN;
 
 }
-static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
-                                     struct iwl_ht_agg *agg,
-                                     struct iwl_tx_resp *tx_resp,
+
+/**
+ * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue
+ */
+static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
+                                     struct iwl4965_ht_agg *agg,
+                                     struct iwl4965_tx_resp *tx_resp,
                                      u16 start_idx)
 {
        u32 status;
@@ -3547,15 +3584,17 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
        u16 seq;
 
        if (agg->wait_for_ba)
-               IWL_DEBUG_TX_REPLY("got tx repsons w/o back\n");
+               IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
 
        agg->frame_count = tx_resp->frame_count;
        agg->start_idx = start_idx;
        agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
        agg->bitmap0 = agg->bitmap1 = 0;
 
+       /* # frames attempted by Tx command */
        if (agg->frame_count == 1) {
-               struct iwl_tx_queue *txq ;
+               /* Only one frame was attempted; no block-ack will arrive */
+               struct iwl4965_tx_queue *txq ;
                status = le32_to_cpu(frame_status[0]);
 
                txq_id = agg->txq_id;
@@ -3564,28 +3603,30 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d \n",
                                   agg->frame_count, agg->start_idx);
 
-               tx_status = &(priv->txq[txq_id].txb[txq->q.last_used].status);
+               tx_status = &(priv->txq[txq_id].txb[txq->q.read_ptr].status);
                tx_status->retry_count = tx_resp->failure_frame;
                tx_status->queue_number = status & 0xff;
                tx_status->queue_length = tx_resp->bt_kill_count;
                tx_status->queue_length |= tx_resp->failure_rts;
 
-               tx_status->flags = iwl_is_tx_success(status)?
+               tx_status->flags = iwl4965_is_tx_success(status)?
                        IEEE80211_TX_STATUS_ACK : 0;
                tx_status->control.tx_rate =
-                               iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags);
+                               iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags);
                /* FIXME: code repetition end */
 
                IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
                                    status & 0xff, tx_resp->failure_frame);
                IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
-                               iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags));
+                               iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
 
                agg->wait_for_ba = 0;
        } else {
+               /* Two or more frames were attempted; expect block-ack */
                u64 bitmap = 0;
                int start = agg->start_idx;
 
+               /* Construct bit-map of pending frames within Tx window */
                for (i = 0; i < agg->frame_count; i++) {
                        u16 sc;
                        status = le32_to_cpu(frame_status[i]);
@@ -3600,7 +3641,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
                        IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
                                           agg->frame_count, txq_id, idx);
 
-                       hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
+                       hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, idx);
 
                        sc = le16_to_cpu(hdr->seq_ctrl);
                        if (idx != (SEQ_TO_SN(sc) & 0xff)) {
@@ -3649,19 +3690,22 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
 #endif
 #endif
 
-static void iwl_rx_reply_tx(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb)
+/**
+ * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
+ */
+static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
+                           struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
-       struct iwl_tx_queue *txq = &priv->txq[txq_id];
+       struct iwl4965_tx_queue *txq = &priv->txq[txq_id];
        struct ieee80211_tx_status *tx_status;
-       struct iwl_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+       struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
        u32  status = le32_to_cpu(tx_resp->status);
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        int tid, sta_id;
 #endif
 #endif
@@ -3669,18 +3713,18 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv,
        if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
                IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
                          "is out of range [0-%d] %d %d\n", txq_id,
-                         index, txq->q.n_bd, txq->q.first_empty,
-                         txq->q.last_used);
+                         index, txq->q.n_bd, txq->q.write_ptr,
+                         txq->q.read_ptr);
                return;
        }
 
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        if (txq->sched_retry) {
-               const u32 scd_ssn = iwl_get_scd_ssn(tx_resp);
+               const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
                struct ieee80211_hdr *hdr =
-                       iwl_tx_queue_get_hdr(priv, txq_id, index);
-               struct iwl_ht_agg *agg = NULL;
+                       iwl4965_tx_queue_get_hdr(priv, txq_id, index);
+               struct iwl4965_ht_agg *agg = NULL;
                __le16 *qc = ieee80211_get_qos_ctrl(hdr);
 
                if (qc == NULL) {
@@ -3690,7 +3734,7 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv,
 
                tid = le16_to_cpu(*qc) & 0xf;
 
-               sta_id = iwl_get_ra_sta_id(priv, hdr);
+               sta_id = iwl4965_get_ra_sta_id(priv, hdr);
                if (unlikely(sta_id == IWL_INVALID_STATION)) {
                        IWL_ERROR("Station not known for\n");
                        return;
@@ -3701,20 +3745,20 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv,
                iwl4965_tx_status_reply_tx(priv, agg, tx_resp, index);
 
                if ((tx_resp->frame_count == 1) &&
-                   !iwl_is_tx_success(status)) {
+                   !iwl4965_is_tx_success(status)) {
                        /* TODO: send BAR */
                }
 
-               if ((txq->q.last_used != (scd_ssn & 0xff))) {
-                       index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+               if ((txq->q.read_ptr != (scd_ssn & 0xff))) {
+                       index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
                        IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
-                       iwl_tx_queue_reclaim(priv, txq_id, index);
+                       iwl4965_tx_queue_reclaim(priv, txq_id, index);
                }
        } else {
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
-       tx_status = &(txq->txb[txq->q.last_used].status);
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
+       tx_status = &(txq->txb[txq->q.read_ptr].status);
 
        tx_status->retry_count = tx_resp->failure_frame;
        tx_status->queue_number = status;
@@ -3722,35 +3766,35 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv,
        tx_status->queue_length |= tx_resp->failure_rts;
 
        tx_status->flags =
-           iwl_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
+           iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
 
        tx_status->control.tx_rate =
-               iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags);
+               iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags);
 
        IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
-                    "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
+                    "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status),
                     status, le32_to_cpu(tx_resp->rate_n_flags),
                     tx_resp->failure_frame);
 
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        if (index != -1)
-               iwl_tx_queue_reclaim(priv, txq_id, index);
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+               iwl4965_tx_queue_reclaim(priv, txq_id, index);
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
        }
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERROR("TODO:  Implement Tx ABORT REQUIRED!!!\n");
 }
 
 
-static void iwl_rx_reply_alive(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_alive(struct iwl4965_priv *priv,
+                              struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_alive_resp *palive;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_alive_resp *palive;
        struct delayed_work *pwork;
 
        palive = &pkt->u.alive_frame;
@@ -3764,12 +3808,12 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
                IWL_DEBUG_INFO("Initialization Alive received.\n");
                memcpy(&priv->card_alive_init,
                       &pkt->u.alive_frame,
-                      sizeof(struct iwl_init_alive_resp));
+                      sizeof(struct iwl4965_init_alive_resp));
                pwork = &priv->init_alive_start;
        } else {
                IWL_DEBUG_INFO("Runtime Alive received.\n");
                memcpy(&priv->card_alive, &pkt->u.alive_frame,
-                      sizeof(struct iwl_alive_resp));
+                      sizeof(struct iwl4965_alive_resp));
                pwork = &priv->alive_start;
        }
 
@@ -3782,19 +3826,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
                IWL_WARNING("uCode did not respond OK.\n");
 }
 
-static void iwl_rx_reply_add_sta(struct iwl_priv *priv,
-                                struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_add_sta(struct iwl4965_priv *priv,
+                                struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
 
        IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status);
        return;
 }
 
-static void iwl_rx_reply_error(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_error(struct iwl4965_priv *priv,
+                              struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
 
        IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) "
                "seq 0x%04X ser 0x%08X\n",
@@ -3807,23 +3851,23 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
 
 #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
 
-static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_csa(struct iwl4965_priv *priv, struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
-       struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon;
+       struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif);
        IWL_DEBUG_11H("CSA notif: channel %d, status %d\n",
                      le16_to_cpu(csa->channel), le32_to_cpu(csa->status));
        rxon->channel = csa->channel;
        priv->staging_rxon.channel = csa->channel;
 }
 
-static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_spectrum_measure_notif(struct iwl4965_priv *priv,
+                                         struct iwl4965_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
 
        if (!report->state) {
                IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO,
@@ -3836,35 +3880,35 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
 #endif
 }
 
-static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_pm_sleep_notif(struct iwl4965_priv *priv,
+                                 struct iwl4965_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+#ifdef CONFIG_IWL4965_DEBUG
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif);
        IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
 #endif
 }
 
-static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_pm_debug_statistics_notif(struct iwl4965_priv *priv,
+                                            struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        IWL_DEBUG_RADIO("Dumping %d bytes of unhandled "
                        "notification for %s:\n",
                        le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+       iwl4965_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
 }
 
-static void iwl_bg_beacon_update(struct work_struct *work)
+static void iwl4965_bg_beacon_update(struct work_struct *work)
 {
-       struct iwl_priv *priv =
-               container_of(work, struct iwl_priv, beacon_update);
+       struct iwl4965_priv *priv =
+               container_of(work, struct iwl4965_priv, beacon_update);
        struct sk_buff *beacon;
 
        /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
-       beacon = ieee80211_beacon_get(priv->hw, priv->interface_id, NULL);
+       beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL);
 
        if (!beacon) {
                IWL_ERROR("update beacon failed\n");
@@ -3879,16 +3923,16 @@ static void iwl_bg_beacon_update(struct work_struct *work)
        priv->ibss_beacon = beacon;
        mutex_unlock(&priv->mutex);
 
-       iwl_send_beacon_cmd(priv);
+       iwl4965_send_beacon_cmd(priv);
 }
 
-static void iwl_rx_beacon_notif(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_beacon_notif(struct iwl4965_priv *priv,
+                               struct iwl4965_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_beacon_notif *beacon = &(pkt->u.beacon_status);
-       u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
+#ifdef CONFIG_IWL4965_DEBUG
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);
+       u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
 
        IWL_DEBUG_RX("beacon status %x retries %d iss %d "
                "tsf %d %d rate %d\n",
@@ -3905,25 +3949,25 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
 }
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl_rx_reply_scan(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_reply_scan(struct iwl4965_priv *priv,
+                             struct iwl4965_rx_mem_buffer *rxb)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanreq_notification *notif =
-           (struct iwl_scanreq_notification *)pkt->u.raw;
+#ifdef CONFIG_IWL4965_DEBUG
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_scanreq_notification *notif =
+           (struct iwl4965_scanreq_notification *)pkt->u.raw;
 
        IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
 #endif
 }
 
 /* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_scan_start_notif(struct iwl4965_priv *priv,
+                                   struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanstart_notification *notif =
-           (struct iwl_scanstart_notification *)pkt->u.raw;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_scanstart_notification *notif =
+           (struct iwl4965_scanstart_notification *)pkt->u.raw;
        priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
        IWL_DEBUG_SCAN("Scan start: "
                       "%d [802.11%s] "
@@ -3935,12 +3979,12 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
 }
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_scan_results_notif(struct iwl4965_priv *priv,
+                                     struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scanresults_notification *notif =
-           (struct iwl_scanresults_notification *)pkt->u.raw;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_scanresults_notification *notif =
+           (struct iwl4965_scanresults_notification *)pkt->u.raw;
 
        IWL_DEBUG_SCAN("Scan ch.res: "
                       "%d [802.11%s] "
@@ -3956,14 +4000,15 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
                                        (priv->last_scan_jiffies, jiffies)));
 
        priv->last_scan_jiffies = jiffies;
+       priv->next_scan_jiffies = 0;
 }
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv,
+                                      struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
-       struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
 
        IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
                       scan_notif->scanned_channels,
@@ -3998,6 +4043,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
        }
 
        priv->last_scan_jiffies = jiffies;
+       priv->next_scan_jiffies = 0;
        IWL_DEBUG_INFO("Setting scan to off\n");
 
        clear_bit(STATUS_SCANNING, &priv->status);
@@ -4016,10 +4062,10 @@ reschedule:
 
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
-static void iwl_rx_card_state_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_rx_card_state_notif(struct iwl4965_priv *priv,
+                                   struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
        unsigned long status = priv->status;
 
@@ -4030,35 +4076,35 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
        if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
                     RF_CARD_DISABLED)) {
 
-               iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+               iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
                            CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-               if (!iwl_grab_restricted_access(priv)) {
-                       iwl_write_restricted(
+               if (!iwl4965_grab_nic_access(priv)) {
+                       iwl4965_write_direct32(
                                priv, HBUS_TARG_MBX_C,
                                HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
-                       iwl_release_restricted_access(priv);
+                       iwl4965_release_nic_access(priv);
                }
 
                if (!(flags & RXON_CARD_DISABLED)) {
-                       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-                       if (!iwl_grab_restricted_access(priv)) {
-                               iwl_write_restricted(
+                       if (!iwl4965_grab_nic_access(priv)) {
+                               iwl4965_write_direct32(
                                        priv, HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
-                               iwl_release_restricted_access(priv);
+                               iwl4965_release_nic_access(priv);
                        }
                }
 
                if (flags & RF_CARD_DISABLED) {
-                       iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
+                       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
-                       iwl_read32(priv, CSR_UCODE_DRV_GP1);
-                       if (!iwl_grab_restricted_access(priv))
-                               iwl_release_restricted_access(priv);
+                       iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
+                       if (!iwl4965_grab_nic_access(priv))
+                               iwl4965_release_nic_access(priv);
                }
        }
 
@@ -4074,7 +4120,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                clear_bit(STATUS_RF_KILL_SW, &priv->status);
 
        if (!(flags & RXON_CARD_DISABLED))
-               iwl_scan_cancel(priv);
+               iwl4965_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
             test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -4086,7 +4132,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
 }
 
 /**
- * iwl_setup_rx_handlers - Initialize Rx handler callbacks
+ * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
  *
  * Setup the RX handlers for each of the reply types sent from the uCode
  * to the host.
@@ -4094,61 +4140,58 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
  * This function chains into the hardware specific files for them to setup
  * any hardware specific handlers as well.
  */
-static void iwl_setup_rx_handlers(struct iwl_priv *priv)
+static void iwl4965_setup_rx_handlers(struct iwl4965_priv *priv)
 {
-       priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
-       priv->rx_handlers[REPLY_ADD_STA] = iwl_rx_reply_add_sta;
-       priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
-       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
+       priv->rx_handlers[REPLY_ALIVE] = iwl4965_rx_reply_alive;
+       priv->rx_handlers[REPLY_ADD_STA] = iwl4965_rx_reply_add_sta;
+       priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error;
+       priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa;
        priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
-           iwl_rx_spectrum_measure_notif;
-       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
+           iwl4965_rx_spectrum_measure_notif;
+       priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl4965_rx_pm_sleep_notif;
        priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
-           iwl_rx_pm_debug_statistics_notif;
-       priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif;
-
-       /* NOTE:  iwl_rx_statistics is different based on whether
-        * the build is for the 3945 or the 4965.  See the
-        * corresponding implementation in iwl-XXXX.c
-        *
-        * The same handler is used for both the REPLY to a
-        * discrete statistics request from the host as well as
-        * for the periodic statistics notification from the uCode
+           iwl4965_rx_pm_debug_statistics_notif;
+       priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif;
+
+       /*
+        * The same handler is used for both the REPLY to a discrete
+        * statistics request from the host as well as for the periodic
+        * statistics notifications (after received beacons) from the uCode.
         */
-       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_hw_rx_statistics;
-       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_hw_rx_statistics;
+       priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics;
+       priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics;
 
-       priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan;
-       priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif;
+       priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan;
+       priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif;
        priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
-           iwl_rx_scan_results_notif;
+           iwl4965_rx_scan_results_notif;
        priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
-           iwl_rx_scan_complete_notif;
-       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif;
-       priv->rx_handlers[REPLY_TX] = iwl_rx_reply_tx;
+           iwl4965_rx_scan_complete_notif;
+       priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;
+       priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
 
-       /* Setup hardware specific Rx handlers */
-       iwl_hw_rx_handler_setup(priv);
+       /* Set up hardware specific Rx handlers */
+       iwl4965_hw_rx_handler_setup(priv);
 }
 
 /**
- * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
+ * iwl4965_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
  * @rxb: Rx buffer to reclaim
  *
  * If an Rx buffer has an async callback associated with it the callback
  * will be executed.  The attached skb (if present) will only be freed
  * if the callback returns 1
  */
-static void iwl_tx_cmd_complete(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static void iwl4965_tx_cmd_complete(struct iwl4965_priv *priv,
+                               struct iwl4965_rx_mem_buffer *rxb)
 {
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
        int txq_id = SEQ_TO_QUEUE(sequence);
        int index = SEQ_TO_INDEX(sequence);
        int huge = sequence & SEQ_HUGE_FRAME;
        int cmd_index;
-       struct iwl_cmd *cmd;
+       struct iwl4965_cmd *cmd;
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -4169,7 +4212,7 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
                   !cmd->meta.u.callback(priv, cmd, rxb->skb))
                rxb->skb = NULL;
 
-       iwl_tx_queue_reclaim(priv, txq_id, index);
+       iwl4965_tx_queue_reclaim(priv, txq_id, index);
 
        if (!(cmd->meta.flags & CMD_ASYNC)) {
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -4181,9 +4224,11 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
 /*
  * Rx theory of operation
  *
- * The host allocates 32 DMA target addresses and passes the host address
- * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
- * 0 to 31
+ * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs),
+ * each of which point to Receive Buffers to be filled by 4965.  These get
+ * used not only for Rx frames, but for any command response or notification
+ * from the 4965.  The driver and 4965 manage the Rx buffers by means
+ * of indexes into the circular buffer.
  *
  * Rx Queue Indexes
  * The host/firmware share two index registers for managing the Rx buffers.
@@ -4199,10 +4244,10 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  * The queue is empty (no good data) if WRITE = READ - 1, and is full if
  * WRITE = READ.
  *
- * During initialization the host sets up the READ queue position to the first
+ * During initialization, the host sets up the READ queue position to the first
  * INDEX position, and WRITE to the last (READ - 1 wrapped)
  *
- * When the firmware places a packet in a buffer it will advance the READ index
+ * When the firmware places a packet in a buffer, it will advance the READ index
  * and fire the RX interrupt.  The driver can then query the READ index and
  * process as many packets as possible, moving the WRITE index forward as it
  * resets the Rx queue buffers with new memory.
@@ -4210,8 +4255,8 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  * The management in the driver is as follows:
  * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free.  When
  *   iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled
- *   to replensish the iwl->rxq->rx_free.
- * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the
+ *   to replenish the iwl->rxq->rx_free.
+ * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the
  *   iwl->rxq is replenished and the READ INDEX is updated (updating the
  *   'processed' and 'read' driver indexes as well)
  * + A received packet is processed and handed to the kernel network stack,
@@ -4224,28 +4269,28 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv,
  *
  * Driver sequence:
  *
- * iwl_rx_queue_alloc()       Allocates rx_free
- * iwl_rx_replenish()         Replenishes rx_free list from rx_used, and calls
- *                            iwl_rx_queue_restock
- * iwl_rx_queue_restock()     Moves available buffers from rx_free into Rx
+ * iwl4965_rx_queue_alloc()   Allocates rx_free
+ * iwl4965_rx_replenish()     Replenishes rx_free list from rx_used, and calls
+ *                            iwl4965_rx_queue_restock
+ * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx
  *                            queue, updates firmware pointers, and updates
  *                            the WRITE index.  If insufficient rx_free buffers
- *                            are available, schedules iwl_rx_replenish
+ *                            are available, schedules iwl4965_rx_replenish
  *
  * -- enable interrupts --
- * ISR - iwl_rx()             Detach iwl_rx_mem_buffers from pool up to the
+ * ISR - iwl4965_rx()         Detach iwl4965_rx_mem_buffers from pool up to the
  *                            READ INDEX, detaching the SKB from the pool.
  *                            Moves the packet buffer from queue to rx_used.
- *                            Calls iwl_rx_queue_restock to refill any empty
+ *                            Calls iwl4965_rx_queue_restock to refill any empty
  *                            slots.
  * ...
  *
  */
 
 /**
- * iwl_rx_queue_space - Return number of free slots available in queue.
+ * iwl4965_rx_queue_space - Return number of free slots available in queue.
  */
-static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
+static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q)
 {
        int s = q->read - q->write;
        if (s <= 0)
@@ -4258,15 +4303,9 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q)
 }
 
 /**
- * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue
- *
- * NOTE: This function has 3945 and 4965 specific code sections
- * but is declared in base due to the majority of the
- * implementation being the same (only a numeric constant is
- * different)
- *
+ * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue
  */
-int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
+int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv, struct iwl4965_rx_queue *q)
 {
        u32 reg = 0;
        int rc = 0;
@@ -4277,24 +4316,29 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
        if (q->need_update == 0)
                goto exit_unlock;
 
+       /* If power-saving is in use, make sure device is awake */
        if (test_bit(STATUS_POWER_PMI, &priv->status)) {
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
+                       iwl4965_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        goto exit_unlock;
                }
 
-               rc = iwl_grab_restricted_access(priv);
+               rc = iwl4965_grab_nic_access(priv);
                if (rc)
                        goto exit_unlock;
 
-               iwl_write_restricted(priv, FH_RSCSR_CHNL0_WPTR,
+               /* Device expects a multiple of 8 */
+               iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_WPTR,
                                     q->write & ~0x7);
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
+
+       /* Else device is assumed to be awake */
        } else
-               iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
+               /* Device expects a multiple of 8 */
+               iwl4965_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7);
 
 
        q->need_update = 0;
@@ -4305,11 +4349,9 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
 }
 
 /**
- * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer pointer.
- *
- * NOTE: This function has 3945 and 4965 specific code paths in it.
+ * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
  */
-static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
+static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl4965_priv *priv,
                                          dma_addr_t dma_addr)
 {
        return cpu_to_le32((u32)(dma_addr >> 8));
@@ -4317,31 +4359,34 @@ static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv,
 
 
 /**
- * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
+ * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool
  *
- * If there are slots in the RX queue that  need to be restocked,
+ * If there are slots in the RX queue that need to be restocked,
  * and we have free pre-allocated buffers, fill the ranks as much
- * as we can pulling from rx_free.
+ * as we can, pulling from rx_free.
  *
  * This moves the 'write' index forward to catch up with 'processed', and
  * also updates the memory address in the firmware to reference the new
  * target buffer.
  */
-int iwl_rx_queue_restock(struct iwl_priv *priv)
+static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv)
 {
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl4965_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
+       struct iwl4965_rx_mem_buffer *rxb;
        unsigned long flags;
        int write, rc;
 
        spin_lock_irqsave(&rxq->lock, flags);
        write = rxq->write & ~0x7;
-       while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+       while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+               /* Get next free Rx buffer, remove from free list */
                element = rxq->rx_free.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list);
                list_del(element);
-               rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr);
+
+               /* Point to Rx buffer via next RBD in circular buffer */
+               rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr);
                rxq->queue[rxq->write] = rxb;
                rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
                rxq->free_count--;
@@ -4353,13 +4398,14 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
                queue_work(priv->workqueue, &priv->rx_replenish);
 
 
-       /* If we've added more space for the firmware to place data, tell it */
+       /* 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))
            || (abs(rxq->write - rxq->read) > 7)) {
                spin_lock_irqsave(&rxq->lock, flags);
                rxq->need_update = 1;
                spin_unlock_irqrestore(&rxq->lock, flags);
-               rc = iwl_rx_queue_update_write_ptr(priv, rxq);
+               rc = iwl4965_rx_queue_update_write_ptr(priv, rxq);
                if (rc)
                        return rc;
        }
@@ -4368,26 +4414,28 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
 }
 
 /**
- * iwl_rx_replensih - Move all used packet from rx_used to rx_free
+ * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free
  *
  * When moving to rx_free an SKB is allocated for the slot.
  *
- * Also restock the Rx queue via iwl_rx_queue_restock.
- * This is called as a scheduled work item (except for during intialization)
+ * Also restock the Rx queue via iwl4965_rx_queue_restock.
+ * This is called as a scheduled work item (except for during initialization)
  */
-void iwl_rx_replenish(void *data)
+static void iwl4965_rx_allocate(struct iwl4965_priv *priv)
 {
-       struct iwl_priv *priv = data;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl4965_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
-       struct iwl_rx_mem_buffer *rxb;
+       struct iwl4965_rx_mem_buffer *rxb;
        unsigned long flags;
        spin_lock_irqsave(&rxq->lock, flags);
        while (!list_empty(&rxq->rx_used)) {
                element = rxq->rx_used.next;
-               rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list);
+
+               /* Alloc a new receive buffer */
                rxb->skb =
-                   alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC);
+                   alloc_skb(priv->hw_setting.rx_buf_size,
+                               __GFP_NOWARN | GFP_ATOMIC);
                if (!rxb->skb) {
                        if (net_ratelimit())
                                printk(KERN_CRIT DRV_NAME
@@ -4399,32 +4447,55 @@ void iwl_rx_replenish(void *data)
                }
                priv->alloc_rxb_skb++;
                list_del(element);
+
+               /* Get physical address of RB/SKB */
                rxb->dma_addr =
                    pci_map_single(priv->pci_dev, rxb->skb->data,
-                                  IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                          priv->hw_setting.rx_buf_size, PCI_DMA_FROMDEVICE);
                list_add_tail(&rxb->list, &rxq->rx_free);
                rxq->free_count++;
        }
        spin_unlock_irqrestore(&rxq->lock, flags);
+}
+
+/*
+ * this should be called while priv->lock is locked
+*/
+static void __iwl4965_rx_replenish(void *data)
+{
+       struct iwl4965_priv *priv = data;
+
+       iwl4965_rx_allocate(priv);
+       iwl4965_rx_queue_restock(priv);
+}
+
+
+void iwl4965_rx_replenish(void *data)
+{
+       struct iwl4965_priv *priv = data;
+       unsigned long flags;
+
+       iwl4965_rx_allocate(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_rx_queue_restock(priv);
+       iwl4965_rx_queue_restock(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
- * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
+ * 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
  * non NULL it is unmapped and freed
  */
-void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+static void iwl4965_rx_queue_free(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq)
 {
        int i;
        for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
                if (rxq->pool[i].skb != NULL) {
                        pci_unmap_single(priv->pci_dev,
                                         rxq->pool[i].dma_addr,
-                                        IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                                        priv->hw_setting.rx_buf_size,
+                                        PCI_DMA_FROMDEVICE);
                        dev_kfree_skb(rxq->pool[i].skb);
                }
        }
@@ -4434,21 +4505,25 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        rxq->bd = NULL;
 }
 
-int iwl_rx_queue_alloc(struct iwl_priv *priv)
+int iwl4965_rx_queue_alloc(struct iwl4965_priv *priv)
 {
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl4965_rx_queue *rxq = &priv->rxq;
        struct pci_dev *dev = priv->pci_dev;
        int i;
 
        spin_lock_init(&rxq->lock);
        INIT_LIST_HEAD(&rxq->rx_free);
        INIT_LIST_HEAD(&rxq->rx_used);
+
+       /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
        rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);
        if (!rxq->bd)
                return -ENOMEM;
+
        /* Fill the rx_used queue with _all_ of the Rx buffers */
        for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
                list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
+
        /* 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;
@@ -4457,7 +4532,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        return 0;
 }
 
-void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
+void iwl4965_rx_queue_reset(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq)
 {
        unsigned long flags;
        int i;
@@ -4471,7 +4546,8 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                if (rxq->pool[i].skb != NULL) {
                        pci_unmap_single(priv->pci_dev,
                                         rxq->pool[i].dma_addr,
-                                        IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                                        priv->hw_setting.rx_buf_size,
+                                        PCI_DMA_FROMDEVICE);
                        priv->alloc_rxb_skb--;
                        dev_kfree_skb(rxq->pool[i].skb);
                        rxq->pool[i].skb = NULL;
@@ -4504,7 +4580,7 @@ static u8 ratio2dB[100] = {
 /* Calculates a relative dB value from a ratio of linear
  *   (i.e. not dB) signal levels.
  * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
-int iwl_calc_db_from_ratio(int sig_ratio)
+int iwl4965_calc_db_from_ratio(int sig_ratio)
 {
        /* 1000:1 or higher just report as 60 dB */
        if (sig_ratio >= 1000)
@@ -4530,7 +4606,7 @@ int iwl_calc_db_from_ratio(int sig_ratio)
 /* Calculate an indication of rx signal quality (a percentage, not dBm!).
  * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
  *   about formulas used below. */
-int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
+int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm)
 {
        int sig_qual;
        int degradation = PERFECT_RSSI - rssi_dbm;
@@ -4565,32 +4641,39 @@ int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
 }
 
 /**
- * iwl_rx_handle - Main entry function for receiving responses from the uCode
+ * iwl4965_rx_handle - Main entry function for receiving responses from uCode
  *
  * Uses the priv->rx_handlers callback function array to invoke
  * the appropriate handlers, including command responses,
  * frame-received notifications, and other notifications.
  */
-static void iwl_rx_handle(struct iwl_priv *priv)
+static void iwl4965_rx_handle(struct iwl4965_priv *priv)
 {
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
-       struct iwl_rx_queue *rxq = &priv->rxq;
+       struct iwl4965_rx_mem_buffer *rxb;
+       struct iwl4965_rx_packet *pkt;
+       struct iwl4965_rx_queue *rxq = &priv->rxq;
        u32 r, i;
        int reclaim;
        unsigned long flags;
+       u8 fill_rx = 0;
+       u32 count = 0;
 
-       r = iwl_hw_get_rx_read(priv);
+       /* uCode's read index (stored in shared DRAM) indicates the last Rx
+        * buffer that the driver may process (last buffer filled by ucode). */
+       r = iwl4965_hw_get_rx_read(priv);
        i = rxq->read;
 
        /* Rx interrupt, but nothing sent from uCode */
        if (i == r)
                IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i);
 
+       if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+               fill_rx = 1;
+
        while (i != r) {
                rxb = rxq->queue[i];
 
-               /* If an RXB doesn't have a queue slot associated with it
+               /* If an RXB doesn't have a Rx queue slot associated with it,
                 * then a bug has been introduced in the queue refilling
                 * routines -- catch it here */
                BUG_ON(rxb == NULL);
@@ -4598,9 +4681,9 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                rxq->queue[i] = NULL;
 
                pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
-                                           IWL_RX_BUF_SIZE,
+                                           priv->hw_setting.rx_buf_size,
                                            PCI_DMA_FROMDEVICE);
-               pkt = (struct iwl_rx_packet *)rxb->skb->data;
+               pkt = (struct iwl4965_rx_packet *)rxb->skb->data;
 
                /* Reclaim a command buffer only if this packet is a response
                 *   to a (driver-originated) command.
@@ -4617,7 +4700,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
 
                /* Based on type of command response or notification,
                 *   handle those that need handling via function in
-                *   rx_handlers table.  See iwl_setup_rx_handlers() */
+                *   rx_handlers table.  See iwl4965_setup_rx_handlers() */
                if (priv->rx_handlers[pkt->hdr.cmd]) {
                        IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR,
                                "r = %d, i = %d, %s, 0x%02x\n", r, i,
@@ -4632,11 +4715,11 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                }
 
                if (reclaim) {
-                       /* Invoke any callbacks, transfer the skb to caller,
-                        * and fire off the (possibly) blocking iwl_send_cmd()
+                       /* Invoke any callbacks, transfer the skb to caller, and
+                        * fire off the (possibly) blocking iwl4965_send_cmd()
                         * as we reclaim the driver command queue */
                        if (rxb && rxb->skb)
-                               iwl_tx_cmd_complete(priv, rxb);
+                               iwl4965_tx_cmd_complete(priv, rxb);
                        else
                                IWL_WARNING("Claim null rxb?\n");
                }
@@ -4651,20 +4734,34 @@ static void iwl_rx_handle(struct iwl_priv *priv)
                }
 
                pci_unmap_single(priv->pci_dev, rxb->dma_addr,
-                                IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+                                priv->hw_setting.rx_buf_size,
+                                PCI_DMA_FROMDEVICE);
                spin_lock_irqsave(&rxq->lock, flags);
                list_add_tail(&rxb->list, &priv->rxq.rx_used);
                spin_unlock_irqrestore(&rxq->lock, flags);
                i = (i + 1) & RX_QUEUE_MASK;
+               /* If there are a lot of unused frames,
+                * restock the Rx queue so ucode wont assert. */
+               if (fill_rx) {
+                       count++;
+                       if (count >= 8) {
+                               priv->rxq.read = i;
+                               __iwl4965_rx_replenish(priv);
+                               count = 0;
+                       }
+               }
        }
 
        /* Backtrack one entry */
        priv->rxq.read = i;
-       iwl_rx_queue_restock(priv);
+       iwl4965_rx_queue_restock(priv);
 }
 
-int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv,
-                                 struct iwl_tx_queue *txq)
+/**
+ * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware
+ */
+static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv,
+                                 struct iwl4965_tx_queue *txq)
 {
        u32 reg = 0;
        int rc = 0;
@@ -4678,41 +4775,41 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv,
                /* wake up nic if it's powered down ...
                 * uCode will wake up, and interrupt us again, so next
                 * time we'll skip this part. */
-               reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);
+               reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1);
 
                if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
                        IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg);
-                       iwl_set_bit(priv, CSR_GP_CNTRL,
+                       iwl4965_set_bit(priv, CSR_GP_CNTRL,
                                    CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
                        return rc;
                }
 
                /* restore this queue's parameters in nic hardware. */
-               rc = iwl_grab_restricted_access(priv);
+               rc = iwl4965_grab_nic_access(priv);
                if (rc)
                        return rc;
-               iwl_write_restricted(priv, HBUS_TARG_WRPTR,
-                                    txq->q.first_empty | (txq_id << 8));
-               iwl_release_restricted_access(priv);
+               iwl4965_write_direct32(priv, HBUS_TARG_WRPTR,
+                                    txq->q.write_ptr | (txq_id << 8));
+               iwl4965_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). */
        } else
-               iwl_write32(priv, HBUS_TARG_WRPTR,
-                           txq->q.first_empty | (txq_id << 8));
+               iwl4965_write32(priv, HBUS_TARG_WRPTR,
+                           txq->q.write_ptr | (txq_id << 8));
 
        txq->need_update = 0;
 
        return rc;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
+#ifdef CONFIG_IWL4965_DEBUG
+static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon)
 {
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RADIO("RX CONFIG:\n");
-       iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
+       iwl4965_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
        IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
        IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
        IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n",
@@ -4729,24 +4826,24 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon)
 }
 #endif
 
-static void iwl_enable_interrupts(struct iwl_priv *priv)
+static void iwl4965_enable_interrupts(struct iwl4965_priv *priv)
 {
        IWL_DEBUG_ISR("Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &priv->status);
-       iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+       iwl4965_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
 }
 
-static inline void iwl_disable_interrupts(struct iwl_priv *priv)
+static inline void iwl4965_disable_interrupts(struct iwl4965_priv *priv)
 {
        clear_bit(STATUS_INT_ENABLED, &priv->status);
 
        /* disable interrupts from uCode/NIC to host */
-       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+       iwl4965_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* acknowledge/clear/reset any interrupts still pending
         * from uCode or flow handler (Rx/Tx DMA) */
-       iwl_write32(priv, CSR_INT, 0xffffffff);
-       iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
+       iwl4965_write32(priv, CSR_INT, 0xffffffff);
+       iwl4965_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
        IWL_DEBUG_ISR("Disabled interrupts\n");
 }
 
@@ -4773,7 +4870,7 @@ static const char *desc_lookup(int i)
 #define ERROR_START_OFFSET  (1 * sizeof(u32))
 #define ERROR_ELEM_SIZE     (7 * sizeof(u32))
 
-static void iwl_dump_nic_error_log(struct iwl_priv *priv)
+static void iwl4965_dump_nic_error_log(struct iwl4965_priv *priv)
 {
        u32 data2, line;
        u32 desc, time, count, base, data1;
@@ -4782,18 +4879,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
 
        base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
-       if (!iwl_hw_valid_rtc_data_addr(base)) {
+       if (!iwl4965_hw_valid_rtc_data_addr(base)) {
                IWL_ERROR("Not valid error log pointer 0x%08X\n", base);
                return;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
-       count = iwl_read_restricted_mem(priv, base);
+       count = iwl4965_read_targ_mem(priv, base);
 
        if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
                IWL_ERROR("Start IWL Error Log Dump:\n");
@@ -4801,15 +4898,15 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
                          priv->status, priv->config, count);
        }
 
-       desc = iwl_read_restricted_mem(priv, base + 1 * sizeof(u32));
-       blink1 = iwl_read_restricted_mem(priv, base + 3 * sizeof(u32));
-       blink2 = iwl_read_restricted_mem(priv, base + 4 * sizeof(u32));
-       ilink1 = iwl_read_restricted_mem(priv, base + 5 * sizeof(u32));
-       ilink2 = iwl_read_restricted_mem(priv, base + 6 * sizeof(u32));
-       data1 = iwl_read_restricted_mem(priv, base + 7 * sizeof(u32));
-       data2 = iwl_read_restricted_mem(priv, base + 8 * sizeof(u32));
-       line = iwl_read_restricted_mem(priv, base + 9 * sizeof(u32));
-       time = iwl_read_restricted_mem(priv, base + 11 * sizeof(u32));
+       desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32));
+       blink1 = iwl4965_read_targ_mem(priv, base + 3 * sizeof(u32));
+       blink2 = iwl4965_read_targ_mem(priv, base + 4 * sizeof(u32));
+       ilink1 = iwl4965_read_targ_mem(priv, base + 5 * sizeof(u32));
+       ilink2 = iwl4965_read_targ_mem(priv, base + 6 * sizeof(u32));
+       data1 = iwl4965_read_targ_mem(priv, base + 7 * sizeof(u32));
+       data2 = iwl4965_read_targ_mem(priv, base + 8 * sizeof(u32));
+       line = iwl4965_read_targ_mem(priv, base + 9 * sizeof(u32));
+       time = iwl4965_read_targ_mem(priv, base + 11 * sizeof(u32));
 
        IWL_ERROR("Desc               Time       "
                  "data1      data2      line\n");
@@ -4819,17 +4916,17 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
        IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
                  ilink1, ilink2);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 }
 
 #define EVENT_START_OFFSET  (4 * sizeof(u32))
 
 /**
- * iwl_print_event_log - Dump error event log to syslog
+ * iwl4965_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl_grab_restricted_access() already obtained!
+ * NOTE: Must be called with iwl4965_grab_nic_access() already obtained!
  */
-static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+static void iwl4965_print_event_log(struct iwl4965_priv *priv, u32 start_idx,
                                u32 num_events, u32 mode)
 {
        u32 i;
@@ -4853,21 +4950,21 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
        /* "time" is actually "data" for mode 0 (no timestamp).
         * place event id # at far right for easier visual parsing. */
        for (i = 0; i < num_events; i++) {
-               ev = iwl_read_restricted_mem(priv, ptr);
+               ev = iwl4965_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
-               time = iwl_read_restricted_mem(priv, ptr);
+               time = iwl4965_read_targ_mem(priv, ptr);
                ptr += sizeof(u32);
                if (mode == 0)
                        IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
                else {
-                       data = iwl_read_restricted_mem(priv, ptr);
+                       data = iwl4965_read_targ_mem(priv, ptr);
                        ptr += sizeof(u32);
                        IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
                }
        }
 }
 
-static void iwl_dump_nic_event_log(struct iwl_priv *priv)
+static void iwl4965_dump_nic_event_log(struct iwl4965_priv *priv)
 {
        int rc;
        u32 base;       /* SRAM byte address of event log header */
@@ -4878,29 +4975,29 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv)
        u32 size;       /* # entries that we'll print */
 
        base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
-       if (!iwl_hw_valid_rtc_data_addr(base)) {
+       if (!iwl4965_hw_valid_rtc_data_addr(base)) {
                IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
                return;
        }
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc) {
                IWL_WARNING("Can not read from adapter at this time.\n");
                return;
        }
 
        /* event log header */
-       capacity = iwl_read_restricted_mem(priv, base);
-       mode = iwl_read_restricted_mem(priv, base + (1 * sizeof(u32)));
-       num_wraps = iwl_read_restricted_mem(priv, base + (2 * sizeof(u32)));
-       next_entry = iwl_read_restricted_mem(priv, base + (3 * sizeof(u32)));
+       capacity = iwl4965_read_targ_mem(priv, base);
+       mode = iwl4965_read_targ_mem(priv, base + (1 * sizeof(u32)));
+       num_wraps = iwl4965_read_targ_mem(priv, base + (2 * sizeof(u32)));
+       next_entry = iwl4965_read_targ_mem(priv, base + (3 * sizeof(u32)));
 
        size = num_wraps ? capacity : next_entry;
 
        /* bail out if nothing in log */
        if (size == 0) {
                IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
                return;
        }
 
@@ -4910,31 +5007,31 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv)
        /* if uCode has wrapped back to top of log, start at the oldest entry,
         * i.e the next one that uCode would fill. */
        if (num_wraps)
-               iwl_print_event_log(priv, next_entry,
+               iwl4965_print_event_log(priv, next_entry,
                                    capacity - next_entry, mode);
 
        /* (then/else) start at top of log */
-       iwl_print_event_log(priv, 0, next_entry, mode);
+       iwl4965_print_event_log(priv, 0, next_entry, mode);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 }
 
 /**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ * iwl4965_irq_handle_error - called for HW or SW error interrupt from card
  */
-static void iwl_irq_handle_error(struct iwl_priv *priv)
+static void iwl4965_irq_handle_error(struct iwl4965_priv *priv)
 {
-       /* Set the FW error flag -- cleared on iwl_down */
+       /* Set the FW error flag -- cleared on iwl4965_down */
        set_bit(STATUS_FW_ERROR, &priv->status);
 
        /* Cancel currently queued command. */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & IWL_DL_FW_ERRORS) {
-               iwl_dump_nic_error_log(priv);
-               iwl_dump_nic_event_log(priv);
-               iwl_print_rx_config_cmd(&priv->staging_rxon);
+#ifdef CONFIG_IWL4965_DEBUG
+       if (iwl4965_debug_level & IWL_DL_FW_ERRORS) {
+               iwl4965_dump_nic_error_log(priv);
+               iwl4965_dump_nic_event_log(priv);
+               iwl4965_print_rx_config_cmd(&priv->staging_rxon);
        }
 #endif
 
@@ -4948,7 +5045,7 @@ static void iwl_irq_handle_error(struct iwl_priv *priv)
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
                          "Restarting adapter due to uCode error.\n");
 
-               if (iwl_is_associated(priv)) {
+               if (iwl4965_is_associated(priv)) {
                        memcpy(&priv->recovery_rxon, &priv->active_rxon,
                               sizeof(priv->recovery_rxon));
                        priv->error_recovering = 1;
@@ -4957,16 +5054,16 @@ static void iwl_irq_handle_error(struct iwl_priv *priv)
        }
 }
 
-static void iwl_error_recovery(struct iwl_priv *priv)
+static void iwl4965_error_recovery(struct iwl4965_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);
+       iwl4965_commit_rxon(priv);
 
-       iwl_rxon_add_station(priv, priv->bssid, 1);
+       iwl4965_rxon_add_station(priv, priv->bssid, 1);
 
        spin_lock_irqsave(&priv->lock, flags);
        priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
@@ -4974,12 +5071,12 @@ static void iwl_error_recovery(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static void iwl_irq_tasklet(struct iwl_priv *priv)
+static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
 {
        u32 inta, handled = 0;
        u32 inta_fh;
        unsigned long flags;
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
        u32 inta_mask;
 #endif
 
@@ -4988,18 +5085,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
         *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
-       inta = iwl_read32(priv, CSR_INT);
-       iwl_write32(priv, CSR_INT, inta);
+       inta = iwl4965_read32(priv, CSR_INT);
+       iwl4965_write32(priv, CSR_INT, inta);
 
        /* Ack/clear/reset pending flow-handler (DMA) interrupts.
         * Any new interrupts that happen after this, either while we're
         * in this tasklet, or later, will show up in next ISR/tasklet. */
-       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-       iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
+       inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
+       iwl4965_write32(priv, CSR_FH_INT_STATUS, inta_fh);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & IWL_DL_ISR) {
-               inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */
+#ifdef CONFIG_IWL4965_DEBUG
+       if (iwl4965_debug_level & IWL_DL_ISR) {
+               /* just for debug */
+               inta_mask = iwl4965_read32(priv, CSR_INT_MASK);
                IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                              inta, inta_mask, inta_fh);
        }
@@ -5019,9 +5117,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                IWL_ERROR("Microcode HW error detected.  Restarting.\n");
 
                /* Tell the device to stop sending interrupts */
-               iwl_disable_interrupts(priv);
+               iwl4965_disable_interrupts(priv);
 
-               iwl_irq_handle_error(priv);
+               iwl4965_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
 
@@ -5030,8 +5128,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                return;
        }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & (IWL_DL_ISR)) {
+#ifdef CONFIG_IWL4965_DEBUG
+       if (iwl4965_debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
                if (inta & CSR_INT_BIT_MAC_CLK_ACTV)
                        IWL_DEBUG_ISR("Microcode started or stopped.\n");
@@ -5044,10 +5142,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Safely ignore these bits for debug checks below */
        inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE);
 
-       /* HW RF KILL switch toggled (4965 only) */
+       /* HW RF KILL switch toggled */
        if (inta & CSR_INT_BIT_RF_KILL) {
                int hw_rf_kill = 0;
-               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+               if (!(iwl4965_read32(priv, CSR_GP_CNTRL) &
                                CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
                        hw_rf_kill = 1;
 
@@ -5067,7 +5165,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                handled |= CSR_INT_BIT_RF_KILL;
        }
 
-       /* Chip got too hot and stopped itself (4965 only) */
+       /* Chip got too hot and stopped itself */
        if (inta & CSR_INT_BIT_CT_KILL) {
                IWL_ERROR("Microcode CT kill error detected.\n");
                handled |= CSR_INT_BIT_CT_KILL;
@@ -5077,20 +5175,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERROR("Microcode SW error detected.  Restarting 0x%X.\n",
                          inta);
-               iwl_irq_handle_error(priv);
+               iwl4965_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("Wakeup interrupt\n");
-               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[0]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[1]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[2]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[3]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[4]);
-               iwl_tx_queue_update_write_ptr(priv, &priv->txq[5]);
+               iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[3]);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[4]);
+               iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[5]);
 
                handled |= CSR_INT_BIT_WAKEUP;
        }
@@ -5099,7 +5197,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
         * 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)) {
-               iwl_rx_handle(priv);
+               iwl4965_rx_handle(priv);
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
 
@@ -5118,13 +5216,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        }
 
        /* Re-enable all interrupts */
-       iwl_enable_interrupts(priv);
+       iwl4965_enable_interrupts(priv);
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_debug_level & (IWL_DL_ISR)) {
-               inta = iwl_read32(priv, CSR_INT);
-               inta_mask = iwl_read32(priv, CSR_INT_MASK);
-               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+#ifdef CONFIG_IWL4965_DEBUG
+       if (iwl4965_debug_level & (IWL_DL_ISR)) {
+               inta = iwl4965_read32(priv, CSR_INT);
+               inta_mask = iwl4965_read32(priv, CSR_INT_MASK);
+               inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
                        "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
        }
@@ -5132,9 +5230,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-static irqreturn_t iwl_isr(int irq, void *data)
+static irqreturn_t iwl4965_isr(int irq, void *data)
 {
-       struct iwl_priv *priv = data;
+       struct iwl4965_priv *priv = data;
        u32 inta, inta_mask;
        u32 inta_fh;
        if (!priv)
@@ -5146,12 +5244,12 @@ static irqreturn_t iwl_isr(int irq, void *data)
         *    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);
+       inta_mask = iwl4965_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl4965_write32(priv, CSR_INT_MASK, 0x00000000);
 
        /* Discover which interrupts are active/pending */
-       inta = iwl_read32(priv, CSR_INT);
-       inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+       inta = iwl4965_read32(priv, CSR_INT);
+       inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS);
 
        /* Ignore interrupt if there's nothing in NIC to service.
         * This may be due to IRQ shared with another device,
@@ -5171,7 +5269,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
                      inta, inta_mask, inta_fh);
 
-       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       /* iwl4965_irq_tasklet() will service interrupts and re-enable them */
        tasklet_schedule(&priv->irq_tasklet);
 
  unplugged:
@@ -5180,18 +5278,18 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
  none:
        /* re-enable interrupts here since we don't have anything to service. */
-       iwl_enable_interrupts(priv);
+       iwl4965_enable_interrupts(priv);
        spin_unlock(&priv->lock);
        return IRQ_NONE;
 }
 
 /************************** EEPROM BANDS ****************************
  *
- * The iwl_eeprom_band definitions below provide the mapping from the
+ * The iwl4965_eeprom_band definitions below provide the mapping from the
  * EEPROM contents to the specific channel number supported for each
  * band.
  *
- * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3
+ * For example, iwl4965_priv->eeprom.band_3_channels[4] from the band_3
  * definition below maps to physical channel 42 in the 5.2GHz spectrum.
  * The specific geography and calibration information for that channel
  * is contained in the eeprom map itself.
@@ -5217,76 +5315,77 @@ static irqreturn_t iwl_isr(int irq, void *data)
  *********************************************************************/
 
 /* 2.4 GHz */
-static const u8 iwl_eeprom_band_1[14] = {
+static const u8 iwl4965_eeprom_band_1[14] = {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
 };
 
 /* 5.2 GHz bands */
-static const u8 iwl_eeprom_band_2[] = {
+static const u8 iwl4965_eeprom_band_2[] = {    /* 4915-5080MHz */
        183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
 };
 
-static const u8 iwl_eeprom_band_3[] = {        /* 5205-5320MHz */
+static const u8 iwl4965_eeprom_band_3[] = {    /* 5170-5320MHz */
        34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
 };
 
-static const u8 iwl_eeprom_band_4[] = {        /* 5500-5700MHz */
+static const u8 iwl4965_eeprom_band_4[] = {    /* 5500-5700MHz */
        100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
 };
 
-static const u8 iwl_eeprom_band_5[] = {        /* 5725-5825MHz */
+static const u8 iwl4965_eeprom_band_5[] = {    /* 5725-5825MHz */
        145, 149, 153, 157, 161, 165
 };
 
-static u8 iwl_eeprom_band_6[] = {       /* 2.4 FAT channel */
+static u8 iwl4965_eeprom_band_6[] = {       /* 2.4 FAT channel */
        1, 2, 3, 4, 5, 6, 7
 };
 
-static u8 iwl_eeprom_band_7[] = {       /* 5.2 FAT channel */
+static u8 iwl4965_eeprom_band_7[] = {       /* 5.2 FAT channel */
        36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157
 };
 
-static void iwl_init_band_reference(const struct iwl_priv *priv, int band,
+static void iwl4965_init_band_reference(const struct iwl4965_priv *priv,
+                                   int band,
                                    int *eeprom_ch_count,
-                                   const struct iwl_eeprom_channel
+                                   const struct iwl4965_eeprom_channel
                                    **eeprom_ch_info,
                                    const u8 **eeprom_ch_index)
 {
        switch (band) {
        case 1:         /* 2.4GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_1);
                *eeprom_ch_info = priv->eeprom.band_1_channels;
-               *eeprom_ch_index = iwl_eeprom_band_1;
+               *eeprom_ch_index = iwl4965_eeprom_band_1;
                break;
-       case 2:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
+       case 2:         /* 4.9GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_2);
                *eeprom_ch_info = priv->eeprom.band_2_channels;
-               *eeprom_ch_index = iwl_eeprom_band_2;
+               *eeprom_ch_index = iwl4965_eeprom_band_2;
                break;
        case 3:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_3);
                *eeprom_ch_info = priv->eeprom.band_3_channels;
-               *eeprom_ch_index = iwl_eeprom_band_3;
+               *eeprom_ch_index = iwl4965_eeprom_band_3;
                break;
-       case 4:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
+       case 4:         /* 5.5GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_4);
                *eeprom_ch_info = priv->eeprom.band_4_channels;
-               *eeprom_ch_index = iwl_eeprom_band_4;
+               *eeprom_ch_index = iwl4965_eeprom_band_4;
                break;
-       case 5:         /* 5.2GHz band */
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
+       case 5:         /* 5.7GHz band */
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_5);
                *eeprom_ch_info = priv->eeprom.band_5_channels;
-               *eeprom_ch_index = iwl_eeprom_band_5;
+               *eeprom_ch_index = iwl4965_eeprom_band_5;
                break;
-       case 6:
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
+       case 6:         /* 2.4GHz FAT channels */
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_6);
                *eeprom_ch_info = priv->eeprom.band_24_channels;
-               *eeprom_ch_index = iwl_eeprom_band_6;
+               *eeprom_ch_index = iwl4965_eeprom_band_6;
                break;
-       case 7:
-               *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
+       case 7:         /* 5 GHz FAT channels */
+               *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_7);
                *eeprom_ch_info = priv->eeprom.band_52_channels;
-               *eeprom_ch_index = iwl_eeprom_band_7;
+               *eeprom_ch_index = iwl4965_eeprom_band_7;
                break;
        default:
                BUG();
@@ -5294,7 +5393,12 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, int band,
        }
 }
 
-const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
+/**
+ * iwl4965_get_channel_info - Find driver's private channel info
+ *
+ * Based on band and channel number.
+ */
+const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv,
                                                    int phymode, u16 channel)
 {
        int i;
@@ -5321,13 +5425,16 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv,
 #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
                            ? # x " " : "")
 
-static int iwl_init_channel_map(struct iwl_priv *priv)
+/**
+ * iwl4965_init_channel_map - Set up driver's info for all possible channels
+ */
+static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
 {
        int eeprom_ch_count = 0;
        const u8 *eeprom_ch_index = NULL;
-       const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
+       const struct iwl4965_eeprom_channel *eeprom_ch_info = NULL;
        int band, ch;
-       struct iwl_channel_info *ch_info;
+       struct iwl4965_channel_info *ch_info;
 
        if (priv->channel_count) {
                IWL_DEBUG_INFO("Channel map already initialized.\n");
@@ -5343,15 +5450,15 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
 
        priv->channel_count =
-           ARRAY_SIZE(iwl_eeprom_band_1) +
-           ARRAY_SIZE(iwl_eeprom_band_2) +
-           ARRAY_SIZE(iwl_eeprom_band_3) +
-           ARRAY_SIZE(iwl_eeprom_band_4) +
-           ARRAY_SIZE(iwl_eeprom_band_5);
+           ARRAY_SIZE(iwl4965_eeprom_band_1) +
+           ARRAY_SIZE(iwl4965_eeprom_band_2) +
+           ARRAY_SIZE(iwl4965_eeprom_band_3) +
+           ARRAY_SIZE(iwl4965_eeprom_band_4) +
+           ARRAY_SIZE(iwl4965_eeprom_band_5);
 
        IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
 
-       priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
+       priv->channel_info = kzalloc(sizeof(struct iwl4965_channel_info) *
                                     priv->channel_count, GFP_KERNEL);
        if (!priv->channel_info) {
                IWL_ERROR("Could not allocate channel_info\n");
@@ -5366,7 +5473,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
         * what just in the EEPROM) */
        for (band = 1; band <= 5; band++) {
 
-               iwl_init_band_reference(priv, band, &eeprom_ch_count,
+               iwl4965_init_band_reference(priv, band, &eeprom_ch_count,
                                        &eeprom_ch_info, &eeprom_ch_index);
 
                /* Loop through each band adding each of the channels */
@@ -5430,14 +5537,17 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
                }
        }
 
+       /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
        for (band = 6; band <= 7; band++) {
                int phymode;
                u8 fat_extension_chan;
 
-               iwl_init_band_reference(priv, band, &eeprom_ch_count,
+               iwl4965_init_band_reference(priv, band, &eeprom_ch_count,
                                        &eeprom_ch_info, &eeprom_ch_index);
 
+               /* EEPROM band 6 is 2.4, band 7 is 5 GHz */
                phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A;
+
                /* Loop through each band adding each of the channels */
                for (ch = 0; ch < eeprom_ch_count; ch++) {
 
@@ -5449,11 +5559,13 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
                        else
                                fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;
 
+                       /* Set up driver's info for lower half */
                        iwl4965_set_fat_chan_info(priv, phymode,
                                                  eeprom_ch_index[ch],
                                                  &(eeprom_ch_info[ch]),
                                                  fat_extension_chan);
 
+                       /* Set up driver's info for upper half */
                        iwl4965_set_fat_chan_info(priv, phymode,
                                                  (eeprom_ch_index[ch] + 4),
                                                  &(eeprom_ch_info[ch]),
@@ -5487,7 +5599,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode)
+static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode)
 {
        if (phymode == MODE_IEEE80211A)
                return IWL_ACTIVE_DWELL_TIME_52;
@@ -5495,14 +5607,14 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode)
                return IWL_ACTIVE_DWELL_TIME_24;
 }
 
-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode)
+static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode)
 {
-       u16 active = iwl_get_active_dwell_time(priv, phymode);
+       u16 active = iwl4965_get_active_dwell_time(priv, phymode);
        u16 passive = (phymode != MODE_IEEE80211A) ?
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
 
-       if (iwl_is_associated(priv)) {
+       if (iwl4965_is_associated(priv)) {
                /* If we're associated, we clamp the maximum passive
                 * dwell time to be 98% of the beacon interval (minus
                 * 2 * channel tune time) */
@@ -5518,30 +5630,30 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode)
        return passive;
 }
 
-static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
+static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
                                     u8 is_active, u8 direct_mask,
-                                    struct iwl_scan_channel *scan_ch)
+                                    struct iwl4965_scan_channel *scan_ch)
 {
        const struct ieee80211_channel *channels = NULL;
        const struct ieee80211_hw_mode *hw_mode;
-       const struct iwl_channel_info *ch_info;
+       const struct iwl4965_channel_info *ch_info;
        u16 passive_dwell = 0;
        u16 active_dwell = 0;
        int added, i;
 
-       hw_mode = iwl_get_hw_mode(priv, phymode);
+       hw_mode = iwl4965_get_hw_mode(priv, phymode);
        if (!hw_mode)
                return 0;
 
        channels = hw_mode->channels;
 
-       active_dwell = iwl_get_active_dwell_time(priv, phymode);
-       passive_dwell = iwl_get_passive_dwell_time(priv, phymode);
+       active_dwell = iwl4965_get_active_dwell_time(priv, phymode);
+       passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode);
 
        for (i = 0, added = 0; i < hw_mode->num_channels; i++) {
                if (channels[i].chan ==
                    le16_to_cpu(priv->active_rxon.channel)) {
-                       if (iwl_is_associated(priv)) {
+                       if (iwl4965_is_associated(priv)) {
                                IWL_DEBUG_SCAN
                                    ("Skipping current channel %d\n",
                                     le16_to_cpu(priv->active_rxon.channel));
@@ -5552,7 +5664,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
 
                scan_ch->channel = channels[i].chan;
 
-               ch_info = iwl_get_channel_info(priv, phymode, scan_ch->channel);
+               ch_info = iwl4965_get_channel_info(priv, phymode,
+                                        scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
                        IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
                                       scan_ch->channel);
@@ -5574,7 +5687,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
                scan_ch->active_dwell = cpu_to_le16(active_dwell);
                scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
 
-               /* Set power levels to defaults */
+               /* Set txpower levels to defaults */
                scan_ch->tpc.dsp_atten = 110;
                /* scan_pwr_info->tpc.dsp_atten; */
 
@@ -5584,8 +5697,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
                else {
                        scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
                        /* NOTE: if we were doing 6Mb OFDM for scans we'd use
-                        * power level
-                        scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3;
+                        * power level:
+                        * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
                         */
                }
 
@@ -5603,7 +5716,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode,
        return added;
 }
 
-static void iwl_reset_channel_flag(struct iwl_priv *priv)
+static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv)
 {
        int i, j;
        for (i = 0; i < 3; i++) {
@@ -5613,13 +5726,13 @@ static void iwl_reset_channel_flag(struct iwl_priv *priv)
        }
 }
 
-static void iwl_init_hw_rates(struct iwl_priv *priv,
+static void iwl4965_init_hw_rates(struct iwl4965_priv *priv,
                              struct ieee80211_rate *rates)
 {
        int i;
 
        for (i = 0; i < IWL_RATE_COUNT; i++) {
-               rates[i].rate = iwl_rates[i].ieee * 5;
+               rates[i].rate = iwl4965_rates[i].ieee * 5;
                rates[i].val = i; /* Rate scaling will work on indexes */
                rates[i].val2 = i;
                rates[i].flags = IEEE80211_RATE_SUPPORTED;
@@ -5631,7 +5744,7 @@ static void iwl_init_hw_rates(struct iwl_priv *priv,
                         * If CCK 1M then set rate flag to CCK else CCK_2
                         * which is CCK | PREAMBLE2
                         */
-                       rates[i].flags |= (iwl_rates[i].plcp == 10) ?
+                       rates[i].flags |= (iwl4965_rates[i].plcp == 10) ?
                                IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2;
                }
 
@@ -5639,16 +5752,14 @@ static void iwl_init_hw_rates(struct iwl_priv *priv,
                if (IWL_BASIC_RATES_MASK & (1 << i))
                        rates[i].flags |= IEEE80211_RATE_BASIC;
        }
-
-       iwl4965_init_hw_rates(priv, rates);
 }
 
 /**
- * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom
+ * iwl4965_init_geos - Initialize mac80211's geo/channel info based from eeprom
  */
-static int iwl_init_geos(struct iwl_priv *priv)
+static int iwl4965_init_geos(struct iwl4965_priv *priv)
 {
-       struct iwl_channel_info *ch;
+       struct iwl4965_channel_info *ch;
        struct ieee80211_hw_mode *modes;
        struct ieee80211_channel *channels;
        struct ieee80211_channel *geo_ch;
@@ -5658,10 +5769,8 @@ static int iwl_init_geos(struct iwl_priv *priv)
                A = 0,
                B = 1,
                G = 2,
-               A_11N = 3,
-               G_11N = 4,
        };
-       int mode_count = 5;
+       int mode_count = 3;
 
        if (priv->modes) {
                IWL_DEBUG_INFO("Geography modes already initialized.\n");
@@ -5696,11 +5805,14 @@ static int iwl_init_geos(struct iwl_priv *priv)
 
        /* 5.2GHz channels start after the 2.4GHz channels */
        modes[A].mode = MODE_IEEE80211A;
-       modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
+       modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)];
        modes[A].rates = rates;
        modes[A].num_rates = 8; /* just OFDM */
        modes[A].rates = &rates[4];
        modes[A].num_channels = 0;
+#ifdef CONFIG_IWL4965_HT
+       iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A);
+#endif
 
        modes[B].mode = MODE_IEEE80211B;
        modes[B].channels = channels;
@@ -5713,23 +5825,14 @@ static int iwl_init_geos(struct iwl_priv *priv)
        modes[G].rates = rates;
        modes[G].num_rates = 12;        /* OFDM & CCK */
        modes[G].num_channels = 0;
-
-       modes[G_11N].mode = MODE_IEEE80211G;
-       modes[G_11N].channels = channels;
-       modes[G_11N].num_rates = 13;        /* OFDM & CCK */
-       modes[G_11N].rates = rates;
-       modes[G_11N].num_channels = 0;
-
-       modes[A_11N].mode = MODE_IEEE80211A;
-       modes[A_11N].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)];
-       modes[A_11N].rates = &rates[4];
-       modes[A_11N].num_rates = 9; /* just OFDM */
-       modes[A_11N].num_channels = 0;
+#ifdef CONFIG_IWL4965_HT
+       iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G);
+#endif
 
        priv->ieee_channels = channels;
        priv->ieee_rates = rates;
 
-       iwl_init_hw_rates(priv, rates);
+       iwl4965_init_hw_rates(priv, rates);
 
        for (i = 0, geo_ch = channels; i < priv->channel_count; i++) {
                ch = &priv->channel_info[i];
@@ -5744,11 +5847,9 @@ static int iwl_init_geos(struct iwl_priv *priv)
 
                if (is_channel_a_band(ch)) {
                        geo_ch = &modes[A].channels[modes[A].num_channels++];
-                       modes[A_11N].num_channels++;
                } else {
                        geo_ch = &modes[B].channels[modes[B].num_channels++];
                        modes[G].num_channels++;
-                       modes[G_11N].num_channels++;
                }
 
                geo_ch->freq = ieee80211chan2mhz(ch->channel);
@@ -5814,57 +5915,22 @@ static int iwl_init_geos(struct iwl_priv *priv)
  *
  ******************************************************************************/
 
-static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl4965_dealloc_ucode_pci(struct iwl4965_priv *priv)
 {
-       if (priv->ucode_code.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_code.len,
-                                   priv->ucode_code.v_addr,
-                                   priv->ucode_code.p_addr);
-               priv->ucode_code.v_addr = NULL;
-       }
-       if (priv->ucode_data.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_data.len,
-                                   priv->ucode_data.v_addr,
-                                   priv->ucode_data.p_addr);
-               priv->ucode_data.v_addr = NULL;
-       }
-       if (priv->ucode_data_backup.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_data_backup.len,
-                                   priv->ucode_data_backup.v_addr,
-                                   priv->ucode_data_backup.p_addr);
-               priv->ucode_data_backup.v_addr = NULL;
-       }
-       if (priv->ucode_init.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_init.len,
-                                   priv->ucode_init.v_addr,
-                                   priv->ucode_init.p_addr);
-               priv->ucode_init.v_addr = NULL;
-       }
-       if (priv->ucode_init_data.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_init_data.len,
-                                   priv->ucode_init_data.v_addr,
-                                   priv->ucode_init_data.p_addr);
-               priv->ucode_init_data.v_addr = NULL;
-       }
-       if (priv->ucode_boot.v_addr != NULL) {
-               pci_free_consistent(priv->pci_dev,
-                                   priv->ucode_boot.len,
-                                   priv->ucode_boot.v_addr,
-                                   priv->ucode_boot.p_addr);
-               priv->ucode_boot.v_addr = NULL;
-       }
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
+       iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
 }
 
 /**
- * iwl_verify_inst_full - verify runtime uCode image in card vs. host,
+ * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host,
  *     looking at all data.
  */
-static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
+static int iwl4965_verify_inst_full(struct iwl4965_priv *priv, __le32 *image,
+                                u32 len)
 {
        u32 val;
        u32 save_len = len;
@@ -5873,18 +5939,18 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
+       iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND);
 
        errcnt = 0;
        for (; len > 0; len -= sizeof(u32), image++) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("uCode INST section is invalid at "
                                  "offset 0x%x, is 0x%x, s/b 0x%x\n",
@@ -5896,7 +5962,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
                }
        }
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 
        if (!errcnt)
                IWL_DEBUG_INFO
@@ -5907,11 +5973,11 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len)
 
 
 /**
- * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
+ * iwl4965_verify_inst_sparse - verify runtime uCode image in card vs. host,
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+static int iwl4965_verify_inst_sparse(struct iwl4965_priv *priv, __le32 *image, u32 len)
 {
        u32 val;
        int rc = 0;
@@ -5920,7 +5986,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
 
        IWL_DEBUG_INFO("ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc)
                return rc;
 
@@ -5928,9 +5994,9 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
                 * if IWL_DL_IO is set */
-               iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR,
+               iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR,
                        i + RTC_INST_LOWER_BOUND);
-               val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT);
+               val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT);
                if (val != le32_to_cpu(*image)) {
 #if 0 /* Enable this if you want to see details */
                        IWL_ERROR("uCode INST section is invalid at "
@@ -5944,17 +6010,17 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
                }
        }
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 
        return rc;
 }
 
 
 /**
- * iwl_verify_ucode - determine which instruction image is in SRAM,
+ * iwl4965_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-static int iwl_verify_ucode(struct iwl_priv *priv)
+static int iwl4965_verify_ucode(struct iwl4965_priv *priv)
 {
        __le32 *image;
        u32 len;
@@ -5963,7 +6029,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try bootstrap */
        image = (__le32 *)priv->ucode_boot.v_addr;
        len = priv->ucode_boot.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl4965_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n");
                return 0;
@@ -5972,7 +6038,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try initialize */
        image = (__le32 *)priv->ucode_init.v_addr;
        len = priv->ucode_init.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl4965_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n");
                return 0;
@@ -5981,7 +6047,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
        /* Try runtime/protocol */
        image = (__le32 *)priv->ucode_code.v_addr;
        len = priv->ucode_code.len;
-       rc = iwl_verify_inst_sparse(priv, image, len);
+       rc = iwl4965_verify_inst_sparse(priv, image, len);
        if (rc == 0) {
                IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n");
                return 0;
@@ -5989,18 +6055,19 @@ static int iwl_verify_ucode(struct iwl_priv *priv)
 
        IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
 
-       /* Show first several data entries in instruction SRAM.
-        * Selection of bootstrap image is arbitrary. */
+       /* Since nothing seems to match, show first several data entries in
+        * instruction SRAM, so maybe visual inspection will give a clue.
+        * Selection of bootstrap image (vs. other images) is arbitrary. */
        image = (__le32 *)priv->ucode_boot.v_addr;
        len = priv->ucode_boot.len;
-       rc = iwl_verify_inst_full(priv, image, len);
+       rc = iwl4965_verify_inst_full(priv, image, len);
 
        return rc;
 }
 
 
 /* check contents of special bootstrap uCode SRAM */
-static int iwl_verify_bsm(struct iwl_priv *priv)
+static int iwl4965_verify_bsm(struct iwl4965_priv *priv)
 {
        __le32 *image = priv->ucode_boot.v_addr;
        u32 len = priv->ucode_boot.len;
@@ -6010,11 +6077,11 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
        IWL_DEBUG_INFO("Begin verify bsm\n");
 
        /* verify BSM SRAM contents */
-       val = iwl_read_restricted_reg(priv, BSM_WR_DWCOUNT_REG);
+       val = iwl4965_read_prph(priv, BSM_WR_DWCOUNT_REG);
        for (reg = BSM_SRAM_LOWER_BOUND;
             reg < BSM_SRAM_LOWER_BOUND + len;
             reg += sizeof(u32), image ++) {
-               val = iwl_read_restricted_reg(priv, reg);
+               val = iwl4965_read_prph(priv, reg);
                if (val != le32_to_cpu(*image)) {
                        IWL_ERROR("BSM uCode verification failed at "
                                  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
@@ -6031,7 +6098,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
 }
 
 /**
- * iwl_load_bsm - Load bootstrap instructions
+ * iwl4965_load_bsm - Load bootstrap instructions
  *
  * BSM operation:
  *
@@ -6062,7 +6129,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv)
  * the runtime uCode instructions and the backup data cache into SRAM,
  * and re-launches the runtime uCode from where it left off.
  */
-static int iwl_load_bsm(struct iwl_priv *priv)
+static int iwl4965_load_bsm(struct iwl4965_priv *priv)
 {
        __le32 *image = priv->ucode_boot.v_addr;
        u32 len = priv->ucode_boot.len;
@@ -6082,8 +6149,8 @@ static int iwl_load_bsm(struct iwl_priv *priv)
                return -EINVAL;
 
        /* Tell bootstrap uCode where to find the "Initialize" uCode
-        *   in host DRAM ... bits 31:0 for 3945, bits 35:4 for 4965.
-        * NOTE:  iwl_initialize_alive_start() will replace these values,
+        *   in host DRAM ... host DRAM physical address bits 35:4 for 4965.
+        * NOTE:  iwl4965_initialize_alive_start() will replace these values,
         *        after the "initialize" uCode has run, to point to
         *        runtime/protocol instructions and backup data cache. */
        pinst = priv->ucode_init.p_addr >> 4;
@@ -6091,42 +6158,42 @@ static int iwl_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_grab_nic_access(priv);
        if (rc)
                return rc;
 
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
+       iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
+       iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
 
        /* Fill BSM memory with bootstrap instructions */
        for (reg_offset = BSM_SRAM_LOWER_BOUND;
             reg_offset < BSM_SRAM_LOWER_BOUND + len;
             reg_offset += sizeof(u32), image++)
-               _iwl_write_restricted_reg(priv, reg_offset,
+               _iwl4965_write_prph(priv, reg_offset,
                                          le32_to_cpu(*image));
 
-       rc = iwl_verify_bsm(priv);
+       rc = iwl4965_verify_bsm(priv);
        if (rc) {
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
                return rc;
        }
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
-       iwl_write_restricted_reg(priv, BSM_WR_MEM_SRC_REG, 0x0);
-       iwl_write_restricted_reg(priv, BSM_WR_MEM_DST_REG,
+       iwl4965_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
+       iwl4965_write_prph(priv, BSM_WR_MEM_DST_REG,
                                 RTC_INST_LOWER_BOUND);
-       iwl_write_restricted_reg(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
+       iwl4965_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
 
        /* Load bootstrap code into instruction SRAM now,
         *   to prepare to load "initialize" uCode */
-       iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG,
+       iwl4965_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START);
 
        /* Wait for load of bootstrap uCode to finish */
        for (i = 0; i < 100; i++) {
-               done = iwl_read_restricted_reg(priv, BSM_WR_CTRL_REG);
+               done = iwl4965_read_prph(priv, BSM_WR_CTRL_REG);
                if (!(done & BSM_WR_CTRL_REG_BIT_START))
                        break;
                udelay(10);
@@ -6140,29 +6207,30 @@ static int iwl_load_bsm(struct iwl_priv *priv)
 
        /* Enable future boot loads whenever power management unit triggers it
         *   (e.g. when powering back up after power-save shutdown) */
-       iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG,
+       iwl4965_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START_EN);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 
        return 0;
 }
 
-static void iwl_nic_start(struct iwl_priv *priv)
+static void iwl4965_nic_start(struct iwl4965_priv *priv)
 {
        /* Remove all resets to allow NIC to operate */
-       iwl_write32(priv, CSR_RESET, 0);
+       iwl4965_write32(priv, CSR_RESET, 0);
 }
 
+
 /**
- * iwl_read_ucode - Read uCode images from disk file.
+ * iwl4965_read_ucode - Read uCode images from disk file.
  *
  * Copy into buffers for card to fetch via bus-mastering
  */
-static int iwl_read_ucode(struct iwl_priv *priv)
+static int iwl4965_read_ucode(struct iwl4965_priv *priv)
 {
-       struct iwl_ucode *ucode;
-       int rc = 0;
+       struct iwl4965_ucode *ucode;
+       int ret;
        const struct firmware *ucode_raw;
        const char *name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode";
        u8 *src;
@@ -6171,9 +6239,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
        /* Ask kernel firmware_class module to get the boot firmware off disk.
         * request_firmware() is synchronous, file is in memory on return. */
-       rc = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
-       if (rc < 0) {
-               IWL_ERROR("%s firmware file req failed: Reason %d\n", name, rc);
+       ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev);
+       if (ret < 0) {
+               IWL_ERROR("%s firmware file req failed: Reason %d\n",
+                                       name, ret);
                goto error;
        }
 
@@ -6183,7 +6252,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        /* Make sure that we got at least our header! */
        if (ucode_raw->size < sizeof(*ucode)) {
                IWL_ERROR("File size way too small!\n");
-               rc = -EINVAL;
+               ret = -EINVAL;
                goto err_release;
        }
 
@@ -6216,43 +6285,43 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
                IWL_DEBUG_INFO("uCode file size %d too small\n",
                               (int)ucode_raw->size);
-               rc = -EINVAL;
+               ret = -EINVAL;
                goto err_release;
        }
 
        /* Verify that uCode images will fit in card's SRAM */
        if (inst_size > IWL_MAX_INST_SIZE) {
-               IWL_DEBUG_INFO("uCode instr len %d too large to fit in card\n",
-                              (int)inst_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n",
+                              inst_size);
+               ret = -EINVAL;
                goto err_release;
        }
 
        if (data_size > IWL_MAX_DATA_SIZE) {
-               IWL_DEBUG_INFO("uCode data len %d too large to fit in card\n",
-                              (int)data_size);
-               rc = -EINVAL;
+               IWL_DEBUG_INFO("uCode data len %d too large to fit in\n",
+                               data_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (init_size > IWL_MAX_INST_SIZE) {
                IWL_DEBUG_INFO
-                   ("uCode init instr len %d too large to fit in card\n",
-                    (int)init_size);
-               rc = -EINVAL;
+                   ("uCode init instr len %d too large to fit in\n",
+                     init_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (init_data_size > IWL_MAX_DATA_SIZE) {
                IWL_DEBUG_INFO
-                   ("uCode init data len %d too large to fit in card\n",
-                    (int)init_data_size);
-               rc = -EINVAL;
+                   ("uCode init data len %d too large to fit in\n",
+                     init_data_size);
+               ret = -EINVAL;
                goto err_release;
        }
        if (boot_size > IWL_MAX_BSM_SIZE) {
                IWL_DEBUG_INFO
-                   ("uCode boot instr len %d too large to fit in bsm\n",
-                    (int)boot_size);
-               rc = -EINVAL;
+                   ("uCode boot instr len %d too large to fit in\n",
+                     boot_size);
+               ret = -EINVAL;
                goto err_release;
        }
 
@@ -6262,66 +6331,50 @@ static int iwl_read_ucode(struct iwl_priv *priv)
         * 1) unmodified from disk
         * 2) backup cache for save/restore during power-downs */
        priv->ucode_code.len = inst_size;
-       priv->ucode_code.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_code.len,
-                                &(priv->ucode_code.p_addr));
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
 
        priv->ucode_data.len = data_size;
-       priv->ucode_data.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_data.len,
-                                &(priv->ucode_data.p_addr));
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
 
        priv->ucode_data_backup.len = data_size;
-       priv->ucode_data_backup.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_data_backup.len,
-                                &(priv->ucode_data_backup.p_addr));
-
+       iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
 
        /* Initialization instructions and data */
-       priv->ucode_init.len = init_size;
-       priv->ucode_init.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_init.len,
-                                &(priv->ucode_init.p_addr));
-
-       priv->ucode_init_data.len = init_data_size;
-       priv->ucode_init_data.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_init_data.len,
-                                &(priv->ucode_init_data.p_addr));
+       if (init_size && init_data_size) {
+               priv->ucode_init.len = init_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
+
+               priv->ucode_init_data.len = init_data_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
+
+               if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
+                       goto err_pci_alloc;
+       }
 
        /* Bootstrap (instructions only, no data) */
-       priv->ucode_boot.len = boot_size;
-       priv->ucode_boot.v_addr =
-           pci_alloc_consistent(priv->pci_dev,
-                                priv->ucode_boot.len,
-                                &(priv->ucode_boot.p_addr));
+       if (boot_size) {
+               priv->ucode_boot.len = boot_size;
+               iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
 
-       if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
-           !priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr ||
-           !priv->ucode_boot.v_addr || !priv->ucode_data_backup.v_addr)
-               goto err_pci_alloc;
+               if (!priv->ucode_boot.v_addr)
+                       goto err_pci_alloc;
+       }
 
        /* Copy images into buffers for card's bus-master reads ... */
 
        /* Runtime instructions (first block of data in file) */
        src = &ucode->data[0];
        len = priv->ucode_code.len;
-       IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %d\n",
-                      (int)len);
+       IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len);
        memcpy(priv->ucode_code.v_addr, src, len);
        IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
                priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
 
        /* Runtime data (2nd block)
-        * NOTE:  Copy into backup buffer will be done in iwl_up()  */
+        * NOTE:  Copy into backup buffer will be done in iwl4965_up()  */
        src = &ucode->data[inst_size];
        len = priv->ucode_data.len;
-       IWL_DEBUG_INFO("Copying (but not loading) uCode data len %d\n",
-                      (int)len);
+       IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len);
        memcpy(priv->ucode_data.v_addr, src, len);
        memcpy(priv->ucode_data_backup.v_addr, src, len);
 
@@ -6329,8 +6382,8 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        if (init_size) {
                src = &ucode->data[inst_size + data_size];
                len = priv->ucode_init.len;
-               IWL_DEBUG_INFO("Copying (but not loading) init instr len %d\n",
-                              (int)len);
+               IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n",
+                               len);
                memcpy(priv->ucode_init.v_addr, src, len);
        }
 
@@ -6338,16 +6391,15 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        if (init_data_size) {
                src = &ucode->data[inst_size + data_size + init_size];
                len = priv->ucode_init_data.len;
-               IWL_DEBUG_INFO("Copying (but not loading) init data len %d\n",
-                              (int)len);
+               IWL_DEBUG_INFO("Copying (but not loading) init data len %Zd\n",
+                              len);
                memcpy(priv->ucode_init_data.v_addr, src, len);
        }
 
        /* Bootstrap instructions (5th block) */
        src = &ucode->data[inst_size + data_size + init_size + init_data_size];
        len = priv->ucode_boot.len;
-       IWL_DEBUG_INFO("Copying (but not loading) boot instr len %d\n",
-                      (int)len);
+       IWL_DEBUG_INFO("Copying (but not loading) boot instr len %Zd\n", len);
        memcpy(priv->ucode_boot.v_addr, src, len);
 
        /* We have our copies now, allow OS release its copies */
@@ -6356,19 +6408,19 @@ static int iwl_read_ucode(struct iwl_priv *priv)
 
  err_pci_alloc:
        IWL_ERROR("failed to allocate pci memory\n");
-       rc = -ENOMEM;
-       iwl_dealloc_ucode_pci(priv);
+       ret = -ENOMEM;
+       iwl4965_dealloc_ucode_pci(priv);
 
  err_release:
        release_firmware(ucode_raw);
 
  error:
-       return rc;
+       return ret;
 }
 
 
 /**
- * iwl_set_ucode_ptrs - Set uCode address location
+ * iwl4965_set_ucode_ptrs - Set uCode address location
  *
  * Tell initialization uCode where to find runtime uCode.
  *
@@ -6376,7 +6428,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
  * We need to replace them to load runtime uCode inst and data,
  * and to save runtime data when powering down.
  */
-static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
+static int iwl4965_set_ucode_ptrs(struct iwl4965_priv *priv)
 {
        dma_addr_t pinst;
        dma_addr_t pdata;
@@ -6388,24 +6440,24 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
        pdata = priv->ucode_data_backup.p_addr >> 4;
 
        spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_restricted_access(priv);
+       rc = iwl4965_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_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata);
-       iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+       iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+       iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+       iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
                                 priv->ucode_data.len);
 
        /* Inst bytecount must be last to set up, bit 31 signals uCode
         *   that all new ptr/size info is in place */
-       iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+       iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
 
-       iwl_release_restricted_access(priv);
+       iwl4965_release_nic_access(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -6415,7 +6467,7 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
 }
 
 /**
- * iwl_init_alive_start - Called after REPLY_ALIVE notification receieved
+ * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received
  *
  * Called after REPLY_ALIVE notification received from "initialize" uCode.
  *
@@ -6425,7 +6477,7 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv)
  *
  * Tell "initialize" uCode to go ahead and load the runtime uCode.
 */
-static void iwl_init_alive_start(struct iwl_priv *priv)
+static void iwl4965_init_alive_start(struct iwl4965_priv *priv)
 {
        /* Check alive response for "valid" sign from uCode */
        if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
@@ -6438,7 +6490,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
        /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
         * This is a paranoid check, because we would not have gotten the
         * "initialize" alive if code weren't properly loaded.  */
-       if (iwl_verify_ucode(priv)) {
+       if (iwl4965_verify_ucode(priv)) {
                /* Runtime instruction load was bad;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
@@ -6452,7 +6504,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
         * load and launch runtime uCode, which will send us another "Alive"
         * notification. */
        IWL_DEBUG_INFO("Initialization Alive received.\n");
-       if (iwl_set_ucode_ptrs(priv)) {
+       if (iwl4965_set_ucode_ptrs(priv)) {
                /* Runtime instruction load won't happen;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
@@ -6466,11 +6518,11 @@ static void iwl_init_alive_start(struct iwl_priv *priv)
 
 
 /**
- * iwl_alive_start - called after REPLY_ALIVE notification received
+ * iwl4965_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
- *                   Alive gets handled by iwl_init_alive_start()).
+ *                   Alive gets handled by iwl4965_init_alive_start()).
  */
-static void iwl_alive_start(struct iwl_priv *priv)
+static void iwl4965_alive_start(struct iwl4965_priv *priv)
 {
        int rc = 0;
 
@@ -6486,14 +6538,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
        /* Initialize uCode has loaded Runtime uCode ... verify inst image.
         * This is a paranoid check, because we would not have gotten the
         * "runtime" alive if code weren't properly loaded.  */
-       if (iwl_verify_ucode(priv)) {
+       if (iwl4965_verify_ucode(priv)) {
                /* Runtime instruction load was bad;
                 * take it all the way back down so we can try again */
                IWL_DEBUG_INFO("Bad runtime uCode load.\n");
                goto restart;
        }
 
-       iwl_clear_stations_table(priv);
+       iwl4965_clear_stations_table(priv);
 
        rc = iwl4965_alive_notify(priv);
        if (rc) {
@@ -6502,78 +6554,61 @@ static void iwl_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       /* After the ALIVE response, we can process host commands */
+       /* After the ALIVE response, we can send host commands to 4965 uCode */
        set_bit(STATUS_ALIVE, &priv->status);
 
        /* Clear out the uCode error bit if it is set */
        clear_bit(STATUS_FW_ERROR, &priv->status);
 
-       rc = iwl_init_channel_map(priv);
+       rc = iwl4965_init_channel_map(priv);
        if (rc) {
                IWL_ERROR("initializing regulatory failed: %d\n", rc);
                return;
        }
 
-       iwl_init_geos(priv);
+       iwl4965_init_geos(priv);
+       iwl4965_reset_channel_flag(priv);
 
-       if (iwl_is_rfkill(priv))
+       if (iwl4965_is_rfkill(priv))
                return;
 
-       if (!priv->mac80211_registered) {
-               /* Unlock so any user space entry points can call back into
-                * the driver without a deadlock... */
-               mutex_unlock(&priv->mutex);
-               iwl_rate_control_register(priv->hw);
-               rc = ieee80211_register_hw(priv->hw);
-               priv->hw->conf.beacon_int = 100;
-               mutex_lock(&priv->mutex);
-
-               if (rc) {
-                       iwl_rate_control_unregister(priv->hw);
-                       IWL_ERROR("Failed to register network "
-                                 "device (error %d)\n", rc);
-                       return;
-               }
-
-               priv->mac80211_registered = 1;
-
-               iwl_reset_channel_flag(priv);
-       } else
-               ieee80211_start_queues(priv->hw);
+       ieee80211_start_queues(priv->hw);
 
        priv->active_rate = priv->rates_mask;
        priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
 
-       iwl_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
+       iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
 
-       if (iwl_is_associated(priv)) {
-               struct iwl_rxon_cmd *active_rxon =
-                               (struct iwl_rxon_cmd *)(&priv->active_rxon);
+       if (iwl4965_is_associated(priv)) {
+               struct iwl4965_rxon_cmd *active_rxon =
+                               (struct iwl4965_rxon_cmd *)(&priv->active_rxon);
 
                memcpy(&priv->staging_rxon, &priv->active_rxon,
                       sizeof(priv->staging_rxon));
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        } else {
                /* Initialize our rx_config data */
-               iwl_connection_init_rx_config(priv);
+               iwl4965_connection_init_rx_config(priv);
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
-       /* Configure BT coexistence */
-       iwl_send_bt_config(priv);
+       /* Configure Bluetooth device coexistence support */
+       iwl4965_send_bt_config(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwl_commit_rxon(priv);
+       iwl4965_commit_rxon(priv);
 
        /* At this point, the NIC is initialized and operational */
        priv->notif_missed_beacons = 0;
        set_bit(STATUS_READY, &priv->status);
 
        iwl4965_rf_kill_ct_config(priv);
+
        IWL_DEBUG_INFO("ALIVE processing complete.\n");
+       wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
-               iwl_error_recovery(priv);
+               iwl4965_error_recovery(priv);
 
        return;
 
@@ -6581,9 +6616,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
        queue_work(priv->workqueue, &priv->restart);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv);
+static void iwl4965_cancel_deferred_work(struct iwl4965_priv *priv);
 
-static void __iwl_down(struct iwl_priv *priv)
+static void __iwl4965_down(struct iwl4965_priv *priv)
 {
        unsigned long flags;
        int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
@@ -6596,7 +6631,7 @@ static void __iwl_down(struct iwl_priv *priv)
        if (!exit_pending)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-       iwl_clear_stations_table(priv);
+       iwl4965_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
        wake_up_interruptible_all(&priv->wait_command_queue);
@@ -6607,17 +6642,17 @@ static void __iwl_down(struct iwl_priv *priv)
                clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
        /* stop and reset the on-board processor */
-       iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+       iwl4965_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 
        /* tell the device to stop sending interrupts */
-       iwl_disable_interrupts(priv);
+       iwl4965_disable_interrupts(priv);
 
        if (priv->mac80211_registered)
                ieee80211_stop_queues(priv->hw);
 
-       /* If we have not previously called iwl_init() then
+       /* If we have not previously called iwl4965_init() then
         * clear all bits but the RF Kill and SUSPEND bits and return */
-       if (!iwl_is_init(priv)) {
+       if (!iwl4965_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) <<
@@ -6639,53 +6674,52 @@ static void __iwl_down(struct iwl_priv *priv)
                                STATUS_FW_ERROR;
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       iwl4965_clear_bit(priv, CSR_GP_CNTRL,
+                        CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       iwl_hw_txq_ctx_stop(priv);
-       iwl_hw_rxq_stop(priv);
+       iwl4965_hw_txq_ctx_stop(priv);
+       iwl4965_hw_rxq_stop(priv);
 
        spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl_grab_restricted_access(priv)) {
-               iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG,
+       if (!iwl4965_grab_nic_access(priv)) {
+               iwl4965_write_prph(priv, APMG_CLK_DIS_REG,
                                         APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_restricted_access(priv);
+               iwl4965_release_nic_access(priv);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        udelay(5);
 
-       iwl_hw_nic_stop_master(priv);
-       iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-       iwl_hw_nic_reset(priv);
+       iwl4965_hw_nic_stop_master(priv);
+       iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       iwl4965_hw_nic_reset(priv);
 
  exit:
-       memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
+       memset(&priv->card_alive, 0, sizeof(struct iwl4965_alive_resp));
 
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
        priv->ibss_beacon = NULL;
 
        /* clear out any free frames */
-       iwl_clear_free_frames(priv);
+       iwl4965_clear_free_frames(priv);
 }
 
-static void iwl_down(struct iwl_priv *priv)
+static void iwl4965_down(struct iwl4965_priv *priv)
 {
        mutex_lock(&priv->mutex);
-       __iwl_down(priv);
+       __iwl4965_down(priv);
        mutex_unlock(&priv->mutex);
 
-       iwl_cancel_deferred_work(priv);
+       iwl4965_cancel_deferred_work(priv);
 }
 
 #define MAX_HW_RESTARTS 5
 
-static int __iwl_up(struct iwl_priv *priv)
+static int __iwl4965_up(struct iwl4965_priv *priv)
 {
-       DECLARE_MAC_BUF(mac);
        int rc, i;
-       u32 hw_rf_kill = 0;
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
                IWL_WARNING("Exit pending; will not bring the NIC up\n");
@@ -6695,7 +6729,19 @@ static int __iwl_up(struct iwl_priv *priv)
        if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
                IWL_WARNING("Radio disabled by SW RF kill (module "
                            "parameter)\n");
-               return 0;
+               return -ENODEV;
+       }
+
+       /* If platform's RF_KILL switch is NOT set to KILL */
+       if (iwl4965_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_IN_SUSPEND, &priv->status)) {
+                       IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+                       return -ENODEV;
+               }
        }
 
        if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
@@ -6703,53 +6749,45 @@ static int __iwl_up(struct iwl_priv *priv)
                return -EIO;
        }
 
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
 
-       rc = iwl_hw_nic_init(priv);
+       rc = iwl4965_hw_nic_init(priv);
        if (rc) {
                IWL_ERROR("Unable to int nic\n");
                return rc;
        }
 
        /* make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
        /* clear (again), then enable host interrupts */
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl_enable_interrupts(priv);
+       iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF);
+       iwl4965_enable_interrupts(priv);
 
        /* really make sure rfkill handshake bits are cleared */
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+       iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        /* Copy original ucode data image from disk into backup cache.
         * This will be used to initialize the on-board processor's
         * data SRAM for a clean start when the runtime program first loads. */
        memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
-                       priv->ucode_data.len);
+              priv->ucode_data.len);
 
-       /* If platform's RF_KILL switch is set to KILL,
-        * wait for BIT_INT_RF_KILL interrupt before loading uCode
-        * and getting things started */
-       if (!(iwl_read32(priv, CSR_GP_CNTRL) &
-                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-               hw_rf_kill = 1;
-
-       if (test_bit(STATUS_RF_KILL_HW, &priv->status) || hw_rf_kill) {
-               IWL_WARNING("Radio disabled by HW RF Kill switch\n");
+       /* We return success when we resume from suspend and rf_kill is on. */
+       if (test_bit(STATUS_RF_KILL_HW, &priv->status))
                return 0;
-       }
 
        for (i = 0; i < MAX_HW_RESTARTS; i++) {
 
-               iwl_clear_stations_table(priv);
+               iwl4965_clear_stations_table(priv);
 
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
                 * prepare to load the "initialize" uCode */
-               rc = iwl_load_bsm(priv);
+               rc = iwl4965_load_bsm(priv);
 
                if (rc) {
                        IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc);
@@ -6757,14 +6795,7 @@ static int __iwl_up(struct iwl_priv *priv)
                }
 
                /* start card; "initialize" will load runtime ucode */
-               iwl_nic_start(priv);
-
-               /* MAC Address location in EEPROM same for 3945/4965 */
-               get_eeprom_mac(priv, priv->mac_addr);
-               IWL_DEBUG_INFO("MAC address: %s\n",
-                              print_mac(mac, priv->mac_addr));
-
-               SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
+               iwl4965_nic_start(priv);
 
                IWL_DEBUG_INFO(DRV_NAME " is coming up\n");
 
@@ -6772,7 +6803,7 @@ static int __iwl_up(struct iwl_priv *priv)
        }
 
        set_bit(STATUS_EXIT_PENDING, &priv->status);
-       __iwl_down(priv);
+       __iwl4965_down(priv);
 
        /* tried to restart and config the device for as long as our
         * patience could withstand */
@@ -6787,35 +6818,35 @@ static int __iwl_up(struct iwl_priv *priv)
  *
  *****************************************************************************/
 
-static void iwl_bg_init_alive_start(struct work_struct *data)
+static void iwl4965_bg_init_alive_start(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, init_alive_start.work);
+       struct iwl4965_priv *priv =
+           container_of(data, struct iwl4965_priv, init_alive_start.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_init_alive_start(priv);
+       iwl4965_init_alive_start(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_alive_start(struct work_struct *data)
+static void iwl4965_bg_alive_start(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, alive_start.work);
+       struct iwl4965_priv *priv =
+           container_of(data, struct iwl4965_priv, alive_start.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_alive_start(priv);
+       iwl4965_alive_start(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_rf_kill(struct work_struct *work)
+static void iwl4965_bg_rf_kill(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, rf_kill);
 
        wake_up_interruptible(&priv->wait_command_queue);
 
@@ -6824,7 +6855,7 @@ static void iwl_bg_rf_kill(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_rfkill(priv)) {
+       if (!iwl4965_is_rfkill(priv)) {
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
                          "HW and/or SW RF Kill no longer active, restarting "
                          "device\n");
@@ -6845,10 +6876,10 @@ static void iwl_bg_rf_kill(struct work_struct *work)
 
 #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
 
-static void iwl_bg_scan_check(struct work_struct *data)
+static void iwl4965_bg_scan_check(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, scan_check.work);
+       struct iwl4965_priv *priv =
+           container_of(data, struct iwl4965_priv, scan_check.work);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
@@ -6861,22 +6892,22 @@ static void iwl_bg_scan_check(struct work_struct *data)
                          jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
 
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-                       iwl_send_scan_abort(priv);
+                       iwl4965_send_scan_abort(priv);
        }
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_request_scan(struct work_struct *data)
+static void iwl4965_bg_request_scan(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, request_scan);
-       struct iwl_host_cmd cmd = {
+       struct iwl4965_priv *priv =
+           container_of(data, struct iwl4965_priv, request_scan);
+       struct iwl4965_host_cmd cmd = {
                .id = REPLY_SCAN_CMD,
-               .len = sizeof(struct iwl_scan_cmd),
+               .len = sizeof(struct iwl4965_scan_cmd),
                .meta.flags = CMD_SIZE_HUGE,
        };
        int rc = 0;
-       struct iwl_scan_cmd *scan;
+       struct iwl4965_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
        u8 direct_mask;
        int phymode;
@@ -6885,7 +6916,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_ready(priv)) {
+       if (!iwl4965_is_ready(priv)) {
                IWL_WARNING("request scan called when driver not ready.\n");
                goto done;
        }
@@ -6914,7 +6945,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                goto done;
        }
 
-       if (iwl_is_rfkill(priv)) {
+       if (iwl4965_is_rfkill(priv)) {
                IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
                goto done;
        }
@@ -6930,7 +6961,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
        }
 
        if (!priv->scan) {
-               priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
+               priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) +
                                     IWL_MAX_SCAN_SIZE, GFP_KERNEL);
                if (!priv->scan) {
                        rc = -ENOMEM;
@@ -6938,12 +6969,12 @@ static void iwl_bg_request_scan(struct work_struct *data)
                }
        }
        scan = priv->scan;
-       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+       memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE);
 
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
        scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
 
-       if (iwl_is_associated(priv)) {
+       if (iwl4965_is_associated(priv)) {
                u16 interval = 0;
                u32 extra;
                u32 suspend_time = 100;
@@ -6973,14 +7004,14 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (priv->one_direct_scan) {
                IWL_DEBUG_SCAN
                    ("Kicking off one direct scan for '%s'\n",
-                    iwl_escape_essid(priv->direct_ssid,
+                    iwl4965_escape_essid(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);
                direct_mask = 1;
-       } else if (!iwl_is_associated(priv) && priv->essid_len) {
+       } else if (!iwl4965_is_associated(priv) && priv->essid_len) {
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->essid_len;
                memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
@@ -6991,7 +7022,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
        /* We don't build a direct scan probe request; the uCode will do
         * that based on the direct_mask added to each channel entry */
        scan->tx_cmd.len = cpu_to_le16(
-               iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
+               iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
                        IWL_MAX_SCAN_SIZE - sizeof(scan), 0));
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
@@ -7005,7 +7036,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
        case 2:
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate_n_flags =
-                               iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
+                               iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
                                RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
 
                scan->good_CRC_th = 0;
@@ -7014,7 +7045,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
 
        case 1:
                scan->tx_cmd.rate_n_flags =
-                               iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+                               iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
                                RATE_MCS_ANT_B_MSK);
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
                phymode = MODE_IEEE80211A;
@@ -7041,23 +7072,23 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (direct_mask)
                IWL_DEBUG_SCAN
                    ("Initiating direct scan for %s.\n",
-                    iwl_escape_essid(priv->essid, priv->essid_len));
+                    iwl4965_escape_essid(priv->essid, priv->essid_len));
        else
                IWL_DEBUG_SCAN("Initiating indirect scan.\n");
 
        scan->channel_count =
-               iwl_get_channels_for_scan(
+               iwl4965_get_channels_for_scan(
                        priv, phymode, 1, /* active */
                        direct_mask,
                        (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
        cmd.len += le16_to_cpu(scan->tx_cmd.len) +
-           scan->channel_count * sizeof(struct iwl_scan_channel);
+           scan->channel_count * sizeof(struct iwl4965_scan_channel);
        cmd.data = scan;
        scan->len = cpu_to_le16(cmd.len);
 
        set_bit(STATUS_SCAN_HW, &priv->status);
-       rc = iwl_send_cmd_sync(priv, &cmd);
+       rc = iwl4965_send_cmd_sync(priv, &cmd);
        if (rc)
                goto done;
 
@@ -7068,50 +7099,52 @@ static void iwl_bg_request_scan(struct work_struct *data)
        return;
 
  done:
-       /* inform mac80211 sacn aborted */
+       /* inform mac80211 scan aborted */
        queue_work(priv->workqueue, &priv->scan_completed);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_up(struct work_struct *data)
+static void iwl4965_bg_up(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
+       struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, up);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       __iwl_up(priv);
+       __iwl4965_up(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_restart(struct work_struct *data)
+static void iwl4965_bg_restart(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
+       struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, restart);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl_down(priv);
+       iwl4965_down(priv);
        queue_work(priv->workqueue, &priv->up);
 }
 
-static void iwl_bg_rx_replenish(struct work_struct *data)
+static void iwl4965_bg_rx_replenish(struct work_struct *data)
 {
-       struct iwl_priv *priv =
-           container_of(data, struct iwl_priv, rx_replenish);
+       struct iwl4965_priv *priv =
+           container_of(data, struct iwl4965_priv, rx_replenish);
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
        mutex_lock(&priv->mutex);
-       iwl_rx_replenish(priv);
+       iwl4965_rx_replenish(priv);
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_post_associate(struct work_struct *data)
+#define IWL_DELAY_NEXT_SCAN (HZ*2)
+
+static void iwl4965_bg_post_associate(struct work_struct *data)
 {
-       struct iwl_priv *priv = container_of(data, struct iwl_priv,
+       struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv,
                                             post_associate.work);
 
        int rc = 0;
@@ -7133,20 +7166,20 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
-       if (!priv->interface_id || !priv->is_open) {
+       if (!priv->vif || !priv->is_open) {
                mutex_unlock(&priv->mutex);
                return;
        }
-       iwl_scan_cancel_timeout(priv, 200);
+       iwl4965_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);
+       iwl4965_commit_rxon(priv);
 
-       memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-       iwl_setup_rxon_timing(priv);
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+       memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
+       iwl4965_setup_rxon_timing(priv);
+       rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                              sizeof(priv->rxon_timing), &priv->rxon_timing);
        if (rc)
                IWL_WARNING("REPLY_RXON_TIMING failed - "
@@ -7154,15 +7187,10 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
-#ifdef CONFIG_IWLWIFI_HT
-       if (priv->is_ht_enabled && priv->current_assoc_ht.is_ht)
-               iwl4965_set_rxon_ht(priv, &priv->current_assoc_ht);
-       else {
-               priv->active_rate_ht[0] = 0;
-               priv->active_rate_ht[1] = 0;
-               priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ;
-       }
-#endif /* CONFIG_IWLWIFI_HT*/
+#ifdef CONFIG_IWL4965_HT
+       if (priv->current_ht_config.is_ht)
+               iwl4965_set_rxon_ht(priv, &priv->current_ht_config);
+#endif /* CONFIG_IWL4965_HT*/
        iwl4965_set_rxon_chain(priv);
        priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
 
@@ -7185,22 +7213,22 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        }
 
-       iwl_commit_rxon(priv);
+       iwl4965_commit_rxon(priv);
 
        switch (priv->iw_mode) {
        case IEEE80211_IF_TYPE_STA:
-               iwl_rate_scale_init(priv->hw, IWL_AP_ID);
+               iwl4965_rate_scale_init(priv->hw, IWL_AP_ID);
                break;
 
        case IEEE80211_IF_TYPE_IBSS:
 
                /* clear out the station table */
-               iwl_clear_stations_table(priv);
+               iwl4965_clear_stations_table(priv);
 
-               iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-               iwl_rxon_add_station(priv, priv->bssid, 0);
-               iwl_rate_scale_init(priv->hw, IWL_STA_ID);
-               iwl_send_beacon_cmd(priv);
+               iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0);
+               iwl4965_rxon_add_station(priv, priv->bssid, 0);
+               iwl4965_rate_scale_init(priv->hw, IWL_STA_ID);
+               iwl4965_send_beacon_cmd(priv);
 
                break;
 
@@ -7210,55 +7238,61 @@ static void iwl_bg_post_associate(struct work_struct *data)
                break;
        }
 
-       iwl_sequence_reset(priv);
+       iwl4965_sequence_reset(priv);
 
-#ifdef CONFIG_IWLWIFI_SENSITIVITY
+#ifdef CONFIG_IWL4965_SENSITIVITY
        /* Enable Rx differential gain and sensitivity calibrations */
        iwl4965_chain_noise_reset(priv);
        priv->start_calib = 1;
-#endif /* CONFIG_IWLWIFI_SENSITIVITY */
+#endif /* CONFIG_IWL4965_SENSITIVITY */
 
        if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
                priv->assoc_station_added = 1;
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_activate_qos(priv, 0);
-#endif /* CONFIG_IWLWIFI_QOS */
+#ifdef CONFIG_IWL4965_QOS
+       iwl4965_activate_qos(priv, 0);
+#endif /* CONFIG_IWL4965_QOS */
+       /* we have just associated, don't start scan too early */
+       priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_abort_scan(struct work_struct *work)
+static void iwl4965_bg_abort_scan(struct work_struct *work)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv,
-                                            abort_scan);
+       struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, abort_scan);
 
-       if (!iwl_is_ready(priv))
+       if (!iwl4965_is_ready(priv))
                return;
 
        mutex_lock(&priv->mutex);
 
        set_bit(STATUS_SCAN_ABORTING, &priv->status);
-       iwl_send_scan_abort(priv);
+       iwl4965_send_scan_abort(priv);
 
        mutex_unlock(&priv->mutex);
 }
 
-static void iwl_bg_scan_completed(struct work_struct *work)
+static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+
+static void iwl4965_bg_scan_completed(struct work_struct *work)
 {
-       struct iwl_priv *priv =
-           container_of(work, struct iwl_priv, scan_completed);
+       struct iwl4965_priv *priv =
+           container_of(work, struct iwl4965_priv, scan_completed);
 
        IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       if (test_bit(STATUS_CONF_PENDING, &priv->status))
+               iwl4965_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
+
        ieee80211_scan_completed(priv->hw);
 
        /* Since setting the TXPOWER may have been deferred while
         * performing the scan, fire one off */
        mutex_lock(&priv->mutex);
-       iwl_hw_reg_send_txpower(priv);
+       iwl4965_hw_reg_send_txpower(priv);
        mutex_unlock(&priv->mutex);
 }
 
@@ -7268,50 +7302,123 @@ static void iwl_bg_scan_completed(struct work_struct *work)
  *
  *****************************************************************************/
 
-static int iwl_mac_start(struct ieee80211_hw *hw)
+#define UCODE_READY_TIMEOUT    (2 * HZ)
+
+static int iwl4965_mac_start(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
+       int ret;
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       if (pci_enable_device(priv->pci_dev)) {
+               IWL_ERROR("Fail to pci_enable_device\n");
+               return -ENODEV;
+       }
+       pci_restore_state(priv->pci_dev);
+       pci_enable_msi(priv->pci_dev);
+
+       ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED,
+                         DRV_NAME, priv);
+       if (ret) {
+               IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq);
+               goto out_disable_msi;
+       }
+
        /* we should be verifying the device is ready to be opened */
        mutex_lock(&priv->mutex);
 
-       priv->is_open = 1;
+       memset(&priv->staging_rxon, 0, sizeof(struct iwl4965_rxon_cmd));
+       /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
+        * ucode filename and max sizes are card-specific. */
+
+       if (!priv->ucode_code.len) {
+               ret = iwl4965_read_ucode(priv);
+               if (ret) {
+                       IWL_ERROR("Could not read microcode: %d\n", ret);
+                       mutex_unlock(&priv->mutex);
+                       goto out_release_irq;
+               }
+       }
 
-       if (!iwl_is_rfkill(priv))
-               ieee80211_start_queues(priv->hw);
+       ret = __iwl4965_up(priv);
 
        mutex_unlock(&priv->mutex);
+
+       if (ret)
+               goto out_release_irq;
+
+       IWL_DEBUG_INFO("Start UP work done.\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,
+                       test_bit(STATUS_READY, &priv->status),
+                       UCODE_READY_TIMEOUT);
+       if (!ret) {
+               if (!test_bit(STATUS_READY, &priv->status)) {
+                       IWL_ERROR("Wait for START_ALIVE timeout after %dms.\n",
+                                 jiffies_to_msecs(UCODE_READY_TIMEOUT));
+                       ret = -ETIMEDOUT;
+                       goto out_release_irq;
+               }
+       }
+
+       priv->is_open = 1;
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
+
+out_release_irq:
+       free_irq(priv->pci_dev->irq, priv);
+out_disable_msi:
+       pci_disable_msi(priv->pci_dev);
+       pci_disable_device(priv->pci_dev);
+       priv->is_open = 0;
+       IWL_DEBUG_MAC80211("leave - failed\n");
+       return ret;
 }
 
-static void iwl_mac_stop(struct ieee80211_hw *hw)
+static void iwl4965_mac_stop(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       if (!priv->is_open) {
+               IWL_DEBUG_MAC80211("leave - skip\n");
+               return;
+       }
 
-       mutex_lock(&priv->mutex);
-       /* stop mac, cancel any scan request and clear
-        * RXON_FILTER_ASSOC_MSK BIT
-        */
        priv->is_open = 0;
-       iwl_scan_cancel_timeout(priv, 100);
-       cancel_delayed_work(&priv->post_associate);
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
-       mutex_unlock(&priv->mutex);
+
+       if (iwl4965_is_ready_rf(priv)) {
+               /* stop mac, cancel any scan request and clear
+                * RXON_FILTER_ASSOC_MSK BIT
+                */
+               mutex_lock(&priv->mutex);
+               iwl4965_scan_cancel_timeout(priv, 100);
+               cancel_delayed_work(&priv->post_associate);
+               mutex_unlock(&priv->mutex);
+       }
+
+       iwl4965_down(priv);
+
+       flush_workqueue(priv->workqueue);
+       free_irq(priv->pci_dev->irq, priv);
+       pci_disable_msi(priv->pci_dev);
+       pci_save_state(priv->pci_dev);
+       pci_disable_device(priv->pci_dev);
 
        IWL_DEBUG_MAC80211("leave\n");
 }
 
-static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
                      struct ieee80211_tx_control *ctl)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -7323,29 +7430,29 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
                     ctl->tx_rate);
 
-       if (iwl_tx_skb(priv, skb, ctl))
+       if (iwl4965_tx_skb(priv, skb, ctl))
                dev_kfree_skb_any(skb);
 
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
+static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
                                 struct ieee80211_if_init_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        unsigned long flags;
        DECLARE_MAC_BUF(mac);
 
-       IWL_DEBUG_MAC80211("enter: id %d, type %d\n", conf->if_id, conf->type);
+       IWL_DEBUG_MAC80211("enter: type %d\n", conf->type);
 
-       if (priv->interface_id) {
-               IWL_DEBUG_MAC80211("leave - interface_id != 0\n");
+       if (priv->vif) {
+               IWL_DEBUG_MAC80211("leave - vif != NULL\n");
                return 0;
        }
 
        spin_lock_irqsave(&priv->lock, flags);
-       priv->interface_id = conf->if_id;
+       priv->vif = conf->vif;
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -7355,58 +7462,62 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw,
                IWL_DEBUG_MAC80211("Set %s\n", print_mac(mac, conf->mac_addr));
                memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
        }
-       iwl_set_mode(priv, conf->type);
 
-       IWL_DEBUG_MAC80211("leave\n");
+       if (iwl4965_is_ready(priv))
+               iwl4965_set_mode(priv, conf->type);
+
        mutex_unlock(&priv->mutex);
 
+       IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
 /**
- * iwl_mac_config - mac80211 config callback
+ * iwl4965_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, struct ieee80211_conf *conf)
+static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
-       const struct iwl_channel_info *ch_info;
+       struct iwl4965_priv *priv = hw->priv;
+       const struct iwl4965_channel_info *ch_info;
        unsigned long flags;
+       int ret = 0;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
 
-       if (!iwl_is_ready(priv)) {
+       priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+
+       if (!iwl4965_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
-       /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only
-        * what is exposed through include/ declrations */
-       if (unlikely(!iwl_param_disable_hw_scan &&
+       if (unlikely(!iwl4965_param_disable_hw_scan &&
                     test_bit(STATUS_SCANNING, &priv->status))) {
                IWL_DEBUG_MAC80211("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->phymode, conf->channel);
+       ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel);
        if (!is_channel_valid(ch_info)) {
                IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
                               conf->channel, conf->phymode);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
-               mutex_unlock(&priv->mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out;
        }
 
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
        /* if we are switching fron ht to 2.4 clear flags
         * from any ht related info since 2.4 does not
         * support ht */
@@ -7416,57 +7527,56 @@ static int iwl_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 #endif
        )
                priv->staging_rxon.flags = 0;
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT */
 
-       iwl_set_rxon_channel(priv, conf->phymode, conf->channel);
+       iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel);
 
-       iwl_set_flags_for_phymode(priv, conf->phymode);
+       iwl4965_set_flags_for_phymode(priv, conf->phymode);
 
        /* 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);
+       iwl4965_set_rate(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
 #ifdef IEEE80211_CONF_CHANNEL_SWITCH
        if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
-               iwl_hw_channel_switch(priv, conf->channel);
-               mutex_unlock(&priv->mutex);
-               return 0;
+               iwl4965_hw_channel_switch(priv, conf->channel);
+               goto out;
        }
 #endif
 
-       iwl_radio_kill_sw(priv, !conf->radio_enabled);
+       iwl4965_radio_kill_sw(priv, !conf->radio_enabled);
 
        if (!conf->radio_enabled) {
                IWL_DEBUG_MAC80211("leave - radio disabled\n");
-               mutex_unlock(&priv->mutex);
-               return 0;
+               goto out;
        }
 
-       if (iwl_is_rfkill(priv)) {
+       if (iwl4965_is_rfkill(priv)) {
                IWL_DEBUG_MAC80211("leave - RF kill\n");
-               mutex_unlock(&priv->mutex);
-               return -EIO;
+               ret = -EIO;
+               goto out;
        }
 
-       iwl_set_rate(priv);
+       iwl4965_set_rate(priv);
 
        if (memcmp(&priv->active_rxon,
                   &priv->staging_rxon, sizeof(priv->staging_rxon)))
-               iwl_commit_rxon(priv);
+               iwl4965_commit_rxon(priv);
        else
                IWL_DEBUG_INFO("No re-sending same RXON configuration.\n");
 
        IWL_DEBUG_MAC80211("leave\n");
 
+out:
+       clear_bit(STATUS_CONF_PENDING, &priv->status);
        mutex_unlock(&priv->mutex);
-
-       return 0;
+       return ret;
 }
 
-static void iwl_config_ap(struct iwl_priv *priv)
+static void iwl4965_config_ap(struct iwl4965_priv *priv)
 {
        int rc = 0;
 
@@ -7478,12 +7588,12 @@ 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);
+               iwl4965_commit_rxon(priv);
 
                /* RXON Timing */
-               memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
-               iwl_setup_rxon_timing(priv);
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
+               memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
+               iwl4965_setup_rxon_timing(priv);
+               rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON_TIMING,
                                sizeof(priv->rxon_timing), &priv->rxon_timing);
                if (rc)
                        IWL_WARNING("REPLY_RXON_TIMING failed - "
@@ -7515,23 +7625,24 @@ 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);
-#ifdef CONFIG_IWLWIFI_QOS
-               iwl_activate_qos(priv, 1);
+               iwl4965_commit_rxon(priv);
+#ifdef CONFIG_IWL4965_QOS
+               iwl4965_activate_qos(priv, 1);
 #endif
-               iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
+               iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0);
        }
-       iwl_send_beacon_cmd(priv);
+       iwl4965_send_beacon_cmd(priv);
 
        /* FIXME - we need to add code here to detect a totally new
         * configuration, reset the AP, unassoc, rxon timing, assoc,
         * clear sta table, add BCAST sta... */
 }
 
-static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
+static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
+                                       struct ieee80211_vif *vif,
                                    struct ieee80211_if_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        DECLARE_MAC_BUF(mac);
        unsigned long flags;
        int rc;
@@ -7546,9 +7657,11 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                return 0;
        }
 
+       if (!iwl4965_is_alive(priv))
+               return -EAGAIN;
+
        mutex_lock(&priv->mutex);
 
-       IWL_DEBUG_MAC80211("enter: interface id %d\n", if_id);
        if (conf->bssid)
                IWL_DEBUG_MAC80211("bssid: %s\n",
                                   print_mac(mac, conf->bssid));
@@ -7565,8 +7678,8 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                return 0;
        }
 
-       if (priv->interface_id != if_id) {
-               IWL_DEBUG_MAC80211("leave - interface_id != if_id\n");
+       if (priv->vif != vif) {
+               IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
                mutex_unlock(&priv->mutex);
                return 0;
        }
@@ -7584,11 +7697,14 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                priv->ibss_beacon = conf->beacon;
        }
 
+       if (iwl4965_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)) {
+               if (iwl4965_scan_cancel_timeout(priv, 100)) {
                        IWL_WARNING("Aborted scan still in progress "
                                    "after 100ms\n");
                        IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
@@ -7604,20 +7720,21 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
 
                if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
-                       iwl_config_ap(priv);
+                       iwl4965_config_ap(priv);
                else {
-                       rc = iwl_commit_rxon(priv);
+                       rc = iwl4965_commit_rxon(priv);
                        if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
-                               iwl_rxon_add_station(
+                               iwl4965_rxon_add_station(
                                        priv, priv->active_rxon.bssid_addr, 1);
                }
 
        } else {
-               iwl_scan_cancel_timeout(priv, 100);
+               iwl4965_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwl4965_commit_rxon(priv);
        }
 
+ done:
        spin_lock_irqsave(&priv->lock, flags);
        if (!conf->ssid_len)
                memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
@@ -7633,34 +7750,35 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
        return 0;
 }
 
-static void iwl_configure_filter(struct ieee80211_hw *hw,
+static void iwl4965_configure_filter(struct ieee80211_hw *hw,
                                 unsigned int changed_flags,
                                 unsigned int *total_flags,
                                 int mc_count, struct dev_addr_list *mc_list)
 {
        /*
         * XXX: dummy
-        * see also iwl_connection_init_rx_config
+        * see also iwl4965_connection_init_rx_config
         */
        *total_flags = 0;
 }
 
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
                                     struct ieee80211_if_init_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
 
-       iwl_scan_cancel_timeout(priv, 100);
-       cancel_delayed_work(&priv->post_associate);
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
-
-       if (priv->interface_id == conf->if_id) {
-               priv->interface_id = 0;
+       if (iwl4965_is_ready_rf(priv)) {
+               iwl4965_scan_cancel_timeout(priv, 100);
+               cancel_delayed_work(&priv->post_associate);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwl4965_commit_rxon(priv);
+       }
+       if (priv->vif == conf->vif) {
+               priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
                memset(priv->essid, 0, IW_ESSID_MAX_SIZE);
                priv->essid_len = 0;
@@ -7671,19 +7789,50 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 
 }
 
-#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *bss_conf,
+                                    u32 changes)
+{
+       struct iwl4965_priv *priv = hw->priv;
+
+       if (changes & BSS_CHANGED_ERP_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) {
+               if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A))
+                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+               else
+                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+       }
+
+       if (changes & BSS_CHANGED_ASSOC) {
+               /*
+                * TODO:
+                * do stuff instead of sniffing assoc resp
+                */
+       }
+
+       if (iwl4965_is_associated(priv))
+               iwl4965_send_rxon_assoc(priv);
+}
+
+static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 {
        int rc = 0;
        unsigned long flags;
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
        spin_lock_irqsave(&priv->lock, flags);
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl4965_is_ready_rf(priv)) {
                rc = -EIO;
                IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
                goto out_unlock;
@@ -7695,17 +7844,21 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
                goto out_unlock;
        }
 
+       /* we don't schedule scan within next_scan_jiffies period */
+       if (priv->next_scan_jiffies &&
+                       time_after(priv->next_scan_jiffies, jiffies)) {
+               rc = -EAGAIN;
+               goto out_unlock;
+       }
        /* if we just finished scan ask for delay */
-       if (priv->last_scan_jiffies &&
-           time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN,
-                      jiffies)) {
+       if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
+                               IWL_DELAY_NEXT_SCAN, jiffies)) {
                rc = -EAGAIN;
                goto out_unlock;
        }
        if (len) {
-               IWL_DEBUG_SCAN("direct scan for  "
-                              "%s [%d]\n ",
-                              iwl_escape_essid(ssid, len), (int)len);
+               IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
+                              iwl4965_escape_essid(ssid, len), (int)len);
 
                priv->one_direct_scan = 1;
                priv->direct_ssid_len = (u8)
@@ -7714,7 +7867,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
        } else
                priv->one_direct_scan = 0;
 
-       rc = iwl_scan_initiate(priv);
+       rc = iwl4965_scan_initiate(priv);
 
        IWL_DEBUG_MAC80211("leave\n");
 
@@ -7725,18 +7878,18 @@ out_unlock:
        return rc;
 }
 
-static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                           const u8 *local_addr, const u8 *addr,
                           struct ieee80211_key_conf *key)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        DECLARE_MAC_BUF(mac);
        int rc = 0;
        u8 sta_id;
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_param_hwcrypto) {
+       if (!iwl4965_param_hwcrypto) {
                IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n");
                return -EOPNOTSUPP;
        }
@@ -7745,7 +7898,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                /* only support pairwise keys */
                return -EOPNOTSUPP;
 
-       sta_id = iwl_hw_find_station(priv, addr);
+       sta_id = iwl4965_hw_find_station(priv, addr);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_DEBUG_MAC80211("leave - %s not in station map.\n",
                                   print_mac(mac, addr));
@@ -7754,24 +7907,24 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        mutex_lock(&priv->mutex);
 
-       iwl_scan_cancel_timeout(priv, 100);
+       iwl4965_scan_cancel_timeout(priv, 100);
 
        switch (cmd) {
        case  SET_KEY:
-               rc = iwl_update_sta_key_info(priv, key, sta_id);
+               rc = iwl4965_update_sta_key_info(priv, key, sta_id);
                if (!rc) {
-                       iwl_set_rxon_hwcrypto(priv, 1);
-                       iwl_commit_rxon(priv);
+                       iwl4965_set_rxon_hwcrypto(priv, 1);
+                       iwl4965_commit_rxon(priv);
                        key->hw_key_idx = sta_id;
                        IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n");
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                }
                break;
        case DISABLE_KEY:
-               rc = iwl_clear_sta_key_info(priv, sta_id);
+               rc = iwl4965_clear_sta_key_info(priv, sta_id);
                if (!rc) {
-                       iwl_set_rxon_hwcrypto(priv, 0);
-                       iwl_commit_rxon(priv);
+                       iwl4965_set_rxon_hwcrypto(priv, 0);
+                       iwl4965_commit_rxon(priv);
                        IWL_DEBUG_MAC80211("disable hwcrypto key\n");
                }
                break;
@@ -7785,18 +7938,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return rc;
 }
 
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
+static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                           const struct ieee80211_tx_queue_params *params)
 {
-       struct iwl_priv *priv = hw->priv;
-#ifdef CONFIG_IWLWIFI_QOS
+       struct iwl4965_priv *priv = hw->priv;
+#ifdef CONFIG_IWL4965_QOS
        unsigned long flags;
        int q;
-#endif /* CONFIG_IWL_QOS */
+#endif /* CONFIG_IWL4965_QOS */
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl4965_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7806,7 +7959,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
                return 0;
        }
 
-#ifdef CONFIG_IWLWIFI_QOS
+#ifdef CONFIG_IWL4965_QOS
        if (!priv->qos_data.qos_enable) {
                priv->qos_data.qos_active = 0;
                IWL_DEBUG_MAC80211("leave - qos not enabled\n");
@@ -7829,30 +7982,30 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue,
 
        mutex_lock(&priv->mutex);
        if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
-               iwl_activate_qos(priv, 1);
-       else if (priv->assoc_id && iwl_is_associated(priv))
-               iwl_activate_qos(priv, 0);
+               iwl4965_activate_qos(priv, 1);
+       else if (priv->assoc_id && iwl4965_is_associated(priv))
+               iwl4965_activate_qos(priv, 0);
 
        mutex_unlock(&priv->mutex);
 
-#endif /*CONFIG_IWLWIFI_QOS */
+#endif /*CONFIG_IWL4965_QOS */
 
        IWL_DEBUG_MAC80211("leave\n");
        return 0;
 }
 
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
                                struct ieee80211_tx_queue_stats *stats)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        int i, avail;
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
+       struct iwl4965_tx_queue *txq;
+       struct iwl4965_queue *q;
        unsigned long flags;
 
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl4965_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                return -EIO;
        }
@@ -7862,7 +8015,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
        for (i = 0; i < AC_NUM; i++) {
                txq = &priv->txq[i];
                q = &txq->q;
-               avail = iwl_queue_space(q);
+               avail = iwl4965_queue_space(q);
 
                stats->data[i].len = q->n_window - avail;
                stats->data[i].limit = q->n_window - q->high_mark;
@@ -7876,7 +8029,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int iwl_mac_get_stats(struct ieee80211_hw *hw,
+static int iwl4965_mac_get_stats(struct ieee80211_hw *hw,
                             struct ieee80211_low_level_stats *stats)
 {
        IWL_DEBUG_MAC80211("enter\n");
@@ -7885,7 +8038,7 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw)
+static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw)
 {
        IWL_DEBUG_MAC80211("enter\n");
        IWL_DEBUG_MAC80211("leave\n");
@@ -7893,35 +8046,35 @@ static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw)
        return 0;
 }
 
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        unsigned long flags;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
        priv->lq_mngr.lq_ready = 0;
-#ifdef CONFIG_IWLWIFI_HT
+#ifdef CONFIG_IWL4965_HT
        spin_lock_irqsave(&priv->lock, flags);
-       memset(&priv->current_assoc_ht, 0, sizeof(struct sta_ht_info));
+       memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
        spin_unlock_irqrestore(&priv->lock, flags);
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT_AGG
 /*     if (priv->lq_mngr.agg_ctrl.granted_ba)
                iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/
 
-       memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl_agg_control));
+       memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control));
        priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10;
        priv->lq_mngr.agg_ctrl.ba_timeout = 5000;
        priv->lq_mngr.agg_ctrl.auto_agg = 1;
 
        if (priv->lq_mngr.agg_ctrl.auto_agg)
                priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED;
-#endif /*CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /*CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_reset_qos(priv);
+#ifdef CONFIG_IWL4965_QOS
+       iwl4965_reset_qos(priv);
 #endif
 
        cancel_delayed_work(&priv->post_associate);
@@ -7946,13 +8099,19 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       if (!iwl4965_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211("leave - not ready\n");
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+
        /* we are restarting association process
         * clear RXON_FILTER_ASSOC_MSK bit
         */
        if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
-               iwl_scan_cancel_timeout(priv, 100);
+               iwl4965_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwl4965_commit_rxon(priv);
        }
 
        /* Per mac80211.h: This is only used in IBSS mode... */
@@ -7963,32 +8122,25 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
                return;
        }
 
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211("leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
        priv->only_active_channel = 0;
 
-       iwl_set_rate(priv);
+       iwl4965_set_rate(priv);
 
        mutex_unlock(&priv->mutex);
 
        IWL_DEBUG_MAC80211("leave\n");
-
 }
 
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                                 struct ieee80211_tx_control *control)
 {
-       struct iwl_priv *priv = hw->priv;
+       struct iwl4965_priv *priv = hw->priv;
        unsigned long flags;
 
        mutex_lock(&priv->mutex);
        IWL_DEBUG_MAC80211("enter\n");
 
-       if (!iwl_is_ready_rf(priv)) {
+       if (!iwl4965_is_ready_rf(priv)) {
                IWL_DEBUG_MAC80211("leave - RF not ready\n");
                mutex_unlock(&priv->mutex);
                return -EIO;
@@ -8012,8 +8164,8 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        IWL_DEBUG_MAC80211("leave\n");
        spin_unlock_irqrestore(&priv->lock, flags);
 
-#ifdef CONFIG_IWLWIFI_QOS
-       iwl_reset_qos(priv);
+#ifdef CONFIG_IWL4965_QOS
+       iwl4965_reset_qos(priv);
 #endif
 
        queue_work(priv->workqueue, &priv->post_associate.work);
@@ -8023,133 +8175,62 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        return 0;
 }
 
-#ifdef CONFIG_IWLWIFI_HT
-union ht_cap_info {
-       struct {
-               u16 advanced_coding_cap         :1;
-               u16 supported_chan_width_set    :1;
-               u16 mimo_power_save_mode        :2;
-               u16 green_field                 :1;
-               u16 short_GI20                  :1;
-               u16 short_GI40                  :1;
-               u16 tx_stbc                     :1;
-               u16 rx_stbc                     :1;
-               u16 beam_forming                :1;
-               u16 delayed_ba                  :1;
-               u16 maximal_amsdu_size          :1;
-               u16 cck_mode_at_40MHz           :1;
-               u16 psmp_support                :1;
-               u16 stbc_ctrl_frame_support     :1;
-               u16 sig_txop_protection_support :1;
-       };
-       u16 val;
-} __attribute__ ((packed));
-
-union ht_param_info{
-       struct {
-               u8 max_rx_ampdu_factor  :2;
-               u8 mpdu_density         :3;
-               u8 reserved             :3;
-       };
-       u8 val;
-} __attribute__ ((packed));
-
-union ht_exra_param_info {
-       struct {
-               u8 ext_chan_offset              :2;
-               u8 tx_chan_width                :1;
-               u8 rifs_mode                    :1;
-               u8 controlled_access_only       :1;
-               u8 service_interval_granularity :3;
-       };
-       u8 val;
-} __attribute__ ((packed));
-
-union ht_operation_mode{
-       struct {
-               u16 op_mode     :2;
-               u16 non_GF      :1;
-               u16 reserved    :13;
-       };
-       u16 val;
-} __attribute__ ((packed));
-
+#ifdef CONFIG_IWL4965_HT
 
-static int sta_ht_info_init(struct ieee80211_ht_capability *ht_cap,
-                           struct ieee80211_ht_additional_info *ht_extra,
-                           struct sta_ht_info *ht_info_ap,
-                           struct sta_ht_info *ht_info)
+static void iwl4965_ht_info_fill(struct ieee80211_conf *conf,
+                                struct iwl4965_priv *priv)
 {
-       union ht_cap_info cap;
-       union ht_operation_mode op_mode;
-       union ht_param_info param_info;
-       union ht_exra_param_info extra_param_info;
+       struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+       struct ieee80211_ht_info *ht_conf = &conf->ht_conf;
+       struct ieee80211_ht_bss_info *ht_bss_conf = &conf->ht_bss_conf;
 
        IWL_DEBUG_MAC80211("enter: \n");
 
-       if (!ht_info) {
-               IWL_DEBUG_MAC80211("leave: ht_info is NULL\n");
-               return -1;
+       if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) {
+               iwl_conf->is_ht = 0;
+               return;
        }
 
-       if (ht_cap) {
-               cap.val = (u16) le16_to_cpu(ht_cap->capabilities_info);
-               param_info.val = ht_cap->mac_ht_params_info;
-               ht_info->is_ht = 1;
-               if (cap.short_GI20)
-                       ht_info->sgf |= 0x1;
-               if (cap.short_GI40)
-                       ht_info->sgf |= 0x2;
-               ht_info->is_green_field = cap.green_field;
-               ht_info->max_amsdu_size = cap.maximal_amsdu_size;
-               ht_info->supported_chan_width = cap.supported_chan_width_set;
-               ht_info->tx_mimo_ps_mode = cap.mimo_power_save_mode;
-               memcpy(ht_info->supp_rates, ht_cap->supported_mcs_set, 16);
-
-               ht_info->ampdu_factor = param_info.max_rx_ampdu_factor;
-               ht_info->mpdu_density = param_info.mpdu_density;
-
-               IWL_DEBUG_MAC80211("SISO mask 0x%X MIMO mask 0x%X \n",
-                                   ht_cap->supported_mcs_set[0],
-                                   ht_cap->supported_mcs_set[1]);
-
-               if (ht_info_ap) {
-                       ht_info->control_channel = ht_info_ap->control_channel;
-                       ht_info->extension_chan_offset =
-                               ht_info_ap->extension_chan_offset;
-                       ht_info->tx_chan_width = ht_info_ap->tx_chan_width;
-                       ht_info->operating_mode = ht_info_ap->operating_mode;
-               }
-
-               if (ht_extra) {
-                       extra_param_info.val = ht_extra->ht_param;
-                       ht_info->control_channel = ht_extra->control_chan;
-                       ht_info->extension_chan_offset =
-                           extra_param_info.ext_chan_offset;
-                       ht_info->tx_chan_width = extra_param_info.tx_chan_width;
-                       op_mode.val = (u16)
-                           le16_to_cpu(ht_extra->operation_mode);
-                       ht_info->operating_mode = op_mode.op_mode;
-                       IWL_DEBUG_MAC80211("control channel %d\n",
-                                           ht_extra->control_chan);
-               }
-       } else
-               ht_info->is_ht = 0;
-
+       iwl_conf->is_ht = 1;
+       priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+               iwl_conf->sgf |= 0x1;
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+               iwl_conf->sgf |= 0x2;
+
+       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);
+       iwl_conf->tx_mimo_ps_mode =
+               (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+       memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
+
+       iwl_conf->control_channel = ht_bss_conf->primary_channel;
+       iwl_conf->extension_chan_offset =
+               ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+       iwl_conf->tx_chan_width =
+               !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
+       iwl_conf->ht_protection =
+               ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
+       iwl_conf->non_GF_STA_present =
+               !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
+
+       IWL_DEBUG_MAC80211("control channel %d\n",
+               iwl_conf->control_channel);
        IWL_DEBUG_MAC80211("leave\n");
-       return 0;
 }
 
-static int iwl_mac_conf_ht(struct ieee80211_hw *hw,
-                          struct ieee80211_ht_capability *ht_cap,
-                          struct ieee80211_ht_additional_info *ht_extra)
+static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw,
+                              struct ieee80211_conf *conf)
 {
-       struct iwl_priv *priv = hw->priv;
-       int rs;
+       struct iwl4965_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter: \n");
 
-       rs = sta_ht_info_init(ht_cap, ht_extra, NULL, &priv->current_assoc_ht);
+       iwl4965_ht_info_fill(conf, priv);
        iwl4965_set_rxon_chain(priv);
 
        if (priv && priv->assoc_id &&
@@ -8164,58 +8245,33 @@ static int iwl_mac_conf_ht(struct ieee80211_hw *hw,
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
-       IWL_DEBUG_MAC80211("leave: control channel %d\n",
-                       ht_extra->control_chan);
-       return rs;
-
+       IWL_DEBUG_MAC80211("leave:\n");
+       return 0;
 }
 
-static void iwl_set_ht_capab(struct ieee80211_hw *hw,
-                            struct ieee80211_ht_capability *ht_cap,
-                            u8 use_wide_chan)
+static void iwl4965_set_ht_capab(struct ieee80211_hw *hw,
+                       struct ieee80211_ht_cap *ht_cap,
+                       u8 use_current_config)
 {
-       union ht_cap_info cap;
-       union ht_param_info param_info;
-
-       memset(&cap, 0, sizeof(union ht_cap_info));
-       memset(&param_info, 0, sizeof(union ht_param_info));
-
-       cap.maximal_amsdu_size = HT_IE_MAX_AMSDU_SIZE_4K;
-       cap.green_field = 1;
-       cap.short_GI20 = 1;
-       cap.short_GI40 = 1;
-       cap.supported_chan_width_set = use_wide_chan;
-       cap.mimo_power_save_mode = 0x3;
-
-       param_info.max_rx_ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
-       param_info.mpdu_density = CFG_HT_MPDU_DENSITY_DEF;
-       ht_cap->capabilities_info = (__le16) cpu_to_le16(cap.val);
-       ht_cap->mac_ht_params_info = (u8) param_info.val;
+       struct ieee80211_conf *conf = &hw->conf;
+       struct ieee80211_hw_mode *mode = conf->mode;
 
-       ht_cap->supported_mcs_set[0] = 0xff;
-       ht_cap->supported_mcs_set[1] = 0xff;
-       ht_cap->supported_mcs_set[4] =
-           (cap.supported_chan_width_set) ? 0x1: 0x0;
+       if (use_current_config) {
+               ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap);
+               memcpy(ht_cap->supp_mcs_set,
+                               conf->ht_conf.supp_mcs_set, 16);
+       } else {
+               ht_cap->cap_info = cpu_to_le16(mode->ht_info.cap);
+               memcpy(ht_cap->supp_mcs_set,
+                               mode->ht_info.supp_mcs_set, 16);
+       }
+       ht_cap->ampdu_params_info =
+               (mode->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
+               ((mode->ht_info.ampdu_density << 2) &
+                                       IEEE80211_HT_CAP_AMPDU_DENSITY);
 }
 
-static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw,
-                                struct ieee80211_ht_capability *ht_cap)
-{
-       u8 use_wide_channel = 1;
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211("enter: \n");
-       if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ)
-               use_wide_channel = 0;
-
-       /* no fat tx allowed on 2.4GHZ */
-       if (priv->phymode != MODE_IEEE80211A)
-               use_wide_channel = 0;
-
-       iwl_set_ht_capab(hw, ht_cap, use_wide_channel);
-       IWL_DEBUG_MAC80211("leave: \n");
-}
-#endif /*CONFIG_IWLWIFI_HT*/
+#endif /*CONFIG_IWL4965_HT*/
 
 /*****************************************************************************
  *
@@ -8223,7 +8279,7 @@ static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw,
  *
  *****************************************************************************/
 
-#ifdef CONFIG_IWLWIFI_DEBUG
+#ifdef CONFIG_IWL4965_DEBUG
 
 /*
  * The following adds a new attribute to the sysfs representation
@@ -8235,7 +8291,7 @@ static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw,
 
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
-       return sprintf(buf, "0x%08X\n", iwl_debug_level);
+       return sprintf(buf, "0x%08X\n", iwl4965_debug_level);
 }
 static ssize_t store_debug_level(struct device_driver *d,
                                 const char *buf, size_t count)
@@ -8248,7 +8304,7 @@ static ssize_t store_debug_level(struct device_driver *d,
                printk(KERN_INFO DRV_NAME
                       ": %s is not in hex or decimal form.\n", buf);
        else
-               iwl_debug_level = val;
+               iwl4965_debug_level = val;
 
        return strnlen(buf, count);
 }
@@ -8256,7 +8312,7 @@ static ssize_t store_debug_level(struct device_driver *d,
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
                   show_debug_level, store_debug_level);
 
-#endif /* CONFIG_IWLWIFI_DEBUG */
+#endif /* CONFIG_IWL4965_DEBUG */
 
 static ssize_t show_rf_kill(struct device *d,
                            struct device_attribute *attr, char *buf)
@@ -8267,7 +8323,7 @@ static ssize_t show_rf_kill(struct device *d,
         * 2 - HW based RF kill active
         * 3 - Both HW and SW based RF kill active
         */
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) |
                  (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0);
 
@@ -8278,10 +8334,10 @@ static ssize_t store_rf_kill(struct device *d,
                             struct device_attribute *attr,
                             const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
 
        mutex_lock(&priv->mutex);
-       iwl_radio_kill_sw(priv, buf[0] == '1');
+       iwl4965_radio_kill_sw(priv, buf[0] == '1');
        mutex_unlock(&priv->mutex);
 
        return count;
@@ -8292,12 +8348,12 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl4965_is_alive(priv))
                return -EAGAIN;
 
-       return sprintf(buf, "%d\n", iwl_hw_get_temperature(priv));
+       return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));
 }
 
 static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
@@ -8306,15 +8362,15 @@ static ssize_t show_rs_window(struct device *d,
                              struct device_attribute *attr,
                              char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
-       return iwl_fill_rs_info(priv->hw, buf, IWL_AP_ID);
+       struct iwl4965_priv *priv = d->driver_data;
+       return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID);
 }
 static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, 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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        return sprintf(buf, "%d\n", priv->user_txpower_limit);
 }
 
@@ -8322,7 +8378,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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        char *p = (char *)buf;
        u32 val;
 
@@ -8331,7 +8387,7 @@ static ssize_t store_tx_power(struct device *d,
                printk(KERN_INFO DRV_NAME
                       ": %s is not in decimal form.\n", buf);
        else
-               iwl_hw_reg_set_txpower(priv, val);
+               iwl4965_hw_reg_set_txpower(priv, val);
 
        return count;
 }
@@ -8341,7 +8397,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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -8350,19 +8406,19 @@ 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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        u32 flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl4965_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
                                       flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
-                       iwl_commit_rxon(priv);
+                       iwl4965_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -8375,7 +8431,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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n",
                le32_to_cpu(priv->active_rxon.filter_flags));
@@ -8385,20 +8441,20 @@ 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 iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
        if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl4965_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing rxon.filter_flags = "
                                       "0x%04X\n", filter_flags);
                        priv->staging_rxon.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwl_commit_rxon(priv);
+                       iwl4965_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -8412,20 +8468,20 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
 static ssize_t show_tune(struct device *d,
                         struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
 
        return sprintf(buf, "0x%04X\n",
                       (priv->phymode << 8) |
                        le16_to_cpu(priv->active_rxon.channel));
 }
 
-static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode);
+static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode);
 
 static ssize_t store_tune(struct device *d,
                          struct device_attribute *attr,
                          const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
        char *p = (char *)buf;
        u16 tune = simple_strtoul(p, &p, 0);
        u8 phymode = (tune >> 8) & 0xff;
@@ -8436,9 +8492,9 @@ static ssize_t store_tune(struct device *d,
        mutex_lock(&priv->mutex);
        if ((le16_to_cpu(priv->staging_rxon.channel) != channel) ||
            (priv->phymode != phymode)) {
-               const struct iwl_channel_info *ch_info;
+               const struct iwl4965_channel_info *ch_info;
 
-               ch_info = iwl_get_channel_info(priv, phymode, channel);
+               ch_info = iwl4965_get_channel_info(priv, phymode, channel);
                if (!ch_info) {
                        IWL_WARNING("Requested invalid phymode/channel "
                                    "combination: %d %d\n", phymode, channel);
@@ -8447,18 +8503,18 @@ static ssize_t store_tune(struct device *d,
                }
 
                /* Cancel any currently running scans... */
-               if (iwl_scan_cancel_timeout(priv, 100))
+               if (iwl4965_scan_cancel_timeout(priv, 100))
                        IWL_WARNING("Could not cancel scan.\n");
                else {
                        IWL_DEBUG_INFO("Committing phymode and "
                                       "rxon.channel = %d %d\n",
                                       phymode, channel);
 
-                       iwl_set_rxon_channel(priv, phymode, channel);
-                       iwl_set_flags_for_phymode(priv, phymode);
+                       iwl4965_set_rxon_channel(priv, phymode, channel);
+                       iwl4965_set_flags_for_phymode(priv, phymode);
 
-                       iwl_set_rate(priv);
-                       iwl_commit_rxon(priv);
+                       iwl4965_set_rate(priv);
+                       iwl4965_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -8468,13 +8524,13 @@ static ssize_t store_tune(struct device *d,
 
 static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune);
 
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
 
 static ssize_t show_measurement(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       struct iwl_spectrum_notification measure_report;
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_spectrum_notification measure_report;
        u32 size = sizeof(measure_report), len = 0, ofs = 0;
        u8 *data = (u8 *) & measure_report;
        unsigned long flags;
@@ -8506,7 +8562,7 @@ static ssize_t store_measurement(struct device *d,
                                 struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
        struct ieee80211_measurement_params params = {
                .channel = le16_to_cpu(priv->active_rxon.channel),
                .start_time = cpu_to_le64(priv->last_tsf),
@@ -8532,20 +8588,20 @@ static ssize_t store_measurement(struct device *d,
 
        IWL_DEBUG_INFO("Invoking measurement of type %d on "
                       "channel %d (for '%s')\n", type, params.channel, buf);
-       iwl_get_measurement(priv, &params, type);
+       iwl4965_get_measurement(priv, &params, type);
 
        return count;
 }
 
 static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
                   show_measurement, store_measurement);
-#endif /* CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT */
+#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */
 
 static ssize_t store_retry_rate(struct device *d,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
 
        priv->retry_rate = simple_strtoul(buf, NULL, 0);
        if (priv->retry_rate <= 0)
@@ -8557,7 +8613,7 @@ static ssize_t store_retry_rate(struct device *d,
 static ssize_t show_retry_rate(struct device *d,
                               struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
        return sprintf(buf, "%d", priv->retry_rate);
 }
 
@@ -8568,14 +8624,14 @@ static ssize_t store_power_level(struct device *d,
                                 struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
        int rc;
        int mode;
 
        mode = simple_strtoul(buf, NULL, 0);
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_ready(priv)) {
+       if (!iwl4965_is_ready(priv)) {
                rc = -EAGAIN;
                goto out;
        }
@@ -8586,7 +8642,7 @@ static ssize_t store_power_level(struct device *d,
                mode |= IWL_POWER_ENABLED;
 
        if (mode != priv->power_mode) {
-               rc = iwl_send_power_mode(priv, IWL_POWER_LEVEL(mode));
+               rc = iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(mode));
                if (rc) {
                        IWL_DEBUG_MAC80211("failed setting power mode.\n");
                        goto out;
@@ -8622,7 +8678,7 @@ static const s32 period_duration[] = {
 static ssize_t show_power_level(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
        int level = IWL_POWER_LEVEL(priv->power_mode);
        char *p = buf;
 
@@ -8657,18 +8713,18 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
 static ssize_t show_channels(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
        int len = 0, i;
        struct ieee80211_channel *channels = NULL;
        const struct ieee80211_hw_mode *hw_mode = NULL;
        int count = 0;
 
-       if (!iwl_is_ready(priv))
+       if (!iwl4965_is_ready(priv))
                return -EAGAIN;
 
-       hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211G);
+       hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G);
        if (!hw_mode)
-               hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211B);
+               hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B);
        if (hw_mode) {
                channels = hw_mode->channels;
                count = hw_mode->num_channels;
@@ -8695,7 +8751,7 @@ static ssize_t show_channels(struct device *d,
                               flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
                               "active/passive" : "passive only");
 
-       hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211A);
+       hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A);
        if (hw_mode) {
                channels = hw_mode->channels;
                count = hw_mode->num_channels;
@@ -8731,17 +8787,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
 static ssize_t show_statistics(struct device *d,
                               struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
-       u32 size = sizeof(struct iwl_notif_statistics);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
+       u32 size = sizeof(struct iwl4965_notif_statistics);
        u32 len = 0, ofs = 0;
        u8 *data = (u8 *) & priv->statistics;
        int rc = 0;
 
-       if (!iwl_is_alive(priv))
+       if (!iwl4965_is_alive(priv))
                return -EAGAIN;
 
        mutex_lock(&priv->mutex);
-       rc = iwl_send_statistics_request(priv);
+       rc = iwl4965_send_statistics_request(priv);
        mutex_unlock(&priv->mutex);
 
        if (rc) {
@@ -8769,9 +8825,9 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
 static ssize_t show_antenna(struct device *d,
                            struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
 
-       if (!iwl_is_alive(priv))
+       if (!iwl4965_is_alive(priv))
                return -EAGAIN;
 
        return sprintf(buf, "%d\n", priv->antenna);
@@ -8782,7 +8838,7 @@ static ssize_t store_antenna(struct device *d,
                             const char *buf, size_t count)
 {
        int ant;
-       struct iwl_priv *priv = dev_get_drvdata(d);
+       struct iwl4965_priv *priv = dev_get_drvdata(d);
 
        if (count == 0)
                return 0;
@@ -8794,7 +8850,7 @@ static ssize_t store_antenna(struct device *d,
 
        if ((ant >= 0) && (ant <= 2)) {
                IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
-               priv->antenna = (enum iwl_antenna)ant;
+               priv->antenna = (enum iwl4965_antenna)ant;
        } else
                IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
 
@@ -8807,8 +8863,8 @@ 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;
-       if (!iwl_is_alive(priv))
+       struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
+       if (!iwl4965_is_alive(priv))
                return -EAGAIN;
        return sprintf(buf, "0x%08x\n", (int)priv->status);
 }
@@ -8822,7 +8878,7 @@ static ssize_t dump_error_log(struct device *d,
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+               iwl4965_dump_nic_error_log((struct iwl4965_priv *)d->driver_data);
 
        return strnlen(buf, count);
 }
@@ -8836,7 +8892,7 @@ static ssize_t dump_event_log(struct device *d,
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+               iwl4965_dump_nic_event_log((struct iwl4965_priv *)d->driver_data);
 
        return strnlen(buf, count);
 }
@@ -8849,34 +8905,34 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
  *
  *****************************************************************************/
 
-static void iwl_setup_deferred_work(struct iwl_priv *priv)
+static void iwl4965_setup_deferred_work(struct iwl4965_priv *priv)
 {
        priv->workqueue = create_workqueue(DRV_NAME);
 
        init_waitqueue_head(&priv->wait_command_queue);
 
-       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->scan_completed, iwl_bg_scan_completed);
-       INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
-       INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
-       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
-       INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
-       INIT_DELAYED_WORK(&priv->post_associate, iwl_bg_post_associate);
-       INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
-       INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
-       INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
-
-       iwl_hw_setup_deferred_work(priv);
+       INIT_WORK(&priv->up, iwl4965_bg_up);
+       INIT_WORK(&priv->restart, iwl4965_bg_restart);
+       INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish);
+       INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed);
+       INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan);
+       INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan);
+       INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);
+       INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);
+       INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate);
+       INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start);
+       INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start);
+       INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check);
+
+       iwl4965_hw_setup_deferred_work(priv);
 
        tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-                    iwl_irq_tasklet, (unsigned long)priv);
+                    iwl4965_irq_tasklet, (unsigned long)priv);
 }
 
-static void iwl_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl4965_cancel_deferred_work(struct iwl4965_priv *priv)
 {
-       iwl_hw_cancel_deferred_work(priv);
+       iwl4965_hw_cancel_deferred_work(priv);
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
@@ -8885,14 +8941,14 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->beacon_update);
 }
 
-static struct attribute *iwl_sysfs_entries[] = {
+static struct attribute *iwl4965_sysfs_entries[] = {
        &dev_attr_antenna.attr,
        &dev_attr_channels.attr,
        &dev_attr_dump_errors.attr,
        &dev_attr_dump_events.attr,
        &dev_attr_flags.attr,
        &dev_attr_filter_flags.attr,
-#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
        &dev_attr_measurement.attr,
 #endif
        &dev_attr_power_level.attr,
@@ -8908,54 +8964,56 @@ static struct attribute *iwl_sysfs_entries[] = {
        NULL
 };
 
-static struct attribute_group iwl_attribute_group = {
+static struct attribute_group iwl4965_attribute_group = {
        .name = NULL,           /* put in device directory */
-       .attrs = iwl_sysfs_entries,
+       .attrs = iwl4965_sysfs_entries,
 };
 
-static struct ieee80211_ops iwl_hw_ops = {
-       .tx = iwl_mac_tx,
-       .start = iwl_mac_start,
-       .stop = iwl_mac_stop,
-       .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,
-       .get_stats = iwl_mac_get_stats,
-       .get_tx_stats = iwl_mac_get_tx_stats,
-       .conf_tx = iwl_mac_conf_tx,
-       .get_tsf = iwl_mac_get_tsf,
-       .reset_tsf = iwl_mac_reset_tsf,
-       .beacon_update = iwl_mac_beacon_update,
-#ifdef CONFIG_IWLWIFI_HT
-       .conf_ht = iwl_mac_conf_ht,
-       .get_ht_capab = iwl_mac_get_ht_capab,
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       .ht_tx_agg_start = iwl_mac_ht_tx_agg_start,
-       .ht_tx_agg_stop = iwl_mac_ht_tx_agg_stop,
-       .ht_rx_agg_start = iwl_mac_ht_rx_agg_start,
-       .ht_rx_agg_stop = iwl_mac_ht_rx_agg_stop,
-#endif  /* CONFIG_IWLWIFI_HT_AGG */
-#endif  /* CONFIG_IWLWIFI_HT */
-       .hw_scan = iwl_mac_hw_scan
+static struct ieee80211_ops iwl4965_hw_ops = {
+       .tx = iwl4965_mac_tx,
+       .start = iwl4965_mac_start,
+       .stop = iwl4965_mac_stop,
+       .add_interface = iwl4965_mac_add_interface,
+       .remove_interface = iwl4965_mac_remove_interface,
+       .config = iwl4965_mac_config,
+       .config_interface = iwl4965_mac_config_interface,
+       .configure_filter = iwl4965_configure_filter,
+       .set_key = iwl4965_mac_set_key,
+       .get_stats = iwl4965_mac_get_stats,
+       .get_tx_stats = iwl4965_mac_get_tx_stats,
+       .conf_tx = iwl4965_mac_conf_tx,
+       .get_tsf = iwl4965_mac_get_tsf,
+       .reset_tsf = iwl4965_mac_reset_tsf,
+       .beacon_update = iwl4965_mac_beacon_update,
+       .bss_info_changed = iwl4965_bss_info_changed,
+#ifdef CONFIG_IWL4965_HT
+       .conf_ht = iwl4965_mac_conf_ht,
+       .ampdu_action = iwl4965_mac_ampdu_action,
+#ifdef CONFIG_IWL4965_HT_AGG
+       .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start,
+       .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop,
+#endif  /* CONFIG_IWL4965_HT_AGG */
+#endif  /* CONFIG_IWL4965_HT */
+       .hw_scan = iwl4965_mac_hw_scan
 };
 
-static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        int err = 0;
-       struct iwl_priv *priv;
+       struct iwl4965_priv *priv;
        struct ieee80211_hw *hw;
        int i;
+       DECLARE_MAC_BUF(mac);
 
-       if (iwl_param_disable_hw_scan) {
+       /* Disabling hardware scan means that mac80211 will perform scans
+        * "the hard way", rather than using device's scan. */
+       if (iwl4965_param_disable_hw_scan) {
                IWL_DEBUG_INFO("Disabling hw_scan\n");
-               iwl_hw_ops.hw_scan = NULL;
+               iwl4965_hw_ops.hw_scan = NULL;
        }
 
-       if ((iwl_param_queues_num > IWL_MAX_NUM_QUEUES) ||
-           (iwl_param_queues_num < IWL_MIN_NUM_QUEUES)) {
+       if ((iwl4965_param_queues_num > IWL_MAX_NUM_QUEUES) ||
+           (iwl4965_param_queues_num < IWL_MIN_NUM_QUEUES)) {
                IWL_ERROR("invalid queues_num, should be between %d and %d\n",
                          IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES);
                err = -EINVAL;
@@ -8964,7 +9022,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* mac80211 allocates memory for this device instance, including
         *   space for this driver's private structure */
-       hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwl_hw_ops);
+       hw = ieee80211_alloc_hw(sizeof(struct iwl4965_priv), &iwl4965_hw_ops);
        if (hw == NULL) {
                IWL_ERROR("Can not allocate network device\n");
                err = -ENOMEM;
@@ -8979,9 +9037,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        priv->hw = hw;
 
        priv->pci_dev = pdev;
-       priv->antenna = (enum iwl_antenna)iwl_param_antenna;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       iwl_debug_level = iwl_param_debug;
+       priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna;
+#ifdef CONFIG_IWL4965_DEBUG
+       iwl4965_debug_level = iwl4965_param_debug;
        atomic_set(&priv->restrict_refcnt, 0);
 #endif
        priv->retry_rate = 1;
@@ -9000,12 +9058,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Tell mac80211 our Tx characteristics */
        hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
 
+       /* Default value; 4 EDCA QOS priorities */
        hw->queues = 4;
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
+#ifdef CONFIG_IWL4965_HT
+#ifdef CONFIG_IWL4965_HT_AGG
+       /* Enhanced value; more queues, to support 11n aggregation */
        hw->queues = 16;
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
+#endif /* CONFIG_IWL4965_HT_AGG */
+#endif /* CONFIG_IWL4965_HT */
 
        spin_lock_init(&priv->lock);
        spin_lock_init(&priv->power_data.lock);
@@ -9026,7 +9086,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
 
-       iwl_clear_stations_table(priv);
+       /* Clear the driver's (not device's) station table */
+       iwl4965_clear_stations_table(priv);
 
        priv->data_retry_limit = -1;
        priv->ieee_channels = NULL;
@@ -9045,9 +9106,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        err = pci_request_regions(pdev, DRV_NAME);
        if (err)
                goto out_pci_disable_device;
+
        /* We disable the RETRY_TIMEOUT register (0x41) to keep
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, 0x41, 0x00);
+
        priv->hw_base = pci_iomap(pdev, 0, 0);
        if (!priv->hw_base) {
                err = -ENODEV;
@@ -9060,7 +9123,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* Initialize module parameter values here */
 
-       if (iwl_param_disable) {
+       /* Disable radio (SW RF KILL) via parameter when loading driver */
+       if (iwl4965_param_disable) {
                set_bit(STATUS_RF_KILL_SW, &priv->status);
                IWL_DEBUG_INFO("Radio disabled.\n");
        }
@@ -9069,91 +9133,92 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        priv->ps_mode = 0;
        priv->use_ant_b_for_management_frame = 1; /* start with ant B */
-       priv->is_ht_enabled = 1;
-       priv->channel_width = IWL_CHANNEL_WIDTH_40MHZ;
        priv->valid_antenna = 0x7;      /* assume all 3 connected */
        priv->ps_mode = IWL_MIMO_PS_NONE;
-       priv->cck_power_index_compensation = iwl_read32(
-               priv, CSR_HW_REV_WA_REG);
 
+       /* Choose which receivers/antennas to use */
        iwl4965_set_rxon_chain(priv);
 
        printk(KERN_INFO DRV_NAME
               ": Detected Intel Wireless WiFi Link 4965AGN\n");
 
        /* Device-specific setup */
-       if (iwl_hw_set_hw_setting(priv)) {
+       if (iwl4965_hw_set_hw_setting(priv)) {
                IWL_ERROR("failed to set hw settings\n");
-               mutex_unlock(&priv->mutex);
                goto out_iounmap;
        }
 
-#ifdef CONFIG_IWLWIFI_QOS
-       if (iwl_param_qos_enable)
+#ifdef CONFIG_IWL4965_QOS
+       if (iwl4965_param_qos_enable)
                priv->qos_data.qos_enable = 1;
 
-       iwl_reset_qos(priv);
+       iwl4965_reset_qos(priv);
 
        priv->qos_data.qos_active = 0;
        priv->qos_data.qos_cap.val = 0;
-#endif /* CONFIG_IWLWIFI_QOS */
+#endif /* CONFIG_IWL4965_QOS */
 
-       iwl_set_rxon_channel(priv, MODE_IEEE80211G, 6);
-       iwl_setup_deferred_work(priv);
-       iwl_setup_rx_handlers(priv);
+       iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6);
+       iwl4965_setup_deferred_work(priv);
+       iwl4965_setup_rx_handlers(priv);
 
        priv->rates_mask = IWL_RATES_MASK;
        /* If power management is turned on, default to AC mode */
        priv->power_mode = IWL_POWER_AC;
        priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
 
-       pci_enable_msi(pdev);
-
-       err = request_irq(pdev->irq, iwl_isr, IRQF_SHARED, DRV_NAME, priv);
-       if (err) {
-               IWL_ERROR("Error allocating IRQ %d\n", pdev->irq);
-               goto out_disable_msi;
-       }
-
-       mutex_lock(&priv->mutex);
+       iwl4965_disable_interrupts(priv);
 
-       err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group);
+       err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
        if (err) {
                IWL_ERROR("failed to create sysfs device attributes\n");
-               mutex_unlock(&priv->mutex);
                goto out_release_irq;
        }
 
-       /* fetch ucode file from disk, alloc and copy to bus-master buffers ...
-        * ucode filename and max sizes are card-specific. */
-       err = iwl_read_ucode(priv);
+       /* nic init */
+       iwl4965_set_bit(priv, CSR_GIO_CHICKEN_BITS,
+                    CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
+
+        iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+        err = iwl4965_poll_bit(priv, CSR_GP_CNTRL,
+                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+        if (err < 0) {
+                IWL_DEBUG_INFO("Failed to init the card\n");
+               goto out_remove_sysfs;
+        }
+       /* Read the EEPROM */
+       err = iwl4965_eeprom_init(priv);
        if (err) {
-               IWL_ERROR("Could not read microcode: %d\n", err);
-               mutex_unlock(&priv->mutex);
-               goto out_pci_alloc;
+               IWL_ERROR("Unable to init EEPROM\n");
+               goto out_remove_sysfs;
        }
+       /* MAC Address location in EEPROM same for 3945/4965 */
+       get_eeprom_mac(priv, priv->mac_addr);
+       IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
+       SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
 
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_INFO("Queing UP work.\n");
+       iwl4965_rate_control_register(priv->hw);
+       err = ieee80211_register_hw(priv->hw);
+       if (err) {
+               IWL_ERROR("Failed to register network device (error %d)\n", err);
+               goto out_remove_sysfs;
+       }
 
-       queue_work(priv->workqueue, &priv->up);
+       priv->hw->conf.beacon_int = 100;
+       priv->mac80211_registered = 1;
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
 
        return 0;
 
- out_pci_alloc:
-       iwl_dealloc_ucode_pci(priv);
-
-       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
+ out_remove_sysfs:
+       sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
  out_release_irq:
-       free_irq(pdev->irq, priv);
-
- out_disable_msi:
-       pci_disable_msi(pdev);
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
-       iwl_unset_hw_setting(priv);
+       iwl4965_unset_hw_setting(priv);
 
  out_iounmap:
        pci_iounmap(pdev, priv->hw_base);
@@ -9168,9 +9233,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        return err;
 }
 
-static void iwl_pci_remove(struct pci_dev *pdev)
+static void iwl4965_pci_remove(struct pci_dev *pdev)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl4965_priv *priv = pci_get_drvdata(pdev);
        struct list_head *p, *q;
        int i;
 
@@ -9181,43 +9246,41 @@ static void iwl_pci_remove(struct pci_dev *pdev)
 
        set_bit(STATUS_EXIT_PENDING, &priv->status);
 
-       iwl_down(priv);
+       iwl4965_down(priv);
 
        /* Free MAC hash list for ADHOC */
        for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
                list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
                        list_del(p);
-                       kfree(list_entry(p, struct iwl_ibss_seq, list));
+                       kfree(list_entry(p, struct iwl4965_ibss_seq, list));
                }
        }
 
-       sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
+       sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
 
-       iwl_dealloc_ucode_pci(priv);
+       iwl4965_dealloc_ucode_pci(priv);
 
        if (priv->rxq.bd)
-               iwl_rx_queue_free(priv, &priv->rxq);
-       iwl_hw_txq_ctx_free(priv);
+               iwl4965_rx_queue_free(priv, &priv->rxq);
+       iwl4965_hw_txq_ctx_free(priv);
 
-       iwl_unset_hw_setting(priv);
-       iwl_clear_stations_table(priv);
+       iwl4965_unset_hw_setting(priv);
+       iwl4965_clear_stations_table(priv);
 
        if (priv->mac80211_registered) {
                ieee80211_unregister_hw(priv->hw);
-               iwl_rate_control_unregister(priv->hw);
+               iwl4965_rate_control_unregister(priv->hw);
        }
 
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
 
-       /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
+       /* ieee80211_unregister_hw calls iwl4965_mac_stop, which flushes
         * priv->workqueue... so we can't take down the workqueue
         * until now... */
        destroy_workqueue(priv->workqueue);
        priv->workqueue = NULL;
 
-       free_irq(pdev->irq, priv);
-       pci_disable_msi(pdev);
        pci_iounmap(pdev, priv->hw_base);
        pci_release_regions(pdev);
        pci_disable_device(pdev);
@@ -9236,93 +9299,31 @@ static void iwl_pci_remove(struct pci_dev *pdev)
 
 #ifdef CONFIG_PM
 
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+static int iwl4965_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       struct iwl4965_priv *priv = pci_get_drvdata(pdev);
 
-       set_bit(STATUS_IN_SUSPEND, &priv->status);
-
-       /* Take down the device; powers it off, etc. */
-       iwl_down(priv);
-
-       if (priv->mac80211_registered)
-               ieee80211_stop_queues(priv->hw);
+       if (priv->is_open) {
+               set_bit(STATUS_IN_SUSPEND, &priv->status);
+               iwl4965_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 void iwl_resume(struct iwl_priv *priv)
+static int iwl4965_pci_resume(struct pci_dev *pdev)
 {
-       unsigned long flags;
-
-       /* The following it a temporary work around due to the
-        * suspend / resume not fully initializing the NIC correctly.
-        * Without all of the following, resume will not attempt to take
-        * down the NIC (it shouldn't really need to) and will just try
-        * and bring the NIC back up.  However that fails during the
-        * ucode verification process.  This then causes iwl_down to be
-        * called *after* iwl_hw_nic_init() has succeeded -- which
-        * then lets the next init sequence succeed.  So, we've
-        * replicated all of that NIC init code here... */
-
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
-       iwl_hw_nic_init(priv);
-
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
-                   CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-       iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
-       /* tell the device to stop sending interrupts */
-       iwl_disable_interrupts(priv);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
-       if (!iwl_grab_restricted_access(priv)) {
-               iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_restricted_access(priv);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       udelay(5);
-
-       iwl_hw_nic_reset(priv);
-
-       /* Bring the device back up */
-       clear_bit(STATUS_IN_SUSPEND, &priv->status);
-       queue_work(priv->workqueue, &priv->up);
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
-{
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-       int err;
-
-       printk(KERN_INFO "Coming out of suspend...\n");
+       struct iwl4965_priv *priv = pci_get_drvdata(pdev);
 
        pci_set_power_state(pdev, PCI_D0);
-       err = pci_enable_device(pdev);
-       pci_restore_state(pdev);
-
-       /*
-        * Suspend/Resume resets the PCI configuration space, so we have to
-        * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
-        * from interfering with C3 CPU state. pci_restore_state won't help
-        * here since it only restores the first 64 bytes pci config header.
-        */
-       pci_write_config_byte(pdev, 0x41, 0x00);
 
-       iwl_resume(priv);
+       if (priv->is_open)
+               iwl4965_mac_start(priv->hw);
 
+       clear_bit(STATUS_IN_SUSPEND, &priv->status);
        return 0;
 }
 
@@ -9334,33 +9335,33 @@ static int iwl_pci_resume(struct pci_dev *pdev)
  *
  *****************************************************************************/
 
-static struct pci_driver iwl_driver = {
+static struct pci_driver iwl4965_driver = {
        .name = DRV_NAME,
-       .id_table = iwl_hw_card_ids,
-       .probe = iwl_pci_probe,
-       .remove = __devexit_p(iwl_pci_remove),
+       .id_table = iwl4965_hw_card_ids,
+       .probe = iwl4965_pci_probe,
+       .remove = __devexit_p(iwl4965_pci_remove),
 #ifdef CONFIG_PM
-       .suspend = iwl_pci_suspend,
-       .resume = iwl_pci_resume,
+       .suspend = iwl4965_pci_suspend,
+       .resume = iwl4965_pci_resume,
 #endif
 };
 
-static int __init iwl_init(void)
+static int __init iwl4965_init(void)
 {
 
        int ret;
        printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
        printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
-       ret = pci_register_driver(&iwl_driver);
+       ret = pci_register_driver(&iwl4965_driver);
        if (ret) {
                IWL_ERROR("Unable to initialize PCI module\n");
                return ret;
        }
-#ifdef CONFIG_IWLWIFI_DEBUG
-       ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level);
+#ifdef CONFIG_IWL4965_DEBUG
+       ret = driver_create_file(&iwl4965_driver.driver, &driver_attr_debug_level);
        if (ret) {
                IWL_ERROR("Unable to create driver sysfs file\n");
-               pci_unregister_driver(&iwl_driver);
+               pci_unregister_driver(&iwl4965_driver);
                return ret;
        }
 #endif
@@ -9368,32 +9369,34 @@ static int __init iwl_init(void)
        return ret;
 }
 
-static void __exit iwl_exit(void)
+static void __exit iwl4965_exit(void)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level);
+#ifdef CONFIG_IWL4965_DEBUG
+       driver_remove_file(&iwl4965_driver.driver, &driver_attr_debug_level);
 #endif
-       pci_unregister_driver(&iwl_driver);
+       pci_unregister_driver(&iwl4965_driver);
 }
 
-module_param_named(antenna, iwl_param_antenna, int, 0444);
+module_param_named(antenna, iwl4965_param_antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl_param_disable, int, 0444);
+module_param_named(disable, iwl4965_param_disable, int, 0444);
 MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
-module_param_named(hwcrypto, iwl_param_hwcrypto, int, 0444);
+module_param_named(hwcrypto, iwl4965_param_hwcrypto, int, 0444);
 MODULE_PARM_DESC(hwcrypto,
                 "using hardware crypto engine (default 0 [software])\n");
-module_param_named(debug, iwl_param_debug, int, 0444);
+module_param_named(debug, iwl4965_param_debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
-module_param_named(disable_hw_scan, iwl_param_disable_hw_scan, int, 0444);
+module_param_named(disable_hw_scan, iwl4965_param_disable_hw_scan, int, 0444);
 MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
 
-module_param_named(queues_num, iwl_param_queues_num, int, 0444);
+module_param_named(queues_num, iwl4965_param_queues_num, int, 0444);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
 
 /* QoS */
-module_param_named(qos_enable, iwl_param_qos_enable, int, 0444);
+module_param_named(qos_enable, iwl4965_param_qos_enable, int, 0444);
 MODULE_PARM_DESC(qos_enable, "enable all QoS functionality");
+module_param_named(amsdu_size_8K, iwl4965_param_amsdu_size_8K, int, 0444);
+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
 
-module_exit(iwl_exit);
-module_init(iwl_init);
+module_exit(iwl4965_exit);
+module_init(iwl4965_init);
diff --git a/drivers/net/wireless/iwlwifi/iwlwifi.h b/drivers/net/wireless/iwlwifi/iwlwifi.h
deleted file mode 100644 (file)
index 432ce88..0000000
+++ /dev/null
@@ -1,708 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2007 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:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwlwifi_h__
-#define __iwlwifi_h__
-
-#include <linux/pci.h> /* for struct pci_device_id */
-#include <linux/kernel.h>
-#include <net/ieee80211_radiotap.h>
-
-struct iwl_priv;
-
-/* Hardware specific file defines the PCI IDs table for that hardware module */
-extern struct pci_device_id iwl_hw_card_ids[];
-
-#include "iwl-hw.h"
-#if IWL == 3945
-#define DRV_NAME       "iwl3945"
-#include "iwl-3945-hw.h"
-#elif IWL == 4965
-#define DRV_NAME        "iwl4965"
-#include "iwl-4965-hw.h"
-#endif
-
-#include "iwl-prph.h"
-
-/*
- * Driver implementation data structures, constants, inline
- * functions
- *
- * NOTE:  DO NOT PUT HARDWARE/UCODE SPECIFIC DECLRATIONS HERE
- *
- * Hardware specific declrations go into iwl-*hw.h
- *
- */
-
-#include "iwl-debug.h"
-
-/* Default noise level to report when noise measurement is not available.
- *   This may be because we're:
- *   1)  Not associated (4965, no beacon statistics being sent to driver)
- *   2)  Scanning (noise measurement does not apply to associated channel)
- *   3)  Receiving CCK (3945 delivers noise info only for OFDM frames)
- * Use default noise value of -127 ... this is below the range of measurable
- *   Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user.
- *   Also, -127 works better than 0 when averaging frames with/without
- *   noise info (e.g. averaging might be done in app); measured dBm values are
- *   always negative ... using a negative value as the default keeps all
- *   averages within an s8's (used in some apps) range of negative values. */
-#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
-
-/* Module parameters accessible from iwl-*.c */
-extern int iwl_param_disable_hw_scan;
-extern int iwl_param_debug;
-extern int iwl_param_mode;
-extern int iwl_param_disable;
-extern int iwl_param_antenna;
-extern int iwl_param_hwcrypto;
-extern int iwl_param_qos_enable;
-extern int iwl_param_queues_num;
-
-enum iwl_antenna {
-       IWL_ANTENNA_DIVERSITY,
-       IWL_ANTENNA_MAIN,
-       IWL_ANTENNA_AUX
-};
-
-/*
- * RTS threshold here is total size [2347] minus 4 FCS bytes
- * Per spec:
- *   a value of 0 means RTS on all data/management packets
- *   a value > max MSDU size means no RTS
- * else RTS for data/management frames where MPDU is larger
- *   than RTS value.
- */
-#define DEFAULT_RTS_THRESHOLD     2347U
-#define MIN_RTS_THRESHOLD         0U
-#define MAX_RTS_THRESHOLD         2347U
-#define MAX_MSDU_SIZE            2304U
-#define MAX_MPDU_SIZE            2346U
-#define DEFAULT_BEACON_INTERVAL   100U
-#define        DEFAULT_SHORT_RETRY_LIMIT 7U
-#define        DEFAULT_LONG_RETRY_LIMIT  4U
-
-struct iwl_rx_mem_buffer {
-       dma_addr_t dma_addr;
-       struct sk_buff *skb;
-       struct list_head list;
-};
-
-struct iwl_rt_rx_hdr {
-       struct ieee80211_radiotap_header rt_hdr;
-       __le64 rt_tsf;          /* TSF */
-       u8 rt_flags;            /* radiotap packet flags */
-       u8 rt_rate;             /* rate in 500kb/s */
-       __le16 rt_channelMHz;   /* channel in MHz */
-       __le16 rt_chbitmask;    /* channel bitfield */
-       s8 rt_dbmsignal;        /* signal in dBm, kluged to signed */
-       s8 rt_dbmnoise;
-       u8 rt_antenna;          /* antenna number */
-       u8 payload[0];          /* payload... */
-} __attribute__ ((packed));
-
-struct iwl_rt_tx_hdr {
-       struct ieee80211_radiotap_header rt_hdr;
-       u8 rt_rate;             /* rate in 500kb/s */
-       __le16 rt_channel;      /* channel in mHz */
-       __le16 rt_chbitmask;    /* channel bitfield */
-       s8 rt_dbmsignal;        /* signal in dBm, kluged to signed */
-       u8 rt_antenna;          /* antenna number */
-       u8 payload[0];          /* payload... */
-} __attribute__ ((packed));
-
-/*
- * Generic queue structure
- *
- * Contains common data for Rx and Tx queues
- */
-struct iwl_queue {
-       int n_bd;              /* number of BDs in this queue */
-       int first_empty;       /* 1-st empty entry (index) host_w*/
-       int last_used;         /* last used entry (index) host_r*/
-       dma_addr_t dma_addr;   /* physical addr for BD's */
-       int n_window;          /* safe queue window */
-       u32 id;
-       int low_mark;          /* low watermark, resume queue if free
-                               * space more than this */
-       int high_mark;         /* high watermark, stop queue if free
-                               * space less than this */
-} __attribute__ ((packed));
-
-#define MAX_NUM_OF_TBS          (20)
-
-struct iwl_tx_info {
-       struct ieee80211_tx_status status;
-       struct sk_buff *skb[MAX_NUM_OF_TBS];
-};
-
-/**
- * struct iwl_tx_queue - Tx Queue for DMA
- * @need_update: need to update read/write index
- * @shed_retry: queue is HT AGG enabled
- *
- * Queue consists of circular buffer of BD's and required locking structures.
- */
-struct iwl_tx_queue {
-       struct iwl_queue q;
-       struct iwl_tfd_frame *bd;
-       struct iwl_cmd *cmd;
-       dma_addr_t dma_addr_cmd;
-       struct iwl_tx_info *txb;
-       int need_update;
-       int sched_retry;
-       int active;
-};
-
-#include "iwl-channel.h"
-
-#if IWL == 3945
-#include "iwl-3945-rs.h"
-#else
-#include "iwl-4965-rs.h"
-#endif
-
-#define IWL_TX_FIFO_AC0        0
-#define IWL_TX_FIFO_AC1        1
-#define IWL_TX_FIFO_AC2        2
-#define IWL_TX_FIFO_AC3        3
-#define IWL_TX_FIFO_HCCA_1     5
-#define IWL_TX_FIFO_HCCA_2     6
-#define IWL_TX_FIFO_NONE       7
-
-/* Minimum number of queues. MAX_NUM is defined in hw specific files */
-#define IWL_MIN_NUM_QUEUES     4
-
-/* Power management (not Tx power) structures */
-
-struct iwl_power_vec_entry {
-       struct iwl_powertable_cmd cmd;
-       u8 no_dtim;
-};
-#define IWL_POWER_RANGE_0  (0)
-#define IWL_POWER_RANGE_1  (1)
-
-#define IWL_POWER_MODE_CAM     0x00    /* Continuously Aware Mode, always on */
-#define IWL_POWER_INDEX_3      0x03
-#define IWL_POWER_INDEX_5      0x05
-#define IWL_POWER_AC           0x06
-#define IWL_POWER_BATTERY      0x07
-#define IWL_POWER_LIMIT                0x07
-#define IWL_POWER_MASK         0x0F
-#define IWL_POWER_ENABLED      0x10
-#define IWL_POWER_LEVEL(x)     ((x) & IWL_POWER_MASK)
-
-struct iwl_power_mgr {
-       spinlock_t lock;
-       struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC];
-       struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC];
-       u8 active_index;
-       u32 dtim_val;
-};
-
-#define IEEE80211_DATA_LEN              2304
-#define IEEE80211_4ADDR_LEN             30
-#define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
-#define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-
-struct iwl_frame {
-       union {
-               struct ieee80211_hdr frame;
-               struct iwl_tx_beacon_cmd beacon;
-               u8 raw[IEEE80211_FRAME_LEN];
-               u8 cmd[360];
-       } u;
-       struct list_head list;
-};
-
-#define SEQ_TO_QUEUE(x)  ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x)  ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) (x & 0xff)
-#define INDEX_TO_SEQ(x) (x & 0xff)
-#define SEQ_HUGE_FRAME  (0x4000)
-#define SEQ_RX_FRAME    __constant_cpu_to_le16(0x8000)
-#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
-#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-
-enum {
-       /* CMD_SIZE_NORMAL = 0, */
-       CMD_SIZE_HUGE = (1 << 0),
-       /* CMD_SYNC = 0, */
-       CMD_ASYNC = (1 << 1),
-       /* CMD_NO_SKB = 0, */
-       CMD_WANT_SKB = (1 << 2),
-};
-
-struct iwl_cmd;
-struct iwl_priv;
-
-struct iwl_cmd_meta {
-       struct iwl_cmd_meta *source;
-       union {
-               struct sk_buff *skb;
-               int (*callback)(struct iwl_priv *priv,
-                               struct iwl_cmd *cmd, struct sk_buff *skb);
-       } __attribute__ ((packed)) u;
-
-       /* The CMD_SIZE_HUGE flag bit indicates that the command
-        * structure is stored at the end of the shared queue memory. */
-       u32 flags;
-
-} __attribute__ ((packed));
-
-struct iwl_cmd {
-       struct iwl_cmd_meta meta;
-       struct iwl_cmd_header hdr;
-       union {
-               struct iwl_addsta_cmd addsta;
-               struct iwl_led_cmd led;
-               u32 flags;
-               u8 val8;
-               u16 val16;
-               u32 val32;
-               struct iwl_bt_cmd bt;
-               struct iwl_rxon_time_cmd rxon_time;
-               struct iwl_powertable_cmd powertable;
-               struct iwl_qosparam_cmd qosparam;
-               struct iwl_tx_cmd tx;
-               struct iwl_tx_beacon_cmd tx_beacon;
-               struct iwl_rxon_assoc_cmd rxon_assoc;
-               u8 *indirect;
-               u8 payload[360];
-       } __attribute__ ((packed)) cmd;
-} __attribute__ ((packed));
-
-struct iwl_host_cmd {
-       u8 id;
-       u16 len;
-       struct iwl_cmd_meta meta;
-       const void *data;
-};
-
-#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
-                             sizeof(struct iwl_cmd_meta))
-
-/*
- * RX related structures and functions
- */
-#define RX_FREE_BUFFERS 64
-#define RX_LOW_WATERMARK 8
-
-#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
-#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
-#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
-
-/**
- * struct iwl_rx_queue - Rx queue
- * @processed: Internal index to last handled Rx packet
- * @read: Shared index to newest available Rx buffer
- * @write: Shared index to oldest written Rx packet
- * @free_count: Number of pre-allocated buffers in rx_free
- * @rx_free: list of free SKBs for use
- * @rx_used: List of Rx buffers with no SKB
- * @need_update: flag to indicate we need to update read/write index
- *
- * NOTE:  rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
- */
-struct iwl_rx_queue {
-       __le32 *bd;
-       dma_addr_t dma_addr;
-       struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS];
-       struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE];
-       u32 processed;
-       u32 read;
-       u32 write;
-       u32 free_count;
-       struct list_head rx_free;
-       struct list_head rx_used;
-       int need_update;
-       spinlock_t lock;
-};
-
-#define IWL_SUPPORTED_RATES_IE_LEN         8
-
-#define SCAN_INTERVAL 100
-
-#define MAX_A_CHANNELS  252
-#define MIN_A_CHANNELS  7
-
-#define MAX_B_CHANNELS  14
-#define MIN_B_CHANNELS  1
-
-#define STATUS_HCMD_ACTIVE     0       /* host command in progress */
-#define STATUS_INT_ENABLED     1
-#define STATUS_RF_KILL_HW      2
-#define STATUS_RF_KILL_SW      3
-#define STATUS_INIT            4
-#define STATUS_ALIVE           5
-#define STATUS_READY           6
-#define STATUS_TEMPERATURE     7
-#define STATUS_GEO_CONFIGURED  8
-#define STATUS_EXIT_PENDING    9
-#define STATUS_IN_SUSPEND      10
-#define STATUS_STATISTICS      11
-#define STATUS_SCANNING                12
-#define STATUS_SCAN_ABORTING   13
-#define STATUS_SCAN_HW         14
-#define STATUS_POWER_PMI       15
-#define STATUS_FW_ERROR                16
-
-#define MAX_TID_COUNT        9
-
-#define IWL_INVALID_RATE     0xFF
-#define IWL_INVALID_VALUE    -1
-
-#if IWL == 4965
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
-struct iwl_ht_agg {
-       u16 txq_id;
-       u16 frame_count;
-       u16 wait_for_ba;
-       u16 start_idx;
-       u32 bitmap0;
-       u32 bitmap1;
-       u32 rate_n_flags;
-};
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
-#endif
-
-struct iwl_tid_data {
-       u16 seq_number;
-#if IWL == 4965
-#ifdef CONFIG_IWLWIFI_HT
-#ifdef CONFIG_IWLWIFI_HT_AGG
-       struct iwl_ht_agg agg;
-#endif /* CONFIG_IWLWIFI_HT_AGG */
-#endif /* CONFIG_IWLWIFI_HT */
-#endif
-};
-
-struct iwl_hw_key {
-       enum ieee80211_key_alg alg;
-       int keylen;
-       u8 key[32];
-};
-
-union iwl_ht_rate_supp {
-       u16 rates;
-       struct {
-               u8 siso_rate;
-               u8 mimo_rate;
-       };
-};
-
-#ifdef CONFIG_IWLWIFI_HT
-#define CFG_HT_RX_AMPDU_FACTOR_DEF  (0x3)
-#define HT_IE_MAX_AMSDU_SIZE_4K     (0)
-#define CFG_HT_MPDU_DENSITY_2USEC   (0x5)
-#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC
-
-struct sta_ht_info {
-       u8 is_ht;
-       u16 rx_mimo_ps_mode;
-       u16 tx_mimo_ps_mode;
-       u16 control_channel;
-       u8 max_amsdu_size;
-       u8 ampdu_factor;
-       u8 mpdu_density;
-       u8 operating_mode;
-       u8 supported_chan_width;
-       u8 extension_chan_offset;
-       u8 is_green_field;
-       u8 sgf;
-       u8 supp_rates[16];
-       u8 tx_chan_width;
-       u8 chan_width_cap;
-};
-#endif                         /*CONFIG_IWLWIFI_HT */
-
-#ifdef CONFIG_IWLWIFI_QOS
-
-union iwl_qos_capabity {
-       struct {
-               u8 edca_count:4;        /* bit 0-3 */
-               u8 q_ack:1;             /* bit 4 */
-               u8 queue_request:1;     /* bit 5 */
-               u8 txop_request:1;      /* bit 6 */
-               u8 reserved:1;          /* bit 7 */
-       } q_AP;
-       struct {
-               u8 acvo_APSD:1;         /* bit 0 */
-               u8 acvi_APSD:1;         /* bit 1 */
-               u8 ac_bk_APSD:1;        /* bit 2 */
-               u8 ac_be_APSD:1;        /* bit 3 */
-               u8 q_ack:1;             /* bit 4 */
-               u8 max_len:2;           /* bit 5-6 */
-               u8 more_data_ack:1;     /* bit 7 */
-       } q_STA;
-       u8 val;
-};
-
-/* QoS sturctures */
-struct iwl_qos_info {
-       int qos_enable;
-       int qos_active;
-       union iwl_qos_capabity qos_cap;
-       struct iwl_qosparam_cmd def_qos_parm;
-};
-#endif /*CONFIG_IWLWIFI_QOS */
-
-#define STA_PS_STATUS_WAKE             0
-#define STA_PS_STATUS_SLEEP            1
-
-struct iwl_station_entry {
-       struct iwl_addsta_cmd sta;
-       struct iwl_tid_data tid[MAX_TID_COUNT];
-#if IWL == 3945
-       union {
-               struct {
-                       u8 rate;
-                       u8 flags;
-               } s;
-               u16 rate_n_flags;
-       } current_rate;
-#endif
-       u8 used;
-       u8 ps_status;
-       struct iwl_hw_key keyinfo;
-};
-
-/* one for each uCode image (inst/data, boot/init/runtime) */
-struct fw_image_desc {
-       void *v_addr;           /* access by driver */
-       dma_addr_t p_addr;      /* access by card's busmaster DMA */
-       u32 len;                /* bytes */
-};
-
-/* uCode file layout */
-struct iwl_ucode {
-       __le32 ver;             /* major/minor/subminor */
-       __le32 inst_size;       /* bytes of runtime instructions */
-       __le32 data_size;       /* bytes of runtime data */
-       __le32 init_size;       /* bytes of initialization instructions */
-       __le32 init_data_size;  /* bytes of initialization data */
-       __le32 boot_size;       /* bytes of bootstrap instructions */
-       u8 data[0];             /* data in same order as "size" elements */
-};
-
-#define IWL_IBSS_MAC_HASH_SIZE 32
-
-struct iwl_ibss_seq {
-       u8 mac[ETH_ALEN];
-       u16 seq_num;
-       u16 frag_num;
-       unsigned long packet_time;
-       struct list_head list;
-};
-
-struct iwl_driver_hw_info {
-       u16 max_txq_num;
-       u16 ac_queue_count;
-       u32 rx_buffer_size;
-       u16 tx_cmd_len;
-       u16 max_rxq_size;
-       u16 max_rxq_log;
-       u32 cck_flag;
-       u8  max_stations;
-       u8  bcast_sta_id;
-       void *shared_virt;
-       dma_addr_t shared_phys;
-};
-
-
-#define STA_FLG_RTS_MIMO_PROT_MSK      __constant_cpu_to_le32(1 << 17)
-#define STA_FLG_AGG_MPDU_8US_MSK       __constant_cpu_to_le32(1 << 18)
-#define STA_FLG_MAX_AGG_SIZE_POS       (19)
-#define STA_FLG_MAX_AGG_SIZE_MSK       __constant_cpu_to_le32(3 << 19)
-#define STA_FLG_FAT_EN_MSK             __constant_cpu_to_le32(1 << 21)
-#define STA_FLG_MIMO_DIS_MSK           __constant_cpu_to_le32(1 << 22)
-#define STA_FLG_AGG_MPDU_DENSITY_POS   (23)
-#define STA_FLG_AGG_MPDU_DENSITY_MSK   __constant_cpu_to_le32(7 << 23)
-#define HT_SHORT_GI_20MHZ_ONLY          (1 << 0)
-#define HT_SHORT_GI_40MHZ_ONLY          (1 << 1)
-
-
-#include "iwl-priv.h"
-
-/* Requires full declaration of iwl_priv before including */
-#include "iwl-io.h"
-
-#define IWL_RX_HDR(x) ((struct iwl_rx_frame_hdr *)(\
-                      x->u.rx_frame.stats.payload + \
-                      x->u.rx_frame.stats.phy_count))
-#define IWL_RX_END(x) ((struct iwl_rx_frame_end *)(\
-                      IWL_RX_HDR(x)->payload + \
-                      le16_to_cpu(IWL_RX_HDR(x)->len)))
-#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
-#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)
-
-
-/******************************************************************************
- *
- * Functions implemented in iwl-base.c which are forward declared here
- * for use by iwl-*.c
- *
- *****************************************************************************/
-struct iwl_addsta_cmd;
-extern int iwl_send_add_station(struct iwl_priv *priv,
-                               struct iwl_addsta_cmd *sta, u8 flags);
-extern const char *iwl_get_tx_fail_reason(u32 status);
-extern u8 iwl_add_station(struct iwl_priv *priv, const u8 *bssid,
-                         int is_ap, u8 flags);
-extern int iwl_is_network_packet(struct iwl_priv *priv,
-                                struct ieee80211_hdr *header);
-extern int iwl_power_init_handle(struct iwl_priv *priv);
-extern int iwl_eeprom_init(struct iwl_priv *priv);
-#ifdef CONFIG_IWLWIFI_DEBUG
-extern void iwl_report_frame(struct iwl_priv *priv,
-                            struct iwl_rx_packet *pkt,
-                            struct ieee80211_hdr *header, int group100);
-#else
-static inline void iwl_report_frame(struct iwl_priv *priv,
-                                   struct iwl_rx_packet *pkt,
-                                   struct ieee80211_hdr *header,
-                                   int group100) {}
-#endif
-extern int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv,
-                                        struct iwl_tx_queue *txq);
-extern void iwl_handle_data_packet_monitor(struct iwl_priv *priv,
-                                          struct iwl_rx_mem_buffer *rxb,
-                                          void *data, short len,
-                                          struct ieee80211_rx_status *stats,
-                                          u16 phy_flags);
-extern int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr
-                              *header);
-extern void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
-extern int iwl_rx_queue_alloc(struct iwl_priv *priv);
-extern void iwl_rx_queue_reset(struct iwl_priv *priv,
-                              struct iwl_rx_queue *rxq);
-extern int iwl_calc_db_from_ratio(int sig_ratio);
-extern int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm);
-extern int iwl_tx_queue_init(struct iwl_priv *priv,
-                            struct iwl_tx_queue *txq, int count, u32 id);
-extern int iwl_rx_queue_restock(struct iwl_priv *priv);
-extern void iwl_rx_replenish(void *data);
-extern void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-extern int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
-                           const void *data);
-extern int __must_check iwl_send_cmd_async(struct iwl_priv *priv,
-               struct iwl_host_cmd *cmd);
-extern int __must_check iwl_send_cmd_sync(struct iwl_priv *priv,
-               struct iwl_host_cmd *cmd);
-extern int __must_check iwl_send_cmd(struct iwl_priv *priv,
-               struct iwl_host_cmd *cmd);
-extern unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
-                                       struct ieee80211_hdr *hdr,
-                                       const u8 *dest, int left);
-extern int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
-                                        struct iwl_rx_queue *q);
-extern int iwl_send_statistics_request(struct iwl_priv *priv);
-extern void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
-                                  u32 decrypt_res,
-                                  struct ieee80211_rx_status *stats);
-extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
-
-extern const u8 BROADCAST_ADDR[ETH_ALEN];
-
-/*
- * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
- * call this... todo... fix that.
-*/
-extern u8 iwl_sync_station(struct iwl_priv *priv, int sta_id,
-                          u16 tx_rate, u8 flags);
-
-static inline int iwl_is_associated(struct iwl_priv *priv)
-{
-       return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-/******************************************************************************
- *
- * Functions implemented in iwl-[34]*.c which are forward declared here
- * for use by iwl-base.c
- *
- * NOTE:  The implementation of these functions are hardware specific
- * which is why they are in the hardware specific files (vs. iwl-base.c)
- *
- * Naming convention --
- * iwl_         <-- Its part of iwlwifi (should be changed to iwl_)
- * iwl_hw_      <-- Hardware specific (implemented in iwl-XXXX.c by all HW)
- * iwlXXXX_     <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
- * iwl_bg_      <-- Called from work queue context
- * iwl_mac_     <-- mac80211 callback
- *
- ****************************************************************************/
-extern void iwl_hw_rx_handler_setup(struct iwl_priv *priv);
-extern void iwl_hw_setup_deferred_work(struct iwl_priv *priv);
-extern void iwl_hw_cancel_deferred_work(struct iwl_priv *priv);
-extern int iwl_hw_rxq_stop(struct iwl_priv *priv);
-extern int iwl_hw_set_hw_setting(struct iwl_priv *priv);
-extern int iwl_hw_nic_init(struct iwl_priv *priv);
-extern void iwl_hw_card_show_info(struct iwl_priv *priv);
-extern int iwl_hw_nic_stop_master(struct iwl_priv *priv);
-extern void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
-extern void iwl_hw_txq_ctx_stop(struct iwl_priv *priv);
-extern int iwl_hw_nic_reset(struct iwl_priv *priv);
-extern int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
-                                       dma_addr_t addr, u16 len);
-extern int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
-extern int iwl_hw_get_temperature(struct iwl_priv *priv);
-extern int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-                               struct iwl_tx_queue *txq);
-extern unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
-                                struct iwl_frame *frame, u8 rate);
-extern int iwl_hw_get_rx_read(struct iwl_priv *priv);
-extern void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv,
-                                    struct iwl_cmd *cmd,
-                                    struct ieee80211_tx_control *ctrl,
-                                    struct ieee80211_hdr *hdr,
-                                    int sta_id, int tx_id);
-extern int iwl_hw_reg_send_txpower(struct iwl_priv *priv);
-extern int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
-extern void iwl_hw_rx_statistics(struct iwl_priv *priv,
-                                struct iwl_rx_mem_buffer *rxb);
-extern void iwl_disable_events(struct iwl_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl_priv *priv);
-
-/**
- * iwl_hw_find_station - Find station id for a given BSSID
- * @bssid: MAC address of station ID to find
- *
- * NOTE:  This should not be hardware specific but the code has
- * not yet been merged into a single common layer for managing the
- * station tables.
- */
-extern u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *bssid);
-
-extern int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel);
-extern int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
-#endif
index 9cf0211de67f497a8da8c0543f5c5e1cdd3e056c..5e10ce0d351c9e8467a83a1fb48725dec69f1c9b 100644 (file)
@@ -43,16 +43,14 @@ static struct chan_freq_power channel_freq_power_UN_BG[] = {
        {14, 2484, TX_PWR_DEFAULT}
 };
 
-static u8 wlan_region_2_code(u8 * region)
+static u8 lbs_region_2_code(u8 *region)
 {
        u8 i;
-       u8 size = sizeof(region_code_mapping)/
-                 sizeof(struct region_code_mapping);
 
        for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++)
                region[i] = toupper(region[i]);
 
-       for (i = 0; i < size; i++) {
+       for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
                if (!memcmp(region, region_code_mapping[i].region,
                            COUNTRY_CODE_LEN))
                        return (region_code_mapping[i].code);
@@ -62,12 +60,11 @@ static u8 wlan_region_2_code(u8 * region)
        return (region_code_mapping[0].code);
 }
 
-static u8 *wlan_code_2_region(u8 code)
+static u8 *lbs_code_2_region(u8 code)
 {
        u8 i;
-       u8 size = sizeof(region_code_mapping)
-                 / sizeof(struct region_code_mapping);
-       for (i = 0; i < size; i++) {
+
+       for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) {
                if (region_code_mapping[i].code == code)
                        return (region_code_mapping[i].region);
        }
@@ -82,7 +79,7 @@ static u8 *wlan_code_2_region(u8 code)
  *  @param nrchan   number of channels
  *  @return          the nrchan-th chan number
 */
-static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
+static u8 lbs_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 *chan)
 /*find the nrchan-th chan after the firstchan*/
 {
        u8 i;
@@ -90,8 +87,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
        u8 cfp_no;
 
        cfp = channel_freq_power_UN_BG;
-       cfp_no = sizeof(channel_freq_power_UN_BG) /
-           sizeof(struct chan_freq_power);
+       cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG);
 
        for (i = 0; i < cfp_no; i++) {
                if ((cfp + i)->channel == firstchan) {
@@ -117,7 +113,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan)
  *  @param parsed_region_chan   pointer to parsed_region_chan_11d
  *  @return                    TRUE; FALSE
 */
-static u8 wlan_channel_known_11d(u8 chan,
+static u8 lbs_channel_known_11d(u8 chan,
                          struct parsed_region_chan_11d * parsed_region_chan)
 {
        struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr;
@@ -138,19 +134,15 @@ static u8 wlan_channel_known_11d(u8 chan,
        return 0;
 }
 
-u32 libertas_chan_2_freq(u8 chan, u8 band)
+u32 lbs_chan_2_freq(u8 chan, u8 band)
 {
        struct chan_freq_power *cf;
-       u16 cnt;
        u16 i;
        u32 freq = 0;
 
        cf = channel_freq_power_UN_BG;
-       cnt =
-           sizeof(channel_freq_power_UN_BG) /
-           sizeof(struct chan_freq_power);
 
-       for (i = 0; i < cnt; i++) {
+       for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) {
                if (chan == cf[i].channel)
                        freq = cf[i].freq;
        }
@@ -160,7 +152,7 @@ u32 libertas_chan_2_freq(u8 chan, u8 band)
 
 static int generate_domain_info_11d(struct parsed_region_chan_11d
                                  *parsed_region_chan,
-                                 struct wlan_802_11d_domain_reg * domaininfo)
+                                 struct lbs_802_11d_domain_reg *domaininfo)
 {
        u8 nr_subband = 0;
 
@@ -225,7 +217,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
  *  @param *parsed_region_chan  pointer to parsed_region_chan_11d
  *  @return                    N/A
 */
-static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_chan,
+static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_chan,
                                          struct parsed_region_chan_11d *
                                          parsed_region_chan)
 {
@@ -246,7 +238,7 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
        parsed_region_chan->band = region_chan->band;
        parsed_region_chan->region = region_chan->region;
        memcpy(parsed_region_chan->countrycode,
-              wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
+              lbs_code_2_region(region_chan->region), COUNTRY_CODE_LEN);
 
        lbs_deb_11d("region 0x%x, band %d\n", parsed_region_chan->region,
               parsed_region_chan->band);
@@ -272,7 +264,7 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_
  *  @param chan                 chan
  *  @return                    TRUE;FALSE
 */
-static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
+static u8 lbs_region_chan_supported_11d(u8 region, u8 band, u8 chan)
 {
        struct chan_freq_power *cfp;
        int cfp_no;
@@ -281,7 +273,7 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
 
        lbs_deb_enter(LBS_DEB_11D);
 
-       cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
+       cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
        if (cfp == NULL)
                return 0;
 
@@ -346,7 +338,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
 
        /*Step1: check region_code */
        parsed_region_chan->region = region =
-           wlan_region_2_code(countryinfo->countrycode);
+           lbs_region_2_code(countryinfo->countrycode);
 
        lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region);
        lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode,
@@ -375,7 +367,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
                for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) {
                        /*step4: channel is supported? */
 
-                       if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) {
+                       if (!lbs_get_chan_11d(band, firstchan, i, &curchan)) {
                                /* Chan is not found in UN table */
                                lbs_deb_11d("chan is not supported: %d \n", i);
                                break;
@@ -383,7 +375,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
 
                        lastchan = curchan;
 
-                       if (wlan_region_chan_supported_11d
+                       if (lbs_region_chan_supported_11d
                            (region, band, curchan)) {
                                /*step5: Check if curchan is supported by mrvl in region */
                                parsed_region_chan->chanpwr[idx].chan = curchan;
@@ -419,14 +411,14 @@ done:
  *  @param parsed_region_chan   pointer to parsed_region_chan_11d
  *  @return                    PASSIVE if chan is unknown; ACTIVE if chan is known
 */
-u8 libertas_get_scan_type_11d(u8 chan,
+u8 lbs_get_scan_type_11d(u8 chan,
                          struct parsed_region_chan_11d * parsed_region_chan)
 {
        u8 scan_type = CMD_SCAN_TYPE_PASSIVE;
 
        lbs_deb_enter(LBS_DEB_11D);
 
-       if (wlan_channel_known_11d(chan, parsed_region_chan)) {
+       if (lbs_channel_known_11d(chan, parsed_region_chan)) {
                lbs_deb_11d("found, do active scan\n");
                scan_type = CMD_SCAN_TYPE_ACTIVE;
        } else {
@@ -438,29 +430,29 @@ u8 libertas_get_scan_type_11d(u8 chan,
 
 }
 
-void libertas_init_11d(wlan_private * priv)
+void lbs_init_11d(struct lbs_private *priv)
 {
-       priv->adapter->enable11d = 0;
-       memset(&(priv->adapter->parsed_region_chan), 0,
+       priv->enable11d = 0;
+       memset(&(priv->parsed_region_chan), 0,
               sizeof(struct parsed_region_chan_11d));
        return;
 }
 
 /**
  *  @brief This function sets DOMAIN INFO to FW
- *  @param priv       pointer to wlan_private
+ *  @param priv       pointer to struct lbs_private
  *  @return          0; -1
 */
-static int set_domain_info_11d(wlan_private * priv)
+static int set_domain_info_11d(struct lbs_private *priv)
 {
        int ret;
 
-       if (!priv->adapter->enable11d) {
+       if (!priv->enable11d) {
                lbs_deb_11d("dnld domain Info with 11d disabled\n");
                return 0;
        }
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
                                    CMD_ACT_SET,
                                    CMD_OPTION_WAITFORRSP, 0, NULL);
        if (ret)
@@ -471,28 +463,27 @@ static int set_domain_info_11d(wlan_private * priv)
 
 /**
  *  @brief This function setups scan channels
- *  @param priv       pointer to wlan_private
+ *  @param priv       pointer to struct lbs_private
  *  @param band       band
  *  @return          0
 */
-int libertas_set_universaltable(wlan_private * priv, u8 band)
+int lbs_set_universaltable(struct lbs_private *priv, u8 band)
 {
-       wlan_adapter *adapter = priv->adapter;
        u16 size = sizeof(struct chan_freq_power);
        u16 i = 0;
 
-       memset(adapter->universal_channel, 0,
-              sizeof(adapter->universal_channel));
+       memset(priv->universal_channel, 0,
+              sizeof(priv->universal_channel));
 
-       adapter->universal_channel[i].nrcfp =
+       priv->universal_channel[i].nrcfp =
            sizeof(channel_freq_power_UN_BG) / size;
        lbs_deb_11d("BG-band nrcfp %d\n",
-              adapter->universal_channel[i].nrcfp);
+              priv->universal_channel[i].nrcfp);
 
-       adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
-       adapter->universal_channel[i].valid = 1;
-       adapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
-       adapter->universal_channel[i].band = band;
+       priv->universal_channel[i].CFP = channel_freq_power_UN_BG;
+       priv->universal_channel[i].valid = 1;
+       priv->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+       priv->universal_channel[i].band = band;
        i++;
 
        return 0;
@@ -500,21 +491,20 @@ int libertas_set_universaltable(wlan_private * priv, u8 band)
 
 /**
  *  @brief This function implements command CMD_802_11D_DOMAIN_INFO
- *  @param priv       pointer to wlan_private
+ *  @param priv       pointer to struct lbs_private
  *  @param cmd        pointer to cmd buffer
  *  @param cmdno      cmd ID
  *  @param cmdOption  cmd action
  *  @return          0
 */
-int libertas_cmd_802_11d_domain_info(wlan_private * priv,
+int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
                                 struct cmd_ds_command *cmd, u16 cmdno,
                                 u16 cmdoption)
 {
        struct cmd_ds_802_11d_domain_info *pdomaininfo =
            &cmd->params.domaininfo;
        struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
-       wlan_adapter *adapter = priv->adapter;
-       u8 nr_subband = adapter->domainreg.nr_subband;
+       u8 nr_subband = priv->domainreg.nr_subband;
 
        lbs_deb_enter(LBS_DEB_11D);
 
@@ -526,12 +516,12 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
                cmd->size =
                    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
                lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
-                       (int)(cmd->size));
+                       le16_to_cpu(cmd->size));
                goto done;
        }
 
        domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
-       memcpy(domain->countrycode, adapter->domainreg.countrycode,
+       memcpy(domain->countrycode, priv->domainreg.countrycode,
               sizeof(domain->countrycode));
 
        domain->header.len =
@@ -539,7 +529,7 @@ int libertas_cmd_802_11d_domain_info(wlan_private * priv,
                             sizeof(domain->countrycode));
 
        if (nr_subband) {
-               memcpy(domain->subband, adapter->domainreg.subband,
+               memcpy(domain->subband, priv->domainreg.subband,
                       nr_subband * sizeof(struct ieeetypes_subbandset));
 
                cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
@@ -560,11 +550,11 @@ done:
 
 /**
  *  @brief This function parses countryinfo from AP and download country info to FW
- *  @param priv    pointer to wlan_private
+ *  @param priv    pointer to struct lbs_private
  *  @param resp    pointer to command response buffer
  *  @return       0; -1
  */
-int libertas_ret_802_11d_domain_info(wlan_private * priv,
+int lbs_ret_802_11d_domain_info(struct lbs_private *priv,
                                 struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
@@ -606,31 +596,30 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv,
 
 /**
  *  @brief This function parses countryinfo from AP and download country info to FW
- *  @param priv    pointer to wlan_private
+ *  @param priv    pointer to struct lbs_private
  *  @return       0; -1
  */
-int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
+int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
                                         struct bss_descriptor * bss)
 {
        int ret;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_11D);
-       if (priv->adapter->enable11d) {
-               memset(&adapter->parsed_region_chan, 0,
+       if (priv->enable11d) {
+               memset(&priv->parsed_region_chan, 0,
                       sizeof(struct parsed_region_chan_11d));
                ret = parse_domain_info_11d(&bss->countryinfo, 0,
-                                              &adapter->parsed_region_chan);
+                                              &priv->parsed_region_chan);
 
                if (ret == -1) {
                        lbs_deb_11d("error parsing domain_info from AP\n");
                        goto done;
                }
 
-               memset(&adapter->domainreg, 0,
-                      sizeof(struct wlan_802_11d_domain_reg));
-               generate_domain_info_11d(&adapter->parsed_region_chan,
-                                     &adapter->domainreg);
+               memset(&priv->domainreg, 0,
+                      sizeof(struct lbs_802_11d_domain_reg));
+               generate_domain_info_11d(&priv->parsed_region_chan,
+                                     &priv->domainreg);
 
                ret = set_domain_info_11d(priv);
 
@@ -648,25 +637,23 @@ done:
 
 /**
  *  @brief This function generates 11D info from user specified regioncode and download to FW
- *  @param priv    pointer to wlan_private
+ *  @param priv    pointer to struct lbs_private
  *  @return       0; -1
  */
-int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
+int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv)
 {
        int ret;
-       wlan_adapter *adapter = priv->adapter;
        struct region_channel *region_chan;
        u8 j;
 
        lbs_deb_enter(LBS_DEB_11D);
-       lbs_deb_11d("curbssparams.band %d\n", adapter->curbssparams.band);
+       lbs_deb_11d("curbssparams.band %d\n", priv->curbssparams.band);
 
-       if (priv->adapter->enable11d) {
+       if (priv->enable11d) {
                /* update parsed_region_chan_11; dnld domaininf to FW */
 
-               for (j = 0; j < sizeof(adapter->region_channel) /
-                    sizeof(adapter->region_channel[0]); j++) {
-                       region_chan = &adapter->region_channel[j];
+               for (j = 0; j < ARRAY_SIZE(priv->region_channel); j++) {
+                       region_chan = &priv->region_channel[j];
 
                        lbs_deb_11d("%d region_chan->band %d\n", j,
                               region_chan->band);
@@ -674,29 +661,28 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv)
                        if (!region_chan || !region_chan->valid
                            || !region_chan->CFP)
                                continue;
-                       if (region_chan->band != adapter->curbssparams.band)
+                       if (region_chan->band != priv->curbssparams.band)
                                continue;
                        break;
                }
 
-               if (j >= sizeof(adapter->region_channel) /
-                   sizeof(adapter->region_channel[0])) {
+               if (j >= ARRAY_SIZE(priv->region_channel)) {
                        lbs_deb_11d("region_chan not found, band %d\n",
-                              adapter->curbssparams.band);
+                              priv->curbssparams.band);
                        ret = -1;
                        goto done;
                }
 
-               memset(&adapter->parsed_region_chan, 0,
+               memset(&priv->parsed_region_chan, 0,
                       sizeof(struct parsed_region_chan_11d));
-               wlan_generate_parsed_region_chan_11d(region_chan,
-                                                    &adapter->
+               lbs_generate_parsed_region_chan_11d(region_chan,
+                                                    &priv->
                                                     parsed_region_chan);
 
-               memset(&adapter->domainreg, 0,
-                      sizeof(struct wlan_802_11d_domain_reg));
-               generate_domain_info_11d(&adapter->parsed_region_chan,
-                                        &adapter->domainreg);
+               memset(&priv->domainreg, 0,
+                      sizeof(struct lbs_802_11d_domain_reg));
+               generate_domain_info_11d(&priv->parsed_region_chan,
+                                        &priv->domainreg);
 
                ret = set_domain_info_11d(priv);
 
index 3a6d1f8db78fcaee88e6bf81bf7e7049d811ffad..811eea2cfba36f7830b491417f64050f6665003d 100644 (file)
@@ -2,8 +2,8 @@
   * This header file contains data structures and
   * function declarations of 802.11d
   */
-#ifndef _WLAN_11D_
-#define _WLAN_11D_
+#ifndef _LBS_11D_
+#define _LBS_11D_
 
 #include "types.h"
 #include "defs.h"
@@ -52,7 +52,7 @@ struct cmd_ds_802_11d_domain_info {
 } __attribute__ ((packed));
 
 /** domain regulatory information */
-struct wlan_802_11d_domain_reg {
+struct lbs_802_11d_domain_reg {
        /** country Code*/
        u8 countrycode[COUNTRY_CODE_LEN];
        /** No. of subband*/
@@ -78,26 +78,28 @@ struct region_code_mapping {
        u8 code;
 };
 
-u8 libertas_get_scan_type_11d(u8 chan,
+struct lbs_private;
+
+u8 lbs_get_scan_type_11d(u8 chan,
                          struct parsed_region_chan_11d *parsed_region_chan);
 
-u32 libertas_chan_2_freq(u8 chan, u8 band);
+u32 lbs_chan_2_freq(u8 chan, u8 band);
 
-void libertas_init_11d(wlan_private * priv);
+void lbs_init_11d(struct lbs_private *priv);
 
-int libertas_set_universaltable(wlan_private * priv, u8 band);
+int lbs_set_universaltable(struct lbs_private *priv, u8 band);
 
-int libertas_cmd_802_11d_domain_info(wlan_private * priv,
+int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
                                 struct cmd_ds_command *cmd, u16 cmdno,
                                 u16 cmdOption);
 
-int libertas_ret_802_11d_domain_info(wlan_private * priv,
+int lbs_ret_802_11d_domain_info(struct lbs_private *priv,
                                 struct cmd_ds_command *resp);
 
 struct bss_descriptor;
-int libertas_parse_dnld_countryinfo_11d(wlan_private * priv,
+int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
                                         struct bss_descriptor * bss);
 
-int libertas_create_dnld_countryinfo_11d(wlan_private * priv);
+int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv);
 
-#endif                         /* _WLAN_11D_ */
+#endif
index 0b133ce6380541069b1c69ffd79641c8ec9eb301..d860fc375752d928b3d51e2ec7e6cca1fdd416d8 100644 (file)
@@ -195,45 +195,33 @@ setuserscan
 
          where [ARGS]:
 
-      chan=[chan#][band][mode] where band is [a,b,g] and mode is
-                               blank for active or 'p' for passive
       bssid=xx:xx:xx:xx:xx:xx  specify a BSSID filter for the scan
       ssid="[SSID]"            specify a SSID filter for the scan
       keep=[0 or 1]            keep the previous scan results (1), discard (0)
       dur=[scan time]          time to scan for each channel in milliseconds
-      probes=[#]               number of probe requests to send on each chan
       type=[1,2,3]             BSS type: 1 (Infra), 2(Adhoc), 3(Any)
 
-    Any combination of the above arguments can be supplied on the command line.
-      If the chan token is absent, a full channel scan will be completed by
-      the driver.  If the dur or probes tokens are absent, the driver default
-      setting will be used.  The bssid and ssid fields, if blank,
-      will produce an unfiltered scan. The type field will default to 3 (Any)
-      and the keep field will default to 0 (Discard).
+    Any combination of the above arguments can be supplied on the command
+    line. If dur tokens are absent, the driver default setting will be used.
+    The bssid and ssid fields, if blank, will produce an unfiltered scan.
+    The type field will default to 3 (Any) and the keep field will default
+    to 0 (Discard).
 
     Examples:
-    1) Perform an active scan on channels 1, 6, and 11 in the 'g' band:
-            echo "chan=1g,6g,11g" > setuserscan
+    1) Perform a passive scan on all channels for 20 ms per channel:
+            echo "dur=20" > setuserscan
 
-    2) Perform a passive scan on channel 11 for 20 ms:
-            echo "chan=11gp dur=20" > setuserscan
+    2) Perform an active scan for a specific SSID:
+            echo "ssid="TestAP"" > setuserscan
 
-    3) Perform an active scan on channels 1, 6, and 11; and a passive scan on
-       channel 36 in the 'a' band:
-
-            echo "chan=1g,6g,11g,36ap" > setuserscan
-
-    4) Perform an active scan on channel 6 and 36 for a specific SSID:
-            echo "chan=6g,36a ssid="TestAP"" > setuserscan
-
-    5) Scan all available channels (B/G, A bands) for a specific BSSID, keep
+    3) Scan all available channels (B/G, A bands) for a specific BSSID, keep
        the current scan table intact, update existing or append new scan data:
             echo "bssid=00:50:43:20:12:82 keep=1" > setuserscan
 
-    6) Scan channel 6, for all infrastructure networks, sending two probe
-       requests.  Keep the previous scan table intact. Update any duplicate
-       BSSID/SSID matches with the new scan data:
-            echo "chan=6g type=1 probes=2 keep=1" > setuserscan
+    4) Scan for all infrastructure networks.
+       Keep the previous scan table intact. Update any duplicate BSSID/SSID
+       matches with the new scan data:
+            echo "type=1 keep=1" > setuserscan
 
     All entries in the scan table (not just the new scan data when keep=1)
     will be displayed upon completion by use of the getscantable ioctl.
index b61b176e9d07a9e234f41444db7c618030772bb4..c622e9b63cd1cc62a0233e9fb30a8d6ae1853440 100644 (file)
@@ -9,39 +9,16 @@
 #include "decl.h"
 #include "hostcmd.h"
 #include "host.h"
+#include "cmd.h"
 
 
 static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-static void print_assoc_req(const char * extra, struct assoc_request * assoc_req)
-{
-       DECLARE_MAC_BUF(mac);
-       lbs_deb_assoc(
-              "#### Association Request: %s\n"
-              "       flags:      0x%08lX\n"
-              "       SSID:       '%s'\n"
-              "       channel:    %d\n"
-              "       band:       %d\n"
-              "       mode:       %d\n"
-              "       BSSID:      %s\n"
-              "       Encryption:%s%s%s\n"
-              "       auth:       %d\n",
-              extra, assoc_req->flags,
-              escape_essid(assoc_req->ssid, assoc_req->ssid_len),
-              assoc_req->channel, assoc_req->band, assoc_req->mode,
-              print_mac(mac, assoc_req->bssid),
-              assoc_req->secinfo.WPAenabled ? " WPA" : "",
-              assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
-              assoc_req->secinfo.wep_enabled ? " WEP" : "",
-              assoc_req->secinfo.auth_mode);
-}
-
 
-static int assoc_helper_essid(wlan_private *priv,
+static int assoc_helper_essid(struct lbs_private *priv,
                               struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        struct bss_descriptor * bss;
        int channel = -1;
@@ -55,18 +32,17 @@ static int assoc_helper_essid(wlan_private *priv,
        if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
                channel = assoc_req->channel;
 
-       lbs_deb_assoc("New SSID requested: '%s'\n",
+       lbs_deb_assoc("SSID '%s' requested\n",
                      escape_essid(assoc_req->ssid, assoc_req->ssid_len));
        if (assoc_req->mode == IW_MODE_INFRA) {
-               libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
+               lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
                        assoc_req->ssid_len, 0);
 
-               bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
+               bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
                                assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
                if (bss != NULL) {
-                       lbs_deb_assoc("SSID found in scan list, associating\n");
                        memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
-                       ret = wlan_associate(priv, assoc_req);
+                       ret = lbs_associate(priv, assoc_req);
                } else {
                        lbs_deb_assoc("SSID not found; cannot associate\n");
                }
@@ -74,23 +50,23 @@ static int assoc_helper_essid(wlan_private *priv,
                /* Scan for the network, do not save previous results.  Stale
                 *   scan data will cause us to join a non-existant adhoc network
                 */
-               libertas_send_specific_ssid_scan(priv, assoc_req->ssid,
+               lbs_send_specific_ssid_scan(priv, assoc_req->ssid,
                        assoc_req->ssid_len, 1);
 
                /* Search for the requested SSID in the scan table */
-               bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid,
+               bss = lbs_find_ssid_in_list(priv, assoc_req->ssid,
                                assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel);
                if (bss != NULL) {
                        lbs_deb_assoc("SSID found, will join\n");
                        memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
-                       libertas_join_adhoc_network(priv, assoc_req);
+                       lbs_join_adhoc_network(priv, assoc_req);
                } else {
                        /* else send START command */
                        lbs_deb_assoc("SSID not found, creating adhoc network\n");
                        memcpy(&assoc_req->bss.ssid, &assoc_req->ssid,
                                IW_ESSID_MAX_SIZE);
                        assoc_req->bss.ssid_len = assoc_req->ssid_len;
-                       libertas_start_adhoc_network(priv, assoc_req);
+                       lbs_start_adhoc_network(priv, assoc_req);
                }
        }
 
@@ -99,10 +75,9 @@ static int assoc_helper_essid(wlan_private *priv,
 }
 
 
-static int assoc_helper_bssid(wlan_private *priv,
+static int assoc_helper_bssid(struct lbs_private *priv,
                               struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        struct bss_descriptor * bss;
        DECLARE_MAC_BUF(mac);
@@ -111,7 +86,7 @@ static int assoc_helper_bssid(wlan_private *priv,
                print_mac(mac, assoc_req->bssid));
 
        /* Search for index position in list for requested MAC */
-       bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid,
+       bss = lbs_find_bssid_in_list(priv, assoc_req->bssid,
                            assoc_req->mode);
        if (bss == NULL) {
                lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, "
@@ -121,10 +96,10 @@ static int assoc_helper_bssid(wlan_private *priv,
 
        memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
        if (assoc_req->mode == IW_MODE_INFRA) {
-               ret = wlan_associate(priv, assoc_req);
-               lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret);
+               ret = lbs_associate(priv, assoc_req);
+               lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret);
        } else if (assoc_req->mode == IW_MODE_ADHOC) {
-               libertas_join_adhoc_network(priv, assoc_req);
+               lbs_join_adhoc_network(priv, assoc_req);
        }
 
 out:
@@ -133,11 +108,13 @@ out:
 }
 
 
-static int assoc_helper_associate(wlan_private *priv,
+static int assoc_helper_associate(struct lbs_private *priv,
                                   struct assoc_request * assoc_req)
 {
        int ret = 0, done = 0;
 
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
        /* If we're given and 'any' BSSID, try associating based on SSID */
 
        if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
@@ -145,42 +122,36 @@ static int assoc_helper_associate(wlan_private *priv,
                    && compare_ether_addr(bssid_off, assoc_req->bssid)) {
                        ret = assoc_helper_bssid(priv, assoc_req);
                        done = 1;
-                       if (ret) {
-                               lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
-                       }
                }
        }
 
        if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
                ret = assoc_helper_essid(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret);
-               }
        }
 
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
 
-static int assoc_helper_mode(wlan_private *priv,
+static int assoc_helper_mode(struct lbs_private *priv,
                              struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       if (assoc_req->mode == adapter->mode)
+       if (assoc_req->mode == priv->mode)
                goto done;
 
        if (assoc_req->mode == IW_MODE_INFRA) {
-               if (adapter->psstate != PS_STATE_FULL_POWER)
-                       libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
-               adapter->psmode = WLAN802_11POWERMODECAM;
+               if (priv->psstate != PS_STATE_FULL_POWER)
+                       lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
+               priv->psmode = LBS802_11POWERMODECAM;
        }
 
-       adapter->mode = assoc_req->mode;
-       ret = libertas_prepare_and_send_command(priv,
+       priv->mode = assoc_req->mode;
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_SNMP_MIB,
                                    0, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_INFRASTRUCTURE_MODE,
@@ -192,57 +163,76 @@ done:
 }
 
 
-static int update_channel(wlan_private * priv)
+int lbs_update_channel(struct lbs_private *priv)
 {
-       /* the channel in f/w could be out of sync, get the current channel */
-       return libertas_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
-                                   CMD_OPT_802_11_RF_CHANNEL_GET,
-                                   CMD_OPTION_WAITFORRSP, 0, NULL);
+       int ret;
+
+       /* the channel in f/w could be out of sync; get the current channel */
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
+       ret = lbs_get_channel(priv);
+       if (ret > 0) {
+               priv->curbssparams.channel = ret;
+               ret = 0;
+       }
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+       return ret;
 }
 
-void libertas_sync_channel(struct work_struct *work)
+void lbs_sync_channel(struct work_struct *work)
 {
-       wlan_private *priv = container_of(work, wlan_private, sync_channel);
+       struct lbs_private *priv = container_of(work, struct lbs_private,
+               sync_channel);
 
-       if (update_channel(priv) != 0)
+       lbs_deb_enter(LBS_DEB_ASSOC);
+       if (lbs_update_channel(priv))
                lbs_pr_info("Channel synchronization failed.");
+       lbs_deb_leave(LBS_DEB_ASSOC);
 }
 
-static int assoc_helper_channel(wlan_private *priv,
+static int assoc_helper_channel(struct lbs_private *priv,
                                 struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       ret = update_channel(priv);
-       if (ret < 0) {
-               lbs_deb_assoc("ASSOC: channel: error getting channel.");
+       ret = lbs_update_channel(priv);
+       if (ret) {
+               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+               goto done;
        }
 
-       if (assoc_req->channel == adapter->curbssparams.channel)
+       if (assoc_req->channel == priv->curbssparams.channel)
                goto done;
 
+       if (priv->mesh_dev) {
+               /* Change mesh channel first; 21.p21 firmware won't let
+                  you change channel otherwise (even though it'll return
+                  an error to this */
+               lbs_mesh_config(priv, 0, assoc_req->channel);
+       }
+
        lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
-              adapter->curbssparams.channel, assoc_req->channel);
+                     priv->curbssparams.channel, assoc_req->channel);
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
-                               CMD_OPT_802_11_RF_CHANNEL_SET,
-                               CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel);
-       if (ret < 0) {
-               lbs_deb_assoc("ASSOC: channel: error setting channel.");
-       }
+       ret = lbs_set_channel(priv, assoc_req->channel);
+       if (ret < 0)
+               lbs_deb_assoc("ASSOC: channel: error setting channel.\n");
 
-       ret = update_channel(priv);
-       if (ret < 0) {
-               lbs_deb_assoc("ASSOC: channel: error getting channel.");
+       /* FIXME: shouldn't need to grab the channel _again_ after setting
+        * it since the firmware is supposed to return the new channel, but
+        * whatever... */
+       ret = lbs_update_channel(priv);
+       if (ret) {
+               lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+               goto done;
        }
 
-       if (assoc_req->channel != adapter->curbssparams.channel) {
-               lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
+       if (assoc_req->channel != priv->curbssparams.channel) {
+               lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
                              assoc_req->channel);
-               goto done;
+               goto restore_mesh;
        }
 
        if (   assoc_req->secinfo.wep_enabled
@@ -255,83 +245,75 @@ static int assoc_helper_channel(wlan_private *priv,
        }
 
        /* Must restart/rejoin adhoc networks after channel change */
-       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
+       set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 
-done:
+ restore_mesh:
+       if (priv->mesh_dev)
+               lbs_mesh_config(priv, 1, priv->curbssparams.channel);
+
+ done:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
 
-static int assoc_helper_wep_keys(wlan_private *priv,
-                                 struct assoc_request * assoc_req)
+static int assoc_helper_wep_keys(struct lbs_private *priv,
+                                struct assoc_request *assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int i;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        /* Set or remove WEP keys */
-       if (   assoc_req->wep_keys[0].len
-           || assoc_req->wep_keys[1].len
-           || assoc_req->wep_keys[2].len
-           || assoc_req->wep_keys[3].len) {
-               ret = libertas_prepare_and_send_command(priv,
-                                           CMD_802_11_SET_WEP,
-                                           CMD_ACT_ADD,
-                                           CMD_OPTION_WAITFORRSP,
-                                           0, assoc_req);
-       } else {
-               ret = libertas_prepare_and_send_command(priv,
-                                           CMD_802_11_SET_WEP,
-                                           CMD_ACT_REMOVE,
-                                           CMD_OPTION_WAITFORRSP,
-                                           0, NULL);
-       }
+       if (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len ||
+           assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)
+               ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_ADD, assoc_req);
+       else
+               ret = lbs_cmd_802_11_set_wep(priv, CMD_ACT_REMOVE, assoc_req);
 
        if (ret)
                goto out;
 
        /* enable/disable the MAC's WEP packet filter */
        if (assoc_req->secinfo.wep_enabled)
-               adapter->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE;
+               priv->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE;
        else
-               adapter->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE;
-       ret = libertas_set_mac_packet_filter(priv);
+               priv->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE;
+
+       ret = lbs_set_mac_packet_filter(priv);
        if (ret)
                goto out;
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
-       /* Copy WEP keys into adapter wep key fields */
+       /* Copy WEP keys into priv wep key fields */
        for (i = 0; i < 4; i++) {
-               memcpy(&adapter->wep_keys[i], &assoc_req->wep_keys[i],
-                       sizeof(struct enc_key));
+               memcpy(&priv->wep_keys[i], &assoc_req->wep_keys[i],
+                      sizeof(struct enc_key));
        }
-       adapter->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
+       priv->wep_tx_keyidx = assoc_req->wep_tx_keyidx;
 
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
-static int assoc_helper_secinfo(wlan_private *priv,
+static int assoc_helper_secinfo(struct lbs_private *priv,
                                 struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
-       u32 do_wpa;
-       u32 rsn = 0;
+       uint16_t do_wpa;
+       uint16_t rsn = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       memcpy(&adapter->secinfo, &assoc_req->secinfo,
-               sizeof(struct wlan_802_11_security));
+       memcpy(&priv->secinfo, &assoc_req->secinfo,
+               sizeof(struct lbs_802_11_security));
 
-       ret = libertas_set_mac_packet_filter(priv);
+       ret = lbs_set_mac_packet_filter(priv);
        if (ret)
                goto out;
 
@@ -341,28 +323,19 @@ static int assoc_helper_secinfo(wlan_private *priv,
         */
 
        /* Get RSN enabled/disabled */
-       ret = libertas_prepare_and_send_command(priv,
-                                   CMD_802_11_ENABLE_RSN,
-                                   CMD_ACT_GET,
-                                   CMD_OPTION_WAITFORRSP,
-                                   0, &rsn);
+       ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_GET, &rsn);
        if (ret) {
-               lbs_deb_assoc("Failed to get RSN status: %d", ret);
+               lbs_deb_assoc("Failed to get RSN status: %d\n", ret);
                goto out;
        }
 
        /* Don't re-enable RSN if it's already enabled */
-       do_wpa = (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled);
+       do_wpa = assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled;
        if (do_wpa == rsn)
                goto out;
 
        /* Set RSN enabled/disabled */
-       rsn = do_wpa;
-       ret = libertas_prepare_and_send_command(priv,
-                                   CMD_802_11_ENABLE_RSN,
-                                   CMD_ACT_SET,
-                                   CMD_OPTION_WAITFORRSP,
-                                   0, &rsn);
+       ret = lbs_cmd_802_11_enable_rsn(priv, CMD_ACT_SET, &do_wpa);
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -370,7 +343,7 @@ out:
 }
 
 
-static int assoc_helper_wpa_keys(wlan_private *priv,
+static int assoc_helper_wpa_keys(struct lbs_private *priv,
                                  struct assoc_request * assoc_req)
 {
        int ret = 0;
@@ -385,7 +358,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
 
        if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
                clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags);
-               ret = libertas_prepare_and_send_command(priv,
+               ret = lbs_prepare_and_send_command(priv,
                                        CMD_802_11_KEY_MATERIAL,
                                        CMD_ACT_SET,
                                        CMD_OPTION_WAITFORRSP,
@@ -399,7 +372,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv,
        if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
                clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags);
 
-               ret = libertas_prepare_and_send_command(priv,
+               ret = lbs_prepare_and_send_command(priv,
                                        CMD_802_11_KEY_MATERIAL,
                                        CMD_ACT_SET,
                                        CMD_OPTION_WAITFORRSP,
@@ -413,20 +386,19 @@ out:
 }
 
 
-static int assoc_helper_wpa_ie(wlan_private *priv,
+static int assoc_helper_wpa_ie(struct lbs_private *priv,
                                struct assoc_request * assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
        if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
-               memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
-               adapter->wpa_ie_len = assoc_req->wpa_ie_len;
+               memcpy(&priv->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len);
+               priv->wpa_ie_len = assoc_req->wpa_ie_len;
        } else {
-               memset(&adapter->wpa_ie, 0, MAX_WPA_IE_LEN);
-               adapter->wpa_ie_len = 0;
+               memset(&priv->wpa_ie, 0, MAX_WPA_IE_LEN);
+               priv->wpa_ie_len = 0;
        }
 
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -434,55 +406,68 @@ static int assoc_helper_wpa_ie(wlan_private *priv,
 }
 
 
-static int should_deauth_infrastructure(wlan_adapter *adapter,
+static int should_deauth_infrastructure(struct lbs_private *priv,
                                         struct assoc_request * assoc_req)
 {
-       if (adapter->connect_status != LIBERTAS_CONNECTED)
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
+       if (priv->connect_status != LBS_CONNECTED)
                return 0;
 
        if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
-               lbs_deb_assoc("Deauthenticating due to new SSID in "
-                       " configuration request.\n");
-               return 1;
+               lbs_deb_assoc("Deauthenticating due to new SSID\n");
+               ret = 1;
+               goto out;
        }
 
        if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
-               if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
-                       lbs_deb_assoc("Deauthenticating due to updated security "
-                               "info in configuration request.\n");
-                       return 1;
+               if (priv->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
+                       lbs_deb_assoc("Deauthenticating due to new security\n");
+                       ret = 1;
+                       goto out;
                }
        }
 
        if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
-               lbs_deb_assoc("Deauthenticating due to new BSSID in "
-                       " configuration request.\n");
-               return 1;
+               lbs_deb_assoc("Deauthenticating due to new BSSID\n");
+               ret = 1;
+               goto out;
        }
 
        if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
-               lbs_deb_assoc("Deauthenticating due to channel switch.\n");
-               return 1;
+               lbs_deb_assoc("Deauthenticating due to channel switch\n");
+               ret = 1;
+               goto out;
        }
 
        /* FIXME: deal with 'auto' mode somehow */
        if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
-               if (assoc_req->mode != IW_MODE_INFRA)
-                       return 1;
+               if (assoc_req->mode != IW_MODE_INFRA) {
+                       lbs_deb_assoc("Deauthenticating due to leaving "
+                               "infra mode\n");
+                       ret = 1;
+                       goto out;
+               }
        }
 
+out:
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return 0;
 }
 
 
-static int should_stop_adhoc(wlan_adapter *adapter,
+static int should_stop_adhoc(struct lbs_private *priv,
                              struct assoc_request * assoc_req)
 {
-       if (adapter->connect_status != LIBERTAS_CONNECTED)
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
+       if (priv->connect_status != LBS_CONNECTED)
                return 0;
 
-       if (libertas_ssid_cmp(adapter->curbssparams.ssid,
-                             adapter->curbssparams.ssid_len,
+       if (lbs_ssid_cmp(priv->curbssparams.ssid,
+                             priv->curbssparams.ssid_len,
                              assoc_req->ssid, assoc_req->ssid_len) != 0)
                return 1;
 
@@ -493,18 +478,19 @@ static int should_stop_adhoc(wlan_adapter *adapter,
        }
 
        if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
-               if (assoc_req->channel != adapter->curbssparams.channel)
+               if (assoc_req->channel != priv->curbssparams.channel)
                        return 1;
        }
 
+       lbs_deb_leave(LBS_DEB_ASSOC);
        return 0;
 }
 
 
-void libertas_association_worker(struct work_struct *work)
+void lbs_association_worker(struct work_struct *work)
 {
-       wlan_private *priv = container_of(work, wlan_private, assoc_work.work);
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = container_of(work, struct lbs_private,
+               assoc_work.work);
        struct assoc_request * assoc_req = NULL;
        int ret = 0;
        int find_any_ssid = 0;
@@ -512,16 +498,33 @@ void libertas_association_worker(struct work_struct *work)
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = adapter->pending_assoc_req;
-       adapter->pending_assoc_req = NULL;
-       adapter->in_progress_assoc_req = assoc_req;
-       mutex_unlock(&adapter->lock);
+       mutex_lock(&priv->lock);
+       assoc_req = priv->pending_assoc_req;
+       priv->pending_assoc_req = NULL;
+       priv->in_progress_assoc_req = assoc_req;
+       mutex_unlock(&priv->lock);
 
        if (!assoc_req)
                goto done;
 
-       print_assoc_req(__func__, assoc_req);
+       lbs_deb_assoc(
+               "Association Request:\n"
+               "    flags:     0x%08lx\n"
+               "    SSID:      '%s'\n"
+               "    chann:     %d\n"
+               "    band:      %d\n"
+               "    mode:      %d\n"
+               "    BSSID:     %s\n"
+               "    secinfo:  %s%s%s\n"
+               "    auth_mode: %d\n",
+               assoc_req->flags,
+               escape_essid(assoc_req->ssid, assoc_req->ssid_len),
+               assoc_req->channel, assoc_req->band, assoc_req->mode,
+               print_mac(mac, assoc_req->bssid),
+               assoc_req->secinfo.WPAenabled ? " WPA" : "",
+               assoc_req->secinfo.WPA2enabled ? " WPA2" : "",
+               assoc_req->secinfo.wep_enabled ? " WEP" : "",
+               assoc_req->secinfo.auth_mode);
 
        /* If 'any' SSID was specified, find an SSID to associate with */
        if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)
@@ -538,7 +541,7 @@ void libertas_association_worker(struct work_struct *work)
        if (find_any_ssid) {
                u8 new_mode;
 
-               ret = libertas_find_best_network_ssid(priv, assoc_req->ssid,
+               ret = lbs_find_best_network_ssid(priv, assoc_req->ssid,
                                &assoc_req->ssid_len, assoc_req->mode, &new_mode);
                if (ret) {
                        lbs_deb_assoc("Could not find best network\n");
@@ -557,18 +560,18 @@ void libertas_association_worker(struct work_struct *work)
         * Check if the attributes being changing require deauthentication
         * from the currently associated infrastructure access point.
         */
-       if (adapter->mode == IW_MODE_INFRA) {
-               if (should_deauth_infrastructure(adapter, assoc_req)) {
-                       ret = libertas_send_deauthentication(priv);
+       if (priv->mode == IW_MODE_INFRA) {
+               if (should_deauth_infrastructure(priv, assoc_req)) {
+                       ret = lbs_send_deauthentication(priv);
                        if (ret) {
                                lbs_deb_assoc("Deauthentication due to new "
                                        "configuration request failed: %d\n",
                                        ret);
                        }
                }
-       } else if (adapter->mode == IW_MODE_ADHOC) {
-               if (should_stop_adhoc(adapter, assoc_req)) {
-                       ret = libertas_stop_adhoc_network(priv);
+       } else if (priv->mode == IW_MODE_ADHOC) {
+               if (should_stop_adhoc(priv, assoc_req)) {
+                       ret = lbs_stop_adhoc_network(priv);
                        if (ret) {
                                lbs_deb_assoc("Teardown of AdHoc network due to "
                                        "new configuration request failed: %d\n",
@@ -581,58 +584,40 @@ void libertas_association_worker(struct work_struct *work)
        /* Send the various configuration bits to the firmware */
        if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
                ret = assoc_helper_mode(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) {
                ret = assoc_helper_channel(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        if (   test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)
            || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) {
                ret = assoc_helper_wep_keys(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
                ret = assoc_helper_secinfo(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
                ret = assoc_helper_wpa_ie(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)
            || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
                ret = assoc_helper_wpa_keys(priv, assoc_req);
-               if (ret) {
-                       lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n",
-                                     __LINE__, ret);
+               if (ret)
                        goto out;
-               }
        }
 
        /* SSID/BSSID should be the _last_ config option set, because they
@@ -644,28 +629,27 @@ void libertas_association_worker(struct work_struct *work)
 
                ret = assoc_helper_associate(priv, assoc_req);
                if (ret) {
-                       lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n",
+                       lbs_deb_assoc("ASSOC: association unsuccessful: %d\n",
                                ret);
                        success = 0;
                }
 
-               if (adapter->connect_status != LIBERTAS_CONNECTED) {
-                       lbs_deb_assoc("ASSOC: association attempt unsuccessful, "
-                               "not connected.\n");
+               if (priv->connect_status != LBS_CONNECTED) {
+                       lbs_deb_assoc("ASSOC: association unsuccessful, "
+                               "not connected\n");
                        success = 0;
                }
 
                if (success) {
-                       lbs_deb_assoc("ASSOC: association attempt successful. "
-                               "Associated to '%s' (%s)\n",
-                               escape_essid(adapter->curbssparams.ssid,
-                                            adapter->curbssparams.ssid_len),
-                               print_mac(mac, adapter->curbssparams.bssid));
-                       libertas_prepare_and_send_command(priv,
+                       lbs_deb_assoc("ASSOC: associated to '%s', %s\n",
+                               escape_essid(priv->curbssparams.ssid,
+                                            priv->curbssparams.ssid_len),
+                               print_mac(mac, priv->curbssparams.bssid));
+                       lbs_prepare_and_send_command(priv,
                                CMD_802_11_RSSI,
                                0, CMD_OPTION_WAITFORRSP, 0, NULL);
 
-                       libertas_prepare_and_send_command(priv,
+                       lbs_prepare_and_send_command(priv,
                                CMD_802_11_GET_LOG,
                                0, CMD_OPTION_WAITFORRSP, 0, NULL);
                } else {
@@ -679,9 +663,9 @@ out:
                        ret);
        }
 
-       mutex_lock(&adapter->lock);
-       adapter->in_progress_assoc_req = NULL;
-       mutex_unlock(&adapter->lock);
+       mutex_lock(&priv->lock);
+       priv->in_progress_assoc_req = NULL;
+       mutex_unlock(&priv->lock);
        kfree(assoc_req);
 
 done:
@@ -692,14 +676,15 @@ done:
 /*
  * Caller MUST hold any necessary locks
  */
-struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
+struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
 {
        struct assoc_request * assoc_req;
 
-       if (!adapter->pending_assoc_req) {
-               adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
+       lbs_deb_enter(LBS_DEB_ASSOC);
+       if (!priv->pending_assoc_req) {
+               priv->pending_assoc_req = kzalloc(sizeof(struct assoc_request),
                                                     GFP_KERNEL);
-               if (!adapter->pending_assoc_req) {
+               if (!priv->pending_assoc_req) {
                        lbs_pr_info("Not enough memory to allocate association"
                                " request!\n");
                        return NULL;
@@ -709,60 +694,59 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
        /* Copy current configuration attributes to the association request,
         * but don't overwrite any that are already set.
         */
-       assoc_req = adapter->pending_assoc_req;
+       assoc_req = priv->pending_assoc_req;
        if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) {
-               memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid,
+               memcpy(&assoc_req->ssid, &priv->curbssparams.ssid,
                       IW_ESSID_MAX_SIZE);
-               assoc_req->ssid_len = adapter->curbssparams.ssid_len;
+               assoc_req->ssid_len = priv->curbssparams.ssid_len;
        }
 
        if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags))
-               assoc_req->channel = adapter->curbssparams.channel;
+               assoc_req->channel = priv->curbssparams.channel;
 
        if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags))
-               assoc_req->band = adapter->curbssparams.band;
+               assoc_req->band = priv->curbssparams.band;
 
        if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
-               assoc_req->mode = adapter->mode;
+               assoc_req->mode = priv->mode;
 
        if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
-               memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
+               memcpy(&assoc_req->bssid, priv->curbssparams.bssid,
                        ETH_ALEN);
        }
 
        if (!test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags)) {
                int i;
                for (i = 0; i < 4; i++) {
-                       memcpy(&assoc_req->wep_keys[i], &adapter->wep_keys[i],
+                       memcpy(&assoc_req->wep_keys[i], &priv->wep_keys[i],
                                sizeof(struct enc_key));
                }
        }
 
        if (!test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags))
-               assoc_req->wep_tx_keyidx = adapter->wep_tx_keyidx;
+               assoc_req->wep_tx_keyidx = priv->wep_tx_keyidx;
 
        if (!test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) {
-               memcpy(&assoc_req->wpa_mcast_key, &adapter->wpa_mcast_key,
+               memcpy(&assoc_req->wpa_mcast_key, &priv->wpa_mcast_key,
                        sizeof(struct enc_key));
        }
 
        if (!test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) {
-               memcpy(&assoc_req->wpa_unicast_key, &adapter->wpa_unicast_key,
+               memcpy(&assoc_req->wpa_unicast_key, &priv->wpa_unicast_key,
                        sizeof(struct enc_key));
        }
 
        if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
-               memcpy(&assoc_req->secinfo, &adapter->secinfo,
-                       sizeof(struct wlan_802_11_security));
+               memcpy(&assoc_req->secinfo, &priv->secinfo,
+                       sizeof(struct lbs_802_11_security));
        }
 
        if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) {
-               memcpy(&assoc_req->wpa_ie, &adapter->wpa_ie,
+               memcpy(&assoc_req->wpa_ie, &priv->wpa_ie,
                        MAX_WPA_IE_LEN);
-               assoc_req->wpa_ie_len = adapter->wpa_ie_len;
+               assoc_req->wpa_ie_len = priv->wpa_ie_len;
        }
 
-       print_assoc_req(__func__, assoc_req);
-
+       lbs_deb_leave(LBS_DEB_ASSOC);
        return assoc_req;
 }
index e09b7490abbdf18710cb1b112dab29d912efe8b9..08372bbf376131af6079b64bf4723d245f35913e 100644 (file)
@@ -1,32 +1,12 @@
 /* Copyright (C) 2006, Red Hat, Inc. */
 
-#ifndef _WLAN_ASSOC_H_
-#define _WLAN_ASSOC_H_
+#ifndef _LBS_ASSOC_H_
+#define _LBS_ASSOC_H_
 
 #include "dev.h"
 
-void libertas_association_worker(struct work_struct *work);
+void lbs_association_worker(struct work_struct *work);
+struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
+void lbs_sync_channel(struct work_struct *work);
 
-struct assoc_request * wlan_get_association_request(wlan_adapter *adapter);
-
-void libertas_sync_channel(struct work_struct *work);
-
-#define ASSOC_DELAY (HZ / 2)
-static inline void wlan_postpone_association_work(wlan_private *priv)
-{
-       if (priv->adapter->surpriseremoved)
-               return;
-       cancel_delayed_work(&priv->assoc_work);
-       queue_delayed_work(priv->work_thread, &priv->assoc_work, ASSOC_DELAY);
-}
-
-static inline void wlan_cancel_association_work(wlan_private *priv)
-{
-       cancel_delayed_work(&priv->assoc_work);
-       if (priv->adapter->pending_assoc_req) {
-               kfree(priv->adapter->pending_assoc_req);
-               priv->adapter->pending_assoc_req = NULL;
-       }
-}
-
-#endif /* _WLAN_ASSOC_H */
+#endif /* _LBS_ASSOC_H */
index be5cfd8402c7bae331e2105b08f946484d2cd729..eab020338fde2b345c1c795b88d68ac4c360364a 100644 (file)
 #include "dev.h"
 #include "join.h"
 #include "wext.h"
+#include "cmd.h"
 
-static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
+static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
+static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
+                   struct cmd_ctrl_node *ptempnode,
+                   void *pdata_buf);
 
-static u16 commands_allowed_in_ps[] = {
-       CMD_802_11_RSSI,
-};
 
 /**
- *  @brief This function checks if the commans is allowed
- *  in PS mode not.
+ *  @brief Checks whether a command is allowed in Power Save mode
  *
  *  @param command the command ID
- *  @return       TRUE or FALSE
+ *  @return       1 if allowed, 0 if not allowed
  */
-static u8 is_command_allowed_in_ps(__le16 command)
+static u8 is_command_allowed_in_ps(u16 cmd)
 {
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) {
-               if (command == cpu_to_le16(commands_allowed_in_ps[i]))
-                       return 1;
+       switch (cmd) {
+       case CMD_802_11_RSSI:
+               return 1;
+       default:
+               break;
        }
-
        return 0;
 }
 
-static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd)
+/**
+ *  @brief Updates the hardware details like MAC address and regulatory region
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_update_hw_spec(struct lbs_private *priv)
 {
-       struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
+       struct cmd_ds_get_hw_spec cmd;
+       int ret = -1;
+       u32 i;
+       DECLARE_MAC_BUF(mac);
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->command = cpu_to_le16(CMD_GET_HW_SPEC);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
-       memcpy(hwspec->permanentaddr, priv->adapter->current_addr, ETH_ALEN);
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
+       ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
+       if (ret)
+               goto out;
+
+       priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
+
+       /* The firmware release is in an interesting format: the patch
+        * level is in the most significant nibble ... so fix that: */
+       priv->fwrelease = le32_to_cpu(cmd.fwrelease);
+       priv->fwrelease = (priv->fwrelease << 8) |
+               (priv->fwrelease >> 24 & 0xff);
+
+       /* Some firmware capabilities:
+        * CF card    firmware 5.0.16p0:   cap 0x00000303
+        * USB dongle firmware 5.110.17p2: cap 0x00000303
+        */
+       printk("libertas: %s, fw %u.%u.%up%u, cap 0x%08x\n",
+               print_mac(mac, cmd.permanentaddr),
+               priv->fwrelease >> 24 & 0xff,
+               priv->fwrelease >> 16 & 0xff,
+               priv->fwrelease >>  8 & 0xff,
+               priv->fwrelease       & 0xff,
+               priv->fwcapinfo);
+       lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
+                   cmd.hwifversion, cmd.version);
+
+       /* 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.
+        */
+       priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
+
+       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
+               /* use the region code to search for the index */
+               if (priv->regioncode == lbs_region_code_to_index[i])
+                       break;
+       }
+
+       /* if it's unidentified region code, use the default (USA) */
+       if (i >= MRVDRV_MAX_REGION_CODE) {
+               priv->regioncode = 0x10;
+               lbs_pr_info("unidentified region code; using the default (USA)\n");
+       }
+
+       if (priv->current_addr[0] == 0xff)
+               memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
+
+       memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
+       if (priv->mesh_dev)
+               memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
+
+       if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
+               ret = -1;
+               goto out;
+       }
 
+       if (lbs_set_universaltable(priv, 0)) {
+               ret = -1;
+               goto out;
+       }
+
+out:
        lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
+       return ret;
 }
 
-static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
+{
+       struct cmd_ds_host_sleep cmd_config;
+       int ret;
+
+       cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
+       cmd_config.criteria = cpu_to_le32(criteria);
+       cmd_config.gpio = priv->wol_gpio;
+       cmd_config.gap = priv->wol_gap;
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
+       if (!ret) {
+               lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
+               priv->wol_criteria = criteria;
+       } else {
+               lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
+
+static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
                                   struct cmd_ds_command *cmd,
                                   u16 cmd_action)
 {
@@ -90,161 +182,161 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv,
-                                             struct cmd_ds_command *cmd,
-                                             u16 cmd_action, void *pdata_buf)
+int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
+                                     uint16_t cmd_action, uint16_t *timeout)
 {
-       u16 *timeout = pdata_buf;
+       struct cmd_ds_802_11_inactivity_timeout cmd;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT);
-       cmd->size =
-           cpu_to_le16(sizeof(struct cmd_ds_802_11_inactivity_timeout)
-                            + S_DS_GEN);
+       cmd.hdr.command = cpu_to_le16(CMD_802_11_INACTIVITY_TIMEOUT);
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 
-       cmd->params.inactivity_timeout.action = cpu_to_le16(cmd_action);
+       cmd.action = cpu_to_le16(cmd_action);
 
-       if (cmd_action)
-               cmd->params.inactivity_timeout.timeout = cpu_to_le16(*timeout);
+       if (cmd_action == CMD_ACT_SET)
+               cmd.timeout = cpu_to_le16(*timeout);
        else
-               cmd->params.inactivity_timeout.timeout = 0;
+               cmd.timeout = 0;
 
-       lbs_deb_leave(LBS_DEB_CMD);
+       ret = lbs_cmd_with_response(priv, CMD_802_11_INACTIVITY_TIMEOUT, &cmd);
+
+       if (!ret)
+               *timeout = le16_to_cpu(cmd.timeout);
+
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
        return 0;
 }
 
-static int wlan_cmd_802_11_sleep_params(wlan_private * priv,
-                                       struct cmd_ds_command *cmd,
-                                       u16 cmd_action)
+int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
+                               struct sleep_params *sp)
 {
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params;
+       struct cmd_ds_802_11_sleep_params cmd;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->size = cpu_to_le16((sizeof(struct cmd_ds_802_11_sleep_params)) +
-                               S_DS_GEN);
-       cmd->command = cpu_to_le16(CMD_802_11_SLEEP_PARAMS);
-
        if (cmd_action == CMD_ACT_GET) {
-               memset(&adapter->sp, 0, sizeof(struct sleep_params));
-               memset(sp, 0, sizeof(struct cmd_ds_802_11_sleep_params));
-               sp->action = cpu_to_le16(cmd_action);
-       } else if (cmd_action == CMD_ACT_SET) {
-               sp->action = cpu_to_le16(cmd_action);
-               sp->error = cpu_to_le16(adapter->sp.sp_error);
-               sp->offset = cpu_to_le16(adapter->sp.sp_offset);
-               sp->stabletime = cpu_to_le16(adapter->sp.sp_stabletime);
-               sp->calcontrol = (u8) adapter->sp.sp_calcontrol;
-               sp->externalsleepclk = (u8) adapter->sp.sp_extsleepclk;
-               sp->reserved = cpu_to_le16(adapter->sp.sp_reserved);
+               memset(&cmd, 0, sizeof(cmd));
+       } else {
+               cmd.error = cpu_to_le16(sp->sp_error);
+               cmd.offset = cpu_to_le16(sp->sp_offset);
+               cmd.stabletime = cpu_to_le16(sp->sp_stabletime);
+               cmd.calcontrol = sp->sp_calcontrol;
+               cmd.externalsleepclk = sp->sp_extsleepclk;
+               cmd.reserved = cpu_to_le16(sp->sp_reserved);
+       }
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(cmd_action);
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd);
+
+       if (!ret) {
+               lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, "
+                           "calcontrol 0x%x extsleepclk 0x%x\n",
+                           le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset),
+                           le16_to_cpu(cmd.stabletime), cmd.calcontrol,
+                           cmd.externalsleepclk);
+
+               sp->sp_error = le16_to_cpu(cmd.error);
+               sp->sp_offset = le16_to_cpu(cmd.offset);
+               sp->sp_stabletime = le16_to_cpu(cmd.stabletime);
+               sp->sp_calcontrol = cmd.calcontrol;
+               sp->sp_extsleepclk = cmd.externalsleepclk;
+               sp->sp_reserved = le16_to_cpu(cmd.reserved);
        }
 
-       lbs_deb_leave(LBS_DEB_CMD);
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
        return 0;
 }
 
-static int wlan_cmd_802_11_set_wep(wlan_private * priv,
-                                   struct cmd_ds_command *cmd,
-                                   u32 cmd_act,
-                                   void * pdata_buf)
+int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
+                          struct assoc_request *assoc)
 {
-       struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep;
-       wlan_adapter *adapter = priv->adapter;
+       struct cmd_ds_802_11_set_wep cmd;
        int ret = 0;
-       struct assoc_request * assoc_req = pdata_buf;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->command = cpu_to_le16(CMD_802_11_SET_WEP);
-       cmd->size = cpu_to_le16(sizeof(*wep) + S_DS_GEN);
-
-       if (cmd_act == CMD_ACT_ADD) {
-               int i;
+       cmd.hdr.command = cpu_to_le16(CMD_802_11_SET_WEP);
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 
-               if (!assoc_req) {
-                       lbs_deb_cmd("Invalid association request!");
-                       ret = -1;
-                       goto done;
-               }
+       cmd.action = cpu_to_le16(cmd_action);
 
-               wep->action = cpu_to_le16(CMD_ACT_ADD);
+       if (cmd_action == CMD_ACT_ADD) {
+               int i;
 
                /* default tx key index */
-               wep->keyindex = cpu_to_le16((u16)(assoc_req->wep_tx_keyidx &
-                                                 (u32)CMD_WEP_KEY_INDEX_MASK));
+               cmd.keyindex = cpu_to_le16(assoc->wep_tx_keyidx &
+                                          CMD_WEP_KEY_INDEX_MASK);
 
                /* Copy key types and material to host command structure */
                for (i = 0; i < 4; i++) {
-                       struct enc_key * pkey = &assoc_req->wep_keys[i];
+                       struct enc_key *pkey = &assoc->wep_keys[i];
 
                        switch (pkey->len) {
                        case KEY_LEN_WEP_40:
-                               wep->keytype[i] = CMD_TYPE_WEP_40_BIT;
-                               memmove(&wep->keymaterial[i], pkey->key,
-                                       pkey->len);
+                               cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
+                               memmove(cmd.keymaterial[i], pkey->key, pkey->len);
                                lbs_deb_cmd("SET_WEP: add key %d (40 bit)\n", i);
                                break;
                        case KEY_LEN_WEP_104:
-                               wep->keytype[i] = CMD_TYPE_WEP_104_BIT;
-                               memmove(&wep->keymaterial[i], pkey->key,
-                                       pkey->len);
+                               cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
+                               memmove(cmd.keymaterial[i], pkey->key, pkey->len);
                                lbs_deb_cmd("SET_WEP: add key %d (104 bit)\n", i);
                                break;
                        case 0:
                                break;
                        default:
                                lbs_deb_cmd("SET_WEP: invalid key %d, length %d\n",
-                                      i, pkey->len);
+                                           i, pkey->len);
                                ret = -1;
                                goto done;
                                break;
                        }
                }
-       } else if (cmd_act == CMD_ACT_REMOVE) {
+       } else if (cmd_action == CMD_ACT_REMOVE) {
                /* ACT_REMOVE clears _all_ WEP keys */
-               wep->action = cpu_to_le16(CMD_ACT_REMOVE);
 
                /* default tx key index */
-               wep->keyindex = cpu_to_le16((u16)(adapter->wep_tx_keyidx &
-                                                 (u32)CMD_WEP_KEY_INDEX_MASK));
-               lbs_deb_cmd("SET_WEP: remove key %d\n", adapter->wep_tx_keyidx);
+               cmd.keyindex = cpu_to_le16(priv->wep_tx_keyidx &
+                                          CMD_WEP_KEY_INDEX_MASK);
+               lbs_deb_cmd("SET_WEP: remove key %d\n", priv->wep_tx_keyidx);
        }
 
-       ret = 0;
-
+       ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
 done:
        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
        return ret;
 }
 
-static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
-                                     struct cmd_ds_command *cmd,
-                                     u16 cmd_action,
-                                     void * pdata_buf)
+int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
+                             uint16_t *enable)
 {
-       struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn;
-       u32 * enable = pdata_buf;
+       struct cmd_ds_802_11_enable_rsn cmd;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->command = cpu_to_le16(CMD_802_11_ENABLE_RSN);
-       cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN);
-       penableRSN->action = cpu_to_le16(cmd_action);
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(cmd_action);
 
        if (cmd_action == CMD_ACT_SET) {
                if (*enable)
-                       penableRSN->enable = cpu_to_le16(CMD_ENABLE_RSN);
+                       cmd.enable = cpu_to_le16(CMD_ENABLE_RSN);
                else
-                       penableRSN->enable = cpu_to_le16(CMD_DISABLE_RSN);
+                       cmd.enable = cpu_to_le16(CMD_DISABLE_RSN);
                lbs_deb_cmd("ENABLE_RSN: %d\n", *enable);
        }
 
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
-}
+       ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
+       if (!ret && cmd_action == CMD_ACT_GET)
+               *enable = le16_to_cpu(cmd.enable);
 
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
+}
 
 static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
                             struct enc_key * pkey)
@@ -272,7 +364,7 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset,
        lbs_deb_leave(LBS_DEB_CMD);
 }
 
-static int wlan_cmd_802_11_key_material(wlan_private * priv,
+static int lbs_cmd_802_11_key_material(struct lbs_private *priv,
                                        struct cmd_ds_command *cmd,
                                        u16 cmd_action,
                                        u32 cmd_oid, void *pdata_buf)
@@ -319,7 +411,7 @@ done:
        return ret;
 }
 
-static int wlan_cmd_802_11_reset(wlan_private * priv,
+static int lbs_cmd_802_11_reset(struct lbs_private *priv,
                                 struct cmd_ds_command *cmd, int cmd_action)
 {
        struct cmd_ds_802_11_reset *reset = &cmd->params.reset;
@@ -334,7 +426,7 @@ static int wlan_cmd_802_11_reset(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_get_log(wlan_private * priv,
+static int lbs_cmd_802_11_get_log(struct lbs_private *priv,
                                   struct cmd_ds_command *cmd)
 {
        lbs_deb_enter(LBS_DEB_CMD);
@@ -346,7 +438,7 @@ static int wlan_cmd_802_11_get_log(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_get_stat(wlan_private * priv,
+static int lbs_cmd_802_11_get_stat(struct lbs_private *priv,
                                    struct cmd_ds_command *cmd)
 {
        lbs_deb_enter(LBS_DEB_CMD);
@@ -358,13 +450,12 @@ static int wlan_cmd_802_11_get_stat(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
+static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
                                    struct cmd_ds_command *cmd,
                                    int cmd_action,
                                    int cmd_oid, void *pdata_buf)
 {
        struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib;
-       wlan_adapter *adapter = priv->adapter;
        u8 ucTemp;
 
        lbs_deb_enter(LBS_DEB_CMD);
@@ -380,7 +471,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
                u8 mode = (u8) (size_t) pdata_buf;
                pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
                pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
-               pSNMPMIB->bufsize = sizeof(u8);
+               pSNMPMIB->bufsize = cpu_to_le16(sizeof(u8));
                if (mode == IW_MODE_ADHOC) {
                        ucTemp = SNMP_MIB_VALUE_ADHOC;
                } else {
@@ -400,8 +491,8 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
                        pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);
 
                        if (cmd_action == CMD_ACT_SET) {
-                               pSNMPMIB->querytype = CMD_ACT_SET;
-                               pSNMPMIB->bufsize = sizeof(u16);
+                               pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
+                               pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
                                ulTemp = *(u32 *)pdata_buf;
                                *((__le16 *)(pSNMPMIB->value)) =
                                    cpu_to_le16((u16) ulTemp);
@@ -433,7 +524,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
                {
 
                        u32 ulTemp;
-                       pSNMPMIB->oid = le16_to_cpu((u16) RTSTHRESH_I);
+                       pSNMPMIB->oid = cpu_to_le16(RTSTHRESH_I);
 
                        if (cmd_action == CMD_ACT_GET) {
                                pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
@@ -456,7 +547,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
                        pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
                        pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
                        *((__le16 *)(pSNMPMIB->value)) =
-                           cpu_to_le16((u16) adapter->txretrycount);
+                           cpu_to_le16((u16) priv->txretrycount);
                }
 
                break;
@@ -479,47 +570,7 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_radio_control(wlan_private * priv,
-                                        struct cmd_ds_command *cmd,
-                                        int cmd_action)
-{
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       cmd->size =
-           cpu_to_le16((sizeof(struct cmd_ds_802_11_radio_control)) +
-                            S_DS_GEN);
-       cmd->command = cpu_to_le16(CMD_802_11_RADIO_CONTROL);
-
-       pradiocontrol->action = cpu_to_le16(cmd_action);
-
-       switch (adapter->preamble) {
-       case CMD_TYPE_SHORT_PREAMBLE:
-               pradiocontrol->control = cpu_to_le16(SET_SHORT_PREAMBLE);
-               break;
-
-       case CMD_TYPE_LONG_PREAMBLE:
-               pradiocontrol->control = cpu_to_le16(SET_LONG_PREAMBLE);
-               break;
-
-       case CMD_TYPE_AUTO_PREAMBLE:
-       default:
-               pradiocontrol->control = cpu_to_le16(SET_AUTO_PREAMBLE);
-               break;
-       }
-
-       if (adapter->radioon)
-               pradiocontrol->control |= cpu_to_le16(TURN_ON_RF);
-       else
-               pradiocontrol->control &= cpu_to_le16(~TURN_ON_RF);
-
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
-}
-
-static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
+static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv,
                                       struct cmd_ds_command *cmd,
                                       u16 cmd_action, void *pdata_buf)
 {
@@ -563,7 +614,7 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_monitor_mode(wlan_private * priv,
+static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv,
                                      struct cmd_ds_command *cmd,
                                      u16 cmd_action, void *pdata_buf)
 {
@@ -583,13 +634,12 @@ static int wlan_cmd_802_11_monitor_mode(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
+static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
                                              struct cmd_ds_command *cmd,
                                              u16 cmd_action)
 {
        struct cmd_ds_802_11_rate_adapt_rateset
        *rateadapt = &cmd->params.rateset;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
        cmd->size =
@@ -598,46 +648,100 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv,
        cmd->command = cpu_to_le16(CMD_802_11_RATE_ADAPT_RATESET);
 
        rateadapt->action = cpu_to_le16(cmd_action);
-       rateadapt->enablehwauto = cpu_to_le16(adapter->enablehwauto);
-       rateadapt->bitmap = cpu_to_le16(adapter->ratebitmap);
+       rateadapt->enablehwauto = cpu_to_le16(priv->enablehwauto);
+       rateadapt->bitmap = cpu_to_le16(priv->ratebitmap);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_cmd_802_11_data_rate(wlan_private * priv,
-                                    struct cmd_ds_command *cmd,
-                                    u16 cmd_action)
+/**
+ *  @brief Get the current data rate
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *
+ *  @return            The data rate on success, error on failure
+ */
+int lbs_get_data_rate(struct lbs_private *priv)
 {
-       struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
-       wlan_adapter *adapter = priv->adapter;
+       struct cmd_ds_802_11_data_rate cmd;
+       int ret = -1;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
-                            S_DS_GEN);
-       cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE);
-       memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate));
-       pdatarate->action = cpu_to_le16(cmd_action);
-
-       if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) {
-               pdatarate->rates[0] = libertas_data_rate_to_fw_index(adapter->cur_rate);
-               lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n",
-                      adapter->cur_rate);
-       } else if (cmd_action == CMD_ACT_SET_TX_AUTO) {
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
+       if (ret)
+               goto out;
+
+       lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
+
+       ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]);
+       lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret);
+
+out:
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
+}
+
+/**
+ *  @brief Set the data rate
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *  @param rate        The desired data rate, or 0 to clear a locked rate
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
+{
+       struct cmd_ds_802_11_data_rate cmd;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+       if (rate > 0) {
+               cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
+               cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
+               if (cmd.rates[0] == 0) {
+                       lbs_deb_cmd("DATA_RATE: invalid requested rate of"
+                                   " 0x%02X\n", rate);
+                       ret = 0;
+                       goto out;
+               }
+               lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
+       } else {
+               cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
                lbs_deb_cmd("DATA_RATE: setting auto\n");
        }
 
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
+       ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
+       if (ret)
+               goto out;
+
+       lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
+
+       /* FIXME: get actual rates FW can do if this command actually returns
+        * all data rates supported.
+        */
+       priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
+       lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
+
+out:
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
 }
 
-static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
+static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv,
                                      struct cmd_ds_command *cmd,
                                      u16 cmd_action)
 {
        struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
        cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) +
@@ -647,39 +751,79 @@ static int wlan_cmd_mac_multicast_adr(wlan_private * priv,
        lbs_deb_cmd("MULTICAST_ADR: setting %d addresses\n", pMCastAdr->nr_of_adrs);
        pMCastAdr->action = cpu_to_le16(cmd_action);
        pMCastAdr->nr_of_adrs =
-           cpu_to_le16((u16) adapter->nr_of_multicastmacaddr);
-       memcpy(pMCastAdr->maclist, adapter->multicastlist,
-              adapter->nr_of_multicastmacaddr * ETH_ALEN);
+           cpu_to_le16((u16) priv->nr_of_multicastmacaddr);
+       memcpy(pMCastAdr->maclist, priv->multicastlist,
+              priv->nr_of_multicastmacaddr * ETH_ALEN);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_cmd_802_11_rf_channel(wlan_private * priv,
-                                     struct cmd_ds_command *cmd,
-                                     int option, void *pdata_buf)
+/**
+ *  @brief Get the radio channel
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *
+ *  @return            The channel on success, error on failure
+ */
+int lbs_get_channel(struct lbs_private *priv)
 {
-       struct cmd_ds_802_11_rf_channel *rfchan = &cmd->params.rfchannel;
+       struct cmd_ds_802_11_rf_channel cmd;
+       int ret = 0;
 
        lbs_deb_enter(LBS_DEB_CMD);
-       cmd->command = cpu_to_le16(CMD_802_11_RF_CHANNEL);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_rf_channel) +
-                               S_DS_GEN);
 
-       if (option == CMD_OPT_802_11_RF_CHANNEL_SET) {
-               rfchan->currentchannel = cpu_to_le16(*((u16 *) pdata_buf));
-       }
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
 
-       rfchan->action = cpu_to_le16(option);
+       ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
+       if (ret)
+               goto out;
 
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
+       ret = le16_to_cpu(cmd.channel);
+       lbs_deb_cmd("current radio channel is %d\n", ret);
+
+out:
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
+}
+
+/**
+ *  @brief Set the radio channel
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *  @param channel     The desired channel, or 0 to clear a locked channel
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_set_channel(struct lbs_private *priv, u8 channel)
+{
+       struct cmd_ds_802_11_rf_channel cmd;
+       u8 old_channel = priv->curbssparams.channel;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
+       cmd.channel = cpu_to_le16(channel);
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
+       if (ret)
+               goto out;
+
+       priv->curbssparams.channel = (uint8_t) le16_to_cpu(cmd.channel);
+       lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
+               priv->curbssparams.channel);
+
+out:
+       lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+       return ret;
 }
 
-static int wlan_cmd_802_11_rssi(wlan_private * priv,
+static int lbs_cmd_802_11_rssi(struct lbs_private *priv,
                                struct cmd_ds_command *cmd)
 {
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
        cmd->command = cpu_to_le16(CMD_802_11_RSSI);
@@ -687,28 +831,28 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv,
        cmd->params.rssi.N = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
 
        /* reset Beacon SNR/NF/RSSI values */
-       adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
-       adapter->SNR[TYPE_BEACON][TYPE_AVG] = 0;
-       adapter->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
-       adapter->NF[TYPE_BEACON][TYPE_AVG] = 0;
-       adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
-       adapter->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
+       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = 0;
+       priv->SNR[TYPE_BEACON][TYPE_AVG] = 0;
+       priv->NF[TYPE_BEACON][TYPE_NOAVG] = 0;
+       priv->NF[TYPE_BEACON][TYPE_AVG] = 0;
+       priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 0;
+       priv->RSSI[TYPE_BEACON][TYPE_AVG] = 0;
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_cmd_reg_access(wlan_private * priv,
+static int lbs_cmd_reg_access(struct lbs_private *priv,
                               struct cmd_ds_command *cmdptr,
                               u8 cmd_action, void *pdata_buf)
 {
-       struct wlan_offset_value *offval;
+       struct lbs_offset_value *offval;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       offval = (struct wlan_offset_value *)pdata_buf;
+       offval = (struct lbs_offset_value *)pdata_buf;
 
-       switch (cmdptr->command) {
+       switch (le16_to_cpu(cmdptr->command)) {
        case CMD_MAC_REG_ACCESS:
                {
                        struct cmd_ds_mac_reg_access *macreg;
@@ -773,11 +917,10 @@ static int wlan_cmd_reg_access(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_802_11_mac_address(wlan_private * priv,
+static int lbs_cmd_802_11_mac_address(struct lbs_private *priv,
                                       struct cmd_ds_command *cmd,
                                       u16 cmd_action)
 {
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
        cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS);
@@ -789,19 +932,19 @@ static int wlan_cmd_802_11_mac_address(wlan_private * priv,
 
        if (cmd_action == CMD_ACT_SET) {
                memcpy(cmd->params.macadd.macadd,
-                      adapter->current_addr, ETH_ALEN);
-               lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", adapter->current_addr, 6);
+                      priv->current_addr, ETH_ALEN);
+               lbs_deb_hex(LBS_DEB_CMD, "SET_CMD: MAC addr", priv->current_addr, 6);
        }
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
+static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv,
                                         struct cmd_ds_command *cmd,
                                         int cmd_action, void *pdata_buf)
 {
-       struct wlan_ioctl_regrdwr *ea = pdata_buf;
+       struct lbs_ioctl_regrdwr *ea = pdata_buf;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
@@ -819,7 +962,7 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_bt_access(wlan_private * priv,
+static int lbs_cmd_bt_access(struct lbs_private *priv,
                               struct cmd_ds_command *cmd,
                               u16 cmd_action, void *pdata_buf)
 {
@@ -857,7 +1000,7 @@ static int wlan_cmd_bt_access(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_fwt_access(wlan_private * priv,
+static int lbs_cmd_fwt_access(struct lbs_private *priv,
                               struct cmd_ds_command *cmd,
                               u16 cmd_action, void *pdata_buf)
 {
@@ -879,47 +1022,72 @@ static int wlan_cmd_fwt_access(wlan_private * priv,
        return 0;
 }
 
-static int wlan_cmd_mesh_access(wlan_private * priv,
-                               struct cmd_ds_command *cmd,
-                               u16 cmd_action, void *pdata_buf)
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+                   struct cmd_ds_mesh_access *cmd)
 {
-       struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
+       int ret;
+
        lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
 
-       cmd->command = cpu_to_le16(CMD_MESH_ACCESS);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
-       cmd->result = 0;
+       cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
+       cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
+       cmd->hdr.result = 0;
 
-       if (pdata_buf)
-               memcpy(mesh_access, pdata_buf, sizeof(*mesh_access));
-       else
-               memset(mesh_access, 0, sizeof(*mesh_access));
+       cmd->action = cpu_to_le16(cmd_action);
 
-       mesh_access->action = cpu_to_le16(cmd_action);
+       ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
 
        lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
+       return ret;
 }
+EXPORT_SYMBOL_GPL(lbs_mesh_access);
 
-static int wlan_cmd_set_boot2_ver(wlan_private * priv,
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
+{
+       struct cmd_ds_mesh_config cmd;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.action = cpu_to_le16(enable);
+       cmd.channel = cpu_to_le16(chan);
+       cmd.type = cpu_to_le16(priv->mesh_tlv);
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+       if (enable) {
+               cmd.length = cpu_to_le16(priv->mesh_ssid_len);
+               memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
+       }
+       lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
+                   enable, priv->mesh_tlv, chan,
+                   escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
+       return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
+}
+
+static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
                                struct cmd_ds_command *cmd,
-                               u16 cmd_action, void *pdata_buf)
+                               u16 cmd_action)
 {
-       struct cmd_ds_set_boot2_ver *boot2_ver = &cmd->params.boot2_ver;
-       cmd->command = cpu_to_le16(CMD_SET_BOOT2_VER);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_set_boot2_ver) + S_DS_GEN);
-       boot2_ver->version = priv->boot2_version;
+       struct cmd_ds_802_11_beacon_control
+               *bcn_ctrl = &cmd->params.bcn_ctrl;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+       cmd->size =
+           cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control)
+                            + S_DS_GEN);
+       cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL);
+
+       bcn_ctrl->action = cpu_to_le16(cmd_action);
+       bcn_ctrl->beacon_enable = cpu_to_le16(priv->beacon_enable);
+       bcn_ctrl->beacon_period = cpu_to_le16(priv->beacon_period);
+
+       lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-/*
- * Note: NEVER use libertas_queue_cmd() with addtail==0 other than for
- * the command timer, because it does not account for queued commands.
- */
-void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail)
+static void lbs_queue_cmd(struct lbs_private *priv,
+                         struct cmd_ctrl_node *cmdnode)
 {
        unsigned long flags;
-       struct cmd_ds_command *cmdptr;
+       int addtail = 1;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
@@ -927,118 +1095,87 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
                lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
                goto done;
        }
-
-       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
-       if (!cmdptr) {
-               lbs_deb_host("QUEUE_CMD: cmdptr is NULL\n");
+       if (!cmdnode->cmdbuf->size) {
+               lbs_deb_host("DNLD_CMD: cmd size is zero\n");
                goto done;
        }
+       cmdnode->result = 0;
 
        /* Exit_PS command needs to be queued in the header always. */
-       if (cmdptr->command == CMD_802_11_PS_MODE) {
-               struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
+       if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
+               struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
+
                if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
-                       if (adapter->psstate != PS_STATE_FULL_POWER)
+                       if (priv->psstate != PS_STATE_FULL_POWER)
                                addtail = 0;
                }
        }
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
-       if (addtail) {
-               list_add_tail((struct list_head *)cmdnode,
-                             &adapter->cmdpendingq);
-               adapter->nr_cmd_pending++;
-       } else
-               list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
+       if (addtail)
+               list_add_tail(&cmdnode->list, &priv->cmdpendingq);
+       else
+               list_add(&cmdnode->list, &priv->cmdpendingq);
 
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
-              le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command));
+                    le16_to_cpu(cmdnode->cmdbuf->command));
 
 done:
        lbs_deb_leave(LBS_DEB_HOST);
 }
 
-/*
- * TODO: Fix the issue when DownloadcommandToStation is being called the
- * second time when the command times out. All the cmdptr->xxx are in little
- * endian and therefore all the comparissions will fail.
- * For now - we are not performing the endian conversion the second time - but
- * for PS and DEEP_SLEEP we need to worry
- */
-static int DownloadcommandToStation(wlan_private * priv,
-                                   struct cmd_ctrl_node *cmdnode)
+static void lbs_submit_command(struct lbs_private *priv,
+                              struct cmd_ctrl_node *cmdnode)
 {
        unsigned long flags;
-       struct cmd_ds_command *cmdptr;
-       wlan_adapter *adapter = priv->adapter;
-       int ret = -1;
-       u16 cmdsize;
-       u16 command;
+       struct cmd_header *cmd;
+       uint16_t cmdsize;
+       uint16_t command;
+       int timeo = 5 * HZ;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       if (!adapter || !cmdnode) {
-               lbs_deb_host("DNLD_CMD: adapter or cmdmode is NULL\n");
-               goto done;
-       }
+       cmd = cmdnode->cmdbuf;
 
-       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       priv->cur_cmd = cmdnode;
+       priv->cur_cmd_retcode = 0;
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       if (!cmdptr || !cmdptr->size) {
-               lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n");
-               __libertas_cleanup_and_insert_cmd(priv, cmdnode);
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
-               goto done;
-       }
+       cmdsize = le16_to_cpu(cmd->size);
+       command = le16_to_cpu(cmd->command);
 
-       adapter->cur_cmd = cmdnode;
-       adapter->cur_cmd_retcode = 0;
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       /* These commands take longer */
+       if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
+           command == CMD_802_11_AUTHENTICATE)
+               timeo = 10 * HZ;
 
-       cmdsize = cmdptr->size;
-       command = cpu_to_le16(cmdptr->command);
+       lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n",
+                    command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
+       lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
 
-       lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
-                   command, le16_to_cpu(cmdptr->size), jiffies);
-       lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize);
+       ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
 
-       cmdnode->cmdwaitqwoken = 0;
-       cmdsize = cpu_to_le16(cmdsize);
-
-       ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
-
-       if (ret != 0) {
-               lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               adapter->cur_cmd_retcode = ret;
-               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-               adapter->nr_cmd_pending--;
-               adapter->cur_cmd = NULL;
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
-               goto done;
-       }
-
-       lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", command, jiffies);
+       if (ret) {
+               lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
+               /* Let the timer kick in and retry, and potentially reset
+                  the whole thing if the condition persists */
+               timeo = HZ;
+       } else
+               lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n",
+                           command, jiffies);
 
        /* Setup the timer after transmit command */
-       if (command == CMD_802_11_SCAN || command == CMD_802_11_AUTHENTICATE
-           || command == CMD_802_11_ASSOCIATE)
-               mod_timer(&adapter->command_timer, jiffies + (10*HZ));
-       else
-               mod_timer(&adapter->command_timer, jiffies + (5*HZ));
-
-       ret = 0;
+       mod_timer(&priv->command_timer, jiffies + timeo);
 
-done:
-       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
-       return ret;
+       lbs_deb_leave(LBS_DEB_HOST);
 }
 
-static int wlan_cmd_mac_control(wlan_private * priv,
+static int lbs_cmd_mac_control(struct lbs_private *priv,
                                struct cmd_ds_command *cmd)
 {
        struct cmd_ds_mac_control *mac = &cmd->params.macctrl;
@@ -1047,7 +1184,7 @@ static int wlan_cmd_mac_control(wlan_private * priv,
 
        cmd->command = cpu_to_le16(CMD_MAC_CONTROL);
        cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN);
-       mac->action = cpu_to_le16(priv->adapter->currentpacketfilter);
+       mac->action = cpu_to_le16(priv->currentpacketfilter);
 
        lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n",
                    le16_to_cpu(mac->action), le16_to_cpu(cmd->size));
@@ -1058,54 +1195,98 @@ static int wlan_cmd_mac_control(wlan_private * priv,
 
 /**
  *  This function inserts command node to cmdfreeq
- *  after cleans it. Requires adapter->driver_lock held.
+ *  after cleans it. Requires priv->driver_lock held.
  */
-void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
+static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
+                                        struct cmd_ctrl_node *cmdnode)
 {
-       wlan_adapter *adapter = priv->adapter;
+       lbs_deb_enter(LBS_DEB_HOST);
 
-       if (!ptempcmd)
-               return;
+       if (!cmdnode)
+               goto out;
+
+       cmdnode->callback = NULL;
+       cmdnode->callback_arg = 0;
 
-       cleanup_cmdnode(ptempcmd);
-       list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq);
+       memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
+
+       list_add_tail(&cmdnode->list, &priv->cmdfreeq);
+ out:
+       lbs_deb_leave(LBS_DEB_HOST);
 }
 
-static void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd)
+static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
+       struct cmd_ctrl_node *ptempcmd)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
-       __libertas_cleanup_and_insert_cmd(priv, ptempcmd);
-       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       __lbs_cleanup_and_insert_cmd(priv, ptempcmd);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 
-int libertas_set_radio_control(wlan_private * priv)
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+                         int result)
+{
+       if (cmd == priv->cur_cmd)
+               priv->cur_cmd_retcode = result;
+
+       cmd->result = result;
+       cmd->cmdwaitqwoken = 1;
+       wake_up_interruptible(&cmd->cmdwait_q);
+
+       if (!cmd->callback)
+               __lbs_cleanup_and_insert_cmd(priv, cmd);
+       priv->cur_cmd = NULL;
+}
+
+int lbs_set_radio_control(struct lbs_private *priv)
 {
        int ret = 0;
+       struct cmd_ds_802_11_radio_control cmd;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       ret = libertas_prepare_and_send_command(priv,
-                                   CMD_802_11_RADIO_CONTROL,
-                                   CMD_ACT_SET,
-                                   CMD_OPTION_WAITFORRSP, 0, NULL);
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(CMD_ACT_SET);
+
+       switch (priv->preamble) {
+       case CMD_TYPE_SHORT_PREAMBLE:
+               cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE);
+               break;
+
+       case CMD_TYPE_LONG_PREAMBLE:
+               cmd.control = cpu_to_le16(SET_LONG_PREAMBLE);
+               break;
+
+       case CMD_TYPE_AUTO_PREAMBLE:
+       default:
+               cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE);
+               break;
+       }
+
+       if (priv->radioon)
+               cmd.control |= cpu_to_le16(TURN_ON_RF);
+       else
+               cmd.control &= cpu_to_le16(~TURN_ON_RF);
+
+       lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
+                   priv->preamble);
 
-       lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n",
-              priv->adapter->radioon, priv->adapter->preamble);
+       ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
 
        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
        return ret;
 }
 
-int libertas_set_mac_packet_filter(wlan_private * priv)
+int lbs_set_mac_packet_filter(struct lbs_private *priv)
 {
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
        /* Send MAC control command to station */
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_MAC_CONTROL, 0, 0, 0, NULL);
 
        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
@@ -1115,7 +1296,7 @@ int libertas_set_mac_packet_filter(wlan_private * priv)
 /**
  *  @brief This function prepare the command before send to firmware.
  *
- *  @param priv                A pointer to wlan_private structure
+ *  @param priv                A pointer to struct lbs_private structure
  *  @param cmd_no      command number
  *  @param cmd_action  command action: GET or SET
  *  @param wait_option wait option: wait response or not
@@ -1123,32 +1304,31 @@ int libertas_set_mac_packet_filter(wlan_private * priv)
  *  @param pdata_buf   A pointer to informaion buffer
  *  @return            0 or -1
  */
-int libertas_prepare_and_send_command(wlan_private * priv,
+int lbs_prepare_and_send_command(struct lbs_private *priv,
                          u16 cmd_no,
                          u16 cmd_action,
                          u16 wait_option, u32 cmd_oid, void *pdata_buf)
 {
        int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ctrl_node *cmdnode;
        struct cmd_ds_command *cmdptr;
        unsigned long flags;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       if (!adapter) {
-               lbs_deb_host("PREP_CMD: adapter is NULL\n");
+       if (!priv) {
+               lbs_deb_host("PREP_CMD: priv is NULL\n");
                ret = -1;
                goto done;
        }
 
-       if (adapter->surpriseremoved) {
+       if (priv->surpriseremoved) {
                lbs_deb_host("PREP_CMD: card removed\n");
                ret = -1;
                goto done;
        }
 
-       cmdnode = libertas_get_free_cmd_ctrl_node(priv);
+       cmdnode = lbs_get_cmd_ctrl_node(priv);
 
        if (cmdnode == NULL) {
                lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
@@ -1159,138 +1339,107 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                goto done;
        }
 
-       libertas_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf);
+       lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
 
-       cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+       cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
 
        lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
 
-       if (!cmdptr) {
-               lbs_deb_host("PREP_CMD: cmdptr is NULL\n");
-               libertas_cleanup_and_insert_cmd(priv, cmdnode);
-               ret = -1;
-               goto done;
-       }
-
        /* Set sequence number, command and INT option */
-       adapter->seqnum++;
-       cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
+       priv->seqnum++;
+       cmdptr->seqnum = cpu_to_le16(priv->seqnum);
 
        cmdptr->command = cpu_to_le16(cmd_no);
        cmdptr->result = 0;
 
        switch (cmd_no) {
-       case CMD_GET_HW_SPEC:
-               ret = wlan_cmd_hw_spec(priv, cmdptr);
-               break;
        case CMD_802_11_PS_MODE:
-               ret = wlan_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
+               ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
                break;
 
        case CMD_802_11_SCAN:
-               ret = libertas_cmd_80211_scan(priv, cmdptr, pdata_buf);
+               ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf);
                break;
 
        case CMD_MAC_CONTROL:
-               ret = wlan_cmd_mac_control(priv, cmdptr);
+               ret = lbs_cmd_mac_control(priv, cmdptr);
                break;
 
        case CMD_802_11_ASSOCIATE:
        case CMD_802_11_REASSOCIATE:
-               ret = libertas_cmd_80211_associate(priv, cmdptr, pdata_buf);
+               ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
                break;
 
        case CMD_802_11_DEAUTHENTICATE:
-               ret = libertas_cmd_80211_deauthenticate(priv, cmdptr);
-               break;
-
-       case CMD_802_11_SET_WEP:
-               ret = wlan_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf);
+               ret = lbs_cmd_80211_deauthenticate(priv, cmdptr);
                break;
 
        case CMD_802_11_AD_HOC_START:
-               ret = libertas_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
+               ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf);
                break;
        case CMD_CODE_DNLD:
                break;
 
        case CMD_802_11_RESET:
-               ret = wlan_cmd_802_11_reset(priv, cmdptr, cmd_action);
+               ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action);
                break;
 
        case CMD_802_11_GET_LOG:
-               ret = wlan_cmd_802_11_get_log(priv, cmdptr);
+               ret = lbs_cmd_802_11_get_log(priv, cmdptr);
                break;
 
        case CMD_802_11_AUTHENTICATE:
-               ret = libertas_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
+               ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
                break;
 
        case CMD_802_11_GET_STAT:
-               ret = wlan_cmd_802_11_get_stat(priv, cmdptr);
+               ret = lbs_cmd_802_11_get_stat(priv, cmdptr);
                break;
 
        case CMD_802_11_SNMP_MIB:
-               ret = wlan_cmd_802_11_snmp_mib(priv, cmdptr,
+               ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr,
                                               cmd_action, cmd_oid, pdata_buf);
                break;
 
        case CMD_MAC_REG_ACCESS:
        case CMD_BBP_REG_ACCESS:
        case CMD_RF_REG_ACCESS:
-               ret = wlan_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
-               break;
-
-       case CMD_802_11_RF_CHANNEL:
-               ret = wlan_cmd_802_11_rf_channel(priv, cmdptr,
-                                                cmd_action, pdata_buf);
+               ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf);
                break;
 
        case CMD_802_11_RF_TX_POWER:
-               ret = wlan_cmd_802_11_rf_tx_power(priv, cmdptr,
+               ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr,
                                                  cmd_action, pdata_buf);
                break;
 
-       case CMD_802_11_RADIO_CONTROL:
-               ret = wlan_cmd_802_11_radio_control(priv, cmdptr, cmd_action);
-               break;
-
-       case CMD_802_11_DATA_RATE:
-               ret = wlan_cmd_802_11_data_rate(priv, cmdptr, cmd_action);
-               break;
        case CMD_802_11_RATE_ADAPT_RATESET:
-               ret = wlan_cmd_802_11_rate_adapt_rateset(priv,
+               ret = lbs_cmd_802_11_rate_adapt_rateset(priv,
                                                         cmdptr, cmd_action);
                break;
 
        case CMD_MAC_MULTICAST_ADR:
-               ret = wlan_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
+               ret = lbs_cmd_mac_multicast_adr(priv, cmdptr, cmd_action);
                break;
 
        case CMD_802_11_MONITOR_MODE:
-               ret = wlan_cmd_802_11_monitor_mode(priv, cmdptr,
+               ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr,
                                          cmd_action, pdata_buf);
                break;
 
        case CMD_802_11_AD_HOC_JOIN:
-               ret = libertas_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
+               ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf);
                break;
 
        case CMD_802_11_RSSI:
-               ret = wlan_cmd_802_11_rssi(priv, cmdptr);
+               ret = lbs_cmd_802_11_rssi(priv, cmdptr);
                break;
 
        case CMD_802_11_AD_HOC_STOP:
-               ret = libertas_cmd_80211_ad_hoc_stop(priv, cmdptr);
-               break;
-
-       case CMD_802_11_ENABLE_RSN:
-               ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action,
-                               pdata_buf);
+               ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr);
                break;
 
        case CMD_802_11_KEY_MATERIAL:
-               ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action,
+               ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action,
                                cmd_oid, pdata_buf);
                break;
 
@@ -1300,11 +1449,11 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                break;
 
        case CMD_802_11_MAC_ADDRESS:
-               ret = wlan_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
+               ret = lbs_cmd_802_11_mac_address(priv, cmdptr, cmd_action);
                break;
 
        case CMD_802_11_EEPROM_ACCESS:
-               ret = wlan_cmd_802_11_eeprom_access(priv, cmdptr,
+               ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr,
                                                    cmd_action, pdata_buf);
                break;
 
@@ -1322,19 +1471,10 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                goto done;
 
        case CMD_802_11D_DOMAIN_INFO:
-               ret = libertas_cmd_802_11d_domain_info(priv, cmdptr,
+               ret = lbs_cmd_802_11d_domain_info(priv, cmdptr,
                                                   cmd_no, cmd_action);
                break;
 
-       case CMD_802_11_SLEEP_PARAMS:
-               ret = wlan_cmd_802_11_sleep_params(priv, cmdptr, cmd_action);
-               break;
-       case CMD_802_11_INACTIVITY_TIMEOUT:
-               ret = wlan_cmd_802_11_inactivity_timeout(priv, cmdptr,
-                                                        cmd_action, pdata_buf);
-               libertas_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf);
-               break;
-
        case CMD_802_11_TPC_CFG:
                cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
                cmdptr->size =
@@ -1361,13 +1501,15 @@ int libertas_prepare_and_send_command(wlan_private * priv,
 
 #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
                        cmdptr->size =
-                           cpu_to_le16(gpio->header.len + S_DS_GEN +
-                                            ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
-                       gpio->header.len = cpu_to_le16(gpio->header.len);
+                           cpu_to_le16(le16_to_cpu(gpio->header.len)
+                               + S_DS_GEN
+                               + ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
+                       gpio->header.len = gpio->header.len;
 
                        ret = 0;
                        break;
                }
+
        case CMD_802_11_PWR_CFG:
                cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG);
                cmdptr->size =
@@ -1379,19 +1521,11 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                ret = 0;
                break;
        case CMD_BT_ACCESS:
-               ret = wlan_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
+               ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf);
                break;
 
        case CMD_FWT_ACCESS:
-               ret = wlan_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
-               break;
-
-       case CMD_MESH_ACCESS:
-               ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
-               break;
-
-       case CMD_SET_BOOT2_VER:
-               ret = wlan_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf);
+               ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
                break;
 
        case CMD_GET_TSF:
@@ -1400,6 +1534,9 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                                           S_DS_GEN);
                ret = 0;
                break;
+       case CMD_802_11_BEACON_CTRL:
+               ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
+               break;
        default:
                lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no);
                ret = -1;
@@ -1409,14 +1546,14 @@ int libertas_prepare_and_send_command(wlan_private * priv,
        /* return error, since the command preparation failed */
        if (ret != 0) {
                lbs_deb_host("PREP_CMD: command preparation failed\n");
-               libertas_cleanup_and_insert_cmd(priv, cmdnode);
+               lbs_cleanup_and_insert_cmd(priv, cmdnode);
                ret = -1;
                goto done;
        }
 
        cmdnode->cmdwaitqwoken = 0;
 
-       libertas_queue_cmd(adapter, cmdnode, 1);
+       lbs_queue_cmd(priv, cmdnode);
        wake_up_interruptible(&priv->waitq);
 
        if (wait_option & CMD_OPTION_WAITFORRSP) {
@@ -1426,67 +1563,60 @@ int libertas_prepare_and_send_command(wlan_private * priv,
                                         cmdnode->cmdwaitqwoken);
        }
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       if (adapter->cur_cmd_retcode) {
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       if (priv->cur_cmd_retcode) {
                lbs_deb_host("PREP_CMD: command failed with return code %d\n",
-                      adapter->cur_cmd_retcode);
-               adapter->cur_cmd_retcode = 0;
+                      priv->cur_cmd_retcode);
+               priv->cur_cmd_retcode = 0;
                ret = -1;
        }
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 done:
        lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command);
+EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
 
 /**
  *  @brief This function allocates the command buffer and link
  *  it to command free queue.
  *
- *  @param priv                A pointer to wlan_private structure
+ *  @param priv                A pointer to struct lbs_private structure
  *  @return            0 or -1
  */
-int libertas_allocate_cmd_buffer(wlan_private * priv)
+int lbs_allocate_cmd_buffer(struct lbs_private *priv)
 {
        int ret = 0;
-       u32 ulbufsize;
+       u32 bufsize;
        u32 i;
-       struct cmd_ctrl_node *tempcmd_array;
-       u8 *ptempvirtualaddr;
-       wlan_adapter *adapter = priv->adapter;
+       struct cmd_ctrl_node *cmdarray;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       /* Allocate and initialize cmdCtrlNode */
-       ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
-
-       if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {
+       /* Allocate and initialize the command array */
+       bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
+       if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
                lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
                ret = -1;
                goto done;
        }
-       adapter->cmd_array = tempcmd_array;
+       priv->cmd_array = cmdarray;
 
-       /* Allocate and initialize command buffers */
-       ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
-       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-               if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {
+       /* Allocate and initialize each command buffer in the command array */
+       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+               cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
+               if (!cmdarray[i].cmdbuf) {
                        lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
                        ret = -1;
                        goto done;
                }
-
-               /* Update command buffer virtual */
-               tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
        }
 
-       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-               init_waitqueue_head(&tempcmd_array[i].cmdwait_q);
-               libertas_cleanup_and_insert_cmd(priv, &tempcmd_array[i]);
+       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+               init_waitqueue_head(&cmdarray[i].cmdwait_q);
+               lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
        }
-
        ret = 0;
 
 done:
@@ -1497,39 +1627,36 @@ done:
 /**
  *  @brief This function frees the command buffer.
  *
- *  @param priv                A pointer to wlan_private structure
+ *  @param priv                A pointer to struct lbs_private structure
  *  @return            0 or -1
  */
-int libertas_free_cmd_buffer(wlan_private * priv)
+int lbs_free_cmd_buffer(struct lbs_private *priv)
 {
-       u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */
+       struct cmd_ctrl_node *cmdarray;
        unsigned int i;
-       struct cmd_ctrl_node *tempcmd_array;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
        /* need to check if cmd array is allocated or not */
-       if (adapter->cmd_array == NULL) {
+       if (priv->cmd_array == NULL) {
                lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
                goto done;
        }
 
-       tempcmd_array = adapter->cmd_array;
+       cmdarray = priv->cmd_array;
 
        /* Release shared memory buffers */
-       ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
-       for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-               if (tempcmd_array[i].bufvirtualaddr) {
-                       kfree(tempcmd_array[i].bufvirtualaddr);
-                       tempcmd_array[i].bufvirtualaddr = NULL;
+       for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+               if (cmdarray[i].cmdbuf) {
+                       kfree(cmdarray[i].cmdbuf);
+                       cmdarray[i].cmdbuf = NULL;
                }
        }
 
        /* Release cmd_ctrl_node */
-       if (adapter->cmd_array) {
-               kfree(adapter->cmd_array);
-               adapter->cmd_array = NULL;
+       if (priv->cmd_array) {
+               kfree(priv->cmd_array);
+               priv->cmd_array = NULL;
        }
 
 done:
@@ -1541,34 +1668,31 @@ done:
  *  @brief This function gets a free command node if available in
  *  command free queue.
  *
- *  @param priv                A pointer to wlan_private structure
+ *  @param priv                A pointer to struct lbs_private structure
  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
  */
-struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
+static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
 {
        struct cmd_ctrl_node *tempnode;
-       wlan_adapter *adapter = priv->adapter;
        unsigned long flags;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       if (!adapter)
+       if (!priv)
                return NULL;
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
-       if (!list_empty(&adapter->cmdfreeq)) {
-               tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
-               list_del((struct list_head *)tempnode);
+       if (!list_empty(&priv->cmdfreeq)) {
+               tempnode = list_first_entry(&priv->cmdfreeq,
+                                           struct cmd_ctrl_node, list);
+               list_del(&tempnode->list);
        } else {
                lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
                tempnode = NULL;
        }
 
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
-
-       if (tempnode)
-               cleanup_cmdnode(tempnode);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        lbs_deb_leave(LBS_DEB_HOST);
        return tempnode;
@@ -1580,47 +1704,26 @@ struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv)
  *  @param ptempnode   A pointer to cmdCtrlNode structure
  *  @return            n/a
  */
-static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
-{
-       lbs_deb_enter(LBS_DEB_HOST);
-
-       if (!ptempnode)
-               return;
-       ptempnode->cmdwaitqwoken = 1;
-       wake_up_interruptible(&ptempnode->cmdwait_q);
-       ptempnode->status = 0;
-       ptempnode->cmd_oid = (u32) 0;
-       ptempnode->wait_option = 0;
-       ptempnode->pdata_buf = NULL;
-
-       if (ptempnode->bufvirtualaddr != NULL)
-               memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
-
-       lbs_deb_leave(LBS_DEB_HOST);
-}
 
 /**
  *  @brief This function initializes the command node.
  *
- *  @param priv                A pointer to wlan_private structure
+ *  @param priv                A pointer to struct lbs_private structure
  *  @param ptempnode   A pointer to cmd_ctrl_node structure
- *  @param cmd_oid     cmd oid: treated as sub command
- *  @param wait_option wait option: wait response or not
  *  @param pdata_buf   A pointer to informaion buffer
  *  @return            0 or -1
  */
-void libertas_set_cmd_ctrl_node(wlan_private * priv,
-                   struct cmd_ctrl_node *ptempnode,
-                   u32 cmd_oid, u16 wait_option, void *pdata_buf)
+static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
+                                 struct cmd_ctrl_node *ptempnode,
+                                 void *pdata_buf)
 {
        lbs_deb_enter(LBS_DEB_HOST);
 
        if (!ptempnode)
                return;
 
-       ptempnode->cmd_oid = cmd_oid;
-       ptempnode->wait_option = wait_option;
-       ptempnode->pdata_buf = pdata_buf;
+       ptempnode->callback = NULL;
+       ptempnode->callback_arg = (unsigned long)pdata_buf;
 
        lbs_deb_leave(LBS_DEB_HOST);
 }
@@ -1630,60 +1733,58 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv,
  *  pending queue. It will put fimware back to PS mode
  *  if applicable.
  *
- *  @param priv     A pointer to wlan_private structure
+ *  @param priv     A pointer to struct lbs_private structure
  *  @return       0 or -1
  */
-int libertas_execute_next_command(wlan_private * priv)
+int lbs_execute_next_command(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ctrl_node *cmdnode = NULL;
-       struct cmd_ds_command *cmdptr;
+       struct cmd_header *cmd;
        unsigned long flags;
        int ret = 0;
 
        // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
-       // only caller to us is libertas_thread() and we get even when a
+       // only caller to us is lbs_thread() and we get even when a
        // data packet is received
        lbs_deb_enter(LBS_DEB_THREAD);
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
-       if (adapter->cur_cmd) {
+       if (priv->cur_cmd) {
                lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                ret = -1;
                goto done;
        }
 
-       if (!list_empty(&adapter->cmdpendingq)) {
-               cmdnode = (struct cmd_ctrl_node *)
-                   adapter->cmdpendingq.next;
+       if (!list_empty(&priv->cmdpendingq)) {
+               cmdnode = list_first_entry(&priv->cmdpendingq,
+                                          struct cmd_ctrl_node, list);
        }
 
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        if (cmdnode) {
-               cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+               cmd = cmdnode->cmdbuf;
 
-               if (is_command_allowed_in_ps(cmdptr->command)) {
-                       if ((adapter->psstate == PS_STATE_SLEEP) ||
-                           (adapter->psstate == PS_STATE_PRE_SLEEP)) {
+               if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
+                       if ((priv->psstate == PS_STATE_SLEEP) ||
+                           (priv->psstate == PS_STATE_PRE_SLEEP)) {
                                lbs_deb_host(
                                       "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
-                                      le16_to_cpu(cmdptr->command),
-                                      adapter->psstate);
+                                      le16_to_cpu(cmd->command),
+                                      priv->psstate);
                                ret = -1;
                                goto done;
                        }
                        lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
-                              "0x%04x in psstate %d\n",
-                                   le16_to_cpu(cmdptr->command),
-                                   adapter->psstate);
-               } else if (adapter->psstate != PS_STATE_FULL_POWER) {
+                                    "0x%04x in psstate %d\n",
+                                    le16_to_cpu(cmd->command), priv->psstate);
+               } else if (priv->psstate != PS_STATE_FULL_POWER) {
                        /*
                         * 1. Non-PS command:
                         * Queue it. set needtowakeup to TRUE if current state
-                        * is SLEEP, otherwise call libertas_ps_wakeup to send Exit_PS.
+                        * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
                         * 2. PS command but not Exit_PS:
                         * Ignore it.
                         * 3. PS command Exit_PS:
@@ -1691,18 +1792,17 @@ int libertas_execute_next_command(wlan_private * priv)
                         * otherwise send this command down to firmware
                         * immediately.
                         */
-                       if (cmdptr->command !=
-                           cpu_to_le16(CMD_802_11_PS_MODE)) {
+                       if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
                                /*  Prepare to send Exit PS,
                                 *  this non PS command will be sent later */
-                               if ((adapter->psstate == PS_STATE_SLEEP)
-                                   || (adapter->psstate == PS_STATE_PRE_SLEEP)
+                               if ((priv->psstate == PS_STATE_SLEEP)
+                                   || (priv->psstate == PS_STATE_PRE_SLEEP)
                                    ) {
                                        /* w/ new scheme, it will not reach here.
                                           since it is blocked in main_thread. */
-                                       adapter->needtowakeup = 1;
+                                       priv->needtowakeup = 1;
                                } else
-                                       libertas_ps_wakeup(priv, 0);
+                                       lbs_ps_wakeup(priv, 0);
 
                                ret = 0;
                                goto done;
@@ -1711,8 +1811,7 @@ int libertas_execute_next_command(wlan_private * priv)
                                 * PS command. Ignore it if it is not Exit_PS.
                                 * otherwise send it down immediately.
                                 */
-                               struct cmd_ds_802_11_ps_mode *psm =
-                                   &cmdptr->params.psmode;
+                               struct cmd_ds_802_11_ps_mode *psm = (void *)&cmd[1];
 
                                lbs_deb_host(
                                       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
@@ -1721,20 +1820,24 @@ int libertas_execute_next_command(wlan_private * priv)
                                    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
-                                       list_del((struct list_head *)cmdnode);
-                                       libertas_cleanup_and_insert_cmd(priv, cmdnode);
+                                       list_del(&cmdnode->list);
+                                       spin_lock_irqsave(&priv->driver_lock, flags);
+                                       lbs_complete_command(priv, cmdnode, 0);
+                                       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                                        ret = 0;
                                        goto done;
                                }
 
-                               if ((adapter->psstate == PS_STATE_SLEEP) ||
-                                   (adapter->psstate == PS_STATE_PRE_SLEEP)) {
+                               if ((priv->psstate == PS_STATE_SLEEP) ||
+                                   (priv->psstate == PS_STATE_PRE_SLEEP)) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
-                                       list_del((struct list_head *)cmdnode);
-                                       libertas_cleanup_and_insert_cmd(priv, cmdnode);
-                                       adapter->needtowakeup = 1;
+                                       list_del(&cmdnode->list);
+                                       spin_lock_irqsave(&priv->driver_lock, flags);
+                                       lbs_complete_command(priv, cmdnode, 0);
+                                       spin_unlock_irqrestore(&priv->driver_lock, flags);
+                                       priv->needtowakeup = 1;
 
                                        ret = 0;
                                        goto done;
@@ -1744,33 +1847,34 @@ int libertas_execute_next_command(wlan_private * priv)
                                       "EXEC_NEXT_CMD: sending EXIT_PS\n");
                        }
                }
-               list_del((struct list_head *)cmdnode);
+               list_del(&cmdnode->list);
                lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
-                           le16_to_cpu(cmdptr->command));
-               DownloadcommandToStation(priv, cmdnode);
+                           le16_to_cpu(cmd->command));
+               lbs_submit_command(priv, cmdnode);
        } else {
                /*
                 * check if in power save mode, if yes, put the device back
                 * to PS mode
                 */
-               if ((adapter->psmode != WLAN802_11POWERMODECAM) &&
-                   (adapter->psstate == PS_STATE_FULL_POWER) &&
-                   (adapter->connect_status == LIBERTAS_CONNECTED)) {
-                       if (adapter->secinfo.WPAenabled ||
-                           adapter->secinfo.WPA2enabled) {
+               if ((priv->psmode != LBS802_11POWERMODECAM) &&
+                   (priv->psstate == PS_STATE_FULL_POWER) &&
+                   ((priv->connect_status == LBS_CONNECTED) ||
+                   (priv->mesh_connect_status == LBS_CONNECTED))) {
+                       if (priv->secinfo.WPAenabled ||
+                           priv->secinfo.WPA2enabled) {
                                /* check for valid WPA group keys */
-                               if (adapter->wpa_mcast_key.len ||
-                                   adapter->wpa_unicast_key.len) {
+                               if (priv->wpa_mcast_key.len ||
+                                   priv->wpa_unicast_key.len) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: WPA enabled and GTK_SET"
                                               " go back to PS_SLEEP");
-                                       libertas_ps_sleep(priv, 0);
+                                       lbs_ps_sleep(priv, 0);
                                }
                        } else {
                                lbs_deb_host(
                                       "EXEC_NEXT_CMD: cmdpendingq empty, "
                                       "go back to PS_SLEEP");
-                               libertas_ps_sleep(priv, 0);
+                               lbs_ps_sleep(priv, 0);
                        }
                }
        }
@@ -1781,7 +1885,7 @@ done:
        return ret;
 }
 
-void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
+void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str)
 {
        union iwreq_data iwrq;
        u8 buf[50];
@@ -1805,10 +1909,9 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str)
        lbs_deb_leave(LBS_DEB_WEXT);
 }
 
-static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
+static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size)
 {
        unsigned long flags;
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_HOST);
@@ -1819,26 +1922,25 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
        lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size);
 
        ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);
-       priv->dnld_sent = DNLD_RES_RECEIVED;
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       if (adapter->intcounter || adapter->currenttxskb)
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       if (priv->intcounter || priv->currenttxskb)
                lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",
-                      adapter->intcounter, adapter->currenttxskb);
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+                      priv->intcounter, priv->currenttxskb);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        if (ret) {
                lbs_pr_alert(
                       "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");
        } else {
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               if (!adapter->intcounter) {
-                       adapter->psstate = PS_STATE_SLEEP;
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               if (!priv->intcounter) {
+                       priv->psstate = PS_STATE_SLEEP;
                } else {
                        lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",
-                              adapter->intcounter);
+                              priv->intcounter);
                }
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n");
        }
@@ -1847,7 +1949,7 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size)
        return ret;
 }
 
-void libertas_ps_sleep(wlan_private * priv, int wait_option)
+void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
 {
        lbs_deb_enter(LBS_DEB_HOST);
 
@@ -1856,7 +1958,7 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
         * Remove this check if it is to be supported in IBSS mode also
         */
 
-       libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
+       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
                              CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
 
        lbs_deb_leave(LBS_DEB_HOST);
@@ -1865,19 +1967,19 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option)
 /**
  *  @brief This function sends Exit_PS command to firmware.
  *
- *  @param priv        A pointer to wlan_private structure
+ *  @param priv        A pointer to struct lbs_private structure
  *  @param wait_option wait response or not
  *  @return            n/a
  */
-void libertas_ps_wakeup(wlan_private * priv, int wait_option)
+void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
 {
        __le32 Localpsmode;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM);
+       Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
 
-       libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
+       lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
                              CMD_SUBCMD_EXIT_PS,
                              wait_option, 0, &Localpsmode);
 
@@ -1888,37 +1990,36 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option)
  *  @brief This function checks condition and prepares to
  *  send sleep confirm command to firmware if ok.
  *
- *  @param priv        A pointer to wlan_private structure
+ *  @param priv        A pointer to struct lbs_private structure
  *  @param psmode      Power Saving mode
  *  @return            n/a
  */
-void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
+void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
 {
        unsigned long flags =0;
-       wlan_adapter *adapter = priv->adapter;
        u8 allowed = 1;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
        if (priv->dnld_sent) {
                allowed = 0;
-               lbs_deb_host("dnld_sent was set");
+               lbs_deb_host("dnld_sent was set\n");
        }
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       if (adapter->cur_cmd) {
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       if (priv->cur_cmd) {
                allowed = 0;
-               lbs_deb_host("cur_cmd was set");
+               lbs_deb_host("cur_cmd was set\n");
        }
-       if (adapter->intcounter > 0) {
+       if (priv->intcounter > 0) {
                allowed = 0;
-               lbs_deb_host("intcounter %d", adapter->intcounter);
+               lbs_deb_host("intcounter %d\n", priv->intcounter);
        }
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        if (allowed) {
-               lbs_deb_host("sending libertas_ps_confirm_sleep\n");
-               sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,
+               lbs_deb_host("sending lbs_ps_confirm_sleep\n");
+               sendconfirmsleep(priv, (u8 *) & priv->lbs_ps_confirm_sleep,
                                 sizeof(struct PS_CMD_ConfirmSleep));
        } else {
                lbs_deb_host("sleep confirm has been delayed\n");
@@ -1926,3 +2027,123 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode)
 
        lbs_deb_leave(LBS_DEB_HOST);
 }
+
+
+/**
+ *  @brief Simple callback that copies response back into command
+ *
+ *  @param priv        A pointer to struct lbs_private structure
+ *  @param extra       A pointer to the original command structure for which
+ *                      'resp' is a response
+ *  @param resp         A pointer to the command response
+ *
+ *  @return            0 on success, error on failure
+ */
+int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
+                    struct cmd_header *resp)
+{
+       struct cmd_header *buf = (void *)extra;
+       uint16_t copy_len;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+
+       copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
+       lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, "
+                   "copy back buffer was %u bytes\n", copy_len,
+                   le16_to_cpu(resp->size), le16_to_cpu(buf->size));
+       memcpy(buf, resp, copy_len);
+
+       lbs_deb_leave(LBS_DEB_CMD);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
+
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
+                                     struct cmd_header *in_cmd, int in_cmd_size,
+                                     int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+                                     unsigned long callback_arg)
+{
+       struct cmd_ctrl_node *cmdnode;
+
+       lbs_deb_enter(LBS_DEB_HOST);
+
+       if (priv->surpriseremoved) {
+               lbs_deb_host("PREP_CMD: card removed\n");
+               cmdnode = ERR_PTR(-ENOENT);
+               goto done;
+       }
+
+       cmdnode = lbs_get_cmd_ctrl_node(priv);
+       if (cmdnode == NULL) {
+               lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
+
+               /* Wake up main thread to execute next command */
+               wake_up_interruptible(&priv->waitq);
+               cmdnode = ERR_PTR(-ENOBUFS);
+               goto done;
+       }
+
+       cmdnode->callback = callback;
+       cmdnode->callback_arg = callback_arg;
+
+       /* Copy the incoming command to the buffer */
+       memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
+
+       /* Set sequence number, clean result, move to buffer */
+       priv->seqnum++;
+       cmdnode->cmdbuf->command = cpu_to_le16(command);
+       cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
+       cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
+       cmdnode->cmdbuf->result  = 0;
+
+       lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
+
+       /* here was the big old switch() statement, which is now obsolete,
+        * because the caller of lbs_cmd() sets up all of *cmd for us. */
+
+       cmdnode->cmdwaitqwoken = 0;
+       lbs_queue_cmd(priv, cmdnode);
+       wake_up_interruptible(&priv->waitq);
+
+ done:
+       lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
+       return cmdnode;
+}
+
+int __lbs_cmd(struct lbs_private *priv, uint16_t command,
+             struct cmd_header *in_cmd, int in_cmd_size,
+             int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+             unsigned long callback_arg)
+{
+       struct cmd_ctrl_node *cmdnode;
+       unsigned long flags;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_HOST);
+
+       cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
+                                 callback, callback_arg);
+       if (IS_ERR(cmdnode)) {
+               ret = PTR_ERR(cmdnode);
+               goto done;
+       }
+
+       might_sleep();
+       wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
+
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       ret = cmdnode->result;
+       if (ret)
+               lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
+                           command, ret);
+
+       __lbs_cleanup_and_insert_cmd(priv, cmdnode);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+done:
+       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__lbs_cmd);
+
+
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h
new file mode 100644 (file)
index 0000000..b9ab85c
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (C) 2007, Red Hat, Inc. */
+
+#ifndef _LBS_CMD_H_
+#define _LBS_CMD_H_
+
+#include "hostcmd.h"
+#include "dev.h"
+
+/* lbs_cmd() infers the size of the buffer to copy data back into, from
+   the size of the target of the pointer. Since the command to be sent 
+   may often be smaller, that size is set in cmd->size by the caller.*/
+#define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg)  ({              \
+       uint16_t __sz = le16_to_cpu((cmd)->hdr.size);           \
+       (cmd)->hdr.size = cpu_to_le16(sizeof(*(cmd)));          \
+       __lbs_cmd(priv, cmdnr, &(cmd)->hdr, __sz, cb, cb_arg);  \
+})
+
+#define lbs_cmd_with_response(priv, cmdnr, cmd)        \
+       lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
+
+/* __lbs_cmd() will free the cmdnode and return success/failure.
+   __lbs_cmd_async() requires that the callback free the cmdnode */
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
+                                     struct cmd_header *in_cmd, int in_cmd_size,
+                                     int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+                                     unsigned long callback_arg);
+int __lbs_cmd(struct lbs_private *priv, uint16_t command,
+             struct cmd_header *in_cmd, int in_cmd_size,
+             int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+             unsigned long callback_arg);
+
+int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
+                    struct cmd_header *resp);
+
+int lbs_update_hw_spec(struct lbs_private *priv);
+
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+                   struct cmd_ds_mesh_access *cmd);
+
+int lbs_get_data_rate(struct lbs_private *priv);
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
+
+int lbs_get_channel(struct lbs_private *priv);
+int lbs_set_channel(struct lbs_private *priv, u8 channel);
+
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
+
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
+int lbs_suspend(struct lbs_private *priv);
+int lbs_resume(struct lbs_private *priv);
+
+int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv,
+                                     uint16_t cmd_action, uint16_t *timeout);
+int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
+                               struct sleep_params *sp);
+int lbs_cmd_802_11_set_wep(struct lbs_private *priv, uint16_t cmd_action,
+                          struct assoc_request *assoc);
+int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, uint16_t cmd_action,
+                             uint16_t *enable);
+
+#endif /* _LBS_CMD_H */
index 8f90892ea22ee7b39cb0a17620b6800e4512704a..159216a91903d14e5f5ec5df62321d302f72b504 100644 (file)
  *  reports disconnect to upper layer, clean tx/rx packets,
  *  reset link state etc.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @return       n/a
  */
-void libertas_mac_event_disconnected(wlan_private * priv)
+void lbs_mac_event_disconnected(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
        union iwreq_data wrqu;
 
-       if (adapter->connect_status != LIBERTAS_CONNECTED)
+       if (priv->connect_status != LBS_CONNECTED)
                return;
 
-       lbs_deb_enter(LBS_DEB_CMD);
+       lbs_deb_enter(LBS_DEB_ASSOC);
 
        memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
        wrqu.ap_addr.sa_family = ARPHRD_ETHER;
@@ -44,40 +43,36 @@ void libertas_mac_event_disconnected(wlan_private * priv)
        msleep_interruptible(1000);
        wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
 
-       /* Free Tx and Rx packets */
-       kfree_skb(priv->adapter->currenttxskb);
-       priv->adapter->currenttxskb = NULL;
-
        /* report disconnect to upper layer */
        netif_stop_queue(priv->dev);
        netif_carrier_off(priv->dev);
 
+       /* Free Tx and Rx packets */
+       kfree_skb(priv->currenttxskb);
+       priv->currenttxskb = NULL;
+       priv->tx_pending_len = 0;
+
        /* reset SNR/NF/RSSI values */
-       memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
-       memset(adapter->NF, 0x00, sizeof(adapter->NF));
-       memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI));
-       memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
-       memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
-       adapter->nextSNRNF = 0;
-       adapter->numSNRNF = 0;
-       lbs_deb_cmd("current SSID '%s', length %u\n",
-                   escape_essid(adapter->curbssparams.ssid,
-                                adapter->curbssparams.ssid_len),
-                   adapter->curbssparams.ssid_len);
-
-       adapter->connect_status = LIBERTAS_DISCONNECTED;
+       memset(priv->SNR, 0x00, sizeof(priv->SNR));
+       memset(priv->NF, 0x00, sizeof(priv->NF));
+       memset(priv->RSSI, 0x00, sizeof(priv->RSSI));
+       memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
+       memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
+       priv->nextSNRNF = 0;
+       priv->numSNRNF = 0;
+       priv->connect_status = LBS_DISCONNECTED;
 
        /* Clear out associated SSID and BSSID since connection is
         * no longer valid.
         */
-       memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
-       memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
-       adapter->curbssparams.ssid_len = 0;
+       memset(&priv->curbssparams.bssid, 0, ETH_ALEN);
+       memset(&priv->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
+       priv->curbssparams.ssid_len = 0;
 
-       if (adapter->psstate != PS_STATE_FULL_POWER) {
+       if (priv->psstate != PS_STATE_FULL_POWER) {
                /* make firmware to exit PS mode */
                lbs_deb_cmd("disconnected, so exit PS mode\n");
-               libertas_ps_wakeup(priv, 0);
+               lbs_ps_wakeup(priv, 0);
        }
        lbs_deb_leave(LBS_DEB_CMD);
 }
@@ -85,11 +80,11 @@ void libertas_mac_event_disconnected(wlan_private * priv)
 /**
  *  @brief This function handles MIC failure event.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @para  event   the event id
  *  @return       n/a
  */
-static void handle_mic_failureevent(wlan_private * priv, u32 event)
+static void handle_mic_failureevent(struct lbs_private *priv, u32 event)
 {
        char buf[50];
 
@@ -104,15 +99,14 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event)
                strcat(buf, "multicast ");
        }
 
-       libertas_send_iwevcustom_event(priv, buf);
+       lbs_send_iwevcustom_event(priv, buf);
        lbs_deb_leave(LBS_DEB_CMD);
 }
 
-static int wlan_ret_reg_access(wlan_private * priv,
+static int lbs_ret_reg_access(struct lbs_private *priv,
                               u16 type, struct cmd_ds_command *resp)
 {
        int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
@@ -121,8 +115,8 @@ static int wlan_ret_reg_access(wlan_private * priv,
                {
                        struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
 
-                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-                       adapter->offsetvalue.value = le32_to_cpu(reg->value);
+                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
+                       priv->offsetvalue.value = le32_to_cpu(reg->value);
                        break;
                }
 
@@ -130,8 +124,8 @@ static int wlan_ret_reg_access(wlan_private * priv,
                {
                        struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
 
-                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-                       adapter->offsetvalue.value = reg->value;
+                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
+                       priv->offsetvalue.value = reg->value;
                        break;
                }
 
@@ -139,8 +133,8 @@ static int wlan_ret_reg_access(wlan_private * priv,
                {
                        struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
 
-                       adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
-                       adapter->offsetvalue.value = reg->value;
+                       priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
+                       priv->offsetvalue.value = reg->value;
                        break;
                }
 
@@ -152,112 +146,23 @@ static int wlan_ret_reg_access(wlan_private * priv,
        return ret;
 }
 
-static int wlan_ret_get_hw_spec(wlan_private * priv,
-                               struct cmd_ds_command *resp)
-{
-       u32 i;
-       struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec;
-       wlan_adapter *adapter = priv->adapter;
-       int ret = 0;
-       DECLARE_MAC_BUF(mac);
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
-
-       memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);
-
-       lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
-                   adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
-                   adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
-       lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
-                   print_mac(mac, hwspec->permanentaddr));
-       lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
-              hwspec->hwifversion, hwspec->version);
-
-       /* 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.
-        */
-       adapter->regioncode = le16_to_cpu(hwspec->regioncode) & 0xFF;
-
-       for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
-               /* use the region code to search for the index */
-               if (adapter->regioncode == libertas_region_code_to_index[i]) {
-                       break;
-               }
-       }
-
-       /* if it's unidentified region code, use the default (USA) */
-       if (i >= MRVDRV_MAX_REGION_CODE) {
-               adapter->regioncode = 0x10;
-               lbs_pr_info("unidentified region code; using the default (USA)\n");
-       }
-
-       if (adapter->current_addr[0] == 0xff)
-               memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);
-
-       memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
-       if (priv->mesh_dev)
-               memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
-
-       if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
-               ret = -1;
-               goto done;
-       }
-
-       if (libertas_set_universaltable(priv, 0)) {
-               ret = -1;
-               goto done;
-       }
-
-done:
-       lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
-       return ret;
-}
-
-static int wlan_ret_802_11_sleep_params(wlan_private * priv,
-                                       struct cmd_ds_command *resp)
-{
-       struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
-       wlan_adapter *adapter = priv->adapter;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, calcontrol 0x%x "
-                   "extsleepclk 0x%x\n", le16_to_cpu(sp->error),
-                   le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
-                   sp->calcontrol, sp->externalsleepclk);
-
-       adapter->sp.sp_error = le16_to_cpu(sp->error);
-       adapter->sp.sp_offset = le16_to_cpu(sp->offset);
-       adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
-       adapter->sp.sp_calcontrol = sp->calcontrol;
-       adapter->sp.sp_extsleepclk = sp->externalsleepclk;
-       adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
-
-       lbs_deb_enter(LBS_DEB_CMD);
-       return 0;
-}
-
-static int wlan_ret_802_11_stat(wlan_private * priv,
+static int lbs_ret_802_11_stat(struct lbs_private *priv,
                                struct cmd_ds_command *resp)
 {
        lbs_deb_enter(LBS_DEB_CMD);
-/*     currently adapter->wlan802_11Stat is unused
+/*     currently priv->wlan802_11Stat is unused
 
        struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
-       wlan_adapter *adapter = priv->adapter;
 
        // TODO Convert it to Big endian befor copy
-       memcpy(&adapter->wlan802_11Stat,
+       memcpy(&priv->wlan802_11Stat,
               p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
 */
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
+static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv,
                                    struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
@@ -273,22 +178,22 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
        if (querytype == CMD_ACT_GET) {
                switch (oid) {
                case FRAGTHRESH_I:
-                       priv->adapter->fragthsd =
+                       priv->fragthsd =
                                le16_to_cpu(*((__le16 *)(smib->value)));
                        lbs_deb_cmd("SNMP_RESP: frag threshold %u\n",
-                                   priv->adapter->fragthsd);
+                                   priv->fragthsd);
                        break;
                case RTSTHRESH_I:
-                       priv->adapter->rtsthsd =
+                       priv->rtsthsd =
                                le16_to_cpu(*((__le16 *)(smib->value)));
                        lbs_deb_cmd("SNMP_RESP: rts threshold %u\n",
-                                   priv->adapter->rtsthsd);
+                                   priv->rtsthsd);
                        break;
                case SHORT_RETRYLIM_I:
-                       priv->adapter->txretrycount =
+                       priv->txretrycount =
                                le16_to_cpu(*((__le16 *)(smib->value)));
                        lbs_deb_cmd("SNMP_RESP: tx retry count %u\n",
-                                   priv->adapter->rtsthsd);
+                                   priv->rtsthsd);
                        break;
                default:
                        break;
@@ -299,12 +204,11 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
        return 0;
 }
 
-static int wlan_ret_802_11_key_material(wlan_private * priv,
+static int lbs_ret_802_11_key_material(struct lbs_private *priv,
                                        struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_key_material *pkeymaterial =
            &resp->params.keymaterial;
-       wlan_adapter *adapter = priv->adapter;
        u16 action = le16_to_cpu(pkeymaterial->action);
 
        lbs_deb_enter(LBS_DEB_CMD);
@@ -332,9 +236,9 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
                                break;
 
                        if (key_flags & KEY_INFO_WPA_UNICAST)
-                               pkey = &adapter->wpa_unicast_key;
+                               pkey = &priv->wpa_unicast_key;
                        else if (key_flags & KEY_INFO_WPA_MCAST)
-                               pkey = &adapter->wpa_mcast_key;
+                               pkey = &priv->wpa_mcast_key;
                        else
                                break;
 
@@ -355,134 +259,85 @@ static int wlan_ret_802_11_key_material(wlan_private * priv,
        return 0;
 }
 
-static int wlan_ret_802_11_mac_address(wlan_private * priv,
+static int lbs_ret_802_11_mac_address(struct lbs_private *priv,
                                       struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
+       memcpy(priv->current_addr, macadd->macadd, ETH_ALEN);
 
        lbs_deb_enter(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
+static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv,
                                       struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
+       priv->txpowerlevel = le16_to_cpu(rtp->currentlevel);
 
-       lbs_deb_cmd("TX power currently %d\n", adapter->txpowerlevel);
+       lbs_deb_cmd("TX power currently %d\n", priv->txpowerlevel);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
+static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
                                              struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
        if (rates->action == CMD_ACT_GET) {
-               adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);
-               adapter->ratebitmap = le16_to_cpu(rates->bitmap);
+               priv->enablehwauto = le16_to_cpu(rates->enablehwauto);
+               priv->ratebitmap = le16_to_cpu(rates->bitmap);
        }
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_ret_802_11_data_rate(wlan_private * priv,
-                                    struct cmd_ds_command *resp)
-{
-       struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
-       wlan_adapter *adapter = priv->adapter;
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) pdatarate,
-               sizeof(struct cmd_ds_802_11_data_rate));
-
-       /* FIXME: get actual rates FW can do if this command actually returns
-        * all data rates supported.
-        */
-       adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]);
-       lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", adapter->cur_rate);
-
-       lbs_deb_leave(LBS_DEB_CMD);
-       return 0;
-}
-
-static int wlan_ret_802_11_rf_channel(wlan_private * priv,
-                                     struct cmd_ds_command *resp)
-{
-       struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
-       wlan_adapter *adapter = priv->adapter;
-       u16 action = le16_to_cpu(rfchannel->action);
-       u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
-
-       lbs_deb_enter(LBS_DEB_CMD);
-
-       if (action == CMD_OPT_802_11_RF_CHANNEL_GET
-           && adapter->curbssparams.channel != newchannel) {
-               lbs_deb_cmd("channel switch from %d to %d\n",
-                      adapter->curbssparams.channel, newchannel);
-
-               /* Update the channel again */
-               adapter->curbssparams.channel = newchannel;
-       }
-
-       lbs_deb_enter(LBS_DEB_CMD);
-       return 0;
-}
-
-static int wlan_ret_802_11_rssi(wlan_private * priv,
+static int lbs_ret_802_11_rssi(struct lbs_private *priv,
                                struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
        /* store the non average value */
-       adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
-       adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
+       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
+       priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
 
-       adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
-       adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
+       priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
+       priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
 
-       adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
-           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
-                    adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
+       priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
+           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
+                    priv->NF[TYPE_BEACON][TYPE_NOAVG]);
 
-       adapter->RSSI[TYPE_BEACON][TYPE_AVG] =
-           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
-                    adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
+       priv->RSSI[TYPE_BEACON][TYPE_AVG] =
+           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
+                    priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
 
        lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
-              adapter->RSSI[TYPE_BEACON][TYPE_NOAVG],
-              adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
+              priv->RSSI[TYPE_BEACON][TYPE_NOAVG],
+              priv->RSSI[TYPE_BEACON][TYPE_AVG]);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
+static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv,
                                  struct cmd_ds_command *resp)
 {
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_ioctl_regrdwr *pbuf;
-       pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
+       struct lbs_ioctl_regrdwr *pbuf;
+       pbuf = (struct lbs_ioctl_regrdwr *) priv->prdeeprom;
 
        lbs_deb_enter_args(LBS_DEB_CMD, "len %d",
               le16_to_cpu(resp->params.rdeeprom.bytecount));
@@ -503,46 +358,45 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
        return 0;
 }
 
-static int wlan_ret_get_log(wlan_private * priv,
+static int lbs_ret_get_log(struct lbs_private *priv,
                            struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
        /* Stored little-endian */
-       memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
+       memcpy(&priv->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
 
        lbs_deb_leave(LBS_DEB_CMD);
        return 0;
 }
 
-static int libertas_ret_802_11_enable_rsn(wlan_private * priv,
-                                          struct cmd_ds_command *resp)
+static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv,
+                                       struct cmd_ds_command *resp)
 {
-       struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn;
-       wlan_adapter *adapter = priv->adapter;
-       u32 * pdata_buf = adapter->cur_cmd->pdata_buf;
+       struct cmd_ds_802_11_beacon_control *bcn_ctrl =
+           &resp->params.bcn_ctrl;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       if (enable_rsn->action == cpu_to_le16(CMD_ACT_GET)) {
-               if (pdata_buf)
-                       *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable);
+       if (bcn_ctrl->action == CMD_ACT_GET) {
+               priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable);
+               priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period);
        }
 
-       lbs_deb_leave(LBS_DEB_CMD);
+       lbs_deb_enter(LBS_DEB_CMD);
        return 0;
 }
 
-static inline int handle_cmd_response(u16 respcmd,
-                                     struct cmd_ds_command *resp,
-                                     wlan_private *priv)
+static inline int handle_cmd_response(struct lbs_private *priv,
+                                     unsigned long dummy,
+                                     struct cmd_header *cmd_response)
 {
+       struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response;
        int ret = 0;
        unsigned long flags;
-       wlan_adapter *adapter = priv->adapter;
+       uint16_t respcmd = le16_to_cpu(resp->command);
 
        lbs_deb_enter(LBS_DEB_HOST);
 
@@ -550,218 +404,213 @@ static inline int handle_cmd_response(u16 respcmd,
        case CMD_RET(CMD_MAC_REG_ACCESS):
        case CMD_RET(CMD_BBP_REG_ACCESS):
        case CMD_RET(CMD_RF_REG_ACCESS):
-               ret = wlan_ret_reg_access(priv, respcmd, resp);
-               break;
-
-       case CMD_RET(CMD_GET_HW_SPEC):
-               ret = wlan_ret_get_hw_spec(priv, resp);
+               ret = lbs_ret_reg_access(priv, respcmd, resp);
                break;
 
        case CMD_RET(CMD_802_11_SCAN):
-               ret = libertas_ret_80211_scan(priv, resp);
+               ret = lbs_ret_80211_scan(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_GET_LOG):
-               ret = wlan_ret_get_log(priv, resp);
+               ret = lbs_ret_get_log(priv, resp);
                break;
 
        case CMD_RET_802_11_ASSOCIATE:
        case CMD_RET(CMD_802_11_ASSOCIATE):
        case CMD_RET(CMD_802_11_REASSOCIATE):
-               ret = libertas_ret_80211_associate(priv, resp);
+               ret = lbs_ret_80211_associate(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_DISASSOCIATE):
        case CMD_RET(CMD_802_11_DEAUTHENTICATE):
-               ret = libertas_ret_80211_disassociate(priv, resp);
+               ret = lbs_ret_80211_disassociate(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_AD_HOC_START):
        case CMD_RET(CMD_802_11_AD_HOC_JOIN):
-               ret = libertas_ret_80211_ad_hoc_start(priv, resp);
+               ret = lbs_ret_80211_ad_hoc_start(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_GET_STAT):
-               ret = wlan_ret_802_11_stat(priv, resp);
+               ret = lbs_ret_802_11_stat(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_SNMP_MIB):
-               ret = wlan_ret_802_11_snmp_mib(priv, resp);
+               ret = lbs_ret_802_11_snmp_mib(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_RF_TX_POWER):
-               ret = wlan_ret_802_11_rf_tx_power(priv, resp);
+               ret = lbs_ret_802_11_rf_tx_power(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_SET_AFC):
        case CMD_RET(CMD_802_11_GET_AFC):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc,
                        sizeof(struct cmd_ds_802_11_afc));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                break;
 
        case CMD_RET(CMD_MAC_MULTICAST_ADR):
        case CMD_RET(CMD_MAC_CONTROL):
-       case CMD_RET(CMD_802_11_SET_WEP):
        case CMD_RET(CMD_802_11_RESET):
        case CMD_RET(CMD_802_11_AUTHENTICATE):
-       case CMD_RET(CMD_802_11_RADIO_CONTROL):
        case CMD_RET(CMD_802_11_BEACON_STOP):
                break;
 
-       case CMD_RET(CMD_802_11_ENABLE_RSN):
-               ret = libertas_ret_802_11_enable_rsn(priv, resp);
-               break;
-
-       case CMD_RET(CMD_802_11_DATA_RATE):
-               ret = wlan_ret_802_11_data_rate(priv, resp);
-               break;
        case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
-               ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp);
-               break;
-       case CMD_RET(CMD_802_11_RF_CHANNEL):
-               ret = wlan_ret_802_11_rf_channel(priv, resp);
+               ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_RSSI):
-               ret = wlan_ret_802_11_rssi(priv, resp);
+               ret = lbs_ret_802_11_rssi(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_MAC_ADDRESS):
-               ret = wlan_ret_802_11_mac_address(priv, resp);
+               ret = lbs_ret_802_11_mac_address(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_AD_HOC_STOP):
-               ret = libertas_ret_80211_ad_hoc_stop(priv, resp);
+               ret = lbs_ret_80211_ad_hoc_stop(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_KEY_MATERIAL):
-               ret = wlan_ret_802_11_key_material(priv, resp);
+               ret = lbs_ret_802_11_key_material(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_EEPROM_ACCESS):
-               ret = wlan_ret_802_11_eeprom_access(priv, resp);
+               ret = lbs_ret_802_11_eeprom_access(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11D_DOMAIN_INFO):
-               ret = libertas_ret_802_11d_domain_info(priv, resp);
-               break;
-
-       case CMD_RET(CMD_802_11_SLEEP_PARAMS):
-               ret = wlan_ret_802_11_sleep_params(priv, resp);
-               break;
-       case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               *((u16 *) adapter->cur_cmd->pdata_buf) =
-                   le16_to_cpu(resp->params.inactivity_timeout.timeout);
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               ret = lbs_ret_802_11d_domain_info(priv, resp);
                break;
 
        case CMD_RET(CMD_802_11_TPC_CFG):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
                        sizeof(struct cmd_ds_802_11_tpc_cfg));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                break;
        case CMD_RET(CMD_802_11_LED_GPIO_CTRL):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.ledgpio,
                        sizeof(struct cmd_ds_802_11_led_ctrl));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                break;
+
        case CMD_RET(CMD_802_11_PWR_CFG):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               memmove((void *)priv->cur_cmd->callback_arg, &resp->params.pwrcfg,
                        sizeof(struct cmd_ds_802_11_pwr_cfg));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                break;
 
        case CMD_RET(CMD_GET_TSF):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               memcpy(priv->adapter->cur_cmd->pdata_buf,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               memcpy((void *)priv->cur_cmd->callback_arg,
                       &resp->params.gettsf.tsfvalue, sizeof(u64));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                break;
        case CMD_RET(CMD_BT_ACCESS):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               if (adapter->cur_cmd->pdata_buf)
-                       memcpy(adapter->cur_cmd->pdata_buf,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               if (priv->cur_cmd->callback_arg)
+                       memcpy((void *)priv->cur_cmd->callback_arg,
                               &resp->params.bt.addr1, 2 * ETH_ALEN);
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                break;
        case CMD_RET(CMD_FWT_ACCESS):
-               spin_lock_irqsave(&adapter->driver_lock, flags);
-               if (adapter->cur_cmd->pdata_buf)
-                       memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt,
+               spin_lock_irqsave(&priv->driver_lock, flags);
+               if (priv->cur_cmd->callback_arg)
+                       memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt,
                               sizeof(resp->params.fwt));
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                break;
-       case CMD_RET(CMD_MESH_ACCESS):
-               if (adapter->cur_cmd->pdata_buf)
-                       memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
-                              sizeof(resp->params.mesh));
+       case CMD_RET(CMD_802_11_BEACON_CTRL):
+               ret = lbs_ret_802_11_bcn_ctrl(priv, resp);
                break;
+
        default:
                lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n",
-                           resp->command);
+                            le16_to_cpu(resp->command));
                break;
        }
        lbs_deb_leave(LBS_DEB_HOST);
        return ret;
 }
 
-int libertas_process_rx_command(wlan_private * priv)
+int lbs_process_rx_command(struct lbs_private *priv)
 {
-       u16 respcmd;
-       struct cmd_ds_command *resp;
-       wlan_adapter *adapter = priv->adapter;
+       uint16_t respcmd, curcmd;
+       struct cmd_header *resp;
        int ret = 0;
-       ulong flags;
-       u16 result;
+       unsigned long flags;
+       uint16_t result;
 
        lbs_deb_enter(LBS_DEB_HOST);
 
-       /* Now we got response from FW, cancel the command timer */
-       del_timer(&adapter->command_timer);
-
-       mutex_lock(&adapter->lock);
-       spin_lock_irqsave(&adapter->driver_lock, flags);
+       mutex_lock(&priv->lock);
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
-       if (!adapter->cur_cmd) {
+       if (!priv->cur_cmd) {
                lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
                ret = -1;
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                goto done;
        }
-       resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
+
+       resp = (void *)priv->upld_buf;
+
+       curcmd = le16_to_cpu(resp->command);
 
        respcmd = le16_to_cpu(resp->command);
        result = le16_to_cpu(resp->result);
 
-       lbs_deb_host("CMD_RESP: response 0x%04x, size %d, jiffies %lu\n",
-               respcmd, priv->upld_len, jiffies);
-       lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", adapter->cur_cmd->bufvirtualaddr,
-                   priv->upld_len);
-
-       if (!(respcmd & 0x8000)) {
-               lbs_deb_host("invalid response!\n");
-               adapter->cur_cmd_retcode = -1;
-               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-               adapter->nr_cmd_pending--;
-               adapter->cur_cmd = NULL;
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       lbs_deb_host("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n",
+                    respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies);
+       lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len);
+
+       if (resp->seqnum != resp->seqnum) {
+               lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
+                           le16_to_cpu(resp->seqnum), le16_to_cpu(resp->seqnum));
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
+               ret = -1;
+               goto done;
+       }
+       if (respcmd != CMD_RET(curcmd) &&
+           respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) {
+               lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
+               ret = -1;
+               goto done;
+       }
+
+       if (resp->result == cpu_to_le16(0x0004)) {
+               /* 0x0004 means -EAGAIN. Drop the response, let it time out
+                  and be resubmitted */
+               lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
+                           le16_to_cpu(resp->command));
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                ret = -1;
                goto done;
        }
 
+       /* Now we got response from FW, cancel the command timer */
+       del_timer(&priv->command_timer);
+       priv->cmd_timed_out = 0;
+       if (priv->nr_retries) {
+               lbs_pr_info("Received result %x to command %x after %d retries\n",
+                           result, curcmd, priv->nr_retries);
+               priv->nr_retries = 0;
+       }
+
        /* Store the response code to cur_cmd_retcode. */
-       adapter->cur_cmd_retcode = result;;
+       priv->cur_cmd_retcode = result;
 
        if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
-               struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
+               struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
                u16 action = le16_to_cpu(psmode->action);
 
                lbs_deb_host(
@@ -774,54 +623,45 @@ int libertas_process_rx_command(wlan_private * priv)
                        /*
                         * We should not re-try enter-ps command in
                         * ad-hoc mode. It takes place in
-                        * libertas_execute_next_command().
+                        * lbs_execute_next_command().
                         */
-                       if (adapter->mode == IW_MODE_ADHOC &&
+                       if (priv->mode == IW_MODE_ADHOC &&
                            action == CMD_SUBCMD_ENTER_PS)
-                               adapter->psmode = WLAN802_11POWERMODECAM;
+                               priv->psmode = LBS802_11POWERMODECAM;
                } else if (action == CMD_SUBCMD_ENTER_PS) {
-                       adapter->needtowakeup = 0;
-                       adapter->psstate = PS_STATE_AWAKE;
+                       priv->needtowakeup = 0;
+                       priv->psstate = PS_STATE_AWAKE;
 
                        lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
-                       if (adapter->connect_status != LIBERTAS_CONNECTED) {
+                       if (priv->connect_status != LBS_CONNECTED) {
                                /*
                                 * When Deauth Event received before Enter_PS command
                                 * response, We need to wake up the firmware.
                                 */
                                lbs_deb_host(
-                                      "disconnected, invoking libertas_ps_wakeup\n");
+                                      "disconnected, invoking lbs_ps_wakeup\n");
 
-                               spin_unlock_irqrestore(&adapter->driver_lock, flags);
-                               mutex_unlock(&adapter->lock);
-                               libertas_ps_wakeup(priv, 0);
-                               mutex_lock(&adapter->lock);
-                               spin_lock_irqsave(&adapter->driver_lock, flags);
+                               spin_unlock_irqrestore(&priv->driver_lock, flags);
+                               mutex_unlock(&priv->lock);
+                               lbs_ps_wakeup(priv, 0);
+                               mutex_lock(&priv->lock);
+                               spin_lock_irqsave(&priv->driver_lock, flags);
                        }
                } else if (action == CMD_SUBCMD_EXIT_PS) {
-                       adapter->needtowakeup = 0;
-                       adapter->psstate = PS_STATE_FULL_POWER;
+                       priv->needtowakeup = 0;
+                       priv->psstate = PS_STATE_FULL_POWER;
                        lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
                } else {
                        lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
                }
 
-               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-               adapter->nr_cmd_pending--;
-               adapter->cur_cmd = NULL;
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               lbs_complete_command(priv, priv->cur_cmd, result);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                ret = 0;
                goto done;
        }
 
-       if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) {
-               /* Copy the response back to response buffer */
-               memcpy(adapter->cur_cmd->pdata_buf, resp,
-                      le16_to_cpu(resp->size));
-               adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD;
-       }
-
        /* If the command is not successful, cleanup and return failure */
        if ((result != 0 || !(respcmd & 0x8000))) {
                lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
@@ -836,106 +676,132 @@ int libertas_process_rx_command(wlan_private * priv)
                        break;
 
                }
-
-               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-               adapter->nr_cmd_pending--;
-               adapter->cur_cmd = NULL;
-               spin_unlock_irqrestore(&adapter->driver_lock, flags);
+               lbs_complete_command(priv, priv->cur_cmd, result);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
 
                ret = -1;
                goto done;
        }
 
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-       ret = handle_cmd_response(respcmd, resp, priv);
+       if (priv->cur_cmd && priv->cur_cmd->callback) {
+               ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
+                               resp);
+       } else
+               ret = handle_cmd_response(priv, 0, resp);
 
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       if (adapter->cur_cmd) {
+       spin_lock_irqsave(&priv->driver_lock, flags);
+
+       if (priv->cur_cmd) {
                /* Clean up and Put current command back to cmdfreeq */
-               __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-               adapter->nr_cmd_pending--;
-               WARN_ON(adapter->nr_cmd_pending > 128);
-               adapter->cur_cmd = NULL;
+               lbs_complete_command(priv, priv->cur_cmd, result);
        }
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 done:
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
        lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
        return ret;
 }
 
-int libertas_process_event(wlan_private * priv)
+static int lbs_send_confirmwake(struct lbs_private *priv)
+{
+       struct cmd_header *cmd = &priv->lbs_ps_confirm_wake;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_HOST);
+
+       cmd->command = cpu_to_le16(CMD_802_11_WAKEUP_CONFIRM);
+       cmd->size = cpu_to_le16(sizeof(*cmd));
+       cmd->seqnum = cpu_to_le16(++priv->seqnum);
+       cmd->result = 0;
+
+       lbs_deb_host("SEND_WAKEC_CMD: before download\n");
+
+       lbs_deb_hex(LBS_DEB_HOST, "wake confirm command", (void *)cmd, sizeof(*cmd));
+
+       ret = priv->hw_host_to_card(priv, MVMS_CMD, (void *)cmd, sizeof(*cmd));
+       if (ret)
+               lbs_pr_alert("SEND_WAKEC_CMD: Host to Card failed for Confirm Wake\n");
+
+       lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
+       return ret;
+}
+
+int lbs_process_event(struct lbs_private *priv)
 {
        int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
        u32 eventcause;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       spin_lock_irq(&adapter->driver_lock);
-       eventcause = adapter->eventcause;
-       spin_unlock_irq(&adapter->driver_lock);
+       spin_lock_irq(&priv->driver_lock);
+       eventcause = priv->eventcause >> SBI_EVENT_CAUSE_SHIFT;
+       spin_unlock_irq(&priv->driver_lock);
 
-       lbs_deb_cmd("event cause 0x%x\n", eventcause);
+       lbs_deb_cmd("event cause %d\n", eventcause);
 
-       switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
+       switch (eventcause) {
        case MACREG_INT_CODE_LINK_SENSED:
                lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
                break;
 
        case MACREG_INT_CODE_DEAUTHENTICATED:
                lbs_deb_cmd("EVENT: deauthenticated\n");
-               libertas_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv);
                break;
 
        case MACREG_INT_CODE_DISASSOCIATED:
                lbs_deb_cmd("EVENT: disassociated\n");
-               libertas_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv);
                break;
 
-       case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
+       case MACREG_INT_CODE_LINK_LOST_NO_SCAN:
                lbs_deb_cmd("EVENT: link lost\n");
-               libertas_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv);
                break;
 
        case MACREG_INT_CODE_PS_SLEEP:
                lbs_deb_cmd("EVENT: sleep\n");
 
                /* handle unexpected PS SLEEP event */
-               if (adapter->psstate == PS_STATE_FULL_POWER) {
+               if (priv->psstate == PS_STATE_FULL_POWER) {
                        lbs_deb_cmd(
                               "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
                        break;
                }
-               adapter->psstate = PS_STATE_PRE_SLEEP;
+               priv->psstate = PS_STATE_PRE_SLEEP;
 
-               libertas_ps_confirm_sleep(priv, (u16) adapter->psmode);
+               lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
 
                break;
 
+       case MACREG_INT_CODE_HOST_AWAKE:
+               lbs_deb_cmd("EVENT: HOST_AWAKE\n");
+               lbs_send_confirmwake(priv);
+               break;
+
        case MACREG_INT_CODE_PS_AWAKE:
                lbs_deb_cmd("EVENT: awake\n");
-
                /* handle unexpected PS AWAKE event */
-               if (adapter->psstate == PS_STATE_FULL_POWER) {
+               if (priv->psstate == PS_STATE_FULL_POWER) {
                        lbs_deb_cmd(
                               "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
                        break;
                }
 
-               adapter->psstate = PS_STATE_AWAKE;
+               priv->psstate = PS_STATE_AWAKE;
 
-               if (adapter->needtowakeup) {
+               if (priv->needtowakeup) {
                        /*
                         * wait for the command processing to finish
                         * before resuming sending
-                        * adapter->needtowakeup will be set to FALSE
-                        * in libertas_ps_wakeup()
+                        * priv->needtowakeup will be set to FALSE
+                        * in lbs_ps_wakeup()
                         */
                        lbs_deb_cmd("waking up ...\n");
-                       libertas_ps_wakeup(priv, 0);
+                       lbs_ps_wakeup(priv, 0);
                }
                break;
 
@@ -979,24 +845,24 @@ int libertas_process_event(wlan_private * priv)
                        break;
                }
                lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
-               adapter->connect_status = LIBERTAS_CONNECTED;
-               if (priv->mesh_open == 1) {
-                       netif_wake_queue(priv->mesh_dev);
+               priv->mesh_connect_status = LBS_CONNECTED;
+               if (priv->mesh_open) {
                        netif_carrier_on(priv->mesh_dev);
+                       if (!priv->tx_pending_len)
+                               netif_wake_queue(priv->mesh_dev);
                }
-               adapter->mode = IW_MODE_ADHOC;
+               priv->mode = IW_MODE_ADHOC;
                schedule_work(&priv->sync_channel);
                break;
 
        default:
-               lbs_pr_alert("EVENT: unknown event id 0x%04x\n",
-                      eventcause >> SBI_EVENT_CAUSE_SHIFT);
+               lbs_pr_alert("EVENT: unknown event id %d\n", eventcause);
                break;
        }
 
-       spin_lock_irq(&adapter->driver_lock);
-       adapter->eventcause = 0;
-       spin_unlock_irq(&adapter->driver_lock);
+       spin_lock_irq(&priv->driver_lock);
+       priv->eventcause = 0;
+       spin_unlock_irq(&priv->driver_lock);
 
        lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
        return ret;
index 0bda0b5119109d1f23f13ab78dd31de2dff1ce25..fd67b770dd784704c64628e145e650854546bc14 100644 (file)
 #include "decl.h"
 #include "host.h"
 #include "debugfs.h"
+#include "cmd.h"
 
-static struct dentry *libertas_dir = NULL;
+static struct dentry *lbs_dir;
 static char *szStates[] = {
        "Connected",
        "Disconnected"
 };
 
 #ifdef PROC_DEBUG
-static void libertas_debug_init(wlan_private * priv, struct net_device *dev);
+static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev);
 #endif
 
 static int open_file_generic(struct inode *inode, struct file *file)
@@ -35,19 +36,19 @@ static ssize_t write_file_dummy(struct file *file, const char __user *buf,
 
 static const size_t len = PAGE_SIZE;
 
-static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
+static ssize_t lbs_dev_info(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        size_t pos = 0;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
        ssize_t res;
 
        pos += snprintf(buf+pos, len-pos, "state = %s\n",
-                               szStates[priv->adapter->connect_status]);
+                               szStates[priv->connect_status]);
        pos += snprintf(buf+pos, len-pos, "region_code = %02x\n",
-                               (u32) priv->adapter->regioncode);
+                               (u32) priv->regioncode);
 
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 
@@ -56,10 +57,10 @@ static ssize_t libertas_dev_info(struct file *file, char __user *userbuf,
 }
 
 
-static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
+static ssize_t lbs_getscantable(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        size_t pos = 0;
        int numscansdone = 0, res;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
@@ -70,8 +71,8 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
        pos += snprintf(buf+pos, len-pos,
                "# | ch  | rssi |       bssid       |   cap    | Qual | SSID \n");
 
-       mutex_lock(&priv->adapter->lock);
-       list_for_each_entry (iter_bss, &priv->adapter->network_list, list) {
+       mutex_lock(&priv->lock);
+       list_for_each_entry (iter_bss, &priv->network_list, list) {
                u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS);
                u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY);
                u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT);
@@ -90,7 +91,7 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
 
                numscansdone++;
        }
-       mutex_unlock(&priv->adapter->lock);
+       mutex_unlock(&priv->lock);
 
        res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 
@@ -98,83 +99,75 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf,
        return res;
 }
 
-static ssize_t libertas_sleepparams_write(struct file *file,
+static ssize_t lbs_sleepparams_write(struct file *file,
                                const char __user *user_buf, size_t count,
                                loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       ssize_t buf_size, res;
+       struct lbs_private *priv = file->private_data;
+       ssize_t buf_size, ret;
+       struct sleep_params sp;
        int p1, p2, p3, p4, p5, p6;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
 
        buf_size = min(count, len - 1);
        if (copy_from_user(buf, user_buf, buf_size)) {
-               res = -EFAULT;
+               ret = -EFAULT;
                goto out_unlock;
        }
-       res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
-       if (res != 6) {
-               res = -EFAULT;
+       ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
+       if (ret != 6) {
+               ret = -EINVAL;
                goto out_unlock;
        }
-       priv->adapter->sp.sp_error = p1;
-       priv->adapter->sp.sp_offset = p2;
-       priv->adapter->sp.sp_stabletime = p3;
-       priv->adapter->sp.sp_calcontrol = p4;
-       priv->adapter->sp.sp_extsleepclk = p5;
-       priv->adapter->sp.sp_reserved = p6;
-
-        res = libertas_prepare_and_send_command(priv,
-                               CMD_802_11_SLEEP_PARAMS,
-                               CMD_ACT_SET,
-                               CMD_OPTION_WAITFORRSP, 0, NULL);
-
-       if (!res)
-               res = count;
-       else
-               res = -EINVAL;
+       sp.sp_error = p1;
+       sp.sp_offset = p2;
+       sp.sp_stabletime = p3;
+       sp.sp_calcontrol = p4;
+       sp.sp_extsleepclk = p5;
+       sp.sp_reserved = p6;
+
+       ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_SET, &sp);
+       if (!ret)
+               ret = count;
+       else if (ret > 0)
+               ret = -EINVAL;
 
 out_unlock:
        free_page(addr);
-       return res;
+       return ret;
 }
 
-static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res;
+       struct lbs_private *priv = file->private_data;
+       ssize_t ret;
        size_t pos = 0;
+       struct sleep_params sp;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
 
-        res = libertas_prepare_and_send_command(priv,
-                               CMD_802_11_SLEEP_PARAMS,
-                               CMD_ACT_GET,
-                               CMD_OPTION_WAITFORRSP, 0, NULL);
-       if (res) {
-               res = -EFAULT;
+       ret = lbs_cmd_802_11_sleep_params(priv, CMD_ACT_GET, &sp);
+       if (ret)
                goto out_unlock;
-       }
 
-       pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error,
-                       adapter->sp.sp_offset, adapter->sp.sp_stabletime,
-                       adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk,
-                       adapter->sp.sp_reserved);
+       pos += snprintf(buf, len, "%d %d %d %d %d %d\n", sp.sp_error,
+                       sp.sp_offset, sp.sp_stabletime,
+                       sp.sp_calcontrol, sp.sp_extsleepclk,
+                       sp.sp_reserved);
 
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
+       ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 
 out_unlock:
        free_page(addr);
-       return res;
+       return ret;
 }
 
-static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
+static ssize_t lbs_extscan(struct file *file, const char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        union iwreq_data wrqu;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
@@ -186,7 +179,7 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf,
                goto out_unlock;
        }
 
-       libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
+       lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0);
 
        memset(&wrqu, 0, sizeof(union iwreq_data));
        wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
@@ -196,45 +189,8 @@ out_unlock:
        return count;
 }
 
-static int libertas_parse_chan(char *buf, size_t count,
-                       struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur)
-{
-       char *start, *end, *hold, *str;
-       int i = 0;
-
-       start = strstr(buf, "chan=");
-       if (!start)
-               return -EINVAL;
-       start += 5;
-       end = strchr(start, ' ');
-       if (!end)
-               end = buf + count;
-       hold = kzalloc((end - start)+1, GFP_KERNEL);
-       if (!hold)
-               return -ENOMEM;
-       strncpy(hold, start, end - start);
-       hold[(end-start)+1] = '\0';
-       while(hold && (str = strsep(&hold, ","))) {
-               int chan;
-               char band, passive = 0;
-               sscanf(str, "%d%c%c", &chan, &band, &passive);
-               scan_cfg->chanlist[i].channumber = chan;
-               scan_cfg->chanlist[i].scantype = passive ? 1 : 0;
-               if (band == 'b' || band == 'g')
-                       scan_cfg->chanlist[i].radiotype = 0;
-               else if (band == 'a')
-                       scan_cfg->chanlist[i].radiotype = 1;
-
-               scan_cfg->chanlist[i].scantime = dur;
-               i++;
-       }
-
-       kfree(hold);
-       return i;
-}
-
-static void libertas_parse_bssid(char *buf, size_t count,
-                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
+static void lbs_parse_bssid(char *buf, size_t count,
+       struct lbs_ioctl_user_scan_cfg *scan_cfg)
 {
        char *hold;
        unsigned int mac[ETH_ALEN];
@@ -243,12 +199,13 @@ static void libertas_parse_bssid(char *buf, size_t count,
        if (!hold)
                return;
        hold += 6;
-       sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5);
+       sscanf(hold, "%02x:%02x:%02x:%02x:%02x:%02x",
+              mac, mac+1, mac+2, mac+3, mac+4, mac+5);
        memcpy(scan_cfg->bssid, mac, ETH_ALEN);
 }
 
-static void libertas_parse_ssid(char *buf, size_t count,
-                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
+static void lbs_parse_ssid(char *buf, size_t count,
+       struct lbs_ioctl_user_scan_cfg *scan_cfg)
 {
        char *hold, *end;
        ssize_t size;
@@ -267,7 +224,7 @@ static void libertas_parse_ssid(char *buf, size_t count,
        return;
 }
 
-static int libertas_parse_clear(char *buf, size_t count, const char *tag)
+static int lbs_parse_clear(char *buf, size_t count, const char *tag)
 {
        char *hold;
        int val;
@@ -284,8 +241,8 @@ static int libertas_parse_clear(char *buf, size_t count, const char *tag)
        return val;
 }
 
-static int libertas_parse_dur(char *buf, size_t count,
-                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
+static int lbs_parse_dur(char *buf, size_t count,
+       struct lbs_ioctl_user_scan_cfg *scan_cfg)
 {
        char *hold;
        int val;
@@ -299,25 +256,8 @@ static int libertas_parse_dur(char *buf, size_t count,
        return val;
 }
 
-static void libertas_parse_probes(char *buf, size_t count,
-                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
-{
-       char *hold;
-       int val;
-
-       hold = strstr(buf, "probes=");
-       if (!hold)
-               return;
-       hold += 7;
-       sscanf(hold, "%d", &val);
-
-       scan_cfg->numprobes = val;
-
-       return;
-}
-
-static void libertas_parse_type(char *buf, size_t count,
-                        struct wlan_ioctl_user_scan_cfg *scan_cfg)
+static void lbs_parse_type(char *buf, size_t count,
+       struct lbs_ioctl_user_scan_cfg *scan_cfg)
 {
        char *hold;
        int val;
@@ -337,1036 +277,324 @@ static void libertas_parse_type(char *buf, size_t count,
        return;
 }
 
-static ssize_t libertas_setuserscan(struct file *file,
+static ssize_t lbs_setuserscan(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
-       struct wlan_ioctl_user_scan_cfg *scan_cfg;
+       struct lbs_ioctl_user_scan_cfg *scan_cfg;
        union iwreq_data wrqu;
        int dur;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
+       char *buf = (char *)get_zeroed_page(GFP_KERNEL);
 
-       scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL);
-       if (!scan_cfg)
+       if (!buf)
                return -ENOMEM;
 
        buf_size = min(count, len - 1);
        if (copy_from_user(buf, userbuf, buf_size)) {
                res = -EFAULT;
-               goto out_unlock;
+               goto out_buf;
+       }
+
+       scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
+       if (!scan_cfg) {
+               res = -ENOMEM;
+               goto out_buf;
        }
+       res = count;
+
+       scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY;
 
-       scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY;
+       dur = lbs_parse_dur(buf, count, scan_cfg);
+       lbs_parse_bssid(buf, count, scan_cfg);
+       scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid=");
+       lbs_parse_ssid(buf, count, scan_cfg);
+       scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid=");
+       lbs_parse_type(buf, count, scan_cfg);
 
-       dur = libertas_parse_dur(buf, count, scan_cfg);
-       libertas_parse_chan(buf, count, scan_cfg, dur);
-       libertas_parse_bssid(buf, count, scan_cfg);
-       scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid=");
-       libertas_parse_ssid(buf, count, scan_cfg);
-       scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid=");
-       libertas_parse_probes(buf, count, scan_cfg);
-       libertas_parse_type(buf, count, scan_cfg);
+       lbs_scan_networks(priv, scan_cfg, 1);
+       wait_event_interruptible(priv->cmd_pending,
+                                priv->surpriseremoved || !priv->last_scanned_channel);
 
-       wlan_scan_networks(priv, scan_cfg, 1);
-       wait_event_interruptible(priv->adapter->cmd_pending,
-                                !priv->adapter->nr_cmd_pending);
+       if (priv->surpriseremoved)
+               goto out_scan_cfg;
 
        memset(&wrqu, 0x00, sizeof(union iwreq_data));
        wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
 
-out_unlock:
-       free_page(addr);
+ out_scan_cfg:
        kfree(scan_cfg);
-       return count;
+ out_buf:
+       free_page((unsigned long)buf);
+       return res;
 }
 
-static int libertas_event_initcmd(wlan_private *priv, void **response_buf,
-                       struct cmd_ctrl_node **cmdnode,
-                       struct cmd_ds_command **cmd)
-{
-       u16 wait_option = CMD_OPTION_WAITFORRSP;
-
-       if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) {
-               lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n");
-               return -ENOMEM;
-       }
-       if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) {
-               lbs_deb_debugfs("failed to allocate response buffer!\n");
-               return -ENOMEM;
-       }
-       libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL);
-       init_waitqueue_head(&(*cmdnode)->cmdwait_q);
-       (*cmdnode)->pdata_buf = *response_buf;
-       (*cmdnode)->cmdflags |= CMD_F_HOSTCMD;
-       (*cmdnode)->cmdwaitqwoken = 0;
-       *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr;
-       (*cmd)->command = cpu_to_le16(CMD_802_11_SUBSCRIBE_EVENT);
-       (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum);
-       (*cmd)->result = 0;
-       return 0;
-}
 
-static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf,
-                                 size_t count, loff_t *ppos)
+/*
+ * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might
+ * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the
+ * firmware. Here's an example:
+ *     04 01 02 00 00 00 05 01 02 00 00 00 06 01 02 00
+ *     00 00 07 01 02 00 3c 00 00 00 00 00 00 00 03 03
+ *     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ *
+ * The 04 01 is the TLV type (here TLV_TYPE_RSSI_LOW), 02 00 is the length,
+ * 00 00 are the data bytes of this TLV. For this TLV, their meaning is
+ * defined in mrvlietypes_thresholds
+ *
+ * This function searches in this TLV data chunk for a given TLV type
+ * and returns a pointer to the first data byte of the TLV, or to NULL
+ * if the TLV hasn't been found.
+ */
+static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
+       struct mrvlietypesheader *tlv_h;
+       uint16_t length;
        ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_rssithreshold  *Lowrssi;
-               case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW):
-                       Lowrssi = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
-                                       Lowrssi->rssivalue,
-                                       Lowrssi->rssifreq,
-                                       (event->events & cpu_to_le16(0x0001))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
-                       break;
-               }
-       }
-
-       kfree(response_buf);
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
-}
-
-static u16 libertas_get_events_bitmap(wlan_private *priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res;
-       u16 event_bitmap;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               return res;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               return 0;
-       }
-
-       if (le16_to_cpu(pcmdptr->command) != CMD_RET(CMD_802_11_SUBSCRIBE_EVENT)) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               return 0;
-       }
-
-       event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN);
-       event_bitmap = le16_to_cpu(event->events);
-       kfree(response_buf);
-       return event_bitmap;
+       while (pos < size) {
+               tlv_h = (struct mrvlietypesheader *) tlv;
+               if (!tlv_h->len)
+                       return NULL;
+               if (tlv_h->type == cpu_to_le16(tlv_type))
+                       return tlv_h;
+               length = le16_to_cpu(tlv_h->len) + sizeof(*tlv_h);
+               pos += length;
+               tlv += length;
+       }
+       return NULL;
 }
 
-static ssize_t libertas_lowrssi_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
-{
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_rssithreshold *rssi_threshold;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-
-       event_bitmap = libertas_get_events_bitmap(priv);
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_rssithreshold));
-
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
-       rssi_threshold->header.type = cpu_to_le16(0x0104);
-       rssi_threshold->header.len = cpu_to_le16(2);
-       rssi_threshold->rssivalue = value;
-       rssi_threshold->rssifreq = freq;
-       event_bitmap |= subscribed ? 0x0001 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
-}
-
-static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
+                                 struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
-       ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
+       struct cmd_ds_802_11_subscribe_event *subscribed;
+       struct mrvlietypes_thresholds *got;
+       struct lbs_private *priv = file->private_data;
+       ssize_t ret = 0;
+       size_t pos = 0;
+       char *buf;
+       u8 value;
+       u8 freq;
+       int events = 0;
 
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
+       buf = (char *)get_zeroed_page(GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
+       subscribed = kzalloc(sizeof(*subscribed), GFP_KERNEL);
+       if (!subscribed) {
+               ret = -ENOMEM;
+               goto out_page;
        }
 
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_snrthreshold *LowSnr;
-               case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW):
-                       LowSnr = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
-                                       LowSnr->snrvalue,
-                                       LowSnr->snrfreq,
-                                       (event->events & cpu_to_le16(0x0002))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
-                       break;
-               }
-       }
+       subscribed->hdr.size = cpu_to_le16(sizeof(*subscribed));
+       subscribed->action = cpu_to_le16(CMD_ACT_GET);
 
-       kfree(response_buf);
+       ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, subscribed);
+       if (ret)
+               goto out_cmd;
 
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
-}
+       got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv));
+       if (got) {
+               value = got->value;
+               freq  = got->freq;
+               events = le16_to_cpu(subscribed->events);
 
-static ssize_t libertas_lowsnr_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
-{
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_snrthreshold *snr_threshold;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-
-       event_bitmap = libertas_get_events_bitmap(priv);
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_snrthreshold));
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
-       snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW);
-       snr_threshold->header.len = cpu_to_le16(2);
-       snr_threshold->snrvalue = value;
-       snr_threshold->snrfreq = freq;
-       event_bitmap |= subscribed ? 0x0002 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
+               pos += snprintf(buf, len, "%d %d %d\n", value, freq,
+                               !!(events & event_mask));
        }
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
+       ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 
-       res = count;
+ out_cmd:
+       kfree(subscribed);
 
-out_unlock:
-       free_page(addr);
-       return res;
+ out_page:
+       free_page((unsigned long)buf);
+       return ret;
 }
 
-static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf,
-                                 size_t count, loff_t *ppos)
-{
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
-       ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_failurecount *failcount;
-               case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT):
-                       failcount = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
-                                       failcount->failvalue,
-                                       failcount->Failfreq,
-                                       (event->events & cpu_to_le16(0x0004))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_failurecount);
-                       break;
-               }
-       }
-
-       kfree(response_buf);
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
-}
 
-static ssize_t libertas_failcount_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
+static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
+                                  struct file *file,
+                                  const char __user *userbuf, size_t count,
+                                  loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_failurecount *failcount;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
+       struct cmd_ds_802_11_subscribe_event *events;
+       struct mrvlietypes_thresholds *tlv;
+       struct lbs_private *priv = file->private_data;
+       ssize_t buf_size;
+       int value, freq, new_mask;
+       uint16_t curr_mask;
+       char *buf;
+       int ret;
+
+       buf = (char *)get_zeroed_page(GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
 
        buf_size = min(count, len - 1);
        if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
+               ret = -EFAULT;
+               goto out_page;
        }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
+       ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
+       if (ret != 3) {
+               ret = -EINVAL;
+               goto out_page;
        }
-
-       event_bitmap = libertas_get_events_bitmap(priv);
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_failurecount));
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       failcount = (struct mrvlietypes_failurecount *)(ptr);
-       failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT);
-       failcount->header.len = cpu_to_le16(2);
-       failcount->failvalue = value;
-       failcount->Failfreq = freq;
-       event_bitmap |= subscribed ? 0x0004 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = (struct cmd_ds_command *)response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
+       events = kzalloc(sizeof(*events), GFP_KERNEL);
+       if (!events) {
+               ret = -ENOMEM;
+               goto out_page;
        }
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
+       events->hdr.size = cpu_to_le16(sizeof(*events));
+       events->action = cpu_to_le16(CMD_ACT_GET);
 
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
-}
-
-static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf,
-                                 size_t count, loff_t *ppos)
-{
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
-       ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
+       ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
+       if (ret)
+               goto out_events;
 
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
+       curr_mask = le16_to_cpu(events->events);
 
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
+       if (new_mask)
+               new_mask = curr_mask | event_mask;
+       else
+               new_mask = curr_mask & ~event_mask;
 
-       pcmdptr = response_buf;
+       /* Now everything is set and we can send stuff down to the firmware */
 
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               free_page(addr);
-               kfree(response_buf);
-               return 0;
-       }
+       tlv = (void *)events->tlv;
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               free_page(addr);
-               kfree(response_buf);
-               return 0;
-       }
+       events->action = cpu_to_le16(CMD_ACT_SET);
+       events->events = cpu_to_le16(new_mask);
+       tlv->header.type = cpu_to_le16(tlv_type);
+       tlv->header.len = cpu_to_le16(sizeof(*tlv) - sizeof(tlv->header));
+       tlv->value = value;
+       if (tlv_type != TLV_TYPE_BCNMISS)
+               tlv->freq = freq;
 
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_beaconsmissed *bcnmiss;
-               case __constant_cpu_to_le16(TLV_TYPE_BCNMISS):
-                       bcnmiss = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d N/A %d\n",
-                                       bcnmiss->beaconmissed,
-                                       (event->events & cpu_to_le16(0x0008))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_beaconsmissed);
-                       break;
-               }
-       }
+       /* The command header, the event mask, and the one TLV */
+       events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv));
 
-       kfree(response_buf);
+       ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events);
 
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
+       if (!ret)
+               ret = count;
+ out_events:
+       kfree(events);
+ out_page:
+       free_page((unsigned long)buf);
+       return ret;
 }
 
-static ssize_t libertas_bcnmiss_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
+
+static ssize_t lbs_lowrssi_read(struct file *file, char __user *userbuf,
+                               size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_beaconsmissed *bcnmiss;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
+       return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
+                                 file, userbuf, count, ppos);
+}
 
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
 
-       event_bitmap = libertas_get_events_bitmap(priv);
+static ssize_t lbs_lowrssi_write(struct file *file, const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW,
+                                  file, userbuf, count, ppos);
+}
 
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
 
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_beaconsmissed));
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr);
-       bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS);
-       bcnmiss->header.len = cpu_to_le16(2);
-       bcnmiss->beaconmissed = value;
-       event_bitmap |= subscribed ? 0x0008 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
+static ssize_t lbs_lowsnr_read(struct file *file, char __user *userbuf,
+                              size_t count, loff_t *ppos)
+{
+       return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
+                                 file, userbuf, count, ppos);
+}
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               free_page(addr);
-               kfree(response_buf);
-               return 0;
-       }
 
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
+static ssize_t lbs_lowsnr_write(struct file *file, const char __user *userbuf,
+                               size_t count, loff_t *ppos)
+{
+       return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW,
+                                  file, userbuf, count, ppos);
 }
 
-static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf,
+
+static ssize_t lbs_failcount_read(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
-       ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_rssithreshold  *Highrssi;
-               case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH):
-                       Highrssi = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
-                                       Highrssi->rssivalue,
-                                       Highrssi->rssifreq,
-                                       (event->events & cpu_to_le16(0x0010))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
-                       break;
-               }
-       }
-
-       kfree(response_buf);
-
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
+       return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
+                                 file, userbuf, count, ppos);
 }
 
-static ssize_t libertas_highrssi_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
-{
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_rssithreshold *rssi_threshold;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
 
-       event_bitmap = libertas_get_events_bitmap(priv);
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_rssithreshold));
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr);
-       rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
-       rssi_threshold->header.len = cpu_to_le16(2);
-       rssi_threshold->rssivalue = value;
-       rssi_threshold->rssifreq = freq;
-       event_bitmap |= subscribed ? 0x0010 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               return 0;
-       }
+static ssize_t lbs_failcount_write(struct file *file, const char __user *userbuf,
+                                  size_t count, loff_t *ppos)
+{
+       return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT,
+                                  file, userbuf, count, ppos);
+}
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               return 0;
-       }
 
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
+static ssize_t lbs_highrssi_read(struct file *file, char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
+                                 file, userbuf, count, ppos);
 }
 
-static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf,
+
+static ssize_t lbs_highrssi_write(struct file *file, const char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       void *response_buf;
-       int res, cmd_len;
-       ssize_t pos = 0;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0) {
-               free_page(addr);
-               return res;
-       }
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_GET);
-       pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN);
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
+       return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH,
+                                  file, userbuf, count, ppos);
+}
 
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
-
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       event = (void *)(response_buf + S_DS_GEN);
-       while (cmd_len < le16_to_cpu(pcmdptr->size)) {
-               struct mrvlietypesheader *header = (void *)(response_buf + cmd_len);
-               switch (header->type) {
-               struct mrvlietypes_snrthreshold *HighSnr;
-               case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH):
-                       HighSnr = (void *)(response_buf + cmd_len);
-                       pos += snprintf(buf+pos, len-pos, "%d %d %d\n",
-                                       HighSnr->snrvalue,
-                                       HighSnr->snrfreq,
-                                       (event->events & cpu_to_le16(0x0020))?1:0);
-               default:
-                       cmd_len += sizeof(struct mrvlietypes_snrthreshold);
-                       break;
-               }
-       }
+static ssize_t lbs_highsnr_read(struct file *file, char __user *userbuf,
+                               size_t count, loff_t *ppos)
+{
+       return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
+                                 file, userbuf, count, ppos);
+}
 
-       kfree(response_buf);
 
-       res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
-       free_page(addr);
-       return res;
+static ssize_t lbs_highsnr_write(struct file *file, const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH,
+                                  file, userbuf, count, ppos);
 }
 
-static ssize_t libertas_highsnr_write(struct file *file,
-                                   const char __user *userbuf,
-                                   size_t count, loff_t *ppos)
+static ssize_t lbs_bcnmiss_read(struct file *file, char __user *userbuf,
+                               size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       ssize_t res, buf_size;
-       int value, freq, subscribed, cmd_len;
-       struct cmd_ctrl_node *pcmdnode;
-       struct cmd_ds_command *pcmdptr;
-       struct cmd_ds_802_11_subscribe_event *event;
-       struct mrvlietypes_snrthreshold *snr_threshold;
-       void *response_buf;
-       u16 event_bitmap;
-       u8 *ptr;
-       unsigned long addr = get_zeroed_page(GFP_KERNEL);
-       char *buf = (char *)addr;
-
-       buf_size = min(count, len - 1);
-       if (copy_from_user(buf, userbuf, buf_size)) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
-       res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed);
-       if (res != 3) {
-               res = -EFAULT;
-               goto out_unlock;
-       }
+       return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
+                                 file, userbuf, count, ppos);
+}
 
-       event_bitmap = libertas_get_events_bitmap(priv);
 
-       res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr);
-       if (res < 0)
-               goto out_unlock;
-
-       event = &pcmdptr->params.subscribe_event;
-       event->action = cpu_to_le16(CMD_ACT_SET);
-       pcmdptr->size = cpu_to_le16(S_DS_GEN +
-               sizeof(struct cmd_ds_802_11_subscribe_event) +
-               sizeof(struct mrvlietypes_snrthreshold));
-       cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event);
-       ptr = (u8*) pcmdptr+cmd_len;
-       snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr);
-       snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH);
-       snr_threshold->header.len = cpu_to_le16(2);
-       snr_threshold->snrvalue = value;
-       snr_threshold->snrfreq = freq;
-       event_bitmap |= subscribed ? 0x0020 : 0x0;
-       event->events = cpu_to_le16(event_bitmap);
-
-       libertas_queue_cmd(adapter, pcmdnode, 1);
-       wake_up_interruptible(&priv->waitq);
-
-       /* Sleep until response is generated by FW */
-       wait_event_interruptible(pcmdnode->cmdwait_q,
-                                pcmdnode->cmdwaitqwoken);
-
-       pcmdptr = response_buf;
-
-       if (pcmdptr->result) {
-               lbs_pr_err("%s: fail, result=%d\n", __func__,
-                          le16_to_cpu(pcmdptr->result));
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
+static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS,
+                                  file, userbuf, count, ppos);
+}
 
-       if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) {
-               lbs_pr_err("command response incorrect!\n");
-               kfree(response_buf);
-               free_page(addr);
-               return 0;
-       }
 
-       res = count;
-out_unlock:
-       free_page(addr);
-       return res;
-}
 
-static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_offset_value offval;
+       struct lbs_private *priv = file->private_data;
+       struct lbs_offset_value offval;
        ssize_t pos = 0;
        int ret;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
@@ -1375,23 +603,23 @@ static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf,
        offval.offset = priv->mac_offset;
        offval.value = 0;
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                CMD_MAC_REG_ACCESS, 0,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
        pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
-                               priv->mac_offset, adapter->offsetvalue.value);
+                               priv->mac_offset, priv->offsetvalue.value);
 
        ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        free_page(addr);
        return ret;
 }
 
-static ssize_t libertas_rdmac_write(struct file *file,
+static ssize_t lbs_rdmac_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
@@ -1408,15 +636,15 @@ out_unlock:
        return res;
 }
 
-static ssize_t libertas_wrmac_write(struct file *file,
+static ssize_t lbs_wrmac_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
 
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        u32 offset, value;
-       struct wlan_offset_value offval;
+       struct lbs_offset_value offval;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
 
@@ -1433,7 +661,7 @@ static ssize_t libertas_wrmac_write(struct file *file,
 
        offval.offset = offset;
        offval.value = value;
-       res = libertas_prepare_and_send_command(priv,
+       res = lbs_prepare_and_send_command(priv,
                                CMD_MAC_REG_ACCESS, 1,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
@@ -1444,12 +672,11 @@ out_unlock:
        return res;
 }
 
-static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_offset_value offval;
+       struct lbs_private *priv = file->private_data;
+       struct lbs_offset_value offval;
        ssize_t pos = 0;
        int ret;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
@@ -1458,12 +685,12 @@ static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
        offval.offset = priv->bbp_offset;
        offval.value = 0;
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                CMD_BBP_REG_ACCESS, 0,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
        pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
-                               priv->bbp_offset, adapter->offsetvalue.value);
+                               priv->bbp_offset, priv->offsetvalue.value);
 
        ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        free_page(addr);
@@ -1471,11 +698,11 @@ static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf,
        return ret;
 }
 
-static ssize_t libertas_rdbbp_write(struct file *file,
+static ssize_t lbs_rdbbp_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
@@ -1492,15 +719,15 @@ out_unlock:
        return res;
 }
 
-static ssize_t libertas_wrbbp_write(struct file *file,
+static ssize_t lbs_wrbbp_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
 
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        u32 offset, value;
-       struct wlan_offset_value offval;
+       struct lbs_offset_value offval;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
 
@@ -1517,7 +744,7 @@ static ssize_t libertas_wrbbp_write(struct file *file,
 
        offval.offset = offset;
        offval.value = value;
-       res = libertas_prepare_and_send_command(priv,
+       res = lbs_prepare_and_send_command(priv,
                                CMD_BBP_REG_ACCESS, 1,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
@@ -1528,12 +755,11 @@ out_unlock:
        return res;
 }
 
-static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
                                  size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_offset_value offval;
+       struct lbs_private *priv = file->private_data;
+       struct lbs_offset_value offval;
        ssize_t pos = 0;
        int ret;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
@@ -1542,12 +768,12 @@ static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
        offval.offset = priv->rf_offset;
        offval.value = 0;
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                CMD_RF_REG_ACCESS, 0,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
        pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
-                               priv->rf_offset, adapter->offsetvalue.value);
+                               priv->rf_offset, priv->offsetvalue.value);
 
        ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
        free_page(addr);
@@ -1555,11 +781,11 @@ static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf,
        return ret;
 }
 
-static ssize_t libertas_rdrf_write(struct file *file,
+static ssize_t lbs_rdrf_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
@@ -1576,15 +802,15 @@ out_unlock:
        return res;
 }
 
-static ssize_t libertas_wrrf_write(struct file *file,
+static ssize_t lbs_wrrf_write(struct file *file,
                                    const char __user *userbuf,
                                    size_t count, loff_t *ppos)
 {
 
-       wlan_private *priv = file->private_data;
+       struct lbs_private *priv = file->private_data;
        ssize_t res, buf_size;
        u32 offset, value;
-       struct wlan_offset_value offval;
+       struct lbs_offset_value offval;
        unsigned long addr = get_zeroed_page(GFP_KERNEL);
        char *buf = (char *)addr;
 
@@ -1601,7 +827,7 @@ static ssize_t libertas_wrrf_write(struct file *file,
 
        offval.offset = offset;
        offval.value = value;
-       res = libertas_prepare_and_send_command(priv,
+       res = lbs_prepare_and_send_command(priv,
                                CMD_RF_REG_ACCESS, 1,
                                CMD_OPTION_WAITFORRSP, 0, &offval);
        mdelay(10);
@@ -1619,69 +845,69 @@ out_unlock:
        .write = (fwrite), \
 }
 
-struct libertas_debugfs_files {
+struct lbs_debugfs_files {
        char *name;
        int perm;
        struct file_operations fops;
 };
 
-static struct libertas_debugfs_files debugfs_files[] = {
-       { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
-       { "getscantable", 0444, FOPS(libertas_getscantable,
+static struct lbs_debugfs_files debugfs_files[] = {
+       { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), },
+       { "getscantable", 0444, FOPS(lbs_getscantable,
                                        write_file_dummy), },
-       { "sleepparams", 0644, FOPS(libertas_sleepparams_read,
-                               libertas_sleepparams_write), },
-       { "extscan", 0600, FOPS(NULL, libertas_extscan), },
-       { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
+       { "sleepparams", 0644, FOPS(lbs_sleepparams_read,
+                               lbs_sleepparams_write), },
+       { "extscan", 0600, FOPS(NULL, lbs_extscan), },
+       { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), },
 };
 
-static struct libertas_debugfs_files debugfs_events_files[] = {
-       {"low_rssi", 0644, FOPS(libertas_lowrssi_read,
-                               libertas_lowrssi_write), },
-       {"low_snr", 0644, FOPS(libertas_lowsnr_read,
-                               libertas_lowsnr_write), },
-       {"failure_count", 0644, FOPS(libertas_failcount_read,
-                               libertas_failcount_write), },
-       {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read,
-                               libertas_bcnmiss_write), },
-       {"high_rssi", 0644, FOPS(libertas_highrssi_read,
-                               libertas_highrssi_write), },
-       {"high_snr", 0644, FOPS(libertas_highsnr_read,
-                               libertas_highsnr_write), },
+static struct lbs_debugfs_files debugfs_events_files[] = {
+       {"low_rssi", 0644, FOPS(lbs_lowrssi_read,
+                               lbs_lowrssi_write), },
+       {"low_snr", 0644, FOPS(lbs_lowsnr_read,
+                               lbs_lowsnr_write), },
+       {"failure_count", 0644, FOPS(lbs_failcount_read,
+                               lbs_failcount_write), },
+       {"beacon_missed", 0644, FOPS(lbs_bcnmiss_read,
+                               lbs_bcnmiss_write), },
+       {"high_rssi", 0644, FOPS(lbs_highrssi_read,
+                               lbs_highrssi_write), },
+       {"high_snr", 0644, FOPS(lbs_highsnr_read,
+                               lbs_highsnr_write), },
 };
 
-static struct libertas_debugfs_files debugfs_regs_files[] = {
-       {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
-       {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
-       {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
-       {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), },
-       {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), },
-       {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), },
+static struct lbs_debugfs_files debugfs_regs_files[] = {
+       {"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), },
+       {"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), },
+       {"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), },
+       {"wrbbp", 0600, FOPS(NULL, lbs_wrbbp_write), },
+       {"rdrf", 0644, FOPS(lbs_rdrf_read, lbs_rdrf_write), },
+       {"wrrf", 0600, FOPS(NULL, lbs_wrrf_write), },
 };
 
-void libertas_debugfs_init(void)
+void lbs_debugfs_init(void)
 {
-       if (!libertas_dir)
-               libertas_dir = debugfs_create_dir("libertas_wireless", NULL);
+       if (!lbs_dir)
+               lbs_dir = debugfs_create_dir("lbs_wireless", NULL);
 
        return;
 }
 
-void libertas_debugfs_remove(void)
+void lbs_debugfs_remove(void)
 {
-       if (libertas_dir)
-                debugfs_remove(libertas_dir);
+       if (lbs_dir)
+                debugfs_remove(lbs_dir);
        return;
 }
 
-void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
+void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
 {
        int i;
-       struct libertas_debugfs_files *files;
-       if (!libertas_dir)
+       struct lbs_debugfs_files *files;
+       if (!lbs_dir)
                goto exit;
 
-       priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir);
+       priv->debugfs_dir = debugfs_create_dir(dev->name, lbs_dir);
        if (!priv->debugfs_dir)
                goto exit;
 
@@ -1721,13 +947,13 @@ void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev)
        }
 
 #ifdef PROC_DEBUG
-       libertas_debug_init(priv, dev);
+       lbs_debug_init(priv, dev);
 #endif
 exit:
        return;
 }
 
-void libertas_debugfs_remove_one(wlan_private *priv)
+void lbs_debugfs_remove_one(struct lbs_private *priv)
 {
        int i;
 
@@ -1754,8 +980,8 @@ void libertas_debugfs_remove_one(wlan_private *priv)
 
 #ifdef PROC_DEBUG
 
-#define item_size(n)   (FIELD_SIZEOF(wlan_adapter, n))
-#define item_addr(n)   (offsetof(wlan_adapter, n))
+#define item_size(n)   (FIELD_SIZEOF(struct lbs_private, n))
+#define item_addr(n)   (offsetof(struct lbs_private, n))
 
 
 struct debug_data {
@@ -1764,7 +990,7 @@ struct debug_data {
        size_t addr;
 };
 
-/* To debug any member of wlan_adapter, simply add one line here.
+/* To debug any member of struct lbs_private, simply add one line here.
  */
 static struct debug_data items[] = {
        {"intcounter", item_size(intcounter), item_addr(intcounter)},
@@ -1785,7 +1011,7 @@ static int num_of_items = ARRAY_SIZE(items);
  *  @param data    data to output
  *  @return       number of output data
  */
-static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
+static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
                        size_t count, loff_t *ppos)
 {
        int val = 0;
@@ -1829,7 +1055,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
  *  @param data    data to write
  *  @return       number of data
  */
-static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
+static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
                            size_t cnt, loff_t *ppos)
 {
        int r, i;
@@ -1881,21 +1107,21 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
        return (ssize_t)cnt;
 }
 
-static struct file_operations libertas_debug_fops = {
+static struct file_operations lbs_debug_fops = {
        .owner = THIS_MODULE,
        .open = open_file_generic,
-       .write = wlan_debugfs_write,
-       .read = wlan_debugfs_read,
+       .write = lbs_debugfs_write,
+       .read = lbs_debugfs_read,
 };
 
 /**
  *  @brief create debug proc file
  *
- *  @param priv           pointer wlan_private
+ *  @param priv           pointer struct lbs_private
  *  @param dev     pointer net_device
  *  @return       N/A
  */
-static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
+static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev)
 {
        int i;
 
@@ -1903,11 +1129,10 @@ static void libertas_debug_init(wlan_private * priv, struct net_device *dev)
                return;
 
        for (i = 0; i < num_of_items; i++)
-               items[i].addr += (size_t) priv->adapter;
+               items[i].addr += (size_t) priv;
 
        priv->debugfs_debug = debugfs_create_file("debug", 0644,
                                                  priv->debugfs_dir, &items[0],
-                                                 &libertas_debug_fops);
+                                                 &lbs_debug_fops);
 }
 #endif
-
index 880a11b95d26c4f06ea04cfaa6b0f881e3c5766e..f2b9c7ffe0fd28d5dc6bee79dd1838d38b97280e 100644 (file)
@@ -1,6 +1,10 @@
-void libertas_debugfs_init(void);
-void libertas_debugfs_remove(void);
+#ifndef _LBS_DEBUGFS_H_
+#define _LBS_DEBUGFS_H_
 
-void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev);
-void libertas_debugfs_remove_one(wlan_private *priv);
+void lbs_debugfs_init(void);
+void lbs_debugfs_remove(void);
 
+void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev);
+void lbs_debugfs_remove_one(struct lbs_private *priv);
+
+#endif
index 87fea9d5b90a7394e4aba2c7e01347e64adb6238..aaacd9bd6bd2bf82d5d604488e04aa44c2b4f2a3 100644 (file)
@@ -3,80 +3,74 @@
   *  functions defined in other source files
   */
 
-#ifndef _WLAN_DECL_H_
-#define _WLAN_DECL_H_
+#ifndef _LBS_DECL_H_
+#define _LBS_DECL_H_
 
 #include <linux/device.h>
 
 #include "defs.h"
 
 /** Function Prototype Declaration */
-struct wlan_private;
+struct lbs_private;
 struct sk_buff;
 struct net_device;
-
-int libertas_set_mac_packet_filter(wlan_private * priv);
-
-void libertas_send_tx_feedback(wlan_private * priv);
-
-int libertas_free_cmd_buffer(wlan_private * priv);
 struct cmd_ctrl_node;
-struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv);
+struct cmd_ds_command;
 
-void libertas_set_cmd_ctrl_node(wlan_private * priv,
-                   struct cmd_ctrl_node *ptempnode,
-                   u32 cmd_oid, u16 wait_option, void *pdata_buf);
+int lbs_set_mac_packet_filter(struct lbs_private *priv);
 
-int libertas_prepare_and_send_command(wlan_private * priv,
-                         u16 cmd_no,
-                         u16 cmd_action,
-                         u16 wait_option, u32 cmd_oid, void *pdata_buf);
+void lbs_send_tx_feedback(struct lbs_private *priv);
 
-void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail);
+int lbs_free_cmd_buffer(struct lbs_private *priv);
 
-int libertas_allocate_cmd_buffer(wlan_private * priv);
-int libertas_execute_next_command(wlan_private * priv);
-int libertas_process_event(wlan_private * priv);
-void libertas_interrupt(struct net_device *);
-int libertas_set_radio_control(wlan_private * priv);
-u32 libertas_fw_index_to_data_rate(u8 index);
-u8 libertas_data_rate_to_fw_index(u32 rate);
-void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen);
+int lbs_prepare_and_send_command(struct lbs_private *priv,
+       u16 cmd_no,
+       u16 cmd_action,
+       u16 wait_option, u32 cmd_oid, void *pdata_buf);
 
-void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb);
+int lbs_allocate_cmd_buffer(struct lbs_private *priv);
+int lbs_execute_next_command(struct lbs_private *priv);
+int lbs_process_event(struct lbs_private *priv);
+void lbs_interrupt(struct lbs_private *priv);
+int lbs_set_radio_control(struct lbs_private *priv);
+u32 lbs_fw_index_to_data_rate(u8 index);
+u8 lbs_data_rate_to_fw_index(u32 rate);
+void lbs_get_fwversion(struct lbs_private *priv,
+       char *fwversion,
+       int maxlen);
 
 /** The proc fs interface */
-int libertas_process_rx_command(wlan_private * priv);
-int libertas_process_tx(wlan_private * priv, struct sk_buff *skb);
-void __libertas_cleanup_and_insert_cmd(wlan_private * priv,
-                                       struct cmd_ctrl_node *ptempcmd);
-
-int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band);
-
-int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *);
+int lbs_process_rx_command(struct lbs_private *priv);
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+                         int result);
+int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
+int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
 
-void libertas_ps_sleep(wlan_private * priv, int wait_option);
-void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode);
-void libertas_ps_wakeup(wlan_private * priv, int wait_option);
+int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
 
-void libertas_tx_runqueue(wlan_private *priv);
+void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
+void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode);
+void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
 
-struct chan_freq_power *libertas_find_cfp_by_band_and_channel(
-                               wlan_adapter * adapter, u8 band, u16 channel);
+struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
+       struct lbs_private *priv,
+       u8 band,
+       u16 channel);
 
-void libertas_mac_event_disconnected(wlan_private * priv);
+void lbs_mac_event_disconnected(struct lbs_private *priv);
 
-void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
+void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str);
 
 /* main.c */
-struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
-                                                            int *cfp_no);
-wlan_private *libertas_add_card(void *card, struct device *dmdev);
-int libertas_remove_card(wlan_private *priv);
-int libertas_start_card(wlan_private *priv);
-int libertas_stop_card(wlan_private *priv);
-int libertas_add_mesh(wlan_private *priv, struct device *dev);
-void libertas_remove_mesh(wlan_private *priv);
-int libertas_reset_device(wlan_private *priv);
-
-#endif                         /* _WLAN_DECL_H_ */
+struct chan_freq_power *lbs_get_region_cfp_table(u8 region,
+       u8 band,
+       int *cfp_no);
+struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
+int lbs_remove_card(struct lbs_private *priv);
+int lbs_start_card(struct lbs_private *priv);
+int lbs_stop_card(struct lbs_private *priv);
+int lbs_reset_device(struct lbs_private *priv);
+void lbs_host_to_card_done(struct lbs_private *priv);
+
+int lbs_update_channel(struct lbs_private *priv);
+#endif
index 3a0c9beefcf8a0260092e03304a3243fe5da9e77..3053cc2160bcecbee8c42e979901c5444f856396 100644 (file)
@@ -2,8 +2,8 @@
   * This header file contains global constant/enum definitions,
   * global variable declaration.
   */
-#ifndef _WLAN_DEFS_H_
-#define _WLAN_DEFS_H_
+#ifndef _LBS_DEFS_H_
+#define _LBS_DEFS_H_
 
 #include <linux/spinlock.h>
 
 #define LBS_DEB_HEX    0x00200000
 #define LBS_DEB_SDIO   0x00400000
 
-extern unsigned int libertas_debug;
+extern unsigned int lbs_debug;
 
 #ifdef DEBUG
 #define LBS_DEB_LL(grp, grpnam, fmt, args...) \
-do { if ((libertas_debug & (grp)) == (grp)) \
+do { if ((lbs_debug & (grp)) == (grp)) \
   printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \
          in_interrupt() ? " (INT)" : "", ## args); } while (0)
 #else
@@ -96,8 +96,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
        int i = 0;
 
        if (len &&
-           (libertas_debug & LBS_DEB_HEX) &&
-           (libertas_debug & grp))
+           (lbs_debug & LBS_DEB_HEX) &&
+           (lbs_debug & grp))
        {
                for (i = 1; i <= len; i++) {
                        if ((i & 0xf) == 1) {
@@ -132,15 +132,22 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 */
 
 #define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
-#define MRVDRV_NUM_OF_CMD_BUFFER        10
-#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+#define LBS_NUM_CMD_BUFFERS             10
+#define LBS_CMD_BUFFER_SIZE             (2 * 1024)
 #define MRVDRV_MAX_CHANNEL_SIZE                14
 #define MRVDRV_ASSOCIATION_TIME_OUT    255
 #define MRVDRV_SNAP_HEADER_LEN          8
 
-#define        WLAN_UPLD_SIZE                  2312
+#define        LBS_UPLD_SIZE                   2312
 #define DEV_NAME_LEN                   32
 
+/* Wake criteria for HOST_SLEEP_CFG command */
+#define EHS_WAKE_ON_BROADCAST_DATA     0x0001
+#define EHS_WAKE_ON_UNICAST_DATA       0x0002
+#define EHS_WAKE_ON_MAC_EVENT          0x0004
+#define EHS_WAKE_ON_MULTICAST_DATA     0x0008
+#define EHS_REMOVE_WAKEUP              0xFFFFFFFF
+
 /** Misc constants */
 /* This section defines 802.11 specific contants */
 
@@ -257,17 +264,11 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 
 #define        MAX_LEDS                        8
 
-#define IS_MESH_FRAME(x) (x->cb[6])
-#define SET_MESH_FRAME(x) (x->cb[6]=1)
-#define UNSET_MESH_FRAME(x) (x->cb[6]=0)
-
 /** Global Variable Declaration */
-typedef struct _wlan_private wlan_private;
-typedef struct _wlan_adapter wlan_adapter;
-extern const char libertas_driver_version[];
-extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE];
+extern const char lbs_driver_version[];
+extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
 
-extern u8 libertas_bg_rates[MAX_RATES];
+extern u8 lbs_bg_rates[MAX_RATES];
 
 /** ENUM definition*/
 /** SNRNF_TYPE */
@@ -284,13 +285,13 @@ enum SNRNF_DATA {
        MAX_TYPE_AVG
 };
 
-/** WLAN_802_11_POWER_MODE */
-enum WLAN_802_11_POWER_MODE {
-       WLAN802_11POWERMODECAM,
-       WLAN802_11POWERMODEMAX_PSP,
-       WLAN802_11POWERMODEFAST_PSP,
+/** LBS_802_11_POWER_MODE */
+enum LBS_802_11_POWER_MODE {
+       LBS802_11POWERMODECAM,
+       LBS802_11POWERMODEMAX_PSP,
+       LBS802_11POWERMODEFAST_PSP,
        /*not a real mode, defined as an upper bound */
-       WLAN802_11POWEMODEMAX
+       LBS802_11POWEMODEMAX
 };
 
 /** PS_STATE */
@@ -308,16 +309,16 @@ enum DNLD_STATE {
        DNLD_CMD_SENT
 };
 
-/** WLAN_MEDIA_STATE */
-enum WLAN_MEDIA_STATE {
-       LIBERTAS_CONNECTED,
-       LIBERTAS_DISCONNECTED
+/** LBS_MEDIA_STATE */
+enum LBS_MEDIA_STATE {
+       LBS_CONNECTED,
+       LBS_DISCONNECTED
 };
 
-/** WLAN_802_11_PRIVACY_FILTER */
-enum WLAN_802_11_PRIVACY_FILTER {
-       WLAN802_11PRIVFILTERACCEPTALL,
-       WLAN802_11PRIVFILTER8021XWEP
+/** LBS_802_11_PRIVACY_FILTER */
+enum LBS_802_11_PRIVACY_FILTER {
+       LBS802_11PRIVFILTERACCEPTALL,
+       LBS802_11PRIVFILTER8021XWEP
 };
 
 /** mv_ms_type */
@@ -382,4 +383,4 @@ enum SNMP_MIB_VALUE_e {
 #define FWT_DEFAULT_SLEEPMODE 0
 #define FWT_DEFAULT_SNR 0
 
-#endif                         /* _WLAN_DEFS_H_ */
+#endif
index 1fb807aa91b96ec84e9742777360bb5681776991..58d7ef6b5ff5b127591c65bd9d60ffb731c87e9d 100644 (file)
@@ -1,21 +1,20 @@
 /**
   * This file contains definitions and data structures specific
   * to Marvell 802.11 NIC. It contains the Device Information
-  * structure wlan_adapter.
+  * structure struct lbs_private..
   */
-#ifndef _WLAN_DEV_H_
-#define _WLAN_DEV_H_
+#ifndef _LBS_DEV_H_
+#define _LBS_DEV_H_
 
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
-#include <net/ieee80211.h>
 
 #include "defs.h"
 #include "scan.h"
 
-extern struct ethtool_ops libertas_ethtool_ops;
+extern struct ethtool_ops lbs_ethtool_ops;
 
 #define        MAX_BSSID_PER_CHANNEL           16
 
@@ -53,7 +52,7 @@ struct region_channel {
        struct chan_freq_power *CFP;
 };
 
-struct wlan_802_11_security {
+struct lbs_802_11_security {
        u8 WPAenabled;
        u8 WPA2enabled;
        u8 wep_enabled;
@@ -78,16 +77,16 @@ struct current_bss_params {
 
 /** sleep_params */
 struct sleep_params {
-       u16 sp_error;
-       u16 sp_offset;
-       u16 sp_stabletime;
-       u8 sp_calcontrol;
-       u8 sp_extsleepclk;
-       u16 sp_reserved;
+       uint16_t sp_error;
+       uint16_t sp_offset;
+       uint16_t sp_stabletime;
+       uint8_t  sp_calcontrol;
+       uint8_t  sp_extsleepclk;
+       uint16_t sp_reserved;
 };
 
 /* Mesh statistics */
-struct wlan_mesh_stats {
+struct lbs_mesh_stats {
        u32     fwd_bcast_cnt;          /* Fwd: Broadcast counter */
        u32     fwd_unicast_cnt;        /* Fwd: Unicast counter */
        u32     fwd_drop_ttl;           /* Fwd: TTL zero */
@@ -99,26 +98,22 @@ struct wlan_mesh_stats {
 };
 
 /** Private structure for the MV device */
-struct _wlan_private {
-       int open;
+struct lbs_private {
        int mesh_open;
        int infra_open;
        int mesh_autostart_enabled;
-       __le16 boot2_version;
 
        char name[DEV_NAME_LEN];
 
        void *card;
-       wlan_adapter *adapter;
        struct net_device *dev;
 
        struct net_device_stats stats;
        struct net_device *mesh_dev; /* Virtual device */
        struct net_device *rtap_net_dev;
-       struct ieee80211_device *ieee;
 
        struct iw_statistics wstats;
-       struct wlan_mesh_stats mstats;
+       struct lbs_mesh_stats mstats;
        struct dentry *debugfs_dir;
        struct dentry *debugfs_debug;
        struct dentry *debugfs_files[6];
@@ -136,15 +131,13 @@ struct _wlan_private {
        /** Upload length */
        u32 upld_len;
        /* Upload buffer */
-       u8 upld_buf[WLAN_UPLD_SIZE];
+       u8 upld_buf[LBS_UPLD_SIZE];
        /* Download sent:
           bit0 1/0=data_sent/data_tx_done,
           bit1 1/0=cmd_sent/cmd_tx_done,
           all other bits reserved 0 */
        u8 dnld_sent;
 
-       struct device *hotplug_device;
-
        /** thread to service interrupts */
        struct task_struct *main_thread;
        wait_queue_head_t waitq;
@@ -155,65 +148,29 @@ struct _wlan_private {
        struct work_struct sync_channel;
 
        /** Hardware access */
-       int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
-       int (*hw_get_int_status) (wlan_private * priv, u8 *);
-       int (*hw_read_event_cause) (wlan_private *);
-};
+       int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb);
+       int (*hw_get_int_status) (struct lbs_private *priv, u8 *);
+       int (*hw_read_event_cause) (struct lbs_private *);
 
-/** Association request
- *
- * Encapsulates all the options that describe a specific assocation request
- * or configuration of the wireless card's radio, mode, and security settings.
- */
-struct assoc_request {
-#define ASSOC_FLAG_SSID                        1
-#define ASSOC_FLAG_CHANNEL             2
-#define ASSOC_FLAG_BAND                        3
-#define ASSOC_FLAG_MODE                        4
-#define ASSOC_FLAG_BSSID               5
-#define ASSOC_FLAG_WEP_KEYS            6
-#define ASSOC_FLAG_WEP_TX_KEYIDX       7
-#define ASSOC_FLAG_WPA_MCAST_KEY       8
-#define ASSOC_FLAG_WPA_UCAST_KEY       9
-#define ASSOC_FLAG_SECINFO             10
-#define ASSOC_FLAG_WPA_IE              11
-       unsigned long flags;
+       /* Wake On LAN */
+       uint32_t wol_criteria;
+       uint8_t wol_gpio;
+       uint8_t wol_gap;
 
-       u8 ssid[IW_ESSID_MAX_SIZE + 1];
-       u8 ssid_len;
-       u8 channel;
-       u8 band;
-       u8 mode;
-       u8 bssid[ETH_ALEN];
-
-       /** WEP keys */
-       struct enc_key wep_keys[4];
-       u16 wep_tx_keyidx;
-
-       /** WPA keys */
-       struct enc_key wpa_mcast_key;
-       struct enc_key wpa_unicast_key;
+       /* was struct lbs_adapter from here... */
 
-       struct wlan_802_11_security secinfo;
-
-       /** WPA Information Elements*/
-       u8 wpa_ie[MAX_WPA_IE_LEN];
-       u8 wpa_ie_len;
-
-       /* BSS to associate with for infrastructure of Ad-Hoc join */
-       struct bss_descriptor bss;
-};
-
-/** Wlan adapter data structure*/
-struct _wlan_adapter {
+       /** Wlan adapter data structure*/
        /** STATUS variables */
-       u8 fwreleasenumber[4];
+       u32 fwrelease;
        u32 fwcapinfo;
        /* protected with big lock */
 
        struct mutex lock;
 
-       u8 tmptxbuf[WLAN_UPLD_SIZE];
+       /* TX packet ready to be sent... */
+       int tx_pending_len;             /* -1 while building packet */
+
+       u8 tx_pending_buf[LBS_UPLD_SIZE];
        /* protected by hard_start_xmit serialization */
 
        /** command-related variables */
@@ -231,8 +188,7 @@ struct _wlan_adapter {
        struct list_head cmdpendingq;
 
        wait_queue_head_t cmd_pending;
-       u8 nr_cmd_pending;
-       /* command related variables protected by adapter->driver_lock */
+       /* command related variables protected by priv->driver_lock */
 
        /** Async and Sync Event variables */
        u32 intcounter;
@@ -244,17 +200,18 @@ struct _wlan_adapter {
 
        /** Timers */
        struct timer_list command_timer;
-
-       /* TX queue used in PS mode */
-       spinlock_t txqueue_lock;
-       struct sk_buff *tx_queue_ps[NR_TX_QUEUE];
-       unsigned int tx_queue_idx;
+       int nr_retries;
+       int cmd_timed_out;
 
        u8 hisregcpy;
 
        /** current ssid/bssid related parameters*/
        struct current_bss_params curbssparams;
 
+       uint16_t mesh_tlv;
+       u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
+       u8 mesh_ssid_len;
+
        /* IW_MODE_* */
        u8 mode;
 
@@ -263,6 +220,8 @@ struct _wlan_adapter {
        struct list_head network_free_list;
        struct bss_descriptor *networks;
 
+       u16 beacon_period;
+       u8 beacon_enable;
        u8 adhoccreate;
 
        /** capability Info used in Association, start, join */
@@ -286,11 +245,11 @@ struct _wlan_adapter {
 
        /** Tx-related variables (for single packet tx) */
        struct sk_buff *currenttxskb;
-       u16 TxLockFlag;
 
        /** NIC Operation characteristics */
        u16 currentpacketfilter;
        u32 connect_status;
+       u32 mesh_connect_status;
        u16 regioncode;
        u16 txpowerlevel;
 
@@ -300,15 +259,17 @@ struct _wlan_adapter {
        u16 psmode;             /* Wlan802_11PowermodeCAM=disable
                                   Wlan802_11PowermodeMAX_PSP=enable */
        u32 psstate;
+       char ps_supported;
        u8 needtowakeup;
 
-       struct PS_CMD_ConfirmSleep libertas_ps_confirm_sleep;
+       struct PS_CMD_ConfirmSleep lbs_ps_confirm_sleep;
+       struct cmd_header lbs_ps_confirm_wake;
 
        struct assoc_request * pending_assoc_req;
        struct assoc_request * in_progress_assoc_req;
 
        /** Encryption parameter */
-       struct wlan_802_11_security secinfo;
+       struct lbs_802_11_security secinfo;
 
        /** WEP keys */
        struct enc_key wep_keys[4];
@@ -338,9 +299,6 @@ struct _wlan_adapter {
        u8 cur_rate;
        u8 auto_rate;
 
-       /** sleep_params */
-       struct sleep_params sp;
-
        /** RF calibration data */
 
 #define        MAX_REGION_CHANNEL_NUM  2
@@ -350,7 +308,7 @@ struct _wlan_adapter {
        struct region_channel universal_channel[MAX_REGION_CHANNEL_NUM];
 
        /** 11D and Domain Regulatory Data */
-       struct wlan_802_11d_domain_reg domainreg;
+       struct lbs_802_11d_domain_reg domainreg;
        struct parsed_region_chan_11d parsed_region_chan;
 
        /** FSM variable for 11d support */
@@ -358,14 +316,57 @@ struct _wlan_adapter {
 
        /**     MISCELLANEOUS */
        u8 *prdeeprom;
-       struct wlan_offset_value offsetvalue;
+       struct lbs_offset_value offsetvalue;
 
        struct cmd_ds_802_11_get_log logmsg;
 
        u32 monitormode;
+       int last_scanned_channel;
        u8 fw_ready;
+};
+
+/** Association request
+ *
+ * Encapsulates all the options that describe a specific assocation request
+ * or configuration of the wireless card's radio, mode, and security settings.
+ */
+struct assoc_request {
+#define ASSOC_FLAG_SSID                        1
+#define ASSOC_FLAG_CHANNEL             2
+#define ASSOC_FLAG_BAND                        3
+#define ASSOC_FLAG_MODE                        4
+#define ASSOC_FLAG_BSSID               5
+#define ASSOC_FLAG_WEP_KEYS            6
+#define ASSOC_FLAG_WEP_TX_KEYIDX       7
+#define ASSOC_FLAG_WPA_MCAST_KEY       8
+#define ASSOC_FLAG_WPA_UCAST_KEY       9
+#define ASSOC_FLAG_SECINFO             10
+#define ASSOC_FLAG_WPA_IE              11
+       unsigned long flags;
 
-       u8 last_scanned_channel;
+       u8 ssid[IW_ESSID_MAX_SIZE + 1];
+       u8 ssid_len;
+       u8 channel;
+       u8 band;
+       u8 mode;
+       u8 bssid[ETH_ALEN];
+
+       /** WEP keys */
+       struct enc_key wep_keys[4];
+       u16 wep_tx_keyidx;
+
+       /** WPA keys */
+       struct enc_key wpa_mcast_key;
+       struct enc_key wpa_unicast_key;
+
+       struct lbs_802_11_security secinfo;
+
+       /** WPA Information Elements*/
+       u8 wpa_ie[MAX_WPA_IE_LEN];
+       u8 wpa_ie_len;
+
+       /* BSS to associate with for infrastructure of Ad-Hoc join */
+       struct bss_descriptor bss;
 };
 
-#endif                         /* _WLAN_DEV_H_ */
+#endif
index 3dae15211b6ad3124c28324eefb9e0f04a4933c8..21e6f988ea81cf9e1753df30e98811e6c9e9da5b 100644 (file)
@@ -8,6 +8,8 @@
 #include "dev.h"
 #include "join.h"
 #include "wext.h"
+#include "cmd.h"
+
 static const char * mesh_stat_strings[]= {
                        "drop_duplicate_bcast",
                        "drop_ttl_zero",
@@ -19,35 +21,34 @@ static const char * mesh_stat_strings[]= {
                        "tx_failed_cnt"
 };
 
-static void libertas_ethtool_get_drvinfo(struct net_device *dev,
+static void lbs_ethtool_get_drvinfo(struct net_device *dev,
                                         struct ethtool_drvinfo *info)
 {
-       wlan_private *priv = (wlan_private *) dev->priv;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
        char fwver[32];
 
-       libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1);
+       lbs_get_fwversion(priv, fwver, sizeof(fwver) - 1);
 
        strcpy(info->driver, "libertas");
-       strcpy(info->version, libertas_driver_version);
+       strcpy(info->version, lbs_driver_version);
        strcpy(info->fw_version, fwver);
 }
 
 /* All 8388 parts have 16KiB EEPROM size at the time of writing.
  * In case that changes this needs fixing.
  */
-#define LIBERTAS_EEPROM_LEN 16384
+#define LBS_EEPROM_LEN 16384
 
-static int libertas_ethtool_get_eeprom_len(struct net_device *dev)
+static int lbs_ethtool_get_eeprom_len(struct net_device *dev)
 {
-       return LIBERTAS_EEPROM_LEN;
+       return LBS_EEPROM_LEN;
 }
 
-static int libertas_ethtool_get_eeprom(struct net_device *dev,
+static int lbs_ethtool_get_eeprom(struct net_device *dev,
                                   struct ethtool_eeprom *eeprom, u8 * bytes)
 {
-       wlan_private *priv = (wlan_private *) dev->priv;
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_ioctl_regrdwr regctrl;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
+       struct lbs_ioctl_regrdwr regctrl;
        char *ptr;
        int ret;
 
@@ -55,47 +56,47 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev,
        regctrl.offset = eeprom->offset;
        regctrl.NOB = eeprom->len;
 
-       if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN)
+       if (eeprom->offset + eeprom->len > LBS_EEPROM_LEN)
                return -EINVAL;
 
 //      mutex_lock(&priv->mutex);
 
-       adapter->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
-       if (!adapter->prdeeprom)
+       priv->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
+       if (!priv->prdeeprom)
                return -ENOMEM;
-       memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
+       memcpy(priv->prdeeprom, &regctrl, sizeof(regctrl));
 
        /* +14 is for action, offset, and NOB in
         * response */
        lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n",
               regctrl.action, regctrl.offset, regctrl.NOB);
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_EEPROM_ACCESS,
                                    regctrl.action,
                                    CMD_OPTION_WAITFORRSP, 0,
                                    &regctrl);
 
        if (ret) {
-               if (adapter->prdeeprom)
-                       kfree(adapter->prdeeprom);
+               if (priv->prdeeprom)
+                       kfree(priv->prdeeprom);
                goto done;
        }
 
        mdelay(10);
 
-       ptr = (char *)adapter->prdeeprom;
+       ptr = (char *)priv->prdeeprom;
 
        /* skip the command header, but include the "value" u32 variable */
-       ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4;
+       ptr = ptr + sizeof(struct lbs_ioctl_regrdwr) - 4;
 
        /*
         * Return the result back to the user
         */
        memcpy(bytes, ptr, eeprom->len);
 
-       if (adapter->prdeeprom)
-               kfree(adapter->prdeeprom);
+       if (priv->prdeeprom)
+               kfree(priv->prdeeprom);
 //     mutex_unlock(&priv->mutex);
 
        ret = 0;
@@ -105,17 +106,17 @@ done:
         return ret;
 }
 
-static void libertas_ethtool_get_stats(struct net_device * dev,
+static void lbs_ethtool_get_stats(struct net_device * dev,
                                struct ethtool_stats * stats, u64 * data)
 {
-       wlan_private *priv = dev->priv;
+       struct lbs_private *priv = dev->priv;
        struct cmd_ds_mesh_access mesh_access;
        int ret;
 
        lbs_deb_enter(LBS_DEB_ETHTOOL);
 
        /* Get Mesh Statistics */
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                        CMD_MESH_ACCESS, CMD_ACT_MESH_GET_STATS,
                        CMD_OPTION_WAITFORRSP, 0, &mesh_access);
 
@@ -143,7 +144,7 @@ static void libertas_ethtool_get_stats(struct net_device * dev,
        lbs_deb_enter(LBS_DEB_ETHTOOL);
 }
 
-static int libertas_ethtool_get_sset_count(struct net_device * dev, int sset)
+static int lbs_ethtool_get_sset_count(struct net_device * dev, int sset)
 {
        switch (sset) {
        case ETH_SS_STATS:
@@ -153,7 +154,7 @@ static int libertas_ethtool_get_sset_count(struct net_device * dev, int sset)
        }
 }
 
-static void libertas_ethtool_get_strings (struct net_device * dev,
+static void lbs_ethtool_get_strings(struct net_device *dev,
                                          u32 stringset,
                                          u8 * s)
 {
@@ -173,12 +174,57 @@ static void libertas_ethtool_get_strings (struct net_device * dev,
        lbs_deb_enter(LBS_DEB_ETHTOOL);
 }
 
-struct ethtool_ops libertas_ethtool_ops = {
-       .get_drvinfo = libertas_ethtool_get_drvinfo,
-       .get_eeprom =  libertas_ethtool_get_eeprom,
-       .get_eeprom_len = libertas_ethtool_get_eeprom_len,
-       .get_sset_count = libertas_ethtool_get_sset_count,
-       .get_ethtool_stats = libertas_ethtool_get_stats,
-       .get_strings = libertas_ethtool_get_strings,
+static void lbs_ethtool_get_wol(struct net_device *dev,
+                               struct ethtool_wolinfo *wol)
+{
+       struct lbs_private *priv = dev->priv;
+
+       if (priv->wol_criteria == 0xffffffff) {
+               /* Interface driver didn't configure wake */
+               wol->supported = wol->wolopts = 0;
+               return;
+       }
+
+       wol->supported = WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY;
+
+       if (priv->wol_criteria & EHS_WAKE_ON_UNICAST_DATA)
+               wol->wolopts |= WAKE_UCAST;
+       if (priv->wol_criteria & EHS_WAKE_ON_MULTICAST_DATA)
+               wol->wolopts |= WAKE_MCAST;
+       if (priv->wol_criteria & EHS_WAKE_ON_BROADCAST_DATA)
+               wol->wolopts |= WAKE_BCAST;
+       if (priv->wol_criteria & EHS_WAKE_ON_MAC_EVENT)
+               wol->wolopts |= WAKE_PHY;
+}
+
+static int lbs_ethtool_set_wol(struct net_device *dev,
+                              struct ethtool_wolinfo *wol)
+{
+       struct lbs_private *priv = dev->priv;
+       uint32_t criteria = 0;
+
+       if (priv->wol_criteria == 0xffffffff && wol->wolopts)
+               return -EOPNOTSUPP;
+
+       if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
+               return -EOPNOTSUPP;
+
+       if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
+       if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
+       if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
+       if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;
+
+       return lbs_host_sleep_cfg(priv, criteria);
+}
+
+struct ethtool_ops lbs_ethtool_ops = {
+       .get_drvinfo = lbs_ethtool_get_drvinfo,
+       .get_eeprom =  lbs_ethtool_get_eeprom,
+       .get_eeprom_len = lbs_ethtool_get_eeprom_len,
+       .get_sset_count = lbs_ethtool_get_sset_count,
+       .get_ethtool_stats = lbs_ethtool_get_stats,
+       .get_strings = lbs_ethtool_get_strings,
+       .get_wol = lbs_ethtool_get_wol,
+       .set_wol = lbs_ethtool_set_wol,
 };
 
index b37ddbca969f74dd1e056b358f6f2fdebbca0ef4..1aa04076b1ac72379d14fb46567a174800bed9bc 100644 (file)
@@ -2,25 +2,25 @@
   * This file contains definitions of WLAN commands.
   */
 
-#ifndef _HOST_H_
-#define _HOST_H_
+#ifndef _LBS_HOST_H_
+#define _LBS_HOST_H_
 
 /** PUBLIC DEFINITIONS */
-#define DEFAULT_AD_HOC_CHANNEL       6
-#define DEFAULT_AD_HOC_CHANNEL_A    36
+#define DEFAULT_AD_HOC_CHANNEL                 6
+#define        DEFAULT_AD_HOC_CHANNEL_A                36
 
 /** IEEE 802.11 oids */
-#define OID_802_11_SSID                       0x00008002
-#define OID_802_11_INFRASTRUCTURE_MODE        0x00008008
-#define OID_802_11_FRAGMENTATION_THRESHOLD    0x00008009
-#define OID_802_11_RTS_THRESHOLD              0x0000800A
-#define OID_802_11_TX_ANTENNA_SELECTED        0x0000800D
-#define OID_802_11_SUPPORTED_RATES            0x0000800E
-#define OID_802_11_STATISTICS                 0x00008012
-#define OID_802_11_TX_RETRYCOUNT              0x0000801D
-#define OID_802_11D_ENABLE                    0x00008020
-
-#define CMD_OPTION_WAITFORRSP             0x0002
+#define OID_802_11_SSID                                0x00008002
+#define OID_802_11_INFRASTRUCTURE_MODE         0x00008008
+#define OID_802_11_FRAGMENTATION_THRESHOLD     0x00008009
+#define OID_802_11_RTS_THRESHOLD               0x0000800A
+#define OID_802_11_TX_ANTENNA_SELECTED         0x0000800D
+#define OID_802_11_SUPPORTED_RATES             0x0000800E
+#define OID_802_11_STATISTICS                  0x00008012
+#define OID_802_11_TX_RETRYCOUNT               0x0000801D
+#define OID_802_11D_ENABLE                     0x00008020
+
+#define CMD_OPTION_WAITFORRSP                  0x0002
 
 /** Host command IDs */
 
 #define CMD_RET(cmd)                   (0x8000 | cmd)
 
 /* Return command convention exceptions: */
-#define CMD_RET_802_11_ASSOCIATE      0x8012
+#define CMD_RET_802_11_ASSOCIATE               0x8012
 
 /* Command codes */
-#define CMD_CODE_DNLD                 0x0002
-#define CMD_GET_HW_SPEC               0x0003
-#define CMD_EEPROM_UPDATE             0x0004
-#define CMD_802_11_RESET              0x0005
-#define CMD_802_11_SCAN               0x0006
-#define CMD_802_11_GET_LOG            0x000b
-#define CMD_MAC_MULTICAST_ADR         0x0010
-#define CMD_802_11_AUTHENTICATE       0x0011
-#define CMD_802_11_EEPROM_ACCESS      0x0059
-#define CMD_802_11_ASSOCIATE          0x0050
-#define CMD_802_11_SET_WEP            0x0013
-#define CMD_802_11_GET_STAT           0x0014
-#define CMD_802_3_GET_STAT            0x0015
-#define CMD_802_11_SNMP_MIB           0x0016
-#define CMD_MAC_REG_MAP               0x0017
-#define CMD_BBP_REG_MAP               0x0018
-#define CMD_MAC_REG_ACCESS            0x0019
-#define CMD_BBP_REG_ACCESS            0x001a
-#define CMD_RF_REG_ACCESS             0x001b
-#define CMD_802_11_RADIO_CONTROL      0x001c
-#define CMD_802_11_RF_CHANNEL         0x001d
-#define CMD_802_11_RF_TX_POWER        0x001e
-#define CMD_802_11_RSSI               0x001f
-#define CMD_802_11_RF_ANTENNA         0x0020
-
-#define CMD_802_11_PS_MODE           0x0021
-
-#define CMD_802_11_DATA_RATE          0x0022
-#define CMD_RF_REG_MAP                0x0023
-#define CMD_802_11_DEAUTHENTICATE     0x0024
-#define CMD_802_11_REASSOCIATE        0x0025
-#define CMD_802_11_DISASSOCIATE       0x0026
-#define CMD_MAC_CONTROL               0x0028
-#define CMD_802_11_AD_HOC_START       0x002b
-#define CMD_802_11_AD_HOC_JOIN        0x002c
-
-#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS  0x002e
-#define CMD_802_11_ENABLE_RSN              0x002f
-#define CMD_802_11_PAIRWISE_TSC       0x0036
-#define CMD_802_11_GROUP_TSC          0x0037
-#define CMD_802_11_KEY_MATERIAL       0x005e
-
-#define CMD_802_11_SET_AFC            0x003c
-#define CMD_802_11_GET_AFC            0x003d
-
-#define CMD_802_11_AD_HOC_STOP        0x0040
-
-#define CMD_802_11_BEACON_STOP        0x0049
-
-#define CMD_802_11_MAC_ADDRESS        0x004D
-#define CMD_802_11_EEPROM_ACCESS      0x0059
-
-#define CMD_802_11_BAND_CONFIG        0x0058
-
-#define CMD_802_11D_DOMAIN_INFO       0x005b
-
-#define CMD_802_11_SLEEP_PARAMS          0x0066
-
-#define CMD_802_11_INACTIVITY_TIMEOUT    0x0067
-
-#define CMD_802_11_TPC_CFG               0x0072
-#define CMD_802_11_PWR_CFG               0x0073
-
-#define CMD_802_11_LED_GPIO_CTRL         0x004e
-
-#define CMD_802_11_SUBSCRIBE_EVENT       0x0075
-
-#define CMD_802_11_RATE_ADAPT_RATESET    0x0076
-
-#define CMD_802_11_TX_RATE_QUERY       0x007f
-
-#define CMD_GET_TSF                      0x0080
-
-#define CMD_BT_ACCESS                 0x0087
-
-#define CMD_FWT_ACCESS                0x0095
-
-#define CMD_802_11_MONITOR_MODE       0x0098
-
-#define CMD_MESH_ACCESS               0x009b
-
-#define CMD_SET_BOOT2_VER                 0x00a5
+#define CMD_CODE_DNLD                          0x0002
+#define CMD_GET_HW_SPEC                                0x0003
+#define        CMD_EEPROM_UPDATE                       0x0004
+#define CMD_802_11_RESET                       0x0005
+#define        CMD_802_11_SCAN                         0x0006
+#define CMD_802_11_GET_LOG                     0x000b
+#define CMD_MAC_MULTICAST_ADR                  0x0010
+#define CMD_802_11_AUTHENTICATE                        0x0011
+#define CMD_802_11_EEPROM_ACCESS               0x0059
+#define CMD_802_11_ASSOCIATE                   0x0050
+#define CMD_802_11_SET_WEP                     0x0013
+#define CMD_802_11_GET_STAT                    0x0014
+#define CMD_802_3_GET_STAT                     0x0015
+#define CMD_802_11_SNMP_MIB                    0x0016
+#define CMD_MAC_REG_MAP                                0x0017
+#define CMD_BBP_REG_MAP                                0x0018
+#define CMD_MAC_REG_ACCESS                     0x0019
+#define CMD_BBP_REG_ACCESS                     0x001a
+#define CMD_RF_REG_ACCESS                      0x001b
+#define CMD_802_11_RADIO_CONTROL               0x001c
+#define CMD_802_11_RF_CHANNEL                  0x001d
+#define CMD_802_11_RF_TX_POWER                 0x001e
+#define CMD_802_11_RSSI                                0x001f
+#define CMD_802_11_RF_ANTENNA                  0x0020
+#define CMD_802_11_PS_MODE                     0x0021
+#define CMD_802_11_DATA_RATE                   0x0022
+#define CMD_RF_REG_MAP                         0x0023
+#define CMD_802_11_DEAUTHENTICATE              0x0024
+#define CMD_802_11_REASSOCIATE                 0x0025
+#define CMD_802_11_DISASSOCIATE                        0x0026
+#define CMD_MAC_CONTROL                                0x0028
+#define CMD_802_11_AD_HOC_START                        0x002b
+#define CMD_802_11_AD_HOC_JOIN                 0x002c
+#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS      0x002e
+#define CMD_802_11_ENABLE_RSN                  0x002f
+#define CMD_802_11_PAIRWISE_TSC                        0x0036
+#define CMD_802_11_GROUP_TSC                   0x0037
+#define CMD_802_11_SET_AFC                     0x003c
+#define CMD_802_11_GET_AFC                     0x003d
+#define CMD_802_11_AD_HOC_STOP                 0x0040
+#define CMD_802_11_HOST_SLEEP_CFG              0x0043
+#define CMD_802_11_WAKEUP_CONFIRM              0x0044
+#define CMD_802_11_HOST_SLEEP_ACTIVATE         0x0045
+#define CMD_802_11_BEACON_STOP                 0x0049
+#define CMD_802_11_MAC_ADDRESS                 0x004d
+#define CMD_802_11_LED_GPIO_CTRL               0x004e
+#define CMD_802_11_EEPROM_ACCESS               0x0059
+#define CMD_802_11_BAND_CONFIG                 0x0058
+#define CMD_802_11D_DOMAIN_INFO                        0x005b
+#define CMD_802_11_KEY_MATERIAL                        0x005e
+#define CMD_802_11_SLEEP_PARAMS                        0x0066
+#define CMD_802_11_INACTIVITY_TIMEOUT          0x0067
+#define CMD_802_11_SLEEP_PERIOD                        0x0068
+#define CMD_802_11_TPC_CFG                     0x0072
+#define CMD_802_11_PWR_CFG                     0x0073
+#define CMD_802_11_FW_WAKE_METHOD              0x0074
+#define CMD_802_11_SUBSCRIBE_EVENT             0x0075
+#define CMD_802_11_RATE_ADAPT_RATESET          0x0076
+#define CMD_802_11_TX_RATE_QUERY               0x007f
+#define        CMD_GET_TSF                             0x0080
+#define CMD_BT_ACCESS                          0x0087
+#define CMD_FWT_ACCESS                         0x0095
+#define CMD_802_11_MONITOR_MODE                        0x0098
+#define CMD_MESH_ACCESS                                0x009b
+#define CMD_MESH_CONFIG                                0x00a3
+#define        CMD_SET_BOOT2_VER                       0x00a5
+#define CMD_802_11_BEACON_CTRL                 0x00b0
 
 /* For the IEEE Power Save */
-#define CMD_SUBCMD_ENTER_PS               0x0030
-#define CMD_SUBCMD_EXIT_PS                0x0031
-#define CMD_SUBCMD_SLEEP_CONFIRMED        0x0034
-#define CMD_SUBCMD_FULL_POWERDOWN         0x0035
-#define CMD_SUBCMD_FULL_POWERUP           0x0036
-
-#define CMD_ENABLE_RSN                    0x0001
-#define CMD_DISABLE_RSN                   0x0000
+#define CMD_SUBCMD_ENTER_PS            0x0030
+#define CMD_SUBCMD_EXIT_PS             0x0031
+#define CMD_SUBCMD_SLEEP_CONFIRMED     0x0034
+#define CMD_SUBCMD_FULL_POWERDOWN      0x0035
+#define CMD_SUBCMD_FULL_POWERUP                0x0036
 
-#define CMD_ACT_SET                       0x0001
-#define CMD_ACT_GET                       0x0000
+#define CMD_ENABLE_RSN                 0x0001
+#define CMD_DISABLE_RSN                        0x0000
 
-#define CMD_ACT_GET_AES                   (CMD_ACT_GET + 2)
-#define CMD_ACT_SET_AES                   (CMD_ACT_SET + 2)
-#define CMD_ACT_REMOVE_AES                (CMD_ACT_SET + 3)
+#define CMD_ACT_GET                    0x0000
+#define CMD_ACT_SET                    0x0001
+#define CMD_ACT_GET_AES                        0x0002
+#define CMD_ACT_SET_AES                        0x0003
+#define CMD_ACT_REMOVE_AES             0x0004
 
 /* Define action or option for CMD_802_11_SET_WEP */
-#define CMD_ACT_ADD                         0x0002
-#define CMD_ACT_REMOVE                      0x0004
-#define CMD_ACT_USE_DEFAULT                 0x0008
+#define CMD_ACT_ADD                    0x0002
+#define CMD_ACT_REMOVE                 0x0004
+#define CMD_ACT_USE_DEFAULT            0x0008
 
-#define CMD_TYPE_WEP_40_BIT                 0x01
-#define CMD_TYPE_WEP_104_BIT                0x02
+#define CMD_TYPE_WEP_40_BIT            0x01
+#define CMD_TYPE_WEP_104_BIT           0x02
 
-#define CMD_NUM_OF_WEP_KEYS                 4
+#define CMD_NUM_OF_WEP_KEYS            4
 
-#define CMD_WEP_KEY_INDEX_MASK              0x3fff
+#define CMD_WEP_KEY_INDEX_MASK         0x3fff
 
 /* Define action or option for CMD_802_11_RESET */
-#define CMD_ACT_HALT                        0x0003
+#define CMD_ACT_HALT                   0x0003
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_BSS_TYPE_BSS                    0x0001
-#define CMD_BSS_TYPE_IBSS                   0x0002
-#define CMD_BSS_TYPE_ANY                    0x0003
+#define CMD_BSS_TYPE_BSS               0x0001
+#define CMD_BSS_TYPE_IBSS              0x0002
+#define CMD_BSS_TYPE_ANY               0x0003
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_SCAN_TYPE_ACTIVE                0x0000
-#define CMD_SCAN_TYPE_PASSIVE               0x0001
+#define CMD_SCAN_TYPE_ACTIVE           0x0000
+#define CMD_SCAN_TYPE_PASSIVE          0x0001
 
 #define CMD_SCAN_RADIO_TYPE_BG         0
 
-#define CMD_SCAN_PROBE_DELAY_TIME           0
+#define        CMD_SCAN_PROBE_DELAY_TIME       0
 
 /* Define action or option for CMD_MAC_CONTROL */
-#define CMD_ACT_MAC_RX_ON                   0x0001
-#define CMD_ACT_MAC_TX_ON                   0x0002
-#define CMD_ACT_MAC_LOOPBACK_ON             0x0004
-#define CMD_ACT_MAC_WEP_ENABLE              0x0008
-#define CMD_ACT_MAC_INT_ENABLE              0x0010
-#define CMD_ACT_MAC_MULTICAST_ENABLE        0x0020
-#define CMD_ACT_MAC_BROADCAST_ENABLE        0x0040
-#define CMD_ACT_MAC_PROMISCUOUS_ENABLE      0x0080
-#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE    0x0100
-#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE  0x0400
+#define CMD_ACT_MAC_RX_ON                      0x0001
+#define CMD_ACT_MAC_TX_ON                      0x0002
+#define CMD_ACT_MAC_LOOPBACK_ON                        0x0004
+#define CMD_ACT_MAC_WEP_ENABLE                 0x0008
+#define CMD_ACT_MAC_INT_ENABLE                 0x0010
+#define CMD_ACT_MAC_MULTICAST_ENABLE           0x0020
+#define CMD_ACT_MAC_BROADCAST_ENABLE           0x0040
+#define CMD_ACT_MAC_PROMISCUOUS_ENABLE         0x0080
+#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE       0x0100
+#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE   0x0400
 
 /* Define action or option for CMD_802_11_RADIO_CONTROL */
-#define CMD_TYPE_AUTO_PREAMBLE              0x0001
-#define CMD_TYPE_SHORT_PREAMBLE             0x0002
-#define CMD_TYPE_LONG_PREAMBLE              0x0003
-
-#define TURN_ON_RF                              0x01
-#define RADIO_ON                                0x01
-#define RADIO_OFF                               0x00
-
-#define SET_AUTO_PREAMBLE                       0x05
-#define SET_SHORT_PREAMBLE                      0x03
-#define SET_LONG_PREAMBLE                       0x01
+#define CMD_TYPE_AUTO_PREAMBLE         0x0001
+#define CMD_TYPE_SHORT_PREAMBLE                0x0002
+#define CMD_TYPE_LONG_PREAMBLE         0x0003
+
+/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
+#define CMD_SUBSCRIBE_RSSI_LOW         0x0001
+#define CMD_SUBSCRIBE_SNR_LOW          0x0002
+#define CMD_SUBSCRIBE_FAILCOUNT                0x0004
+#define CMD_SUBSCRIBE_BCNMISS          0x0008
+#define CMD_SUBSCRIBE_RSSI_HIGH                0x0010
+#define CMD_SUBSCRIBE_SNR_HIGH         0x0020
+
+#define TURN_ON_RF                     0x01
+#define RADIO_ON                       0x01
+#define RADIO_OFF                      0x00
+
+#define SET_AUTO_PREAMBLE              0x05
+#define SET_SHORT_PREAMBLE             0x03
+#define SET_LONG_PREAMBLE              0x01
 
 /* Define action or option for CMD_802_11_RF_CHANNEL */
-#define CMD_OPT_802_11_RF_CHANNEL_GET       0x00
-#define CMD_OPT_802_11_RF_CHANNEL_SET       0x01
+#define CMD_OPT_802_11_RF_CHANNEL_GET  0x00
+#define CMD_OPT_802_11_RF_CHANNEL_SET  0x01
 
 /* Define action or option for CMD_802_11_RF_TX_POWER */
-#define CMD_ACT_TX_POWER_OPT_GET            0x0000
-#define CMD_ACT_TX_POWER_OPT_SET_HIGH       0x8007
-#define CMD_ACT_TX_POWER_OPT_SET_MID        0x8004
-#define CMD_ACT_TX_POWER_OPT_SET_LOW        0x8000
+#define CMD_ACT_TX_POWER_OPT_GET       0x0000
+#define CMD_ACT_TX_POWER_OPT_SET_HIGH  0x8007
+#define CMD_ACT_TX_POWER_OPT_SET_MID   0x8004
+#define CMD_ACT_TX_POWER_OPT_SET_LOW   0x8000
 
-#define CMD_ACT_TX_POWER_INDEX_HIGH         0x0007
-#define CMD_ACT_TX_POWER_INDEX_MID          0x0004
-#define CMD_ACT_TX_POWER_INDEX_LOW          0x0000
+#define CMD_ACT_TX_POWER_INDEX_HIGH    0x0007
+#define CMD_ACT_TX_POWER_INDEX_MID     0x0004
+#define CMD_ACT_TX_POWER_INDEX_LOW     0x0000
 
 /* Define action or option for CMD_802_11_DATA_RATE */
-#define CMD_ACT_SET_TX_AUTO                 0x0000
-#define CMD_ACT_SET_TX_FIX_RATE             0x0001
-#define CMD_ACT_GET_TX_RATE                 0x0002
+#define CMD_ACT_SET_TX_AUTO            0x0000
+#define CMD_ACT_SET_TX_FIX_RATE                0x0001
+#define CMD_ACT_GET_TX_RATE            0x0002
 
-#define CMD_ACT_SET_RX                      0x0001
-#define CMD_ACT_SET_TX                      0x0002
-#define CMD_ACT_SET_BOTH                    0x0003
-#define CMD_ACT_GET_RX                      0x0004
-#define CMD_ACT_GET_TX                      0x0008
-#define CMD_ACT_GET_BOTH                    0x000c
+#define CMD_ACT_SET_RX                 0x0001
+#define        CMD_ACT_SET_TX                  0x0002
+#define CMD_ACT_SET_BOTH               0x0003
+#define        CMD_ACT_GET_RX                  0x0004
+#define CMD_ACT_GET_TX                 0x0008
+#define        CMD_ACT_GET_BOTH                0x000c
 
 /* Define action or option for CMD_802_11_PS_MODE */
-#define CMD_TYPE_CAM                        0x0000
-#define CMD_TYPE_MAX_PSP                    0x0001
-#define CMD_TYPE_FAST_PSP                   0x0002
+#define CMD_TYPE_CAM                   0x0000
+#define        CMD_TYPE_MAX_PSP                0x0001
+#define CMD_TYPE_FAST_PSP              0x0002
+
+/* Options for CMD_802_11_FW_WAKE_METHOD */
+#define CMD_WAKE_METHOD_UNCHANGED      0x0000
+#define CMD_WAKE_METHOD_COMMAND_INT    0x0001
+#define CMD_WAKE_METHOD_GPIO           0x0002
 
 /* Define action or option for CMD_BT_ACCESS */
 enum cmd_bt_access_opts {
@@ -237,8 +234,8 @@ enum cmd_fwt_access_opts {
        CMD_ACT_FWT_ACCESS_DEL,
        CMD_ACT_FWT_ACCESS_LOOKUP,
        CMD_ACT_FWT_ACCESS_LIST,
-       CMD_ACT_FWT_ACCESS_LIST_route,
-       CMD_ACT_FWT_ACCESS_LIST_neighbor,
+       CMD_ACT_FWT_ACCESS_LIST_ROUTE,
+       CMD_ACT_FWT_ACCESS_LIST_NEIGHBOR,
        CMD_ACT_FWT_ACCESS_RESET,
        CMD_ACT_FWT_ACCESS_CLEANUP,
        CMD_ACT_FWT_ACCESS_TIME,
@@ -264,27 +261,36 @@ enum cmd_mesh_access_opts {
 };
 
 /** Card Event definition */
-#define MACREG_INT_CODE_TX_PPA_FREE             0x00000000
-#define MACREG_INT_CODE_TX_DMA_DONE             0x00000001
-#define MACREG_INT_CODE_LINK_LOSE_W_SCAN        0x00000002
-#define MACREG_INT_CODE_LINK_LOSE_NO_SCAN       0x00000003
-#define MACREG_INT_CODE_LINK_SENSED             0x00000004
-#define MACREG_INT_CODE_CMD_FINISHED            0x00000005
-#define MACREG_INT_CODE_MIB_CHANGED             0x00000006
-#define MACREG_INT_CODE_INIT_DONE               0x00000007
-#define MACREG_INT_CODE_DEAUTHENTICATED         0x00000008
-#define MACREG_INT_CODE_DISASSOCIATED           0x00000009
-#define MACREG_INT_CODE_PS_AWAKE                0x0000000a
-#define MACREG_INT_CODE_PS_SLEEP                0x0000000b
-#define MACREG_INT_CODE_MIC_ERR_MULTICAST       0x0000000d
-#define MACREG_INT_CODE_MIC_ERR_UNICAST         0x0000000e
-#define MACREG_INT_CODE_WM_AWAKE                0x0000000f
-#define MACREG_INT_CODE_ADHOC_BCN_LOST          0x00000011
-#define MACREG_INT_CODE_RSSI_LOW               0x00000019
-#define MACREG_INT_CODE_SNR_LOW                        0x0000001a
-#define MACREG_INT_CODE_MAX_FAIL               0x0000001b
-#define MACREG_INT_CODE_RSSI_HIGH              0x0000001c
-#define MACREG_INT_CODE_SNR_HIGH               0x0000001d
-#define MACREG_INT_CODE_MESH_AUTO_STARTED      0x00000023
-
-#endif                         /* _HOST_H_ */
+#define MACREG_INT_CODE_TX_PPA_FREE            0
+#define MACREG_INT_CODE_TX_DMA_DONE            1
+#define MACREG_INT_CODE_LINK_LOST_W_SCAN       2
+#define MACREG_INT_CODE_LINK_LOST_NO_SCAN      3
+#define MACREG_INT_CODE_LINK_SENSED            4
+#define MACREG_INT_CODE_CMD_FINISHED           5
+#define MACREG_INT_CODE_MIB_CHANGED            6
+#define MACREG_INT_CODE_INIT_DONE              7
+#define MACREG_INT_CODE_DEAUTHENTICATED                8
+#define MACREG_INT_CODE_DISASSOCIATED          9
+#define MACREG_INT_CODE_PS_AWAKE               10
+#define MACREG_INT_CODE_PS_SLEEP               11
+#define MACREG_INT_CODE_MIC_ERR_MULTICAST      13
+#define MACREG_INT_CODE_MIC_ERR_UNICAST                14
+#define MACREG_INT_CODE_WM_AWAKE               15
+#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE       16
+#define MACREG_INT_CODE_ADHOC_BCN_LOST         17
+#define MACREG_INT_CODE_HOST_AWAKE             18
+#define MACREG_INT_CODE_STOP_TX                        19
+#define MACREG_INT_CODE_START_TX               20
+#define MACREG_INT_CODE_CHANNEL_SWITCH         21
+#define MACREG_INT_CODE_MEASUREMENT_RDY                22
+#define MACREG_INT_CODE_WMM_CHANGE             23
+#define MACREG_INT_CODE_BG_SCAN_REPORT         24
+#define MACREG_INT_CODE_RSSI_LOW               25
+#define MACREG_INT_CODE_SNR_LOW                        26
+#define MACREG_INT_CODE_MAX_FAIL               27
+#define MACREG_INT_CODE_RSSI_HIGH              28
+#define MACREG_INT_CODE_SNR_HIGH               29
+#define MACREG_INT_CODE_MESH_AUTO_STARTED      35
+#define MACREG_INT_CODE_FIRMWARE_READY         48
+
+#endif
index e1045dc02cce26ca18736bfba0568d591d4e17b9..d35b015b66577d80620b1e1bdebfa4cf81d1af51 100644 (file)
@@ -2,8 +2,8 @@
  * This file contains the function prototypes, data structure
  * and defines for all the host/station commands
  */
-#ifndef __HOSTCMD__H
-#define __HOSTCMD__H
+#ifndef _LBS_HOSTCMD_H
+#define _LBS_HOSTCMD_H
 
 #include <linux/wireless.h>
 #include "11d.h"
@@ -65,19 +65,21 @@ struct rxpd {
        u8 reserved[3];
 };
 
+struct cmd_header {
+       __le16 command;
+       __le16 size;
+       __le16 seqnum;
+       __le16 result;
+} __attribute__ ((packed));
+
 struct cmd_ctrl_node {
-       /* CMD link list */
        struct list_head list;
-       u32 status;
-       /* CMD ID */
-       u32 cmd_oid;
-       /*CMD wait option: wait for finish or no wait */
-       u16 wait_option;
-       /* command parameter */
-       void *pdata_buf;
-       /*command data */
-       u8 *bufvirtualaddr;
-       u16 cmdflags;
+       int result;
+       /* command response */
+       int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
+       unsigned long callback_arg;
+       /* command data */
+       struct cmd_header *cmdbuf;
        /* wait queue */
        u16 cmdwaitqwoken;
        wait_queue_head_t cmdwait_q;
@@ -86,13 +88,13 @@ struct cmd_ctrl_node {
 /* Generic structure to hold all key types. */
 struct enc_key {
        u16 len;
-       u16 flags;  /* KEY_INFO_* from wlan_defs.h */
-       u16 type; /* KEY_TYPE_* from wlan_defs.h */
+       u16 flags;  /* KEY_INFO_* from defs.h */
+       u16 type; /* KEY_TYPE_* from defs.h */
        u8 key[32];
 };
 
-/* wlan_offset_value */
-struct wlan_offset_value {
+/* lbs_offset_value */
+struct lbs_offset_value {
        u32 offset;
        u32 value;
 };
@@ -104,14 +106,19 @@ struct cmd_ds_gen {
        __le16 size;
        __le16 seqnum;
        __le16 result;
+       void *cmdresp[0];
 };
 
 #define S_DS_GEN sizeof(struct cmd_ds_gen)
+
+
 /*
  * Define data structure for CMD_GET_HW_SPEC
  * This structure defines the response for the GET_HW_SPEC command
  */
 struct cmd_ds_get_hw_spec {
+       struct cmd_header hdr;
+
        /* HW Interface version number */
        __le16 hwifversion;
        /* HW version number */
@@ -129,8 +136,8 @@ struct cmd_ds_get_hw_spec {
        /* Number of antenna used */
        __le16 nr_antenna;
 
-       /* FW release number, example 1,2,3,4 = 3.2.1p4 */
-       u8 fwreleasenumber[4];
+       /* FW release number, example 0x01030304 = 2.3.4p1 */
+       __le32 fwrelease;
 
        /* Base Address of TxPD queue */
        __le32 wcb_base;
@@ -149,8 +156,17 @@ struct cmd_ds_802_11_reset {
 };
 
 struct cmd_ds_802_11_subscribe_event {
+       struct cmd_header hdr;
+
        __le16 action;
        __le16 events;
+
+       /* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a
+        * number of TLVs. From the v5.1 manual, those TLVs would add up to
+        * 40 bytes. However, future firmware might add additional TLVs, so I
+        * bump this up a bit.
+        */
+       uint8_t tlv[128];
 };
 
 /*
@@ -242,6 +258,8 @@ struct cmd_ds_802_11_ad_hoc_result {
 };
 
 struct cmd_ds_802_11_set_wep {
+       struct cmd_header hdr;
+
        /* ACT_ADD, ACT_REMOVE or ACT_ENABLE */
        __le16 action;
 
@@ -249,8 +267,8 @@ struct cmd_ds_802_11_set_wep {
        __le16 keyindex;
 
        /* 40, 128bit or TXWEP */
-       u8 keytype[4];
-       u8 keymaterial[4][16];
+       uint8_t keytype[4];
+       uint8_t keymaterial[4][16];
 };
 
 struct cmd_ds_802_3_get_stat {
@@ -328,11 +346,21 @@ struct cmd_ds_rf_reg_access {
 };
 
 struct cmd_ds_802_11_radio_control {
+       struct cmd_header hdr;
+
        __le16 action;
        __le16 control;
 };
 
+struct cmd_ds_802_11_beacon_control {
+       __le16 action;
+       __le16 beacon_enable;
+       __le16 beacon_period;
+};
+
 struct cmd_ds_802_11_sleep_params {
+       struct cmd_header hdr;
+
        /* ACT_GET/ACT_SET */
        __le16 action;
 
@@ -346,16 +374,18 @@ struct cmd_ds_802_11_sleep_params {
        __le16 stabletime;
 
        /* control periodic calibration */
-       u8 calcontrol;
+       uint8_t calcontrol;
 
        /* control the use of external sleep clock */
-       u8 externalsleepclk;
+       uint8_t externalsleepclk;
 
        /* reserved field, should be set to zero */
        __le16 reserved;
 };
 
 struct cmd_ds_802_11_inactivity_timeout {
+       struct cmd_header hdr;
+
        /* ACT_GET/ACT_SET */
        __le16 action;
 
@@ -364,11 +394,13 @@ struct cmd_ds_802_11_inactivity_timeout {
 };
 
 struct cmd_ds_802_11_rf_channel {
+       struct cmd_header hdr;
+
        __le16 action;
-       __le16 currentchannel;
-       __le16 rftype;
-       __le16 reserved;
-       u8 channellist[32];
+       __le16 channel;
+       __le16 rftype;      /* unused */
+       __le16 reserved;    /* unused */
+       u8 channellist[32]; /* unused */
 };
 
 struct cmd_ds_802_11_rssi {
@@ -406,13 +438,29 @@ struct cmd_ds_802_11_rf_antenna {
 };
 
 struct cmd_ds_802_11_monitor_mode {
-       u16 action;
-       u16 mode;
+       __le16 action;
+       __le16 mode;
 };
 
 struct cmd_ds_set_boot2_ver {
-       u16 action;
-       u16 version;
+       struct cmd_header hdr;
+
+       __le16 action;
+       __le16 version;
+};
+
+struct cmd_ds_802_11_fw_wake_method {
+       struct cmd_header hdr;
+
+       __le16 action;
+       __le16 method;
+};
+
+struct cmd_ds_802_11_sleep_period {
+       struct cmd_header hdr;
+
+       __le16 action;
+       __le16 period;
 };
 
 struct cmd_ds_802_11_ps_mode {
@@ -437,6 +485,8 @@ struct PS_CMD_ConfirmSleep {
 };
 
 struct cmd_ds_802_11_data_rate {
+       struct cmd_header hdr;
+
        __le16 action;
        __le16 reserved;
        u8 rates[MAX_RATES];
@@ -488,6 +538,8 @@ struct cmd_ds_802_11_ad_hoc_join {
 } __attribute__ ((packed));
 
 struct cmd_ds_802_11_enable_rsn {
+       struct cmd_header hdr;
+
        __le16 action;
        __le16 enable;
 } __attribute__ ((packed));
@@ -512,6 +564,13 @@ struct MrvlIEtype_keyParamSet {
        u8 key[32];
 };
 
+struct cmd_ds_host_sleep {
+       struct cmd_header hdr;
+       __le32 criteria;
+       uint8_t gpio;
+       uint8_t gap;
+} __attribute__ ((packed));
+
 struct cmd_ds_802_11_key_material {
        __le16 action;
        struct MrvlIEtype_keyParamSet keyParamSet[2];
@@ -598,7 +657,21 @@ struct cmd_ds_fwt_access {
        u8 prec[ETH_ALEN];
 } __attribute__ ((packed));
 
+
+struct cmd_ds_mesh_config {
+       struct cmd_header hdr;
+
+        __le16 action;
+        __le16 channel;
+        __le16 type;
+        __le16 length;
+        u8 data[128];   /* last position reserved */
+} __attribute__ ((packed));
+
+
 struct cmd_ds_mesh_access {
+       struct cmd_header hdr;
+
        __le16 action;
        __le32 data[32];        /* last position reserved */
 } __attribute__ ((packed));
@@ -615,14 +688,12 @@ struct cmd_ds_command {
 
        /* command Body */
        union {
-               struct cmd_ds_get_hw_spec hwspec;
                struct cmd_ds_802_11_ps_mode psmode;
                struct cmd_ds_802_11_scan scan;
                struct cmd_ds_802_11_scan_rsp scanresp;
                struct cmd_ds_mac_control macctrl;
                struct cmd_ds_802_11_associate associate;
                struct cmd_ds_802_11_deauthenticate deauth;
-               struct cmd_ds_802_11_set_wep wep;
                struct cmd_ds_802_11_ad_hoc_start ads;
                struct cmd_ds_802_11_reset reset;
                struct cmd_ds_802_11_ad_hoc_result result;
@@ -634,17 +705,13 @@ struct cmd_ds_command {
                struct cmd_ds_802_11_rf_tx_power txp;
                struct cmd_ds_802_11_rf_antenna rant;
                struct cmd_ds_802_11_monitor_mode monitor;
-               struct cmd_ds_802_11_data_rate drate;
                struct cmd_ds_802_11_rate_adapt_rateset rateset;
                struct cmd_ds_mac_multicast_adr madr;
                struct cmd_ds_802_11_ad_hoc_join adj;
-               struct cmd_ds_802_11_radio_control radio;
-               struct cmd_ds_802_11_rf_channel rfchannel;
                struct cmd_ds_802_11_rssi rssi;
                struct cmd_ds_802_11_rssi_rsp rssirsp;
                struct cmd_ds_802_11_disassociate dassociate;
                struct cmd_ds_802_11_mac_address macadd;
-               struct cmd_ds_802_11_enable_rsn enbrsn;
                struct cmd_ds_802_11_key_material keymaterial;
                struct cmd_ds_mac_reg_access macreg;
                struct cmd_ds_bbp_reg_access bbpreg;
@@ -654,8 +721,6 @@ struct cmd_ds_command {
                struct cmd_ds_802_11d_domain_info domaininfo;
                struct cmd_ds_802_11d_domain_info domaininforesp;
 
-               struct cmd_ds_802_11_sleep_params sleep_params;
-               struct cmd_ds_802_11_inactivity_timeout inactivity_timeout;
                struct cmd_ds_802_11_tpc_cfg tpccfg;
                struct cmd_ds_802_11_pwr_cfg pwrcfg;
                struct cmd_ds_802_11_afc afc;
@@ -664,10 +729,8 @@ struct cmd_ds_command {
                struct cmd_tx_rate_query txrate;
                struct cmd_ds_bt_access bt;
                struct cmd_ds_fwt_access fwt;
-               struct cmd_ds_mesh_access mesh;
-               struct cmd_ds_set_boot2_ver boot2_ver;
                struct cmd_ds_get_tsf gettsf;
-               struct cmd_ds_802_11_subscribe_event subscribe_event;
+               struct cmd_ds_802_11_beacon_control bcn_ctrl;
        } params;
 } __attribute__ ((packed));
 
index ba4fc2b3bf0a3a87f41ae6175b00c4593ef0fda4..4b5ab9a6b97b78687e56d1e5070addd9c7a1d8d9 100644 (file)
@@ -57,7 +57,7 @@ MODULE_LICENSE("GPL");
 
 struct if_cs_card {
        struct pcmcia_device *p_dev;
-       wlan_private *priv;
+       struct lbs_private *priv;
        void __iomem *iobase;
 };
 
@@ -243,7 +243,7 @@ static inline void if_cs_disable_ints(struct if_cs_card *card)
 
 static irqreturn_t if_cs_interrupt(int irq, void *data)
 {
-       struct if_cs_card *card = (struct if_cs_card *)data;
+       struct if_cs_card *card = data;
        u16 int_cause;
 
        lbs_deb_enter(LBS_DEB_CS);
@@ -253,25 +253,20 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
                /* Not for us */
                return IRQ_NONE;
 
-       } else if(int_cause == 0xffff) {
+       } else if (int_cause == 0xffff) {
                /* Read in junk, the card has probably been removed */
-               card->priv->adapter->surpriseremoved = 1;
+               card->priv->surpriseremoved = 1;
 
        } else {
-               if(int_cause & IF_CS_H_IC_TX_OVER) {
-                       card->priv->dnld_sent = DNLD_RES_RECEIVED;
-                       if (!card->priv->adapter->cur_cmd)
-                               wake_up_interruptible(&card->priv->waitq);
-
-                       if (card->priv->adapter->connect_status == LIBERTAS_CONNECTED)
-                               netif_wake_queue(card->priv->dev);
-               }
+               if (int_cause & IF_CS_H_IC_TX_OVER)
+                       lbs_host_to_card_done(card->priv);
 
                /* clear interrupt */
                if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK);
        }
-
-       libertas_interrupt(card->priv->dev);
+       spin_lock(&card->priv->driver_lock);
+       lbs_interrupt(card->priv);
+       spin_unlock(&card->priv->driver_lock);
 
        return IRQ_HANDLED;
 }
@@ -286,7 +281,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
 /*
  * Called from if_cs_host_to_card to send a command to the hardware
  */
-static int if_cs_send_cmd(wlan_private *priv, u8 *buf, u16 nb)
+static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb)
 {
        struct if_cs_card *card = (struct if_cs_card *)priv->card;
        int ret = -1;
@@ -331,7 +326,7 @@ done:
 /*
  * Called from if_cs_host_to_card to send a data to the hardware
  */
-static void if_cs_send_data(wlan_private *priv, u8 *buf, u16 nb)
+static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb)
 {
        struct if_cs_card *card = (struct if_cs_card *)priv->card;
 
@@ -354,7 +349,7 @@ static void if_cs_send_data(wlan_private *priv, u8 *buf, u16 nb)
 /*
  * Get the command result out of the card.
  */
-static int if_cs_receive_cmdres(wlan_private *priv, u8* data, u32 *len)
+static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
 {
        int ret = -1;
        u16 val;
@@ -369,7 +364,7 @@ static int if_cs_receive_cmdres(wlan_private *priv, u8* data, u32 *len)
        }
 
        *len = if_cs_read16(priv->card, IF_CS_C_CMD_LEN);
-       if ((*len == 0) || (*len > MRVDRV_SIZE_OF_CMD_BUFFER)) {
+       if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
                lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
                goto out;
        }
@@ -379,6 +374,9 @@ static int if_cs_receive_cmdres(wlan_private *priv, u8* data, u32 *len)
        if (*len & 1)
                data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD);
 
+       /* This is a workaround for a firmware that reports too much
+        * bytes */
+       *len -= 8;
        ret = 0;
 out:
        lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len);
@@ -386,7 +384,7 @@ out:
 }
 
 
-static struct sk_buff *if_cs_receive_data(wlan_private *priv)
+static struct sk_buff *if_cs_receive_data(struct lbs_private *priv)
 {
        struct sk_buff *skb = NULL;
        u16 len;
@@ -616,7 +614,10 @@ done:
 /********************************************************************/
 
 /* Send commands or data packets to the card */
-static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
+static int if_cs_host_to_card(struct lbs_private *priv,
+       u8 type,
+       u8 *buf,
+       u16 nb)
 {
        int ret = -1;
 
@@ -641,18 +642,16 @@ static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
 }
 
 
-static int if_cs_get_int_status(wlan_private *priv, u8 *ireg)
+static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg)
 {
        struct if_cs_card *card = (struct if_cs_card *)priv->card;
-       //wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        u16 int_cause;
-       u8 *cmdbuf;
        *ireg = 0;
 
        lbs_deb_enter(LBS_DEB_CS);
 
-       if (priv->adapter->surpriseremoved)
+       if (priv->surpriseremoved)
                goto out;
 
        int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE) & IF_CS_C_IC_MASK;
@@ -668,7 +667,7 @@ sbi_get_int_status_exit:
        /* is there a data packet for us? */
        if (*ireg & IF_CS_C_S_RX_UPLD_RDY) {
                struct sk_buff *skb = if_cs_receive_data(priv);
-               libertas_process_rxed_packet(priv, skb);
+               lbs_process_rxed_packet(priv, skb);
                *ireg &= ~IF_CS_C_S_RX_UPLD_RDY;
        }
 
@@ -678,31 +677,24 @@ sbi_get_int_status_exit:
 
        /* Card has a command result for us */
        if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
-               spin_lock(&priv->adapter->driver_lock);
-               if (!priv->adapter->cur_cmd) {
-                       cmdbuf = priv->upld_buf;
-                       priv->adapter->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY;
-               } else {
-                       cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
-               }
-
-               ret = if_cs_receive_cmdres(priv, cmdbuf, &priv->upld_len);
-               spin_unlock(&priv->adapter->driver_lock);
+               spin_lock(&priv->driver_lock);
+               ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
+               spin_unlock(&priv->driver_lock);
                if (ret < 0)
                        lbs_pr_err("could not receive cmd from card\n");
        }
 
 out:
-       lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->adapter->hisregcpy);
+       lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->hisregcpy);
        return ret;
 }
 
 
-static int if_cs_read_event_cause(wlan_private *priv)
+static int if_cs_read_event_cause(struct lbs_private *priv)
 {
        lbs_deb_enter(LBS_DEB_CS);
 
-       priv->adapter->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5;
+       priv->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5;
        if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_HOST_EVENT);
 
        return 0;
@@ -746,7 +738,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
 static int if_cs_probe(struct pcmcia_device *p_dev)
 {
        int ret = -ENOMEM;
-       wlan_private *priv;
+       struct lbs_private *priv;
        struct if_cs_card *card;
        /* CIS parsing */
        tuple_t tuple;
@@ -856,7 +848,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
                goto out2;
 
        /* Make this card known to the libertas driver */
-       priv = libertas_add_card(card, &p_dev->dev);
+       priv = lbs_add_card(card, &p_dev->dev);
        if (!priv) {
                ret = -ENOMEM;
                goto out2;
@@ -869,7 +861,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        priv->hw_get_int_status   = if_cs_get_int_status;
        priv->hw_read_event_cause = if_cs_read_event_cause;
 
-       priv->adapter->fw_ready = 1;
+       priv->fw_ready = 1;
 
        /* Now actually get the IRQ */
        ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
@@ -885,7 +877,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        if_cs_enable_ints(card);
 
        /* And finally bring the card up */
-       if (libertas_start_card(priv) != 0) {
+       if (lbs_start_card(priv) != 0) {
                lbs_pr_err("could not activate card\n");
                goto out3;
        }
@@ -894,7 +886,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
        goto out;
 
 out3:
-       libertas_remove_card(priv);
+       lbs_remove_card(priv);
 out2:
        ioport_unmap(card->iobase);
 out1:
@@ -917,8 +909,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
 
        lbs_deb_enter(LBS_DEB_CS);
 
-       libertas_stop_card(card->priv);
-       libertas_remove_card(card->priv);
+       lbs_stop_card(card->priv);
+       lbs_remove_card(card->priv);
        if_cs_disable_ints(card);
        if_cs_release(p_dev);
        kfree(card);
@@ -939,7 +931,7 @@ static struct pcmcia_device_id if_cs_ids[] = {
 MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
 
 
-static struct pcmcia_driver libertas_driver = {
+static struct pcmcia_driver lbs_driver = {
        .owner          = THIS_MODULE,
        .drv            = {
                .name   = DRV_NAME,
@@ -955,7 +947,7 @@ static int __init if_cs_init(void)
        int ret;
 
        lbs_deb_enter(LBS_DEB_CS);
-       ret = pcmcia_register_driver(&libertas_driver);
+       ret = pcmcia_register_driver(&lbs_driver);
        lbs_deb_leave(LBS_DEB_CS);
        return ret;
 }
@@ -964,7 +956,7 @@ static int __init if_cs_init(void)
 static void __exit if_cs_exit(void)
 {
        lbs_deb_enter(LBS_DEB_CS);
-       pcmcia_unregister_driver(&libertas_driver);
+       pcmcia_unregister_driver(&lbs_driver);
        lbs_deb_leave(LBS_DEB_CS);
 }
 
index 4f1efb108c28dfa7260ee7f1a1355fa67fccd576..eed73204bcc94719a2620a7ded3705d33c77b4dc 100644 (file)
@@ -19,7 +19,7 @@
  * current block size.
  *
  * As SDIO is still new to the kernel, it is unfortunately common with
- * bugs in the host controllers related to that. One such bug is that 
+ * bugs in the host controllers related to that. One such bug is that
  * controllers cannot do transfers that aren't a multiple of 4 bytes.
  * If you don't have time to fix the host controller driver, you can
  * work around the problem by modifying if_sdio_host_to_card() and
 #include "dev.h"
 #include "if_sdio.h"
 
-static char *libertas_helper_name = NULL;
-module_param_named(helper_name, libertas_helper_name, charp, 0644);
+static char *lbs_helper_name = NULL;
+module_param_named(helper_name, lbs_helper_name, charp, 0644);
 
-static char *libertas_fw_name = NULL;
-module_param_named(fw_name, libertas_fw_name, charp, 0644);
+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) },
@@ -82,7 +82,7 @@ struct if_sdio_packet {
 
 struct if_sdio_card {
        struct sdio_func        *func;
-       wlan_private            *priv;
+       struct lbs_private      *priv;
 
        int                     model;
        unsigned long           ioport;
@@ -134,32 +134,26 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
-       spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+       spin_lock_irqsave(&card->priv->driver_lock, flags);
 
-       if (!card->priv->adapter->cur_cmd) {
-               lbs_deb_sdio("discarding spurious response\n");
-               ret = 0;
-               goto out;
-       }
-
-       if (size > MRVDRV_SIZE_OF_CMD_BUFFER) {
+       if (size > LBS_CMD_BUFFER_SIZE) {
                lbs_deb_sdio("response packet too large (%d bytes)\n",
                        (int)size);
                ret = -E2BIG;
                goto out;
        }
 
-       memcpy(card->priv->adapter->cur_cmd->bufvirtualaddr, buffer, size);
+       memcpy(card->priv->upld_buf, buffer, size);
        card->priv->upld_len = size;
 
        card->int_cause |= MRVDRV_CMD_UPLD_RDY;
 
-       libertas_interrupt(card->priv->dev);
+       lbs_interrupt(card->priv);
 
        ret = 0;
 
 out:
-       spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&card->priv->driver_lock, flags);
 
        lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
@@ -194,7 +188,7 @@ static int if_sdio_handle_data(struct if_sdio_card *card,
 
        memcpy(data, buffer, size);
 
-       libertas_process_rxed_packet(card->priv, skb);
+       lbs_process_rxed_packet(card->priv, skb);
 
        ret = 0;
 
@@ -231,14 +225,14 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
                event <<= SBI_EVENT_CAUSE_SHIFT;
        }
 
-       spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+       spin_lock_irqsave(&card->priv->driver_lock, flags);
 
        card->event = event;
        card->int_cause |= MRVDRV_CARDEVENT;
 
-       libertas_interrupt(card->priv->dev);
+       lbs_interrupt(card->priv);
 
-       spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&card->priv->driver_lock, flags);
 
        ret = 0;
 
@@ -454,7 +448,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
 
                chunk_size = min(size, (size_t)60);
 
-               *((u32*)chunk_buffer) = cpu_to_le32(chunk_size);
+               *((__le32*)chunk_buffer) = cpu_to_le32(chunk_size);
                memcpy(chunk_buffer + 4, firmware, chunk_size);
 /*
                lbs_deb_sdio("sending %d bytes chunk\n", chunk_size);
@@ -694,7 +688,8 @@ out:
 /* Libertas callbacks                                              */
 /*******************************************************************/
 
-static int if_sdio_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
+static int if_sdio_host_to_card(struct lbs_private *priv,
+               u8 type, u8 *buf, u16 nb)
 {
        int ret;
        struct if_sdio_card *card;
@@ -775,7 +770,7 @@ out:
        return ret;
 }
 
-static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg)
+static int if_sdio_get_int_status(struct lbs_private *priv, u8 *ireg)
 {
        struct if_sdio_card *card;
 
@@ -791,7 +786,7 @@ static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg)
        return 0;
 }
 
-static int if_sdio_read_event_cause(wlan_private *priv)
+static int if_sdio_read_event_cause(struct lbs_private *priv)
 {
        struct if_sdio_card *card;
 
@@ -799,7 +794,7 @@ static int if_sdio_read_event_cause(wlan_private *priv)
 
        card = priv->card;
 
-       priv->adapter->eventcause = card->event;
+       priv->eventcause = card->event;
 
        lbs_deb_leave(LBS_DEB_SDIO);
 
@@ -834,12 +829,9 @@ static void if_sdio_interrupt(struct sdio_func *func)
         * Ignore the define name, this really means the card has
         * successfully received the command.
         */
-       if (cause & IF_SDIO_H_INT_DNLD) {
-               if ((card->priv->dnld_sent == DNLD_DATA_SENT) &&
-                       (card->priv->adapter->connect_status == LIBERTAS_CONNECTED))
-                       netif_wake_queue(card->priv->dev);
-               card->priv->dnld_sent = DNLD_RES_RECEIVED;
-       }
+       if (cause & IF_SDIO_H_INT_DNLD)
+               lbs_host_to_card_done(card->priv);
+
 
        if (cause & IF_SDIO_H_INT_UPLD) {
                ret = if_sdio_card_to_host(card);
@@ -857,7 +849,7 @@ static int if_sdio_probe(struct sdio_func *func,
                const struct sdio_device_id *id)
 {
        struct if_sdio_card *card;
-       wlan_private *priv;
+       struct lbs_private *priv;
        int ret, i;
        unsigned int model;
        struct if_sdio_packet *packet;
@@ -905,15 +897,15 @@ static int if_sdio_probe(struct sdio_func *func,
        card->helper = if_sdio_models[i].helper;
        card->firmware = if_sdio_models[i].firmware;
 
-       if (libertas_helper_name) {
+       if (lbs_helper_name) {
                lbs_deb_sdio("overriding helper firmware: %s\n",
-                       libertas_helper_name);
-               card->helper = libertas_helper_name;
+                       lbs_helper_name);
+               card->helper = lbs_helper_name;
        }
 
-       if (libertas_fw_name) {
-               lbs_deb_sdio("overriding firmware: %s\n", libertas_fw_name);
-               card->firmware = libertas_fw_name;
+       if (lbs_fw_name) {
+               lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name);
+               card->firmware = lbs_fw_name;
        }
 
        sdio_claim_host(func);
@@ -951,7 +943,7 @@ static int if_sdio_probe(struct sdio_func *func,
        if (ret)
                goto reclaim;
 
-       priv = libertas_add_card(card, &func->dev);
+       priv = lbs_add_card(card, &func->dev);
        if (!priv) {
                ret = -ENOMEM;
                goto reclaim;
@@ -964,7 +956,7 @@ static int if_sdio_probe(struct sdio_func *func,
        priv->hw_get_int_status = if_sdio_get_int_status;
        priv->hw_read_event_cause = if_sdio_read_event_cause;
 
-       priv->adapter->fw_ready = 1;
+       priv->fw_ready = 1;
 
        /*
         * Enable interrupts now that everything is set up
@@ -975,7 +967,7 @@ static int if_sdio_probe(struct sdio_func *func,
        if (ret)
                goto reclaim;
 
-       ret = libertas_start_card(priv);
+       ret = lbs_start_card(priv);
        if (ret)
                goto err_activate_card;
 
@@ -987,7 +979,7 @@ out:
 err_activate_card:
        flush_scheduled_work();
        free_netdev(priv->dev);
-       kfree(priv->adapter);
+       kfree(priv);
 reclaim:
        sdio_claim_host(func);
 release_int:
@@ -1017,11 +1009,11 @@ static void if_sdio_remove(struct sdio_func *func)
 
        card = sdio_get_drvdata(func);
 
-       card->priv->adapter->surpriseremoved = 1;
+       card->priv->surpriseremoved = 1;
 
        lbs_deb_sdio("call remove card\n");
-       libertas_stop_card(card->priv);
-       libertas_remove_card(card->priv);
+       lbs_stop_card(card->priv);
+       lbs_remove_card(card->priv);
 
        flush_scheduled_work();
 
@@ -1052,7 +1044,7 @@ static struct sdio_driver if_sdio_driver = {
 /* Module functions                                                */
 /*******************************************************************/
 
-static int if_sdio_init_module(void)
+static int __init if_sdio_init_module(void)
 {
        int ret = 0;
 
@@ -1068,7 +1060,7 @@ static int if_sdio_init_module(void)
        return ret;
 }
 
-static void if_sdio_exit_module(void)
+static void __exit if_sdio_exit_module(void)
 {
        lbs_deb_enter(LBS_DEB_SDIO);
 
index dfcaea7b168f6d90a009cc91db04272698fac9b4..533bdfbf5d2af794570e1232e6e23a3052f9d7bc 100644 (file)
@@ -9,8 +9,8 @@
  * your option) any later version.
  */
 
-#ifndef LIBERTAS_IF_SDIO_H
-#define LIBERTAS_IF_SDIO_H
+#ifndef _LBS_IF_SDIO_H
+#define _LBS_IF_SDIO_H
 
 #define IF_SDIO_IOPORT         0x00
 
index cb59f46ed126471816cee87712f89ee32d2cd4ef..75aed9d0736702007725e6fab0ee94b6b39dfeea 100644 (file)
@@ -5,7 +5,6 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/netdevice.h>
-#include <linux/list.h>
 #include <linux/usb.h>
 
 #define DRV_NAME "usb8xxx"
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "cmd.h"
 #include "if_usb.h"
 
-#define MESSAGE_HEADER_LEN     4
-
-static const char usbdriver_name[] = "usb8xxx";
-static u8 *default_fw_name = "usb8388.bin";
+#define INSANEDEBUG    0
+#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
 
-static char *libertas_fw_name = NULL;
-module_param_named(fw_name, libertas_fw_name, charp, 0644);
+#define MESSAGE_HEADER_LEN     4
 
-/*
- * We need to send a RESET command to all USB devices before
- * we tear down the USB connection. Otherwise we would not
- * be able to re-init device the device if the module gets
- * loaded again. This is a list of all initialized USB devices,
- * for the reset code see if_usb_reset_device()
-*/
-static LIST_HEAD(usb_devices);
+static char *lbs_fw_name = "usb8388.bin";
+module_param_named(fw_name, lbs_fw_name, charp, 0644);
 
 static struct usb_device_id if_usb_table[] = {
        /* Enter the device signature inside */
@@ -44,14 +35,16 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
 
 static void if_usb_receive(struct urb *urb);
 static void if_usb_receive_fwload(struct urb *urb);
-static int if_usb_prog_firmware(struct usb_card_rec *cardp);
-static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
-static int if_usb_get_int_status(wlan_private * priv, u8 *);
-static int if_usb_read_event_cause(wlan_private *);
-static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
-static void if_usb_free(struct usb_card_rec *cardp);
-static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
-static int if_usb_reset_device(struct usb_card_rec *cardp);
+static int if_usb_prog_firmware(struct if_usb_card *cardp);
+static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
+                              uint8_t *payload, uint16_t nb);
+static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *);
+static int if_usb_read_event_cause(struct lbs_private *);
+static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
+                       uint16_t nb);
+static void if_usb_free(struct if_usb_card *cardp);
+static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
+static int if_usb_reset_device(struct if_usb_card *cardp);
 
 /**
  *  @brief  call back function to handle the status of the URB
@@ -60,37 +53,22 @@ static int if_usb_reset_device(struct usb_card_rec *cardp);
  */
 static void if_usb_write_bulk_callback(struct urb *urb)
 {
-       struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
+       struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
 
        /* handle the transmission complete validations */
 
        if (urb->status == 0) {
-               wlan_private *priv = cardp->priv;
+               struct lbs_private *priv = cardp->priv;
 
-               /*
-               lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
-               lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
-                      urb->actual_length);
-               */
+               lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
+               lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
+                            urb->actual_length);
 
                /* Used for both firmware TX and regular TX.  priv isn't
                 * valid at firmware load time.
                 */
-               if (priv) {
-                       wlan_adapter *adapter = priv->adapter;
-                       struct net_device *dev = priv->dev;
-
-                       priv->dnld_sent = DNLD_RES_RECEIVED;
-
-                       /* Wake main thread if commands are pending */
-                       if (!adapter->cur_cmd)
-                               wake_up_interruptible(&priv->waitq);
-
-                       if ((adapter->connect_status == LIBERTAS_CONNECTED)) {
-                               netif_wake_queue(dev);
-                               netif_wake_queue(priv->mesh_dev);
-                       }
-               }
+               if (priv)
+                       lbs_host_to_card_done(priv);
        } else {
                /* print the failure status number for debug */
                lbs_pr_info("URB in failure status: %d\n", urb->status);
@@ -101,10 +79,10 @@ static void if_usb_write_bulk_callback(struct urb *urb)
 
 /**
  *  @brief  free tx/rx urb, skb and rx buffer
- *  @param cardp       pointer usb_card_rec
+ *  @param cardp       pointer if_usb_card
  *  @return            N/A
  */
-static void if_usb_free(struct usb_card_rec *cardp)
+static void if_usb_free(struct if_usb_card *cardp)
 {
        lbs_deb_enter(LBS_DEB_USB);
 
@@ -118,12 +96,58 @@ static void if_usb_free(struct usb_card_rec *cardp)
        usb_free_urb(cardp->rx_urb);
        cardp->rx_urb = NULL;
 
-       kfree(cardp->bulk_out_buffer);
-       cardp->bulk_out_buffer = NULL;
+       kfree(cardp->ep_out_buf);
+       cardp->ep_out_buf = NULL;
 
        lbs_deb_leave(LBS_DEB_USB);
 }
 
+static void if_usb_setup_firmware(struct lbs_private *priv)
+{
+       struct if_usb_card *cardp = priv->card;
+       struct cmd_ds_set_boot2_ver b2_cmd;
+       struct cmd_ds_802_11_fw_wake_method wake_method;
+
+       b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
+       b2_cmd.action = 0;
+       b2_cmd.version = cardp->boot2_version;
+
+       if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
+               lbs_deb_usb("Setting boot2 version failed\n");
+
+       priv->wol_gpio = 2; /* Wake via GPIO2... */
+       priv->wol_gap = 20; /* ... after 20ms    */
+       lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
+
+       wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
+       wake_method.action = cpu_to_le16(CMD_ACT_GET);
+       if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
+               lbs_pr_info("Firmware does not seem to support PS mode\n");
+       } else {
+               if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
+                       lbs_deb_usb("Firmware seems to support PS with wake-via-command\n");
+                       priv->ps_supported = 1;
+               } else {
+                       /* The versions which boot up this way don't seem to
+                          work even if we set it to the command interrupt */
+                       lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
+               }
+       }
+}
+
+static void if_usb_fw_timeo(unsigned long priv)
+{
+       struct if_usb_card *cardp = (void *)priv;
+
+       if (cardp->fwdnldover) {
+               lbs_deb_usb("Download complete, no event. Assuming success\n");
+       } else {
+               lbs_pr_err("Download timed out\n");
+               cardp->surprise_removed = 1;
+       }
+       wake_up(&cardp->fw_wq);
+}
+
 /**
  *  @brief sets the configuration values
  *  @param ifnum       interface number
@@ -136,23 +160,26 @@ static int if_usb_probe(struct usb_interface *intf,
        struct usb_device *udev;
        struct usb_host_interface *iface_desc;
        struct usb_endpoint_descriptor *endpoint;
-       wlan_private *priv;
-       struct usb_card_rec *cardp;
+       struct lbs_private *priv;
+       struct if_usb_card *cardp;
        int i;
 
        udev = interface_to_usbdev(intf);
 
-       cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
+       cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
        if (!cardp) {
                lbs_pr_err("Out of memory allocating private data.\n");
                goto error;
        }
 
+       setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
+       init_waitqueue_head(&cardp->fw_wq);
+
        cardp->udev = udev;
        iface_desc = intf->cur_altsetting;
 
        lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
-              " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
+                    " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
                     le16_to_cpu(udev->descriptor.bcdUSB),
                     udev->descriptor.bDeviceClass,
                     udev->descriptor.bDeviceSubClass,
@@ -160,92 +187,62 @@ static int if_usb_probe(struct usb_interface *intf,
 
        for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
                endpoint = &iface_desc->endpoint[i].desc;
-               if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
-                   && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-                       USB_ENDPOINT_XFER_BULK)) {
-                       /* we found a bulk in endpoint */
-                       lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
-                                    le16_to_cpu(endpoint->wMaxPacketSize));
-                       if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
-                               lbs_deb_usbd(&udev->dev,
-                                      "Rx URB allocation failed\n");
-                               goto dealloc;
-                       }
-                       cardp->rx_urb_recall = 0;
-
-                       cardp->bulk_in_size =
-                               le16_to_cpu(endpoint->wMaxPacketSize);
-                       cardp->bulk_in_endpointAddr =
-                           (endpoint->
-                            bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-                       lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
-                              endpoint->bEndpointAddress);
-               }
+               if (usb_endpoint_is_bulk_in(endpoint)) {
+                       cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
+                       cardp->ep_in = usb_endpoint_num(endpoint);
 
-               if (((endpoint->
-                     bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
-                    USB_DIR_OUT)
-                   && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-                       USB_ENDPOINT_XFER_BULK)) {
-                       /* We found bulk out endpoint */
-                       if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
-                               lbs_deb_usbd(&udev->dev,
-                                      "Tx URB allocation failed\n");
-                               goto dealloc;
-                       }
+                       lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
+                       lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
 
-                       cardp->bulk_out_size =
-                               le16_to_cpu(endpoint->wMaxPacketSize);
-                       lbs_deb_usbd(&udev->dev,
-                                    "Bulk out size is %d\n",
-                                    le16_to_cpu(endpoint->wMaxPacketSize));
-                       cardp->bulk_out_endpointAddr =
-                           endpoint->bEndpointAddress;
-                       lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
-                                   endpoint->bEndpointAddress);
-                       cardp->bulk_out_buffer =
-                           kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
-                                   GFP_KERNEL);
-
-                       if (!cardp->bulk_out_buffer) {
-                               lbs_deb_usbd(&udev->dev,
-                                      "Could not allocate buffer\n");
-                               goto dealloc;
-                       }
+               } else if (usb_endpoint_is_bulk_out(endpoint)) {
+                       cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
+                       cardp->ep_out = usb_endpoint_num(endpoint);
+
+                       lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
+                       lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
                }
        }
+       if (!cardp->ep_out_size || !cardp->ep_in_size) {
+               lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
+               goto dealloc;
+       }
+       if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+               lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
+               goto dealloc;
+       }
+       if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+               lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
+               goto dealloc;
+       }
+       cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
+       if (!cardp->ep_out_buf) {
+               lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
+               goto dealloc;
+       }
 
        /* Upload firmware */
-       cardp->rinfo.cardp = cardp;
        if (if_usb_prog_firmware(cardp)) {
-               lbs_deb_usbd(&udev->dev, "FW upload failed");
+               lbs_deb_usbd(&udev->dev, "FW upload failed\n");
                goto err_prog_firmware;
        }
 
-       if (!(priv = libertas_add_card(cardp, &udev->dev)))
+       if (!(priv = lbs_add_card(cardp, &udev->dev)))
                goto err_prog_firmware;
 
        cardp->priv = priv;
-
-       if (libertas_add_mesh(priv, &udev->dev))
-               goto err_add_mesh;
-
-       cardp->eth_dev = priv->dev;
+       cardp->priv->fw_ready = 1;
 
        priv->hw_host_to_card = if_usb_host_to_card;
        priv->hw_get_int_status = if_usb_get_int_status;
        priv->hw_read_event_cause = if_usb_read_event_cause;
-       priv->boot2_version = udev->descriptor.bcdDevice;
+       cardp->boot2_version = udev->descriptor.bcdDevice;
 
-       /* Delay 200 ms to waiting for the FW ready */
        if_usb_submit_rx_urb(cardp);
-       msleep_interruptible(200);
-       priv->adapter->fw_ready = 1;
 
-       if (libertas_start_card(priv))
+       if (lbs_start_card(priv))
                goto err_start_card;
 
-       list_add_tail(&cardp->list, &usb_devices);
+       if_usb_setup_firmware(priv);
 
        usb_get_dev(udev);
        usb_set_intfdata(intf, cardp);
@@ -253,9 +250,7 @@ static int if_usb_probe(struct usb_interface *intf,
        return 0;
 
 err_start_card:
-       libertas_remove_mesh(priv);
-err_add_mesh:
-       libertas_remove_card(priv);
+       lbs_remove_card(priv);
 err_prog_firmware:
        if_usb_reset_device(cardp);
 dealloc:
@@ -272,23 +267,17 @@ error:
  */
 static void if_usb_disconnect(struct usb_interface *intf)
 {
-       struct usb_card_rec *cardp = usb_get_intfdata(intf);
-       wlan_private *priv = (wlan_private *) cardp->priv;
+       struct if_usb_card *cardp = usb_get_intfdata(intf);
+       struct lbs_private *priv = (struct lbs_private *) cardp->priv;
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       /* Update Surprise removed to TRUE */
        cardp->surprise_removed = 1;
 
-       list_del(&cardp->list);
-
        if (priv) {
-               wlan_adapter *adapter = priv->adapter;
-
-               adapter->surpriseremoved = 1;
-               libertas_stop_card(priv);
-               libertas_remove_mesh(priv);
-               libertas_remove_card(priv);
+               priv->surpriseremoved = 1;
+               lbs_stop_card(priv);
+               lbs_remove_card(priv);
        }
 
        /* Unlink and free urb */
@@ -302,102 +291,82 @@ static void if_usb_disconnect(struct usb_interface *intf)
 
 /**
  *  @brief  This function download FW
- *  @param priv                pointer to wlan_private
+ *  @param priv                pointer to struct lbs_private
  *  @return            0
  */
-static int if_prog_firmware(struct usb_card_rec *cardp)
+static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
 {
-       struct FWData *fwdata;
-       struct fwheader *fwheader;
-       u8 *firmware = cardp->fw->data;
-
-       fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
-
-       if (!fwdata)
-               return -1;
-
-       fwheader = &fwdata->fwheader;
+       struct fwdata *fwdata = cardp->ep_out_buf;
+       uint8_t *firmware = cardp->fw->data;
 
+       /* If we got a CRC failure on the last block, back
+          up and retry it */
        if (!cardp->CRC_OK) {
                cardp->totalbytes = cardp->fwlastblksent;
-               cardp->fwseqnum = cardp->lastseqnum - 1;
+               cardp->fwseqnum--;
        }
 
-       /*
-       lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
-                   cardp->totalbytes);
-       */
+       lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
+                    cardp->totalbytes);
 
-       memcpy(fwheader, &firmware[cardp->totalbytes],
+       /* struct fwdata (which we sent to the card) has an
+          extra __le32 field in between the header and the data,
+          which is not in the struct fwheader in the actual
+          firmware binary. Insert the seqnum in the middle... */
+       memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
               sizeof(struct fwheader));
 
        cardp->fwlastblksent = cardp->totalbytes;
        cardp->totalbytes += sizeof(struct fwheader);
 
-       /* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
        memcpy(fwdata->data, &firmware[cardp->totalbytes],
-              le32_to_cpu(fwdata->fwheader.datalength));
+              le32_to_cpu(fwdata->hdr.datalength));
 
-       /*
-       lbs_deb_usbd(&cardp->udev->dev,
-                   "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
-       */
+       lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
+                    le32_to_cpu(fwdata->hdr.datalength));
 
-       cardp->fwseqnum = cardp->fwseqnum + 1;
+       fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
+       cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
 
-       fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
-       cardp->lastseqnum = cardp->fwseqnum;
-       cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
+       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
+                    le32_to_cpu(fwdata->hdr.datalength));
+
+       if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
+               lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
+               lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
+                            cardp->fwseqnum, cardp->totalbytes);
+       } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
+               lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
+               lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
 
-       if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
-               /*
-               lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
-                           cardp->totalbytes);
-               */
-               memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-               usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
-
-       } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
-               /*
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "Host has finished FW downloading\n");
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "Donwloading FW JUMP BLOCK\n");
-               */
-               memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-               usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
                cardp->fwfinalblk = 1;
        }
 
-       /*
-       lbs_deb_usbd(&cardp->udev->dev,
-                   "The firmware download is done size is %d\n",
-                   cardp->totalbytes);
-       */
-
-       kfree(fwdata);
+       lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
+                    cardp->totalbytes);
 
        return 0;
 }
 
-static int if_usb_reset_device(struct usb_card_rec *cardp)
+static int if_usb_reset_device(struct if_usb_card *cardp)
 {
+       struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
        int ret;
-       wlan_private * priv = cardp->priv;
 
        lbs_deb_enter(LBS_DEB_USB);
 
-       /* Try a USB port reset first, if that fails send the reset
-        * command to the firmware.
-        */
+       *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
+
+       cmd->command = cpu_to_le16(CMD_802_11_RESET);
+       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
+       cmd->result = cpu_to_le16(0);
+       cmd->seqnum = cpu_to_le16(0x5a5a);
+       cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
+       usb_tx_block(cardp, cardp->ep_out_buf, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
+
+       msleep(100);
        ret = usb_reset_device(cardp->udev);
-       if (!ret && priv) {
-               msleep(10);
-               ret = libertas_reset_device(priv);
-               msleep(10);
-       }
+       msleep(100);
 
        lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
 
@@ -406,12 +375,12 @@ static int if_usb_reset_device(struct usb_card_rec *cardp)
 
 /**
  *  @brief This function transfer the data to the device.
- *  @param priv        pointer to wlan_private
+ *  @param priv        pointer to struct lbs_private
  *  @param payload     pointer to payload data
  *  @param nb          data length
  *  @return            0 or -1
  */
-static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
+static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
 {
        int ret = -1;
 
@@ -423,17 +392,16 @@ static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
 
        usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
                          usb_sndbulkpipe(cardp->udev,
-                                         cardp->bulk_out_endpointAddr),
+                                         cardp->ep_out),
                          payload, nb, if_usb_write_bulk_callback, cardp);
 
        cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
 
        if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
-               /*  transfer failed */
-               lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
+               lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
                ret = -1;
        } else {
-               /* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
+               lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
                ret = 0;
        }
 
@@ -441,11 +409,10 @@ tx_ret:
        return ret;
 }
 
-static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
+static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
                                  void (*callbackfn)(struct urb *urb))
 {
        struct sk_buff *skb;
-       struct read_cb_info *rinfo = &cardp->rinfo;
        int ret = -1;
 
        if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
@@ -453,25 +420,25 @@ static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
                goto rx_ret;
        }
 
-       rinfo->skb = skb;
+       cardp->rx_skb = skb;
 
        /* Fill the receive configuration URB and initialise the Rx call back */
        usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
-                         usb_rcvbulkpipe(cardp->udev,
-                                         cardp->bulk_in_endpointAddr),
+                         usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
                          (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
                          MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
-                         rinfo);
+                         cardp);
 
        cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
 
-       /* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
+       lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
        if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
-               /* handle failure conditions */
-               lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
+               lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
+               kfree_skb(skb);
+               cardp->rx_skb = NULL;
                ret = -1;
        } else {
-               /* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
+               lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
                ret = 0;
        }
 
@@ -479,58 +446,78 @@ rx_ret:
        return ret;
 }
 
-static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
+static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
 {
        return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
 }
 
-static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
+static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
 {
        return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
 }
 
 static void if_usb_receive_fwload(struct urb *urb)
 {
-       struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-       struct sk_buff *skb = rinfo->skb;
-       struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
+       struct if_usb_card *cardp = urb->context;
+       struct sk_buff *skb = cardp->rx_skb;
        struct fwsyncheader *syncfwheader;
-       struct bootcmdrespStr bootcmdresp;
+       struct bootcmdresp bootcmdresp;
 
        if (urb->status) {
                lbs_deb_usbd(&cardp->udev->dev,
-                           "URB status is failed during fw load\n");
+                            "URB status is failed during fw load\n");
                kfree_skb(skb);
                return;
        }
 
-       if (cardp->bootcmdresp == 0) {
+       if (cardp->fwdnldover) {
+               __le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
+
+               if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
+                   tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
+                       lbs_pr_info("Firmware ready event received\n");
+                       wake_up(&cardp->fw_wq);
+               } else {
+                       lbs_deb_usb("Waiting for confirmation; got %x %x\n",
+                                   le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
+                       if_usb_submit_rx_urb_fwload(cardp);
+               }
+               kfree_skb(skb);
+               return;
+       }
+       if (cardp->bootcmdresp <= 0) {
                memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
                        sizeof(bootcmdresp));
+
                if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
                        kfree_skb(skb);
                        if_usb_submit_rx_urb_fwload(cardp);
                        cardp->bootcmdresp = 1;
                        lbs_deb_usbd(&cardp->udev->dev,
-                                   "Received valid boot command response\n");
+                                    "Received valid boot command response\n");
                        return;
                }
-               if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
-                       lbs_pr_info(
-                               "boot cmd response wrong magic number (0x%x)\n",
-                               le32_to_cpu(bootcmdresp.u32magicnumber));
-               } else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
-                       lbs_pr_info(
-                               "boot cmd response cmd_tag error (%d)\n",
-                               bootcmdresp.u8cmd_tag);
-               } else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
-                       lbs_pr_info(
-                               "boot cmd response result error (%d)\n",
-                               bootcmdresp.u8result);
+               if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
+                       if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
+                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
+                           bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
+                               if (!cardp->bootcmdresp)
+                                       lbs_pr_info("Firmware already seems alive; resetting\n");
+                               cardp->bootcmdresp = -1;
+                       } else {
+                               lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
+                                           le32_to_cpu(bootcmdresp.magic));
+                       }
+               } else if (bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
+                       lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
+                                   bootcmdresp.cmd);
+               } else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
+                       lbs_pr_info("boot cmd response result error (%d)\n",
+                                   bootcmdresp.result);
                } else {
                        cardp->bootcmdresp = 1;
                        lbs_deb_usbd(&cardp->udev->dev,
-                                   "Received valid boot command response\n");
+                                    "Received valid boot command response\n");
                }
                kfree_skb(skb);
                if_usb_submit_rx_urb_fwload(cardp);
@@ -545,50 +532,47 @@ static void if_usb_receive_fwload(struct urb *urb)
        }
 
        memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
-                       sizeof(struct fwsyncheader));
+              sizeof(struct fwsyncheader));
 
        if (!syncfwheader->cmd) {
-               /*
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "FW received Blk with correct CRC\n");
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "FW received Blk seqnum = %d\n",
-                      syncfwheader->seqnum);
-               */
+               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
+               lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
+                            le32_to_cpu(syncfwheader->seqnum));
                cardp->CRC_OK = 1;
        } else {
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "FW received Blk with CRC error\n");
+               lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
                cardp->CRC_OK = 0;
        }
 
        kfree_skb(skb);
 
+       /* reschedule timer for 200ms hence */
+       mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));
+
        if (cardp->fwfinalblk) {
                cardp->fwdnldover = 1;
                goto exit;
        }
 
-       if_prog_firmware(cardp);
+       if_usb_send_fw_pkt(cardp);
 
+ exit:
        if_usb_submit_rx_urb_fwload(cardp);
-exit:
+
        kfree(syncfwheader);
 
        return;
-
 }
 
 #define MRVDRV_MIN_PKT_LEN     30
 
 static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
-                                      struct usb_card_rec *cardp,
-                                      wlan_private *priv)
+                                      struct if_usb_card *cardp,
+                                      struct lbs_private *priv)
 {
-       if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
-           MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
-               lbs_deb_usbd(&cardp->udev->dev,
-                           "Packet length is Invalid\n");
+       if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
+           || recvlength < MRVDRV_MIN_PKT_LEN) {
+               lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
                kfree_skb(skb);
                return;
        }
@@ -596,19 +580,19 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
        skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
        skb_put(skb, recvlength);
        skb_pull(skb, MESSAGE_HEADER_LEN);
-       libertas_process_rxed_packet(priv, skb);
+
+       lbs_process_rxed_packet(priv, skb);
        priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
 }
 
-static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
+static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
                                      struct sk_buff *skb,
-                                     struct usb_card_rec *cardp,
-                                     wlan_private *priv)
+                                     struct if_usb_card *cardp,
+                                     struct lbs_private *priv)
 {
-       u8 *cmdbuf;
-       if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
+       if (recvlength > LBS_CMD_BUFFER_SIZE) {
                lbs_deb_usbd(&cardp->udev->dev,
-                           "The receive buffer is too large\n");
+                            "The receive buffer is too large\n");
                kfree_skb(skb);
                return;
        }
@@ -616,28 +600,17 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
        if (!in_interrupt())
                BUG();
 
-       spin_lock(&priv->adapter->driver_lock);
-       /* take care of cur_cmd = NULL case by reading the
-        * data to clear the interrupt */
-       if (!priv->adapter->cur_cmd) {
-               cmdbuf = priv->upld_buf;
-               priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
-       } else
-               cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
-
+       spin_lock(&priv->driver_lock);
        cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
        priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
-       memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
-              priv->upld_len);
+       memcpy(priv->upld_buf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
 
        kfree_skb(skb);
-       libertas_interrupt(priv->dev);
-       spin_unlock(&priv->adapter->driver_lock);
+       lbs_interrupt(priv);
+       spin_unlock(&priv->driver_lock);
 
        lbs_deb_usbd(&cardp->udev->dev,
                    "Wake up main thread to handle cmd response\n");
-
-       return;
 }
 
 /**
@@ -649,35 +622,33 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
  */
 static void if_usb_receive(struct urb *urb)
 {
-       struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-       struct sk_buff *skb = rinfo->skb;
-       struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
-       wlan_private * priv = cardp->priv;
-
+       struct if_usb_card *cardp = urb->context;
+       struct sk_buff *skb = cardp->rx_skb;
+       struct lbs_private *priv = cardp->priv;
        int recvlength = urb->actual_length;
-       u8 *recvbuff = NULL;
-       u32 recvtype = 0;
+       uint8_t *recvbuff = NULL;
+       uint32_t recvtype = 0;
+       __le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
 
        lbs_deb_enter(LBS_DEB_USB);
 
        if (recvlength) {
-               __le32 tmp;
-
                if (urb->status) {
-                       lbs_deb_usbd(&cardp->udev->dev,
-                                   "URB status is failed\n");
+                       lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
+                                    urb->status);
                        kfree_skb(skb);
                        goto setup_for_next;
                }
 
                recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
-               memcpy(&tmp, recvbuff, sizeof(u32));
-               recvtype = le32_to_cpu(tmp);
+               recvtype = le32_to_cpu(pkt[0]);
                lbs_deb_usbd(&cardp->udev->dev,
                            "Recv length = 0x%x, Recv type = 0x%X\n",
                            recvlength, recvtype);
-       } else if (urb->status)
+       } else if (urb->status) {
+               kfree_skb(skb);
                goto rx_exit;
+       }
 
        switch (recvtype) {
        case CMD_TYPE_DATA:
@@ -690,24 +661,28 @@ static void if_usb_receive(struct urb *urb)
 
        case CMD_TYPE_INDICATION:
                /* Event cause handling */
-               spin_lock(&priv->adapter->driver_lock);
-               cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
+               spin_lock(&priv->driver_lock);
+
+               cardp->usb_event_cause = le32_to_cpu(pkt[1]);
+
                lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
-                           cardp->usb_event_cause);
+                            cardp->usb_event_cause);
+
+               /* Icky undocumented magic special case */
                if (cardp->usb_event_cause & 0xffff0000) {
-                       libertas_send_tx_feedback(priv);
-                       spin_unlock(&priv->adapter->driver_lock);
+                       lbs_send_tx_feedback(priv);
+                       spin_unlock(&priv->driver_lock);
                        break;
                }
                cardp->usb_event_cause <<= 3;
                cardp->usb_int_cause |= MRVDRV_CARDEVENT;
                kfree_skb(skb);
-               libertas_interrupt(priv->dev);
-               spin_unlock(&priv->adapter->driver_lock);
+               lbs_interrupt(priv);
+               spin_unlock(&priv->driver_lock);
                goto rx_exit;
        default:
                lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
-                            recvtype);
+                            recvtype);
                kfree_skb(skb);
                break;
        }
@@ -720,58 +695,54 @@ rx_exit:
 
 /**
  *  @brief This function downloads data to FW
- *  @param priv                pointer to wlan_private structure
+ *  @param priv                pointer to struct lbs_private structure
  *  @param type                type of data
  *  @param buf         pointer to data buffer
  *  @param len         number of bytes
  *  @return            0 or -1
  */
-static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
+static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
+                              uint8_t *payload, uint16_t nb)
 {
-       struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
+       struct if_usb_card *cardp = priv->card;
 
        lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
        lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
 
        if (type == MVMS_CMD) {
-               __le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
+               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
                priv->dnld_sent = DNLD_CMD_SENT;
-               memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
-                      MESSAGE_HEADER_LEN);
-
        } else {
-               __le32 tmp = cpu_to_le32(CMD_TYPE_DATA);
+               *(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
                priv->dnld_sent = DNLD_DATA_SENT;
-               memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
-                      MESSAGE_HEADER_LEN);
        }
 
-       memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
+       memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
 
-       return usb_tx_block(cardp, cardp->bulk_out_buffer,
-                           nb + MESSAGE_HEADER_LEN);
+       return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
 }
 
-/* called with adapter->driver_lock held */
-static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
+/* called with priv->driver_lock held */
+static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *ireg)
 {
-       struct usb_card_rec *cardp = priv->card;
+       struct if_usb_card *cardp = priv->card;
 
        *ireg = cardp->usb_int_cause;
        cardp->usb_int_cause = 0;
 
-       lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
+       lbs_deb_usbd(&cardp->udev->dev, "Int cause is 0x%X\n", *ireg);
 
        return 0;
 }
 
-static int if_usb_read_event_cause(wlan_private * priv)
+static int if_usb_read_event_cause(struct lbs_private *priv)
 {
-       struct usb_card_rec *cardp = priv->card;
+       struct if_usb_card *cardp = priv->card;
 
-       priv->adapter->eventcause = cardp->usb_event_cause;
+       priv->eventcause = cardp->usb_event_cause;
        /* Re-submit rx urb here to avoid event lost issue */
        if_usb_submit_rx_urb(cardp);
+
        return 0;
 }
 
@@ -781,20 +752,17 @@ static int if_usb_read_event_cause(wlan_private * priv)
  *                  2:Boot from FW in EEPROM
  *  @return            0
  */
-static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
+static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
 {
-       struct bootcmdstr sbootcmd;
-       int i;
+       struct bootcmd *bootcmd = cardp->ep_out_buf;
 
        /* Prepare command */
-       sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
-       sbootcmd.u8cmd_tag = ivalue;
-       for (i=0; i<11; i++)
-               sbootcmd.au8dumy[i]=0x00;
-       memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
+       bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
+       bootcmd->cmd = ivalue;
+       memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
 
        /* Issue command */
-       usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
+       usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
 
        return 0;
 }
@@ -807,10 +775,10 @@ static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
  *         len               image length
  *  @return     0 or -1
  */
-static int check_fwfile_format(u8 *data, u32 totlen)
+static int check_fwfile_format(uint8_t *data, uint32_t totlen)
 {
-       u32 bincmd, exit;
-       u32 blksize, offset, len;
+       uint32_t bincmd, exit;
+       uint32_t blksize, offset, len;
        int ret;
 
        ret = 1;
@@ -848,7 +816,7 @@ static int check_fwfile_format(u8 *data, u32 totlen)
 }
 
 
-static int if_usb_prog_firmware(struct usb_card_rec *cardp)
+static int if_usb_prog_firmware(struct if_usb_card *cardp)
 {
        int i = 0;
        static int reset_count = 10;
@@ -856,10 +824,10 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp)
 
        lbs_deb_enter(LBS_DEB_USB);
 
-       if ((ret = request_firmware(&cardp->fw, libertas_fw_name,
+       if ((ret = request_firmware(&cardp->fw, lbs_fw_name,
                                    &cardp->udev->dev)) < 0) {
                lbs_pr_err("request_firmware() failed with %#x\n", ret);
-               lbs_pr_err("firmware %s not found\n", libertas_fw_name);
+               lbs_pr_err("firmware %s not found\n", lbs_fw_name);
                goto done;
        }
 
@@ -886,7 +854,7 @@ restart:
                } while (cardp->bootcmdresp == 0 && j < 10);
        } while (cardp->bootcmdresp == 0 && i < 5);
 
-       if (cardp->bootcmdresp == 0) {
+       if (cardp->bootcmdresp <= 0) {
                if (--reset_count >= 0) {
                        if_usb_reset_device(cardp);
                        goto restart;
@@ -904,15 +872,14 @@ restart:
        cardp->totalbytes = 0;
        cardp->fwfinalblk = 0;
 
-       if_prog_firmware(cardp);
+       /* Send the first firmware packet... */
+       if_usb_send_fw_pkt(cardp);
 
-       do {
-               lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
-               i++;
-               msleep_interruptible(100);
-               if (cardp->surprise_removed || i >= 20)
-                       break;
-       } while (!cardp->fwdnldover);
+       /* ... and wait for the process to complete */
+       wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
+
+       del_timer_sync(&cardp->fw_timeout);
+       usb_kill_urb(cardp->rx_urb);
 
        if (!cardp->fwdnldover) {
                lbs_pr_info("failed to load fw, resetting device!\n");
@@ -926,11 +893,11 @@ restart:
                goto release_fw;
        }
 
-release_fw:
+ release_fw:
        release_firmware(cardp->fw);
        cardp->fw = NULL;
 
-done:
+ done:
        lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
        return ret;
 }
@@ -939,66 +906,38 @@ done:
 #ifdef CONFIG_PM
 static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {
-       struct usb_card_rec *cardp = usb_get_intfdata(intf);
-       wlan_private *priv = cardp->priv;
+       struct if_usb_card *cardp = usb_get_intfdata(intf);
+       struct lbs_private *priv = cardp->priv;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_USB);
 
-       if (priv->adapter->psstate != PS_STATE_FULL_POWER)
+       if (priv->psstate != PS_STATE_FULL_POWER)
                return -1;
 
-       if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-               /* Mesh autostart must be activated while sleeping
-                * On resume it will go back to the current state
-                */
-               struct cmd_ds_mesh_access mesh_access;
-               memset(&mesh_access, 0, sizeof(mesh_access));
-               mesh_access.data[0] = cpu_to_le32(1);
-               libertas_prepare_and_send_command(priv,
-                               CMD_MESH_ACCESS,
-                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-       }
-
-       netif_device_detach(cardp->eth_dev);
-       netif_device_detach(priv->mesh_dev);
+       ret = lbs_suspend(priv);
+       if (ret)
+               goto out;
 
        /* Unlink tx & rx urb */
        usb_kill_urb(cardp->tx_urb);
        usb_kill_urb(cardp->rx_urb);
 
-       cardp->rx_urb_recall = 1;
-
+ out:
        lbs_deb_leave(LBS_DEB_USB);
-       return 0;
+       return ret;
 }
 
 static int if_usb_resume(struct usb_interface *intf)
 {
-       struct usb_card_rec *cardp = usb_get_intfdata(intf);
-       wlan_private *priv = cardp->priv;
+       struct if_usb_card *cardp = usb_get_intfdata(intf);
+       struct lbs_private *priv = cardp->priv;
 
        lbs_deb_enter(LBS_DEB_USB);
 
-       cardp->rx_urb_recall = 0;
-
-       if_usb_submit_rx_urb(cardp->priv);
+       if_usb_submit_rx_urb(cardp);
 
-       netif_device_attach(cardp->eth_dev);
-       netif_device_attach(priv->mesh_dev);
-
-       if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-               /* Mesh autostart was activated while sleeping
-                * Disable it if appropriate
-                */
-               struct cmd_ds_mesh_access mesh_access;
-               memset(&mesh_access, 0, sizeof(mesh_access));
-               mesh_access.data[0] = cpu_to_le32(0);
-               libertas_prepare_and_send_command(priv,
-                               CMD_MESH_ACCESS,
-                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-       }
+       lbs_resume(priv);
 
        lbs_deb_leave(LBS_DEB_USB);
        return 0;
@@ -1009,46 +948,30 @@ static int if_usb_resume(struct usb_interface *intf)
 #endif
 
 static struct usb_driver if_usb_driver = {
-       /* driver name */
-       .name = usbdriver_name,
-       /* probe function name */
+       .name = DRV_NAME,
        .probe = if_usb_probe,
-       /* disconnect function  name */
        .disconnect = if_usb_disconnect,
-       /* device signature table */
        .id_table = if_usb_table,
        .suspend = if_usb_suspend,
        .resume = if_usb_resume,
 };
 
-static int if_usb_init_module(void)
+static int __init if_usb_init_module(void)
 {
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       if (libertas_fw_name == NULL) {
-               libertas_fw_name = default_fw_name;
-       }
-
        ret = usb_register(&if_usb_driver);
 
        lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
 }
 
-static void if_usb_exit_module(void)
+static void __exit if_usb_exit_module(void)
 {
-       struct usb_card_rec *cardp, *cardp_temp;
-
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list) {
-               libertas_prepare_and_send_command(cardp->priv, CMD_802_11_RESET,
-                                                 CMD_ACT_HALT, 0, 0, NULL);
-       }
-
-       /* API unregisters the driver from USB subsystem */
        usb_deregister(&if_usb_driver);
 
        lbs_deb_leave(LBS_DEB_MAIN);
@@ -1058,5 +981,5 @@ module_init(if_usb_init_module);
 module_exit(if_usb_exit_module);
 
 MODULE_DESCRIPTION("8388 USB WLAN Driver");
-MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
 MODULE_LICENSE("GPL");
index e07a10ed28b5d34447ab28cd97d9be71faea8f73..e4829a391eb9be7ed39688eb1cc5e04eadd14168 100644 (file)
@@ -1,79 +1,76 @@
-#ifndef _LIBERTAS_IF_USB_H
-#define _LIBERTAS_IF_USB_H
+#ifndef _LBS_IF_USB_H
+#define _LBS_IF_USB_H
 
-#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/timer.h>
+
+struct lbs_private;
 
 /**
   * This file contains definition for USB interface.
   */
-#define CMD_TYPE_REQUEST                0xF00DFACE
-#define CMD_TYPE_DATA                   0xBEADC0DE
-#define CMD_TYPE_INDICATION             0xBEEFFACE
+#define CMD_TYPE_REQUEST               0xF00DFACE
+#define CMD_TYPE_DATA                  0xBEADC0DE
+#define CMD_TYPE_INDICATION            0xBEEFFACE
 
-#define IPFIELD_ALIGN_OFFSET   2
+#define IPFIELD_ALIGN_OFFSET           2
 
-#define BOOT_CMD_FW_BY_USB     0x01
-#define BOOT_CMD_FW_IN_EEPROM  0x02
-#define BOOT_CMD_UPDATE_BOOT2  0x03
-#define BOOT_CMD_UPDATE_FW     0x04
-#define BOOT_CMD_MAGIC_NUMBER  0x4C56524D   /* M=>0x4D,R=>0x52,V=>0x56,L=>0x4C */
+#define BOOT_CMD_FW_BY_USB             0x01
+#define BOOT_CMD_FW_IN_EEPROM          0x02
+#define BOOT_CMD_UPDATE_BOOT2          0x03
+#define BOOT_CMD_UPDATE_FW             0x04
+#define BOOT_CMD_MAGIC_NUMBER          0x4C56524D   /* LVRM */
 
-struct bootcmdstr
+struct bootcmd
 {
-       __le32 u32magicnumber;
-       u8  u8cmd_tag;
-       u8  au8dumy[11];
+       __le32  magic;
+       uint8_t cmd;
+       uint8_t pad[11];
 };
 
-#define BOOT_CMD_RESP_OK     0x0001
-#define BOOT_CMD_RESP_FAIL   0x0000
+#define BOOT_CMD_RESP_OK               0x0001
+#define BOOT_CMD_RESP_FAIL             0x0000
 
-struct bootcmdrespStr
+struct bootcmdresp
 {
-       __le32 u32magicnumber;
-       u8  u8cmd_tag;
-       u8  u8result;
-       u8  au8dumy[2];
-};
-
-/* read callback private data */
-struct read_cb_info {
-        struct usb_card_rec *cardp;
-        struct sk_buff *skb;
+       __le32  magic;
+       uint8_t cmd;
+       uint8_t result;
+       uint8_t pad[2];
 };
 
 /** USB card description structure*/
-struct usb_card_rec {
-       struct list_head list;
-       struct net_device *eth_dev;
+struct if_usb_card {
        struct usb_device *udev;
        struct urb *rx_urb, *tx_urb;
-       void *priv;
-       struct read_cb_info rinfo;
+       struct lbs_private *priv;
 
-       int bulk_in_size;
-       u8 bulk_in_endpointAddr;
+       struct sk_buff *rx_skb;
+       uint32_t usb_event_cause;
+       uint8_t usb_int_cause;
 
-       u8 *bulk_out_buffer;
-       int bulk_out_size;
-       u8 bulk_out_endpointAddr;
+       uint8_t ep_in;
+       uint8_t ep_out;
 
-       const struct firmware *fw;
-       u8 CRC_OK;
-       u32 fwseqnum;
-       u32 lastseqnum;
-       u32 totalbytes;
-       u32 fwlastblksent;
-       u8 fwdnldover;
-       u8 fwfinalblk;
-       u8 surprise_removed;
+       int8_t bootcmdresp;
 
-       u32 usb_event_cause;
-       u8 usb_int_cause;
+       int ep_in_size;
 
-       u8 rx_urb_recall;
+       void *ep_out_buf;
+       int ep_out_size;
 
-       u8 bootcmdresp;
+       const struct firmware *fw;
+       struct timer_list fw_timeout;
+       wait_queue_head_t fw_wq;
+       uint32_t fwseqnum;
+       uint32_t totalbytes;
+       uint32_t fwlastblksent;
+       uint8_t CRC_OK;
+       uint8_t fwdnldover;
+       uint8_t fwfinalblk;
+       uint8_t surprise_removed;
+
+       __le16 boot2_version;
 };
 
 /** fwheader */
@@ -86,10 +83,10 @@ struct fwheader {
 
 #define FW_MAX_DATA_BLK_SIZE   600
 /** FWData */
-struct FWData {
-       struct fwheader fwheader;
+struct fwdata {
+       struct fwheader hdr;
        __le32 seqnum;
-       u8 data[FW_MAX_DATA_BLK_SIZE];
+       uint8_t data[0];
 };
 
 /** fwsyncheader */
@@ -101,7 +98,5 @@ struct fwsyncheader {
 #define FW_HAS_DATA_TO_RECV            0x00000001
 #define FW_HAS_LAST_BLOCK              0x00000004
 
-#define FW_DATA_XMIT_SIZE \
-       sizeof(struct fwheader) + le32_to_cpu(fwdata->fwheader.datalength) + sizeof(u32)
 
 #endif
index dc24a05c9447557d72f3443020e8e00ef0cbc701..2d4508048b68fe38029dd3d82156dad73aaa44ab 100644 (file)
  * NOTE: Setting the MSB of the basic rates need to be taken
  *   care, either before or after calling this function
  *
- *  @param adapter     A pointer to wlan_adapter structure
+ *  @param priv     A pointer to struct lbs_private structure
  *  @param rate1       the buffer which keeps input and output
  *  @param rate1_size  the size of rate1 buffer; new size of buffer on return
  *
  *  @return            0 or -1
  */
-static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size)
+static int get_common_rates(struct lbs_private *priv,
+       u8 *rates,
+       u16 *rates_size)
 {
-       u8 *card_rates = libertas_bg_rates;
-       size_t num_card_rates = sizeof(libertas_bg_rates);
+       u8 *card_rates = lbs_bg_rates;
+       size_t num_card_rates = sizeof(lbs_bg_rates);
        int ret = 0, i, j;
        u8 tmp[30];
        size_t tmp_size = 0;
@@ -55,15 +57,15 @@ static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size)
        lbs_deb_hex(LBS_DEB_JOIN, "AP rates    ", rates, *rates_size);
        lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", card_rates, num_card_rates);
        lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
-       lbs_deb_join("Tx datarate is currently 0x%X\n", adapter->cur_rate);
+       lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
 
-       if (!adapter->auto_rate) {
+       if (!priv->auto_rate) {
                for (i = 0; i < tmp_size; i++) {
-                       if (tmp[i] == adapter->cur_rate)
+                       if (tmp[i] == priv->cur_rate)
                                goto done;
                }
                lbs_pr_alert("Previously set fixed data rate %#x isn't "
-                      "compatible with the network.\n", adapter->cur_rate);
+                      "compatible with the network.\n", priv->cur_rate);
                ret = -1;
                goto done;
        }
@@ -85,7 +87,7 @@ done:
  *  @param rates     buffer of data rates
  *  @param len       size of buffer
  */
-static void libertas_set_basic_rate_flags(u8 * rates, size_t len)
+static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
 {
        int i;
 
@@ -104,7 +106,7 @@ static void libertas_set_basic_rate_flags(u8 * rates, size_t len)
  *  @param rates     buffer of data rates
  *  @param len       size of buffer
  */
-void libertas_unset_basic_rate_flags(u8 * rates, size_t len)
+void lbs_unset_basic_rate_flags(u8 *rates, size_t len)
 {
        int i;
 
@@ -116,19 +118,18 @@ void libertas_unset_basic_rate_flags(u8 * rates, size_t len)
 /**
  *  @brief Associate to a specific BSS discovered in a scan
  *
- *  @param priv      A pointer to wlan_private structure
+ *  @param priv      A pointer to struct lbs_private structure
  *  @param pbssdesc  Pointer to the BSS descriptor to associate with.
  *
  *  @return          0-success, otherwise fail
  */
-int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
+int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret;
 
-       lbs_deb_enter(LBS_DEB_JOIN);
+       lbs_deb_enter(LBS_DEB_ASSOC);
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
                                    0, CMD_OPTION_WAITFORRSP,
                                    0, assoc_req->bss.bssid);
 
@@ -136,50 +137,50 @@ int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req)
                goto done;
 
        /* set preamble to firmware */
-       if (   (adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+       if (   (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
            && (assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
-               adapter->preamble = CMD_TYPE_SHORT_PREAMBLE;
+               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
        else
-               adapter->preamble = CMD_TYPE_LONG_PREAMBLE;
+               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
 
-       libertas_set_radio_control(priv);
+       lbs_set_radio_control(priv);
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
                                    0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
 
 done:
-       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
 /**
  *  @brief Start an Adhoc Network
  *
- *  @param priv         A pointer to wlan_private structure
+ *  @param priv         A pointer to struct lbs_private structure
  *  @param adhocssid    The ssid of the Adhoc Network
  *  @return             0--success, -1--fail
  */
-int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
+int lbs_start_adhoc_network(struct lbs_private *priv,
+       struct assoc_request *assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
-       adapter->adhoccreate = 1;
+       priv->adhoccreate = 1;
 
-       if (adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
+       if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
                lbs_deb_join("AdhocStart: Short preamble\n");
-               adapter->preamble = CMD_TYPE_SHORT_PREAMBLE;
+               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
        } else {
                lbs_deb_join("AdhocStart: Long preamble\n");
-               adapter->preamble = CMD_TYPE_LONG_PREAMBLE;
+               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
        }
 
-       libertas_set_radio_control(priv);
+       lbs_set_radio_control(priv);
 
        lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
        lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
                                    0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
 
        return ret;
@@ -188,34 +189,34 @@ int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * ass
 /**
  *  @brief Join an adhoc network found in a previous scan
  *
- *  @param priv         A pointer to wlan_private structure
+ *  @param priv         A pointer to struct lbs_private structure
  *  @param pbssdesc     Pointer to a BSS descriptor found in a previous scan
  *                      to attempt to join
  *
  *  @return             0--success, -1--fail
  */
-int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req)
+int lbs_join_adhoc_network(struct lbs_private *priv,
+       struct assoc_request *assoc_req)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct bss_descriptor * bss = &assoc_req->bss;
        int ret = 0;
 
        lbs_deb_join("%s: Current SSID '%s', ssid length %u\n",
                     __func__,
-                    escape_essid(adapter->curbssparams.ssid,
-                                 adapter->curbssparams.ssid_len),
-                    adapter->curbssparams.ssid_len);
+                    escape_essid(priv->curbssparams.ssid,
+                                 priv->curbssparams.ssid_len),
+                    priv->curbssparams.ssid_len);
        lbs_deb_join("%s: requested ssid '%s', ssid length %u\n",
                     __func__, escape_essid(bss->ssid, bss->ssid_len),
                     bss->ssid_len);
 
        /* check if the requested SSID is already joined */
-       if (   adapter->curbssparams.ssid_len
-           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
-                                 adapter->curbssparams.ssid_len,
+       if (   priv->curbssparams.ssid_len
+           && !lbs_ssid_cmp(priv->curbssparams.ssid,
+                                 priv->curbssparams.ssid_len,
                                  bss->ssid, bss->ssid_len)
-           && (adapter->mode == IW_MODE_ADHOC)
-           && (adapter->connect_status == LIBERTAS_CONNECTED)) {
+           && (priv->mode == IW_MODE_ADHOC)
+           && (priv->connect_status == LBS_CONNECTED)) {
                union iwreq_data wrqu;
 
                lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as "
@@ -225,7 +226,7 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso
                 * request really was successful, even if just a null-op.
                 */
                memset(&wrqu, 0, sizeof(wrqu));
-               memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid,
+               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);
@@ -235,22 +236,22 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso
        /* Use shortpreamble only when both creator and card supports
           short preamble */
        if (   !(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
-           || !(adapter->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+           || !(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
                lbs_deb_join("AdhocJoin: Long preamble\n");
-               adapter->preamble = CMD_TYPE_LONG_PREAMBLE;
+               priv->preamble = CMD_TYPE_LONG_PREAMBLE;
        } else {
                lbs_deb_join("AdhocJoin: Short preamble\n");
-               adapter->preamble = CMD_TYPE_SHORT_PREAMBLE;
+               priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
        }
 
-       libertas_set_radio_control(priv);
+       lbs_set_radio_control(priv);
 
        lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
        lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
 
-       adapter->adhoccreate = 0;
+       priv->adhoccreate = 0;
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN,
                                    0, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_SSID, assoc_req);
 
@@ -258,38 +259,37 @@ out:
        return ret;
 }
 
-int libertas_stop_adhoc_network(wlan_private * priv)
+int lbs_stop_adhoc_network(struct lbs_private *priv)
 {
-       return libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP,
+       return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP,
                                     0, CMD_OPTION_WAITFORRSP, 0, NULL);
 }
 
 /**
  *  @brief Send Deauthentication Request
  *
- *  @param priv      A pointer to wlan_private structure
+ *  @param priv      A pointer to struct lbs_private structure
  *  @return          0--success, -1--fail
  */
-int libertas_send_deauthentication(wlan_private * priv)
+int lbs_send_deauthentication(struct lbs_private *priv)
 {
-       return libertas_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
+       return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE,
                                     0, CMD_OPTION_WAITFORRSP, 0, NULL);
 }
 
 /**
  *  @brief This function prepares command of authenticate.
  *
- *  @param priv      A pointer to wlan_private structure
+ *  @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 libertas_cmd_80211_authenticate(wlan_private * priv,
+int lbs_cmd_80211_authenticate(struct lbs_private *priv,
                                 struct cmd_ds_command *cmd,
                                 void *pdata_buf)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
        int ret = -1;
        u8 *bssid = pdata_buf;
@@ -302,7 +302,7 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
                                + S_DS_GEN);
 
        /* translate auth mode to 802.11 defined wire value */
-       switch (adapter->secinfo.auth_mode) {
+       switch (priv->secinfo.auth_mode) {
        case IW_AUTH_ALG_OPEN_SYSTEM:
                pauthenticate->authtype = 0x00;
                break;
@@ -314,13 +314,13 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
                break;
        default:
                lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
-                            adapter->secinfo.auth_mode);
+                            priv->secinfo.auth_mode);
                goto out;
        }
 
        memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
 
-       lbs_deb_join("AUTH_CMD: BSSID is : %s auth=0x%X\n",
+       lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
                     print_mac(mac, bssid), pauthenticate->authtype);
        ret = 0;
 
@@ -329,10 +329,9 @@ out:
        return ret;
 }
 
-int libertas_cmd_80211_deauthenticate(wlan_private * priv,
+int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
                                   struct cmd_ds_command *cmd)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth;
 
        lbs_deb_enter(LBS_DEB_JOIN);
@@ -342,7 +341,7 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv,
                             S_DS_GEN);
 
        /* set AP MAC address */
-       memmove(dauth->macaddr, adapter->curbssparams.bssid, ETH_ALEN);
+       memmove(dauth->macaddr, priv->curbssparams.bssid, ETH_ALEN);
 
        /* Reason code 3 = Station is leaving */
 #define REASON_CODE_STA_LEAVING 3
@@ -352,10 +351,9 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv,
        return 0;
 }
 
-int libertas_cmd_80211_associate(wlan_private * priv,
+int lbs_cmd_80211_associate(struct lbs_private *priv,
                              struct cmd_ds_command *cmd, void *pdata_buf)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
        int ret = 0;
        struct assoc_request * assoc_req = pdata_buf;
@@ -368,11 +366,11 @@ int libertas_cmd_80211_associate(wlan_private * priv,
        struct mrvlietypes_ratesparamset *rates;
        struct mrvlietypes_rsnparamset *rsn;
 
-       lbs_deb_enter(LBS_DEB_JOIN);
+       lbs_deb_enter(LBS_DEB_ASSOC);
 
        pos = (u8 *) passo;
 
-       if (!adapter) {
+       if (!priv) {
                ret = -1;
                goto done;
        }
@@ -416,22 +414,22 @@ int libertas_cmd_80211_associate(wlan_private * priv,
        rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
        memcpy(&rates->rates, &bss->rates, MAX_RATES);
        tmplen = MAX_RATES;
-       if (get_common_rates(adapter, rates->rates, &tmplen)) {
+       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_join("ASSOC_CMD: num rates = %u\n", tmplen);
+       lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
 
        /* Copy the infra. association rates into Current BSS state structure */
-       memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
-       memcpy(&adapter->curbssparams.rates, &rates->rates, tmplen);
+       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.
         */
-       libertas_set_basic_rate_flags(rates->rates, tmplen);
+       lbs_set_basic_rate_flags(rates->rates, tmplen);
 
        if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
                rsn = (struct mrvlietypes_rsnparamset *) pos;
@@ -446,9 +444,9 @@ int libertas_cmd_80211_associate(wlan_private * priv,
        }
 
        /* update curbssparams */
-       adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
+       priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
 
-       if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
+       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
                ret = -1;
                goto done;
        }
@@ -460,18 +458,16 @@ int libertas_cmd_80211_associate(wlan_private * priv,
        if (bss->mode == IW_MODE_INFRA)
                tmpcap |= WLAN_CAPABILITY_ESS;
        passo->capability = cpu_to_le16(tmpcap);
-       lbs_deb_join("ASSOC_CMD: capability=%4X CAPINFO_MASK=%4X\n",
-                    tmpcap, CAPINFO_MASK);
+       lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
 
 done:
-       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
-int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
                                 struct cmd_ds_command *cmd, void *pdata_buf)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads;
        int ret = 0;
        int cmdappendsize = 0;
@@ -481,7 +477,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
 
        lbs_deb_enter(LBS_DEB_JOIN);
 
-       if (!adapter) {
+       if (!priv) {
                ret = -1;
                goto done;
        }
@@ -491,7 +487,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
        /*
         * Fill in the parameters for 2 data structures:
         *   1. cmd_ds_802_11_ad_hoc_start command
-        *   2. adapter->scantable[i]
+        *   2. priv->scantable[i]
         *
         * Driver will fill up SSID, bsstype,IBSS param, Physical Param,
         *   probe delay, and cap info.
@@ -509,8 +505,10 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
 
        /* set the BSS type */
        adhs->bsstype = CMD_BSS_TYPE_IBSS;
-       adapter->mode = IW_MODE_ADHOC;
-       adhs->beaconperiod = cpu_to_le16(MRVDRV_BEACON_INTERVAL);
+       priv->mode = IW_MODE_ADHOC;
+       if (priv->beacon_period == 0)
+               priv->beacon_period = MRVDRV_BEACON_INTERVAL;
+       adhs->beaconperiod = cpu_to_le16(priv->beacon_period);
 
        /* set Physical param set */
 #define DS_PARA_IE_ID   3
@@ -548,24 +546,24 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
        adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
 
        memset(adhs->rates, 0, sizeof(adhs->rates));
-       ratesize = min(sizeof(adhs->rates), sizeof(libertas_bg_rates));
-       memcpy(adhs->rates, libertas_bg_rates, ratesize);
+       ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates));
+       memcpy(adhs->rates, lbs_bg_rates, ratesize);
 
        /* Copy the ad-hoc creating rates into Current BSS state structure */
-       memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
-       memcpy(&adapter->curbssparams.rates, &adhs->rates, ratesize);
+       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
+       memcpy(&priv->curbssparams.rates, &adhs->rates, ratesize);
 
        /* Set MSB on basic rates as the firmware requires, but _after_
         * copying to current bss rates.
         */
-       libertas_set_basic_rate_flags(adhs->rates, ratesize);
+       lbs_set_basic_rate_flags(adhs->rates, ratesize);
 
        lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n",
               adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]);
 
        lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n");
 
-       if (libertas_create_dnld_countryinfo_11d(priv)) {
+       if (lbs_create_dnld_countryinfo_11d(priv)) {
                lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n");
                ret = -1;
                goto done;
@@ -580,7 +578,7 @@ done:
        return ret;
 }
 
-int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv,
                                struct cmd_ds_command *cmd)
 {
        cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP);
@@ -589,10 +587,9 @@ int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
        return 0;
 }
 
-int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
                                struct cmd_ds_command *cmd, void *pdata_buf)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj;
        struct assoc_request * assoc_req = pdata_buf;
        struct bss_descriptor *bss = &assoc_req->bss;
@@ -633,26 +630,26 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
        /* probedelay */
        join_cmd->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
 
-       adapter->curbssparams.channel = bss->channel;
+       priv->curbssparams.channel = bss->channel;
 
        /* Copy Data rates from the rates recorded in scan response */
        memset(join_cmd->bss.rates, 0, sizeof(join_cmd->bss.rates));
        ratesize = min_t(u16, sizeof(join_cmd->bss.rates), MAX_RATES);
        memcpy(join_cmd->bss.rates, bss->rates, ratesize);
-       if (get_common_rates(adapter, join_cmd->bss.rates, &ratesize)) {
+       if (get_common_rates(priv, join_cmd->bss.rates, &ratesize)) {
                lbs_deb_join("ADHOC_J_CMD: get_common_rates returns error.\n");
                ret = -1;
                goto done;
        }
 
        /* Copy the ad-hoc creating rates into Current BSS state structure */
-       memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates));
-       memcpy(&adapter->curbssparams.rates, join_cmd->bss.rates, ratesize);
+       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
+       memcpy(&priv->curbssparams.rates, join_cmd->bss.rates, ratesize);
 
        /* Set MSB on basic rates as the firmware requires, but _after_
         * copying to current bss rates.
         */
-       libertas_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
+       lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize);
 
        join_cmd->bss.ssparamset.ibssparamset.atimwindow =
            cpu_to_le16(bss->atimwindow);
@@ -663,12 +660,12 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
                join_cmd->bss.capability = cpu_to_le16(tmp);
        }
 
-       if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
+       if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
                /* wake up first */
                __le32 Localpsmode;
 
-               Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM);
-               ret = libertas_prepare_and_send_command(priv,
+               Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
+               ret = lbs_prepare_and_send_command(priv,
                                            CMD_802_11_PS_MODE,
                                            CMD_ACT_SET,
                                            0, 0, &Localpsmode);
@@ -679,7 +676,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
                }
        }
 
-       if (libertas_parse_dnld_countryinfo_11d(priv, bss)) {
+       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
                ret = -1;
                goto done;
        }
@@ -692,24 +689,23 @@ done:
        return ret;
 }
 
-int libertas_ret_80211_associate(wlan_private * priv,
+int lbs_ret_80211_associate(struct lbs_private *priv,
                              struct cmd_ds_command *resp)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        union iwreq_data wrqu;
        struct ieeetypes_assocrsp *passocrsp;
        struct bss_descriptor * bss;
        u16 status_code;
 
-       lbs_deb_enter(LBS_DEB_JOIN);
+       lbs_deb_enter(LBS_DEB_ASSOC);
 
-       if (!adapter->in_progress_assoc_req) {
-               lbs_deb_join("ASSOC_RESP: no in-progress association request\n");
+       if (!priv->in_progress_assoc_req) {
+               lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
                ret = -1;
                goto done;
        }
-       bss = &adapter->in_progress_assoc_req->bss;
+       bss = &priv->in_progress_assoc_req->bss;
 
        passocrsp = (struct ieeetypes_assocrsp *) & resp->params;
 
@@ -734,96 +730,83 @@ int libertas_ret_80211_associate(wlan_private * priv,
        status_code = le16_to_cpu(passocrsp->statuscode);
        switch (status_code) {
        case 0x00:
-               lbs_deb_join("ASSOC_RESP: Association succeeded\n");
                break;
        case 0x01:
-               lbs_deb_join("ASSOC_RESP: Association failed; invalid "
-                            "parameters (status code %d)\n", status_code);
+               lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
                break;
        case 0x02:
-               lbs_deb_join("ASSOC_RESP: Association failed; internal timer "
-                            "expired while waiting for the AP (status code %d)"
-                            "\n", status_code);
+               lbs_deb_assoc("ASSOC_RESP: internal timer "
+                       "expired while waiting for the AP\n");
                break;
        case 0x03:
-               lbs_deb_join("ASSOC_RESP: Association failed; association "
-                            "was refused by the AP (status code %d)\n",
-                            status_code);
+               lbs_deb_assoc("ASSOC_RESP: association "
+                       "refused by AP\n");
                break;
        case 0x04:
-               lbs_deb_join("ASSOC_RESP: Association failed; authentication "
-                            "was refused by the AP (status code %d)\n",
-                            status_code);
+               lbs_deb_assoc("ASSOC_RESP: authentication "
+                       "refused by AP\n");
                break;
        default:
-               lbs_deb_join("ASSOC_RESP: Association failed; reason unknown "
-                            "(status code %d)\n", status_code);
+               lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
+                       " unknown\n", status_code);
                break;
        }
 
        if (status_code) {
-               libertas_mac_event_disconnected(priv);
+               lbs_mac_event_disconnected(priv);
                ret = -1;
                goto done;
        }
 
-       lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_RESP", (void *)&resp->params,
+       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 */
-       adapter->connect_status = LIBERTAS_CONNECTED;
-
-       lbs_deb_join("ASSOC_RESP: assocated to '%s'\n",
-                    escape_essid(bss->ssid, bss->ssid_len));
+       priv->connect_status = LBS_CONNECTED;
 
        /* Update current SSID and BSSID */
-       memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
-       adapter->curbssparams.ssid_len = bss->ssid_len;
-       memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
+       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);
 
-       lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n",
-              adapter->currentpacketfilter);
+       lbs_deb_assoc("ASSOC_RESP: currentpacketfilter is 0x%x\n",
+               priv->currentpacketfilter);
 
-       adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
-       adapter->NF[TYPE_RXPD][TYPE_AVG] = 0;
+       priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
+       priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
 
-       memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
-       memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
-       adapter->nextSNRNF = 0;
-       adapter->numSNRNF = 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);
-       netif_wake_queue(priv->dev);
-
-       if (priv->mesh_dev) {
-               netif_carrier_on(priv->mesh_dev);
-               netif_wake_queue(priv->mesh_dev);
-       }
+       if (!priv->tx_pending_len)
+               netif_wake_queue(priv->dev);
 
-       memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
+       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_JOIN, "ret %d", ret);
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
-int libertas_ret_80211_disassociate(wlan_private * priv,
+int lbs_ret_80211_disassociate(struct lbs_private *priv,
                                 struct cmd_ds_command *resp)
 {
        lbs_deb_enter(LBS_DEB_JOIN);
 
-       libertas_mac_event_disconnected(priv);
+       lbs_mac_event_disconnected(priv);
 
        lbs_deb_leave(LBS_DEB_JOIN);
        return 0;
 }
 
-int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
+int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
                                 struct cmd_ds_command *resp)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        u16 command = le16_to_cpu(resp->command);
        u16 result = le16_to_cpu(resp->result);
@@ -840,20 +823,20 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
        lbs_deb_join("ADHOC_RESP: command = %x\n", command);
        lbs_deb_join("ADHOC_RESP: result = %x\n", result);
 
-       if (!adapter->in_progress_assoc_req) {
+       if (!priv->in_progress_assoc_req) {
                lbs_deb_join("ADHOC_RESP: no in-progress association request\n");
                ret = -1;
                goto done;
        }
-       bss = &adapter->in_progress_assoc_req->bss;
+       bss = &priv->in_progress_assoc_req->bss;
 
        /*
         * Join result code 0 --> SUCCESS
         */
        if (result) {
                lbs_deb_join("ADHOC_RESP: failed\n");
-               if (adapter->connect_status == LIBERTAS_CONNECTED) {
-                       libertas_mac_event_disconnected(priv);
+               if (priv->connect_status == LBS_CONNECTED) {
+                       lbs_mac_event_disconnected(priv);
                }
                ret = -1;
                goto done;
@@ -867,7 +850,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
                     escape_essid(bss->ssid, bss->ssid_len));
 
        /* Send a Media Connected event, according to the Spec */
-       adapter->connect_status = LIBERTAS_CONNECTED;
+       priv->connect_status = LBS_CONNECTED;
 
        if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
                /* Update the created network descriptor with the new BSSID */
@@ -875,27 +858,23 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
        }
 
        /* Set the BSSID from the joined/started descriptor */
-       memcpy(&adapter->curbssparams.bssid, bss->bssid, ETH_ALEN);
+       memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
 
        /* Set the new SSID to current SSID */
-       memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
-       adapter->curbssparams.ssid_len = bss->ssid_len;
+       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+       priv->curbssparams.ssid_len = bss->ssid_len;
 
        netif_carrier_on(priv->dev);
-       netif_wake_queue(priv->dev);
-
-       if (priv->mesh_dev) {
-               netif_carrier_on(priv->mesh_dev);
-               netif_wake_queue(priv->mesh_dev);
-       }
+       if (!priv->tx_pending_len)
+               netif_wake_queue(priv->dev);
 
        memset(&wrqu, 0, sizeof(wrqu));
-       memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN);
+       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 Ad Hoc\n");
-       lbs_deb_join("ADHOC_RESP: channel = %d\n", adapter->curbssparams.channel);
+       lbs_deb_join("ADHOC_RESP: channel = %d\n", priv->curbssparams.channel);
        lbs_deb_join("ADHOC_RESP: BSSID = %s\n",
                     print_mac(mac, padhocresult->bssid));
 
@@ -904,12 +883,12 @@ done:
        return ret;
 }
 
-int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
+int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv,
                                struct cmd_ds_command *resp)
 {
        lbs_deb_enter(LBS_DEB_JOIN);
 
-       libertas_mac_event_disconnected(priv);
+       lbs_mac_event_disconnected(priv);
 
        lbs_deb_leave(LBS_DEB_JOIN);
        return 0;
index 894a072b9f8d4e6ab8164a422deec0aa68e462df..c617d071f7811031975946b47ace752b94406166 100644 (file)
@@ -2,52 +2,52 @@
   * Interface for the wlan infrastructure and adhoc join routines
   *
   * Driver interface functions and type declarations for the join module
-  *   implemented in wlan_join.c.  Process all start/join requests for
+  *   implemented in join.c.  Process all start/join requests for
   *   both adhoc and infrastructure networks
   */
-#ifndef _WLAN_JOIN_H
-#define _WLAN_JOIN_H
+#ifndef _LBS_JOIN_H
+#define _LBS_JOIN_H
 
 #include "defs.h"
 #include "dev.h"
 
 struct cmd_ds_command;
-int libertas_cmd_80211_authenticate(wlan_private * priv,
+int lbs_cmd_80211_authenticate(struct lbs_private *priv,
                                        struct cmd_ds_command *cmd,
                                        void *pdata_buf);
-int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv,
                                       struct cmd_ds_command *cmd,
                                       void *pdata_buf);
-int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv,
                                       struct cmd_ds_command *cmd);
-int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
+int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv,
                                        struct cmd_ds_command *cmd,
                                        void *pdata_buf);
-int libertas_cmd_80211_deauthenticate(wlan_private * priv,
+int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
                                          struct cmd_ds_command *cmd);
-int libertas_cmd_80211_associate(wlan_private * priv,
+int lbs_cmd_80211_associate(struct lbs_private *priv,
                                     struct cmd_ds_command *cmd,
                                     void *pdata_buf);
 
-int libertas_ret_80211_ad_hoc_start(wlan_private * priv,
+int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
                                        struct cmd_ds_command *resp);
-int libertas_ret_80211_ad_hoc_stop(wlan_private * priv,
+int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv,
                                       struct cmd_ds_command *resp);
-int libertas_ret_80211_disassociate(wlan_private * priv,
+int lbs_ret_80211_disassociate(struct lbs_private *priv,
                                        struct cmd_ds_command *resp);
-int libertas_ret_80211_associate(wlan_private * priv,
+int lbs_ret_80211_associate(struct lbs_private *priv,
                                     struct cmd_ds_command *resp);
 
-int libertas_start_adhoc_network(wlan_private * priv,
+int lbs_start_adhoc_network(struct lbs_private *priv,
                             struct assoc_request * assoc_req);
-int libertas_join_adhoc_network(wlan_private * priv,
+int lbs_join_adhoc_network(struct lbs_private *priv,
                                struct assoc_request * assoc_req);
-int libertas_stop_adhoc_network(wlan_private * priv);
+int lbs_stop_adhoc_network(struct lbs_private *priv);
 
-int libertas_send_deauthentication(wlan_private * priv);
+int lbs_send_deauthentication(struct lbs_private *priv);
 
-int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req);
+int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req);
 
-void libertas_unset_basic_rate_flags(u8 * rates, size_t len);
+void lbs_unset_basic_rate_flags(u8 *rates, size_t len);
 
 #endif
index 1823b48a8ba74653c6be98fc3f65caedfdb9f9b0..84fb49ca0fae3cbf53713b5f586d82102de30ea9 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
-#include <linux/freezer.h>
 #include <linux/etherdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include "debugfs.h"
 #include "assoc.h"
 #include "join.h"
+#include "cmd.h"
 
 #define DRIVER_RELEASE_VERSION "323.p0"
-const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
+const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
 #ifdef  DEBUG
     "-dbg"
 #endif
@@ -32,80 +32,80 @@ const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
 
 
 /* Module parameters */
-unsigned int libertas_debug = 0;
-module_param(libertas_debug, int, 0644);
-EXPORT_SYMBOL_GPL(libertas_debug);
+unsigned int lbs_debug;
+EXPORT_SYMBOL_GPL(lbs_debug);
+module_param_named(libertas_debug, lbs_debug, int, 0644);
 
 
-#define WLAN_TX_PWR_DEFAULT            20      /*100mW */
-#define WLAN_TX_PWR_US_DEFAULT         20      /*100mW */
-#define WLAN_TX_PWR_JP_DEFAULT         16      /*50mW */
-#define WLAN_TX_PWR_FR_DEFAULT         20      /*100mW */
-#define WLAN_TX_PWR_EMEA_DEFAULT       20      /*100mW */
+#define LBS_TX_PWR_DEFAULT             20      /*100mW */
+#define LBS_TX_PWR_US_DEFAULT          20      /*100mW */
+#define LBS_TX_PWR_JP_DEFAULT          16      /*50mW */
+#define LBS_TX_PWR_FR_DEFAULT          20      /*100mW */
+#define LBS_TX_PWR_EMEA_DEFAULT        20      /*100mW */
 
 /* Format { channel, frequency (MHz), maxtxpower } */
 /* band: 'B/G', region: USA FCC/Canada IC */
 static struct chan_freq_power channel_freq_power_US_BG[] = {
-       {1, 2412, WLAN_TX_PWR_US_DEFAULT},
-       {2, 2417, WLAN_TX_PWR_US_DEFAULT},
-       {3, 2422, WLAN_TX_PWR_US_DEFAULT},
-       {4, 2427, WLAN_TX_PWR_US_DEFAULT},
-       {5, 2432, WLAN_TX_PWR_US_DEFAULT},
-       {6, 2437, WLAN_TX_PWR_US_DEFAULT},
-       {7, 2442, WLAN_TX_PWR_US_DEFAULT},
-       {8, 2447, WLAN_TX_PWR_US_DEFAULT},
-       {9, 2452, WLAN_TX_PWR_US_DEFAULT},
-       {10, 2457, WLAN_TX_PWR_US_DEFAULT},
-       {11, 2462, WLAN_TX_PWR_US_DEFAULT}
+       {1, 2412, LBS_TX_PWR_US_DEFAULT},
+       {2, 2417, LBS_TX_PWR_US_DEFAULT},
+       {3, 2422, LBS_TX_PWR_US_DEFAULT},
+       {4, 2427, LBS_TX_PWR_US_DEFAULT},
+       {5, 2432, LBS_TX_PWR_US_DEFAULT},
+       {6, 2437, LBS_TX_PWR_US_DEFAULT},
+       {7, 2442, LBS_TX_PWR_US_DEFAULT},
+       {8, 2447, LBS_TX_PWR_US_DEFAULT},
+       {9, 2452, LBS_TX_PWR_US_DEFAULT},
+       {10, 2457, LBS_TX_PWR_US_DEFAULT},
+       {11, 2462, LBS_TX_PWR_US_DEFAULT}
 };
 
 /* band: 'B/G', region: Europe ETSI */
 static struct chan_freq_power channel_freq_power_EU_BG[] = {
-       {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
-       {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
-       {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
-       {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
-       {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
-       {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
-       {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
-       {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
-       {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
-       {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
-       {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
-       {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
-       {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
+       {1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
+       {2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
+       {3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
+       {4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
+       {5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
+       {6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
+       {7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
+       {8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
+       {9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
+       {10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
+       {11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
+       {12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
+       {13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
 };
 
 /* band: 'B/G', region: Spain */
 static struct chan_freq_power channel_freq_power_SPN_BG[] = {
-       {10, 2457, WLAN_TX_PWR_DEFAULT},
-       {11, 2462, WLAN_TX_PWR_DEFAULT}
+       {10, 2457, LBS_TX_PWR_DEFAULT},
+       {11, 2462, LBS_TX_PWR_DEFAULT}
 };
 
 /* band: 'B/G', region: France */
 static struct chan_freq_power channel_freq_power_FR_BG[] = {
-       {10, 2457, WLAN_TX_PWR_FR_DEFAULT},
-       {11, 2462, WLAN_TX_PWR_FR_DEFAULT},
-       {12, 2467, WLAN_TX_PWR_FR_DEFAULT},
-       {13, 2472, WLAN_TX_PWR_FR_DEFAULT}
+       {10, 2457, LBS_TX_PWR_FR_DEFAULT},
+       {11, 2462, LBS_TX_PWR_FR_DEFAULT},
+       {12, 2467, LBS_TX_PWR_FR_DEFAULT},
+       {13, 2472, LBS_TX_PWR_FR_DEFAULT}
 };
 
 /* band: 'B/G', region: Japan */
 static struct chan_freq_power channel_freq_power_JPN_BG[] = {
-       {1, 2412, WLAN_TX_PWR_JP_DEFAULT},
-       {2, 2417, WLAN_TX_PWR_JP_DEFAULT},
-       {3, 2422, WLAN_TX_PWR_JP_DEFAULT},
-       {4, 2427, WLAN_TX_PWR_JP_DEFAULT},
-       {5, 2432, WLAN_TX_PWR_JP_DEFAULT},
-       {6, 2437, WLAN_TX_PWR_JP_DEFAULT},
-       {7, 2442, WLAN_TX_PWR_JP_DEFAULT},
-       {8, 2447, WLAN_TX_PWR_JP_DEFAULT},
-       {9, 2452, WLAN_TX_PWR_JP_DEFAULT},
-       {10, 2457, WLAN_TX_PWR_JP_DEFAULT},
-       {11, 2462, WLAN_TX_PWR_JP_DEFAULT},
-       {12, 2467, WLAN_TX_PWR_JP_DEFAULT},
-       {13, 2472, WLAN_TX_PWR_JP_DEFAULT},
-       {14, 2484, WLAN_TX_PWR_JP_DEFAULT}
+       {1, 2412, LBS_TX_PWR_JP_DEFAULT},
+       {2, 2417, LBS_TX_PWR_JP_DEFAULT},
+       {3, 2422, LBS_TX_PWR_JP_DEFAULT},
+       {4, 2427, LBS_TX_PWR_JP_DEFAULT},
+       {5, 2432, LBS_TX_PWR_JP_DEFAULT},
+       {6, 2437, LBS_TX_PWR_JP_DEFAULT},
+       {7, 2442, LBS_TX_PWR_JP_DEFAULT},
+       {8, 2447, LBS_TX_PWR_JP_DEFAULT},
+       {9, 2452, LBS_TX_PWR_JP_DEFAULT},
+       {10, 2457, LBS_TX_PWR_JP_DEFAULT},
+       {11, 2462, LBS_TX_PWR_JP_DEFAULT},
+       {12, 2467, LBS_TX_PWR_JP_DEFAULT},
+       {13, 2472, LBS_TX_PWR_JP_DEFAULT},
+       {14, 2484, LBS_TX_PWR_JP_DEFAULT}
 };
 
 /**
@@ -153,13 +153,13 @@ static struct region_cfp_table region_cfp_table[] = {
 /**
  * the table to keep region code
  */
-u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
+u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
     { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
 
 /**
  * 802.11b/g supported bitrates (in 500Kb/s units)
  */
-u8 libertas_bg_rates[MAX_RATES] =
+u8 lbs_bg_rates[MAX_RATES] =
     { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
 0x00, 0x00 };
 
@@ -179,7 +179,7 @@ static u8 fw_data_rates[MAX_RATES] =
  *  @param idx                The index of data rate
  *  @return                    data rate or 0
  */
-u32 libertas_fw_index_to_data_rate(u8 idx)
+u32 lbs_fw_index_to_data_rate(u8 idx)
 {
        if (idx >= sizeof(fw_data_rates))
                idx = 0;
@@ -192,7 +192,7 @@ u32 libertas_fw_index_to_data_rate(u8 idx)
  *  @param rate                 data rate
  *  @return                    index or 0
  */
-u8 libertas_data_rate_to_fw_index(u32 rate)
+u8 lbs_data_rate_to_fw_index(u32 rate)
 {
        u8 i;
 
@@ -213,16 +213,18 @@ u8 libertas_data_rate_to_fw_index(u32 rate)
 /**
  * @brief Get function for sysfs attribute anycast_mask
  */
-static ssize_t libertas_anycast_get(struct device * dev,
+static ssize_t lbs_anycast_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
+       struct lbs_private *priv = to_net_dev(dev)->priv;
        struct cmd_ds_mesh_access mesh_access;
+       int ret;
 
        memset(&mesh_access, 0, sizeof(mesh_access));
-       libertas_prepare_and_send_command(to_net_dev(dev)->priv,
-                       CMD_MESH_ACCESS,
-                       CMD_ACT_MESH_GET_ANYCAST,
-                       CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+
+       ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
+       if (ret)
+               return ret;
 
        return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
 }
@@ -230,244 +232,191 @@ static ssize_t libertas_anycast_get(struct device * dev,
 /**
  * @brief Set function for sysfs attribute anycast_mask
  */
-static ssize_t libertas_anycast_set(struct device * dev,
+static ssize_t lbs_anycast_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
+       struct lbs_private *priv = to_net_dev(dev)->priv;
        struct cmd_ds_mesh_access mesh_access;
        uint32_t datum;
+       int ret;
 
        memset(&mesh_access, 0, sizeof(mesh_access));
        sscanf(buf, "%x", &datum);
        mesh_access.data[0] = cpu_to_le32(datum);
 
-       libertas_prepare_and_send_command((to_net_dev(dev))->priv,
-                       CMD_MESH_ACCESS,
-                       CMD_ACT_MESH_SET_ANYCAST,
-                       CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+       ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
+       if (ret)
+               return ret;
+
        return strlen(buf);
 }
 
-int libertas_add_rtap(wlan_private *priv);
-void libertas_remove_rtap(wlan_private *priv);
+static int lbs_add_rtap(struct lbs_private *priv);
+static void lbs_remove_rtap(struct lbs_private *priv);
+static int lbs_add_mesh(struct lbs_private *priv);
+static void lbs_remove_mesh(struct lbs_private *priv);
+
 
 /**
  * Get function for sysfs attribute rtap
  */
-static ssize_t libertas_rtap_get(struct device * dev,
+static ssize_t lbs_rtap_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv;
-       wlan_adapter *adapter = priv->adapter;
-       return snprintf(buf, 5, "0x%X\n", adapter->monitormode);
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       return snprintf(buf, 5, "0x%X\n", priv->monitormode);
 }
 
 /**
  *  Set function for sysfs attribute rtap
  */
-static ssize_t libertas_rtap_set(struct device * dev,
+static ssize_t lbs_rtap_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
        int monitor_mode;
-       wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
 
        sscanf(buf, "%x", &monitor_mode);
-       if (monitor_mode != WLAN_MONITOR_OFF) {
-               if(adapter->monitormode == monitor_mode)
+       if (monitor_mode != LBS_MONITOR_OFF) {
+               if(priv->monitormode == monitor_mode)
                        return strlen(buf);
-               if (adapter->monitormode == WLAN_MONITOR_OFF) {
-                       if (adapter->mode == IW_MODE_INFRA)
-                               libertas_send_deauthentication(priv);
-                       else if (adapter->mode == IW_MODE_ADHOC)
-                               libertas_stop_adhoc_network(priv);
-                       libertas_add_rtap(priv);
+               if (priv->monitormode == LBS_MONITOR_OFF) {
+                       if (priv->infra_open || priv->mesh_open)
+                               return -EBUSY;
+                       if (priv->mode == IW_MODE_INFRA)
+                               lbs_send_deauthentication(priv);
+                       else if (priv->mode == IW_MODE_ADHOC)
+                               lbs_stop_adhoc_network(priv);
+                       lbs_add_rtap(priv);
                }
-               adapter->monitormode = monitor_mode;
+               priv->monitormode = monitor_mode;
        }
 
        else {
-               if(adapter->monitormode == WLAN_MONITOR_OFF)
+               if (priv->monitormode == LBS_MONITOR_OFF)
                        return strlen(buf);
-               adapter->monitormode = WLAN_MONITOR_OFF;
-               libertas_remove_rtap(priv);
-               netif_wake_queue(priv->dev);
-               netif_wake_queue(priv->mesh_dev);
+               priv->monitormode = LBS_MONITOR_OFF;
+               lbs_remove_rtap(priv);
+
+               if (priv->currenttxskb) {
+                       dev_kfree_skb_any(priv->currenttxskb);
+                       priv->currenttxskb = NULL;
+               }
+
+               /* Wake queues, command thread, etc. */
+               lbs_host_to_card_done(priv);
        }
 
-       libertas_prepare_and_send_command(priv,
+       lbs_prepare_and_send_command(priv,
                        CMD_802_11_MONITOR_MODE, CMD_ACT_SET,
-                       CMD_OPTION_WAITFORRSP, 0, &adapter->monitormode);
+                       CMD_OPTION_WAITFORRSP, 0, &priv->monitormode);
        return strlen(buf);
 }
 
 /**
- * libertas_rtap attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/libertas-rtap)
+ * lbs_rtap attribute to be exported per ethX interface
+ * through sysfs (/sys/class/net/ethX/lbs_rtap)
  */
-static DEVICE_ATTR(libertas_rtap, 0644, libertas_rtap_get,
-               libertas_rtap_set );
+static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
 
 /**
- * anycast_mask attribute to be exported per mshX interface
- * through sysfs (/sys/class/net/mshX/anycast_mask)
+ * Get function for sysfs attribute mesh
  */
-static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set);
-
-static ssize_t libertas_autostart_enabled_get(struct device * dev,
+static ssize_t lbs_mesh_get(struct device *dev,
                struct device_attribute *attr, char * buf)
 {
-       struct cmd_ds_mesh_access mesh_access;
-
-       memset(&mesh_access, 0, sizeof(mesh_access));
-       libertas_prepare_and_send_command(to_net_dev(dev)->priv,
-                       CMD_MESH_ACCESS,
-                       CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
-                       CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-
-       return sprintf(buf, "%d\n", le32_to_cpu(mesh_access.data[0]));
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
 }
 
-static ssize_t libertas_autostart_enabled_set(struct device * dev,
+/**
+ *  Set function for sysfs attribute mesh
+ */
+static ssize_t lbs_mesh_set(struct device *dev,
                struct device_attribute *attr, const char * buf, size_t count)
 {
-       struct cmd_ds_mesh_access mesh_access;
-       uint32_t datum;
-       wlan_private * priv = (to_net_dev(dev))->priv;
+       struct lbs_private *priv = to_net_dev(dev)->priv;
+       int enable;
        int ret;
 
-       memset(&mesh_access, 0, sizeof(mesh_access));
-       sscanf(buf, "%d", &datum);
-       mesh_access.data[0] = cpu_to_le32(datum);
+       sscanf(buf, "%x", &enable);
+       enable = !!enable;
+       if (enable == !!priv->mesh_dev)
+               return count;
+
+       ret = lbs_mesh_config(priv, enable, priv->curbssparams.channel);
+       if (ret)
+               return ret;
 
-       ret = libertas_prepare_and_send_command(priv,
-                       CMD_MESH_ACCESS,
-                       CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-                       CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-       if (ret == 0)
-               priv->mesh_autostart_enabled = datum ? 1 : 0;
+       if (enable)
+               lbs_add_mesh(priv);
+       else
+               lbs_remove_mesh(priv);
 
-       return strlen(buf);
+       return count;
 }
 
-static DEVICE_ATTR(autostart_enabled, 0644,
-               libertas_autostart_enabled_get, libertas_autostart_enabled_set);
+/**
+ * lbs_mesh attribute to be exported per ethX interface
+ * through sysfs (/sys/class/net/ethX/lbs_mesh)
+ */
+static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
 
-static struct attribute *libertas_mesh_sysfs_entries[] = {
+/**
+ * anycast_mask attribute to be exported per mshX interface
+ * through sysfs (/sys/class/net/mshX/anycast_mask)
+ */
+static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
+
+static struct attribute *lbs_mesh_sysfs_entries[] = {
        &dev_attr_anycast_mask.attr,
-       &dev_attr_autostart_enabled.attr,
        NULL,
 };
 
-static struct attribute_group libertas_mesh_attr_group = {
-       .attrs = libertas_mesh_sysfs_entries,
+static struct attribute_group lbs_mesh_attr_group = {
+       .attrs = lbs_mesh_sysfs_entries,
 };
 
 /**
- *  @brief Check if the device can be open and wait if necessary.
- *
- *  @param dev     A pointer to net_device structure
- *  @return       0
- *
- * For USB adapter, on some systems the device open handler will be
- * called before FW ready. Use the following flag check and wait
- * function to work around the issue.
- *
- */
-static int pre_open_check(struct net_device *dev)
-{
-       wlan_private *priv = (wlan_private *) dev->priv;
-       wlan_adapter *adapter = priv->adapter;
-       int i = 0;
-
-       while (!adapter->fw_ready && i < 20) {
-               i++;
-               msleep_interruptible(100);
-       }
-       if (!adapter->fw_ready) {
-               lbs_pr_err("firmware not ready\n");
-               return -1;
-       }
-
-       return 0;
-}
-
-/**
- *  @brief This function opens the device
+ *  @brief This function opens the ethX or mshX interface
  *
  *  @param dev     A pointer to net_device structure
- *  @return       0
+ *  @return       0 or -EBUSY if monitor mode active
  */
-static int libertas_dev_open(struct net_device *dev)
+static int lbs_dev_open(struct net_device *dev)
 {
-       wlan_private *priv = (wlan_private *) dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv ;
+       int ret = 0;
 
        lbs_deb_enter(LBS_DEB_NET);
 
-       priv->open = 1;
+       spin_lock_irq(&priv->driver_lock);
 
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
-               netif_carrier_on(priv->dev);
-               if (priv->mesh_dev)
-                       netif_carrier_on(priv->mesh_dev);
-       } else {
-               netif_carrier_off(priv->dev);
-               if (priv->mesh_dev)
-                       netif_carrier_off(priv->mesh_dev);
+       if (priv->monitormode != LBS_MONITOR_OFF) {
+               ret = -EBUSY;
+               goto out;
        }
 
-       lbs_deb_leave(LBS_DEB_NET);
-       return 0;
-}
-/**
- *  @brief This function opens the mshX interface
- *
- *  @param dev     A pointer to net_device structure
- *  @return       0
- */
-static int libertas_mesh_open(struct net_device *dev)
-{
-       wlan_private *priv = (wlan_private *) dev->priv ;
-
-       if (pre_open_check(dev) == -1)
-               return -1;
-       priv->mesh_open = 1 ;
-       netif_wake_queue(priv->mesh_dev);
-       if (priv->infra_open == 0)
-               return libertas_dev_open(priv->dev) ;
-       return 0;
-}
-
-/**
- *  @brief This function opens the ethX interface
- *
- *  @param dev     A pointer to net_device structure
- *  @return       0
- */
-static int libertas_open(struct net_device *dev)
-{
-       wlan_private *priv = (wlan_private *) dev->priv ;
-
-       if(pre_open_check(dev) == -1)
-               return -1;
-       priv->infra_open = 1 ;
-       netif_wake_queue(priv->dev);
-       if (priv->open == 0)
-               return libertas_dev_open(priv->dev) ;
-       return 0;
-}
-
-static int libertas_dev_close(struct net_device *dev)
-{
-       wlan_private *priv = dev->priv;
+       if (dev == priv->mesh_dev) {
+               priv->mesh_open = 1;
+               priv->mesh_connect_status = LBS_CONNECTED;
+               netif_carrier_on(dev);
+       } else {
+               priv->infra_open = 1;
 
-       lbs_deb_enter(LBS_DEB_NET);
+               if (priv->connect_status == LBS_CONNECTED)
+                       netif_carrier_on(dev);
+               else
+                       netif_carrier_off(dev);
+       }
 
-       netif_carrier_off(priv->dev);
-       priv->open = 0;
+       if (!priv->tx_pending_len)
+               netif_wake_queue(dev);
+ out:
 
-       lbs_deb_leave(LBS_DEB_NET);
-       return 0;
+       spin_unlock_irq(&priv->driver_lock);
+       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+       return ret;
 }
 
 /**
@@ -476,16 +425,23 @@ static int libertas_dev_close(struct net_device *dev)
  *  @param dev     A pointer to net_device structure
  *  @return       0
  */
-static int libertas_mesh_close(struct net_device *dev)
+static int lbs_mesh_stop(struct net_device *dev)
 {
-       wlan_private *priv = (wlan_private *) (dev->priv);
+       struct lbs_private *priv = (struct lbs_private *) (dev->priv);
+
+       lbs_deb_enter(LBS_DEB_MESH);
+       spin_lock_irq(&priv->driver_lock);
 
        priv->mesh_open = 0;
-       netif_stop_queue(priv->mesh_dev);
-       if (priv->infra_open == 0)
-               return libertas_dev_close(dev);
-       else
-               return 0;
+       priv->mesh_connect_status = LBS_DISCONNECTED;
+
+       netif_stop_queue(dev);
+       netif_carrier_off(dev);
+
+       spin_unlock_irq(&priv->driver_lock);
+
+       lbs_deb_leave(LBS_DEB_MESH);
+       return 0;
 }
 
 /**
@@ -494,134 +450,86 @@ static int libertas_mesh_close(struct net_device *dev)
  *  @param dev     A pointer to net_device structure
  *  @return       0
  */
-static int libertas_close(struct net_device *dev)
-{
-       wlan_private *priv = (wlan_private *) dev->priv;
-
-       netif_stop_queue(dev);
-       priv->infra_open = 0;
-       if (priv->mesh_open == 0)
-               return libertas_dev_close(dev);
-       else
-               return 0;
-}
-
-
-static int libertas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int lbs_eth_stop(struct net_device *dev)
 {
-       int ret = 0;
-       wlan_private *priv = dev->priv;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
 
        lbs_deb_enter(LBS_DEB_NET);
 
-       if (priv->dnld_sent || priv->adapter->TxLockFlag) {
-               priv->stats.tx_dropped++;
-               goto done;
-       }
-
-       netif_stop_queue(priv->dev);
-       if (priv->mesh_dev)
-               netif_stop_queue(priv->mesh_dev);
+       spin_lock_irq(&priv->driver_lock);
+       priv->infra_open = 0;
+       netif_stop_queue(dev);
+       spin_unlock_irq(&priv->driver_lock);
 
-       if (libertas_process_tx(priv, skb) == 0)
-               dev->trans_start = jiffies;
-done:
-       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
-       return ret;
+       lbs_deb_leave(LBS_DEB_NET);
+       return 0;
 }
 
-/**
- * @brief Mark mesh packets and handover them to libertas_hard_start_xmit
- *
- */
-static int libertas_mesh_pre_start_xmit(struct sk_buff *skb,
-               struct net_device *dev)
+static void lbs_tx_timeout(struct net_device *dev)
 {
-       wlan_private *priv = dev->priv;
-       int ret;
-
-       lbs_deb_enter(LBS_DEB_MESH);
-       if(priv->adapter->monitormode != WLAN_MONITOR_OFF) {
-               netif_stop_queue(dev);
-               return -EOPNOTSUPP;
-       }
-
-       SET_MESH_FRAME(skb);
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
 
-       ret = libertas_hard_start_xmit(skb, priv->dev);
-       lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-       return ret;
-}
+       lbs_deb_enter(LBS_DEB_TX);
 
-/**
- * @brief Mark non-mesh packets and handover them to libertas_hard_start_xmit
- *
- */
-static int libertas_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       wlan_private *priv = dev->priv;
-       int ret;
+       lbs_pr_err("tx watch dog timeout\n");
 
-       lbs_deb_enter(LBS_DEB_NET);
+       dev->trans_start = jiffies;
 
-       if(priv->adapter->monitormode != WLAN_MONITOR_OFF) {
-               netif_stop_queue(dev);
-               return -EOPNOTSUPP;
+       if (priv->currenttxskb) {
+               priv->eventcause = 0x01000000;
+               lbs_send_tx_feedback(priv);
        }
+       /* XX: Shouldn't we also call into the hw-specific driver
+          to kick it somehow? */
+       lbs_host_to_card_done(priv);
 
-       UNSET_MESH_FRAME(skb);
+       /* More often than not, this actually happens because the
+          firmware has crapped itself -- rather than just a very
+          busy medium. So send a harmless command, and if/when
+          _that_ times out, we'll kick it in the head. */
+       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+                                    0, 0, NULL);
 
-       ret = libertas_hard_start_xmit(skb, dev);
-       lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
-       return ret;
+       lbs_deb_leave(LBS_DEB_TX);
 }
 
-static void libertas_tx_timeout(struct net_device *dev)
+void lbs_host_to_card_done(struct lbs_private *priv)
 {
-       wlan_private *priv = (wlan_private *) dev->priv;
+       unsigned long flags;
 
-       lbs_deb_enter(LBS_DEB_TX);
+       lbs_deb_enter(LBS_DEB_THREAD);
 
-       lbs_pr_err("tx watch dog timeout\n");
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
        priv->dnld_sent = DNLD_RES_RECEIVED;
-       dev->trans_start = jiffies;
 
-       if (priv->adapter->currenttxskb) {
-               if (priv->adapter->monitormode != WLAN_MONITOR_OFF) {
-                       /* If we are here, we have not received feedback from
-                          the previous packet.  Assume TX_FAIL and move on. */
-                       priv->adapter->eventcause = 0x01000000;
-                       libertas_send_tx_feedback(priv);
-               } else
-                       wake_up_interruptible(&priv->waitq);
-       } else if (priv->adapter->connect_status == LIBERTAS_CONNECTED) {
-               netif_wake_queue(priv->dev);
-               if (priv->mesh_dev)
-                       netif_wake_queue(priv->mesh_dev);
-       }
+       /* Wake main thread if commands are pending */
+       if (!priv->cur_cmd || priv->tx_pending_len > 0)
+               wake_up_interruptible(&priv->waitq);
 
-       lbs_deb_leave(LBS_DEB_TX);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+       lbs_deb_leave(LBS_DEB_THREAD);
 }
+EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
 
 /**
  *  @brief This function returns the network statistics
  *
- *  @param dev     A pointer to wlan_private structure
+ *  @param dev     A pointer to struct lbs_private structure
  *  @return       A pointer to net_device_stats structure
  */
-static struct net_device_stats *libertas_get_stats(struct net_device *dev)
+static struct net_device_stats *lbs_get_stats(struct net_device *dev)
 {
-       wlan_private *priv = (wlan_private *) dev->priv;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
 
+       lbs_deb_enter(LBS_DEB_NET);
        return &priv->stats;
 }
 
-static int libertas_set_mac_address(struct net_device *dev, void *addr)
+static int lbs_set_mac_address(struct net_device *dev, void *addr)
 {
        int ret = 0;
-       wlan_private *priv = (wlan_private *) dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = (struct lbs_private *) dev->priv;
        struct sockaddr *phwaddr = addr;
 
        lbs_deb_enter(LBS_DEB_NET);
@@ -629,15 +537,15 @@ static int libertas_set_mac_address(struct net_device *dev, void *addr)
        /* In case it was called from the mesh device */
        dev = priv->dev ;
 
-       memset(adapter->current_addr, 0, ETH_ALEN);
+       memset(priv->current_addr, 0, ETH_ALEN);
 
        /* dev->dev_addr is 8 bytes */
        lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN);
 
        lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);
-       memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN);
+       memcpy(priv->current_addr, phwaddr->sa_data, ETH_ALEN);
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,
                                    CMD_ACT_SET,
                                    CMD_OPTION_WAITFORRSP, 0, NULL);
 
@@ -647,89 +555,86 @@ static int libertas_set_mac_address(struct net_device *dev, void *addr)
                goto done;
        }
 
-       lbs_deb_hex(LBS_DEB_NET, "adapter->macaddr", adapter->current_addr, ETH_ALEN);
-       memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);
+       lbs_deb_hex(LBS_DEB_NET, "priv->macaddr", priv->current_addr, ETH_ALEN);
+       memcpy(dev->dev_addr, priv->current_addr, ETH_ALEN);
        if (priv->mesh_dev)
-               memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
+               memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
 
 done:
        lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
        return ret;
 }
 
-static int libertas_copy_multicast_address(wlan_adapter * adapter,
+static int lbs_copy_multicast_address(struct lbs_private *priv,
                                     struct net_device *dev)
 {
        int i = 0;
        struct dev_mc_list *mcptr = dev->mc_list;
 
        for (i = 0; i < dev->mc_count; i++) {
-               memcpy(&adapter->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
+               memcpy(&priv->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);
                mcptr = mcptr->next;
        }
-
        return i;
-
 }
 
-static void libertas_set_multicast_list(struct net_device *dev)
+static void lbs_set_multicast_list(struct net_device *dev)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int oldpacketfilter;
        DECLARE_MAC_BUF(mac);
 
        lbs_deb_enter(LBS_DEB_NET);
 
-       oldpacketfilter = adapter->currentpacketfilter;
+       oldpacketfilter = priv->currentpacketfilter;
 
        if (dev->flags & IFF_PROMISC) {
                lbs_deb_net("enable promiscuous mode\n");
-               adapter->currentpacketfilter |=
+               priv->currentpacketfilter |=
                    CMD_ACT_MAC_PROMISCUOUS_ENABLE;
-               adapter->currentpacketfilter &=
+               priv->currentpacketfilter &=
                    ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |
                      CMD_ACT_MAC_MULTICAST_ENABLE);
        } else {
                /* Multicast */
-               adapter->currentpacketfilter &=
+               priv->currentpacketfilter &=
                    ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
 
                if (dev->flags & IFF_ALLMULTI || dev->mc_count >
                    MRVDRV_MAX_MULTICAST_LIST_SIZE) {
                        lbs_deb_net( "enabling all multicast\n");
-                       adapter->currentpacketfilter |=
+                       priv->currentpacketfilter |=
                            CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
-                       adapter->currentpacketfilter &=
+                       priv->currentpacketfilter &=
                            ~CMD_ACT_MAC_MULTICAST_ENABLE;
                } else {
-                       adapter->currentpacketfilter &=
+                       priv->currentpacketfilter &=
                            ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
 
                        if (!dev->mc_count) {
                                lbs_deb_net("no multicast addresses, "
                                       "disabling multicast\n");
-                               adapter->currentpacketfilter &=
+                               priv->currentpacketfilter &=
                                    ~CMD_ACT_MAC_MULTICAST_ENABLE;
                        } else {
                                int i;
 
-                               adapter->currentpacketfilter |=
+                               priv->currentpacketfilter |=
                                    CMD_ACT_MAC_MULTICAST_ENABLE;
 
-                               adapter->nr_of_multicastmacaddr =
-                                   libertas_copy_multicast_address(adapter, dev);
+                               priv->nr_of_multicastmacaddr =
+                                   lbs_copy_multicast_address(priv, dev);
 
                                lbs_deb_net("multicast addresses: %d\n",
                                       dev->mc_count);
 
                                for (i = 0; i < dev->mc_count; i++) {
-                                       lbs_deb_net("Multicast address %d:%s\n",
+                                       lbs_deb_net("Multicast address %d: %s\n",
                                               i, print_mac(mac,
-                                              adapter->multicastlist[i]));
+                                              priv->multicastlist[i]));
                                }
                                /* send multicast addresses to firmware */
-                               libertas_prepare_and_send_command(priv,
+                               lbs_prepare_and_send_command(priv,
                                                      CMD_MAC_MULTICAST_ADR,
                                                      CMD_ACT_SET, 0, 0,
                                                      NULL);
@@ -737,26 +642,25 @@ static void libertas_set_multicast_list(struct net_device *dev)
                }
        }
 
-       if (adapter->currentpacketfilter != oldpacketfilter) {
-               libertas_set_mac_packet_filter(priv);
+       if (priv->currentpacketfilter != oldpacketfilter) {
+               lbs_set_mac_packet_filter(priv);
        }
 
        lbs_deb_leave(LBS_DEB_NET);
 }
 
 /**
- *  @brief This function handles the major jobs in the WLAN driver.
+ *  @brief This function handles the major jobs in the LBS driver.
  *  It handles all events generated by firmware, RX data received
  *  from firmware and TX data sent from kernel.
  *
- *  @param data    A pointer to wlan_thread structure
+ *  @param data    A pointer to lbs_thread structure
  *  @return       0
  */
-static int libertas_thread(void *data)
+static int lbs_thread(void *data)
 {
        struct net_device *dev = data;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        wait_queue_t wait;
        u8 ireg = 0;
 
@@ -764,215 +668,291 @@ static int libertas_thread(void *data)
 
        init_waitqueue_entry(&wait, current);
 
-       set_freezable();
        for (;;) {
-               lbs_deb_thread( "main-thread 111: intcounter=%d "
-                      "currenttxskb=%p dnld_sent=%d\n",
-                      adapter->intcounter,
-                      adapter->currenttxskb, priv->dnld_sent);
+               int shouldsleep;
+
+               lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+                               priv->intcounter, priv->currenttxskb, priv->dnld_sent);
 
                add_wait_queue(&priv->waitq, &wait);
                set_current_state(TASK_INTERRUPTIBLE);
-               spin_lock_irq(&adapter->driver_lock);
-               if ((adapter->psstate == PS_STATE_SLEEP) ||
-                   (!adapter->intcounter
-                    && (priv->dnld_sent || adapter->cur_cmd ||
-                        list_empty(&adapter->cmdpendingq)))) {
-                       lbs_deb_thread(
-                              "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
-                              adapter->connect_status, adapter->intcounter,
-                              adapter->psmode, adapter->psstate);
-                       spin_unlock_irq(&adapter->driver_lock);
+               spin_lock_irq(&priv->driver_lock);
+
+               if (kthread_should_stop())
+                       shouldsleep = 0;        /* Bye */
+               else if (priv->surpriseremoved)
+                       shouldsleep = 1;        /* We need to wait until we're _told_ to die */
+               else if (priv->psstate == PS_STATE_SLEEP)
+                       shouldsleep = 1;        /* Sleep mode. Nothing we can do till it wakes */
+               else if (priv->intcounter)
+                       shouldsleep = 0;        /* Interrupt pending. Deal with it now */
+               else if (priv->cmd_timed_out)
+                       shouldsleep = 0;        /* Command timed out. Recover */
+               else if (!priv->fw_ready)
+                       shouldsleep = 1;        /* Firmware not ready. We're waiting for it */
+               else if (priv->dnld_sent)
+                       shouldsleep = 1;        /* Something is en route to the device already */
+               else if (priv->tx_pending_len > 0)
+                       shouldsleep = 0;        /* We've a packet to send */
+               else if (priv->cur_cmd)
+                       shouldsleep = 1;        /* Can't send a command; one already running */
+               else if (!list_empty(&priv->cmdpendingq))
+                       shouldsleep = 0;        /* We have a command to send */
+               else
+                       shouldsleep = 1;        /* No command */
+
+               if (shouldsleep) {
+                       lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
+                                      priv->connect_status, priv->intcounter,
+                                      priv->psmode, priv->psstate);
+                       spin_unlock_irq(&priv->driver_lock);
                        schedule();
                } else
-                       spin_unlock_irq(&adapter->driver_lock);
+                       spin_unlock_irq(&priv->driver_lock);
 
-               lbs_deb_thread(
-                      "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
-                      "dnld_sent=%d\n", adapter->intcounter,
-                      adapter->currenttxskb, priv->dnld_sent);
+               lbs_deb_thread("main-thread 222 (waking up): intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
 
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&priv->waitq, &wait);
-               try_to_freeze();
-
-               lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
-                      "dnld_sent=%d\n",
-                      adapter->intcounter,
-                      adapter->currenttxskb, priv->dnld_sent);
-
-               if (kthread_should_stop()
-                   || adapter->surpriseremoved) {
-                       lbs_deb_thread(
-                              "main-thread: break from main thread: surpriseremoved=0x%x\n",
-                              adapter->surpriseremoved);
+
+               lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
+
+               if (kthread_should_stop()) {
+                       lbs_deb_thread("main-thread: break from main thread\n");
                        break;
                }
 
+               if (priv->surpriseremoved) {
+                       lbs_deb_thread("adapter removed; waiting to die...\n");
+                       continue;
+               }
+
+               spin_lock_irq(&priv->driver_lock);
 
-               spin_lock_irq(&adapter->driver_lock);
-               if (adapter->intcounter) {
+               if (priv->intcounter) {
                        u8 int_status;
-                       adapter->intcounter = 0;
+
+                       priv->intcounter = 0;
                        int_status = priv->hw_get_int_status(priv, &ireg);
 
                        if (int_status) {
-                               lbs_deb_thread(
-                                      "main-thread: reading HOST_INT_STATUS_REG failed\n");
-                               spin_unlock_irq(&adapter->driver_lock);
+                               lbs_deb_thread("main-thread: reading HOST_INT_STATUS_REG failed\n");
+                               spin_unlock_irq(&priv->driver_lock);
                                continue;
                        }
-                       adapter->hisregcpy |= ireg;
+                       priv->hisregcpy |= ireg;
                }
 
-               lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
-                      "dnld_sent=%d\n",
-                      adapter->intcounter,
-                      adapter->currenttxskb, priv->dnld_sent);
+               lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+                              priv->intcounter, priv->currenttxskb, priv->dnld_sent);
 
                /* command response? */
-               if (adapter->hisregcpy & MRVDRV_CMD_UPLD_RDY) {
+               if (priv->hisregcpy & MRVDRV_CMD_UPLD_RDY) {
                        lbs_deb_thread("main-thread: cmd response ready\n");
 
-                       adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
-                       spin_unlock_irq(&adapter->driver_lock);
-                       libertas_process_rx_command(priv);
-                       spin_lock_irq(&adapter->driver_lock);
+                       priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
+                       spin_unlock_irq(&priv->driver_lock);
+                       lbs_process_rx_command(priv);
+                       spin_lock_irq(&priv->driver_lock);
                }
 
+               if (priv->cmd_timed_out && priv->cur_cmd) {
+                       struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
+
+                       if (++priv->nr_retries > 10) {
+                               lbs_pr_info("Excessive timeouts submitting command %x\n",
+                                           le16_to_cpu(cmdnode->cmdbuf->command));
+                               lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
+                               priv->nr_retries = 0;
+                       } else {
+                               priv->cur_cmd = NULL;
+                               lbs_pr_info("requeueing command %x due to timeout (#%d)\n",
+                                           le16_to_cpu(cmdnode->cmdbuf->command), priv->nr_retries);
+
+                               /* Stick it back at the _top_ of the pending queue
+                                  for immediate resubmission */
+                               list_add(&cmdnode->list, &priv->cmdpendingq);
+                       }
+               }
+               priv->cmd_timed_out = 0;
+
                /* Any Card Event */
-               if (adapter->hisregcpy & MRVDRV_CARDEVENT) {
+               if (priv->hisregcpy & MRVDRV_CARDEVENT) {
                        lbs_deb_thread("main-thread: Card Event Activity\n");
 
-                       adapter->hisregcpy &= ~MRVDRV_CARDEVENT;
+                       priv->hisregcpy &= ~MRVDRV_CARDEVENT;
 
                        if (priv->hw_read_event_cause(priv)) {
-                               lbs_pr_alert(
-                                      "main-thread: hw_read_event_cause failed\n");
-                               spin_unlock_irq(&adapter->driver_lock);
+                               lbs_pr_alert("main-thread: hw_read_event_cause failed\n");
+                               spin_unlock_irq(&priv->driver_lock);
                                continue;
                        }
-                       spin_unlock_irq(&adapter->driver_lock);
-                       libertas_process_event(priv);
+                       spin_unlock_irq(&priv->driver_lock);
+                       lbs_process_event(priv);
                } else
-                       spin_unlock_irq(&adapter->driver_lock);
+                       spin_unlock_irq(&priv->driver_lock);
+
+               if (!priv->fw_ready)
+                       continue;
 
                /* Check if we need to confirm Sleep Request received previously */
-               if (adapter->psstate == PS_STATE_PRE_SLEEP) {
-                       if (!priv->dnld_sent && !adapter->cur_cmd) {
-                               if (adapter->connect_status ==
-                                   LIBERTAS_CONNECTED) {
-                                       lbs_deb_thread(
-                                              "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
-                                              "dnld_sent=%d cur_cmd=%p, confirm now\n",
-                                              adapter->intcounter,
-                                              adapter->currenttxskb,
-                                              priv->dnld_sent,
-                                              adapter->cur_cmd);
-
-                                       libertas_ps_confirm_sleep(priv,
-                                                      (u16) adapter->psmode);
-                               } else {
-                                       /* workaround for firmware sending
-                                        * deauth/linkloss event immediately
-                                        * after sleep request, remove this
-                                        * after firmware fixes it
-                                        */
-                                       adapter->psstate = PS_STATE_AWAKE;
-                                       lbs_pr_alert(
-                                              "main-thread: ignore PS_SleepConfirm in non-connected state\n");
-                               }
+               if (priv->psstate == PS_STATE_PRE_SLEEP &&
+                   !priv->dnld_sent && !priv->cur_cmd) {
+                       if (priv->connect_status == LBS_CONNECTED) {
+                               lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n",
+                                              priv->intcounter, priv->currenttxskb, priv->dnld_sent, priv->cur_cmd);
+
+                               lbs_ps_confirm_sleep(priv, (u16) priv->psmode);
+                       } else {
+                               /* workaround for firmware sending
+                                * deauth/linkloss event immediately
+                                * after sleep request; remove this
+                                * after firmware fixes it
+                                */
+                               priv->psstate = PS_STATE_AWAKE;
+                               lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n");
                        }
                }
 
                /* The PS state is changed during processing of Sleep Request
                 * event above
                 */
-               if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
-                   (priv->adapter->psstate == PS_STATE_PRE_SLEEP))
+               if ((priv->psstate == PS_STATE_SLEEP) ||
+                   (priv->psstate == PS_STATE_PRE_SLEEP))
                        continue;
 
                /* Execute the next command */
-               if (!priv->dnld_sent && !priv->adapter->cur_cmd)
-                       libertas_execute_next_command(priv);
+               if (!priv->dnld_sent && !priv->cur_cmd)
+                       lbs_execute_next_command(priv);
 
                /* Wake-up command waiters which can't sleep in
-                * libertas_prepare_and_send_command
+                * lbs_prepare_and_send_command
                 */
-               if (!adapter->nr_cmd_pending)
-                       wake_up_all(&adapter->cmd_pending);
-
-               libertas_tx_runqueue(priv);
+               if (!list_empty(&priv->cmdpendingq))
+                       wake_up_all(&priv->cmd_pending);
+
+               spin_lock_irq(&priv->driver_lock);
+               if (!priv->dnld_sent && priv->tx_pending_len > 0) {
+                       int ret = priv->hw_host_to_card(priv, MVMS_DAT,
+                                                       priv->tx_pending_buf,
+                                                       priv->tx_pending_len);
+                       if (ret) {
+                               lbs_deb_tx("host_to_card failed %d\n", ret);
+                               priv->dnld_sent = DNLD_RES_RECEIVED;
+                       }
+                       priv->tx_pending_len = 0;
+                       if (!priv->currenttxskb) {
+                               /* We can wake the queues immediately if we aren't
+                                  waiting for TX feedback */
+                               if (priv->connect_status == LBS_CONNECTED)
+                                       netif_wake_queue(priv->dev);
+                               if (priv->mesh_dev &&
+                                   priv->mesh_connect_status == LBS_CONNECTED)
+                                       netif_wake_queue(priv->mesh_dev);
+                       }
+               }
+               spin_unlock_irq(&priv->driver_lock);
        }
 
-       del_timer(&adapter->command_timer);
-       adapter->nr_cmd_pending = 0;
-       wake_up_all(&adapter->cmd_pending);
+       del_timer(&priv->command_timer);
+       wake_up_all(&priv->cmd_pending);
 
        lbs_deb_leave(LBS_DEB_THREAD);
        return 0;
 }
 
+static int lbs_suspend_callback(struct lbs_private *priv, unsigned long dummy,
+                               struct cmd_header *cmd)
+{
+       lbs_deb_enter(LBS_DEB_FW);
+
+       netif_device_detach(priv->dev);
+       if (priv->mesh_dev)
+               netif_device_detach(priv->mesh_dev);
+
+       priv->fw_ready = 0;
+       lbs_deb_leave(LBS_DEB_FW);
+       return 0;
+}
+
+int lbs_suspend(struct lbs_private *priv)
+{
+       struct cmd_header cmd;
+       int ret;
+
+       lbs_deb_enter(LBS_DEB_FW);
+
+       if (priv->wol_criteria == 0xffffffff) {
+               lbs_pr_info("Suspend attempt without configuring wake params!\n");
+               return -EINVAL;
+       }
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
+                       sizeof(cmd), lbs_suspend_callback, 0);
+       if (ret)
+               lbs_pr_info("HOST_SLEEP_ACTIVATE failed: %d\n", ret);
+
+       lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lbs_suspend);
+
+int lbs_resume(struct lbs_private *priv)
+{
+       lbs_deb_enter(LBS_DEB_FW);
+
+       priv->fw_ready = 1;
+
+       /* Firmware doesn't seem to give us RX packets any more
+          until we send it some command. Might as well update */
+       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+                                    0, 0, NULL);
+
+       netif_device_attach(priv->dev);
+       if (priv->mesh_dev)
+               netif_device_attach(priv->mesh_dev);
+
+       lbs_deb_leave(LBS_DEB_FW);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lbs_resume);
+
 /**
  *  @brief This function downloads firmware image, gets
  *  HW spec from firmware and set basic parameters to
  *  firmware.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @return       0 or -1
  */
-static int wlan_setup_firmware(wlan_private * priv)
+static int lbs_setup_firmware(struct lbs_private *priv)
 {
        int ret = -1;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ds_mesh_access mesh_access;
 
        lbs_deb_enter(LBS_DEB_FW);
 
        /*
         * Read MAC address from HW
         */
-       memset(adapter->current_addr, 0xff, ETH_ALEN);
-
-       ret = libertas_prepare_and_send_command(priv, CMD_GET_HW_SPEC,
-                                   0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
+       memset(priv->current_addr, 0xff, ETH_ALEN);
+       ret = lbs_update_hw_spec(priv);
        if (ret) {
                ret = -1;
                goto done;
        }
 
-       libertas_set_mac_packet_filter(priv);
-
-       /* Get the supported Data rates */
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,
-                                   CMD_ACT_GET_TX_RATE,
-                                   CMD_OPTION_WAITFORRSP, 0, NULL);
+       lbs_set_mac_packet_filter(priv);
 
-       if (ret) {
+       ret = lbs_get_data_rate(priv);
+       if (ret < 0) {
                ret = -1;
                goto done;
        }
 
-       /* Disable mesh autostart */
-       if (priv->mesh_dev) {
-               memset(&mesh_access, 0, sizeof(mesh_access));
-               mesh_access.data[0] = cpu_to_le32(0);
-               ret = libertas_prepare_and_send_command(priv,
-                               CMD_MESH_ACCESS,
-                               CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-                               CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
-               if (ret) {
-                       ret = -1;
-                       goto done;
-               }
-               priv->mesh_autostart_enabled = 0;
-       }
-
-       /* Set the boot2 version in firmware */
-       ret = libertas_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,
-                                   0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
        ret = 0;
 done:
        lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
@@ -985,164 +965,130 @@ done:
  */
 static void command_timer_fn(unsigned long data)
 {
-       wlan_private *priv = (wlan_private *)data;
-       wlan_adapter *adapter = priv->adapter;
-       struct cmd_ctrl_node *ptempnode;
-       struct cmd_ds_command *cmd;
+       struct lbs_private *priv = (struct lbs_private *)data;
        unsigned long flags;
 
-       ptempnode = adapter->cur_cmd;
-       if (ptempnode == NULL) {
-               lbs_deb_fw("ptempnode empty\n");
-               return;
-       }
+       lbs_deb_enter(LBS_DEB_CMD);
+       spin_lock_irqsave(&priv->driver_lock, flags);
 
-       cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
-       if (!cmd) {
-               lbs_deb_fw("cmd is NULL\n");
-               return;
+       if (!priv->cur_cmd) {
+               lbs_pr_info("Command timer expired; no pending command\n");
+               goto out;
        }
 
-       lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);
-
-       if (!adapter->fw_ready)
-               return;
-
-       spin_lock_irqsave(&adapter->driver_lock, flags);
-       adapter->cur_cmd = NULL;
-       spin_unlock_irqrestore(&adapter->driver_lock, flags);
-
-       lbs_deb_fw("re-sending same command because of timeout\n");
-       libertas_queue_cmd(adapter, ptempnode, 0);
+       lbs_pr_info("Command %x timed out\n", le16_to_cpu(priv->cur_cmd->cmdbuf->command));
 
+       priv->cmd_timed_out = 1;
        wake_up_interruptible(&priv->waitq);
-
-       return;
+out:
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+       lbs_deb_leave(LBS_DEB_CMD);
 }
 
-static int libertas_init_adapter(wlan_private * priv)
+static int lbs_init_adapter(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
        size_t bufsize;
        int i, ret = 0;
 
+       lbs_deb_enter(LBS_DEB_MAIN);
+
        /* Allocate buffer to store the BSSID list */
        bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
-       adapter->networks = kzalloc(bufsize, GFP_KERNEL);
-       if (!adapter->networks) {
+       priv->networks = kzalloc(bufsize, GFP_KERNEL);
+       if (!priv->networks) {
                lbs_pr_err("Out of memory allocating beacons\n");
                ret = -1;
                goto out;
        }
 
        /* Initialize scan result lists */
-       INIT_LIST_HEAD(&adapter->network_free_list);
-       INIT_LIST_HEAD(&adapter->network_list);
+       INIT_LIST_HEAD(&priv->network_free_list);
+       INIT_LIST_HEAD(&priv->network_list);
        for (i = 0; i < MAX_NETWORK_COUNT; i++) {
-               list_add_tail(&adapter->networks[i].list,
-                             &adapter->network_free_list);
+               list_add_tail(&priv->networks[i].list,
+                             &priv->network_free_list);
        }
 
-       adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);
-       adapter->libertas_ps_confirm_sleep.command =
+       priv->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++priv->seqnum);
+       priv->lbs_ps_confirm_sleep.command =
            cpu_to_le16(CMD_802_11_PS_MODE);
-       adapter->libertas_ps_confirm_sleep.size =
+       priv->lbs_ps_confirm_sleep.size =
            cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
-       adapter->libertas_ps_confirm_sleep.action =
+       priv->lbs_ps_confirm_sleep.action =
            cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
 
-       memset(adapter->current_addr, 0xff, ETH_ALEN);
-
-       adapter->connect_status = LIBERTAS_DISCONNECTED;
-       adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
-       adapter->mode = IW_MODE_INFRA;
-       adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
-       adapter->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
-       adapter->radioon = RADIO_ON;
-       adapter->auto_rate = 1;
-       adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
-       adapter->psmode = WLAN802_11POWERMODECAM;
-       adapter->psstate = PS_STATE_FULL_POWER;
+       memset(priv->current_addr, 0xff, ETH_ALEN);
 
-       mutex_init(&adapter->lock);
+       priv->connect_status = LBS_DISCONNECTED;
+       priv->mesh_connect_status = LBS_DISCONNECTED;
+       priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
+       priv->mode = IW_MODE_INFRA;
+       priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
+       priv->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
+       priv->radioon = RADIO_ON;
+       priv->auto_rate = 1;
+       priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
+       priv->psmode = LBS802_11POWERMODECAM;
+       priv->psstate = PS_STATE_FULL_POWER;
 
-       memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
-       adapter->tx_queue_idx = 0;
-       spin_lock_init(&adapter->txqueue_lock);
+       mutex_init(&priv->lock);
 
-       setup_timer(&adapter->command_timer, command_timer_fn,
-                   (unsigned long)priv);
+       setup_timer(&priv->command_timer, command_timer_fn,
+               (unsigned long)priv);
 
-       INIT_LIST_HEAD(&adapter->cmdfreeq);
-       INIT_LIST_HEAD(&adapter->cmdpendingq);
+       INIT_LIST_HEAD(&priv->cmdfreeq);
+       INIT_LIST_HEAD(&priv->cmdpendingq);
 
-       spin_lock_init(&adapter->driver_lock);
-       init_waitqueue_head(&adapter->cmd_pending);
-       adapter->nr_cmd_pending = 0;
+       spin_lock_init(&priv->driver_lock);
+       init_waitqueue_head(&priv->cmd_pending);
 
        /* Allocate the command buffers */
-       if (libertas_allocate_cmd_buffer(priv)) {
+       if (lbs_allocate_cmd_buffer(priv)) {
                lbs_pr_err("Out of memory allocating command buffers\n");
                ret = -1;
        }
 
 out:
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+
        return ret;
 }
 
-static void libertas_free_adapter(wlan_private * priv)
+static void lbs_free_adapter(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
-
-       if (!adapter) {
-               lbs_deb_fw("why double free adapter?\n");
-               return;
-       }
-
-       lbs_deb_fw("free command buffer\n");
-       libertas_free_cmd_buffer(priv);
-
-       lbs_deb_fw("free command_timer\n");
-       del_timer(&adapter->command_timer);
+       lbs_deb_enter(LBS_DEB_MAIN);
 
-       lbs_deb_fw("free scan results table\n");
-       kfree(adapter->networks);
-       adapter->networks = NULL;
+       lbs_free_cmd_buffer(priv);
+       del_timer(&priv->command_timer);
+       kfree(priv->networks);
+       priv->networks = NULL;
 
-       /* Free the adapter object itself */
-       lbs_deb_fw("free adapter\n");
-       kfree(adapter);
-       priv->adapter = NULL;
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 
 /**
  * @brief This function adds the card. it will probe the
- * card, allocate the wlan_priv and initialize the device.
+ * card, allocate the lbs_priv and initialize the device.
  *
  *  @param card    A pointer to card
- *  @return       A pointer to wlan_private structure
+ *  @return       A pointer to struct lbs_private structure
  */
-wlan_private *libertas_add_card(void *card, struct device *dmdev)
+struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 {
        struct net_device *dev = NULL;
-       wlan_private *priv = NULL;
+       struct lbs_private *priv = NULL;
 
-       lbs_deb_enter(LBS_DEB_NET);
+       lbs_deb_enter(LBS_DEB_MAIN);
 
        /* Allocate an Ethernet device and register it */
-       if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
+       dev = alloc_etherdev(sizeof(struct lbs_private));
+       if (!dev) {
                lbs_pr_err("init ethX device failed\n");
                goto done;
        }
        priv = dev->priv;
 
-       /* allocate buffer for wlan_adapter */
-       if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
-               lbs_pr_err("allocate buffer for wlan_adapter failed\n");
-               goto err_kzalloc;
-       }
-
-       if (libertas_init_adapter(priv)) {
+       if (lbs_init_adapter(priv)) {
                lbs_pr_err("failed to initialize adapter structure.\n");
                goto err_init_adapter;
        }
@@ -1151,81 +1097,78 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev)
        priv->card = card;
        priv->mesh_open = 0;
        priv->infra_open = 0;
-       priv->hotplug_device = dmdev;
 
        /* Setup the OS Interface to our functions */
-       dev->open = libertas_open;
-       dev->hard_start_xmit = libertas_pre_start_xmit;
-       dev->stop = libertas_close;
-       dev->set_mac_address = libertas_set_mac_address;
-       dev->tx_timeout = libertas_tx_timeout;
-       dev->get_stats = libertas_get_stats;
+       dev->open = lbs_dev_open;
+       dev->hard_start_xmit = lbs_hard_start_xmit;
+       dev->stop = lbs_eth_stop;
+       dev->set_mac_address = lbs_set_mac_address;
+       dev->tx_timeout = lbs_tx_timeout;
+       dev->get_stats = lbs_get_stats;
        dev->watchdog_timeo = 5 * HZ;
-       dev->ethtool_ops = &libertas_ethtool_ops;
+       dev->ethtool_ops = &lbs_ethtool_ops;
 #ifdef WIRELESS_EXT
-       dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def;
+       dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def;
 #endif
        dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
-       dev->set_multicast_list = libertas_set_multicast_list;
+       dev->set_multicast_list = lbs_set_multicast_list;
 
        SET_NETDEV_DEV(dev, dmdev);
 
        priv->rtap_net_dev = NULL;
-       if (device_create_file(dmdev, &dev_attr_libertas_rtap))
-               goto err_init_adapter;
 
        lbs_deb_thread("Starting main thread...\n");
        init_waitqueue_head(&priv->waitq);
-       priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main");
+       priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
        if (IS_ERR(priv->main_thread)) {
                lbs_deb_thread("Error creating main thread.\n");
-               goto err_kthread_run;
+               goto err_init_adapter;
        }
 
-       priv->work_thread = create_singlethread_workqueue("libertas_worker");
-       INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
-       INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker);
-       INIT_WORK(&priv->sync_channel, libertas_sync_channel);
+       priv->work_thread = create_singlethread_workqueue("lbs_worker");
+       INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
+       INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
+       INIT_WORK(&priv->sync_channel, lbs_sync_channel);
 
-       goto done;
+       sprintf(priv->mesh_ssid, "mesh");
+       priv->mesh_ssid_len = 4;
 
-err_kthread_run:
-       device_remove_file(dmdev, &dev_attr_libertas_rtap);
+       priv->wol_criteria = 0xffffffff;
+       priv->wol_gpio = 0xff;
 
-err_init_adapter:
-       libertas_free_adapter(priv);
+       goto done;
 
-err_kzalloc:
+err_init_adapter:
+       lbs_free_adapter(priv);
        free_netdev(dev);
        priv = NULL;
 
 done:
-       lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
+       lbs_deb_leave_args(LBS_DEB_MAIN, "priv %p", priv);
        return priv;
 }
-EXPORT_SYMBOL_GPL(libertas_add_card);
+EXPORT_SYMBOL_GPL(lbs_add_card);
 
 
-int libertas_remove_card(wlan_private *priv)
+int lbs_remove_card(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct net_device *dev = priv->dev;
        union iwreq_data wrqu;
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       libertas_remove_rtap(priv);
+       lbs_remove_mesh(priv);
+       lbs_remove_rtap(priv);
 
        dev = priv->dev;
-       device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap);
 
        cancel_delayed_work(&priv->scan_work);
        cancel_delayed_work(&priv->assoc_work);
        destroy_workqueue(priv->work_thread);
 
-       if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
-               adapter->psmode = WLAN802_11POWERMODECAM;
-               libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
+       if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
+               priv->psmode = LBS802_11POWERMODECAM;
+               lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
        }
 
        memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
@@ -1233,10 +1176,10 @@ int libertas_remove_card(wlan_private *priv)
        wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
 
        /* Stop the thread servicing the interrupts */
-       adapter->surpriseremoved = 1;
+       priv->surpriseremoved = 1;
        kthread_stop(priv->main_thread);
 
-       libertas_free_adapter(priv);
+       lbs_free_adapter(priv);
 
        priv->dev = NULL;
        free_netdev(dev);
@@ -1244,10 +1187,10 @@ int libertas_remove_card(wlan_private *priv)
        lbs_deb_leave(LBS_DEB_MAIN);
        return 0;
 }
-EXPORT_SYMBOL_GPL(libertas_remove_card);
+EXPORT_SYMBOL_GPL(lbs_remove_card);
 
 
-int libertas_start_card(wlan_private *priv)
+int lbs_start_card(struct lbs_private *priv)
 {
        struct net_device *dev = priv->dev;
        int ret = -1;
@@ -1255,19 +1198,52 @@ int libertas_start_card(wlan_private *priv)
        lbs_deb_enter(LBS_DEB_MAIN);
 
        /* poke the firmware */
-       ret = wlan_setup_firmware(priv);
+       ret = lbs_setup_firmware(priv);
        if (ret)
                goto done;
 
        /* init 802.11d */
-       libertas_init_11d(priv);
+       lbs_init_11d(priv);
 
        if (register_netdev(dev)) {
                lbs_pr_err("cannot register ethX device\n");
                goto done;
        }
+       if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+               lbs_pr_err("cannot register lbs_rtap attribute\n");
+
+       lbs_update_channel(priv);
+
+       /* 5.0.16p0 is known to NOT support any mesh */
+       if (priv->fwrelease > 0x05001000) {
+               /* 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
+                  but we check them in that order because 20.pXX doesn't
+                  give an error -- it just silently fails. */
+
+               /* 5.110.20.pXX firmware will fail the command if the channel
+                  doesn't match the existing channel. But only if the TLV
+                  is correct. If the channel is wrong, _BOTH_ versions will
+                  give an error to 0x100+291, and allow 0x100+37 to succeed.
+                  It's just that 5.110.20.pXX will not have done anything
+                  useful */
+
+               priv->mesh_tlv = 0x100 + 291;
+               if (lbs_mesh_config(priv, 1, priv->curbssparams.channel)) {
+                       priv->mesh_tlv = 0x100 + 37;
+                       if (lbs_mesh_config(priv, 1, priv->curbssparams.channel))
+                               priv->mesh_tlv = 0;
+               }
+               if (priv->mesh_tlv) {
+                       lbs_add_mesh(priv);
 
-       libertas_debugfs_init_one(priv, dev);
+                       if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+                               lbs_pr_err("cannot register lbs_mesh attribute\n");
+               }
+       }
+
+       lbs_debugfs_init_one(priv, dev);
 
        lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
 
@@ -1277,10 +1253,10 @@ done:
        lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_start_card);
+EXPORT_SYMBOL_GPL(lbs_start_card);
 
 
-int libertas_stop_card(wlan_private *priv)
+int lbs_stop_card(struct lbs_private *priv)
 {
        struct net_device *dev = priv->dev;
        int ret = -1;
@@ -1292,31 +1268,35 @@ int libertas_stop_card(wlan_private *priv)
        netif_stop_queue(priv->dev);
        netif_carrier_off(priv->dev);
 
-       libertas_debugfs_remove_one(priv);
+       lbs_debugfs_remove_one(priv);
+       device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
+       if (priv->mesh_tlv)
+               device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
 
        /* Flush pending command nodes */
-       spin_lock_irqsave(&priv->adapter->driver_lock, flags);
-       list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
+               cmdnode->result = -ENOENT;
                cmdnode->cmdwaitqwoken = 1;
                wake_up_interruptible(&cmdnode->cmdwait_q);
        }
-       spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
 
        unregister_netdev(dev);
 
        lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_stop_card);
+EXPORT_SYMBOL_GPL(lbs_stop_card);
 
 
 /**
  * @brief This function adds mshX interface
  *
- *  @param priv    A pointer to the wlan_private structure
+ *  @param priv    A pointer to the struct lbs_private structure
  *  @return       0 if successful, -X otherwise
  */
-int libertas_add_mesh(wlan_private *priv, struct device *dev)
+static int lbs_add_mesh(struct lbs_private *priv)
 {
        struct net_device *mesh_dev = NULL;
        int ret = 0;
@@ -1332,16 +1312,16 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev)
        mesh_dev->priv = priv;
        priv->mesh_dev = mesh_dev;
 
-       mesh_dev->open = libertas_mesh_open;
-       mesh_dev->hard_start_xmit = libertas_mesh_pre_start_xmit;
-       mesh_dev->stop = libertas_mesh_close;
-       mesh_dev->get_stats = libertas_get_stats;
-       mesh_dev->set_mac_address = libertas_set_mac_address;
-       mesh_dev->ethtool_ops = &libertas_ethtool_ops;
+       mesh_dev->open = lbs_dev_open;
+       mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
+       mesh_dev->stop = lbs_mesh_stop;
+       mesh_dev->get_stats = lbs_get_stats;
+       mesh_dev->set_mac_address = lbs_set_mac_address;
+       mesh_dev->ethtool_ops = &lbs_ethtool_ops;
        memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
                        sizeof(priv->dev->dev_addr));
 
-       SET_NETDEV_DEV(priv->mesh_dev, dev);
+       SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
 
 #ifdef WIRELESS_EXT
        mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
@@ -1353,7 +1333,7 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev)
                goto err_free;
        }
 
-       ret = sysfs_create_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group);
+       ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
        if (ret)
                goto err_unregister;
 
@@ -1371,33 +1351,28 @@ done:
        lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_add_mesh);
+EXPORT_SYMBOL_GPL(lbs_add_mesh);
 
 
-void libertas_remove_mesh(wlan_private *priv)
+static void lbs_remove_mesh(struct lbs_private *priv)
 {
        struct net_device *mesh_dev;
 
-       lbs_deb_enter(LBS_DEB_MAIN);
-
-       if (!priv)
-               goto out;
 
        mesh_dev = priv->mesh_dev;
+       if (!mesh_dev)
+               return;
 
+       lbs_deb_enter(LBS_DEB_MESH);
        netif_stop_queue(mesh_dev);
        netif_carrier_off(priv->mesh_dev);
-
-       sysfs_remove_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group);
+       sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
        unregister_netdev(mesh_dev);
-
-       priv->mesh_dev = NULL ;
+       priv->mesh_dev = NULL;
        free_netdev(mesh_dev);
-
-out:
-       lbs_deb_leave(LBS_DEB_MAIN);
+       lbs_deb_leave(LBS_DEB_MESH);
 }
-EXPORT_SYMBOL_GPL(libertas_remove_mesh);
+EXPORT_SYMBOL_GPL(lbs_remove_mesh);
 
 /**
  *  @brief This function finds the CFP in
@@ -1408,7 +1383,7 @@ EXPORT_SYMBOL_GPL(libertas_remove_mesh);
  *  @param cfp_no  A pointer to CFP number
  *  @return       A pointer to CFP
  */
-struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
+struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
 {
        int i, end;
 
@@ -1430,9 +1405,8 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c
        return NULL;
 }
 
-int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
+int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
        int i = 0;
 
@@ -1441,24 +1415,22 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band)
 
        lbs_deb_enter(LBS_DEB_MAIN);
 
-       memset(adapter->region_channel, 0, sizeof(adapter->region_channel));
+       memset(priv->region_channel, 0, sizeof(priv->region_channel));
 
-       {
-               cfp = libertas_get_region_cfp_table(region, band, &cfp_no);
-               if (cfp != NULL) {
-                       adapter->region_channel[i].nrcfp = cfp_no;
-                       adapter->region_channel[i].CFP = cfp;
-               } else {
-                       lbs_deb_main("wrong region code %#x in band B/G\n",
-                              region);
-                       ret = -1;
-                       goto out;
-               }
-               adapter->region_channel[i].valid = 1;
-               adapter->region_channel[i].region = region;
-               adapter->region_channel[i].band = band;
-               i++;
+       cfp = lbs_get_region_cfp_table(region, band, &cfp_no);
+       if (cfp != NULL) {
+               priv->region_channel[i].nrcfp = cfp_no;
+               priv->region_channel[i].CFP = cfp;
+       } else {
+               lbs_deb_main("wrong region code %#x in band B/G\n",
+                      region);
+               ret = -1;
+               goto out;
        }
+       priv->region_channel[i].valid = 1;
+       priv->region_channel[i].region = region;
+       priv->region_channel[i].band = band;
+       i++;
 out:
        lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
@@ -1472,58 +1444,46 @@ out:
  *  @param dev     A pointer to net_device structure
  *  @return       n/a
  */
-void libertas_interrupt(struct net_device *dev)
+void lbs_interrupt(struct lbs_private *priv)
 {
-       wlan_private *priv = dev->priv;
-
        lbs_deb_enter(LBS_DEB_THREAD);
 
-       lbs_deb_thread("libertas_interrupt: intcounter=%d\n",
-              priv->adapter->intcounter);
-
-       priv->adapter->intcounter++;
-
-       if (priv->adapter->psstate == PS_STATE_SLEEP) {
-               priv->adapter->psstate = PS_STATE_AWAKE;
-               netif_wake_queue(dev);
-               if (priv->mesh_dev)
-                       netif_wake_queue(priv->mesh_dev);
-       }
-
+       lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);
+       priv->intcounter++;
+       if (priv->psstate == PS_STATE_SLEEP)
+               priv->psstate = PS_STATE_AWAKE;
        wake_up_interruptible(&priv->waitq);
 
        lbs_deb_leave(LBS_DEB_THREAD);
 }
-EXPORT_SYMBOL_GPL(libertas_interrupt);
+EXPORT_SYMBOL_GPL(lbs_interrupt);
 
-int libertas_reset_device(wlan_private *priv)
+int lbs_reset_device(struct lbs_private *priv)
 {
        int ret;
 
        lbs_deb_enter(LBS_DEB_MAIN);
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_RESET,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET,
                                    CMD_ACT_HALT, 0, 0, NULL);
        msleep_interruptible(10);
 
        lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_reset_device);
+EXPORT_SYMBOL_GPL(lbs_reset_device);
 
-static int libertas_init_module(void)
+static int __init lbs_init_module(void)
 {
        lbs_deb_enter(LBS_DEB_MAIN);
-       libertas_debugfs_init();
+       lbs_debugfs_init();
        lbs_deb_leave(LBS_DEB_MAIN);
        return 0;
 }
 
-static void libertas_exit_module(void)
+static void __exit lbs_exit_module(void)
 {
        lbs_deb_enter(LBS_DEB_MAIN);
-
-       libertas_debugfs_remove();
-
+       lbs_debugfs_remove();
        lbs_deb_leave(LBS_DEB_MAIN);
 }
 
@@ -1531,79 +1491,89 @@ static void libertas_exit_module(void)
  * rtap interface support fuctions
  */
 
-static int libertas_rtap_open(struct net_device *dev)
+static int lbs_rtap_open(struct net_device *dev)
 {
-        netif_carrier_off(dev);
-        netif_stop_queue(dev);
-        return 0;
+       /* Yes, _stop_ the queue. Because we don't support injection */
+       lbs_deb_enter(LBS_DEB_MAIN);
+       netif_carrier_off(dev);
+       netif_stop_queue(dev);
+       lbs_deb_leave(LBS_DEB_LEAVE);
+       return 0;
 }
 
-static int libertas_rtap_stop(struct net_device *dev)
+static int lbs_rtap_stop(struct net_device *dev)
 {
-        return 0;
+       lbs_deb_enter(LBS_DEB_MAIN);
+       lbs_deb_leave(LBS_DEB_MAIN);
+       return 0;
 }
 
-static int libertas_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-        netif_stop_queue(dev);
-        return -EOPNOTSUPP;
+       netif_stop_queue(dev);
+       return NETDEV_TX_BUSY;
 }
 
-static struct net_device_stats *libertas_rtap_get_stats(struct net_device *dev)
+static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
 {
-       wlan_private *priv = dev->priv;
-       return &priv->ieee->stats;
+       struct lbs_private *priv = dev->priv;
+       lbs_deb_enter(LBS_DEB_NET);
+       return &priv->stats;
 }
 
 
-void libertas_remove_rtap(wlan_private *priv)
+static void lbs_remove_rtap(struct lbs_private *priv)
 {
+       lbs_deb_enter(LBS_DEB_MAIN);
        if (priv->rtap_net_dev == NULL)
                return;
        unregister_netdev(priv->rtap_net_dev);
-       free_ieee80211(priv->rtap_net_dev);
+       free_netdev(priv->rtap_net_dev);
        priv->rtap_net_dev = NULL;
+       lbs_deb_leave(LBS_DEB_MAIN);
 }
 
-int libertas_add_rtap(wlan_private *priv)
+static int lbs_add_rtap(struct lbs_private *priv)
 {
-       int rc = 0;
-
-       if (priv->rtap_net_dev)
-               return -EPERM;
-
-       priv->rtap_net_dev = alloc_ieee80211(0);
-       if (priv->rtap_net_dev == NULL)
-               return -ENOMEM;
-
-
-       priv->ieee = netdev_priv(priv->rtap_net_dev);
+       int ret = 0;
+       struct net_device *rtap_dev;
 
-       strcpy(priv->rtap_net_dev->name, "rtap%d");
+       lbs_deb_enter(LBS_DEB_MAIN);
+       if (priv->rtap_net_dev) {
+               ret = -EPERM;
+               goto out;
+       }
 
-       priv->rtap_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-       priv->rtap_net_dev->open = libertas_rtap_open;
-       priv->rtap_net_dev->stop = libertas_rtap_stop;
-       priv->rtap_net_dev->get_stats = libertas_rtap_get_stats;
-       priv->rtap_net_dev->hard_start_xmit = libertas_rtap_hard_start_xmit;
-       priv->rtap_net_dev->set_multicast_list = libertas_set_multicast_list;
-       priv->rtap_net_dev->priv = priv;
+       rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
+       if (rtap_dev == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
-       priv->ieee->iw_mode = IW_MODE_MONITOR;
+       memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
+       rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+       rtap_dev->open = lbs_rtap_open;
+       rtap_dev->stop = lbs_rtap_stop;
+       rtap_dev->get_stats = lbs_rtap_get_stats;
+       rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
+       rtap_dev->set_multicast_list = lbs_set_multicast_list;
+       rtap_dev->priv = priv;
 
-       rc = register_netdev(priv->rtap_net_dev);
-       if (rc) {
-               free_ieee80211(priv->rtap_net_dev);
-               priv->rtap_net_dev = NULL;
-               return rc;
+       ret = register_netdev(rtap_dev);
+       if (ret) {
+               free_netdev(rtap_dev);
+               goto out;
        }
+       priv->rtap_net_dev = rtap_dev;
 
-       return 0;
+out:
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+       return ret;
 }
 
 
-module_init(libertas_init_module);
-module_exit(libertas_exit_module);
+module_init(lbs_init_module);
+module_exit(lbs_exit_module);
 
 MODULE_DESCRIPTION("Libertas WLAN Driver Library");
 MODULE_AUTHOR("Marvell International Ltd.");
index 0420e5b9ff9bbde84e72eecba277718cb9e1497e..149557a478ac0dc4f0820c4236d4922bdc53e8c1 100644 (file)
@@ -35,134 +35,114 @@ struct rx80211packethdr {
        void *eth80211_hdr;
 } __attribute__ ((packed));
 
-static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb);
+static int process_rxed_802_11_packet(struct lbs_private *priv,
+       struct sk_buff *skb);
 
 /**
  *  @brief This function computes the avgSNR .
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @return       avgSNR
  */
-static u8 wlan_getavgsnr(wlan_private * priv)
+static u8 lbs_getavgsnr(struct lbs_private *priv)
 {
        u8 i;
        u16 temp = 0;
-       wlan_adapter *adapter = priv->adapter;
-       if (adapter->numSNRNF == 0)
+       if (priv->numSNRNF == 0)
                return 0;
-       for (i = 0; i < adapter->numSNRNF; i++)
-               temp += adapter->rawSNR[i];
-       return (u8) (temp / adapter->numSNRNF);
+       for (i = 0; i < priv->numSNRNF; i++)
+               temp += priv->rawSNR[i];
+       return (u8) (temp / priv->numSNRNF);
 
 }
 
 /**
  *  @brief This function computes the AvgNF
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @return       AvgNF
  */
-static u8 wlan_getavgnf(wlan_private * priv)
+static u8 lbs_getavgnf(struct lbs_private *priv)
 {
        u8 i;
        u16 temp = 0;
-       wlan_adapter *adapter = priv->adapter;
-       if (adapter->numSNRNF == 0)
+       if (priv->numSNRNF == 0)
                return 0;
-       for (i = 0; i < adapter->numSNRNF; i++)
-               temp += adapter->rawNF[i];
-       return (u8) (temp / adapter->numSNRNF);
+       for (i = 0; i < priv->numSNRNF; i++)
+               temp += priv->rawNF[i];
+       return (u8) (temp / priv->numSNRNF);
 
 }
 
 /**
  *  @brief This function save the raw SNR/NF to our internel buffer
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @param prxpd   A pointer to rxpd structure of received packet
  *  @return       n/a
  */
-static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd)
+static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd)
 {
-       wlan_adapter *adapter = priv->adapter;
-       if (adapter->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
-               adapter->numSNRNF++;
-       adapter->rawSNR[adapter->nextSNRNF] = p_rx_pd->snr;
-       adapter->rawNF[adapter->nextSNRNF] = p_rx_pd->nf;
-       adapter->nextSNRNF++;
-       if (adapter->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
-               adapter->nextSNRNF = 0;
+       if (priv->numSNRNF < DEFAULT_DATA_AVG_FACTOR)
+               priv->numSNRNF++;
+       priv->rawSNR[priv->nextSNRNF] = p_rx_pd->snr;
+       priv->rawNF[priv->nextSNRNF] = p_rx_pd->nf;
+       priv->nextSNRNF++;
+       if (priv->nextSNRNF >= DEFAULT_DATA_AVG_FACTOR)
+               priv->nextSNRNF = 0;
        return;
 }
 
 /**
  *  @brief This function computes the RSSI in received packet.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @param prxpd   A pointer to rxpd structure of received packet
  *  @return       n/a
  */
-static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd)
+static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
 {
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_RX);
 
        lbs_deb_rx("rxpd: SNR %d, NF %d\n", p_rx_pd->snr, p_rx_pd->nf);
        lbs_deb_rx("before computing SNR: SNR-avg = %d, NF-avg = %d\n",
-              adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
-              adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
+              priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
+              priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
 
-       adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
-       adapter->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
-       wlan_save_rawSNRNF(priv, p_rx_pd);
+       priv->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr;
+       priv->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf;
+       lbs_save_rawSNRNF(priv, p_rx_pd);
 
-       adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE;
-       adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE;
+       priv->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE;
+       priv->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE;
        lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n",
-              adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
-              adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
+              priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
+              priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
 
-       adapter->RSSI[TYPE_RXPD][TYPE_NOAVG] =
-           CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
-                    adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
+       priv->RSSI[TYPE_RXPD][TYPE_NOAVG] =
+           CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_NOAVG],
+                    priv->NF[TYPE_RXPD][TYPE_NOAVG]);
 
-       adapter->RSSI[TYPE_RXPD][TYPE_AVG] =
-           CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
-                    adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
+       priv->RSSI[TYPE_RXPD][TYPE_AVG] =
+           CAL_RSSI(priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
+                    priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
 
        lbs_deb_leave(LBS_DEB_RX);
 }
 
-void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb)
-{
-       lbs_deb_rx("skb->data %p\n", skb->data);
-
-       if (priv->adapter->monitormode != WLAN_MONITOR_OFF) {
-               skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
-       } else {
-               if (priv->mesh_dev && IS_MESH_FRAME(skb))
-                       skb->protocol = eth_type_trans(skb, priv->mesh_dev);
-               else
-                       skb->protocol = eth_type_trans(skb, priv->dev);
-       }
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       netif_rx(skb);
-}
-
 /**
  *  @brief This function processes received packet and forwards it
  *  to kernel/upper layer
  *
- *  @param priv    A pointer to wlan_private
+ *  @param priv    A pointer to struct lbs_private
  *  @param skb     A pointer to skb which includes the received packet
  *  @return       0 or -1
  */
-int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
+int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
-
+       struct net_device *dev = priv->dev;
        struct rxpackethdr *p_rx_pkt;
        struct rxpd *p_rx_pd;
 
@@ -173,15 +153,15 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
 
        lbs_deb_enter(LBS_DEB_RX);
 
-       if (priv->adapter->monitormode != WLAN_MONITOR_OFF)
+       skb->ip_summed = CHECKSUM_NONE;
+
+       if (priv->monitormode != LBS_MONITOR_OFF)
                return process_rxed_802_11_packet(priv, skb);
 
        p_rx_pkt = (struct rxpackethdr *) skb->data;
        p_rx_pd = &p_rx_pkt->rx_pd;
-       if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
-               SET_MESH_FRAME(skb);
-       else
-               UNSET_MESH_FRAME(skb);
+       if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
+               dev = priv->mesh_dev;
 
        lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
                 min_t(unsigned int, skb->len, 100));
@@ -257,23 +237,27 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
        /* Take the data rate from the rxpd structure
         * only if the rate is auto
         */
-       if (adapter->auto_rate)
-               adapter->cur_rate = libertas_fw_index_to_data_rate(p_rx_pd->rx_rate);
+       if (priv->auto_rate)
+               priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate);
 
-       wlan_compute_rssi(priv, p_rx_pd);
+       lbs_compute_rssi(priv, p_rx_pd);
 
        lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
        priv->stats.rx_bytes += skb->len;
        priv->stats.rx_packets++;
 
-       libertas_upload_rx_packet(priv, skb);
+       skb->protocol = eth_type_trans(skb, dev);
+       if (in_interrupt())
+               netif_rx(skb);
+       else
+               netif_rx_ni(skb);
 
        ret = 0;
 done:
        lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
        return ret;
 }
-EXPORT_SYMBOL_GPL(libertas_process_rxed_packet);
+EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
 
 /**
  *  @brief This function converts Tx/Rx rates from the Marvell WLAN format
@@ -319,13 +303,13 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
  *  @brief This function processes a received 802.11 packet and forwards it
  *  to kernel/upper layer
  *
- *  @param priv    A pointer to wlan_private
+ *  @param priv    A pointer to struct lbs_private
  *  @param skb     A pointer to skb which includes the received packet
  *  @return       0 or -1
  */
-static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
+static int process_rxed_802_11_packet(struct lbs_private *priv,
+       struct sk_buff *skb)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = 0;
 
        struct rx80211packethdr *p_rx_pkt;
@@ -341,9 +325,10 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
        // lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
 
        if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
-               lbs_deb_rx("rx err: frame received wit bad length\n");
+               lbs_deb_rx("rx err: frame received with bad length\n");
                priv->stats.rx_length_errors++;
-               ret = 0;
+               ret = -EINVAL;
+               kfree(skb);
                goto done;
        }
 
@@ -359,65 +344,56 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
               skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
        /* create the exported radio header */
-       if(priv->adapter->monitormode == WLAN_MONITOR_OFF) {
-               /* no radio header */
-               /* chop the rxpd */
-               skb_pull(skb, sizeof(struct rxpd));
-       }
 
-       else {
-               /* radiotap header */
-               radiotap_hdr.hdr.it_version = 0;
-               /* XXX must check this value for pad */
-               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);
-               /* unknown values */
-               radiotap_hdr.flags = 0;
-               radiotap_hdr.chan_freq = 0;
-               radiotap_hdr.chan_flags = 0;
-               radiotap_hdr.antenna = 0;
-               /* known values */
-               radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
-               /* XXX must check no carryout */
-               radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
-               radiotap_hdr.rx_flags = 0;
-               if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
-                       radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
-               //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
-
-               /* chop the rxpd */
-               skb_pull(skb, sizeof(struct rxpd));
-
-               /* add space for the new radio header */
-               if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
-                   pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
-                                    GFP_ATOMIC)) {
-                       lbs_pr_alert("%s: couldn't pskb_expand_head\n",
-                              __func__);
-               }
-
-               pradiotap_hdr =
-                   (struct rx_radiotap_hdr *)skb_push(skb,
-                                                    sizeof(struct
-                                                           rx_radiotap_hdr));
-               memcpy(pradiotap_hdr, &radiotap_hdr,
-                      sizeof(struct rx_radiotap_hdr));
+       /* radiotap header */
+       radiotap_hdr.hdr.it_version = 0;
+       /* XXX must check this value for pad */
+       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);
+       /* unknown values */
+       radiotap_hdr.flags = 0;
+       radiotap_hdr.chan_freq = 0;
+       radiotap_hdr.chan_flags = 0;
+       radiotap_hdr.antenna = 0;
+       /* known values */
+       radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
+       /* XXX must check no carryout */
+       radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
+       radiotap_hdr.rx_flags = 0;
+       if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
+               radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
+       //memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
+
+       /* chop the rxpd */
+       skb_pull(skb, sizeof(struct rxpd));
+
+       /* add space for the new radio header */
+       if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
+           pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
+               lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
+               ret = -ENOMEM;
+               kfree_skb(skb);
+               goto done;
        }
 
+       pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
+       memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));
+
        /* Take the data rate from the rxpd structure
         * only if the rate is auto
         */
-       if (adapter->auto_rate)
-               adapter->cur_rate = libertas_fw_index_to_data_rate(prxpd->rx_rate);
+       if (priv->auto_rate)
+               priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);
 
-       wlan_compute_rssi(priv, prxpd);
+       lbs_compute_rssi(priv, prxpd);
 
        lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
        priv->stats.rx_bytes += skb->len;
        priv->stats.rx_packets++;
 
-       libertas_upload_rx_packet(priv, skb);
+       skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
+       netif_rx(skb);
 
        ret = 0;
 
index ad1e67d984ce70e9b2a59b4a97cfbe61f71c13c4..9a61188b62e92cf2fe9984c5ca58f4ac8cbd8570 100644 (file)
@@ -39,9 +39,8 @@
 //! Memory needed to store a max number/size SSID TLV for a firmware scan
 #define SSID_TLV_MAX_SIZE  (1 * sizeof(struct mrvlietypes_ssidparamset))
 
-//! Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max
-#define MAX_SCAN_CFG_ALLOC (sizeof(struct wlan_scan_cmd_config)  \
-                            + sizeof(struct mrvlietypes_numprobes)   \
+//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max
+#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config)  \
                             + CHAN_TLV_MAX_SIZE                 \
                             + SSID_TLV_MAX_SIZE)
 
@@ -80,7 +79,23 @@ static inline void clear_bss_descriptor (struct bss_descriptor * bss)
        memset(bss, 0, offsetof(struct bss_descriptor, list));
 }
 
-static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
+/**
+ *  @brief Compare two SSIDs
+ *
+ *  @param ssid1    A pointer to ssid to compare
+ *  @param ssid2    A pointer to ssid to compare
+ *
+ *  @return         0: ssid is same, otherwise is different
+ */
+int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
+{
+       if (ssid1_len != ssid2_len)
+               return -1;
+
+       return memcmp(ssid1, ssid2, ssid1_len);
+}
+
+static inline int match_bss_no_security(struct lbs_802_11_security *secinfo,
                        struct bss_descriptor * match_bss)
 {
        if (   !secinfo->wep_enabled
@@ -94,7 +109,7 @@ static inline int match_bss_no_security(struct wlan_802_11_security * secinfo,
        return 0;
 }
 
-static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo,
+static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo,
                        struct bss_descriptor * match_bss)
 {
        if ( secinfo->wep_enabled
@@ -106,7 +121,7 @@ static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo,
        return 0;
 }
 
-static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
+static inline int match_bss_wpa(struct lbs_802_11_security *secinfo,
                        struct bss_descriptor * match_bss)
 {
        if (  !secinfo->wep_enabled
@@ -121,7 +136,7 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo,
        return 0;
 }
 
-static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
+static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo,
                        struct bss_descriptor * match_bss)
 {
        if (  !secinfo->wep_enabled
@@ -136,7 +151,7 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo,
        return 0;
 }
 
-static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
+static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo,
                        struct bss_descriptor * match_bss)
 {
        if (  !secinfo->wep_enabled
@@ -150,6 +165,18 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
        return 0;
 }
 
+static inline int is_same_network(struct bss_descriptor *src,
+                                 struct bss_descriptor *dst)
+{
+       /* A network is only a duplicate if the channel, BSSID, and ESSID
+        * all match.  We treat all <hidden> with the same BSSID and channel
+        * as one network */
+       return ((src->ssid_len == dst->ssid_len) &&
+               (src->channel == dst->channel) &&
+               !compare_ether_addr(src->bssid, dst->bssid) &&
+               !memcmp(src->ssid, dst->ssid, src->ssid_len));
+}
+
 /**
  *  @brief Check if a scanned network compatible with the driver settings
  *
@@ -163,13 +190,13 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo,
  *    0       0        0       0     !=NONE     1      0    0   yes Dynamic WEP
  *
  *
- *  @param adapter A pointer to wlan_adapter
+ *  @param priv A pointer to struct lbs_private
  *  @param index   Index in scantable to check against current driver settings
  *  @param mode    Network mode: Infrastructure or IBSS
  *
  *  @return        Index in scantable, or error code if negative
  */
-static int is_network_compatible(wlan_adapter * adapter,
+static int is_network_compatible(struct lbs_private *priv,
                struct bss_descriptor * bss, u8 mode)
 {
        int matched = 0;
@@ -179,34 +206,34 @@ static int is_network_compatible(wlan_adapter * adapter,
        if (bss->mode != mode)
                goto done;
 
-       if ((matched = match_bss_no_security(&adapter->secinfo, bss))) {
+       if ((matched = match_bss_no_security(&priv->secinfo, bss))) {
                goto done;
-       } else if ((matched = match_bss_static_wep(&adapter->secinfo, bss))) {
+       } else if ((matched = match_bss_static_wep(&priv->secinfo, bss))) {
                goto done;
-       } else if ((matched = match_bss_wpa(&adapter->secinfo, bss))) {
+       } else if ((matched = match_bss_wpa(&priv->secinfo, bss))) {
                lbs_deb_scan(
-                      "is_network_compatible() WPA: wpa_ie=%#x "
-                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
-                      "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
-                      adapter->secinfo.wep_enabled ? "e" : "d",
-                      adapter->secinfo.WPAenabled ? "e" : "d",
-                      adapter->secinfo.WPA2enabled ? "e" : "d",
+                      "is_network_compatible() WPA: wpa_ie 0x%x "
+                      "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
+                      "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
+                      priv->secinfo.wep_enabled ? "e" : "d",
+                      priv->secinfo.WPAenabled ? "e" : "d",
+                      priv->secinfo.WPA2enabled ? "e" : "d",
                       (bss->capability & WLAN_CAPABILITY_PRIVACY));
                goto done;
-       } else if ((matched = match_bss_wpa2(&adapter->secinfo, bss))) {
+       } else if ((matched = match_bss_wpa2(&priv->secinfo, bss))) {
                lbs_deb_scan(
-                      "is_network_compatible() WPA2: wpa_ie=%#x "
-                      "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
-                      "privacy=%#x\n", bss->wpa_ie[0], bss->rsn_ie[0],
-                      adapter->secinfo.wep_enabled ? "e" : "d",
-                      adapter->secinfo.WPAenabled ? "e" : "d",
-                      adapter->secinfo.WPA2enabled ? "e" : "d",
+                      "is_network_compatible() WPA2: wpa_ie 0x%x "
+                      "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s "
+                      "privacy 0x%x\n", bss->wpa_ie[0], bss->rsn_ie[0],
+                      priv->secinfo.wep_enabled ? "e" : "d",
+                      priv->secinfo.WPAenabled ? "e" : "d",
+                      priv->secinfo.WPA2enabled ? "e" : "d",
                       (bss->capability & WLAN_CAPABILITY_PRIVACY));
                goto done;
-       } else if ((matched = match_bss_dynamic_wep(&adapter->secinfo, bss))) {
+       } else if ((matched = match_bss_dynamic_wep(&priv->secinfo, bss))) {
                lbs_deb_scan(
                       "is_network_compatible() dynamic WEP: "
-                      "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
+                      "wpa_ie 0x%x wpa2_ie 0x%x privacy 0x%x\n",
                       bss->wpa_ie[0], bss->rsn_ie[0],
                       (bss->capability & WLAN_CAPABILITY_PRIVACY));
                goto done;
@@ -214,12 +241,12 @@ static int is_network_compatible(wlan_adapter * adapter,
 
        /* bss security settings don't match those configured on card */
        lbs_deb_scan(
-              "is_network_compatible() FAILED: wpa_ie=%#x "
-              "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
+              "is_network_compatible() FAILED: wpa_ie 0x%x "
+              "wpa2_ie 0x%x WEP %s WPA %s WPA2 %s privacy 0x%x\n",
               bss->wpa_ie[0], bss->rsn_ie[0],
-              adapter->secinfo.wep_enabled ? "e" : "d",
-              adapter->secinfo.WPAenabled ? "e" : "d",
-              adapter->secinfo.WPA2enabled ? "e" : "d",
+              priv->secinfo.wep_enabled ? "e" : "d",
+              priv->secinfo.WPAenabled ? "e" : "d",
+              priv->secinfo.WPA2enabled ? "e" : "d",
               (bss->capability & WLAN_CAPABILITY_PRIVACY));
 
 done:
@@ -227,22 +254,6 @@ done:
        return matched;
 }
 
-/**
- *  @brief Compare two SSIDs
- *
- *  @param ssid1    A pointer to ssid to compare
- *  @param ssid2    A pointer to ssid to compare
- *
- *  @return         0--ssid is same, otherwise is different
- */
-int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
-{
-       if (ssid1_len != ssid2_len)
-               return -1;
-
-       return memcmp(ssid1, ssid2, ssid1_len);
-}
-
 
 
 
@@ -252,17 +263,27 @@ int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
 /*                                                                   */
 /*********************************************************************/
 
+void lbs_scan_worker(struct work_struct *work)
+{
+       struct lbs_private *priv =
+               container_of(work, struct lbs_private, scan_work.work);
+
+       lbs_deb_enter(LBS_DEB_SCAN);
+       lbs_scan_networks(priv, NULL, 0);
+       lbs_deb_leave(LBS_DEB_SCAN);
+}
+
 
 /**
  *  @brief Create a channel list for the driver to scan based on region info
  *
- *  Only used from wlan_scan_setup_scan_config()
+ *  Only used from lbs_scan_setup_scan_config()
  *
  *  Use the driver region/band information to construct a comprehensive list
  *    of channels to scan.  This routine is used for any scan that is not
  *    provided a specific channel list to scan.
  *
- *  @param priv          A pointer to wlan_private structure
+ *  @param priv          A pointer to struct lbs_private structure
  *  @param scanchanlist  Output parameter: resulting channel list to scan
  *  @param filteredscan  Flag indicating whether or not a BSSID or SSID filter
  *                       is being sent in the command to firmware.  Used to
@@ -272,12 +293,11 @@ int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len)
  *
  *  @return              void
  */
-static void wlan_scan_create_channel_list(wlan_private * priv,
+static int lbs_scan_create_channel_list(struct lbs_private *priv,
                                          struct chanscanparamset * scanchanlist,
                                          u8 filteredscan)
 {
 
-       wlan_adapter *adapter = priv->adapter;
        struct region_channel *scanregion;
        struct chan_freq_power *cfp;
        int rgnidx;
@@ -285,8 +305,6 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
        int nextchan;
        u8 scantype;
 
-       lbs_deb_enter_args(LBS_DEB_SCAN, "filteredscan %d", filteredscan);
-
        chanidx = 0;
 
        /* Set the default scan type to the user specified type, will later
@@ -295,21 +313,22 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
         */
        scantype = CMD_SCAN_TYPE_ACTIVE;
 
-       for (rgnidx = 0; rgnidx < ARRAY_SIZE(adapter->region_channel); rgnidx++) {
-               if (priv->adapter->enable11d &&
-                   adapter->connect_status != LIBERTAS_CONNECTED) {
+       for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
+               if (priv->enable11d &&
+                   (priv->connect_status != LBS_CONNECTED) &&
+                   (priv->mesh_connect_status != LBS_CONNECTED)) {
                        /* Scan all the supported chan for the first scan */
-                       if (!adapter->universal_channel[rgnidx].valid)
+                       if (!priv->universal_channel[rgnidx].valid)
                                continue;
-                       scanregion = &adapter->universal_channel[rgnidx];
+                       scanregion = &priv->universal_channel[rgnidx];
 
                        /* clear the parsed_region_chan for the first scan */
-                       memset(&adapter->parsed_region_chan, 0x00,
-                              sizeof(adapter->parsed_region_chan));
+                       memset(&priv->parsed_region_chan, 0x00,
+                              sizeof(priv->parsed_region_chan));
                } else {
-                       if (!adapter->region_channel[rgnidx].valid)
+                       if (!priv->region_channel[rgnidx].valid)
                                continue;
-                       scanregion = &adapter->region_channel[rgnidx];
+                       scanregion = &priv->region_channel[rgnidx];
                }
 
                for (nextchan = 0;
@@ -317,10 +336,10 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
 
                        cfp = scanregion->CFP + nextchan;
 
-                       if (priv->adapter->enable11d) {
+                       if (priv->enable11d) {
                                scantype =
-                                   libertas_get_scan_type_11d(cfp->channel,
-                                                          &adapter->
+                                   lbs_get_scan_type_11d(cfp->channel,
+                                                          &priv->
                                                           parsed_region_chan);
                        }
 
@@ -353,453 +372,151 @@ static void wlan_scan_create_channel_list(wlan_private * priv,
                        }
                }
        }
+       return chanidx;
 }
 
 
-/* Delayed partial scan worker */
-void libertas_scan_worker(struct work_struct *work)
+/*
+ * Add SSID TLV of the form:
+ *
+ * TLV-ID SSID     00 00
+ * length          06 00
+ * ssid            4d 4e 54 45 53 54
+ */
+static int lbs_scan_add_ssid_tlv(u8 *tlv,
+       const struct lbs_ioctl_user_scan_cfg *user_cfg)
 {
-       wlan_private *priv = container_of(work, wlan_private, scan_work.work);
-
-       wlan_scan_networks(priv, NULL, 0);
+       struct mrvlietypes_ssidparamset *ssid_tlv =
+               (struct mrvlietypes_ssidparamset *)tlv;
+       ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
+       ssid_tlv->header.len = cpu_to_le16(user_cfg->ssid_len);
+       memcpy(ssid_tlv->ssid, user_cfg->ssid, user_cfg->ssid_len);
+       return sizeof(ssid_tlv->header) + user_cfg->ssid_len;
 }
 
 
-/**
- *  @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds
- *
- *  Application layer or other functions can invoke wlan_scan_networks
- *    with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct.
- *    This structure is used as the basis of one or many wlan_scan_cmd_config
- *    commands that are sent to the command processing module and sent to
- *    firmware.
- *
- *  Create a wlan_scan_cmd_config based on the following user supplied
- *    parameters (if present):
- *             - SSID filter
- *             - BSSID filter
- *             - Number of Probes to be sent
- *             - channel list
- *
- *  If the SSID or BSSID filter is not present, disable/clear the filter.
- *  If the number of probes is not set, use the adapter default setting
- *  Qualify the channel
+/*
+ * Add CHANLIST TLV of the form
  *
- *  @param priv             A pointer to wlan_private structure
- *  @param puserscanin      NULL or pointer to scan configuration parameters
- *  @param ppchantlvout     Output parameter: Pointer to the start of the
- *                          channel TLV portion of the output scan config
- *  @param pscanchanlist    Output parameter: Pointer to the resulting channel
- *                          list to scan
- *  @param pmaxchanperscan  Output parameter: Number of channels to scan for
- *                          each issuance of the firmware scan command
- *  @param pfilteredscan    Output parameter: Flag indicating whether or not
- *                          a BSSID or SSID filter is being sent in the
- *                          command to firmware.  Used to increase the number
- *                          of channels sent in a scan command and to
- *                          disable the firmware channel scan filter.
- *  @param pscancurrentonly Output parameter: Flag indicating whether or not
- *                          we are only scanning our current active channel
+ * TLV-ID CHANLIST 01 01
+ * length          5b 00
+ * channel 1       00 01 00 00 00 64 00
+ *   radio type    00
+ *   channel          01
+ *   scan type           00
+ *   min scan time          00 00
+ *   max scan time                64 00
+ * channel 2       00 02 00 00 00 64 00
+ * channel 3       00 03 00 00 00 64 00
+ * channel 4       00 04 00 00 00 64 00
+ * channel 5       00 05 00 00 00 64 00
+ * channel 6       00 06 00 00 00 64 00
+ * channel 7       00 07 00 00 00 64 00
+ * channel 8       00 08 00 00 00 64 00
+ * channel 9       00 09 00 00 00 64 00
+ * channel 10      00 0a 00 00 00 64 00
+ * channel 11      00 0b 00 00 00 64 00
+ * channel 12      00 0c 00 00 00 64 00
+ * channel 13      00 0d 00 00 00 64 00
  *
- *  @return                 resulting scan configuration
  */
-static struct wlan_scan_cmd_config *
-wlan_scan_setup_scan_config(wlan_private * priv,
-                           const struct wlan_ioctl_user_scan_cfg * puserscanin,
-                           struct mrvlietypes_chanlistparamset ** ppchantlvout,
-                           struct chanscanparamset * pscanchanlist,
-                           int *pmaxchanperscan,
-                           u8 * pfilteredscan,
-                           u8 * pscancurrentonly)
+static int lbs_scan_add_chanlist_tlv(u8 *tlv,
+       struct chanscanparamset *chan_list,
+       int chan_count)
 {
-       struct mrvlietypes_numprobes *pnumprobestlv;
-       struct mrvlietypes_ssidparamset *pssidtlv;
-       struct wlan_scan_cmd_config * pscancfgout = NULL;
-       u8 *ptlvpos;
-       u16 numprobes;
-       int chanidx;
-       int scantype;
-       int scandur;
-       int channel;
-       int radiotype;
-
-       lbs_deb_enter(LBS_DEB_SCAN);
-
-       pscancfgout = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
-       if (pscancfgout == NULL)
-               goto out;
-
-       /* The tlvbufferlen is calculated for each scan command.  The TLVs added
-        *   in this routine will be preserved since the routine that sends
-        *   the command will append channelTLVs at *ppchantlvout.  The difference
-        *   between the *ppchantlvout and the tlvbuffer start will be used
-        *   to calculate the size of anything we add in this routine.
-        */
-       pscancfgout->tlvbufferlen = 0;
-
-       /* Running tlv pointer.  Assigned to ppchantlvout at end of function
-        *  so later routines know where channels can be added to the command buf
-        */
-       ptlvpos = pscancfgout->tlvbuffer;
-
-       /*
-        * Set the initial scan paramters for progressive scanning.  If a specific
-        *   BSSID or SSID is used, the number of channels in the scan command
-        *   will be increased to the absolute maximum
-        */
-       *pmaxchanperscan = MRVDRV_CHANNELS_PER_SCAN_CMD;
-
-       /* Initialize the scan as un-filtered by firmware, set to TRUE below if
-        *   a SSID or BSSID filter is sent in the command
-        */
-       *pfilteredscan = 0;
-
-       /* Initialize the scan as not being only on the current channel.  If
-        *   the channel list is customized, only contains one channel, and
-        *   is the active channel, this is set true and data flow is not halted.
-        */
-       *pscancurrentonly = 0;
-
-       if (puserscanin) {
-               /* Set the bss type scan filter, use adapter setting if unset */
-               pscancfgout->bsstype =
-                   puserscanin->bsstype ? puserscanin->bsstype : CMD_BSS_TYPE_ANY;
-
-               /* Set the number of probes to send, use adapter setting if unset */
-               numprobes = puserscanin->numprobes ? puserscanin->numprobes : 0;
-
-               /*
-                * Set the BSSID filter to the incoming configuration,
-                *   if non-zero.  If not set, it will remain disabled (all zeros).
-                */
-               memcpy(pscancfgout->bssid, puserscanin->bssid,
-                      sizeof(pscancfgout->bssid));
-
-               if (puserscanin->ssid_len) {
-                       pssidtlv =
-                           (struct mrvlietypes_ssidparamset *) pscancfgout->
-                           tlvbuffer;
-                       pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
-                       pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len);
-                       memcpy(pssidtlv->ssid, puserscanin->ssid,
-                              puserscanin->ssid_len);
-                       ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len;
-               }
-
-               /*
-                *  The default number of channels sent in the command is low to
-                *    ensure the response buffer from the firmware does not truncate
-                *    scan results.  That is not an issue with an SSID or BSSID
-                *    filter applied to the scan results in the firmware.
-                */
-               if (   puserscanin->ssid_len
-                   || (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) {
-                       *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
-                       *pfilteredscan = 1;
-               }
-       } else {
-               pscancfgout->bsstype = CMD_BSS_TYPE_ANY;
-               numprobes = 0;
-       }
-
-       /* If the input config or adapter has the number of Probes set, add tlv */
-       if (numprobes) {
-               pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos;
-               pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
-               pnumprobestlv->header.len = cpu_to_le16(2);
-               pnumprobestlv->numprobes = cpu_to_le16(numprobes);
-
-               ptlvpos += sizeof(*pnumprobestlv);
-       }
-
-       /*
-        * Set the output for the channel TLV to the address in the tlv buffer
-        *   past any TLVs that were added in this fuction (SSID, numprobes).
-        *   channel TLVs will be added past this for each scan command, preserving
-        *   the TLVs that were previously added.
-        */
-       *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos;
-
-       if (!puserscanin || !puserscanin->chanlist[0].channumber) {
-               /* Create a default channel scan list */
-               lbs_deb_scan("creating full region channel list\n");
-               wlan_scan_create_channel_list(priv, pscanchanlist,
-                                             *pfilteredscan);
-               goto out;
-       }
-
-       for (chanidx = 0;
-            chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX
-            && puserscanin->chanlist[chanidx].channumber; chanidx++) {
-
-               channel = puserscanin->chanlist[chanidx].channumber;
-               (pscanchanlist + chanidx)->channumber = channel;
-
-               radiotype = puserscanin->chanlist[chanidx].radiotype;
-               (pscanchanlist + chanidx)->radiotype = radiotype;
-
-               scantype = puserscanin->chanlist[chanidx].scantype;
-
-               if (scantype == CMD_SCAN_TYPE_PASSIVE) {
-                       (pscanchanlist +
-                        chanidx)->chanscanmode.passivescan = 1;
-               } else {
-                       (pscanchanlist +
-                        chanidx)->chanscanmode.passivescan = 0;
-               }
-
-               if (puserscanin->chanlist[chanidx].scantime) {
-                       scandur = puserscanin->chanlist[chanidx].scantime;
-               } else {
-                       if (scantype == CMD_SCAN_TYPE_PASSIVE) {
-                               scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
-                       } else {
-                               scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
-                       }
-               }
-
-               (pscanchanlist + chanidx)->minscantime =
-                   cpu_to_le16(scandur);
-               (pscanchanlist + chanidx)->maxscantime =
-                   cpu_to_le16(scandur);
-       }
-
-       /* Check if we are only scanning the current channel */
-       if ((chanidx == 1) &&
-           (puserscanin->chanlist[0].channumber ==
-                              priv->adapter->curbssparams.channel)) {
-               *pscancurrentonly = 1;
-               lbs_deb_scan("scanning current channel only");
-       }
-
-out:
-       return pscancfgout;
+       size_t size = sizeof(struct chanscanparamset) * chan_count;
+       struct mrvlietypes_chanlistparamset *chan_tlv =
+               (struct mrvlietypes_chanlistparamset *) tlv;
+
+       chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+       memcpy(chan_tlv->chanscanparam, chan_list, size);
+       chan_tlv->header.len = cpu_to_le16(size);
+       return sizeof(chan_tlv->header) + size;
 }
 
-/**
- *  @brief Construct and send multiple scan config commands to the firmware
- *
- *  Only used from wlan_scan_networks()
- *
- *  Previous routines have created a wlan_scan_cmd_config with any requested
- *   TLVs.  This function splits the channel TLV into maxchanperscan lists
- *   and sends the portion of the channel TLV along with the other TLVs
- *   to the wlan_cmd routines for execution in the firmware.
+
+/*
+ * Add RATES TLV of the form
  *
- *  @param priv            A pointer to wlan_private structure
- *  @param maxchanperscan  Maximum number channels to be included in each
- *                         scan command sent to firmware
- *  @param filteredscan    Flag indicating whether or not a BSSID or SSID
- *                         filter is being used for the firmware command
- *                         scan command sent to firmware
- *  @param pscancfgout     Scan configuration used for this scan.
- *  @param pchantlvout     Pointer in the pscancfgout where the channel TLV
- *                         should start.  This is past any other TLVs that
- *                         must be sent down in each firmware command.
- *  @param pscanchanlist   List of channels to scan in maxchanperscan segments
+ * TLV-ID RATES    01 00
+ * length          0e 00
+ * rates           82 84 8b 96 0c 12 18 24 30 48 60 6c
  *
- *  @return                0 or error return otherwise
+ * The rates are in lbs_bg_rates[], but for the 802.11b
+ * rates the high bit isn't set.
  */
-static int wlan_scan_channel_list(wlan_private * priv,
-                                 int maxchanperscan,
-                                 u8 filteredscan,
-                                 struct wlan_scan_cmd_config * pscancfgout,
-                                 struct mrvlietypes_chanlistparamset * pchantlvout,
-                                 struct chanscanparamset * pscanchanlist,
-                                 const struct wlan_ioctl_user_scan_cfg * puserscanin,
-                                 int full_scan)
+static int lbs_scan_add_rates_tlv(u8 *tlv)
 {
-       struct chanscanparamset *ptmpchan;
-       struct chanscanparamset *pstartchan;
-       u8 scanband;
-       int doneearly;
-       int tlvidx;
-       int ret = 0;
-       int scanned = 0;
-       union iwreq_data wrqu;
-
-       lbs_deb_enter_args(LBS_DEB_SCAN, "maxchanperscan %d, filteredscan %d, "
-               "full_scan %d", maxchanperscan, filteredscan, full_scan);
-
-       if (!pscancfgout || !pchantlvout || !pscanchanlist) {
-               lbs_deb_scan("pscancfgout, pchantlvout or "
-                       "pscanchanlist is NULL\n");
-               ret = -1;
-               goto out;
-       }
-
-       pchantlvout->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
-
-       /* Set the temp channel struct pointer to the start of the desired list */
-       ptmpchan = pscanchanlist;
-
-       if (priv->adapter->last_scanned_channel && !puserscanin)
-               ptmpchan += priv->adapter->last_scanned_channel;
-
-       /* Loop through the desired channel list, sending a new firmware scan
-        *   commands for each maxchanperscan channels (or for 1,6,11 individually
-        *   if configured accordingly)
-        */
-       while (ptmpchan->channumber) {
-
-               tlvidx = 0;
-               pchantlvout->header.len = 0;
-               scanband = ptmpchan->radiotype;
-               pstartchan = ptmpchan;
-               doneearly = 0;
-
-               /* Construct the channel TLV for the scan command.  Continue to
-                *  insert channel TLVs until:
-                *    - the tlvidx hits the maximum configured per scan command
-                *    - the next channel to insert is 0 (end of desired channel list)
-                *    - doneearly is set (controlling individual scanning of 1,6,11)
-                */
-               while (tlvidx < maxchanperscan && ptmpchan->channumber
-                      && !doneearly && scanned < 2) {
-
-                       lbs_deb_scan("channel %d, radio %d, passive %d, "
-                               "dischanflt %d, maxscantime %d\n",
-                               ptmpchan->channumber,
-                               ptmpchan->radiotype,
-                                    ptmpchan->chanscanmode.passivescan,
-                                    ptmpchan->chanscanmode.disablechanfilt,
-                                    ptmpchan->maxscantime);
-
-                       /* Copy the current channel TLV to the command being prepared */
-                       memcpy(pchantlvout->chanscanparam + tlvidx,
-                              ptmpchan, sizeof(pchantlvout->chanscanparam));
-
-                       /* Increment the TLV header length by the size appended */
-                       /* Ew, it would be _so_ nice if we could just declare the
-                          variable little-endian and let GCC handle it for us */
-                       pchantlvout->header.len =
-                               cpu_to_le16(le16_to_cpu(pchantlvout->header.len) +
-                                           sizeof(pchantlvout->chanscanparam));
-
-                       /*
-                        *  The tlv buffer length is set to the number of bytes of the
-                        *    between the channel tlv pointer and the start of the
-                        *    tlv buffer.  This compensates for any TLVs that were appended
-                        *    before the channel list.
-                        */
-                       pscancfgout->tlvbufferlen = ((u8 *) pchantlvout
-                                                    - pscancfgout->tlvbuffer);
-
-                       /*  Add the size of the channel tlv header and the data length */
-                       pscancfgout->tlvbufferlen +=
-                           (sizeof(pchantlvout->header)
-                            + le16_to_cpu(pchantlvout->header.len));
-
-                       /* Increment the index to the channel tlv we are constructing */
-                       tlvidx++;
-
-                       doneearly = 0;
-
-                       /* Stop the loop if the *current* channel is in the 1,6,11 set
-                        *   and we are not filtering on a BSSID or SSID.
-                        */
-                       if (!filteredscan && (ptmpchan->channumber == 1
-                                             || ptmpchan->channumber == 6
-                                             || ptmpchan->channumber == 11)) {
-                               doneearly = 1;
-                       }
-
-                       /* Increment the tmp pointer to the next channel to be scanned */
-                       ptmpchan++;
-                       scanned++;
-
-                       /* Stop the loop if the *next* channel is in the 1,6,11 set.
-                        *  This will cause it to be the only channel scanned on the next
-                        *  interation
-                        */
-                       if (!filteredscan && (ptmpchan->channumber == 1
-                                             || ptmpchan->channumber == 6
-                                             || ptmpchan->channumber == 11)) {
-                               doneearly = 1;
-                       }
-               }
-
-               /* Send the scan command to the firmware with the specified cfg */
-               ret = libertas_prepare_and_send_command(priv, CMD_802_11_SCAN, 0,
-                                           0, 0, pscancfgout);
-               if (scanned >= 2 && !full_scan) {
-                       ret = 0;
-                       goto done;
-               }
-               scanned = 0;
-       }
-
-done:
-       priv->adapter->last_scanned_channel = ptmpchan->channumber;
-
-       if (priv->adapter->last_scanned_channel) {
-               /* Schedule the next part of the partial scan */
-               if (!full_scan && !priv->adapter->surpriseremoved) {
-                       cancel_delayed_work(&priv->scan_work);
-                       queue_delayed_work(priv->work_thread, &priv->scan_work,
-                                          msecs_to_jiffies(300));
-               }
-       } else {
-               /* All done, tell userspace the scan table has been updated */
-               memset(&wrqu, 0, sizeof(union iwreq_data));
-               wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
+       int i;
+       struct mrvlietypes_ratesparamset *rate_tlv =
+               (struct mrvlietypes_ratesparamset *) tlv;
+
+       rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
+       tlv += sizeof(rate_tlv->header);
+       for (i = 0; i < MAX_RATES; i++) {
+               *tlv = lbs_bg_rates[i];
+               if (*tlv == 0)
+                       break;
+               /* This code makes sure that the 802.11b rates (1 MBit/s, 2
+                  MBit/s, 5.5 MBit/s and 11 MBit/s get's the high bit set.
+                  Note that the values are MBit/s * 2, to mark them as
+                  basic rates so that the firmware likes it better */
+               if (*tlv == 0x02 || *tlv == 0x04 ||
+                   *tlv == 0x0b || *tlv == 0x16)
+                       *tlv |= 0x80;
+               tlv++;
        }
-
-out:
-       lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
-       return ret;
+       rate_tlv->header.len = cpu_to_le16(i);
+       return sizeof(rate_tlv->header) + i;
 }
 
+
 /*
- * Only used from wlan_scan_networks()
-*/
-static void clear_selected_scan_list_entries(wlan_adapter *adapter,
-       const struct wlan_ioctl_user_scan_cfg *scan_cfg)
+ * Generate the CMD_802_11_SCAN command with the proper tlv
+ * for a bunch of channels.
+ */
+static int lbs_do_scan(struct lbs_private *priv,
+       u8 bsstype,
+       struct chanscanparamset *chan_list,
+       int chan_count,
+       const struct lbs_ioctl_user_scan_cfg *user_cfg)
 {
-       struct bss_descriptor *bss;
-       struct bss_descriptor *safe;
-       u32 clear_ssid_flag = 0, clear_bssid_flag = 0;
+       int ret = -ENOMEM;
+       struct lbs_scan_cmd_config *scan_cmd;
+       u8 *tlv;    /* pointer into our current, growing TLV storage area */
 
-       lbs_deb_enter(LBS_DEB_SCAN);
+       lbs_deb_enter_args(LBS_DEB_SCAN, "bsstype %d, chanlist[].chan %d, "
+               "chan_count %d",
+               bsstype, chan_list[0].channumber, chan_count);
 
-       if (!scan_cfg)
+       /* create the fixed part for scan command */
+       scan_cmd = kzalloc(MAX_SCAN_CFG_ALLOC, GFP_KERNEL);
+       if (scan_cmd == NULL)
                goto out;
-
-       if (scan_cfg->clear_ssid && scan_cfg->ssid_len)
-               clear_ssid_flag = 1;
-
-       if (scan_cfg->clear_bssid
-           && (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0)
-           && (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) {
-               clear_bssid_flag = 1;
-       }
-
-       if (!clear_ssid_flag && !clear_bssid_flag)
-               goto out;
-
-       mutex_lock(&adapter->lock);
-       list_for_each_entry_safe (bss, safe, &adapter->network_list, list) {
-               u32 clear = 0;
-
-               /* Check for an SSID match */
-               if (   clear_ssid_flag
-                   && (bss->ssid_len == scan_cfg->ssid_len)
-                   && !memcmp(bss->ssid, scan_cfg->ssid, bss->ssid_len))
-                       clear = 1;
-
-               /* Check for a BSSID match */
-               if (   clear_bssid_flag
-                   && !compare_ether_addr(bss->bssid, scan_cfg->bssid))
-                       clear = 1;
-
-               if (clear) {
-                       list_move_tail (&bss->list, &adapter->network_free_list);
-                       clear_bss_descriptor(bss);
-               }
-       }
-       mutex_unlock(&adapter->lock);
+       tlv = scan_cmd->tlvbuffer;
+       if (user_cfg)
+               memcpy(scan_cmd->bssid, user_cfg->bssid, ETH_ALEN);
+       scan_cmd->bsstype = bsstype;
+
+       /* add TLVs */
+       if (user_cfg && user_cfg->ssid_len)
+               tlv += lbs_scan_add_ssid_tlv(tlv, user_cfg);
+       if (chan_list && chan_count)
+               tlv += lbs_scan_add_chanlist_tlv(tlv, chan_list, chan_count);
+       tlv += lbs_scan_add_rates_tlv(tlv);
+
+       /* This is the final data we are about to send */
+       scan_cmd->tlvbufferlen = tlv - scan_cmd->tlvbuffer;
+       lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd, 1+6);
+       lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
+               scan_cmd->tlvbufferlen);
+
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0,
+               CMD_OPTION_WAITFORRSP, 0, scan_cmd);
 out:
-       lbs_deb_leave(LBS_DEB_SCAN);
+       kfree(scan_cmd);
+       lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
+       return ret;
 }
 
 
@@ -812,32 +529,32 @@ out:
  *    order to send the appropriate scan commands to firmware to populate or
  *    update the internal driver scan table
  *
- *  @param priv          A pointer to wlan_private structure
+ *  @param priv          A pointer to struct lbs_private structure
  *  @param puserscanin   Pointer to the input configuration for the requested
  *                       scan.
- *  @param full_scan     ???
  *
  *  @return              0 or < 0 if error
  */
-int wlan_scan_networks(wlan_private * priv,
-                       const struct wlan_ioctl_user_scan_cfg * puserscanin,
+int lbs_scan_networks(struct lbs_private *priv,
+       const struct lbs_ioctl_user_scan_cfg *user_cfg,
                        int full_scan)
 {
-       wlan_adapter * adapter = priv->adapter;
-       struct mrvlietypes_chanlistparamset *pchantlvout;
-       struct chanscanparamset * scan_chan_list = NULL;
-       struct wlan_scan_cmd_config * scan_cfg = NULL;
-       u8 filteredscan;
-       u8 scancurrentchanonly;
-       int maxchanperscan;
-       int ret;
+       int ret = -ENOMEM;
+       struct chanscanparamset *chan_list;
+       struct chanscanparamset *curr_chans;
+       int chan_count;
+       u8 bsstype = CMD_BSS_TYPE_ANY;
+       int numchannels = MRVDRV_CHANNELS_PER_SCAN_CMD;
+       int filteredscan = 0;
+       union iwreq_data wrqu;
 #ifdef CONFIG_LIBERTAS_DEBUG
-       struct bss_descriptor * iter_bss;
+       struct bss_descriptor *iter;
        int i = 0;
        DECLARE_MAC_BUF(mac);
 #endif
 
-       lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d", full_scan);
+       lbs_deb_enter_args(LBS_DEB_SCAN, "full_scan %d",
+               full_scan);
 
        /* Cancel any partial outstanding partial scans if this scan
         * is a full scan.
@@ -845,90 +562,138 @@ int wlan_scan_networks(wlan_private * priv,
        if (full_scan && delayed_work_pending(&priv->scan_work))
                cancel_delayed_work(&priv->scan_work);
 
-       scan_chan_list = kzalloc(sizeof(struct chanscanparamset) *
-                               WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
-       if (scan_chan_list == NULL) {
-               ret = -ENOMEM;
+       /* Determine same scan parameters */
+       if (user_cfg) {
+               if (user_cfg->bsstype)
+                       bsstype = user_cfg->bsstype;
+               if (compare_ether_addr(user_cfg->bssid, &zeromac[0]) != 0) {
+                       numchannels = MRVDRV_MAX_CHANNELS_PER_SCAN;
+                       filteredscan = 1;
+               }
+       }
+       lbs_deb_scan("numchannels %d, bsstype %d, "
+               "filteredscan %d\n",
+               numchannels, bsstype, filteredscan);
+
+       /* Create list of channels to scan */
+       chan_list = kzalloc(sizeof(struct chanscanparamset) *
+                               LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL);
+       if (!chan_list) {
+               lbs_pr_alert("SCAN: chan_list empty\n");
                goto out;
        }
 
-       scan_cfg = wlan_scan_setup_scan_config(priv,
-                                              puserscanin,
-                                              &pchantlvout,
-                                              scan_chan_list,
-                                              &maxchanperscan,
-                                              &filteredscan,
-                                              &scancurrentchanonly);
-       if (scan_cfg == NULL) {
-               ret = -ENOMEM;
-               goto out;
+       /* We want to scan all channels */
+       chan_count = lbs_scan_create_channel_list(priv, chan_list,
+               filteredscan);
+
+       netif_stop_queue(priv->dev);
+       netif_carrier_off(priv->dev);
+       if (priv->mesh_dev) {
+               netif_stop_queue(priv->mesh_dev);
+               netif_carrier_off(priv->mesh_dev);
+       }
+
+       /* Prepare to continue an interrupted scan */
+       lbs_deb_scan("chan_count %d, last_scanned_channel %d\n",
+                    chan_count, priv->last_scanned_channel);
+       curr_chans = chan_list;
+       /* advance channel list by already-scanned-channels */
+       if (priv->last_scanned_channel > 0) {
+               curr_chans += priv->last_scanned_channel;
+               chan_count -= priv->last_scanned_channel;
        }
 
-       clear_selected_scan_list_entries(adapter, puserscanin);
+       /* Send scan command(s)
+        * numchannels contains the number of channels we should maximally scan
+        * chan_count is the total number of channels to scan
+        */
 
-       /* Keep the data path active if we are only scanning our current channel */
-       if (!scancurrentchanonly) {
-               netif_stop_queue(priv->dev);
-               netif_carrier_off(priv->dev);
-               if (priv->mesh_dev) {
-                       netif_stop_queue(priv->mesh_dev);
-                       netif_carrier_off(priv->mesh_dev);
+       while (chan_count) {
+               int to_scan = min(numchannels, chan_count);
+               lbs_deb_scan("scanning %d of %d channels\n",
+                       to_scan, chan_count);
+               ret = lbs_do_scan(priv, bsstype, curr_chans,
+                       to_scan, user_cfg);
+               if (ret) {
+                       lbs_pr_err("SCAN_CMD failed\n");
+                       goto out2;
+               }
+               curr_chans += to_scan;
+               chan_count -= to_scan;
+
+               /* somehow schedule the next part of the scan */
+               if (chan_count &&
+                   !full_scan &&
+                   !priv->surpriseremoved) {
+                       /* -1 marks just that we're currently scanning */
+                       if (priv->last_scanned_channel < 0)
+                               priv->last_scanned_channel = to_scan;
+                       else
+                               priv->last_scanned_channel += to_scan;
+                       cancel_delayed_work(&priv->scan_work);
+                       queue_delayed_work(priv->work_thread, &priv->scan_work,
+                               msecs_to_jiffies(300));
+                       /* skip over GIWSCAN event */
+                       goto out;
                }
-       }
 
-       ret = wlan_scan_channel_list(priv,
-                                    maxchanperscan,
-                                    filteredscan,
-                                    scan_cfg,
-                                    pchantlvout,
-                                    scan_chan_list,
-                                    puserscanin,
-                                    full_scan);
+       }
+       memset(&wrqu, 0, sizeof(union iwreq_data));
+       wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
 
 #ifdef CONFIG_LIBERTAS_DEBUG
        /* Dump the scan table */
-       mutex_lock(&adapter->lock);
-       lbs_deb_scan("The scan table contains:\n");
-       list_for_each_entry (iter_bss, &adapter->network_list, list) {
-               lbs_deb_scan("scan %02d, %s, RSSI, %d, SSID '%s'\n",
-                      i++, print_mac(mac, iter_bss->bssid), (s32) iter_bss->rssi,
-                      escape_essid(iter_bss->ssid, iter_bss->ssid_len));
-       }
-       mutex_unlock(&adapter->lock);
+       mutex_lock(&priv->lock);
+       lbs_deb_scan("scan table:\n");
+       list_for_each_entry(iter, &priv->network_list, list)
+               lbs_deb_scan("%02d: BSSID %s, RSSI %d, SSID '%s'\n",
+                      i++, print_mac(mac, iter->bssid), (s32) iter->rssi,
+                      escape_essid(iter->ssid, iter->ssid_len));
+       mutex_unlock(&priv->lock);
 #endif
 
-       if (priv->adapter->connect_status == LIBERTAS_CONNECTED) {
+out2:
+       priv->last_scanned_channel = 0;
+
+out:
+       if (priv->connect_status == LBS_CONNECTED) {
                netif_carrier_on(priv->dev);
-               netif_wake_queue(priv->dev);
-               if (priv->mesh_dev) {
-                       netif_carrier_on(priv->mesh_dev);
+               if (!priv->tx_pending_len)
+                       netif_wake_queue(priv->dev);
+       }
+       if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
+               netif_carrier_on(priv->mesh_dev);
+               if (!priv->tx_pending_len)
                        netif_wake_queue(priv->mesh_dev);
-               }
        }
-
-out:
-       if (scan_cfg)
-               kfree(scan_cfg);
-
-       if (scan_chan_list)
-               kfree(scan_chan_list);
+       kfree(chan_list);
 
        lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
        return ret;
 }
 
+
+
+
+/*********************************************************************/
+/*                                                                   */
+/*  Result interpretation                                            */
+/*                                                                   */
+/*********************************************************************/
+
 /**
  *  @brief Interpret a BSS scan response returned from the firmware
  *
  *  Parse the various fixed fields and IEs passed back for a a BSS probe
- *   response or beacon from the scan command.  Record information as needed
- *   in the scan table struct bss_descriptor for that entry.
+ *  response or beacon from the scan command.  Record information as needed
+ *  in the scan table struct bss_descriptor for that entry.
  *
  *  @param bss  Output parameter: Pointer to the BSS Entry
  *
  *  @return             0 or -1
  */
-static int libertas_process_bss(struct bss_descriptor * bss,
+static int lbs_process_bss(struct bss_descriptor *bss,
                                u8 ** pbeaconinfo, int *bytesleft)
 {
        struct ieeetypes_fhparamset *pFH;
@@ -946,7 +711,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
        if (*bytesleft >= sizeof(beaconsize)) {
                /* Extract & convert beacon size from the command buffer */
-               beaconsize = le16_to_cpu(get_unaligned((u16 *)*pbeaconinfo));
+               beaconsize = le16_to_cpu(get_unaligned((__le16 *)*pbeaconinfo));
                *bytesleft -= sizeof(beaconsize);
                *pbeaconinfo += sizeof(beaconsize);
        }
@@ -967,7 +732,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
        *bytesleft -= beaconsize;
 
        memcpy(bss->bssid, pos, ETH_ALEN);
-       lbs_deb_scan("process_bss: AP BSSID %s\n", print_mac(mac, bss->bssid));
+       lbs_deb_scan("process_bss: BSSID %s\n", print_mac(mac, bss->bssid));
        pos += ETH_ALEN;
 
        if ((end - pos) < 12) {
@@ -983,7 +748,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
        /* RSSI is 1 byte long */
        bss->rssi = *pos;
-       lbs_deb_scan("process_bss: RSSI=%02X\n", *pos);
+       lbs_deb_scan("process_bss: RSSI %d\n", *pos);
        pos++;
 
        /* time stamp is 8 bytes long */
@@ -995,18 +760,18 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
        /* capability information is 2 bytes long */
        bss->capability = le16_to_cpup((void *) pos);
-       lbs_deb_scan("process_bss: capabilities = 0x%4X\n", bss->capability);
+       lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability);
        pos += 2;
 
        if (bss->capability & WLAN_CAPABILITY_PRIVACY)
-               lbs_deb_scan("process_bss: AP WEP enabled\n");
+               lbs_deb_scan("process_bss: WEP enabled\n");
        if (bss->capability & WLAN_CAPABILITY_IBSS)
                bss->mode = IW_MODE_ADHOC;
        else
                bss->mode = IW_MODE_INFRA;
 
        /* rest of the current buffer are IE's */
-       lbs_deb_scan("process_bss: IE length for this AP = %zd\n", end - pos);
+       lbs_deb_scan("process_bss: IE len %zd\n", end - pos);
        lbs_deb_hex(LBS_DEB_SCAN, "process_bss: IE info", pos, end - pos);
 
        /* process variable IE */
@@ -1024,7 +789,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                case MFIE_TYPE_SSID:
                        bss->ssid_len = elem->len;
                        memcpy(bss->ssid, elem->data, elem->len);
-                       lbs_deb_scan("ssid '%s', ssid length %u\n",
+                       lbs_deb_scan("got SSID IE: '%s', len %u\n",
                                     escape_essid(bss->ssid, bss->ssid_len),
                                     bss->ssid_len);
                        break;
@@ -1033,16 +798,14 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                        n_basic_rates = min_t(u8, MAX_RATES, elem->len);
                        memcpy(bss->rates, elem->data, n_basic_rates);
                        got_basic_rates = 1;
+                       lbs_deb_scan("got RATES IE\n");
                        break;
 
                case MFIE_TYPE_FH_SET:
                        pFH = (struct ieeetypes_fhparamset *) pos;
                        memmove(&bss->phyparamset.fhparamset, pFH,
                                sizeof(struct ieeetypes_fhparamset));
-#if 0 /* I think we can store these LE */
-                       bss->phyparamset.fhparamset.dwelltime
-                           = le16_to_cpu(bss->phyparamset.fhparamset.dwelltime);
-#endif
+                       lbs_deb_scan("got FH IE\n");
                        break;
 
                case MFIE_TYPE_DS_SET:
@@ -1050,31 +813,31 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                        bss->channel = pDS->currentchan;
                        memcpy(&bss->phyparamset.dsparamset, pDS,
                               sizeof(struct ieeetypes_dsparamset));
+                       lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
                        break;
 
                case MFIE_TYPE_CF_SET:
                        pCF = (struct ieeetypes_cfparamset *) pos;
                        memcpy(&bss->ssparamset.cfparamset, pCF,
                               sizeof(struct ieeetypes_cfparamset));
+                       lbs_deb_scan("got CF IE\n");
                        break;
 
                case MFIE_TYPE_IBSS_SET:
                        pibss = (struct ieeetypes_ibssparamset *) pos;
-                       bss->atimwindow = le32_to_cpu(pibss->atimwindow);
+                       bss->atimwindow = le16_to_cpu(pibss->atimwindow);
                        memmove(&bss->ssparamset.ibssparamset, pibss,
                                sizeof(struct ieeetypes_ibssparamset));
-#if 0
-                       bss->ssparamset.ibssparamset.atimwindow
-                           = le16_to_cpu(bss->ssparamset.ibssparamset.atimwindow);
-#endif
+                       lbs_deb_scan("got IBSS IE\n");
                        break;
 
                case MFIE_TYPE_COUNTRY:
                        pcountryinfo = (struct ieeetypes_countryinfoset *) 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",
+                                      "CountryInfo len %d, min %zd, max 254\n",
                                       pcountryinfo->len,
                                       sizeof(pcountryinfo->countrycode));
                                ret = -1;
@@ -1093,8 +856,11 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                         * already found. Data rate IE should come before
                         * extended supported rate IE
                         */
-                       if (!got_basic_rates)
+                       lbs_deb_scan("got RATESEX IE\n");
+                       if (!got_basic_rates) {
+                               lbs_deb_scan("... but ignoring it\n");
                                break;
+                       }
 
                        n_ex_rates = elem->len;
                        if (n_basic_rates + n_ex_rates > MAX_RATES)
@@ -1113,24 +879,36 @@ static int libertas_process_bss(struct bss_descriptor * bss,
                                bss->wpa_ie_len = min(elem->len + 2,
                                                      MAX_WPA_IE_LEN);
                                memcpy(bss->wpa_ie, elem, bss->wpa_ie_len);
-                               lbs_deb_hex(LBS_DEB_SCAN, "process_bss: WPA IE", bss->wpa_ie,
+                               lbs_deb_scan("got WPA IE\n");
+                               lbs_deb_hex(LBS_DEB_SCAN, "WPA IE", bss->wpa_ie,
                                            elem->len);
                        } else if (elem->len >= MARVELL_MESH_IE_LENGTH &&
                            elem->data[0] == 0x00 &&
                            elem->data[1] == 0x50 &&
                            elem->data[2] == 0x43 &&
                            elem->data[3] == 0x04) {
+                               lbs_deb_scan("got mesh IE\n");
                                bss->mesh = 1;
+                       } else {
+                               lbs_deb_scan("got generiec IE: "
+                                       "%02x:%02x:%02x:%02x, len %d\n",
+                                       elem->data[0], elem->data[1],
+                                       elem->data[2], elem->data[3],
+                                       elem->len);
                        }
                        break;
 
                case MFIE_TYPE_RSN:
+                       lbs_deb_scan("got RSN IE\n");
                        bss->rsn_ie_len = min(elem->len + 2, MAX_WPA_IE_LEN);
                        memcpy(bss->rsn_ie, elem, bss->rsn_ie_len);
-                       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE", bss->rsn_ie, elem->len);
+                       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: RSN_IE",
+                               bss->rsn_ie, elem->len);
                        break;
 
                default:
+                       lbs_deb_scan("got IE 0x%04x, len %d\n",
+                               elem->id, elem->len);
                        break;
                }
 
@@ -1139,7 +917,7 @@ static int libertas_process_bss(struct bss_descriptor * bss,
 
        /* Timestamp */
        bss->last_scanned = jiffies;
-       libertas_unset_basic_rate_flags(bss->rates, sizeof(bss->rates));
+       lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates));
 
        ret = 0;
 
@@ -1153,13 +931,13 @@ done:
  *
  *  Used in association code
  *
- *  @param adapter  A pointer to wlan_adapter
+ *  @param priv  A pointer to struct lbs_private
  *  @param bssid    BSSID to find in the scan list
  *  @param mode     Network mode: Infrastructure or IBSS
  *
  *  @return         index in BSSID list, or error return code (< 0)
  */
-struct bss_descriptor *libertas_find_bssid_in_list(wlan_adapter * adapter,
+struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
                u8 * bssid, u8 mode)
 {
        struct bss_descriptor * iter_bss;
@@ -1177,14 +955,14 @@ struct bss_descriptor *libertas_find_bssid_in_list(wlan_adapter * adapter,
         *   continue past a matched bssid that is not compatible in case there
         *   is an AP with multiple SSIDs assigned to the same BSSID
         */
-       mutex_lock(&adapter->lock);
-       list_for_each_entry (iter_bss, &adapter->network_list, list) {
+       mutex_lock(&priv->lock);
+       list_for_each_entry (iter_bss, &priv->network_list, list) {
                if (compare_ether_addr(iter_bss->bssid, bssid))
                        continue; /* bssid doesn't match */
                switch (mode) {
                case IW_MODE_INFRA:
                case IW_MODE_ADHOC:
-                       if (!is_network_compatible(adapter, iter_bss, mode))
+                       if (!is_network_compatible(priv, iter_bss, mode))
                                break;
                        found_bss = iter_bss;
                        break;
@@ -1193,7 +971,7 @@ struct bss_descriptor *libertas_find_bssid_in_list(wlan_adapter * adapter,
                        break;
                }
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
 out:
        lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
@@ -1205,14 +983,14 @@ out:
  *
  *  Used in association code
  *
- *  @param adapter  A pointer to wlan_adapter
+ *  @param priv  A pointer to struct lbs_private
  *  @param ssid     SSID to find in the list
  *  @param bssid    BSSID to qualify the SSID selection (if provided)
  *  @param mode     Network mode: Infrastructure or IBSS
  *
  *  @return         index in BSSID list
  */
-struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
+struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
                   u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
                   int channel)
 {
@@ -1223,14 +1001,14 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
-       list_for_each_entry (iter_bss, &adapter->network_list, list) {
+       list_for_each_entry (iter_bss, &priv->network_list, list) {
                if (   !tmp_oldest
                    || (iter_bss->last_scanned < tmp_oldest->last_scanned))
                        tmp_oldest = iter_bss;
 
-               if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
+               if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len,
                                      ssid, ssid_len) != 0)
                        continue; /* ssid doesn't match */
                if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0)
@@ -1241,7 +1019,7 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
                switch (mode) {
                case IW_MODE_INFRA:
                case IW_MODE_ADHOC:
-                       if (!is_network_compatible(adapter, iter_bss, mode))
+                       if (!is_network_compatible(priv, iter_bss, mode))
                                break;
 
                        if (bssid) {
@@ -1266,7 +1044,7 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
        }
 
 out:
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
        lbs_deb_leave_args(LBS_DEB_SCAN, "found_bss %p", found_bss);
        return found_bss;
 }
@@ -1277,12 +1055,13 @@ out:
  *  Search the scan table for the best SSID that also matches the current
  *   adapter network preference (infrastructure or adhoc)
  *
- *  @param adapter  A pointer to wlan_adapter
+ *  @param priv  A pointer to struct lbs_private
  *
  *  @return         index in BSSID list
  */
-static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter,
-               u8 mode)
+static struct bss_descriptor *lbs_find_best_ssid_in_list(
+       struct lbs_private *priv,
+       u8 mode)
 {
        u8 bestrssi = 0;
        struct bss_descriptor * iter_bss;
@@ -1290,13 +1069,13 @@ static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * ad
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
-       list_for_each_entry (iter_bss, &adapter->network_list, list) {
+       list_for_each_entry (iter_bss, &priv->network_list, list) {
                switch (mode) {
                case IW_MODE_INFRA:
                case IW_MODE_ADHOC:
-                       if (!is_network_compatible(adapter, iter_bss, mode))
+                       if (!is_network_compatible(priv, iter_bss, mode))
                                break;
                        if (SCAN_RSSI(iter_bss->rssi) <= bestrssi)
                                break;
@@ -1313,7 +1092,7 @@ static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * ad
                }
        }
 
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
        lbs_deb_leave_args(LBS_DEB_SCAN, "best_bss %p", best_bss);
        return best_bss;
 }
@@ -1323,27 +1102,24 @@ static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * ad
  *
  *  Used from association worker.
  *
- *  @param priv         A pointer to wlan_private structure
+ *  @param priv         A pointer to struct lbs_private structure
  *  @param pSSID        A pointer to AP's ssid
  *
  *  @return             0--success, otherwise--fail
  */
-int libertas_find_best_network_ssid(wlan_private * priv,
+int lbs_find_best_network_ssid(struct lbs_private *priv,
                u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode)
 {
-       wlan_adapter *adapter = priv->adapter;
        int ret = -1;
        struct bss_descriptor * found;
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
-       wlan_scan_networks(priv, NULL, 1);
-       if (adapter->surpriseremoved)
+       lbs_scan_networks(priv, NULL, 1);
+       if (priv->surpriseremoved)
                goto out;
 
-       wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
-
-       found = libertas_find_best_ssid_in_list(adapter, preferred_mode);
+       found = lbs_find_best_ssid_in_list(priv, preferred_mode);
        if (found && (found->ssid_len > 0)) {
                memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE);
                *out_ssid_len = found->ssid_len;
@@ -1356,57 +1132,24 @@ out:
        return ret;
 }
 
-/**
- *  @brief Scan Network
- *
- *  @param dev          A pointer to net_device structure
- *  @param info         A pointer to iw_request_info structure
- *  @param vwrq         A pointer to iw_param structure
- *  @param extra        A pointer to extra data buf
- *
- *  @return             0 --success, otherwise fail
- */
-int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
-                 struct iw_param *vwrq, char *extra)
-{
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
-
-       lbs_deb_enter(LBS_DEB_SCAN);
-
-       if (!delayed_work_pending(&priv->scan_work)) {
-               queue_delayed_work(priv->work_thread, &priv->scan_work,
-                                  msecs_to_jiffies(50));
-       }
-
-       if (adapter->surpriseremoved)
-               return -1;
-
-       lbs_deb_leave(LBS_DEB_SCAN);
-       return 0;
-}
-
 
 /**
  *  @brief Send a scan command for all available channels filtered on a spec
  *
  *  Used in association code and from debugfs
  *
- *  @param priv             A pointer to wlan_private structure
+ *  @param priv             A pointer to struct lbs_private structure
  *  @param ssid             A pointer to the SSID to scan for
  *  @param ssid_len         Length of the SSID
  *  @param clear_ssid       Should existing scan results with this SSID
  *                          be cleared?
- *  @param prequestedssid   A pointer to AP's ssid
- *  @param keeppreviousscan Flag used to save/clear scan table before scan
  *
  *  @return                0-success, otherwise fail
  */
-int libertas_send_specific_ssid_scan(wlan_private * priv,
+int lbs_send_specific_ssid_scan(struct lbs_private *priv,
                        u8 *ssid, u8 ssid_len, u8 clear_ssid)
 {
-       wlan_adapter *adapter = priv->adapter;
-       struct wlan_ioctl_user_scan_cfg scancfg;
+       struct lbs_ioctl_user_scan_cfg scancfg;
        int ret = 0;
 
        lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d",
@@ -1420,12 +1163,11 @@ int libertas_send_specific_ssid_scan(wlan_private * priv,
        scancfg.ssid_len = ssid_len;
        scancfg.clear_ssid = clear_ssid;
 
-       wlan_scan_networks(priv, &scancfg, 1);
-       if (adapter->surpriseremoved) {
+       lbs_scan_networks(priv, &scancfg, 1);
+       if (priv->surpriseremoved) {
                ret = -1;
                goto out;
        }
-       wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
 
 out:
        lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
@@ -1441,13 +1183,13 @@ out:
 /*                                                                   */
 /*********************************************************************/
 
+
 #define MAX_CUSTOM_LEN 64
 
-static inline char *libertas_translate_scan(wlan_private *priv,
+static inline char *lbs_translate_scan(struct lbs_private *priv,
                                        char *start, char *stop,
                                        struct bss_descriptor *bss)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct chan_freq_power *cfp;
        char *current_val;      /* For rates */
        struct iw_event iwe;    /* Temporary buffer */
@@ -1459,14 +1201,14 @@ static inline char *libertas_translate_scan(wlan_private *priv,
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
-       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel);
+       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, bss->channel);
        if (!cfp) {
                lbs_deb_scan("Invalid channel number %d\n", bss->channel);
                start = NULL;
                goto out;
        }
 
-       /* First entry *MUST* be the AP BSSID */
+       /* First entry *MUST* be the BSSID */
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
        memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
@@ -1502,25 +1244,25 @@ static inline char *libertas_translate_scan(wlan_private *priv,
        if (iwe.u.qual.qual > 100)
                iwe.u.qual.qual = 100;
 
-       if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
+       if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
                iwe.u.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
        } else {
                iwe.u.qual.noise =
-                   CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
+                   CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
        }
 
        /* Locally created ad-hoc BSSs won't have beacons if this is the
         * only station in the adhoc network; so get signal strength
         * from receive statistics.
         */
-       if ((adapter->mode == IW_MODE_ADHOC)
-           && adapter->adhoccreate
-           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
-                                 adapter->curbssparams.ssid_len,
+       if ((priv->mode == IW_MODE_ADHOC)
+           && priv->adhoccreate
+           && !lbs_ssid_cmp(priv->curbssparams.ssid,
+                                 priv->curbssparams.ssid_len,
                                  bss->ssid, bss->ssid_len)) {
                int snr, nf;
-               snr = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-               nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
+               snr = priv->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
+               nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
                iwe.u.qual.level = CAL_RSSI(snr, nf);
        }
        start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
@@ -1549,10 +1291,10 @@ static inline char *libertas_translate_scan(wlan_private *priv,
                                         stop, &iwe, IW_EV_PARAM_LEN);
        }
        if ((bss->mode == IW_MODE_ADHOC)
-           && !libertas_ssid_cmp(adapter->curbssparams.ssid,
-                                 adapter->curbssparams.ssid_len,
+           && !lbs_ssid_cmp(priv->curbssparams.ssid,
+                                 priv->curbssparams.ssid_len,
                                  bss->ssid, bss->ssid_len)
-           && adapter->adhoccreate) {
+           && priv->adhoccreate) {
                iwe.u.bitrate.value = 22 * 500000;
                current_val = iwe_stream_add_value(start, current_val,
                                         stop, &iwe, IW_EV_PARAM_LEN);
@@ -1596,6 +1338,54 @@ out:
        return start;
 }
 
+
+/**
+ *  @brief Handle Scan Network ioctl
+ *
+ *  @param dev          A pointer to net_device structure
+ *  @param info         A pointer to iw_request_info structure
+ *  @param vwrq         A pointer to iw_param structure
+ *  @param extra        A pointer to extra data buf
+ *
+ *  @return             0 --success, otherwise fail
+ */
+int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
+                 struct iw_param *wrqu, char *extra)
+{
+       struct lbs_private *priv = dev->priv;
+
+       lbs_deb_enter(LBS_DEB_SCAN);
+
+       if (!netif_running(dev))
+               return -ENETDOWN;
+
+       /* mac80211 does this:
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       if (sdata->type != IEEE80211_IF_TYPE_xxx)
+               return -EOPNOTSUPP;
+
+       if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+           wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+               req = (struct iw_scan_req *)extra;
+                       ssid = req->essid;
+               ssid_len = req->essid_len;
+       }
+       */
+
+       if (!delayed_work_pending(&priv->scan_work))
+               queue_delayed_work(priv->work_thread, &priv->scan_work,
+                       msecs_to_jiffies(50));
+       /* set marker that currently a scan is taking place */
+       priv->last_scanned_channel = -1;
+
+       if (priv->surpriseremoved)
+               return -EIO;
+
+       lbs_deb_leave(LBS_DEB_SCAN);
+       return 0;
+}
+
+
 /**
  *  @brief  Handle Retrieve scan table ioctl
  *
@@ -1606,12 +1396,11 @@ out:
  *
  *  @return             0 --success, otherwise fail
  */
-int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
+int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
                  struct iw_point *dwrq, char *extra)
 {
 #define SCAN_ITEM_SIZE 128
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int err = 0;
        char *ev = extra;
        char *stop = ev + dwrq->length;
@@ -1620,14 +1409,18 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
+       /* iwlist should wait until the current scan is finished */
+       if (priv->last_scanned_channel)
+               return -EAGAIN;
+
        /* Update RSSI if current BSS is a locally created ad-hoc BSS */
-       if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) {
-               libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+       if ((priv->mode == IW_MODE_ADHOC) && priv->adhoccreate) {
+               lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
                                        CMD_OPTION_WAITFORRSP, 0, NULL);
        }
 
-       mutex_lock(&adapter->lock);
-       list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
+       mutex_lock(&priv->lock);
+       list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
                char * next_ev;
                unsigned long stale_time;
 
@@ -1644,18 +1437,18 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
                stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
                if (time_after(jiffies, stale_time)) {
                        list_move_tail (&iter_bss->list,
-                                       &adapter->network_free_list);
+                                       &priv->network_free_list);
                        clear_bss_descriptor(iter_bss);
                        continue;
                }
 
                /* Translate to WE format this entry */
-               next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
+               next_ev = lbs_translate_scan(priv, ev, stop, iter_bss);
                if (next_ev == NULL)
                        continue;
                ev = next_ev;
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        dwrq->length = (ev - extra);
        dwrq->flags = 0;
@@ -1677,24 +1470,25 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 /**
  *  @brief Prepare a scan command to be sent to the firmware
  *
- *  Called from libertas_prepare_and_send_command() in cmd.c
+ *  Called via lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, ...)
+ *  from cmd.c
  *
  *  Sends a fixed lenght data part (specifying the BSS type and BSSID filters)
  *  as well as a variable number/length of TLVs to the firmware.
  *
- *  @param priv       A pointer to wlan_private structure
+ *  @param priv       A pointer to struct lbs_private structure
  *  @param cmd        A pointer to cmd_ds_command structure to be sent to
  *                    firmware with the cmd_DS_801_11_SCAN structure
- *  @param pdata_buf  Void pointer cast of a wlan_scan_cmd_config struct used
+ *  @param pdata_buf  Void pointer cast of a lbs_scan_cmd_config struct used
  *                    to set the fields/TLVs for the command sent to firmware
  *
  *  @return           0 or -1
  */
-int libertas_cmd_80211_scan(wlan_private * priv,
-                        struct cmd_ds_command *cmd, void *pdata_buf)
+int lbs_cmd_80211_scan(struct lbs_private *priv,
+       struct cmd_ds_command *cmd, void *pdata_buf)
 {
        struct cmd_ds_802_11_scan *pscan = &cmd->params.scan;
-       struct wlan_scan_cmd_config *pscancfg = pdata_buf;
+       struct lbs_scan_cmd_config *pscancfg = pdata_buf;
 
        lbs_deb_enter(LBS_DEB_SCAN);
 
@@ -1703,32 +1497,14 @@ int libertas_cmd_80211_scan(wlan_private * priv,
        memcpy(pscan->bssid, pscancfg->bssid, ETH_ALEN);
        memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
 
-       cmd->command = cpu_to_le16(CMD_802_11_SCAN);
-
        /* size is equal to the sizeof(fixed portions) + the TLV len + header */
        cmd->size = cpu_to_le16(sizeof(pscan->bsstype) + ETH_ALEN
                                + pscancfg->tlvbufferlen + S_DS_GEN);
 
-       lbs_deb_scan("SCAN_CMD: command 0x%04x, size %d, seqnum %d\n",
-                    le16_to_cpu(cmd->command), le16_to_cpu(cmd->size),
-                    le16_to_cpu(cmd->seqnum));
-
        lbs_deb_leave(LBS_DEB_SCAN);
        return 0;
 }
 
-static inline int is_same_network(struct bss_descriptor *src,
-                                 struct bss_descriptor *dst)
-{
-       /* A network is only a duplicate if the channel, BSSID, and ESSID
-        * all match.  We treat all <hidden> with the same BSSID and channel
-        * as one network */
-       return ((src->ssid_len == dst->ssid_len) &&
-               (src->channel == dst->channel) &&
-               !compare_ether_addr(src->bssid, dst->bssid) &&
-               !memcmp(src->ssid, dst->ssid, src->ssid_len));
-}
-
 /**
  *  @brief This function handles the command response of scan
  *
@@ -1750,14 +1526,13 @@ static inline int is_same_network(struct bss_descriptor *src,
  *     |            bufsize and sizeof the fixed fields above)     |
  *     .-----------------------------------------------------------.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @param resp    A pointer to cmd_ds_command
  *
  *  @return        0 or -1
  */
-int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
+int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct cmd_ds_802_11_scan_rsp *pscan;
        struct bss_descriptor * iter_bss;
        struct bss_descriptor * safe;
@@ -1771,11 +1546,11 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
        lbs_deb_enter(LBS_DEB_SCAN);
 
        /* Prune old entries from scan table */
-       list_for_each_entry_safe (iter_bss, safe, &adapter->network_list, list) {
+       list_for_each_entry_safe (iter_bss, safe, &priv->network_list, list) {
                unsigned long stale_time = iter_bss->last_scanned + DEFAULT_MAX_SCAN_AGE;
                if (time_before(jiffies, stale_time))
                        continue;
-               list_move_tail (&iter_bss->list, &adapter->network_free_list);
+               list_move_tail (&iter_bss->list, &priv->network_free_list);
                clear_bss_descriptor(iter_bss);
        }
 
@@ -1789,12 +1564,11 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
                goto done;
        }
 
-       bytesleft = le16_to_cpu(get_unaligned((u16*)&pscan->bssdescriptsize));
+       bytesleft = le16_to_cpu(pscan->bssdescriptsize);
        lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
 
-       scanrespsize = le16_to_cpu(get_unaligned((u16*)&resp->size));
-       lbs_deb_scan("SCAN_RESP: returned %d AP before parsing\n",
-              pscan->nr_sets);
+       scanrespsize = le16_to_cpu(resp->size);
+       lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets);
 
        pbssinfo = pscan->bssdesc_and_tlvbuffer;
 
@@ -1821,14 +1595,14 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
 
                /* Process the data fields and IEs returned for this BSS */
                memset(&new, 0, sizeof (struct bss_descriptor));
-               if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
+               if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) {
                        /* error parsing the scan response, skipped */
                        lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n");
                        continue;
                }
 
                /* Try to find this bss in the scan table */
-               list_for_each_entry (iter_bss, &adapter->network_list, list) {
+               list_for_each_entry (iter_bss, &priv->network_list, list) {
                        if (is_same_network(iter_bss, &new)) {
                                found = iter_bss;
                                break;
@@ -1842,21 +1616,21 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp)
                if (found) {
                        /* found, clear it */
                        clear_bss_descriptor(found);
-               } else if (!list_empty(&adapter->network_free_list)) {
+               } else if (!list_empty(&priv->network_free_list)) {
                        /* Pull one from the free list */
-                       found = list_entry(adapter->network_free_list.next,
+                       found = list_entry(priv->network_free_list.next,
                                           struct bss_descriptor, list);
-                       list_move_tail(&found->list, &adapter->network_list);
+                       list_move_tail(&found->list, &priv->network_list);
                } else if (oldest) {
                        /* If there are no more slots, expire the oldest */
                        found = oldest;
                        clear_bss_descriptor(found);
-                       list_move_tail(&found->list, &adapter->network_list);
+                       list_move_tail(&found->list, &priv->network_list);
                } else {
                        continue;
                }
 
-               lbs_deb_scan("SCAN_RESP: BSSID %s\n",
+               lbs_deb_scan("SCAN_RESP: BSSID %s\n",
                             print_mac(mac, new.bssid));
 
                /* Copy the locally created newbssentry to the scan table */
index c29c031bef8cf8a9798ee9bf31e9314e0acc0676..319f70dde350dcd48c034ba1ee100b75ad2b2d35 100644 (file)
@@ -2,10 +2,10 @@
   * Interface for the wlan network scan routines
   *
   * Driver interface functions and type declarations for the scan module
-  *   implemented in wlan_scan.c.
+  * implemented in scan.c.
   */
-#ifndef _WLAN_SCAN_H
-#define _WLAN_SCAN_H
+#ifndef _LBS_SCAN_H
+#define _LBS_SCAN_H
 
 #include <net/ieee80211.h>
 #include "hostcmd.h"
 /**
  *  @brief Maximum number of channels that can be sent in a setuserscan ioctl
  *
- *  @sa wlan_ioctl_user_scan_cfg
+ *  @sa lbs_ioctl_user_scan_cfg
  */
-#define WLAN_IOCTL_USER_SCAN_CHAN_MAX  50
+#define LBS_IOCTL_USER_SCAN_CHAN_MAX  50
 
-//! Infrastructure BSS scan type in wlan_scan_cmd_config
-#define WLAN_SCAN_BSS_TYPE_BSS         1
+//! Infrastructure BSS scan type in lbs_scan_cmd_config
+#define LBS_SCAN_BSS_TYPE_BSS         1
 
-//! Adhoc BSS scan type in wlan_scan_cmd_config
-#define WLAN_SCAN_BSS_TYPE_IBSS        2
+//! Adhoc BSS scan type in lbs_scan_cmd_config
+#define LBS_SCAN_BSS_TYPE_IBSS        2
 
-//! Adhoc or Infrastructure BSS scan type in wlan_scan_cmd_config, no filter
-#define WLAN_SCAN_BSS_TYPE_ANY         3
+//! Adhoc or Infrastructure BSS scan type in lbs_scan_cmd_config, no filter
+#define LBS_SCAN_BSS_TYPE_ANY         3
 
 /**
  * @brief Structure used internally in the wlan driver to configure a scan.
  *
  * Sent to the command processing module to configure the firmware
- *   scan command prepared by libertas_cmd_80211_scan.
+ *   scan command prepared by lbs_cmd_80211_scan.
  *
- * @sa wlan_scan_networks
+ * @sa lbs_scan_networks
  *
  */
-struct wlan_scan_cmd_config {
+struct lbs_scan_cmd_config {
     /**
      *  @brief BSS type to be sent in the firmware command
      *
      *  Field can be used to restrict the types of networks returned in the
      *    scan.  valid settings are:
      *
-     *   - WLAN_SCAN_BSS_TYPE_BSS  (infrastructure)
-     *   - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
-     *   - WLAN_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
+     *   - LBS_SCAN_BSS_TYPE_BSS  (infrastructure)
+     *   - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
+     *   - LBS_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
      */
        u8 bsstype;
 
@@ -68,12 +68,12 @@ struct wlan_scan_cmd_config {
 };
 
 /**
- *  @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg
+ *  @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg
  *
  *  Multiple instances of this structure are included in the IOCTL command
  *   to configure a instance of a scan on the specific channel.
  */
-struct wlan_ioctl_user_scan_chan {
+struct lbs_ioctl_user_scan_chan {
        u8 channumber;          //!< channel Number to scan
        u8 radiotype;           //!< Radio type: 'B/G' band = 0, 'A' band = 1
        u8 scantype;            //!< Scan type: Active = 0, Passive = 1
@@ -83,31 +83,26 @@ struct wlan_ioctl_user_scan_chan {
 /**
  *  @brief IOCTL input structure to configure an immediate scan cmd to firmware
  *
- *  Used in the setuserscan (WLAN_SET_USER_SCAN) private ioctl.  Specifies
+ *  Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl.  Specifies
  *   a number of parameters to be used in general for the scan as well
- *   as a channel list (wlan_ioctl_user_scan_chan) for each scan period
+ *   as a channel list (lbs_ioctl_user_scan_chan) for each scan period
  *   desired.
  *
- *  @sa libertas_set_user_scan_ioctl
+ *  @sa lbs_set_user_scan_ioctl
  */
-struct wlan_ioctl_user_scan_cfg {
+struct lbs_ioctl_user_scan_cfg {
     /**
      *  @brief BSS type to be sent in the firmware command
      *
      *  Field can be used to restrict the types of networks returned in the
      *    scan.  valid settings are:
      *
-     *   - WLAN_SCAN_BSS_TYPE_BSS  (infrastructure)
-     *   - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
-     *   - WLAN_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
+     *   - LBS_SCAN_BSS_TYPE_BSS  (infrastructure)
+     *   - LBS_SCAN_BSS_TYPE_IBSS (adhoc)
+     *   - LBS_SCAN_BSS_TYPE_ANY  (unrestricted, adhoc and infrastructure)
      */
        u8 bsstype;
 
-    /**
-     *  @brief Configure the number of probe requests for active chan scans
-     */
-       u8 numprobes;
-
        /**
         *  @brief BSSID filter sent in the firmware command to limit the results
         */
@@ -124,11 +119,6 @@ struct wlan_ioctl_user_scan_cfg {
 
        /* Clear existing scan results matching this SSID */
        u8 clear_ssid;
-
-    /**
-     *  @brief Variable number (fixed maximum) of channels to scan up
-     */
-       struct wlan_ioctl_user_scan_chan chanlist[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
 };
 
 /**
@@ -174,30 +164,30 @@ struct bss_descriptor {
        struct list_head list;
 };
 
-int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
+int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len);
 
-struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter,
-                       u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode,
-                       int channel);
+struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_private *priv,
+               u8 *ssid, u8 ssid_len, u8 *bssid, u8 mode,
+               int channel);
 
-struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter,
-                       u8 * bssid, u8 mode);
+struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_private *priv,
+       u8 *bssid, u8 mode);
 
-int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid,
+int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid,
                        u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode);
 
-int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid,
+int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid,
                                u8 ssid_len, u8 clear_ssid);
 
-int libertas_cmd_80211_scan(wlan_private * priv,
+int lbs_cmd_80211_scan(struct lbs_private *priv,
                                struct cmd_ds_command *cmd,
                                void *pdata_buf);
 
-int libertas_ret_80211_scan(wlan_private * priv,
+int lbs_ret_80211_scan(struct lbs_private *priv,
                                struct cmd_ds_command *resp);
 
-int wlan_scan_networks(wlan_private * priv,
-                const struct wlan_ioctl_user_scan_cfg * puserscanin,
+int lbs_scan_networks(struct lbs_private *priv,
+       const struct lbs_ioctl_user_scan_cfg *puserscanin,
                 int full_scan);
 
 struct ifreq;
@@ -205,11 +195,11 @@ struct ifreq;
 struct iw_point;
 struct iw_param;
 struct iw_request_info;
-int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
+int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra);
-int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
+int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra);
 
-void libertas_scan_worker(struct work_struct *work);
+void lbs_scan_worker(struct work_struct *work);
 
-#endif                         /* _WLAN_SCAN_H */
+#endif
index fbec06c10dd7c227941811f739c5ee820bb8e1f3..00d95f75bd890603d814e4f54e5dff982cae96dd 100644 (file)
@@ -2,6 +2,7 @@
   * This file contains the handling of TX in wlan driver.
   */
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 
 #include "hostcmd.h"
 #include "radiotap.h"
@@ -49,188 +50,122 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
 }
 
 /**
- *  @brief This function processes a single packet and sends
- *  to IF layer
+ *  @brief This function checks the conditions and sends packet to IF
+ *  layer if everything is ok.
  *
- *  @param priv    A pointer to wlan_private structure
+ *  @param priv    A pointer to struct lbs_private structure
  *  @param skb     A pointer to skb which includes TX packet
  *  @return       0 or -1
  */
-static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
+int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       int ret = 0;
-       struct txpd localtxpd;
-       struct txpd *plocaltxpd = &localtxpd;
-       u8 *p802x_hdr;
-       struct tx_radiotap_hdr *pradiotap_hdr;
-       u32 new_rate;
-       u8 *ptr = priv->adapter->tmptxbuf;
+       unsigned long flags;
+       struct lbs_private *priv = dev->priv;
+       struct txpd *txpd;
+       char *p802x_hdr;
+       uint16_t pkt_len;
+       int ret;
 
        lbs_deb_enter(LBS_DEB_TX);
 
-       if (priv->adapter->surpriseremoved)
-               return -1;
+       ret = NETDEV_TX_OK;
+
+       /* We need to protect against the queues being restarted before
+          we get round to stopping them */
+       spin_lock_irqsave(&priv->driver_lock, flags);
+
+       if (priv->surpriseremoved)
+               goto free;
 
        if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
                lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
                       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
-               ret = -1;
-               goto done;
+               /* We'll never manage to send this one; drop it and return 'OK' */
+
+               priv->stats.tx_dropped++;
+               priv->stats.tx_errors++;
+               goto free;
        }
 
-       memset(plocaltxpd, 0, sizeof(struct txpd));
 
-       plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
+       netif_stop_queue(priv->dev);
+       if (priv->mesh_dev)
+               netif_stop_queue(priv->mesh_dev);
 
-       /* offset of actual data */
-       plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
+       if (priv->tx_pending_len) {
+               /* This can happen if packets come in on the mesh and eth
+                  device simultaneously -- there's no mutual exclusion on
+                  hard_start_xmit() calls between devices. */
+               lbs_deb_tx("Packet on %s while busy\n", dev->name);
+               ret = NETDEV_TX_BUSY;
+               goto unlock;
+       }
+
+       priv->tx_pending_len = -1;
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+
+       lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
+
+       txpd = (void *)priv->tx_pending_buf;
+       memset(txpd, 0, sizeof(struct txpd));
 
        p802x_hdr = skb->data;
-       if (priv->adapter->monitormode != WLAN_MONITOR_OFF) {
+       pkt_len = skb->len;
 
-               /* locate radiotap header */
-               pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data;
+       if (dev == priv->rtap_net_dev) {
+               struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
 
                /* set txpd fields from the radiotap header */
-               new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
-               if (new_rate != 0) {
-                       /* use new tx_control[4:0] */
-                       plocaltxpd->tx_control = cpu_to_le32(new_rate);
-               }
+               txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
 
                /* skip the radiotap header */
-               p802x_hdr += sizeof(struct tx_radiotap_hdr);
-               plocaltxpd->tx_packet_length =
-                       cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
-                                   - sizeof(struct tx_radiotap_hdr));
+               p802x_hdr += sizeof(*rtap_hdr);
+               pkt_len -= sizeof(*rtap_hdr);
 
+               /* copy destination address from 802.11 header */
+               memcpy(txpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
+       } else {
+               /* copy destination address from 802.3 header */
+               memcpy(txpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
        }
-       /* copy destination address from 802.3 or 802.11 header */
-       if (priv->adapter->monitormode != WLAN_MONITOR_OFF)
-               memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
-       else
-               memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
 
-       lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
+       txpd->tx_packet_length = cpu_to_le16(pkt_len);
+       txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
 
-       if (IS_MESH_FRAME(skb)) {
-               plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
-       }
+       if (dev == priv->mesh_dev)
+               txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
 
-       memcpy(ptr, plocaltxpd, sizeof(struct txpd));
+       lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
 
-       ptr += sizeof(struct txpd);
+       lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
 
-       lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
-       memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
-       ret = priv->hw_host_to_card(priv, MVMS_DAT,
-                                   priv->adapter->tmptxbuf,
-                                   le16_to_cpu(plocaltxpd->tx_packet_length) +
-                                   sizeof(struct txpd));
+       memcpy(&txpd[1], p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
 
-       if (ret) {
-               lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
-               goto done;
-       }
+       spin_lock_irqsave(&priv->driver_lock, flags);
+       priv->tx_pending_len = pkt_len + sizeof(struct txpd);
 
-       lbs_deb_tx("SendSinglePacket succeeds\n");
+       lbs_deb_tx("%s lined up packet\n", __func__);
 
-done:
-       if (!ret) {
-               priv->stats.tx_packets++;
-               priv->stats.tx_bytes += skb->len;
-       } else {
-               priv->stats.tx_dropped++;
-               priv->stats.tx_errors++;
-       }
+       priv->stats.tx_packets++;
+       priv->stats.tx_bytes += skb->len;
 
-       if (!ret && priv->adapter->monitormode != WLAN_MONITOR_OFF) {
+       dev->trans_start = jiffies;
+
+       if (priv->monitormode != LBS_MONITOR_OFF) {
                /* Keep the skb to echo it back once Tx feedback is
                   received from FW */
                skb_orphan(skb);
-               /* stop processing outgoing pkts */
-               netif_stop_queue(priv->dev);
-               if (priv->mesh_dev)
-                       netif_stop_queue(priv->mesh_dev);
-               /* freeze any packets already in our queues */
-               priv->adapter->TxLockFlag = 1;
-       } else {
-               dev_kfree_skb_any(skb);
-               priv->adapter->currenttxskb = NULL;
-       }
 
-       lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
-       return ret;
-}
-
-
-void libertas_tx_runqueue(wlan_private *priv)
-{
-       wlan_adapter *adapter = priv->adapter;
-       int i;
-
-       spin_lock(&adapter->txqueue_lock);
-       for (i = 0; i < adapter->tx_queue_idx; i++) {
-               struct sk_buff *skb = adapter->tx_queue_ps[i];
-               spin_unlock(&adapter->txqueue_lock);
-               SendSinglePacket(priv, skb);
-               spin_lock(&adapter->txqueue_lock);
-       }
-       adapter->tx_queue_idx = 0;
-       spin_unlock(&adapter->txqueue_lock);
-}
-
-static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb)
-{
-       wlan_adapter *adapter = priv->adapter;
-
-       spin_lock(&adapter->txqueue_lock);
-
-       WARN_ON(priv->adapter->tx_queue_idx >= NR_TX_QUEUE);
-       adapter->tx_queue_ps[adapter->tx_queue_idx++] = skb;
-       if (adapter->tx_queue_idx == NR_TX_QUEUE) {
-               netif_stop_queue(priv->dev);
-               if (priv->mesh_dev)
-                       netif_stop_queue(priv->mesh_dev);
+               /* Keep the skb around for when we get feedback */
+               priv->currenttxskb = skb;
        } else {
-               netif_start_queue(priv->dev);
-               if (priv->mesh_dev)
-                       netif_start_queue(priv->mesh_dev);
-       }
-
-       spin_unlock(&adapter->txqueue_lock);
-}
-
-/**
- *  @brief This function checks the conditions and sends packet to IF
- *  layer if everything is ok.
- *
- *  @param priv    A pointer to wlan_private structure
- *  @return       n/a
- */
-int libertas_process_tx(wlan_private * priv, struct sk_buff *skb)
-{
-       int ret = -1;
-
-       lbs_deb_enter(LBS_DEB_TX);
-       lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
-
-       if (priv->dnld_sent) {
-               lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
-                      priv->dnld_sent);
-               goto done;
-       }
-
-       if ((priv->adapter->psstate == PS_STATE_SLEEP) ||
-           (priv->adapter->psstate == PS_STATE_PRE_SLEEP)) {
-               wlan_tx_queue(priv, skb);
-               return ret;
+ free:
+               dev_kfree_skb_any(skb);
        }
+ unlock:
+       spin_unlock_irqrestore(&priv->driver_lock, flags);
+       wake_up(&priv->waitq);
 
-       priv->adapter->currenttxskb = skb;
-
-       ret = SendSinglePacket(priv, skb);
-done:
        lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
        return ret;
 }
@@ -239,24 +174,23 @@ done:
  *  @brief This function sends to the host the last transmitted packet,
  *  filling the radiotap headers with transmission information.
  *
- *  @param priv     A pointer to wlan_private structure
+ *  @param priv     A pointer to struct lbs_private structure
  *  @param status   A 32 bit value containing transmission status.
  *
  *  @returns void
  */
-void libertas_send_tx_feedback(wlan_private * priv)
+void lbs_send_tx_feedback(struct lbs_private *priv)
 {
-       wlan_adapter *adapter = priv->adapter;
        struct tx_radiotap_hdr *radiotap_hdr;
-       u32 status = adapter->eventcause;
+       u32 status = priv->eventcause;
        int txfail;
        int try_count;
 
-       if (adapter->monitormode == WLAN_MONITOR_OFF ||
-           adapter->currenttxskb == NULL)
+       if (priv->monitormode == LBS_MONITOR_OFF ||
+           priv->currenttxskb == NULL)
                return;
 
-       radiotap_hdr = (struct tx_radiotap_hdr *)adapter->currenttxskb->data;
+       radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data;
 
        txfail = (status >> 24);
 
@@ -269,14 +203,19 @@ void libertas_send_tx_feedback(wlan_private * priv)
 #endif
        try_count = (status >> 16) & 0xff;
        radiotap_hdr->data_retries = (try_count) ?
-           (1 + adapter->txretrycount - try_count) : 0;
-       libertas_upload_rx_packet(priv, adapter->currenttxskb);
-       adapter->currenttxskb = NULL;
-       priv->adapter->TxLockFlag = 0;
-       if (priv->adapter->connect_status == LIBERTAS_CONNECTED) {
+           (1 + priv->txretrycount - try_count) : 0;
+
+
+       priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb,
+                                                     priv->rtap_net_dev);
+       netif_rx(priv->currenttxskb);
+
+       priv->currenttxskb = NULL;
+
+       if (priv->connect_status == LBS_CONNECTED)
                netif_wake_queue(priv->dev);
-               if (priv->mesh_dev)
-                       netif_wake_queue(priv->mesh_dev);
-       }
+
+       if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED))
+               netif_wake_queue(priv->mesh_dev);
 }
-EXPORT_SYMBOL_GPL(libertas_send_tx_feedback);
+EXPORT_SYMBOL_GPL(lbs_send_tx_feedback);
index a43a5f63c879c81d44a4d87834c8d21671c194df..f0d57958b34b141f5c6274ebf59d5f89bc9e56f5 100644 (file)
@@ -1,8 +1,8 @@
 /**
   * This header file contains definition for global types
   */
-#ifndef _WLAN_TYPES_
-#define _WLAN_TYPES_
+#ifndef _LBS_TYPES_H_
+#define _LBS_TYPES_H_
 
 #include <linux/if_ether.h>
 #include <asm/byteorder.h>
@@ -201,22 +201,11 @@ struct mrvlietypes_powercapability {
        s8 maxpower;
 } __attribute__ ((packed));
 
-struct mrvlietypes_rssithreshold {
+/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
+struct mrvlietypes_thresholds {
        struct mrvlietypesheader header;
-       u8 rssivalue;
-       u8 rssifreq;
-} __attribute__ ((packed));
-
-struct mrvlietypes_snrthreshold {
-       struct mrvlietypesheader header;
-       u8 snrvalue;
-       u8 snrfreq;
-} __attribute__ ((packed));
-
-struct mrvlietypes_failurecount {
-       struct mrvlietypesheader header;
-       u8 failvalue;
-       u8 Failfreq;
+       u8 value;
+       u8 freq;
 } __attribute__ ((packed));
 
 struct mrvlietypes_beaconsmissed {
@@ -250,4 +239,4 @@ struct mrvlietypes_ledgpio {
        struct led_pin ledpin[1];
 } __attribute__ ((packed));
 
-#endif                         /* _WLAN_TYPES_ */
+#endif
index 395b7882d4d65f1e33ee074913e026ca71394812..e8bfc26b10a4eb11d647229bc085cea71a00f84c 100644 (file)
 #include "join.h"
 #include "wext.h"
 #include "assoc.h"
+#include "cmd.h"
+
+
+static inline void lbs_postpone_association_work(struct lbs_private *priv)
+{
+       if (priv->surpriseremoved)
+               return;
+       cancel_delayed_work(&priv->assoc_work);
+       queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2);
+}
+
+static inline void lbs_cancel_association_work(struct lbs_private *priv)
+{
+       cancel_delayed_work(&priv->assoc_work);
+       kfree(priv->pending_assoc_req);
+       priv->pending_assoc_req = NULL;
+}
 
 
 /**
  *  @brief Find the channel frequency power info with specific channel
  *
- *  @param adapter     A pointer to wlan_adapter structure
+ *  @param priv        A pointer to struct lbs_private structure
  *  @param band                it can be BAND_A, BAND_G or BAND_B
  *  @param channel      the channel for looking
  *  @return            A pointer to struct chan_freq_power structure or NULL if not find.
  */
-struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * adapter,
-                                                u8 band, u16 channel)
+struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
+       struct lbs_private *priv,
+       u8 band,
+       u16 channel)
 {
        struct chan_freq_power *cfp = NULL;
        struct region_channel *rc;
-       int count = sizeof(adapter->region_channel) /
-           sizeof(adapter->region_channel[0]);
        int i, j;
 
-       for (j = 0; !cfp && (j < count); j++) {
-               rc = &adapter->region_channel[j];
+       for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+               rc = &priv->region_channel[j];
 
-               if (adapter->enable11d)
-                       rc = &adapter->universal_channel[j];
+               if (priv->enable11d)
+                       rc = &priv->universal_channel[j];
                if (!rc->valid || !rc->CFP)
                        continue;
                if (rc->band != band)
@@ -56,7 +73,7 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada
        }
 
        if (!cfp && channel)
-               lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find "
+               lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find "
                       "cfp by band %d / channel %d\n", band, channel);
 
        return cfp;
@@ -65,25 +82,25 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada
 /**
  *  @brief Find the channel frequency power info with specific frequency
  *
- *  @param adapter     A pointer to wlan_adapter structure
+ *  @param priv        A pointer to struct lbs_private structure
  *  @param band                it can be BAND_A, BAND_G or BAND_B
  *  @param freq                the frequency for looking
  *  @return            A pointer to struct chan_freq_power structure or NULL if not find.
  */
-static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
-                                                    u8 band, u32 freq)
+static struct chan_freq_power *find_cfp_by_band_and_freq(
+       struct lbs_private *priv,
+       u8 band,
+       u32 freq)
 {
        struct chan_freq_power *cfp = NULL;
        struct region_channel *rc;
-       int count = sizeof(adapter->region_channel) /
-           sizeof(adapter->region_channel[0]);
        int i, j;
 
-       for (j = 0; !cfp && (j < count); j++) {
-               rc = &adapter->region_channel[j];
+       for (j = 0; !cfp && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+               rc = &priv->region_channel[j];
 
-               if (adapter->enable11d)
-                       rc = &adapter->universal_channel[j];
+               if (priv->enable11d)
+                       rc = &priv->universal_channel[j];
                if (!rc->valid || !rc->CFP)
                        continue;
                if (rc->band != band)
@@ -107,22 +124,21 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter,
 /**
  *  @brief Set Radio On/OFF
  *
- *  @param priv                 A pointer to wlan_private structure
+ *  @param priv                 A pointer to struct lbs_private structure
  *  @option                    Radio Option
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_radio_ioctl(wlan_private * priv, u8 option)
+static int lbs_radio_ioctl(struct lbs_private *priv, u8 option)
 {
        int ret = 0;
-       wlan_adapter *adapter = priv->adapter;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       if (adapter->radioon != option) {
+       if (priv->radioon != option) {
                lbs_deb_wext("switching radio %s\n", option ? "on" : "off");
-               adapter->radioon = option;
+               priv->radioon = option;
 
-               ret = libertas_prepare_and_send_command(priv,
+               ret = lbs_prepare_and_send_command(priv,
                                            CMD_802_11_RADIO_CONTROL,
                                            CMD_ACT_SET,
                                            CMD_OPTION_WAITFORRSP, 0, NULL);
@@ -135,22 +151,23 @@ static int wlan_radio_ioctl(wlan_private * priv, u8 option)
 /**
  *  @brief Copy active data rates based on adapter mode and status
  *
- *  @param adapter              A pointer to wlan_adapter structure
+ *  @param priv              A pointer to struct lbs_private structure
  *  @param rate                        The buf to return the active rates
  */
-static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates)
+static void copy_active_data_rates(struct lbs_private *priv, u8 *rates)
 {
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       if (adapter->connect_status != LIBERTAS_CONNECTED)
-               memcpy(rates, libertas_bg_rates, MAX_RATES);
+       if ((priv->connect_status != LBS_CONNECTED) &&
+               (priv->mesh_connect_status != LBS_CONNECTED))
+               memcpy(rates, lbs_bg_rates, MAX_RATES);
        else
-               memcpy(rates, adapter->curbssparams.rates, MAX_RATES);
+               memcpy(rates, priv->curbssparams.rates, MAX_RATES);
 
        lbs_deb_leave(LBS_DEB_WEXT);
 }
 
-static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_name(struct net_device *dev, struct iw_request_info *info,
                         char *cwrq, char *extra)
 {
 
@@ -163,22 +180,21 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info,
                         struct iw_freq *fwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct chan_freq_power *cfp;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0,
-                                          adapter->curbssparams.channel);
+       cfp = lbs_find_cfp_by_band_and_channel(priv, 0,
+                                          priv->curbssparams.channel);
 
        if (!cfp) {
-               if (adapter->curbssparams.channel)
+               if (priv->curbssparams.channel)
                        lbs_deb_wext("invalid channel %d\n",
-                              adapter->curbssparams.channel);
+                              priv->curbssparams.channel);
                return -EINVAL;
        }
 
@@ -190,16 +206,15 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info,
                        struct sockaddr *awrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
-               memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN);
+       if (priv->connect_status == LBS_CONNECTED) {
+               memcpy(awrq->sa_data, priv->curbssparams.bssid, ETH_ALEN);
        } else {
                memset(awrq->sa_data, 0, ETH_ALEN);
        }
@@ -209,11 +224,10 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -225,25 +239,24 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info,
                return -E2BIG;
        }
 
-       mutex_lock(&adapter->lock);
-       memset(adapter->nodename, 0, sizeof(adapter->nodename));
-       memcpy(adapter->nodename, extra, dwrq->length);
-       mutex_unlock(&adapter->lock);
+       mutex_lock(&priv->lock);
+       memset(priv->nodename, 0, sizeof(priv->nodename));
+       memcpy(priv->nodename, extra, dwrq->length);
+       mutex_unlock(&priv->lock);
 
        lbs_deb_leave(LBS_DEB_WEXT);
        return 0;
 }
 
-static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       dwrq->length = strlen(adapter->nodename);
-       memcpy(extra, adapter->nodename, dwrq->length);
+       dwrq->length = strlen(priv->nodename);
+       memcpy(extra, priv->nodename, dwrq->length);
        extra[dwrq->length] = '\0';
 
        dwrq->flags = 1;        /* active */
@@ -255,14 +268,13 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info,
 static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
                         struct iw_point *dwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        /* Use nickname to indicate that mesh is on */
 
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
+       if (priv->mesh_connect_status == LBS_CONNECTED) {
                strncpy(extra, "Mesh", 12);
                extra[12] = '\0';
                dwrq->length = strlen(extra);
@@ -277,25 +289,24 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        u32 rthr = vwrq->value;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        if (vwrq->disabled) {
-               adapter->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
+               priv->rtsthsd = rthr = MRVDRV_RTS_MAX_VALUE;
        } else {
                if (rthr < MRVDRV_RTS_MIN_VALUE || rthr > MRVDRV_RTS_MAX_VALUE)
                        return -EINVAL;
-               adapter->rtsthsd = rthr;
+               priv->rtsthsd = rthr;
        }
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
                                    CMD_ACT_SET, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_RTS_THRESHOLD, &rthr);
 
@@ -303,23 +314,22 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info,
        return ret;
 }
 
-static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info,
                        struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       adapter->rtsthsd = 0;
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
+       priv->rtsthsd = 0;
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
                                    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_RTS_THRESHOLD, NULL);
        if (ret)
                goto out;
 
-       vwrq->value = adapter->rtsthsd;
+       vwrq->value = priv->rtsthsd;
        vwrq->disabled = ((vwrq->value < MRVDRV_RTS_MIN_VALUE)
                          || (vwrq->value > MRVDRV_RTS_MAX_VALUE));
        vwrq->fixed = 1;
@@ -329,26 +339,25 @@ out:
        return ret;
 }
 
-static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
        u32 fthr = vwrq->value;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        if (vwrq->disabled) {
-               adapter->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
+               priv->fragthsd = fthr = MRVDRV_FRAG_MAX_VALUE;
        } else {
                if (fthr < MRVDRV_FRAG_MIN_VALUE
                    || fthr > MRVDRV_FRAG_MAX_VALUE)
                        return -EINVAL;
-               adapter->fragthsd = fthr;
+               priv->fragthsd = fthr;
        }
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
+       ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
                                    CMD_ACT_SET, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_FRAGMENTATION_THRESHOLD, &fthr);
 
@@ -356,24 +365,23 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info,
        return ret;
 }
 
-static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info,
                         struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       adapter->fragthsd = 0;
-       ret = libertas_prepare_and_send_command(priv,
+       priv->fragthsd = 0;
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_SNMP_MIB,
                                    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_FRAGMENTATION_THRESHOLD, NULL);
        if (ret)
                goto out;
 
-       vwrq->value = adapter->fragthsd;
+       vwrq->value = priv->fragthsd;
        vwrq->disabled = ((vwrq->value < MRVDRV_FRAG_MIN_VALUE)
                          || (vwrq->value > MRVDRV_FRAG_MAX_VALUE));
        vwrq->fixed = 1;
@@ -383,15 +391,14 @@ out:
        return ret;
 }
 
-static int wlan_get_mode(struct net_device *dev,
+static int lbs_get_mode(struct net_device *dev,
                         struct iw_request_info *info, u32 * uwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       *uwrq = adapter->mode;
+       *uwrq = priv->mode;
 
        lbs_deb_leave(LBS_DEB_WEXT);
        return 0;
@@ -409,17 +416,16 @@ static int mesh_wlan_get_mode(struct net_device *dev,
        return 0;
 }
 
-static int wlan_get_txpow(struct net_device *dev,
+static int lbs_get_txpow(struct net_device *dev,
                          struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_RF_TX_POWER,
                                    CMD_ACT_TX_POWER_OPT_GET,
                                    CMD_OPTION_WAITFORRSP, 0, NULL);
@@ -427,10 +433,10 @@ static int wlan_get_txpow(struct net_device *dev,
        if (ret)
                goto out;
 
-       lbs_deb_wext("tx power level %d dbm\n", adapter->txpowerlevel);
-       vwrq->value = adapter->txpowerlevel;
+       lbs_deb_wext("tx power level %d dbm\n", priv->txpowerlevel);
+       vwrq->value = priv->txpowerlevel;
        vwrq->fixed = 1;
-       if (adapter->radioon) {
+       if (priv->radioon) {
                vwrq->disabled = 0;
                vwrq->flags = IW_TXPOW_DBM;
        } else {
@@ -442,12 +448,11 @@ out:
        return ret;
 }
 
-static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -460,9 +465,9 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info,
                        return -EINVAL;
 
                /* Adding 1 to convert retry count to try count */
-               adapter->txretrycount = vwrq->value + 1;
+               priv->txretrycount = vwrq->value + 1;
 
-               ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
+               ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB,
                                            CMD_ACT_SET,
                                            CMD_OPTION_WAITFORRSP,
                                            OID_802_11_TX_RETRYCOUNT, NULL);
@@ -478,17 +483,16 @@ out:
        return ret;
 }
 
-static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int ret = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       adapter->txretrycount = 0;
-       ret = libertas_prepare_and_send_command(priv,
+       priv->txretrycount = 0;
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_SNMP_MIB,
                                    CMD_ACT_GET, CMD_OPTION_WAITFORRSP,
                                    OID_802_11_TX_RETRYCOUNT, NULL);
@@ -499,7 +503,7 @@ static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info,
        if (!vwrq->flags) {
                vwrq->flags = IW_RETRY_LIMIT;
                /* Subtract 1 to convert try count to retry count */
-               vwrq->value = adapter->txretrycount - 1;
+               vwrq->value = priv->txretrycount - 1;
        }
 
 out:
@@ -546,12 +550,11 @@ static inline void sort_channels(struct iw_freq *freq, int num)
  *  @param extra               A pointer to extra data buf
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_range(struct net_device *dev, struct iw_request_info *info,
                          struct iw_point *dwrq, char *extra)
 {
        int i, j;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct iw_range *range = (struct iw_range *)extra;
        struct chan_freq_power *cfp;
        u8 rates[MAX_RATES + 1];
@@ -567,7 +570,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
        range->max_nwid = 0;
 
        memset(rates, 0, sizeof(rates));
-       copy_active_data_rates(adapter, rates);
+       copy_active_data_rates(priv, rates);
        range->num_bitrates = strnlen(rates, IW_MAX_BITRATES);
        for (i = 0; i < range->num_bitrates; i++)
                range->bitrate[i] = rates[i] * 500000;
@@ -576,13 +579,14 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
               range->num_bitrates);
 
        range->num_frequency = 0;
-       if (priv->adapter->enable11d &&
-           adapter->connect_status == LIBERTAS_CONNECTED) {
+       if (priv->enable11d &&
+           (priv->connect_status == LBS_CONNECTED ||
+           priv->mesh_connect_status == LBS_CONNECTED)) {
                u8 chan_no;
                u8 band;
 
                struct parsed_region_chan_11d *parsed_region_chan =
-                   &adapter->parsed_region_chan;
+                   &priv->parsed_region_chan;
 
                if (parsed_region_chan == NULL) {
                        lbs_deb_wext("11d: parsed_region_chan is NULL\n");
@@ -598,7 +602,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
                        lbs_deb_wext("chan_no %d\n", chan_no);
                        range->freq[range->num_frequency].i = (long)chan_no;
                        range->freq[range->num_frequency].m =
-                           (long)libertas_chan_2_freq(chan_no, band) * 100000;
+                           (long)lbs_chan_2_freq(chan_no, band) * 100000;
                        range->freq[range->num_frequency].e = 1;
                        range->num_frequency++;
                }
@@ -606,13 +610,12 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
        }
        if (!flag) {
                for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
-                    && (j < sizeof(adapter->region_channel)
-                        / sizeof(adapter->region_channel[0])); j++) {
-                       cfp = adapter->region_channel[j].CFP;
+                    && (j < ARRAY_SIZE(priv->region_channel)); j++) {
+                       cfp = priv->region_channel[j].CFP;
                        for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES)
-                            && adapter->region_channel[j].valid
+                            && priv->region_channel[j].valid
                             && cfp
-                            && (i < adapter->region_channel[j].nrcfp); i++) {
+                            && (i < priv->region_channel[j].nrcfp); i++) {
                                range->freq[range->num_frequency].i =
                                    (long)cfp->channel;
                                range->freq[range->num_frequency].m =
@@ -712,7 +715,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info,
                                IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
        range->event_capa[1] = IW_EVENT_CAPA_K_1;
 
-       if (adapter->fwcapinfo & FW_CAPINFO_WPA) {
+       if (priv->fwcapinfo & FW_CAPINFO_WPA) {
                range->enc_capa =   IW_ENC_CAPA_WPA
                                  | IW_ENC_CAPA_WPA2
                                  | IW_ENC_CAPA_CIPHER_TKIP
@@ -724,22 +727,28 @@ out:
        return 0;
 }
 
-static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
+       if (!priv->ps_supported) {
+               if (vwrq->disabled)
+                       return 0;
+               else
+                       return -EINVAL;
+       }
+
        /* PS is currently supported only in Infrastructure mode
         * Remove this check if it is to be supported in IBSS mode also
         */
 
        if (vwrq->disabled) {
-               adapter->psmode = WLAN802_11POWERMODECAM;
-               if (adapter->psstate != PS_STATE_FULL_POWER) {
-                       libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
+               priv->psmode = LBS802_11POWERMODECAM;
+               if (priv->psstate != PS_STATE_FULL_POWER) {
+                       lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
                }
 
                return 0;
@@ -754,33 +763,32 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info,
                return -EINVAL;
        }
 
-       if (adapter->psmode != WLAN802_11POWERMODECAM) {
+       if (priv->psmode != LBS802_11POWERMODECAM) {
                return 0;
        }
 
-       adapter->psmode = WLAN802_11POWERMODEMAX_PSP;
+       priv->psmode = LBS802_11POWERMODEMAX_PSP;
 
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
-               libertas_ps_sleep(priv, CMD_OPTION_WAITFORRSP);
+       if (priv->connect_status == LBS_CONNECTED) {
+               lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP);
        }
 
        lbs_deb_leave(LBS_DEB_WEXT);
        return 0;
 }
 
-static int wlan_get_power(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_power(struct net_device *dev, struct iw_request_info *info,
                          struct iw_param *vwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int mode;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mode = adapter->psmode;
+       mode = priv->psmode;
 
-       if ((vwrq->disabled = (mode == WLAN802_11POWERMODECAM))
-           || adapter->connect_status == LIBERTAS_DISCONNECTED)
+       if ((vwrq->disabled = (mode == LBS802_11POWERMODECAM))
+           || priv->connect_status == LBS_DISCONNECTED)
        {
                goto out;
        }
@@ -792,7 +800,7 @@ out:
        return 0;
 }
 
-static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
+static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev)
 {
        enum {
                POOR = 30,
@@ -802,8 +810,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
                EXCELLENT = 95,
                PERFECT = 100
        };
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        u32 rssi_qual;
        u32 tx_qual;
        u32 quality = 0;
@@ -813,22 +820,23 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       priv->wstats.status = adapter->mode;
+       priv->wstats.status = priv->mode;
 
        /* If we're not associated, all quality values are meaningless */
-       if (adapter->connect_status != LIBERTAS_CONNECTED)
+       if ((priv->connect_status != LBS_CONNECTED) &&
+           (priv->mesh_connect_status != LBS_CONNECTED))
                goto out;
 
        /* Quality by RSSI */
        priv->wstats.qual.level =
-           CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
-            adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
+           CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
+            priv->NF[TYPE_BEACON][TYPE_NOAVG]);
 
-       if (adapter->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
+       if (priv->NF[TYPE_BEACON][TYPE_NOAVG] == 0) {
                priv->wstats.qual.noise = MRVDRV_NF_DEFAULT_SCAN_VALUE;
        } else {
                priv->wstats.qual.noise =
-                   CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
+                   CAL_NF(priv->NF[TYPE_BEACON][TYPE_NOAVG]);
        }
 
        lbs_deb_wext("signal level %#x\n", priv->wstats.qual.level);
@@ -852,7 +860,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
        /* Quality by TX errors */
        priv->wstats.discard.retries = priv->stats.tx_errors;
 
-       tx_retries = le32_to_cpu(adapter->logmsg.retry);
+       tx_retries = le32_to_cpu(priv->logmsg.retry);
 
        if (tx_retries > 75)
                tx_qual = (90 - tx_retries) * POOR / 15;
@@ -868,10 +876,10 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
                    (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
        quality = min(quality, tx_qual);
 
-       priv->wstats.discard.code = le32_to_cpu(adapter->logmsg.wepundecryptable);
-       priv->wstats.discard.fragment = le32_to_cpu(adapter->logmsg.rxfrag);
+       priv->wstats.discard.code = le32_to_cpu(priv->logmsg.wepundecryptable);
+       priv->wstats.discard.fragment = le32_to_cpu(priv->logmsg.rxfrag);
        priv->wstats.discard.retries = tx_retries;
-       priv->wstats.discard.misc = le32_to_cpu(adapter->logmsg.ackfailure);
+       priv->wstats.discard.misc = le32_to_cpu(priv->logmsg.ackfailure);
 
        /* Calculate quality */
        priv->wstats.qual.qual = min_t(u8, quality, 100);
@@ -879,9 +887,9 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
        stats_valid = 1;
 
        /* update stats asynchronously for future calls */
-       libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
+       lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
                                        0, 0, NULL);
-       libertas_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0,
+       lbs_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0,
                                        0, 0, NULL);
 out:
        if (!stats_valid) {
@@ -901,19 +909,18 @@ out:
 
 }
 
-static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info,
                  struct iw_freq *fwrq, char *extra)
 {
        int ret = -EINVAL;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct chan_freq_power *cfp;
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
                goto out;
@@ -923,7 +930,7 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
        if (fwrq->e == 1) {
                long f = fwrq->m / 100000;
 
-               cfp = find_cfp_by_band_and_freq(adapter, 0, f);
+               cfp = find_cfp_by_band_and_freq(priv, 0, f);
                if (!cfp) {
                        lbs_deb_wext("invalid freq %ld\n", f);
                        goto out;
@@ -938,7 +945,7 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
                goto out;
        }
 
-       cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m);
+       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
        if (!cfp) {
                goto out;
        }
@@ -949,23 +956,71 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
 out:
        if (ret == 0) {
                set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        } else {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
+       }
+       mutex_unlock(&priv->lock);
+
+       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+       return ret;
+}
+
+static int lbs_mesh_set_freq(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct iw_freq *fwrq, char *extra)
+{
+       struct lbs_private *priv = dev->priv;
+       struct chan_freq_power *cfp;
+       int ret = -EINVAL;
+
+       lbs_deb_enter(LBS_DEB_WEXT);
+
+       /* If setting by frequency, convert to a channel */
+       if (fwrq->e == 1) {
+               long f = fwrq->m / 100000;
+
+               cfp = find_cfp_by_band_and_freq(priv, 0, f);
+               if (!cfp) {
+                       lbs_deb_wext("invalid freq %ld\n", f);
+                       goto out;
+               }
+
+               fwrq->e = 0;
+               fwrq->m = (int) cfp->channel;
+       }
+
+       /* Setting by channel number */
+       if (fwrq->m > 1000 || fwrq->e > 0) {
+               goto out;
+       }
+
+       cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
+       if (!cfp) {
+               goto out;
+       }
+
+       if (fwrq->m != priv->curbssparams.channel) {
+               lbs_deb_wext("mesh channel change forces eth disconnect\n");
+               if (priv->mode == IW_MODE_INFRA)
+                       lbs_send_deauthentication(priv);
+               else if (priv->mode == IW_MODE_ADHOC)
+                       lbs_stop_adhoc_network(priv);
        }
-       mutex_unlock(&adapter->lock);
+       lbs_mesh_config(priv, 1, fwrq->m);
+       lbs_update_channel(priv);
+       ret = 0;
 
+out:
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
 
-static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
-       u32 new_rate;
-       u16 action;
+       struct lbs_private *priv = dev->priv;
+       u8 new_rate = 0;
        int ret = -EINVAL;
        u8 rates[MAX_RATES + 1];
 
@@ -974,15 +1029,14 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
 
        /* Auto rate? */
        if (vwrq->value == -1) {
-               action = CMD_ACT_SET_TX_AUTO;
-               adapter->auto_rate = 1;
-               adapter->cur_rate = 0;
+               priv->auto_rate = 1;
+               priv->cur_rate = 0;
        } else {
                if (vwrq->value % 100000)
                        goto out;
 
                memset(rates, 0, sizeof(rates));
-               copy_active_data_rates(adapter, rates);
+               copy_active_data_rates(priv, rates);
                new_rate = vwrq->value / 500000;
                if (!memchr(rates, new_rate, sizeof(rates))) {
                        lbs_pr_alert("fixed data rate 0x%X out of range\n",
@@ -990,31 +1044,28 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info,
                        goto out;
                }
 
-               adapter->cur_rate = new_rate;
-               action = CMD_ACT_SET_TX_FIX_RATE;
-               adapter->auto_rate = 0;
+               priv->cur_rate = new_rate;
+               priv->auto_rate = 0;
        }
 
-       ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,
-                                   action, CMD_OPTION_WAITFORRSP, 0, NULL);
+       ret = lbs_set_data_rate(priv, new_rate);
 
 out:
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
 
-static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info,
                  struct iw_param *vwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
-               vwrq->value = adapter->cur_rate * 500000;
+       if (priv->connect_status == LBS_CONNECTED) {
+               vwrq->value = priv->cur_rate * 500000;
 
-               if (adapter->auto_rate)
+               if (priv->auto_rate)
                        vwrq->fixed = 0;
                else
                        vwrq->fixed = 1;
@@ -1028,12 +1079,11 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_set_mode(struct net_device *dev,
+static int lbs_set_mode(struct net_device *dev,
                  struct iw_request_info *info, u32 * uwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
@@ -1046,18 +1096,18 @@ static int wlan_set_mode(struct net_device *dev,
                goto out;
        }
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
        } else {
                assoc_req->mode = *uwrq;
                set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
                lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq);
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
 out:
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
@@ -1074,23 +1124,22 @@ out:
  *  @param extra               A pointer to extra data buf
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_get_encode(struct net_device *dev,
+static int lbs_get_encode(struct net_device *dev,
                           struct iw_request_info *info,
                           struct iw_point *dwrq, u8 * extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        lbs_deb_wext("flags 0x%x, index %d, length %d, wep_tx_keyidx %d\n",
-              dwrq->flags, index, dwrq->length, adapter->wep_tx_keyidx);
+              dwrq->flags, index, dwrq->length, priv->wep_tx_keyidx);
 
        dwrq->flags = 0;
 
        /* Authentication method */
-       switch (adapter->secinfo.auth_mode) {
+       switch (priv->secinfo.auth_mode) {
        case IW_AUTH_ALG_OPEN_SYSTEM:
                dwrq->flags = IW_ENCODE_OPEN;
                break;
@@ -1104,41 +1153,32 @@ static int wlan_get_encode(struct net_device *dev,
                break;
        }
 
-       if (   adapter->secinfo.wep_enabled
-           || adapter->secinfo.WPAenabled
-           || adapter->secinfo.WPA2enabled) {
-               dwrq->flags &= ~IW_ENCODE_DISABLED;
-       } else {
-               dwrq->flags |= IW_ENCODE_DISABLED;
-       }
-
        memset(extra, 0, 16);
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
        /* Default to returning current transmit key */
        if (index < 0)
-               index = adapter->wep_tx_keyidx;
+               index = priv->wep_tx_keyidx;
 
-       if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) {
-               memcpy(extra, adapter->wep_keys[index].key,
-                      adapter->wep_keys[index].len);
-               dwrq->length = adapter->wep_keys[index].len;
+       if ((priv->wep_keys[index].len) && priv->secinfo.wep_enabled) {
+               memcpy(extra, priv->wep_keys[index].key,
+                      priv->wep_keys[index].len);
+               dwrq->length = priv->wep_keys[index].len;
 
                dwrq->flags |= (index + 1);
                /* Return WEP enabled */
                dwrq->flags &= ~IW_ENCODE_DISABLED;
-       } else if ((adapter->secinfo.WPAenabled)
-                  || (adapter->secinfo.WPA2enabled)) {
+       } else if ((priv->secinfo.WPAenabled)
+                  || (priv->secinfo.WPA2enabled)) {
                /* return WPA enabled */
                dwrq->flags &= ~IW_ENCODE_DISABLED;
+               dwrq->flags |= IW_ENCODE_NOKEY;
        } else {
                dwrq->flags |= IW_ENCODE_DISABLED;
        }
 
-       mutex_unlock(&adapter->lock);
-
-       dwrq->flags |= IW_ENCODE_NOKEY;
+       mutex_unlock(&priv->lock);
 
        lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n",
               extra[0], extra[1], extra[2],
@@ -1160,7 +1200,7 @@ static int wlan_get_encode(struct net_device *dev,
  *  @param set_tx_key          Force set TX key (1 = yes, 0 = no)
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_set_wep_key(struct assoc_request *assoc_req,
+static int lbs_set_wep_key(struct assoc_request *assoc_req,
                            const char *key_material,
                            u16 key_length,
                            u16 index,
@@ -1278,20 +1318,19 @@ static void disable_wpa(struct assoc_request *assoc_req)
  *  @param extra               A pointer to extra data buf
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_set_encode(struct net_device *dev,
+static int lbs_set_encode(struct net_device *dev,
                    struct iw_request_info *info,
                    struct iw_point *dwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct assoc_request * assoc_req;
        u16 is_default = 0, index = 0, set_tx_key = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
                goto out;
@@ -1317,7 +1356,7 @@ static int wlan_set_encode(struct net_device *dev,
        if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
                set_tx_key = 1;
 
-       ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
+       ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
        if (ret)
                goto out;
 
@@ -1335,11 +1374,11 @@ static int wlan_set_encode(struct net_device *dev,
 out:
        if (ret == 0) {
                set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        } else {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
@@ -1354,14 +1393,13 @@ out:
  *  @param extra               A pointer to extra data buf
  *  @return                    0 on success, otherwise failure
  */
-static int wlan_get_encodeext(struct net_device *dev,
+static int lbs_get_encodeext(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq,
                              char *extra)
 {
        int ret = -EINVAL;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int index, max_key_len;
 
@@ -1377,46 +1415,46 @@ static int wlan_get_encodeext(struct net_device *dev,
                        goto out;
                index--;
        } else {
-               index = adapter->wep_tx_keyidx;
+               index = priv->wep_tx_keyidx;
        }
 
-       if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
+       if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
            ext->alg != IW_ENCODE_ALG_WEP) {
-               if (index != 0 || adapter->mode != IW_MODE_INFRA)
+               if (index != 0 || priv->mode != IW_MODE_INFRA)
                        goto out;
        }
 
        dwrq->flags = index + 1;
        memset(ext, 0, sizeof(*ext));
 
-       if (   !adapter->secinfo.wep_enabled
-           && !adapter->secinfo.WPAenabled
-           && !adapter->secinfo.WPA2enabled) {
+       if (   !priv->secinfo.wep_enabled
+           && !priv->secinfo.WPAenabled
+           && !priv->secinfo.WPA2enabled) {
                ext->alg = IW_ENCODE_ALG_NONE;
                ext->key_len = 0;
                dwrq->flags |= IW_ENCODE_DISABLED;
        } else {
                u8 *key = NULL;
 
-               if (   adapter->secinfo.wep_enabled
-                   && !adapter->secinfo.WPAenabled
-                   && !adapter->secinfo.WPA2enabled) {
+               if (   priv->secinfo.wep_enabled
+                   && !priv->secinfo.WPAenabled
+                   && !priv->secinfo.WPA2enabled) {
                        /* WEP */
                        ext->alg = IW_ENCODE_ALG_WEP;
-                       ext->key_len = adapter->wep_keys[index].len;
-                       key = &adapter->wep_keys[index].key[0];
-               } else if (   !adapter->secinfo.wep_enabled
-                          && (adapter->secinfo.WPAenabled ||
-                              adapter->secinfo.WPA2enabled)) {
+                       ext->key_len = priv->wep_keys[index].len;
+                       key = &priv->wep_keys[index].key[0];
+               } else if (   !priv->secinfo.wep_enabled
+                          && (priv->secinfo.WPAenabled ||
+                              priv->secinfo.WPA2enabled)) {
                        /* WPA */
                        struct enc_key * pkey = NULL;
 
-                       if (   adapter->wpa_mcast_key.len
-                           && (adapter->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
-                               pkey = &adapter->wpa_mcast_key;
-                       else if (   adapter->wpa_unicast_key.len
-                                && (adapter->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
-                               pkey = &adapter->wpa_unicast_key;
+                       if (   priv->wpa_mcast_key.len
+                           && (priv->wpa_mcast_key.flags & KEY_INFO_WPA_ENABLED))
+                               pkey = &priv->wpa_mcast_key;
+                       else if (   priv->wpa_unicast_key.len
+                                && (priv->wpa_unicast_key.flags & KEY_INFO_WPA_ENABLED))
+                               pkey = &priv->wpa_unicast_key;
 
                        if (pkey) {
                                if (pkey->type == KEY_TYPE_ID_AES) {
@@ -1461,22 +1499,21 @@ out:
  *  @param extra               A pointer to extra data buf
  *  @return                    0 --success, otherwise fail
  */
-static int wlan_set_encodeext(struct net_device *dev,
+static int lbs_set_encodeext(struct net_device *dev,
                              struct iw_request_info *info,
                              struct iw_point *dwrq,
                              char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        int alg = ext->alg;
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
                goto out;
@@ -1503,7 +1540,7 @@ static int wlan_set_encodeext(struct net_device *dev,
                        set_tx_key = 1;
 
                /* Copy key to driver */
-               ret = wlan_set_wep_key (assoc_req, ext->key, ext->key_len, index,
+               ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index,
                                        set_tx_key);
                if (ret)
                        goto out;
@@ -1576,31 +1613,30 @@ static int wlan_set_encodeext(struct net_device *dev,
 
 out:
        if (ret == 0) {
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        } else {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
 
 
-static int wlan_set_genie(struct net_device *dev,
+static int lbs_set_genie(struct net_device *dev,
                          struct iw_request_info *info,
                          struct iw_point *dwrq,
                          char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int ret = 0;
        struct assoc_request * assoc_req;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
                goto out;
@@ -1616,46 +1652,45 @@ static int wlan_set_genie(struct net_device *dev,
                memcpy(&assoc_req->wpa_ie[0], extra, dwrq->length);
                assoc_req->wpa_ie_len = dwrq->length;
        } else {
-               memset(&assoc_req->wpa_ie[0], 0, sizeof(adapter->wpa_ie));
+               memset(&assoc_req->wpa_ie[0], 0, sizeof(priv->wpa_ie));
                assoc_req->wpa_ie_len = 0;
        }
 
 out:
        if (ret == 0) {
                set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        } else {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
 
-static int wlan_get_genie(struct net_device *dev,
+static int lbs_get_genie(struct net_device *dev,
                          struct iw_request_info *info,
                          struct iw_point *dwrq,
                          char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       if (adapter->wpa_ie_len == 0) {
+       if (priv->wpa_ie_len == 0) {
                dwrq->length = 0;
                goto out;
        }
 
-       if (dwrq->length < adapter->wpa_ie_len) {
+       if (dwrq->length < priv->wpa_ie_len) {
                ret = -E2BIG;
                goto out;
        }
 
-       dwrq->length = adapter->wpa_ie_len;
-       memcpy(extra, &adapter->wpa_ie[0], adapter->wpa_ie_len);
+       dwrq->length = priv->wpa_ie_len;
+       memcpy(extra, &priv->wpa_ie[0], priv->wpa_ie_len);
 
 out:
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
@@ -1663,21 +1698,20 @@ out:
 }
 
 
-static int wlan_set_auth(struct net_device *dev,
+static int lbs_set_auth(struct net_device *dev,
                         struct iw_request_info *info,
                         struct iw_param *dwrq,
                         char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct assoc_request * assoc_req;
        int ret = 0;
        int updated = 0;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
-       mutex_lock(&adapter->lock);
-       assoc_req = wlan_get_association_request(adapter);
+       mutex_lock(&priv->lock);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
                ret = -ENOMEM;
                goto out;
@@ -1752,44 +1786,43 @@ out:
        if (ret == 0) {
                if (updated)
                        set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        } else if (ret != -EOPNOTSUPP) {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
        }
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
 
-static int wlan_get_auth(struct net_device *dev,
+static int lbs_get_auth(struct net_device *dev,
                         struct iw_request_info *info,
                         struct iw_param *dwrq,
                         char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        switch (dwrq->flags & IW_AUTH_INDEX) {
        case IW_AUTH_WPA_VERSION:
                dwrq->value = 0;
-               if (adapter->secinfo.WPAenabled)
+               if (priv->secinfo.WPAenabled)
                        dwrq->value |= IW_AUTH_WPA_VERSION_WPA;
-               if (adapter->secinfo.WPA2enabled)
+               if (priv->secinfo.WPA2enabled)
                        dwrq->value |= IW_AUTH_WPA_VERSION_WPA2;
                if (!dwrq->value)
                        dwrq->value |= IW_AUTH_WPA_VERSION_DISABLED;
                break;
 
        case IW_AUTH_80211_AUTH_ALG:
-               dwrq->value = adapter->secinfo.auth_mode;
+               dwrq->value = priv->secinfo.auth_mode;
                break;
 
        case IW_AUTH_WPA_ENABLED:
-               if (adapter->secinfo.WPAenabled && adapter->secinfo.WPA2enabled)
+               if (priv->secinfo.WPAenabled && priv->secinfo.WPA2enabled)
                        dwrq->value = 1;
                break;
 
@@ -1802,25 +1835,24 @@ static int wlan_get_auth(struct net_device *dev,
 }
 
 
-static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info,
                   struct iw_param *vwrq, char *extra)
 {
        int ret = 0;
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        u16 dbm;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
        if (vwrq->disabled) {
-               wlan_radio_ioctl(priv, RADIO_OFF);
+               lbs_radio_ioctl(priv, RADIO_OFF);
                return 0;
        }
 
-       adapter->preamble = CMD_TYPE_AUTO_PREAMBLE;
+       priv->preamble = CMD_TYPE_AUTO_PREAMBLE;
 
-       wlan_radio_ioctl(priv, RADIO_ON);
+       lbs_radio_ioctl(priv, RADIO_ON);
 
        /* Userspace check in iwrange if it should use dBm or mW,
         * therefore this should never happen... Jean II */
@@ -1836,7 +1868,7 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
 
        lbs_deb_wext("txpower set %d dbm\n", dbm);
 
-       ret = libertas_prepare_and_send_command(priv,
+       ret = lbs_prepare_and_send_command(priv,
                                    CMD_802_11_RF_TX_POWER,
                                    CMD_ACT_TX_POWER_OPT_SET_LOW,
                                    CMD_OPTION_WAITFORRSP, 0, (void *)&dbm);
@@ -1845,11 +1877,10 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info,
        return ret;
 }
 
-static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
+static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
 
        lbs_deb_enter(LBS_DEB_WEXT);
 
@@ -1861,19 +1892,19 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
        /*
         * Get the current SSID
         */
-       if (adapter->connect_status == LIBERTAS_CONNECTED) {
-               memcpy(extra, adapter->curbssparams.ssid,
-                      adapter->curbssparams.ssid_len);
-               extra[adapter->curbssparams.ssid_len] = '\0';
+       if (priv->connect_status == LBS_CONNECTED) {
+               memcpy(extra, priv->curbssparams.ssid,
+                      priv->curbssparams.ssid_len);
+               extra[priv->curbssparams.ssid_len] = '\0';
        } else {
                memset(extra, 0, 32);
-               extra[adapter->curbssparams.ssid_len] = '\0';
+               extra[priv->curbssparams.ssid_len] = '\0';
        }
        /*
         * If none, we may want to get the one that was set
         */
 
-       dwrq->length = adapter->curbssparams.ssid_len;
+       dwrq->length = priv->curbssparams.ssid_len;
 
        dwrq->flags = 1;        /* active */
 
@@ -1881,11 +1912,10 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info,
        return 0;
 }
 
-static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info,
                   struct iw_point *dwrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        int ret = 0;
        u8 ssid[IW_ESSID_MAX_SIZE];
        u8 ssid_len = 0;
@@ -1918,10 +1948,10 @@ static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info,
        }
 
 out:
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
        if (ret == 0) {
                /* Get or create the current association request */
-               assoc_req = wlan_get_association_request(adapter);
+               assoc_req = lbs_get_association_request(priv);
                if (!assoc_req) {
                        ret = -ENOMEM;
                } else {
@@ -1929,17 +1959,65 @@ out:
                        memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE);
                        assoc_req->ssid_len = ssid_len;
                        set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
-                       wlan_postpone_association_work(priv);
+                       lbs_postpone_association_work(priv);
                }
        }
 
        /* Cancel the association request if there was an error */
        if (ret != 0) {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
+       }
+
+       mutex_unlock(&priv->lock);
+
+       lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+       return ret;
+}
+
+static int lbs_mesh_get_essid(struct net_device *dev,
+                             struct iw_request_info *info,
+                             struct iw_point *dwrq, char *extra)
+{
+       struct lbs_private *priv = dev->priv;
+
+       lbs_deb_enter(LBS_DEB_WEXT);
+
+       memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
+
+       dwrq->length = priv->mesh_ssid_len;
+
+       dwrq->flags = 1;        /* active */
+
+       lbs_deb_leave(LBS_DEB_WEXT);
+       return 0;
+}
+
+static int lbs_mesh_set_essid(struct net_device *dev,
+                             struct iw_request_info *info,
+                             struct iw_point *dwrq, char *extra)
+{
+       struct lbs_private *priv = dev->priv;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_WEXT);
+
+       /* Check the size of the string */
+       if (dwrq->length > IW_ESSID_MAX_SIZE) {
+               ret = -E2BIG;
+               goto out;
        }
 
-       mutex_unlock(&adapter->lock);
+       if (!dwrq->flags || !dwrq->length) {
+               ret = -EINVAL;
+               goto out;
+       } else {
+               /* Specific SSID requested */
+               memcpy(priv->mesh_ssid, extra, dwrq->length);
+               priv->mesh_ssid_len = dwrq->length;
+       }
 
+       lbs_mesh_config(priv, 1, priv->curbssparams.channel);
+ out:
        lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
        return ret;
 }
@@ -1953,11 +2031,10 @@ out:
  *  @param extra        A pointer to extra data buf
  *  @return             0 --success, otherwise fail
  */
-static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
+static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info,
                 struct sockaddr *awrq, char *extra)
 {
-       wlan_private *priv = dev->priv;
-       wlan_adapter *adapter = priv->adapter;
+       struct lbs_private *priv = dev->priv;
        struct assoc_request * assoc_req;
        int ret = 0;
        DECLARE_MAC_BUF(mac);
@@ -1969,44 +2046,38 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info,
 
        lbs_deb_wext("ASSOC: WAP: sa_data %s\n", print_mac(mac, awrq->sa_data));
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
        /* Get or create the current association request */
-       assoc_req = wlan_get_association_request(adapter);
+       assoc_req = lbs_get_association_request(priv);
        if (!assoc_req) {
-               wlan_cancel_association_work(priv);
+               lbs_cancel_association_work(priv);
                ret = -ENOMEM;
        } else {
                /* Copy the BSSID to the association request */
                memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN);
                set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags);
-               wlan_postpone_association_work(priv);
+               lbs_postpone_association_work(priv);
        }
 
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
 
        return ret;
 }
 
-void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
+void lbs_get_fwversion(struct lbs_private *priv, char *fwversion, int maxlen)
 {
        char fwver[32];
 
-       mutex_lock(&adapter->lock);
+       mutex_lock(&priv->lock);
 
-       if (adapter->fwreleasenumber[3] == 0)
-               sprintf(fwver, "%u.%u.%u",
-                       adapter->fwreleasenumber[2],
-                       adapter->fwreleasenumber[1],
-                       adapter->fwreleasenumber[0]);
-       else
-               sprintf(fwver, "%u.%u.%u.p%u",
-                       adapter->fwreleasenumber[2],
-                       adapter->fwreleasenumber[1],
-                       adapter->fwreleasenumber[0],
-                       adapter->fwreleasenumber[3]);
+       sprintf(fwver, "%u.%u.%u.p%u",
+               priv->fwrelease >> 24 & 0xff,
+               priv->fwrelease >> 16 & 0xff,
+               priv->fwrelease >>  8 & 0xff,
+               priv->fwrelease       & 0xff);
 
-       mutex_unlock(&adapter->lock);
+       mutex_unlock(&priv->lock);
        snprintf(fwversion, maxlen, fwver);
 }
 
@@ -2014,19 +2085,19 @@ void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen)
 /*
  * iwconfig settable callbacks
  */
-static const iw_handler wlan_handler[] = {
+static const iw_handler lbs_handler[] = {
        (iw_handler) NULL,      /* SIOCSIWCOMMIT */
-       (iw_handler) wlan_get_name,     /* SIOCGIWNAME */
+       (iw_handler) lbs_get_name,      /* SIOCGIWNAME */
        (iw_handler) NULL,      /* SIOCSIWNWID */
        (iw_handler) NULL,      /* SIOCGIWNWID */
-       (iw_handler) wlan_set_freq,     /* SIOCSIWFREQ */
-       (iw_handler) wlan_get_freq,     /* SIOCGIWFREQ */
-       (iw_handler) wlan_set_mode,     /* SIOCSIWMODE */
-       (iw_handler) wlan_get_mode,     /* SIOCGIWMODE */
+       (iw_handler) lbs_set_freq,      /* SIOCSIWFREQ */
+       (iw_handler) lbs_get_freq,      /* SIOCGIWFREQ */
+       (iw_handler) lbs_set_mode,      /* SIOCSIWMODE */
+       (iw_handler) lbs_get_mode,      /* SIOCGIWMODE */
        (iw_handler) NULL,      /* SIOCSIWSENS */
        (iw_handler) NULL,      /* SIOCGIWSENS */
        (iw_handler) NULL,      /* SIOCSIWRANGE */
-       (iw_handler) wlan_get_range,    /* SIOCGIWRANGE */
+       (iw_handler) lbs_get_range,     /* SIOCGIWRANGE */
        (iw_handler) NULL,      /* SIOCSIWPRIV */
        (iw_handler) NULL,      /* SIOCGIWPRIV */
        (iw_handler) NULL,      /* SIOCSIWSTATS */
@@ -2035,56 +2106,56 @@ static const iw_handler wlan_handler[] = {
        iw_handler_get_spy,     /* SIOCGIWSPY */
        iw_handler_set_thrspy,  /* SIOCSIWTHRSPY */
        iw_handler_get_thrspy,  /* SIOCGIWTHRSPY */
-       (iw_handler) wlan_set_wap,      /* SIOCSIWAP */
-       (iw_handler) wlan_get_wap,      /* SIOCGIWAP */
+       (iw_handler) lbs_set_wap,       /* SIOCSIWAP */
+       (iw_handler) lbs_get_wap,       /* SIOCGIWAP */
        (iw_handler) NULL,      /* SIOCSIWMLME */
        (iw_handler) NULL,      /* SIOCGIWAPLIST - deprecated */
-       (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
-       (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
-       (iw_handler) wlan_set_essid,    /* SIOCSIWESSID */
-       (iw_handler) wlan_get_essid,    /* SIOCGIWESSID */
-       (iw_handler) wlan_set_nick,     /* SIOCSIWNICKN */
-       (iw_handler) wlan_get_nick,     /* SIOCGIWNICKN */
+       (iw_handler) lbs_set_scan,      /* SIOCSIWSCAN */
+       (iw_handler) lbs_get_scan,      /* SIOCGIWSCAN */
+       (iw_handler) lbs_set_essid,     /* SIOCSIWESSID */
+       (iw_handler) lbs_get_essid,     /* SIOCGIWESSID */
+       (iw_handler) lbs_set_nick,      /* SIOCSIWNICKN */
+       (iw_handler) lbs_get_nick,      /* SIOCGIWNICKN */
        (iw_handler) NULL,      /* -- hole -- */
        (iw_handler) NULL,      /* -- hole -- */
-       (iw_handler) wlan_set_rate,     /* SIOCSIWRATE */
-       (iw_handler) wlan_get_rate,     /* SIOCGIWRATE */
-       (iw_handler) wlan_set_rts,      /* SIOCSIWRTS */
-       (iw_handler) wlan_get_rts,      /* SIOCGIWRTS */
-       (iw_handler) wlan_set_frag,     /* SIOCSIWFRAG */
-       (iw_handler) wlan_get_frag,     /* SIOCGIWFRAG */
-       (iw_handler) wlan_set_txpow,    /* SIOCSIWTXPOW */
-       (iw_handler) wlan_get_txpow,    /* SIOCGIWTXPOW */
-       (iw_handler) wlan_set_retry,    /* SIOCSIWRETRY */
-       (iw_handler) wlan_get_retry,    /* SIOCGIWRETRY */
-       (iw_handler) wlan_set_encode,   /* SIOCSIWENCODE */
-       (iw_handler) wlan_get_encode,   /* SIOCGIWENCODE */
-       (iw_handler) wlan_set_power,    /* SIOCSIWPOWER */
-       (iw_handler) wlan_get_power,    /* SIOCGIWPOWER */
+       (iw_handler) lbs_set_rate,      /* SIOCSIWRATE */
+       (iw_handler) lbs_get_rate,      /* SIOCGIWRATE */
+       (iw_handler) lbs_set_rts,       /* SIOCSIWRTS */
+       (iw_handler) lbs_get_rts,       /* SIOCGIWRTS */
+       (iw_handler) lbs_set_frag,      /* SIOCSIWFRAG */
+       (iw_handler) lbs_get_frag,      /* SIOCGIWFRAG */
+       (iw_handler) lbs_set_txpow,     /* SIOCSIWTXPOW */
+       (iw_handler) lbs_get_txpow,     /* SIOCGIWTXPOW */
+       (iw_handler) lbs_set_retry,     /* SIOCSIWRETRY */
+       (iw_handler) lbs_get_retry,     /* SIOCGIWRETRY */
+       (iw_handler) lbs_set_encode,    /* SIOCSIWENCODE */
+       (iw_handler) lbs_get_encode,    /* SIOCGIWENCODE */
+       (iw_handler) lbs_set_power,     /* SIOCSIWPOWER */
+       (iw_handler) lbs_get_power,     /* SIOCGIWPOWER */
        (iw_handler) NULL,      /* -- hole -- */
        (iw_handler) NULL,      /* -- hole -- */
-       (iw_handler) wlan_set_genie,    /* SIOCSIWGENIE */
-       (iw_handler) wlan_get_genie,    /* SIOCGIWGENIE */
-       (iw_handler) wlan_set_auth,     /* SIOCSIWAUTH */
-       (iw_handler) wlan_get_auth,     /* SIOCGIWAUTH */
-       (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
-       (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
+       (iw_handler) lbs_set_genie,     /* SIOCSIWGENIE */
+       (iw_handler) lbs_get_genie,     /* SIOCGIWGENIE */
+       (iw_handler) lbs_set_auth,      /* SIOCSIWAUTH */
+       (iw_handler) lbs_get_auth,      /* SIOCGIWAUTH */
+       (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
+       (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
        (iw_handler) NULL,              /* SIOCSIWPMKSA */
 };
 
 static const iw_handler mesh_wlan_handler[] = {
        (iw_handler) NULL,      /* SIOCSIWCOMMIT */
-       (iw_handler) wlan_get_name,     /* SIOCGIWNAME */
+       (iw_handler) lbs_get_name,      /* SIOCGIWNAME */
        (iw_handler) NULL,      /* SIOCSIWNWID */
        (iw_handler) NULL,      /* SIOCGIWNWID */
-       (iw_handler) wlan_set_freq,     /* SIOCSIWFREQ */
-       (iw_handler) wlan_get_freq,     /* SIOCGIWFREQ */
+       (iw_handler) lbs_mesh_set_freq, /* SIOCSIWFREQ */
+       (iw_handler) lbs_get_freq,      /* SIOCGIWFREQ */
        (iw_handler) NULL,              /* SIOCSIWMODE */
        (iw_handler) mesh_wlan_get_mode,        /* SIOCGIWMODE */
        (iw_handler) NULL,      /* SIOCSIWSENS */
        (iw_handler) NULL,      /* SIOCGIWSENS */
        (iw_handler) NULL,      /* SIOCSIWRANGE */
-       (iw_handler) wlan_get_range,    /* SIOCGIWRANGE */
+       (iw_handler) lbs_get_range,     /* SIOCGIWRANGE */
        (iw_handler) NULL,      /* SIOCSIWPRIV */
        (iw_handler) NULL,      /* SIOCGIWPRIV */
        (iw_handler) NULL,      /* SIOCSIWSTATS */
@@ -2097,46 +2168,46 @@ static const iw_handler mesh_wlan_handler[] = {
        (iw_handler) NULL,      /* SIOCGIWAP */
        (iw_handler) NULL,      /* SIOCSIWMLME */
        (iw_handler) NULL,      /* SIOCGIWAPLIST - deprecated */
-       (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */
-       (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */
-       (iw_handler) NULL,              /* SIOCSIWESSID */
-       (iw_handler) NULL,              /* SIOCGIWESSID */
+       (iw_handler) lbs_set_scan,      /* SIOCSIWSCAN */
+       (iw_handler) lbs_get_scan,      /* SIOCGIWSCAN */
+       (iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
+       (iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
        (iw_handler) NULL,              /* SIOCSIWNICKN */
        (iw_handler) mesh_get_nick,     /* SIOCGIWNICKN */
        (iw_handler) NULL,      /* -- hole -- */
        (iw_handler) NULL,      /* -- hole -- */
-       (iw_handler) wlan_set_rate,     /* SIOCSIWRATE */
-       (iw_handler) wlan_get_rate,     /* SIOCGIWRATE */
-       (iw_handler) wlan_set_rts,      /* SIOCSIWRTS */
-       (iw_handler) wlan_get_rts,      /* SIOCGIWRTS */
-       (iw_handler) wlan_set_frag,     /* SIOCSIWFRAG */
-       (iw_handler) wlan_get_frag,     /* SIOCGIWFRAG */
-       (iw_handler) wlan_set_txpow,    /* SIOCSIWTXPOW */
-       (iw_handler) wlan_get_txpow,    /* SIOCGIWTXPOW */
-       (iw_handler) wlan_set_retry,    /* SIOCSIWRETRY */
-       (iw_handler) wlan_get_retry,    /* SIOCGIWRETRY */
-       (iw_handler) wlan_set_encode,   /* SIOCSIWENCODE */
-       (iw_handler) wlan_get_encode,   /* SIOCGIWENCODE */
-       (iw_handler) wlan_set_power,    /* SIOCSIWPOWER */
-       (iw_handler) wlan_get_power,    /* SIOCGIWPOWER */
+       (iw_handler) lbs_set_rate,      /* SIOCSIWRATE */
+       (iw_handler) lbs_get_rate,      /* SIOCGIWRATE */
+       (iw_handler) lbs_set_rts,       /* SIOCSIWRTS */
+       (iw_handler) lbs_get_rts,       /* SIOCGIWRTS */
+       (iw_handler) lbs_set_frag,      /* SIOCSIWFRAG */
+       (iw_handler) lbs_get_frag,      /* SIOCGIWFRAG */
+       (iw_handler) lbs_set_txpow,     /* SIOCSIWTXPOW */
+       (iw_handler) lbs_get_txpow,     /* SIOCGIWTXPOW */
+       (iw_handler) lbs_set_retry,     /* SIOCSIWRETRY */
+       (iw_handler) lbs_get_retry,     /* SIOCGIWRETRY */
+       (iw_handler) lbs_set_encode,    /* SIOCSIWENCODE */
+       (iw_handler) lbs_get_encode,    /* SIOCGIWENCODE */
+       (iw_handler) lbs_set_power,     /* SIOCSIWPOWER */
+       (iw_handler) lbs_get_power,     /* SIOCGIWPOWER */
        (iw_handler) NULL,      /* -- hole -- */
        (iw_handler) NULL,      /* -- hole -- */
-       (iw_handler) wlan_set_genie,    /* SIOCSIWGENIE */
-       (iw_handler) wlan_get_genie,    /* SIOCGIWGENIE */
-       (iw_handler) wlan_set_auth,     /* SIOCSIWAUTH */
-       (iw_handler) wlan_get_auth,     /* SIOCGIWAUTH */
-       (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */
-       (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */
+       (iw_handler) lbs_set_genie,     /* SIOCSIWGENIE */
+       (iw_handler) lbs_get_genie,     /* SIOCGIWGENIE */
+       (iw_handler) lbs_set_auth,      /* SIOCSIWAUTH */
+       (iw_handler) lbs_get_auth,      /* SIOCGIWAUTH */
+       (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */
+       (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */
        (iw_handler) NULL,              /* SIOCSIWPMKSA */
 };
-struct iw_handler_def libertas_handler_def = {
-       .num_standard   = ARRAY_SIZE(wlan_handler),
-       .standard       = (iw_handler *) wlan_handler,
-       .get_wireless_stats = wlan_get_wireless_stats,
+struct iw_handler_def lbs_handler_def = {
+       .num_standard   = ARRAY_SIZE(lbs_handler),
+       .standard       = (iw_handler *) lbs_handler,
+       .get_wireless_stats = lbs_get_wireless_stats,
 };
 
 struct iw_handler_def mesh_handler_def = {
        .num_standard   = ARRAY_SIZE(mesh_wlan_handler),
        .standard       = (iw_handler *) mesh_wlan_handler,
-       .get_wireless_stats = wlan_get_wireless_stats,
+       .get_wireless_stats = lbs_get_wireless_stats,
 };
index 6aa444c7de8d6d43fc144ee5beb4397beca880b4..a563d9a231b6d3e113f0bd7f30f6aa0ef43b8567 100644 (file)
@@ -1,11 +1,11 @@
 /**
   * This file contains definition for IOCTL call.
   */
-#ifndef        _WLAN_WEXT_H_
-#define        _WLAN_WEXT_H_
+#ifndef        _LBS_WEXT_H_
+#define        _LBS_WEXT_H_
 
-/** wlan_ioctl_regrdwr */
-struct wlan_ioctl_regrdwr {
+/** lbs_ioctl_regrdwr */
+struct lbs_ioctl_regrdwr {
        /** Which register to access */
        u16 whichreg;
        /** Read or Write */
@@ -15,9 +15,9 @@ struct wlan_ioctl_regrdwr {
        u32 value;
 };
 
-#define WLAN_MONITOR_OFF                       0
+#define LBS_MONITOR_OFF                        0
 
-extern struct iw_handler_def libertas_handler_def;
+extern struct iw_handler_def lbs_handler_def;
 extern struct iw_handler_def mesh_handler_def;
 
-#endif                         /* _WLAN_WEXT_H_ */
+#endif
index ca6c2da7bc5d3acc727e9037c59e75174752b253..6d13a0d15a0cba9818b21852e89da8dc0a0c22cf 100644 (file)
@@ -270,6 +270,37 @@ static inline void set_port_type(struct orinoco_private *priv)
        }
 }
 
+#define ORINOCO_MAX_BSS_COUNT  64
+static int orinoco_bss_data_allocate(struct orinoco_private *priv)
+{
+       if (priv->bss_data)
+               return 0;
+
+       priv->bss_data =
+           kzalloc(ORINOCO_MAX_BSS_COUNT * sizeof(bss_element), GFP_KERNEL);
+       if (!priv->bss_data) {
+               printk(KERN_WARNING "Out of memory allocating beacons");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+static void orinoco_bss_data_free(struct orinoco_private *priv)
+{
+       kfree(priv->bss_data);
+       priv->bss_data = NULL;
+}
+
+static void orinoco_bss_data_init(struct orinoco_private *priv)
+{
+       int i;
+
+       INIT_LIST_HEAD(&priv->bss_free_list);
+       INIT_LIST_HEAD(&priv->bss_list);
+       for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++)
+               list_add_tail(&priv->bss_data[i].list, &priv->bss_free_list);
+}
+
 /********************************************************************/
 /* Device methods                                                   */
 /********************************************************************/
@@ -1083,6 +1114,124 @@ static void orinoco_send_wevents(struct work_struct *work)
        orinoco_unlock(priv, &flags);
 }
 
+
+static inline void orinoco_clear_scan_results(struct orinoco_private *priv,
+                                             unsigned long scan_age)
+{
+       bss_element *bss;
+       bss_element *tmp_bss;
+
+       /* Blow away current list of scan results */
+       list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) {
+               if (!scan_age ||
+                   time_after(jiffies, bss->last_scanned + scan_age)) {
+                       list_move_tail(&bss->list, &priv->bss_free_list);
+                       /* Don't blow away ->list, just BSS data */
+                       memset(bss, 0, sizeof(bss->bss));
+                       bss->last_scanned = 0;
+               }
+       }
+}
+
+static int orinoco_process_scan_results(struct net_device *dev,
+                                       unsigned char *buf,
+                                       int len)
+{
+       struct orinoco_private *priv = netdev_priv(dev);
+       int                     offset;         /* In the scan data */
+       union hermes_scan_info *atom;
+       int                     atom_len;
+
+       switch (priv->firmware_type) {
+       case FIRMWARE_TYPE_AGERE:
+               atom_len = sizeof(struct agere_scan_apinfo);
+               offset = 0;
+               break;
+       case FIRMWARE_TYPE_SYMBOL:
+               /* Lack of documentation necessitates this hack.
+                * Different firmwares have 68 or 76 byte long atoms.
+                * We try modulo first.  If the length divides by both,
+                * we check what would be the channel in the second
+                * frame for a 68-byte atom.  76-byte atoms have 0 there.
+                * Valid channel cannot be 0.  */
+               if (len % 76)
+                       atom_len = 68;
+               else if (len % 68)
+                       atom_len = 76;
+               else if (len >= 1292 && buf[68] == 0)
+                       atom_len = 76;
+               else
+                       atom_len = 68;
+               offset = 0;
+               break;
+       case FIRMWARE_TYPE_INTERSIL:
+               offset = 4;
+               if (priv->has_hostscan) {
+                       atom_len = le16_to_cpup((__le16 *)buf);
+                       /* Sanity check for atom_len */
+                       if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+                               printk(KERN_ERR "%s: Invalid atom_len in scan "
+                                      "data: %d\n", dev->name, atom_len);
+                               return -EIO;
+                       }
+               } else
+                       atom_len = offsetof(struct prism2_scan_apinfo, atim);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       /* Check that we got an whole number of atoms */
+       if ((len - offset) % atom_len) {
+               printk(KERN_ERR "%s: Unexpected scan data length %d, "
+                      "atom_len %d, offset %d\n", dev->name, len,
+                      atom_len, offset);
+               return -EIO;
+       }
+
+       orinoco_clear_scan_results(priv, msecs_to_jiffies(15000));
+
+       /* Read the entries one by one */
+       for (; offset + atom_len <= len; offset += atom_len) {
+               int found = 0;
+               bss_element *bss = NULL;
+
+               /* Get next atom */
+               atom = (union hermes_scan_info *) (buf + offset);
+
+               /* Try to update an existing bss first */
+               list_for_each_entry(bss, &priv->bss_list, list) {
+                       if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid))
+                               continue;
+                       if (le16_to_cpu(bss->bss.a.essid_len) !=
+                             le16_to_cpu(atom->a.essid_len))
+                               continue;
+                       if (memcmp(bss->bss.a.essid, atom->a.essid,
+                             le16_to_cpu(atom->a.essid_len)))
+                               continue;
+                       found = 1;
+                       break;
+               }
+
+               /* Grab a bss off the free list */
+               if (!found && !list_empty(&priv->bss_free_list)) {
+                       bss = list_entry(priv->bss_free_list.next,
+                                        bss_element, list);
+                       list_del(priv->bss_free_list.next);
+
+                       list_add_tail(&bss->list, &priv->bss_list);
+               }
+
+               if (bss) {
+                       /* Always update the BSS to get latest beacon info */
+                       memcpy(&bss->bss, atom, sizeof(bss->bss));
+                       bss->last_scanned = jiffies;
+               }
+       }
+
+       return 0;
+}
+
 static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
 {
        struct orinoco_private *priv = netdev_priv(dev);
@@ -1208,6 +1357,9 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
                union iwreq_data        wrqu;
                unsigned char *buf;
 
+               /* Scan is no longer in progress */
+               priv->scan_inprogress = 0;
+
                /* Sanity check */
                if (len > 4096) {
                        printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n",
@@ -1215,15 +1367,6 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
                        break;
                }
 
-               /* We are a strict producer. If the previous scan results
-                * have not been consumed, we just have to drop this
-                * frame. We can't remove the previous results ourselves,
-                * that would be *very* racy... Jean II */
-               if (priv->scan_result != NULL) {
-                       printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name);
-                       break;
-               }
-
                /* Allocate buffer for results */
                buf = kmalloc(len, GFP_ATOMIC);
                if (buf == NULL)
@@ -1248,18 +1391,17 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
                }
 #endif /* ORINOCO_DEBUG */
 
-               /* Allow the clients to access the results */
-               priv->scan_len = len;
-               priv->scan_result = buf;
-
-               /* Send an empty event to user space.
-                * We don't send the received data on the event because
-                * it would require us to do complex transcoding, and
-                * we want to minimise the work done in the irq handler
-                * Use a request to extract the data - Jean II */
-               wrqu.data.length = 0;
-               wrqu.data.flags = 0;
-               wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+               if (orinoco_process_scan_results(dev, buf, len) == 0) {
+                       /* Send an empty event to user space.
+                        * We don't send the received data on the event because
+                        * it would require us to do complex transcoding, and
+                        * we want to minimise the work done in the irq handler
+                        * Use a request to extract the data - Jean II */
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+               }
+               kfree(buf);
        }
        break;
        case HERMES_INQ_SEC_STAT_AGERE:
@@ -1896,8 +2038,7 @@ static void orinoco_reset(struct work_struct *work)
        orinoco_unlock(priv, &flags);
 
        /* Scanning support: Cleanup of driver struct */
-       kfree(priv->scan_result);
-       priv->scan_result = NULL;
+       orinoco_clear_scan_results(priv, 0);
        priv->scan_inprogress = 0;
 
        if (priv->hard_reset) {
@@ -2412,6 +2553,10 @@ struct net_device *alloc_orinocodev(int sizeof_card,
        else
                priv->card = NULL;
 
+       if (orinoco_bss_data_allocate(priv))
+               goto err_out_free;
+       orinoco_bss_data_init(priv);
+
        /* Setup / override net_device fields */
        dev->init = orinoco_init;
        dev->hard_start_xmit = orinoco_xmit;
@@ -2447,13 +2592,16 @@ struct net_device *alloc_orinocodev(int sizeof_card,
 
        return dev;
 
+err_out_free:
+       free_netdev(dev);
+       return NULL;
 }
 
 void free_orinocodev(struct net_device *dev)
 {
        struct orinoco_private *priv = netdev_priv(dev);
 
-       kfree(priv->scan_result);
+       orinoco_bss_data_free(priv);
        free_netdev(dev);
 }
 
@@ -3841,23 +3989,10 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
         * we access scan variables in priv is critical.
         *      o scan_inprogress : not touched by irq handler
         *      o scan_mode : not touched by irq handler
-        *      o scan_result : irq is strict producer, non-irq is strict
-        *              consumer.
         *      o scan_len : synchronised with scan_result
         * Before modifying anything on those variables, please think hard !
         * Jean II */
 
-       /* If there is still some left-over scan results, get rid of it */
-       if (priv->scan_result != NULL) {
-               /* What's likely is that a client did crash or was killed
-                * between triggering the scan request and reading the
-                * results, so we need to reset everything.
-                * Some clients that are too slow may suffer from that...
-                * Jean II */
-               kfree(priv->scan_result);
-               priv->scan_result = NULL;
-       }
-
        /* Save flags */
        priv->scan_mode = srq->flags;
 
@@ -3905,169 +4040,125 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
        return err;
 }
 
+#define MAX_CUSTOM_LEN 64
+
 /* Translate scan data returned from the card to a card independant
  * format that the Wireless Tools will understand - Jean II
  * Return message length or -errno for fatal errors */
-static inline int orinoco_translate_scan(struct net_device *dev,
-                                        char *buffer,
-                                        char *scan,
-                                        int scan_len)
+static inline char *orinoco_translate_scan(struct net_device *dev,
+                                          char *current_ev,
+                                          char *end_buf,
+                                          union hermes_scan_info *bss,
+                                          unsigned int last_scanned)
 {
        struct orinoco_private *priv = netdev_priv(dev);
-       int                     offset;         /* In the scan data */
-       union hermes_scan_info *atom;
-       int                     atom_len;
        u16                     capabilities;
        u16                     channel;
        struct iw_event         iwe;            /* Temporary buffer */
-       char *                  current_ev = buffer;
-       char *                  end_buf = buffer + IW_SCAN_MAX_DATA;
-
-       switch (priv->firmware_type) {
-       case FIRMWARE_TYPE_AGERE:
-               atom_len = sizeof(struct agere_scan_apinfo);
-               offset = 0;
-               break;
-       case FIRMWARE_TYPE_SYMBOL:
-               /* Lack of documentation necessitates this hack.
-                * Different firmwares have 68 or 76 byte long atoms.
-                * We try modulo first.  If the length divides by both,
-                * we check what would be the channel in the second
-                * frame for a 68-byte atom.  76-byte atoms have 0 there.
-                * Valid channel cannot be 0.  */
-               if (scan_len % 76)
-                       atom_len = 68;
-               else if (scan_len % 68)
-                       atom_len = 76;
-               else if (scan_len >= 1292 && scan[68] == 0)
-                       atom_len = 76;
+       char                   *p;
+       char custom[MAX_CUSTOM_LEN];
+
+       /* First entry *MUST* be the AP MAC address */
+       iwe.cmd = SIOCGIWAP;
+       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+       memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
+       current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+       /* Other entries will be displayed in the order we give them */
+
+       /* Add the ESSID */
+       iwe.u.data.length = le16_to_cpu(bss->a.essid_len);
+       if (iwe.u.data.length > 32)
+               iwe.u.data.length = 32;
+       iwe.cmd = SIOCGIWESSID;
+       iwe.u.data.flags = 1;
+       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
+
+       /* Add mode */
+       iwe.cmd = SIOCGIWMODE;
+       capabilities = le16_to_cpu(bss->a.capabilities);
+       if (capabilities & 0x3) {
+               if (capabilities & 0x1)
+                       iwe.u.mode = IW_MODE_MASTER;
                else
-                       atom_len = 68;
-               offset = 0;
-               break;
-       case FIRMWARE_TYPE_INTERSIL:
-               offset = 4;
-               if (priv->has_hostscan) {
-                       atom_len = le16_to_cpup((__le16 *)scan);
-                       /* Sanity check for atom_len */
-                       if (atom_len < sizeof(struct prism2_scan_apinfo)) {
-                               printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
-                               dev->name, atom_len);
-                               return -EIO;
-                       }
-               } else
-                       atom_len = offsetof(struct prism2_scan_apinfo, atim);
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       /* Check that we got an whole number of atoms */
-       if ((scan_len - offset) % atom_len) {
-               printk(KERN_ERR "%s: Unexpected scan data length %d, "
-                      "atom_len %d, offset %d\n", dev->name, scan_len,
-                      atom_len, offset);
-               return -EIO;
-       }
-
-       /* Read the entries one by one */
-       for (; offset + atom_len <= scan_len; offset += atom_len) {
-               /* Get next atom */
-               atom = (union hermes_scan_info *) (scan + offset);
-
-               /* First entry *MUST* be the AP MAC address */
-               iwe.cmd = SIOCGIWAP;
-               iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-               memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
-               current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
-
-               /* Other entries will be displayed in the order we give them */
-
-               /* Add the ESSID */
-               iwe.u.data.length = le16_to_cpu(atom->a.essid_len);
-               if (iwe.u.data.length > 32)
-                       iwe.u.data.length = 32;
-               iwe.cmd = SIOCGIWESSID;
-               iwe.u.data.flags = 1;
-               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
-
-               /* Add mode */
-               iwe.cmd = SIOCGIWMODE;
-               capabilities = le16_to_cpu(atom->a.capabilities);
-               if (capabilities & 0x3) {
-                       if (capabilities & 0x1)
-                               iwe.u.mode = IW_MODE_MASTER;
-                       else
-                               iwe.u.mode = IW_MODE_ADHOC;
-                       current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
-               }
-
-               channel = atom->s.channel;
-               if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) {
-                       /* Add frequency */
-                       iwe.cmd = SIOCGIWFREQ;
-                       iwe.u.freq.m = channel_frequency[channel-1] * 100000;
-                       iwe.u.freq.e = 1;
-                       current_ev = iwe_stream_add_event(current_ev, end_buf,
-                                                         &iwe, IW_EV_FREQ_LEN);
-               }
+                       iwe.u.mode = IW_MODE_ADHOC;
+               current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+       }
+
+       channel = bss->s.channel;
+       if ((channel >= 1) && (channel <= NUM_CHANNELS)) {
+               /* Add frequency */
+               iwe.cmd = SIOCGIWFREQ;
+               iwe.u.freq.m = channel_frequency[channel-1] * 100000;
+               iwe.u.freq.e = 1;
+               current_ev = iwe_stream_add_event(current_ev, end_buf,
+                                                 &iwe, IW_EV_FREQ_LEN);
+       }
+
+       /* Add quality statistics */
+       iwe.cmd = IWEVQUAL;
+       iwe.u.qual.updated = 0x10;      /* no link quality */
+       iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95;
+       iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95;
+       /* Wireless tools prior to 27.pre22 will show link quality
+        * anyway, so we provide a reasonable value. */
+       if (iwe.u.qual.level > iwe.u.qual.noise)
+               iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
+       else
+               iwe.u.qual.qual = 0;
+       current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
 
-               /* Add quality statistics */
-               iwe.cmd = IWEVQUAL;
-               iwe.u.qual.updated = 0x10;      /* no link quality */
-               iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95;
-               iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95;
-               /* Wireless tools prior to 27.pre22 will show link quality
-                * anyway, so we provide a reasonable value. */
-               if (iwe.u.qual.level > iwe.u.qual.noise)
-                       iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
-               else
-                       iwe.u.qual.qual = 0;
-               current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+       /* Add encryption capability */
+       iwe.cmd = SIOCGIWENCODE;
+       if (capabilities & 0x10)
+               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+       else
+               iwe.u.data.flags = IW_ENCODE_DISABLED;
+       iwe.u.data.length = 0;
+       current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid);
+
+       /* Add EXTRA: Age to display seconds since last beacon/probe response
+        * for given network. */
+       iwe.cmd = IWEVCUSTOM;
+       p = custom;
+       p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
+                     " Last beacon: %dms ago",
+                     jiffies_to_msecs(jiffies - last_scanned));
+       iwe.u.data.length = p - custom;
+       if (iwe.u.data.length)
+               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+
+       /* Bit rate is not available in Lucent/Agere firmwares */
+       if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
+               char *current_val = current_ev + IW_EV_LCP_LEN;
+               int i;
+               int step;
 
-               /* Add encryption capability */
-               iwe.cmd = SIOCGIWENCODE;
-               if (capabilities & 0x10)
-                       iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+               if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+                       step = 2;
                else
-                       iwe.u.data.flags = IW_ENCODE_DISABLED;
-               iwe.u.data.length = 0;
-               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
-
-               /* Bit rate is not available in Lucent/Agere firmwares */
-               if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-                       char *  current_val = current_ev + IW_EV_LCP_LEN;
-                       int     i;
-                       int     step;
-
-                       if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-                               step = 2;
-                       else
-                               step = 1;
-
-                       iwe.cmd = SIOCGIWRATE;
-                       /* Those two flags are ignored... */
-                       iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-                       /* Max 10 values */
-                       for (i = 0; i < 10; i += step) {
-                               /* NULL terminated */
-                               if (atom->p.rates[i] == 0x0)
-                                       break;
-                               /* Bit rate given in 500 kb/s units (+ 0x80) */
-                               iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
-                               current_val = iwe_stream_add_value(current_ev, current_val,
-                                                                  end_buf, &iwe,
-                                                                  IW_EV_PARAM_LEN);
-                       }
-                       /* Check if we added any event */
-                       if ((current_val - current_ev) > IW_EV_LCP_LEN)
-                               current_ev = current_val;
+                       step = 1;
+
+               iwe.cmd = SIOCGIWRATE;
+               /* Those two flags are ignored... */
+               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+               /* Max 10 values */
+               for (i = 0; i < 10; i += step) {
+                       /* NULL terminated */
+                       if (bss->p.rates[i] == 0x0)
+                               break;
+                       /* Bit rate given in 500 kb/s units (+ 0x80) */
+                       iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
+                       current_val = iwe_stream_add_value(current_ev, current_val,
+                                                          end_buf, &iwe,
+                                                          IW_EV_PARAM_LEN);
                }
-
-               /* The other data in the scan result are not really
-                * interesting, so for now drop it - Jean II */
+               /* Check if we added any event */
+               if ((current_val - current_ev) > IW_EV_LCP_LEN)
+                       current_ev = current_val;
        }
-       return current_ev - buffer;
+
+       return current_ev;
 }
 
 /* Return results of a scan */
@@ -4077,68 +4168,45 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
                                 char *extra)
 {
        struct orinoco_private *priv = netdev_priv(dev);
+       bss_element *bss;
        int err = 0;
        unsigned long flags;
+       char *current_ev = extra;
 
        if (orinoco_lock(priv, &flags) != 0)
                return -EBUSY;
 
-       /* If no results yet, ask to try again later */
-       if (priv->scan_result == NULL) {
-               if (priv->scan_inprogress)
-                       /* Important note : we don't want to block the caller
-                        * until results are ready for various reasons.
-                        * First, managing wait queues is complex and racy.
-                        * Second, we grab some rtnetlink lock before comming
-                        * here (in dev_ioctl()).
-                        * Third, we generate an Wireless Event, so the
-                        * caller can wait itself on that - Jean II */
-                       err = -EAGAIN;
-               else
-                       /* Client error, no scan results...
-                        * The caller need to restart the scan. */
-                       err = -ENODATA;
-       } else {
-               /* We have some results to push back to user space */
-
-               /* Translate to WE format */
-               int ret = orinoco_translate_scan(dev, extra,
-                                                priv->scan_result,
-                                                priv->scan_len);
-
-               if (ret < 0) {
-                       err = ret;
-                       kfree(priv->scan_result);
-                       priv->scan_result = NULL;
-               } else {
-                       srq->length = ret;
+       if (priv->scan_inprogress) {
+               /* Important note : we don't want to block the caller
+                * until results are ready for various reasons.
+                * First, managing wait queues is complex and racy.
+                * Second, we grab some rtnetlink lock before comming
+                * here (in dev_ioctl()).
+                * Third, we generate an Wireless Event, so the
+                * caller can wait itself on that - Jean II */
+               err = -EAGAIN;
+               goto out;
+       }
 
-                       /* Return flags */
-                       srq->flags = (__u16) priv->scan_mode;
+       list_for_each_entry(bss, &priv->bss_list, list) {
+               /* Translate to WE format this entry */
+               current_ev = orinoco_translate_scan(dev, current_ev,
+                                                   extra + srq->length,
+                                                   &bss->bss,
+                                                   bss->last_scanned);
 
-                       /* In any case, Scan results will be cleaned up in the
-                        * reset function and when exiting the driver.
-                        * The person triggering the scanning may never come to
-                        * pick the results, so we need to do it in those places.
-                        * Jean II */
-
-#ifdef SCAN_SINGLE_READ
-                       /* If you enable this option, only one client (the first
-                        * one) will be able to read the result (and only one
-                        * time). If there is multiple concurent clients that
-                        * want to read scan results, this behavior is not
-                        * advisable - Jean II */
-                       kfree(priv->scan_result);
-                       priv->scan_result = NULL;
-#endif /* SCAN_SINGLE_READ */
-                       /* Here, if too much time has elapsed since last scan,
-                        * we may want to clean up scan results... - Jean II */
+               /* Check if there is space for one more entry */
+               if ((extra + srq->length - current_ev) <= IW_EV_ADDR_LEN) {
+                       /* Ask user space to try again with a bigger buffer */
+                       err = -E2BIG;
+                       goto out;
                }
-
-               /* Scan is no longer in progress */
-               priv->scan_inprogress = 0;
        }
-         
+
+       srq->length = (current_ev - extra);
+       srq->flags = (__u16) priv->scan_mode;
+
+out:
        orinoco_unlock(priv, &flags);
        return err;
 }
index 4720fb20d66d1c730582e8ecf5d4552a7b4540b5..c6b1858abde87597f3ff64bdbd4deeb33bad9568 100644 (file)
@@ -36,6 +36,12 @@ typedef enum {
        FIRMWARE_TYPE_SYMBOL
 } fwtype_t;
 
+typedef struct {
+       union hermes_scan_info bss;
+       unsigned long last_scanned;
+       struct list_head list;
+} bss_element;
+
 struct orinoco_private {
        void *card;     /* Pointer to card dependent structure */
        int (*hard_reset)(struct orinoco_private *);
@@ -105,10 +111,12 @@ struct orinoco_private {
        int promiscuous, mc_count;
 
        /* Scanning support */
+       struct list_head bss_list;
+       struct list_head bss_free_list;
+       bss_element *bss_data;
+
        int     scan_inprogress;        /* Scan pending... */
        u32     scan_mode;              /* Type of scan done */
-       char *  scan_result;            /* Result of previous scan */
-       int     scan_len;               /* Lenght of result */
 };
 
 #ifdef ORINOCO_DEBUG
index 1437db0cf4b271372d1a96df5164d74725169919..5cda49aff3a86a12b0bdfda94b3bab5de3d83344 100644 (file)
@@ -54,7 +54,7 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                u32 code = le32_to_cpu(bootrec->code);
                switch (code) {
                case BR_CODE_COMPONENT_ID:
-                       switch (be32_to_cpu(*bootrec->data)) {
+                       switch (be32_to_cpu(*(__be32 *)bootrec->data)) {
                        case FW_FMAC:
                                printk(KERN_INFO "p54: FreeMAC firmware\n");
                                break;
@@ -78,14 +78,14 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                                fw_version = (unsigned char*)bootrec->data;
                        break;
                case BR_CODE_DESCR:
-                       priv->rx_start = le32_to_cpu(bootrec->data[1]);
+                       priv->rx_start = le32_to_cpu(((__le32 *)bootrec->data)[1]);
                        /* FIXME add sanity checking */
-                       priv->rx_end = le32_to_cpu(bootrec->data[2]) - 0x3500;
+                       priv->rx_end = le32_to_cpu(((__le32 *)bootrec->data)[2]) - 0x3500;
                        break;
                case BR_CODE_EXPOSED_IF:
                        exp_if = (struct bootrec_exp_if *) bootrec->data;
                        for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
-                               if (exp_if[i].if_id == 0x1a)
+                               if (exp_if[i].if_id == cpu_to_le16(0x1a))
                                        priv->fw_var = le16_to_cpu(exp_if[i].variant);
                        break;
                case BR_CODE_DEPENDENT_IF:
@@ -314,6 +314,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
        rx_status.phymode = MODE_IEEE80211G;
        rx_status.antenna = hdr->antenna;
        rx_status.mactime = le64_to_cpu(hdr->timestamp);
+       rx_status.flag |= RX_FLAG_TSFT;
 
        skb_pull(skb, sizeof(*hdr));
        skb_trim(skb, le16_to_cpu(hdr->len));
@@ -374,7 +375,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
                        if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
                                pad = entry_data->align[0];
 
-                       if (!status.control.flags & IEEE80211_TXCTL_NO_ACK) {
+                       if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
                                if (!(payload->status & 0x01))
                                        status.flags |= IEEE80211_TX_STATUS_ACK;
                                else
@@ -853,7 +854,8 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        return ret;
 }
 
-static int p54_config_interface(struct ieee80211_hw *dev, int if_id,
+static int p54_config_interface(struct ieee80211_hw *dev,
+                               struct ieee80211_vif *vif,
                                struct ieee80211_if_conf *conf)
 {
        struct p54_common *priv = dev->priv;
index 410b54387f23672f04225d4e11c020f0830825b0..fa527723fbe0e210f7e774d0e22a13f5fcb4bfea 100644 (file)
@@ -48,10 +48,10 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
        const struct firmware *fw_entry = NULL;
        __le32 reg;
        int err;
-       u32 *data;
+       __le32 *data;
        u32 remains, left, device_addr;
 
-       P54P_WRITE(int_enable, 0);
+       P54P_WRITE(int_enable, cpu_to_le32(0));
        P54P_READ(int_enable);
        udelay(10);
 
@@ -82,7 +82,7 @@ static int p54p_upload_firmware(struct ieee80211_hw *dev)
 
        p54_parse_firmware(dev, fw_entry);
 
-       data = (u32 *) fw_entry->data;
+       data = (__le32 *) fw_entry->data;
        remains = fw_entry->size;
        device_addr = ISL38XX_DEV_FIRMWARE_ADDR;
        while (remains) {
@@ -141,6 +141,7 @@ static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id)
 static int p54p_read_eeprom(struct ieee80211_hw *dev)
 {
        struct p54p_priv *priv = dev->priv;
+       struct p54p_ring_control *ring_control = priv->ring_control;
        int err;
        struct p54_control_hdr *hdr;
        void *eeprom;
@@ -164,8 +165,8 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
                goto out;
        }
 
-       memset(priv->ring_control, 0, sizeof(*priv->ring_control));
-       P54P_WRITE(ring_control_base, priv->ring_control_dma);
+       memset(ring_control, 0, sizeof(*ring_control));
+       P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
        P54P_READ(ring_control_base);
        udelay(10);
 
@@ -194,14 +195,14 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
        tx_mapping = pci_map_single(priv->pdev, (void *)hdr,
                                    EEPROM_READBACK_LEN, PCI_DMA_TODEVICE);
 
-       priv->ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping);
-       priv->ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010);
-       priv->ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping);
-       priv->ring_control->tx_data[0].device_addr = hdr->req_id;
-       priv->ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN);
+       ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping);
+       ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010);
+       ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping);
+       ring_control->tx_data[0].device_addr = hdr->req_id;
+       ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN);
 
-       priv->ring_control->host_idx[2] = cpu_to_le32(1);
-       priv->ring_control->host_idx[1] = cpu_to_le32(1);
+       ring_control->host_idx[2] = cpu_to_le32(1);
+       ring_control->host_idx[1] = cpu_to_le32(1);
 
        wmb();
        mdelay(100);
@@ -215,8 +216,8 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
        pci_unmap_single(priv->pdev, rx_mapping,
                         0x2010, PCI_DMA_FROMDEVICE);
 
-       alen = le16_to_cpu(priv->ring_control->rx_mgmt[0].len);
-       if (le32_to_cpu(priv->ring_control->device_idx[2]) != 1 ||
+       alen = le16_to_cpu(ring_control->rx_mgmt[0].len);
+       if (le32_to_cpu(ring_control->device_idx[2]) != 1 ||
            alen < 0x10) {
                printk(KERN_ERR "%s (prism54pci): Cannot read eeprom!\n",
                       pci_name(priv->pdev));
@@ -228,7 +229,7 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
 
  out:
        kfree(eeprom);
-       P54P_WRITE(int_enable, 0);
+       P54P_WRITE(int_enable, cpu_to_le32(0));
        P54P_READ(int_enable);
        udelay(10);
        free_irq(priv->pdev->irq, priv);
@@ -239,16 +240,17 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev)
 static void p54p_refill_rx_ring(struct ieee80211_hw *dev)
 {
        struct p54p_priv *priv = dev->priv;
+       struct p54p_ring_control *ring_control = priv->ring_control;
        u32 limit, host_idx, idx;
 
-       host_idx = le32_to_cpu(priv->ring_control->host_idx[0]);
+       host_idx = le32_to_cpu(ring_control->host_idx[0]);
        limit = host_idx;
-       limit -= le32_to_cpu(priv->ring_control->device_idx[0]);
-       limit = ARRAY_SIZE(priv->ring_control->rx_data) - limit;
+       limit -= le32_to_cpu(ring_control->device_idx[0]);
+       limit = ARRAY_SIZE(ring_control->rx_data) - limit;
 
-       idx = host_idx % ARRAY_SIZE(priv->ring_control->rx_data);
+       idx = host_idx % ARRAY_SIZE(ring_control->rx_data);
        while (limit-- > 1) {
-               struct p54p_desc *desc = &priv->ring_control->rx_data[idx];
+               struct p54p_desc *desc = &ring_control->rx_data[idx];
 
                if (!desc->host_addr) {
                        struct sk_buff *skb;
@@ -270,22 +272,23 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev)
 
                idx++;
                host_idx++;
-               idx %= ARRAY_SIZE(priv->ring_control->rx_data);
+               idx %= ARRAY_SIZE(ring_control->rx_data);
        }
 
        wmb();
-       priv->ring_control->host_idx[0] = cpu_to_le32(host_idx);
+       ring_control->host_idx[0] = cpu_to_le32(host_idx);
 }
 
 static irqreturn_t p54p_interrupt(int irq, void *dev_id)
 {
        struct ieee80211_hw *dev = dev_id;
        struct p54p_priv *priv = dev->priv;
+       struct p54p_ring_control *ring_control = priv->ring_control;
        __le32 reg;
 
        spin_lock(&priv->lock);
        reg = P54P_READ(int_ident);
-       if (unlikely(reg == 0xFFFFFFFF)) {
+       if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) {
                spin_unlock(&priv->lock);
                return IRQ_HANDLED;
        }
@@ -298,12 +301,12 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
                struct p54p_desc *desc;
                u32 idx, i;
                i = priv->tx_idx;
-               i %= ARRAY_SIZE(priv->ring_control->tx_data);
-               priv->tx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[1]);
-               idx %= ARRAY_SIZE(priv->ring_control->tx_data);
+               i %= ARRAY_SIZE(ring_control->tx_data);
+               priv->tx_idx = idx = le32_to_cpu(ring_control->device_idx[1]);
+               idx %= ARRAY_SIZE(ring_control->tx_data);
 
                while (i != idx) {
-                       desc = &priv->ring_control->tx_data[i];
+                       desc = &ring_control->tx_data[i];
                        if (priv->tx_buf[i]) {
                                kfree(priv->tx_buf[i]);
                                priv->tx_buf[i] = NULL;
@@ -318,17 +321,17 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
                        desc->flags = 0;
 
                        i++;
-                       i %= ARRAY_SIZE(priv->ring_control->tx_data);
+                       i %= ARRAY_SIZE(ring_control->tx_data);
                }
 
                i = priv->rx_idx;
-               i %= ARRAY_SIZE(priv->ring_control->rx_data);
-               priv->rx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[0]);
-               idx %= ARRAY_SIZE(priv->ring_control->rx_data);
+               i %= ARRAY_SIZE(ring_control->rx_data);
+               priv->rx_idx = idx = le32_to_cpu(ring_control->device_idx[0]);
+               idx %= ARRAY_SIZE(ring_control->rx_data);
                while (i != idx) {
                        u16 len;
                        struct sk_buff *skb;
-                       desc = &priv->ring_control->rx_data[i];
+                       desc = &ring_control->rx_data[i];
                        len = le16_to_cpu(desc->len);
                        skb = priv->rx_buf[i];
 
@@ -347,7 +350,7 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id)
                        }
 
                        i++;
-                       i %= ARRAY_SIZE(priv->ring_control->rx_data);
+                       i %= ARRAY_SIZE(ring_control->rx_data);
                }
 
                p54p_refill_rx_ring(dev);
@@ -366,6 +369,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
                    size_t len, int free_on_tx)
 {
        struct p54p_priv *priv = dev->priv;
+       struct p54p_ring_control *ring_control = priv->ring_control;
        unsigned long flags;
        struct p54p_desc *desc;
        dma_addr_t mapping;
@@ -373,19 +377,19 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       device_idx = le32_to_cpu(priv->ring_control->device_idx[1]);
-       idx = le32_to_cpu(priv->ring_control->host_idx[1]);
-       i = idx % ARRAY_SIZE(priv->ring_control->tx_data);
+       device_idx = le32_to_cpu(ring_control->device_idx[1]);
+       idx = le32_to_cpu(ring_control->host_idx[1]);
+       i = idx % ARRAY_SIZE(ring_control->tx_data);
 
        mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE);
-       desc = &priv->ring_control->tx_data[i];
+       desc = &ring_control->tx_data[i];
        desc->host_addr = cpu_to_le32(mapping);
        desc->device_addr = data->req_id;
        desc->len = cpu_to_le16(len);
        desc->flags = 0;
 
        wmb();
-       priv->ring_control->host_idx[1] = cpu_to_le32(idx + 1);
+       ring_control->host_idx[1] = cpu_to_le32(idx + 1);
 
        if (free_on_tx)
                priv->tx_buf[i] = data;
@@ -397,7 +401,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data,
 
        /* FIXME: unlikely to happen because the device usually runs out of
           memory before we fill the ring up, but we can make it impossible */
-       if (idx - device_idx > ARRAY_SIZE(priv->ring_control->tx_data) - 2)
+       if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2)
                printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy));
 }
 
@@ -421,7 +425,7 @@ static int p54p_open(struct ieee80211_hw *dev)
 
        p54p_upload_firmware(dev);
 
-       P54P_WRITE(ring_control_base, priv->ring_control_dma);
+       P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma));
        P54P_READ(ring_control_base);
        wmb();
        udelay(10);
@@ -457,10 +461,11 @@ static int p54p_open(struct ieee80211_hw *dev)
 static void p54p_stop(struct ieee80211_hw *dev)
 {
        struct p54p_priv *priv = dev->priv;
+       struct p54p_ring_control *ring_control = priv->ring_control;
        unsigned int i;
        struct p54p_desc *desc;
 
-       P54P_WRITE(int_enable, 0);
+       P54P_WRITE(int_enable, cpu_to_le32(0));
        P54P_READ(int_enable);
        udelay(10);
 
@@ -469,7 +474,7 @@ static void p54p_stop(struct ieee80211_hw *dev)
        P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
 
        for (i = 0; i < ARRAY_SIZE(priv->rx_buf); i++) {
-               desc = &priv->ring_control->rx_data[i];
+               desc = &ring_control->rx_data[i];
                if (desc->host_addr)
                        pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
                                         MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
@@ -478,7 +483,7 @@ static void p54p_stop(struct ieee80211_hw *dev)
        }
 
        for (i = 0; i < ARRAY_SIZE(priv->tx_buf); i++) {
-               desc = &priv->ring_control->tx_data[i];
+               desc = &ring_control->tx_data[i];
                if (desc->host_addr)
                        pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr),
                                         le16_to_cpu(desc->len), PCI_DMA_TODEVICE);
@@ -487,7 +492,7 @@ static void p54p_stop(struct ieee80211_hw *dev)
                priv->tx_buf[i] = NULL;
        }
 
-       memset(priv->ring_control, 0, sizeof(*priv->ring_control));
+       memset(ring_control, 0, sizeof(ring_control));
 }
 
 static int __devinit p54p_probe(struct pci_dev *pdev,
index 52feb597dc4a8a4cb6c6b964df0e49929cd2f6af..5bedd7af385d287f8151bd1df88f2bfd8f0e9e92 100644 (file)
@@ -85,8 +85,8 @@ struct p54p_ring_control {
        struct p54p_desc tx_mgmt[4];
 } __attribute__ ((packed));
 
-#define P54P_READ(r) __raw_readl(&priv->map->r)
-#define P54P_WRITE(r, val) __raw_writel((__force u32)(val), &priv->map->r)
+#define P54P_READ(r) (__force __le32)__raw_readl(&priv->map->r)
+#define P54P_WRITE(r, val) __raw_writel((__force u32)(__le32)(val), &priv->map->r)
 
 struct p54p_priv {
        struct p54_common common;
index 3fadcb6f5297857da8d214be4cb0450e1ad98349..19c33d3137348b52eeb1b98124b0c2a1a1edb972 100644 (file)
@@ -138,14 +138,14 @@ isl38xx_w32_flush(void __iomem *base, u32 val, unsigned long offset)
 #define MAX_FRAGMENT_SIZE_RX                   1600
 
 typedef struct {
-       u32 address;            /* physical address on host */
-       u16 size;               /* packet size */
-       u16 flags;              /* set of bit-wise flags */
+       __le32 address;         /* physical address on host */
+       __le16 size;            /* packet size */
+       __le16 flags;           /* set of bit-wise flags */
 } isl38xx_fragment;
 
 struct isl38xx_cb {
-       u32 driver_curr_frag[ISL38XX_CB_QCOUNT];
-       u32 device_curr_frag[ISL38XX_CB_QCOUNT];
+       __le32 driver_curr_frag[ISL38XX_CB_QCOUNT];
+       __le32 device_curr_frag[ISL38XX_CB_QCOUNT];
        isl38xx_fragment rx_data_low[ISL38XX_CB_RX_QSIZE];
        isl38xx_fragment tx_data_low[ISL38XX_CB_TX_QSIZE];
        isl38xx_fragment rx_data_high[ISL38XX_CB_RX_QSIZE];
index 6d80ca421cf0a2c1974176cc0eac33fd0470f725..1b595a6525f4e4346ba2b1f9100ba31e8c1ddfef 100644 (file)
@@ -165,8 +165,7 @@ prism54_update_stats(struct work_struct *work)
        struct obj_bss bss, *bss2;
        union oid_res_t r;
 
-       if (down_interruptible(&priv->stats_sem))
-               return;
+       down(&priv->stats_sem);
 
 /* Noise floor.
  * I'm not sure if the unit is dBm.
@@ -1118,7 +1117,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info,
                            mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
                                            &index);
                } else {
-                       if (!dwrq->flags & IW_ENCODE_MODE) {
+                       if (!(dwrq->flags & IW_ENCODE_MODE)) {
                                /* we cannot do anything. Complain. */
                                return -EINVAL;
                        }
@@ -1793,8 +1792,7 @@ prism54_clear_mac(struct islpci_acl *acl)
        struct list_head *ptr, *next;
        struct mac_entry *entry;
 
-       if (down_interruptible(&acl->sem))
-               return;
+       down(&acl->sem);
 
        if (acl->size == 0) {
                up(&acl->sem);
@@ -2116,8 +2114,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid,
        if (wpa_ie_len > MAX_WPA_IE_LEN)
                wpa_ie_len = MAX_WPA_IE_LEN;
 
-       if (down_interruptible(&priv->wpa_sem))
-               return;
+       down(&priv->wpa_sem);
 
        /* try to use existing entry */
        list_for_each(ptr, &priv->bss_wpa_list) {
@@ -2178,8 +2175,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie)
        struct islpci_bss_wpa_ie *bss = NULL;
        size_t len = 0;
 
-       if (down_interruptible(&priv->wpa_sem))
-               return 0;
+       down(&priv->wpa_sem);
 
        list_for_each(ptr, &priv->bss_wpa_list) {
                bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
@@ -2610,7 +2606,7 @@ prism2_ioctl_set_encryption(struct net_device *dev,
                            mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
                                            &index);
                } else {
-                       if (!param->u.crypt.flags & IW_ENCODE_MODE) {
+                       if (!(param->u.crypt.flags & IW_ENCODE_MODE)) {
                                /* we cannot do anything. Complain. */
                                return -EINVAL;
                        }
index 219dd651dc41067b4ecd66083b9d23a172ffd261..dbb538ccb4ecc295fa1a451fe00377816bd89297 100644 (file)
@@ -861,7 +861,7 @@ islpci_setup(struct pci_dev *pdev)
        init_waitqueue_head(&priv->reset_done);
 
        /* init the queue read locks, process wait counter */
-       sema_init(&priv->mgmt_sem, 1);
+       mutex_init(&priv->mgmt_lock);
        priv->mgmt_received = NULL;
        init_waitqueue_head(&priv->mgmt_wqueue);
        sema_init(&priv->stats_sem, 1);
index 736666da6c24344580c547ea708e3c24a65727f7..4e0182ce835bacecc067fcc871b859bb1f93e664 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 
 #include "isl_38xx.h"
 #include "isl_oid.h"
@@ -164,7 +165,7 @@ typedef struct {
        wait_queue_head_t reset_done;
 
        /* used by islpci_mgt_transaction */
-       struct semaphore mgmt_sem; /* serialize access to mailbox and wqueue */
+       struct mutex mgmt_lock; /* serialize access to mailbox and wqueue */
        struct islpci_mgmtframe *mgmt_received;   /* mbox for incoming frame */
        wait_queue_head_t mgmt_wqueue;            /* waitqueue for mbox */
 
index f49eb068c7d0ce232b9535d6d036bf64ae11222c..762e85bef55dcef657ded932a53f911b051ae4b9 100644 (file)
@@ -471,7 +471,7 @@ islpci_eth_receive(islpci_private *priv)
                wmb();
 
                /* increment the driver read pointer */
-               add_le32p((u32 *) &control_block->
+               add_le32p(&control_block->
                          driver_curr_frag[ISL38XX_CB_RX_DATA_LQ], 1);
        }
 
index 5bf820defbd01b73b906d295bfe3ce40f1e02e80..61454d32d74d31b02456fe0c416cf2e0b5ccd3c2 100644 (file)
 #include "islpci_dev.h"
 
 struct rfmon_header {
-       u16 unk0;               /* = 0x0000 */
-       u16 length;             /* = 0x1400 */
-       u32 clock;              /* 1MHz clock */
+       __le16 unk0;            /* = 0x0000 */
+       __le16 length;          /* = 0x1400 */
+       __le32 clock;           /* 1MHz clock */
        u8 flags;
        u8 unk1;
        u8 rate;
        u8 unk2;
-       u16 freq;
-       u16 unk3;
+       __le16 freq;
+       __le16 unk3;
        u8 rssi;
        u8 padding[3];
 } __attribute__ ((packed));
@@ -47,20 +47,20 @@ struct rx_annex_header {
 #define P80211CAPTURE_VERSION 0x80211001
 
 struct avs_80211_1_header {
-       uint32_t version;
-       uint32_t length;
-       uint64_t mactime;
-       uint64_t hosttime;
-       uint32_t phytype;
-       uint32_t channel;
-       uint32_t datarate;
-       uint32_t antenna;
-       uint32_t priority;
-       uint32_t ssi_type;
-       int32_t ssi_signal;
-       int32_t ssi_noise;
-       uint32_t preamble;
-       uint32_t encoding;
+       __be32 version;
+       __be32 length;
+       __be64 mactime;
+       __be64 hosttime;
+       __be32 phytype;
+       __be32 channel;
+       __be32 datarate;
+       __be32 antenna;
+       __be32 priority;
+       __be32 ssi_type;
+       __be32 ssi_signal;
+       __be32 ssi_noise;
+       __be32 preamble;
+       __be32 encoding;
 };
 
 void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *);
index 2246f7930b4edfd45aeac66a5bdf4c194ce91a96..f7c677e2094d168e53fe5ea890bdec5a6459b4b2 100644 (file)
@@ -460,7 +460,7 @@ islpci_mgt_transaction(struct net_device *ndev,
 
        *recvframe = NULL;
 
-       if (down_interruptible(&priv->mgmt_sem))
+       if (mutex_lock_interruptible(&priv->mgmt_lock))
                return -ERESTARTSYS;
 
        prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE);
@@ -504,7 +504,7 @@ islpci_mgt_transaction(struct net_device *ndev,
        /* TODO: we should reset the device here */
  out:
        finish_wait(&priv->mgmt_wqueue, &wait);
-       up(&priv->mgmt_sem);
+       mutex_unlock(&priv->mgmt_lock);
        return err;
 }
 
index fc53b587b72238bcaeab9f505bedf55ced865503..f91a88fc1e35b0023faf78daf85780fafb17f495 100644 (file)
@@ -86,7 +86,7 @@ extern int pc_debug;
 #define PIMFOR_FLAG_LITTLE_ENDIAN               0x02
 
 static inline void
-add_le32p(u32 * le_number, u32 add)
+add_le32p(__le32 * le_number, u32 add)
 {
        *le_number = cpu_to_le32(le32_to_cpup(le_number) + add);
 }
index f87fe10059ae0f40319372cee58488fd0c9e899c..f3858ee36f32a14f7589cf43c57c3b1ca989738b 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/ioport.h>
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
+#include <linux/ieee80211.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -997,13 +998,13 @@ static int ray_hw_xmit(unsigned char* data, int len, struct net_device* dev,
 static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigned char *data,
                     int len)
 {
-    unsigned short int proto = ((struct ethhdr *)data)->h_proto;
+    __be16 proto = ((struct ethhdr *)data)->h_proto;
     if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
         DEBUG(3,"ray_cs translate_frame DIX II\n");
         /* Copy LLC header to card buffer */
         memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
         memcpy_toio( ((void __iomem *)&ptx->var) + sizeof(eth2_llc), (UCHAR *)&proto, 2);
-        if ((proto == 0xf380) || (proto == 0x3781)) {
+        if (proto == htons(ETH_P_AARP) || proto == htons(ETH_P_IPX)) {
             /* This is the selective translation table, only 2 entries */
             writeb(0xf8, &((struct snaphdr_t __iomem *)ptx->var)->org[3]);
         }
@@ -1014,7 +1015,7 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, unsigne
     }
     else { /* already  802 type, and proto is length */
         DEBUG(3,"ray_cs translate_frame 802\n");
-        if (proto == 0xffff) { /* evil netware IPX 802.3 without LLC */
+        if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
         DEBUG(3,"ray_cs translate_frame evil IPX\n");
             memcpy_toio(&ptx->var, data + ETH_HLEN,  len - ETH_HLEN);
             return 0 - ETH_HLEN;
@@ -1780,19 +1781,19 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev)
     }
     if (readb(&p->mrx_overflow_for_host))
     {
-        local->stats.rx_over_errors += ntohs(readb(&p->mrx_overflow));
+        local->stats.rx_over_errors += swab16(readw(&p->mrx_overflow));
         writeb(0,&p->mrx_overflow);
         writeb(0,&p->mrx_overflow_for_host);
     }
     if (readb(&p->mrx_checksum_error_for_host))
     {
-        local->stats.rx_crc_errors += ntohs(readb(&p->mrx_checksum_error));
+        local->stats.rx_crc_errors += swab16(readw(&p->mrx_checksum_error));
         writeb(0,&p->mrx_checksum_error);
         writeb(0,&p->mrx_checksum_error_for_host);
     }
     if (readb(&p->rx_hec_error_for_host))
     {
-        local->stats.rx_frame_errors += ntohs(readb(&p->rx_hec_error));
+        local->stats.rx_frame_errors += swab16(readw(&p->rx_hec_error));
         writeb(0,&p->rx_hec_error);
         writeb(0,&p->rx_hec_error_for_host);
     }
@@ -2316,32 +2317,17 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i
 static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
 {
     snaphdr_t *psnap = (snaphdr_t *)(skb->data + RX_MAC_HEADER_LENGTH);
-    struct mac_header *pmac = (struct mac_header *)skb->data;
-    unsigned short type = *(unsigned short *)psnap->ethertype;
-    unsigned int xsap = *(unsigned int *)psnap & 0x00ffffff;
-    unsigned int org = (*(unsigned int *)psnap->org) & 0x00ffffff;
+    struct ieee80211_hdr *pmac = (struct ieee80211_hdr *)skb->data;
+    __be16 type = *(__be16 *)psnap->ethertype;
     int delta;
     struct ethhdr *peth;
     UCHAR srcaddr[ADDRLEN];
     UCHAR destaddr[ADDRLEN];
+    static UCHAR org_bridge[3] = {0, 0, 0xf8};
+    static UCHAR org_1042[3] = {0, 0, 0};
 
-    if (pmac->frame_ctl_2 & FC2_FROM_DS) {
-       if (pmac->frame_ctl_2 & FC2_TO_DS) { /* AP to AP */
-           memcpy(destaddr, pmac->addr_3, ADDRLEN);
-           memcpy(srcaddr, ((unsigned char *)pmac->addr_3) + ADDRLEN, ADDRLEN);
-       } else { /* AP to terminal */
-           memcpy(destaddr, pmac->addr_1, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_3, ADDRLEN); 
-       }
-    } else { /* Terminal to AP */
-       if (pmac->frame_ctl_2 & FC2_TO_DS) {
-           memcpy(destaddr, pmac->addr_3, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_2, ADDRLEN); 
-       } else { /* Adhoc */
-           memcpy(destaddr, pmac->addr_1, ADDRLEN);
-           memcpy(srcaddr, pmac->addr_2, ADDRLEN); 
-       }
-    }
+    memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
+    memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
 
 #ifdef PCMCIA_DEBUG
     if (pc_debug > 3) {
@@ -2349,33 +2335,34 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
     printk(KERN_DEBUG "skb->data before untranslate");
     for (i=0;i<64;i++) 
         printk("%02x ",skb->data[i]);
-    printk("\n" KERN_DEBUG "type = %08x, xsap = %08x, org = %08x\n",
-           type,xsap,org);
+    printk("\n" KERN_DEBUG "type = %08x, xsap = %02x%02x%02x, org = %02x02x02x\n",
+           ntohs(type),
+          psnap->dsap, psnap->ssap, psnap->ctrl,
+          psnap->org[0], psnap->org[1], psnap->org[2]);
     printk(KERN_DEBUG "untranslate skb->data = %p\n",skb->data);
     }
 #endif
 
-    if ( xsap != SNAP_ID) {
+    if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
         /* not a snap type so leave it alone */
-        DEBUG(3,"ray_cs untranslate NOT SNAP %x\n", *(unsigned int *)psnap & 0x00ffffff);
+        DEBUG(3,"ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+               psnap->dsap, psnap->ssap, psnap->ctrl);
 
         delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
         peth = (struct ethhdr *)(skb->data + delta);
         peth->h_proto = htons(len - RX_MAC_HEADER_LENGTH);
     }
     else { /* Its a SNAP */
-        if (org == BRIDGE_ENCAP) { /* EtherII and nuke the LLC  */
+        if (memcmp(psnap->org, org_bridge, 3) == 0) { /* EtherII and nuke the LLC  */
         DEBUG(3,"ray_cs untranslate Bridge encap\n");
             delta = RX_MAC_HEADER_LENGTH 
                 + sizeof(struct snaphdr_t) - ETH_HLEN;
             peth = (struct ethhdr *)(skb->data + delta);
             peth->h_proto = type;
-        }
-        else {
-            if (org == RFC1042_ENCAP) {
-                switch (type) {
-                case RAY_IPX_TYPE:
-                case APPLEARP_TYPE:
+       } else if (memcmp(psnap->org, org_1042, 3) == 0) {
+                switch (ntohs(type)) {
+                case ETH_P_IPX:
+                case ETH_P_AARP:
                     DEBUG(3,"ray_cs untranslate RFC IPX/AARP\n");
                     delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
                     peth = (struct ethhdr *)(skb->data + delta);
@@ -2389,14 +2376,12 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
                     peth->h_proto = type;
                     break;
                 }
-            }
-            else {
+       } else {
                 printk("ray_cs untranslate very confused by packet\n");
                 delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
                 peth = (struct ethhdr *)(skb->data + delta);
                 peth->h_proto = type;
-            }
-        }
+       }
     }
 /* TBD reserve  skb_reserve(skb, delta); */
     skb_pull(skb, delta);
index 31c1dd271627191813d37278d23abc08bcb48455..d6cba138c7ab7723cd5b039c18ebb6e5e9ce4010 100644 (file)
        Supported chipsets: RT2460.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2400pci"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -54,7 +49,7 @@
  * the access attempt is considered to have failed,
  * and we will print an error.
  */
-static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt2400pci_bbp_check(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
        unsigned int i;
@@ -69,7 +64,7 @@ static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
        return reg;
 }
 
-static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, const u8 value)
 {
        u32 reg;
@@ -95,7 +90,7 @@ static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
 }
 
-static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u8 *value)
 {
        u32 reg;
@@ -132,7 +127,7 @@ static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
        *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
 }
 
-static void rt2400pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, const u32 value)
 {
        u32 reg;
@@ -195,13 +190,13 @@ static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 #define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
 
-static void rt2400pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_read_csr(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u32 *data)
 {
        rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
 }
 
-static void rt2400pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2400pci_write_csr(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, u32 data)
 {
        rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
@@ -285,7 +280,7 @@ static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type,
         */
        rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
        rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
-       rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+       rt2x00_set_field32(&reg, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, CSR14_TSF_SYNC, tsf_sync);
        rt2x00pci_register_write(rt2x00dev, CSR14, reg);
@@ -397,7 +392,7 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower)
 }
 
 static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    int antenna_tx, int antenna_rx)
+                                    struct antenna_setup *ant)
 {
        u8 r1;
        u8 r4;
@@ -408,14 +403,20 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the TX antenna.
         */
-       switch (antenna_tx) {
-       case ANTENNA_SW_DIVERSITY:
+       switch (ant->tx) {
        case ANTENNA_HW_DIVERSITY:
                rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
                break;
        case ANTENNA_A:
                rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
                break;
@@ -424,14 +425,20 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the RX antenna.
         */
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
                rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
                break;
        case ANTENNA_A:
                rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
                break;
@@ -485,9 +492,7 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
                rt2400pci_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
        if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2400pci_config_antenna(rt2x00dev,
-                                        libconf->conf->antenna_sel_tx,
-                                        libconf->conf->antenna_sel_rx);
+               rt2400pci_config_antenna(rt2x00dev, &libconf->ant);
        if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
                rt2400pci_config_duration(rt2x00dev, libconf);
 }
@@ -514,18 +519,10 @@ static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev)
 
        rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
        rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
-
-       if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 1);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
-       } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 1);
-       } else {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 1);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 1);
-       }
-
+       rt2x00_set_field32(&reg, LEDCSR_LINK,
+                          (rt2x00dev->led_mode != LED_MODE_ASUS));
+       rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
+                          (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
        rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
 }
 
@@ -542,7 +539,8 @@ static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev)
 /*
  * Link tuning
  */
-static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u32 reg;
        u8 bbp;
@@ -551,13 +549,13 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev)
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT0, &reg);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2400pci_bbp_read(rt2x00dev, 39, &bbp);
-       rt2x00dev->link.false_cca = bbp;
+       qual->false_cca = bbp;
 }
 
 static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -582,10 +580,10 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
         */
        rt2400pci_bbp_read(rt2x00dev, 13, &reg);
 
-       if (rt2x00dev->link.false_cca > 512 && reg < 0x20) {
+       if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
                rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
                rt2x00dev->link.vgc_level = reg;
-       } else if (rt2x00dev->link.false_cca < 100 && reg > 0x08) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
                rt2400pci_bbp_write(rt2x00dev, 13, --reg);
                rt2x00dev->link.vgc_level = reg;
        }
@@ -594,80 +592,49 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 /*
  * Initialization functions.
  */
-static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev)
+static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                                  struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00dev->rx;
-       struct data_desc *rxd;
-       unsigned int i;
+       __le32 *rxd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               rxd = ring->entry[i].priv;
-
-               rt2x00_desc_read(rxd, 2, &word);
-               rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH,
-                                  ring->data_size);
-               rt2x00_desc_write(rxd, 2, word);
-
-               rt2x00_desc_read(rxd, 1, &word);
-               rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(rxd, 1, word);
+       rt2x00_desc_read(rxd, 2, &word);
+       rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->ring->data_size);
+       rt2x00_desc_write(rxd, 2, word);
 
-               rt2x00_desc_read(rxd, 0, &word);
-               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-               rt2x00_desc_write(rxd, 0, word);
-       }
+       rt2x00_desc_read(rxd, 1, &word);
+       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma);
+       rt2x00_desc_write(rxd, 1, word);
 
-       rt2x00_ring_index_clear(rt2x00dev->rx);
+       rt2x00_desc_read(rxd, 0, &word);
+       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+       rt2x00_desc_write(rxd, 0, word);
 }
 
-static void rt2400pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
+static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev,
+                                  struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
-       struct data_desc *txd;
-       unsigned int i;
+       __le32 *txd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               txd = ring->entry[i].priv;
-
-               rt2x00_desc_read(txd, 1, &word);
-               rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(txd, 1, word);
-
-               rt2x00_desc_read(txd, 2, &word);
-               rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH,
-                                  ring->data_size);
-               rt2x00_desc_write(txd, 2, word);
+       rt2x00_desc_read(txd, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma);
+       rt2x00_desc_write(txd, 1, word);
 
-               rt2x00_desc_read(txd, 0, &word);
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-               rt2x00_desc_write(txd, 0, word);
-       }
+       rt2x00_desc_read(txd, 2, &word);
+       rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, entry->ring->data_size);
+       rt2x00_desc_write(txd, 2, word);
 
-       rt2x00_ring_index_clear(ring);
+       rt2x00_desc_read(txd, 0, &word);
+       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+       rt2x00_desc_write(txd, 0, word);
 }
 
 static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
 
-       /*
-        * Initialize rings.
-        */
-       rt2400pci_init_rxring(rt2x00dev);
-       rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-       rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
-       rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON);
-       rt2400pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
-
        /*
         * Initialize registers.
         */
@@ -1014,53 +981,37 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                   struct data_desc *txd,
+                                   struct sk_buff *skb,
                                    struct txdata_entry_desc *desc,
-                                   struct ieee80211_hdr *ieee80211hdr,
-                                   unsigned int length,
                                    struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
-       u32 signal = 0;
-       u32 service = 0;
-       u32 length_high = 0;
-       u32 length_low = 0;
-
-       /*
-        * The PLCP values should be treated as if they
-        * were BBP values.
-        */
-       rt2x00_set_field32(&signal, BBPCSR_VALUE, desc->signal);
-       rt2x00_set_field32(&signal, BBPCSR_REGNUM, 5);
-       rt2x00_set_field32(&signal, BBPCSR_BUSY, 1);
-
-       rt2x00_set_field32(&service, BBPCSR_VALUE, desc->service);
-       rt2x00_set_field32(&service, BBPCSR_REGNUM, 6);
-       rt2x00_set_field32(&service, BBPCSR_BUSY, 1);
-
-       rt2x00_set_field32(&length_high, BBPCSR_VALUE, desc->length_high);
-       rt2x00_set_field32(&length_high, BBPCSR_REGNUM, 7);
-       rt2x00_set_field32(&length_high, BBPCSR_BUSY, 1);
-
-       rt2x00_set_field32(&length_low, BBPCSR_VALUE, desc->length_low);
-       rt2x00_set_field32(&length_low, BBPCSR_REGNUM, 8);
-       rt2x00_set_field32(&length_low, BBPCSR_BUSY, 1);
 
        /*
         * Start writing the descriptor words.
         */
        rt2x00_desc_read(txd, 2, &word);
-       rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_desc_write(txd, 2, word);
 
        rt2x00_desc_read(txd, 3, &word);
-       rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, signal);
-       rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, service);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1);
        rt2x00_desc_write(txd, 3, word);
 
        rt2x00_desc_read(txd, 4, &word);
-       rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, length_low);
-       rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, length_high);
+       rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1);
+       rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7);
+       rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1);
        rt2x00_desc_write(txd, 4, word);
 
        rt2x00_desc_read(txd, 0, &word);
@@ -1069,7 +1020,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_RTS,
@@ -1099,12 +1050,12 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
        }
 
        rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-       if (queue == IEEE80211_TX_QUEUE_DATA0)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA1)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
-       else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
+       rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO,
+                          (queue == IEEE80211_TX_QUEUE_DATA0));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_TX,
+                          (queue == IEEE80211_TX_QUEUE_DATA1));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM,
+                          (queue == IEEE80211_TX_QUEUE_AFTER_BEACON));
        rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 }
 
@@ -1114,7 +1065,7 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 static void rt2400pci_fill_rxdone(struct data_entry *entry,
                                  struct rxdata_entry_desc *desc)
 {
-       struct data_desc *rxd = entry->priv;
+       __le32 *rxd = entry->priv;
        u32 word0;
        u32 word2;
 
@@ -1135,6 +1086,7 @@ static void rt2400pci_fill_rxdone(struct data_entry *entry,
            entry->ring->rt2x00dev->rssi_offset;
        desc->ofdm = 0;
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
 
 /*
@@ -1144,7 +1096,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
 {
        struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
        struct data_entry *entry;
-       struct data_desc *txd;
+       __le32 *txd;
        u32 word;
        int tx_status;
        int retry;
@@ -1164,26 +1116,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
                tx_status = rt2x00_get_field32(word, TXD_W0_RESULT);
                retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-               rt2x00lib_txdone(entry, tx_status, retry);
-
-               /*
-                * Make this entry available for reuse.
-                */
-               entry->flags = 0;
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_desc_write(txd, 0, word);
-               rt2x00_ring_index_done_inc(ring);
+               rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
        }
-
-       /*
-        * If the data ring was full before the txdone handler
-        * we must make sure the packet queue in the mac80211 stack
-        * is reenabled when the txdone handler has finished.
-        */
-       entry = ring->entry;
-       if (!rt2x00_ring_full(ring))
-               ieee80211_wake_queue(rt2x00dev->hw,
-                                    entry->tx_status.control.queue);
 }
 
 static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
@@ -1315,11 +1249,22 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->hw->conf.antenna_sel_tx =
+       rt2x00dev->default_ant.tx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
-       rt2x00dev->hw->conf.antenna_sel_rx =
+       rt2x00dev->default_ant.rx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
 
+       /*
+        * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead.
+        * I am not 100% sure about this, but the legacy drivers do not
+        * indicate antenna swapping in software is required when
+        * diversity is enabled.
+        */
+       if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+               rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY;
+       if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+               rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY;
+
        /*
         * Store led mode, for correct led behaviour.
         */
@@ -1447,7 +1392,6 @@ static void rt2400pci_configure_filter(struct ieee80211_hw *hw,
                                       struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u32 reg;
 
        /*
@@ -1466,21 +1410,18 @@ static void rt2400pci_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
         */
        *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * Start configuration steps.
@@ -1583,7 +1524,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
        .configure_filter       = rt2400pci_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt2400pci_set_retry_limit,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2400pci_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt2400pci_get_tsf,
@@ -1597,6 +1538,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
        .probe_hw               = rt2400pci_probe_hw,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
+       .init_rxentry           = rt2400pci_init_rxentry,
+       .init_txentry           = rt2400pci_init_txentry,
        .set_device_state       = rt2400pci_set_device_state,
        .rfkill_poll            = rt2400pci_rfkill_poll,
        .link_stats             = rt2400pci_link_stats,
@@ -1614,7 +1557,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt2400pci_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -1642,7 +1585,7 @@ MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver rt2400pci_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt2400pci_device_table,
        .probe          = rt2x00pci_probe,
        .remove         = __devexit_p(rt2x00pci_remove),
index ae22501f085d20ea42db5cc93160912ad037b9d1..369aac6d033628c5e4ee39894b82e72f438dd469 100644 (file)
 /*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE                  ( 8 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE                  ( 8 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE                  ( 8 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 8 * sizeof(__le32) )
 
 /*
  * TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
 
 /*
  * Word3 & 4: PLCP information
- */
-#define TXD_W3_PLCP_SIGNAL             FIELD32(0x0000ffff)
-#define TXD_W3_PLCP_SERVICE            FIELD32(0xffff0000)
-#define TXD_W4_PLCP_LENGTH_LOW         FIELD32(0x0000ffff)
-#define TXD_W4_PLCP_LENGTH_HIGH                FIELD32(0xffff0000)
+ * The PLCP values should be treated as if they were BBP values.
+ */
+#define TXD_W3_PLCP_SIGNAL             FIELD32(0x000000ff)
+#define TXD_W3_PLCP_SIGNAL_REGNUM      FIELD32(0x00007f00)
+#define TXD_W3_PLCP_SIGNAL_BUSY                FIELD32(0x00008000)
+#define TXD_W3_PLCP_SERVICE            FIELD32(0x00ff0000)
+#define TXD_W3_PLCP_SERVICE_REGNUM     FIELD32(0x7f000000)
+#define TXD_W3_PLCP_SERVICE_BUSY       FIELD32(0x80000000)
+
+#define TXD_W4_PLCP_LENGTH_LOW         FIELD32(0x000000ff)
+#define TXD_W3_PLCP_LENGTH_LOW_REGNUM  FIELD32(0x00007f00)
+#define TXD_W3_PLCP_LENGTH_LOW_BUSY    FIELD32(0x00008000)
+#define TXD_W4_PLCP_LENGTH_HIGH                FIELD32(0x00ff0000)
+#define TXD_W3_PLCP_LENGTH_HIGH_REGNUM FIELD32(0x7f000000)
+#define TXD_W3_PLCP_LENGTH_HIGH_BUSY   FIELD32(0x80000000)
 
 /*
  * Word5
index 702321c30164d6e46310b9f959c4497a27d68bb9..e874fdcae20450d015cea1fd23fa8dc3d03a1cd1 100644 (file)
        Supported chipsets: RT2560.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2500pci"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -54,7 +49,7 @@
  * the access attempt is considered to have failed,
  * and we will print an error.
  */
-static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt2500pci_bbp_check(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
        unsigned int i;
@@ -69,7 +64,7 @@ static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
        return reg;
 }
 
-static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, const u8 value)
 {
        u32 reg;
@@ -95,7 +90,7 @@ static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
 }
 
-static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u8 *value)
 {
        u32 reg;
@@ -132,7 +127,7 @@ static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
        *value = rt2x00_get_field32(reg, BBPCSR_VALUE);
 }
 
-static void rt2500pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, const u32 value)
 {
        u32 reg;
@@ -195,13 +190,13 @@ static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 #define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
 
-static void rt2500pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_read_csr(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u32 *data)
 {
        rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
 }
 
-static void rt2500pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500pci_write_csr(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, u32 data)
 {
        rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
@@ -289,7 +284,7 @@ static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type,
         */
        rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
        rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
-       rt2x00_set_field32(&reg, CSR14_TBCN, 1);
+       rt2x00_set_field32(&reg, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, CSR14_TSF_SYNC, tsf_sync);
        rt2x00pci_register_write(rt2x00dev, CSR14, reg);
@@ -424,7 +419,7 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    const int antenna_tx, const int antenna_rx)
+                                    struct antenna_setup *ant)
 {
        u32 reg;
        u8 r14;
@@ -437,18 +432,20 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the TX antenna.
         */
-       switch (antenna_tx) {
-       case ANTENNA_SW_DIVERSITY:
-       case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
-               rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
-               rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
-               break;
+       switch (ant->tx) {
        case ANTENNA_A:
                rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
                rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
                rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
                break;
+       case ANTENNA_HW_DIVERSITY:
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
                rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
@@ -459,14 +456,18 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the RX antenna.
         */
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
-       case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
-               break;
+       switch (ant->rx) {
        case ANTENNA_A:
                rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
                break;
+       case ANTENNA_HW_DIVERSITY:
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
                break;
@@ -541,9 +542,7 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
                rt2500pci_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
        if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2500pci_config_antenna(rt2x00dev,
-                                        libconf->conf->antenna_sel_tx,
-                                        libconf->conf->antenna_sel_rx);
+               rt2500pci_config_antenna(rt2x00dev, &libconf->ant);
        if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
                rt2500pci_config_duration(rt2x00dev, libconf);
 }
@@ -559,18 +558,10 @@ static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev)
 
        rt2x00_set_field32(&reg, LEDCSR_ON_PERIOD, 70);
        rt2x00_set_field32(&reg, LEDCSR_OFF_PERIOD, 30);
-
-       if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 1);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 0);
-       } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 0);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 1);
-       } else {
-               rt2x00_set_field32(&reg, LEDCSR_LINK, 1);
-               rt2x00_set_field32(&reg, LEDCSR_ACTIVITY, 1);
-       }
-
+       rt2x00_set_field32(&reg, LEDCSR_LINK,
+                          (rt2x00dev->led_mode != LED_MODE_ASUS));
+       rt2x00_set_field32(&reg, LEDCSR_ACTIVITY,
+                          (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
        rt2x00pci_register_write(rt2x00dev, LEDCSR, reg);
 }
 
@@ -587,7 +578,8 @@ static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev)
 /*
  * Link tuning
  */
-static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u32 reg;
 
@@ -595,13 +587,13 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev)
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT0, &reg);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2x00pci_register_read(rt2x00dev, CNT3, &reg);
-       rt2x00dev->link.false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
+       qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
 }
 
 static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -679,10 +671,10 @@ dynamic_cca_tune:
         * R17 is inside the dynamic tuning range,
         * start tuning the link based on the false cca counter.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < 0x40) {
+       if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
                rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
                rt2x00dev->link.vgc_level = r17;
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > 0x32) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
                rt2500pci_bbp_write(rt2x00dev, 17, --r17);
                rt2x00dev->link.vgc_level = r17;
        }
@@ -691,70 +683,41 @@ dynamic_cca_tune:
 /*
  * Initialization functions.
  */
-static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev)
+static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                                  struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00dev->rx;
-       struct data_desc *rxd;
-       unsigned int i;
+       __le32 *rxd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               rxd = ring->entry[i].priv;
-
-               rt2x00_desc_read(rxd, 1, &word);
-               rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(rxd, 1, word);
-
-               rt2x00_desc_read(rxd, 0, &word);
-               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-               rt2x00_desc_write(rxd, 0, word);
-       }
+       rt2x00_desc_read(rxd, 1, &word);
+       rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma);
+       rt2x00_desc_write(rxd, 1, word);
 
-       rt2x00_ring_index_clear(rt2x00dev->rx);
+       rt2x00_desc_read(rxd, 0, &word);
+       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+       rt2x00_desc_write(rxd, 0, word);
 }
 
-static void rt2500pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
+static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev,
+                                  struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
-       struct data_desc *txd;
-       unsigned int i;
+       __le32 *txd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               txd = ring->entry[i].priv;
-
-               rt2x00_desc_read(txd, 1, &word);
-               rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(txd, 1, word);
-
-               rt2x00_desc_read(txd, 0, &word);
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-               rt2x00_desc_write(txd, 0, word);
-       }
+       rt2x00_desc_read(txd, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma);
+       rt2x00_desc_write(txd, 1, word);
 
-       rt2x00_ring_index_clear(ring);
+       rt2x00_desc_read(txd, 0, &word);
+       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+       rt2x00_desc_write(txd, 0, word);
 }
 
 static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
 
-       /*
-        * Initialize rings.
-        */
-       rt2500pci_init_rxring(rt2x00dev);
-       rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-       rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
-       rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON);
-       rt2500pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
-
        /*
         * Initialize registers.
         */
@@ -1170,12 +1133,12 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                   struct data_desc *txd,
+                                   struct sk_buff *skb,
                                    struct txdata_entry_desc *desc,
-                                   struct ieee80211_hdr *ieee80211hdr,
-                                   unsigned int length,
                                    struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
@@ -1206,7 +1169,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
@@ -1216,7 +1179,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
                           !!(control->flags &
                              IEEE80211_TXCTL_LONG_RETRY_LIMIT));
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
        rt2x00_desc_write(txd, 0, word);
 }
@@ -1239,12 +1202,12 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
        }
 
        rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
-       if (queue == IEEE80211_TX_QUEUE_DATA0)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA1)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_TX, 1);
-       else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
-               rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM, 1);
+       rt2x00_set_field32(&reg, TXCSR0_KICK_PRIO,
+                          (queue == IEEE80211_TX_QUEUE_DATA0));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_TX,
+                          (queue == IEEE80211_TX_QUEUE_DATA1));
+       rt2x00_set_field32(&reg, TXCSR0_KICK_ATIM,
+                          (queue == IEEE80211_TX_QUEUE_AFTER_BEACON));
        rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
 }
 
@@ -1254,7 +1217,7 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 static void rt2500pci_fill_rxdone(struct data_entry *entry,
                                  struct rxdata_entry_desc *desc)
 {
-       struct data_desc *rxd = entry->priv;
+       __le32 *rxd = entry->priv;
        u32 word0;
        u32 word2;
 
@@ -1272,6 +1235,7 @@ static void rt2500pci_fill_rxdone(struct data_entry *entry,
            entry->ring->rt2x00dev->rssi_offset;
        desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
 
 /*
@@ -1281,7 +1245,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
 {
        struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
        struct data_entry *entry;
-       struct data_desc *txd;
+       __le32 *txd;
        u32 word;
        int tx_status;
        int retry;
@@ -1301,26 +1265,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
                tx_status = rt2x00_get_field32(word, TXD_W0_RESULT);
                retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-               rt2x00lib_txdone(entry, tx_status, retry);
-
-               /*
-                * Make this entry available for reuse.
-                */
-               entry->flags = 0;
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_desc_write(txd, 0, word);
-               rt2x00_ring_index_done_inc(ring);
+               rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
        }
-
-       /*
-        * If the data ring was full before the txdone handler
-        * we must make sure the packet queue in the mac80211 stack
-        * is reenabled when the txdone handler has finished.
-        */
-       entry = ring->entry;
-       if (!rt2x00_ring_full(ring))
-               ieee80211_wake_queue(rt2x00dev->hw,
-                                    entry->tx_status.control.queue);
 }
 
 static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
@@ -1420,9 +1366,12 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
        if (word == 0xffff) {
                rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+                                  ANTENNA_SW_DIVERSITY);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+                                  ANTENNA_SW_DIVERSITY);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
+                                  LED_MODE_DEFAULT);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
@@ -1481,9 +1430,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->hw->conf.antenna_sel_tx =
+       rt2x00dev->default_ant.tx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
-       rt2x00dev->hw->conf.antenna_sel_rx =
+       rt2x00dev->default_ant.rx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
 
        /*
@@ -1774,7 +1723,6 @@ static void rt2500pci_configure_filter(struct ieee80211_hw *hw,
                                       struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u32 reg;
 
        /*
@@ -1793,22 +1741,19 @@ static void rt2500pci_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
         */
        if (mc_count)
                *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * Start configuration steps.
@@ -1890,7 +1835,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
        .configure_filter       = rt2500pci_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt2500pci_set_retry_limit,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt2500pci_get_tsf,
@@ -1904,6 +1849,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
        .probe_hw               = rt2500pci_probe_hw,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
+       .init_rxentry           = rt2500pci_init_rxentry,
+       .init_txentry           = rt2500pci_init_txentry,
        .set_device_state       = rt2500pci_set_device_state,
        .rfkill_poll            = rt2500pci_rfkill_poll,
        .link_stats             = rt2500pci_link_stats,
@@ -1921,7 +1868,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt2500pci_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -1949,7 +1896,7 @@ MODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver rt2500pci_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt2500pci_device_table,
        .probe          = rt2x00pci_probe,
        .remove         = __devexit_p(rt2x00pci_remove),
index d92aa56b2f4b01f54fcea7feec61ca347717341d..92ba0902d107254725cbb0b6c230b2e1acbc57f4 100644 (file)
 /*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE                  ( 11 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE                  ( 11 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE                  ( 11 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 11 * sizeof(__le32) )
 
 /*
  * TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
index 18b1f9145389975df1b28e5b8a1064b34b3e6aff..86ded4066f5bbcc6e9d466b800b994ce329162ad 100644 (file)
        Supported chipsets: RT2570.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2500usb"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
  * 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.
+ * If the usb_cache_mutex is already held then the _lock variants must
+ * be used instead.
  */
-static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
                                           const unsigned int offset,
                                           u16 *value)
 {
@@ -64,8 +61,18 @@ static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev,
        *value = le16_to_cpu(reg);
 }
 
-static inline void rt2500usb_register_multiread(const struct rt2x00_dev
-                                               *rt2x00dev,
+static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+                                               const unsigned int offset,
+                                               u16 *value)
+{
+       __le16 reg;
+       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
+                                      USB_VENDOR_REQUEST_IN, offset,
+                                      &reg, sizeof(u16), REGISTER_TIMEOUT);
+       *value = le16_to_cpu(reg);
+}
+
+static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
                                                const unsigned int offset,
                                                void *value, const u16 length)
 {
@@ -75,7 +82,7 @@ static inline void rt2500usb_register_multiread(const struct rt2x00_dev
                                      value, length, timeout);
 }
 
-static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
                                            const unsigned int offset,
                                            u16 value)
 {
@@ -85,8 +92,17 @@ static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev,
                                      &reg, sizeof(u16), REGISTER_TIMEOUT);
 }
 
-static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev
-                                                *rt2x00dev,
+static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+                                                const unsigned int offset,
+                                                u16 value)
+{
+       __le16 reg = cpu_to_le16(value);
+       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
+                                      USB_VENDOR_REQUEST_OUT, offset,
+                                      &reg, sizeof(u16), REGISTER_TIMEOUT);
+}
+
+static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
                                                 const unsigned int offset,
                                                 void *value, const u16 length)
 {
@@ -96,13 +112,13 @@ static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev
                                      value, length, timeout);
 }
 
-static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev)
 {
        u16 reg;
        unsigned int i;
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2500usb_register_read(rt2x00dev, PHY_CSR8, &reg);
+               rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, &reg);
                if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY))
                        break;
                udelay(REGISTER_BUSY_DELAY);
@@ -111,17 +127,20 @@ static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
        return reg;
 }
 
-static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, const u8 value)
 {
        u16 reg;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt2500usb_bbp_check(rt2x00dev);
        if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
                ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
+               mutex_unlock(&rt2x00dev->usb_cache_mutex);
                return;
        }
 
@@ -133,14 +152,18 @@ static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
        rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 0);
 
-       rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg);
+       rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
+
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
-static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u8 *value)
 {
        u16 reg;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
@@ -157,7 +180,7 @@ static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
        rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 1);
 
-       rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg);
+       rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
 
        /*
         * Wait until the BBP becomes ready.
@@ -166,14 +189,17 @@ static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
        if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
                ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
                *value = 0xff;
+               mutex_unlock(&rt2x00dev->usb_cache_mutex);
                return;
        }
 
-       rt2500usb_register_read(rt2x00dev, PHY_CSR7, &reg);
+       rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
        *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
+
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
-static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, const u32 value)
 {
        u16 reg;
@@ -182,20 +208,23 @@ static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt2500usb_register_read(rt2x00dev, PHY_CSR10, &reg);
+               rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
                if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY))
                        goto rf_write;
                udelay(REGISTER_BUSY_DELAY);
        }
 
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
        ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
        return;
 
 rf_write:
        reg = 0;
        rt2x00_set_field16(&reg, PHY_CSR9_RF_VALUE, value);
-       rt2500usb_register_write(rt2x00dev, PHY_CSR9, reg);
+       rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg);
 
        reg = 0;
        rt2x00_set_field16(&reg, PHY_CSR10_RF_VALUE, value >> 16);
@@ -203,20 +232,22 @@ rf_write:
        rt2x00_set_field16(&reg, PHY_CSR10_RF_IF_SELECT, 0);
        rt2x00_set_field16(&reg, PHY_CSR10_RF_BUSY, 1);
 
-       rt2500usb_register_write(rt2x00dev, PHY_CSR10, reg);
+       rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
+
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 #define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u16)) )
 
-static void rt2500usb_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_read_csr(struct rt2x00_dev *rt2x00dev,
                               const unsigned int word, u32 *data)
 {
        rt2500usb_register_read(rt2x00dev, CSR_OFFSET(word), (u16 *) data);
 }
 
-static void rt2500usb_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt2500usb_write_csr(struct rt2x00_dev *rt2x00dev,
                                const unsigned int word, u32 data)
 {
        rt2500usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
@@ -296,7 +327,8 @@ static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type,
 
        rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
        rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
-       rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
+       rt2x00_set_field16(&reg, TXRX_CSR19_TBCN,
+                          (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
        rt2x00_set_field16(&reg, TXRX_CSR19_TSF_SYNC, tsf_sync);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
@@ -385,7 +417,7 @@ static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                    const int antenna_tx, const int antenna_rx)
+                                    struct antenna_setup *ant)
 {
        u8 r2;
        u8 r14;
@@ -400,8 +432,7 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the TX antenna.
         */
-       switch (antenna_tx) {
-       case ANTENNA_SW_DIVERSITY:
+       switch (ant->tx) {
        case ANTENNA_HW_DIVERSITY:
                rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1);
                rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 1);
@@ -412,6 +443,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
                rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0);
                rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
                rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2);
@@ -422,14 +460,20 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
        /*
         * Configure the RX antenna.
         */
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
                rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1);
                break;
        case ANTENNA_A:
                rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
                rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
                break;
@@ -487,9 +531,7 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
                rt2500usb_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
        if (flags & CONFIG_UPDATE_ANTENNA)
-               rt2500usb_config_antenna(rt2x00dev,
-                                        libconf->conf->antenna_sel_tx,
-                                        libconf->conf->antenna_sel_rx);
+               rt2500usb_config_antenna(rt2x00dev, &libconf->ant);
        if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
                rt2500usb_config_duration(rt2x00dev, libconf);
 }
@@ -507,18 +549,10 @@ static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev)
        rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg);
 
        rt2500usb_register_read(rt2x00dev, MAC_CSR20, &reg);
-
-       if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) {
-               rt2x00_set_field16(&reg, MAC_CSR20_LINK, 1);
-               rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, 0);
-       } else if (rt2x00dev->led_mode == LED_MODE_ASUS) {
-               rt2x00_set_field16(&reg, MAC_CSR20_LINK, 0);
-               rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, 1);
-       } else {
-               rt2x00_set_field16(&reg, MAC_CSR20_LINK, 1);
-               rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY, 1);
-       }
-
+       rt2x00_set_field16(&reg, MAC_CSR20_LINK,
+                          (rt2x00dev->led_mode != LED_MODE_ASUS));
+       rt2x00_set_field16(&reg, MAC_CSR20_ACTIVITY,
+                          (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY));
        rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg);
 }
 
@@ -535,7 +569,8 @@ static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev)
 /*
  * Link tuning
  */
-static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
 {
        u16 reg;
 
@@ -543,14 +578,13 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev)
         * Update FCS error count from register.
         */
        rt2500usb_register_read(rt2x00dev, STA_CSR0, &reg);
-       rt2x00dev->link.rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2500usb_register_read(rt2x00dev, STA_CSR3, &reg);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR);
 }
 
 static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -673,10 +707,10 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
        if (r17 > up_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, up_bound);
                rt2x00dev->link.vgc_level = up_bound;
-       } else if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, ++r17);
                rt2x00dev->link.vgc_level = r17;
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                rt2500usb_bbp_write(rt2x00dev, 17, --r17);
                rt2x00dev->link.vgc_level = r17;
        }
@@ -755,9 +789,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
 
        if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
                rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
-               reg &= ~0x0002;
+               rt2x00_set_field16(&reg, PHY_CSR2_LNA, 0);
        } else {
-               reg = 0x3002;
+               reg = 0;
+               rt2x00_set_field16(&reg, PHY_CSR2_LNA, 1);
+               rt2x00_set_field16(&reg, PHY_CSR2_LNA_MODE, 3);
        }
        rt2500usb_register_write(rt2x00dev, PHY_CSR2, reg);
 
@@ -884,8 +920,6 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev)
                return -EIO;
        }
 
-       rt2x00usb_enable_radio(rt2x00dev);
-
        /*
         * Enable LED
         */
@@ -988,12 +1022,12 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                   struct data_desc *txd,
+                                   struct sk_buff *skb,
                                    struct txdata_entry_desc *desc,
-                                   struct ieee80211_hdr *ieee80211hdr,
-                                   unsigned int length,
                                    struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
@@ -1018,7 +1052,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
@@ -1026,7 +1060,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
                           !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT));
        rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE);
        rt2x00_desc_write(txd, 0, word);
 }
@@ -1079,10 +1113,10 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 static void rt2500usb_fill_rxdone(struct data_entry *entry,
                                  struct rxdata_entry_desc *desc)
 {
+       struct skb_desc *skbdesc = get_skb_desc(entry->skb);
        struct urb *urb = entry->priv;
-       struct data_desc *rxd = (struct data_desc *)(entry->skb->data +
-                                                    (urb->actual_length -
-                                                     entry->ring->desc_size));
+       __le32 *rxd = (__le32 *)(entry->skb->data +
+                                (urb->actual_length - entry->ring->desc_size));
        u32 word0;
        u32 word1;
 
@@ -1103,8 +1137,15 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry,
            entry->ring->rt2x00dev->rssi_offset;
        desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 
-       return;
+       /*
+        * Set descriptor and data pointer.
+        */
+       skbdesc->desc = entry->skb->data + desc->size;
+       skbdesc->desc_len = entry->ring->desc_size;
+       skbdesc->data = entry->skb->data;
+       skbdesc->data_len = desc->size;
 }
 
 /*
@@ -1163,9 +1204,12 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
        if (word == 0xffff) {
                rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+                                  ANTENNA_SW_DIVERSITY);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+                                  ANTENNA_SW_DIVERSITY);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE,
+                                  LED_MODE_DEFAULT);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522);
@@ -1275,11 +1319,22 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->hw->conf.antenna_sel_tx =
+       rt2x00dev->default_ant.tx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
-       rt2x00dev->hw->conf.antenna_sel_rx =
+       rt2x00dev->default_ant.rx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
 
+       /*
+        * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead.
+        * I am not 100% sure about this, but the legacy drivers do not
+        * indicate antenna swapping in software is required when
+        * diversity is enabled.
+        */
+       if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+               rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY;
+       if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+               rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY;
+
        /*
         * Store led mode, for correct led behaviour.
         */
@@ -1562,7 +1617,6 @@ static void rt2500usb_configure_filter(struct ieee80211_hw *hw,
                                       struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u16 reg;
 
        /*
@@ -1581,22 +1635,19 @@ static void rt2500usb_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
         */
        if (mc_count)
                *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * When in atomic context, reschedule and let rt2x00lib
@@ -1638,8 +1689,8 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct usb_device *usb_dev =
            interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
-       struct data_ring *ring =
-           rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+       struct skb_desc *desc;
+       struct data_ring *ring;
        struct data_entry *beacon;
        struct data_entry *guardian;
        int pipe = usb_sndbulkpipe(usb_dev, 1);
@@ -1651,6 +1702,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
 
        /*
         * Obtain 2 entries, one for the guardian byte,
@@ -1661,23 +1713,34 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
        beacon = rt2x00_get_data_entry(ring);
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
         */
        skb_push(skb, ring->desc_size);
        memset(skb->data, 0, ring->desc_size);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        ring->desc_size),
-                               skb->len - ring->desc_size, control);
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = beacon;
+
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
+       /*
+        * USB devices cannot blindly pass the skb->len as the
+        * length of the data to usb_fill_bulk_urb. Pass the skb
+        * to the driver to determine what the length should be.
+        */
        length = rt2500usb_get_tx_data_len(rt2x00dev, skb);
 
        usb_fill_bulk_urb(beacon->priv, usb_dev, pipe,
                          skb->data, length, rt2500usb_beacondone, beacon);
 
-       beacon->skb = skb;
-
        /*
         * Second we need to create the guardian byte.
         * We only need a single byte, so lets recycle
@@ -1710,7 +1773,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
        .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2500usb_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .beacon_update          = rt2500usb_beacon_update,
@@ -1720,6 +1783,8 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
        .probe_hw               = rt2500usb_probe_hw,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
+       .init_rxentry           = rt2x00usb_init_rxentry,
+       .init_txentry           = rt2x00usb_init_txentry,
        .set_device_state       = rt2500usb_set_device_state,
        .link_stats             = rt2500usb_link_stats,
        .reset_tuner            = rt2500usb_reset_tuner,
@@ -1737,7 +1802,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt2500usb_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -1809,7 +1874,7 @@ MODULE_DEVICE_TABLE(usb, rt2500usb_device_table);
 MODULE_LICENSE("GPL");
 
 static struct usb_driver rt2500usb_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt2500usb_device_table,
        .probe          = rt2x00usb_probe,
        .disconnect     = rt2x00usb_disconnect,
index b18d56e73cf1cf8c5a5ed7d2316bf9f67e8802d1..9e0433722e3d713baee398f2a63ca2777ee19522 100644 (file)
 
 /*
  * MAC configuration registers.
+ */
+
+/*
  * PHY_CSR2: TX MAC configuration.
- * PHY_CSR3: RX MAC configuration.
+ * NOTE: Both register fields are complete dummy,
+ * documentation and legacy drivers are unclear un
+ * what this register means or what fields exists.
  */
 #define PHY_CSR2                       0x04c4
+#define PHY_CSR2_LNA                   FIELD16(0x0002)
+#define PHY_CSR2_LNA_MODE              FIELD16(0x3000)
+
+/*
+ * PHY_CSR3: RX MAC configuration.
+ */
 #define PHY_CSR3                       0x04c6
 
 /*
 /*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE                  ( 5 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE                  ( 4 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE                  ( 5 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 4 * sizeof(__le32) )
 
 /*
  * TX descriptor format for TX, PRIO, ATIM and Beacon Ring.
index c8f16f161c285e5a90069f797fc980a648a465b0..05927b908f80d12ee54b035200509bc687238e9b 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/skbuff.h>
 #include <linux/workqueue.h>
 #include <linux/firmware.h>
+#include <linux/mutex.h>
+#include <linux/etherdevice.h>
 
 #include <net/mac80211.h>
 
@@ -40,9 +42,8 @@
 
 /*
  * Module information.
- * DRV_NAME should be set within the individual module source files.
  */
-#define DRV_VERSION    "2.0.10"
+#define DRV_VERSION    "2.0.14"
 #define DRV_PROJECT    "http://rt2x00.serialmonkey.com"
 
 /*
@@ -55,7 +56,7 @@
 
 #define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \
        printk(__kernlvl "%s -> %s: %s - " __msg,               \
-              DRV_NAME, __FUNCTION__, __lvl, ##__args)
+              KBUILD_MODNAME, __FUNCTION__, __lvl, ##__args)
 
 #ifdef CONFIG_RT2X00_DEBUG
 #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...)        \
  */
 static inline int is_rts_frame(u16 fc)
 {
-       return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
-                 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
+       return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
+               ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS));
 }
 
 static inline int is_cts_frame(u16 fc)
 {
-       return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
-                 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
+       return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
+               ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS));
 }
 
 static inline int is_probe_resp(u16 fc)
 {
-       return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
-                 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
+       return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
+               ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP));
+}
+
+static inline int is_beacon(u16 fc)
+{
+       return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
+               ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON));
 }
 
 /*
@@ -180,18 +187,17 @@ struct rf_channel {
 };
 
 /*
- * To optimize the quality of the link we need to store
- * the quality of received frames and periodically
- * optimize the link.
+ * Antenna setup values.
  */
-struct link {
-       /*
-        * Link tuner counter
-        * The number of times the link has been tuned
-        * since the radio has been switched on.
-        */
-       u32 count;
+struct antenna_setup {
+       enum antenna rx;
+       enum antenna tx;
+};
 
+/*
+ * Quality statistics about the currently active link.
+ */
+struct link_qual {
        /*
         * Statistics required for Link tuning.
         * For the average RSSI value we use the "Walking average" approach.
@@ -211,7 +217,6 @@ struct link {
         * the new values correctly allowing a effective link tuning.
         */
        int avg_rssi;
-       int vgc_level;
        int false_cca;
 
        /*
@@ -240,6 +245,72 @@ struct link {
 #define WEIGHT_RSSI    20
 #define WEIGHT_RX      40
 #define WEIGHT_TX      40
+};
+
+/*
+ * Antenna settings about the currently active link.
+ */
+struct link_ant {
+       /*
+        * Antenna flags
+        */
+       unsigned int flags;
+#define ANTENNA_RX_DIVERSITY   0x00000001
+#define ANTENNA_TX_DIVERSITY   0x00000002
+#define ANTENNA_MODE_SAMPLE    0x00000004
+
+       /*
+        * Currently active TX/RX antenna setup.
+        * When software diversity is used, this will indicate
+        * which antenna is actually used at this time.
+        */
+       struct antenna_setup active;
+
+       /*
+        * RSSI information for the different antenna's.
+        * These statistics are used to determine when
+        * to switch antenna when using software diversity.
+        *
+        *        rssi[0] -> Antenna A RSSI
+        *        rssi[1] -> Antenna B RSSI
+        */
+       int rssi_history[2];
+
+       /*
+        * Current RSSI average of the currently active antenna.
+        * Similar to the avg_rssi in the link_qual structure
+        * this value is updated by using the walking average.
+        */
+       int rssi_ant;
+};
+
+/*
+ * To optimize the quality of the link we need to store
+ * the quality of received frames and periodically
+ * optimize the link.
+ */
+struct link {
+       /*
+        * Link tuner counter
+        * The number of times the link has been tuned
+        * since the radio has been switched on.
+        */
+       u32 count;
+
+       /*
+        * Quality measurement values.
+        */
+       struct link_qual qual;
+
+       /*
+        * TX/RX antenna setup.
+        */
+       struct link_ant ant;
+
+       /*
+        * Active VGC level
+        */
+       int vgc_level;
 
        /*
         * Work structure for scheduling periodic link tuning.
@@ -248,36 +319,47 @@ struct link {
 };
 
 /*
- * Clear all counters inside the link structure.
- * This can be easiest achieved by memsetting everything
- * except for the work structure at the end.
+ * Small helper macro to work with moving/walking averages.
  */
-static inline void rt2x00_clear_link(struct link *link)
-{
-       memset(link, 0x00, sizeof(*link) - sizeof(link->work));
-       link->rx_percentage = 50;
-       link->tx_percentage = 50;
-}
+#define MOVING_AVERAGE(__avg, __val, __samples) \
+       ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) )
 
 /*
- * Update the rssi using the walking average approach.
+ * When we lack RSSI information return something less then -80 to
+ * tell the driver to tune the device to maximum sensitivity.
  */
-static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
-{
-       if (!link->avg_rssi)
-               link->avg_rssi = rssi;
-       else
-               link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8;
-}
+#define DEFAULT_RSSI   ( -128 )
 
 /*
- * When the avg_rssi is unset or no frames  have been received),
- * we need to return the default value which needs to be less
- * than -80 so the device will select the maximum sensitivity.
+ * Link quality access functions.
  */
 static inline int rt2x00_get_link_rssi(struct link *link)
 {
-       return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128;
+       if (link->qual.avg_rssi && link->qual.rx_success)
+               return link->qual.avg_rssi;
+       return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_get_link_ant_rssi(struct link *link)
+{
+       if (link->ant.rssi_ant && link->qual.rx_success)
+               return link->ant.rssi_ant;
+       return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_get_link_ant_rssi_history(struct link *link,
+                                                  enum antenna ant)
+{
+       if (link->ant.rssi_history[ant - ANTENNA_A])
+               return link->ant.rssi_history[ant - ANTENNA_A];
+       return DEFAULT_RSSI;
+}
+
+static inline int rt2x00_update_ant_rssi(struct link *link, int rssi)
+{
+       int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A];
+       link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi;
+       return old_rssi;
 }
 
 /*
@@ -290,14 +372,12 @@ struct interface {
         * to us by the 80211 stack, and is used to request
         * new beacons.
         */
-       int id;
+       struct ieee80211_vif *id;
 
        /*
         * Current working type (IEEE80211_IF_TYPE_*).
-        * When set to INVALID_INTERFACE, no interface is configured.
         */
        int type;
-#define INVALID_INTERFACE      IEEE80211_IF_TYPE_INVALID
 
        /*
         * MAC of the device.
@@ -308,11 +388,6 @@ struct interface {
         * BBSID of the AP to associate with.
         */
        u8 bssid[ETH_ALEN];
-
-       /*
-        * Store the packet filter mode for the current interface.
-        */
-       unsigned int filter;
 };
 
 static inline int is_interface_present(struct interface *intf)
@@ -362,6 +437,8 @@ struct rt2x00lib_conf {
        struct ieee80211_conf *conf;
        struct rf_channel rf;
 
+       struct antenna_setup ant;
+
        int phymode;
 
        int basic_rates;
@@ -396,13 +473,22 @@ struct rt2x00lib_ops {
        int (*initialize) (struct rt2x00_dev *rt2x00dev);
        void (*uninitialize) (struct rt2x00_dev *rt2x00dev);
 
+       /*
+        * Ring initialization handlers
+        */
+       void (*init_rxentry) (struct rt2x00_dev *rt2x00dev,
+                             struct data_entry *entry);
+       void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
+                             struct data_entry *entry);
+
        /*
         * Radio control handlers.
         */
        int (*set_device_state) (struct rt2x00_dev *rt2x00dev,
                                 enum dev_state state);
        int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev);
-       void (*link_stats) (struct rt2x00_dev *rt2x00dev);
+       void (*link_stats) (struct rt2x00_dev *rt2x00dev,
+                           struct link_qual *qual);
        void (*reset_tuner) (struct rt2x00_dev *rt2x00dev);
        void (*link_tuner) (struct rt2x00_dev *rt2x00dev);
 
@@ -410,10 +496,8 @@ struct rt2x00lib_ops {
         * TX control handlers
         */
        void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
-                              struct data_desc *txd,
+                              struct sk_buff *skb,
                               struct txdata_entry_desc *desc,
-                              struct ieee80211_hdr *ieee80211hdr,
-                              unsigned int length,
                               struct ieee80211_tx_control *control);
        int (*write_tx_data) (struct rt2x00_dev *rt2x00dev,
                              struct data_ring *ring, struct sk_buff *skb,
@@ -545,7 +629,7 @@ struct rt2x00_dev {
         * required for deregistration of debugfs.
         */
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
-       const struct rt2x00debug_intf *debugfs_intf;
+       struct rt2x00debug_intf *debugfs_intf;
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
        /*
@@ -565,6 +649,13 @@ struct rt2x00_dev {
         */
        struct hw_mode_spec spec;
 
+       /*
+        * This is the default TX/RX antenna setup as indicated
+        * by the device's EEPROM. When mac80211 sets its
+        * antenna value to 0 we should be using these values.
+        */
+       struct antenna_setup default_ant;
+
        /*
         * Register pointers
         * csr_addr: Base register address. (PCI)
@@ -573,6 +664,25 @@ struct rt2x00_dev {
        void __iomem *csr_addr;
        void *csr_cache;
 
+       /*
+        * Mutex to protect register accesses on USB devices.
+        * There are 2 reasons this is needed, one is to ensure
+        * use of the csr_cache (for USB devices) by one thread
+        * isn't corrupted by another thread trying to access it.
+        * The other is that access to BBP and RF registers
+        * require multiple BUS transactions and if another thread
+        * attempted to access one of those registers at the same
+        * time one of the writes could silently fail.
+        */
+       struct mutex usb_cache_mutex;
+
+       /*
+        * Current packet filter configuration for the device.
+        * This contains all currently active FIF_* flags send
+        * to us by mac80211 during configure_filter().
+        */
+       unsigned int packet_filter;
+
        /*
         * Interface configuration.
         */
@@ -697,13 +807,13 @@ struct rt2x00_dev {
  * Generic RF access.
  * The RF is being accessed by word index.
  */
-static inline void rt2x00_rf_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
                                  const unsigned int word, u32 *data)
 {
        *data = rt2x00dev->rf[word];
 }
 
-static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
                                   const unsigned int word, u32 data)
 {
        rt2x00dev->rf[word] = data;
@@ -713,19 +823,19 @@ static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
  *  Generic EEPROM access.
  * The EEPROM is being accessed by word index.
  */
-static inline void *rt2x00_eeprom_addr(const struct rt2x00_dev *rt2x00dev,
+static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev,
                                       const unsigned int word)
 {
        return (void *)&rt2x00dev->eeprom[word];
 }
 
-static inline void rt2x00_eeprom_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev,
                                      const unsigned int word, u16 *data)
 {
        *data = le16_to_cpu(rt2x00dev->eeprom[word]);
 }
 
-static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev,
                                       const unsigned int word, u16 data)
 {
        rt2x00dev->eeprom[word] = cpu_to_le16(data);
@@ -804,9 +914,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            struct data_desc *txd,
-                            struct ieee80211_hdr *ieee80211hdr,
-                            unsigned int length,
+                            struct sk_buff *skb,
                             struct ieee80211_tx_control *control);
 
 /*
@@ -821,14 +929,17 @@ 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, struct ieee80211_conf *conf);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
+int rt2x00mac_config_interface(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
                               struct ieee80211_if_conf *conf);
 int rt2x00mac_get_stats(struct ieee80211_hw *hw,
                        struct ieee80211_low_level_stats *stats);
 int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
                           struct ieee80211_tx_queue_stats *stats);
-void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
-                             int cts_protection, int preamble);
+void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_bss_conf *bss_conf,
+                               u32 changes);
 int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
                      const struct ieee80211_tx_queue_params *params);
 
index 12914cf7156cb4fc6582dd6cbfe06b96ed4fb4bb..72cfe00c1ed7385834e2574fe1e24349785d7dd2 100644 (file)
        Abstract: rt2x00 generic configuration routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 
@@ -94,12 +89,44 @@ void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type)
        rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync);
 }
 
+void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
+                             enum antenna rx, enum antenna tx)
+{
+       struct rt2x00lib_conf libconf;
+
+       libconf.ant.rx = rx;
+       libconf.ant.tx = tx;
+
+       /*
+        * Antenna setup changes require the RX to be disabled,
+        * else the changes will be ignored by the device.
+        */
+       if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
+
+       /*
+        * Write new antenna setup to device and reset the link tuner.
+        * The latter is required since we need to recalibrate the
+        * noise-sensitivity ratio for the new setup.
+        */
+       rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf);
+       rt2x00lib_reset_link_tuner(rt2x00dev);
+
+       rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+       rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+
+       if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+               rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
+}
+
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                      struct ieee80211_conf *conf, const int force_config)
 {
        struct rt2x00lib_conf libconf;
        struct ieee80211_hw_mode *mode;
        struct ieee80211_rate *rate;
+       struct antenna_setup *default_ant = &rt2x00dev->default_ant;
+       struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
        int flags = 0;
        int short_slot_time;
 
@@ -122,7 +149,39 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                flags |= CONFIG_UPDATE_CHANNEL;
        if (rt2x00dev->tx_power != conf->power_level)
                flags |= CONFIG_UPDATE_TXPOWER;
-       if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx)
+
+       /*
+        * Determining changes in the antenna setups request several checks:
+        * antenna_sel_{r,t}x = 0
+        *    -> Does active_{r,t}x match default_{r,t}x
+        *    -> Is default_{r,t}x SW_DIVERSITY
+        * antenna_sel_{r,t}x = 1/2
+        *    -> Does active_{r,t}x match antenna_sel_{r,t}x
+        * The reason for not updating the antenna while SW diversity
+        * should be used is simple: Software diversity means that
+        * we should switch between the antenna's based on the
+        * quality. This means that the current antenna is good enough
+        * to work with untill the link tuner decides that an antenna
+        * switch should be performed.
+        */
+       if (!conf->antenna_sel_rx &&
+           default_ant->rx != ANTENNA_SW_DIVERSITY &&
+           default_ant->rx != active_ant->rx)
+               flags |= CONFIG_UPDATE_ANTENNA;
+       else if (conf->antenna_sel_rx &&
+                conf->antenna_sel_rx != active_ant->rx)
+               flags |= CONFIG_UPDATE_ANTENNA;
+       else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
+               flags |= CONFIG_UPDATE_ANTENNA;
+
+       if (!conf->antenna_sel_tx &&
+           default_ant->tx != ANTENNA_SW_DIVERSITY &&
+           default_ant->tx != active_ant->tx)
+               flags |= CONFIG_UPDATE_ANTENNA;
+       else if (conf->antenna_sel_tx &&
+                conf->antenna_sel_tx != active_ant->tx)
+               flags |= CONFIG_UPDATE_ANTENNA;
+       else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
                flags |= CONFIG_UPDATE_ANTENNA;
 
        /*
@@ -171,6 +230,22 @@ config:
                       sizeof(libconf.rf));
        }
 
+       if (flags & CONFIG_UPDATE_ANTENNA) {
+               if (conf->antenna_sel_rx)
+                       libconf.ant.rx = conf->antenna_sel_rx;
+               else if (default_ant->rx != ANTENNA_SW_DIVERSITY)
+                       libconf.ant.rx = default_ant->rx;
+               else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
+                       libconf.ant.rx = ANTENNA_B;
+
+               if (conf->antenna_sel_tx)
+                       libconf.ant.tx = conf->antenna_sel_tx;
+               else if (default_ant->tx != ANTENNA_SW_DIVERSITY)
+                       libconf.ant.tx = default_ant->tx;
+               else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
+                       libconf.ant.tx = ANTENNA_B;
+       }
+
        if (flags & CONFIG_UPDATE_SLOT_TIME) {
                short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME;
 
@@ -196,10 +271,17 @@ config:
        if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA))
                rt2x00lib_reset_link_tuner(rt2x00dev);
 
-       rt2x00dev->curr_hwmode = libconf.phymode;
-       rt2x00dev->rx_status.phymode = conf->phymode;
+       if (flags & CONFIG_UPDATE_PHYMODE) {
+               rt2x00dev->curr_hwmode = libconf.phymode;
+               rt2x00dev->rx_status.phymode = conf->phymode;
+       }
+
        rt2x00dev->rx_status.freq = conf->freq;
        rt2x00dev->rx_status.channel = conf->channel;
        rt2x00dev->tx_power = conf->power_level;
-       rt2x00dev->rx_status.antenna = conf->antenna_sel_rx;
+
+       if (flags & CONFIG_UPDATE_ANTENNA) {
+               rt2x00dev->link.ant.active.rx = libconf.ant.rx;
+               rt2x00dev->link.ant.active.tx = libconf.ant.tx;
+       }
 }
index 9275d6f9517e32c714a179923f2b162c157cbd8a..b44a9f4b9b7f85ba776f81cd2d764497ac73f2f7 100644 (file)
        Abstract: rt2x00 debugfs specific routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/poll.h>
 #include <linux/uaccess.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
+#include "rt2x00dump.h"
 
 #define PRINT_LINE_LEN_MAX 32
 
@@ -55,18 +52,22 @@ struct rt2x00debug_intf {
        /*
         * Debugfs entries for:
         * - driver folder
-        * - driver file
-        * - chipset file
-        * - device flags file
-        * - register offset/value files
-        * - eeprom offset/value files
-        * - bbp offset/value files
-        * - rf offset/value files
+        *   - driver file
+        *   - chipset file
+        *   - device flags file
+        *   - register folder
+        *     - csr offset/value files
+        *     - eeprom offset/value files
+        *     - bbp offset/value files
+        *     - rf offset/value files
+        *   - frame dump folder
+        *     - frame dump file
         */
        struct dentry *driver_folder;
        struct dentry *driver_entry;
        struct dentry *chipset_entry;
        struct dentry *dev_flags;
+       struct dentry *register_folder;
        struct dentry *csr_off_entry;
        struct dentry *csr_val_entry;
        struct dentry *eeprom_off_entry;
@@ -75,6 +76,24 @@ struct rt2x00debug_intf {
        struct dentry *bbp_val_entry;
        struct dentry *rf_off_entry;
        struct dentry *rf_val_entry;
+       struct dentry *frame_folder;
+       struct dentry *frame_dump_entry;
+
+       /*
+        * The frame dump file only allows a single reader,
+        * so we need to store the current state here.
+        */
+       unsigned long frame_dump_flags;
+#define FRAME_DUMP_FILE_OPEN   1
+
+       /*
+        * We queue each frame before dumping it to the user,
+        * per read command we will pass a single skb structure
+        * so we should be prepared to queue multiple sk buffers
+        * before sending it to userspace.
+        */
+       struct sk_buff_head frame_dump_skbqueue;
+       wait_queue_head_t frame_dump_waitqueue;
 
        /*
         * Driver and chipset files will use a data buffer
@@ -93,6 +112,59 @@ struct rt2x00debug_intf {
        unsigned int offset_rf;
 };
 
+void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+                           struct sk_buff *skb)
+{
+       struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
+       struct skb_desc *desc = get_skb_desc(skb);
+       struct sk_buff *skbcopy;
+       struct rt2x00dump_hdr *dump_hdr;
+       struct timeval timestamp;
+
+       do_gettimeofday(&timestamp);
+
+       if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
+               return;
+
+       if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) {
+               DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n");
+               return;
+       }
+
+       skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len,
+                           GFP_ATOMIC);
+       if (!skbcopy) {
+               DEBUG(rt2x00dev, "Failed to copy skb for dump.\n");
+               return;
+       }
+
+       dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr));
+       dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION);
+       dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr));
+       dump_hdr->desc_length = cpu_to_le32(desc->desc_len);
+       dump_hdr->data_length = cpu_to_le32(desc->data_len);
+       dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt);
+       dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
+       dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev);
+       dump_hdr->type = cpu_to_le16(desc->frame_type);
+       dump_hdr->ring_index = desc->ring->queue_idx;
+       dump_hdr->entry_index = desc->entry->entry_idx;
+       dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
+       dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
+
+       memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len);
+       memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len);
+
+       skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy);
+       wake_up_interruptible(&intf->frame_dump_waitqueue);
+
+       /*
+        * Verify that the file has not been closed while we were working.
+        */
+       if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags))
+               skb_queue_purge(&intf->frame_dump_skbqueue);
+}
+
 static int rt2x00debug_file_open(struct inode *inode, struct file *file)
 {
        struct rt2x00debug_intf *intf = inode->i_private;
@@ -114,13 +186,96 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file)
        return 0;
 }
 
+static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file)
+{
+       struct rt2x00debug_intf *intf = inode->i_private;
+       int retval;
+
+       retval = rt2x00debug_file_open(inode, file);
+       if (retval)
+               return retval;
+
+       if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) {
+               rt2x00debug_file_release(inode, file);
+               return -EBUSY;
+       }
+
+       return 0;
+}
+
+static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file)
+{
+       struct rt2x00debug_intf *intf = inode->i_private;
+
+       skb_queue_purge(&intf->frame_dump_skbqueue);
+
+       clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags);
+
+       return rt2x00debug_file_release(inode, file);
+}
+
+static ssize_t rt2x00debug_read_ring_dump(struct file *file,
+                                         char __user *buf,
+                                         size_t length,
+                                         loff_t *offset)
+{
+       struct rt2x00debug_intf *intf = file->private_data;
+       struct sk_buff *skb;
+       size_t status;
+       int retval;
+
+       if (file->f_flags & O_NONBLOCK)
+               return -EAGAIN;
+
+       retval =
+           wait_event_interruptible(intf->frame_dump_waitqueue,
+                                    (skb =
+                                    skb_dequeue(&intf->frame_dump_skbqueue)));
+       if (retval)
+               return retval;
+
+       status = min((size_t)skb->len, length);
+       if (copy_to_user(buf, skb->data, status)) {
+               status = -EFAULT;
+               goto exit;
+       }
+
+       *offset += status;
+
+exit:
+       kfree_skb(skb);
+
+       return status;
+}
+
+static unsigned int rt2x00debug_poll_ring_dump(struct file *file,
+                                              poll_table *wait)
+{
+       struct rt2x00debug_intf *intf = file->private_data;
+
+       poll_wait(file, &intf->frame_dump_waitqueue, wait);
+
+       if (!skb_queue_empty(&intf->frame_dump_skbqueue))
+               return POLLOUT | POLLWRNORM;
+
+       return 0;
+}
+
+static const struct file_operations rt2x00debug_fop_ring_dump = {
+       .owner          = THIS_MODULE,
+       .read           = rt2x00debug_read_ring_dump,
+       .poll           = rt2x00debug_poll_ring_dump,
+       .open           = rt2x00debug_open_ring_dump,
+       .release        = rt2x00debug_release_ring_dump,
+};
+
 #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type)       \
 static ssize_t rt2x00debug_read_##__name(struct file *file,    \
                                         char __user *buf,      \
                                         size_t length,         \
                                         loff_t *offset)        \
 {                                                              \
-       struct rt2x00debug_intf *intf = file->private_data;     \
+       struct rt2x00debug_intf *intf = file->private_data;     \
        const struct rt2x00debug *debug = intf->debug;          \
        char line[16];                                          \
        size_t size;                                            \
@@ -150,7 +305,7 @@ static ssize_t rt2x00debug_write_##__name(struct file *file,        \
                                          size_t length,        \
                                          loff_t *offset)       \
 {                                                              \
-       struct rt2x00debug_intf *intf = file->private_data;     \
+       struct rt2x00debug_intf *intf = file->private_data;     \
        const struct rt2x00debug *debug = intf->debug;          \
        char line[16];                                          \
        size_t size;                                            \
@@ -254,11 +409,15 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
        const struct rt2x00debug *debug = intf->debug;
        char *data;
 
-       data = kzalloc(4 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
+       data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL);
        if (!data)
                return NULL;
 
        blob->data = data;
+       data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt);
+       data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf);
+       data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev);
+       data += sprintf(data, "\n");
        data += sprintf(data, "csr length: %d\n", debug->csr.word_count);
        data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count);
        data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count);
@@ -306,12 +465,17 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
        if (IS_ERR(intf->dev_flags))
                goto exit;
 
-#define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name)             \
+       intf->register_folder =
+           debugfs_create_dir("register", intf->driver_folder);
+       if (IS_ERR(intf->register_folder))
+               goto exit;
+
+#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name)    \
 ({                                                             \
        (__intf)->__name##_off_entry =                          \
            debugfs_create_u32(__stringify(__name) "_offset",   \
                               S_IRUGO | S_IWUSR,               \
-                              (__intf)->driver_folder,         \
+                              (__intf)->register_folder,       \
                               &(__intf)->offset_##__name);     \
        if (IS_ERR((__intf)->__name##_off_entry))               \
                goto exit;                                      \
@@ -319,18 +483,32 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
        (__intf)->__name##_val_entry =                          \
            debugfs_create_file(__stringify(__name) "_value",   \
                                S_IRUGO | S_IWUSR,              \
-                               (__intf)->driver_folder,        \
+                               (__intf)->register_folder,      \
                                (__intf), &rt2x00debug_fop_##__name);\
        if (IS_ERR((__intf)->__name##_val_entry))               \
                goto exit;                                      \
 })
 
-       RT2X00DEBUGFS_CREATE_ENTRY(intf, csr);
-       RT2X00DEBUGFS_CREATE_ENTRY(intf, eeprom);
-       RT2X00DEBUGFS_CREATE_ENTRY(intf, bbp);
-       RT2X00DEBUGFS_CREATE_ENTRY(intf, rf);
+       RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
+       RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
+       RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
+       RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
 
-#undef RT2X00DEBUGFS_CREATE_ENTRY
+#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
+
+       intf->frame_folder =
+           debugfs_create_dir("frame", intf->driver_folder);
+       if (IS_ERR(intf->frame_folder))
+               goto exit;
+
+       intf->frame_dump_entry =
+           debugfs_create_file("dump", S_IRUGO, intf->frame_folder,
+                               intf, &rt2x00debug_fop_ring_dump);
+       if (IS_ERR(intf->frame_dump_entry))
+               goto exit;
+
+       skb_queue_head_init(&intf->frame_dump_skbqueue);
+       init_waitqueue_head(&intf->frame_dump_waitqueue);
 
        return;
 
@@ -343,11 +521,15 @@ exit:
 
 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
 {
-       const struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
+       struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
 
        if (unlikely(!intf))
                return;
 
+       skb_queue_purge(&intf->frame_dump_skbqueue);
+
+       debugfs_remove(intf->frame_dump_entry);
+       debugfs_remove(intf->frame_folder);
        debugfs_remove(intf->rf_val_entry);
        debugfs_remove(intf->rf_off_entry);
        debugfs_remove(intf->bbp_val_entry);
@@ -356,6 +538,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
        debugfs_remove(intf->eeprom_off_entry);
        debugfs_remove(intf->csr_val_entry);
        debugfs_remove(intf->csr_off_entry);
+       debugfs_remove(intf->register_folder);
        debugfs_remove(intf->dev_flags);
        debugfs_remove(intf->chipset_entry);
        debugfs_remove(intf->driver_entry);
index 860e8fa3a0da7a285c675206f28575692efb5bc1..d37efbd09c417c33372ed5cb6b46251e86e906dd 100644 (file)
@@ -30,9 +30,9 @@ struct rt2x00_dev;
 
 #define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type)           \
 struct reg##__name {                                           \
-       void (*read)(const struct rt2x00_dev *rt2x00dev,        \
+       void (*read)(struct rt2x00_dev *rt2x00dev,              \
                     const unsigned int word, __type *data);    \
-       void (*write)(const struct rt2x00_dev *rt2x00dev,       \
+       void (*write)(struct rt2x00_dev *rt2x00dev,             \
                      const unsigned int word, __type data);    \
                                                                \
        unsigned int word_size;                                 \
index ff399f8083e9c9cfcdd179250a0610453afb4885..c4be2ac4d7a407887d32e4569ff3baebbc126b48 100644 (file)
        Abstract: rt2x00 generic device routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
+#include "rt2x00dump.h"
 
 /*
  * Ring handler.
@@ -67,7 +63,21 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring);
  */
 static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
 {
-       rt2x00_clear_link(&rt2x00dev->link);
+       rt2x00dev->link.count = 0;
+       rt2x00dev->link.vgc_level = 0;
+
+       memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual));
+
+       /*
+        * The RX and TX percentage should start at 50%
+        * this will assure we will get at least get some
+        * decent value when the link tuner starts.
+        * The value will be dropped and overwritten with
+        * the correct (measured )value anyway during the
+        * first run of the link tuner.
+        */
+       rt2x00dev->link.qual.rx_percentage = 50;
+       rt2x00dev->link.qual.tx_percentage = 50;
 
        /*
         * Reset the link tuner.
@@ -92,6 +102,46 @@ void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
        rt2x00lib_start_link_tuner(rt2x00dev);
 }
 
+/*
+ * Ring initialization
+ */
+static void rt2x00lib_init_rxrings(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_ring *ring = rt2x00dev->rx;
+       unsigned int i;
+
+       if (!rt2x00dev->ops->lib->init_rxentry)
+               return;
+
+       if (ring->data_addr)
+               memset(ring->data_addr, 0, rt2x00_get_ring_size(ring));
+
+       for (i = 0; i < ring->stats.limit; i++)
+               rt2x00dev->ops->lib->init_rxentry(rt2x00dev, &ring->entry[i]);
+
+       rt2x00_ring_index_clear(ring);
+}
+
+static void rt2x00lib_init_txrings(struct rt2x00_dev *rt2x00dev)
+{
+       struct data_ring *ring;
+       unsigned int i;
+
+       if (!rt2x00dev->ops->lib->init_txentry)
+               return;
+
+       txringall_for_each(rt2x00dev, ring) {
+               if (ring->data_addr)
+                       memset(ring->data_addr, 0, rt2x00_get_ring_size(ring));
+
+               for (i = 0; i < ring->stats.limit; i++)
+                       rt2x00dev->ops->lib->init_txentry(rt2x00dev,
+                                                         &ring->entry[i]);
+
+               rt2x00_ring_index_clear(ring);
+       }
+}
+
 /*
  * Radio control handlers.
  */
@@ -107,6 +157,12 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
            test_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags))
                return 0;
 
+       /*
+        * Initialize all data rings.
+        */
+       rt2x00lib_init_rxrings(rt2x00dev);
+       rt2x00lib_init_txrings(rt2x00dev);
+
        /*
         * Enable radio.
         */
@@ -179,26 +235,153 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
                rt2x00lib_start_link_tuner(rt2x00dev);
 }
 
-static void rt2x00lib_precalculate_link_signal(struct link *link)
+static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev)
 {
-       if (link->rx_failed || link->rx_success)
-               link->rx_percentage =
-                   (link->rx_success * 100) /
-                   (link->rx_failed + link->rx_success);
+       enum antenna rx = rt2x00dev->link.ant.active.rx;
+       enum antenna tx = rt2x00dev->link.ant.active.tx;
+       int sample_a =
+           rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A);
+       int sample_b =
+           rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B);
+
+       /*
+        * We are done sampling. Now we should evaluate the results.
+        */
+       rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+
+       /*
+        * During the last period we have sampled the RSSI
+        * from both antenna's. It now is time to determine
+        * which antenna demonstrated the best performance.
+        * When we are already on the antenna with the best
+        * performance, then there really is nothing for us
+        * left to do.
+        */
+       if (sample_a == sample_b)
+               return;
+
+       if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) {
+               if (sample_a > sample_b && rx == ANTENNA_B)
+                       rx = ANTENNA_A;
+               else if (rx == ANTENNA_A)
+                       rx = ANTENNA_B;
+       }
+
+       if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) {
+               if (sample_a > sample_b && tx == ANTENNA_B)
+                       tx = ANTENNA_A;
+               else if (tx == ANTENNA_A)
+                       tx = ANTENNA_B;
+       }
+
+       rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+}
+
+static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev)
+{
+       enum antenna rx = rt2x00dev->link.ant.active.rx;
+       enum antenna tx = rt2x00dev->link.ant.active.tx;
+       int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link);
+       int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr);
+
+       /*
+        * Legacy driver indicates that we should swap antenna's
+        * when the difference in RSSI is greater that 5. This
+        * also should be done when the RSSI was actually better
+        * then the previous sample.
+        * When the difference exceeds the threshold we should
+        * sample the rssi from the other antenna to make a valid
+        * comparison between the 2 antennas.
+        */
+       if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5)
+               return;
+
+       rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE;
+
+       if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY)
+               rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+       if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)
+               tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
+
+       rt2x00lib_config_antenna(rt2x00dev, rx, tx);
+}
+
+static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev)
+{
+       /*
+        * Determine if software diversity is enabled for
+        * either the TX or RX antenna (or both).
+        * Always perform this check since within the link
+        * tuner interval the configuration might have changed.
+        */
+       rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
+       rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
+
+       if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
+           rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY)
+               rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
+       if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
+           rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY)
+               rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
+
+       if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&
+           !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) {
+               rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE;
+               return;
+       }
+
+       /*
+        * If we have only sampled the data over the last period
+        * we should now harvest the data. Otherwise just evaluate
+        * the data. The latter should only be performed once
+        * every 2 seconds.
+        */
+       if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE)
+               rt2x00lib_evaluate_antenna_sample(rt2x00dev);
+       else if (rt2x00dev->link.count & 1)
+               rt2x00lib_evaluate_antenna_eval(rt2x00dev);
+}
+
+static void rt2x00lib_update_link_stats(struct link *link, int rssi)
+{
+       int avg_rssi = rssi;
+
+       /*
+        * Update global RSSI
+        */
+       if (link->qual.avg_rssi)
+               avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8);
+       link->qual.avg_rssi = avg_rssi;
+
+       /*
+        * Update antenna RSSI
+        */
+       if (link->ant.rssi_ant)
+               rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8);
+       link->ant.rssi_ant = rssi;
+}
+
+static void rt2x00lib_precalculate_link_signal(struct link_qual *qual)
+{
+       if (qual->rx_failed || qual->rx_success)
+               qual->rx_percentage =
+                   (qual->rx_success * 100) /
+                   (qual->rx_failed + qual->rx_success);
        else
-               link->rx_percentage = 50;
+               qual->rx_percentage = 50;
 
-       if (link->tx_failed || link->tx_success)
-               link->tx_percentage =
-                   (link->tx_success * 100) /
-                   (link->tx_failed + link->tx_success);
+       if (qual->tx_failed || qual->tx_success)
+               qual->tx_percentage =
+                   (qual->tx_success * 100) /
+                   (qual->tx_failed + qual->tx_success);
        else
-               link->tx_percentage = 50;
+               qual->tx_percentage = 50;
 
-       link->rx_success = 0;
-       link->rx_failed = 0;
-       link->tx_success = 0;
-       link->tx_failed = 0;
+       qual->rx_success = 0;
+       qual->rx_failed = 0;
+       qual->tx_success = 0;
+       qual->tx_failed = 0;
 }
 
 static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
@@ -225,8 +408,8 @@ static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
         * defines to calculate the current link signal.
         */
        signal = ((WEIGHT_RSSI * rssi_percentage) +
-                 (WEIGHT_TX * rt2x00dev->link.tx_percentage) +
-                 (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100;
+                 (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) +
+                 (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100;
 
        return (signal > 100) ? 100 : signal;
 }
@@ -246,10 +429,9 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
        /*
         * Update statistics.
         */
-       rt2x00dev->ops->lib->link_stats(rt2x00dev);
-
+       rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual);
        rt2x00dev->low_level_stats.dot11FCSErrorCount +=
-           rt2x00dev->link.rx_failed;
+           rt2x00dev->link.qual.rx_failed;
 
        /*
         * Only perform the link tuning when Link tuning
@@ -258,11 +440,16 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
        if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags))
                rt2x00dev->ops->lib->link_tuner(rt2x00dev);
 
+       /*
+        * Evaluate antenna setup.
+        */
+       rt2x00lib_evaluate_antenna(rt2x00dev);
+
        /*
         * Precalculate a portion of the link signal which is
         * in based on the tx/rx success/failure counters.
         */
-       rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
+       rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual);
 
        /*
         * Increase tuner counter, and reschedule the next link tuner run.
@@ -276,7 +463,7 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
 {
        struct rt2x00_dev *rt2x00dev =
            container_of(work, struct rt2x00_dev, filter_work);
-       unsigned int filter = rt2x00dev->interface.filter;
+       unsigned int filter = rt2x00dev->packet_filter;
 
        /*
         * Since we had stored the filter inside interface.filter,
@@ -284,7 +471,7 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
         * assume nothing has changed (*total_flags will be compared
         * to interface.filter to determine if any action is required).
         */
-       rt2x00dev->interface.filter = 0;
+       rt2x00dev->packet_filter = 0;
 
        rt2x00dev->ops->hw->configure_filter(rt2x00dev->hw,
                                             filter, &filter, 0, NULL);
@@ -294,10 +481,17 @@ static void rt2x00lib_configuration_scheduled(struct work_struct *work)
 {
        struct rt2x00_dev *rt2x00dev =
            container_of(work, struct rt2x00_dev, config_work);
-       int preamble = !test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);
+       struct ieee80211_bss_conf bss_conf;
 
-       rt2x00mac_erp_ie_changed(rt2x00dev->hw,
-                                IEEE80211_ERP_CHANGE_PREAMBLE, 0, preamble);
+       bss_conf.use_short_preamble =
+               test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags);
+
+       /*
+        * FIXME: shouldn't invoke it this way because all other contents
+        *        of bss_conf is invalid.
+        */
+       rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id,
+                                  &bss_conf, BSS_CHANGED_ERP_PREAMBLE);
 }
 
 /*
@@ -350,8 +544,8 @@ void rt2x00lib_txdone(struct data_entry *entry,
        tx_status->ack_signal = 0;
        tx_status->excessive_retries = (status == TX_FAIL_RETRY);
        tx_status->retry_count = retry;
-       rt2x00dev->link.tx_success += success;
-       rt2x00dev->link.tx_failed += retry + fail;
+       rt2x00dev->link.qual.tx_success += success;
+       rt2x00dev->link.qual.tx_failed += retry + fail;
 
        if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) {
                if (success)
@@ -371,9 +565,11 @@ void rt2x00lib_txdone(struct data_entry *entry,
        }
 
        /*
-        * Send the tx_status to mac80211,
-        * that method also cleans up the skb structure.
+        * Send the tx_status to mac80211 & debugfs.
+        * mac80211 will clean up the skb structure.
         */
+       get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE;
+       rt2x00debug_dump_frame(rt2x00dev, entry->skb);
        ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status);
        entry->skb = NULL;
 }
@@ -386,8 +582,10 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
        struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
        struct ieee80211_hw_mode *mode;
        struct ieee80211_rate *rate;
+       struct ieee80211_hdr *hdr;
        unsigned int i;
        int val = 0;
+       u16 fc;
 
        /*
         * Update RX statistics.
@@ -412,17 +610,28 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
                }
        }
 
-       rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
-       rt2x00dev->link.rx_success++;
+       /*
+        * Only update link status if this is a beacon frame carrying our bssid.
+        */
+       hdr = (struct ieee80211_hdr*)skb->data;
+       fc = le16_to_cpu(hdr->frame_control);
+       if (is_beacon(fc) && desc->my_bss)
+               rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi);
+
+       rt2x00dev->link.qual.rx_success++;
+
        rx_status->rate = val;
        rx_status->signal =
            rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
        rx_status->ssi = desc->rssi;
        rx_status->flag = desc->flags;
+       rx_status->antenna = rt2x00dev->link.ant.active.rx;
 
        /*
-        * Send frame to mac80211
+        * Send frame to mac80211 & debugfs
         */
+       get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE;
+       rt2x00debug_dump_frame(rt2x00dev, skb);
        ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
@@ -431,36 +640,25 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                            struct data_desc *txd,
-                            struct ieee80211_hdr *ieee80211hdr,
-                            unsigned int length,
+                            struct sk_buff *skb,
                             struct ieee80211_tx_control *control)
 {
        struct txdata_entry_desc desc;
-       struct data_ring *ring;
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       struct ieee80211_hdr *ieee80211hdr = skbdesc->data;
        int tx_rate;
        int bitrate;
+       int length;
        int duration;
        int residual;
        u16 frame_control;
        u16 seq_ctrl;
 
-       /*
-        * Make sure the descriptor is properly cleared.
-        */
-       memset(&desc, 0x00, sizeof(desc));
+       memset(&desc, 0, sizeof(desc));
 
-       /*
-        * Get ring pointer, if we fail to obtain the
-        * correct ring, then use the first TX ring.
-        */
-       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
-       if (!ring)
-               ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-
-       desc.cw_min = ring->tx_params.cw_min;
-       desc.cw_max = ring->tx_params.cw_max;
-       desc.aifs = ring->tx_params.aifs;
+       desc.cw_min = skbdesc->ring->tx_params.cw_min;
+       desc.cw_max = skbdesc->ring->tx_params.cw_max;
+       desc.aifs = skbdesc->ring->tx_params.aifs;
 
        /*
         * Identify queue
@@ -481,13 +679,22 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 
        tx_rate = control->tx_rate;
 
+       /*
+        * Check whether this frame is to be acked
+        */
+       if (!(control->flags & IEEE80211_TXCTL_NO_ACK))
+               __set_bit(ENTRY_TXD_ACK, &desc.flags);
+
        /*
         * Check if this is a RTS/CTS frame
         */
        if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
                __set_bit(ENTRY_TXD_BURST, &desc.flags);
-               if (is_rts_frame(frame_control))
+               if (is_rts_frame(frame_control)) {
                        __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags);
+                       __set_bit(ENTRY_TXD_ACK, &desc.flags);
+               } else
+                       __clear_bit(ENTRY_TXD_ACK, &desc.flags);
                if (control->rts_cts_rate)
                        tx_rate = control->rts_cts_rate;
        }
@@ -532,17 +739,18 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP);
        desc.service = 0x04;
 
+       length = skbdesc->data_len + FCS_LEN;
        if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) {
-               desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f;
-               desc.length_low = ((length + FCS_LEN) & 0x3f);
+               desc.length_high = (length >> 6) & 0x3f;
+               desc.length_low = length & 0x3f;
        } else {
                bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE);
 
                /*
                 * Convert length to microseconds.
                 */
-               residual = get_duration_res(length + FCS_LEN, bitrate);
-               duration = get_duration(length + FCS_LEN, bitrate);
+               residual = get_duration_res(length, bitrate);
+               duration = get_duration(length, bitrate);
 
                if (residual != 0) {
                        duration++;
@@ -565,8 +773,22 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                        desc.signal |= 0x08;
        }
 
-       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc,
-                                          ieee80211hdr, length, control);
+       rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control);
+
+       /*
+        * Update ring entry.
+        */
+       skbdesc->entry->skb = skb;
+       memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control));
+
+       /*
+        * The frame has been completely initialized and ready
+        * for sending to the device. The caller will push the
+        * frame to the device, but we are going to push the
+        * frame to debugfs here.
+        */
+       skbdesc->frame_type = DUMP_FRAME_TX;
+       rt2x00debug_dump_frame(rt2x00dev, skb);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
 
@@ -809,6 +1031,7 @@ static int rt2x00lib_alloc_entries(struct data_ring *ring,
                entry[i].flags = 0;
                entry[i].ring = ring;
                entry[i].skb = NULL;
+               entry[i].entry_idx = i;
        }
 
        ring->entry = entry;
@@ -866,7 +1089,7 @@ static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev)
        }
 }
 
-void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
+static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
 {
        if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
                return;
@@ -887,7 +1110,7 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
        rt2x00lib_free_ring_entries(rt2x00dev);
 }
 
-int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
+static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
 {
        int status;
 
@@ -930,12 +1153,65 @@ exit:
        return status;
 }
 
+int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
+{
+       int retval;
+
+       if (test_bit(DEVICE_STARTED, &rt2x00dev->flags))
+               return 0;
+
+       /*
+        * If this is the first interface which is added,
+        * we should load the firmware now.
+        */
+       if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
+               retval = rt2x00lib_load_firmware(rt2x00dev);
+               if (retval)
+                       return retval;
+       }
+
+       /*
+        * Initialize the device.
+        */
+       retval = rt2x00lib_initialize(rt2x00dev);
+       if (retval)
+               return retval;
+
+       /*
+        * Enable radio.
+        */
+       retval = rt2x00lib_enable_radio(rt2x00dev);
+       if (retval) {
+               rt2x00lib_uninitialize(rt2x00dev);
+               return retval;
+       }
+
+       __set_bit(DEVICE_STARTED, &rt2x00dev->flags);
+
+       return 0;
+}
+
+void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
+{
+       if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
+               return;
+
+       /*
+        * Perhaps we can add something smarter here,
+        * but for now just disabling the radio should do.
+        */
+       rt2x00lib_disable_radio(rt2x00dev);
+
+       __clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
+}
+
 /*
  * driver allocation handlers.
  */
 static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
 {
        struct data_ring *ring;
+       unsigned int index;
 
        /*
         * We need the following rings:
@@ -963,11 +1239,18 @@ static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
 
        /*
         * Initialize ring parameters.
-        * cw_min: 2^5 = 32.
-        * cw_max: 2^10 = 1024.
+        * RX: queue_idx = 0
+        * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index
+        * TX: cw_min: 2^5 = 32.
+        * TX: cw_max: 2^10 = 1024.
         */
-       ring_for_each(rt2x00dev, ring) {
+       rt2x00dev->rx->rt2x00dev = rt2x00dev;
+       rt2x00dev->rx->queue_idx = 0;
+
+       index = IEEE80211_TX_QUEUE_DATA0;
+       txring_for_each(rt2x00dev, ring) {
                ring->rt2x00dev = rt2x00dev;
+               ring->queue_idx = index++;
                ring->tx_params.aifs = 2;
                ring->tx_params.cw_min = 5;
                ring->tx_params.cw_max = 10;
@@ -1008,7 +1291,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
        /*
         * Reset current working type.
         */
-       rt2x00dev->interface.type = INVALID_INTERFACE;
+       rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID;
 
        /*
         * Allocate ring array.
@@ -1112,7 +1395,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
         * Disable radio and unitialize all items
         * that must be recreated on resume.
         */
-       rt2x00mac_stop(rt2x00dev->hw);
+       rt2x00lib_stop(rt2x00dev);
        rt2x00lib_uninitialize(rt2x00dev);
        rt2x00debug_deregister(rt2x00dev);
 
@@ -1134,7 +1417,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
        int retval;
 
        NOTICE(rt2x00dev, "Waking up.\n");
-       __set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
 
        /*
         * Open the debugfs entry.
@@ -1150,7 +1432,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
        /*
         * Reinitialize device and all active interfaces.
         */
-       retval = rt2x00mac_start(rt2x00dev->hw);
+       retval = rt2x00lib_start(rt2x00dev);
        if (retval)
                goto exit;
 
@@ -1165,6 +1447,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
        rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
        rt2x00lib_config_type(rt2x00dev, intf->type);
 
+       /*
+        * We are ready again to receive requests from mac80211.
+        */
+       __set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
+
        /*
         * It is possible that during that mac80211 has attempted
         * to send frames while we were suspending or resuming.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h
new file mode 100644 (file)
index 0000000..99f3f36
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+       Copyright (C) 2004 - 2007 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: rt2x00dump
+       Abstract: Data structures for the rt2x00debug & userspace.
+ */
+
+#ifndef RT2X00DUMP_H
+#define RT2X00DUMP_H
+
+/**
+ * DOC: Introduction
+ *
+ * This header is intended to be exported to userspace,
+ * to make the structures and enumerations available to userspace
+ * applications. This means that all data types should be exportable.
+ *
+ * When rt2x00 is compiled with debugfs support enabled,
+ * it is possible to capture all data coming in and out of the device
+ * by reading the frame dump file. This file can have only a single reader.
+ * The following frames will be reported:
+ *   - All incoming frames (rx)
+ *   - All outgoing frames (tx, including beacon and atim)
+ *   - All completed frames (txdone including atim)
+ *
+ * The data is send to the file using the following format:
+ *
+ *   [rt2x00dump header][hardware descriptor][ieee802.11 frame]
+ *
+ * rt2x00dump header: The description of the dumped frame, as well as
+ *     additional information usefull for debugging. See &rt2x00dump_hdr.
+ * hardware descriptor: Descriptor that was used to receive or transmit
+ *     the frame.
+ * ieee802.11 frame: The actual frame that was received or transmitted.
+ */
+
+/**
+ * enum rt2x00_dump_type - Frame type
+ *
+ * These values are used for the @type member of &rt2x00dump_hdr.
+ * @DUMP_FRAME_RXDONE: This frame has been received by the hardware.
+ * @DUMP_FRAME_TX: This frame is queued for transmission to the hardware.
+ * @DUMP_FRAME_TXDONE: This frame indicates the device has handled
+ *     the tx event which has either succeeded or failed. A frame
+ *     with this type should also have been reported with as a
+ *     %DUMP_FRAME_TX frame.
+ */
+enum rt2x00_dump_type {
+       DUMP_FRAME_RXDONE = 1,
+       DUMP_FRAME_TX = 2,
+       DUMP_FRAME_TXDONE = 3,
+};
+
+/**
+ * struct rt2x00dump_hdr - Dump frame header
+ *
+ * Each frame dumped to the debugfs file starts with this header
+ * attached. This header contains the description of the actual
+ * frame which was dumped.
+ *
+ * New fields inside the structure must be appended to the end of
+ * the structure. This way userspace tools compiled for earlier
+ * header versions can still correctly handle the frame dump
+ * (although they will not handle all data passed to them in the dump).
+ *
+ * @version: Header version should always be set to %DUMP_HEADER_VERSION.
+ *     This field must be checked by userspace to determine if it can
+ *     handle this frame.
+ * @header_length: The length of the &rt2x00dump_hdr structure. This is
+ *     used for compatibility reasons so userspace can easily determine
+ *     the location of the next field in the dump.
+ * @desc_length: The length of the device descriptor.
+ * @data_length: The length of the frame data (including the ieee802.11 header.
+ * @chip_rt: RT chipset
+ * @chip_rf: RF chipset
+ * @chip_rev: Chipset revision
+ * @type: The frame type (&rt2x00_dump_type)
+ * @ring_index: The index number of the data ring.
+ * @entry_index: The index number of the entry inside the data ring.
+ * @timestamp_sec: Timestamp - seconds
+ * @timestamp_usec: Timestamp - microseconds
+ */
+struct rt2x00dump_hdr {
+       __le32 version;
+#define DUMP_HEADER_VERSION    2
+
+       __le32 header_length;
+       __le32 desc_length;
+       __le32 data_length;
+
+       __le16 chip_rt;
+       __le16 chip_rf;
+       __le32 chip_rev;
+
+       __le16 type;
+       __u8 ring_index;
+       __u8 entry_index;
+
+       __le32 timestamp_sec;
+       __le32 timestamp_usec;
+};
+
+#endif /* RT2X00DUMP_H */
index 236025f8b90f8834f491ee4d02be075904d21bcb..0a475e4e24429b157563af8ec444db886bd51125 100644 (file)
        Abstract: rt2x00 firmware loading routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/crc-itu-t.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
index 06d9bc0015c0ed9376ddb7b7e0a65d9c3a374087..1adbd28e0973eb9f023a01bab25b0f29a2b11075 100644 (file)
@@ -44,8 +44,8 @@ void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
 /*
  * Initialization handlers.
  */
-int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev);
-void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
+int rt2x00lib_start(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev);
 
 /*
  * Configuration handlers.
@@ -53,6 +53,8 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac);
 void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid);
 void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type);
+void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
+                             enum antenna rx, enum antenna tx);
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
                      struct ieee80211_conf *conf, const int force_config);
 
@@ -78,6 +80,7 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 void rt2x00debug_register(struct rt2x00_dev *rt2x00dev);
 void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev);
+void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 #else
 static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 {
@@ -86,6 +89,11 @@ static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
 {
 }
+
+static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
+                                         struct sk_buff *skb)
+{
+}
 #endif /* CONFIG_RT2X00_LIB_DEBUGFS */
 
 /*
index 85ea8a8e658ef52641702a614d4d75b4e2857e60..e3f15e518c76eafc7e669bae485476148fa60635 100644 (file)
        Abstract: rt2x00 generic mac80211 routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 
@@ -89,7 +84,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
         */
        if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) {
                ieee80211_stop_queues(hw);
-               return 0;
+               return NETDEV_TX_OK;
        }
 
        /*
@@ -115,15 +110,24 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
        if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) &&
            (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS |
                               IEEE80211_TXCTL_USE_CTS_PROTECT))) {
-               if (rt2x00_ring_free(ring) <= 1)
+               if (rt2x00_ring_free(ring) <= 1) {
+                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                        return NETDEV_TX_BUSY;
+               }
 
-               if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control))
+               if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) {
+                       ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                        return NETDEV_TX_BUSY;
+               }
        }
 
-       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control))
+       if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) {
+               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                return NETDEV_TX_BUSY;
+       }
+
+       if (rt2x00_ring_full(ring))
+               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
 
        if (rt2x00dev->ops->lib->kick_tx_queue)
                rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
@@ -135,41 +139,11 @@ EXPORT_SYMBOL_GPL(rt2x00mac_tx);
 int rt2x00mac_start(struct ieee80211_hw *hw)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       int status;
 
-       if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
-           test_bit(DEVICE_STARTED, &rt2x00dev->flags))
+       if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
                return 0;
 
-       /*
-        * If this is the first interface which is added,
-        * we should load the firmware now.
-        */
-       if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
-               status = rt2x00lib_load_firmware(rt2x00dev);
-               if (status)
-                       return status;
-       }
-
-       /*
-        * Initialize the device.
-        */
-       status = rt2x00lib_initialize(rt2x00dev);
-       if (status)
-               return status;
-
-       /*
-        * Enable radio.
-        */
-       status = rt2x00lib_enable_radio(rt2x00dev);
-       if (status) {
-               rt2x00lib_uninitialize(rt2x00dev);
-               return status;
-       }
-
-       __set_bit(DEVICE_STARTED, &rt2x00dev->flags);
-
-       return 0;
+       return rt2x00lib_start(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_start);
 
@@ -180,13 +154,7 @@ void rt2x00mac_stop(struct ieee80211_hw *hw)
        if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
                return;
 
-       /*
-        * Perhaps we can add something smarter here,
-        * but for now just disabling the radio should do.
-        */
-       rt2x00lib_disable_radio(rt2x00dev);
-
-       __clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
+       rt2x00lib_stop(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_stop);
 
@@ -213,7 +181,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
            is_interface_present(intf))
                return -ENOBUFS;
 
-       intf->id = conf->if_id;
+       intf->id = conf->vif;
        intf->type = conf->type;
        if (conf->type == IEEE80211_IF_TYPE_AP)
                memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
@@ -247,7 +215,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
                return;
 
        intf->id = 0;
-       intf->type = INVALID_INTERFACE;
+       intf->type = IEEE80211_IF_TYPE_INVALID;
        memset(&intf->bssid, 0x00, ETH_ALEN);
        memset(&intf->mac, 0x00, ETH_ALEN);
 
@@ -297,7 +265,8 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_config);
 
-int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
+int rt2x00mac_config_interface(struct ieee80211_hw *hw,
+                              struct ieee80211_vif *vif,
                               struct ieee80211_if_conf *conf)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -373,23 +342,27 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_get_tx_stats);
 
-void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
-                             int cts_protection, int preamble)
+void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
+                               struct ieee80211_vif *vif,
+                               struct ieee80211_bss_conf *bss_conf,
+                               u32 changes)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
        int short_preamble;
        int ack_timeout;
        int ack_consume_time;
        int difs;
+       int preamble;
 
        /*
         * We only support changing preamble mode.
         */
-       if (!(changes & IEEE80211_ERP_CHANGE_PREAMBLE))
+       if (!(changes & BSS_CHANGED_ERP_PREAMBLE))
                return;
 
-       short_preamble = !preamble;
-       preamble = !!(preamble) ? PREAMBLE : SHORT_PREAMBLE;
+       short_preamble = bss_conf->use_short_preamble;
+       preamble = bss_conf->use_short_preamble ?
+                               SHORT_PREAMBLE : PREAMBLE;
 
        difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ?
                SHORT_DIFS : DIFS;
@@ -405,7 +378,7 @@ void rt2x00mac_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
        rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble,
                                             ack_timeout, ack_consume_time);
 }
-EXPORT_SYMBOL_GPL(rt2x00mac_erp_ie_changed);
+EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
 
 int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
                      const struct ieee80211_tx_queue_params *params)
index 04663eb319504f53d31af8e8fc0dfa509a836570..804a9980055d6a73c105575a879976b9ad7645f3 100644 (file)
        Abstract: rt2x00 generic pci device routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00pci"
-
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -43,9 +38,9 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                            struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct data_ring *ring =
-           rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
-       struct data_entry *entry = rt2x00_get_data_entry(ring);
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
 
        /*
         * Just in case mac80211 doesn't set this correctly,
@@ -53,14 +48,22 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
-        * Update the beacon entry.
+        * Fill in skb descriptor
         */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len;
+       desc->desc = entry->priv;
+       desc->data = skb->data;
+       desc->ring = ring;
+       desc->entry = entry;
+
        memcpy(entry->data_addr, skb->data, skb->len);
-       rt2x00lib_write_tx_desc(rt2x00dev, entry->priv,
-                               (struct ieee80211_hdr *)skb->data,
-                               skb->len, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Enable beacon generation.
@@ -78,15 +81,13 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                            struct data_ring *ring, struct sk_buff *skb,
                            struct ieee80211_tx_control *control)
 {
-       struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;
        struct data_entry *entry = rt2x00_get_data_entry(ring);
-       struct data_desc *txd = entry->priv;
+       __le32 *txd = entry->priv;
+       struct skb_desc *desc;
        u32 word;
 
-       if (rt2x00_ring_full(ring)) {
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+       if (rt2x00_ring_full(ring))
                return -EINVAL;
-       }
 
        rt2x00_desc_read(txd, 0, &word);
 
@@ -96,37 +97,42 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                      "Arrived at non-free entry in the non-full queue %d.\n"
                      "Please file bug report to %s.\n",
                      control->queue, DRV_PROJECT);
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                return -EINVAL;
        }
 
-       entry->skb = skb;
-       memcpy(&entry->tx_status.control, control, sizeof(*control));
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len;
+       desc->desc = entry->priv;
+       desc->data = skb->data;
+       desc->ring = ring;
+       desc->entry = entry;
+
        memcpy(entry->data_addr, skb->data, skb->len);
-       rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr,
-                               skb->len, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        rt2x00_ring_index_inc(ring);
 
-       if (rt2x00_ring_full(ring))
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
 
 /*
- * RX data handlers.
+ * TX/RX data handlers.
  */
 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 {
        struct data_ring *ring = rt2x00dev->rx;
        struct data_entry *entry;
-       struct data_desc *rxd;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
+       struct skb_desc *skbdesc;
        struct rxdata_entry_desc desc;
        int header_size;
+       __le32 *rxd;
        int align;
        u32 word;
 
@@ -138,7 +144,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
                        break;
 
-               memset(&desc, 0x00, sizeof(desc));
+               memset(&desc, 0, sizeof(desc));
                rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
 
                hdr = (struct ieee80211_hdr *)entry->data_addr;
@@ -162,6 +168,17 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
                skb_reserve(skb, align);
                memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size);
 
+               /*
+                * Fill in skb descriptor
+                */
+               skbdesc = get_skb_desc(skb);
+               skbdesc->desc_len = entry->ring->desc_size;
+               skbdesc->data_len = skb->len;
+               skbdesc->desc = entry->priv;
+               skbdesc->data = skb->data;
+               skbdesc->ring = ring;
+               skbdesc->entry = entry;
+
                /*
                 * Send the frame to rt2x00lib for further processing.
                 */
@@ -177,6 +194,37 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
 
+void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry,
+                     const int tx_status, const int retry)
+{
+       u32 word;
+
+       rt2x00lib_txdone(entry, tx_status, retry);
+
+       /*
+        * Make this entry available for reuse.
+        */
+       entry->flags = 0;
+
+       rt2x00_desc_read(entry->priv, 0, &word);
+       rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0);
+       rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
+       rt2x00_desc_write(entry->priv, 0, word);
+
+       rt2x00_ring_index_done_inc(entry->ring);
+
+       /*
+        * If the data ring was full before the txdone handler
+        * we must make sure the packet queue in the mac80211 stack
+        * is reenabled when the txdone handler has finished.
+        */
+       if (!rt2x00_ring_full(entry->ring))
+               ieee80211_wake_queue(rt2x00dev->hw,
+                                    entry->tx_status.control.queue);
+
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
+
 /*
  * Device initialization handlers.
  */
index 82adeac061d0d309c0f8a475db4dcb2cc6175e9e..2d1eb8144da46654524f01183c77d9a847ee75d2 100644 (file)
@@ -57,7 +57,7 @@
 /*
  * Register access.
  */
-static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
                                           const unsigned long offset,
                                           u32 *value)
 {
@@ -65,14 +65,14 @@ static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev,
 }
 
 static inline void
-rt2x00pci_register_multiread(const struct rt2x00_dev *rt2x00dev,
+rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
                             const unsigned long offset,
                             void *value, const u16 length)
 {
        memcpy_fromio(value, rt2x00dev->csr_addr + offset, length);
 }
 
-static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
                                            const unsigned long offset,
                                            u32 value)
 {
@@ -80,7 +80,7 @@ static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev,
 }
 
 static inline void
-rt2x00pci_register_multiwrite(const struct rt2x00_dev *rt2x00dev,
+rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
                              const unsigned long offset,
                              void *value, const u16 length)
 {
@@ -101,9 +101,11 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
                            struct ieee80211_tx_control *control);
 
 /*
- * RX data handlers.
+ * RX/TX data handlers.
  */
 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry,
+                     const int tx_status, const int retry);
 
 /*
  * Device initialization handlers.
index a0f8b8e0a24b52dc274267e4db22c4aa056191e4..34a96d44e306cfb3714782c6f1fad80e810598a0 100644 (file)
        Abstract: rt2x00 rfkill routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00lib"
-
 #include <linux/input-polldev.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -68,8 +63,10 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
        struct rt2x00_dev *rt2x00dev = poll_dev->private;
        int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
 
-       if (rt2x00dev->rfkill->state != state)
+       if (rt2x00dev->rfkill->state != state) {
                input_report_key(poll_dev->input, KEY_WLAN, 1);
+               input_report_key(poll_dev->input, KEY_WLAN, 0);
+       }
 }
 
 int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -92,6 +89,13 @@ int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
                return retval;
        }
 
+       /*
+        * Force initial poll which will detect the initial device state,
+        * and correctly sends the signal to the rfkill layer about this
+        * state.
+        */
+       rt2x00rfkill_poll(rt2x00dev->poll_dev);
+
        return 0;
 }
 
@@ -114,26 +118,41 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
        rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
        if (!rt2x00dev->rfkill) {
                ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n");
-               return -ENOMEM;
+               goto exit;
        }
 
        rt2x00dev->rfkill->name = rt2x00dev->ops->name;
        rt2x00dev->rfkill->data = rt2x00dev;
-       rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+       rt2x00dev->rfkill->state = -1;
        rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
 
        rt2x00dev->poll_dev = input_allocate_polled_device();
        if (!rt2x00dev->poll_dev) {
                ERROR(rt2x00dev, "Failed to allocate polled device.\n");
-               rfkill_free(rt2x00dev->rfkill);
-               return -ENOMEM;
+               goto exit_free_rfkill;
        }
 
        rt2x00dev->poll_dev->private = rt2x00dev;
        rt2x00dev->poll_dev->poll = rt2x00rfkill_poll;
        rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL;
 
+       rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name;
+       rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy);
+       rt2x00dev->poll_dev->input->id.bustype = BUS_HOST;
+       rt2x00dev->poll_dev->input->id.vendor = 0x1814;
+       rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt;
+       rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev;
+       rt2x00dev->poll_dev->input->dev.parent = device;
+       rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY);
+       set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit);
+
        return 0;
+
+exit_free_rfkill:
+       rfkill_free(rt2x00dev->rfkill);
+
+exit:
+       return -ENOMEM;
 }
 
 void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
index 1a864d32cfbd2a9615169c87d7967d2877f95378..1caa6d688c402f74f4244a1ec0365d3f7096880f 100644 (file)
 #define RT2X00RING_H
 
 /*
- * data_desc
- * Each data entry also contains a descriptor which is used by the
- * device to determine what should be done with the packet and
- * what the current status is.
- * This structure is greatly simplified, but the descriptors
- * are basically a list of little endian 32 bit values.
- * Make the array by default 1 word big, this will allow us
- * to use sizeof() correctly.
+ * skb_desc
+ * Descriptor information for the skb buffer
  */
-struct data_desc {
-       __le32 word[1];
+struct skb_desc {
+       unsigned int frame_type;
+
+       unsigned int desc_len;
+       unsigned int data_len;
+
+       void *desc;
+       void *data;
+
+       struct data_ring *ring;
+       struct data_entry *entry;
 };
 
+static inline struct skb_desc* get_skb_desc(struct sk_buff *skb)
+{
+       return (struct skb_desc*)&skb->cb[0];
+}
+
 /*
  * rxdata_entry_desc
  * Summary of information that has been read from the
@@ -51,6 +59,7 @@ struct rxdata_entry_desc {
        int ofdm;
        int size;
        int flags;
+       int my_bss;
 };
 
 /*
@@ -66,6 +75,7 @@ struct txdata_entry_desc {
 #define ENTRY_TXD_MORE_FRAG    4
 #define ENTRY_TXD_REQ_TIMESTAMP        5
 #define ENTRY_TXD_BURST                6
+#define ENTRY_TXD_ACK          7
 
 /*
  * Queue ID. ID's 0-4 are data TX rings
@@ -134,6 +144,11 @@ struct data_entry {
         */
        void *data_addr;
        dma_addr_t data_dma;
+
+       /*
+        * Entry identification number (index).
+        */
+       unsigned int entry_idx;
 };
 
 /*
@@ -171,6 +186,13 @@ struct data_ring {
        dma_addr_t data_dma;
        void *data_addr;
 
+       /*
+        * Queue identification number:
+        * RX: 0
+        * TX: IEEE80211_TX_*
+        */
+       unsigned int queue_idx;
+
        /*
         * Index variables.
         */
@@ -253,16 +275,16 @@ static inline int rt2x00_ring_free(struct data_ring *ring)
 /*
  * TX/RX Descriptor access functions.
  */
-static inline void rt2x00_desc_read(struct data_desc *desc,
+static inline void rt2x00_desc_read(__le32 *desc,
                                    const u8 word, u32 *value)
 {
-       *value = le32_to_cpu(desc->word[word]);
+       *value = le32_to_cpu(desc[word]);
 }
 
-static inline void rt2x00_desc_write(struct data_desc *desc,
+static inline void rt2x00_desc_write(__le32 *desc,
                                     const u8 word, const u32 value)
 {
-       desc->word[word] = cpu_to_le32(value);
+       desc[word] = cpu_to_le32(value);
 }
 
 #endif /* RT2X00RING_H */
index 568d73847dca4eabcaf3d2ee974b5f20dcb26a00..84e9bdb73910ca5db00fa03e4d879b8b5f06cc78 100644 (file)
        Abstract: rt2x00 generic usb device routines.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt2x00usb"
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/bug.h>
 
 #include "rt2x00.h"
 #include "rt2x00usb.h"
@@ -38,7 +34,7 @@
 /*
  * Interfacing with the HW.
  */
-int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
                             const u8 request, const u8 requesttype,
                             const u16 offset, const u16 value,
                             void *buffer, const u16 buffer_length,
@@ -52,6 +48,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
            (requesttype == USB_VENDOR_REQUEST_IN) ?
            usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0);
 
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
                status = usb_control_msg(usb_dev, pipe, request, requesttype,
                                         value, offset, buffer, buffer_length,
@@ -76,13 +73,15 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
 
-int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
-                                 const u8 request, const u8 requesttype,
-                                 const u16 offset, void *buffer,
-                                 const u16 buffer_length, const int timeout)
+int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
+                                  const u8 request, const u8 requesttype,
+                                  const u16 offset, void *buffer,
+                                  const u16 buffer_length, const int timeout)
 {
        int status;
 
+       BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex));
+
        /*
         * Check for Cache availability.
         */
@@ -103,6 +102,25 @@ int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
 
        return status;
 }
+EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock);
+
+int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
+                                 const u8 request, const u8 requesttype,
+                                 const u16 offset, void *buffer,
+                                 const u16 buffer_length, const int timeout)
+{
+       int status;
+
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
+       status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,
+                                               requesttype, offset, buffer,
+                                               buffer_length, timeout);
+
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       return status;
+}
 EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
 
 /*
@@ -113,7 +131,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
        struct data_entry *entry = (struct data_entry *)urb->context;
        struct data_ring *ring = entry->ring;
        struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
-       struct data_desc *txd = (struct data_desc *)entry->skb->data;
+       __le32 *txd = (__le32 *)entry->skb->data;
        u32 word;
        int tx_status;
 
@@ -158,20 +176,17 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        struct usb_device *usb_dev =
            interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
        struct data_entry *entry = rt2x00_get_data_entry(ring);
-       int pipe = usb_sndbulkpipe(usb_dev, 1);
+       struct skb_desc *desc;
        u32 length;
 
-       if (rt2x00_ring_full(ring)) {
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
+       if (rt2x00_ring_full(ring))
                return -EINVAL;
-       }
 
        if (test_bit(ENTRY_OWNER_NIC, &entry->flags)) {
                ERROR(rt2x00dev,
                      "Arrived at non-free entry in the non-full queue %d.\n"
                      "Please file bug report to %s.\n",
                      control->queue, DRV_PROJECT);
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
                return -EINVAL;
        }
 
@@ -181,12 +196,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
        skb_push(skb, ring->desc_size);
        memset(skb->data, 0, ring->desc_size);
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        ring->desc_size),
-                               skb->len - ring->desc_size, control);
-       memcpy(&entry->tx_status.control, control, sizeof(*control));
-       entry->skb = skb;
+       /*
+        * Fill in skb descriptor
+        */
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
+
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * USB devices cannot blindly pass the skb->len as the
@@ -199,15 +220,12 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
         * Initialize URB and send the frame to the device.
         */
        __set_bit(ENTRY_OWNER_NIC, &entry->flags);
-       usb_fill_bulk_urb(entry->priv, usb_dev, pipe,
+       usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1),
                          skb->data, length, rt2x00usb_interrupt_txdone, entry);
        usb_submit_urb(entry->priv, GFP_ATOMIC);
 
        rt2x00_ring_index_inc(ring);
 
-       if (rt2x00_ring_full(ring))
-               ieee80211_stop_queue(rt2x00dev->hw, control->queue);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data);
@@ -222,6 +240,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
        struct sk_buff *skb;
        struct ieee80211_hdr *hdr;
+       struct skb_desc *skbdesc;
        struct rxdata_entry_desc desc;
        int header_size;
        int frame_size;
@@ -238,7 +257,14 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        if (urb->actual_length < entry->ring->desc_size || urb->status)
                goto skip_entry;
 
-       memset(&desc, 0x00, sizeof(desc));
+       /*
+        * Fill in skb descriptor
+        */
+       skbdesc = get_skb_desc(entry->skb);
+       skbdesc->ring = ring;
+       skbdesc->entry = entry;
+
+       memset(&desc, 0, sizeof(desc));
        rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
 
        /*
@@ -264,9 +290,6 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
        /*
         * The data behind the ieee80211 header must be
         * aligned on a 4 byte boundary.
-        * After that trim the entire buffer down to only
-        * contain the valid frame data excluding the device
-        * descriptor.
         */
        hdr = (struct ieee80211_hdr *)entry->skb->data;
        header_size =
@@ -276,6 +299,16 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
                skb_push(entry->skb, 2);
                memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2);
        }
+
+       /*
+        * Trim the entire buffer down to only contain the valid frame data
+        * excluding the device descriptor. The position of the descriptor
+        * varies. This means that we should check where the descriptor is
+        * and decide if we need to pull the data pointer to exclude the
+        * device descriptor.
+        */
+       if (skbdesc->data > skbdesc->desc)
+               skb_pull(entry->skb, skbdesc->desc_len);
        skb_trim(entry->skb, desc.size);
 
        /*
@@ -303,43 +336,6 @@ skip_entry:
 /*
  * Radio handlers
  */
-void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev)
-{
-       struct usb_device *usb_dev =
-           interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
-       struct data_ring *ring;
-       struct data_entry *entry;
-       unsigned int i;
-
-       /*
-        * Initialize the TX rings
-        */
-       txringall_for_each(rt2x00dev, ring) {
-               for (i = 0; i < ring->stats.limit; i++)
-                       ring->entry[i].flags = 0;
-
-               rt2x00_ring_index_clear(ring);
-       }
-
-       /*
-        * Initialize and start the RX ring.
-        */
-       rt2x00_ring_index_clear(rt2x00dev->rx);
-
-       for (i = 0; i < rt2x00dev->rx->stats.limit; i++) {
-               entry = &rt2x00dev->rx->entry[i];
-
-               usb_fill_bulk_urb(entry->priv, usb_dev,
-                                 usb_rcvbulkpipe(usb_dev, 1),
-                                 entry->skb->data, entry->skb->len,
-                                 rt2x00usb_interrupt_rxdone, entry);
-
-               __set_bit(ENTRY_OWNER_NIC, &entry->flags);
-               usb_submit_urb(entry->priv, GFP_ATOMIC);
-       }
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_enable_radio);
-
 void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
        struct data_ring *ring;
@@ -361,6 +357,29 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
 /*
  * Device initialization handlers.
  */
+void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                           struct data_entry *entry)
+{
+       struct usb_device *usb_dev =
+            interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
+
+       usb_fill_bulk_urb(entry->priv, usb_dev,
+                         usb_rcvbulkpipe(usb_dev, 1),
+                         entry->skb->data, entry->skb->len,
+                         rt2x00usb_interrupt_rxdone, entry);
+
+       __set_bit(ENTRY_OWNER_NIC, &entry->flags);
+       usb_submit_urb(entry->priv, GFP_ATOMIC);
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry);
+
+void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
+                           struct data_entry *entry)
+{
+       entry->flags = 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry);
+
 static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
                               struct data_ring *ring)
 {
@@ -400,7 +419,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev)
        struct sk_buff *skb;
        unsigned int entry_size;
        unsigned int i;
-       int status;
+       int uninitialized_var(status);
 
        /*
         * Allocate DMA
@@ -507,6 +526,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
        rt2x00dev->dev = usb_intf;
        rt2x00dev->ops = ops;
        rt2x00dev->hw = hw;
+       mutex_init(&rt2x00dev->usb_cache_mutex);
 
        rt2x00dev->usb_maxpacket =
            usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1);
index 2681abe4d49eb7a4f595cbdadce556c160b4ad42..e40df4050cd07ba116a2f86e94784bb6db76afcc 100644 (file)
@@ -91,7 +91,7 @@
  * a buffer allocated by kmalloc. Failure to do so can lead
  * to unexpected behavior depending on the architecture.
  */
-int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev,
                             const u8 request, const u8 requesttype,
                             const u16 offset, const u16 value,
                             void *buffer, const u16 buffer_length,
@@ -107,18 +107,25 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
  * kmalloc. Hence the reason for using a previously allocated cache
  * which has been allocated properly.
  */
-int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
+int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev,
                                  const u8 request, const u8 requesttype,
                                  const u16 offset, void *buffer,
                                  const u16 buffer_length, const int timeout);
 
+/*
+ * A version of rt2x00usb_vendor_request_buff which must be called
+ * if the usb_cache_mutex is already held. */
+int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
+                                  const u8 request, const u8 requesttype,
+                                  const u16 offset, void *buffer,
+                                  const u16 buffer_length, const int timeout);
+
 /*
  * Simple wrapper around rt2x00usb_vendor_request to write a single
  * command to the device. Since we don't use the buffer argument we
  * don't have to worry about kmalloc here.
  */
-static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
-                                             *rt2x00dev,
+static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev,
                                              const u8 request,
                                              const u16 offset,
                                              const u16 value,
@@ -134,8 +141,8 @@ static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
  * from the device. Note that the eeprom argument _must_ be allocated using
  * kmalloc for correct handling inside the kernel USB layer.
  */
-static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev,
-                                        __le16 *eeprom, const u16 lenght)
+static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev,
+                                       __le16 *eeprom, const u16 lenght)
 {
        int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16));
 
@@ -147,7 +154,6 @@ static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev,
 /*
  * Radio handlers
  */
-void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
 
 /*
@@ -160,6 +166,10 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
 /*
  * Device initialization handlers.
  */
+void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                           struct data_entry *entry);
+void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
+                           struct data_entry *entry);
 int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
 void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
 
index ecae968ce091ef595f2ab5e4e5a0394109da033d..ab52f221cd718c06411d50c76b06c308be7b4f3b 100644 (file)
        Supported chipsets: RT2561, RT2561s, RT2661.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt61pci"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -52,7 +47,7 @@
  * the access attempt is considered to have failed,
  * and we will print an error.
  */
-static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt61pci_bbp_check(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
        unsigned int i;
@@ -67,7 +62,7 @@ static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev)
        return reg;
 }
 
-static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
                              const unsigned int word, const u8 value)
 {
        u32 reg;
@@ -93,7 +88,7 @@ static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
 }
 
-static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, u8 *value)
 {
        u32 reg;
@@ -130,7 +125,7 @@ static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev,
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
 }
 
-static void rt61pci_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, const u32 value)
 {
        u32 reg;
@@ -160,7 +155,7 @@ rf_write:
        rt2x00_rf_write(rt2x00dev, word, value);
 }
 
-static void rt61pci_mcu_request(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
                                const u8 command, const u8 token,
                                const u8 arg0, const u8 arg1)
 {
@@ -220,13 +215,13 @@ static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom)
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 #define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
 
-static void rt61pci_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_read_csr(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, u32 *data)
 {
        rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data);
 }
 
-static void rt61pci_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt61pci_write_csr(struct rt2x00_dev *rt2x00dev,
                              const unsigned int word, u32 data)
 {
        rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data);
@@ -322,7 +317,8 @@ static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type,
         */
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
+                         (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, tsf_sync);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
@@ -411,8 +407,7 @@ static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
-                                     const int antenna_tx,
-                                     const int antenna_rx)
+                                     struct antenna_setup *ant)
 {
        u8 r3;
        u8 r4;
@@ -423,32 +418,39 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-                         !rt2x00_rf(&rt2x00dev->chip, RF5225));
+                         rt2x00_rf(&rt2x00dev->chip, RF5325));
 
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-                                 !!(rt2x00dev->curr_hwmode != HWMODE_A));
+                                 (rt2x00dev->curr_hwmode != HWMODE_A));
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
                if (rt2x00dev->curr_hwmode == HWMODE_A)
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                else
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
                if (rt2x00dev->curr_hwmode == HWMODE_A)
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                else
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                break;
        }
 
@@ -458,8 +460,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
-                                     const int antenna_tx,
-                                     const int antenna_rx)
+                                     struct antenna_setup *ant)
 {
        u8 r3;
        u8 r4;
@@ -470,22 +471,31 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
-                         !rt2x00_rf(&rt2x00dev->chip, RF2527));
+                         rt2x00_rf(&rt2x00dev->chip, RF2529));
        rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
                          !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                break;
        }
 
@@ -501,23 +511,18 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
 
        rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
 
-       if (p1 != 0xff) {
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT4, !!p1);
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
-               rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
-       }
-       if (p2 != 0xff) {
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
-               rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
-               rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
-       }
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT4, p1);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
+
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
+       rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
+
+       rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
 }
 
 static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
-                                       const int antenna_tx,
-                                       const int antenna_rx)
+                                       struct antenna_setup *ant)
 {
-       u16 eeprom;
        u8 r3;
        u8 r4;
        u8 r77;
@@ -525,70 +530,36 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
        rt61pci_bbp_read(rt2x00dev, 3, &r3);
        rt61pci_bbp_read(rt2x00dev, 4, &r4);
        rt61pci_bbp_read(rt2x00dev, 77, &r77);
-       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
 
-       rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
-
-       if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
-           rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-               rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1);
-               rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
-       } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) {
-               if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) {
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-                       rt61pci_bbp_write(rt2x00dev, 77, r77);
-               }
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
-       } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
-                  rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-               rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
-               switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
-               case 0:
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
-                       break;
-               case 1:
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
-                       break;
-               case 2:
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
-                       break;
-               case 3:
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
-                       break;
-               }
-       } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
-                  !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+       /* FIXME: Antenna selection for the rf 2529 is very confusing in the
+        * legacy driver. The code below should be ok for non-diversity setups.
+        */
 
-               switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
-               case 0:
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-                       rt61pci_bbp_write(rt2x00dev, 77, r77);
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
-                       break;
-               case 1:
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-                       rt61pci_bbp_write(rt2x00dev, 77, r77);
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
-                       break;
-               case 2:
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-                       rt61pci_bbp_write(rt2x00dev, 77, r77);
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
-                       break;
-               case 3:
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-                       rt61pci_bbp_write(rt2x00dev, 77, r77);
-                       rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
-                       break;
-               }
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
+       case ANTENNA_A:
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+               rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
+               break;
+       case ANTENNA_SW_DIVERSITY:
+       case ANTENNA_HW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
+       case ANTENNA_B:
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+               rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
+               break;
        }
 
+       rt61pci_bbp_write(rt2x00dev, 77, r77);
        rt61pci_bbp_write(rt2x00dev, 3, r3);
        rt61pci_bbp_write(rt2x00dev, 4, r4);
 }
@@ -625,46 +596,44 @@ static const struct antenna_sel antenna_sel_bg[] = {
 };
 
 static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                  const int antenna_tx, const int antenna_rx)
+                                  struct antenna_setup *ant)
 {
        const struct antenna_sel *sel;
        unsigned int lna;
        unsigned int i;
        u32 reg;
 
-       rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
-
        if (rt2x00dev->curr_hwmode == HWMODE_A) {
                sel = antenna_sel_a;
                lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
        } else {
                sel = antenna_sel_bg;
                lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
-
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
        }
 
        for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
                rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
 
+       rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
+
+       rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
+                          (rt2x00dev->curr_hwmode == HWMODE_B ||
+                           rt2x00dev->curr_hwmode == HWMODE_G));
+       rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
+                          (rt2x00dev->curr_hwmode == HWMODE_A));
+
        rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
 
        if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
            rt2x00_rf(&rt2x00dev->chip, RF5325))
-               rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+               rt61pci_config_antenna_5x(rt2x00dev, ant);
        else if (rt2x00_rf(&rt2x00dev->chip, RF2527))
-               rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+               rt61pci_config_antenna_2x(rt2x00dev, ant);
        else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) {
                if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
-                       rt61pci_config_antenna_2x(rt2x00dev, antenna_tx,
-                                                 antenna_rx);
+                       rt61pci_config_antenna_2x(rt2x00dev, ant);
                else
-                       rt61pci_config_antenna_2529(rt2x00dev, antenna_tx,
-                                                   antenna_rx);
+                       rt61pci_config_antenna_2529(rt2x00dev, ant);
        }
 }
 
@@ -709,8 +678,7 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
        if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
                rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & CONFIG_UPDATE_ANTENNA)
-               rt61pci_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx,
-                                      libconf->conf->antenna_sel_rx);
+               rt61pci_config_antenna(rt2x00dev, &libconf->ant);
        if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
                rt61pci_config_duration(rt2x00dev, libconf);
 }
@@ -721,7 +689,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
 static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
-       u16 led_reg;
        u8 arg0;
        u8 arg1;
 
@@ -730,15 +697,14 @@ static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, MAC_CSR14_OFF_PERIOD, 30);
        rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg);
 
-       led_reg = rt2x00dev->led_reg;
-       rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1);
-       if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)
-               rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1);
-       else
-               rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1);
+       rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
+       rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
+                          (rt2x00dev->rx_status.phymode == MODE_IEEE80211A));
+       rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
+                          (rt2x00dev->rx_status.phymode != MODE_IEEE80211A));
 
-       arg0 = led_reg & 0xff;
-       arg1 = (led_reg >> 8) & 0xff;
+       arg0 = rt2x00dev->led_reg & 0xff;
+       arg1 = (rt2x00dev->led_reg >> 8) & 0xff;
 
        rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1);
 }
@@ -792,7 +758,8 @@ static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
 /*
  * Link tuning
  */
-static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev,
+                              struct link_qual *qual)
 {
        u32 reg;
 
@@ -800,14 +767,13 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev)
         * Update FCS error count from register.
         */
        rt2x00pci_register_read(rt2x00dev, STA_CSR0, &reg);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt2x00pci_register_read(rt2x00dev, STA_CSR1, &reg);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
 static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -904,11 +870,11 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
         * r17 does not yet exceed upper limit, continue and base
         * the r17 tuning on the false CCA count.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
                if (++r17 > up_bound)
                        r17 = up_bound;
                rt61pci_bbp_write(rt2x00dev, 17, r17);
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                if (--r17 < low_bound)
                        r17 = low_bound;
                rt61pci_bbp_write(rt2x00dev, 17, r17);
@@ -1023,80 +989,52 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data,
        return 0;
 }
 
-static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev)
+static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev,
+                                struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00dev->rx;
-       struct data_desc *rxd;
-       unsigned int i;
+       __le32 *rxd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               rxd = ring->entry[i].priv;
-
-               rt2x00_desc_read(rxd, 5, &word);
-               rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(rxd, 5, word);
+       rt2x00_desc_read(rxd, 5, &word);
+       rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
+                          entry->data_dma);
+       rt2x00_desc_write(rxd, 5, word);
 
-               rt2x00_desc_read(rxd, 0, &word);
-               rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
-               rt2x00_desc_write(rxd, 0, word);
-       }
-
-       rt2x00_ring_index_clear(rt2x00dev->rx);
+       rt2x00_desc_read(rxd, 0, &word);
+       rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
+       rt2x00_desc_write(rxd, 0, word);
 }
 
-static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue)
+static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev,
+                                struct data_entry *entry)
 {
-       struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue);
-       struct data_desc *txd;
-       unsigned int i;
+       __le32 *txd = entry->priv;
        u32 word;
 
-       memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring));
-
-       for (i = 0; i < ring->stats.limit; i++) {
-               txd = ring->entry[i].priv;
-
-               rt2x00_desc_read(txd, 1, &word);
-               rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
-               rt2x00_desc_write(txd, 1, word);
-
-               rt2x00_desc_read(txd, 5, &word);
-               rt2x00_set_field32(&word, TXD_W5_PID_TYPE, queue);
-               rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, i);
-               rt2x00_desc_write(txd, 5, word);
+       rt2x00_desc_read(txd, 1, &word);
+       rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1);
+       rt2x00_desc_write(txd, 1, word);
 
-               rt2x00_desc_read(txd, 6, &word);
-               rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
-                                  ring->entry[i].data_dma);
-               rt2x00_desc_write(txd, 6, word);
+       rt2x00_desc_read(txd, 5, &word);
+       rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx);
+       rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
+       rt2x00_desc_write(txd, 5, word);
 
-               rt2x00_desc_read(txd, 0, &word);
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
-               rt2x00_desc_write(txd, 0, word);
-       }
+       rt2x00_desc_read(txd, 6, &word);
+       rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS,
+                          entry->data_dma);
+       rt2x00_desc_write(txd, 6, word);
 
-       rt2x00_ring_index_clear(ring);
+       rt2x00_desc_read(txd, 0, &word);
+       rt2x00_set_field32(&word, TXD_W0_VALID, 0);
+       rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
+       rt2x00_desc_write(txd, 0, word);
 }
 
 static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
 
-       /*
-        * Initialize rings.
-        */
-       rt61pci_init_rxring(rt2x00dev);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA1);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3);
-       rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4);
-
        /*
         * Initialize registers.
         */
@@ -1565,12 +1503,12 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                 struct data_desc *txd,
-                                 struct txdata_entry_desc *desc,
-                                 struct ieee80211_hdr *ieee80211hdr,
-                                 unsigned int length,
-                                 struct ieee80211_tx_control *control)
+                                   struct sk_buff *skb,
+                                   struct txdata_entry_desc *desc,
+                                   struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
@@ -1599,7 +1537,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_desc_write(txd, 5, word);
 
        rt2x00_desc_read(txd, 11, &word);
-       rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, length);
+       rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len);
        rt2x00_desc_write(txd, 11, word);
 
        rt2x00_desc_read(txd, 0, &word);
@@ -1608,7 +1546,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
@@ -1618,7 +1556,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                           !!(control->flags &
                              IEEE80211_TXCTL_LONG_RETRY_LIMIT));
        rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W0_BURST,
                           test_bit(ENTRY_TXD_BURST, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -1649,16 +1587,16 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
        }
 
        rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, &reg);
-       if (queue == IEEE80211_TX_QUEUE_DATA0)
-               rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA1)
-               rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA2)
-               rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA3)
-               rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3, 1);
-       else if (queue == IEEE80211_TX_QUEUE_DATA4)
-               rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_MGMT, 1);
+       rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC0,
+                          (queue == IEEE80211_TX_QUEUE_DATA0));
+       rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC1,
+                          (queue == IEEE80211_TX_QUEUE_DATA1));
+       rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC2,
+                          (queue == IEEE80211_TX_QUEUE_DATA2));
+       rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_AC3,
+                          (queue == IEEE80211_TX_QUEUE_DATA3));
+       rt2x00_set_field32(&reg, TX_CNTL_CSR_KICK_TX_MGMT,
+                          (queue == IEEE80211_TX_QUEUE_DATA4));
        rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
 }
 
@@ -1709,7 +1647,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 static void rt61pci_fill_rxdone(struct data_entry *entry,
                                struct rxdata_entry_desc *desc)
 {
-       struct data_desc *rxd = entry->priv;
+       __le32 *rxd = entry->priv;
        u32 word0;
        u32 word1;
 
@@ -1727,8 +1665,7 @@ static void rt61pci_fill_rxdone(struct data_entry *entry,
        desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
        desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
-
-       return;
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 }
 
 /*
@@ -1739,7 +1676,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
        struct data_ring *ring;
        struct data_entry *entry;
        struct data_entry *entry_done;
-       struct data_desc *txd;
+       __le32 *txd;
        u32 word;
        u32 reg;
        u32 old_reg;
@@ -1809,24 +1746,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
                tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT);
                retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
 
-               rt2x00lib_txdone(entry, tx_status, retry);
-
-               /*
-                * Make this entry available for reuse.
-                */
-               entry->flags = 0;
-               rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-               rt2x00_desc_write(txd, 0, word);
-               rt2x00_ring_index_done_inc(entry->ring);
-
-               /*
-                * If the data ring was full before the txdone handler
-                * we must make sure the packet queue in the mac80211 stack
-                * is reenabled when the txdone handler has finished.
-                */
-               if (!rt2x00_ring_full(ring))
-                       ieee80211_wake_queue(rt2x00dev->hw,
-                                            entry->tx_status.control.queue);
+               rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
        }
 }
 
@@ -1920,8 +1840,10 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
        if (word == 0xffff) {
                rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+                                  ANTENNA_B);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+                                  ANTENNA_B);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
@@ -2024,12 +1946,18 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
                return -ENODEV;
        }
 
+       /*
+        * Determine number of antenna's.
+        */
+       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
+               __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
+
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->hw->conf.antenna_sel_tx =
+       rt2x00dev->default_ant.tx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
-       rt2x00dev->hw->conf.antenna_sel_rx =
+       rt2x00dev->default_ant.rx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
 
        /*
@@ -2038,12 +1966,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
                __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
 
-       /*
-        * Determine number of antenna's.
-        */
-       if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
-               __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
-
        /*
         * Detect if this device has an hardware controlled radio.
         */
@@ -2071,6 +1993,38 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
                __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
 
+       /*
+        * When working with a RF2529 chip without double antenna
+        * the antenna settings should be gathered from the NIC
+        * eeprom word.
+        */
+       if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
+           !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
+               switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
+               case 0:
+                       rt2x00dev->default_ant.tx = ANTENNA_B;
+                       rt2x00dev->default_ant.rx = ANTENNA_A;
+                       break;
+               case 1:
+                       rt2x00dev->default_ant.tx = ANTENNA_B;
+                       rt2x00dev->default_ant.rx = ANTENNA_B;
+                       break;
+               case 2:
+                       rt2x00dev->default_ant.tx = ANTENNA_A;
+                       rt2x00dev->default_ant.rx = ANTENNA_A;
+                       break;
+               case 3:
+                       rt2x00dev->default_ant.tx = ANTENNA_A;
+                       rt2x00dev->default_ant.rx = ANTENNA_B;
+                       break;
+               }
+
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
+                       rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
+               if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY))
+                       rt2x00dev->default_ant.rx = ANTENNA_SW_DIVERSITY;
+       }
+
        /*
         * Store led settings, for correct led behaviour.
         * If the eeprom value is invalid,
@@ -2325,7 +2279,6 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
                                     struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u32 reg;
 
        /*
@@ -2344,22 +2297,19 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
         */
        if (mc_count)
                *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * Start configuration steps.
@@ -2426,6 +2376,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                          struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
 
        /*
         * Just in case the ieee80211 doesn't set this,
@@ -2433,6 +2386,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
 
        /*
         * We need to append the descriptor in front of the
@@ -2446,15 +2401,23 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
        }
 
        /*
-        * First we create the beacon.
+        * Add the descriptor in front of the skb.
+        */
+       skb_push(skb, ring->desc_size);
+       memset(skb->data, 0, ring->desc_size);
+
+       /*
+        * Fill in skb descriptor
         */
-       skb_push(skb, TXD_DESC_SIZE);
-       memset(skb->data, 0, TXD_DESC_SIZE);
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        TXD_DESC_SIZE),
-                               skb->len - TXD_DESC_SIZE, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Write entire beacon with descriptor to register,
@@ -2478,7 +2441,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .configure_filter       = rt61pci_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt61pci_set_retry_limit,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt61pci_get_tsf,
@@ -2493,6 +2456,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
        .load_firmware          = rt61pci_load_firmware,
        .initialize             = rt2x00pci_initialize,
        .uninitialize           = rt2x00pci_uninitialize,
+       .init_rxentry           = rt61pci_init_rxentry,
+       .init_txentry           = rt61pci_init_txentry,
        .set_device_state       = rt61pci_set_device_state,
        .rfkill_poll            = rt61pci_rfkill_poll,
        .link_stats             = rt61pci_link_stats,
@@ -2510,7 +2475,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt61pci_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -2547,7 +2512,7 @@ MODULE_FIRMWARE(FIRMWARE_RT2661);
 MODULE_LICENSE("GPL");
 
 static struct pci_driver rt61pci_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt61pci_device_table,
        .probe          = rt2x00pci_probe,
        .remove         = __devexit_p(rt2x00pci_remove),
index 6721d7dd32bc67222f2feae5730fc6f2050cc610..4c6524eedad0d219ca6ed3bb8e1f7267cb6b1520 100644 (file)
@@ -1077,13 +1077,19 @@ struct hw_pairwise_ta_entry {
  * R4: RX antenna control
  * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
  */
-#define BBP_R4_RX_ANTENNA              FIELD8(0x03)
+
+/*
+ * ANTENNA_CONTROL semantics (guessed):
+ * 0x1: Software controlled antenna switching (fixed or SW diversity)
+ * 0x2: Hardware diversity.
+ */
+#define BBP_R4_RX_ANTENNA_CONTROL      FIELD8(0x03)
 #define BBP_R4_RX_FRAME_END            FIELD8(0x20)
 
 /*
  * R77
  */
-#define BBP_R77_PAIR                   FIELD8(0x03)
+#define BBP_R77_RX_ANTENNA             FIELD8(0x03)
 
 /*
  * RF registers
@@ -1240,8 +1246,8 @@ struct hw_pairwise_ta_entry {
 /*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE                  ( 16 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE                  ( 16 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE                  ( 16 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 16 * sizeof(__le32) )
 
 /*
  * TX descriptor format for TX, PRIO and Beacon Ring.
index c0671c2e6e7301e93d9909c864fbda8b651a140b..4d576ab3e7f984f503608696d2112eb7d1793f54 100644 (file)
        Supported chipsets: rt2571W & rt2671.
  */
 
-/*
- * Set enviroment defines for rt2x00.h
- */
-#define DRV_NAME "rt73usb"
-
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
@@ -52,8 +47,9 @@
  * 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 usb_cache_mutex
  */
-static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev,
+static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev,
                                         const unsigned int offset, u32 *value)
 {
        __le32 reg;
@@ -63,8 +59,17 @@ static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev,
        *value = le32_to_cpu(reg);
 }
 
-static inline void rt73usb_register_multiread(const struct rt2x00_dev
-                                             *rt2x00dev,
+static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
+                                             const unsigned int offset, u32 *value)
+{
+       __le32 reg;
+       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
+                                      USB_VENDOR_REQUEST_IN, offset,
+                                      &reg, sizeof(u32), REGISTER_TIMEOUT);
+       *value = le32_to_cpu(reg);
+}
+
+static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev,
                                              const unsigned int offset,
                                              void *value, const u32 length)
 {
@@ -74,7 +79,7 @@ static inline void rt73usb_register_multiread(const struct rt2x00_dev
                                      value, length, timeout);
 }
 
-static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev,
+static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev,
                                          const unsigned int offset, u32 value)
 {
        __le32 reg = cpu_to_le32(value);
@@ -83,8 +88,16 @@ static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev,
                                      &reg, sizeof(u32), REGISTER_TIMEOUT);
 }
 
-static inline void rt73usb_register_multiwrite(const struct rt2x00_dev
-                                              *rt2x00dev,
+static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
+                                              const unsigned int offset, u32 value)
+{
+       __le32 reg = cpu_to_le32(value);
+       rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
+                                      USB_VENDOR_REQUEST_OUT, offset,
+                                     &reg, sizeof(u32), REGISTER_TIMEOUT);
+}
+
+static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
                                               const unsigned int offset,
                                               void *value, const u32 length)
 {
@@ -94,13 +107,13 @@ static inline void rt73usb_register_multiwrite(const struct rt2x00_dev
                                      value, length, timeout);
 }
 
-static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
+static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev)
 {
        u32 reg;
        unsigned int i;
 
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt73usb_register_read(rt2x00dev, PHY_CSR3, &reg);
+               rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, &reg);
                if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
                        break;
                udelay(REGISTER_BUSY_DELAY);
@@ -109,17 +122,20 @@ static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev)
        return reg;
 }
 
-static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
                              const unsigned int word, const u8 value)
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt73usb_bbp_check(rt2x00dev);
        if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
                ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
+               mutex_unlock(&rt2x00dev->usb_cache_mutex);
                return;
        }
 
@@ -132,20 +148,24 @@ static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
        rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
 
-       rt73usb_register_write(rt2x00dev, PHY_CSR3, reg);
+       rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
-static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, u8 *value)
 {
        u32 reg;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        /*
         * Wait until the BBP becomes ready.
         */
        reg = rt73usb_bbp_check(rt2x00dev);
        if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
                ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
+               mutex_unlock(&rt2x00dev->usb_cache_mutex);
                return;
        }
 
@@ -157,7 +177,7 @@ static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
        rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 1);
 
-       rt73usb_register_write(rt2x00dev, PHY_CSR3, reg);
+       rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
 
        /*
         * Wait until the BBP becomes ready.
@@ -170,9 +190,10 @@ static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev,
        }
 
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
-static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, const u32 value)
 {
        u32 reg;
@@ -181,13 +202,16 @@ static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev,
        if (!word)
                return;
 
+       mutex_lock(&rt2x00dev->usb_cache_mutex);
+
        for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-               rt73usb_register_read(rt2x00dev, PHY_CSR4, &reg);
+               rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, &reg);
                if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY))
                        goto rf_write;
                udelay(REGISTER_BUSY_DELAY);
        }
 
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
        ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n");
        return;
 
@@ -200,25 +224,26 @@ rf_write:
         * all others contain 20 bits.
         */
        rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS,
-                          20 + !!(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-                                  rt2x00_rf(&rt2x00dev->chip, RF2527)));
+                          20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+                                rt2x00_rf(&rt2x00dev->chip, RF2527)));
        rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
        rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
 
-       rt73usb_register_write(rt2x00dev, PHY_CSR4, reg);
+       rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg);
        rt2x00_rf_write(rt2x00dev, word, value);
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
 }
 
 #ifdef CONFIG_RT2X00_LIB_DEBUGFS
 #define CSR_OFFSET(__word)     ( CSR_REG_BASE + ((__word) * sizeof(u32)) )
 
-static void rt73usb_read_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev,
                             const unsigned int word, u32 *data)
 {
        rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data);
 }
 
-static void rt73usb_write_csr(const struct rt2x00_dev *rt2x00dev,
+static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev,
                              const unsigned int word, u32 data)
 {
        rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data);
@@ -302,7 +327,8 @@ static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type,
         */
        rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
-       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE,
+                          (tsf_sync == TSF_SYNC_BEACON));
        rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
        rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, tsf_sync);
        rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
@@ -396,12 +422,12 @@ static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
-                                     const int antenna_tx,
-                                     const int antenna_rx)
+                                     struct antenna_setup *ant)
 {
        u8 r3;
        u8 r4;
        u8 r77;
+       u8 temp;
 
        rt73usb_bbp_read(rt2x00dev, 3, &r3);
        rt73usb_bbp_read(rt2x00dev, 4, &r4);
@@ -409,30 +435,38 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
 
        rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
 
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-               rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-                                 !!(rt2x00dev->curr_hwmode != HWMODE_A));
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
+               temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
+                      && (rt2x00dev->curr_hwmode != HWMODE_A);
+               rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
                if (rt2x00dev->curr_hwmode == HWMODE_A)
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                else
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
-
                if (rt2x00dev->curr_hwmode == HWMODE_A)
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
                else
-                       rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+                       rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
                break;
        }
 
@@ -442,8 +476,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
 }
 
 static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
-                                     const int antenna_tx,
-                                     const int antenna_rx)
+                                     struct antenna_setup *ant)
 {
        u8 r3;
        u8 r4;
@@ -457,18 +490,27 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
                          !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
-       switch (antenna_rx) {
-       case ANTENNA_SW_DIVERSITY:
+       /*
+        * Configure the RX antenna.
+        */
+       switch (ant->rx) {
        case ANTENNA_HW_DIVERSITY:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
                break;
        case ANTENNA_A:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                break;
+       case ANTENNA_SW_DIVERSITY:
+               /*
+                * NOTE: We should never come here because rt2x00lib is
+                * supposed to catch this and send us the correct antenna
+                * explicitely. However we are nog going to bug about this.
+                * Instead, just default to antenna B.
+                */
        case ANTENNA_B:
-               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-               rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+               rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
+               rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
                break;
        }
 
@@ -509,40 +551,40 @@ static const struct antenna_sel antenna_sel_bg[] = {
 };
 
 static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-                                  const int antenna_tx, const int antenna_rx)
+                                  struct antenna_setup *ant)
 {
        const struct antenna_sel *sel;
        unsigned int lna;
        unsigned int i;
        u32 reg;
 
-       rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
-
        if (rt2x00dev->curr_hwmode == HWMODE_A) {
                sel = antenna_sel_a;
                lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
        } else {
                sel = antenna_sel_bg;
                lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
-
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
-               rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
        }
 
        for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
                rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
 
+       rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
+
+       rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
+                          (rt2x00dev->curr_hwmode == HWMODE_B ||
+                           rt2x00dev->curr_hwmode == HWMODE_G));
+       rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
+                          (rt2x00dev->curr_hwmode == HWMODE_A));
+
        rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
 
        if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
            rt2x00_rf(&rt2x00dev->chip, RF5225))
-               rt73usb_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+               rt73usb_config_antenna_5x(rt2x00dev, ant);
        else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
                 rt2x00_rf(&rt2x00dev->chip, RF2527))
-               rt73usb_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+               rt73usb_config_antenna_2x(rt2x00dev, ant);
 }
 
 static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
@@ -586,8 +628,7 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
        if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL))
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & CONFIG_UPDATE_ANTENNA)
-               rt73usb_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx,
-                                      libconf->conf->antenna_sel_rx);
+               rt73usb_config_antenna(rt2x00dev, &libconf->ant);
        if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT))
                rt73usb_config_duration(rt2x00dev, libconf);
 }
@@ -605,12 +646,10 @@ static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev)
        rt73usb_register_write(rt2x00dev, MAC_CSR14, reg);
 
        rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
-       if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)
-               rt2x00_set_field16(&rt2x00dev->led_reg,
-                                  MCU_LEDCS_LINK_A_STATUS, 1);
-       else
-               rt2x00_set_field16(&rt2x00dev->led_reg,
-                                  MCU_LEDCS_LINK_BG_STATUS, 1);
+       rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
+                          (rt2x00dev->rx_status.phymode == MODE_IEEE80211A));
+       rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
+                          (rt2x00dev->rx_status.phymode != MODE_IEEE80211A));
 
        rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
                                    rt2x00dev->led_reg, REGISTER_TIMEOUT);
@@ -659,7 +698,8 @@ static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi)
 /*
  * Link tuning
  */
-static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev)
+static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev,
+                              struct link_qual *qual)
 {
        u32 reg;
 
@@ -667,15 +707,13 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev)
         * Update FCS error count from register.
         */
        rt73usb_register_read(rt2x00dev, STA_CSR0, &reg);
-       rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
+       qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR);
 
        /*
         * Update False CCA count from register.
         */
        rt73usb_register_read(rt2x00dev, STA_CSR1, &reg);
-       reg = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
-       rt2x00dev->link.false_cca =
-           rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
+       qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
 }
 
 static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
@@ -781,12 +819,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
         * r17 does not yet exceed upper limit, continue and base
         * the r17 tuning on the false CCA count.
         */
-       if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) {
+       if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
                r17 += 4;
                if (r17 > up_bound)
                        r17 = up_bound;
                rt73usb_bbp_write(rt2x00dev, 17, r17);
-       } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) {
+       } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
                r17 -= 4;
                if (r17 < low_bound)
                        r17 = low_bound;
@@ -1098,8 +1136,6 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev)
                return -EIO;
        }
 
-       rt2x00usb_enable_radio(rt2x00dev);
-
        /*
         * Enable LED
         */
@@ -1193,12 +1229,12 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-                                 struct data_desc *txd,
-                                 struct txdata_entry_desc *desc,
-                                 struct ieee80211_hdr *ieee80211hdr,
-                                 unsigned int length,
-                                 struct ieee80211_tx_control *control)
+                                   struct sk_buff *skb,
+                                   struct txdata_entry_desc *desc,
+                                   struct ieee80211_tx_control *control)
 {
+       struct skb_desc *skbdesc = get_skb_desc(skb);
+       __le32 *txd = skbdesc->desc;
        u32 word;
 
        /*
@@ -1233,7 +1269,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
                           test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_ACK,
-                          !(control->flags & IEEE80211_TXCTL_NO_ACK));
+                          test_bit(ENTRY_TXD_ACK, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
                           test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_OFDM,
@@ -1243,7 +1279,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
                           !!(control->flags &
                              IEEE80211_TXCTL_LONG_RETRY_LIMIT));
        rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
-       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
+       rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len);
        rt2x00_set_field32(&word, TXD_W0_BURST2,
                           test_bit(ENTRY_TXD_BURST, &desc->flags));
        rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
@@ -1340,7 +1376,8 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 static void rt73usb_fill_rxdone(struct data_entry *entry,
                                struct rxdata_entry_desc *desc)
 {
-       struct data_desc *rxd = (struct data_desc *)entry->skb->data;
+       struct skb_desc *skbdesc = get_skb_desc(entry->skb);
+       __le32 *rxd = (__le32 *)entry->skb->data;
        u32 word0;
        u32 word1;
 
@@ -1358,13 +1395,15 @@ static void rt73usb_fill_rxdone(struct data_entry *entry,
        desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1);
        desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
        desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+       desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS);
 
        /*
-        * Pull the skb to clear the descriptor area.
+        * Set descriptor and data pointer.
         */
-       skb_pull(entry->skb, entry->ring->desc_size);
-
-       return;
+       skbdesc->desc = entry->skb->data;
+       skbdesc->desc_len = entry->ring->desc_size;
+       skbdesc->data = entry->skb->data + entry->ring->desc_size;
+       skbdesc->data_len = desc->size;
 }
 
 /*
@@ -1392,8 +1431,10 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
        if (word == 0xffff) {
                rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2);
-               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT,
+                                  ANTENNA_B);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT,
+                                  ANTENNA_B);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0);
                rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0);
@@ -1502,9 +1543,9 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        /*
         * Identify default antenna configuration.
         */
-       rt2x00dev->hw->conf.antenna_sel_tx =
+       rt2x00dev->default_ant.tx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT);
-       rt2x00dev->hw->conf.antenna_sel_rx =
+       rt2x00dev->default_ant.rx =
            rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT);
 
        /*
@@ -1806,7 +1847,6 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,
                                     struct dev_addr_list *mc_list)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct interface *intf = &rt2x00dev->interface;
        u32 reg;
 
        /*
@@ -1825,22 +1865,19 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw,
         * Apply some rules to the filters:
         * - Some filters imply different filters to be set.
         * - Some things we can't filter out at all.
-        * - Some filters are set based on interface type.
         */
        if (mc_count)
                *total_flags |= FIF_ALLMULTI;
        if (*total_flags & FIF_OTHER_BSS ||
            *total_flags & FIF_PROMISC_IN_BSS)
                *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
-       if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
-               *total_flags |= FIF_PROMISC_IN_BSS;
 
        /*
         * Check if there is any work left for us.
         */
-       if (intf->filter == *total_flags)
+       if (rt2x00dev->packet_filter == *total_flags)
                return;
-       intf->filter = *total_flags;
+       rt2x00dev->packet_filter = *total_flags;
 
        /*
         * When in atomic context, reschedule and let rt2x00lib
@@ -1926,6 +1963,9 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
                          struct ieee80211_tx_control *control)
 {
        struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct skb_desc *desc;
+       struct data_ring *ring;
+       struct data_entry *entry;
        int timeout;
 
        /*
@@ -1934,17 +1974,27 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * initialization.
         */
        control->queue = IEEE80211_TX_QUEUE_BEACON;
+       ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+       entry = rt2x00_get_data_entry(ring);
+
+       /*
+        * Add the descriptor in front of the skb.
+        */
+       skb_push(skb, ring->desc_size);
+       memset(skb->data, 0, ring->desc_size);
 
        /*
-        * First we create the beacon.
+        * Fill in skb descriptor
         */
-       skb_push(skb, TXD_DESC_SIZE);
-       memset(skb->data, 0, TXD_DESC_SIZE);
+       desc = get_skb_desc(skb);
+       desc->desc_len = ring->desc_size;
+       desc->data_len = skb->len - ring->desc_size;
+       desc->desc = skb->data;
+       desc->data = skb->data + ring->desc_size;
+       desc->ring = ring;
+       desc->entry = entry;
 
-       rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
-                               (struct ieee80211_hdr *)(skb->data +
-                                                        TXD_DESC_SIZE),
-                               skb->len - TXD_DESC_SIZE, control);
+       rt2x00lib_write_tx_desc(rt2x00dev, skb, control);
 
        /*
         * Write entire beacon with descriptor to register,
@@ -1971,7 +2021,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .configure_filter       = rt73usb_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .set_retry_limit        = rt73usb_set_retry_limit,
-       .erp_ie_changed         = rt2x00mac_erp_ie_changed,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
        .conf_tx                = rt2x00mac_conf_tx,
        .get_tx_stats           = rt2x00mac_get_tx_stats,
        .get_tsf                = rt73usb_get_tsf,
@@ -1985,6 +2035,8 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
        .load_firmware          = rt73usb_load_firmware,
        .initialize             = rt2x00usb_initialize,
        .uninitialize           = rt2x00usb_uninitialize,
+       .init_rxentry           = rt2x00usb_init_rxentry,
+       .init_txentry           = rt2x00usb_init_txentry,
        .set_device_state       = rt73usb_set_device_state,
        .link_stats             = rt73usb_link_stats,
        .reset_tuner            = rt73usb_reset_tuner,
@@ -2002,7 +2054,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
 };
 
 static const struct rt2x00_ops rt73usb_ops = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .rxd_size       = RXD_DESC_SIZE,
        .txd_size       = TXD_DESC_SIZE,
        .eeprom_size    = EEPROM_SIZE,
@@ -2089,7 +2141,7 @@ MODULE_FIRMWARE(FIRMWARE_RT2571);
 MODULE_LICENSE("GPL");
 
 static struct usb_driver rt73usb_driver = {
-       .name           = DRV_NAME,
+       .name           = KBUILD_MODNAME,
        .id_table       = rt73usb_device_table,
        .probe          = rt2x00usb_probe,
        .disconnect     = rt2x00usb_disconnect,
index f0951519f74b32592077587d22dfa304d5b9e9fe..d49dcaaceceec65066b7a816412969adb7063201 100644 (file)
@@ -713,13 +713,19 @@ struct hw_pairwise_ta_entry {
  * R4: RX antenna control
  * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
  */
-#define BBP_R4_RX_ANTENNA              FIELD8(0x03)
+
+/*
+ * ANTENNA_CONTROL semantics (guessed):
+ * 0x1: Software controlled antenna switching (fixed or SW diversity)
+ * 0x2: Hardware diversity.
+ */
+#define BBP_R4_RX_ANTENNA_CONTROL      FIELD8(0x03)
 #define BBP_R4_RX_FRAME_END            FIELD8(0x20)
 
 /*
  * R77
  */
-#define BBP_R77_PAIR                   FIELD8(0x03)
+#define BBP_R77_RX_ANTENNA             FIELD8(0x03)
 
 /*
  * RF registers
@@ -860,8 +866,8 @@ struct hw_pairwise_ta_entry {
 /*
  * DMA descriptor defines.
  */
-#define TXD_DESC_SIZE                  ( 6 * sizeof(struct data_desc) )
-#define RXD_DESC_SIZE                  ( 6 * sizeof(struct data_desc) )
+#define TXD_DESC_SIZE                  ( 6 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 6 * sizeof(__le32) )
 
 /*
  * TX descriptor format for TX, PRIO and Beacon Ring.
diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h
new file mode 100644 (file)
index 0000000..2cbfe3c
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef RTL8180_H
+#define RTL8180_H
+
+#include "rtl818x.h"
+
+#define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD
+
+#define RF_PARAM_ANALOGPHY     (1 << 0)
+#define RF_PARAM_ANTBDEFAULT   (1 << 1)
+#define RF_PARAM_CARRIERSENSE1 (1 << 2)
+#define RF_PARAM_CARRIERSENSE2 (1 << 3)
+
+#define BB_ANTATTEN_CHAN14     0x0C
+#define BB_ANTENNA_B           0x40
+
+#define BB_HOST_BANG           (1 << 30)
+#define BB_HOST_BANG_EN        (1 << 2)
+#define BB_HOST_BANG_CLK       (1 << 1)
+#define BB_HOST_BANG_DATA      1
+
+#define ANAPARAM_TXDACOFF_SHIFT        27
+#define ANAPARAM_PWR0_SHIFT    28
+#define ANAPARAM_PWR0_MASK     (0x07 << ANAPARAM_PWR0_SHIFT)
+#define ANAPARAM_PWR1_SHIFT    20
+#define ANAPARAM_PWR1_MASK     (0x7F << ANAPARAM_PWR1_SHIFT)
+
+enum rtl8180_tx_desc_flags {
+       RTL8180_TX_DESC_FLAG_NO_ENC     = (1 << 15),
+       RTL8180_TX_DESC_FLAG_TX_OK      = (1 << 15),
+       RTL8180_TX_DESC_FLAG_SPLCP      = (1 << 16),
+       RTL8180_TX_DESC_FLAG_RX_UNDER   = (1 << 16),
+       RTL8180_TX_DESC_FLAG_MOREFRAG   = (1 << 17),
+       RTL8180_TX_DESC_FLAG_CTS        = (1 << 18),
+       RTL8180_TX_DESC_FLAG_RTS        = (1 << 23),
+       RTL8180_TX_DESC_FLAG_LS         = (1 << 28),
+       RTL8180_TX_DESC_FLAG_FS         = (1 << 29),
+       RTL8180_TX_DESC_FLAG_DMA        = (1 << 30),
+       RTL8180_TX_DESC_FLAG_OWN        = (1 << 31)
+};
+
+struct rtl8180_tx_desc {
+       __le32 flags;
+       __le16 rts_duration;
+       __le16 plcp_len;
+       __le32 tx_buf;
+       __le32 frame_len;
+       __le32 next_tx_desc;
+       u8 cw;
+       u8 retry_limit;
+       u8 agc;
+       u8 flags2;
+       u32 reserved[2];
+} __attribute__ ((packed));
+
+enum rtl8180_rx_desc_flags {
+       RTL8180_RX_DESC_FLAG_ICV_ERR    = (1 << 12),
+       RTL8180_RX_DESC_FLAG_CRC32_ERR  = (1 << 13),
+       RTL8180_RX_DESC_FLAG_PM         = (1 << 14),
+       RTL8180_RX_DESC_FLAG_RX_ERR     = (1 << 15),
+       RTL8180_RX_DESC_FLAG_BCAST      = (1 << 16),
+       RTL8180_RX_DESC_FLAG_PAM        = (1 << 17),
+       RTL8180_RX_DESC_FLAG_MCAST      = (1 << 18),
+       RTL8180_RX_DESC_FLAG_SPLCP      = (1 << 25),
+       RTL8180_RX_DESC_FLAG_FOF        = (1 << 26),
+       RTL8180_RX_DESC_FLAG_DMA_FAIL   = (1 << 27),
+       RTL8180_RX_DESC_FLAG_LS         = (1 << 28),
+       RTL8180_RX_DESC_FLAG_FS         = (1 << 29),
+       RTL8180_RX_DESC_FLAG_EOR        = (1 << 30),
+       RTL8180_RX_DESC_FLAG_OWN        = (1 << 31)
+};
+
+struct rtl8180_rx_desc {
+       __le32 flags;
+       __le32 flags2;
+       union {
+               __le32 rx_buf;
+               __le64 tsft;
+       };
+} __attribute__ ((packed));
+
+struct rtl8180_tx_ring {
+       struct rtl8180_tx_desc *desc;
+       dma_addr_t dma;
+       unsigned int idx;
+       unsigned int entries;
+       struct sk_buff_head queue;
+};
+
+struct rtl8180_priv {
+       /* common between rtl818x drivers */
+       struct rtl818x_csr __iomem *map;
+       const struct rtl818x_rf_ops *rf;
+       struct ieee80211_vif *vif;
+       int mode;
+
+       /* rtl8180 driver specific */
+       spinlock_t lock;
+       struct rtl8180_rx_desc *rx_ring;
+       dma_addr_t rx_ring_dma;
+       unsigned int rx_idx;
+       struct sk_buff *rx_buf[32];
+       struct rtl8180_tx_ring tx_ring[4];
+       struct ieee80211_channel channels[14];
+       struct ieee80211_rate rates[12];
+       struct ieee80211_hw_mode modes[2];
+       struct pci_dev *pdev;
+       u32 rx_conf;
+
+       int r8185;
+       u32 anaparam;
+       u16 rfparam;
+       u8 csthreshold;
+};
+
+void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
+void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
+
+static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
+{
+       return ioread8(addr);
+}
+
+static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr)
+{
+       return ioread16(addr);
+}
+
+static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr)
+{
+       return ioread32(addr);
+}
+
+static inline void rtl818x_iowrite8(struct rtl8180_priv *priv,
+                                   u8 __iomem *addr, u8 val)
+{
+       iowrite8(val, addr);
+}
+
+static inline void rtl818x_iowrite16(struct rtl8180_priv *priv,
+                                    __le16 __iomem *addr, u16 val)
+{
+       iowrite16(val, addr);
+}
+
+static inline void rtl818x_iowrite32(struct rtl8180_priv *priv,
+                                    __le32 __iomem *addr, u32 val)
+{
+       iowrite32(val, addr);
+}
+
+#endif /* RTL8180_H */
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
new file mode 100644 (file)
index 0000000..07f37b0
--- /dev/null
@@ -0,0 +1,1051 @@
+
+/*
+ * Linux device driver for RTL8180 / RTL8185
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8180 driver, which is:
+ * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/eeprom_93cx6.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_rtl8225.h"
+#include "rtl8180_sa2400.h"
+#include "rtl8180_max2820.h"
+#include "rtl8180_grf5101.h"
+
+MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
+MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
+MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver");
+MODULE_LICENSE("GPL");
+
+static struct pci_device_id rtl8180_table[] __devinitdata = {
+       /* rtl8185 */
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
+
+       /* rtl8180 */
+       { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) },
+       { PCI_DEVICE(0x1799, 0x6001) },
+       { PCI_DEVICE(0x1799, 0x6020) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
+       { }
+};
+
+MODULE_DEVICE_TABLE(pci, rtl8180_table);
+
+void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       int i = 10;
+       u32 buf;
+
+       buf = (data << 8) | addr;
+
+       rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80);
+       while (i--) {
+               rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf);
+               if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF))
+                       return;
+       }
+}
+
+static void rtl8180_handle_rx(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       unsigned int count = 32;
+
+       while (count--) {
+               struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
+               struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
+               u32 flags = le32_to_cpu(entry->flags);
+
+               if (flags & RTL8180_RX_DESC_FLAG_OWN)
+                       return;
+
+               if (unlikely(flags & (RTL8180_RX_DESC_FLAG_DMA_FAIL |
+                                     RTL8180_RX_DESC_FLAG_FOF |
+                                     RTL8180_RX_DESC_FLAG_RX_ERR)))
+                       goto done;
+               else {
+                       u32 flags2 = le32_to_cpu(entry->flags2);
+                       struct ieee80211_rx_status rx_status = {0};
+                       struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
+
+                       if (unlikely(!new_skb))
+                               goto done;
+
+                       pci_unmap_single(priv->pdev,
+                                        *((dma_addr_t *)skb->cb),
+                                        MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
+                       skb_put(skb, flags & 0xFFF);
+
+                       rx_status.antenna = (flags2 >> 15) & 1;
+                       /* TODO: improve signal/rssi reporting */
+                       rx_status.signal = flags2 & 0xFF;
+                       rx_status.ssi = (flags2 >> 8) & 0x7F;
+                       rx_status.rate = (flags >> 20) & 0xF;
+                       rx_status.freq = dev->conf.freq;
+                       rx_status.channel = dev->conf.channel;
+                       rx_status.phymode = dev->conf.phymode;
+                       rx_status.mactime = le64_to_cpu(entry->tsft);
+                       rx_status.flag |= RX_FLAG_TSFT;
+                       if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR)
+                               rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
+
+                       ieee80211_rx_irqsafe(dev, skb, &rx_status);
+
+                       skb = new_skb;
+                       priv->rx_buf[priv->rx_idx] = skb;
+                       *((dma_addr_t *) skb->cb) =
+                               pci_map_single(priv->pdev, skb_tail_pointer(skb),
+                                              MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
+               }
+
+       done:
+               entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
+               entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN |
+                                          MAX_RX_SIZE);
+               if (priv->rx_idx == 31)
+                       entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR);
+               priv->rx_idx = (priv->rx_idx + 1) % 32;
+       }
+}
+
+static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
+
+       while (skb_queue_len(&ring->queue)) {
+               struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
+               struct sk_buff *skb;
+               struct ieee80211_tx_status status = { {0} };
+               struct ieee80211_tx_control *control;
+               u32 flags = le32_to_cpu(entry->flags);
+
+               if (flags & RTL8180_TX_DESC_FLAG_OWN)
+                       return;
+
+               ring->idx = (ring->idx + 1) % ring->entries;
+               skb = __skb_dequeue(&ring->queue);
+               pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
+                                skb->len, PCI_DMA_TODEVICE);
+
+               control = *((struct ieee80211_tx_control **)skb->cb);
+               if (control)
+                       memcpy(&status.control, control, sizeof(*control));
+               kfree(control);
+
+               if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+                       if (flags & RTL8180_TX_DESC_FLAG_TX_OK)
+                               status.flags = IEEE80211_TX_STATUS_ACK;
+                       else
+                               status.excessive_retries = 1;
+               }
+               status.retry_count = flags & 0xFF;
+
+               ieee80211_tx_status_irqsafe(dev, skb, &status);
+               if (ring->entries - skb_queue_len(&ring->queue) == 2)
+                       ieee80211_wake_queue(dev, prio);
+       }
+}
+
+static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
+{
+       struct ieee80211_hw *dev = dev_id;
+       struct rtl8180_priv *priv = dev->priv;
+       u16 reg;
+
+       spin_lock(&priv->lock);
+       reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
+       if (unlikely(reg == 0xFFFF)) {
+               spin_unlock(&priv->lock);
+               return IRQ_HANDLED;
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
+
+       if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
+               rtl8180_handle_tx(dev, 3);
+
+       if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR))
+               rtl8180_handle_tx(dev, 2);
+
+       if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
+               rtl8180_handle_tx(dev, 1);
+
+       if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
+               rtl8180_handle_tx(dev, 0);
+
+       if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
+               rtl8180_handle_rx(dev);
+
+       spin_unlock(&priv->lock);
+
+       return IRQ_HANDLED;
+}
+
+static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
+                     struct ieee80211_tx_control *control)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       struct rtl8180_tx_ring *ring;
+       struct rtl8180_tx_desc *entry;
+       unsigned long flags;
+       unsigned int idx, prio;
+       dma_addr_t mapping;
+       u32 tx_flags;
+       u16 plcp_len = 0;
+       __le16 rts_duration = 0;
+
+       prio = control->queue;
+       ring = &priv->tx_ring[prio];
+
+       mapping = pci_map_single(priv->pdev, skb->data,
+                                skb->len, PCI_DMA_TODEVICE);
+
+       tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
+                  RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) |
+                  (control->rts_cts_rate << 19) | skb->len;
+
+       if (priv->r8185)
+               tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
+                           RTL8180_TX_DESC_FLAG_NO_ENC;
+
+       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+               tx_flags |= RTL8180_TX_DESC_FLAG_RTS;
+       else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
+               tx_flags |= RTL8180_TX_DESC_FLAG_CTS;
+
+       *((struct ieee80211_tx_control **) skb->cb) =
+               kmemdup(control, sizeof(*control), GFP_ATOMIC);
+
+       if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
+               rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
+                                                     control);
+
+       if (!priv->r8185) {
+               unsigned int remainder;
+
+               plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
+                                       (control->rate->rate * 2) / 10);
+               remainder = (16 * (skb->len + 4)) %
+                           ((control->rate->rate * 2) / 10);
+               if (remainder > 0 && remainder <= 6)
+                       plcp_len |= 1 << 15;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+       entry = &ring->desc[idx];
+
+       entry->rts_duration = rts_duration;
+       entry->plcp_len = cpu_to_le16(plcp_len);
+       entry->tx_buf = cpu_to_le32(mapping);
+       entry->frame_len = cpu_to_le32(skb->len);
+       entry->flags2 = control->alt_retry_rate != -1 ?
+                       control->alt_retry_rate << 4 : 0;
+       entry->retry_limit = control->retry_limit;
+       entry->flags = cpu_to_le32(tx_flags);
+       __skb_queue_tail(&ring->queue, skb);
+       if (ring->entries - skb_queue_len(&ring->queue) < 2)
+               ieee80211_stop_queue(dev, control->queue);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4)));
+
+       return 0;
+}
+
+void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
+{
+       u8 reg;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+                reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3,
+                reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+}
+
+static int rtl8180_init_hw(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u16 reg;
+
+       rtl818x_iowrite8(priv, &priv->map->CMD, 0);
+       rtl818x_ioread8(priv, &priv->map->CMD);
+       msleep(10);
+
+       /* reset */
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+       rtl818x_ioread8(priv, &priv->map->CMD);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg &= (1 << 1);
+       reg |= RTL818X_CMD_RESET;
+       rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET);
+       rtl818x_ioread8(priv, &priv->map->CMD);
+       msleep(200);
+
+       /* check success of reset */
+       if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
+               printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
+               return -ETIMEDOUT;
+       }
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
+       rtl818x_ioread8(priv, &priv->map->CMD);
+       msleep(200);
+
+       if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) {
+               /* For cardbus */
+               reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+               reg |= 1 << 1;
+               rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
+               reg = rtl818x_ioread16(priv, &priv->map->FEMR);
+               reg |= (1 << 15) | (1 << 14) | (1 << 4);
+               rtl818x_iowrite16(priv, &priv->map->FEMR, reg);
+       }
+
+       rtl818x_iowrite8(priv, &priv->map->MSR, 0);
+
+       if (!priv->r8185)
+               rtl8180_set_anaparam(priv, priv->anaparam);
+
+       rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
+       rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
+       rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
+       rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
+       rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
+
+       /* TODO: necessary? specs indicate not */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3));
+       if (priv->r8185) {
+               reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
+               rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4));
+       }
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */
+
+       /* TODO: turn off hw wep on rtl8180 */
+
+       rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
+
+       if (priv->r8185) {
+               rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
+               rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
+               rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
+
+               rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+
+               /* TODO: set ClkRun enable? necessary? */
+               reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
+               rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
+               rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+               reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+               rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
+               rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+       } else {
+               rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1);
+               rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
+
+               rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
+               rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
+       }
+
+       priv->rf->init(dev);
+       if (priv->r8185)
+               rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
+       return 0;
+}
+
+static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       struct rtl8180_rx_desc *entry;
+       int i;
+
+       priv->rx_ring = pci_alloc_consistent(priv->pdev,
+                                            sizeof(*priv->rx_ring) * 32,
+                                            &priv->rx_ring_dma);
+
+       if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
+               printk(KERN_ERR "%s: Cannot allocate RX ring\n",
+                      wiphy_name(dev->wiphy));
+               return -ENOMEM;
+       }
+
+       memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32);
+       priv->rx_idx = 0;
+
+       for (i = 0; i < 32; i++) {
+               struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
+               dma_addr_t *mapping;
+               entry = &priv->rx_ring[i];
+               if (!skb)
+                       return 0;
+
+               priv->rx_buf[i] = skb;
+               mapping = (dma_addr_t *)skb->cb;
+               *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb),
+                                         MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
+               entry->rx_buf = cpu_to_le32(*mapping);
+               entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN |
+                                          MAX_RX_SIZE);
+       }
+       entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR);
+       return 0;
+}
+
+static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       int i;
+
+       for (i = 0; i < 32; i++) {
+               struct sk_buff *skb = priv->rx_buf[i];
+               if (!skb)
+                       continue;
+
+               pci_unmap_single(priv->pdev,
+                                *((dma_addr_t *)skb->cb),
+                                MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
+               kfree_skb(skb);
+       }
+
+       pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32,
+                           priv->rx_ring, priv->rx_ring_dma);
+       priv->rx_ring = NULL;
+}
+
+static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
+                               unsigned int prio, unsigned int entries)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       struct rtl8180_tx_desc *ring;
+       dma_addr_t dma;
+       int i;
+
+       ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
+       if (!ring || (unsigned long)ring & 0xFF) {
+               printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
+                      wiphy_name(dev->wiphy), prio);
+               return -ENOMEM;
+       }
+
+       memset(ring, 0, sizeof(*ring)*entries);
+       priv->tx_ring[prio].desc = ring;
+       priv->tx_ring[prio].dma = dma;
+       priv->tx_ring[prio].idx = 0;
+       priv->tx_ring[prio].entries = entries;
+       skb_queue_head_init(&priv->tx_ring[prio].queue);
+
+       for (i = 0; i < entries; i++)
+               ring[i].next_tx_desc =
+                       cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
+
+       return 0;
+}
+
+static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
+
+       while (skb_queue_len(&ring->queue)) {
+               struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
+               struct sk_buff *skb = __skb_dequeue(&ring->queue);
+
+               pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf),
+                                skb->len, PCI_DMA_TODEVICE);
+               kfree(*((struct ieee80211_tx_control **) skb->cb));
+               kfree_skb(skb);
+               ring->idx = (ring->idx + 1) % ring->entries;
+       }
+
+       pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
+                           ring->desc, ring->dma);
+       ring->desc = NULL;
+}
+
+static int rtl8180_start(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       int ret, i;
+       u32 reg;
+
+       ret = rtl8180_init_rx_ring(dev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < 4; i++)
+               if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
+                       goto err_free_rings;
+
+       ret = rtl8180_init_hw(dev);
+       if (ret)
+               goto err_free_rings;
+
+       rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
+       rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma);
+       rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma);
+       rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma);
+       rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma);
+
+       ret = request_irq(priv->pdev->irq, &rtl8180_interrupt,
+                         IRQF_SHARED, KBUILD_MODNAME, dev);
+       if (ret) {
+               printk(KERN_ERR "%s: failed to register IRQ handler\n",
+                      wiphy_name(dev->wiphy));
+               goto err_free_rings;
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
+
+       rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
+       rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
+
+       reg = RTL818X_RX_CONF_ONLYERLPKT |
+             RTL818X_RX_CONF_RX_AUTORESETPHY |
+             RTL818X_RX_CONF_MGMT |
+             RTL818X_RX_CONF_DATA |
+             (7 << 8 /* MAX RX DMA */) |
+             RTL818X_RX_CONF_BROADCAST |
+             RTL818X_RX_CONF_NICMAC;
+
+       if (priv->r8185)
+               reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2;
+       else {
+               reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1)
+                       ? RTL818X_RX_CONF_CSDM1 : 0;
+               reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2)
+                       ? RTL818X_RX_CONF_CSDM2 : 0;
+       }
+
+       priv->rx_conf = reg;
+       rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
+
+       if (priv->r8185) {
+               reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
+               reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
+               reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
+               rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
+
+               reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
+               reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
+               reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
+               reg |=  RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
+               rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
+
+               /* disable early TX */
+               rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f);
+       }
+
+       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+       reg |= (6 << 21 /* MAX TX DMA */) |
+              RTL818X_TX_CONF_NO_ICV;
+
+       if (priv->r8185)
+               reg &= ~RTL818X_TX_CONF_PROBE_DTS;
+       else
+               reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
+
+       /* different meaning, same value on both rtl8185 and rtl8180 */
+       reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
+
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg |= RTL818X_CMD_RX_ENABLE;
+       reg |= RTL818X_CMD_TX_ENABLE;
+       rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+
+       priv->mode = IEEE80211_IF_TYPE_MNTR;
+       return 0;
+
+ err_free_rings:
+       rtl8180_free_rx_ring(dev);
+       for (i = 0; i < 4; i++)
+               if (priv->tx_ring[i].desc)
+                       rtl8180_free_tx_ring(dev, i);
+
+       return ret;
+}
+
+static void rtl8180_stop(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 reg;
+       int i;
+
+       priv->mode = IEEE80211_IF_TYPE_INVALID;
+
+       rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
+
+       reg = rtl818x_ioread8(priv, &priv->map->CMD);
+       reg &= ~RTL818X_CMD_TX_ENABLE;
+       reg &= ~RTL818X_CMD_RX_ENABLE;
+       rtl818x_iowrite8(priv, &priv->map->CMD, reg);
+
+       priv->rf->stop(dev);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       free_irq(priv->pdev->irq, dev);
+
+       rtl8180_free_rx_ring(dev);
+       for (i = 0; i < 4; i++)
+               rtl8180_free_tx_ring(dev, i);
+}
+
+static int rtl8180_add_interface(struct ieee80211_hw *dev,
+                                struct ieee80211_if_init_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       if (priv->mode != IEEE80211_IF_TYPE_MNTR)
+               return -EOPNOTSUPP;
+
+       switch (conf->type) {
+       case IEEE80211_IF_TYPE_STA:
+               priv->mode = conf->type;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       priv->vif = conf->vif;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
+                         cpu_to_le32(*(u32 *)conf->mac_addr));
+       rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
+                         cpu_to_le16(*(u16 *)(conf->mac_addr + 4)));
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       return 0;
+}
+
+static void rtl8180_remove_interface(struct ieee80211_hw *dev,
+                                    struct ieee80211_if_init_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       priv->mode = IEEE80211_IF_TYPE_MNTR;
+       priv->vif = NULL;
+}
+
+static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       priv->rf->set_chan(dev, conf);
+
+       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_configure_filter(struct ieee80211_hw *dev,
+                                    unsigned int changed_flags,
+                                    unsigned int *total_flags,
+                                    int mc_count, struct dev_addr_list *mclist)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       if (changed_flags & FIF_FCSFAIL)
+               priv->rx_conf ^= RTL818X_RX_CONF_FCS;
+       if (changed_flags & FIF_CONTROL)
+               priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
+       if (changed_flags & FIF_OTHER_BSS)
+               priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
+       if (*total_flags & FIF_ALLMULTI || mc_count > 0)
+               priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
+       else
+               priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
+
+       *total_flags = 0;
+
+       if (priv->rx_conf & RTL818X_RX_CONF_FCS)
+               *total_flags |= FIF_FCSFAIL;
+       if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
+               *total_flags |= FIF_CONTROL;
+       if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
+               *total_flags |= FIF_OTHER_BSS;
+       if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
+               *total_flags |= FIF_ALLMULTI;
+
+       rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
+}
+
+static const struct ieee80211_ops rtl8180_ops = {
+       .tx                     = rtl8180_tx,
+       .start                  = rtl8180_start,
+       .stop                   = rtl8180_stop,
+       .add_interface          = rtl8180_add_interface,
+       .remove_interface       = rtl8180_remove_interface,
+       .config                 = rtl8180_config,
+       .config_interface       = rtl8180_config_interface,
+       .configure_filter       = rtl8180_configure_filter,
+};
+
+static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+       struct ieee80211_hw *dev = eeprom->data;
+       struct rtl8180_priv *priv = dev->priv;
+       u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+
+       eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
+       eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
+       eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
+       eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
+}
+
+static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+       struct ieee80211_hw *dev = eeprom->data;
+       struct rtl8180_priv *priv = dev->priv;
+       u8 reg = 2 << 6;
+
+       if (eeprom->reg_data_in)
+               reg |= RTL818X_EEPROM_CMD_WRITE;
+       if (eeprom->reg_data_out)
+               reg |= RTL818X_EEPROM_CMD_READ;
+       if (eeprom->reg_data_clock)
+               reg |= RTL818X_EEPROM_CMD_CK;
+       if (eeprom->reg_chip_select)
+               reg |= RTL818X_EEPROM_CMD_CS;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(10);
+}
+
+static int __devinit rtl8180_probe(struct pci_dev *pdev,
+                                  const struct pci_device_id *id)
+{
+       struct ieee80211_hw *dev;
+       struct rtl8180_priv *priv;
+       unsigned long mem_addr, mem_len;
+       unsigned int io_addr, io_len;
+       int err, i;
+       struct eeprom_93cx6 eeprom;
+       const char *chip_name, *rf_name = NULL;
+       u32 reg;
+       u16 eeprom_val;
+       DECLARE_MAC_BUF(mac);
+
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n",
+                      pci_name(pdev));
+               return err;
+       }
+
+       err = pci_request_regions(pdev, KBUILD_MODNAME);
+       if (err) {
+               printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n",
+                      pci_name(pdev));
+               return err;
+       }
+
+       io_addr = pci_resource_start(pdev, 0);
+       io_len = pci_resource_len(pdev, 0);
+       mem_addr = pci_resource_start(pdev, 1);
+       mem_len = pci_resource_len(pdev, 1);
+
+       if (mem_len < sizeof(struct rtl818x_csr) ||
+           io_len < sizeof(struct rtl818x_csr)) {
+               printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n",
+                      pci_name(pdev));
+               err = -ENOMEM;
+               goto err_free_reg;
+       }
+
+       if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) ||
+           (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) {
+               printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
+                      pci_name(pdev));
+               goto err_free_reg;
+       }
+
+       pci_set_master(pdev);
+
+       dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops);
+       if (!dev) {
+               printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n",
+                      pci_name(pdev));
+               err = -ENOMEM;
+               goto err_free_reg;
+       }
+
+       priv = dev->priv;
+       priv->pdev = pdev;
+
+       SET_IEEE80211_DEV(dev, &pdev->dev);
+       pci_set_drvdata(pdev, dev);
+
+       priv->map = pci_iomap(pdev, 1, mem_len);
+       if (!priv->map)
+               priv->map = pci_iomap(pdev, 0, io_len);
+
+       if (!priv->map) {
+               printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n",
+                      pci_name(pdev));
+               goto err_free_dev;
+       }
+
+       memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
+       memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
+       priv->modes[0].mode = MODE_IEEE80211G;
+       priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates);
+       priv->modes[0].rates = priv->rates;
+       priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels);
+       priv->modes[0].channels = priv->channels;
+       priv->modes[1].mode = MODE_IEEE80211B;
+       priv->modes[1].num_rates = 4;
+       priv->modes[1].rates = priv->rates;
+       priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
+       priv->modes[1].channels = priv->channels;
+       priv->mode = IEEE80211_IF_TYPE_INVALID;
+       dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                    IEEE80211_HW_RX_INCLUDES_FCS;
+       dev->queues = 1;
+       dev->max_rssi = 65;
+
+       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+       reg &= RTL818X_TX_CONF_HWVER_MASK;
+       switch (reg) {
+       case RTL818X_TX_CONF_R8180_ABCD:
+               chip_name = "RTL8180";
+               break;
+       case RTL818X_TX_CONF_R8180_F:
+               chip_name = "RTL8180vF";
+               break;
+       case RTL818X_TX_CONF_R8185_ABC:
+               chip_name = "RTL8185";
+               break;
+       case RTL818X_TX_CONF_R8185_D:
+               chip_name = "RTL8185vD";
+               break;
+       default:
+               printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
+                      pci_name(pdev), reg >> 25);
+               goto err_iounmap;
+       }
+
+       priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
+       if (priv->r8185) {
+               if ((err = ieee80211_register_hwmode(dev, &priv->modes[0])))
+                       goto err_iounmap;
+
+               pci_try_set_mwi(pdev);
+       }
+
+       if ((err = ieee80211_register_hwmode(dev, &priv->modes[1])))
+               goto err_iounmap;
+
+       eeprom.data = dev;
+       eeprom.register_read = rtl8180_eeprom_register_read;
+       eeprom.register_write = rtl8180_eeprom_register_write;
+       if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
+               eeprom.width = PCI_EEPROM_WIDTH_93C66;
+       else
+               eeprom.width = PCI_EEPROM_WIDTH_93C46;
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(10);
+
+       eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
+       eeprom_val &= 0xFF;
+       switch (eeprom_val) {
+       case 1: rf_name = "Intersil";
+               break;
+       case 2: rf_name = "RFMD";
+               break;
+       case 3: priv->rf = &sa2400_rf_ops;
+               break;
+       case 4: priv->rf = &max2820_rf_ops;
+               break;
+       case 5: priv->rf = &grf5101_rf_ops;
+               break;
+       case 9: priv->rf = rtl8180_detect_rf(dev);
+               break;
+       case 10:
+               rf_name = "RTL8255";
+               break;
+       default:
+               printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
+                      pci_name(pdev), eeprom_val);
+               goto err_iounmap;
+       }
+
+       if (!priv->rf) {
+               printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
+                      pci_name(pdev), rf_name);
+               goto err_iounmap;
+       }
+
+       eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
+       priv->csthreshold = eeprom_val >> 8;
+       if (!priv->r8185) {
+               __le32 anaparam;
+               eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
+               priv->anaparam = le32_to_cpu(anaparam);
+               eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
+       }
+
+       eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3);
+       if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
+               printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
+                      " randomly generated MAC addr\n", pci_name(pdev));
+               random_ether_addr(dev->wiphy->perm_addr);
+       }
+
+       /* CCK TX power */
+       for (i = 0; i < 14; i += 2) {
+               u16 txpwr;
+               eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr);
+               priv->channels[i].val = txpwr & 0xFF;
+               priv->channels[i + 1].val = txpwr >> 8;
+       }
+
+       /* OFDM TX power */
+       if (priv->r8185) {
+               for (i = 0; i < 14; i += 2) {
+                       u16 txpwr;
+                       eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
+                       priv->channels[i].val |= (txpwr & 0xFF) << 8;
+                       priv->channels[i + 1].val |= txpwr & 0xFF00;
+               }
+       }
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       spin_lock_init(&priv->lock);
+
+       err = ieee80211_register_hw(dev);
+       if (err) {
+               printk(KERN_ERR "%s (rtl8180): Cannot register device\n",
+                      pci_name(pdev));
+               goto err_iounmap;
+       }
+
+       printk(KERN_INFO "%s: hwaddr %s, %s + %s\n",
+              wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
+              chip_name, priv->rf->name);
+
+       return 0;
+
+ err_iounmap:
+       iounmap(priv->map);
+
+ err_free_dev:
+       pci_set_drvdata(pdev, NULL);
+       ieee80211_free_hw(dev);
+
+ err_free_reg:
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       return err;
+}
+
+static void __devexit rtl8180_remove(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *dev = pci_get_drvdata(pdev);
+       struct rtl8180_priv *priv;
+
+       if (!dev)
+               return;
+
+       ieee80211_unregister_hw(dev);
+
+       priv = dev->priv;
+
+       pci_iounmap(pdev, priv->map);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       ieee80211_free_hw(dev);
+}
+
+#ifdef CONFIG_PM
+static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       pci_save_state(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       return 0;
+}
+
+static int rtl8180_resume(struct pci_dev *pdev)
+{
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
+static struct pci_driver rtl8180_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = rtl8180_table,
+       .probe          = rtl8180_probe,
+       .remove         = __devexit_p(rtl8180_remove),
+#ifdef CONFIG_PM
+       .suspend        = rtl8180_suspend,
+       .resume         = rtl8180_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init rtl8180_init(void)
+{
+       return pci_register_driver(&rtl8180_driver);
+}
+
+static void __exit rtl8180_exit(void)
+{
+       pci_unregister_driver(&rtl8180_driver);
+}
+
+module_init(rtl8180_init);
+module_exit(rtl8180_exit);
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c
new file mode 100644 (file)
index 0000000..8293e19
--- /dev/null
@@ -0,0 +1,179 @@
+
+/*
+ * Radio tuning for GCT GRF5101 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_grf5101.h"
+
+static const int grf5101_encode[] = {
+       0x0, 0x8, 0x4, 0xC,
+       0x2, 0xA, 0x6, 0xE,
+       0x1, 0x9, 0x5, 0xD,
+       0x3, 0xB, 0x7, 0xF
+};
+
+static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 phy_config;
+
+       phy_config =  grf5101_encode[(data >> 8) & 0xF];
+       phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4;
+       phy_config |= grf5101_encode[data & 0xF] << 8;
+       phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12;
+       phy_config |= (addr & 1) << 16;
+       phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24;
+
+       /* MAC will bang bits to the chip */
+       phy_config |= 0x90000000;
+
+       rtl818x_iowrite32(priv,
+               (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
+
+       msleep(3);
+}
+
+static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 ant = GRF5101_ANTENNA;
+
+       if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
+               ant |= BB_ANTENNA_B;
+
+       if (chan == 14)
+               ant |= BB_ANTATTEN_CHAN14;
+
+       rtl8180_write_phy(dev, 0x10, ant);
+}
+
+static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
+                                  struct ieee80211_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
+       u32 chan = conf->channel - 1;
+
+       /* set TX power */
+       write_grf5101(dev, 0x15, 0x0);
+       write_grf5101(dev, 0x06, txpw);
+       write_grf5101(dev, 0x15, 0x10);
+       write_grf5101(dev, 0x15, 0x0);
+
+       /* set frequency */
+       write_grf5101(dev, 0x07, 0x0);
+       write_grf5101(dev, 0x0B, chan);
+       write_grf5101(dev, 0x07, 0x1000);
+
+       grf5101_write_phy_antenna(dev, chan);
+}
+
+static void grf5101_rf_stop(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 anaparam;
+
+       anaparam = priv->anaparam;
+       anaparam &= 0x000fffff;
+       anaparam |= 0x3f900000;
+       rtl8180_set_anaparam(priv, anaparam);
+
+       write_grf5101(dev, 0x07, 0x0);
+       write_grf5101(dev, 0x1f, 0x45);
+       write_grf5101(dev, 0x1f, 0x5);
+       write_grf5101(dev, 0x00, 0x8e4);
+}
+
+static void grf5101_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       rtl8180_set_anaparam(priv, priv->anaparam);
+
+       write_grf5101(dev, 0x1f, 0x0);
+       write_grf5101(dev, 0x1f, 0x0);
+       write_grf5101(dev, 0x1f, 0x40);
+       write_grf5101(dev, 0x1f, 0x60);
+       write_grf5101(dev, 0x1f, 0x61);
+       write_grf5101(dev, 0x1f, 0x61);
+       write_grf5101(dev, 0x00, 0xae4);
+       write_grf5101(dev, 0x1f, 0x1);
+       write_grf5101(dev, 0x1f, 0x41);
+       write_grf5101(dev, 0x1f, 0x61);
+
+       write_grf5101(dev, 0x01, 0x1a23);
+       write_grf5101(dev, 0x02, 0x4971);
+       write_grf5101(dev, 0x03, 0x41de);
+       write_grf5101(dev, 0x04, 0x2d80);
+       write_grf5101(dev, 0x05, 0x68ff);       /* 0x61ff original value */
+       write_grf5101(dev, 0x06, 0x0);
+       write_grf5101(dev, 0x07, 0x0);
+       write_grf5101(dev, 0x08, 0x7533);
+       write_grf5101(dev, 0x09, 0xc401);
+       write_grf5101(dev, 0x0a, 0x0);
+       write_grf5101(dev, 0x0c, 0x1c7);
+       write_grf5101(dev, 0x0d, 0x29d3);
+       write_grf5101(dev, 0x0e, 0x2e8);
+       write_grf5101(dev, 0x10, 0x192);
+       write_grf5101(dev, 0x11, 0x248);
+       write_grf5101(dev, 0x12, 0x0);
+       write_grf5101(dev, 0x13, 0x20c4);
+       write_grf5101(dev, 0x14, 0xf4fc);
+       write_grf5101(dev, 0x15, 0x0);
+       write_grf5101(dev, 0x16, 0x1500);
+
+       write_grf5101(dev, 0x07, 0x1000);
+
+       /* baseband configuration */
+       rtl8180_write_phy(dev, 0, 0xa8);
+       rtl8180_write_phy(dev, 3, 0x0);
+       rtl8180_write_phy(dev, 4, 0xc0);
+       rtl8180_write_phy(dev, 5, 0x90);
+       rtl8180_write_phy(dev, 6, 0x1e);
+       rtl8180_write_phy(dev, 7, 0x64);
+
+       grf5101_write_phy_antenna(dev, 1);
+
+       rtl8180_write_phy(dev, 0x11, 0x88);
+
+       if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
+           RTL818X_CONFIG2_ANTENNA_DIV)
+               rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */
+       else
+               rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */
+
+       rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
+
+       rtl8180_write_phy(dev, 0x19, 0x0);
+       rtl8180_write_phy(dev, 0x1a, 0xa0);
+       rtl8180_write_phy(dev, 0x1b, 0x44);
+}
+
+const struct rtl818x_rf_ops grf5101_rf_ops = {
+       .name           = "GCT",
+       .init           = grf5101_rf_init,
+       .stop           = grf5101_rf_stop,
+       .set_chan       = grf5101_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_grf5101.h b/drivers/net/wireless/rtl8180_grf5101.h
new file mode 100644 (file)
index 0000000..7664711
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef RTL8180_GRF5101_H
+#define RTL8180_GRF5101_H
+
+/*
+ * Radio tuning for GCT GRF5101 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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.
+ */
+
+#define GRF5101_ANTENNA 0xA3
+
+extern const struct rtl818x_rf_ops grf5101_rf_ops;
+
+#endif /* RTL8180_GRF5101_H */
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c
new file mode 100644 (file)
index 0000000..98fe9fd
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Radio tuning for Maxim max2820 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_max2820.h"
+
+static const u32 max2820_chan[] = {
+       12, /* CH 1 */
+       17,
+       22,
+       27,
+       32,
+       37,
+       42,
+       47,
+       52,
+       57,
+       62,
+       67,
+       72,
+       84, /* CH 14 */
+};
+
+static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 phy_config;
+
+       phy_config = 0x90 + (data & 0xf);
+       phy_config <<= 16;
+       phy_config += addr;
+       phy_config <<= 8;
+       phy_config += (data >> 4) & 0xff;
+
+       rtl818x_iowrite32(priv,
+               (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
+
+       msleep(1);
+}
+
+static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 ant;
+
+       ant = MAXIM_ANTENNA;
+       if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
+               ant |= BB_ANTENNA_B;
+       if (chan == 14)
+               ant |= BB_ANTATTEN_CHAN14;
+
+       rtl8180_write_phy(dev, 0x10, ant);
+}
+
+static void max2820_rf_set_channel(struct ieee80211_hw *dev,
+                                  struct ieee80211_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       unsigned int chan_idx = conf ? conf->channel - 1 : 0;
+       u32 txpw = priv->channels[chan_idx].val & 0xFF;
+       u32 chan = max2820_chan[chan_idx];
+
+       /* While philips SA2400 drive the PA bias from
+        * sa2400, for MAXIM we do this directly from BB */
+       rtl8180_write_phy(dev, 3, txpw);
+
+       max2820_write_phy_antenna(dev, chan);
+       write_max2820(dev, 3, chan);
+}
+
+static void max2820_rf_stop(struct ieee80211_hw *dev)
+{
+       rtl8180_write_phy(dev, 3, 0x8);
+       write_max2820(dev, 1, 0);
+}
+
+
+static void max2820_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       /* MAXIM from netbsd driver */
+       write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
+       write_max2820(dev, 1, 0x01e); /* enable register */
+       write_max2820(dev, 2, 0x001); /* synt register */
+
+       max2820_rf_set_channel(dev, NULL);
+
+       write_max2820(dev, 4, 0x313); /* rx register */
+
+       /* PA is driven directly by the BB, we keep the MAXIM bias
+        * at the highest value in case that setting it to lower
+        * values may introduce some further attenuation somewhere..
+        */
+       write_max2820(dev, 5, 0x00f);
+
+       /* baseband configuration */
+       rtl8180_write_phy(dev, 0, 0x88); /* sys1       */
+       rtl8180_write_phy(dev, 3, 0x08); /* txagc      */
+       rtl8180_write_phy(dev, 4, 0xf8); /* lnadet     */
+       rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit  */
+       rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
+       rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet   */
+
+       max2820_write_phy_antenna(dev, 1);
+
+       rtl8180_write_phy(dev, 0x11, 0x88); /* trl */
+
+       if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
+           RTL818X_CONFIG2_ANTENNA_DIV)
+               rtl8180_write_phy(dev, 0x12, 0xc7);
+       else
+               rtl8180_write_phy(dev, 0x12, 0x47);
+
+       rtl8180_write_phy(dev, 0x13, 0x9b);
+
+       rtl8180_write_phy(dev, 0x19, 0x0);  /* CHESTLIM */
+       rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM  */
+
+       max2820_rf_set_channel(dev, NULL);
+}
+
+const struct rtl818x_rf_ops max2820_rf_ops = {
+       .name           = "Maxim",
+       .init           = max2820_rf_init,
+       .stop           = max2820_rf_stop,
+       .set_chan       = max2820_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_max2820.h b/drivers/net/wireless/rtl8180_max2820.h
new file mode 100644 (file)
index 0000000..61cf6d1
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef RTL8180_MAX2820_H
+#define RTL8180_MAX2820_H
+
+/*
+ * Radio tuning for Maxim max2820 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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.
+ */
+
+#define MAXIM_ANTENNA 0xb3
+
+extern const struct rtl818x_rf_ops max2820_rf_ops;
+
+#endif /* RTL8180_MAX2820_H */
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c
new file mode 100644 (file)
index 0000000..ef3832b
--- /dev/null
@@ -0,0 +1,779 @@
+
+/*
+ * Radio tuning for RTL8225 on RTL8180
+ *
+ * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Based on the r8180 driver, which is:
+ * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_rtl8225.h"
+
+static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u16 reg80, reg84, reg82;
+       u32 bangdata;
+       int i;
+
+       bangdata = (data << 4) | (addr & 0xf);
+
+       reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
+       reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
+
+       reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(10);
+
+       for (i = 15; i >= 0; i--) {
+               u16 reg = reg80 | !!(bangdata & (1 << i));
+
+               if (i & 1)
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
+
+               if (!(i & 1))
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(10);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+}
+
+static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u16 reg80, reg82, reg84, out;
+       int i;
+
+       reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
+       reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
+       reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
+
+       reg80 &= ~0xF;
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(4);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(5);
+
+       for (i = 4; i >= 0; i--) {
+               u16 reg = reg80 | ((addr >> i) & 1);
+
+               if (!(i & 1)) {
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+                       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+                       udelay(1);
+               }
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg | (1 << 1));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg | (1 << 1));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+
+               if (i & 1) {
+                       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
+                       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+                       udelay(1);
+               }
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3) | (1 << 1));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(2);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(2);
+
+       out = 0;
+       for (i = 11; i >= 0; i--) {
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(1);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3) | (1 << 1));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+
+               if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
+                       out |= 1 << i;
+
+               rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                                 reg80 | (1 << 3));
+               rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+               udelay(2);
+       }
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
+                         reg80 | (1 << 3) | (1 << 2));
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       udelay(2);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
+
+       return out;
+}
+
+static const u16 rtl8225bcd_rxgain[] = {
+       0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
+       0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
+       0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
+       0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
+       0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
+       0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
+       0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
+       0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
+       0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
+       0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
+       0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
+       0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
+};
+
+static const u8 rtl8225_agc[] = {
+       0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
+       0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
+       0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
+       0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
+       0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
+       0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
+       0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
+       0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
+       0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
+       0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
+       0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
+       0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
+       0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+static const u8 rtl8225_gain[] = {
+       0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
+       0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
+       0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
+       0x33, 0x80, 0x79, 0xc5, /* -78dbm */
+       0x43, 0x78, 0x76, 0xc5, /* -74dbm */
+       0x53, 0x60, 0x73, 0xc5, /* -70dbm */
+       0x63, 0x58, 0x70, 0xc5, /* -66dbm */
+};
+
+static const u8 rtl8225_threshold[] = {
+       0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
+};
+
+static const u8 rtl8225_tx_gain_cck_ofdm[] = {
+       0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
+};
+
+static const u8 rtl8225_tx_power_cck[] = {
+       0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
+       0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
+       0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
+       0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
+       0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
+       0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
+};
+
+static const u8 rtl8225_tx_power_cck_ch14[] = {
+       0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
+       0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
+       0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
+       0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
+       0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
+       0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 rtl8225_tx_power_ofdm[] = {
+       0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
+};
+
+static const u32 rtl8225_chan[] = {
+       0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
+       0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
+};
+
+static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 cck_power, ofdm_power;
+       const u8 *tmp;
+       u32 reg;
+       int i;
+
+       cck_power = priv->channels[channel - 1].val & 0xFF;
+       ofdm_power = priv->channels[channel - 1].val >> 8;
+
+       cck_power = min(cck_power, (u8)35);
+       ofdm_power = min(ofdm_power, (u8)35);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
+                        rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
+
+       if (channel == 14)
+               tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
+       else
+               tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
+
+       for (i = 0; i < 8; i++)
+               rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+       msleep(1); /* FIXME: optional? */
+
+       /* anaparam2 on */
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
+                        rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
+
+       tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
+
+       rtl8225_write_phy_ofdm(dev, 5, *tmp);
+       rtl8225_write_phy_ofdm(dev, 7, *tmp);
+
+       msleep(1);
+}
+
+static void rtl8225_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       int i;
+
+       rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
+
+       /* host_pci_init */
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       msleep(200);    /* FIXME: ehh?? */
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
+
+       rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
+
+       /* TODO: check if we need really to change BRSR to do RF config */
+       rtl818x_ioread16(priv, &priv->map->BRSR);
+       rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
+       rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl8225_write(dev, 0x0, 0x067);
+       rtl8225_write(dev, 0x1, 0xFE0);
+       rtl8225_write(dev, 0x2, 0x44D);
+       rtl8225_write(dev, 0x3, 0x441);
+       rtl8225_write(dev, 0x4, 0x8BE);
+       rtl8225_write(dev, 0x5, 0xBF0);         /* TODO: minipci */
+       rtl8225_write(dev, 0x6, 0xAE6);
+       rtl8225_write(dev, 0x7, rtl8225_chan[0]);
+       rtl8225_write(dev, 0x8, 0x01F);
+       rtl8225_write(dev, 0x9, 0x334);
+       rtl8225_write(dev, 0xA, 0xFD4);
+       rtl8225_write(dev, 0xB, 0x391);
+       rtl8225_write(dev, 0xC, 0x050);
+       rtl8225_write(dev, 0xD, 0x6DB);
+       rtl8225_write(dev, 0xE, 0x029);
+       rtl8225_write(dev, 0xF, 0x914); msleep(1);
+
+       rtl8225_write(dev, 0x2, 0xC4D); msleep(100);
+
+       rtl8225_write(dev, 0x0, 0x127);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
+               rtl8225_write(dev, 0x1, i + 1);
+               rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
+       }
+
+       rtl8225_write(dev, 0x0, 0x027);
+       rtl8225_write(dev, 0x0, 0x22F);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
+               rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
+               msleep(1);
+               rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
+               msleep(1);
+       }
+
+       msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+
+       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x13, 0xd0);
+       rtl8225_write_phy_cck(dev, 0x19, 0x00);
+       rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
+       rtl8225_write_phy_cck(dev, 0x1b, 0x08);
+       rtl8225_write_phy_cck(dev, 0x40, 0x86);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+
+       rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1);
+
+       rtl8225_rf_set_tx_power(dev, 1);
+
+       /* RX antenna default to A */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+
+       rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
+       msleep(1);
+       rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+
+       rtl8225_write(dev, 0x0c, 0x50);
+       /* set OFDM initial gain */
+       rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
+       rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
+       rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
+       rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
+       /* set CCK threshold */
+       rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
+}
+
+static const u8 rtl8225z2_tx_power_cck_ch14[] = {
+       0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
+};
+
+static const u8 rtl8225z2_tx_power_cck_B[] = {
+       0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
+};
+
+static const u8 rtl8225z2_tx_power_cck_A[] = {
+       0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
+};
+
+static const u8 rtl8225z2_tx_power_cck[] = {
+       0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
+};
+
+static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 cck_power, ofdm_power;
+       const u8 *tmp;
+       int i;
+
+       cck_power = priv->channels[channel - 1].val & 0xFF;
+       ofdm_power = priv->channels[channel - 1].val >> 8;
+
+       if (channel == 14)
+               tmp = rtl8225z2_tx_power_cck_ch14;
+       else if (cck_power == 12)
+               tmp = rtl8225z2_tx_power_cck_B;
+       else if (cck_power == 13)
+               tmp = rtl8225z2_tx_power_cck_A;
+       else
+               tmp = rtl8225z2_tx_power_cck;
+
+       for (i = 0; i < 8; i++)
+               rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
+
+       cck_power = min(cck_power, (u8)35);
+       if (cck_power == 13 || cck_power == 14)
+               cck_power = 12;
+       if (cck_power >= 15)
+               cck_power -= 2;
+
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
+       rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
+       msleep(1);
+
+       ofdm_power = min(ofdm_power, (u8)35);
+       rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
+
+       rtl8225_write_phy_ofdm(dev, 2, 0x62);
+       rtl8225_write_phy_ofdm(dev, 5, 0x00);
+       rtl8225_write_phy_ofdm(dev, 6, 0x40);
+       rtl8225_write_phy_ofdm(dev, 7, 0x00);
+       rtl8225_write_phy_ofdm(dev, 8, 0x40);
+
+       msleep(1);
+}
+
+static const u16 rtl8225z2_rxgain[] = {
+       0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
+       0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
+       0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
+       0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
+       0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
+       0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
+       0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
+       0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
+       0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
+       0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
+       0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
+       0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
+};
+
+static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       int i;
+
+       rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON);
+
+       /* host_pci_init */
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       msleep(200);    /* FIXME: ehh?? */
+       rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
+
+       rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
+
+       /* TODO: check if we need really to change BRSR to do RF config */
+       rtl818x_ioread16(priv, &priv->map->BRSR);
+       rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
+       rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+
+       rtl8225_write(dev, 0x0, 0x0B7); msleep(1);
+       rtl8225_write(dev, 0x1, 0xEE0); msleep(1);
+       rtl8225_write(dev, 0x2, 0x44D); msleep(1);
+       rtl8225_write(dev, 0x3, 0x441); msleep(1);
+       rtl8225_write(dev, 0x4, 0x8C3); msleep(1);
+       rtl8225_write(dev, 0x5, 0xC72); msleep(1);
+       rtl8225_write(dev, 0x6, 0x0E6); msleep(1);
+       rtl8225_write(dev, 0x7, 0x82A); msleep(1);
+       rtl8225_write(dev, 0x8, 0x03F); msleep(1);
+       rtl8225_write(dev, 0x9, 0x335); msleep(1);
+       rtl8225_write(dev, 0xa, 0x9D4); msleep(1);
+       rtl8225_write(dev, 0xb, 0x7BB); msleep(1);
+       rtl8225_write(dev, 0xc, 0x850); msleep(1);
+       rtl8225_write(dev, 0xd, 0xCDF); msleep(1);
+       rtl8225_write(dev, 0xe, 0x02B); msleep(1);
+       rtl8225_write(dev, 0xf, 0x114); msleep(100);
+
+       if (!(rtl8225_read(dev, 6) & (1 << 7))) {
+               rtl8225_write(dev, 0x02, 0x0C4D);
+               msleep(200);
+               rtl8225_write(dev, 0x02, 0x044D);
+               msleep(100);
+               /* TODO: readd calibration failure message when the calibration
+                  check works */
+       }
+
+       rtl8225_write(dev, 0x0, 0x1B7);
+       rtl8225_write(dev, 0x3, 0x002);
+       rtl8225_write(dev, 0x5, 0x004);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
+               rtl8225_write(dev, 0x1, i + 1);
+               rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
+       }
+
+       rtl8225_write(dev, 0x0, 0x0B7); msleep(100);
+       rtl8225_write(dev, 0x2, 0xC4D);
+
+       msleep(200);
+       rtl8225_write(dev, 0x2, 0x44D);
+       msleep(100);
+
+       rtl8225_write(dev, 0x00, 0x2BF);
+       rtl8225_write(dev, 0xFF, 0xFFFF);
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+
+       for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
+               rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
+               msleep(1);
+               rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
+               msleep(1);
+       }
+
+       msleep(1);
+
+       rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
+       rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */
+       rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);
+       rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1);
+
+       rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x13, 0xd0);
+       rtl8225_write_phy_cck(dev, 0x19, 0x00);
+       rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
+       rtl8225_write_phy_cck(dev, 0x1b, 0x08);
+       rtl8225_write_phy_cck(dev, 0x40, 0x86);
+       rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1);
+       rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1);
+
+       rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1);
+
+       rtl8225z2_rf_set_tx_power(dev, 1);
+
+       /* RX antenna default to A */
+       rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1);      /* B: 0xDB */
+       rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1);     /* B: 0x10 */
+
+       rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
+       msleep(1);
+       rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+}
+
+static void rtl8225_rf_stop(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 reg;
+
+       rtl8225_write(dev, 0x4, 0x1f); msleep(1);
+
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
+       reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
+       rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
+       rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
+       rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
+}
+
+static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
+                                  struct ieee80211_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+
+       if (priv->rf->init == rtl8225_rf_init)
+               rtl8225_rf_set_tx_power(dev, conf->channel);
+       else
+               rtl8225z2_rf_set_tx_power(dev, conf->channel);
+
+       rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]);
+       msleep(10);
+
+       if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
+               rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
+               rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
+               rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
+               rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
+               rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
+       } else {
+               rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
+               rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
+               rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
+               rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
+               rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
+       }
+}
+
+static const struct rtl818x_rf_ops rtl8225_ops = {
+       .name           = "rtl8225",
+       .init           = rtl8225_rf_init,
+       .stop           = rtl8225_rf_stop,
+       .set_chan       = rtl8225_rf_set_channel
+};
+
+static const struct rtl818x_rf_ops rtl8225z2_ops = {
+       .name           = "rtl8225z2",
+       .init           = rtl8225z2_rf_init,
+       .stop           = rtl8225_rf_stop,
+       .set_chan       = rtl8225_rf_set_channel
+};
+
+const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u16 reg8, reg9;
+
+       rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
+       rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
+       rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
+       msleep(100);
+
+       rtl8225_write(dev, 0, 0x1B7);
+
+       reg8 = rtl8225_read(dev, 8);
+       reg9 = rtl8225_read(dev, 9);
+
+       rtl8225_write(dev, 0, 0x0B7);
+
+       if (reg8 != 0x588 || reg9 != 0x700)
+               return &rtl8225_ops;
+
+       return &rtl8225z2_ops;
+}
diff --git a/drivers/net/wireless/rtl8180_rtl8225.h b/drivers/net/wireless/rtl8180_rtl8225.h
new file mode 100644 (file)
index 0000000..310013a
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef RTL8180_RTL8225_H
+#define RTL8180_RTL8225_H
+
+#define RTL8225_ANAPARAM_ON    0xa0000b59
+#define RTL8225_ANAPARAM2_ON   0x860dec11
+#define RTL8225_ANAPARAM_OFF   0xa00beb59
+#define RTL8225_ANAPARAM2_OFF  0x840dec11
+
+const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *);
+
+static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
+                                         u8 addr, u8 data)
+{
+       rtl8180_write_phy(dev, addr, data);
+}
+
+static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev,
+                                        u8 addr, u8 data)
+{
+       rtl8180_write_phy(dev, addr, data | 0x10000);
+}
+
+#endif /* RTL8180_RTL8225_H */
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c
new file mode 100644 (file)
index 0000000..e08ace7
--- /dev/null
@@ -0,0 +1,201 @@
+
+/*
+ * Radio tuning for Philips SA2400 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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/init.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <net/mac80211.h>
+
+#include "rtl8180.h"
+#include "rtl8180_sa2400.h"
+
+static const u32 sa2400_chan[] = {
+       0x00096c, /* ch1 */
+       0x080970,
+       0x100974,
+       0x180978,
+       0x000980,
+       0x080984,
+       0x100988,
+       0x18098c,
+       0x000994,
+       0x080998,
+       0x10099c,
+       0x1809a0,
+       0x0009a8,
+       0x0009b4, /* ch 14 */
+};
+
+static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 phy_config;
+
+       /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */
+       phy_config = 0xb0000000;
+
+       phy_config |= ((u32)(addr & 0xf)) << 24;
+       phy_config |= data & 0xffffff;
+
+       rtl818x_iowrite32(priv,
+               (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);
+
+       msleep(3);
+}
+
+static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u8 ant = SA2400_ANTENNA;
+
+       if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
+               ant |= BB_ANTENNA_B;
+
+       if (chan == 14)
+               ant |= BB_ANTATTEN_CHAN14;
+
+       rtl8180_write_phy(dev, 0x10, ant);
+
+}
+
+static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
+                                 struct ieee80211_conf *conf)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 txpw = priv->channels[conf->channel - 1].val & 0xFF;
+       u32 chan = sa2400_chan[conf->channel - 1];
+
+       write_sa2400(dev, 7, txpw);
+
+       sa2400_write_phy_antenna(dev, chan);
+
+       write_sa2400(dev, 0, chan);
+       write_sa2400(dev, 1, 0xbb50);
+       write_sa2400(dev, 2, 0x80);
+       write_sa2400(dev, 3, 0);
+}
+
+static void sa2400_rf_stop(struct ieee80211_hw *dev)
+{
+       write_sa2400(dev, 4, 0);
+}
+
+static void sa2400_rf_init(struct ieee80211_hw *dev)
+{
+       struct rtl8180_priv *priv = dev->priv;
+       u32 anaparam, txconf;
+       u8 firdac;
+       int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY;
+
+       anaparam = priv->anaparam;
+       anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT);
+       anaparam &= ~ANAPARAM_PWR1_MASK;
+       anaparam &= ~ANAPARAM_PWR0_MASK;
+
+       if (analogphy) {
+               anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT;
+               firdac = 0;
+       } else {
+               anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT);
+               anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT);
+               firdac = 1 << SA2400_REG4_FIRDAC_SHIFT;
+       }
+
+       rtl8180_set_anaparam(priv, anaparam);
+
+       write_sa2400(dev, 0, sa2400_chan[0]);
+       write_sa2400(dev, 1, 0xbb50);
+       write_sa2400(dev, 2, 0x80);
+       write_sa2400(dev, 3, 0);
+       write_sa2400(dev, 4, 0x19340 | firdac);
+       write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15);
+       write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */
+
+       if (!analogphy)
+               write_sa2400(dev, 4, 0x1938c); /*???*/
+
+       write_sa2400(dev, 4, 0x19340 | firdac);
+
+       write_sa2400(dev, 0, sa2400_chan[0]);
+       write_sa2400(dev, 1, 0xbb50);
+       write_sa2400(dev, 2, 0x80);
+       write_sa2400(dev, 3, 0);
+       write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */
+
+       /* new from rtl8180 embedded driver (rtl8181 project) */
+       write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */
+       write_sa2400(dev, 8, 0); /* VCO */
+
+       if (analogphy) {
+               rtl8180_set_anaparam(priv, anaparam |
+                                    (1 << ANAPARAM_TXDACOFF_SHIFT));
+
+               txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+               rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+                       txconf | RTL818X_TX_CONF_LOOPBACK_CONT);
+
+               write_sa2400(dev, 4, 0x19341); /* calibrates DC */
+
+               /* a 5us sleep is required here,
+                * we rely on the 3ms delay introduced in write_sa2400 */
+               write_sa2400(dev, 4, 0x19345);
+
+               /* a 20us sleep is required here,
+                * we rely on the 3ms delay introduced in write_sa2400 */
+
+               rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf);
+
+               rtl8180_set_anaparam(priv, anaparam);
+       }
+       /* end new code */
+
+       write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */
+
+       /* baseband configuration */
+       rtl8180_write_phy(dev, 0, 0x98);
+       rtl8180_write_phy(dev, 3, 0x38);
+       rtl8180_write_phy(dev, 4, 0xe0);
+       rtl8180_write_phy(dev, 5, 0x90);
+       rtl8180_write_phy(dev, 6, 0x1a);
+       rtl8180_write_phy(dev, 7, 0x64);
+
+       sa2400_write_phy_antenna(dev, 1);
+
+       rtl8180_write_phy(dev, 0x11, 0x80);
+
+       if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
+           RTL818X_CONFIG2_ANTENNA_DIV)
+               rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */
+       else
+               rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */
+
+       rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold);
+
+       rtl8180_write_phy(dev, 0x19, 0x0);
+       rtl8180_write_phy(dev, 0x1a, 0xa0);
+}
+
+const struct rtl818x_rf_ops sa2400_rf_ops = {
+       .name           = "Philips",
+       .init           = sa2400_rf_init,
+       .stop           = sa2400_rf_stop,
+       .set_chan       = sa2400_rf_set_channel
+};
diff --git a/drivers/net/wireless/rtl8180_sa2400.h b/drivers/net/wireless/rtl8180_sa2400.h
new file mode 100644 (file)
index 0000000..a4aaa0d
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef RTL8180_SA2400_H
+#define RTL8180_SA2400_H
+
+/*
+ * Radio tuning for Philips SA2400 on RTL8180
+ *
+ * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
+ *
+ * Code from the BSD driver and the rtl8181 project have been
+ * very useful to understand certain things
+ *
+ * I want to thanks the Authors of such projects and the Ndiswrapper
+ * project Authors.
+ *
+ * A special Big Thanks also is for all people who donated me cards,
+ * making possible the creation of the original rtl8180 driver
+ * from which this code is derived!
+ *
+ * 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.
+ */
+
+#define SA2400_ANTENNA 0x91
+#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
+#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
+#define SA2400_ANAPARAM_PWR0_ON 0x3
+
+/* RX sensitivity in dbm */
+#define SA2400_MAX_SENS 85
+
+#define SA2400_REG4_FIRDAC_SHIFT 7
+
+extern const struct rtl818x_rf_ops sa2400_rf_ops;
+
+#endif /* RTL8180_SA2400_H */
index 6ad322ef0da13a974a8cb6c7793239213fb9123b..8680a0b6433cd46fccd1c1a703e152de68fd5861 100644 (file)
@@ -64,9 +64,9 @@ struct rtl8187_tx_hdr {
 struct rtl8187_priv {
        /* common between rtl818x drivers */
        struct rtl818x_csr *map;
-       void (*rf_init)(struct ieee80211_hw *);
+       const struct rtl818x_rf_ops *rf;
+       struct ieee80211_vif *vif;
        int mode;
-       int if_id;
 
        /* rtl8187 specific */
        struct ieee80211_channel channels[14];
index bd1ab3b3afc0d6fe505ee94bd216a31ea073f225..0d71716d750df858345bd81718369700e0322357 100644 (file)
@@ -150,7 +150,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
                flags |= RTL8187_TX_FLAG_MORE_FRAG;
        if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
                flags |= RTL8187_TX_FLAG_RTS;
-               rts_dur = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
+               rts_dur = ieee80211_rts_duration(dev, priv->vif,
+                                                skb->len, control);
        }
        if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
                flags |= RTL8187_TX_FLAG_CTS;
@@ -227,6 +228,7 @@ static void rtl8187_rx_cb(struct urb *urb)
        rx_status.channel = dev->conf.channel;
        rx_status.phymode = dev->conf.phymode;
        rx_status.mactime = le64_to_cpu(hdr->mac_time);
+       rx_status.flag |= RX_FLAG_TSFT;
        if (flags & (1 << 13))
                rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
        ieee80211_rx_irqsafe(dev, skb, &rx_status);
@@ -392,37 +394,19 @@ static int rtl8187_init_hw(struct ieee80211_hw *dev)
        rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7);
        msleep(100);
 
-       priv->rf_init(dev);
+       priv->rf->init(dev);
 
        rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
-       reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe;
-       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1);
+       reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
+       rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
        rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10);
        rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80);
        rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60);
-       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+       rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
 
        return 0;
 }
 
-static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel)
-{
-       u32 reg;
-       struct rtl8187_priv *priv = dev->priv;
-
-       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
-       /* Enable TX loopback on MAC level to avoid TX during channel
-        * changes, as this has be seen to causes problems and the
-        * card will stop work until next reset
-        */
-       rtl818x_iowrite32(priv, &priv->map->TX_CONF,
-                         reg | RTL818X_TX_CONF_LOOPBACK_MAC);
-       msleep(10);
-       rtl8225_rf_set_channel(dev, channel);
-       msleep(10);
-       rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
-}
-
 static int rtl8187_start(struct ieee80211_hw *dev)
 {
        struct rtl8187_priv *priv = dev->priv;
@@ -491,7 +475,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
        reg &= ~RTL818X_CMD_RX_ENABLE;
        rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 
-       rtl8225_rf_stop(dev);
+       priv->rf->stop(dev);
 
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
        reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
@@ -542,7 +526,19 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
 static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 {
        struct rtl8187_priv *priv = dev->priv;
-       rtl8187_set_channel(dev, conf->channel);
+       u32 reg;
+
+       reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
+       /* Enable TX loopback on MAC level to avoid TX during channel
+        * changes, as this has be seen to causes problems and the
+        * card will stop work until next reset
+        */
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF,
+                         reg | RTL818X_TX_CONF_LOOPBACK_MAC);
+       msleep(10);
+       priv->rf->set_chan(dev, conf);
+       msleep(10);
+       rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
 
        rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
 
@@ -565,14 +561,13 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        return 0;
 }
 
-static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
+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;
 
-       priv->if_id = if_id;
-
        for (i = 0; i < ETH_ALEN; i++)
                rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
 
@@ -752,23 +747,16 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
        eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
                          &priv->txpwr_base);
 
-       reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1;
-       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1);
+       reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1;
+       rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
        /* 0 means asic B-cut, we should use SW 3 wire
         * bit-by-bit banging for radio. 1 means we can use
         * USB specific request to write radio registers */
        priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3;
-       rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg);
+       rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 
-       rtl8225_write(dev, 0, 0x1B7);
-
-       if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700)
-               priv->rf_init = rtl8225_rf_init;
-       else
-               priv->rf_init = rtl8225z2_rf_init;
-
-       rtl8225_write(dev, 0, 0x0B7);
+       priv->rf = rtl8187_detect_rf(dev);
 
        err = ieee80211_register_hw(dev);
        if (err) {
@@ -778,8 +766,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
 
        printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
               wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
-              priv->asic_rev, priv->rf_init == rtl8225_rf_init ?
-              "rtl8225" : "rtl8225z2");
+              priv->asic_rev, priv->rf->name);
 
        return 0;
 
index efc41207780eea5a7410caf72aab5410fa6decca..b713de17ba0a0d77ebeb0b728c19265643b3d165 100644 (file)
@@ -101,7 +101,7 @@ static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
        msleep(2);
 }
 
-void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
+static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
 {
        struct rtl8187_priv *priv = dev->priv;
 
@@ -111,7 +111,7 @@ void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
                rtl8225_write_bitbang(dev, addr, data);
 }
 
-u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
+static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr)
 {
        struct rtl8187_priv *priv = dev->priv;
        u16 reg80, reg82, reg84, out;
@@ -325,7 +325,7 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
        msleep(1);
 }
 
-void rtl8225_rf_init(struct ieee80211_hw *dev)
+static void rtl8225_rf_init(struct ieee80211_hw *dev)
 {
        struct rtl8187_priv *priv = dev->priv;
        int i;
@@ -567,7 +567,7 @@ static const u8 rtl8225z2_gain_bg[] = {
        0x63, 0x15, 0xc5  /* -66dBm */
 };
 
-void rtl8225z2_rf_init(struct ieee80211_hw *dev)
+static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
 {
        struct rtl8187_priv *priv = dev->priv;
        int i;
@@ -715,7 +715,7 @@ void rtl8225z2_rf_init(struct ieee80211_hw *dev)
        rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002);
 }
 
-void rtl8225_rf_stop(struct ieee80211_hw *dev)
+static void rtl8225_rf_stop(struct ieee80211_hw *dev)
 {
        u8 reg;
        struct rtl8187_priv *priv = dev->priv;
@@ -731,15 +731,47 @@ void rtl8225_rf_stop(struct ieee80211_hw *dev)
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
 }
 
-void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel)
+static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
+                                  struct ieee80211_conf *conf)
 {
        struct rtl8187_priv *priv = dev->priv;
 
-       if (priv->rf_init == rtl8225_rf_init)
-               rtl8225_rf_set_tx_power(dev, channel);
+       if (priv->rf->init == rtl8225_rf_init)
+               rtl8225_rf_set_tx_power(dev, conf->channel);
        else
-               rtl8225z2_rf_set_tx_power(dev, channel);
+               rtl8225z2_rf_set_tx_power(dev, conf->channel);
 
-       rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]);
+       rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]);
        msleep(10);
 }
+
+static const struct rtl818x_rf_ops rtl8225_ops = {
+       .name           = "rtl8225",
+       .init           = rtl8225_rf_init,
+       .stop           = rtl8225_rf_stop,
+       .set_chan       = rtl8225_rf_set_channel
+};
+
+static const struct rtl818x_rf_ops rtl8225z2_ops = {
+       .name           = "rtl8225z2",
+       .init           = rtl8225z2_rf_init,
+       .stop           = rtl8225_rf_stop,
+       .set_chan       = rtl8225_rf_set_channel
+};
+
+const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev)
+{
+       u16 reg8, reg9;
+
+       rtl8225_write(dev, 0, 0x1B7);
+
+       reg8 = rtl8225_read(dev, 8);
+       reg9 = rtl8225_read(dev, 9);
+
+       rtl8225_write(dev, 0, 0x0B7);
+
+       if (reg8 != 0x588 || reg9 != 0x700)
+               return &rtl8225_ops;
+
+       return &rtl8225z2_ops;
+}
index 798ba4a97376444cbb28e6a78ece85ba21e57be9..d39ed0295b6e70887f15954330f6e560a585aa18 100644 (file)
 #define RTL8225_ANAPARAM_OFF   0xa00beb59
 #define RTL8225_ANAPARAM2_OFF  0x840dec11
 
-void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data);
-u16  rtl8225_read(struct ieee80211_hw *, u8 addr);
-
-void rtl8225_rf_init(struct ieee80211_hw *);
-void rtl8225z2_rf_init(struct ieee80211_hw *);
-void rtl8225_rf_stop(struct ieee80211_hw *);
-void rtl8225_rf_set_channel(struct ieee80211_hw *, int);
-
+const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *);
 
 static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev,
                                          u8 addr, u32 data)
index 880d4becae312b92de01681762c919ec44730824..1e7d6f8278d7466235433b70052c50d9f960d74a 100644 (file)
@@ -58,13 +58,17 @@ struct rtl818x_csr {
 #define RTL818X_INT_TX_FO              (1 << 15)
        __le32  TX_CONF;
 #define RTL818X_TX_CONF_LOOPBACK_MAC   (1 << 17)
+#define RTL818X_TX_CONF_LOOPBACK_CONT  (3 << 17)
 #define RTL818X_TX_CONF_NO_ICV         (1 << 19)
 #define RTL818X_TX_CONF_DISCW          (1 << 20)
+#define RTL818X_TX_CONF_SAT_HWPLCP     (1 << 24)
 #define RTL818X_TX_CONF_R8180_ABCD     (2 << 25)
 #define RTL818X_TX_CONF_R8180_F                (3 << 25)
 #define RTL818X_TX_CONF_R8185_ABC      (4 << 25)
 #define RTL818X_TX_CONF_R8185_D                (5 << 25)
 #define RTL818X_TX_CONF_HWVER_MASK     (7 << 25)
+#define RTL818X_TX_CONF_PROBE_DTS      (1 << 29)
+#define RTL818X_TX_CONF_HW_SEQNUM      (1 << 30)
 #define RTL818X_TX_CONF_CW_MIN         (1 << 31)
        __le32  RX_CONF;
 #define RTL818X_RX_CONF_MONITOR                (1 <<  0)
@@ -75,8 +79,12 @@ struct rtl818x_csr {
 #define RTL818X_RX_CONF_DATA           (1 << 18)
 #define RTL818X_RX_CONF_CTRL           (1 << 19)
 #define RTL818X_RX_CONF_MGMT           (1 << 20)
+#define RTL818X_RX_CONF_ADDR3          (1 << 21)
+#define RTL818X_RX_CONF_PM             (1 << 22)
 #define RTL818X_RX_CONF_BSSID          (1 << 23)
 #define RTL818X_RX_CONF_RX_AUTORESETPHY        (1 << 28)
+#define RTL818X_RX_CONF_CSDM1          (1 << 29)
+#define RTL818X_RX_CONF_CSDM2          (1 << 30)
 #define RTL818X_RX_CONF_ONLYERLPKT     (1 << 31)
        __le32  INT_TIMEOUT;
        __le32  TBDA;
@@ -92,6 +100,7 @@ struct rtl818x_csr {
        u8      CONFIG0;
        u8      CONFIG1;
        u8      CONFIG2;
+#define RTL818X_CONFIG2_ANTENNA_DIV    (1 << 6)
        __le32  ANAPARAM;
        u8      MSR;
 #define RTL818X_MSR_NO_LINK            (0 << 2)
@@ -104,14 +113,17 @@ struct rtl818x_csr {
 #define RTL818X_CONFIG4_VCOOFF         (1 << 7)
        u8      TESTR;
        u8      reserved_9[2];
-       __le16  PGSELECT;
+       u8      PGSELECT;
+       u8      SECURITY;
        __le32  ANAPARAM2;
        u8      reserved_10[12];
        __le16  BEACON_INTERVAL;
        __le16  ATIM_WND;
        __le16  BEACON_INTERVAL_TIME;
        __le16  ATIMTR_INTERVAL;
-       u8      reserved_11[4];
+       u8      PHY_DELAY;
+       u8      CARRIER_SENSE_COUNTER;
+       u8      reserved_11[2];
        u8      PHY[4];
        __le16  RFPinsOutput;
        __le16  RFPinsEnable;
@@ -149,11 +161,20 @@ struct rtl818x_csr {
        u8      RETRY_CTR;
        u8      reserved_18[5];
        __le32  RDSAR;
-       u8      reserved_19[18];
-       u16     TALLY_CNT;
+       u8      reserved_19[12];
+       __le16  FEMR;
+       u8      reserved_20[4];
+       __le16  TALLY_CNT;
        u8      TALLY_SEL;
 } __attribute__((packed));
 
+struct rtl818x_rf_ops {
+       char *name;
+       void (*init)(struct ieee80211_hw *);
+       void (*stop)(struct ieee80211_hw *);
+       void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
+};
+
 static const struct ieee80211_rate rtl818x_rates[] = {
        { .rate = 10,
          .val = 0,
index a1f8a16878429717e4e0d628e7451ea1a324c742..03384a43186b3470d81744e7f75ee584e4fe57ce 100644 (file)
@@ -49,27 +49,6 @@ static int __init wv_psa_to_irq(u8 irqval)
        return -1;
 }
 
-#ifdef STRUCT_CHECK
-/*------------------------------------------------------------------*/
-/*
- * Sanity routine to verify the sizes of the various WaveLAN interface
- * structures.
- */
-static char *wv_struct_check(void)
-{
-#define        SC(t,s,n)       if (sizeof(t) != s) return(n);
-
-       SC(psa_t, PSA_SIZE, "psa_t");
-       SC(mmw_t, MMW_SIZE, "mmw_t");
-       SC(mmr_t, MMR_SIZE, "mmr_t");
-       SC(ha_t, HA_SIZE, "ha_t");
-
-#undef SC
-
-       return ((char *) NULL);
-}                              /* wv_struct_check */
-#endif                         /* STRUCT_CHECK */
-
 /********************* HOST ADAPTER SUBROUTINES *********************/
 /*
  * Useful subroutines to manage the WaveLAN ISA interface
@@ -3740,7 +3719,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac)
         * non-NCR/AT&T/Lucent ISA card.  See wavelan.p.h for detail on
         * how to configure your card.
         */
-       for (i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
+       for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
                if ((mac[0] == MAC_ADDRESSES[i][0]) &&
                    (mac[1] == MAC_ADDRESSES[i][1]) &&
                    (mac[2] == MAC_ADDRESSES[i][2]))
@@ -4215,14 +4194,11 @@ struct net_device * __init wavelan_probe(int unit)
        int i;
        int r = 0;
 
-#ifdef STRUCT_CHECK
-       if (wv_struct_check() != (char *) NULL) {
-               printk(KERN_WARNING
-                      "%s: wavelan_probe(): structure/compiler botch: \"%s\"\n",
-                      dev->name, wv_struct_check());
-               return -ENODEV;
-       }
-#endif                         /* STRUCT_CHECK */
+       /* compile-time check the sizes of structures */
+       BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
+       BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
+       BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
+       BUILD_BUG_ON(sizeof(ha_t) != HA_SIZE);
 
        dev = alloc_etherdev(sizeof(net_local));
        if (!dev)
index fe242812d858e6161aa4272d43e4461c22cdfeb7..b33ac47dd8df710956340f9cd258e6b6e1c4cd23 100644 (file)
  */
 #undef SET_PSA_CRC             /* Calculate and set the CRC on PSA (slower) */
 #define USE_PSA_CONFIG         /* Use info from the PSA. */
-#undef STRUCT_CHECK            /* Verify padding of structures. */
 #undef EEPROM_IS_PROTECTED     /* doesn't seem to be necessary */
 #define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical). */
 #undef SET_MAC_ADDRESS         /* Experimental */
index 577c647824fecd902447c561780db11a82b09caa..c2037b2a05bf664c5e37192bb6cc9f37956230e6 100644 (file)
@@ -71,27 +71,6 @@ static void wv_nwid_filter(unsigned char mode, net_local *lp);
  * (wavelan modem or i82593)
  */
 
-#ifdef STRUCT_CHECK
-/*------------------------------------------------------------------*/
-/*
- * Sanity routine to verify the sizes of the various WaveLAN interface
- * structures.
- */
-static char *
-wv_structuct_check(void)
-{
-#define        SC(t,s,n)       if (sizeof(t) != s) return(n);
-
-  SC(psa_t, PSA_SIZE, "psa_t");
-  SC(mmw_t, MMW_SIZE, "mmw_t");
-  SC(mmr_t, MMR_SIZE, "mmr_t");
-
-#undef SC
-
-  return((char *) NULL);
-} /* wv_structuct_check */
-#endif /* STRUCT_CHECK */
-
 /******************* MODEM MANAGEMENT SUBROUTINES *******************/
 /*
  * Useful subroutines to manage the modem of the wavelan
@@ -3223,14 +3202,14 @@ wv_mmc_init(struct net_device * dev)
    * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on
    * how to configure your card...
    */
-  for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++)
-    if((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
-       (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
-       (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
+  for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++)
+    if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) &&
+        (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) &&
+        (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2]))
       break;
 
   /* If we have not found it... */
-  if(i == (sizeof(MAC_ADDRESSES) / sizeof(char) / 3))
+  if (i == ARRAY_SIZE(MAC_ADDRESSES))
     {
 #ifdef DEBUG_CONFIG_ERRORS
       printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n",
@@ -3794,14 +3773,10 @@ wv_hw_config(struct net_device *        dev)
   printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
 #endif
 
-#ifdef STRUCT_CHECK
-  if(wv_structuct_check() != (char *) NULL)
-    {
-      printk(KERN_WARNING "%s: wv_hw_config: structure/compiler botch: \"%s\"\n",
-            dev->name, wv_structuct_check());
-      return FALSE;
-    }
-#endif /* STRUCT_CHECK == 1 */
+  /* compile-time check the sizes of structures */
+  BUILD_BUG_ON(sizeof(psa_t) != PSA_SIZE);
+  BUILD_BUG_ON(sizeof(mmw_t) != MMW_SIZE);
+  BUILD_BUG_ON(sizeof(mmr_t) != MMR_SIZE);
 
   /* Reset the pcmcia interface */
   if(wv_pcmcia_reset(dev) == FALSE)
index 4b9de0093a7b2314bf6439512b21f47fe8d6668a..33dd97094227afd07a3d3fb005b4761e7f651d8f 100644 (file)
 #undef WAVELAN_ROAMING_EXT     /* Enable roaming wireless extensions */
 #undef SET_PSA_CRC             /* Set the CRC in PSA (slower) */
 #define USE_PSA_CONFIG         /* Use info from the PSA */
-#undef STRUCT_CHECK            /* Verify padding of structures */
 #undef EEPROM_IS_PROTECTED     /* Doesn't seem to be necessary */
 #define MULTICAST_AVOID                /* Avoid extra multicast (I'm sceptical) */
 #undef SET_MAC_ADDRESS         /* Experimental */
@@ -548,7 +547,7 @@ typedef struct wavepoint_beacon
                        spec_id2,       /* Unused */
                        pdu_type,       /* Unused */
                        seq;            /* WavePoint beacon sequence number */
-  unsigned short       domain_id,      /* WavePoint Domain ID */
+  __be16               domain_id,      /* WavePoint Domain ID */
                        nwid;           /* WavePoint NWID */
 } wavepoint_beacon;
 
index d1ab24a95630e0d56e1049a583f1b84eec998cd0..74b31eafe72db4a374ece9111225eb7798b147c6 100644 (file)
@@ -1,14 +1,13 @@
 config ZD1211RW
        tristate "ZyDAS ZD1211/ZD1211B USB-wireless support"
-       depends on USB && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
-       select WIRELESS_EXT
+       depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
        select FW_LOADER
        ---help---
          This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless
          chip, present in many USB-wireless adapters.
 
-         Device firmware is required alongside this driver. You can download the
-         firmware distribution from http://zd1211.ath.cx/get-firmware
+         Device firmware is required alongside this driver. You can download
+         the firmware distribution from http://zd1211.ath.cx/get-firmware
 
 config ZD1211RW_DEBUG
        bool "ZyDAS ZD1211 debugging"
index 7a2f2a98edab61cfce719d163861c45041969823..cc36126cee8860bd8ad167087ec6f9f3547d6277 100644 (file)
@@ -1,7 +1,6 @@
 obj-$(CONFIG_ZD1211RW) += zd1211rw.o
 
-zd1211rw-objs := zd_chip.o zd_ieee80211.o \
-               zd_mac.o zd_netdev.o \
+zd1211rw-objs := zd_chip.o zd_ieee80211.o zd_mac.o \
                zd_rf_al2230.o zd_rf_rf2959.o \
                zd_rf_al7230b.o zd_rf_uw2453.o \
                zd_rf.o zd_usb.o
index f831b68f1b9cb7b562f8299cb90fb70ba8712a69..99e5b03b3f514043802a457059bfadafc1770cc9 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_chip.c
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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 "zd_rf.h"
 
 void zd_chip_init(struct zd_chip *chip,
-                struct net_device *netdev,
+                struct ieee80211_hw *hw,
                 struct usb_interface *intf)
 {
        memset(chip, 0, sizeof(*chip));
        mutex_init(&chip->mutex);
-       zd_usb_init(&chip->usb, netdev, intf);
+       zd_usb_init(&chip->usb, hw, intf);
        zd_rf_init(&chip->rf);
 }
 
@@ -50,7 +53,7 @@ void zd_chip_clear(struct zd_chip *chip)
 
 static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
 {
-       u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr;
+       u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip));
        return scnprintf(buffer, size, "%02x-%02x-%02x",
                         addr[0], addr[1], addr[2]);
 }
@@ -378,15 +381,18 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
        };
        DECLARE_MAC_BUF(mac);
 
-       reqs[0].value = (mac_addr[3] << 24)
-                     | (mac_addr[2] << 16)
-                     | (mac_addr[1] <<  8)
-                     |  mac_addr[0];
-       reqs[1].value = (mac_addr[5] <<  8)
-                     |  mac_addr[4];
-
-       dev_dbg_f(zd_chip_dev(chip),
-               "mac addr %s\n", print_mac(mac, mac_addr));
+       if (mac_addr) {
+               reqs[0].value = (mac_addr[3] << 24)
+                             | (mac_addr[2] << 16)
+                             | (mac_addr[1] <<  8)
+                             |  mac_addr[0];
+               reqs[1].value = (mac_addr[5] <<  8)
+                             |  mac_addr[4];
+               dev_dbg_f(zd_chip_dev(chip),
+                       "mac addr %s\n", print_mac(mac, mac_addr));
+       } else {
+               dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
+       }
 
        mutex_lock(&chip->mutex);
        r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
@@ -980,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip)
        return 0;
 }
 
-static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
+static int set_mandatory_rates(struct zd_chip *chip, int mode)
 {
        u32 rates;
        ZD_ASSERT(mutex_is_locked(&chip->mutex));
@@ -988,11 +994,11 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
         * that the device is supporting. Until further notice we should try
         * to support 802.11g also for full speed USB.
         */
-       switch (std) {
-       case IEEE80211B:
+       switch (mode) {
+       case MODE_IEEE80211B:
                rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
                break;
-       case IEEE80211G:
+       case MODE_IEEE80211G:
                rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
                        CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
                break;
@@ -1003,24 +1009,17 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
 }
 
 int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
-       u8 rts_rate, int preamble)
+                                   int preamble)
 {
-       int rts_mod = ZD_RX_CCK;
        u32 value = 0;
 
-       /* Modulation bit */
-       if (ZD_MODULATION_TYPE(rts_rate) == ZD_OFDM)
-               rts_mod = ZD_RX_OFDM;
-
-       dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
-               rts_rate, preamble);
-
-       value |= ZD_PURE_RATE(rts_rate) << RTSCTS_SH_RTS_RATE;
-       value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
+       dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble);
        value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
        value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
 
-       /* We always send 11M self-CTS messages, like the vendor driver. */
+       /* We always send 11M RTS/self-CTS messages, like the vendor driver. */
+       value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE;
+       value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE;
        value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE;
        value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
 
@@ -1109,7 +1108,7 @@ int zd_chip_init_hw(struct zd_chip *chip)
         * It might be discussed, whether we should suppport pure b mode for
         * full speed USB.
         */
-       r = set_mandatory_rates(chip, IEEE80211G);
+       r = set_mandatory_rates(chip, MODE_IEEE80211G);
        if (r)
                goto out;
        /* Disabling interrupts is certainly a smart thing here.
@@ -1320,12 +1319,17 @@ out:
        return r;
 }
 
-int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
+int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
 {
-       ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
-       dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
+       int r;
+
+       if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
+               return -EINVAL;
 
-       return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
+       mutex_lock(&chip->mutex);
+       r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
+       mutex_unlock(&chip->mutex);
+       return r;
 }
 
 static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size)
@@ -1468,56 +1472,44 @@ u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
 {
        return (status->frame_status&ZD_RX_OFDM) ?
                ofdm_qual_percent(status->signal_quality_ofdm,
-                                         zd_rate_from_ofdm_plcp_header(rx_frame),
+                                 zd_rate_from_ofdm_plcp_header(rx_frame),
                                  size) :
                cck_qual_percent(status->signal_quality_cck);
 }
 
-u8 zd_rx_strength_percent(u8 rssi)
-{
-       int r = (rssi*100) / 41;
-       if (r > 100)
-               r = 100;
-       return (u8) r;
-}
-
-u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
+/**
+ * zd_rx_rate - report zd-rate
+ * @rx_frame - received frame
+ * @rx_status - rx_status as given by the device
+ *
+ * This function converts the rate as encoded in the received packet to the
+ * zd-rate, we are using on other places in the driver.
+ */
+u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
 {
-       static const u16 ofdm_rates[] = {
-               [ZD_OFDM_PLCP_RATE_6M]  = 60,
-               [ZD_OFDM_PLCP_RATE_9M]  = 90,
-               [ZD_OFDM_PLCP_RATE_12M] = 120,
-               [ZD_OFDM_PLCP_RATE_18M] = 180,
-               [ZD_OFDM_PLCP_RATE_24M] = 240,
-               [ZD_OFDM_PLCP_RATE_36M] = 360,
-               [ZD_OFDM_PLCP_RATE_48M] = 480,
-               [ZD_OFDM_PLCP_RATE_54M] = 540,
-       };
-       u16 rate;
+       u8 zd_rate;
        if (status->frame_status & ZD_RX_OFDM) {
-               /* Deals with PLCP OFDM rate (not zd_rates) */
-               u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);
-               rate = ofdm_rates[ofdm_rate & 0xf];
+               zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame);
        } else {
                switch (zd_cck_plcp_header_signal(rx_frame)) {
                case ZD_CCK_PLCP_SIGNAL_1M:
-                       rate = 10;
+                       zd_rate = ZD_CCK_RATE_1M;
                        break;
                case ZD_CCK_PLCP_SIGNAL_2M:
-                       rate = 20;
+                       zd_rate = ZD_CCK_RATE_2M;
                        break;
                case ZD_CCK_PLCP_SIGNAL_5M5:
-                       rate = 55;
+                       zd_rate = ZD_CCK_RATE_5_5M;
                        break;
                case ZD_CCK_PLCP_SIGNAL_11M:
-                       rate = 110;
+                       zd_rate = ZD_CCK_RATE_11M;
                        break;
                default:
-                       rate = 0;
+                       zd_rate = 0;
                }
        }
 
-       return rate;
+       return zd_rate;
 }
 
 int zd_chip_switch_radio_on(struct zd_chip *chip)
@@ -1557,20 +1549,22 @@ void zd_chip_disable_int(struct zd_chip *chip)
        mutex_unlock(&chip->mutex);
 }
 
-int zd_chip_enable_rx(struct zd_chip *chip)
+int zd_chip_enable_rxtx(struct zd_chip *chip)
 {
        int r;
 
        mutex_lock(&chip->mutex);
+       zd_usb_enable_tx(&chip->usb);
        r = zd_usb_enable_rx(&chip->usb);
        mutex_unlock(&chip->mutex);
        return r;
 }
 
-void zd_chip_disable_rx(struct zd_chip *chip)
+void zd_chip_disable_rxtx(struct zd_chip *chip)
 {
        mutex_lock(&chip->mutex);
        zd_usb_disable_rx(&chip->usb);
+       zd_usb_disable_tx(&chip->usb);
        mutex_unlock(&chip->mutex);
 }
 
index 8009b70213e2d21abbda4a7842cb4d078d0cddc7..009c03777a3543ef369ff889dda72b5867498971 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_chip.h
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
@@ -433,9 +436,10 @@ enum {
 #define CR_GROUP_HASH_P2               CTL_REG(0x0628)
 
 #define CR_RX_TIMEOUT                  CTL_REG(0x062C)
+
 /* Basic rates supported by the BSS. When producing ACK or CTS messages, the
  * device will use a rate in this table that is less than or equal to the rate
- * of the incoming frame which prompted the response */
+ * of the incoming frame which prompted the response. */
 #define CR_BASIC_RATE_TBL              CTL_REG(0x0630)
 #define CR_RATE_1M     (1 <<  0)       /* 802.11b */
 #define CR_RATE_2M     (1 <<  1)       /* 802.11b */
@@ -509,14 +513,37 @@ enum {
 #define CR_UNDERRUN_CNT                        CTL_REG(0x0688)
 
 #define CR_RX_FILTER                   CTL_REG(0x068c)
+#define RX_FILTER_ASSOC_REQUEST                (1 <<  0)
 #define RX_FILTER_ASSOC_RESPONSE       (1 <<  1)
+#define RX_FILTER_REASSOC_REQUEST      (1 <<  2)
 #define RX_FILTER_REASSOC_RESPONSE     (1 <<  3)
+#define RX_FILTER_PROBE_REQUEST                (1 <<  4)
 #define RX_FILTER_PROBE_RESPONSE       (1 <<  5)
+/* bits 6 and 7 reserved */
 #define RX_FILTER_BEACON               (1 <<  8)
+#define RX_FILTER_ATIM                 (1 <<  9)
 #define RX_FILTER_DISASSOC             (1 << 10)
 #define RX_FILTER_AUTH                 (1 << 11)
-#define AP_RX_FILTER                   0x0400feff
-#define STA_RX_FILTER                  0x0000ffff
+#define RX_FILTER_DEAUTH               (1 << 12)
+#define RX_FILTER_PSPOLL               (1 << 26)
+#define RX_FILTER_RTS                  (1 << 27)
+#define RX_FILTER_CTS                  (1 << 28)
+#define RX_FILTER_ACK                  (1 << 29)
+#define RX_FILTER_CFEND                        (1 << 30)
+#define RX_FILTER_CFACK                        (1 << 31)
+
+/* Enable bits for all frames you are interested in. */
+#define STA_RX_FILTER  (RX_FILTER_ASSOC_REQUEST | RX_FILTER_ASSOC_RESPONSE | \
+       RX_FILTER_REASSOC_REQUEST | RX_FILTER_REASSOC_RESPONSE | \
+       RX_FILTER_PROBE_REQUEST | RX_FILTER_PROBE_RESPONSE | \
+       (0x3 << 6) /* vendor driver sets these reserved bits */ | \
+       RX_FILTER_BEACON | RX_FILTER_ATIM | RX_FILTER_DISASSOC | \
+       RX_FILTER_AUTH | RX_FILTER_DEAUTH | \
+       (0x7 << 13) /* vendor driver sets these reserved bits */ | \
+       RX_FILTER_PSPOLL | RX_FILTER_ACK) /* 0x2400ffff */
+
+#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \
+       RX_FILTER_CFEND | RX_FILTER_CFACK)
 
 /* Monitor mode sets filter to 0xfffff */
 
@@ -730,7 +757,7 @@ static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf)
 #define zd_chip_dev(chip) (&(chip)->usb.intf->dev)
 
 void zd_chip_init(struct zd_chip *chip,
-                struct net_device *netdev,
+                struct ieee80211_hw *hw,
                 struct usb_interface *intf);
 void zd_chip_clear(struct zd_chip *chip);
 int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr);
@@ -835,14 +862,12 @@ int zd_chip_switch_radio_on(struct zd_chip *chip);
 int zd_chip_switch_radio_off(struct zd_chip *chip);
 int zd_chip_enable_int(struct zd_chip *chip);
 void zd_chip_disable_int(struct zd_chip *chip);
-int zd_chip_enable_rx(struct zd_chip *chip);
-void zd_chip_disable_rx(struct zd_chip *chip);
+int zd_chip_enable_rxtx(struct zd_chip *chip);
+void zd_chip_disable_rxtx(struct zd_chip *chip);
 int zd_chip_enable_hwint(struct zd_chip *chip);
 int zd_chip_disable_hwint(struct zd_chip *chip);
 int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel);
-
-int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
-       u8 rts_rate, int preamble);
+int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, int preamble);
 
 static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type)
 {
@@ -859,17 +884,7 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates)
        return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates);
 }
 
-int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates);
-
-static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
-{
-       int r;
-
-       mutex_lock(&chip->mutex);
-       r = zd_chip_set_basic_rates_locked(chip, cr_rates);
-       mutex_unlock(&chip->mutex);
-       return r;
-}
+int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates);
 
 int zd_chip_lock_phy_regs(struct zd_chip *chip);
 int zd_chip_unlock_phy_regs(struct zd_chip *chip);
@@ -893,9 +908,8 @@ struct rx_status;
 
 u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
                       const struct rx_status *status);
-u8 zd_rx_strength_percent(u8 rssi);
 
-u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
+u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status);
 
 struct zd_mc_hash {
        u32 low;
index 505b4d7dd0e29003f7ce2e825f469a5a895e77f1..5200db405610709508c91f5c1d04ab4c2f4de022 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_def.h
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index 189160efd2ae45e3265f97baafd40c472224556a..7c277ec43f79a6a736f3055a283c18a9c677e5c9 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_ieee80211.c
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
  */
 
 /*
- * A lot of this code is generic and should be moved into the upper layers
- * at some point.
+ * In the long term, we'll probably find a better way of handling regulatory
+ * requirements outside of the driver.
  */
 
-#include <linux/errno.h>
-#include <linux/wireless.h>
 #include <linux/kernel.h>
-#include <net/ieee80211.h>
+#include <net/mac80211.h>
 
-#include "zd_def.h"
 #include "zd_ieee80211.h"
 #include "zd_mac.h"
 
+struct channel_range {
+       u8 regdomain;
+       u8 start;
+       u8 end; /* exclusive (channel must be less than end) */
+};
+
 static const struct channel_range channel_ranges[] = {
-       [0]                      = { 0,  0},
-       [ZD_REGDOMAIN_FCC]       = { 1, 12},
-       [ZD_REGDOMAIN_IC]        = { 1, 12},
-       [ZD_REGDOMAIN_ETSI]      = { 1, 14},
-       [ZD_REGDOMAIN_JAPAN]     = { 1, 14},
-       [ZD_REGDOMAIN_SPAIN]     = { 1, 14},
-       [ZD_REGDOMAIN_FRANCE]    = { 1, 14},
+       { ZD_REGDOMAIN_FCC,             1, 12 },
+       { ZD_REGDOMAIN_IC,              1, 12 },
+       { ZD_REGDOMAIN_ETSI,            1, 14 },
+       { ZD_REGDOMAIN_JAPAN,           1, 14 },
+       { ZD_REGDOMAIN_SPAIN,           1, 14 },
+       { ZD_REGDOMAIN_FRANCE,          1, 14 },
 
        /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in
         * 802.11). However, in 2001 the range was extended to include channels
         * 1-13. The ZyDAS devices still use the old region code but are
         * designed to allow the extra channel access in Japan. */
-       [ZD_REGDOMAIN_JAPAN_ADD] = { 1, 15},
+       { ZD_REGDOMAIN_JAPAN_ADD,       1, 15 },
 };
 
-const struct channel_range *zd_channel_range(u8 regdomain)
-{
-       if (regdomain >= ARRAY_SIZE(channel_ranges))
-               regdomain = 0;
-       return &channel_ranges[regdomain];
-}
-
-int zd_regdomain_supports_channel(u8 regdomain, u8 channel)
-{
-       const struct channel_range *range = zd_channel_range(regdomain);
-       return range->start <= channel && channel < range->end;
-}
-
-int zd_regdomain_supported(u8 regdomain)
-{
-       const struct channel_range *range = zd_channel_range(regdomain);
-       return range->start != 0;
-}
-
-/* Stores channel frequencies in MHz. */
-static const u16 channel_frequencies[] = {
-       2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447,
-       2452, 2457, 2462, 2467, 2472, 2484,
-};
-
-#define NUM_CHANNELS ARRAY_SIZE(channel_frequencies)
-
-static int compute_freq(struct iw_freq *freq, u32 mhz, u32 hz)
-{
-       u32 factor;
-
-       freq->e = 0;
-       if (mhz >= 1000000000U) {
-               pr_debug("zd1211 mhz %u to large\n", mhz);
-               freq->m = 0;
-               return -EINVAL;
-       }
-
-       factor = 1000;
-       while (mhz >= factor) {
-
-               freq->e += 1;
-               factor *= 10;
-       }
-
-       factor /= 1000U;
-       freq->m = mhz * (1000000U/factor) + hz/factor;
-
-       return 0;
-}
-
-int zd_channel_to_freq(struct iw_freq *freq, u8 channel)
+static const struct channel_range *zd_channel_range(u8 regdomain)
 {
-       if (channel > NUM_CHANNELS) {
-               freq->m = 0;
-               freq->e = 0;
-               return -EINVAL;
-       }
-       if (!channel) {
-               freq->m = 0;
-               freq->e = 0;
-               return -EINVAL;
+       int i;
+       for (i = 0; i < ARRAY_SIZE(channel_ranges); i++) {
+               const struct channel_range *range = &channel_ranges[i];
+               if (range->regdomain == regdomain)
+                       return range;
        }
-       return compute_freq(freq, channel_frequencies[channel-1], 0);
+       return NULL;
 }
 
-static int freq_to_mhz(const struct iw_freq *freq)
-{
-       u32 factor;
-       int e;
-
-       /* Such high frequencies are not supported. */
-       if (freq->e > 6)
-               return -EINVAL;
-
-       factor = 1;
-       for (e = freq->e; e > 0; --e) {
-               factor *= 10;
-       }
-       factor = 1000000U / factor;
-
-       if (freq->m % factor) {
-               return -EINVAL;
-       }
-
-       return freq->m / factor;
-}
+#define CHAN_TO_IDX(chan) ((chan) - 1)
 
-int zd_find_channel(u8 *channel, const struct iw_freq *freq)
+static void unmask_bg_channels(struct ieee80211_hw *hw,
+       const struct channel_range *range,
+       struct ieee80211_hw_mode *mode)
 {
-       int i, r;
-       u32 mhz;
-
-       if (freq->m < 1000) {
-               if (freq->m  > NUM_CHANNELS || freq->m == 0)
-                       return -EINVAL;
-               *channel = freq->m;
-               return 1;
-       }
-
-       r = freq_to_mhz(freq);
-       if (r < 0)
-               return r;
-       mhz = r;
+       u8 channel;
 
-       for (i = 0; i < NUM_CHANNELS; i++) {
-               if (mhz == channel_frequencies[i]) {
-                       *channel = i+1;
-                       return 1;
-               }
+       for (channel = range->start; channel < range->end; channel++) {
+               struct ieee80211_channel *chan =
+                       &mode->channels[CHAN_TO_IDX(channel)];
+               chan->flag |= IEEE80211_CHAN_W_SCAN |
+                       IEEE80211_CHAN_W_ACTIVE_SCAN |
+                       IEEE80211_CHAN_W_IBSS;
        }
-
-       return -EINVAL;
 }
 
-int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain)
+void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain)
 {
-       struct ieee80211_geo geo;
+       struct zd_mac *mac = zd_hw_mac(hw);
        const struct channel_range *range;
-       int i;
-       u8 channel;
 
-       dev_dbg(zd_mac_dev(zd_netdev_mac(ieee->dev)),
-               "regdomain %#04x\n", regdomain);
+       dev_dbg(zd_mac_dev(mac), "regdomain %#02x\n", regdomain);
 
        range = zd_channel_range(regdomain);
-       if (range->start == 0) {
-               dev_err(zd_mac_dev(zd_netdev_mac(ieee->dev)),
-                       "zd1211 regdomain %#04x not supported\n",
-                       regdomain);
-               return -EINVAL;
+       if (!range) {
+               /* The vendor driver overrides the regulatory domain and
+                * allowed channel registers and unconditionally restricts
+                * available channels to 1-11 everywhere. Match their
+                * questionable behaviour only for regdomains which we don't
+                * recognise. */
+               dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: "
+                       "%#02x. Defaulting to FCC.\n", regdomain);
+               range = zd_channel_range(ZD_REGDOMAIN_FCC);
        }
 
-       memset(&geo, 0, sizeof(geo));
-
-       for (i = 0, channel = range->start; channel < range->end; channel++) {
-               struct ieee80211_channel *chan = &geo.bg[i++];
-               chan->freq = channel_frequencies[channel - 1];
-               chan->channel = channel;
-       }
-
-       geo.bg_channels = i;
-       memcpy(geo.name, "XX ", 4);
-       ieee80211_set_geo(ieee, &geo);
-       return 0;
+       unmask_bg_channels(hw, range, &mac->modes[0]);
+       unmask_bg_channels(hw, range, &mac->modes[1]);
 }
+
index fbf6491dce7e00d45a0ecdaca36ca76a3f0b0a0e..26b79f19758751daadade34a7422595397950d4e 100644 (file)
@@ -1,7 +1,27 @@
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
+ *
+ * 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 _ZD_IEEE80211_H
 #define _ZD_IEEE80211_H
 
-#include <net/ieee80211.h>
+#include <net/mac80211.h>
 
 /* Additional definitions from the standards.
  */
@@ -19,22 +39,7 @@ enum {
        MAX_CHANNEL24 = 14,
 };
 
-struct channel_range {
-       u8 start;
-       u8 end; /* exclusive (channel must be less than end) */
-};
-
-struct iw_freq;
-
-int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain);
-
-const struct channel_range *zd_channel_range(u8 regdomain);
-int zd_regdomain_supports_channel(u8 regdomain, u8 channel);
-int zd_regdomain_supported(u8 regdomain);
-
-/* for 2.4 GHz band */
-int zd_channel_to_freq(struct iw_freq *freq, u8 channel);
-int zd_find_channel(u8 *channel, const struct iw_freq *freq);
+void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain);
 
 #define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80
 
@@ -54,8 +59,8 @@ static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header)
  *
  * See the struct zd_ctrlset definition in zd_mac.h.
  */
-#define ZD_OFDM_PLCP_RATE_6M           0xb
-#define ZD_OFDM_PLCP_RATE_9M           0xf
+#define ZD_OFDM_PLCP_RATE_6M   0xb
+#define ZD_OFDM_PLCP_RATE_9M   0xf
 #define ZD_OFDM_PLCP_RATE_12M  0xa
 #define ZD_OFDM_PLCP_RATE_18M  0xe
 #define ZD_OFDM_PLCP_RATE_24M  0x9
@@ -87,10 +92,4 @@ static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header)
 #define ZD_CCK_PLCP_SIGNAL_5M5 0x37
 #define ZD_CCK_PLCP_SIGNAL_11M 0x6e
 
-enum ieee80211_std {
-       IEEE80211B = 0x01,
-       IEEE80211A = 0x02,
-       IEEE80211G = 0x04,
-};
-
 #endif /* _ZD_IEEE80211_H */
index 5298a8bf11298496fa2496544355ef29649a9e89..49127e4b42c24c3b22d5b8c8c6d3918e224acdfa 100644 (file)
@@ -1,4 +1,9 @@
-/* zd_mac.c
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
+ * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
  *
  * 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
@@ -17,7 +22,6 @@
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/wireless.h>
 #include <linux/usb.h>
 #include <linux/jiffies.h>
 #include <net/ieee80211_radiotap.h>
 #include "zd_chip.h"
 #include "zd_mac.h"
 #include "zd_ieee80211.h"
-#include "zd_netdev.h"
 #include "zd_rf.h"
 
-static void ieee_init(struct ieee80211_device *ieee);
-static void softmac_init(struct ieee80211softmac_device *sm);
-static void set_rts_cts_work(struct work_struct *work);
-static void set_basic_rates_work(struct work_struct *work);
+/* This table contains the hardware specific values for the modulation rates. */
+static const struct ieee80211_rate zd_rates[] = {
+       { .rate = 10,
+         .val = ZD_CCK_RATE_1M,
+         .flags = IEEE80211_RATE_CCK },
+       { .rate = 20,
+         .val = ZD_CCK_RATE_2M,
+         .val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT,
+         .flags = IEEE80211_RATE_CCK_2 },
+       { .rate = 55,
+         .val = ZD_CCK_RATE_5_5M,
+         .val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT,
+         .flags = IEEE80211_RATE_CCK_2 },
+       { .rate = 110,
+         .val = ZD_CCK_RATE_11M,
+         .val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT,
+         .flags = IEEE80211_RATE_CCK_2 },
+       { .rate = 60,
+         .val = ZD_OFDM_RATE_6M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 90,
+         .val = ZD_OFDM_RATE_9M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 120,
+         .val = ZD_OFDM_RATE_12M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 180,
+         .val = ZD_OFDM_RATE_18M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 240,
+         .val = ZD_OFDM_RATE_24M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 360,
+         .val = ZD_OFDM_RATE_36M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 480,
+         .val = ZD_OFDM_RATE_48M,
+         .flags = IEEE80211_RATE_OFDM },
+       { .rate = 540,
+         .val = ZD_OFDM_RATE_54M,
+         .flags = IEEE80211_RATE_OFDM },
+};
+
+static const struct ieee80211_channel zd_channels[] = {
+       { .chan = 1,
+         .freq = 2412},
+       { .chan = 2,
+         .freq = 2417},
+       { .chan = 3,
+         .freq = 2422},
+       { .chan = 4,
+         .freq = 2427},
+       { .chan = 5,
+         .freq = 2432},
+       { .chan = 6,
+         .freq = 2437},
+       { .chan = 7,
+         .freq = 2442},
+       { .chan = 8,
+         .freq = 2447},
+       { .chan = 9,
+         .freq = 2452},
+       { .chan = 10,
+         .freq = 2457},
+       { .chan = 11,
+         .freq = 2462},
+       { .chan = 12,
+         .freq = 2467},
+       { .chan = 13,
+         .freq = 2472},
+       { .chan = 14,
+         .freq = 2484}
+};
 
 static void housekeeping_init(struct zd_mac *mac);
 static void housekeeping_enable(struct zd_mac *mac);
 static void housekeeping_disable(struct zd_mac *mac);
 
-static void set_multicast_hash_handler(struct work_struct *work);
-
-static void do_rx(unsigned long mac_ptr);
-
-int zd_mac_init(struct zd_mac *mac,
-               struct net_device *netdev,
-               struct usb_interface *intf)
-{
-       struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
-
-       memset(mac, 0, sizeof(*mac));
-       spin_lock_init(&mac->lock);
-       mac->netdev = netdev;
-       INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
-       INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work);
-
-       skb_queue_head_init(&mac->rx_queue);
-       tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac);
-       tasklet_disable(&mac->rx_tasklet);
-
-       ieee_init(ieee);
-       softmac_init(ieee80211_priv(netdev));
-       zd_chip_init(&mac->chip, netdev, intf);
-       housekeeping_init(mac);
-       INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
-       return 0;
-}
-
-static int reset_channel(struct zd_mac *mac)
-{
-       int r;
-       unsigned long flags;
-       const struct channel_range *range;
-
-       spin_lock_irqsave(&mac->lock, flags);
-       range = zd_channel_range(mac->regdomain);
-       if (!range->start) {
-               r = -EINVAL;
-               goto out;
-       }
-       mac->requested_channel = range->start;
-       r = 0;
-out:
-       spin_unlock_irqrestore(&mac->lock, flags);
-       return r;
-}
-
-int zd_mac_preinit_hw(struct zd_mac *mac)
+int zd_mac_preinit_hw(struct ieee80211_hw *hw)
 {
        int r;
        u8 addr[ETH_ALEN];
+       struct zd_mac *mac = zd_hw_mac(hw);
 
        r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
        if (r)
                return r;
 
-       memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
+       SET_IEEE80211_PERM_ADDR(hw, addr);
+
        return 0;
 }
 
-int zd_mac_init_hw(struct zd_mac *mac)
+int zd_mac_init_hw(struct ieee80211_hw *hw)
 {
        int r;
+       struct zd_mac *mac = zd_hw_mac(hw);
        struct zd_chip *chip = &mac->chip;
        u8 default_regdomain;
 
@@ -116,22 +144,9 @@ int zd_mac_init_hw(struct zd_mac *mac)
        r = zd_read_regdomain(chip, &default_regdomain);
        if (r)
                goto disable_int;
-       if (!zd_regdomain_supported(default_regdomain)) {
-               /* The vendor driver overrides the regulatory domain and
-                * allowed channel registers and unconditionally restricts
-                * available channels to 1-11 everywhere. Match their
-                * questionable behaviour only for regdomains which we don't
-                * recognise. */
-               dev_warn(zd_mac_dev(mac),  "Unrecognised regulatory domain: "
-                       "%#04x. Defaulting to FCC.\n", default_regdomain);
-               default_regdomain = ZD_REGDOMAIN_FCC;
-       }
        spin_lock_irq(&mac->lock);
        mac->regdomain = mac->default_regdomain = default_regdomain;
        spin_unlock_irq(&mac->lock);
-       r = reset_channel(mac);
-       if (r)
-               goto disable_int;
 
        /* We must inform the device that we are doing encryption/decryption in
         * software at the moment. */
@@ -139,9 +154,7 @@ int zd_mac_init_hw(struct zd_mac *mac)
        if (r)
                goto disable_int;
 
-       r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain);
-       if (r)
-               goto disable_int;
+       zd_geo_init(hw, mac->regdomain);
 
        r = 0;
 disable_int:
@@ -153,8 +166,6 @@ out:
 void zd_mac_clear(struct zd_mac *mac)
 {
        flush_workqueue(zd_workqueue);
-       skb_queue_purge(&mac->rx_queue);
-       tasklet_kill(&mac->rx_tasklet);
        zd_chip_clear(&mac->chip);
        ZD_ASSERT(!spin_is_locked(&mac->lock));
        ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
@@ -162,34 +173,27 @@ void zd_mac_clear(struct zd_mac *mac)
 
 static int set_rx_filter(struct zd_mac *mac)
 {
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-       u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER;
-       return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
-}
+       unsigned long flags;
+       u32 filter = STA_RX_FILTER;
 
-static int set_sniffer(struct zd_mac *mac)
-{
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-       return zd_iowrite32(&mac->chip, CR_SNIFFER_ON,
-               ieee->iw_mode == IW_MODE_MONITOR ? 1 : 0);
-       return 0;
+       spin_lock_irqsave(&mac->lock, flags);
+       if (mac->pass_ctrl)
+               filter |= RX_FILTER_CTRL;
+       spin_unlock_irqrestore(&mac->lock, flags);
+
+       return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
 }
 
 static int set_mc_hash(struct zd_mac *mac)
 {
        struct zd_mc_hash hash;
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-
        zd_mc_clear(&hash);
-       if (ieee->iw_mode == IW_MODE_MONITOR)
-               zd_mc_add_all(&hash);
-
        return zd_chip_set_multicast_hash(&mac->chip, &hash);
 }
 
-int zd_mac_open(struct net_device *netdev)
+static int zd_op_start(struct ieee80211_hw *hw)
 {
-       struct zd_mac *mac = zd_netdev_mac(netdev);
+       struct zd_mac *mac = zd_hw_mac(hw);
        struct zd_chip *chip = &mac->chip;
        struct zd_usb *usb = &chip->usb;
        int r;
@@ -200,23 +204,14 @@ int zd_mac_open(struct net_device *netdev)
                        goto out;
        }
 
-       tasklet_enable(&mac->rx_tasklet);
-
        r = zd_chip_enable_int(chip);
        if (r < 0)
                goto out;
 
-       r = zd_write_mac_addr(chip, netdev->dev_addr);
-       if (r)
-               goto disable_int;
-
        r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
        if (r < 0)
                goto disable_int;
        r = set_rx_filter(mac);
-       if (r)
-               goto disable_int;
-       r = set_sniffer(mac);
        if (r)
                goto disable_int;
        r = set_mc_hash(mac);
@@ -225,21 +220,17 @@ int zd_mac_open(struct net_device *netdev)
        r = zd_chip_switch_radio_on(chip);
        if (r < 0)
                goto disable_int;
-       r = zd_chip_set_channel(chip, mac->requested_channel);
-       if (r < 0)
-               goto disable_radio;
-       r = zd_chip_enable_rx(chip);
+       r = zd_chip_enable_rxtx(chip);
        if (r < 0)
                goto disable_radio;
        r = zd_chip_enable_hwint(chip);
        if (r < 0)
-               goto disable_rx;
+               goto disable_rxtx;
 
        housekeeping_enable(mac);
-       ieee80211softmac_start(netdev);
        return 0;
-disable_rx:
-       zd_chip_disable_rx(chip);
+disable_rxtx:
+       zd_chip_disable_rxtx(chip);
 disable_radio:
        zd_chip_switch_radio_off(chip);
 disable_int:
@@ -248,494 +239,190 @@ out:
        return r;
 }
 
-int zd_mac_stop(struct net_device *netdev)
+/**
+ * clear_tx_skb_control_block - clears the control block of tx skbuffs
+ * @skb: a &struct sk_buff pointer
+ *
+ * This clears the control block of skbuff buffers, which were transmitted to
+ * the device. Notify that the function is not thread-safe, so prevent
+ * multiple calls.
+ */
+static void clear_tx_skb_control_block(struct sk_buff *skb)
 {
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct zd_chip *chip = &mac->chip;
+       struct zd_tx_skb_control_block *cb =
+               (struct zd_tx_skb_control_block *)skb->cb;
 
-       netif_stop_queue(netdev);
+       kfree(cb->control);
+       cb->control = NULL;
+}
 
-       /*
-        * The order here deliberately is a little different from the open()
+/**
+ * kfree_tx_skb - frees a tx skbuff
+ * @skb: a &struct sk_buff pointer
+ *
+ * Frees the tx skbuff. Frees also the allocated control structure in the
+ * control block if necessary.
+ */
+static void kfree_tx_skb(struct sk_buff *skb)
+{
+       clear_tx_skb_control_block(skb);
+       dev_kfree_skb_any(skb);
+}
+
+static void zd_op_stop(struct ieee80211_hw *hw)
+{
+       struct zd_mac *mac = zd_hw_mac(hw);
+       struct zd_chip *chip = &mac->chip;
+       struct sk_buff *skb;
+       struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue;
+
+       /* The order here deliberately is a little different from the open()
         * method, since we need to make sure there is no opportunity for RX
-        * frames to be processed by softmac after we have stopped it.
+        * frames to be processed by mac80211 after we have stopped it.
         */
 
-       zd_chip_disable_rx(chip);
-       skb_queue_purge(&mac->rx_queue);
-       tasklet_disable(&mac->rx_tasklet);
+       zd_chip_disable_rxtx(chip);
        housekeeping_disable(mac);
-       ieee80211softmac_stop(netdev);
-
-       /* Ensure no work items are running or queued from this point */
-       cancel_delayed_work(&mac->set_rts_cts_work);
-       cancel_delayed_work(&mac->set_basic_rates_work);
        flush_workqueue(zd_workqueue);
-       mac->updating_rts_rate = 0;
-       mac->updating_basic_rates = 0;
 
        zd_chip_disable_hwint(chip);
        zd_chip_switch_radio_off(chip);
        zd_chip_disable_int(chip);
 
-       return 0;
-}
-
-int zd_mac_set_mac_address(struct net_device *netdev, void *p)
-{
-       int r;
-       unsigned long flags;
-       struct sockaddr *addr = p;
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct zd_chip *chip = &mac->chip;
-       DECLARE_MAC_BUF(mac2);
-
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       dev_dbg_f(zd_mac_dev(mac),
-                 "Setting MAC to %s\n", print_mac(mac2, addr->sa_data));
-
-       if (netdev->flags & IFF_UP) {
-               r = zd_write_mac_addr(chip, addr->sa_data);
-               if (r)
-                       return r;
-       }
-
-       spin_lock_irqsave(&mac->lock, flags);
-       memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
-       spin_unlock_irqrestore(&mac->lock, flags);
-
-       return 0;
-}
-
-static void set_multicast_hash_handler(struct work_struct *work)
-{
-       struct zd_mac *mac = container_of(work, struct zd_mac,
-                                         set_multicast_hash_work);
-       struct zd_mc_hash hash;
-
-       spin_lock_irq(&mac->lock);
-       hash = mac->multicast_hash;
-       spin_unlock_irq(&mac->lock);
 
-       zd_chip_set_multicast_hash(&mac->chip, &hash);
+       while ((skb = skb_dequeue(ack_wait_queue)))
+               kfree_tx_skb(skb);
 }
 
-void zd_mac_set_multicast_list(struct net_device *dev)
-{
-       struct zd_mac *mac = zd_netdev_mac(dev);
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-       struct zd_mc_hash hash;
-       struct dev_mc_list *mc;
-       unsigned long flags;
-       DECLARE_MAC_BUF(mac2);
-
-       if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) ||
-                       ieee->iw_mode == IW_MODE_MONITOR) {
-               zd_mc_add_all(&hash);
-       } else {
-               zd_mc_clear(&hash);
-               for (mc = dev->mc_list; mc; mc = mc->next) {
-                       dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n",
-                                 print_mac(mac2, mc->dmi_addr));
-                       zd_mc_add_addr(&hash, mc->dmi_addr);
-               }
-       }
-
-       spin_lock_irqsave(&mac->lock, flags);
-       mac->multicast_hash = hash;
-       spin_unlock_irqrestore(&mac->lock, flags);
-       queue_work(zd_workqueue, &mac->set_multicast_hash_work);
-}
-
-int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain)
-{
-       int r;
-       u8 channel;
-
-       ZD_ASSERT(!irqs_disabled());
-       spin_lock_irq(&mac->lock);
-       if (regdomain == 0) {
-               regdomain = mac->default_regdomain;
-       }
-       if (!zd_regdomain_supported(regdomain)) {
-               spin_unlock_irq(&mac->lock);
-               return -EINVAL;
-       }
-       mac->regdomain = regdomain;
-       channel = mac->requested_channel;
-       spin_unlock_irq(&mac->lock);
-
-       r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain);
-       if (r)
-               return r;
-       if (!zd_regdomain_supports_channel(regdomain, channel)) {
-               r = reset_channel(mac);
-               if (r)
-                       return r;
-       }
+/**
+ * init_tx_skb_control_block - initializes skb control block
+ * @skb: a &sk_buff pointer
+ * @dev: pointer to the mac80221 device
+ * @control: mac80211 tx control applying for the frame in @skb
+ *
+ * Initializes the control block of the skbuff to be transmitted.
+ */
+static int init_tx_skb_control_block(struct sk_buff *skb,
+                                    struct ieee80211_hw *hw,
+                                    struct ieee80211_tx_control *control)
+{
+       struct zd_tx_skb_control_block *cb =
+               (struct zd_tx_skb_control_block *)skb->cb;
+
+       ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb));
+       memset(cb, 0, sizeof(*cb));
+       cb->hw= hw;
+       cb->control = kmalloc(sizeof(*control), GFP_ATOMIC);
+       if (cb->control == NULL)
+               return -ENOMEM;
+       memcpy(cb->control, control, sizeof(*control));
 
        return 0;
 }
 
-u8 zd_mac_get_regdomain(struct zd_mac *mac)
-{
-       unsigned long flags;
-       u8 regdomain;
-
-       spin_lock_irqsave(&mac->lock, flags);
-       regdomain = mac->regdomain;
-       spin_unlock_irqrestore(&mac->lock, flags);
-       return regdomain;
-}
-
-/* Fallback to lowest rate, if rate is unknown. */
-static u8 rate_to_zd_rate(u8 rate)
-{
-       switch (rate) {
-       case IEEE80211_CCK_RATE_2MB:
-               return ZD_CCK_RATE_2M;
-       case IEEE80211_CCK_RATE_5MB:
-               return ZD_CCK_RATE_5_5M;
-       case IEEE80211_CCK_RATE_11MB:
-               return ZD_CCK_RATE_11M;
-       case IEEE80211_OFDM_RATE_6MB:
-               return ZD_OFDM_RATE_6M;
-       case IEEE80211_OFDM_RATE_9MB:
-               return ZD_OFDM_RATE_9M;
-       case IEEE80211_OFDM_RATE_12MB:
-               return ZD_OFDM_RATE_12M;
-       case IEEE80211_OFDM_RATE_18MB:
-               return ZD_OFDM_RATE_18M;
-       case IEEE80211_OFDM_RATE_24MB:
-               return ZD_OFDM_RATE_24M;
-       case IEEE80211_OFDM_RATE_36MB:
-               return ZD_OFDM_RATE_36M;
-       case IEEE80211_OFDM_RATE_48MB:
-               return ZD_OFDM_RATE_48M;
-       case IEEE80211_OFDM_RATE_54MB:
-               return ZD_OFDM_RATE_54M;
-       }
-       return ZD_CCK_RATE_1M;
-}
-
-static u16 rate_to_cr_rate(u8 rate)
-{
-       switch (rate) {
-       case IEEE80211_CCK_RATE_2MB:
-               return CR_RATE_1M;
-       case IEEE80211_CCK_RATE_5MB:
-               return CR_RATE_5_5M;
-       case IEEE80211_CCK_RATE_11MB:
-               return CR_RATE_11M;
-       case IEEE80211_OFDM_RATE_6MB:
-               return CR_RATE_6M;
-       case IEEE80211_OFDM_RATE_9MB:
-               return CR_RATE_9M;
-       case IEEE80211_OFDM_RATE_12MB:
-               return CR_RATE_12M;
-       case IEEE80211_OFDM_RATE_18MB:
-               return CR_RATE_18M;
-       case IEEE80211_OFDM_RATE_24MB:
-               return CR_RATE_24M;
-       case IEEE80211_OFDM_RATE_36MB:
-               return CR_RATE_36M;
-       case IEEE80211_OFDM_RATE_48MB:
-               return CR_RATE_48M;
-       case IEEE80211_OFDM_RATE_54MB:
-               return CR_RATE_54M;
-       }
-       return CR_RATE_1M;
-}
-
-static void try_enable_tx(struct zd_mac *mac)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&mac->lock, flags);
-       if (mac->updating_rts_rate == 0 && mac->updating_basic_rates == 0)
-               netif_wake_queue(mac->netdev);
-       spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-static void set_rts_cts_work(struct work_struct *work)
+/**
+ * tx_status - reports tx status of a packet if required
+ * @hw - a &struct ieee80211_hw pointer
+ * @skb - a sk-buffer
+ * @status - the tx status of the packet without control information
+ * @success - True for successfull transmission of the frame
+ *
+ * This information calls ieee80211_tx_status_irqsafe() if required by the
+ * control information. It copies the control information into the status
+ * information.
+ *
+ * If no status information has been requested, the skb is freed.
+ */
+static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
+                     struct ieee80211_tx_status *status,
+                     bool success)
 {
-       struct zd_mac *mac =
-               container_of(work, struct zd_mac, set_rts_cts_work.work);
-       unsigned long flags;
-       u8 rts_rate;
-       unsigned int short_preamble;
-
-       mutex_lock(&mac->chip.mutex);
-
-       spin_lock_irqsave(&mac->lock, flags);
-       mac->updating_rts_rate = 0;
-       rts_rate = mac->rts_rate;
-       short_preamble = mac->short_preamble;
-       spin_unlock_irqrestore(&mac->lock, flags);
-
-       zd_chip_set_rts_cts_rate_locked(&mac->chip, rts_rate, short_preamble);
-       mutex_unlock(&mac->chip.mutex);
+       struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *)
+               skb->cb;
 
-       try_enable_tx(mac);
+       ZD_ASSERT(cb->control != NULL);
+       memcpy(&status->control, cb->control, sizeof(status->control));
+       if (!success)
+               status->excessive_retries = 1;
+       clear_tx_skb_control_block(skb);
+       ieee80211_tx_status_irqsafe(hw, skb, status);
 }
 
-static void set_basic_rates_work(struct work_struct *work)
+/**
+ * zd_mac_tx_failed - callback for failed frames
+ * @dev: the mac80211 wireless device
+ *
+ * This function is called if a frame couldn't be succesfully be
+ * transferred. The first frame from the tx queue, will be selected and
+ * reported as error to the upper layers.
+ */
+void zd_mac_tx_failed(struct ieee80211_hw *hw)
 {
-       struct zd_mac *mac =
-               container_of(work, struct zd_mac, set_basic_rates_work.work);
-       unsigned long flags;
-       u16 basic_rates;
-
-       mutex_lock(&mac->chip.mutex);
-
-       spin_lock_irqsave(&mac->lock, flags);
-       mac->updating_basic_rates = 0;
-       basic_rates = mac->basic_rates;
-       spin_unlock_irqrestore(&mac->lock, flags);
-
-       zd_chip_set_basic_rates_locked(&mac->chip, basic_rates);
-       mutex_unlock(&mac->chip.mutex);
+       struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
+       struct sk_buff *skb;
+       struct ieee80211_tx_status status = {{0}};
 
-       try_enable_tx(mac);
+       skb = skb_dequeue(q);
+       if (skb == NULL)
+               return;
+       tx_status(hw, skb, &status, 0);
 }
 
-static void bssinfo_change(struct net_device *netdev, u32 changes)
-{
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct ieee80211softmac_device *softmac = ieee80211_priv(netdev);
-       struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo;
-       int need_set_rts_cts = 0;
-       int need_set_rates = 0;
-       u16 basic_rates;
-       unsigned long flags;
-
-       dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
-
-       if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) {
-               spin_lock_irqsave(&mac->lock, flags);
-               mac->short_preamble = bssinfo->short_preamble;
-               spin_unlock_irqrestore(&mac->lock, flags);
-               need_set_rts_cts = 1;
-       }
-
-       if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) {
-               /* Set RTS rate to highest available basic rate */
-               u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac,
-                       &bssinfo->supported_rates, 1);
-               hi_rate = rate_to_zd_rate(hi_rate);
-
-               spin_lock_irqsave(&mac->lock, flags);
-               if (hi_rate != mac->rts_rate) {
-                       mac->rts_rate = hi_rate;
-                       need_set_rts_cts = 1;
-               }
-               spin_unlock_irqrestore(&mac->lock, flags);
-
-               /* Set basic rates */
-               need_set_rates = 1;
-               if (bssinfo->supported_rates.count == 0) {
-                       /* Allow the device to be flexible */
-                       basic_rates = CR_RATES_80211B | CR_RATES_80211G;
+/**
+ * zd_mac_tx_to_dev - callback for USB layer
+ * @skb: a &sk_buff pointer
+ * @error: error value, 0 if transmission successful
+ *
+ * Informs the MAC layer that the frame has successfully transferred to the
+ * device. If an ACK is required and the transfer to the device has been
+ * successful, the packets are put on the @ack_wait_queue with
+ * the control set removed.
+ */
+void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
+{
+       struct zd_tx_skb_control_block *cb =
+               (struct zd_tx_skb_control_block *)skb->cb;
+       struct ieee80211_hw *hw = cb->hw;
+
+       if (likely(cb->control)) {
+               skb_pull(skb, sizeof(struct zd_ctrlset));
+               if (unlikely(error ||
+                   (cb->control->flags & IEEE80211_TXCTL_NO_ACK)))
+               {
+                       struct ieee80211_tx_status status = {{0}};
+                       tx_status(hw, skb, &status, !error);
                } else {
-                       int i = 0;
-                       basic_rates = 0;
-
-                       for (i = 0; i < bssinfo->supported_rates.count; i++) {
-                               u16 rate = bssinfo->supported_rates.rates[i];
-                               if ((rate & IEEE80211_BASIC_RATE_MASK) == 0)
-                                       continue;
+                       struct sk_buff_head *q =
+                               &zd_hw_mac(hw)->ack_wait_queue;
 
-                               rate &= ~IEEE80211_BASIC_RATE_MASK;
-                               basic_rates |= rate_to_cr_rate(rate);
-                       }
+                       skb_queue_tail(q, skb);
+                       while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
+                               zd_mac_tx_failed(hw);
                }
-               spin_lock_irqsave(&mac->lock, flags);
-               mac->basic_rates = basic_rates;
-               spin_unlock_irqrestore(&mac->lock, flags);
-       }
-
-       /* Schedule any changes we made above */
-
-       spin_lock_irqsave(&mac->lock, flags);
-       if (need_set_rts_cts && !mac->updating_rts_rate) {
-               mac->updating_rts_rate = 1;
-               netif_stop_queue(mac->netdev);
-               queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0);
-       }
-       if (need_set_rates && !mac->updating_basic_rates) {
-               mac->updating_basic_rates = 1;
-               netif_stop_queue(mac->netdev);
-               queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work,
-                                  0);
-       }
-       spin_unlock_irqrestore(&mac->lock, flags);
-}
-
-static void set_channel(struct net_device *netdev, u8 channel)
-{
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-
-       dev_dbg_f(zd_mac_dev(mac), "channel %d\n", channel);
-
-       zd_chip_set_channel(&mac->chip, channel);
-}
-
-int zd_mac_request_channel(struct zd_mac *mac, u8 channel)
-{
-       unsigned long lock_flags;
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-
-       if (ieee->iw_mode == IW_MODE_INFRA)
-               return -EPERM;
-
-       spin_lock_irqsave(&mac->lock, lock_flags);
-       if (!zd_regdomain_supports_channel(mac->regdomain, channel)) {
-               spin_unlock_irqrestore(&mac->lock, lock_flags);
-               return -EINVAL;
-       }
-       mac->requested_channel = channel;
-       spin_unlock_irqrestore(&mac->lock, lock_flags);
-       if (netif_running(mac->netdev))
-               return zd_chip_set_channel(&mac->chip, channel);
-       else
-               return 0;
-}
-
-u8 zd_mac_get_channel(struct zd_mac *mac)
-{
-       u8 channel = zd_chip_get_channel(&mac->chip);
-
-       dev_dbg_f(zd_mac_dev(mac), "channel %u\n", channel);
-       return channel;
-}
-
-int zd_mac_set_mode(struct zd_mac *mac, u32 mode)
-{
-       struct ieee80211_device *ieee;
-
-       switch (mode) {
-       case IW_MODE_AUTO:
-       case IW_MODE_ADHOC:
-       case IW_MODE_INFRA:
-               mac->netdev->type = ARPHRD_ETHER;
-               break;
-       case IW_MODE_MONITOR:
-               mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
-               break;
-       default:
-               dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode);
-               return -EINVAL;
-       }
-
-       ieee = zd_mac_to_ieee80211(mac);
-       ZD_ASSERT(!irqs_disabled());
-       spin_lock_irq(&ieee->lock);
-       ieee->iw_mode = mode;
-       spin_unlock_irq(&ieee->lock);
-
-       if (netif_running(mac->netdev)) {
-               int r = set_rx_filter(mac);
-               if (r)
-                       return r;
-               return set_sniffer(mac);
-       }
-
-       return 0;
-}
-
-int zd_mac_get_mode(struct zd_mac *mac, u32 *mode)
-{
-       unsigned long flags;
-       struct ieee80211_device *ieee;
-
-       ieee = zd_mac_to_ieee80211(mac);
-       spin_lock_irqsave(&ieee->lock, flags);
-       *mode = ieee->iw_mode;
-       spin_unlock_irqrestore(&ieee->lock, flags);
-       return 0;
-}
-
-int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range)
-{
-       int i;
-       const struct channel_range *channel_range;
-       u8 regdomain;
-
-       memset(range, 0, sizeof(*range));
-
-       /* FIXME: Not so important and depends on the mode. For 802.11g
-        * usually this value is used. It seems to be that Bit/s number is
-        * given here.
-        */
-       range->throughput = 27 * 1000 * 1000;
-
-       range->max_qual.qual = 100;
-       range->max_qual.level = 100;
-
-       /* FIXME: Needs still to be tuned. */
-       range->avg_qual.qual = 71;
-       range->avg_qual.level = 80;
-
-       /* FIXME: depends on standard? */
-       range->min_rts = 256;
-       range->max_rts = 2346;
-
-       range->min_frag = MIN_FRAG_THRESHOLD;
-       range->max_frag = MAX_FRAG_THRESHOLD;
-
-       range->max_encoding_tokens = WEP_KEYS;
-       range->num_encoding_sizes = 2;
-       range->encoding_size[0] = 5;
-       range->encoding_size[1] = WEP_KEY_LEN;
-
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = 20;
-
-       range->enc_capa = IW_ENC_CAPA_WPA |  IW_ENC_CAPA_WPA2 |
-                         IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
-       ZD_ASSERT(!irqs_disabled());
-       spin_lock_irq(&mac->lock);
-       regdomain = mac->regdomain;
-       spin_unlock_irq(&mac->lock);
-       channel_range = zd_channel_range(regdomain);
-
-       range->num_channels = channel_range->end - channel_range->start;
-       range->old_num_channels = range->num_channels;
-       range->num_frequency = range->num_channels;
-       range->old_num_frequency = range->num_frequency;
-
-       for (i = 0; i < range->num_frequency; i++) {
-               struct iw_freq *freq = &range->freq[i];
-               freq->i = channel_range->start + i;
-               zd_channel_to_freq(freq, freq->i);
+       } else {
+               kfree_tx_skb(skb);
        }
-
-       return 0;
 }
 
 static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
 {
        /* ZD_PURE_RATE() must be used to remove the modulation type flag of
-        * the zd-rate values. */
+        * the zd-rate values.
+        */
        static const u8 rate_divisor[] = {
-               [ZD_PURE_RATE(ZD_CCK_RATE_1M)]          =  1,
-               [ZD_PURE_RATE(ZD_CCK_RATE_2M)]          =  2,
-
-               /* bits must be doubled */
-               [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)]        = 11,
-
-               [ZD_PURE_RATE(ZD_CCK_RATE_11M)]         = 11,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_6M)]         =  6,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_9M)]         =  9,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_12M)]        = 12,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_18M)]        = 18,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_24M)]        = 24,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_36M)]        = 36,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_48M)]        = 48,
-               [ZD_PURE_RATE(ZD_OFDM_RATE_54M)]        = 54,
+               [ZD_PURE_RATE(ZD_CCK_RATE_1M)]   =  1,
+               [ZD_PURE_RATE(ZD_CCK_RATE_2M)]   =  2,
+               /* Bits must be doubled. */
+               [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11,
+               [ZD_PURE_RATE(ZD_CCK_RATE_11M)]  = 11,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_6M)]  =  6,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_9M)]  =  9,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48,
+               [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54,
        };
 
        u32 bits = (u32)tx_length * 8;
@@ -764,34 +451,10 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
        return bits/divisor;
 }
 
-static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs,
-                             struct ieee80211_hdr_4addr *hdr)
-{
-       struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
-       u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl));
-       u8 rate;
-       int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0;
-       int is_multicast = is_multicast_ether_addr(hdr->addr1);
-       int short_preamble = ieee80211softmac_short_preamble_ok(softmac,
-               is_multicast, is_mgt);
-
-       rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt);
-       cs->modulation = rate_to_zd_rate(rate);
-
-       /* Set short preamble bit when appropriate */
-       if (short_preamble && ZD_MODULATION_TYPE(cs->modulation) == ZD_CCK
-           && cs->modulation != ZD_CCK_RATE_1M)
-               cs->modulation |= ZD_CCK_PREA_SHORT;
-}
-
 static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
-                          struct ieee80211_hdr_4addr *header)
+                          struct ieee80211_hdr *header, u32 flags)
 {
-       struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev);
-       unsigned int tx_length = le16_to_cpu(cs->tx_length);
-       u16 fctl = le16_to_cpu(header->frame_ctl);
-       u16 ftype = WLAN_FC_GET_TYPE(fctl);
-       u16 stype = WLAN_FC_GET_STYPE(fctl);
+       u16 fctl = le16_to_cpu(header->frame_control);
 
        /*
         * CONTROL TODO:
@@ -802,7 +465,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
        cs->control = 0;
 
        /* First fragment */
-       if (WLAN_GET_SEQ_FRAG(le16_to_cpu(header->seq_ctl)) == 0)
+       if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT)
                cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
 
        /* Multicast */
@@ -810,54 +473,37 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
                cs->control |= ZD_CS_MULTICAST;
 
        /* PS-POLL */
-       if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL)
+       if ((fctl & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) ==
+           (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL))
                cs->control |= ZD_CS_PS_POLL_FRAME;
 
-       /* Unicast data frames over the threshold should have RTS */
-       if (!is_multicast_ether_addr(header->addr1) &&
-               ftype != IEEE80211_FTYPE_MGMT &&
-                   tx_length > zd_netdev_ieee80211(mac->netdev)->rts)
+       if (flags & IEEE80211_TXCTL_USE_RTS_CTS)
                cs->control |= ZD_CS_RTS;
 
-       /* Use CTS-to-self protection if required */
-       if (ZD_MODULATION_TYPE(cs->modulation) == ZD_OFDM &&
-                       ieee80211softmac_protection_needed(softmac)) {
-               /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */
-               cs->control &= ~ZD_CS_RTS;
+       if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
                cs->control |= ZD_CS_SELF_CTS;
-       }
 
        /* FIXME: Management frame? */
 }
 
 static int fill_ctrlset(struct zd_mac *mac,
-                       struct ieee80211_txb *txb,
-                       int frag_num)
+                       struct sk_buff *skb,
+                       struct ieee80211_tx_control *control)
 {
        int r;
-       struct sk_buff *skb = txb->fragments[frag_num];
-       struct ieee80211_hdr_4addr *hdr =
-               (struct ieee80211_hdr_4addr *) skb->data;
-       unsigned int frag_len = skb->len + IEEE80211_FCS_LEN;
-       unsigned int next_frag_len;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       unsigned int frag_len = skb->len + FCS_LEN;
        unsigned int packet_length;
        struct zd_ctrlset *cs = (struct zd_ctrlset *)
                skb_push(skb, sizeof(struct zd_ctrlset));
 
-       if (frag_num+1  < txb->nr_frags) {
-               next_frag_len = txb->fragments[frag_num+1]->len +
-                               IEEE80211_FCS_LEN;
-       } else {
-               next_frag_len = 0;
-       }
        ZD_ASSERT(frag_len <= 0xffff);
-       ZD_ASSERT(next_frag_len <= 0xffff);
 
-       cs_set_modulation(mac, cs, hdr);
+       cs->modulation = control->tx_rate;
 
        cs->tx_length = cpu_to_le16(frag_len);
 
-       cs_set_control(mac, cs, hdr);
+       cs_set_control(mac, cs, hdr, control->flags);
 
        packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
        ZD_ASSERT(packet_length <= 0xffff);
@@ -886,419 +532,417 @@ static int fill_ctrlset(struct zd_mac *mac,
        if (r < 0)
                return r;
        cs->current_length = cpu_to_le16(r);
-
-       if (next_frag_len == 0) {
-               cs->next_frame_length = 0;
-       } else {
-               r = zd_calc_tx_length_us(NULL, ZD_RATE(cs->modulation),
-                                        next_frag_len);
-               if (r < 0)
-                       return r;
-               cs->next_frame_length = cpu_to_le16(r);
-       }
+       cs->next_frame_length = 0;
 
        return 0;
 }
 
-static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
+/**
+ * zd_op_tx - transmits a network frame to the device
+ *
+ * @dev: mac80211 hardware device
+ * @skb: socket buffer
+ * @control: the control structure
+ *
+ * This function transmit an IEEE 802.11 network frame to the device. The
+ * control block of the skbuff will be initialized. If necessary the incoming
+ * mac80211 queues will be stopped.
+ */
+static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+                    struct ieee80211_tx_control *control)
 {
-       int i, r;
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+       struct zd_mac *mac = zd_hw_mac(hw);
+       int r;
 
-       for (i = 0; i < txb->nr_frags; i++) {
-               struct sk_buff *skb = txb->fragments[i];
+       r = fill_ctrlset(mac, skb, control);
+       if (r)
+               return r;
 
-               r = fill_ctrlset(mac, txb, i);
-               if (r) {
-                       ieee->stats.tx_dropped++;
-                       return r;
-               }
-               r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
-               if (r) {
-                       ieee->stats.tx_dropped++;
-                       return r;
-               }
+       r = init_tx_skb_control_block(skb, hw, control);
+       if (r)
+               return r;
+       r = zd_usb_tx(&mac->chip.usb, skb);
+       if (r) {
+               clear_tx_skb_control_block(skb);
+               return r;
        }
-
-       /* FIXME: shouldn't this be handled by the upper layers? */
-       mac->netdev->trans_start = jiffies;
-
-       ieee80211_txb_free(txb);
        return 0;
 }
 
-struct zd_rt_hdr {
-       struct ieee80211_radiotap_header rt_hdr;
-       u8  rt_flags;
-       u8  rt_rate;
-       u16 rt_channel;
-       u16 rt_chbitmask;
-} __attribute__((packed));
-
-static void fill_rt_header(void *buffer, struct zd_mac *mac,
-                          const struct ieee80211_rx_stats *stats,
-                          const struct rx_status *status)
-{
-       struct zd_rt_hdr *hdr = buffer;
-
-       hdr->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
-       hdr->rt_hdr.it_pad = 0;
-       hdr->rt_hdr.it_len = cpu_to_le16(sizeof(struct zd_rt_hdr));
-       hdr->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
-                                (1 << IEEE80211_RADIOTAP_CHANNEL) |
-                                (1 << IEEE80211_RADIOTAP_RATE));
-
-       hdr->rt_flags = 0;
-       if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256))
-               hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP;
-
-       hdr->rt_rate = stats->rate / 5;
-
-       /* FIXME: 802.11a */
-       hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz(
-                                            _zd_chip_get_channel(&mac->chip)));
-       hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ |
-               ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) ==
-               ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK));
-}
-
-/* Returns 1 if the data packet is for us and 0 otherwise. */
-static int is_data_packet_for_us(struct ieee80211_device *ieee,
-                                struct ieee80211_hdr_4addr *hdr)
-{
-       struct net_device *netdev = ieee->dev;
-       u16 fc = le16_to_cpu(hdr->frame_ctl);
-
-       ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA);
-
-       switch (ieee->iw_mode) {
-       case IW_MODE_ADHOC:
-               if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 ||
-                   compare_ether_addr(hdr->addr3, ieee->bssid) != 0)
-                       return 0;
-               break;
-       case IW_MODE_AUTO:
-       case IW_MODE_INFRA:
-               if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) !=
-                   IEEE80211_FCTL_FROMDS ||
-                   compare_ether_addr(hdr->addr2, ieee->bssid) != 0)
-                       return 0;
-               break;
-       default:
-               ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR);
-               return 0;
-       }
-
-       return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 ||
-              (is_multicast_ether_addr(hdr->addr1) &&
-               compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) ||
-              (netdev->flags & IFF_PROMISC);
-}
-
-/* Filters received packets. The function returns 1 if the packet should be
- * forwarded to ieee80211_rx(). If the packet should be ignored the function
- * returns 0. If an invalid packet is found the function returns -EINVAL.
+/**
+ * filter_ack - filters incoming packets for acknowledgements
+ * @dev: the mac80211 device
+ * @rx_hdr: received header
+ * @stats: the status for the received packet
  *
- * The function calls ieee80211_rx_mgt() directly.
+ * This functions looks for ACK packets and tries to match them with the
+ * frames in the tx queue. If a match is found the frame will be dequeued and
+ * the upper layers is informed about the successful transmission. If
+ * mac80211 queues have been stopped and the number of frames still to be
+ * transmitted is low the queues will be opened again.
  *
- * It has been based on ieee80211_rx_any.
+ * Returns 1 if the frame was an ACK, 0 if it was ignored.
  */
-static int filter_rx(struct ieee80211_device *ieee,
-                    const u8 *buffer, unsigned int length,
-                    struct ieee80211_rx_stats *stats)
+static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
+                     struct ieee80211_rx_status *stats)
 {
-       struct ieee80211_hdr_4addr *hdr;
-       u16 fc;
-
-       if (ieee->iw_mode == IW_MODE_MONITOR)
-               return 1;
-
-       hdr = (struct ieee80211_hdr_4addr *)buffer;
-       fc = le16_to_cpu(hdr->frame_ctl);
-       if ((fc & IEEE80211_FCTL_VERS) != 0)
-               return -EINVAL;
+       u16 fc = le16_to_cpu(rx_hdr->frame_control);
+       struct sk_buff *skb;
+       struct sk_buff_head *q;
+       unsigned long flags;
 
-       switch (WLAN_FC_GET_TYPE(fc)) {
-       case IEEE80211_FTYPE_MGMT:
-               if (length < sizeof(struct ieee80211_hdr_3addr))
-                       return -EINVAL;
-               ieee80211_rx_mgt(ieee, hdr, stats);
-               return 0;
-       case IEEE80211_FTYPE_CTL:
+       if ((fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) !=
+           (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK))
                return 0;
-       case IEEE80211_FTYPE_DATA:
-               /* Ignore invalid short buffers */
-               if (length < sizeof(struct ieee80211_hdr_3addr))
-                       return -EINVAL;
-               return is_data_packet_for_us(ieee, hdr);
-       }
 
-       return -EINVAL;
+       q = &zd_hw_mac(hw)->ack_wait_queue;
+       spin_lock_irqsave(&q->lock, flags);
+       for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) {
+               struct ieee80211_hdr *tx_hdr;
+
+               tx_hdr = (struct ieee80211_hdr *)skb->data;
+               if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1)))
+               {
+                       struct ieee80211_tx_status status = {{0}};
+                       status.flags = IEEE80211_TX_STATUS_ACK;
+                       status.ack_signal = stats->ssi;
+                       __skb_unlink(skb, q);
+                       tx_status(hw, skb, &status, 1);
+                       goto out;
+               }
+       }
+out:
+       spin_unlock_irqrestore(&q->lock, flags);
+       return 1;
 }
 
-static void update_qual_rssi(struct zd_mac *mac,
-                            const u8 *buffer, unsigned int length,
-                            u8 qual_percent, u8 rssi_percent)
+int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
 {
-       unsigned long flags;
-       struct ieee80211_hdr_3addr *hdr;
-       int i;
+       struct zd_mac *mac = zd_hw_mac(hw);
+       struct ieee80211_rx_status stats;
+       const struct rx_status *status;
+       struct sk_buff *skb;
+       int bad_frame = 0;
+       u16 fc;
+       bool is_qos, is_4addr, need_padding;
 
-       hdr = (struct ieee80211_hdr_3addr *)buffer;
-       if (length < offsetof(struct ieee80211_hdr_3addr, addr3))
-               return;
-       if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0)
-               return;
+       if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
+                    FCS_LEN + sizeof(struct rx_status))
+               return -EINVAL;
 
-       spin_lock_irqsave(&mac->lock, flags);
-       i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE;
-       mac->qual_buffer[i] = qual_percent;
-       mac->rssi_buffer[i] = rssi_percent;
-       mac->stats_count++;
-       spin_unlock_irqrestore(&mac->lock, flags);
-}
+       memset(&stats, 0, sizeof(stats));
 
-static int fill_rx_stats(struct ieee80211_rx_stats *stats,
-                        const struct rx_status **pstatus,
-                        struct zd_mac *mac,
-                        const u8 *buffer, unsigned int length)
-{
-       const struct rx_status *status;
+       /* Note about pass_failed_fcs and pass_ctrl access below:
+        * mac locking intentionally omitted here, as this is the only unlocked
+        * reader and the only writer is configure_filter. Plus, if there were
+        * any races accessing these variables, it wouldn't really matter.
+        * If mac80211 ever provides a way for us to access filter flags
+        * from outside configure_filter, we could improve on this. Also, this
+        * situation may change once we implement some kind of DMA-into-skb
+        * RX path. */
 
-       *pstatus = status = (struct rx_status *)
+       /* Caller has to ensure that length >= sizeof(struct rx_status). */
+       status = (struct rx_status *)
                (buffer + (length - sizeof(struct rx_status)));
        if (status->frame_status & ZD_RX_ERROR) {
-               struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-               ieee->stats.rx_errors++;
-               if (status->frame_status & ZD_RX_TIMEOUT_ERROR)
-                       ieee->stats.rx_missed_errors++;
-               else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR)
-                       ieee->stats.rx_fifo_errors++;
-               else if (status->frame_status & ZD_RX_DECRYPTION_ERROR)
-                       ieee->ieee_stats.rx_discards_undecryptable++;
-               else if (status->frame_status & ZD_RX_CRC32_ERROR) {
-                       ieee->stats.rx_crc_errors++;
-                       ieee->ieee_stats.rx_fcs_errors++;
+               if (mac->pass_failed_fcs &&
+                               (status->frame_status & ZD_RX_CRC32_ERROR)) {
+                       stats.flag |= RX_FLAG_FAILED_FCS_CRC;
+                       bad_frame = 1;
+               } else {
+                       return -EINVAL;
                }
-               else if (status->frame_status & ZD_RX_CRC16_ERROR)
-                       ieee->stats.rx_crc_errors++;
-               return -EINVAL;
        }
 
-       memset(stats, 0, sizeof(struct ieee80211_rx_stats));
-       stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
-                              + sizeof(struct rx_status));
-       /* FIXME: 802.11a */
-       stats->freq = IEEE80211_24GHZ_BAND;
-       stats->received_channel = _zd_chip_get_channel(&mac->chip);
-       stats->rssi = zd_rx_strength_percent(status->signal_strength);
-       stats->signal = zd_rx_qual_percent(buffer,
+       stats.channel = _zd_chip_get_channel(&mac->chip);
+       stats.freq = zd_channels[stats.channel - 1].freq;
+       stats.phymode = MODE_IEEE80211G;
+       stats.ssi = status->signal_strength;
+       stats.signal = zd_rx_qual_percent(buffer,
                                          length - sizeof(struct rx_status),
                                          status);
-       stats->mask = IEEE80211_STATMASK_RSSI | IEEE80211_STATMASK_SIGNAL;
-       stats->rate = zd_rx_rate(buffer, status);
-       if (stats->rate)
-               stats->mask |= IEEE80211_STATMASK_RATE;
+       stats.rate = zd_rx_rate(buffer, status);
+
+       length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status);
+       buffer += ZD_PLCP_HEADER_SIZE;
+
+       /* Except for bad frames, filter each frame to see if it is an ACK, in
+        * which case our internal TX tracking is updated. Normally we then
+        * bail here as there's no need to pass ACKs on up to the stack, but
+        * there is also the case where the stack has requested us to pass
+        * control frames on up (pass_ctrl) which we must consider. */
+       if (!bad_frame &&
+                       filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats)
+                       && !mac->pass_ctrl)
+               return 0;
 
-       return 0;
-}
+       fc = le16_to_cpu(*((__le16 *) buffer));
 
-static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
-{
-       int r;
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-       struct ieee80211_rx_stats stats;
-       const struct rx_status *status;
+       is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
+                ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
+       is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
+                  (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS);
+       need_padding = is_qos ^ is_4addr;
 
-       if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
-                      IEEE80211_FCS_LEN + sizeof(struct rx_status))
-       {
-               ieee->stats.rx_errors++;
-               ieee->stats.rx_length_errors++;
-               goto free_skb;
+       skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
+       if (skb == NULL)
+               return -ENOMEM;
+       if (need_padding) {
+               /* Make sure the the payload data is 4 byte aligned. */
+               skb_reserve(skb, 2);
        }
 
-       r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len);
-       if (r) {
-               /* Only packets with rx errors are included here.
-                * The error stats have already been set in fill_rx_stats.
-                */
-               goto free_skb;
-       }
+       memcpy(skb_put(skb, length), buffer, length);
 
-       __skb_pull(skb, ZD_PLCP_HEADER_SIZE);
-       __skb_trim(skb, skb->len -
-                       (IEEE80211_FCS_LEN + sizeof(struct rx_status)));
+       ieee80211_rx_irqsafe(hw, skb, &stats);
+       return 0;
+}
 
-       ZD_ASSERT(IS_ALIGNED((unsigned long)skb->data, 4));
+static int zd_op_add_interface(struct ieee80211_hw *hw,
+                               struct ieee80211_if_init_conf *conf)
+{
+       struct zd_mac *mac = zd_hw_mac(hw);
 
-       update_qual_rssi(mac, skb->data, skb->len, stats.signal,
-                        status->signal_strength);
+       /* using IEEE80211_IF_TYPE_INVALID to indicate no mode selected */
+       if (mac->type != IEEE80211_IF_TYPE_INVALID)
+               return -EOPNOTSUPP;
 
-       r = filter_rx(ieee, skb->data, skb->len, &stats);
-       if (r <= 0) {
-               if (r < 0) {
-                       ieee->stats.rx_errors++;
-                       dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
-               }
-               goto free_skb;
+       switch (conf->type) {
+       case IEEE80211_IF_TYPE_MNTR:
+       case IEEE80211_IF_TYPE_STA:
+               mac->type = conf->type;
+               break;
+       default:
+               return -EOPNOTSUPP;
        }
 
-       if (ieee->iw_mode == IW_MODE_MONITOR)
-               fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac,
-                              &stats, status);
-
-       r = ieee80211_rx(ieee, skb, &stats);
-       if (r)
-               return;
-free_skb:
-       /* We are always in a soft irq. */
-       dev_kfree_skb(skb);
+       return zd_write_mac_addr(&mac->chip, conf->mac_addr);
 }
 
-static void do_rx(unsigned long mac_ptr)
+static void zd_op_remove_interface(struct ieee80211_hw *hw,
+                                   struct ieee80211_if_init_conf *conf)
 {
-       struct zd_mac *mac = (struct zd_mac *)mac_ptr;
-       struct sk_buff *skb;
+       struct zd_mac *mac = zd_hw_mac(hw);
+       mac->type = IEEE80211_IF_TYPE_INVALID;
+       zd_write_mac_addr(&mac->chip, NULL);
+}
 
-       while ((skb = skb_dequeue(&mac->rx_queue)) != NULL)
-               zd_mac_rx(mac, skb);
+static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+{
+       struct zd_mac *mac = zd_hw_mac(hw);
+       return zd_chip_set_channel(&mac->chip, conf->channel);
 }
 
-int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length)
+static int zd_op_config_interface(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+                                  struct ieee80211_if_conf *conf)
 {
-       struct sk_buff *skb;
-       unsigned int reserved =
-               ALIGN(max_t(unsigned int,
-                           sizeof(struct zd_rt_hdr), ZD_PLCP_HEADER_SIZE), 4) -
-               ZD_PLCP_HEADER_SIZE;
-
-       skb = dev_alloc_skb(reserved + length);
-       if (!skb) {
-               struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-               dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
-               ieee->stats.rx_dropped++;
-               return -ENOMEM;
-       }
-       skb_reserve(skb, reserved);
-       memcpy(__skb_put(skb, length), buffer, length);
-       skb_queue_tail(&mac->rx_queue, skb);
-       tasklet_schedule(&mac->rx_tasklet);
+       struct zd_mac *mac = zd_hw_mac(hw);
+
+       spin_lock_irq(&mac->lock);
+       mac->associated = is_valid_ether_addr(conf->bssid);
+       spin_unlock_irq(&mac->lock);
+
+       /* TODO: do hardware bssid filtering */
        return 0;
 }
 
-static int netdev_tx(struct ieee80211_txb *txb, struct net_device *netdev,
-                    int pri)
+static void set_multicast_hash_handler(struct work_struct *work)
 {
-       return zd_mac_tx(zd_netdev_mac(netdev), txb, pri);
+       struct zd_mac *mac =
+               container_of(work, struct zd_mac, set_multicast_hash_work);
+       struct zd_mc_hash hash;
+
+       spin_lock_irq(&mac->lock);
+       hash = mac->multicast_hash;
+       spin_unlock_irq(&mac->lock);
+
+       zd_chip_set_multicast_hash(&mac->chip, &hash);
 }
 
-static void set_security(struct net_device *netdev,
-                        struct ieee80211_security *sec)
+static void set_rx_filter_handler(struct work_struct *work)
 {
-       struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev);
-       struct ieee80211_security *secinfo = &ieee->sec;
-       int keyidx;
-
-       dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
-
-       for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
-               if (sec->flags & (1<<keyidx)) {
-                       secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx];
-                       secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx];
-                       memcpy(secinfo->keys[keyidx], sec->keys[keyidx],
-                              SCM_KEY_LEN);
-               }
+       struct zd_mac *mac =
+               container_of(work, struct zd_mac, set_rx_filter_work);
+       int r;
 
-       if (sec->flags & SEC_ACTIVE_KEY) {
-               secinfo->active_key = sec->active_key;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .active_key = %d\n", sec->active_key);
-       }
-       if (sec->flags & SEC_UNICAST_GROUP) {
-               secinfo->unicast_uses_group = sec->unicast_uses_group;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .unicast_uses_group = %d\n",
-                       sec->unicast_uses_group);
-       }
-       if (sec->flags & SEC_LEVEL) {
-               secinfo->level = sec->level;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .level = %d\n", sec->level);
-       }
-       if (sec->flags & SEC_ENABLED) {
-               secinfo->enabled = sec->enabled;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .enabled = %d\n", sec->enabled);
-       }
-       if (sec->flags & SEC_ENCRYPT) {
-               secinfo->encrypt = sec->encrypt;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .encrypt = %d\n", sec->encrypt);
-       }
-       if (sec->flags & SEC_AUTH_MODE) {
-               secinfo->auth_mode = sec->auth_mode;
-               dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)),
-                       "   .auth_mode = %d\n", sec->auth_mode);
+       dev_dbg_f(zd_mac_dev(mac), "\n");
+       r = set_rx_filter(mac);
+       if (r)
+               dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
+}
+
+#define SUPPORTED_FIF_FLAGS \
+       (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
+       FIF_OTHER_BSS)
+static void zd_op_configure_filter(struct ieee80211_hw *hw,
+                       unsigned int changed_flags,
+                       unsigned int *new_flags,
+                       int mc_count, struct dev_mc_list *mclist)
+{
+       struct zd_mc_hash hash;
+       struct zd_mac *mac = zd_hw_mac(hw);
+       unsigned long flags;
+       int i;
+
+       /* Only deal with supported flags */
+       changed_flags &= SUPPORTED_FIF_FLAGS;
+       *new_flags &= SUPPORTED_FIF_FLAGS;
+
+       /* changed_flags is always populated but this driver
+        * doesn't support all FIF flags so its possible we don't
+        * need to do anything */
+       if (!changed_flags)
+               return;
+
+       if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) {
+               zd_mc_add_all(&hash);
+       } else {
+               DECLARE_MAC_BUF(macbuf);
+
+               zd_mc_clear(&hash);
+               for (i = 0; i < mc_count; i++) {
+                       if (!mclist)
+                               break;
+                       dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n",
+                                 print_mac(macbuf, mclist->dmi_addr));
+                       zd_mc_add_addr(&hash, mclist->dmi_addr);
+                       mclist = mclist->next;
+               }
        }
+
+       spin_lock_irqsave(&mac->lock, flags);
+       mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
+       mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
+       mac->multicast_hash = hash;
+       spin_unlock_irqrestore(&mac->lock, flags);
+       queue_work(zd_workqueue, &mac->set_multicast_hash_work);
+
+       if (changed_flags & FIF_CONTROL)
+               queue_work(zd_workqueue, &mac->set_rx_filter_work);
+
+       /* no handling required for FIF_OTHER_BSS as we don't currently
+        * do BSSID filtering */
+       /* FIXME: in future it would be nice to enable the probe response
+        * filter (so that the driver doesn't see them) until
+        * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd
+        * have to schedule work to enable prbresp reception, which might
+        * happen too late. For now we'll just listen and forward them all the
+        * time. */
 }
 
-static void ieee_init(struct ieee80211_device *ieee)
+static void set_rts_cts_work(struct work_struct *work)
 {
-       ieee->mode = IEEE_B | IEEE_G;
-       ieee->freq_band = IEEE80211_24GHZ_BAND;
-       ieee->modulation = IEEE80211_OFDM_MODULATION | IEEE80211_CCK_MODULATION;
-       ieee->tx_headroom = sizeof(struct zd_ctrlset);
-       ieee->set_security = set_security;
-       ieee->hard_start_xmit = netdev_tx;
-
-       /* Software encryption/decryption for now */
-       ieee->host_build_iv = 0;
-       ieee->host_encrypt = 1;
-       ieee->host_decrypt = 1;
-
-       /* FIXME: default to managed mode, until ieee80211 and zd1211rw can
-        * correctly support AUTO */
-       ieee->iw_mode = IW_MODE_INFRA;
+       struct zd_mac *mac =
+               container_of(work, struct zd_mac, set_rts_cts_work);
+       unsigned long flags;
+       unsigned int short_preamble;
+
+       mutex_lock(&mac->chip.mutex);
+
+       spin_lock_irqsave(&mac->lock, flags);
+       mac->updating_rts_rate = 0;
+       short_preamble = mac->short_preamble;
+       spin_unlock_irqrestore(&mac->lock, flags);
+
+       zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
+       mutex_unlock(&mac->chip.mutex);
 }
 
-static void softmac_init(struct ieee80211softmac_device *sm)
+static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_bss_conf *bss_conf,
+                                  u32 changes)
 {
-       sm->set_channel = set_channel;
-       sm->bssinfo_change = bssinfo_change;
+       struct zd_mac *mac = zd_hw_mac(hw);
+       unsigned long flags;
+
+       dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
+
+       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+               spin_lock_irqsave(&mac->lock, flags);
+               mac->short_preamble = bss_conf->use_short_preamble;
+               if (!mac->updating_rts_rate) {
+                       mac->updating_rts_rate = 1;
+                       /* FIXME: should disable TX here, until work has
+                        * completed and RTS_CTS reg is updated */
+                       queue_work(zd_workqueue, &mac->set_rts_cts_work);
+               }
+               spin_unlock_irqrestore(&mac->lock, flags);
+       }
 }
 
-struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev)
+static const struct ieee80211_ops zd_ops = {
+       .tx                     = zd_op_tx,
+       .start                  = zd_op_start,
+       .stop                   = zd_op_stop,
+       .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,
+};
+
+struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
 {
-       struct zd_mac *mac = zd_netdev_mac(ndev);
-       struct iw_statistics *iw_stats = &mac->iw_stats;
-       unsigned int i, count, qual_total, rssi_total;
+       struct zd_mac *mac;
+       struct ieee80211_hw *hw;
+       int i;
 
-       memset(iw_stats, 0, sizeof(struct iw_statistics));
-       /* We are not setting the status, because ieee->state is not updated
-        * at all and this driver doesn't track authentication state.
-        */
-       spin_lock_irq(&mac->lock);
-       count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ?
-               mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE;
-       qual_total = rssi_total = 0;
-       for (i = 0; i < count; i++) {
-               qual_total += mac->qual_buffer[i];
-               rssi_total += mac->rssi_buffer[i];
+       hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops);
+       if (!hw) {
+               dev_dbg_f(&intf->dev, "out of memory\n");
+               return NULL;
        }
-       spin_unlock_irq(&mac->lock);
-       iw_stats->qual.updated = IW_QUAL_NOISE_INVALID;
-       if (count > 0) {
-               iw_stats->qual.qual = qual_total / count;
-               iw_stats->qual.level = rssi_total / count;
-               iw_stats->qual.updated |=
-                       IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED;
-       } else {
-               iw_stats->qual.updated |=
-                       IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID;
+
+       mac = zd_hw_mac(hw);
+
+       memset(mac, 0, sizeof(*mac));
+       spin_lock_init(&mac->lock);
+       mac->hw = hw;
+
+       mac->type = IEEE80211_IF_TYPE_INVALID;
+
+       memcpy(mac->channels, zd_channels, sizeof(zd_channels));
+       memcpy(mac->rates, zd_rates, sizeof(zd_rates));
+       mac->modes[0].mode = MODE_IEEE80211G;
+       mac->modes[0].num_rates = ARRAY_SIZE(zd_rates);
+       mac->modes[0].rates = mac->rates;
+       mac->modes[0].num_channels = ARRAY_SIZE(zd_channels);
+       mac->modes[0].channels = mac->channels;
+       mac->modes[1].mode = MODE_IEEE80211B;
+       mac->modes[1].num_rates = 4;
+       mac->modes[1].rates = mac->rates;
+       mac->modes[1].num_channels = ARRAY_SIZE(zd_channels);
+       mac->modes[1].channels = mac->channels;
+
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+                    IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED;
+       hw->max_rssi = 100;
+       hw->max_signal = 100;
+
+       hw->queues = 1;
+       hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
+
+       skb_queue_head_init(&mac->ack_wait_queue);
+
+       for (i = 0; i < 2; i++) {
+               if (ieee80211_register_hwmode(hw, &mac->modes[i])) {
+                       dev_dbg_f(&intf->dev, "cannot register hwmode\n");
+                       ieee80211_free_hw(hw);
+                       return NULL;
+               }
        }
-       /* TODO: update counter */
-       return iw_stats;
+
+       zd_chip_init(&mac->chip, hw, intf);
+       housekeeping_init(mac);
+       INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
+       INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
+       INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
+
+       SET_IEEE80211_DEV(hw, &intf->dev);
+       return hw;
 }
 
 #define LINK_LED_WORK_DELAY HZ
@@ -1308,18 +952,17 @@ static void link_led_handler(struct work_struct *work)
        struct zd_mac *mac =
                container_of(work, struct zd_mac, housekeeping.link_led_work.work);
        struct zd_chip *chip = &mac->chip;
-       struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev);
        int is_associated;
        int r;
 
        spin_lock_irq(&mac->lock);
-       is_associated = sm->associnfo.associated != 0;
+       is_associated = mac->associated;
        spin_unlock_irq(&mac->lock);
 
        r = zd_chip_control_leds(chip,
                                 is_associated ? LED_ASSOCIATED : LED_SCANNING);
        if (r)
-               dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
+               dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
 
        queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
                           LINK_LED_WORK_DELAY);
index 1b15bde3ff60a35599a86361778605e926b71963..2dde108df76743cafaaa477bf38c2199e263e0ab 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_mac.h
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
 #ifndef _ZD_MAC_H
 #define _ZD_MAC_H
 
-#include <linux/wireless.h>
 #include <linux/kernel.h>
-#include <linux/workqueue.h>
-#include <net/ieee80211.h>
-#include <net/ieee80211softmac.h>
+#include <net/mac80211.h>
 
 #include "zd_chip.h"
-#include "zd_netdev.h"
+#include "zd_ieee80211.h"
 
 struct zd_ctrlset {
        u8     modulation;
@@ -57,7 +57,7 @@ struct zd_ctrlset {
 /* The two possible modulation types. Notify that 802.11b doesn't use the CCK
  * codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain
  * consistent with uses the term at other places.
 */
+ */
 #define ZD_CCK                  0x00
 #define ZD_OFDM                 0x10
 
@@ -141,58 +141,68 @@ struct rx_status {
 #define ZD_RX_CRC16_ERROR              0x40
 #define ZD_RX_ERROR                    0x80
 
+enum mac_flags {
+       MAC_FIXED_CHANNEL = 0x01,
+};
+
 struct housekeeping {
        struct delayed_work link_led_work;
 };
 
+/**
+ * struct zd_tx_skb_control_block - control block for tx skbuffs
+ * @control: &struct ieee80211_tx_control pointer
+ * @context: context pointer
+ *
+ * This structure is used to fill the cb field in an &sk_buff to transmit.
+ * The control field is NULL, if there is no requirement from the mac80211
+ * stack to report about the packet ACK. This is the case if the flag
+ * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control.
+ */
+struct zd_tx_skb_control_block {
+       struct ieee80211_tx_control *control;
+       struct ieee80211_hw *hw;
+       void *context;
+};
+
 #define ZD_MAC_STATS_BUFFER_SIZE 16
 
+#define ZD_MAC_MAX_ACK_WAITERS 10
+
 struct zd_mac {
        struct zd_chip chip;
        spinlock_t lock;
-       struct net_device *netdev;
-
-       /* Unlocked reading possible */
-       struct iw_statistics iw_stats;
-
+       struct ieee80211_hw *hw;
        struct housekeeping housekeeping;
        struct work_struct set_multicast_hash_work;
+       struct work_struct set_rts_cts_work;
+       struct work_struct set_rx_filter_work;
        struct zd_mc_hash multicast_hash;
-       struct delayed_work set_rts_cts_work;
-       struct delayed_work set_basic_rates_work;
-
-       struct tasklet_struct rx_tasklet;
-       struct sk_buff_head rx_queue;
-
-       unsigned int stats_count;
-       u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE];
-       u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE];
        u8 regdomain;
        u8 default_regdomain;
-       u8 requested_channel;
-
-       /* A bitpattern of cr_rates */
-       u16 basic_rates;
-
-       /* A zd_rate */
-       u8 rts_rate;
+       int type;
+       int associated;
+       struct sk_buff_head ack_wait_queue;
+       struct ieee80211_channel channels[14];
+       struct ieee80211_rate rates[12];
+       struct ieee80211_hw_mode modes[2];
 
        /* Short preamble (used for RTS/CTS) */
        unsigned int short_preamble:1;
 
        /* flags to indicate update in progress */
        unsigned int updating_rts_rate:1;
-       unsigned int updating_basic_rates:1;
-};
 
-static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac)
-{
-       return zd_netdev_ieee80211(mac->netdev);
-}
+       /* whether to pass frames with CRC errors to stack */
+       unsigned int pass_failed_fcs:1;
 
-static inline struct zd_mac *zd_netdev_mac(struct net_device *netdev)
+       /* whether to pass control frames to stack */
+       unsigned int pass_ctrl:1;
+};
+
+static inline struct zd_mac *zd_hw_mac(struct ieee80211_hw *hw)
 {
-       return ieee80211softmac_priv(netdev);
+       return hw->priv;
 }
 
 static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip)
@@ -205,35 +215,22 @@ static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb)
        return zd_chip_to_mac(zd_usb_to_chip(usb));
 }
 
+static inline u8 *zd_mac_get_perm_addr(struct zd_mac *mac)
+{
+       return mac->hw->wiphy->perm_addr;
+}
+
 #define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip))
 
-int zd_mac_init(struct zd_mac *mac,
-                struct net_device *netdev,
-               struct usb_interface *intf);
+struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf);
 void zd_mac_clear(struct zd_mac *mac);
 
-int zd_mac_preinit_hw(struct zd_mac *mac);
-int zd_mac_init_hw(struct zd_mac *mac);
-
-int zd_mac_open(struct net_device *netdev);
-int zd_mac_stop(struct net_device *netdev);
-int zd_mac_set_mac_address(struct net_device *dev, void *p);
-void zd_mac_set_multicast_list(struct net_device *netdev);
-
-int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length);
-
-int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain);
-u8 zd_mac_get_regdomain(struct zd_mac *zd_mac);
-
-int zd_mac_request_channel(struct zd_mac *mac, u8 channel);
-u8 zd_mac_get_channel(struct zd_mac *mac);
-
-int zd_mac_set_mode(struct zd_mac *mac, u32 mode);
-int zd_mac_get_mode(struct zd_mac *mac, u32 *mode);
-
-int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range);
+int zd_mac_preinit_hw(struct ieee80211_hw *hw);
+int zd_mac_init_hw(struct ieee80211_hw *hw);
 
-struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev);
+int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length);
+void zd_mac_tx_failed(struct ieee80211_hw *hw);
+void zd_mac_tx_to_dev(struct sk_buff *skb, int error);
 
 #ifdef DEBUG
 void zd_dump_rx_status(const struct rx_status *status);
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c
deleted file mode 100644 (file)
index 047cab3..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/* zd_netdev.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <net/ieee80211.h>
-#include <net/ieee80211softmac.h>
-#include <net/ieee80211softmac_wx.h>
-#include <net/iw_handler.h>
-
-#include "zd_def.h"
-#include "zd_netdev.h"
-#include "zd_mac.h"
-#include "zd_ieee80211.h"
-
-/* Region 0 means reset regdomain to default. */
-static int zd_set_regdomain(struct net_device *netdev,
-                           struct iw_request_info *info,
-                           union iwreq_data *req, char *extra)
-{
-       const u8 *regdomain = (u8 *)req;
-       return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain);
-}
-
-static int zd_get_regdomain(struct net_device *netdev,
-                           struct iw_request_info *info,
-                           union iwreq_data *req, char *extra)
-{
-       u8 *regdomain = (u8 *)req;
-       if (!regdomain)
-               return -EINVAL;
-       *regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev));
-       return 0;
-}
-
-static const struct iw_priv_args zd_priv_args[] = {
-       {
-               .cmd = ZD_PRIV_SET_REGDOMAIN,
-               .set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
-               .name = "set_regdomain",
-       },
-       {
-               .cmd = ZD_PRIV_GET_REGDOMAIN,
-               .get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1,
-               .name = "get_regdomain",
-       },
-};
-
-#define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV]
-
-static const iw_handler zd_priv_handler[] = {
-       PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain,
-       PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain,
-};
-
-static int iw_get_name(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       /* FIXME: check whether 802.11a will also supported */
-       strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ);
-       return 0;
-}
-
-static int iw_get_nick(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       strcpy(extra, "zd1211");
-       req->data.length = strlen(extra);
-       req->data.flags = 1;
-       return 0;
-}
-
-static int iw_set_freq(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       int r;
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct iw_freq *freq = &req->freq;
-       u8 channel;
-
-       r = zd_find_channel(&channel, freq);
-       if (r < 0)
-               return r;
-       r = zd_mac_request_channel(mac, channel);
-       return r;
-}
-
-static int iw_get_freq(struct net_device *netdev,
-                  struct iw_request_info *info,
-                  union iwreq_data *req, char *extra)
-{
-       struct zd_mac *mac = zd_netdev_mac(netdev);
-       struct iw_freq *freq = &req->freq;
-
-       return zd_channel_to_freq(freq, zd_mac_get_channel(mac));
-}
-
-static int iw_set_mode(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode);
-}
-
-static int iw_get_mode(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode);
-}
-
-static int iw_get_range(struct net_device *netdev,
-                      struct iw_request_info *info,
-                      union iwreq_data *req, char *extra)
-{
-       struct iw_range *range = (struct iw_range *)extra;
-
-       dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n");
-       req->data.length = sizeof(*range);
-       return zd_mac_get_range(zd_netdev_mac(netdev), range);
-}
-
-static int iw_set_encode(struct net_device *netdev,
-                        struct iw_request_info *info,
-                        union iwreq_data *data,
-                        char *extra)
-{
-       return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info,
-               data, extra);
-}
-
-static int iw_get_encode(struct net_device *netdev,
-                        struct iw_request_info *info,
-                        union iwreq_data *data,
-                        char *extra)
-{
-       return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info,
-               data, extra);
-}
-
-static int iw_set_encodeext(struct net_device *netdev,
-                        struct iw_request_info *info,
-                        union iwreq_data *data,
-                        char *extra)
-{
-       return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info,
-               data, extra);
-}
-
-static int iw_get_encodeext(struct net_device *netdev,
-                        struct iw_request_info *info,
-                        union iwreq_data *data,
-                        char *extra)
-{
-       return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info,
-               data, extra);
-}
-
-#define WX(x) [(x)-SIOCIWFIRST]
-
-static const iw_handler zd_standard_iw_handlers[] = {
-       WX(SIOCGIWNAME)         = iw_get_name,
-       WX(SIOCGIWNICKN)        = iw_get_nick,
-       WX(SIOCSIWFREQ)         = iw_set_freq,
-       WX(SIOCGIWFREQ)         = iw_get_freq,
-       WX(SIOCSIWMODE)         = iw_set_mode,
-       WX(SIOCGIWMODE)         = iw_get_mode,
-       WX(SIOCGIWRANGE)        = iw_get_range,
-       WX(SIOCSIWENCODE)       = iw_set_encode,
-       WX(SIOCGIWENCODE)       = iw_get_encode,
-       WX(SIOCSIWENCODEEXT)    = iw_set_encodeext,
-       WX(SIOCGIWENCODEEXT)    = iw_get_encodeext,
-       WX(SIOCSIWAUTH)         = ieee80211_wx_set_auth,
-       WX(SIOCGIWAUTH)         = ieee80211_wx_get_auth,
-       WX(SIOCSIWSCAN)         = ieee80211softmac_wx_trigger_scan,
-       WX(SIOCGIWSCAN)         = ieee80211softmac_wx_get_scan_results,
-       WX(SIOCSIWESSID)        = ieee80211softmac_wx_set_essid,
-       WX(SIOCGIWESSID)        = ieee80211softmac_wx_get_essid,
-       WX(SIOCSIWAP)           = ieee80211softmac_wx_set_wap,
-       WX(SIOCGIWAP)           = ieee80211softmac_wx_get_wap,
-       WX(SIOCSIWRATE)         = ieee80211softmac_wx_set_rate,
-       WX(SIOCGIWRATE)         = ieee80211softmac_wx_get_rate,
-       WX(SIOCSIWGENIE)        = ieee80211softmac_wx_set_genie,
-       WX(SIOCGIWGENIE)        = ieee80211softmac_wx_get_genie,
-       WX(SIOCSIWMLME)         = ieee80211softmac_wx_set_mlme,
-};
-
-static const struct iw_handler_def iw_handler_def = {
-       .standard               = zd_standard_iw_handlers,
-       .num_standard           = ARRAY_SIZE(zd_standard_iw_handlers),
-       .private                = zd_priv_handler,
-       .num_private            = ARRAY_SIZE(zd_priv_handler),
-       .private_args           = zd_priv_args,
-       .num_private_args       = ARRAY_SIZE(zd_priv_args),
-       .get_wireless_stats     = zd_mac_get_wireless_stats,
-};
-
-struct net_device *zd_netdev_alloc(struct usb_interface *intf)
-{
-       int r;
-       struct net_device *netdev;
-       struct zd_mac *mac;
-
-       netdev = alloc_ieee80211softmac(sizeof(struct zd_mac));
-       if (!netdev) {
-               dev_dbg_f(&intf->dev, "out of memory\n");
-               return NULL;
-       }
-
-       mac = zd_netdev_mac(netdev);
-       r = zd_mac_init(mac, netdev, intf);
-       if (r) {
-               usb_set_intfdata(intf, NULL);
-               free_ieee80211(netdev);
-               return NULL;
-       }
-
-       SET_NETDEV_DEV(netdev, &intf->dev);
-
-       dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags);
-       dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features);
-
-       netdev->open = zd_mac_open;
-       netdev->stop = zd_mac_stop;
-       /* netdev->get_stats = */
-       netdev->set_multicast_list = zd_mac_set_multicast_list;
-       netdev->set_mac_address = zd_mac_set_mac_address;
-       netdev->wireless_handlers = &iw_handler_def;
-       /* netdev->ethtool_ops = */
-
-       return netdev;
-}
-
-void zd_netdev_free(struct net_device *netdev)
-{
-       if (!netdev)
-               return;
-
-       zd_mac_clear(zd_netdev_mac(netdev));
-       free_ieee80211(netdev);
-}
-
-void zd_netdev_disconnect(struct net_device *netdev)
-{
-       unregister_netdev(netdev);
-}
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.h b/drivers/net/wireless/zd1211rw/zd_netdev.h
deleted file mode 100644 (file)
index 374a957..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* zd_netdev.h: Header for net device related functions.
- *
- * 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 _ZD_NETDEV_H
-#define _ZD_NETDEV_H
-
-#include <linux/usb.h>
-#include <linux/netdevice.h>
-#include <net/ieee80211.h>
-
-#define ZD_PRIV_SET_REGDOMAIN (SIOCIWFIRSTPRIV)
-#define ZD_PRIV_GET_REGDOMAIN (SIOCIWFIRSTPRIV+1)
-
-static inline struct ieee80211_device *zd_netdev_ieee80211(
-       struct net_device *ndev)
-{
-       return netdev_priv(ndev);
-}
-
-static inline struct net_device *zd_ieee80211_to_netdev(
-       struct ieee80211_device *ieee)
-{
-       return ieee->dev;
-}
-
-struct net_device *zd_netdev_alloc(struct usb_interface *intf);
-void zd_netdev_free(struct net_device *netdev);
-
-void zd_netdev_disconnect(struct net_device *netdev);
-
-#endif /* _ZD_NETDEV_H */
index abe5d38f7f4de5ed9c21c7fa3df0620f109ac436..ec4129312813608089cc98fd13964fe0428e5ecd 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf.c
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index 30502f26b71cbd79999ca8b1d26a93cbb34a6e94..79dc1035592ded4692d0b6aa9f0c8282321e35aa 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf.h
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index 006774de3202a4185edeb7bcb2b45af2afb30bcc..74a8f7a55591759b343c8d445dd14e242f6f5b0c 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf_al2230.c: Functions for the AL2230 RF controller
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index 73d0bb26f81049ec969fd0bf49928cf641f6c44a..65095d661e6ba6ec392a48d48dc33479223a0fd8 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf_al7230b.c: Functions for the AL7230B RF controller
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index cc70d40684eaca405df41843ed5c2c01793b76fc..0597d862fbd2edb47368fd13c4db04b0c4d918cc 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf_rfmd.c: Functions for the RFMD RF controller
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
index 857dcf3eae61506aea5b45c3c396004d91679f0b..439799b84876b9f597d0ec8004f2fae39f9a67a4 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_rf_uw2453.c: Functions for the UW2453 RF controller
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
@@ -403,7 +406,7 @@ static int uw2453_init_hw(struct zd_rf *rf)
                if (r)
                        return r;
 
-               if (!intr_status & 0xf) {
+               if (!(intr_status & 0xf)) {
                        dev_dbg_f(zd_chip_dev(chip),
                                "PLL locked on configuration %d\n", i);
                        found_config = i;
index c755b69238123c56cece6d8df9d77b5ed68022a6..7942b15acfe7019bc604ccc442b066b56107c36b 100644 (file)
@@ -1,4 +1,8 @@
-/* zd_usb.c
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
+ * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.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/kernel.h>
 #include <linux/init.h>
-#include <linux/module.h>
 #include <linux/firmware.h>
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/skbuff.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
-#include <net/ieee80211.h>
+#include <net/mac80211.h>
 #include <asm/unaligned.h>
 
 #include "zd_def.h"
-#include "zd_netdev.h"
 #include "zd_mac.h"
 #include "zd_usb.h"
 
@@ -55,6 +57,7 @@ static struct usb_device_id usb_ids[] = {
        { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
        /* ZD1211B */
        { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
@@ -353,18 +356,6 @@ out:
        spin_unlock(&intr->lock);
 }
 
-static inline void handle_retry_failed_int(struct urb *urb)
-{
-       struct zd_usb *usb = urb->context;
-       struct zd_mac *mac = zd_usb_to_mac(usb);
-       struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-
-       ieee->stats.tx_errors++;
-       ieee->ieee_stats.tx_retry_limit_exceeded++;
-       dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
-}
-
-
 static void int_urb_complete(struct urb *urb)
 {
        int r;
@@ -400,7 +391,7 @@ static void int_urb_complete(struct urb *urb)
                handle_regs_int(urb);
                break;
        case USB_INT_ID_RETRY_FAILED:
-               handle_retry_failed_int(urb);
+               zd_mac_tx_failed(zd_usb_to_hw(urb->context));
                break;
        default:
                dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb,
@@ -530,14 +521,10 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
                             unsigned int length)
 {
        int i;
-       struct zd_mac *mac = zd_usb_to_mac(usb);
        const struct rx_length_info *length_info;
 
        if (length < sizeof(struct rx_length_info)) {
                /* It's not a complete packet anyhow. */
-               struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-               ieee->stats.rx_errors++;
-               ieee->stats.rx_length_errors++;
                return;
        }
        length_info = (struct rx_length_info *)
@@ -561,13 +548,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
                        n = l+k;
                        if (n > length)
                                return;
-                       zd_mac_rx_irq(mac, buffer+l, k);
+                       zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k);
                        if (i >= 2)
                                return;
                        l = (n+3) & ~3;
                }
        } else {
-               zd_mac_rx_irq(mac, buffer, length);
+               zd_mac_rx(zd_usb_to_hw(usb), buffer, length);
        }
 }
 
@@ -629,7 +616,7 @@ resubmit:
        usb_submit_urb(urb, GFP_ATOMIC);
 }
 
-static struct urb *alloc_urb(struct zd_usb *usb)
+static struct urb *alloc_rx_urb(struct zd_usb *usb)
 {
        struct usb_device *udev = zd_usb_to_usbdev(usb);
        struct urb *urb;
@@ -653,7 +640,7 @@ static struct urb *alloc_urb(struct zd_usb *usb)
        return urb;
 }
 
-static void free_urb(struct urb *urb)
+static void free_rx_urb(struct urb *urb)
 {
        if (!urb)
                return;
@@ -671,11 +658,11 @@ int zd_usb_enable_rx(struct zd_usb *usb)
        dev_dbg_f(zd_usb_dev(usb), "\n");
 
        r = -ENOMEM;
-       urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);
+       urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);
        if (!urbs)
                goto error;
-       for (i = 0; i < URBS_COUNT; i++) {
-               urbs[i] = alloc_urb(usb);
+       for (i = 0; i < RX_URBS_COUNT; i++) {
+               urbs[i] = alloc_rx_urb(usb);
                if (!urbs[i])
                        goto error;
        }
@@ -688,10 +675,10 @@ int zd_usb_enable_rx(struct zd_usb *usb)
                goto error;
        }
        rx->urbs = urbs;
-       rx->urbs_count = URBS_COUNT;
+       rx->urbs_count = RX_URBS_COUNT;
        spin_unlock_irq(&rx->lock);
 
-       for (i = 0; i < URBS_COUNT; i++) {
+       for (i = 0; i < RX_URBS_COUNT; i++) {
                r = usb_submit_urb(urbs[i], GFP_KERNEL);
                if (r)
                        goto error_submit;
@@ -699,7 +686,7 @@ int zd_usb_enable_rx(struct zd_usb *usb)
 
        return 0;
 error_submit:
-       for (i = 0; i < URBS_COUNT; i++) {
+       for (i = 0; i < RX_URBS_COUNT; i++) {
                usb_kill_urb(urbs[i]);
        }
        spin_lock_irq(&rx->lock);
@@ -708,8 +695,8 @@ error_submit:
        spin_unlock_irq(&rx->lock);
 error:
        if (urbs) {
-               for (i = 0; i < URBS_COUNT; i++)
-                       free_urb(urbs[i]);
+               for (i = 0; i < RX_URBS_COUNT; i++)
+                       free_rx_urb(urbs[i]);
        }
        return r;
 }
@@ -731,7 +718,7 @@ void zd_usb_disable_rx(struct zd_usb *usb)
 
        for (i = 0; i < count; i++) {
                usb_kill_urb(urbs[i]);
-               free_urb(urbs[i]);
+               free_rx_urb(urbs[i]);
        }
        kfree(urbs);
 
@@ -741,9 +728,142 @@ void zd_usb_disable_rx(struct zd_usb *usb)
        spin_unlock_irqrestore(&rx->lock, flags);
 }
 
+/**
+ * zd_usb_disable_tx - disable transmission
+ * @usb: the zd1211rw-private USB structure
+ *
+ * Frees all URBs in the free list and marks the transmission as disabled.
+ */
+void zd_usb_disable_tx(struct zd_usb *usb)
+{
+       struct zd_usb_tx *tx = &usb->tx;
+       unsigned long flags;
+       struct list_head *pos, *n;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       list_for_each_safe(pos, n, &tx->free_urb_list) {
+               list_del(pos);
+               usb_free_urb(list_entry(pos, struct urb, urb_list));
+       }
+       tx->enabled = 0;
+       tx->submitted_urbs = 0;
+       /* The stopped state is ignored, relying on ieee80211_wake_queues()
+        * in a potentionally following zd_usb_enable_tx().
+        */
+       spin_unlock_irqrestore(&tx->lock, flags);
+}
+
+/**
+ * zd_usb_enable_tx - enables transmission
+ * @usb: a &struct zd_usb pointer
+ *
+ * This function enables transmission and prepares the &zd_usb_tx data
+ * structure.
+ */
+void zd_usb_enable_tx(struct zd_usb *usb)
+{
+       unsigned long flags;
+       struct zd_usb_tx *tx = &usb->tx;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       tx->enabled = 1;
+       tx->submitted_urbs = 0;
+       ieee80211_wake_queues(zd_usb_to_hw(usb));
+       tx->stopped = 0;
+       spin_unlock_irqrestore(&tx->lock, flags);
+}
+
+/**
+ * alloc_tx_urb - provides an tx URB
+ * @usb: a &struct zd_usb pointer
+ *
+ * Allocates a new URB. If possible takes the urb from the free list in
+ * usb->tx.
+ */
+static struct urb *alloc_tx_urb(struct zd_usb *usb)
+{
+       struct zd_usb_tx *tx = &usb->tx;
+       unsigned long flags;
+       struct list_head *entry;
+       struct urb *urb;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       if (list_empty(&tx->free_urb_list)) {
+               urb = usb_alloc_urb(0, GFP_ATOMIC);
+               goto out;
+       }
+       entry = tx->free_urb_list.next;
+       list_del(entry);
+       urb = list_entry(entry, struct urb, urb_list);
+out:
+       spin_unlock_irqrestore(&tx->lock, flags);
+       return urb;
+}
+
+/**
+ * free_tx_urb - frees a used tx URB
+ * @usb: a &struct zd_usb pointer
+ * @urb: URB to be freed
+ *
+ * Frees the the transmission URB, which means to put it on the free URB
+ * list.
+ */
+static void free_tx_urb(struct zd_usb *usb, struct urb *urb)
+{
+       struct zd_usb_tx *tx = &usb->tx;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       if (!tx->enabled) {
+               usb_free_urb(urb);
+               goto out;
+       }
+       list_add(&urb->urb_list, &tx->free_urb_list);
+out:
+       spin_unlock_irqrestore(&tx->lock, flags);
+}
+
+static void tx_dec_submitted_urbs(struct zd_usb *usb)
+{
+       struct zd_usb_tx *tx = &usb->tx;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       --tx->submitted_urbs;
+       if (tx->stopped && tx->submitted_urbs <= ZD_USB_TX_LOW) {
+               ieee80211_wake_queues(zd_usb_to_hw(usb));
+               tx->stopped = 0;
+       }
+       spin_unlock_irqrestore(&tx->lock, flags);
+}
+
+static void tx_inc_submitted_urbs(struct zd_usb *usb)
+{
+       struct zd_usb_tx *tx = &usb->tx;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tx->lock, flags);
+       ++tx->submitted_urbs;
+       if (!tx->stopped && tx->submitted_urbs > ZD_USB_TX_HIGH) {
+               ieee80211_stop_queues(zd_usb_to_hw(usb));
+               tx->stopped = 1;
+       }
+       spin_unlock_irqrestore(&tx->lock, flags);
+}
+
+/**
+ * tx_urb_complete - completes the execution of an URB
+ * @urb: a URB
+ *
+ * This function is called if the URB has been transferred to a device or an
+ * error has happened.
+ */
 static void tx_urb_complete(struct urb *urb)
 {
        int r;
+       struct sk_buff *skb;
+       struct zd_tx_skb_control_block *cb;
+       struct zd_usb *usb;
 
        switch (urb->status) {
        case 0:
@@ -761,9 +881,12 @@ static void tx_urb_complete(struct urb *urb)
                goto resubmit;
        }
 free_urb:
-       usb_buffer_free(urb->dev, urb->transfer_buffer_length,
-                       urb->transfer_buffer, urb->transfer_dma);
-       usb_free_urb(urb);
+       skb = (struct sk_buff *)urb->context;
+       zd_mac_tx_to_dev(skb, urb->status);
+       cb = (struct zd_tx_skb_control_block *)skb->cb;
+       usb = &zd_hw_mac(cb->hw)->chip.usb;
+       free_tx_urb(usb, urb);
+       tx_dec_submitted_urbs(usb);
        return;
 resubmit:
        r = usb_submit_urb(urb, GFP_ATOMIC);
@@ -773,43 +896,40 @@ resubmit:
        }
 }
 
-/* Puts the frame on the USB endpoint. It doesn't wait for
- * completion. The frame must contain the control set.
+/**
+ * zd_usb_tx: initiates transfer of a frame of the device
+ *
+ * @usb: the zd1211rw-private USB structure
+ * @skb: a &struct sk_buff pointer
+ *
+ * This function tranmits a frame to the device. It doesn't wait for
+ * completion. The frame must contain the control set and have all the
+ * control set information available.
+ *
+ * The function returns 0 if the transfer has been successfully initiated.
  */
-int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length)
+int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb)
 {
        int r;
        struct usb_device *udev = zd_usb_to_usbdev(usb);
        struct urb *urb;
-       void *buffer;
 
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       urb = alloc_tx_urb(usb);
        if (!urb) {
                r = -ENOMEM;
                goto out;
        }
 
-       buffer = usb_buffer_alloc(zd_usb_to_usbdev(usb), length, GFP_ATOMIC,
-                                 &urb->transfer_dma);
-       if (!buffer) {
-               r = -ENOMEM;
-               goto error_free_urb;
-       }
-       memcpy(buffer, frame, length);
-
        usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT),
-                         buffer, length, tx_urb_complete, NULL);
-       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+                         skb->data, skb->len, tx_urb_complete, skb);
 
        r = usb_submit_urb(urb, GFP_ATOMIC);
        if (r)
                goto error;
+       tx_inc_submitted_urbs(usb);
        return 0;
 error:
-       usb_buffer_free(zd_usb_to_usbdev(usb), length, buffer,
-                       urb->transfer_dma);
-error_free_urb:
-       usb_free_urb(urb);
+       free_tx_urb(usb, urb);
 out:
        return r;
 }
@@ -838,16 +958,20 @@ static inline void init_usb_rx(struct zd_usb *usb)
 
 static inline void init_usb_tx(struct zd_usb *usb)
 {
-       /* FIXME: at this point we will allocate a fixed number of urb's for
-        * use in a cyclic scheme */
+       struct zd_usb_tx *tx = &usb->tx;
+       spin_lock_init(&tx->lock);
+       tx->enabled = 0;
+       tx->stopped = 0;
+       INIT_LIST_HEAD(&tx->free_urb_list);
+       tx->submitted_urbs = 0;
 }
 
-void zd_usb_init(struct zd_usb *usb, struct net_device *netdev,
+void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw,
                 struct usb_interface *intf)
 {
        memset(usb, 0, sizeof(*usb));
        usb->intf = usb_get_intf(intf);
-       usb_set_intfdata(usb->intf, netdev);
+       usb_set_intfdata(usb->intf, hw);
        init_usb_interrupt(usb);
        init_usb_tx(usb);
        init_usb_rx(usb);
@@ -973,7 +1097,7 @@ int zd_usb_init_hw(struct zd_usb *usb)
                return r;
        }
 
-       r = zd_mac_init_hw(mac);
+       r = zd_mac_init_hw(mac->hw);
        if (r) {
                dev_dbg_f(zd_usb_dev(usb),
                         "couldn't initialize mac. Error number %d\n", r);
@@ -987,9 +1111,9 @@ int zd_usb_init_hw(struct zd_usb *usb)
 static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        int r;
-       struct zd_usb *usb;
        struct usb_device *udev = interface_to_usbdev(intf);
-       struct net_device *netdev = NULL;
+       struct zd_usb *usb;
+       struct ieee80211_hw *hw = NULL;
 
        print_id(udev);
 
@@ -1007,57 +1131,65 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
                goto error;
        }
 
-       usb_reset_device(interface_to_usbdev(intf));
+       r = usb_reset_device(udev);
+       if (r) {
+               dev_err(&intf->dev,
+                       "couldn't reset usb device. Error number %d\n", r);
+               goto error;
+       }
 
-       netdev = zd_netdev_alloc(intf);
-       if (netdev == NULL) {
+       hw = zd_mac_alloc_hw(intf);
+       if (hw == NULL) {
                r = -ENOMEM;
                goto error;
        }
 
-       usb = &zd_netdev_mac(netdev)->chip.usb;
+       usb = &zd_hw_mac(hw)->chip.usb;
        usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
 
-       r = zd_mac_preinit_hw(zd_netdev_mac(netdev));
+       r = zd_mac_preinit_hw(hw);
        if (r) {
                dev_dbg_f(&intf->dev,
                         "couldn't initialize mac. Error number %d\n", r);
                goto error;
        }
 
-       r = register_netdev(netdev);
+       r = ieee80211_register_hw(hw);
        if (r) {
                dev_dbg_f(&intf->dev,
-                        "couldn't register netdev. Error number %d\n", r);
+                        "couldn't register device. Error number %d\n", r);
                goto error;
        }
 
        dev_dbg_f(&intf->dev, "successful\n");
-       dev_info(&intf->dev,"%s\n", netdev->name);
+       dev_info(&intf->dev, "%s\n", wiphy_name(hw->wiphy));
        return 0;
 error:
        usb_reset_device(interface_to_usbdev(intf));
-       zd_netdev_free(netdev);
+       if (hw) {
+               zd_mac_clear(zd_hw_mac(hw));
+               ieee80211_free_hw(hw);
+       }
        return r;
 }
 
 static void disconnect(struct usb_interface *intf)
 {
-       struct net_device *netdev = zd_intf_to_netdev(intf);
+       struct ieee80211_hw *hw = zd_intf_to_hw(intf);
        struct zd_mac *mac;
        struct zd_usb *usb;
 
        /* Either something really bad happened, or we're just dealing with
         * a DEVICE_INSTALLER. */
-       if (netdev == NULL)
+       if (hw == NULL)
                return;
 
-       mac = zd_netdev_mac(netdev);
+       mac = zd_hw_mac(hw);
        usb = &mac->chip.usb;
 
        dev_dbg_f(zd_usb_dev(usb), "\n");
 
-       zd_netdev_disconnect(netdev);
+       ieee80211_unregister_hw(hw);
 
        /* Just in case something has gone wrong! */
        zd_usb_disable_rx(usb);
@@ -1070,12 +1202,13 @@ static void disconnect(struct usb_interface *intf)
         */
        usb_reset_device(interface_to_usbdev(intf));
 
-       zd_netdev_free(netdev);
+       zd_mac_clear(mac);
+       ieee80211_free_hw(hw);
        dev_dbg(&intf->dev, "disconnected\n");
 }
 
 static struct usb_driver driver = {
-       .name           = "zd1211rw",
+       .name           = KBUILD_MODNAME,
        .id_table       = usb_ids,
        .probe          = probe,
        .disconnect     = disconnect,
index 961a7a12ad68189d4b7877ed692d9f1c08374547..049f8b91f0204f91782819aadd00f991ef422c3a 100644 (file)
@@ -1,4 +1,7 @@
-/* zd_usb.h: Header for USB interface implemented by ZD1211 chip
+/* ZD1211 USB-WLAN driver for Linux
+ *
+ * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
+ * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
  *
  * 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
@@ -26,6 +29,9 @@
 
 #include "zd_def.h"
 
+#define ZD_USB_TX_HIGH  5
+#define ZD_USB_TX_LOW   2
+
 enum devicetype {
        DEVICE_ZD1211  = 0,
        DEVICE_ZD1211B = 1,
@@ -165,7 +171,7 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr)
        return (struct usb_int_regs *)intr->read_regs.buffer;
 }
 
-#define URBS_COUNT 5
+#define RX_URBS_COUNT 5
 
 struct zd_usb_rx {
        spinlock_t lock;
@@ -176,8 +182,21 @@ struct zd_usb_rx {
        int urbs_count;
 };
 
+/**
+ * struct zd_usb_tx - structure used for transmitting frames
+ * @lock: lock for transmission
+ * @free_urb_list: list of free URBs, contains all the URBs, which can be used
+ * @submitted_urbs: atomic integer that counts the URBs having sent to the
+ *     device, which haven't been completed
+ * @enabled: enabled flag, indicates whether tx is enabled
+ * @stopped: indicates whether higher level tx queues are stopped
+ */
 struct zd_usb_tx {
        spinlock_t lock;
+       struct list_head free_urb_list;
+       int submitted_urbs;
+       int enabled;
+       int stopped;
 };
 
 /* Contains the usb parts. The structure doesn't require a lock because intf
@@ -198,17 +217,17 @@ static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb)
        return interface_to_usbdev(usb->intf);
 }
 
-static inline struct net_device *zd_intf_to_netdev(struct usb_interface *intf)
+static inline struct ieee80211_hw *zd_intf_to_hw(struct usb_interface *intf)
 {
        return usb_get_intfdata(intf);
 }
 
-static inline struct net_device *zd_usb_to_netdev(struct zd_usb *usb)
+static inline struct ieee80211_hw *zd_usb_to_hw(struct zd_usb *usb)
 {
-       return zd_intf_to_netdev(usb->intf);
+       return zd_intf_to_hw(usb->intf);
 }
 
-void zd_usb_init(struct zd_usb *usb, struct net_device *netdev,
+void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw,
                 struct usb_interface *intf);
 int zd_usb_init_hw(struct zd_usb *usb);
 void zd_usb_clear(struct zd_usb *usb);
@@ -221,7 +240,10 @@ void zd_usb_disable_int(struct zd_usb *usb);
 int zd_usb_enable_rx(struct zd_usb *usb);
 void zd_usb_disable_rx(struct zd_usb *usb);
 
-int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length);
+void zd_usb_enable_tx(struct zd_usb *usb);
+void zd_usb_disable_tx(struct zd_usb *usb);
+
+int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb);
 
 int zd_usb_ioread16v(struct zd_usb *usb, u16 *values,
                 const zd_addr_t *addresses, unsigned int count);
index bca37bf0f5455812913e448272749b5d55e7c1a6..7483d45bc5bccffefd18b4fa94122eb78d40460f 100644 (file)
@@ -1073,7 +1073,7 @@ static void xennet_release_rx_bufs(struct netfront_info *np)
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
                        /* Do all the remapping work and M2P updates. */
                        MULTI_mmu_update(mcl, np->rx_mmu, mmu - np->rx_mmu,
-                                        0, DOMID_SELF);
+                                        NULL, DOMID_SELF);
                        mcl++;
                        HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
                }
index a6d6b2488ffc267c475a09c849f5f18c73e53cbb..703b85edb004b3d5b9f7dca1286ad4cba156291f 100644 (file)
@@ -364,7 +364,7 @@ static __inline__ int led_get_net_activity(void)
            struct in_device *in_dev = __in_dev_get_rcu(dev);
            if (!in_dev || !in_dev->ifa_list)
                continue;
-           if (LOOPBACK(in_dev->ifa_list->ifa_local))
+           if (ipv4_is_loopback(in_dev->ifa_list->ifa_local))
                continue;
            stats = dev->get_stats(dev);
            rx_total += stats->rx_packets;
index ff999ff0b6272a9edc2dc1feb5990f549642e416..62606ce26e5562bdd1bc6a5a8447c283951ab57d 100644 (file)
@@ -3890,7 +3890,7 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
                        break;
                }
        }
-       if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card))
+       if (rc && !(vlan_dev_info(dev)->real_dev->priv == (void *)card))
                return 0;
 
 #endif
@@ -3930,7 +3930,7 @@ qeth_get_card_from_dev(struct net_device *dev)
                card = (struct qeth_card *)dev->priv;
        else if (rc == QETH_VLAN_CARD)
                card = (struct qeth_card *)
-                       VLAN_DEV_INFO(dev)->real_dev->priv;
+                       vlan_dev_info(dev)->real_dev->priv;
 
        QETH_DBF_TEXT_(trace, 4, "%d", rc);
        return card ;
@@ -8340,7 +8340,7 @@ qeth_arp_constructor(struct neighbour *neigh)
        neigh->parms = neigh_parms_clone(parms);
        rcu_read_unlock();
 
-       neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
+       neigh->type = inet_addr_type(&init_net, *(__be32 *) neigh->primary_key);
        neigh->nud_state = NUD_NOARP;
        neigh->ops = arp_direct_ops;
        neigh->output = neigh->ops->queue_xmit;
index f55b9f7d93965ca46cc0516789f6e56f4fc938e6..d3f86646cb088b0fecbbd9edcd0b26c8b51bebd1 100644 (file)
@@ -173,18 +173,6 @@ static void qla4xxx_conn_stop(struct iscsi_cls_conn *conn, int flag)
                printk(KERN_ERR "iscsi: invalid stop flag %d\n", flag);
 }
 
-static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
-{
-       int i;
-       char *cp = buf;
-
-       for (i = 0; i < len; i++)
-               cp += sprintf(cp, "%02x%c", addr[i],
-                             i == (len - 1) ? '\n' : ':');
-       return cp - buf;
-}
-
-
 static int qla4xxx_host_get_param(struct Scsi_Host *shost,
                                  enum iscsi_host_param param, char *buf)
 {
@@ -193,7 +181,7 @@ static int qla4xxx_host_get_param(struct Scsi_Host *shost,
 
        switch (param) {
        case ISCSI_HOST_PARAM_HWADDRESS:
-               len = format_addr(buf, ha->my_mac, MAC_ADDR_LEN);
+               len = sysfs_format_mac(buf, ha->my_mac, MAC_ADDR_LEN);
                break;
        case ISCSI_HOST_PARAM_IPADDRESS:
                len = sprintf(buf, "%d.%d.%d.%d\n", ha->ip_address[0],
index 3e15918281719b5faddd5186314ab85ba8b52b05..370c78cc1cb562f20af68017489a78b6650374a0 100644 (file)
@@ -164,7 +164,7 @@ void
 scsi_netlink_exit(void)
 {
        if (scsi_nl_sock) {
-               sock_release(scsi_nl_sock->sk_socket);
+               netlink_kernel_release(scsi_nl_sock);
                netlink_unregister_notifier(&scsi_netlink_notifier);
        }
 
index ef0e74264880625ffc78687e1603c1823ca0c6f3..0d7b4e79415c6b141256e7f91328c12d2a86c56d 100644 (file)
@@ -1558,7 +1558,7 @@ static __init int iscsi_transport_init(void)
        return 0;
 
 release_nls:
-       sock_release(nls->sk_socket);
+       netlink_kernel_release(nls);
 unregister_session_class:
        transport_class_unregister(&iscsi_session_class);
 unregister_conn_class:
@@ -1573,7 +1573,7 @@ unregister_transport_class:
 static void __exit iscsi_transport_exit(void)
 {
        destroy_workqueue(iscsi_eh_timer_workq);
-       sock_release(nls->sk_socket);
+       netlink_kernel_release(nls);
        transport_class_unregister(&iscsi_connection_class);
        transport_class_unregister(&iscsi_session_class);
        transport_class_unregister(&iscsi_host_class);
index f145d8a4cfdeb0b629f5d36f7e64df3007db181b..1a31f7a72848d0cb8329c95c73b94f18efe27b51 100644 (file)
@@ -27,6 +27,8 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4329) },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
index 85a20546e82777c169cecafa1d65f7a52dd921f5..9028ed5715a1e11b778454583c48e97d4c7e8bdd 100644 (file)
@@ -872,14 +872,22 @@ EXPORT_SYMBOL(ssb_clockspeed);
 
 static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
 {
+       u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
+
        /* The REJECT bit changed position in TMSLOW between
         * Backplane revisions. */
-       switch (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV) {
+       switch (rev) {
        case SSB_IDLOW_SSBREV_22:
                return SSB_TMSLOW_REJECT_22;
        case SSB_IDLOW_SSBREV_23:
                return SSB_TMSLOW_REJECT_23;
+       case SSB_IDLOW_SSBREV_24:     /* TODO - find the proper REJECT bits */
+       case SSB_IDLOW_SSBREV_25:     /* same here */
+       case SSB_IDLOW_SSBREV_26:     /* same here */
+       case SSB_IDLOW_SSBREV_27:     /* same here */
+               return SSB_TMSLOW_REJECT_23;    /* this is a guess */
        default:
+               printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
                WARN_ON(1);
        }
        return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
index 0ab095c6581afb2a06ca8403374be1ef11ab17a6..b434df75047f3a2e2527d6715fdd195664475303 100644 (file)
@@ -212,29 +212,29 @@ static inline u8 ssb_crc8(u8 crc, u8 data)
        return t[crc ^ data];
 }
 
-static u8 ssb_sprom_crc(const u16 *sprom)
+static u8 ssb_sprom_crc(const u16 *sprom, u16 size)
 {
        int word;
        u8 crc = 0xFF;
 
-       for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) {
+       for (word = 0; word < size - 1; word++) {
                crc = ssb_crc8(crc, sprom[word] & 0x00FF);
                crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
        }
-       crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF);
+       crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
        crc ^= 0xFF;
 
        return crc;
 }
 
-static int sprom_check_crc(const u16 *sprom)
+static int sprom_check_crc(const u16 *sprom, u16 size)
 {
        u8 crc;
        u8 expected_crc;
        u16 tmp;
 
-       crc = ssb_sprom_crc(sprom);
-       tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC;
+       crc = ssb_sprom_crc(sprom, size);
+       tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC;
        expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
        if (crc != expected_crc)
                return -EPROTO;
@@ -246,8 +246,8 @@ static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
 {
        int i;
 
-       for (i = 0; i < SSB_SPROMSIZE_WORDS; i++)
-               sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2));
+       for (i = 0; i < bus->sprom_size; i++)
+               sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
 }
 
 static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
@@ -255,6 +255,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
        struct pci_dev *pdev = bus->host_pci;
        int i, err;
        u32 spromctl;
+       u16 size = bus->sprom_size;
 
        ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
        err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
@@ -266,12 +267,12 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
                goto err_ctlreg;
        ssb_printk(KERN_NOTICE PFX "[ 0%%");
        msleep(500);
-       for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
-               if (i == SSB_SPROMSIZE_WORDS / 4)
+       for (i = 0; i < size; i++) {
+               if (i == size / 4)
                        ssb_printk("25%%");
-               else if (i == SSB_SPROMSIZE_WORDS / 2)
+               else if (i == size / 2)
                        ssb_printk("50%%");
-               else if (i == (SSB_SPROMSIZE_WORDS / 4) * 3)
+               else if (i == (size * 3) / 4)
                        ssb_printk("75%%");
                else if (i % 2)
                        ssb_printk(".");
@@ -296,24 +297,53 @@ err_ctlreg:
        return err;
 }
 
-static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
+static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
+                              u16 mask, u16 shift)
+{
+       u16 v;
+       u8 gain;
+
+       v = in[SPOFF(SSB_SPROM1_AGAIN)];
+       gain = (v & mask) >> shift;
+       if (gain == 0xFF)
+               gain = 2; /* If unset use 2dBm */
+       if (sprom_revision == 1) {
+               /* Convert to Q5.2 */
+               gain <<= 2;
+       } else {
+               /* Q5.2 Fractional part is stored in 0xC0 */
+               gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
+       }
+
+       return (s8)gain;
+}
+
+static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
 {
        int i;
        u16 v;
+       s8 gain;
+       u16 loc[3];
 
-       SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
-       SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
-       SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
+       if (out->revision == 3) {                       /* rev 3 moved MAC */
+               loc[0] = SSB_SPROM3_IL0MAC;
+               loc[1] = SSB_SPROM3_ET0MAC;
+               loc[2] = SSB_SPROM3_ET1MAC;
+       } else {
+               loc[0] = SSB_SPROM1_IL0MAC;
+               loc[1] = SSB_SPROM1_ET0MAC;
+               loc[2] = SSB_SPROM1_ET1MAC;
+       }
        for (i = 0; i < 3; i++) {
-               v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
+               v = in[SPOFF(loc[0]) + i];
                *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
        }
        for (i = 0; i < 3; i++) {
-               v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
+               v = in[SPOFF(loc[1]) + i];
                *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
        }
        for (i = 0; i < 3; i++) {
-               v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
+               v = in[SPOFF(loc[2]) + i];
                *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
        }
        SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
@@ -324,9 +354,9 @@ static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
        SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
        SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
             SSB_SPROM1_BINF_CCODE_SHIFT);
-       SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
+       SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
             SSB_SPROM1_BINF_ANTA_SHIFT);
-       SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
+       SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
             SSB_SPROM1_BINF_ANTBG_SHIFT);
        SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
        SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
@@ -347,100 +377,108 @@ static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
             SSB_SPROM1_ITSSI_A_SHIFT);
        SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
        SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
-       SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
-       SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
-            SSB_SPROM1_AGAIN_BG_SHIFT);
-       for (i = 0; i < 4; i++) {
-               v = in[SPOFF(SSB_SPROM1_OEM) + i];
-               *(((__le16 *)out->oem) + i) = cpu_to_le16(v);
-       }
+       if (out->revision >= 2)
+               SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
+
+       /* Extract the antenna gain values. */
+       gain = r123_extract_antgain(out->revision, in,
+                                   SSB_SPROM1_AGAIN_BG,
+                                   SSB_SPROM1_AGAIN_BG_SHIFT);
+       out->antenna_gain.ghz24.a0 = gain;
+       out->antenna_gain.ghz24.a1 = gain;
+       out->antenna_gain.ghz24.a2 = gain;
+       out->antenna_gain.ghz24.a3 = gain;
+       gain = r123_extract_antgain(out->revision, in,
+                                   SSB_SPROM1_AGAIN_A,
+                                   SSB_SPROM1_AGAIN_A_SHIFT);
+       out->antenna_gain.ghz5.a0 = gain;
+       out->antenna_gain.ghz5.a1 = gain;
+       out->antenna_gain.ghz5.a2 = gain;
+       out->antenna_gain.ghz5.a3 = gain;
 }
 
-static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in)
+static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in)
 {
        int i;
        u16 v;
 
-       SPEX(boardflags_hi, SSB_SPROM2_BFLHI,  0xFFFF, 0);
-       SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
-       SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
-            SSB_SPROM2_MAXP_A_LO_SHIFT);
-       SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
-       SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
-       SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
-       SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
-       SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
-       SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
-       SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
-       for (i = 0; i < 4; i++) {
-               v = in[SPOFF(SSB_SPROM2_CCODE) + i];
-               *(((__le16 *)out->country_str) + i) = cpu_to_le16(v);
+       /* extract the equivalent of the r1 variables */
+       for (i = 0; i < 3; i++) {
+               v = in[SPOFF(SSB_SPROM4_IL0MAC) + i];
+               *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
        }
+       for (i = 0; i < 3; i++) {
+               v = in[SPOFF(SSB_SPROM4_ET0MAC) + i];
+               *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v);
+       }
+       for (i = 0; i < 3; i++) {
+               v = in[SPOFF(SSB_SPROM4_ET1MAC) + i];
+               *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v);
+       }
+       SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
+       SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
+            SSB_SPROM4_ETHPHY_ET1A_SHIFT);
+       SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
+       SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
+       SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
+       SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
+            SSB_SPROM4_ANTAVAIL_A_SHIFT);
+       SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
+            SSB_SPROM4_ANTAVAIL_BG_SHIFT);
+       SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
+       SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
+            SSB_SPROM4_ITSSI_BG_SHIFT);
+       SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
+       SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
+            SSB_SPROM4_ITSSI_A_SHIFT);
+       SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
+       SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
+            SSB_SPROM4_GPIOA_P1_SHIFT);
+       SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
+       SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
+            SSB_SPROM4_GPIOB_P3_SHIFT);
+
+       /* Extract the antenna gain values. */
+       SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
+            SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
+       SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
+            SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
+       SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
+            SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
+       SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
+            SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
+       memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
+              sizeof(out->antenna_gain.ghz5));
+
+       /* TODO - get remaining rev 4 stuff needed */
 }
 
-static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
-{
-       out->ofdmapo  = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8;
-       out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8;
-       out->ofdmapo <<= 16;
-       out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8;
-       out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8;
-
-       out->ofdmalpo  = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8;
-       out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8;
-       out->ofdmalpo <<= 16;
-       out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8;
-       out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8;
-
-       out->ofdmahpo  = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8;
-       out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8;
-       out->ofdmahpo <<= 16;
-       out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8;
-       out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8;
-
-       SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON,
-            SSB_SPROM3_GPIOLDC_ON_SHIFT);
-       SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF,
-            SSB_SPROM3_GPIOLDC_OFF_SHIFT);
-       SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0);
-       SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M,
-            SSB_SPROM3_CCKPO_2M_SHIFT);
-       SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M,
-            SSB_SPROM3_CCKPO_55M_SHIFT);
-       SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M,
-            SSB_SPROM3_CCKPO_11M_SHIFT);
-
-       out->ofdmgpo  = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8;
-       out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8;
-       out->ofdmgpo <<= 16;
-       out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8;
-       out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
-}
-
-static int sprom_extract(struct ssb_bus *bus,
-                        struct ssb_sprom *out, const u16 *in)
+static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out,
+                        const u16 *in, u16 size)
 {
        memset(out, 0, sizeof(*out));
 
-       SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0);
-       SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
-            SSB_SPROM_REVISION_CRC_SHIFT);
-
+       out->revision = in[size - 1] & 0x00FF;
+       ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
        if ((bus->chip_id & 0xFF00) == 0x4400) {
                /* Workaround: The BCM44XX chip has a stupid revision
                 * number stored in the SPROM.
                 * Always extract r1. */
-               sprom_extract_r1(&out->r1, in);
+               out->revision = 1;
+               sprom_extract_r123(out, in);
+       } else if (bus->chip_id == 0x4321) {
+               /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
+               out->revision = 4;
+               sprom_extract_r4(out, in);
        } else {
                if (out->revision == 0)
                        goto unsupported;
-               if (out->revision >= 1 && out->revision <= 3)
-                       sprom_extract_r1(&out->r1, in);
-               if (out->revision >= 2 && out->revision <= 3)
-                       sprom_extract_r2(&out->r2, in);
-               if (out->revision == 3)
-                       sprom_extract_r3(&out->r3, in);
-               if (out->revision >= 4)
+               if (out->revision >= 1 && out->revision <= 3) {
+                       sprom_extract_r123(out, in);
+               }
+               if (out->revision == 4)
+                       sprom_extract_r4(out, in);
+               if (out->revision >= 5)
                        goto unsupported;
        }
 
@@ -448,7 +486,7 @@ static int sprom_extract(struct ssb_bus *bus,
 unsupported:
        ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
                   "detected. Will extract v1\n", out->revision);
-       sprom_extract_r1(&out->r1, in);
+       sprom_extract_r123(out, in);
        return 0;
 }
 
@@ -458,16 +496,29 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
        int err = -ENOMEM;
        u16 *buf;
 
-       buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
+       buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
        if (!buf)
                goto out;
+       bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
        sprom_do_read(bus, buf);
-       err = sprom_check_crc(buf);
+       err = sprom_check_crc(buf, bus->sprom_size);
        if (err) {
-               ssb_printk(KERN_WARNING PFX
-                          "WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
+               /* check for rev 4 sprom - has special signature */
+               if (buf[32] == 0x5372) {
+                       kfree(buf);
+                       buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
+                                     GFP_KERNEL);
+                       if (!buf)
+                               goto out;
+                       bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
+                       sprom_do_read(bus, buf);
+                       err = sprom_check_crc(buf, bus->sprom_size);
+               }
+               if (err)
+                       ssb_printk(KERN_WARNING PFX "WARNING: Invalid"
+                                  " SPROM CRC (corrupt SPROM)\n");
        }
-       err = sprom_extract(bus, sprom, buf);
+       err = sprom_extract(bus, sprom, buf, bus->sprom_size);
 
        kfree(buf);
 out:
@@ -581,29 +632,28 @@ const struct ssb_bus_ops ssb_pci_ops = {
        .write32        = ssb_pci_write32,
 };
 
-static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
+static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, u16 size)
 {
        int i, pos = 0;
 
-       for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
+       for (i = 0; i < size; i++)
                pos += snprintf(buf + pos, buf_len - pos - 1,
                                "%04X", swab16(sprom[i]) & 0xFFFF);
-       }
        pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
 
        return pos + 1;
 }
 
-static int hex2sprom(u16 *sprom, const char *dump, size_t len)
+static int hex2sprom(u16 *sprom, const char *dump, size_t len, u16 size)
 {
        char tmp[5] = { 0 };
        int cnt = 0;
        unsigned long parsed;
 
-       if (len < SSB_SPROMSIZE_BYTES * 2)
+       if (len < size * 2)
                return -EINVAL;
 
-       while (cnt < SSB_SPROMSIZE_WORDS) {
+       while (cnt < size) {
                memcpy(tmp, dump, 4);
                dump += 4;
                parsed = simple_strtoul(tmp, NULL, 16);
@@ -627,7 +677,7 @@ static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
        if (!bus)
                goto out;
        err = -ENOMEM;
-       sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
+       sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
        if (!sprom)
                goto out;
 
@@ -640,7 +690,7 @@ static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
        sprom_do_read(bus, sprom);
        mutex_unlock(&bus->pci_sprom_mutex);
 
-       count = sprom2hex(sprom, buf, PAGE_SIZE);
+       count = sprom2hex(sprom, buf, PAGE_SIZE, bus->sprom_size);
        err = 0;
 
 out_kfree:
@@ -662,15 +712,15 @@ static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
        if (!bus)
                goto out;
        err = -ENOMEM;
-       sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
+       sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
        if (!sprom)
                goto out;
-       err = hex2sprom(sprom, buf, count);
+       err = hex2sprom(sprom, buf, count, bus->sprom_size);
        if (err) {
                err = -EINVAL;
                goto out_kfree;
        }
-       err = sprom_check_crc(sprom);
+       err = sprom_check_crc(sprom, bus->sprom_size);
        if (err) {
                err = -EINVAL;
                goto out_kfree;
index bb44a76b3eb5508d605869936e34857afbfc2e18..46816cda8b984411da0e9aceeb40baaab82f9c8c 100644 (file)
@@ -94,7 +94,6 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus,
                           struct ssb_device *dev)
 {
        int err;
-       unsigned long flags;
 
 #if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
        ssb_printk(KERN_INFO PFX
@@ -103,11 +102,9 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus,
                   dev->core_index);
 #endif
 
-       spin_lock_irqsave(&bus->bar_lock, flags);
        err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
        if (!err)
                bus->mapped_device = dev;
-       spin_unlock_irqrestore(&bus->bar_lock, flags);
 
        return err;
 }
@@ -115,14 +112,12 @@ int ssb_pcmcia_switch_core(struct ssb_bus *bus,
 int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
 {
        int attempts = 0;
-       unsigned long flags;
        conf_reg_t reg;
-       int res, err = 0;
+       int res;
 
        SSB_WARN_ON((seg != 0) && (seg != 1));
        reg.Offset = 0x34;
        reg.Function = 0;
-       spin_lock_irqsave(&bus->bar_lock, flags);
        while (1) {
                reg.Action = CS_WRITE;
                reg.Value = seg;
@@ -143,13 +138,11 @@ int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
                udelay(10);
        }
        bus->mapped_pcmcia_seg = seg;
-out_unlock:
-       spin_unlock_irqrestore(&bus->bar_lock, flags);
-       return err;
+
+       return 0;
 error:
        ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
-       err = -ENODEV;
-       goto out_unlock;
+       return -ENODEV;
 }
 
 static int select_core_and_segment(struct ssb_device *dev,
@@ -182,22 +175,33 @@ static int select_core_and_segment(struct ssb_device *dev,
 static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
+       unsigned long flags;
+       int err;
+       u16 value = 0xFFFF;
 
-       if (unlikely(select_core_and_segment(dev, &offset)))
-               return 0xFFFF;
+       spin_lock_irqsave(&bus->bar_lock, flags);
+       err = select_core_and_segment(dev, &offset);
+       if (likely(!err))
+               value = readw(bus->mmio + offset);
+       spin_unlock_irqrestore(&bus->bar_lock, flags);
 
-       return readw(bus->mmio + offset);
+       return value;
 }
 
 static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
 {
        struct ssb_bus *bus = dev->bus;
-       u32 lo, hi;
+       unsigned long flags;
+       int err;
+       u32 lo = 0xFFFFFFFF, hi = 0xFFFFFFFF;
 
-       if (unlikely(select_core_and_segment(dev, &offset)))
-               return 0xFFFFFFFF;
-       lo = readw(bus->mmio + offset);
-       hi = readw(bus->mmio + offset + 2);
+       spin_lock_irqsave(&bus->bar_lock, flags);
+       err = select_core_and_segment(dev, &offset);
+       if (likely(!err)) {
+               lo = readw(bus->mmio + offset);
+               hi = readw(bus->mmio + offset + 2);
+       }
+       spin_unlock_irqrestore(&bus->bar_lock, flags);
 
        return (lo | (hi << 16));
 }
@@ -205,22 +209,31 @@ static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
 static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
 {
        struct ssb_bus *bus = dev->bus;
+       unsigned long flags;
+       int err;
 
-       if (unlikely(select_core_and_segment(dev, &offset)))
-               return;
-       writew(value, bus->mmio + offset);
+       spin_lock_irqsave(&bus->bar_lock, flags);
+       err = select_core_and_segment(dev, &offset);
+       if (likely(!err))
+               writew(value, bus->mmio + offset);
+       mmiowb();
+       spin_unlock_irqrestore(&bus->bar_lock, flags);
 }
 
 static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
 {
        struct ssb_bus *bus = dev->bus;
+       unsigned long flags;
+       int err;
 
-       if (unlikely(select_core_and_segment(dev, &offset)))
-               return;
-       writeb((value & 0xFF000000) >> 24, bus->mmio + offset + 3);
-       writeb((value & 0x00FF0000) >> 16, bus->mmio + offset + 2);
-       writeb((value & 0x0000FF00) >> 8, bus->mmio + offset + 1);
-       writeb((value & 0x000000FF) >> 0, bus->mmio + offset + 0);
+       spin_lock_irqsave(&bus->bar_lock, flags);
+       err = select_core_and_segment(dev, &offset);
+       if (likely(!err)) {
+               writew((value & 0x0000FFFF), bus->mmio + offset);
+               writew(((value & 0xFFFF0000) >> 16), bus->mmio + offset + 2);
+       }
+       mmiowb();
+       spin_unlock_irqrestore(&bus->bar_lock, flags);
 }
 
 /* Not "static", as it's used in main.c */
@@ -231,10 +244,12 @@ const struct ssb_bus_ops ssb_pcmcia_ops = {
        .write32        = ssb_pcmcia_write32,
 };
 
+#include <linux/etherdevice.h>
 int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
                              struct ssb_init_invariants *iv)
 {
        //TODO
+       random_ether_addr(iv->sprom.il0mac);
        return 0;
 }
 
index 9aa345121e09cf2bf2f600259f95a03557f85de3..f638a698dc525350bc44054f567217d52c0fca71 100644 (file)
@@ -237,7 +237,6 @@ out:
  */
 void ecryptfs_release_netlink(void)
 {
-       if (ecryptfs_nl_sock && ecryptfs_nl_sock->sk_socket)
-               sock_release(ecryptfs_nl_sock->sk_socket);
+       netlink_kernel_release(ecryptfs_nl_sock);
        ecryptfs_nl_sock = NULL;
 }
index 0afe21ee0607e6b5fe883ad5a3c93a8742d8b585..4823c9677facf0790ccf0971f516d253ef43f093 100644 (file)
 #include <linux/mount.h>
 #include <linux/nsproxy.h>
 #include <net/net_namespace.h>
+#include <linux/seq_file.h>
 
 #include "internal.h"
 
 
+int seq_open_net(struct inode *ino, struct file *f,
+                const struct seq_operations *ops, int size)
+{
+       struct net *net;
+       struct seq_net_private *p;
+
+       BUG_ON(size < sizeof(*p));
+
+       net = get_proc_net(ino);
+       if (net == NULL)
+               return -ENXIO;
+
+       p = __seq_open_private(f, ops, size);
+       if (p == NULL) {
+               put_net(net);
+               return -ENOMEM;
+       }
+       p->net = net;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(seq_open_net);
+
+int seq_release_net(struct inode *ino, struct file *f)
+{
+       struct seq_file *seq;
+       struct seq_net_private *p;
+
+       seq = f->private_data;
+       p = seq->private;
+
+       put_net(p->net);
+       seq_release_private(ino, f);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(seq_release_net);
+
+
 struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops)
 {
@@ -58,6 +96,17 @@ static struct proc_dir_entry *proc_net_shadow(struct task_struct *task,
        return task->nsproxy->net_ns->proc_net;
 }
 
+struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+               struct proc_dir_entry *parent)
+{
+       struct proc_dir_entry *pde;
+       pde = proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
+       if (pde != NULL)
+               pde->data = net;
+       return pde;
+}
+EXPORT_SYMBOL_GPL(proc_net_mkdir);
+
 static __net_init int proc_net_ns_init(struct net *net)
 {
        struct proc_dir_entry *root, *netd, *net_statd;
@@ -69,18 +118,16 @@ static __net_init int proc_net_ns_init(struct net *net)
                goto out;
 
        err = -EEXIST;
-       netd = proc_mkdir("net", root);
+       netd = proc_net_mkdir(net, "net", root);
        if (!netd)
                goto free_root;
 
        err = -EEXIST;
-       net_statd = proc_mkdir("stat", netd);
+       net_statd = proc_net_mkdir(net, "stat", netd);
        if (!net_statd)
                goto free_net;
 
        root->data = net;
-       netd->data = net;
-       net_statd->data = net;
 
        net->proc_net_root = root;
        net->proc_net = netd;
index 56b802bfbfa4879021cc2af03f175e69cec621d8..0a0b79b01d059a1c71b632de1807100578be8269 100644 (file)
@@ -254,11 +254,16 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
        }
 
        while (page_nr < spd_pages)
-               page_cache_release(spd->pages[page_nr++]);
+               spd->spd_release(spd, page_nr++);
 
        return ret;
 }
 
+static void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
+{
+       page_cache_release(spd->pages[i]);
+}
+
 static int
 __generic_file_splice_read(struct file *in, loff_t *ppos,
                           struct pipe_inode_info *pipe, size_t len,
@@ -277,6 +282,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                .partial = partial,
                .flags = flags,
                .ops = &page_cache_pipe_buf_ops,
+               .spd_release = spd_release_page,
        };
 
        index = *ppos >> PAGE_CACHE_SHIFT;
@@ -1432,6 +1438,7 @@ static long vmsplice_to_pipe(struct file *file, const struct iovec __user *iov,
                .partial = partial,
                .flags = flags,
                .ops = &user_page_pipe_buf_ops,
+               .spd_release = spd_release_page,
        };
 
        pipe = pipe_info(file->f_path.dentry->d_inode);
diff --git a/include/asm-powerpc/pasemi_dma.h b/include/asm-powerpc/pasemi_dma.h
new file mode 100644 (file)
index 0000000..b4526ff
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Hardware register layout and descriptor formats for the on-board
+ * DMA engine on PA Semi PWRficient. Used by ethernet, function and security
+ * drivers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef ASM_PASEMI_DMA_H
+#define ASM_PASEMI_DMA_H
+
+/* status register layout in IOB region, at 0xfb800000 */
+struct pasdma_status {
+       u64 rx_sta[64];         /* RX channel status */
+       u64 tx_sta[20];         /* TX channel status */
+};
+
+
+/* All these registers live in the PCI configuration space for the DMA PCI
+ * device. Use the normal PCI config access functions for them.
+ */
+enum {
+       PAS_DMA_CAP_TXCH  = 0x44,       /* Transmit Channel Info      */
+       PAS_DMA_CAP_RXCH  = 0x48,       /* Transmit Channel Info      */
+       PAS_DMA_CAP_IFI   = 0x4c,       /* Interface Info             */
+       PAS_DMA_COM_TXCMD = 0x100,      /* Transmit Command Register  */
+       PAS_DMA_COM_TXSTA = 0x104,      /* Transmit Status Register   */
+       PAS_DMA_COM_RXCMD = 0x108,      /* Receive Command Register   */
+       PAS_DMA_COM_RXSTA = 0x10c,      /* Receive Status Register    */
+};
+
+
+#define PAS_DMA_CAP_TXCH_TCHN_M        0x00ff0000 /* # of TX channels */
+#define PAS_DMA_CAP_TXCH_TCHN_S        16
+
+#define PAS_DMA_CAP_RXCH_RCHN_M        0x00ff0000 /* # of RX channels */
+#define PAS_DMA_CAP_RXCH_RCHN_S        16
+
+#define PAS_DMA_CAP_IFI_IOFF_M 0xff000000 /* Cfg reg for intf pointers */
+#define PAS_DMA_CAP_IFI_IOFF_S 24
+#define PAS_DMA_CAP_IFI_NIN_M  0x00ff0000 /* # of interfaces */
+#define PAS_DMA_CAP_IFI_NIN_S  16
+
+#define PAS_DMA_COM_TXCMD_EN   0x00000001 /* enable */
+#define PAS_DMA_COM_TXSTA_ACT  0x00000001 /* active */
+#define PAS_DMA_COM_RXCMD_EN   0x00000001 /* enable */
+#define PAS_DMA_COM_RXSTA_ACT  0x00000001 /* active */
+
+
+/* Per-interface and per-channel registers */
+#define _PAS_DMA_RXINT_STRIDE          0x20
+#define PAS_DMA_RXINT_RCMDSTA(i)       (0x200+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_RCMDSTA_EN    0x00000001
+#define    PAS_DMA_RXINT_RCMDSTA_ST    0x00000002
+#define    PAS_DMA_RXINT_RCMDSTA_MBT   0x00000008
+#define    PAS_DMA_RXINT_RCMDSTA_MDR   0x00000010
+#define    PAS_DMA_RXINT_RCMDSTA_MOO   0x00000020
+#define    PAS_DMA_RXINT_RCMDSTA_MBP   0x00000040
+#define    PAS_DMA_RXINT_RCMDSTA_BT    0x00000800
+#define    PAS_DMA_RXINT_RCMDSTA_DR    0x00001000
+#define    PAS_DMA_RXINT_RCMDSTA_OO    0x00002000
+#define    PAS_DMA_RXINT_RCMDSTA_BP    0x00004000
+#define    PAS_DMA_RXINT_RCMDSTA_TB    0x00008000
+#define    PAS_DMA_RXINT_RCMDSTA_ACT   0x00010000
+#define    PAS_DMA_RXINT_RCMDSTA_DROPS_M       0xfffe0000
+#define    PAS_DMA_RXINT_RCMDSTA_DROPS_S       17
+#define PAS_DMA_RXINT_CFG(i)           (0x204+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_CFG_RBP       0x80000000
+#define    PAS_DMA_RXINT_CFG_ITRR      0x40000000
+#define    PAS_DMA_RXINT_CFG_DHL_M     0x07000000
+#define    PAS_DMA_RXINT_CFG_DHL_S     24
+#define    PAS_DMA_RXINT_CFG_DHL(x)    (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
+                                        PAS_DMA_RXINT_CFG_DHL_M)
+#define    PAS_DMA_RXINT_CFG_ITR       0x00400000
+#define    PAS_DMA_RXINT_CFG_LW                0x00200000
+#define    PAS_DMA_RXINT_CFG_L2                0x00100000
+#define    PAS_DMA_RXINT_CFG_HEN       0x00080000
+#define    PAS_DMA_RXINT_CFG_WIF       0x00000002
+#define    PAS_DMA_RXINT_CFG_WIL       0x00000001
+
+#define PAS_DMA_RXINT_INCR(i)          (0x210+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_INCR_INCR_M   0x0000ffff
+#define    PAS_DMA_RXINT_INCR_INCR_S   0
+#define    PAS_DMA_RXINT_INCR_INCR(x)  ((x) & 0x0000ffff)
+#define PAS_DMA_RXINT_BASEL(i)         (0x218+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_BASEL_BRBL(x) ((x) & ~0x3f)
+#define PAS_DMA_RXINT_BASEU(i)         (0x21c+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_BASEU_BRBH(x) ((x) & 0xfff)
+#define    PAS_DMA_RXINT_BASEU_SIZ_M   0x3fff0000      /* # of cache lines worth of buffer ring */
+#define    PAS_DMA_RXINT_BASEU_SIZ_S   16              /* 0 = 16K */
+#define    PAS_DMA_RXINT_BASEU_SIZ(x)  (((x) << PAS_DMA_RXINT_BASEU_SIZ_S) & \
+                                        PAS_DMA_RXINT_BASEU_SIZ_M)
+
+
+#define _PAS_DMA_TXCHAN_STRIDE 0x20    /* Size per channel             */
+#define _PAS_DMA_TXCHAN_TCMDSTA        0x300   /* Command / Status             */
+#define _PAS_DMA_TXCHAN_CFG    0x304   /* Configuration                */
+#define _PAS_DMA_TXCHAN_DSCRBU 0x308   /* Descriptor BU Allocation     */
+#define _PAS_DMA_TXCHAN_INCR   0x310   /* Descriptor increment         */
+#define _PAS_DMA_TXCHAN_CNT    0x314   /* Descriptor count/offset      */
+#define _PAS_DMA_TXCHAN_BASEL  0x318   /* Descriptor ring base (low)   */
+#define _PAS_DMA_TXCHAN_BASEU  0x31c   /*                      (high)  */
+#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
+#define    PAS_DMA_TXCHAN_TCMDSTA_EN   0x00000001      /* Enabled */
+#define    PAS_DMA_TXCHAN_TCMDSTA_ST   0x00000002      /* Stop interface */
+#define    PAS_DMA_TXCHAN_TCMDSTA_ACT  0x00010000      /* Active */
+#define    PAS_DMA_TXCHAN_TCMDSTA_SZ   0x00000800
+#define    PAS_DMA_TXCHAN_TCMDSTA_DB   0x00000400
+#define    PAS_DMA_TXCHAN_TCMDSTA_DE   0x00000200
+#define    PAS_DMA_TXCHAN_TCMDSTA_DA   0x00000100
+#define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
+#define    PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000      /* Type = interface */
+#define    PAS_DMA_TXCHAN_CFG_TATTR_M  0x0000003c
+#define    PAS_DMA_TXCHAN_CFG_TATTR_S  2
+#define    PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
+                                        PAS_DMA_TXCHAN_CFG_TATTR_M)
+#define    PAS_DMA_TXCHAN_CFG_WT_M     0x000001c0
+#define    PAS_DMA_TXCHAN_CFG_WT_S     6
+#define    PAS_DMA_TXCHAN_CFG_WT(x)    (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
+                                        PAS_DMA_TXCHAN_CFG_WT_M)
+#define    PAS_DMA_TXCHAN_CFG_TRD      0x00010000      /* translate data */
+#define    PAS_DMA_TXCHAN_CFG_TRR      0x00008000      /* translate rings */
+#define    PAS_DMA_TXCHAN_CFG_UP       0x00004000      /* update tx descr when sent */
+#define    PAS_DMA_TXCHAN_CFG_CL       0x00002000      /* Clean last line */
+#define    PAS_DMA_TXCHAN_CFG_CF       0x00001000      /* Clean first line */
+#define PAS_DMA_TXCHAN_INCR(c)    (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
+#define PAS_DMA_TXCHAN_BASEL(c)   (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
+#define    PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
+#define    PAS_DMA_TXCHAN_BASEL_BRBL_S 0
+#define    PAS_DMA_TXCHAN_BASEL_BRBL(x)        (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
+                                        PAS_DMA_TXCHAN_BASEL_BRBL_M)
+#define PAS_DMA_TXCHAN_BASEU(c)   (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
+#define    PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
+#define    PAS_DMA_TXCHAN_BASEU_BRBH_S 0
+#define    PAS_DMA_TXCHAN_BASEU_BRBH(x)        (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
+                                        PAS_DMA_TXCHAN_BASEU_BRBH_M)
+/* # of cache lines worth of buffer ring */
+#define    PAS_DMA_TXCHAN_BASEU_SIZ_M  0x3fff0000
+#define    PAS_DMA_TXCHAN_BASEU_SIZ_S  16              /* 0 = 16K */
+#define    PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
+                                        PAS_DMA_TXCHAN_BASEU_SIZ_M)
+
+#define _PAS_DMA_RXCHAN_STRIDE 0x20    /* Size per channel             */
+#define _PAS_DMA_RXCHAN_CCMDSTA        0x800   /* Command / Status             */
+#define _PAS_DMA_RXCHAN_CFG    0x804   /* Configuration                */
+#define _PAS_DMA_RXCHAN_INCR   0x810   /* Descriptor increment         */
+#define _PAS_DMA_RXCHAN_CNT    0x814   /* Descriptor count/offset      */
+#define _PAS_DMA_RXCHAN_BASEL  0x818   /* Descriptor ring base (low)   */
+#define _PAS_DMA_RXCHAN_BASEU  0x81c   /*                      (high)  */
+#define PAS_DMA_RXCHAN_CCMDSTA(c) (0x800+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define    PAS_DMA_RXCHAN_CCMDSTA_EN   0x00000001      /* Enabled */
+#define    PAS_DMA_RXCHAN_CCMDSTA_ST   0x00000002      /* Stop interface */
+#define    PAS_DMA_RXCHAN_CCMDSTA_ACT  0x00010000      /* Active */
+#define    PAS_DMA_RXCHAN_CCMDSTA_DU   0x00020000
+#define    PAS_DMA_RXCHAN_CCMDSTA_OD   0x00002000
+#define    PAS_DMA_RXCHAN_CCMDSTA_FD   0x00001000
+#define    PAS_DMA_RXCHAN_CCMDSTA_DT   0x00000800
+#define PAS_DMA_RXCHAN_CFG(c)     (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define    PAS_DMA_RXCHAN_CFG_CTR      0x00000400
+#define    PAS_DMA_RXCHAN_CFG_HBU_M    0x00000380
+#define    PAS_DMA_RXCHAN_CFG_HBU_S    7
+#define    PAS_DMA_RXCHAN_CFG_HBU(x)   (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \
+                                        PAS_DMA_RXCHAN_CFG_HBU_M)
+#define PAS_DMA_RXCHAN_INCR(c)    (0x810+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define PAS_DMA_RXCHAN_BASEL(c)   (0x818+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define    PAS_DMA_RXCHAN_BASEL_BRBL_M 0xffffffc0
+#define    PAS_DMA_RXCHAN_BASEL_BRBL_S 0
+#define    PAS_DMA_RXCHAN_BASEL_BRBL(x)        (((x) << PAS_DMA_RXCHAN_BASEL_BRBL_S) & \
+                                        PAS_DMA_RXCHAN_BASEL_BRBL_M)
+#define PAS_DMA_RXCHAN_BASEU(c)   (0x81c+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define    PAS_DMA_RXCHAN_BASEU_BRBH_M 0x00000fff
+#define    PAS_DMA_RXCHAN_BASEU_BRBH_S 0
+#define    PAS_DMA_RXCHAN_BASEU_BRBH(x)        (((x) << PAS_DMA_RXCHAN_BASEU_BRBH_S) & \
+                                        PAS_DMA_RXCHAN_BASEU_BRBH_M)
+/* # of cache lines worth of buffer ring */
+#define    PAS_DMA_RXCHAN_BASEU_SIZ_M  0x3fff0000
+#define    PAS_DMA_RXCHAN_BASEU_SIZ_S  16              /* 0 = 16K */
+#define    PAS_DMA_RXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_RXCHAN_BASEU_SIZ_S) & \
+                                        PAS_DMA_RXCHAN_BASEU_SIZ_M)
+
+#define    PAS_STATUS_PCNT_M           0x000000000000ffffull
+#define    PAS_STATUS_PCNT_S           0
+#define    PAS_STATUS_DCNT_M           0x00000000ffff0000ull
+#define    PAS_STATUS_DCNT_S           16
+#define    PAS_STATUS_BPCNT_M          0x0000ffff00000000ull
+#define    PAS_STATUS_BPCNT_S          32
+#define    PAS_STATUS_CAUSE_M          0xf000000000000000ull
+#define    PAS_STATUS_TIMER            0x1000000000000000ull
+#define    PAS_STATUS_ERROR            0x2000000000000000ull
+#define    PAS_STATUS_SOFT             0x4000000000000000ull
+#define    PAS_STATUS_INT              0x8000000000000000ull
+
+#define PAS_IOB_COM_PKTHDRCNT          0x120
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_M     0x0fff0000
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_S     16
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_M     0x00000fff
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_S     0
+
+#define PAS_IOB_DMA_RXCH_CFG(i)                (0x1100 + (i)*4)
+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_M                0x00000fff
+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH_S                0
+#define    PAS_IOB_DMA_RXCH_CFG_CNTTH(x)       (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
+                                                PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
+#define PAS_IOB_DMA_TXCH_CFG(i)                (0x1200 + (i)*4)
+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_M                0x00000fff
+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH_S                0
+#define    PAS_IOB_DMA_TXCH_CFG_CNTTH(x)       (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
+                                                PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
+#define PAS_IOB_DMA_RXCH_STAT(i)       (0x1300 + (i)*4)
+#define    PAS_IOB_DMA_RXCH_STAT_INTGEN        0x00001000
+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_M      0x00000fff
+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL_S      0
+#define    PAS_IOB_DMA_RXCH_STAT_CNTDEL(x)     (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
+                                                PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
+#define PAS_IOB_DMA_TXCH_STAT(i)       (0x1400 + (i)*4)
+#define    PAS_IOB_DMA_TXCH_STAT_INTGEN        0x00001000
+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_M      0x00000fff
+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL_S      0
+#define    PAS_IOB_DMA_TXCH_STAT_CNTDEL(x)     (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
+                                                PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
+#define PAS_IOB_DMA_RXCH_RESET(i)      (0x1500 + (i)*4)
+#define    PAS_IOB_DMA_RXCH_RESET_PCNT_M       0xffff0000
+#define    PAS_IOB_DMA_RXCH_RESET_PCNT_S       16
+#define    PAS_IOB_DMA_RXCH_RESET_PCNT(x)      (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
+                                                PAS_IOB_DMA_RXCH_RESET_PCNT_M)
+#define    PAS_IOB_DMA_RXCH_RESET_PCNTRST      0x00000020
+#define    PAS_IOB_DMA_RXCH_RESET_DCNTRST      0x00000010
+#define    PAS_IOB_DMA_RXCH_RESET_TINTC                0x00000008
+#define    PAS_IOB_DMA_RXCH_RESET_DINTC                0x00000004
+#define    PAS_IOB_DMA_RXCH_RESET_SINTC                0x00000002
+#define    PAS_IOB_DMA_RXCH_RESET_PINTC                0x00000001
+#define PAS_IOB_DMA_TXCH_RESET(i)      (0x1600 + (i)*4)
+#define    PAS_IOB_DMA_TXCH_RESET_PCNT_M       0xffff0000
+#define    PAS_IOB_DMA_TXCH_RESET_PCNT_S       16
+#define    PAS_IOB_DMA_TXCH_RESET_PCNT(x)      (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
+                                                PAS_IOB_DMA_TXCH_RESET_PCNT_M)
+#define    PAS_IOB_DMA_TXCH_RESET_PCNTRST      0x00000020
+#define    PAS_IOB_DMA_TXCH_RESET_DCNTRST      0x00000010
+#define    PAS_IOB_DMA_TXCH_RESET_TINTC                0x00000008
+#define    PAS_IOB_DMA_TXCH_RESET_DINTC                0x00000004
+#define    PAS_IOB_DMA_TXCH_RESET_SINTC                0x00000002
+#define    PAS_IOB_DMA_TXCH_RESET_PINTC                0x00000001
+
+#define PAS_IOB_DMA_COM_TIMEOUTCFG             0x1700
+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M   0x00ffffff
+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S   0
+#define    PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x)  (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
+                                                PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
+
+/* Transmit descriptor fields */
+#define        XCT_MACTX_T             0x8000000000000000ull
+#define        XCT_MACTX_ST            0x4000000000000000ull
+#define XCT_MACTX_NORES                0x0000000000000000ull
+#define XCT_MACTX_8BRES                0x1000000000000000ull
+#define XCT_MACTX_24BRES       0x2000000000000000ull
+#define XCT_MACTX_40BRES       0x3000000000000000ull
+#define XCT_MACTX_I            0x0800000000000000ull
+#define XCT_MACTX_O            0x0400000000000000ull
+#define XCT_MACTX_E            0x0200000000000000ull
+#define XCT_MACTX_VLAN_M       0x0180000000000000ull
+#define XCT_MACTX_VLAN_NOP     0x0000000000000000ull
+#define XCT_MACTX_VLAN_REMOVE  0x0080000000000000ull
+#define XCT_MACTX_VLAN_INSERT   0x0100000000000000ull
+#define XCT_MACTX_VLAN_REPLACE  0x0180000000000000ull
+#define XCT_MACTX_CRC_M                0x0060000000000000ull
+#define XCT_MACTX_CRC_NOP      0x0000000000000000ull
+#define XCT_MACTX_CRC_INSERT   0x0020000000000000ull
+#define XCT_MACTX_CRC_PAD      0x0040000000000000ull
+#define XCT_MACTX_CRC_REPLACE  0x0060000000000000ull
+#define XCT_MACTX_SS           0x0010000000000000ull
+#define XCT_MACTX_LLEN_M       0x00007fff00000000ull
+#define XCT_MACTX_LLEN_S       32ull
+#define XCT_MACTX_LLEN(x)      ((((long)(x)) << XCT_MACTX_LLEN_S) & \
+                                XCT_MACTX_LLEN_M)
+#define XCT_MACTX_IPH_M                0x00000000f8000000ull
+#define XCT_MACTX_IPH_S                27ull
+#define XCT_MACTX_IPH(x)       ((((long)(x)) << XCT_MACTX_IPH_S) & \
+                                XCT_MACTX_IPH_M)
+#define XCT_MACTX_IPO_M                0x0000000007c00000ull
+#define XCT_MACTX_IPO_S                22ull
+#define XCT_MACTX_IPO(x)       ((((long)(x)) << XCT_MACTX_IPO_S) & \
+                                XCT_MACTX_IPO_M)
+#define XCT_MACTX_CSUM_M       0x0000000000000060ull
+#define XCT_MACTX_CSUM_NOP     0x0000000000000000ull
+#define XCT_MACTX_CSUM_TCP     0x0000000000000040ull
+#define XCT_MACTX_CSUM_UDP     0x0000000000000060ull
+#define XCT_MACTX_V6           0x0000000000000010ull
+#define XCT_MACTX_C            0x0000000000000004ull
+#define XCT_MACTX_AL2          0x0000000000000002ull
+
+/* Receive descriptor fields */
+#define        XCT_MACRX_T             0x8000000000000000ull
+#define        XCT_MACRX_ST            0x4000000000000000ull
+#define XCT_MACRX_RR_M         0x3000000000000000ull
+#define XCT_MACRX_RR_NORES     0x0000000000000000ull
+#define XCT_MACRX_RR_8BRES     0x1000000000000000ull
+#define XCT_MACRX_O            0x0400000000000000ull
+#define XCT_MACRX_E            0x0200000000000000ull
+#define XCT_MACRX_FF           0x0100000000000000ull
+#define XCT_MACRX_PF           0x0080000000000000ull
+#define XCT_MACRX_OB           0x0040000000000000ull
+#define XCT_MACRX_OD           0x0020000000000000ull
+#define XCT_MACRX_FS           0x0010000000000000ull
+#define XCT_MACRX_NB_M         0x000fc00000000000ull
+#define XCT_MACRX_NB_S         46ULL
+#define XCT_MACRX_NB(x)                ((((long)(x)) << XCT_MACRX_NB_S) & \
+                                XCT_MACRX_NB_M)
+#define XCT_MACRX_LLEN_M       0x00003fff00000000ull
+#define XCT_MACRX_LLEN_S       32ULL
+#define XCT_MACRX_LLEN(x)      ((((long)(x)) << XCT_MACRX_LLEN_S) & \
+                                XCT_MACRX_LLEN_M)
+#define XCT_MACRX_CRC          0x0000000080000000ull
+#define XCT_MACRX_LEN_M                0x0000000060000000ull
+#define XCT_MACRX_LEN_TOOSHORT 0x0000000020000000ull
+#define XCT_MACRX_LEN_BELOWMIN 0x0000000040000000ull
+#define XCT_MACRX_LEN_TRUNC    0x0000000060000000ull
+#define XCT_MACRX_CAST_M       0x0000000018000000ull
+#define XCT_MACRX_CAST_UNI     0x0000000000000000ull
+#define XCT_MACRX_CAST_MULTI   0x0000000008000000ull
+#define XCT_MACRX_CAST_BROAD   0x0000000010000000ull
+#define XCT_MACRX_CAST_PAUSE   0x0000000018000000ull
+#define XCT_MACRX_VLC_M                0x0000000006000000ull
+#define XCT_MACRX_FM           0x0000000001000000ull
+#define XCT_MACRX_HTY_M                0x0000000000c00000ull
+#define XCT_MACRX_HTY_IPV4_OK  0x0000000000000000ull
+#define XCT_MACRX_HTY_IPV6     0x0000000000400000ull
+#define XCT_MACRX_HTY_IPV4_BAD 0x0000000000800000ull
+#define XCT_MACRX_HTY_NONIP    0x0000000000c00000ull
+#define XCT_MACRX_IPP_M                0x00000000003f0000ull
+#define XCT_MACRX_IPP_S                16
+#define XCT_MACRX_CSUM_M       0x000000000000ffffull
+#define XCT_MACRX_CSUM_S       0
+
+#define XCT_PTR_T              0x8000000000000000ull
+#define XCT_PTR_LEN_M          0x7ffff00000000000ull
+#define XCT_PTR_LEN_S          44
+#define XCT_PTR_LEN(x)         ((((long)(x)) << XCT_PTR_LEN_S) & \
+                                XCT_PTR_LEN_M)
+#define XCT_PTR_ADDR_M         0x00000fffffffffffull
+#define XCT_PTR_ADDR_S         0
+#define XCT_PTR_ADDR(x)                ((((long)(x)) << XCT_PTR_ADDR_S) & \
+                                XCT_PTR_ADDR_M)
+
+/* Receive interface 8byte result fields */
+#define XCT_RXRES_8B_L4O_M     0xff00000000000000ull
+#define XCT_RXRES_8B_L4O_S     56
+#define XCT_RXRES_8B_RULE_M    0x00ffff0000000000ull
+#define XCT_RXRES_8B_RULE_S    40
+#define XCT_RXRES_8B_EVAL_M    0x000000ffff000000ull
+#define XCT_RXRES_8B_EVAL_S    24
+#define XCT_RXRES_8B_HTYPE_M   0x0000000000f00000ull
+#define XCT_RXRES_8B_HASH_M    0x00000000000fffffull
+#define XCT_RXRES_8B_HASH_S    0
+
+/* Receive interface buffer fields */
+#define XCT_RXB_LEN_M          0x0ffff00000000000ull
+#define XCT_RXB_LEN_S          44
+#define XCT_RXB_LEN(x)         ((((long)(x)) << XCT_RXB_LEN_S) & \
+                                XCT_RXB_LEN_M)
+#define XCT_RXB_ADDR_M         0x00000fffffffffffull
+#define XCT_RXB_ADDR_S         0
+#define XCT_RXB_ADDR(x)                ((((long)(x)) << XCT_RXB_ADDR_S) & \
+                                XCT_RXB_ADDR_M)
+
+/* Copy descriptor fields */
+#define XCT_COPY_T             0x8000000000000000ull
+#define XCT_COPY_ST            0x4000000000000000ull
+#define XCT_COPY_RR_M          0x3000000000000000ull
+#define XCT_COPY_RR_NORES      0x0000000000000000ull
+#define XCT_COPY_RR_8BRES      0x1000000000000000ull
+#define XCT_COPY_RR_24BRES     0x2000000000000000ull
+#define XCT_COPY_RR_40BRES     0x3000000000000000ull
+#define XCT_COPY_I             0x0800000000000000ull
+#define XCT_COPY_O             0x0400000000000000ull
+#define XCT_COPY_E             0x0200000000000000ull
+#define XCT_COPY_STY_ZERO      0x01c0000000000000ull
+#define XCT_COPY_DTY_PREF      0x0038000000000000ull
+#define XCT_COPY_LLEN_M                0x0007ffff00000000ull
+#define XCT_COPY_LLEN_S                32
+#define XCT_COPY_LLEN(x)       ((((long)(x)) << XCT_COPY_LLEN_S) & \
+                                XCT_COPY_LLEN_M)
+#define XCT_COPY_SE            0x0000000000000001ull
+
+/* Control descriptor fields */
+#define CTRL_CMD_T             0x8000000000000000ull
+#define CTRL_CMD_META_EVT      0x2000000000000000ull
+#define CTRL_CMD_O             0x0400000000000000ull
+#define CTRL_CMD_REG_M         0x000000000000000full
+#define CTRL_CMD_REG_S         0
+#define CTRL_CMD_REG(x)                ((((long)(x)) << CTRL_CMD_REG_S) & \
+                                CTRL_CMD_REG_M)
+
+
+
+/* Prototypes for the shared DMA functions in the platform code. */
+
+/* DMA TX Channel type. Right now only limitations used are event types 0/1,
+ * for event-triggered DMA transactions.
+ */
+
+enum pasemi_dmachan_type {
+       RXCHAN = 0,             /* Any RX chan */
+       TXCHAN = 1,             /* Any TX chan */
+       TXCHAN_EVT0 = 0x1001,   /* TX chan in event class 0 (chan 0-9) */
+       TXCHAN_EVT1 = 0x2001,   /* TX chan in event class 1 (chan 10-19) */
+};
+
+struct pasemi_dmachan {
+       int              chno;          /* Channel number */
+       enum pasemi_dmachan_type chan_type;     /* TX / RX */
+       u64             *status;        /* Ptr to cacheable status */
+       int              irq;           /* IRQ used by channel */
+       unsigned int     ring_size;     /* size of allocated ring */
+       dma_addr_t       ring_dma;      /* DMA address for ring */
+       u64             *ring_virt;     /* Virt address for ring */
+       void            *priv;          /* Ptr to start of client struct */
+};
+
+/* Read/write the different registers in the I/O Bridge, Ethernet
+ * and DMA Controller
+ */
+extern unsigned int pasemi_read_iob_reg(unsigned int reg);
+extern void pasemi_write_iob_reg(unsigned int reg, unsigned int val);
+
+extern unsigned int pasemi_read_mac_reg(int intf, unsigned int reg);
+extern void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val);
+
+extern unsigned int pasemi_read_dma_reg(unsigned int reg);
+extern void pasemi_write_dma_reg(unsigned int reg, unsigned int val);
+
+/* Channel management routines */
+
+extern void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
+                                  int total_size, int offset);
+extern void pasemi_dma_free_chan(struct pasemi_dmachan *chan);
+
+extern void pasemi_dma_start_chan(const struct pasemi_dmachan *chan,
+                                 const u32 cmdsta);
+extern int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan);
+
+/* Common routines to allocate rings and buffers */
+
+extern int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size);
+extern void pasemi_dma_free_ring(struct pasemi_dmachan *chan);
+
+extern void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
+                                 dma_addr_t *handle);
+extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
+                               dma_addr_t *handle);
+
+/* Initialize the library, must be called before any other functions */
+extern int pasemi_dma_init(void);
+
+#endif /* ASM_PASEMI_DMA_H */
index ad99ce9f916960063e521d05017dace2f551f79f..27b9350052b46dd7ed8a848174f3d4a26e490eca 100644 (file)
@@ -1,4 +1,5 @@
 header-y += byteorder/
+header-y += can/
 header-y += dvb/
 header-y += hdlc/
 header-y += isdn/
@@ -40,6 +41,7 @@ header-y += baycom.h
 header-y += bfs_fs.h
 header-y += blkpg.h
 header-y += bpqether.h
+header-y += can.h
 header-y += cdk.h
 header-y += chio.h
 header-y += coda_psdev.h
@@ -228,7 +230,6 @@ unifdef-y += if_ltalk.h
 unifdef-y += if_link.h
 unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
-unifdef-y += if_shaper.h
 unifdef-y += if_tr.h
 unifdef-y += if_tun.h
 unifdef-y += if_vlan.h
index 969fb6c9e1cc07654ca3576a65fbb8172fc4b4e5..52bf72affbbae9405f8bc43066f6126cf6d39f54 100644 (file)
@@ -14,6 +14,9 @@
 #define BR2684_MEDIA_FDDI      (3)
 #define BR2684_MEDIA_802_6     (4)     /* 802.6 */
 
+                                       /* used only at device creation:  */
+#define BR2684_FLAG_ROUTED     (1<<16) /* payload is routed, not bridged */
+
 /*
  * Is there FCS inbound on this VC?  This currently isn't supported.
  */
 #define BR2684_ENCAPS_LLC      (1)
 #define BR2684_ENCAPS_AUTODETECT (2)   /* Unsuported */
 
+/*
+ * Is this VC bridged or routed?
+ */
+
+#define BR2684_PAYLOAD_ROUTED   (0)
+#define BR2684_PAYLOAD_BRIDGED  (1)
+
 /*
  * This is for the ATM_NEWBACKENDIF call - these are like socket families:
  * the first element of the structure is the backend number and the rest
  * is per-backend specific
  */
 struct atm_newif_br2684 {
-       atm_backend_t   backend_num;    /* ATM_BACKEND_BR2684 */
-       int             media;          /* BR2684_MEDIA_* */
-       char            ifname[IFNAMSIZ];
-       int             mtu;
+       atm_backend_t backend_num;      /* ATM_BACKEND_BR2684 */
+       int media;              /* BR2684_MEDIA_*, flags in upper bits */
+       char ifname[IFNAMSIZ];
+       int mtu;
 };
 
 /*
@@ -55,10 +65,10 @@ struct atm_newif_br2684 {
 #define BR2684_FIND_BYNUM      (1)
 #define BR2684_FIND_BYIFNAME   (2)
 struct br2684_if_spec {
-       int method;                     /* BR2684_FIND_* */
+       int method;             /* BR2684_FIND_* */
        union {
-               char            ifname[IFNAMSIZ];
-               int             devnum;
+               char ifname[IFNAMSIZ];
+               int devnum;
        } spec;
 };
 
@@ -68,16 +78,16 @@ struct br2684_if_spec {
  * is per-backend specific
  */
 struct atm_backend_br2684 {
-       atm_backend_t   backend_num;    /* ATM_BACKEND_BR2684 */
+       atm_backend_t backend_num;      /* ATM_BACKEND_BR2684 */
        struct br2684_if_spec ifspec;
-       int     fcs_in;         /* BR2684_FCSIN_* */
-       int     fcs_out;        /* BR2684_FCSOUT_* */
-       int     fcs_auto;       /* 1: fcs_{in,out} disabled if no FCS rx'ed */
-       int     encaps;         /* BR2684_ENCAPS_* */
-       int     has_vpiid;      /* 1: use vpn_id - Unsupported */
-       __u8    vpn_id[7];
-       int     send_padding;   /* unsupported */
-       int     min_size;       /* we will pad smaller packets than this */
+       int fcs_in;             /* BR2684_FCSIN_* */
+       int fcs_out;            /* BR2684_FCSOUT_* */
+       int fcs_auto;           /* 1: fcs_{in,out} disabled if no FCS rx'ed */
+       int encaps;             /* BR2684_ENCAPS_* */
+       int has_vpiid;          /* 1: use vpn_id - Unsupported */
+       __u8 vpn_id[7];
+       int send_padding;       /* unsupported */
+       int min_size;           /* we will pad smaller packets than this */
 };
 
 /*
@@ -86,8 +96,8 @@ struct atm_backend_br2684 {
  * efficient per-if in/out filters, this support will be removed
  */
 struct br2684_filter {
-       __be32  prefix;         /* network byte order */
-       __be32  netmask;        /* 0 = disable filter */
+       __be32 prefix;          /* network byte order */
+       __be32 netmask;         /* 0 = disable filter */
 };
 
 struct br2684_filter_set {
@@ -95,6 +105,11 @@ struct br2684_filter_set {
        struct br2684_filter filter;
 };
 
+enum br2684_payload {
+       p_routed = BR2684_PAYLOAD_ROUTED,
+       p_bridged = BR2684_PAYLOAD_BRIDGED,
+};
+
 #define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \
                                struct br2684_filter_set)
 
index 2096e5c7282724fbd3da6085bcbdfe87823c9c1f..a3d07c29d16c65bc97b25027e15c6c5dbfe10c62 100644 (file)
@@ -359,7 +359,7 @@ struct atm_dev {
        struct proc_dir_entry *proc_entry; /* proc entry */
        char *proc_name;                /* proc entry name */
 #endif
-       struct class_device class_dev;  /* sysfs class device */
+       struct device class_dev;        /* sysfs device */
        struct list_head dev_list;      /* linkage */
 };
 
@@ -461,7 +461,7 @@ static inline void atm_dev_put(struct atm_dev *dev)
                BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
                if (dev->ops->dev_close)
                        dev->ops->dev_close(dev);
-               class_device_put(&dev->class_dev);
+               put_device(&dev->class_dev);
        }
 }
 
diff --git a/include/linux/can.h b/include/linux/can.h
new file mode 100644 (file)
index 0000000..d183333
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * linux/can.h
+ *
+ * Definitions for CAN network layer (socket addr / CAN frame / CAN filter)
+ *
+ * Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ *          Urs Thuermann   <urs.thuermann@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_H
+#define CAN_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/* controller area network (CAN) kernel definitions */
+
+/* special address description flags for the CAN_ID */
+#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
+#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
+#define CAN_ERR_FLAG 0x20000000U /* error frame */
+
+/* valid bits in CAN ID for frame formats */
+#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
+#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
+#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
+
+/*
+ * Controller Area Network Identifier structure
+ *
+ * bit 0-28    : CAN identifier (11/29 bit)
+ * bit 29      : error frame flag (0 = data frame, 1 = error frame)
+ * bit 30      : remote transmission request flag (1 = rtr frame)
+ * bit 31      : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
+ */
+typedef __u32 canid_t;
+
+/*
+ * Controller Area Network Error Frame Mask structure
+ *
+ * bit 0-28    : error class mask (see include/linux/can/error.h)
+ * bit 29-31   : set to zero
+ */
+typedef __u32 can_err_mask_t;
+
+/**
+ * struct can_frame - basic CAN frame structure
+ * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
+ * @can_dlc: the data length field of the CAN frame
+ * @data:    the CAN frame payload.
+ */
+struct can_frame {
+       canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+       __u8    can_dlc; /* data length code: 0 .. 8 */
+       __u8    data[8] __attribute__((aligned(8)));
+};
+
+/* particular protocols of the protocol family PF_CAN */
+#define CAN_RAW                1 /* RAW sockets */
+#define CAN_BCM                2 /* Broadcast Manager */
+#define CAN_TP16       3 /* VAG Transport Protocol v1.6 */
+#define CAN_TP20       4 /* VAG Transport Protocol v2.0 */
+#define CAN_MCNET      5 /* Bosch MCNet */
+#define CAN_ISOTP      6 /* ISO 15765-2 Transport Protocol */
+#define CAN_NPROTO     7
+
+#define SOL_CAN_BASE 100
+
+/**
+ * struct sockaddr_can - the sockaddr structure for CAN sockets
+ * @can_family:  address family number AF_CAN.
+ * @can_ifindex: CAN network interface index.
+ * @can_addr:    protocol specific address information
+ */
+struct sockaddr_can {
+       sa_family_t can_family;
+       int         can_ifindex;
+       union {
+               /* transport protocol class address information (e.g. ISOTP) */
+               struct { canid_t rx_id, tx_id; } tp;
+
+               /* reserved for future CAN protocols address information */
+       } can_addr;
+};
+
+/**
+ * struct can_filter - CAN ID based filter in can_register().
+ * @can_id:   relevant bits of CAN ID which are not masked out.
+ * @can_mask: CAN mask (see description)
+ *
+ * Description:
+ * A filter matches, when
+ *
+ *          <received_can_id> & mask == can_id & mask
+ *
+ * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
+ * filter for error frames (CAN_ERR_FLAG bit set in mask).
+ */
+struct can_filter {
+       canid_t can_id;
+       canid_t can_mask;
+};
+
+#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+
+#endif /* CAN_H */
diff --git a/include/linux/can/Kbuild b/include/linux/can/Kbuild
new file mode 100644 (file)
index 0000000..eff898a
--- /dev/null
@@ -0,0 +1,3 @@
+header-y += raw.h
+header-y += bcm.h
+header-y += error.h
diff --git a/include/linux/can/bcm.h b/include/linux/can/bcm.h
new file mode 100644 (file)
index 0000000..7f29327
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * linux/can/bcm.h
+ *
+ * Definitions for CAN Broadcast Manager (BCM)
+ *
+ * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_BCM_H
+#define CAN_BCM_H
+
+/**
+ * struct bcm_msg_head - head of messages to/from the broadcast manager
+ * @opcode:    opcode, see enum below.
+ * @flags:     special flags, see below.
+ * @count:     number of frames to send before changing interval.
+ * @ival1:     interval for the first @count frames.
+ * @ival2:     interval for the following frames.
+ * @can_id:    CAN ID of frames to be sent or received.
+ * @nframes:   number of frames appended to the message head.
+ * @frames:    array of CAN frames.
+ */
+struct bcm_msg_head {
+       __u32 opcode;
+       __u32 flags;
+       __u32 count;
+       struct timeval ival1, ival2;
+       canid_t can_id;
+       __u32 nframes;
+       struct can_frame frames[0];
+};
+
+enum {
+       TX_SETUP = 1,   /* create (cyclic) transmission task */
+       TX_DELETE,      /* remove (cyclic) transmission task */
+       TX_READ,        /* read properties of (cyclic) transmission task */
+       TX_SEND,        /* send one CAN frame */
+       RX_SETUP,       /* create RX content filter subscription */
+       RX_DELETE,      /* remove RX content filter subscription */
+       RX_READ,        /* read properties of RX content filter subscription */
+       TX_STATUS,      /* reply to TX_READ request */
+       TX_EXPIRED,     /* notification on performed transmissions (count=0) */
+       RX_STATUS,      /* reply to RX_READ request */
+       RX_TIMEOUT,     /* cyclic message is absent */
+       RX_CHANGED      /* updated CAN frame (detected content change) */
+};
+
+#define SETTIMER            0x0001
+#define STARTTIMER          0x0002
+#define TX_COUNTEVT         0x0004
+#define TX_ANNOUNCE         0x0008
+#define TX_CP_CAN_ID        0x0010
+#define RX_FILTER_ID        0x0020
+#define RX_CHECK_DLC        0x0040
+#define RX_NO_AUTOTIMER     0x0080
+#define RX_ANNOUNCE_RESUME  0x0100
+#define TX_RESET_MULTI_IDX  0x0200
+#define RX_RTR_FRAME        0x0400
+
+#endif /* CAN_BCM_H */
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
new file mode 100644 (file)
index 0000000..e9ca210
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * linux/can/core.h
+ *
+ * Protoypes and definitions for CAN protocol modules using the PF_CAN core
+ *
+ * Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ *          Urs Thuermann   <urs.thuermann@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_CORE_H
+#define CAN_CORE_H
+
+#include <linux/can.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+
+#define CAN_VERSION "20071116"
+
+/* increment this number each time you change some user-space interface */
+#define CAN_ABI_VERSION "8"
+
+#define CAN_VERSION_STRING "rev " CAN_VERSION " abi " CAN_ABI_VERSION
+
+#define DNAME(dev) ((dev) ? (dev)->name : "any")
+
+/**
+ * struct can_proto - CAN protocol structure
+ * @type:       type argument in socket() syscall, e.g. SOCK_DGRAM.
+ * @protocol:   protocol number in socket() syscall.
+ * @capability: capability needed to open the socket, or -1 for no restriction.
+ * @ops:        pointer to struct proto_ops for sock->ops.
+ * @prot:       pointer to struct proto structure.
+ */
+struct can_proto {
+       int              type;
+       int              protocol;
+       int              capability;
+       struct proto_ops *ops;
+       struct proto     *prot;
+};
+
+/* function prototypes for the CAN networklayer core (af_can.c) */
+
+extern int  can_proto_register(struct can_proto *cp);
+extern void can_proto_unregister(struct can_proto *cp);
+
+extern int  can_rx_register(struct net_device *dev, canid_t can_id,
+                           canid_t mask,
+                           void (*func)(struct sk_buff *, void *),
+                           void *data, char *ident);
+
+extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
+                             canid_t mask,
+                             void (*func)(struct sk_buff *, void *),
+                             void *data);
+
+extern int can_send(struct sk_buff *skb, int loop);
+
+#endif /* CAN_CORE_H */
diff --git a/include/linux/can/error.h b/include/linux/can/error.h
new file mode 100644 (file)
index 0000000..d4127fd
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * linux/can/error.h
+ *
+ * Definitions of the CAN error frame to be filtered and passed to the user.
+ *
+ * Author: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_ERROR_H
+#define CAN_ERROR_H
+
+#define CAN_ERR_DLC 8 /* dlc for error frames */
+
+/* error class (mask) in can_id */
+#define CAN_ERR_TX_TIMEOUT   0x00000001U /* TX timeout (by netdevice driver) */
+#define CAN_ERR_LOSTARB      0x00000002U /* lost arbitration    / data[0]    */
+#define CAN_ERR_CRTL         0x00000004U /* controller problems / data[1]    */
+#define CAN_ERR_PROT         0x00000008U /* protocol violations / data[2..3] */
+#define CAN_ERR_TRX          0x00000010U /* transceiver status  / data[4]    */
+#define CAN_ERR_ACK          0x00000020U /* received no ACK on transmission */
+#define CAN_ERR_BUSOFF       0x00000040U /* bus off */
+#define CAN_ERR_BUSERROR     0x00000080U /* bus error (may flood!) */
+#define CAN_ERR_RESTARTED    0x00000100U /* controller restarted */
+
+/* arbitration lost in bit ... / data[0] */
+#define CAN_ERR_LOSTARB_UNSPEC   0x00 /* unspecified */
+                                     /* else bit number in bitstream */
+
+/* error status of CAN-controller / data[1] */
+#define CAN_ERR_CRTL_UNSPEC      0x00 /* unspecified */
+#define CAN_ERR_CRTL_RX_OVERFLOW 0x01 /* RX buffer overflow */
+#define CAN_ERR_CRTL_TX_OVERFLOW 0x02 /* TX buffer overflow */
+#define CAN_ERR_CRTL_RX_WARNING  0x04 /* reached warning level for RX errors */
+#define CAN_ERR_CRTL_TX_WARNING  0x08 /* reached warning level for TX errors */
+#define CAN_ERR_CRTL_RX_PASSIVE  0x10 /* reached error passive status RX */
+#define CAN_ERR_CRTL_TX_PASSIVE  0x20 /* reached error passive status TX */
+                                     /* (at least one error counter exceeds */
+                                     /* the protocol-defined level of 127)  */
+
+/* error in CAN protocol (type) / data[2] */
+#define CAN_ERR_PROT_UNSPEC      0x00 /* unspecified */
+#define CAN_ERR_PROT_BIT         0x01 /* single bit error */
+#define CAN_ERR_PROT_FORM        0x02 /* frame format error */
+#define CAN_ERR_PROT_STUFF       0x04 /* bit stuffing error */
+#define CAN_ERR_PROT_BIT0        0x08 /* unable to send dominant bit */
+#define CAN_ERR_PROT_BIT1        0x10 /* unable to send recessive bit */
+#define CAN_ERR_PROT_OVERLOAD    0x20 /* bus overload */
+#define CAN_ERR_PROT_ACTIVE      0x40 /* active error announcement */
+#define CAN_ERR_PROT_TX          0x80 /* error occured on transmission */
+
+/* error in CAN protocol (location) / data[3] */
+#define CAN_ERR_PROT_LOC_UNSPEC  0x00 /* unspecified */
+#define CAN_ERR_PROT_LOC_SOF     0x03 /* start of frame */
+#define CAN_ERR_PROT_LOC_ID28_21 0x02 /* ID bits 28 - 21 (SFF: 10 - 3) */
+#define CAN_ERR_PROT_LOC_ID20_18 0x06 /* ID bits 20 - 18 (SFF: 2 - 0 )*/
+#define CAN_ERR_PROT_LOC_SRTR    0x04 /* substitute RTR (SFF: RTR) */
+#define CAN_ERR_PROT_LOC_IDE     0x05 /* identifier extension */
+#define CAN_ERR_PROT_LOC_ID17_13 0x07 /* ID bits 17-13 */
+#define CAN_ERR_PROT_LOC_ID12_05 0x0F /* ID bits 12-5 */
+#define CAN_ERR_PROT_LOC_ID04_00 0x0E /* ID bits 4-0 */
+#define CAN_ERR_PROT_LOC_RTR     0x0C /* RTR */
+#define CAN_ERR_PROT_LOC_RES1    0x0D /* reserved bit 1 */
+#define CAN_ERR_PROT_LOC_RES0    0x09 /* reserved bit 0 */
+#define CAN_ERR_PROT_LOC_DLC     0x0B /* data length code */
+#define CAN_ERR_PROT_LOC_DATA    0x0A /* data section */
+#define CAN_ERR_PROT_LOC_CRC_SEQ 0x08 /* CRC sequence */
+#define CAN_ERR_PROT_LOC_CRC_DEL 0x18 /* CRC delimiter */
+#define CAN_ERR_PROT_LOC_ACK     0x19 /* ACK slot */
+#define CAN_ERR_PROT_LOC_ACK_DEL 0x1B /* ACK delimiter */
+#define CAN_ERR_PROT_LOC_EOF     0x1A /* end of frame */
+#define CAN_ERR_PROT_LOC_INTERM  0x12 /* intermission */
+
+/* error status of CAN-transceiver / data[4] */
+/*                                             CANH CANL */
+#define CAN_ERR_TRX_UNSPEC             0x00 /* 0000 0000 */
+#define CAN_ERR_TRX_CANH_NO_WIRE       0x04 /* 0000 0100 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_BAT  0x05 /* 0000 0101 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_VCC  0x06 /* 0000 0110 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_GND  0x07 /* 0000 0111 */
+#define CAN_ERR_TRX_CANL_NO_WIRE       0x40 /* 0100 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_BAT  0x50 /* 0101 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_VCC  0x60 /* 0110 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_GND  0x70 /* 0111 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
+
+/* controller specific additional information / data[5..7] */
+
+#endif /* CAN_ERROR_H */
diff --git a/include/linux/can/raw.h b/include/linux/can/raw.h
new file mode 100644 (file)
index 0000000..b2a0f87
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * linux/can/raw.h
+ *
+ * Definitions for raw CAN sockets
+ *
+ * Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ *          Urs Thuermann   <urs.thuermann@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_RAW_H
+#define CAN_RAW_H
+
+#include <linux/can.h>
+
+#define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW)
+
+/* for socket options affecting the socket (not the global system) */
+
+enum {
+       CAN_RAW_FILTER = 1,     /* set 0 .. n can_filter(s)          */
+       CAN_RAW_ERR_FILTER,     /* set filter for error frames       */
+       CAN_RAW_LOOPBACK,       /* local loopback (default:on)       */
+       CAN_RAW_RECV_OWN_MSGS   /* receive my own msgs (default:off) */
+};
+
+#endif
index 13fc4541bf235b14333920f35e7ac744c5085bc9..da6dd957f9089ab1523f2d150c7a7696884d6964 100644 (file)
@@ -112,7 +112,6 @@ struct cn_queue_dev {
        struct list_head queue_list;
        spinlock_t queue_lock;
 
-       int netlink_groups;
        struct sock *nls;
 };
 
@@ -133,15 +132,13 @@ struct cn_callback_data {
 
 struct cn_callback_entry {
        struct list_head callback_entry;
-       struct cn_callback *cb;
        struct work_struct work;
        struct cn_queue_dev *pdev;
 
        struct cn_callback_id id;
        struct cn_callback_data data;
 
-       int seq, group;
-       struct sock *nls;
+       u32 seq, group;
 };
 
 struct cn_ctl_entry {
index 333c3ea82a5ddc8d044a59d817a38b344eaae7d2..484e45c7c89a832dd986c7fe927e545168e2ec77 100644 (file)
@@ -205,6 +205,7 @@ struct dccp_so_feat {
 #define DCCP_SOCKOPT_CHANGE_L          3
 #define DCCP_SOCKOPT_CHANGE_R          4
 #define DCCP_SOCKOPT_GET_CUR_MPS       5
+#define DCCP_SOCKOPT_SERVER_TIMEWAIT   6
 #define DCCP_SOCKOPT_SEND_CSCOV                10
 #define DCCP_SOCKOPT_RECV_CSCOV                11
 #define DCCP_SOCKOPT_CCID_RX_INFO      128
@@ -227,37 +228,50 @@ struct dccp_so_feat {
 #include <net/tcp_states.h>
 
 enum dccp_state {
-       DCCP_OPEN       = TCP_ESTABLISHED,
-       DCCP_REQUESTING = TCP_SYN_SENT,
-       DCCP_PARTOPEN   = TCP_FIN_WAIT1, /* FIXME:
-                                           This mapping is horrible, but TCP has
-                                           no matching state for DCCP_PARTOPEN,
-                                           as TCP_SYN_RECV is already used by
-                                           DCCP_RESPOND, why don't stop using TCP
-                                           mapping of states? OK, now we don't use
-                                           sk_stream_sendmsg anymore, so doesn't
-                                           seem to exist any reason for us to
-                                           do the TCP mapping here */
-       DCCP_LISTEN     = TCP_LISTEN,
-       DCCP_RESPOND    = TCP_SYN_RECV,
-       DCCP_CLOSING    = TCP_CLOSING,
-       DCCP_TIME_WAIT  = TCP_TIME_WAIT,
-       DCCP_CLOSED     = TCP_CLOSE,
-       DCCP_MAX_STATES = TCP_MAX_STATES,
+       DCCP_OPEN            = TCP_ESTABLISHED,
+       DCCP_REQUESTING      = TCP_SYN_SENT,
+       DCCP_LISTEN          = TCP_LISTEN,
+       DCCP_RESPOND         = TCP_SYN_RECV,
+       /*
+        * States involved in closing a DCCP connection:
+        * 1) ACTIVE_CLOSEREQ is entered by a server sending a CloseReq.
+        *
+        * 2) CLOSING can have three different meanings (RFC 4340, 8.3):
+        *  a. Client has performed active-close, has sent a Close to the server
+        *     from state OPEN or PARTOPEN, and is waiting for the final Reset
+        *     (in this case, SOCK_DONE == 1).
+        *  b. Client is asked to perform passive-close, by receiving a CloseReq
+        *     in (PART)OPEN state. It sends a Close and waits for final Reset
+        *     (in this case, SOCK_DONE == 0).
+        *  c. Server performs an active-close as in (a), keeps TIMEWAIT state.
+        *
+        * 3) The following intermediate states are employed to give passively
+        *    closing nodes a chance to process their unread data:
+        *    - PASSIVE_CLOSE    (from OPEN => CLOSED) and
+        *    - PASSIVE_CLOSEREQ (from (PART)OPEN to CLOSING; case (b) above).
+        */
+       DCCP_ACTIVE_CLOSEREQ = TCP_FIN_WAIT1,
+       DCCP_PASSIVE_CLOSE   = TCP_CLOSE_WAIT,  /* any node receiving a Close */
+       DCCP_CLOSING         = TCP_CLOSING,
+       DCCP_TIME_WAIT       = TCP_TIME_WAIT,
+       DCCP_CLOSED          = TCP_CLOSE,
+       DCCP_PARTOPEN        = TCP_MAX_STATES,
+       DCCP_PASSIVE_CLOSEREQ,                  /* clients receiving CloseReq */
+       DCCP_MAX_STATES
 };
 
-#define DCCP_STATE_MASK 0xf
-#define DCCP_ACTION_FIN (1<<7)
+#define DCCP_STATE_MASK 0x1f
 
 enum {
-       DCCPF_OPEN       = TCPF_ESTABLISHED,
-       DCCPF_REQUESTING = TCPF_SYN_SENT,
-       DCCPF_PARTOPEN   = TCPF_FIN_WAIT1,
-       DCCPF_LISTEN     = TCPF_LISTEN,
-       DCCPF_RESPOND    = TCPF_SYN_RECV,
-       DCCPF_CLOSING    = TCPF_CLOSING,
-       DCCPF_TIME_WAIT  = TCPF_TIME_WAIT,
-       DCCPF_CLOSED     = TCPF_CLOSE,
+       DCCPF_OPEN            = TCPF_ESTABLISHED,
+       DCCPF_REQUESTING      = TCPF_SYN_SENT,
+       DCCPF_LISTEN          = TCPF_LISTEN,
+       DCCPF_RESPOND         = TCPF_SYN_RECV,
+       DCCPF_ACTIVE_CLOSEREQ = TCPF_FIN_WAIT1,
+       DCCPF_CLOSING         = TCPF_CLOSING,
+       DCCPF_TIME_WAIT       = TCPF_TIME_WAIT,
+       DCCPF_CLOSED          = TCPF_CLOSE,
+       DCCPF_PARTOPEN        = (1 << DCCP_PARTOPEN),
 };
 
 static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
@@ -393,13 +407,23 @@ struct dccp_opt_pend {
 
 extern void dccp_minisock_init(struct dccp_minisock *dmsk);
 
-extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb);
-
+/**
+ * struct dccp_request_sock  -  represent DCCP-specific connection request
+ * @dreq_inet_rsk: structure inherited from
+ * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1)
+ * @dreq_isr: initial sequence number received on the Request
+ * @dreq_service: service code present on the Request (there is just one)
+ * The following two fields are analogous to the ones in dccp_sock:
+ * @dreq_timestamp_echo: last received timestamp to echo (13.1)
+ * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo
+ */
 struct dccp_request_sock {
        struct inet_request_sock dreq_inet_rsk;
        __u64                    dreq_iss;
        __u64                    dreq_isr;
        __be32                   dreq_service;
+       __u32                    dreq_timestamp_echo;
+       __u32                    dreq_timestamp_time;
 };
 
 static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
@@ -409,6 +433,9 @@ static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
 
 extern struct inet_timewait_death_row dccp_death_row;
 
+extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
+                             struct sk_buff *skb);
+
 struct dccp_options_received {
        u32     dccpor_ndp; /* only 24 bits */
        u32     dccpor_timestamp;
@@ -462,8 +489,8 @@ struct dccp_ackvec;
  * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
  * @dccps_service - first (passive sock) or unique (active sock) service code
  * @dccps_service_list - second .. last service code on passive socket
- * @dccps_timestamp_time - time of latest TIMESTAMP option
  * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
+ * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo
  * @dccps_l_ack_ratio - feature-local Ack Ratio
  * @dccps_r_ack_ratio - feature-remote Ack Ratio
  * @dccps_pcslen - sender   partial checksum coverage (via sockopt)
@@ -479,6 +506,7 @@ struct dccp_ackvec;
  * @dccps_role - role of this sock, one of %dccp_role
  * @dccps_hc_rx_insert_options - receiver wants to add options when acking
  * @dccps_hc_tx_insert_options - sender wants to add options when sending
+ * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3)
  * @dccps_xmit_timer - timer for when CCID is not ready to send
  * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs)
  */
@@ -498,8 +526,8 @@ struct dccp_sock {
        __u64                           dccps_gar;
        __be32                          dccps_service;
        struct dccp_service_list        *dccps_service_list;
-       ktime_t                         dccps_timestamp_time;
        __u32                           dccps_timestamp_echo;
+       __u32                           dccps_timestamp_time;
        __u16                           dccps_l_ack_ratio;
        __u16                           dccps_r_ack_ratio;
        __u16                           dccps_pcslen;
@@ -515,6 +543,7 @@ struct dccp_sock {
        enum dccp_role                  dccps_role:2;
        __u8                            dccps_hc_rx_insert_options:1;
        __u8                            dccps_hc_tx_insert_options:1;
+       __u8                            dccps_server_timewait:1;
        struct timer_list               dccps_xmit_timer;
 };
 
index 30621c27159fda57e3946ba82a0daa0bdcea6b5a..5de6d911cdf7be1d8f7edf1b228fa70495e553e5 100644 (file)
@@ -54,6 +54,8 @@
 #define IEEE80211_STYPE_ACTION         0x00D0
 
 /* control */
+#define IEEE80211_STYPE_BACK_REQ       0x0080
+#define IEEE80211_STYPE_BACK           0x0090
 #define IEEE80211_STYPE_PSPOLL         0x00A0
 #define IEEE80211_STYPE_RTS            0x00B0
 #define IEEE80211_STYPE_CTS            0x00C0
 
 
 /* miscellaneous IEEE 802.11 constants */
-#define IEEE80211_MAX_FRAG_THRESHOLD   2346
-#define IEEE80211_MAX_RTS_THRESHOLD    2347
+#define IEEE80211_MAX_FRAG_THRESHOLD   2352
+#define IEEE80211_MAX_RTS_THRESHOLD    2353
 #define IEEE80211_MAX_AID              2007
 #define IEEE80211_MAX_TIM_LEN          251
-#define IEEE80211_MAX_DATA_LEN         2304
 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
    6.2.1.1.2.
 
-   The figure in section 7.1.2 suggests a body size of up to 2312
-   bytes is allowed, which is a bit confusing, I suspect this
-   represents the 2304 bytes of real data, plus a possible 8 bytes of
-   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+   802.11e clarifies the figure in section 7.1.2. The frame body is
+   up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
+#define IEEE80211_MAX_DATA_LEN         2304
+/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
+#define IEEE80211_MAX_FRAME_LEN                2352
 
 #define IEEE80211_MAX_SSID_LEN         32
 
@@ -185,6 +187,25 @@ struct ieee80211_mgmt {
                                        u8 new_chan;
                                        u8 switch_count;
                                } __attribute__((packed)) chan_switch;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 capab;
+                                       __le16 timeout;
+                                       __le16 start_seq_num;
+                               } __attribute__((packed)) addba_req;
+                               struct{
+                                       u8 action_code;
+                                       u8 dialog_token;
+                                       __le16 status;
+                                       __le16 capab;
+                                       __le16 timeout;
+                               } __attribute__((packed)) addba_resp;
+                               struct{
+                                       u8 action_code;
+                                       __le16 params;
+                                       __le16 reason_code;
+                               } __attribute__((packed)) delba;
                        } u;
                } __attribute__ ((packed)) action;
        } u;
@@ -205,6 +226,66 @@ struct ieee80211_cts {
        u8 ra[6];
 } __attribute__ ((packed));
 
+/**
+ * struct ieee80211_bar - HT Block Ack Request
+ *
+ * This structure refers to "HT BlockAckReq" as
+ * described in 802.11n draft section 7.2.1.7.1
+ */
+struct ieee80211_bar {
+       __le16 frame_control;
+       __le16 duration;
+       __u8 ra[6];
+       __u8 ta[6];
+       __le16 control;
+       __le16 start_seq_num;
+} __attribute__((packed));
+
+/**
+ * struct ieee80211_ht_cap - HT capabilities
+ *
+ * This structure refers to "HT capabilities element" as
+ * described in 802.11n draft section 7.3.2.52
+ */
+struct ieee80211_ht_cap {
+       __le16 cap_info;
+       u8 ampdu_params_info;
+       u8 supp_mcs_set[16];
+       __le16 extended_ht_cap_info;
+       __le32 tx_BF_cap_info;
+       u8 antenna_selection_info;
+} __attribute__ ((packed));
+
+/**
+ * struct ieee80211_ht_cap - HT additional information
+ *
+ * This structure refers to "HT information element" as
+ * described in 802.11n draft section 7.3.2.53
+ */
+struct ieee80211_ht_addt_info {
+       u8 control_chan;
+       u8 ht_param;
+       __le16 operation_mode;
+       __le16 stbc_param;
+       u8 basic_set[16];
+} __attribute__ ((packed));
+
+/* 802.11n HT capabilities masks */
+#define IEEE80211_HT_CAP_SUP_WIDTH             0x0002
+#define IEEE80211_HT_CAP_MIMO_PS               0x000C
+#define IEEE80211_HT_CAP_GRN_FLD               0x0010
+#define IEEE80211_HT_CAP_SGI_20                        0x0020
+#define IEEE80211_HT_CAP_SGI_40                        0x0040
+#define IEEE80211_HT_CAP_DELAY_BA              0x0400
+#define IEEE80211_HT_CAP_MAX_AMSDU             0x0800
+#define IEEE80211_HT_CAP_AMPDU_FACTOR          0x03
+#define IEEE80211_HT_CAP_AMPDU_DENSITY         0x1C
+/* 802.11n HT IE masks */
+#define IEEE80211_HT_IE_CHA_SEC_OFFSET         0x03
+#define IEEE80211_HT_IE_CHA_WIDTH              0x04
+#define IEEE80211_HT_IE_HT_PROTECTION          0x0003
+#define IEEE80211_HT_IE_NON_GF_STA_PRSNT       0x0004
+#define IEEE80211_HT_IE_NON_HT_STA_PRSNT       0x0010
 
 /* Authentication algorithms */
 #define WLAN_AUTH_OPEN 0
@@ -271,6 +352,18 @@ enum ieee80211_statuscode {
        WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
        WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
        WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+       /* 802.11e */
+       WLAN_STATUS_UNSPECIFIED_QOS = 32,
+       WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33,
+       WLAN_STATUS_ASSOC_DENIED_LOWACK = 34,
+       WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35,
+       WLAN_STATUS_REQUEST_DECLINED = 37,
+       WLAN_STATUS_INVALID_QOS_PARAM = 38,
+       WLAN_STATUS_CHANGE_TSPEC = 39,
+       WLAN_STATUS_WAIT_TS_DELAY = 47,
+       WLAN_STATUS_NO_DIRECT_LINK = 48,
+       WLAN_STATUS_STA_NOT_PRESENT = 49,
+       WLAN_STATUS_STA_NOT_QSTA = 50,
 };
 
 
@@ -301,6 +394,16 @@ enum ieee80211_reasoncode {
        WLAN_REASON_INVALID_RSN_IE_CAP = 22,
        WLAN_REASON_IEEE8021X_FAILED = 23,
        WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+       /* 802.11e */
+       WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32,
+       WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33,
+       WLAN_REASON_DISASSOC_LOW_ACK = 34,
+       WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35,
+       WLAN_REASON_QSTA_LEAVE_QBSS = 36,
+       WLAN_REASON_QSTA_NOT_USE = 37,
+       WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
+       WLAN_REASON_QSTA_TIMEOUT = 39,
+       WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
 };
 
 
@@ -319,6 +422,15 @@ enum ieee80211_eid {
        WLAN_EID_HP_PARAMS = 8,
        WLAN_EID_HP_TABLE = 9,
        WLAN_EID_REQUEST = 10,
+       /* 802.11e */
+       WLAN_EID_QBSS_LOAD = 11,
+       WLAN_EID_EDCA_PARAM_SET = 12,
+       WLAN_EID_TSPEC = 13,
+       WLAN_EID_TCLAS = 14,
+       WLAN_EID_SCHEDULE = 15,
+       WLAN_EID_TS_DELAY = 43,
+       WLAN_EID_TCLAS_PROCESSING = 44,
+       WLAN_EID_QOS_CAPA = 46,
        /* 802.11h */
        WLAN_EID_PWR_CONSTRAINT = 32,
        WLAN_EID_PWR_CAPABILITY = 33,
@@ -333,6 +445,9 @@ enum ieee80211_eid {
        /* 802.11g */
        WLAN_EID_ERP_INFO = 42,
        WLAN_EID_EXT_SUPP_RATES = 50,
+       /* 802.11n */
+       WLAN_EID_HT_CAPABILITY = 45,
+       WLAN_EID_HT_EXTRA_INFO = 61,
        /* 802.11i */
        WLAN_EID_RSN = 48,
        WLAN_EID_WPA = 221,
@@ -341,6 +456,32 @@ enum ieee80211_eid {
        WLAN_EID_QOS_PARAMETER = 222
 };
 
+/* Action category code */
+enum ieee80211_category {
+       WLAN_CATEGORY_SPECTRUM_MGMT = 0,
+       WLAN_CATEGORY_QOS = 1,
+       WLAN_CATEGORY_DLS = 2,
+       WLAN_CATEGORY_BACK = 3,
+       WLAN_CATEGORY_WMM = 17,
+};
+
+/* BACK action code */
+enum ieee80211_back_actioncode {
+       WLAN_ACTION_ADDBA_REQ = 0,
+       WLAN_ACTION_ADDBA_RESP = 1,
+       WLAN_ACTION_DELBA = 2,
+};
+
+/* BACK (block-ack) parties */
+enum ieee80211_back_parties {
+       WLAN_BACK_RECIPIENT = 0,
+       WLAN_BACK_INITIATOR = 1,
+       WLAN_BACK_TIMER = 2,
+};
+
+/* A-MSDU 802.11n */
+#define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080
+
 /* cipher suite selectors */
 #define WLAN_CIPHER_SUITE_USE_GROUP    0x000FAC00
 #define WLAN_CIPHER_SUITE_WEP40                0x000FAC01
index 32bf419351f184242dfd5af400dd1859f297282d..5c9d1fa93fef9f48852ce163f10badd26266f775 100644 (file)
@@ -50,7 +50,9 @@
 #define IFF_LOWER_UP   0x10000         /* driver signals L1 up         */
 #define IFF_DORMANT    0x20000         /* driver signals dormant       */
 
-#define IFF_VOLATILE   (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|\
+#define IFF_ECHO       0x40000         /* echo sent packets            */
+
+#define IFF_VOLATILE   (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
                IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
 
 /* Private (from user) interface flags (netdevice->priv_flags). */
@@ -61,6 +63,7 @@
 #define IFF_MASTER_ALB 0x10            /* bonding master, balance-alb. */
 #define IFF_BONDING    0x20            /* bonding master or slave      */
 #define IFF_SLAVE_NEEDARP 0x40         /* need ARPs for validation     */
+#define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)   */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
diff --git a/include/linux/if_addrlabel.h b/include/linux/if_addrlabel.h
new file mode 100644 (file)
index 0000000..9fe79c9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * if_addrlabel.h - netlink interface for address labels
+ *
+ * Copyright (C)2007 USAGI/WIDE Project,  All Rights Reserved.
+ *
+ * Authors:
+ *     YOSHIFUJI Hideaki @ USAGI/WIDE <yoshfuji@linux-ipv6.org>
+ */
+
+#ifndef __LINUX_IF_ADDRLABEL_H
+#define __LINUX_IF_ADDRLABEL_H
+
+struct ifaddrlblmsg
+{
+       __u8            ifal_family;            /* Address family */
+       __u8            __ifal_reserved;        /* Reserved */
+       __u8            ifal_prefixlen;         /* Prefix length */
+       __u8            ifal_flags;             /* Flags */
+       __u32           ifal_index;             /* Link index */
+       __u32           ifal_seq;               /* sequence number */
+};
+
+enum
+{
+       IFAL_ADDRESS = 1,
+       IFAL_LABEL = 2,
+       __IFAL_MAX
+};
+
+#define IFAL_MAX       (__IFAL_MAX - 1)
+
+#endif
index ed7b93c3083ae668b1505d434aa58a1d9dc601ce..296e8e86e91d1c33052ea2b27ad3b1d8f86895db 100644 (file)
@@ -52,6 +52,7 @@
 #define ARPHRD_ROSE    270
 #define ARPHRD_X25     271             /* CCITT X.25                   */
 #define ARPHRD_HWX25   272             /* Boards with X.25 in firmware */
+#define ARPHRD_CAN     280             /* Controller Area Network      */
 #define ARPHRD_PPP     512
 #define ARPHRD_CISCO   513             /* Cisco HDLC                   */
 #define ARPHRD_HDLC    ARPHRD_CISCO
index 5f9297793661784f05d2e8567f6f4eddc36d43b8..e157c1399b61c691b9b7ee192556cbbec74f2f03 100644 (file)
@@ -90,6 +90,7 @@
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
 #define ETH_P_LOCALTALK 0x0009         /* Localtalk pseudo type        */
+#define ETH_P_CAN      0x000C          /* Controller Area Network      */
 #define ETH_P_PPPTALK  0x0010          /* Dummy type for Atalk over PPP*/
 #define ETH_P_TR_802_2 0x0011          /* 802.2 frames                 */
 #define ETH_P_MOBITEX  0x0015          /* Mobitex (kaz@cafe.net)       */
@@ -123,12 +124,15 @@ int eth_header_parse(const struct sk_buff *skb, unsigned char *haddr);
 extern struct ctl_table ether_table[];
 #endif
 
+extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len);
+
 /*
  *     Display a 6 byte device address (MAC) in a readable format.
  */
+extern char *print_mac(char *buf, const unsigned char *addr);
 #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-extern char *print_mac(char *buf, const u8 *addr);
-#define DECLARE_MAC_BUF(var) char var[18] __maybe_unused
+#define MAC_BUF_SIZE   18
+#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] __maybe_unused
 
 #endif
 
index f272a80caa3e577aa21d73760ac3519c2659506e..5c34240de746dd3c9123f481c7bea984acfa4827 100644 (file)
@@ -137,7 +137,7 @@ struct frhdr
 
    unsigned char  NLPID;
    unsigned char  OUI[3];
-   unsigned short PID;
+   __be16 PID;
 
 #define IP_NLPID pad 
 } __attribute__((packed));
diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h
deleted file mode 100644 (file)
index 3b1b7ba..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef __LINUX_SHAPER_H
-#define __LINUX_SHAPER_H
-
-#ifdef __KERNEL__
-
-#define SHAPER_QLEN    10
-/*
- *     This is a bit speed dependent (read it shouldn't be a constant!)
- *
- *     5 is about right for 28.8 upwards. Below that double for every
- *     halving of speed or so. - ie about 20 for 9600 baud.
- */
-#define SHAPER_LATENCY (5*HZ)
-#define SHAPER_MAXSLIP 2
-#define SHAPER_BURST   (HZ/50)         /* Good for >128K then */
-
-struct shaper
-{
-       struct sk_buff_head sendq;
-       __u32 bytespertick;
-       __u32 bitspersec;
-       __u32 shapelatency;
-       __u32 shapeclock;
-       unsigned long recovery; /* Time we can next clock a packet out on
-                                  an empty queue */
-       spinlock_t lock;
-       struct net_device *dev;
-       struct net_device_stats* (*get_stats)(struct net_device *dev);
-       struct timer_list timer;
-};
-
-#endif
-
-#define SHAPER_SET_DEV         0x0001
-#define SHAPER_SET_SPEED       0x0002
-#define SHAPER_GET_DEV         0x0003
-#define SHAPER_GET_SPEED       0x0004
-
-struct shaperconf
-{
-       __u16   ss_cmd;
-       union
-       {
-               char    ssu_name[14];
-               __u32   ssu_speed;
-       } ss_u;
-#define ss_speed ss_u.ssu_speed
-#define ss_name ss_u.ssu_name
-};
-
-#endif
index 046e9d95ba9a55a79999f59449d181512aff4c97..5bcec8b2c5e2b557d1cdbbec372177c4bc3c24ed 100644 (file)
@@ -49,9 +49,6 @@ static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb)
 {
        return (struct trh_hdr *)skb_mac_header(skb);
 }
-#ifdef CONFIG_SYSCTL
-extern struct ctl_table tr_table[];
-#endif
 #endif
 
 /* This is an Token-Ring LLC structure */
index 33e489d5bb33ed4e476360577474a90f580e2b2c..72f1c5f47be325444270ec2ccd81fbfea927914b 100644 (file)
@@ -21,6 +21,8 @@
 /* Uncomment to enable debugging */
 /* #define TUN_DEBUG 1 */
 
+#include <linux/types.h>
+
 #ifdef __KERNEL__
 
 #ifdef TUN_DEBUG
@@ -88,7 +90,7 @@ struct tun_struct {
 
 struct tun_pi {
        unsigned short flags;
-       unsigned short proto;
+       __be16 proto;
 };
 #define TUN_PKT_STRIP  0x0001
 
index 660b5010c2d96bdeecc331e635f5375c59937ec5..228eb4eb31295aae0df29a9637e1bf416e086c62 100644 (file)
@@ -17,6 +17,9 @@
 #define GRE_FLAGS      __constant_htons(0x00F8)
 #define GRE_VERSION    __constant_htons(0x0007)
 
+/* i_flags values for SIT mode */
+#define        SIT_ISATAP      0x0001
+
 struct ip_tunnel_parm
 {
        char                    name[IFNAMSIZ];
index 976d4b1067d1fb80ac72abc23f9e66e466e523f9..34f40efc7607d1801a0cb5d02407c0db9783a542 100644 (file)
 #ifdef __KERNEL__
 
 /* externally defined structs */
-struct vlan_group;
-struct net_device;
-struct packet_type;
-struct vlan_collection;
-struct vlan_dev_info;
 struct hlist_node;
 
 #include <linux/netdevice.h>
@@ -39,12 +34,30 @@ struct hlist_node;
 #define VLAN_ETH_DATA_LEN      1500    /* Max. octets in payload        */
 #define VLAN_ETH_FRAME_LEN     1518    /* Max. octets in frame sans FCS */
 
+/*
+ *     struct vlan_hdr - vlan header
+ *     @h_vlan_TCI: priority and VLAN ID
+ *     @h_vlan_encapsulated_proto: packet type ID or len
+ */
+struct vlan_hdr {
+       __be16  h_vlan_TCI;
+       __be16  h_vlan_encapsulated_proto;
+};
+
+/**
+ *     struct vlan_ethhdr - vlan ethernet header (ethhdr + vlan_hdr)
+ *     @h_dest: destination ethernet address
+ *     @h_source: source ethernet address
+ *     @h_vlan_proto: ethernet protocol (always 0x8100)
+ *     @h_vlan_TCI: priority and VLAN ID
+ *     @h_vlan_encapsulated_proto: packet type ID or len
+ */
 struct vlan_ethhdr {
-   unsigned char       h_dest[ETH_ALEN];          /* destination eth addr      */
-   unsigned char       h_source[ETH_ALEN];        /* source ether addr */
-   __be16               h_vlan_proto;              /* Should always be 0x8100 */
-   __be16               h_vlan_TCI;                /* Encapsulates priority and VLAN ID */
-   __be16              h_vlan_encapsulated_proto; /* packet type ID field (or len) */
+       unsigned char   h_dest[ETH_ALEN];
+       unsigned char   h_source[ETH_ALEN];
+       __be16          h_vlan_proto;
+       __be16          h_vlan_TCI;
+       __be16          h_vlan_encapsulated_proto;
 };
 
 #include <linux/skbuff.h>
@@ -54,18 +67,11 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
        return (struct vlan_ethhdr *)skb_mac_header(skb);
 }
 
-struct vlan_hdr {
-   __be16               h_vlan_TCI;                /* Encapsulates priority and VLAN ID */
-   __be16               h_vlan_encapsulated_proto; /* packet type ID field (or len) */
-};
-
 #define VLAN_VID_MASK  0xfff
 
 /* found in socket.c */
 extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
 
-#define VLAN_NAME "vlan"
-
 /* if this changes, algorithm will have to be reworked because this
  * depends on completely exhausting the VLAN identifier space.  Thus
  * it gives constant time look-up, but in many cases it wastes memory.
@@ -76,19 +82,22 @@ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
 
 struct vlan_group {
        int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */
+       unsigned int            nr_vlans;
        struct hlist_node       hlist;  /* linked list */
        struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS];
        struct rcu_head         rcu;
 };
 
-static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, int vlan_id)
+static inline struct net_device *vlan_group_get_device(struct vlan_group *vg,
+                                                      unsigned int vlan_id)
 {
        struct net_device **array;
        array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN];
        return array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN];
 }
 
-static inline void vlan_group_set_device(struct vlan_group *vg, int vlan_id,
+static inline void vlan_group_set_device(struct vlan_group *vg,
+                                        unsigned int vlan_id,
                                         struct net_device *dev)
 {
        struct net_device **array;
@@ -132,22 +141,18 @@ struct vlan_dev_info {
        struct proc_dir_entry *dent;    /* Holds the proc data */
        unsigned long cnt_inc_headroom_on_tx; /* How many times did we have to grow the skb on TX. */
        unsigned long cnt_encap_on_xmit;      /* How many times did we have to encapsulate the skb on TX. */
-       struct net_device_stats dev_stats; /* Device stats (rx-bytes, tx-pkts, etc...) */
 };
 
-#define VLAN_DEV_INFO(x) ((struct vlan_dev_info *)(x->priv))
-
-/* inline functions */
-
-static inline struct net_device_stats *vlan_dev_get_stats(struct net_device *dev)
+static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev)
 {
-       return &(VLAN_DEV_INFO(dev)->dev_stats);
+       return netdev_priv(dev);
 }
 
+/* inline functions */
 static inline __u32 vlan_get_ingress_priority(struct net_device *dev,
                                              unsigned short vlan_tag)
 {
-       struct vlan_dev_info *vip = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vip = vlan_dev_info(dev);
 
        return vip->ingress_priority_map[(vlan_tag >> 13) & 0x7];
 }
@@ -188,7 +193,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
 
        skb->dev->last_rx = jiffies;
 
-       stats = vlan_dev_get_stats(skb->dev);
+       stats = &skb->dev->stats;
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
 
@@ -266,12 +271,12 @@ static inline struct sk_buff *__vlan_put_tag(struct sk_buff *skb, unsigned short
        memmove(skb->data, skb->data + VLAN_HLEN, 2 * VLAN_ETH_ALEN);
 
        /* first, the ethernet type */
-       veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
+       veth->h_vlan_proto = htons(ETH_P_8021Q);
 
        /* now, the tag */
        veth->h_vlan_TCI = htons(tag);
 
-       skb->protocol = __constant_htons(ETH_P_8021Q);
+       skb->protocol = htons(ETH_P_8021Q);
        skb->mac_header -= VLAN_HLEN;
        skb->network_header -= VLAN_HLEN;
 
@@ -326,7 +331,7 @@ static inline int __vlan_get_tag(struct sk_buff *skb, unsigned short *tag)
 {
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb->data;
 
-       if (veth->h_vlan_proto != __constant_htons(ETH_P_8021Q)) {
+       if (veth->h_vlan_proto != htons(ETH_P_8021Q)) {
                return -EINVAL;
        }
 
index 3975cbf52f203116608b7003b1ba61a94afbe3ff..70c6df882694b70c6ba372b9fedc21b35bce396c 100644 (file)
@@ -246,13 +246,69 @@ struct sockaddr_in {
 #include <asm/byteorder.h> 
 
 #ifdef __KERNEL__
-/* Some random defines to make it easier in the kernel.. */
-#define LOOPBACK(x)    (((x) & htonl(0xff000000)) == htonl(0x7f000000))
-#define MULTICAST(x)   (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
-#define BADCLASS(x)    (((x) & htonl(0xf0000000)) == htonl(0xf0000000))
-#define ZERONET(x)     (((x) & htonl(0xff000000)) == htonl(0x00000000))
-#define LOCAL_MCAST(x) (((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
 
+static inline bool ipv4_is_loopback(__be32 addr)
+{
+       return (addr & htonl(0xff000000)) == htonl(0x7f000000);
+}
+
+static inline bool ipv4_is_multicast(__be32 addr)
+{
+       return (addr & htonl(0xf0000000)) == htonl(0xe0000000);
+}
+
+static inline bool ipv4_is_local_multicast(__be32 addr)
+{
+       return (addr & htonl(0xffffff00)) == htonl(0xe0000000);
+}
+
+static inline bool ipv4_is_lbcast(__be32 addr)
+{
+       /* limited broadcast */
+       return addr == INADDR_BROADCAST;
+}
+
+static inline bool ipv4_is_zeronet(__be32 addr)
+{
+       return (addr & htonl(0xff000000)) == htonl(0x00000000);
+}
+
+/* Special-Use IPv4 Addresses (RFC3330) */
+
+static inline bool ipv4_is_private_10(__be32 addr)
+{
+       return (addr & htonl(0xff000000)) == htonl(0x0a000000);
+}
+
+static inline bool ipv4_is_private_172(__be32 addr)
+{
+       return (addr & htonl(0xfff00000)) == htonl(0xac100000);
+}
+
+static inline bool ipv4_is_private_192(__be32 addr)
+{
+       return (addr & htonl(0xffff0000)) == htonl(0xc0a80000);
+}
+
+static inline bool ipv4_is_linklocal_169(__be32 addr)
+{
+       return (addr & htonl(0xffff0000)) == htonl(0xa9fe0000);
+}
+
+static inline bool ipv4_is_anycast_6to4(__be32 addr)
+{
+       return (addr & htonl(0xffffff00)) == htonl(0xc0586300);
+}
+
+static inline bool ipv4_is_test_192(__be32 addr)
+{
+       return (addr & htonl(0xffffff00)) == htonl(0xc0000200);
+}
+
+static inline bool ipv4_is_test_198(__be32 addr)
+{
+       return (addr & htonl(0xfffe0000)) == htonl(0xc6120000);
+}
 #endif
 
 #endif /* _LINUX_IN_H */
index d83fee2dc643603eca731cfb8e74df4a1a5d7284..8d9eaaebded7e753c6a79af7fb03064fea39cd90 100644 (file)
@@ -44,7 +44,8 @@ struct in_device
 };
 
 #define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1])
-#define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr)
+#define IPV4_DEVCONF_ALL(net, attr) \
+       IPV4_DEVCONF((*(net)->ipv4.devconf_all), attr)
 
 static inline int ipv4_devconf_get(struct in_device *in_dev, int index)
 {
@@ -71,16 +72,17 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
        ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val))
 
 #define IN_DEV_ANDCONF(in_dev, attr) \
-       (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr))
+       (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr) && \
+        IN_DEV_CONF_GET((in_dev), attr))
 #define IN_DEV_ORCONF(in_dev, attr) \
-       (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr))
+       (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr) || \
+        IN_DEV_CONF_GET((in_dev), attr))
 #define IN_DEV_MAXCONF(in_dev, attr) \
-       (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr)))
+       (max(IPV4_DEVCONF_ALL(in_dev->dev->nd_net, attr), \
+            IN_DEV_CONF_GET((in_dev), attr)))
 
 #define IN_DEV_FORWARD(in_dev)         IN_DEV_CONF_GET((in_dev), FORWARDING)
-#define IN_DEV_MFORWARD(in_dev)                (IPV4_DEVCONF_ALL(MC_FORWARDING) && \
-                                        IPV4_DEVCONF((in_dev)->cnf, \
-                                                     MC_FORWARDING))
+#define IN_DEV_MFORWARD(in_dev)                IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
 #define IN_DEV_RPFILTER(in_dev)                IN_DEV_ANDCONF((in_dev), RP_FILTER)
 #define IN_DEV_SOURCE_ROUTE(in_dev)    IN_DEV_ANDCONF((in_dev), \
                                                       ACCEPT_SOURCE_ROUTE)
@@ -127,15 +129,14 @@ struct in_ifaddr
 extern int register_inetaddr_notifier(struct notifier_block *nb);
 extern int unregister_inetaddr_notifier(struct notifier_block *nb);
 
-extern struct net_device       *ip_dev_find(__be32 addr);
+extern struct net_device *ip_dev_find(struct net *net, __be32 addr);
 extern int             inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
 extern int             devinet_ioctl(unsigned int cmd, void __user *);
 extern void            devinet_init(void);
-extern struct in_device        *inetdev_by_index(int);
+extern struct in_device        *inetdev_by_index(struct net *, int);
 extern __be32          inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
-extern __be32          inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
+extern __be32          inet_confirm_addr(struct in_device *in_dev, __be32 dst, __be32 local, int scope);
 extern struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix, __be32 mask);
-extern void            inet_forward_change(void);
 
 static __inline__ int inet_ifa_match(__be32 addr, struct in_ifaddr *ifa)
 {
index 596131ea46f40259004d1ff4c8fd38b47ee58bea..c414d90e647bd3f1c71ef7a5eefe9e8a933107b0 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/socket.h>
 
 struct poll_table_struct;
+struct pipe_inode_info;
 struct inode;
 struct net;
 
@@ -172,6 +173,8 @@ struct proto_ops {
                                      struct vm_area_struct * vma);
        ssize_t         (*sendpage)  (struct socket *sock, struct page *page,
                                      int offset, size_t size, int flags);
+       ssize_t         (*splice_read)(struct socket *sock,  loff_t *ppos,
+                                      struct pipe_inode_info *pipe, size_t len, unsigned int flags);
 };
 
 struct net_proto_family {
@@ -183,6 +186,13 @@ struct net_proto_family {
 struct iovec;
 struct kvec;
 
+enum {
+       SOCK_WAKE_IO,
+       SOCK_WAKE_WAITD,
+       SOCK_WAKE_SPACE,
+       SOCK_WAKE_URG,
+};
+
 extern int          sock_wake_async(struct socket *sk, int how, int band);
 extern int          sock_register(const struct net_proto_family *fam);
 extern void         sock_unregister(int family);
@@ -327,7 +337,6 @@ static const struct proto_ops name##_ops = {                        \
 
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
-extern ctl_table net_table[];
 extern int net_msg_cost;
 extern int net_msg_burst;
 #endif
index 16adac688af5923f0ab64d129fd566acff89c008..d74e79bacd2d19c240f5b8d27ba6fdd123c8ca9b 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/skbuff.h>
 #include <linux/net.h>
 #include <linux/if.h>
+#include <linux/in.h>
+#include <linux/in6.h>
 #include <linux/wait.h>
 #include <linux/list.h>
 #endif
 #define NFC_ALTERED 0x8000
 #endif
 
+enum nf_inet_hooks {
+       NF_INET_PRE_ROUTING,
+       NF_INET_LOCAL_IN,
+       NF_INET_FORWARD,
+       NF_INET_LOCAL_OUT,
+       NF_INET_POST_ROUTING,
+       NF_INET_NUMHOOKS
+};
+
+union nf_inet_addr {
+       u_int32_t       all[4];
+       __be32          ip;
+       __be32          ip6[4];
+       struct in_addr  in;
+       struct in6_addr in6;
+};
+
 #ifdef __KERNEL__
 #ifdef CONFIG_NETFILTER
 
@@ -92,19 +111,6 @@ struct nf_sockopt_ops
        struct module *owner;
 };
 
-/* Each queued (to userspace) skbuff has one of these. */
-struct nf_info
-{
-       /* The ops struct which sent us to userspace. */
-       struct nf_hook_ops *elem;
-       
-       /* If we're sent to userspace, this keeps housekeeping info */
-       int pf;
-       unsigned int hook;
-       struct net_device *indev, *outdev;
-       int (*okfn)(struct sk_buff *);
-};
-                                                                                
 /* Function to register/unregister hook points. */
 int nf_register_hook(struct nf_hook_ops *reg);
 void nf_unregister_hook(struct nf_hook_ops *reg);
@@ -118,71 +124,12 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
 
 #ifdef CONFIG_SYSCTL
 /* Sysctl registration */
-struct ctl_table_header *nf_register_sysctl_table(struct ctl_table *path,
-                                                 struct ctl_table *table);
-void nf_unregister_sysctl_table(struct ctl_table_header *header,
-                               struct ctl_table *table);
-extern struct ctl_table nf_net_netfilter_sysctl_path[];
-extern struct ctl_table nf_net_ipv4_netfilter_sysctl_path[];
+extern struct ctl_path nf_net_netfilter_sysctl_path[];
+extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
 #endif /* CONFIG_SYSCTL */
 
 extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
 
-/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
- * disappear once iptables is replaced with pkttables.  Please DO NOT use them
- * for any new code! */
-#define NF_LOG_TCPSEQ          0x01    /* Log TCP sequence numbers */
-#define NF_LOG_TCPOPT          0x02    /* Log TCP options */
-#define NF_LOG_IPOPT           0x04    /* Log IP options */
-#define NF_LOG_UID             0x08    /* Log UID owning local socket */
-#define NF_LOG_MASK            0x0f
-
-#define NF_LOG_TYPE_LOG                0x01
-#define NF_LOG_TYPE_ULOG       0x02
-
-struct nf_loginfo {
-       u_int8_t type;
-       union {
-               struct {
-                       u_int32_t copy_len;
-                       u_int16_t group;
-                       u_int16_t qthreshold;
-               } ulog;
-               struct {
-                       u_int8_t level;
-                       u_int8_t logflags;
-               } log;
-       } u;
-};
-
-typedef void nf_logfn(unsigned int pf,
-                     unsigned int hooknum,
-                     const struct sk_buff *skb,
-                     const struct net_device *in,
-                     const struct net_device *out,
-                     const struct nf_loginfo *li,
-                     const char *prefix);
-
-struct nf_logger {
-       struct module   *me;
-       nf_logfn        *logfn;
-       char            *name;
-};
-
-/* Function to register/unregister log function. */
-int nf_log_register(int pf, struct nf_logger *logger);
-void nf_log_unregister(struct nf_logger *logger);
-void nf_log_unregister_pf(int pf);
-
-/* Calls the registered backend logging function */
-void nf_log_packet(int pf,
-                  unsigned int hooknum,
-                  const struct sk_buff *skb,
-                  const struct net_device *in,
-                  const struct net_device *out,
-                  struct nf_loginfo *li,
-                  const char *fmt, ...);
-
 int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
                 struct net_device *indev, struct net_device *outdev,
                 int (*okfn)(struct sk_buff *), int thresh);
@@ -265,65 +212,28 @@ int compat_nf_setsockopt(struct sock *sk, int pf, int optval,
 int compat_nf_getsockopt(struct sock *sk, int pf, int optval,
                char __user *opt, int *len);
 
-/* Packet queuing */
-struct nf_queue_handler {
-       int (*outfn)(struct sk_buff *skb, struct nf_info *info,
-                    unsigned int queuenum, void *data);
-       void *data;
-       char *name;
-};
-extern int nf_register_queue_handler(int pf, 
-                                     struct nf_queue_handler *qh);
-extern int nf_unregister_queue_handler(int pf,
-                                      struct nf_queue_handler *qh);
-extern void nf_unregister_queue_handlers(struct nf_queue_handler *qh);
-extern void nf_reinject(struct sk_buff *skb,
-                       struct nf_info *info,
-                       unsigned int verdict);
-
-/* FIXME: Before cache is ever used, this must be implemented for real. */
-extern void nf_invalidate_cache(int pf);
-
 /* Call this before modifying an existing packet: ensures it is
    modifiable and linear to the point you care about (writable_len).
    Returns true or false. */
 extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len);
 
-static inline void nf_csum_replace4(__sum16 *sum, __be32 from, __be32 to)
-{
-       __be32 diff[] = { ~from, to };
-
-       *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
-}
-
-static inline void nf_csum_replace2(__sum16 *sum, __be16 from, __be16 to)
-{
-       nf_csum_replace4(sum, (__force __be32)from, (__force __be32)to);
-}
-
-extern void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
-                                     __be32 from, __be32 to, int pseudohdr);
-
-static inline void nf_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
-                                     __be16 from, __be16 to, int pseudohdr)
-{
-       nf_proto_csum_replace4(sum, skb, (__force __be32)from,
-                               (__force __be32)to, pseudohdr);
-}
+struct flowi;
+struct nf_queue_entry;
 
 struct nf_afinfo {
        unsigned short  family;
        __sum16         (*checksum)(struct sk_buff *skb, unsigned int hook,
                                    unsigned int dataoff, u_int8_t protocol);
+       int             (*route)(struct dst_entry **dst, struct flowi *fl);
        void            (*saveroute)(const struct sk_buff *skb,
-                                    struct nf_info *info);
+                                    struct nf_queue_entry *entry);
        int             (*reroute)(struct sk_buff *skb,
-                                  const struct nf_info *info);
+                                  const struct nf_queue_entry *entry);
        int             route_key_size;
 };
 
-extern struct nf_afinfo *nf_afinfo[];
-static inline struct nf_afinfo *nf_get_afinfo(unsigned short family)
+extern const struct nf_afinfo *nf_afinfo[NPROTO];
+static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
 {
        return rcu_dereference(nf_afinfo[family]);
 }
@@ -332,7 +242,7 @@ static inline __sum16
 nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff,
            u_int8_t protocol, unsigned short family)
 {
-       struct nf_afinfo *afinfo;
+       const struct nf_afinfo *afinfo;
        __sum16 csum = 0;
 
        rcu_read_lock();
@@ -343,10 +253,8 @@ nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff,
        return csum;
 }
 
-extern int nf_register_afinfo(struct nf_afinfo *afinfo);
-extern void nf_unregister_afinfo(struct nf_afinfo *afinfo);
-
-#define nf_info_reroute(x) ((void *)x + sizeof(struct nf_info))
+extern int nf_register_afinfo(const struct nf_afinfo *afinfo);
+extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
 
 #include <net/flow.h>
 extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
@@ -354,11 +262,16 @@ extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
 static inline void
 nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
 {
-#if defined(CONFIG_IP_NF_NAT_NEEDED) || defined(CONFIG_NF_NAT_NEEDED)
+#ifdef CONFIG_NF_NAT_NEEDED
        void (*decodefn)(struct sk_buff *, struct flowi *);
 
-       if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
-               decodefn(skb, fl);
+       if (family == AF_INET) {
+               rcu_read_lock();
+               decodefn = rcu_dereference(ip_nat_decode_session);
+               if (decodefn)
+                       decodefn(skb, fl);
+               rcu_read_unlock();
+       }
 #endif
 }
 
index b87e83a5e0707e5f9e06c18f09a25fbc42e31c62..91fef0cae42f2bf28feddeb0d0d0ad715baaaee8 100644 (file)
@@ -10,6 +10,7 @@ header-y += xt_DSCP.h
 header-y += xt_MARK.h
 header-y += xt_NFLOG.h
 header-y += xt_NFQUEUE.h
+header-y += xt_RATEEST.h
 header-y += xt_SECMARK.h
 header-y += xt_TCPMSS.h
 header-y += xt_comment.h
@@ -20,14 +21,17 @@ header-y += xt_dccp.h
 header-y += xt_dscp.h
 header-y += xt_esp.h
 header-y += xt_hashlimit.h
+header-y += xt_iprange.h
 header-y += xt_helper.h
 header-y += xt_length.h
 header-y += xt_limit.h
 header-y += xt_mac.h
 header-y += xt_mark.h
 header-y += xt_multiport.h
+header-y += xt_owner.h
 header-y += xt_pkttype.h
 header-y += xt_policy.h
+header-y += xt_rateest.h
 header-y += xt_realm.h
 header-y += xt_sctp.h
 header-y += xt_state.h
index 9e0dae07861ef7bcc5c15d08bd9ed5e51e6063ff..bad1eb760f615b8ffbc925fe1b8f2fb215e1bfa3 100644 (file)
@@ -129,6 +129,14 @@ enum ip_conntrack_events
        /* 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 {
index aabd24ac763116517edb114f92aed330e649a382..26f9226ea72b18ff379e2d553ccdc00112c95617 100644 (file)
@@ -31,7 +31,7 @@ struct nf_conn;
 
 extern int get_h225_addr(struct nf_conn *ct, unsigned char *data,
                         TransportAddress *taddr,
-                        union nf_conntrack_address *addr, __be16 *port);
+                        union nf_inet_addr *addr, __be16 *port);
 extern void nf_conntrack_h245_expect(struct nf_conn *new,
                                     struct nf_conntrack_expect *this);
 extern void nf_conntrack_q931_expect(struct nf_conn *new,
@@ -39,12 +39,12 @@ extern void nf_conntrack_q931_expect(struct nf_conn *new,
 extern int (*set_h245_addr_hook) (struct sk_buff *skb,
                                  unsigned char **data, int dataoff,
                                  H245_TransportAddress *taddr,
-                                 union nf_conntrack_address *addr,
+                                 union nf_inet_addr *addr,
                                  __be16 port);
 extern int (*set_h225_addr_hook) (struct sk_buff *skb,
                                  unsigned char **data, int dataoff,
                                  TransportAddress *taddr,
-                                 union nf_conntrack_address *addr,
+                                 union nf_inet_addr *addr,
                                  __be16 port);
 extern int (*set_sig_addr_hook) (struct sk_buff *skb,
                                 struct nf_conn *ct,
index 5cf2c115cce4c2ba80f8763df9bda154800d4096..768f78c4ac53cf24dd1613c83205ee66076bf8fc 100644 (file)
@@ -21,7 +21,6 @@ struct ip_ct_sctp
        enum sctp_conntrack state;
 
        __be32 vtag[IP_CT_DIR_MAX];
-       u_int32_t ttag[IP_CT_DIR_MAX];
 };
 
 #endif /* _NF_CONNTRACK_SCTP_H */
index 4affa3fe78e0dbd0cd68e0fb3a2afc0d5c40675b..e3e1533aba2d9656ce6fed4282a9589494c006e2 100644 (file)
@@ -37,6 +37,9 @@ enum ctattr_type {
        CTA_ID,
        CTA_NAT_DST,
        CTA_TUPLE_MASTER,
+       CTA_NAT_SEQ_ADJ_ORIG,
+       CTA_NAT_SEQ_ADJ_REPLY,
+       CTA_SECMARK,
        __CTA_MAX
 };
 #define CTA_MAX (__CTA_MAX - 1)
@@ -119,6 +122,14 @@ enum ctattr_protonat {
 };
 #define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
 
+enum ctattr_natseq {
+       CTA_NAT_SEQ_CORRECTION_POS,
+       CTA_NAT_SEQ_OFFSET_BEFORE,
+       CTA_NAT_SEQ_OFFSET_AFTER,
+       __CTA_NAT_SEQ_MAX
+};
+#define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
+
 enum ctattr_expect {
        CTA_EXPECT_UNSPEC,
        CTA_EXPECT_MASTER,
index 5966afa026e958482f871f4b83f737eb671ffbf9..a85721332924e934b6f128912f70cf65e32f5911 100644 (file)
@@ -47,6 +47,7 @@ enum nfulnl_attr_type {
        NFULA_UID,                      /* user id of socket */
        NFULA_SEQ,                      /* instance-local sequence number */
        NFULA_SEQ_GLOBAL,               /* global sequence number */
+       NFULA_GID,                      /* group id of socket */
 
        __NFULA_MAX
 };
index 03e6ce979eaa52f1a58493f1f020e5298ab16f70..b99ede51318a25c9d895259fc0eabbeebe0a9635 100644 (file)
@@ -126,6 +126,49 @@ struct xt_counters_info
 
 #define XT_INV_PROTO           0x40    /* Invert the sense of PROTO. */
 
+/* fn returns 0 to continue iteration */
+#define XT_MATCH_ITERATE(type, e, fn, args...)                 \
+({                                                             \
+       unsigned int __i;                                       \
+       int __ret = 0;                                          \
+       struct xt_entry_match *__m;                             \
+                                                               \
+       for (__i = sizeof(type);                                \
+            __i < (e)->target_offset;                          \
+            __i += __m->u.match_size) {                        \
+               __m = (void *)e + __i;                          \
+                                                               \
+               __ret = fn(__m , ## args);                      \
+               if (__ret != 0)                                 \
+                       break;                                  \
+       }                                                       \
+       __ret;                                                  \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
+({                                                             \
+       unsigned int __i, __n;                                  \
+       int __ret = 0;                                          \
+       type *__entry;                                          \
+                                                               \
+       for (__i = 0, __n = 0; __i < (size);                    \
+            __i += __entry->next_offset, __n++) {              \
+               __entry = (void *)(entries) + __i;              \
+               if (__n < n)                                    \
+                       continue;                               \
+                                                               \
+               __ret = fn(__entry , ## args);                  \
+               if (__ret != 0)                                 \
+                       break;                                  \
+       }                                                       \
+       __ret;                                                  \
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
+       XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+
 #ifdef __KERNEL__
 
 #include <linux/netdevice.h>
@@ -265,13 +308,16 @@ struct xt_table_info
        unsigned int initial_entries;
 
        /* Entry points and underflows */
-       unsigned int hook_entry[NF_IP_NUMHOOKS];
-       unsigned int underflow[NF_IP_NUMHOOKS];
+       unsigned int hook_entry[NF_INET_NUMHOOKS];
+       unsigned int underflow[NF_INET_NUMHOOKS];
 
        /* ipt_entry tables: one per CPU */
-       char *entries[NR_CPUS];
+       /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
+       char *entries[1];
 };
 
+#define XT_TABLE_INFO_SZ (offsetof(struct xt_table_info, entries) \
+                         + nr_cpu_ids * sizeof(char *))
 extern int xt_register_target(struct xt_target *target);
 extern void xt_unregister_target(struct xt_target *target);
 extern int xt_register_targets(struct xt_target *target, unsigned int n);
@@ -378,9 +424,13 @@ struct compat_xt_counters_info
 extern void xt_compat_lock(int af);
 extern void xt_compat_unlock(int af);
 
+extern int xt_compat_add_offset(int af, unsigned int offset, short delta);
+extern void xt_compat_flush_offsets(int af);
+extern short xt_compat_calc_jump(int af, unsigned int offset);
+
 extern int xt_compat_match_offset(struct xt_match *match);
-extern void xt_compat_match_from_user(struct xt_entry_match *m,
-                                     void **dstptr, int *size);
+extern int xt_compat_match_from_user(struct xt_entry_match *m,
+                                    void **dstptr, int *size);
 extern int xt_compat_match_to_user(struct xt_entry_match *m,
                                   void __user **dstptr, int *size);
 
index 9f744689fffc2facc4b45af2f80927519cc582dd..4e58ba43c289ab7a8bf943c4c9c54b538a647c80 100644 (file)
@@ -22,4 +22,9 @@ struct xt_connmark_target_info {
        u_int8_t mode;
 };
 
+struct xt_connmark_tginfo1 {
+       u_int32_t ctmark, ctmask, nfmask;
+       u_int8_t mode;
+};
+
 #endif /*_XT_CONNMARK_H_target*/
index 3c7c963997bd3ab67121562e595725fc9f00de49..14da1968e2c627c3cc35aed0798a7d90aebd847e 100644 (file)
@@ -17,4 +17,9 @@ struct xt_DSCP_info {
        u_int8_t dscp;
 };
 
+struct xt_tos_target_info {
+       u_int8_t tos_value;
+       u_int8_t tos_mask;
+};
+
 #endif /* _XT_DSCP_TARGET_H */
index b021e93ee5d64d2c7524abe40300a610dfdfcbff..778b278fd9f278e825a1caae596e11c3b4c47ae7 100644 (file)
@@ -18,4 +18,8 @@ struct xt_mark_target_info_v1 {
        u_int8_t mode;
 };
 
+struct xt_mark_tginfo2 {
+       u_int32_t mark, mask;
+};
+
 #endif /*_XT_MARK_H_target */
diff --git a/include/linux/netfilter/xt_RATEEST.h b/include/linux/netfilter/xt_RATEEST.h
new file mode 100644 (file)
index 0000000..f79e313
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _XT_RATEEST_TARGET_H
+#define _XT_RATEEST_TARGET_H
+
+struct xt_rateest_target_info {
+       char                    name[IFNAMSIZ];
+       int8_t                  interval;
+       u_int8_t                ewma_log;
+
+       /* Used internally by the kernel */
+       struct xt_rateest       *est __attribute__((aligned(8)));
+};
+
+#endif /* _XT_RATEEST_TARGET_H */
diff --git a/include/linux/netfilter/xt_TCPOPTSTRIP.h b/include/linux/netfilter/xt_TCPOPTSTRIP.h
new file mode 100644 (file)
index 0000000..2db5432
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _XT_TCPOPTSTRIP_H
+#define _XT_TCPOPTSTRIP_H
+
+#define tcpoptstrip_set_bit(bmap, idx) \
+       (bmap[(idx) >> 5] |= 1U << (idx & 31))
+#define tcpoptstrip_test_bit(bmap, idx) \
+       (((1U << (idx & 31)) & bmap[(idx) >> 5]) != 0)
+
+struct xt_tcpoptstrip_target_info {
+       u_int32_t strip_bmap[8];
+};
+
+#endif /* _XT_TCPOPTSTRIP_H */
index 37e933c9987d0ddf680cc58c3ffb00719d644c67..7e3284bcbd2bd118470cbd5b9fc9ec955ad9ccea 100644 (file)
@@ -5,12 +5,17 @@ struct xt_connlimit_data;
 
 struct xt_connlimit_info {
        union {
-               __be32 v4_mask;
-               __be32 v6_mask[4];
+               union nf_inet_addr mask;
+#ifndef __KERNEL__
+               union {
+                       __be32 v4_mask;
+                       __be32 v6_mask[4];
+               };
+#endif
        };
        unsigned int limit, inverse;
 
-       /* this needs to be at the end */
+       /* Used internally by the kernel */
        struct xt_connlimit_data *data __attribute__((aligned(8)));
 };
 
index c592f6ae08832ca0d46cb181d2ee62eb811a1232..359ef86918dcca37af7e7529578a6fc9236f6898 100644 (file)
@@ -15,4 +15,9 @@ struct xt_connmark_info {
        u_int8_t invert;
 };
 
+struct xt_connmark_mtinfo1 {
+       u_int32_t mark, mask;
+       u_int8_t invert;
+};
+
 #endif /*_XT_CONNMARK_H*/
index 70b6f718cf4cbe5fa48d51725a7d00f4fdf55054..d2492a3329bed137c9c46f7354a0b1f0599e005f 100644 (file)
@@ -6,7 +6,9 @@
 #define _XT_CONNTRACK_H
 
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
-#include <linux/in.h>
+#ifdef __KERNEL__
+#      include <linux/in.h>
+#endif
 
 #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
 #define XT_CONNTRACK_STATE_INVALID (1 << 0)
@@ -60,4 +62,16 @@ struct xt_conntrack_info
        /* Inverse flags */
        u_int8_t invflags;
 };
+
+struct xt_conntrack_mtinfo1 {
+       union nf_inet_addr origsrc_addr, origsrc_mask;
+       union nf_inet_addr origdst_addr, origdst_mask;
+       union nf_inet_addr replsrc_addr, replsrc_mask;
+       union nf_inet_addr repldst_addr, repldst_mask;
+       u_int32_t expires_min, expires_max;
+       u_int16_t l4proto;
+       u_int8_t state_mask, status_mask;
+       u_int8_t match_flags, invert_flags;
+};
+
 #endif /*_XT_CONNTRACK_H*/
index 1da61e6acaf77b99eb0a3aa16a7ca84679770a50..f49bc1a648dc5fd505551e0d4521fcb3f622de52 100644 (file)
@@ -20,4 +20,10 @@ struct xt_dscp_info {
        u_int8_t invert;
 };
 
+struct xt_tos_match_info {
+       u_int8_t tos_mask;
+       u_int8_t tos_value;
+       u_int8_t invert;
+};
+
 #endif /* _XT_DSCP_H */
index b4556b8edbfd22e16aab5d8f860025dd3930dd52..c19972e4564da6182cf4fc3b9799ba2f44aa8e58 100644 (file)
@@ -29,9 +29,9 @@ struct hashlimit_cfg {
 struct xt_hashlimit_info {
        char name [IFNAMSIZ];           /* name */
        struct hashlimit_cfg cfg;
-       struct xt_hashlimit_htable *hinfo;
 
        /* Used internally by the kernel */
+       struct xt_hashlimit_htable *hinfo;
        union {
                void *ptr;
                struct xt_hashlimit_info *master;
diff --git a/include/linux/netfilter/xt_iprange.h b/include/linux/netfilter/xt_iprange.h
new file mode 100644 (file)
index 0000000..a4299c7
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _LINUX_NETFILTER_XT_IPRANGE_H
+#define _LINUX_NETFILTER_XT_IPRANGE_H 1
+
+enum {
+       IPRANGE_SRC     = 1 << 0,       /* match source IP address */
+       IPRANGE_DST     = 1 << 1,       /* match destination IP address */
+       IPRANGE_SRC_INV = 1 << 4,       /* negate the condition */
+       IPRANGE_DST_INV = 1 << 5,       /* -"- */
+};
+
+struct xt_iprange_mtinfo {
+       union nf_inet_addr src_min, src_max;
+       union nf_inet_addr dst_min, dst_max;
+       u_int8_t flags;
+};
+
+#endif /* _LINUX_NETFILTER_XT_IPRANGE_H */
index 802dd4842cafa95e74684c9e6b1983f58fce49a0..fae74bc3f34e753b342391f4dd58e664a932c268 100644 (file)
@@ -6,4 +6,9 @@ struct xt_mark_info {
     u_int8_t invert;
 };
 
+struct xt_mark_mtinfo1 {
+       u_int32_t mark, mask;
+       u_int8_t invert;
+};
+
 #endif /*_XT_MARK_H*/
diff --git a/include/linux/netfilter/xt_owner.h b/include/linux/netfilter/xt_owner.h
new file mode 100644 (file)
index 0000000..eacd34e
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _XT_OWNER_MATCH_H
+#define _XT_OWNER_MATCH_H
+
+enum {
+       XT_OWNER_UID    = 1 << 0,
+       XT_OWNER_GID    = 1 << 1,
+       XT_OWNER_SOCKET = 1 << 2,
+};
+
+struct xt_owner_match_info {
+       u_int32_t uid;
+       u_int32_t gid;
+       u_int8_t match, invert;
+};
+
+#endif /* _XT_OWNER_MATCH_H */
index 45654d359a68c39653af02d832e2f7b2a2eec3de..053d8cc6546401988b13d8fb613d818a7a913deb 100644 (file)
@@ -27,18 +27,33 @@ struct xt_policy_spec
                        reqid:1;
 };
 
+#ifndef __KERNEL__
 union xt_policy_addr
 {
        struct in_addr  a4;
        struct in6_addr a6;
 };
+#endif
 
 struct xt_policy_elem
 {
-       union xt_policy_addr    saddr;
-       union xt_policy_addr    smask;
-       union xt_policy_addr    daddr;
-       union xt_policy_addr    dmask;
+       union {
+#ifdef __KERNEL__
+               struct {
+                       union nf_inet_addr saddr;
+                       union nf_inet_addr smask;
+                       union nf_inet_addr daddr;
+                       union nf_inet_addr dmask;
+               };
+#else
+               struct {
+                       union xt_policy_addr saddr;
+                       union xt_policy_addr smask;
+                       union xt_policy_addr daddr;
+                       union xt_policy_addr dmask;
+               };
+#endif
+       };
        __be32                  spi;
        u_int32_t               reqid;
        u_int8_t                proto;
index acd7fd77bbeeacec8eb60cc28c797b03d0394c06..4c8368d781e5d2f570ac19a74e8c68f633f768eb 100644 (file)
@@ -9,6 +9,8 @@ enum xt_quota_flags {
 struct xt_quota_info {
        u_int32_t               flags;
        u_int32_t               pad;
+
+       /* Used internally by the kernel */
        aligned_u64             quota;
        struct xt_quota_info    *master;
 };
diff --git a/include/linux/netfilter/xt_rateest.h b/include/linux/netfilter/xt_rateest.h
new file mode 100644 (file)
index 0000000..2010cb7
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _XT_RATEEST_MATCH_H
+#define _XT_RATEEST_MATCH_H
+
+enum xt_rateest_match_flags {
+       XT_RATEEST_MATCH_INVERT = 1<<0,
+       XT_RATEEST_MATCH_ABS    = 1<<1,
+       XT_RATEEST_MATCH_REL    = 1<<2,
+       XT_RATEEST_MATCH_DELTA  = 1<<3,
+       XT_RATEEST_MATCH_BPS    = 1<<4,
+       XT_RATEEST_MATCH_PPS    = 1<<5,
+};
+
+enum xt_rateest_match_mode {
+       XT_RATEEST_MATCH_NONE,
+       XT_RATEEST_MATCH_EQ,
+       XT_RATEEST_MATCH_LT,
+       XT_RATEEST_MATCH_GT,
+};
+
+struct xt_rateest_match_info {
+       char                    name1[IFNAMSIZ];
+       char                    name2[IFNAMSIZ];
+       u_int16_t               flags;
+       u_int16_t               mode;
+       u_int32_t               bps1;
+       u_int32_t               pps1;
+       u_int32_t               bps2;
+       u_int32_t               pps2;
+
+       /* Used internally by the kernel */
+       struct xt_rateest       *est1 __attribute__((aligned(8)));
+       struct xt_rateest       *est2 __attribute__((aligned(8)));
+};
+
+#endif /* _XT_RATEEST_MATCH_H */
index c344e9916e23b53cbac2eca346983d8538bc6b38..3d38bc975048285348b9cc5bc1d705232b14bc0d 100644 (file)
@@ -23,6 +23,7 @@ struct xt_statistic_info {
                struct {
                        u_int32_t       every;
                        u_int32_t       packet;
+                       /* Used internally by the kernel */
                        u_int32_t       count;
                } nth;
        } u;
index 3b3419f2637d03d18017f667140e493c653a2ad3..bb21dd1aee2d3ec610e73fb39a219bcd39af92d9 100644 (file)
@@ -12,6 +12,8 @@ struct xt_string_info
        char      pattern[XT_STRING_MAX_PATTERN_SIZE];
        u_int8_t  patlen;
        u_int8_t  invert;
+
+       /* Used internally by the kernel */
        struct ts_config __attribute__((aligned(8))) *config;
 };
 
index 2fc73fa8e37f859fbeec4948e7ab009ef0e1a333..53dd4df27aa1a881722f8c6a055de3b1e1b7e946 100644 (file)
@@ -217,21 +217,8 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e
 }
 
 /* fn returns 0 to continue iteration */
-#define ARPT_ENTRY_ITERATE(entries, size, fn, args...)         \
-({                                                             \
-       unsigned int __i;                                       \
-       int __ret = 0;                                          \
-       struct arpt_entry *__entry;                             \
-                                                               \
-       for (__i = 0; __i < (size); __i += __entry->next_offset) { \
-               __entry = (void *)(entries) + __i;              \
-                                                               \
-               __ret = fn(__entry , ## args);                  \
-               if (__ret != 0)                                 \
-                       break;                                  \
-       }                                                       \
-       __ret;                                                  \
-})
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
 
 /*
  *     Main firewall chains definitions and global var's definitions.
@@ -293,6 +280,37 @@ extern unsigned int arpt_do_table(struct sk_buff *skb,
                                  const struct net_device *out,
                                  struct arpt_table *table);
 
-#define ARPT_ALIGN(s) (((s) + (__alignof__(struct arpt_entry)-1)) & ~(__alignof__(struct arpt_entry)-1))
+#define ARPT_ALIGN(s) XT_ALIGN(s)
+
+#ifdef CONFIG_COMPAT
+#include <net/compat.h>
+
+struct compat_arpt_entry
+{
+       struct arpt_arp arp;
+       u_int16_t target_offset;
+       u_int16_t next_offset;
+       compat_uint_t comefrom;
+       struct compat_xt_counters counters;
+       unsigned char elems[0];
+};
+
+static inline struct arpt_entry_target *
+compat_arpt_get_target(struct compat_arpt_entry *e)
+{
+       return (void *)e + e->target_offset;
+}
+
+#define COMPAT_ARPT_ALIGN(s)   COMPAT_XT_ALIGN(s)
+
+/* fn returns 0 to continue iteration */
+#define COMPAT_ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct compat_arpt_entry, entries, size, fn, ## args)
+
+#define COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
+       XT_ENTRY_ITERATE_CONTINUE(struct compat_arpt_entry, entries, size, n, \
+                                 fn, ## args)
+
+#endif /* CONFIG_COMPAT */
 #endif /*__KERNEL__*/
 #endif /* _ARPTABLES_H */
index 1a63adf5c4c13527273e5d2603a6ed4563357f5a..9a10092e358cacead0c968e694eb2b0f426d4cbf 100644 (file)
@@ -36,7 +36,6 @@
 #define NFC_IP_DST_PT          0x0400
 /* Something else about the proto */
 #define NFC_IP_PROTO_UNKNOWN   0x2000
-#endif /* ! __KERNEL__ */
 
 /* IP Hooks */
 /* After promisc drops, checksum checks. */
@@ -50,6 +49,7 @@
 /* Packets about to hit the wire. */
 #define NF_IP_POST_ROUTING     4
 #define NF_IP_NUMHOOKS         5
+#endif /* ! __KERNEL__ */
 
 enum nf_ip_hook_priorities {
        NF_IP_PRI_FIRST = INT_MIN,
index d79ed69cbc1fb94b1d8a9919948cc7909a19631a..45fcad91e67b4df4246b47c425e941e06f3c1117 100644 (file)
@@ -156,10 +156,10 @@ struct ipt_getinfo
        unsigned int valid_hooks;
 
        /* Hook entry points: one per netfilter hook. */
-       unsigned int hook_entry[NF_IP_NUMHOOKS];
+       unsigned int hook_entry[NF_INET_NUMHOOKS];
 
        /* Underflow points. */
-       unsigned int underflow[NF_IP_NUMHOOKS];
+       unsigned int underflow[NF_INET_NUMHOOKS];
 
        /* Number of entries */
        unsigned int num_entries;
@@ -185,10 +185,10 @@ struct ipt_replace
        unsigned int size;
 
        /* Hook entry points. */
-       unsigned int hook_entry[NF_IP_NUMHOOKS];
+       unsigned int hook_entry[NF_INET_NUMHOOKS];
 
        /* Underflow points. */
-       unsigned int underflow[NF_IP_NUMHOOKS];
+       unsigned int underflow[NF_INET_NUMHOOKS];
 
        /* Information about old entries: */
        /* Number of counters (must be equal to current number of entries). */
@@ -229,60 +229,12 @@ ipt_get_target(struct ipt_entry *e)
 }
 
 /* fn returns 0 to continue iteration */
-#define IPT_MATCH_ITERATE(e, fn, args...)      \
-({                                             \
-       unsigned int __i;                       \
-       int __ret = 0;                          \
-       struct ipt_entry_match *__match;        \
-                                               \
-       for (__i = sizeof(struct ipt_entry);    \
-            __i < (e)->target_offset;          \
-            __i += __match->u.match_size) {    \
-               __match = (void *)(e) + __i;    \
-                                               \
-               __ret = fn(__match , ## args);  \
-               if (__ret != 0)                 \
-                       break;                  \
-       }                                       \
-       __ret;                                  \
-})
+#define IPT_MATCH_ITERATE(e, fn, args...) \
+       XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
 
 /* fn returns 0 to continue iteration */
-#define IPT_ENTRY_ITERATE(entries, size, fn, args...)          \
-({                                                             \
-       unsigned int __i;                                       \
-       int __ret = 0;                                          \
-       struct ipt_entry *__entry;                              \
-                                                               \
-       for (__i = 0; __i < (size); __i += __entry->next_offset) { \
-               __entry = (void *)(entries) + __i;              \
-                                                               \
-               __ret = fn(__entry , ## args);                  \
-               if (__ret != 0)                                 \
-                       break;                                  \
-       }                                                       \
-       __ret;                                                  \
-})
-
-/* fn returns 0 to continue iteration */
-#define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
-({                                                             \
-       unsigned int __i, __n;                                  \
-       int __ret = 0;                                          \
-       struct ipt_entry *__entry;                              \
-                                                               \
-       for (__i = 0, __n = 0; __i < (size);                    \
-            __i += __entry->next_offset, __n++) {              \
-               __entry = (void *)(entries) + __i;              \
-               if (__n < n)                                    \
-                       continue;                               \
-                                                               \
-               __ret = fn(__entry , ## args);                  \
-               if (__ret != 0)                                 \
-                       break;                                  \
-       }                                                       \
-       __ret;                                                  \
-})
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
 
 /*
  *     Main firewall chains definitions and global var's definitions.
@@ -359,8 +311,28 @@ struct compat_ipt_entry
        unsigned char elems[0];
 };
 
+/* Helper functions */
+static inline struct ipt_entry_target *
+compat_ipt_get_target(struct compat_ipt_entry *e)
+{
+       return (void *)e + e->target_offset;
+}
+
 #define COMPAT_IPT_ALIGN(s)    COMPAT_XT_ALIGN(s)
 
+/* fn returns 0 to continue iteration */
+#define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \
+       XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
+       XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \
+                                 fn, ## args)
+
 #endif /* CONFIG_COMPAT */
 #endif /*__KERNEL__*/
 #endif /* _IPTABLES_H */
index daf50be22c9d5f1cac9846e086cc68a55390147d..e5a3687c8a7238d90c6be77941429d0ca6071db0 100644 (file)
@@ -27,6 +27,7 @@ struct ipt_clusterip_tgt_info {
        u_int32_t hash_mode;
        u_int32_t hash_initval;
 
+       /* Used internally by the kernel */
        struct clusterip_config *config;
 };
 
index 166ed01a8122927f8247f409cea83c641a144b4e..446de6aef9838f07775ae5d28008b1d6ca379ca7 100644 (file)
@@ -1,6 +1,20 @@
 #ifndef _IPT_ADDRTYPE_H
 #define _IPT_ADDRTYPE_H
 
+enum {
+       IPT_ADDRTYPE_INVERT_SOURCE      = 0x0001,
+       IPT_ADDRTYPE_INVERT_DEST        = 0x0002,
+       IPT_ADDRTYPE_LIMIT_IFACE_IN     = 0x0004,
+       IPT_ADDRTYPE_LIMIT_IFACE_OUT    = 0x0008,
+};
+
+struct ipt_addrtype_info_v1 {
+       u_int16_t       source;         /* source-type mask */
+       u_int16_t       dest;           /* dest-type mask */
+       u_int32_t       flags;
+};
+
+/* revision 0 */
 struct ipt_addrtype_info {
        u_int16_t       source;         /* source-type mask */
        u_int16_t       dest;           /* dest-type mask */
index a92fefc3c7ecbc222f76694101c600886f61b6da..5f1aebde4d2fa6457c633b98d7845b8f0186254f 100644 (file)
@@ -2,11 +2,7 @@
 #define _IPT_IPRANGE_H
 
 #include <linux/types.h>
-
-#define IPRANGE_SRC            0x01    /* Match source IP address */
-#define IPRANGE_DST            0x02    /* Match destination IP address */
-#define IPRANGE_SRC_INV                0x10    /* Negate the condition */
-#define IPRANGE_DST_INV                0x20    /* Negate the condition */
+#include <linux/netfilter/xt_iprange.h>
 
 struct ipt_iprange {
        /* Inclusive: network order. */
index 66ca8e3100dca2eb31ae5fc8bcafdf0f43bf6750..3475a65dae9b52d33683b140d43dd6aa902eb0cf 100644 (file)
@@ -40,8 +40,6 @@
 #define NFC_IP6_DST_PT           0x0400
 /* Something else about the proto */
 #define NFC_IP6_PROTO_UNKNOWN    0x2000
-#endif /* ! __KERNEL__ */
-
 
 /* IP6 Hooks */
 /* After promisc drops, checksum checks. */
@@ -55,6 +53,7 @@
 /* Packets about to hit the wire. */
 #define NF_IP6_POST_ROUTING    4
 #define NF_IP6_NUMHOOKS                5
+#endif /* ! __KERNEL__ */
 
 
 enum nf_ip6_hook_priorities {
index 7dc481ce7cba057d55ae26d1832aa9ef76005dd2..110801d699ee95ab2f649f20a482bf179a1f7bbd 100644 (file)
@@ -216,10 +216,10 @@ struct ip6t_getinfo
        unsigned int valid_hooks;
 
        /* Hook entry points: one per netfilter hook. */
-       unsigned int hook_entry[NF_IP6_NUMHOOKS];
+       unsigned int hook_entry[NF_INET_NUMHOOKS];
 
        /* Underflow points. */
-       unsigned int underflow[NF_IP6_NUMHOOKS];
+       unsigned int underflow[NF_INET_NUMHOOKS];
 
        /* Number of entries */
        unsigned int num_entries;
@@ -245,10 +245,10 @@ struct ip6t_replace
        unsigned int size;
 
        /* Hook entry points. */
-       unsigned int hook_entry[NF_IP6_NUMHOOKS];
+       unsigned int hook_entry[NF_INET_NUMHOOKS];
 
        /* Underflow points. */
-       unsigned int underflow[NF_IP6_NUMHOOKS];
+       unsigned int underflow[NF_INET_NUMHOOKS];
 
        /* Information about old entries: */
        /* Number of counters (must be equal to current number of entries). */
@@ -289,40 +289,12 @@ ip6t_get_target(struct ip6t_entry *e)
 }
 
 /* fn returns 0 to continue iteration */
-#define IP6T_MATCH_ITERATE(e, fn, args...)     \
-({                                             \
-       unsigned int __i;                       \
-       int __ret = 0;                          \
-       struct ip6t_entry_match *__m;           \
-                                               \
-       for (__i = sizeof(struct ip6t_entry);   \
-            __i < (e)->target_offset;          \
-            __i += __m->u.match_size) {        \
-               __m = (void *)(e) + __i;        \
-                                               \
-               __ret = fn(__m , ## args);      \
-               if (__ret != 0)                 \
-                       break;                  \
-       }                                       \
-       __ret;                                  \
-})
+#define IP6T_MATCH_ITERATE(e, fn, args...) \
+       XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
 
 /* fn returns 0 to continue iteration */
-#define IP6T_ENTRY_ITERATE(entries, size, fn, args...)         \
-({                                                             \
-       unsigned int __i;                                       \
-       int __ret = 0;                                          \
-       struct ip6t_entry *__e;                                 \
-                                                               \
-       for (__i = 0; __i < (size); __i += __e->next_offset) {  \
-               __e = (void *)(entries) + __i;                  \
-                                                               \
-               __ret = fn(__e , ## args);                      \
-               if (__ret != 0)                                 \
-                       break;                                  \
-       }                                                       \
-       __ret;                                                  \
-})
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
 
 /*
  *     Main firewall chains definitions and global var's definitions.
@@ -352,7 +324,42 @@ extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
                              const struct in6_addr *mask,
                              const struct in6_addr *addr2);
 
-#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
+#define IP6T_ALIGN(s) XT_ALIGN(s)
 
+#ifdef CONFIG_COMPAT
+#include <net/compat.h>
+
+struct compat_ip6t_entry
+{
+       struct ip6t_ip6 ipv6;
+       compat_uint_t nfcache;
+       u_int16_t target_offset;
+       u_int16_t next_offset;
+       compat_uint_t comefrom;
+       struct compat_xt_counters counters;
+       unsigned char elems[0];
+};
+
+static inline struct ip6t_entry_target *
+compat_ip6t_get_target(struct compat_ip6t_entry *e)
+{
+       return (void *)e + e->target_offset;
+}
+
+#define COMPAT_IP6T_ALIGN(s)   COMPAT_XT_ALIGN(s)
+
+/* fn returns 0 to continue iteration */
+#define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \
+       XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define COMPAT_IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+       XT_ENTRY_ITERATE(struct compat_ip6t_entry, entries, size, fn, ## args)
+
+#define COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \
+       XT_ENTRY_ITERATE_CONTINUE(struct compat_ip6t_entry, entries, size, n, \
+                                 fn, ## args)
+
+#endif /* CONFIG_COMPAT */
 #endif /*__KERNEL__*/
 #endif /* _IP6_TABLES_H */
index d5bfaba595c79e796be9d105b0359d02ac5a88a8..bd13b6f4a98ec0932503273858988795bcc5bf35 100644 (file)
@@ -178,6 +178,7 @@ extern struct sock *netlink_kernel_create(struct net *net,
                                          void (*input)(struct sk_buff *skb),
                                          struct mutex *cb_mutex,
                                          struct module *module);
+extern void netlink_kernel_release(struct sock *sk);
 extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
 extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group);
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
@@ -245,7 +246,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
 }
 
 #define NLMSG_NEW(skb, pid, seq, type, len, flags) \
-({     if (skb_tailroom(skb) < (int)NLMSG_SPACE(len)) \
+({     if (unlikely(skb_tailroom(skb) < (int)NLMSG_SPACE(len))) \
                goto nlmsg_failure; \
        __nlmsg_put(skb, pid, seq, type, len, flags); })
 
index 20250d963d72014a81a687ca7652bad4a873bceb..a0525a1f4715d7cce2e1e883070b75a655b12359 100644 (file)
@@ -20,12 +20,11 @@ struct netpoll {
 
        u32 local_ip, remote_ip;
        u16 local_port, remote_port;
-       u8 local_mac[ETH_ALEN], remote_mac[ETH_ALEN];
+       u8 remote_mac[ETH_ALEN];
 };
 
 struct netpoll_info {
        atomic_t refcnt;
-       int rx_flags;
        spinlock_t rx_lock;
        struct netpoll *rx_np; /* netpoll that registered an rx_hook */
        struct sk_buff_head arp_tx; /* list of arp requests to reply to */
@@ -51,12 +50,12 @@ static inline int netpoll_rx(struct sk_buff *skb)
        unsigned long flags;
        int ret = 0;
 
-       if (!npinfo || (!npinfo->rx_np && !npinfo->rx_flags))
+       if (!npinfo || !npinfo->rx_np)
                return 0;
 
        spin_lock_irqsave(&npinfo->rx_lock, flags);
-       /* check rx_flags again with the lock held */
-       if (npinfo->rx_flags && __netpoll_rx(skb))
+       /* check rx_np again with the lock held */
+       if (npinfo->rx_np && __netpoll_rx(skb))
                ret = 1;
        spin_unlock_irqrestore(&npinfo->rx_lock, flags);
 
index 538ee1dd3d0af43959a44d1a7b37a549eb128162..9fecf902419c574eae20efe379fe50b2e8adbb9c 100644 (file)
@@ -6,6 +6,18 @@
  * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
  */
 
+/**
+ * DOC: Station handling
+ *
+ * Stations are added per interface, but a special case exists with VLAN
+ * interfaces. When a station is bound to an AP interface, it may be moved
+ * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN).
+ * The station is still assumed to belong to the AP interface it was added
+ * to.
+ *
+ * TODO: need more info?
+ */
+
 /**
  * enum nl80211_commands - supported nl80211 commands
  *
  *     userspace to request deletion of a virtual interface, then requires
  *     attribute %NL80211_ATTR_IFINDEX.
  *
+ * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
+ *     by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
+ * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT 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_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
+ *     or %NL80211_ATTR_MAC.
+ *
+ * @NL80211_CMD_GET_BEACON: retrieve beacon information (returned in a
+ *     %NL80222_CMD_NEW_BEACON message)
+ * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface
+ *     using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD,
+ *     %NL80211_BEACON_HEAD and %NL80211_BEACON_TAIL attributes.
+ * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface,
+ *     parameters are like for %NL80211_CMD_SET_BEACON.
+ * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it
+ *
+ * @NL80211_CMD_GET_STATION: Get station attributes for station identified by
+ *     %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_SET_STATION: Set station attributes for station identified by
+ *     %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the
+ *     the interface identified by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC
+ *     or, if no MAC address given, all stations, on the interface identified
+ *     by %NL80211_ATTR_IFINDEX.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -54,6 +95,21 @@ enum nl80211_commands {
        NL80211_CMD_NEW_INTERFACE,
        NL80211_CMD_DEL_INTERFACE,
 
+       NL80211_CMD_GET_KEY,
+       NL80211_CMD_SET_KEY,
+       NL80211_CMD_NEW_KEY,
+       NL80211_CMD_DEL_KEY,
+
+       NL80211_CMD_GET_BEACON,
+       NL80211_CMD_SET_BEACON,
+       NL80211_CMD_NEW_BEACON,
+       NL80211_CMD_DEL_BEACON,
+
+       NL80211_CMD_GET_STATION,
+       NL80211_CMD_SET_STATION,
+       NL80211_CMD_NEW_STATION,
+       NL80211_CMD_DEL_STATION,
+
        /* add commands here */
 
        /* used to define NL80211_CMD_MAX below */
@@ -75,6 +131,36 @@ enum nl80211_commands {
  * @NL80211_ATTR_IFNAME: network interface name
  * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
  *
+ * @NL80211_ATTR_MAC: MAC address (various uses)
+ *
+ * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of
+ *     16 bytes encryption key followed by 8 bytes each for TX and RX MIC
+ *     keys
+ * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3)
+ * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
+ *     section 7.3.2.25.1, e.g. 0x000FAC04)
+ * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
+ *     CCMP keys, each six bytes in little endian
+ *
+ * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU
+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing
+ * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE
+ * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE
+ *
+ * @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.
+ * @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
+ *     rates as defined by IEEE 802.11 7.3.2.2 but without the length
+ *     restriction (at most %NL80211_MAX_SUPP_RATES).
+ * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
+ *     to, or the AP interface the station was originally added to to.
+ * @NL80211_ATTR_STA_STATS: statistics for a station, part of station info
+ *     given for %NL80211_CMD_GET_STATION, nested attribute containing
+ *     info as possible, see &enum nl80211_sta_stats.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -89,12 +175,34 @@ enum nl80211_attrs {
        NL80211_ATTR_IFNAME,
        NL80211_ATTR_IFTYPE,
 
+       NL80211_ATTR_MAC,
+
+       NL80211_ATTR_KEY_DATA,
+       NL80211_ATTR_KEY_IDX,
+       NL80211_ATTR_KEY_CIPHER,
+       NL80211_ATTR_KEY_SEQ,
+       NL80211_ATTR_KEY_DEFAULT,
+
+       NL80211_ATTR_BEACON_INTERVAL,
+       NL80211_ATTR_DTIM_PERIOD,
+       NL80211_ATTR_BEACON_HEAD,
+       NL80211_ATTR_BEACON_TAIL,
+
+       NL80211_ATTR_STA_AID,
+       NL80211_ATTR_STA_FLAGS,
+       NL80211_ATTR_STA_LISTEN_INTERVAL,
+       NL80211_ATTR_STA_SUPPORTED_RATES,
+       NL80211_ATTR_STA_VLAN,
+       NL80211_ATTR_STA_STATS,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
        NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
 };
 
+#define NL80211_MAX_SUPP_RATES 32
+
 /**
  * enum nl80211_iftype - (virtual) interface types
  *
@@ -126,4 +234,50 @@ enum nl80211_iftype {
        NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1
 };
 
+/**
+ * enum nl80211_sta_flags - station flags
+ *
+ * Station flags. When a station is added to an AP interface, it is
+ * assumed to be already associated (and hence authenticated.)
+ *
+ * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X)
+ * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
+ *     with short barker preamble
+ * @NL80211_STA_FLAG_WME: station is WME/QoS capable
+ */
+enum nl80211_sta_flags {
+       __NL80211_STA_FLAG_INVALID,
+       NL80211_STA_FLAG_AUTHORIZED,
+       NL80211_STA_FLAG_SHORT_PREAMBLE,
+       NL80211_STA_FLAG_WME,
+
+       /* keep last */
+       __NL80211_STA_FLAG_AFTER_LAST,
+       NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
+};
+
+/**
+ * enum nl80211_sta_stats - station statistics
+ *
+ * These attribute types are used with %NL80211_ATTR_STA_STATS
+ * when getting information about a station.
+ *
+ * @__NL80211_STA_STAT_INVALID: attribute number 0 is reserved
+ * @NL80211_STA_STAT_INACTIVE_TIME: time since last activity (u32, msecs)
+ * @NL80211_STA_STAT_RX_BYTES: total received bytes (u32, from this station)
+ * @NL80211_STA_STAT_TX_BYTES: total transmitted bytes (u32, to this station)
+ * @__NL80211_STA_STAT_AFTER_LAST: internal
+ * @NL80211_STA_STAT_MAX: highest possible station stats attribute
+ */
+enum nl80211_sta_stats {
+       __NL80211_STA_STAT_INVALID,
+       NL80211_STA_STAT_INACTIVE_TIME,
+       NL80211_STA_STAT_RX_BYTES,
+       NL80211_STA_STAT_TX_BYTES,
+
+       /* keep last */
+       __NL80211_STA_STAT_AFTER_LAST,
+       NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1
+};
+
 #endif /* __LINUX_NL80211_H */
index 1fbd0256e86b6f0b0da7c1dfb1b287a83a43a749..c69531348363dde5551164c50f4fac84e9180cf8 100644 (file)
 #define PCI_DEVICE_ID_NX2_5706         0x164a
 #define PCI_DEVICE_ID_NX2_5708         0x164c
 #define PCI_DEVICE_ID_TIGON3_5702FE    0x164d
+#define PCI_DEVICE_ID_NX2_57710                0x164e
 #define PCI_DEVICE_ID_TIGON3_5705      0x1653
 #define PCI_DEVICE_ID_TIGON3_5705_2    0x1654
 #define PCI_DEVICE_ID_TIGON3_5720      0x1658
 #define PCI_DEVICE_ID_ALTIMA_AC9100    0x03ea
 #define PCI_DEVICE_ID_ALTIMA_AC1003    0x03eb
 
+#define PCI_VENDOR_ID_BELKIN           0x1799
+#define PCI_DEVICE_ID_BELKIN_F5D7010V7 0x701f
+
 #define PCI_VENDOR_ID_LENOVO           0x17aa
 
 #define PCI_VENDOR_ID_ARECA            0x17d3
 #define PCI_DEVICE_ID_HERC_WIN         0x5732
 #define PCI_DEVICE_ID_HERC_UNI         0x5832
 
+#define PCI_VENDOR_ID_RDC              0x17f3
+
 #define PCI_VENDOR_ID_SITECOM          0x182d
 #define PCI_DEVICE_ID_SITECOM_DC105V2  0x3069
 
diff --git a/include/linux/pcounter.h b/include/linux/pcounter.h
new file mode 100644 (file)
index 0000000..a82d9f2
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __LINUX_PCOUNTER_H
+#define __LINUX_PCOUNTER_H
+/*
+ * Using a dynamic percpu 'int' variable has a cost :
+ * 1) Extra dereference
+ * Current per_cpu_ptr() implementation uses an array per 'percpu variable'.
+ * 2) memory cost of NR_CPUS*(32+sizeof(void *)) instead of num_possible_cpus()*4
+ *
+ * This pcounter implementation is an abstraction to be able to use
+ * either a static or a dynamic per cpu variable.
+ * One dynamic per cpu variable gets a fast & cheap implementation, we can
+ * change pcounter implementation too.
+ */
+struct pcounter {
+#ifdef CONFIG_SMP
+       void            (*add)(struct pcounter *self, int inc);
+       int             (*getval)(const struct pcounter *self, int cpu);
+       int             *per_cpu_values;
+#else
+       int             val;
+#endif
+};
+
+#ifdef CONFIG_SMP
+#include <linux/percpu.h>
+
+#define DEFINE_PCOUNTER(NAME)                                          \
+static DEFINE_PER_CPU(int, NAME##_pcounter_values);                    \
+static void NAME##_pcounter_add(struct pcounter *self, int val)                \
+{                                                                      \
+       __get_cpu_var(NAME##_pcounter_values) += val;                   \
+}                                                                      \
+static int NAME##_pcounter_getval(const struct pcounter *self, int cpu)        \
+{                                                                      \
+       return per_cpu(NAME##_pcounter_values, cpu);                    \
+}                                                                      \
+
+#define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER)              \
+       MEMBER = {                                              \
+               .add    = NAME##_pcounter_add,                  \
+               .getval = NAME##_pcounter_getval,               \
+       }
+
+
+static inline void pcounter_add(struct pcounter *self, int inc)
+{
+       self->add(self, inc);
+}
+
+extern int pcounter_getval(const struct pcounter *self);
+extern int pcounter_alloc(struct pcounter *self);
+extern void pcounter_free(struct pcounter *self);
+
+
+#else /* CONFIG_SMP */
+
+static inline void pcounter_add(struct pcounter *self, int inc)
+{
+       self->val += inc;
+}
+
+static inline int pcounter_getval(const struct pcounter *self)
+{
+       return self->val;
+}
+
+#define DEFINE_PCOUNTER(NAME)
+#define PCOUNTER_MEMBER_INITIALIZER(NAME, MEMBER)
+#define pcounter_alloc(self) 0
+#define pcounter_free(self)
+
+#endif /* CONFIG_SMP */
+
+#endif /* __LINUX_PCOUNTER_H */
index 919af93b70596e70a06bdd10363c1d57a1aa50f4..32761352e858cd4c95b15ab215b8c39be9fe756e 100644 (file)
@@ -83,6 +83,8 @@ struct tc_ratespec
        __u32           rate;
 };
 
+#define TC_RTAB_SIZE   1024
+
 /* FIFO section */
 
 struct tc_fifo_qopt
index a5316829215b4baa861db001db567ac93d836282..8f92546b403d205633bb51e417913a1ec420a41d 100644 (file)
@@ -201,6 +201,8 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
 extern struct proc_dir_entry *proc_net_fops_create(struct net *net,
        const char *name, mode_t mode, const struct file_operations *fops);
 extern void proc_net_remove(struct net *net, const char *name);
+extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+       struct proc_dir_entry *parent);
 
 #else
 
index 4e81836191df82ebaa5d8bf19e658ad29e92c16e..b014f6b7fe2918784d1095c6cd8c25f3668862a9 100644 (file)
@@ -100,6 +100,13 @@ enum {
        RTM_NEWNDUSEROPT = 68,
 #define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
 
+       RTM_NEWADDRLABEL = 72,
+#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
+       RTM_DELADDRLABEL,
+#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
+       RTM_GETADDRLABEL,
+#define RTM_GETADDRLABEL RTM_GETADDRLABEL
+
        __RTM_MAX,
 #define RTM_MAX                (((__RTM_MAX + 3) & ~3) - 1)
 };
@@ -613,11 +620,11 @@ extern int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
 ({     data = RTA_PAYLOAD(rta) >= len ? RTA_DATA(rta) : NULL; \
        __rtattr_parse_nested_compat(tb, max, rta, len); })
 
-extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
-extern int rtnl_unicast(struct sk_buff *skb, u32 pid);
-extern int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
+extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
+extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
+extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
                       struct nlmsghdr *nlh, gfp_t flags);
-extern void rtnl_set_sk_err(u32 group, int error);
+extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
 extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
 extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
                              u32 id, u32 ts, u32 tsage, long expires,
index ebbc02b325fc88cc65dbab470def7e3d80084608..648dfeb444db33dee57c705b591fe68bbd3eaa9c 100644 (file)
@@ -63,5 +63,18 @@ extern struct list_head *seq_list_start_head(struct list_head *head,
 extern struct list_head *seq_list_next(void *v, struct list_head *head,
                loff_t *ppos);
 
+struct net;
+struct seq_net_private {
+       struct net *net;
+};
+
+int seq_open_net(struct inode *, struct file *,
+                const struct seq_operations *, int);
+int seq_release_net(struct inode *, struct file *);
+static inline struct net *seq_file_net(struct seq_file *seq)
+{
+       return ((struct seq_net_private *)seq->private)->net;
+}
+
 #endif
 #endif
index bddd50bd6878856ba20363ec2dda6101cde0f879..c618fbf7d173c4974da2adf399edf51a2c5034cc 100644 (file)
@@ -95,6 +95,7 @@
 
 struct net_device;
 struct scatterlist;
+struct pipe_inode_info;
 
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 struct nf_conntrack {
@@ -287,6 +288,7 @@ struct sk_buff {
        __u8                    pkt_type:3,
                                fclone:2,
                                ipvs_property:1,
+                               peeked:1,
                                nf_trace:1;
        __be16                  protocol;
 
@@ -1537,6 +1539,8 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
                     skb = skb->prev)
 
 
+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,
                                         int noblock, int *err);
 extern unsigned int    datagram_poll(struct file *file, struct socket *sock,
@@ -1548,7 +1552,7 @@ extern int               skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
                                                        int hlen,
                                                        struct iovec *iov);
 extern void           skb_free_datagram(struct sock *sk, struct sk_buff *skb);
-extern void           skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
+extern int            skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
                                         unsigned int flags);
 extern __wsum         skb_checksum(const struct sk_buff *skb, int offset,
                                    int len, __wsum csum);
@@ -1559,6 +1563,11 @@ extern int              skb_store_bits(struct sk_buff *skb, int offset,
 extern __wsum         skb_copy_and_csum_bits(const struct sk_buff *skb,
                                              int offset, u8 *to, int len,
                                              __wsum csum);
+extern int             skb_splice_bits(struct sk_buff *skb,
+                                               unsigned int offset,
+                                               struct pipe_inode_info *pipe,
+                                               unsigned int len,
+                                               unsigned int flags);
 extern void           skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
 extern void           skb_split(struct sk_buff *skb,
                                 struct sk_buff *skb1, const u32 len);
index 89f0c2b5f405d27e15d9defd989a859f2434772c..86d3effb283626f8b053db379ceacca52c6bef06 100644 (file)
@@ -217,4 +217,35 @@ enum
        __LINUX_MIB_MAX
 };
 
+/* linux Xfrm mib definitions */
+enum
+{
+       LINUX_MIB_XFRMNUM = 0,
+       LINUX_MIB_XFRMINERROR,                  /* XfrmInError */
+       LINUX_MIB_XFRMINBUFFERERROR,            /* XfrmInBufferError */
+       LINUX_MIB_XFRMINHDRERROR,               /* XfrmInHdrError */
+       LINUX_MIB_XFRMINNOSTATES,               /* XfrmInNoStates */
+       LINUX_MIB_XFRMINSTATEPROTOERROR,        /* XfrmInStateProtoError */
+       LINUX_MIB_XFRMINSTATEMODEERROR,         /* XfrmInStateModeError */
+       LINUX_MIB_XFRMINSEQOUTOFWINDOW,         /* XfrmInSeqOutOfWindow */
+       LINUX_MIB_XFRMINSTATEEXPIRED,           /* XfrmInStateExpired */
+       LINUX_MIB_XFRMINSTATEMISMATCH,          /* XfrmInStateMismatch */
+       LINUX_MIB_XFRMINSTATEINVALID,           /* XfrmInStateInvalid */
+       LINUX_MIB_XFRMINTMPLMISMATCH,           /* XfrmInTmplMismatch */
+       LINUX_MIB_XFRMINNOPOLS,                 /* XfrmInNoPols */
+       LINUX_MIB_XFRMINPOLBLOCK,               /* XfrmInPolBlock */
+       LINUX_MIB_XFRMINPOLERROR,               /* XfrmInPolError */
+       LINUX_MIB_XFRMOUTERROR,                 /* XfrmOutError */
+       LINUX_MIB_XFRMOUTBUNDLEGENERROR,        /* XfrmOutBundleGenError */
+       LINUX_MIB_XFRMOUTBUNDLECHECKERROR,      /* XfrmOutBundleCheckError */
+       LINUX_MIB_XFRMOUTNOSTATES,              /* XfrmOutNoStates */
+       LINUX_MIB_XFRMOUTSTATEPROTOERROR,       /* XfrmOutStateProtoError */
+       LINUX_MIB_XFRMOUTSTATEMODEERROR,        /* XfrmOutStateModeError */
+       LINUX_MIB_XFRMOUTSTATEEXPIRED,          /* XfrmOutStateExpired */
+       LINUX_MIB_XFRMOUTPOLBLOCK,              /* XfrmOutPolBlock */
+       LINUX_MIB_XFRMOUTPOLDEAD,               /* XfrmOutPolDead */
+       LINUX_MIB_XFRMOUTPOLERROR,              /* XfrmOutPolError */
+       __LINUX_MIB_XFRMMAX
+};
+
 #endif /* _LINUX_SNMP_H */
index c22ef1c1afb803e651a2b656a0add216e5d98590..bd2b30a74e7694b67038ee0d69865580b4081d2f 100644 (file)
@@ -24,7 +24,6 @@ struct __kernel_sockaddr_storage {
 #include <linux/types.h>               /* pid_t                        */
 #include <linux/compiler.h>            /* __user                       */
 
-extern int sysctl_somaxconn;
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void socket_seq_show(struct seq_file *seq);
@@ -185,6 +184,7 @@ struct ucred {
 #define AF_PPPOX       24      /* PPPoX sockets                */
 #define AF_WANPIPE     25      /* Wanpipe API Sockets */
 #define AF_LLC         26      /* Linux LLC                    */
+#define AF_CAN         29      /* Controller Area Network      */
 #define AF_TIPC                30      /* TIPC sockets                 */
 #define AF_BLUETOOTH   31      /* Bluetooth sockets            */
 #define AF_IUCV                32      /* IUCV sockets                 */
@@ -220,6 +220,7 @@ struct ucred {
 #define PF_PPPOX       AF_PPPOX
 #define PF_WANPIPE     AF_WANPIPE
 #define PF_LLC         AF_LLC
+#define PF_CAN         AF_CAN
 #define PF_TIPC                AF_TIPC
 #define PF_BLUETOOTH   AF_BLUETOOTH
 #define PF_IUCV                AF_IUCV
index 33e447f98a545c891192ab8b76acc78c92d6fc34..528dcb93c2f21b08cad24fd56e3a6ae8e707dbc0 100644 (file)
@@ -53,6 +53,7 @@ struct splice_pipe_desc {
        int nr_pages;                   /* number of pages in map */
        unsigned int flags;             /* splice flags */
        const struct pipe_buf_operations *ops;/* ops associated with output pipe */
+       void (*spd_release)(struct splice_pipe_desc *, unsigned int);
 };
 
 typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
index 2b5c312c496057bc9ffdb09ed292f16075952a0a..e18f5c23b9301eddd5e37dc9fce527ac63c47335 100644 (file)
@@ -15,22 +15,19 @@ struct pcmcia_device;
 struct ssb_bus;
 struct ssb_driver;
 
-
-struct ssb_sprom_r1 {
-       u16 pci_spid;           /* Subsystem Product ID for PCI */
-       u16 pci_svid;           /* Subsystem Vendor ID for PCI */
-       u16 pci_pid;            /* Product ID for PCI */
+struct ssb_sprom {
+       u8 revision;
        u8 il0mac[6];           /* MAC address for 802.11b/g */
        u8 et0mac[6];           /* MAC address for Ethernet */
        u8 et1mac[6];           /* MAC address for 802.11a */
-       u8 et0phyaddr:5;        /* MII address for enet0 */
-       u8 et1phyaddr:5;        /* MII address for enet1 */
-       u8 et0mdcport:1;        /* MDIO for enet0 */
-       u8 et1mdcport:1;        /* MDIO for enet1 */
-       u8 board_rev;           /* Board revision */
-       u8 country_code:4;      /* Country Code */
-       u8 antenna_a:2;         /* Antenna 0/1 available for A-PHY */
-       u8 antenna_bg:2;        /* Antenna 0/1 available for B-PHY and G-PHY */
+       u8 et0phyaddr;          /* MII address for enet0 */
+       u8 et1phyaddr;          /* MII address for enet1 */
+       u8 et0mdcport;          /* MDIO for enet0 */
+       u8 et1mdcport;          /* MDIO for enet1 */
+       u8 board_rev;           /* Board revision number from SPROM. */
+       u8 country_code;        /* Country Code */
+       u8 ant_available_a;     /* A-PHY antenna available bits (up to 4) */
+       u8 ant_available_bg;    /* B/G-PHY antenna available bits (up to 4) */
        u16 pa0b0;
        u16 pa0b1;
        u16 pa0b2;
@@ -41,61 +38,26 @@ struct ssb_sprom_r1 {
        u8 gpio1;               /* GPIO pin 1 */
        u8 gpio2;               /* GPIO pin 2 */
        u8 gpio3;               /* GPIO pin 3 */
-       u16 maxpwr_a;           /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */
-       u16 maxpwr_bg;          /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */
+       u16 maxpwr_a;           /* A-PHY Amplifier Max Power (in dBm Q5.2) */
+       u16 maxpwr_bg;          /* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
        u8 itssi_a;             /* Idle TSSI Target for A-PHY */
        u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
        u16 boardflags_lo;      /* Boardflags (low 16 bits) */
-       u8 antenna_gain_a;      /* A-PHY Antenna gain (in dBm Q5.2) */
-       u8 antenna_gain_bg;     /* B/G-PHY Antenna gain (in dBm Q5.2) */
-       u8 oem[8];              /* OEM string (rev 1 only) */
-};
-
-struct ssb_sprom_r2 {
        u16 boardflags_hi;      /* Boardflags (high 16 bits) */
-       u8 maxpwr_a_lo;         /* A-PHY Max Power Low */
-       u8 maxpwr_a_hi;         /* A-PHY Max Power High */
-       u16 pa1lob0;            /* A-PHY PA Low Settings */
-       u16 pa1lob1;            /* A-PHY PA Low Settings */
-       u16 pa1lob2;            /* A-PHY PA Low Settings */
-       u16 pa1hib0;            /* A-PHY PA High Settings */
-       u16 pa1hib1;            /* A-PHY PA High Settings */
-       u16 pa1hib2;            /* A-PHY PA High Settings */
-       u8 ofdm_pwr_off;        /* OFDM Power Offset from CCK Level */
-       u8 country_str[2];      /* Two char Country Code */
-};
-
-struct ssb_sprom_r3 {
-       u32 ofdmapo;            /* A-PHY OFDM Mid Power Offset */
-       u32 ofdmalpo;           /* A-PHY OFDM Low Power Offset */
-       u32 ofdmahpo;           /* A-PHY OFDM High Power Offset */
-       u8 gpioldc_on_cnt;      /* GPIO LED Powersave Duty Cycle ON count */
-       u8 gpioldc_off_cnt;     /* GPIO LED Powersave Duty Cycle OFF count */
-       u8 cckpo_1M:4;          /* CCK Power Offset for Rate 1M */
-       u8 cckpo_2M:4;          /* CCK Power Offset for Rate 2M */
-       u8 cckpo_55M:4;         /* CCK Power Offset for Rate 5.5M */
-       u8 cckpo_11M:4;         /* CCK Power Offset for Rate 11M */
-       u32 ofdmgpo;            /* G-PHY OFDM Power Offset */
-};
-
-struct ssb_sprom_r4 {
-       /* TODO */
-};
 
-struct ssb_sprom {
-       u8 revision;
-       u8 crc;
-       /* The valid r# fields are selected by the "revision".
-        * Revision 3 and lower inherit from lower revisions.
-        */
-       union {
+       /* Antenna gain values for up to 4 antennas
+        * on each band. Values in dBm/4 (Q5.2). Negative gain means the
+        * loss in the connectors is bigger than the gain. */
+       struct {
                struct {
-                       struct ssb_sprom_r1 r1;
-                       struct ssb_sprom_r2 r2;
-                       struct ssb_sprom_r3 r3;
-               };
-               struct ssb_sprom_r4 r4;
-       };
+                       s8 a0, a1, a2, a3;
+               } ghz24;        /* 2.4GHz band */
+               struct {
+                       s8 a0, a1, a2, a3;
+               } ghz5;         /* 5GHz band */
+       } antenna_gain;
+
+       /* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
 };
 
 /* Information about the PCB the circuitry is soldered on. */
@@ -270,7 +232,8 @@ struct ssb_bus {
        struct ssb_device *mapped_device;
        /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
        u8 mapped_pcmcia_seg;
-       /* Lock for core and segment switching. */
+       /* Lock for core and segment switching.
+        * On PCMCIA-host busses this is used to protect the whole MMIO access. */
        spinlock_t bar_lock;
 
        /* The bus this backplane is running on. */
@@ -288,6 +251,7 @@ struct ssb_bus {
        /* ID information about the Chip. */
        u16 chip_id;
        u16 chip_rev;
+       u16 sprom_size;         /* number of words in sprom */
        u8 chip_package;
 
        /* List of devices (cores) on the backplane. */
@@ -402,6 +366,13 @@ static inline void ssb_pcihost_unregister(struct pci_driver *driver)
 {
        pci_unregister_driver(driver);
 }
+
+static inline
+void ssb_pcihost_set_power_state(struct ssb_device *sdev, pci_power_t state)
+{
+       if (sdev->bus->bustype == SSB_BUSTYPE_PCI)
+               pci_set_power_state(sdev->bus->host_pci, state);
+}
 #endif /* CONFIG_SSB_PCIHOST */
 
 
index 47c7c71a5acf844d5dbb92e7cfba2f2dfb7d3b2a..ebad0bac980137ee84286f897b0b64207e8541af 100644 (file)
 #define  SSB_IDLOW_SSBREV      0xF0000000 /* Sonics Backplane Revision code */
 #define  SSB_IDLOW_SSBREV_22   0x00000000 /* <= 2.2 */
 #define  SSB_IDLOW_SSBREV_23   0x10000000 /* 2.3 */
+#define  SSB_IDLOW_SSBREV_24   0x40000000 /* ?? Found in BCM4328 */
+#define  SSB_IDLOW_SSBREV_25   0x50000000 /* ?? Not Found yet */
+#define  SSB_IDLOW_SSBREV_26   0x60000000 /* ?? Found in some BCM4311/2 */
+#define  SSB_IDLOW_SSBREV_27   0x70000000 /* ?? Found in some BCM4311/2 */
 #define SSB_IDHIGH             0x0FFC     /* SB Identification High */
 #define  SSB_IDHIGH_RCLO       0x0000000F /* Revision Code (low part) */
 #define  SSB_IDHIGH_CC         0x00008FF0 /* Core Code */
  */
 #define SSB_SPROMSIZE_WORDS            64
 #define SSB_SPROMSIZE_BYTES            (SSB_SPROMSIZE_WORDS * sizeof(u16))
+#define SSB_SPROMSIZE_WORDS_R123       64
+#define SSB_SPROMSIZE_WORDS_R4         220
+#define SSB_SPROMSIZE_BYTES_R123       (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
+#define SSB_SPROMSIZE_BYTES_R4         (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
 #define SSB_SPROM_BASE                 0x1000
 #define SSB_SPROM_REVISION             0x107E
 #define  SSB_SPROM_REVISION_REV                0x00FF  /* SPROM Revision number */
 #define  SSB_SPROM_REVISION_CRC                0xFF00  /* SPROM CRC8 value */
 #define  SSB_SPROM_REVISION_CRC_SHIFT  8
+
 /* SPROM Revision 1 */
 #define SSB_SPROM1_SPID                        0x1004  /* Subsystem Product ID for PCI */
 #define SSB_SPROM1_SVID                        0x1006  /* Subsystem Vendor ID for PCI */
 #define  SSB_SPROM1_BINF_BREV          0x00FF  /* Board Revision */
 #define  SSB_SPROM1_BINF_CCODE         0x0F00  /* Country Code */
 #define  SSB_SPROM1_BINF_CCODE_SHIFT   8
-#define  SSB_SPROM1_BINF_ANTA          0x3000  /* Available A-PHY antennas */
-#define  SSB_SPROM1_BINF_ANTA_SHIFT    12
-#define  SSB_SPROM1_BINF_ANTBG         0xC000  /* Available B-PHY antennas */
-#define  SSB_SPROM1_BINF_ANTBG_SHIFT   14
+#define  SSB_SPROM1_BINF_ANTBG         0x3000  /* Available B-PHY and G-PHY antennas */
+#define  SSB_SPROM1_BINF_ANTBG_SHIFT   12
+#define  SSB_SPROM1_BINF_ANTA          0xC000  /* Available A-PHY antennas */
+#define  SSB_SPROM1_BINF_ANTA_SHIFT    14
 #define SSB_SPROM1_PA0B0               0x105E
 #define SSB_SPROM1_PA0B1               0x1060
 #define SSB_SPROM1_PA0B2               0x1062
 #define  SSB_SPROM1_ITSSI_A_SHIFT      8
 #define SSB_SPROM1_BFLLO               0x1072  /* Boardflags (low 16 bits) */
 #define SSB_SPROM1_AGAIN               0x1074  /* Antenna Gain (in dBm Q5.2) */
-#define  SSB_SPROM1_AGAIN_A            0x00FF  /* A-PHY */
-#define  SSB_SPROM1_AGAIN_BG           0xFF00  /* B-PHY and G-PHY */
-#define  SSB_SPROM1_AGAIN_BG_SHIFT     8
-#define SSB_SPROM1_OEM                 0x1076  /* 8 bytes OEM string (rev 1 only) */
+#define  SSB_SPROM1_AGAIN_BG           0x00FF  /* B-PHY and G-PHY */
+#define  SSB_SPROM1_AGAIN_BG_SHIFT     0
+#define  SSB_SPROM1_AGAIN_A            0xFF00  /* A-PHY */
+#define  SSB_SPROM1_AGAIN_A_SHIFT      8
+
 /* SPROM Revision 2 (inherits from rev 1) */
 #define SSB_SPROM2_BFLHI               0x1038  /* Boardflags (high 16 bits) */
 #define SSB_SPROM2_MAXP_A              0x103A  /* A-PHY Max Power */
 #define  SSB_SPROM2_OPO_VALUE          0x00FF
 #define  SSB_SPROM2_OPO_UNUSED         0xFF00
 #define SSB_SPROM2_CCODE               0x107C  /* Two char Country Code */
-/* SPROM Revision 3 (inherits from rev 2) */
+
+/* SPROM Revision 3 (inherits most data from rev 2) */
+#define SSB_SPROM3_IL0MAC              0x104A  /* 6 bytes MAC address for 802.11b/g */
+#define SSB_SPROM3_ET0MAC              0x1050  /* 6 bytes MAC address for Ethernet ?? */
+#define SSB_SPROM3_ET1MAC              0x1050  /* 6 bytes MAC address for 802.11a ?? */
 #define SSB_SPROM3_OFDMAPO             0x102C  /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
 #define SSB_SPROM3_OFDMALPO            0x1030  /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
 #define SSB_SPROM3_OFDMAHPO            0x1034  /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
 #define  SSB_SPROM3_CCKPO_11M_SHIFT    12
 #define  SSB_SPROM3_OFDMGPO            0x107A  /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
 
+/* SPROM Revision 4 */
+#define SSB_SPROM4_IL0MAC              0x104C  /* 6 byte MAC address for a/b/g/n */
+#define SSB_SPROM4_ET0MAC              0x1018  /* 6 bytes MAC address for Ethernet ?? */
+#define SSB_SPROM4_ET1MAC              0x1018  /* 6 bytes MAC address for 802.11a ?? */
+#define SSB_SPROM4_ETHPHY              0x105A  /* Ethernet PHY settings ?? */
+#define  SSB_SPROM4_ETHPHY_ET0A                0x001F  /* MII Address for enet0 */
+#define  SSB_SPROM4_ETHPHY_ET1A                0x03E0  /* MII Address for enet1 */
+#define  SSB_SPROM4_ETHPHY_ET1A_SHIFT  5
+#define  SSB_SPROM4_ETHPHY_ET0M                (1<<14) /* MDIO for enet0 */
+#define  SSB_SPROM4_ETHPHY_ET1M                (1<<15) /* MDIO for enet1 */
+#define SSB_SPROM4_CCODE               0x1052  /* Country Code (2 bytes) */
+#define SSB_SPROM4_ANTAVAIL            0x105D  /* Antenna available bitfields */
+#define SSB_SPROM4_ANTAVAIL_A          0x00FF  /* A-PHY bitfield */
+#define SSB_SPROM4_ANTAVAIL_A_SHIFT    0
+#define SSB_SPROM4_ANTAVAIL_BG         0xFF00  /* B-PHY and G-PHY bitfield */
+#define SSB_SPROM4_ANTAVAIL_BG_SHIFT   8
+#define SSB_SPROM4_BFLLO               0x1044  /* Boardflags (low 16 bits) */
+#define SSB_SPROM4_AGAIN01             0x105E  /* Antenna Gain (in dBm Q5.2) */
+#define  SSB_SPROM4_AGAIN0             0x00FF  /* Antenna 0 */
+#define  SSB_SPROM4_AGAIN0_SHIFT       0
+#define  SSB_SPROM4_AGAIN1             0xFF00  /* Antenna 1 */
+#define  SSB_SPROM4_AGAIN1_SHIFT       8
+#define SSB_SPROM4_AGAIN23             0x1060
+#define  SSB_SPROM4_AGAIN2             0x00FF  /* Antenna 2 */
+#define  SSB_SPROM4_AGAIN2_SHIFT       0
+#define  SSB_SPROM4_AGAIN3             0xFF00  /* Antenna 3 */
+#define  SSB_SPROM4_AGAIN3_SHIFT       8
+#define SSB_SPROM4_BFLHI               0x1046  /* Board Flags Hi */
+#define SSB_SPROM4_MAXP_BG             0x1080  /* Max Power BG in path 1 */
+#define  SSB_SPROM4_MAXP_BG_MASK       0x00FF  /* Mask for Max Power BG */
+#define  SSB_SPROM4_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
+#define  SSB_SPROM4_ITSSI_BG_SHIFT     8
+#define SSB_SPROM4_MAXP_A              0x108A  /* Max Power A in path 1 */
+#define  SSB_SPROM4_MAXP_A_MASK                0x00FF  /* Mask for Max Power A */
+#define  SSB_SPROM4_ITSSI_A            0xFF00  /* Mask for path 1 itssi_a */
+#define  SSB_SPROM4_ITSSI_A_SHIFT      8
+#define SSB_SPROM4_GPIOA               0x1056  /* Gen. Purpose IO # 0 and 1 */
+#define  SSB_SPROM4_GPIOA_P0           0x00FF  /* Pin 0 */
+#define  SSB_SPROM4_GPIOA_P1           0xFF00  /* Pin 1 */
+#define  SSB_SPROM4_GPIOA_P1_SHIFT     8
+#define SSB_SPROM4_GPIOB               0x1058  /* Gen. Purpose IO # 2 and 3 */
+#define  SSB_SPROM4_GPIOB_P2           0x00FF  /* Pin 2 */
+#define  SSB_SPROM4_GPIOB_P3           0xFF00  /* Pin 3 */
+#define  SSB_SPROM4_GPIOB_P3_SHIFT     8
+#define SSB_SPROM4_PA0B0               0x1082  /* The paXbY locations are */
+#define SSB_SPROM4_PA0B1               0x1084  /*   only guesses */
+#define SSB_SPROM4_PA0B2               0x1086
+#define SSB_SPROM4_PA1B0               0x108E
+#define SSB_SPROM4_PA1B1               0x1090
+#define SSB_SPROM4_PA1B2               0x1092
+
 /* Values for SSB_SPROM1_BINF_CCODE */
 enum {
        SSB_SPROM1CCODE_WORLD = 0,
index 4f5047df8a9efbf6672c31883222f902f5ee6c8b..89faebfe48b8aa4a29b7f4ac3d756aedb71b4251 100644 (file)
@@ -945,7 +945,10 @@ enum
 
 /* For the /proc/sys support */
 struct ctl_table;
+struct nsproxy;
 extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev);
+extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
+                                               struct ctl_table_header *prev);
 extern void sysctl_head_finish(struct ctl_table_header *prev);
 extern int sysctl_perm(struct ctl_table *table, int op);
 
@@ -1049,6 +1052,13 @@ struct ctl_table
        void *extra2;
 };
 
+struct ctl_table_root {
+       struct list_head root_list;
+       struct list_head header_list;
+       struct list_head *(*lookup)(struct ctl_table_root *root,
+                                          struct nsproxy *namespaces);
+};
+
 /* struct ctl_table_header is used to maintain dynamic lists of
    struct ctl_table trees. */
 struct ctl_table_header
@@ -1057,12 +1067,26 @@ struct ctl_table_header
        struct list_head ctl_entry;
        int used;
        struct completion *unregistering;
+       struct ctl_table *ctl_table_arg;
+       struct ctl_table_root *root;
+};
+
+/* struct ctl_path describes where in the hierarchy a table is added */
+struct ctl_path {
+       const char *procname;
+       int ctl_name;
 };
 
+void register_sysctl_root(struct ctl_table_root *root);
+struct ctl_table_header *__register_sysctl_paths(
+       struct ctl_table_root *root, struct nsproxy *namespaces,
+       const struct ctl_path *path, struct ctl_table *table);
 struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                                               struct ctl_table *table);
 
 void unregister_sysctl_table(struct ctl_table_header * table);
-int sysctl_check_table(struct ctl_table *table);
+int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table);
 
 #else /* __KERNEL__ */
 
index bac17c59b24ef8a0c24d93d1fc7e041c6e0b571c..08027f1d7f31d81836de46fd58f89d1fd5edbcae 100644 (file)
@@ -330,10 +330,12 @@ struct tcp_sock {
        struct tcp_sack_block duplicate_sack[1]; /* D-SACK block */
        struct tcp_sack_block selective_acks[4]; /* The SACKS themselves*/
 
-       struct tcp_sack_block_wire recv_sack_cache[4];
+       struct tcp_sack_block recv_sack_cache[4];
 
-       u32     highest_sack;   /* Start seq of globally highest revd SACK
-                                * (validity guaranteed only if sacked_out > 0) */
+       struct sk_buff *highest_sack;   /* highest skb with SACK received
+                                        * (validity guaranteed only if
+                                        * sacked_out > 0)
+                                        */
 
        /* from STCP, retrans queue hinting */
        struct sk_buff* lost_skb_hint;
@@ -341,10 +343,7 @@ struct tcp_sock {
        struct sk_buff *scoreboard_skb_hint;
        struct sk_buff *retransmit_skb_hint;
        struct sk_buff *forward_skb_hint;
-       struct sk_buff *fastpath_skb_hint;
 
-       int     fastpath_cnt_hint;      /* Lags behind by current skb's pcount
-                                        * compared to respective fackets_out */
        int     lost_cnt_hint;
        int     retransmit_cnt_hint;
 
index defd2ab72449d4b9ef91f4def9a9e1cb2635364f..402de892b3edcdd0ae3bbf16892100e5c5570915 100644 (file)
@@ -23,7 +23,7 @@
  */
 #define NR_UNIX98_PTY_DEFAULT  4096      /* Default maximum for Unix98 ptys */
 #define NR_UNIX98_PTY_MAX      (1 << MINORBITS) /* Absolute limit */
-#define NR_LDISCS              17
+#define NR_LDISCS              18
 
 /* line disciplines */
 #define N_TTY          0
@@ -44,6 +44,7 @@
 #define N_SYNC_PPP     14      /* synchronous PPP */
 #define N_HCI          15      /* Bluetooth HCI UART */
 #define N_GIGASET_M101 16      /* Siemens Gigaset M101 serial DECT adapter */
+#define N_SLCAN                17      /* Serial / USB serial CAN Adaptors */
 
 /*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
index 0987aa7a6cf513281b0c6fb50332bc260f3ca279..74e84caa1e208ba529729597bf8a66612d40061b 100644 (file)
 /* Maximum size of returned data */
 #define IW_SCAN_MAX_DATA       4096    /* In bytes */
 
+/* Scan capability flags - in (struct iw_range *)->scan_capa */
+#define IW_SCAN_CAPA_NONE              0x00
+#define IW_SCAN_CAPA_ESSID             0x01
+#define IW_SCAN_CAPA_BSSID             0x02
+#define IW_SCAN_CAPA_CHANNEL   0x04
+#define IW_SCAN_CAPA_MODE              0x08
+#define IW_SCAN_CAPA_RATE              0x10
+#define IW_SCAN_CAPA_TYPE              0x20
+#define IW_SCAN_CAPA_TIME              0x40
+
 /* Max number of char in custom event - use multiple of them if needed */
 #define IW_CUSTOM_MAX          256     /* In bytes */
 
@@ -963,6 +973,9 @@ struct      iw_range
        __u16           old_num_channels;
        __u8            old_num_frequency;
 
+       /* Scan capabilities */
+       __u8            scan_capa;      /* IW_SCAN_CAPA_* bit field */
+
        /* Wireless event capability bitmasks */
        __u32           event_capa[6];
 
index b58adc52448d62df6f3a3dee465c458946cbdf00..9b5b00c4ef9dee3e8f6bace149b16d4a91f87eab 100644 (file)
@@ -91,9 +91,9 @@ struct xfrm_replay_state
 };
 
 struct xfrm_algo {
-       char    alg_name[64];
-       int     alg_key_len;    /* in bits */
-       char    alg_key[0];
+       char            alg_name[64];
+       unsigned int    alg_key_len;    /* in bits */
+       char            alg_key[0];
 };
 
 struct xfrm_stats {
@@ -114,6 +114,7 @@ enum
        XFRM_POLICY_IN  = 0,
        XFRM_POLICY_OUT = 1,
        XFRM_POLICY_FWD = 2,
+       XFRM_POLICY_MASK = 3,
        XFRM_POLICY_MAX = 3
 };
 
@@ -328,6 +329,7 @@ struct xfrm_usersa_info {
 #define XFRM_STATE_DECAP_DSCP  2
 #define XFRM_STATE_NOPMTUDISC  4
 #define XFRM_STATE_WILDRECV    8
+#define XFRM_STATE_ICMP                16
 };
 
 struct xfrm_usersa_id {
@@ -362,6 +364,8 @@ struct xfrm_userpolicy_info {
 #define XFRM_POLICY_BLOCK      1
        __u8                            flags;
 #define XFRM_POLICY_LOCALOK    1       /* Allow user to override global policy */
+       /* Automatically expand selector to include matching ICMP payloads. */
+#define XFRM_POLICY_ICMP       2
        __u8                            share;
 };
 
index 68b4eaf7719df31188d886ac3213ef2fae2bf5fe..565eed8fe496d55c81c3454564eb5605e27afd71 100644 (file)
@@ -89,7 +89,7 @@ struct tc_action_ops {
        int     (*dump)(struct sk_buff *, struct tc_action *, int, int);
        int     (*cleanup)(struct tc_action *, int bind);
        int     (*lookup)(struct tc_action *, u32);
-       int     (*init)(struct rtattr *, struct rtattr *, struct tc_action *, int , int);
+       int     (*init)(struct nlattr *, struct nlattr *, struct tc_action *, int , int);
        int     (*walk)(struct sk_buff *, struct netlink_callback *, int, struct tc_action *);
 };
 
@@ -104,7 +104,7 @@ extern u32 tcf_hash_new_index(u32 *idx_gen, struct tcf_hashinfo *hinfo);
 extern int tcf_hash_search(struct tc_action *a, u32 index);
 extern struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a,
                                         int bind, struct tcf_hashinfo *hinfo);
-extern struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est,
+extern struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est,
                                          struct tc_action *a, int size,
                                          int bind, u32 *idx_gen,
                                          struct tcf_hashinfo *hinfo);
@@ -114,8 +114,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
 extern int tcf_unregister_action(struct tc_action_ops *a);
 extern void tcf_action_destroy(struct tc_action *a, int bind);
 extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
-extern struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
-extern struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, char *n, int ovr, int bind, int *err);
+extern struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
+extern struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est, char *n, int ovr, int bind);
 extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
 extern int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int);
index 33b593e174412792347be0d366a1f036e963430e..496503c038463bf41f6122b20ffdf0e609bf526a 100644 (file)
@@ -17,6 +17,7 @@
 
 #define IPV6_MAX_ADDRESSES             16
 
+#include <linux/in.h>
 #include <linux/in6.h>
 
 struct prefix_info {
@@ -58,15 +59,20 @@ extern int                  addrconf_add_ifaddr(void __user *arg);
 extern int                     addrconf_del_ifaddr(void __user *arg);
 extern int                     addrconf_set_dstaddr(void __user *arg);
 
-extern int                     ipv6_chk_addr(struct in6_addr *addr,
+extern int                     ipv6_chk_addr(struct net *net,
+                                             struct in6_addr *addr,
                                              struct net_device *dev,
                                              int strict);
+
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-extern int                     ipv6_chk_home_addr(struct in6_addr *addr);
+extern int                     ipv6_chk_home_addr(struct net *net,
+                                                  struct in6_addr *addr);
 #endif
-extern struct inet6_ifaddr *   ipv6_get_ifaddr(struct in6_addr *addr,
-                                               struct net_device *dev,
-                                               int strict);
+extern struct inet6_ifaddr      *ipv6_get_ifaddr(struct net *net,
+                                                struct in6_addr *addr,
+                                                struct net_device *dev,
+                                                int strict);
+
 extern int                     ipv6_get_saddr(struct dst_entry *dst, 
                                               struct in6_addr *daddr,
                                               struct in6_addr *saddr);
@@ -83,6 +89,14 @@ extern void                  addrconf_join_solict(struct net_device *dev,
 extern void                    addrconf_leave_solict(struct inet6_dev *idev,
                                        struct in6_addr *addr);
 
+/*
+ *     IPv6 Address Label subsystem (addrlabel.c)
+ */
+extern int                     ipv6_addr_label_init(void);
+extern void                    ipv6_addr_label_rtnl_register(void);
+extern u32                     ipv6_addr_label(const struct in6_addr *addr,
+                                               int type, int ifindex);
+
 /*
  *     multicast prototypes (mcast.c)
  */
@@ -241,6 +255,26 @@ static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
                addr->s6_addr32[3] == htonl(0x00000002));
 }
 
+static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr)
+{
+       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) ||
+                 ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
+                 ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
+                 ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
+       eui[1] = 0;
+       eui[2] = 0x5E;
+       eui[3] = 0xFE;
+       memcpy (eui+4, &addr, 4);
+       return 0;
+}
+
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
+{
+       return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE));
+}
+
 #ifdef CONFIG_PROC_FS
 extern int if6_proc_init(void);
 extern void if6_proc_exit(void);
index a1c805d7f488b7295a335c33de66f495cd5d0e37..2dfa96b0575e638233475bd7af33a457319dd1c9 100644 (file)
@@ -59,12 +59,11 @@ struct unix_sock {
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
 
 #ifdef CONFIG_SYSCTL
-extern int sysctl_unix_max_dgram_qlen;
-extern void unix_sysctl_register(void);
-extern void unix_sysctl_unregister(void);
+extern int unix_sysctl_register(struct net *net);
+extern void unix_sysctl_unregister(struct net *net);
 #else
-static inline void unix_sysctl_register(void) {}
-static inline void unix_sysctl_unregister(void) {}
+static inline int unix_sysctl_register(struct net *net) { return 0; }
+static inline void unix_sysctl_unregister(struct net *net) {}
 #endif
 #endif
 #endif
index f026645686008af614cf4949a1adba3bcaec3e15..752eb47b2678b0ceecabd1c44190e16cd59fde66 100644 (file)
@@ -5,13 +5,12 @@
 #include <linux/if_arp.h>
 #include <net/neighbour.h>
 
-#define HAVE_ARP_CREATE
 
 extern struct neigh_table arp_tbl;
 
 extern void    arp_init(void);
 extern int     arp_find(unsigned char *haddr, struct sk_buff *skb);
-extern int     arp_ioctl(unsigned int cmd, void __user *arg);
+extern int     arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
 extern void     arp_send(int type, int ptype, __be32 dest_ip,
                         struct net_device *dev, __be32 src_ip,
                         unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
index 25aa575db807b8e7881aec4bcafa428e24dbb779..98ec7a3206899cb7aff544cc69a355a592436698 100644 (file)
@@ -252,8 +252,8 @@ static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
                rfcomm_dlc_free(d);
 }
 
-extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
+extern void __rfcomm_dlc_throttle(struct rfcomm_dlc *d);
+extern void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d);
 
 static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
 {
index d30960e1755c64d32bbd651b195265c1aacca0d5..bcc480b8892aba4c9ce19bcc3e0fc825ff839c07 100644 (file)
@@ -49,6 +49,120 @@ extern int ieee80211_radiotap_iterator_next(
    struct ieee80211_radiotap_iterator *iterator);
 
 
+ /**
+ * struct key_params - key information
+ *
+ * Information about a key
+ *
+ * @key: key material
+ * @key_len: length of key material
+ * @cipher: cipher suite selector
+ * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used
+ *     with the get_key() callback, must be in little endian,
+ *     length given by @seq_len.
+ */
+struct key_params {
+       u8 *key;
+       u8 *seq;
+       int key_len;
+       int seq_len;
+       u32 cipher;
+};
+
+/**
+ * struct beacon_parameters - beacon parameters
+ *
+ * Used to configure the beacon for an interface.
+ *
+ * @head: head portion of beacon (before TIM IE)
+ *     or %NULL if not changed
+ * @tail: tail portion of beacon (after TIM IE)
+ *     or %NULL if not changed
+ * @interval: beacon interval or zero if not changed
+ * @dtim_period: DTIM period or zero if not changed
+ * @head_len: length of @head
+ * @tail_len: length of @tail
+ */
+struct beacon_parameters {
+       u8 *head, *tail;
+       int interval, dtim_period;
+       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
+ */
+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,
+};
+
+/**
+ * struct station_parameters - station parameters
+ *
+ * Used to change and create a new station.
+ *
+ * @vlan: vlan interface station should belong to
+ * @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)
+ * @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;
+       int listen_interval;
+       u16 aid;
+       u8 supported_rates_len;
+};
+
+/**
+ * enum station_stats_flags - station statistics flags
+ *
+ * Used by the driver to indicate which info in &struct station_stats
+ * it has filled in during get_station().
+ *
+ * @STATION_STAT_INACTIVE_TIME: @inactive_time filled
+ * @STATION_STAT_RX_BYTES: @rx_bytes filled
+ * @STATION_STAT_TX_BYTES: @tx_bytes filled
+ */
+enum station_stats_flags {
+       STATION_STAT_INACTIVE_TIME      = 1<<0,
+       STATION_STAT_RX_BYTES           = 1<<1,
+       STATION_STAT_TX_BYTES           = 1<<2,
+};
+
+/**
+ * struct station_stats - station statistics
+ *
+ * Station information filled by driver for get_station().
+ *
+ * @filled: bitflag of flags from &enum station_stats_flags
+ * @inactive_time: time since last station activity (tx/rx) in milliseconds
+ * @rx_bytes: bytes received from this station
+ * @tx_bytes: bytes transmitted to this station
+ */
+struct station_stats {
+       u32 filled;
+       u32 inactive_time;
+       u32 rx_bytes;
+       u32 tx_bytes;
+};
+
 /* from net/wireless.h */
 struct wiphy;
 
@@ -71,6 +185,31 @@ struct wiphy;
  *
  * @change_virtual_intf: change type of virtual interface
  *
+ * @add_key: add a key with the given parameters. @mac_addr will be %NULL
+ *     when adding a group key.
+ *
+ * @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.
+ *
+ * @del_key: remove a key given the @mac_addr (%NULL for a group key)
+ *     and @key_index
+ *
+ * @set_default_key: set the default key on an interface
+ *
+ * @add_beacon: Add a beacon with given parameters, @head, @interval
+ *     and @dtim_period will be valid, @tail is optional.
+ * @set_beacon: Change the beacon parameters for an access point mode
+ *     interface. This should reject the call when no beacon has been
+ *     configured.
+ * @del_beacon: Remove beacon configuration and stop sending the beacon.
+ *
+ * @add_station: Add a new station.
+ *
+ * @del_station: Remove a station; @mac may be NULL to remove all stations.
+ *
+ * @change_station: Modify a given station.
  */
 struct cfg80211_ops {
        int     (*add_virtual_intf)(struct wiphy *wiphy, char *name,
@@ -78,6 +217,34 @@ struct cfg80211_ops {
        int     (*del_virtual_intf)(struct wiphy *wiphy, int ifindex);
        int     (*change_virtual_intf)(struct wiphy *wiphy, int ifindex,
                                       enum nl80211_iftype type);
+
+       int     (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
+                          u8 key_index, 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,
+                          void (*callback)(void *cookie, struct key_params*));
+       int     (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
+                          u8 key_index, u8 *mac_addr);
+       int     (*set_default_key)(struct wiphy *wiphy,
+                                  struct net_device *netdev,
+                                  u8 key_index);
+
+       int     (*add_beacon)(struct wiphy *wiphy, struct net_device *dev,
+                             struct beacon_parameters *info);
+       int     (*set_beacon)(struct wiphy *wiphy, struct net_device *dev,
+                             struct beacon_parameters *info);
+       int     (*del_beacon)(struct wiphy *wiphy, struct net_device *dev);
+
+
+       int     (*add_station)(struct wiphy *wiphy, struct net_device *dev,
+                              u8 *mac, struct station_parameters *params);
+       int     (*del_station)(struct wiphy *wiphy, struct net_device *dev,
+                              u8 *mac);
+       int     (*change_station)(struct wiphy *wiphy, struct net_device *dev,
+                                 u8 *mac, struct station_parameters *params);
+       int     (*get_station)(struct wiphy *wiphy, struct net_device *dev,
+                              u8 *mac, struct station_stats *stats);
 };
 
 #endif /* __NET_CFG80211_H */
index 124246172a88990ba6e04c1c7315a4e09f81ce0a..07602b7fa2185970d14f7af67f6a5f996c92bfe3 100644 (file)
@@ -93,4 +93,29 @@ static inline __wsum csum_unfold(__sum16 n)
 }
 
 #define CSUM_MANGLED_0 ((__force __sum16)0xffff)
+
+static inline void csum_replace4(__sum16 *sum, __be32 from, __be32 to)
+{
+       __be32 diff[] = { ~from, to };
+
+       *sum = csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum_unfold(*sum)));
+}
+
+static inline void csum_replace2(__sum16 *sum, __be16 from, __be16 to)
+{
+       csum_replace4(sum, (__force __be32)from, (__force __be32)to);
+}
+
+struct sk_buff;
+extern void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+                                    __be32 from, __be32 to, int pseudohdr);
+
+static inline void inet_proto_csum_replace2(__sum16 *sum, struct sk_buff *skb,
+                                           __be16 from, __be16 to,
+                                           int pseudohdr)
+{
+       inet_proto_csum_replace4(sum, skb, (__force __be32)from,
+                                (__force __be32)to, pseudohdr);
+}
+
 #endif
index eb65bf2e2502d972218c99bc95e8b65c8abc0856..8a8d4e06900d8824ba4a892c5f29f9c40525f0e0 100644 (file)
 #include <asm/byteorder.h>
 
 
-static inline __u8 ipv4_get_dsfield(struct iphdr *iph)
+static inline __u8 ipv4_get_dsfield(const struct iphdr *iph)
 {
        return iph->tos;
 }
 
 
-static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h)
+static inline __u8 ipv6_get_dsfield(const struct ipv6hdr *ipv6h)
 {
-       return ntohs(*(__be16 *) ipv6h) >> 4;
+       return ntohs(*(const __be16 *)ipv6h) >> 4;
 }
 
 
index 2f65e894b8295f310ad20d331e56d981c94b67d0..e3ac7d0fc4e1807e62d1246b74aefa5d9ae9f23a 100644 (file)
@@ -50,14 +50,17 @@ struct dst_entry
        unsigned long           expires;
 
        unsigned short          header_len;     /* more space at head required */
-       unsigned short          nfheader_len;   /* more non-fragment space at head required */
        unsigned short          trailer_len;    /* space to reserve at tail */
 
        u32                     metrics[RTAX_MAX];
        struct dst_entry        *path;
 
        unsigned long           rate_last;      /* rate limiting for ICMP */
-       unsigned long           rate_tokens;
+       unsigned int            rate_tokens;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+       __u32                   tclassid;
+#endif
 
        struct neighbour        *neighbour;
        struct hh_cache         *hh;
@@ -66,10 +69,6 @@ struct dst_entry
        int                     (*input)(struct sk_buff*);
        int                     (*output)(struct sk_buff*);
 
-#ifdef CONFIG_NET_CLS_ROUTE
-       __u32                   tclassid;
-#endif
-
        struct  dst_ops         *ops;
                
        unsigned long           lastuse;
@@ -81,7 +80,6 @@ struct dst_entry
                struct rt6_info   *rt6_next;
                struct dn_route  *dn_next;
        };
-       char                    info[0];
 };
 
 
@@ -91,7 +89,7 @@ struct dst_ops
        __be16                  protocol;
        unsigned                gc_thresh;
 
-       int                     (*gc)(void);
+       int                     (*gc)(struct dst_ops *ops);
        struct dst_entry *      (*check)(struct dst_entry *, __u32 cookie);
        void                    (*destroy)(struct dst_entry *);
        void                    (*ifdown)(struct dst_entry *,
@@ -99,10 +97,12 @@ struct dst_ops
        struct dst_entry *      (*negative_advice)(struct dst_entry *);
        void                    (*link_failure)(struct sk_buff *);
        void                    (*update_pmtu)(struct dst_entry *dst, u32 mtu);
+       int                     (*local_out)(struct sk_buff *skb);
        int                     entry_size;
 
        atomic_t                entries;
        struct kmem_cache               *kmem_cachep;
+       struct net              *dst_net;
 };
 
 #ifdef __KERNEL__
@@ -180,6 +180,7 @@ static inline struct dst_entry *dst_pop(struct dst_entry *dst)
        return child;
 }
 
+extern int dst_discard(struct sk_buff *skb);
 extern void * dst_alloc(struct dst_ops * ops);
 extern void __dst_free(struct dst_entry * dst);
 extern struct dst_entry *dst_destroy(struct dst_entry * dst);
@@ -264,6 +265,12 @@ static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
 
 extern void            dst_init(void);
 
+/* Flags for xfrm_lookup flags argument. */
+enum {
+       XFRM_LOOKUP_WAIT = 1 << 0,
+       XFRM_LOOKUP_ICMP = 1 << 1,
+};
+
 struct flowi;
 #ifndef CONFIG_XFRM
 static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
index 41a301e386433006e659ae14409e1373f905d36b..34349f9f4331a1d81e22d65a848511f446eea226 100644 (file)
@@ -22,6 +22,7 @@ struct fib_rule
        u32                     target;
        struct fib_rule *       ctarget;
        struct rcu_head         rcu;
+       struct net *            fr_net;
 };
 
 struct fib_lookup_arg
@@ -56,7 +57,7 @@ struct fib_rules_ops
        int                     (*fill)(struct fib_rule *, struct sk_buff *,
                                        struct nlmsghdr *,
                                        struct fib_rule_hdr *);
-       u32                     (*default_pref)(void);
+       u32                     (*default_pref)(struct fib_rules_ops *ops);
        size_t                  (*nlmsg_payload)(struct fib_rule *);
 
        /* Called after modifications to the rules set, must flush
@@ -67,6 +68,7 @@ struct fib_rules_ops
        const struct nla_policy *policy;
        struct list_head        rules_list;
        struct module           *owner;
+       struct net              *fro_net;
 };
 
 #define FRA_GENERIC_POLICY \
@@ -101,8 +103,9 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
        return frh->table;
 }
 
-extern int                     fib_rules_register(struct fib_rules_ops *);
-extern int                     fib_rules_unregister(struct fib_rules_ops *);
+extern int fib_rules_register(struct fib_rules_ops *);
+extern void fib_rules_unregister(struct fib_rules_ops *);
+extern void                     fib_rules_cleanup_ops(struct fib_rules_ops *);
 
 extern int                     fib_rules_lookup(struct fib_rules_ops *,
                                                 struct flowi *, int flags,
index af59fa5cc1f82560360833d02d60144e32662555..ad16e0076c89dd2ec10d9a8579a9e8b375a08640 100644 (file)
@@ -48,7 +48,6 @@ struct flowi {
 
        __u8    proto;
        __u8    flags;
-#define FLOWI_FLAG_MULTIPATHOLDROUTE 0x01
        union {
                struct {
                        __be16  sport;
index 0b95cf031d6e0f8dd6a27f4b8fe186cefa6f8a04..8cd8185fa2ed59a320b393d96812c32eb7ab0748 100644 (file)
@@ -10,7 +10,7 @@ struct gnet_dump
 {
        spinlock_t *      lock;
        struct sk_buff *  skb;
-       struct rtattr *   tail;
+       struct nlattr *   tail;
 
        /* Backward compatability */
        int               compat_tc_stats;
@@ -39,11 +39,11 @@ extern int gnet_stats_finish_copy(struct gnet_dump *d);
 
 extern int gen_new_estimator(struct gnet_stats_basic *bstats,
                             struct gnet_stats_rate_est *rate_est,
-                            spinlock_t *stats_lock, struct rtattr *opt);
+                            spinlock_t *stats_lock, struct nlattr *opt);
 extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
                               struct gnet_stats_rate_est *rate_est);
 extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
                                 struct gnet_stats_rate_est *rate_est,
-                                spinlock_t *stats_lock, struct rtattr *opt);
+                                spinlock_t *stats_lock, struct nlattr *opt);
 
 #endif
index d8ae48439f120a27b18e7d226ba49d54a16b322e..285b2adfa648c1cc6c9ccfc5d3ce853c51732543 100644 (file)
@@ -677,7 +677,7 @@ struct ieee80211_probe_request {
 
 struct ieee80211_probe_response {
        struct ieee80211_hdr_3addr header;
-       u32 time_stamp[2];
+       __le32 time_stamp[2];
        __le16 beacon_interval;
        __le16 capability;
        /* SSID, supported rates, FH params, DS params,
@@ -718,8 +718,8 @@ struct ieee80211_txb {
        u8 encrypted;
        u8 rts_included;
        u8 reserved;
-       __le16 frag_size;
-       __le16 payload_size;
+       u16 frag_size;
+       u16 payload_size;
        struct sk_buff *fragments[0];
 };
 
index de8399a797749007f17501f8371136fb83d33fd1..ba33db0538545a55c39553042278f52d318611e8 100644 (file)
@@ -83,9 +83,9 @@ static inline void IP_ECN_clear(struct iphdr *iph)
        iph->tos &= ~INET_ECN_MASK;
 }
 
-static inline void ipv4_copy_dscp(struct iphdr *outer, struct iphdr *inner)
+static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner)
 {
-       u32 dscp = ipv4_get_dsfield(outer) & ~INET_ECN_MASK;
+       dscp &= ~INET_ECN_MASK;
        ipv4_change_dsfield(inner, INET_ECN_MASK, dscp);
 }
 
@@ -104,9 +104,9 @@ static inline void IP6_ECN_clear(struct ipv6hdr *iph)
        *(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
 }
 
-static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner)
+static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
 {
-       u32 dscp = ipv6_get_dsfield(outer) & ~INET_ECN_MASK;
+       dscp &= ~INET_ECN_MASK;
        ipv6_change_dsfield(inner, INET_ECN_MASK, dscp);
 }
 
index 954def408975a13a11b6e57cbeb3624346f0328c..7374251b97879f46646fefb270c6c88f0c9061d0 100644 (file)
@@ -1,8 +1,20 @@
 #ifndef __NET_FRAG_H__
 #define __NET_FRAG_H__
 
+struct netns_frags {
+       int                     nqueues;
+       atomic_t                mem;
+       struct list_head        lru_list;
+
+       /* sysctls */
+       int                     timeout;
+       int                     high_thresh;
+       int                     low_thresh;
+};
+
 struct inet_frag_queue {
        struct hlist_node       list;
+       struct netns_frags      *net;
        struct list_head        lru_list;   /* lru list member */
        spinlock_t              lock;
        atomic_t                refcnt;
@@ -20,23 +32,13 @@ struct inet_frag_queue {
 
 #define INETFRAGS_HASHSZ               64
 
-struct inet_frags_ctl {
-       int high_thresh;
-       int low_thresh;
-       int timeout;
-       int secret_interval;
-};
-
 struct inet_frags {
-       struct list_head        lru_list;
        struct hlist_head       hash[INETFRAGS_HASHSZ];
        rwlock_t                lock;
        u32                     rnd;
-       int                     nqueues;
        int                     qsize;
-       atomic_t                mem;
+       int                     secret_interval;
        struct timer_list       secret_timer;
-       struct inet_frags_ctl   *ctl;
 
        unsigned int            (*hashfn)(struct inet_frag_queue *);
        void                    (*constructor)(struct inet_frag_queue *q,
@@ -51,12 +53,15 @@ struct inet_frags {
 void inet_frags_init(struct inet_frags *);
 void inet_frags_fini(struct inet_frags *);
 
+void inet_frags_init_net(struct netns_frags *nf);
+void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
+
 void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
 void inet_frag_destroy(struct inet_frag_queue *q,
                                struct inet_frags *f, int *work);
-int inet_frag_evictor(struct inet_frags *f);
-struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
-               unsigned int hash);
+int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
+struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
+               struct inet_frags *f, void *key, unsigned int hash);
 
 static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f)
 {
index 37f6cb11212723f7f2094a16b6cec92bbe9ef670..761bdc01425d796b6669bcaa73243d33abf7aab2 100644 (file)
@@ -264,37 +264,14 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo)
                wake_up(&hashinfo->lhash_wait);
 }
 
-static inline void __inet_hash(struct inet_hashinfo *hashinfo,
-                              struct sock *sk, const int listen_possible)
-{
-       struct hlist_head *list;
-       rwlock_t *lock;
-
-       BUG_TRAP(sk_unhashed(sk));
-       if (listen_possible && sk->sk_state == TCP_LISTEN) {
-               list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
-               lock = &hashinfo->lhash_lock;
-               inet_listen_wlock(hashinfo);
-       } else {
-               struct inet_ehash_bucket *head;
-               sk->sk_hash = inet_sk_ehashfn(sk);
-               head = inet_ehash_bucket(hashinfo, sk->sk_hash);
-               list = &head->chain;
-               lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
-               write_lock(lock);
-       }
-       __sk_add_node(sk, list);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock(lock);
-       if (listen_possible && sk->sk_state == TCP_LISTEN)
-               wake_up(&hashinfo->lhash_wait);
-}
+extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk);
+extern void __inet_hash_nolisten(struct inet_hashinfo *hinfo, struct sock *sk);
 
 static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
 {
        if (sk->sk_state != TCP_CLOSE) {
                local_bh_disable();
-               __inet_hash(hashinfo, sk, 1);
+               __inet_hash(hashinfo, sk);
                local_bh_enable();
        }
 }
@@ -316,7 +293,7 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk)
        }
 
        if (__sk_del_node_init(sk))
-               sock_prot_dec_use(sk->sk_prot);
+               sock_prot_inuse_add(sk->sk_prot, -1);
        write_unlock_bh(lock);
 out:
        if (sk->sk_state == TCP_LISTEN)
@@ -397,43 +374,9 @@ typedef __u64 __bitwise __addrpair;
  *
  * Local BH must be disabled here.
  */
-static inline struct sock *
-       __inet_lookup_established(struct inet_hashinfo *hashinfo,
-                                 const __be32 saddr, const __be16 sport,
-                                 const __be32 daddr, const u16 hnum,
-                                 const int dif)
-{
-       INET_ADDR_COOKIE(acookie, saddr, daddr)
-       const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
-       struct sock *sk;
-       const struct hlist_node *node;
-       /* Optimize here for direct hit, only listening connections can
-        * have wildcards anyways.
-        */
-       unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
-       struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
-       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
-
-       prefetch(head->chain.first);
-       read_lock(lock);
-       sk_for_each(sk, node, &head->chain) {
-               if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
-                       goto hit; /* You sunk my battleship! */
-       }
-
-       /* Must check for a TIME_WAIT'er before going to listener hash. */
-       sk_for_each(sk, node, &head->twchain) {
-               if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
-                       goto hit;
-       }
-       sk = NULL;
-out:
-       read_unlock(lock);
-       return sk;
-hit:
-       sock_hold(sk);
-       goto out;
-}
+extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+               const __be32 saddr, const __be16 sport,
+               const __be32 daddr, const u16 hnum, const int dif);
 
 static inline struct sock *
        inet_lookup_established(struct inet_hashinfo *hashinfo,
index abaff05972707feac79c5ca7199996e3f252167b..67e925065aaeee1245c8088a6ccead3a128f4fc2 100644 (file)
@@ -193,19 +193,7 @@ static inline __be32 inet_rcv_saddr(const struct sock *sk)
                inet_sk(sk)->rcv_saddr : inet_twsk(sk)->tw_rcv_saddr;
 }
 
-static inline void inet_twsk_put(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);
-#ifdef SOCK_REFCNT_DEBUG
-               printk(KERN_DEBUG "%s timewait_sock %p released\n",
-                      tw->tw_prot->name, tw);
-#endif
-               kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
-               module_put(owner);
-       }
-}
+extern void inet_twsk_put(struct inet_timewait_sock *tw);
 
 extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk,
                                                  const int state);
index 50c8889b1b8d7e6625cf4580a673c9a516e27bfd..9f50d4f1f157de867079b5048be3de494bed280f 100644 (file)
@@ -82,8 +82,6 @@ struct packet_type;
 struct rtable;
 struct sockaddr;
 
-extern void            ip_mc_dropsocket(struct sock *);
-extern void            ip_mc_dropdevice(struct net_device *dev);
 extern int             igmp_mc_proc_init(void);
 
 /*
@@ -102,6 +100,8 @@ extern int          ip_mc_output(struct sk_buff *skb);
 extern int             ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 extern int             ip_do_nat(struct sk_buff *skb);
 extern void            ip_send_check(struct iphdr *ip);
+extern int             __ip_local_out(struct sk_buff *skb);
+extern int             ip_local_out(struct sk_buff *skb);
 extern int             ip_queue_xmit(struct sk_buff *skb, int ipfragok);
 extern void            ip_init(void);
 extern int             ip_append_data(struct sock *sk,
@@ -169,7 +169,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
 #define NET_ADD_STATS_USER(field, adnd)        SNMP_ADD_STATS_USER(net_statistics, field, adnd)
 
 extern unsigned long snmp_fold_field(void *mib[], int offt);
-extern int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
+extern int snmp_mib_init(void *ptr[2], size_t mibsize);
 extern void snmp_mib_free(void *ptr[2]);
 
 extern void inet_get_local_port_range(int *low, int *high);
@@ -177,10 +177,7 @@ extern void inet_get_local_port_range(int *low, int *high);
 extern int sysctl_ip_default_ttl;
 extern int sysctl_ip_nonlocal_bind;
 
-/* From ip_fragment.c */
-struct inet_frags_ctl;
-extern struct inet_frags_ctl ip4_frags_ctl;
-extern int sysctl_ipfrag_max_dist;
+extern struct ctl_path net_ipv4_ctl_path[];
 
 /* From inetpeer.c */
 extern int inet_peer_threshold;
@@ -319,7 +316,7 @@ static __inline__ void inet_reset_saddr(struct sock *sk)
 extern int     ip_call_ra_chain(struct sk_buff *skb);
 
 /*
- *     Functions provided by ip_fragment.o
+ *     Functions provided by ip_fragment.c
  */
 
 enum ip_defrag_users
@@ -334,15 +331,14 @@ enum ip_defrag_users
 };
 
 int ip_defrag(struct sk_buff *skb, u32 user);
-int ip_frag_mem(void);
-int ip_frag_nqueues(void);
+int ip_frag_mem(struct net *net);
+int ip_frag_nqueues(struct net *net);
 
 /*
  *     Functions provided by ip_forward.c
  */
  
 extern int ip_forward(struct sk_buff *skb);
-extern int ip_net_unreachable(struct sk_buff *skb);
  
 /*
  *     Functions provided by ip_options.c
@@ -393,6 +389,4 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
 extern int ip_misc_proc_init(void);
 #endif
 
-extern struct ctl_table ipv4_table[];
-
 #endif /* _IP_H */
index 857821360bb6cf99af1d5694722d588044b6dd5e..d8d85b13364dd23e3c6772a506465e71812c7685 100644 (file)
@@ -99,16 +99,21 @@ struct rt6_info
        u32                             rt6i_flags;
        u32                             rt6i_metric;
        atomic_t                        rt6i_ref;
-       struct fib6_table               *rt6i_table;
 
-       struct rt6key                   rt6i_dst;
-       struct rt6key                   rt6i_src;
+       /* more non-fragment space at head required */
+       unsigned short                  rt6i_nfheader_len;
 
        u8                              rt6i_protocol;
 
+       struct fib6_table               *rt6i_table;
+
+       struct rt6key                   rt6i_dst;
+
 #ifdef CONFIG_XFRM
        u32                             rt6i_flow_cache_genid;
 #endif
+
+       struct rt6key                   rt6i_src;
 };
 
 static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
@@ -219,10 +224,20 @@ extern void                       fib6_run_gc(unsigned long dummy);
 
 extern void                    fib6_gc_cleanup(void);
 
-extern void                    fib6_init(void);
+extern int                     fib6_init(void);
 
-extern void                    fib6_rules_init(void);
+#ifdef CONFIG_IPV6_MULTIPLE_TABLES
+extern int                     fib6_rules_init(void);
 extern void                    fib6_rules_cleanup(void);
-
+#else
+static inline int               fib6_rules_init(void)
+{
+       return 0;
+}
+static inline void              fib6_rules_cleanup(void)
+{
+       return ;
+}
+#endif
 #endif
 #endif
index 5456fdd6d047b1e8149814a623ee77ed56670970..faac0eee1ef3d934482209406d7e4ac406760379 100644 (file)
@@ -43,14 +43,12 @@ extern struct rt6_info      ip6_prohibit_entry;
 extern struct rt6_info ip6_blk_hole_entry;
 #endif
 
-extern int ip6_rt_gc_interval;
-
 extern void                    ip6_route_input(struct sk_buff *skb);
 
 extern struct dst_entry *      ip6_route_output(struct sock *sk,
                                                 struct flowi *fl);
 
-extern void                    ip6_route_init(void);
+extern int                     ip6_route_init(void);
 extern void                    ip6_route_cleanup(void);
 
 extern int                     ipv6_route_ioctl(unsigned int cmd, void __user *arg);
index ed514bfb61ba066edc9c560eccdd7d468ac694c5..9daa60b544ba8839f8ca690fe2173ac5506d0922 100644 (file)
@@ -125,11 +125,15 @@ struct fib_result_nl {
 #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
+
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
 
 #define FIB_RES_PREFSRC(res)           ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
@@ -141,6 +145,7 @@ 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 *);
        int             (*tb_delete)(struct fib_table *, struct fib_config *);
@@ -155,50 +160,51 @@ struct fib_table {
 
 #ifndef CONFIG_IP_MULTIPLE_TABLES
 
-extern struct fib_table *ip_fib_local_table;
-extern struct fib_table *ip_fib_main_table;
+#define TABLE_LOCAL_INDEX      0
+#define TABLE_MAIN_INDEX       1
 
-static inline struct fib_table *fib_get_table(u32 id)
+static inline struct fib_table *fib_get_table(struct net *net, u32 id)
 {
-       if (id != RT_TABLE_LOCAL)
-               return ip_fib_main_table;
-       return ip_fib_local_table;
-}
+       struct hlist_head *ptr;
 
-static inline struct fib_table *fib_new_table(u32 id)
-{
-       return fib_get_table(id);
+       ptr = id == RT_TABLE_LOCAL ?
+               &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] :
+               &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX];
+       return hlist_entry(ptr->first, struct fib_table, tb_hlist);
 }
 
-static inline int fib_lookup(const struct flowi *flp, struct fib_result *res)
+static inline struct fib_table *fib_new_table(struct net *net, u32 id)
 {
-       if (ip_fib_local_table->tb_lookup(ip_fib_local_table, flp, res) &&
-           ip_fib_main_table->tb_lookup(ip_fib_main_table, flp, res))
-               return -ENETUNREACH;
-       return 0;
+       return fib_get_table(net, id);
 }
 
-static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
+static inline int fib_lookup(struct net *net, const struct flowi *flp,
+                            struct fib_result *res)
 {
-       if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
-               ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
+       struct fib_table *table;
+
+       table = fib_get_table(net, RT_TABLE_LOCAL);
+       if (!table->tb_lookup(table, flp, res))
+               return 0;
+
+       table = fib_get_table(net, RT_TABLE_MAIN);
+       if (!table->tb_lookup(table, flp, res))
+               return 0;
+       return -ENETUNREACH;
 }
 
 #else /* CONFIG_IP_MULTIPLE_TABLES */
-extern void __init fib4_rules_init(void);
+extern int __net_init fib4_rules_init(struct net *net);
+extern void __net_exit fib4_rules_exit(struct net *net);
 
 #ifdef CONFIG_NET_CLS_ROUTE
 extern u32 fib_rules_tclass(struct fib_result *res);
 #endif
 
-#define ip_fib_local_table fib_get_table(RT_TABLE_LOCAL)
-#define ip_fib_main_table fib_get_table(RT_TABLE_MAIN)
-
-extern int fib_lookup(struct flowi *flp, struct fib_result *res);
+extern int fib_lookup(struct net *n, struct flowi *flp, struct fib_result *res);
 
-extern struct fib_table *fib_new_table(u32 id);
-extern struct fib_table *fib_get_table(u32 id);
-extern void fib_select_default(const struct flowi *flp, struct fib_result *res);
+extern struct fib_table *fib_new_table(struct net *net, u32 id);
+extern struct fib_table *fib_get_table(struct net *net, u32 id);
 
 #endif /* CONFIG_IP_MULTIPLE_TABLES */
 
@@ -207,18 +213,19 @@ extern const struct nla_policy rtm_ipv4_policy[];
 extern void            ip_fib_init(void);
 extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
                               struct net_device *dev, __be32 *spec_dst, u32 *itag);
-extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
-
-struct rtentry;
+extern void fib_select_default(struct net *net, const struct flowi *flp,
+                              struct fib_result *res);
 
 /* Exported by fib_semantics.c */
 extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
 extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
 extern int fib_sync_up(struct net_device *dev);
 extern __be32  __fib_res_prefsrc(struct fib_result *res);
+extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
-/* Exported by fib_hash.c */
-extern struct fib_table *fib_hash_init(u32 id);
+/* Exported by fib_{hash|trie}.c */
+extern void fib_hash_init(void);
+extern struct fib_table *fib_hash_table(u32 id);
 
 static inline void fib_combine_itag(u32 *itag, struct fib_result *res)
 {
@@ -255,8 +262,8 @@ static inline void fib_res_put(struct fib_result *res)
 }
 
 #ifdef CONFIG_PROC_FS
-extern int  fib_proc_init(void);
-extern void fib_proc_exit(void);
+extern int __net_init  fib_proc_init(struct net *net);
+extern void __net_exit fib_proc_exit(struct net *net);
 #endif
 
 #endif  /* _NET_FIB_H */
index 8a7d59be8a0d0e4886d9384215b315a1f1f320a1..56f3c94ae620823d09a013ba3878ff2de04510ba 100644 (file)
@@ -9,6 +9,8 @@
 #include <asm/types.h>         /* For __uXX types */
 #include <linux/types.h>       /* For __beXX types in userland */
 
+#include <linux/sysctl.h>      /* For ctl_path */
+
 #define IP_VS_VERSION_CODE     0x010201
 #define NVERSION(version)                      \
        (version >> 16) & 0xFF,                 \
@@ -676,7 +678,6 @@ extern const char *ip_vs_proto_name(unsigned proto);
 extern void ip_vs_init_hash_table(struct list_head *table, int rows);
 #define IP_VS_INIT_HASH_TABLE(t) ip_vs_init_hash_table(t, sizeof(t)/sizeof(t[0]))
 
-#define IP_VS_APP_TYPE_UNSPEC  0
 #define IP_VS_APP_TYPE_FTP     1
 
 /*
@@ -735,7 +736,6 @@ extern const char * ip_vs_state_name(__u16 proto, int state);
 
 extern void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp);
 extern int ip_vs_check_template(struct ip_vs_conn *ct);
-extern void ip_vs_secure_tcp_set(int on);
 extern void ip_vs_random_dropentry(void);
 extern int ip_vs_conn_init(void);
 extern void ip_vs_conn_cleanup(void);
@@ -856,6 +856,7 @@ extern int sysctl_ip_vs_expire_quiescent_template;
 extern int sysctl_ip_vs_sync_threshold[2];
 extern int sysctl_ip_vs_nat_icmp_send;
 extern struct ip_vs_stats ip_vs_stats;
+extern struct ctl_path net_vs_ctl_path[];
 
 extern struct ip_vs_service *
 ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport);
index 7cdc914322f0c490fbed511fbddd6b7f167a0eba..549e132bca9c834638416182698169175859e80c 100644 (file)
@@ -2,6 +2,7 @@
 #define __NET_IPIP_H 1
 
 #include <linux/if_tunnel.h>
+#include <net/ip.h>
 
 /* Keep error state on tunnel for 30 sec */
 #define IPTUNNEL_ERR_TIMEO     (30*HZ)
@@ -30,11 +31,9 @@ struct ip_tunnel
        int pkt_len = skb->len;                                         \
                                                                        \
        skb->ip_summed = CHECKSUM_NONE;                                 \
-       iph->tot_len = htons(skb->len);                                 \
        ip_select_ident(iph, &rt->u.dst, NULL);                         \
-       ip_send_check(iph);                                             \
                                                                        \
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\
+       err = ip_local_out(skb);                                        \
        if (net_xmit_eval(err) == 0) {                                  \
                stats->tx_bytes += pkt_len;                             \
                stats->tx_packets++;                                    \
index ae328b680ff2a5e5de0cd41955f7476efae95035..fa80ea48639dd30002bfeaac4200eaef4bce7faf 100644 (file)
@@ -109,9 +109,10 @@ struct frag_hdr {
 #include <net/sock.h>
 
 /* sysctls */
-extern int sysctl_ipv6_bindv6only;
 extern int sysctl_mld_max_msf;
 
+extern struct ctl_path net_ipv6_ctl_path[];
+
 #define _DEVINC(statname, modifier, idev, field)                       \
 ({                                                                     \
        struct inet6_dev *_idev = (idev);                               \
@@ -143,14 +144,6 @@ DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
 #define ICMP6_INC_STATS_BH(idev, field)        _DEVINC(icmpv6, _BH, idev, field)
 #define ICMP6_INC_STATS_USER(idev, field) _DEVINC(icmpv6, _USER, idev, field)
 
-#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({                      \
-       struct inet6_dev *_idev = idev;                                         \
-       __typeof__(offset) _offset = (offset);                                  \
-       if (likely(_idev != NULL))                                              \
-               SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset);  \
-       SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset);            \
-})
-
 #define ICMP6MSGOUT_INC_STATS(idev, field) \
        _DEVINC(icmpv6msg, , idev, field +256)
 #define ICMP6MSGOUT_INC_STATS_BH(idev, field) \
@@ -164,15 +157,6 @@ DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
 #define ICMP6MSGIN_INC_STATS_USER(idev, field) \
        _DEVINC(icmpv6msg, _USER, idev, field)
 
-DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
-DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
-#define UDP6_INC_STATS_BH(field, is_udplite)                         do  {  \
-       if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);         \
-       else            SNMP_INC_STATS_BH(udp_stats_in6, field);    } while(0)
-#define UDP6_INC_STATS_USER(field, is_udplite)                        do {    \
-       if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field);         \
-       else            SNMP_INC_STATS_USER(udp_stats_in6, field);    } while(0)
-
 struct ip6_ra_chain
 {
        struct ip6_ra_chain     *next;
@@ -236,7 +220,7 @@ extern struct ipv6_txoptions        *fl6_merge_options(struct ipv6_txoptions * opt_spac
                                                   struct ipv6_txoptions * fopt);
 extern void                    fl6_free_socklist(struct sock *sk);
 extern int                     ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen);
-extern void                    ip6_flowlabel_init(void);
+extern int                     ip6_flowlabel_init(void);
 extern void                    ip6_flowlabel_cleanup(void);
 
 static inline void fl6_sock_release(struct ip6_flowlabel *fl)
@@ -261,8 +245,8 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
 
 extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
 
-int ip6_frag_nqueues(void);
-int ip6_frag_mem(void);
+int ip6_frag_nqueues(struct net *net);
+int ip6_frag_mem(struct net *net);
 
 #define IPV6_FRAG_TIMEOUT      (60*HZ)         /* 60 seconds */
 
@@ -509,6 +493,9 @@ extern int                  ip6_forward(struct sk_buff *skb);
 extern int                     ip6_input(struct sk_buff *skb);
 extern int                     ip6_mc_input(struct sk_buff *skb);
 
+extern int                     __ip6_local_out(struct sk_buff *skb);
+extern int                     ip6_local_out(struct sk_buff *skb);
+
 /*
  *     Extension header (options) processing
  */
@@ -559,7 +546,7 @@ extern int                  compat_ipv6_getsockopt(struct sock *sk,
                                                char __user *optval,
                                                int __user *optlen);
 
-extern void                    ipv6_packet_init(void);
+extern int                     ipv6_packet_init(void);
 
 extern void                    ipv6_packet_cleanup(void);
 
@@ -585,9 +572,6 @@ extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
 /*
  * reassembly.c
  */
-struct inet_frags_ctl;
-extern struct inet_frags_ctl ip6_frags_ctl;
-
 extern const struct proto_ops inet6_stream_ops;
 extern const struct proto_ops inet6_dgram_ops;
 
@@ -602,6 +586,9 @@ extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
                         int __user *optlen);
 
 #ifdef CONFIG_PROC_FS
+extern struct ctl_table *ipv6_icmp_sysctl_init(struct net *net);
+extern struct ctl_table *ipv6_route_sysctl_init(struct net *net);
+
 extern int  ac6_proc_init(void);
 extern void ac6_proc_exit(void);
 extern int  raw6_proc_init(void);
@@ -631,10 +618,10 @@ static inline int snmp6_unregister_dev(struct inet6_dev *idev)
 #endif
 
 #ifdef CONFIG_SYSCTL
-extern ctl_table ipv6_route_table[];
-extern ctl_table ipv6_icmp_table[];
+extern ctl_table ipv6_route_table_template[];
+extern ctl_table ipv6_icmp_table_template[];
 
-extern void ipv6_sysctl_register(void);
+extern int ipv6_sysctl_register(void);
 extern void ipv6_sysctl_unregister(void);
 #endif
 
index bca19ca7bdd47418b7d93d7aca538479951047d9..f70e9b39ebafaba5711beb31fda3e19e412ccc14 100644 (file)
@@ -228,21 +228,8 @@ static inline int irda_device_txqueue_empty(const struct net_device *dev)
 int  irda_device_set_raw_mode(struct net_device* self, int status);
 struct net_device *alloc_irdadev(int sizeof_priv);
 
-/* Dongle interface */
-void irda_device_unregister_dongle(struct dongle_reg *dongle);
-int  irda_device_register_dongle(struct dongle_reg *dongle);
-dongle_t *irda_device_dongle_init(struct net_device *dev, int type);
-int irda_device_dongle_cleanup(dongle_t *dongle);
-
 void irda_setup_dma(int channel, dma_addr_t buffer, int count, int mode);
 
-void irda_task_delete(struct irda_task *task);
-struct irda_task *irda_task_execute(void *instance, 
-                                   IRDA_TASK_CALLBACK function, 
-                                   IRDA_TASK_CALLBACK finished, 
-                                   struct irda_task *parent, void *param);
-void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state);
-
 /*
  * Function irda_get_mtt (skb)
  *
index 17b60391fcd66c7ba94ff14b44c0139881412b8b..9083bafb63ca07e311b56e60d3d28c8b24da07fc 100644 (file)
@@ -138,18 +138,55 @@ enum ieee80211_phymode {
        NUM_IEEE80211_MODES
 };
 
+/**
+ * struct ieee80211_ht_info - describing 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 STA, 0: no, 1: yes
+ * @cap: HT capabilities map as described in 802.11n spec
+ * @ampdu_factor: Maximum A-MPDU length factor
+ * @ampdu_density: Minimum A-MPDU spacing
+ * @supp_mcs_set: Supported MCS set as described in 802.11n spec
+ */
+struct ieee80211_ht_info {
+       u8 ht_supported;
+       u16 cap; /* use IEEE80211_HT_CAP_ */
+       u8 ampdu_factor;
+       u8 ampdu_density;
+       u8 supp_mcs_set[16];
+};
+
+/**
+ * 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_ */
+};
+
 /**
  * struct ieee80211_hw_mode - PHY mode definition
  *
  * This structure describes the capabilities supported by the device
  * in a single PHY mode.
  *
+ * @list: internal
+ * @channels: pointer to array of supported channels
+ * @rates: pointer to array of supported bitrates
  * @mode: the PHY mode for this definition
  * @num_channels: number of supported channels
- * @channels: pointer to array of supported channels
  * @num_rates: number of supported bitrates
- * @rates: pointer to array of supported bitrates
- * @list: internal
+ * @ht_info: PHY's 802.11n HT abilities for this mode
  */
 struct ieee80211_hw_mode {
        struct list_head list;
@@ -158,6 +195,7 @@ struct ieee80211_hw_mode {
        enum ieee80211_phymode mode;
        int num_channels;
        int num_rates;
+       struct ieee80211_ht_info ht_info;
 };
 
 /**
@@ -237,11 +275,49 @@ struct ieee80211_low_level_stats {
        unsigned int dot11RTSSuccessCount;
 };
 
+/**
+ * enum ieee80211_bss_change - BSS change notification flags
+ *
+ * These flags are used with the bss_info_changed() callback
+ * to indicate which BSS parameter changed.
+ *
+ * @BSS_CHANGED_ASSOC: association status changed (associated/disassociated),
+ *     also implies a change in the AID.
+ * @BSS_CHANGED_ERP_CTS_PROT: CTS protection changed
+ * @BSS_CHANGED_ERP_PREAMBLE: preamble changed
+ */
+enum ieee80211_bss_change {
+       BSS_CHANGED_ASSOC               = 1<<0,
+       BSS_CHANGED_ERP_CTS_PROT        = 1<<1,
+       BSS_CHANGED_ERP_PREAMBLE        = 1<<2,
+};
+
+/**
+ * struct ieee80211_bss_conf - holds the BSS's changing parameters
+ *
+ * This structure keeps information about a BSS (and an association
+ * to that BSS) that can change during the lifetime of the BSS.
+ *
+ * @assoc: association status
+ * @aid: association ID number, valid only when @assoc is true
+ * @use_cts_prot: use CTS protection
+ * @use_short_preamble: use 802.11b short preamble
+ */
+struct ieee80211_bss_conf {
+       /* association related data */
+       bool assoc;
+       u16 aid;
+       /* erp related data */
+       bool use_cts_prot;
+       bool use_short_preamble;
+};
+
 /* Transmit control fields. This data structure is passed to low-level driver
  * with each TX frame. The low-level driver is responsible for configuring
  * the hardware to use given values (depending on what is supported). */
 
 struct ieee80211_tx_control {
+       struct ieee80211_vif *vif;
        int tx_rate; /* Transmit rate, given as the hw specific value for the
                      * rate (from struct ieee80211_rate) */
        int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw
@@ -269,6 +345,9 @@ struct ieee80211_tx_control {
                                                  * using the through
                                                  * set_retry_limit configured
                                                  * long retry value */
+#define IEEE80211_TXCTL_EAPOL_FRAME    (1<<11) /* internal to mac80211 */
+#define IEEE80211_TXCTL_SEND_AFTER_DTIM        (1<<12) /* send this frame after DTIM
+                                                * beacon */
        u32 flags;                             /* tx control flags defined
                                                * above */
        u8 key_idx;             /* keyidx from hw->set_key(), undefined if
@@ -291,7 +370,6 @@ struct ieee80211_tx_control {
                             * packet dropping when probing higher rates, if hw
                             * supports multiple retry rates. -1 = not used */
        int type;       /* internal */
-       int ifindex;    /* internal */
 };
 
 
@@ -312,6 +390,8 @@ struct ieee80211_tx_control {
  *     the frame.
  * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on
  *     the frame.
+ * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field)
+ *     is valid.
  */
 enum mac80211_rx_flags {
        RX_FLAG_MMIC_ERROR      = 1<<0,
@@ -321,6 +401,7 @@ enum mac80211_rx_flags {
        RX_FLAG_IV_STRIPPED     = 1<<4,
        RX_FLAG_FAILED_FCS_CRC  = 1<<5,
        RX_FLAG_FAILED_PLCP_CRC = 1<<6,
+       RX_FLAG_TSFT            = 1<<7,
 };
 
 /**
@@ -406,11 +487,12 @@ struct ieee80211_tx_status {
  *
  * @IEEE80211_CONF_SHORT_SLOT_TIME: use 802.11g short slot time
  * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
- *
+ * @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
  */
 enum ieee80211_conf_flags {
-       IEEE80211_CONF_SHORT_SLOT_TIME  = 1<<0,
-       IEEE80211_CONF_RADIOTAP         = 1<<1,
+       IEEE80211_CONF_SHORT_SLOT_TIME  = (1<<0),
+       IEEE80211_CONF_RADIOTAP         = (1<<1),
+       IEEE80211_CONF_SUPPORT_HT_MODE  = (1<<2),
 };
 
 /**
@@ -434,6 +516,8 @@ enum ieee80211_conf_flags {
  * @antenna_sel_tx: transmit antenna selection, 0: default/diversity,
  *     1/2: antenna 0/1
  * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx
+ * @ht_conf: describes current self configuration of 802.11n HT capabilies
+ * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
  */
 struct ieee80211_conf {
        int channel;                    /* IEEE 802.11 channel number */
@@ -452,6 +536,9 @@ struct ieee80211_conf {
        u8 antenna_max;
        u8 antenna_sel_tx;
        u8 antenna_sel_rx;
+
+       struct ieee80211_ht_info ht_conf;
+       struct ieee80211_ht_bss_info ht_bss_conf;
 };
 
 /**
@@ -479,14 +566,28 @@ enum ieee80211_if_types {
        IEEE80211_IF_TYPE_VLAN,
 };
 
+/**
+ * struct ieee80211_vif - per-interface data
+ *
+ * Data in this structure is continually present for driver
+ * use during the life of a virtual interface.
+ *
+ * @type: type of this virtual interface
+ * @drv_priv: data area for driver use, will always be aligned to
+ *     sizeof(void *).
+ */
+struct ieee80211_vif {
+       enum ieee80211_if_types type;
+       /* must be last */
+       u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
+};
+
 /**
  * struct ieee80211_if_init_conf - initial configuration of an interface
  *
- * @if_id: internal interface ID. This number has no particular meaning to
- *     drivers and the only allowed usage is to pass it to
- *     ieee80211_beacon_get() and ieee80211_get_buffered_bc() functions.
- *     This field is not valid for monitor interfaces
- *     (interfaces of %IEEE80211_IF_TYPE_MNTR type).
+ * @vif: pointer to a driver-use per-interface structure. The pointer
+ *     itself is also used for various functions including
+ *     ieee80211_beacon_get() and ieee80211_get_buffered_bc().
  * @type: one of &enum ieee80211_if_types constants. Determines the type of
  *     added/removed interface.
  * @mac_addr: pointer to MAC address of the interface. This pointer is valid
@@ -503,8 +604,8 @@ enum ieee80211_if_types {
  * in pure monitor mode.
  */
 struct ieee80211_if_init_conf {
-       int if_id;
        enum ieee80211_if_types type;
+       struct ieee80211_vif *vif;
        void *mac_addr;
 };
 
@@ -597,9 +698,6 @@ struct ieee80211_key_conf {
        u8 key[0];
 };
 
-#define IEEE80211_SEQ_COUNTER_RX       0
-#define IEEE80211_SEQ_COUNTER_TX       1
-
 /**
  * enum set_key_cmd - key command
  *
@@ -710,6 +808,9 @@ enum ieee80211_hw_flags {
  * @rate_control_algorithm: rate control algorithm for this hardware.
  *     If unset (NULL), the default algorithm will be used. Must be
  *     set before calling ieee80211_register_hw().
+ *
+ * @vif_data_size: size (in bytes) of the drv_priv data area
+ *     within &struct ieee80211_vif.
  */
 struct ieee80211_hw {
        struct ieee80211_conf conf;
@@ -720,6 +821,7 @@ struct ieee80211_hw {
        u32 flags;
        unsigned int extra_tx_headroom;
        int channel_change_time;
+       int vif_data_size;
        u8 queues;
        s8 max_rssi;
        s8 max_signal;
@@ -859,19 +961,18 @@ enum ieee80211_filter_flags {
 };
 
 /**
- * enum ieee80211_erp_change_flags - erp change flags
+ * enum ieee80211_ampdu_mlme_action - A-MPDU actions
  *
- * These flags are used with the erp_ie_changed() callback in
- * &struct ieee80211_ops to indicate which parameter(s) changed.
- * @IEEE80211_ERP_CHANGE_PROTECTION: protection changed
- * @IEEE80211_ERP_CHANGE_PREAMBLE: barker preamble mode changed
+ * These flags are used with the ampdu_action() callback in
+ * &struct ieee80211_ops to indicate which action is needed.
+ * @IEEE80211_AMPDU_RX_START: start Rx aggregation
+ * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
  */
-enum ieee80211_erp_change_flags {
-       IEEE80211_ERP_CHANGE_PROTECTION = 1<<0,
-       IEEE80211_ERP_CHANGE_PREAMBLE   = 1<<1,
+enum ieee80211_ampdu_mlme_action {
+       IEEE80211_AMPDU_RX_START,
+       IEEE80211_AMPDU_RX_STOP,
 };
 
-
 /**
  * struct ieee80211_ops - callbacks from mac80211 to the driver
  *
@@ -927,6 +1028,14 @@ enum ieee80211_erp_change_flags {
  * @config_interface: Handler for configuration requests related to interfaces
  *     (e.g. BSSID changes.)
  *
+ * @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).
+ *     This function should not be used if no BSS has been set, unless
+ *     for association indication. The @changed parameter indicates which
+ *     of the bss parameters has changed when a call is made. This callback
+ *     has to be atomic.
+ *
  * @configure_filter: Configure the device's RX filter.
  *     See the section "Frame filtering" for more information.
  *     This callback must be implemented and atomic.
@@ -946,9 +1055,9 @@ enum ieee80211_erp_change_flags {
  *
  * @get_stats: return low-level statistics
  *
- * @get_sequence_counter: For devices that have internal sequence counters this
- *     callback allows mac80211 to access the current value of a counter.
- *     This callback seems not well-defined, tell us if you need it.
+ * @get_tkip_seq: If your device implements TKIP encryption in hardware this
+ *     callback should be provided to read the TKIP transmit IVs (both IV32
+ *     and IV16) for the given key from hardware.
  *
  * @set_rts_threshold: Configuration of RTS threshold (if device needs it)
  *
@@ -961,8 +1070,6 @@ enum ieee80211_erp_change_flags {
  * @sta_notify: Notifies low level driver about addition or removal
  *     of assocaited station or AP.
  *
- * @erp_ie_changed: Handle ERP IE change notifications. Must be atomic.
- *
  * @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
  *     bursting) for a hardware TX queue. The @queue parameter uses the
  *     %IEEE80211_TX_QUEUE_* constants. Must be atomic.
@@ -997,6 +1104,14 @@ enum ieee80211_erp_change_flags {
  * @tx_last_beacon: Determine whether the last IBSS beacon was sent by us.
  *     This is needed only for IBSS mode and the result of this function is
  *     used to determine whether to reply to Probe Requests.
+ *
+ * @conf_ht: Configures low level driver with 802.11n HT data. Must be atomic.
+ *
+ * @ampdu_action: Perform a certain A-MPDU action
+ *     The RA/TID combination determines the destination and TID we want
+ *     the ampdu action to be performed for. The action is defined through
+ *     ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
+ *     is the first frame we expect to perform the action on.
  */
 struct ieee80211_ops {
        int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -1009,7 +1124,12 @@ struct ieee80211_ops {
                                 struct ieee80211_if_init_conf *conf);
        int (*config)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
        int (*config_interface)(struct ieee80211_hw *hw,
-                               int if_id, struct ieee80211_if_conf *conf);
+                               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,
+                                u32 changed);
        void (*configure_filter)(struct ieee80211_hw *hw,
                                 unsigned int changed_flags,
                                 unsigned int *total_flags,
@@ -1021,17 +1141,14 @@ struct ieee80211_ops {
        int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
        int (*get_stats)(struct ieee80211_hw *hw,
                         struct ieee80211_low_level_stats *stats);
-       int (*get_sequence_counter)(struct ieee80211_hw *hw,
-                                   u8* addr, u8 keyidx, u8 txrx,
-                                   u32* iv32, u16* iv16);
+       void (*get_tkip_seq)(struct ieee80211_hw *hw, u8 hw_key_idx,
+                            u32 *iv32, u16 *iv16);
        int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
        int (*set_retry_limit)(struct ieee80211_hw *hw,
                               u32 short_retry, u32 long_retr);
-       void (*sta_notify)(struct ieee80211_hw *hw, int if_id,
+       void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                        enum sta_notify_cmd, const u8 *addr);
-       void (*erp_ie_changed)(struct ieee80211_hw *hw, u8 changes,
-                              int cts_protection, int preamble);
        int (*conf_tx)(struct ieee80211_hw *hw, int queue,
                       const struct ieee80211_tx_queue_params *params);
        int (*get_tx_stats)(struct ieee80211_hw *hw,
@@ -1042,6 +1159,10 @@ struct ieee80211_ops {
                             struct sk_buff *skb,
                             struct ieee80211_tx_control *control);
        int (*tx_last_beacon)(struct ieee80211_hw *hw);
+       int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+       int (*ampdu_action)(struct ieee80211_hw *hw,
+                           enum ieee80211_ampdu_mlme_action action,
+                           const u8 *ra, u16 tid, u16 ssn);
 };
 
 /**
@@ -1073,6 +1194,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw);
 extern char *__ieee80211_get_tx_led_name(struct ieee80211_hw *hw);
 extern char *__ieee80211_get_rx_led_name(struct ieee80211_hw *hw);
 extern char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw);
+extern char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw);
 #endif
 /**
  * ieee80211_get_tx_led_name - get name of TX LED
@@ -1112,6 +1234,16 @@ static inline char *ieee80211_get_rx_led_name(struct ieee80211_hw *hw)
 #endif
 }
 
+/**
+ * ieee80211_get_assoc_led_name - get name of association LED
+ *
+ * mac80211 creates a association LED trigger for each wireless hardware
+ * that can be used to drive LEDs if your driver registers a LED device.
+ * This function returns the name (or %NULL if not configured for LEDs)
+ * of the trigger so you can automatically link the LED device.
+ *
+ * @hw: the hardware to get the LED trigger name for
+ */
 static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
 {
 #ifdef CONFIG_MAC80211_LEDS
@@ -1121,6 +1253,24 @@ static inline char *ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
 #endif
 }
 
+/**
+ * ieee80211_get_radio_led_name - get name of radio LED
+ *
+ * mac80211 creates a radio change LED trigger for each wireless hardware
+ * that can be used to drive LEDs if your driver registers a LED device.
+ * This function returns the name (or %NULL if not configured for LEDs)
+ * of the trigger so you can automatically link the LED device.
+ *
+ * @hw: the hardware to get the LED trigger name for
+ */
+static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
+{
+#ifdef CONFIG_MAC80211_LEDS
+       return __ieee80211_get_radio_led_name(hw);
+#else
+       return NULL;
+#endif
+}
 
 /* Register a new hardware PHYMODE capability to the stack. */
 int ieee80211_register_hwmode(struct ieee80211_hw *hw,
@@ -1210,7 +1360,7 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
 /**
  * ieee80211_beacon_get - beacon generation function
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @control: will be filled with information needed to send this beacon.
  *
  * If the beacon frames are generated by the host system (i.e., not in
@@ -1221,13 +1371,13 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
  * is responsible of freeing it.
  */
 struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
-                                    int if_id,
+                                    struct ieee80211_vif *vif,
                                     struct ieee80211_tx_control *control);
 
 /**
  * ieee80211_rts_get - RTS frame generation function
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame: pointer to the frame that is going to be protected by the RTS.
  * @frame_len: the frame length (in octets).
  * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -1238,7 +1388,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
  * the next RTS frame from the 802.11 code. The low-level is responsible
  * for calling this function before and RTS frame is needed.
  */
-void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       const void *frame, size_t frame_len,
                       const struct ieee80211_tx_control *frame_txctl,
                       struct ieee80211_rts *rts);
@@ -1246,7 +1396,7 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
 /**
  * ieee80211_rts_duration - Get the duration field for an RTS frame
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame_len: the length of the frame that is going to be protected by the RTS.
  * @frame_txctl: &struct ieee80211_tx_control of the frame.
  *
@@ -1254,14 +1404,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
  * the duration field, the low-level driver uses this function to receive
  * the duration field value in little-endian byteorder.
  */
-__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
-                             size_t frame_len,
+__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif, size_t frame_len,
                              const struct ieee80211_tx_control *frame_txctl);
 
 /**
  * ieee80211_ctstoself_get - CTS-to-self frame generation function
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame: pointer to the frame that is going to be protected by the CTS-to-self.
  * @frame_len: the frame length (in octets).
  * @frame_txctl: &struct ieee80211_tx_control of the frame.
@@ -1272,7 +1422,8 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
  * the next CTS-to-self frame from the 802.11 code. The low-level is responsible
  * for calling this function before and CTS-to-self frame is needed.
  */
-void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif,
                             const void *frame, size_t frame_len,
                             const struct ieee80211_tx_control *frame_txctl,
                             struct ieee80211_cts *cts);
@@ -1280,7 +1431,7 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
 /**
  * ieee80211_ctstoself_duration - Get the duration field for a CTS-to-self frame
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame_len: the length of the frame that is going to be protected by the CTS-to-self.
  * @frame_txctl: &struct ieee80211_tx_control of the frame.
  *
@@ -1288,28 +1439,30 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
  * the duration field, the low-level driver uses this function to receive
  * the duration field value in little-endian byteorder.
  */
-__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
                                    size_t frame_len,
                                    const struct ieee80211_tx_control *frame_txctl);
 
 /**
  * ieee80211_generic_frame_duration - Calculate the duration field for a frame
  * @hw: pointer obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @frame_len: the length of the frame.
  * @rate: the rate (in 100kbps) at which the frame is going to be transmitted.
  *
  * Calculate the duration field of some generic frame, given its
  * length and transmission rate (in 100kbps).
  */
-__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
+                                       struct ieee80211_vif *vif,
                                        size_t frame_len,
                                        int rate);
 
 /**
  * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames
  * @hw: pointer as obtained from ieee80211_alloc_hw().
- * @if_id: interface ID from &struct ieee80211_if_init_conf.
+ * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf.
  * @control: will be filled with information needed to send returned frame.
  *
  * Function for accessing buffered broadcast and multicast frames. If
@@ -1328,7 +1481,7 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
  * use common code for all beacons.
  */
 struct sk_buff *
-ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
+ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                          struct ieee80211_tx_control *control);
 
 /**
@@ -1406,4 +1559,19 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
  */
 void ieee80211_scan_completed(struct ieee80211_hw *hw);
 
+/**
+ * ieee80211_iterate_active_interfaces - iterate active interfaces
+ *
+ * This function iterates over the interfaces associated with a given
+ * hardware that are currently active and calls the callback for them.
+ *
+ * @hw: the hardware struct of which the interfaces should be iterated over
+ * @iterator: the iterator function to call, cannot sleep
+ * @data: first argument of the iterator function
+ */
+void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
+                                        void (*iterator)(void *data, u8 *mac,
+                                               struct ieee80211_vif *vif),
+                                        void *data);
+
 #endif /* MAC80211_H */
index a4f26187fc1aae78249d88846a5d896d2fbcadd7..ebbfb509822e068a992c49ef7b2de6c5f92a617f 100644 (file)
 #include <linux/sysctl.h>
 #include <net/rtnetlink.h>
 
+/*
+ * NUD stands for "neighbor unreachability detection"
+ */
+
 #define NUD_IN_TIMER   (NUD_INCOMPLETE|NUD_REACHABLE|NUD_DELAY|NUD_PROBE)
 #define NUD_VALID      (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY)
 #define NUD_CONNECTED  (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)
@@ -34,6 +38,7 @@ struct neighbour;
 
 struct neigh_parms
 {
+       struct net *net;
        struct net_device *dev;
        struct neigh_parms *next;
        int     (*neigh_setup)(struct neighbour *);
@@ -126,7 +131,8 @@ struct neigh_ops
 struct pneigh_entry
 {
        struct pneigh_entry     *next;
-       struct net_device               *dev;
+       struct net              *net;
+       struct net_device       *dev;
        u8                      flags;
        u8                      key[0];
 };
@@ -187,6 +193,7 @@ extern struct neighbour *   neigh_lookup(struct neigh_table *tbl,
                                             const void *pkey,
                                             struct net_device *dev);
 extern struct neighbour *      neigh_lookup_nodev(struct neigh_table *tbl,
+                                                  struct net *net,
                                                   const void *pkey);
 extern struct neighbour *      neigh_create(struct neigh_table *tbl,
                                             const void *pkey,
@@ -206,13 +213,12 @@ extern struct neighbour   *neigh_event_ns(struct neigh_table *tbl,
 
 extern struct neigh_parms      *neigh_parms_alloc(struct net_device *dev, struct neigh_table *tbl);
 extern void                    neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms);
-extern void                    neigh_parms_destroy(struct neigh_parms *parms);
 extern unsigned long           neigh_rand_reach_time(unsigned long base);
 
 extern void                    pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
                                               struct sk_buff *skb);
-extern struct pneigh_entry     *pneigh_lookup(struct neigh_table *tbl, const void *key, struct net_device *dev, int creat);
-extern int                     pneigh_delete(struct neigh_table *tbl, const void *key, struct net_device *dev);
+extern struct pneigh_entry     *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
+extern int                     pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
 
 extern void neigh_app_ns(struct neighbour *n);
 extern void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie);
@@ -220,6 +226,7 @@ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct n
 extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
 
 struct neigh_seq_state {
+       struct seq_net_private p;
        struct neigh_table *tbl;
        void *(*neigh_sub_iter)(struct neigh_seq_state *state,
                                struct neighbour *n, loff_t *pos);
@@ -246,12 +253,6 @@ static inline void __neigh_parms_put(struct neigh_parms *parms)
        atomic_dec(&parms->refcnt);
 }
 
-static inline void neigh_parms_put(struct neigh_parms *parms)
-{
-       if (atomic_dec_and_test(&parms->refcnt))
-               neigh_parms_destroy(parms);
-}
-
 static inline struct neigh_parms *neigh_parms_clone(struct neigh_parms *parms)
 {
        atomic_inc(&parms->refcnt);
@@ -288,10 +289,6 @@ static inline int neigh_is_connected(struct neighbour *neigh)
        return neigh->nud_state&NUD_CONNECTED;
 }
 
-static inline int neigh_is_valid(struct neighbour *neigh)
-{
-       return neigh->nud_state&NUD_VALID;
-}
 
 static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
 {
index 5dd6d90b37eb778dfffde65e4998b0bdb8c8d13b..b8c1d60ba9e45dbde637576c43b83311d1e531ea 100644 (file)
@@ -8,8 +8,16 @@
 #include <linux/workqueue.h>
 #include <linux/list.h>
 
+#include <net/netns/unix.h>
+#include <net/netns/packet.h>
+#include <net/netns/ipv4.h>
+#include <net/netns/ipv6.h>
+
 struct proc_dir_entry;
 struct net_device;
+struct sock;
+struct ctl_table_header;
+
 struct net {
        atomic_t                count;          /* To decided when the network
                                                 *  namespace should be freed.
@@ -24,11 +32,30 @@ struct net {
        struct proc_dir_entry   *proc_net_stat;
        struct proc_dir_entry   *proc_net_root;
 
+       struct list_head        sysctl_table_headers;
+
        struct net_device       *loopback_dev;          /* The loopback */
 
        struct list_head        dev_base_head;
        struct hlist_head       *dev_name_head;
        struct hlist_head       *dev_index_head;
+
+       /* core fib_rules */
+       struct list_head        rules_ops;
+       spinlock_t              rules_mod_lock;
+
+       struct sock             *rtnl;                  /* rtnetlink socket */
+
+       /* core sysctls */
+       struct ctl_table_header *sysctl_core_hdr;
+       int                     sysctl_somaxconn;
+
+       struct netns_packet     packet;
+       struct netns_unix       unx;
+       struct netns_ipv4       ipv4;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+       struct netns_ipv6       ipv6;
+#endif
 };
 
 #ifdef CONFIG_NET
@@ -137,4 +164,11 @@ extern void unregister_pernet_subsys(struct pernet_operations *);
 extern int register_pernet_device(struct pernet_operations *);
 extern void unregister_pernet_device(struct pernet_operations *);
 
+struct ctl_path;
+struct ctl_table;
+struct ctl_table_header;
+extern struct ctl_table_header *register_net_sysctl_table(struct net *net,
+       const struct ctl_path *path, struct ctl_table *table);
+extern void unregister_net_sysctl_table(struct ctl_table_header *header);
+
 #endif /* __NET_NET_NAMESPACE_H */
index e5d2162414234c383dae1382f3ca75fad2a75ea2..e82b7bab3ff355bfe85bb6a0f8504ff3a4ea54d7 100644 (file)
@@ -12,7 +12,7 @@
  */
 #ifdef __KERNEL__
 
-#include <net/dst.h>
+struct dst_entry;
 
 struct netevent_redirect {
        struct dst_entry *old;
index f703533fb4db2ddf923e3cb301f3d706d101c547..abc55ad75c2b849b1b22e036275133785588c151 100644 (file)
@@ -16,6 +16,8 @@ extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
                               int (*okfn)(struct sk_buff *));
 
 struct inet_frags_ctl;
-extern struct inet_frags_ctl nf_frags_ctl;
+
+#include <linux/sysctl.h>
+extern struct ctl_table nf_ct_ipv6_sysctl_table[];
 
 #endif /* _NF_CONNTRACK_IPV6_H*/
index 4ac5ab187c2a0ad0281b4700d8d9420243be01e5..857d89951790ab2b35c37c38b9628689e1296536 100644 (file)
@@ -223,8 +223,6 @@ extern void nf_conntrack_tcp_update(struct sk_buff *skb,
 /* Fake conntrack entry for untracked connections */
 extern struct nf_conn nf_conntrack_untracked;
 
-extern int nf_ct_no_defrag;
-
 /* Iterate over all conntracks: if iter returns true, it's deleted. */
 extern void
 nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data);
@@ -264,10 +262,5 @@ do {                                                       \
        local_bh_enable();                              \
 } while (0)
 
-extern int
-nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
-extern void
-nf_conntrack_unregister_cache(u_int32_t features);
-
 #endif /* __KERNEL__ */
 #endif /* _NF_CONNTRACK_H */
index a532e7b5ed6a8c105cedece60df658fb8d5e425e..7ad0828f05cfef3c8e322886c02efcffa0fac516 100644 (file)
@@ -30,16 +30,6 @@ extern void nf_conntrack_cleanup(void);
 extern int nf_conntrack_proto_init(void);
 extern void nf_conntrack_proto_fini(void);
 
-extern int nf_conntrack_helper_init(void);
-extern void nf_conntrack_helper_fini(void);
-
-struct nf_conntrack_l3proto;
-extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf);
-/* Like above, but you already have conntrack read lock. */
-extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto);
-
-struct nf_conntrack_l4proto;
-
 extern int
 nf_ct_get_tuple(const struct sk_buff *skb,
                unsigned int nhoff,
@@ -76,8 +66,6 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
        return ret;
 }
 
-extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb);
-
 int
 print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
            struct nf_conntrack_l3proto *l3proto,
index b47c04f12dbe19d17da9efc445b31f2f749e310f..6c3fd254c28ef148a8f9f04f2c35c19bbc8f7f7b 100644 (file)
@@ -73,8 +73,8 @@ void nf_ct_unexpect_related(struct nf_conntrack_expect *exp);
    nf_ct_expect_related.  You will have to call put afterwards. */
 struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me);
 void nf_ct_expect_init(struct nf_conntrack_expect *, int,
-                      union nf_conntrack_address *,
-                      union nf_conntrack_address *,
+                      union nf_inet_addr *,
+                      union nf_inet_addr *,
                       u_int8_t, __be16 *, __be16 *);
 void nf_ct_expect_put(struct nf_conntrack_expect *exp);
 int nf_ct_expect_related(struct nf_conntrack_expect *expect);
index d7b2d5483a7128702fdd81ac914908eba8b15e23..2f3af00643cf92166c1898740d45c56334d0c55c 100644 (file)
@@ -58,4 +58,8 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
 {
        return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
 }
+
+extern int nf_conntrack_helper_init(void);
+extern void nf_conntrack_helper_fini(void);
+
 #endif /*_NF_CONNTRACK_HELPER_H*/
index 15888fc7b72dc5ab49d702886fc7fa083bbe0a90..d5526bcce147ab906c884e33b38c4cc9ba977b1d 100644 (file)
@@ -42,9 +42,6 @@ struct nf_conntrack_l3proto
        int (*print_tuple)(struct seq_file *s,
                           const struct nf_conntrack_tuple *);
 
-       /* Print out the private part of the conntrack. */
-       int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
-
        /* Returns verdict for packet, or -1 for invalid. */
        int (*packet)(struct nf_conn *conntrack,
                      const struct sk_buff *skb,
@@ -73,7 +70,7 @@ struct nf_conntrack_l3proto
 
 #ifdef CONFIG_SYSCTL
        struct ctl_table_header *ctl_table_header;
-       struct ctl_table        *ctl_table_path;
+       struct ctl_path         *ctl_table_path;
        struct ctl_table        *ctl_table;
 #endif /* CONFIG_SYSCTL */
 
index c48e390f4b0f01e4c201d34d6ade08b90dec3755..45cb17cdcfd0c8555edcb280f9db61ca94d1f080 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef _NF_CONNTRACK_TUPLE_H
 #define _NF_CONNTRACK_TUPLE_H
 
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 
 /* A `tuple' is a structure containing the information to uniquely
   "non-manipulatable" lines, for the benefit of the NAT code.
 */
 
-#define NF_CT_TUPLE_L3SIZE     4
-
-/* The l3 protocol-specific manipulable parts of the tuple: always in
-   network order! */
-union nf_conntrack_address {
-       u_int32_t all[NF_CT_TUPLE_L3SIZE];
-       __be32 ip;
-       __be32 ip6[4];
-};
+#define NF_CT_TUPLE_L3SIZE     ARRAY_SIZE(((union nf_inet_addr *)NULL)->all)
 
 /* The protocol-specific manipulable parts of the tuple: always in
    network order! */
@@ -57,7 +50,7 @@ union nf_conntrack_man_proto
 /* The manipulable part of the tuple. */
 struct nf_conntrack_man
 {
-       union nf_conntrack_address u3;
+       union nf_inet_addr u3;
        union nf_conntrack_man_proto u;
        /* Layer 3 protocol */
        u_int16_t l3num;
@@ -70,7 +63,7 @@ struct nf_conntrack_tuple
 
        /* These are the parts of the tuple which are fixed. */
        struct {
-               union nf_conntrack_address u3;
+               union nf_inet_addr u3;
                union {
                        /* Add other protocols here. */
                        __be16 all;
@@ -103,7 +96,7 @@ struct nf_conntrack_tuple
 struct nf_conntrack_tuple_mask
 {
        struct {
-               union nf_conntrack_address u3;
+               union nf_inet_addr u3;
                union nf_conntrack_man_proto u;
        } src;
 };
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
new file mode 100644 (file)
index 0000000..037e824
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef _NF_LOG_H
+#define _NF_LOG_H
+
+/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
+ * disappear once iptables is replaced with pkttables.  Please DO NOT use them
+ * for any new code! */
+#define NF_LOG_TCPSEQ          0x01    /* Log TCP sequence numbers */
+#define NF_LOG_TCPOPT          0x02    /* Log TCP options */
+#define NF_LOG_IPOPT           0x04    /* Log IP options */
+#define NF_LOG_UID             0x08    /* Log UID owning local socket */
+#define NF_LOG_MASK            0x0f
+
+#define NF_LOG_TYPE_LOG                0x01
+#define NF_LOG_TYPE_ULOG       0x02
+
+struct nf_loginfo {
+       u_int8_t type;
+       union {
+               struct {
+                       u_int32_t copy_len;
+                       u_int16_t group;
+                       u_int16_t qthreshold;
+               } ulog;
+               struct {
+                       u_int8_t level;
+                       u_int8_t logflags;
+               } log;
+       } u;
+};
+
+typedef void nf_logfn(unsigned int pf,
+                     unsigned int hooknum,
+                     const struct sk_buff *skb,
+                     const struct net_device *in,
+                     const struct net_device *out,
+                     const struct nf_loginfo *li,
+                     const char *prefix);
+
+struct nf_logger {
+       struct module   *me;
+       nf_logfn        *logfn;
+       char            *name;
+};
+
+/* Function to register/unregister log function. */
+int nf_log_register(int pf, const struct nf_logger *logger);
+void nf_log_unregister(const struct nf_logger *logger);
+void nf_log_unregister_pf(int pf);
+
+/* Calls the registered backend logging function */
+void nf_log_packet(int pf,
+                  unsigned int hooknum,
+                  const struct sk_buff *skb,
+                  const struct net_device *in,
+                  const struct net_device *out,
+                  const struct nf_loginfo *li,
+                  const char *fmt, ...);
+
+#endif /* _NF_LOG_H */
index 6ae52f7c9f557facd58c94be4fc7f6c68bbac22c..9dc1039ff78bf935a1a954e1df593c41af328f67 100644 (file)
@@ -12,7 +12,8 @@ enum nf_nat_manip_type
 };
 
 /* SRC manip occurs POST_ROUTING or LOCAL_IN */
-#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
+#define HOOK2MANIP(hooknum) ((hooknum) != NF_INET_POST_ROUTING && \
+                            (hooknum) != NF_INET_LOCAL_IN)
 
 #define IP_NAT_RANGE_MAP_IPS 1
 #define IP_NAT_RANGE_PROTO_SPECIFIED 2
@@ -79,7 +80,7 @@ struct nf_conn_nat
 /* Set up the info structure to map into this range. */
 extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
                                      const struct nf_nat_range *range,
-                                     unsigned int hooknum);
+                                     enum nf_nat_manip_type maniptype);
 
 /* Is this tuple already taken? (not by us)*/
 extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
index 04578bfe23e17fbfa8791bc92dfb7a7bdd4c1b79..4aa0edbb5b966c7b2b7f16969734c522cf840ecf 100644 (file)
@@ -46,21 +46,21 @@ struct nf_nat_protocol
 };
 
 /* Protocol registration. */
-extern int nf_nat_protocol_register(struct nf_nat_protocol *proto);
-extern void nf_nat_protocol_unregister(struct nf_nat_protocol *proto);
+extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto);
+extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto);
 
-extern struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
-extern void nf_nat_proto_put(struct nf_nat_protocol *proto);
+extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol);
+extern void nf_nat_proto_put(const struct nf_nat_protocol *proto);
 
 /* Built-in protocols. */
-extern struct nf_nat_protocol nf_nat_protocol_tcp;
-extern struct nf_nat_protocol nf_nat_protocol_udp;
-extern struct nf_nat_protocol nf_nat_protocol_icmp;
-extern struct nf_nat_protocol nf_nat_unknown_protocol;
+extern const struct nf_nat_protocol nf_nat_protocol_tcp;
+extern const struct nf_nat_protocol nf_nat_protocol_udp;
+extern const struct nf_nat_protocol nf_nat_protocol_icmp;
+extern const struct nf_nat_protocol nf_nat_unknown_protocol;
 
 extern int init_protocols(void) __init;
 extern void cleanup_protocols(void);
-extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
+extern const struct nf_nat_protocol *find_nat_proto(u_int16_t protonum);
 
 extern int nf_nat_port_range_to_nlattr(struct sk_buff *skb,
                                       const struct nf_nat_range *range);
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
new file mode 100644 (file)
index 0000000..d030044
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _NF_QUEUE_H
+#define _NF_QUEUE_H
+
+/* Each queued (to userspace) skbuff has one of these. */
+struct nf_queue_entry {
+       struct list_head        list;
+       struct sk_buff          *skb;
+       unsigned int            id;
+
+       struct nf_hook_ops      *elem;
+       int                     pf;
+       unsigned int            hook;
+       struct net_device       *indev;
+       struct net_device       *outdev;
+       int                     (*okfn)(struct sk_buff *);
+};
+
+#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
+
+/* Packet queuing */
+struct nf_queue_handler {
+       int                     (*outfn)(struct nf_queue_entry *entry,
+                                        unsigned int queuenum);
+       char                    *name;
+};
+
+extern int nf_register_queue_handler(int pf,
+                                    const struct nf_queue_handler *qh);
+extern int nf_unregister_queue_handler(int pf,
+                                      const struct nf_queue_handler *qh);
+extern void nf_unregister_queue_handlers(const struct nf_queue_handler *qh);
+extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
+
+#endif /* _NF_QUEUE_H */
diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h
new file mode 100644 (file)
index 0000000..65d594d
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _XT_RATEEST_H
+#define _XT_RATEEST_H
+
+struct xt_rateest {
+       struct hlist_node               list;
+       char                            name[IFNAMSIZ];
+       unsigned int                    refcnt;
+       spinlock_t                      lock;
+       struct gnet_estimator           params;
+       struct gnet_stats_rate_est      rstats;
+       struct gnet_stats_basic         bstats;
+};
+
+extern struct xt_rateest *xt_rateest_lookup(const char *name);
+extern void xt_rateest_put(struct xt_rateest *est);
+
+#endif /* _XT_RATEEST_H */
index 9298218c07f9afa7fda027fcbb07a8b4684b673f..a5506c42f03c164350e1ba69e5dfc445d3b388c2 100644 (file)
@@ -91,6 +91,7 @@
  *   nla_reserve_nohdr(skb, len)       reserve room for an attribute w/o hdr
  *   nla_put(skb, type, len, data)     add attribute to skb
  *   nla_put_nohdr(skb, len, data)     add attribute w/o hdr
+ *   nla_append(skb, len, data)                append data to skb
  *
  * Attribute Construction for Basic Types:
  *   nla_put_u8(skb, type, value)      add u8 attribute to skb
@@ -217,6 +218,7 @@ struct nla_policy {
  */
 struct nl_info {
        struct nlmsghdr         *nlh;
+       struct net              *nl_net;
        u32                     pid;
 };
 
@@ -253,6 +255,8 @@ extern int          nla_put(struct sk_buff *skb, int attrtype,
                                int attrlen, const void *data);
 extern int             nla_put_nohdr(struct sk_buff *skb, int attrlen,
                                      const void *data);
+extern int             nla_append(struct sk_buff *skb, int attrlen,
+                                  const void *data);
 
 /**************************************************************************
  * Netlink Messages
@@ -862,7 +866,7 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
 
 #define NLA_PUT(skb, attrtype, attrlen, data) \
        do { \
-               if (nla_put(skb, attrtype, attrlen, data) < 0) \
+               if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
                        goto nla_put_failure; \
        } while(0)
 
@@ -881,6 +885,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype,
 #define NLA_PUT_LE16(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, __le16, attrtype, value)
 
+#define NLA_PUT_BE16(skb, attrtype, value) \
+       NLA_PUT_TYPE(skb, __be16, attrtype, value)
+
 #define NLA_PUT_U32(skb, attrtype, value) \
        NLA_PUT_TYPE(skb, u32, attrtype, value)
 
@@ -926,6 +933,15 @@ static inline u16 nla_get_u16(struct nlattr *nla)
        return *(u16 *) nla_data(nla);
 }
 
+/**
+ * nla_get_be16 - return payload of __be16 attribute
+ * @nla: __be16 netlink attribute
+ */
+static inline __be16 nla_get_be16(struct nlattr *nla)
+{
+       return *(__be16 *) nla_data(nla);
+}
+
 /**
  * nla_get_le16 - return payload of __le16 attribute
  * @nla: __le16 netlink attribute
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
new file mode 100644 (file)
index 0000000..15a0b05
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * ipv4 in net namespaces
+ */
+
+#ifndef __NETNS_IPV4_H__
+#define __NETNS_IPV4_H__
+
+#include <net/inet_frag.h>
+
+struct ctl_table_header;
+struct ipv4_devconf;
+struct fib_rules_ops;
+struct hlist_head;
+struct sock;
+
+struct netns_ipv4 {
+#ifdef CONFIG_SYSCTL
+       struct ctl_table_header *forw_hdr;
+       struct ctl_table_header *frags_hdr;
+#endif
+       struct ipv4_devconf     *devconf_all;
+       struct ipv4_devconf     *devconf_dflt;
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+       struct fib_rules_ops    *rules_ops;
+#endif
+       struct hlist_head       *fib_table_hash;
+       struct sock             *fibnl;
+
+       struct netns_frags      frags;
+};
+#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
new file mode 100644 (file)
index 0000000..187c424
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * ipv6 in net namespaces
+ */
+
+#include <net/inet_frag.h>
+
+#ifndef __NETNS_IPV6_H__
+#define __NETNS_IPV6_H__
+
+struct ctl_table_header;
+
+struct netns_sysctl_ipv6 {
+#ifdef CONFIG_SYSCTL
+       struct ctl_table_header *table;
+       struct ctl_table_header *frags_hdr;
+#endif
+       int bindv6only;
+       int flush_delay;
+       int ip6_rt_max_size;
+       int ip6_rt_gc_min_interval;
+       int ip6_rt_gc_timeout;
+       int ip6_rt_gc_interval;
+       int ip6_rt_gc_elasticity;
+       int ip6_rt_mtu_expires;
+       int ip6_rt_min_advmss;
+       int icmpv6_time;
+};
+
+struct netns_ipv6 {
+       struct netns_sysctl_ipv6 sysctl;
+       struct ipv6_devconf     *devconf_all;
+       struct ipv6_devconf     *devconf_dflt;
+       struct netns_frags      frags;
+};
+#endif
diff --git a/include/net/netns/packet.h b/include/net/netns/packet.h
new file mode 100644 (file)
index 0000000..637daf6
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Packet network namespace
+ */
+#ifndef __NETNS_PACKET_H__
+#define __NETNS_PACKET_H__
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct netns_packet {
+       rwlock_t                sklist_lock;
+       struct hlist_head       sklist;
+};
+
+#endif /* __NETNS_PACKET_H__ */
diff --git a/include/net/netns/unix.h b/include/net/netns/unix.h
new file mode 100644 (file)
index 0000000..284649d
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * Unix network namespace
+ */
+#ifndef __NETNS_UNIX_H__
+#define __NETNS_UNIX_H__
+
+struct ctl_table_header;
+struct netns_unix {
+       int                     sysctl_max_dgram_qlen;
+       struct ctl_table_header *ctl;
+};
+
+#endif /* __NETNS_UNIX_H__ */
index f285de69c615edeb003eb3e3e5ca9746cdcb7fda..8716eb757d514f076f33a60e550096f1ede1d0dc 100644 (file)
@@ -2,7 +2,6 @@
 #define __NET_PKT_CLS_H
 
 #include <linux/pkt_cls.h>
-#include <net/net_namespace.h>
 #include <net/sch_generic.h>
 #include <net/act_api.h>
 
@@ -130,8 +129,8 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
        return 0;
 }
 
-extern int tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
-                            struct rtattr *rate_tlv, struct tcf_exts *exts,
+extern int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
+                            struct nlattr *rate_tlv, struct tcf_exts *exts,
                             struct tcf_ext_map *map);
 extern void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
 extern void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
@@ -248,7 +247,7 @@ struct tcf_ematch_ops
 
 extern int tcf_em_register(struct tcf_ematch_ops *);
 extern int tcf_em_unregister(struct tcf_ematch_ops *);
-extern int tcf_em_tree_validate(struct tcf_proto *, struct rtattr *,
+extern int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
                                struct tcf_ematch_tree *);
 extern void tcf_em_tree_destroy(struct tcf_proto *, struct tcf_ematch_tree *);
 extern int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
@@ -336,10 +335,12 @@ static inline int tcf_valid_offset(const struct sk_buff *skb,
 }
 
 #ifdef CONFIG_NET_CLS_IND
+#include <net/net_namespace.h>
+
 static inline int
-tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv)
+tcf_change_indev(struct tcf_proto *tp, char *indev, struct nlattr *indev_tlv)
 {
-       if (rtattr_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
+       if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
                return -EINVAL;
        return 0;
 }
index ab61809a9616af402d8d197da3fc58a89b05e69c..46fb4d80c74a9d69253eaff15219cc4093004a30 100644 (file)
@@ -77,7 +77,7 @@ extern int unregister_qdisc(struct Qdisc_ops *qops);
 extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
 extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
-               struct rtattr *tab);
+               struct nlattr *tab);
 extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
 
 extern void __qdisc_run(struct net_device *dev);
index 1166ffb4b3ec7a253c640b680bbbd412718b1d48..ad8c584233a62c75f857929d1b4ee5ba3c6d0521 100644 (file)
@@ -102,7 +102,7 @@ extern void inet_unregister_protosw(struct inet_protosw *p);
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 extern int     inet6_add_protocol(struct inet6_protocol *prot, unsigned char num);
 extern int     inet6_del_protocol(struct inet6_protocol *prot, unsigned char num);
-extern void    inet6_register_protosw(struct inet_protosw *p);
+extern int     inet6_register_protosw(struct inet_protosw *p);
 extern void    inet6_unregister_protosw(struct inet_protosw *p);
 #endif
 
index e4af59781949f12b0a097fafd06abea7ee841fde..cca81d8b2d8ba2052e75539aa314cec10d066833 100644 (file)
 
 extern struct proto raw_prot;
 
-extern void    raw_err(struct sock *, struct sk_buff *, u32 info);
-extern int     raw_rcv(struct sock *, struct sk_buff *);
-
-/* Note: v4 ICMP wants to get at this stuff, if you change the
- *       hashing mechanism, make sure you update icmp.c as well.
- */
-#define RAWV4_HTABLE_SIZE      MAX_INET_PROTOS
-extern struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
-
-extern rwlock_t raw_v4_lock;
+void raw_icmp_error(struct sk_buff *, int, u32);
+int raw_local_deliver(struct sk_buff *, int);
 
+extern int     raw_rcv(struct sock *, struct sk_buff *);
 
-extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
-                                   __be32 raddr, __be32 laddr,
-                                   int dif);
+#define RAW_HTABLE_SIZE        MAX_INET_PROTOS
 
-extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
+struct raw_hashinfo {
+       rwlock_t lock;
+       struct hlist_head ht[RAW_HTABLE_SIZE];
+};
 
 #ifdef CONFIG_PROC_FS
 extern int  raw_proc_init(void);
 extern void raw_proc_exit(void);
+
+struct raw_iter_state {
+       struct seq_net_private p;
+       int bucket;
+       unsigned short family;
+       struct raw_hashinfo *h;
+};
+
+#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
+void *raw_seq_start(struct seq_file *seq, loff_t *pos);
+void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos);
+void raw_seq_stop(struct seq_file *seq, void *v);
+int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
+               unsigned short family);
+
 #endif
 
+void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h);
+void raw_unhash_sk(struct sock *sk, struct raw_hashinfo *h);
+
 #endif /* _RAW_H */
index a5819891d52518a25b8430ba1f90cdad6ab0b403..8a22599f26ba9ce4fe7b9e649e23321fc359263d 100644 (file)
@@ -5,26 +5,13 @@
 
 #include <net/protocol.h>
 
-#define RAWV6_HTABLE_SIZE      MAX_INET_PROTOS
-extern struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
-extern rwlock_t raw_v6_lock;
-
-extern int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr);
-
-extern struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
-                                   struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
-                                   int dif);
+void raw6_icmp_error(struct sk_buff *, int nexthdr,
+               int type, int code, int inner_offset, __be32);
+int raw6_local_deliver(struct sk_buff *, int);
 
 extern int                     rawv6_rcv(struct sock *sk,
                                          struct sk_buff *skb);
 
-
-extern void                    rawv6_err(struct sock *sk,
-                                         struct sk_buff *skb,
-                                         struct inet6_skb_parm *opt,
-                                         int type, int code, 
-                                         int offset, __be32 info);
-
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 int rawv6_mh_filter_register(int (*filter)(struct sock *sock,
                                           struct sk_buff *skb));
index 59b0b19205a290e07d666d259012979ae4d1d800..4eabf008413bfb18390fd552e88a49f4fcf44e28 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ip.h>
 #include <linux/cache.h>
 #include <linux/security.h>
+#include <net/sock.h>
 
 #ifndef __KERNEL__
 #warning This file is not supposed to be used outside of kernel.
@@ -110,16 +111,17 @@ extern int                ip_rt_init(void);
 extern void            ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
                                       __be32 src, struct net_device *dev);
 extern void            rt_cache_flush(int how);
-extern int             __ip_route_output_key(struct rtable **, const struct flowi *flp);
-extern int             ip_route_output_key(struct rtable **, struct flowi *flp);
-extern int             ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
+extern int             __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
+extern int             ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
+extern int             ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
 extern int             ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin);
-extern unsigned short  ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
+extern unsigned short  ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu);
 extern void            ip_rt_send_redirect(struct sk_buff *skb);
 
-extern unsigned                inet_addr_type(__be32 addr);
+extern unsigned                inet_addr_type(struct net *net, __be32 addr);
+extern unsigned                inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
 extern void            ip_rt_multicast_event(struct in_device *);
-extern int             ip_rt_ioctl(unsigned int cmd, void __user *arg);
+extern int             ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
 extern void            ip_rt_get_source(u8 *src, struct rtable *rt);
 extern int             ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
 
@@ -156,8 +158,9 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
                                         .dport = dport } } };
 
        int err;
+       struct net *net = sk->sk_net;
        if (!dst || !src) {
-               err = __ip_route_output_key(rp, &fl);
+               err = __ip_route_output_key(net, rp, &fl);
                if (err)
                        return err;
                fl.fl4_dst = (*rp)->rt_dst;
@@ -166,7 +169,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
                *rp = NULL;
        }
        security_sk_classify_flow(sk, &fl);
-       return ip_route_output_flow(rp, &fl, sk, flags);
+       return ip_route_output_flow(net, rp, &fl, sk, flags);
 }
 
 static inline int ip_route_newports(struct rtable **rp, u8 protocol,
@@ -183,7 +186,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol,
                ip_rt_put(*rp);
                *rp = NULL;
                security_sk_classify_flow(sk, &fl);
-               return ip_route_output_flow(rp, &fl, sk, 0);
+               return ip_route_output_flow(sk->sk_net, rp, &fl, sk, 0);
        }
        return 0;
 }
index 4c3b35153c3722b2a5871cf78ed11023f7fa9e17..ab502ec1c61c3752b022b24ce49f833235b8621c 100644 (file)
@@ -66,7 +66,7 @@ struct Qdisc_class_ops
        unsigned long           (*get)(struct Qdisc *, u32 classid);
        void                    (*put)(struct Qdisc *, unsigned long);
        int                     (*change)(struct Qdisc *, u32, u32,
-                                       struct rtattr **, unsigned long *);
+                                       struct nlattr **, unsigned long *);
        int                     (*delete)(struct Qdisc *, unsigned long);
        void                    (*walk)(struct Qdisc *, struct qdisc_walker * arg);
 
@@ -86,7 +86,7 @@ struct Qdisc_class_ops
 struct Qdisc_ops
 {
        struct Qdisc_ops        *next;
-       struct Qdisc_class_ops  *cl_ops;
+       const struct Qdisc_class_ops    *cl_ops;
        char                    id[IFNAMSIZ];
        int                     priv_size;
 
@@ -95,10 +95,10 @@ struct Qdisc_ops
        int                     (*requeue)(struct sk_buff *, struct Qdisc *);
        unsigned int            (*drop)(struct Qdisc *);
 
-       int                     (*init)(struct Qdisc *, struct rtattr *arg);
+       int                     (*init)(struct Qdisc *, struct nlattr *arg);
        void                    (*reset)(struct Qdisc *);
        void                    (*destroy)(struct Qdisc *);
-       int                     (*change)(struct Qdisc *, struct rtattr *arg);
+       int                     (*change)(struct Qdisc *, struct nlattr *arg);
 
        int                     (*dump)(struct Qdisc *, struct sk_buff *);
        int                     (*dump_stats)(struct Qdisc *, struct gnet_dump *);
@@ -126,7 +126,7 @@ struct tcf_proto_ops
        unsigned long           (*get)(struct tcf_proto*, u32 handle);
        void                    (*put)(struct tcf_proto*, unsigned long);
        int                     (*change)(struct tcf_proto*, unsigned long,
-                                       u32 handle, struct rtattr **,
+                                       u32 handle, struct nlattr **,
                                        unsigned long *);
        int                     (*delete)(struct tcf_proto*, unsigned long);
        void                    (*walk)(struct tcf_proto*, struct tcf_walker *arg);
diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
new file mode 100644 (file)
index 0000000..ba75c67
--- /dev/null
@@ -0,0 +1,78 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ *
+ * This file is part of the SCTP kernel reference Implementation
+ *
+ * SCTP Checksum functions
+ *
+ * The SCTP reference implementation 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, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *    Dinakaran Joseph
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Rewritten to use libcrc32c by:
+ *    Vlad Yasevich <vladislav.yasevich@hp.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
+#include <linux/types.h>
+#include <net/sctp/sctp.h>
+#include <linux/crc32c.h>
+
+static inline __u32 sctp_start_cksum(__u8 *buffer, __u16 length)
+{
+       __u32 crc = ~(__u32) 0;
+       __u8  zero[sizeof(__u32)] = {0};
+
+       /* Optimize this routine to be SCTP specific, knowing how
+        * to skip the checksum field of the SCTP header.
+        */
+
+       /* Calculate CRC up to the checksum. */
+       crc = crc32c(crc, buffer, sizeof(struct sctphdr) - sizeof(__u32));
+
+       /* Skip checksum field of the header. */
+       crc = crc32c(crc, zero, sizeof(__u32));
+
+       /* Calculate the rest of the CRC. */
+       crc = crc32c(crc, &buffer[sizeof(struct sctphdr)],
+                           length - sizeof(struct sctphdr));
+       return crc;
+}
+
+static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
+{
+       return crc32c(crc32, buffer, length);
+}
+
+static inline __u32 sctp_end_cksum(__u32 crc32)
+{
+       return ntohl(~crc32);
+}
index 05f22a6afbcdc4cceeefd4431696db74c384f044..fefcba67bd1edc7b8c863472755afe95c925c8d2 100644 (file)
@@ -365,36 +365,12 @@ typedef enum {
  * Also, RFC 8.4, non-unicast addresses are not considered valid SCTP
  * addresses.
  */
-#define IS_IPV4_UNUSABLE_ADDRESS(a) \
-       ((htonl(INADDR_BROADCAST) == *a) || \
-       (MULTICAST(*a)) || \
-       (((unsigned char *)(a))[0] == 0) || \
-       ((((unsigned char *)(a))[0] == 198) && \
-       (((unsigned char *)(a))[1] == 18) && \
-       (((unsigned char *)(a))[2] == 0)) || \
-       ((((unsigned char *)(a))[0] == 192) && \
-       (((unsigned char *)(a))[1] == 88) && \
-       (((unsigned char *)(a))[2] == 99)))
-
-/* IPv4 Link-local addresses: 169.254.0.0/16.  */
-#define IS_IPV4_LINK_ADDRESS(a) \
-       ((((unsigned char *)(a))[0] == 169) && \
-       (((unsigned char *)(a))[1] == 254))
-
-/* RFC 1918 "Address Allocation for Private Internets" defines the IPv4
- * private address space as the following:
- *
- * 10.0.0.0 - 10.255.255.255 (10/8 prefix)
- * 172.16.0.0.0 - 172.31.255.255 (172.16/12 prefix)
- * 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
- */
-#define IS_IPV4_PRIVATE_ADDRESS(a) \
-       ((((unsigned char *)(a))[0] == 10) || \
-       ((((unsigned char *)(a))[0] == 172) && \
-       (((unsigned char *)(a))[1] >= 16) && \
-       (((unsigned char *)(a))[1] < 32)) || \
-       ((((unsigned char *)(a))[0] == 192) && \
-       (((unsigned char *)(a))[1] == 168)))
+#define IS_IPV4_UNUSABLE_ADDRESS(a)        \
+       ((htonl(INADDR_BROADCAST) == a) ||  \
+        ipv4_is_multicast(a) ||            \
+        ipv4_is_zeronet(a) ||              \
+        ipv4_is_test_198(a) ||             \
+        ipv4_is_anycast_6to4(a))
 
 /* Flags used for the bind address copy functions.  */
 #define SCTP_ADDR6_ALLOWED     0x00000001      /* IPv6 address is allowed by
index 34318a33a94c0471126a763439fe62ce695aa008..4977b0a81535519508fa0f0f90b0bd44c6dd19d3 100644 (file)
@@ -149,13 +149,6 @@ int sctp_primitive_SEND(struct sctp_association *, void *arg);
 int sctp_primitive_REQUESTHEARTBEAT(struct sctp_association *, void *arg);
 int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
 
-/*
- * sctp/crc32c.c
- */
-__u32 sctp_start_cksum(__u8 *ptr, __u16 count);
-__u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum);
-__u32 sctp_end_cksum(__u32 cksum);
-
 /*
  * sctp/input.c
  */
@@ -470,8 +463,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
        skb->destructor = sctp_sock_rfree;
        atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
        /*
-        * This mimics the behavior of
-        * sk_stream_set_owner_r
+        * This mimics the behavior of skb_set_owner_r
         */
        sk->sk_forward_alloc -= event->rmem_len;
 }
index bb965742b64e4bb73610698e6b9f3f15a61d2d17..4d591bfce45246334a6062abe9d6816d47d9cf65 100644 (file)
@@ -451,6 +451,7 @@ union sctp_params {
        struct sctp_random_param *random;
        struct sctp_chunks_param *chunks;
        struct sctp_hmac_algo_param *hmac_algo;
+       struct sctp_addip_param *addip;
 };
 
 /* RFC 2960.  Section 3.3.5 Heartbeat.
@@ -743,6 +744,7 @@ struct sctp_chunk {
        __u8 tsn_missing_report; /* Data chunk missing counter. */
        __u8 data_accepted;     /* At least 1 chunk in this packet accepted */
        __u8 auth;              /* IN: was auth'ed | OUT: needs auth */
+       __u8 has_asconf;        /* IN: have seen an asconf before */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
@@ -758,12 +760,18 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *,
                     union sctp_addr *);
 const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
 
+enum {
+       SCTP_ADDR_NEW,          /* new address added to assoc/ep */
+       SCTP_ADDR_SRC,          /* address can be used as source */
+       SCTP_ADDR_DEL,          /* address about to be deleted */
+};
+
 /* This is a structure for holding either an IPv6 or an IPv4 address.  */
 struct sctp_sockaddr_entry {
        struct list_head list;
        struct rcu_head rcu;
        union sctp_addr a;
-       __u8 use_as_src;
+       __u8 state;
        __u8 valid;
 };
 
@@ -1188,10 +1196,12 @@ int sctp_bind_addr_dup(struct sctp_bind_addr *dest,
                        const struct sctp_bind_addr *src,
                        gfp_t gfp);
 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *,
-                      __u8 use_as_src, gfp_t gfp);
+                      __u8 addr_state, gfp_t gfp);
 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
 int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *,
                         struct sctp_sock *);
+int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
+                        const union sctp_addr *addr);
 union sctp_addr *sctp_find_unmatch_addr(struct sctp_bind_addr  *bp,
                                        const union sctp_addr   *addrs,
                                        int                     addrcnt,
@@ -1784,20 +1794,16 @@ struct sctp_association {
         */
        struct sctp_chunk *addip_last_asconf;
 
-       /* ADDIP Section 4.2 Upon reception of an ASCONF Chunk.
+       /* ADDIP Section 5.2 Upon reception of an ASCONF Chunk.
         *
-        * IMPLEMENTATION NOTE: As an optimization a receiver may wish
-        * to save the last ASCONF-ACK for some predetermined period
-        * of time and instead of re-processing the ASCONF (with the
-        * same serial number) it may just re-transmit the
-        * ASCONF-ACK. It may wish to use the arrival of a new serial
-        * number to discard the previously saved ASCONF-ACK or any
-        * other means it may choose to expire the saved ASCONF-ACK.
+        * This is needed to implement itmes E1 - E4 of the updated
+        * spec.  Here is the justification:
         *
-        * [This is our saved ASCONF-ACK.  We invalidate it when a new
-        * ASCONF serial number arrives.]
+        * Since the peer may bundle multiple ASCONF chunks toward us,
+        * we now need the ability to cache multiple ACKs.  The section
+        * describes in detail how they are cached and cleaned up.
         */
-       struct sctp_chunk *addip_last_asconf_ack;
+       struct list_head asconf_ack_list;
 
        /* These ASCONF chunks are waiting to be sent.
         *
@@ -1938,12 +1944,19 @@ void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned);
 void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned);
 void sctp_assoc_set_primary(struct sctp_association *,
                            struct sctp_transport *);
+void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
+                                   struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
                                     gfp_t);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
                                         struct sctp_cookie*,
                                         gfp_t gfp);
 int sctp_assoc_set_id(struct sctp_association *, gfp_t);
+void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc);
+struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
+                                       const struct sctp_association *asoc,
+                                       __be32 serial);
+
 
 int sctp_cmp_addr_exact(const union sctp_addr *ss1,
                        const union sctp_addr *ss2);
index ea206bff0dc4c01e8fa6cfa5f00d82add2c96743..ce2f48507510d95db72c064973cc76a4b3925677 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/cache.h>
 #include <linux/snmp.h>
+#include <linux/smp.h>
 
 /*
  * Mibs are stored in array of unsigned long.
@@ -117,6 +118,11 @@ struct linux_mib {
        unsigned long   mibs[LINUX_MIB_MAX];
 };
 
+/* Linux Xfrm */
+#define LINUX_MIB_XFRMMAX      __LINUX_MIB_XFRMMAX
+struct linux_xfrm_mib {
+       unsigned long   mibs[LINUX_MIB_XFRMMAX];
+};
 
 /* 
  * FIXME: On x86 and some other CPUs the split into user and softirq parts
@@ -134,17 +140,27 @@ struct linux_mib {
 
 #define SNMP_INC_STATS_BH(mib, field)  \
        (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field]++)
-#define SNMP_INC_STATS_OFFSET_BH(mib, field, offset)   \
-       (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field + (offset)]++)
 #define SNMP_INC_STATS_USER(mib, field) \
-       (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field]++)
+       do { \
+               per_cpu_ptr(mib[1], get_cpu())->mibs[field]++; \
+               put_cpu(); \
+       } while (0)
 #define SNMP_INC_STATS(mib, field)     \
-       (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]++)
+       do { \
+               per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]++; \
+               put_cpu(); \
+       } while (0)
 #define SNMP_DEC_STATS(mib, field)     \
-       (per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id())->mibs[field]--)
+       do { \
+               per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
+               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)        \
-       (per_cpu_ptr(mib[1], raw_smp_processor_id())->mibs[field] += addend)
+       do { \
+               per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
+               put_cpu(); \
+       } while (0)
 
 #endif
index 6e1542da33a1ae26ddc93b80a2071401c6f73c09..902324488d0f7d2fb9a485258f59efa827344b0f 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/module.h>
 #include <linux/lockdep.h>
 #include <linux/netdevice.h>
+#include <linux/pcounter.h>
 #include <linux/skbuff.h>      /* struct sk_buff */
 #include <linux/mm.h>
 #include <linux/security.h>
@@ -56,7 +57,6 @@
 #include <asm/atomic.h>
 #include <net/dst.h>
 #include <net/checksum.h>
-#include <net/net_namespace.h>
 
 /*
  * This structure really needs to be cleaned up.
@@ -94,6 +94,7 @@ typedef struct {
 
 struct sock;
 struct proto;
+struct net;
 
 /**
  *     struct sock_common - minimal network layer representation of sockets
@@ -145,7 +146,8 @@ struct sock_common {
   *    @sk_forward_alloc: space allocated forward
   *    @sk_allocation: allocation mode
   *    @sk_sndbuf: size of send buffer in bytes
-  *    @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
+  *    @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE,
+  *               %SO_OOBINLINE settings
   *    @sk_no_check: %SO_NO_CHECK setting, wether or not checkup packets
   *    @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO)
   *    @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4)
@@ -153,9 +155,12 @@ struct sock_common {
   *    @sk_backlog: always used with the per-socket spinlock held
   *    @sk_callback_lock: used with the callbacks in the end of this struct
   *    @sk_error_queue: rarely used
-  *    @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt, IPV6_ADDRFORM for instance)
+  *    @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt,
+  *                      IPV6_ADDRFORM for instance)
   *    @sk_err: last error
-  *    @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out'
+  *    @sk_err_soft: errors that don't cause failure but are the cause of a
+  *                  persistent failure not just 'timed out'
+  *    @sk_drops: raw drops counter
   *    @sk_ack_backlog: current listen backlog
   *    @sk_max_ack_backlog: listen backlog set in listen()
   *    @sk_priority: %SO_PRIORITY setting
@@ -239,6 +244,7 @@ struct sock {
        rwlock_t                sk_callback_lock;
        int                     sk_err,
                                sk_err_soft;
+       atomic_t                sk_drops;
        unsigned short          sk_ack_backlog;
        unsigned short          sk_max_ack_backlog;
        __u32                   sk_priority;
@@ -439,7 +445,7 @@ static inline int sk_acceptq_is_full(struct sock *sk)
  */
 static inline int sk_stream_min_wspace(struct sock *sk)
 {
-       return sk->sk_wmem_queued / 2;
+       return sk->sk_wmem_queued >> 1;
 }
 
 static inline int sk_stream_wspace(struct sock *sk)
@@ -454,25 +460,6 @@ static inline int sk_stream_memory_free(struct sock *sk)
        return sk->sk_wmem_queued < sk->sk_sndbuf;
 }
 
-extern void sk_stream_rfree(struct sk_buff *skb);
-
-static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
-{
-       skb->sk = sk;
-       skb->destructor = sk_stream_rfree;
-       atomic_add(skb->truesize, &sk->sk_rmem_alloc);
-       sk->sk_forward_alloc -= skb->truesize;
-}
-
-static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
-{
-       skb_truesize_check(skb);
-       sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
-       sk->sk_wmem_queued   -= skb->truesize;
-       sk->sk_forward_alloc += skb->truesize;
-       __kfree_skb(skb);
-}
-
 /* The per-socket spinlock must be held here. */
 static inline void sk_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
@@ -560,14 +547,11 @@ struct proto {
        void                    (*unhash)(struct sock *sk);
        int                     (*get_port)(struct sock *sk, unsigned short snum);
 
-#ifdef CONFIG_SMP
        /* Keeping track of sockets in use */
-       void                    (*inuse_add)(struct proto *prot, int inc);
-       int                     (*inuse_getval)(const struct proto *prot);
-       int                     *inuse_ptr;
-#else
-       int                     inuse;
+#ifdef CONFIG_PROC_FS
+       struct pcounter         inuse;
 #endif
+
        /* Memory pressure */
        void                    (*enter_memory_pressure)(void);
        atomic_t                *memory_allocated;      /* Current allocated memory. */
@@ -575,7 +559,7 @@ struct proto {
        /*
         * Pressure flag: try to collapse.
         * Technical note: it is used by multiple contexts non atomically.
-        * All the sk_stream_mem_schedule() is of this nature: accounting
+        * All the __sk_mem_schedule() is of this nature: accounting
         * is strict, actions are advisory and have some latency.
         */
        int                     *memory_pressure;
@@ -602,36 +586,6 @@ struct proto {
 #endif
 };
 
-/*
- * Special macros to let protos use a fast version of inuse{get|add}
- * using a static percpu variable per proto instead of an allocated one,
- * saving one dereference.
- * This might be changed if/when dynamic percpu vars become fast.
- */
-#ifdef CONFIG_SMP
-# define DEFINE_PROTO_INUSE(NAME)                      \
-static DEFINE_PER_CPU(int, NAME##_inuse);              \
-static void NAME##_inuse_add(struct proto *prot, int inc)      \
-{                                                      \
-       __get_cpu_var(NAME##_inuse) += inc;             \
-}                                                      \
-                                                       \
-static int NAME##_inuse_getval(const struct proto *prot)\
-{                                                      \
-       int res = 0, cpu;                               \
-                                                       \
-       for_each_possible_cpu(cpu)                      \
-               res += per_cpu(NAME##_inuse, cpu);      \
-       return res;                                     \
-}
-# define REF_PROTO_INUSE(NAME)                         \
-       .inuse_add = NAME##_inuse_add,                  \
-       .inuse_getval = NAME##_inuse_getval,
-#else
-# define DEFINE_PROTO_INUSE(NAME)
-# define REF_PROTO_INUSE(NAME)
-#endif
-
 extern int proto_register(struct proto *prot, int alloc_slab);
 extern void proto_unregister(struct proto *prot);
 
@@ -660,33 +614,42 @@ static inline void sk_refcnt_debug_release(const struct sock *sk)
 #define sk_refcnt_debug_release(sk) do { } while (0)
 #endif /* SOCK_REFCNT_DEBUG */
 
+
+#ifdef CONFIG_PROC_FS
+# define DEFINE_PROTO_INUSE(NAME) DEFINE_PCOUNTER(NAME)
+# define REF_PROTO_INUSE(NAME) PCOUNTER_MEMBER_INITIALIZER(NAME, .inuse)
 /* Called with local bh disabled */
-static __inline__ void sock_prot_inc_use(struct proto *prot)
+static inline void sock_prot_inuse_add(struct proto *prot, int inc)
 {
-#ifdef CONFIG_SMP
-       prot->inuse_add(prot, 1);
-#else
-       prot->inuse++;
-#endif
+       pcounter_add(&prot->inuse, inc);
 }
-
-static __inline__ void sock_prot_dec_use(struct proto *prot)
+static inline int sock_prot_inuse_init(struct proto *proto)
 {
-#ifdef CONFIG_SMP
-       prot->inuse_add(prot, -1);
-#else
-       prot->inuse--;
-#endif
+       return pcounter_alloc(&proto->inuse);
 }
-
-static __inline__ int sock_prot_inuse(struct proto *proto)
+static inline int sock_prot_inuse_get(struct proto *proto)
 {
-#ifdef CONFIG_SMP
-       return proto->inuse_getval(proto);
+       return pcounter_getval(&proto->inuse);
+}
+static inline void sock_prot_inuse_free(struct proto *proto)
+{
+       pcounter_free(&proto->inuse);
+}
 #else
-       return proto->inuse;
-#endif
+# define DEFINE_PROTO_INUSE(NAME)
+# define REF_PROTO_INUSE(NAME)
+static void inline sock_prot_inuse_add(struct proto *prot, int inc)
+{
+}
+static int inline sock_prot_inuse_init(struct proto *proto)
+{
+       return 0;
 }
+static void inline sock_prot_inuse_free(struct proto *proto)
+{
+}
+#endif
+
 
 /* With per-bucket locks this operation is not-atomic, so that
  * this version is not worse.
@@ -750,32 +713,81 @@ static inline struct inode *SOCK_INODE(struct socket *socket)
        return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
 }
 
-extern void __sk_stream_mem_reclaim(struct sock *sk);
-extern int sk_stream_mem_schedule(struct sock *sk, int size, int kind);
+/*
+ * Functions for memory accounting
+ */
+extern int __sk_mem_schedule(struct sock *sk, int size, int kind);
+extern void __sk_mem_reclaim(struct sock *sk);
 
-#define SK_STREAM_MEM_QUANTUM ((int)PAGE_SIZE)
+#define SK_MEM_QUANTUM ((int)PAGE_SIZE)
+#define SK_MEM_QUANTUM_SHIFT ilog2(SK_MEM_QUANTUM)
+#define SK_MEM_SEND    0
+#define SK_MEM_RECV    1
 
-static inline int sk_stream_pages(int amt)
+static inline int sk_mem_pages(int amt)
 {
-       return DIV_ROUND_UP(amt, SK_STREAM_MEM_QUANTUM);
+       return (amt + SK_MEM_QUANTUM - 1) >> SK_MEM_QUANTUM_SHIFT;
 }
 
-static inline void sk_stream_mem_reclaim(struct sock *sk)
+static inline int sk_has_account(struct sock *sk)
 {
-       if (sk->sk_forward_alloc >= SK_STREAM_MEM_QUANTUM)
-               __sk_stream_mem_reclaim(sk);
+       /* return true if protocol supports memory accounting */
+       return !!sk->sk_prot->memory_allocated;
 }
 
-static inline int sk_stream_rmem_schedule(struct sock *sk, struct sk_buff *skb)
+static inline int sk_wmem_schedule(struct sock *sk, int size)
 {
-       return (int)skb->truesize <= sk->sk_forward_alloc ||
-               sk_stream_mem_schedule(sk, skb->truesize, 1);
+       if (!sk_has_account(sk))
+               return 1;
+       return size <= sk->sk_forward_alloc ||
+               __sk_mem_schedule(sk, size, SK_MEM_SEND);
 }
 
-static inline int sk_stream_wmem_schedule(struct sock *sk, int size)
+static inline int sk_rmem_schedule(struct sock *sk, int size)
 {
+       if (!sk_has_account(sk))
+               return 1;
        return size <= sk->sk_forward_alloc ||
-              sk_stream_mem_schedule(sk, size, 0);
+               __sk_mem_schedule(sk, size, SK_MEM_RECV);
+}
+
+static inline void sk_mem_reclaim(struct sock *sk)
+{
+       if (!sk_has_account(sk))
+               return;
+       if (sk->sk_forward_alloc >= SK_MEM_QUANTUM)
+               __sk_mem_reclaim(sk);
+}
+
+static inline void sk_mem_reclaim_partial(struct sock *sk)
+{
+       if (!sk_has_account(sk))
+               return;
+       if (sk->sk_forward_alloc > SK_MEM_QUANTUM)
+               __sk_mem_reclaim(sk);
+}
+
+static inline void sk_mem_charge(struct sock *sk, int size)
+{
+       if (!sk_has_account(sk))
+               return;
+       sk->sk_forward_alloc -= size;
+}
+
+static inline void sk_mem_uncharge(struct sock *sk, int size)
+{
+       if (!sk_has_account(sk))
+               return;
+       sk->sk_forward_alloc += size;
+}
+
+static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb)
+{
+       skb_truesize_check(skb);
+       sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
+       sk->sk_wmem_queued -= skb->truesize;
+       sk_mem_uncharge(sk, skb->truesize);
+       __kfree_skb(skb);
 }
 
 /* Used by processes to "lock" a socket state, so that
@@ -812,14 +824,14 @@ do {                                                                      \
        lockdep_init_map(&(sk)->sk_lock.dep_map, (name), (key), 0);     \
 } while (0)
 
-extern void FASTCALL(lock_sock_nested(struct sock *sk, int subclass));
+extern void lock_sock_nested(struct sock *sk, int subclass);
 
 static inline void lock_sock(struct sock *sk)
 {
        lock_sock_nested(sk, 0);
 }
 
-extern void FASTCALL(release_sock(struct sock *sk));
+extern void release_sock(struct sock *sk);
 
 /* BH context may only use the following locking interface. */
 #define bh_lock_sock(__sk)     spin_lock(&((__sk)->sk_lock.slock))
@@ -1113,12 +1125,6 @@ static inline int sk_can_gso(const struct sock *sk)
 
 extern void sk_setup_caps(struct sock *sk, struct dst_entry *dst);
 
-static inline void sk_charge_skb(struct sock *sk, struct sk_buff *skb)
-{
-       sk->sk_wmem_queued   += skb->truesize;
-       sk->sk_forward_alloc -= skb->truesize;
-}
-
 static inline int skb_copy_to_page(struct sock *sk, char __user *from,
                                   struct sk_buff *skb, struct page *page,
                                   int off, int copy)
@@ -1138,7 +1144,7 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from,
        skb->data_len        += copy;
        skb->truesize        += copy;
        sk->sk_wmem_queued   += copy;
-       sk->sk_forward_alloc -= copy;
+       sk_mem_charge(sk, copy);
        return 0;
 }
 
@@ -1164,6 +1170,7 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
        skb->sk = sk;
        skb->destructor = sock_rfree;
        atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+       sk_mem_charge(sk, skb->truesize);
 }
 
 extern void sk_reset_timer(struct sock *sk, struct timer_list* timer,
@@ -1225,45 +1232,12 @@ static inline void sk_wake_async(struct sock *sk, int how, int band)
 static inline void sk_stream_moderate_sndbuf(struct sock *sk)
 {
        if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) {
-               sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued / 2);
+               sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1);
                sk->sk_sndbuf = max(sk->sk_sndbuf, SOCK_MIN_SNDBUF);
        }
 }
 
-static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk,
-                                                  int size, int mem,
-                                                  gfp_t gfp)
-{
-       struct sk_buff *skb;
-
-       /* The TCP header must be at least 32-bit aligned.  */
-       size = ALIGN(size, 4);
-
-       skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
-       if (skb) {
-               skb->truesize += mem;
-               if (sk_stream_wmem_schedule(sk, skb->truesize)) {
-                       /*
-                        * Make sure that we have exactly size bytes
-                        * available to the caller, no more, no less.
-                        */
-                       skb_reserve(skb, skb_tailroom(skb) - size);
-                       return skb;
-               }
-               __kfree_skb(skb);
-       } else {
-               sk->sk_prot->enter_memory_pressure();
-               sk_stream_moderate_sndbuf(sk);
-       }
-       return NULL;
-}
-
-static inline struct sk_buff *sk_stream_alloc_skb(struct sock *sk,
-                                                 int size,
-                                                 gfp_t gfp)
-{
-       return sk_stream_alloc_pskb(sk, size, 0, gfp);
-}
+struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp);
 
 static inline struct page *sk_stream_alloc_page(struct sock *sk)
 {
@@ -1282,7 +1256,7 @@ static inline struct page *sk_stream_alloc_page(struct sock *sk)
  */
 static inline int sock_writeable(const struct sock *sk) 
 {
-       return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf / 2);
+       return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1);
 }
 
 static inline gfp_t gfp_any(void)
@@ -1391,23 +1365,11 @@ extern int net_msg_warn;
                                lock_sock(sk); \
                                }
 
-static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
-{
-       if (valbool)
-               sock_set_flag(sk, bit);
-       else
-               sock_reset_flag(sk, bit);
-}
-
 extern __u32 sysctl_wmem_max;
 extern __u32 sysctl_rmem_max;
 
 extern void sk_init(void);
 
-#ifdef CONFIG_SYSCTL
-extern struct ctl_table core_table[];
-#endif
-
 extern int sysctl_optmem_max;
 
 extern __u32 sysctl_wmem_default;
index cb5b033e0e59c205980243d2b7e494db0925f218..7de4ea3a04d928b12a3c93a36bfe0f9a9c6ed960 100644 (file)
@@ -309,6 +309,9 @@ extern int                  tcp_twsk_unique(struct sock *sk,
 
 extern void                    tcp_twsk_destructor(struct sock *sk);
 
+extern ssize_t                 tcp_splice_read(struct socket *sk, loff_t *ppos,
+                                               struct pipe_inode_info *pipe, size_t len, unsigned int flags);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
                                         const unsigned int pkts)
 {
@@ -575,10 +578,6 @@ struct tcp_skb_cb {
 #define TCPCB_EVER_RETRANS     0x80    /* Ever retransmitted frame     */
 #define TCPCB_RETRANS          (TCPCB_SACKED_RETRANS|TCPCB_EVER_RETRANS)
 
-#define TCPCB_URG              0x20    /* Urgent pointer advanced here */
-
-#define TCPCB_AT_TAIL          (TCPCB_URG)
-
        __u16           urg_ptr;        /* Valid w/URG flags is set.    */
        __u32           ack_seq;        /* Sequence number ACK'd        */
 };
@@ -649,7 +648,7 @@ struct tcp_congestion_ops {
        /* lower bound for congestion window (optional) */
        u32 (*min_cwnd)(const struct sock *sk);
        /* do new cwnd calculation (required) */
-       void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight, int good_ack);
+       void (*cong_avoid)(struct sock *sk, u32 ack, u32 in_flight);
        /* call before changing ca_state (optional) */
        void (*set_state)(struct sock *sk, u8 new_state);
        /* call when cwnd event occurs (optional) */
@@ -680,7 +679,7 @@ extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
-extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int flag);
+extern void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight);
 extern u32 tcp_reno_min_cwnd(const struct sock *sk);
 extern struct tcp_congestion_ops tcp_reno;
 
@@ -782,26 +781,12 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp)
        return 3;
 }
 
-/* RFC2861 Check whether we are limited by application or congestion window
- * This is the inverse of cwnd check in tcp_tso_should_defer
- */
-static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
+/* Returns end sequence number of the receiver's advertised window */
+static inline u32 tcp_wnd_end(const struct tcp_sock *tp)
 {
-       const struct tcp_sock *tp = tcp_sk(sk);
-       u32 left;
-
-       if (in_flight >= tp->snd_cwnd)
-               return 1;
-
-       if (!sk_can_gso(sk))
-               return 0;
-
-       left = tp->snd_cwnd - in_flight;
-       if (sysctl_tcp_tso_win_divisor)
-               return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
-       else
-               return left <= tcp_max_burst(tp);
+       return tp->snd_una + tp->snd_wnd;
 }
+extern int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight);
 
 static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss,
                                       const struct sk_buff *skb)
@@ -921,40 +906,7 @@ static const char *statename[]={
        "Close Wait","Last ACK","Listen","Closing"
 };
 #endif
-
-static inline void tcp_set_state(struct sock *sk, int state)
-{
-       int oldstate = sk->sk_state;
-
-       switch (state) {
-       case TCP_ESTABLISHED:
-               if (oldstate != TCP_ESTABLISHED)
-                       TCP_INC_STATS(TCP_MIB_CURRESTAB);
-               break;
-
-       case TCP_CLOSE:
-               if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
-                       TCP_INC_STATS(TCP_MIB_ESTABRESETS);
-
-               sk->sk_prot->unhash(sk);
-               if (inet_csk(sk)->icsk_bind_hash &&
-                   !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
-                       inet_put_port(&tcp_hashinfo, sk);
-               /* fall through */
-       default:
-               if (oldstate==TCP_ESTABLISHED)
-                       TCP_DEC_STATS(TCP_MIB_CURRESTAB);
-       }
-
-       /* Change state AFTER socket is unhashed to avoid closed
-        * socket sitting in hash tables.
-        */
-       sk->sk_state = state;
-
-#ifdef STATE_TRACE
-       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
-#endif 
-}
+extern void tcp_set_state(struct sock *sk, int state);
 
 extern void tcp_done(struct sock *sk);
 
@@ -1078,7 +1030,6 @@ static inline void tcp_clear_retrans_hints_partial(struct tcp_sock *tp)
 static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
 {
        tcp_clear_retrans_hints_partial(tp);
-       tp->fastpath_skb_hint = NULL;
 }
 
 /* MD5 Signature */
@@ -1153,7 +1104,8 @@ extern int                        tcp_v4_calc_md5_hash(char *md5_hash,
                                                     struct dst_entry *dst,
                                                     struct request_sock *req,
                                                     struct tcphdr *th,
-                                                    int protocol, int tcplen);
+                                                    int protocol,
+                                                    unsigned int tcplen);
 extern struct tcp_md5sig_key   *tcp_v4_md5_lookup(struct sock *sk,
                                                   struct sock *addr_sk);
 
@@ -1193,8 +1145,8 @@ static inline void tcp_write_queue_purge(struct sock *sk)
        struct sk_buff *skb;
 
        while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
-               sk_stream_free_skb(sk, skb);
-       sk_stream_mem_reclaim(sk);
+               sk_wmem_free_skb(sk, skb);
+       sk_mem_reclaim(sk);
 }
 
 static inline struct sk_buff *tcp_write_queue_head(struct sock *sk)
@@ -1227,6 +1179,11 @@ static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_bu
                for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
                     skb = skb->next)
 
+#define tcp_for_write_queue_from_safe(skb, tmp, sk)                    \
+               for (tmp = skb->next;                                   \
+                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
+                    skb = tmp, tmp = skb->next)
+
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
        return sk->sk_send_head;
@@ -1234,14 +1191,9 @@ static inline struct sk_buff *tcp_send_head(struct sock *sk)
 
 static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
-
        sk->sk_send_head = skb->next;
        if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
                sk->sk_send_head = NULL;
-       /* Don't override Nagle indefinately with F-RTO */
-       if (tp->frto_counter == 2)
-               tp->frto_counter = 3;
 }
 
 static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
@@ -1265,8 +1217,12 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
        __tcp_add_write_queue_tail(sk, skb);
 
        /* Queue it, remembering where we must start sending. */
-       if (sk->sk_send_head == NULL)
+       if (sk->sk_send_head == NULL) {
                sk->sk_send_head = skb;
+
+               if (tcp_sk(sk)->highest_sack == NULL)
+                       tcp_sk(sk)->highest_sack = skb;
+       }
 }
 
 static inline void __tcp_add_write_queue_head(struct sock *sk, struct sk_buff *skb)
@@ -1309,6 +1265,45 @@ static inline int tcp_write_queue_empty(struct sock *sk)
        return skb_queue_empty(&sk->sk_write_queue);
 }
 
+/* Start sequence of the highest skb with SACKed bit, valid only if
+ * sacked > 0 or when the caller has ensured validity by itself.
+ */
+static inline u32 tcp_highest_sack_seq(struct tcp_sock *tp)
+{
+       if (!tp->sacked_out)
+               return tp->snd_una;
+
+       if (tp->highest_sack == NULL)
+               return tp->snd_nxt;
+
+       return TCP_SKB_CB(tp->highest_sack)->seq;
+}
+
+static inline void tcp_advance_highest_sack(struct sock *sk, struct sk_buff *skb)
+{
+       tcp_sk(sk)->highest_sack = tcp_skb_is_last(sk, skb) ? NULL :
+                                               tcp_write_queue_next(sk, skb);
+}
+
+static inline struct sk_buff *tcp_highest_sack(struct sock *sk)
+{
+       return tcp_sk(sk)->highest_sack;
+}
+
+static inline void tcp_highest_sack_reset(struct sock *sk)
+{
+       tcp_sk(sk)->highest_sack = tcp_write_queue_head(sk);
+}
+
+/* Called when old skb is about to be deleted (to be combined with new skb) */
+static inline void tcp_highest_sack_combine(struct sock *sk,
+                                           struct sk_buff *old,
+                                           struct sk_buff *new)
+{
+       if (tcp_sk(sk)->sacked_out && (old == tcp_sk(sk)->highest_sack))
+               tcp_sk(sk)->highest_sack = new;
+}
+
 /* /proc */
 enum tcp_seq_states {
        TCP_SEQ_STATE_LISTENING,
@@ -1359,7 +1354,8 @@ struct tcp_sock_af_ops {
                                                  struct dst_entry *dst,
                                                  struct request_sock *req,
                                                  struct tcphdr *th,
-                                                 int protocol, int len);
+                                                 int protocol,
+                                                 unsigned int len);
        int                     (*md5_add) (struct sock *sk,
                                            struct sock *addr_sk,
                                            u8 *newkey,
index 409da3a9a455c634bb670db6840ae68ff758d2f7..27394e0447d88d9b5d788b14b8e4bed582b45817 100644 (file)
@@ -17,16 +17,20 @@ extern struct proto tcpv6_prot;
 struct flowi;
 
 /* extention headers */
-extern void                            ipv6_rthdr_init(void);
-extern void                            ipv6_frag_init(void);
-extern void                            ipv6_nodata_init(void);
-extern void                            ipv6_destopt_init(void);
+extern int                             ipv6_exthdrs_init(void);
+extern void                            ipv6_exthdrs_exit(void);
+extern int                             ipv6_frag_init(void);
+extern void                            ipv6_frag_exit(void);
 
 /* transport protocols */
-extern void                            rawv6_init(void);
-extern void                            udpv6_init(void);
-extern void                            udplitev6_init(void);
-extern void                            tcpv6_init(void);
+extern int                             rawv6_init(void);
+extern void                            rawv6_exit(void);
+extern int                             udpv6_init(void);
+extern void                            udpv6_exit(void);
+extern int                             udplitev6_init(void);
+extern void                            udplitev6_exit(void);
+extern int                             tcpv6_init(void);
+extern void                            tcpv6_exit(void);
 
 extern int                             udpv6_connect(struct sock *sk,
                                                      struct sockaddr *uaddr,
index 98755ebaf163cfe788b4117167cfeaf1a861f269..c6669c0a74c7e5468d10ca7cbdac7966a1ff05c3 100644 (file)
@@ -65,6 +65,13 @@ extern rwlock_t udp_hash_lock;
 
 extern struct proto udp_prot;
 
+extern atomic_t udp_memory_allocated;
+
+/* sysctl variables for udp */
+extern int sysctl_udp_mem[3];
+extern int sysctl_udp_rmem_min;
+extern int sysctl_udp_wmem_min;
+
 struct sk_buff;
 
 /*
@@ -108,7 +115,7 @@ static inline void udp_lib_unhash(struct sock *sk)
        write_lock_bh(&udp_hash_lock);
        if (sk_del_node_init(sk)) {
                inet_sk(sk)->num = 0;
-               sock_prot_dec_use(sk->sk_prot);
+               sock_prot_inuse_add(sk->sk_prot, -1);
        }
        write_unlock_bh(&udp_hash_lock);
 }
@@ -139,6 +146,12 @@ extern int         udp_lib_setsockopt(struct sock *sk, int level, int optname,
                                   int (*push_pending_frames)(struct sock *));
 
 DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
+DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
+
+/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
+DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
+DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
+
 /*
  *     SNMP statistics for UDP and UDP-Lite
  */
@@ -149,6 +162,25 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
        if (is_udplite) SNMP_INC_STATS_BH(udplite_statistics, field);         \
        else            SNMP_INC_STATS_BH(udp_statistics, field);    }  while(0)
 
+#define UDP6_INC_STATS_BH(field, is_udplite)                         do  {  \
+       if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field);         \
+       else            SNMP_INC_STATS_BH(udp_stats_in6, field);    } while(0)
+#define UDP6_INC_STATS_USER(field, is_udplite)                        do {    \
+       if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field);         \
+       else            SNMP_INC_STATS_USER(udp_stats_in6, field);    } while(0)
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#define UDPX_INC_STATS_BH(sk, field) \
+       do { \
+               if ((sk)->sk_family == AF_INET) \
+                       UDP_INC_STATS_BH(field, 0); \
+               else \
+                       UDP6_INC_STATS_BH(field, 0); \
+       } while (0);
+#else
+#define UDPX_INC_STATS_BH(sk, field) UDP_INC_STATS_BH(field, 0)
+#endif
+
 /* /proc */
 struct udp_seq_afinfo {
        struct module           *owner;
@@ -173,4 +205,6 @@ extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo);
 extern int  udp4_proc_init(void);
 extern void udp4_proc_exit(void);
 #endif
+
+extern void udp_init(void);
 #endif /* _UDP_H */
index 635b0eafca95d256e789edb0323cbb8aef759f4f..b76b2e377af4540bc8336328f55485d87a26947b 100644 (file)
@@ -13,9 +13,6 @@
 extern struct proto            udplite_prot;
 extern struct hlist_head       udplite_hash[UDP_HTABLE_SIZE];
 
-/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
-DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics);
-
 /*
  *     Checksum computation is all in software, hence simpler getfrag.
  */
index 1dd20cf17982663b8881f55c76440d7dd096d98d..5ebb9ba479b107edfb11c582390c478100bee7f3 100644 (file)
@@ -19,6 +19,9 @@
 #include <net/route.h>
 #include <net/ipv6.h>
 #include <net/ip6_fib.h>
+#ifdef CONFIG_XFRM_STATISTICS
+#include <net/snmp.h>
+#endif
 
 #define XFRM_PROTO_ESP         50
 #define XFRM_PROTO_AH          51
 #define MODULE_ALIAS_XFRM_TYPE(family, proto) \
        MODULE_ALIAS("xfrm-type-" __stringify(family) "-" __stringify(proto))
 
+#ifdef CONFIG_XFRM_STATISTICS
+DECLARE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
+#define XFRM_INC_STATS(field)          SNMP_INC_STATS(xfrm_statistics, field)
+#define XFRM_INC_STATS_BH(field)       SNMP_INC_STATS_BH(xfrm_statistics, field)
+#define XFRM_INC_STATS_USER(field)     SNMP_INC_STATS_USER(xfrm_statistics, field)
+#else
+#define XFRM_INC_STATS(field)
+#define XFRM_INC_STATS_BH(field)
+#define XFRM_INC_STATS_USER(field)
+#endif
+
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
@@ -183,7 +197,7 @@ struct xfrm_state
        struct timer_list       timer;
 
        /* Last used time */
-       u64                     lastused;
+       unsigned long           lastused;
 
        /* Reference to data common to all the instances of this
         * transformer. */
@@ -227,22 +241,26 @@ struct km_event
        u32     event;
 };
 
+struct net_device;
 struct xfrm_type;
 struct xfrm_dst;
 struct xfrm_policy_afinfo {
        unsigned short          family;
        struct dst_ops          *dst_ops;
        void                    (*garbage_collect)(void);
-       int                     (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
+       struct dst_entry        *(*dst_lookup)(int tos, xfrm_address_t *saddr,
+                                              xfrm_address_t *daddr);
        int                     (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
        struct dst_entry        *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
-       int                     (*bundle_create)(struct xfrm_policy *policy, 
-                                                struct xfrm_state **xfrm, 
-                                                int nx,
-                                                struct flowi *fl, 
-                                                struct dst_entry **dst_p);
        void                    (*decode_session)(struct sk_buff *skb,
-                                                 struct flowi *fl);
+                                                 struct flowi *fl,
+                                                 int reverse);
+       int                     (*get_tos)(struct flowi *fl);
+       int                     (*init_path)(struct xfrm_dst *path,
+                                            struct dst_entry *dst,
+                                            int nfheader_len);
+       int                     (*fill_dst)(struct xfrm_dst *xdst,
+                                           struct net_device *dev);
 };
 
 extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
@@ -257,6 +275,8 @@ extern int __xfrm_state_delete(struct xfrm_state *x);
 
 struct xfrm_state_afinfo {
        unsigned int            family;
+       unsigned int            proto;
+       unsigned int            eth_proto;
        struct module           *owner;
        struct xfrm_type        *type_map[IPPROTO_MAX];
        struct xfrm_mode        *mode_map[XFRM_MODE_MAX];
@@ -267,6 +287,12 @@ struct xfrm_state_afinfo {
        int                     (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
        int                     (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
        int                     (*output)(struct sk_buff *skb);
+       int                     (*extract_input)(struct xfrm_state *x,
+                                                struct sk_buff *skb);
+       int                     (*extract_output)(struct xfrm_state *x,
+                                                 struct sk_buff *skb);
+       int                     (*transport_finish)(struct sk_buff *skb,
+                                                   int async);
 };
 
 extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
@@ -282,6 +308,8 @@ struct xfrm_type
        __u8                    flags;
 #define XFRM_TYPE_NON_FRAGMENT 1
 #define XFRM_TYPE_REPLAY_PROT  2
+#define XFRM_TYPE_LOCAL_COADDR 4
+#define XFRM_TYPE_REMOTE_COADDR        8
 
        int                     (*init_state)(struct xfrm_state *x);
        void                    (*destructor)(struct xfrm_state *);
@@ -289,8 +317,6 @@ struct xfrm_type
        int                     (*output)(struct xfrm_state *, struct sk_buff *pskb);
        int                     (*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
        int                     (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
-       xfrm_address_t          *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
-       xfrm_address_t          *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
        /* Estimate maximal size of result of transformation of a dgram */
        u32                     (*get_mtu)(struct xfrm_state *, int size);
 };
@@ -299,6 +325,27 @@ extern int xfrm_register_type(struct xfrm_type *type, unsigned short family);
 extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family);
 
 struct xfrm_mode {
+       /*
+        * Remove encapsulation header.
+        *
+        * The IP header will be moved over the top of the encapsulation
+        * header.
+        *
+        * On entry, the transport header shall point to where the IP header
+        * should be and the network header shall be set to where the IP
+        * header currently is.  skb->data shall point to the start of the
+        * payload.
+        */
+       int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
+
+       /*
+        * This is the actual input entry point.
+        *
+        * For transport mode and equivalent this would be identical to
+        * input2 (which does not need to be set).  While tunnel mode
+        * and equivalent would set this to the tunnel encapsulation function
+        * xfrm4_prepare_input that would in turn call input2.
+        */
        int (*input)(struct xfrm_state *x, struct sk_buff *skb);
 
        /*
@@ -312,7 +359,18 @@ struct xfrm_mode {
         * header.  The value of the network header will always point
         * to the top IP header while skb->data will point to the payload.
         */
-       int (*output)(struct xfrm_state *x,struct sk_buff *skb);
+       int (*output2)(struct xfrm_state *x,struct sk_buff *skb);
+
+       /*
+        * This is the actual output entry point.
+        *
+        * For transport mode and equivalent this would be identical to
+        * output2 (which does not need to be set).  While tunnel mode
+        * and equivalent would set this to a tunnel encapsulation function
+        * (xfrm4_prepare_output or xfrm6_prepare_output) that would in turn
+        * call output2.
+        */
+       int (*output)(struct xfrm_state *x, struct sk_buff *skb);
 
        struct xfrm_state_afinfo *afinfo;
        struct module *owner;
@@ -454,6 +512,51 @@ struct xfrm_skb_cb {
 
 #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
 
+/*
+ * This structure is used by the afinfo prepare_input/prepare_output functions
+ * to transmit header information to the mode input/output functions.
+ */
+struct xfrm_mode_skb_cb {
+       union {
+               struct inet_skb_parm h4;
+               struct inet6_skb_parm h6;
+       } header;
+
+       /* Copied from header for IPv4, always set to zero and DF for IPv6. */
+       __be16 id;
+       __be16 frag_off;
+
+       /* TOS for IPv4, class for IPv6. */
+       u8 tos;
+
+       /* TTL for IPv4, hop limitfor IPv6. */
+       u8 ttl;
+
+       /* Protocol for IPv4, NH for IPv6. */
+       u8 protocol;
+
+       /* Used by IPv6 only, zero for IPv4. */
+       u8 flow_lbl[3];
+};
+
+#define XFRM_MODE_SKB_CB(__skb) ((struct xfrm_mode_skb_cb *)&((__skb)->cb[0]))
+
+/*
+ * This structure is used by the input processing to locate the SPI and
+ * related information.
+ */
+struct xfrm_spi_skb_cb {
+       union {
+               struct inet_skb_parm h4;
+               struct inet6_skb_parm h6;
+       } header;
+
+       unsigned int daddroff;
+       unsigned int family;
+};
+
+#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
+
 /* Audit Information */
 struct xfrm_audit
 {
@@ -462,41 +565,59 @@ struct xfrm_audit
 };
 
 #ifdef CONFIG_AUDITSYSCALL
-static inline struct audit_buffer *xfrm_audit_start(u32 auid, u32 sid)
+static inline struct audit_buffer *xfrm_audit_start(const char *op)
 {
        struct audit_buffer *audit_buf = NULL;
-       char *secctx;
-       u32 secctx_len;
 
+       if (audit_enabled == 0)
+               return NULL;
        audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC,
-                             AUDIT_MAC_IPSEC_EVENT);
+                                   AUDIT_MAC_IPSEC_EVENT);
        if (audit_buf == NULL)
                return NULL;
+       audit_log_format(audit_buf, "op=%s", op);
+       return audit_buf;
+}
 
-       audit_log_format(audit_buf, "auid=%u", auid);
+static inline void xfrm_audit_helper_usrinfo(u32 auid, u32 secid,
+                                            struct audit_buffer *audit_buf)
+{
+       char *secctx;
+       u32 secctx_len;
 
-       if (sid != 0 &&
-           security_secid_to_secctx(sid, &secctx, &secctx_len) == 0) {
+       audit_log_format(audit_buf, " auid=%u", auid);
+       if (secid != 0 &&
+           security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
                audit_log_format(audit_buf, " subj=%s", secctx);
                security_release_secctx(secctx, secctx_len);
        } else
                audit_log_task_context(audit_buf);
-       return audit_buf;
 }
 
 extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
-                                 u32 auid, u32 sid);
+                                 u32 auid, u32 secid);
 extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
-                                 u32 auid, u32 sid);
+                                 u32 auid, u32 secid);
 extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
-                                u32 auid, u32 sid);
+                                u32 auid, u32 secid);
 extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
-                                   u32 auid, u32 sid);
+                                   u32 auid, u32 secid);
+extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+                                            struct sk_buff *skb);
+extern void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family);
+extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+                                     __be32 net_spi, __be32 net_seq);
+extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
+                                    struct sk_buff *skb, u8 proto);
 #else
 #define xfrm_audit_policy_add(x, r, a, s)      do { ; } while (0)
 #define xfrm_audit_policy_delete(x, r, a, s)   do { ; } while (0)
 #define xfrm_audit_state_add(x, r, a, s)       do { ; } while (0)
 #define xfrm_audit_state_delete(x, r, a, s)    do { ; } while (0)
+#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0)
+#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
+#define xfrm_audit_state_notfound(s, f, sp, sq)        do { ; } while (0)
+#define xfrm_audit_state_icvfail(x, s, p)      do { ; } while (0)
 #endif /* CONFIG_AUDITSYSCALL */
 
 static inline void xfrm_pol_hold(struct xfrm_policy *policy)
@@ -505,12 +626,12 @@ static inline void xfrm_pol_hold(struct xfrm_policy *policy)
                atomic_inc(&policy->refcnt);
 }
 
-extern void __xfrm_policy_destroy(struct xfrm_policy *policy);
+extern void xfrm_policy_destroy(struct xfrm_policy *policy);
 
 static inline void xfrm_pol_put(struct xfrm_policy *policy)
 {
        if (atomic_dec_and_test(&policy->refcnt))
-               __xfrm_policy_destroy(policy);
+               xfrm_policy_destroy(policy);
 }
 
 #ifdef CONFIG_XFRM_SUB_POLICY
@@ -757,17 +878,25 @@ xfrm_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x, unsigned short
 }
 
 #ifdef CONFIG_XFRM
-
 extern int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb, unsigned short family);
 
-static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+static inline int __xfrm_policy_check2(struct sock *sk, int dir,
+                                      struct sk_buff *skb,
+                                      unsigned int family, int reverse)
 {
+       int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+
        if (sk && sk->sk_policy[XFRM_POLICY_IN])
-               return __xfrm_policy_check(sk, dir, skb, family);
+               return __xfrm_policy_check(sk, ndir, skb, family);
 
        return  (!xfrm_policy_count[dir] && !skb->sp) ||
                (skb->dst->flags & DST_NOPOLICY) ||
-               __xfrm_policy_check(sk, dir, skb, family);
+               __xfrm_policy_check(sk, ndir, skb, family);
+}
+
+static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, unsigned short family)
+{
+       return __xfrm_policy_check2(sk, dir, skb, family, 0);
 }
 
 static inline int xfrm4_policy_check(struct sock *sk, int dir, struct sk_buff *skb)
@@ -780,7 +909,34 @@ static inline int xfrm6_policy_check(struct sock *sk, int dir, struct sk_buff *s
        return xfrm_policy_check(sk, dir, skb, AF_INET6);
 }
 
-extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+                                            struct sk_buff *skb)
+{
+       return __xfrm_policy_check2(sk, dir, skb, AF_INET, 1);
+}
+
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+                                            struct sk_buff *skb)
+{
+       return __xfrm_policy_check2(sk, dir, skb, AF_INET6, 1);
+}
+
+extern int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+                                unsigned int family, int reverse);
+
+static inline int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+                                     unsigned int family)
+{
+       return __xfrm_decode_session(skb, fl, family, 0);
+}
+
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+                                             struct flowi *fl,
+                                             unsigned int family)
+{
+       return __xfrm_decode_session(skb, fl, family, 1);
+}
+
 extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
 static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
@@ -841,6 +997,22 @@ static inline int xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *sk
 {
        return 1;
 }
+static inline int xfrm_decode_session_reverse(struct sk_buff *skb,
+                                             struct flowi *fl,
+                                             unsigned int family)
+{
+       return -ENOSYS;
+}
+static inline int xfrm4_policy_check_reverse(struct sock *sk, int dir,
+                                            struct sk_buff *skb)
+{
+       return 1;
+}
+static inline int xfrm6_policy_check_reverse(struct sock *sk, int dir,
+                                            struct sk_buff *skb)
+{
+       return 1;
+}
 #endif
 
 static __inline__
@@ -981,12 +1153,27 @@ struct xfrm6_tunnel {
 
 extern void xfrm_init(void);
 extern void xfrm4_init(void);
-extern void xfrm6_init(void);
-extern void xfrm6_fini(void);
 extern void xfrm_state_init(void);
 extern void xfrm4_state_init(void);
-extern void xfrm6_state_init(void);
+#ifdef CONFIG_XFRM
+extern int xfrm6_init(void);
+extern void xfrm6_fini(void);
+extern int xfrm6_state_init(void);
 extern void xfrm6_state_fini(void);
+#else
+static inline int xfrm6_init(void)
+{
+       return 0;
+}
+static inline void xfrm6_fini(void)
+{
+       ;
+}
+#endif
+
+#ifdef CONFIG_XFRM_STATISTICS
+extern int xfrm_proc_init(void);
+#endif
 
 extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);
 extern struct xfrm_state *xfrm_state_alloc(void);
@@ -1045,14 +1232,23 @@ extern int xfrm_state_delete(struct xfrm_state *x);
 extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info);
 extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si);
 extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si);
-extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq);
+extern int xfrm_replay_check(struct xfrm_state *x,
+                            struct sk_buff *skb, __be32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, __be32 seq);
 extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
+extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi,
+                     int encap_type);
+extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
+extern int xfrm_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm4_extract_header(struct sk_buff *skb);
+extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
                           int encap_type);
+extern int xfrm4_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm4_rcv(struct sk_buff *skb);
 
 static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
@@ -1060,10 +1256,15 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
        return xfrm4_rcv_encap(skb, nexthdr, spi, 0);
 }
 
+extern int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_output(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family);
+extern int xfrm6_extract_header(struct sk_buff *skb);
+extern int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi);
+extern int xfrm6_transport_finish(struct sk_buff *skb, int async);
 extern int xfrm6_rcv(struct sk_buff *skb);
 extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
                            xfrm_address_t *saddr, u8 proto);
@@ -1072,6 +1273,8 @@ extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short
 extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
 extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);
 extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);
+extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
+extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm6_output(struct sk_buff *skb);
 extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
                                 u8 **prevhdr);
@@ -1079,7 +1282,6 @@ extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
 #ifdef CONFIG_XFRM
 extern int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb);
 extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);
-extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);
 #else
 static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)
 {
@@ -1092,11 +1294,6 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
        kfree_skb(skb);
        return 0;
 }
-
-static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)
-{
-       return -EINVAL;
-} 
 #endif
 
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
@@ -1113,11 +1310,9 @@ extern int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
 struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
                                  xfrm_address_t *daddr, xfrm_address_t *saddr,
                                  int create, unsigned short family);
-extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
 extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
                          struct flowi *fl, int family, int strict);
-extern void xfrm_init_pmtu(struct dst_entry *dst);
 
 #ifdef CONFIG_XFRM_MIGRATE
 extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
@@ -1214,4 +1409,9 @@ static inline void xfrm_states_delete(struct xfrm_state **states, int n)
 }
 #endif
 
+static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
+{
+       return skb->sp->xvec[skb->sp->len - 1];
+}
+
 #endif /* _NET_XFRM_H */
index 8e96558cb8f395394e92676349fefcc887feca50..4bc8e48434a7f9a8879d8ffee7797dc06f8b8107 100644 (file)
@@ -157,8 +157,16 @@ static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *
 #endif
 
 static struct ctl_table root_table[];
-static struct ctl_table_header root_table_header =
-       { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
+static struct ctl_table_root sysctl_table_root;
+static struct ctl_table_header root_table_header = {
+       .ctl_table = root_table,
+       .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list),
+       .root = &sysctl_table_root,
+};
+static struct ctl_table_root sysctl_table_root = {
+       .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
+       .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry),
+};
 
 static struct ctl_table kern_table[];
 static struct ctl_table vm_table[];
@@ -192,14 +200,6 @@ static struct ctl_table root_table[] = {
                .mode           = 0555,
                .child          = vm_table,
        },
-#ifdef CONFIG_NET
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = net_table,
-       },
-#endif
        {
                .ctl_name       = CTL_FS,
                .procname       = "fs",
@@ -1371,12 +1371,27 @@ void sysctl_head_finish(struct ctl_table_header *head)
        spin_unlock(&sysctl_lock);
 }
 
-struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
+static struct list_head *
+lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
 {
+       struct list_head *header_list;
+       header_list = &root->header_list;
+       if (root->lookup)
+               header_list = root->lookup(root, namespaces);
+       return header_list;
+}
+
+struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
+                                           struct ctl_table_header *prev)
+{
+       struct ctl_table_root *root;
+       struct list_head *header_list;
        struct ctl_table_header *head;
        struct list_head *tmp;
+
        spin_lock(&sysctl_lock);
        if (prev) {
+               head = prev;
                tmp = &prev->ctl_entry;
                unuse_table(prev);
                goto next;
@@ -1390,14 +1405,38 @@ struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
                spin_unlock(&sysctl_lock);
                return head;
        next:
+               root = head->root;
                tmp = tmp->next;
-               if (tmp == &root_table_header.ctl_entry)
-                       break;
+               header_list = lookup_header_list(root, namespaces);
+               if (tmp != header_list)
+                       continue;
+
+               do {
+                       root = list_entry(root->root_list.next,
+                                       struct ctl_table_root, root_list);
+                       if (root == &sysctl_table_root)
+                               goto out;
+                       header_list = lookup_header_list(root, namespaces);
+               } while (list_empty(header_list));
+               tmp = header_list->next;
        }
+out:
        spin_unlock(&sysctl_lock);
        return NULL;
 }
 
+struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev)
+{
+       return __sysctl_head_next(current->nsproxy, prev);
+}
+
+void register_sysctl_root(struct ctl_table_root *root)
+{
+       spin_lock(&sysctl_lock);
+       list_add_tail(&root->root_list, &sysctl_table_root.root_list);
+       spin_unlock(&sysctl_lock);
+}
+
 #ifdef CONFIG_SYSCTL_SYSCALL
 int do_sysctl(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp,
               void __user *newval, size_t newlen)
@@ -1554,18 +1593,21 @@ static __init int sysctl_init(void)
 {
        int err;
        sysctl_set_parent(NULL, root_table);
-       err = sysctl_check_table(root_table);
+       err = sysctl_check_table(current->nsproxy, root_table);
        return 0;
 }
 
 core_initcall(sysctl_init);
 
 /**
- * register_sysctl_table - register a sysctl hierarchy
+ * __register_sysctl_paths - register a sysctl hierarchy
+ * @root: List of sysctl headers to register on
+ * @namespaces: Data to compute which lists of sysctl entries are visible
+ * @path: The path to the directory the sysctl table is in.
  * @table: the top-level table structure
  *
  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
- * array. An entry with a ctl_name of 0 terminates the table. 
+ * array. A completely 0 filled entry terminates the table.
  *
  * The members of the &struct ctl_table structure are used as follows:
  *
@@ -1628,25 +1670,99 @@ core_initcall(sysctl_init);
  * This routine returns %NULL on a failure to register, and a pointer
  * to the table header on success.
  */
-struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
+struct ctl_table_header *__register_sysctl_paths(
+       struct ctl_table_root *root,
+       struct nsproxy *namespaces,
+       const struct ctl_path *path, struct ctl_table *table)
 {
-       struct ctl_table_header *tmp;
-       tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL);
-       if (!tmp)
+       struct list_head *header_list;
+       struct ctl_table_header *header;
+       struct ctl_table *new, **prevp;
+       unsigned int n, npath;
+
+       /* Count the path components */
+       for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
+               ;
+
+       /*
+        * For each path component, allocate a 2-element ctl_table array.
+        * The first array element will be filled with the sysctl entry
+        * for this, the second will be the sentinel (ctl_name == 0).
+        *
+        * We allocate everything in one go so that we don't have to
+        * worry about freeing additional memory in unregister_sysctl_table.
+        */
+       header = kzalloc(sizeof(struct ctl_table_header) +
+                        (2 * npath * sizeof(struct ctl_table)), GFP_KERNEL);
+       if (!header)
                return NULL;
-       tmp->ctl_table = table;
-       INIT_LIST_HEAD(&tmp->ctl_entry);
-       tmp->used = 0;
-       tmp->unregistering = NULL;
-       sysctl_set_parent(NULL, table);
-       if (sysctl_check_table(tmp->ctl_table)) {
-               kfree(tmp);
+
+       new = (struct ctl_table *) (header + 1);
+
+       /* Now connect the dots */
+       prevp = &header->ctl_table;
+       for (n = 0; n < npath; ++n, ++path) {
+               /* Copy the procname */
+               new->procname = path->procname;
+               new->ctl_name = path->ctl_name;
+               new->mode     = 0555;
+
+               *prevp = new;
+               prevp = &new->child;
+
+               new += 2;
+       }
+       *prevp = table;
+       header->ctl_table_arg = table;
+
+       INIT_LIST_HEAD(&header->ctl_entry);
+       header->used = 0;
+       header->unregistering = NULL;
+       header->root = root;
+       sysctl_set_parent(NULL, header->ctl_table);
+       if (sysctl_check_table(namespaces, header->ctl_table)) {
+               kfree(header);
                return NULL;
        }
        spin_lock(&sysctl_lock);
-       list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry);
+       header_list = lookup_header_list(root, namespaces);
+       list_add_tail(&header->ctl_entry, header_list);
        spin_unlock(&sysctl_lock);
-       return tmp;
+
+       return header;
+}
+
+/**
+ * register_sysctl_table_path - register a sysctl table hierarchy
+ * @path: The path to the directory the sysctl table is in.
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See __register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                                               struct ctl_table *table)
+{
+       return __register_sysctl_paths(&sysctl_table_root, current->nsproxy,
+                                       path, table);
+}
+
+/**
+ * register_sysctl_table - register a sysctl table hierarchy
+ * @table: the top-level table structure
+ *
+ * Register a sysctl table hierarchy. @table should be a filled in ctl_table
+ * array. A completely 0 filled entry terminates the table.
+ *
+ * See register_sysctl_paths for more details.
+ */
+struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
+{
+       static const struct ctl_path null_path[] = { {} };
+
+       return register_sysctl_paths(null_path, table);
 }
 
 /**
@@ -1675,6 +1791,12 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
        return NULL;
 }
 
+struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
+                                                   struct ctl_table *table)
+{
+       return NULL;
+}
+
 void unregister_sysctl_table(struct ctl_table_header * table)
 {
 }
@@ -2733,6 +2855,7 @@ EXPORT_SYMBOL(proc_dostring);
 EXPORT_SYMBOL(proc_doulongvec_minmax);
 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
 EXPORT_SYMBOL(register_sysctl_table);
+EXPORT_SYMBOL(register_sysctl_paths);
 EXPORT_SYMBOL(sysctl_intvec);
 EXPORT_SYMBOL(sysctl_jiffies);
 EXPORT_SYMBOL(sysctl_ms_jiffies);
index d8a5558a47b4d772e4b00356f8430cc23ab281e7..c3206fa50048b8333be64be54a3a52acf8d39bcb 100644 (file)
@@ -1342,7 +1342,8 @@ static void sysctl_repair_table(struct ctl_table *table)
        }
 }
 
-static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
+static struct ctl_table *sysctl_check_lookup(struct nsproxy *namespaces,
+                                               struct ctl_table *table)
 {
        struct ctl_table_header *head;
        struct ctl_table *ref, *test;
@@ -1350,8 +1351,8 @@ static struct ctl_table *sysctl_check_lookup(struct ctl_table *table)
 
        depth = sysctl_depth(table);
 
-       for (head = sysctl_head_next(NULL); head;
-            head = sysctl_head_next(head)) {
+       for (head = __sysctl_head_next(namespaces, NULL); head;
+            head = __sysctl_head_next(namespaces, head)) {
                cur_depth = depth;
                ref = head->ctl_table;
 repeat:
@@ -1396,13 +1397,14 @@ static void set_fail(const char **fail, struct ctl_table *table, const char *str
        *fail = str;
 }
 
-static int sysctl_check_dir(struct ctl_table *table)
+static int sysctl_check_dir(struct nsproxy *namespaces,
+                               struct ctl_table *table)
 {
        struct ctl_table *ref;
        int error;
 
        error = 0;
-       ref = sysctl_check_lookup(table);
+       ref = sysctl_check_lookup(namespaces, table);
        if (ref) {
                int match = 0;
                if ((!table->procname && !ref->procname) ||
@@ -1427,11 +1429,12 @@ static int sysctl_check_dir(struct ctl_table *table)
        return error;
 }
 
-static void sysctl_check_leaf(struct ctl_table *table, const char **fail)
+static void sysctl_check_leaf(struct nsproxy *namespaces,
+                               struct ctl_table *table, const char **fail)
 {
        struct ctl_table *ref;
 
-       ref = sysctl_check_lookup(table);
+       ref = sysctl_check_lookup(namespaces, table);
        if (ref && (ref != table))
                set_fail(fail, table, "Sysctl already exists");
 }
@@ -1455,7 +1458,7 @@ static void sysctl_check_bin_path(struct ctl_table *table, const char **fail)
        }
 }
 
-int sysctl_check_table(struct ctl_table *table)
+int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table)
 {
        int error = 0;
        for (; table->ctl_name || table->procname; table++) {
@@ -1485,7 +1488,7 @@ int sysctl_check_table(struct ctl_table *table)
                                set_fail(&fail, table, "Directory with extra1");
                        if (table->extra2)
                                set_fail(&fail, table, "Directory with extra2");
-                       if (sysctl_check_dir(table))
+                       if (sysctl_check_dir(namespaces, table))
                                set_fail(&fail, table, "Inconsistent directory names");
                } else {
                        if ((table->strategy == sysctl_data) ||
@@ -1534,7 +1537,7 @@ int sysctl_check_table(struct ctl_table *table)
                        if (!table->procname && table->proc_handler)
                                set_fail(&fail, table, "proc_handler without procname");
 #endif
-                       sysctl_check_leaf(table, &fail);
+                       sysctl_check_leaf(namespaces, table, &fail);
                }
                sysctl_check_bin_path(table, &fail);
                if (fail) {
@@ -1542,7 +1545,7 @@ int sysctl_check_table(struct ctl_table *table)
                        error = -EINVAL;
                }
                if (table->child)
-                       error |= sysctl_check_table(table->child);
+                       error |= sysctl_check_table(namespaces, table->child);
        }
        return error;
 }
index 89841dc9d91c8dd8bc832f7af3040d9ef5f15cfc..543f2502b60a416f2bb97575e2e8f0254c7a9199 100644 (file)
@@ -61,6 +61,7 @@ obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
 obj-$(CONFIG_TEXTSEARCH_BM) += ts_bm.o
 obj-$(CONFIG_TEXTSEARCH_FSM) += ts_fsm.o
 obj-$(CONFIG_SMP) += percpu_counter.o
+obj-$(CONFIG_SMP) += pcounter.o
 obj-$(CONFIG_AUDIT_GENERIC) += audit.o
 
 obj-$(CONFIG_SWIOTLB) += swiotlb.o
diff --git a/lib/pcounter.c b/lib/pcounter.c
new file mode 100644 (file)
index 0000000..9b56807
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Define default pcounter functions
+ * Note that often used pcounters use dedicated functions to get a speed increase.
+ * (see DEFINE_PCOUNTER/REF_PCOUNTER_MEMBER)
+ */
+
+#include <linux/module.h>
+#include <linux/pcounter.h>
+#include <linux/smp.h>
+#include <linux/cpumask.h>
+
+static void pcounter_dyn_add(struct pcounter *self, int inc)
+{
+       per_cpu_ptr(self->per_cpu_values, smp_processor_id())[0] += inc;
+}
+
+static int pcounter_dyn_getval(const struct pcounter *self, int cpu)
+{
+       return per_cpu_ptr(self->per_cpu_values, cpu)[0];
+}
+
+int pcounter_getval(const struct pcounter *self)
+{
+       int res = 0, cpu;
+
+       for_each_possible_cpu(cpu)
+               res += self->getval(self, cpu);
+
+       return res;
+}
+EXPORT_SYMBOL_GPL(pcounter_getval);
+
+int pcounter_alloc(struct pcounter *self)
+{
+       int rc = 0;
+       if (self->add == NULL) {
+               self->per_cpu_values = alloc_percpu(int);
+               if (self->per_cpu_values != NULL) {
+                       self->add    = pcounter_dyn_add;
+                       self->getval = pcounter_dyn_getval;
+               } else
+                       rc = 1;
+       }
+       return rc;
+}
+EXPORT_SYMBOL_GPL(pcounter_alloc);
+
+void pcounter_free(struct pcounter *self)
+{
+       if (self->per_cpu_values != NULL) {
+               free_percpu(self->per_cpu_values);
+               self->per_cpu_values = NULL;
+               self->getval = NULL;
+               self->add = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(pcounter_free);
+
index 977704a54f6879ae3d3fef2123c6e38793c97112..68569ffddea1af326bd503853bc017b235da73ce 100644 (file)
@@ -3,9 +3,8 @@
 #
 
 # Check the p8022 selections against net/core/Makefile.
-obj-$(CONFIG_SYSCTL)   += sysctl_net_802.o
 obj-$(CONFIG_LLC)      += p8022.o psnap.o
-obj-$(CONFIG_TR)       += p8022.o psnap.o tr.o sysctl_net_802.o
+obj-$(CONFIG_TR)       += p8022.o psnap.o tr.o
 obj-$(CONFIG_NET_FC)   +=                 fc.o
 obj-$(CONFIG_FDDI)     +=                 fddi.o
 obj-$(CONFIG_HIPPI)    +=                 hippi.o
diff --git a/net/802/sysctl_net_802.c b/net/802/sysctl_net_802.c
deleted file mode 100644 (file)
index ead5603..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- linux-c -*-
- *             sysctl_net_802.c: sysctl interface to net 802 subsystem.
- *
- *             Begun April 1, 1996, Mike Shaver.
- *             Added /proc/sys/net/802 directory entry (empty =) ). [MS]
- *
- *             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/mm.h>
-#include <linux/if_tr.h>
-#include <linux/sysctl.h>
-
-#ifdef CONFIG_TR
-extern int sysctl_tr_rif_timeout;
-#endif
-
-struct ctl_table tr_table[] = {
-#ifdef CONFIG_TR
-       {
-               .ctl_name       = NET_TR_RIF_TIMEOUT,
-               .procname       = "rif_timeout",
-               .data           = &sysctl_tr_rif_timeout,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
-#endif /* CONFIG_TR */
-       { 0 },
-};
index 1e115e5beab635aeb67baede5c4aa36881545efe..3f16b1720554ffc147ff634b7f1564d871ab10fb 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/init.h>
+#include <linux/sysctl.h>
 #include <net/arp.h>
 #include <net/net_namespace.h>
 
@@ -634,6 +635,26 @@ struct net_device *alloc_trdev(int sizeof_priv)
        return alloc_netdev(sizeof_priv, "tr%d", tr_setup);
 }
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table tr_table[] = {
+       {
+               .ctl_name       = NET_TR_RIF_TIMEOUT,
+               .procname       = "rif_timeout",
+               .data           = &sysctl_tr_rif_timeout,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       { 0 },
+};
+
+static __initdata struct ctl_path tr_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "token-ring", .ctl_name = NET_TR, },
+       { }
+};
+#endif
+
 /*
  *     Called during bootup.  We don't actually have to initialise
  *     too much for this.
@@ -641,12 +662,12 @@ struct net_device *alloc_trdev(int sizeof_priv)
 
 static int __init rif_init(void)
 {
-       init_timer(&rif_timer);
        rif_timer.expires  = jiffies + sysctl_tr_rif_timeout;
-       rif_timer.data     = 0L;
-       rif_timer.function = rif_check_expire;
+       setup_timer(&rif_timer, rif_check_expire, 0);
        add_timer(&rif_timer);
-
+#ifdef CONFIG_SYSCTL
+       register_sysctl_paths(tr_path, tr_table);
+#endif
        proc_net_fops_create(&init_net, "tr_rif", S_IRUGO, &rif_seq_fops);
        return 0;
 }
index 032bf44eca5e4e3cbbf39b825435f1f2cb573960..dbc81b96509666595a7e02265446be3c8076e45b 100644 (file)
@@ -3,7 +3,7 @@
  *             Ethernet-type device handling.
  *
  * Authors:    Ben Greear <greearb@candelatech.com>
- *              Please send support related email to: vlan@scry.wanfear.com
+ *              Please send support related email to: netdev@vger.kernel.org
  *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
  *
  * Fixes:
 
 /* Our listing of VLAN group(s) */
 static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE];
-#define vlan_grp_hashfn(IDX)   ((((IDX) >> VLAN_GRP_HASH_SHIFT) ^ (IDX)) & VLAN_GRP_HASH_MASK)
 
 static char vlan_fullname[] = "802.1Q VLAN Support";
 static char vlan_version[] = DRV_VERSION;
 static char vlan_copyright[] = "Ben Greear <greearb@candelatech.com>";
 static char vlan_buggyright[] = "David S. Miller <davem@redhat.com>";
 
-static int vlan_device_event(struct notifier_block *, unsigned long, void *);
-static int vlan_ioctl_handler(struct net *net, void __user *);
-static int unregister_vlan_dev(struct net_device *, unsigned short );
-
-static struct notifier_block vlan_notifier_block = {
-       .notifier_call = vlan_device_event,
-};
-
-/* These may be changed at run-time through IOCTLs */
-
 /* Determines interface naming scheme. */
 unsigned short vlan_name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
 
@@ -70,82 +59,11 @@ static struct packet_type vlan_packet_type = {
 
 /* End of global variables definitions. */
 
-/*
- * Function vlan_proto_init (pro)
- *
- *    Initialize VLAN protocol layer,
- *
- */
-static int __init vlan_proto_init(void)
+static inline unsigned int vlan_grp_hashfn(unsigned int idx)
 {
-       int err;
-
-       printk(VLAN_INF "%s v%s %s\n",
-              vlan_fullname, vlan_version, vlan_copyright);
-       printk(VLAN_INF "All bugs added by %s\n",
-              vlan_buggyright);
-
-       /* proc file system initialization */
-       err = vlan_proc_init();
-       if (err < 0) {
-               printk(KERN_ERR
-                      "%s %s: can't create entry in proc filesystem!\n",
-                      __FUNCTION__, VLAN_NAME);
-               return err;
-       }
-
-       dev_add_pack(&vlan_packet_type);
-
-       /* Register us to receive netdevice events */
-       err = register_netdevice_notifier(&vlan_notifier_block);
-       if (err < 0)
-               goto err1;
-
-       err = vlan_netlink_init();
-       if (err < 0)
-               goto err2;
-
-       vlan_ioctl_set(vlan_ioctl_handler);
-       return 0;
-
-err2:
-       unregister_netdevice_notifier(&vlan_notifier_block);
-err1:
-       vlan_proc_cleanup();
-       dev_remove_pack(&vlan_packet_type);
-       return err;
+       return ((idx >> VLAN_GRP_HASH_SHIFT) ^ idx) & VLAN_GRP_HASH_MASK;
 }
 
-/*
- *     Module 'remove' entry point.
- *     o delete /proc/net/router directory and static entries.
- */
-static void __exit vlan_cleanup_module(void)
-{
-       int i;
-
-       vlan_ioctl_set(NULL);
-       vlan_netlink_fini();
-
-       /* Un-register us from receiving netdevice events */
-       unregister_netdevice_notifier(&vlan_notifier_block);
-
-       dev_remove_pack(&vlan_packet_type);
-
-       /* This table must be empty if there are no module
-        * references left.
-        */
-       for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) {
-               BUG_ON(!hlist_empty(&vlan_group_hash[i]));
-       }
-       vlan_proc_cleanup();
-
-       synchronize_net();
-}
-
-module_init(vlan_proto_init);
-module_exit(vlan_cleanup_module);
-
 /* Must be invoked with RCU read lock (no preempt) */
 static struct vlan_group *__vlan_find_group(int real_dev_ifindex)
 {
@@ -180,7 +98,7 @@ static void vlan_group_free(struct vlan_group *grp)
 {
        int i;
 
-       for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++)
+       for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++)
                kfree(grp->vlan_devices_arrays[i]);
        kfree(grp);
 }
@@ -218,179 +136,50 @@ static void vlan_rcu_free(struct rcu_head *rcu)
        vlan_group_free(container_of(rcu, struct vlan_group, rcu));
 }
 
-
-/* This returns 0 if everything went fine.
- * It will return 1 if the group was killed as a result.
- * A negative return indicates failure.
- *
- * The RTNL lock must be held.
- */
-static int unregister_vlan_dev(struct net_device *real_dev,
-                              unsigned short vlan_id)
+void unregister_vlan_dev(struct net_device *dev)
 {
-       struct net_device *dev = NULL;
-       int real_dev_ifindex = real_dev->ifindex;
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
+       struct net_device *real_dev = vlan->real_dev;
        struct vlan_group *grp;
-       int i, ret;
-
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: VID: %i\n", __FUNCTION__, vlan_id);
-#endif
-
-       /* sanity check */
-       if (vlan_id >= VLAN_VID_MASK)
-               return -EINVAL;
+       unsigned short vlan_id = vlan->vlan_id;
 
        ASSERT_RTNL();
-       grp = __vlan_find_group(real_dev_ifindex);
-
-       ret = 0;
-
-       if (grp) {
-               dev = vlan_group_get_device(grp, vlan_id);
-               if (dev) {
-                       /* Remove proc entry */
-                       vlan_proc_rem_dev(dev);
 
-                       /* Take it out of our own structures, but be sure to
-                        * interlock with HW accelerating devices or SW vlan
-                        * input packet processing.
-                        */
-                       if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
-                               real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
-
-                       vlan_group_set_device(grp, vlan_id, NULL);
-                       synchronize_net();
+       grp = __vlan_find_group(real_dev->ifindex);
+       BUG_ON(!grp);
 
+       vlan_proc_rem_dev(dev);
 
-                       /* Caller unregisters (and if necessary, puts)
-                        * VLAN device, but we get rid of the reference to
-                        * real_dev here.
-                        */
-                       dev_put(real_dev);
+       /* Take it out of our own structures, but be sure to interlock with
+        * HW accelerating devices or SW vlan input packet processing.
+        */
+       if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
+               real_dev->vlan_rx_kill_vid(real_dev, vlan_id);
 
-                       /* If the group is now empty, kill off the
-                        * group.
-                        */
-                       for (i = 0; i < VLAN_VID_MASK; i++)
-                               if (vlan_group_get_device(grp, i))
-                                       break;
+       vlan_group_set_device(grp, vlan_id, NULL);
+       grp->nr_vlans--;
 
-                       if (i == VLAN_VID_MASK) {
-                               if (real_dev->features & NETIF_F_HW_VLAN_RX)
-                                       real_dev->vlan_rx_register(real_dev, NULL);
+       synchronize_net();
 
-                               hlist_del_rcu(&grp->hlist);
+       /* If the group is now empty, kill off the group. */
+       if (grp->nr_vlans == 0) {
+               if (real_dev->features & NETIF_F_HW_VLAN_RX)
+                       real_dev->vlan_rx_register(real_dev, NULL);
 
-                               /* Free the group, after all cpu's are done. */
-                               call_rcu(&grp->rcu, vlan_rcu_free);
+               hlist_del_rcu(&grp->hlist);
 
-                               grp = NULL;
-                               ret = 1;
-                       }
-               }
+               /* Free the group, after all cpu's are done. */
+               call_rcu(&grp->rcu, vlan_rcu_free);
        }
 
-       return ret;
-}
+       /* Get rid of the vlan's reference to real_dev */
+       dev_put(real_dev);
 
-int unregister_vlan_device(struct net_device *dev)
-{
-       int ret;
-
-       ret = unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev,
-                                 VLAN_DEV_INFO(dev)->vlan_id);
        unregister_netdevice(dev);
-
-       if (ret == 1)
-               ret = 0;
-       return ret;
-}
-
-/*
- * vlan network devices have devices nesting below it, and are a special
- * "super class" of normal network devices; split their locks off into a
- * separate class since they always nest.
- */
-static struct lock_class_key vlan_netdev_xmit_lock_key;
-
-static const struct header_ops vlan_header_ops = {
-       .create  = vlan_dev_hard_header,
-       .rebuild = vlan_dev_rebuild_header,
-       .parse   = eth_header_parse,
-};
-
-static int vlan_dev_init(struct net_device *dev)
-{
-       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
-       int subclass = 0;
-
-       /* IFF_BROADCAST|IFF_MULTICAST; ??? */
-       dev->flags  = real_dev->flags & ~IFF_UP;
-       dev->iflink = real_dev->ifindex;
-       dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
-                                         (1<<__LINK_STATE_DORMANT))) |
-                     (1<<__LINK_STATE_PRESENT);
-
-       /* ipv6 shared card related stuff */
-       dev->dev_id = real_dev->dev_id;
-
-       if (is_zero_ether_addr(dev->dev_addr))
-               memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
-       if (is_zero_ether_addr(dev->broadcast))
-               memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
-
-       if (real_dev->features & NETIF_F_HW_VLAN_TX) {
-               dev->header_ops      = real_dev->header_ops;
-               dev->hard_header_len = real_dev->hard_header_len;
-               dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
-       } else {
-               dev->header_ops      = &vlan_header_ops;
-               dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
-               dev->hard_start_xmit = vlan_dev_hard_start_xmit;
-       }
-
-       if (real_dev->priv_flags & IFF_802_1Q_VLAN)
-               subclass = 1;
-
-       lockdep_set_class_and_subclass(&dev->_xmit_lock,
-                               &vlan_netdev_xmit_lock_key, subclass);
-       return 0;
-}
-
-void vlan_setup(struct net_device *new_dev)
-{
-       ether_setup(new_dev);
-
-       /* new_dev->ifindex = 0;  it will be set when added to
-        * the global list.
-        * iflink is set as well.
-        */
-       new_dev->get_stats = vlan_dev_get_stats;
-
-       /* Make this thing known as a VLAN device */
-       new_dev->priv_flags |= IFF_802_1Q_VLAN;
-
-       /* Set us up to have no queue, as the underlying Hardware device
-        * can do all the queueing we could want.
-        */
-       new_dev->tx_queue_len = 0;
-
-       /* set up method calls */
-       new_dev->change_mtu = vlan_dev_change_mtu;
-       new_dev->init = vlan_dev_init;
-       new_dev->open = vlan_dev_open;
-       new_dev->stop = vlan_dev_stop;
-       new_dev->set_mac_address = vlan_set_mac_address;
-       new_dev->set_multicast_list = vlan_dev_set_multicast_list;
-       new_dev->change_rx_flags = vlan_change_rx_flags;
-       new_dev->destructor = free_netdev;
-       new_dev->do_ioctl = vlan_dev_ioctl;
-
-       memset(new_dev->broadcast, 0, ETH_ALEN);
 }
 
-static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
+static void vlan_transfer_operstate(const struct net_device *dev,
+                                   struct net_device *vlandev)
 {
        /* Have to respect userspace enforced dormant state
         * of real device, also must allow supplicant running
@@ -412,23 +201,22 @@ static void vlan_transfer_operstate(const struct net_device *dev, struct net_dev
 
 int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id)
 {
+       char *name = real_dev->name;
+
        if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
-               printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
-                       __FUNCTION__, real_dev->name);
+               pr_info("8021q: VLANs not supported on %s\n", name);
                return -EOPNOTSUPP;
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
            !real_dev->vlan_rx_register) {
-               printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-                       __FUNCTION__, real_dev->name);
+               pr_info("8021q: device %s has buggy VLAN hw accel\n", name);
                return -EOPNOTSUPP;
        }
 
        if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
            (!real_dev->vlan_rx_add_vid || !real_dev->vlan_rx_kill_vid)) {
-               printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
-                       __FUNCTION__, real_dev->name);
+               pr_info("8021q: Device %s has buggy VLAN hw accel\n", name);
                return -EOPNOTSUPP;
        }
 
@@ -438,18 +226,15 @@ int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id)
        if (!(real_dev->flags & IFF_UP))
                return -ENETDOWN;
 
-       if (__find_vlan_dev(real_dev, vlan_id) != NULL) {
-               /* was already registered. */
-               printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
+       if (__find_vlan_dev(real_dev, vlan_id) != NULL)
                return -EEXIST;
-       }
 
        return 0;
 }
 
 int register_vlan_dev(struct net_device *dev)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct net_device *real_dev = vlan->real_dev;
        unsigned short vlan_id = vlan->vlan_id;
        struct vlan_group *grp, *ngrp = NULL;
@@ -476,14 +261,16 @@ int register_vlan_dev(struct net_device *dev)
         * it into our local structure.
         */
        vlan_group_set_device(grp, vlan_id, dev);
+       grp->nr_vlans++;
+
        if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX)
                real_dev->vlan_rx_register(real_dev, ngrp);
        if (real_dev->features & NETIF_F_HW_VLAN_FILTER)
                real_dev->vlan_rx_add_vid(real_dev, vlan_id);
 
        if (vlan_proc_add_dev(dev) < 0)
-               printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n",
-                      dev->name);
+               pr_warning("8021q: failed to add proc entry for %s\n",
+                          dev->name);
        return 0;
 
 out_free_group:
@@ -502,11 +289,6 @@ static int register_vlan_device(struct net_device *real_dev,
        char name[IFNAMSIZ];
        int err;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: if_name -:%s:-     vid: %i\n",
-               __FUNCTION__, eth_IF_name, VLAN_ID);
-#endif
-
        if (VLAN_ID >= VLAN_VID_MASK)
                return -ERANGE;
 
@@ -515,10 +297,6 @@ static int register_vlan_device(struct net_device *real_dev,
                return err;
 
        /* Gotta set up the fields for the device. */
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "About to allocate name, vlan_name_type: %i\n",
-              vlan_name_type);
-#endif
        switch (vlan_name_type) {
        case VLAN_NAME_TYPE_RAW_PLUS_VID:
                /* name will look like:  eth1.0005 */
@@ -555,26 +333,16 @@ static int register_vlan_device(struct net_device *real_dev,
         */
        new_dev->mtu = real_dev->mtu;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "Allocated new name -:%s:-\n", new_dev->name);
-       VLAN_MEM_DBG("new_dev->priv malloc, addr: %p  size: %i\n",
-                    new_dev->priv,
-                    sizeof(struct vlan_dev_info));
-#endif
-
-       VLAN_DEV_INFO(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
-       VLAN_DEV_INFO(new_dev)->real_dev = real_dev;
-       VLAN_DEV_INFO(new_dev)->dent = NULL;
-       VLAN_DEV_INFO(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
+       vlan_dev_info(new_dev)->vlan_id = VLAN_ID; /* 1 through VLAN_VID_MASK */
+       vlan_dev_info(new_dev)->real_dev = real_dev;
+       vlan_dev_info(new_dev)->dent = NULL;
+       vlan_dev_info(new_dev)->flags = VLAN_FLAG_REORDER_HDR;
 
        new_dev->rtnl_link_ops = &vlan_link_ops;
        err = register_vlan_dev(new_dev);
        if (err < 0)
                goto out_free_newdev;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "Allocated new device successfully, returning.\n");
-#endif
        return 0;
 
 out_free_newdev:
@@ -585,7 +353,7 @@ out_free_newdev:
 static void vlan_sync_address(struct net_device *dev,
                              struct net_device *vlandev)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(vlandev);
+       struct vlan_dev_info *vlan = vlan_dev_info(vlandev);
 
        /* May be called without an actual change */
        if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr))
@@ -606,7 +374,8 @@ static void vlan_sync_address(struct net_device *dev,
        memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
 }
 
-static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
+static int vlan_device_event(struct notifier_block *unused, unsigned long event,
+                            void *ptr)
 {
        struct net_device *dev = ptr;
        struct vlan_group *grp = __vlan_find_group(dev->ifindex);
@@ -683,20 +452,16 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
        case NETDEV_UNREGISTER:
                /* Delete all VLANs for this dev. */
                for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-                       int ret;
-
                        vlandev = vlan_group_get_device(grp, i);
                        if (!vlandev)
                                continue;
 
-                       ret = unregister_vlan_dev(dev,
-                                                 VLAN_DEV_INFO(vlandev)->vlan_id);
+                       /* unregistration of last vlan destroys group, abort
+                        * afterwards */
+                       if (grp->nr_vlans == 1)
+                               i = VLAN_GROUP_ARRAY_LEN;
 
-                       unregister_netdevice(vlandev);
-
-                       /* Group was destroyed? */
-                       if (ret == 1)
-                               break;
+                       unregister_vlan_dev(vlandev);
                }
                break;
        }
@@ -705,6 +470,10 @@ out:
        return NOTIFY_DONE;
 }
 
+static struct notifier_block vlan_notifier_block __read_mostly = {
+       .notifier_call = vlan_device_event,
+};
+
 /*
  *     VLAN IOCTL handler.
  *     o execute requested action or pass command to the device driver
@@ -724,10 +493,6 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
        args.device1[23] = 0;
        args.u.device2[23] = 0;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
-#endif
-
        rtnl_lock();
 
        switch (args.cmd) {
@@ -802,36 +567,16 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
                err = -EPERM;
                if (!capable(CAP_NET_ADMIN))
                        break;
-               err = unregister_vlan_device(dev);
+               unregister_vlan_dev(dev);
+               err = 0;
                break;
 
-       case GET_VLAN_INGRESS_PRIORITY_CMD:
-               /* TODO:  Implement
-                  err = vlan_dev_get_ingress_priority(args);
-                  if (copy_to_user((void*)arg, &args,
-                       sizeof(struct vlan_ioctl_args))) {
-                       err = -EFAULT;
-                  }
-               */
-               err = -EINVAL;
-               break;
-       case GET_VLAN_EGRESS_PRIORITY_CMD:
-               /* TODO:  Implement
-                  err = vlan_dev_get_egress_priority(args.device1, &(args.args);
-                  if (copy_to_user((void*)arg, &args,
-                       sizeof(struct vlan_ioctl_args))) {
-                       err = -EFAULT;
-                  }
-               */
-               err = -EINVAL;
-               break;
        case GET_VLAN_REALDEV_NAME_CMD:
                err = 0;
                vlan_dev_get_realdev_name(dev, args.u.device2);
                if (copy_to_user(arg, &args,
-                                sizeof(struct vlan_ioctl_args))) {
+                                sizeof(struct vlan_ioctl_args)))
                        err = -EFAULT;
-               }
                break;
 
        case GET_VLAN_VID_CMD:
@@ -839,16 +584,12 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg)
                vlan_dev_get_vid(dev, &vid);
                args.u.VID = vid;
                if (copy_to_user(arg, &args,
-                                sizeof(struct vlan_ioctl_args))) {
+                                sizeof(struct vlan_ioctl_args)))
                      err = -EFAULT;
-               }
                break;
 
        default:
-               /* pass on to underlying device instead?? */
-               printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
-                       __FUNCTION__, args.cmd);
-               err = -EINVAL;
+               err = -EOPNOTSUPP;
                break;
        }
 out:
@@ -856,5 +597,59 @@ out:
        return err;
 }
 
+static int __init vlan_proto_init(void)
+{
+       int err;
+
+       pr_info("%s v%s %s\n", vlan_fullname, vlan_version, vlan_copyright);
+       pr_info("All bugs added by %s\n", vlan_buggyright);
+
+       err = vlan_proc_init();
+       if (err < 0)
+               goto err1;
+
+       err = register_netdevice_notifier(&vlan_notifier_block);
+       if (err < 0)
+               goto err2;
+
+       err = vlan_netlink_init();
+       if (err < 0)
+               goto err3;
+
+       dev_add_pack(&vlan_packet_type);
+       vlan_ioctl_set(vlan_ioctl_handler);
+       return 0;
+
+err3:
+       unregister_netdevice_notifier(&vlan_notifier_block);
+err2:
+       vlan_proc_cleanup();
+err1:
+       return err;
+}
+
+static void __exit vlan_cleanup_module(void)
+{
+       unsigned int i;
+
+       vlan_ioctl_set(NULL);
+       vlan_netlink_fini();
+
+       unregister_netdevice_notifier(&vlan_notifier_block);
+
+       dev_remove_pack(&vlan_packet_type);
+
+       /* This table must be empty if there are no module references left. */
+       for (i = 0; i < VLAN_GRP_HASH_SIZE; i++)
+               BUG_ON(!hlist_empty(&vlan_group_hash[i]));
+
+       vlan_proc_cleanup();
+
+       synchronize_net();
+}
+
+module_init(vlan_proto_init);
+module_exit(vlan_cleanup_module);
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
index 2cd1393073ec8e4e845aac4d0f14672dabbf1f37..73efcc715ccb3dba46bb8e975bffadb554fec01d 100644 (file)
@@ -3,31 +3,6 @@
 
 #include <linux/if_vlan.h>
 
-/*  Uncomment this if you want debug traces to be shown. */
-/* #define VLAN_DEBUG */
-
-#define VLAN_ERR KERN_ERR
-#define VLAN_INF KERN_INFO
-#define VLAN_DBG KERN_ALERT /* change these... to debug, having a hard time
-                            * changing the log level at run-time..for some reason.
-                            */
-
-/*
-
-These I use for memory debugging.  I feared a leak at one time, but
-I never found it..and the problem seems to have dissappeared.  Still,
-I'll bet they might prove useful again... --Ben
-
-
-#define VLAN_MEM_DBG(x, y, z) printk(VLAN_DBG "%s:  "  x, __FUNCTION__, y, z);
-#define VLAN_FMEM_DBG(x, y) printk(VLAN_DBG "%s:  " x, __FUNCTION__, y);
-*/
-
-/* This way they don't do anything! */
-#define VLAN_MEM_DBG(x, y, z)
-#define VLAN_FMEM_DBG(x, y)
-
-
 extern unsigned short vlan_name_type;
 
 #define VLAN_GRP_HASH_SHIFT    5
@@ -45,23 +20,12 @@ extern unsigned short vlan_name_type;
  *  Must be invoked with rcu_read_lock (ie preempt disabled)
  *  or with RTNL.
  */
-struct net_device *__find_vlan_dev(struct net_devicereal_dev,
+struct net_device *__find_vlan_dev(struct net_device *real_dev,
                                   unsigned short VID); /* vlan.c */
 
 /* found in vlan_dev.c */
-int vlan_dev_rebuild_header(struct sk_buff *skb);
 int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
                  struct packet_type *ptype, struct net_device *orig_dev);
-int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
-                        unsigned short type, const void *daddr,
-                        const void *saddr, unsigned len);
-int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
-int vlan_dev_change_mtu(struct net_device *dev, int new_mtu);
-int vlan_dev_open(struct net_device* dev);
-int vlan_dev_stop(struct net_device* dev);
-int vlan_set_mac_address(struct net_device *dev, void *p);
-int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd);
 void vlan_dev_set_ingress_priority(const struct net_device *dev,
                                   u32 skb_prio, short vlan_prio);
 int vlan_dev_set_egress_priority(const struct net_device *dev,
@@ -70,13 +34,11 @@ int vlan_dev_set_vlan_flag(const struct net_device *dev,
                           u32 flag, short flag_val);
 void vlan_dev_get_realdev_name(const struct net_device *dev, char *result);
 void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result);
-void vlan_change_rx_flags(struct net_device *dev, int change);
-void vlan_dev_set_multicast_list(struct net_device *vlan_dev);
 
 int vlan_check_real_dev(struct net_device *real_dev, unsigned short vlan_id);
 void vlan_setup(struct net_device *dev);
 int register_vlan_dev(struct net_device *dev);
-int unregister_vlan_device(struct net_device *dev);
+void unregister_vlan_dev(struct net_device *dev);
 
 int vlan_netlink_init(void);
 void vlan_netlink_fini(void);
index 4f99bb86af5c594b1bb77042ba43b321a9d50d4a..8059fa42b0859a1217946d91fde310d21baaba32 100644 (file)
@@ -3,7 +3,7 @@
  *             Ethernet-type device handling.
  *
  * Authors:    Ben Greear <greearb@candelatech.com>
- *              Please send support related email to: vlan@scry.wanfear.com
+ *              Please send support related email to: netdev@vger.kernel.org
  *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
  *
  * Fixes:       Mar 22 2001: Martin Bokaemper <mbokaemper@unispherenetworks.com>
@@ -47,7 +47,7 @@
  *
  * TODO:  This needs a checkup, I'm ignorant here. --BLG
  */
-int vlan_dev_rebuild_header(struct sk_buff *skb)
+static int vlan_dev_rebuild_header(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
@@ -60,9 +60,8 @@ int vlan_dev_rebuild_header(struct sk_buff *skb)
                return arp_find(veth->h_dest, skb);
 #endif
        default:
-               printk(VLAN_DBG
-                      "%s: unable to resolve type %X addresses.\n",
-                      dev->name, ntohs(veth->h_vlan_encapsulated_proto));
+               pr_debug("%s: unable to resolve type %X addresses.\n",
+                        dev->name, ntohs(veth->h_vlan_encapsulated_proto));
 
                memcpy(veth->h_source, dev->dev_addr, ETH_ALEN);
                break;
@@ -73,7 +72,7 @@ int vlan_dev_rebuild_header(struct sk_buff *skb)
 
 static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
 {
-       if (VLAN_DEV_INFO(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
+       if (vlan_dev_info(skb->dev)->flags & VLAN_FLAG_REORDER_HDR) {
                if (skb_shared(skb) || skb_cloned(skb)) {
                        struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
                        kfree_skb(skb);
@@ -90,6 +89,40 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
        return skb;
 }
 
+static inline void vlan_set_encap_proto(struct sk_buff *skb,
+               struct vlan_hdr *vhdr)
+{
+       __be16 proto;
+       unsigned char *rawp;
+
+       /*
+        * Was a VLAN packet, grab the encapsulated protocol, which the layer
+        * three protocols care about.
+        */
+
+       proto = vhdr->h_vlan_encapsulated_proto;
+       if (ntohs(proto) >= 1536) {
+               skb->protocol = proto;
+               return;
+       }
+
+       rawp = skb->data;
+       if (*(unsigned short *)rawp == 0xFFFF)
+               /*
+                * This is a magic hack to spot IPX packets. Older Novell
+                * breaks the protocol design and runs IPX over 802.3 without
+                * an 802.2 LLC layer. We look for FFFF which isn't a used
+                * 802.2 SSAP/DSAP. This won't work for fault tolerant netware
+                * but does for the rest.
+                */
+               skb->protocol = htons(ETH_P_802_3);
+       else
+               /*
+                * Real 802.2 LLC
+                */
+               skb->protocol = htons(ETH_P_802_2);
+}
+
 /*
  *     Determine the packet's protocol ID. The rule here is that we
  *     assume 802.3 if the type field is short enough to be a length.
@@ -107,115 +140,58 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
  *  SANITY NOTE 2: We are referencing to the VLAN_HDR frields, which MAY be
  *                 stored UNALIGNED in the memory.  RISC systems don't like
  *                 such cases very much...
- *  SANITY NOTE 2a:  According to Dave Miller & Alexey, it will always be aligned,
- *                 so there doesn't need to be any of the unaligned stuff.  It has
- *                 been commented out now...  --Ben
+ *  SANITY NOTE 2a: According to Dave Miller & Alexey, it will always be
+ *                 aligned, so there doesn't need to be any of the unaligned
+ *                 stuff.  It has been commented out now...  --Ben
  *
  */
 int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
-                 struct packet_typeptype, struct net_device *orig_dev)
+                 struct packet_type *ptype, struct net_device *orig_dev)
 {
-       unsigned char *rawp = NULL;
        struct vlan_hdr *vhdr;
        unsigned short vid;
        struct net_device_stats *stats;
        unsigned short vlan_TCI;
-       __be16 proto;
 
-       if (dev->nd_net != &init_net) {
-               kfree_skb(skb);
-               return -1;
-       }
+       if (dev->nd_net != &init_net)
+               goto err_free;
 
-       if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-               return -1;
+       skb = skb_share_check(skb, GFP_ATOMIC);
+       if (skb == NULL)
+               goto err_free;
 
-       if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) {
-               kfree_skb(skb);
-               return -1;
-       }
-
-       vhdr = (struct vlan_hdr *)(skb->data);
+       if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+               goto err_free;
 
-       /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */
+       vhdr = (struct vlan_hdr *)skb->data;
        vlan_TCI = ntohs(vhdr->h_vlan_TCI);
-
        vid = (vlan_TCI & VLAN_VID_MASK);
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: skb: %p vlan_id: %hx\n",
-               __FUNCTION__, skb, vid);
-#endif
-
-       /* Ok, we will find the correct VLAN device, strip the header,
-        * and then go on as usual.
-        */
-
-       /* We have 12 bits of vlan ID.
-        *
-        * We must not drop allow preempt until we hold a
-        * reference to the device (netif_rx does that) or we
-        * fail.
-        */
-
        rcu_read_lock();
        skb->dev = __find_vlan_dev(dev, vid);
        if (!skb->dev) {
-               rcu_read_unlock();
-
-#ifdef VLAN_DEBUG
-               printk(VLAN_DBG "%s: ERROR: No net_device for VID: %i on dev: %s [%i]\n",
-                       __FUNCTION__, (unsigned int)(vid), dev->name, dev->ifindex);
-#endif
-               kfree_skb(skb);
-               return -1;
+               pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
+                        __FUNCTION__, (unsigned int)vid, dev->name);
+               goto err_unlock;
        }
 
        skb->dev->last_rx = jiffies;
 
-       /* Bump the rx counters for the VLAN device. */
-       stats = vlan_dev_get_stats(skb->dev);
+       stats = &skb->dev->stats;
        stats->rx_packets++;
        stats->rx_bytes += skb->len;
 
-       /* Take off the VLAN header (4 bytes currently) */
        skb_pull_rcsum(skb, VLAN_HLEN);
 
-       /* Ok, lets check to make sure the device (dev) we
-        * came in on is what this VLAN is attached to.
-        */
-
-       if (dev != VLAN_DEV_INFO(skb->dev)->real_dev) {
-               rcu_read_unlock();
-
-#ifdef VLAN_DEBUG
-               printk(VLAN_DBG "%s: dropping skb: %p because came in on wrong device, dev: %s  real_dev: %s, skb_dev: %s\n",
-                       __FUNCTION__, skb, dev->name,
-                       VLAN_DEV_INFO(skb->dev)->real_dev->name,
-                       skb->dev->name);
-#endif
-               kfree_skb(skb);
-               stats->rx_errors++;
-               return -1;
-       }
-
-       /*
-        * Deal with ingress priority mapping.
-        */
-       skb->priority = vlan_get_ingress_priority(skb->dev, ntohs(vhdr->h_vlan_TCI));
+       skb->priority = vlan_get_ingress_priority(skb->dev,
+                                                 ntohs(vhdr->h_vlan_TCI));
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: priority: %lu  for TCI: %hu (hbo)\n",
-               __FUNCTION__, (unsigned long)(skb->priority),
-               ntohs(vhdr->h_vlan_TCI));
-#endif
+       pr_debug("%s: priority: %u for TCI: %hu\n",
+                __FUNCTION__, skb->priority, ntohs(vhdr->h_vlan_TCI));
 
-       /* The ethernet driver already did the pkt_type calculations
-        * for us...
-        */
        switch (skb->pkt_type) {
        case PACKET_BROADCAST: /* Yeah, stats collect these together.. */
-               // stats->broadcast ++; // no such counter :-(
+               /* stats->broadcast ++; // no such counter :-( */
                break;
 
        case PACKET_MULTICAST:
@@ -224,109 +200,47 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 
        case PACKET_OTHERHOST:
                /* Our lower layer thinks this is not local, let's make sure.
-                * This allows the VLAN to have a different MAC than the underlying
-                * device, and still route correctly.
+                * This allows the VLAN to have a different MAC than the
+                * underlying device, and still route correctly.
                 */
-               if (!compare_ether_addr(eth_hdr(skb)->h_dest, skb->dev->dev_addr)) {
-                       /* It is for our (changed) MAC-address! */
+               if (!compare_ether_addr(eth_hdr(skb)->h_dest,
+                                       skb->dev->dev_addr))
                        skb->pkt_type = PACKET_HOST;
-               }
                break;
        default:
                break;
        }
 
-       /*  Was a VLAN packet, grab the encapsulated protocol, which the layer
-        * three protocols care about.
-        */
-       /* proto = get_unaligned(&vhdr->h_vlan_encapsulated_proto); */
-       proto = vhdr->h_vlan_encapsulated_proto;
-
-       skb->protocol = proto;
-       if (ntohs(proto) >= 1536) {
-               /* place it back on the queue to be handled by
-                * true layer 3 protocols.
-                */
-
-               /* See if we are configured to re-write the VLAN header
-                * to make it look like ethernet...
-                */
-               skb = vlan_check_reorder_header(skb);
-
-               /* Can be null if skb-clone fails when re-ordering */
-               if (skb) {
-                       netif_rx(skb);
-               } else {
-                       /* TODO:  Add a more specific counter here. */
-                       stats->rx_errors++;
-               }
-               rcu_read_unlock();
-               return 0;
-       }
-
-       rawp = skb->data;
-
-       /*
-        * This is a magic hack to spot IPX packets. Older Novell breaks
-        * the protocol design and runs IPX over 802.3 without an 802.2 LLC
-        * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
-        * won't work for fault tolerant netware but does for the rest.
-        */
-       if (*(unsigned short *)rawp == 0xFFFF) {
-               skb->protocol = htons(ETH_P_802_3);
-               /* place it back on the queue to be handled by true layer 3 protocols.
-                */
-
-               /* See if we are configured to re-write the VLAN header
-                * to make it look like ethernet...
-                */
-               skb = vlan_check_reorder_header(skb);
+       vlan_set_encap_proto(skb, vhdr);
 
-               /* Can be null if skb-clone fails when re-ordering */
-               if (skb) {
-                       netif_rx(skb);
-               } else {
-                       /* TODO:  Add a more specific counter here. */
-                       stats->rx_errors++;
-               }
-               rcu_read_unlock();
-               return 0;
-       }
-
-       /*
-        *      Real 802.2 LLC
-        */
-       skb->protocol = htons(ETH_P_802_2);
-       /* place it back on the queue to be handled by upper layer protocols.
-        */
-
-       /* See if we are configured to re-write the VLAN header
-        * to make it look like ethernet...
-        */
        skb = vlan_check_reorder_header(skb);
-
-       /* Can be null if skb-clone fails when re-ordering */
-       if (skb) {
-               netif_rx(skb);
-       } else {
-               /* TODO:  Add a more specific counter here. */
+       if (!skb) {
                stats->rx_errors++;
+               goto err_unlock;
        }
+
+       netif_rx(skb);
        rcu_read_unlock();
-       return 0;
+       return NET_RX_SUCCESS;
+
+err_unlock:
+       rcu_read_unlock();
+err_free:
+       kfree_skb(skb);
+       return NET_RX_DROP;
 }
 
-static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev,
-                                                         struct sk_buff* skb)
+static inline unsigned short
+vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
 {
-       struct vlan_priority_tci_mapping *mp =
-               VLAN_DEV_INFO(dev)->egress_priority_map[(skb->priority & 0xF)];
+       struct vlan_priority_tci_mapping *mp;
 
+       mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)];
        while (mp) {
                if (mp->priority == skb->priority) {
-                       return mp->vlan_qos; /* This should already be shifted to mask
-                                             * correctly with the VLAN's TCI
-                                             */
+                       return mp->vlan_qos; /* This should already be shifted
+                                             * to mask correctly with the
+                                             * VLAN's TCI */
                }
                mp = mp->next;
        }
@@ -342,20 +256,20 @@ static inline unsigned short vlan_dev_get_egress_qos_mask(struct net_device* dev
  *  This is called when the SKB is moving down the stack towards the
  *  physical devices.
  */
-int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
-                        unsigned short type,
-                        const void *daddr, const void *saddr, unsigned len)
+static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
+                               unsigned short type,
+                               const void *daddr, const void *saddr,
+                               unsigned int len)
 {
        struct vlan_hdr *vhdr;
        unsigned short veth_TCI = 0;
        int rc = 0;
        int build_vlan_header = 0;
-       struct net_device *vdev = dev; /* save this for the bottom of the method */
+       struct net_device *vdev = dev;
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: skb: %p type: %hx len: %x vlan_id: %hx, daddr: %p\n",
-               __FUNCTION__, skb, type, len, VLAN_DEV_INFO(dev)->vlan_id, daddr);
-#endif
+       pr_debug("%s: skb: %p type: %hx len: %u vlan_id: %hx, daddr: %p\n",
+                __FUNCTION__, skb, type, len, vlan_dev_info(dev)->vlan_id,
+                daddr);
 
        /* build vlan header only if re_order_header flag is NOT set.  This
         * fixes some programs that get confused when they see a VLAN device
@@ -365,7 +279,7 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
         * header shuffling in the hard_start_xmit.  Users can turn off this
         * REORDER behaviour with the vconfig tool.
         */
-       if (!(VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR))
+       if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR))
                build_vlan_header = 1;
 
        if (build_vlan_header) {
@@ -373,29 +287,28 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 
                /* build the four bytes that make this a VLAN header. */
 
-               /* Now, construct the second two bytes. This field looks something
-                * like:
+               /* Now, construct the second two bytes. This field looks
+                * something like:
                 * usr_priority: 3 bits  (high bits)
                 * CFI           1 bit
                 * VLAN ID       12 bits (low bits)
                 *
                 */
-               veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
+               veth_TCI = vlan_dev_info(dev)->vlan_id;
                veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
 
                vhdr->h_vlan_TCI = htons(veth_TCI);
 
                /*
-                *  Set the protocol type.
-                *  For a packet of type ETH_P_802_3 we put the length in here instead.
-                *  It is up to the 802.2 layer to carry protocol information.
+                *  Set the protocol type. For a packet of type ETH_P_802_3 we
+                *  put the length in here instead. It is up to the 802.2
+                *  layer to carry protocol information.
                 */
 
-               if (type != ETH_P_802_3) {
+               if (type != ETH_P_802_3)
                        vhdr->h_vlan_encapsulated_proto = htons(type);
-               } else {
+               else
                        vhdr->h_vlan_encapsulated_proto = htons(len);
-               }
 
                skb->protocol = htons(ETH_P_8021Q);
                skb_reset_network_header(skb);
@@ -405,16 +318,16 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
        if (saddr == NULL)
                saddr = dev->dev_addr;
 
-       dev = VLAN_DEV_INFO(dev)->real_dev;
+       dev = vlan_dev_info(dev)->real_dev;
 
-       /* MPLS can send us skbuffs w/out enough space.  This check will grow the
-        * skb if it doesn't have enough headroom.  Not a beautiful solution, so
-        * I'll tick a counter so that users can know it's happening...  If they
-        * care...
+       /* MPLS can send us skbuffs w/out enough space. This check will grow
+        * the skb if it doesn't have enough headroom. Not a beautiful solution,
+        * so I'll tick a counter so that users can know it's happening...
+        * If they care...
         */
 
-       /* NOTE:  This may still break if the underlying device is not the final
-        * device (and thus there are more headers to add...)  It should work for
+       /* NOTE: This may still break if the underlying device is not the final
+        * device (and thus there are more headers to add...) It should work for
         * good-ole-ethernet though.
         */
        if (skb_headroom(skb) < dev->hard_header_len) {
@@ -422,14 +335,12 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
                skb = skb_realloc_headroom(sk_tmp, dev->hard_header_len);
                kfree_skb(sk_tmp);
                if (skb == NULL) {
-                       struct net_device_stats *stats = vlan_dev_get_stats(vdev);
+                       struct net_device_stats *stats = &vdev->stats;
                        stats->tx_dropped++;
                        return -ENOMEM;
                }
-               VLAN_DEV_INFO(vdev)->cnt_inc_headroom_on_tx++;
-#ifdef VLAN_DEBUG
-               printk(VLAN_DBG "%s: %s: had to grow skb.\n", __FUNCTION__, vdev->name);
-#endif
+               vlan_dev_info(vdev)->cnt_inc_headroom_on_tx++;
+               pr_debug("%s: %s: had to grow skb\n", __FUNCTION__, vdev->name);
        }
 
        if (build_vlan_header) {
@@ -441,19 +352,19 @@ int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
                else if (rc < 0)
                        rc -= VLAN_HLEN;
        } else
-               /* If here, then we'll just make a normal looking ethernet frame,
-                * but, the hard_start_xmit method will insert the tag (it has to
-                * be able to do this for bridged and other skbs that don't come
-                * down the protocol stack in an orderly manner.
+               /* If here, then we'll just make a normal looking ethernet
+                * frame, but, the hard_start_xmit method will insert the tag
+                * (it has to be able to do this for bridged and other skbs
+                * that don't come down the protocol stack in an orderly manner.
                 */
                rc = dev_hard_header(skb, dev, type, daddr, saddr, len);
 
        return rc;
 }
 
-int vlan_dev_hard_start_xmit(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 = vlan_dev_get_stats(dev);
+       struct net_device_stats *stats = &dev->stats;
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
 
        /* Handle non-VLAN frames if they are sent to us, for example by DHCP.
@@ -463,24 +374,22 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
 
        if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
-               VLAN_DEV_INFO(dev)->flags & VLAN_FLAG_REORDER_HDR) {
+               vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
                int orig_headroom = skb_headroom(skb);
                unsigned short veth_TCI;
 
                /* This is not a VLAN frame...but we can fix that! */
-               VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++;
+               vlan_dev_info(dev)->cnt_encap_on_xmit++;
 
-#ifdef VLAN_DEBUG
-               printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n",
-                       __FUNCTION__, htons(veth->h_vlan_proto));
-#endif
+               pr_debug("%s: proto to encap: 0x%hx\n",
+                        __FUNCTION__, htons(veth->h_vlan_proto));
                /* Construct the second two bytes. This field looks something
                 * like:
                 * usr_priority: 3 bits  (high bits)
                 * CFI           1 bit
                 * VLAN ID       12 bits (low bits)
                 */
-               veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
+               veth_TCI = vlan_dev_info(dev)->vlan_id;
                veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
 
                skb = __vlan_put_tag(skb, veth_TCI);
@@ -489,32 +398,33 @@ int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        return 0;
                }
 
-               if (orig_headroom < VLAN_HLEN) {
-                       VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
-               }
+               if (orig_headroom < VLAN_HLEN)
+                       vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
        }
 
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n",
+       pr_debug("%s: about to send skb: %p to dev: %s\n",
                __FUNCTION__, skb, skb->dev->name);
-       printk(VLAN_DBG "  %2hx.%2hx.%2hx.%2xh.%2hx.%2hx %2hx.%2hx.%2hx.%2hx.%2hx.%2hx %4hx %4hx %4hx\n",
-              veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
-              veth->h_source[0], veth->h_source[1], veth->h_source[2], veth->h_source[3], veth->h_source[4], veth->h_source[5],
-              veth->h_vlan_proto, veth->h_vlan_TCI, veth->h_vlan_encapsulated_proto);
-#endif
+       pr_debug("  " MAC_FMT " " MAC_FMT " %4hx %4hx %4hx\n",
+                veth->h_dest[0], veth->h_dest[1], veth->h_dest[2],
+                veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
+                veth->h_source[0], veth->h_source[1], veth->h_source[2],
+                veth->h_source[3], veth->h_source[4], veth->h_source[5],
+                veth->h_vlan_proto, veth->h_vlan_TCI,
+                veth->h_vlan_encapsulated_proto);
 
        stats->tx_packets++; /* for statics only */
        stats->tx_bytes += skb->len;
 
-       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+       skb->dev = vlan_dev_info(dev)->real_dev;
        dev_queue_xmit(skb);
 
        return 0;
 }
 
-int vlan_dev_hwaccel_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 = vlan_dev_get_stats(dev);
+       struct net_device_stats *stats = &dev->stats;
        unsigned short veth_TCI;
 
        /* Construct the second two bytes. This field looks something
@@ -523,25 +433,25 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev
         * CFI           1 bit
         * VLAN ID       12 bits (low bits)
         */
-       veth_TCI = VLAN_DEV_INFO(dev)->vlan_id;
+       veth_TCI = vlan_dev_info(dev)->vlan_id;
        veth_TCI |= vlan_dev_get_egress_qos_mask(dev, skb);
        skb = __vlan_hwaccel_put_tag(skb, veth_TCI);
 
        stats->tx_packets++;
        stats->tx_bytes += skb->len;
 
-       skb->dev = VLAN_DEV_INFO(dev)->real_dev;
+       skb->dev = vlan_dev_info(dev)->real_dev;
        dev_queue_xmit(skb);
 
        return 0;
 }
 
-int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
+static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
 {
        /* TODO: gotta make sure the underlying layer can handle it,
         * maybe an IFF_VLAN_CAPABLE flag for devices?
         */
-       if (VLAN_DEV_INFO(dev)->real_dev->mtu < new_mtu)
+       if (vlan_dev_info(dev)->real_dev->mtu < new_mtu)
                return -ERANGE;
 
        dev->mtu = new_mtu;
@@ -552,7 +462,7 @@ int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
 void vlan_dev_set_ingress_priority(const struct net_device *dev,
                                   u32 skb_prio, short vlan_prio)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
 
        if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio)
                vlan->nr_ingress_mappings--;
@@ -565,7 +475,7 @@ void vlan_dev_set_ingress_priority(const struct net_device *dev,
 int vlan_dev_set_egress_priority(const struct net_device *dev,
                                 u32 skb_prio, short vlan_prio)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct vlan_priority_tci_mapping *mp = NULL;
        struct vlan_priority_tci_mapping *np;
        u32 vlan_qos = (vlan_prio << 13) & 0xE000;
@@ -605,30 +515,28 @@ int vlan_dev_set_vlan_flag(const struct net_device *dev,
 {
        /* verify flag is supported */
        if (flag == VLAN_FLAG_REORDER_HDR) {
-               if (flag_val) {
-                       VLAN_DEV_INFO(dev)->flags |= VLAN_FLAG_REORDER_HDR;
-               } else {
-                       VLAN_DEV_INFO(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
-               }
+               if (flag_val)
+                       vlan_dev_info(dev)->flags |= VLAN_FLAG_REORDER_HDR;
+               else
+                       vlan_dev_info(dev)->flags &= ~VLAN_FLAG_REORDER_HDR;
                return 0;
        }
-       printk(KERN_ERR "%s: flag %i is not valid.\n", __FUNCTION__, flag);
        return -EINVAL;
 }
 
 void vlan_dev_get_realdev_name(const struct net_device *dev, char *result)
 {
-       strncpy(result, VLAN_DEV_INFO(dev)->real_dev->name, 23);
+       strncpy(result, vlan_dev_info(dev)->real_dev->name, 23);
 }
 
 void vlan_dev_get_vid(const struct net_device *dev, unsigned short *result)
 {
-       *result = VLAN_DEV_INFO(dev)->vlan_id;
+       *result = vlan_dev_info(dev)->vlan_id;
 }
 
-int vlan_dev_open(struct net_device *dev)
+static int vlan_dev_open(struct net_device *dev)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct net_device *real_dev = vlan->real_dev;
        int err;
 
@@ -650,9 +558,9 @@ int vlan_dev_open(struct net_device *dev)
        return 0;
 }
 
-int vlan_dev_stop(struct net_device *dev)
+static int vlan_dev_stop(struct net_device *dev)
 {
-       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
 
        dev_mc_unsync(real_dev, dev);
        if (dev->flags & IFF_ALLMULTI)
@@ -666,9 +574,9 @@ int vlan_dev_stop(struct net_device *dev)
        return 0;
 }
 
-int vlan_set_mac_address(struct net_device *dev, void *p)
+static int vlan_dev_set_mac_address(struct net_device *dev, void *p)
 {
-       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
        struct sockaddr *addr = p;
        int err;
 
@@ -692,16 +600,16 @@ out:
        return 0;
 }
 
-int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
        struct ifreq ifrr;
        int err = -EOPNOTSUPP;
 
        strncpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
        ifrr.ifr_ifru = ifr->ifr_ifru;
 
-       switch(cmd) {
+       switch (cmd) {
        case SIOCGMIIPHY:
        case SIOCGMIIREG:
        case SIOCSMIIREG:
@@ -716,9 +624,9 @@ int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return err;
 }
 
-void vlan_change_rx_flags(struct net_device *dev, int change)
+static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
 {
-       struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev;
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
 
        if (change & IFF_ALLMULTI)
                dev_set_allmulti(real_dev, dev->flags & IFF_ALLMULTI ? 1 : -1);
@@ -726,8 +634,78 @@ void vlan_change_rx_flags(struct net_device *dev, int change)
                dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1);
 }
 
-/** Taken from Gleb + Lennert's VLAN code, and modified... */
-void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+static void vlan_dev_set_multicast_list(struct net_device *vlan_dev)
+{
+       dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev);
+}
+
+/*
+ * vlan network devices have devices nesting below it, and are a special
+ * "super class" of normal network devices; split their locks off into a
+ * separate class since they always nest.
+ */
+static struct lock_class_key vlan_netdev_xmit_lock_key;
+
+static const struct header_ops vlan_header_ops = {
+       .create  = vlan_dev_hard_header,
+       .rebuild = vlan_dev_rebuild_header,
+       .parse   = eth_header_parse,
+};
+
+static int vlan_dev_init(struct net_device *dev)
+{
+       struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
+       int subclass = 0;
+
+       /* IFF_BROADCAST|IFF_MULTICAST; ??? */
+       dev->flags  = real_dev->flags & ~IFF_UP;
+       dev->iflink = real_dev->ifindex;
+       dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
+                                         (1<<__LINK_STATE_DORMANT))) |
+                     (1<<__LINK_STATE_PRESENT);
+
+       /* ipv6 shared card related stuff */
+       dev->dev_id = real_dev->dev_id;
+
+       if (is_zero_ether_addr(dev->dev_addr))
+               memcpy(dev->dev_addr, real_dev->dev_addr, dev->addr_len);
+       if (is_zero_ether_addr(dev->broadcast))
+               memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
+
+       if (real_dev->features & NETIF_F_HW_VLAN_TX) {
+               dev->header_ops      = real_dev->header_ops;
+               dev->hard_header_len = real_dev->hard_header_len;
+               dev->hard_start_xmit = vlan_dev_hwaccel_hard_start_xmit;
+       } else {
+               dev->header_ops      = &vlan_header_ops;
+               dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
+               dev->hard_start_xmit = vlan_dev_hard_start_xmit;
+       }
+
+       if (real_dev->priv_flags & IFF_802_1Q_VLAN)
+               subclass = 1;
+
+       lockdep_set_class_and_subclass(&dev->_xmit_lock,
+                               &vlan_netdev_xmit_lock_key, subclass);
+       return 0;
+}
+
+void vlan_setup(struct net_device *dev)
 {
-       dev_mc_sync(VLAN_DEV_INFO(vlan_dev)->real_dev, vlan_dev);
+       ether_setup(dev);
+
+       dev->priv_flags         |= IFF_802_1Q_VLAN;
+       dev->tx_queue_len       = 0;
+
+       dev->change_mtu         = vlan_dev_change_mtu;
+       dev->init               = vlan_dev_init;
+       dev->open               = vlan_dev_open;
+       dev->stop               = vlan_dev_stop;
+       dev->set_mac_address    = vlan_dev_set_mac_address;
+       dev->set_multicast_list = vlan_dev_set_multicast_list;
+       dev->change_rx_flags    = vlan_dev_change_rx_flags;
+       dev->do_ioctl           = vlan_dev_ioctl;
+       dev->destructor         = free_netdev;
+
+       memset(dev->broadcast, 0, ETH_ALEN);
 }
index 0996185e2ed5dd816946df9fdcf10a1d4a1d4b13..e32eeb37987e87ad4c07d8c6f5e97fc7e67bdc53 100644 (file)
@@ -75,7 +75,7 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
 static int vlan_changelink(struct net_device *dev,
                           struct nlattr *tb[], struct nlattr *data[])
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct ifla_vlan_flags *flags;
        struct ifla_vlan_qos_mapping *m;
        struct nlattr *attr;
@@ -104,7 +104,7 @@ static int vlan_changelink(struct net_device *dev,
 static int vlan_newlink(struct net_device *dev,
                        struct nlattr *tb[], struct nlattr *data[])
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct net_device *real_dev;
        int err;
 
@@ -137,11 +137,6 @@ static int vlan_newlink(struct net_device *dev,
        return register_vlan_dev(dev);
 }
 
-static void vlan_dellink(struct net_device *dev)
-{
-       unregister_vlan_device(dev);
-}
-
 static inline size_t vlan_qos_map_size(unsigned int n)
 {
        if (n == 0)
@@ -153,7 +148,7 @@ static inline size_t vlan_qos_map_size(unsigned int n)
 
 static size_t vlan_get_size(const struct net_device *dev)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
 
        return nla_total_size(2) +      /* IFLA_VLAN_ID */
               vlan_qos_map_size(vlan->nr_ingress_mappings) +
@@ -162,14 +157,14 @@ static size_t vlan_get_size(const struct net_device *dev)
 
 static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
-       struct vlan_dev_info *vlan = VLAN_DEV_INFO(dev);
+       struct vlan_dev_info *vlan = vlan_dev_info(dev);
        struct vlan_priority_tci_mapping *pm;
        struct ifla_vlan_flags f;
        struct ifla_vlan_qos_mapping m;
        struct nlattr *nest;
        unsigned int i;
 
-       NLA_PUT_U16(skb, IFLA_VLAN_ID, VLAN_DEV_INFO(dev)->vlan_id);
+       NLA_PUT_U16(skb, IFLA_VLAN_ID, vlan_dev_info(dev)->vlan_id);
        if (vlan->flags) {
                f.flags = vlan->flags;
                f.mask  = ~0;
@@ -226,7 +221,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = {
        .validate       = vlan_validate,
        .newlink        = vlan_newlink,
        .changelink     = vlan_changelink,
-       .dellink        = vlan_dellink,
+       .dellink        = unregister_vlan_dev,
        .get_size       = vlan_get_size,
        .fill_info      = vlan_fill_info,
 };
index 6cefdf8e381a3b40bf9d6d78c5535e25bab6f612..a0ec4792559713a0afe6fb1051be7d0b3cec31f1 100644 (file)
@@ -125,10 +125,10 @@ static struct proc_dir_entry *proc_vlan_conf;
 
 /* Strings */
 static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
-    [VLAN_NAME_TYPE_RAW_PLUS_VID]       = "VLAN_NAME_TYPE_RAW_PLUS_VID",
-    [VLAN_NAME_TYPE_PLUS_VID_NO_PAD]   = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
-    [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD]= "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
-    [VLAN_NAME_TYPE_PLUS_VID]          = "VLAN_NAME_TYPE_PLUS_VID",
+    [VLAN_NAME_TYPE_RAW_PLUS_VID]        = "VLAN_NAME_TYPE_RAW_PLUS_VID",
+    [VLAN_NAME_TYPE_PLUS_VID_NO_PAD]    = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
+    [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
+    [VLAN_NAME_TYPE_PLUS_VID]           = "VLAN_NAME_TYPE_PLUS_VID",
 };
 /*
  *     Interface functions
@@ -158,15 +158,18 @@ void vlan_proc_cleanup(void)
 int __init vlan_proc_init(void)
 {
        proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net);
-       if (proc_vlan_dir) {
-               proc_vlan_conf = create_proc_entry(name_conf,
-                                                  S_IFREG|S_IRUSR|S_IWUSR,
-                                                  proc_vlan_dir);
-               if (proc_vlan_conf) {
-                       proc_vlan_conf->proc_fops = &vlan_fops;
-                       return 0;
-               }
-       }
+       if (!proc_vlan_dir)
+               goto err;
+
+       proc_vlan_conf = create_proc_entry(name_conf, S_IFREG|S_IRUSR|S_IWUSR,
+                                          proc_vlan_dir);
+       if (!proc_vlan_conf)
+               goto err;
+       proc_vlan_conf->proc_fops = &vlan_fops;
+       return 0;
+
+err:
+       pr_err("%s: can't create entry in proc filesystem!\n", __FUNCTION__);
        vlan_proc_cleanup();
        return -ENOBUFS;
 }
@@ -175,16 +178,9 @@ int __init vlan_proc_init(void)
  *     Add directory entry for VLAN device.
  */
 
-int vlan_proc_add_dev (struct net_device *vlandev)
+int vlan_proc_add_dev(struct net_device *vlandev)
 {
-       struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
-
-       if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
-               printk(KERN_ERR
-                      "ERROR:  vlan_proc_add, device -:%s:- is NOT a VLAN\n",
-                      vlandev->name);
-               return -EINVAL;
-       }
+       struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
 
        dev_info->dent = create_proc_entry(vlandev->name,
                                           S_IFREG|S_IRUSR|S_IWUSR,
@@ -194,11 +190,6 @@ int vlan_proc_add_dev (struct net_device *vlandev)
 
        dev_info->dent->proc_fops = &vlandev_fops;
        dev_info->dent->data = vlandev;
-
-#ifdef VLAN_DEBUG
-       printk(KERN_ERR "vlan_proc_add, device -:%s:- being added.\n",
-              vlandev->name);
-#endif
        return 0;
 }
 
@@ -207,28 +198,12 @@ int vlan_proc_add_dev (struct net_device *vlandev)
  */
 int vlan_proc_rem_dev(struct net_device *vlandev)
 {
-       if (!vlandev) {
-               printk(VLAN_ERR "%s: invalid argument: %p\n",
-                       __FUNCTION__, vlandev);
-               return -EINVAL;
-       }
-
-       if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
-               printk(VLAN_DBG "%s: invalid argument, device: %s is not a VLAN device, priv_flags: 0x%4hX.\n",
-                       __FUNCTION__, vlandev->name, vlandev->priv_flags);
-               return -EINVAL;
-       }
-
-#ifdef VLAN_DEBUG
-       printk(VLAN_DBG "%s: dev: %p\n", __FUNCTION__, vlandev);
-#endif
-
        /** NOTE:  This will consume the memory pointed to by dent, it seems. */
-       if (VLAN_DEV_INFO(vlandev)->dent) {
-               remove_proc_entry(VLAN_DEV_INFO(vlandev)->dent->name, proc_vlan_dir);
-               VLAN_DEV_INFO(vlandev)->dent = NULL;
+       if (vlan_dev_info(vlandev)->dent) {
+               remove_proc_entry(vlan_dev_info(vlandev)->dent->name,
+                                 proc_vlan_dir);
+               vlan_dev_info(vlandev)->dent = NULL;
        }
-
        return 0;
 }
 
@@ -245,6 +220,7 @@ static inline int is_vlan_dev(struct net_device *dev)
 
 /* start read of /proc/net/vlan/config */
 static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
        struct net_device *dev;
        loff_t i = 1;
@@ -286,6 +262,7 @@ static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void vlan_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        read_unlock(&dev_base_lock);
 }
@@ -301,10 +278,10 @@ static int vlan_seq_show(struct seq_file *seq, void *v)
                    nmtype =  vlan_name_type_str[vlan_name_type];
 
                seq_printf(seq, "Name-Type: %s\n",
-                          nmtype ? nmtype :  "UNKNOWN" );
+                          nmtype ? nmtype :  "UNKNOWN");
        } else {
                const struct net_device *vlandev = v;
-               const struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
+               const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
 
                seq_printf(seq, "%-15s| %d  | %s\n",  vlandev->name,
                           dev_info->vlan_id,    dev_info->real_dev->name);
@@ -315,20 +292,18 @@ static int vlan_seq_show(struct seq_file *seq, void *v)
 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;
+       const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
+       struct net_device_stats *stats = &vlandev->stats;
        static const char fmt[] = "%30s %12lu\n";
        int i;
 
        if (!(vlandev->priv_flags & IFF_802_1Q_VLAN))
                return 0;
 
-       seq_printf(seq, "%s  VID: %d     REORDER_HDR: %i  dev->priv_flags: %hx\n",
-                      vlandev->name, dev_info->vlan_id,
-                      (int)(dev_info->flags & 1), vlandev->priv_flags);
-
-
-       stats = vlan_dev_get_stats(vlandev);
+       seq_printf(seq,
+                  "%s  VID: %d  REORDER_HDR: %i  dev->priv_flags: %hx\n",
+                  vlandev->name, dev_info->vlan_id,
+                  (int)(dev_info->flags & 1), vlandev->priv_flags);
 
        seq_printf(seq, fmt, "total frames received", stats->rx_packets);
        seq_printf(seq, fmt, "total bytes received", stats->rx_bytes);
@@ -342,16 +317,16 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
                   dev_info->cnt_encap_on_xmit);
        seq_printf(seq, "Device: %s", dev_info->real_dev->name);
        /* now show all PRIORITY mappings relating to this VLAN */
-       seq_printf(seq,
-                      "\nINGRESS priority mappings: 0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
-                      dev_info->ingress_priority_map[0],
-                      dev_info->ingress_priority_map[1],
-                      dev_info->ingress_priority_map[2],
-                      dev_info->ingress_priority_map[3],
-                      dev_info->ingress_priority_map[4],
-                      dev_info->ingress_priority_map[5],
-                      dev_info->ingress_priority_map[6],
-                      dev_info->ingress_priority_map[7]);
+       seq_printf(seq, "\nINGRESS priority mappings: "
+                       "0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
+                  dev_info->ingress_priority_map[0],
+                  dev_info->ingress_priority_map[1],
+                  dev_info->ingress_priority_map[2],
+                  dev_info->ingress_priority_map[3],
+                  dev_info->ingress_priority_map[4],
+                  dev_info->ingress_priority_map[5],
+                  dev_info->ingress_priority_map[6],
+                  dev_info->ingress_priority_map[7]);
 
        seq_printf(seq, "EGRESSS priority Mappings: ");
        for (i = 0; i < 16; i++) {
index f908ee332fd80ed32a353d091f215b5bdf546fee..da542cacc5a5ea3980a80286a96d79d1828da2f0 100644 (file)
@@ -4,16 +4,15 @@
 #ifdef CONFIG_PROC_FS
 int vlan_proc_init(void);
 int vlan_proc_rem_dev(struct net_device *vlandev);
-int vlan_proc_add_dev (struct net_device *vlandev);
-void vlan_proc_cleanup (void);
+int vlan_proc_add_dev(struct net_device *vlandev);
+void vlan_proc_cleanup(void);
 
 #else /* No CONFIG_PROC_FS */
 
 #define vlan_proc_init()       (0)
-#define vlan_proc_cleanup()    do {} while(0)
-#define vlan_proc_add_dev(dev) ({(void)(dev), 0;})
-#define vlan_proc_rem_dev(dev) ({(void)(dev), 0;})
-
+#define vlan_proc_cleanup()    do {} while (0)
+#define vlan_proc_add_dev(dev) ({(void)(dev), 0; })
+#define vlan_proc_rem_dev(dev) ({(void)(dev), 0; })
 #endif
 
 #endif /* !(__BEN_VLAN_PROC_INC__) */
index ab4e6da5012f1e1d2ef45436fa863d80655f75e2..b6a5d454f2ffa9219c4037c68e50d6b49eef6f2f 100644 (file)
@@ -144,9 +144,21 @@ config NETFILTER_DEBUG
          You can say Y here if you want to get additional messages useful in
          debugging the netfilter code.
 
+config NETFILTER_ADVANCED
+       bool "Advanced netfilter configuration"
+       depends on NETFILTER
+       default y
+       help
+         If you say Y here you can select between all the netfilter modules.
+         If you say N the more ununsual ones will not be shown and the
+         basic ones needed by most people will default to 'M'.
+
+         If unsure, say Y.
+
 config BRIDGE_NETFILTER
        bool "Bridged IP/ARP packets filtering"
        depends on BRIDGE && NETFILTER && INET
+       depends on NETFILTER_ADVANCED
        default y
        ---help---
          Enabling this option will let arptables resp. iptables see bridged
@@ -218,6 +230,7 @@ endmenu
 endmenu
 
 source "net/ax25/Kconfig"
+source "net/can/Kconfig"
 source "net/irda/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/rxrpc/Kconfig"
index bbe7d2a4148670511dbffdabebdc90256fc80f33..b7a13643b5498baf8da7de4fe31dd18d6a598061 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_LAPB)            += lapb/
 obj-$(CONFIG_NETROM)           += netrom/
 obj-$(CONFIG_ROSE)             += rose/
 obj-$(CONFIG_AX25)             += ax25/
+obj-$(CONFIG_CAN)              += can/
 obj-$(CONFIG_IRDA)             += irda/
 obj-$(CONFIG_BT)               += bluetooth/
 obj-$(CONFIG_SUNRPC)           += sunrpc/
index 6c5c6dc098ec3c34814202979d84ec4dcc951376..18058bbc7962273ff21fea2cca4de9a8da18ef03 100644 (file)
@@ -874,9 +874,7 @@ void __init aarp_proto_init(void)
        aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv);
        if (!aarp_dl)
                printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
-       init_timer(&aarp_timer);
-       aarp_timer.function = aarp_expire_timeout;
-       aarp_timer.data     = 0;
+       setup_timer(&aarp_timer, aarp_expire_timeout, 0);
        aarp_timer.expires  = jiffies + sysctl_aarp_expiry_time;
        add_timer(&aarp_timer);
        register_netdevice_notifier(&aarp_notifier);
@@ -943,6 +941,7 @@ static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos)
 }
 
 static void *aarp_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(aarp_lock)
 {
        struct aarp_iter_state *iter = seq->private;
 
@@ -977,6 +976,7 @@ static void *aarp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void aarp_seq_stop(struct seq_file *seq, void *v)
+       __releases(aarp_lock)
 {
        read_unlock_bh(&aarp_lock);
 }
index 05d9652afcb6a57708219094b1f849d1207668fb..8e8dcfd532dbba7ca73edae10ec88a52879ef08f 100644 (file)
@@ -27,6 +27,7 @@ static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
 }
 
 static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos)
+       __acquires(atalk_interfaces_lock)
 {
        loff_t l = *pos;
 
@@ -52,6 +53,7 @@ out:
 }
 
 static void atalk_seq_interface_stop(struct seq_file *seq, void *v)
+       __releases(atalk_interfaces_lock)
 {
        read_unlock_bh(&atalk_interfaces_lock);
 }
@@ -86,6 +88,7 @@ static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos)
 }
 
 static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos)
+       __acquires(atalk_routes_lock)
 {
        loff_t l = *pos;
 
@@ -111,6 +114,7 @@ out:
 }
 
 static void atalk_seq_route_stop(struct seq_file *seq, void *v)
+       __releases(atalk_routes_lock)
 {
        read_unlock_bh(&atalk_routes_lock);
 }
@@ -154,6 +158,7 @@ found:
 }
 
 static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos)
+       __acquires(atalk_sockets_lock)
 {
        loff_t l = *pos;
 
@@ -176,6 +181,7 @@ out:
 }
 
 static void atalk_seq_socket_stop(struct seq_file *seq, void *v)
+       __releases(atalk_sockets_lock)
 {
        read_unlock_bh(&atalk_sockets_lock);
 }
index e0d37d6dc1f81e6ec7455fe5d1f0c5acabc0ccd8..3be55c8ca4ef660f8cabab3786d0ace8daa4de9d 100644 (file)
@@ -177,10 +177,9 @@ static inline void atalk_destroy_socket(struct sock *sk)
 
        if (atomic_read(&sk->sk_wmem_alloc) ||
            atomic_read(&sk->sk_rmem_alloc)) {
-               init_timer(&sk->sk_timer);
+               setup_timer(&sk->sk_timer, atalk_destroy_timer,
+                               (unsigned long)sk);
                sk->sk_timer.expires    = jiffies + SOCK_DESTROY_TIME;
-               sk->sk_timer.function   = atalk_destroy_timer;
-               sk->sk_timer.data       = (unsigned long)sk;
                add_timer(&sk->sk_timer);
        } else
                sock_put(sk);
index 7df1778e221a6f9ab3782789ffeb51af61ceb165..621805dfa2f4a4f84c9c0264dfc027935f2a85ac 100644 (file)
@@ -49,31 +49,17 @@ static struct ctl_table atalk_table[] = {
        { 0 },
 };
 
-static struct ctl_table atalk_dir_table[] = {
-       {
-               .ctl_name       = NET_ATALK,
-               .procname       = "appletalk",
-               .mode           = 0555,
-               .child          = atalk_table,
-       },
-       { 0 },
-};
-
-static struct ctl_table atalk_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = atalk_dir_table,
-       },
-       { 0 },
+static struct ctl_path atalk_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "appletalk", .ctl_name = NET_ATALK, },
+       { }
 };
 
 static struct ctl_table_header *atalk_table_header;
 
 void atalk_register_sysctl(void)
 {
-       atalk_table_header = register_sysctl_table(atalk_root_table);
+       atalk_table_header = register_sysctl_paths(atalk_path, atalk_table);
 }
 
 void atalk_unregister_sysctl(void)
index 21ff276b2d8047f87a7bec4b5af6996ef91abf75..754ea103b378970775a395ac3a16de491582ec80 100644 (file)
@@ -1,10 +1,9 @@
 #
-# Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)
+# Asynchronous Transfer Mode (ATM)
 #
 
 config ATM
-       tristate "Asynchronous Transfer Mode (ATM) (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       tristate "Asynchronous Transfer Mode (ATM)"
        ---help---
          ATM is a high-speed networking technology for Local Area Networks
          and Wide Area Networks.  It uses a fixed packet size and is
@@ -20,7 +19,7 @@ config ATM
          further details.
 
 config ATM_CLIP
-       tristate "Classical IP over ATM (EXPERIMENTAL)"
+       tristate "Classical IP over ATM"
        depends on ATM && INET
        help
          Classical IP over ATM for PVCs and SVCs, supporting InARP and
@@ -29,7 +28,7 @@ config ATM_CLIP
          (LANE)" below.
 
 config ATM_CLIP_NO_ICMP
-       bool "Do NOT send ICMP if no neighbour (EXPERIMENTAL)"
+       bool "Do NOT send ICMP if no neighbour"
        depends on ATM_CLIP
        help
          Normally, an "ICMP host unreachable" message is sent if a neighbour
@@ -39,7 +38,7 @@ config ATM_CLIP_NO_ICMP
          such neighbours are silently discarded instead.
 
 config ATM_LANE
-       tristate "LAN Emulation (LANE) support (EXPERIMENTAL)"
+       tristate "LAN Emulation (LANE) support"
        depends on ATM
        help
          LAN Emulation emulates services of existing LANs across an ATM
@@ -48,7 +47,7 @@ config ATM_LANE
          ELAN and Ethernet segments. You need LANE if you want to try MPOA.
 
 config ATM_MPOA
-       tristate "Multi-Protocol Over ATM (MPOA) support (EXPERIMENTAL)"
+       tristate "Multi-Protocol Over ATM (MPOA) support"
        depends on ATM && INET && ATM_LANE!=n
        help
          Multi-Protocol Over ATM allows ATM edge devices such as routers,
index 9ef07eda2c437be45c4fbba4a984c2ca04d929c9..1b88311f2130b57598bc13ee82dc74bab3cc3fc2 100644 (file)
@@ -9,13 +9,15 @@
 
 #define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
 
-static ssize_t show_type(struct class_device *cdev, char *buf)
+static ssize_t show_type(struct device *cdev,
+                        struct device_attribute *attr, char *buf)
 {
        struct atm_dev *adev = to_atm_dev(cdev);
        return sprintf(buf, "%s\n", adev->type);
 }
 
-static ssize_t show_address(struct class_device *cdev, char *buf)
+static ssize_t show_address(struct device *cdev,
+                           struct device_attribute *attr, char *buf)
 {
        char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
@@ -28,7 +30,8 @@ static ssize_t show_address(struct class_device *cdev, char *buf)
        return pos - buf;
 }
 
-static ssize_t show_atmaddress(struct class_device *cdev, char *buf)
+static ssize_t show_atmaddress(struct device *cdev,
+                              struct device_attribute *attr, char *buf)
 {
        unsigned long flags;
        char *pos = buf;
@@ -54,7 +57,8 @@ static ssize_t show_atmaddress(struct class_device *cdev, char *buf)
        return pos - buf;
 }
 
-static ssize_t show_carrier(struct class_device *cdev, char *buf)
+static ssize_t show_carrier(struct device *cdev,
+                           struct device_attribute *attr, char *buf)
 {
        char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
@@ -65,7 +69,8 @@ static ssize_t show_carrier(struct class_device *cdev, char *buf)
        return pos - buf;
 }
 
-static ssize_t show_link_rate(struct class_device *cdev, char *buf)
+static ssize_t show_link_rate(struct device *cdev,
+                             struct device_attribute *attr, char *buf)
 {
        char *pos = buf;
        struct atm_dev *adev = to_atm_dev(cdev);
@@ -90,22 +95,23 @@ static ssize_t show_link_rate(struct class_device *cdev, char *buf)
        return pos - buf;
 }
 
-static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static CLASS_DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL);
-static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
-static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
-static CLASS_DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL);
-
-static struct class_device_attribute *atm_attrs[] = {
-       &class_device_attr_atmaddress,
-       &class_device_attr_address,
-       &class_device_attr_carrier,
-       &class_device_attr_type,
-       &class_device_attr_link_rate,
+static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL);
+static DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
+static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL);
+
+static struct device_attribute *atm_attrs[] = {
+       &dev_attr_atmaddress,
+       &dev_attr_address,
+       &dev_attr_carrier,
+       &dev_attr_type,
+       &dev_attr_link_rate,
        NULL
 };
 
-static int atm_uevent(struct class_device *cdev, struct kobj_uevent_env *env)
+
+static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env)
 {
        struct atm_dev *adev;
 
@@ -122,7 +128,7 @@ static int atm_uevent(struct class_device *cdev, struct kobj_uevent_env *env)
        return 0;
 }
 
-static void atm_release(struct class_device *cdev)
+static void atm_release(struct device *cdev)
 {
        struct atm_dev *adev = to_atm_dev(cdev);
 
@@ -131,25 +137,25 @@ static void atm_release(struct class_device *cdev)
 
 static struct class atm_class = {
        .name           = "atm",
-       .release        = atm_release,
-       .uevent         = atm_uevent,
+       .dev_release    = atm_release,
+       .dev_uevent             = atm_uevent,
 };
 
 int atm_register_sysfs(struct atm_dev *adev)
 {
-       struct class_device *cdev = &adev->class_dev;
+       struct device *cdev = &adev->class_dev;
        int i, j, err;
 
        cdev->class = &atm_class;
-       class_set_devdata(cdev, adev);
+       dev_set_drvdata(cdev, adev);
 
-       snprintf(cdev->class_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number);
-       err = class_device_register(cdev);
+       snprintf(cdev->bus_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number);
+       err = device_register(cdev);
        if (err < 0)
                return err;
 
        for (i = 0; atm_attrs[i]; i++) {
-               err = class_device_create_file(cdev, atm_attrs[i]);
+               err = device_create_file(cdev, atm_attrs[i]);
                if (err)
                        goto err_out;
        }
@@ -158,16 +164,16 @@ int atm_register_sysfs(struct atm_dev *adev)
 
 err_out:
        for (j = 0; j < i; j++)
-               class_device_remove_file(cdev, atm_attrs[j]);
-       class_device_del(cdev);
+               device_remove_file(cdev, atm_attrs[j]);
+       device_del(cdev);
        return err;
 }
 
 void atm_unregister_sysfs(struct atm_dev *adev)
 {
-       struct class_device *cdev = &adev->class_dev;
+       struct device *cdev = &adev->class_dev;
 
-       class_device_del(cdev);
+       device_del(cdev);
 }
 
 int __init atm_sysfs_init(void)
index ba6428f204f9020209bc1dd693a5aa0e4727f4ac..574d9a9641764f0a0d354a5b871ac33572f3d89f 100644 (file)
@@ -1,8 +1,10 @@
 /*
-Experimental ethernet netdevice using ATM AAL5 as underlying carrier
-(RFC1483 obsoleted by RFC2684) for Linux 2.4
-Author: Marcell GAL, 2000, XDSL Ltd, Hungary
-*/
+ * Ethernet netdevice using ATM AAL5 as underlying carrier
+ * (RFC1483 obsoleted by RFC2684) for Linux
+ *
+ * Authors: Marcell GAL, 2000, XDSL Ltd, Hungary
+ *          Eric Kinzie, 2006-2007, US Naval Research Laboratory
+ */
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -39,21 +41,35 @@ static void skb_debug(const struct sk_buff *skb)
 #define skb_debug(skb) do {} while (0)
 #endif
 
+#define BR2684_ETHERTYPE_LEN   2
+#define BR2684_PAD_LEN         2
+
+#define LLC            0xaa, 0xaa, 0x03
+#define SNAP_BRIDGED   0x00, 0x80, 0xc2
+#define SNAP_ROUTED    0x00, 0x00, 0x00
+#define PID_ETHERNET   0x00, 0x07
+#define ETHERTYPE_IPV4 0x08, 0x00
+#define ETHERTYPE_IPV6 0x86, 0xdd
+#define PAD_BRIDGED    0x00, 0x00
+
+static unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 };
+static unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 };
 static unsigned char llc_oui_pid_pad[] =
-    { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 };
-#define PADLEN (2)
+                       { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED };
+static unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 };
+static unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 };
 
 enum br2684_encaps {
-       e_vc  = BR2684_ENCAPS_VC,
+       e_vc = BR2684_ENCAPS_VC,
        e_llc = BR2684_ENCAPS_LLC,
 };
 
 struct br2684_vcc {
-       struct atm_vcc  *atmvcc;
+       struct atm_vcc *atmvcc;
        struct net_device *device;
-       /* keep old push,pop functions for chaining */
-       void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
-       /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */
+       /* keep old push, pop functions for chaining */
+       void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb);
+       /* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */
        enum br2684_encaps encaps;
        struct list_head brvccs;
 #ifdef CONFIG_ATM_BR2684_IPFILTER
@@ -66,9 +82,10 @@ struct br2684_dev {
        struct net_device *net_dev;
        struct list_head br2684_devs;
        int number;
-       struct list_head brvccs; /* one device <=> one vcc (before xmas) */
+       struct list_head brvccs;        /* one device <=> one vcc (before xmas) */
        struct net_device_stats stats;
        int mac_was_set;
+       enum br2684_payload payload;
 };
 
 /*
@@ -84,7 +101,7 @@ static LIST_HEAD(br2684_devs);
 
 static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
 {
-       return (struct br2684_dev *) net_dev->priv;
+       return (struct br2684_dev *)net_dev->priv;
 }
 
 static inline struct net_device *list_entry_brdev(const struct list_head *le)
@@ -94,7 +111,7 @@ static inline struct net_device *list_entry_brdev(const struct list_head *le)
 
 static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc)
 {
-       return (struct br2684_vcc *) (atmvcc->user_back);
+       return (struct br2684_vcc *)(atmvcc->user_back);
 }
 
 static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le)
@@ -132,10 +149,11 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
  * otherwise false
  */
 static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
-       struct br2684_vcc *brvcc)
+                          struct br2684_vcc *brvcc)
 {
        struct atm_vcc *atmvcc;
        int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
+
        if (skb_headroom(skb) < minheadroom) {
                struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
                brvcc->copies_needed++;
@@ -146,23 +164,48 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
                }
                skb = skb2;
        }
-       skb_push(skb, minheadroom);
-       if (brvcc->encaps == e_llc)
-               skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10);
-       else
-               memset(skb->data, 0, 2);
+
+       if (brvcc->encaps == e_llc) {
+               if (brdev->payload == p_bridged) {
+                       skb_push(skb, sizeof(llc_oui_pid_pad));
+                       skb_copy_to_linear_data(skb, llc_oui_pid_pad,
+                                               sizeof(llc_oui_pid_pad));
+               } else if (brdev->payload == p_routed) {
+                       unsigned short prot = ntohs(skb->protocol);
+
+                       skb_push(skb, sizeof(llc_oui_ipv4));
+                       switch (prot) {
+                       case ETH_P_IP:
+                               skb_copy_to_linear_data(skb, llc_oui_ipv4,
+                                                       sizeof(llc_oui_ipv4));
+                               break;
+                       case ETH_P_IPV6:
+                               skb_copy_to_linear_data(skb, llc_oui_ipv6,
+                                                       sizeof(llc_oui_ipv6));
+                               break;
+                       default:
+                               dev_kfree_skb(skb);
+                               return 0;
+                       }
+               }
+       } else {
+               skb_push(skb, 2);
+               if (brdev->payload == p_bridged)
+                       memset(skb->data, 0, 2);
+       }
        skb_debug(skb);
 
        ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
        pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
        if (!atm_may_send(atmvcc, skb->truesize)) {
-               /* we free this here for now, because we cannot know in a higher
-                       layer whether the skb point it supplied wasn't freed yet.
-                       now, it always is.
-               */
+               /*
+                * We free this here for now, because we cannot know in a higher
+                * layer whether the skb pointer it supplied wasn't freed yet.
+                * Now, it always is.
+                */
                dev_kfree_skb(skb);
                return 0;
-               }
+       }
        atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc);
        ATM_SKB(skb)->atm_options = atmvcc->atm_options;
        brdev->stats.tx_packets++;
@@ -172,10 +215,9 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
 }
 
 static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb,
-       struct br2684_dev *brdev)
+                                                  struct br2684_dev *brdev)
 {
-       return list_empty(&brdev->brvccs) ? NULL :
-           list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
+       return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next);        /* 1 vcc/dev right now */
 }
 
 static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -199,11 +241,10 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
                /*
                 * We should probably use netif_*_queue() here, but that
                 * involves added complication.  We need to walk before
-                * we can run
+                * we can run.
+                *
+                * Don't free here! this pointer might be no longer valid!
                 */
-               /* don't free here! this pointer might be no longer valid!
-               dev_kfree_skb(skb);
-               */
                brdev->stats.tx_errors++;
                brdev->stats.tx_fifo_errors++;
        }
@@ -217,12 +258,11 @@ static struct net_device_stats *br2684_get_stats(struct net_device *dev)
        return &BRPRIV(dev)->stats;
 }
 
-
 /*
  * We remember when the MAC gets set, so we don't override it later with
  * the ESI of the ATM card of the first VC
  */
-static int (*my_eth_mac_addr)(struct net_device *, void *);
+static int (*my_eth_mac_addr) (struct net_device *, void *);
 static int br2684_mac_addr(struct net_device *dev, void *p)
 {
        int err = my_eth_mac_addr(dev, p);
@@ -233,7 +273,7 @@ static int br2684_mac_addr(struct net_device *dev, void *p)
 
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 /* this IOCTL is experimental. */
-static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
+static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
 {
        struct br2684_vcc *brvcc;
        struct br2684_filter_set fs;
@@ -243,13 +283,12 @@ static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
        if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
                /*
                 * This is really a per-vcc thing, but we can also search
-                * by device
+                * by device.
                 */
                struct br2684_dev *brdev;
                read_lock(&devs_lock);
                brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
-               if (brdev == NULL || list_empty(&brdev->brvccs) ||
-                   brdev->brvccs.next != brdev->brvccs.prev)  /* >1 VCC */
+               if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev)    /* >1 VCC */
                        brvcc = NULL;
                else
                        brvcc = list_entry_brvcc(brdev->brvccs.next);
@@ -267,15 +306,16 @@ static inline int
 packet_fails_filter(__be16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
 {
        if (brvcc->filter.netmask == 0)
-               return 0;                       /* no filter in place */
+               return 0;       /* no filter in place */
        if (type == htons(ETH_P_IP) &&
-           (((struct iphdr *) (skb->data))->daddr & brvcc->filter.
+           (((struct iphdr *)(skb->data))->daddr & brvcc->filter.
             netmask) == brvcc->filter.prefix)
                return 0;
        if (type == htons(ETH_P_ARP))
                return 0;
-       /* TODO: we should probably filter ARPs too.. don't want to have
-        *   them returning values that don't make sense, or is that ok?
+       /*
+        * TODO: we should probably filter ARPs too.. don't want to have
+        * them returning values that don't make sense, or is that ok?
         */
        return 1;               /* drop */
 }
@@ -299,7 +339,6 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
        struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
        struct net_device *net_dev = brvcc->device;
        struct br2684_dev *brdev = BRPRIV(net_dev);
-       int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN;
 
        pr_debug("br2684_push\n");
 
@@ -320,35 +359,58 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
        atm_return(atmvcc, skb->truesize);
        pr_debug("skb from brdev %p\n", brdev);
        if (brvcc->encaps == e_llc) {
-               /* let us waste some time for checking the encapsulation.
-                  Note, that only 7 char is checked so frames with a valid FCS
-                  are also accepted (but FCS is not checked of course) */
-               if (memcmp(skb->data, llc_oui_pid_pad, 7)) {
+
+               if (skb->len > 7 && skb->data[7] == 0x01)
+                       __skb_trim(skb, skb->len - 4);
+
+               /* accept packets that have "ipv[46]" in the snap header */
+               if ((skb->len >= (sizeof(llc_oui_ipv4)))
+                   &&
+                   (memcmp
+                    (skb->data, llc_oui_ipv4,
+                     sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
+                       if (memcmp
+                           (skb->data + 6, ethertype_ipv6,
+                            sizeof(ethertype_ipv6)) == 0)
+                               skb->protocol = __constant_htons(ETH_P_IPV6);
+                       else if (memcmp
+                                (skb->data + 6, ethertype_ipv4,
+                                 sizeof(ethertype_ipv4)) == 0)
+                               skb->protocol = __constant_htons(ETH_P_IP);
+                       else {
+                               brdev->stats.rx_errors++;
+                               dev_kfree_skb(skb);
+                               return;
+                       }
+                       skb_pull(skb, sizeof(llc_oui_ipv4));
+                       skb_reset_network_header(skb);
+                       skb->pkt_type = PACKET_HOST;
+                       /*
+                        * Let us waste some time for checking the encapsulation.
+                        * Note, that only 7 char is checked so frames with a valid FCS
+                        * are also accepted (but FCS is not checked of course).
+                        */
+               } else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
+                          (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
+                       skb_pull(skb, sizeof(llc_oui_pid_pad));
+                       skb->protocol = eth_type_trans(skb, net_dev);
+               } else {
                        brdev->stats.rx_errors++;
                        dev_kfree_skb(skb);
                        return;
                }
 
-               /* Strip FCS if present */
-               if (skb->len > 7 && skb->data[7] == 0x01)
-                       __skb_trim(skb, skb->len - 4);
        } else {
-               plen = PADLEN + ETH_HLEN;       /* pad, dstmac,srcmac, ethtype */
                /* first 2 chars should be 0 */
                if (*((u16 *) (skb->data)) != 0) {
                        brdev->stats.rx_errors++;
                        dev_kfree_skb(skb);
                        return;
                }
-       }
-       if (skb->len < plen) {
-               brdev->stats.rx_errors++;
-               dev_kfree_skb(skb);     /* dev_ not needed? */
-               return;
+               skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN);       /* pad, dstmac, srcmac, ethtype */
+               skb->protocol = eth_type_trans(skb, net_dev);
        }
 
-       skb_pull(skb, plen - ETH_HLEN);
-       skb->protocol = eth_type_trans(skb, net_dev);
 #ifdef CONFIG_ATM_BR2684_IPFILTER
        if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
                brdev->stats.rx_dropped++;
@@ -372,11 +434,12 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
        netif_rx(skb);
 }
 
-static int br2684_regvcc(struct atm_vcc *atmvcc, void __user *arg)
+/*
+ * Assign a vcc to a dev
+ * Note: we do not have explicit unassign, but look at _push()
+ */
+static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
 {
-/* assign a vcc to a dev
-Note: we do not have explicit unassign, but look at _push()
-*/
        int err;
        struct br2684_vcc *brvcc;
        struct sk_buff *skb;
@@ -395,7 +458,7 @@ Note: we do not have explicit unassign, but look at _push()
        net_dev = br2684_find_dev(&be.ifspec);
        if (net_dev == NULL) {
                printk(KERN_ERR
-                   "br2684: tried to attach to non-existant device\n");
+                      "br2684: tried to attach to non-existant device\n");
                err = -ENXIO;
                goto error;
        }
@@ -411,13 +474,15 @@ Note: we do not have explicit unassign, but look at _push()
        }
        if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO ||
            be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps !=
-           BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) ||
-           be.min_size != 0) {
+                                                              BR2684_ENCAPS_VC
+                                                              && be.encaps !=
+                                                              BR2684_ENCAPS_LLC)
+           || be.min_size != 0) {
                err = -EINVAL;
                goto error;
        }
-       pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps,
-               brvcc);
+       pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc,
+                be.encaps, brvcc);
        if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
                unsigned char *esi = atmvcc->dev->esi;
                if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
@@ -430,7 +495,7 @@ Note: we do not have explicit unassign, but look at _push()
        brvcc->device = net_dev;
        brvcc->atmvcc = atmvcc;
        atmvcc->user_back = brvcc;
-       brvcc->encaps = (enum br2684_encaps) be.encaps;
+       brvcc->encaps = (enum br2684_encaps)be.encaps;
        brvcc->old_push = atmvcc->push;
        barrier();
        atmvcc->push = br2684_push;
@@ -461,7 +526,7 @@ Note: we do not have explicit unassign, but look at _push()
        }
        __module_get(THIS_MODULE);
        return 0;
-    error:
+      error:
        write_unlock_irq(&devs_lock);
        kfree(brvcc);
        return err;
@@ -482,25 +547,52 @@ static void br2684_setup(struct net_device *netdev)
        INIT_LIST_HEAD(&brdev->brvccs);
 }
 
-static int br2684_create(void __user *arg)
+static void br2684_setup_routed(struct net_device *netdev)
+{
+       struct br2684_dev *brdev = BRPRIV(netdev);
+       brdev->net_dev = netdev;
+
+       netdev->hard_header_len = 0;
+       my_eth_mac_addr = netdev->set_mac_address;
+       netdev->set_mac_address = br2684_mac_addr;
+       netdev->hard_start_xmit = br2684_start_xmit;
+       netdev->get_stats = br2684_get_stats;
+       netdev->addr_len = 0;
+       netdev->mtu = 1500;
+       netdev->type = ARPHRD_PPP;
+       netdev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
+       netdev->tx_queue_len = 100;
+       INIT_LIST_HEAD(&brdev->brvccs);
+}
+
+static int br2684_create(void __user * arg)
 {
        int err;
        struct net_device *netdev;
        struct br2684_dev *brdev;
        struct atm_newif_br2684 ni;
+       enum br2684_payload payload;
 
        pr_debug("br2684_create\n");
 
        if (copy_from_user(&ni, arg, sizeof ni)) {
                return -EFAULT;
        }
+
+       if (ni.media & BR2684_FLAG_ROUTED)
+               payload = p_routed;
+       else
+               payload = p_bridged;
+       ni.media &= 0xffff;     /* strip flags */
+
        if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
                return -EINVAL;
        }
 
        netdev = alloc_netdev(sizeof(struct br2684_dev),
                              ni.ifname[0] ? ni.ifname : "nas%d",
-                             br2684_setup);
+                             (payload == p_routed) ?
+                             br2684_setup_routed : br2684_setup);
        if (!netdev)
                return -ENOMEM;
 
@@ -516,6 +608,7 @@ static int br2684_create(void __user *arg)
        }
 
        write_lock_irq(&devs_lock);
+       brdev->payload = payload;
        brdev->number = list_empty(&br2684_devs) ? 1 :
            BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
        list_add_tail(&brdev->br2684_devs, &br2684_devs);
@@ -528,16 +621,16 @@ static int br2684_create(void __user *arg)
  * -ENOIOCTLCMD for any unrecognized ioctl
  */
 static int br2684_ioctl(struct socket *sock, unsigned int cmd,
-       unsigned long arg)
+                       unsigned long arg)
 {
        struct atm_vcc *atmvcc = ATM_SD(sock);
        void __user *argp = (void __user *)arg;
+       atm_backend_t b;
 
        int err;
-       switch(cmd) {
+       switch (cmd) {
        case ATM_SETBACKEND:
-       case ATM_NEWBACKENDIF: {
-               atm_backend_t b;
+       case ATM_NEWBACKENDIF:
                err = get_user(b, (atm_backend_t __user *) argp);
                if (err)
                        return -EFAULT;
@@ -549,7 +642,6 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
                        return br2684_regvcc(atmvcc, argp);
                else
                        return br2684_create(argp);
-               }
 #ifdef CONFIG_ATM_BR2684_IPFILTER
        case BR2684_SETFILT:
                if (atmvcc->push != br2684_push)
@@ -557,6 +649,7 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
                err = br2684_setfilt(atmvcc, argp);
+
                return err;
 #endif /* CONFIG_ATM_BR2684_IPFILTER */
        }
@@ -564,24 +657,25 @@ static int br2684_ioctl(struct socket *sock, unsigned int cmd,
 }
 
 static struct atm_ioctl br2684_ioctl_ops = {
-       .owner  = THIS_MODULE,
-       .ioctl  = br2684_ioctl,
+       .owner = THIS_MODULE,
+       .ioctl = br2684_ioctl,
 };
 
-
 #ifdef CONFIG_PROC_FS
-static void *br2684_seq_start(struct seq_file *seq, loff_t *pos)
+static void *br2684_seq_start(struct seq_file *seq, loff_t * pos)
+       __acquires(devs_lock)
 {
        read_lock(&devs_lock);
        return seq_list_start(&br2684_devs, *pos);
 }
 
-static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t * pos)
 {
        return seq_list_next(v, &br2684_devs, pos);
 }
 
 static void br2684_seq_stop(struct seq_file *seq, void *v)
+       __releases(devs_lock)
 {
        read_unlock(&devs_lock);
 }
@@ -589,7 +683,7 @@ static void br2684_seq_stop(struct seq_file *seq, void *v)
 static int br2684_seq_show(struct seq_file *seq, void *v)
 {
        const struct br2684_dev *brdev = list_entry(v, struct br2684_dev,
-                       br2684_devs);
+                                                   br2684_devs);
        const struct net_device *net_dev = brdev->net_dev;
        const struct br2684_vcc *brvcc;
        DECLARE_MAC_BUF(mac);
@@ -601,21 +695,19 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
                   brdev->mac_was_set ? "set" : "auto");
 
        list_for_each_entry(brvcc, &brdev->brvccs, brvccs) {
-               seq_printf(seq, "  vcc %d.%d.%d: encaps=%s"
-                                   ", failed copies %u/%u"
-                                   "\n", brvcc->atmvcc->dev->number,
-                                   brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
-                                   (brvcc->encaps == e_llc) ? "LLC" : "VC"
-                                   , brvcc->copies_failed
-                                   , brvcc->copies_needed
-                                   );
+               seq_printf(seq, "  vcc %d.%d.%d: encaps=%s payload=%s"
+                          ", failed copies %u/%u"
+                          "\n", brvcc->atmvcc->dev->number,
+                          brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
+                          (brvcc->encaps == e_llc) ? "LLC" : "VC",
+                          (brdev->payload == p_bridged) ? "bridged" : "routed",
+                          brvcc->copies_failed, brvcc->copies_needed);
 #ifdef CONFIG_ATM_BR2684_IPFILTER
 #define b1(var, byte)  ((u8 *) &brvcc->filter.var)[byte]
 #define bs(var)                b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
-                       if (brvcc->filter.netmask != 0)
-                               seq_printf(seq, "    filter=%d.%d.%d.%d/"
-                                               "%d.%d.%d.%d\n",
-                                               bs(prefix), bs(netmask));
+               if (brvcc->filter.netmask != 0)
+                       seq_printf(seq, "    filter=%d.%d.%d.%d/"
+                                  "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
 #undef bs
 #undef b1
 #endif /* CONFIG_ATM_BR2684_IPFILTER */
@@ -625,9 +717,9 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
 
 static const struct seq_operations br2684_seq_ops = {
        .start = br2684_seq_start,
-       .next  = br2684_seq_next,
-       .stop  = br2684_seq_stop,
-       .show  = br2684_seq_show,
+       .next = br2684_seq_next,
+       .stop = br2684_seq_stop,
+       .show = br2684_seq_show,
 };
 
 static int br2684_proc_open(struct inode *inode, struct file *file)
@@ -636,15 +728,15 @@ static int br2684_proc_open(struct inode *inode, struct file *file)
 }
 
 static const struct file_operations br2684_proc_ops = {
-       .owner   = THIS_MODULE,
-       .open    = br2684_proc_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
+       .owner = THIS_MODULE,
+       .open = br2684_proc_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
        .release = seq_release,
 };
 
 extern struct proc_dir_entry *atm_proc_root;   /* from proc.c */
-#endif
+#endif /* CONFIG_PROC_FS */
 
 static int __init br2684_init(void)
 {
index 741742f0079715604430491a71de39288e429ff0..86b885ec1cbd4b6cf992f2332bab5a0bd4c445a3 100644 (file)
@@ -285,7 +285,7 @@ static int clip_constructor(struct neighbour *neigh)
        struct neigh_parms *parms;
 
        pr_debug("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
-       neigh->type = inet_addr_type(entry->ip);
+       neigh->type = inet_addr_type(&init_net, entry->ip);
        if (neigh->type != RTN_UNICAST)
                return -EINVAL;
 
@@ -534,7 +534,7 @@ static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
                unlink_clip_vcc(clip_vcc);
                return 0;
        }
-       error = ip_route_output_key(&rt, &fl);
+       error = ip_route_output_key(&init_net, &rt, &fl);
        if (error)
                return error;
        neigh = __neigh_lookup(&clip_tbl, &ip, rt->u.dst.dev, 1);
@@ -903,6 +903,8 @@ static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
 
 static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
 {
+       struct clip_seq_state *state = seq->private;
+       state->ns.neigh_sub_iter = clip_seq_sub_iter;
        return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
 }
 
@@ -932,36 +934,15 @@ static const struct seq_operations arp_seq_ops = {
 
 static int arp_seq_open(struct inode *inode, struct file *file)
 {
-       struct clip_seq_state *state;
-       struct seq_file *seq;
-       int rc = -EAGAIN;
-
-       state = kzalloc(sizeof(*state), GFP_KERNEL);
-       if (!state) {
-               rc = -ENOMEM;
-               goto out_kfree;
-       }
-       state->ns.neigh_sub_iter = clip_seq_sub_iter;
-
-       rc = seq_open(file, &arp_seq_ops);
-       if (rc)
-               goto out_kfree;
-
-       seq = file->private_data;
-       seq->private = state;
-out:
-       return rc;
-
-out_kfree:
-       kfree(state);
-       goto out;
+       return seq_open_net(inode, file, &arp_seq_ops,
+                           sizeof(struct clip_seq_state));
 }
 
 static const struct file_operations arp_seq_fops = {
        .open           = arp_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
        .owner          = THIS_MODULE
 };
 #endif
index eba09a04f6bf446f7922ca6b2a36e4b976993143..c865517ba4499578052b7461d2fa7cd0f59b5556 100644 (file)
@@ -113,7 +113,7 @@ static void vcc_write_space(struct sock *sk)
                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                        wake_up_interruptible(sk->sk_sleep);
 
-               sk_wake_async(sk, 2, POLL_OUT);
+               sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        }
 
        read_unlock(&sk->sk_callback_lock);
index 7eb1b21a0e9415d0730e4942d9bb129f88067b2a..1a8c4c6c0cd054d928fd974ec33094b8586ec305 100644 (file)
@@ -176,7 +176,7 @@ static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
 static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
 {
        struct trh_hdr *trh;
-       int riflen, num_rdsc;
+       unsigned int riflen, num_rdsc;
 
        trh = (struct trh_hdr *)packet;
        if (trh->daddr[0] & (uint8_t) 0x80)
@@ -1789,9 +1789,8 @@ static struct lec_arp_table *make_entry(struct lec_priv *priv,
        }
        memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
        INIT_HLIST_NODE(&to_return->next);
-       init_timer(&to_return->timer);
-       to_return->timer.function = lec_arp_expire_arp;
-       to_return->timer.data = (unsigned long)to_return;
+       setup_timer(&to_return->timer, lec_arp_expire_arp,
+                       (unsigned long)to_return);
        to_return->last_used = jiffies;
        to_return->priv = priv;
        skb_queue_head_init(&to_return->tx_wait);
index 5d9d5ffba145d5295ff9dab749739547376ca0ca..49125110bb8b0910c777dcb2f8402f9271f294c2 100644 (file)
@@ -142,6 +142,7 @@ static int vcc_seq_release(struct inode *inode, struct file *file)
 }
 
 static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(vcc_sklist_lock)
 {
        struct vcc_state *state = seq->private;
        loff_t left = *pos;
@@ -152,6 +153,7 @@ static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
 }
 
 static void vcc_seq_stop(struct seq_file *seq, void *v)
+       __releases(vcc_sklist_lock)
 {
        read_unlock(&vcc_sklist_lock);
 }
@@ -476,7 +478,7 @@ static void atm_proc_dirs_remove(void)
                if (e->dirent)
                        remove_proc_entry(e->name, atm_proc_root);
        }
-       remove_proc_entry("atm", init_net.proc_net);
+       proc_net_remove(&init_net, "atm");
 }
 
 int __init atm_proc_init(void)
@@ -484,7 +486,7 @@ int __init atm_proc_init(void)
        static struct atm_proc_entry *e;
        int ret;
 
-       atm_proc_root = proc_mkdir("atm", init_net.proc_net);
+       atm_proc_root = proc_net_mkdir(&init_net, "atm", init_net.proc_net);
        if (!atm_proc_root)
                goto err_out;
        for (e = atm_proc_ents; e->name; e++) {
index b4725ff317c06a648ef225744651da76412b7068..1bc0e85f04a5112afbfa5be6140d59ba4f38f2b0 100644 (file)
@@ -330,10 +330,9 @@ void ax25_destroy_socket(ax25_cb *ax25)
                if (atomic_read(&ax25->sk->sk_wmem_alloc) ||
                    atomic_read(&ax25->sk->sk_rmem_alloc)) {
                        /* Defer: outstanding buffers */
-                       init_timer(&ax25->dtimer);
+                       setup_timer(&ax25->dtimer, ax25_destroy_timer,
+                                       (unsigned long)ax25);
                        ax25->dtimer.expires  = jiffies + 2 * HZ;
-                       ax25->dtimer.function = ax25_destroy_timer;
-                       ax25->dtimer.data     = (unsigned long)ax25;
                        add_timer(&ax25->dtimer);
                } else {
                        struct sock *sk=ax25->sk;
@@ -571,7 +570,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
                        res = -EINVAL;
                        break;
                }
-               ax25->rtt = (opt * HZ) / 2;
+               ax25->rtt = (opt * HZ) >> 1;
                ax25->t1  = opt * HZ;
                break;
 
@@ -1864,6 +1863,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 #ifdef CONFIG_PROC_FS
 
 static void *ax25_info_start(struct seq_file *seq, loff_t *pos)
+       __acquires(ax25_list_lock)
 {
        struct ax25_cb *ax25;
        struct hlist_node *node;
@@ -1887,6 +1887,7 @@ static void *ax25_info_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ax25_info_stop(struct seq_file *seq, void *v)
+       __releases(ax25_list_lock)
 {
        spin_unlock_bh(&ax25_list_lock);
 }
index 4f44185955c790403435227d598d7c575d4880ea..c4e3b025d21c20c824d6b0b6b5fb42105e713360 100644 (file)
@@ -130,7 +130,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
                 */
                if (sk != NULL) {
                        if (atomic_read(&sk->sk_rmem_alloc) <
-                           (sk->sk_rcvbuf / 2) &&
+                           (sk->sk_rcvbuf >> 1) &&
                            (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
                                ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
                                ax25->condition &= ~AX25_COND_ACK_PENDING;
index 9ecf6f1df863078c3a238a079787123a1df5f437..38c7f3087ec3d17c1fc8a5ff48be10cb9dedda60 100644 (file)
@@ -249,6 +249,7 @@ int ax25_rt_ioctl(unsigned int cmd, void __user *arg)
 #ifdef CONFIG_PROC_FS
 
 static void *ax25_rt_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(ax25_route_lock)
 {
        struct ax25_route *ax25_rt;
        int i = 1;
@@ -274,6 +275,7 @@ static void *ax25_rt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
+       __releases(ax25_route_lock)
 {
        read_unlock(&ax25_route_lock);
 }
index f2f6918ac9bb69cae0c93f084b5955aed97f460c..96e4b9273250918b4a60fdcc9ccce00b79090827 100644 (file)
@@ -32,7 +32,7 @@
 
 void ax25_std_heartbeat_expiry(ax25_cb *ax25)
 {
-       struct sock *sk=ax25->sk;
+       struct sock *sk = ax25->sk;
 
        if (sk)
                bh_lock_sock(sk);
@@ -62,7 +62,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
                 */
                if (sk != NULL) {
                        if (atomic_read(&sk->sk_rmem_alloc) <
-                           (sk->sk_rcvbuf / 2) &&
+                           (sk->sk_rcvbuf >> 1) &&
                            (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
                                ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
                                ax25->condition &= ~AX25_COND_ACK_PENDING;
index ce0b13d44385fad3c588a0ee7087ee58d6189a2e..5f4eb73fb9d344f35fc338857444cd1d01abbb1e 100644 (file)
  *     Callsign/UID mapper. This is in kernel space for security on multi-amateur machines.
  */
 
-HLIST_HEAD(ax25_uid_list);
+static HLIST_HEAD(ax25_uid_list);
 static DEFINE_RWLOCK(ax25_uid_lock);
 
-int ax25_uid_policy = 0;
+int ax25_uid_policy;
 
 EXPORT_SYMBOL(ax25_uid_policy);
 
@@ -144,6 +144,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
 #ifdef CONFIG_PROC_FS
 
 static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(ax25_uid_lock)
 {
        struct ax25_uid_assoc *pt;
        struct hlist_node *node;
@@ -167,6 +168,7 @@ static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
+       __releases(ax25_uid_lock)
 {
        read_unlock(&ax25_uid_lock);
 }
index 443a8367663807c4265e002268b88e9be0acf221..f597987b242439556c66cc83cc93cb8373ab7a30 100644 (file)
@@ -31,25 +31,11 @@ static struct ctl_table_header *ax25_table_header;
 static ctl_table *ax25_table;
 static int ax25_table_size;
 
-static ctl_table ax25_dir_table[] = {
-       {
-               .ctl_name       = NET_AX25,
-               .procname       = "ax25",
-               .mode           = 0555,
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ax25_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ax25_dir_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path ax25_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ax25", .ctl_name = NET_AX25, },
+       { }
 };
-
 static const ctl_table ax25_param_table[] = {
        {
                .ctl_name       = NET_AX25_IP_DEFAULT_MODE,
@@ -243,9 +229,7 @@ void ax25_register_sysctl(void)
        }
        spin_unlock_bh(&ax25_dev_lock);
 
-       ax25_dir_table[0].child = ax25_table;
-
-       ax25_table_header = register_sysctl_table(ax25_root_table);
+       ax25_table_header = register_sysctl_paths(ax25_path, ax25_table);
 }
 
 void ax25_unregister_sysctl(void)
@@ -253,7 +237,6 @@ void ax25_unregister_sysctl(void)
        ctl_table *p;
        unregister_sysctl_table(ax25_table_header);
 
-       ax25_dir_table[0].child = NULL;
        for (p = ax25_table; p->ctl_name; p++)
                kfree(p->child);
        kfree(ax25_table);
index 9ebd3c64474d916480506d20e2db8be6f1b30182..81065e548a1f50d4c4a37dd9c4c54f52726d7fdd 100644 (file)
@@ -94,7 +94,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                        return err;
 
                if (nsock->sk->sk_state != BT_CONNECTED) {
-                       fput(nsock->file);
+                       sockfd_put(nsock);
                        return -EBADFD;
                }
 
@@ -103,7 +103,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                        if (copy_to_user(argp, &ca, sizeof(ca)))
                                err = -EFAULT;
                } else
-                       fput(nsock->file);
+                       sockfd_put(nsock);
 
                return err;
 
index 783edab12ce82c024610b9dd3b91b9ee9f21ca3e..8c7f7bc4e0bacbbed7ef05daae6aacb0af34a8e3 100644 (file)
@@ -88,7 +88,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                        return err;
 
                if (nsock->sk->sk_state != BT_CONNECTED) {
-                       fput(nsock->file);
+                       sockfd_put(nsock);
                        return -EBADFD;
                }
 
@@ -97,7 +97,7 @@ static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                        if (copy_to_user(argp, &ca, sizeof(ca)))
                                err = -EFAULT;
                } else
-                       fput(nsock->file);
+                       sockfd_put(nsock);
 
                return err;
 
index 34d1a3c822bf54b4cdef61add3ab243ac9c8fd13..5fc7be206f629972ea32543079a7972bd02bd156 100644 (file)
@@ -208,13 +208,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 
        skb_queue_head_init(&conn->data_q);
 
-       init_timer(&conn->disc_timer);
-       conn->disc_timer.function = hci_conn_timeout;
-       conn->disc_timer.data = (unsigned long) conn;
-
-       init_timer(&conn->idle_timer);
-       conn->idle_timer.function = hci_conn_idle;
-       conn->idle_timer.data = (unsigned long) conn;
+       setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
+       setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
 
        atomic_set(&conn->refcnt, 0);
 
index 4bbacddeb49d4d4425177cf972b921bd195ec92f..782a22602b86cb9bca1838ee7758adbfcd0984f6 100644 (file)
@@ -811,10 +811,7 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
        session->intr_sock = intr_sock;
        session->state     = BT_CONNECTED;
 
-       init_timer(&session->timer);
-
-       session->timer.function = hidp_idle_timeout;
-       session->timer.data     = (unsigned long) session;
+       setup_timer(&session->timer, hidp_idle_timeout, (unsigned long)session);
 
        skb_queue_head_init(&session->ctrl_transmit);
        skb_queue_head_init(&session->intr_transmit);
index 3292b956a7c491267d023ae5406561447a639810..f4dd02ca9a96d9acd1c73872aac795b6de68575b 100644 (file)
@@ -86,13 +86,13 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
 
                isock = sockfd_lookup(ca.intr_sock, &err);
                if (!isock) {
-                       fput(csock->file);
+                       sockfd_put(csock);
                        return err;
                }
 
                if (csock->sk->sk_state != BT_CONNECTED || isock->sk->sk_state != BT_CONNECTED) {
-                       fput(csock->file);
-                       fput(isock->file);
+                       sockfd_put(csock);
+                       sockfd_put(isock);
                        return -EBADFD;
                }
 
@@ -101,8 +101,8 @@ static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
                        if (copy_to_user(argp, &ca, sizeof(ca)))
                                err = -EFAULT;
                } else {
-                       fput(csock->file);
-                       fput(isock->file);
+                       sockfd_put(csock);
+                       sockfd_put(isock);
                }
 
                return err;
index 477e052b17b5d57bdbb820f9b5b98252b13f17b9..a8811c0a0ceaf436f74002397041765e5757f7a3 100644 (file)
@@ -99,13 +99,6 @@ static void l2cap_sock_clear_timer(struct sock *sk)
        sk_stop_timer(sk, &sk->sk_timer);
 }
 
-static void l2cap_sock_init_timer(struct sock *sk)
-{
-       init_timer(&sk->sk_timer);
-       sk->sk_timer.function = l2cap_sock_timeout;
-       sk->sk_timer.data = (unsigned long)sk;
-}
-
 /* ---- L2CAP channels ---- */
 static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
 {
@@ -395,9 +388,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 
        conn->feat_mask = 0;
 
-       init_timer(&conn->info_timer);
-       conn->info_timer.function = l2cap_info_timeout;
-       conn->info_timer.data = (unsigned long) conn;
+       setup_timer(&conn->info_timer, l2cap_info_timeout, (unsigned long)conn);
 
        spin_lock_init(&conn->lock);
        rwlock_init(&conn->chan_list.lock);
@@ -622,7 +613,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
        sk->sk_protocol = proto;
        sk->sk_state    = BT_OPEN;
 
-       l2cap_sock_init_timer(sk);
+       setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long)sk);
 
        bt_sock_link(&l2cap_sk_list, sk);
        return sk;
index e7ac6ba7ecab0391829956d3bc97ad756a2c3800..d3e4e1877e6a53bb06a339b54be593128ad05763 100644 (file)
@@ -279,9 +279,7 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
        if (!d)
                return NULL;
 
-       init_timer(&d->timer);
-       d->timer.function = rfcomm_dlc_timeout;
-       d->timer.data = (unsigned long) d;
+       setup_timer(&d->timer, rfcomm_dlc_timeout, (unsigned long)d);
 
        skb_queue_head_init(&d->tx_queue);
        spin_lock_init(&d->lock);
index 93ad1aae3f38dece58f5820002216c18942b6b75..b91d3c81a73c58981ab105dd952bcafc65df35c6 100644 (file)
@@ -97,13 +97,6 @@ static void sco_sock_clear_timer(struct sock *sk)
        sk_stop_timer(sk, &sk->sk_timer);
 }
 
-static void sco_sock_init_timer(struct sock *sk)
-{
-       init_timer(&sk->sk_timer);
-       sk->sk_timer.function = sco_sock_timeout;
-       sk->sk_timer.data = (unsigned long)sk;
-}
-
 /* ---- SCO connections ---- */
 static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
 {
@@ -436,7 +429,7 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro
        sk->sk_protocol = proto;
        sk->sk_state    = BT_OPEN;
 
-       sco_sock_init_timer(sk);
+       setup_timer(&sk->sk_timer, sco_sock_timeout, (unsigned long)sk);
 
        bt_sock_link(&sco_sk_list, sk);
        return sk;
index 0ee79a726d91f3159e293282013dd7fad395760e..255c00f60ce7a3a14a5b0089e440d2edf46403e1 100644 (file)
@@ -109,7 +109,7 @@ static inline int is_link_local(const unsigned char *dest)
 {
        __be16 *a = (__be16 *)dest;
        static const __be16 *b = (const __be16 *)br_group_address;
-       static const __be16 m = __constant_cpu_to_be16(0xfff0);
+       static const __be16 m = cpu_to_be16(0xfff0);
 
        return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
 }
index 9f78a69d6b8b570ff20e0be70d7a68471cc45d4c..80014bab81b0afdb43b02ea5724afe24e747a546 100644 (file)
@@ -353,7 +353,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
                        if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
                                goto free_skb;
 
-                       if (!ip_route_output_key(&rt, &fl)) {
+                       if (!ip_route_output_key(&init_net, &rt, &fl)) {
                                /* - Bridged-and-DNAT'ed traffic doesn't
                                 *   require ip_forwarding. */
                                if (((struct dst_entry *)rt)->dev == dev) {
@@ -511,7 +511,7 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
        if (!setup_pre_routing(skb))
                return NF_DROP;
 
-       NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                br_nf_pre_routing_finish_ipv6);
 
        return NF_STOLEN;
@@ -584,7 +584,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
                return NF_DROP;
        store_orig_dstaddr(skb);
 
-       NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                br_nf_pre_routing_finish);
 
        return NF_STOLEN;
@@ -681,7 +681,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
        nf_bridge->mask |= BRNF_BRIDGED;
        nf_bridge->physoutdev = skb->dev;
 
-       NF_HOOK(pf, NF_IP_FORWARD, skb, bridge_parent(in), parent,
+       NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
                br_nf_forward_finish);
 
        return NF_STOLEN;
@@ -832,7 +832,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
        if (nf_bridge->netoutdev)
                realoutdev = nf_bridge->netoutdev;
 #endif
-       NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
+       NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
                br_nf_dev_queue_xmit);
 
        return NF_STOLEN;
@@ -871,7 +871,7 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
  * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
  * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
  * ip_refrag() can return NF_STOLEN. */
-static struct nf_hook_ops br_nf_ops[] = {
+static struct nf_hook_ops br_nf_ops[] __read_mostly = {
        { .hook = br_nf_pre_routing,
          .owner = THIS_MODULE,
          .pf = PF_BRIDGE,
@@ -905,12 +905,12 @@ static struct nf_hook_ops br_nf_ops[] = {
        { .hook = ip_sabotage_in,
          .owner = THIS_MODULE,
          .pf = PF_INET,
-         .hooknum = NF_IP_PRE_ROUTING,
+         .hooknum = NF_INET_PRE_ROUTING,
          .priority = NF_IP_PRI_FIRST, },
        { .hook = ip_sabotage_in,
          .owner = THIS_MODULE,
          .pf = PF_INET6,
-         .hooknum = NF_IP6_PRE_ROUTING,
+         .hooknum = NF_INET_PRE_ROUTING,
          .priority = NF_IP6_PRI_FIRST, },
 };
 
@@ -967,24 +967,10 @@ static ctl_table brnf_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table brnf_bridge_table[] = {
-       {
-               .ctl_name       = NET_BRIDGE,
-               .procname       = "bridge",
-               .mode           = 0555,
-               .child          = brnf_table,
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table brnf_net_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = brnf_bridge_table,
-       },
-       { .ctl_name = 0 }
+static struct ctl_path brnf_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "bridge", .ctl_name = NET_BRIDGE, },
+       { }
 };
 #endif
 
@@ -996,7 +982,7 @@ int __init br_netfilter_init(void)
        if (ret < 0)
                return ret;
 #ifdef CONFIG_SYSCTL
-       brnf_sysctl_header = register_sysctl_table(brnf_net_table);
+       brnf_sysctl_header = register_sysctl_paths(brnf_path, brnf_table);
        if (brnf_sysctl_header == NULL) {
                printk(KERN_WARNING
                       "br_netfilter: can't register to sysctl.\n");
index 53ab8e0cb5189c40a880b92b9b49e9c9e0aad85e..f5d69336d97b037eff3e912cd3e596b639e0ef0c 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <net/rtnetlink.h>
 #include <net/net_namespace.h>
+#include <net/sock.h>
 #include "br_private.h"
 
 static inline size_t br_nlmsg_size(void)
@@ -96,10 +97,10 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_LINK, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
 }
 
 /*
@@ -107,9 +108,13 @@ errout:
  */
 static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        struct net_device *dev;
        int idx;
 
+       if (net != &init_net)
+               return 0;
+
        idx = 0;
        for_each_netdev(&init_net, dev) {
                /* not a bridge port */
@@ -135,12 +140,16 @@ skip:
  */
 static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct ifinfomsg *ifm;
        struct nlattr *protinfo;
        struct net_device *dev;
        struct net_bridge_port *p;
        u8 new_state;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        if (nlmsg_len(nlh) < sizeof(*ifm))
                return -EINVAL;
 
index b84fc6075fe1ad9f33d1de0a2947f607de6a32a1..4a3e2bf892c788c6f4f55af094851916207407ac 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 menu "Bridge: Netfilter Configuration"
-       depends on BRIDGE && NETFILTER
+       depends on BRIDGE && BRIDGE_NETFILTER
 
 config BRIDGE_NF_EBTABLES
        tristate "Ethernet Bridge tables (ebtables) support"
index 457815fb558440fefeedb04a01d22dccdffcf27d..3be9e9898553b1d129700929dac0177853c0b377 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/in.h>
 #include <linux/if_arp.h>
 #include <linux/spinlock.h>
+#include <net/netfilter/nf_log.h>
 
 static DEFINE_SPINLOCK(ebt_log_lock);
 
@@ -182,7 +183,7 @@ static struct ebt_watcher log =
        .me             = THIS_MODULE,
 };
 
-static struct nf_logger ebt_log_logger = {
+static const struct nf_logger ebt_log_logger = {
        .name           = "ebt_log",
        .logfn          = &ebt_log_packet,
        .me             = THIS_MODULE,
index e7cfd30bac756f0c97b32aaa1eb6200bcc5c47f8..8e7b00b68d3868107dd52f01a82a9262f2f34f49 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/netdevice.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_ulog.h>
+#include <net/netfilter/nf_log.h>
 #include <net/sock.h>
 #include "../br_private.h"
 
@@ -278,7 +279,7 @@ static struct ebt_watcher ulog = {
        .me             = THIS_MODULE,
 };
 
-static struct nf_logger ebt_ulog_logger = {
+static const struct nf_logger ebt_ulog_logger = {
        .name           = EBT_ULOG_WATCHER,
        .logfn          = &ebt_log_packet,
        .me             = THIS_MODULE,
@@ -306,7 +307,7 @@ static int __init ebt_ulog_init(void)
        if (!ebtulognl)
                ret = -ENOMEM;
        else if ((ret = ebt_register_watcher(&ulog)))
-               sock_release(ebtulognl->sk_socket);
+               netlink_kernel_release(ebtulognl);
 
        if (ret == 0)
                nf_log_register(PF_BRIDGE, &ebt_ulog_logger);
@@ -332,7 +333,7 @@ static void __exit ebt_ulog_fini(void)
                }
                spin_unlock_bh(&ub->lock);
        }
-       sock_release(ebtulognl->sk_socket);
+       netlink_kernel_release(ebtulognl);
 }
 
 module_init(ebt_ulog_init);
index a43c697d3d7305dc4bc48d66254e4aa8cdacff63..0ddf7499d4962f34a28e4d5c87a0ce1e944593e4 100644 (file)
@@ -37,9 +37,7 @@ MODULE_LICENSE("GPL");
 
 
 #define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
-#define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : ""
 #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
-#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_
 #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;}
 
 static int
index 210493f99bc48f09e4c1c90bbb8bc63426465e81..fb810908732f6b420de1ada658915fa80463ae8e 100644 (file)
@@ -67,7 +67,7 @@ ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
        return ebt_do_table(hook, skb, in, out, &frame_filter);
 }
 
-static struct nf_hook_ops ebt_ops_filter[] = {
+static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
        {
                .hook           = ebt_hook,
                .owner          = THIS_MODULE,
index 3e58c2e5ee213c02881dc9b5cea498464a5c7b98..bc712730c54a96925bbe1558ce5b261d69f6f473 100644 (file)
@@ -74,7 +74,7 @@ ebt_nat_src(unsigned int hook, struct sk_buff *skb, const struct net_device *in
        return ebt_do_table(hook, skb, in, out, &frame_nat);
 }
 
-static struct nf_hook_ops ebt_ops_nat[] = {
+static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
        {
                .hook           = ebt_nat_dst,
                .owner          = THIS_MODULE,
index 817169e718c1180ee8e9c3f5fab222727f4c4846..32afff859e4ac3b9da111f92dc453d630d8abef4 100644 (file)
@@ -15,8 +15,6 @@
  *  2 of the License, or (at your option) any later version.
  */
 
-/* used for print_string */
-#include <linux/tty.h>
 
 #include <linux/kmod.h>
 #include <linux/module.h>
diff --git a/net/can/Kconfig b/net/can/Kconfig
new file mode 100644 (file)
index 0000000..89395b2
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Controller Area Network (CAN) network layer core configuration
+#
+
+menuconfig CAN
+       depends on NET
+       tristate "CAN bus subsystem support"
+       ---help---
+         Controller Area Network (CAN) is a slow (up to 1Mbit/s) serial
+         communications protocol which was developed by Bosch in
+         1991, mainly for automotive, but now widely used in marine
+         (NMEA2000), industrial, and medical applications.
+         More information on the CAN network protocol family PF_CAN
+         is contained in <Documentation/networking/can.txt>.
+
+         If you want CAN support you should say Y here and also to the
+         specific driver for your controller(s) below.
+
+config CAN_RAW
+       tristate "Raw CAN Protocol (raw access with CAN-ID filtering)"
+       depends on CAN
+       default N
+       ---help---
+         The raw CAN protocol option offers access to the CAN bus via
+         the BSD socket API. You probably want to use the raw socket in
+         most cases where no higher level protocol is being used. The raw
+         socket has several filter options e.g. ID masking / error frames.
+         To receive/send raw CAN messages, use AF_CAN with protocol CAN_RAW.
+
+config CAN_BCM
+       tristate "Broadcast Manager CAN Protocol (with content filtering)"
+       depends on CAN
+       default N
+       ---help---
+         The Broadcast Manager offers content filtering, timeout monitoring,
+         sending of RTR frames, and cyclic CAN messages without permanent user
+         interaction. The BCM can be 'programmed' via the BSD socket API and
+         informs you on demand e.g. only on content updates / timeouts.
+         You probably want to use the bcm socket in most cases where cyclic
+         CAN messages are used on the bus (e.g. in automotive environments).
+         To use the Broadcast Manager, use AF_CAN with protocol CAN_BCM.
+
+
+source "drivers/net/can/Kconfig"
diff --git a/net/can/Makefile b/net/can/Makefile
new file mode 100644 (file)
index 0000000..9cd3c4b
--- /dev/null
@@ -0,0 +1,12 @@
+#
+#  Makefile for the Linux Controller Area Network core.
+#
+
+obj-$(CONFIG_CAN)      += can.o
+can-objs               := af_can.o proc.o
+
+obj-$(CONFIG_CAN_RAW)  += can-raw.o
+can-raw-objs           := raw.o
+
+obj-$(CONFIG_CAN_BCM)  += can-bcm.o
+can-bcm-objs           := bcm.o
diff --git a/net/can/af_can.c b/net/can/af_can.c
new file mode 100644 (file)
index 0000000..5158e88
--- /dev/null
@@ -0,0 +1,861 @@
+/*
+ * af_can.c - Protocol family CAN core module
+ *            (used by different CAN protocol modules)
+ *
+ * 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/kmod.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/uaccess.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include "af_can.h"
+
+static __initdata const char banner[] = KERN_INFO
+       "can: controller area network core (" CAN_VERSION_STRING ")\n";
+
+MODULE_DESCRIPTION("Controller Area Network PF_CAN core");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>, "
+             "Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+
+MODULE_ALIAS_NETPROTO(PF_CAN);
+
+static int stats_timer __read_mostly = 1;
+module_param(stats_timer, int, S_IRUGO);
+MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)");
+
+HLIST_HEAD(can_rx_dev_list);
+static struct dev_rcv_lists can_rx_alldev_list;
+static DEFINE_SPINLOCK(can_rcvlists_lock);
+
+static struct kmem_cache *rcv_cache __read_mostly;
+
+/* table of registered CAN protocols */
+static struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
+static DEFINE_SPINLOCK(proto_tab_lock);
+
+struct timer_list can_stattimer;   /* timer for statistics update */
+struct s_stats    can_stats;       /* packet statistics */
+struct s_pstats   can_pstats;      /* receive list statistics */
+
+/*
+ * af_can socket functions
+ */
+
+static int can_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);
+
+       default:
+               return -ENOIOCTLCMD;
+       }
+}
+
+static void can_sock_destruct(struct sock *sk)
+{
+       skb_queue_purge(&sk->sk_receive_queue);
+}
+
+static int can_create(struct net *net, struct socket *sock, int protocol)
+{
+       struct sock *sk;
+       struct can_proto *cp;
+       char module_name[sizeof("can-proto-000")];
+       int err = 0;
+
+       sock->state = SS_UNCONNECTED;
+
+       if (protocol < 0 || protocol >= CAN_NPROTO)
+               return -EINVAL;
+
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
+       /* try to load protocol module, when CONFIG_KMOD is defined */
+       if (!proto_tab[protocol]) {
+               sprintf(module_name, "can-proto-%d", protocol);
+               err = request_module(module_name);
+
+               /*
+                * In case of error we only print a message but don't
+                * return the error code immediately.  Below we will
+                * return -EPROTONOSUPPORT
+                */
+               if (err == -ENOSYS) {
+                       if (printk_ratelimit())
+                               printk(KERN_INFO "can: request_module(%s)"
+                                      " not implemented.\n", module_name);
+               } else if (err) {
+                       if (printk_ratelimit())
+                               printk(KERN_ERR "can: request_module(%s)"
+                                      " failed.\n", module_name);
+               }
+       }
+
+       spin_lock(&proto_tab_lock);
+       cp = proto_tab[protocol];
+       if (cp && !try_module_get(cp->prot->owner))
+               cp = NULL;
+       spin_unlock(&proto_tab_lock);
+
+       /* check for available protocol and correct usage */
+
+       if (!cp)
+               return -EPROTONOSUPPORT;
+
+       if (cp->type != sock->type) {
+               err = -EPROTONOSUPPORT;
+               goto errout;
+       }
+
+       if (cp->capability >= 0 && !capable(cp->capability)) {
+               err = -EPERM;
+               goto errout;
+       }
+
+       sock->ops = cp->ops;
+
+       sk = sk_alloc(net, PF_CAN, GFP_KERNEL, cp->prot);
+       if (!sk) {
+               err = -ENOMEM;
+               goto errout;
+       }
+
+       sock_init_data(sock, sk);
+       sk->sk_destruct = can_sock_destruct;
+
+       if (sk->sk_prot->init)
+               err = sk->sk_prot->init(sk);
+
+       if (err) {
+               /* release sk on errors */
+               sock_orphan(sk);
+               sock_put(sk);
+       }
+
+ errout:
+       module_put(cp->prot->owner);
+       return err;
+}
+
+/*
+ * af_can tx path
+ */
+
+/**
+ * can_send - transmit a CAN frame (optional with local loopback)
+ * @skb: pointer to socket buffer with CAN frame in data section
+ * @loop: loopback for listeners on local CAN sockets (recommended default!)
+ *
+ * Return:
+ *  0 on success
+ *  -ENETDOWN when the selected interface is down
+ *  -ENOBUFS on full driver queue (see net_xmit_errno())
+ *  -ENOMEM when local loopback failed at calling skb_clone()
+ *  -EPERM when trying to send on a non-CAN interface
+ */
+int can_send(struct sk_buff *skb, int loop)
+{
+       int err;
+
+       if (skb->dev->type != ARPHRD_CAN) {
+               kfree_skb(skb);
+               return -EPERM;
+       }
+
+       if (!(skb->dev->flags & IFF_UP)) {
+               kfree_skb(skb);
+               return -ENETDOWN;
+       }
+
+       skb->protocol = htons(ETH_P_CAN);
+       skb_reset_network_header(skb);
+       skb_reset_transport_header(skb);
+
+       if (loop) {
+               /* local loopback of sent CAN frames */
+
+               /* indication for the CAN driver: do loopback */
+               skb->pkt_type = PACKET_LOOPBACK;
+
+               /*
+                * The reference to the originating sock may be required
+                * by the receiving socket to check whether the frame is
+                * its own. Example: can_raw sockopt CAN_RAW_RECV_OWN_MSGS
+                * Therefore we have to ensure that skb->sk remains the
+                * reference to the originating sock by restoring skb->sk
+                * after each skb_clone() or skb_orphan() usage.
+                */
+
+               if (!(skb->dev->flags & IFF_ECHO)) {
+                       /*
+                        * If the interface is not capable to do loopback
+                        * itself, we do it here.
+                        */
+                       struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
+
+                       if (!newskb) {
+                               kfree_skb(skb);
+                               return -ENOMEM;
+                       }
+
+                       newskb->sk = skb->sk;
+                       newskb->ip_summed = CHECKSUM_UNNECESSARY;
+                       newskb->pkt_type = PACKET_BROADCAST;
+                       netif_rx(newskb);
+               }
+       } else {
+               /* indication for the CAN driver: no loopback required */
+               skb->pkt_type = PACKET_HOST;
+       }
+
+       /* send to netdevice */
+       err = dev_queue_xmit(skb);
+       if (err > 0)
+               err = net_xmit_errno(err);
+
+       /* update statistics */
+       can_stats.tx_frames++;
+       can_stats.tx_frames_delta++;
+
+       return err;
+}
+EXPORT_SYMBOL(can_send);
+
+/*
+ * af_can rx path
+ */
+
+static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev)
+{
+       struct dev_rcv_lists *d = NULL;
+       struct hlist_node *n;
+
+       /*
+        * find receive list for this device
+        *
+        * The hlist_for_each_entry*() macros curse through the list
+        * using the pointer variable n and set d to the containing
+        * struct in each list iteration.  Therefore, after list
+        * iteration, d is unmodified when the list is empty, and it
+        * points to last list element, when the list is non-empty
+        * but no match in the loop body is found.  I.e. d is *not*
+        * NULL when no match is found.  We can, however, use the
+        * cursor variable n to decide if a match was found.
+        */
+
+       hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
+               if (d->dev == dev)
+                       break;
+       }
+
+       return n ? d : NULL;
+}
+
+static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
+                                       struct dev_rcv_lists *d)
+{
+       canid_t inv = *can_id & CAN_INV_FILTER; /* save flag before masking */
+
+       /* filter error frames */
+       if (*mask & CAN_ERR_FLAG) {
+               /* clear CAN_ERR_FLAG in list entry */
+               *mask &= CAN_ERR_MASK;
+               return &d->rx[RX_ERR];
+       }
+
+       /* ensure valid values in can_mask */
+       if (*mask & CAN_EFF_FLAG)
+               *mask &= (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG);
+       else
+               *mask &= (CAN_SFF_MASK | CAN_RTR_FLAG);
+
+       /* reduce condition testing at receive time */
+       *can_id &= *mask;
+
+       /* inverse can_id/can_mask filter */
+       if (inv)
+               return &d->rx[RX_INV];
+
+       /* mask == 0 => no condition testing at receive time */
+       if (!(*mask))
+               return &d->rx[RX_ALL];
+
+       /* use extra filterset for the subscription of exactly *ONE* can_id */
+       if (*can_id & CAN_EFF_FLAG) {
+               if (*mask == (CAN_EFF_MASK | CAN_EFF_FLAG)) {
+                       /* RFC: a use-case for hash-tables in the future? */
+                       return &d->rx[RX_EFF];
+               }
+       } else {
+               if (*mask == CAN_SFF_MASK)
+                       return &d->rx_sff[*can_id];
+       }
+
+       /* default: filter via can_id/can_mask */
+       return &d->rx[RX_FIL];
+}
+
+/**
+ * can_rx_register - subscribe CAN frames from a specific interface
+ * @dev: pointer to netdevice (NULL => subcribe from 'all' CAN devices list)
+ * @can_id: CAN identifier (see description)
+ * @mask: CAN mask (see description)
+ * @func: callback function on filter match
+ * @data: returned parameter for callback function
+ * @ident: string for calling module indentification
+ *
+ * Description:
+ *  Invokes the callback function with the received sk_buff and the given
+ *  parameter 'data' on a matching receive filter. A filter matches, when
+ *
+ *          <received_can_id> & mask == can_id & mask
+ *
+ *  The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
+ *  filter for error frames (CAN_ERR_FLAG bit set in mask).
+ *
+ * Return:
+ *  0 on success
+ *  -ENOMEM on missing cache mem to create subscription entry
+ *  -ENODEV unknown device
+ */
+int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
+                   void (*func)(struct sk_buff *, void *), void *data,
+                   char *ident)
+{
+       struct receiver *r;
+       struct hlist_head *rl;
+       struct dev_rcv_lists *d;
+       int err = 0;
+
+       /* insert new receiver  (dev,canid,mask) -> (func,data) */
+
+       r = kmem_cache_alloc(rcv_cache, GFP_KERNEL);
+       if (!r)
+               return -ENOMEM;
+
+       spin_lock(&can_rcvlists_lock);
+
+       d = find_dev_rcv_lists(dev);
+       if (d) {
+               rl = find_rcv_list(&can_id, &mask, d);
+
+               r->can_id  = can_id;
+               r->mask    = mask;
+               r->matches = 0;
+               r->func    = func;
+               r->data    = data;
+               r->ident   = ident;
+
+               hlist_add_head_rcu(&r->list, rl);
+               d->entries++;
+
+               can_pstats.rcv_entries++;
+               if (can_pstats.rcv_entries_max < can_pstats.rcv_entries)
+                       can_pstats.rcv_entries_max = can_pstats.rcv_entries;
+       } else {
+               kmem_cache_free(rcv_cache, r);
+               err = -ENODEV;
+       }
+
+       spin_unlock(&can_rcvlists_lock);
+
+       return err;
+}
+EXPORT_SYMBOL(can_rx_register);
+
+/*
+ * can_rx_delete_device - rcu callback for dev_rcv_lists structure removal
+ */
+static void can_rx_delete_device(struct rcu_head *rp)
+{
+       struct dev_rcv_lists *d = container_of(rp, struct dev_rcv_lists, rcu);
+
+       kfree(d);
+}
+
+/*
+ * can_rx_delete_receiver - rcu callback for single receiver entry removal
+ */
+static void can_rx_delete_receiver(struct rcu_head *rp)
+{
+       struct receiver *r = container_of(rp, struct receiver, rcu);
+
+       kmem_cache_free(rcv_cache, r);
+}
+
+/**
+ * can_rx_unregister - unsubscribe CAN frames from a specific interface
+ * @dev: pointer to netdevice (NULL => unsubcribe from 'all' CAN devices list)
+ * @can_id: CAN identifier
+ * @mask: CAN mask
+ * @func: callback function on filter match
+ * @data: returned parameter for callback function
+ *
+ * Description:
+ *  Removes subscription entry depending on given (subscription) values.
+ */
+void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
+                      void (*func)(struct sk_buff *, void *), void *data)
+{
+       struct receiver *r = NULL;
+       struct hlist_head *rl;
+       struct hlist_node *next;
+       struct dev_rcv_lists *d;
+
+       spin_lock(&can_rcvlists_lock);
+
+       d = find_dev_rcv_lists(dev);
+       if (!d) {
+               printk(KERN_ERR "BUG: receive list not found for "
+                      "dev %s, id %03X, mask %03X\n",
+                      DNAME(dev), can_id, mask);
+               goto out;
+       }
+
+       rl = find_rcv_list(&can_id, &mask, d);
+
+       /*
+        * Search the receiver list for the item to delete.  This should
+        * exist, since no receiver may be unregistered that hasn't
+        * been registered before.
+        */
+
+       hlist_for_each_entry_rcu(r, next, rl, list) {
+               if (r->can_id == can_id && r->mask == mask
+                   && r->func == func && r->data == data)
+                       break;
+       }
+
+       /*
+        * Check for bugs in CAN protocol implementations:
+        * If no matching list item was found, the list cursor variable next
+        * will be NULL, while r will point to the last item of the list.
+        */
+
+       if (!next) {
+               printk(KERN_ERR "BUG: receive list entry not found for "
+                      "dev %s, id %03X, mask %03X\n",
+                      DNAME(dev), can_id, mask);
+               r = NULL;
+               d = NULL;
+               goto out;
+       }
+
+       hlist_del_rcu(&r->list);
+       d->entries--;
+
+       if (can_pstats.rcv_entries > 0)
+               can_pstats.rcv_entries--;
+
+       /* remove device structure requested by NETDEV_UNREGISTER */
+       if (d->remove_on_zero_entries && !d->entries)
+               hlist_del_rcu(&d->list);
+       else
+               d = NULL;
+
+ out:
+       spin_unlock(&can_rcvlists_lock);
+
+       /* schedule the receiver item for deletion */
+       if (r)
+               call_rcu(&r->rcu, can_rx_delete_receiver);
+
+       /* schedule the device structure for deletion */
+       if (d)
+               call_rcu(&d->rcu, can_rx_delete_device);
+}
+EXPORT_SYMBOL(can_rx_unregister);
+
+static inline void deliver(struct sk_buff *skb, struct receiver *r)
+{
+       struct sk_buff *clone = skb_clone(skb, GFP_ATOMIC);
+
+       if (clone) {
+               clone->sk = skb->sk;
+               r->func(clone, r->data);
+               r->matches++;
+       }
+}
+
+static int can_rcv_filter(struct dev_rcv_lists *d, struct sk_buff *skb)
+{
+       struct receiver *r;
+       struct hlist_node *n;
+       int matches = 0;
+       struct can_frame *cf = (struct can_frame *)skb->data;
+       canid_t can_id = cf->can_id;
+
+       if (d->entries == 0)
+               return 0;
+
+       if (can_id & CAN_ERR_FLAG) {
+               /* check for error frame entries only */
+               hlist_for_each_entry_rcu(r, n, &d->rx[RX_ERR], list) {
+                       if (can_id & r->mask) {
+                               deliver(skb, r);
+                               matches++;
+                       }
+               }
+               return matches;
+       }
+
+       /* check for unfiltered entries */
+       hlist_for_each_entry_rcu(r, n, &d->rx[RX_ALL], list) {
+               deliver(skb, r);
+               matches++;
+       }
+
+       /* check for can_id/mask entries */
+       hlist_for_each_entry_rcu(r, n, &d->rx[RX_FIL], list) {
+               if ((can_id & r->mask) == r->can_id) {
+                       deliver(skb, r);
+                       matches++;
+               }
+       }
+
+       /* check for inverted can_id/mask entries */
+       hlist_for_each_entry_rcu(r, n, &d->rx[RX_INV], list) {
+               if ((can_id & r->mask) != r->can_id) {
+                       deliver(skb, r);
+                       matches++;
+               }
+       }
+
+       /* check CAN_ID specific entries */
+       if (can_id & CAN_EFF_FLAG) {
+               hlist_for_each_entry_rcu(r, n, &d->rx[RX_EFF], list) {
+                       if (r->can_id == can_id) {
+                               deliver(skb, r);
+                               matches++;
+                       }
+               }
+       } else {
+               can_id &= CAN_SFF_MASK;
+               hlist_for_each_entry_rcu(r, n, &d->rx_sff[can_id], list) {
+                       deliver(skb, r);
+                       matches++;
+               }
+       }
+
+       return matches;
+}
+
+static int can_rcv(struct sk_buff *skb, struct net_device *dev,
+                  struct packet_type *pt, struct net_device *orig_dev)
+{
+       struct dev_rcv_lists *d;
+       int matches;
+
+       if (dev->type != ARPHRD_CAN || dev->nd_net != &init_net) {
+               kfree_skb(skb);
+               return 0;
+       }
+
+       /* update statistics */
+       can_stats.rx_frames++;
+       can_stats.rx_frames_delta++;
+
+       rcu_read_lock();
+
+       /* deliver the packet to sockets listening on all devices */
+       matches = can_rcv_filter(&can_rx_alldev_list, skb);
+
+       /* find receive list for this device */
+       d = find_dev_rcv_lists(dev);
+       if (d)
+               matches += can_rcv_filter(d, skb);
+
+       rcu_read_unlock();
+
+       /* free the skbuff allocated by the netdevice driver */
+       kfree_skb(skb);
+
+       if (matches > 0) {
+               can_stats.matches++;
+               can_stats.matches_delta++;
+       }
+
+       return 0;
+}
+
+/*
+ * af_can protocol functions
+ */
+
+/**
+ * can_proto_register - register CAN transport protocol
+ * @cp: pointer to CAN protocol structure
+ *
+ * Return:
+ *  0 on success
+ *  -EINVAL invalid (out of range) protocol number
+ *  -EBUSY  protocol already in use
+ *  -ENOBUF if proto_register() fails
+ */
+int can_proto_register(struct can_proto *cp)
+{
+       int proto = cp->protocol;
+       int err = 0;
+
+       if (proto < 0 || proto >= CAN_NPROTO) {
+               printk(KERN_ERR "can: protocol number %d out of range\n",
+                      proto);
+               return -EINVAL;
+       }
+
+       spin_lock(&proto_tab_lock);
+       if (proto_tab[proto]) {
+               printk(KERN_ERR "can: protocol %d already registered\n",
+                      proto);
+               err = -EBUSY;
+               goto errout;
+       }
+
+       err = proto_register(cp->prot, 0);
+       if (err < 0)
+               goto errout;
+
+       proto_tab[proto] = cp;
+
+       /* use generic ioctl function if the module doesn't bring its own */
+       if (!cp->ops->ioctl)
+               cp->ops->ioctl = can_ioctl;
+
+ errout:
+       spin_unlock(&proto_tab_lock);
+
+       return err;
+}
+EXPORT_SYMBOL(can_proto_register);
+
+/**
+ * can_proto_unregister - unregister CAN transport protocol
+ * @cp: pointer to CAN protocol structure
+ */
+void can_proto_unregister(struct can_proto *cp)
+{
+       int proto = cp->protocol;
+
+       spin_lock(&proto_tab_lock);
+       if (!proto_tab[proto]) {
+               printk(KERN_ERR "BUG: can: protocol %d is not registered\n",
+                      proto);
+       }
+       proto_unregister(cp->prot);
+       proto_tab[proto] = NULL;
+       spin_unlock(&proto_tab_lock);
+}
+EXPORT_SYMBOL(can_proto_unregister);
+
+/*
+ * af_can notifier to create/remove CAN netdevice specific structs
+ */
+static int can_notifier(struct notifier_block *nb, unsigned long msg,
+                       void *data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct dev_rcv_lists *d;
+
+       if (dev->nd_net != &init_net)
+               return NOTIFY_DONE;
+
+       if (dev->type != ARPHRD_CAN)
+               return NOTIFY_DONE;
+
+       switch (msg) {
+
+       case NETDEV_REGISTER:
+
+               /*
+                * create new dev_rcv_lists for this device
+                *
+                * N.B. zeroing the struct is the correct initialization
+                * for the embedded hlist_head structs.
+                * Another list type, e.g. list_head, would require
+                * explicit initialization.
+                */
+
+               d = kzalloc(sizeof(*d), GFP_KERNEL);
+               if (!d) {
+                       printk(KERN_ERR
+                              "can: allocation of receive list failed\n");
+                       return NOTIFY_DONE;
+               }
+               d->dev = dev;
+
+               spin_lock(&can_rcvlists_lock);
+               hlist_add_head_rcu(&d->list, &can_rx_dev_list);
+               spin_unlock(&can_rcvlists_lock);
+
+               break;
+
+       case NETDEV_UNREGISTER:
+               spin_lock(&can_rcvlists_lock);
+
+               d = find_dev_rcv_lists(dev);
+               if (d) {
+                       if (d->entries) {
+                               d->remove_on_zero_entries = 1;
+                               d = NULL;
+                       } else
+                               hlist_del_rcu(&d->list);
+               } else
+                       printk(KERN_ERR "can: notifier: receive list not "
+                              "found for dev %s\n", dev->name);
+
+               spin_unlock(&can_rcvlists_lock);
+
+               if (d)
+                       call_rcu(&d->rcu, can_rx_delete_device);
+
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+/*
+ * af_can module init/exit functions
+ */
+
+static struct packet_type can_packet __read_mostly = {
+       .type = __constant_htons(ETH_P_CAN),
+       .dev  = NULL,
+       .func = can_rcv,
+};
+
+static struct net_proto_family can_family_ops __read_mostly = {
+       .family = PF_CAN,
+       .create = can_create,
+       .owner  = THIS_MODULE,
+};
+
+/* notifier block for netdevice event */
+static struct notifier_block can_netdev_notifier __read_mostly = {
+       .notifier_call = can_notifier,
+};
+
+static __init int can_init(void)
+{
+       printk(banner);
+
+       rcv_cache = kmem_cache_create("can_receiver", sizeof(struct receiver),
+                                     0, 0, NULL);
+       if (!rcv_cache)
+               return -ENOMEM;
+
+       /*
+        * Insert can_rx_alldev_list for reception on all devices.
+        * This struct is zero initialized which is correct for the
+        * embedded hlist heads, the dev pointer, and the entries counter.
+        */
+
+       spin_lock(&can_rcvlists_lock);
+       hlist_add_head_rcu(&can_rx_alldev_list.list, &can_rx_dev_list);
+       spin_unlock(&can_rcvlists_lock);
+
+       if (stats_timer) {
+               /* the statistics are updated every second (timer triggered) */
+               setup_timer(&can_stattimer, can_stat_update, 0);
+               mod_timer(&can_stattimer, round_jiffies(jiffies + HZ));
+       } else
+               can_stattimer.function = NULL;
+
+       can_init_proc();
+
+       /* protocol register */
+       sock_register(&can_family_ops);
+       register_netdevice_notifier(&can_netdev_notifier);
+       dev_add_pack(&can_packet);
+
+       return 0;
+}
+
+static __exit void can_exit(void)
+{
+       struct dev_rcv_lists *d;
+       struct hlist_node *n, *next;
+
+       if (stats_timer)
+               del_timer(&can_stattimer);
+
+       can_remove_proc();
+
+       /* protocol unregister */
+       dev_remove_pack(&can_packet);
+       unregister_netdevice_notifier(&can_netdev_notifier);
+       sock_unregister(PF_CAN);
+
+       /* remove can_rx_dev_list */
+       spin_lock(&can_rcvlists_lock);
+       hlist_del(&can_rx_alldev_list.list);
+       hlist_for_each_entry_safe(d, n, next, &can_rx_dev_list, list) {
+               hlist_del(&d->list);
+               kfree(d);
+       }
+       spin_unlock(&can_rcvlists_lock);
+
+       kmem_cache_destroy(rcv_cache);
+}
+
+module_init(can_init);
+module_exit(can_exit);
diff --git a/net/can/af_can.h b/net/can/af_can.h
new file mode 100644 (file)
index 0000000..18f91e3
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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 AF_CAN_H
+#define AF_CAN_H
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/can.h>
+
+/* af_can rx dispatcher structures */
+
+struct receiver {
+       struct hlist_node list;
+       struct rcu_head rcu;
+       canid_t can_id;
+       canid_t mask;
+       unsigned long matches;
+       void (*func)(struct sk_buff *, void *);
+       void *data;
+       char *ident;
+};
+
+enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_EFF, RX_MAX };
+
+struct dev_rcv_lists {
+       struct hlist_node list;
+       struct rcu_head rcu;
+       struct net_device *dev;
+       struct hlist_head rx[RX_MAX];
+       struct hlist_head rx_sff[0x800];
+       int remove_on_zero_entries;
+       int entries;
+};
+
+/* statistic structures */
+
+/* can be reset e.g. by can_init_stats() */
+struct s_stats {
+       unsigned long jiffies_init;
+
+       unsigned long rx_frames;
+       unsigned long tx_frames;
+       unsigned long matches;
+
+       unsigned long total_rx_rate;
+       unsigned long total_tx_rate;
+       unsigned long total_rx_match_ratio;
+
+       unsigned long current_rx_rate;
+       unsigned long current_tx_rate;
+       unsigned long current_rx_match_ratio;
+
+       unsigned long max_rx_rate;
+       unsigned long max_tx_rate;
+       unsigned long max_rx_match_ratio;
+
+       unsigned long rx_frames_delta;
+       unsigned long tx_frames_delta;
+       unsigned long matches_delta;
+};
+
+/* persistent statistics */
+struct s_pstats {
+       unsigned long stats_reset;
+       unsigned long user_reset;
+       unsigned long rcv_entries;
+       unsigned long rcv_entries_max;
+};
+
+/* function prototypes for the CAN networklayer procfs (proc.c) */
+extern void can_init_proc(void);
+extern void can_remove_proc(void);
+extern void can_stat_update(unsigned long data);
+
+/* structures and variables from af_can.c needed in proc.c for reading */
+extern struct timer_list can_stattimer;    /* timer for statistics update */
+extern struct s_stats    can_stats;        /* packet statistics */
+extern struct s_pstats   can_pstats;       /* receive list statistics */
+extern struct hlist_head can_rx_dev_list;  /* rx dispatcher structures */
+
+#endif /* AF_CAN_H */
diff --git a/net/can/bcm.c b/net/can/bcm.c
new file mode 100644 (file)
index 0000000..bd4282d
--- /dev/null
@@ -0,0 +1,1561 @@
+/*
+ * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
+ *
+ * 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/list.h>
+#include <linux/proc_fs.h>
+#include <linux/uio.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <linux/can/bcm.h>
+#include <net/sock.h>
+#include <net/net_namespace.h>
+
+/* use of last_frames[index].can_dlc */
+#define RX_RECV    0x40 /* received data for this element */
+#define RX_THR     0x80 /* element not been sent due to throttle feature */
+#define BCM_CAN_DLC_MASK 0x0F /* clean private flags in can_dlc by masking */
+
+/* get best masking value for can_rx_register() for a given single can_id */
+#define REGMASK(id) ((id & CAN_RTR_FLAG) | ((id & CAN_EFF_FLAG) ? \
+                       (CAN_EFF_MASK | CAN_EFF_FLAG) : CAN_SFF_MASK))
+
+#define CAN_BCM_VERSION CAN_VERSION
+static __initdata const char banner[] = KERN_INFO
+       "can: broadcast manager protocol (rev " CAN_BCM_VERSION ")\n";
+
+MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+
+/* easy access to can_frame payload */
+static inline u64 GET_U64(const struct can_frame *cp)
+{
+       return *(u64 *)cp->data;
+}
+
+struct bcm_op {
+       struct list_head list;
+       int ifindex;
+       canid_t can_id;
+       int flags;
+       unsigned long j_ival1, j_ival2, j_lastmsg;
+       unsigned long frames_abs, frames_filtered;
+       struct timer_list timer, thrtimer;
+       struct timeval ival1, ival2;
+       ktime_t rx_stamp;
+       int rx_ifindex;
+       int count;
+       int nframes;
+       int currframe;
+       struct can_frame *frames;
+       struct can_frame *last_frames;
+       struct can_frame sframe;
+       struct can_frame last_sframe;
+       struct sock *sk;
+       struct net_device *rx_reg_dev;
+};
+
+static struct proc_dir_entry *proc_dir;
+
+struct bcm_sock {
+       struct sock sk;
+       int bound;
+       int ifindex;
+       struct notifier_block notifier;
+       struct list_head rx_ops;
+       struct list_head tx_ops;
+       unsigned long dropped_usr_msgs;
+       struct proc_dir_entry *bcm_proc_read;
+       char procname [9]; /* pointer printed in ASCII with \0 */
+};
+
+static inline struct bcm_sock *bcm_sk(const struct sock *sk)
+{
+       return (struct bcm_sock *)sk;
+}
+
+#define CFSIZ sizeof(struct can_frame)
+#define OPSIZ sizeof(struct bcm_op)
+#define MHSIZ sizeof(struct bcm_msg_head)
+
+/*
+ * rounded_tv2jif - calculate jiffies from timeval including optional up
+ * @tv: pointer to timeval
+ *
+ * Description:
+ * Unlike timeval_to_jiffies() provided in include/linux/jiffies.h, this
+ * function is intentionally more relaxed on precise timer ticks to get
+ * exact one jiffy for requested 1000us on a 1000HZ machine.
+ * This code is to be removed when upgrading to kernel hrtimer.
+ *
+ * Return:
+ *  calculated jiffies (max: ULONG_MAX)
+ */
+static unsigned long rounded_tv2jif(const struct timeval *tv)
+{
+       unsigned long sec  = tv->tv_sec;
+       unsigned long usec = tv->tv_usec;
+       unsigned long jif;
+
+       if (sec > ULONG_MAX / HZ)
+               return ULONG_MAX;
+
+       /* round up to get at least the requested time */
+       usec += 1000000 / HZ - 1;
+
+       jif  = usec / (1000000 / HZ);
+
+       if (sec * HZ > ULONG_MAX - jif)
+               return ULONG_MAX;
+
+       return jif + sec * HZ;
+}
+
+/*
+ * procfs functions
+ */
+static char *bcm_proc_getifname(int ifindex)
+{
+       struct net_device *dev;
+
+       if (!ifindex)
+               return "any";
+
+       /* no usage counting */
+       dev = __dev_get_by_index(&init_net, ifindex);
+       if (dev)
+               return dev->name;
+
+       return "???";
+}
+
+static int bcm_read_proc(char *page, char **start, off_t off,
+                        int count, int *eof, void *data)
+{
+       int len = 0;
+       struct sock *sk = (struct sock *)data;
+       struct bcm_sock *bo = bcm_sk(sk);
+       struct bcm_op *op;
+
+       len += snprintf(page + len, PAGE_SIZE - len, ">>> socket %p",
+                       sk->sk_socket);
+       len += snprintf(page + len, PAGE_SIZE - len, " / sk %p", sk);
+       len += snprintf(page + len, PAGE_SIZE - len, " / bo %p", bo);
+       len += snprintf(page + len, PAGE_SIZE - len, " / dropped %lu",
+                       bo->dropped_usr_msgs);
+       len += snprintf(page + len, PAGE_SIZE - len, " / bound %s",
+                       bcm_proc_getifname(bo->ifindex));
+       len += snprintf(page + len, PAGE_SIZE - len, " <<<\n");
+
+       list_for_each_entry(op, &bo->rx_ops, list) {
+
+               unsigned long reduction;
+
+               /* print only active entries & prevent division by zero */
+               if (!op->frames_abs)
+                       continue;
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "rx_op: %03X %-5s ",
+                               op->can_id, bcm_proc_getifname(op->ifindex));
+               len += snprintf(page + len, PAGE_SIZE - len, "[%d]%c ",
+                               op->nframes,
+                               (op->flags & RX_CHECK_DLC)?'d':' ');
+               if (op->j_ival1)
+                       len += snprintf(page + len, PAGE_SIZE - len,
+                                       "timeo=%ld ", op->j_ival1);
+
+               if (op->j_ival2)
+                       len += snprintf(page + len, PAGE_SIZE - len,
+                                       "thr=%ld ", op->j_ival2);
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "# recv %ld (%ld) => reduction: ",
+                               op->frames_filtered, op->frames_abs);
+
+               reduction = 100 - (op->frames_filtered * 100) / op->frames_abs;
+
+               len += snprintf(page + len, PAGE_SIZE - len, "%s%ld%%\n",
+                               (reduction == 100)?"near ":"", reduction);
+
+               if (len > PAGE_SIZE - 200) {
+                       /* mark output cut off */
+                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
+                       break;
+               }
+       }
+
+       list_for_each_entry(op, &bo->tx_ops, list) {
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "tx_op: %03X %s [%d] ",
+                               op->can_id, bcm_proc_getifname(op->ifindex),
+                               op->nframes);
+               if (op->j_ival1)
+                       len += snprintf(page + len, PAGE_SIZE - len, "t1=%ld ",
+                                       op->j_ival1);
+
+               if (op->j_ival2)
+                       len += snprintf(page + len, PAGE_SIZE - len, "t2=%ld ",
+                                       op->j_ival2);
+
+               len += snprintf(page + len, PAGE_SIZE - len, "# sent %ld\n",
+                               op->frames_abs);
+
+               if (len > PAGE_SIZE - 100) {
+                       /* mark output cut off */
+                       len += snprintf(page + len, PAGE_SIZE - len, "(..)\n");
+                       break;
+               }
+       }
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+       *eof = 1;
+       return len;
+}
+
+/*
+ * bcm_can_tx - send the (next) CAN frame to the appropriate CAN interface
+ *              of the given bcm tx op
+ */
+static void bcm_can_tx(struct bcm_op *op)
+{
+       struct sk_buff *skb;
+       struct net_device *dev;
+       struct can_frame *cf = &op->frames[op->currframe];
+
+       /* no target device? => exit */
+       if (!op->ifindex)
+               return;
+
+       dev = dev_get_by_index(&init_net, op->ifindex);
+       if (!dev) {
+               /* RFC: should this bcm_op remove itself here? */
+               return;
+       }
+
+       skb = alloc_skb(CFSIZ, gfp_any());
+       if (!skb)
+               goto out;
+
+       memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
+
+       /* send with loopback */
+       skb->dev = dev;
+       skb->sk = op->sk;
+       can_send(skb, 1);
+
+       /* update statistics */
+       op->currframe++;
+       op->frames_abs++;
+
+       /* reached last frame? */
+       if (op->currframe >= op->nframes)
+               op->currframe = 0;
+ out:
+       dev_put(dev);
+}
+
+/*
+ * bcm_send_to_user - send a BCM message to the userspace
+ *                    (consisting of bcm_msg_head + x CAN frames)
+ */
+static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
+                            struct can_frame *frames, int has_timestamp)
+{
+       struct sk_buff *skb;
+       struct can_frame *firstframe;
+       struct sockaddr_can *addr;
+       struct sock *sk = op->sk;
+       int datalen = head->nframes * CFSIZ;
+       int err;
+
+       skb = alloc_skb(sizeof(*head) + datalen, gfp_any());
+       if (!skb)
+               return;
+
+       memcpy(skb_put(skb, sizeof(*head)), head, sizeof(*head));
+
+       if (head->nframes) {
+               /* can_frames starting here */
+               firstframe = (struct can_frame *) skb_tail_pointer(skb);
+
+               memcpy(skb_put(skb, datalen), frames, datalen);
+
+               /*
+                * the BCM uses the can_dlc-element of the can_frame
+                * structure for internal purposes. This is only
+                * relevant for updates that are generated by the
+                * BCM, where nframes is 1
+                */
+               if (head->nframes == 1)
+                       firstframe->can_dlc &= BCM_CAN_DLC_MASK;
+       }
+
+       if (has_timestamp) {
+               /* restore rx timestamp */
+               skb->tstamp = op->rx_stamp;
+       }
+
+       /*
+        *  Put the datagram to the queue so that bcm_recvmsg() can
+        *  get it from there.  We need to pass the interface index to
+        *  bcm_recvmsg().  We pass a whole struct sockaddr_can in skb->cb
+        *  containing the interface index.
+        */
+
+       BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct sockaddr_can));
+       addr = (struct sockaddr_can *)skb->cb;
+       memset(addr, 0, sizeof(*addr));
+       addr->can_family  = AF_CAN;
+       addr->can_ifindex = op->rx_ifindex;
+
+       err = sock_queue_rcv_skb(sk, skb);
+       if (err < 0) {
+               struct bcm_sock *bo = bcm_sk(sk);
+
+               kfree_skb(skb);
+               /* don't care about overflows in this statistic */
+               bo->dropped_usr_msgs++;
+       }
+}
+
+/*
+ * bcm_tx_timeout_handler - performes cyclic CAN frame transmissions
+ */
+static void bcm_tx_timeout_handler(unsigned long data)
+{
+       struct bcm_op *op = (struct bcm_op *)data;
+
+       if (op->j_ival1 && (op->count > 0)) {
+
+               op->count--;
+               if (!op->count && (op->flags & TX_COUNTEVT)) {
+                       struct bcm_msg_head msg_head;
+
+                       /* create notification to user */
+                       msg_head.opcode  = TX_EXPIRED;
+                       msg_head.flags   = op->flags;
+                       msg_head.count   = op->count;
+                       msg_head.ival1   = op->ival1;
+                       msg_head.ival2   = op->ival2;
+                       msg_head.can_id  = op->can_id;
+                       msg_head.nframes = 0;
+
+                       bcm_send_to_user(op, &msg_head, NULL, 0);
+               }
+       }
+
+       if (op->j_ival1 && (op->count > 0)) {
+
+               /* send (next) frame */
+               bcm_can_tx(op);
+               mod_timer(&op->timer, jiffies + op->j_ival1);
+
+       } else {
+               if (op->j_ival2) {
+
+                       /* send (next) frame */
+                       bcm_can_tx(op);
+                       mod_timer(&op->timer, jiffies + op->j_ival2);
+               }
+       }
+
+       return;
+}
+
+/*
+ * bcm_rx_changed - create a RX_CHANGED notification due to changed content
+ */
+static void bcm_rx_changed(struct bcm_op *op, struct can_frame *data)
+{
+       struct bcm_msg_head head;
+
+       op->j_lastmsg = jiffies;
+
+       /* update statistics */
+       op->frames_filtered++;
+
+       /* prevent statistics overflow */
+       if (op->frames_filtered > ULONG_MAX/100)
+               op->frames_filtered = op->frames_abs = 0;
+
+       head.opcode  = RX_CHANGED;
+       head.flags   = op->flags;
+       head.count   = op->count;
+       head.ival1   = op->ival1;
+       head.ival2   = op->ival2;
+       head.can_id  = op->can_id;
+       head.nframes = 1;
+
+       bcm_send_to_user(op, &head, data, 1);
+}
+
+/*
+ * bcm_rx_update_and_send - process a detected relevant receive content change
+ *                          1. update the last received data
+ *                          2. send a notification to the user (if possible)
+ */
+static void bcm_rx_update_and_send(struct bcm_op *op,
+                                  struct can_frame *lastdata,
+                                  struct can_frame *rxdata)
+{
+       unsigned long nexttx = op->j_lastmsg + op->j_ival2;
+
+       memcpy(lastdata, rxdata, CFSIZ);
+
+       /* mark as used */
+       lastdata->can_dlc |= RX_RECV;
+
+       /* throttle bcm_rx_changed ? */
+       if ((op->thrtimer.expires) ||
+           ((op->j_ival2) && (nexttx > jiffies))) {
+               /* we are already waiting OR we have to start waiting */
+
+               /* mark as 'throttled' */
+               lastdata->can_dlc |= RX_THR;
+
+               if (!(op->thrtimer.expires)) {
+                       /* start the timer only the first time */
+                       mod_timer(&op->thrtimer, nexttx);
+               }
+
+       } else {
+               /* send RX_CHANGED to the user immediately */
+               bcm_rx_changed(op, rxdata);
+       }
+}
+
+/*
+ * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
+ *                       received data stored in op->last_frames[]
+ */
+static void bcm_rx_cmp_to_index(struct bcm_op *op, int index,
+                               struct can_frame *rxdata)
+{
+       /*
+        * no one uses the MSBs of can_dlc for comparation,
+        * so we use it here to detect the first time of reception
+        */
+
+       if (!(op->last_frames[index].can_dlc & RX_RECV)) {
+               /* received data for the first time => send update to user */
+               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
+               return;
+       }
+
+       /* do a real check in can_frame data section */
+
+       if ((GET_U64(&op->frames[index]) & GET_U64(rxdata)) !=
+           (GET_U64(&op->frames[index]) & GET_U64(&op->last_frames[index]))) {
+               bcm_rx_update_and_send(op, &op->last_frames[index], rxdata);
+               return;
+       }
+
+       if (op->flags & RX_CHECK_DLC) {
+               /* do a real check in can_frame dlc */
+               if (rxdata->can_dlc != (op->last_frames[index].can_dlc &
+                                       BCM_CAN_DLC_MASK)) {
+                       bcm_rx_update_and_send(op, &op->last_frames[index],
+                                              rxdata);
+                       return;
+               }
+       }
+}
+
+/*
+ * bcm_rx_starttimer - enable timeout monitoring for CAN frame receiption
+ */
+static void bcm_rx_starttimer(struct bcm_op *op)
+{
+       if (op->flags & RX_NO_AUTOTIMER)
+               return;
+
+       if (op->j_ival1)
+               mod_timer(&op->timer, jiffies + op->j_ival1);
+}
+
+/*
+ * bcm_rx_timeout_handler - when the (cyclic) CAN frame receiption timed out
+ */
+static void bcm_rx_timeout_handler(unsigned long data)
+{
+       struct bcm_op *op = (struct bcm_op *)data;
+       struct bcm_msg_head msg_head;
+
+       msg_head.opcode  = RX_TIMEOUT;
+       msg_head.flags   = op->flags;
+       msg_head.count   = op->count;
+       msg_head.ival1   = op->ival1;
+       msg_head.ival2   = op->ival2;
+       msg_head.can_id  = op->can_id;
+       msg_head.nframes = 0;
+
+       bcm_send_to_user(op, &msg_head, NULL, 0);
+
+       /* no restart of the timer is done here! */
+
+       /* if user wants to be informed, when cyclic CAN-Messages come back */
+       if ((op->flags & RX_ANNOUNCE_RESUME) && op->last_frames) {
+               /* clear received can_frames to indicate 'nothing received' */
+               memset(op->last_frames, 0, op->nframes * CFSIZ);
+       }
+}
+
+/*
+ * bcm_rx_thr_handler - the time for blocked content updates is over now:
+ *                      Check for throttled data and send it to the userspace
+ */
+static void bcm_rx_thr_handler(unsigned long data)
+{
+       struct bcm_op *op = (struct bcm_op *)data;
+       int i = 0;
+
+       /* mark disabled / consumed timer */
+       op->thrtimer.expires = 0;
+
+       if (op->nframes > 1) {
+               /* for MUX filter we start at index 1 */
+               for (i = 1; i < op->nframes; i++) {
+                       if ((op->last_frames) &&
+                           (op->last_frames[i].can_dlc & RX_THR)) {
+                               op->last_frames[i].can_dlc &= ~RX_THR;
+                               bcm_rx_changed(op, &op->last_frames[i]);
+                       }
+               }
+
+       } else {
+               /* for RX_FILTER_ID and simple filter */
+               if (op->last_frames && (op->last_frames[0].can_dlc & RX_THR)) {
+                       op->last_frames[0].can_dlc &= ~RX_THR;
+                       bcm_rx_changed(op, &op->last_frames[0]);
+               }
+       }
+}
+
+/*
+ * bcm_rx_handler - handle a CAN frame receiption
+ */
+static void bcm_rx_handler(struct sk_buff *skb, void *data)
+{
+       struct bcm_op *op = (struct bcm_op *)data;
+       struct can_frame rxframe;
+       int i;
+
+       /* disable timeout */
+       del_timer(&op->timer);
+
+       if (skb->len == sizeof(rxframe)) {
+               memcpy(&rxframe, skb->data, sizeof(rxframe));
+               /* save rx timestamp */
+               op->rx_stamp = skb->tstamp;
+               /* save originator for recvfrom() */
+               op->rx_ifindex = skb->dev->ifindex;
+               /* update statistics */
+               op->frames_abs++;
+               kfree_skb(skb);
+
+       } else {
+               kfree_skb(skb);
+               return;
+       }
+
+       if (op->can_id != rxframe.can_id)
+               return;
+
+       if (op->flags & RX_RTR_FRAME) {
+               /* send reply for RTR-request (placed in op->frames[0]) */
+               bcm_can_tx(op);
+               return;
+       }
+
+       if (op->flags & RX_FILTER_ID) {
+               /* the easiest case */
+               bcm_rx_update_and_send(op, &op->last_frames[0], &rxframe);
+               bcm_rx_starttimer(op);
+               return;
+       }
+
+       if (op->nframes == 1) {
+               /* simple compare with index 0 */
+               bcm_rx_cmp_to_index(op, 0, &rxframe);
+               bcm_rx_starttimer(op);
+               return;
+       }
+
+       if (op->nframes > 1) {
+               /*
+                * multiplex compare
+                *
+                * find the first multiplex mask that fits.
+                * Remark: The MUX-mask is stored in index 0
+                */
+
+               for (i = 1; i < op->nframes; i++) {
+                       if ((GET_U64(&op->frames[0]) & GET_U64(&rxframe)) ==
+                           (GET_U64(&op->frames[0]) &
+                            GET_U64(&op->frames[i]))) {
+                               bcm_rx_cmp_to_index(op, i, &rxframe);
+                               break;
+                       }
+               }
+               bcm_rx_starttimer(op);
+       }
+}
+
+/*
+ * helpers for bcm_op handling: find & delete bcm [rx|tx] op elements
+ */
+static struct bcm_op *bcm_find_op(struct list_head *ops, canid_t can_id,
+                                 int ifindex)
+{
+       struct bcm_op *op;
+
+       list_for_each_entry(op, ops, list) {
+               if ((op->can_id == can_id) && (op->ifindex == ifindex))
+                       return op;
+       }
+
+       return NULL;
+}
+
+static void bcm_remove_op(struct bcm_op *op)
+{
+       del_timer(&op->timer);
+       del_timer(&op->thrtimer);
+
+       if ((op->frames) && (op->frames != &op->sframe))
+               kfree(op->frames);
+
+       if ((op->last_frames) && (op->last_frames != &op->last_sframe))
+               kfree(op->last_frames);
+
+       kfree(op);
+
+       return;
+}
+
+static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
+{
+       if (op->rx_reg_dev == dev) {
+               can_rx_unregister(dev, op->can_id, REGMASK(op->can_id),
+                                 bcm_rx_handler, op);
+
+               /* mark as removed subscription */
+               op->rx_reg_dev = NULL;
+       } else
+               printk(KERN_ERR "can-bcm: bcm_rx_unreg: registered device "
+                      "mismatch %p %p\n", op->rx_reg_dev, dev);
+}
+
+/*
+ * bcm_delete_rx_op - find and remove a rx op (returns number of removed ops)
+ */
+static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
+{
+       struct bcm_op *op, *n;
+
+       list_for_each_entry_safe(op, n, ops, list) {
+               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
+
+                       /*
+                        * Don't care if we're bound or not (due to netdev
+                        * problems) can_rx_unregister() is always a save
+                        * thing to do here.
+                        */
+                       if (op->ifindex) {
+                               /*
+                                * Only remove subscriptions that had not
+                                * been removed due to NETDEV_UNREGISTER
+                                * in bcm_notifier()
+                                */
+                               if (op->rx_reg_dev) {
+                                       struct net_device *dev;
+
+                                       dev = dev_get_by_index(&init_net,
+                                                              op->ifindex);
+                                       if (dev) {
+                                               bcm_rx_unreg(dev, op);
+                                               dev_put(dev);
+                                       }
+                               }
+                       } else
+                               can_rx_unregister(NULL, op->can_id,
+                                                 REGMASK(op->can_id),
+                                                 bcm_rx_handler, op);
+
+                       list_del(&op->list);
+                       bcm_remove_op(op);
+                       return 1; /* done */
+               }
+       }
+
+       return 0; /* not found */
+}
+
+/*
+ * bcm_delete_tx_op - find and remove a tx op (returns number of removed ops)
+ */
+static int bcm_delete_tx_op(struct list_head *ops, canid_t can_id, int ifindex)
+{
+       struct bcm_op *op, *n;
+
+       list_for_each_entry_safe(op, n, ops, list) {
+               if ((op->can_id == can_id) && (op->ifindex == ifindex)) {
+                       list_del(&op->list);
+                       bcm_remove_op(op);
+                       return 1; /* done */
+               }
+       }
+
+       return 0; /* not found */
+}
+
+/*
+ * bcm_read_op - read out a bcm_op and send it to the user (for bcm_sendmsg)
+ */
+static int bcm_read_op(struct list_head *ops, struct bcm_msg_head *msg_head,
+                      int ifindex)
+{
+       struct bcm_op *op = bcm_find_op(ops, msg_head->can_id, ifindex);
+
+       if (!op)
+               return -EINVAL;
+
+       /* put current values into msg_head */
+       msg_head->flags   = op->flags;
+       msg_head->count   = op->count;
+       msg_head->ival1   = op->ival1;
+       msg_head->ival2   = op->ival2;
+       msg_head->nframes = op->nframes;
+
+       bcm_send_to_user(op, msg_head, op->frames, 0);
+
+       return MHSIZ;
+}
+
+/*
+ * bcm_tx_setup - create or update a bcm tx op (for bcm_sendmsg)
+ */
+static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+                       int ifindex, struct sock *sk)
+{
+       struct bcm_sock *bo = bcm_sk(sk);
+       struct bcm_op *op;
+       int i, err;
+
+       /* we need a real device to send frames */
+       if (!ifindex)
+               return -ENODEV;
+
+       /* we need at least one can_frame */
+       if (msg_head->nframes < 1)
+               return -EINVAL;
+
+       /* check the given can_id */
+       op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex);
+
+       if (op) {
+               /* update existing BCM operation */
+
+               /*
+                * Do we need more space for the can_frames than currently
+                * allocated? -> This is a _really_ unusual use-case and
+                * therefore (complexity / locking) it is not supported.
+                */
+               if (msg_head->nframes > op->nframes)
+                       return -E2BIG;
+
+               /* update can_frames content */
+               for (i = 0; i < msg_head->nframes; i++) {
+                       err = memcpy_fromiovec((u8 *)&op->frames[i],
+                                              msg->msg_iov, CFSIZ);
+                       if (err < 0)
+                               return err;
+
+                       if (msg_head->flags & TX_CP_CAN_ID) {
+                               /* copy can_id into frame */
+                               op->frames[i].can_id = msg_head->can_id;
+                       }
+               }
+
+       } else {
+               /* insert new BCM operation for the given can_id */
+
+               op = kzalloc(OPSIZ, GFP_KERNEL);
+               if (!op)
+                       return -ENOMEM;
+
+               op->can_id    = msg_head->can_id;
+
+               /* create array for can_frames and copy the data */
+               if (msg_head->nframes > 1) {
+                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
+                                            GFP_KERNEL);
+                       if (!op->frames) {
+                               kfree(op);
+                               return -ENOMEM;
+                       }
+               } else
+                       op->frames = &op->sframe;
+
+               for (i = 0; i < msg_head->nframes; i++) {
+                       err = memcpy_fromiovec((u8 *)&op->frames[i],
+                                              msg->msg_iov, CFSIZ);
+                       if (err < 0) {
+                               if (op->frames != &op->sframe)
+                                       kfree(op->frames);
+                               kfree(op);
+                               return err;
+                       }
+
+                       if (msg_head->flags & TX_CP_CAN_ID) {
+                               /* copy can_id into frame */
+                               op->frames[i].can_id = msg_head->can_id;
+                       }
+               }
+
+               /* tx_ops never compare with previous received messages */
+               op->last_frames = NULL;
+
+               /* bcm_can_tx / bcm_tx_timeout_handler needs this */
+               op->sk = sk;
+               op->ifindex = ifindex;
+
+               /* initialize uninitialized (kzalloc) structure */
+               setup_timer(&op->timer, bcm_tx_timeout_handler,
+                           (unsigned long)op);
+
+               /* currently unused in tx_ops */
+               init_timer(&op->thrtimer);
+
+               /* add this bcm_op to the list of the tx_ops */
+               list_add(&op->list, &bo->tx_ops);
+
+       } /* if ((op = bcm_find_op(&bo->tx_ops, msg_head->can_id, ifindex))) */
+
+       if (op->nframes != msg_head->nframes) {
+               op->nframes   = msg_head->nframes;
+               /* start multiple frame transmission with index 0 */
+               op->currframe = 0;
+       }
+
+       /* check flags */
+
+       op->flags = msg_head->flags;
+
+       if (op->flags & TX_RESET_MULTI_IDX) {
+               /* start multiple frame transmission with index 0 */
+               op->currframe = 0;
+       }
+
+       if (op->flags & SETTIMER) {
+               /* set timer values */
+               op->count = msg_head->count;
+               op->ival1 = msg_head->ival1;
+               op->ival2 = msg_head->ival2;
+               op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
+               op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
+
+               /* disable an active timer due to zero values? */
+               if (!op->j_ival1 && !op->j_ival2)
+                       del_timer(&op->timer);
+       }
+
+       if ((op->flags & STARTTIMER) &&
+           ((op->j_ival1 && op->count) || op->j_ival2)) {
+
+               /* spec: send can_frame when starting timer */
+               op->flags |= TX_ANNOUNCE;
+
+               if (op->j_ival1 && (op->count > 0)) {
+                       /* op->count-- is done in bcm_tx_timeout_handler */
+                       mod_timer(&op->timer, jiffies + op->j_ival1);
+               } else
+                       mod_timer(&op->timer, jiffies + op->j_ival2);
+       }
+
+       if (op->flags & TX_ANNOUNCE)
+               bcm_can_tx(op);
+
+       return msg_head->nframes * CFSIZ + MHSIZ;
+}
+
+/*
+ * bcm_rx_setup - create or update a bcm rx op (for bcm_sendmsg)
+ */
+static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+                       int ifindex, struct sock *sk)
+{
+       struct bcm_sock *bo = bcm_sk(sk);
+       struct bcm_op *op;
+       int do_rx_register;
+       int err = 0;
+
+       if ((msg_head->flags & RX_FILTER_ID) || (!(msg_head->nframes))) {
+               /* be robust against wrong usage ... */
+               msg_head->flags |= RX_FILTER_ID;
+               /* ignore trailing garbage */
+               msg_head->nframes = 0;
+       }
+
+       if ((msg_head->flags & RX_RTR_FRAME) &&
+           ((msg_head->nframes != 1) ||
+            (!(msg_head->can_id & CAN_RTR_FLAG))))
+               return -EINVAL;
+
+       /* check the given can_id */
+       op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex);
+       if (op) {
+               /* update existing BCM operation */
+
+               /*
+                * Do we need more space for the can_frames than currently
+                * allocated? -> This is a _really_ unusual use-case and
+                * therefore (complexity / locking) it is not supported.
+                */
+               if (msg_head->nframes > op->nframes)
+                       return -E2BIG;
+
+               if (msg_head->nframes) {
+                       /* update can_frames content */
+                       err = memcpy_fromiovec((u8 *)op->frames,
+                                              msg->msg_iov,
+                                              msg_head->nframes * CFSIZ);
+                       if (err < 0)
+                               return err;
+
+                       /* clear last_frames to indicate 'nothing received' */
+                       memset(op->last_frames, 0, msg_head->nframes * CFSIZ);
+               }
+
+               op->nframes = msg_head->nframes;
+
+               /* Only an update -> do not call can_rx_register() */
+               do_rx_register = 0;
+
+       } else {
+               /* insert new BCM operation for the given can_id */
+               op = kzalloc(OPSIZ, GFP_KERNEL);
+               if (!op)
+                       return -ENOMEM;
+
+               op->can_id    = msg_head->can_id;
+               op->nframes   = msg_head->nframes;
+
+               if (msg_head->nframes > 1) {
+                       /* create array for can_frames and copy the data */
+                       op->frames = kmalloc(msg_head->nframes * CFSIZ,
+                                            GFP_KERNEL);
+                       if (!op->frames) {
+                               kfree(op);
+                               return -ENOMEM;
+                       }
+
+                       /* create and init array for received can_frames */
+                       op->last_frames = kzalloc(msg_head->nframes * CFSIZ,
+                                                 GFP_KERNEL);
+                       if (!op->last_frames) {
+                               kfree(op->frames);
+                               kfree(op);
+                               return -ENOMEM;
+                       }
+
+               } else {
+                       op->frames = &op->sframe;
+                       op->last_frames = &op->last_sframe;
+               }
+
+               if (msg_head->nframes) {
+                       err = memcpy_fromiovec((u8 *)op->frames, msg->msg_iov,
+                                              msg_head->nframes * CFSIZ);
+                       if (err < 0) {
+                               if (op->frames != &op->sframe)
+                                       kfree(op->frames);
+                               if (op->last_frames != &op->last_sframe)
+                                       kfree(op->last_frames);
+                               kfree(op);
+                               return err;
+                       }
+               }
+
+               /* bcm_can_tx / bcm_tx_timeout_handler needs this */
+               op->sk = sk;
+               op->ifindex = ifindex;
+
+               /* initialize uninitialized (kzalloc) structure */
+               setup_timer(&op->timer, bcm_rx_timeout_handler,
+                           (unsigned long)op);
+
+               /* init throttle timer for RX_CHANGED */
+               setup_timer(&op->thrtimer, bcm_rx_thr_handler,
+                           (unsigned long)op);
+
+               /* mark disabled timer */
+               op->thrtimer.expires = 0;
+
+               /* add this bcm_op to the list of the rx_ops */
+               list_add(&op->list, &bo->rx_ops);
+
+               /* call can_rx_register() */
+               do_rx_register = 1;
+
+       } /* if ((op = bcm_find_op(&bo->rx_ops, msg_head->can_id, ifindex))) */
+
+       /* check flags */
+       op->flags = msg_head->flags;
+
+       if (op->flags & RX_RTR_FRAME) {
+
+               /* no timers in RTR-mode */
+               del_timer(&op->thrtimer);
+               del_timer(&op->timer);
+
+               /*
+                * funny feature in RX(!)_SETUP only for RTR-mode:
+                * copy can_id into frame BUT without RTR-flag to
+                * prevent a full-load-loopback-test ... ;-]
+                */
+               if ((op->flags & TX_CP_CAN_ID) ||
+                   (op->frames[0].can_id == op->can_id))
+                       op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG;
+
+       } else {
+               if (op->flags & SETTIMER) {
+
+                       /* set timer value */
+                       op->ival1 = msg_head->ival1;
+                       op->ival2 = msg_head->ival2;
+                       op->j_ival1 = rounded_tv2jif(&msg_head->ival1);
+                       op->j_ival2 = rounded_tv2jif(&msg_head->ival2);
+
+                       /* disable an active timer due to zero value? */
+                       if (!op->j_ival1)
+                               del_timer(&op->timer);
+
+                       /* free currently blocked msgs ? */
+                       if (op->thrtimer.expires) {
+                               /* send blocked msgs hereafter */
+                               mod_timer(&op->thrtimer, jiffies + 2);
+                       }
+
+                       /*
+                        * if (op->j_ival2) is zero, no (new) throttling
+                        * will happen. For details see functions
+                        * bcm_rx_update_and_send() and bcm_rx_thr_handler()
+                        */
+               }
+
+               if ((op->flags & STARTTIMER) && op->j_ival1)
+                       mod_timer(&op->timer, jiffies + op->j_ival1);
+       }
+
+       /* now we can register for can_ids, if we added a new bcm_op */
+       if (do_rx_register) {
+               if (ifindex) {
+                       struct net_device *dev;
+
+                       dev = dev_get_by_index(&init_net, ifindex);
+                       if (dev) {
+                               err = can_rx_register(dev, op->can_id,
+                                                     REGMASK(op->can_id),
+                                                     bcm_rx_handler, op,
+                                                     "bcm");
+
+                               op->rx_reg_dev = dev;
+                               dev_put(dev);
+                       }
+
+               } else
+                       err = can_rx_register(NULL, op->can_id,
+                                             REGMASK(op->can_id),
+                                             bcm_rx_handler, op, "bcm");
+               if (err) {
+                       /* this bcm rx op is broken -> remove it */
+                       list_del(&op->list);
+                       bcm_remove_op(op);
+                       return err;
+               }
+       }
+
+       return msg_head->nframes * CFSIZ + MHSIZ;
+}
+
+/*
+ * bcm_tx_send - send a single CAN frame to the CAN interface (for bcm_sendmsg)
+ */
+static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
+{
+       struct sk_buff *skb;
+       struct net_device *dev;
+       int err;
+
+       /* we need a real device to send frames */
+       if (!ifindex)
+               return -ENODEV;
+
+       skb = alloc_skb(CFSIZ, GFP_KERNEL);
+
+       if (!skb)
+               return -ENOMEM;
+
+       err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
+       if (err < 0) {
+               kfree_skb(skb);
+               return err;
+       }
+
+       dev = dev_get_by_index(&init_net, ifindex);
+       if (!dev) {
+               kfree_skb(skb);
+               return -ENODEV;
+       }
+
+       skb->dev = dev;
+       skb->sk  = sk;
+       can_send(skb, 1); /* send with loopback */
+       dev_put(dev);
+
+       return CFSIZ + MHSIZ;
+}
+
+/*
+ * bcm_sendmsg - process BCM commands (opcodes) from the userspace
+ */
+static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
+                      struct msghdr *msg, size_t size)
+{
+       struct sock *sk = sock->sk;
+       struct bcm_sock *bo = bcm_sk(sk);
+       int ifindex = bo->ifindex; /* default ifindex for this bcm_op */
+       struct bcm_msg_head msg_head;
+       int ret; /* read bytes or error codes as return value */
+
+       if (!bo->bound)
+               return -ENOTCONN;
+
+       /* check for alternative ifindex for this bcm_op */
+
+       if (!ifindex && msg->msg_name) {
+               /* no bound device as default => check msg_name */
+               struct sockaddr_can *addr =
+                       (struct sockaddr_can *)msg->msg_name;
+
+               if (addr->can_family != AF_CAN)
+                       return -EINVAL;
+
+               /* ifindex from sendto() */
+               ifindex = addr->can_ifindex;
+
+               if (ifindex) {
+                       struct net_device *dev;
+
+                       dev = dev_get_by_index(&init_net, ifindex);
+                       if (!dev)
+                               return -ENODEV;
+
+                       if (dev->type != ARPHRD_CAN) {
+                               dev_put(dev);
+                               return -ENODEV;
+                       }
+
+                       dev_put(dev);
+               }
+       }
+
+       /* read message head information */
+
+       ret = memcpy_fromiovec((u8 *)&msg_head, msg->msg_iov, MHSIZ);
+       if (ret < 0)
+               return ret;
+
+       lock_sock(sk);
+
+       switch (msg_head.opcode) {
+
+       case TX_SETUP:
+               ret = bcm_tx_setup(&msg_head, msg, ifindex, sk);
+               break;
+
+       case RX_SETUP:
+               ret = bcm_rx_setup(&msg_head, msg, ifindex, sk);
+               break;
+
+       case TX_DELETE:
+               if (bcm_delete_tx_op(&bo->tx_ops, msg_head.can_id, ifindex))
+                       ret = MHSIZ;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case RX_DELETE:
+               if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex))
+                       ret = MHSIZ;
+               else
+                       ret = -EINVAL;
+               break;
+
+       case TX_READ:
+               /* reuse msg_head for the reply to TX_READ */
+               msg_head.opcode  = TX_STATUS;
+               ret = bcm_read_op(&bo->tx_ops, &msg_head, ifindex);
+               break;
+
+       case RX_READ:
+               /* reuse msg_head for the reply to RX_READ */
+               msg_head.opcode  = RX_STATUS;
+               ret = bcm_read_op(&bo->rx_ops, &msg_head, ifindex);
+               break;
+
+       case TX_SEND:
+               /* we need at least one can_frame */
+               if (msg_head.nframes < 1)
+                       ret = -EINVAL;
+               else
+                       ret = bcm_tx_send(msg, ifindex, sk);
+               break;
+
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       release_sock(sk);
+
+       return ret;
+}
+
+/*
+ * notification handler for netdevice status changes
+ */
+static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
+                       void *data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);
+       struct sock *sk = &bo->sk;
+       struct bcm_op *op;
+       int notify_enodev = 0;
+
+       if (dev->nd_net != &init_net)
+               return NOTIFY_DONE;
+
+       if (dev->type != ARPHRD_CAN)
+               return NOTIFY_DONE;
+
+       switch (msg) {
+
+       case NETDEV_UNREGISTER:
+               lock_sock(sk);
+
+               /* remove device specific receive entries */
+               list_for_each_entry(op, &bo->rx_ops, list)
+                       if (op->rx_reg_dev == dev)
+                               bcm_rx_unreg(dev, op);
+
+               /* remove device reference, if this is our bound device */
+               if (bo->bound && bo->ifindex == dev->ifindex) {
+                       bo->bound   = 0;
+                       bo->ifindex = 0;
+                       notify_enodev = 1;
+               }
+
+               release_sock(sk);
+
+               if (notify_enodev) {
+                       sk->sk_err = ENODEV;
+                       if (!sock_flag(sk, SOCK_DEAD))
+                               sk->sk_error_report(sk);
+               }
+               break;
+
+       case NETDEV_DOWN:
+               if (bo->bound && bo->ifindex == dev->ifindex) {
+                       sk->sk_err = ENETDOWN;
+                       if (!sock_flag(sk, SOCK_DEAD))
+                               sk->sk_error_report(sk);
+               }
+       }
+
+       return NOTIFY_DONE;
+}
+
+/*
+ * initial settings for all BCM sockets to be set at socket creation time
+ */
+static int bcm_init(struct sock *sk)
+{
+       struct bcm_sock *bo = bcm_sk(sk);
+
+       bo->bound            = 0;
+       bo->ifindex          = 0;
+       bo->dropped_usr_msgs = 0;
+       bo->bcm_proc_read    = NULL;
+
+       INIT_LIST_HEAD(&bo->tx_ops);
+       INIT_LIST_HEAD(&bo->rx_ops);
+
+       /* set notifier */
+       bo->notifier.notifier_call = bcm_notifier;
+
+       register_netdevice_notifier(&bo->notifier);
+
+       return 0;
+}
+
+/*
+ * standard socket functions
+ */
+static int bcm_release(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+       struct bcm_sock *bo = bcm_sk(sk);
+       struct bcm_op *op, *next;
+
+       /* remove bcm_ops, timer, rx_unregister(), etc. */
+
+       unregister_netdevice_notifier(&bo->notifier);
+
+       lock_sock(sk);
+
+       list_for_each_entry_safe(op, next, &bo->tx_ops, list)
+               bcm_remove_op(op);
+
+       list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
+               /*
+                * Don't care if we're bound or not (due to netdev problems)
+                * can_rx_unregister() is always a save thing to do here.
+                */
+               if (op->ifindex) {
+                       /*
+                        * Only remove subscriptions that had not
+                        * been removed due to NETDEV_UNREGISTER
+                        * in bcm_notifier()
+                        */
+                       if (op->rx_reg_dev) {
+                               struct net_device *dev;
+
+                               dev = dev_get_by_index(&init_net, op->ifindex);
+                               if (dev) {
+                                       bcm_rx_unreg(dev, op);
+                                       dev_put(dev);
+                               }
+                       }
+               } else
+                       can_rx_unregister(NULL, op->can_id,
+                                         REGMASK(op->can_id),
+                                         bcm_rx_handler, op);
+
+               bcm_remove_op(op);
+       }
+
+       /* remove procfs entry */
+       if (proc_dir && bo->bcm_proc_read)
+               remove_proc_entry(bo->procname, proc_dir);
+
+       /* remove device reference */
+       if (bo->bound) {
+               bo->bound   = 0;
+               bo->ifindex = 0;
+       }
+
+       release_sock(sk);
+       sock_put(sk);
+
+       return 0;
+}
+
+static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
+                      int flags)
+{
+       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+       struct sock *sk = sock->sk;
+       struct bcm_sock *bo = bcm_sk(sk);
+
+       if (bo->bound)
+               return -EISCONN;
+
+       /* bind a device to this socket */
+       if (addr->can_ifindex) {
+               struct net_device *dev;
+
+               dev = dev_get_by_index(&init_net, addr->can_ifindex);
+               if (!dev)
+                       return -ENODEV;
+
+               if (dev->type != ARPHRD_CAN) {
+                       dev_put(dev);
+                       return -ENODEV;
+               }
+
+               bo->ifindex = dev->ifindex;
+               dev_put(dev);
+
+       } else {
+               /* no interface reference for ifindex = 0 ('any' CAN device) */
+               bo->ifindex = 0;
+       }
+
+       bo->bound = 1;
+
+       if (proc_dir) {
+               /* unique socket address as filename */
+               sprintf(bo->procname, "%p", sock);
+               bo->bcm_proc_read = create_proc_read_entry(bo->procname, 0644,
+                                                          proc_dir,
+                                                          bcm_read_proc, sk);
+       }
+
+       return 0;
+}
+
+static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
+                      struct msghdr *msg, size_t size, int flags)
+{
+       struct sock *sk = sock->sk;
+       struct sk_buff *skb;
+       int error = 0;
+       int noblock;
+       int err;
+
+       noblock =  flags & MSG_DONTWAIT;
+       flags   &= ~MSG_DONTWAIT;
+       skb = skb_recv_datagram(sk, flags, noblock, &error);
+       if (!skb)
+               return error;
+
+       if (skb->len < size)
+               size = skb->len;
+
+       err = memcpy_toiovec(msg->msg_iov, skb->data, size);
+       if (err < 0) {
+               skb_free_datagram(sk, skb);
+               return err;
+       }
+
+       sock_recv_timestamp(msg, sk, skb);
+
+       if (msg->msg_name) {
+               msg->msg_namelen = sizeof(struct sockaddr_can);
+               memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
+       }
+
+       skb_free_datagram(sk, skb);
+
+       return size;
+}
+
+static struct proto_ops bcm_ops __read_mostly = {
+       .family        = PF_CAN,
+       .release       = bcm_release,
+       .bind          = sock_no_bind,
+       .connect       = bcm_connect,
+       .socketpair    = sock_no_socketpair,
+       .accept        = sock_no_accept,
+       .getname       = sock_no_getname,
+       .poll          = datagram_poll,
+       .ioctl         = NULL,          /* use can_ioctl() from af_can.c */
+       .listen        = sock_no_listen,
+       .shutdown      = sock_no_shutdown,
+       .setsockopt    = sock_no_setsockopt,
+       .getsockopt    = sock_no_getsockopt,
+       .sendmsg       = bcm_sendmsg,
+       .recvmsg       = bcm_recvmsg,
+       .mmap          = sock_no_mmap,
+       .sendpage      = sock_no_sendpage,
+};
+
+static struct proto bcm_proto __read_mostly = {
+       .name       = "CAN_BCM",
+       .owner      = THIS_MODULE,
+       .obj_size   = sizeof(struct bcm_sock),
+       .init       = bcm_init,
+};
+
+static struct can_proto bcm_can_proto __read_mostly = {
+       .type       = SOCK_DGRAM,
+       .protocol   = CAN_BCM,
+       .capability = -1,
+       .ops        = &bcm_ops,
+       .prot       = &bcm_proto,
+};
+
+static int __init bcm_module_init(void)
+{
+       int err;
+
+       printk(banner);
+
+       err = can_proto_register(&bcm_can_proto);
+       if (err < 0) {
+               printk(KERN_ERR "can: registration of bcm protocol failed\n");
+               return err;
+       }
+
+       /* create /proc/net/can-bcm directory */
+       proc_dir = proc_mkdir("can-bcm", init_net.proc_net);
+
+       if (proc_dir)
+               proc_dir->owner = THIS_MODULE;
+
+       return 0;
+}
+
+static void __exit bcm_module_exit(void)
+{
+       can_proto_unregister(&bcm_can_proto);
+
+       if (proc_dir)
+               proc_net_remove(&init_net, "can-bcm");
+}
+
+module_init(bcm_module_init);
+module_exit(bcm_module_exit);
diff --git a/net/can/proc.c b/net/can/proc.c
new file mode 100644 (file)
index 0000000..520fef5
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * proc.c - procfs support for Protocol family CAN core module
+ *
+ * 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/proc_fs.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/can/core.h>
+
+#include "af_can.h"
+
+/*
+ * proc filenames for the PF_CAN core
+ */
+
+#define CAN_PROC_VERSION     "version"
+#define CAN_PROC_STATS       "stats"
+#define CAN_PROC_RESET_STATS "reset_stats"
+#define CAN_PROC_RCVLIST_ALL "rcvlist_all"
+#define CAN_PROC_RCVLIST_FIL "rcvlist_fil"
+#define CAN_PROC_RCVLIST_INV "rcvlist_inv"
+#define CAN_PROC_RCVLIST_SFF "rcvlist_sff"
+#define CAN_PROC_RCVLIST_EFF "rcvlist_eff"
+#define CAN_PROC_RCVLIST_ERR "rcvlist_err"
+
+static struct proc_dir_entry *can_dir;
+static struct proc_dir_entry *pde_version;
+static struct proc_dir_entry *pde_stats;
+static struct proc_dir_entry *pde_reset_stats;
+static struct proc_dir_entry *pde_rcvlist_all;
+static struct proc_dir_entry *pde_rcvlist_fil;
+static struct proc_dir_entry *pde_rcvlist_inv;
+static struct proc_dir_entry *pde_rcvlist_sff;
+static struct proc_dir_entry *pde_rcvlist_eff;
+static struct proc_dir_entry *pde_rcvlist_err;
+
+static int user_reset;
+
+static const char rx_list_name[][8] = {
+       [RX_ERR] = "rx_err",
+       [RX_ALL] = "rx_all",
+       [RX_FIL] = "rx_fil",
+       [RX_INV] = "rx_inv",
+       [RX_EFF] = "rx_eff",
+};
+
+/*
+ * af_can statistics stuff
+ */
+
+static void can_init_stats(void)
+{
+       /*
+        * This memset function is called from a timer context (when
+        * can_stattimer is active which is the default) OR in a process
+        * context (reading the proc_fs when can_stattimer is disabled).
+        */
+       memset(&can_stats, 0, sizeof(can_stats));
+       can_stats.jiffies_init = jiffies;
+
+       can_pstats.stats_reset++;
+
+       if (user_reset) {
+               user_reset = 0;
+               can_pstats.user_reset++;
+       }
+}
+
+static unsigned long calc_rate(unsigned long oldjif, unsigned long newjif,
+                              unsigned long count)
+{
+       unsigned long rate;
+
+       if (oldjif == newjif)
+               return 0;
+
+       /* see can_stat_update() - this should NEVER happen! */
+       if (count > (ULONG_MAX / HZ)) {
+               printk(KERN_ERR "can: calc_rate: count exceeded! %ld\n",
+                      count);
+               return 99999999;
+       }
+
+       rate = (count * HZ) / (newjif - oldjif);
+
+       return rate;
+}
+
+void can_stat_update(unsigned long data)
+{
+       unsigned long j = jiffies; /* snapshot */
+
+       /* restart counting in timer context on user request */
+       if (user_reset)
+               can_init_stats();
+
+       /* restart counting on jiffies overflow */
+       if (j < can_stats.jiffies_init)
+               can_init_stats();
+
+       /* prevent overflow in calc_rate() */
+       if (can_stats.rx_frames > (ULONG_MAX / HZ))
+               can_init_stats();
+
+       /* prevent overflow in calc_rate() */
+       if (can_stats.tx_frames > (ULONG_MAX / HZ))
+               can_init_stats();
+
+       /* matches overflow - very improbable */
+       if (can_stats.matches > (ULONG_MAX / 100))
+               can_init_stats();
+
+       /* calc total values */
+       if (can_stats.rx_frames)
+               can_stats.total_rx_match_ratio = (can_stats.matches * 100) /
+                       can_stats.rx_frames;
+
+       can_stats.total_tx_rate = calc_rate(can_stats.jiffies_init, j,
+                                           can_stats.tx_frames);
+       can_stats.total_rx_rate = calc_rate(can_stats.jiffies_init, j,
+                                           can_stats.rx_frames);
+
+       /* calc current values */
+       if (can_stats.rx_frames_delta)
+               can_stats.current_rx_match_ratio =
+                       (can_stats.matches_delta * 100) /
+                       can_stats.rx_frames_delta;
+
+       can_stats.current_tx_rate = calc_rate(0, HZ, can_stats.tx_frames_delta);
+       can_stats.current_rx_rate = calc_rate(0, HZ, can_stats.rx_frames_delta);
+
+       /* check / update maximum values */
+       if (can_stats.max_tx_rate < can_stats.current_tx_rate)
+               can_stats.max_tx_rate = can_stats.current_tx_rate;
+
+       if (can_stats.max_rx_rate < can_stats.current_rx_rate)
+               can_stats.max_rx_rate = can_stats.current_rx_rate;
+
+       if (can_stats.max_rx_match_ratio < can_stats.current_rx_match_ratio)
+               can_stats.max_rx_match_ratio = can_stats.current_rx_match_ratio;
+
+       /* clear values for 'current rate' calculation */
+       can_stats.tx_frames_delta = 0;
+       can_stats.rx_frames_delta = 0;
+       can_stats.matches_delta   = 0;
+
+       /* restart timer (one second) */
+       mod_timer(&can_stattimer, round_jiffies(jiffies + HZ));
+}
+
+/*
+ * proc read functions
+ *
+ * From known use-cases we expect about 10 entries in a receive list to be
+ * printed in the proc_fs. So PAGE_SIZE is definitely enough space here.
+ *
+ */
+
+static int can_print_rcvlist(char *page, int len, struct hlist_head *rx_list,
+                            struct net_device *dev)
+{
+       struct receiver *r;
+       struct hlist_node *n;
+
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(r, n, rx_list, list) {
+               char *fmt = (r->can_id & CAN_EFF_FLAG)?
+                       "   %-5s  %08X  %08x  %08x  %08x  %8ld  %s\n" :
+                       "   %-5s     %03X    %08x  %08lx  %08lx  %8ld  %s\n";
+
+               len += snprintf(page + len, PAGE_SIZE - len, fmt,
+                               DNAME(dev), r->can_id, r->mask,
+                               (unsigned long)r->func, (unsigned long)r->data,
+                               r->matches, r->ident);
+
+               /* does a typical line fit into the current buffer? */
+
+               /* 100 Bytes before end of buffer */
+               if (len > PAGE_SIZE - 100) {
+                       /* mark output cut off */
+                       len += snprintf(page + len, PAGE_SIZE - len,
+                                       "   (..)\n");
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return len;
+}
+
+static int can_print_recv_banner(char *page, int len)
+{
+       /*
+        *                  can1.  00000000  00000000  00000000
+        *                 .......          0  tp20
+        */
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       "  device   can_id   can_mask  function"
+                       "  userdata   matches  ident\n");
+
+       return len;
+}
+
+static int can_proc_read_stats(char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
+{
+       int len = 0;
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       " %8ld transmitted frames (TXF)\n",
+                       can_stats.tx_frames);
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       " %8ld received frames (RXF)\n", can_stats.rx_frames);
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       " %8ld matched frames (RXMF)\n", can_stats.matches);
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+       if (can_stattimer.function == can_stat_update) {
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld %% total match ratio (RXMR)\n",
+                               can_stats.total_rx_match_ratio);
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s total tx rate (TXR)\n",
+                               can_stats.total_tx_rate);
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s total rx rate (RXR)\n",
+                               can_stats.total_rx_rate);
+
+               len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld %% current match ratio (CRXMR)\n",
+                               can_stats.current_rx_match_ratio);
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s current tx rate (CTXR)\n",
+                               can_stats.current_tx_rate);
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s current rx rate (CRXR)\n",
+                               can_stats.current_rx_rate);
+
+               len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld %% max match ratio (MRXMR)\n",
+                               can_stats.max_rx_match_ratio);
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s max tx rate (MTXR)\n",
+                               can_stats.max_tx_rate);
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld frames/s max rx rate (MRXR)\n",
+                               can_stats.max_rx_rate);
+
+               len += snprintf(page + len, PAGE_SIZE - len, "\n");
+       }
+
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       " %8ld current receive list entries (CRCV)\n",
+                       can_pstats.rcv_entries);
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       " %8ld maximum receive list entries (MRCV)\n",
+                       can_pstats.rcv_entries_max);
+
+       if (can_pstats.stats_reset)
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "\n %8ld statistic resets (STR)\n",
+                               can_pstats.stats_reset);
+
+       if (can_pstats.user_reset)
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               " %8ld user statistic resets (USTR)\n",
+                               can_pstats.user_reset);
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+       *eof = 1;
+       return len;
+}
+
+static int can_proc_read_reset_stats(char *page, char **start, off_t off,
+                                    int count, int *eof, void *data)
+{
+       int len = 0;
+
+       user_reset = 1;
+
+       if (can_stattimer.function == can_stat_update) {
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "Scheduled statistic reset #%ld.\n",
+                               can_pstats.stats_reset + 1);
+
+       } else {
+               if (can_stats.jiffies_init != jiffies)
+                       can_init_stats();
+
+               len += snprintf(page + len, PAGE_SIZE - len,
+                               "Performed statistic reset #%ld.\n",
+                               can_pstats.stats_reset);
+       }
+
+       *eof = 1;
+       return len;
+}
+
+static int can_proc_read_version(char *page, char **start, off_t off,
+                                int count, int *eof, void *data)
+{
+       int len = 0;
+
+       len += snprintf(page + len, PAGE_SIZE - len, "%s\n",
+                       CAN_VERSION_STRING);
+       *eof = 1;
+       return len;
+}
+
+static int can_proc_read_rcvlist(char *page, char **start, off_t off,
+                                int count, int *eof, void *data)
+{
+       /* double cast to prevent GCC warning */
+       int idx = (int)(long)data;
+       int len = 0;
+       struct dev_rcv_lists *d;
+       struct hlist_node *n;
+
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       "\nreceive list '%s':\n", rx_list_name[idx]);
+
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
+
+               if (!hlist_empty(&d->rx[idx])) {
+                       len = can_print_recv_banner(page, len);
+                       len = can_print_rcvlist(page, len, &d->rx[idx], d->dev);
+               } else
+                       len += snprintf(page + len, PAGE_SIZE - len,
+                                       "  (%s: no entry)\n", DNAME(d->dev));
+
+               /* exit on end of buffer? */
+               if (len > PAGE_SIZE - 100)
+                       break;
+       }
+       rcu_read_unlock();
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+       *eof = 1;
+       return len;
+}
+
+static int can_proc_read_rcvlist_sff(char *page, char **start, off_t off,
+                                    int count, int *eof, void *data)
+{
+       int len = 0;
+       struct dev_rcv_lists *d;
+       struct hlist_node *n;
+
+       /* RX_SFF */
+       len += snprintf(page + len, PAGE_SIZE - len,
+                       "\nreceive list 'rx_sff':\n");
+
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(d, n, &can_rx_dev_list, list) {
+               int i, all_empty = 1;
+               /* check wether at least one list is non-empty */
+               for (i = 0; i < 0x800; i++)
+                       if (!hlist_empty(&d->rx_sff[i])) {
+                               all_empty = 0;
+                               break;
+                       }
+
+               if (!all_empty) {
+                       len = can_print_recv_banner(page, len);
+                       for (i = 0; i < 0x800; i++) {
+                               if (!hlist_empty(&d->rx_sff[i]) &&
+                                   len < PAGE_SIZE - 100)
+                                       len = can_print_rcvlist(page, len,
+                                                               &d->rx_sff[i],
+                                                               d->dev);
+                       }
+               } else
+                       len += snprintf(page + len, PAGE_SIZE - len,
+                                       "  (%s: no entry)\n", DNAME(d->dev));
+
+               /* exit on end of buffer? */
+               if (len > PAGE_SIZE - 100)
+                       break;
+       }
+       rcu_read_unlock();
+
+       len += snprintf(page + len, PAGE_SIZE - len, "\n");
+
+       *eof = 1;
+       return len;
+}
+
+/*
+ * proc utility functions
+ */
+
+static struct proc_dir_entry *can_create_proc_readentry(const char *name,
+                                                       mode_t mode,
+                                                       read_proc_t *read_proc,
+                                                       void *data)
+{
+       if (can_dir)
+               return create_proc_read_entry(name, mode, can_dir, read_proc,
+                                             data);
+       else
+               return NULL;
+}
+
+static void can_remove_proc_readentry(const char *name)
+{
+       if (can_dir)
+               remove_proc_entry(name, can_dir);
+}
+
+/*
+ * can_init_proc - create main CAN proc directory and procfs entries
+ */
+void can_init_proc(void)
+{
+       /* create /proc/net/can directory */
+       can_dir = proc_mkdir("can", init_net.proc_net);
+
+       if (!can_dir) {
+               printk(KERN_INFO "can: failed to create /proc/net/can . "
+                      "CONFIG_PROC_FS missing?\n");
+               return;
+       }
+
+       can_dir->owner = THIS_MODULE;
+
+       /* own procfs entries from the AF_CAN core */
+       pde_version     = can_create_proc_readentry(CAN_PROC_VERSION, 0644,
+                                       can_proc_read_version, NULL);
+       pde_stats       = can_create_proc_readentry(CAN_PROC_STATS, 0644,
+                                       can_proc_read_stats, NULL);
+       pde_reset_stats = can_create_proc_readentry(CAN_PROC_RESET_STATS, 0644,
+                                       can_proc_read_reset_stats, NULL);
+       pde_rcvlist_err = can_create_proc_readentry(CAN_PROC_RCVLIST_ERR, 0644,
+                                       can_proc_read_rcvlist, (void *)RX_ERR);
+       pde_rcvlist_all = can_create_proc_readentry(CAN_PROC_RCVLIST_ALL, 0644,
+                                       can_proc_read_rcvlist, (void *)RX_ALL);
+       pde_rcvlist_fil = can_create_proc_readentry(CAN_PROC_RCVLIST_FIL, 0644,
+                                       can_proc_read_rcvlist, (void *)RX_FIL);
+       pde_rcvlist_inv = can_create_proc_readentry(CAN_PROC_RCVLIST_INV, 0644,
+                                       can_proc_read_rcvlist, (void *)RX_INV);
+       pde_rcvlist_eff = can_create_proc_readentry(CAN_PROC_RCVLIST_EFF, 0644,
+                                       can_proc_read_rcvlist, (void *)RX_EFF);
+       pde_rcvlist_sff = can_create_proc_readentry(CAN_PROC_RCVLIST_SFF, 0644,
+                                       can_proc_read_rcvlist_sff, NULL);
+}
+
+/*
+ * can_remove_proc - remove procfs entries and main CAN proc directory
+ */
+void can_remove_proc(void)
+{
+       if (pde_version)
+               can_remove_proc_readentry(CAN_PROC_VERSION);
+
+       if (pde_stats)
+               can_remove_proc_readentry(CAN_PROC_STATS);
+
+       if (pde_reset_stats)
+               can_remove_proc_readentry(CAN_PROC_RESET_STATS);
+
+       if (pde_rcvlist_err)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_ERR);
+
+       if (pde_rcvlist_all)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_ALL);
+
+       if (pde_rcvlist_fil)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_FIL);
+
+       if (pde_rcvlist_inv)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_INV);
+
+       if (pde_rcvlist_eff)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_EFF);
+
+       if (pde_rcvlist_sff)
+               can_remove_proc_readentry(CAN_PROC_RCVLIST_SFF);
+
+       if (can_dir)
+               proc_net_remove(&init_net, "can");
+}
diff --git a/net/can/raw.c b/net/can/raw.c
new file mode 100644 (file)
index 0000000..aeefd14
--- /dev/null
@@ -0,0 +1,763 @@
+/*
+ * raw.c - Raw sockets for protocol family CAN
+ *
+ * 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/uio.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/socket.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/can.h>
+#include <linux/can/core.h>
+#include <linux/can/raw.h>
+#include <net/sock.h>
+#include <net/net_namespace.h>
+
+#define CAN_RAW_VERSION CAN_VERSION
+static __initdata const char banner[] =
+       KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
+
+MODULE_DESCRIPTION("PF_CAN raw protocol");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
+
+#define MASK_ALL 0
+
+/*
+ * A raw socket has a list of can_filters attached to it, each receiving
+ * the CAN frames matching that filter.  If the filter list is empty,
+ * no CAN frames will be received by the socket.  The default after
+ * opening the socket, is to have one filter which receives all frames.
+ * The filter list is allocated dynamically with the exception of the
+ * list containing only one item.  This common case is optimized by
+ * storing the single filter in dfilter, to avoid using dynamic memory.
+ */
+
+struct raw_sock {
+       struct sock sk;
+       int bound;
+       int ifindex;
+       struct notifier_block notifier;
+       int loopback;
+       int recv_own_msgs;
+       int count;                 /* number of active filters */
+       struct can_filter dfilter; /* default/single filter */
+       struct can_filter *filter; /* pointer to filter(s) */
+       can_err_mask_t err_mask;
+};
+
+static inline struct raw_sock *raw_sk(const struct sock *sk)
+{
+       return (struct raw_sock *)sk;
+}
+
+static void raw_rcv(struct sk_buff *skb, void *data)
+{
+       struct sock *sk = (struct sock *)data;
+       struct raw_sock *ro = raw_sk(sk);
+       struct sockaddr_can *addr;
+       int error;
+
+       if (!ro->recv_own_msgs) {
+               /* check the received tx sock reference */
+               if (skb->sk == sk) {
+                       kfree_skb(skb);
+                       return;
+               }
+       }
+
+       /*
+        *  Put the datagram to the queue so that raw_recvmsg() can
+        *  get it from there.  We need to pass the interface index to
+        *  raw_recvmsg().  We pass a whole struct sockaddr_can in skb->cb
+        *  containing the interface index.
+        */
+
+       BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct sockaddr_can));
+       addr = (struct sockaddr_can *)skb->cb;
+       memset(addr, 0, sizeof(*addr));
+       addr->can_family  = AF_CAN;
+       addr->can_ifindex = skb->dev->ifindex;
+
+       error = sock_queue_rcv_skb(sk, skb);
+       if (error < 0)
+               kfree_skb(skb);
+}
+
+static int raw_enable_filters(struct net_device *dev, struct sock *sk,
+                             struct can_filter *filter,
+                             int count)
+{
+       int err = 0;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               err = can_rx_register(dev, filter[i].can_id,
+                                     filter[i].can_mask,
+                                     raw_rcv, sk, "raw");
+               if (err) {
+                       /* clean up successfully registered filters */
+                       while (--i >= 0)
+                               can_rx_unregister(dev, filter[i].can_id,
+                                                 filter[i].can_mask,
+                                                 raw_rcv, sk);
+                       break;
+               }
+       }
+
+       return err;
+}
+
+static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
+                               can_err_mask_t err_mask)
+{
+       int err = 0;
+
+       if (err_mask)
+               err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
+                                     raw_rcv, sk, "raw");
+
+       return err;
+}
+
+static void raw_disable_filters(struct net_device *dev, struct sock *sk,
+                             struct can_filter *filter,
+                             int count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask,
+                                 raw_rcv, sk);
+}
+
+static inline void raw_disable_errfilter(struct net_device *dev,
+                                        struct sock *sk,
+                                        can_err_mask_t err_mask)
+
+{
+       if (err_mask)
+               can_rx_unregister(dev, 0, err_mask | CAN_ERR_FLAG,
+                                 raw_rcv, sk);
+}
+
+static inline void raw_disable_allfilters(struct net_device *dev,
+                                         struct sock *sk)
+{
+       struct raw_sock *ro = raw_sk(sk);
+
+       raw_disable_filters(dev, sk, ro->filter, ro->count);
+       raw_disable_errfilter(dev, sk, ro->err_mask);
+}
+
+static int raw_enable_allfilters(struct net_device *dev, struct sock *sk)
+{
+       struct raw_sock *ro = raw_sk(sk);
+       int err;
+
+       err = raw_enable_filters(dev, sk, ro->filter, ro->count);
+       if (!err) {
+               err = raw_enable_errfilter(dev, sk, ro->err_mask);
+               if (err)
+                       raw_disable_filters(dev, sk, ro->filter, ro->count);
+       }
+
+       return err;
+}
+
+static int raw_notifier(struct notifier_block *nb,
+                       unsigned long msg, void *data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct raw_sock *ro = container_of(nb, struct raw_sock, notifier);
+       struct sock *sk = &ro->sk;
+
+       if (dev->nd_net != &init_net)
+               return NOTIFY_DONE;
+
+       if (dev->type != ARPHRD_CAN)
+               return NOTIFY_DONE;
+
+       if (ro->ifindex != dev->ifindex)
+               return NOTIFY_DONE;
+
+       switch (msg) {
+
+       case NETDEV_UNREGISTER:
+               lock_sock(sk);
+               /* remove current filters & unregister */
+               if (ro->bound)
+                       raw_disable_allfilters(dev, sk);
+
+               if (ro->count > 1)
+                       kfree(ro->filter);
+
+               ro->ifindex = 0;
+               ro->bound   = 0;
+               ro->count   = 0;
+               release_sock(sk);
+
+               sk->sk_err = ENODEV;
+               if (!sock_flag(sk, SOCK_DEAD))
+                       sk->sk_error_report(sk);
+               break;
+
+       case NETDEV_DOWN:
+               sk->sk_err = ENETDOWN;
+               if (!sock_flag(sk, SOCK_DEAD))
+                       sk->sk_error_report(sk);
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static int raw_init(struct sock *sk)
+{
+       struct raw_sock *ro = raw_sk(sk);
+
+       ro->bound            = 0;
+       ro->ifindex          = 0;
+
+       /* set default filter to single entry dfilter */
+       ro->dfilter.can_id   = 0;
+       ro->dfilter.can_mask = MASK_ALL;
+       ro->filter           = &ro->dfilter;
+       ro->count            = 1;
+
+       /* set default loopback behaviour */
+       ro->loopback         = 1;
+       ro->recv_own_msgs    = 0;
+
+       /* set notifier */
+       ro->notifier.notifier_call = raw_notifier;
+
+       register_netdevice_notifier(&ro->notifier);
+
+       return 0;
+}
+
+static int raw_release(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+
+       unregister_netdevice_notifier(&ro->notifier);
+
+       lock_sock(sk);
+
+       /* remove current filters & unregister */
+       if (ro->bound) {
+               if (ro->ifindex) {
+                       struct net_device *dev;
+
+                       dev = dev_get_by_index(&init_net, ro->ifindex);
+                       if (dev) {
+                               raw_disable_allfilters(dev, sk);
+                               dev_put(dev);
+                       }
+               } else
+                       raw_disable_allfilters(NULL, sk);
+       }
+
+       if (ro->count > 1)
+               kfree(ro->filter);
+
+       ro->ifindex = 0;
+       ro->bound   = 0;
+       ro->count   = 0;
+
+       release_sock(sk);
+       sock_put(sk);
+
+       return 0;
+}
+
+static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
+{
+       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+       int ifindex;
+       int err = 0;
+       int notify_enetdown = 0;
+
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
+       lock_sock(sk);
+
+       if (ro->bound && addr->can_ifindex == ro->ifindex)
+               goto out;
+
+       if (addr->can_ifindex) {
+               struct net_device *dev;
+
+               dev = dev_get_by_index(&init_net, addr->can_ifindex);
+               if (!dev) {
+                       err = -ENODEV;
+                       goto out;
+               }
+               if (dev->type != ARPHRD_CAN) {
+                       dev_put(dev);
+                       err = -ENODEV;
+                       goto out;
+               }
+               if (!(dev->flags & IFF_UP))
+                       notify_enetdown = 1;
+
+               ifindex = dev->ifindex;
+
+               /* filters set by default/setsockopt */
+               err = raw_enable_allfilters(dev, sk);
+               dev_put(dev);
+
+       } else {
+               ifindex = 0;
+
+               /* filters set by default/setsockopt */
+               err = raw_enable_allfilters(NULL, sk);
+       }
+
+       if (!err) {
+               if (ro->bound) {
+                       /* unregister old filters */
+                       if (ro->ifindex) {
+                               struct net_device *dev;
+
+                               dev = dev_get_by_index(&init_net, ro->ifindex);
+                               if (dev) {
+                                       raw_disable_allfilters(dev, sk);
+                                       dev_put(dev);
+                               }
+                       } else
+                               raw_disable_allfilters(NULL, sk);
+               }
+               ro->ifindex = ifindex;
+               ro->bound = 1;
+       }
+
+ out:
+       release_sock(sk);
+
+       if (notify_enetdown) {
+               sk->sk_err = ENETDOWN;
+               if (!sock_flag(sk, SOCK_DEAD))
+                       sk->sk_error_report(sk);
+       }
+
+       return err;
+}
+
+static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
+                      int *len, int peer)
+{
+       struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+
+       if (peer)
+               return -EOPNOTSUPP;
+
+       addr->can_family  = AF_CAN;
+       addr->can_ifindex = ro->ifindex;
+
+       *len = sizeof(*addr);
+
+       return 0;
+}
+
+static int raw_setsockopt(struct socket *sock, int level, int optname,
+                         char __user *optval, int optlen)
+{
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+       struct can_filter *filter = NULL;  /* dyn. alloc'ed filters */
+       struct can_filter sfilter;         /* single filter */
+       struct net_device *dev = NULL;
+       can_err_mask_t err_mask = 0;
+       int count = 0;
+       int err = 0;
+
+       if (level != SOL_CAN_RAW)
+               return -EINVAL;
+       if (optlen < 0)
+               return -EINVAL;
+
+       switch (optname) {
+
+       case CAN_RAW_FILTER:
+               if (optlen % sizeof(struct can_filter) != 0)
+                       return -EINVAL;
+
+               count = optlen / sizeof(struct can_filter);
+
+               if (count > 1) {
+                       /* filter does not fit into dfilter => alloc space */
+                       filter = kmalloc(optlen, GFP_KERNEL);
+                       if (!filter)
+                               return -ENOMEM;
+
+                       err = copy_from_user(filter, optval, optlen);
+                       if (err) {
+                               kfree(filter);
+                               return err;
+                       }
+               } else if (count == 1) {
+                       err = copy_from_user(&sfilter, optval, optlen);
+                       if (err)
+                               return err;
+               }
+
+               lock_sock(sk);
+
+               if (ro->bound && ro->ifindex)
+                       dev = dev_get_by_index(&init_net, ro->ifindex);
+
+               if (ro->bound) {
+                       /* (try to) register the new filters */
+                       if (count == 1)
+                               err = raw_enable_filters(dev, sk, &sfilter, 1);
+                       else
+                               err = raw_enable_filters(dev, sk, filter,
+                                                        count);
+                       if (err) {
+                               if (count > 1)
+                                       kfree(filter);
+
+                               goto out_fil;
+                       }
+
+                       /* remove old filter registrations */
+                       raw_disable_filters(dev, sk, ro->filter, ro->count);
+               }
+
+               /* remove old filter space */
+               if (ro->count > 1)
+                       kfree(ro->filter);
+
+               /* link new filters to the socket */
+               if (count == 1) {
+                       /* copy filter data for single filter */
+                       ro->dfilter = sfilter;
+                       filter = &ro->dfilter;
+               }
+               ro->filter = filter;
+               ro->count  = count;
+
+ out_fil:
+               if (dev)
+                       dev_put(dev);
+
+               release_sock(sk);
+
+               break;
+
+       case CAN_RAW_ERR_FILTER:
+               if (optlen != sizeof(err_mask))
+                       return -EINVAL;
+
+               err = copy_from_user(&err_mask, optval, optlen);
+               if (err)
+                       return err;
+
+               err_mask &= CAN_ERR_MASK;
+
+               lock_sock(sk);
+
+               if (ro->bound && ro->ifindex)
+                       dev = dev_get_by_index(&init_net, ro->ifindex);
+
+               /* remove current error mask */
+               if (ro->bound) {
+                       /* (try to) register the new err_mask */
+                       err = raw_enable_errfilter(dev, sk, err_mask);
+
+                       if (err)
+                               goto out_err;
+
+                       /* remove old err_mask registration */
+                       raw_disable_errfilter(dev, sk, ro->err_mask);
+               }
+
+               /* link new err_mask to the socket */
+               ro->err_mask = err_mask;
+
+ out_err:
+               if (dev)
+                       dev_put(dev);
+
+               release_sock(sk);
+
+               break;
+
+       case CAN_RAW_LOOPBACK:
+               if (optlen != sizeof(ro->loopback))
+                       return -EINVAL;
+
+               err = copy_from_user(&ro->loopback, optval, optlen);
+
+               break;
+
+       case CAN_RAW_RECV_OWN_MSGS:
+               if (optlen != sizeof(ro->recv_own_msgs))
+                       return -EINVAL;
+
+               err = copy_from_user(&ro->recv_own_msgs, optval, optlen);
+
+               break;
+
+       default:
+               return -ENOPROTOOPT;
+       }
+       return err;
+}
+
+static int raw_getsockopt(struct socket *sock, int level, int optname,
+                         char __user *optval, int __user *optlen)
+{
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+       int len;
+       void *val;
+       int err = 0;
+
+       if (level != SOL_CAN_RAW)
+               return -EINVAL;
+       if (get_user(len, optlen))
+               return -EFAULT;
+       if (len < 0)
+               return -EINVAL;
+
+       switch (optname) {
+
+       case CAN_RAW_FILTER:
+               lock_sock(sk);
+               if (ro->count > 0) {
+                       int fsize = ro->count * sizeof(struct can_filter);
+                       if (len > fsize)
+                               len = fsize;
+                       err = copy_to_user(optval, ro->filter, len);
+               } else
+                       len = 0;
+               release_sock(sk);
+
+               if (!err)
+                       err = put_user(len, optlen);
+               return err;
+
+       case CAN_RAW_ERR_FILTER:
+               if (len > sizeof(can_err_mask_t))
+                       len = sizeof(can_err_mask_t);
+               val = &ro->err_mask;
+               break;
+
+       case CAN_RAW_LOOPBACK:
+               if (len > sizeof(int))
+                       len = sizeof(int);
+               val = &ro->loopback;
+               break;
+
+       case CAN_RAW_RECV_OWN_MSGS:
+               if (len > sizeof(int))
+                       len = sizeof(int);
+               val = &ro->recv_own_msgs;
+               break;
+
+       default:
+               return -ENOPROTOOPT;
+       }
+
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (copy_to_user(optval, val, len))
+               return -EFAULT;
+       return 0;
+}
+
+static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
+                      struct msghdr *msg, size_t size)
+{
+       struct sock *sk = sock->sk;
+       struct raw_sock *ro = raw_sk(sk);
+       struct sk_buff *skb;
+       struct net_device *dev;
+       int ifindex;
+       int err;
+
+       if (msg->msg_name) {
+               struct sockaddr_can *addr =
+                       (struct sockaddr_can *)msg->msg_name;
+
+               if (addr->can_family != AF_CAN)
+                       return -EINVAL;
+
+               ifindex = addr->can_ifindex;
+       } else
+               ifindex = ro->ifindex;
+
+       dev = dev_get_by_index(&init_net, ifindex);
+       if (!dev)
+               return -ENXIO;
+
+       skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT,
+                                 &err);
+       if (!skb) {
+               dev_put(dev);
+               return err;
+       }
+
+       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       if (err < 0) {
+               kfree_skb(skb);
+               dev_put(dev);
+               return err;
+       }
+       skb->dev = dev;
+       skb->sk  = sk;
+
+       err = can_send(skb, ro->loopback);
+
+       dev_put(dev);
+
+       if (err)
+               return err;
+
+       return size;
+}
+
+static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
+                      struct msghdr *msg, size_t size, int flags)
+{
+       struct sock *sk = sock->sk;
+       struct sk_buff *skb;
+       int error = 0;
+       int noblock;
+
+       noblock =  flags & MSG_DONTWAIT;
+       flags   &= ~MSG_DONTWAIT;
+
+       skb = skb_recv_datagram(sk, flags, noblock, &error);
+       if (!skb)
+               return error;
+
+       if (size < skb->len)
+               msg->msg_flags |= MSG_TRUNC;
+       else
+               size = skb->len;
+
+       error = memcpy_toiovec(msg->msg_iov, skb->data, size);
+       if (error < 0) {
+               skb_free_datagram(sk, skb);
+               return error;
+       }
+
+       sock_recv_timestamp(msg, sk, skb);
+
+       if (msg->msg_name) {
+               msg->msg_namelen = sizeof(struct sockaddr_can);
+               memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
+       }
+
+       skb_free_datagram(sk, skb);
+
+       return size;
+}
+
+static struct proto_ops raw_ops __read_mostly = {
+       .family        = PF_CAN,
+       .release       = raw_release,
+       .bind          = raw_bind,
+       .connect       = sock_no_connect,
+       .socketpair    = sock_no_socketpair,
+       .accept        = sock_no_accept,
+       .getname       = raw_getname,
+       .poll          = datagram_poll,
+       .ioctl         = NULL,          /* use can_ioctl() from af_can.c */
+       .listen        = sock_no_listen,
+       .shutdown      = sock_no_shutdown,
+       .setsockopt    = raw_setsockopt,
+       .getsockopt    = raw_getsockopt,
+       .sendmsg       = raw_sendmsg,
+       .recvmsg       = raw_recvmsg,
+       .mmap          = sock_no_mmap,
+       .sendpage      = sock_no_sendpage,
+};
+
+static struct proto raw_proto __read_mostly = {
+       .name       = "CAN_RAW",
+       .owner      = THIS_MODULE,
+       .obj_size   = sizeof(struct raw_sock),
+       .init       = raw_init,
+};
+
+static struct can_proto raw_can_proto __read_mostly = {
+       .type       = SOCK_RAW,
+       .protocol   = CAN_RAW,
+       .capability = -1,
+       .ops        = &raw_ops,
+       .prot       = &raw_proto,
+};
+
+static __init int raw_module_init(void)
+{
+       int err;
+
+       printk(banner);
+
+       err = can_proto_register(&raw_can_proto);
+       if (err < 0)
+               printk(KERN_ERR "can: registration of raw protocol failed\n");
+
+       return err;
+}
+
+static __exit void raw_module_exit(void)
+{
+       can_proto_unregister(&raw_can_proto);
+}
+
+module_init(raw_module_init);
+module_exit(raw_module_exit);
index 377e560ab5c98bb99cc5d83340082c926b2c39de..80013fb69a61e0a62bb05ee48643ad2466e2cef8 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/syscalls.h>
 #include <linux/filter.h>
 #include <linux/compat.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/security.h>
 
 #include <net/scm.h>
@@ -316,107 +315,6 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
        __scm_destroy(scm);
 }
 
-/*
- * For now, we assume that the compatibility and native version
- * of struct ipt_entry are the same - sfr.  FIXME
- */
-struct compat_ipt_replace {
-       char                    name[IPT_TABLE_MAXNAMELEN];
-       u32                     valid_hooks;
-       u32                     num_entries;
-       u32                     size;
-       u32                     hook_entry[NF_IP_NUMHOOKS];
-       u32                     underflow[NF_IP_NUMHOOKS];
-       u32                     num_counters;
-       compat_uptr_t           counters;       /* struct ipt_counters * */
-       struct ipt_entry        entries[0];
-};
-
-static int do_netfilter_replace(int fd, int level, int optname,
-                               char __user *optval, int optlen)
-{
-       struct compat_ipt_replace __user *urepl;
-       struct ipt_replace __user *repl_nat;
-       char name[IPT_TABLE_MAXNAMELEN];
-       u32 origsize, tmp32, num_counters;
-       unsigned int repl_nat_size;
-       int ret;
-       int i;
-       compat_uptr_t ucntrs;
-
-       urepl = (struct compat_ipt_replace __user *)optval;
-       if (get_user(origsize, &urepl->size))
-               return -EFAULT;
-
-       /* Hack: Causes ipchains to give correct error msg --RR */
-       if (optlen != sizeof(*urepl) + origsize)
-               return -ENOPROTOOPT;
-
-       /* XXX Assumes that size of ipt_entry is the same both in
-        *     native and compat environments.
-        */
-       repl_nat_size = sizeof(*repl_nat) + origsize;
-       repl_nat = compat_alloc_user_space(repl_nat_size);
-
-       ret = -EFAULT;
-       if (put_user(origsize, &repl_nat->size))
-               goto out;
-
-       if (!access_ok(VERIFY_READ, urepl, optlen) ||
-           !access_ok(VERIFY_WRITE, repl_nat, optlen))
-               goto out;
-
-       if (__copy_from_user(name, urepl->name, sizeof(urepl->name)) ||
-           __copy_to_user(repl_nat->name, name, sizeof(repl_nat->name)))
-               goto out;
-
-       if (__get_user(tmp32, &urepl->valid_hooks) ||
-           __put_user(tmp32, &repl_nat->valid_hooks))
-               goto out;
-
-       if (__get_user(tmp32, &urepl->num_entries) ||
-           __put_user(tmp32, &repl_nat->num_entries))
-               goto out;
-
-       if (__get_user(num_counters, &urepl->num_counters) ||
-           __put_user(num_counters, &repl_nat->num_counters))
-               goto out;
-
-       if (__get_user(ucntrs, &urepl->counters) ||
-           __put_user(compat_ptr(ucntrs), &repl_nat->counters))
-               goto out;
-
-       if (__copy_in_user(&repl_nat->entries[0],
-                          &urepl->entries[0],
-                          origsize))
-               goto out;
-
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
-               if (__get_user(tmp32, &urepl->hook_entry[i]) ||
-                   __put_user(tmp32, &repl_nat->hook_entry[i]) ||
-                   __get_user(tmp32, &urepl->underflow[i]) ||
-                   __put_user(tmp32, &repl_nat->underflow[i]))
-                       goto out;
-       }
-
-       /*
-        * Since struct ipt_counters just contains two u_int64_t members
-        * we can just do the access_ok check here and pass the (converted)
-        * pointer into the standard syscall.  We hope that the pointer is
-        * not misaligned ...
-        */
-       if (!access_ok(VERIFY_WRITE, compat_ptr(ucntrs),
-                      num_counters * sizeof(struct ipt_counters)))
-               goto out;
-
-
-       ret = sys_setsockopt(fd, level, optname,
-                            (char __user *)repl_nat, repl_nat_size);
-
-out:
-       return ret;
-}
-
 /*
  * A struct sock_filter is architecture independent.
  */
@@ -485,10 +383,6 @@ asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
        int err;
        struct socket *sock;
 
-       if (level == SOL_IPV6 && optname == IPT_SO_SET_REPLACE)
-               return do_netfilter_replace(fd, level, optname,
-                                           optval, optlen);
-
        if (optlen < 0)
                return -EINVAL;
 
index 029b93e246b45ea934b1da0cd018425e52965fcb..8a28fc93b72424bafe31a63e336ca4ead747dc89 100644 (file)
@@ -115,10 +115,10 @@ out_noerr:
 }
 
 /**
- *     skb_recv_datagram - Receive a datagram skbuff
+ *     __skb_recv_datagram - Receive a datagram skbuff
  *     @sk: socket
  *     @flags: MSG_ flags
- *     @noblock: blocking operation?
+ *     @peeked: returns non-zero if this packet has been seen before
  *     @err: error code returned
  *
  *     Get a datagram skbuff, understands the peeking, nonblocking wakeups
@@ -143,8 +143,8 @@ out_noerr:
  *     quite explicitly by POSIX 1003.1g, don't change them without having
  *     the standard around please.
  */
-struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
-                                 int noblock, int *err)
+struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
+                                   int *peeked, int *err)
 {
        struct sk_buff *skb;
        long timeo;
@@ -156,7 +156,7 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
        if (error)
                goto no_packet;
 
-       timeo = sock_rcvtimeo(sk, noblock);
+       timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 
        do {
                /* Again only user level code calls this function, so nothing
@@ -165,18 +165,19 @@ struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
                 * Look at current nfs client by the way...
                 * However, this function was corrent in any case. 8)
                 */
-               if (flags & MSG_PEEK) {
-                       unsigned long cpu_flags;
-
-                       spin_lock_irqsave(&sk->sk_receive_queue.lock,
-                                         cpu_flags);
-                       skb = skb_peek(&sk->sk_receive_queue);
-                       if (skb)
+               unsigned long cpu_flags;
+
+               spin_lock_irqsave(&sk->sk_receive_queue.lock, cpu_flags);
+               skb = skb_peek(&sk->sk_receive_queue);
+               if (skb) {
+                       *peeked = skb->peeked;
+                       if (flags & MSG_PEEK) {
+                               skb->peeked = 1;
                                atomic_inc(&skb->users);
-                       spin_unlock_irqrestore(&sk->sk_receive_queue.lock,
-                                              cpu_flags);
-               } else
-                       skb = skb_dequeue(&sk->sk_receive_queue);
+                       } else
+                               __skb_unlink(skb, &sk->sk_receive_queue);
+               }
+               spin_unlock_irqrestore(&sk->sk_receive_queue.lock, cpu_flags);
 
                if (skb)
                        return skb;
@@ -194,10 +195,21 @@ no_packet:
        *err = error;
        return NULL;
 }
+EXPORT_SYMBOL(__skb_recv_datagram);
+
+struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
+                                 int noblock, int *err)
+{
+       int peeked;
+
+       return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+                                  &peeked, err);
+}
 
 void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
 {
        kfree_skb(skb);
+       sk_mem_reclaim(sk);
 }
 
 /**
@@ -217,20 +229,28 @@ void skb_free_datagram(struct sock *sk, struct sk_buff *skb)
  *     This function currently only disables BH when acquiring the
  *     sk_receive_queue lock.  Therefore it must not be used in a
  *     context where that lock is acquired in an IRQ context.
+ *
+ *     It returns 0 if the packet was removed by us.
  */
 
-void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
+int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
 {
+       int err = 0;
+
        if (flags & MSG_PEEK) {
+               err = -ENOENT;
                spin_lock_bh(&sk->sk_receive_queue.lock);
                if (skb == skb_peek(&sk->sk_receive_queue)) {
                        __skb_unlink(skb, &sk->sk_receive_queue);
                        atomic_dec(&skb->users);
+                       err = 0;
                }
                spin_unlock_bh(&sk->sk_receive_queue.lock);
        }
 
        kfree_skb(skb);
+       sk_mem_reclaim(sk);
+       return err;
 }
 
 EXPORT_SYMBOL(skb_kill_datagram);
index 0879f52115eb9bada2f73bb3de2188ef9bf9a910..c9c593e1ba6fd4d26d8580bb12f1fccb99126484 100644 (file)
  *             86DD    IPv6
  */
 
+#define PTYPE_HASH_SIZE        (16)
+#define PTYPE_HASH_MASK        (PTYPE_HASH_SIZE - 1)
+
 static DEFINE_SPINLOCK(ptype_lock);
-static struct list_head ptype_base[16] __read_mostly;  /* 16 way hashed list */
+static struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
 static struct list_head ptype_all __read_mostly;       /* Taps */
 
 #ifdef CONFIG_NET_DMA
@@ -362,7 +365,7 @@ void dev_add_pack(struct packet_type *pt)
        if (pt->type == htons(ETH_P_ALL))
                list_add_rcu(&pt->list, &ptype_all);
        else {
-               hash = ntohs(pt->type) & 15;
+               hash = ntohs(pt->type) & PTYPE_HASH_MASK;
                list_add_rcu(&pt->list, &ptype_base[hash]);
        }
        spin_unlock_bh(&ptype_lock);
@@ -391,7 +394,7 @@ void __dev_remove_pack(struct packet_type *pt)
        if (pt->type == htons(ETH_P_ALL))
                head = &ptype_all;
        else
-               head = &ptype_base[ntohs(pt->type) & 15];
+               head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];
 
        list_for_each_entry(pt1, head, list) {
                if (pt == pt1) {
@@ -672,7 +675,7 @@ struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type, char *h
 
        ASSERT_RTNL();
 
-       for_each_netdev(&init_net, dev)
+       for_each_netdev(net, dev)
                if (dev->type == type &&
                    !memcmp(dev->dev_addr, ha, dev->addr_len))
                        return dev;
@@ -1420,7 +1423,8 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
        }
 
        rcu_read_lock();
-       list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
+       list_for_each_entry_rcu(ptype,
+                       &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
                if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
                        if (unlikely(skb->ip_summed != CHECKSUM_PARTIAL)) {
                                err = ptype->gso_send_check(skb);
@@ -2077,7 +2081,8 @@ ncls:
                goto out;
 
        type = skb->protocol;
-       list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
+       list_for_each_entry_rcu(ptype,
+                       &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
                if (ptype->type == type &&
                    (!ptype->dev || ptype->dev == skb->dev)) {
                        if (pt_prev)
@@ -2363,8 +2368,9 @@ static int dev_ifconf(struct net *net, char __user *arg)
  *     in detail.
  */
 void *dev_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        loff_t off;
        struct net_device *dev;
 
@@ -2382,13 +2388,14 @@ void *dev_seq_start(struct seq_file *seq, loff_t *pos)
 
 void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        ++*pos;
        return v == SEQ_START_TOKEN ?
                first_net_device(net) : next_net_device((struct net_device *)v);
 }
 
 void dev_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        read_unlock(&dev_base_lock);
 }
@@ -2481,26 +2488,8 @@ static const struct seq_operations dev_seq_ops = {
 
 static int dev_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res =  seq_open(file, &dev_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int dev_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &dev_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_seq_fops = {
@@ -2508,7 +2497,7 @@ static const struct file_operations dev_seq_fops = {
        .open    = dev_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = dev_seq_release,
+       .release = seq_release_net,
 };
 
 static const struct seq_operations softnet_seq_ops = {
@@ -2543,7 +2532,7 @@ static void *ptype_get_idx(loff_t pos)
                ++i;
        }
 
-       for (t = 0; t < 16; t++) {
+       for (t = 0; t < PTYPE_HASH_SIZE; t++) {
                list_for_each_entry_rcu(pt, &ptype_base[t], list) {
                        if (i == pos)
                                return pt;
@@ -2554,6 +2543,7 @@ static void *ptype_get_idx(loff_t pos)
 }
 
 static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
        rcu_read_lock();
        return *pos ? ptype_get_idx(*pos - 1) : SEQ_START_TOKEN;
@@ -2577,10 +2567,10 @@ static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                hash = 0;
                nxt = ptype_base[0].next;
        } else
-               hash = ntohs(pt->type) & 15;
+               hash = ntohs(pt->type) & PTYPE_HASH_MASK;
 
        while (nxt == &ptype_base[hash]) {
-               if (++hash >= 16)
+               if (++hash >= PTYPE_HASH_SIZE)
                        return NULL;
                nxt = ptype_base[hash].next;
        }
@@ -2589,6 +2579,7 @@ found:
 }
 
 static void ptype_seq_stop(struct seq_file *seq, void *v)
+       __releases(RCU)
 {
        rcu_read_unlock();
 }
@@ -3505,7 +3496,7 @@ static int dev_new_index(struct net *net)
 
 /* Delayed registration/unregisteration */
 static DEFINE_SPINLOCK(net_todo_list_lock);
-static struct list_head net_todo_list = LIST_HEAD_INIT(net_todo_list);
+static LIST_HEAD(net_todo_list);
 
 static void net_set_todo(struct net_device *dev)
 {
@@ -3984,6 +3975,8 @@ void synchronize_net(void)
 
 void unregister_netdevice(struct net_device *dev)
 {
+       ASSERT_RTNL();
+
        rollback_registered(dev);
        /* Finish processing unregister after unlock */
        net_set_todo(dev);
@@ -4416,7 +4409,7 @@ static int __init net_dev_init(void)
                goto out;
 
        INIT_LIST_HEAD(&ptype_all);
-       for (i = 0; i < 16; i++)
+       for (i = 0; i < PTYPE_HASH_SIZE; i++)
                INIT_LIST_HEAD(&ptype_base[i]);
 
        if (register_pernet_subsys(&netdev_net_ops))
index 69fff16ece10c70c3c94d2624a2d1086a23e26a8..cadbfbf7e7f57a687f4f134030b106a4781f4715 100644 (file)
@@ -186,8 +186,9 @@ EXPORT_SYMBOL(dev_mc_unsync);
 
 #ifdef CONFIG_PROC_FS
 static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
-       struct net *net = seq->private;
+       struct net *net = seq_file_net(seq);
        struct net_device *dev;
        loff_t off = 0;
 
@@ -206,6 +207,7 @@ static void *dev_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void dev_mc_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        read_unlock(&dev_base_lock);
 }
@@ -241,26 +243,8 @@ static const struct seq_operations dev_mc_seq_ops = {
 
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res = seq_open(file, &dev_mc_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int dev_mc_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &dev_mc_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations dev_mc_seq_fops = {
@@ -268,7 +252,7 @@ static const struct file_operations dev_mc_seq_fops = {
        .open    = dev_mc_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = dev_mc_seq_release,
+       .release = seq_release_net,
 };
 
 #endif
index 03daead3592ad0ef60628e85eef11e18da28b610..7deef483c79f263959c0c1dac148529ecc80d73c 100644 (file)
@@ -153,18 +153,19 @@ loop:
 #endif
 }
 
-static int dst_discard(struct sk_buff *skb)
+int dst_discard(struct sk_buff *skb)
 {
        kfree_skb(skb);
        return 0;
 }
+EXPORT_SYMBOL(dst_discard);
 
 void * dst_alloc(struct dst_ops * ops)
 {
        struct dst_entry * dst;
 
        if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) {
-               if (ops->gc())
+               if (ops->gc(ops))
                        return NULL;
        }
        dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
@@ -278,13 +279,13 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
        if (!unregister) {
                dst->input = dst->output = dst_discard;
        } else {
-               dst->dev = init_net.loopback_dev;
+               dst->dev = dst->dev->nd_net->loopback_dev;
                dev_hold(dst->dev);
                dev_put(dev);
                if (dst->neighbour && dst->neighbour->dev == dev) {
-                       dst->neighbour->dev = init_net.loopback_dev;
+                       dst->neighbour->dev = dst->dev;
+                       dev_hold(dst->dev);
                        dev_put(dev);
-                       dev_hold(dst->neighbour->dev);
                }
        }
 }
index 848132b6cb733500663b64f4097516799d599f36..42ccaf5b85097f43842a9e394dbc082795e80b30 100644 (file)
@@ -15,9 +15,6 @@
 #include <net/sock.h>
 #include <net/fib_rules.h>
 
-static LIST_HEAD(rules_ops);
-static DEFINE_SPINLOCK(rules_mod_lock);
-
 int fib_default_rule_add(struct fib_rules_ops *ops,
                         u32 pref, u32 table, u32 flags)
 {
@@ -32,6 +29,7 @@ int fib_default_rule_add(struct fib_rules_ops *ops,
        r->pref = pref;
        r->table = table;
        r->flags = flags;
+       r->fr_net = ops->fro_net;
 
        /* The lock is not required here, the list in unreacheable
         * at the moment this function is called */
@@ -44,12 +42,12 @@ static void notify_rule_change(int event, struct fib_rule *rule,
                               struct fib_rules_ops *ops, struct nlmsghdr *nlh,
                               u32 pid);
 
-static struct fib_rules_ops *lookup_rules_ops(int family)
+static struct fib_rules_ops *lookup_rules_ops(struct net *net, int family)
 {
        struct fib_rules_ops *ops;
 
        rcu_read_lock();
-       list_for_each_entry_rcu(ops, &rules_ops, list) {
+       list_for_each_entry_rcu(ops, &net->rules_ops, list) {
                if (ops->family == family) {
                        if (!try_module_get(ops->owner))
                                ops = NULL;
@@ -78,6 +76,9 @@ int fib_rules_register(struct fib_rules_ops *ops)
 {
        int err = -EEXIST;
        struct fib_rules_ops *o;
+       struct net *net;
+
+       net = ops->fro_net;
 
        if (ops->rule_size < sizeof(struct fib_rule))
                return -EINVAL;
@@ -87,22 +88,23 @@ int fib_rules_register(struct fib_rules_ops *ops)
            ops->action == NULL)
                return -EINVAL;
 
-       spin_lock(&rules_mod_lock);
-       list_for_each_entry(o, &rules_ops, list)
+       spin_lock(&net->rules_mod_lock);
+       list_for_each_entry(o, &net->rules_ops, list)
                if (ops->family == o->family)
                        goto errout;
 
-       list_add_tail_rcu(&ops->list, &rules_ops);
+       hold_net(net);
+       list_add_tail_rcu(&ops->list, &net->rules_ops);
        err = 0;
 errout:
-       spin_unlock(&rules_mod_lock);
+       spin_unlock(&net->rules_mod_lock);
 
        return err;
 }
 
 EXPORT_SYMBOL_GPL(fib_rules_register);
 
-static void cleanup_ops(struct fib_rules_ops *ops)
+void fib_rules_cleanup_ops(struct fib_rules_ops *ops)
 {
        struct fib_rule *rule, *tmp;
 
@@ -111,28 +113,19 @@ static void cleanup_ops(struct fib_rules_ops *ops)
                fib_rule_put(rule);
        }
 }
+EXPORT_SYMBOL_GPL(fib_rules_cleanup_ops);
 
-int fib_rules_unregister(struct fib_rules_ops *ops)
+void fib_rules_unregister(struct fib_rules_ops *ops)
 {
-       int err = 0;
-       struct fib_rules_ops *o;
-
-       spin_lock(&rules_mod_lock);
-       list_for_each_entry(o, &rules_ops, list) {
-               if (o == ops) {
-                       list_del_rcu(&o->list);
-                       cleanup_ops(ops);
-                       goto out;
-               }
-       }
+       struct net *net = ops->fro_net;
 
-       err = -ENOENT;
-out:
-       spin_unlock(&rules_mod_lock);
+       spin_lock(&net->rules_mod_lock);
+       list_del_rcu(&ops->list);
+       fib_rules_cleanup_ops(ops);
+       spin_unlock(&net->rules_mod_lock);
 
        synchronize_rcu();
-
-       return err;
+       release_net(net);
 }
 
 EXPORT_SYMBOL_GPL(fib_rules_unregister);
@@ -231,7 +224,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
                goto errout;
 
-       ops = lookup_rules_ops(frh->family);
+       ops = lookup_rules_ops(net, frh->family);
        if (ops == NULL) {
                err = EAFNOSUPPORT;
                goto errout;
@@ -250,6 +243,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                err = -ENOMEM;
                goto errout;
        }
+       rule->fr_net = net;
 
        if (tb[FRA_PRIORITY])
                rule->pref = nla_get_u32(tb[FRA_PRIORITY]);
@@ -281,7 +275,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        rule->table = frh_get_table(frh, tb);
 
        if (!rule->pref && ops->default_pref)
-               rule->pref = ops->default_pref();
+               rule->pref = ops->default_pref(ops);
 
        err = -EINVAL;
        if (tb[FRA_GOTO]) {
@@ -358,6 +352,7 @@ errout:
 
 static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib_rule_hdr *frh = nlmsg_data(nlh);
        struct fib_rules_ops *ops = NULL;
        struct fib_rule *rule, *tmp;
@@ -367,7 +362,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*frh)))
                goto errout;
 
-       ops = lookup_rules_ops(frh->family);
+       ops = lookup_rules_ops(net, frh->family);
        if (ops == NULL) {
                err = EAFNOSUPPORT;
                goto errout;
@@ -539,13 +534,14 @@ skip:
 
 static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib_rules_ops *ops;
        int idx = 0, family;
 
        family = rtnl_msg_family(cb->nlh);
        if (family != AF_UNSPEC) {
                /* Protocol specific dump request */
-               ops = lookup_rules_ops(family);
+               ops = lookup_rules_ops(net, family);
                if (ops == NULL)
                        return -EAFNOSUPPORT;
 
@@ -553,7 +549,7 @@ static int fib_nl_dumprule(struct sk_buff *skb, struct netlink_callback *cb)
        }
 
        rcu_read_lock();
-       list_for_each_entry_rcu(ops, &rules_ops, list) {
+       list_for_each_entry_rcu(ops, &net->rules_ops, list) {
                if (idx < cb->args[0] || !try_module_get(ops->owner))
                        goto skip;
 
@@ -574,9 +570,11 @@ static void notify_rule_change(int event, struct fib_rule *rule,
                               struct fib_rules_ops *ops, struct nlmsghdr *nlh,
                               u32 pid)
 {
+       struct net *net;
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
+       net = ops->fro_net;
        skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
        if (skb == NULL)
                goto errout;
@@ -588,10 +586,11 @@ static void notify_rule_change(int event, struct fib_rule *rule,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
+
+       err = rtnl_notify(skb, net, pid, ops->nlgroup, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(ops->nlgroup, err);
+               rtnl_set_sk_err(net, ops->nlgroup, err);
 }
 
 static void attach_rules(struct list_head *rules, struct net_device *dev)
@@ -619,22 +618,20 @@ static int fib_rules_event(struct notifier_block *this, unsigned long event,
                            void *ptr)
 {
        struct net_device *dev = ptr;
+       struct net *net = dev->nd_net;
        struct fib_rules_ops *ops;
 
-       if (dev->nd_net != &init_net)
-               return NOTIFY_DONE;
-
        ASSERT_RTNL();
        rcu_read_lock();
 
        switch (event) {
        case NETDEV_REGISTER:
-               list_for_each_entry(ops, &rules_ops, list)
+               list_for_each_entry(ops, &net->rules_ops, list)
                        attach_rules(&ops->rules_list, dev);
                break;
 
        case NETDEV_UNREGISTER:
-               list_for_each_entry(ops, &rules_ops, list)
+               list_for_each_entry(ops, &net->rules_ops, list)
                        detach_rules(&ops->rules_list, dev);
                break;
        }
@@ -648,13 +645,40 @@ static struct notifier_block fib_rules_notifier = {
        .notifier_call = fib_rules_event,
 };
 
+static int fib_rules_net_init(struct net *net)
+{
+       INIT_LIST_HEAD(&net->rules_ops);
+       spin_lock_init(&net->rules_mod_lock);
+       return 0;
+}
+
+static struct pernet_operations fib_rules_net_ops = {
+       .init = fib_rules_net_init,
+};
+
 static int __init fib_rules_init(void)
 {
+       int err;
        rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
        rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
        rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
 
-       return register_netdevice_notifier(&fib_rules_notifier);
+       err = register_netdevice_notifier(&fib_rules_notifier);
+       if (err < 0)
+               goto fail;
+
+       err = register_pernet_subsys(&fib_rules_net_ops);
+       if (err < 0)
+               goto fail_unregister;
+       return 0;
+
+fail_unregister:
+       unregister_netdevice_notifier(&fib_rules_notifier);
+fail:
+       rtnl_unregister(PF_UNSPEC, RTM_NEWRULE);
+       rtnl_unregister(PF_UNSPEC, RTM_DELRULE);
+       rtnl_unregister(PF_UNSPEC, RTM_GETRULE);
+       return err;
 }
 
 subsys_initcall(fib_rules_init);
index 6489f4e24ecf118f98a457284d130973ca841130..46b38e06e0d75601bde3fbef5dbf3048008bc263 100644 (file)
@@ -352,8 +352,7 @@ static int __init flow_cache_init(void)
        flow_lwm = 2 * flow_hash_size;
        flow_hwm = 4 * flow_hash_size;
 
-       init_timer(&flow_hash_rnd_timer);
-       flow_hash_rnd_timer.function = flow_cache_new_hashrnd;
+       setup_timer(&flow_hash_rnd_timer, flow_cache_new_hashrnd, 0);
        flow_hash_rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD;
        add_timer(&flow_hash_rnd_timer);
 
index daadbcc4e8dd7e45d92205f6ef4810a315ce3a62..57abe8266be198dd483c71ce07cf3ce0757ced0e 100644 (file)
@@ -135,7 +135,7 @@ skip:
        }
 
        if (!list_empty(&elist[idx].list))
-               mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+               mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
        rcu_read_unlock();
 }
 
@@ -159,13 +159,13 @@ skip:
 int gen_new_estimator(struct gnet_stats_basic *bstats,
                      struct gnet_stats_rate_est *rate_est,
                      spinlock_t *stats_lock,
-                     struct rtattr *opt)
+                     struct nlattr *opt)
 {
        struct gen_estimator *est;
-       struct gnet_estimator *parm = RTA_DATA(opt);
+       struct gnet_estimator *parm = nla_data(opt);
        int idx;
 
-       if (RTA_PAYLOAD(opt) < sizeof(*parm))
+       if (nla_len(opt) < sizeof(*parm))
                return -EINVAL;
 
        if (parm->interval < -2 || parm->interval > 3)
@@ -191,7 +191,7 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
        }
 
        if (list_empty(&elist[idx].list))
-               mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+               mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
 
        list_add_rcu(&est->list, &elist[idx].list);
        return 0;
@@ -241,7 +241,7 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
 }
 
 /**
- * gen_replace_estimator - replace rate estimator configruation
+ * gen_replace_estimator - replace rate estimator configuration
  * @bstats: basic statistics
  * @rate_est: rate estimator statistics
  * @stats_lock: statistics lock
@@ -252,13 +252,12 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
  *
  * Returns 0 on success or a negative error code.
  */
-int
-gen_replace_estimator(struct gnet_stats_basic *bstats,
-       struct gnet_stats_rate_est *rate_est, spinlock_t *stats_lock,
-       struct rtattr *opt)
+int gen_replace_estimator(struct gnet_stats_basic *bstats,
+                         struct gnet_stats_rate_est *rate_est,
+                         spinlock_t *stats_lock, struct nlattr *opt)
 {
-    gen_kill_estimator(bstats, rate_est);
-    return gen_new_estimator(bstats, rate_est, stats_lock, opt);
+       gen_kill_estimator(bstats, rate_est);
+       return gen_new_estimator(bstats, rate_est, stats_lock, opt);
 }
 
 
index bcc25591d8ac554c898bbf0a47573ad6705d5934..c3d0ffeac24342417bca0017e3d55e7c05100018 100644 (file)
 #include <linux/socket.h>
 #include <linux/rtnetlink.h>
 #include <linux/gen_stats.h>
+#include <net/netlink.h>
 #include <net/gen_stats.h>
 
 
 static inline int
 gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size)
 {
-       RTA_PUT(d->skb, type, size, buf);
+       NLA_PUT(d->skb, type, size, buf);
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        spin_unlock_bh(d->lock);
        return -1;
 }
@@ -55,13 +56,14 @@ rtattr_failure:
 int
 gnet_stats_start_copy_compat(struct sk_buff *skb, int type, int tc_stats_type,
        int xstats_type, spinlock_t *lock, struct gnet_dump *d)
+       __acquires(lock)
 {
        memset(d, 0, sizeof(*d));
 
        spin_lock_bh(lock);
        d->lock = lock;
        if (type)
-               d->tail = (struct rtattr *)skb_tail_pointer(skb);
+               d->tail = (struct nlattr *)skb_tail_pointer(skb);
        d->skb = skb;
        d->compat_tc_stats = tc_stats_type;
        d->compat_xstats = xstats_type;
@@ -212,7 +214,7 @@ int
 gnet_stats_finish_copy(struct gnet_dump *d)
 {
        if (d->tail)
-               d->tail->rta_len = skb_tail_pointer(d->skb) - (u8 *)d->tail;
+               d->tail->nla_len = skb_tail_pointer(d->skb) - (u8 *)d->tail;
 
        if (d->compat_tc_stats)
                if (gnet_stats_copy(d, d->compat_tc_stats, &d->tc_stats,
index 29b8ee4e35d6dc53f32064c1c067c7287ce80924..a16cf1ec5e5ebe9fc100cb027c740c9387184472 100644 (file)
@@ -59,7 +59,6 @@ static void neigh_timer_handler(unsigned long arg);
 static void __neigh_notify(struct neighbour *n, int type, int flags);
 static void neigh_update_notify(struct neighbour *neigh);
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
-void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
 static struct neigh_table *neigh_tables;
 #ifdef CONFIG_PROC_FS
@@ -165,6 +164,16 @@ static int neigh_forced_gc(struct neigh_table *tbl)
        return shrunk;
 }
 
+static void neigh_add_timer(struct neighbour *n, unsigned long when)
+{
+       neigh_hold(n);
+       if (unlikely(mod_timer(&n->timer, when))) {
+               printk("NEIGH: BUG, double timer add, state is %x\n",
+                      n->nud_state);
+               dump_stack();
+       }
+}
+
 static int neigh_del_timer(struct neighbour *n)
 {
        if ((n->nud_state & NUD_IN_TIMER) &&
@@ -270,9 +279,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl)
        n->nud_state      = NUD_NONE;
        n->output         = neigh_blackhole;
        n->parms          = neigh_parms_clone(&tbl->parms);
-       init_timer(&n->timer);
-       n->timer.function = neigh_timer_handler;
-       n->timer.data     = (unsigned long)n;
+       setup_timer(&n->timer, neigh_timer_handler, (unsigned long)n);
 
        NEIGH_CACHE_STAT_INC(tbl, allocs);
        n->tbl            = tbl;
@@ -367,7 +374,8 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
        return n;
 }
 
-struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
+struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
+                                    const void *pkey)
 {
        struct neighbour *n;
        int key_len = tbl->key_len;
@@ -377,7 +385,8 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, const void *pkey)
 
        read_lock_bh(&tbl->lock);
        for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
-               if (!memcmp(n->primary_key, pkey, key_len)) {
+               if (!memcmp(n->primary_key, pkey, key_len) &&
+                   (net == n->dev->nd_net)) {
                        neigh_hold(n);
                        NEIGH_CACHE_STAT_INC(tbl, hits);
                        break;
@@ -455,7 +464,8 @@ out_neigh_release:
        goto out;
 }
 
-struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
+struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
+                                   struct net *net, const void *pkey,
                                    struct net_device *dev, int creat)
 {
        struct pneigh_entry *n;
@@ -471,6 +481,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
 
        for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
                if (!memcmp(n->key, pkey, key_len) &&
+                   (n->net == net) &&
                    (n->dev == dev || !n->dev)) {
                        read_unlock_bh(&tbl->lock);
                        goto out;
@@ -487,6 +498,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, const void *pkey,
        if (!n)
                goto out;
 
+       n->net = hold_net(net);
        memcpy(n->key, pkey, key_len);
        n->dev = dev;
        if (dev)
@@ -509,7 +521,7 @@ out:
 }
 
 
-int pneigh_delete(struct neigh_table *tbl, const void *pkey,
+int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
                  struct net_device *dev)
 {
        struct pneigh_entry *n, **np;
@@ -524,13 +536,15 @@ int pneigh_delete(struct neigh_table *tbl, const void *pkey,
        write_lock_bh(&tbl->lock);
        for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;
             np = &n->next) {
-               if (!memcmp(n->key, pkey, key_len) && n->dev == dev) {
+               if (!memcmp(n->key, pkey, key_len) && n->dev == dev &&
+                   (n->net == net)) {
                        *np = n->next;
                        write_unlock_bh(&tbl->lock);
                        if (tbl->pdestructor)
                                tbl->pdestructor(n);
                        if (n->dev)
                                dev_put(n->dev);
+                       release_net(n->net);
                        kfree(n);
                        return 0;
                }
@@ -553,6 +567,7 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
                                        tbl->pdestructor(n);
                                if (n->dev)
                                        dev_put(n->dev);
+                               release_net(n->net);
                                kfree(n);
                                continue;
                        }
@@ -562,6 +577,13 @@ static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
        return -ENOENT;
 }
 
+static void neigh_parms_destroy(struct neigh_parms *parms);
+
+static inline void neigh_parms_put(struct neigh_parms *parms)
+{
+       if (atomic_dec_and_test(&parms->refcnt))
+               neigh_parms_destroy(parms);
+}
 
 /*
  *     neighbour must already be out of the table;
@@ -718,15 +740,6 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
                p->ucast_probes + p->app_probes + p->mcast_probes);
 }
 
-static inline void neigh_add_timer(struct neighbour *n, unsigned long when)
-{
-       if (unlikely(mod_timer(&n->timer, when))) {
-               printk("NEIGH: BUG, double timer add, state is %x\n",
-                      n->nud_state);
-               dump_stack();
-       }
-}
-
 /* Called when a timer expires for a neighbour entry. */
 
 static void neigh_timer_handler(unsigned long arg)
@@ -858,7 +871,6 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                        atomic_set(&neigh->probes, neigh->parms->ucast_probes);
                        neigh->nud_state     = NUD_INCOMPLETE;
                        neigh->updated = jiffies;
-                       neigh_hold(neigh);
                        neigh_add_timer(neigh, now + 1);
                } else {
                        neigh->nud_state = NUD_FAILED;
@@ -871,7 +883,6 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                }
        } else if (neigh->nud_state & NUD_STALE) {
                NEIGH_PRINTK2("neigh %p is delayed.\n", neigh);
-               neigh_hold(neigh);
                neigh->nud_state = NUD_DELAY;
                neigh->updated = jiffies;
                neigh_add_timer(neigh,
@@ -1015,13 +1026,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
 
        if (new != old) {
                neigh_del_timer(neigh);
-               if (new & NUD_IN_TIMER) {
-                       neigh_hold(neigh);
+               if (new & NUD_IN_TIMER)
                        neigh_add_timer(neigh, (jiffies +
                                                ((new & NUD_REACHABLE) ?
                                                 neigh->parms->reachable_time :
                                                 0)));
-               }
                neigh->nud_state = new;
        }
 
@@ -1266,27 +1275,49 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
        spin_unlock(&tbl->proxy_queue.lock);
 }
 
+static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+                                                     struct net *net, int ifindex)
+{
+       struct neigh_parms *p;
+
+       for (p = &tbl->parms; p; p = p->next) {
+               if (p->net != net)
+                       continue;
+               if ((p->dev && p->dev->ifindex == ifindex) ||
+                   (!p->dev && !ifindex))
+                       return p;
+       }
+
+       return NULL;
+}
 
 struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
                                      struct neigh_table *tbl)
 {
-       struct neigh_parms *p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
+       struct neigh_parms *p, *ref;
+       struct net *net;
+
+       net = dev->nd_net;
+       ref = lookup_neigh_params(tbl, net, 0);
+       if (!ref)
+               return NULL;
 
+       p = kmemdup(ref, sizeof(*p), GFP_KERNEL);
        if (p) {
                p->tbl            = tbl;
                atomic_set(&p->refcnt, 1);
                INIT_RCU_HEAD(&p->rcu_head);
                p->reachable_time =
                                neigh_rand_reach_time(p->base_reachable_time);
-               if (dev) {
-                       if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
-                               kfree(p);
-                               return NULL;
-                       }
 
-                       dev_hold(dev);
-                       p->dev = dev;
+               if (dev->neigh_setup && dev->neigh_setup(dev, p)) {
+                       kfree(p);
+                       return NULL;
                }
+
+               dev_hold(dev);
+               p->dev = dev;
+               p->net = hold_net(net);
                p->sysctl_table = NULL;
                write_lock_bh(&tbl->lock);
                p->next         = tbl->parms.next;
@@ -1326,8 +1357,9 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
        NEIGH_PRINTK1("neigh_parms_release: not found\n");
 }
 
-void neigh_parms_destroy(struct neigh_parms *parms)
+static void neigh_parms_destroy(struct neigh_parms *parms)
 {
+       release_net(parms->net);
        kfree(parms);
 }
 
@@ -1338,6 +1370,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
        unsigned long now = jiffies;
        unsigned long phsize;
 
+       tbl->parms.net = &init_net;
        atomic_set(&tbl->parms.refcnt, 1);
        INIT_RCU_HEAD(&tbl->parms.rcu_head);
        tbl->parms.reachable_time =
@@ -1372,15 +1405,11 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
        get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd));
 
        rwlock_init(&tbl->lock);
-       init_timer(&tbl->gc_timer);
-       tbl->gc_timer.data     = (unsigned long)tbl;
-       tbl->gc_timer.function = neigh_periodic_timer;
+       setup_timer(&tbl->gc_timer, neigh_periodic_timer, (unsigned long)tbl);
        tbl->gc_timer.expires  = now + 1;
        add_timer(&tbl->gc_timer);
 
-       init_timer(&tbl->proxy_timer);
-       tbl->proxy_timer.data     = (unsigned long)tbl;
-       tbl->proxy_timer.function = neigh_proxy_process;
+       setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl);
        skb_queue_head_init_class(&tbl->proxy_queue,
                        &neigh_table_proxy_queue_class);
 
@@ -1483,7 +1512,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                        goto out_dev_put;
 
                if (ndm->ndm_flags & NTF_PROXY) {
-                       err = pneigh_delete(tbl, nla_data(dst_attr), dev);
+                       err = pneigh_delete(tbl, net, nla_data(dst_attr), dev);
                        goto out_dev_put;
                }
 
@@ -1560,7 +1589,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                        struct pneigh_entry *pn;
 
                        err = -ENOBUFS;
-                       pn = pneigh_lookup(tbl, dst, dev, 1);
+                       pn = pneigh_lookup(tbl, net, dst, dev, 1);
                        if (pn) {
                                pn->flags = ndm->ndm_flags;
                                err = 0;
@@ -1755,19 +1784,6 @@ errout:
        return -EMSGSIZE;
 }
 
-static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
-                                                     int ifindex)
-{
-       struct neigh_parms *p;
-
-       for (p = &tbl->parms; p; p = p->next)
-               if ((p->dev && p->dev->ifindex == ifindex) ||
-                   (!p->dev && !ifindex))
-                       return p;
-
-       return NULL;
-}
-
 static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = {
        [NDTA_NAME]             = { .type = NLA_STRING },
        [NDTA_THRESH1]          = { .type = NLA_U32 },
@@ -1795,6 +1811,7 @@ static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = {
 
 static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct neigh_table *tbl;
        struct ndtmsg *ndtmsg;
        struct nlattr *tb[NDTA_MAX+1];
@@ -1844,7 +1861,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                if (tbp[NDTPA_IFINDEX])
                        ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
 
-               p = lookup_neigh_params(tbl, ifindex);
+               p = lookup_neigh_params(tbl, net, ifindex);
                if (p == NULL) {
                        err = -ENOENT;
                        goto errout_tbl_lock;
@@ -1919,6 +1936,7 @@ errout:
 
 static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int family, tidx, nidx = 0;
        int tbl_skip = cb->args[0];
        int neigh_skip = cb->args[1];
@@ -1938,8 +1956,11 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
                                       NLM_F_MULTI) <= 0)
                        break;
 
-               for (nidx = 0, p = tbl->parms.next; p; p = p->next, nidx++) {
-                       if (nidx < neigh_skip)
+               for (nidx = 0, p = tbl->parms.next; p; p = p->next) {
+                       if (net != p->net)
+                               continue;
+
+                       if (nidx++ < neigh_skip)
                                continue;
 
                        if (neightbl_fill_param_info(skb, tbl, p,
@@ -2015,6 +2036,7 @@ static void neigh_update_notify(struct neighbour *neigh)
 static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                            struct netlink_callback *cb)
 {
+       struct net * net = skb->sk->sk_net;
        struct neighbour *n;
        int rc, h, s_h = cb->args[1];
        int idx, s_idx = idx = cb->args[2];
@@ -2025,8 +2047,12 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                        continue;
                if (h > s_h)
                        s_idx = 0;
-               for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next, idx++) {
-                       if (idx < s_idx)
+               for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
+                       int lidx;
+                       if (n->dev->nd_net != net)
+                               continue;
+                       lidx = idx++;
+                       if (lidx < s_idx)
                                continue;
                        if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
                                            cb->nlh->nlmsg_seq,
@@ -2118,6 +2144,7 @@ EXPORT_SYMBOL(__neigh_for_each_release);
 static struct neighbour *neigh_get_first(struct seq_file *seq)
 {
        struct neigh_seq_state *state = seq->private;
+       struct net *net = state->p.net;
        struct neigh_table *tbl = state->tbl;
        struct neighbour *n = NULL;
        int bucket = state->bucket;
@@ -2127,6 +2154,8 @@ static struct neighbour *neigh_get_first(struct seq_file *seq)
                n = tbl->hash_buckets[bucket];
 
                while (n) {
+                       if (n->dev->nd_net != net)
+                               goto next;
                        if (state->neigh_sub_iter) {
                                loff_t fakep = 0;
                                void *v;
@@ -2156,6 +2185,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
                                        loff_t *pos)
 {
        struct neigh_seq_state *state = seq->private;
+       struct net *net = state->p.net;
        struct neigh_table *tbl = state->tbl;
 
        if (state->neigh_sub_iter) {
@@ -2167,6 +2197,8 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
 
        while (1) {
                while (n) {
+                       if (n->dev->nd_net != net)
+                               goto next;
                        if (state->neigh_sub_iter) {
                                void *v = state->neigh_sub_iter(state, n, pos);
                                if (v)
@@ -2213,6 +2245,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
 static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
 {
        struct neigh_seq_state *state = seq->private;
+       struct net * net = state->p.net;
        struct neigh_table *tbl = state->tbl;
        struct pneigh_entry *pn = NULL;
        int bucket = state->bucket;
@@ -2220,6 +2253,8 @@ static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
        state->flags |= NEIGH_SEQ_IS_PNEIGH;
        for (bucket = 0; bucket <= PNEIGH_HASHMASK; bucket++) {
                pn = tbl->phash_buckets[bucket];
+               while (pn && (pn->net != net))
+                       pn = pn->next;
                if (pn)
                        break;
        }
@@ -2233,6 +2268,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
                                            loff_t *pos)
 {
        struct neigh_seq_state *state = seq->private;
+       struct net * net = state->p.net;
        struct neigh_table *tbl = state->tbl;
 
        pn = pn->next;
@@ -2240,6 +2276,8 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
                if (++state->bucket > PNEIGH_HASHMASK)
                        break;
                pn = tbl->phash_buckets[state->bucket];
+               while (pn && (pn->net != net))
+                       pn = pn->next;
                if (pn)
                        break;
        }
@@ -2277,6 +2315,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
 }
 
 void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags)
+       __acquires(tbl->lock)
 {
        struct neigh_seq_state *state = seq->private;
        loff_t pos_minus_one;
@@ -2320,6 +2359,7 @@ out:
 EXPORT_SYMBOL(neigh_seq_next);
 
 void neigh_seq_stop(struct seq_file *seq, void *v)
+       __releases(tbl->lock)
 {
        struct neigh_seq_state *state = seq->private;
        struct neigh_table *tbl = state->tbl;
@@ -2441,6 +2481,7 @@ static inline size_t neigh_nlmsg_size(void)
 
 static void __neigh_notify(struct neighbour *n, int type, int flags)
 {
+       struct net *net = n->dev->nd_net;
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
@@ -2455,10 +2496,10 @@ static void __neigh_notify(struct neighbour *n, int type, int flags)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_NEIGH, err);
+               rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
 }
 
 #ifdef CONFIG_ARPD
@@ -2472,11 +2513,8 @@ void neigh_app_ns(struct neighbour *n)
 
 static struct neigh_sysctl_table {
        struct ctl_table_header *sysctl_header;
-       ctl_table               neigh_vars[__NET_NEIGH_MAX];
-       ctl_table               neigh_dev[2];
-       ctl_table               neigh_neigh_dir[2];
-       ctl_table               neigh_proto_dir[2];
-       ctl_table               neigh_root_dir[2];
+       struct ctl_table neigh_vars[__NET_NEIGH_MAX];
+       char *dev_name;
 } neigh_sysctl_template __read_mostly = {
        .neigh_vars = {
                {
@@ -2607,32 +2645,7 @@ static struct neigh_sysctl_table {
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec,
                },
-               {}
-       },
-       .neigh_dev = {
-               {
-                       .ctl_name       = NET_PROTO_CONF_DEFAULT,
-                       .procname       = "default",
-                       .mode           = 0555,
-               },
-       },
-       .neigh_neigh_dir = {
-               {
-                       .procname       = "neigh",
-                       .mode           = 0555,
-               },
-       },
-       .neigh_proto_dir = {
-               {
-                       .mode           = 0555,
-               },
-       },
-       .neigh_root_dir = {
-               {
-                       .ctl_name       = CTL_NET,
-                       .procname       = "net",
-                       .mode           = 0555,
-               },
+               {},
        },
 };
 
@@ -2640,14 +2653,26 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
                          int p_id, int pdev_id, char *p_name,
                          proc_handler *handler, ctl_handler *strategy)
 {
-       struct neigh_sysctl_table *t = kmemdup(&neigh_sysctl_template,
-                                              sizeof(*t), GFP_KERNEL);
+       struct neigh_sysctl_table *t;
        const char *dev_name_source = NULL;
-       char *dev_name = NULL;
-       int err = 0;
 
+#define NEIGH_CTL_PATH_ROOT    0
+#define NEIGH_CTL_PATH_PROTO   1
+#define NEIGH_CTL_PATH_NEIGH   2
+#define NEIGH_CTL_PATH_DEV     3
+
+       struct ctl_path neigh_path[] = {
+               { .procname = "net",     .ctl_name = CTL_NET, },
+               { .procname = "proto",   .ctl_name = 0, },
+               { .procname = "neigh",   .ctl_name = 0, },
+               { .procname = "default", .ctl_name = NET_PROTO_CONF_DEFAULT, },
+               { },
+       };
+
+       t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL);
        if (!t)
-               return -ENOBUFS;
+               goto err;
+
        t->neigh_vars[0].data  = &p->mcast_probes;
        t->neigh_vars[1].data  = &p->ucast_probes;
        t->neigh_vars[2].data  = &p->app_probes;
@@ -2665,11 +2690,11 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
 
        if (dev) {
                dev_name_source = dev->name;
-               t->neigh_dev[0].ctl_name = dev->ifindex;
+               neigh_path[NEIGH_CTL_PATH_DEV].ctl_name = dev->ifindex;
                /* Terminate the table early */
                memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
        } else {
-               dev_name_source = t->neigh_dev[0].procname;
+               dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname;
                t->neigh_vars[14].data = (int *)(p + 1);
                t->neigh_vars[15].data = (int *)(p + 1) + 1;
                t->neigh_vars[16].data = (int *)(p + 1) + 2;
@@ -2704,39 +2729,28 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
                        t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
        }
 
-       dev_name = kstrdup(dev_name_source, GFP_KERNEL);
-       if (!dev_name) {
-               err = -ENOBUFS;
+       t->dev_name = kstrdup(dev_name_source, GFP_KERNEL);
+       if (!t->dev_name)
                goto free;
-       }
-
-       t->neigh_dev[0].procname = dev_name;
-
-       t->neigh_neigh_dir[0].ctl_name = pdev_id;
 
-       t->neigh_proto_dir[0].procname = p_name;
-       t->neigh_proto_dir[0].ctl_name = p_id;
+       neigh_path[NEIGH_CTL_PATH_DEV].procname = t->dev_name;
+       neigh_path[NEIGH_CTL_PATH_NEIGH].ctl_name = pdev_id;
+       neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
+       neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id;
 
-       t->neigh_dev[0].child          = t->neigh_vars;
-       t->neigh_neigh_dir[0].child    = t->neigh_dev;
-       t->neigh_proto_dir[0].child    = t->neigh_neigh_dir;
-       t->neigh_root_dir[0].child     = t->neigh_proto_dir;
-
-       t->sysctl_header = register_sysctl_table(t->neigh_root_dir);
-       if (!t->sysctl_header) {
-               err = -ENOBUFS;
+       t->sysctl_header = register_sysctl_paths(neigh_path, t->neigh_vars);
+       if (!t->sysctl_header)
                goto free_procname;
-       }
+
        p->sysctl_table = t;
        return 0;
 
-       /* error path */
- free_procname:
-       kfree(dev_name);
- free:
+free_procname:
+       kfree(t->dev_name);
+free:
        kfree(t);
-
-       return err;
+err:
+       return -ENOBUFS;
 }
 
 void neigh_sysctl_unregister(struct neigh_parms *p)
@@ -2745,7 +2759,7 @@ void neigh_sysctl_unregister(struct neigh_parms *p)
                struct neigh_sysctl_table *t = p->sysctl_table;
                p->sysctl_table = NULL;
                unregister_sysctl_table(t->sysctl_header);
-               kfree(t->neigh_dev[0].procname);
+               kfree(t->dev_name);
                kfree(t);
        }
 }
index 61ead1d111321d292798d5cc539845ea0917f5e6..7635d3f7272324f06866754ffd22df48408fc455 100644 (file)
@@ -95,17 +95,6 @@ NETDEVICE_SHOW(type, fmt_dec);
 NETDEVICE_SHOW(link_mode, fmt_dec);
 
 /* use same locking rules as GIFHWADDR ioctl's */
-static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
-{
-       int i;
-       char *cp = buf;
-
-       for (i = 0; i < len; i++)
-               cp += sprintf(cp, "%02x%c", addr[i],
-                             i == (len - 1) ? '\n' : ':');
-       return cp - buf;
-}
-
 static ssize_t show_address(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
@@ -114,7 +103,7 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr,
 
        read_lock(&dev_base_lock);
        if (dev_isalive(net))
-           ret = format_addr(buf, net->dev_addr, net->addr_len);
+               ret = sysfs_format_mac(buf, net->dev_addr, net->addr_len);
        read_unlock(&dev_base_lock);
        return ret;
 }
@@ -124,7 +113,7 @@ static ssize_t show_broadcast(struct device *dev,
 {
        struct net_device *net = to_net_dev(dev);
        if (dev_isalive(net))
-               return format_addr(buf, net->broadcast, net->addr_len);
+               return sysfs_format_mac(buf, net->broadcast, net->addr_len);
        return -EINVAL;
 }
 
@@ -247,9 +236,8 @@ static ssize_t netstat_show(const struct device *d,
        struct net_device_stats *stats;
        ssize_t ret = -EINVAL;
 
-       if (offset > sizeof(struct net_device_stats) ||
-           offset % sizeof(unsigned long) != 0)
-               WARN_ON(1);
+       WARN_ON(offset > sizeof(struct net_device_stats) ||
+                       offset % sizeof(unsigned long) != 0);
 
        read_lock(&dev_base_lock);
        if (dev_isalive(dev) && dev->get_stats &&
index ec936ae92458fb6325b33495b09216bb5fc09831..26e941d912e8e68dd1e308e705fec2bbd92d37fc 100644 (file)
@@ -58,6 +58,7 @@ out_undo:
 
 #ifdef CONFIG_NET_NS
 static struct kmem_cache *net_cachep;
+static struct workqueue_struct *netns_wq;
 
 static struct net *net_alloc(void)
 {
@@ -149,7 +150,7 @@ void __put_net(struct net *net)
 {
        /* Cleanup the network namespace in process context */
        INIT_WORK(&net->work, cleanup_net);
-       schedule_work(&net->work);
+       queue_work(netns_wq, &net->work);
 }
 EXPORT_SYMBOL_GPL(__put_net);
 
@@ -171,7 +172,13 @@ static int __init net_ns_init(void)
        net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
                                        SMP_CACHE_BYTES,
                                        SLAB_PANIC, NULL);
+
+       /* Create workqueue for cleanup */
+       netns_wq = create_singlethread_workqueue("netns");
+       if (!netns_wq)
+               panic("Could not create netns workq");
 #endif
+
        mutex_lock(&net_mutex);
        err = setup_net(&init_net);
 
index c499b5c69bedbce96611baaec02eb9cfcb0798a6..6faa128a4c8ef22d110c22b2add2dc8a4ffbbfd3 100644 (file)
@@ -39,8 +39,6 @@ static struct sk_buff_head skb_pool;
 static atomic_t trapped;
 
 #define USEC_PER_POLL  50
-#define NETPOLL_RX_ENABLED  1
-#define NETPOLL_RX_DROP     2
 
 #define MAX_SKB_SIZE \
                (MAX_UDP_CHUNK + sizeof(struct udphdr) + \
@@ -128,27 +126,24 @@ static int poll_one_napi(struct netpoll_info *npinfo,
        if (!test_bit(NAPI_STATE_SCHED, &napi->state))
                return budget;
 
-       npinfo->rx_flags |= NETPOLL_RX_DROP;
        atomic_inc(&trapped);
 
        work = napi->poll(napi, budget);
 
        atomic_dec(&trapped);
-       npinfo->rx_flags &= ~NETPOLL_RX_DROP;
 
        return budget - work;
 }
 
-static void poll_napi(struct netpoll *np)
+static void poll_napi(struct net_device *dev)
 {
-       struct netpoll_info *npinfo = np->dev->npinfo;
        struct napi_struct *napi;
        int budget = 16;
 
-       list_for_each_entry(napi, &np->dev->napi_list, dev_list) {
+       list_for_each_entry(napi, &dev->napi_list, dev_list) {
                if (napi->poll_owner != smp_processor_id() &&
                    spin_trylock(&napi->poll_lock)) {
-                       budget = poll_one_napi(npinfo, napi, budget);
+                       budget = poll_one_napi(dev->npinfo, napi, budget);
                        spin_unlock(&napi->poll_lock);
 
                        if (!budget)
@@ -159,30 +154,27 @@ static void poll_napi(struct netpoll *np)
 
 static void service_arp_queue(struct netpoll_info *npi)
 {
-       struct sk_buff *skb;
-
-       if (unlikely(!npi))
-               return;
-
-       skb = skb_dequeue(&npi->arp_tx);
+       if (npi) {
+               struct sk_buff *skb;
 
-       while (skb != NULL) {
-               arp_reply(skb);
-               skb = skb_dequeue(&npi->arp_tx);
+               while ((skb = skb_dequeue(&npi->arp_tx)))
+                       arp_reply(skb);
        }
 }
 
 void netpoll_poll(struct netpoll *np)
 {
-       if (!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
+       struct net_device *dev = np->dev;
+
+       if (!dev || !netif_running(dev) || !dev->poll_controller)
                return;
 
        /* Process pending work on NIC */
-       np->dev->poll_controller(np->dev);
-       if (!list_empty(&np->dev->napi_list))
-               poll_napi(np);
+       dev->poll_controller(dev);
+
+       poll_napi(dev);
 
-       service_arp_queue(np->dev->npinfo);
+       service_arp_queue(dev->npinfo);
 
        zap_completion_queue();
 }
@@ -364,8 +356,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
        eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
        skb_reset_mac_header(skb);
        skb->protocol = eth->h_proto = htons(ETH_P_IP);
-       memcpy(eth->h_source, np->local_mac, 6);
-       memcpy(eth->h_dest, np->remote_mac, 6);
+       memcpy(eth->h_source, np->dev->dev_addr, ETH_ALEN);
+       memcpy(eth->h_dest, np->remote_mac, ETH_ALEN);
 
        skb->dev = np->dev;
 
@@ -418,7 +410,8 @@ static void arp_reply(struct sk_buff *skb)
        memcpy(&tip, arp_ptr, 4);
 
        /* Should we ignore arp? */
-       if (tip != htonl(np->local_ip) || LOOPBACK(tip) || MULTICAST(tip))
+       if (tip != htonl(np->local_ip) ||
+           ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
                return;
 
        size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
@@ -435,7 +428,7 @@ static void arp_reply(struct sk_buff *skb)
 
        /* Fill the device header for the ARP frame */
        if (dev_hard_header(send_skb, skb->dev, ptype,
-                           sha, np->local_mac,
+                           sha, np->dev->dev_addr,
                            send_skb->len) < 0) {
                kfree_skb(send_skb);
                return;
@@ -479,7 +472,7 @@ int __netpoll_rx(struct sk_buff *skb)
        if (skb->dev->type != ARPHRD_ETHER)
                goto out;
 
-       /* check if netpoll clients need ARP */
+       /* if receive ARP during middle of NAPI poll, then queue */
        if (skb->protocol == htons(ETH_P_ARP) &&
            atomic_read(&trapped)) {
                skb_queue_tail(&npi->arp_tx, skb);
@@ -541,6 +534,9 @@ int __netpoll_rx(struct sk_buff *skb)
        return 1;
 
 out:
+       /* If packet received while already in poll then just
+        * silently drop.
+        */
        if (atomic_read(&trapped)) {
                kfree_skb(skb);
                return 1;
@@ -679,7 +675,6 @@ int netpoll_setup(struct netpoll *np)
                        goto release;
                }
 
-               npinfo->rx_flags = 0;
                npinfo->rx_np = NULL;
 
                spin_lock_init(&npinfo->rx_lock);
@@ -741,9 +736,6 @@ int netpoll_setup(struct netpoll *np)
                }
        }
 
-       if (is_zero_ether_addr(np->local_mac) && ndev->dev_addr)
-               memcpy(np->local_mac, ndev->dev_addr, 6);
-
        if (!np->local_ip) {
                rcu_read_lock();
                in_dev = __in_dev_get_rcu(ndev);
@@ -764,7 +756,6 @@ int netpoll_setup(struct netpoll *np)
 
        if (np->rx_hook) {
                spin_lock_irqsave(&npinfo->rx_lock, flags);
-               npinfo->rx_flags |= NETPOLL_RX_ENABLED;
                npinfo->rx_np = np;
                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
        }
@@ -806,7 +797,6 @@ void netpoll_cleanup(struct netpoll *np)
                        if (npinfo->rx_np == np) {
                                spin_lock_irqsave(&npinfo->rx_lock, flags);
                                npinfo->rx_np = NULL;
-                               npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
                                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
                        }
 
@@ -816,11 +806,7 @@ void netpoll_cleanup(struct netpoll *np)
                                cancel_rearming_delayed_work(&npinfo->tx_work);
 
                                /* clean after last, unfinished work */
-                               if (!skb_queue_empty(&npinfo->txq)) {
-                                       struct sk_buff *skb;
-                                       skb = __skb_dequeue(&npinfo->txq);
-                                       kfree_skb(skb);
-                               }
+                               __skb_queue_purge(&npinfo->txq);
                                kfree(npinfo);
                                np->dev->npinfo = NULL;
                        }
index 285ec3ed9b378179248b8d8900ad983c9ee0f210..eebccdbdbacafb1c913be9dc6ec51b57875afc46 100644 (file)
@@ -397,62 +397,6 @@ struct pktgen_thread {
 #define REMOVE 1
 #define FIND   0
 
-/*  This code works around the fact that do_div cannot handle two 64-bit
-    numbers, and regular 64-bit division doesn't work on x86 kernels.
-    --Ben
-*/
-
-#define PG_DIV 0
-
-/* This was emailed to LMKL by: Chris Caputo <ccaputo@alt.net>
- * Function copied/adapted/optimized from:
- *
- *  nemesis.sourceforge.net/browse/lib/static/intmath/ix86/intmath.c.html
- *
- * Copyright 1994, University of Cambridge Computer Laboratory
- * All Rights Reserved.
- *
- */
-static inline s64 divremdi3(s64 x, s64 y, int type)
-{
-       u64 a = (x < 0) ? -x : x;
-       u64 b = (y < 0) ? -y : y;
-       u64 res = 0, d = 1;
-
-       if (b > 0) {
-               while (b < a) {
-                       b <<= 1;
-                       d <<= 1;
-               }
-       }
-
-       do {
-               if (a >= b) {
-                       a -= b;
-                       res += d;
-               }
-               b >>= 1;
-               d >>= 1;
-       }
-       while (d);
-
-       if (PG_DIV == type) {
-               return (((x ^ y) & (1ll << 63)) == 0) ? res : -(s64) res;
-       } else {
-               return ((x & (1ll << 63)) == 0) ? a : -(s64) a;
-       }
-}
-
-/* End of hacks to deal with 64-bit math on x86 */
-
-/** Convert to milliseconds */
-static inline __u64 tv_to_ms(const struct timeval *tv)
-{
-       __u64 ms = tv->tv_usec / 1000;
-       ms += (__u64) tv->tv_sec * (__u64) 1000;
-       return ms;
-}
-
 /** Convert to micro-seconds */
 static inline __u64 tv_to_us(const struct timeval *tv)
 {
@@ -461,51 +405,13 @@ static inline __u64 tv_to_us(const struct timeval *tv)
        return us;
 }
 
-static inline __u64 pg_div(__u64 n, __u32 base)
-{
-       __u64 tmp = n;
-       do_div(tmp, base);
-       /* printk("pktgen: pg_div, n: %llu  base: %d  rv: %llu\n",
-          n, base, tmp); */
-       return tmp;
-}
-
-static inline __u64 pg_div64(__u64 n, __u64 base)
-{
-       __u64 tmp = n;
-/*
- * How do we know if the architecture we are running on
- * supports division with 64 bit base?
- *
- */
-#if defined(__sparc_v9__) || defined(__powerpc64__) || defined(__alpha__) || defined(__x86_64__) || defined(__ia64__)
-
-       do_div(tmp, base);
-#else
-       tmp = divremdi3(n, base, PG_DIV);
-#endif
-       return tmp;
-}
-
-static inline __u64 getCurMs(void)
-{
-       struct timeval tv;
-       do_gettimeofday(&tv);
-       return tv_to_ms(&tv);
-}
-
-static inline __u64 getCurUs(void)
+static __u64 getCurUs(void)
 {
        struct timeval tv;
        do_gettimeofday(&tv);
        return tv_to_us(&tv);
 }
 
-static inline __u64 tv_diff(const struct timeval *a, const struct timeval *b)
-{
-       return tv_to_us(a) - tv_to_us(b);
-}
-
 /* old include end */
 
 static char version[] __initdata = VERSION;
@@ -2358,9 +2264,11 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
                                        t = random32() % (imx - imn) + imn;
                                        s = htonl(t);
 
-                                       while (LOOPBACK(s) || MULTICAST(s)
-                                              || BADCLASS(s) || ZERONET(s)
-                                              || LOCAL_MCAST(s)) {
+                                       while (ipv4_is_loopback(s) ||
+                                              ipv4_is_multicast(s) ||
+                                              ipv4_is_lbcast(s) ||
+                                              ipv4_is_zeronet(s) ||
+                                              ipv4_is_local_multicast(s)) {
                                                t = random32() % (imx - imn) + imn;
                                                s = htonl(t);
                                        }
index 45aed75cb571220da14d2924ec9674ac06f4d99b..2d3035d3abd7a923eef8849f0b31590ee418bdd4 100644 (file)
@@ -69,8 +69,6 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
        return 0;
 }
 
-EXPORT_SYMBOL(reqsk_queue_alloc);
-
 void __reqsk_queue_destroy(struct request_sock_queue *queue)
 {
        struct listen_sock *lopt;
@@ -91,8 +89,6 @@ void __reqsk_queue_destroy(struct request_sock_queue *queue)
                kfree(lopt);
 }
 
-EXPORT_SYMBOL(__reqsk_queue_destroy);
-
 static inline struct listen_sock *reqsk_queue_yank_listen_sk(
                struct request_sock_queue *queue)
 {
@@ -134,4 +130,3 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
                kfree(lopt);
 }
 
-EXPORT_SYMBOL(reqsk_queue_destroy);
index fed95a323b281049f8245ba2fc1619c21decf2c9..ddbdde82a700dcf46a81a05439c966182b851d8c 100644 (file)
@@ -60,7 +60,6 @@ struct rtnl_link
 };
 
 static DEFINE_MUTEX(rtnl_mutex);
-static struct sock *rtnl;
 
 void rtnl_lock(void)
 {
@@ -458,8 +457,9 @@ size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
        return ret;
 }
 
-int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
+int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo)
 {
+       struct sock *rtnl = net->rtnl;
        int err = 0;
 
        NETLINK_CB(skb).dst_group = group;
@@ -471,14 +471,17 @@ int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
        return err;
 }
 
-int rtnl_unicast(struct sk_buff *skb, u32 pid)
+int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
 {
+       struct sock *rtnl = net->rtnl;
+
        return nlmsg_unicast(rtnl, skb, pid);
 }
 
-int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
+int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
                struct nlmsghdr *nlh, gfp_t flags)
 {
+       struct sock *rtnl = net->rtnl;
        int report = 0;
 
        if (nlh)
@@ -487,8 +490,10 @@ int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
        return nlmsg_notify(rtnl, skb, pid, group, report, flags);
 }
 
-void rtnl_set_sk_err(u32 group, int error)
+void rtnl_set_sk_err(struct net *net, u32 group, int error)
 {
+       struct sock *rtnl = net->rtnl;
+
        netlink_set_err(rtnl, 0, group, error);
 }
 
@@ -1186,7 +1191,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
                kfree_skb(nskb);
                goto errout;
        }
-       err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
+       err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
 errout:
        dev_put(dev);
 
@@ -1219,6 +1224,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
 
 void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
 {
+       struct net *net = dev->nd_net;
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
@@ -1233,10 +1239,10 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
+       err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_LINK, err);
+               rtnl_set_sk_err(net, RTNLGRP_LINK, err);
 }
 
 /* Protected by RTNL sempahore.  */
@@ -1247,6 +1253,7 @@ static int rtattr_max;
 
 static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
+       struct net *net = skb->sk->sk_net;
        rtnl_doit_func doit;
        int sz_idx, kind;
        int min_len;
@@ -1275,6 +1282,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                return -EPERM;
 
        if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
+               struct sock *rtnl;
                rtnl_dumpit_func dumpit;
 
                dumpit = rtnl_get_dumpit(family, type);
@@ -1282,6 +1290,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                        return -EOPNOTSUPP;
 
                __rtnl_unlock();
+               rtnl = net->rtnl;
                err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
                rtnl_lock();
                return err;
@@ -1326,9 +1335,6 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
 {
        struct net_device *dev = ptr;
 
-       if (dev->nd_net != &init_net)
-               return NOTIFY_DONE;
-
        switch (event) {
        case NETDEV_UNREGISTER:
                rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
@@ -1354,6 +1360,29 @@ static struct notifier_block rtnetlink_dev_notifier = {
        .notifier_call  = rtnetlink_event,
 };
 
+
+static int rtnetlink_net_init(struct net *net)
+{
+       struct sock *sk;
+       sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
+                                  rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
+       if (!sk)
+               return -ENOMEM;
+       net->rtnl = sk;
+       return 0;
+}
+
+static void rtnetlink_net_exit(struct net *net)
+{
+       netlink_kernel_release(net->rtnl);
+       net->rtnl = NULL;
+}
+
+static struct pernet_operations rtnetlink_net_ops = {
+       .init = rtnetlink_net_init,
+       .exit = rtnetlink_net_exit,
+};
+
 void __init rtnetlink_init(void)
 {
        int i;
@@ -1366,10 +1395,9 @@ void __init rtnetlink_init(void)
        if (!rta_buf)
                panic("rtnetlink_init: cannot allocate rta_buf\n");
 
-       rtnl = netlink_kernel_create(&init_net, NETLINK_ROUTE, RTNLGRP_MAX,
-                                    rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
-       if (rtnl == NULL)
+       if (register_pernet_subsys(&rtnetlink_net_ops))
                panic("rtnetlink_init: cannot initialize rtnetlink\n");
+
        netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
        register_netdevice_notifier(&rtnetlink_dev_notifier);
 
index b6283779e93d4432f9f9cad9f4c7a1610b3d1763..98420f9c4b6d3cf8e77ec27856ff0abbec10ea46 100644 (file)
@@ -52,6 +52,7 @@
 #endif
 #include <linux/string.h>
 #include <linux/skbuff.h>
+#include <linux/splice.h>
 #include <linux/cache.h>
 #include <linux/rtnetlink.h>
 #include <linux/init.h>
 static struct kmem_cache *skbuff_head_cache __read_mostly;
 static struct kmem_cache *skbuff_fclone_cache __read_mostly;
 
+static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
+                                 struct pipe_buffer *buf)
+{
+       struct sk_buff *skb = (struct sk_buff *) buf->private;
+
+       kfree_skb(skb);
+}
+
+static void sock_pipe_buf_get(struct pipe_inode_info *pipe,
+                               struct pipe_buffer *buf)
+{
+       struct sk_buff *skb = (struct sk_buff *) buf->private;
+
+       skb_get(skb);
+}
+
+static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
+                              struct pipe_buffer *buf)
+{
+       return 1;
+}
+
+
+/* Pipe buffer operations for a socket. */
+static struct pipe_buf_operations sock_pipe_buf_ops = {
+       .can_merge = 0,
+       .map = generic_pipe_buf_map,
+       .unmap = generic_pipe_buf_unmap,
+       .confirm = generic_pipe_buf_confirm,
+       .release = sock_pipe_buf_release,
+       .steal = sock_pipe_buf_steal,
+       .get = sock_pipe_buf_get,
+};
+
 /*
  *     Keep out-of-line to prevent kernel bloat.
  *     __builtin_return_address is not used because it is not always
@@ -1122,6 +1157,217 @@ fault:
        return -EFAULT;
 }
 
+/*
+ * Callback from splice_to_pipe(), if we need to release some pages
+ * at the end of the spd in case we error'ed out in filling the pipe.
+ */
+static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
+{
+       struct sk_buff *skb = (struct sk_buff *) spd->partial[i].private;
+
+       kfree_skb(skb);
+}
+
+/*
+ * Fill page/offset/length into spd, if it can hold more pages.
+ */
+static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
+                               unsigned int len, unsigned int offset,
+                               struct sk_buff *skb)
+{
+       if (unlikely(spd->nr_pages == PIPE_BUFFERS))
+               return 1;
+
+       spd->pages[spd->nr_pages] = page;
+       spd->partial[spd->nr_pages].len = len;
+       spd->partial[spd->nr_pages].offset = offset;
+       spd->partial[spd->nr_pages].private = (unsigned long) skb_get(skb);
+       spd->nr_pages++;
+       return 0;
+}
+
+/*
+ * Map linear and fragment data from the skb to spd. Returns number of
+ * pages mapped.
+ */
+static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
+                            unsigned int *total_len,
+                            struct splice_pipe_desc *spd)
+{
+       unsigned int nr_pages = spd->nr_pages;
+       unsigned int poff, plen, len, toff, tlen;
+       int headlen, seg;
+
+       toff = *offset;
+       tlen = *total_len;
+       if (!tlen)
+               goto err;
+
+       /*
+        * if the offset is greater than the linear part, go directly to
+        * the fragments.
+        */
+       headlen = skb_headlen(skb);
+       if (toff >= headlen) {
+               toff -= headlen;
+               goto map_frag;
+       }
+
+       /*
+        * first map the linear region into the pages/partial map, skipping
+        * any potential initial offset.
+        */
+       len = 0;
+       while (len < headlen) {
+               void *p = skb->data + len;
+
+               poff = (unsigned long) p & (PAGE_SIZE - 1);
+               plen = min_t(unsigned int, headlen - len, PAGE_SIZE - poff);
+               len += plen;
+
+               if (toff) {
+                       if (plen <= toff) {
+                               toff -= plen;
+                               continue;
+                       }
+                       plen -= toff;
+                       poff += toff;
+                       toff = 0;
+               }
+
+               plen = min(plen, tlen);
+               if (!plen)
+                       break;
+
+               /*
+                * just jump directly to update and return, no point
+                * in going over fragments when the output is full.
+                */
+               if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb))
+                       goto done;
+
+               tlen -= plen;
+       }
+
+       /*
+        * then map the fragments
+        */
+map_frag:
+       for (seg = 0; seg < skb_shinfo(skb)->nr_frags; seg++) {
+               const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
+
+               plen = f->size;
+               poff = f->page_offset;
+
+               if (toff) {
+                       if (plen <= toff) {
+                               toff -= plen;
+                               continue;
+                       }
+                       plen -= toff;
+                       poff += toff;
+                       toff = 0;
+               }
+
+               plen = min(plen, tlen);
+               if (!plen)
+                       break;
+
+               if (spd_fill_page(spd, f->page, plen, poff, skb))
+                       break;
+
+               tlen -= plen;
+       }
+
+done:
+       if (spd->nr_pages - nr_pages) {
+               *offset = 0;
+               *total_len = tlen;
+               return 0;
+       }
+err:
+       return 1;
+}
+
+/*
+ * Map data from the skb to a pipe. Should handle both the linear part,
+ * the fragments, and the frag list. It does NOT handle frag lists within
+ * the frag list, if such a thing exists. We'd probably need to recurse to
+ * handle that cleanly.
+ */
+int skb_splice_bits(struct sk_buff *__skb, unsigned int offset,
+                   struct pipe_inode_info *pipe, unsigned int tlen,
+                   unsigned int flags)
+{
+       struct partial_page partial[PIPE_BUFFERS];
+       struct page *pages[PIPE_BUFFERS];
+       struct splice_pipe_desc spd = {
+               .pages = pages,
+               .partial = partial,
+               .flags = flags,
+               .ops = &sock_pipe_buf_ops,
+               .spd_release = sock_spd_release,
+       };
+       struct sk_buff *skb;
+
+       /*
+        * I'd love to avoid the clone here, but tcp_read_sock()
+        * ignores reference counts and unconditonally kills the sk_buff
+        * on return from the actor.
+        */
+       skb = skb_clone(__skb, GFP_KERNEL);
+       if (unlikely(!skb))
+               return -ENOMEM;
+
+       /*
+        * __skb_splice_bits() only fails if the output has no room left,
+        * so no point in going over the frag_list for the error case.
+        */
+       if (__skb_splice_bits(skb, &offset, &tlen, &spd))
+               goto done;
+       else if (!tlen)
+               goto done;
+
+       /*
+        * 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))
+                               break;
+               }
+       }
+
+done:
+       /*
+        * drop our reference to the clone, the pipe consumption will
+        * drop the rest.
+        */
+       kfree_skb(skb);
+
+       if (spd.nr_pages) {
+               int ret;
+
+               /*
+                * Drop the socket lock, otherwise we have reverse
+                * locking dependencies between sk_lock and i_mutex
+                * here as compared to sendfile(). We enter here
+                * with the socket lock held, and splice_to_pipe() will
+                * grab the pipe inode lock. For sendfile() emulation,
+                * we call into ->sendpage() with the i_mutex lock held
+                * and networking will grab the socket lock.
+                */
+               release_sock(__skb->sk);
+               ret = splice_to_pipe(pipe, &spd);
+               lock_sock(__skb->sk);
+               return ret;
+       }
+
+       return 0;
+}
+
 /**
  *     skb_store_bits - store bits from kernel buffer to skb
  *     @skb: destination buffer
index c519b439b8b1927acf2e01209417747d5ebe7cb4..1c4b1cd16d654f1a6737a6bfed3ca6d445f3e8c4 100644 (file)
@@ -154,7 +154,7 @@ static const char *af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_ASH"   , "sk_lock-AF_ECONET"   , "sk_lock-AF_ATMSVC"   ,
   "sk_lock-21"       , "sk_lock-AF_SNA"      , "sk_lock-AF_IRDA"     ,
   "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE"  , "sk_lock-AF_LLC"      ,
-  "sk_lock-27"       , "sk_lock-28"          , "sk_lock-29"          ,
+  "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_MAX"
 };
@@ -168,7 +168,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_ASH"   , "slock-AF_ECONET"   , "slock-AF_ATMSVC"   ,
   "slock-21"       , "slock-AF_SNA"      , "slock-AF_IRDA"     ,
   "slock-AF_PPPOX" , "slock-AF_WANPIPE"  , "slock-AF_LLC"      ,
-  "slock-27"       , "slock-28"          , "slock-29"          ,
+  "slock-27"       , "slock-28"          , "slock-AF_CAN"      ,
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_MAX"
 };
@@ -282,6 +282,11 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        if (err)
                goto out;
 
+       if (!sk_rmem_schedule(sk, skb->truesize)) {
+               err = -ENOBUFS;
+               goto out;
+       }
+
        skb->dev = NULL;
        skb_set_owner_r(skb, sk);
 
@@ -419,6 +424,14 @@ out:
        return ret;
 }
 
+static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
+{
+       if (valbool)
+               sock_set_flag(sk, bit);
+       else
+               sock_reset_flag(sk, bit);
+}
+
 /*
  *     This is meant for all protocols to use and covers goings on
  *     at the socket level. Everything here is generic.
@@ -463,11 +476,8 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
        case SO_DEBUG:
                if (val && !capable(CAP_NET_ADMIN)) {
                        ret = -EACCES;
-               }
-               else if (valbool)
-                       sock_set_flag(sk, SOCK_DBG);
-               else
-                       sock_reset_flag(sk, SOCK_DBG);
+               } else
+                       sock_valbool_flag(sk, SOCK_DBG, valbool);
                break;
        case SO_REUSEADDR:
                sk->sk_reuse = valbool;
@@ -477,10 +487,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
                ret = -ENOPROTOOPT;
                break;
        case SO_DONTROUTE:
-               if (valbool)
-                       sock_set_flag(sk, SOCK_LOCALROUTE);
-               else
-                       sock_reset_flag(sk, SOCK_LOCALROUTE);
+               sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
                break;
        case SO_BROADCAST:
                sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
@@ -1105,7 +1112,9 @@ void sock_rfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
 
+       skb_truesize_check(skb);
        atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+       sk_mem_uncharge(skb->sk, skb->truesize);
 }
 
 
@@ -1382,6 +1391,103 @@ int sk_wait_data(struct sock *sk, long *timeo)
 
 EXPORT_SYMBOL(sk_wait_data);
 
+/**
+ *     __sk_mem_schedule - increase sk_forward_alloc and memory_allocated
+ *     @sk: socket
+ *     @size: memory size to allocate
+ *     @kind: allocation type
+ *
+ *     If kind is SK_MEM_SEND, it means wmem allocation. Otherwise it means
+ *     rmem allocation. This function assumes that protocols which have
+ *     memory_pressure use sk_wmem_queued as write buffer accounting.
+ */
+int __sk_mem_schedule(struct sock *sk, int size, int kind)
+{
+       struct proto *prot = sk->sk_prot;
+       int amt = sk_mem_pages(size);
+       int allocated;
+
+       sk->sk_forward_alloc += amt * SK_MEM_QUANTUM;
+       allocated = atomic_add_return(amt, prot->memory_allocated);
+
+       /* Under limit. */
+       if (allocated <= prot->sysctl_mem[0]) {
+               if (prot->memory_pressure && *prot->memory_pressure)
+                       *prot->memory_pressure = 0;
+               return 1;
+       }
+
+       /* Under pressure. */
+       if (allocated > prot->sysctl_mem[1])
+               if (prot->enter_memory_pressure)
+                       prot->enter_memory_pressure();
+
+       /* Over hard limit. */
+       if (allocated > prot->sysctl_mem[2])
+               goto suppress_allocation;
+
+       /* guarantee minimum buffer size under pressure */
+       if (kind == SK_MEM_RECV) {
+               if (atomic_read(&sk->sk_rmem_alloc) < prot->sysctl_rmem[0])
+                       return 1;
+       } else { /* SK_MEM_SEND */
+               if (sk->sk_type == SOCK_STREAM) {
+                       if (sk->sk_wmem_queued < prot->sysctl_wmem[0])
+                               return 1;
+               } else if (atomic_read(&sk->sk_wmem_alloc) <
+                          prot->sysctl_wmem[0])
+                               return 1;
+       }
+
+       if (prot->memory_pressure) {
+               if (!*prot->memory_pressure ||
+                   prot->sysctl_mem[2] > atomic_read(prot->sockets_allocated) *
+                   sk_mem_pages(sk->sk_wmem_queued +
+                                atomic_read(&sk->sk_rmem_alloc) +
+                                sk->sk_forward_alloc))
+                       return 1;
+       }
+
+suppress_allocation:
+
+       if (kind == SK_MEM_SEND && sk->sk_type == SOCK_STREAM) {
+               sk_stream_moderate_sndbuf(sk);
+
+               /* Fail only if socket is _under_ its sndbuf.
+                * In this case we cannot block, so that we have to fail.
+                */
+               if (sk->sk_wmem_queued + size >= sk->sk_sndbuf)
+                       return 1;
+       }
+
+       /* Alas. Undo changes. */
+       sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM;
+       atomic_sub(amt, prot->memory_allocated);
+       return 0;
+}
+
+EXPORT_SYMBOL(__sk_mem_schedule);
+
+/**
+ *     __sk_reclaim - reclaim memory_allocated
+ *     @sk: socket
+ */
+void __sk_mem_reclaim(struct sock *sk)
+{
+       struct proto *prot = sk->sk_prot;
+
+       atomic_sub(sk->sk_forward_alloc >> SK_MEM_QUANTUM_SHIFT,
+                  prot->memory_allocated);
+       sk->sk_forward_alloc &= SK_MEM_QUANTUM - 1;
+
+       if (prot->memory_pressure && *prot->memory_pressure &&
+           (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0]))
+               *prot->memory_pressure = 0;
+}
+
+EXPORT_SYMBOL(__sk_mem_reclaim);
+
+
 /*
  * Set of default routines for initialising struct proto_ops when
  * the protocol does not support a particular function. In certain
@@ -1496,7 +1602,7 @@ static void sock_def_error_report(struct sock *sk)
        read_lock(&sk->sk_callback_lock);
        if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                wake_up_interruptible(sk->sk_sleep);
-       sk_wake_async(sk,0,POLL_ERR);
+       sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
        read_unlock(&sk->sk_callback_lock);
 }
 
@@ -1505,7 +1611,7 @@ static void sock_def_readable(struct sock *sk, int len)
        read_lock(&sk->sk_callback_lock);
        if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                wake_up_interruptible(sk->sk_sleep);
-       sk_wake_async(sk,1,POLL_IN);
+       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
        read_unlock(&sk->sk_callback_lock);
 }
 
@@ -1522,7 +1628,7 @@ static void sock_def_write_space(struct sock *sk)
 
                /* Should agree with poll, otherwise some programs break */
                if (sock_writeable(sk))
-                       sk_wake_async(sk, 2, POLL_OUT);
+                       sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        }
 
        read_unlock(&sk->sk_callback_lock);
@@ -1537,7 +1643,7 @@ void sk_send_sigurg(struct sock *sk)
 {
        if (sk->sk_socket && sk->sk_socket->file)
                if (send_sigurg(&sk->sk_socket->file->f_owner))
-                       sk_wake_async(sk, 3, POLL_PRI);
+                       sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI);
 }
 
 void sk_reset_timer(struct sock *sk, struct timer_list* timer,
@@ -1611,6 +1717,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
        sk->sk_stamp = ktime_set(-1L, -1L);
 
        atomic_set(&sk->sk_refcnt, 1);
+       atomic_set(&sk->sk_drops, 0);
 }
 
 void fastcall lock_sock_nested(struct sock *sk, int subclass)
@@ -1801,65 +1908,15 @@ EXPORT_SYMBOL(sk_common_release);
 static DEFINE_RWLOCK(proto_list_lock);
 static LIST_HEAD(proto_list);
 
-#ifdef CONFIG_SMP
-/*
- * Define default functions to keep track of inuse sockets per protocol
- * Note that often used protocols use dedicated functions to get a speed increase.
- * (see DEFINE_PROTO_INUSE/REF_PROTO_INUSE)
- */
-static void inuse_add(struct proto *prot, int inc)
-{
-       per_cpu_ptr(prot->inuse_ptr, smp_processor_id())[0] += inc;
-}
-
-static int inuse_get(const struct proto *prot)
-{
-       int res = 0, cpu;
-       for_each_possible_cpu(cpu)
-               res += per_cpu_ptr(prot->inuse_ptr, cpu)[0];
-       return res;
-}
-
-static int inuse_init(struct proto *prot)
-{
-       if (!prot->inuse_getval || !prot->inuse_add) {
-               prot->inuse_ptr = alloc_percpu(int);
-               if (prot->inuse_ptr == NULL)
-                       return -ENOBUFS;
-
-               prot->inuse_getval = inuse_get;
-               prot->inuse_add = inuse_add;
-       }
-       return 0;
-}
-
-static void inuse_fini(struct proto *prot)
-{
-       if (prot->inuse_ptr != NULL) {
-               free_percpu(prot->inuse_ptr);
-               prot->inuse_ptr = NULL;
-               prot->inuse_getval = NULL;
-               prot->inuse_add = NULL;
-       }
-}
-#else
-static inline int inuse_init(struct proto *prot)
-{
-       return 0;
-}
-
-static inline void inuse_fini(struct proto *prot)
-{
-}
-#endif
-
 int proto_register(struct proto *prot, int alloc_slab)
 {
        char *request_sock_slab_name = NULL;
        char *timewait_sock_slab_name;
 
-       if (inuse_init(prot))
+       if (sock_prot_inuse_init(prot) != 0) {
+               printk(KERN_CRIT "%s: Can't alloc inuse counters!\n", prot->name);
                goto out;
+       }
 
        if (alloc_slab) {
                prot->slab = kmem_cache_create(prot->name, prot->obj_size, 0,
@@ -1927,7 +1984,7 @@ out_free_sock_slab:
        kmem_cache_destroy(prot->slab);
        prot->slab = NULL;
 out_free_inuse:
-       inuse_fini(prot);
+       sock_prot_inuse_free(prot);
 out:
        return -ENOBUFS;
 }
@@ -1940,7 +1997,8 @@ void proto_unregister(struct proto *prot)
        list_del(&prot->node);
        write_unlock(&proto_list_lock);
 
-       inuse_fini(prot);
+       sock_prot_inuse_free(prot);
+
        if (prot->slab != NULL) {
                kmem_cache_destroy(prot->slab);
                prot->slab = NULL;
@@ -1967,6 +2025,7 @@ EXPORT_SYMBOL(proto_unregister);
 
 #ifdef CONFIG_PROC_FS
 static void *proto_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(proto_list_lock)
 {
        read_lock(&proto_list_lock);
        return seq_list_start_head(&proto_list, *pos);
@@ -1978,6 +2037,7 @@ static void *proto_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void proto_seq_stop(struct seq_file *seq, void *v)
+       __releases(proto_list_lock)
 {
        read_unlock(&proto_list_lock);
 }
index 755bacbcb321c296a45c5d53ae872469674aa4a8..4a0ad152c9c4492c35fc3abc6ac21bf4580abb20 100644 (file)
@@ -35,7 +35,7 @@ void sk_stream_write_space(struct sock *sk)
                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                        wake_up_interruptible(sk->sk_sleep);
                if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
-                       sock_wake_async(sock, 2, POLL_OUT);
+                       sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT);
        }
 }
 
@@ -172,17 +172,6 @@ do_interrupted:
 
 EXPORT_SYMBOL(sk_stream_wait_memory);
 
-void sk_stream_rfree(struct sk_buff *skb)
-{
-       struct sock *sk = skb->sk;
-
-       skb_truesize_check(skb);
-       atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
-       sk->sk_forward_alloc += skb->truesize;
-}
-
-EXPORT_SYMBOL(sk_stream_rfree);
-
 int sk_stream_error(struct sock *sk, int flags, int err)
 {
        if (err == -EPIPE)
@@ -194,76 +183,6 @@ int sk_stream_error(struct sock *sk, int flags, int err)
 
 EXPORT_SYMBOL(sk_stream_error);
 
-void __sk_stream_mem_reclaim(struct sock *sk)
-{
-       atomic_sub(sk->sk_forward_alloc / SK_STREAM_MEM_QUANTUM,
-                  sk->sk_prot->memory_allocated);
-       sk->sk_forward_alloc &= SK_STREAM_MEM_QUANTUM - 1;
-       if (*sk->sk_prot->memory_pressure &&
-           (atomic_read(sk->sk_prot->memory_allocated) <
-            sk->sk_prot->sysctl_mem[0]))
-               *sk->sk_prot->memory_pressure = 0;
-}
-
-EXPORT_SYMBOL(__sk_stream_mem_reclaim);
-
-int sk_stream_mem_schedule(struct sock *sk, int size, int kind)
-{
-       int amt = sk_stream_pages(size);
-
-       sk->sk_forward_alloc += amt * SK_STREAM_MEM_QUANTUM;
-       atomic_add(amt, sk->sk_prot->memory_allocated);
-
-       /* Under limit. */
-       if (atomic_read(sk->sk_prot->memory_allocated) < sk->sk_prot->sysctl_mem[0]) {
-               if (*sk->sk_prot->memory_pressure)
-                       *sk->sk_prot->memory_pressure = 0;
-               return 1;
-       }
-
-       /* Over hard limit. */
-       if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[2]) {
-               sk->sk_prot->enter_memory_pressure();
-               goto suppress_allocation;
-       }
-
-       /* Under pressure. */
-       if (atomic_read(sk->sk_prot->memory_allocated) > sk->sk_prot->sysctl_mem[1])
-               sk->sk_prot->enter_memory_pressure();
-
-       if (kind) {
-               if (atomic_read(&sk->sk_rmem_alloc) < sk->sk_prot->sysctl_rmem[0])
-                       return 1;
-       } else if (sk->sk_wmem_queued < sk->sk_prot->sysctl_wmem[0])
-               return 1;
-
-       if (!*sk->sk_prot->memory_pressure ||
-           sk->sk_prot->sysctl_mem[2] > atomic_read(sk->sk_prot->sockets_allocated) *
-                               sk_stream_pages(sk->sk_wmem_queued +
-                                               atomic_read(&sk->sk_rmem_alloc) +
-                                               sk->sk_forward_alloc))
-               return 1;
-
-suppress_allocation:
-
-       if (!kind) {
-               sk_stream_moderate_sndbuf(sk);
-
-               /* Fail only if socket is _under_ its sndbuf.
-                * In this case we cannot block, so that we have to fail.
-                */
-               if (sk->sk_wmem_queued + size >= sk->sk_sndbuf)
-                       return 1;
-       }
-
-       /* Alas. Undo changes. */
-       sk->sk_forward_alloc -= amt * SK_STREAM_MEM_QUANTUM;
-       atomic_sub(amt, sk->sk_prot->memory_allocated);
-       return 0;
-}
-
-EXPORT_SYMBOL(sk_stream_mem_schedule);
-
 void sk_stream_kill_queues(struct sock *sk)
 {
        /* First the read buffer. */
@@ -276,7 +195,7 @@ void sk_stream_kill_queues(struct sock *sk)
        BUG_TRAP(skb_queue_empty(&sk->sk_write_queue));
 
        /* Account for returned memory. */
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 
        BUG_TRAP(!sk->sk_wmem_queued);
        BUG_TRAP(!sk->sk_forward_alloc);
index 113cc728dc3190d90d493078aac5c02ab33f012f..130338f83ae5c7be54b7f848d755931f65b4bc0e 100644 (file)
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/netdevice.h>
+#include <linux/init.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
 
-#ifdef CONFIG_SYSCTL
-
-ctl_table core_table[] = {
+static struct ctl_table net_core_table[] = {
 #ifdef CONFIG_NET
        {
                .ctl_name       = NET_CORE_WMEM_MAX,
@@ -128,7 +127,7 @@ ctl_table core_table[] = {
        {
                .ctl_name       = NET_CORE_SOMAXCONN,
                .procname       = "somaxconn",
-               .data           = &sysctl_somaxconn,
+               .data           = &init_net.sysctl_somaxconn,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
@@ -152,4 +151,65 @@ ctl_table core_table[] = {
        { .ctl_name = 0 }
 };
 
-#endif
+static __net_initdata struct ctl_path net_core_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "core", .ctl_name = NET_CORE, },
+       { },
+};
+
+static __net_init int sysctl_core_net_init(struct net *net)
+{
+       struct ctl_table *tbl, *tmp;
+
+       net->sysctl_somaxconn = SOMAXCONN;
+
+       tbl = net_core_table;
+       if (net != &init_net) {
+               tbl = kmemdup(tbl, sizeof(net_core_table), GFP_KERNEL);
+               if (tbl == NULL)
+                       goto err_dup;
+
+               for (tmp = tbl; tmp->procname; tmp++) {
+                       if (tmp->data >= (void *)&init_net &&
+                                       tmp->data < (void *)(&init_net + 1))
+                               tmp->data += (char *)net - (char *)&init_net;
+                       else
+                               tmp->mode &= ~0222;
+               }
+       }
+
+       net->sysctl_core_hdr = register_net_sysctl_table(net,
+                       net_core_path, tbl);
+       if (net->sysctl_core_hdr == NULL)
+               goto err_reg;
+
+       return 0;
+
+err_reg:
+       if (tbl != net_core_table)
+               kfree(tbl);
+err_dup:
+       return -ENOMEM;
+}
+
+static __net_exit void sysctl_core_net_exit(struct net *net)
+{
+       struct ctl_table *tbl;
+
+       tbl = net->sysctl_core_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->sysctl_core_hdr);
+       BUG_ON(tbl == net_core_table);
+       kfree(tbl);
+}
+
+static __net_initdata struct pernet_operations sysctl_core_ops = {
+       .init = sysctl_core_net_init,
+       .exit = sysctl_core_net_exit,
+};
+
+static __init int sysctl_core_init(void)
+{
+       return register_pernet_subsys(&sysctl_core_ops);
+}
+
+__initcall(sysctl_core_init);
index 0bf17da40d52e0b60158052c20783ea5f5fe24ba..8031eb59054e057f4556f0cf4f4d251020f57b0d 100644 (file)
@@ -91,17 +91,6 @@ EXPORT_SYMBOL(in_aton);
 #define IN6PTON_NULL           0x20000000      /* first/tail */
 #define IN6PTON_UNKNOWN                0x40000000
 
-static inline int digit2bin(char c, int delim)
-{
-       if (c == delim || c == '\0')
-               return IN6PTON_DELIM;
-       if (c == '.')
-               return IN6PTON_DOT;
-       if (c >= '0' && c <= '9')
-               return (IN6PTON_DIGIT | (c - '0'));
-       return IN6PTON_UNKNOWN;
-}
-
 static inline int xdigit2bin(char c, int delim)
 {
        if (c == delim || c == '\0')
@@ -293,3 +282,19 @@ out:
 }
 
 EXPORT_SYMBOL(in6_pton);
+
+void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
+                             __be32 from, __be32 to, int pseudohdr)
+{
+       __be32 diff[] = { ~from, to };
+       if (skb->ip_summed != CHECKSUM_PARTIAL) {
+               *sum = csum_fold(csum_partial(diff, sizeof(diff),
+                               ~csum_unfold(*sum)));
+               if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
+                       skb->csum = ~csum_partial(diff, sizeof(diff),
+                                               ~skb->csum);
+       } else if (pseudohdr)
+               *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
+                               csum_unfold(*sum)));
+}
+EXPORT_SYMBOL(inet_proto_csum_replace4);
index 0549e4719b1349e4eb1f4506e3dd42035c7464ae..7aa2a7acc7ec815ab34f7d35df05425bd8765e2a 100644 (file)
@@ -1,6 +1,7 @@
 menuconfig IP_DCCP
        tristate "The DCCP Protocol (EXPERIMENTAL)"
        depends on INET && EXPERIMENTAL
+       select IP_DCCP_CCID2
        ---help---
          Datagram Congestion Control Protocol (RFC 4340)
 
index 83378f379f72c129670fabf8cbe86e06626485b3..6de4bd195d280cbcd0528a04ecca215665a085f9 100644 (file)
@@ -30,7 +30,7 @@ static struct dccp_ackvec_record *dccp_ackvec_record_new(void)
                        kmem_cache_alloc(dccp_ackvec_record_slab, GFP_ATOMIC);
 
        if (avr != NULL)
-               INIT_LIST_HEAD(&avr->dccpavr_node);
+               INIT_LIST_HEAD(&avr->avr_node);
 
        return avr;
 }
@@ -40,7 +40,7 @@ static void dccp_ackvec_record_delete(struct dccp_ackvec_record *avr)
        if (unlikely(avr == NULL))
                return;
        /* Check if deleting a linked record */
-       WARN_ON(!list_empty(&avr->dccpavr_node));
+       WARN_ON(!list_empty(&avr->avr_node));
        kmem_cache_free(dccp_ackvec_record_slab, avr);
 }
 
@@ -52,16 +52,15 @@ static void dccp_ackvec_insert_avr(struct dccp_ackvec *av,
         * just add the AVR at the head of the list.
         * -sorbo.
         */
-       if (!list_empty(&av->dccpav_records)) {
+       if (!list_empty(&av->av_records)) {
                const struct dccp_ackvec_record *head =
-                                       list_entry(av->dccpav_records.next,
+                                       list_entry(av->av_records.next,
                                                   struct dccp_ackvec_record,
-                                                  dccpavr_node);
-               BUG_ON(before48(avr->dccpavr_ack_seqno,
-                               head->dccpavr_ack_seqno));
+                                                  avr_node);
+               BUG_ON(before48(avr->avr_ack_seqno, head->avr_ack_seqno));
        }
 
-       list_add(&avr->dccpavr_node, &av->dccpav_records);
+       list_add(&avr->avr_node, &av->av_records);
 }
 
 int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
@@ -69,9 +68,8 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
        struct dccp_sock *dp = dccp_sk(sk);
        struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
        /* Figure out how many options do we need to represent the ackvec */
-       const u16 nr_opts = DIV_ROUND_UP(av->dccpav_vec_len,
-                                        DCCP_MAX_ACKVEC_OPT_LEN);
-       u16 len = av->dccpav_vec_len + 2 * nr_opts, i;
+       const u16 nr_opts = DIV_ROUND_UP(av->av_vec_len, DCCP_MAX_ACKVEC_OPT_LEN);
+       u16 len = av->av_vec_len + 2 * nr_opts, i;
        u32 elapsed_time;
        const unsigned char *tail, *from;
        unsigned char *to;
@@ -81,7 +79,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
        if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
                return -1;
 
-       delta = ktime_us_delta(ktime_get_real(), av->dccpav_time);
+       delta = ktime_us_delta(ktime_get_real(), av->av_time);
        elapsed_time = delta / 10;
 
        if (elapsed_time != 0 &&
@@ -95,9 +93,9 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
        DCCP_SKB_CB(skb)->dccpd_opt_len += len;
 
        to   = skb_push(skb, len);
-       len  = av->dccpav_vec_len;
-       from = av->dccpav_buf + av->dccpav_buf_head;
-       tail = av->dccpav_buf + DCCP_MAX_ACKVEC_LEN;
+       len  = av->av_vec_len;
+       from = av->av_buf + av->av_buf_head;
+       tail = av->av_buf + DCCP_MAX_ACKVEC_LEN;
 
        for (i = 0; i < nr_opts; ++i) {
                int copylen = len;
@@ -116,7 +114,7 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
                        to      += tailsize;
                        len     -= tailsize;
                        copylen -= tailsize;
-                       from    = av->dccpav_buf;
+                       from    = av->av_buf;
                }
 
                memcpy(to, from, copylen);
@@ -134,19 +132,19 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
         *      buf_head; ack_ackno will equal buf_ackno; and ack_nonce will
         *      equal buf_nonce.
         */
-       avr->dccpavr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
-       avr->dccpavr_ack_ptr   = av->dccpav_buf_head;
-       avr->dccpavr_ack_ackno = av->dccpav_buf_ackno;
-       avr->dccpavr_ack_nonce = av->dccpav_buf_nonce;
-       avr->dccpavr_sent_len  = av->dccpav_vec_len;
+       avr->avr_ack_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
+       avr->avr_ack_ptr   = av->av_buf_head;
+       avr->avr_ack_ackno = av->av_buf_ackno;
+       avr->avr_ack_nonce = av->av_buf_nonce;
+       avr->avr_sent_len  = av->av_vec_len;
 
        dccp_ackvec_insert_avr(av, avr);
 
        dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, "
                      "ack_ackno=%llu\n",
-                     dccp_role(sk), avr->dccpavr_sent_len,
-                     (unsigned long long)avr->dccpavr_ack_seqno,
-                     (unsigned long long)avr->dccpavr_ack_ackno);
+                     dccp_role(sk), avr->avr_sent_len,
+                     (unsigned long long)avr->avr_ack_seqno,
+                     (unsigned long long)avr->avr_ack_ackno);
        return 0;
 }
 
@@ -155,12 +153,12 @@ struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
        struct dccp_ackvec *av = kmem_cache_alloc(dccp_ackvec_slab, priority);
 
        if (av != NULL) {
-               av->dccpav_buf_head     = DCCP_MAX_ACKVEC_LEN - 1;
-               av->dccpav_buf_ackno    = UINT48_MAX + 1;
-               av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0;
-               av->dccpav_time      = ktime_set(0, 0);
-               av->dccpav_vec_len      = 0;
-               INIT_LIST_HEAD(&av->dccpav_records);
+               av->av_buf_head  = DCCP_MAX_ACKVEC_LEN - 1;
+               av->av_buf_ackno = UINT48_MAX + 1;
+               av->av_buf_nonce = 0;
+               av->av_time      = ktime_set(0, 0);
+               av->av_vec_len   = 0;
+               INIT_LIST_HEAD(&av->av_records);
        }
 
        return av;
@@ -171,12 +169,11 @@ void dccp_ackvec_free(struct dccp_ackvec *av)
        if (unlikely(av == NULL))
                return;
 
-       if (!list_empty(&av->dccpav_records)) {
+       if (!list_empty(&av->av_records)) {
                struct dccp_ackvec_record *avr, *next;
 
-               list_for_each_entry_safe(avr, next, &av->dccpav_records,
-                                        dccpavr_node) {
-                       list_del_init(&avr->dccpavr_node);
+               list_for_each_entry_safe(avr, next, &av->av_records, avr_node) {
+                       list_del_init(&avr->avr_node);
                        dccp_ackvec_record_delete(avr);
                }
        }
@@ -187,13 +184,13 @@ void dccp_ackvec_free(struct dccp_ackvec *av)
 static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
                                   const u32 index)
 {
-       return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
+       return av->av_buf[index] & DCCP_ACKVEC_STATE_MASK;
 }
 
 static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
                                 const u32 index)
 {
-       return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
+       return av->av_buf[index] & DCCP_ACKVEC_LEN_MASK;
 }
 
 /*
@@ -208,29 +205,29 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
        unsigned int gap;
        long new_head;
 
-       if (av->dccpav_vec_len + packets > DCCP_MAX_ACKVEC_LEN)
+       if (av->av_vec_len + packets > DCCP_MAX_ACKVEC_LEN)
                return -ENOBUFS;
 
        gap      = packets - 1;
-       new_head = av->dccpav_buf_head - packets;
+       new_head = av->av_buf_head - packets;
 
        if (new_head < 0) {
                if (gap > 0) {
-                       memset(av->dccpav_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED,
+                       memset(av->av_buf, DCCP_ACKVEC_STATE_NOT_RECEIVED,
                               gap + new_head + 1);
                        gap = -new_head;
                }
                new_head += DCCP_MAX_ACKVEC_LEN;
        }
 
-       av->dccpav_buf_head = new_head;
+       av->av_buf_head = new_head;
 
        if (gap > 0)
-               memset(av->dccpav_buf + av->dccpav_buf_head + 1,
+               memset(av->av_buf + av->av_buf_head + 1,
                       DCCP_ACKVEC_STATE_NOT_RECEIVED, gap);
 
-       av->dccpav_buf[av->dccpav_buf_head] = state;
-       av->dccpav_vec_len += packets;
+       av->av_buf[av->av_buf_head] = state;
+       av->av_vec_len += packets;
        return 0;
 }
 
@@ -243,7 +240,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
        /*
         * Check at the right places if the buffer is full, if it is, tell the
         * caller to start dropping packets till the HC-Sender acks our ACK
-        * vectors, when we will free up space in dccpav_buf.
+        * vectors, when we will free up space in av_buf.
         *
         * We may well decide to do buffer compression, etc, but for now lets
         * just drop.
@@ -263,22 +260,20 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
         */
 
        /* See if this is the first ackno being inserted */
-       if (av->dccpav_vec_len == 0) {
-               av->dccpav_buf[av->dccpav_buf_head] = state;
-               av->dccpav_vec_len = 1;
-       } else if (after48(ackno, av->dccpav_buf_ackno)) {
-               const u64 delta = dccp_delta_seqno(av->dccpav_buf_ackno,
-                                                  ackno);
+       if (av->av_vec_len == 0) {
+               av->av_buf[av->av_buf_head] = state;
+               av->av_vec_len = 1;
+       } else if (after48(ackno, av->av_buf_ackno)) {
+               const u64 delta = dccp_delta_seqno(av->av_buf_ackno, ackno);
 
                /*
                 * Look if the state of this packet is the same as the
                 * previous ackno and if so if we can bump the head len.
                 */
                if (delta == 1 &&
-                   dccp_ackvec_state(av, av->dccpav_buf_head) == state &&
-                   (dccp_ackvec_len(av, av->dccpav_buf_head) <
-                    DCCP_ACKVEC_LEN_MASK))
-                       av->dccpav_buf[av->dccpav_buf_head]++;
+                   dccp_ackvec_state(av, av->av_buf_head) == state &&
+                   dccp_ackvec_len(av, av->av_buf_head) < DCCP_ACKVEC_LEN_MASK)
+                       av->av_buf[av->av_buf_head]++;
                else if (dccp_ackvec_set_buf_head_state(av, delta, state))
                        return -ENOBUFS;
        } else {
@@ -290,14 +285,14 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
                 *      the byte corresponding to S. (Indexing structures
                 *      could reduce the complexity of this scan.)
                 */
-               u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
-               u32 index = av->dccpav_buf_head;
+               u64 delta = dccp_delta_seqno(ackno, av->av_buf_ackno);
+               u32 index = av->av_buf_head;
 
                while (1) {
                        const u8 len = dccp_ackvec_len(av, index);
                        const u8 state = dccp_ackvec_state(av, index);
                        /*
-                        * valid packets not yet in dccpav_buf have a reserved
+                        * valid packets not yet in av_buf have a reserved
                         * entry, with a len equal to 0.
                         */
                        if (state == DCCP_ACKVEC_STATE_NOT_RECEIVED &&
@@ -305,7 +300,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
                                                         reserved seat! */
                                dccp_pr_debug("Found %llu reserved seat!\n",
                                              (unsigned long long)ackno);
-                               av->dccpav_buf[index] = state;
+                               av->av_buf[index] = state;
                                goto out;
                        }
                        /* len == 0 means one packet */
@@ -318,8 +313,8 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
                }
        }
 
-       av->dccpav_buf_ackno = ackno;
-       av->dccpav_time = ktime_get_real();
+       av->av_buf_ackno = ackno;
+       av->av_time = ktime_get_real();
 out:
        return 0;
 
@@ -349,9 +344,9 @@ void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
 
 void dccp_ackvec_print(const struct dccp_ackvec *av)
 {
-       dccp_ackvector_print(av->dccpav_buf_ackno,
-                            av->dccpav_buf + av->dccpav_buf_head,
-                            av->dccpav_vec_len);
+       dccp_ackvector_print(av->av_buf_ackno,
+                            av->av_buf + av->av_buf_head,
+                            av->av_vec_len);
 }
 #endif
 
@@ -361,17 +356,15 @@ static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
        struct dccp_ackvec_record *next;
 
        /* sort out vector length */
-       if (av->dccpav_buf_head <= avr->dccpavr_ack_ptr)
-               av->dccpav_vec_len = avr->dccpavr_ack_ptr - av->dccpav_buf_head;
+       if (av->av_buf_head <= avr->avr_ack_ptr)
+               av->av_vec_len = avr->avr_ack_ptr - av->av_buf_head;
        else
-               av->dccpav_vec_len = DCCP_MAX_ACKVEC_LEN - 1
-                                    - av->dccpav_buf_head
-                                    + avr->dccpavr_ack_ptr;
+               av->av_vec_len = DCCP_MAX_ACKVEC_LEN - 1 -
+                                av->av_buf_head + avr->avr_ack_ptr;
 
        /* free records */
-       list_for_each_entry_safe_from(avr, next, &av->dccpav_records,
-                                     dccpavr_node) {
-               list_del_init(&avr->dccpavr_node);
+       list_for_each_entry_safe_from(avr, next, &av->av_records, avr_node) {
+               list_del_init(&avr->avr_node);
                dccp_ackvec_record_delete(avr);
        }
 }
@@ -386,16 +379,16 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
         * windows. We will be receiving ACKs for stuff we sent a while back
         * -sorbo.
         */
-       list_for_each_entry_reverse(avr, &av->dccpav_records, dccpavr_node) {
-               if (ackno == avr->dccpavr_ack_seqno) {
+       list_for_each_entry_reverse(avr, &av->av_records, avr_node) {
+               if (ackno == avr->avr_ack_seqno) {
                        dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, "
                                      "ack_ackno=%llu, ACKED!\n",
                                      dccp_role(sk), 1,
-                                     (unsigned long long)avr->dccpavr_ack_seqno,
-                                     (unsigned long long)avr->dccpavr_ack_ackno);
+                                     (unsigned long long)avr->avr_ack_seqno,
+                                     (unsigned long long)avr->avr_ack_ackno);
                        dccp_ackvec_throw_record(av, avr);
                        break;
-               } else if (avr->dccpavr_ack_seqno > ackno)
+               } else if (avr->avr_ack_seqno > ackno)
                        break; /* old news */
        }
 }
@@ -409,7 +402,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
        struct dccp_ackvec_record *avr;
 
        /* Check if we actually sent an ACK vector */
-       if (list_empty(&av->dccpav_records))
+       if (list_empty(&av->av_records))
                return;
 
        i = len;
@@ -418,8 +411,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
         * I think it might be more efficient to work backwards. See comment on
         * rcv_ackno. -sorbo.
         */
-       avr = list_entry(av->dccpav_records.next, struct dccp_ackvec_record,
-                        dccpavr_node);
+       avr = list_entry(av->av_records.next, struct dccp_ackvec_record, avr_node);
        while (i--) {
                const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
                u64 ackno_end_rl;
@@ -430,15 +422,14 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
                 * If our AVR sequence number is greater than the ack, go
                 * forward in the AVR list until it is not so.
                 */
-               list_for_each_entry_from(avr, &av->dccpav_records,
-                                        dccpavr_node) {
-                       if (!after48(avr->dccpavr_ack_seqno, *ackno))
+               list_for_each_entry_from(avr, &av->av_records, avr_node) {
+                       if (!after48(avr->avr_ack_seqno, *ackno))
                                goto found;
                }
-               /* End of the dccpav_records list, not found, exit */
+               /* End of the av_records list, not found, exit */
                break;
 found:
-               if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, *ackno)) {
+               if (between48(avr->avr_ack_seqno, ackno_end_rl, *ackno)) {
                        const u8 state = *vector & DCCP_ACKVEC_STATE_MASK;
                        if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
                                dccp_pr_debug("%s ACK vector 0, len=%d, "
@@ -446,9 +437,9 @@ found:
                                              "ACKED!\n",
                                              dccp_role(sk), len,
                                              (unsigned long long)
-                                             avr->dccpavr_ack_seqno,
+                                             avr->avr_ack_seqno,
                                              (unsigned long long)
-                                             avr->dccpavr_ack_ackno);
+                                             avr->avr_ack_ackno);
                                dccp_ackvec_throw_record(av, avr);
                                break;
                        }
index 9671ecd17e00581c8fb81d222cf975ba27a70f68..bcb64fb4acefd5ef96d31637d5d5ff80b439bd87 100644 (file)
  *
  * This data structure is the one defined in RFC 4340, Appendix A.
  *
- * @dccpav_buf_head - circular buffer head
- * @dccpav_buf_tail - circular buffer tail
- * @dccpav_buf_ackno - ack # of the most recent packet acknowledgeable in the
- *                    buffer (i.e. %dccpav_buf_head)
- * @dccpav_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
+ * @av_buf_head - circular buffer head
+ * @av_buf_tail - circular buffer tail
+ * @av_buf_ackno - ack # of the most recent packet acknowledgeable in the
+ *                    buffer (i.e. %av_buf_head)
+ * @av_buf_nonce - the one-bit sum of the ECN Nonces on all packets acked
  *                    by the buffer with State 0
  *
  * Additionally, the HC-Receiver must keep some information about the
  * Ack Vectors it has recently sent. For each packet sent carrying an
  * Ack Vector, it remembers four variables:
  *
- * @dccpav_records - list of dccp_ackvec_record
- * @dccpav_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
+ * @av_records - list of dccp_ackvec_record
+ * @av_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
  *
- * @dccpav_time                - the time in usecs
- * @dccpav_buf - circular buffer of acknowledgeable packets
+ * @av_time - the time in usecs
+ * @av_buf - circular buffer of acknowledgeable packets
  */
 struct dccp_ackvec {
-       u64             dccpav_buf_ackno;
-       struct list_head dccpav_records;
-       ktime_t         dccpav_time;
-       u16             dccpav_buf_head;
-       u16             dccpav_vec_len;
-       u8              dccpav_buf_nonce;
-       u8              dccpav_ack_nonce;
-       u8              dccpav_buf[DCCP_MAX_ACKVEC_LEN];
+       u64                     av_buf_ackno;
+       struct list_head        av_records;
+       ktime_t                 av_time;
+       u16                     av_buf_head;
+       u16                     av_vec_len;
+       u8                      av_buf_nonce;
+       u8                      av_ack_nonce;
+       u8                      av_buf[DCCP_MAX_ACKVEC_LEN];
 };
 
 /** struct dccp_ackvec_record - ack vector record
  *
  * ACK vector record as defined in Appendix A of spec.
  *
- * The list is sorted by dccpavr_ack_seqno
+ * The list is sorted by avr_ack_seqno
  *
- * @dccpavr_node - node in dccpav_records
- * @dccpavr_ack_seqno - sequence number of the packet this record was sent on
- * @dccpavr_ack_ackno - sequence number being acknowledged
- * @dccpavr_ack_ptr - pointer into dccpav_buf where this record starts
- * @dccpavr_ack_nonce - dccpav_ack_nonce at the time this record was sent
- * @dccpavr_sent_len - length of the record in dccpav_buf
+ * @avr_node - node in av_records
+ * @avr_ack_seqno - sequence number of the packet this record was sent on
+ * @avr_ack_ackno - sequence number being acknowledged
+ * @avr_ack_ptr - pointer into av_buf where this record starts
+ * @avr_ack_nonce - av_ack_nonce at the time this record was sent
+ * @avr_sent_len - lenght of the record in av_buf
  */
 struct dccp_ackvec_record {
-       struct list_head dccpavr_node;
-       u64              dccpavr_ack_seqno;
-       u64              dccpavr_ack_ackno;
-       u16              dccpavr_ack_ptr;
-       u16              dccpavr_sent_len;
-       u8               dccpavr_ack_nonce;
+       struct list_head avr_node;
+       u64              avr_ack_seqno;
+       u64              avr_ack_ackno;
+       u16              avr_ack_ptr;
+       u16              avr_sent_len;
+       u8               avr_ack_nonce;
 };
 
 struct sock;
@@ -105,7 +105,7 @@ extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb);
 
 static inline int dccp_ackvec_pending(const struct dccp_ackvec *av)
 {
-       return av->dccpav_vec_len;
+       return av->av_vec_len;
 }
 #else /* CONFIG_IP_DCCP_ACKVEC */
 static inline int dccp_ackvec_init(void)
index c45088b5e6fb68f5c8a453561453061dee512d54..4809753d12aed1c4e6304f02d97e7a301fc44680 100644 (file)
@@ -92,15 +92,15 @@ int ccid_register(struct ccid_operations *ccid_ops)
 
        ccid_ops->ccid_hc_rx_slab =
                        ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
-                                              "%s_hc_rx_sock",
-                                              ccid_ops->ccid_name);
+                                              "ccid%u_hc_rx_sock",
+                                              ccid_ops->ccid_id);
        if (ccid_ops->ccid_hc_rx_slab == NULL)
                goto out;
 
        ccid_ops->ccid_hc_tx_slab =
                        ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
-                                              "%s_hc_tx_sock",
-                                              ccid_ops->ccid_name);
+                                              "ccid%u_hc_tx_sock",
+                                              ccid_ops->ccid_id);
        if (ccid_ops->ccid_hc_tx_slab == NULL)
                goto out_free_rx_slab;
 
index c65cb2453e43d7836e80ab25059d3993c5d875ce..fdeae7b5731950ed3caa776cf82a0d35f2771012 100644 (file)
 
 struct tcp_info;
 
+/**
+ *  struct ccid_operations  -  Interface to Congestion-Control Infrastructure
+ *
+ *  @ccid_id: numerical CCID ID (up to %CCID_MAX, cf. table 5 in RFC 4340, 10.)
+ *  @ccid_ccmps: the CCMPS including network/transport headers (0 when disabled)
+ *  @ccid_name: alphabetical identifier string for @ccid_id
+ *  @ccid_owner: module which implements/owns this CCID
+ *  @ccid_hc_{r,t}x_slab: memory pool for the receiver/sender half-connection
+ *  @ccid_hc_{r,t}x_obj_size: size of the receiver/sender half-connection socket
+ *
+ *  @ccid_hc_{r,t}x_init: CCID-specific initialisation routine (before startup)
+ *  @ccid_hc_{r,t}x_exit: CCID-specific cleanup routine (before destruction)
+ *  @ccid_hc_rx_packet_recv: implements the HC-receiver side
+ *  @ccid_hc_{r,t}x_parse_options: parsing routine for CCID/HC-specific options
+ *  @ccid_hc_{r,t}x_insert_options: insert routine for CCID/HC-specific options
+ *  @ccid_hc_tx_packet_recv: implements feedback processing for the HC-sender
+ *  @ccid_hc_tx_send_packet: implements the sending part of the HC-sender
+ *  @ccid_hc_tx_packet_sent: does accounting for packets in flight by HC-sender
+ *  @ccid_hc_{r,t}x_get_info: INET_DIAG information for HC-receiver/sender
+ *  @ccid_hc_{r,t}x_getsockopt: socket options specific to HC-receiver/sender
+ */
 struct ccid_operations {
-       unsigned char   ccid_id;
-       const char      *ccid_name;
-       struct module   *ccid_owner;
-       struct kmem_cache       *ccid_hc_rx_slab;
-       __u32           ccid_hc_rx_obj_size;
-       struct kmem_cache       *ccid_hc_tx_slab;
-       __u32           ccid_hc_tx_obj_size;
+       unsigned char           ccid_id;
+       __u32                   ccid_ccmps;
+       const char              *ccid_name;
+       struct module           *ccid_owner;
+       struct kmem_cache       *ccid_hc_rx_slab,
+                               *ccid_hc_tx_slab;
+       __u32                   ccid_hc_rx_obj_size,
+                               ccid_hc_tx_obj_size;
+       /* Interface Routines */
        int             (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk);
        int             (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk);
        void            (*ccid_hc_rx_exit)(struct sock *sk);
index 80f469887691859cb227b49907f2b4f99ab96c93..12275943eab8fae852664b3adba29ecb54415f24 100644 (file)
@@ -1,9 +1,8 @@
 menu "DCCP CCIDs Configuration (EXPERIMENTAL)"
-       depends on IP_DCCP && EXPERIMENTAL
+       depends on EXPERIMENTAL
 
 config IP_DCCP_CCID2
        tristate "CCID2 (TCP-Like) (EXPERIMENTAL)"
-       depends on IP_DCCP
        def_tristate IP_DCCP
        select IP_DCCP_ACKVEC
        ---help---
@@ -20,18 +19,9 @@ config IP_DCCP_CCID2
          to the user.  For example, a hypothetical application that
          transferred files over DCCP, using application-level retransmissions
          for lost packets, would prefer CCID 2 to CCID 3.  On-line games may
-         also prefer CCID 2.
+         also prefer CCID 2.  See RFC 4341 for further details.
 
-         CCID 2 is further described in RFC 4341,
-         http://www.ietf.org/rfc/rfc4341.txt
-
-         This text was extracted from RFC 4340 (sec. 10.1),
-         http://www.ietf.org/rfc/rfc4340.txt
-
-         To compile this CCID as a module, choose M here: the module will be
-         called dccp_ccid2.
-
-         If in doubt, say M.
+         CCID2 is the default CCID used by DCCP.
 
 config IP_DCCP_CCID2_DEBUG
          bool "CCID2 debugging messages"
@@ -47,8 +37,8 @@ config IP_DCCP_CCID2_DEBUG
 
 config IP_DCCP_CCID3
        tristate "CCID3 (TCP-Friendly) (EXPERIMENTAL)"
-       depends on IP_DCCP
        def_tristate IP_DCCP
+       select IP_DCCP_TFRC_LIB
        ---help---
          CCID 3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
          rate-controlled congestion control mechanism.  TFRC is designed to
@@ -74,10 +64,6 @@ config IP_DCCP_CCID3
 
          If in doubt, say M.
 
-config IP_DCCP_TFRC_LIB
-       depends on IP_DCCP_CCID3
-       def_tristate IP_DCCP_CCID3
-
 config IP_DCCP_CCID3_DEBUG
          bool "CCID3 debugging messages"
          depends on IP_DCCP_CCID3
@@ -121,5 +107,13 @@ config IP_DCCP_CCID3_RTO
            is serious network congestion: experimenting with larger values should
            therefore not be performed on WANs.
 
+config IP_DCCP_TFRC_LIB
+       tristate
+       default n
+
+config IP_DCCP_TFRC_DEBUG
+       bool
+       depends on IP_DCCP_TFRC_LIB
+       default y if IP_DCCP_CCID3_DEBUG
 
 endmenu
index d694656b8800ec451156bf232f55e87a38f0aa00..b5b52ebb2693d308d46deee5e6c5f6a5e27d7199 100644 (file)
@@ -24,9 +24,6 @@
 
 /*
  * This implementation should follow RFC 4341
- *
- * BUGS:
- * - sequence number wrapping
  */
 
 #include "../ccid.h"
@@ -129,50 +126,35 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 {
        struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
 
-       ccid2_pr_debug("pipe=%d cwnd=%d\n", hctx->ccid2hctx_pipe,
-                      hctx->ccid2hctx_cwnd);
-
-       if (hctx->ccid2hctx_pipe < hctx->ccid2hctx_cwnd) {
-               /* OK we can send... make sure previous packet was sent off */
-               if (!hctx->ccid2hctx_sendwait) {
-                       hctx->ccid2hctx_sendwait = 1;
-                       return 0;
-               }
-       }
+       if (hctx->ccid2hctx_pipe < hctx->ccid2hctx_cwnd)
+               return 0;
 
        return 1; /* XXX CCID should dequeue when ready instead of polling */
 }
 
-static void ccid2_change_l_ack_ratio(struct sock *sk, int val)
+static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
 {
        struct dccp_sock *dp = dccp_sk(sk);
+       u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->ccid2hctx_cwnd, 2);
+
        /*
-        * XXX I don't really agree with val != 2.  If cwnd is 1, ack ratio
-        * should be 1... it shouldn't be allowed to become 2.
-        * -sorbo.
+        * Ensure that Ack Ratio does not exceed ceil(cwnd/2), which is (2) from
+        * RFC 4341, 6.1.2. We ignore the statement that Ack Ratio 2 is always
+        * acceptable since this causes starvation/deadlock whenever cwnd < 2.
+        * The same problem arises when Ack Ratio is 0 (ie. Ack Ratio disabled).
         */
-       if (val != 2) {
-               const struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
-               int max = hctx->ccid2hctx_cwnd / 2;
-
-               /* round up */
-               if (hctx->ccid2hctx_cwnd & 1)
-                       max++;
-
-               if (val > max)
-                       val = max;
+       if (val == 0 || val > max_ratio) {
+               DCCP_WARN("Limiting Ack Ratio (%u) to %u\n", val, max_ratio);
+               val = max_ratio;
        }
+       if (val > 0xFFFF)               /* RFC 4340, 11.3 */
+               val = 0xFFFF;
 
-       ccid2_pr_debug("changing local ack ratio to %d\n", val);
-       WARN_ON(val <= 0);
-       dp->dccps_l_ack_ratio = val;
-}
+       if (val == dp->dccps_l_ack_ratio)
+               return;
 
-static void ccid2_change_cwnd(struct ccid2_hc_tx_sock *hctx, u32 val)
-{
-       /* XXX do we need to change ack ratio? */
-       hctx->ccid2hctx_cwnd = val? : 1;
-       ccid2_pr_debug("changed cwnd to %u\n", hctx->ccid2hctx_cwnd);
+       ccid2_pr_debug("changing local ack ratio to %u\n", val);
+       dp->dccps_l_ack_ratio = val;
 }
 
 static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
@@ -181,11 +163,6 @@ static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
        hctx->ccid2hctx_srtt = val;
 }
 
-static void ccid2_change_pipe(struct ccid2_hc_tx_sock *hctx, long val)
-{
-       hctx->ccid2hctx_pipe = val;
-}
-
 static void ccid2_start_rto_timer(struct sock *sk);
 
 static void ccid2_hc_tx_rto_expire(unsigned long data)
@@ -215,21 +192,17 @@ static void ccid2_hc_tx_rto_expire(unsigned long data)
        ccid2_start_rto_timer(sk);
 
        /* adjust pipe, cwnd etc */
-       ccid2_change_pipe(hctx, 0);
-       hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd >> 1;
+       hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd / 2;
        if (hctx->ccid2hctx_ssthresh < 2)
                hctx->ccid2hctx_ssthresh = 2;
-       ccid2_change_cwnd(hctx, 1);
+       hctx->ccid2hctx_cwnd     = 1;
+       hctx->ccid2hctx_pipe     = 0;
 
        /* clear state about stuff we sent */
-       hctx->ccid2hctx_seqt    = hctx->ccid2hctx_seqh;
-       hctx->ccid2hctx_ssacks  = 0;
-       hctx->ccid2hctx_acks    = 0;
-       hctx->ccid2hctx_sent    = 0;
+       hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh;
+       hctx->ccid2hctx_packets_acked = 0;
 
        /* clear ack ratio state. */
-       hctx->ccid2hctx_arsent   = 0;
-       hctx->ccid2hctx_ackloss  = 0;
        hctx->ccid2hctx_rpseq    = 0;
        hctx->ccid2hctx_rpdupack = -1;
        ccid2_change_l_ack_ratio(sk, 1);
@@ -255,23 +228,10 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
        struct dccp_sock *dp = dccp_sk(sk);
        struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
        struct ccid2_seq *next;
-       u64 seq;
-
-       ccid2_hc_tx_check_sanity(hctx);
 
-       BUG_ON(!hctx->ccid2hctx_sendwait);
-       hctx->ccid2hctx_sendwait = 0;
-       ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe + 1);
-       BUG_ON(hctx->ccid2hctx_pipe < 0);
+       hctx->ccid2hctx_pipe++;
 
-       /* There is an issue.  What if another packet is sent between
-        * packet_send() and packet_sent().  Then the sequence number would be
-        * wrong.
-        * -sorbo.
-        */
-       seq = dp->dccps_gss;
-
-       hctx->ccid2hctx_seqh->ccid2s_seq   = seq;
+       hctx->ccid2hctx_seqh->ccid2s_seq   = dp->dccps_gss;
        hctx->ccid2hctx_seqh->ccid2s_acked = 0;
        hctx->ccid2hctx_seqh->ccid2s_sent  = jiffies;
 
@@ -291,8 +251,26 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
        ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd,
                       hctx->ccid2hctx_pipe);
 
-       hctx->ccid2hctx_sent++;
-
+       /*
+        * FIXME: The code below is broken and the variables have been removed
+        * from the socket struct. The `ackloss' variable was always set to 0,
+        * and with arsent there are several problems:
+        *  (i) it doesn't just count the number of Acks, but all sent packets;
+        *  (ii) it is expressed in # of packets, not # of windows, so the
+        *  comparison below uses the wrong formula: Appendix A of RFC 4341
+        *  comes up with the number K = cwnd / (R^2 - R) of consecutive windows
+        *  of data with no lost or marked Ack packets. If arsent were the # of
+        *  consecutive Acks received without loss, then Ack Ratio needs to be
+        *  decreased by 1 when
+        *            arsent >=  K * cwnd / R  =  cwnd^2 / (R^3 - R^2)
+        *  where cwnd / R is the number of Acks received per window of data
+        *  (cf. RFC 4341, App. A). The problems are that
+        *  - arsent counts other packets as well;
+        *  - the comparison uses a formula different from RFC 4341;
+        *  - computing a cubic/quadratic equation each time is too complicated.
+        *  Hence a different algorithm is needed.
+        */
+#if 0
        /* Ack Ratio.  Need to maintain a concept of how many windows we sent */
        hctx->ccid2hctx_arsent++;
        /* We had an ack loss in this window... */
@@ -320,14 +298,13 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
                        hctx->ccid2hctx_arsent = 0; /* or maybe set it to cwnd*/
                }
        }
+#endif
 
        /* setup RTO timer */
        if (!timer_pending(&hctx->ccid2hctx_rtotimer))
                ccid2_start_rto_timer(sk);
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
-       ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
-       ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq);
        do {
                struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
 
@@ -419,31 +396,15 @@ static inline void ccid2_new_ack(struct sock *sk,
 {
        struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
 
-       /* slow start */
        if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh) {
-               hctx->ccid2hctx_acks = 0;
-
-               /* We can increase cwnd at most maxincr [ack_ratio/2] */
-               if (*maxincr) {
-                       /* increase every 2 acks */
-                       hctx->ccid2hctx_ssacks++;
-                       if (hctx->ccid2hctx_ssacks == 2) {
-                               ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd+1);
-                               hctx->ccid2hctx_ssacks = 0;
-                               *maxincr = *maxincr - 1;
-                       }
-               } else {
-                       /* increased cwnd enough for this single ack */
-                       hctx->ccid2hctx_ssacks = 0;
-               }
-       } else {
-               hctx->ccid2hctx_ssacks = 0;
-               hctx->ccid2hctx_acks++;
-
-               if (hctx->ccid2hctx_acks >= hctx->ccid2hctx_cwnd) {
-                       ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd + 1);
-                       hctx->ccid2hctx_acks = 0;
+               if (*maxincr > 0 && ++hctx->ccid2hctx_packets_acked == 2) {
+                       hctx->ccid2hctx_cwnd += 1;
+                       *maxincr             -= 1;
+                       hctx->ccid2hctx_packets_acked = 0;
                }
+       } else if (++hctx->ccid2hctx_packets_acked >= hctx->ccid2hctx_cwnd) {
+                       hctx->ccid2hctx_cwnd += 1;
+                       hctx->ccid2hctx_packets_acked = 0;
        }
 
        /* update RTO */
@@ -502,7 +463,6 @@ static inline void ccid2_new_ack(struct sock *sk,
                ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
                               hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,
                               hctx->ccid2hctx_rto, HZ, r);
-               hctx->ccid2hctx_sent = 0;
        }
 
        /* we got a new ack, so re-start RTO timer */
@@ -514,16 +474,19 @@ static void ccid2_hc_tx_dec_pipe(struct sock *sk)
 {
        struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
 
-       ccid2_change_pipe(hctx, hctx->ccid2hctx_pipe-1);
-       BUG_ON(hctx->ccid2hctx_pipe < 0);
+       if (hctx->ccid2hctx_pipe == 0)
+               DCCP_BUG("pipe == 0");
+       else
+               hctx->ccid2hctx_pipe--;
 
        if (hctx->ccid2hctx_pipe == 0)
                ccid2_hc_tx_kill_rto_timer(sk);
 }
 
-static void ccid2_congestion_event(struct ccid2_hc_tx_sock *hctx,
-                                  struct ccid2_seq *seqp)
+static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
 {
+       struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
+
        if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) {
                ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
                return;
@@ -531,10 +494,12 @@ static void ccid2_congestion_event(struct ccid2_hc_tx_sock *hctx,
 
        hctx->ccid2hctx_last_cong = jiffies;
 
-       ccid2_change_cwnd(hctx, hctx->ccid2hctx_cwnd >> 1);
-       hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd;
-       if (hctx->ccid2hctx_ssthresh < 2)
-               hctx->ccid2hctx_ssthresh = 2;
+       hctx->ccid2hctx_cwnd     = hctx->ccid2hctx_cwnd / 2 ? : 1U;
+       hctx->ccid2hctx_ssthresh = max(hctx->ccid2hctx_cwnd, 2U);
+
+       /* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
+       if (dccp_sk(sk)->dccps_l_ack_ratio > hctx->ccid2hctx_cwnd)
+               ccid2_change_l_ack_ratio(sk, hctx->ccid2hctx_cwnd);
 }
 
 static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -570,12 +535,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                        hctx->ccid2hctx_rpdupack++;
 
                        /* check if we got enough dupacks */
-                       if (hctx->ccid2hctx_rpdupack >=
-                           hctx->ccid2hctx_numdupack) {
+                       if (hctx->ccid2hctx_rpdupack >= NUMDUPACK) {
                                hctx->ccid2hctx_rpdupack = -1; /* XXX lame */
                                hctx->ccid2hctx_rpseq = 0;
 
-                               ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio << 1);
+                               ccid2_change_l_ack_ratio(sk, 2 * dp->dccps_l_ack_ratio);
                        }
                }
        }
@@ -606,12 +570,13 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                }
        }
 
-       /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for
-        * this single ack.  I round up.
-        * -sorbo.
+       /*
+        * In slow-start, cwnd can increase up to a maximum of Ack Ratio/2
+        * packets per acknowledgement. Rounding up avoids that cwnd is not
+        * advanced when Ack Ratio is 1 and gives a slight edge otherwise.
         */
-       maxincr = dp->dccps_l_ack_ratio >> 1;
-       maxincr++;
+       if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh)
+               maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2);
 
        /* go through all ack vectors */
        while ((offset = ccid2_ackvector(sk, skb, offset,
@@ -619,9 +584,8 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                /* go through this ack vector */
                while (veclen--) {
                        const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
-                       u64 ackno_end_rl;
+                       u64 ackno_end_rl = SUB48(ackno, rl);
 
-                       dccp_set_seqno(&ackno_end_rl, ackno - rl);
                        ccid2_pr_debug("ackvec start:%llu end:%llu\n",
                                       (unsigned long long)ackno,
                                       (unsigned long long)ackno_end_rl);
@@ -651,7 +615,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                                    !seqp->ccid2s_acked) {
                                        if (state ==
                                            DCCP_ACKVEC_STATE_ECN_MARKED) {
-                                               ccid2_congestion_event(hctx,
+                                               ccid2_congestion_event(sk,
                                                                       seqp);
                                        } else
                                                ccid2_new_ack(sk, seqp,
@@ -666,13 +630,12 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                                        done = 1;
                                        break;
                                }
-                               seqp = seqp->ccid2s_next;
+                               seqp = seqp->ccid2s_prev;
                        }
                        if (done)
                                break;
 
-
-                       dccp_set_seqno(&ackno, ackno_end_rl - 1);
+                       ackno = SUB48(ackno_end_rl, 1);
                        vector++;
                }
                if (done)
@@ -694,7 +657,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
        while (1) {
                if (seqp->ccid2s_acked) {
                        done++;
-                       if (done == hctx->ccid2hctx_numdupack)
+                       if (done == NUMDUPACK)
                                break;
                }
                if (seqp == hctx->ccid2hctx_seqt)
@@ -705,7 +668,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
        /* If there are at least 3 acknowledgements, anything unacknowledged
         * below the last sequence number is considered lost
         */
-       if (done == hctx->ccid2hctx_numdupack) {
+       if (done == NUMDUPACK) {
                struct ccid2_seq *last_acked = seqp;
 
                /* check for lost packets */
@@ -717,7 +680,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                                 * order to detect multiple congestion events in
                                 * one ack vector.
                                 */
-                               ccid2_congestion_event(hctx, seqp);
+                               ccid2_congestion_event(sk, seqp);
                                ccid2_hc_tx_dec_pipe(sk);
                        }
                        if (seqp == hctx->ccid2hctx_seqt)
@@ -742,14 +705,23 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
 {
        struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
+       struct dccp_sock *dp = dccp_sk(sk);
+       u32 max_ratio;
+
+       /* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */
+       hctx->ccid2hctx_ssthresh  = ~0U;
 
-       ccid2_change_cwnd(hctx, 1);
-       /* Initialize ssthresh to infinity.  This means that we will exit the
-        * initial slow-start after the first packet loss.  This is what we
-        * want.
+       /*
+        * RFC 4341, 5: "The cwnd parameter is initialized to at most four
+        * packets for new connections, following the rules from [RFC3390]".
+        * We need to convert the bytes of RFC3390 into the packets of RFC 4341.
         */
-       hctx->ccid2hctx_ssthresh  = ~0;
-       hctx->ccid2hctx_numdupack = 3;
+       hctx->ccid2hctx_cwnd = min(4U, max(2U, 4380U / dp->dccps_mss_cache));
+
+       /* Make sure that Ack Ratio is enabled and within bounds. */
+       max_ratio = DIV_ROUND_UP(hctx->ccid2hctx_cwnd, 2);
+       if (dp->dccps_l_ack_ratio == 0 || dp->dccps_l_ack_ratio > max_ratio)
+               dp->dccps_l_ack_ratio = max_ratio;
 
        /* XXX init ~ to window size... */
        if (ccid2_hc_tx_alloc_seq(hctx))
@@ -760,10 +732,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
        hctx->ccid2hctx_rttvar   = -1;
        hctx->ccid2hctx_rpdupack = -1;
        hctx->ccid2hctx_last_cong = jiffies;
-
-       hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
-       hctx->ccid2hctx_rtotimer.data     = (unsigned long)sk;
-       init_timer(&hctx->ccid2hctx_rtotimer);
+       setup_timer(&hctx->ccid2hctx_rtotimer, ccid2_hc_tx_rto_expire,
+                       (unsigned long)sk);
 
        ccid2_hc_tx_check_sanity(hctx);
        return 0;
@@ -800,7 +770,7 @@ static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 
 static struct ccid_operations ccid2 = {
        .ccid_id                = DCCPC_CCID2,
-       .ccid_name              = "ccid2",
+       .ccid_name              = "TCP-like",
        .ccid_owner             = THIS_MODULE,
        .ccid_hc_tx_obj_size    = sizeof(struct ccid2_hc_tx_sock),
        .ccid_hc_tx_init        = ccid2_hc_tx_init,
index d9daa534c9bef108d1435d53b49d16b2975cbda9..2c94ca0290107b1d464cb9938101969d4b135763 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/timer.h>
 #include <linux/types.h>
 #include "../ccid.h"
+/* NUMDUPACK parameter from RFC 4341, p. 6 */
+#define NUMDUPACK      3
 
 struct sock;
 
@@ -40,22 +42,17 @@ struct ccid2_seq {
 
 /** struct ccid2_hc_tx_sock - CCID2 TX half connection
  *
- * @ccid2hctx_ssacks - ACKs recv in slow start
- * @ccid2hctx_acks - ACKS recv in AI phase
- * @ccid2hctx_sent - packets sent in this window
+ * @ccid2hctx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
+ * @ccid2hctx_packets_acked - Ack counter for deriving cwnd growth (RFC 3465)
  * @ccid2hctx_lastrtt -time RTT was last measured
- * @ccid2hctx_arsent - packets sent [ack ratio]
- * @ccid2hctx_ackloss - ack was lost in this win
  * @ccid2hctx_rpseq - last consecutive seqno
  * @ccid2hctx_rpdupack - dupacks since rpseq
 */
 struct ccid2_hc_tx_sock {
        u32                     ccid2hctx_cwnd;
-       int                     ccid2hctx_ssacks;
-       int                     ccid2hctx_acks;
-       unsigned int            ccid2hctx_ssthresh;
-       int                     ccid2hctx_pipe;
-       int                     ccid2hctx_numdupack;
+       u32                     ccid2hctx_ssthresh;
+       u32                     ccid2hctx_pipe;
+       u32                     ccid2hctx_packets_acked;
        struct ccid2_seq        *ccid2hctx_seqbuf[CCID2_SEQBUF_MAX];
        int                     ccid2hctx_seqbufc;
        struct ccid2_seq        *ccid2hctx_seqh;
@@ -63,14 +60,10 @@ struct ccid2_hc_tx_sock {
        long                    ccid2hctx_rto;
        long                    ccid2hctx_srtt;
        long                    ccid2hctx_rttvar;
-       int                     ccid2hctx_sent;
        unsigned long           ccid2hctx_lastrtt;
        struct timer_list       ccid2hctx_rtotimer;
-       unsigned long           ccid2hctx_arsent;
-       int                     ccid2hctx_ackloss;
        u64                     ccid2hctx_rpseq;
        int                     ccid2hctx_rpdupack;
-       int                     ccid2hctx_sendwait;
        unsigned long           ccid2hctx_last_cong;
        u64                     ccid2hctx_high_ack;
 };
index d133416d3970f2d8b74e9ea2abdfeccbb8b99d3a..e76f460af0ea03a2c634d9e18137789ece6fd047 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  net/dccp/ccids/ccid3.c
  *
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include "../ccid.h"
 #include "../dccp.h"
-#include "lib/packet_history.h"
-#include "lib/loss_interval.h"
-#include "lib/tfrc.h"
 #include "ccid3.h"
 
 #include <asm/unaligned.h>
@@ -49,9 +46,6 @@ static int ccid3_debug;
 #define ccid3_pr_debug(format, a...)
 #endif
 
-static struct dccp_tx_hist *ccid3_tx_hist;
-static struct dccp_rx_hist *ccid3_rx_hist;
-
 /*
  *     Transmitter Half-Connection Routines
  */
@@ -83,24 +77,27 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
 }
 
 /*
- * Compute the initial sending rate X_init according to RFC 3390:
- *     w_init   =    min(4 * MSS, max(2 * MSS, 4380 bytes))
- *     X_init   =    w_init / RTT
+ * Compute the initial sending rate X_init in the manner of RFC 3390:
+ *
+ *     X_init  =  min(4 * s, max(2 * s, 4380 bytes)) / RTT
+ *
+ * Note that RFC 3390 uses MSS, RFC 4342 refers to RFC 3390, and rfc3448bis
+ * (rev-02) clarifies the use of RFC 3390 with regard to the above formula.
  * For consistency with other parts of the code, X_init is scaled by 2^6.
  */
 static inline u64 rfc3390_initial_rate(struct sock *sk)
 {
-       const struct dccp_sock *dp = dccp_sk(sk);
-       const __u32 w_init = min(4 * dp->dccps_mss_cache,
-                                max(2 * dp->dccps_mss_cache, 4380U));
+       const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
+       const __u32 w_init = min_t(__u32, 4 * hctx->ccid3hctx_s,
+                                  max_t(__u32, 2 * hctx->ccid3hctx_s, 4380));
 
-       return scaled_div(w_init << 6, ccid3_hc_tx_sk(sk)->ccid3hctx_rtt);
+       return scaled_div(w_init << 6, hctx->ccid3hctx_rtt);
 }
 
 /*
  * Recalculate t_ipi and delta (should be called whenever X changes)
  */
-static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
+static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
 {
        /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
        hctx->ccid3hctx_t_ipi = scaled_div32(((u64)hctx->ccid3hctx_s) << 6,
@@ -116,6 +113,13 @@ static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
 
 }
 
+static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
+{
+       u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
+
+       return delta / hctx->ccid3hctx_rtt;
+}
+
 /**
  * ccid3_hc_tx_update_x  -  Update allowed sending rate X
  * @stamp: most recent time if available - can be left NULL.
@@ -127,19 +131,19 @@ static inline void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
  *
  */
 static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
-
 {
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
        __u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
        const  __u64 old_x = hctx->ccid3hctx_x;
-       ktime_t now = stamp? *stamp : ktime_get_real();
+       ktime_t now = stamp ? *stamp : ktime_get_real();
 
        /*
         * Handle IDLE periods: do not reduce below RFC3390 initial sending rate
-        * when idling [RFC 4342, 5.1]. See also draft-ietf-dccp-rfc3448bis.
+        * when idling [RFC 4342, 5.1]. Definition of idling is from rfc3448bis:
+        * a sender is idle if it has not sent anything over a 2-RTT-period.
         * For consistency with X and X_recv, min_rate is also scaled by 2^6.
         */
-       if (unlikely(hctx->ccid3hctx_idle)) {
+       if (ccid3_hc_tx_idle_rtt(hctx, now) >= 2) {
                min_rate = rfc3390_initial_rate(sk);
                min_rate = max(min_rate, 2 * hctx->ccid3hctx_x_recv);
        }
@@ -181,7 +185,7 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
 {
        const u16 old_s = hctx->ccid3hctx_s;
 
-       hctx->ccid3hctx_s = old_s == 0 ? len : (9 * old_s + len) / 10;
+       hctx->ccid3hctx_s = tfrc_ewma(hctx->ccid3hctx_s, len, 9);
 
        if (hctx->ccid3hctx_s != old_s)
                ccid3_update_send_interval(hctx);
@@ -225,29 +229,27 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
        ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
                       ccid3_tx_state_name(hctx->ccid3hctx_state));
 
-       hctx->ccid3hctx_idle = 1;
+       if (hctx->ccid3hctx_state == TFRC_SSTATE_FBACK)
+               ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
+       else if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
+               goto out;
 
-       switch (hctx->ccid3hctx_state) {
-       case TFRC_SSTATE_NO_FBACK:
-               /* RFC 3448, 4.4: Halve send rate directly */
+       /*
+        * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
+        */
+       if (hctx->ccid3hctx_t_rto == 0 ||       /* no feedback received yet */
+           hctx->ccid3hctx_p == 0) {
+
+               /* halve send rate directly */
                hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
                                        (((__u64)hctx->ccid3hctx_s) << 6) /
                                                                    TFRC_T_MBI);
-
-               ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
-                              "bytes/s\n", dccp_role(sk), sk,
-                              ccid3_tx_state_name(hctx->ccid3hctx_state),
-                              (unsigned)(hctx->ccid3hctx_x >> 6));
-               /* The value of R is still undefined and so we can not recompute
-                * the timeout value. Keep initial value as per [RFC 4342, 5]. */
-               t_nfb = TFRC_INITIAL_TIMEOUT;
                ccid3_update_send_interval(hctx);
-               break;
-       case TFRC_SSTATE_FBACK:
+       } else {
                /*
-                *  Modify the cached value of X_recv [RFC 3448, 4.4]
+                *  Modify the cached value of X_recv
                 *
-                *  If (p == 0 || X_calc > 2 * X_recv)
+                *  If (X_calc > 2 * X_recv)
                 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
                 *  Else
                 *    X_recv = X_calc / 4;
@@ -256,32 +258,28 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
                 */
                BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
 
-               if (hctx->ccid3hctx_p == 0 ||
-                   (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))) {
-
+               if (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))
                        hctx->ccid3hctx_x_recv =
                                max(hctx->ccid3hctx_x_recv / 2,
                                    (((__u64)hctx->ccid3hctx_s) << 6) /
                                                              (2 * TFRC_T_MBI));
-               else {
+               else {
                        hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
                        hctx->ccid3hctx_x_recv <<= 4;
                }
-               /* Now recalculate X [RFC 3448, 4.3, step (4)] */
                ccid3_hc_tx_update_x(sk, NULL);
-               /*
-                * Schedule no feedback timer to expire in
-                * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
-                * See comments in packet_recv() regarding the value of t_RTO.
-                */
-               t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
-               break;
-       case TFRC_SSTATE_NO_SENT:
-               DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
-               /* fall through */
-       case TFRC_SSTATE_TERM:
-               goto out;
        }
+       ccid3_pr_debug("Reduced X to %llu/64 bytes/sec\n",
+                       (unsigned long long)hctx->ccid3hctx_x);
+
+       /*
+        * Set new timeout for the nofeedback timer.
+        * See comments in packet_recv() regarding the value of t_RTO.
+        */
+       if (unlikely(hctx->ccid3hctx_t_rto == 0))       /* no feedback yet */
+               t_nfb = TFRC_INITIAL_TIMEOUT;
+       else
+               t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
 
 restart_timer:
        sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
@@ -336,8 +334,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
                        hctx->ccid3hctx_x    = rfc3390_initial_rate(sk);
                        hctx->ccid3hctx_t_ld = now;
                } else {
-                       /* Sender does not have RTT sample: X = MSS/second */
-                       hctx->ccid3hctx_x = dp->dccps_mss_cache;
+                       /* Sender does not have RTT sample: X_pps = 1 pkt/sec */
+                       hctx->ccid3hctx_x = hctx->ccid3hctx_s;
                        hctx->ccid3hctx_x <<= 6;
                }
                ccid3_update_send_interval(hctx);
@@ -369,7 +367,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
        /* prepare to send now (add options etc.) */
        dp->dccps_hc_tx_insert_options = 1;
        DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
-       hctx->ccid3hctx_idle = 0;
 
        /* set the nominal send time for the next following packet */
        hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
@@ -381,28 +378,17 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
                                    unsigned int len)
 {
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
-       struct dccp_tx_hist_entry *packet;
 
        ccid3_hc_tx_update_s(hctx, len);
 
-       packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC);
-       if (unlikely(packet == NULL)) {
+       if (tfrc_tx_hist_add(&hctx->ccid3hctx_hist, dccp_sk(sk)->dccps_gss))
                DCCP_CRIT("packet history - out of memory!");
-               return;
-       }
-       dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet);
-
-       packet->dccphtx_tstamp = ktime_get_real();
-       packet->dccphtx_seqno  = dccp_sk(sk)->dccps_gss;
-       packet->dccphtx_rtt    = hctx->ccid3hctx_rtt;
-       packet->dccphtx_sent   = 1;
 }
 
 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
        struct ccid3_options_received *opt_recv;
-       struct dccp_tx_hist_entry *packet;
        ktime_t now;
        unsigned long t_nfb;
        u32 pinv, r_sample;
@@ -411,131 +397,112 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
        if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
              DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
                return;
+       /* ... and only in the established state */
+       if (hctx->ccid3hctx_state != TFRC_SSTATE_FBACK &&
+           hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
+               return;
 
        opt_recv = &hctx->ccid3hctx_options_received;
+       now = ktime_get_real();
 
-       switch (hctx->ccid3hctx_state) {
-       case TFRC_SSTATE_NO_FBACK:
-       case TFRC_SSTATE_FBACK:
-               /* get packet from history to look up t_recvdata */
-               packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
-                                             DCCP_SKB_CB(skb)->dccpd_ack_seq);
-               if (unlikely(packet == NULL)) {
-                       DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist "
-                                 "in history!\n",  dccp_role(sk), sk,
-                           (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
-                               dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
-                       return;
-               }
-
-               /* Update receive rate in units of 64 * bytes/second */
-               hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
-               hctx->ccid3hctx_x_recv <<= 6;
+       /* Estimate RTT from history if ACK number is valid */
+       r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist,
+                                   DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
+       if (r_sample == 0) {
+               DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
+                         dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type),
+                         (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq);
+               return;
+       }
 
-               /* Update loss event rate */
-               pinv = opt_recv->ccid3or_loss_event_rate;
-               if (pinv == ~0U || pinv == 0)          /* see RFC 4342, 8.5   */
-                       hctx->ccid3hctx_p = 0;
-               else                                   /* can not exceed 100% */
-                       hctx->ccid3hctx_p = 1000000 / pinv;
+       /* Update receive rate in units of 64 * bytes/second */
+       hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
+       hctx->ccid3hctx_x_recv <<= 6;
 
-               now = ktime_get_real();
-               /*
-                * Calculate new round trip sample as per [RFC 3448, 4.3] by
-                *      R_sample  =  (now - t_recvdata) - t_elapsed
-                */
-               r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, packet->dccphtx_tstamp));
+       /* Update loss event rate (which is scaled by 1e6) */
+       pinv = opt_recv->ccid3or_loss_event_rate;
+       if (pinv == ~0U || pinv == 0)          /* see RFC 4342, 8.5   */
+               hctx->ccid3hctx_p = 0;
+       else                                   /* can not exceed 100% */
+               hctx->ccid3hctx_p = scaled_div(1, pinv);
+       /*
+        * Validate new RTT sample and update moving average
+        */
+       r_sample = dccp_sample_rtt(sk, r_sample);
+       hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
+       /*
+        * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
+        */
+       if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
+               ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
 
-               /*
-                * Update RTT estimate by
-                * If (No feedback recv)
-                *    R = R_sample;
-                * Else
-                *    R = q * R + (1 - q) * R_sample;
-                *
-                * q is a constant, RFC 3448 recomments 0.9
-                */
-               if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
+               if (hctx->ccid3hctx_t_rto == 0) {
                        /*
-                        * Larger Initial Windows [RFC 4342, sec. 5]
+                        * Initial feedback packet: Larger Initial Windows (4.2)
                         */
-                       hctx->ccid3hctx_rtt  = r_sample;
                        hctx->ccid3hctx_x    = rfc3390_initial_rate(sk);
                        hctx->ccid3hctx_t_ld = now;
 
                        ccid3_update_send_interval(hctx);
 
-                       ccid3_pr_debug("%s(%p), s=%u, MSS=%u, "
-                                      "R_sample=%uus, X=%u\n", dccp_role(sk),
-                                      sk, hctx->ccid3hctx_s,
-                                      dccp_sk(sk)->dccps_mss_cache, r_sample,
-                                      (unsigned)(hctx->ccid3hctx_x >> 6));
-
-                       ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
-               } else {
-                       hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
-                                                  r_sample) / 10;
-
-                       /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
-                       if (hctx->ccid3hctx_p > 0)
-                               hctx->ccid3hctx_x_calc =
-                                       tfrc_calc_x(hctx->ccid3hctx_s,
-                                                   hctx->ccid3hctx_rtt,
-                                                   hctx->ccid3hctx_p);
-                       ccid3_hc_tx_update_x(sk, &now);
-
-                       ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
-                                      "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
-                                      dccp_role(sk),
-                                      sk, hctx->ccid3hctx_rtt, r_sample,
-                                      hctx->ccid3hctx_s, hctx->ccid3hctx_p,
-                                      hctx->ccid3hctx_x_calc,
-                                      (unsigned)(hctx->ccid3hctx_x_recv >> 6),
-                                      (unsigned)(hctx->ccid3hctx_x >> 6));
+                       goto done_computing_x;
+               } else if (hctx->ccid3hctx_p == 0) {
+                       /*
+                        * First feedback after nofeedback timer expiry (4.3)
+                        */
+                       goto done_computing_x;
                }
+       }
 
-               /* unschedule no feedback timer */
-               sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
+       /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
+       if (hctx->ccid3hctx_p > 0)
+               hctx->ccid3hctx_x_calc =
+                               tfrc_calc_x(hctx->ccid3hctx_s,
+                                           hctx->ccid3hctx_rtt,
+                                           hctx->ccid3hctx_p);
+       ccid3_hc_tx_update_x(sk, &now);
+
+done_computing_x:
+       ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
+                              "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
+                              dccp_role(sk),
+                              sk, hctx->ccid3hctx_rtt, r_sample,
+                              hctx->ccid3hctx_s, hctx->ccid3hctx_p,
+                              hctx->ccid3hctx_x_calc,
+                              (unsigned)(hctx->ccid3hctx_x_recv >> 6),
+                              (unsigned)(hctx->ccid3hctx_x >> 6));
 
-               /* remove all packets older than the one acked from history */
-               dccp_tx_hist_purge_older(ccid3_tx_hist,
-                                        &hctx->ccid3hctx_hist, packet);
-               /*
-                * As we have calculated new ipi, delta, t_nom it is possible
-                * that we now can send a packet, so wake up dccp_wait_for_ccid
-                */
-               sk->sk_write_space(sk);
+       /* unschedule no feedback timer */
+       sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
 
-               /*
-                * Update timeout interval for the nofeedback timer.
-                * We use a configuration option to increase the lower bound.
-                * This can help avoid triggering the nofeedback timer too
-                * often ('spinning') on LANs with small RTTs.
-                */
-               hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
-                                                  CONFIG_IP_DCCP_CCID3_RTO *
-                                                  (USEC_PER_SEC/1000));
-               /*
-                * Schedule no feedback timer to expire in
-                * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
-                */
-               t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
+       /*
+        * As we have calculated new ipi, delta, t_nom it is possible
+        * that we now can send a packet, so wake up dccp_wait_for_ccid
+        */
+       sk->sk_write_space(sk);
 
-               ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
-                              "expire in %lu jiffies (%luus)\n",
-                              dccp_role(sk),
-                              sk, usecs_to_jiffies(t_nfb), t_nfb);
+       /*
+        * Update timeout interval for the nofeedback timer.
+        * We use a configuration option to increase the lower bound.
+        * This can help avoid triggering the nofeedback timer too
+        * often ('spinning') on LANs with small RTTs.
+        */
+       hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
+                                          (CONFIG_IP_DCCP_CCID3_RTO *
+                                           (USEC_PER_SEC / 1000)));
+       /*
+        * Schedule no feedback timer to expire in
+        * max(t_RTO, 2 * s/X)  =  max(t_RTO, 2 * t_ipi)
+        */
+       t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
 
-               sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
-                                  jiffies + usecs_to_jiffies(t_nfb));
+       ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
+                      "expire in %lu jiffies (%luus)\n",
+                      dccp_role(sk),
+                      sk, usecs_to_jiffies(t_nfb), t_nfb);
 
-               /* set idle flag */
-               hctx->ccid3hctx_idle = 1;
-               break;
-       case TFRC_SSTATE_NO_SENT:       /* fall through */
-       case TFRC_SSTATE_TERM:          /* ignore feedback when closing */
-               break;
-       }
+       sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
+                          jiffies + usecs_to_jiffies(t_nfb));
 }
 
 static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
@@ -605,12 +572,9 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
        struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
 
        hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
-       INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
-
-       hctx->ccid3hctx_no_feedback_timer.function =
-                               ccid3_hc_tx_no_feedback_timer;
-       hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
-       init_timer(&hctx->ccid3hctx_no_feedback_timer);
+       hctx->ccid3hctx_hist = NULL;
+       setup_timer(&hctx->ccid3hctx_no_feedback_timer,
+                       ccid3_hc_tx_no_feedback_timer, (unsigned long)sk);
 
        return 0;
 }
@@ -622,8 +586,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
        ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
        sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
 
-       /* Empty packet history */
-       dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
+       tfrc_tx_hist_purge(&hctx->ccid3hctx_hist);
 }
 
 static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
@@ -670,6 +633,15 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
 /*
  *     Receiver Half-Connection Routines
  */
+
+/* CCID3 feedback types */
+enum ccid3_fback_type {
+       CCID3_FBACK_NONE = 0,
+       CCID3_FBACK_INITIAL,
+       CCID3_FBACK_PERIODIC,
+       CCID3_FBACK_PARAM_CHANGE
+};
+
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
 {
@@ -696,67 +668,58 @@ static void ccid3_hc_rx_set_state(struct sock *sk,
        hcrx->ccid3hcrx_state = state;
 }
 
-static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
-{
-       if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */
-               ccid3_pr_debug("Packet payload length is 0 - not updating\n");
-       else
-               hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
-                                   (9 * hcrx->ccid3hcrx_s + len) / 10;
-}
-
-static void ccid3_hc_rx_send_feedback(struct sock *sk)
+static void ccid3_hc_rx_send_feedback(struct sock *sk,
+                                     const struct sk_buff *skb,
+                                     enum ccid3_fback_type fbtype)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
-       struct dccp_rx_hist_entry *packet;
        ktime_t now;
-       suseconds_t delta;
+       s64 delta = 0;
 
-       ccid3_pr_debug("%s(%p) - entry \n", dccp_role(sk), sk);
+       if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_TERM))
+               return;
 
        now = ktime_get_real();
 
-       switch (hcrx->ccid3hcrx_state) {
-       case TFRC_RSTATE_NO_DATA:
+       switch (fbtype) {
+       case CCID3_FBACK_INITIAL:
                hcrx->ccid3hcrx_x_recv = 0;
+               hcrx->ccid3hcrx_pinv   = ~0U;   /* see RFC 4342, 8.5 */
                break;
-       case TFRC_RSTATE_DATA:
-               delta = ktime_us_delta(now,
-                                      hcrx->ccid3hcrx_tstamp_last_feedback);
-               DCCP_BUG_ON(delta < 0);
-               hcrx->ccid3hcrx_x_recv =
-                       scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
+       case CCID3_FBACK_PARAM_CHANGE:
+               /*
+                * When parameters change (new loss or p > p_prev), we do not
+                * have a reliable estimate for R_m of [RFC 3448, 6.2] and so
+                * need to  reuse the previous value of X_recv. However, when
+                * X_recv was 0 (due to early loss), this would kill X down to
+                * s/t_mbi (i.e. one packet in 64 seconds).
+                * To avoid such drastic reduction, we approximate X_recv as
+                * the number of bytes since last feedback.
+                * This is a safe fallback, since X is bounded above by X_calc.
+                */
+               if (hcrx->ccid3hcrx_x_recv > 0)
+                       break;
+               /* fall through */
+       case CCID3_FBACK_PERIODIC:
+               delta = ktime_us_delta(now, hcrx->ccid3hcrx_tstamp_last_feedback);
+               if (delta <= 0)
+                       DCCP_BUG("delta (%ld) <= 0", (long)delta);
+               else
+                       hcrx->ccid3hcrx_x_recv =
+                               scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
                break;
-       case TFRC_RSTATE_TERM:
-               DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
+       default:
                return;
        }
 
-       packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
-       if (unlikely(packet == NULL)) {
-               DCCP_WARN("%s(%p), no data packet in history!\n",
-                         dccp_role(sk), sk);
-               return;
-       }
+       ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta,
+                      hcrx->ccid3hcrx_x_recv, hcrx->ccid3hcrx_pinv);
 
        hcrx->ccid3hcrx_tstamp_last_feedback = now;
-       hcrx->ccid3hcrx_ccval_last_counter   = packet->dccphrx_ccval;
+       hcrx->ccid3hcrx_last_counter         = dccp_hdr(skb)->dccph_ccval;
        hcrx->ccid3hcrx_bytes_recv           = 0;
 
-       /* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
-       delta = ktime_us_delta(now, packet->dccphrx_tstamp);
-       DCCP_BUG_ON(delta < 0);
-       hcrx->ccid3hcrx_elapsed_time = delta / 10;
-
-       if (hcrx->ccid3hcrx_p == 0)
-               hcrx->ccid3hcrx_pinv = ~0U;     /* see RFC 4342, 8.5 */
-       else if (hcrx->ccid3hcrx_p > 1000000) {
-               DCCP_WARN("p (%u) > 100%%\n", hcrx->ccid3hcrx_p);
-               hcrx->ccid3hcrx_pinv = 1;       /* use 100% in this case */
-       } else
-               hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
-
        dp->dccps_hc_rx_insert_options = 1;
        dccp_send_ack(sk);
 }
@@ -770,7 +733,6 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
                return 0;
 
        hcrx = ccid3_hc_rx_sk(sk);
-       DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_ccval_last_counter;
 
        if (dccp_packet_without_ack(skb))
                return 0;
@@ -778,11 +740,7 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
        x_recv = htonl(hcrx->ccid3hcrx_x_recv);
        pinv   = htonl(hcrx->ccid3hcrx_pinv);
 
-       if ((hcrx->ccid3hcrx_elapsed_time != 0 &&
-            dccp_insert_option_elapsed_time(sk, skb,
-                                            hcrx->ccid3hcrx_elapsed_time)) ||
-           dccp_insert_option_timestamp(sk, skb) ||
-           dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
+       if (dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
                               &pinv, sizeof(pinv)) ||
            dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
                               &x_recv, sizeof(x_recv)))
@@ -791,180 +749,139 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
-static int ccid3_hc_rx_detect_loss(struct sock *sk,
-                                   struct dccp_rx_hist_entry *packet)
+/** ccid3_first_li  -  Implements [RFC 3448, 6.3.1]
+ *
+ * Determine the length of the first loss interval via inverse lookup.
+ * Assume that X_recv can be computed by the throughput equation
+ *                 s
+ *     X_recv = --------
+ *              R * fval
+ * Find some p such that f(p) = fval; return 1/p (scaled).
+ */
+static u32 ccid3_first_li(struct sock *sk)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_rx_hist_entry *rx_hist =
-                               dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
-       u64 seqno = packet->dccphrx_seqno;
-       u64 tmp_seqno;
-       int loss = 0;
-       u8 ccval;
-
-
-       tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
+       u32 x_recv, p, delta;
+       u64 fval;
 
-       if (!rx_hist ||
-          follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
-               hcrx->ccid3hcrx_seqno_nonloss = seqno;
-               hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
-               goto detect_out;
+       if (hcrx->ccid3hcrx_rtt == 0) {
+               DCCP_WARN("No RTT estimate available, using fallback RTT\n");
+               hcrx->ccid3hcrx_rtt = DCCP_FALLBACK_RTT;
        }
 
-
-       while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
-          > TFRC_RECV_NUM_LATE_LOSS) {
-               loss = 1;
-               dccp_li_update_li(sk,
-                                 &hcrx->ccid3hcrx_li_hist,
-                                 &hcrx->ccid3hcrx_hist,
-                                 hcrx->ccid3hcrx_tstamp_last_feedback,
-                                 hcrx->ccid3hcrx_s,
-                                 hcrx->ccid3hcrx_bytes_recv,
-                                 hcrx->ccid3hcrx_x_recv,
-                                 hcrx->ccid3hcrx_seqno_nonloss,
-                                 hcrx->ccid3hcrx_ccval_nonloss);
-               tmp_seqno = hcrx->ccid3hcrx_seqno_nonloss;
-               dccp_inc_seqno(&tmp_seqno);
-               hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
-               dccp_inc_seqno(&tmp_seqno);
-               while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist,
-                  tmp_seqno, &ccval)) {
-                       hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
-                       hcrx->ccid3hcrx_ccval_nonloss = ccval;
-                       dccp_inc_seqno(&tmp_seqno);
+       delta = ktime_to_us(net_timedelta(hcrx->ccid3hcrx_tstamp_last_feedback));
+       x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
+       if (x_recv == 0) {              /* would also trigger divide-by-zero */
+               DCCP_WARN("X_recv==0\n");
+               if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
+                       DCCP_BUG("stored value of X_recv is zero");
+                       return ~0U;
                }
        }
 
-       /* FIXME - this code could be simplified with above while */
-       /* but works at moment */
-       if (follows48(packet->dccphrx_seqno, hcrx->ccid3hcrx_seqno_nonloss)) {
-               hcrx->ccid3hcrx_seqno_nonloss = seqno;
-               hcrx->ccid3hcrx_ccval_nonloss = packet->dccphrx_ccval;
-       }
+       fval = scaled_div(hcrx->ccid3hcrx_s, hcrx->ccid3hcrx_rtt);
+       fval = scaled_div32(fval, x_recv);
+       p = tfrc_calc_x_reverse_lookup(fval);
 
-detect_out:
-       dccp_rx_hist_add_packet(ccid3_rx_hist, &hcrx->ccid3hcrx_hist,
-                  &hcrx->ccid3hcrx_li_hist, packet,
-                  hcrx->ccid3hcrx_seqno_nonloss);
-       return loss;
+       ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
+                      "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
+
+       return p == 0 ? ~0U : scaled_div(1, p);
 }
 
 static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       const struct dccp_options_received *opt_recv;
-       struct dccp_rx_hist_entry *packet;
-       u32 p_prev, r_sample, rtt_prev;
-       int loss, payload_size;
-       ktime_t now;
-
-       opt_recv = &dccp_sk(sk)->dccps_options_received;
-
-       switch (DCCP_SKB_CB(skb)->dccpd_type) {
-       case DCCP_PKT_ACK:
-               if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
-                       return;
-       case DCCP_PKT_DATAACK:
-               if (opt_recv->dccpor_timestamp_echo == 0)
-                       break;
-               r_sample = dccp_timestamp() - opt_recv->dccpor_timestamp_echo;
-               rtt_prev = hcrx->ccid3hcrx_rtt;
-               r_sample = dccp_sample_rtt(sk, 10 * r_sample);
+       enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
+       const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
+       const bool is_data_packet = dccp_data_packet(skb);
+
+       if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
+               if (is_data_packet) {
+                       const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
+                       do_feedback = CCID3_FBACK_INITIAL;
+                       ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
+                       hcrx->ccid3hcrx_s = payload;
+                       /*
+                        * Not necessary to update ccid3hcrx_bytes_recv here,
+                        * since X_recv = 0 for the first feedback packet (cf.
+                        * RFC 3448, 6.3) -- gerrit
+                        */
+               }
+               goto update_records;
+       }
 
-               if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
-                       hcrx->ccid3hcrx_rtt = r_sample;
-               else
-                       hcrx->ccid3hcrx_rtt = (hcrx->ccid3hcrx_rtt * 9) / 10 +
-                                             r_sample / 10;
+       if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
+               return; /* done receiving */
 
-               if (rtt_prev != hcrx->ccid3hcrx_rtt)
-                       ccid3_pr_debug("%s(%p), New RTT=%uus, elapsed time=%u\n",
-                                      dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
-                                      opt_recv->dccpor_elapsed_time);
-               break;
-       case DCCP_PKT_DATA:
-               break;
-       default: /* We're not interested in other packet types, move along */
-               return;
+       if (is_data_packet) {
+               const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
+               /*
+                * Update moving-average of s and the sum of received payload bytes
+                */
+               hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload, 9);
+               hcrx->ccid3hcrx_bytes_recv += payload;
        }
 
-       packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp,
-                                       skb, GFP_ATOMIC);
-       if (unlikely(packet == NULL)) {
-               DCCP_WARN("%s(%p), Not enough mem to add rx packet "
-                         "to history, consider it lost!\n", dccp_role(sk), sk);
-               return;
+       /*
+        * Handle pending losses and otherwise check for new loss
+        */
+       if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist) &&
+           tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist,
+                               &hcrx->ccid3hcrx_li_hist,
+                               skb, ndp, ccid3_first_li, sk) ) {
+               do_feedback = CCID3_FBACK_PARAM_CHANGE;
+               goto done_receiving;
        }
 
-       loss = ccid3_hc_rx_detect_loss(sk, packet);
+       if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
+               goto update_records;
 
-       if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
-               return;
-
-       payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
-       ccid3_hc_rx_update_s(hcrx, payload_size);
+       /*
+        * Handle data packets: RTT sampling and monitoring p
+        */
+       if (unlikely(!is_data_packet))
+               goto update_records;
 
-       switch (hcrx->ccid3hcrx_state) {
-       case TFRC_RSTATE_NO_DATA:
-               ccid3_pr_debug("%s(%p, state=%s), skb=%p, sending initial "
-                              "feedback\n", dccp_role(sk), sk,
-                              dccp_state_name(sk->sk_state), skb);
-               ccid3_hc_rx_send_feedback(sk);
-               ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
-               return;
-       case TFRC_RSTATE_DATA:
-               hcrx->ccid3hcrx_bytes_recv += payload_size;
-               if (loss)
-                       break;
+       if (!tfrc_lh_is_initialised(&hcrx->ccid3hcrx_li_hist)) {
+               const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
+               /*
+                * Empty loss history: no loss so far, hence p stays 0.
+                * Sample RTT values, since an RTT estimate is required for the
+                * computation of p when the first loss occurs; RFC 3448, 6.3.1.
+                */
+               if (sample != 0)
+                       hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
 
-               now = ktime_get_real();
-               if ((ktime_us_delta(now, hcrx->ccid3hcrx_tstamp_last_ack) -
-                    (s64)hcrx->ccid3hcrx_rtt) >= 0) {
-                       hcrx->ccid3hcrx_tstamp_last_ack = now;
-                       ccid3_hc_rx_send_feedback(sk);
-               }
-               return;
-       case TFRC_RSTATE_TERM:
-               DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
-               return;
+       } else if (tfrc_lh_update_i_mean(&hcrx->ccid3hcrx_li_hist, skb)) {
+               /*
+                * Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
+                * has decreased (resp. p has increased), send feedback now.
+                */
+               do_feedback = CCID3_FBACK_PARAM_CHANGE;
        }
 
-       /* Dealing with packet loss */
-       ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n",
-                      dccp_role(sk), sk, dccp_state_name(sk->sk_state));
-
-       p_prev = hcrx->ccid3hcrx_p;
-
-       /* Calculate loss event rate */
-       if (!list_empty(&hcrx->ccid3hcrx_li_hist)) {
-               u32 i_mean = dccp_li_hist_calc_i_mean(&hcrx->ccid3hcrx_li_hist);
+       /*
+        * Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
+        */
+       if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
+               do_feedback = CCID3_FBACK_PERIODIC;
 
-               /* Scaling up by 1000000 as fixed decimal */
-               if (i_mean != 0)
-                       hcrx->ccid3hcrx_p = 1000000 / i_mean;
-       } else
-               DCCP_BUG("empty loss history");
+update_records:
+       tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
 
-       if (hcrx->ccid3hcrx_p > p_prev) {
-               ccid3_hc_rx_send_feedback(sk);
-               return;
-       }
+done_receiving:
+       if (do_feedback)
+               ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
 }
 
 static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
 
-       ccid3_pr_debug("entry\n");
-
        hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
-       INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
-       INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
-       hcrx->ccid3hcrx_tstamp_last_feedback =
-               hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real();
-       return 0;
+       tfrc_lh_init(&hcrx->ccid3hcrx_li_hist);
+       return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist);
 }
 
 static void ccid3_hc_rx_exit(struct sock *sk)
@@ -973,11 +890,8 @@ static void ccid3_hc_rx_exit(struct sock *sk)
 
        ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
 
-       /* Empty packet history */
-       dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
-
-       /* Empty loss interval history */
-       dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
+       tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist);
+       tfrc_lh_cleanup(&hcrx->ccid3hcrx_li_hist);
 }
 
 static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -998,6 +912,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
                                  u32 __user *optval, int __user *optlen)
 {
        const struct ccid3_hc_rx_sock *hcrx;
+       struct tfrc_rx_info rx_info;
        const void *val;
 
        /* Listen socks doesn't have a private CCID block */
@@ -1007,10 +922,14 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
        hcrx = ccid3_hc_rx_sk(sk);
        switch (optname) {
        case DCCP_SOCKOPT_CCID_RX_INFO:
-               if (len < sizeof(hcrx->ccid3hcrx_tfrc))
+               if (len < sizeof(rx_info))
                        return -EINVAL;
-               len = sizeof(hcrx->ccid3hcrx_tfrc);
-               val = &hcrx->ccid3hcrx_tfrc;
+               rx_info.tfrcrx_x_recv = hcrx->ccid3hcrx_x_recv;
+               rx_info.tfrcrx_rtt    = hcrx->ccid3hcrx_rtt;
+               rx_info.tfrcrx_p      = hcrx->ccid3hcrx_pinv == 0 ? ~0U :
+                                          scaled_div(1, hcrx->ccid3hcrx_pinv);
+               len = sizeof(rx_info);
+               val = &rx_info;
                break;
        default:
                return -ENOPROTOOPT;
@@ -1024,7 +943,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
 
 static struct ccid_operations ccid3 = {
        .ccid_id                   = DCCPC_CCID3,
-       .ccid_name                 = "ccid3",
+       .ccid_name                 = "TCP-Friendly Rate Control",
        .ccid_owner                = THIS_MODULE,
        .ccid_hc_tx_obj_size       = sizeof(struct ccid3_hc_tx_sock),
        .ccid_hc_tx_init           = ccid3_hc_tx_init,
@@ -1051,44 +970,13 @@ MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
 
 static __init int ccid3_module_init(void)
 {
-       int rc = -ENOBUFS;
-
-       ccid3_rx_hist = dccp_rx_hist_new("ccid3");
-       if (ccid3_rx_hist == NULL)
-               goto out;
-
-       ccid3_tx_hist = dccp_tx_hist_new("ccid3");
-       if (ccid3_tx_hist == NULL)
-               goto out_free_rx;
-
-       rc = ccid_register(&ccid3);
-       if (rc != 0)
-               goto out_free_tx;
-out:
-       return rc;
-
-out_free_tx:
-       dccp_tx_hist_delete(ccid3_tx_hist);
-       ccid3_tx_hist = NULL;
-out_free_rx:
-       dccp_rx_hist_delete(ccid3_rx_hist);
-       ccid3_rx_hist = NULL;
-       goto out;
+       return ccid_register(&ccid3);
 }
 module_init(ccid3_module_init);
 
 static __exit void ccid3_module_exit(void)
 {
        ccid_unregister(&ccid3);
-
-       if (ccid3_tx_hist != NULL) {
-               dccp_tx_hist_delete(ccid3_tx_hist);
-               ccid3_tx_hist = NULL;
-       }
-       if (ccid3_rx_hist != NULL) {
-               dccp_rx_hist_delete(ccid3_rx_hist);
-               ccid3_rx_hist = NULL;
-       }
 }
 module_exit(ccid3_module_exit);
 
index 0cdc982cfe470f46a59210bf06d4a913164aed8e..49ca32bd7e79d608592aaae0371545ff246ab013 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *  net/dccp/ccids/ccid3.h
  *
- *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *
  *  An implementation of the DCCP protocol
  *
@@ -40,6 +41,7 @@
 #include <linux/list.h>
 #include <linux/types.h>
 #include <linux/tfrc.h>
+#include "lib/tfrc.h"
 #include "../ccid.h"
 
 /* Two seconds as per RFC 3448 4.2 */
@@ -88,7 +90,6 @@ enum ccid3_hc_tx_states {
  * @ccid3hctx_t_last_win_count - Timestamp of earliest packet
  *                              with last_win_count value sent
  * @ccid3hctx_no_feedback_timer - Handle to no feedback timer
- * @ccid3hctx_idle - Flag indicating that sender is idling
  * @ccid3hctx_t_ld - Time last doubled during slow start
  * @ccid3hctx_t_nom - Nominal send time of next packet
  * @ccid3hctx_delta - Send timer delta (RFC 3448, 4.6) in usecs
@@ -107,13 +108,12 @@ struct ccid3_hc_tx_sock {
        u16                             ccid3hctx_s;
        enum ccid3_hc_tx_states         ccid3hctx_state:8;
        u8                              ccid3hctx_last_win_count;
-       u8                              ccid3hctx_idle;
        ktime_t                         ccid3hctx_t_last_win_count;
        struct timer_list               ccid3hctx_no_feedback_timer;
        ktime_t                         ccid3hctx_t_ld;
        ktime_t                         ccid3hctx_t_nom;
        u32                             ccid3hctx_delta;
-       struct list_head                ccid3hctx_hist;
+       struct tfrc_tx_hist_entry       *ccid3hctx_hist;
        struct ccid3_options_received   ccid3hctx_options_received;
 };
 
@@ -135,37 +135,30 @@ enum ccid3_hc_rx_states {
  *
  *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448 4.3)
  *  @ccid3hcrx_rtt  -  Receiver estimate of rtt (non-standard)
- *  @ccid3hcrx_p  -  current loss event rate (RFC 3448 5.4)
- *  @ccid3hcrx_seqno_nonloss  -  Last received non-loss sequence number
- *  @ccid3hcrx_ccval_nonloss  -  Last received non-loss Window CCVal
- *  @ccid3hcrx_ccval_last_counter  -  Tracks window counter (RFC 4342, 8.1)
- *  @ccid3hcrx_state  -  receiver state, one of %ccid3_hc_rx_states
+ *  @ccid3hcrx_p  -  Current loss event rate (RFC 3448 5.4)
+ *  @ccid3hcrx_last_counter  -  Tracks window counter (RFC 4342, 8.1)
+ *  @ccid3hcrx_state  -  Receiver state, one of %ccid3_hc_rx_states
  *  @ccid3hcrx_bytes_recv  -  Total sum of DCCP payload bytes
+ *  @ccid3hcrx_x_recv  -  Receiver estimate of send rate (RFC 3448, sec. 4.3)
+ *  @ccid3hcrx_rtt  -  Receiver estimate of RTT
  *  @ccid3hcrx_tstamp_last_feedback  -  Time at which last feedback was sent
  *  @ccid3hcrx_tstamp_last_ack  -  Time at which last feedback was sent
- *  @ccid3hcrx_hist  -  Packet history
- *  @ccid3hcrx_li_hist  -  Loss Interval History
+ *  @ccid3hcrx_hist  -  Packet history (loss detection + RTT sampling)
+ *  @ccid3hcrx_li_hist  -  Loss Interval database
  *  @ccid3hcrx_s  -  Received packet size in bytes
  *  @ccid3hcrx_pinv  -  Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
- *  @ccid3hcrx_elapsed_time  -  Time since packet reception
  */
 struct ccid3_hc_rx_sock {
-       struct tfrc_rx_info             ccid3hcrx_tfrc;
-#define ccid3hcrx_x_recv               ccid3hcrx_tfrc.tfrcrx_x_recv
-#define ccid3hcrx_rtt                  ccid3hcrx_tfrc.tfrcrx_rtt
-#define ccid3hcrx_p                    ccid3hcrx_tfrc.tfrcrx_p
-       u64                             ccid3hcrx_seqno_nonloss:48,
-                                       ccid3hcrx_ccval_nonloss:4,
-                                       ccid3hcrx_ccval_last_counter:4;
+       u8                              ccid3hcrx_last_counter:4;
        enum ccid3_hc_rx_states         ccid3hcrx_state:8;
        u32                             ccid3hcrx_bytes_recv;
+       u32                             ccid3hcrx_x_recv;
+       u32                             ccid3hcrx_rtt;
        ktime_t                         ccid3hcrx_tstamp_last_feedback;
-       ktime_t                         ccid3hcrx_tstamp_last_ack;
-       struct list_head                ccid3hcrx_hist;
-       struct list_head                ccid3hcrx_li_hist;
+       struct tfrc_rx_hist             ccid3hcrx_hist;
+       struct tfrc_loss_hist           ccid3hcrx_li_hist;
        u16                             ccid3hcrx_s;
-       u32                             ccid3hcrx_pinv;
-       u32                             ccid3hcrx_elapsed_time;
+#define ccid3hcrx_pinv                 ccid3hcrx_li_hist.i_mean
 };
 
 static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
index 5f940a6cbaca2fca442c9dcda0a783fd771c7bd2..68c93e3d89dce33ec98c8492b90829afc8f573ac 100644 (file)
@@ -1,3 +1,3 @@
 obj-$(CONFIG_IP_DCCP_TFRC_LIB) += dccp_tfrc_lib.o
 
-dccp_tfrc_lib-y := loss_interval.o packet_history.o tfrc_equation.o
+dccp_tfrc_lib-y := tfrc.o tfrc_equation.o packet_history.o loss_interval.o
index d26b88dbbb45cbab0b5de86bf0151d9cfa3a6638..849e181e698fa84d0a7c3e1665cc8e459f5567ac 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.c
  *
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
  */
-
-#include <linux/module.h>
 #include <net/sock.h>
-#include "../../dccp.h"
-#include "loss_interval.h"
-#include "packet_history.h"
 #include "tfrc.h"
 
-#define DCCP_LI_HIST_IVAL_F_LENGTH  8
-
-struct dccp_li_hist_entry {
-       struct list_head dccplih_node;
-       u64              dccplih_seqno:48,
-                        dccplih_win_count:4;
-       u32              dccplih_interval;
-};
+static struct kmem_cache  *tfrc_lh_slab  __read_mostly;
+/* Loss Interval weights from [RFC 3448, 5.4], scaled by 10 */
+static const int tfrc_lh_weights[NINTERVAL] = { 10, 10, 10, 10, 8, 6, 4, 2 };
 
-static struct kmem_cache *dccp_li_cachep __read_mostly;
-
-static inline struct dccp_li_hist_entry *dccp_li_hist_entry_new(const gfp_t prio)
+/* implements LIFO semantics on the array */
+static inline u8 LIH_INDEX(const u8 ctr)
 {
-       return kmem_cache_alloc(dccp_li_cachep, prio);
+       return (LIH_SIZE - 1 - (ctr % LIH_SIZE));
 }
 
-static inline void dccp_li_hist_entry_delete(struct dccp_li_hist_entry *entry)
+/* the `counter' index always points at the next entry to be populated */
+static inline struct tfrc_loss_interval *tfrc_lh_peek(struct tfrc_loss_hist *lh)
 {
-       if (entry != NULL)
-               kmem_cache_free(dccp_li_cachep, entry);
+       return lh->counter ? lh->ring[LIH_INDEX(lh->counter - 1)] : NULL;
 }
 
-void dccp_li_hist_purge(struct list_head *list)
+/* given i with 0 <= i <= k, return I_i as per the rfc3448bis notation */
+static inline u32 tfrc_lh_get_interval(struct tfrc_loss_hist *lh, const u8 i)
 {
-       struct dccp_li_hist_entry *entry, *next;
-
-       list_for_each_entry_safe(entry, next, list, dccplih_node) {
-               list_del_init(&entry->dccplih_node);
-               kmem_cache_free(dccp_li_cachep, entry);
-       }
+       BUG_ON(i >= lh->counter);
+       return lh->ring[LIH_INDEX(lh->counter - i - 1)]->li_length;
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_purge);
-
-/* Weights used to calculate loss event rate */
 /*
- * These are integers as per section 8 of RFC3448. We can then divide by 4 *
- * when we use it.
+ *     On-demand allocation and de-allocation of entries
  */
-static const int dccp_li_hist_w[DCCP_LI_HIST_IVAL_F_LENGTH] = {
-       4, 4, 4, 4, 3, 2, 1, 1,
-};
-
-u32 dccp_li_hist_calc_i_mean(struct list_head *list)
+static struct tfrc_loss_interval *tfrc_lh_demand_next(struct tfrc_loss_hist *lh)
 {
-       struct dccp_li_hist_entry *li_entry, *li_next;
-       int i = 0;
-       u32 i_tot;
-       u32 i_tot0 = 0;
-       u32 i_tot1 = 0;
-       u32 w_tot  = 0;
-
-       list_for_each_entry_safe(li_entry, li_next, list, dccplih_node) {
-               if (li_entry->dccplih_interval != ~0U) {
-                       i_tot0 += li_entry->dccplih_interval * dccp_li_hist_w[i];
-                       w_tot  += dccp_li_hist_w[i];
-                       if (i != 0)
-                               i_tot1 += li_entry->dccplih_interval * dccp_li_hist_w[i - 1];
-               }
-
-
-               if (++i > DCCP_LI_HIST_IVAL_F_LENGTH)
-                       break;
-       }
-
-       if (i != DCCP_LI_HIST_IVAL_F_LENGTH)
-               return 0;
-
-       i_tot = max(i_tot0, i_tot1);
-
-       if (!w_tot) {
-               DCCP_WARN("w_tot = 0\n");
-               return 1;
-       }
-
-       return i_tot / w_tot;
+       if (lh->ring[LIH_INDEX(lh->counter)] == NULL)
+               lh->ring[LIH_INDEX(lh->counter)] = kmem_cache_alloc(tfrc_lh_slab,
+                                                                   GFP_ATOMIC);
+       return lh->ring[LIH_INDEX(lh->counter)];
 }
 
-EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);
-
-static int dccp_li_hist_interval_new(struct list_head *list,
-                                    const u64 seq_loss, const u8 win_loss)
+void tfrc_lh_cleanup(struct tfrc_loss_hist *lh)
 {
-       struct dccp_li_hist_entry *entry;
-       int i;
-
-       for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
-               entry = dccp_li_hist_entry_new(GFP_ATOMIC);
-               if (entry == NULL) {
-                       dccp_li_hist_purge(list);
-                       DCCP_BUG("loss interval list entry is NULL");
-                       return 0;
+       if (!tfrc_lh_is_initialised(lh))
+               return;
+
+       for (lh->counter = 0; lh->counter < LIH_SIZE; lh->counter++)
+               if (lh->ring[LIH_INDEX(lh->counter)] != NULL) {
+                       kmem_cache_free(tfrc_lh_slab,
+                                       lh->ring[LIH_INDEX(lh->counter)]);
+                       lh->ring[LIH_INDEX(lh->counter)] = NULL;
                }
-               entry->dccplih_interval = ~0;
-               list_add(&entry->dccplih_node, list);
-       }
-
-       entry->dccplih_seqno     = seq_loss;
-       entry->dccplih_win_count = win_loss;
-       return 1;
 }
+EXPORT_SYMBOL_GPL(tfrc_lh_cleanup);
 
-/* calculate first loss interval
- *
- * returns estimated loss interval in usecs */
-static u32 dccp_li_calc_first_li(struct sock *sk,
-                                struct list_head *hist_list,
-                                ktime_t last_feedback,
-                                u16 s, u32 bytes_recv,
-                                u32 previous_x_recv)
+static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
 {
-       struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
-       u32 x_recv, p;
-       suseconds_t rtt, delta;
-       ktime_t tstamp = ktime_set(0, 0);
-       int interval = 0;
-       int win_count = 0;
-       int step = 0;
-       u64 fval;
+       u32 i_i, i_tot0 = 0, i_tot1 = 0, w_tot = 0;
+       int i, k = tfrc_lh_length(lh) - 1; /* k is as in rfc3448bis, 5.4 */
 
-       list_for_each_entry_safe(entry, next, hist_list, dccphrx_node) {
-               if (dccp_rx_hist_entry_data_packet(entry)) {
-                       tail = entry;
+       for (i=0; i <= k; i++) {
+               i_i = tfrc_lh_get_interval(lh, i);
 
-                       switch (step) {
-                       case 0:
-                               tstamp    = entry->dccphrx_tstamp;
-                               win_count = entry->dccphrx_ccval;
-                               step = 1;
-                               break;
-                       case 1:
-                               interval = win_count - entry->dccphrx_ccval;
-                               if (interval < 0)
-                                       interval += TFRC_WIN_COUNT_LIMIT;
-                               if (interval > 4)
-                                       goto found;
-                               break;
-                       }
+               if (i < k) {
+                       i_tot0 += i_i * tfrc_lh_weights[i];
+                       w_tot  += tfrc_lh_weights[i];
                }
+               if (i > 0)
+                       i_tot1 += i_i * tfrc_lh_weights[i-1];
        }
 
-       if (unlikely(step == 0)) {
-               DCCP_WARN("%s(%p), packet history has no data packets!\n",
-                         dccp_role(sk), sk);
-               return ~0;
-       }
-
-       if (unlikely(interval == 0)) {
-               DCCP_WARN("%s(%p), Could not find a win_count interval > 0. "
-                         "Defaulting to 1\n", dccp_role(sk), sk);
-               interval = 1;
-       }
-found:
-       if (!tail) {
-               DCCP_CRIT("tail is null\n");
-               return ~0;
-       }
-
-       delta = ktime_us_delta(tstamp, tail->dccphrx_tstamp);
-       DCCP_BUG_ON(delta < 0);
+       BUG_ON(w_tot == 0);
+       lh->i_mean = max(i_tot0, i_tot1) / w_tot;
+}
 
-       rtt = delta * 4 / interval;
-       dccp_pr_debug("%s(%p), approximated RTT to %dus\n",
-                     dccp_role(sk), sk, (int)rtt);
+/**
+ * tfrc_lh_update_i_mean  -  Update the `open' loss interval I_0
+ * For recomputing p: returns `true' if p > p_prev  <=>  1/p < 1/p_prev
+ */
+u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
+{
+       struct tfrc_loss_interval *cur = tfrc_lh_peek(lh);
+       u32 old_i_mean = lh->i_mean;
+       s64 length;
 
-       /*
-        * Determine the length of the first loss interval via inverse lookup.
-        * Assume that X_recv can be computed by the throughput equation
-        *                  s
-        *      X_recv = --------
-        *               R * fval
-        * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
-        */
-       if (rtt == 0) {                 /* would result in divide-by-zero */
-               DCCP_WARN("RTT==0\n");
-               return ~0;
-       }
+       if (cur == NULL)                        /* not initialised */
+               return 0;
 
-       delta = ktime_us_delta(ktime_get_real(), last_feedback);
-       DCCP_BUG_ON(delta <= 0);
+       length = dccp_delta_seqno(cur->li_seqno, DCCP_SKB_CB(skb)->dccpd_seq);
 
-       x_recv = scaled_div32(bytes_recv, delta);
-       if (x_recv == 0) {              /* would also trigger divide-by-zero */
-               DCCP_WARN("X_recv==0\n");
-               if (previous_x_recv == 0) {
-                       DCCP_BUG("stored value of X_recv is zero");
-                       return ~0;
-               }
-               x_recv = previous_x_recv;
-       }
+       if (length - cur->li_length <= 0)       /* duplicate or reordered */
+               return 0;
 
-       fval = scaled_div(s, rtt);
-       fval = scaled_div32(fval, x_recv);
-       p = tfrc_calc_x_reverse_lookup(fval);
+       if (SUB16(dccp_hdr(skb)->dccph_ccval, cur->li_ccval) > 4)
+               /*
+                * Implements RFC 4342, 10.2:
+                * If a packet S (skb) exists whose seqno comes `after' the one
+                * starting the current loss interval (cur) and if the modulo-16
+                * distance from C(cur) to C(S) is greater than 4, consider all
+                * subsequent packets as belonging to a new loss interval. This
+                * test is necessary since CCVal may wrap between intervals.
+                */
+               cur->li_is_closed = 1;
+
+       if (tfrc_lh_length(lh) == 1)            /* due to RFC 3448, 6.3.1 */
+               return 0;
 
-       dccp_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
-                     "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
+       cur->li_length = length;
+       tfrc_lh_calc_i_mean(lh);
 
-       if (p == 0)
-               return ~0;
-       else
-               return 1000000 / p;
+       return (lh->i_mean < old_i_mean);
 }
+EXPORT_SYMBOL_GPL(tfrc_lh_update_i_mean);
 
-void dccp_li_update_li(struct sock *sk,
-                      struct list_head *li_hist_list,
-                      struct list_head *hist_list,
-                      ktime_t last_feedback, u16 s, u32 bytes_recv,
-                      u32 previous_x_recv, u64 seq_loss, u8 win_loss)
+/* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */
+static inline u8 tfrc_lh_is_new_loss(struct tfrc_loss_interval *cur,
+                                    struct tfrc_rx_hist_entry *new_loss)
 {
-       struct dccp_li_hist_entry *head;
-       u64 seq_temp;
-
-       if (list_empty(li_hist_list)) {
-               if (!dccp_li_hist_interval_new(li_hist_list, seq_loss,
-                                              win_loss))
-                       return;
-
-               head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
-                                 dccplih_node);
-               head->dccplih_interval = dccp_li_calc_first_li(sk, hist_list,
-                                                              last_feedback,
-                                                              s, bytes_recv,
-                                                              previous_x_recv);
-       } else {
-               struct dccp_li_hist_entry *entry;
-               struct list_head *tail;
+       return  dccp_delta_seqno(cur->li_seqno, new_loss->tfrchrx_seqno) > 0 &&
+               (cur->li_is_closed || SUB16(new_loss->tfrchrx_ccval, cur->li_ccval) > 4);
+}
 
-               head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
-                                 dccplih_node);
-               /* FIXME win count check removed as was wrong */
-               /* should make this check with receive history */
-               /* and compare there as per section 10.2 of RFC4342 */
+/** tfrc_lh_interval_add  -  Insert new record into the Loss Interval database
+ * @lh:                   Loss Interval database
+ * @rh:                   Receive history containing a fresh loss event
+ * @calc_first_li: Caller-dependent routine to compute length of first interval
+ * @sk:                   Used by @calc_first_li in caller-specific way (subtyping)
+ * Updates I_mean and returns 1 if a new interval has in fact been added to @lh.
+ */
+int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
+                        u32 (*calc_first_li)(struct sock *), struct sock *sk)
+{
+       struct tfrc_loss_interval *cur = tfrc_lh_peek(lh), *new;
 
-               /* new loss event detected */
-               /* calculate last interval length */
-               seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
-               entry = dccp_li_hist_entry_new(GFP_ATOMIC);
+       if (cur != NULL && !tfrc_lh_is_new_loss(cur, tfrc_rx_hist_loss_prev(rh)))
+               return 0;
 
-               if (entry == NULL) {
-                       DCCP_BUG("out of memory - can not allocate entry");
-                       return;
-               }
+       new = tfrc_lh_demand_next(lh);
+       if (unlikely(new == NULL)) {
+               DCCP_CRIT("Cannot allocate/add loss record.");
+               return 0;
+       }
 
-               list_add(&entry->dccplih_node, li_hist_list);
+       new->li_seqno     = tfrc_rx_hist_loss_prev(rh)->tfrchrx_seqno;
+       new->li_ccval     = tfrc_rx_hist_loss_prev(rh)->tfrchrx_ccval;
+       new->li_is_closed = 0;
 
-               tail = li_hist_list->prev;
-               list_del(tail);
-               kmem_cache_free(dccp_li_cachep, tail);
+       if (++lh->counter == 1)
+               lh->i_mean = new->li_length = (*calc_first_li)(sk);
+       else {
+               cur->li_length = dccp_delta_seqno(cur->li_seqno, new->li_seqno);
+               new->li_length = dccp_delta_seqno(new->li_seqno,
+                                 tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno);
+               if (lh->counter > (2*LIH_SIZE))
+                       lh->counter -= LIH_SIZE;
 
-               /* Create the newest interval */
-               entry->dccplih_seqno = seq_loss;
-               entry->dccplih_interval = seq_temp;
-               entry->dccplih_win_count = win_loss;
+               tfrc_lh_calc_i_mean(lh);
        }
+       return 1;
 }
+EXPORT_SYMBOL_GPL(tfrc_lh_interval_add);
 
-EXPORT_SYMBOL_GPL(dccp_li_update_li);
-
-static __init int dccp_li_init(void)
+int __init tfrc_li_init(void)
 {
-       dccp_li_cachep = kmem_cache_create("dccp_li_hist",
-                                          sizeof(struct dccp_li_hist_entry),
-                                          0, SLAB_HWCACHE_ALIGN, NULL);
-       return dccp_li_cachep == NULL ? -ENOBUFS : 0;
+       tfrc_lh_slab = kmem_cache_create("tfrc_li_hist",
+                                        sizeof(struct tfrc_loss_interval), 0,
+                                        SLAB_HWCACHE_ALIGN, NULL);
+       return tfrc_lh_slab == NULL ? -ENOBUFS : 0;
 }
 
-static __exit void dccp_li_exit(void)
+void tfrc_li_exit(void)
 {
-       kmem_cache_destroy(dccp_li_cachep);
+       if (tfrc_lh_slab != NULL) {
+               kmem_cache_destroy(tfrc_lh_slab);
+               tfrc_lh_slab = NULL;
+       }
 }
-
-module_init(dccp_li_init);
-module_exit(dccp_li_exit);
index 27bee92dae13481a5299e8e7fb686b6133b956b4..246018a3b269f7a714f121eeb18cedbf832fee20 100644 (file)
@@ -3,6 +3,7 @@
 /*
  *  net/dccp/ccids/lib/loss_interval.h
  *
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *  Software Foundation; either version 2 of the License, or (at your option)
  *  any later version.
  */
-
 #include <linux/ktime.h>
 #include <linux/list.h>
+#include <linux/slab.h>
+
+/*
+ * Number of loss intervals (RFC 4342, 8.6.1). The history size is one more than
+ * NINTERVAL, since the `open' interval I_0 is always stored as the first entry.
+ */
+#define NINTERVAL      8
+#define LIH_SIZE       (NINTERVAL + 1)
+
+/**
+ *  tfrc_loss_interval  -  Loss history record for TFRC-based protocols
+ *  @li_seqno:         Highest received seqno before the start of loss
+ *  @li_ccval:         The CCVal belonging to @li_seqno
+ *  @li_is_closed:     Whether @li_seqno is older than 1 RTT
+ *  @li_length:                Loss interval sequence length
+ */
+struct tfrc_loss_interval {
+       u64              li_seqno:48,
+                        li_ccval:4,
+                        li_is_closed:1;
+       u32              li_length;
+};
+
+/**
+ *  tfrc_loss_hist  -  Loss record database
+ *  @ring:     Circular queue managed in LIFO manner
+ *  @counter:  Current count of entries (can be more than %LIH_SIZE)
+ *  @i_mean:   Current Average Loss Interval [RFC 3448, 5.4]
+ */
+struct tfrc_loss_hist {
+       struct tfrc_loss_interval       *ring[LIH_SIZE];
+       u8                              counter;
+       u32                             i_mean;
+};
+
+static inline void tfrc_lh_init(struct tfrc_loss_hist *lh)
+{
+       memset(lh, 0, sizeof(struct tfrc_loss_hist));
+}
+
+static inline u8 tfrc_lh_is_initialised(struct tfrc_loss_hist *lh)
+{
+       return lh->counter > 0;
+}
+
+static inline u8 tfrc_lh_length(struct tfrc_loss_hist *lh)
+{
+       return min(lh->counter, (u8)LIH_SIZE);
+}
 
-extern void dccp_li_hist_purge(struct list_head *list);
+struct tfrc_rx_hist;
 
-extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);
+extern int  tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *,
+                                u32 (*first_li)(struct sock *), struct sock *);
+extern u8   tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *);
+extern void tfrc_lh_cleanup(struct tfrc_loss_hist *lh);
 
-extern void dccp_li_update_li(struct sock *sk,
-                             struct list_head *li_hist_list,
-                             struct list_head *hist_list,
-                             ktime_t last_feedback, u16 s,
-                             u32 bytes_recv, u32 previous_x_recv,
-                             u64 seq_loss, u8 win_loss);
 #endif /* _DCCP_LI_HIST_ */
index 34c4f60477248de941d92fc2718be7aca970defc..20af1a69342789f96abc6454b9a93187624de027 100644 (file)
@@ -1,7 +1,8 @@
 /*
  *  net/dccp/packet_history.c
  *
- *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
+ *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
  *
  *  An implementation of the DCCP protocol
  *
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/module.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include "packet_history.h"
+#include "../../dccp.h"
+
+/**
+ *  tfrc_tx_hist_entry  -  Simple singly-linked TX history list
+ *  @next:  next oldest entry (LIFO order)
+ *  @seqno: sequence number of this entry
+ *  @stamp: send time of packet with sequence number @seqno
+ */
+struct tfrc_tx_hist_entry {
+       struct tfrc_tx_hist_entry *next;
+       u64                       seqno;
+       ktime_t                   stamp;
+};
 
 /*
- *     Transmitter History Routines
+ * Transmitter History Routines
  */
-struct dccp_tx_hist *dccp_tx_hist_new(const char *name)
+static struct kmem_cache *tfrc_tx_hist_slab;
+
+int __init tfrc_tx_packet_history_init(void)
 {
-       struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
-       static const char dccp_tx_hist_mask[] = "tx_hist_%s";
-       char *slab_name;
-
-       if (hist == NULL)
-               goto out;
-
-       slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
-                           GFP_ATOMIC);
-       if (slab_name == NULL)
-               goto out_free_hist;
-
-       sprintf(slab_name, dccp_tx_hist_mask, name);
-       hist->dccptxh_slab = kmem_cache_create(slab_name,
-                                            sizeof(struct dccp_tx_hist_entry),
-                                              0, SLAB_HWCACHE_ALIGN,
-                                              NULL);
-       if (hist->dccptxh_slab == NULL)
-               goto out_free_slab_name;
-out:
-       return hist;
-out_free_slab_name:
-       kfree(slab_name);
-out_free_hist:
-       kfree(hist);
-       hist = NULL;
-       goto out;
+       tfrc_tx_hist_slab = kmem_cache_create("tfrc_tx_hist",
+                                             sizeof(struct tfrc_tx_hist_entry),
+                                             0, SLAB_HWCACHE_ALIGN, NULL);
+       return tfrc_tx_hist_slab == NULL ? -ENOBUFS : 0;
 }
 
-EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
-
-void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
+void tfrc_tx_packet_history_exit(void)
 {
-       const char* name = kmem_cache_name(hist->dccptxh_slab);
-
-       kmem_cache_destroy(hist->dccptxh_slab);
-       kfree(name);
-       kfree(hist);
+       if (tfrc_tx_hist_slab != NULL) {
+               kmem_cache_destroy(tfrc_tx_hist_slab);
+               tfrc_tx_hist_slab = NULL;
+       }
 }
 
-EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
-
-struct dccp_tx_hist_entry *
-       dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
+static struct tfrc_tx_hist_entry *
+       tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno)
 {
-       struct dccp_tx_hist_entry *packet = NULL, *entry;
-
-       list_for_each_entry(entry, list, dccphtx_node)
-               if (entry->dccphtx_seqno == seq) {
-                       packet = entry;
-                       break;
-               }
+       while (head != NULL && head->seqno != seqno)
+               head = head->next;
 
-       return packet;
+       return head;
 }
 
-EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
+int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno)
+{
+       struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any());
+
+       if (entry == NULL)
+               return -ENOBUFS;
+       entry->seqno = seqno;
+       entry->stamp = ktime_get_real();
+       entry->next  = *headp;
+       *headp       = entry;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(tfrc_tx_hist_add);
 
-void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
+void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp)
 {
-       struct dccp_tx_hist_entry *entry, *next;
+       struct tfrc_tx_hist_entry *head = *headp;
+
+       while (head != NULL) {
+               struct tfrc_tx_hist_entry *next = head->next;
 
-       list_for_each_entry_safe(entry, next, list, dccphtx_node) {
-               list_del_init(&entry->dccphtx_node);
-               dccp_tx_hist_entry_delete(hist, entry);
+               kmem_cache_free(tfrc_tx_hist_slab, head);
+               head = next;
        }
-}
 
-EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
+       *headp = NULL;
+}
+EXPORT_SYMBOL_GPL(tfrc_tx_hist_purge);
 
-void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
-                             struct list_head *list,
-                             struct dccp_tx_hist_entry *packet)
+u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno,
+                    const ktime_t now)
 {
-       struct dccp_tx_hist_entry *next;
+       u32 rtt = 0;
+       struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno);
 
-       list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) {
-               list_del_init(&packet->dccphtx_node);
-               dccp_tx_hist_entry_delete(hist, packet);
+       if (packet != NULL) {
+               rtt = ktime_us_delta(now, packet->stamp);
+               /*
+                * Garbage-collect older (irrelevant) entries:
+                */
+               tfrc_tx_hist_purge(&packet->next);
        }
+
+       return rtt;
 }
+EXPORT_SYMBOL_GPL(tfrc_tx_hist_rtt);
 
-EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older);
 
 /*
  *     Receiver History Routines
  */
-struct dccp_rx_hist *dccp_rx_hist_new(const char *name)
+static struct kmem_cache *tfrc_rx_hist_slab;
+
+int __init tfrc_rx_packet_history_init(void)
 {
-       struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
-       static const char dccp_rx_hist_mask[] = "rx_hist_%s";
-       char *slab_name;
-
-       if (hist == NULL)
-               goto out;
-
-       slab_name = kmalloc(strlen(name) + sizeof(dccp_rx_hist_mask) - 1,
-                           GFP_ATOMIC);
-       if (slab_name == NULL)
-               goto out_free_hist;
-
-       sprintf(slab_name, dccp_rx_hist_mask, name);
-       hist->dccprxh_slab = kmem_cache_create(slab_name,
-                                            sizeof(struct dccp_rx_hist_entry),
-                                              0, SLAB_HWCACHE_ALIGN,
-                                              NULL);
-       if (hist->dccprxh_slab == NULL)
-               goto out_free_slab_name;
-out:
-       return hist;
-out_free_slab_name:
-       kfree(slab_name);
-out_free_hist:
-       kfree(hist);
-       hist = NULL;
-       goto out;
+       tfrc_rx_hist_slab = kmem_cache_create("tfrc_rxh_cache",
+                                             sizeof(struct tfrc_rx_hist_entry),
+                                             0, SLAB_HWCACHE_ALIGN, NULL);
+       return tfrc_rx_hist_slab == NULL ? -ENOBUFS : 0;
 }
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_new);
+void tfrc_rx_packet_history_exit(void)
+{
+       if (tfrc_rx_hist_slab != NULL) {
+               kmem_cache_destroy(tfrc_rx_hist_slab);
+               tfrc_rx_hist_slab = NULL;
+       }
+}
 
-void dccp_rx_hist_delete(struct dccp_rx_hist *hist)
+static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *entry,
+                                              const struct sk_buff *skb,
+                                              const u32 ndp)
 {
-       const char* name = kmem_cache_name(hist->dccprxh_slab);
+       const struct dccp_hdr *dh = dccp_hdr(skb);
 
-       kmem_cache_destroy(hist->dccprxh_slab);
-       kfree(name);
-       kfree(hist);
+       entry->tfrchrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
+       entry->tfrchrx_ccval = dh->dccph_ccval;
+       entry->tfrchrx_type  = dh->dccph_type;
+       entry->tfrchrx_ndp   = ndp;
+       entry->tfrchrx_tstamp = ktime_get_real();
 }
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_delete);
+void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h,
+                            const struct sk_buff *skb,
+                            const u32 ndp)
+{
+       struct tfrc_rx_hist_entry *entry = tfrc_rx_hist_last_rcv(h);
+
+       tfrc_rx_hist_entry_from_skb(entry, skb, ndp);
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_add_packet);
 
-int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
-                           u8 *ccval)
+/* has the packet contained in skb been seen before? */
+int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb)
 {
-       struct dccp_rx_hist_entry *packet = NULL, *entry;
+       const u64 seq = DCCP_SKB_CB(skb)->dccpd_seq;
+       int i;
 
-       list_for_each_entry(entry, list, dccphrx_node)
-               if (entry->dccphrx_seqno == seq) {
-                       packet = entry;
-                       break;
-               }
+       if (dccp_delta_seqno(tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno, seq) <= 0)
+               return 1;
 
-       if (packet)
-               *ccval = packet->dccphrx_ccval;
+       for (i = 1; i <= h->loss_count; i++)
+               if (tfrc_rx_hist_entry(h, i)->tfrchrx_seqno == seq)
+                       return 1;
 
-       return packet != NULL;
+       return 0;
 }
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_duplicate);
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);
-struct dccp_rx_hist_entry *
-               dccp_rx_hist_find_data_packet(const struct list_head *list)
+static void tfrc_rx_hist_swap(struct tfrc_rx_hist *h, const u8 a, const u8 b)
 {
-       struct dccp_rx_hist_entry *entry, *packet = NULL;
-
-       list_for_each_entry(entry, list, dccphrx_node)
-               if (entry->dccphrx_type == DCCP_PKT_DATA ||
-                   entry->dccphrx_type == DCCP_PKT_DATAACK) {
-                       packet = entry;
-                       break;
-               }
+       const u8 idx_a = tfrc_rx_hist_index(h, a),
+                idx_b = tfrc_rx_hist_index(h, b);
+       struct tfrc_rx_hist_entry *tmp = h->ring[idx_a];
 
-       return packet;
+       h->ring[idx_a] = h->ring[idx_b];
+       h->ring[idx_b] = tmp;
 }
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_find_data_packet);
+/*
+ * Private helper functions for loss detection.
+ *
+ * In the descriptions, `Si' refers to the sequence number of entry number i,
+ * whose NDP count is `Ni' (lower case is used for variables).
+ * Note: All __after_loss functions expect that a test against duplicates has
+ *       been performed already: the seqno of the skb must not be less than the
+ *       seqno of loss_prev; and it must not equal that of any valid hist_entry.
+ */
+static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2)
+{
+       u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno,
+           s1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_seqno,
+           s2 = DCCP_SKB_CB(skb)->dccpd_seq;
+       int n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp,
+          d12 = dccp_delta_seqno(s1, s2), d2;
+
+       if (d12 > 0) {                  /* S1  <  S2 */
+               h->loss_count = 2;
+               tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 2), skb, n2);
+               return;
+       }
+
+       /* S0  <  S2  <  S1 */
+       d2 = dccp_delta_seqno(s0, s2);
 
-void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
-                           struct list_head *rx_list,
-                           struct list_head *li_list,
-                           struct dccp_rx_hist_entry *packet,
-                           u64 nonloss_seqno)
+       if (d2 == 1 || n2 >= d2) {      /* S2 is direct successor of S0 */
+               int d21 = -d12;
+
+               if (d21 == 1 || n1 >= d21) {
+                       /* hole is filled: S0, S2, and S1 are consecutive */
+                       h->loss_count = 0;
+                       h->loss_start = tfrc_rx_hist_index(h, 1);
+               } else
+                       /* gap between S2 and S1: just update loss_prev */
+                       tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_loss_prev(h), skb, n2);
+
+       } else {                        /* hole between S0 and S2 */
+               /*
+                * Reorder history to insert S2 between S0 and s1
+                */
+               tfrc_rx_hist_swap(h, 0, 3);
+               h->loss_start = tfrc_rx_hist_index(h, 3);
+               tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 1), skb, n2);
+               h->loss_count = 2;
+       }
+}
+
+/* return 1 if a new loss event has been identified */
+static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
 {
-       struct dccp_rx_hist_entry *entry, *next;
-       u8 num_later = 0;
-
-       list_add(&packet->dccphrx_node, rx_list);
-
-       num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
-
-       if (!list_empty(li_list)) {
-               list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {
-                       if (num_later == 0) {
-                               if (after48(nonloss_seqno,
-                                  entry->dccphrx_seqno)) {
-                                       list_del_init(&entry->dccphrx_node);
-                                       dccp_rx_hist_entry_delete(hist, entry);
-                               }
-                       } else if (dccp_rx_hist_entry_data_packet(entry))
-                               --num_later;
-               }
-       } else {
-               int step = 0;
-               u8 win_count = 0; /* Not needed, but lets shut up gcc */
-               int tmp;
+       u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno,
+           s1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_seqno,
+           s2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_seqno,
+           s3 = DCCP_SKB_CB(skb)->dccpd_seq;
+       int n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp,
+          d23 = dccp_delta_seqno(s2, s3), d13, d3, d31;
+
+       if (d23 > 0) {                  /* S2  <  S3 */
+               h->loss_count = 3;
+               tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 3), skb, n3);
+               return 1;
+       }
+
+       /* S3  <  S2 */
+       d13 = dccp_delta_seqno(s1, s3);
+
+       if (d13 > 0) {
                /*
-                * We have no loss interval history so we need at least one
-                * rtt:s of data packets to approximate rtt.
+                * The sequence number order is S1, S3, S2
+                * Reorder history to insert entry between S1 and S2
                 */
-               list_for_each_entry_safe(entry, next, rx_list, dccphrx_node) {
-                       if (num_later == 0) {
-                               switch (step) {
-                               case 0:
-                                       step = 1;
-                                       /* OK, find next data packet */
-                                       num_later = 1;
-                                       break;
-                               case 1:
-                                       step = 2;
-                                       /* OK, find next data packet */
-                                       num_later = 1;
-                                       win_count = entry->dccphrx_ccval;
-                                       break;
-                               case 2:
-                                       tmp = win_count - entry->dccphrx_ccval;
-                                       if (tmp < 0)
-                                               tmp += TFRC_WIN_COUNT_LIMIT;
-                                       if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
-                                               /*
-                                                * We have found a packet older
-                                                * than one rtt remove the rest
-                                                */
-                                               step = 3;
-                                       } else /* OK, find next data packet */
-                                               num_later = 1;
-                                       break;
-                               case 3:
-                                       list_del_init(&entry->dccphrx_node);
-                                       dccp_rx_hist_entry_delete(hist, entry);
-                                       break;
-                               }
-                       } else if (dccp_rx_hist_entry_data_packet(entry))
-                               --num_later;
+               tfrc_rx_hist_swap(h, 2, 3);
+               tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 2), skb, n3);
+               h->loss_count = 3;
+               return 1;
+       }
+
+       /* S0  <  S3  <  S1 */
+       d31 = -d13;
+       d3  = dccp_delta_seqno(s0, s3);
+
+       if (d3 == 1 || n3 >= d3) {      /* S3 is a successor of S0 */
+
+               if (d31 == 1 || n1 >= d31) {
+                       /* hole between S0 and S1 filled by S3 */
+                       int  d2 = dccp_delta_seqno(s1, s2),
+                            n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp;
+
+                       if (d2 == 1 || n2 >= d2) {
+                               /* entire hole filled by S0, S3, S1, S2 */
+                               h->loss_start = tfrc_rx_hist_index(h, 2);
+                               h->loss_count = 0;
+                       } else {
+                               /* gap remains between S1 and S2 */
+                               h->loss_start = tfrc_rx_hist_index(h, 1);
+                               h->loss_count = 1;
+                       }
+
+               } else /* gap exists between S3 and S1, loss_count stays at 2 */
+                       tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_loss_prev(h), skb, n3);
+
+               return 0;
+       }
+
+       /*
+        * The remaining case: S3 is not a successor of S0.
+        * Sequence order is S0, S3, S1, S2; reorder to insert between S0 and S1
+        */
+       tfrc_rx_hist_swap(h, 0, 3);
+       h->loss_start = tfrc_rx_hist_index(h, 3);
+       tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 1), skb, n3);
+       h->loss_count = 3;
+
+       return 1;
+}
+
+/* return the signed modulo-2^48 sequence number distance from entry e1 to e2 */
+static s64 tfrc_rx_hist_delta_seqno(struct tfrc_rx_hist *h, u8 e1, u8 e2)
+{
+       DCCP_BUG_ON(e1 > h->loss_count || e2 > h->loss_count);
+
+       return dccp_delta_seqno(tfrc_rx_hist_entry(h, e1)->tfrchrx_seqno,
+                               tfrc_rx_hist_entry(h, e2)->tfrchrx_seqno);
+}
+
+/* recycle RX history records to continue loss detection if necessary */
+static void __three_after_loss(struct tfrc_rx_hist *h)
+{
+       /*
+        * The distance between S0 and S1 is always greater than 1 and the NDP
+        * count of S1 is smaller than this distance. Otherwise there would
+        * have been no loss. Hence it is only necessary to see whether there
+        * are further missing data packets between S1/S2 and S2/S3.
+        */
+       int d2 = tfrc_rx_hist_delta_seqno(h, 1, 2),
+           d3 = tfrc_rx_hist_delta_seqno(h, 2, 3),
+           n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp,
+           n3 = tfrc_rx_hist_entry(h, 3)->tfrchrx_ndp;
+
+       if (d2 == 1 || n2 >= d2) {      /* S2 is successor to S1 */
+
+               if (d3 == 1 || n3 >= d3) {
+                       /* S3 is successor of S2: entire hole is filled */
+                       h->loss_start = tfrc_rx_hist_index(h, 3);
+                       h->loss_count = 0;
+               } else {
+                       /* gap between S2 and S3 */
+                       h->loss_start = tfrc_rx_hist_index(h, 2);
+                       h->loss_count = 1;
                }
+
+       } else {                        /* gap between S1 and S2 */
+               h->loss_start = tfrc_rx_hist_index(h, 1);
+               h->loss_count = 2;
        }
 }
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);
+/**
+ *  tfrc_rx_handle_loss  -  Loss detection and further processing
+ *  @h:                    The non-empty RX history object
+ *  @lh:           Loss Intervals database to update
+ *  @skb:          Currently received packet
+ *  @ndp:          The NDP count belonging to @skb
+ *  @calc_first_li: Caller-dependent computation of first loss interval in @lh
+ *  @sk:           Used by @calc_first_li (see tfrc_lh_interval_add)
+ *  Chooses action according to pending loss, updates LI database when a new
+ *  loss was detected, and does required post-processing. Returns 1 when caller
+ *  should send feedback, 0 otherwise.
+ */
+int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
+                       struct tfrc_loss_hist *lh,
+                       struct sk_buff *skb, u32 ndp,
+                       u32 (*calc_first_li)(struct sock *), struct sock *sk)
+{
+       int is_new_loss = 0;
 
-void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list)
+       if (h->loss_count == 1) {
+               __one_after_loss(h, skb, ndp);
+       } else if (h->loss_count != 2) {
+               DCCP_BUG("invalid loss_count %d", h->loss_count);
+       } else if (__two_after_loss(h, skb, ndp)) {
+               /*
+                * Update Loss Interval database and recycle RX records
+                */
+               is_new_loss = tfrc_lh_interval_add(lh, h, calc_first_li, sk);
+               __three_after_loss(h);
+       }
+       return is_new_loss;
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_handle_loss);
+
+int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h)
 {
-       struct dccp_rx_hist_entry *entry, *next;
+       int i;
+
+       for (i = 0; i <= TFRC_NDUPACK; i++) {
+               h->ring[i] = kmem_cache_alloc(tfrc_rx_hist_slab, GFP_ATOMIC);
+               if (h->ring[i] == NULL)
+                       goto out_free;
+       }
+
+       h->loss_count = h->loss_start = 0;
+       return 0;
 
-       list_for_each_entry_safe(entry, next, list, dccphrx_node) {
-               list_del_init(&entry->dccphrx_node);
-               kmem_cache_free(hist->dccprxh_slab, entry);
+out_free:
+       while (i-- != 0) {
+               kmem_cache_free(tfrc_rx_hist_slab, h->ring[i]);
+               h->ring[i] = NULL;
        }
+       return -ENOBUFS;
 }
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_alloc);
+
+void tfrc_rx_hist_purge(struct tfrc_rx_hist *h)
+{
+       int i;
 
-EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
+       for (i = 0; i <= TFRC_NDUPACK; ++i)
+               if (h->ring[i] != NULL) {
+                       kmem_cache_free(tfrc_rx_hist_slab, h->ring[i]);
+                       h->ring[i] = NULL;
+               }
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_purge);
 
+/**
+ * tfrc_rx_hist_rtt_last_s - reference entry to compute RTT samples against
+ */
+static inline struct tfrc_rx_hist_entry *
+                       tfrc_rx_hist_rtt_last_s(const struct tfrc_rx_hist *h)
+{
+       return h->ring[0];
+}
 
-MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
-             "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
-MODULE_DESCRIPTION("DCCP TFRC library");
-MODULE_LICENSE("GPL");
+/**
+ * tfrc_rx_hist_rtt_prev_s: previously suitable (wrt rtt_last_s) RTT-sampling entry
+ */
+static inline struct tfrc_rx_hist_entry *
+                       tfrc_rx_hist_rtt_prev_s(const struct tfrc_rx_hist *h)
+{
+       return h->ring[h->rtt_sample_prev];
+}
+
+/**
+ * tfrc_rx_hist_sample_rtt  -  Sample RTT from timestamp / CCVal
+ * Based on ideas presented in RFC 4342, 8.1. Returns 0 if it was not able
+ * to compute a sample with given data - calling function should check this.
+ */
+u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h, const struct sk_buff *skb)
+{
+       u32 sample = 0,
+           delta_v = SUB16(dccp_hdr(skb)->dccph_ccval,
+                           tfrc_rx_hist_rtt_last_s(h)->tfrchrx_ccval);
+
+       if (delta_v < 1 || delta_v > 4) {       /* unsuitable CCVal delta */
+               if (h->rtt_sample_prev == 2) {  /* previous candidate stored */
+                       sample = SUB16(tfrc_rx_hist_rtt_prev_s(h)->tfrchrx_ccval,
+                                      tfrc_rx_hist_rtt_last_s(h)->tfrchrx_ccval);
+                       if (sample)
+                               sample = 4 / sample *
+                                        ktime_us_delta(tfrc_rx_hist_rtt_prev_s(h)->tfrchrx_tstamp,
+                                                       tfrc_rx_hist_rtt_last_s(h)->tfrchrx_tstamp);
+                       else    /*
+                                * FIXME: This condition is in principle not
+                                * possible but occurs when CCID is used for
+                                * two-way data traffic. I have tried to trace
+                                * it, but the cause does not seem to be here.
+                                */
+                               DCCP_BUG("please report to dccp@vger.kernel.org"
+                                        " => prev = %u, last = %u",
+                                        tfrc_rx_hist_rtt_prev_s(h)->tfrchrx_ccval,
+                                        tfrc_rx_hist_rtt_last_s(h)->tfrchrx_ccval);
+               } else if (delta_v < 1) {
+                       h->rtt_sample_prev = 1;
+                       goto keep_ref_for_next_time;
+               }
+
+       } else if (delta_v == 4) /* optimal match */
+               sample = ktime_to_us(net_timedelta(tfrc_rx_hist_rtt_last_s(h)->tfrchrx_tstamp));
+       else {                   /* suboptimal match */
+               h->rtt_sample_prev = 2;
+               goto keep_ref_for_next_time;
+       }
+
+       if (unlikely(sample > DCCP_SANE_RTT_MAX)) {
+               DCCP_WARN("RTT sample %u too large, using max\n", sample);
+               sample = DCCP_SANE_RTT_MAX;
+       }
+
+       h->rtt_sample_prev = 0;        /* use current entry as next reference */
+keep_ref_for_next_time:
+
+       return sample;
+}
+EXPORT_SYMBOL_GPL(tfrc_rx_hist_sample_rtt);
index 032bb61c6e39f833ddd8d9a525dd90921fc22a16..c7eeda49cb20aae104fe3026d871e269a75bc848 100644 (file)
@@ -1,10 +1,9 @@
 /*
- *  net/dccp/packet_history.h
+ *  Packet RX/TX history data structures and routines for TFRC-based protocols.
  *
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
  *
- *  An implementation of the DCCP protocol
- *
  *  This code has been developed by the University of Waikato WAND
  *  research group. For further information please see http://www.wand.net.nz/
  *  or e-mail Ian McDonald - ian.mcdonald@jandi.co.nz
 #ifndef _DCCP_PKT_HIST_
 #define _DCCP_PKT_HIST_
 
-#include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/slab.h>
+#include "tfrc.h"
 
-#include "../../dccp.h"
+struct tfrc_tx_hist_entry;
 
-/* Number of later packets received before one is considered lost */
-#define TFRC_RECV_NUM_LATE_LOSS         3
+extern int  tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno);
+extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp);
+extern u32  tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head,
+                            const u64 seqno, const ktime_t now);
 
-#define TFRC_WIN_COUNT_PER_RTT  4
-#define TFRC_WIN_COUNT_LIMIT   16
+/* Subtraction a-b modulo-16, respects circular wrap-around */
+#define SUB16(a, b) (((a) + 16 - (b)) & 0xF)
 
-/*
- *     Transmitter History data structures and declarations
+/* Number of packets to wait after a missing packet (RFC 4342, 6.1) */
+#define TFRC_NDUPACK 3
+
+/**
+ * tfrc_rx_hist_entry - Store information about a single received packet
+ * @tfrchrx_seqno:     DCCP packet sequence number
+ * @tfrchrx_ccval:     window counter value of packet (RFC 4342, 8.1)
+ * @tfrchrx_ndp:       the NDP count (if any) of the packet
+ * @tfrchrx_tstamp:    actual receive time of packet
  */
-struct dccp_tx_hist_entry {
-       struct list_head dccphtx_node;
-       u64              dccphtx_seqno:48,
-                        dccphtx_sent:1;
-       u32              dccphtx_rtt;
-       ktime_t          dccphtx_tstamp;
+struct tfrc_rx_hist_entry {
+       u64              tfrchrx_seqno:48,
+                        tfrchrx_ccval:4,
+                        tfrchrx_type:4;
+       u32              tfrchrx_ndp; /* In fact it is from 8 to 24 bits */
+       ktime_t          tfrchrx_tstamp;
 };
 
-struct dccp_tx_hist {
-       struct kmem_cache *dccptxh_slab;
+/**
+ * tfrc_rx_hist  -  RX history structure for TFRC-based protocols
+ *
+ * @ring:              Packet history for RTT sampling and loss detection
+ * @loss_count:                Number of entries in circular history
+ * @loss_start:                Movable index (for loss detection)
+ * @rtt_sample_prev:   Used during RTT sampling, points to candidate entry
+ */
+struct tfrc_rx_hist {
+       struct tfrc_rx_hist_entry *ring[TFRC_NDUPACK + 1];
+       u8                        loss_count:2,
+                                 loss_start:2;
+#define rtt_sample_prev                  loss_start
 };
 
-extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name);
-extern void                dccp_tx_hist_delete(struct dccp_tx_hist *hist);
-
-static inline struct dccp_tx_hist_entry *
-                       dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
-                                              const gfp_t prio)
+/**
+ * tfrc_rx_hist_index - index to reach n-th entry after loss_start
+ */
+static inline u8 tfrc_rx_hist_index(const struct tfrc_rx_hist *h, const u8 n)
 {
-       struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
-                                                           prio);
-
-       if (entry != NULL)
-               entry->dccphtx_sent = 0;
-
-       return entry;
+       return (h->loss_start + n) & TFRC_NDUPACK;
 }
 
-static inline struct dccp_tx_hist_entry *
-                       dccp_tx_hist_head(struct list_head *list)
+/**
+ * tfrc_rx_hist_last_rcv - entry with highest-received-seqno so far
+ */
+static inline struct tfrc_rx_hist_entry *
+                       tfrc_rx_hist_last_rcv(const struct tfrc_rx_hist *h)
 {
-       struct dccp_tx_hist_entry *head = NULL;
-
-       if (!list_empty(list))
-               head = list_entry(list->next, struct dccp_tx_hist_entry,
-                                 dccphtx_node);
-       return head;
+       return h->ring[tfrc_rx_hist_index(h, h->loss_count)];
 }
 
-extern struct dccp_tx_hist_entry *
-                       dccp_tx_hist_find_entry(const struct list_head *list,
-                                               const u64 seq);
-
-static inline void dccp_tx_hist_add_entry(struct list_head *list,
-                                         struct dccp_tx_hist_entry *entry)
+/**
+ * tfrc_rx_hist_entry - return the n-th history entry after loss_start
+ */
+static inline struct tfrc_rx_hist_entry *
+                       tfrc_rx_hist_entry(const struct tfrc_rx_hist *h, const u8 n)
 {
-       list_add(&entry->dccphtx_node, list);
+       return h->ring[tfrc_rx_hist_index(h, n)];
 }
 
-static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist,
-                                            struct dccp_tx_hist_entry *entry)
+/**
+ * tfrc_rx_hist_loss_prev - entry with highest-received-seqno before loss was detected
+ */
+static inline struct tfrc_rx_hist_entry *
+                       tfrc_rx_hist_loss_prev(const struct tfrc_rx_hist *h)
 {
-       if (entry != NULL)
-               kmem_cache_free(hist->dccptxh_slab, entry);
+       return h->ring[h->loss_start];
 }
 
-extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist,
-                              struct list_head *list);
-
-extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
-                                    struct list_head *list,
-                                    struct dccp_tx_hist_entry *next);
-
-/*
- *     Receiver History data structures and declarations
- */
-struct dccp_rx_hist_entry {
-       struct list_head dccphrx_node;
-       u64              dccphrx_seqno:48,
-                        dccphrx_ccval:4,
-                        dccphrx_type:4;
-       u32              dccphrx_ndp; /* In fact it is from 8 to 24 bits */
-       ktime_t          dccphrx_tstamp;
-};
-
-struct dccp_rx_hist {
-       struct kmem_cache *dccprxh_slab;
-};
-
-extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
-extern void            dccp_rx_hist_delete(struct dccp_rx_hist *hist);
-
-static inline struct dccp_rx_hist_entry *
-                       dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
-                                              const u32 ndp,
-                                              const struct sk_buff *skb,
-                                              const gfp_t prio)
+/* initialise loss detection and disable RTT sampling */
+static inline void tfrc_rx_hist_loss_indicated(struct tfrc_rx_hist *h)
 {
-       struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
-                                                           prio);
-
-       if (entry != NULL) {
-               const struct dccp_hdr *dh = dccp_hdr(skb);
-
-               entry->dccphrx_seqno = DCCP_SKB_CB(skb)->dccpd_seq;
-               entry->dccphrx_ccval = dh->dccph_ccval;
-               entry->dccphrx_type  = dh->dccph_type;
-               entry->dccphrx_ndp   = ndp;
-               entry->dccphrx_tstamp = ktime_get_real();
-       }
-
-       return entry;
+       h->loss_count = 1;
 }
 
-static inline struct dccp_rx_hist_entry *
-                       dccp_rx_hist_head(struct list_head *list)
+/* indicate whether previously a packet was detected missing */
+static inline int tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h)
 {
-       struct dccp_rx_hist_entry *head = NULL;
-
-       if (!list_empty(list))
-               head = list_entry(list->next, struct dccp_rx_hist_entry,
-                                 dccphrx_node);
-       return head;
+       return h->loss_count;
 }
 
-extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
-                                  u8 *ccval);
-extern struct dccp_rx_hist_entry *
-               dccp_rx_hist_find_data_packet(const struct list_head *list);
-
-extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
-                                   struct list_head *rx_list,
-                                   struct list_head *li_list,
-                                   struct dccp_rx_hist_entry *packet,
-                                   u64 nonloss_seqno);
-
-static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
-                                            struct dccp_rx_hist_entry *entry)
+/* any data packets missing between last reception and skb ? */
+static inline int tfrc_rx_hist_new_loss_indicated(struct tfrc_rx_hist *h,
+                                                 const struct sk_buff *skb,
+                                                 u32 ndp)
 {
-       if (entry != NULL)
-               kmem_cache_free(hist->dccprxh_slab, entry);
-}
+       int delta = dccp_delta_seqno(tfrc_rx_hist_last_rcv(h)->tfrchrx_seqno,
+                                    DCCP_SKB_CB(skb)->dccpd_seq);
 
-extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
-                              struct list_head *list);
+       if (delta > 1 && ndp < delta)
+               tfrc_rx_hist_loss_indicated(h);
 
-static inline int
-       dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
-{
-       return entry->dccphrx_type == DCCP_PKT_DATA ||
-              entry->dccphrx_type == DCCP_PKT_DATAACK;
+       return tfrc_rx_hist_loss_pending(h);
 }
 
-extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
-                                   struct list_head *li_list, u8 *win_loss);
+extern void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h,
+                                   const struct sk_buff *skb, const u32 ndp);
+
+extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb);
+
+struct tfrc_loss_hist;
+extern int  tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
+                               struct tfrc_loss_hist *lh,
+                               struct sk_buff *skb, u32 ndp,
+                               u32 (*first_li)(struct sock *sk),
+                               struct sock *sk);
+extern u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h,
+                                  const struct sk_buff *skb);
+extern int tfrc_rx_hist_alloc(struct tfrc_rx_hist *h);
+extern void tfrc_rx_hist_purge(struct tfrc_rx_hist *h);
 
 #endif /* _DCCP_PKT_HIST_ */
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c
new file mode 100644 (file)
index 0000000..d1dfbb8
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * TFRC: main module holding the pieces of the TFRC library together
+ *
+ * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
+ * Copyright (c) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include "tfrc.h"
+
+#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
+int tfrc_debug;
+module_param(tfrc_debug, bool, 0444);
+MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
+#endif
+
+extern int  tfrc_tx_packet_history_init(void);
+extern void tfrc_tx_packet_history_exit(void);
+extern int  tfrc_rx_packet_history_init(void);
+extern void tfrc_rx_packet_history_exit(void);
+
+extern int  tfrc_li_init(void);
+extern void tfrc_li_exit(void);
+
+static int __init tfrc_module_init(void)
+{
+       int rc = tfrc_li_init();
+
+       if (rc)
+               goto out;
+
+       rc = tfrc_tx_packet_history_init();
+       if (rc)
+               goto out_free_loss_intervals;
+
+       rc = tfrc_rx_packet_history_init();
+       if (rc)
+               goto out_free_tx_history;
+       return 0;
+
+out_free_tx_history:
+       tfrc_tx_packet_history_exit();
+out_free_loss_intervals:
+       tfrc_li_exit();
+out:
+       return rc;
+}
+
+static void __exit tfrc_module_exit(void)
+{
+       tfrc_rx_packet_history_exit();
+       tfrc_tx_packet_history_exit();
+       tfrc_li_exit();
+}
+
+module_init(tfrc_module_init);
+module_exit(tfrc_module_exit);
+
+MODULE_AUTHOR("Gerrit Renker <gerrit@erg.abdn.ac.uk>, "
+             "Ian McDonald <ian.mcdonald@jandi.co.nz>, "
+             "Arnaldo Carvalho de Melo <acme@redhat.com>");
+MODULE_DESCRIPTION("DCCP TFRC library");
+MODULE_LICENSE("GPL");
index faf5f7e219e36a85ecdfdf182e81ba8e6b7ef4af..1fb1187bbf1ca818a133fe476e5cb3781bbd3818 100644 (file)
@@ -3,10 +3,11 @@
 /*
  *  net/dccp/ccids/lib/tfrc.h
  *
- *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
- *  Copyright (c) 2005 Ian McDonald <ian.mcdonald@jandi.co.nz>
- *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
+ *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
+ *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
+ *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
+ *  Copyright (c) 2005   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *  Copyright (c) 2003   Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
  *
  *  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 <asm/div64.h>
+#include "../../dccp.h"
+/* internal includes that this module exports: */
+#include "loss_interval.h"
+#include "packet_history.h"
+
+#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
+extern int tfrc_debug;
+#define tfrc_pr_debug(format, a...)    DCCP_PR_DEBUG(tfrc_debug, format, ##a)
+#else
+#define tfrc_pr_debug(format, a...)
+#endif
 
 /* integer-arithmetic divisions of type (a * 1000000)/b */
 static inline u64 scaled_div(u64 a, u32 b)
@@ -37,6 +49,15 @@ static inline u32 scaled_div32(u64 a, u32 b)
        return result;
 }
 
+/**
+ * tfrc_ewma  -  Exponentially weighted moving average
+ * @weight: Weight to be used as damping factor, in units of 1/10
+ */
+static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
+{
+       return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval;
+}
+
 extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
 extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
 
index ee97950d77d1993bdc53ddb1609bbd804342b150..ebe59d98721a58a934b89ca1143c96b45d3dec9a 100644 (file)
@@ -72,11 +72,21 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);
 /* RFC 1122, 4.2.3.1 initial RTO value */
 #define DCCP_TIMEOUT_INIT ((unsigned)(3 * HZ))
 
-#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
+/*
+ * The maximum back-off value for retransmissions. This is needed for
+ *  - retransmitting client-Requests (sec. 8.1.1),
+ *  - retransmitting Close/CloseReq when closing (sec. 8.3),
+ *  - feature-negotiation retransmission (sec. 6.6.3),
+ *  - Acks in client-PARTOPEN state (sec. 8.1.5).
+ */
+#define DCCP_RTO_MAX ((unsigned)(64 * HZ))
 
-/* bounds for sampled RTT values from packet exchanges (in usec) */
+/*
+ * RTT sampling: sanity bounds and fallback RTT value from RFC 4340, section 3.4
+ */
 #define DCCP_SANE_RTT_MIN      100
-#define DCCP_SANE_RTT_MAX      (4 * USEC_PER_SEC)
+#define DCCP_FALLBACK_RTT      (USEC_PER_SEC / 5)
+#define DCCP_SANE_RTT_MAX      (3 * USEC_PER_SEC)
 
 /* Maximal interval between probes for local resources.  */
 #define DCCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ / 2U))
@@ -143,12 +153,6 @@ static inline u64 max48(const u64 seq1, const u64 seq2)
        return after48(seq1, seq2) ? seq1 : seq2;
 }
 
-/* is seq1 next seqno after seq2 */
-static inline int follows48(const u64 seq1, const u64 seq2)
-{
-       return dccp_delta_seqno(seq2, seq1) == 1;
-}
-
 enum {
        DCCP_MIB_NUM = 0,
        DCCP_MIB_ACTIVEOPENS,                   /* ActiveOpens */
@@ -334,6 +338,7 @@ struct dccp_skb_cb {
 
 #define DCCP_SKB_CB(__skb) ((struct dccp_skb_cb *)&((__skb)->cb[0]))
 
+/* RFC 4340, sec. 7.7 */
 static inline int dccp_non_data_packet(const struct sk_buff *skb)
 {
        const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
@@ -346,6 +351,17 @@ static inline int dccp_non_data_packet(const struct sk_buff *skb)
               type == DCCP_PKT_SYNCACK;
 }
 
+/* RFC 4340, sec. 7.7 */
+static inline int dccp_data_packet(const struct sk_buff *skb)
+{
+       const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
+
+       return type == DCCP_PKT_DATA     ||
+              type == DCCP_PKT_DATAACK  ||
+              type == DCCP_PKT_REQUEST  ||
+              type == DCCP_PKT_RESPONSE;
+}
+
 static inline int dccp_packet_without_ack(const struct sk_buff *skb)
 {
        const __u8 type = DCCP_SKB_CB(skb)->dccpd_type;
@@ -406,6 +422,7 @@ static inline int dccp_ack_pending(const struct sock *sk)
 }
 
 extern int dccp_insert_options(struct sock *sk, struct sk_buff *skb);
+extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*);
 extern int dccp_insert_option_elapsed_time(struct sock *sk,
                                            struct sk_buff *skb,
                                            u32 elapsed_time);
index 5ebdd86c1b99f34ae2c86c36e8cbda2b23fed0cc..4a4f6ce4498d42c77dde9b7a5867575210931b31 100644 (file)
@@ -4,10 +4,16 @@
  *  An implementation of the DCCP protocol
  *  Andrea Bittau <a.bittau@cs.ucl.ac.uk>
  *
- *      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.
+ *  ASSUMPTIONS
+ *  -----------
+ *  o All currently known SP features have 1-byte quantities. If in the future
+ *    extensions of RFCs 4340..42 define features with item lengths larger than
+ *    one byte, a feature-specific extension of the code will be required.
+ *
+ *  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/module.h>
@@ -24,11 +30,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
 
        dccp_feat_debug(type, feature, *val);
 
-       if (!dccp_feat_is_valid_type(type)) {
-               DCCP_WARN("option type %d invalid in negotiation\n", type);
-               return 1;
-       }
-       if (!dccp_feat_is_valid_length(type, feature, len)) {
+       if (len > 3) {
                DCCP_WARN("invalid length %d\n", len);
                return 1;
        }
@@ -99,7 +101,6 @@ static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
        return 0;
 }
 
-/* XXX taking only u8 vals */
 static int dccp_feat_update(struct sock *sk, u8 type, u8 feat, u8 val)
 {
        dccp_feat_debug(type, feat, val);
@@ -144,7 +145,6 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
        /* FIXME sanity check vals */
 
        /* Are values in any order?  XXX Lame "algorithm" here */
-       /* XXX assume values are 1 byte */
        for (i = 0; i < slen; i++) {
                for (j = 0; j < rlen; j++) {
                        if (spref[i] == rpref[j]) {
@@ -179,7 +179,6 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
        }
 
        /* need to put result and our preference list */
-       /* XXX assume 1 byte vals */
        rlen = 1 + opt->dccpop_len;
        rpref = kmalloc(rlen, GFP_ATOMIC);
        if (rpref == NULL)
@@ -637,12 +636,12 @@ const char *dccp_feat_name(const u8 feat)
                [DCCPF_MIN_CSUM_COVER]  = "Min. Csum Coverage",
                [DCCPF_DATA_CHECKSUM]   = "Send Data Checksum",
        };
+       if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
+               return feature_names[DCCPF_RESERVED];
+
        if (feat >= DCCPF_MIN_CCID_SPECIFIC)
                return "CCID-specific";
 
-       if (dccp_feat_is_reserved(feat))
-               return feature_names[DCCPF_RESERVED];
-
        return feature_names[feat];
 }
 
index 177f7dee4d101bf3a5963b0cd61d03cc1c605552..e272222c7ace353951cf5cade968a54663a5e443 100644 (file)
 #include <linux/types.h>
 #include "dccp.h"
 
-static inline int dccp_feat_is_valid_length(u8 type, u8 feature, u8 len)
-{
-       /* sec. 6.1: Confirm has at least length 3,
-        * sec. 6.2: Change  has at least length 4 */
-       if (len < 3)
-               return 1;
-       if (len < 4  && (type == DCCPO_CHANGE_L || type == DCCPO_CHANGE_R))
-               return 1;
-       /* XXX: add per-feature length validation (sec. 6.6.8) */
-       return 0;
-}
-
-static inline int dccp_feat_is_reserved(const u8 feat)
-{
-       return (feat > DCCPF_DATA_CHECKSUM &&
-               feat < DCCPF_MIN_CCID_SPECIFIC) ||
-               feat == DCCPF_RESERVED;
-}
-
-/* feature negotiation knows only these four option types (RFC 4340, sec. 6) */
-static inline int dccp_feat_is_valid_type(const u8 optnum)
-{
-       return optnum >= DCCPO_CHANGE_L && optnum <= DCCPO_CONFIRM_R;
-
-}
-
 #ifdef CONFIG_IP_DCCP_DEBUG
 extern const char *dccp_feat_typename(const u8 type);
 extern const char *dccp_feat_name(const u8 feat);
index 1ce101062824ef25fca9280889a572ae2c62408b..08392ed86c25403ea574c1e2b39786b8488e4625 100644 (file)
 /* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */
 int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8;
 
-static void dccp_fin(struct sock *sk, struct sk_buff *skb)
+static void dccp_enqueue_skb(struct sock *sk, struct sk_buff *skb)
 {
-       sk->sk_shutdown |= RCV_SHUTDOWN;
-       sock_set_flag(sk, SOCK_DONE);
        __skb_pull(skb, dccp_hdr(skb)->dccph_doff * 4);
        __skb_queue_tail(&sk->sk_receive_queue, skb);
        skb_set_owner_r(skb, sk);
        sk->sk_data_ready(sk, 0);
 }
 
-static void dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
+static void dccp_fin(struct sock *sk, struct sk_buff *skb)
 {
-       dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
-       dccp_fin(sk, skb);
-       dccp_set_state(sk, DCCP_CLOSED);
-       sk_wake_async(sk, 1, POLL_HUP);
+       /*
+        * On receiving Close/CloseReq, both RD/WR shutdown are performed.
+        * RFC 4340, 8.3 says that we MAY send further Data/DataAcks after
+        * receiving the closing segment, but there is no guarantee that such
+        * data will be processed at all.
+        */
+       sk->sk_shutdown = SHUTDOWN_MASK;
+       sock_set_flag(sk, SOCK_DONE);
+       dccp_enqueue_skb(sk, skb);
+}
+
+static int dccp_rcv_close(struct sock *sk, struct sk_buff *skb)
+{
+       int queued = 0;
+
+       switch (sk->sk_state) {
+       /*
+        * We ignore Close when received in one of the following states:
+        *  - CLOSED            (may be a late or duplicate packet)
+        *  - PASSIVE_CLOSEREQ  (the peer has sent a CloseReq earlier)
+        *  - RESPOND           (already handled by dccp_check_req)
+        */
+       case DCCP_CLOSING:
+               /*
+                * Simultaneous-close: receiving a Close after sending one. This
+                * can happen if both client and server perform active-close and
+                * will result in an endless ping-pong of crossing and retrans-
+                * mitted Close packets, which only terminates when one of the
+                * nodes times out (min. 64 seconds). Quicker convergence can be
+                * achieved when one of the nodes acts as tie-breaker.
+                * This is ok as both ends are done with data transfer and each
+                * end is just waiting for the other to acknowledge termination.
+                */
+               if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT)
+                       break;
+               /* fall through */
+       case DCCP_REQUESTING:
+       case DCCP_ACTIVE_CLOSEREQ:
+               dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
+               dccp_done(sk);
+               break;
+       case DCCP_OPEN:
+       case DCCP_PARTOPEN:
+               /* Give waiting application a chance to read pending data */
+               queued = 1;
+               dccp_fin(sk, skb);
+               dccp_set_state(sk, DCCP_PASSIVE_CLOSE);
+               /* fall through */
+       case DCCP_PASSIVE_CLOSE:
+               /*
+                * Retransmitted Close: we have already enqueued the first one.
+                */
+               sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP);
+       }
+       return queued;
 }
 
-static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
+static int dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
 {
+       int queued = 0;
+
        /*
         *   Step 7: Check for unexpected packet types
         *      If (S.is_server and P.type == CloseReq)
@@ -50,12 +101,26 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
         */
        if (dccp_sk(sk)->dccps_role != DCCP_ROLE_CLIENT) {
                dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
-               return;
+               return queued;
        }
 
-       if (sk->sk_state != DCCP_CLOSING)
+       /* Step 13: process relevant Client states < CLOSEREQ */
+       switch (sk->sk_state) {
+       case DCCP_REQUESTING:
+               dccp_send_close(sk, 0);
                dccp_set_state(sk, DCCP_CLOSING);
-       dccp_send_close(sk, 0);
+               break;
+       case DCCP_OPEN:
+       case DCCP_PARTOPEN:
+               /* Give waiting application a chance to read pending data */
+               queued = 1;
+               dccp_fin(sk, skb);
+               dccp_set_state(sk, DCCP_PASSIVE_CLOSEREQ);
+               /* fall through */
+       case DCCP_PASSIVE_CLOSEREQ:
+               sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP);
+       }
+       return queued;
 }
 
 static u8 dccp_reset_code_convert(const u8 code)
@@ -90,7 +155,7 @@ static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
        dccp_fin(sk, skb);
 
        if (err && !sock_flag(sk, SOCK_DEAD))
-               sk_wake_async(sk, 0, POLL_ERR);
+               sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
        dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
 }
 
@@ -103,6 +168,21 @@ static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
                                            DCCP_SKB_CB(skb)->dccpd_ack_seq);
 }
 
+static void dccp_deliver_input_to_ccids(struct sock *sk, struct sk_buff *skb)
+{
+       const struct dccp_sock *dp = dccp_sk(sk);
+
+       /* Don't deliver to RX CCID when node has shut down read end. */
+       if (!(sk->sk_shutdown & RCV_SHUTDOWN))
+               ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+       /*
+        * Until the TX queue has been drained, we can not honour SHUT_WR, since
+        * we need received feedback as input to adjust congestion control.
+        */
+       if (sk->sk_write_queue.qlen > 0 || !(sk->sk_shutdown & SEND_SHUTDOWN))
+               ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+}
+
 static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
 {
        const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -209,13 +289,11 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
        case DCCP_PKT_DATAACK:
        case DCCP_PKT_DATA:
                /*
-                * FIXME: check if sk_receive_queue is full, schedule DATA_DROPPED
-                * option if it is.
+                * FIXME: schedule DATA_DROPPED (RFC 4340, 11.7.2) if and when
+                * - sk_shutdown == RCV_SHUTDOWN, use Code 1, "Not Listening"
+                * - sk_receive_queue is full, use Code 2, "Receive Buffer"
                 */
-               __skb_pull(skb, dh->dccph_doff * 4);
-               __skb_queue_tail(&sk->sk_receive_queue, skb);
-               skb_set_owner_r(skb, sk);
-               sk->sk_data_ready(sk, 0);
+               dccp_enqueue_skb(sk, skb);
                return 0;
        case DCCP_PKT_ACK:
                goto discard;
@@ -231,11 +309,13 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
                dccp_rcv_reset(sk, skb);
                return 0;
        case DCCP_PKT_CLOSEREQ:
-               dccp_rcv_closereq(sk, skb);
+               if (dccp_rcv_closereq(sk, skb))
+                       return 0;
                goto discard;
        case DCCP_PKT_CLOSE:
-               dccp_rcv_close(sk, skb);
-               return 0;
+               if (dccp_rcv_close(sk, skb))
+                       return 0;
+               goto discard;
        case DCCP_PKT_REQUEST:
                /* Step 7
                 *   or (S.is_server and P.type == Response)
@@ -289,7 +369,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
        if (dccp_check_seqno(sk, skb))
                goto discard;
 
-       if (dccp_parse_options(sk, skb))
+       if (dccp_parse_options(sk, NULL, skb))
                goto discard;
 
        if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
@@ -300,9 +380,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
                            DCCP_SKB_CB(skb)->dccpd_seq,
                            DCCP_ACKVEC_STATE_RECEIVED))
                goto discard;
-
-       ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-       ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+       dccp_deliver_input_to_ccids(sk, skb);
 
        return __dccp_rcv_established(sk, skb, dh, len);
 discard:
@@ -349,7 +427,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                        goto out_invalid_packet;
                }
 
-               if (dccp_parse_options(sk, skb))
+               if (dccp_parse_options(sk, NULL, skb))
                        goto out_invalid_packet;
 
                /* Obtain usec RTT sample from SYN exchange (used by CCID 3) */
@@ -402,7 +480,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
 
                if (!sock_flag(sk, SOCK_DEAD)) {
                        sk->sk_state_change(sk);
-                       sk_wake_async(sk, 0, POLL_OUT);
+                       sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
                }
 
                if (sk->sk_write_pending || icsk->icsk_ack.pingpong ||
@@ -531,7 +609,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                /*
                 * Step 8: Process options and mark acknowledgeable
                 */
-               if (dccp_parse_options(sk, skb))
+               if (dccp_parse_options(sk, NULL, skb))
                        goto discard;
 
                if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
@@ -543,8 +621,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                                    DCCP_ACKVEC_STATE_RECEIVED))
                        goto discard;
 
-               ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-               ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+               dccp_deliver_input_to_ccids(sk, skb);
        }
 
        /*
@@ -560,16 +637,14 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                return 0;
                /*
                 *   Step 7: Check for unexpected packet types
-                *      If (S.is_server and P.type == CloseReq)
-                *          or (S.is_server and P.type == Response)
+                *      If (S.is_server and P.type == Response)
                 *          or (S.is_client and P.type == Request)
                 *          or (S.state == RESPOND and P.type == Data),
                 *        Send Sync packet acknowledging P.seqno
                 *        Drop packet and return
                 */
        } else if ((dp->dccps_role != DCCP_ROLE_CLIENT &&
-                   (dh->dccph_type == DCCP_PKT_RESPONSE ||
-                    dh->dccph_type == DCCP_PKT_CLOSEREQ)) ||
+                   dh->dccph_type == DCCP_PKT_RESPONSE) ||
                    (dp->dccps_role == DCCP_ROLE_CLIENT &&
                     dh->dccph_type == DCCP_PKT_REQUEST) ||
                    (sk->sk_state == DCCP_RESPOND &&
@@ -577,11 +652,13 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                dccp_send_sync(sk, dcb->dccpd_seq, DCCP_PKT_SYNC);
                goto discard;
        } else if (dh->dccph_type == DCCP_PKT_CLOSEREQ) {
-               dccp_rcv_closereq(sk, skb);
+               if (dccp_rcv_closereq(sk, skb))
+                       return 0;
                goto discard;
        } else if (dh->dccph_type == DCCP_PKT_CLOSE) {
-               dccp_rcv_close(sk, skb);
-               return 0;
+               if (dccp_rcv_close(sk, skb))
+                       return 0;
+               goto discard;
        }
 
        switch (sk->sk_state) {
@@ -611,7 +688,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                switch (old_state) {
                case DCCP_PARTOPEN:
                        sk->sk_state_change(sk);
-                       sk_wake_async(sk, 0, POLL_OUT);
+                       sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
                        break;
                }
        } else if (unlikely(dh->dccph_type == DCCP_PKT_SYNC)) {
index db17b83e8d3e85b267ed1bd352338ad64119f9df..9e38b0d6195ce637355762471cb988e8ea4527fa 100644 (file)
@@ -408,7 +408,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
 
        dccp_sync_mss(newsk, dst_mtu(dst));
 
-       __inet_hash(&dccp_hashinfo, newsk, 0);
+       __inet_hash_nolisten(&dccp_hashinfo, newsk);
        __inet_inherit_port(&dccp_hashinfo, sk, newsk);
 
        return newsk;
@@ -469,7 +469,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
                          };
 
        security_skb_classify_flow(skb, &fl);
-       if (ip_route_output_flow(&rt, &fl, sk, 0)) {
+       if (ip_route_output_flow(&init_net, &rt, &fl, sk, 0)) {
                IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return NULL;
        }
@@ -600,11 +600,12 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        if (req == NULL)
                goto drop;
 
-       if (dccp_parse_options(sk, skb))
-               goto drop_and_free;
-
        dccp_reqsk_init(req, skb);
 
+       dreq = dccp_rsk(req);
+       if (dccp_parse_options(sk, dreq, skb))
+               goto drop_and_free;
+
        if (security_inet_conn_request(sk, skb, req))
                goto drop_and_free;
 
@@ -621,7 +622,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
         * In fact we defer setting S.GSR, S.SWL, S.SWH to
         * dccp_create_openreq_child.
         */
-       dreq = dccp_rsk(req);
        dreq->dreq_isr     = dcb->dccpd_seq;
        dreq->dreq_iss     = dccp_v4_init_sequence(skb);
        dreq->dreq_service = service;
index 87c98fb86fa89311fb33863102875f5d853a94cf..f42b75ce7f5ce3c0065cb6b987f291d8bf32a99e 100644 (file)
@@ -415,11 +415,12 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        if (req == NULL)
                goto drop;
 
-       if (dccp_parse_options(sk, skb))
-               goto drop_and_free;
-
        dccp_reqsk_init(req, skb);
 
+       dreq = dccp_rsk(req);
+       if (dccp_parse_options(sk, dreq, skb))
+               goto drop_and_free;
+
        if (security_inet_conn_request(sk, skb, req))
                goto drop_and_free;
 
@@ -449,7 +450,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
         *   In fact we defer setting S.GSR, S.SWL, S.SWH to
         *   dccp_create_openreq_child.
         */
-       dreq = dccp_rsk(req);
        dreq->dreq_isr     = dcb->dccpd_seq;
        dreq->dreq_iss     = dccp_v6_init_sequence(skb);
        dreq->dreq_service = service;
@@ -994,7 +994,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       err = __xfrm_lookup(&dst, &fl, sk, 1);
+       err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT);
        if (err < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
index 831b76e08d028c87c8a7cb3a4c69afff92a86358..027d1814e1ab39da6efdc7cceead60ac38c01fe8 100644 (file)
@@ -117,11 +117,13 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
                struct dccp_sock *newdp = dccp_sk(newsk);
                struct dccp_minisock *newdmsk = dccp_msk(newsk);
 
-               newdp->dccps_role          = DCCP_ROLE_SERVER;
-               newdp->dccps_hc_rx_ackvec  = NULL;
-               newdp->dccps_service_list  = NULL;
-               newdp->dccps_service       = dreq->dreq_service;
-               newicsk->icsk_rto          = DCCP_TIMEOUT_INIT;
+               newdp->dccps_role           = DCCP_ROLE_SERVER;
+               newdp->dccps_hc_rx_ackvec   = NULL;
+               newdp->dccps_service_list   = NULL;
+               newdp->dccps_service        = dreq->dreq_service;
+               newdp->dccps_timestamp_echo = dreq->dreq_timestamp_echo;
+               newdp->dccps_timestamp_time = dreq->dreq_timestamp_time;
+               newicsk->icsk_rto           = DCCP_TIMEOUT_INIT;
 
                if (dccp_feat_clone(sk, newsk))
                        goto out_free;
@@ -200,10 +202,10 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
                            struct request_sock **prev)
 {
        struct sock *child = NULL;
+       struct dccp_request_sock *dreq = dccp_rsk(req);
 
        /* Check for retransmitted REQUEST */
        if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
-               struct dccp_request_sock *dreq = dccp_rsk(req);
 
                if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) {
                        dccp_pr_debug("Retransmitted REQUEST\n");
@@ -227,22 +229,22 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
                goto drop;
 
        /* Invalid ACK */
-       if (DCCP_SKB_CB(skb)->dccpd_ack_seq != dccp_rsk(req)->dreq_iss) {
+       if (DCCP_SKB_CB(skb)->dccpd_ack_seq != dreq->dreq_iss) {
                dccp_pr_debug("Invalid ACK number: ack_seq=%llu, "
                              "dreq_iss=%llu\n",
                              (unsigned long long)
                              DCCP_SKB_CB(skb)->dccpd_ack_seq,
-                             (unsigned long long)
-                             dccp_rsk(req)->dreq_iss);
+                             (unsigned long long) dreq->dreq_iss);
                goto drop;
        }
 
+       if (dccp_parse_options(sk, dreq, skb))
+                goto drop;
+
        child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
        if (child == NULL)
                goto listen_overflow;
 
-       /* FIXME: deal with options */
-
        inet_csk_reqsk_queue_unlink(sk, req, prev);
        inet_csk_reqsk_queue_removed(sk, req);
        inet_csk_reqsk_queue_add(sk, req, child);
@@ -303,9 +305,12 @@ EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack);
 
 void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
 {
-       inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
-       inet_rsk(req)->acked    = 0;
-       req->rcv_wnd            = sysctl_dccp_feat_sequence_window;
+       struct dccp_request_sock *dreq = dccp_rsk(req);
+
+       inet_rsk(req)->rmt_port   = dccp_hdr(skb)->dccph_sport;
+       inet_rsk(req)->acked      = 0;
+       req->rcv_wnd              = sysctl_dccp_feat_sequence_window;
+       dreq->dreq_timestamp_echo = 0;
 }
 
 EXPORT_SYMBOL_GPL(dccp_reqsk_init);
index d286cffe2c4969f9390b51727da7dcf88d0841dd..d2a84a2fecee6eaf663b4a23d8eabda76e6d08c7 100644 (file)
@@ -46,7 +46,13 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
        return value;
 }
 
-int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
+/**
+ * dccp_parse_options  -  Parse DCCP options present in @skb
+ * @sk: client|server|listening dccp socket (when @dreq != NULL)
+ * @dreq: request socket to use during connection setup, or NULL
+ */
+int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
+                      struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -92,6 +98,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                                goto out_invalid_option;
                }
 
+               /*
+                * CCID-Specific Options (from RFC 4340, sec. 10.3):
+                *
+                * Option numbers 128 through 191 are for options sent from the
+                * HC-Sender to the HC-Receiver; option numbers 192 through 255
+                * are for options sent from the HC-Receiver to the HC-Sender.
+                *
+                * CCID-specific options are ignored during connection setup, as
+                * negotiation may still be in progress (see RFC 4340, 10.3).
+                *
+                */
+               if (dreq != NULL && opt >= 128)
+                       goto ignore_option;
+
                switch (opt) {
                case DCCPO_PADDING:
                        break;
@@ -112,6 +132,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                case DCCPO_CHANGE_L:
                        /* fall through */
                case DCCPO_CHANGE_R:
+                       if (pkt_type == DCCP_PKT_DATA)
+                               break;
                        if (len < 2)
                                goto out_invalid_option;
                        rc = dccp_feat_change_recv(sk, opt, *value, value + 1,
@@ -128,7 +150,9 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                case DCCPO_CONFIRM_L:
                        /* fall through */
                case DCCPO_CONFIRM_R:
-                       if (len < 2)
+                       if (pkt_type == DCCP_PKT_DATA)
+                               break;
+                       if (len < 2)    /* FIXME this disallows empty confirm */
                                goto out_invalid_option;
                        if (dccp_feat_confirm_recv(sk, opt, *value,
                                                   value + 1, len - 1))
@@ -136,7 +160,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                        break;
                case DCCPO_ACK_VECTOR_0:
                case DCCPO_ACK_VECTOR_1:
-                       if (pkt_type == DCCP_PKT_DATA)
+                       if (dccp_packet_without_ack(skb))   /* RFC 4340, 11.4 */
                                break;
 
                        if (dccp_msk(sk)->dccpms_send_ack_vector &&
@@ -146,15 +170,27 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                case DCCPO_TIMESTAMP:
                        if (len != 4)
                                goto out_invalid_option;
-
+                       /*
+                        * RFC 4340 13.1: "The precise time corresponding to
+                        * Timestamp Value zero is not specified". We use
+                        * zero to indicate absence of a meaningful timestamp.
+                        */
                        opt_val = get_unaligned((__be32 *)value);
-                       opt_recv->dccpor_timestamp = ntohl(opt_val);
-
-                       dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
-                       dp->dccps_timestamp_time = ktime_get_real();
+                       if (unlikely(opt_val == 0)) {
+                               DCCP_WARN("Timestamp with zero value\n");
+                               break;
+                       }
 
+                       if (dreq != NULL) {
+                               dreq->dreq_timestamp_echo = ntohl(opt_val);
+                               dreq->dreq_timestamp_time = dccp_timestamp();
+                       } else {
+                               opt_recv->dccpor_timestamp =
+                                       dp->dccps_timestamp_echo = ntohl(opt_val);
+                               dp->dccps_timestamp_time = dccp_timestamp();
+                       }
                        dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
-                                     dccp_role(sk), opt_recv->dccpor_timestamp,
+                                     dccp_role(sk), ntohl(opt_val),
                                      (unsigned long long)
                                      DCCP_SKB_CB(skb)->dccpd_ack_seq);
                        break;
@@ -194,18 +230,17 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                                opt_recv->dccpor_elapsed_time = elapsed_time;
                        break;
                case DCCPO_ELAPSED_TIME:
-                       if (len != 2 && len != 4)
-                               goto out_invalid_option;
-
-                       if (pkt_type == DCCP_PKT_DATA)
-                               continue;
+                       if (dccp_packet_without_ack(skb))   /* RFC 4340, 13.2 */
+                               break;
 
                        if (len == 2) {
                                __be16 opt_val2 = get_unaligned((__be16 *)value);
                                elapsed_time = ntohs(opt_val2);
-                       } else {
+                       } else if (len == 4) {
                                opt_val = get_unaligned((__be32 *)value);
                                elapsed_time = ntohl(opt_val);
+                       } else {
+                               goto out_invalid_option;
                        }
 
                        if (elapsed_time > opt_recv->dccpor_elapsed_time)
@@ -214,15 +249,6 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                        dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
                                      dccp_role(sk), elapsed_time);
                        break;
-                       /*
-                        * From RFC 4340, sec. 10.3:
-                        *
-                        *      Option numbers 128 through 191 are for
-                        *      options sent from the HC-Sender to the
-                        *      HC-Receiver; option numbers 192 through 255
-                        *      are for options sent from the HC-Receiver to
-                        *      the HC-Sender.
-                        */
                case 128 ... 191: {
                        const u16 idx = value - options;
 
@@ -246,7 +272,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                                  "implemented, ignoring", sk, opt, len);
                        break;
                }
-
+ignore_option:
                if (opt != DCCPO_MANDATORY)
                        mandatory = 0;
        }
@@ -382,16 +408,24 @@ int dccp_insert_option_timestamp(struct sock *sk, struct sk_buff *skb)
 
 EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp);
 
-static int dccp_insert_option_timestamp_echo(struct sock *sk,
+static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp,
+                                            struct dccp_request_sock *dreq,
                                             struct sk_buff *skb)
 {
-       struct dccp_sock *dp = dccp_sk(sk);
        __be32 tstamp_echo;
-       int len, elapsed_time_len;
        unsigned char *to;
-       const suseconds_t delta = ktime_us_delta(ktime_get_real(),
-                                                dp->dccps_timestamp_time);
-       u32 elapsed_time = delta / 10;
+       u32 elapsed_time, elapsed_time_len, len;
+
+       if (dreq != NULL) {
+               elapsed_time = dccp_timestamp() - dreq->dreq_timestamp_time;
+               tstamp_echo  = htonl(dreq->dreq_timestamp_echo);
+               dreq->dreq_timestamp_echo = 0;
+       } else {
+               elapsed_time = dccp_timestamp() - dp->dccps_timestamp_time;
+               tstamp_echo  = htonl(dp->dccps_timestamp_echo);
+               dp->dccps_timestamp_echo = 0;
+       }
+
        elapsed_time_len = dccp_elapsed_time_len(elapsed_time);
        len = 6 + elapsed_time_len;
 
@@ -404,7 +438,6 @@ static int dccp_insert_option_timestamp_echo(struct sock *sk,
        *to++ = DCCPO_TIMESTAMP_ECHO;
        *to++ = len;
 
-       tstamp_echo = htonl(dp->dccps_timestamp_echo);
        memcpy(to, &tstamp_echo, 4);
        to += 4;
 
@@ -416,8 +449,6 @@ static int dccp_insert_option_timestamp_echo(struct sock *sk,
                memcpy(to, &var32, 4);
        }
 
-       dp->dccps_timestamp_echo = 0;
-       dp->dccps_timestamp_time = ktime_set(0, 0);
        return 0;
 }
 
@@ -510,6 +541,18 @@ static int dccp_insert_options_feat(struct sock *sk, struct sk_buff *skb)
        return 0;
 }
 
+/* The length of all options needs to be a multiple of 4 (5.8) */
+static void dccp_insert_option_padding(struct sk_buff *skb)
+{
+       int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
+
+       if (padding != 0) {
+               padding = 4 - padding;
+               memset(skb_push(skb, padding), 0, padding);
+               DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
+       }
+}
+
 int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
@@ -526,10 +569,6 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
                    dccp_ackvec_pending(dp->dccps_hc_rx_ackvec) &&
                    dccp_insert_option_ackvec(sk, skb))
                        return -1;
-
-               if (dp->dccps_timestamp_echo != 0 &&
-                   dccp_insert_option_timestamp_echo(sk, skb))
-                       return -1;
        }
 
        if (dp->dccps_hc_rx_insert_options) {
@@ -553,18 +592,22 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
            dccp_insert_option_timestamp(sk, skb))
                return -1;
 
-       /* XXX: insert other options when appropriate */
+       if (dp->dccps_timestamp_echo != 0 &&
+           dccp_insert_option_timestamp_echo(dp, NULL, skb))
+               return -1;
+
+       dccp_insert_option_padding(skb);
+       return 0;
+}
 
-       if (DCCP_SKB_CB(skb)->dccpd_opt_len != 0) {
-               /* The length of all options has to be a multiple of 4 */
-               int padding = DCCP_SKB_CB(skb)->dccpd_opt_len % 4;
+int dccp_insert_options_rsk(struct dccp_request_sock *dreq, struct sk_buff *skb)
+{
+       DCCP_SKB_CB(skb)->dccpd_opt_len = 0;
 
-               if (padding != 0) {
-                       padding = 4 - padding;
-                       memset(skb_push(skb, padding), 0, padding);
-                       DCCP_SKB_CB(skb)->dccpd_opt_len += padding;
-               }
-       }
+       if (dreq->dreq_timestamp_echo != 0 &&
+           dccp_insert_option_timestamp_echo(NULL, dreq, skb))
+               return -1;
 
+       dccp_insert_option_padding(skb);
        return 0;
 }
index f49544618f2007857dcf31c59512e5d1d2faca2c..3b763db3d863bbdd941080a24a1c0c7abff607e7 100644 (file)
@@ -133,15 +133,31 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
        return -ENOBUFS;
 }
 
+/**
+ * dccp_determine_ccmps  -  Find out about CCID-specfic packet-size limits
+ * We only consider the HC-sender CCID for setting the CCMPS (RFC 4340, 14.),
+ * since the RX CCID is restricted to feedback packets (Acks), which are small
+ * in comparison with the data traffic. A value of 0 means "no current CCMPS".
+ */
+static u32 dccp_determine_ccmps(const struct dccp_sock *dp)
+{
+       const struct ccid *tx_ccid = dp->dccps_hc_tx_ccid;
+
+       if (tx_ccid == NULL || tx_ccid->ccid_ops == NULL)
+               return 0;
+       return tx_ccid->ccid_ops->ccid_ccmps;
+}
+
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct dccp_sock *dp = dccp_sk(sk);
-       int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
-                      sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
+       u32 ccmps = dccp_determine_ccmps(dp);
+       int cur_mps = ccmps ? min(pmtu, ccmps) : pmtu;
 
-       /* Now subtract optional transport overhead */
-       mss_now -= icsk->icsk_ext_hdr_len;
+       /* Account for header lengths and IPv4/v6 option overhead */
+       cur_mps -= (icsk->icsk_af_ops->net_header_len + icsk->icsk_ext_hdr_len +
+                   sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
 
        /*
         * FIXME: this should come from the CCID infrastructure, where, say,
@@ -151,13 +167,13 @@ unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
         * make it a multiple of 4
         */
 
-       mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
+       cur_mps -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
 
        /* And store cached results */
        icsk->icsk_pmtu_cookie = pmtu;
-       dp->dccps_mss_cache = mss_now;
+       dp->dccps_mss_cache = cur_mps;
 
-       return mss_now;
+       return cur_mps;
 }
 
 EXPORT_SYMBOL_GPL(dccp_sync_mss);
@@ -170,7 +186,7 @@ void dccp_write_space(struct sock *sk)
                wake_up_interruptible(sk->sk_sleep);
        /* Should agree with poll, otherwise some programs break */
        if (sock_writeable(sk))
-               sk_wake_async(sk, 2, POLL_OUT);
+               sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
 
        read_unlock(&sk->sk_callback_lock);
 }
@@ -303,7 +319,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
        DCCP_SKB_CB(skb)->dccpd_seq  = dreq->dreq_iss;
 
-       if (dccp_insert_options(sk, skb)) {
+       if (dccp_insert_options_rsk(dreq, skb)) {
                kfree_skb(skb);
                return NULL;
        }
@@ -391,7 +407,7 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
         * FIXME: what if rebuild_header fails?
         * Should we be doing a rebuild_header here?
         */
-       int err = inet_sk_rebuild_header(sk);
+       int err = inet_csk(sk)->icsk_af_ops->rebuild_header(sk);
 
        if (err != 0)
                return err;
@@ -567,14 +583,27 @@ void dccp_send_close(struct sock *sk, const int active)
 
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, sk->sk_prot->max_header);
-       DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
-                                       DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
+       if (dp->dccps_role == DCCP_ROLE_SERVER && !dp->dccps_server_timewait)
+               DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSEREQ;
+       else
+               DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_CLOSE;
 
        if (active) {
                dccp_write_xmit(sk, 1);
                dccp_skb_entail(sk, skb);
                dccp_transmit_skb(sk, skb_clone(skb, prio));
-               /* FIXME do we need a retransmit timer here? */
+               /*
+                * Retransmission timer for active-close: RFC 4340, 8.3 requires
+                * to retransmit the Close/CloseReq until the CLOSING/CLOSEREQ
+                * state can be left. The initial timeout is 2 RTTs.
+                * Since RTT measurement is done by the CCIDs, there is no easy
+                * way to get an RTT sample. The fallback RTT from RFC 4340, 3.4
+                * is too low (200ms); we use a high value to avoid unnecessary
+                * retransmissions when the link RTT is > 0.2 seconds.
+                * FIXME: Let main module sample RTTs and use that instead.
+                */
+               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+                                         DCCP_TIMEOUT_INIT, DCCP_RTO_MAX);
        } else
                dccp_transmit_skb(sk, skb);
 }
index 7a3bea9c28c172c8768414cf0fe8f616fb5e15b3..0bed4a6095b7afd4f84ec179daefcf1285371a8c 100644 (file)
@@ -60,8 +60,7 @@ void dccp_set_state(struct sock *sk, const int state)
 {
        const int oldstate = sk->sk_state;
 
-       dccp_pr_debug("%s(%p) %-10.10s -> %s\n",
-                     dccp_role(sk), sk,
+       dccp_pr_debug("%s(%p)  %s  -->  %s\n", dccp_role(sk), sk,
                      dccp_state_name(oldstate), dccp_state_name(state));
        WARN_ON(state == oldstate);
 
@@ -72,7 +71,8 @@ void dccp_set_state(struct sock *sk, const int state)
                break;
 
        case DCCP_CLOSED:
-               if (oldstate == DCCP_CLOSING || oldstate == DCCP_OPEN)
+               if (oldstate == DCCP_OPEN || oldstate == DCCP_ACTIVE_CLOSEREQ ||
+                   oldstate == DCCP_CLOSING)
                        DCCP_INC_STATS(DCCP_MIB_ESTABRESETS);
 
                sk->sk_prot->unhash(sk);
@@ -93,6 +93,24 @@ void dccp_set_state(struct sock *sk, const int state)
 
 EXPORT_SYMBOL_GPL(dccp_set_state);
 
+static void dccp_finish_passive_close(struct sock *sk)
+{
+       switch (sk->sk_state) {
+       case DCCP_PASSIVE_CLOSE:
+               /* Node (client or server) has received Close packet. */
+               dccp_send_reset(sk, DCCP_RESET_CODE_CLOSED);
+               dccp_set_state(sk, DCCP_CLOSED);
+               break;
+       case DCCP_PASSIVE_CLOSEREQ:
+               /*
+                * Client received CloseReq. We set the `active' flag so that
+                * dccp_send_close() retransmits the Close as per RFC 4340, 8.3.
+                */
+               dccp_send_close(sk, 1);
+               dccp_set_state(sk, DCCP_CLOSING);
+       }
+}
+
 void dccp_done(struct sock *sk)
 {
        dccp_set_state(sk, DCCP_CLOSED);
@@ -134,14 +152,17 @@ EXPORT_SYMBOL_GPL(dccp_packet_name);
 const char *dccp_state_name(const int state)
 {
        static char *dccp_state_names[] = {
-       [DCCP_OPEN]       = "OPEN",
-       [DCCP_REQUESTING] = "REQUESTING",
-       [DCCP_PARTOPEN]   = "PARTOPEN",
-       [DCCP_LISTEN]     = "LISTEN",
-       [DCCP_RESPOND]    = "RESPOND",
-       [DCCP_CLOSING]    = "CLOSING",
-       [DCCP_TIME_WAIT]  = "TIME_WAIT",
-       [DCCP_CLOSED]     = "CLOSED",
+       [DCCP_OPEN]             = "OPEN",
+       [DCCP_REQUESTING]       = "REQUESTING",
+       [DCCP_PARTOPEN]         = "PARTOPEN",
+       [DCCP_LISTEN]           = "LISTEN",
+       [DCCP_RESPOND]          = "RESPOND",
+       [DCCP_CLOSING]          = "CLOSING",
+       [DCCP_ACTIVE_CLOSEREQ]  = "CLOSEREQ",
+       [DCCP_PASSIVE_CLOSE]    = "PASSIVE_CLOSE",
+       [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ",
+       [DCCP_TIME_WAIT]        = "TIME_WAIT",
+       [DCCP_CLOSED]           = "CLOSED",
        };
 
        if (state >= DCCP_MAX_STATES)
@@ -174,6 +195,19 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
 
        dccp_minisock_init(&dp->dccps_minisock);
 
+       icsk->icsk_rto          = DCCP_TIMEOUT_INIT;
+       icsk->icsk_syn_retries  = sysctl_dccp_request_retries;
+       sk->sk_state            = DCCP_CLOSED;
+       sk->sk_write_space      = dccp_write_space;
+       icsk->icsk_sync_mss     = dccp_sync_mss;
+       dp->dccps_mss_cache     = 536;
+       dp->dccps_rate_last     = jiffies;
+       dp->dccps_role          = DCCP_ROLE_UNDEFINED;
+       dp->dccps_service       = DCCP_SERVICE_CODE_IS_ABSENT;
+       dp->dccps_l_ack_ratio   = dp->dccps_r_ack_ratio = 1;
+
+       dccp_init_xmit_timers(sk);
+
        /*
         * FIXME: We're hardcoding the CCID, and doing this at this point makes
         * the listening (master) sock get CCID control blocks, which is not
@@ -213,18 +247,6 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
                INIT_LIST_HEAD(&dmsk->dccpms_conf);
        }
 
-       dccp_init_xmit_timers(sk);
-       icsk->icsk_rto          = DCCP_TIMEOUT_INIT;
-       icsk->icsk_syn_retries  = sysctl_dccp_request_retries;
-       sk->sk_state            = DCCP_CLOSED;
-       sk->sk_write_space      = dccp_write_space;
-       icsk->icsk_sync_mss     = dccp_sync_mss;
-       dp->dccps_mss_cache     = 536;
-       dp->dccps_rate_last     = jiffies;
-       dp->dccps_role          = DCCP_ROLE_UNDEFINED;
-       dp->dccps_service       = DCCP_SERVICE_CODE_IS_ABSENT;
-       dp->dccps_l_ack_ratio   = dp->dccps_r_ack_ratio = 1;
-
        return 0;
 }
 
@@ -275,6 +297,12 @@ static inline int dccp_listen_start(struct sock *sk, int backlog)
        return inet_csk_listen_start(sk, backlog);
 }
 
+static inline int dccp_need_reset(int state)
+{
+       return state != DCCP_CLOSED && state != DCCP_LISTEN &&
+              state != DCCP_REQUESTING;
+}
+
 int dccp_disconnect(struct sock *sk, int flags)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
@@ -285,10 +313,15 @@ int dccp_disconnect(struct sock *sk, int flags)
        if (old_state != DCCP_CLOSED)
                dccp_set_state(sk, DCCP_CLOSED);
 
-       /* ABORT function of RFC793 */
+       /*
+        * This corresponds to the ABORT function of RFC793, sec. 3.8
+        * TCP uses a RST segment, DCCP a Reset packet with Code 2, "Aborted".
+        */
        if (old_state == DCCP_LISTEN) {
                inet_csk_listen_stop(sk);
-       /* FIXME: do the active reset thing */
+       } else if (dccp_need_reset(old_state)) {
+               dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
+               sk->sk_err = ECONNRESET;
        } else if (old_state == DCCP_REQUESTING)
                sk->sk_err = ECONNRESET;
 
@@ -518,6 +551,12 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
                                                     (struct dccp_so_feat __user *)
                                                     optval);
                break;
+       case DCCP_SOCKOPT_SERVER_TIMEWAIT:
+               if (dp->dccps_role != DCCP_ROLE_SERVER)
+                       err = -EOPNOTSUPP;
+               else
+                       dp->dccps_server_timewait = (val != 0);
+               break;
        case DCCP_SOCKOPT_SEND_CSCOV:   /* sender side, RFC 4340, sec. 9.2 */
                if (val < 0 || val > 15)
                        err = -EINVAL;
@@ -618,15 +657,15 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
                                               (__be32 __user *)optval, optlen);
        case DCCP_SOCKOPT_GET_CUR_MPS:
                val = dp->dccps_mss_cache;
-               len = sizeof(val);
+               break;
+       case DCCP_SOCKOPT_SERVER_TIMEWAIT:
+               val = dp->dccps_server_timewait;
                break;
        case DCCP_SOCKOPT_SEND_CSCOV:
                val = dp->dccps_pcslen;
-               len = sizeof(val);
                break;
        case DCCP_SOCKOPT_RECV_CSCOV:
                val = dp->dccps_pcrlen;
-               len = sizeof(val);
                break;
        case 128 ... 191:
                return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
@@ -638,6 +677,7 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
                return -ENOPROTOOPT;
        }
 
+       len = sizeof(val);
        if (put_user(len, optlen) || copy_to_user(optval, &val, len))
                return -EFAULT;
 
@@ -748,19 +788,26 @@ int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
                dh = dccp_hdr(skb);
 
-               if (dh->dccph_type == DCCP_PKT_DATA ||
-                   dh->dccph_type == DCCP_PKT_DATAACK)
+               switch (dh->dccph_type) {
+               case DCCP_PKT_DATA:
+               case DCCP_PKT_DATAACK:
                        goto found_ok_skb;
 
-               if (dh->dccph_type == DCCP_PKT_RESET ||
-                   dh->dccph_type == DCCP_PKT_CLOSE) {
-                       dccp_pr_debug("found fin ok!\n");
+               case DCCP_PKT_CLOSE:
+               case DCCP_PKT_CLOSEREQ:
+                       if (!(flags & MSG_PEEK))
+                               dccp_finish_passive_close(sk);
+                       /* fall through */
+               case DCCP_PKT_RESET:
+                       dccp_pr_debug("found fin (%s) ok!\n",
+                                     dccp_packet_name(dh->dccph_type));
                        len = 0;
                        goto found_fin_ok;
+               default:
+                       dccp_pr_debug("packet_type=%s\n",
+                                     dccp_packet_name(dh->dccph_type));
+                       sk_eat_skb(sk, skb, 0);
                }
-               dccp_pr_debug("packet_type=%s\n",
-                             dccp_packet_name(dh->dccph_type));
-               sk_eat_skb(sk, skb, 0);
 verify_sock_status:
                if (sock_flag(sk, SOCK_DONE)) {
                        len = 0;
@@ -862,34 +909,38 @@ out:
 
 EXPORT_SYMBOL_GPL(inet_dccp_listen);
 
-static const unsigned char dccp_new_state[] = {
-       /* current state:   new state:      action:     */
-       [0]               = DCCP_CLOSED,
-       [DCCP_OPEN]       = DCCP_CLOSING | DCCP_ACTION_FIN,
-       [DCCP_REQUESTING] = DCCP_CLOSED,
-       [DCCP_PARTOPEN]   = DCCP_CLOSING | DCCP_ACTION_FIN,
-       [DCCP_LISTEN]     = DCCP_CLOSED,
-       [DCCP_RESPOND]    = DCCP_CLOSED,
-       [DCCP_CLOSING]    = DCCP_CLOSED,
-       [DCCP_TIME_WAIT]  = DCCP_CLOSED,
-       [DCCP_CLOSED]     = DCCP_CLOSED,
-};
-
-static int dccp_close_state(struct sock *sk)
+static void dccp_terminate_connection(struct sock *sk)
 {
-       const int next = dccp_new_state[sk->sk_state];
-       const int ns = next & DCCP_STATE_MASK;
+       u8 next_state = DCCP_CLOSED;
 
-       if (ns != sk->sk_state)
-               dccp_set_state(sk, ns);
+       switch (sk->sk_state) {
+       case DCCP_PASSIVE_CLOSE:
+       case DCCP_PASSIVE_CLOSEREQ:
+               dccp_finish_passive_close(sk);
+               break;
+       case DCCP_PARTOPEN:
+               dccp_pr_debug("Stop PARTOPEN timer (%p)\n", sk);
+               inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
+               /* fall through */
+       case DCCP_OPEN:
+               dccp_send_close(sk, 1);
 
-       return next & DCCP_ACTION_FIN;
+               if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER &&
+                   !dccp_sk(sk)->dccps_server_timewait)
+                       next_state = DCCP_ACTIVE_CLOSEREQ;
+               else
+                       next_state = DCCP_CLOSING;
+               /* fall through */
+       default:
+               dccp_set_state(sk, next_state);
+       }
 }
 
 void dccp_close(struct sock *sk, long timeout)
 {
        struct dccp_sock *dp = dccp_sk(sk);
        struct sk_buff *skb;
+       u32 data_was_unread = 0;
        int state;
 
        lock_sock(sk);
@@ -912,16 +963,21 @@ void dccp_close(struct sock *sk, long timeout)
         * descriptor close, not protocol-sourced closes, because the
          *reader process may not have drained the data yet!
         */
-       /* FIXME: check for unread data */
        while ((skb = __skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+               data_was_unread += skb->len;
                __kfree_skb(skb);
        }
 
-       if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
+       if (data_was_unread) {
+               /* Unread data was tossed, send an appropriate Reset Code */
+               DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread);
+               dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED);
+               dccp_set_state(sk, DCCP_CLOSED);
+       } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
                /* Check zero linger _after_ checking for unread data. */
                sk->sk_prot->disconnect(sk, 0);
-       } else if (dccp_close_state(sk)) {
-               dccp_send_close(sk, 1);
+       } else if (sk->sk_state != DCCP_CLOSED) {
+               dccp_terminate_connection(sk);
        }
 
        sk_stream_wait_close(sk, timeout);
@@ -948,24 +1004,6 @@ adjudge_to_death:
        if (state != DCCP_CLOSED && sk->sk_state == DCCP_CLOSED)
                goto out;
 
-       /*
-        * The last release_sock may have processed the CLOSE or RESET
-        * packet moving sock to CLOSED state, if not we have to fire
-        * the CLOSE/CLOSEREQ retransmission timer, see "8.3. Termination"
-        * in draft-ietf-dccp-spec-11. -acme
-        */
-       if (sk->sk_state == DCCP_CLOSING) {
-               /* FIXME: should start at 2 * RTT */
-               /* Timer for repeating the CLOSE/CLOSEREQ until an answer. */
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
-                                         inet_csk(sk)->icsk_rto,
-                                         DCCP_RTO_MAX);
-#if 0
-               /* Yeah, we should use sk->sk_prot->orphan_count, etc */
-               dccp_set_state(sk, DCCP_CLOSED);
-#endif
-       }
-
        if (sk->sk_state == DCCP_CLOSED)
                inet_csk_destroy_sock(sk);
 
@@ -981,7 +1019,7 @@ EXPORT_SYMBOL_GPL(dccp_close);
 
 void dccp_shutdown(struct sock *sk, int how)
 {
-       dccp_pr_debug("entry\n");
+       dccp_pr_debug("called shutdown(%x)\n", how);
 }
 
 EXPORT_SYMBOL_GPL(dccp_shutdown);
index c62c05039f693e40bbd2b4cad307fa68d619629f..21295993fdb84f2dd53dea972b137eb95395aca2 100644 (file)
@@ -100,41 +100,19 @@ static struct ctl_table dccp_default_table[] = {
        { .ctl_name = 0, }
 };
 
-static struct ctl_table dccp_table[] = {
-       {
-               .ctl_name       = NET_DCCP_DEFAULT,
-               .procname       = "default",
-               .mode           = 0555,
-               .child          = dccp_default_table,
-       },
-       { .ctl_name = 0, },
-};
-
-static struct ctl_table dccp_dir_table[] = {
-       {
-               .ctl_name       = NET_DCCP,
-               .procname       = "dccp",
-               .mode           = 0555,
-               .child          = dccp_table,
-       },
-       { .ctl_name = 0, },
-};
-
-static struct ctl_table dccp_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = dccp_dir_table,
-       },
-       { .ctl_name = 0, },
+static struct ctl_path dccp_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "dccp", .ctl_name = NET_DCCP, },
+       { .procname = "default", .ctl_name = NET_DCCP_DEFAULT, },
+       { }
 };
 
 static struct ctl_table_header *dccp_table_header;
 
 int __init dccp_sysctl_init(void)
 {
-       dccp_table_header = register_sysctl_table(dccp_root_table);
+       dccp_table_header = register_sysctl_paths(dccp_path,
+                       dccp_default_table);
 
        return dccp_table_header != NULL ? 0 : -ENOMEM;
 }
index 3af067354bd4ec531ab61f2b22cf4ecd01028552..8703a792b56068ec44e15804731d2a0366ce7873 100644 (file)
@@ -280,9 +280,8 @@ static void dccp_init_write_xmit_timer(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
-       init_timer(&dp->dccps_xmit_timer);
-       dp->dccps_xmit_timer.data = (unsigned long)sk;
-       dp->dccps_xmit_timer.function = dccp_write_xmit_timer;
+       setup_timer(&dp->dccps_xmit_timer, dccp_write_xmit_timer,
+                       (unsigned long)sk);
 }
 
 void dccp_init_xmit_timers(struct sock *sk)
index 57d5749518380c06cd9dc6863d649e8cfbc230fe..acd48ee522d6b4f77ef95462bc4b379179f46f36 100644 (file)
@@ -1904,7 +1904,7 @@ static inline struct sk_buff *dn_alloc_send_pskb(struct sock *sk,
        struct sk_buff *skb = sock_alloc_send_skb(sk, datalen,
                                                   noblock, errcode);
        if (skb) {
-               skb->protocol = __constant_htons(ETH_P_DNA_RT);
+               skb->protocol = htons(ETH_P_DNA_RT);
                skb->pkt_type = PACKET_OUTGOING;
        }
        return skb;
index 3bc82dc83b387d33f92d496d81383c9346296f9d..1bbfce5f7a2dc851094d2a3e286f2e17a642864d 100644 (file)
@@ -173,10 +173,6 @@ static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
 static struct dn_dev_sysctl_table {
        struct ctl_table_header *sysctl_header;
        ctl_table dn_dev_vars[5];
-       ctl_table dn_dev_dev[2];
-       ctl_table dn_dev_conf_dir[2];
-       ctl_table dn_dev_proto_dir[2];
-       ctl_table dn_dev_root_dir[2];
 } dn_dev_sysctl = {
        NULL,
        {
@@ -224,30 +220,6 @@ static struct dn_dev_sysctl_table {
        },
        {0}
        },
-       {{
-               .ctl_name = 0,
-               .procname = "",
-               .mode = 0555,
-               .child = dn_dev_sysctl.dn_dev_vars
-       }, {0}},
-       {{
-               .ctl_name = NET_DECNET_CONF,
-               .procname = "conf",
-               .mode = 0555,
-               .child = dn_dev_sysctl.dn_dev_dev
-       }, {0}},
-       {{
-               .ctl_name = NET_DECNET,
-               .procname = "decnet",
-               .mode = 0555,
-               .child = dn_dev_sysctl.dn_dev_conf_dir
-       }, {0}},
-       {{
-               .ctl_name = CTL_NET,
-               .procname = "net",
-               .mode = 0555,
-               .child = dn_dev_sysctl.dn_dev_proto_dir
-       }, {0}}
 };
 
 static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *parms)
@@ -255,6 +227,16 @@ static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *
        struct dn_dev_sysctl_table *t;
        int i;
 
+#define DN_CTL_PATH_DEV        3
+
+       struct ctl_path dn_ctl_path[] = {
+               { .procname = "net", .ctl_name = CTL_NET, },
+               { .procname = "decnet", .ctl_name = NET_DECNET, },
+               { .procname = "conf", .ctl_name = NET_DECNET_CONF, },
+               { /* to be set */ },
+               { },
+       };
+
        t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL);
        if (t == NULL)
                return;
@@ -265,20 +247,16 @@ static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *
        }
 
        if (dev) {
-               t->dn_dev_dev[0].procname = dev->name;
-               t->dn_dev_dev[0].ctl_name = dev->ifindex;
+               dn_ctl_path[DN_CTL_PATH_DEV].procname = dev->name;
+               dn_ctl_path[DN_CTL_PATH_DEV].ctl_name = dev->ifindex;
        } else {
-               t->dn_dev_dev[0].procname = parms->name;
-               t->dn_dev_dev[0].ctl_name = parms->ctl_name;
+               dn_ctl_path[DN_CTL_PATH_DEV].procname = parms->name;
+               dn_ctl_path[DN_CTL_PATH_DEV].ctl_name = parms->ctl_name;
        }
 
-       t->dn_dev_dev[0].child = t->dn_dev_vars;
-       t->dn_dev_conf_dir[0].child = t->dn_dev_dev;
-       t->dn_dev_proto_dir[0].child = t->dn_dev_conf_dir;
-       t->dn_dev_root_dir[0].child = t->dn_dev_proto_dir;
        t->dn_dev_vars[0].extra1 = (void *)dev;
 
-       t->sysctl_header = register_sysctl_table(t->dn_dev_root_dir);
+       t->sysctl_header = register_sysctl_paths(dn_ctl_path, t->dn_dev_vars);
        if (t->sysctl_header == NULL)
                kfree(t);
        else
@@ -647,11 +625,15 @@ static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = {
 
 static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct nlattr *tb[IFA_MAX+1];
        struct dn_dev *dn_db;
        struct ifaddrmsg *ifm;
        struct dn_ifaddr *ifa, **ifap;
-       int err;
+       int err = -EINVAL;
+
+       if (net != &init_net)
+               goto errout;
 
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
        if (err < 0)
@@ -681,6 +663,7 @@ errout:
 
 static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct nlattr *tb[IFA_MAX+1];
        struct net_device *dev;
        struct dn_dev *dn_db;
@@ -688,6 +671,9 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        struct dn_ifaddr *ifa;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
        if (err < 0)
                return err;
@@ -785,19 +771,23 @@ static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
+       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_IFADDR, err);
 }
 
 static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int idx, dn_idx = 0, skip_ndevs, skip_naddr;
        struct net_device *dev;
        struct dn_dev *dn_db;
        struct dn_ifaddr *ifa;
 
+       if (net != &init_net)
+               return 0;
+
        skip_ndevs = cb->args[0];
        skip_naddr = cb->args[1];
 
index 3760a20d10d08b661d5b881164ab1b14cd2f20c5..4aa9a423e606360e959ad54d83595d9281bde2a4 100644 (file)
@@ -203,8 +203,6 @@ static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct
                struct flowi fl;
                struct dn_fib_res res;
 
-               memset(&fl, 0, sizeof(fl));
-
                if (nh->nh_flags&RTNH_F_ONLINK) {
                        struct net_device *dev;
 
@@ -506,10 +504,14 @@ static int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta)
 
 static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct dn_fib_table *tb;
        struct rtattr **rta = arg;
        struct rtmsg *r = NLMSG_DATA(nlh);
 
+       if (net != &init_net)
+               return -EINVAL;
+
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
@@ -522,10 +524,14 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *
 
 static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct dn_fib_table *tb;
        struct rtattr **rta = arg;
        struct rtmsg *r = NLMSG_DATA(nlh);
 
+       if (net != &init_net)
+               return -EINVAL;
+
        if (dn_fib_check_attr(r, rta))
                return -EINVAL;
 
index e851b143cca3e4284018c14831f8ea492c9e4a44..1ca13b17974d92e0fed3e1b6a7e475d06059cd55 100644 (file)
@@ -580,8 +580,8 @@ static const struct seq_operations dn_neigh_seq_ops = {
 
 static int dn_neigh_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &dn_neigh_seq_ops,
-                       sizeof(struct neigh_seq_state));
+       return seq_open_net(inode, file, &dn_neigh_seq_ops,
+                           sizeof(struct neigh_seq_state));
 }
 
 static const struct file_operations dn_neigh_seq_fops = {
@@ -589,7 +589,7 @@ static const struct file_operations dn_neigh_seq_fops = {
        .open           = dn_neigh_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
 };
 
 #endif
index 7404653880b061c9ea8cb35bd10d63bf0b5a677e..1964faf203e48a41d6a30d468db3b8b4503ee533 100644 (file)
@@ -124,7 +124,7 @@ struct sk_buff *dn_alloc_skb(struct sock *sk, int size, gfp_t pri)
        if ((skb = alloc_skb(size + hdr, pri)) == NULL)
                return NULL;
 
-       skb->protocol = __constant_htons(ETH_P_DNA_RT);
+       skb->protocol = htons(ETH_P_DNA_RT);
        skb->pkt_type = PACKET_OUTGOING;
 
        if (sk)
index 0e10ff21e29204d227bf7558b8fc5d9d6ea076ac..31be29b8b5a3cb597b7ea991ef0c074293692b5b 100644 (file)
@@ -107,7 +107,7 @@ static const int dn_rt_mtu_expires = 10 * 60 * HZ;
 
 static unsigned long dn_rt_deadline;
 
-static int dn_dst_gc(void);
+static int dn_dst_gc(struct dst_ops *ops);
 static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static void dn_dst_link_failure(struct sk_buff *);
@@ -185,7 +185,7 @@ static void dn_dst_check_expire(unsigned long dummy)
        mod_timer(&dn_route_timer, now + decnet_dst_gc_interval * HZ);
 }
 
-static int dn_dst_gc(void)
+static int dn_dst_gc(struct dst_ops *ops)
 {
        struct dn_route *rt, **rtp;
        int i;
@@ -764,17 +764,6 @@ drop:
        return NET_RX_DROP;
 }
 
-/*
- * Drop packet. This is used for endnodes and for
- * when we should not be forwarding packets from
- * this dest.
- */
-static int dn_blackhole(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return NET_RX_DROP;
-}
-
 /*
  * Used to catch bugs. This should never normally get
  * called.
@@ -995,7 +984,7 @@ source_ok:
                 * here
                 */
                if (!try_hard) {
-                       neigh = neigh_lookup_nodev(&dn_neigh_table, &fl.fld_dst);
+                       neigh = neigh_lookup_nodev(&dn_neigh_table, &init_net, &fl.fld_dst);
                        if (neigh) {
                                if ((oldflp->oif &&
                                    (neigh->dev->ifindex != oldflp->oif)) ||
@@ -1207,7 +1196,8 @@ int dn_route_output_sock(struct dst_entry **pprt, struct flowi *fl, struct sock
 
        err = __dn_route_output_key(pprt, fl, flags & MSG_TRYHARD);
        if (err == 0 && fl->proto) {
-               err = xfrm_lookup(pprt, fl, sk, !(flags & MSG_DONTWAIT));
+               err = xfrm_lookup(pprt, fl, sk, (flags & MSG_DONTWAIT) ?
+                                               0 : XFRM_LOOKUP_WAIT);
        }
        return err;
 }
@@ -1396,7 +1386,7 @@ make_route:
                default:
                case RTN_UNREACHABLE:
                case RTN_BLACKHOLE:
-                       rt->u.dst.input = dn_blackhole;
+                       rt->u.dst.input = dst_discard;
        }
        rt->rt_flags = flags;
        if (rt->u.dst.dev)
@@ -1522,6 +1512,7 @@ rtattr_failure:
  */
 static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = in_skb->sk->sk_net;
        struct rtattr **rta = arg;
        struct rtmsg *rtm = NLMSG_DATA(nlh);
        struct dn_route *rt = NULL;
@@ -1530,6 +1521,9 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
        struct sk_buff *skb;
        struct flowi fl;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        memset(&fl, 0, sizeof(fl));
        fl.proto = DNPROTO_NSP;
 
@@ -1557,7 +1551,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
                        kfree_skb(skb);
                        return -ENODEV;
                }
-               skb->protocol = __constant_htons(ETH_P_DNA_RT);
+               skb->protocol = htons(ETH_P_DNA_RT);
                skb->dev = dev;
                cb->src = fl.fld_src;
                cb->dst = fl.fld_dst;
@@ -1594,7 +1588,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
                goto out_free;
        }
 
-       return rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+       return rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
 
 out_free:
        kfree_skb(skb);
@@ -1607,10 +1601,14 @@ out_free:
  */
 int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        struct dn_route *rt;
        int h, s_h;
        int idx, s_idx;
 
+       if (net != &init_net)
+               return 0;
+
        if (NLMSG_PAYLOAD(cb->nlh, 0) < sizeof(struct rtmsg))
                return -EINVAL;
        if (!(((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED))
@@ -1752,8 +1750,7 @@ void __init dn_route_init(void)
        dn_dst_ops.kmem_cachep =
                kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0,
                                  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
-       init_timer(&dn_route_timer);
-       dn_route_timer.function = dn_dst_check_expire;
+       setup_timer(&dn_route_timer, dn_dst_check_expire, 0);
        dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
        add_timer(&dn_route_timer);
 
index ffebea04cc99b9f6c5820734f057f9307ed5e333..5b7539b7fe0c81af38cf66046defc40a83145f94 100644 (file)
@@ -212,7 +212,7 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-static u32 dn_fib_rule_default_pref(void)
+static u32 dn_fib_rule_default_pref(struct fib_rules_ops *ops)
 {
        struct list_head *pos;
        struct fib_rule *rule;
@@ -249,6 +249,7 @@ static struct fib_rules_ops dn_fib_rules_ops = {
        .policy         = dn_fib_rule_policy,
        .rules_list     = LIST_HEAD_INIT(dn_fib_rules_ops.rules_list),
        .owner          = THIS_MODULE,
+       .fro_net        = &init_net,
 };
 
 void __init dn_fib_rules_init(void)
index fda0772fa215afa59ab258668fecffaa95625f87..e09d915dbd776598bb66d5e142beeef8cbe4fcd8 100644 (file)
@@ -375,10 +375,10 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
+       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_DECnet_ROUTE, err);
 }
 
 static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
@@ -463,12 +463,16 @@ static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb,
 
 int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        unsigned int h, s_h;
        unsigned int e = 0, s_e;
        struct dn_fib_table *tb;
        struct hlist_node *node;
        int dumped = 0;
 
+       if (net != &init_net)
+               return 0;
+
        if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
                ((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
                        return dn_cache_dump(skb, cb);
index ecdb3f9f14ca858ef49067a571ded1cccaad00e2..2f81de5e752f67ff1091fb9790da1b4c6504a182 100644 (file)
@@ -4,6 +4,7 @@
 
 menu "DECnet: Netfilter Configuration"
        depends on DECNET && NETFILTER && EXPERIMENTAL
+       depends on NETFILTER_ADVANCED
 
 config DECNET_NF_GRABULATOR
        tristate "Routing message grabulator (for userland routing daemon)"
index 43fcd29046d1f30b14a60569284ef0ab4afa69d3..6d2bd3202048a8c8b36e17ef707278cc806d89e4 100644 (file)
@@ -115,7 +115,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
        RCV_SKB_FAIL(-EINVAL);
 }
 
-static struct nf_hook_ops dnrmg_ops = {
+static struct nf_hook_ops dnrmg_ops __read_mostly = {
        .hook           = dnrmg_hook,
        .pf             = PF_DECnet,
        .hooknum        = NF_DN_ROUTE,
@@ -137,7 +137,7 @@ static int __init dn_rtmsg_init(void)
 
        rv = nf_register_hook(&dnrmg_ops);
        if (rv) {
-               sock_release(dnrmg->sk_socket);
+               netlink_kernel_release(dnrmg);
        }
 
        return rv;
@@ -146,7 +146,7 @@ static int __init dn_rtmsg_init(void)
 static void __exit dn_rtmsg_fini(void)
 {
        nf_unregister_hook(&dnrmg_ops);
-       sock_release(dnrmg->sk_socket);
+       netlink_kernel_release(dnrmg);
 }
 
 
index ae354a43fb97af91d7f8c0250585051e0aa2b186..228067c571ba2aaf379463a609c822a2f6797861 100644 (file)
@@ -470,28 +470,15 @@ static ctl_table dn_table[] = {
        {0}
 };
 
-static ctl_table dn_dir_table[] = {
-       {
-               .ctl_name = NET_DECNET,
-               .procname = "decnet",
-               .mode = 0555,
-               .child = dn_table},
-       {0}
-};
-
-static ctl_table dn_root_table[] = {
-       {
-               .ctl_name = CTL_NET,
-               .procname = "net",
-               .mode = 0555,
-               .child = dn_dir_table
-       },
-       {0}
+static struct ctl_path dn_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "decnet", .ctl_name = NET_DECNET, },
+       { }
 };
 
 void dn_register_sysctl(void)
 {
-       dn_table_header = register_sysctl_table(dn_root_table);
+       dn_table_header = register_sysctl_paths(dn_path, dn_table);
 }
 
 void dn_unregister_sysctl(void)
index f70df073c58800552cf69a105da1b2c800e40383..bc0f6252613f1adc43aa72258831a39989b4c39e 100644 (file)
@@ -1014,9 +1014,8 @@ static int __init aun_udp_initialise(void)
 
        skb_queue_head_init(&aun_queue);
        spin_lock_init(&aun_queue_lock);
-       init_timer(&ab_cleanup_timer);
+       setup_timer(&ab_cleanup_timer, ab_cleanup, 0);
        ab_cleanup_timer.expires = jiffies + (HZ*2);
-       ab_cleanup_timer.function = ab_cleanup;
        add_timer(&ab_cleanup_timer);
 
        memset(&sin, 0, sizeof(sin));
index 6b2e454ae31301364b7e02ce646daa7a54201abb..a7b417523e9b1181597c340d9305a57dd4c9d431 100644 (file)
@@ -359,10 +359,34 @@ struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count)
 }
 EXPORT_SYMBOL(alloc_etherdev_mq);
 
-char *print_mac(char *buf, const u8 *addr)
+static size_t _format_mac_addr(char *buf, int buflen,
+                               const unsigned char *addr, int len)
 {
-       sprintf(buf, MAC_FMT,
-               addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+       int i;
+       char *cp = buf;
+
+       for (i = 0; i < len; i++) {
+               cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]);
+               if (i == len - 1)
+                       break;
+               cp += strlcpy(cp, ":", buflen - (cp - buf));
+       }
+       return cp - buf;
+}
+
+ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
+{
+       size_t l;
+
+       l = _format_mac_addr(buf, PAGE_SIZE, addr, len);
+       l += strlcpy(buf + l, "\n", PAGE_SIZE - l);
+       return ((ssize_t) l);
+}
+EXPORT_SYMBOL(sysfs_format_mac);
+
+char *print_mac(char *buf, const unsigned char *addr)
+{
+       _format_mac_addr(buf, MAC_BUF_SIZE, addr, ETH_ALEN);
        return buf;
 }
 EXPORT_SYMBOL(print_mac);
index 1438adedbc83b04c26cbc6726804852f40c7b256..bd501046c9c0c0ef4fa5512e7c565e62f53e24a0 100644 (file)
@@ -1,8 +1,9 @@
 config IEEE80211
-       tristate "Generic IEEE 802.11 Networking Stack"
+       tristate "Generic IEEE 802.11 Networking Stack (DEPRECATED)"
        ---help---
        This option enables the hardware independent IEEE 802.11
-       networking stack.
+       networking stack.  This component is deprecated in favor of the
+       mac80211 component.
 
 config IEEE80211_DEBUG
        bool "Enable full debugging output"
index 8e146949fc6f595eb75ca15f234060347ade8c89..bba0152e2d713b5798e6501711312e59a4267cef 100644 (file)
@@ -189,7 +189,7 @@ static inline u16 Mk16(u8 hi, u8 lo)
        return lo | (((u16) hi) << 8);
 }
 
-static inline u16 Mk16_le(u16 * v)
+static inline u16 Mk16_le(__le16 * v)
 {
        return le16_to_cpu(*v);
 }
@@ -275,15 +275,15 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
        PPK[5] = TTAK[4] + IV16;
 
        /* Step 2 - 96-bit bijective mixing using S-box */
-       PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) & TK[0]));
-       PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) & TK[2]));
-       PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) & TK[4]));
-       PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) & TK[6]));
-       PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) & TK[8]));
-       PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) & TK[10]));
-
-       PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) & TK[12]));
-       PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) & TK[14]));
+       PPK[0] += _S_(PPK[5] ^ Mk16_le((__le16 *) & TK[0]));
+       PPK[1] += _S_(PPK[0] ^ Mk16_le((__le16 *) & TK[2]));
+       PPK[2] += _S_(PPK[1] ^ Mk16_le((__le16 *) & TK[4]));
+       PPK[3] += _S_(PPK[2] ^ Mk16_le((__le16 *) & TK[6]));
+       PPK[4] += _S_(PPK[3] ^ Mk16_le((__le16 *) & TK[8]));
+       PPK[5] += _S_(PPK[4] ^ Mk16_le((__le16 *) & TK[10]));
+
+       PPK[0] += RotR1(PPK[5] ^ Mk16_le((__le16 *) & TK[12]));
+       PPK[1] += RotR1(PPK[0] ^ Mk16_le((__le16 *) & TK[14]));
        PPK[2] += RotR1(PPK[1]);
        PPK[3] += RotR1(PPK[2]);
        PPK[4] += RotR1(PPK[3]);
@@ -294,7 +294,7 @@ static void tkip_mixing_phase2(u8 * WEPSeed, const u8 * TK, const u16 * TTAK,
        WEPSeed[0] = Hi8(IV16);
        WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
        WEPSeed[2] = Lo8(IV16);
-       WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) & TK[0])) >> 1);
+       WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((__le16 *) & TK[0])) >> 1);
 
 #ifdef __BIG_ENDIAN
        {
index 69cb6aad25be0b6bf760492d6ca580c63883a026..3bca97f55d47c3b6e7b1591d999bed3800efd64f 100644 (file)
@@ -181,9 +181,8 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
        ieee->ieee802_1x = 1;   /* Default to supporting 802.1x */
 
        INIT_LIST_HEAD(&ieee->crypt_deinit_list);
-       init_timer(&ieee->crypt_deinit_timer);
-       ieee->crypt_deinit_timer.data = (unsigned long)ieee;
-       ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
+       setup_timer(&ieee->crypt_deinit_timer, ieee80211_crypt_deinit_handler,
+                       (unsigned long)ieee);
        ieee->crypt_quiesced = 0;
 
        spin_lock_init(&ieee->lock);
index 21c0fadde03b1fc7a86b083b8f5194ecec1a8617..1e3f87c8c012b9120f307ab5c4108b1dfdaa70f7 100644 (file)
@@ -45,7 +45,7 @@ static void ieee80211_monitor_rx(struct ieee80211_device *ieee,
        skb_reset_mac_header(skb);
        skb_pull(skb, ieee80211_get_hdrlen(fc));
        skb->pkt_type = PACKET_OTHERHOST;
-       skb->protocol = __constant_htons(ETH_P_80211_RAW);
+       skb->protocol = htons(ETH_P_80211_RAW);
        memset(skb->cb, 0, sizeof(skb->cb));
        netif_rx(skb);
 }
@@ -754,7 +754,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
                memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
        } else {
-               u16 len;
+               __be16 len;
                /* Leave Ethernet header part of hdr and full payload */
                skb_pull(skb, hdrlen);
                len = htons(skb->len);
@@ -800,7 +800,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (skb2 != NULL) {
                /* send to wireless media */
                skb2->dev = dev;
-               skb2->protocol = __constant_htons(ETH_P_802_3);
+               skb2->protocol = htons(ETH_P_802_3);
                skb_reset_mac_header(skb2);
                skb_reset_network_header(skb2);
                /* skb2->network_header += ETH_HLEN; */
@@ -1032,16 +1032,16 @@ static int ieee80211_qos_convert_ac_to_parameters(struct
                qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
 
                cw_min = ac_params->ecw_min_max & 0x0F;
-               qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
+               qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
 
                cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
-               qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
+               qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
 
                qos_param->flag[i] =
                    (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
 
                txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
-               qos_param->tx_op_limit[i] = (u16) txop;
+               qos_param->tx_op_limit[i] = cpu_to_le16(txop);
        }
        return rc;
 }
@@ -1585,26 +1585,25 @@ static void ieee80211_process_probe_response(struct ieee80211_device
        DECLARE_MAC_BUF(mac);
 
        IEEE80211_DEBUG_SCAN("'%s' (%s"
-                            "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
-                            escape_essid(info_element->data,
-                                         info_element->len),
-                            print_mac(mac, beacon->header.addr3),
-                            (beacon->capability & (1 << 0xf)) ? '1' : '0',
-                            (beacon->capability & (1 << 0xe)) ? '1' : '0',
-                            (beacon->capability & (1 << 0xd)) ? '1' : '0',
-                            (beacon->capability & (1 << 0xc)) ? '1' : '0',
-                            (beacon->capability & (1 << 0xb)) ? '1' : '0',
-                            (beacon->capability & (1 << 0xa)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x9)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x8)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x7)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x6)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x5)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x4)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x3)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x2)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x1)) ? '1' : '0',
-                            (beacon->capability & (1 << 0x0)) ? '1' : '0');
+                    "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+                    escape_essid(info_element->data, info_element->len),
+                    print_mac(mac, beacon->header.addr3),
+                    (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
+                    (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
 
        if (ieee80211_network_init(ieee, beacon, &network, stats)) {
                IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n",
index 6d06f1385e2803cd1f263917e8bd6f8d2684a834..d8b02603cbe5d9a86811b88c5510620cfec42a94 100644 (file)
@@ -126,7 +126,7 @@ payload of each frame is reduced to 492 bytes.
 static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
 static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
 
-static int ieee80211_copy_snap(u8 * data, u16 h_proto)
+static int ieee80211_copy_snap(u8 * data, __be16 h_proto)
 {
        struct ieee80211_snap_hdr *snap;
        u8 *oui;
@@ -136,7 +136,7 @@ static int ieee80211_copy_snap(u8 * data, u16 h_proto)
        snap->ssap = 0xaa;
        snap->ctrl = 0x03;
 
-       if (h_proto == 0x8137 || h_proto == 0x80f3)
+       if (h_proto == htons(ETH_P_AARP) || h_proto == htons(ETH_P_IPX))
                oui = P802_1H_OUI;
        else
                oui = RFC1042_OUI;
@@ -144,7 +144,6 @@ static int ieee80211_copy_snap(u8 * data, u16 h_proto)
        snap->oui[1] = oui[1];
        snap->oui[2] = oui[2];
 
-       h_proto = htons(h_proto);
        memcpy(data + SNAP_SIZE, &h_proto, sizeof(u16));
 
        return SNAP_SIZE + sizeof(u16);
@@ -261,7 +260,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
            rts_required;
        unsigned long flags;
        struct net_device_stats *stats = &ieee->stats;
-       int ether_type, encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
+       int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
+       __be16 ether_type;
        int bytes, fc, hdr_len;
        struct sk_buff *skb_frag;
        struct ieee80211_hdr_3addrqos header = {/* Ensure zero initialized */
@@ -292,11 +292,11 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
                goto success;
        }
 
-       ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
+       ether_type = ((struct ethhdr *)skb->data)->h_proto;
 
        crypt = ieee->crypt[ieee->tx_keyidx];
 
-       encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
+       encrypt = !(ether_type == htons(ETH_P_PAE) && ieee->ieee802_1x) &&
            ieee->sec.encrypt;
 
        host_encrypt = ieee->host_encrypt && encrypt && crypt;
@@ -304,7 +304,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        host_build_iv = ieee->host_build_iv && encrypt && crypt;
 
        if (!encrypt && ieee->ieee802_1x &&
-           ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
+           ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
                stats->tx_dropped++;
                goto success;
        }
index d309e8f199929618b1fb0a2ee02fc9aed362b881..623489afa62c223e3f4b9d3ee1963c5aea2c1479 100644 (file)
@@ -709,7 +709,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee,
        } else
                idx = ieee->tx_keyidx;
 
-       if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
+       if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) &&
            ext->alg != IW_ENCODE_ALG_WEP)
                if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA)
                        return -EINVAL;
index a53a751d07025e54613175af93d01c62bb179248..1a96c2572578603d2959b667b26807e8f4e4e667 100644 (file)
@@ -178,11 +178,11 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
        }
 
        /* Parse the auth packet */
-       switch(auth->algorithm) {
+       switch(le16_to_cpu(auth->algorithm)) {
        case WLAN_AUTH_OPEN:
                /* Check the status code of the response */
 
-               switch(auth->status) {
+               switch(le16_to_cpu(auth->status)) {
                case WLAN_STATUS_SUCCESS:
                        /* Update the status to Authenticated */
                        spin_lock_irqsave(&mac->lock, flags);
@@ -210,7 +210,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
                break;
        case WLAN_AUTH_SHARED_KEY:
                /* Figure out where we are in the process */
-               switch(auth->transaction) {
+               switch(le16_to_cpu(auth->transaction)) {
                case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE:
                        /* Check to make sure we have a challenge IE */
                        data = (u8 *)auth->info_element;
index 26c35253be334266680a01aa1579f794945b779f..73b4b13fbd8f0e7ac220c6fa9d17a8fe8d79f604 100644 (file)
@@ -148,11 +148,11 @@ ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
         * shouldn't the sequence number be in ieee80211? */
 }
 
-static u16
+static __le16
 ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
        struct ieee80211softmac_network *net)
 {
-       u16 capability = 0;
+       __le16 capability = 0;
 
        /* ESS and IBSS bits are set according to the current mode */
        switch (mac->ieee->iw_mode) {
@@ -163,8 +163,8 @@ ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
                capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
                break;
        case IW_MODE_AUTO:
-               capability = net->capabilities &
-                       (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
+               capability = cpu_to_le16(net->capabilities &
+                       (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS));
                break;
        default:
                /* bleh. we don't ever go to these modes */
@@ -182,7 +182,7 @@ ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
        /* Short Preamble */
        /* Always supported: we probably won't ever be powering devices which
         * dont support this... */
-       capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+       capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
 
        /* PBCC */
        /* Not widely used */
index 9f9fd2c6f6e27f2dabc5ced271040ca774a8a153..24e2b7294bf89e46874cd7dd7dd30f2d08c15c5f 100644 (file)
@@ -85,6 +85,13 @@ endchoice
 config IP_FIB_HASH
        def_bool ASK_IP_FIB_HASH || !IP_ADVANCED_ROUTER
 
+config IP_FIB_TRIE_STATS
+       bool "FIB TRIE statistics"
+       depends on IP_FIB_TRIE
+       ---help---
+         Keep track of statistics on structure of FIB TRIE table.
+         Useful for testing and measuring TRIE performance.
+
 config IP_MULTIPLE_TABLES
        bool "IP: policy routing"
        depends on IP_ADVANCED_ROUTER
index 93fe3966805de37bf456ecc2940e6db4c8a2cefc..ad40ef3f9ebcdedeac09b58a5bda14c0fe48a71a 100644 (file)
@@ -10,9 +10,10 @@ obj-y     := route.o inetpeer.o protocol.o \
             tcp_minisocks.o tcp_cong.o \
             datagram.o raw.o udp.o udplite.o \
             arp.o icmp.o devinet.o af_inet.o  igmp.o \
-            sysctl_net_ipv4.o fib_frontend.o fib_semantics.o \
+            fib_frontend.o fib_semantics.o \
             inet_fragment.o
 
+obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
 obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
 obj-$(CONFIG_IP_FIB_TRIE) += fib_trie.o
 obj-$(CONFIG_PROC_FS) += proc.o
index d2f22e74b26713b2125d2e6c2a7385eb47840336..09ca5293d08f3c354ad85cea31ddbb9f75c4c4db 100644 (file)
@@ -126,6 +126,10 @@ extern void ip_mc_drop_socket(struct sock *sk);
 static struct list_head inetsw[SOCK_MAX];
 static DEFINE_SPINLOCK(inetsw_lock);
 
+struct ipv4_config ipv4_config;
+
+EXPORT_SYMBOL(ipv4_config);
+
 /* New destruction routine */
 
 void inet_sock_destruct(struct sock *sk)
@@ -135,6 +139,8 @@ void inet_sock_destruct(struct sock *sk)
        __skb_queue_purge(&sk->sk_receive_queue);
        __skb_queue_purge(&sk->sk_error_queue);
 
+       sk_mem_reclaim(sk);
+
        if (sk->sk_type == SOCK_STREAM && sk->sk_state != TCP_CLOSE) {
                printk("Attempt to release TCP socket in state %d %p\n",
                       sk->sk_state, sk);
@@ -440,7 +446,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr_len < sizeof(struct sockaddr_in))
                goto out;
 
-       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+       chk_addr_ret = inet_addr_type(&init_net, addr->sin_addr.s_addr);
 
        /* Not specified by any standard per-se, however it breaks too
         * many applications when removed.  It is unfortunate since
@@ -789,12 +795,12 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                case SIOCADDRT:
                case SIOCDELRT:
                case SIOCRTMSG:
-                       err = ip_rt_ioctl(cmd, (void __user *)arg);
+                       err = ip_rt_ioctl(sk->sk_net, cmd, (void __user *)arg);
                        break;
                case SIOCDARP:
                case SIOCGARP:
                case SIOCSARP:
-                       err = arp_ioctl(cmd, (void __user *)arg);
+                       err = arp_ioctl(sk->sk_net, cmd, (void __user *)arg);
                        break;
                case SIOCGIFADDR:
                case SIOCSIFADDR:
@@ -838,6 +844,7 @@ const struct proto_ops inet_stream_ops = {
        .recvmsg           = sock_common_recvmsg,
        .mmap              = sock_no_mmap,
        .sendpage          = tcp_sendpage,
+       .splice_read       = tcp_splice_read,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_sock_common_setsockopt,
        .compat_getsockopt = compat_sock_common_getsockopt,
@@ -1106,7 +1113,7 @@ int inet_sk_rebuild_header(struct sock *sk)
        };
 
        security_sk_classify_flow(sk, &fl);
-       err = ip_route_output_flow(&rt, &fl, sk, 0);
+       err = ip_route_output_flow(&init_net, &rt, &fl, sk, 0);
 }
        if (!err)
                sk_setup_caps(sk, &rt->u.dst);
@@ -1237,7 +1244,7 @@ unsigned long snmp_fold_field(void *mib[], int offt)
 }
 EXPORT_SYMBOL_GPL(snmp_fold_field);
 
-int snmp_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
+int snmp_mib_init(void *ptr[2], size_t mibsize)
 {
        BUG_ON(ptr == NULL);
        ptr[0] = __alloc_percpu(mibsize);
@@ -1286,37 +1293,31 @@ static struct net_protocol udp_protocol = {
 
 static struct net_protocol icmp_protocol = {
        .handler =      icmp_rcv,
+       .no_policy =    1,
 };
 
 static int __init init_ipv4_mibs(void)
 {
        if (snmp_mib_init((void **)net_statistics,
-                         sizeof(struct linux_mib),
-                         __alignof__(struct linux_mib)) < 0)
+                         sizeof(struct linux_mib)) < 0)
                goto err_net_mib;
        if (snmp_mib_init((void **)ip_statistics,
-                         sizeof(struct ipstats_mib),
-                         __alignof__(struct ipstats_mib)) < 0)
+                         sizeof(struct ipstats_mib)) < 0)
                goto err_ip_mib;
        if (snmp_mib_init((void **)icmp_statistics,
-                         sizeof(struct icmp_mib),
-                         __alignof__(struct icmp_mib)) < 0)
+                         sizeof(struct icmp_mib)) < 0)
                goto err_icmp_mib;
        if (snmp_mib_init((void **)icmpmsg_statistics,
-                         sizeof(struct icmpmsg_mib),
-                         __alignof__(struct icmpmsg_mib)) < 0)
+                         sizeof(struct icmpmsg_mib)) < 0)
                goto err_icmpmsg_mib;
        if (snmp_mib_init((void **)tcp_statistics,
-                         sizeof(struct tcp_mib),
-                         __alignof__(struct tcp_mib)) < 0)
+                         sizeof(struct tcp_mib)) < 0)
                goto err_tcp_mib;
        if (snmp_mib_init((void **)udp_statistics,
-                         sizeof(struct udp_mib),
-                         __alignof__(struct udp_mib)) < 0)
+                         sizeof(struct udp_mib)) < 0)
                goto err_udp_mib;
        if (snmp_mib_init((void **)udplite_statistics,
-                         sizeof(struct udp_mib),
-                         __alignof__(struct udp_mib)) < 0)
+                         sizeof(struct udp_mib)) < 0)
                goto err_udplite_mib;
 
        tcp_mib_init();
@@ -1418,6 +1419,9 @@ static int __init inet_init(void)
        /* Setup TCP slab cache for open requests. */
        tcp_init();
 
+       /* Setup UDP memory threshold */
+       udp_init();
+
        /* Add UDP-Lite (RFC 3828) */
        udplite4_register();
 
@@ -1471,15 +1475,11 @@ static int __init ipv4_proc_init(void)
                goto out_tcp;
        if (udp4_proc_init())
                goto out_udp;
-       if (fib_proc_init())
-               goto out_fib;
        if (ip_misc_proc_init())
                goto out_misc;
 out:
        return rc;
 out_misc:
-       fib_proc_exit();
-out_fib:
        udp4_proc_exit();
 out_udp:
        tcp4_proc_exit();
index 5fc346d8b5665a344f80a8b82e6c2013b9dd549f..d76803a3dcae843f1ebf07794fdd0da6c34b9498 100644 (file)
@@ -169,6 +169,8 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
                if (ip_clear_mutable_options(iph, &dummy))
                        goto out;
        }
+
+       spin_lock(&x->lock);
        {
                u8 auth_data[MAX_AH_AUTH_LEN];
 
@@ -176,13 +178,16 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
                skb_push(skb, ihl);
                err = ah_mac_digest(ahp, skb, ah->auth_data);
                if (err)
-                       goto out;
-               err = -EINVAL;
-               if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
-                       x->stats.integrity_failed++;
-                       goto out;
-               }
+                       goto unlock;
+               if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len))
+                       err = -EBADMSG;
        }
+unlock:
+       spin_unlock(&x->lock);
+
+       if (err)
+               goto out;
+
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), work_buf, ihl);
        skb->transport_header = skb->network_header;
index 54a76b8b803ab23d530471cdd4c507ccfad5e3f0..5976c598cc4ba5e5cee2e7f089dc9cbd84f70a9a 100644 (file)
@@ -235,8 +235,6 @@ static int arp_constructor(struct neighbour *neigh)
        struct in_device *in_dev;
        struct neigh_parms *parms;
 
-       neigh->type = inet_addr_type(addr);
-
        rcu_read_lock();
        in_dev = __in_dev_get_rcu(dev);
        if (in_dev == NULL) {
@@ -244,6 +242,8 @@ static int arp_constructor(struct neighbour *neigh)
                return -EINVAL;
        }
 
+       neigh->type = inet_addr_type(&init_net, addr);
+
        parms = in_dev->arp_parms;
        __neigh_parms_put(neigh->parms);
        neigh->parms = neigh_parms_clone(parms);
@@ -341,14 +341,14 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
        switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
        default:
        case 0:         /* By default announce any local IP */
-               if (skb && inet_addr_type(ip_hdr(skb)->saddr) == RTN_LOCAL)
+               if (skb && inet_addr_type(&init_net, ip_hdr(skb)->saddr) == RTN_LOCAL)
                        saddr = ip_hdr(skb)->saddr;
                break;
        case 1:         /* Restrict announcements of saddr in same subnet */
                if (!skb)
                        break;
                saddr = ip_hdr(skb)->saddr;
-               if (inet_addr_type(saddr) == RTN_LOCAL) {
+               if (inet_addr_type(&init_net, saddr) == RTN_LOCAL) {
                        /* saddr should be known to target */
                        if (inet_addr_onlink(in_dev, target, saddr))
                                break;
@@ -382,8 +382,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
                read_unlock_bh(&neigh->lock);
 }
 
-static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
-                     __be32 sip, __be32 tip)
+static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
 {
        int scope;
 
@@ -403,7 +402,6 @@ static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
        case 3: /* Do not reply for scope host addresses */
                sip = 0;
                scope = RT_SCOPE_LINK;
-               dev = NULL;
                break;
        case 4: /* Reserved */
        case 5:
@@ -415,7 +413,7 @@ static int arp_ignore(struct in_device *in_dev, struct net_device *dev,
        default:
                return 0;
        }
-       return !inet_confirm_addr(dev, sip, tip, scope);
+       return !inet_confirm_addr(in_dev, sip, tip, scope);
 }
 
 static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
@@ -426,7 +424,7 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
        int flag = 0;
        /*unsigned long now; */
 
-       if (ip_route_output_key(&rt, &fl) < 0)
+       if (ip_route_output_key(&init_net, &rt, &fl) < 0)
                return 1;
        if (rt->u.dst.dev != dev) {
                NET_INC_STATS_BH(LINUX_MIB_ARPFILTER);
@@ -479,7 +477,7 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
 
        paddr = ((struct rtable*)skb->dst)->rt_gateway;
 
-       if (arp_set_predefined(inet_addr_type(paddr), haddr, paddr, dev))
+       if (arp_set_predefined(inet_addr_type(&init_net, paddr), haddr, paddr, dev))
                return 0;
 
        n = __neigh_lookup(&arp_tbl, &paddr, dev, 1);
@@ -777,7 +775,7 @@ static int arp_process(struct sk_buff *skb)
  *     Check for bad requests for 127.x.x.x and requests for multicast
  *     addresses.  If this is one such, delete it.
  */
-       if (LOOPBACK(tip) || MULTICAST(tip))
+       if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
                goto out;
 
 /*
@@ -806,8 +804,8 @@ static int arp_process(struct sk_buff *skb)
        /* Special case: IPv4 duplicate address detection packet (RFC2131) */
        if (sip == 0) {
                if (arp->ar_op == htons(ARPOP_REQUEST) &&
-                   inet_addr_type(tip) == RTN_LOCAL &&
-                   !arp_ignore(in_dev,dev,sip,tip))
+                   inet_addr_type(&init_net, tip) == RTN_LOCAL &&
+                   !arp_ignore(in_dev, sip, tip))
                        arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
                                 dev->dev_addr, sha);
                goto out;
@@ -825,7 +823,7 @@ static int arp_process(struct sk_buff *skb)
                                int dont_send = 0;
 
                                if (!dont_send)
-                                       dont_send |= arp_ignore(in_dev,dev,sip,tip);
+                                       dont_send |= arp_ignore(in_dev,sip,tip);
                                if (!dont_send && IN_DEV_ARPFILTER(in_dev))
                                        dont_send |= arp_filter(sip,tip,dev);
                                if (!dont_send)
@@ -835,9 +833,8 @@ static int arp_process(struct sk_buff *skb)
                        }
                        goto out;
                } else if (IN_DEV_FORWARD(in_dev)) {
-                       if ((rt->rt_flags&RTCF_DNAT) ||
-                           (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
-                            (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
+                           if (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
+                            (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &init_net, &tip, dev, 0))) {
                                n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
                                if (n)
                                        neigh_release(n);
@@ -860,14 +857,14 @@ static int arp_process(struct sk_buff *skb)
 
        n = __neigh_lookup(&arp_tbl, &sip, dev, 0);
 
-       if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) {
+       if (IPV4_DEVCONF_ALL(dev->nd_net, ARP_ACCEPT)) {
                /* Unsolicited ARP is not accepted by default.
                   It is possible, that this option should be enabled for some
                   devices (strip is candidate)
                 */
                if (n == NULL &&
                    arp->ar_op == htons(ARPOP_REPLY) &&
-                   inet_addr_type(sip) == RTN_UNICAST)
+                   inet_addr_type(&init_net, sip) == RTN_UNICAST)
                        n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
        }
 
@@ -952,44 +949,60 @@ out_of_mem:
  *     Set (create) an ARP cache entry.
  */
 
-static int arp_req_set(struct arpreq *r, struct net_device * dev)
+static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
 {
-       __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+       if (dev == NULL) {
+               IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
+               return 0;
+       }
+       if (__in_dev_get_rtnl(dev)) {
+               IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
+               return 0;
+       }
+       return -ENXIO;
+}
+
+static int arp_req_set_public(struct net *net, struct arpreq *r,
+               struct net_device *dev)
+{
+       __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+       __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
+
+       if (mask && mask != htonl(0xFFFFFFFF))
+               return -EINVAL;
+       if (!dev && (r->arp_flags & ATF_COM)) {
+               dev = dev_getbyhwaddr(net, r->arp_ha.sa_family,
+                               r->arp_ha.sa_data);
+               if (!dev)
+                       return -ENODEV;
+       }
+       if (mask) {
+               if (pneigh_lookup(&arp_tbl, net, &ip, dev, 1) == NULL)
+                       return -ENOBUFS;
+               return 0;
+       }
+
+       return arp_req_set_proxy(net, dev, 1);
+}
+
+static int arp_req_set(struct net *net, struct arpreq *r,
+               struct net_device * dev)
+{
+       __be32 ip;
        struct neighbour *neigh;
        int err;
 
-       if (r->arp_flags&ATF_PUBL) {
-               __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr;
-               if (mask && mask != htonl(0xFFFFFFFF))
-                       return -EINVAL;
-               if (!dev && (r->arp_flags & ATF_COM)) {
-                       dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family, r->arp_ha.sa_data);
-                       if (!dev)
-                               return -ENODEV;
-               }
-               if (mask) {
-                       if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
-                               return -ENOBUFS;
-                       return 0;
-               }
-               if (dev == NULL) {
-                       IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
-                       return 0;
-               }
-               if (__in_dev_get_rtnl(dev)) {
-                       IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
-                       return 0;
-               }
-               return -ENXIO;
-       }
+       if (r->arp_flags & ATF_PUBL)
+               return arp_req_set_public(net, r, dev);
 
+       ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
        if (r->arp_flags & ATF_PERM)
                r->arp_flags |= ATF_COM;
        if (dev == NULL) {
                struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
                                                         .tos = RTO_ONLINK } } };
                struct rtable * rt;
-               if ((err = ip_route_output_key(&rt, &fl)) != 0)
+               if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
                        return err;
                dev = rt->u.dst.dev;
                ip_rt_put(rt);
@@ -1066,37 +1079,37 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
        return err;
 }
 
-static int arp_req_delete(struct arpreq *r, struct net_device * dev)
+static int arp_req_delete_public(struct net *net, struct arpreq *r,
+               struct net_device *dev)
+{
+       __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr;
+       __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
+
+       if (mask == htonl(0xFFFFFFFF))
+               return pneigh_delete(&arp_tbl, net, &ip, dev);
+
+       if (mask)
+               return -EINVAL;
+
+       return arp_req_set_proxy(net, dev, 0);
+}
+
+static int arp_req_delete(struct net *net, struct arpreq *r,
+               struct net_device * dev)
 {
        int err;
-       __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
+       __be32 ip;
        struct neighbour *neigh;
 
-       if (r->arp_flags & ATF_PUBL) {
-               __be32 mask =
-                      ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
-               if (mask == htonl(0xFFFFFFFF))
-                       return pneigh_delete(&arp_tbl, &ip, dev);
-               if (mask == 0) {
-                       if (dev == NULL) {
-                               IPV4_DEVCONF_ALL(PROXY_ARP) = 0;
-                               return 0;
-                       }
-                       if (__in_dev_get_rtnl(dev)) {
-                               IN_DEV_CONF_SET(__in_dev_get_rtnl(dev),
-                                               PROXY_ARP, 0);
-                               return 0;
-                       }
-                       return -ENXIO;
-               }
-               return -EINVAL;
-       }
+       if (r->arp_flags & ATF_PUBL)
+               return arp_req_delete_public(net, r, dev);
 
+       ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
        if (dev == NULL) {
                struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip,
                                                         .tos = RTO_ONLINK } } };
                struct rtable * rt;
-               if ((err = ip_route_output_key(&rt, &fl)) != 0)
+               if ((err = ip_route_output_key(net, &rt, &fl)) != 0)
                        return err;
                dev = rt->u.dst.dev;
                ip_rt_put(rt);
@@ -1119,7 +1132,7 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev)
  *     Handle an ARP layer I/O control request.
  */
 
-int arp_ioctl(unsigned int cmd, void __user *arg)
+int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 {
        int err;
        struct arpreq r;
@@ -1151,7 +1164,7 @@ int arp_ioctl(unsigned int cmd, void __user *arg)
        rtnl_lock();
        if (r.arp_dev[0]) {
                err = -ENODEV;
-               if ((dev = __dev_get_by_name(&init_net, r.arp_dev)) == NULL)
+               if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL)
                        goto out;
 
                /* Mmmm... It is wrong... ARPHRD_NETROM==0 */
@@ -1167,10 +1180,10 @@ int arp_ioctl(unsigned int cmd, void __user *arg)
 
        switch (cmd) {
        case SIOCDARP:
-               err = arp_req_delete(&r, dev);
+               err = arp_req_delete(net, &r, dev);
                break;
        case SIOCSARP:
-               err = arp_req_set(&r, dev);
+               err = arp_req_set(net, &r, dev);
                break;
        case SIOCGARP:
                err = arp_req_get(&r, dev);
@@ -1359,8 +1372,8 @@ static const struct seq_operations arp_seq_ops = {
 
 static int arp_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &arp_seq_ops,
-                       sizeof(struct neigh_seq_state));
+       return seq_open_net(inode, file, &arp_seq_ops,
+                           sizeof(struct neigh_seq_state));
 }
 
 static const struct file_operations arp_seq_fops = {
@@ -1368,7 +1381,7 @@ static const struct file_operations arp_seq_fops = {
        .open           = arp_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
 };
 
 static int __init arp_proc_init(void)
index f18e88bc86ecb5c8696e89b44171ed697b192cd8..d4dc4eb48d95ab32c79b96297e7e1a5bb8c23dcc 100644 (file)
@@ -63,7 +63,7 @@ struct cipso_v4_domhsh_entry {
  * probably be turned into a hash table or something similar so we
  * can do quick lookups. */
 static DEFINE_SPINLOCK(cipso_v4_doi_list_lock);
-static struct list_head cipso_v4_doi_list = LIST_HEAD_INIT(cipso_v4_doi_list);
+static LIST_HEAD(cipso_v4_doi_list);
 
 /* Label mapping cache */
 int cipso_v4_cache_enabled = 1;
index 0301dd468cf47638fdd7d434c35ac44a7b96cae6..0c0c73f368ce7c930e14000a9ef35d63f01115c0 100644 (file)
@@ -40,7 +40,7 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 
        oif = sk->sk_bound_dev_if;
        saddr = inet->saddr;
-       if (MULTICAST(usin->sin_addr.s_addr)) {
+       if (ipv4_is_multicast(usin->sin_addr.s_addr)) {
                if (!oif)
                        oif = inet->mc_index;
                if (!saddr)
index b42f74617bacfffaaf3af90856cc014ecf239dd5..21f71bf912d5b1621ec81fc4807dcde7f7355166 100644 (file)
@@ -62,6 +62,7 @@
 #include <net/route.h>
 #include <net/ip_fib.h>
 #include <net/rtnetlink.h>
+#include <net/net_namespace.h>
 
 struct ipv4_devconf ipv4_devconf = {
        .data = {
@@ -82,7 +83,8 @@ static struct ipv4_devconf ipv4_devconf_dflt = {
        },
 };
 
-#define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr)
+#define IPV4_DEVCONF_DFLT(net, attr) \
+       IPV4_DEVCONF((*net->ipv4.devconf_dflt), attr)
 
 static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = {
        [IFA_LOCAL]             = { .type = NLA_U32 },
@@ -98,9 +100,15 @@ static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                         int destroy);
 #ifdef CONFIG_SYSCTL
-static void devinet_sysctl_register(struct in_device *in_dev,
-                                   struct ipv4_devconf *p);
-static void devinet_sysctl_unregister(struct ipv4_devconf *p);
+static void devinet_sysctl_register(struct in_device *idev);
+static void devinet_sysctl_unregister(struct in_device *idev);
+#else
+static inline void devinet_sysctl_register(struct in_device *idev)
+{
+}
+static inline void devinet_sysctl_unregister(struct in_device *idev)
+{
+}
 #endif
 
 /* Locks all the inet devices. */
@@ -157,24 +165,18 @@ static struct in_device *inetdev_init(struct net_device *dev)
        if (!in_dev)
                goto out;
        INIT_RCU_HEAD(&in_dev->rcu_head);
-       memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
+       memcpy(&in_dev->cnf, dev->nd_net->ipv4.devconf_dflt,
+                       sizeof(in_dev->cnf));
        in_dev->cnf.sysctl = NULL;
        in_dev->dev = dev;
        if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
                goto out_kfree;
        /* Reference in_dev->dev */
        dev_hold(dev);
-#ifdef CONFIG_SYSCTL
-       neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
-                             NET_IPV4_NEIGH, "ipv4", NULL, NULL);
-#endif
-
        /* Account for reference dev->ip_ptr (below) */
        in_dev_hold(in_dev);
 
-#ifdef CONFIG_SYSCTL
-       devinet_sysctl_register(in_dev, &in_dev->cnf);
-#endif
+       devinet_sysctl_register(in_dev);
        ip_mc_init_dev(in_dev);
        if (dev->flags & IFF_UP)
                ip_mc_up(in_dev);
@@ -213,15 +215,9 @@ static void inetdev_destroy(struct in_device *in_dev)
                inet_free_ifa(ifa);
        }
 
-#ifdef CONFIG_SYSCTL
-       devinet_sysctl_unregister(&in_dev->cnf);
-#endif
-
        dev->ip_ptr = NULL;
 
-#ifdef CONFIG_SYSCTL
-       neigh_sysctl_unregister(in_dev->arp_parms);
-#endif
+       devinet_sysctl_unregister(in_dev);
        neigh_parms_release(&arp_tbl, in_dev->arp_parms);
        arp_ifdown(dev);
 
@@ -408,17 +404,17 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
                in_dev_hold(in_dev);
                ifa->ifa_dev = in_dev;
        }
-       if (LOOPBACK(ifa->ifa_local))
+       if (ipv4_is_loopback(ifa->ifa_local))
                ifa->ifa_scope = RT_SCOPE_HOST;
        return inet_insert_ifa(ifa);
 }
 
-struct in_device *inetdev_by_index(int ifindex)
+struct in_device *inetdev_by_index(struct net *net, int ifindex)
 {
        struct net_device *dev;
        struct in_device *in_dev = NULL;
        read_lock(&dev_base_lock);
-       dev = __dev_get_by_index(&init_net, ifindex);
+       dev = __dev_get_by_index(net, ifindex);
        if (dev)
                in_dev = in_dev_get(dev);
        read_unlock(&dev_base_lock);
@@ -441,6 +437,7 @@ struct in_ifaddr *inet_ifa_byprefix(struct in_device *in_dev, __be32 prefix,
 
 static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct nlattr *tb[IFA_MAX+1];
        struct in_device *in_dev;
        struct ifaddrmsg *ifm;
@@ -449,12 +446,15 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
 
        ASSERT_RTNL();
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
        if (err < 0)
                goto errout;
 
        ifm = nlmsg_data(nlh);
-       in_dev = inetdev_by_index(ifm->ifa_index);
+       in_dev = inetdev_by_index(net, ifm->ifa_index);
        if (in_dev == NULL) {
                err = -ENODEV;
                goto errout;
@@ -560,10 +560,14 @@ errout:
 
 static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct in_ifaddr *ifa;
 
        ASSERT_RTNL();
 
+       if (net != &init_net)
+               return -EINVAL;
+
        ifa = rtm_to_ifaddr(nlh);
        if (IS_ERR(ifa))
                return PTR_ERR(ifa);
@@ -579,7 +583,7 @@ static __inline__ int inet_abc_len(__be32 addr)
 {
        int rc = -1;    /* Something else, probably a multicast. */
 
-       if (ZERONET(addr))
+       if (ipv4_is_zeronet(addr))
                rc = 0;
        else {
                __u32 haddr = ntohl(addr);
@@ -964,28 +968,25 @@ static __be32 confirm_addr_indev(struct in_device *in_dev, __be32 dst,
 
 /*
  * Confirm that local IP address exists using wildcards:
- * - dev: only on this interface, 0=any interface
+ * - in_dev: only on this interface, 0=any interface
  * - dst: only in the same subnet as dst, 0=any dst
  * - local: address, 0=autoselect the local address
  * - scope: maximum allowed scope value for the local address
  */
-__be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope)
+__be32 inet_confirm_addr(struct in_device *in_dev,
+                        __be32 dst, __be32 local, int scope)
 {
        __be32 addr = 0;
-       struct in_device *in_dev;
-
-       if (dev) {
-               rcu_read_lock();
-               if ((in_dev = __in_dev_get_rcu(dev)))
-                       addr = confirm_addr_indev(in_dev, dst, local, scope);
-               rcu_read_unlock();
+       struct net_device *dev;
+       struct net *net;
 
-               return addr;
-       }
+       if (scope != RT_SCOPE_LINK)
+               return confirm_addr_indev(in_dev, dst, local, scope);
 
+       net = in_dev->dev->nd_net;
        read_lock(&dev_base_lock);
        rcu_read_lock();
-       for_each_netdev(&init_net, dev) {
+       for_each_netdev(net, dev) {
                if ((in_dev = __in_dev_get_rcu(dev))) {
                        addr = confirm_addr_indev(in_dev, dst, local, scope);
                        if (addr)
@@ -1106,13 +1107,8 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
                 */
                inetdev_changename(dev, in_dev);
 
-#ifdef CONFIG_SYSCTL
-               devinet_sysctl_unregister(&in_dev->cnf);
-               neigh_sysctl_unregister(in_dev->arp_parms);
-               neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
-                                     NET_IPV4_NEIGH, "ipv4", NULL, NULL);
-               devinet_sysctl_register(in_dev, &in_dev->cnf);
-#endif
+               devinet_sysctl_unregister(in_dev);
+               devinet_sysctl_register(in_dev);
                break;
        }
 out:
@@ -1174,12 +1170,16 @@ nla_put_failure:
 
 static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int idx, ip_idx;
        struct net_device *dev;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
        int s_ip_idx, s_idx = cb->args[0];
 
+       if (net != &init_net)
+               return 0;
+
        s_ip_idx = ip_idx = cb->args[1];
        idx = 0;
        for_each_netdev(&init_net, dev) {
@@ -1228,28 +1228,50 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
+       err = rtnl_notify(skb, &init_net, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV4_IFADDR, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV4_IFADDR, err);
 }
 
 #ifdef CONFIG_SYSCTL
 
-static void devinet_copy_dflt_conf(int i)
+static void devinet_copy_dflt_conf(struct net *net, int i)
 {
        struct net_device *dev;
 
        read_lock(&dev_base_lock);
-       for_each_netdev(&init_net, dev) {
+       for_each_netdev(net, dev) {
                struct in_device *in_dev;
                rcu_read_lock();
                in_dev = __in_dev_get_rcu(dev);
                if (in_dev && !test_bit(i, in_dev->cnf.state))
-                       in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i];
+                       in_dev->cnf.data[i] = net->ipv4.devconf_dflt->data[i];
+               rcu_read_unlock();
+       }
+       read_unlock(&dev_base_lock);
+}
+
+static void inet_forward_change(struct net *net)
+{
+       struct net_device *dev;
+       int on = IPV4_DEVCONF_ALL(net, FORWARDING);
+
+       IPV4_DEVCONF_ALL(net, ACCEPT_REDIRECTS) = !on;
+       IPV4_DEVCONF_DFLT(net, FORWARDING) = on;
+
+       read_lock(&dev_base_lock);
+       for_each_netdev(net, dev) {
+               struct in_device *in_dev;
+               rcu_read_lock();
+               in_dev = __in_dev_get_rcu(dev);
+               if (in_dev)
+                       IN_DEV_CONF_SET(in_dev, FORWARDING, on);
                rcu_read_unlock();
        }
        read_unlock(&dev_base_lock);
+
+       rt_cache_flush(0);
 }
 
 static int devinet_conf_proc(ctl_table *ctl, int write,
@@ -1260,12 +1282,13 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
 
        if (write) {
                struct ipv4_devconf *cnf = ctl->extra1;
+               struct net *net = ctl->extra2;
                int i = (int *)ctl->data - cnf->data;
 
                set_bit(i, cnf->state);
 
-               if (cnf == &ipv4_devconf_dflt)
-                       devinet_copy_dflt_conf(i);
+               if (cnf == net->ipv4.devconf_dflt)
+                       devinet_copy_dflt_conf(net, i);
        }
 
        return ret;
@@ -1276,6 +1299,7 @@ static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
                               void __user *newval, size_t newlen)
 {
        struct ipv4_devconf *cnf;
+       struct net *net;
        int *valp = table->data;
        int new;
        int i;
@@ -1311,38 +1335,17 @@ static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
        *valp = new;
 
        cnf = table->extra1;
+       net = table->extra2;
        i = (int *)table->data - cnf->data;
 
        set_bit(i, cnf->state);
 
-       if (cnf == &ipv4_devconf_dflt)
-               devinet_copy_dflt_conf(i);
+       if (cnf == net->ipv4.devconf_dflt)
+               devinet_copy_dflt_conf(net, i);
 
        return 1;
 }
 
-void inet_forward_change(void)
-{
-       struct net_device *dev;
-       int on = IPV4_DEVCONF_ALL(FORWARDING);
-
-       IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on;
-       IPV4_DEVCONF_DFLT(FORWARDING) = on;
-
-       read_lock(&dev_base_lock);
-       for_each_netdev(&init_net, dev) {
-               struct in_device *in_dev;
-               rcu_read_lock();
-               in_dev = __in_dev_get_rcu(dev);
-               if (in_dev)
-                       IN_DEV_CONF_SET(in_dev, FORWARDING, on);
-               rcu_read_unlock();
-       }
-       read_unlock(&dev_base_lock);
-
-       rt_cache_flush(0);
-}
-
 static int devinet_sysctl_forward(ctl_table *ctl, int write,
                                  struct file* filp, void __user *buffer,
                                  size_t *lenp, loff_t *ppos)
@@ -1352,9 +1355,11 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
        int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
        if (write && *valp != val) {
-               if (valp == &IPV4_DEVCONF_ALL(FORWARDING))
-                       inet_forward_change();
-               else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING))
+               struct net *net = ctl->extra2;
+
+               if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING))
+                       inet_forward_change(net);
+               else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING))
                        rt_cache_flush(0);
        }
 
@@ -1419,11 +1424,8 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
 
 static struct devinet_sysctl_table {
        struct ctl_table_header *sysctl_header;
-       ctl_table               devinet_vars[__NET_IPV4_CONF_MAX];
-       ctl_table               devinet_dev[2];
-       ctl_table               devinet_conf_dir[2];
-       ctl_table               devinet_proto_dir[2];
-       ctl_table               devinet_root_dir[2];
+       struct ctl_table devinet_vars[__NET_IPV4_CONF_MAX];
+       char *dev_name;
 } devinet_sysctl = {
        .devinet_vars = {
                DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding",
@@ -1455,62 +1457,32 @@ static struct devinet_sysctl_table {
                DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES,
                                              "promote_secondaries"),
        },
-       .devinet_dev = {
-               {
-                       .ctl_name       = NET_PROTO_CONF_ALL,
-                       .procname       = "all",
-                       .mode           = 0555,
-                       .child          = devinet_sysctl.devinet_vars,
-               },
-       },
-       .devinet_conf_dir = {
-               {
-                       .ctl_name       = NET_IPV4_CONF,
-                       .procname       = "conf",
-                       .mode           = 0555,
-                       .child          = devinet_sysctl.devinet_dev,
-               },
-       },
-       .devinet_proto_dir = {
-               {
-                       .ctl_name       = NET_IPV4,
-                       .procname       = "ipv4",
-                       .mode           = 0555,
-                       .child          = devinet_sysctl.devinet_conf_dir,
-               },
-       },
-       .devinet_root_dir = {
-               {
-                       .ctl_name       = CTL_NET,
-                       .procname       = "net",
-                       .mode           = 0555,
-                       .child          = devinet_sysctl.devinet_proto_dir,
-               },
-       },
 };
 
-static void devinet_sysctl_register(struct in_device *in_dev,
-                                   struct ipv4_devconf *p)
+static int __devinet_sysctl_register(struct net *net, char *dev_name,
+               int ctl_name, struct ipv4_devconf *p)
 {
        int i;
-       struct net_device *dev = in_dev ? in_dev->dev : NULL;
-       struct devinet_sysctl_table *t = kmemdup(&devinet_sysctl, sizeof(*t),
-                                                GFP_KERNEL);
-       char *dev_name = NULL;
+       struct devinet_sysctl_table *t;
 
+#define DEVINET_CTL_PATH_DEV   3
+
+       struct ctl_path devinet_ctl_path[] = {
+               { .procname = "net", .ctl_name = CTL_NET, },
+               { .procname = "ipv4", .ctl_name = NET_IPV4, },
+               { .procname = "conf", .ctl_name = NET_IPV4_CONF, },
+               { /* to be set */ },
+               { },
+       };
+
+       t = kmemdup(&devinet_sysctl, sizeof(*t), GFP_KERNEL);
        if (!t)
-               return;
+               goto out;
+
        for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
                t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
                t->devinet_vars[i].extra1 = p;
-       }
-
-       if (dev) {
-               dev_name = dev->name;
-               t->devinet_dev[0].ctl_name = dev->ifindex;
-       } else {
-               dev_name = "default";
-               t->devinet_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
+               t->devinet_vars[i].extra2 = net;
        }
 
        /*
@@ -1518,56 +1490,183 @@ static void devinet_sysctl_register(struct in_device *in_dev,
         * by sysctl and we wouldn't want anyone to change it under our feet
         * (see SIOCSIFNAME).
         */
-       dev_name = kstrdup(dev_name, GFP_KERNEL);
-       if (!dev_name)
-           goto free;
+       t->dev_name = kstrdup(dev_name, GFP_KERNEL);
+       if (!t->dev_name)
+               goto free;
 
-       t->devinet_dev[0].procname    = dev_name;
-       t->devinet_dev[0].child       = t->devinet_vars;
-       t->devinet_conf_dir[0].child  = t->devinet_dev;
-       t->devinet_proto_dir[0].child = t->devinet_conf_dir;
-       t->devinet_root_dir[0].child  = t->devinet_proto_dir;
+       devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name;
+       devinet_ctl_path[DEVINET_CTL_PATH_DEV].ctl_name = ctl_name;
 
-       t->sysctl_header = register_sysctl_table(t->devinet_root_dir);
+       t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path,
+                       t->devinet_vars);
        if (!t->sysctl_header)
-           goto free_procname;
+               goto free_procname;
 
        p->sysctl = t;
-       return;
+       return 0;
 
-       /* error path */
- free_procname:
-       kfree(dev_name);
- free:
+free_procname:
+       kfree(t->dev_name);
+free:
        kfree(t);
-       return;
+out:
+       return -ENOBUFS;
 }
 
-static void devinet_sysctl_unregister(struct ipv4_devconf *p)
+static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
+{
+       struct devinet_sysctl_table *t = cnf->sysctl;
+
+       if (t == NULL)
+               return;
+
+       cnf->sysctl = NULL;
+       unregister_sysctl_table(t->sysctl_header);
+       kfree(t->dev_name);
+       kfree(t);
+}
+
+static void devinet_sysctl_register(struct in_device *idev)
+{
+       neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4,
+                       NET_IPV4_NEIGH, "ipv4", NULL, NULL);
+       __devinet_sysctl_register(idev->dev->nd_net, idev->dev->name,
+                       idev->dev->ifindex, &idev->cnf);
+}
+
+static void devinet_sysctl_unregister(struct in_device *idev)
+{
+       __devinet_sysctl_unregister(&idev->cnf);
+       neigh_sysctl_unregister(idev->arp_parms);
+}
+
+static struct ctl_table ctl_forward_entry[] = {
+       {
+               .ctl_name       = NET_IPV4_FORWARD,
+               .procname       = "ip_forward",
+               .data           = &ipv4_devconf.data[
+                                       NET_IPV4_CONF_FORWARDING - 1],
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = devinet_sysctl_forward,
+               .strategy       = devinet_conf_sysctl,
+               .extra1         = &ipv4_devconf,
+               .extra2         = &init_net,
+       },
+       { },
+};
+
+static __net_initdata struct ctl_path net_ipv4_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv4", .ctl_name = NET_IPV4, },
+       { },
+};
+#endif
+
+static __net_init int devinet_init_net(struct net *net)
 {
-       if (p->sysctl) {
-               struct devinet_sysctl_table *t = p->sysctl;
-               p->sysctl = NULL;
-               unregister_sysctl_table(t->sysctl_header);
-               kfree(t->devinet_dev[0].procname);
-               kfree(t);
+       int err;
+       struct ipv4_devconf *all, *dflt;
+#ifdef CONFIG_SYSCTL
+       struct ctl_table *tbl = ctl_forward_entry;
+       struct ctl_table_header *forw_hdr;
+#endif
+
+       err = -ENOMEM;
+       all = &ipv4_devconf;
+       dflt = &ipv4_devconf_dflt;
+
+       if (net != &init_net) {
+               all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL);
+               if (all == NULL)
+                       goto err_alloc_all;
+
+               dflt = kmemdup(dflt, sizeof(ipv4_devconf_dflt), GFP_KERNEL);
+               if (dflt == NULL)
+                       goto err_alloc_dflt;
+
+#ifdef CONFIG_SYSCTL
+               tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL);
+               if (tbl == NULL)
+                       goto err_alloc_ctl;
+
+               tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1];
+               tbl[0].extra1 = all;
+               tbl[0].extra2 = net;
+#endif
        }
+
+#ifdef CONFIG_SYSCTL
+       err = __devinet_sysctl_register(net, "all",
+                       NET_PROTO_CONF_ALL, all);
+       if (err < 0)
+               goto err_reg_all;
+
+       err = __devinet_sysctl_register(net, "default",
+                       NET_PROTO_CONF_DEFAULT, dflt);
+       if (err < 0)
+               goto err_reg_dflt;
+
+       err = -ENOMEM;
+       forw_hdr = register_net_sysctl_table(net, net_ipv4_path, tbl);
+       if (forw_hdr == NULL)
+               goto err_reg_ctl;
+       net->ipv4.forw_hdr = forw_hdr;
+#endif
+
+       net->ipv4.devconf_all = all;
+       net->ipv4.devconf_dflt = dflt;
+       return 0;
+
+#ifdef CONFIG_SYSCTL
+err_reg_ctl:
+       __devinet_sysctl_unregister(dflt);
+err_reg_dflt:
+       __devinet_sysctl_unregister(all);
+err_reg_all:
+       if (tbl != ctl_forward_entry)
+               kfree(tbl);
+err_alloc_ctl:
+#endif
+       if (dflt != &ipv4_devconf_dflt)
+               kfree(dflt);
+err_alloc_dflt:
+       if (all != &ipv4_devconf)
+               kfree(all);
+err_alloc_all:
+       return err;
 }
+
+static __net_exit void devinet_exit_net(struct net *net)
+{
+#ifdef CONFIG_SYSCTL
+       struct ctl_table *tbl;
+
+       tbl = net->ipv4.forw_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.forw_hdr);
+       __devinet_sysctl_unregister(net->ipv4.devconf_dflt);
+       __devinet_sysctl_unregister(net->ipv4.devconf_all);
+       kfree(tbl);
 #endif
+       kfree(net->ipv4.devconf_dflt);
+       kfree(net->ipv4.devconf_all);
+}
+
+static __net_initdata struct pernet_operations devinet_ops = {
+       .init = devinet_init_net,
+       .exit = devinet_exit_net,
+};
 
 void __init devinet_init(void)
 {
+       register_pernet_subsys(&devinet_ops);
+
        register_gifconf(PF_INET, inet_gifconf);
        register_netdevice_notifier(&ip_netdev_notifier);
 
        rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL);
        rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL);
        rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr);
-#ifdef CONFIG_SYSCTL
-       devinet_sysctl.sysctl_header =
-               register_sysctl_table(devinet_sysctl.devinet_root_dir);
-       devinet_sysctl_register(NULL, &ipv4_devconf_dflt);
-#endif
 }
 
 EXPORT_SYMBOL(in_dev_finish_destroy);
index 1738113268bc12f1e1a23e4a1ca14bb82a637ffa..28ea5c77ca238a72a424ae292c2decc622c2d70e 100644 (file)
@@ -163,7 +163,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        u8 nexthdr[2];
        struct scatterlist *sg;
        int padlen;
-       int err;
+       int err = -EINVAL;
 
        if (!pskb_may_pull(skb, sizeof(*esph)))
                goto out;
@@ -171,28 +171,31 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        if (elen <= 0 || (elen & (blksize-1)))
                goto out;
 
+       if ((err = skb_cow_data(skb, 0, &trailer)) < 0)
+               goto out;
+       nfrags = err;
+
+       skb->ip_summed = CHECKSUM_NONE;
+
+       spin_lock(&x->lock);
+
        /* If integrity check is required, do this. */
        if (esp->auth.icv_full_len) {
                u8 sum[alen];
 
                err = esp_mac_digest(esp, skb, 0, skb->len - alen);
                if (err)
-                       goto out;
+                       goto unlock;
 
                if (skb_copy_bits(skb, skb->len - alen, sum, alen))
                        BUG();
 
                if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-                       x->stats.integrity_failed++;
-                       goto out;
+                       err = -EBADMSG;
+                       goto unlock;
                }
        }
 
-       if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)
-               goto out;
-
-       skb->ip_summed = CHECKSUM_NONE;
-
        esph = (struct ip_esp_hdr *)skb->data;
 
        /* Get ivec. This can be wrong, check against another impls. */
@@ -202,9 +205,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        sg = &esp->sgbuf[0];
 
        if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
+               err = -ENOMEM;
                sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
                if (!sg)
-                       goto out;
+                       goto unlock;
        }
        sg_init_table(sg, nfrags);
        skb_to_sgvec(skb, sg,
@@ -213,12 +217,17 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
        if (unlikely(sg != &esp->sgbuf[0]))
                kfree(sg);
+
+unlock:
+       spin_unlock(&x->lock);
+
        if (unlikely(err))
-               return err;
+               goto out;
 
        if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
                BUG();
 
+       err = -EINVAL;
        padlen = nexthdr[0];
        if (padlen+2 >= elen)
                goto out;
@@ -276,7 +285,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
        return nexthdr[1];
 
 out:
-       return -EINVAL;
+       return err;
 }
 
 static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
index 97abf934d1852931d36a18f8027d1597fa66e135..d28261826bc2b35b775946a378cef1959fa99077 100644 (file)
 #include <net/ip_fib.h>
 #include <net/rtnetlink.h>
 
-#define FFprint(a...) printk(KERN_DEBUG a)
+#ifndef CONFIG_IP_MULTIPLE_TABLES
 
-static struct sock *fibnl;
+static int __net_init fib4_rules_init(struct net *net)
+{
+       struct fib_table *local_table, *main_table;
 
-#ifndef CONFIG_IP_MULTIPLE_TABLES
+       local_table = fib_hash_table(RT_TABLE_LOCAL);
+       if (local_table == NULL)
+               return -ENOMEM;
 
-struct fib_table *ip_fib_local_table;
-struct fib_table *ip_fib_main_table;
+       main_table  = fib_hash_table(RT_TABLE_MAIN);
+       if (main_table == NULL)
+               goto fail;
 
-#define FIB_TABLE_HASHSZ 1
-static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
+       hlist_add_head_rcu(&local_table->tb_hlist,
+                               &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX]);
+       hlist_add_head_rcu(&main_table->tb_hlist,
+                               &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]);
+       return 0;
 
-static void __init fib4_rules_init(void)
-{
-       ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
-       hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
-       ip_fib_main_table  = fib_hash_init(RT_TABLE_MAIN);
-       hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
+fail:
+       kfree(local_table);
+       return -ENOMEM;
 }
 #else
 
-#define FIB_TABLE_HASHSZ 256
-static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
-
-struct fib_table *fib_new_table(u32 id)
+struct fib_table *fib_new_table(struct net *net, u32 id)
 {
        struct fib_table *tb;
        unsigned int h;
 
        if (id == 0)
                id = RT_TABLE_MAIN;
-       tb = fib_get_table(id);
+       tb = fib_get_table(net, id);
        if (tb)
                return tb;
-       tb = fib_hash_init(id);
+
+       tb = fib_hash_table(id);
        if (!tb)
                return NULL;
        h = id & (FIB_TABLE_HASHSZ - 1);
-       hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]);
+       hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]);
        return tb;
 }
 
-struct fib_table *fib_get_table(u32 id)
+struct fib_table *fib_get_table(struct net *net, u32 id)
 {
        struct fib_table *tb;
        struct hlist_node *node;
+       struct hlist_head *head;
        unsigned int h;
 
        if (id == 0)
                id = RT_TABLE_MAIN;
        h = id & (FIB_TABLE_HASHSZ - 1);
+
        rcu_read_lock();
-       hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) {
+       head = &net->ipv4.fib_table_hash[h];
+       hlist_for_each_entry_rcu(tb, node, head, tb_hlist) {
                if (tb->tb_id == id) {
                        rcu_read_unlock();
                        return tb;
@@ -110,15 +116,32 @@ struct fib_table *fib_get_table(u32 id)
 }
 #endif /* CONFIG_IP_MULTIPLE_TABLES */
 
-static void fib_flush(void)
+void fib_select_default(struct net *net,
+                       const struct flowi *flp, struct fib_result *res)
+{
+       struct fib_table *tb;
+       int table = RT_TABLE_MAIN;
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+       if (res->r == NULL || res->r->action != FR_ACT_TO_TBL)
+               return;
+       table = res->r->table;
+#endif
+       tb = fib_get_table(net, table);
+       if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
+               tb->tb_select_default(tb, flp, res);
+}
+
+static void fib_flush(struct net *net)
 {
        int flushed = 0;
        struct fib_table *tb;
        struct hlist_node *node;
+       struct hlist_head *head;
        unsigned int h;
 
        for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
-               hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist)
+               head = &net->ipv4.fib_table_hash[h];
+               hlist_for_each_entry(tb, node, head, tb_hlist)
                        flushed += tb->tb_flush(tb);
        }
 
@@ -130,7 +153,7 @@ static void fib_flush(void)
  *     Find the first device with a given source address.
  */
 
-struct net_device * ip_dev_find(__be32 addr)
+struct net_device * ip_dev_find(struct net *net, __be32 addr)
 {
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result res;
@@ -141,7 +164,7 @@ struct net_device * ip_dev_find(__be32 addr)
        res.r = NULL;
 #endif
 
-       local_table = fib_get_table(RT_TABLE_LOCAL);
+       local_table = fib_get_table(net, RT_TABLE_LOCAL);
        if (!local_table || local_table->tb_lookup(local_table, &fl, &res))
                return NULL;
        if (res.type != RTN_LOCAL)
@@ -155,33 +178,51 @@ out:
        return dev;
 }
 
-unsigned inet_addr_type(__be32 addr)
+/*
+ * Find address type as if only "dev" was present in the system. If
+ * on_dev is NULL then all interfaces are taken into consideration.
+ */
+static inline unsigned __inet_dev_addr_type(struct net *net,
+                                           const struct net_device *dev,
+                                           __be32 addr)
 {
        struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result       res;
        unsigned ret = RTN_BROADCAST;
        struct fib_table *local_table;
 
-       if (ZERONET(addr) || BADCLASS(addr))
+       if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr))
                return RTN_BROADCAST;
-       if (MULTICAST(addr))
+       if (ipv4_is_multicast(addr))
                return RTN_MULTICAST;
 
 #ifdef CONFIG_IP_MULTIPLE_TABLES
        res.r = NULL;
 #endif
 
-       local_table = fib_get_table(RT_TABLE_LOCAL);
+       local_table = fib_get_table(net, RT_TABLE_LOCAL);
        if (local_table) {
                ret = RTN_UNICAST;
                if (!local_table->tb_lookup(local_table, &fl, &res)) {
-                       ret = res.type;
+                       if (!dev || dev == res.fi->fib_dev)
+                               ret = res.type;
                        fib_res_put(&res);
                }
        }
        return ret;
 }
 
+unsigned int inet_addr_type(struct net *net, __be32 addr)
+{
+       return __inet_dev_addr_type(net, NULL, addr);
+}
+
+unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
+                               __be32 addr)
+{
+       return __inet_dev_addr_type(net, dev, addr);
+}
+
 /* Given (packet source, input interface) and optional (dst, oif, tos):
    - (main) check, that source is valid i.e. not broadcast or our local
      address.
@@ -202,6 +243,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
        struct fib_result res;
        int no_addr, rpf;
        int ret;
+       struct net *net;
 
        no_addr = rpf = 0;
        rcu_read_lock();
@@ -215,7 +257,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
        if (in_dev == NULL)
                goto e_inval;
 
-       if (fib_lookup(&fl, &res))
+       net = dev->nd_net;
+       if (fib_lookup(net, &fl, &res))
                goto last_resort;
        if (res.type != RTN_UNICAST)
                goto e_inval_res;
@@ -239,7 +282,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
        fl.oif = dev->ifindex;
 
        ret = 0;
-       if (fib_lookup(&fl, &res) == 0) {
+       if (fib_lookup(net, &fl, &res) == 0) {
                if (res.type == RTN_UNICAST) {
                        *spec_dst = FIB_RES_PREFSRC(res);
                        ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
@@ -278,13 +321,14 @@ static int put_rtax(struct nlattr *mx, int len, int type, u32 value)
        return len + nla_total_size(4);
 }
 
-static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
+static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
                                 struct fib_config *cfg)
 {
        __be32 addr;
        int plen;
 
        memset(cfg, 0, sizeof(*cfg));
+       cfg->fc_nlinfo.nl_net = net;
 
        if (rt->rt_dst.sa_family != AF_INET)
                return -EAFNOSUPPORT;
@@ -345,7 +389,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
                colon = strchr(devname, ':');
                if (colon)
                        *colon = 0;
-               dev = __dev_get_by_name(&init_net, devname);
+               dev = __dev_get_by_name(net, devname);
                if (!dev)
                        return -ENODEV;
                cfg->fc_oif = dev->ifindex;
@@ -368,7 +412,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
        if (rt->rt_gateway.sa_family == AF_INET && addr) {
                cfg->fc_gw = addr;
                if (rt->rt_flags & RTF_GATEWAY &&
-                   inet_addr_type(addr) == RTN_UNICAST)
+                   inet_addr_type(net, addr) == RTN_UNICAST)
                        cfg->fc_scope = RT_SCOPE_UNIVERSE;
        }
 
@@ -409,7 +453,7 @@ static int rtentry_to_fib_config(int cmd, struct rtentry *rt,
  *     Handle IP routing ioctl calls. These are used to manipulate the routing tables
  */
 
-int ip_rt_ioctl(unsigned int cmd, void __user *arg)
+int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 {
        struct fib_config cfg;
        struct rtentry rt;
@@ -425,18 +469,18 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg)
                        return -EFAULT;
 
                rtnl_lock();
-               err = rtentry_to_fib_config(cmd, &rt, &cfg);
+               err = rtentry_to_fib_config(net, cmd, &rt, &cfg);
                if (err == 0) {
                        struct fib_table *tb;
 
                        if (cmd == SIOCDELRT) {
-                               tb = fib_get_table(cfg.fc_table);
+                               tb = fib_get_table(net, cfg.fc_table);
                                if (tb)
                                        err = tb->tb_delete(tb, &cfg);
                                else
                                        err = -ESRCH;
                        } else {
-                               tb = fib_new_table(cfg.fc_table);
+                               tb = fib_new_table(net, cfg.fc_table);
                                if (tb)
                                        err = tb->tb_insert(tb, &cfg);
                                else
@@ -466,8 +510,8 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
        [RTA_FLOW]              = { .type = NLA_U32 },
 };
 
-static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
-                            struct fib_config *cfg)
+static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
+                           struct nlmsghdr *nlh, struct fib_config *cfg)
 {
        struct nlattr *attr;
        int err, remaining;
@@ -491,6 +535,7 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh,
 
        cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
        cfg->fc_nlinfo.nlh = nlh;
+       cfg->fc_nlinfo.nl_net = net;
 
        if (cfg->fc_type > RTN_MAX) {
                err = -EINVAL;
@@ -538,15 +583,16 @@ errout:
 
 static int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib_config cfg;
        struct fib_table *tb;
        int err;
 
-       err = rtm_to_fib_config(skb, nlh, &cfg);
+       err = rtm_to_fib_config(net, skb, nlh, &cfg);
        if (err < 0)
                goto errout;
 
-       tb = fib_get_table(cfg.fc_table);
+       tb = fib_get_table(net, cfg.fc_table);
        if (tb == NULL) {
                err = -ESRCH;
                goto errout;
@@ -559,15 +605,16 @@ errout:
 
 static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib_config cfg;
        struct fib_table *tb;
        int err;
 
-       err = rtm_to_fib_config(skb, nlh, &cfg);
+       err = rtm_to_fib_config(net, skb, nlh, &cfg);
        if (err < 0)
                goto errout;
 
-       tb = fib_new_table(cfg.fc_table);
+       tb = fib_new_table(net, cfg.fc_table);
        if (tb == NULL) {
                err = -ENOBUFS;
                goto errout;
@@ -580,10 +627,12 @@ errout:
 
 static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        unsigned int h, s_h;
        unsigned int e = 0, s_e;
        struct fib_table *tb;
        struct hlist_node *node;
+       struct hlist_head *head;
        int dumped = 0;
 
        if (nlmsg_len(cb->nlh) >= sizeof(struct rtmsg) &&
@@ -595,7 +644,8 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 
        for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
                e = 0;
-               hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) {
+               head = &net->ipv4.fib_table_hash[h];
+               hlist_for_each_entry(tb, node, head, tb_hlist) {
                        if (e < s_e)
                                goto next;
                        if (dumped)
@@ -624,6 +674,7 @@ out:
 
 static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
 {
+       struct net *net = ifa->ifa_dev->dev->nd_net;
        struct fib_table *tb;
        struct fib_config cfg = {
                .fc_protocol = RTPROT_KERNEL,
@@ -633,12 +684,15 @@ static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifad
                .fc_prefsrc = ifa->ifa_local,
                .fc_oif = ifa->ifa_dev->dev->ifindex,
                .fc_nlflags = NLM_F_CREATE | NLM_F_APPEND,
+               .fc_nlinfo = {
+                       .nl_net = net,
+               },
        };
 
        if (type == RTN_UNICAST)
-               tb = fib_new_table(RT_TABLE_MAIN);
+               tb = fib_new_table(net, RT_TABLE_MAIN);
        else
-               tb = fib_new_table(RT_TABLE_LOCAL);
+               tb = fib_new_table(net, RT_TABLE_LOCAL);
 
        if (tb == NULL)
                return;
@@ -668,7 +722,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
        if (ifa->ifa_flags&IFA_F_SECONDARY) {
                prim = inet_ifa_byprefix(in_dev, prefix, mask);
                if (prim == NULL) {
-                       printk(KERN_DEBUG "fib_add_ifaddr: bug: prim == NULL\n");
+                       printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n");
                        return;
                }
        }
@@ -682,7 +736,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
        if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
                fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
 
-       if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
+       if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
            (prefix != addr || ifa->ifa_prefixlen < 32)) {
                fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL :
                          RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim);
@@ -715,7 +769,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
        else {
                prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
                if (prim == NULL) {
-                       printk(KERN_DEBUG "fib_del_ifaddr: bug: prim == NULL\n");
+                       printk(KERN_WARNING "fib_del_ifaddr: bug: prim == NULL\n");
                        return;
                }
        }
@@ -747,7 +801,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
                fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
 
                /* Check, that this local address finally disappeared. */
-               if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
+               if (inet_addr_type(dev->nd_net, ifa->ifa_local) != RTN_LOCAL) {
                        /* And the last, but not the least thing.
                           We must flush stray FIB entries.
 
@@ -755,7 +809,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
                           for stray nexthop entries, then ignite fib_flush.
                        */
                        if (fib_sync_down(ifa->ifa_local, NULL, 0))
-                               fib_flush();
+                               fib_flush(dev->nd_net);
                }
        }
 #undef LOCAL_OK
@@ -797,11 +851,13 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
 
 static void nl_fib_input(struct sk_buff *skb)
 {
+       struct net *net;
        struct fib_result_nl *frn;
        struct nlmsghdr *nlh;
        struct fib_table *tb;
        u32 pid;
 
+       net = skb->sk->sk_net;
        nlh = nlmsg_hdr(skb);
        if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
            nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn)))
@@ -813,26 +869,37 @@ static void nl_fib_input(struct sk_buff *skb)
        nlh = nlmsg_hdr(skb);
 
        frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
-       tb = fib_get_table(frn->tb_id_in);
+       tb = fib_get_table(net, frn->tb_id_in);
 
        nl_fib_lookup(frn, tb);
 
        pid = NETLINK_CB(skb).pid;       /* pid of sending process */
        NETLINK_CB(skb).pid = 0;         /* from kernel */
        NETLINK_CB(skb).dst_group = 0;  /* unicast */
-       netlink_unicast(fibnl, skb, pid, MSG_DONTWAIT);
+       netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT);
+}
+
+static int nl_fib_lookup_init(struct net *net)
+{
+       struct sock *sk;
+       sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0,
+                                  nl_fib_input, NULL, THIS_MODULE);
+       if (sk == NULL)
+               return -EAFNOSUPPORT;
+       net->ipv4.fibnl = sk;
+       return 0;
 }
 
-static void nl_fib_lookup_init(void)
+static void nl_fib_lookup_exit(struct net *net)
 {
-       fibnl = netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0,
-                                     nl_fib_input, NULL, THIS_MODULE);
+       netlink_kernel_release(net->ipv4.fibnl);
+       net->ipv4.fibnl = NULL;
 }
 
 static void fib_disable_ip(struct net_device *dev, int force)
 {
        if (fib_sync_down(0, dev, force))
-               fib_flush();
+               fib_flush(dev->nd_net);
        rt_cache_flush(0);
        arp_ifdown(dev);
 }
@@ -869,9 +936,6 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
        struct net_device *dev = ptr;
        struct in_device *in_dev = __in_dev_get_rtnl(dev);
 
-       if (dev->nd_net != &init_net)
-               return NOTIFY_DONE;
-
        if (event == NETDEV_UNREGISTER) {
                fib_disable_ip(dev, 2);
                return NOTIFY_DONE;
@@ -909,23 +973,92 @@ static struct notifier_block fib_netdev_notifier = {
        .notifier_call =fib_netdev_event,
 };
 
-void __init ip_fib_init(void)
+static int __net_init ip_fib_net_init(struct net *net)
 {
        unsigned int i;
 
+       net->ipv4.fib_table_hash = kzalloc(
+                       sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL);
+       if (net->ipv4.fib_table_hash == NULL)
+               return -ENOMEM;
+
        for (i = 0; i < FIB_TABLE_HASHSZ; i++)
-               INIT_HLIST_HEAD(&fib_table_hash[i]);
+               INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]);
 
-       fib4_rules_init();
+       return fib4_rules_init(net);
+}
 
-       register_netdevice_notifier(&fib_netdev_notifier);
-       register_inetaddr_notifier(&fib_inetaddr_notifier);
-       nl_fib_lookup_init();
+static void __net_exit ip_fib_net_exit(struct net *net)
+{
+       unsigned int i;
+
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+       fib4_rules_exit(net);
+#endif
 
+       for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
+               struct fib_table *tb;
+               struct hlist_head *head;
+               struct hlist_node *node, *tmp;
+
+               head = &net->ipv4.fib_table_hash[i];
+               hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) {
+                       hlist_del(node);
+                       tb->tb_flush(tb);
+                       kfree(tb);
+               }
+       }
+       kfree(net->ipv4.fib_table_hash);
+}
+
+static int __net_init fib_net_init(struct net *net)
+{
+       int error;
+
+       error = ip_fib_net_init(net);
+       if (error < 0)
+               goto out;
+       error = nl_fib_lookup_init(net);
+       if (error < 0)
+               goto out_nlfl;
+       error = fib_proc_init(net);
+       if (error < 0)
+               goto out_proc;
+out:
+       return error;
+
+out_proc:
+       nl_fib_lookup_exit(net);
+out_nlfl:
+       ip_fib_net_exit(net);
+       goto out;
+}
+
+static void __net_exit fib_net_exit(struct net *net)
+{
+       fib_proc_exit(net);
+       nl_fib_lookup_exit(net);
+       ip_fib_net_exit(net);
+}
+
+static struct pernet_operations fib_net_ops = {
+       .init = fib_net_init,
+       .exit = fib_net_exit,
+};
+
+void __init ip_fib_init(void)
+{
        rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL);
        rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL);
        rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib);
+
+       register_pernet_subsys(&fib_net_ops);
+       register_netdevice_notifier(&fib_netdev_notifier);
+       register_inetaddr_notifier(&fib_inetaddr_notifier);
+
+       fib_hash_init();
 }
 
 EXPORT_SYMBOL(inet_addr_type);
+EXPORT_SYMBOL(inet_dev_addr_type);
 EXPORT_SYMBOL(ip_dev_find);
index 0dfee27cfbcd8c80364ddf2bace37e955b8b55d8..a15b2f1b2721d8d4239c81f4eddf13f3fccd6947 100644 (file)
@@ -52,6 +52,7 @@ struct fib_node {
        struct hlist_node       fn_hash;
        struct list_head        fn_alias;
        __be32                  fn_key;
+       struct fib_alias        fn_embedded_alias;
 };
 
 struct fn_zone {
@@ -102,10 +103,10 @@ static struct hlist_head *fz_hash_alloc(int divisor)
        unsigned long size = divisor * sizeof(struct hlist_head);
 
        if (size <= PAGE_SIZE) {
-               return kmalloc(size, GFP_KERNEL);
+               return kzalloc(size, GFP_KERNEL);
        } else {
                return (struct hlist_head *)
-                       __get_free_pages(GFP_KERNEL, get_order(size));
+                       __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(size));
        }
 }
 
@@ -168,14 +169,13 @@ static void fn_rehash_zone(struct fn_zone *fz)
        new_hashmask = (new_divisor - 1);
 
 #if RT_CACHE_DEBUG >= 2
-       printk("fn_rehash_zone: hash for zone %d grows from %d\n", fz->fz_order, old_divisor);
+       printk(KERN_DEBUG "fn_rehash_zone: hash for zone %d grows from %d\n",
+              fz->fz_order, old_divisor);
 #endif
 
        ht = fz_hash_alloc(new_divisor);
 
        if (ht) {
-               memset(ht, 0, new_divisor * sizeof(struct hlist_head));
-
                write_lock_bh(&fib_hash_lock);
                old_ht = fz->fz_hash;
                fz->fz_hash = ht;
@@ -194,10 +194,13 @@ static inline void fn_free_node(struct fib_node * f)
        kmem_cache_free(fn_hash_kmem, f);
 }
 
-static inline void fn_free_alias(struct fib_alias *fa)
+static inline void fn_free_alias(struct fib_alias *fa, struct fib_node *f)
 {
        fib_release_info(fa->fa_info);
-       kmem_cache_free(fn_alias_kmem, fa);
+       if (fa == &f->fn_embedded_alias)
+               fa->fa_info = NULL;
+       else
+               kmem_cache_free(fn_alias_kmem, fa);
 }
 
 static struct fn_zone *
@@ -219,7 +222,6 @@ fn_new_zone(struct fn_hash *table, int z)
                kfree(fz);
                return NULL;
        }
-       memset(fz->fz_hash, 0, fz->fz_divisor * sizeof(struct hlist_head *));
        fz->fz_order = z;
        fz->fz_mask = inet_make_mask(z);
 
@@ -275,8 +277,6 @@ out:
        return err;
 }
 
-static int fn_hash_last_dflt=-1;
-
 static void
 fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
 {
@@ -317,12 +317,9 @@ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
                                if (next_fi != res->fi)
                                        break;
                        } else if (!fib_detect_death(fi, order, &last_resort,
-                                                    &last_idx, &fn_hash_last_dflt)) {
-                               if (res->fi)
-                                       fib_info_put(res->fi);
-                               res->fi = fi;
-                               atomic_inc(&fi->fib_clntref);
-                               fn_hash_last_dflt = order;
+                                               &last_idx, tb->tb_default)) {
+                               fib_result_assign(res, fi);
+                               tb->tb_default = order;
                                goto out;
                        }
                        fi = next_fi;
@@ -331,27 +328,20 @@ fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
        }
 
        if (order <= 0 || fi == NULL) {
-               fn_hash_last_dflt = -1;
+               tb->tb_default = -1;
                goto out;
        }
 
-       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &fn_hash_last_dflt)) {
-               if (res->fi)
-                       fib_info_put(res->fi);
-               res->fi = fi;
-               atomic_inc(&fi->fib_clntref);
-               fn_hash_last_dflt = order;
+       if (!fib_detect_death(fi, order, &last_resort, &last_idx,
+                               tb->tb_default)) {
+               fib_result_assign(res, fi);
+               tb->tb_default = order;
                goto out;
        }
 
-       if (last_idx >= 0) {
-               if (res->fi)
-                       fib_info_put(res->fi);
-               res->fi = last_resort;
-               if (last_resort)
-                       atomic_inc(&last_resort->fib_clntref);
-       }
-       fn_hash_last_dflt = last_idx;
+       if (last_idx >= 0)
+               fib_result_assign(res, last_resort);
+       tb->tb_default = last_idx;
 out:
        read_unlock(&fib_hash_lock);
 }
@@ -490,15 +480,12 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                goto out;
 
        err = -ENOBUFS;
-       new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
-       if (new_fa == NULL)
-               goto out;
 
        new_f = NULL;
        if (!f) {
-               new_f = kmem_cache_alloc(fn_hash_kmem, GFP_KERNEL);
+               new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL);
                if (new_f == NULL)
-                       goto out_free_new_fa;
+                       goto out;
 
                INIT_HLIST_NODE(&new_f->fn_hash);
                INIT_LIST_HEAD(&new_f->fn_alias);
@@ -506,6 +493,12 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                f = new_f;
        }
 
+       new_fa = &f->fn_embedded_alias;
+       if (new_fa->fa_info != NULL) {
+               new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
+               if (new_fa == NULL)
+                       goto out_free_new_f;
+       }
        new_fa->fa_info = fi;
        new_fa->fa_tos = tos;
        new_fa->fa_type = cfg->fc_type;
@@ -532,8 +525,8 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
                  &cfg->fc_nlinfo, 0);
        return 0;
 
-out_free_new_fa:
-       kmem_cache_free(fn_alias_kmem, new_fa);
+out_free_new_f:
+       kmem_cache_free(fn_hash_kmem, new_f);
 out:
        fib_release_info(fi);
        return err;
@@ -609,7 +602,7 @@ static int fn_hash_delete(struct fib_table *tb, struct fib_config *cfg)
 
                if (fa->fa_state & FA_S_ACCESSED)
                        rt_cache_flush(-1);
-               fn_free_alias(fa);
+               fn_free_alias(fa, f);
                if (kill_fn) {
                        fn_free_node(f);
                        fz->fz_nent--;
@@ -645,7 +638,7 @@ static int fn_flush_list(struct fn_zone *fz, int idx)
                                fib_hash_genid++;
                                write_unlock_bh(&fib_hash_lock);
 
-                               fn_free_alias(fa);
+                               fn_free_alias(fa, f);
                                found++;
                        }
                }
@@ -761,25 +754,19 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin
        return skb->len;
 }
 
-#ifdef CONFIG_IP_MULTIPLE_TABLES
-struct fib_table * fib_hash_init(u32 id)
-#else
-struct fib_table * __init fib_hash_init(u32 id)
-#endif
+void __init fib_hash_init(void)
 {
-       struct fib_table *tb;
+       fn_hash_kmem = kmem_cache_create("ip_fib_hash", sizeof(struct fib_node),
+                                        0, SLAB_PANIC, NULL);
 
-       if (fn_hash_kmem == NULL)
-               fn_hash_kmem = kmem_cache_create("ip_fib_hash",
-                                                sizeof(struct fib_node),
-                                                0, SLAB_HWCACHE_ALIGN,
-                                                NULL);
+       fn_alias_kmem = kmem_cache_create("ip_fib_alias", sizeof(struct fib_alias),
+                                         0, SLAB_PANIC, NULL);
 
-       if (fn_alias_kmem == NULL)
-               fn_alias_kmem = kmem_cache_create("ip_fib_alias",
-                                                 sizeof(struct fib_alias),
-                                                 0, SLAB_HWCACHE_ALIGN,
-                                                 NULL);
+}
+
+struct fib_table *fib_hash_table(u32 id)
+{
+       struct fib_table *tb;
 
        tb = kmalloc(sizeof(struct fib_table) + sizeof(struct fn_hash),
                     GFP_KERNEL);
@@ -787,6 +774,7 @@ struct fib_table * __init fib_hash_init(u32 id)
                return NULL;
 
        tb->tb_id = id;
+       tb->tb_default = -1;
        tb->tb_lookup = fn_hash_lookup;
        tb->tb_insert = fn_hash_insert;
        tb->tb_delete = fn_hash_delete;
@@ -801,6 +789,7 @@ struct fib_table * __init fib_hash_init(u32 id)
 #ifdef CONFIG_PROC_FS
 
 struct fib_iter_state {
+       struct seq_net_private p;
        struct fn_zone  *zone;
        int             bucket;
        struct hlist_head *hash_head;
@@ -814,7 +803,11 @@ struct fib_iter_state {
 static struct fib_alias *fib_get_first(struct seq_file *seq)
 {
        struct fib_iter_state *iter = seq->private;
-       struct fn_hash *table = (struct fn_hash *) ip_fib_main_table->tb_data;
+       struct fib_table *main_table;
+       struct fn_hash *table;
+
+       main_table = fib_get_table(iter->p.net, RT_TABLE_MAIN);
+       table = (struct fn_hash *)main_table->tb_data;
 
        iter->bucket    = 0;
        iter->hash_head = NULL;
@@ -949,11 +942,13 @@ static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *fib_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(fib_hash_lock)
 {
+       struct fib_iter_state *iter = seq->private;
        void *v = NULL;
 
        read_lock(&fib_hash_lock);
-       if (ip_fib_main_table)
+       if (fib_get_table(iter->p.net, RT_TABLE_MAIN))
                v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
        return v;
 }
@@ -965,6 +960,7 @@ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void fib_seq_stop(struct seq_file *seq, void *v)
+       __releases(fib_hash_lock)
 {
        read_unlock(&fib_hash_lock);
 }
@@ -1040,8 +1036,8 @@ static const struct seq_operations fib_seq_ops = {
 
 static int fib_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &fib_seq_ops,
-                       sizeof(struct fib_iter_state));
+       return seq_open_net(inode, file, &fib_seq_ops,
+                           sizeof(struct fib_iter_state));
 }
 
 static const struct file_operations fib_seq_fops = {
@@ -1049,18 +1045,18 @@ static const struct file_operations fib_seq_fops = {
        .open           = fib_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
 };
 
-int __init fib_proc_init(void)
+int __net_init fib_proc_init(struct net *net)
 {
-       if (!proc_net_fops_create(&init_net, "route", S_IRUGO, &fib_seq_fops))
+       if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_seq_fops))
                return -ENOMEM;
        return 0;
 }
 
-void __init fib_proc_exit(void)
+void __net_exit fib_proc_exit(struct net *net)
 {
-       proc_net_remove(&init_net, "route");
+       proc_net_remove(net, "route");
 }
 #endif /* CONFIG_PROC_FS */
index eef9eec17e0c584a383df0a8064117b3feb238f8..2c1623d2768bfd2a1e5acd952d8ec610337f1294 100644 (file)
@@ -7,12 +7,14 @@
 
 struct fib_alias {
        struct list_head        fa_list;
-       struct rcu_head rcu;
        struct fib_info         *fa_info;
        u8                      fa_tos;
        u8                      fa_type;
        u8                      fa_scope;
        u8                      fa_state;
+#ifdef CONFIG_IP_FIB_TRIE
+       struct rcu_head         rcu;
+#endif
 };
 
 #define FA_S_ACCESSED  0x01
@@ -36,6 +38,16 @@ extern struct fib_alias *fib_find_alias(struct list_head *fah,
                                        u8 tos, u32 prio);
 extern int fib_detect_death(struct fib_info *fi, int order,
                            struct fib_info **last_resort,
-                           int *last_idx, int *dflt);
+                           int *last_idx, int dflt);
+
+static inline void fib_result_assign(struct fib_result *res,
+                                    struct fib_info *fi)
+{
+       if (res->fi != NULL)
+               fib_info_put(res->fi);
+       res->fi = fi;
+       if (fi != NULL)
+               atomic_inc(&fi->fib_clntref);
+}
 
 #endif /* _FIB_LOOKUP_H */
index a0ada3a8d8dd8c2cfd931cc0c475c73aadf8d62b..19274d01afa4a36c3777b5ff34816fa63783734a 100644 (file)
@@ -32,8 +32,6 @@
 #include <net/ip_fib.h>
 #include <net/fib_rules.h>
 
-static struct fib_rules_ops fib4_rules_ops;
-
 struct fib4_rule
 {
        struct fib_rule         common;
@@ -56,14 +54,14 @@ u32 fib_rules_tclass(struct fib_result *res)
 }
 #endif
 
-int fib_lookup(struct flowi *flp, struct fib_result *res)
+int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res)
 {
        struct fib_lookup_arg arg = {
                .result = res,
        };
        int err;
 
-       err = fib_rules_lookup(&fib4_rules_ops, flp, 0, &arg);
+       err = fib_rules_lookup(net->ipv4.rules_ops, flp, 0, &arg);
        res->r = arg.rule;
 
        return err;
@@ -93,7 +91,7 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
                goto errout;
        }
 
-       if ((tbl = fib_get_table(rule->table)) == NULL)
+       if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL)
                goto errout;
 
        err = tbl->tb_lookup(tbl, flp, (struct fib_result *) arg->result);
@@ -104,16 +102,6 @@ errout:
 }
 
 
-void fib_select_default(const struct flowi *flp, struct fib_result *res)
-{
-       if (res->r && res->r->action == FR_ACT_TO_TBL &&
-           FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
-               struct fib_table *tb;
-               if ((tb = fib_get_table(res->r->table)) != NULL)
-                       tb->tb_select_default(tb, flp, res);
-       }
-}
-
 static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 {
        struct fib4_rule *r = (struct fib4_rule *) rule;
@@ -130,13 +118,13 @@ static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
        return 1;
 }
 
-static struct fib_table *fib_empty_table(void)
+static struct fib_table *fib_empty_table(struct net *net)
 {
        u32 id;
 
        for (id = 1; id <= RT_TABLE_MAX; id++)
-               if (fib_get_table(id) == NULL)
-                       return fib_new_table(id);
+               if (fib_get_table(net, id) == NULL)
+                       return fib_new_table(net, id);
        return NULL;
 }
 
@@ -149,6 +137,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
                               struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
                               struct nlattr **tb)
 {
+       struct net *net = skb->sk->sk_net;
        int err = -EINVAL;
        struct fib4_rule *rule4 = (struct fib4_rule *) rule;
 
@@ -159,7 +148,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
                if (rule->action == FR_ACT_TO_TBL) {
                        struct fib_table *table;
 
-                       table = fib_empty_table();
+                       table = fib_empty_table(net);
                        if (table == NULL) {
                                err = -ENOBUFS;
                                goto errout;
@@ -245,14 +234,14 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-static u32 fib4_rule_default_pref(void)
+static u32 fib4_rule_default_pref(struct fib_rules_ops *ops)
 {
        struct list_head *pos;
        struct fib_rule *rule;
 
-       if (!list_empty(&fib4_rules_ops.rules_list)) {
-               pos = fib4_rules_ops.rules_list.next;
-               if (pos->next != &fib4_rules_ops.rules_list) {
+       if (!list_empty(&ops->rules_list)) {
+               pos = ops->rules_list.next;
+               if (pos->next != &ops->rules_list) {
                        rule = list_entry(pos->next, struct fib_rule, list);
                        if (rule->pref)
                                return rule->pref - 1;
@@ -274,7 +263,7 @@ static void fib4_rule_flush_cache(void)
        rt_cache_flush(-1);
 }
 
-static struct fib_rules_ops fib4_rules_ops = {
+static struct fib_rules_ops fib4_rules_ops_template = {
        .family         = AF_INET,
        .rule_size      = sizeof(struct fib4_rule),
        .addr_size      = sizeof(u32),
@@ -288,31 +277,53 @@ static struct fib_rules_ops fib4_rules_ops = {
        .flush_cache    = fib4_rule_flush_cache,
        .nlgroup        = RTNLGRP_IPV4_RULE,
        .policy         = fib4_rule_policy,
-       .rules_list     = LIST_HEAD_INIT(fib4_rules_ops.rules_list),
        .owner          = THIS_MODULE,
 };
 
-static int __init fib_default_rules_init(void)
+static int fib_default_rules_init(struct fib_rules_ops *ops)
 {
        int err;
 
-       err = fib_default_rule_add(&fib4_rules_ops, 0,
-                                  RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
+       err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT);
        if (err < 0)
                return err;
-       err = fib_default_rule_add(&fib4_rules_ops, 0x7FFE,
-                                  RT_TABLE_MAIN, 0);
+       err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0);
        if (err < 0)
                return err;
-       err = fib_default_rule_add(&fib4_rules_ops, 0x7FFF,
-                                  RT_TABLE_DEFAULT, 0);
+       err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0);
        if (err < 0)
                return err;
        return 0;
 }
 
-void __init fib4_rules_init(void)
+int __net_init fib4_rules_init(struct net *net)
+{
+       int err;
+       struct fib_rules_ops *ops;
+
+       ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL);
+       if (ops == NULL)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&ops->rules_list);
+       ops->fro_net = net;
+
+       fib_rules_register(ops);
+
+       err = fib_default_rules_init(ops);
+       if (err < 0)
+               goto fail;
+       net->ipv4.rules_ops = ops;
+       return 0;
+
+fail:
+       /* also cleans all rules already added */
+       fib_rules_unregister(ops);
+       kfree(ops);
+       return err;
+}
+
+void __net_exit fib4_rules_exit(struct net *net)
 {
-       BUG_ON(fib_default_rules_init());
-       fib_rules_register(&fib4_rules_ops);
+       fib_rules_unregister(net->ipv4.rules_ops);
+       kfree(net->ipv4.rules_ops);
 }
index 1351a2617dcef072ee0adebdd59ea1007b9a4bbd..c7912866d98719d248c796c89b1a1ef9d899e92a 100644 (file)
@@ -47,8 +47,6 @@
 
 #include "fib_lookup.h"
 
-#define FSprintk(a...)
-
 static DEFINE_SPINLOCK(fib_info_lock);
 static struct hlist_head *fib_info_hash;
 static struct hlist_head *fib_info_laddrhash;
@@ -145,7 +143,7 @@ static const struct
 void free_fib_info(struct fib_info *fi)
 {
        if (fi->fib_dead == 0) {
-               printk("Freeing alive fib_info %p\n", fi);
+               printk(KERN_WARNING "Freeing alive fib_info %p\n", fi);
                return;
        }
        change_nexthops(fi) {
@@ -196,6 +194,15 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *
        return 0;
 }
 
+static inline unsigned int fib_devindex_hashfn(unsigned int val)
+{
+       unsigned int mask = DEVINDEX_HASHSIZE - 1;
+
+       return (val ^
+               (val >> DEVINDEX_HASHBITS) ^
+               (val >> (DEVINDEX_HASHBITS * 2))) & mask;
+}
+
 static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
 {
        unsigned int mask = (fib_hash_size - 1);
@@ -204,6 +211,9 @@ static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
        val ^= fi->fib_protocol;
        val ^= (__force u32)fi->fib_prefsrc;
        val ^= fi->fib_priority;
+       for_nexthops(fi) {
+               val ^= fib_devindex_hashfn(nh->nh_oif);
+       } endfor_nexthops(fi)
 
        return (val ^ (val >> 7) ^ (val >> 12)) & mask;
 }
@@ -234,15 +244,6 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
        return NULL;
 }
 
-static inline unsigned int fib_devindex_hashfn(unsigned int val)
-{
-       unsigned int mask = DEVINDEX_HASHSIZE - 1;
-
-       return (val ^
-               (val >> DEVINDEX_HASHBITS) ^
-               (val >> (DEVINDEX_HASHBITS * 2))) & mask;
-}
-
 /* Check, that the gateway is already configured.
    Used only by redirect accept routine.
  */
@@ -320,11 +321,11 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
+       err = rtnl_notify(skb, info->nl_net, info->pid, RTNLGRP_IPV4_ROUTE,
                          info->nlh, GFP_KERNEL);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV4_ROUTE, err);
+               rtnl_set_sk_err(info->nl_net, RTNLGRP_IPV4_ROUTE, err);
 }
 
 /* Return the first fib alias matching TOS with
@@ -346,7 +347,7 @@ struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
 }
 
 int fib_detect_death(struct fib_info *fi, int order,
-                    struct fib_info **last_resort, int *last_idx, int *dflt)
+                    struct fib_info **last_resort, int *last_idx, int dflt)
 {
        struct neighbour *n;
        int state = NUD_NONE;
@@ -358,10 +359,10 @@ int fib_detect_death(struct fib_info *fi, int order,
        }
        if (state==NUD_REACHABLE)
                return 0;
-       if ((state&NUD_VALID) && order != *dflt)
+       if ((state&NUD_VALID) && order != dflt)
                return 0;
        if ((state&NUD_VALID) ||
-           (*last_idx<0 && order > *dflt)) {
+           (*last_idx<0 && order > dflt)) {
                *last_resort = fi;
                *last_idx = order;
        }
@@ -518,7 +519,9 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
                        struct fib_nh *nh)
 {
        int err;
+       struct net *net;
 
+       net = cfg->fc_nlinfo.nl_net;
        if (nh->nh_gw) {
                struct fib_result res;
 
@@ -531,9 +534,9 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
 
                        if (cfg->fc_scope >= RT_SCOPE_LINK)
                                return -EINVAL;
-                       if (inet_addr_type(nh->nh_gw) != RTN_UNICAST)
+                       if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
                                return -EINVAL;
-                       if ((dev = __dev_get_by_index(&init_net, nh->nh_oif)) == NULL)
+                       if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
                                return -ENODEV;
                        if (!(dev->flags&IFF_UP))
                                return -ENETDOWN;
@@ -556,7 +559,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
                        /* It is not necessary, but requires a bit of thinking */
                        if (fl.fl4_scope < RT_SCOPE_LINK)
                                fl.fl4_scope = RT_SCOPE_LINK;
-                       if ((err = fib_lookup(&fl, &res)) != 0)
+                       if ((err = fib_lookup(net, &fl, &res)) != 0)
                                return err;
                }
                err = -EINVAL;
@@ -580,7 +583,7 @@ out:
                if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
                        return -EINVAL;
 
-               in_dev = inetdev_by_index(nh->nh_oif);
+               in_dev = inetdev_by_index(net, nh->nh_oif);
                if (in_dev == NULL)
                        return -ENODEV;
                if (!(in_dev->dev->flags&IFF_UP)) {
@@ -605,10 +608,10 @@ static inline unsigned int fib_laddr_hashfn(__be32 val)
 static struct hlist_head *fib_hash_alloc(int bytes)
 {
        if (bytes <= PAGE_SIZE)
-               return kmalloc(bytes, GFP_KERNEL);
+               return kzalloc(bytes, GFP_KERNEL);
        else
                return (struct hlist_head *)
-                       __get_free_pages(GFP_KERNEL, get_order(bytes));
+                       __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes));
 }
 
 static void fib_hash_free(struct hlist_head *hash, int bytes)
@@ -712,12 +715,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                if (!new_info_hash || !new_laddrhash) {
                        fib_hash_free(new_info_hash, bytes);
                        fib_hash_free(new_laddrhash, bytes);
-               } else {
-                       memset(new_info_hash, 0, bytes);
-                       memset(new_laddrhash, 0, bytes);
-
+               } else
                        fib_hash_move(new_info_hash, new_laddrhash, new_size);
-               }
 
                if (!fib_hash_size)
                        goto failure;
@@ -799,7 +798,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
                if (nhs != 1 || nh->nh_gw)
                        goto err_inval;
                nh->nh_scope = RT_SCOPE_NOWHERE;
-               nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif);
+               nh->nh_dev = dev_get_by_index(cfg->fc_nlinfo.nl_net,
+                                             fi->fib_nh->nh_oif);
                err = -ENODEV;
                if (nh->nh_dev == NULL)
                        goto failure;
@@ -813,7 +813,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
        if (fi->fib_prefsrc) {
                if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
                    fi->fib_prefsrc != cfg->fc_dst)
-                       if (inet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
+                       if (inet_addr_type(cfg->fc_nlinfo.nl_net,
+                                          fi->fib_prefsrc) != RTN_LOCAL)
                                goto err_inval;
        }
 
@@ -914,7 +915,8 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
                                continue;
 
                        default:
-                               printk(KERN_DEBUG "impossible 102\n");
+                               printk(KERN_WARNING "fib_semantic_match bad type %#x\n",
+                                       fa->fa_type);
                                return -EINVAL;
                        }
                }
index 1010b469d7d3440a4f9980c13bfaf280fd6a3e0e..f2f47033f31f3a211a1cba23438500c0a1076be9 100644 (file)
@@ -82,7 +82,6 @@
 #include <net/ip_fib.h>
 #include "fib_lookup.h"
 
-#undef CONFIG_IP_FIB_TRIE_STATS
 #define MAX_STAT_DEPTH 32
 
 #define KEYLENGTH (8*sizeof(t_key))
@@ -98,13 +97,13 @@ typedef unsigned int t_key;
 #define IS_LEAF(n) (n->parent & T_LEAF)
 
 struct node {
-       t_key key;
        unsigned long parent;
+       t_key key;
 };
 
 struct leaf {
-       t_key key;
        unsigned long parent;
+       t_key key;
        struct hlist_head list;
        struct rcu_head rcu;
 };
@@ -117,12 +116,12 @@ struct leaf_info {
 };
 
 struct tnode {
-       t_key key;
        unsigned long parent;
-       unsigned short pos:5;           /* 2log(KEYLENGTH) bits needed */
-       unsigned short bits:5;          /* 2log(KEYLENGTH) bits needed */
-       unsigned short full_children;   /* KEYLENGTH bits needed */
-       unsigned short empty_children;  /* KEYLENGTH bits needed */
+       t_key key;
+       unsigned char pos;              /* 2log(KEYLENGTH) bits needed */
+       unsigned char bits;             /* 2log(KEYLENGTH) bits needed */
+       unsigned int full_children;     /* KEYLENGTH bits needed */
+       unsigned int empty_children;    /* KEYLENGTH bits needed */
        struct rcu_head rcu;
        struct node *child[0];
 };
@@ -144,6 +143,7 @@ struct trie_stat {
        unsigned int tnodes;
        unsigned int leaves;
        unsigned int nullpointers;
+       unsigned int prefixes;
        unsigned int nodesizes[MAX_STAT_DEPTH];
 };
 
@@ -152,25 +152,28 @@ struct trie {
 #ifdef CONFIG_IP_FIB_TRIE_STATS
        struct trie_use_stats stats;
 #endif
-       int size;
-       unsigned int revision;
 };
 
 static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n);
-static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull);
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
+                                 int wasfull);
 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);
 static void tnode_free(struct tnode *tn);
 
 static struct kmem_cache *fn_alias_kmem __read_mostly;
-static struct trie *trie_local = NULL, *trie_main = NULL;
+static struct kmem_cache *trie_leaf_kmem __read_mostly;
 
 static inline struct tnode *node_parent(struct node *node)
 {
-       struct tnode *ret;
+       return (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
+}
+
+static inline struct tnode *node_parent_rcu(struct node *node)
+{
+       struct tnode *ret = node_parent(node);
 
-       ret = (struct tnode *)(node->parent & ~NODE_TYPE_MASK);
        return rcu_dereference(ret);
 }
 
@@ -180,13 +183,18 @@ static inline void node_set_parent(struct node *node, struct tnode *ptr)
                           (unsigned long)ptr | NODE_TYPE(node));
 }
 
-/* rcu_read_lock needs to be hold by caller from readside */
+static inline struct node *tnode_get_child(struct tnode *tn, unsigned int i)
+{
+       BUG_ON(i >= 1U << tn->bits);
+
+       return tn->child[i];
+}
 
-static inline struct node *tnode_get_child(struct tnode *tn, int i)
+static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
 {
-       BUG_ON(i >= 1 << tn->bits);
+       struct node *ret = tnode_get_child(tn, i);
 
-       return rcu_dereference(tn->child[i]);
+       return rcu_dereference(ret);
 }
 
 static inline int tnode_child_length(const struct tnode *tn)
@@ -300,10 +308,10 @@ static inline void check_tnode(const struct tnode *tn)
        WARN_ON(tn && tn->pos+tn->bits > 32);
 }
 
-static int halve_threshold = 25;
-static int inflate_threshold = 50;
-static int halve_threshold_root = 8;
-static int inflate_threshold_root = 15;
+static const int halve_threshold = 25;
+static const int inflate_threshold = 50;
+static const int halve_threshold_root = 8;
+static const int inflate_threshold_root = 15;
 
 
 static void __alias_free_mem(struct rcu_head *head)
@@ -319,7 +327,8 @@ static inline void alias_free_mem_rcu(struct fib_alias *fa)
 
 static void __leaf_free_rcu(struct rcu_head *head)
 {
-       kfree(container_of(head, struct leaf, rcu));
+       struct leaf *l = container_of(head, struct leaf, rcu);
+       kmem_cache_free(trie_leaf_kmem, l);
 }
 
 static void __leaf_info_free_rcu(struct rcu_head *head)
@@ -332,12 +341,12 @@ static inline void free_leaf_info(struct leaf_info *leaf)
        call_rcu(&leaf->rcu, __leaf_info_free_rcu);
 }
 
-static struct tnode *tnode_alloc(unsigned int size)
+static struct tnode *tnode_alloc(size_t size)
 {
        struct page *pages;
 
        if (size <= PAGE_SIZE)
-               return kcalloc(size, 1, GFP_KERNEL);
+               return kzalloc(size, GFP_KERNEL);
 
        pages = alloc_pages(GFP_KERNEL|__GFP_ZERO, get_order(size));
        if (!pages)
@@ -349,8 +358,8 @@ static struct tnode *tnode_alloc(unsigned int size)
 static void __tnode_free_rcu(struct rcu_head *head)
 {
        struct tnode *tn = container_of(head, struct tnode, rcu);
-       unsigned int size = sizeof(struct tnode) +
-               (1 << tn->bits) * sizeof(struct node *);
+       size_t size = sizeof(struct tnode) +
+                     (sizeof(struct node *) << tn->bits);
 
        if (size <= PAGE_SIZE)
                kfree(tn);
@@ -369,7 +378,7 @@ static inline void tnode_free(struct tnode *tn)
 
 static struct leaf *leaf_new(void)
 {
-       struct leaf *l = kmalloc(sizeof(struct leaf),  GFP_KERNEL);
+       struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
        if (l) {
                l->parent = T_LEAF;
                INIT_HLIST_HEAD(&l->list);
@@ -387,14 +396,12 @@ static struct leaf_info *leaf_info_new(int plen)
        return li;
 }
 
-static struct tnodetnode_new(t_key key, int pos, int bits)
+static struct tnode *tnode_new(t_key key, int pos, int bits)
 {
-       int nchildren = 1<<bits;
-       int sz = sizeof(struct tnode) + nchildren * sizeof(struct node *);
+       size_t sz = sizeof(struct tnode) + (sizeof(struct node *) << bits);
        struct tnode *tn = tnode_alloc(sz);
 
        if (tn) {
-               memset(tn, 0, sz);
                tn->parent = T_TNODE;
                tn->pos = pos;
                tn->bits = bits;
@@ -403,8 +410,8 @@ static struct tnode* tnode_new(t_key key, int pos, int bits)
                tn->empty_children = 1<<bits;
        }
 
-       pr_debug("AT %p s=%u %u\n", tn, (unsigned int) sizeof(struct tnode),
-                (unsigned int) (sizeof(struct node) * 1<<bits));
+       pr_debug("AT %p s=%u %lu\n", tn, (unsigned int) sizeof(struct tnode),
+                (unsigned long) (sizeof(struct node) << bits));
        return tn;
 }
 
@@ -421,7 +428,8 @@ static inline int tnode_full(const struct tnode *tn, const struct node *n)
        return ((struct tnode *) n)->pos == tn->pos + tn->bits;
 }
 
-static inline void put_child(struct trie *t, struct tnode *tn, int i, struct node *n)
+static inline void put_child(struct trie *t, struct tnode *tn, int i,
+                            struct node *n)
 {
        tnode_put_child_reorg(tn, i, n, -1);
 }
@@ -431,14 +439,14 @@ static inline void put_child(struct trie *t, struct tnode *tn, int i, struct nod
   * Update the value of full_children and empty_children.
   */
 
-static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull)
+static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
+                                 int wasfull)
 {
        struct node *chi = tn->child[i];
        int isfull;
 
        BUG_ON(i >= 1<<tn->bits);
 
-
        /* update emptyChildren */
        if (n == NULL && chi != NULL)
                tn->empty_children++;
@@ -571,11 +579,13 @@ static struct node *resize(struct trie *t, struct tnode *tn)
        err = 0;
        max_resize = 10;
        while ((tn->full_children > 0 &&  max_resize-- &&
-              50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >=
-                               inflate_threshold_use * tnode_child_length(tn))) {
+               50 * (tn->full_children + tnode_child_length(tn)
+                     - tn->empty_children)
+               >= inflate_threshold_use * tnode_child_length(tn))) {
 
                old_tn = tn;
                tn = inflate(t, tn);
+
                if (IS_ERR(tn)) {
                        tn = old_tn;
 #ifdef CONFIG_IP_FIB_TRIE_STATS
@@ -587,11 +597,13 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
        if (max_resize < 0) {
                if (!tn->parent)
-                       printk(KERN_WARNING "Fix inflate_threshold_root. Now=%d size=%d bits\n",
-                              inflate_threshold_root, tn->bits);
+                       pr_warning("Fix inflate_threshold_root."
+                                  " Now=%d size=%d bits\n",
+                                  inflate_threshold_root, tn->bits);
                else
-                       printk(KERN_WARNING "Fix inflate_threshold. Now=%d size=%d bits\n",
-                              inflate_threshold, tn->bits);
+                       pr_warning("Fix inflate_threshold."
+                                  " Now=%d size=%d bits\n",
+                                  inflate_threshold, tn->bits);
        }
 
        check_tnode(tn);
@@ -628,11 +640,13 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
        if (max_resize < 0) {
                if (!tn->parent)
-                       printk(KERN_WARNING "Fix halve_threshold_root. Now=%d size=%d bits\n",
-                              halve_threshold_root, tn->bits);
+                       pr_warning("Fix halve_threshold_root."
+                                  " Now=%d size=%d bits\n",
+                                  halve_threshold_root, tn->bits);
                else
-                       printk(KERN_WARNING "Fix halve_threshold. Now=%d size=%d bits\n",
-                              halve_threshold, tn->bits);
+                       pr_warning("Fix halve_threshold."
+                                  " Now=%d size=%d bits\n",
+                                  halve_threshold, tn->bits);
        }
 
        /* Only one child remains */
@@ -656,7 +670,6 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
 static struct tnode *inflate(struct trie *t, struct tnode *tn)
 {
-       struct tnode *inode;
        struct tnode *oldtnode = tn;
        int olen = tnode_child_length(tn);
        int i;
@@ -676,8 +689,9 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
         */
 
        for (i = 0; i < olen; i++) {
-               struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i);
+               struct tnode *inode;
 
+               inode = (struct tnode *) tnode_get_child(oldtnode, i);
                if (inode &&
                    IS_TNODE(inode) &&
                    inode->pos == oldtnode->pos + oldtnode->bits &&
@@ -704,6 +718,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
        }
 
        for (i = 0; i < olen; i++) {
+               struct tnode *inode;
                struct node *node = tnode_get_child(oldtnode, i);
                struct tnode *left, *right;
                int size, j;
@@ -716,8 +731,9 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
 
                if (IS_LEAF(node) || ((struct tnode *) node)->pos >
                   tn->pos + tn->bits - 1) {
-                       if (tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits,
-                                            1) == 0)
+                       if (tkey_extract_bits(node->key,
+                                             oldtnode->pos + oldtnode->bits,
+                                             1) == 0)
                                put_child(t, tn, 2*i, node);
                        else
                                put_child(t, tn, 2*i+1, node);
@@ -877,19 +893,6 @@ nomem:
        }
 }
 
-static void trie_init(struct trie *t)
-{
-       if (!t)
-               return;
-
-       t->size = 0;
-       rcu_assign_pointer(t->trie, NULL);
-       t->revision = 0;
-#ifdef CONFIG_IP_FIB_TRIE_STATS
-       memset(&t->stats, 0, sizeof(struct trie_use_stats));
-#endif
-}
-
 /* readside must use rcu_read_lock currently dump routines
  via get_fa_head and dump */
 
@@ -906,7 +909,7 @@ static struct leaf_info *find_leaf_info(struct leaf *l, int plen)
        return NULL;
 }
 
-static inline struct list_head * get_fa_head(struct leaf *l, int plen)
+static inline struct list_head *get_fa_head(struct leaf *l, int plen)
 {
        struct leaf_info *li = find_leaf_info(l, plen);
 
@@ -956,7 +959,10 @@ fib_find_node(struct trie *t, u32 key)
 
                if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
                        pos = tn->pos + tn->bits;
-                       n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+                       n = tnode_get_child_rcu(tn,
+                                               tkey_extract_bits(key,
+                                                                 tn->pos,
+                                                                 tn->bits));
                } else
                        break;
        }
@@ -977,8 +983,10 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
        while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) {
                cindex = tkey_extract_bits(key, tp->pos, tp->bits);
                wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
-               tn = (struct tnode *) resize (t, (struct tnode *)tn);
-               tnode_put_child_reorg((struct tnode *)tp, cindex,(struct node*)tn, wasfull);
+               tn = (struct tnode *) resize(t, (struct tnode *)tn);
+
+               tnode_put_child_reorg((struct tnode *)tp, cindex,
+                                     (struct node *)tn, wasfull);
 
                tp = node_parent((struct node *) tn);
                if (!tp)
@@ -988,15 +996,14 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
 
        /* Handle last (top) tnode */
        if (IS_TNODE(tn))
-               tn = (struct tnode*) resize(t, (struct tnode *)tn);
+               tn = (struct tnode *)resize(t, (struct tnode *)tn);
 
-       return (struct node*) tn;
+       return (struct node *)tn;
 }
 
 /* only used from updater-side */
 
-static  struct list_head *
-fib_insert_node(struct trie *t, int *err, u32 key, int plen)
+static struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
 {
        int pos, newpos;
        struct tnode *tp = NULL, *tn = NULL;
@@ -1036,7 +1043,10 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
                if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
                        tp = tn;
                        pos = tn->pos + tn->bits;
-                       n = tnode_get_child(tn, tkey_extract_bits(key, tn->pos, tn->bits));
+                       n = tnode_get_child(tn,
+                                           tkey_extract_bits(key,
+                                                             tn->pos,
+                                                             tn->bits));
 
                        BUG_ON(n && node_parent(n) != tn);
                } else
@@ -1054,34 +1064,27 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
        /* Case 1: n is a leaf. Compare prefixes */
 
        if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
-               struct leaf *l = (struct leaf *) n;
-
+               l = (struct leaf *) n;
                li = leaf_info_new(plen);
 
-               if (!li) {
-                       *err = -ENOMEM;
-                       goto err;
-               }
+               if (!li)
+                       return NULL;
 
                fa_head = &li->falh;
                insert_leaf_info(&l->list, li);
                goto done;
        }
-       t->size++;
        l = leaf_new();
 
-       if (!l) {
-               *err = -ENOMEM;
-               goto err;
-       }
+       if (!l)
+               return NULL;
 
        l->key = key;
        li = leaf_info_new(plen);
 
        if (!li) {
                tnode_free((struct tnode *) l);
-               *err = -ENOMEM;
-               goto err;
+               return NULL;
        }
 
        fa_head = &li->falh;
@@ -1117,8 +1120,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
                if (!tn) {
                        free_leaf_info(li);
                        tnode_free((struct tnode *) l);
-                       *err = -ENOMEM;
-                       goto err;
+                       return NULL;
                }
 
                node_set_parent((struct node *)tn, tp);
@@ -1129,23 +1131,23 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
 
                if (tp) {
                        cindex = tkey_extract_bits(key, tp->pos, tp->bits);
-                       put_child(t, (struct tnode *)tp, cindex, (struct node *)tn);
+                       put_child(t, (struct tnode *)tp, cindex,
+                                 (struct node *)tn);
                } else {
-                       rcu_assign_pointer(t->trie, (struct node *)tn); /* First tnode */
+                       rcu_assign_pointer(t->trie, (struct node *)tn);
                        tp = tn;
                }
        }
 
        if (tp && tp->pos + tp->bits > 32)
-               printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
-                      tp, tp->pos, tp->bits, key, plen);
+               pr_warning("fib_trie"
+                          " tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
+                          tp, tp->pos, tp->bits, key, plen);
 
        /* Rebalance the trie */
 
        rcu_assign_pointer(t->trie, trie_rebalance(t, tp));
 done:
-       t->revision++;
-err:
        return fa_head;
 }
 
@@ -1253,10 +1255,10 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
                                break;
                        if (fa->fa_type == cfg->fc_type &&
                            fa->fa_scope == cfg->fc_scope &&
-                           fa->fa_info == fi) {
+                           fa->fa_info == fi)
                                goto out;
-                       }
                }
+
                if (!(cfg->fc_nlflags & NLM_F_APPEND))
                        fa = fa_orig;
        }
@@ -1279,10 +1281,11 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
         */
 
        if (!fa_head) {
-               err = 0;
-               fa_head = fib_insert_node(t, &err, key, plen);
-               if (err)
+               fa_head = fib_insert_node(t, key, plen);
+               if (unlikely(!fa_head)) {
+                       err = -ENOMEM;
                        goto out_free_new_fa;
+               }
        }
 
        list_add_tail_rcu(&new_fa->fa_list,
@@ -1302,40 +1305,41 @@ err:
        return err;
 }
 
-
 /* should be called with rcu_read_lock */
-static inline int check_leaf(struct trie *t, struct leaf *l,
-                            t_key key, int *plen, const struct flowi *flp,
-                            struct fib_result *res)
+static int check_leaf(struct trie *t, struct leaf *l,
+                     t_key key,  const struct flowi *flp,
+                     struct fib_result *res)
 {
-       int err, i;
-       __be32 mask;
        struct leaf_info *li;
        struct hlist_head *hhead = &l->list;
        struct hlist_node *node;
 
        hlist_for_each_entry_rcu(li, node, hhead, hlist) {
-               i = li->plen;
-               mask = inet_make_mask(i);
+               int err;
+               int plen = li->plen;
+               __be32 mask = inet_make_mask(plen);
+
                if (l->key != (key & ntohl(mask)))
                        continue;
 
-               if ((err = fib_semantic_match(&li->falh, flp, res, htonl(l->key), mask, i)) <= 0) {
-                       *plen = i;
+               err = fib_semantic_match(&li->falh, flp, res,
+                                        htonl(l->key), mask, plen);
+
 #ifdef CONFIG_IP_FIB_TRIE_STATS
+               if (err <= 0)
                        t->stats.semantic_match_passed++;
+               else
+                       t->stats.semantic_match_miss++;
 #endif
-                       return err;
-               }
-#ifdef CONFIG_IP_FIB_TRIE_STATS
-               t->stats.semantic_match_miss++;
-#endif
+               if (err <= 0)
+                       return plen;
        }
-       return 1;
+
+       return -1;
 }
 
-static int
-fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
+                         struct fib_result *res)
 {
        struct trie *t = (struct trie *) tb->tb_data;
        int plen, ret = 0;
@@ -1362,10 +1366,13 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
 
        /* Just a leaf? */
        if (IS_LEAF(n)) {
-               if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
-                       goto found;
-               goto failed;
+               plen = check_leaf(t, (struct leaf *)n, key, flp, res);
+               if (plen < 0)
+                       goto failed;
+               ret = 0;
+               goto found;
        }
+
        pn = (struct tnode *) n;
        chopped_off = 0;
 
@@ -1387,14 +1394,14 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                }
 
                if (IS_LEAF(n)) {
-                       if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0)
-                               goto found;
-                       else
+                       plen = check_leaf(t, (struct leaf *)n, key, flp, res);
+                       if (plen < 0)
                                goto backtrace;
+
+                       ret = 0;
+                       goto found;
                }
 
-#define HL_OPTIMIZE
-#ifdef HL_OPTIMIZE
                cn = (struct tnode *)n;
 
                /*
@@ -1423,12 +1430,13 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                 * *are* zero.
                 */
 
-               /* NOTA BENE: CHECKING ONLY SKIPPED BITS FOR THE NEW NODE HERE */
+               /* NOTA BENE: Checking only skipped bits
+                  for the new node here */
 
                if (current_prefix_length < pos+bits) {
                        if (tkey_extract_bits(cn->key, current_prefix_length,
-                                               cn->pos - current_prefix_length) != 0 ||
-                           !(cn->child[0]))
+                                               cn->pos - current_prefix_length)
+                           || !(cn->child[0]))
                                goto backtrace;
                }
 
@@ -1451,14 +1459,17 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                 * new tnode's key.
                 */
 
-               /* Note: We aren't very concerned about the piece of the key
-                * that precede pn->pos+pn->bits, since these have already been
-                * checked. The bits after cn->pos aren't checked since these are
-                * by definition "unknown" at this point. Thus, what we want to
-                * see is if we are about to enter the "prefix matching" state,
-                * and in that case verify that the skipped bits that will prevail
-                * throughout this subtree are zero, as they have to be if we are
-                * to find a matching prefix.
+               /*
+                * Note: We aren't very concerned about the piece of
+                * the key that precede pn->pos+pn->bits, since these
+                * have already been checked. The bits after cn->pos
+                * aren't checked since these are by definition
+                * "unknown" at this point. Thus, what we want to see
+                * is if we are about to enter the "prefix matching"
+                * state, and in that case verify that the skipped
+                * bits that will prevail throughout this subtree are
+                * zero, as they have to be if we are to find a
+                * matching prefix.
                 */
 
                node_prefix = mask_pfx(cn->key, cn->pos);
@@ -1466,13 +1477,15 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                pref_mismatch = key_prefix^node_prefix;
                mp = 0;
 
-               /* In short: If skipped bits in this node do not match the search
-                * key, enter the "prefix matching" state.directly.
+               /*
+                * In short: If skipped bits in this node do not match
+                * the search key, enter the "prefix matching"
+                * state.directly.
                 */
                if (pref_mismatch) {
                        while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) {
                                mp++;
-                               pref_mismatch = pref_mismatch <<1;
+                               pref_mismatch = pref_mismatch << 1;
                        }
                        key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp);
 
@@ -1482,7 +1495,7 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
                        if (current_prefix_length >= cn->pos)
                                current_prefix_length = mp;
                }
-#endif
+
                pn = (struct tnode *)n; /* Descend */
                chopped_off = 0;
                continue;
@@ -1491,12 +1504,14 @@ backtrace:
                chopped_off++;
 
                /* As zero don't change the child key (cindex) */
-               while ((chopped_off <= pn->bits) && !(cindex & (1<<(chopped_off-1))))
+               while ((chopped_off <= pn->bits)
+                      && !(cindex & (1<<(chopped_off-1))))
                        chopped_off++;
 
                /* Decrease current_... with bits chopped off */
                if (current_prefix_length > pn->pos + pn->bits - chopped_off)
-                       current_prefix_length = pn->pos + pn->bits - chopped_off;
+                       current_prefix_length = pn->pos + pn->bits
+                               - chopped_off;
 
                /*
                 * Either we do the actual chop off according or if we have
@@ -1528,52 +1543,23 @@ found:
        return ret;
 }
 
-/* only called from updater side */
-static int trie_leaf_remove(struct trie *t, t_key key)
+/*
+ * Remove the leaf and return parent.
+ */
+static void trie_leaf_remove(struct trie *t, struct leaf *l)
 {
-       t_key cindex;
-       struct tnode *tp = NULL;
-       struct node *n = t->trie;
-       struct leaf *l;
-
-       pr_debug("entering trie_leaf_remove(%p)\n", n);
-
-       /* Note that in the case skipped bits, those bits are *not* checked!
-        * When we finish this, we will have NULL or a T_LEAF, and the
-        * T_LEAF may or may not match our key.
-        */
-
-       while (n != NULL && IS_TNODE(n)) {
-               struct tnode *tn = (struct tnode *) n;
-               check_tnode(tn);
-               n = tnode_get_child(tn ,tkey_extract_bits(key, tn->pos, tn->bits));
-
-               BUG_ON(n && node_parent(n) != tn);
-       }
-       l = (struct leaf *) n;
-
-       if (!n || !tkey_equals(l->key, key))
-               return 0;
-
-       /*
-        * Key found.
-        * Remove the leaf and rebalance the tree
-        */
-
-       t->revision++;
-       t->size--;
+       struct tnode *tp = node_parent((struct node *) l);
 
-       tp = node_parent(n);
-       tnode_free((struct tnode *) n);
+       pr_debug("entering trie_leaf_remove(%p)\n", l);
 
        if (tp) {
-               cindex = tkey_extract_bits(key, tp->pos, tp->bits);
+               t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits);
                put_child(t, (struct tnode *)tp, cindex, NULL);
                rcu_assign_pointer(t->trie, trie_rebalance(t, tp));
        } else
                rcu_assign_pointer(t->trie, NULL);
 
-       return 1;
+       tnode_free((struct tnode *) l);
 }
 
 /*
@@ -1651,7 +1637,7 @@ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg)
        }
 
        if (hlist_empty(&l->list))
-               trie_leaf_remove(t, key);
+               trie_leaf_remove(t, l);
 
        if (fa->fa_state & FA_S_ACCESSED)
                rt_cache_flush(-1);
@@ -1697,64 +1683,64 @@ static int trie_flush_leaf(struct trie *t, struct leaf *l)
        return found;
 }
 
-/* rcu_read_lock needs to be hold by caller from readside */
-
-static struct leaf *nextleaf(struct trie *t, struct leaf *thisleaf)
+/*
+ * Scan for the next right leaf starting at node p->child[idx]
+ * Since we have back pointer, no recursion necessary.
+ */
+static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c)
 {
-       struct node *c = (struct node *) thisleaf;
-       struct tnode *p;
-       int idx;
-       struct node *trie = rcu_dereference(t->trie);
-
-       if (c == NULL) {
-               if (trie == NULL)
-                       return NULL;
-
-               if (IS_LEAF(trie))          /* trie w. just a leaf */
-                       return (struct leaf *) trie;
-
-               p = (struct tnode*) trie;  /* Start */
-       } else
-               p = node_parent(c);
-
-       while (p) {
-               int pos, last;
+       do {
+               t_key idx;
 
-               /*  Find the next child of the parent */
                if (c)
-                       pos = 1 + tkey_extract_bits(c->key, p->pos, p->bits);
+                       idx = tkey_extract_bits(c->key, p->pos, p->bits) + 1;
                else
-                       pos = 0;
-
-               last = 1 << p->bits;
-               for (idx = pos; idx < last ; idx++) {
-                       c = rcu_dereference(p->child[idx]);
+                       idx = 0;
 
+               while (idx < 1u << p->bits) {
+                       c = tnode_get_child_rcu(p, idx++);
                        if (!c)
                                continue;
 
-                       /* Decend if tnode */
-                       while (IS_TNODE(c)) {
-                               p = (struct tnode *) c;
-                               idx = 0;
-
-                               /* Rightmost non-NULL branch */
-                               if (p && IS_TNODE(p))
-                                       while (!(c = rcu_dereference(p->child[idx]))
-                                              && idx < (1<<p->bits)) idx++;
-
-                               /* Done with this tnode? */
-                               if (idx >= (1 << p->bits) || !c)
-                                       goto up;
+                       if (IS_LEAF(c)) {
+                               prefetch(p->child[idx]);
+                               return (struct leaf *) c;
                        }
-                       return (struct leaf *) c;
+
+                       /* Rescan start scanning in new node */
+                       p = (struct tnode *) c;
+                       idx = 0;
                }
-up:
-               /* No more children go up one step  */
+
+               /* Node empty, walk back up to parent */
                c = (struct node *) p;
-               p = node_parent(c);
-       }
-       return NULL; /* Ready. Root of trie */
+       } while ( (p = node_parent_rcu(c)) != NULL);
+
+       return NULL; /* Root of trie */
+}
+
+static struct leaf *trie_firstleaf(struct trie *t)
+{
+       struct tnode *n = (struct tnode *) rcu_dereference(t->trie);
+
+       if (!n)
+               return NULL;
+
+       if (IS_LEAF(n))          /* trie is just a leaf */
+               return (struct leaf *) n;
+
+       return leaf_walk_rcu(n, NULL);
+}
+
+static struct leaf *trie_nextleaf(struct leaf *l)
+{
+       struct node *c = (struct node *) l;
+       struct tnode *p = node_parent(c);
+
+       if (!p)
+               return NULL;    /* trie with just one leaf */
+
+       return leaf_walk_rcu(p, c);
 }
 
 /*
@@ -1763,30 +1749,27 @@ up:
 static int fn_trie_flush(struct fib_table *tb)
 {
        struct trie *t = (struct trie *) tb->tb_data;
-       struct leaf *ll = NULL, *l = NULL;
-       int found = 0, h;
-
-       t->revision++;
+       struct leaf *l, *ll = NULL;
+       int found = 0;
 
-       for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
+       for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
                found += trie_flush_leaf(t, l);
 
                if (ll && hlist_empty(&ll->list))
-                       trie_leaf_remove(t, ll->key);
+                       trie_leaf_remove(t, ll);
                ll = l;
        }
 
        if (ll && hlist_empty(&ll->list))
-               trie_leaf_remove(t, ll->key);
+               trie_leaf_remove(t, ll);
 
        pr_debug("trie_flush found=%d\n", found);
        return found;
 }
 
-static int trie_last_dflt = -1;
-
-static void
-fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
+static void fn_trie_select_default(struct fib_table *tb,
+                                  const struct flowi *flp,
+                                  struct fib_result *res)
 {
        struct trie *t = (struct trie *) tb->tb_data;
        int order, last_idx;
@@ -1831,48 +1814,38 @@ fn_trie_select_default(struct fib_table *tb, const struct flowi *flp, struct fib
                        if (next_fi != res->fi)
                                break;
                } else if (!fib_detect_death(fi, order, &last_resort,
-                                            &last_idx, &trie_last_dflt)) {
-                       if (res->fi)
-                               fib_info_put(res->fi);
-                       res->fi = fi;
-                       atomic_inc(&fi->fib_clntref);
-                       trie_last_dflt = order;
+                                            &last_idx, tb->tb_default)) {
+                       fib_result_assign(res, fi);
+                       tb->tb_default = order;
                        goto out;
                }
                fi = next_fi;
                order++;
        }
        if (order <= 0 || fi == NULL) {
-               trie_last_dflt = -1;
+               tb->tb_default = -1;
                goto out;
        }
 
-       if (!fib_detect_death(fi, order, &last_resort, &last_idx, &trie_last_dflt)) {
-               if (res->fi)
-                       fib_info_put(res->fi);
-               res->fi = fi;
-               atomic_inc(&fi->fib_clntref);
-               trie_last_dflt = order;
+       if (!fib_detect_death(fi, order, &last_resort, &last_idx,
+                               tb->tb_default)) {
+               fib_result_assign(res, fi);
+               tb->tb_default = order;
                goto out;
        }
-       if (last_idx >= 0) {
-               if (res->fi)
-                       fib_info_put(res->fi);
-               res->fi = last_resort;
-               if (last_resort)
-                       atomic_inc(&last_resort->fib_clntref);
-       }
-       trie_last_dflt = last_idx;
- out:;
+       if (last_idx >= 0)
+               fib_result_assign(res, last_resort);
+       tb->tb_default = last_idx;
+out:
        rcu_read_unlock();
 }
 
-static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fib_table *tb,
+static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
+                          struct fib_table *tb,
                           struct sk_buff *skb, struct netlink_callback *cb)
 {
        int i, s_i;
        struct fib_alias *fa;
-
        __be32 xkey = htonl(key);
 
        s_i = cb->args[4];
@@ -1885,7 +1858,6 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
                        i++;
                        continue;
                }
-               BUG_ON(!fa->fa_info);
 
                if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
                                  cb->nlh->nlmsg_seq,
@@ -1896,7 +1868,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
                                  xkey,
                                  plen,
                                  fa->fa_tos,
-                                 fa->fa_info, 0) < 0) {
+                                 fa->fa_info, NLM_F_MULTI) < 0) {
                        cb->args[4] = i;
                        return -1;
                }
@@ -1906,109 +1878,118 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
        return skb->len;
 }
 
-static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb, struct sk_buff *skb,
-                            struct netlink_callback *cb)
+static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
+                       struct sk_buff *skb, struct netlink_callback *cb)
 {
-       int h, s_h;
-       struct list_head *fa_head;
-       struct leaf *l = NULL;
+       struct leaf_info *li;
+       struct hlist_node *node;
+       int i, s_i;
 
-       s_h = cb->args[3];
+       s_i = cb->args[3];
+       i = 0;
 
-       for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {
-               if (h < s_h)
+       /* rcu_read_lock is hold by caller */
+       hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
+               if (i < s_i) {
+                       i++;
                        continue;
-               if (h > s_h)
-                       memset(&cb->args[4], 0,
-                              sizeof(cb->args) - 4*sizeof(cb->args[0]));
-
-               fa_head = get_fa_head(l, plen);
+               }
 
-               if (!fa_head)
-                       continue;
+               if (i > s_i)
+                       cb->args[4] = 0;
 
-               if (list_empty(fa_head))
+               if (list_empty(&li->falh))
                        continue;
 
-               if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb)<0) {
-                       cb->args[3] = h;
+               if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
+                       cb->args[3] = i;
                        return -1;
                }
+               i++;
        }
-       cb->args[3] = h;
+
+       cb->args[3] = i;
        return skb->len;
 }
 
-static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb)
+static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
+                       struct netlink_callback *cb)
 {
-       int m, s_m;
+       struct leaf *l;
        struct trie *t = (struct trie *) tb->tb_data;
-
-       s_m = cb->args[2];
+       t_key key = cb->args[2];
 
        rcu_read_lock();
-       for (m = 0; m <= 32; m++) {
-               if (m < s_m)
-                       continue;
-               if (m > s_m)
-                       memset(&cb->args[3], 0,
-                               sizeof(cb->args) - 3*sizeof(cb->args[0]));
+       /* Dump starting at last key.
+        * Note: 0.0.0.0/0 (ie default) is first key.
+        */
+       if (!key)
+               l = trie_firstleaf(t);
+       else {
+               l = fib_find_node(t, key);
+               if (!l) {
+                       /* The table changed during the dump, rather than
+                        * giving partial data, just make application retry.
+                        */
+                       rcu_read_unlock();
+                       return -EBUSY;
+               }
+       }
 
-               if (fn_trie_dump_plen(t, 32-m, tb, skb, cb)<0) {
-                       cb->args[2] = m;
-                       goto out;
+       while (l) {
+               cb->args[2] = l->key;
+               if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+                       rcu_read_unlock();
+                       return -1;
                }
+
+               l = trie_nextleaf(l);
+               memset(&cb->args[3], 0,
+                      sizeof(cb->args) - 3*sizeof(cb->args[0]));
        }
        rcu_read_unlock();
-       cb->args[2] = m;
+
        return skb->len;
-out:
-       rcu_read_unlock();
-       return -1;
 }
 
-/* Fix more generic FIB names for init later */
+void __init fib_hash_init(void)
+{
+       fn_alias_kmem = kmem_cache_create("ip_fib_alias",
+                                         sizeof(struct fib_alias),
+                                         0, SLAB_PANIC, NULL);
 
-#ifdef CONFIG_IP_MULTIPLE_TABLES
-struct fib_table * fib_hash_init(u32 id)
-#else
-struct fib_table * __init fib_hash_init(u32 id)
-#endif
+       trie_leaf_kmem = kmem_cache_create("ip_fib_trie",
+                                          max(sizeof(struct leaf),
+                                              sizeof(struct leaf_info)),
+                                          0, SLAB_PANIC, NULL);
+}
+
+
+/* Fix more generic FIB names for init later */
+struct fib_table *fib_hash_table(u32 id)
 {
        struct fib_table *tb;
        struct trie *t;
 
-       if (fn_alias_kmem == NULL)
-               fn_alias_kmem = kmem_cache_create("ip_fib_alias",
-                                                 sizeof(struct fib_alias),
-                                                 0, SLAB_HWCACHE_ALIGN,
-                                                 NULL);
-
        tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
                     GFP_KERNEL);
        if (tb == NULL)
                return NULL;
 
        tb->tb_id = id;
+       tb->tb_default = -1;
        tb->tb_lookup = fn_trie_lookup;
        tb->tb_insert = fn_trie_insert;
        tb->tb_delete = fn_trie_delete;
        tb->tb_flush = fn_trie_flush;
        tb->tb_select_default = fn_trie_select_default;
        tb->tb_dump = fn_trie_dump;
-       memset(tb->tb_data, 0, sizeof(struct trie));
 
        t = (struct trie *) tb->tb_data;
-
-       trie_init(t);
-
-       if (id == RT_TABLE_LOCAL)
-               trie_local = t;
-       else if (id == RT_TABLE_MAIN)
-               trie_main = t;
+       memset(t, 0, sizeof(*t));
 
        if (id == RT_TABLE_LOCAL)
-               printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
+               pr_info("IPv4 FIB: Using LC-trie version %s\n", VERSION);
 
        return tb;
 }
@@ -2016,6 +1997,8 @@ struct fib_table * __init fib_hash_init(u32 id)
 #ifdef CONFIG_PROC_FS
 /* Depth first Trie walk iterator */
 struct fib_trie_iter {
+       struct seq_net_private p;
+       struct trie *trie_local, *trie_main;
        struct tnode *tnode;
        struct trie *trie;
        unsigned index;
@@ -2036,7 +2019,7 @@ static struct node *fib_trie_get_next(struct fib_trie_iter *iter)
                 iter->tnode, iter->index, iter->depth);
 rescan:
        while (cindex < (1<<tn->bits)) {
-               struct node *n = tnode_get_child(tn, cindex);
+               struct node *n = tnode_get_child_rcu(tn, cindex);
 
                if (n) {
                        if (IS_LEAF(n)) {
@@ -2055,7 +2038,7 @@ rescan:
        }
 
        /* Current node exhausted, pop back up */
-       p = node_parent((struct node *)tn);
+       p = node_parent_rcu((struct node *)tn);
        if (p) {
                cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
                tn = p;
@@ -2108,10 +2091,17 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s)
        for (n = fib_trie_get_first(&iter, t); n;
             n = fib_trie_get_next(&iter)) {
                if (IS_LEAF(n)) {
+                       struct leaf *l = (struct leaf *)n;
+                       struct leaf_info *li;
+                       struct hlist_node *tmp;
+
                        s->leaves++;
                        s->totdepth += iter.depth;
                        if (iter.depth > s->maxdepth)
                                s->maxdepth = iter.depth;
+
+                       hlist_for_each_entry_rcu(li, tmp, &l->list, hlist)
+                               ++s->prefixes;
                } else {
                        const struct tnode *tn = (const struct tnode *) n;
                        int i;
@@ -2140,13 +2130,17 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
        else
                avdepth = 0;
 
-       seq_printf(seq, "\tAver depth:     %d.%02d\n", avdepth / 100, avdepth % 100 );
+       seq_printf(seq, "\tAver depth:     %u.%02d\n",
+                  avdepth / 100, avdepth % 100);
        seq_printf(seq, "\tMax depth:      %u\n", stat->maxdepth);
 
        seq_printf(seq, "\tLeaves:         %u\n", stat->leaves);
-
        bytes = sizeof(struct leaf) * stat->leaves;
-       seq_printf(seq, "\tInternal nodes: %d\n\t", stat->tnodes);
+
+       seq_printf(seq, "\tPrefixes:       %u\n", stat->prefixes);
+       bytes += sizeof(struct leaf_info) * stat->prefixes;
+
+       seq_printf(seq, "\tInternal nodes: %u\n\t", stat->tnodes);
        bytes += sizeof(struct tnode) * stat->tnodes;
 
        max = MAX_STAT_DEPTH;
@@ -2156,60 +2150,89 @@ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
        pointers = 0;
        for (i = 1; i <= max; i++)
                if (stat->nodesizes[i] != 0) {
-                       seq_printf(seq, "  %d: %d",  i, stat->nodesizes[i]);
+                       seq_printf(seq, "  %u: %u",  i, stat->nodesizes[i]);
                        pointers += (1<<i) * stat->nodesizes[i];
                }
        seq_putc(seq, '\n');
-       seq_printf(seq, "\tPointers: %d\n", pointers);
+       seq_printf(seq, "\tPointers: %u\n", pointers);
 
        bytes += sizeof(struct node *) * pointers;
-       seq_printf(seq, "Null ptrs: %d\n", stat->nullpointers);
-       seq_printf(seq, "Total size: %d  kB\n", (bytes + 1023) / 1024);
+       seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers);
+       seq_printf(seq, "Total size: %u  kB\n", (bytes + 1023) / 1024);
+}
 
 #ifdef CONFIG_IP_FIB_TRIE_STATS
-       seq_printf(seq, "Counters:\n---------\n");
-       seq_printf(seq,"gets = %d\n", t->stats.gets);
-       seq_printf(seq,"backtracks = %d\n", t->stats.backtrack);
-       seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed);
-       seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss);
-       seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit);
-       seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped);
-#ifdef CLEAR_STATS
-       memset(&(t->stats), 0, sizeof(t->stats));
-#endif
+static void trie_show_usage(struct seq_file *seq,
+                           const struct trie_use_stats *stats)
+{
+       seq_printf(seq, "\nCounters:\n---------\n");
+       seq_printf(seq, "gets = %u\n", stats->gets);
+       seq_printf(seq, "backtracks = %u\n", stats->backtrack);
+       seq_printf(seq, "semantic match passed = %u\n",
+                  stats->semantic_match_passed);
+       seq_printf(seq, "semantic match miss = %u\n",
+                  stats->semantic_match_miss);
+       seq_printf(seq, "null node hit= %u\n", stats->null_node_hit);
+       seq_printf(seq, "skipped node resize = %u\n\n",
+                  stats->resize_node_skipped);
+}
 #endif /*  CONFIG_IP_FIB_TRIE_STATS */
+
+static void fib_trie_show(struct seq_file *seq, const char *name,
+                         struct trie *trie)
+{
+       struct trie_stat stat;
+
+       trie_collect_stats(trie, &stat);
+       seq_printf(seq, "%s:\n", name);
+       trie_show_stats(seq, &stat);
+#ifdef CONFIG_IP_FIB_TRIE_STATS
+       trie_show_usage(seq, &trie->stats);
+#endif
 }
 
 static int fib_triestat_seq_show(struct seq_file *seq, void *v)
 {
-       struct trie_stat *stat;
-
-       stat = kmalloc(sizeof(*stat), GFP_KERNEL);
-       if (!stat)
-               return -ENOMEM;
+       struct net *net = (struct net *)seq->private;
+       struct fib_table *tb;
 
-       seq_printf(seq, "Basic info: size of leaf: %Zd bytes, size of tnode: %Zd bytes.\n",
+       seq_printf(seq,
+                  "Basic info: size of leaf:"
+                  " %Zd bytes, size of tnode: %Zd bytes.\n",
                   sizeof(struct leaf), sizeof(struct tnode));
 
-       if (trie_local) {
-               seq_printf(seq, "Local:\n");
-               trie_collect_stats(trie_local, stat);
-               trie_show_stats(seq, stat);
-       }
+       tb = fib_get_table(net, RT_TABLE_LOCAL);
+       if (tb)
+               fib_trie_show(seq, "Local", (struct trie *) tb->tb_data);
 
-       if (trie_main) {
-               seq_printf(seq, "Main:\n");
-               trie_collect_stats(trie_main, stat);
-               trie_show_stats(seq, stat);
-       }
-       kfree(stat);
+       tb = fib_get_table(net, RT_TABLE_MAIN);
+       if (tb)
+               fib_trie_show(seq, "Main", (struct trie *) tb->tb_data);
 
        return 0;
 }
 
 static int fib_triestat_seq_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, fib_triestat_seq_show, NULL);
+       int err;
+       struct net *net;
+
+       net = get_proc_net(inode);
+       if (net == NULL)
+               return -ENXIO;
+       err = single_open(file, fib_triestat_seq_show, net);
+       if (err < 0) {
+               put_net(net);
+               return err;
+       }
+       return 0;
+}
+
+static int fib_triestat_seq_release(struct inode *ino, struct file *f)
+{
+       struct seq_file *seq = f->private_data;
+       put_net(seq->private);
+       return single_release(ino, f);
 }
 
 static const struct file_operations fib_triestat_fops = {
@@ -2217,7 +2240,7 @@ static const struct file_operations fib_triestat_fops = {
        .open   = fib_triestat_seq_open,
        .read   = seq_read,
        .llseek = seq_lseek,
-       .release = single_release,
+       .release = fib_triestat_seq_release,
 };
 
 static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
@@ -2226,13 +2249,13 @@ static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
        loff_t idx = 0;
        struct node *n;
 
-       for (n = fib_trie_get_first(iter, trie_local);
+       for (n = fib_trie_get_first(iter, iter->trie_local);
             n; ++idx, n = fib_trie_get_next(iter)) {
                if (pos == idx)
                        return n;
        }
 
-       for (n = fib_trie_get_first(iter, trie_main);
+       for (n = fib_trie_get_first(iter, iter->trie_main);
             n; ++idx, n = fib_trie_get_next(iter)) {
                if (pos == idx)
                        return n;
@@ -2241,11 +2264,25 @@ static struct node *fib_trie_get_idx(struct fib_trie_iter *iter,
 }
 
 static void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(RCU)
 {
+       struct fib_trie_iter *iter = seq->private;
+       struct fib_table *tb;
+
+       if (!iter->trie_local) {
+               tb = fib_get_table(iter->p.net, RT_TABLE_LOCAL);
+               if (tb)
+                       iter->trie_local = (struct trie *) tb->tb_data;
+       }
+       if (!iter->trie_main) {
+               tb = fib_get_table(iter->p.net, RT_TABLE_MAIN);
+               if (tb)
+                       iter->trie_main = (struct trie *) tb->tb_data;
+       }
        rcu_read_lock();
        if (*pos == 0)
                return SEQ_START_TOKEN;
-       return fib_trie_get_idx(seq->private, *pos - 1);
+       return fib_trie_get_idx(iter, *pos - 1);
 }
 
 static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
@@ -2263,13 +2300,14 @@ static void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                return v;
 
        /* continue scan in next trie */
-       if (iter->trie == trie_local)
-               return fib_trie_get_first(iter, trie_main);
+       if (iter->trie == iter->trie_local)
+               return fib_trie_get_first(iter, iter->trie_main);
 
        return NULL;
 }
 
 static void fib_trie_seq_stop(struct seq_file *seq, void *v)
+       __releases(RCU)
 {
        rcu_read_unlock();
 }
@@ -2279,10 +2317,8 @@ static void seq_indent(struct seq_file *seq, int n)
        while (n-- > 0) seq_puts(seq, "   ");
 }
 
-static inline const char *rtn_scope(enum rt_scope_t s)
+static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
 {
-       static char buf[32];
-
        switch (s) {
        case RT_SCOPE_UNIVERSE: return "universe";
        case RT_SCOPE_SITE:     return "site";
@@ -2290,7 +2326,7 @@ static inline const char *rtn_scope(enum rt_scope_t s)
        case RT_SCOPE_HOST:     return "host";
        case RT_SCOPE_NOWHERE:  return "nowhere";
        default:
-               snprintf(buf, sizeof(buf), "scope=%d", s);
+               snprintf(buf, len, "scope=%d", s);
                return buf;
        }
 }
@@ -2310,13 +2346,11 @@ static const char *rtn_type_names[__RTN_MAX] = {
        [RTN_XRESOLVE] = "XRESOLVE",
 };
 
-static inline const char *rtn_type(unsigned t)
+static inline const char *rtn_type(char *buf, size_t len, unsigned t)
 {
-       static char buf[32];
-
        if (t < __RTN_MAX && rtn_type_names[t])
                return rtn_type_names[t];
-       snprintf(buf, sizeof(buf), "type %d", t);
+       snprintf(buf, len, "type %u", t);
        return buf;
 }
 
@@ -2329,8 +2363,8 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
        if (v == SEQ_START_TOKEN)
                return 0;
 
-       if (!node_parent(n)) {
-               if (iter->trie == trie_local)
+       if (!node_parent_rcu(n)) {
+               if (iter->trie == iter->trie_local)
                        seq_puts(seq, "<local>:\n");
                else
                        seq_puts(seq, "<main>:\n");
@@ -2347,25 +2381,29 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
 
        } else {
                struct leaf *l = (struct leaf *) n;
-               int i;
+               struct leaf_info *li;
+               struct hlist_node *node;
                __be32 val = htonl(l->key);
 
                seq_indent(seq, iter->depth);
                seq_printf(seq, "  |-- %d.%d.%d.%d\n", NIPQUAD(val));
-               for (i = 32; i >= 0; i--) {
-                       struct leaf_info *li = find_leaf_info(l, i);
-                       if (li) {
-                               struct fib_alias *fa;
-                               list_for_each_entry_rcu(fa, &li->falh, fa_list) {
-                                       seq_indent(seq, iter->depth+1);
-                                       seq_printf(seq, "  /%d %s %s", i,
-                                                  rtn_scope(fa->fa_scope),
-                                                  rtn_type(fa->fa_type));
-                                       if (fa->fa_tos)
-                                               seq_printf(seq, "tos =%d\n",
-                                                          fa->fa_tos);
-                                       seq_putc(seq, '\n');
-                               }
+
+               hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
+                       struct fib_alias *fa;
+
+                       list_for_each_entry_rcu(fa, &li->falh, fa_list) {
+                               char buf1[32], buf2[32];
+
+                               seq_indent(seq, iter->depth+1);
+                               seq_printf(seq, "  /%d %s %s", li->plen,
+                                          rtn_scope(buf1, sizeof(buf1),
+                                                    fa->fa_scope),
+                                          rtn_type(buf2, sizeof(buf2),
+                                                   fa->fa_type));
+                               if (fa->fa_tos)
+                                       seq_printf(seq, "tos =%d\n",
+                                                  fa->fa_tos);
+                               seq_putc(seq, '\n');
                        }
                }
        }
@@ -2382,8 +2420,8 @@ static const struct seq_operations fib_trie_seq_ops = {
 
 static int fib_trie_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &fib_trie_seq_ops,
-                       sizeof(struct fib_trie_iter));
+       return seq_open_net(inode, file, &fib_trie_seq_ops,
+                           sizeof(struct fib_trie_iter));
 }
 
 static const struct file_operations fib_trie_fops = {
@@ -2391,7 +2429,7 @@ static const struct file_operations fib_trie_fops = {
        .open   = fib_trie_seq_open,
        .read   = seq_read,
        .llseek = seq_lseek,
-       .release = seq_release_private,
+       .release = seq_release_net,
 };
 
 static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
@@ -2419,8 +2457,8 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
 {
        const struct fib_trie_iter *iter = seq->private;
        struct leaf *l = v;
-       int i;
-       char bf[128];
+       struct leaf_info *li;
+       struct hlist_node *node;
 
        if (v == SEQ_START_TOKEN) {
                seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
@@ -2429,25 +2467,23 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
 
-       if (iter->trie == trie_local)
+       if (iter->trie == iter->trie_local)
                return 0;
+
        if (IS_TNODE(l))
                return 0;
 
-       for (i=32; i>=0; i--) {
-               struct leaf_info *li = find_leaf_info(l, i);
+       hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
                struct fib_alias *fa;
                __be32 mask, prefix;
 
-               if (!li)
-                       continue;
-
                mask = inet_make_mask(li->plen);
                prefix = htonl(l->key);
 
                list_for_each_entry_rcu(fa, &li->falh, fa_list) {
                        const struct fib_info *fi = fa->fa_info;
                        unsigned flags = fib_flag_trans(fa->fa_type, mask, fi);
+                       char bf[128];
 
                        if (fa->fa_type == RTN_BROADCAST
                            || fa->fa_type == RTN_MULTICAST)
@@ -2461,7 +2497,8 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
                                         fi->fib_nh->nh_gw, flags, 0, 0,
                                         fi->fib_priority,
                                         mask,
-                                        (fi->fib_advmss ? fi->fib_advmss + 40 : 0),
+                                        (fi->fib_advmss ?
+                                         fi->fib_advmss + 40 : 0),
                                         fi->fib_window,
                                         fi->fib_rtt >> 3);
                        else
@@ -2486,8 +2523,8 @@ static const struct seq_operations fib_route_seq_ops = {
 
 static int fib_route_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &fib_route_seq_ops,
-                       sizeof(struct fib_trie_iter));
+       return seq_open_net(inode, file, &fib_route_seq_ops,
+                           sizeof(struct fib_trie_iter));
 }
 
 static const struct file_operations fib_route_fops = {
@@ -2495,35 +2532,36 @@ static const struct file_operations fib_route_fops = {
        .open   = fib_route_seq_open,
        .read   = seq_read,
        .llseek = seq_lseek,
-       .release = seq_release_private,
+       .release = seq_release_net,
 };
 
-int __init fib_proc_init(void)
+int __net_init fib_proc_init(struct net *net)
 {
-       if (!proc_net_fops_create(&init_net, "fib_trie", S_IRUGO, &fib_trie_fops))
+       if (!proc_net_fops_create(net, "fib_trie", S_IRUGO, &fib_trie_fops))
                goto out1;
 
-       if (!proc_net_fops_create(&init_net, "fib_triestat", S_IRUGO, &fib_triestat_fops))
+       if (!proc_net_fops_create(net, "fib_triestat", S_IRUGO,
+                                 &fib_triestat_fops))
                goto out2;
 
-       if (!proc_net_fops_create(&init_net, "route", S_IRUGO, &fib_route_fops))
+       if (!proc_net_fops_create(net, "route", S_IRUGO, &fib_route_fops))
                goto out3;
 
        return 0;
 
 out3:
-       proc_net_remove(&init_net, "fib_triestat");
+       proc_net_remove(net, "fib_triestat");
 out2:
-       proc_net_remove(&init_net, "fib_trie");
+       proc_net_remove(net, "fib_trie");
 out1:
        return -ENOMEM;
 }
 
-void __init fib_proc_exit(void)
+void __net_exit fib_proc_exit(struct net *net)
 {
-       proc_net_remove(&init_net, "fib_trie");
-       proc_net_remove(&init_net, "fib_triestat");
-       proc_net_remove(&init_net, "route");
+       proc_net_remove(net, "fib_trie");
+       proc_net_remove(net, "fib_triestat");
+       proc_net_remove(net, "route");
 }
 
 #endif /* CONFIG_PROC_FS */
index 82baea026484d6b311986f24db8855dbf184b611..a7321a82df6d24b3a1921d3918c23412b4271a4c 100644 (file)
@@ -92,6 +92,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <net/checksum.h>
+#include <net/xfrm.h>
 
 /*
  *     Build xmit assembly blocks
@@ -231,7 +232,7 @@ static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
 static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL;
 #define icmp_socket    __get_cpu_var(__icmp_socket)
 
-static __inline__ int icmp_xmit_lock(void)
+static inline int icmp_xmit_lock(void)
 {
        local_bh_disable();
 
@@ -245,7 +246,7 @@ static __inline__ int icmp_xmit_lock(void)
        return 0;
 }
 
-static void icmp_xmit_unlock(void)
+static inline void icmp_xmit_unlock(void)
 {
        spin_unlock_bh(&icmp_socket->sk->sk_lock.slock);
 }
@@ -274,18 +275,19 @@ static void icmp_xmit_unlock(void)
 #define XRLIM_BURST_FACTOR 6
 int xrlim_allow(struct dst_entry *dst, int timeout)
 {
-       unsigned long now;
+       unsigned long now, token = dst->rate_tokens;
        int rc = 0;
 
        now = jiffies;
-       dst->rate_tokens += now - dst->rate_last;
+       token += now - dst->rate_last;
        dst->rate_last = now;
-       if (dst->rate_tokens > XRLIM_BURST_FACTOR * timeout)
-               dst->rate_tokens = XRLIM_BURST_FACTOR * timeout;
-       if (dst->rate_tokens >= timeout) {
-               dst->rate_tokens -= timeout;
+       if (token > XRLIM_BURST_FACTOR * timeout)
+               token = XRLIM_BURST_FACTOR * timeout;
+       if (token >= timeout) {
+               token -= timeout;
                rc = 1;
        }
+       dst->rate_tokens = token;
        return rc;
 }
 
@@ -403,7 +405,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
                                                .tos = RT_TOS(ip_hdr(skb)->tos) } },
                                    .proto = IPPROTO_ICMP };
                security_skb_classify_flow(skb, &fl);
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(rt->u.dst.dev->nd_net, &rt, &fl))
                        goto out_unlock;
        }
        if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type,
@@ -435,9 +437,11 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
        struct ipcm_cookie ipc;
        __be32 saddr;
        u8  tos;
+       struct net *net;
 
        if (!rt)
                goto out;
+       net = rt->u.dst.dev->nd_net;
 
        /*
         *      Find the original header. It is expected to be valid, of course.
@@ -513,7 +517,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                struct net_device *dev = NULL;
 
                if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr)
-                       dev = dev_get_by_index(&init_net, rt->fl.iif);
+                       dev = dev_get_by_index(net, rt->fl.iif);
 
                if (dev) {
                        saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
@@ -563,11 +567,71 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                                }
                        }
                };
+               int err;
+               struct rtable *rt2;
+
                security_skb_classify_flow(skb_in, &fl);
-               if (ip_route_output_key(&rt, &fl))
+               if (__ip_route_output_key(net, &rt, &fl))
+                       goto out_unlock;
+
+               /* No need to clone since we're just using its address. */
+               rt2 = rt;
+
+               err = xfrm_lookup((struct dst_entry **)&rt, &fl, NULL, 0);
+               switch (err) {
+               case 0:
+                       if (rt != rt2)
+                               goto route_done;
+                       break;
+               case -EPERM:
+                       rt = NULL;
+                       break;
+               default:
+                       goto out_unlock;
+               }
+
+               if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
+                       goto out_unlock;
+
+               if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL)
+                       err = __ip_route_output_key(net, &rt2, &fl);
+               else {
+                       struct flowi fl2 = {};
+                       struct dst_entry *odst;
+
+                       fl2.fl4_dst = fl.fl4_src;
+                       if (ip_route_output_key(net, &rt2, &fl2))
+                               goto out_unlock;
+
+                       /* Ugh! */
+                       odst = skb_in->dst;
+                       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 = (struct rtable *)skb_in->dst;
+                       skb_in->dst = odst;
+               }
+
+               if (err)
+                       goto out_unlock;
+
+               err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL,
+                                 XFRM_LOOKUP_ICMP);
+               if (err == -ENOENT) {
+                       if (!rt)
+                               goto out_unlock;
+                       goto route_done;
+               }
+
+               dst_release(&rt->u.dst);
+               rt = rt2;
+
+               if (err)
                        goto out_unlock;
        }
 
+route_done:
        if (!icmpv4_xrlim_allow(rt, type, code))
                goto ende;
 
@@ -603,8 +667,10 @@ static void icmp_unreach(struct sk_buff *skb)
        struct icmphdr *icmph;
        int hash, protocol;
        struct net_protocol *ipprot;
-       struct sock *raw_sk;
        u32 info = 0;
+       struct net *net;
+
+       net = skb->dst->dev->nd_net;
 
        /*
         *      Incomplete header ?
@@ -635,7 +701,7 @@ static void icmp_unreach(struct sk_buff *skb)
                                                         "and DF set.\n",
                                               NIPQUAD(iph->daddr));
                        } else {
-                               info = ip_rt_frag_needed(iph,
+                               info = ip_rt_frag_needed(net, iph,
                                                     ntohs(icmph->un.frag.mtu));
                                if (!info)
                                        goto out;
@@ -673,7 +739,7 @@ static void icmp_unreach(struct sk_buff *skb)
         */
 
        if (!sysctl_icmp_ignore_bogus_error_responses &&
-           inet_addr_type(iph->daddr) == RTN_BROADCAST) {
+           inet_addr_type(net, iph->daddr) == RTN_BROADCAST) {
                if (net_ratelimit())
                        printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
                                            "type %u, code %u "
@@ -697,21 +763,9 @@ static void icmp_unreach(struct sk_buff *skb)
        /*
         *      Deliver ICMP message to raw sockets. Pretty useless feature?
         */
+       raw_icmp_error(skb, protocol, info);
 
-       /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */
        hash = protocol & (MAX_INET_PROTOS - 1);
-       read_lock(&raw_v4_lock);
-       if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) {
-               while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
-                                                iph->saddr,
-                                                skb->dev->ifindex)) != NULL) {
-                       raw_err(raw_sk, skb, info);
-                       raw_sk = sk_next(raw_sk);
-                       iph = (struct iphdr *)skb->data;
-               }
-       }
-       read_unlock(&raw_v4_lock);
-
        rcu_read_lock();
        ipprot = rcu_dereference(inet_protos[hash]);
        if (ipprot && ipprot->err_handler)
@@ -929,6 +983,25 @@ int icmp_rcv(struct sk_buff *skb)
        struct icmphdr *icmph;
        struct rtable *rt = (struct rtable *)skb->dst;
 
+       if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+               int nh;
+
+               if (!(skb->sp && skb->sp->xvec[skb->sp->len - 1]->props.flags &
+                                XFRM_STATE_ICMP))
+                       goto drop;
+
+               if (!pskb_may_pull(skb, sizeof(*icmph) + sizeof(struct iphdr)))
+                       goto drop;
+
+               nh = skb_network_offset(skb);
+               skb_set_network_header(skb, sizeof(*icmph));
+
+               if (!xfrm4_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
+                       goto drop;
+
+               skb_set_network_header(skb, nh);
+       }
+
        ICMP_INC_STATS_BH(ICMP_MIB_INMSGS);
 
        switch (skb->ip_summed) {
@@ -942,8 +1015,7 @@ int icmp_rcv(struct sk_buff *skb)
                        goto error;
        }
 
-       if (!pskb_pull(skb, sizeof(struct icmphdr)))
-               goto error;
+       __skb_pull(skb, sizeof(*icmph));
 
        icmph = icmp_hdr(skb);
 
index 7dbc282d4f9f3eb86a363f19f0fa19f29f1ad97b..994648be80ab7e3e4a60abdb3e1a28e4aae290ca 100644 (file)
  */
 
 #define IGMP_V1_SEEN(in_dev) \
-       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \
+       (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, FORCE_IGMP_VERSION) == 1 || \
         IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \
         ((in_dev)->mr_v1_seen && \
          time_before(jiffies, (in_dev)->mr_v1_seen)))
 #define IGMP_V2_SEEN(in_dev) \
-       (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \
+       (IPV4_DEVCONF_ALL(in_dev->dev->nd_net, FORCE_IGMP_VERSION) == 2 || \
         IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \
         ((in_dev)->mr_v2_seen && \
          time_before(jiffies, (in_dev)->mr_v2_seen)))
@@ -301,7 +301,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
                                    .nl_u = { .ip4_u = {
                                    .daddr = IGMPV3_ALL_MCR } },
                                    .proto = IPPROTO_IGMP };
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        kfree_skb(skb);
                        return NULL;
                }
@@ -349,17 +349,12 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
 
 static int igmpv3_sendpack(struct sk_buff *skb)
 {
-       struct iphdr *pip = ip_hdr(skb);
        struct igmphdr *pig = igmp_hdr(skb);
-       const int iplen = skb->tail - skb->network_header;
        const int igmplen = skb->tail - skb->transport_header;
 
-       pip->tot_len = htons(iplen);
-       ip_send_check(pip);
        pig->csum = ip_compute_csum(igmp_hdr(skb), igmplen);
 
-       return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, skb->dev,
-                      dst_output);
+       return ip_local_out(skb);
 }
 
 static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel)
@@ -650,7 +645,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
                struct flowi fl = { .oif = dev->ifindex,
                                    .nl_u = { .ip4_u = { .daddr = dst } },
                                    .proto = IPPROTO_IGMP };
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(&init_net, &rt, &fl))
                        return -1;
        }
        if (rt->rt_src == 0) {
@@ -680,13 +675,11 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
        iph->daddr    = dst;
        iph->saddr    = rt->rt_src;
        iph->protocol = IPPROTO_IGMP;
-       iph->tot_len  = htons(IGMP_SIZE);
        ip_select_ident(iph, &rt->u.dst, NULL);
        ((u8*)&iph[1])[0] = IPOPT_RA;
        ((u8*)&iph[1])[1] = 4;
        ((u8*)&iph[1])[2] = 0;
        ((u8*)&iph[1])[3] = 0;
-       ip_send_check(iph);
 
        ih = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr));
        ih->type=type;
@@ -695,8 +688,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
        ih->group=group;
        ih->csum=ip_compute_csum((void *)ih, sizeof(struct igmphdr));
 
-       return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-                      dst_output);
+       return ip_local_out(skb);
 }
 
 static void igmp_gq_timer_expire(unsigned long data)
@@ -1234,9 +1226,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
        spin_lock_init(&im->lock);
 #ifdef CONFIG_IP_MULTICAST
        im->tm_running=0;
-       init_timer(&im->timer);
-       im->timer.data=(unsigned long)im;
-       im->timer.function=&igmp_timer_expire;
+       setup_timer(&im->timer, &igmp_timer_expire, (unsigned long)im);
        im->unsolicit_count = IGMP_Unsolicited_Report_Count;
        im->reporter = 0;
        im->gsquery = 0;
@@ -1338,13 +1328,11 @@ void ip_mc_init_dev(struct in_device *in_dev)
        in_dev->mc_tomb = NULL;
 #ifdef CONFIG_IP_MULTICAST
        in_dev->mr_gq_running = 0;
-       init_timer(&in_dev->mr_gq_timer);
-       in_dev->mr_gq_timer.data=(unsigned long) in_dev;
-       in_dev->mr_gq_timer.function=&igmp_gq_timer_expire;
+       setup_timer(&in_dev->mr_gq_timer, igmp_gq_timer_expire,
+                       (unsigned long)in_dev);
        in_dev->mr_ifc_count = 0;
-       init_timer(&in_dev->mr_ifc_timer);
-       in_dev->mr_ifc_timer.data=(unsigned long) in_dev;
-       in_dev->mr_ifc_timer.function=&igmp_ifc_timer_expire;
+       setup_timer(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire,
+                       (unsigned long)in_dev);
        in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
 #endif
 
@@ -1401,19 +1389,19 @@ static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr)
        struct in_device *idev = NULL;
 
        if (imr->imr_ifindex) {
-               idev = inetdev_by_index(imr->imr_ifindex);
+               idev = inetdev_by_index(&init_net, imr->imr_ifindex);
                if (idev)
                        __in_dev_put(idev);
                return idev;
        }
        if (imr->imr_address.s_addr) {
-               dev = ip_dev_find(imr->imr_address.s_addr);
+               dev = ip_dev_find(&init_net, imr->imr_address.s_addr);
                if (!dev)
                        return NULL;
                dev_put(dev);
        }
 
-       if (!dev && !ip_route_output_key(&rt, &fl)) {
+       if (!dev && !ip_route_output_key(&init_net, &rt, &fl)) {
                dev = rt->u.dst.dev;
                ip_rt_put(rt);
        }
@@ -1754,7 +1742,7 @@ int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr)
        int ifindex;
        int count = 0;
 
-       if (!MULTICAST(addr))
+       if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
        rtnl_lock();
@@ -1867,7 +1855,7 @@ int ip_mc_source(int add, int omode, struct sock *sk, struct
        int leavegroup = 0;
        int i, j, rv;
 
-       if (!MULTICAST(addr))
+       if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
        rtnl_lock();
@@ -1997,7 +1985,7 @@ int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf, int ifindex)
        struct ip_sf_socklist *newpsl, *psl;
        int leavegroup = 0;
 
-       if (!MULTICAST(addr))
+       if (!ipv4_is_multicast(addr))
                return -EINVAL;
        if (msf->imsf_fmode != MCAST_INCLUDE &&
            msf->imsf_fmode != MCAST_EXCLUDE)
@@ -2080,7 +2068,7 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
        struct inet_sock *inet = inet_sk(sk);
        struct ip_sf_socklist *psl;
 
-       if (!MULTICAST(addr))
+       if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
        rtnl_lock();
@@ -2142,7 +2130,7 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
        if (psin->sin_family != AF_INET)
                return -EINVAL;
        addr = psin->sin_addr.s_addr;
-       if (!MULTICAST(addr))
+       if (!ipv4_is_multicast(addr))
                return -EINVAL;
 
        rtnl_lock();
@@ -2192,7 +2180,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
        struct ip_sf_socklist *psl;
        int i;
 
-       if (!MULTICAST(loc_addr))
+       if (!ipv4_is_multicast(loc_addr))
                return 1;
 
        for (pmc=inet->mc_list; pmc; pmc=pmc->next) {
@@ -2234,7 +2222,7 @@ void ip_mc_drop_socket(struct sock *sk)
                struct in_device *in_dev;
                inet->mc_list = iml->next;
 
-               in_dev = inetdev_by_index(iml->multi.imr_ifindex);
+               in_dev = inetdev_by_index(&init_net, iml->multi.imr_ifindex);
                (void) ip_mc_leave_src(sk, iml, in_dev);
                if (in_dev != NULL) {
                        ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);
@@ -2341,6 +2329,7 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
        read_lock(&dev_base_lock);
        return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -2358,6 +2347,7 @@ static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp_mc_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq);
        if (likely(state->in_dev != NULL)) {
index 8fb6ca23700aa8de4c446879b19186e626dfa396..7801cceb2d1b7844e11227322490dd14af5722df 100644 (file)
@@ -277,18 +277,11 @@ void inet_csk_init_xmit_timers(struct sock *sk,
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
 
-       init_timer(&icsk->icsk_retransmit_timer);
-       init_timer(&icsk->icsk_delack_timer);
-       init_timer(&sk->sk_timer);
-
-       icsk->icsk_retransmit_timer.function = retransmit_handler;
-       icsk->icsk_delack_timer.function     = delack_handler;
-       sk->sk_timer.function                = keepalive_handler;
-
-       icsk->icsk_retransmit_timer.data =
-               icsk->icsk_delack_timer.data =
-                       sk->sk_timer.data  = (unsigned long)sk;
-
+       setup_timer(&icsk->icsk_retransmit_timer, retransmit_handler,
+                       (unsigned long)sk);
+       setup_timer(&icsk->icsk_delack_timer, delack_handler,
+                       (unsigned long)sk);
+       setup_timer(&sk->sk_timer, keepalive_handler, (unsigned long)sk);
        icsk->icsk_pending = icsk->icsk_ack.pending = 0;
 }
 
@@ -340,7 +333,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
                                         .dport = ireq->rmt_port } } };
 
        security_req_classify_flow(req, &fl);
-       if (ip_route_output_flow(&rt, &fl, sk, 0)) {
+       if (ip_route_output_flow(&init_net, &rt, &fl, sk, 0)) {
                IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
                return NULL;
        }
index e468e7a7aac4d8c7940955eac466af2e6303858f..605ed2cd79724b461e933ed4e00ca694f0797bf9 100644 (file)
@@ -935,7 +935,7 @@ out_free_table:
 
 static void __exit inet_diag_exit(void)
 {
-       sock_release(idiagnl->sk_socket);
+       netlink_kernel_release(idiagnl);
        kfree(inet_diag_table);
 }
 
index e15e04fc66615dc354241214fdadaa366512264f..724d69aed031974234501ff024852b7a55ea1810 100644 (file)
@@ -47,7 +47,7 @@ static void inet_frag_secret_rebuild(unsigned long dummy)
        }
        write_unlock(&f->lock);
 
-       mod_timer(&f->secret_timer, now + f->ctl->secret_interval);
+       mod_timer(&f->secret_timer, now + f->secret_interval);
 }
 
 void inet_frags_init(struct inet_frags *f)
@@ -57,35 +57,45 @@ void inet_frags_init(struct inet_frags *f)
        for (i = 0; i < INETFRAGS_HASHSZ; i++)
                INIT_HLIST_HEAD(&f->hash[i]);
 
-       INIT_LIST_HEAD(&f->lru_list);
        rwlock_init(&f->lock);
 
        f->rnd = (u32) ((num_physpages ^ (num_physpages>>7)) ^
                                   (jiffies ^ (jiffies >> 6)));
 
-       f->nqueues = 0;
-       atomic_set(&f->mem, 0);
-
-       init_timer(&f->secret_timer);
-       f->secret_timer.function = inet_frag_secret_rebuild;
-       f->secret_timer.data = (unsigned long)f;
-       f->secret_timer.expires = jiffies + f->ctl->secret_interval;
+       setup_timer(&f->secret_timer, inet_frag_secret_rebuild,
+                       (unsigned long)f);
+       f->secret_timer.expires = jiffies + f->secret_interval;
        add_timer(&f->secret_timer);
 }
 EXPORT_SYMBOL(inet_frags_init);
 
+void inet_frags_init_net(struct netns_frags *nf)
+{
+       nf->nqueues = 0;
+       atomic_set(&nf->mem, 0);
+       INIT_LIST_HEAD(&nf->lru_list);
+}
+EXPORT_SYMBOL(inet_frags_init_net);
+
 void inet_frags_fini(struct inet_frags *f)
 {
        del_timer(&f->secret_timer);
 }
 EXPORT_SYMBOL(inet_frags_fini);
 
+void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
+{
+       nf->low_thresh = 0;
+       inet_frag_evictor(nf, f);
+}
+EXPORT_SYMBOL(inet_frags_exit_net);
+
 static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
 {
        write_lock(&f->lock);
        hlist_del(&fq->list);
        list_del(&fq->lru_list);
-       f->nqueues--;
+       fq->net->nqueues--;
        write_unlock(&f->lock);
 }
 
@@ -103,13 +113,13 @@ void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f)
 
 EXPORT_SYMBOL(inet_frag_kill);
 
-static inline void frag_kfree_skb(struct inet_frags *f, struct sk_buff *skb,
-                                               int *work)
+static inline void frag_kfree_skb(struct netns_frags *nf, struct inet_frags *f,
+               struct sk_buff *skb, int *work)
 {
        if (work)
                *work -= skb->truesize;
 
-       atomic_sub(skb->truesize, &f->mem);
+       atomic_sub(skb->truesize, &nf->mem);
        if (f->skb_free)
                f->skb_free(skb);
        kfree_skb(skb);
@@ -119,22 +129,24 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
                                        int *work)
 {
        struct sk_buff *fp;
+       struct netns_frags *nf;
 
        BUG_TRAP(q->last_in & COMPLETE);
        BUG_TRAP(del_timer(&q->timer) == 0);
 
        /* Release all fragment data. */
        fp = q->fragments;
+       nf = q->net;
        while (fp) {
                struct sk_buff *xp = fp->next;
 
-               frag_kfree_skb(f, fp, work);
+               frag_kfree_skb(nf, f, fp, work);
                fp = xp;
        }
 
        if (work)
                *work -= f->qsize;
-       atomic_sub(f->qsize, &f->mem);
+       atomic_sub(f->qsize, &nf->mem);
 
        if (f->destructor)
                f->destructor(q);
@@ -143,20 +155,20 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
 }
 EXPORT_SYMBOL(inet_frag_destroy);
 
-int inet_frag_evictor(struct inet_frags *f)
+int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
 {
        struct inet_frag_queue *q;
        int work, evicted = 0;
 
-       work = atomic_read(&f->mem) - f->ctl->low_thresh;
+       work = atomic_read(&nf->mem) - nf->low_thresh;
        while (work > 0) {
                read_lock(&f->lock);
-               if (list_empty(&f->lru_list)) {
+               if (list_empty(&nf->lru_list)) {
                        read_unlock(&f->lock);
                        break;
                }
 
-               q = list_first_entry(&f->lru_list,
+               q = list_first_entry(&nf->lru_list,
                                struct inet_frag_queue, lru_list);
                atomic_inc(&q->refcnt);
                read_unlock(&f->lock);
@@ -175,8 +187,9 @@ int inet_frag_evictor(struct inet_frags *f)
 }
 EXPORT_SYMBOL(inet_frag_evictor);
 
-static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
-               struct inet_frags *f, unsigned int hash, void *arg)
+static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
+               struct inet_frag_queue *qp_in, struct inet_frags *f,
+               unsigned int hash, void *arg)
 {
        struct inet_frag_queue *qp;
 #ifdef CONFIG_SMP
@@ -190,7 +203,7 @@ static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
         * promoted read lock to write lock.
         */
        hlist_for_each_entry(qp, n, &f->hash[hash], list) {
-               if (f->match(qp, arg)) {
+               if (qp->net == nf && f->match(qp, arg)) {
                        atomic_inc(&qp->refcnt);
                        write_unlock(&f->lock);
                        qp_in->last_in |= COMPLETE;
@@ -200,18 +213,19 @@ static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
        }
 #endif
        qp = qp_in;
-       if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout))
+       if (!mod_timer(&qp->timer, jiffies + nf->timeout))
                atomic_inc(&qp->refcnt);
 
        atomic_inc(&qp->refcnt);
        hlist_add_head(&qp->list, &f->hash[hash]);
-       list_add_tail(&qp->lru_list, &f->lru_list);
-       f->nqueues++;
+       list_add_tail(&qp->lru_list, &nf->lru_list);
+       nf->nqueues++;
        write_unlock(&f->lock);
        return qp;
 }
 
-static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
+static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
+               struct inet_frags *f, void *arg)
 {
        struct inet_frag_queue *q;
 
@@ -220,35 +234,36 @@ static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
                return NULL;
 
        f->constructor(q, arg);
-       atomic_add(f->qsize, &f->mem);
+       atomic_add(f->qsize, &nf->mem);
        setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
        spin_lock_init(&q->lock);
        atomic_set(&q->refcnt, 1);
+       q->net = nf;
 
        return q;
 }
 
-static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
-               void *arg, unsigned int hash)
+static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
+               struct inet_frags *f, void *arg, unsigned int hash)
 {
        struct inet_frag_queue *q;
 
-       q = inet_frag_alloc(f, arg);
+       q = inet_frag_alloc(nf, f, arg);
        if (q == NULL)
                return NULL;
 
-       return inet_frag_intern(q, f, hash, arg);
+       return inet_frag_intern(nf, q, f, hash, arg);
 }
 
-struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
-               unsigned int hash)
+struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
+               struct inet_frags *f, void *key, unsigned int hash)
 {
        struct inet_frag_queue *q;
        struct hlist_node *n;
 
        read_lock(&f->lock);
        hlist_for_each_entry(q, n, &f->hash[hash], list) {
-               if (f->match(q, key)) {
+               if (q->net == nf && f->match(q, key)) {
                        atomic_inc(&q->refcnt);
                        read_unlock(&f->lock);
                        return q;
@@ -256,6 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
        }
        read_unlock(&f->lock);
 
-       return inet_frag_create(f, key, hash);
+       return inet_frag_create(nf, f, key, hash);
 }
 EXPORT_SYMBOL(inet_frag_find);
index 67704da04fc4ca98d88eeaae7db3e53d1a6157aa..619c63c6948aa1cac403c3a7e94a5dc550acba1b 100644 (file)
@@ -96,6 +96,7 @@ EXPORT_SYMBOL(inet_put_port);
  * exclusive lock release). It should be ifdefed really.
  */
 void inet_listen_wlock(struct inet_hashinfo *hashinfo)
+       __acquires(hashinfo->lhash_lock)
 {
        write_lock(&hashinfo->lhash_lock);
 
@@ -190,6 +191,44 @@ sherry_cache:
 }
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
 
+struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo,
+                                 const __be32 saddr, const __be16 sport,
+                                 const __be32 daddr, const u16 hnum,
+                                 const int dif)
+{
+       INET_ADDR_COOKIE(acookie, saddr, daddr)
+       const __portpair ports = INET_COMBINED_PORTS(sport, hnum);
+       struct sock *sk;
+       const struct hlist_node *node;
+       /* Optimize here for direct hit, only listening connections can
+        * have wildcards anyways.
+        */
+       unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport);
+       struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
+       rwlock_t *lock = inet_ehash_lockp(hashinfo, hash);
+
+       prefetch(head->chain.first);
+       read_lock(lock);
+       sk_for_each(sk, node, &head->chain) {
+               if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+                       goto hit; /* You sunk my battleship! */
+       }
+
+       /* Must check for a TIME_WAIT'er before going to listener hash. */
+       sk_for_each(sk, node, &head->twchain) {
+               if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif))
+                       goto hit;
+       }
+       sk = NULL;
+out:
+       read_unlock(lock);
+       return sk;
+hit:
+       sock_hold(sk);
+       goto out;
+}
+EXPORT_SYMBOL_GPL(__inet_lookup_established);
+
 /* called with local bh disabled */
 static int __inet_check_established(struct inet_timewait_death_row *death_row,
                                    struct sock *sk, __u16 lport,
@@ -239,7 +278,7 @@ unique:
        sk->sk_hash = hash;
        BUG_TRAP(sk_unhashed(sk));
        __sk_add_node(sk, &head->chain);
-       sock_prot_inc_use(sk->sk_prot);
+       sock_prot_inuse_add(sk->sk_prot, 1);
        write_unlock(lock);
 
        if (twp) {
@@ -267,6 +306,48 @@ static inline u32 inet_sk_port_offset(const struct sock *sk)
                                          inet->dport);
 }
 
+void __inet_hash_nolisten(struct inet_hashinfo *hashinfo, struct sock *sk)
+{
+       struct hlist_head *list;
+       rwlock_t *lock;
+       struct inet_ehash_bucket *head;
+
+       BUG_TRAP(sk_unhashed(sk));
+
+       sk->sk_hash = inet_sk_ehashfn(sk);
+       head = inet_ehash_bucket(hashinfo, sk->sk_hash);
+       list = &head->chain;
+       lock = inet_ehash_lockp(hashinfo, sk->sk_hash);
+
+       write_lock(lock);
+       __sk_add_node(sk, list);
+       sock_prot_inuse_add(sk->sk_prot, 1);
+       write_unlock(lock);
+}
+EXPORT_SYMBOL_GPL(__inet_hash_nolisten);
+
+void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk)
+{
+       struct hlist_head *list;
+       rwlock_t *lock;
+
+       if (sk->sk_state != TCP_LISTEN) {
+               __inet_hash_nolisten(hashinfo, sk);
+               return;
+       }
+
+       BUG_TRAP(sk_unhashed(sk));
+       list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+       lock = &hashinfo->lhash_lock;
+
+       inet_listen_wlock(hashinfo);
+       __sk_add_node(sk, list);
+       sock_prot_inuse_add(sk->sk_prot, 1);
+       write_unlock(lock);
+       wake_up(&hashinfo->lhash_wait);
+}
+EXPORT_SYMBOL_GPL(__inet_hash);
+
 /*
  * Bind a port for a connect operation and hash it.
  */
@@ -334,7 +415,7 @@ ok:
                inet_bind_hash(sk, tb, port);
                if (sk_unhashed(sk)) {
                        inet_sk(sk)->sport = htons(port);
-                       __inet_hash(hinfo, sk, 0);
+                       __inet_hash_nolisten(hinfo, sk);
                }
                spin_unlock(&head->lock);
 
@@ -351,7 +432,7 @@ ok:
        tb  = inet_csk(sk)->icsk_bind_hash;
        spin_lock_bh(&head->lock);
        if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-               __inet_hash(hinfo, sk, 0);
+               __inet_hash_nolisten(hinfo, sk);
                spin_unlock_bh(&head->lock);
                return 0;
        } else {
index a60b99e0ebdc2d1dfa838a1134e361139ceeb910..876169f3a5286db53d6371763549941a578cb445 100644 (file)
@@ -48,6 +48,21 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
        inet_twsk_put(tw);
 }
 
+void inet_twsk_put(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);
+#ifdef SOCK_REFCNT_DEBUG
+               printk(KERN_DEBUG "%s timewait_sock %p released\n",
+                      tw->tw_prot->name, tw);
+#endif
+               kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
+               module_put(owner);
+       }
+}
+EXPORT_SYMBOL_GPL(inet_twsk_put);
+
 /*
  * Enter the time wait state. This is called with locally disabled BH.
  * Essentially we whip up a timewait bucket, copy the relevant info into it
@@ -76,7 +91,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk,
 
        /* Step 2: Remove SK from established hash. */
        if (__sk_del_node_init(sk))
-               sock_prot_dec_use(sk->sk_prot);
+               sock_prot_inuse_add(sk->sk_prot, -1);
 
        /* Step 3: Hash TW into TIMEWAIT chain. */
        inet_twsk_add_node(tw, &ehead->twchain);
@@ -194,16 +209,14 @@ out:
 
 EXPORT_SYMBOL_GPL(inet_twdr_hangman);
 
-extern void twkill_slots_invalid(void);
-
 void inet_twdr_twkill_work(struct work_struct *work)
 {
        struct inet_timewait_death_row *twdr =
                container_of(work, struct inet_timewait_death_row, twkill_work);
        int i;
 
-       if ((INET_TWDR_TWKILL_SLOTS - 1) > (sizeof(twdr->thread_slots) * 8))
-               twkill_slots_invalid();
+       BUILD_BUG_ON((INET_TWDR_TWKILL_SLOTS - 1) >
+                       (sizeof(twdr->thread_slots) * 8));
 
        while (twdr->thread_slots) {
                spin_lock_bh(&twdr->death_lock);
index 877da3ed52e2bef524d12cc88f2d23aa33b69502..0b3b328d82db608519ce2fbb57050b1f944da959 100644 (file)
@@ -110,7 +110,7 @@ int ip_forward(struct sk_buff *skb)
 
        skb->priority = rt_tos2priority(iph->tos);
 
-       return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
+       return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev,
                       ip_forward_finish);
 
 sr_failed:
index 2143bf30597a84b528e0cced57bc657dbe577417..a2e92f9709db8459bd573e82c6842b6d9ea1d715 100644 (file)
@@ -50,7 +50,7 @@
  * as well. Or notify me, at least. --ANK
  */
 
-int sysctl_ipfrag_max_dist __read_mostly = 64;
+static int sysctl_ipfrag_max_dist __read_mostly = 64;
 
 struct ipfrag_skb_cb
 {
@@ -74,35 +74,16 @@ struct ipq {
        struct inet_peer *peer;
 };
 
-struct inet_frags_ctl ip4_frags_ctl __read_mostly = {
-       /*
-        * Fragment cache limits. We will commit 256K at one time. Should we
-        * cross that limit we will prune down to 192K. This should cope with
-        * even the most extreme cases without allowing an attacker to
-        * measurably harm machine performance.
-        */
-       .high_thresh     = 256 * 1024,
-       .low_thresh      = 192 * 1024,
-
-       /*
-        * Important NOTE! Fragment queue must be destroyed before MSL expires.
-        * RFC791 is wrong proposing to prolongate timer each fragment arrival
-        * by TTL.
-        */
-       .timeout         = IP_FRAG_TIME,
-       .secret_interval = 10 * 60 * HZ,
-};
-
 static struct inet_frags ip4_frags;
 
-int ip_frag_nqueues(void)
+int ip_frag_nqueues(struct net *net)
 {
-       return ip4_frags.nqueues;
+       return net->ipv4.frags.nqueues;
 }
 
-int ip_frag_mem(void)
+int ip_frag_mem(struct net *net)
 {
-       return atomic_read(&ip4_frags.mem);
+       return atomic_read(&net->ipv4.frags.mem);
 }
 
 static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
@@ -142,11 +123,12 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a)
 }
 
 /* Memory Tracking Functions. */
-static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work)
+static __inline__ void frag_kfree_skb(struct netns_frags *nf,
+               struct sk_buff *skb, int *work)
 {
        if (work)
                *work -= skb->truesize;
-       atomic_sub(skb->truesize, &ip4_frags.mem);
+       atomic_sub(skb->truesize, &nf->mem);
        kfree_skb(skb);
 }
 
@@ -192,11 +174,11 @@ static void ipq_kill(struct ipq *ipq)
 /* Memory limiting on fragments.  Evictor trashes the oldest
  * fragment queue until we are back under the threshold.
  */
-static void ip_evictor(void)
+static void ip_evictor(struct net *net)
 {
        int evicted;
 
-       evicted = inet_frag_evictor(&ip4_frags);
+       evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
        if (evicted)
                IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted);
 }
@@ -236,7 +218,7 @@ out:
 /* Find the correct entry in the "incomplete datagrams" queue for
  * this IP datagram, and create new one, if nothing is found.
  */
-static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
+static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
 {
        struct inet_frag_queue *q;
        struct ip4_create_arg arg;
@@ -246,7 +228,7 @@ static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
        arg.user = user;
        hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
 
-       q = inet_frag_find(&ip4_frags, &arg, hash);
+       q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
        if (q == NULL)
                goto out_nomem;
 
@@ -286,7 +268,7 @@ static int ip_frag_reinit(struct ipq *qp)
 {
        struct sk_buff *fp;
 
-       if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) {
+       if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
                atomic_inc(&qp->q.refcnt);
                return -ETIMEDOUT;
        }
@@ -294,7 +276,7 @@ static int ip_frag_reinit(struct ipq *qp)
        fp = qp->q.fragments;
        do {
                struct sk_buff *xp = fp->next;
-               frag_kfree_skb(fp, NULL);
+               frag_kfree_skb(qp->q.net, fp, NULL);
                fp = xp;
        } while (fp);
 
@@ -431,7 +413,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
                                qp->q.fragments = next;
 
                        qp->q.meat -= free_it->len;
-                       frag_kfree_skb(free_it, NULL);
+                       frag_kfree_skb(qp->q.net, free_it, NULL);
                }
        }
 
@@ -451,7 +433,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
        }
        qp->q.stamp = skb->tstamp;
        qp->q.meat += skb->len;
-       atomic_add(skb->truesize, &ip4_frags.mem);
+       atomic_add(skb->truesize, &qp->q.net->mem);
        if (offset == 0)
                qp->q.last_in |= FIRST_IN;
 
@@ -459,7 +441,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
                return ip_frag_reasm(qp, prev, dev);
 
        write_lock(&ip4_frags.lock);
-       list_move_tail(&qp->q.lru_list, &ip4_frags.lru_list);
+       list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list);
        write_unlock(&ip4_frags.lock);
        return -EINPROGRESS;
 
@@ -534,12 +516,12 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                head->len -= clone->len;
                clone->csum = 0;
                clone->ip_summed = head->ip_summed;
-               atomic_add(clone->truesize, &ip4_frags.mem);
+               atomic_add(clone->truesize, &qp->q.net->mem);
        }
 
        skb_shinfo(head)->frag_list = head->next;
        skb_push(head, head->data - skb_network_header(head));
-       atomic_sub(head->truesize, &ip4_frags.mem);
+       atomic_sub(head->truesize, &qp->q.net->mem);
 
        for (fp=head->next; fp; fp = fp->next) {
                head->data_len += fp->len;
@@ -549,7 +531,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                else if (head->ip_summed == CHECKSUM_COMPLETE)
                        head->csum = csum_add(head->csum, fp->csum);
                head->truesize += fp->truesize;
-               atomic_sub(fp->truesize, &ip4_frags.mem);
+               atomic_sub(fp->truesize, &qp->q.net->mem);
        }
 
        head->next = NULL;
@@ -582,15 +564,17 @@ out_fail:
 int ip_defrag(struct sk_buff *skb, u32 user)
 {
        struct ipq *qp;
+       struct net *net;
 
        IP_INC_STATS_BH(IPSTATS_MIB_REASMREQDS);
 
+       net = skb->dev->nd_net;
        /* Start by cleaning up the memory. */
-       if (atomic_read(&ip4_frags.mem) > ip4_frags_ctl.high_thresh)
-               ip_evictor();
+       if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
+               ip_evictor(net);
 
        /* Lookup (or create) queue header */
-       if ((qp = ip_find(ip_hdr(skb), user)) != NULL) {
+       if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
                int ret;
 
                spin_lock(&qp->q.lock);
@@ -607,9 +591,142 @@ int ip_defrag(struct sk_buff *skb, u32 user)
        return -ENOMEM;
 }
 
+#ifdef CONFIG_SYSCTL
+static int zero;
+
+static struct ctl_table ip4_frags_ctl_table[] = {
+       {
+               .ctl_name       = NET_IPV4_IPFRAG_HIGH_THRESH,
+               .procname       = "ipfrag_high_thresh",
+               .data           = &init_net.ipv4.frags.high_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = NET_IPV4_IPFRAG_LOW_THRESH,
+               .procname       = "ipfrag_low_thresh",
+               .data           = &init_net.ipv4.frags.low_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = NET_IPV4_IPFRAG_TIME,
+               .procname       = "ipfrag_time",
+               .data           = &init_net.ipv4.frags.timeout,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_jiffies,
+               .strategy       = &sysctl_jiffies
+       },
+       {
+               .ctl_name       = NET_IPV4_IPFRAG_SECRET_INTERVAL,
+               .procname       = "ipfrag_secret_interval",
+               .data           = &ip4_frags.secret_interval,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_jiffies,
+               .strategy       = &sysctl_jiffies
+       },
+       {
+               .procname       = "ipfrag_max_dist",
+               .data           = &sysctl_ipfrag_max_dist,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .extra1         = &zero
+       },
+       { }
+};
+
+static int ip4_frags_ctl_register(struct net *net)
+{
+       struct ctl_table *table;
+       struct ctl_table_header *hdr;
+
+       table = ip4_frags_ctl_table;
+       if (net != &init_net) {
+               table = kmemdup(table, sizeof(ip4_frags_ctl_table), GFP_KERNEL);
+               if (table == NULL)
+                       goto err_alloc;
+
+               table[0].data = &net->ipv4.frags.high_thresh;
+               table[1].data = &net->ipv4.frags.low_thresh;
+               table[2].data = &net->ipv4.frags.timeout;
+               table[3].mode &= ~0222;
+               table[4].mode &= ~0222;
+       }
+
+       hdr = register_net_sysctl_table(net, net_ipv4_ctl_path, table);
+       if (hdr == NULL)
+               goto err_reg;
+
+       net->ipv4.frags_hdr = hdr;
+       return 0;
+
+err_reg:
+       if (net != &init_net)
+               kfree(table);
+err_alloc:
+       return -ENOMEM;
+}
+
+static void ip4_frags_ctl_unregister(struct net *net)
+{
+       struct ctl_table *table;
+
+       table = net->ipv4.frags_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv4.frags_hdr);
+       kfree(table);
+}
+#else
+static inline int ip4_frags_ctl_register(struct net *net)
+{
+       return 0;
+}
+
+static inline void ip4_frags_ctl_unregister(struct net *net)
+{
+}
+#endif
+
+static int ipv4_frags_init_net(struct net *net)
+{
+       /*
+        * Fragment cache limits. We will commit 256K at one time. Should we
+        * cross that limit we will prune down to 192K. This should cope with
+        * even the most extreme cases without allowing an attacker to
+        * measurably harm machine performance.
+        */
+       net->ipv4.frags.high_thresh = 256 * 1024;
+       net->ipv4.frags.low_thresh = 192 * 1024;
+       /*
+        * Important NOTE! Fragment queue must be destroyed before MSL expires.
+        * RFC791 is wrong proposing to prolongate timer each fragment arrival
+        * by TTL.
+        */
+       net->ipv4.frags.timeout = IP_FRAG_TIME;
+
+       inet_frags_init_net(&net->ipv4.frags);
+
+       return ip4_frags_ctl_register(net);
+}
+
+static void ipv4_frags_exit_net(struct net *net)
+{
+       ip4_frags_ctl_unregister(net);
+       inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
+}
+
+static struct pernet_operations ip4_frags_ops = {
+       .init = ipv4_frags_init_net,
+       .exit = ipv4_frags_exit_net,
+};
+
 void __init ipfrag_init(void)
 {
-       ip4_frags.ctl = &ip4_frags_ctl;
+       register_pernet_subsys(&ip4_frags_ops);
        ip4_frags.hashfn = ip4_hashfn;
        ip4_frags.constructor = ip4_frag_init;
        ip4_frags.destructor = ip4_frag_free;
@@ -617,6 +734,7 @@ void __init ipfrag_init(void)
        ip4_frags.qsize = sizeof(struct ipq);
        ip4_frags.match = ip4_frag_match;
        ip4_frags.frag_expire = ip_expire;
+       ip4_frags.secret_interval = 10 * 60 * HZ;
        inet_frags_init(&ip4_frags);
 }
 
index 4b93f32de10dc5213232a936d064b4fdefd49f06..63f691719353dbc98eb34211b86d9492b8d58190 100644 (file)
@@ -176,7 +176,8 @@ static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be3
        }
        for (t = tunnels_l[h1]; t; t = t->next) {
                if (local == t->parms.iph.saddr ||
-                    (local == t->parms.iph.daddr && MULTICAST(local))) {
+                    (local == t->parms.iph.daddr &&
+                     ipv4_is_multicast(local))) {
                        if (t->parms.i_key == key && (t->dev->flags&IFF_UP))
                                return t;
                }
@@ -201,7 +202,7 @@ static struct ip_tunnel **__ipgre_bucket(struct ip_tunnel_parm *parms)
 
        if (local)
                prio |= 1;
-       if (remote && !MULTICAST(remote)) {
+       if (remote && !ipv4_is_multicast(remote)) {
                prio |= 2;
                h ^= HASH(remote);
        }
@@ -367,7 +368,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
 
        read_lock(&ipgre_lock);
        t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0);
-       if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr))
+       if (t == NULL || t->parms.iph.daddr == 0 ||
+           ipv4_is_multicast(t->parms.iph.daddr))
                goto out;
 
        if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
@@ -478,7 +480,7 @@ out:
        fl.fl4_dst = eiph->saddr;
        fl.fl4_tos = RT_TOS(eiph->tos);
        fl.proto = IPPROTO_GRE;
-       if (ip_route_output_key(&rt, &fl)) {
+       if (ip_route_output_key(&init_net, &rt, &fl)) {
                kfree_skb(skb2);
                return;
        }
@@ -491,7 +493,7 @@ out:
                fl.fl4_dst = eiph->daddr;
                fl.fl4_src = eiph->saddr;
                fl.fl4_tos = eiph->tos;
-               if (ip_route_output_key(&rt, &fl) ||
+               if (ip_route_output_key(&init_net, &rt, &fl) ||
                    rt->u.dst.dev->type != ARPHRD_IPGRE) {
                        ip_rt_put(rt);
                        kfree_skb(skb2);
@@ -619,7 +621,7 @@ static int ipgre_rcv(struct sk_buff *skb)
                skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
                skb->pkt_type = PACKET_HOST;
 #ifdef CONFIG_NET_IPGRE_BROADCAST
-               if (MULTICAST(iph->daddr)) {
+               if (ipv4_is_multicast(iph->daddr)) {
                        /* Looped back packet, drop it! */
                        if (((struct rtable*)skb->dst)->fl.iif == 0)
                                goto drop;
@@ -746,7 +748,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                                                .saddr = tiph->saddr,
                                                .tos = RT_TOS(tos) } },
                                    .proto = IPPROTO_GRE };
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        tunnel->stat.tx_carrier_errors++;
                        goto tx_error;
                }
@@ -783,7 +785,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
 
                if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
-                       if ((tunnel->parms.iph.daddr && !MULTICAST(tunnel->parms.iph.daddr)) ||
+                       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;
@@ -896,6 +899,59 @@ tx_error:
        return 0;
 }
 
+static void ipgre_tunnel_bind_dev(struct net_device *dev)
+{
+       struct net_device *tdev = NULL;
+       struct ip_tunnel *tunnel;
+       struct iphdr *iph;
+       int hlen = LL_MAX_HEADER;
+       int mtu = ETH_DATA_LEN;
+       int addend = sizeof(struct iphdr) + 4;
+
+       tunnel = netdev_priv(dev);
+       iph = &tunnel->parms.iph;
+
+       /* Guess output device to choose reasonable mtu and hard_header_len */
+
+       if (iph->daddr) {
+               struct flowi fl = { .oif = tunnel->parms.link,
+                                   .nl_u = { .ip4_u =
+                                             { .daddr = iph->daddr,
+                                               .saddr = iph->saddr,
+                                               .tos = RT_TOS(iph->tos) } },
+                                   .proto = IPPROTO_GRE };
+               struct rtable *rt;
+               if (!ip_route_output_key(&init_net, &rt, &fl)) {
+                       tdev = rt->u.dst.dev;
+                       ip_rt_put(rt);
+               }
+               dev->flags |= IFF_POINTOPOINT;
+       }
+
+       if (!tdev && tunnel->parms.link)
+               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+       if (tdev) {
+               hlen = tdev->hard_header_len;
+               mtu = tdev->mtu;
+       }
+       dev->iflink = tunnel->parms.link;
+
+       /* Precalculate GRE options length */
+       if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
+               if (tunnel->parms.o_flags&GRE_CSUM)
+                       addend += 4;
+               if (tunnel->parms.o_flags&GRE_KEY)
+                       addend += 4;
+               if (tunnel->parms.o_flags&GRE_SEQ)
+                       addend += 4;
+       }
+       dev->hard_header_len = hlen + addend;
+       dev->mtu = mtu - addend;
+       tunnel->hlen = addend;
+
+}
+
 static int
 ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -956,7 +1012,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 
                                t = netdev_priv(dev);
 
-                               if (MULTICAST(p.iph.daddr))
+                               if (ipv4_is_multicast(p.iph.daddr))
                                        nflags = IFF_BROADCAST;
                                else if (p.iph.daddr)
                                        nflags = IFF_POINTOPOINT;
@@ -983,6 +1039,11 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
                                t->parms.iph.frag_off = p.iph.frag_off;
+                               if (t->parms.link != p.link) {
+                                       t->parms.link = p.link;
+                                       ipgre_tunnel_bind_dev(dev);
+                                       netdev_state_change(dev);
+                               }
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
@@ -1085,7 +1146,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
                memcpy(&iph->daddr, daddr, 4);
                return t->hlen;
        }
-       if (iph->daddr && !MULTICAST(iph->daddr))
+       if (iph->daddr && !ipv4_is_multicast(iph->daddr))
                return t->hlen;
 
        return -t->hlen;
@@ -1108,7 +1169,7 @@ static int ipgre_open(struct net_device *dev)
 {
        struct ip_tunnel *t = netdev_priv(dev);
 
-       if (MULTICAST(t->parms.iph.daddr)) {
+       if (ipv4_is_multicast(t->parms.iph.daddr)) {
                struct flowi fl = { .oif = t->parms.link,
                                    .nl_u = { .ip4_u =
                                              { .daddr = t->parms.iph.daddr,
@@ -1116,7 +1177,7 @@ static int ipgre_open(struct net_device *dev)
                                                .tos = RT_TOS(t->parms.iph.tos) } },
                                    .proto = IPPROTO_GRE };
                struct rtable *rt;
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(&init_net, &rt, &fl))
                        return -EADDRNOTAVAIL;
                dev = rt->u.dst.dev;
                ip_rt_put(rt);
@@ -1131,8 +1192,9 @@ static int ipgre_open(struct net_device *dev)
 static int ipgre_close(struct net_device *dev)
 {
        struct ip_tunnel *t = netdev_priv(dev);
-       if (MULTICAST(t->parms.iph.daddr) && t->mlink) {
-               struct in_device *in_dev = inetdev_by_index(t->mlink);
+       if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
+               struct in_device *in_dev;
+               in_dev = inetdev_by_index(dev->nd_net, t->mlink);
                if (in_dev) {
                        ip_mc_dec_group(in_dev, t->parms.iph.daddr);
                        in_dev_put(in_dev);
@@ -1162,12 +1224,8 @@ static void ipgre_tunnel_setup(struct net_device *dev)
 
 static int ipgre_tunnel_init(struct net_device *dev)
 {
-       struct net_device *tdev = NULL;
        struct ip_tunnel *tunnel;
        struct iphdr *iph;
-       int hlen = LL_MAX_HEADER;
-       int mtu = ETH_DATA_LEN;
-       int addend = sizeof(struct iphdr) + 4;
 
        tunnel = netdev_priv(dev);
        iph = &tunnel->parms.iph;
@@ -1178,25 +1236,11 @@ static int ipgre_tunnel_init(struct net_device *dev)
        memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
        memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-       /* Guess output device to choose reasonable mtu and hard_header_len */
+       ipgre_tunnel_bind_dev(dev);
 
        if (iph->daddr) {
-               struct flowi fl = { .oif = tunnel->parms.link,
-                                   .nl_u = { .ip4_u =
-                                             { .daddr = iph->daddr,
-                                               .saddr = iph->saddr,
-                                               .tos = RT_TOS(iph->tos) } },
-                                   .proto = IPPROTO_GRE };
-               struct rtable *rt;
-               if (!ip_route_output_key(&rt, &fl)) {
-                       tdev = rt->u.dst.dev;
-                       ip_rt_put(rt);
-               }
-
-               dev->flags |= IFF_POINTOPOINT;
-
 #ifdef CONFIG_NET_IPGRE_BROADCAST
-               if (MULTICAST(iph->daddr)) {
+               if (ipv4_is_multicast(iph->daddr)) {
                        if (!iph->saddr)
                                return -EINVAL;
                        dev->flags = IFF_BROADCAST;
@@ -1205,31 +1249,9 @@ static int ipgre_tunnel_init(struct net_device *dev)
                        dev->stop = ipgre_close;
                }
 #endif
-       } else {
+       } else
                dev->header_ops = &ipgre_header_ops;
-       }
-
-       if (!tdev && tunnel->parms.link)
-               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
-
-       if (tdev) {
-               hlen = tdev->hard_header_len;
-               mtu = tdev->mtu;
-       }
-       dev->iflink = tunnel->parms.link;
 
-       /* Precalculate GRE options length */
-       if (tunnel->parms.o_flags&(GRE_CSUM|GRE_KEY|GRE_SEQ)) {
-               if (tunnel->parms.o_flags&GRE_CSUM)
-                       addend += 4;
-               if (tunnel->parms.o_flags&GRE_KEY)
-                       addend += 4;
-               if (tunnel->parms.o_flags&GRE_SEQ)
-                       addend += 4;
-       }
-       dev->hard_header_len = hlen + addend;
-       dev->mtu = mtu - addend;
-       tunnel->hlen = addend;
        return 0;
 }
 
index 168c871fcd796a4c4b411e440bb1fe3da004389d..65631391d479580de09f5eddf1302a39060b37c2 100644 (file)
@@ -204,22 +204,14 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
 
        rcu_read_lock();
        {
-               /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */
                int protocol = ip_hdr(skb)->protocol;
-               int hash;
-               struct sock *raw_sk;
+               int hash, raw;
                struct net_protocol *ipprot;
 
        resubmit:
-               hash = protocol & (MAX_INET_PROTOS - 1);
-               raw_sk = sk_head(&raw_v4_htable[hash]);
-
-               /* If there maybe a raw socket we must check - if not we
-                * don't care less
-                */
-               if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
-                       raw_sk = NULL;
+               raw = raw_local_deliver(skb, protocol);
 
+               hash = protocol & (MAX_INET_PROTOS - 1);
                if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
                        int ret;
 
@@ -237,7 +229,7 @@ static int ip_local_deliver_finish(struct sk_buff *skb)
                        }
                        IP_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);
                } else {
-                       if (!raw_sk) {
+                       if (!raw) {
                                if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
                                        IP_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
                                        icmp_send(skb, ICMP_DEST_UNREACH,
@@ -268,7 +260,7 @@ int ip_local_deliver(struct sk_buff *skb)
                        return 0;
        }
 
-       return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
+       return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
                       ip_local_deliver_finish);
 }
 
@@ -347,7 +339,7 @@ static int ip_rcv_finish(struct sk_buff *skb)
 
 #ifdef CONFIG_NET_CLS_ROUTE
        if (unlikely(skb->dst->tclassid)) {
-               struct ip_rt_acct *st = ip_rt_acct + 256*smp_processor_id();
+               struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id());
                u32 idx = skb->dst->tclassid;
                st[idx&0xFF].o_packets++;
                st[idx&0xFF].o_bytes+=skb->len;
@@ -442,7 +434,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        /* Remove any debris in the socket control block */
        memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
-       return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,
+       return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL,
                       ip_rcv_finish);
 
 inhdr_error:
index 2f14745a9e1fb0aa5bdc779421d9376049963884..4d315158fd3cde41b827dc3424fbedbe114437a4 100644 (file)
@@ -151,7 +151,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(addr) != RTN_LOCAL) {
+                                               if (inet_addr_type(&init_net, addr) != RTN_LOCAL) {
                                                        dopt->ts_needtime = 1;
                                                        soffset += 8;
                                                }
@@ -400,7 +400,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                        {
                                                __be32 addr;
                                                memcpy(&addr, &optptr[optptr[2]-1], 4);
-                                               if (inet_addr_type(addr) == RTN_UNICAST)
+                                               if (inet_addr_type(&init_net, addr) == RTN_UNICAST)
                                                        break;
                                                if (skb)
                                                        timeptr = (__be32*)&optptr[optptr[2]+3];
index bc9e57550e86d9b4f5b9ee965466f3d4f52f2585..18070ca65771c853dea40e08b02bb1e809b70535 100644 (file)
@@ -91,6 +91,28 @@ __inline__ void ip_send_check(struct iphdr *iph)
        iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
 }
 
+int __ip_local_out(struct sk_buff *skb)
+{
+       struct iphdr *iph = ip_hdr(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,
+                      dst_output);
+}
+
+int ip_local_out(struct sk_buff *skb)
+{
+       int err;
+
+       err = __ip_local_out(skb);
+       if (likely(err == 1))
+               err = dst_output(skb);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(ip_local_out);
+
 /* dev_loopback_xmit for use with netfilter. */
 static int ip_dev_loopback_xmit(struct sk_buff *newskb)
 {
@@ -138,20 +160,17 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
        iph->daddr    = rt->rt_dst;
        iph->saddr    = rt->rt_src;
        iph->protocol = sk->sk_protocol;
-       iph->tot_len  = htons(skb->len);
        ip_select_ident(iph, &rt->u.dst, sk);
 
        if (opt && opt->optlen) {
                iph->ihl += opt->optlen>>2;
                ip_options_build(skb, opt, daddr, rt, 0);
        }
-       ip_send_check(iph);
 
        skb->priority = sk->sk_priority;
 
        /* Send it out. */
-       return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-                      dst_output);
+       return ip_local_out(skb);
 }
 
 EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
@@ -251,8 +270,8 @@ int ip_mc_output(struct sk_buff *skb)
                ) {
                        struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                        if (newskb)
-                               NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
-                                       newskb->dev,
+                               NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb,
+                                       NULL, newskb->dev,
                                        ip_dev_loopback_xmit);
                }
 
@@ -267,11 +286,11 @@ int ip_mc_output(struct sk_buff *skb)
        if (rt->rt_flags&RTCF_BROADCAST) {
                struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                if (newskb)
-                       NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL,
+                       NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL,
                                newskb->dev, ip_dev_loopback_xmit);
        }
 
-       return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
                            ip_finish_output,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
@@ -285,7 +304,7 @@ int ip_output(struct sk_buff *skb)
        skb->dev = dev;
        skb->protocol = htons(ETH_P_IP);
 
-       return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev,
                            ip_finish_output,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
@@ -331,7 +350,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
                         * itself out.
                         */
                        security_sk_classify_flow(sk, &fl);
-                       if (ip_route_output_flow(&rt, &fl, sk, 0))
+                       if (ip_route_output_flow(&init_net, &rt, &fl, sk, 0))
                                goto no_route;
                }
                sk_setup_caps(sk, &rt->u.dst);
@@ -347,7 +366,6 @@ packet_routed:
        skb_reset_network_header(skb);
        iph = ip_hdr(skb);
        *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
-       iph->tot_len = htons(skb->len);
        if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
                iph->frag_off = htons(IP_DF);
        else
@@ -366,13 +384,9 @@ packet_routed:
        ip_select_ident_more(iph, &rt->u.dst, sk,
                             (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 
-       /* Add an IP checksum. */
-       ip_send_check(iph);
-
        skb->priority = sk->sk_priority;
 
-       return NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-                      dst_output);
+       return ip_local_out(skb);
 
 no_route:
        IP_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
@@ -1262,14 +1276,12 @@ int ip_push_pending_frames(struct sock *sk)
                ip_options_build(skb, opt, inet->cork.addr, rt, 0);
        }
        iph->tos = inet->tos;
-       iph->tot_len = htons(skb->len);
        iph->frag_off = df;
        ip_select_ident(iph, &rt->u.dst, sk);
        iph->ttl = ttl;
        iph->protocol = sk->sk_protocol;
        iph->saddr = rt->rt_src;
        iph->daddr = rt->rt_dst;
-       ip_send_check(iph);
 
        skb->priority = sk->sk_priority;
        skb->dst = dst_clone(&rt->u.dst);
@@ -1279,8 +1291,7 @@ int ip_push_pending_frames(struct sock *sk)
                        skb_transport_header(skb))->type);
 
        /* Netfilter gets whole the not fragmented skb. */
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
-                     skb->dst->dev, dst_output);
+       err = ip_local_out(skb);
        if (err) {
                if (err > 0)
                        err = inet->recverr ? net_xmit_errno(err) : 0;
@@ -1330,8 +1341,6 @@ static int ip_reply_glue_bits(void *dptr, char *to, int offset,
  *
  *     Should run single threaded per socket because it uses the sock
  *             structure to pass arguments.
- *
- *     LATER: switch from ip_build_xmit to ip_append_*
  */
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
                   unsigned int len)
@@ -1370,7 +1379,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
                                                 .dport = tcp_hdr(skb)->source } },
                                    .proto = sk->sk_protocol };
                security_skb_classify_flow(skb, &fl);
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(sk->sk_net, &rt, &fl))
                        return;
        }
 
index 82817e5543638e93299e017262693da28bf1bff8..754b0a5bbfe9b225a52041b7a4ced135fded0afe 100644 (file)
@@ -594,7 +594,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                                err = 0;
                                break;
                        }
-                       dev = ip_dev_find(mreq.imr_address.s_addr);
+                       dev = ip_dev_find(&init_net, mreq.imr_address.s_addr);
                        if (dev) {
                                mreq.imr_ifindex = dev->ifindex;
                                dev_put(dev);
index 2c44a94c2135d80aebb3a8708292b829f6f3bcf6..f4af99ad8fdb6015de40393d52b5bde5bd6c42c7 100644 (file)
@@ -182,7 +182,6 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
 static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
 {
        struct xfrm_state *t;
-       u8 mode = XFRM_MODE_TUNNEL;
 
        t = xfrm_state_alloc();
        if (t == NULL)
@@ -193,9 +192,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
        t->id.daddr.a4 = x->id.daddr.a4;
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET;
-       if (x->props.mode == XFRM_MODE_BEET)
-               mode = x->props.mode;
-       t->props.mode = mode;
+       t->props.mode = x->props.mode;
        t->props.saddr.a4 = x->props.saddr.a4;
        t->props.flags = x->props.flags;
 
@@ -389,15 +386,22 @@ static int ipcomp_init_state(struct xfrm_state *x)
        if (x->encap)
                goto out;
 
+       x->props.header_len = 0;
+       switch (x->props.mode) {
+       case XFRM_MODE_TRANSPORT:
+               break;
+       case XFRM_MODE_TUNNEL:
+               x->props.header_len += sizeof(struct iphdr);
+               break;
+       default:
+               goto out;
+       }
+
        err = -ENOMEM;
        ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
        if (!ipcd)
                goto out;
 
-       x->props.header_len = 0;
-       if (x->props.mode == XFRM_MODE_TUNNEL)
-               x->props.header_len += sizeof(struct iphdr);
-
        mutex_lock(&ipcomp_resource_mutex);
        if (!ipcomp_alloc_scratches())
                goto error;
index b8f7763b2261474e4e5d35961193bcdcbebf26cd..a52b5853aaa846a407d89e6ba281f6d619aa585b 100644 (file)
@@ -140,6 +140,9 @@ __be32 ic_servaddr = NONE;  /* Boot server IP address */
 __be32 root_server_addr = NONE;        /* Address of NFS server */
 u8 root_server_path[256] = { 0, };     /* Path to mount as root */
 
+/* vendor class identifier */
+static char vendor_class_identifier[253] __initdata;
+
 /* Persistent data: */
 
 static int ic_proto_used;                      /* Protocol used, if any */
@@ -299,7 +302,7 @@ static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
 
        mm_segment_t oldfs = get_fs();
        set_fs(get_ds());
-       res = ip_rt_ioctl(cmd, (void __user *) arg);
+       res = ip_rt_ioctl(&init_net, cmd, (void __user *) arg);
        set_fs(oldfs);
        return res;
 }
@@ -588,6 +591,7 @@ ic_dhcp_init_options(u8 *options)
        u8 mt = ((ic_servaddr == NONE)
                 ? DHCPDISCOVER : DHCPREQUEST);
        u8 *e = options;
+       int len;
 
 #ifdef IPCONFIG_DEBUG
        printk("DHCP: Sending message type %d\n", mt);
@@ -628,6 +632,16 @@ ic_dhcp_init_options(u8 *options)
                *e++ = sizeof(ic_req_params);
                memcpy(e, ic_req_params, sizeof(ic_req_params));
                e += sizeof(ic_req_params);
+
+               if (*vendor_class_identifier) {
+                       printk(KERN_INFO "DHCP: sending class identifier \"%s\"\n",
+                              vendor_class_identifier);
+                       *e++ = 60;      /* Class-identifier */
+                       len = strlen(vendor_class_identifier);
+                       *e++ = len;
+                       memcpy(e, vendor_class_identifier, len);
+                       e += len;
+               }
        }
 
        *e++ = 255;     /* End of the list */
@@ -1513,5 +1527,16 @@ static int __init nfsaddrs_config_setup(char *addrs)
        return ip_auto_config_setup(addrs);
 }
 
+static int __init vendor_class_identifier_setup(char *addrs)
+{
+       if (strlcpy(vendor_class_identifier, addrs,
+                   sizeof(vendor_class_identifier))
+           >= sizeof(vendor_class_identifier))
+               printk(KERN_WARNING "DHCP: vendorclass too long, truncated to \"%s\"",
+                      vendor_class_identifier);
+       return 1;
+}
+
 __setup("ip=", ip_auto_config_setup);
 __setup("nfsaddrs=", nfsaddrs_config_setup);
+__setup("dhcpclass=", vendor_class_identifier_setup);
index 8c2b2b0741daeb4ac118ea39721ecaab19ad00fb..da281581692c2bd7333ae481fceaeb52c55bb2ca 100644 (file)
@@ -405,7 +405,7 @@ out:
        fl.fl4_daddr = eiph->saddr;
        fl.fl4_tos = RT_TOS(eiph->tos);
        fl.proto = IPPROTO_IPIP;
-       if (ip_route_output_key(&rt, &key)) {
+       if (ip_route_output_key(&init_net, &rt, &key)) {
                kfree_skb(skb2);
                return 0;
        }
@@ -418,7 +418,7 @@ out:
                fl.fl4_daddr = eiph->daddr;
                fl.fl4_src = eiph->saddr;
                fl.fl4_tos = eiph->tos;
-               if (ip_route_output_key(&rt, &fl) ||
+               if (ip_route_output_key(&init_net, &rt, &fl) ||
                    rt->u.dst.dev->type != ARPHRD_TUNNEL) {
                        ip_rt_put(rt);
                        kfree_skb(skb2);
@@ -547,7 +547,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                                                .saddr = tiph->saddr,
                                                .tos = RT_TOS(tos) } },
                                    .proto = IPPROTO_IPIP };
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        tunnel->stat.tx_carrier_errors++;
                        goto tx_error_icmp;
                }
@@ -651,6 +651,40 @@ tx_error:
        return 0;
 }
 
+static void ipip_tunnel_bind_dev(struct net_device *dev)
+{
+       struct net_device *tdev = NULL;
+       struct ip_tunnel *tunnel;
+       struct iphdr *iph;
+
+       tunnel = netdev_priv(dev);
+       iph = &tunnel->parms.iph;
+
+       if (iph->daddr) {
+               struct flowi fl = { .oif = tunnel->parms.link,
+                                   .nl_u = { .ip4_u =
+                                             { .daddr = iph->daddr,
+                                               .saddr = iph->saddr,
+                                               .tos = RT_TOS(iph->tos) } },
+                                   .proto = IPPROTO_IPIP };
+               struct rtable *rt;
+               if (!ip_route_output_key(&init_net, &rt, &fl)) {
+                       tdev = rt->u.dst.dev;
+                       ip_rt_put(rt);
+               }
+               dev->flags |= IFF_POINTOPOINT;
+       }
+
+       if (!tdev && tunnel->parms.link)
+               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+       if (tdev) {
+               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
+               dev->mtu = tdev->mtu - sizeof(struct iphdr);
+       }
+       dev->iflink = tunnel->parms.link;
+}
+
 static int
 ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -723,6 +757,11 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
                                t->parms.iph.frag_off = p.iph.frag_off;
+                               if (t->parms.link != p.link) {
+                                       t->parms.link = p.link;
+                                       ipip_tunnel_bind_dev(dev);
+                                       netdev_state_change(dev);
+                               }
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
@@ -791,12 +830,9 @@ static void ipip_tunnel_setup(struct net_device *dev)
 
 static int ipip_tunnel_init(struct net_device *dev)
 {
-       struct net_device *tdev = NULL;
        struct ip_tunnel *tunnel;
-       struct iphdr *iph;
 
        tunnel = netdev_priv(dev);
-       iph = &tunnel->parms.iph;
 
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
@@ -804,29 +840,7 @@ static int ipip_tunnel_init(struct net_device *dev)
        memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
        memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-       if (iph->daddr) {
-               struct flowi fl = { .oif = tunnel->parms.link,
-                                   .nl_u = { .ip4_u =
-                                             { .daddr = iph->daddr,
-                                               .saddr = iph->saddr,
-                                               .tos = RT_TOS(iph->tos) } },
-                                   .proto = IPPROTO_IPIP };
-               struct rtable *rt;
-               if (!ip_route_output_key(&rt, &fl)) {
-                       tdev = rt->u.dst.dev;
-                       ip_rt_put(rt);
-               }
-               dev->flags |= IFF_POINTOPOINT;
-       }
-
-       if (!tdev && tunnel->parms.link)
-               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
-
-       if (tdev) {
-               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
-               dev->mtu = tdev->mtu - sizeof(struct iphdr);
-       }
-       dev->iflink = tunnel->parms.link;
+       ipip_tunnel_bind_dev(dev);
 
        return 0;
 }
index 37bb497d92af2af2d714ed4d4694d25a4b9c5471..a94f52c207a7e4f789e9ddf8dcc50d1475766677 100644 (file)
@@ -141,7 +141,7 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
                p.iph.ihl = 5;
                p.iph.protocol = IPPROTO_IPIP;
                sprintf(p.name, "dvmrp%d", v->vifc_vifi);
-               ifr.ifr_ifru.ifru_data = (void*)&p;
+               ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
                oldfs = get_fs(); set_fs(KERNEL_DS);
                err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
@@ -321,7 +321,7 @@ static void ipmr_destroy_unres(struct mfc_cache *c)
                        e->error = -ETIMEDOUT;
                        memset(&e->msg, 0, sizeof(e->msg));
 
-                       rtnl_unicast(skb, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
                } else
                        kfree_skb(skb);
        }
@@ -423,7 +423,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock)
                        return -ENOBUFS;
                break;
        case 0:
-               dev = ip_dev_find(vifc->vifc_lcl_addr.s_addr);
+               dev = ip_dev_find(&init_net, vifc->vifc_lcl_addr.s_addr);
                if (!dev)
                        return -EADDRNOTAVAIL;
                dev_put(dev);
@@ -533,7 +533,7 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c)
                                memset(&e->msg, 0, sizeof(e->msg));
                        }
 
-                       rtnl_unicast(skb, NETLINK_CB(skb).pid);
+                       rtnl_unicast(skb, &init_net, NETLINK_CB(skb).pid);
                } else
                        ip_mr_forward(skb, c, 0);
        }
@@ -749,7 +749,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock)
                return 0;
        }
 
-       if (!MULTICAST(mfc->mfcc_mcastgrp.s_addr))
+       if (!ipv4_is_multicast(mfc->mfcc_mcastgrp.s_addr))
                return -EINVAL;
 
        c=ipmr_cache_alloc();
@@ -849,7 +849,7 @@ static void mrtsock_destruct(struct sock *sk)
 {
        rtnl_lock();
        if (sk == mroute_socket) {
-               IPV4_DEVCONF_ALL(MC_FORWARDING)--;
+               IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)--;
 
                write_lock_bh(&mrt_lock);
                mroute_socket=NULL;
@@ -898,7 +898,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
                        mroute_socket=sk;
                        write_unlock_bh(&mrt_lock);
 
-                       IPV4_DEVCONF_ALL(MC_FORWARDING)++;
+                       IPV4_DEVCONF_ALL(sk->sk_net, MC_FORWARDING)++;
                }
                rtnl_unlock();
                return ret;
@@ -954,10 +954,12 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt
 #ifdef CONFIG_IP_PIMSM
        case MRT_PIM:
        {
-               int v, ret;
+               int v;
+
                if (get_user(v,(int __user *)optval))
                        return -EFAULT;
-               v = (v)?1:0;
+               v = (v) ? 1 : 0;
+
                rtnl_lock();
                ret = 0;
                if (v != mroute_do_pim) {
@@ -1183,7 +1185,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
                                                .saddr = vif->local,
                                                .tos = RT_TOS(iph->tos) } },
                                    .proto = IPPROTO_IPIP };
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(&init_net, &rt, &fl))
                        goto out_free;
                encap = sizeof(struct iphdr);
        } else {
@@ -1192,7 +1194,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
                                              { .daddr = iph->daddr,
                                                .tos = RT_TOS(iph->tos) } },
                                    .proto = IPPROTO_IPIP };
-               if (ip_route_output_key(&rt, &fl))
+               if (ip_route_output_key(&init_net, &rt, &fl))
                        goto out_free;
        }
 
@@ -1245,7 +1247,7 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
         * not mrouter) cannot join to more than one interface - it will
         * result in receiving multiple packets.
         */
-       NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev,
+       NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev,
                ipmr_forward_finish);
        return;
 
@@ -1461,7 +1463,7 @@ int pim_rcv_v1(struct sk_buff * skb)
           b. packet is not a NULL-REGISTER
           c. packet is not truncated
         */
-       if (!MULTICAST(encap->daddr) ||
+       if (!ipv4_is_multicast(encap->daddr) ||
            encap->tot_len == 0 ||
            ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
                goto drop;
@@ -1517,7 +1519,7 @@ static int pim_rcv(struct sk_buff * skb)
        /* check if the inner packet is destined to mcast group */
        encap = (struct iphdr *)(skb_transport_header(skb) +
                                 sizeof(struct pimreghdr));
-       if (!MULTICAST(encap->daddr) ||
+       if (!ipv4_is_multicast(encap->daddr) ||
            encap->tot_len == 0 ||
            ntohs(encap->tot_len) + sizeof(*pim) > skb->len)
                goto drop;
@@ -1659,6 +1661,7 @@ static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter,
 }
 
 static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(mrt_lock)
 {
        read_lock(&mrt_lock);
        return *pos ? ipmr_vif_seq_idx(seq->private, *pos - 1)
@@ -1682,6 +1685,7 @@ static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
+       __releases(mrt_lock)
 {
        read_unlock(&mrt_lock);
 }
@@ -1889,8 +1893,7 @@ void __init ip_mr_init(void)
                                       sizeof(struct mfc_cache),
                                       0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
                                       NULL);
-       init_timer(&ipmr_expire_timer);
-       ipmr_expire_timer.function=ipmr_expire_process;
+       setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
        register_netdevice_notifier(&ip_mr_notifier);
 #ifdef CONFIG_PROC_FS
        proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops);
index 664cb8e97c1c515202d8bd6f05cca73bd9e789b1..535abe0c45e7f4fc4e71c401f249e58bdf9d90eb 100644 (file)
@@ -51,18 +51,13 @@ static DEFINE_MUTEX(__ip_vs_app_mutex);
  */
 static inline int ip_vs_app_get(struct ip_vs_app *app)
 {
-       /* test and get the module atomically */
-       if (app->module)
-               return try_module_get(app->module);
-       else
-               return 1;
+       return try_module_get(app->module);
 }
 
 
 static inline void ip_vs_app_put(struct ip_vs_app *app)
 {
-       if (app->module)
-               module_put(app->module);
+       module_put(app->module);
 }
 
 
index 0a9f3c37e18d8caa939f22d40b7b66dc72df3753..65f1ba1127526c35bb7f263075801258b8fc8d82 100644 (file)
@@ -393,7 +393,15 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
        atomic_inc(&dest->refcnt);
 
        /* Bind with the destination and its corresponding transmitter */
-       cp->flags |= atomic_read(&dest->conn_flags);
+       if ((cp->flags & IP_VS_CONN_F_SYNC) &&
+           (!(cp->flags & IP_VS_CONN_F_TEMPLATE)))
+               /* if the connection is not template and is created
+                * by sync, preserve the activity flag.
+                */
+               cp->flags |= atomic_read(&dest->conn_flags) &
+                            (~IP_VS_CONN_F_INACTIVE);
+       else
+               cp->flags |= atomic_read(&dest->conn_flags);
        cp->dest = dest;
 
        IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
@@ -412,7 +420,11 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
                /* It is a normal connection, so increase the inactive
                   connection counter because it is in TCP SYNRECV
                   state (inactive) or other protocol inacive state */
-               atomic_inc(&dest->inactconns);
+               if ((cp->flags & IP_VS_CONN_F_SYNC) &&
+                   (!(cp->flags & IP_VS_CONN_F_INACTIVE)))
+                       atomic_inc(&dest->activeconns);
+               else
+                       atomic_inc(&dest->inactconns);
        } else {
                /* It is a persistent connection/template, so increase
                   the peristent connection counter */
@@ -629,9 +641,7 @@ ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport
        }
 
        INIT_LIST_HEAD(&cp->c_list);
-       init_timer(&cp->timer);
-       cp->timer.data     = (unsigned long)cp;
-       cp->timer.function = ip_vs_conn_expire;
+       setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
        cp->protocol       = proto;
        cp->caddr          = caddr;
        cp->cport          = cport;
@@ -783,6 +793,57 @@ static const struct file_operations ip_vs_conn_fops = {
        .llseek  = seq_lseek,
        .release = seq_release,
 };
+
+static const char *ip_vs_origin_name(unsigned flags)
+{
+       if (flags & IP_VS_CONN_F_SYNC)
+               return "SYNC";
+       else
+               return "LOCAL";
+}
+
+static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)
+{
+
+       if (v == SEQ_START_TOKEN)
+               seq_puts(seq,
+   "Pro FromIP   FPrt ToIP     TPrt DestIP   DPrt State       Origin Expires\n");
+       else {
+               const struct ip_vs_conn *cp = v;
+
+               seq_printf(seq,
+                       "%-3s %08X %04X %08X %04X %08X %04X %-11s %-6s %7lu\n",
+                               ip_vs_proto_name(cp->protocol),
+                               ntohl(cp->caddr), ntohs(cp->cport),
+                               ntohl(cp->vaddr), ntohs(cp->vport),
+                               ntohl(cp->daddr), ntohs(cp->dport),
+                               ip_vs_state_name(cp->protocol, cp->state),
+                               ip_vs_origin_name(cp->flags),
+                               (cp->timer.expires-jiffies)/HZ);
+       }
+       return 0;
+}
+
+static const struct seq_operations ip_vs_conn_sync_seq_ops = {
+       .start = ip_vs_conn_seq_start,
+       .next  = ip_vs_conn_seq_next,
+       .stop  = ip_vs_conn_seq_stop,
+       .show  = ip_vs_conn_sync_seq_show,
+};
+
+static int ip_vs_conn_sync_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &ip_vs_conn_sync_seq_ops);
+}
+
+static const struct file_operations ip_vs_conn_sync_fops = {
+       .owner   = THIS_MODULE,
+       .open    = ip_vs_conn_sync_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+};
+
 #endif
 
 
@@ -942,6 +1003,7 @@ int ip_vs_conn_init(void)
        }
 
        proc_net_fops_create(&init_net, "ip_vs_conn", 0, &ip_vs_conn_fops);
+       proc_net_fops_create(&init_net, "ip_vs_conn_sync", 0, &ip_vs_conn_sync_fops);
 
        /* calculate the random value for connection hash */
        get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd));
@@ -958,5 +1020,6 @@ void ip_vs_conn_cleanup(void)
        /* Release the empty cache */
        kmem_cache_destroy(ip_vs_conn_cachep);
        proc_net_remove(&init_net, "ip_vs_conn");
+       proc_net_remove(&init_net, "ip_vs_conn_sync");
        vfree(ip_vs_conn_tab);
 }
index 8fba20256f52abeae41df323563a8c04149b1293..963981a9d5015945bed33b431ddfef9406ecc264 100644 (file)
@@ -423,7 +423,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
           and the destination is RTN_UNICAST (and not local), then create
           a cache_bypass connection entry */
        if (sysctl_ip_vs_cache_bypass && svc->fwmark
-           && (inet_addr_type(iph->daddr) == RTN_UNICAST)) {
+           && (inet_addr_type(&init_net, iph->daddr) == RTN_UNICAST)) {
                int ret, cs;
                struct ip_vs_conn *cp;
 
@@ -481,7 +481,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
 
 
 /*
- *      It is hooked before NF_IP_PRI_NAT_SRC at the NF_IP_POST_ROUTING
+ *      It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING
  *      chain, and is used for VS/NAT.
  *      It detects packets for VS/NAT connections and sends the packets
  *      immediately. This can avoid that iptable_nat mangles the packets
@@ -679,7 +679,7 @@ static inline int is_tcp_reset(const struct sk_buff *skb)
 }
 
 /*
- *     It is hooked at the NF_IP_FORWARD chain, used only for VS/NAT.
+ *     It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT.
  *     Check if outgoing packet belongs to the established ip_vs_conn,
  *      rewrite addresses of the packet and send it on its way...
  */
@@ -814,7 +814,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
 
        /* reassemble IP fragments */
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
-               if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ?
+               if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ?
                                            IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD))
                        return NF_STOLEN;
        }
@@ -1003,12 +1003,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
 
 
 /*
- *     It is hooked at the NF_IP_FORWARD chain, in order to catch ICMP
+ *     It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP
  *      related packets destined for 0.0.0.0/0.
  *      When fwmark-based virtual service is used, such as transparent
  *      cache cluster, TCP packets can be marked and routed to ip_vs_in,
  *      but ICMP destined for 0.0.0.0/0 cannot not be easily marked and
- *      sent to ip_vs_in_icmp. So, catch them at the NF_IP_FORWARD chain
+ *      sent to ip_vs_in_icmp. So, catch them at the NF_INET_FORWARD chain
  *      and send them to ip_vs_in_icmp.
  */
 static unsigned int
@@ -1025,43 +1025,42 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
 }
 
 
-/* After packet filtering, forward packet through VS/DR, VS/TUN,
-   or VS/NAT(change destination), so that filtering rules can be
-   applied to IPVS. */
-static struct nf_hook_ops ip_vs_in_ops = {
-       .hook           = ip_vs_in,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_LOCAL_IN,
-       .priority       = 100,
-};
-
-/* After packet filtering, change source only for VS/NAT */
-static struct nf_hook_ops ip_vs_out_ops = {
-       .hook           = ip_vs_out,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_FORWARD,
-       .priority       = 100,
-};
-
-/* After packet filtering (but before ip_vs_out_icmp), catch icmp
-   destined for 0.0.0.0/0, which is for incoming IPVS connections */
-static struct nf_hook_ops ip_vs_forward_icmp_ops = {
-       .hook           = ip_vs_forward_icmp,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_FORWARD,
-       .priority       = 99,
-};
-
-/* Before the netfilter connection tracking, exit from POST_ROUTING */
-static struct nf_hook_ops ip_vs_post_routing_ops = {
-       .hook           = ip_vs_post_routing,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_POST_ROUTING,
-       .priority       = NF_IP_PRI_NAT_SRC-1,
+static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
+       /* After packet filtering, forward packet through VS/DR, VS/TUN,
+        * or VS/NAT(change destination), so that filtering rules can be
+        * applied to IPVS. */
+       {
+               .hook           = ip_vs_in,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_INET_LOCAL_IN,
+               .priority       = 100,
+       },
+       /* After packet filtering, change source only for VS/NAT */
+       {
+               .hook           = ip_vs_out,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_INET_FORWARD,
+               .priority       = 100,
+       },
+       /* After packet filtering (but before ip_vs_out_icmp), catch icmp
+        * destined for 0.0.0.0/0, which is for incoming IPVS connections */
+       {
+               .hook           = ip_vs_forward_icmp,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_INET_FORWARD,
+               .priority       = 99,
+       },
+       /* Before the netfilter connection tracking, exit from POST_ROUTING */
+       {
+               .hook           = ip_vs_post_routing,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_INET_POST_ROUTING,
+               .priority       = NF_IP_PRI_NAT_SRC-1,
+       },
 };
 
 
@@ -1092,37 +1091,15 @@ static int __init ip_vs_init(void)
                goto cleanup_app;
        }
 
-       ret = nf_register_hook(&ip_vs_in_ops);
+       ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
        if (ret < 0) {
-               IP_VS_ERR("can't register in hook.\n");
+               IP_VS_ERR("can't register hooks.\n");
                goto cleanup_conn;
        }
 
-       ret = nf_register_hook(&ip_vs_out_ops);
-       if (ret < 0) {
-               IP_VS_ERR("can't register out hook.\n");
-               goto cleanup_inops;
-       }
-       ret = nf_register_hook(&ip_vs_post_routing_ops);
-       if (ret < 0) {
-               IP_VS_ERR("can't register post_routing hook.\n");
-               goto cleanup_outops;
-       }
-       ret = nf_register_hook(&ip_vs_forward_icmp_ops);
-       if (ret < 0) {
-               IP_VS_ERR("can't register forward_icmp hook.\n");
-               goto cleanup_postroutingops;
-       }
-
        IP_VS_INFO("ipvs loaded.\n");
        return ret;
 
-  cleanup_postroutingops:
-       nf_unregister_hook(&ip_vs_post_routing_ops);
-  cleanup_outops:
-       nf_unregister_hook(&ip_vs_out_ops);
-  cleanup_inops:
-       nf_unregister_hook(&ip_vs_in_ops);
   cleanup_conn:
        ip_vs_conn_cleanup();
   cleanup_app:
@@ -1136,10 +1113,7 @@ static int __init ip_vs_init(void)
 
 static void __exit ip_vs_cleanup(void)
 {
-       nf_unregister_hook(&ip_vs_forward_icmp_ops);
-       nf_unregister_hook(&ip_vs_post_routing_ops);
-       nf_unregister_hook(&ip_vs_out_ops);
-       nf_unregister_hook(&ip_vs_in_ops);
+       nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops));
        ip_vs_conn_cleanup();
        ip_vs_app_cleanup();
        ip_vs_protocol_cleanup();
index 693d92490c117a587db3b882d648fa179c201698..94c5767c8e0192545c75e071893bae08af0fe4c9 100644 (file)
@@ -704,7 +704,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
        conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
 
        /* check if local node and update the flags */
-       if (inet_addr_type(udest->addr) == RTN_LOCAL) {
+       if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) {
                conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
                        | IP_VS_CONN_F_LOCALNODE;
        }
@@ -756,7 +756,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
 
        EnterFunction(2);
 
-       atype = inet_addr_type(udest->addr);
+       atype = inet_addr_type(&init_net, udest->addr);
        if (atype != RTN_LOCAL && atype != RTN_UNICAST)
                return -EINVAL;
 
@@ -1591,34 +1591,13 @@ static struct ctl_table vs_vars[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table vs_table[] = {
-       {
-               .procname       = "vs",
-               .mode           = 0555,
-               .child          = vs_vars
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipvs_ipv4_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = vs_table,
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table vs_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipvs_ipv4_table,
-       },
-       { .ctl_name = 0 }
+struct ctl_path net_vs_ctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv4", .ctl_name = NET_IPV4, },
+       { .procname = "vs", },
+       { }
 };
+EXPORT_SYMBOL_GPL(net_vs_ctl_path);
 
 static struct ctl_table_header * sysctl_header;
 
@@ -2345,7 +2324,7 @@ int ip_vs_control_init(void)
        proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
        proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
 
-       sysctl_header = register_sysctl_table(vs_root_table);
+       sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars);
 
        /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */
        for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++)  {
index 7d68b80c4c19534679c29c400a35fdd5a00c9295..dfa0d713c801b81dc6465feba8ad4ae3587d0ad1 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/interrupt.h>
+#include <linux/sysctl.h>
 
 #include <net/ip_vs.h>
 
@@ -146,9 +147,8 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats)
        write_lock_bh(&est_lock);
        est->next = est_list;
        if (est->next == NULL) {
-               init_timer(&est_timer);
+               setup_timer(&est_timer, estimation_timer, 0);
                est_timer.expires = jiffies + 2*HZ;
-               est_timer.function = estimation_timer;
                add_timer(&est_timer);
        }
        est_list = est;
index ad89644ef5d27e797f9a188451dc4f5c315cce70..3888642706ada030290f809050f273b0bb1dd33a 100644 (file)
@@ -123,35 +123,6 @@ static ctl_table vs_vars_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table vs_table[] = {
-       {
-               .procname       = "vs",
-               .mode           = 0555,
-               .child          = vs_vars_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipvs_ipv4_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = vs_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table lblc_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipvs_ipv4_table
-       },
-       { .ctl_name = 0 }
-};
-
 static struct ctl_table_header * sysctl_header;
 
 /*
@@ -391,9 +362,8 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
        /*
         *    Hook periodic timer for garbage collection
         */
-       init_timer(&tbl->periodic_timer);
-       tbl->periodic_timer.data = (unsigned long)tbl;
-       tbl->periodic_timer.function = ip_vs_lblc_check_expire;
+       setup_timer(&tbl->periodic_timer, ip_vs_lblc_check_expire,
+                       (unsigned long)tbl);
        tbl->periodic_timer.expires = jiffies+CHECK_EXPIRE_INTERVAL;
        add_timer(&tbl->periodic_timer);
 
@@ -583,7 +553,7 @@ static int __init ip_vs_lblc_init(void)
        int ret;
 
        INIT_LIST_HEAD(&ip_vs_lblc_scheduler.n_list);
-       sysctl_header = register_sysctl_table(lblc_root_table);
+       sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
        ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler);
        if (ret)
                unregister_sysctl_table(sysctl_header);
index 2a5ed85a3352f6a7ad06658c478cf29d7065d62a..daa260eb21cf03df49c1e13e22dd94420876d177 100644 (file)
@@ -311,35 +311,6 @@ static ctl_table vs_vars_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table vs_table[] = {
-       {
-               .procname       = "vs",
-               .mode           = 0555,
-               .child          = vs_vars_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipvs_ipv4_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = vs_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table lblcr_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipvs_ipv4_table
-       },
-       { .ctl_name = 0 }
-};
-
 static struct ctl_table_header * sysctl_header;
 
 /*
@@ -575,9 +546,8 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
        /*
         *    Hook periodic timer for garbage collection
         */
-       init_timer(&tbl->periodic_timer);
-       tbl->periodic_timer.data = (unsigned long)tbl;
-       tbl->periodic_timer.function = ip_vs_lblcr_check_expire;
+       setup_timer(&tbl->periodic_timer, ip_vs_lblcr_check_expire,
+                       (unsigned long)tbl);
        tbl->periodic_timer.expires = jiffies+CHECK_EXPIRE_INTERVAL;
        add_timer(&tbl->periodic_timer);
 
@@ -772,7 +742,7 @@ static int __init ip_vs_lblcr_init(void)
        int ret;
 
        INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
-       sysctl_header = register_sysctl_table(lblcr_root_table);
+       sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
        ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
        if (ret)
                unregister_sysctl_table(sysctl_header);
index c0e11ec8f0f991d7096ce0e44f1535eddd7e39b2..dde28a250d92f0c0dd1d9776cfa4c366a9793c35 100644 (file)
@@ -165,7 +165,7 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
        ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
        if (ih == NULL)
                sprintf(buf, "%s TRUNCATED", pp->name);
-       else if (ih->frag_off & __constant_htons(IP_OFFSET))
+       else if (ih->frag_off & htons(IP_OFFSET))
                sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag",
                        pp->name, NIPQUAD(ih->saddr),
                        NIPQUAD(ih->daddr));
index c36ccf057a19fe53942de7a387b7c328fcd24664..aef0d3ee8e44f6859d6dfed03b352c2c7b7aba44 100644 (file)
@@ -52,15 +52,15 @@ esp_conn_in_get(const struct sk_buff *skb,
        if (likely(!inverse)) {
                cp = ip_vs_conn_in_get(IPPROTO_UDP,
                                       iph->saddr,
-                                      __constant_htons(PORT_ISAKMP),
+                                      htons(PORT_ISAKMP),
                                       iph->daddr,
-                                      __constant_htons(PORT_ISAKMP));
+                                      htons(PORT_ISAKMP));
        } else {
                cp = ip_vs_conn_in_get(IPPROTO_UDP,
                                       iph->daddr,
-                                      __constant_htons(PORT_ISAKMP),
+                                      htons(PORT_ISAKMP),
                                       iph->saddr,
-                                      __constant_htons(PORT_ISAKMP));
+                                      htons(PORT_ISAKMP));
        }
 
        if (!cp) {
@@ -89,15 +89,15 @@ esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
        if (likely(!inverse)) {
                cp = ip_vs_conn_out_get(IPPROTO_UDP,
                                        iph->saddr,
-                                       __constant_htons(PORT_ISAKMP),
+                                       htons(PORT_ISAKMP),
                                        iph->daddr,
-                                       __constant_htons(PORT_ISAKMP));
+                                       htons(PORT_ISAKMP));
        } else {
                cp = ip_vs_conn_out_get(IPPROTO_UDP,
                                        iph->daddr,
-                                       __constant_htons(PORT_ISAKMP),
+                                       htons(PORT_ISAKMP),
                                        iph->saddr,
-                                       __constant_htons(PORT_ISAKMP));
+                                       htons(PORT_ISAKMP));
        }
 
        if (!cp) {
index 43223586190839ffa92bc5a56e7ca7d37a58824e..121a32b1b756739aaafb3902e41dc1d6458ce101 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <asm/string.h>
 #include <linux/kmod.h>
+#include <linux/sysctl.h>
 
 #include <net/ip_vs.h>
 
index bd930efc18dabb27e0058adc97d20900b02a4ef2..948378d0a755f39386974c27b51b8a5b2ac509e2 100644 (file)
@@ -305,10 +305,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
 
        p = (char *)buffer + sizeof(struct ip_vs_sync_mesg);
        for (i=0; i<m->nr_conns; i++) {
-               unsigned flags;
+               unsigned flags, state;
 
                s = (struct ip_vs_sync_conn *)p;
-               flags = ntohs(s->flags);
+               flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
+               state = ntohs(s->state);
                if (!(flags & IP_VS_CONN_F_TEMPLATE))
                        cp = ip_vs_conn_in_get(s->protocol,
                                               s->caddr, s->cport,
@@ -326,6 +327,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                        dest = ip_vs_find_dest(s->daddr, s->dport,
                                               s->vaddr, s->vport,
                                               s->protocol);
+                       /*  Set the approprite ativity flag */
+                       if (s->protocol == IPPROTO_TCP) {
+                               if (state != IP_VS_TCP_S_ESTABLISHED)
+                                       flags |= IP_VS_CONN_F_INACTIVE;
+                               else
+                                       flags &= ~IP_VS_CONN_F_INACTIVE;
+                       }
                        cp = ip_vs_conn_new(s->protocol,
                                            s->caddr, s->cport,
                                            s->vaddr, s->vport,
@@ -337,7 +345,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                                IP_VS_ERR("ip_vs_conn_new failed\n");
                                return;
                        }
-                       cp->state = ntohs(s->state);
+                       cp->state = state;
                } else if (!cp->dest) {
                        dest = ip_vs_try_bind_dest(cp);
                        if (!dest) {
@@ -346,8 +354,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                                cp->flags = flags | IP_VS_CONN_F_HASHED;
                        } else
                                atomic_dec(&dest->refcnt);
-               }       /* Note that we don't touch its state and flags
-                          if it is a normal entry. */
+               } else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
+                          (cp->state != state)) {
+                       /* update active/inactive flag for the connection */
+                       dest = cp->dest;
+                       if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
+                               (state != IP_VS_TCP_S_ESTABLISHED)) {
+                               atomic_dec(&dest->activeconns);
+                               atomic_inc(&dest->inactconns);
+                               cp->flags |= IP_VS_CONN_F_INACTIVE;
+                       } else if ((cp->flags & IP_VS_CONN_F_INACTIVE) &&
+                               (state == IP_VS_TCP_S_ESTABLISHED)) {
+                               atomic_inc(&dest->activeconns);
+                               atomic_dec(&dest->inactconns);
+                               cp->flags &= ~IP_VS_CONN_F_INACTIVE;
+                       }
+               }
 
                if (flags & IP_VS_CONN_F_SEQ_MASK) {
                        opt = (struct ip_vs_sync_conn_options *)&s[1];
@@ -357,7 +379,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
                        p += SIMPLE_CONN_SIZE;
 
                atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
-               cp->state = ntohs(s->state);
+               cp->state = state;
                pp = ip_vs_proto_get(s->protocol);
                cp->timeout = pp->timeout_table[cp->state];
                ip_vs_conn_put(cp);
index 7c074e386c17235a3f9a98bd350a390b316f4835..f63006caea0358d472a57f911f5e8dba2be16af6 100644 (file)
@@ -16,8 +16,8 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/ip.h>
 #include <linux/tcp.h>                  /* for tcphdr */
+#include <net/ip.h>
 #include <net/tcp.h>                    /* for csum_tcpudp_magic */
 #include <net/udp.h>
 #include <net/icmp.h>                   /* for icmp_send */
@@ -59,7 +59,7 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie)
        return dst;
 }
 
-static inline struct rtable *
+static struct rtable *
 __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
 {
        struct rtable *rt;                      /* Route to the other host */
@@ -78,7 +78,7 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
                                                .tos = rtos, } },
                        };
 
-                       if (ip_route_output_key(&rt, &fl)) {
+                       if (ip_route_output_key(&init_net, &rt, &fl)) {
                                spin_unlock(&dest->dst_lock);
                                IP_VS_DBG_RL("ip_route_output error, "
                                             "dest: %u.%u.%u.%u\n",
@@ -101,7 +101,7 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
                                        .tos = rtos, } },
                };
 
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        IP_VS_DBG_RL("ip_route_output error, dest: "
                                     "%u.%u.%u.%u\n", NIPQUAD(cp->daddr));
                        return NULL;
@@ -129,7 +129,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
 do {                                                   \
        (skb)->ipvs_property = 1;                       \
        skb_forward_csum(skb);                          \
-       NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, (skb), NULL,  \
+       NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, (skb), NULL,        \
                (rt)->u.dst.dev, dst_output);           \
 } while (0)
 
@@ -170,7 +170,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
 
        EnterFunction(10);
 
-       if (ip_route_output_key(&rt, &fl)) {
+       if (ip_route_output_key(&init_net, &rt, &fl)) {
                IP_VS_DBG_RL("ip_vs_bypass_xmit(): ip_route_output error, "
                             "dest: %u.%u.%u.%u\n", NIPQUAD(iph->daddr));
                goto tx_error_icmp;
@@ -406,14 +406,12 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        iph->daddr              =       rt->rt_dst;
        iph->saddr              =       rt->rt_src;
        iph->ttl                =       old_iph->ttl;
-       iph->tot_len            =       htons(skb->len);
        ip_select_ident(iph, &rt->u.dst, NULL);
-       ip_send_check(iph);
 
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(skb, rt);
+       ip_local_out(skb);
 
        LeaveFunction(10);
 
index 5539debf49735de2ea50105b507139ed1d35799d..9a904c6c0dc8d0d72244ecac2c53ce49cf68cb65 100644 (file)
@@ -7,6 +7,7 @@
 #include <net/route.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
+#include <net/netfilter/nf_queue.h>
 
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
@@ -18,12 +19,12 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
        unsigned int hh_len;
        unsigned int type;
 
-       type = inet_addr_type(iph->saddr);
+       type = inet_addr_type(&init_net, iph->saddr);
        if (addr_type == RTN_UNSPEC)
                addr_type = type;
 
        /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
-        * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
+        * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
         */
        if (addr_type == RTN_LOCAL) {
                fl.nl_u.ip4_u.daddr = iph->daddr;
@@ -32,7 +33,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
                fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
                fl.mark = skb->mark;
-               if (ip_route_output_key(&rt, &fl) != 0)
+               if (ip_route_output_key(&init_net, &rt, &fl) != 0)
                        return -1;
 
                /* Drop old route. */
@@ -42,7 +43,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                /* non-local src, find valid iif to satisfy
                 * rp-filter when calling ip_route_input. */
                fl.nl_u.ip4_u.daddr = iph->saddr;
-               if (ip_route_output_key(&rt, &fl) != 0)
+               if (ip_route_output_key(&init_net, &rt, &fl) != 0)
                        return -1;
 
                odst = skb->dst;
@@ -122,11 +123,12 @@ struct ip_rt_info {
        u_int8_t tos;
 };
 
-static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info)
+static void nf_ip_saveroute(const struct sk_buff *skb,
+                           struct nf_queue_entry *entry)
 {
-       struct ip_rt_info *rt_info = nf_info_reroute(info);
+       struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
 
-       if (info->hook == NF_IP_LOCAL_OUT) {
+       if (entry->hook == NF_INET_LOCAL_OUT) {
                const struct iphdr *iph = ip_hdr(skb);
 
                rt_info->tos = iph->tos;
@@ -135,11 +137,12 @@ static void nf_ip_saveroute(const struct sk_buff *skb, struct nf_info *info)
        }
 }
 
-static int nf_ip_reroute(struct sk_buff *skb, const struct nf_info *info)
+static int nf_ip_reroute(struct sk_buff *skb,
+                        const struct nf_queue_entry *entry)
 {
-       const struct ip_rt_info *rt_info = nf_info_reroute(info);
+       const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
 
-       if (info->hook == NF_IP_LOCAL_OUT) {
+       if (entry->hook == NF_INET_LOCAL_OUT) {
                const struct iphdr *iph = ip_hdr(skb);
 
                if (!(iph->tos == rt_info->tos
@@ -158,7 +161,7 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
 
        switch (skb->ip_summed) {
        case CHECKSUM_COMPLETE:
-               if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN)
+               if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
                        break;
                if ((protocol == 0 && !csum_fold(skb->csum)) ||
                    !csum_tcpudp_magic(iph->saddr, iph->daddr,
@@ -182,9 +185,15 @@ __sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
 
 EXPORT_SYMBOL(nf_ip_checksum);
 
-static struct nf_afinfo nf_ip_afinfo = {
+static int nf_ip_route(struct dst_entry **dst, struct flowi *fl)
+{
+       return ip_route_output_key(&init_net, (struct rtable **)dst, fl);
+}
+
+static const struct nf_afinfo nf_ip_afinfo = {
        .family         = AF_INET,
        .checksum       = nf_ip_checksum,
+       .route          = nf_ip_route,
        .saveroute      = nf_ip_saveroute,
        .reroute        = nf_ip_reroute,
        .route_key_size = sizeof(struct ip_rt_info),
@@ -202,3 +211,13 @@ static void ipv4_netfilter_fini(void)
 
 module_init(ipv4_netfilter_init);
 module_exit(ipv4_netfilter_fini);
+
+#ifdef CONFIG_SYSCTL
+struct ctl_path nf_net_ipv4_netfilter_sysctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv4", .ctl_name = NET_IPV4, },
+       { .procname = "netfilter", .ctl_name = NET_IPV4_NETFILTER, },
+       { }
+};
+EXPORT_SYMBOL_GPL(nf_net_ipv4_netfilter_sysctl_path);
+#endif /* CONFIG_SYSCTL */
index 9aca9c55687cd6bfd6a96a63bb40d90b8d1f3ba1..9a077cb2479841787936a49c3652d93ac8542ba4 100644 (file)
@@ -8,6 +8,7 @@ menu "IP: Netfilter Configuration"
 config NF_CONNTRACK_IPV4
        tristate "IPv4 connection tracking support (required for NAT)"
        depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        ---help---
          Connection tracking keeps a record of what packets have passed
          through your machine, in order to figure out how they are related
@@ -32,6 +33,7 @@ config NF_CONNTRACK_PROC_COMPAT
 
 config IP_NF_QUEUE
        tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
+       depends on NETFILTER_ADVANCED
        help
          Netfilter has the ability to queue packets to user space: the
          netlink device can be used to access them using this driver.
@@ -44,6 +46,7 @@ config IP_NF_QUEUE
 
 config IP_NF_IPTABLES
        tristate "IP tables support (required for filtering/masq/NAT)"
+       default m if NETFILTER_ADVANCED=n
        select NETFILTER_XTABLES
        help
          iptables is a general, extensible packet identification framework.
@@ -54,27 +57,10 @@ config IP_NF_IPTABLES
          To compile it as a module, choose M here.  If unsure, say N.
 
 # The matches.
-config IP_NF_MATCH_IPRANGE
-       tristate "IP range match support"
-       depends on IP_NF_IPTABLES
-       help
-         This option makes possible to match IP addresses against IP address
-         ranges.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
-config IP_NF_MATCH_TOS
-       tristate "TOS match support"
-       depends on IP_NF_IPTABLES
-       help
-         TOS matching allows you to match packets based on the Type Of
-         Service fields of the IP packet.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_MATCH_RECENT
-       tristate "recent match support"
+       tristate '"recent" match support'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This match is used for creating one or many lists of recently
          used addresses and then matching against that/those list(s).
@@ -85,8 +71,9 @@ config IP_NF_MATCH_RECENT
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP_NF_MATCH_ECN
-       tristate "ECN match support"
+       tristate '"ecn" match support'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `ECN' match, which allows you to match against
          the IPv4 and TCP header ECN fields.
@@ -94,8 +81,9 @@ config IP_NF_MATCH_ECN
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP_NF_MATCH_AH
-       tristate "AH match support"
+       tristate '"ah" match support'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This match extension allows you to match a range of SPIs
          inside AH header of IPSec packets.
@@ -103,30 +91,23 @@ config IP_NF_MATCH_AH
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP_NF_MATCH_TTL
-       tristate "TTL match support"
+       tristate '"ttl" match support'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
          to match packets by their TTL value.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_MATCH_OWNER
-       tristate "Owner match support"
-       depends on IP_NF_IPTABLES
-       help
-         Packet owner matching allows you to match locally-generated packets
-         based on who created them: the user, group, process or session.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_MATCH_ADDRTYPE
-       tristate  'address type match support'
+       tristate '"addrtype" address type match support'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option allows you to match what routing thinks of an address,
          eg. UNICAST, LOCAL, BROADCAST, ...
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
@@ -134,6 +115,7 @@ config IP_NF_MATCH_ADDRTYPE
 config IP_NF_FILTER
        tristate "Packet filtering"
        depends on IP_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          Packet filtering defines a table `filter', which has a series of
          rules for simple packet filtering at local input, forwarding and
@@ -144,6 +126,7 @@ config IP_NF_FILTER
 config IP_NF_TARGET_REJECT
        tristate "REJECT target support"
        depends on IP_NF_FILTER
+       default m if NETFILTER_ADVANCED=n
        help
          The REJECT target allows a filtering rule to specify that an ICMP
          error should be issued in response to an incoming packet, rather
@@ -154,6 +137,7 @@ config IP_NF_TARGET_REJECT
 config IP_NF_TARGET_LOG
        tristate "LOG target support"
        depends on IP_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          This option adds a `LOG' target, which allows you to create rules in
          any iptables table which records the packet header to the syslog.
@@ -163,6 +147,7 @@ config IP_NF_TARGET_LOG
 config IP_NF_TARGET_ULOG
        tristate "ULOG target support"
        depends on IP_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        ---help---
 
          This option enables the old IPv4-only "ipt_ULOG" implementation
@@ -183,6 +168,7 @@ config IP_NF_TARGET_ULOG
 config NF_NAT
        tristate "Full NAT"
        depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
+       default m if NETFILTER_ADVANCED=n
        help
          The Full NAT option allows masquerading, port forwarding and other
          forms of full Network Address Port Translation.  It is controlled by
@@ -198,6 +184,7 @@ config NF_NAT_NEEDED
 config IP_NF_TARGET_MASQUERADE
        tristate "MASQUERADE target support"
        depends on NF_NAT
+       default m if NETFILTER_ADVANCED=n
        help
          Masquerading is a special case of NAT: all outgoing connections are
          changed to seem to come from a particular interface's address, and
@@ -210,6 +197,7 @@ config IP_NF_TARGET_MASQUERADE
 config IP_NF_TARGET_REDIRECT
        tristate "REDIRECT target support"
        depends on NF_NAT
+       depends on NETFILTER_ADVANCED
        help
          REDIRECT is a special case of NAT: all incoming connections are
          mapped onto the incoming interface's address, causing the packets to
@@ -221,6 +209,7 @@ config IP_NF_TARGET_REDIRECT
 config IP_NF_TARGET_NETMAP
        tristate "NETMAP target support"
        depends on NF_NAT
+       depends on NETFILTER_ADVANCED
        help
          NETMAP is an implementation of static 1:1 NAT mapping of network
          addresses. It maps the network address part, while keeping the host
@@ -229,18 +218,10 @@ config IP_NF_TARGET_NETMAP
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_TARGET_SAME
-       tristate "SAME target support (OBSOLETE)"
-       depends on NF_NAT
-       help
-         This option adds a `SAME' target, which works like the standard SNAT
-         target, but attempts to give clients the same IP for all connections.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config NF_NAT_SNMP_BASIC
-       tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && NF_NAT
+       tristate "Basic SNMP-ALG support"
+       depends on NF_NAT
+       depends on NETFILTER_ADVANCED
        ---help---
 
          This module implements an Application Layer Gateway (ALG) for
@@ -304,6 +285,7 @@ config NF_NAT_SIP
 config IP_NF_MANGLE
        tristate "Packet mangling"
        depends on IP_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          This option adds a `mangle' table to iptables: see the man page for
          iptables(8).  This table is used for various packet alterations
@@ -311,19 +293,10 @@ config IP_NF_MANGLE
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_TARGET_TOS
-       tristate "TOS target support"
-       depends on IP_NF_MANGLE
-       help
-         This option adds a `TOS' target, which allows you to create rules in
-         the `mangle' table which alter the Type Of Service field of an IP
-         packet prior to routing.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_TARGET_ECN
        tristate "ECN target support"
        depends on IP_NF_MANGLE
+       depends on NETFILTER_ADVANCED
        ---help---
          This option adds a `ECN' target, which can be used in the iptables mangle
          table.  
@@ -338,6 +311,7 @@ config IP_NF_TARGET_ECN
 config IP_NF_TARGET_TTL
        tristate  'TTL target support'
        depends on IP_NF_MANGLE
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `TTL' target, which enables the user to modify
          the TTL value of the IP header.
@@ -353,6 +327,7 @@ config IP_NF_TARGET_CLUSTERIP
        tristate "CLUSTERIP target support (EXPERIMENTAL)"
        depends on IP_NF_MANGLE && EXPERIMENTAL
        depends on NF_CONNTRACK_IPV4
+       depends on NETFILTER_ADVANCED
        select NF_CONNTRACK_MARK
        help
          The CLUSTERIP target allows you to build load-balancing clusters of
@@ -365,6 +340,7 @@ config IP_NF_TARGET_CLUSTERIP
 config IP_NF_RAW
        tristate  'raw table support (required for NOTRACK/TRACE)'
        depends on IP_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `raw' table to iptables. This table is the very
          first in the netfilter framework and hooks in at the PREROUTING
@@ -377,6 +353,7 @@ config IP_NF_RAW
 config IP_NF_ARPTABLES
        tristate "ARP tables support"
        select NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          arptables is a general, extensible packet identification framework.
          The ARP packet filtering and mangling (manipulation)subsystems
index 7456833d6ade438f3b5c5f478fb6062cdaf5e3a2..0c7dc78a62e99ab6eaf77320a2624024cfa4199c 100644 (file)
@@ -44,10 +44,7 @@ obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
-obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
-obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
 obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
-obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
 
 # targets
@@ -58,8 +55,6 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
-obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o
-obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o
 obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
 obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
 
index 2909c92ecd999b22fc8001d501db48e4882d0eba..b4a810c28ac85c3f79e6e350ea985b8a85ba380d 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/module.h>
 #include <linux/init.h>
-
-#include <asm/uaccess.h>
 #include <linux/mutex.h>
+#include <linux/err.h>
+#include <net/compat.h>
+#include <asm/uaccess.h>
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_arp/arp_tables.h>
@@ -83,7 +84,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
        __be32 src_ipaddr, tgt_ipaddr;
        int i, ret;
 
-#define FWINV(bool,invflg) ((bool) ^ !!(arpinfo->invflags & invflg))
+#define FWINV(bool, invflg) ((bool) ^ !!(arpinfo->invflags & (invflg)))
 
        if (FWINV((arphdr->ar_op & arpinfo->arpop_mask) != arpinfo->arpop,
                  ARPT_INV_ARPOP)) {
@@ -179,6 +180,7 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
        }
 
        return 1;
+#undef FWINV
 }
 
 static inline int arp_checkentry(const struct arpt_arp *arp)
@@ -435,29 +437,9 @@ static int mark_source_chains(struct xt_table_info *newinfo,
        return 1;
 }
 
-static inline int standard_check(const struct arpt_entry_target *t,
-                                unsigned int max_offset)
-{
-       /* Check standard info. */
-       if (t->u.target_size
-           != ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
-               duprintf("arpt_standard_check: target size %u != %Zu\n",
-                        t->u.target_size,
-                        ARPT_ALIGN(sizeof(struct arpt_standard_target)));
-               return 0;
-       }
-
-       return 1;
-}
-
-static struct arpt_target arpt_standard_target;
-
-static inline int check_entry(struct arpt_entry *e, const char *name, unsigned int size,
-                             unsigned int *i)
+static inline int check_entry(struct arpt_entry *e, const char *name)
 {
        struct arpt_entry_target *t;
-       struct arpt_target *target;
-       int ret;
 
        if (!arp_checkentry(&e->arp)) {
                duprintf("arp_tables: arp check failed %p %s.\n", e, name);
@@ -471,35 +453,57 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
        if (e->target_offset + t->u.target_size > e->next_offset)
                return -EINVAL;
 
+       return 0;
+}
+
+static inline int check_target(struct arpt_entry *e, const char *name)
+{
+       struct arpt_entry_target *t;
+       struct arpt_target *target;
+       int ret;
+
+       t = arpt_get_target(e);
+       target = t->u.kernel.target;
+
+       ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
+                             name, e->comefrom, 0, 0);
+       if (!ret && t->u.kernel.target->checkentry
+           && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                              e->comefrom)) {
+               duprintf("arp_tables: check failed for `%s'.\n",
+                        t->u.kernel.target->name);
+               ret = -EINVAL;
+       }
+       return ret;
+}
+
+static inline int
+find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
+                unsigned int *i)
+{
+       struct arpt_entry_target *t;
+       struct arpt_target *target;
+       int ret;
+
+       ret = check_entry(e, name);
+       if (ret)
+               return ret;
+
+       t = arpt_get_target(e);
        target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
                                                        t->u.user.revision),
                                         "arpt_%s", t->u.user.name);
        if (IS_ERR(target) || !target) {
-               duprintf("check_entry: `%s' not found\n", t->u.user.name);
+               duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
                ret = target ? PTR_ERR(target) : -ENOENT;
                goto out;
        }
        t->u.kernel.target = target;
 
-       ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t),
-                             name, e->comefrom, 0, 0);
+       ret = check_target(e, name);
        if (ret)
                goto err;
 
-       if (t->u.kernel.target == &arpt_standard_target) {
-               if (!standard_check(t, size)) {
-                       ret = -EINVAL;
-                       goto err;
-               }
-       } else if (t->u.kernel.target->checkentry
-                  && !t->u.kernel.target->checkentry(name, e, target, t->data,
-                                                     e->comefrom)) {
-               duprintf("arp_tables: check failed for `%s'.\n",
-                        t->u.kernel.target->name);
-               ret = -EINVAL;
-               goto err;
-       }
-
        (*i)++;
        return 0;
 err:
@@ -633,7 +637,7 @@ static int translate_table(const char *name,
        /* Finally, each sanity check must pass */
        i = 0;
        ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
-                                check_entry, name, size, &i);
+                                find_check_entry, name, size, &i);
 
        if (ret != 0) {
                ARPT_ENTRY_ITERATE(entry0, newinfo->size,
@@ -704,16 +708,11 @@ static void get_counters(const struct xt_table_info *t,
        }
 }
 
-static int copy_entries_to_user(unsigned int total_size,
-                               struct arpt_table *table,
-                               void __user *userptr)
+static inline struct xt_counters *alloc_counters(struct arpt_table *table)
 {
-       unsigned int off, num, countersize;
-       struct arpt_entry *e;
+       unsigned int countersize;
        struct xt_counters *counters;
        struct xt_table_info *private = table->private;
-       int ret = 0;
-       void *loc_cpu_entry;
 
        /* We need atomic snapshot of counters: rest doesn't change
         * (other than comefrom, which userspace doesn't care
@@ -723,13 +722,31 @@ static int copy_entries_to_user(unsigned int total_size,
        counters = vmalloc_node(countersize, numa_node_id());
 
        if (counters == NULL)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        /* First, sum counters... */
        write_lock_bh(&table->lock);
        get_counters(private, counters);
        write_unlock_bh(&table->lock);
 
+       return counters;
+}
+
+static int copy_entries_to_user(unsigned int total_size,
+                               struct arpt_table *table,
+                               void __user *userptr)
+{
+       unsigned int off, num;
+       struct arpt_entry *e;
+       struct xt_counters *counters;
+       struct xt_table_info *private = table->private;
+       int ret = 0;
+       void *loc_cpu_entry;
+
+       counters = alloc_counters(table);
+       if (IS_ERR(counters))
+               return PTR_ERR(counters);
+
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        /* ... then copy entire thing ... */
        if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
@@ -767,23 +784,159 @@ static int copy_entries_to_user(unsigned int total_size,
        return ret;
 }
 
-static int get_entries(const struct arpt_get_entries *entries,
-                      struct arpt_get_entries __user *uptr)
+#ifdef CONFIG_COMPAT
+static void compat_standard_from_user(void *dst, void *src)
+{
+       int v = *(compat_int_t *)src;
+
+       if (v > 0)
+               v += xt_compat_calc_jump(NF_ARP, v);
+       memcpy(dst, &v, sizeof(v));
+}
+
+static int compat_standard_to_user(void __user *dst, void *src)
 {
+       compat_int_t cv = *(int *)src;
+
+       if (cv > 0)
+               cv -= xt_compat_calc_jump(NF_ARP, cv);
+       return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
+}
+
+static int compat_calc_entry(struct arpt_entry *e,
+                            const struct xt_table_info *info,
+                            void *base, struct xt_table_info *newinfo)
+{
+       struct arpt_entry_target *t;
+       unsigned int entry_offset;
+       int off, i, ret;
+
+       off = sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry);
+       entry_offset = (void *)e - base;
+
+       t = arpt_get_target(e);
+       off += xt_compat_target_offset(t->u.kernel.target);
+       newinfo->size -= off;
+       ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+               if (info->hook_entry[i] &&
+                   (e < (struct arpt_entry *)(base + info->hook_entry[i])))
+                       newinfo->hook_entry[i] -= off;
+               if (info->underflow[i] &&
+                   (e < (struct arpt_entry *)(base + info->underflow[i])))
+                       newinfo->underflow[i] -= off;
+       }
+       return 0;
+}
+
+static int compat_table_info(const struct xt_table_info *info,
+                            struct xt_table_info *newinfo)
+{
+       void *loc_cpu_entry;
+
+       if (!newinfo || !info)
+               return -EINVAL;
+
+       /* we dont care about newinfo->entries[] */
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
+       loc_cpu_entry = info->entries[raw_smp_processor_id()];
+       return ARPT_ENTRY_ITERATE(loc_cpu_entry, info->size,
+                                 compat_calc_entry, info, loc_cpu_entry,
+                                 newinfo);
+}
+#endif
+
+static int get_info(void __user *user, int *len, int compat)
+{
+       char name[ARPT_TABLE_MAXNAMELEN];
+       struct arpt_table *t;
        int ret;
+
+       if (*len != sizeof(struct arpt_getinfo)) {
+               duprintf("length %u != %Zu\n", *len,
+                        sizeof(struct arpt_getinfo));
+               return -EINVAL;
+       }
+
+       if (copy_from_user(name, user, sizeof(name)) != 0)
+               return -EFAULT;
+
+       name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
+#ifdef CONFIG_COMPAT
+       if (compat)
+               xt_compat_lock(NF_ARP);
+#endif
+       t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+                                   "arptable_%s", name);
+       if (t && !IS_ERR(t)) {
+               struct arpt_getinfo info;
+               struct xt_table_info *private = t->private;
+
+#ifdef CONFIG_COMPAT
+               if (compat) {
+                       struct xt_table_info tmp;
+                       ret = compat_table_info(private, &tmp);
+                       xt_compat_flush_offsets(NF_ARP);
+                       private = &tmp;
+               }
+#endif
+               info.valid_hooks = t->valid_hooks;
+               memcpy(info.hook_entry, private->hook_entry,
+                      sizeof(info.hook_entry));
+               memcpy(info.underflow, private->underflow,
+                      sizeof(info.underflow));
+               info.num_entries = private->number;
+               info.size = private->size;
+               strcpy(info.name, name);
+
+               if (copy_to_user(user, &info, *len) != 0)
+                       ret = -EFAULT;
+               else
+                       ret = 0;
+               xt_table_unlock(t);
+               module_put(t->me);
+       } else
+               ret = t ? PTR_ERR(t) : -ENOENT;
+#ifdef CONFIG_COMPAT
+       if (compat)
+               xt_compat_unlock(NF_ARP);
+#endif
+       return ret;
+}
+
+static int get_entries(struct arpt_get_entries __user *uptr, int *len)
+{
+       int ret;
+       struct arpt_get_entries get;
        struct arpt_table *t;
 
-       t = xt_find_table_lock(NF_ARP, entries->name);
+       if (*len < sizeof(get)) {
+               duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
+               return -EINVAL;
+       }
+       if (copy_from_user(&get, uptr, sizeof(get)) != 0)
+               return -EFAULT;
+       if (*len != sizeof(struct arpt_get_entries) + get.size) {
+               duprintf("get_entries: %u != %Zu\n", *len,
+                        sizeof(struct arpt_get_entries) + get.size);
+               return -EINVAL;
+       }
+
+       t = xt_find_table_lock(NF_ARP, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                duprintf("t->private->number = %u\n",
                         private->number);
-               if (entries->size == private->size)
+               if (get.size == private->size)
                        ret = copy_entries_to_user(private->size,
                                                   t, uptr->entrytable);
                else {
                        duprintf("get_entries: I've got %u not %u!\n",
-                                private->size, entries->size);
+                                private->size, get.size);
                        ret = -EINVAL;
                }
                module_put(t->me);
@@ -794,71 +947,41 @@ static int get_entries(const struct arpt_get_entries *entries,
        return ret;
 }
 
-static int do_replace(void __user *user, unsigned int len)
+static int __do_replace(const char *name, unsigned int valid_hooks,
+                       struct xt_table_info *newinfo,
+                       unsigned int num_counters,
+                       void __user *counters_ptr)
 {
        int ret;
-       struct arpt_replace tmp;
        struct arpt_table *t;
-       struct xt_table_info *newinfo, *oldinfo;
+       struct xt_table_info *oldinfo;
        struct xt_counters *counters;
-       void *loc_cpu_entry, *loc_cpu_old_entry;
-
-       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
-               return -EFAULT;
+       void *loc_cpu_old_entry;
 
-       /* Hack: Causes ipchains to give correct error msg --RR */
-       if (len != sizeof(tmp) + tmp.size)
-               return -ENOPROTOOPT;
-
-       /* overflow check */
-       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
-                       SMP_CACHE_BYTES)
-               return -ENOMEM;
-       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
-               return -ENOMEM;
-
-       newinfo = xt_alloc_table_info(tmp.size);
-       if (!newinfo)
-               return -ENOMEM;
-
-       /* choose the copy that is on our node/cpu */
-       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
-       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
-                          tmp.size) != 0) {
-               ret = -EFAULT;
-               goto free_newinfo;
-       }
-
-       counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters));
+       ret = 0;
+       counters = vmalloc_node(num_counters * sizeof(struct xt_counters),
+                               numa_node_id());
        if (!counters) {
                ret = -ENOMEM;
-               goto free_newinfo;
+               goto out;
        }
 
-       ret = translate_table(tmp.name, tmp.valid_hooks,
-                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
-                             tmp.hook_entry, tmp.underflow);
-       if (ret != 0)
-               goto free_newinfo_counters;
-
-       duprintf("arp_tables: Translated table\n");
-
-       t = try_then_request_module(xt_find_table_lock(NF_ARP, tmp.name),
-                                   "arptable_%s", tmp.name);
+       t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
+                                   "arptable_%s", name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free_newinfo_counters_untrans;
        }
 
        /* You lied! */
-       if (tmp.valid_hooks != t->valid_hooks) {
+       if (valid_hooks != t->valid_hooks) {
                duprintf("Valid hook crap: %08X vs %08X\n",
-                        tmp.valid_hooks, t->valid_hooks);
+                        valid_hooks, t->valid_hooks);
                ret = -EINVAL;
                goto put_module;
        }
 
-       oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret);
+       oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
        if (!oldinfo)
                goto put_module;
 
@@ -876,11 +999,12 @@ static int do_replace(void __user *user, unsigned int len)
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
        loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
-       ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+       ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
+                          NULL);
 
        xt_free_table_info(oldinfo);
-       if (copy_to_user(tmp.counters, counters,
-                        sizeof(struct xt_counters) * tmp.num_counters) != 0)
+       if (copy_to_user(counters_ptr, counters,
+                        sizeof(struct xt_counters) * num_counters) != 0)
                ret = -EFAULT;
        vfree(counters);
        xt_table_unlock(t);
@@ -890,9 +1014,53 @@ static int do_replace(void __user *user, unsigned int len)
        module_put(t->me);
        xt_table_unlock(t);
  free_newinfo_counters_untrans:
-       ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
- free_newinfo_counters:
        vfree(counters);
+ out:
+       return ret;
+}
+
+static int do_replace(void __user *user, unsigned int len)
+{
+       int ret;
+       struct arpt_replace tmp;
+       struct xt_table_info *newinfo;
+       void *loc_cpu_entry;
+
+       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+               return -EFAULT;
+
+       /* overflow check */
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
+       newinfo = xt_alloc_table_info(tmp.size);
+       if (!newinfo)
+               return -ENOMEM;
+
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
+                          tmp.size) != 0) {
+               ret = -EFAULT;
+               goto free_newinfo;
+       }
+
+       ret = translate_table(tmp.name, tmp.valid_hooks,
+                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
+                             tmp.hook_entry, tmp.underflow);
+       if (ret != 0)
+               goto free_newinfo;
+
+       duprintf("arp_tables: Translated table\n");
+
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, tmp.counters);
+       if (ret)
+               goto free_newinfo_untrans;
+       return 0;
+
+ free_newinfo_untrans:
+       ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo:
        xt_free_table_info(newinfo);
        return ret;
@@ -912,31 +1080,59 @@ static inline int add_counter_to_entry(struct arpt_entry *e,
        return 0;
 }
 
-static int do_add_counters(void __user *user, unsigned int len)
+static int do_add_counters(void __user *user, unsigned int len, int compat)
 {
        unsigned int i;
-       struct xt_counters_info tmp, *paddc;
+       struct xt_counters_info tmp;
+       struct xt_counters *paddc;
+       unsigned int num_counters;
+       char *name;
+       int size;
+       void *ptmp;
        struct arpt_table *t;
        struct xt_table_info *private;
        int ret = 0;
        void *loc_cpu_entry;
+#ifdef CONFIG_COMPAT
+       struct compat_xt_counters_info compat_tmp;
 
-       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+       if (compat) {
+               ptmp = &compat_tmp;
+               size = sizeof(struct compat_xt_counters_info);
+       } else
+#endif
+       {
+               ptmp = &tmp;
+               size = sizeof(struct xt_counters_info);
+       }
+
+       if (copy_from_user(ptmp, user, size) != 0)
                return -EFAULT;
 
-       if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters))
+#ifdef CONFIG_COMPAT
+       if (compat) {
+               num_counters = compat_tmp.num_counters;
+               name = compat_tmp.name;
+       } else
+#endif
+       {
+               num_counters = tmp.num_counters;
+               name = tmp.name;
+       }
+
+       if (len != size + num_counters * sizeof(struct xt_counters))
                return -EINVAL;
 
-       paddc = vmalloc(len);
+       paddc = vmalloc_node(len - size, numa_node_id());
        if (!paddc)
                return -ENOMEM;
 
-       if (copy_from_user(paddc, user, len) != 0) {
+       if (copy_from_user(paddc, user + size, len - size) != 0) {
                ret = -EFAULT;
                goto free;
        }
 
-       t = xt_find_table_lock(NF_ARP, tmp.name);
+       t = xt_find_table_lock(NF_ARP, name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free;
@@ -944,7 +1140,7 @@ static int do_add_counters(void __user *user, unsigned int len)
 
        write_lock_bh(&t->lock);
        private = t->private;
-       if (private->number != tmp.num_counters) {
+       if (private->number != num_counters) {
                ret = -EINVAL;
                goto unlock_up_free;
        }
@@ -955,7 +1151,7 @@ static int do_add_counters(void __user *user, unsigned int len)
        ARPT_ENTRY_ITERATE(loc_cpu_entry,
                           private->size,
                           add_counter_to_entry,
-                          paddc->counters,
+                          paddc,
                           &i);
  unlock_up_free:
        write_unlock_bh(&t->lock);
@@ -967,7 +1163,329 @@ static int do_add_counters(void __user *user, unsigned int len)
        return ret;
 }
 
-static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
+#ifdef CONFIG_COMPAT
+static inline int
+compat_release_entry(struct compat_arpt_entry *e, unsigned int *i)
+{
+       struct arpt_entry_target *t;
+
+       if (i && (*i)-- == 0)
+               return 1;
+
+       t = compat_arpt_get_target(e);
+       module_put(t->u.kernel.target->me);
+       return 0;
+}
+
+static inline int
+check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
+                                 struct xt_table_info *newinfo,
+                                 unsigned int *size,
+                                 unsigned char *base,
+                                 unsigned char *limit,
+                                 unsigned int *hook_entries,
+                                 unsigned int *underflows,
+                                 unsigned int *i,
+                                 const char *name)
+{
+       struct arpt_entry_target *t;
+       struct xt_target *target;
+       unsigned int entry_offset;
+       int ret, off, h;
+
+       duprintf("check_compat_entry_size_and_hooks %p\n", e);
+       if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0
+           || (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) {
+               duprintf("Bad offset %p, limit = %p\n", e, limit);
+               return -EINVAL;
+       }
+
+       if (e->next_offset < sizeof(struct compat_arpt_entry) +
+                            sizeof(struct compat_xt_entry_target)) {
+               duprintf("checking: element %p size %u\n",
+                        e, e->next_offset);
+               return -EINVAL;
+       }
+
+       /* For purposes of check_entry casting the compat entry is fine */
+       ret = check_entry((struct arpt_entry *)e, name);
+       if (ret)
+               return ret;
+
+       off = sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry);
+       entry_offset = (void *)e - (void *)base;
+
+       t = compat_arpt_get_target(e);
+       target = try_then_request_module(xt_find_target(NF_ARP,
+                                                       t->u.user.name,
+                                                       t->u.user.revision),
+                                        "arpt_%s", t->u.user.name);
+       if (IS_ERR(target) || !target) {
+               duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
+                        t->u.user.name);
+               ret = target ? PTR_ERR(target) : -ENOENT;
+               goto out;
+       }
+       t->u.kernel.target = target;
+
+       off += xt_compat_target_offset(target);
+       *size += off;
+       ret = xt_compat_add_offset(NF_ARP, entry_offset, off);
+       if (ret)
+               goto release_target;
+
+       /* Check hooks & underflows */
+       for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+               if ((unsigned char *)e - base == hook_entries[h])
+                       newinfo->hook_entry[h] = hook_entries[h];
+               if ((unsigned char *)e - base == underflows[h])
+                       newinfo->underflow[h] = underflows[h];
+       }
+
+       /* Clear counters and comefrom */
+       memset(&e->counters, 0, sizeof(e->counters));
+       e->comefrom = 0;
+
+       (*i)++;
+       return 0;
+
+release_target:
+       module_put(t->u.kernel.target->me);
+out:
+       return ret;
+}
+
+static int
+compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
+                           unsigned int *size, const char *name,
+                           struct xt_table_info *newinfo, unsigned char *base)
+{
+       struct arpt_entry_target *t;
+       struct xt_target *target;
+       struct arpt_entry *de;
+       unsigned int origsize;
+       int ret, h;
+
+       ret = 0;
+       origsize = *size;
+       de = (struct arpt_entry *)*dstptr;
+       memcpy(de, e, sizeof(struct arpt_entry));
+       memcpy(&de->counters, &e->counters, sizeof(e->counters));
+
+       *dstptr += sizeof(struct arpt_entry);
+       *size += sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry);
+
+       de->target_offset = e->target_offset - (origsize - *size);
+       t = compat_arpt_get_target(e);
+       target = t->u.kernel.target;
+       xt_compat_target_from_user(t, dstptr, size);
+
+       de->next_offset = e->next_offset - (origsize - *size);
+       for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+               if ((unsigned char *)de - base < newinfo->hook_entry[h])
+                       newinfo->hook_entry[h] -= origsize - *size;
+               if ((unsigned char *)de - base < newinfo->underflow[h])
+                       newinfo->underflow[h] -= origsize - *size;
+       }
+       return ret;
+}
+
+static inline int compat_check_entry(struct arpt_entry *e, const char *name,
+                                    unsigned int *i)
+{
+       int ret;
+
+       ret = check_target(e, name);
+       if (ret)
+               return ret;
+
+       (*i)++;
+       return 0;
+}
+
+static int translate_compat_table(const char *name,
+                                 unsigned int valid_hooks,
+                                 struct xt_table_info **pinfo,
+                                 void **pentry0,
+                                 unsigned int total_size,
+                                 unsigned int number,
+                                 unsigned int *hook_entries,
+                                 unsigned int *underflows)
+{
+       unsigned int i, j;
+       struct xt_table_info *newinfo, *info;
+       void *pos, *entry0, *entry1;
+       unsigned int size;
+       int ret;
+
+       info = *pinfo;
+       entry0 = *pentry0;
+       size = total_size;
+       info->number = number;
+
+       /* Init all hooks to impossible value. */
+       for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+               info->hook_entry[i] = 0xFFFFFFFF;
+               info->underflow[i] = 0xFFFFFFFF;
+       }
+
+       duprintf("translate_compat_table: size %u\n", info->size);
+       j = 0;
+       xt_compat_lock(NF_ARP);
+       /* Walk through entries, checking offsets. */
+       ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
+                                       check_compat_entry_size_and_hooks,
+                                       info, &size, entry0,
+                                       entry0 + total_size,
+                                       hook_entries, underflows, &j, name);
+       if (ret != 0)
+               goto out_unlock;
+
+       ret = -EINVAL;
+       if (j != number) {
+               duprintf("translate_compat_table: %u not %u entries\n",
+                        j, number);
+               goto out_unlock;
+       }
+
+       /* Check hooks all assigned */
+       for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+               /* Only hooks which are valid */
+               if (!(valid_hooks & (1 << i)))
+                       continue;
+               if (info->hook_entry[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid hook entry %u %u\n",
+                                i, hook_entries[i]);
+                       goto out_unlock;
+               }
+               if (info->underflow[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid underflow %u %u\n",
+                                i, underflows[i]);
+                       goto out_unlock;
+               }
+       }
+
+       ret = -ENOMEM;
+       newinfo = xt_alloc_table_info(size);
+       if (!newinfo)
+               goto out_unlock;
+
+       newinfo->number = number;
+       for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+               newinfo->hook_entry[i] = info->hook_entry[i];
+               newinfo->underflow[i] = info->underflow[i];
+       }
+       entry1 = newinfo->entries[raw_smp_processor_id()];
+       pos = entry1;
+       size = total_size;
+       ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
+                                       compat_copy_entry_from_user,
+                                       &pos, &size, name, newinfo, entry1);
+       xt_compat_flush_offsets(NF_ARP);
+       xt_compat_unlock(NF_ARP);
+       if (ret)
+               goto free_newinfo;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry1))
+               goto free_newinfo;
+
+       i = 0;
+       ret = ARPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
+                                name, &i);
+       if (ret) {
+               j -= i;
+               COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
+                                                  compat_release_entry, &j);
+               ARPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
+               xt_free_table_info(newinfo);
+               return ret;
+       }
+
+       /* And one copy for every other CPU */
+       for_each_possible_cpu(i)
+               if (newinfo->entries[i] && newinfo->entries[i] != entry1)
+                       memcpy(newinfo->entries[i], entry1, newinfo->size);
+
+       *pinfo = newinfo;
+       *pentry0 = entry1;
+       xt_free_table_info(info);
+       return 0;
+
+free_newinfo:
+       xt_free_table_info(newinfo);
+out:
+       COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
+       return ret;
+out_unlock:
+       xt_compat_flush_offsets(NF_ARP);
+       xt_compat_unlock(NF_ARP);
+       goto out;
+}
+
+struct compat_arpt_replace {
+       char                            name[ARPT_TABLE_MAXNAMELEN];
+       u32                             valid_hooks;
+       u32                             num_entries;
+       u32                             size;
+       u32                             hook_entry[NF_ARP_NUMHOOKS];
+       u32                             underflow[NF_ARP_NUMHOOKS];
+       u32                             num_counters;
+       compat_uptr_t                   counters;
+       struct compat_arpt_entry        entries[0];
+};
+
+static int compat_do_replace(void __user *user, unsigned int len)
+{
+       int ret;
+       struct compat_arpt_replace tmp;
+       struct xt_table_info *newinfo;
+       void *loc_cpu_entry;
+
+       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+               return -EFAULT;
+
+       /* overflow check */
+       if (tmp.size >= INT_MAX / num_possible_cpus())
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
+       newinfo = xt_alloc_table_info(tmp.size);
+       if (!newinfo)
+               return -ENOMEM;
+
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp), tmp.size) != 0) {
+               ret = -EFAULT;
+               goto free_newinfo;
+       }
+
+       ret = translate_compat_table(tmp.name, tmp.valid_hooks,
+                                    &newinfo, &loc_cpu_entry, tmp.size,
+                                    tmp.num_entries, tmp.hook_entry,
+                                    tmp.underflow);
+       if (ret != 0)
+               goto free_newinfo;
+
+       duprintf("compat_do_replace: Translated table\n");
+
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, compat_ptr(tmp.counters));
+       if (ret)
+               goto free_newinfo_untrans;
+       return 0;
+
+ free_newinfo_untrans:
+       ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
+ free_newinfo:
+       xt_free_table_info(newinfo);
+       return ret;
+}
+
+static int compat_do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user,
+                                 unsigned int len)
 {
        int ret;
 
@@ -976,11 +1494,11 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
 
        switch (cmd) {
        case ARPT_SO_SET_REPLACE:
-               ret = do_replace(user, len);
+               ret = compat_do_replace(user, len);
                break;
 
        case ARPT_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len);
+               ret = do_add_counters(user, len, 1);
                break;
 
        default:
@@ -991,74 +1509,190 @@ static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned
        return ret;
 }
 
-static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr,
+                                    compat_uint_t *size,
+                                    struct xt_counters *counters,
+                                    unsigned int *i)
 {
+       struct arpt_entry_target *t;
+       struct compat_arpt_entry __user *ce;
+       u_int16_t target_offset, next_offset;
+       compat_uint_t origsize;
        int ret;
 
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
+       ret = -EFAULT;
+       origsize = *size;
+       ce = (struct compat_arpt_entry __user *)*dstptr;
+       if (copy_to_user(ce, e, sizeof(struct arpt_entry)))
+               goto out;
 
-       switch (cmd) {
-       case ARPT_SO_GET_INFO: {
-               char name[ARPT_TABLE_MAXNAMELEN];
-               struct arpt_table *t;
+       if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i])))
+               goto out;
+
+       *dstptr += sizeof(struct compat_arpt_entry);
+       *size -= sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry);
 
-               if (*len != sizeof(struct arpt_getinfo)) {
-                       duprintf("length %u != %Zu\n", *len,
-                                sizeof(struct arpt_getinfo));
+       target_offset = e->target_offset - (origsize - *size);
+
+       t = arpt_get_target(e);
+       ret = xt_compat_target_to_user(t, dstptr, size);
+       if (ret)
+               goto out;
+       ret = -EFAULT;
+       next_offset = e->next_offset - (origsize - *size);
+       if (put_user(target_offset, &ce->target_offset))
+               goto out;
+       if (put_user(next_offset, &ce->next_offset))
+               goto out;
+
+       (*i)++;
+       return 0;
+out:
+       return ret;
+}
+
+static int compat_copy_entries_to_user(unsigned int total_size,
+                                      struct arpt_table *table,
+                                      void __user *userptr)
+{
+       struct xt_counters *counters;
+       struct xt_table_info *private = table->private;
+       void __user *pos;
+       unsigned int size;
+       int ret = 0;
+       void *loc_cpu_entry;
+       unsigned int i = 0;
+
+       counters = alloc_counters(table);
+       if (IS_ERR(counters))
+               return PTR_ERR(counters);
+
+       /* choose the copy on our node/cpu */
+       loc_cpu_entry = private->entries[raw_smp_processor_id()];
+       pos = userptr;
+       size = total_size;
+       ret = ARPT_ENTRY_ITERATE(loc_cpu_entry, total_size,
+                                compat_copy_entry_to_user,
+                                &pos, &size, counters, &i);
+       vfree(counters);
+       return ret;
+}
+
+struct compat_arpt_get_entries {
+       char name[ARPT_TABLE_MAXNAMELEN];
+       compat_uint_t size;
+       struct compat_arpt_entry entrytable[0];
+};
+
+static int compat_get_entries(struct compat_arpt_get_entries __user *uptr,
+                             int *len)
+{
+       int ret;
+       struct compat_arpt_get_entries get;
+       struct arpt_table *t;
+
+       if (*len < sizeof(get)) {
+               duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
+               return -EINVAL;
+       }
+       if (copy_from_user(&get, uptr, sizeof(get)) != 0)
+               return -EFAULT;
+       if (*len != sizeof(struct compat_arpt_get_entries) + get.size) {
+               duprintf("compat_get_entries: %u != %zu\n",
+                        *len, sizeof(get) + get.size);
+               return -EINVAL;
+       }
+
+       xt_compat_lock(NF_ARP);
+       t = xt_find_table_lock(NF_ARP, get.name);
+       if (t && !IS_ERR(t)) {
+               struct xt_table_info *private = t->private;
+               struct xt_table_info info;
+
+               duprintf("t->private->number = %u\n", private->number);
+               ret = compat_table_info(private, &info);
+               if (!ret && get.size == info.size) {
+                       ret = compat_copy_entries_to_user(private->size,
+                                                         t, uptr->entrytable);
+               } else if (!ret) {
+                       duprintf("compat_get_entries: I've got %u not %u!\n",
+                                private->size, get.size);
                        ret = -EINVAL;
-                       break;
                }
+               xt_compat_flush_offsets(NF_ARP);
+               module_put(t->me);
+               xt_table_unlock(t);
+       } else
+               ret = t ? PTR_ERR(t) : -ENOENT;
 
-               if (copy_from_user(name, user, sizeof(name)) != 0) {
-                       ret = -EFAULT;
-                       break;
-               }
-               name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
-
-               t = try_then_request_module(xt_find_table_lock(NF_ARP, name),
-                                           "arptable_%s", name);
-               if (t && !IS_ERR(t)) {
-                       struct arpt_getinfo info;
-                       struct xt_table_info *private = t->private;
-
-                       info.valid_hooks = t->valid_hooks;
-                       memcpy(info.hook_entry, private->hook_entry,
-                              sizeof(info.hook_entry));
-                       memcpy(info.underflow, private->underflow,
-                              sizeof(info.underflow));
-                       info.num_entries = private->number;
-                       info.size = private->size;
-                       strcpy(info.name, name);
-
-                       if (copy_to_user(user, &info, *len) != 0)
-                               ret = -EFAULT;
-                       else
-                               ret = 0;
-                       xt_table_unlock(t);
-                       module_put(t->me);
-               } else
-                       ret = t ? PTR_ERR(t) : -ENOENT;
+       xt_compat_unlock(NF_ARP);
+       return ret;
+}
+
+static int do_arpt_get_ctl(struct sock *, int, void __user *, int *);
+
+static int compat_do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user,
+                                 int *len)
+{
+       int ret;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case ARPT_SO_GET_INFO:
+               ret = get_info(user, len, 1);
+               break;
+       case ARPT_SO_GET_ENTRIES:
+               ret = compat_get_entries(user, len);
+               break;
+       default:
+               ret = do_arpt_get_ctl(sk, cmd, user, len);
        }
-       break;
+       return ret;
+}
+#endif
 
-       case ARPT_SO_GET_ENTRIES: {
-               struct arpt_get_entries get;
+static int do_arpt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
+{
+       int ret;
 
-               if (*len < sizeof(get)) {
-                       duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
-                       ret = -EINVAL;
-               } else if (copy_from_user(&get, user, sizeof(get)) != 0) {
-                       ret = -EFAULT;
-               } else if (*len != sizeof(struct arpt_get_entries) + get.size) {
-                       duprintf("get_entries: %u != %Zu\n", *len,
-                                sizeof(struct arpt_get_entries) + get.size);
-                       ret = -EINVAL;
-               } else
-                       ret = get_entries(&get, user);
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case ARPT_SO_SET_REPLACE:
+               ret = do_replace(user, len);
+               break;
+
+       case ARPT_SO_SET_ADD_COUNTERS:
+               ret = do_add_counters(user, len, 0);
                break;
+
+       default:
+               duprintf("do_arpt_set_ctl:  unknown request %i\n", cmd);
+               ret = -EINVAL;
        }
 
+       return ret;
+}
+
+static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+{
+       int ret;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case ARPT_SO_GET_INFO:
+               ret = get_info(user, len, 0);
+               break;
+
+       case ARPT_SO_GET_ENTRIES:
+               ret = get_entries(user, len);
+               break;
+
        case ARPT_SO_GET_REVISION_TARGET: {
                struct xt_get_revision rev;
 
@@ -1090,7 +1724,7 @@ int arpt_register_table(struct arpt_table *table,
 {
        int ret;
        struct xt_table_info *newinfo;
-       static struct xt_table_info bootstrap
+       struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
 
@@ -1144,6 +1778,11 @@ static struct arpt_target arpt_standard_target __read_mostly = {
        .name           = ARPT_STANDARD_TARGET,
        .targetsize     = sizeof(int),
        .family         = NF_ARP,
+#ifdef CONFIG_COMPAT
+       .compatsize     = sizeof(compat_int_t),
+       .compat_from_user = compat_standard_from_user,
+       .compat_to_user = compat_standard_to_user,
+#endif
 };
 
 static struct arpt_target arpt_error_target __read_mostly = {
@@ -1158,9 +1797,15 @@ static struct nf_sockopt_ops arpt_sockopts = {
        .set_optmin     = ARPT_BASE_CTL,
        .set_optmax     = ARPT_SO_SET_MAX+1,
        .set            = do_arpt_set_ctl,
+#ifdef CONFIG_COMPAT
+       .compat_set     = compat_do_arpt_set_ctl,
+#endif
        .get_optmin     = ARPT_BASE_CTL,
        .get_optmax     = ARPT_SO_GET_MAX+1,
        .get            = do_arpt_get_ctl,
+#ifdef CONFIG_COMPAT
+       .compat_get     = compat_do_arpt_get_ctl,
+#endif
        .owner          = THIS_MODULE,
 };
 
index 302d3da5f696ea6f57f4c09fc403fb8f43c3df6c..7201511d54d2dbc0da216b4ae8ff04d0483dd733 100644 (file)
@@ -64,7 +64,7 @@ static unsigned int arpt_hook(unsigned int hook,
        return arpt_do_table(skb, hook, in, out, &packet_filter);
 }
 
-static struct nf_hook_ops arpt_ops[] = {
+static struct nf_hook_ops arpt_ops[] __read_mostly = {
        {
                .hook           = arpt_hook,
                .owner          = THIS_MODULE,
index 14d64a383db1a7223ed321e5dedfbc1942af1095..5109839da222b28f6f1c255d16f45d729cf87ff2 100644 (file)
 #include <net/net_namespace.h>
 #include <net/sock.h>
 #include <net/route.h>
+#include <net/netfilter/nf_queue.h>
+#include <net/ip.h>
 
 #define IPQ_QMAX_DEFAULT 1024
 #define IPQ_PROC_FS_NAME "ip_queue"
 #define NET_IPQ_QMAX 2088
 #define NET_IPQ_QMAX_NAME "ip_queue_maxlen"
 
-struct ipq_queue_entry {
-       struct list_head list;
-       struct nf_info *info;
-       struct sk_buff *skb;
-};
-
-typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long);
+typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long);
 
 static unsigned char copy_mode __read_mostly = IPQ_COPY_NONE;
 static unsigned int queue_maxlen __read_mostly = IPQ_QMAX_DEFAULT;
@@ -54,76 +50,13 @@ static struct sock *ipqnl __read_mostly;
 static LIST_HEAD(queue_list);
 static DEFINE_MUTEX(ipqnl_mutex);
 
-static void
-ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
-{
-       /* TCP input path (and probably other bits) assume to be called
-        * from softirq context, not from syscall, like ipq_issue_verdict is
-        * called.  TCP input path deadlocks with locks taken from timer
-        * softirq, e.g.  We therefore emulate this by local_bh_disable() */
-
-       local_bh_disable();
-       nf_reinject(entry->skb, entry->info, verdict);
-       local_bh_enable();
-
-       kfree(entry);
-}
-
 static inline void
-__ipq_enqueue_entry(struct ipq_queue_entry *entry)
+__ipq_enqueue_entry(struct nf_queue_entry *entry)
 {
-       list_add(&entry->list, &queue_list);
+       list_add_tail(&entry->list, &queue_list);
        queue_total++;
 }
 
-/*
- * Find and return a queued entry matched by cmpfn, or return the last
- * entry if cmpfn is NULL.
- */
-static inline struct ipq_queue_entry *
-__ipq_find_entry(ipq_cmpfn cmpfn, unsigned long data)
-{
-       struct list_head *p;
-
-       list_for_each_prev(p, &queue_list) {
-               struct ipq_queue_entry *entry = (struct ipq_queue_entry *)p;
-
-               if (!cmpfn || cmpfn(entry, data))
-                       return entry;
-       }
-       return NULL;
-}
-
-static inline void
-__ipq_dequeue_entry(struct ipq_queue_entry *entry)
-{
-       list_del(&entry->list);
-       queue_total--;
-}
-
-static inline struct ipq_queue_entry *
-__ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
-{
-       struct ipq_queue_entry *entry;
-
-       entry = __ipq_find_entry(cmpfn, data);
-       if (entry == NULL)
-               return NULL;
-
-       __ipq_dequeue_entry(entry);
-       return entry;
-}
-
-
-static inline void
-__ipq_flush(int verdict)
-{
-       struct ipq_queue_entry *entry;
-
-       while ((entry = __ipq_find_dequeue_entry(NULL, 0)))
-               ipq_issue_verdict(entry, verdict);
-}
-
 static inline int
 __ipq_set_mode(unsigned char mode, unsigned int range)
 {
@@ -150,36 +83,64 @@ __ipq_set_mode(unsigned char mode, unsigned int range)
        return status;
 }
 
+static void __ipq_flush(ipq_cmpfn cmpfn, unsigned long data);
+
 static inline void
 __ipq_reset(void)
 {
        peer_pid = 0;
        net_disable_timestamp();
        __ipq_set_mode(IPQ_COPY_NONE, 0);
-       __ipq_flush(NF_DROP);
+       __ipq_flush(NULL, 0);
 }
 
-static struct ipq_queue_entry *
-ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
+static struct nf_queue_entry *
+ipq_find_dequeue_entry(unsigned long id)
 {
-       struct ipq_queue_entry *entry;
+       struct nf_queue_entry *entry = NULL, *i;
 
        write_lock_bh(&queue_lock);
-       entry = __ipq_find_dequeue_entry(cmpfn, data);
+
+       list_for_each_entry(i, &queue_list, list) {
+               if ((unsigned long)i == id) {
+                       entry = i;
+                       break;
+               }
+       }
+
+       if (entry) {
+               list_del(&entry->list);
+               queue_total--;
+       }
+
        write_unlock_bh(&queue_lock);
        return entry;
 }
 
 static void
-ipq_flush(int verdict)
+__ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
+{
+       struct nf_queue_entry *entry, *next;
+
+       list_for_each_entry_safe(entry, next, &queue_list, list) {
+               if (!cmpfn || cmpfn(entry, data)) {
+                       list_del(&entry->list);
+                       queue_total--;
+                       nf_reinject(entry, NF_DROP);
+               }
+       }
+}
+
+static void
+ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
 {
        write_lock_bh(&queue_lock);
-       __ipq_flush(verdict);
+       __ipq_flush(cmpfn, data);
        write_unlock_bh(&queue_lock);
 }
 
 static struct sk_buff *
-ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
+ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 {
        sk_buff_data_t old_tail;
        size_t size = 0;
@@ -236,20 +197,20 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
        pmsg->timestamp_sec   = tv.tv_sec;
        pmsg->timestamp_usec  = tv.tv_usec;
        pmsg->mark            = entry->skb->mark;
-       pmsg->hook            = entry->info->hook;
+       pmsg->hook            = entry->hook;
        pmsg->hw_protocol     = entry->skb->protocol;
 
-       if (entry->info->indev)
-               strcpy(pmsg->indev_name, entry->info->indev->name);
+       if (entry->indev)
+               strcpy(pmsg->indev_name, entry->indev->name);
        else
                pmsg->indev_name[0] = '\0';
 
-       if (entry->info->outdev)
-               strcpy(pmsg->outdev_name, entry->info->outdev->name);
+       if (entry->outdev)
+               strcpy(pmsg->outdev_name, entry->outdev->name);
        else
                pmsg->outdev_name[0] = '\0';
 
-       if (entry->info->indev && entry->skb->dev) {
+       if (entry->indev && entry->skb->dev) {
                pmsg->hw_type = entry->skb->dev->type;
                pmsg->hw_addrlen = dev_parse_header(entry->skb,
                                                    pmsg->hw_addr);
@@ -271,28 +232,17 @@ nlmsg_failure:
 }
 
 static int
-ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
-                  unsigned int queuenum, void *data)
+ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
 {
        int status = -EINVAL;
        struct sk_buff *nskb;
-       struct ipq_queue_entry *entry;
 
        if (copy_mode == IPQ_COPY_NONE)
                return -EAGAIN;
 
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       if (entry == NULL) {
-               printk(KERN_ERR "ip_queue: OOM in ipq_enqueue_packet()\n");
-               return -ENOMEM;
-       }
-
-       entry->info = info;
-       entry->skb = skb;
-
        nskb = ipq_build_packet_message(entry, &status);
        if (nskb == NULL)
-               goto err_out_free;
+               return status;
 
        write_lock_bh(&queue_lock);
 
@@ -326,14 +276,11 @@ err_out_free_nskb:
 
 err_out_unlock:
        write_unlock_bh(&queue_lock);
-
-err_out_free:
-       kfree(entry);
        return status;
 }
 
 static int
-ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
+ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
 {
        int diff;
        int err;
@@ -368,21 +315,15 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
        return 0;
 }
 
-static inline int
-id_cmp(struct ipq_queue_entry *e, unsigned long id)
-{
-       return (id == (unsigned long )e);
-}
-
 static int
 ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
 {
-       struct ipq_queue_entry *entry;
+       struct nf_queue_entry *entry;
 
        if (vmsg->value > NF_MAX_VERDICT)
                return -EINVAL;
 
-       entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
+       entry = ipq_find_dequeue_entry(vmsg->id);
        if (entry == NULL)
                return -ENOENT;
        else {
@@ -392,7 +333,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
                        if (ipq_mangle_ipv4(vmsg, entry) < 0)
                                verdict = NF_DROP;
 
-               ipq_issue_verdict(entry, verdict);
+               nf_reinject(entry, verdict);
                return 0;
        }
 }
@@ -437,13 +378,13 @@ ipq_receive_peer(struct ipq_peer_msg *pmsg,
 }
 
 static int
-dev_cmp(struct ipq_queue_entry *entry, unsigned long ifindex)
+dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
 {
-       if (entry->info->indev)
-               if (entry->info->indev->ifindex == ifindex)
+       if (entry->indev)
+               if (entry->indev->ifindex == ifindex)
                        return 1;
-       if (entry->info->outdev)
-               if (entry->info->outdev->ifindex == ifindex)
+       if (entry->outdev)
+               if (entry->outdev->ifindex == ifindex)
                        return 1;
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (entry->skb->nf_bridge) {
@@ -461,10 +402,7 @@ dev_cmp(struct ipq_queue_entry *entry, unsigned long ifindex)
 static void
 ipq_dev_drop(int ifindex)
 {
-       struct ipq_queue_entry *entry;
-
-       while ((entry = ipq_find_dequeue_entry(dev_cmp, ifindex)) != NULL)
-               ipq_issue_verdict(entry, NF_DROP);
+       ipq_flush(dev_cmp, ifindex);
 }
 
 #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
@@ -588,26 +526,6 @@ static ctl_table ipq_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table ipq_dir_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = ipq_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipq_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipq_dir_table
-       },
-       { .ctl_name = 0 }
-};
-
 static int ip_queue_show(struct seq_file *m, void *v)
 {
        read_lock_bh(&queue_lock);
@@ -645,7 +563,7 @@ static const struct file_operations ip_queue_proc_fops = {
        .owner          = THIS_MODULE,
 };
 
-static struct nf_queue_handler nfqh = {
+static const struct nf_queue_handler nfqh = {
        .name   = "ip_queue",
        .outfn  = &ipq_enqueue_packet,
 };
@@ -673,7 +591,7 @@ static int __init ip_queue_init(void)
        }
 
        register_netdevice_notifier(&ipq_dev_notifier);
-       ipq_sysctl_header = register_sysctl_table(ipq_root_table);
+       ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table);
 
        status = nf_register_queue_handler(PF_INET, &nfqh);
        if (status < 0) {
@@ -687,7 +605,7 @@ cleanup_sysctl:
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 cleanup_ipqnl:
-       sock_release(ipqnl->sk_socket);
+       netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
 
@@ -700,13 +618,13 @@ static void __exit ip_queue_fini(void)
 {
        nf_unregister_queue_handlers(&nfqh);
        synchronize_net();
-       ipq_flush(NF_DROP);
+       ipq_flush(NULL, 0);
 
        unregister_sysctl_table(ipq_sysctl_header);
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
-       sock_release(ipqnl->sk_socket);
+       netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
 
index b9b189c262080cdfe0612f5b266c5c475939a563..982b7f9862918cd3c25d1ad9e11c95985fc2e459 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
+#include <net/netfilter/nf_log.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
@@ -74,7 +75,8 @@ do {                                                          \
    Hence the start of any table is given by get_table() below.  */
 
 /* Returns whether matches rule or not. */
-static inline int
+/* Performance critical - called for every packet */
+static inline bool
 ip_packet_match(const struct iphdr *ip,
                const char *indev,
                const char *outdev,
@@ -84,7 +86,7 @@ ip_packet_match(const struct iphdr *ip,
        size_t i;
        unsigned long ret;
 
-#define FWINV(bool,invflg) ((bool) ^ !!(ipinfo->invflags & invflg))
+#define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
 
        if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
                  IPT_INV_SRCIP)
@@ -102,7 +104,7 @@ ip_packet_match(const struct iphdr *ip,
                        NIPQUAD(ipinfo->dmsk.s_addr),
                        NIPQUAD(ipinfo->dst.s_addr),
                        ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
-               return 0;
+               return false;
        }
 
        /* Look for ifname matches; this should unroll nicely. */
@@ -116,7 +118,7 @@ ip_packet_match(const struct iphdr *ip,
                dprintf("VIA in mismatch (%s vs %s).%s\n",
                        indev, ipinfo->iniface,
                        ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
-               return 0;
+               return false;
        }
 
        for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
@@ -129,7 +131,7 @@ ip_packet_match(const struct iphdr *ip,
                dprintf("VIA out mismatch (%s vs %s).%s\n",
                        outdev, ipinfo->outiface,
                        ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
-               return 0;
+               return false;
        }
 
        /* Check specific protocol */
@@ -138,7 +140,7 @@ ip_packet_match(const struct iphdr *ip,
                dprintf("Packet protocol %hi does not match %hi.%s\n",
                        ip->protocol, ipinfo->proto,
                        ipinfo->invflags&IPT_INV_PROTO ? " (INV)":"");
-               return 0;
+               return false;
        }
 
        /* If we have a fragment rule but the packet is not a fragment
@@ -146,13 +148,13 @@ ip_packet_match(const struct iphdr *ip,
        if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG)) {
                dprintf("Fragment rule but not fragment.%s\n",
                        ipinfo->invflags & IPT_INV_FRAG ? " (INV)" : "");
-               return 0;
+               return false;
        }
 
-       return 1;
+       return true;
 }
 
-static inline bool
+static bool
 ip_checkentry(const struct ipt_ip *ip)
 {
        if (ip->flags & ~IPT_F_MASK) {
@@ -182,8 +184,9 @@ ipt_error(struct sk_buff *skb,
        return NF_DROP;
 }
 
-static inline
-bool do_match(struct ipt_entry_match *m,
+/* Performance critical - called for every packet */
+static inline bool
+do_match(struct ipt_entry_match *m,
              const struct sk_buff *skb,
              const struct net_device *in,
              const struct net_device *out,
@@ -198,6 +201,7 @@ bool do_match(struct ipt_entry_match *m,
                return false;
 }
 
+/* Performance critical */
 static inline struct ipt_entry *
 get_entry(void *base, unsigned int offset)
 {
@@ -205,6 +209,7 @@ get_entry(void *base, unsigned int offset)
 }
 
 /* All zeroes == unconditional rule. */
+/* Mildly perf critical (only if packet tracing is on) */
 static inline int
 unconditional(const struct ipt_ip *ip)
 {
@@ -215,16 +220,17 @@ unconditional(const struct ipt_ip *ip)
                        return 0;
 
        return 1;
+#undef FWINV
 }
 
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
-static const char *hooknames[] = {
-       [NF_IP_PRE_ROUTING]             = "PREROUTING",
-       [NF_IP_LOCAL_IN]                = "INPUT",
-       [NF_IP_FORWARD]                 = "FORWARD",
-       [NF_IP_LOCAL_OUT]               = "OUTPUT",
-       [NF_IP_POST_ROUTING]            = "POSTROUTING",
+static const char *const hooknames[] = {
+       [NF_INET_PRE_ROUTING]           = "PREROUTING",
+       [NF_INET_LOCAL_IN]              = "INPUT",
+       [NF_INET_FORWARD]               = "FORWARD",
+       [NF_INET_LOCAL_OUT]             = "OUTPUT",
+       [NF_INET_POST_ROUTING]          = "POSTROUTING",
 };
 
 enum nf_ip_trace_comments {
@@ -233,7 +239,7 @@ enum nf_ip_trace_comments {
        NF_IP_TRACE_COMMENT_POLICY,
 };
 
-static const char *comments[] = {
+static const char *const comments[] = {
        [NF_IP_TRACE_COMMENT_RULE]      = "rule",
        [NF_IP_TRACE_COMMENT_RETURN]    = "return",
        [NF_IP_TRACE_COMMENT_POLICY]    = "policy",
@@ -249,6 +255,7 @@ 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,
@@ -465,10 +472,9 @@ mark_source_chains(struct xt_table_info *newinfo,
 
        /* No recursion; use packet counter to save back ptrs (reset
           to 0 as we leave), and comefrom to save source hook bitmask */
-       for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
+       for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
                unsigned int pos = newinfo->hook_entry[hook];
-               struct ipt_entry *e
-                       = (struct ipt_entry *)(entry0 + pos);
+               struct ipt_entry *e = (struct ipt_entry *)(entry0 + pos);
 
                if (!(valid_hooks & (1 << hook)))
                        continue;
@@ -481,13 +487,12 @@ mark_source_chains(struct xt_table_info *newinfo,
                                = (void *)ipt_get_target(e);
                        int visited = e->comefrom & (1 << hook);
 
-                       if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
+                       if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
                                printk("iptables: loop hook %u pos %u %08X.\n",
                                       hook, pos, e->comefrom);
                                return 0;
                        }
-                       e->comefrom
-                               |= ((1 << hook) | (1 << NF_IP_NUMHOOKS));
+                       e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
                        /* Unconditional return/END. */
                        if ((e->target_offset == sizeof(struct ipt_entry)
@@ -507,10 +512,10 @@ mark_source_chains(struct xt_table_info *newinfo,
                                /* Return: backtrack through the last
                                   big jump. */
                                do {
-                                       e->comefrom ^= (1<<NF_IP_NUMHOOKS);
+                                       e->comefrom ^= (1<<NF_INET_NUMHOOKS);
 #ifdef DEBUG_IP_FIREWALL_USER
                                        if (e->comefrom
-                                           & (1 << NF_IP_NUMHOOKS)) {
+                                           & (1 << NF_INET_NUMHOOKS)) {
                                                duprintf("Back unset "
                                                         "on hook %u "
                                                         "rule %u\n",
@@ -567,7 +572,7 @@ mark_source_chains(struct xt_table_info *newinfo,
        return 1;
 }
 
-static inline int
+static int
 cleanup_match(struct ipt_entry_match *m, unsigned int *i)
 {
        if (i && (*i)-- == 0)
@@ -579,7 +584,7 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
        return 0;
 }
 
-static inline int
+static int
 check_entry(struct ipt_entry *e, const char *name)
 {
        struct ipt_entry_target *t;
@@ -589,7 +594,8 @@ check_entry(struct ipt_entry *e, const char *name)
                return -EINVAL;
        }
 
-       if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
+       if (e->target_offset + sizeof(struct ipt_entry_target) >
+           e->next_offset)
                return -EINVAL;
 
        t = ipt_get_target(e);
@@ -599,9 +605,10 @@ check_entry(struct ipt_entry *e, const char *name)
        return 0;
 }
 
-static inline int check_match(struct ipt_entry_match *m, const char *name,
-                               const struct ipt_ip *ip, unsigned int hookmask,
-                               unsigned int *i)
+static int
+check_match(struct ipt_entry_match *m, const char *name,
+                             const struct ipt_ip *ip,
+                             unsigned int hookmask, unsigned int *i)
 {
        struct xt_match *match;
        int ret;
@@ -622,18 +629,18 @@ static inline int check_match(struct ipt_entry_match *m, const char *name,
        return ret;
 }
 
-static inline int
+static int
 find_check_match(struct ipt_entry_match *m,
-           const char *name,
-           const struct ipt_ip *ip,
-           unsigned int hookmask,
-           unsigned int *i)
+                const char *name,
+                const struct ipt_ip *ip,
+                unsigned int hookmask,
+                unsigned int *i)
 {
        struct xt_match *match;
        int ret;
 
        match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
-                                                  m->u.user.revision),
+                                                     m->u.user.revision),
                                        "ipt_%s", m->u.user.name);
        if (IS_ERR(match) || !match) {
                duprintf("find_check_match: `%s' not found\n", m->u.user.name);
@@ -651,7 +658,7 @@ err:
        return ret;
 }
 
-static inline int check_target(struct ipt_entry *e, const char *name)
+static int check_target(struct ipt_entry *e, const char *name)
 {
        struct ipt_entry_target *t;
        struct xt_target *target;
@@ -663,8 +670,8 @@ static inline int check_target(struct ipt_entry *e, const char *name)
                              name, e->comefrom, e->ip.proto,
                              e->ip.invflags & IPT_INV_PROTO);
        if (!ret && t->u.kernel.target->checkentry
-                  && !t->u.kernel.target->checkentry(name, e, target,
-                                                     t->data, e->comefrom)) {
+           && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                              e->comefrom)) {
                duprintf("ip_tables: check failed for `%s'.\n",
                         t->u.kernel.target->name);
                ret = -EINVAL;
@@ -672,9 +679,9 @@ static inline int check_target(struct ipt_entry *e, const char *name)
        return ret;
 }
 
-static inline int
+static int
 find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
-           unsigned int *i)
+                unsigned int *i)
 {
        struct ipt_entry_target *t;
        struct xt_target *target;
@@ -687,14 +694,14 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
 
        j = 0;
        ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
-                                                       e->comefrom, &j);
+                               e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ipt_get_target(e);
        target = try_then_request_module(xt_find_target(AF_INET,
-                                                    t->u.user.name,
-                                                    t->u.user.revision),
+                                                       t->u.user.name,
+                                                       t->u.user.revision),
                                         "ipt_%s", t->u.user.name);
        if (IS_ERR(target) || !target) {
                duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
@@ -716,7 +723,7 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
        return ret;
 }
 
-static inline int
+static int
 check_entry_size_and_hooks(struct ipt_entry *e,
                           struct xt_table_info *newinfo,
                           unsigned char *base,
@@ -741,7 +748,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
        }
 
        /* Check hooks & underflows */
-       for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -759,7 +766,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
        return 0;
 }
 
-static inline int
+static int
 cleanup_entry(struct ipt_entry *e, unsigned int *i)
 {
        struct ipt_entry_target *t;
@@ -795,7 +802,7 @@ translate_table(const char *name,
        newinfo->number = number;
 
        /* Init all hooks to impossible value. */
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                newinfo->hook_entry[i] = 0xFFFFFFFF;
                newinfo->underflow[i] = 0xFFFFFFFF;
        }
@@ -819,7 +826,7 @@ translate_table(const char *name,
        }
 
        /* Check hooks all assigned */
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                /* Only hooks which are valid */
                if (!(valid_hooks & (1 << i)))
                        continue;
@@ -915,7 +922,7 @@ get_counters(const struct xt_table_info *t,
        }
 }
 
-static inline struct xt_counters * alloc_counters(struct xt_table *table)
+static struct xt_counters * alloc_counters(struct xt_table *table)
 {
        unsigned int countersize;
        struct xt_counters *counters;
@@ -959,7 +966,6 @@ copy_entries_to_user(unsigned int total_size,
         * allowed to migrate to another cpu)
         */
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
-       /* ... then copy entire thing ... */
        if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
                ret = -EFAULT;
                goto free_counters;
@@ -1014,63 +1020,12 @@ copy_entries_to_user(unsigned int total_size,
 }
 
 #ifdef CONFIG_COMPAT
-struct compat_delta {
-       struct compat_delta *next;
-       unsigned int offset;
-       short delta;
-};
-
-static struct compat_delta *compat_offsets = NULL;
-
-static int compat_add_offset(unsigned int offset, short delta)
-{
-       struct compat_delta *tmp;
-
-       tmp = kmalloc(sizeof(struct compat_delta), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-       tmp->offset = offset;
-       tmp->delta = delta;
-       if (compat_offsets) {
-               tmp->next = compat_offsets->next;
-               compat_offsets->next = tmp;
-       } else {
-               compat_offsets = tmp;
-               tmp->next = NULL;
-       }
-       return 0;
-}
-
-static void compat_flush_offsets(void)
-{
-       struct compat_delta *tmp, *next;
-
-       if (compat_offsets) {
-               for(tmp = compat_offsets; tmp; tmp = next) {
-                       next = tmp->next;
-                       kfree(tmp);
-               }
-               compat_offsets = NULL;
-       }
-}
-
-static short compat_calc_jump(unsigned int offset)
-{
-       struct compat_delta *tmp;
-       short delta;
-
-       for(tmp = compat_offsets, delta = 0; tmp; tmp = tmp->next)
-               if (tmp->offset < offset)
-                       delta += tmp->delta;
-       return delta;
-}
-
 static void compat_standard_from_user(void *dst, void *src)
 {
        int v = *(compat_int_t *)src;
 
        if (v > 0)
-               v += compat_calc_jump(v);
+               v += xt_compat_calc_jump(AF_INET, v);
        memcpy(dst, &v, sizeof(v));
 }
 
@@ -1079,64 +1034,61 @@ static int compat_standard_to_user(void __user *dst, void *src)
        compat_int_t cv = *(int *)src;
 
        if (cv > 0)
-               cv -= compat_calc_jump(cv);
+               cv -= xt_compat_calc_jump(AF_INET, cv);
        return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
 }
 
 static inline int
-compat_calc_match(struct ipt_entry_match *m, int * size)
+compat_calc_match(struct ipt_entry_match *m, int *size)
 {
        *size += xt_compat_match_offset(m->u.kernel.match);
        return 0;
 }
 
-static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info,
-               void *base, struct xt_table_info *newinfo)
+static int compat_calc_entry(struct ipt_entry *e,
+                            const struct xt_table_info *info,
+                            void *base, struct xt_table_info *newinfo)
 {
        struct ipt_entry_target *t;
        unsigned int entry_offset;
        int off, i, ret;
 
-       off = 0;
+       off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
        entry_offset = (void *)e - base;
        IPT_MATCH_ITERATE(e, compat_calc_match, &off);
        t = ipt_get_target(e);
        off += xt_compat_target_offset(t->u.kernel.target);
        newinfo->size -= off;
-       ret = compat_add_offset(entry_offset, off);
+       ret = xt_compat_add_offset(AF_INET, entry_offset, off);
        if (ret)
                return ret;
 
-       for (i = 0; i< NF_IP_NUMHOOKS; i++) {
-               if (info->hook_entry[i] && (e < (struct ipt_entry *)
-                               (base + info->hook_entry[i])))
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               if (info->hook_entry[i] &&
+                   (e < (struct ipt_entry *)(base + info->hook_entry[i])))
                        newinfo->hook_entry[i] -= off;
-               if (info->underflow[i] && (e < (struct ipt_entry *)
-                               (base + info->underflow[i])))
+               if (info->underflow[i] &&
+                   (e < (struct ipt_entry *)(base + info->underflow[i])))
                        newinfo->underflow[i] -= off;
        }
        return 0;
 }
 
-static int compat_table_info(struct xt_table_info *info,
-               struct xt_table_info *newinfo)
+static int compat_table_info(const struct xt_table_info *info,
+                            struct xt_table_info *newinfo)
 {
        void *loc_cpu_entry;
-       int i;
 
        if (!newinfo || !info)
                return -EINVAL;
 
-       memset(newinfo, 0, sizeof(struct xt_table_info));
-       newinfo->size = info->size;
-       newinfo->number = info->number;
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
-               newinfo->hook_entry[i] = info->hook_entry[i];
-               newinfo->underflow[i] = info->underflow[i];
-       }
+       /* we dont care about newinfo->entries[] */
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
        loc_cpu_entry = info->entries[raw_smp_processor_id()];
        return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size,
-                       compat_calc_entry, info, loc_cpu_entry, newinfo);
+                                compat_calc_entry, info, loc_cpu_entry,
+                                newinfo);
 }
 #endif
 
@@ -1147,8 +1099,8 @@ static int get_info(void __user *user, int *len, int compat)
        int ret;
 
        if (*len != sizeof(struct ipt_getinfo)) {
-               duprintf("length %u != %u\n", *len,
-                       (unsigned int)sizeof(struct ipt_getinfo));
+               duprintf("length %u != %zu\n", *len,
+                        sizeof(struct ipt_getinfo));
                return -EINVAL;
        }
 
@@ -1161,7 +1113,7 @@ static int get_info(void __user *user, int *len, int compat)
                xt_compat_lock(AF_INET);
 #endif
        t = try_then_request_module(xt_find_table_lock(AF_INET, name),
-                       "iptable_%s", name);
+                                   "iptable_%s", name);
        if (t && !IS_ERR(t)) {
                struct ipt_getinfo info;
                struct xt_table_info *private = t->private;
@@ -1170,15 +1122,15 @@ static int get_info(void __user *user, int *len, int compat)
                if (compat) {
                        struct xt_table_info tmp;
                        ret = compat_table_info(private, &tmp);
-                       compat_flush_offsets();
-                       private =  &tmp;
+                       xt_compat_flush_offsets(AF_INET);
+                       private = &tmp;
                }
 #endif
                info.valid_hooks = t->valid_hooks;
                memcpy(info.hook_entry, private->hook_entry,
-                               sizeof(info.hook_entry));
+                      sizeof(info.hook_entry));
                memcpy(info.underflow, private->underflow,
-                               sizeof(info.underflow));
+                      sizeof(info.underflow));
                info.num_entries = private->number;
                info.size = private->size;
                strcpy(info.name, name);
@@ -1207,31 +1159,27 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
        struct xt_table *t;
 
        if (*len < sizeof(get)) {
-               duprintf("get_entries: %u < %d\n", *len,
-                               (unsigned int)sizeof(get));
+               duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
                return -EINVAL;
        }
        if (copy_from_user(&get, uptr, sizeof(get)) != 0)
                return -EFAULT;
        if (*len != sizeof(struct ipt_get_entries) + get.size) {
-               duprintf("get_entries: %u != %u\n", *len,
-                               (unsigned int)(sizeof(struct ipt_get_entries) +
-                               get.size));
+               duprintf("get_entries: %u != %zu\n",
+                        *len, sizeof(get) + get.size);
                return -EINVAL;
        }
 
        t = xt_find_table_lock(AF_INET, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
-               duprintf("t->private->number = %u\n",
-                        private->number);
+               duprintf("t->private->number = %u\n", private->number);
                if (get.size == private->size)
                        ret = copy_entries_to_user(private->size,
                                                   t, uptr->entrytable);
                else {
                        duprintf("get_entries: I've got %u not %u!\n",
-                                private->size,
-                                get.size);
+                                private->size, get.size);
                        ret = -EINVAL;
                }
                module_put(t->me);
@@ -1244,8 +1192,8 @@ get_entries(struct ipt_get_entries __user *uptr, int *len)
 
 static int
 __do_replace(const char *name, unsigned int valid_hooks,
-               struct xt_table_info *newinfo, unsigned int num_counters,
-               void __user *counters_ptr)
+            struct xt_table_info *newinfo, unsigned int num_counters,
+            void __user *counters_ptr)
 {
        int ret;
        struct xt_table *t;
@@ -1293,7 +1241,8 @@ __do_replace(const char *name, unsigned int valid_hooks,
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
        loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
-       IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+       IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
+                         NULL);
        xt_free_table_info(oldinfo);
        if (copy_to_user(counters_ptr, counters,
                         sizeof(struct xt_counters) * num_counters) != 0)
@@ -1322,14 +1271,7 @@ do_replace(void __user *user, unsigned int len)
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
 
-       /* Hack: Causes ipchains to give correct error msg --RR */
-       if (len != sizeof(tmp) + tmp.size)
-               return -ENOPROTOOPT;
-
        /* overflow check */
-       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
-                       SMP_CACHE_BYTES)
-               return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
 
@@ -1337,7 +1279,7 @@ do_replace(void __user *user, unsigned int len)
        if (!newinfo)
                return -ENOMEM;
 
-       /* choose the copy that is our node/cpu */
+       /* choose the copy that is on our node/cpu */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
        if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
                           tmp.size) != 0) {
@@ -1353,15 +1295,14 @@ do_replace(void __user *user, unsigned int len)
 
        duprintf("ip_tables: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks,
-                             newinfo, tmp.num_counters,
-                             tmp.counters);
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, tmp.counters);
        if (ret)
                goto free_newinfo_untrans;
        return 0;
 
  free_newinfo_untrans:
-       IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
+       IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo:
        xt_free_table_info(newinfo);
        return ret;
@@ -1369,7 +1310,7 @@ do_replace(void __user *user, unsigned int len)
 
 /* We're lazy, and add to the first CPU; overflow works its fey magic
  * and everything is OK. */
-static inline int
+static int
 add_counter_to_entry(struct ipt_entry *e,
                     const struct xt_counters addme[],
                     unsigned int *i)
@@ -1479,19 +1420,13 @@ struct compat_ipt_replace {
        u32                     valid_hooks;
        u32                     num_entries;
        u32                     size;
-       u32                     hook_entry[NF_IP_NUMHOOKS];
-       u32                     underflow[NF_IP_NUMHOOKS];
+       u32                     hook_entry[NF_INET_NUMHOOKS];
+       u32                     underflow[NF_INET_NUMHOOKS];
        u32                     num_counters;
        compat_uptr_t           counters;       /* struct ipt_counters * */
        struct compat_ipt_entry entries[0];
 };
 
-static inline int compat_copy_match_to_user(struct ipt_entry_match *m,
-               void __user **dstptr, compat_uint_t *size)
-{
-       return xt_compat_match_to_user(m, dstptr, size);
-}
-
 static int
 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
                          compat_uint_t *size, struct xt_counters *counters,
@@ -1513,7 +1448,9 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
                goto out;
 
        *dstptr += sizeof(struct compat_ipt_entry);
-       ret = IPT_MATCH_ITERATE(e, compat_copy_match_to_user, dstptr, size);
+       *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
+
+       ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size);
        target_offset = e->target_offset - (origsize - *size);
        if (ret)
                goto out;
@@ -1534,21 +1471,21 @@ out:
        return ret;
 }
 
-static inline int
+static int
 compat_find_calc_match(struct ipt_entry_match *m,
-           const char *name,
-           const struct ipt_ip *ip,
-           unsigned int hookmask,
-           int *size, int *i)
+                      const char *name,
+                      const struct ipt_ip *ip,
+                      unsigned int hookmask,
+                      int *size, int *i)
 {
        struct xt_match *match;
 
        match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
-                                                  m->u.user.revision),
+                                                     m->u.user.revision),
                                        "ipt_%s", m->u.user.name);
        if (IS_ERR(match) || !match) {
                duprintf("compat_check_calc_match: `%s' not found\n",
-                               m->u.user.name);
+                        m->u.user.name);
                return match ? PTR_ERR(match) : -ENOENT;
        }
        m->u.kernel.match = match;
@@ -1558,7 +1495,7 @@ compat_find_calc_match(struct ipt_entry_match *m,
        return 0;
 }
 
-static inline int
+static int
 compat_release_match(struct ipt_entry_match *m, unsigned int *i)
 {
        if (i && (*i)-- == 0)
@@ -1568,8 +1505,8 @@ compat_release_match(struct ipt_entry_match *m, unsigned int *i)
        return 0;
 }
 
-static inline int
-compat_release_entry(struct ipt_entry *e, unsigned int *i)
+static int
+compat_release_entry(struct compat_ipt_entry *e, unsigned int *i)
 {
        struct ipt_entry_target *t;
 
@@ -1577,22 +1514,22 @@ compat_release_entry(struct ipt_entry *e, unsigned int *i)
                return 1;
 
        /* Cleanup all matches */
-       IPT_MATCH_ITERATE(e, compat_release_match, NULL);
-       t = ipt_get_target(e);
+       COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL);
+       t = compat_ipt_get_target(e);
        module_put(t->u.kernel.target->me);
        return 0;
 }
 
-static inline int
-check_compat_entry_size_and_hooks(struct ipt_entry *e,
-                          struct xt_table_info *newinfo,
-                          unsigned int *size,
-                          unsigned char *base,
-                          unsigned char *limit,
-                          unsigned int *hook_entries,
-                          unsigned int *underflows,
-                          unsigned int *i,
-                          const char *name)
+static int
+check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
+                                 struct xt_table_info *newinfo,
+                                 unsigned int *size,
+                                 unsigned char *base,
+                                 unsigned char *limit,
+                                 unsigned int *hook_entries,
+                                 unsigned int *underflows,
+                                 unsigned int *i,
+                                 const char *name)
 {
        struct ipt_entry_target *t;
        struct xt_target *target;
@@ -1607,32 +1544,33 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
        }
 
        if (e->next_offset < sizeof(struct compat_ipt_entry) +
-                       sizeof(struct compat_xt_entry_target)) {
+                            sizeof(struct compat_xt_entry_target)) {
                duprintf("checking: element %p size %u\n",
                         e, e->next_offset);
                return -EINVAL;
        }
 
-       ret = check_entry(e, name);
+       /* For purposes of check_entry casting the compat entry is fine */
+       ret = check_entry((struct ipt_entry *)e, name);
        if (ret)
                return ret;
 
-       off = 0;
+       off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
        entry_offset = (void *)e - (void *)base;
        j = 0;
-       ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip,
-                       e->comefrom, &off, &j);
+       ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name,
+                                      &e->ip, e->comefrom, &off, &j);
        if (ret != 0)
                goto release_matches;
 
-       t = ipt_get_target(e);
+       t = compat_ipt_get_target(e);
        target = try_then_request_module(xt_find_target(AF_INET,
-                                                    t->u.user.name,
-                                                    t->u.user.revision),
+                                                       t->u.user.name,
+                                                       t->u.user.revision),
                                         "ipt_%s", t->u.user.name);
        if (IS_ERR(target) || !target) {
                duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
-                                                       t->u.user.name);
+                        t->u.user.name);
                ret = target ? PTR_ERR(target) : -ENOENT;
                goto release_matches;
        }
@@ -1640,12 +1578,12 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 
        off += xt_compat_target_offset(target);
        *size += off;
-       ret = compat_add_offset(entry_offset, off);
+       ret = xt_compat_add_offset(AF_INET, entry_offset, off);
        if (ret)
                goto out;
 
        /* Check hooks & underflows */
-       for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -1653,7 +1591,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
        }
 
        /* Clear counters and comefrom */
-       e->counters = ((struct ipt_counters) { 0, 0 });
+       memset(&e->counters, 0, sizeof(e->counters));
        e->comefrom = 0;
 
        (*i)++;
@@ -1666,17 +1604,10 @@ release_matches:
        return ret;
 }
 
-static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
-       void **dstptr, compat_uint_t *size, const char *name,
-       const struct ipt_ip *ip, unsigned int hookmask)
-{
-       xt_compat_match_from_user(m, dstptr, size);
-       return 0;
-}
-
-static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
-       unsigned int *size, const char *name,
-       struct xt_table_info *newinfo, unsigned char *base)
+static int
+compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
+                           unsigned int *size, const char *name,
+                           struct xt_table_info *newinfo, unsigned char *base)
 {
        struct ipt_entry_target *t;
        struct xt_target *target;
@@ -1688,19 +1619,22 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
        origsize = *size;
        de = (struct ipt_entry *)*dstptr;
        memcpy(de, e, sizeof(struct ipt_entry));
+       memcpy(&de->counters, &e->counters, sizeof(e->counters));
 
-       *dstptr += sizeof(struct compat_ipt_entry);
-       ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
-                       name, &de->ip, de->comefrom);
+       *dstptr += sizeof(struct ipt_entry);
+       *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
+
+       ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user,
+                                      dstptr, size);
        if (ret)
                return ret;
        de->target_offset = e->target_offset - (origsize - *size);
-       t = ipt_get_target(e);
+       t = compat_ipt_get_target(e);
        target = t->u.kernel.target;
        xt_compat_target_from_user(t, dstptr, size);
 
        de->next_offset = e->next_offset - (origsize - *size);
-       for (h = 0; h < NF_IP_NUMHOOKS; h++) {
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
                if ((unsigned char *)de - base < newinfo->hook_entry[h])
                        newinfo->hook_entry[h] -= origsize - *size;
                if ((unsigned char *)de - base < newinfo->underflow[h])
@@ -1709,13 +1643,15 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
        return ret;
 }
 
-static inline int compat_check_entry(struct ipt_entry *e, const char *name,
-                                               unsigned int *i)
+static int
+compat_check_entry(struct ipt_entry *e, const char *name,
+                                    unsigned int *i)
 {
        int j, ret;
 
        j = 0;
-       ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
+       ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip,
+                               e->comefrom, &j);
        if (ret)
                goto cleanup_matches;
 
@@ -1733,13 +1669,13 @@ static inline int compat_check_entry(struct ipt_entry *e, const char *name,
 
 static int
 translate_compat_table(const char *name,
-               unsigned int valid_hooks,
-               struct xt_table_info **pinfo,
-               void **pentry0,
-               unsigned int total_size,
-               unsigned int number,
-               unsigned int *hook_entries,
-               unsigned int *underflows)
+                      unsigned int valid_hooks,
+                      struct xt_table_info **pinfo,
+                      void **pentry0,
+                      unsigned int total_size,
+                      unsigned int number,
+                      unsigned int *hook_entries,
+                      unsigned int *underflows)
 {
        unsigned int i, j;
        struct xt_table_info *newinfo, *info;
@@ -1753,7 +1689,7 @@ translate_compat_table(const char *name,
        info->number = number;
 
        /* Init all hooks to impossible value. */
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                info->hook_entry[i] = 0xFFFFFFFF;
                info->underflow[i] = 0xFFFFFFFF;
        }
@@ -1762,11 +1698,11 @@ translate_compat_table(const char *name,
        j = 0;
        xt_compat_lock(AF_INET);
        /* Walk through entries, checking offsets. */
-       ret = IPT_ENTRY_ITERATE(entry0, total_size,
-                               check_compat_entry_size_and_hooks,
-                               info, &size, entry0,
-                               entry0 + total_size,
-                               hook_entries, underflows, &j, name);
+       ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
+                                      check_compat_entry_size_and_hooks,
+                                      info, &size, entry0,
+                                      entry0 + total_size,
+                                      hook_entries, underflows, &j, name);
        if (ret != 0)
                goto out_unlock;
 
@@ -1778,7 +1714,7 @@ translate_compat_table(const char *name,
        }
 
        /* Check hooks all assigned */
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                /* Only hooks which are valid */
                if (!(valid_hooks & (1 << i)))
                        continue;
@@ -1800,17 +1736,17 @@ translate_compat_table(const char *name,
                goto out_unlock;
 
        newinfo->number = number;
-       for (i = 0; i < NF_IP_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                newinfo->hook_entry[i] = info->hook_entry[i];
                newinfo->underflow[i] = info->underflow[i];
        }
        entry1 = newinfo->entries[raw_smp_processor_id()];
        pos = entry1;
-       size =  total_size;
-       ret = IPT_ENTRY_ITERATE(entry0, total_size,
-                       compat_copy_entry_from_user, &pos, &size,
-                       name, newinfo, entry1);
-       compat_flush_offsets();
+       size = total_size;
+       ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size,
+                                      compat_copy_entry_from_user,
+                                      &pos, &size, name, newinfo, entry1);
+       xt_compat_flush_offsets(AF_INET);
        xt_compat_unlock(AF_INET);
        if (ret)
                goto free_newinfo;
@@ -1821,11 +1757,11 @@ translate_compat_table(const char *name,
 
        i = 0;
        ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
-                                                               name, &i);
+                               name, &i);
        if (ret) {
                j -= i;
-               IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i,
-                                               compat_release_entry, &j);
+               COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
+                                                 compat_release_entry, &j);
                IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
                xt_free_table_info(newinfo);
                return ret;
@@ -1844,10 +1780,10 @@ translate_compat_table(const char *name,
 free_newinfo:
        xt_free_table_info(newinfo);
 out:
-       IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
+       COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
        return ret;
 out_unlock:
-       compat_flush_offsets();
+       xt_compat_flush_offsets(AF_INET);
        xt_compat_unlock(AF_INET);
        goto out;
 }
@@ -1863,13 +1799,8 @@ compat_do_replace(void __user *user, unsigned int len)
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
 
-       /* Hack: Causes ipchains to give correct error msg --RR */
-       if (len != sizeof(tmp) + tmp.size)
-               return -ENOPROTOOPT;
-
        /* overflow check */
-       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
-                       SMP_CACHE_BYTES)
+       if (tmp.size >= INT_MAX / num_possible_cpus())
                return -ENOMEM;
        if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
@@ -1878,7 +1809,7 @@ compat_do_replace(void __user *user, unsigned int len)
        if (!newinfo)
                return -ENOMEM;
 
-       /* choose the copy that is our node/cpu */
+       /* choose the copy that is on our node/cpu */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
        if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
                           tmp.size) != 0) {
@@ -1887,22 +1818,22 @@ compat_do_replace(void __user *user, unsigned int len)
        }
 
        ret = translate_compat_table(tmp.name, tmp.valid_hooks,
-                             &newinfo, &loc_cpu_entry, tmp.size,
-                             tmp.num_entries, tmp.hook_entry, tmp.underflow);
+                                    &newinfo, &loc_cpu_entry, tmp.size,
+                                    tmp.num_entries, tmp.hook_entry,
+                                    tmp.underflow);
        if (ret != 0)
                goto free_newinfo;
 
        duprintf("compat_do_replace: Translated table\n");
 
-       ret = __do_replace(tmp.name, tmp.valid_hooks,
-                             newinfo, tmp.num_counters,
-                             compat_ptr(tmp.counters));
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, compat_ptr(tmp.counters));
        if (ret)
                goto free_newinfo_untrans;
        return 0;
 
  free_newinfo_untrans:
-       IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
+       IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo:
        xt_free_table_info(newinfo);
        return ret;
@@ -1910,7 +1841,7 @@ compat_do_replace(void __user *user, unsigned int len)
 
 static int
 compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
-               unsigned int len)
+                     unsigned int len)
 {
        int ret;
 
@@ -1934,15 +1865,15 @@ compat_do_ipt_set_ctl(struct sock *sk,  int cmd, void __user *user,
        return ret;
 }
 
-struct compat_ipt_get_entries
-{
+struct compat_ipt_get_entries {
        char name[IPT_TABLE_MAXNAMELEN];
        compat_uint_t size;
        struct compat_ipt_entry entrytable[0];
 };
 
-static int compat_copy_entries_to_user(unsigned int total_size,
-                    struct xt_table *table, void __user *userptr)
+static int
+compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
+                           void __user *userptr)
 {
        struct xt_counters *counters;
        struct xt_table_info *private = table->private;
@@ -1978,10 +1909,8 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
        struct compat_ipt_get_entries get;
        struct xt_table *t;
 
-
        if (*len < sizeof(get)) {
-               duprintf("compat_get_entries: %u < %u\n",
-                               *len, (unsigned int)sizeof(get));
+               duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
                return -EINVAL;
        }
 
@@ -1989,9 +1918,8 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
                return -EFAULT;
 
        if (*len != sizeof(struct compat_ipt_get_entries) + get.size) {
-               duprintf("compat_get_entries: %u != %u\n", *len,
-                       (unsigned int)(sizeof(struct compat_ipt_get_entries) +
-                       get.size));
+               duprintf("compat_get_entries: %u != %zu\n",
+                        *len, sizeof(get) + get.size);
                return -EINVAL;
        }
 
@@ -2000,19 +1928,17 @@ compat_get_entries(struct compat_ipt_get_entries __user *uptr, int *len)
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                struct xt_table_info info;
-               duprintf("t->private->number = %u\n",
-                        private->number);
+               duprintf("t->private->number = %u\n", private->number);
                ret = compat_table_info(private, &info);
                if (!ret && get.size == info.size) {
                        ret = compat_copy_entries_to_user(private->size,
-                                                  t, uptr->entrytable);
+                                                         t, uptr->entrytable);
                } else if (!ret) {
                        duprintf("compat_get_entries: I've got %u not %u!\n",
-                                private->size,
-                                get.size);
+                                private->size, get.size);
                        ret = -EINVAL;
                }
-               compat_flush_offsets();
+               xt_compat_flush_offsets(AF_INET);
                module_put(t->me);
                xt_table_unlock(t);
        } else
@@ -2047,7 +1973,7 @@ compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
 #endif
 
 static int
-do_ipt_set_ctl(struct sock *sk,        int cmd, void __user *user, unsigned int len)
+do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 {
        int ret;
 
@@ -2126,7 +2052,7 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
 {
        int ret;
        struct xt_table_info *newinfo;
-       static struct xt_table_info bootstrap
+       struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
 
@@ -2134,9 +2060,7 @@ int ipt_register_table(struct xt_table *table, const struct ipt_replace *repl)
        if (!newinfo)
                return -ENOMEM;
 
-       /* choose the copy on our node/cpu
-        * but dont care of preemption
-        */
+       /* choose the copy on our node/cpu, but dont care about preemption */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
        memcpy(loc_cpu_entry, repl->entries, repl->size);
 
@@ -2178,7 +2102,8 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
                     u_int8_t type, u_int8_t code,
                     bool invert)
 {
-       return ((test_type == 0xFF) || (type == test_type && code >= min_code && code <= max_code))
+       return ((test_type == 0xFF) ||
+               (type == test_type && code >= min_code && code <= max_code))
                ^ invert;
 }
 
@@ -2219,7 +2144,7 @@ icmp_match(const struct sk_buff *skb,
 /* Called when user tries to insert an entry of this type. */
 static bool
 icmp_checkentry(const char *tablename,
-          const void *info,
+          const void *entry,
           const struct xt_match *match,
           void *matchinfo,
           unsigned int hook_mask)
@@ -2270,9 +2195,9 @@ static struct xt_match icmp_matchstruct __read_mostly = {
        .name           = "icmp",
        .match          = icmp_match,
        .matchsize      = sizeof(struct ipt_icmp),
+       .checkentry     = icmp_checkentry,
        .proto          = IPPROTO_ICMP,
        .family         = AF_INET,
-       .checkentry     = icmp_checkentry,
 };
 
 static int __init ip_tables_init(void)
index 2f544dac72df7708f7753d74e70de22b2869c46d..1b31f7d14d46b6c87de794f1cd4d4700c0a6ce1e 100644 (file)
@@ -32,7 +32,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("iptables target for CLUSTERIP");
+MODULE_DESCRIPTION("Xtables: CLUSTERIP target");
 
 struct clusterip_config {
        struct list_head list;                  /* list of all configs */
@@ -109,11 +109,9 @@ clusterip_config_entry_put(struct clusterip_config *c)
 static struct clusterip_config *
 __clusterip_config_find(__be32 clusterip)
 {
-       struct list_head *pos;
+       struct clusterip_config *c;
 
-       list_for_each(pos, &clusterip_configs) {
-               struct clusterip_config *c = list_entry(pos,
-                                       struct clusterip_config, list);
+       list_for_each_entry(c, &clusterip_configs, list) {
                if (c->clusterip == clusterip)
                        return c;
        }
@@ -275,7 +273,7 @@ clusterip_hashfn(const struct sk_buff *skb,
        }
 
        /* node numbers are 1..n, not 0..n */
-       return (hashval % config->num_total_nodes) + 1;
+       return (((u64)hashval * config->num_total_nodes) >> 32) + 1;
 }
 
 static inline int
@@ -289,12 +287,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
  ***********************************************************************/
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+clusterip_tg(struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, unsigned int hooknum,
+             const struct xt_target *target, const void *targinfo)
 {
        const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
        struct nf_conn *ct;
@@ -361,11 +356,9 @@ target(struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *e_void,
-          const struct xt_target *target,
-          void *targinfo,
-          unsigned int hook_mask)
+clusterip_tg_check(const char *tablename, const void *e_void,
+                   const struct xt_target *target, void *targinfo,
+                   unsigned int hook_mask)
 {
        struct ipt_clusterip_tgt_info *cipinfo = targinfo;
        const struct ipt_entry *e = e_void;
@@ -421,7 +414,7 @@ checkentry(const char *tablename,
 
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", target->family);
+                                   "proto=%u\n", target->family);
                return false;
        }
 
@@ -429,7 +422,7 @@ checkentry(const char *tablename,
 }
 
 /* drop reference count of cluster config when rule is deleted */
-static void destroy(const struct xt_target *target, void *targinfo)
+static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
 {
        struct ipt_clusterip_tgt_info *cipinfo = targinfo;
 
@@ -456,12 +449,12 @@ struct compat_ipt_clusterip_tgt_info
 };
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target clusterip_tgt __read_mostly = {
+static struct xt_target clusterip_tg_reg __read_mostly = {
        .name           = "CLUSTERIP",
        .family         = AF_INET,
-       .target         = target,
-       .checkentry     = checkentry,
-       .destroy        = destroy,
+       .target         = clusterip_tg,
+       .checkentry     = clusterip_tg_check,
+       .destroy        = clusterip_tg_destroy,
        .targetsize     = sizeof(struct ipt_clusterip_tgt_info),
 #ifdef CONFIG_COMPAT
        .compatsize     = sizeof(struct compat_ipt_clusterip_tgt_info),
@@ -558,7 +551,7 @@ arp_mangle(unsigned int hook,
        return NF_ACCEPT;
 }
 
-static struct nf_hook_ops cip_arp_ops = {
+static struct nf_hook_ops cip_arp_ops __read_mostly = {
        .hook = arp_mangle,
        .pf = NF_ARP,
        .hooknum = NF_ARP_OUT,
@@ -714,11 +707,11 @@ static const struct file_operations clusterip_proc_fops = {
 
 #endif /* CONFIG_PROC_FS */
 
-static int __init ipt_clusterip_init(void)
+static int __init clusterip_tg_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&clusterip_tgt);
+       ret = xt_register_target(&clusterip_tg_reg);
        if (ret < 0)
                return ret;
 
@@ -744,11 +737,11 @@ cleanup_hook:
        nf_unregister_hook(&cip_arp_ops);
 #endif /* CONFIG_PROC_FS */
 cleanup_target:
-       xt_unregister_target(&clusterip_tgt);
+       xt_unregister_target(&clusterip_tg_reg);
        return ret;
 }
 
-static void __exit ipt_clusterip_fini(void)
+static void __exit clusterip_tg_exit(void)
 {
        printk(KERN_NOTICE "ClusterIP Version %s unloading\n",
                CLUSTERIP_VERSION);
@@ -756,8 +749,8 @@ static void __exit ipt_clusterip_fini(void)
        remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent);
 #endif
        nf_unregister_hook(&cip_arp_ops);
-       xt_unregister_target(&clusterip_tgt);
+       xt_unregister_target(&clusterip_tg_reg);
 }
 
-module_init(ipt_clusterip_init);
-module_exit(ipt_clusterip_fini);
+module_init(clusterip_tg_init);
+module_exit(clusterip_tg_exit);
index add110060a22f8d1ef4179a3f15fcfbe6daf6741..21395bc2b27f5b24a28d3d5cda075a362d6fec5e 100644 (file)
@@ -21,7 +21,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("iptables ECN modification module");
+MODULE_DESCRIPTION("Xtables: Explicit Congestion Notification (ECN) flag modification");
 
 /* set ECT codepoint from IP header.
  *     return false if there was an error. */
@@ -38,7 +38,7 @@ set_ect_ip(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
                oldtos = iph->tos;
                iph->tos &= ~IPT_ECN_IP_MASK;
                iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
-               nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
+               csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
        }
        return true;
 }
@@ -71,18 +71,15 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
        if (einfo->operation & IPT_ECN_OP_SET_CWR)
                tcph->cwr = einfo->proto.tcp.cwr;
 
-       nf_proto_csum_replace2(&tcph->check, skb,
-                               oldval, ((__be16 *)tcph)[6], 0);
+       inet_proto_csum_replace2(&tcph->check, skb,
+                                oldval, ((__be16 *)tcph)[6], 0);
        return true;
 }
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+ecn_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
 {
        const struct ipt_ECN_info *einfo = targinfo;
 
@@ -99,11 +96,9 @@ target(struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *e_void,
-          const struct xt_target *target,
-          void *targinfo,
-          unsigned int hook_mask)
+ecn_tg_check(const char *tablename, const void *e_void,
+             const struct xt_target *target, void *targinfo,
+             unsigned int hook_mask)
 {
        const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;
        const struct ipt_entry *e = e_void;
@@ -127,25 +122,25 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target ipt_ecn_reg __read_mostly = {
+static struct xt_target ecn_tg_reg __read_mostly = {
        .name           = "ECN",
        .family         = AF_INET,
-       .target         = target,
+       .target         = ecn_tg,
        .targetsize     = sizeof(struct ipt_ECN_info),
        .table          = "mangle",
-       .checkentry     = checkentry,
+       .checkentry     = ecn_tg_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ecn_init(void)
+static int __init ecn_tg_init(void)
 {
-       return xt_register_target(&ipt_ecn_reg);
+       return xt_register_target(&ecn_tg_reg);
 }
 
-static void __exit ipt_ecn_fini(void)
+static void __exit ecn_tg_exit(void)
 {
-       xt_unregister_target(&ipt_ecn_reg);
+       xt_unregister_target(&ecn_tg_reg);
 }
 
-module_init(ipt_ecn_init);
-module_exit(ipt_ecn_fini);
+module_init(ecn_tg_init);
+module_exit(ecn_tg_exit);
index 4b5e8216a4e7a6bc1bc4d32a5a19d53677ac14b4..b38d7850f506999f84691977ea4e6379a92cd34d 100644 (file)
 #include <linux/netfilter.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ipt_LOG.h>
+#include <net/netfilter/nf_log.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables syslog logging module");
+MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog");
 
 /* Use lock to serialize, so printks don't overlap */
 static DEFINE_SPINLOCK(log_lock);
@@ -337,7 +338,9 @@ static void dump_packet(const struct nf_loginfo *info,
        if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
                read_lock_bh(&skb->sk->sk_callback_lock);
                if (skb->sk->sk_socket && skb->sk->sk_socket->file)
-                       printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+                       printk("UID=%u GID=%u",
+                               skb->sk->sk_socket->file->f_uid,
+                               skb->sk->sk_socket->file->f_gid);
                read_unlock_bh(&skb->sk->sk_callback_lock);
        }
 
@@ -418,12 +421,9 @@ ipt_log_packet(unsigned int pf,
 }
 
 static unsigned int
-ipt_log_target(struct sk_buff *skb,
-              const struct net_device *in,
-              const struct net_device *out,
-              unsigned int hooknum,
-              const struct xt_target *target,
-              const void *targinfo)
+log_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
 {
        const struct ipt_log_info *loginfo = targinfo;
        struct nf_loginfo li;
@@ -437,11 +437,10 @@ ipt_log_target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static bool ipt_log_checkentry(const char *tablename,
-                              const void *e,
-                              const struct xt_target *target,
-                              void *targinfo,
-                              unsigned int hook_mask)
+static bool
+log_tg_check(const char *tablename, const void *e,
+             const struct xt_target *target, void *targinfo,
+             unsigned int hook_mask)
 {
        const struct ipt_log_info *loginfo = targinfo;
 
@@ -457,37 +456,37 @@ static bool ipt_log_checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target ipt_log_reg __read_mostly = {
+static struct xt_target log_tg_reg __read_mostly = {
        .name           = "LOG",
        .family         = AF_INET,
-       .target         = ipt_log_target,
+       .target         = log_tg,
        .targetsize     = sizeof(struct ipt_log_info),
-       .checkentry     = ipt_log_checkentry,
+       .checkentry     = log_tg_check,
        .me             = THIS_MODULE,
 };
 
-static struct nf_logger ipt_log_logger ={
+static const struct nf_logger ipt_log_logger ={
        .name           = "ipt_LOG",
        .logfn          = &ipt_log_packet,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_log_init(void)
+static int __init log_tg_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&ipt_log_reg);
+       ret = xt_register_target(&log_tg_reg);
        if (ret < 0)
                return ret;
        nf_log_register(PF_INET, &ipt_log_logger);
        return 0;
 }
 
-static void __exit ipt_log_fini(void)
+static void __exit log_tg_exit(void)
 {
        nf_log_unregister(&ipt_log_logger);
-       xt_unregister_target(&ipt_log_reg);
+       xt_unregister_target(&log_tg_reg);
 }
 
-module_init(ipt_log_init);
-module_exit(ipt_log_fini);
+module_init(log_tg_init);
+module_exit(log_tg_exit);
index 44b516e7cb79f1c9c814930bbaca7922ef08b03d..d80fee8327e4c156f672386cff5b29b625f6e440 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables MASQUERADE target module");
+MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
 
 /* Lock protects masq region inside conntrack */
 static DEFINE_RWLOCK(masq_lock);
 
 /* FIXME: Multiple targets. --RR */
 static bool
-masquerade_check(const char *tablename,
-                const void *e,
-                const struct xt_target *target,
-                void *targinfo,
-                unsigned int hook_mask)
+masquerade_tg_check(const char *tablename, const void *e,
+                    const struct xt_target *target, void *targinfo,
+                    unsigned int hook_mask)
 {
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
@@ -52,12 +50,9 @@ masquerade_check(const char *tablename,
 }
 
 static unsigned int
-masquerade_target(struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 unsigned int hooknum,
-                 const struct xt_target *target,
-                 const void *targinfo)
+masquerade_tg(struct sk_buff *skb, const struct net_device *in,
+              const struct net_device *out, unsigned int hooknum,
+              const struct xt_target *target, const void *targinfo)
 {
        struct nf_conn *ct;
        struct nf_conn_nat *nat;
@@ -67,7 +62,7 @@ masquerade_target(struct sk_buff *skb,
        const struct rtable *rt;
        __be32 newsrc;
 
-       NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
+       NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
 
        ct = nf_ct_get(skb, &ctinfo);
        nat = nfct_nat(ct);
@@ -100,7 +95,7 @@ masquerade_target(struct sk_buff *skb,
                  mr->range[0].min, mr->range[0].max });
 
        /* Hand modified range to generic setup. */
-       return nf_nat_setup_info(ct, &newrange, hooknum);
+       return nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_SRC);
 }
 
 static int
@@ -166,22 +161,22 @@ static struct notifier_block masq_inet_notifier = {
        .notifier_call  = masq_inet_event,
 };
 
-static struct xt_target masquerade __read_mostly = {
+static struct xt_target masquerade_tg_reg __read_mostly = {
        .name           = "MASQUERADE",
        .family         = AF_INET,
-       .target         = masquerade_target,
+       .target         = masquerade_tg,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
        .table          = "nat",
-       .hooks          = 1 << NF_IP_POST_ROUTING,
-       .checkentry     = masquerade_check,
+       .hooks          = 1 << NF_INET_POST_ROUTING,
+       .checkentry     = masquerade_tg_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_masquerade_init(void)
+static int __init masquerade_tg_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&masquerade);
+       ret = xt_register_target(&masquerade_tg_reg);
 
        if (ret == 0) {
                /* Register for device down reports */
@@ -193,12 +188,12 @@ static int __init ipt_masquerade_init(void)
        return ret;
 }
 
-static void __exit ipt_masquerade_fini(void)
+static void __exit masquerade_tg_exit(void)
 {
-       xt_unregister_target(&masquerade);
+       xt_unregister_target(&masquerade_tg_reg);
        unregister_netdevice_notifier(&masq_dev_notifier);
        unregister_inetaddr_notifier(&masq_inet_notifier);
 }
 
-module_init(ipt_masquerade_init);
-module_exit(ipt_masquerade_fini);
+module_init(masquerade_tg_init);
+module_exit(masquerade_tg_exit);
index f8699291e33d75a2c4d288859b8ca43bb634e46e..6739abfd1521d151e8da7577bf2c39bfdc2d29ff 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
-MODULE_DESCRIPTION("iptables 1:1 NAT mapping of IP networks target");
+MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
 
 static bool
-check(const char *tablename,
-      const void *e,
-      const struct xt_target *target,
-      void *targinfo,
-      unsigned int hook_mask)
+netmap_tg_check(const char *tablename, const void *e,
+                const struct xt_target *target, void *targinfo,
+                unsigned int hook_mask)
 {
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
@@ -43,12 +41,9 @@ check(const char *tablename,
 }
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+netmap_tg(struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, unsigned int hooknum,
+          const struct xt_target *target, const void *targinfo)
 {
        struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
@@ -56,14 +51,14 @@ target(struct sk_buff *skb,
        const struct nf_nat_multi_range_compat *mr = targinfo;
        struct nf_nat_range newrange;
 
-       NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
-                    || hooknum == NF_IP_POST_ROUTING
-                    || hooknum == NF_IP_LOCAL_OUT);
+       NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
+                    || hooknum == NF_INET_POST_ROUTING
+                    || hooknum == NF_INET_LOCAL_OUT);
        ct = nf_ct_get(skb, &ctinfo);
 
        netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
 
-       if (hooknum == NF_IP_PRE_ROUTING || hooknum == NF_IP_LOCAL_OUT)
+       if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT)
                new_ip = ip_hdr(skb)->daddr & ~netmask;
        else
                new_ip = ip_hdr(skb)->saddr & ~netmask;
@@ -75,30 +70,31 @@ target(struct sk_buff *skb,
                  mr->range[0].min, mr->range[0].max });
 
        /* Hand modified range to generic setup. */
-       return nf_nat_setup_info(ct, &newrange, hooknum);
+       return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum));
 }
 
-static struct xt_target target_module __read_mostly = {
+static struct xt_target netmap_tg_reg __read_mostly = {
        .name           = "NETMAP",
        .family         = AF_INET,
-       .target         = target,
+       .target         = netmap_tg,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
        .table          = "nat",
-       .hooks          = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_POST_ROUTING) |
-                         (1 << NF_IP_LOCAL_OUT),
-       .checkentry     = check,
+       .hooks          = (1 << NF_INET_PRE_ROUTING) |
+                         (1 << NF_INET_POST_ROUTING) |
+                         (1 << NF_INET_LOCAL_OUT),
+       .checkentry     = netmap_tg_check,
        .me             = THIS_MODULE
 };
 
-static int __init ipt_netmap_init(void)
+static int __init netmap_tg_init(void)
 {
-       return xt_register_target(&target_module);
+       return xt_register_target(&netmap_tg_reg);
 }
 
-static void __exit ipt_netmap_fini(void)
+static void __exit netmap_tg_exit(void)
 {
-       xt_unregister_target(&target_module);
+       xt_unregister_target(&netmap_tg_reg);
 }
 
-module_init(ipt_netmap_init);
-module_exit(ipt_netmap_fini);
+module_init(netmap_tg_init);
+module_exit(netmap_tg_exit);
index f7cf7d61a2d4a3e16f543491885e3633e8358fee..5c6292449d131205c8df99fe4eaad4f5488ae260 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables REDIRECT target module");
+MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
 
 /* FIXME: Take multiple ranges --RR */
 static bool
-redirect_check(const char *tablename,
-              const void *e,
-              const struct xt_target *target,
-              void *targinfo,
-              unsigned int hook_mask)
+redirect_tg_check(const char *tablename, const void *e,
+                  const struct xt_target *target, void *targinfo,
+                  unsigned int hook_mask)
 {
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
@@ -47,12 +45,9 @@ redirect_check(const char *tablename,
 }
 
 static unsigned int
-redirect_target(struct sk_buff *skb,
-               const struct net_device *in,
-               const struct net_device *out,
-               unsigned int hooknum,
-               const struct xt_target *target,
-               const void *targinfo)
+redirect_tg(struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, unsigned int hooknum,
+            const struct xt_target *target, const void *targinfo)
 {
        struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
@@ -60,14 +55,14 @@ redirect_target(struct sk_buff *skb,
        const struct nf_nat_multi_range_compat *mr = targinfo;
        struct nf_nat_range newrange;
 
-       NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING
-                    || hooknum == NF_IP_LOCAL_OUT);
+       NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING
+                    || hooknum == NF_INET_LOCAL_OUT);
 
        ct = nf_ct_get(skb, &ctinfo);
        NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
        /* Local packets: make them go to loopback */
-       if (hooknum == NF_IP_LOCAL_OUT)
+       if (hooknum == NF_INET_LOCAL_OUT)
                newdst = htonl(0x7F000001);
        else {
                struct in_device *indev;
@@ -92,29 +87,29 @@ redirect_target(struct sk_buff *skb,
                  mr->range[0].min, mr->range[0].max });
 
        /* Hand modified range to generic setup. */
-       return nf_nat_setup_info(ct, &newrange, hooknum);
+       return nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_DST);
 }
 
-static struct xt_target redirect_reg __read_mostly = {
+static struct xt_target redirect_tg_reg __read_mostly = {
        .name           = "REDIRECT",
        .family         = AF_INET,
-       .target         = redirect_target,
+       .target         = redirect_tg,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
        .table          = "nat",
-       .hooks          = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
-       .checkentry     = redirect_check,
+       .hooks          = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
+       .checkentry     = redirect_tg_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_redirect_init(void)
+static int __init redirect_tg_init(void)
 {
-       return xt_register_target(&redirect_reg);
+       return xt_register_target(&redirect_tg_reg);
 }
 
-static void __exit ipt_redirect_fini(void)
+static void __exit redirect_tg_exit(void)
 {
-       xt_unregister_target(&redirect_reg);
+       xt_unregister_target(&redirect_tg_reg);
 }
 
-module_init(ipt_redirect_init);
-module_exit(ipt_redirect_fini);
+module_init(redirect_tg_init);
+module_exit(redirect_tg_exit);
index dcf4d21d51161fa99625168c9990379cd988e01f..22606e2baa16cbeca5b99380bf34a7c8ed9b1076 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables REJECT target module");
+MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4");
 
 /* Send RST reply */
 static void send_reset(struct sk_buff *oldskb, int hook)
 {
        struct sk_buff *nskb;
-       struct iphdr *niph;
+       struct iphdr *oiph, *niph;
        struct tcphdr _otcph, *oth, *tcph;
-       __be16 tmp_port;
-       __be32 tmp_addr;
-       int needs_ack;
        unsigned int addr_type;
 
        /* IP header checks: fragment. */
@@ -58,99 +55,73 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        /* Check checksum */
        if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
                return;
+       oiph = ip_hdr(oldskb);
 
-       /* We need a linear, writeable skb.  We also need to expand
-          headroom in case hh_len of incoming interface < hh_len of
-          outgoing interface */
-       nskb = skb_copy_expand(oldskb, LL_MAX_HEADER, skb_tailroom(oldskb),
-                              GFP_ATOMIC);
+       nskb = alloc_skb(sizeof(struct iphdr) + sizeof(struct tcphdr) +
+                        LL_MAX_HEADER, GFP_ATOMIC);
        if (!nskb)
                return;
 
-       /* This packet will not be the same as the other: clear nf fields */
-       nf_reset(nskb);
-       nskb->mark = 0;
-       skb_init_secmark(nskb);
-
-       skb_shinfo(nskb)->gso_size = 0;
-       skb_shinfo(nskb)->gso_segs = 0;
-       skb_shinfo(nskb)->gso_type = 0;
-
-       tcph = (struct tcphdr *)(skb_network_header(nskb) + ip_hdrlen(nskb));
-
-       /* Swap source and dest */
-       niph = ip_hdr(nskb);
-       tmp_addr = niph->saddr;
-       niph->saddr = niph->daddr;
-       niph->daddr = tmp_addr;
-       tmp_port = tcph->source;
-       tcph->source = tcph->dest;
-       tcph->dest = tmp_port;
-
-       /* Truncate to length (no data) */
-       tcph->doff = sizeof(struct tcphdr)/4;
-       skb_trim(nskb, ip_hdrlen(nskb) + sizeof(struct tcphdr));
-       niph->tot_len = htons(nskb->len);
-
-       if (tcph->ack) {
-               needs_ack = 0;
+       skb_reserve(nskb, LL_MAX_HEADER);
+
+       skb_reset_network_header(nskb);
+       niph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
+       niph->version   = 4;
+       niph->ihl       = sizeof(struct iphdr) / 4;
+       niph->tos       = 0;
+       niph->id        = 0;
+       niph->frag_off  = htons(IP_DF);
+       niph->protocol  = IPPROTO_TCP;
+       niph->check     = 0;
+       niph->saddr     = oiph->daddr;
+       niph->daddr     = oiph->saddr;
+
+       tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
+       memset(tcph, 0, sizeof(*tcph));
+       tcph->source    = oth->dest;
+       tcph->dest      = oth->source;
+       tcph->doff      = sizeof(struct tcphdr) / 4;
+
+       if (oth->ack)
                tcph->seq = oth->ack_seq;
-               tcph->ack_seq = 0;
-       } else {
-               needs_ack = 1;
+       else {
                tcph->ack_seq = htonl(ntohl(oth->seq) + oth->syn + oth->fin +
                                      oldskb->len - ip_hdrlen(oldskb) -
                                      (oth->doff << 2));
-               tcph->seq = 0;
+               tcph->ack = 1;
        }
 
-       /* Reset flags */
-       ((u_int8_t *)tcph)[13] = 0;
-       tcph->rst = 1;
-       tcph->ack = needs_ack;
-
-       tcph->window = 0;
-       tcph->urg_ptr = 0;
-
-       /* Adjust TCP checksum */
-       tcph->check = 0;
-       tcph->check = tcp_v4_check(sizeof(struct tcphdr),
-                                  niph->saddr, niph->daddr,
-                                  csum_partial(tcph,
-                                               sizeof(struct tcphdr), 0));
-
-       /* Set DF, id = 0 */
-       niph->frag_off = htons(IP_DF);
-       niph->id = 0;
+       tcph->rst       = 1;
+       tcph->check     = tcp_v4_check(sizeof(struct tcphdr),
+                                      niph->saddr, niph->daddr,
+                                      csum_partial(tcph,
+                                                   sizeof(struct tcphdr), 0));
 
        addr_type = RTN_UNSPEC;
-       if (hook != NF_IP_FORWARD
+       if (hook != NF_INET_FORWARD
 #ifdef CONFIG_BRIDGE_NETFILTER
            || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
 #endif
           )
                addr_type = RTN_LOCAL;
 
+       /* ip_route_me_harder expects skb->dst to be set */
+       dst_hold(oldskb->dst);
+       nskb->dst = oldskb->dst;
+
        if (ip_route_me_harder(nskb, addr_type))
                goto free_nskb;
 
+       niph->ttl       = dst_metric(nskb->dst, RTAX_HOPLIMIT);
        nskb->ip_summed = CHECKSUM_NONE;
 
-       /* Adjust IP TTL */
-       niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
-
-       /* Adjust IP checksum */
-       niph->check = 0;
-       niph->check = ip_fast_csum(skb_network_header(nskb), niph->ihl);
-
        /* "Never happens" */
        if (nskb->len > dst_mtu(nskb->dst))
                goto free_nskb;
 
        nf_ct_attach(nskb, oldskb);
 
-       NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
-               dst_output);
+       ip_local_out(nskb);
        return;
 
  free_nskb:
@@ -162,20 +133,13 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
        icmp_send(skb_in, ICMP_DEST_UNREACH, code, 0);
 }
 
-static unsigned int reject(struct sk_buff *skb,
-                          const struct net_device *in,
-                          const struct net_device *out,
-                          unsigned int hooknum,
-                          const struct xt_target *target,
-                          const void *targinfo)
+static unsigned int
+reject_tg(struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, unsigned int hooknum,
+          const struct xt_target *target, const void *targinfo)
 {
        const struct ipt_reject_info *reject = targinfo;
 
-       /* Our naive response construction doesn't deal with IP
-          options, and probably shouldn't try. */
-       if (ip_hdrlen(skb) != sizeof(struct iphdr))
-               return NF_DROP;
-
        /* WARNING: This code causes reentry within iptables.
           This means that the iptables jump stack is now crap.  We
           must return an absolute verdict. --RR */
@@ -211,11 +175,10 @@ static unsigned int reject(struct sk_buff *skb,
        return NF_DROP;
 }
 
-static bool check(const char *tablename,
-                 const void *e_void,
-                 const struct xt_target *target,
-                 void *targinfo,
-                 unsigned int hook_mask)
+static bool
+reject_tg_check(const char *tablename, const void *e_void,
+                const struct xt_target *target, void *targinfo,
+                unsigned int hook_mask)
 {
        const struct ipt_reject_info *rejinfo = targinfo;
        const struct ipt_entry *e = e_void;
@@ -234,27 +197,27 @@ static bool check(const char *tablename,
        return true;
 }
 
-static struct xt_target ipt_reject_reg __read_mostly = {
+static struct xt_target reject_tg_reg __read_mostly = {
        .name           = "REJECT",
        .family         = AF_INET,
-       .target         = reject,
+       .target         = reject_tg,
        .targetsize     = sizeof(struct ipt_reject_info),
        .table          = "filter",
-       .hooks          = (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) |
-                         (1 << NF_IP_LOCAL_OUT),
-       .checkentry     = check,
+       .hooks          = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
+                         (1 << NF_INET_LOCAL_OUT),
+       .checkentry     = reject_tg_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_reject_init(void)
+static int __init reject_tg_init(void)
 {
-       return xt_register_target(&ipt_reject_reg);
+       return xt_register_target(&reject_tg_reg);
 }
 
-static void __exit ipt_reject_fini(void)
+static void __exit reject_tg_exit(void)
 {
-       xt_unregister_target(&ipt_reject_reg);
+       xt_unregister_target(&reject_tg_reg);
 }
 
-module_init(ipt_reject_init);
-module_exit(ipt_reject_fini);
+module_init(reject_tg_init);
+module_exit(reject_tg_exit);
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
deleted file mode 100644 (file)
index 8988571..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Same.  Just like SNAT, only try to make the connections
- *       between client A and server B always have the same source ip.
- *
- * (C) 2000 Paul `Rusty' Russell
- * (C) 2001 Martin Josefsson
- *
- * 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/types.h>
-#include <linux/ip.h>
-#include <linux/timer.h>
-#include <linux/module.h>
-#include <linux/netfilter.h>
-#include <linux/netdevice.h>
-#include <linux/if.h>
-#include <linux/inetdevice.h>
-#include <net/protocol.h>
-#include <net/checksum.h>
-#include <linux/netfilter_ipv4.h>
-#include <linux/netfilter/x_tables.h>
-#include <net/netfilter/nf_nat_rule.h>
-#include <linux/netfilter_ipv4/ipt_SAME.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Martin Josefsson <gandalf@wlug.westbo.se>");
-MODULE_DESCRIPTION("iptables special SNAT module for consistent sourceip");
-
-static bool
-same_check(const char *tablename,
-             const void *e,
-             const struct xt_target *target,
-             void *targinfo,
-             unsigned int hook_mask)
-{
-       unsigned int count, countess, rangeip, index = 0;
-       struct ipt_same_info *mr = targinfo;
-
-       mr->ipnum = 0;
-
-       if (mr->rangesize < 1) {
-               pr_debug("same_check: need at least one dest range.\n");
-               return false;
-       }
-       if (mr->rangesize > IPT_SAME_MAX_RANGE) {
-               pr_debug("same_check: too many ranges specified, maximum "
-                        "is %u ranges\n", IPT_SAME_MAX_RANGE);
-               return false;
-       }
-       for (count = 0; count < mr->rangesize; count++) {
-               if (ntohl(mr->range[count].min_ip) >
-                               ntohl(mr->range[count].max_ip)) {
-                       pr_debug("same_check: min_ip is larger than max_ip in "
-                                "range `%u.%u.%u.%u-%u.%u.%u.%u'.\n",
-                                NIPQUAD(mr->range[count].min_ip),
-                                NIPQUAD(mr->range[count].max_ip));
-                       return false;
-               }
-               if (!(mr->range[count].flags & IP_NAT_RANGE_MAP_IPS)) {
-                       pr_debug("same_check: bad MAP_IPS.\n");
-                       return false;
-               }
-               rangeip = (ntohl(mr->range[count].max_ip) -
-                                       ntohl(mr->range[count].min_ip) + 1);
-               mr->ipnum += rangeip;
-
-               pr_debug("same_check: range %u, ipnum = %u\n", count, rangeip);
-       }
-       pr_debug("same_check: total ipaddresses = %u\n", mr->ipnum);
-
-       mr->iparray = kmalloc((sizeof(u_int32_t) * mr->ipnum), GFP_KERNEL);
-       if (!mr->iparray) {
-               pr_debug("same_check: Couldn't allocate %Zu bytes "
-                        "for %u ipaddresses!\n",
-                        (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
-               return false;
-       }
-       pr_debug("same_check: Allocated %Zu bytes for %u ipaddresses.\n",
-                (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
-
-       for (count = 0; count < mr->rangesize; count++) {
-               for (countess = ntohl(mr->range[count].min_ip);
-                               countess <= ntohl(mr->range[count].max_ip);
-                                       countess++) {
-                       mr->iparray[index] = countess;
-                       pr_debug("same_check: Added ipaddress `%u.%u.%u.%u' "
-                                "in index %u.\n", HIPQUAD(countess), index);
-                       index++;
-               }
-       }
-       return true;
-}
-
-static void
-same_destroy(const struct xt_target *target, void *targinfo)
-{
-       struct ipt_same_info *mr = targinfo;
-
-       kfree(mr->iparray);
-
-       pr_debug("same_destroy: Deallocated %Zu bytes for %u ipaddresses.\n",
-                (sizeof(u_int32_t) * mr->ipnum), mr->ipnum);
-}
-
-static unsigned int
-same_target(struct sk_buff *skb,
-               const struct net_device *in,
-               const struct net_device *out,
-               unsigned int hooknum,
-               const struct xt_target *target,
-               const void *targinfo)
-{
-       struct nf_conn *ct;
-       enum ip_conntrack_info ctinfo;
-       u_int32_t tmpip, aindex;
-       __be32 new_ip;
-       const struct ipt_same_info *same = targinfo;
-       struct nf_nat_range newrange;
-       const struct nf_conntrack_tuple *t;
-
-       NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-                       hooknum == NF_IP_POST_ROUTING);
-       ct = nf_ct_get(skb, &ctinfo);
-
-       t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-
-       /* Base new source on real src ip and optionally dst ip,
-          giving some hope for consistency across reboots.
-          Here we calculate the index in same->iparray which
-          holds the ipaddress we should use */
-
-       tmpip = ntohl(t->src.u3.ip);
-
-       if (!(same->info & IPT_SAME_NODST))
-               tmpip += ntohl(t->dst.u3.ip);
-       aindex = tmpip % same->ipnum;
-
-       new_ip = htonl(same->iparray[aindex]);
-
-       pr_debug("ipt_SAME: src=%u.%u.%u.%u dst=%u.%u.%u.%u, "
-                "new src=%u.%u.%u.%u\n",
-                NIPQUAD(t->src.u3.ip), NIPQUAD(t->dst.u3.ip), NIPQUAD(new_ip));
-
-       /* Transfer from original range. */
-       newrange = ((struct nf_nat_range)
-               { same->range[0].flags, new_ip, new_ip,
-                 /* FIXME: Use ports from correct range! */
-                 same->range[0].min, same->range[0].max });
-
-       /* Hand modified range to generic setup. */
-       return nf_nat_setup_info(ct, &newrange, hooknum);
-}
-
-static struct xt_target same_reg __read_mostly = {
-       .name           = "SAME",
-       .family         = AF_INET,
-       .target         = same_target,
-       .targetsize     = sizeof(struct ipt_same_info),
-       .table          = "nat",
-       .hooks          = (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_POST_ROUTING),
-       .checkentry     = same_check,
-       .destroy        = same_destroy,
-       .me             = THIS_MODULE,
-};
-
-static int __init ipt_same_init(void)
-{
-       return xt_register_target(&same_reg);
-}
-
-static void __exit ipt_same_fini(void)
-{
-       xt_unregister_target(&same_reg);
-}
-
-module_init(ipt_same_init);
-module_exit(ipt_same_fini);
-
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
deleted file mode 100644 (file)
index d4573ba..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* This is a module which is used for setting the TOS field of a packet. */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
- *
- * 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/skbuff.h>
-#include <linux/ip.h>
-#include <net/checksum.h>
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv4/ipt_TOS.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables TOS mangling module");
-
-static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
-{
-       const struct ipt_tos_target_info *tosinfo = targinfo;
-       struct iphdr *iph = ip_hdr(skb);
-
-       if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
-               __u8 oldtos;
-               if (!skb_make_writable(skb, sizeof(struct iphdr)))
-                       return NF_DROP;
-               iph = ip_hdr(skb);
-               oldtos = iph->tos;
-               iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
-               nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
-       }
-       return XT_CONTINUE;
-}
-
-static bool
-checkentry(const char *tablename,
-          const void *e_void,
-          const struct xt_target *target,
-          void *targinfo,
-          unsigned int hook_mask)
-{
-       const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos;
-
-       if (tos != IPTOS_LOWDELAY
-           && tos != IPTOS_THROUGHPUT
-           && tos != IPTOS_RELIABILITY
-           && tos != IPTOS_MINCOST
-           && tos != IPTOS_NORMALSVC) {
-               printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
-               return false;
-       }
-       return true;
-}
-
-static struct xt_target ipt_tos_reg __read_mostly = {
-       .name           = "TOS",
-       .family         = AF_INET,
-       .target         = target,
-       .targetsize     = sizeof(struct ipt_tos_target_info),
-       .table          = "mangle",
-       .checkentry     = checkentry,
-       .me             = THIS_MODULE,
-};
-
-static int __init ipt_tos_init(void)
-{
-       return xt_register_target(&ipt_tos_reg);
-}
-
-static void __exit ipt_tos_fini(void)
-{
-       xt_unregister_target(&ipt_tos_reg);
-}
-
-module_init(ipt_tos_init);
-module_exit(ipt_tos_fini);
index c620a052766616349f561e119fe0087d41ea6607..30eed65e7338c717003e2f17ad7e4c6a2f0ef737 100644 (file)
 #include <linux/netfilter_ipv4/ipt_TTL.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("IP tables TTL modification module");
+MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target");
 MODULE_LICENSE("GPL");
 
 static unsigned int
-ipt_ttl_target(struct sk_buff *skb,
-              const struct net_device *in, const struct net_device *out,
-              unsigned int hooknum, const struct xt_target *target,
-              const void *targinfo)
+ttl_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
 {
        struct iphdr *iph;
        const struct ipt_TTL_info *info = targinfo;
@@ -54,19 +53,18 @@ ipt_ttl_target(struct sk_buff *skb,
        }
 
        if (new_ttl != iph->ttl) {
-               nf_csum_replace2(&iph->check, htons(iph->ttl << 8),
-                                             htons(new_ttl << 8));
+               csum_replace2(&iph->check, htons(iph->ttl << 8),
+                                          htons(new_ttl << 8));
                iph->ttl = new_ttl;
        }
 
        return XT_CONTINUE;
 }
 
-static bool ipt_ttl_checkentry(const char *tablename,
-               const void *e,
-               const struct xt_target *target,
-               void *targinfo,
-               unsigned int hook_mask)
+static bool
+ttl_tg_check(const char *tablename, const void *e,
+             const struct xt_target *target, void *targinfo,
+             unsigned int hook_mask)
 {
        const struct ipt_TTL_info *info = targinfo;
 
@@ -80,25 +78,25 @@ static bool ipt_ttl_checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target ipt_TTL __read_mostly = {
+static struct xt_target ttl_tg_reg __read_mostly = {
        .name           = "TTL",
        .family         = AF_INET,
-       .target         = ipt_ttl_target,
+       .target         = ttl_tg,
        .targetsize     = sizeof(struct ipt_TTL_info),
        .table          = "mangle",
-       .checkentry     = ipt_ttl_checkentry,
+       .checkentry     = ttl_tg_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ttl_init(void)
+static int __init ttl_tg_init(void)
 {
-       return xt_register_target(&ipt_TTL);
+       return xt_register_target(&ttl_tg_reg);
 }
 
-static void __exit ipt_ttl_fini(void)
+static void __exit ttl_tg_exit(void)
 {
-       xt_unregister_target(&ipt_TTL);
+       xt_unregister_target(&ttl_tg_reg);
 }
 
-module_init(ipt_ttl_init);
-module_exit(ipt_ttl_fini);
+module_init(ttl_tg_init);
+module_exit(ttl_tg_exit);
index 212b830765a49f75abc1a9ca334d6748e2d99147..b192756c6d0dfa57cd7fa6b9befc43420e823f45 100644 (file)
 #include <linux/netfilter.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ipt_ULOG.h>
+#include <net/netfilter/nf_log.h>
 #include <net/sock.h>
 #include <linux/bitops.h>
 #include <asm/unaligned.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
-MODULE_DESCRIPTION("iptables userspace logging module");
+MODULE_DESCRIPTION("Xtables: packet logging to netlink using ULOG");
 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
 
 #define ULOG_NL_EVENT          111             /* Harald's favorite number */
@@ -279,12 +280,10 @@ alloc_failure:
        spin_unlock_bh(&ulog_lock);
 }
 
-static unsigned int ipt_ulog_target(struct sk_buff *skb,
-                                   const struct net_device *in,
-                                   const struct net_device *out,
-                                   unsigned int hooknum,
-                                   const struct xt_target *target,
-                                   const void *targinfo)
+static unsigned int
+ulog_tg(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
 {
        struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo;
 
@@ -318,11 +317,10 @@ static void ipt_logfn(unsigned int pf,
        ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 
-static bool ipt_ulog_checkentry(const char *tablename,
-                               const void *e,
-                               const struct xt_target *target,
-                               void *targinfo,
-                               unsigned int hookmask)
+static bool
+ulog_tg_check(const char *tablename, const void *e,
+              const struct xt_target *target, void *targinfo,
+              unsigned int hookmask)
 {
        const struct ipt_ulog_info *loginfo = targinfo;
 
@@ -347,7 +345,7 @@ struct compat_ipt_ulog_info {
        char            prefix[ULOG_PREFIX_LEN];
 };
 
-static void compat_from_user(void *dst, void *src)
+static void ulog_tg_compat_from_user(void *dst, void *src)
 {
        const struct compat_ipt_ulog_info *cl = src;
        struct ipt_ulog_info l = {
@@ -360,7 +358,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &l, sizeof(l));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int ulog_tg_compat_to_user(void __user *dst, void *src)
 {
        const struct ipt_ulog_info *l = src;
        struct compat_ipt_ulog_info cl = {
@@ -374,16 +372,16 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target ipt_ulog_reg __read_mostly = {
+static struct xt_target ulog_tg_reg __read_mostly = {
        .name           = "ULOG",
        .family         = AF_INET,
-       .target         = ipt_ulog_target,
+       .target         = ulog_tg,
        .targetsize     = sizeof(struct ipt_ulog_info),
-       .checkentry     = ipt_ulog_checkentry,
+       .checkentry     = ulog_tg_check,
 #ifdef CONFIG_COMPAT
        .compatsize     = sizeof(struct compat_ipt_ulog_info),
-       .compat_from_user = compat_from_user,
-       .compat_to_user = compat_to_user,
+       .compat_from_user = ulog_tg_compat_from_user,
+       .compat_to_user = ulog_tg_compat_to_user,
 #endif
        .me             = THIS_MODULE,
 };
@@ -394,7 +392,7 @@ static struct nf_logger ipt_ulog_logger = {
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ulog_init(void)
+static int __init ulog_tg_init(void)
 {
        int ret, i;
 
@@ -415,9 +413,9 @@ static int __init ipt_ulog_init(void)
        if (!nflognl)
                return -ENOMEM;
 
-       ret = xt_register_target(&ipt_ulog_reg);
+       ret = xt_register_target(&ulog_tg_reg);
        if (ret < 0) {
-               sock_release(nflognl->sk_socket);
+               netlink_kernel_release(nflognl);
                return ret;
        }
        if (nflog)
@@ -426,7 +424,7 @@ static int __init ipt_ulog_init(void)
        return 0;
 }
 
-static void __exit ipt_ulog_fini(void)
+static void __exit ulog_tg_exit(void)
 {
        ulog_buff_t *ub;
        int i;
@@ -435,8 +433,8 @@ static void __exit ipt_ulog_fini(void)
 
        if (nflog)
                nf_log_unregister(&ipt_ulog_logger);
-       xt_unregister_target(&ipt_ulog_reg);
-       sock_release(nflognl->sk_socket);
+       xt_unregister_target(&ulog_tg_reg);
+       netlink_kernel_release(nflognl);
 
        /* remove pending timers and free allocated skb's */
        for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
@@ -453,5 +451,5 @@ static void __exit ipt_ulog_fini(void)
        }
 }
 
-module_init(ipt_ulog_init);
-module_exit(ipt_ulog_fini);
+module_init(ulog_tg_init);
+module_exit(ulog_tg_exit);
index 59f01f7ba6b47c20653674d5693b142421d51e0a..49587a497229e68aa9e1d49e7dcd6f2e78e8afea 100644 (file)
@@ -2,6 +2,7 @@
  *  iptables module to match inet_addr_type() of an ip.
  *
  *  Copyright (c) 2004 Patrick McHardy <kaber@trash.net>
+ *  (C) 2007 Laszlo Attila Toth <panther@balabit.hu>
  *
  *  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
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_DESCRIPTION("iptables addrtype match");
+MODULE_DESCRIPTION("Xtables: address type match for IPv4");
 
-static inline bool match_type(__be32 addr, u_int16_t mask)
+static inline bool match_type(const struct net_device *dev, __be32 addr,
+                             u_int16_t mask)
 {
-       return !!(mask & (1 << inet_addr_type(addr)));
+       return !!(mask & (1 << inet_dev_addr_type(&init_net, dev, addr)));
 }
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in, const struct net_device *out,
-                 const struct xt_match *match, const void *matchinfo,
-                 int offset, unsigned int protoff, bool *hotdrop)
+static bool
+addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+              const struct net_device *out, const struct xt_match *match,
+              const void *matchinfo, int offset, unsigned int protoff,
+              bool *hotdrop)
 {
        const struct ipt_addrtype_info *info = matchinfo;
        const struct iphdr *iph = ip_hdr(skb);
        bool ret = true;
 
        if (info->source)
-               ret &= match_type(iph->saddr, info->source)^info->invert_source;
+               ret &= match_type(NULL, iph->saddr, info->source) ^
+                      info->invert_source;
        if (info->dest)
-               ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
+               ret &= match_type(NULL, iph->daddr, info->dest) ^
+                      info->invert_dest;
 
        return ret;
 }
 
-static struct xt_match addrtype_match __read_mostly = {
-       .name           = "addrtype",
-       .family         = AF_INET,
-       .match          = match,
-       .matchsize      = sizeof(struct ipt_addrtype_info),
-       .me             = THIS_MODULE
+static bool
+addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
+              const struct net_device *out, const struct xt_match *match,
+              const void *matchinfo, int offset, unsigned int protoff,
+              bool *hotdrop)
+{
+       const struct ipt_addrtype_info_v1 *info = matchinfo;
+       const struct iphdr *iph = ip_hdr(skb);
+       const struct net_device *dev = NULL;
+       bool ret = true;
+
+       if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
+               dev = in;
+       else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
+               dev = out;
+
+       if (info->source)
+               ret &= match_type(dev, iph->saddr, info->source) ^
+                      (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
+       if (ret && info->dest)
+               ret &= match_type(dev, iph->daddr, info->dest) ^
+                      (info->flags & IPT_ADDRTYPE_INVERT_DEST);
+       return ret;
+}
+
+static bool
+addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
+                         const struct xt_match *match, void *matchinfo,
+                         unsigned int hook_mask)
+{
+       struct ipt_addrtype_info_v1 *info = matchinfo;
+
+       if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
+           info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+               printk(KERN_ERR "ipt_addrtype: both incoming and outgoing "
+                               "interface limitation cannot be selected\n");
+               return false;
+       }
+
+       if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
+           info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+               printk(KERN_ERR "ipt_addrtype: output interface limitation "
+                               "not valid in PRE_ROUTING and INPUT\n");
+               return false;
+       }
+
+       if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
+           info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+               printk(KERN_ERR "ipt_addrtype: input interface limitation "
+                               "not valid in POST_ROUTING and OUTPUT\n");
+               return false;
+       }
+
+       return true;
+}
+
+static struct xt_match addrtype_mt_reg[] __read_mostly = {
+       {
+               .name           = "addrtype",
+               .family         = AF_INET,
+               .match          = addrtype_mt_v0,
+               .matchsize      = sizeof(struct ipt_addrtype_info),
+               .me             = THIS_MODULE
+       },
+       {
+               .name           = "addrtype",
+               .family         = AF_INET,
+               .revision       = 1,
+               .match          = addrtype_mt_v1,
+               .checkentry     = addrtype_mt_checkentry_v1,
+               .matchsize      = sizeof(struct ipt_addrtype_info_v1),
+               .me             = THIS_MODULE
+       }
 };
 
-static int __init ipt_addrtype_init(void)
+static int __init addrtype_mt_init(void)
 {
-       return xt_register_match(&addrtype_match);
+       return xt_register_matches(addrtype_mt_reg,
+                                  ARRAY_SIZE(addrtype_mt_reg));
 }
 
-static void __exit ipt_addrtype_fini(void)
+static void __exit addrtype_mt_exit(void)
 {
-       xt_unregister_match(&addrtype_match);
+       xt_unregister_matches(addrtype_mt_reg, ARRAY_SIZE(addrtype_mt_reg));
 }
 
-module_init(ipt_addrtype_init);
-module_exit(ipt_addrtype_fini);
+module_init(addrtype_mt_init);
+module_exit(addrtype_mt_exit);
index 61b017fd743c14987fea3038b1781bfb2ee7634d..e977989629c79139ff844b91598aeef7a3c0c781 100644 (file)
@@ -16,7 +16,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
-MODULE_DESCRIPTION("iptables AH SPI match module");
+MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match");
 
 #ifdef DEBUG_CONNTRACK
 #define duprintf(format, args...) printk(format , ## args)
@@ -37,14 +37,9 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+ah_mt(const struct sk_buff *skb, const struct net_device *in,
+      const struct net_device *out, const struct xt_match *match,
+      const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct ip_auth_hdr _ahdr;
        const struct ip_auth_hdr *ah;
@@ -72,11 +67,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *ip_void,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+ah_mt_check(const char *tablename, const void *ip_void,
+            const struct xt_match *match, void *matchinfo,
+            unsigned int hook_mask)
 {
        const struct ipt_ah *ahinfo = matchinfo;
 
@@ -88,25 +81,25 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match ah_match __read_mostly = {
+static struct xt_match ah_mt_reg __read_mostly = {
        .name           = "ah",
        .family         = AF_INET,
-       .match          = match,
+       .match          = ah_mt,
        .matchsize      = sizeof(struct ipt_ah),
        .proto          = IPPROTO_AH,
-       .checkentry     = checkentry,
+       .checkentry     = ah_mt_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ah_init(void)
+static int __init ah_mt_init(void)
 {
-       return xt_register_match(&ah_match);
+       return xt_register_match(&ah_mt_reg);
 }
 
-static void __exit ipt_ah_fini(void)
+static void __exit ah_mt_exit(void)
 {
-       xt_unregister_match(&ah_match);
+       xt_unregister_match(&ah_mt_reg);
 }
 
-module_init(ipt_ah_init);
-module_exit(ipt_ah_fini);
+module_init(ah_mt_init);
+module_exit(ah_mt_exit);
index d6925c6740692a730c64fc6313bc788fd8a72e45..749de8284ce53fb61cc17c56e7b584fa1cd77031 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/netfilter_ipv4/ipt_ecn.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("iptables ECN matching module");
+MODULE_DESCRIPTION("Xtables: Explicit Congestion Notification (ECN) flag match for IPv4");
 MODULE_LICENSE("GPL");
 
 static inline bool match_ip(const struct sk_buff *skb,
@@ -67,10 +67,10 @@ static inline bool match_tcp(const struct sk_buff *skb,
        return true;
 }
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in, const struct net_device *out,
-                 const struct xt_match *match, const void *matchinfo,
-                 int offset, unsigned int protoff, bool *hotdrop)
+static bool
+ecn_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_ecn_info *info = matchinfo;
 
@@ -88,9 +88,10 @@ static bool match(const struct sk_buff *skb,
        return true;
 }
 
-static bool checkentry(const char *tablename, const void *ip_void,
-                      const struct xt_match *match,
-                      void *matchinfo, unsigned int hook_mask)
+static bool
+ecn_mt_check(const char *tablename, const void *ip_void,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct ipt_ecn_info *info = matchinfo;
        const struct ipt_ip *ip = ip_void;
@@ -111,24 +112,24 @@ static bool checkentry(const char *tablename, const void *ip_void,
        return true;
 }
 
-static struct xt_match ecn_match __read_mostly = {
+static struct xt_match ecn_mt_reg __read_mostly = {
        .name           = "ecn",
        .family         = AF_INET,
-       .match          = match,
+       .match          = ecn_mt,
        .matchsize      = sizeof(struct ipt_ecn_info),
-       .checkentry     = checkentry,
+       .checkentry     = ecn_mt_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ecn_init(void)
+static int __init ecn_mt_init(void)
 {
-       return xt_register_match(&ecn_match);
+       return xt_register_match(&ecn_mt_reg);
 }
 
-static void __exit ipt_ecn_fini(void)
+static void __exit ecn_mt_exit(void)
 {
-       xt_unregister_match(&ecn_match);
+       xt_unregister_match(&ecn_mt_reg);
 }
 
-module_init(ipt_ecn_init);
-module_exit(ipt_ecn_fini);
+module_init(ecn_mt_init);
+module_exit(ecn_mt_exit);
diff --git a/net/ipv4/netfilter/ipt_iprange.c b/net/ipv4/netfilter/ipt_iprange.c
deleted file mode 100644 (file)
index 0106dc9..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * iptables module to match IP address ranges
- *
- * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
- *
- * 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/skbuff.h>
-#include <linux/ip.h>
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv4/ipt_iprange.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
-MODULE_DESCRIPTION("iptables arbitrary IP range match module");
-
-static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset, unsigned int protoff, bool *hotdrop)
-{
-       const struct ipt_iprange_info *info = matchinfo;
-       const struct iphdr *iph = ip_hdr(skb);
-
-       if (info->flags & IPRANGE_SRC) {
-               if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
-                         || ntohl(iph->saddr) > ntohl(info->src.max_ip))
-                        ^ !!(info->flags & IPRANGE_SRC_INV)) {
-                       pr_debug("src IP %u.%u.%u.%u NOT in range %s"
-                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                                NIPQUAD(iph->saddr),
-                                info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
-                                NIPQUAD(info->src.min_ip),
-                                NIPQUAD(info->src.max_ip));
-                       return false;
-               }
-       }
-       if (info->flags & IPRANGE_DST) {
-               if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
-                         || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
-                        ^ !!(info->flags & IPRANGE_DST_INV)) {
-                       pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
-                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
-                                NIPQUAD(iph->daddr),
-                                info->flags & IPRANGE_DST_INV ? "(INV) " : "",
-                                NIPQUAD(info->dst.min_ip),
-                                NIPQUAD(info->dst.max_ip));
-                       return false;
-               }
-       }
-       return true;
-}
-
-static struct xt_match iprange_match __read_mostly = {
-       .name           = "iprange",
-       .family         = AF_INET,
-       .match          = match,
-       .matchsize      = sizeof(struct ipt_iprange_info),
-       .me             = THIS_MODULE
-};
-
-static int __init ipt_iprange_init(void)
-{
-       return xt_register_match(&iprange_match);
-}
-
-static void __exit ipt_iprange_fini(void)
-{
-       xt_unregister_match(&iprange_match);
-}
-
-module_init(ipt_iprange_init);
-module_exit(ipt_iprange_fini);
diff --git a/net/ipv4/netfilter/ipt_owner.c b/net/ipv4/netfilter/ipt_owner.c
deleted file mode 100644 (file)
index b14e77d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets. */
-
-/* (C) 2000 Marc Boucher <marc@mbsi.ca>
- *
- * 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/skbuff.h>
-#include <linux/file.h>
-#include <linux/rcupdate.h>
-#include <net/sock.h>
-
-#include <linux/netfilter_ipv4/ipt_owner.h>
-#include <linux/netfilter/x_tables.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("iptables owner match");
-
-static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
-{
-       const struct ipt_owner_info *info = matchinfo;
-
-       if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-               return false;
-
-       if(info->match & IPT_OWNER_UID) {
-               if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
-                   !!(info->invert & IPT_OWNER_UID))
-                       return false;
-       }
-
-       if(info->match & IPT_OWNER_GID) {
-               if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
-                   !!(info->invert & IPT_OWNER_GID))
-                       return false;
-       }
-
-       return true;
-}
-
-static bool
-checkentry(const char *tablename,
-          const void *ip,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
-{
-       const struct ipt_owner_info *info = matchinfo;
-
-       if (info->match & (IPT_OWNER_PID|IPT_OWNER_SID|IPT_OWNER_COMM)) {
-               printk("ipt_owner: pid, sid and command matching "
-                      "not supported anymore\n");
-               return false;
-       }
-       return true;
-}
-
-static struct xt_match owner_match __read_mostly = {
-       .name           = "owner",
-       .family         = AF_INET,
-       .match          = match,
-       .matchsize      = sizeof(struct ipt_owner_info),
-       .hooks          = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_POST_ROUTING),
-       .checkentry     = checkentry,
-       .me             = THIS_MODULE,
-};
-
-static int __init ipt_owner_init(void)
-{
-       return xt_register_match(&owner_match);
-}
-
-static void __exit ipt_owner_fini(void)
-{
-       xt_unregister_match(&owner_match);
-}
-
-module_init(ipt_owner_init);
-module_exit(ipt_owner_fini);
index 11d39fb5f38bade83b7ce74aa5a435f6e38da854..e3154a99c08ae9d975378b80684b8f361fd07839 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/netfilter_ipv4/ipt_recent.h>
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_DESCRIPTION("IP tables recently seen matching module");
+MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4");
 MODULE_LICENSE("GPL");
 
 static unsigned int ip_list_tot = 100;
@@ -170,10 +170,10 @@ static void recent_table_flush(struct recent_table *t)
 }
 
 static bool
-ipt_recent_match(const struct sk_buff *skb,
-                const struct net_device *in, const struct net_device *out,
-                const struct xt_match *match, const void *matchinfo,
-                int offset, unsigned int protoff, bool *hotdrop)
+recent_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
@@ -236,9 +236,9 @@ out:
 }
 
 static bool
-ipt_recent_checkentry(const char *tablename, const void *ip,
-                     const struct xt_match *match, void *matchinfo,
-                     unsigned int hook_mask)
+recent_mt_check(const char *tablename, const void *ip,
+                const struct xt_match *match, void *matchinfo,
+                unsigned int hook_mask)
 {
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
@@ -293,8 +293,7 @@ out:
        return ret;
 }
 
-static void
-ipt_recent_destroy(const struct xt_match *match, void *matchinfo)
+static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        const struct ipt_recent_info *info = matchinfo;
        struct recent_table *t;
@@ -455,17 +454,17 @@ static const struct file_operations recent_fops = {
 };
 #endif /* CONFIG_PROC_FS */
 
-static struct xt_match recent_match __read_mostly = {
+static struct xt_match recent_mt_reg __read_mostly = {
        .name           = "recent",
        .family         = AF_INET,
-       .match          = ipt_recent_match,
+       .match          = recent_mt,
        .matchsize      = sizeof(struct ipt_recent_info),
-       .checkentry     = ipt_recent_checkentry,
-       .destroy        = ipt_recent_destroy,
+       .checkentry     = recent_mt_check,
+       .destroy        = recent_mt_destroy,
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_recent_init(void)
+static int __init recent_mt_init(void)
 {
        int err;
 
@@ -473,27 +472,27 @@ static int __init ipt_recent_init(void)
                return -EINVAL;
        ip_list_hash_size = 1 << fls(ip_list_tot);
 
-       err = xt_register_match(&recent_match);
+       err = xt_register_match(&recent_mt_reg);
 #ifdef CONFIG_PROC_FS
        if (err)
                return err;
        proc_dir = proc_mkdir("ipt_recent", init_net.proc_net);
        if (proc_dir == NULL) {
-               xt_unregister_match(&recent_match);
+               xt_unregister_match(&recent_mt_reg);
                err = -ENOMEM;
        }
 #endif
        return err;
 }
 
-static void __exit ipt_recent_exit(void)
+static void __exit recent_mt_exit(void)
 {
        BUG_ON(!list_empty(&tables));
-       xt_unregister_match(&recent_match);
+       xt_unregister_match(&recent_mt_reg);
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("ipt_recent", init_net.proc_net);
 #endif
 }
 
-module_init(ipt_recent_init);
-module_exit(ipt_recent_exit);
+module_init(recent_mt_init);
+module_exit(recent_mt_exit);
diff --git a/net/ipv4/netfilter/ipt_tos.c b/net/ipv4/netfilter/ipt_tos.c
deleted file mode 100644 (file)
index e740441..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Kernel module to match TOS values. */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
- *
- * 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/ip.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-
-#include <linux/netfilter_ipv4/ipt_tos.h>
-#include <linux/netfilter/x_tables.h>
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("iptables TOS match module");
-
-static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
-{
-       const struct ipt_tos_info *info = matchinfo;
-
-       return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
-}
-
-static struct xt_match tos_match __read_mostly = {
-       .name           = "tos",
-       .family         = AF_INET,
-       .match          = match,
-       .matchsize      = sizeof(struct ipt_tos_info),
-       .me             = THIS_MODULE,
-};
-
-static int __init ipt_multiport_init(void)
-{
-       return xt_register_match(&tos_match);
-}
-
-static void __exit ipt_multiport_fini(void)
-{
-       xt_unregister_match(&tos_match);
-}
-
-module_init(ipt_multiport_init);
-module_exit(ipt_multiport_fini);
index a439900a4ba5caa5066946aea2fff7350fde60f0..e0b8caeb710c9d188ded36dd0acb790719cf6c9b 100644 (file)
 #include <linux/netfilter/x_tables.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("IP tables TTL matching module");
+MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
 MODULE_LICENSE("GPL");
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in, const struct net_device *out,
-                 const struct xt_match *match, const void *matchinfo,
-                 int offset, unsigned int protoff, bool *hotdrop)
+static bool
+ttl_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ipt_ttl_info *info = matchinfo;
        const u8 ttl = ip_hdr(skb)->ttl;
@@ -44,23 +44,23 @@ static bool match(const struct sk_buff *skb,
        return false;
 }
 
-static struct xt_match ttl_match __read_mostly = {
+static struct xt_match ttl_mt_reg __read_mostly = {
        .name           = "ttl",
        .family         = AF_INET,
-       .match          = match,
+       .match          = ttl_mt,
        .matchsize      = sizeof(struct ipt_ttl_info),
        .me             = THIS_MODULE,
 };
 
-static int __init ipt_ttl_init(void)
+static int __init ttl_mt_init(void)
 {
-       return xt_register_match(&ttl_match);
+       return xt_register_match(&ttl_mt_reg);
 }
 
-static void __exit ipt_ttl_fini(void)
+static void __exit ttl_mt_exit(void)
 {
-       xt_unregister_match(&ttl_match);
+       xt_unregister_match(&ttl_mt_reg);
 }
 
-module_init(ipt_ttl_init);
-module_exit(ipt_ttl_fini);
+module_init(ttl_mt_init);
+module_exit(ttl_mt_exit);
index ba3262c604376307ac40f35dc2ffef91a8f7f116..29bb4f9fbda0f7f7d4fcc5cce744e557907f0e86 100644 (file)
@@ -19,7 +19,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables filter table");
 
-#define FILTER_VALID_HOOKS ((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
+                           (1 << NF_INET_FORWARD) | \
+                           (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -33,14 +35,14 @@ static struct
                .num_entries = 4,
                .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
                .hook_entry = {
-                       [NF_IP_LOCAL_IN] = 0,
-                       [NF_IP_FORWARD] = sizeof(struct ipt_standard),
-                       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+                       [NF_INET_LOCAL_IN] = 0,
+                       [NF_INET_FORWARD] = sizeof(struct ipt_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
                },
                .underflow = {
-                       [NF_IP_LOCAL_IN] = 0,
-                       [NF_IP_FORWARD] = sizeof(struct ipt_standard),
-                       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
+                       [NF_INET_LOCAL_IN] = 0,
+                       [NF_INET_FORWARD] = sizeof(struct ipt_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2,
                },
        },
        .entries = {
@@ -89,26 +91,26 @@ ipt_local_out_hook(unsigned int hook,
        return ipt_do_table(skb, hook, in, out, &packet_filter);
 }
 
-static struct nf_hook_ops ipt_ops[] = {
+static struct nf_hook_ops ipt_ops[] __read_mostly = {
        {
                .hook           = ipt_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_FILTER,
        },
        {
                .hook           = ipt_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_FORWARD,
+               .hooknum        = NF_INET_FORWARD,
                .priority       = NF_IP_PRI_FILTER,
        },
        {
                .hook           = ipt_local_out_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_FILTER,
        },
 };
index b4360a69d5ca9cdb979afc2cc16d53bbacd363bb..5c4be202430c8b7dbcabea9306ae8989b8d29f1d 100644 (file)
@@ -21,11 +21,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("iptables mangle table");
 
-#define MANGLE_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | \
-                           (1 << NF_IP_LOCAL_IN) | \
-                           (1 << NF_IP_FORWARD) | \
-                           (1 << NF_IP_LOCAL_OUT) | \
-                           (1 << NF_IP_POST_ROUTING))
+#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+                           (1 << NF_INET_LOCAL_IN) | \
+                           (1 << NF_INET_FORWARD) | \
+                           (1 << NF_INET_LOCAL_OUT) | \
+                           (1 << NF_INET_POST_ROUTING))
 
 /* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
 static struct
@@ -40,18 +40,18 @@ static struct
                .num_entries = 6,
                .size = sizeof(struct ipt_standard) * 5 + sizeof(struct ipt_error),
                .hook_entry = {
-                       [NF_IP_PRE_ROUTING]     = 0,
-                       [NF_IP_LOCAL_IN]        = sizeof(struct ipt_standard),
-                       [NF_IP_FORWARD]         = sizeof(struct ipt_standard) * 2,
-                       [NF_IP_LOCAL_OUT]       = sizeof(struct ipt_standard) * 3,
-                       [NF_IP_POST_ROUTING]    = sizeof(struct ipt_standard) * 4,
+                       [NF_INET_PRE_ROUTING]   = 0,
+                       [NF_INET_LOCAL_IN]      = sizeof(struct ipt_standard),
+                       [NF_INET_FORWARD]       = sizeof(struct ipt_standard) * 2,
+                       [NF_INET_LOCAL_OUT]     = sizeof(struct ipt_standard) * 3,
+                       [NF_INET_POST_ROUTING]  = sizeof(struct ipt_standard) * 4,
                },
                .underflow = {
-                       [NF_IP_PRE_ROUTING]     = 0,
-                       [NF_IP_LOCAL_IN]        = sizeof(struct ipt_standard),
-                       [NF_IP_FORWARD]         = sizeof(struct ipt_standard) * 2,
-                       [NF_IP_LOCAL_OUT]       = sizeof(struct ipt_standard) * 3,
-                       [NF_IP_POST_ROUTING]    = sizeof(struct ipt_standard) * 4,
+                       [NF_INET_PRE_ROUTING]   = 0,
+                       [NF_INET_LOCAL_IN]      = sizeof(struct ipt_standard),
+                       [NF_INET_FORWARD]       = sizeof(struct ipt_standard) * 2,
+                       [NF_INET_LOCAL_OUT]     = sizeof(struct ipt_standard) * 3,
+                       [NF_INET_POST_ROUTING]  = sizeof(struct ipt_standard) * 4,
                },
        },
        .entries = {
@@ -128,40 +128,40 @@ ipt_local_hook(unsigned int hook,
        return ret;
 }
 
-static struct nf_hook_ops ipt_ops[] = {
+static struct nf_hook_ops ipt_ops[] __read_mostly = {
        {
                .hook           = ipt_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_MANGLE,
        },
        {
                .hook           = ipt_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_MANGLE,
        },
        {
                .hook           = ipt_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_FORWARD,
+               .hooknum        = NF_INET_FORWARD,
                .priority       = NF_IP_PRI_MANGLE,
        },
        {
                .hook           = ipt_local_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_MANGLE,
        },
        {
                .hook           = ipt_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_MANGLE,
        },
 };
index f8678651250f0b349058e9243444372ab8b1d95a..dc34aa274533b8d5893fd6d4bd3642a003c19e28 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <net/ip.h>
 
-#define RAW_VALID_HOOKS ((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT))
+#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -21,12 +21,12 @@ static struct
                .num_entries = 3,
                .size = sizeof(struct ipt_standard) * 2 + sizeof(struct ipt_error),
                .hook_entry = {
-                       [NF_IP_PRE_ROUTING] = 0,
-                       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard)
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard)
                },
                .underflow = {
-                       [NF_IP_PRE_ROUTING] = 0,
-                       [NF_IP_LOCAL_OUT]  = sizeof(struct ipt_standard)
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_LOCAL_OUT]  = sizeof(struct ipt_standard)
                },
        },
        .entries = {
@@ -74,18 +74,18 @@ ipt_local_hook(unsigned int hook,
 }
 
 /* 'raw' is the very first table. */
-static struct nf_hook_ops ipt_ops[] = {
+static struct nf_hook_ops ipt_ops[] __read_mostly = {
        {
                .hook = ipt_hook,
                .pf = PF_INET,
-               .hooknum = NF_IP_PRE_ROUTING,
+               .hooknum = NF_INET_PRE_ROUTING,
                .priority = NF_IP_PRI_RAW,
                .owner = THIS_MODULE,
        },
        {
                .hook = ipt_local_hook,
                .pf = PF_INET,
-               .hooknum = NF_IP_LOCAL_OUT,
+               .hooknum = NF_INET_LOCAL_OUT,
                .priority = NF_IP_PRI_RAW,
                .owner = THIS_MODULE,
        },
index 910dae732a0f14c3987bd4792ebce42137013636..ac3d61d8026e2d6d0052b0ca2d30b20433224413 100644 (file)
@@ -56,12 +56,6 @@ static int ipv4_print_tuple(struct seq_file *s,
                          NIPQUAD(tuple->dst.u3.ip));
 }
 
-static int ipv4_print_conntrack(struct seq_file *s,
-                               const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns new sk_buff, or NULL */
 static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
 {
@@ -150,7 +144,7 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
        /* Gather fragments. */
        if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
                if (nf_ct_ipv4_gather_frags(skb,
-                                           hooknum == NF_IP_PRE_ROUTING ?
+                                           hooknum == NF_INET_PRE_ROUTING ?
                                            IP_DEFRAG_CONNTRACK_IN :
                                            IP_DEFRAG_CONNTRACK_OUT))
                        return NF_STOLEN;
@@ -185,61 +179,61 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
 
 /* Connection tracking may drop packets, but never alters them, so
    make it the first hook. */
-static struct nf_hook_ops ipv4_conntrack_ops[] = {
+static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
        {
                .hook           = ipv4_conntrack_defrag,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
        },
        {
                .hook           = ipv4_conntrack_in,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_CONNTRACK,
        },
        {
                .hook           = ipv4_conntrack_defrag,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_CONNTRACK_DEFRAG,
        },
        {
                .hook           = ipv4_conntrack_local,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_CONNTRACK,
        },
        {
                .hook           = ipv4_conntrack_help,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_CONNTRACK_HELPER,
        },
        {
                .hook           = ipv4_conntrack_help,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_CONNTRACK_HELPER,
        },
        {
                .hook           = ipv4_confirm,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_CONNTRACK_CONFIRM,
        },
        {
                .hook           = ipv4_confirm,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_CONNTRACK_CONFIRM,
        },
 };
@@ -363,10 +357,8 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
 static int ipv4_tuple_to_nlattr(struct sk_buff *skb,
                                const struct nf_conntrack_tuple *tuple)
 {
-       NLA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t),
-               &tuple->src.u3.ip);
-       NLA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t),
-               &tuple->dst.u3.ip);
+       NLA_PUT_BE32(skb, CTA_IP_V4_SRC, tuple->src.u3.ip);
+       NLA_PUT_BE32(skb, CTA_IP_V4_DST, tuple->dst.u3.ip);
        return 0;
 
 nla_put_failure:
@@ -384,8 +376,8 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
        if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST])
                return -EINVAL;
 
-       t->src.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_SRC]);
-       t->dst.u3.ip = *(__be32 *)nla_data(tb[CTA_IP_V4_DST]);
+       t->src.u3.ip = nla_get_be32(tb[CTA_IP_V4_SRC]);
+       t->dst.u3.ip = nla_get_be32(tb[CTA_IP_V4_DST]);
 
        return 0;
 }
@@ -405,7 +397,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
        .pkt_to_tuple    = ipv4_pkt_to_tuple,
        .invert_tuple    = ipv4_invert_tuple,
        .print_tuple     = ipv4_print_tuple,
-       .print_conntrack = ipv4_print_conntrack,
        .get_l4proto     = ipv4_get_l4proto,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nlattr = ipv4_tuple_to_nlattr,
index 741f3dfaa5a101efe385dc9c30755a8e8de218dd..543c02b74c96be28532e1c30a01929cea0a70547 100644 (file)
@@ -121,10 +121,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                      ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
                return -ENOSPC;
 
-       if (l3proto->print_conntrack(s, ct))
-               return -ENOSPC;
-
-       if (l4proto->print_conntrack(s, ct))
+       if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
                return -ENOSPC;
 
        if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
index adcbaf6d4299c8be3c94ccd815f23bc736a6cbf3..4004a04c551014205886bc3768523a77f2ccdd2b 100644 (file)
@@ -18,6 +18,7 @@
 #include <net/netfilter/nf_conntrack_tuple.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_log.h>
 
 static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
 
@@ -73,13 +74,6 @@ static int icmp_print_tuple(struct seq_file *s,
                          ntohs(tuple->src.u.icmp.id));
 }
 
-/* Print out the private part of the conntrack. */
-static int icmp_print_conntrack(struct seq_file *s,
-                               const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, or -1 for invalid. */
 static int icmp_packet(struct nf_conn *ct,
                       const struct sk_buff *skb,
@@ -128,7 +122,6 @@ static int icmp_new(struct nf_conn *conntrack,
        return 1;
 }
 
-extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 /* Returns conntrack if it dealt with ICMP, and filled in skb fields */
 static int
 icmp_error_message(struct sk_buff *skb,
@@ -195,7 +188,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
        }
 
        /* See ip_conntrack_proto_tcp.c */
-       if (nf_conntrack_checksum && hooknum == NF_IP_PRE_ROUTING &&
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_ip_checksum(skb, hooknum, dataoff, 0)) {
                if (LOG_INVALID(IPPROTO_ICMP))
                        nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
@@ -235,12 +228,9 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
 static int icmp_tuple_to_nlattr(struct sk_buff *skb,
                                const struct nf_conntrack_tuple *t)
 {
-       NLA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t),
-               &t->src.u.icmp.id);
-       NLA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
-               &t->dst.u.icmp.type);
-       NLA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
-               &t->dst.u.icmp.code);
+       NLA_PUT_BE16(skb, CTA_PROTO_ICMP_ID, t->src.u.icmp.id);
+       NLA_PUT_U8(skb, CTA_PROTO_ICMP_TYPE, t->dst.u.icmp.type);
+       NLA_PUT_U8(skb, CTA_PROTO_ICMP_CODE, t->dst.u.icmp.code);
 
        return 0;
 
@@ -262,12 +252,9 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[],
            || !tb[CTA_PROTO_ICMP_ID])
                return -EINVAL;
 
-       tuple->dst.u.icmp.type =
-                       *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMP_TYPE]);
-       tuple->dst.u.icmp.code =
-                       *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMP_CODE]);
-       tuple->src.u.icmp.id =
-                       *(__be16 *)nla_data(tb[CTA_PROTO_ICMP_ID]);
+       tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]);
+       tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMP_CODE]);
+       tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]);
 
        if (tuple->dst.u.icmp.type >= sizeof(invmap)
            || !invmap[tuple->dst.u.icmp.type])
@@ -315,7 +302,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
        .pkt_to_tuple           = icmp_pkt_to_tuple,
        .invert_tuple           = icmp_invert_tuple,
        .print_tuple            = icmp_print_tuple,
-       .print_conntrack        = icmp_print_conntrack,
        .packet                 = icmp_packet,
        .new                    = icmp_new,
        .error                  = icmp_error,
index 86b465b176baad0e0a3a504d47cb2d059894cf20..e53ae1ef8f5e1f0dae45e5d191b079c681a0dcb3 100644 (file)
 
 static DEFINE_RWLOCK(nf_nat_lock);
 
-static struct nf_conntrack_l3proto *l3proto = NULL;
+static struct nf_conntrack_l3proto *l3proto __read_mostly;
 
 /* Calculated at init based on memory size */
-static unsigned int nf_nat_htable_size;
+static unsigned int nf_nat_htable_size __read_mostly;
 static int nf_nat_vmalloced;
 
-static struct hlist_head *bysource;
+static struct hlist_head *bysource __read_mostly;
 
 #define MAX_IP_NAT_PROTO 256
-static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO];
+static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
+                                               __read_mostly;
 
-static inline struct nf_nat_protocol *
+static inline const struct nf_nat_protocol *
 __nf_nat_proto_find(u_int8_t protonum)
 {
        return rcu_dereference(nf_nat_protos[protonum]);
 }
 
-struct nf_nat_protocol *
+const struct nf_nat_protocol *
 nf_nat_proto_find_get(u_int8_t protonum)
 {
-       struct nf_nat_protocol *p;
+       const struct nf_nat_protocol *p;
 
        rcu_read_lock();
        p = __nf_nat_proto_find(protonum);
@@ -66,7 +67,7 @@ nf_nat_proto_find_get(u_int8_t protonum)
 EXPORT_SYMBOL_GPL(nf_nat_proto_find_get);
 
 void
-nf_nat_proto_put(struct nf_nat_protocol *p)
+nf_nat_proto_put(const struct nf_nat_protocol *p)
 {
        module_put(p->me);
 }
@@ -76,10 +77,13 @@ EXPORT_SYMBOL_GPL(nf_nat_proto_put);
 static inline unsigned int
 hash_by_src(const struct nf_conntrack_tuple *tuple)
 {
+       unsigned int hash;
+
        /* Original src, to ensure we map it consistently if poss. */
-       return jhash_3words((__force u32)tuple->src.u3.ip,
+       hash = jhash_3words((__force u32)tuple->src.u3.ip,
                            (__force u32)tuple->src.u.all,
-                           tuple->dst.protonum, 0) % nf_nat_htable_size;
+                           tuple->dst.protonum, 0);
+       return ((u64)hash * nf_nat_htable_size) >> 32;
 }
 
 /* Is this tuple already taken? (not by us) */
@@ -105,7 +109,7 @@ static int
 in_range(const struct nf_conntrack_tuple *tuple,
         const struct nf_nat_range *range)
 {
-       struct nf_nat_protocol *proto;
+       const struct nf_nat_protocol *proto;
        int ret = 0;
 
        /* If we are supposed to map IPs, then we must be in the
@@ -210,12 +214,13 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
        maxip = ntohl(range->max_ip);
        j = jhash_2words((__force u32)tuple->src.u3.ip,
                         (__force u32)tuple->dst.u3.ip, 0);
-       *var_ipp = htonl(minip + j % (maxip - minip + 1));
+       j = ((u64)j * (maxip - minip + 1)) >> 32;
+       *var_ipp = htonl(minip + j);
 }
 
-/* Manipulate the tuple into the range given.  For NF_IP_POST_ROUTING,
- * we change the source to map into the range.  For NF_IP_PRE_ROUTING
- * and NF_IP_LOCAL_OUT, we change the destination to map into the
+/* Manipulate the tuple into the range given.  For NF_INET_POST_ROUTING,
+ * we change the source to map into the range.  For NF_INET_PRE_ROUTING
+ * and NF_INET_LOCAL_OUT, we change the destination to map into the
  * range.  It might not be possible to get a unique tuple, but we try.
  * At worst (or if we race), we will end up with a final duplicate in
  * __ip_conntrack_confirm and drop the packet. */
@@ -226,7 +231,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
                 struct nf_conn *ct,
                 enum nf_nat_manip_type maniptype)
 {
-       struct nf_nat_protocol *proto;
+       const struct nf_nat_protocol *proto;
 
        /* 1) If this srcip/proto/src-proto-part is currently mapped,
           and that same mapping gives a unique tuple within the given
@@ -276,12 +281,11 @@ out:
 unsigned int
 nf_nat_setup_info(struct nf_conn *ct,
                  const struct nf_nat_range *range,
-                 unsigned int hooknum)
+                 enum nf_nat_manip_type maniptype)
 {
        struct nf_conntrack_tuple curr_tuple, new_tuple;
        struct nf_conn_nat *nat;
        int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
-       enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
 
        /* nat helper or nfctnetlink also setup binding */
        nat = nfct_nat(ct);
@@ -293,10 +297,8 @@ nf_nat_setup_info(struct nf_conn *ct,
                }
        }
 
-       NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-                    hooknum == NF_IP_POST_ROUTING ||
-                    hooknum == NF_IP_LOCAL_IN ||
-                    hooknum == NF_IP_LOCAL_OUT);
+       NF_CT_ASSERT(maniptype == IP_NAT_MANIP_SRC ||
+                    maniptype == IP_NAT_MANIP_DST);
        BUG_ON(nf_nat_initialized(ct, maniptype));
 
        /* What we've got will look like inverse of reply. Normally
@@ -355,7 +357,7 @@ manip_pkt(u_int16_t proto,
          enum nf_nat_manip_type maniptype)
 {
        struct iphdr *iph;
-       struct nf_nat_protocol *p;
+       const struct nf_nat_protocol *p;
 
        if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
                return 0;
@@ -372,10 +374,10 @@ manip_pkt(u_int16_t proto,
        iph = (void *)skb->data + iphdroff;
 
        if (maniptype == IP_NAT_MANIP_SRC) {
-               nf_csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
+               csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
                iph->saddr = target->src.u3.ip;
        } else {
-               nf_csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
+               csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
                iph->daddr = target->dst.u3.ip;
        }
        return 1;
@@ -515,7 +517,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
 EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation);
 
 /* Protocol registration. */
-int nf_nat_protocol_register(struct nf_nat_protocol *proto)
+int nf_nat_protocol_register(const struct nf_nat_protocol *proto)
 {
        int ret = 0;
 
@@ -532,7 +534,7 @@ int nf_nat_protocol_register(struct nf_nat_protocol *proto)
 EXPORT_SYMBOL(nf_nat_protocol_register);
 
 /* Noone stores the protocol anywhere; simply delete it. */
-void nf_nat_protocol_unregister(struct nf_nat_protocol *proto)
+void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
 {
        write_lock_bh(&nf_nat_lock);
        rcu_assign_pointer(nf_nat_protos[proto->protonum],
@@ -547,10 +549,8 @@ int
 nf_nat_port_range_to_nlattr(struct sk_buff *skb,
                            const struct nf_nat_range *range)
 {
-       NLA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16),
-               &range->min.tcp.port);
-       NLA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16),
-               &range->max.tcp.port);
+       NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.tcp.port);
+       NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.tcp.port);
 
        return 0;
 
@@ -568,8 +568,7 @@ nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range)
 
        if (tb[CTA_PROTONAT_PORT_MIN]) {
                ret = 1;
-               range->min.tcp.port =
-                       *(__be16 *)nla_data(tb[CTA_PROTONAT_PORT_MIN]);
+               range->min.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]);
        }
 
        if (!tb[CTA_PROTONAT_PORT_MAX]) {
@@ -577,8 +576,7 @@ nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range)
                        range->max.tcp.port = range->min.tcp.port;
        } else {
                ret = 1;
-               range->max.tcp.port =
-                       *(__be16 *)nla_data(tb[CTA_PROTONAT_PORT_MAX]);
+               range->max.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]);
        }
 
        return ret;
index 93e18ef114f2e1052798d1b2d2f200cafb345b6a..a121989fdad7c5c38363fe77d447c43dc07038b5 100644 (file)
@@ -76,7 +76,7 @@ static int set_addr(struct sk_buff *skb,
 static int set_h225_addr(struct sk_buff *skb,
                         unsigned char **data, int dataoff,
                         TransportAddress *taddr,
-                        union nf_conntrack_address *addr, __be16 port)
+                        union nf_inet_addr *addr, __be16 port)
 {
        return set_addr(skb, data, dataoff, taddr->ipAddress.ip,
                        addr->ip, port);
@@ -86,7 +86,7 @@ static int set_h225_addr(struct sk_buff *skb,
 static int set_h245_addr(struct sk_buff *skb,
                         unsigned char **data, int dataoff,
                         H245_TransportAddress *taddr,
-                        union nf_conntrack_address *addr, __be16 port)
+                        union nf_inet_addr *addr, __be16 port)
 {
        return set_addr(skb, data, dataoff,
                        taddr->unicastAddress.iPAddress.network,
@@ -103,7 +103,7 @@ static int set_sig_addr(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int i;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
 
        for (i = 0; i < count; i++) {
                if (get_h225_addr(ct, *data, &taddr[i], &addr, &port)) {
@@ -155,7 +155,7 @@ static int set_ras_addr(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int i;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
 
        for (i = 0; i < count; i++) {
                if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
@@ -389,18 +389,14 @@ static void ip_nat_q931_expect(struct nf_conn *new,
        /* Change src to where master sends to */
        range.flags = IP_NAT_RANGE_MAP_IPS;
        range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
-
-       /* hook doesn't matter, but it has to do source manip */
-       nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
+       nf_nat_setup_info(new, &range, IP_NAT_MANIP_SRC);
 
        /* For DST manip, map port here to where it's expected. */
        range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
        range.min = range.max = this->saved_proto;
        range.min_ip = range.max_ip =
            new->master->tuplehash[!this->dir].tuple.src.u3.ip;
-
-       /* hook doesn't matter, but it has to do destination manip */
-       nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
+       nf_nat_setup_info(new, &range, IP_NAT_MANIP_DST);
 }
 
 /****************************************************************************/
@@ -412,7 +408,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct,
        struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        u_int16_t nated_port = ntohs(port);
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
 
        /* Set expectations for NAT */
        exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
@@ -479,17 +475,13 @@ static void ip_nat_callforwarding_expect(struct nf_conn *new,
        /* Change src to where master sends to */
        range.flags = IP_NAT_RANGE_MAP_IPS;
        range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
-
-       /* hook doesn't matter, but it has to do source manip */
-       nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
+       nf_nat_setup_info(new, &range, IP_NAT_MANIP_SRC);
 
        /* For DST manip, map port here to where it's expected. */
        range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
        range.min = range.max = this->saved_proto;
        range.min_ip = range.max_ip = this->saved_ip;
-
-       /* hook doesn't matter, but it has to do destination manip */
-       nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
+       nf_nat_setup_info(new, &range, IP_NAT_MANIP_DST);
 }
 
 /****************************************************************************/
index 8718da00ef2a16fffeb15901016688d1ea769ad9..4c0232842e75408759a7a6324c3a2a4ea3452b1e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_conntrack_expect.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_protocol.h>
@@ -180,8 +181,8 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
                                                                datalen, 0));
                }
        } else
-               nf_proto_csum_replace2(&tcph->check, skb,
-                                      htons(oldlen), htons(datalen), 1);
+               inet_proto_csum_replace2(&tcph->check, skb,
+                                        htons(oldlen), htons(datalen), 1);
 
        if (rep_len != match_len) {
                set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
@@ -191,6 +192,8 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
                /* Tell TCP window tracking about seq change */
                nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
                                        ct, CTINFO2DIR(ctinfo));
+
+               nf_conntrack_event_cache(IPCT_NATSEQADJ, skb);
        }
        return 1;
 }
@@ -270,8 +273,8 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb,
                                udph->check = CSUM_MANGLED_0;
                }
        } else
-               nf_proto_csum_replace2(&udph->check, skb,
-                                      htons(oldlen), htons(datalen), 1);
+               inet_proto_csum_replace2(&udph->check, skb,
+                                        htons(oldlen), htons(datalen), 1);
 
        return 1;
 }
@@ -310,10 +313,10 @@ sack_adjust(struct sk_buff *skb,
                         ntohl(sack->start_seq), new_start_seq,
                         ntohl(sack->end_seq), new_end_seq);
 
-               nf_proto_csum_replace4(&tcph->check, skb,
-                                      sack->start_seq, new_start_seq, 0);
-               nf_proto_csum_replace4(&tcph->check, skb,
-                                      sack->end_seq, new_end_seq, 0);
+               inet_proto_csum_replace4(&tcph->check, skb,
+                                        sack->start_seq, new_start_seq, 0);
+               inet_proto_csum_replace4(&tcph->check, skb,
+                                        sack->end_seq, new_end_seq, 0);
                sack->start_seq = new_start_seq;
                sack->end_seq = new_end_seq;
                sackoff += sizeof(*sack);
@@ -397,8 +400,8 @@ nf_nat_seq_adjust(struct sk_buff *skb,
        else
                newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
 
-       nf_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
-       nf_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
+       inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
+       inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
 
        pr_debug("Adjusting sequence number from %u->%u, ack from %u->%u\n",
                 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
@@ -430,15 +433,13 @@ void nf_nat_follow_master(struct nf_conn *ct,
        range.flags = IP_NAT_RANGE_MAP_IPS;
        range.min_ip = range.max_ip
                = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
-       /* hook doesn't matter, but it has to do source manip */
-       nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
 
        /* For DST manip, map port here to where it's expected. */
        range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
        range.min = range.max = exp->saved_proto;
        range.min_ip = range.max_ip
                = ct->master->tuplehash[!exp->dir].tuple.src.u3.ip;
-       /* hook doesn't matter, but it has to do destination manip */
-       nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
 }
 EXPORT_SYMBOL(nf_nat_follow_master);
index 6817e7995f35ca4963c1757e939e7e904f9f92f8..e63b944a2ebbd85a03f8ed5cdb4e3ba810ea0efb 100644 (file)
@@ -93,8 +93,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
                range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
                range.min = range.max = exp->saved_proto;
        }
-       /* hook doesn't matter, but it has to do source manip */
-       nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
 
        /* For DST manip, map port here to where it's expected. */
        range.flags = IP_NAT_RANGE_MAP_IPS;
@@ -104,8 +103,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
                range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
                range.min = range.max = exp->saved_proto;
        }
-       /* hook doesn't matter, but it has to do destination manip */
-       nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
 }
 
 /* outbound packets == from PNS to PAC */
index b820f996035673ecb5da8262cba2a56838f2675d..9fa272e73113f6bdda3e8908677b76169ca63201 100644 (file)
@@ -135,9 +135,10 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
        return 1;
 }
 
-static struct nf_nat_protocol gre __read_mostly = {
+static const struct nf_nat_protocol gre = {
        .name                   = "GRE",
        .protonum               = IPPROTO_GRE,
+       .me                     = THIS_MODULE,
        .manip_pkt              = gre_manip_pkt,
        .in_range               = gre_in_range,
        .unique_tuple           = gre_unique_tuple,
index b9fc724388fc6485212310609cd4ac8a01f73a29..a0e44c953cb6352248a6fa89e3eddc7846b0ec86 100644 (file)
@@ -65,13 +65,13 @@ icmp_manip_pkt(struct sk_buff *skb,
                return 0;
 
        hdr = (struct icmphdr *)(skb->data + hdroff);
-       nf_proto_csum_replace2(&hdr->checksum, skb,
-                              hdr->un.echo.id, tuple->src.u.icmp.id, 0);
+       inet_proto_csum_replace2(&hdr->checksum, skb,
+                                hdr->un.echo.id, tuple->src.u.icmp.id, 0);
        hdr->un.echo.id = tuple->src.u.icmp.id;
        return 1;
 }
 
-struct nf_nat_protocol nf_nat_protocol_icmp = {
+const struct nf_nat_protocol nf_nat_protocol_icmp = {
        .name                   = "ICMP",
        .protonum               = IPPROTO_ICMP,
        .me                     = THIS_MODULE,
index 6bab2e184455fa1dd74c0cdf95e7bd43766e4148..da23e9fbe6790b9ba957cb98b8b7d36e14b65fad 100644 (file)
@@ -132,12 +132,12 @@ tcp_manip_pkt(struct sk_buff *skb,
        if (hdrsize < sizeof(*hdr))
                return 1;
 
-       nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
-       nf_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
+       inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
+       inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
        return 1;
 }
 
-struct nf_nat_protocol nf_nat_protocol_tcp = {
+const struct nf_nat_protocol nf_nat_protocol_tcp = {
        .name                   = "TCP",
        .protonum               = IPPROTO_TCP,
        .me                     = THIS_MODULE,
index cbf1a61e2908351ebc813800faf163121d614e82..10df4db078afd1693b62d95faa2aa2f848bee815 100644 (file)
@@ -117,9 +117,9 @@ udp_manip_pkt(struct sk_buff *skb,
                portptr = &hdr->dest;
        }
        if (hdr->check || skb->ip_summed == CHECKSUM_PARTIAL) {
-               nf_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
-               nf_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
-                                      0);
+               inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
+               inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
+                                        0);
                if (!hdr->check)
                        hdr->check = CSUM_MANGLED_0;
        }
@@ -127,7 +127,7 @@ udp_manip_pkt(struct sk_buff *skb,
        return 1;
 }
 
-struct nf_nat_protocol nf_nat_protocol_udp = {
+const struct nf_nat_protocol nf_nat_protocol_udp = {
        .name                   = "UDP",
        .protonum               = IPPROTO_UDP,
        .me                     = THIS_MODULE,
index cfd2742e9706f3f6867dbbab3f81450cdae739b5..a26efeb073cb927ac86f9a469a40763662398e7c 100644 (file)
@@ -45,7 +45,7 @@ unknown_manip_pkt(struct sk_buff *skb,
        return 1;
 }
 
-struct nf_nat_protocol nf_nat_unknown_protocol = {
+const struct nf_nat_protocol nf_nat_unknown_protocol = {
        .name                   = "unknown",
        /* .me isn't set: getting a ref to this cannot fail. */
        .manip_pkt              = unknown_manip_pkt,
index 46b25ab5f78b013ae89fc823f930553bcd5548db..519182269e76d1418c0ef6830b073c330e7e4dcc 100644 (file)
@@ -24,7 +24,9 @@
 #include <net/netfilter/nf_nat_core.h>
 #include <net/netfilter/nf_nat_rule.h>
 
-#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
+#define NAT_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+                        (1 << NF_INET_POST_ROUTING) | \
+                        (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -38,14 +40,14 @@ static struct
                .num_entries = 4,
                .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
                .hook_entry = {
-                       [NF_IP_PRE_ROUTING] = 0,
-                       [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
-                       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
                },
                .underflow = {
-                       [NF_IP_PRE_ROUTING] = 0,
-                       [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
-                       [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_POST_ROUTING] = sizeof(struct ipt_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ipt_standard) * 2
                },
        },
        .entries = {
@@ -76,7 +78,7 @@ static unsigned int ipt_snat_target(struct sk_buff *skb,
        enum ip_conntrack_info ctinfo;
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
-       NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
+       NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING);
 
        ct = nf_ct_get(skb, &ctinfo);
 
@@ -85,7 +87,7 @@ static unsigned int ipt_snat_target(struct sk_buff *skb,
                            ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
        NF_CT_ASSERT(out);
 
-       return nf_nat_setup_info(ct, &mr->range[0], hooknum);
+       return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
 }
 
 /* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
@@ -95,7 +97,7 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
        struct rtable *rt;
 
-       if (ip_route_output_key(&rt, &fl) != 0)
+       if (ip_route_output_key(&init_net, &rt, &fl) != 0)
                return;
 
        if (rt->rt_src != srcip && !warned) {
@@ -118,20 +120,20 @@ static unsigned int ipt_dnat_target(struct sk_buff *skb,
        enum ip_conntrack_info ctinfo;
        const struct nf_nat_multi_range_compat *mr = targinfo;
 
-       NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
-                    hooknum == NF_IP_LOCAL_OUT);
+       NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING ||
+                    hooknum == NF_INET_LOCAL_OUT);
 
        ct = nf_ct_get(skb, &ctinfo);
 
        /* Connection must be valid and new. */
        NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
 
-       if (hooknum == NF_IP_LOCAL_OUT &&
+       if (hooknum == NF_INET_LOCAL_OUT &&
            mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
                warn_if_extra_mangle(ip_hdr(skb)->daddr,
                                     mr->range[0].min_ip);
 
-       return nf_nat_setup_info(ct, &mr->range[0], hooknum);
+       return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
 }
 
 static bool ipt_snat_checkentry(const char *tablename,
@@ -182,7 +184,7 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
 
        pr_debug("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
                 ct, NIPQUAD(ip));
-       return nf_nat_setup_info(ct, &range, hooknum);
+       return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
 }
 
 unsigned int
@@ -201,7 +203,7 @@ alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
 
        pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
                 ct, NIPQUAD(ip));
-       return nf_nat_setup_info(ct, &range, hooknum);
+       return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
 }
 
 int nf_nat_rule_find(struct sk_buff *skb,
@@ -227,7 +229,7 @@ static struct xt_target ipt_snat_reg __read_mostly = {
        .target         = ipt_snat_target,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
        .table          = "nat",
-       .hooks          = 1 << NF_IP_POST_ROUTING,
+       .hooks          = 1 << NF_INET_POST_ROUTING,
        .checkentry     = ipt_snat_checkentry,
        .family         = AF_INET,
 };
@@ -237,7 +239,7 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
        .target         = ipt_dnat_target,
        .targetsize     = sizeof(struct nf_nat_multi_range_compat),
        .table          = "nat",
-       .hooks          = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
+       .hooks          = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT),
        .checkentry     = ipt_dnat_checkentry,
        .family         = AF_INET,
 };
index 8996ccb757dbb31c5e1d9e54b446647cd965ad5b..606a170bf4cae443895733f5401d82926996743e 100644 (file)
@@ -228,15 +228,13 @@ static void ip_nat_sdp_expect(struct nf_conn *ct,
        range.flags = IP_NAT_RANGE_MAP_IPS;
        range.min_ip = range.max_ip
                = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
-       /* hook doesn't matter, but it has to do source manip */
-       nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
 
        /* For DST manip, map port here to where it's expected. */
        range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
        range.min = range.max = exp->saved_proto;
        range.min_ip = range.max_ip = exp->saved_ip;
-       /* hook doesn't matter, but it has to do destination manip */
-       nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
 }
 
 /* So, this packet has hit the connection tracking matching code.
index 03709d6b4b060d76e3006c40658a9cd3096955d7..07f2a49926d4ae1c5ffe6227e0058ff3b19dff05 100644 (file)
@@ -60,7 +60,7 @@ MODULE_ALIAS("ip_nat_snmp_basic");
 
 #define SNMP_PORT 161
 #define SNMP_TRAP_PORT 162
-#define NOCT1(n) (*(u8 *)n)
+#define NOCT1(n) (*(u8 *)(n))
 
 static int debug;
 static DEFINE_SPINLOCK(snmp_lock);
index 7db76ea9af91148c9581b822cb4db9aca0aa88b7..99b2c788d5a8dfbdef55d7f8b6efcc9ffee970c2 100644 (file)
@@ -137,7 +137,7 @@ nf_nat_fn(unsigned int hooknum,
                        if (unlikely(nf_ct_is_confirmed(ct)))
                                /* NAT module was loaded late */
                                ret = alloc_null_binding_confirmed(ct, hooknum);
-                       else if (hooknum == NF_IP_LOCAL_IN)
+                       else if (hooknum == NF_INET_LOCAL_IN)
                                /* LOCAL_IN hook doesn't have a chain!  */
                                ret = alloc_null_binding(ct, hooknum);
                        else
@@ -273,13 +273,13 @@ nf_nat_adjust(unsigned int hooknum,
 
 /* We must be after connection tracking and before packet filtering. */
 
-static struct nf_hook_ops nf_nat_ops[] = {
+static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
        /* Before packet filtering, change destination */
        {
                .hook           = nf_nat_in,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP_PRI_NAT_DST,
        },
        /* After packet filtering, change source */
@@ -287,7 +287,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_out,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_NAT_SRC,
        },
        /* After conntrack, adjust sequence number */
@@ -295,7 +295,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_adjust,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
        },
        /* Before packet filtering, change destination */
@@ -303,7 +303,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_local_fn,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP_PRI_NAT_DST,
        },
        /* After packet filtering, change source */
@@ -311,7 +311,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_fn,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_NAT_SRC,
        },
        /* After conntrack, adjust sequence number */
@@ -319,7 +319,7 @@ static struct nf_hook_ops nf_nat_ops[] = {
                .hook           = nf_nat_adjust,
                .owner          = THIS_MODULE,
                .pf             = PF_INET,
-               .hooknum        = NF_IP_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP_PRI_NAT_SEQ_ADJUST,
        },
 };
@@ -332,7 +332,7 @@ static int __init nf_nat_standalone_init(void)
 
 #ifdef CONFIG_XFRM
        BUG_ON(ip_nat_decode_session != NULL);
-       ip_nat_decode_session = nat_decode_session;
+       rcu_assign_pointer(ip_nat_decode_session, nat_decode_session);
 #endif
        ret = nf_nat_rule_init();
        if (ret < 0) {
@@ -350,7 +350,7 @@ static int __init nf_nat_standalone_init(void)
        nf_nat_rule_cleanup();
  cleanup_decode_session:
 #ifdef CONFIG_XFRM
-       ip_nat_decode_session = NULL;
+       rcu_assign_pointer(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        return ret;
@@ -361,7 +361,7 @@ static void __exit nf_nat_standalone_fini(void)
        nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
        nf_nat_rule_cleanup();
 #ifdef CONFIG_XFRM
-       ip_nat_decode_session = NULL;
+       rcu_assign_pointer(ip_nat_decode_session, NULL);
        synchronize_net();
 #endif
        /* Conntrack caches are unregistered in nf_conntrack_cleanup */
index ce34b281803f479ba29196aafaad416a01441191..d63474c6b400382f2b102069299f3069226fd3f6 100644 (file)
@@ -53,14 +53,16 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
 {
        socket_seq_show(seq);
        seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
-                  sock_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
+                  sock_prot_inuse_get(&tcp_prot),
+                  atomic_read(&tcp_orphan_count),
                   tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
                   atomic_read(&tcp_memory_allocated));
-       seq_printf(seq, "UDP: inuse %d\n", sock_prot_inuse(&udp_prot));
-       seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse(&udplite_prot));
-       seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse(&raw_prot));
+       seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(&udp_prot),
+                  atomic_read(&udp_memory_allocated));
+       seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot));
+       seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot));
        seq_printf(seq,  "FRAG: inuse %d memory %d\n",
-                       ip_frag_nqueues(), ip_frag_mem());
+                       ip_frag_nqueues(&init_net), ip_frag_mem(&init_net));
        return 0;
 }
 
@@ -309,7 +311,8 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
                seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
 
        seq_printf(seq, "\nIp: %d %d",
-                  IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl);
+                  IPV4_DEVCONF_ALL(&init_net, FORWARDING) ? 1 : 2,
+                  sysctl_ip_default_ttl);
 
        for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
                seq_printf(seq, " %lu",
index e7050f8eabebb63c6d0e3f46b55e4aef65da96b4..85c08696abbe40b4a38de040fe59788a5ff4138e 100644 (file)
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 
-struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
-DEFINE_RWLOCK(raw_v4_lock);
+static struct raw_hashinfo raw_v4_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(),
+};
 
-static void raw_v4_hash(struct sock *sk)
+void raw_hash_sk(struct sock *sk, struct raw_hashinfo *h)
 {
-       struct hlist_head *head = &raw_v4_htable[inet_sk(sk)->num &
-                                                (RAWV4_HTABLE_SIZE - 1)];
+       struct hlist_head *head;
+
+       head = &h->ht[inet_sk(sk)->num & (RAW_HTABLE_SIZE - 1)];
 
-       write_lock_bh(&raw_v4_lock);
+       write_lock_bh(&h->lock);
        sk_add_node(sk, head);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock_bh(&raw_v4_lock);
+       sock_prot_inuse_add(sk->sk_prot, 1);
+       write_unlock_bh(&h->lock);
 }
+EXPORT_SYMBOL_GPL(raw_hash_sk);
 
-static void raw_v4_unhash(struct sock *sk)
+void raw_unhash_sk(struct sock *sk, struct raw_hashinfo *h)
 {
-       write_lock_bh(&raw_v4_lock);
+       write_lock_bh(&h->lock);
        if (sk_del_node_init(sk))
-               sock_prot_dec_use(sk->sk_prot);
-       write_unlock_bh(&raw_v4_lock);
+               sock_prot_inuse_add(sk->sk_prot, -1);
+       write_unlock_bh(&h->lock);
+}
+EXPORT_SYMBOL_GPL(raw_unhash_sk);
+
+static void raw_v4_hash(struct sock *sk)
+{
+       raw_hash_sk(sk, &raw_v4_hashinfo);
 }
 
-struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
-                            __be32 raddr, __be32 laddr,
-                            int dif)
+static void raw_v4_unhash(struct sock *sk)
+{
+       raw_unhash_sk(sk, &raw_v4_hashinfo);
+}
+
+static struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+               unsigned short num, __be32 raddr, __be32 laddr, int dif)
 {
        struct hlist_node *node;
 
        sk_for_each_from(sk, node) {
                struct inet_sock *inet = inet_sk(sk);
 
-               if (inet->num == num                                    &&
+               if (sk->sk_net == net && inet->num == num               &&
                    !(inet->daddr && inet->daddr != raddr)              &&
                    !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
                    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
@@ -150,17 +163,20 @@ static __inline__ int icmp_filter(struct sock *sk, struct sk_buff *skb)
  * RFC 1122: SHOULD pass TOS value up to the transport layer.
  * -> It does. And not only TOS, but all IP header.
  */
-int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
+static int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
 {
        struct sock *sk;
        struct hlist_head *head;
        int delivered = 0;
+       struct net *net;
 
-       read_lock(&raw_v4_lock);
-       head = &raw_v4_htable[hash];
+       read_lock(&raw_v4_hashinfo.lock);
+       head = &raw_v4_hashinfo.ht[hash];
        if (hlist_empty(head))
                goto out;
-       sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
+
+       net = skb->dev->nd_net;
+       sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
                             iph->saddr, iph->daddr,
                             skb->dev->ifindex);
 
@@ -173,16 +189,34 @@ int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
                        if (clone)
                                raw_rcv(sk, clone);
                }
-               sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
+               sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
                                     iph->saddr, iph->daddr,
                                     skb->dev->ifindex);
        }
 out:
-       read_unlock(&raw_v4_lock);
+       read_unlock(&raw_v4_hashinfo.lock);
        return delivered;
 }
 
-void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
+int raw_local_deliver(struct sk_buff *skb, int protocol)
+{
+       int hash;
+       struct sock *raw_sk;
+
+       hash = protocol & (RAW_HTABLE_SIZE - 1);
+       raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
+
+       /* If there maybe a raw socket we must check - if not we
+        * don't care less
+        */
+       if (raw_sk && !raw_v4_input(skb, ip_hdr(skb), hash))
+               raw_sk = NULL;
+
+       return raw_sk != NULL;
+
+}
+
+static void raw_err(struct sock *sk, struct sk_buff *skb, u32 info)
 {
        struct inet_sock *inet = inet_sk(sk);
        const int type = icmp_hdr(skb)->type;
@@ -236,12 +270,38 @@ void raw_err (struct sock *sk, struct sk_buff *skb, u32 info)
        }
 }
 
+void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
+{
+       int hash;
+       struct sock *raw_sk;
+       struct iphdr *iph;
+       struct net *net;
+
+       hash = protocol & (RAW_HTABLE_SIZE - 1);
+
+       read_lock(&raw_v4_hashinfo.lock);
+       raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
+       if (raw_sk != NULL) {
+               iph = (struct iphdr *)skb->data;
+               net = skb->dev->nd_net;
+
+               while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
+                                               iph->daddr, iph->saddr,
+                                               skb->dev->ifindex)) != NULL) {
+                       raw_err(raw_sk, skb, info);
+                       raw_sk = sk_next(raw_sk);
+                       iph = (struct iphdr *)skb->data;
+               }
+       }
+       read_unlock(&raw_v4_hashinfo.lock);
+}
+
 static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
        /* Charge it to the socket. */
 
        if (sock_queue_rcv_skb(sk, skb) < 0) {
-               /* FIXME: increment a raw drops counter here */
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
@@ -252,6 +312,7 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
 int raw_rcv(struct sock *sk, struct sk_buff *skb)
 {
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
@@ -320,7 +381,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
                icmp_out_count(((struct icmphdr *)
                        skb_transport_header(skb))->type);
 
-       err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+       err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                      dst_output);
        if (err > 0)
                err = inet->recverr ? net_xmit_errno(err) : 0;
@@ -474,7 +535,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        if (msg->msg_flags & MSG_DONTROUTE)
                tos |= RTO_ONLINK;
 
-       if (MULTICAST(daddr)) {
+       if (ipv4_is_multicast(daddr)) {
                if (!ipc.oif)
                        ipc.oif = inet->mc_index;
                if (!saddr)
@@ -497,7 +558,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                }
 
                security_sk_classify_flow(sk, &fl);
-               err = ip_route_output_flow(&rt, &fl, sk, 1);
+               err = ip_route_output_flow(&init_net, &rt, &fl, sk, 1);
        }
        if (err)
                goto done;
@@ -564,7 +625,7 @@ static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 
        if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_in))
                goto out;
-       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+       chk_addr_ret = inet_addr_type(sk->sk_net, addr->sin_addr.s_addr);
        ret = -EADDRNOTAVAIL;
        if (addr->sin_addr.s_addr && chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST)
@@ -789,22 +850,18 @@ struct proto raw_prot = {
 };
 
 #ifdef CONFIG_PROC_FS
-struct raw_iter_state {
-       int bucket;
-};
-
-#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private)
-
 static struct sock *raw_get_first(struct seq_file *seq)
 {
        struct sock *sk;
        struct raw_iter_state* state = raw_seq_private(seq);
 
-       for (state->bucket = 0; state->bucket < RAWV4_HTABLE_SIZE; ++state->bucket) {
+       for (state->bucket = 0; state->bucket < RAW_HTABLE_SIZE;
+                       ++state->bucket) {
                struct hlist_node *node;
 
-               sk_for_each(sk, node, &raw_v4_htable[state->bucket])
-                       if (sk->sk_family == PF_INET)
+               sk_for_each(sk, node, &state->h->ht[state->bucket])
+                       if (sk->sk_net == state->p.net &&
+                                       sk->sk_family == state->family)
                                goto found;
        }
        sk = NULL;
@@ -820,10 +877,11 @@ static struct sock *raw_get_next(struct seq_file *seq, struct sock *sk)
                sk = sk_next(sk);
 try_again:
                ;
-       } while (sk && sk->sk_family != PF_INET);
+       } while (sk && sk->sk_net != state->p.net &&
+                       sk->sk_family != state->family);
 
-       if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) {
-               sk = sk_head(&raw_v4_htable[state->bucket]);
+       if (!sk && ++state->bucket < RAW_HTABLE_SIZE) {
+               sk = sk_head(&state->h->ht[state->bucket]);
                goto try_again;
        }
        return sk;
@@ -839,13 +897,16 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
        return pos ? NULL : sk;
 }
 
-static void *raw_seq_start(struct seq_file *seq, loff_t *pos)
+void *raw_seq_start(struct seq_file *seq, loff_t *pos)
 {
-       read_lock(&raw_v4_lock);
+       struct raw_iter_state *state = raw_seq_private(seq);
+
+       read_lock(&state->h->lock);
        return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
 }
+EXPORT_SYMBOL_GPL(raw_seq_start);
 
-static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
        struct sock *sk;
 
@@ -856,11 +917,15 @@ static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        ++*pos;
        return sk;
 }
+EXPORT_SYMBOL_GPL(raw_seq_next);
 
-static void raw_seq_stop(struct seq_file *seq, void *v)
+void raw_seq_stop(struct seq_file *seq, void *v)
 {
-       read_unlock(&raw_v4_lock);
+       struct raw_iter_state *state = raw_seq_private(seq);
+
+       read_unlock(&state->h->lock);
 }
+EXPORT_SYMBOL_GPL(raw_seq_stop);
 
 static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
 {
@@ -871,28 +936,30 @@ static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
              srcp  = inet->num;
 
        sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X"
-               " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p",
+               " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d",
                i, src, srcp, dest, destp, sp->sk_state,
                atomic_read(&sp->sk_wmem_alloc),
                atomic_read(&sp->sk_rmem_alloc),
                0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
-               atomic_read(&sp->sk_refcnt), sp);
+               atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
        return tmpbuf;
 }
 
+#define TMPSZ 128
+
 static int raw_seq_show(struct seq_file *seq, void *v)
 {
-       char tmpbuf[129];
+       char tmpbuf[TMPSZ+1];
 
        if (v == SEQ_START_TOKEN)
-               seq_printf(seq, "%-127s\n",
+               seq_printf(seq, "%-*s\n", TMPSZ-1,
                               "  sl  local_address rem_address   st tx_queue "
                               "rx_queue tr tm->when retrnsmt   uid  timeout "
-                              "inode");
+                              "inode  drops");
        else {
                struct raw_iter_state *state = raw_seq_private(seq);
 
-               seq_printf(seq, "%-127s\n",
+               seq_printf(seq, "%-*s\n", TMPSZ-1,
                           get_raw_sock(v, tmpbuf, state->bucket));
        }
        return 0;
@@ -905,29 +972,62 @@ static const struct seq_operations raw_seq_ops = {
        .show  = raw_seq_show,
 };
 
-static int raw_seq_open(struct inode *inode, struct file *file)
+int raw_seq_open(struct inode *ino, struct file *file, struct raw_hashinfo *h,
+               unsigned short family)
 {
-       return seq_open_private(file, &raw_seq_ops,
+       int err;
+       struct raw_iter_state *i;
+
+       err = seq_open_net(ino, file, &raw_seq_ops,
                        sizeof(struct raw_iter_state));
+       if (err < 0)
+               return err;
+
+       i = raw_seq_private((struct seq_file *)file->private_data);
+       i->h = h;
+       i->family = family;
+       return 0;
+}
+EXPORT_SYMBOL_GPL(raw_seq_open);
+
+static int raw_v4_seq_open(struct inode *inode, struct file *file)
+{
+       return raw_seq_open(inode, file, &raw_v4_hashinfo, PF_INET);
 }
 
 static const struct file_operations raw_seq_fops = {
        .owner   = THIS_MODULE,
-       .open    = raw_seq_open,
+       .open    = raw_v4_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release_private,
+       .release = seq_release_net,
 };
 
-int __init raw_proc_init(void)
+static __net_init int raw_init_net(struct net *net)
 {
-       if (!proc_net_fops_create(&init_net, "raw", S_IRUGO, &raw_seq_fops))
+       if (!proc_net_fops_create(net, "raw", S_IRUGO, &raw_seq_fops))
                return -ENOMEM;
+
        return 0;
 }
 
+static __net_exit void raw_exit_net(struct net *net)
+{
+       proc_net_remove(net, "raw");
+}
+
+static __net_initdata struct pernet_operations raw_net_ops = {
+       .init = raw_init_net,
+       .exit = raw_exit_net,
+};
+
+int __init raw_proc_init(void)
+{
+       return register_pernet_subsys(&raw_net_ops);
+}
+
 void __init raw_proc_exit(void)
 {
-       proc_net_remove(&init_net, "raw");
+       unregister_pernet_subsys(&raw_net_ops);
 }
 #endif /* CONFIG_PROC_FS */
index 28484f396b048e1dd49210e5caffc24e29148f2b..896c768e41a2d90baef4b4a3783be0164678ff9e 100644 (file)
@@ -92,6 +92,7 @@
 #include <linux/jhash.h>
 #include <linux/rcupdate.h>
 #include <linux/times.h>
+#include <net/dst.h>
 #include <net/net_namespace.h>
 #include <net/protocol.h>
 #include <net/ip.h>
@@ -132,13 +133,14 @@ static int ip_rt_mtu_expires              = 10 * 60 * HZ;
 static int ip_rt_min_pmtu              = 512 + 20 + 20;
 static int ip_rt_min_advmss            = 256;
 static int ip_rt_secret_interval       = 10 * 60 * HZ;
+static int ip_rt_flush_expected;
 static unsigned long rt_deadline;
 
 #define RTprint(a...)  printk(KERN_DEBUG a)
 
 static struct timer_list rt_flush_timer;
-static void rt_check_expire(struct work_struct *work);
-static DECLARE_DELAYED_WORK(expires_work, rt_check_expire);
+static void rt_worker_func(struct work_struct *work);
+static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
 static struct timer_list rt_secret_timer;
 
 /*
@@ -152,7 +154,7 @@ static void          ipv4_dst_ifdown(struct dst_entry *dst,
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void             ipv4_link_failure(struct sk_buff *skb);
 static void             ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
-static int rt_garbage_collect(void);
+static int rt_garbage_collect(struct dst_ops *ops);
 
 
 static struct dst_ops ipv4_dst_ops = {
@@ -165,6 +167,7 @@ static struct dst_ops ipv4_dst_ops = {
        .negative_advice =      ipv4_negative_advice,
        .link_failure =         ipv4_link_failure,
        .update_pmtu =          ip_rt_update_pmtu,
+       .local_out =            ip_local_out,
        .entry_size =           sizeof(struct rtable),
 };
 
@@ -232,16 +235,25 @@ struct rt_hash_bucket {
 
 static spinlock_t      *rt_hash_locks;
 # define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)]
-# define rt_hash_lock_init()   { \
-               int i; \
-               rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \
-               if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \
-               for (i = 0; i < RT_HASH_LOCK_SZ; i++) \
-                       spin_lock_init(&rt_hash_locks[i]); \
-               }
+
+static __init void rt_hash_lock_init(void)
+{
+       int i;
+
+       rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ,
+                       GFP_KERNEL);
+       if (!rt_hash_locks)
+               panic("IP: failed to allocate rt_hash_locks\n");
+
+       for (i = 0; i < RT_HASH_LOCK_SZ; i++)
+               spin_lock_init(&rt_hash_locks[i]);
+}
 #else
 # define rt_hash_lock_addr(slot) NULL
-# define rt_hash_lock_init()
+
+static inline void rt_hash_lock_init(void)
+{
+}
 #endif
 
 static struct rt_hash_bucket   *rt_hash_table;
@@ -478,6 +490,83 @@ static const struct file_operations rt_cpu_seq_fops = {
        .release = seq_release,
 };
 
+#ifdef CONFIG_NET_CLS_ROUTE
+static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
+                          int length, int *eof, void *data)
+{
+       unsigned int i;
+
+       if ((offset & 3) || (length & 3))
+               return -EIO;
+
+       if (offset >= sizeof(struct ip_rt_acct) * 256) {
+               *eof = 1;
+               return 0;
+       }
+
+       if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
+               length = sizeof(struct ip_rt_acct) * 256 - offset;
+               *eof = 1;
+       }
+
+       offset /= sizeof(u32);
+
+       if (length > 0) {
+               u32 *dst = (u32 *) buffer;
+
+               *start = buffer;
+               memset(dst, 0, length);
+
+               for_each_possible_cpu(i) {
+                       unsigned int j;
+                       u32 *src;
+
+                       src = ((u32 *) per_cpu_ptr(ip_rt_acct, i)) + offset;
+                       for (j = 0; j < length/4; j++)
+                               dst[j] += src[j];
+               }
+       }
+       return length;
+}
+#endif
+
+static __init int ip_rt_proc_init(struct net *net)
+{
+       struct proc_dir_entry *pde;
+
+       pde = proc_net_fops_create(net, "rt_cache", S_IRUGO,
+                       &rt_cache_seq_fops);
+       if (!pde)
+               goto err1;
+
+       pde = create_proc_entry("rt_cache", S_IRUGO, net->proc_net_stat);
+       if (!pde)
+               goto err2;
+
+       pde->proc_fops = &rt_cpu_seq_fops;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+       pde = create_proc_read_entry("rt_acct", 0, net->proc_net,
+                       ip_rt_acct_read, NULL);
+       if (!pde)
+               goto err3;
+#endif
+       return 0;
+
+#ifdef CONFIG_NET_CLS_ROUTE
+err3:
+       remove_proc_entry("rt_cache", net->proc_net_stat);
+#endif
+err2:
+       remove_proc_entry("rt_cache", net->proc_net);
+err1:
+       return -ENOMEM;
+}
+#else
+static inline int ip_rt_proc_init(struct net *net)
+{
+       return 0;
+}
 #endif /* CONFIG_PROC_FS */
 
 static __inline__ void rt_free(struct rtable *rt)
@@ -559,7 +648,41 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
                (fl1->iif ^ fl2->iif)) == 0;
 }
 
-static void rt_check_expire(struct work_struct *work)
+static inline int compare_netns(struct rtable *rt1, struct rtable *rt2)
+{
+       return rt1->u.dst.dev->nd_net == rt2->u.dst.dev->nd_net;
+}
+
+/*
+ * Perform a full scan of hash table and free all entries.
+ * Can be called by a softirq or a process.
+ * In the later case, we want to be reschedule if necessary
+ */
+static void rt_do_flush(int process_context)
+{
+       unsigned int i;
+       struct rtable *rth, *next;
+
+       for (i = 0; i <= rt_hash_mask; i++) {
+               if (process_context && need_resched())
+                       cond_resched();
+               rth = rt_hash_table[i].chain;
+               if (!rth)
+                       continue;
+
+               spin_lock_bh(rt_hash_lock_addr(i));
+               rth = rt_hash_table[i].chain;
+               rt_hash_table[i].chain = NULL;
+               spin_unlock_bh(rt_hash_lock_addr(i));
+
+               for (; rth; rth = next) {
+                       next = rth->u.dst.rt_next;
+                       rt_free(rth);
+               }
+       }
+}
+
+static void rt_check_expire(void)
 {
        static unsigned int rover;
        unsigned int i = rover, goal;
@@ -605,33 +728,33 @@ static void rt_check_expire(struct work_struct *work)
                spin_unlock_bh(rt_hash_lock_addr(i));
        }
        rover = i;
+}
+
+/*
+ * rt_worker_func() is run in process context.
+ * If a whole flush was scheduled, it is done.
+ * Else, we call rt_check_expire() to scan part of the hash table
+ */
+static void rt_worker_func(struct work_struct *work)
+{
+       if (ip_rt_flush_expected) {
+               ip_rt_flush_expected = 0;
+               rt_do_flush(1);
+       } else
+               rt_check_expire();
        schedule_delayed_work(&expires_work, ip_rt_gc_interval);
 }
 
 /* This can run from both BH and non-BH contexts, the latter
  * in the case of a forced flush event.
  */
-static void rt_run_flush(unsigned long dummy)
+static void rt_run_flush(unsigned long process_context)
 {
-       int i;
-       struct rtable *rth, *next;
-
        rt_deadline = 0;
 
        get_random_bytes(&rt_hash_rnd, 4);
 
-       for (i = rt_hash_mask; i >= 0; i--) {
-               spin_lock_bh(rt_hash_lock_addr(i));
-               rth = rt_hash_table[i].chain;
-               if (rth)
-                       rt_hash_table[i].chain = NULL;
-               spin_unlock_bh(rt_hash_lock_addr(i));
-
-               for (; rth; rth = next) {
-                       next = rth->u.dst.rt_next;
-                       rt_free(rth);
-               }
-       }
+       rt_do_flush(process_context);
 }
 
 static DEFINE_SPINLOCK(rt_flush_lock);
@@ -665,7 +788,7 @@ void rt_cache_flush(int delay)
 
        if (delay <= 0) {
                spin_unlock_bh(&rt_flush_lock);
-               rt_run_flush(0);
+               rt_run_flush(user_mode);
                return;
        }
 
@@ -676,12 +799,17 @@ void rt_cache_flush(int delay)
        spin_unlock_bh(&rt_flush_lock);
 }
 
+/*
+ * We change rt_hash_rnd and ask next rt_worker_func() invocation
+ * to perform a flush in process context
+ */
 static void rt_secret_rebuild(unsigned long dummy)
 {
-       unsigned long now = jiffies;
-
-       rt_cache_flush(0);
-       mod_timer(&rt_secret_timer, now + ip_rt_secret_interval);
+       get_random_bytes(&rt_hash_rnd, 4);
+       ip_rt_flush_expected = 1;
+       cancel_delayed_work(&expires_work);
+       schedule_delayed_work(&expires_work, HZ/10);
+       mod_timer(&rt_secret_timer, jiffies + ip_rt_secret_interval);
 }
 
 /*
@@ -697,7 +825,7 @@ static void rt_secret_rebuild(unsigned long dummy)
    and when load increases it reduces to limit cache size.
  */
 
-static int rt_garbage_collect(void)
+static int rt_garbage_collect(struct dst_ops *ops)
 {
        static unsigned long expire = RT_GC_TIMEOUT;
        static unsigned long last_gc;
@@ -728,14 +856,14 @@ static int rt_garbage_collect(void)
                        equilibrium = ipv4_dst_ops.gc_thresh;
                goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
                if (goal > 0) {
-                       equilibrium += min_t(unsigned int, goal / 2, rt_hash_mask + 1);
+                       equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1);
                        goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium;
                }
        } else {
                /* We are in dangerous area. Try to reduce cache really
                 * aggressively.
                 */
-               goal = max_t(unsigned int, goal / 2, rt_hash_mask + 1);
+               goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1);
                equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal;
        }
 
@@ -838,7 +966,7 @@ restart:
 
        spin_lock_bh(rt_hash_lock_addr(hash));
        while ((rth = *rthp) != NULL) {
-               if (compare_keys(&rth->fl, &rt->fl)) {
+               if (compare_keys(&rth->fl, &rt->fl) && compare_netns(rth, rt)) {
                        /* Put it first */
                        *rthp = rth->u.dst.rt_next;
                        /*
@@ -912,7 +1040,7 @@ restart:
                                int saved_int = ip_rt_gc_min_interval;
                                ip_rt_gc_elasticity     = 1;
                                ip_rt_gc_min_interval   = 0;
-                               rt_garbage_collect();
+                               rt_garbage_collect(&ipv4_dst_ops);
                                ip_rt_gc_min_interval   = saved_int;
                                ip_rt_gc_elasticity     = saved_elasticity;
                                goto restart;
@@ -1031,7 +1159,8 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                return;
 
        if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev)
-           || MULTICAST(new_gw) || BADCLASS(new_gw) || ZERONET(new_gw))
+           || ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw)
+           || ipv4_is_zeronet(new_gw))
                goto reject_redirect;
 
        if (!IN_DEV_SHARED_MEDIA(in_dev)) {
@@ -1040,7 +1169,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                if (IN_DEV_SEC_REDIRECTS(in_dev) && ip_fib_check_default(new_gw, dev))
                        goto reject_redirect;
        } else {
-               if (inet_addr_type(new_gw) != RTN_UNICAST)
+               if (inet_addr_type(&init_net, new_gw) != RTN_UNICAST)
                        goto reject_redirect;
        }
 
@@ -1291,7 +1420,8 @@ static __inline__ unsigned short guess_mtu(unsigned short old_mtu)
        return 68;
 }
 
-unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
+unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
+                                unsigned short new_mtu)
 {
        int i;
        unsigned short old_mtu = ntohs(iph->tot_len);
@@ -1314,7 +1444,8 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
                            rth->rt_dst  == daddr &&
                            rth->rt_src  == iph->saddr &&
                            rth->fl.iif == 0 &&
-                           !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
+                           !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) &&
+                           rth->u.dst.dev->nd_net == net) {
                                unsigned short mtu = new_mtu;
 
                                if (new_mtu < 68 || new_mtu >= old_mtu) {
@@ -1389,8 +1520,9 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 {
        struct rtable *rt = (struct rtable *) dst;
        struct in_device *idev = rt->idev;
-       if (dev != init_net.loopback_dev && idev && idev->dev == dev) {
-               struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev);
+       if (dev != dev->nd_net->loopback_dev && idev && idev->dev == dev) {
+               struct in_device *loopback_idev =
+                       in_dev_get(dev->nd_net->loopback_dev);
                if (loopback_idev) {
                        rt->idev = loopback_idev;
                        in_dev_put(idev);
@@ -1434,7 +1566,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
 
        if (rt->fl.iif == 0)
                src = rt->rt_src;
-       else if (fib_lookup(&rt->fl, &res) == 0) {
+       else if (fib_lookup(rt->u.dst.dev->nd_net, &rt->fl, &res) == 0) {
                src = FIB_RES_PREFSRC(res);
                fib_res_put(&res);
        } else
@@ -1509,12 +1641,12 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        if (in_dev == NULL)
                return -EINVAL;
 
-       if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr) ||
-           skb->protocol != htons(ETH_P_IP))
+       if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
+           ipv4_is_loopback(saddr) || skb->protocol != htons(ETH_P_IP))
                goto e_inval;
 
-       if (ZERONET(saddr)) {
-               if (!LOCAL_MCAST(daddr))
+       if (ipv4_is_zeronet(saddr)) {
+               if (!ipv4_is_local_multicast(daddr))
                        goto e_inval;
                spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
        } else if (fib_validate_source(saddr, 0, tos, 0,
@@ -1556,7 +1688,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        }
 
 #ifdef CONFIG_IP_MROUTE
-       if (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev))
+       if (!ipv4_is_local_multicast(daddr) && IN_DEV_MFORWARD(in_dev))
                rth->u.dst.input = ip_mr_input;
 #endif
        RT_CACHE_STAT_INC(in_slow_mc);
@@ -1643,7 +1775,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
        if (err)
                flags |= RTCF_DIRECTSRC;
 
-       if (out_dev == in_dev && err && !(flags & (RTCF_NAT | RTCF_MASQ)) &&
+       if (out_dev == in_dev && err && !(flags & RTCF_MASQ) &&
            (IN_DEV_SHARED_MEDIA(out_dev) ||
             inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
                flags |= RTCF_DOREDIRECT;
@@ -1652,7 +1784,7 @@ static inline int __mkroute_input(struct sk_buff *skb,
                /* Not IP (i.e. ARP). Do not create route, if it is
                 * invalid for proxy arp. DNAT routes are always valid.
                 */
-               if (out_dev == in_dev && !(flags & RTCF_DNAT)) {
+               if (out_dev == in_dev) {
                        err = -EINVAL;
                        goto cleanup;
                }
@@ -1756,6 +1888,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        __be32          spec_dst;
        int             err = -EINVAL;
        int             free_res = 0;
+       struct net    * net = dev->nd_net;
 
        /* IP on this device is disabled. */
 
@@ -1766,7 +1899,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
           by fib_lookup.
         */
 
-       if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr))
+       if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
+           ipv4_is_loopback(saddr))
                goto martian_source;
 
        if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0))
@@ -1775,16 +1909,17 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        /* Accept zero addresses only to limited broadcast;
         * I even do not know to fix it or not. Waiting for complains :-)
         */
-       if (ZERONET(saddr))
+       if (ipv4_is_zeronet(saddr))
                goto martian_source;
 
-       if (BADCLASS(daddr) || ZERONET(daddr) || LOOPBACK(daddr))
+       if (ipv4_is_lbcast(daddr) || ipv4_is_zeronet(daddr) ||
+           ipv4_is_loopback(daddr))
                goto martian_destination;
 
        /*
         *      Now we are ready to route packet.
         */
-       if ((err = fib_lookup(&fl, &res)) != 0) {
+       if ((err = fib_lookup(net, &fl, &res)) != 0) {
                if (!IN_DEV_FORWARD(in_dev))
                        goto e_hostunreach;
                goto no_route;
@@ -1799,7 +1934,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        if (res.type == RTN_LOCAL) {
                int result;
                result = fib_validate_source(saddr, daddr, tos,
-                                            init_net.loopback_dev->ifindex,
+                                            net->loopback_dev->ifindex,
                                             dev, &spec_dst, &itag);
                if (result < 0)
                        goto martian_source;
@@ -1825,7 +1960,7 @@ brd_input:
        if (skb->protocol != htons(ETH_P_IP))
                goto e_inval;
 
-       if (ZERONET(saddr))
+       if (ipv4_is_zeronet(saddr))
                spec_dst = inet_select_addr(dev, 0, RT_SCOPE_LINK);
        else {
                err = fib_validate_source(saddr, 0, tos, 0, dev, &spec_dst,
@@ -1861,7 +1996,7 @@ local_input:
 #endif
        rth->rt_iif     =
        rth->fl.iif     = dev->ifindex;
-       rth->u.dst.dev  = init_net.loopback_dev;
+       rth->u.dst.dev  = net->loopback_dev;
        dev_hold(rth->u.dst.dev);
        rth->idev       = in_dev_get(rth->u.dst.dev);
        rth->rt_gateway = daddr;
@@ -1921,7 +2056,9 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
        struct rtable * rth;
        unsigned        hash;
        int iif = dev->ifindex;
+       struct net *net;
 
+       net = skb->dev->nd_net;
        tos &= IPTOS_RT_MASK;
        hash = rt_hash(daddr, saddr, iif);
 
@@ -1933,7 +2070,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                    rth->fl.iif == iif &&
                    rth->fl.oif == 0 &&
                    rth->fl.mark == skb->mark &&
-                   rth->fl.fl4_tos == tos) {
+                   rth->fl.fl4_tos == tos &&
+                   rth->u.dst.dev->nd_net == net) {
                        dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(in_hit);
                        rcu_read_unlock();
@@ -1955,7 +2093,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
           Note, that multicast routers are not affected, because
           route cache entry is created eventually.
         */
-       if (MULTICAST(daddr)) {
+       if (ipv4_is_multicast(daddr)) {
                struct in_device *in_dev;
 
                rcu_read_lock();
@@ -1964,7 +2102,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                                ip_hdr(skb)->protocol);
                        if (our
 #ifdef CONFIG_IP_MROUTE
-                           || (!LOCAL_MCAST(daddr) && IN_DEV_MFORWARD(in_dev))
+                           || (!ipv4_is_local_multicast(daddr) &&
+                               IN_DEV_MFORWARD(in_dev))
 #endif
                            ) {
                                rcu_read_unlock();
@@ -1990,14 +2129,14 @@ static inline int __mkroute_output(struct rtable **result,
        u32 tos = RT_FL_TOS(oldflp);
        int err = 0;
 
-       if (LOOPBACK(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
+       if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK))
                return -EINVAL;
 
        if (fl->fl4_dst == htonl(0xFFFFFFFF))
                res->type = RTN_BROADCAST;
-       else if (MULTICAST(fl->fl4_dst))
+       else if (ipv4_is_multicast(fl->fl4_dst))
                res->type = RTN_MULTICAST;
-       else if (BADCLASS(fl->fl4_dst) || ZERONET(fl->fl4_dst))
+       else if (ipv4_is_lbcast(fl->fl4_dst) || ipv4_is_zeronet(fl->fl4_dst))
                return -EINVAL;
 
        if (dev_out->flags & IFF_LOOPBACK)
@@ -2077,7 +2216,7 @@ static inline int __mkroute_output(struct rtable **result,
 #ifdef CONFIG_IP_MROUTE
                if (res->type == RTN_MULTICAST) {
                        if (IN_DEV_MFORWARD(in_dev) &&
-                           !LOCAL_MCAST(oldflp->fl4_dst)) {
+                           !ipv4_is_local_multicast(oldflp->fl4_dst)) {
                                rth->u.dst.input = ip_mr_input;
                                rth->u.dst.output = ip_mc_output;
                        }
@@ -2119,7 +2258,8 @@ static inline int ip_mkroute_output(struct rtable **rp,
  * Major route resolver routine.
  */
 
-static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
+static int ip_route_output_slow(struct net *net, struct rtable **rp,
+                               const struct flowi *oldflp)
 {
        u32 tos = RT_FL_TOS(oldflp);
        struct flowi fl = { .nl_u = { .ip4_u =
@@ -2131,7 +2271,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                                                  RT_SCOPE_UNIVERSE),
                                      } },
                            .mark = oldflp->mark,
-                           .iif = init_net.loopback_dev->ifindex,
+                           .iif = net->loopback_dev->ifindex,
                            .oif = oldflp->oif };
        struct fib_result res;
        unsigned flags = 0;
@@ -2147,26 +2287,27 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
 
        if (oldflp->fl4_src) {
                err = -EINVAL;
-               if (MULTICAST(oldflp->fl4_src) ||
-                   BADCLASS(oldflp->fl4_src) ||
-                   ZERONET(oldflp->fl4_src))
+               if (ipv4_is_multicast(oldflp->fl4_src) ||
+                   ipv4_is_lbcast(oldflp->fl4_src) ||
+                   ipv4_is_zeronet(oldflp->fl4_src))
                        goto out;
 
                /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
-               dev_out = ip_dev_find(oldflp->fl4_src);
+               dev_out = ip_dev_find(net, oldflp->fl4_src);
                if (dev_out == NULL)
                        goto out;
 
                /* I removed check for oif == dev_out->oif here.
                   It was wrong for two reasons:
-                  1. ip_dev_find(saddr) can return wrong iface, if saddr is
-                     assigned to multiple interfaces.
+                  1. ip_dev_find(net, saddr) can return wrong iface, if saddr
+                     is assigned to multiple interfaces.
                   2. Moreover, we are allowed to send packets with saddr
                      of another iface. --ANK
                 */
 
                if (oldflp->oif == 0
-                   && (MULTICAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
+                   && (ipv4_is_multicast(oldflp->fl4_dst) ||
+                       oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
                        /* Special hack: user can direct multicasts
                           and limited broadcast via necessary interface
                           without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2192,7 +2333,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
 
 
        if (oldflp->oif) {
-               dev_out = dev_get_by_index(&init_net, oldflp->oif);
+               dev_out = dev_get_by_index(net, oldflp->oif);
                err = -ENODEV;
                if (dev_out == NULL)
                        goto out;
@@ -2203,14 +2344,15 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        goto out;       /* Wrong error code */
                }
 
-               if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
+               if (ipv4_is_local_multicast(oldflp->fl4_dst) ||
+                   oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
                        if (!fl.fl4_src)
                                fl.fl4_src = inet_select_addr(dev_out, 0,
                                                              RT_SCOPE_LINK);
                        goto make_route;
                }
                if (!fl.fl4_src) {
-                       if (MULTICAST(oldflp->fl4_dst))
+                       if (ipv4_is_multicast(oldflp->fl4_dst))
                                fl.fl4_src = inet_select_addr(dev_out, 0,
                                                              fl.fl4_scope);
                        else if (!oldflp->fl4_dst)
@@ -2225,15 +2367,15 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK);
                if (dev_out)
                        dev_put(dev_out);
-               dev_out = init_net.loopback_dev;
+               dev_out = net->loopback_dev;
                dev_hold(dev_out);
-               fl.oif = init_net.loopback_dev->ifindex;
+               fl.oif = net->loopback_dev->ifindex;
                res.type = RTN_LOCAL;
                flags |= RTCF_LOCAL;
                goto make_route;
        }
 
-       if (fib_lookup(&fl, &res)) {
+       if (fib_lookup(net, &fl, &res)) {
                res.fi = NULL;
                if (oldflp->oif) {
                        /* Apparently, routing tables are wrong. Assume,
@@ -2272,7 +2414,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
                        fl.fl4_src = fl.fl4_dst;
                if (dev_out)
                        dev_put(dev_out);
-               dev_out = init_net.loopback_dev;
+               dev_out = net->loopback_dev;
                dev_hold(dev_out);
                fl.oif = dev_out->ifindex;
                if (res.fi)
@@ -2288,7 +2430,7 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
        else
 #endif
        if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
-               fib_select_default(&fl, &res);
+               fib_select_default(net, &fl, &res);
 
        if (!fl.fl4_src)
                fl.fl4_src = FIB_RES_PREFSRC(res);
@@ -2311,7 +2453,8 @@ make_route:
 out:   return err;
 }
 
-int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
+int __ip_route_output_key(struct net *net, struct rtable **rp,
+                         const struct flowi *flp)
 {
        unsigned hash;
        struct rtable *rth;
@@ -2327,7 +2470,8 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
                    rth->fl.oif == flp->oif &&
                    rth->fl.mark == flp->mark &&
                    !((rth->fl.fl4_tos ^ flp->fl4_tos) &
-                           (IPTOS_RT_MASK | RTO_ONLINK))) {
+                           (IPTOS_RT_MASK | RTO_ONLINK)) &&
+                   rth->u.dst.dev->nd_net == net) {
                        dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(out_hit);
                        rcu_read_unlock_bh();
@@ -2338,7 +2482,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
        }
        rcu_read_unlock_bh();
 
-       return ip_route_output_slow(rp, flp);
+       return ip_route_output_slow(net, rp, flp);
 }
 
 EXPORT_SYMBOL_GPL(__ip_route_output_key);
@@ -2357,12 +2501,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
 };
 
 
-static int ipv4_blackhole_output(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return 0;
-}
-
 static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock *sk)
 {
        struct rtable *ort = *rp;
@@ -2374,8 +2512,8 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock
 
                atomic_set(&new->__refcnt, 1);
                new->__use = 1;
-               new->input = ipv4_blackhole_output;
-               new->output = ipv4_blackhole_output;
+               new->input = dst_discard;
+               new->output = dst_discard;
                memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
 
                new->dev = ort->u.dst.dev;
@@ -2406,11 +2544,12 @@ static int ipv4_dst_blackhole(struct rtable **rp, struct flowi *flp, struct sock
        return (rt ? 0 : -ENOMEM);
 }
 
-int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
+int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp,
+                        struct sock *sk, int flags)
 {
        int err;
 
-       if ((err = __ip_route_output_key(rp, flp)) != 0)
+       if ((err = __ip_route_output_key(net, rp, flp)) != 0)
                return err;
 
        if (flp->proto) {
@@ -2418,7 +2557,8 @@ int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk,
                        flp->fl4_src = (*rp)->rt_src;
                if (!flp->fl4_dst)
                        flp->fl4_dst = (*rp)->rt_dst;
-               err = __xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
+               err = __xfrm_lookup((struct dst_entry **)rp, flp, sk,
+                                   flags ? XFRM_LOOKUP_WAIT : 0);
                if (err == -EREMOTE)
                        err = ipv4_dst_blackhole(rp, flp, sk);
 
@@ -2430,9 +2570,9 @@ int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk,
 
 EXPORT_SYMBOL_GPL(ip_route_output_flow);
 
-int ip_route_output_key(struct rtable **rp, struct flowi *flp)
+int ip_route_output_key(struct net *net, struct rtable **rp, struct flowi *flp)
 {
-       return ip_route_output_flow(rp, flp, NULL, 0);
+       return ip_route_output_flow(net, rp, flp, NULL, 0);
 }
 
 static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
@@ -2499,8 +2639,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 #ifdef CONFIG_IP_MROUTE
                __be32 dst = rt->rt_dst;
 
-               if (MULTICAST(dst) && !LOCAL_MCAST(dst) &&
-                   IPV4_DEVCONF_ALL(MC_FORWARDING)) {
+               if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) &&
+                   IPV4_DEVCONF_ALL(&init_net, MC_FORWARDING)) {
                        int err = ipmr_get_route(skb, r, nowait);
                        if (err <= 0) {
                                if (!nowait) {
@@ -2531,6 +2671,7 @@ nla_put_failure:
 
 static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = in_skb->sk->sk_net;
        struct rtmsg *rtm;
        struct nlattr *tb[RTA_MAX+1];
        struct rtable *rt = NULL;
@@ -2540,6 +2681,9 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        int err;
        struct sk_buff *skb;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv4_policy);
        if (err < 0)
                goto errout;
@@ -2595,7 +2739,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
                        },
                        .oif = tb[RTA_OIF] ? nla_get_u32(tb[RTA_OIF]) : 0,
                };
-               err = ip_route_output_key(&rt, &fl);
+               err = ip_route_output_key(&init_net, &rt, &fl);
        }
 
        if (err)
@@ -2610,7 +2754,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        if (err <= 0)
                goto errout_free;
 
-       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
 errout:
        return err;
 
@@ -2862,51 +3006,7 @@ ctl_table ipv4_route_table[] = {
 #endif
 
 #ifdef CONFIG_NET_CLS_ROUTE
-struct ip_rt_acct *ip_rt_acct;
-
-/* This code sucks.  But you should have seen it before! --RR */
-
-/* IP route accounting ptr for this logical cpu number. */
-#define IP_RT_ACCT_CPU(i) (ip_rt_acct + i * 256)
-
-#ifdef CONFIG_PROC_FS
-static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
-                          int length, int *eof, void *data)
-{
-       unsigned int i;
-
-       if ((offset & 3) || (length & 3))
-               return -EIO;
-
-       if (offset >= sizeof(struct ip_rt_acct) * 256) {
-               *eof = 1;
-               return 0;
-       }
-
-       if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
-               length = sizeof(struct ip_rt_acct) * 256 - offset;
-               *eof = 1;
-       }
-
-       offset /= sizeof(u32);
-
-       if (length > 0) {
-               u32 *dst = (u32 *) buffer;
-
-               *start = buffer;
-               memset(dst, 0, length);
-
-               for_each_possible_cpu(i) {
-                       unsigned int j;
-                       u32 *src = ((u32 *) IP_RT_ACCT_CPU(i)) + offset;
-
-                       for (j = 0; j < length/4; j++)
-                               dst[j] += src[j];
-               }
-       }
-       return length;
-}
-#endif /* CONFIG_PROC_FS */
+struct ip_rt_acct *ip_rt_acct __read_mostly;
 #endif /* CONFIG_NET_CLS_ROUTE */
 
 static __initdata unsigned long rhash_entries;
@@ -2927,16 +3027,9 @@ int __init ip_rt_init(void)
                             (jiffies ^ (jiffies >> 7)));
 
 #ifdef CONFIG_NET_CLS_ROUTE
-       {
-       int order;
-       for (order = 0;
-            (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++)
-               /* NOTHING */;
-       ip_rt_acct = (struct ip_rt_acct *)__get_free_pages(GFP_KERNEL, order);
+       ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct));
        if (!ip_rt_acct)
                panic("IP: failed to allocate ip_rt_acct\n");
-       memset(ip_rt_acct, 0, PAGE_SIZE << order);
-       }
 #endif
 
        ipv4_dst_ops.kmem_cachep =
@@ -2964,10 +3057,8 @@ int __init ip_rt_init(void)
        devinet_init();
        ip_fib_init();
 
-       init_timer(&rt_flush_timer);
-       rt_flush_timer.function = rt_run_flush;
-       init_timer(&rt_secret_timer);
-       rt_secret_timer.function = rt_secret_rebuild;
+       setup_timer(&rt_flush_timer, rt_run_flush, 0);
+       setup_timer(&rt_secret_timer, rt_secret_rebuild, 0);
 
        /* All the timers, started at system startup tend
           to synchronize. Perturb it a bit.
@@ -2979,20 +3070,8 @@ int __init ip_rt_init(void)
                ip_rt_secret_interval;
        add_timer(&rt_secret_timer);
 
-#ifdef CONFIG_PROC_FS
-       {
-       struct proc_dir_entry *rtstat_pde = NULL; /* keep gcc happy */
-       if (!proc_net_fops_create(&init_net, "rt_cache", S_IRUGO, &rt_cache_seq_fops) ||
-           !(rtstat_pde = create_proc_entry("rt_cache", S_IRUGO,
-                                            init_net.proc_net_stat))) {
-               return -ENOMEM;
-       }
-       rtstat_pde->proc_fops = &rt_cpu_seq_fops;
-       }
-#ifdef CONFIG_NET_CLS_ROUTE
-       create_proc_read_entry("rt_acct", 0, init_net.proc_net, ip_rt_acct_read, NULL);
-#endif
-#endif
+       if (ip_rt_proc_init(&init_net))
+               printk(KERN_ERR "Unable to create route proc files\n");
 #ifdef CONFIG_XFRM
        xfrm_init();
        xfrm4_init();
index 2da1be0589a9e7f2fb2cb6c0383e0452df570207..f470fe4511dbf6a03205e3690ff616dfdf2c8ffa 100644 (file)
@@ -264,7 +264,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
                                               { .sport = th->dest,
                                                 .dport = th->source } } };
                security_req_classify_flow(req, &fl);
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        reqsk_free(req);
                        goto out;
                }
index bec6fe880657b9149228ac191ac1cb309f6bc05a..82cdf23837e3e8b9766ba5f7dbb28634a20c2675 100644 (file)
 #include <linux/igmp.h>
 #include <linux/inetdevice.h>
 #include <linux/seqlock.h>
+#include <linux/init.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/tcp.h>
+#include <net/udp.h>
 #include <net/cipso_ipv4.h>
 #include <net/inet_frag.h>
 
-/* From af_inet.c */
-extern int sysctl_ip_nonlocal_bind;
-
-#ifdef CONFIG_SYSCTL
 static int zero;
 static int tcp_retr1_max = 255;
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
-#endif
-
-struct ipv4_config ipv4_config;
-
-#ifdef CONFIG_SYSCTL
-
-static
-int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
-                       void __user *buffer, size_t *lenp, loff_t *ppos)
-{
-       int val = IPV4_DEVCONF_ALL(FORWARDING);
-       int ret;
-
-       ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-
-       if (write && IPV4_DEVCONF_ALL(FORWARDING) != val)
-               inet_forward_change();
-
-       return ret;
-}
-
-static int ipv4_sysctl_forward_strategy(ctl_table *table,
-                        int __user *name, int nlen,
-                        void __user *oldval, size_t __user *oldlenp,
-                        void __user *newval, size_t newlen)
-{
-       int *valp = table->data;
-       int new;
-
-       if (!newval || !newlen)
-               return 0;
-
-       if (newlen != sizeof(int))
-               return -EINVAL;
-
-       if (get_user(new, (int __user *)newval))
-               return -EFAULT;
-
-       if (new == *valp)
-               return 0;
-
-       if (oldval && oldlenp) {
-               size_t len;
-
-               if (get_user(len, oldlenp))
-                       return -EFAULT;
-
-               if (len) {
-                       if (len > table->maxlen)
-                               len = table->maxlen;
-                       if (copy_to_user(oldval, valp, len))
-                               return -EFAULT;
-                       if (put_user(len, oldlenp))
-                               return -EFAULT;
-               }
-       }
-
-       *valp = new;
-       inet_forward_change();
-       return 1;
-}
 
 extern seqlock_t sysctl_port_range_lock;
 extern int sysctl_local_port_range[2];
@@ -256,7 +193,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
 
 }
 
-ctl_table ipv4_table[] = {
+static struct ctl_table ipv4_table[] = {
        {
                .ctl_name       = NET_IPV4_TCP_TIMESTAMPS,
                .procname       = "tcp_timestamps",
@@ -289,15 +226,6 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-       {
-               .ctl_name       = NET_IPV4_FORWARD,
-               .procname       = "ip_forward",
-               .data           = &IPV4_DEVCONF_ALL(FORWARDING),
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &ipv4_sysctl_forward,
-               .strategy       = &ipv4_sysctl_forward_strategy
-       },
        {
                .ctl_name       = NET_IPV4_DEFAULT_TTL,
                .procname       = "ip_default_ttl",
@@ -355,22 +283,6 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-       {
-               .ctl_name       = NET_IPV4_IPFRAG_HIGH_THRESH,
-               .procname       = "ipfrag_high_thresh",
-               .data           = &ip4_frags_ctl.high_thresh,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
-       {
-               .ctl_name       = NET_IPV4_IPFRAG_LOW_THRESH,
-               .procname       = "ipfrag_low_thresh",
-               .data           = &ip4_frags_ctl.low_thresh,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
        {
                .ctl_name       = NET_IPV4_DYNADDR,
                .procname       = "ip_dynaddr",
@@ -379,15 +291,6 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-       {
-               .ctl_name       = NET_IPV4_IPFRAG_TIME,
-               .procname       = "ipfrag_time",
-               .data           = &ip4_frags_ctl.timeout,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
-       },
        {
                .ctl_name       = NET_IPV4_TCP_KEEPALIVE_TIME,
                .procname       = "tcp_keepalive_time",
@@ -730,23 +633,6 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-       {
-               .ctl_name       = NET_IPV4_IPFRAG_SECRET_INTERVAL,
-               .procname       = "ipfrag_secret_interval",
-               .data           = &ip4_frags_ctl.secret_interval,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
-       },
-       {
-               .procname       = "ipfrag_max_dist",
-               .data           = &sysctl_ipfrag_max_dist,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_minmax,
-               .extra1         = &zero
-       },
        {
                .ctl_name       = NET_TCP_NO_METRICS_SAVE,
                .procname       = "tcp_no_metrics_save",
@@ -885,9 +771,52 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "udp_mem",
+               .data           = &sysctl_udp_mem,
+               .maxlen         = sizeof(sysctl_udp_mem),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &zero
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "udp_rmem_min",
+               .data           = &sysctl_udp_rmem_min,
+               .maxlen         = sizeof(sysctl_udp_rmem_min),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &zero
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "udp_wmem_min",
+               .data           = &sysctl_udp_wmem_min,
+               .maxlen         = sizeof(sysctl_udp_wmem_min),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_minmax,
+               .strategy       = &sysctl_intvec,
+               .extra1         = &zero
+       },
        { .ctl_name = 0 }
 };
 
-#endif /* CONFIG_SYSCTL */
+struct ctl_path net_ipv4_ctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv4", .ctl_name = NET_IPV4, },
+       { },
+};
+EXPORT_SYMBOL_GPL(net_ipv4_ctl_path);
+
+static __init int sysctl_ipv4_init(void)
+{
+       struct ctl_table_header *hdr;
+
+       hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table);
+       return hdr == NULL ? -ENOMEM : 0;
+}
 
-EXPORT_SYMBOL(ipv4_config);
+__initcall(sysctl_ipv4_init);
index 8e65182f7af1cd04f71bb4d1f5b33bf8d2c2793c..a0d373bd906588276f2f8eef8aaab93a31d1fb31 100644 (file)
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/fs.h>
+#include <linux/skbuff.h>
+#include <linux/splice.h>
+#include <linux/net.h>
+#include <linux/socket.h>
 #include <linux/random.h>
 #include <linux/bootmem.h>
 #include <linux/cache.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 #include <net/netdma.h>
+#include <net/sock.h>
 
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
@@ -291,10 +296,19 @@ atomic_t tcp_sockets_allocated;   /* Current number of TCP sockets. */
 EXPORT_SYMBOL(tcp_memory_allocated);
 EXPORT_SYMBOL(tcp_sockets_allocated);
 
+/*
+ * TCP splice context
+ */
+struct tcp_splice_state {
+       struct pipe_inode_info *pipe;
+       size_t len;
+       unsigned int flags;
+};
+
 /*
  * Pressure flag: try to collapse.
  * Technical note: it is used by multiple contexts non atomically.
- * All the sk_stream_mem_schedule() is of this nature: accounting
+ * All the __sk_mem_schedule() is of this nature: accounting
  * is strict, actions are advisory and have some latency.
  */
 int tcp_memory_pressure __read_mostly;
@@ -471,7 +485,8 @@ static inline void skb_entail(struct sock *sk, struct sk_buff *skb)
        tcb->sacked  = 0;
        skb_header_release(skb);
        tcp_add_write_queue_tail(sk, skb);
-       sk_charge_skb(sk, skb);
+       sk->sk_wmem_queued += skb->truesize;
+       sk_mem_charge(sk, skb->truesize);
        if (tp->nonagle & TCP_NAGLE_PUSH)
                tp->nonagle &= ~TCP_NAGLE_PUSH;
 }
@@ -482,7 +497,6 @@ static inline void tcp_mark_urg(struct tcp_sock *tp, int flags,
        if (flags & MSG_OOB) {
                tp->urg_mode = 1;
                tp->snd_up = tp->write_seq;
-               TCP_SKB_CB(skb)->sacked |= TCPCB_URG;
        }
 }
 
@@ -501,6 +515,145 @@ static inline void tcp_push(struct sock *sk, int flags, int mss_now,
        }
 }
 
+static int tcp_splice_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+                               unsigned int offset, size_t len)
+{
+       struct tcp_splice_state *tss = rd_desc->arg.data;
+
+       return skb_splice_bits(skb, offset, tss->pipe, tss->len, tss->flags);
+}
+
+static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss)
+{
+       /* Store TCP splice context information in read_descriptor_t. */
+       read_descriptor_t rd_desc = {
+               .arg.data = tss,
+       };
+
+       return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv);
+}
+
+/**
+ *  tcp_splice_read - splice data from TCP socket to a pipe
+ * @sock:      socket to splice from
+ * @ppos:      position (not valid)
+ * @pipe:      pipe to splice to
+ * @len:       number of bytes to splice
+ * @flags:     splice modifier flags
+ *
+ * Description:
+ *    Will read pages from given socket and fill them into a pipe.
+ *
+ **/
+ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
+                       struct pipe_inode_info *pipe, size_t len,
+                       unsigned int flags)
+{
+       struct sock *sk = sock->sk;
+       struct tcp_splice_state tss = {
+               .pipe = pipe,
+               .len = len,
+               .flags = flags,
+       };
+       long timeo;
+       ssize_t spliced;
+       int ret;
+
+       /*
+        * We can't seek on a socket input
+        */
+       if (unlikely(*ppos))
+               return -ESPIPE;
+
+       ret = spliced = 0;
+
+       lock_sock(sk);
+
+       timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK);
+       while (tss.len) {
+               ret = __tcp_splice_read(sk, &tss);
+               if (ret < 0)
+                       break;
+               else if (!ret) {
+                       if (spliced)
+                               break;
+                       if (flags & SPLICE_F_NONBLOCK) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+                       if (sock_flag(sk, SOCK_DONE))
+                               break;
+                       if (sk->sk_err) {
+                               ret = sock_error(sk);
+                               break;
+                       }
+                       if (sk->sk_shutdown & RCV_SHUTDOWN)
+                               break;
+                       if (sk->sk_state == TCP_CLOSE) {
+                               /*
+                                * This occurs when user tries to read
+                                * from never connected socket.
+                                */
+                               if (!sock_flag(sk, SOCK_DONE))
+                                       ret = -ENOTCONN;
+                               break;
+                       }
+                       if (!timeo) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+                       sk_wait_data(sk, &timeo);
+                       if (signal_pending(current)) {
+                               ret = sock_intr_errno(timeo);
+                               break;
+                       }
+                       continue;
+               }
+               tss.len -= ret;
+               spliced += ret;
+
+               release_sock(sk);
+               lock_sock(sk);
+
+               if (sk->sk_err || sk->sk_state == TCP_CLOSE ||
+                   (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo ||
+                   signal_pending(current))
+                       break;
+       }
+
+       release_sock(sk);
+
+       if (spliced)
+               return spliced;
+
+       return ret;
+}
+
+struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
+{
+       struct sk_buff *skb;
+
+       /* The TCP header must be at least 32-bit aligned.  */
+       size = ALIGN(size, 4);
+
+       skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
+       if (skb) {
+               if (sk_wmem_schedule(sk, skb->truesize)) {
+                       /*
+                        * Make sure that we have exactly size bytes
+                        * available to the caller, no more, no less.
+                        */
+                       skb_reserve(skb, skb_tailroom(skb) - size);
+                       return skb;
+               }
+               __kfree_skb(skb);
+       } else {
+               sk->sk_prot->enter_memory_pressure();
+               sk_stream_moderate_sndbuf(sk);
+       }
+       return NULL;
+}
+
 static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset,
                         size_t psize, int flags)
 {
@@ -537,8 +690,7 @@ new_segment:
                        if (!sk_stream_memory_free(sk))
                                goto wait_for_sndbuf;
 
-                       skb = sk_stream_alloc_pskb(sk, 0, 0,
-                                                  sk->sk_allocation);
+                       skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation);
                        if (!skb)
                                goto wait_for_memory;
 
@@ -555,7 +707,7 @@ new_segment:
                        tcp_mark_push(tp, skb);
                        goto new_segment;
                }
-               if (!sk_stream_wmem_schedule(sk, copy))
+               if (!sk_wmem_schedule(sk, copy))
                        goto wait_for_memory;
 
                if (can_coalesce) {
@@ -569,7 +721,7 @@ new_segment:
                skb->data_len += copy;
                skb->truesize += copy;
                sk->sk_wmem_queued += copy;
-               sk->sk_forward_alloc -= copy;
+               sk_mem_charge(sk, copy);
                skb->ip_summed = CHECKSUM_PARTIAL;
                tp->write_seq += copy;
                TCP_SKB_CB(skb)->end_seq += copy;
@@ -718,8 +870,8 @@ new_segment:
                                if (!sk_stream_memory_free(sk))
                                        goto wait_for_sndbuf;
 
-                               skb = sk_stream_alloc_pskb(sk, select_size(sk),
-                                                          0, sk->sk_allocation);
+                               skb = sk_stream_alloc_skb(sk, select_size(sk),
+                                               sk->sk_allocation);
                                if (!skb)
                                        goto wait_for_memory;
 
@@ -776,7 +928,7 @@ new_segment:
                                if (copy > PAGE_SIZE - off)
                                        copy = PAGE_SIZE - off;
 
-                               if (!sk_stream_wmem_schedule(sk, copy))
+                               if (!sk_wmem_schedule(sk, copy))
                                        goto wait_for_memory;
 
                                if (!page) {
@@ -867,7 +1019,7 @@ do_fault:
                 * reset, where we can be unlinking the send_head.
                 */
                tcp_check_send_head(sk, skb);
-               sk_stream_free_skb(sk, skb);
+               sk_wmem_free_skb(sk, skb);
        }
 
 do_error:
@@ -1500,6 +1652,41 @@ recv_urg:
        goto out;
 }
 
+void tcp_set_state(struct sock *sk, int state)
+{
+       int oldstate = sk->sk_state;
+
+       switch (state) {
+       case TCP_ESTABLISHED:
+               if (oldstate != TCP_ESTABLISHED)
+                       TCP_INC_STATS(TCP_MIB_CURRESTAB);
+               break;
+
+       case TCP_CLOSE:
+               if (oldstate == TCP_CLOSE_WAIT || oldstate == TCP_ESTABLISHED)
+                       TCP_INC_STATS(TCP_MIB_ESTABRESETS);
+
+               sk->sk_prot->unhash(sk);
+               if (inet_csk(sk)->icsk_bind_hash &&
+                   !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
+                       inet_put_port(&tcp_hashinfo, sk);
+               /* fall through */
+       default:
+               if (oldstate==TCP_ESTABLISHED)
+                       TCP_DEC_STATS(TCP_MIB_CURRESTAB);
+       }
+
+       /* Change state AFTER socket is unhashed to avoid closed
+        * socket sitting in hash tables.
+        */
+       sk->sk_state = state;
+
+#ifdef STATE_TRACE
+       SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
+#endif
+}
+EXPORT_SYMBOL_GPL(tcp_set_state);
+
 /*
  *     State processing on a close. This implements the state shift for
  *     sending our FIN frame. Note that we only send a FIN for some
@@ -1586,7 +1773,7 @@ void tcp_close(struct sock *sk, long timeout)
                __kfree_skb(skb);
        }
 
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 
        /* As outlined in RFC 2525, section 2.17, we send a RST here because
         * data was lost. To witness the awful effects of the old behavior of
@@ -1689,7 +1876,7 @@ adjudge_to_death:
                }
        }
        if (sk->sk_state != TCP_CLOSE) {
-               sk_stream_mem_reclaim(sk);
+               sk_mem_reclaim(sk);
                if (tcp_too_many_orphans(sk,
                                atomic_read(sk->sk_prot->orphan_count))) {
                        if (net_ratelimit())
@@ -2411,7 +2598,6 @@ void tcp_done(struct sock *sk)
 }
 EXPORT_SYMBOL_GPL(tcp_done);
 
-extern void __skb_cb_too_small_for_tcp(int, int);
 extern struct tcp_congestion_ops tcp_reno;
 
 static __initdata unsigned long thash_entries;
@@ -2430,9 +2616,7 @@ void __init tcp_init(void)
        unsigned long limit;
        int order, i, max_share;
 
-       if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb))
-               __skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb),
-                                          sizeof(skb->cb));
+       BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
 
        tcp_hashinfo.bind_bucket_cachep =
                kmem_cache_create("tcp_bind_bucket",
@@ -2509,11 +2693,11 @@ void __init tcp_init(void)
        limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
        max_share = min(4UL*1024*1024, limit);
 
-       sysctl_tcp_wmem[0] = SK_STREAM_MEM_QUANTUM;
+       sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_wmem[1] = 16*1024;
        sysctl_tcp_wmem[2] = max(64*1024, max_share);
 
-       sysctl_tcp_rmem[0] = SK_STREAM_MEM_QUANTUM;
+       sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
        sysctl_tcp_rmem[1] = 87380;
        sysctl_tcp_rmem[2] = max(87380, max_share);
 
@@ -2532,6 +2716,7 @@ EXPORT_SYMBOL(tcp_poll);
 EXPORT_SYMBOL(tcp_read_sock);
 EXPORT_SYMBOL(tcp_recvmsg);
 EXPORT_SYMBOL(tcp_sendmsg);
+EXPORT_SYMBOL(tcp_splice_read);
 EXPORT_SYMBOL(tcp_sendpage);
 EXPORT_SYMBOL(tcp_setsockopt);
 EXPORT_SYMBOL(tcp_shutdown);
index 5dba0fc8f579f8b5b31ca47b0e458a440d524de1..5212ed9b0c98d701169074f83898cd143e9315c6 100644 (file)
@@ -136,8 +136,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
                ca->cnt = 1;
 }
 
-static void bictcp_cong_avoid(struct sock *sk, u32 ack,
-                             u32 in_flight, int data_acked)
+static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bictcp *ca = inet_csk_ca(sk);
index 55fca1820c344d7bb900e0ab486ff627c951f924..3a6be23d222f382c32dcd1e3acc5e55b97594797 100644 (file)
@@ -274,6 +274,27 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
        return err;
 }
 
+/* RFC2861 Check whether we are limited by application or congestion window
+ * This is the inverse of cwnd check in tcp_tso_should_defer
+ */
+int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
+{
+       const struct tcp_sock *tp = tcp_sk(sk);
+       u32 left;
+
+       if (in_flight >= tp->snd_cwnd)
+               return 1;
+
+       if (!sk_can_gso(sk))
+               return 0;
+
+       left = tp->snd_cwnd - in_flight;
+       if (sysctl_tcp_tso_win_divisor)
+               return left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd;
+       else
+               return left <= tcp_max_burst(tp);
+}
+EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited);
 
 /*
  * Slow start is used when congestion window is less than slow start
@@ -324,7 +345,7 @@ EXPORT_SYMBOL_GPL(tcp_slow_start);
 /* This is Jacobson's slow start and congestion avoidance.
  * SIGCOMM '88, p. 328.
  */
-void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int flag)
+void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
index 80bd084a9f9198d5b4c31f380ffcd5448a8390b0..3aa0b23c1ea0293c7d68e65f4bf568b3c18b261e 100644 (file)
@@ -246,8 +246,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
                ca->cnt = 1;
 }
 
-static void bictcp_cong_avoid(struct sock *sk, u32 ack,
-                             u32 in_flight, int data_acked)
+static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct bictcp *ca = inet_csk_ca(sk);
index 14a073d8b60f41bf5ecf84bd07d21dcbd89664ff..8b6caaf75bb9877648052b97209c7b2bca2f132b 100644 (file)
@@ -109,8 +109,7 @@ static void hstcp_init(struct sock *sk)
        tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128);
 }
 
-static void hstcp_cong_avoid(struct sock *sk, u32 adk,
-                            u32 in_flight, int data_acked)
+static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct hstcp *ca = inet_csk_ca(sk);
index 5215691f2760e710ac56934e539665f51161fbe2..af99776146ffc14a4f85cb08ceaaea619d7b8a90 100644 (file)
@@ -225,8 +225,7 @@ static u32 htcp_recalc_ssthresh(struct sock *sk)
        return max((tp->snd_cwnd * ca->beta) >> 7, 2U);
 }
 
-static void htcp_cong_avoid(struct sock *sk, u32 ack,
-                           u32 in_flight, int data_acked)
+static void htcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct htcp *ca = inet_csk_ca(sk);
index b3e55cf56171b7fb90078d221df609777c6d84f2..44618b6759167b8d48227ade7d8ede9f72fa9779 100644 (file)
@@ -85,8 +85,7 @@ static inline u32 hybla_fraction(u32 odds)
  *     o Give cwnd a new value based on the model proposed
  *     o remember increments <1
  */
-static void hybla_cong_avoid(struct sock *sk, u32 ack,
-                           u32 in_flight, int flag)
+static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct hybla *ca = inet_csk_ca(sk);
@@ -103,7 +102,7 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack,
                return;
 
        if (!ca->hybla_en)
-               return tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+               return tcp_reno_cong_avoid(sk, ack, in_flight);
 
        if (ca->rho == 0)
                hybla_recalc_param(sk);
index 5aa5f5496d6d79e4553fcb2cdf0f5f8283f33e45..1eba160b72dc452b70ddbbfaa374de51ce938f0d 100644 (file)
@@ -256,8 +256,7 @@ static void tcp_illinois_state(struct sock *sk, u8 new_state)
 /*
  * Increase window in response to successful acknowledgment.
  */
-static void tcp_illinois_cong_avoid(struct sock *sk, u32 ack,
-                                   u32 in_flight, int flag)
+static void tcp_illinois_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct illinois *ca = inet_csk_ca(sk);
index b39f0d86e44cb06abfc76fcfbebbad27c86ab367..fa2c85ca5bc39c32947f499ef6f531d840cc925e 100644 (file)
@@ -105,6 +105,7 @@ int sysctl_tcp_abc __read_mostly;
 #define FLAG_SND_UNA_ADVANCED  0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
 #define FLAG_DSACKING_ACK      0x800 /* SACK blocks contained D-SACK info */
 #define FLAG_NONHEAD_RETRANS_ACKED     0x1000 /* Non-head rexmitted data was ACKed */
+#define FLAG_SACK_RENEGING     0x2000 /* snd_una advanced to a sacked seq */
 
 #define FLAG_ACKED             (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
 #define FLAG_NOT_DUP           (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
@@ -120,8 +121,7 @@ int sysctl_tcp_abc __read_mostly;
 /* Adapt the MSS value used to make delayed ack decision to the
  * real world.
  */
-static void tcp_measure_rcv_mss(struct sock *sk,
-                               const struct sk_buff *skb)
+static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        const unsigned int lss = icsk->icsk_ack.last_seg_size;
@@ -132,7 +132,7 @@ static void tcp_measure_rcv_mss(struct sock *sk,
        /* skb->len may jitter because of SACKs, even if peer
         * sends good full-sized frames.
         */
-       len = skb_shinfo(skb)->gso_size ?: skb->len;
+       len = skb_shinfo(skb)->gso_size ? : skb->len;
        if (len >= icsk->icsk_ack.rcv_mss) {
                icsk->icsk_ack.rcv_mss = len;
        } else {
@@ -172,8 +172,8 @@ static void tcp_incr_quickack(struct sock *sk)
        struct inet_connection_sock *icsk = inet_csk(sk);
        unsigned quickacks = tcp_sk(sk)->rcv_wnd / (2 * icsk->icsk_ack.rcv_mss);
 
-       if (quickacks==0)
-               quickacks=2;
+       if (quickacks == 0)
+               quickacks = 2;
        if (quickacks > icsk->icsk_ack.quick)
                icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
 }
@@ -198,7 +198,7 @@ static inline int tcp_in_quickack_mode(const struct sock *sk)
 
 static inline void TCP_ECN_queue_cwr(struct tcp_sock *tp)
 {
-       if (tp->ecn_flags&TCP_ECN_OK)
+       if (tp->ecn_flags & TCP_ECN_OK)
                tp->ecn_flags |= TCP_ECN_QUEUE_CWR;
 }
 
@@ -215,7 +215,7 @@ static inline void TCP_ECN_withdraw_cwr(struct tcp_sock *tp)
 
 static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb)
 {
-       if (tp->ecn_flags&TCP_ECN_OK) {
+       if (tp->ecn_flags & TCP_ECN_OK) {
                if (INET_ECN_is_ce(TCP_SKB_CB(skb)->flags))
                        tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
                /* Funny extension: if ECT is not set on a segment,
@@ -228,19 +228,19 @@ static inline void TCP_ECN_check_ce(struct tcp_sock *tp, struct sk_buff *skb)
 
 static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, struct tcphdr *th)
 {
-       if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || th->cwr))
+       if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || th->cwr))
                tp->ecn_flags &= ~TCP_ECN_OK;
 }
 
 static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, struct tcphdr *th)
 {
-       if ((tp->ecn_flags&TCP_ECN_OK) && (!th->ece || !th->cwr))
+       if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || !th->cwr))
                tp->ecn_flags &= ~TCP_ECN_OK;
 }
 
 static inline int TCP_ECN_rcv_ecn_echo(struct tcp_sock *tp, struct tcphdr *th)
 {
-       if (th->ece && !th->syn && (tp->ecn_flags&TCP_ECN_OK))
+       if (th->ece && !th->syn && (tp->ecn_flags & TCP_ECN_OK))
                return 1;
        return 0;
 }
@@ -289,8 +289,8 @@ static int __tcp_grow_window(const struct sock *sk, const struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        /* Optimize this! */
-       int truesize = tcp_win_from_space(skb->truesize)/2;
-       int window = tcp_win_from_space(sysctl_tcp_rmem[2])/2;
+       int truesize = tcp_win_from_space(skb->truesize) >> 1;
+       int window = tcp_win_from_space(sysctl_tcp_rmem[2]) >> 1;
 
        while (tp->rcv_ssthresh <= window) {
                if (truesize <= skb->len)
@@ -302,8 +302,7 @@ static int __tcp_grow_window(const struct sock *sk, const struct sk_buff *skb)
        return 0;
 }
 
-static void tcp_grow_window(struct sock *sk,
-                           struct sk_buff *skb)
+static void tcp_grow_window(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
@@ -317,12 +316,13 @@ static void tcp_grow_window(struct sock *sk,
                 * will fit to rcvbuf in future.
                 */
                if (tcp_win_from_space(skb->truesize) <= skb->len)
-                       incr = 2*tp->advmss;
+                       incr = 2 * tp->advmss;
                else
                        incr = __tcp_grow_window(sk, skb);
 
                if (incr) {
-                       tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp);
+                       tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr,
+                                              tp->window_clamp);
                        inet_csk(sk)->icsk_ack.quick |= 1;
                }
        }
@@ -397,10 +397,9 @@ static void tcp_clamp_window(struct sock *sk)
                                    sysctl_tcp_rmem[2]);
        }
        if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf)
-               tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
+               tp->rcv_ssthresh = min(tp->window_clamp, 2U * tp->advmss);
 }
 
-
 /* Initialize RCV_MSS value.
  * RCV_MSS is an our guess about MSS used by the peer.
  * We haven't any direct information about the MSS.
@@ -413,7 +412,7 @@ void tcp_initialize_rcv_mss(struct sock *sk)
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
 
-       hint = min(hint, tp->rcv_wnd/2);
+       hint = min(hint, tp->rcv_wnd / 2);
        hint = min(hint, TCP_MIN_RCVMSS);
        hint = max(hint, TCP_MIN_MSS);
 
@@ -470,16 +469,15 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp)
                goto new_measure;
        if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq))
                return;
-       tcp_rcv_rtt_update(tp,
-                          jiffies - tp->rcv_rtt_est.time,
-                          1);
+       tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1);
 
 new_measure:
        tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd;
        tp->rcv_rtt_est.time = tcp_time_stamp;
 }
 
-static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, const struct sk_buff *skb)
+static inline void tcp_rcv_rtt_measure_ts(struct sock *sk,
+                                         const struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        if (tp->rx_opt.rcv_tsecr &&
@@ -502,8 +500,7 @@ void tcp_rcv_space_adjust(struct sock *sk)
                goto new_measure;
 
        time = tcp_time_stamp - tp->rcvq_space.time;
-       if (time < (tp->rcv_rtt_est.rtt >> 3) ||
-           tp->rcv_rtt_est.rtt == 0)
+       if (time < (tp->rcv_rtt_est.rtt >> 3) || tp->rcv_rtt_est.rtt == 0)
                return;
 
        space = 2 * (tp->copied_seq - tp->rcvq_space.seq);
@@ -579,7 +576,7 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
        } else {
                int m = now - icsk->icsk_ack.lrcvtime;
 
-               if (m <= TCP_ATO_MIN/2) {
+               if (m <= TCP_ATO_MIN / 2) {
                        /* The fastest case is the first. */
                        icsk->icsk_ack.ato = (icsk->icsk_ack.ato >> 1) + TCP_ATO_MIN / 2;
                } else if (m < icsk->icsk_ack.ato) {
@@ -591,7 +588,7 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
                         * restart window, so that we send ACKs quickly.
                         */
                        tcp_incr_quickack(sk);
-                       sk_stream_mem_reclaim(sk);
+                       sk_mem_reclaim(sk);
                }
        }
        icsk->icsk_ack.lrcvtime = now;
@@ -608,7 +605,7 @@ static u32 tcp_rto_min(struct sock *sk)
        u32 rto_min = TCP_RTO_MIN;
 
        if (dst && dst_metric_locked(dst, RTAX_RTO_MIN))
-               rto_min = dst->metrics[RTAX_RTO_MIN-1];
+               rto_min = dst->metrics[RTAX_RTO_MIN - 1];
        return rto_min;
 }
 
@@ -671,14 +668,14 @@ static void tcp_rtt_estimator(struct sock *sk, const __u32 mrtt)
                }
                if (after(tp->snd_una, tp->rtt_seq)) {
                        if (tp->mdev_max < tp->rttvar)
-                               tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2;
+                               tp->rttvar -= (tp->rttvar - tp->mdev_max) >> 2;
                        tp->rtt_seq = tp->snd_nxt;
                        tp->mdev_max = tcp_rto_min(sk);
                }
        } else {
                /* no previous measure. */
-               tp->srtt = m<<3;        /* take the measured time to be rtt */
-               tp->mdev = m<<1;        /* make sure rto = 3*rtt */
+               tp->srtt = m << 3;      /* take the measured time to be rtt */
+               tp->mdev = m << 1;      /* make sure rto = 3*rtt */
                tp->mdev_max = tp->rttvar = max(tp->mdev, tcp_rto_min(sk));
                tp->rtt_seq = tp->snd_nxt;
        }
@@ -732,7 +729,7 @@ void tcp_update_metrics(struct sock *sk)
 
        dst_confirm(dst);
 
-       if (dst && (dst->flags&DST_HOST)) {
+       if (dst && (dst->flags & DST_HOST)) {
                const struct inet_connection_sock *icsk = inet_csk(sk);
                int m;
 
@@ -742,7 +739,7 @@ void tcp_update_metrics(struct sock *sk)
                         * Reset our results.
                         */
                        if (!(dst_metric_locked(dst, RTAX_RTT)))
-                               dst->metrics[RTAX_RTT-1] = 0;
+                               dst->metrics[RTAX_RTT - 1] = 0;
                        return;
                }
 
@@ -754,9 +751,9 @@ void tcp_update_metrics(struct sock *sk)
                 */
                if (!(dst_metric_locked(dst, RTAX_RTT))) {
                        if (m <= 0)
-                               dst->metrics[RTAX_RTT-1] = tp->srtt;
+                               dst->metrics[RTAX_RTT - 1] = tp->srtt;
                        else
-                               dst->metrics[RTAX_RTT-1] -= (m>>3);
+                               dst->metrics[RTAX_RTT - 1] -= (m >> 3);
                }
 
                if (!(dst_metric_locked(dst, RTAX_RTTVAR))) {
@@ -769,7 +766,7 @@ void tcp_update_metrics(struct sock *sk)
                                m = tp->mdev;
 
                        if (m >= dst_metric(dst, RTAX_RTTVAR))
-                               dst->metrics[RTAX_RTTVAR-1] = m;
+                               dst->metrics[RTAX_RTTVAR - 1] = m;
                        else
                                dst->metrics[RTAX_RTTVAR-1] -=
                                        (dst->metrics[RTAX_RTTVAR-1] - m)>>2;
@@ -783,7 +780,7 @@ void tcp_update_metrics(struct sock *sk)
                                dst->metrics[RTAX_SSTHRESH-1] = tp->snd_cwnd >> 1;
                        if (!dst_metric_locked(dst, RTAX_CWND) &&
                            tp->snd_cwnd > dst_metric(dst, RTAX_CWND))
-                               dst->metrics[RTAX_CWND-1] = tp->snd_cwnd;
+                               dst->metrics[RTAX_CWND - 1] = tp->snd_cwnd;
                } else if (tp->snd_cwnd > tp->snd_ssthresh &&
                           icsk->icsk_ca_state == TCP_CA_Open) {
                        /* Cong. avoidance phase, cwnd is reliable. */
@@ -863,6 +860,9 @@ void tcp_enter_cwr(struct sock *sk, const int set_ssthresh)
  */
 static void tcp_disable_fack(struct tcp_sock *tp)
 {
+       /* RFC3517 uses different metric in lost marker => reset on change */
+       if (tcp_is_fack(tp))
+               tp->lost_skb_hint = NULL;
        tp->rx_opt.sack_ok &= ~2;
 }
 
@@ -1112,16 +1112,22 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack,
  *
  * Search retransmitted skbs from write_queue that were sent when snd_nxt was
  * less than what is now known to be received by the other end (derived from
- * SACK blocks by the caller). Also calculate the lowest snd_nxt among the
- * remaining retransmitted skbs to avoid some costly processing per ACKs.
+ * highest SACK block). Also calculate the lowest snd_nxt among the remaining
+ * retransmitted skbs to avoid some costly processing per ACKs.
  */
-static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
+static void tcp_mark_lost_retrans(struct sock *sk)
 {
+       const struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
-       int flag = 0;
        int cnt = 0;
        u32 new_low_seq = tp->snd_nxt;
+       u32 received_upto = tcp_highest_sack_seq(tp);
+
+       if (!tcp_is_fack(tp) || !tp->retrans_out ||
+           !after(received_upto, tp->lost_retrans_low) ||
+           icsk->icsk_ca_state != TCP_CA_Recovery)
+               return;
 
        tcp_for_write_queue(skb, sk) {
                u32 ack_seq = TCP_SKB_CB(skb)->ack_seq;
@@ -1149,9 +1155,8 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
                        if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
                                tp->lost_out += tcp_skb_pcount(skb);
                                TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-                               flag |= FLAG_DATA_SACKED;
-                               NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
                        }
+                       NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT);
                } else {
                        if (before(ack_seq, new_low_seq))
                                new_low_seq = ack_seq;
@@ -1161,8 +1166,6 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto)
 
        if (tp->retrans_out)
                tp->lost_retrans_low = new_low_seq;
-
-       return flag;
 }
 
 static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb,
@@ -1230,34 +1233,205 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
        return in_sack;
 }
 
+static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
+                          int *reord, int dup_sack, int fack_count)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       u8 sacked = TCP_SKB_CB(skb)->sacked;
+       int flag = 0;
+
+       /* Account D-SACK for retransmitted packet. */
+       if (dup_sack && (sacked & TCPCB_RETRANS)) {
+               if (after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker))
+                       tp->undo_retrans--;
+               if (sacked & TCPCB_SACKED_ACKED)
+                       *reord = min(fack_count, *reord);
+       }
+
+       /* Nothing to do; acked frame is about to be dropped (was ACKed). */
+       if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
+               return flag;
+
+       if (!(sacked & TCPCB_SACKED_ACKED)) {
+               if (sacked & TCPCB_SACKED_RETRANS) {
+                       /* If the segment is not tagged as lost,
+                        * we do not clear RETRANS, believing
+                        * that retransmission is still in flight.
+                        */
+                       if (sacked & TCPCB_LOST) {
+                               TCP_SKB_CB(skb)->sacked &=
+                                       ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
+                               tp->lost_out -= tcp_skb_pcount(skb);
+                               tp->retrans_out -= tcp_skb_pcount(skb);
+
+                               /* clear lost hint */
+                               tp->retransmit_skb_hint = NULL;
+                       }
+               } else {
+                       if (!(sacked & TCPCB_RETRANS)) {
+                               /* New sack for not retransmitted frame,
+                                * which was in hole. It is reordering.
+                                */
+                               if (before(TCP_SKB_CB(skb)->seq,
+                                          tcp_highest_sack_seq(tp)))
+                                       *reord = min(fack_count, *reord);
+
+                               /* SACK enhanced F-RTO (RFC4138; Appendix B) */
+                               if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
+                                       flag |= FLAG_ONLY_ORIG_SACKED;
+                       }
+
+                       if (sacked & TCPCB_LOST) {
+                               TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
+                               tp->lost_out -= tcp_skb_pcount(skb);
+
+                               /* clear lost hint */
+                               tp->retransmit_skb_hint = NULL;
+                       }
+               }
+
+               TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
+               flag |= FLAG_DATA_SACKED;
+               tp->sacked_out += tcp_skb_pcount(skb);
+
+               fack_count += tcp_skb_pcount(skb);
+
+               /* Lost marker hint past SACKed? Tweak RFC3517 cnt */
+               if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) &&
+                   before(TCP_SKB_CB(skb)->seq,
+                          TCP_SKB_CB(tp->lost_skb_hint)->seq))
+                       tp->lost_cnt_hint += tcp_skb_pcount(skb);
+
+               if (fack_count > tp->fackets_out)
+                       tp->fackets_out = fack_count;
+
+               if (!before(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp)))
+                       tcp_advance_highest_sack(sk, skb);
+       }
+
+       /* D-SACK. We can detect redundant retransmission in S|R and plain R
+        * frames and clear it. undo_retrans is decreased above, L|R frames
+        * are accounted above as well.
+        */
+       if (dup_sack && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)) {
+               TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
+               tp->retrans_out -= tcp_skb_pcount(skb);
+               tp->retransmit_skb_hint = NULL;
+       }
+
+       return flag;
+}
+
+static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk,
+                                       struct tcp_sack_block *next_dup,
+                                       u32 start_seq, u32 end_seq,
+                                       int dup_sack_in, int *fack_count,
+                                       int *reord, int *flag)
+{
+       tcp_for_write_queue_from(skb, sk) {
+               int in_sack = 0;
+               int dup_sack = dup_sack_in;
+
+               if (skb == tcp_send_head(sk))
+                       break;
+
+               /* queue is in-order => we can short-circuit the walk early */
+               if (!before(TCP_SKB_CB(skb)->seq, end_seq))
+                       break;
+
+               if ((next_dup != NULL) &&
+                   before(TCP_SKB_CB(skb)->seq, next_dup->end_seq)) {
+                       in_sack = tcp_match_skb_to_sack(sk, skb,
+                                                       next_dup->start_seq,
+                                                       next_dup->end_seq);
+                       if (in_sack > 0)
+                               dup_sack = 1;
+               }
+
+               if (in_sack <= 0)
+                       in_sack = tcp_match_skb_to_sack(sk, skb, start_seq,
+                                                       end_seq);
+               if (unlikely(in_sack < 0))
+                       break;
+
+               if (in_sack)
+                       *flag |= tcp_sacktag_one(skb, sk, reord, dup_sack,
+                                                *fack_count);
+
+               *fack_count += tcp_skb_pcount(skb);
+       }
+       return skb;
+}
+
+/* Avoid all extra work that is being done by sacktag while walking in
+ * a normal way
+ */
+static struct sk_buff *tcp_sacktag_skip(struct sk_buff *skb, struct sock *sk,
+                                       u32 skip_to_seq)
+{
+       tcp_for_write_queue_from(skb, sk) {
+               if (skb == tcp_send_head(sk))
+                       break;
+
+               if (!before(TCP_SKB_CB(skb)->end_seq, skip_to_seq))
+                       break;
+       }
+       return skb;
+}
+
+static struct sk_buff *tcp_maybe_skipping_dsack(struct sk_buff *skb,
+                                               struct sock *sk,
+                                               struct tcp_sack_block *next_dup,
+                                               u32 skip_to_seq,
+                                               int *fack_count, int *reord,
+                                               int *flag)
+{
+       if (next_dup == NULL)
+               return skb;
+
+       if (before(next_dup->start_seq, skip_to_seq)) {
+               skb = tcp_sacktag_skip(skb, sk, next_dup->start_seq);
+               tcp_sacktag_walk(skb, sk, NULL,
+                                next_dup->start_seq, next_dup->end_seq,
+                                1, fack_count, reord, flag);
+       }
+
+       return skb;
+}
+
+static int tcp_sack_cache_ok(struct tcp_sock *tp, struct tcp_sack_block *cache)
+{
+       return cache < tp->recv_sack_cache + ARRAY_SIZE(tp->recv_sack_cache);
+}
+
 static int
-tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_una)
+tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb,
+                       u32 prior_snd_una)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
        unsigned char *ptr = (skb_transport_header(ack_skb) +
                              TCP_SKB_CB(ack_skb)->sacked);
-       struct tcp_sack_block_wire *sp = (struct tcp_sack_block_wire *)(ptr+2);
-       struct sk_buff *cached_skb;
-       int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
+       struct tcp_sack_block_wire *sp_wire = (struct tcp_sack_block_wire *)(ptr+2);
+       struct tcp_sack_block sp[4];
+       struct tcp_sack_block *cache;
+       struct sk_buff *skb;
+       int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE) >> 3;
+       int used_sacks;
        int reord = tp->packets_out;
-       int prior_fackets;
-       u32 highest_sack_end_seq = tp->lost_retrans_low;
        int flag = 0;
        int found_dup_sack = 0;
-       int cached_fack_count;
-       int i;
+       int fack_count;
+       int i, j;
        int first_sack_index;
-       int force_one_sack;
 
        if (!tp->sacked_out) {
                if (WARN_ON(tp->fackets_out))
                        tp->fackets_out = 0;
-               tp->highest_sack = tp->snd_una;
+               tcp_highest_sack_reset(sk);
        }
-       prior_fackets = tp->fackets_out;
 
-       found_dup_sack = tcp_check_dsack(tp, ack_skb, sp,
+       found_dup_sack = tcp_check_dsack(tp, ack_skb, sp_wire,
                                         num_sacks, prior_snd_una);
        if (found_dup_sack)
                flag |= FLAG_DSACKING_ACK;
@@ -1272,78 +1446,17 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        if (!tp->packets_out)
                goto out;
 
-       /* SACK fastpath:
-        * if the only SACK change is the increase of the end_seq of
-        * the first block then only apply that SACK block
-        * and use retrans queue hinting otherwise slowpath */
-       force_one_sack = 1;
-       for (i = 0; i < num_sacks; i++) {
-               __be32 start_seq = sp[i].start_seq;
-               __be32 end_seq = sp[i].end_seq;
-
-               if (i == 0) {
-                       if (tp->recv_sack_cache[i].start_seq != start_seq)
-                               force_one_sack = 0;
-               } else {
-                       if ((tp->recv_sack_cache[i].start_seq != start_seq) ||
-                           (tp->recv_sack_cache[i].end_seq != end_seq))
-                               force_one_sack = 0;
-               }
-               tp->recv_sack_cache[i].start_seq = start_seq;
-               tp->recv_sack_cache[i].end_seq = end_seq;
-       }
-       /* Clear the rest of the cache sack blocks so they won't match mistakenly. */
-       for (; i < ARRAY_SIZE(tp->recv_sack_cache); i++) {
-               tp->recv_sack_cache[i].start_seq = 0;
-               tp->recv_sack_cache[i].end_seq = 0;
-       }
-
+       used_sacks = 0;
        first_sack_index = 0;
-       if (force_one_sack)
-               num_sacks = 1;
-       else {
-               int j;
-               tp->fastpath_skb_hint = NULL;
-
-               /* order SACK blocks to allow in order walk of the retrans queue */
-               for (i = num_sacks-1; i > 0; i--) {
-                       for (j = 0; j < i; j++){
-                               if (after(ntohl(sp[j].start_seq),
-                                         ntohl(sp[j+1].start_seq))){
-                                       struct tcp_sack_block_wire tmp;
-
-                                       tmp = sp[j];
-                                       sp[j] = sp[j+1];
-                                       sp[j+1] = tmp;
-
-                                       /* Track where the first SACK block goes to */
-                                       if (j == first_sack_index)
-                                               first_sack_index = j+1;
-                               }
-
-                       }
-               }
-       }
-
-       /* Use SACK fastpath hint if valid */
-       cached_skb = tp->fastpath_skb_hint;
-       cached_fack_count = tp->fastpath_cnt_hint;
-       if (!cached_skb) {
-               cached_skb = tcp_write_queue_head(sk);
-               cached_fack_count = 0;
-       }
-
        for (i = 0; i < num_sacks; i++) {
-               struct sk_buff *skb;
-               __u32 start_seq = ntohl(sp->start_seq);
-               __u32 end_seq = ntohl(sp->end_seq);
-               int fack_count;
-               int dup_sack = (found_dup_sack && (i == first_sack_index));
-               int next_dup = (found_dup_sack && (i+1 == first_sack_index));
+               int dup_sack = !i && found_dup_sack;
 
-               sp++;
+               sp[used_sacks].start_seq = ntohl(get_unaligned(&sp_wire[i].start_seq));
+               sp[used_sacks].end_seq = ntohl(get_unaligned(&sp_wire[i].end_seq));
 
-               if (!tcp_is_sackblock_valid(tp, dup_sack, start_seq, end_seq)) {
+               if (!tcp_is_sackblock_valid(tp, dup_sack,
+                                           sp[used_sacks].start_seq,
+                                           sp[used_sacks].end_seq)) {
                        if (dup_sack) {
                                if (!tp->undo_marker)
                                        NET_INC_STATS_BH(LINUX_MIB_TCPDSACKIGNOREDNOUNDO);
@@ -1352,169 +1465,148 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                        } else {
                                /* Don't count olds caused by ACK reordering */
                                if ((TCP_SKB_CB(ack_skb)->ack_seq != tp->snd_una) &&
-                                   !after(end_seq, tp->snd_una))
+                                   !after(sp[used_sacks].end_seq, tp->snd_una))
                                        continue;
                                NET_INC_STATS_BH(LINUX_MIB_TCPSACKDISCARD);
                        }
+                       if (i == 0)
+                               first_sack_index = -1;
                        continue;
                }
 
-               skb = cached_skb;
-               fack_count = cached_fack_count;
-
-               /* Event "B" in the comment above. */
-               if (after(end_seq, tp->high_seq))
-                       flag |= FLAG_DATA_LOST;
-
-               tcp_for_write_queue_from(skb, sk) {
-                       int in_sack = 0;
-                       u8 sacked;
-
-                       if (skb == tcp_send_head(sk))
-                               break;
-
-                       cached_skb = skb;
-                       cached_fack_count = fack_count;
-                       if (i == first_sack_index) {
-                               tp->fastpath_skb_hint = skb;
-                               tp->fastpath_cnt_hint = fack_count;
-                       }
+               /* Ignore very old stuff early */
+               if (!after(sp[used_sacks].end_seq, prior_snd_una))
+                       continue;
 
-                       /* The retransmission queue is always in order, so
-                        * we can short-circuit the walk early.
-                        */
-                       if (!before(TCP_SKB_CB(skb)->seq, end_seq))
-                               break;
+               used_sacks++;
+       }
 
-                       dup_sack = (found_dup_sack && (i == first_sack_index));
+       /* order SACK blocks to allow in order walk of the retrans queue */
+       for (i = used_sacks - 1; i > 0; i--) {
+               for (j = 0; j < i; j++) {
+                       if (after(sp[j].start_seq, sp[j + 1].start_seq)) {
+                               struct tcp_sack_block tmp;
 
-                       /* Due to sorting DSACK may reside within this SACK block! */
-                       if (next_dup) {
-                               u32 dup_start = ntohl(sp->start_seq);
-                               u32 dup_end = ntohl(sp->end_seq);
+                               tmp = sp[j];
+                               sp[j] = sp[j + 1];
+                               sp[j + 1] = tmp;
 
-                               if (before(TCP_SKB_CB(skb)->seq, dup_end)) {
-                                       in_sack = tcp_match_skb_to_sack(sk, skb, dup_start, dup_end);
-                                       if (in_sack > 0)
-                                               dup_sack = 1;
-                               }
+                               /* Track where the first SACK block goes to */
+                               if (j == first_sack_index)
+                                       first_sack_index = j + 1;
                        }
+               }
+       }
 
-                       /* DSACK info lost if out-of-mem, try SACK still */
-                       if (in_sack <= 0)
-                               in_sack = tcp_match_skb_to_sack(sk, skb, start_seq, end_seq);
-                       if (unlikely(in_sack < 0))
-                               break;
+       skb = tcp_write_queue_head(sk);
+       fack_count = 0;
+       i = 0;
 
-                       sacked = TCP_SKB_CB(skb)->sacked;
+       if (!tp->sacked_out) {
+               /* It's already past, so skip checking against it */
+               cache = tp->recv_sack_cache + ARRAY_SIZE(tp->recv_sack_cache);
+       } else {
+               cache = tp->recv_sack_cache;
+               /* Skip empty blocks in at head of the cache */
+               while (tcp_sack_cache_ok(tp, cache) && !cache->start_seq &&
+                      !cache->end_seq)
+                       cache++;
+       }
 
-                       /* Account D-SACK for retransmitted packet. */
-                       if ((dup_sack && in_sack) &&
-                           (sacked & TCPCB_RETRANS) &&
-                           after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker))
-                               tp->undo_retrans--;
+       while (i < used_sacks) {
+               u32 start_seq = sp[i].start_seq;
+               u32 end_seq = sp[i].end_seq;
+               int dup_sack = (found_dup_sack && (i == first_sack_index));
+               struct tcp_sack_block *next_dup = NULL;
 
-                       /* The frame is ACKed. */
-                       if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) {
-                               if (sacked&TCPCB_RETRANS) {
-                                       if ((dup_sack && in_sack) &&
-                                           (sacked&TCPCB_SACKED_ACKED))
-                                               reord = min(fack_count, reord);
-                               }
+               if (found_dup_sack && ((i + 1) == first_sack_index))
+                       next_dup = &sp[i + 1];
 
-                               /* Nothing to do; acked frame is about to be dropped. */
-                               fack_count += tcp_skb_pcount(skb);
-                               continue;
-                       }
+               /* Event "B" in the comment above. */
+               if (after(end_seq, tp->high_seq))
+                       flag |= FLAG_DATA_LOST;
 
-                       if (!in_sack) {
-                               fack_count += tcp_skb_pcount(skb);
-                               continue;
+               /* Skip too early cached blocks */
+               while (tcp_sack_cache_ok(tp, cache) &&
+                      !before(start_seq, cache->end_seq))
+                       cache++;
+
+               /* Can skip some work by looking recv_sack_cache? */
+               if (tcp_sack_cache_ok(tp, cache) && !dup_sack &&
+                   after(end_seq, cache->start_seq)) {
+
+                       /* Head todo? */
+                       if (before(start_seq, cache->start_seq)) {
+                               skb = tcp_sacktag_skip(skb, sk, start_seq);
+                               skb = tcp_sacktag_walk(skb, sk, next_dup,
+                                                      start_seq,
+                                                      cache->start_seq,
+                                                      dup_sack, &fack_count,
+                                                      &reord, &flag);
                        }
 
-                       if (!(sacked&TCPCB_SACKED_ACKED)) {
-                               if (sacked & TCPCB_SACKED_RETRANS) {
-                                       /* If the segment is not tagged as lost,
-                                        * we do not clear RETRANS, believing
-                                        * that retransmission is still in flight.
-                                        */
-                                       if (sacked & TCPCB_LOST) {
-                                               TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
-                                               tp->lost_out -= tcp_skb_pcount(skb);
-                                               tp->retrans_out -= tcp_skb_pcount(skb);
-
-                                               /* clear lost hint */
-                                               tp->retransmit_skb_hint = NULL;
-                                       }
-                               } else {
-                                       if (!(sacked & TCPCB_RETRANS)) {
-                                               /* New sack for not retransmitted frame,
-                                                * which was in hole. It is reordering.
-                                                */
-                                               if (fack_count < prior_fackets)
-                                                       reord = min(fack_count, reord);
-
-                                               /* SACK enhanced F-RTO (RFC4138; Appendix B) */
-                                               if (!after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark))
-                                                       flag |= FLAG_ONLY_ORIG_SACKED;
-                                       }
-
-                                       if (sacked & TCPCB_LOST) {
-                                               TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
-                                               tp->lost_out -= tcp_skb_pcount(skb);
+                       /* Rest of the block already fully processed? */
+                       if (!after(end_seq, cache->end_seq))
+                               goto advance_sp;
 
-                                               /* clear lost hint */
-                                               tp->retransmit_skb_hint = NULL;
-                                       }
-                               }
+                       skb = tcp_maybe_skipping_dsack(skb, sk, next_dup,
+                                                      cache->end_seq,
+                                                      &fack_count, &reord,
+                                                      &flag);
 
-                               TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
-                               flag |= FLAG_DATA_SACKED;
-                               tp->sacked_out += tcp_skb_pcount(skb);
-
-                               fack_count += tcp_skb_pcount(skb);
-                               if (fack_count > tp->fackets_out)
-                                       tp->fackets_out = fack_count;
-
-                               if (after(TCP_SKB_CB(skb)->seq, tp->highest_sack)) {
-                                       tp->highest_sack = TCP_SKB_CB(skb)->seq;
-                                       highest_sack_end_seq = TCP_SKB_CB(skb)->end_seq;
-                               }
-                       } else {
-                               if (dup_sack && (sacked&TCPCB_RETRANS))
-                                       reord = min(fack_count, reord);
-
-                               fack_count += tcp_skb_pcount(skb);
+                       /* ...tail remains todo... */
+                       if (tcp_highest_sack_seq(tp) == cache->end_seq) {
+                               /* ...but better entrypoint exists! */
+                               skb = tcp_highest_sack(sk);
+                               if (skb == NULL)
+                                       break;
+                               fack_count = tp->fackets_out;
+                               cache++;
+                               goto walk;
                        }
 
-                       /* D-SACK. We can detect redundant retransmission
-                        * in S|R and plain R frames and clear it.
-                        * undo_retrans is decreased above, L|R frames
-                        * are accounted above as well.
-                        */
-                       if (dup_sack &&
-                           (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) {
-                               TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-                               tp->retrans_out -= tcp_skb_pcount(skb);
-                               tp->retransmit_skb_hint = NULL;
-                       }
+                       skb = tcp_sacktag_skip(skb, sk, cache->end_seq);
+                       /* Check overlap against next cached too (past this one already) */
+                       cache++;
+                       continue;
+               }
+
+               if (!before(start_seq, tcp_highest_sack_seq(tp))) {
+                       skb = tcp_highest_sack(sk);
+                       if (skb == NULL)
+                               break;
+                       fack_count = tp->fackets_out;
                }
+               skb = tcp_sacktag_skip(skb, sk, start_seq);
+
+walk:
+               skb = tcp_sacktag_walk(skb, sk, next_dup, start_seq, end_seq,
+                                      dup_sack, &fack_count, &reord, &flag);
 
+advance_sp:
                /* SACK enhanced FRTO (RFC4138, Appendix B): Clearing correct
                 * due to in-order walk
                 */
                if (after(end_seq, tp->frto_highmark))
                        flag &= ~FLAG_ONLY_ORIG_SACKED;
+
+               i++;
        }
 
-       if (tp->retrans_out &&
-           after(highest_sack_end_seq, tp->lost_retrans_low) &&
-           icsk->icsk_ca_state == TCP_CA_Recovery)
-               flag |= tcp_mark_lost_retrans(sk, highest_sack_end_seq);
+       /* Clear the head of the cache sack blocks so we can skip it next time */
+       for (i = 0; i < ARRAY_SIZE(tp->recv_sack_cache) - used_sacks; i++) {
+               tp->recv_sack_cache[i].start_seq = 0;
+               tp->recv_sack_cache[i].end_seq = 0;
+       }
+       for (j = 0; j < used_sacks; j++)
+               tp->recv_sack_cache[i++] = sp[j];
+
+       tcp_mark_lost_retrans(sk);
 
        tcp_verify_left_out(tp);
 
-       if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss &&
+       if ((reord < tp->fackets_out) &&
+           ((icsk->icsk_ca_state != TCP_CA_Loss) || tp->undo_marker) &&
            (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark)))
                tcp_update_reordering(sk, tp->fackets_out - reord, 0);
 
@@ -1565,10 +1657,10 @@ static void tcp_remove_reno_sacks(struct sock *sk, int acked)
 
        if (acked > 0) {
                /* One ACK acked hole. The rest eat duplicate ACKs. */
-               if (acked-1 >= tp->sacked_out)
+               if (acked - 1 >= tp->sacked_out)
                        tp->sacked_out = 0;
                else
-                       tp->sacked_out -= acked-1;
+                       tp->sacked_out -= acked - 1;
        }
        tcp_check_reno_reordering(sk, acked);
        tcp_verify_left_out(tp);
@@ -1602,10 +1694,10 @@ int tcp_use_frto(struct sock *sk)
        tcp_for_write_queue_from(skb, sk) {
                if (skb == tcp_send_head(sk))
                        break;
-               if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS)
+               if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
                        return 0;
                /* Short-circuit when first non-SACKed skb has been checked */
-               if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED))
+               if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                        break;
        }
        return 1;
@@ -1715,7 +1807,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
                 * Count the retransmission made on RTO correctly (only when
                 * waiting for the first ACK and did not get it)...
                 */
-               if ((tp->frto_counter == 1) && !(flag&FLAG_DATA_ACKED)) {
+               if ((tp->frto_counter == 1) && !(flag & FLAG_DATA_ACKED)) {
                        /* For some reason this R-bit might get cleared? */
                        if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)
                                tp->retrans_out += tcp_skb_pcount(skb);
@@ -1728,7 +1820,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
                }
 
                /* Don't lost mark skbs that were fwd transmitted after RTO */
-               if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) &&
+               if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED) &&
                    !after(TCP_SKB_CB(skb)->end_seq, tp->frto_highmark)) {
                        TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
                        tp->lost_out += tcp_skb_pcount(skb);
@@ -1743,7 +1835,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
        tp->bytes_acked = 0;
 
        tp->reordering = min_t(unsigned int, tp->reordering,
-                                            sysctl_tcp_reordering);
+                              sysctl_tcp_reordering);
        tcp_set_ca_state(sk, TCP_CA_Loss);
        tp->high_seq = tp->frto_highmark;
        TCP_ECN_queue_cwr(tp);
@@ -1810,7 +1902,7 @@ void tcp_enter_loss(struct sock *sk, int how)
                if (skb == tcp_send_head(sk))
                        break;
 
-               if (TCP_SKB_CB(skb)->sacked&TCPCB_RETRANS)
+               if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS)
                        tp->undo_marker = 0;
                TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED;
                if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) {
@@ -1822,7 +1914,7 @@ void tcp_enter_loss(struct sock *sk, int how)
        tcp_verify_left_out(tp);
 
        tp->reordering = min_t(unsigned int, tp->reordering,
-                                            sysctl_tcp_reordering);
+                              sysctl_tcp_reordering);
        tcp_set_ca_state(sk, TCP_CA_Loss);
        tp->high_seq = tp->snd_nxt;
        TCP_ECN_queue_cwr(tp);
@@ -1830,18 +1922,15 @@ void tcp_enter_loss(struct sock *sk, int how)
        tp->frto_counter = 0;
 }
 
-static int tcp_check_sack_reneging(struct sock *sk)
+/* If ACK arrived pointing to a remembered SACK, it means that our
+ * remembered SACKs do not reflect real state of receiver i.e.
+ * receiver _host_ is heavily congested (or buggy).
+ *
+ * Do processing similar to RTO timeout.
+ */
+static int tcp_check_sack_reneging(struct sock *sk, int flag)
 {
-       struct sk_buff *skb;
-
-       /* If ACK arrived pointing to a remembered SACK,
-        * it means that our remembered SACKs do not reflect
-        * real state of receiver i.e.
-        * receiver _host_ is heavily congested (or buggy).
-        * Do processing similar to RTO timeout.
-        */
-       if ((skb = tcp_write_queue_head(sk)) != NULL &&
-           (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
+       if (flag & FLAG_SACK_RENEGING) {
                struct inet_connection_sock *icsk = inet_csk(sk);
                NET_INC_STATS_BH(LINUX_MIB_TCPSACKRENEGING);
 
@@ -1857,7 +1946,27 @@ static int tcp_check_sack_reneging(struct sock *sk)
 
 static inline int tcp_fackets_out(struct tcp_sock *tp)
 {
-       return tcp_is_reno(tp) ? tp->sacked_out+1 : tp->fackets_out;
+       return tcp_is_reno(tp) ? tp->sacked_out + 1 : tp->fackets_out;
+}
+
+/* Heurestics to calculate number of duplicate ACKs. There's no dupACKs
+ * counter when SACK is enabled (without SACK, sacked_out is used for
+ * that purpose).
+ *
+ * Instead, with FACK TCP uses fackets_out that includes both SACKed
+ * segments up to the highest received SACK block so far and holes in
+ * between them.
+ *
+ * With reordering, holes may still be in flight, so RFC3517 recovery
+ * uses pure sacked_out (total number of SACKed segments) even though
+ * it violates the RFC that uses duplicate ACKs, often these are equal
+ * but when e.g. out-of-window ACKs or packet duplication occurs,
+ * they differ. Since neither occurs due to loss, TCP should really
+ * ignore them.
+ */
+static inline int tcp_dupack_heurestics(struct tcp_sock *tp)
+{
+       return tcp_is_fack(tp) ? tp->fackets_out : tp->sacked_out + 1;
 }
 
 static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb)
@@ -1980,13 +2089,13 @@ static int tcp_time_to_recover(struct sock *sk)
                return 1;
 
        /* Not-A-Trick#2 : Classic rule... */
-       if (tcp_fackets_out(tp) > tp->reordering)
+       if (tcp_dupack_heurestics(tp) > tp->reordering)
                return 1;
 
        /* Trick#3 : when we use RFC2988 timer restart, fast
         * retransmit can be triggered by timeout of queue head.
         */
-       if (tcp_head_timedout(sk))
+       if (tcp_is_fack(tp) && tcp_head_timedout(sk))
                return 1;
 
        /* Trick#4: It is still not OK... But will it be useful to delay
@@ -2010,17 +2119,18 @@ static int tcp_time_to_recover(struct sock *sk)
  * retransmitted past LOST markings in the first place? I'm not fully sure
  * about undo and end of connection cases, which can cause R without L?
  */
-static void tcp_verify_retransmit_hint(struct tcp_sock *tp,
-                                      struct sk_buff *skb)
+static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
 {
        if ((tp->retransmit_skb_hint != NULL) &&
            before(TCP_SKB_CB(skb)->seq,
-           TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
+                  TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
                tp->retransmit_skb_hint = NULL;
 }
 
-/* Mark head of queue up as lost. */
-static void tcp_mark_head_lost(struct sock *sk, int packets)
+/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
+ * is against sacked "cnt", otherwise it's against facked "cnt"
+ */
+static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
@@ -2042,8 +2152,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
                /* this is not the most efficient way to do this... */
                tp->lost_skb_hint = skb;
                tp->lost_cnt_hint = cnt;
-               cnt += tcp_skb_pcount(skb);
-               if (cnt > packets || after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
+
+               if (tcp_is_fack(tp) ||
+                   (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
+                       cnt += tcp_skb_pcount(skb);
+
+               if (((!fast_rexmit || (tp->lost_out > 0)) && (cnt > packets)) ||
+                   after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
                        break;
                if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_SACKED_ACKED|TCPCB_LOST))) {
                        TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
@@ -2056,17 +2171,22 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
 
 /* Account newly detected lost packet(s) */
 
-static void tcp_update_scoreboard(struct sock *sk)
+static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
-       if (tcp_is_fack(tp)) {
+       if (tcp_is_reno(tp)) {
+               tcp_mark_head_lost(sk, 1, fast_rexmit);
+       } else if (tcp_is_fack(tp)) {
                int lost = tp->fackets_out - tp->reordering;
                if (lost <= 0)
                        lost = 1;
-               tcp_mark_head_lost(sk, lost);
+               tcp_mark_head_lost(sk, lost, fast_rexmit);
        } else {
-               tcp_mark_head_lost(sk, 1);
+               int sacked_upto = tp->sacked_out - tp->reordering;
+               if (sacked_upto < 0)
+                       sacked_upto = 0;
+               tcp_mark_head_lost(sk, sacked_upto, fast_rexmit);
        }
 
        /* New heuristics: it is possible only after we switched
@@ -2074,7 +2194,7 @@ static void tcp_update_scoreboard(struct sock *sk)
         * Hence, we can detect timed out packets during fast
         * retransmit without falling to slow start.
         */
-       if (!tcp_is_reno(tp) && tcp_head_timedout(sk)) {
+       if (tcp_is_fack(tp) && tcp_head_timedout(sk)) {
                struct sk_buff *skb;
 
                skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint
@@ -2105,7 +2225,7 @@ static void tcp_update_scoreboard(struct sock *sk)
 static inline void tcp_moderate_cwnd(struct tcp_sock *tp)
 {
        tp->snd_cwnd = min(tp->snd_cwnd,
-                          tcp_packets_in_flight(tp)+tcp_max_burst(tp));
+                          tcp_packets_in_flight(tp) + tcp_max_burst(tp));
        tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -2125,15 +2245,15 @@ static void tcp_cwnd_down(struct sock *sk, int flag)
        struct tcp_sock *tp = tcp_sk(sk);
        int decr = tp->snd_cwnd_cnt + 1;
 
-       if ((flag&(FLAG_ANY_PROGRESS|FLAG_DSACKING_ACK)) ||
-           (tcp_is_reno(tp) && !(flag&FLAG_NOT_DUP))) {
-               tp->snd_cwnd_cnt = decr&1;
+       if ((flag & (FLAG_ANY_PROGRESS | FLAG_DSACKING_ACK)) ||
+           (tcp_is_reno(tp) && !(flag & FLAG_NOT_DUP))) {
+               tp->snd_cwnd_cnt = decr & 1;
                decr >>= 1;
 
                if (decr && tp->snd_cwnd > tcp_cwnd_min(sk))
                        tp->snd_cwnd -= decr;
 
-               tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp)+1);
+               tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp) + 1);
                tp->snd_cwnd_stamp = tcp_time_stamp;
        }
 }
@@ -2177,7 +2297,7 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
                if (icsk->icsk_ca_ops->undo_cwnd)
                        tp->snd_cwnd = icsk->icsk_ca_ops->undo_cwnd(sk);
                else
-                       tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh<<1);
+                       tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh << 1);
 
                if (undo && tp->prior_ssthresh > tp->snd_ssthresh) {
                        tp->snd_ssthresh = tp->prior_ssthresh;
@@ -2196,8 +2316,7 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
 
 static inline int tcp_may_undo(struct tcp_sock *tp)
 {
-       return tp->undo_marker &&
-               (!tp->undo_retrans || tcp_packet_delayed(tp));
+       return tp->undo_marker && (!tp->undo_retrans || tcp_packet_delayed(tp));
 }
 
 /* People celebrate: "We love our President!" */
@@ -2247,7 +2366,7 @@ static int tcp_try_undo_partial(struct sock *sk, int acked)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        /* Partial ACK arrived. Force Hoe's retransmit. */
-       int failed = tcp_is_reno(tp) || tp->fackets_out>tp->reordering;
+       int failed = tcp_is_reno(tp) || (tcp_fackets_out(tp) > tp->reordering);
 
        if (tcp_may_undo(tp)) {
                /* Plain luck! Hole if filled with delayed
@@ -2316,7 +2435,7 @@ static void tcp_try_to_open(struct sock *sk, int flag)
        if (tp->retrans_out == 0)
                tp->retrans_stamp = 0;
 
-       if (flag&FLAG_ECE)
+       if (flag & FLAG_ECE)
                tcp_enter_cwr(sk, 1);
 
        if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) {
@@ -2362,7 +2481,6 @@ static void tcp_mtup_probe_success(struct sock *sk, struct sk_buff *skb)
        tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 }
 
-
 /* Process an event, which can update packets-in-flight not trivially.
  * Main goal of this function is to calculate new estimate for left_out,
  * taking into account both packets sitting in receiver's buffer and
@@ -2374,38 +2492,35 @@ static void tcp_mtup_probe_success(struct sock *sk, struct sk_buff *skb)
  * It does _not_ decide what to send, it is made in function
  * tcp_xmit_retransmit_queue().
  */
-static void
-tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
+static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct tcp_sock *tp = tcp_sk(sk);
-       int is_dupack = !(flag&(FLAG_SND_UNA_ADVANCED|FLAG_NOT_DUP));
-       int do_lost = is_dupack || ((flag&FLAG_DATA_SACKED) &&
-                                   (tp->fackets_out > tp->reordering));
+       int is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
+       int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) &&
+                                   (tcp_fackets_out(tp) > tp->reordering));
+       int fast_rexmit = 0;
 
-       /* Some technical things:
-        * 1. Reno does not count dupacks (sacked_out) automatically. */
-       if (!tp->packets_out)
+       if (WARN_ON(!tp->packets_out && tp->sacked_out))
                tp->sacked_out = 0;
-
        if (WARN_ON(!tp->sacked_out && tp->fackets_out))
                tp->fackets_out = 0;
 
        /* Now state machine starts.
         * A. ECE, hence prohibit cwnd undoing, the reduction is required. */
-       if (flag&FLAG_ECE)
+       if (flag & FLAG_ECE)
                tp->prior_ssthresh = 0;
 
        /* B. In all the states check for reneging SACKs. */
-       if (tp->sacked_out && tcp_check_sack_reneging(sk))
+       if (tcp_check_sack_reneging(sk, flag))
                return;
 
        /* C. Process data loss notification, provided it is valid. */
-       if ((flag&FLAG_DATA_LOST) &&
+       if (tcp_is_fack(tp) && (flag & FLAG_DATA_LOST) &&
            before(tp->snd_una, tp->high_seq) &&
            icsk->icsk_ca_state != TCP_CA_Open &&
            tp->fackets_out > tp->reordering) {
-               tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering);
+               tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
                NET_INC_STATS_BH(LINUX_MIB_TCPLOSS);
        }
 
@@ -2465,7 +2580,7 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
                        do_lost = tcp_try_undo_partial(sk, pkts_acked);
                break;
        case TCP_CA_Loss:
-               if (flag&FLAG_DATA_ACKED)
+               if (flag & FLAG_DATA_ACKED)
                        icsk->icsk_retransmits = 0;
                if (!tcp_try_undo_loss(sk)) {
                        tcp_moderate_cwnd(tp);
@@ -2515,7 +2630,7 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
                tp->undo_retrans = tp->retrans_out;
 
                if (icsk->icsk_ca_state < TCP_CA_CWR) {
-                       if (!(flag&FLAG_ECE))
+                       if (!(flag & FLAG_ECE))
                                tp->prior_ssthresh = tcp_current_ssthresh(sk);
                        tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
                        TCP_ECN_queue_cwr(tp);
@@ -2524,10 +2639,11 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
                tp->bytes_acked = 0;
                tp->snd_cwnd_cnt = 0;
                tcp_set_ca_state(sk, TCP_CA_Recovery);
+               fast_rexmit = 1;
        }
 
-       if (do_lost || tcp_head_timedout(sk))
-               tcp_update_scoreboard(sk);
+       if (do_lost || (tcp_is_fack(tp) && tcp_head_timedout(sk)))
+               tcp_update_scoreboard(sk, fast_rexmit);
        tcp_cwnd_down(sk, flag);
        tcp_xmit_retransmit_queue(sk);
 }
@@ -2591,11 +2707,10 @@ static inline void tcp_ack_update_rtt(struct sock *sk, const int flag,
                tcp_ack_no_tstamp(sk, seq_rtt, flag);
 }
 
-static void tcp_cong_avoid(struct sock *sk, u32 ack,
-                          u32 in_flight, int good)
+static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
-       icsk->icsk_ca_ops->cong_avoid(sk, ack, in_flight, good);
+       icsk->icsk_ca_ops->cong_avoid(sk, ack, in_flight);
        tcp_sk(sk)->snd_cwnd_stamp = tcp_time_stamp;
 }
 
@@ -2609,7 +2724,8 @@ static void tcp_rearm_rto(struct sock *sk)
        if (!tp->packets_out) {
                inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
        } else {
-               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
+               inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
+                                         inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
        }
 }
 
@@ -2638,8 +2754,7 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
  * is before the ack sequence we can discard it as it's confirmed to have
  * arrived at the other end.
  */
-static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
-                              int prior_fackets)
+static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2647,8 +2762,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
        u32 now = tcp_time_stamp;
        int fully_acked = 1;
        int flag = 0;
-       int prior_packets = tp->packets_out;
-       u32 cnt = 0;
+       u32 pkts_acked = 0;
        u32 reord = tp->packets_out;
        s32 seq_rtt = -1;
        s32 ca_seq_rtt = -1;
@@ -2657,7 +2771,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
        while ((skb = tcp_write_queue_head(sk)) && skb != tcp_send_head(sk)) {
                struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
                u32 end_seq;
-               u32 packets_acked;
+               u32 acked_pcount;
                u8 sacked = scb->sacked;
 
                /* Determine how many packets and what bytes were acked, tso and else */
@@ -2666,14 +2780,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
                            !after(tp->snd_una, scb->seq))
                                break;
 
-                       packets_acked = tcp_tso_acked(sk, skb);
-                       if (!packets_acked)
+                       acked_pcount = tcp_tso_acked(sk, skb);
+                       if (!acked_pcount)
                                break;
 
                        fully_acked = 0;
                        end_seq = tp->snd_una;
                } else {
-                       packets_acked = tcp_skb_pcount(skb);
+                       acked_pcount = tcp_skb_pcount(skb);
                        end_seq = scb->end_seq;
                }
 
@@ -2683,44 +2797,34 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
                        tcp_mtup_probe_success(sk, skb);
                }
 
-               if (sacked) {
-                       if (sacked & TCPCB_RETRANS) {
-                               if (sacked & TCPCB_SACKED_RETRANS)
-                                       tp->retrans_out -= packets_acked;
-                               flag |= FLAG_RETRANS_DATA_ACKED;
-                               ca_seq_rtt = -1;
-                               seq_rtt = -1;
-                               if ((flag & FLAG_DATA_ACKED) ||
-                                   (packets_acked > 1))
-                                       flag |= FLAG_NONHEAD_RETRANS_ACKED;
-                       } else {
-                               ca_seq_rtt = now - scb->when;
-                               last_ackt = skb->tstamp;
-                               if (seq_rtt < 0) {
-                                       seq_rtt = ca_seq_rtt;
-                               }
-                               if (!(sacked & TCPCB_SACKED_ACKED))
-                                       reord = min(cnt, reord);
-                       }
-
-                       if (sacked & TCPCB_SACKED_ACKED)
-                               tp->sacked_out -= packets_acked;
-                       if (sacked & TCPCB_LOST)
-                               tp->lost_out -= packets_acked;
-
-                       if ((sacked & TCPCB_URG) && tp->urg_mode &&
-                           !before(end_seq, tp->snd_up))
-                               tp->urg_mode = 0;
+               if (sacked & TCPCB_RETRANS) {
+                       if (sacked & TCPCB_SACKED_RETRANS)
+                               tp->retrans_out -= acked_pcount;
+                       flag |= FLAG_RETRANS_DATA_ACKED;
+                       ca_seq_rtt = -1;
+                       seq_rtt = -1;
+                       if ((flag & FLAG_DATA_ACKED) || (acked_pcount > 1))
+                               flag |= FLAG_NONHEAD_RETRANS_ACKED;
                } else {
                        ca_seq_rtt = now - scb->when;
                        last_ackt = skb->tstamp;
                        if (seq_rtt < 0) {
                                seq_rtt = ca_seq_rtt;
                        }
-                       reord = min(cnt, reord);
+                       if (!(sacked & TCPCB_SACKED_ACKED))
+                               reord = min(pkts_acked, reord);
                }
-               tp->packets_out -= packets_acked;
-               cnt += packets_acked;
+
+               if (sacked & TCPCB_SACKED_ACKED)
+                       tp->sacked_out -= acked_pcount;
+               if (sacked & TCPCB_LOST)
+                       tp->lost_out -= acked_pcount;
+
+               if (unlikely(tp->urg_mode && !before(end_seq, tp->snd_up)))
+                       tp->urg_mode = 0;
+
+               tp->packets_out -= acked_pcount;
+               pkts_acked += acked_pcount;
 
                /* Initial outgoing SYN's get put onto the write_queue
                 * just like anything else we transmit.  It is not
@@ -2740,12 +2844,14 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
                        break;
 
                tcp_unlink_write_queue(skb, sk);
-               sk_stream_free_skb(sk, skb);
+               sk_wmem_free_skb(sk, skb);
                tcp_clear_all_retrans_hints(tp);
        }
 
+       if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
+               flag |= FLAG_SACK_RENEGING;
+
        if (flag & FLAG_ACKED) {
-               u32 pkts_acked = prior_packets - tp->packets_out;
                const struct tcp_congestion_ops *ca_ops
                        = inet_csk(sk)->icsk_ca_ops;
 
@@ -2761,9 +2867,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
                }
 
                tp->fackets_out -= min(pkts_acked, tp->fackets_out);
-               /* hint's skb might be NULL but we don't need to care */
-               tp->fastpath_cnt_hint -= min_t(u32, pkts_acked,
-                                              tp->fastpath_cnt_hint);
+
                if (ca_ops->pkts_acked) {
                        s32 rtt_us = -1;
 
@@ -2806,7 +2910,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, s32 *seq_rtt_p,
                }
        }
 #endif
-       *seq_rtt_p = seq_rtt;
        return flag;
 }
 
@@ -2817,8 +2920,7 @@ static void tcp_ack_probe(struct sock *sk)
 
        /* Was it a usable window open? */
 
-       if (!after(TCP_SKB_CB(tcp_send_head(sk))->end_seq,
-                  tp->snd_una + tp->snd_wnd)) {
+       if (!after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, tcp_wnd_end(tp))) {
                icsk->icsk_backoff = 0;
                inet_csk_clear_xmit_timer(sk, ICSK_TIME_PROBE0);
                /* Socket must be waked up by subsequent tcp_data_snd_check().
@@ -2847,8 +2949,9 @@ static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag)
 /* Check that window update is acceptable.
  * The function assumes that snd_una<=ack<=snd_next.
  */
-static inline int tcp_may_update_window(const struct tcp_sock *tp, const u32 ack,
-                                       const u32 ack_seq, const u32 nwin)
+static inline int tcp_may_update_window(const struct tcp_sock *tp,
+                                       const u32 ack, const u32 ack_seq,
+                                       const u32 nwin)
 {
        return (after(ack, tp->snd_una) ||
                after(ack_seq, tp->snd_wl1) ||
@@ -2917,7 +3020,7 @@ static void tcp_ratehalving_spur_to_response(struct sock *sk)
 
 static void tcp_undo_spur_to_response(struct sock *sk, int flag)
 {
-       if (flag&FLAG_ECE)
+       if (flag & FLAG_ECE)
                tcp_ratehalving_spur_to_response(sk);
        else
                tcp_undo_cwr(sk, 1);
@@ -2960,7 +3063,7 @@ static int tcp_process_frto(struct sock *sk, int flag)
        tcp_verify_left_out(tp);
 
        /* Duplicate the behavior from Loss state (fastretrans_alert) */
-       if (flag&FLAG_DATA_ACKED)
+       if (flag & FLAG_DATA_ACKED)
                inet_csk(sk)->icsk_retransmits = 0;
 
        if ((flag & FLAG_NONHEAD_RETRANS_ACKED) ||
@@ -2977,16 +3080,16 @@ static int tcp_process_frto(struct sock *sk, int flag)
                 * ACK isn't duplicate nor advances window, e.g., opposite dir
                 * data, winupdate
                 */
-               if (!(flag&FLAG_ANY_PROGRESS) && (flag&FLAG_NOT_DUP))
+               if (!(flag & FLAG_ANY_PROGRESS) && (flag & FLAG_NOT_DUP))
                        return 1;
 
-               if (!(flag&FLAG_DATA_ACKED)) {
+               if (!(flag & FLAG_DATA_ACKED)) {
                        tcp_enter_frto_loss(sk, (tp->frto_counter == 1 ? 0 : 3),
                                            flag);
                        return 1;
                }
        } else {
-               if (!(flag&FLAG_DATA_ACKED) && (tp->frto_counter == 1)) {
+               if (!(flag & FLAG_DATA_ACKED) && (tp->frto_counter == 1)) {
                        /* Prevent sending of new data. */
                        tp->snd_cwnd = min(tp->snd_cwnd,
                                           tcp_packets_in_flight(tp));
@@ -2994,10 +3097,12 @@ static int tcp_process_frto(struct sock *sk, int flag)
                }
 
                if ((tp->frto_counter >= 2) &&
-                   (!(flag&FLAG_FORWARD_PROGRESS) ||
-                    ((flag&FLAG_DATA_SACKED) && !(flag&FLAG_ONLY_ORIG_SACKED)))) {
+                   (!(flag & FLAG_FORWARD_PROGRESS) ||
+                    ((flag & FLAG_DATA_SACKED) &&
+                     !(flag & FLAG_ONLY_ORIG_SACKED)))) {
                        /* RFC4138 shortcoming (see comment above) */
-                       if (!(flag&FLAG_FORWARD_PROGRESS) && (flag&FLAG_NOT_DUP))
+                       if (!(flag & FLAG_FORWARD_PROGRESS) &&
+                           (flag & FLAG_NOT_DUP))
                                return 1;
 
                        tcp_enter_frto_loss(sk, 3, flag);
@@ -3043,7 +3148,6 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
        u32 ack = TCP_SKB_CB(skb)->ack_seq;
        u32 prior_in_flight;
        u32 prior_fackets;
-       s32 seq_rtt;
        int prior_packets;
        int frto_cwnd = 0;
 
@@ -3064,13 +3168,14 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
                        tp->bytes_acked += ack - prior_snd_una;
                else if (icsk->icsk_ca_state == TCP_CA_Loss)
                        /* we assume just one segment left network */
-                       tp->bytes_acked += min(ack - prior_snd_una, tp->mss_cache);
+                       tp->bytes_acked += min(ack - prior_snd_una,
+                                              tp->mss_cache);
        }
 
        prior_fackets = tp->fackets_out;
        prior_in_flight = tcp_packets_in_flight(tp);
 
-       if (!(flag&FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
+       if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
                /* Window is constant, pure forward advance.
                 * No more checks are required.
                 * Note, we use the fact that SND.UNA>=SND.WL2.
@@ -3109,7 +3214,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
                goto no_queue;
 
        /* See if we can take anything off of the retransmit queue. */
-       flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets);
+       flag |= tcp_clean_rtx_queue(sk, prior_fackets);
 
        if (tp->frto_counter)
                frto_cwnd = tcp_process_frto(sk, flag);
@@ -3121,14 +3226,15 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
                /* Advance CWND, if state allows this. */
                if ((flag & FLAG_DATA_ACKED) && !frto_cwnd &&
                    tcp_may_raise_cwnd(sk, flag))
-                       tcp_cong_avoid(sk, ack, prior_in_flight, 0);
-               tcp_fastretrans_alert(sk, prior_packets - tp->packets_out, flag);
+                       tcp_cong_avoid(sk, ack, prior_in_flight);
+               tcp_fastretrans_alert(sk, prior_packets - tp->packets_out,
+                                     flag);
        } else {
                if ((flag & FLAG_DATA_ACKED) && !frto_cwnd)
-                       tcp_cong_avoid(sk, ack, prior_in_flight, 1);
+                       tcp_cong_avoid(sk, ack, prior_in_flight);
        }
 
-       if ((flag & FLAG_FORWARD_PROGRESS) || !(flag&FLAG_NOT_DUP))
+       if ((flag & FLAG_FORWARD_PROGRESS) || !(flag & FLAG_NOT_DUP))
                dst_confirm(sk->sk_dst_cache);
 
        return 1;
@@ -3153,100 +3259,99 @@ uninteresting_ack:
        return 0;
 }
 
-
 /* Look for tcp options. Normally only called on SYN and SYNACK packets.
  * But, this can also be called on packets in the established flow when
  * the fast version below fails.
  */
-void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, int estab)
+void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
+                      int estab)
 {
        unsigned char *ptr;
        struct tcphdr *th = tcp_hdr(skb);
-       int length=(th->doff*4)-sizeof(struct tcphdr);
+       int length = (th->doff * 4) - sizeof(struct tcphdr);
 
        ptr = (unsigned char *)(th + 1);
        opt_rx->saw_tstamp = 0;
 
        while (length > 0) {
-               int opcode=*ptr++;
+               int opcode = *ptr++;
                int opsize;
 
                switch (opcode) {
-                       case TCPOPT_EOL:
+               case TCPOPT_EOL:
+                       return;
+               case TCPOPT_NOP:        /* Ref: RFC 793 section 3.1 */
+                       length--;
+                       continue;
+               default:
+                       opsize = *ptr++;
+                       if (opsize < 2) /* "silly options" */
                                return;
-                       case TCPOPT_NOP:        /* Ref: RFC 793 section 3.1 */
-                               length--;
-                               continue;
-                       default:
-                               opsize=*ptr++;
-                               if (opsize < 2) /* "silly options" */
-                                       return;
-                               if (opsize > length)
-                                       return; /* don't parse partial options */
-                               switch (opcode) {
-                               case TCPOPT_MSS:
-                                       if (opsize==TCPOLEN_MSS && th->syn && !estab) {
-                                               u16 in_mss = ntohs(get_unaligned((__be16 *)ptr));
-                                               if (in_mss) {
-                                                       if (opt_rx->user_mss && opt_rx->user_mss < in_mss)
-                                                               in_mss = opt_rx->user_mss;
-                                                       opt_rx->mss_clamp = in_mss;
-                                               }
-                                       }
-                                       break;
-                               case TCPOPT_WINDOW:
-                                       if (opsize==TCPOLEN_WINDOW && th->syn && !estab)
-                                               if (sysctl_tcp_window_scaling) {
-                                                       __u8 snd_wscale = *(__u8 *) ptr;
-                                                       opt_rx->wscale_ok = 1;
-                                                       if (snd_wscale > 14) {
-                                                               if (net_ratelimit())
-                                                                       printk(KERN_INFO "tcp_parse_options: Illegal window "
-                                                                              "scaling value %d >14 received.\n",
-                                                                              snd_wscale);
-                                                               snd_wscale = 14;
-                                                       }
-                                                       opt_rx->snd_wscale = snd_wscale;
-                                               }
-                                       break;
-                               case TCPOPT_TIMESTAMP:
-                                       if (opsize==TCPOLEN_TIMESTAMP) {
-                                               if ((estab && opt_rx->tstamp_ok) ||
-                                                   (!estab && sysctl_tcp_timestamps)) {
-                                                       opt_rx->saw_tstamp = 1;
-                                                       opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
-                                                       opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
-                                               }
+                       if (opsize > length)
+                               return; /* don't parse partial options */
+                       switch (opcode) {
+                       case TCPOPT_MSS:
+                               if (opsize == TCPOLEN_MSS && th->syn && !estab) {
+                                       u16 in_mss = ntohs(get_unaligned((__be16 *)ptr));
+                                       if (in_mss) {
+                                               if (opt_rx->user_mss &&
+                                                   opt_rx->user_mss < in_mss)
+                                                       in_mss = opt_rx->user_mss;
+                                               opt_rx->mss_clamp = in_mss;
                                        }
-                                       break;
-                               case TCPOPT_SACK_PERM:
-                                       if (opsize==TCPOLEN_SACK_PERM && th->syn && !estab) {
-                                               if (sysctl_tcp_sack) {
-                                                       opt_rx->sack_ok = 1;
-                                                       tcp_sack_reset(opt_rx);
-                                               }
+                               }
+                               break;
+                       case TCPOPT_WINDOW:
+                               if (opsize == TCPOLEN_WINDOW && th->syn &&
+                                   !estab && sysctl_tcp_window_scaling) {
+                                       __u8 snd_wscale = *(__u8 *)ptr;
+                                       opt_rx->wscale_ok = 1;
+                                       if (snd_wscale > 14) {
+                                               if (net_ratelimit())
+                                                       printk(KERN_INFO "tcp_parse_options: Illegal window "
+                                                              "scaling value %d >14 received.\n",
+                                                              snd_wscale);
+                                               snd_wscale = 14;
                                        }
-                                       break;
+                                       opt_rx->snd_wscale = snd_wscale;
+                               }
+                               break;
+                       case TCPOPT_TIMESTAMP:
+                               if ((opsize == TCPOLEN_TIMESTAMP) &&
+                                   ((estab && opt_rx->tstamp_ok) ||
+                                    (!estab && sysctl_tcp_timestamps))) {
+                                       opt_rx->saw_tstamp = 1;
+                                       opt_rx->rcv_tsval = ntohl(get_unaligned((__be32 *)ptr));
+                                       opt_rx->rcv_tsecr = ntohl(get_unaligned((__be32 *)(ptr+4)));
+                               }
+                               break;
+                       case TCPOPT_SACK_PERM:
+                               if (opsize == TCPOLEN_SACK_PERM && th->syn &&
+                                   !estab && sysctl_tcp_sack) {
+                                       opt_rx->sack_ok = 1;
+                                       tcp_sack_reset(opt_rx);
+                               }
+                               break;
 
-                               case TCPOPT_SACK:
-                                       if ((opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK)) &&
-                                          !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK) &&
-                                          opt_rx->sack_ok) {
-                                               TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th;
-                                       }
-                                       break;
+                       case TCPOPT_SACK:
+                               if ((opsize >= (TCPOLEN_SACK_BASE + TCPOLEN_SACK_PERBLOCK)) &&
+                                  !((opsize - TCPOLEN_SACK_BASE) % TCPOLEN_SACK_PERBLOCK) &&
+                                  opt_rx->sack_ok) {
+                                       TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th;
+                               }
+                               break;
 #ifdef CONFIG_TCP_MD5SIG
-                               case TCPOPT_MD5SIG:
-                                       /*
-                                        * The MD5 Hash has already been
-                                        * checked (see tcp_v{4,6}_do_rcv()).
-                                        */
-                                       break;
+                       case TCPOPT_MD5SIG:
+                               /*
+                                * The MD5 Hash has already been
+                                * checked (see tcp_v{4,6}_do_rcv()).
+                                */
+                               break;
 #endif
-                               }
+                       }
 
-                               ptr+=opsize-2;
-                               length-=opsize;
+                       ptr += opsize-2;
+                       length -= opsize;
                }
        }
 }
@@ -3257,7 +3362,7 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
 static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
                                  struct tcp_sock *tp)
 {
-       if (th->doff == sizeof(struct tcphdr)>>2) {
+       if (th->doff == sizeof(struct tcphdr) >> 2) {
                tp->rx_opt.saw_tstamp = 0;
                return 0;
        } else if (tp->rx_opt.tstamp_ok &&
@@ -3342,7 +3447,8 @@ static int tcp_disordered_ack(const struct sock *sk, const struct sk_buff *skb)
                (s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) <= (inet_csk(sk)->icsk_rto * 1024) / HZ);
 }
 
-static inline int tcp_paws_discard(const struct sock *sk, const struct sk_buff *skb)
+static inline int tcp_paws_discard(const struct sock *sk,
+                                  const struct sk_buff *skb)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
        return ((s32)(tp->rx_opt.ts_recent - tp->rx_opt.rcv_tsval) > TCP_PAWS_WINDOW &&
@@ -3374,16 +3480,16 @@ static void tcp_reset(struct sock *sk)
 {
        /* We want the right error as BSD sees it (and indeed as we do). */
        switch (sk->sk_state) {
-               case TCP_SYN_SENT:
-                       sk->sk_err = ECONNREFUSED;
-                       break;
-               case TCP_CLOSE_WAIT:
-                       sk->sk_err = EPIPE;
-                       break;
-               case TCP_CLOSE:
-                       return;
-               default:
-                       sk->sk_err = ECONNRESET;
+       case TCP_SYN_SENT:
+               sk->sk_err = ECONNREFUSED;
+               break;
+       case TCP_CLOSE_WAIT:
+               sk->sk_err = EPIPE;
+               break;
+       case TCP_CLOSE:
+               return;
+       default:
+               sk->sk_err = ECONNRESET;
        }
 
        if (!sock_flag(sk, SOCK_DEAD))
@@ -3416,43 +3522,43 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
        sock_set_flag(sk, SOCK_DONE);
 
        switch (sk->sk_state) {
-               case TCP_SYN_RECV:
-               case TCP_ESTABLISHED:
-                       /* Move to CLOSE_WAIT */
-                       tcp_set_state(sk, TCP_CLOSE_WAIT);
-                       inet_csk(sk)->icsk_ack.pingpong = 1;
-                       break;
+       case TCP_SYN_RECV:
+       case TCP_ESTABLISHED:
+               /* Move to CLOSE_WAIT */
+               tcp_set_state(sk, TCP_CLOSE_WAIT);
+               inet_csk(sk)->icsk_ack.pingpong = 1;
+               break;
 
-               case TCP_CLOSE_WAIT:
-               case TCP_CLOSING:
-                       /* Received a retransmission of the FIN, do
-                        * nothing.
-                        */
-                       break;
-               case TCP_LAST_ACK:
-                       /* RFC793: Remain in the LAST-ACK state. */
-                       break;
+       case TCP_CLOSE_WAIT:
+       case TCP_CLOSING:
+               /* Received a retransmission of the FIN, do
+                * nothing.
+                */
+               break;
+       case TCP_LAST_ACK:
+               /* RFC793: Remain in the LAST-ACK state. */
+               break;
 
-               case TCP_FIN_WAIT1:
-                       /* This case occurs when a simultaneous close
-                        * happens, we must ack the received FIN and
-                        * enter the CLOSING state.
-                        */
-                       tcp_send_ack(sk);
-                       tcp_set_state(sk, TCP_CLOSING);
-                       break;
-               case TCP_FIN_WAIT2:
-                       /* Received a FIN -- send ACK and enter TIME_WAIT. */
-                       tcp_send_ack(sk);
-                       tcp_time_wait(sk, TCP_TIME_WAIT, 0);
-                       break;
-               default:
-                       /* Only TCP_LISTEN and TCP_CLOSE are left, in these
-                        * cases we should never reach this piece of code.
-                        */
-                       printk(KERN_ERR "%s: Impossible, sk->sk_state=%d\n",
-                              __FUNCTION__, sk->sk_state);
-                       break;
+       case TCP_FIN_WAIT1:
+               /* This case occurs when a simultaneous close
+                * happens, we must ack the received FIN and
+                * enter the CLOSING state.
+                */
+               tcp_send_ack(sk);
+               tcp_set_state(sk, TCP_CLOSING);
+               break;
+       case TCP_FIN_WAIT2:
+               /* Received a FIN -- send ACK and enter TIME_WAIT. */
+               tcp_send_ack(sk);
+               tcp_time_wait(sk, TCP_TIME_WAIT, 0);
+               break;
+       default:
+               /* Only TCP_LISTEN and TCP_CLOSE are left, in these
+                * cases we should never reach this piece of code.
+                */
+               printk(KERN_ERR "%s: Impossible, sk->sk_state=%d\n",
+                      __FUNCTION__, sk->sk_state);
+               break;
        }
 
        /* It _is_ possible, that we have something out-of-order _after_ FIN.
@@ -3461,7 +3567,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
        __skb_queue_purge(&tp->out_of_order_queue);
        if (tcp_is_sack(tp))
                tcp_sack_reset(&tp->rx_opt);
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 
        if (!sock_flag(sk, SOCK_DEAD)) {
                sk->sk_state_change(sk);
@@ -3469,13 +3575,14 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
                /* Do not send POLL_HUP for half duplex close. */
                if (sk->sk_shutdown == SHUTDOWN_MASK ||
                    sk->sk_state == TCP_CLOSE)
-                       sk_wake_async(sk, 1, POLL_HUP);
+                       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_HUP);
                else
-                       sk_wake_async(sk, 1, POLL_IN);
+                       sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
        }
 }
 
-static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
+static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq,
+                                 u32 end_seq)
 {
        if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) {
                if (before(seq, sp->start_seq))
@@ -3498,7 +3605,8 @@ static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
                tp->rx_opt.dsack = 1;
                tp->duplicate_sack[0].start_seq = seq;
                tp->duplicate_sack[0].end_seq = end_seq;
-               tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + 1, 4 - tp->rx_opt.tstamp_ok);
+               tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + 1,
+                                          4 - tp->rx_opt.tstamp_ok);
        }
 }
 
@@ -3538,12 +3646,12 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp)
 {
        int this_sack;
        struct tcp_sack_block *sp = &tp->selective_acks[0];
-       struct tcp_sack_block *swalk = sp+1;
+       struct tcp_sack_block *swalk = sp + 1;
 
        /* See if the recent change to the first SACK eats into
         * or hits the sequence space of other SACK blocks, if so coalesce.
         */
-       for (this_sack = 1; this_sack < tp->rx_opt.num_sacks; ) {
+       for (this_sack = 1; this_sack < tp->rx_opt.num_sacks;) {
                if (tcp_sack_extend(sp, swalk->start_seq, swalk->end_seq)) {
                        int i;
 
@@ -3551,16 +3659,19 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp)
                         * Decrease num_sacks.
                         */
                        tp->rx_opt.num_sacks--;
-                       tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
-                       for (i=this_sack; i < tp->rx_opt.num_sacks; i++)
-                               sp[i] = sp[i+1];
+                       tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks +
+                                                  tp->rx_opt.dsack,
+                                                  4 - tp->rx_opt.tstamp_ok);
+                       for (i = this_sack; i < tp->rx_opt.num_sacks; i++)
+                               sp[i] = sp[i + 1];
                        continue;
                }
                this_sack++, swalk++;
        }
 }
 
-static inline void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
+static inline void tcp_sack_swap(struct tcp_sack_block *sack1,
+                                struct tcp_sack_block *sack2)
 {
        __u32 tmp;
 
@@ -3583,11 +3694,11 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
        if (!cur_sacks)
                goto new_sack;
 
-       for (this_sack=0; this_sack<cur_sacks; this_sack++, sp++) {
+       for (this_sack = 0; this_sack < cur_sacks; this_sack++, sp++) {
                if (tcp_sack_extend(sp, seq, end_seq)) {
                        /* Rotate this_sack to the first one. */
-                       for (; this_sack>0; this_sack--, sp--)
-                               tcp_sack_swap(sp, sp-1);
+                       for (; this_sack > 0; this_sack--, sp--)
+                               tcp_sack_swap(sp, sp - 1);
                        if (cur_sacks > 1)
                                tcp_sack_maybe_coalesce(tp);
                        return;
@@ -3606,14 +3717,15 @@ static void tcp_sack_new_ofo_skb(struct sock *sk, u32 seq, u32 end_seq)
                sp--;
        }
        for (; this_sack > 0; this_sack--, sp--)
-               *sp = *(sp-1);
+               *sp = *(sp - 1);
 
 new_sack:
        /* Build the new head SACK, and we're done. */
        sp->start_seq = seq;
        sp->end_seq = end_seq;
        tp->rx_opt.num_sacks++;
-       tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
+       tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack,
+                                  4 - tp->rx_opt.tstamp_ok);
 }
 
 /* RCV.NXT advances, some SACKs should be eaten. */
@@ -3631,7 +3743,7 @@ static void tcp_sack_remove(struct tcp_sock *tp)
                return;
        }
 
-       for (this_sack = 0; this_sack < num_sacks; ) {
+       for (this_sack = 0; this_sack < num_sacks;) {
                /* Check if the start of the sack is covered by RCV.NXT. */
                if (!before(tp->rcv_nxt, sp->start_seq)) {
                        int i;
@@ -3650,7 +3762,9 @@ static void tcp_sack_remove(struct tcp_sock *tp)
        }
        if (num_sacks != tp->rx_opt.num_sacks) {
                tp->rx_opt.num_sacks = num_sacks;
-               tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks + tp->rx_opt.dsack, 4 - tp->rx_opt.tstamp_ok);
+               tp->rx_opt.eff_sacks = min(tp->rx_opt.num_sacks +
+                                          tp->rx_opt.dsack,
+                                          4 - tp->rx_opt.tstamp_ok);
        }
 }
 
@@ -3703,14 +3817,14 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
        if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
                goto drop;
 
-       __skb_pull(skb, th->doff*4);
+       __skb_pull(skb, th->doff * 4);
 
        TCP_ECN_accept_cwr(tp, skb);
 
        if (tp->rx_opt.dsack) {
                tp->rx_opt.dsack = 0;
                tp->rx_opt.eff_sacks = min_t(unsigned int, tp->rx_opt.num_sacks,
-                                                   4 - tp->rx_opt.tstamp_ok);
+                                            4 - tp->rx_opt.tstamp_ok);
        }
 
        /*  Queue data for delivery to the user.
@@ -3726,7 +3840,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
                    tp->copied_seq == tp->rcv_nxt && tp->ucopy.len &&
                    sock_owned_by_user(sk) && !tp->urg_data) {
                        int chunk = min_t(unsigned int, skb->len,
-                                                       tp->ucopy.len);
+                                         tp->ucopy.len);
 
                        __set_current_state(TASK_RUNNING);
 
@@ -3744,12 +3858,12 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 queue_and_out:
                        if (eaten < 0 &&
                            (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
-                            !sk_stream_rmem_schedule(sk, skb))) {
+                            !sk_rmem_schedule(sk, skb->truesize))) {
                                if (tcp_prune_queue(sk) < 0 ||
-                                   !sk_stream_rmem_schedule(sk, skb))
+                                   !sk_rmem_schedule(sk, skb->truesize))
                                        goto drop;
                        }
-                       sk_stream_set_owner_r(skb, sk);
+                       skb_set_owner_r(skb, sk);
                        __skb_queue_tail(&sk->sk_receive_queue, skb);
                }
                tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
@@ -3818,9 +3932,9 @@ drop:
        TCP_ECN_check_ce(tp, skb);
 
        if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
-           !sk_stream_rmem_schedule(sk, skb)) {
+           !sk_rmem_schedule(sk, skb->truesize)) {
                if (tcp_prune_queue(sk) < 0 ||
-                   !sk_stream_rmem_schedule(sk, skb))
+                   !sk_rmem_schedule(sk, skb->truesize))
                        goto drop;
        }
 
@@ -3831,7 +3945,7 @@ drop:
        SOCK_DEBUG(sk, "out of order segment: rcv_next %X seq %X - %X\n",
                   tp->rcv_nxt, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
 
-       sk_stream_set_owner_r(skb, sk);
+       skb_set_owner_r(skb, sk);
 
        if (!skb_peek(&tp->out_of_order_queue)) {
                /* Initial out of order segment, build 1 SACK. */
@@ -3843,7 +3957,7 @@ drop:
                        tp->selective_acks[0].end_seq =
                                                TCP_SKB_CB(skb)->end_seq;
                }
-               __skb_queue_head(&tp->out_of_order_queue,skb);
+               __skb_queue_head(&tp->out_of_order_queue, skb);
        } else {
                struct sk_buff *skb1 = tp->out_of_order_queue.prev;
                u32 seq = TCP_SKB_CB(skb)->seq;
@@ -3866,10 +3980,10 @@ drop:
                        if (!after(TCP_SKB_CB(skb1)->seq, seq))
                                break;
                } while ((skb1 = skb1->prev) !=
-                        (struct sk_buff*)&tp->out_of_order_queue);
+                        (struct sk_buff *)&tp->out_of_order_queue);
 
                /* Do skb overlap to previous one? */
-               if (skb1 != (struct sk_buff*)&tp->out_of_order_queue &&
+               if (skb1 != (struct sk_buff *)&tp->out_of_order_queue &&
                    before(seq, TCP_SKB_CB(skb1)->end_seq)) {
                        if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
                                /* All the bits are present. Drop. */
@@ -3879,7 +3993,8 @@ drop:
                        }
                        if (after(seq, TCP_SKB_CB(skb1)->seq)) {
                                /* Partial overlap. */
-                               tcp_dsack_set(tp, seq, TCP_SKB_CB(skb1)->end_seq);
+                               tcp_dsack_set(tp, seq,
+                                             TCP_SKB_CB(skb1)->end_seq);
                        } else {
                                skb1 = skb1->prev;
                        }
@@ -3888,15 +4003,17 @@ drop:
 
                /* And clean segments covered by new one as whole. */
                while ((skb1 = skb->next) !=
-                      (struct sk_buff*)&tp->out_of_order_queue &&
+                      (struct sk_buff *)&tp->out_of_order_queue &&
                       after(end_seq, TCP_SKB_CB(skb1)->seq)) {
-                      if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
-                              tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, end_seq);
-                              break;
-                      }
-                      __skb_unlink(skb1, &tp->out_of_order_queue);
-                      tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq, TCP_SKB_CB(skb1)->end_seq);
-                      __kfree_skb(skb1);
+                       if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
+                               tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq,
+                                                end_seq);
+                               break;
+                       }
+                       __skb_unlink(skb1, &tp->out_of_order_queue);
+                       tcp_dsack_extend(tp, TCP_SKB_CB(skb1)->seq,
+                                        TCP_SKB_CB(skb1)->end_seq);
+                       __kfree_skb(skb1);
                }
 
 add_sack:
@@ -3919,7 +4036,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
 
        /* First, check that queue is collapsible and find
         * the point where collapsing can be useful. */
-       for (skb = head; skb != tail; ) {
+       for (skb = head; skb != tail;) {
                /* No new bits? It is possible on ofo queue. */
                if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
                        struct sk_buff *next = skb->next;
@@ -3957,9 +4074,9 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
                /* Too big header? This can happen with IPv6. */
                if (copy < 0)
                        return;
-               if (end-start < copy)
-                       copy = end-start;
-               nskb = alloc_skb(copy+header, GFP_ATOMIC);
+               if (end - start < copy)
+                       copy = end - start;
+               nskb = alloc_skb(copy + header, GFP_ATOMIC);
                if (!nskb)
                        return;
 
@@ -3973,7 +4090,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
                memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
                TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
                __skb_insert(nskb, skb->prev, skb, list);
-               sk_stream_set_owner_r(nskb, sk);
+               skb_set_owner_r(nskb, sk);
 
                /* Copy data, releasing collapsed skbs. */
                while (copy > 0) {
@@ -4069,9 +4186,9 @@ static int tcp_prune_queue(struct sock *sk)
        tcp_collapse_ofo_queue(sk);
        tcp_collapse(sk, &sk->sk_receive_queue,
                     sk->sk_receive_queue.next,
-                    (struct sk_buff*)&sk->sk_receive_queue,
+                    (struct sk_buff *)&sk->sk_receive_queue,
                     tp->copied_seq, tp->rcv_nxt);
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 
        if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
                return 0;
@@ -4091,7 +4208,7 @@ static int tcp_prune_queue(struct sock *sk)
                 */
                if (tcp_is_sack(tp))
                        tcp_sack_reset(&tp->rx_opt);
-               sk_stream_mem_reclaim(sk);
+               sk_mem_reclaim(sk);
        }
 
        if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
@@ -4108,7 +4225,6 @@ static int tcp_prune_queue(struct sock *sk)
        return -1;
 }
 
-
 /* RFC2861, slow part. Adjust cwnd, after it was not full during one rto.
  * As additional protections, we do not touch cwnd in retransmission phases,
  * and if application hit its sndbuf limit recently.
@@ -4170,8 +4286,8 @@ static void tcp_new_space(struct sock *sk)
                int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) +
                        MAX_TCP_HEADER + 16 + sizeof(struct sk_buff),
                    demanded = max_t(unsigned int, tp->snd_cwnd,
-                                                  tp->reordering + 1);
-               sndmem *= 2*demanded;
+                                    tp->reordering + 1);
+               sndmem *= 2 * demanded;
                if (sndmem > sk->sk_sndbuf)
                        sk->sk_sndbuf = min(sndmem, sysctl_tcp_wmem[2]);
                tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -4212,8 +4328,7 @@ static void __tcp_ack_snd_check(struct sock *sk, int ofo_possible)
            /* We ACK each frame or... */
            tcp_in_quickack_mode(sk) ||
            /* We have out of order data. */
-           (ofo_possible &&
-            skb_peek(&tp->out_of_order_queue))) {
+           (ofo_possible && skb_peek(&tp->out_of_order_queue))) {
                /* Then ack it now */
                tcp_send_ack(sk);
        } else {
@@ -4241,7 +4356,7 @@ static inline void tcp_ack_snd_check(struct sock *sk)
  *     either form (or just set the sysctl tcp_stdurg).
  */
 
-static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
+static void tcp_check_urg(struct sock *sk, struct tcphdr *th)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        u32 ptr = ntohs(th->urg_ptr);
@@ -4290,8 +4405,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
         * buggy users.
         */
        if (tp->urg_seq == tp->copied_seq && tp->urg_data &&
-           !sock_flag(sk, SOCK_URGINLINE) &&
-           tp->copied_seq != tp->rcv_nxt) {
+           !sock_flag(sk, SOCK_URGINLINE) && tp->copied_seq != tp->rcv_nxt) {
                struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
                tp->copied_seq++;
                if (skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq)) {
@@ -4300,8 +4414,8 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
                }
        }
 
-       tp->urg_data   = TCP_URG_NOTYET;
-       tp->urg_seq    = ptr;
+       tp->urg_data = TCP_URG_NOTYET;
+       tp->urg_seq = ptr;
 
        /* Disable header prediction. */
        tp->pred_flags = 0;
@@ -4314,7 +4428,7 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th)
 
        /* Check if we get a new urgent pointer - normally not. */
        if (th->urg)
-               tcp_check_urg(sk,th);
+               tcp_check_urg(sk, th);
 
        /* Do we wait for any urgent data? - normally not... */
        if (tp->urg_data == TCP_URG_NOTYET) {
@@ -4356,7 +4470,8 @@ static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
        return err;
 }
 
-static __sum16 __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+static __sum16 __tcp_checksum_complete_user(struct sock *sk,
+                                           struct sk_buff *skb)
 {
        __sum16 result;
 
@@ -4370,14 +4485,16 @@ static __sum16 __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb
        return result;
 }
 
-static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_checksum_complete_user(struct sock *sk,
+                                            struct sk_buff *skb)
 {
        return !skb_csum_unnecessary(skb) &&
-               __tcp_checksum_complete_user(sk, skb);
+              __tcp_checksum_complete_user(sk, skb);
 }
 
 #ifdef CONFIG_NET_DMA
-static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen)
+static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb,
+                                 int hlen)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        int chunk = skb->len - hlen;
@@ -4393,7 +4510,9 @@ static int tcp_dma_try_early_copy(struct sock *sk, struct sk_buff *skb, int hlen
        if (tp->ucopy.dma_chan && skb_csum_unnecessary(skb)) {
 
                dma_cookie = dma_skb_copy_datagram_iovec(tp->ucopy.dma_chan,
-                       skb, hlen, tp->ucopy.iov, chunk, tp->ucopy.pinned_list);
+                                                        skb, hlen,
+                                                        tp->ucopy.iov, chunk,
+                                                        tp->ucopy.pinned_list);
 
                if (dma_cookie < 0)
                        goto out;
@@ -4475,7 +4594,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
         */
 
        if ((tcp_flag_word(th) & TCP_HP_BITS) == tp->pred_flags &&
-               TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
+           TCP_SKB_CB(skb)->seq == tp->rcv_nxt) {
                int tcp_header_len = tp->tcp_header_len;
 
                /* Timestamp header prediction: tcp_header_len
@@ -4544,7 +4663,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                        eaten = 1;
                                }
 #endif
-                               if (tp->ucopy.task == current && sock_owned_by_user(sk) && !copied_early) {
+                               if (tp->ucopy.task == current &&
+                                   sock_owned_by_user(sk) && !copied_early) {
                                        __set_current_state(TASK_RUNNING);
 
                                        if (!tcp_copy_to_iovec(sk, skb, tcp_header_len))
@@ -4591,9 +4711,9 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
                                NET_INC_STATS_BH(LINUX_MIB_TCPHPHITS);
 
                                /* Bulk data transfer: receiver */
-                               __skb_pull(skb,tcp_header_len);
+                               __skb_pull(skb, tcp_header_len);
                                __skb_queue_tail(&sk->sk_receive_queue, skb);
-                               sk_stream_set_owner_r(skb, sk);
+                               skb_set_owner_r(skb, sk);
                                tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
                        }
 
@@ -4623,7 +4743,7 @@ no_ack:
        }
 
 slow_path:
-       if (len < (th->doff<<2) || tcp_checksum_complete_user(sk, skb))
+       if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb))
                goto csum_error;
 
        /*
@@ -4830,7 +4950,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
 
                if (!sock_flag(sk, SOCK_DEAD)) {
                        sk->sk_state_change(sk);
-                       sk_wake_async(sk, 0, POLL_OUT);
+                       sk_wake_async(sk, SOCK_WAKE_IO, POLL_OUT);
                }
 
                if (sk->sk_write_pending ||
@@ -4873,7 +4993,8 @@ discard:
        }
 
        /* PAWS check. */
-       if (tp->rx_opt.ts_recent_stamp && tp->rx_opt.saw_tstamp && tcp_paws_check(&tp->rx_opt, 0))
+       if (tp->rx_opt.ts_recent_stamp && tp->rx_opt.saw_tstamp &&
+           tcp_paws_check(&tp->rx_opt, 0))
                goto discard_and_undo;
 
        if (th->syn) {
@@ -4908,7 +5029,6 @@ discard:
                tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
                tcp_initialize_rcv_mss(sk);
 
-
                tcp_send_synack(sk);
 #if 0
                /* Note, we could accept data and URG from this segment.
@@ -4940,7 +5060,6 @@ reset_and_undo:
        return 1;
 }
 
-
 /*
  *     This function implements the receiving procedure of RFC 793 for
  *     all states except ESTABLISHED and TIME_WAIT.
@@ -5060,9 +5179,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                                 * are not waked up, because sk->sk_sleep ==
                                 * NULL and sk->sk_socket == NULL.
                                 */
-                               if (sk->sk_socket) {
-                                       sk_wake_async(sk,0,POLL_OUT);
-                               }
+                               if (sk->sk_socket)
+                                       sk_wake_async(sk,
+                                                     SOCK_WAKE_IO, POLL_OUT);
 
                                tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
                                tp->snd_wnd = ntohs(th->window) <<
@@ -5074,8 +5193,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
                                 * and does not calculate rtt.
                                 * Fix it at least with timestamps.
                                 */
-                               if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
-                                   !tp->srtt)
+                               if (tp->rx_opt.saw_tstamp &&
+                                   tp->rx_opt.rcv_tsecr && !tp->srtt)
                                        tcp_ack_saw_tstamp(sk, 0);
 
                                if (tp->rx_opt.tstamp_ok)
index 652c32368cccb6cb590c2c4eec96b77026288d0b..9aea88b8d4fc6a9b5dd9f12c0160129770f47011 100644 (file)
@@ -99,7 +99,7 @@ static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
 static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                   __be32 saddr, __be32 daddr,
                                   struct tcphdr *th, int protocol,
-                                  int tcplen);
+                                  unsigned int tcplen);
 #endif
 
 struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
@@ -1020,7 +1020,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
 static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                   __be32 saddr, __be32 daddr,
                                   struct tcphdr *th, int protocol,
-                                  int tcplen)
+                                  unsigned int tcplen)
 {
        struct scatterlist sg[4];
        __u16 data_len;
@@ -1113,7 +1113,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                         struct dst_entry *dst,
                         struct request_sock *req,
                         struct tcphdr *th, int protocol,
-                        int tcplen)
+                        unsigned int tcplen)
 {
        __be32 saddr, daddr;
 
@@ -1478,7 +1478,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
        }
 #endif
 
-       __inet_hash(&tcp_hashinfo, newsk, 0);
+       __inet_hash_nolisten(&tcp_hashinfo, newsk);
        __inet_inherit_port(&tcp_hashinfo, sk, newsk);
 
        return newsk;
index e7f5ef92cbd88ec0fd8f341e8bfed09da7b68dd0..ce3c41ff50b2736d5c41b1436cdcd189dcb11c00 100644 (file)
@@ -115,12 +115,12 @@ static void tcp_lp_init(struct sock *sk)
  * Will only call newReno CA when away from inference.
  * From TCP-LP's paper, this will be handled in additive increasement.
  */
-static void tcp_lp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight, int flag)
+static void tcp_lp_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct lp *lp = inet_csk_ca(sk);
 
        if (!(lp->flag & LP_WITHIN_INF))
-               tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+               tcp_reno_cong_avoid(sk, ack, in_flight);
 }
 
 /**
index f4c1eef89af0b3ac1e63ed91ecf3725a761d6949..89f0188885c7e1962f2916d4f4084faf22063701 100644 (file)
@@ -61,27 +61,24 @@ int sysctl_tcp_base_mss __read_mostly = 512;
 /* By default, RFC2861 behavior.  */
 int sysctl_tcp_slow_start_after_idle __read_mostly = 1;
 
-static inline void tcp_packets_out_inc(struct sock *sk,
-                                      const struct sk_buff *skb)
+static void tcp_event_new_data_sent(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       int orig = tp->packets_out;
+       unsigned int prior_packets = tp->packets_out;
+
+       tcp_advance_send_head(sk, skb);
+       tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
+
+       /* Don't override Nagle indefinately with F-RTO */
+       if (tp->frto_counter == 2)
+               tp->frto_counter = 3;
 
        tp->packets_out += tcp_skb_pcount(skb);
-       if (!orig)
+       if (!prior_packets)
                inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
                                          inet_csk(sk)->icsk_rto, TCP_RTO_MAX);
 }
 
-static void update_send_head(struct sock *sk, struct sk_buff *skb)
-{
-       struct tcp_sock *tp = tcp_sk(sk);
-
-       tcp_advance_send_head(sk, skb);
-       tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-       tcp_packets_out_inc(sk, skb);
-}
-
 /* SND.NXT, if window was not shrunk.
  * If window has been shrunk, what should we make? It is not clear at all.
  * Using SND.UNA we will fail to open window, SND.NXT is out of window. :-(
@@ -92,10 +89,10 @@ static inline __u32 tcp_acceptable_seq(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
-       if (!before(tp->snd_una+tp->snd_wnd, tp->snd_nxt))
+       if (!before(tcp_wnd_end(tp), tp->snd_nxt))
                return tp->snd_nxt;
        else
-               return tp->snd_una+tp->snd_wnd;
+               return tcp_wnd_end(tp);
 }
 
 /* Calculate mss to advertise in SYN segment.
@@ -224,14 +221,14 @@ void tcp_select_initial_window(int __space, __u32 mss,
         * following RFC2414. Senders, not following this RFC,
         * will be satisfied with 2.
         */
-       if (mss > (1<<*rcv_wscale)) {
+       if (mss > (1 << *rcv_wscale)) {
                int init_cwnd = 4;
-               if (mss > 1460*3)
+               if (mss > 1460 * 3)
                        init_cwnd = 2;
                else if (mss > 1460)
                        init_cwnd = 3;
-               if (*rcv_wnd > init_cwnd*mss)
-                       *rcv_wnd = init_cwnd*mss;
+               if (*rcv_wnd > init_cwnd * mss)
+                       *rcv_wnd = init_cwnd * mss;
        }
 
        /* Set the clamp no higher than max representable value */
@@ -281,11 +278,10 @@ static u16 tcp_select_window(struct sock *sk)
        return new_win;
 }
 
-static inline void TCP_ECN_send_synack(struct tcp_sock *tp,
-                                      struct sk_buff *skb)
+static inline void TCP_ECN_send_synack(struct tcp_sock *tp, struct sk_buff *skb)
 {
        TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_CWR;
-       if (!(tp->ecn_flags&TCP_ECN_OK))
+       if (!(tp->ecn_flags & TCP_ECN_OK))
                TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_ECE;
 }
 
@@ -295,7 +291,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
 
        tp->ecn_flags = 0;
        if (sysctl_tcp_ecn) {
-               TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE|TCPCB_FLAG_CWR;
+               TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR;
                tp->ecn_flags = TCP_ECN_OK;
        }
 }
@@ -317,7 +313,7 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb,
                if (skb->len != tcp_header_len &&
                    !before(TCP_SKB_CB(skb)->seq, tp->snd_nxt)) {
                        INET_ECN_xmit(sk);
-                       if (tp->ecn_flags&TCP_ECN_QUEUE_CWR) {
+                       if (tp->ecn_flags & TCP_ECN_QUEUE_CWR) {
                                tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
                                tcp_hdr(skb)->cwr = 1;
                                skb_shinfo(skb)->gso_type |= SKB_GSO_TCP_ECN;
@@ -331,6 +327,26 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb,
        }
 }
 
+/* Constructs common control bits of non-data skb. If SYN/FIN is present,
+ * auto increment end seqno.
+ */
+static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
+{
+       skb->csum = 0;
+
+       TCP_SKB_CB(skb)->flags = flags;
+       TCP_SKB_CB(skb)->sacked = 0;
+
+       skb_shinfo(skb)->gso_segs = 1;
+       skb_shinfo(skb)->gso_size = 0;
+       skb_shinfo(skb)->gso_type = 0;
+
+       TCP_SKB_CB(skb)->seq = seq;
+       if (flags & (TCPCB_FLAG_SYN | TCPCB_FLAG_FIN))
+               seq++;
+       TCP_SKB_CB(skb)->end_seq = seq;
+}
+
 static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
                                         __u32 tstamp, __u8 **md5_hash)
 {
@@ -434,7 +450,7 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
                               (TCPOPT_NOP << 16) |
                               (TCPOPT_MD5SIG << 8) |
                               TCPOLEN_MD5SIG);
-               *md5_hash = (__u8 *) ptr;
+               *md5_hash = (__u8 *)ptr;
        }
 #endif
 }
@@ -450,7 +466,8 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
  * We are working here with either a clone of the original
  * SKB, or a fresh unique copy made by the retransmit engine.
  */
-static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, gfp_t gfp_mask)
+static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
+                           gfp_t gfp_mask)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
        struct inet_sock *inet;
@@ -554,8 +571,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
        th->urg_ptr             = 0;
 
        if (unlikely(tp->urg_mode &&
-                    between(tp->snd_up, tcb->seq+1, tcb->seq+0xFFFF))) {
-               th->urg_ptr             = htons(tp->snd_up-tcb->seq);
+                    between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
+               th->urg_ptr             = htons(tp->snd_up - tcb->seq);
                th->urg                 = 1;
        }
 
@@ -619,7 +636,6 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
 #undef SYSCTL_FLAG_SACK
 }
 
-
 /* This routine just queue's the buffer
  *
  * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
@@ -633,10 +649,12 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb)
        tp->write_seq = TCP_SKB_CB(skb)->end_seq;
        skb_header_release(skb);
        tcp_add_write_queue_tail(sk, skb);
-       sk_charge_skb(sk, skb);
+       sk->sk_wmem_queued += skb->truesize;
+       sk_mem_charge(sk, skb->truesize);
 }
 
-static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb,
+                                unsigned int mss_now)
 {
        if (skb->len <= mss_now || !sk_can_gso(sk)) {
                /* Avoid the costly divide in the normal
@@ -653,23 +671,18 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned
 }
 
 /* When a modification to fackets out becomes necessary, we need to check
- * skb is counted to fackets_out or not. Another important thing is to
- * tweak SACK fastpath hint too as it would overwrite all changes unless
- * hint is also changed.
+ * skb is counted to fackets_out or not.
  */
-static void tcp_adjust_fackets_out(struct tcp_sock *tp, struct sk_buff *skb,
+static void tcp_adjust_fackets_out(struct sock *sk, struct sk_buff *skb,
                                   int decr)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
+
        if (!tp->sacked_out || tcp_is_reno(tp))
                return;
 
-       if (!before(tp->highest_sack, TCP_SKB_CB(skb)->seq))
+       if (after(tcp_highest_sack_seq(tp), TCP_SKB_CB(skb)->seq))
                tp->fackets_out -= decr;
-
-       /* cnt_hint is "off-by-one" compared with fackets_out (see sacktag) */
-       if (tp->fastpath_skb_hint != NULL &&
-           after(TCP_SKB_CB(tp->fastpath_skb_hint)->seq, TCP_SKB_CB(skb)->seq))
-               tp->fastpath_cnt_hint -= decr;
 }
 
 /* Function to create two new TCP segments.  Shrinks the given segment
@@ -677,7 +690,8 @@ static void tcp_adjust_fackets_out(struct tcp_sock *tp, struct sk_buff *skb,
  * packet to the list.  This won't be called frequently, I hope.
  * Remember, these are still headerless SKBs at this point.
  */
-int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss_now)
+int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
+                unsigned int mss_now)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *buff;
@@ -702,7 +716,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        if (buff == NULL)
                return -ENOMEM; /* We'll just try again later. */
 
-       sk_charge_skb(sk, buff);
+       sk->sk_wmem_queued += buff->truesize;
+       sk_mem_charge(sk, buff->truesize);
        nlen = skb->len - len - nsize;
        buff->truesize += nlen;
        skb->truesize -= nlen;
@@ -712,20 +727,16 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
        TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
 
-       if (tcp_is_sack(tp) && tp->sacked_out &&
-           (TCP_SKB_CB(skb)->seq == tp->highest_sack))
-               tp->highest_sack = TCP_SKB_CB(buff)->seq;
-
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
-       TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
+       TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN | TCPCB_FLAG_PSH);
        TCP_SKB_CB(buff)->flags = flags;
        TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked;
-       TCP_SKB_CB(skb)->sacked &= ~TCPCB_AT_TAIL;
 
        if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_PARTIAL) {
                /* Copy and checksum data tail into the new buffer. */
-               buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize),
+               buff->csum = csum_partial_copy_nocheck(skb->data + len,
+                                                      skb_put(buff, nsize),
                                                       nsize, 0);
 
                skb_trim(skb, len);
@@ -772,7 +783,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
                        tcp_dec_pcount_approx_int(&tp->sacked_out, diff);
                        tcp_verify_left_out(tp);
                }
-               tcp_adjust_fackets_out(tp, skb, diff);
+               tcp_adjust_fackets_out(sk, skb, diff);
        }
 
        /* Link BUFF into the send queue. */
@@ -792,7 +803,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
 
        eat = len;
        k = 0;
-       for (i=0; i<skb_shinfo(skb)->nr_frags; i++) {
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                if (skb_shinfo(skb)->frags[i].size <= eat) {
                        put_page(skb_shinfo(skb)->frags[i].page);
                        eat -= skb_shinfo(skb)->frags[i].size;
@@ -815,8 +826,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
 
 int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
 {
-       if (skb_cloned(skb) &&
-           pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
+       if (skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
                return -ENOMEM;
 
        /* If len == headlen, we avoid __skb_pull to preserve alignment. */
@@ -830,7 +840,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
 
        skb->truesize        -= len;
        sk->sk_wmem_queued   -= len;
-       sk->sk_forward_alloc += len;
+       sk_mem_uncharge(sk, len);
        sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
 
        /* Any change of skb->len requires recalculation of tso
@@ -898,6 +908,15 @@ void tcp_mtup_init(struct sock *sk)
        icsk->icsk_mtup.probe_size = 0;
 }
 
+/* Bound MSS / TSO packet size with the half of the window */
+static int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
+{
+       if (tp->max_window && pktsize > (tp->max_window >> 1))
+               return max(tp->max_window >> 1, 68U - tp->tcp_header_len);
+       else
+               return pktsize;
+}
+
 /* This function synchronize snd mss to current pmtu/exthdr set.
 
    tp->rx_opt.user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
@@ -920,7 +939,6 @@ void tcp_mtup_init(struct sock *sk)
    NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
    are READ ONLY outside this function.                --ANK (980731)
  */
-
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
 {
        struct tcp_sock *tp = tcp_sk(sk);
@@ -931,10 +949,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
                icsk->icsk_mtup.search_high = pmtu;
 
        mss_now = tcp_mtu_to_mss(sk, pmtu);
-
-       /* Bound mss with half of window */
-       if (tp->max_window && mss_now > (tp->max_window>>1))
-               mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
+       mss_now = tcp_bound_to_half_wnd(tp, mss_now);
 
        /* And store cached results */
        icsk->icsk_pmtu_cookie = pmtu;
@@ -988,11 +1003,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
                                  inet_csk(sk)->icsk_ext_hdr_len -
                                  tp->tcp_header_len);
 
-               if (tp->max_window &&
-                   (xmit_size_goal > (tp->max_window >> 1)))
-                       xmit_size_goal = max((tp->max_window >> 1),
-                                            68U - tp->tcp_header_len);
-
+               xmit_size_goal = tcp_bound_to_half_wnd(tp, xmit_size_goal);
                xmit_size_goal -= (xmit_size_goal % mss_now);
        }
        tp->xmit_size_goal = xmit_size_goal;
@@ -1001,13 +1012,11 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
 }
 
 /* Congestion window validation. (RFC2861) */
-
 static void tcp_cwnd_validate(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
-       __u32 packets_out = tp->packets_out;
 
-       if (packets_out >= tp->snd_cwnd) {
+       if (tp->packets_out >= tp->snd_cwnd) {
                /* Network is feed fully. */
                tp->snd_cwnd_used = 0;
                tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -1022,19 +1031,35 @@ static void tcp_cwnd_validate(struct sock *sk)
        }
 }
 
-static unsigned int tcp_window_allows(struct tcp_sock *tp, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd)
+/* Returns the portion of skb which can be sent right away without
+ * introducing MSS oddities to segment boundaries. In rare cases where
+ * mss_now != mss_cache, we will request caller to create a small skb
+ * per input skb which could be mostly avoided here (if desired).
+ */
+static unsigned int tcp_mss_split_point(struct sock *sk, struct sk_buff *skb,
+                                       unsigned int mss_now, unsigned int cwnd)
 {
-       u32 window, cwnd_len;
+       struct tcp_sock *tp = tcp_sk(sk);
+       u32 needed, window, cwnd_len;
 
-       window = (tp->snd_una + tp->snd_wnd - TCP_SKB_CB(skb)->seq);
+       window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
        cwnd_len = mss_now * cwnd;
-       return min(window, cwnd_len);
+
+       if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
+               return cwnd_len;
+
+       if (skb == tcp_write_queue_tail(sk) && cwnd_len <= skb->len)
+               return cwnd_len;
+
+       needed = min(skb->len, window);
+       return needed - needed % mss_now;
 }
 
 /* Can at least one segment of SKB be sent right now, according to the
  * congestion window rules?  If so, return how many segments are allowed.
  */
-static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb)
+static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp,
+                                        struct sk_buff *skb)
 {
        u32 in_flight, cwnd;
 
@@ -1054,13 +1079,12 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *sk
 /* This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
-static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb,
+                            unsigned int mss_now)
 {
        int tso_segs = tcp_skb_pcount(skb);
 
-       if (!tso_segs ||
-           (tso_segs > 1 &&
-            tcp_skb_mss(skb) != mss_now)) {
+       if (!tso_segs || (tso_segs > 1 && tcp_skb_mss(skb) != mss_now)) {
                tcp_set_skb_tso_segs(sk, skb, mss_now);
                tso_segs = tcp_skb_pcount(skb);
        }
@@ -1080,16 +1104,13 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp)
  * 4. Or TCP_CORK is not set, and all sent packets are ACKed.
  *    With Minshall's modification: all sent small packets are ACKed.
  */
-
 static inline int tcp_nagle_check(const struct tcp_sock *tp,
                                  const struct sk_buff *skb,
                                  unsigned mss_now, int nonagle)
 {
        return (skb->len < mss_now &&
-               ((nonagle&TCP_NAGLE_CORK) ||
-                (!nonagle &&
-                 tp->packets_out &&
-                 tcp_minshall_check(tp))));
+               ((nonagle & TCP_NAGLE_CORK) ||
+                (!nonagle && tp->packets_out && tcp_minshall_check(tp))));
 }
 
 /* Return non-zero if the Nagle test allows this packet to be
@@ -1121,14 +1142,15 @@ static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
 }
 
 /* Does at least the first segment of SKB fit into the send window? */
-static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss)
+static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb,
+                                  unsigned int cur_mss)
 {
        u32 end_seq = TCP_SKB_CB(skb)->end_seq;
 
        if (skb->len > cur_mss)
                end_seq = TCP_SKB_CB(skb)->seq + cur_mss;
 
-       return !after(end_seq, tp->snd_una + tp->snd_wnd);
+       return !after(end_seq, tcp_wnd_end(tp));
 }
 
 /* This checks if the data bearing packet SKB (usually tcp_send_head(sk))
@@ -1147,8 +1169,7 @@ static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb,
                return 0;
 
        cwnd_quota = tcp_cwnd_test(tp, skb);
-       if (cwnd_quota &&
-           !tcp_snd_wnd_test(tp, skb, cur_mss))
+       if (cwnd_quota && !tcp_snd_wnd_test(tp, skb, cur_mss))
                cwnd_quota = 0;
 
        return cwnd_quota;
@@ -1172,7 +1193,8 @@ int tcp_may_send_now(struct sock *sk)
  * know that all the data is in scatter-gather pages, and that the
  * packet has never been sent out before (and thus is not cloned).
  */
-static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, unsigned int mss_now)
+static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
+                       unsigned int mss_now)
 {
        struct sk_buff *buff;
        int nlen = skb->len - len;
@@ -1182,11 +1204,12 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
        if (skb->len != skb->data_len)
                return tcp_fragment(sk, skb, len, mss_now);
 
-       buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC);
+       buff = sk_stream_alloc_skb(sk, 0, GFP_ATOMIC);
        if (unlikely(buff == NULL))
                return -ENOMEM;
 
-       sk_charge_skb(sk, buff);
+       sk->sk_wmem_queued += buff->truesize;
+       sk_mem_charge(sk, buff->truesize);
        buff->truesize += nlen;
        skb->truesize -= nlen;
 
@@ -1197,7 +1220,7 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
 
        /* PSH and FIN should only be set in the second packet. */
        flags = TCP_SKB_CB(skb)->flags;
-       TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
+       TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN | TCPCB_FLAG_PSH);
        TCP_SKB_CB(buff)->flags = flags;
 
        /* This packet was never sent out yet, so no SACK bits. */
@@ -1235,15 +1258,15 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
                goto send_now;
 
        /* Defer for less than two clock ticks. */
-       if (!tp->tso_deferred && ((jiffies<<1)>>1) - (tp->tso_deferred>>1) > 1)
+       if (tp->tso_deferred &&
+           ((jiffies << 1) >> 1) - (tp->tso_deferred >> 1) > 1)
                goto send_now;
 
        in_flight = tcp_packets_in_flight(tp);
 
-       BUG_ON(tcp_skb_pcount(skb) <= 1 ||
-              (tp->snd_cwnd <= in_flight));
+       BUG_ON(tcp_skb_pcount(skb) <= 1 || (tp->snd_cwnd <= in_flight));
 
-       send_win = (tp->snd_una + tp->snd_wnd) - TCP_SKB_CB(skb)->seq;
+       send_win = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
 
        /* From in_flight test above, we know that cwnd > in_flight.  */
        cong_win = (tp->snd_cwnd - in_flight) * tp->mss_cache;
@@ -1274,7 +1297,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
        }
 
        /* Ok, it looks like it is advisable to defer.  */
-       tp->tso_deferred = 1 | (jiffies<<1);
+       tp->tso_deferred = 1 | (jiffies << 1);
 
        return 1;
 
@@ -1286,7 +1309,8 @@ send_now:
 /* Create a new MTU probe if we are ready.
  * Returns 0 if we should wait to probe (no cwnd available),
  *         1 if a probe was sent,
- *         -1 otherwise */
+ *         -1 otherwise
+ */
 static int tcp_mtu_probe(struct sock *sk)
 {
        struct tcp_sock *tp = tcp_sk(sk);
@@ -1295,7 +1319,6 @@ static int tcp_mtu_probe(struct sock *sk)
        int len;
        int probe_size;
        int size_needed;
-       unsigned int pif;
        int copy;
        int mss_now;
 
@@ -1312,7 +1335,7 @@ static int tcp_mtu_probe(struct sock *sk)
 
        /* Very simple search strategy: just double the MSS. */
        mss_now = tcp_current_mss(sk, 0);
-       probe_size = 2*tp->mss_cache;
+       probe_size = 2 * tp->mss_cache;
        size_needed = probe_size + (tp->reordering + 1) * tp->mss_cache;
        if (probe_size > tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_high)) {
                /* TODO: set timer for probe_converge_event */
@@ -1325,14 +1348,12 @@ static int tcp_mtu_probe(struct sock *sk)
 
        if (tp->snd_wnd < size_needed)
                return -1;
-       if (after(tp->snd_nxt + size_needed, tp->snd_una + tp->snd_wnd))
+       if (after(tp->snd_nxt + size_needed, tcp_wnd_end(tp)))
                return 0;
 
-       /* Do we need to wait to drain cwnd? */
-       pif = tcp_packets_in_flight(tp);
-       if (pif + 2 > tp->snd_cwnd) {
-               /* With no packets in flight, don't stall. */
-               if (pif == 0)
+       /* Do we need to wait to drain cwnd? With none in flight, don't stall */
+       if (tcp_packets_in_flight(tp) + 2 > tp->snd_cwnd) {
+               if (!tcp_packets_in_flight(tp))
                        return -1;
                else
                        return 0;
@@ -1341,10 +1362,10 @@ static int tcp_mtu_probe(struct sock *sk)
        /* We're allowed to probe.  Build it now. */
        if ((nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC)) == NULL)
                return -1;
-       sk_charge_skb(sk, nskb);
+       sk->sk_wmem_queued += nskb->truesize;
+       sk_mem_charge(sk, nskb->truesize);
 
        skb = tcp_send_head(sk);
-       tcp_insert_write_queue_before(nskb, skb, sk);
 
        TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(skb)->seq;
        TCP_SKB_CB(nskb)->end_seq = TCP_SKB_CB(skb)->seq + probe_size;
@@ -1353,30 +1374,32 @@ static int tcp_mtu_probe(struct sock *sk)
        nskb->csum = 0;
        nskb->ip_summed = skb->ip_summed;
 
-       len = 0;
-       while (len < probe_size) {
-               next = tcp_write_queue_next(sk, skb);
+       tcp_insert_write_queue_before(nskb, skb, sk);
 
+       len = 0;
+       tcp_for_write_queue_from_safe(skb, next, sk) {
                copy = min_t(int, skb->len, probe_size - len);
                if (nskb->ip_summed)
                        skb_copy_bits(skb, 0, skb_put(nskb, copy), copy);
                else
                        nskb->csum = skb_copy_and_csum_bits(skb, 0,
-                                        skb_put(nskb, copy), copy, nskb->csum);
+                                                           skb_put(nskb, copy),
+                                                           copy, nskb->csum);
 
                if (skb->len <= copy) {
                        /* We've eaten all the data from this skb.
                         * Throw it away. */
                        TCP_SKB_CB(nskb)->flags |= TCP_SKB_CB(skb)->flags;
                        tcp_unlink_write_queue(skb, sk);
-                       sk_stream_free_skb(sk, skb);
+                       sk_wmem_free_skb(sk, skb);
                } else {
                        TCP_SKB_CB(nskb)->flags |= TCP_SKB_CB(skb)->flags &
                                                   ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
                        if (!skb_shinfo(skb)->nr_frags) {
                                skb_pull(skb, copy);
                                if (skb->ip_summed != CHECKSUM_PARTIAL)
-                                       skb->csum = csum_partial(skb->data, skb->len, 0);
+                                       skb->csum = csum_partial(skb->data,
+                                                                skb->len, 0);
                        } else {
                                __pskb_trim_head(skb, copy);
                                tcp_set_skb_tso_segs(sk, skb, mss_now);
@@ -1385,7 +1408,9 @@ static int tcp_mtu_probe(struct sock *sk)
                }
 
                len += copy;
-               skb = next;
+
+               if (len >= probe_size)
+                       break;
        }
        tcp_init_tso_segs(sk, nskb, nskb->len);
 
@@ -1394,9 +1419,9 @@ static int tcp_mtu_probe(struct sock *sk)
        TCP_SKB_CB(nskb)->when = tcp_time_stamp;
        if (!tcp_transmit_skb(sk, nskb, 1, GFP_ATOMIC)) {
                /* Decrement cwnd here because we are sending
-               * effectively two packets. */
+                * effectively two packets. */
                tp->snd_cwnd--;
-               update_send_head(sk, nskb);
+               tcp_event_new_data_sent(sk, nskb);
 
                icsk->icsk_mtup.probe_size = tcp_mss_to_mtu(sk, nskb->len);
                tp->mtu_probe.probe_seq_start = TCP_SKB_CB(nskb)->seq;
@@ -1408,7 +1433,6 @@ static int tcp_mtu_probe(struct sock *sk)
        return -1;
 }
 
-
 /* This routine writes packets to the network.  It advances the
  * send_head.  This happens as incoming acks open up the remote
  * window for us.
@@ -1464,17 +1488,9 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
                }
 
                limit = mss_now;
-               if (tso_segs > 1) {
-                       limit = tcp_window_allows(tp, skb,
-                                                 mss_now, cwnd_quota);
-
-                       if (skb->len < limit) {
-                               unsigned int trim = skb->len % mss_now;
-
-                               if (trim)
-                                       limit = skb->len - trim;
-                       }
-               }
+               if (tso_segs > 1)
+                       limit = tcp_mss_split_point(sk, skb, mss_now,
+                                                   cwnd_quota);
 
                if (skb->len > limit &&
                    unlikely(tso_fragment(sk, skb, limit, mss_now)))
@@ -1488,7 +1504,7 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
                /* Advance the send_head.  This one is sent out.
                 * This call will increment packets_out.
                 */
-               update_send_head(sk, skb);
+               tcp_event_new_data_sent(sk, skb);
 
                tcp_minshall_update(tp, mss_now, skb);
                sent_pkts++;
@@ -1521,7 +1537,6 @@ void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
  */
 void tcp_push_one(struct sock *sk, unsigned int mss_now)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb = tcp_send_head(sk);
        unsigned int tso_segs, cwnd_quota;
 
@@ -1536,17 +1551,9 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
                BUG_ON(!tso_segs);
 
                limit = mss_now;
-               if (tso_segs > 1) {
-                       limit = tcp_window_allows(tp, skb,
-                                                 mss_now, cwnd_quota);
-
-                       if (skb->len < limit) {
-                               unsigned int trim = skb->len % mss_now;
-
-                               if (trim)
-                                       limit = skb->len - trim;
-                       }
-               }
+               if (tso_segs > 1)
+                       limit = tcp_mss_split_point(sk, skb, mss_now,
+                                                   cwnd_quota);
 
                if (skb->len > limit &&
                    unlikely(tso_fragment(sk, skb, limit, mss_now)))
@@ -1556,7 +1563,7 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
                TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
                if (likely(!tcp_transmit_skb(sk, skb, 1, sk->sk_allocation))) {
-                       update_send_head(sk, skb);
+                       tcp_event_new_data_sent(sk, skb);
                        tcp_cwnd_validate(sk);
                        return;
                }
@@ -1633,11 +1640,12 @@ u32 __tcp_select_window(struct sock *sk)
        if (mss > full_space)
                mss = full_space;
 
-       if (free_space < full_space/2) {
+       if (free_space < (full_space >> 1)) {
                icsk->icsk_ack.quick = 0;
 
                if (tcp_memory_pressure)
-                       tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss);
+                       tp->rcv_ssthresh = min(tp->rcv_ssthresh,
+                                              4U * tp->advmss);
 
                if (free_space < mss)
                        return 0;
@@ -1670,9 +1678,9 @@ u32 __tcp_select_window(struct sock *sk)
                 * is too small.
                 */
                if (window <= free_space - mss || window > free_space)
-                       window = (free_space/mss)*mss;
+                       window = (free_space / mss) * mss;
                else if (mss == full_space &&
-                        free_space > window + full_space/2)
+                        free_space > window + (full_space >> 1))
                        window = free_space;
        }
 
@@ -1680,86 +1688,82 @@ u32 __tcp_select_window(struct sock *sk)
 }
 
 /* Attempt to collapse two adjacent SKB's during retransmission. */
-static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int mss_now)
+static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb,
+                                    int mss_now)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *next_skb = tcp_write_queue_next(sk, skb);
+       int skb_size, next_skb_size;
+       u16 flags;
 
        /* The first test we must make is that neither of these two
         * SKB's are still referenced by someone else.
         */
-       if (!skb_cloned(skb) && !skb_cloned(next_skb)) {
-               int skb_size = skb->len, next_skb_size = next_skb->len;
-               u16 flags = TCP_SKB_CB(skb)->flags;
+       if (skb_cloned(skb) || skb_cloned(next_skb))
+               return;
 
-               /* Also punt if next skb has been SACK'd. */
-               if (TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_ACKED)
-                       return;
+       skb_size = skb->len;
+       next_skb_size = next_skb->len;
+       flags = TCP_SKB_CB(skb)->flags;
 
-               /* Next skb is out of window. */
-               if (after(TCP_SKB_CB(next_skb)->end_seq, tp->snd_una+tp->snd_wnd))
-                       return;
+       /* Also punt if next skb has been SACK'd. */
+       if (TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_ACKED)
+               return;
 
-               /* Punt if not enough space exists in the first SKB for
-                * the data in the second, or the total combined payload
-                * would exceed the MSS.
-                */
-               if ((next_skb_size > skb_tailroom(skb)) ||
-                   ((skb_size + next_skb_size) > mss_now))
-                       return;
+       /* Next skb is out of window. */
+       if (after(TCP_SKB_CB(next_skb)->end_seq, tcp_wnd_end(tp)))
+               return;
 
-               BUG_ON(tcp_skb_pcount(skb) != 1 ||
-                      tcp_skb_pcount(next_skb) != 1);
+       /* Punt if not enough space exists in the first SKB for
+        * the data in the second, or the total combined payload
+        * would exceed the MSS.
+        */
+       if ((next_skb_size > skb_tailroom(skb)) ||
+           ((skb_size + next_skb_size) > mss_now))
+               return;
 
-               if (WARN_ON(tcp_is_sack(tp) && tp->sacked_out &&
-                   (TCP_SKB_CB(next_skb)->seq == tp->highest_sack)))
-                       return;
+       BUG_ON(tcp_skb_pcount(skb) != 1 || tcp_skb_pcount(next_skb) != 1);
 
-               /* Ok.  We will be able to collapse the packet. */
-               tcp_unlink_write_queue(next_skb, sk);
+       tcp_highest_sack_combine(sk, next_skb, skb);
 
-               skb_copy_from_linear_data(next_skb,
-                                         skb_put(skb, next_skb_size),
-                                         next_skb_size);
+       /* Ok.  We will be able to collapse the packet. */
+       tcp_unlink_write_queue(next_skb, sk);
 
-               if (next_skb->ip_summed == CHECKSUM_PARTIAL)
-                       skb->ip_summed = CHECKSUM_PARTIAL;
+       skb_copy_from_linear_data(next_skb, skb_put(skb, next_skb_size),
+                                 next_skb_size);
 
-               if (skb->ip_summed != CHECKSUM_PARTIAL)
-                       skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size);
+       if (next_skb->ip_summed == CHECKSUM_PARTIAL)
+               skb->ip_summed = CHECKSUM_PARTIAL;
 
-               /* Update sequence range on original skb. */
-               TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
+       if (skb->ip_summed != CHECKSUM_PARTIAL)
+               skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size);
 
-               /* Merge over control information. */
-               flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
-               TCP_SKB_CB(skb)->flags = flags;
+       /* Update sequence range on original skb. */
+       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
 
-               /* All done, get rid of second SKB and account for it so
-                * packet counting does not break.
-                */
-               TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked&(TCPCB_EVER_RETRANS|TCPCB_AT_TAIL);
-               if (TCP_SKB_CB(next_skb)->sacked&TCPCB_SACKED_RETRANS)
-                       tp->retrans_out -= tcp_skb_pcount(next_skb);
-               if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST)
-                       tp->lost_out -= tcp_skb_pcount(next_skb);
-               /* Reno case is special. Sigh... */
-               if (tcp_is_reno(tp) && tp->sacked_out)
-                       tcp_dec_pcount_approx(&tp->sacked_out, next_skb);
-
-               tcp_adjust_fackets_out(tp, next_skb, tcp_skb_pcount(next_skb));
-               tp->packets_out -= tcp_skb_pcount(next_skb);
-
-               /* changed transmit queue under us so clear hints */
-               tcp_clear_retrans_hints_partial(tp);
-               /* manually tune sacktag skb hint */
-               if (tp->fastpath_skb_hint == next_skb) {
-                       tp->fastpath_skb_hint = skb;
-                       tp->fastpath_cnt_hint -= tcp_skb_pcount(skb);
-               }
+       /* Merge over control information. */
+       flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
+       TCP_SKB_CB(skb)->flags = flags;
 
-               sk_stream_free_skb(sk, next_skb);
-       }
+       /* All done, get rid of second SKB and account for it so
+        * packet counting does not break.
+        */
+       TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked & TCPCB_EVER_RETRANS;
+       if (TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_RETRANS)
+               tp->retrans_out -= tcp_skb_pcount(next_skb);
+       if (TCP_SKB_CB(next_skb)->sacked & TCPCB_LOST)
+               tp->lost_out -= tcp_skb_pcount(next_skb);
+       /* Reno case is special. Sigh... */
+       if (tcp_is_reno(tp) && tp->sacked_out)
+               tcp_dec_pcount_approx(&tp->sacked_out, next_skb);
+
+       tcp_adjust_fackets_out(sk, next_skb, tcp_skb_pcount(next_skb));
+       tp->packets_out -= tcp_skb_pcount(next_skb);
+
+       /* changed transmit queue under us so clear hints */
+       tcp_clear_retrans_hints_partial(tp);
+
+       sk_wmem_free_skb(sk, next_skb);
 }
 
 /* Do a simple retransmit without using the backoff mechanisms in
@@ -1778,12 +1782,12 @@ void tcp_simple_retransmit(struct sock *sk)
                if (skb == tcp_send_head(sk))
                        break;
                if (skb->len > mss &&
-                   !(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
-                       if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
+                   !(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
+                       if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) {
                                TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
                                tp->retrans_out -= tcp_skb_pcount(skb);
                        }
-                       if (!(TCP_SKB_CB(skb)->sacked&TCPCB_LOST)) {
+                       if (!(TCP_SKB_CB(skb)->sacked & TCPCB_LOST)) {
                                TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
                                tp->lost_out += tcp_skb_pcount(skb);
                                lost = 1;
@@ -1848,7 +1852,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
         * case, when window is shrunk to zero. In this case
         * our retransmit serves as a zero window probe.
         */
-       if (!before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)
+       if (!before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))
            && TCP_SKB_CB(skb)->seq != tp->snd_una)
                return -EAGAIN;
 
@@ -1862,8 +1866,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
            (skb->len < (cur_mss >> 1)) &&
            (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
            (!tcp_skb_is_last(sk, skb)) &&
-           (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) &&
-           (tcp_skb_pcount(skb) == 1 && tcp_skb_pcount(tcp_write_queue_next(sk, skb)) == 1) &&
+           (skb_shinfo(skb)->nr_frags == 0 &&
+            skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) &&
+           (tcp_skb_pcount(skb) == 1 &&
+            tcp_skb_pcount(tcp_write_queue_next(sk, skb)) == 1) &&
            (sysctl_tcp_retrans_collapse != 0))
                tcp_retrans_try_collapse(sk, skb, cur_mss);
 
@@ -1878,12 +1884,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
            (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
            tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
                if (!pskb_trim(skb, 0)) {
-                       TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
-                       skb_shinfo(skb)->gso_segs = 1;
-                       skb_shinfo(skb)->gso_size = 0;
-                       skb_shinfo(skb)->gso_type = 0;
+                       /* Reuse, even though it does some unnecessary work */
+                       tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1,
+                                            TCP_SKB_CB(skb)->flags);
                        skb->ip_summed = CHECKSUM_NONE;
-                       skb->csum = 0;
                }
        }
 
@@ -1901,7 +1905,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
                tp->total_retrans++;
 
 #if FASTRETRANS_DEBUG > 0
-               if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
+               if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) {
                        if (net_ratelimit())
                                printk(KERN_DEBUG "retrans_out leaked.\n");
                }
@@ -1943,7 +1947,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
        if (tp->retransmit_skb_hint) {
                skb = tp->retransmit_skb_hint;
                packet_cnt = tp->retransmit_cnt_hint;
-       }else{
+       } else {
                skb = tcp_write_queue_head(sk);
                packet_cnt = 0;
        }
@@ -1970,7 +1974,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
                                return;
 
                        if (sacked & TCPCB_LOST) {
-                               if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
+                               if (!(sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
                                        if (tcp_retransmit_skb(sk, skb)) {
                                                tp->retransmit_skb_hint = NULL;
                                                return;
@@ -2028,7 +2032,7 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
                        break;
                tp->forward_skb_hint = skb;
 
-               if (after(TCP_SKB_CB(skb)->seq, tp->highest_sack))
+               if (!before(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp)))
                        break;
 
                if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
@@ -2052,7 +2056,6 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
        }
 }
 
-
 /* Send a fin.  The caller locks the socket for us.  This cannot be
  * allowed to fail queueing a FIN frame under any circumstances.
  */
@@ -2083,16 +2086,9 @@ void tcp_send_fin(struct sock *sk)
 
                /* Reserve space for headers and prepare control bits. */
                skb_reserve(skb, MAX_TCP_HEADER);
-               skb->csum = 0;
-               TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
-               TCP_SKB_CB(skb)->sacked = 0;
-               skb_shinfo(skb)->gso_segs = 1;
-               skb_shinfo(skb)->gso_size = 0;
-               skb_shinfo(skb)->gso_type = 0;
-
                /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
-               TCP_SKB_CB(skb)->seq = tp->write_seq;
-               TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
+               tcp_init_nondata_skb(skb, tp->write_seq,
+                                    TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
                tcp_queue_skb(sk, skb);
        }
        __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF);
@@ -2116,16 +2112,9 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
 
        /* Reserve space for headers and prepare control bits. */
        skb_reserve(skb, MAX_TCP_HEADER);
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
-       TCP_SKB_CB(skb)->sacked = 0;
-       skb_shinfo(skb)->gso_segs = 1;
-       skb_shinfo(skb)->gso_size = 0;
-       skb_shinfo(skb)->gso_type = 0;
-
+       tcp_init_nondata_skb(skb, tcp_acceptable_seq(sk),
+                            TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
        /* Send it off. */
-       TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk);
-       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
        if (tcp_transmit_skb(sk, skb, 0, priority))
                NET_INC_STATS(LINUX_MIB_TCPABORTFAILED);
@@ -2138,14 +2127,14 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
  */
 int tcp_send_synack(struct sock *sk)
 {
-       struct sk_buffskb;
+       struct sk_buff *skb;
 
        skb = tcp_write_queue_head(sk);
-       if (skb == NULL || !(TCP_SKB_CB(skb)->flags&TCPCB_FLAG_SYN)) {
+       if (skb == NULL || !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN)) {
                printk(KERN_DEBUG "tcp_send_synack: wrong queue state\n");
                return -EFAULT;
        }
-       if (!(TCP_SKB_CB(skb)->flags&TCPCB_FLAG_ACK)) {
+       if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_ACK)) {
                if (skb_cloned(skb)) {
                        struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
                        if (nskb == NULL)
@@ -2153,8 +2142,9 @@ int tcp_send_synack(struct sock *sk)
                        tcp_unlink_write_queue(skb, sk);
                        skb_header_release(nskb);
                        __tcp_add_write_queue_head(sk, nskb);
-                       sk_stream_free_skb(sk, skb);
-                       sk_charge_skb(sk, nskb);
+                       sk_wmem_free_skb(sk, skb);
+                       sk->sk_wmem_queued += nskb->truesize;
+                       sk_mem_charge(sk, nskb->truesize);
                        skb = nskb;
                }
 
@@ -2168,8 +2158,8 @@ int tcp_send_synack(struct sock *sk)
 /*
  * Prepare a SYN-ACK.
  */
-struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
-                                struct request_sock *req)
+struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
+                               struct request_sock *req)
 {
        struct inet_request_sock *ireq = inet_rsk(req);
        struct tcp_sock *tp = tcp_sk(sk);
@@ -2212,12 +2202,11 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        TCP_ECN_make_synack(req, th);
        th->source = inet_sk(sk)->sport;
        th->dest = ireq->rmt_port;
-       TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn;
-       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
-       TCP_SKB_CB(skb)->sacked = 0;
-       skb_shinfo(skb)->gso_segs = 1;
-       skb_shinfo(skb)->gso_size = 0;
-       skb_shinfo(skb)->gso_type = 0;
+       /* Setting of flags are superfluous here for callers (and ECE is
+        * not even correctly set)
+        */
+       tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn,
+                            TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
        th->seq = htonl(TCP_SKB_CB(skb)->seq);
        th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
        if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
@@ -2249,7 +2238,6 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
                               NULL)
                              );
 
-       skb->csum = 0;
        th->doff = (tcp_header_size >> 2);
        TCP_INC_STATS(TCP_MIB_OUTSEGS);
 
@@ -2341,23 +2329,17 @@ int tcp_connect(struct sock *sk)
        /* Reserve space for headers. */
        skb_reserve(buff, MAX_TCP_HEADER);
 
-       TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
-       TCP_ECN_send_syn(sk, buff);
-       TCP_SKB_CB(buff)->sacked = 0;
-       skb_shinfo(buff)->gso_segs = 1;
-       skb_shinfo(buff)->gso_size = 0;
-       skb_shinfo(buff)->gso_type = 0;
-       buff->csum = 0;
        tp->snd_nxt = tp->write_seq;
-       TCP_SKB_CB(buff)->seq = tp->write_seq++;
-       TCP_SKB_CB(buff)->end_seq = tp->write_seq;
+       tcp_init_nondata_skb(buff, tp->write_seq++, TCPCB_FLAG_SYN);
+       TCP_ECN_send_syn(sk, buff);
 
        /* Send it off. */
        TCP_SKB_CB(buff)->when = tcp_time_stamp;
        tp->retrans_stamp = TCP_SKB_CB(buff)->when;
        skb_header_release(buff);
        __tcp_add_write_queue_tail(sk, buff);
-       sk_charge_skb(sk, buff);
+       sk->sk_wmem_queued += buff->truesize;
+       sk_mem_charge(sk, buff->truesize);
        tp->packets_out += tcp_skb_pcount(buff);
        tcp_transmit_skb(sk, buff, 1, GFP_KERNEL);
 
@@ -2386,9 +2368,10 @@ void tcp_send_delayed_ack(struct sock *sk)
 
        if (ato > TCP_DELACK_MIN) {
                const struct tcp_sock *tp = tcp_sk(sk);
-               int max_ato = HZ/2;
+               int max_ato = HZ / 2;
 
-               if (icsk->icsk_ack.pingpong || (icsk->icsk_ack.pending & ICSK_ACK_PUSHED))
+               if (icsk->icsk_ack.pingpong ||
+                   (icsk->icsk_ack.pending & ICSK_ACK_PUSHED))
                        max_ato = TCP_DELACK_MAX;
 
                /* Slow path, intersegment interval is "high". */
@@ -2398,7 +2381,7 @@ void tcp_send_delayed_ack(struct sock *sk)
                 * directly.
                 */
                if (tp->srtt) {
-                       int rtt = max(tp->srtt>>3, TCP_DELACK_MIN);
+                       int rtt = max(tp->srtt >> 3, TCP_DELACK_MIN);
 
                        if (rtt < max_ato)
                                max_ato = rtt;
@@ -2432,37 +2415,32 @@ void tcp_send_delayed_ack(struct sock *sk)
 /* This routine sends an ack and also updates the window. */
 void tcp_send_ack(struct sock *sk)
 {
-       /* If we have been reset, we may not send again. */
-       if (sk->sk_state != TCP_CLOSE) {
-               struct sk_buff *buff;
+       struct sk_buff *buff;
 
-               /* We are not putting this on the write queue, so
-                * tcp_transmit_skb() will set the ownership to this
-                * sock.
-                */
-               buff = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC);
-               if (buff == NULL) {
-                       inet_csk_schedule_ack(sk);
-                       inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
-                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
-                                                 TCP_DELACK_MAX, TCP_RTO_MAX);
-                       return;
-               }
+       /* If we have been reset, we may not send again. */
+       if (sk->sk_state == TCP_CLOSE)
+               return;
 
-               /* Reserve space for headers and prepare control bits. */
-               skb_reserve(buff, MAX_TCP_HEADER);
-               buff->csum = 0;
-               TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
-               TCP_SKB_CB(buff)->sacked = 0;
-               skb_shinfo(buff)->gso_segs = 1;
-               skb_shinfo(buff)->gso_size = 0;
-               skb_shinfo(buff)->gso_type = 0;
-
-               /* Send it off, this clears delayed acks for us. */
-               TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk);
-               TCP_SKB_CB(buff)->when = tcp_time_stamp;
-               tcp_transmit_skb(sk, buff, 0, GFP_ATOMIC);
+       /* We are not putting this on the write queue, so
+        * tcp_transmit_skb() will set the ownership to this
+        * sock.
+        */
+       buff = alloc_skb(MAX_TCP_HEADER, GFP_ATOMIC);
+       if (buff == NULL) {
+               inet_csk_schedule_ack(sk);
+               inet_csk(sk)->icsk_ack.ato = TCP_ATO_MIN;
+               inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+                                         TCP_DELACK_MAX, TCP_RTO_MAX);
+               return;
        }
+
+       /* Reserve space for headers and prepare control bits. */
+       skb_reserve(buff, MAX_TCP_HEADER);
+       tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPCB_FLAG_ACK);
+
+       /* Send it off, this clears delayed acks for us. */
+       TCP_SKB_CB(buff)->when = tcp_time_stamp;
+       tcp_transmit_skb(sk, buff, 0, GFP_ATOMIC);
 }
 
 /* This routine sends a packet with an out of date sequence
@@ -2488,66 +2466,57 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent)
 
        /* Reserve space for headers and set control bits. */
        skb_reserve(skb, MAX_TCP_HEADER);
-       skb->csum = 0;
-       TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
-       TCP_SKB_CB(skb)->sacked = urgent;
-       skb_shinfo(skb)->gso_segs = 1;
-       skb_shinfo(skb)->gso_size = 0;
-       skb_shinfo(skb)->gso_type = 0;
-
        /* Use a previous sequence.  This should cause the other
         * end to send an ack.  Don't queue or clone SKB, just
         * send it.
         */
-       TCP_SKB_CB(skb)->seq = urgent ? tp->snd_una : tp->snd_una - 1;
-       TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
+       tcp_init_nondata_skb(skb, tp->snd_una - !urgent, TCPCB_FLAG_ACK);
        TCP_SKB_CB(skb)->when = tcp_time_stamp;
        return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
 }
 
 int tcp_write_wakeup(struct sock *sk)
 {
-       if (sk->sk_state != TCP_CLOSE) {
-               struct tcp_sock *tp = tcp_sk(sk);
-               struct sk_buff *skb;
-
-               if ((skb = tcp_send_head(sk)) != NULL &&
-                   before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)) {
-                       int err;
-                       unsigned int mss = tcp_current_mss(sk, 0);
-                       unsigned int seg_size = tp->snd_una+tp->snd_wnd-TCP_SKB_CB(skb)->seq;
-
-                       if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq))
-                               tp->pushed_seq = TCP_SKB_CB(skb)->end_seq;
-
-                       /* We are probing the opening of a window
-                        * but the window size is != 0
-                        * must have been a result SWS avoidance ( sender )
-                        */
-                       if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
-                           skb->len > mss) {
-                               seg_size = min(seg_size, mss);
-                               TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-                               if (tcp_fragment(sk, skb, seg_size, mss))
-                                       return -1;
-                       } else if (!tcp_skb_pcount(skb))
-                               tcp_set_skb_tso_segs(sk, skb, mss);
+       struct tcp_sock *tp = tcp_sk(sk);
+       struct sk_buff *skb;
 
+       if (sk->sk_state == TCP_CLOSE)
+               return -1;
+
+       if ((skb = tcp_send_head(sk)) != NULL &&
+           before(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp))) {
+               int err;
+               unsigned int mss = tcp_current_mss(sk, 0);
+               unsigned int seg_size = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
+
+               if (before(tp->pushed_seq, TCP_SKB_CB(skb)->end_seq))
+                       tp->pushed_seq = TCP_SKB_CB(skb)->end_seq;
+
+               /* We are probing the opening of a window
+                * but the window size is != 0
+                * must have been a result SWS avoidance ( sender )
+                */
+               if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
+                   skb->len > mss) {
+                       seg_size = min(seg_size, mss);
                        TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-                       TCP_SKB_CB(skb)->when = tcp_time_stamp;
-                       err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
-                       if (!err) {
-                               update_send_head(sk, skb);
-                       }
-                       return err;
-               } else {
-                       if (tp->urg_mode &&
-                           between(tp->snd_up, tp->snd_una+1, tp->snd_una+0xFFFF))
-                               tcp_xmit_probe_skb(sk, TCPCB_URG);
-                       return tcp_xmit_probe_skb(sk, 0);
-               }
+                       if (tcp_fragment(sk, skb, seg_size, mss))
+                               return -1;
+               } else if (!tcp_skb_pcount(skb))
+                       tcp_set_skb_tso_segs(sk, skb, mss);
+
+               TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
+               TCP_SKB_CB(skb)->when = tcp_time_stamp;
+               err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+               if (!err)
+                       tcp_event_new_data_sent(sk, skb);
+               return err;
+       } else {
+               if (tp->urg_mode &&
+                   between(tp->snd_up, tp->snd_una + 1, tp->snd_una + 0xFFFF))
+                       tcp_xmit_probe_skb(sk, 1);
+               return tcp_xmit_probe_skb(sk, 0);
        }
-       return -1;
 }
 
 /* A window probe timeout has occurred.  If window is not closed send
index be27a33a1c68dcad4235b7fb4ee4ac4286166dd6..2747ec7bfb63e885fdc286836f41f5e157f6ded8 100644 (file)
@@ -15,8 +15,7 @@
 #define TCP_SCALABLE_AI_CNT    50U
 #define TCP_SCALABLE_MD_SCALE  3
 
-static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack,
-                                   u32 in_flight, int flag)
+static void tcp_scalable_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
index d8970ecfcfc892dd35667dfe540e67e9d49bad30..803d758a2b124f0301f9dae7dbbd750722acf5e9 100644 (file)
@@ -114,13 +114,31 @@ static int tcp_orphan_retries(struct sock *sk, int alive)
        return retries;
 }
 
+static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk)
+{
+       /* Black hole detection */
+       if (sysctl_tcp_mtu_probing) {
+               if (!icsk->icsk_mtup.enabled) {
+                       icsk->icsk_mtup.enabled = 1;
+                       tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
+               } else {
+                       struct tcp_sock *tp = tcp_sk(sk);
+                       int mss;
+
+                       mss = tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low) >> 1;
+                       mss = min(sysctl_tcp_base_mss, mss);
+                       mss = max(mss, 68 - tp->tcp_header_len);
+                       icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
+                       tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
+               }
+       }
+}
+
 /* A write timeout has occurred. Process the after effects. */
 static int tcp_write_timeout(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
-       struct tcp_sock *tp = tcp_sk(sk);
        int retry_until;
-       int mss;
 
        if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) {
                if (icsk->icsk_retransmits)
@@ -129,18 +147,7 @@ static int tcp_write_timeout(struct sock *sk)
        } else {
                if (icsk->icsk_retransmits >= sysctl_tcp_retries1) {
                        /* Black hole detection */
-                       if (sysctl_tcp_mtu_probing) {
-                               if (!icsk->icsk_mtup.enabled) {
-                                       icsk->icsk_mtup.enabled = 1;
-                                       tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
-                               } else {
-                                       mss = min(sysctl_tcp_base_mss,
-                                                 tcp_mtu_to_mss(sk, icsk->icsk_mtup.search_low)/2);
-                                       mss = max(mss, 68 - tp->tcp_header_len);
-                                       icsk->icsk_mtup.search_low = tcp_mss_to_mtu(sk, mss);
-                                       tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
-                               }
-                       }
+                       tcp_mtu_probing(icsk, sk);
 
                        dst_negative_advice(&sk->sk_dst_cache);
                }
@@ -179,7 +186,7 @@ static void tcp_delack_timer(unsigned long data)
                goto out_unlock;
        }
 
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim_partial(sk);
 
        if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
                goto out;
@@ -219,7 +226,7 @@ static void tcp_delack_timer(unsigned long data)
 
 out:
        if (tcp_memory_pressure)
-               sk_stream_mem_reclaim(sk);
+               sk_mem_reclaim(sk);
 out_unlock:
        bh_unlock_sock(sk);
        sock_put(sk);
@@ -413,7 +420,7 @@ static void tcp_write_timer(unsigned long data)
        TCP_CHECK_TIMER(sk);
 
 out:
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 out_unlock:
        bh_unlock_sock(sk);
        sock_put(sk);
@@ -507,7 +514,7 @@ static void tcp_keepalive_timer (unsigned long data)
        }
 
        TCP_CHECK_TIMER(sk);
-       sk_stream_mem_reclaim(sk);
+       sk_mem_reclaim(sk);
 
 resched:
        inet_csk_reset_keepalive_timer (sk, elapsed);
index 007304e99842f700da8d4ff7ffab7ac37fddd28c..be24d6ee34bd7be9af38ceaeda87b8ec5744ea9a 100644 (file)
@@ -162,14 +162,13 @@ void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 }
 EXPORT_SYMBOL_GPL(tcp_vegas_cwnd_event);
 
-static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
-                                u32 in_flight, int flag)
+static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct vegas *vegas = inet_csk_ca(sk);
 
        if (!vegas->doing_vegas_now)
-               return tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+               return tcp_reno_cong_avoid(sk, ack, in_flight);
 
        /* The key players are v_beg_snd_una and v_beg_snd_nxt.
         *
@@ -228,7 +227,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack,
                        /* We don't have enough RTT samples to do the Vegas
                         * calculation, so we'll behave like Reno.
                         */
-                       tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+                       tcp_reno_cong_avoid(sk, ack, in_flight);
                } else {
                        u32 rtt, target_cwnd, diff;
 
index 8fb2aee0b1a408171f43fd9e7b4d4987c6cc5f08..d16689e9851620a44944c397989004bc447411ef 100644 (file)
@@ -114,14 +114,13 @@ static void tcp_veno_cwnd_event(struct sock *sk, enum tcp_ca_event event)
                tcp_veno_init(sk);
 }
 
-static void tcp_veno_cong_avoid(struct sock *sk, u32 ack,
-                               u32 in_flight, int flag)
+static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct veno *veno = inet_csk_ca(sk);
 
        if (!veno->doing_veno_now)
-               return tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+               return tcp_reno_cong_avoid(sk, ack, in_flight);
 
        /* limited by applications */
        if (!tcp_is_cwnd_limited(sk, in_flight))
@@ -132,7 +131,7 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack,
                /* We don't have enough rtt samples to do the Veno
                 * calculation, so we'll behave like Reno.
                 */
-               tcp_reno_cong_avoid(sk, ack, in_flight, flag);
+               tcp_reno_cong_avoid(sk, ack, in_flight);
        } else {
                u32 rtt, target_cwnd;
 
index c107fba7430e6c824c6aff448d0bdaf01e09eb8d..e03b10183a8b86810cc7f33d4bc69815d3c05f7f 100644 (file)
@@ -69,8 +69,7 @@ static void tcp_yeah_pkts_acked(struct sock *sk, u32 pkts_acked, s32 rtt_us)
        tcp_vegas_pkts_acked(sk, pkts_acked, rtt_us);
 }
 
-static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack,
-                               u32 in_flight, int flag)
+static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct yeah *yeah = inet_csk_ca(sk);
index 03c400ca14c5af07db1ab22686d95621b5cc8813..2fb8d731026b7c325288a4966e7f6f08a95392a8 100644 (file)
@@ -82,6 +82,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
+#include <linux/bootmem.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/module.h>
  */
 
 DEFINE_SNMP_STAT(struct udp_mib, udp_statistics) __read_mostly;
+EXPORT_SYMBOL(udp_statistics);
+
+DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
+EXPORT_SYMBOL(udp_stats_in6);
 
 struct hlist_head udp_hash[UDP_HTABLE_SIZE];
 DEFINE_RWLOCK(udp_hash_lock);
 
+int sysctl_udp_mem[3] __read_mostly;
+int sysctl_udp_rmem_min __read_mostly;
+int sysctl_udp_wmem_min __read_mostly;
+
+EXPORT_SYMBOL(sysctl_udp_mem);
+EXPORT_SYMBOL(sysctl_udp_rmem_min);
+EXPORT_SYMBOL(sysctl_udp_wmem_min);
+
+atomic_t udp_memory_allocated;
+EXPORT_SYMBOL(udp_memory_allocated);
+
 static inline int __udp_lib_lport_inuse(__u16 num,
                                        const struct hlist_head udptable[])
 {
@@ -214,7 +230,7 @@ gotit:
        if (sk_unhashed(sk)) {
                head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
                sk_add_node(sk, head);
-               sock_prot_inc_use(sk->sk_prot);
+               sock_prot_inuse_add(sk->sk_prot, 1);
        }
        error = 0;
 fail:
@@ -402,7 +418,7 @@ out:
 
 void udp_err(struct sk_buff *skb, u32 info)
 {
-       return __udp4_lib_err(skb, info, udp_hash);
+       __udp4_lib_err(skb, info, udp_hash);
 }
 
 /*
@@ -471,6 +487,7 @@ static int udp_push_pending_frames(struct sock *sk)
        struct sk_buff *skb;
        struct udphdr *uh;
        int err = 0;
+       int is_udplite = IS_UDPLITE(sk);
        __wsum csum = 0;
 
        /* Grab the skbuff where UDP header space exists. */
@@ -486,7 +503,7 @@ static int udp_push_pending_frames(struct sock *sk)
        uh->len = htons(up->len);
        uh->check = 0;
 
-       if (up->pcflag)                                  /*     UDP-Lite      */
+       if (is_udplite)                                  /*     UDP-Lite      */
                csum  = udplite_csum_outgoing(sk, skb);
 
        else if (sk->sk_no_check == UDP_CSUM_NOXMIT) {   /* UDP csum disabled */
@@ -514,7 +531,7 @@ out:
        up->len = 0;
        up->pending = 0;
        if (!err)
-               UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, up->pcflag);
+               UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
        return err;
 }
 
@@ -531,7 +548,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        __be32 daddr, faddr, saddr;
        __be16 dport;
        u8  tos;
-       int err, is_udplite = up->pcflag;
+       int err, is_udplite = IS_UDPLITE(sk);
        int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
        int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 
@@ -621,7 +638,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                connected = 0;
        }
 
-       if (MULTICAST(daddr)) {
+       if (ipv4_is_multicast(daddr)) {
                if (!ipc.oif)
                        ipc.oif = inet->mc_index;
                if (!saddr)
@@ -643,7 +660,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
                security_sk_classify_flow(sk, &fl);
-               err = ip_route_output_flow(&rt, &fl, sk, 1);
+               err = ip_route_output_flow(&init_net, &rt, &fl, sk, 1);
                if (err) {
                        if (err == -ENETUNREACH)
                                IP_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES);
@@ -825,6 +842,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
        struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
        struct sk_buff *skb;
        unsigned int ulen, copied;
+       int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
 
@@ -838,7 +856,8 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                return ip_recv_error(sk, msg, len);
 
 try_again:
-       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+                                 &peeked, &err);
        if (!skb)
                goto out;
 
@@ -873,6 +892,9 @@ try_again:
        if (err)
                goto out_free;
 
+       if (!peeked)
+               UDP_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);
+
        sock_recv_timestamp(msg, sk, skb);
 
        /* Copy the address. */
@@ -891,14 +913,17 @@ try_again:
                err = ulen;
 
 out_free:
+       lock_sock(sk);
        skb_free_datagram(sk, skb);
+       release_sock(sk);
 out:
        return err;
 
 csum_copy_err:
-       UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
-
-       skb_kill_datagram(sk, skb, flags);
+       lock_sock(sk);
+       if (!skb_kill_datagram(sk, skb, flags))
+               UDP_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
+       release_sock(sk);
 
        if (noblock)
                return -EAGAIN;
@@ -940,6 +965,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
        struct udp_sock *up = udp_sk(sk);
        int rc;
+       int is_udplite = IS_UDPLITE(sk);
 
        /*
         *      Charge it to the socket, dropping if the queue is full.
@@ -967,7 +993,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 
                        ret = (*up->encap_rcv)(sk, skb);
                        if (ret <= 0) {
-                               UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
+                               UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS,
+                                                is_udplite);
                                return -ret;
                        }
                }
@@ -978,7 +1005,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        /*
         *      UDP-Lite specific tests, ignored on UDP sockets
         */
-       if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+       if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
 
                /*
                 * MIB statistics other than incrementing the error count are
@@ -1019,15 +1046,14 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
                /* Note that an ENOMEM error is charged twice */
                if (rc == -ENOMEM)
-                       UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, up->pcflag);
+                       UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
                goto drop;
        }
 
-       UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
        return 0;
 
 drop:
-       UDP_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
+       UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
        kfree_skb(skb);
        return -1;
 }
@@ -1062,7 +1088,15 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
                                skb1 = skb_clone(skb, GFP_ATOMIC);
 
                        if (skb1) {
-                               int ret = udp_queue_rcv_skb(sk, skb1);
+                               int ret = 0;
+
+                               bh_lock_sock_nested(sk);
+                               if (!sock_owned_by_user(sk))
+                                       ret = udp_queue_rcv_skb(sk, skb1);
+                               else
+                                       sk_add_backlog(sk, skb1);
+                               bh_unlock_sock(sk);
+
                                if (ret > 0)
                                        /* we should probably re-process instead
                                         * of dropping packets here. */
@@ -1155,7 +1189,13 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
                               inet_iif(skb), udptable);
 
        if (sk != NULL) {
-               int ret = udp_queue_rcv_skb(sk, skb);
+               int ret = 0;
+               bh_lock_sock_nested(sk);
+               if (!sock_owned_by_user(sk))
+                       ret = udp_queue_rcv_skb(sk, skb);
+               else
+                       sk_add_backlog(sk, skb);
+               bh_unlock_sock(sk);
                sock_put(sk);
 
                /* a return value > 0 means to resubmit the input, but
@@ -1236,6 +1276,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
        struct udp_sock *up = udp_sk(sk);
        int val;
        int err = 0;
+       int is_udplite = IS_UDPLITE(sk);
 
        if (optlen<sizeof(int))
                return -EINVAL;
@@ -1277,7 +1318,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
        /* The sender sets actual checksum coverage length via this option.
         * The case coverage > packet length is handled by send module. */
        case UDPLITE_SEND_CSCOV:
-               if (!up->pcflag)         /* Disable the option on UDP sockets */
+               if (!is_udplite)         /* Disable the option on UDP sockets */
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
                        val = 8;
@@ -1289,7 +1330,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
         * sense, this should be set to at least 8 (as done below). If zero is
         * used, this again means full checksum coverage.                     */
        case UDPLITE_RECV_CSCOV:
-               if (!up->pcflag)         /* Disable the option on UDP sockets */
+               if (!is_udplite)         /* Disable the option on UDP sockets */
                        return -ENOPROTOOPT;
                if (val != 0 && val < 8) /* Avoid silly minimal values.       */
                        val = 8;
@@ -1449,6 +1490,10 @@ struct proto udp_prot = {
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v4_get_port,
+       .memory_allocated  = &udp_memory_allocated,
+       .sysctl_mem        = sysctl_udp_mem,
+       .sysctl_wmem       = &sysctl_udp_wmem_min,
+       .sysctl_rmem       = &sysctl_udp_rmem_min,
        .obj_size          = sizeof(struct udp_sock),
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udp_setsockopt,
@@ -1505,6 +1550,7 @@ static struct sock *udp_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(udp_hash_lock)
 {
        read_lock(&udp_hash_lock);
        return *pos ? udp_get_idx(seq, *pos-1) : (void *)1;
@@ -1524,6 +1570,7 @@ static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void udp_seq_stop(struct seq_file *seq, void *v)
+       __releases(udp_hash_lock)
 {
        read_unlock(&udp_hash_lock);
 }
@@ -1644,6 +1691,25 @@ void udp4_proc_exit(void)
 }
 #endif /* CONFIG_PROC_FS */
 
+void __init udp_init(void)
+{
+       unsigned long limit;
+
+       /* Set the pressure threshold up by the same strategy of TCP. It is a
+        * fraction of global memory that is up to 1/2 at 256 MB, decreasing
+        * toward zero with the amount of memory, with a floor of 128 pages.
+        */
+       limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+       limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+       limit = max(limit, 128UL);
+       sysctl_udp_mem[0] = limit / 4 * 3;
+       sysctl_udp_mem[1] = limit;
+       sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2;
+
+       sysctl_udp_rmem_min = SK_MEM_QUANTUM;
+       sysctl_udp_wmem_min = SK_MEM_QUANTUM;
+}
+
 EXPORT_SYMBOL(udp_disconnect);
 EXPORT_SYMBOL(udp_hash);
 EXPORT_SYMBOL(udp_hash_lock);
index f5baeb3e8b85d368e075cd57ca7cd8c48b68702b..001b881ca36fa5e543bcac52fed1b43f36013068 100644 (file)
@@ -35,7 +35,7 @@ static int udplite_rcv(struct sk_buff *skb)
 
 static void udplite_err(struct sk_buff *skb, u32 info)
 {
-       return __udp4_lib_err(skb, info, udplite_hash);
+       __udp4_lib_err(skb, info, udplite_hash);
 }
 
 static struct net_protocol udplite_protocol = {
index 5e95c8a07efbad59809f5370c62b317b58e1fe9c..390dcb1354a5e4f6c76ad0c9bf8d3bc238a217ab 100644 (file)
 #include <net/ip.h>
 #include <net/xfrm.h>
 
-#ifdef CONFIG_NETFILTER
+int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       return xfrm4_extract_header(skb);
+}
+
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
        if (skb->dst == NULL) {
@@ -31,129 +35,35 @@ drop:
        kfree_skb(skb);
        return NET_RX_DROP;
 }
-#endif
 
 int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
                    int encap_type)
 {
-       int err;
-       __be32 seq;
-       struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-       struct xfrm_state *x;
-       int xfrm_nr = 0;
-       int decaps = 0;
-       unsigned int nhoff = offsetof(struct iphdr, protocol);
-
-       seq = 0;
-       if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
-               goto drop;
-
-       do {
-               const struct iphdr *iph = ip_hdr(skb);
-
-               if (xfrm_nr == XFRM_MAX_DEPTH)
-                       goto drop;
-
-               x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-                                     nexthdr, AF_INET);
-               if (x == NULL)
-                       goto drop;
-
-               spin_lock(&x->lock);
-               if (unlikely(x->km.state != XFRM_STATE_VALID))
-                       goto drop_unlock;
-
-               if ((x->encap ? x->encap->encap_type : 0) != encap_type)
-                       goto drop_unlock;
-
-               if (x->props.replay_window && xfrm_replay_check(x, seq))
-                       goto drop_unlock;
-
-               if (xfrm_state_check_expire(x))
-                       goto drop_unlock;
-
-               nexthdr = x->type->input(x, skb);
-               if (nexthdr <= 0)
-                       goto drop_unlock;
-
-               skb_network_header(skb)[nhoff] = nexthdr;
-
-               /* only the first xfrm gets the encap type */
-               encap_type = 0;
-
-               if (x->props.replay_window)
-                       xfrm_replay_advance(x, seq);
-
-               x->curlft.bytes += skb->len;
-               x->curlft.packets++;
-
-               spin_unlock(&x->lock);
-
-               xfrm_vec[xfrm_nr++] = x;
-
-               if (x->outer_mode->input(x, skb))
-                       goto drop;
-
-               if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-                       decaps = 1;
-                       break;
-               }
-
-               err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
-               if (err < 0)
-                       goto drop;
-       } while (!err);
-
-       /* Allocate new secpath or COW existing one. */
-
-       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-               struct sec_path *sp;
-               sp = secpath_dup(skb->sp);
-               if (!sp)
-                       goto drop;
-               if (skb->sp)
-                       secpath_put(skb->sp);
-               skb->sp = sp;
-       }
-       if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-               goto drop;
-
-       memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-              xfrm_nr * sizeof(xfrm_vec[0]));
-       skb->sp->len += xfrm_nr;
+       XFRM_SPI_SKB_CB(skb)->family = AF_INET;
+       XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
+       return xfrm_input(skb, nexthdr, spi, encap_type);
+}
+EXPORT_SYMBOL(xfrm4_rcv_encap);
 
-       nf_reset(skb);
+int xfrm4_transport_finish(struct sk_buff *skb, int async)
+{
+       struct iphdr *iph = ip_hdr(skb);
 
-       if (decaps) {
-               dst_release(skb->dst);
-               skb->dst = NULL;
-               netif_rx(skb);
-               return 0;
-       } else {
-#ifdef CONFIG_NETFILTER
-               __skb_push(skb, skb->data - skb_network_header(skb));
-               ip_hdr(skb)->tot_len = htons(skb->len);
-               ip_send_check(ip_hdr(skb));
+       iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
 
-               NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
-                       xfrm4_rcv_encap_finish);
-               return 0;
-#else
-               return -ip_hdr(skb)->protocol;
+#ifndef CONFIG_NETFILTER
+       if (!async)
+               return -iph->protocol;
 #endif
-       }
 
-drop_unlock:
-       spin_unlock(&x->lock);
-       xfrm_state_put(x);
-drop:
-       while (--xfrm_nr >= 0)
-               xfrm_state_put(xfrm_vec[xfrm_nr]);
+       __skb_push(skb, skb->data - skb_network_header(skb));
+       iph->tot_len = htons(skb->len);
+       ip_send_check(iph);
 
-       kfree_skb(skb);
+       NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+               xfrm4_rcv_encap_finish);
        return 0;
 }
-EXPORT_SYMBOL(xfrm4_rcv_encap);
 
 /* If it's a keepalive packet, then just eat it.
  * If it's an encapsulated packet, then pass it to the
index e42e122414be1e461c01898aff091f405b48dfa2..e093a7b59e18af38cf918aed2754159cf68db8fd 100644 (file)
 #include <net/ip.h>
 #include <net/xfrm.h>
 
+static void xfrm4_beet_make_header(struct sk_buff *skb)
+{
+       struct iphdr *iph = ip_hdr(skb);
+
+       iph->ihl = 5;
+       iph->version = 4;
+
+       iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
+       iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
+
+       iph->id = XFRM_MODE_SKB_CB(skb)->id;
+       iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
+       iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
+}
+
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
@@ -40,10 +55,12 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
                          offsetof(struct iphdr, protocol);
        skb->transport_header = skb->network_header + sizeof(*iph);
 
+       xfrm4_beet_make_header(skb);
+
        ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
 
        top_iph = ip_hdr(skb);
-       memmove(top_iph, iph, sizeof(*iph));
+
        if (unlikely(optlen)) {
                BUG_ON(optlen < 0);
 
@@ -65,43 +82,46 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 
 static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct iphdr *iph = ip_hdr(skb);
-       int phlen = 0;
+       struct iphdr *iph;
        int optlen = 0;
-       u8 ph_nexthdr = 0;
        int err = -EINVAL;
 
-       if (unlikely(iph->protocol == IPPROTO_BEETPH)) {
+       if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) {
                struct ip_beet_phdr *ph;
+               int phlen;
 
                if (!pskb_may_pull(skb, sizeof(*ph)))
                        goto out;
-               ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);
+
+               ph = (struct ip_beet_phdr *)skb->data;
 
                phlen = sizeof(*ph) + ph->padlen;
                optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
                if (optlen < 0 || optlen & 3 || optlen > 250)
                        goto out;
 
-               if (!pskb_may_pull(skb, phlen + optlen))
-                       goto out;
-               skb->len -= phlen + optlen;
+               XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
 
-               ph_nexthdr = ph->nexthdr;
+               if (!pskb_may_pull(skb, phlen));
+                       goto out;
+               __skb_pull(skb, phlen);
        }
 
-       skb_set_network_header(skb, phlen - sizeof(*iph));
-       memmove(skb_network_header(skb), iph, sizeof(*iph));
-       skb_set_transport_header(skb, phlen + optlen);
-       skb->data = skb_transport_header(skb);
+       skb_push(skb, sizeof(*iph));
+       skb_reset_network_header(skb);
+
+       memmove(skb->data - skb->mac_len, skb_mac_header(skb),
+               skb->mac_len);
+       skb_set_mac_header(skb, -skb->mac_len);
+
+       xfrm4_beet_make_header(skb);
 
        iph = ip_hdr(skb);
-       iph->ihl = (sizeof(*iph) + optlen) / 4;
-       iph->tot_len = htons(skb->len + iph->ihl * 4);
+
+       iph->ihl += optlen / 4;
+       iph->tot_len = htons(skb->len);
        iph->daddr = x->sel.daddr.a4;
        iph->saddr = x->sel.saddr.a4;
-       if (ph_nexthdr)
-               iph->protocol = ph_nexthdr;
        iph->check = 0;
        iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
        err = 0;
@@ -110,8 +130,10 @@ out:
 }
 
 static struct xfrm_mode xfrm4_beet_mode = {
-       .input = xfrm4_beet_input,
-       .output = xfrm4_beet_output,
+       .input2 = xfrm4_beet_input,
+       .input = xfrm_prepare_input,
+       .output2 = xfrm4_beet_output,
+       .output = xfrm4_prepare_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
        .flags = XFRM_MODE_FLAG_TUNNEL,
index e4deecba6dd216d546706f57e3e557123af52c71..8dee617ee900662ddac773b7350fe0cc23745692 100644 (file)
 
 static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
 {
-       struct iphdr *outer_iph = ip_hdr(skb);
        struct iphdr *inner_iph = ipip_hdr(skb);
 
-       if (INET_ECN_is_ce(outer_iph->tos))
+       if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
                IP_ECN_set_ce(inner_iph);
 }
 
-static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
-{
-       if (INET_ECN_is_ce(iph->tos))
-               IP6_ECN_set_ce(ipv6_hdr(skb));
-}
-
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per RFC 2401.
  */
-static int xfrm4_tunnel_output(struct xfrm_state *x, 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 xfrm_dst *xdst = (struct xfrm_dst*)dst;
-       struct iphdr *iph, *top_iph;
+       struct iphdr *top_iph;
        int flags;
 
-       iph = ip_hdr(skb);
-
        skb_set_network_header(skb, -x->props.header_len);
        skb->mac_header = skb->network_header +
                          offsetof(struct iphdr, protocol);
-       skb->transport_header = skb->network_header + sizeof(*iph);
+       skb->transport_header = skb->network_header + sizeof(*top_iph);
        top_iph = ip_hdr(skb);
 
        top_iph->ihl = 5;
        top_iph->version = 4;
 
-       flags = x->props.flags;
+       top_iph->protocol = x->inner_mode->afinfo->proto;
 
        /* DS disclosed */
-       if (xdst->route->ops->family == AF_INET) {
-               top_iph->protocol = IPPROTO_IPIP;
-               top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
-               top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
-                       0 : (iph->frag_off & htons(IP_DF));
-       }
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-       else {
-               struct ipv6hdr *ipv6h = (struct ipv6hdr*)iph;
-               top_iph->protocol = IPPROTO_IPV6;
-               top_iph->tos = INET_ECN_encapsulate(iph->tos, ipv6_get_dsfield(ipv6h));
-               top_iph->frag_off = 0;
-       }
-#endif
+       top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
+                                           XFRM_MODE_SKB_CB(skb)->tos);
 
+       flags = x->props.flags;
        if (flags & XFRM_STATE_NOECN)
                IP_ECN_clear(top_iph);
 
-       if (!top_iph->frag_off)
-               __ip_select_ident(top_iph, dst->child, 0);
+       top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
+                           0 : XFRM_MODE_SKB_CB(skb)->frag_off;
+       ip_select_ident(top_iph, dst->child, NULL);
 
        top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
 
        top_iph->saddr = x->props.saddr.a4;
        top_iph->daddr = x->id.daddr.a4;
 
-       skb->protocol = htons(ETH_P_IP);
-
-       memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
        return 0;
 }
 
-static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
+static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct iphdr *iph = ip_hdr(skb);
        const unsigned char *old_mac;
        int err = -EINVAL;
 
-       switch (iph->protocol){
-               case IPPROTO_IPIP:
-                       break;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-               case IPPROTO_IPV6:
-                       break;
-#endif
-               default:
-                       goto out;
-       }
+       if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
+               goto out;
 
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
                goto out;
@@ -110,20 +78,11 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
            (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
                goto out;
 
-       iph = ip_hdr(skb);
-       if (iph->protocol == IPPROTO_IPIP) {
-               if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-                       ipv4_copy_dscp(iph, ipip_hdr(skb));
-               if (!(x->props.flags & XFRM_STATE_NOECN))
-                       ipip_ecn_decapsulate(skb);
-       }
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-       else {
-               if (!(x->props.flags & XFRM_STATE_NOECN))
-                       ipip6_ecn_decapsulate(iph, skb);
-               skb->protocol = htons(ETH_P_IPV6);
-       }
-#endif
+       if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+               ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
+       if (!(x->props.flags & XFRM_STATE_NOECN))
+               ipip_ecn_decapsulate(skb);
+
        old_mac = skb_mac_header(skb);
        skb_set_mac_header(skb, -skb->mac_len);
        memmove(skb_mac_header(skb), old_mac, skb->mac_len);
@@ -135,19 +94,21 @@ out:
 }
 
 static struct xfrm_mode xfrm4_tunnel_mode = {
-       .input = xfrm4_tunnel_input,
-       .output = xfrm4_tunnel_output,
+       .input2 = xfrm4_mode_tunnel_input,
+       .input = xfrm_prepare_input,
+       .output2 = xfrm4_mode_tunnel_output,
+       .output = xfrm4_prepare_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
        .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
-static int __init xfrm4_tunnel_init(void)
+static int __init xfrm4_mode_tunnel_init(void)
 {
        return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET);
 }
 
-static void __exit xfrm4_tunnel_exit(void)
+static void __exit xfrm4_mode_tunnel_exit(void)
 {
        int err;
 
@@ -155,7 +116,7 @@ static void __exit xfrm4_tunnel_exit(void)
        BUG_ON(err);
 }
 
-module_init(xfrm4_tunnel_init);
-module_exit(xfrm4_tunnel_exit);
+module_init(xfrm4_mode_tunnel_init);
+module_exit(xfrm4_mode_tunnel_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_XFRM_MODE(AF_INET, XFRM_MODE_TUNNEL);
index c4a7156962bd58797d93b7c21051bcc797c98de9..d5a58a8180210a0ffdef8fce568426f448d223a8 100644 (file)
@@ -8,11 +8,12 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/compiler.h>
 #include <linux/if_ether.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4.h>
+#include <net/dst.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/icmp.h>
@@ -25,8 +26,6 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
        if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE)
                goto out;
 
-       IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
-
        if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
                goto out;
 
@@ -40,106 +39,54 @@ out:
        return ret;
 }
 
-static inline int xfrm4_output_one(struct sk_buff *skb)
+int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
-       struct xfrm_state *x = dst->xfrm;
-       struct iphdr *iph;
        int err;
 
-       if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-               err = xfrm4_tunnel_check_size(skb);
-               if (err)
-                       goto error_nolock;
-       }
-
-       err = xfrm_output(skb);
+       err = xfrm4_tunnel_check_size(skb);
        if (err)
-               goto error_nolock;
+               return err;
 
-       iph = ip_hdr(skb);
-       iph->tot_len = htons(skb->len);
-       ip_send_check(iph);
+       XFRM_MODE_SKB_CB(skb)->protocol = ip_hdr(skb)->protocol;
 
-       IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
-       err = 0;
-
-out_exit:
-       return err;
-error_nolock:
-       kfree_skb(skb);
-       goto out_exit;
+       return xfrm4_extract_header(skb);
 }
 
-static int xfrm4_output_finish2(struct sk_buff *skb)
+int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
 
-       while (likely((err = xfrm4_output_one(skb)) == 0)) {
-               nf_reset(skb);
-
-               err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
-                             skb->dst->dev, dst_output);
-               if (unlikely(err != 1))
-                       break;
+       err = x->inner_mode->afinfo->extract_output(x, skb);
+       if (err)
+               return err;
 
-               if (!skb->dst->xfrm)
-                       return dst_output(skb);
+       memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+       IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED;
 
-               err = nf_hook(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
-                             skb->dst->dev, xfrm4_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
+       skb->protocol = htons(ETH_P_IP);
 
-       return err;
+       return x->outer_mode->output2(x, skb);
 }
+EXPORT_SYMBOL(xfrm4_prepare_output);
 
 static int xfrm4_output_finish(struct sk_buff *skb)
 {
-       struct sk_buff *segs;
-
 #ifdef CONFIG_NETFILTER
        if (!skb->dst->xfrm) {
                IPCB(skb)->flags |= IPSKB_REROUTED;
                return dst_output(skb);
        }
-#endif
 
-       if (!skb_is_gso(skb))
-               return xfrm4_output_finish2(skb);
+       IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
+#endif
 
        skb->protocol = htons(ETH_P_IP);
-       segs = skb_gso_segment(skb, 0);
-       kfree_skb(skb);
-       if (unlikely(IS_ERR(segs)))
-               return PTR_ERR(segs);
-
-       do {
-               struct sk_buff *nskb = segs->next;
-               int err;
-
-               segs->next = NULL;
-               err = xfrm4_output_finish2(segs);
-
-               if (unlikely(err)) {
-                       while ((segs = nskb)) {
-                               nskb = segs->next;
-                               segs->next = NULL;
-                               kfree_skb(segs);
-                       }
-                       return err;
-               }
-
-               segs = nskb;
-       } while (segs);
-
-       return 0;
+       return xfrm_output(skb);
 }
 
 int xfrm4_output(struct sk_buff *skb)
 {
-       return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
-                           xfrm4_output_finish,
+       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb,
+                           NULL, skb->dst->dev, xfrm4_output_finish,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
index cc86fb110dd882050848053e94406d6870803a01..3783e3ee56a424f185beb18c38a7cf00cb11c24f 100644 (file)
@@ -8,36 +8,54 @@
  *
  */
 
-#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
 #include <linux/inetdevice.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 
 static struct dst_ops xfrm4_dst_ops;
 static struct xfrm_policy_afinfo xfrm4_policy_afinfo;
 
-static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
+static struct dst_entry *xfrm4_dst_lookup(int tos, xfrm_address_t *saddr,
+                                         xfrm_address_t *daddr)
 {
-       return __ip_route_output_key((struct rtable**)dst, fl);
-}
-
-static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
-{
-       struct rtable *rt;
-       struct flowi fl_tunnel = {
+       struct flowi fl = {
                .nl_u = {
                        .ip4_u = {
+                               .tos = tos,
                                .daddr = daddr->a4,
                        },
                },
        };
+       struct dst_entry *dst;
+       struct rtable *rt;
+       int err;
 
-       if (!xfrm4_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
-               saddr->a4 = rt->rt_src;
-               dst_release(&rt->u.dst);
-               return 0;
-       }
-       return -EHOSTUNREACH;
+       if (saddr)
+               fl.fl4_src = saddr->a4;
+
+       err = __ip_route_output_key(&init_net, &rt, &fl);
+       dst = &rt->u.dst;
+       if (err)
+               dst = ERR_PTR(err);
+       return dst;
+}
+
+static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
+{
+       struct dst_entry *dst;
+       struct rtable *rt;
+
+       dst = xfrm4_dst_lookup(0, NULL, daddr);
+       if (IS_ERR(dst))
+               return -EHOSTUNREACH;
+
+       rt = (struct rtable *)dst;
+       saddr->a4 = rt->rt_src;
+       dst_release(dst);
+       return 0;
 }
 
 static struct dst_entry *
@@ -61,142 +79,49 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
        return dst;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
+static int xfrm4_get_tos(struct flowi *fl)
+{
+       return fl->fl4_tos;
+}
 
-static int
-__xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-                     struct flowi *fl, struct dst_entry **dst_p)
+static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+                          int nfheader_len)
 {
-       struct dst_entry *dst, *dst_prev;
-       struct rtable *rt0 = (struct rtable*)(*dst_p);
-       struct rtable *rt = rt0;
-       struct flowi fl_tunnel = {
-               .nl_u = {
-                       .ip4_u = {
-                               .saddr = fl->fl4_src,
-                               .daddr = fl->fl4_dst,
-                               .tos = fl->fl4_tos
-                       }
-               }
-       };
-       int i;
-       int err;
-       int header_len = 0;
-       int trailer_len = 0;
+       return 0;
+}
 
-       dst = dst_prev = NULL;
-       dst_hold(&rt->u.dst);
+static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+{
+       struct rtable *rt = (struct rtable *)xdst->route;
 
-       for (i = 0; i < nx; i++) {
-               struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops);
-               struct xfrm_dst *xdst;
+       xdst->u.rt.fl = rt->fl;
 
-               if (unlikely(dst1 == NULL)) {
-                       err = -ENOBUFS;
-                       dst_release(&rt->u.dst);
-                       goto error;
-               }
+       xdst->u.dst.dev = dev;
+       dev_hold(dev);
 
-               if (!dst)
-                       dst = dst1;
-               else {
-                       dst_prev->child = dst1;
-                       dst1->flags |= DST_NOHASH;
-                       dst_clone(dst1);
-               }
+       xdst->u.rt.idev = in_dev_get(dev);
+       if (!xdst->u.rt.idev)
+               return -ENODEV;
 
-               xdst = (struct xfrm_dst *)dst1;
-               xdst->route = &rt->u.dst;
-               xdst->genid = xfrm[i]->genid;
-
-               dst1->next = dst_prev;
-               dst_prev = dst1;
-
-               header_len += xfrm[i]->props.header_len;
-               trailer_len += xfrm[i]->props.trailer_len;
-
-               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-                       unsigned short encap_family = xfrm[i]->props.family;
-                       switch (encap_family) {
-                       case AF_INET:
-                               fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
-                               fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
-                               break;
-#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
-                       case AF_INET6:
-                               ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr*)&xfrm[i]->id.daddr.a6);
-                               ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr*)&xfrm[i]->props.saddr.a6);
-                               break;
-#endif
-                       default:
-                               BUG_ON(1);
-                       }
-                       err = xfrm_dst_lookup((struct xfrm_dst **)&rt,
-                                             &fl_tunnel, encap_family);
-                       if (err)
-                               goto error;
-               } else
-                       dst_hold(&rt->u.dst);
-       }
+       xdst->u.rt.peer = rt->peer;
+       if (rt->peer)
+               atomic_inc(&rt->peer->refcnt);
 
-       dst_prev->child = &rt->u.dst;
-       dst->path = &rt->u.dst;
-
-       *dst_p = dst;
-       dst = dst_prev;
-
-       dst_prev = *dst_p;
-       i = 0;
-       for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-               struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-               x->u.rt.fl = *fl;
-
-               dst_prev->xfrm = xfrm[i++];
-               dst_prev->dev = rt->u.dst.dev;
-               if (rt->u.dst.dev)
-                       dev_hold(rt->u.dst.dev);
-               dst_prev->obsolete      = -1;
-               dst_prev->flags        |= DST_HOST;
-               dst_prev->lastuse       = jiffies;
-               dst_prev->header_len    = header_len;
-               dst_prev->nfheader_len  = 0;
-               dst_prev->trailer_len   = trailer_len;
-               memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
-
-               /* Copy neighbout for reachability confirmation */
-               dst_prev->neighbour     = neigh_clone(rt->u.dst.neighbour);
-               dst_prev->input         = rt->u.dst.input;
-               dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
-               if (rt0->peer)
-                       atomic_inc(&rt0->peer->refcnt);
-               x->u.rt.peer = rt0->peer;
-               /* Sheit... I remember I did this right. Apparently,
-                * it was magically lost, so this code needs audit */
-               x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL);
-               x->u.rt.rt_type = rt0->rt_type;
-               x->u.rt.rt_src = rt0->rt_src;
-               x->u.rt.rt_dst = rt0->rt_dst;
-               x->u.rt.rt_gateway = rt0->rt_gateway;
-               x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
-               x->u.rt.idev = rt0->idev;
-               in_dev_hold(rt0->idev);
-               header_len -= x->u.dst.xfrm->props.header_len;
-               trailer_len -= x->u.dst.xfrm->props.trailer_len;
-       }
+       /* Sheit... I remember I did this right. Apparently,
+        * it was magically lost, so this code needs audit */
+       xdst->u.rt.rt_flags = rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST |
+                                             RTCF_LOCAL);
+       xdst->u.rt.rt_type = rt->rt_type;
+       xdst->u.rt.rt_src = rt->rt_src;
+       xdst->u.rt.rt_dst = rt->rt_dst;
+       xdst->u.rt.rt_gateway = rt->rt_gateway;
+       xdst->u.rt.rt_spec_dst = rt->rt_spec_dst;
 
-       xfrm_init_pmtu(dst);
        return 0;
-
-error:
-       if (dst)
-               dst_free(dst);
-       return err;
 }
 
 static void
-_decode_session4(struct sk_buff *skb, struct flowi *fl)
+_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
 {
        struct iphdr *iph = ip_hdr(skb);
        u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
@@ -212,8 +137,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
                        if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
                                __be16 *ports = (__be16 *)xprth;
 
-                               fl->fl_ip_sport = ports[0];
-                               fl->fl_ip_dport = ports[1];
+                               fl->fl_ip_sport = ports[!!reverse];
+                               fl->fl_ip_dport = ports[!reverse];
                        }
                        break;
 
@@ -255,12 +180,12 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
                }
        }
        fl->proto = iph->protocol;
-       fl->fl4_dst = iph->daddr;
-       fl->fl4_src = iph->saddr;
+       fl->fl4_dst = reverse ? iph->saddr : iph->daddr;
+       fl->fl4_src = reverse ? iph->daddr : iph->saddr;
        fl->fl4_tos = iph->tos;
 }
 
-static inline int xfrm4_garbage_collect(void)
+static inline int xfrm4_garbage_collect(struct dst_ops *ops)
 {
        xfrm4_policy_afinfo.garbage_collect();
        return (atomic_read(&xfrm4_dst_ops.entries) > xfrm4_dst_ops.gc_thresh*2);
@@ -295,7 +220,8 @@ static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 
        xdst = (struct xfrm_dst *)dst;
        if (xdst->u.rt.idev->dev == dev) {
-               struct in_device *loopback_idev = in_dev_get(init_net.loopback_dev);
+               struct in_device *loopback_idev =
+                       in_dev_get(dev->nd_net->loopback_dev);
                BUG_ON(!loopback_idev);
 
                do {
@@ -318,6 +244,7 @@ static struct dst_ops xfrm4_dst_ops = {
        .update_pmtu =          xfrm4_update_pmtu,
        .destroy =              xfrm4_dst_destroy,
        .ifdown =               xfrm4_dst_ifdown,
+       .local_out =            __ip_local_out,
        .gc_thresh =            1024,
        .entry_size =           sizeof(struct xfrm_dst),
 };
@@ -328,8 +255,10 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
        .dst_lookup =           xfrm4_dst_lookup,
        .get_saddr =            xfrm4_get_saddr,
        .find_bundle =          __xfrm4_find_bundle,
-       .bundle_create =        __xfrm4_bundle_create,
        .decode_session =       _decode_session4,
+       .get_tos =              xfrm4_get_tos,
+       .init_path =            xfrm4_init_path,
+       .fill_dst =             xfrm4_fill_dst,
 };
 
 static void __init xfrm4_policy_init(void)
index 13d54a1c3337bd311c7245f331367296f07b0558..fdeebe68a379781853e4a0ea6f4197195af8cb89 100644 (file)
@@ -11,6 +11,7 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <linux/netfilter_ipv4.h>
 
 static struct xfrm_state_afinfo xfrm4_state_afinfo;
 
@@ -47,12 +48,31 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
        x->props.family = AF_INET;
 }
 
+int xfrm4_extract_header(struct sk_buff *skb)
+{
+       struct iphdr *iph = ip_hdr(skb);
+
+       XFRM_MODE_SKB_CB(skb)->id = iph->id;
+       XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
+       XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
+       XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
+       memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
+              sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
+
+       return 0;
+}
+
 static struct xfrm_state_afinfo xfrm4_state_afinfo = {
        .family                 = AF_INET,
+       .proto                  = IPPROTO_IPIP,
+       .eth_proto              = htons(ETH_P_IP),
        .owner                  = THIS_MODULE,
        .init_flags             = xfrm4_init_flags,
        .init_tempsel           = __xfrm4_init_tempsel,
        .output                 = xfrm4_output,
+       .extract_input          = xfrm4_extract_input,
+       .extract_output         = xfrm4_extract_output,
+       .transport_finish       = xfrm4_transport_finish,
 };
 
 void __init xfrm4_state_init(void)
index 87c23a73d28426f8d3dba9d5cdbfa1303835609f..24f3aa0f2a35d93661a5fb38ab0d947b8a253b89 100644 (file)
@@ -5,11 +5,12 @@
 obj-$(CONFIG_IPV6) += ipv6.o
 
 ipv6-objs :=   af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
+               addrlabel.o \
                route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
                raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
-               exthdrs.o sysctl_net_ipv6.o datagram.o \
-               ip6_flowlabel.o inet6_connection_sock.o
+               exthdrs.o datagram.o ip6_flowlabel.o inet6_connection_sock.o
 
+ipv6-$(CONFIG_SYSCTL) = sysctl_net_ipv6.o
 ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
        xfrm6_output.o
 ipv6-$(CONFIG_NETFILTER) += netfilter.o
index e8c347579da9a21f6d347b359ed2f28ad2218e43..e40213db9e4c6355e665c8684e4549feca77614d 100644 (file)
 #define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
 
 #ifdef CONFIG_SYSCTL
-static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p);
-static void addrconf_sysctl_unregister(struct ipv6_devconf *p);
+static void addrconf_sysctl_register(struct inet6_dev *idev);
+static void addrconf_sysctl_unregister(struct inet6_dev *idev);
+#else
+static inline void addrconf_sysctl_register(struct inet6_dev *idev)
+{
+}
+
+static inline void addrconf_sysctl_unregister(struct inet6_dev *idev)
+{
+}
 #endif
 
 #ifdef CONFIG_IPV6_PRIVACY
@@ -141,7 +149,8 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
 
 static void inet6_prefix_notify(int event, struct inet6_dev *idev,
                                struct prefix_info *pinfo);
-static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
+static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
+                             struct net_device *dev);
 
 static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
 
@@ -256,16 +265,13 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
 static int snmp6_alloc_dev(struct inet6_dev *idev)
 {
        if (snmp_mib_init((void **)idev->stats.ipv6,
-                         sizeof(struct ipstats_mib),
-                         __alignof__(struct ipstats_mib)) < 0)
+                         sizeof(struct ipstats_mib)) < 0)
                goto err_ip;
        if (snmp_mib_init((void **)idev->stats.icmpv6,
-                         sizeof(struct icmpv6_mib),
-                         __alignof__(struct icmpv6_mib)) < 0)
+                         sizeof(struct icmpv6_mib)) < 0)
                goto err_icmp;
        if (snmp_mib_init((void **)idev->stats.icmpv6msg,
-                         sizeof(struct icmpv6msg_mib),
-                         __alignof__(struct icmpv6msg_mib)) < 0)
+                         sizeof(struct icmpv6msg_mib)) < 0)
                goto err_icmpmsg;
 
        return 0;
@@ -329,7 +335,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 
        rwlock_init(&ndev->lock);
        ndev->dev = dev;
-       memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
+       memcpy(&ndev->cnf, dev->nd_net->ipv6.devconf_dflt, sizeof(ndev->cnf));
        ndev->cnf.mtu6 = dev->mtu;
        ndev->cnf.sysctl = NULL;
        ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
@@ -366,9 +372,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
        in6_dev_hold(ndev);
 
 #ifdef CONFIG_IPV6_PRIVACY
-       init_timer(&ndev->regen_timer);
-       ndev->regen_timer.function = ipv6_regen_rndid;
-       ndev->regen_timer.data = (unsigned long) ndev;
+       setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
        if ((dev->flags&IFF_LOOPBACK) ||
            dev->type == ARPHRD_TUNNEL ||
 #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
@@ -379,6 +383,13 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
                       "%s: Disabled Privacy Extensions\n",
                       dev->name);
                ndev->cnf.use_tempaddr = -1;
+
+               if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
+                       printk(KERN_INFO
+                              "%s: Disabled Multicast RS\n",
+                              dev->name);
+                       ndev->cnf.rtr_solicits = 0;
+               }
        } else {
                in6_dev_hold(ndev);
                ipv6_regen_rndid((unsigned long) ndev);
@@ -390,13 +401,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 
        ipv6_mc_init_dev(ndev);
        ndev->tstamp = jiffies;
-#ifdef CONFIG_SYSCTL
-       neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6,
-                             NET_IPV6_NEIGH, "ipv6",
-                             &ndisc_ifinfo_sysctl_change,
-                             NULL);
-       addrconf_sysctl_register(ndev, &ndev->cnf);
-#endif
+       addrconf_sysctl_register(ndev);
        /* protected by rtnl_lock */
        rcu_assign_pointer(dev->ip6_ptr, ndev);
 
@@ -452,18 +457,18 @@ static void dev_forward_change(struct inet6_dev *idev)
 }
 
 
-static void addrconf_forward_change(void)
+static void addrconf_forward_change(struct net *net, __s32 newf)
 {
        struct net_device *dev;
        struct inet6_dev *idev;
 
        read_lock(&dev_base_lock);
-       for_each_netdev(&init_net, dev) {
+       for_each_netdev(net, dev) {
                rcu_read_lock();
                idev = __in6_dev_get(dev);
                if (idev) {
-                       int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding);
-                       idev->cnf.forwarding = ipv6_devconf.forwarding;
+                       int changed = (!idev->cnf.forwarding) ^ (!newf);
+                       idev->cnf.forwarding = newf;
                        if (changed)
                                dev_forward_change(idev);
                }
@@ -471,6 +476,25 @@ static void addrconf_forward_change(void)
        }
        read_unlock(&dev_base_lock);
 }
+
+static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
+{
+       struct net *net;
+
+       net = (struct net *)table->extra2;
+       if (p == &net->ipv6.devconf_dflt->forwarding)
+               return;
+
+       if (p == &net->ipv6.devconf_all->forwarding) {
+               __s32 newf = net->ipv6.devconf_all->forwarding;
+               net->ipv6.devconf_dflt->forwarding = newf;
+               addrconf_forward_change(net, newf);
+       } else if ((!*p) ^ (!old))
+               dev_forward_change((struct inet6_dev *)table->extra1);
+
+       if (*p)
+               rt6_purge_dflt_routers();
+}
 #endif
 
 /* Nobody refers to this ifaddr, destroy it */
@@ -537,7 +561,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
        write_lock(&addrconf_hash_lock);
 
        /* Ignore adding duplicate addresses on an interface */
-       if (ipv6_chk_same_addr(addr, idev->dev)) {
+       if (ipv6_chk_same_addr(&init_net, addr, idev->dev)) {
                ADBG(("ipv6_add_addr: already assigned\n"));
                err = -EEXIST;
                goto out;
@@ -876,35 +900,6 @@ static inline int ipv6_saddr_preferred(int type)
        return 0;
 }
 
-/* static matching label */
-static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
-{
- /*
-  *    prefix (longest match)  label
-  *    -----------------------------
-  *    ::1/128                 0
-  *    ::/0                    1
-  *    2002::/16               2
-  *    ::/96                   3
-  *    ::ffff:0:0/96           4
-  *    fc00::/7                5
-  *    2001::/32               6
-  */
-       if (type & IPV6_ADDR_LOOPBACK)
-               return 0;
-       else if (type & IPV6_ADDR_COMPATv4)
-               return 3;
-       else if (type & IPV6_ADDR_MAPPED)
-               return 4;
-       else if (addr->s6_addr32[0] == htonl(0x20010000))
-               return 6;
-       else if (addr->s6_addr16[0] == htons(0x2002))
-               return 2;
-       else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
-               return 5;
-       return 1;
-}
-
 int ipv6_dev_get_saddr(struct net_device *daddr_dev,
                       struct in6_addr *daddr, struct in6_addr *saddr)
 {
@@ -912,7 +907,8 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
        struct inet6_ifaddr *ifa_result = NULL;
        int daddr_type = __ipv6_addr_type(daddr);
        int daddr_scope = __ipv6_addr_src_scope(daddr_type);
-       u32 daddr_label = ipv6_saddr_label(daddr, daddr_type);
+       int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0;
+       u32 daddr_label = ipv6_addr_label(daddr, daddr_type, daddr_ifindex);
        struct net_device *dev;
 
        memset(&hiscore, 0, sizeof(hiscore));
@@ -1085,11 +1081,15 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
 
                        /* Rule 6: Prefer matching label */
                        if (hiscore.rule < 6) {
-                               if (ipv6_saddr_label(&ifa_result->addr, hiscore.addr_type) == daddr_label)
+                               if (ipv6_addr_label(&ifa_result->addr,
+                                                   hiscore.addr_type,
+                                                   ifa_result->idev->dev->ifindex) == daddr_label)
                                        hiscore.attrs |= IPV6_SADDR_SCORE_LABEL;
                                hiscore.rule++;
                        }
-                       if (ipv6_saddr_label(&ifa->addr, score.addr_type) == daddr_label) {
+                       if (ipv6_addr_label(&ifa->addr,
+                                           score.addr_type,
+                                           ifa->idev->dev->ifindex) == daddr_label) {
                                score.attrs |= IPV6_SADDR_SCORE_LABEL;
                                if (!(hiscore.attrs & IPV6_SADDR_SCORE_LABEL)) {
                                        score.rule = 6;
@@ -1207,13 +1207,16 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
        return cnt;
 }
 
-int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
+int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
+                 struct net_device *dev, int strict)
 {
        struct inet6_ifaddr * ifp;
        u8 hash = ipv6_addr_hash(addr);
 
        read_lock_bh(&addrconf_hash_lock);
        for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+               if (ifp->idev->dev->nd_net != net)
+                       continue;
                if (ipv6_addr_equal(&ifp->addr, addr) &&
                    !(ifp->flags&IFA_F_TENTATIVE)) {
                        if (dev == NULL || ifp->idev->dev == dev ||
@@ -1224,16 +1227,18 @@ int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
        read_unlock_bh(&addrconf_hash_lock);
        return ifp != NULL;
 }
-
 EXPORT_SYMBOL(ipv6_chk_addr);
 
 static
-int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
+int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
+                      struct net_device *dev)
 {
        struct inet6_ifaddr * ifp;
        u8 hash = ipv6_addr_hash(addr);
 
        for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+               if (ifp->idev->dev->nd_net != net)
+                       continue;
                if (ipv6_addr_equal(&ifp->addr, addr)) {
                        if (dev == NULL || ifp->idev->dev == dev)
                                break;
@@ -1242,13 +1247,16 @@ int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev)
        return ifp != NULL;
 }
 
-struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *dev, int strict)
+struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
+                                    struct net_device *dev, int strict)
 {
        struct inet6_ifaddr * ifp;
        u8 hash = ipv6_addr_hash(addr);
 
        read_lock_bh(&addrconf_hash_lock);
        for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
+               if (ifp->idev->dev->nd_net != net)
+                       continue;
                if (ipv6_addr_equal(&ifp->addr, addr)) {
                        if (dev == NULL || ifp->idev->dev == dev ||
                            !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
@@ -1435,6 +1443,9 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
                return addrconf_ifid_arcnet(eui, dev);
        case ARPHRD_INFINIBAND:
                return addrconf_ifid_infiniband(eui, dev);
+       case ARPHRD_SIT:
+               if (dev->priv_flags & IFF_ISATAP)
+                       return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
        }
        return -1;
 }
@@ -1470,7 +1481,7 @@ regen:
         *
         *  - Reserved subnet anycast (RFC 2526)
         *      11111101 11....11 1xxxxxxx
-        *  - ISATAP (draft-ietf-ngtrans-isatap-13.txt) 5.1
+        *  - ISATAP (RFC4214) 6.1
         *      00-00-5E-FE-xx-xx-xx-xx
         *  - value 0
         *  - XXX: already assigned to an address on the device
@@ -1731,7 +1742,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
 
 ok:
 
-               ifp = ipv6_get_ifaddr(&addr, dev, 1);
+               ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1);
 
                if (ifp == NULL && valid_lft) {
                        int max_addresses = in6_dev->cnf.max_addresses;
@@ -1889,7 +1900,7 @@ int addrconf_set_dstaddr(void __user *arg)
                p.iph.ihl = 5;
                p.iph.protocol = IPPROTO_IPV6;
                p.iph.ttl = 64;
-               ifr.ifr_ifru.ifru_data = (void __user *)&p;
+               ifr.ifr_ifru.ifru_data = (__force void __user *)&p;
 
                oldfs = get_fs(); set_fs(KERNEL_DS);
                err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
@@ -2201,6 +2212,16 @@ static void addrconf_sit_config(struct net_device *dev)
                return;
        }
 
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct in6_addr addr;
+
+               ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+               addrconf_prefix_route(&addr, 64, dev, 0, 0);
+               if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
+                       addrconf_add_linklocal(idev, &addr);
+               return;
+       }
+
        sit_add_v4_addrs(idev);
 
        if (dev->flags&IFF_POINTOPOINT) {
@@ -2385,15 +2406,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
        case NETDEV_CHANGENAME:
                if (idev) {
                        snmp6_unregister_dev(idev);
-#ifdef CONFIG_SYSCTL
-                       addrconf_sysctl_unregister(&idev->cnf);
-                       neigh_sysctl_unregister(idev->nd_parms);
-                       neigh_sysctl_register(dev, idev->nd_parms,
-                                             NET_IPV6, NET_IPV6_NEIGH, "ipv6",
-                                             &ndisc_ifinfo_sysctl_change,
-                                             NULL);
-                       addrconf_sysctl_register(idev, &idev->cnf);
-#endif
+                       addrconf_sysctl_unregister(idev);
+                       addrconf_sysctl_register(idev);
                        err = snmp6_register_dev(idev);
                        if (err)
                                return notifier_from_errno(err);
@@ -2517,10 +2531,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
        /* Shot the device (if unregistered) */
 
        if (how == 1) {
-#ifdef CONFIG_SYSCTL
-               addrconf_sysctl_unregister(&idev->cnf);
-               neigh_sysctl_unregister(idev->nd_parms);
-#endif
+               addrconf_sysctl_unregister(idev);
                neigh_parms_release(&nd_tbl, idev->nd_parms);
                neigh_ifdown(&nd_tbl, dev);
                in6_dev_put(idev);
@@ -2734,6 +2745,7 @@ static void addrconf_dad_run(struct inet6_dev *idev) {
 
 #ifdef CONFIG_PROC_FS
 struct if6_iter_state {
+       struct seq_net_private p;
        int bucket;
 };
 
@@ -2741,9 +2753,13 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
 {
        struct inet6_ifaddr *ifa = NULL;
        struct if6_iter_state *state = seq->private;
+       struct net *net = state->p.net;
 
        for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
                ifa = inet6_addr_lst[state->bucket];
+
+               while (ifa && ifa->idev->dev->nd_net != net)
+                       ifa = ifa->lst_next;
                if (ifa)
                        break;
        }
@@ -2753,13 +2769,22 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
 static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
 {
        struct if6_iter_state *state = seq->private;
+       struct net *net = state->p.net;
 
        ifa = ifa->lst_next;
 try_again:
+       if (ifa) {
+               if (ifa->idev->dev->nd_net != net) {
+                       ifa = ifa->lst_next;
+                       goto try_again;
+               }
+       }
+
        if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
                ifa = inet6_addr_lst[state->bucket];
                goto try_again;
        }
+
        return ifa;
 }
 
@@ -2774,6 +2799,7 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(addrconf_hash_lock)
 {
        read_lock_bh(&addrconf_hash_lock);
        return if6_get_idx(seq, *pos);
@@ -2789,6 +2815,7 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void if6_seq_stop(struct seq_file *seq, void *v)
+       __releases(addrconf_hash_lock)
 {
        read_unlock_bh(&addrconf_hash_lock);
 }
@@ -2816,8 +2843,8 @@ static const struct seq_operations if6_seq_ops = {
 
 static int if6_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &if6_seq_ops,
-                       sizeof(struct if6_iter_state));
+       return seq_open_net(inode, file, &if6_seq_ops,
+                           sizeof(struct if6_iter_state));
 }
 
 static const struct file_operations if6_fops = {
@@ -2825,31 +2852,48 @@ static const struct file_operations if6_fops = {
        .open           = if6_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
 };
 
-int __init if6_proc_init(void)
+static int if6_proc_net_init(struct net *net)
 {
-       if (!proc_net_fops_create(&init_net, "if_inet6", S_IRUGO, &if6_fops))
+       if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
                return -ENOMEM;
        return 0;
 }
 
+static void if6_proc_net_exit(struct net *net)
+{
+       proc_net_remove(net, "if_inet6");
+}
+
+static struct pernet_operations if6_proc_net_ops = {
+       .init = if6_proc_net_init,
+       .exit = if6_proc_net_exit,
+};
+
+int __init if6_proc_init(void)
+{
+       return register_pernet_subsys(&if6_proc_net_ops);
+}
+
 void if6_proc_exit(void)
 {
-       proc_net_remove(&init_net, "if_inet6");
+       unregister_pernet_subsys(&if6_proc_net_ops);
 }
 #endif /* CONFIG_PROC_FS */
 
 #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
 /* Check if address is a home address configured on any interface. */
-int ipv6_chk_home_addr(struct in6_addr *addr)
+int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
 {
        int ret = 0;
        struct inet6_ifaddr * ifp;
        u8 hash = ipv6_addr_hash(addr);
        read_lock_bh(&addrconf_hash_lock);
        for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
+               if (ifp->idev->dev->nd_net != net)
+                       continue;
                if (ipv6_addr_cmp(&ifp->addr, addr) == 0 &&
                    (ifp->flags & IFA_F_HOMEADDRESS)) {
                        ret = 1;
@@ -2997,11 +3041,15 @@ static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = {
 static int
 inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct ifaddrmsg *ifm;
        struct nlattr *tb[IFA_MAX+1];
        struct in6_addr *pfx;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
        if (err < 0)
                return err;
@@ -3054,6 +3102,7 @@ static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
 static int
 inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct ifaddrmsg *ifm;
        struct nlattr *tb[IFA_MAX+1];
        struct in6_addr *pfx;
@@ -3063,6 +3112,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        u8 ifa_flags;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
        if (err < 0)
                return err;
@@ -3090,7 +3142,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
        /* We ignore other flags so far. */
        ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS);
 
-       ifa = ipv6_get_ifaddr(pfx, dev, 1);
+       ifa = ipv6_get_ifaddr(net, pfx, dev, 1);
        if (ifa == NULL) {
                /*
                 * It would be best to check for !NLM_F_CREATE here but
@@ -3283,11 +3335,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifa = ifa->if_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifaddr(skb, ifa,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_NEWADDR,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifaddr(skb, ifa,
+                                                       NETLINK_CB(cb->skb).pid,
+                                                       cb->nlh->nlmsg_seq,
+                                                       RTM_NEWADDR,
+                                                       NLM_F_MULTI);
                        }
                        break;
                case MULTICAST_ADDR:
@@ -3296,11 +3348,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifmca = ifmca->next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifmcaddr(skb, ifmca,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_GETMULTICAST,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifmcaddr(skb, ifmca,
+                                                         NETLINK_CB(cb->skb).pid,
+                                                         cb->nlh->nlmsg_seq,
+                                                         RTM_GETMULTICAST,
+                                                         NLM_F_MULTI);
                        }
                        break;
                case ANYCAST_ADDR:
@@ -3309,11 +3361,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                             ifaca = ifaca->aca_next, ip_idx++) {
                                if (ip_idx < s_ip_idx)
                                        continue;
-                               if ((err = inet6_fill_ifacaddr(skb, ifaca,
-                                   NETLINK_CB(cb->skb).pid,
-                                   cb->nlh->nlmsg_seq, RTM_GETANYCAST,
-                                   NLM_F_MULTI)) <= 0)
-                                       goto done;
+                               err = inet6_fill_ifacaddr(skb, ifaca,
+                                                         NETLINK_CB(cb->skb).pid,
+                                                         cb->nlh->nlmsg_seq,
+                                                         RTM_GETANYCAST,
+                                                         NLM_F_MULTI);
                        }
                        break;
                default:
@@ -3321,14 +3373,12 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
                }
                read_unlock_bh(&idev->lock);
                in6_dev_put(idev);
+
+               if (err <= 0)
+                       break;
 cont:
                idx++;
        }
-done:
-       if (err <= 0) {
-               read_unlock_bh(&idev->lock);
-               in6_dev_put(idev);
-       }
        cb->args[0] = idx;
        cb->args[1] = ip_idx;
        return skb->len;
@@ -3336,26 +3386,42 @@ done:
 
 static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        enum addr_type_t type = UNICAST_ADDR;
+
+       if (net != &init_net)
+               return 0;
+
        return inet6_dump_addr(skb, cb, type);
 }
 
 static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        enum addr_type_t type = MULTICAST_ADDR;
+
+       if (net != &init_net)
+               return 0;
+
        return inet6_dump_addr(skb, cb, type);
 }
 
 
 static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        enum addr_type_t type = ANYCAST_ADDR;
+
+       if (net != &init_net)
+               return 0;
+
        return inet6_dump_addr(skb, cb, type);
 }
 
 static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
                             void *arg)
 {
+       struct net *net = in_skb->sk->sk_net;
        struct ifaddrmsg *ifm;
        struct nlattr *tb[IFA_MAX+1];
        struct in6_addr *addr = NULL;
@@ -3364,6 +3430,9 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
        struct sk_buff *skb;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
        if (err < 0)
                goto errout;
@@ -3378,7 +3447,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
        if (ifm->ifa_index)
                dev = __dev_get_by_index(&init_net, ifm->ifa_index);
 
-       if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) {
+       if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
                err = -EADDRNOTAVAIL;
                goto errout;
        }
@@ -3396,7 +3465,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
                kfree_skb(skb);
                goto errout_ifa;
        }
-       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
 errout_ifa:
        in6_ifa_put(ifa);
 errout:
@@ -3419,10 +3488,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
 }
 
 static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
@@ -3581,11 +3650,15 @@ nla_put_failure:
 
 static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int idx, err;
        int s_idx = cb->args[0];
        struct net_device *dev;
        struct inet6_dev *idev;
 
+       if (net != &init_net)
+               return 0;
+
        read_lock(&dev_base_lock);
        idx = 0;
        for_each_netdev(&init_net, dev) {
@@ -3623,10 +3696,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
 }
 
 static inline size_t inet6_prefix_nlmsg_size(void)
@@ -3692,10 +3765,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV6_PREFIX, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
 }
 
 static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@ -3746,22 +3819,8 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
 
        ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
 
-       if (write && valp != &ipv6_devconf_dflt.forwarding) {
-               if (valp != &ipv6_devconf.forwarding) {
-                       if ((!*valp) ^ (!val)) {
-                               struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
-                               if (idev == NULL)
-                                       return ret;
-                               dev_forward_change(idev);
-                       }
-               } else {
-                       ipv6_devconf_dflt.forwarding = ipv6_devconf.forwarding;
-                       addrconf_forward_change();
-               }
-               if (*valp)
-                       rt6_purge_dflt_routers();
-       }
-
+       if (write)
+               addrconf_fixup_forwarding(ctl, valp, val);
        return ret;
 }
 
@@ -3772,6 +3831,7 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
                                            void __user *newval, size_t newlen)
 {
        int *valp = table->data;
+       int val = *valp;
        int new;
 
        if (!newval || !newlen)
@@ -3796,26 +3856,8 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
                }
        }
 
-       if (valp != &ipv6_devconf_dflt.forwarding) {
-               if (valp != &ipv6_devconf.forwarding) {
-                       struct inet6_dev *idev = (struct inet6_dev *)table->extra1;
-                       int changed;
-                       if (unlikely(idev == NULL))
-                               return -ENODEV;
-                       changed = (!*valp) ^ (!new);
-                       *valp = new;
-                       if (changed)
-                               dev_forward_change(idev);
-               } else {
-                       *valp = new;
-                       addrconf_forward_change();
-               }
-
-               if (*valp)
-                       rt6_purge_dflt_routers();
-       } else
-               *valp = new;
-
+       *valp = new;
+       addrconf_fixup_forwarding(table, valp, val);
        return 1;
 }
 
@@ -3823,10 +3865,7 @@ static struct addrconf_sysctl_table
 {
        struct ctl_table_header *sysctl_header;
        ctl_table addrconf_vars[__NET_IPV6_MAX];
-       ctl_table addrconf_dev[2];
-       ctl_table addrconf_conf_dir[2];
-       ctl_table addrconf_proto_dir[2];
-       ctl_table addrconf_root_dir[2];
+       char *dev_name;
 } addrconf_sysctl __read_mostly = {
        .sysctl_header = NULL,
        .addrconf_vars = {
@@ -4047,72 +4086,33 @@ static struct addrconf_sysctl_table
                        .ctl_name       =       0,      /* sentinel */
                }
        },
-       .addrconf_dev = {
-               {
-                       .ctl_name       =       NET_PROTO_CONF_ALL,
-                       .procname       =       "all",
-                       .mode           =       0555,
-                       .child          =       addrconf_sysctl.addrconf_vars,
-               },
-               {
-                       .ctl_name       =       0,      /* sentinel */
-               }
-       },
-       .addrconf_conf_dir = {
-               {
-                       .ctl_name       =       NET_IPV6_CONF,
-                       .procname       =       "conf",
-                       .mode           =       0555,
-                       .child          =       addrconf_sysctl.addrconf_dev,
-               },
-               {
-                       .ctl_name       =       0,      /* sentinel */
-               }
-       },
-       .addrconf_proto_dir = {
-               {
-                       .ctl_name       =       NET_IPV6,
-                       .procname       =       "ipv6",
-                       .mode           =       0555,
-                       .child          =       addrconf_sysctl.addrconf_conf_dir,
-               },
-               {
-                       .ctl_name       =       0,      /* sentinel */
-               }
-       },
-       .addrconf_root_dir = {
-               {
-                       .ctl_name       =       CTL_NET,
-                       .procname       =       "net",
-                       .mode           =       0555,
-                       .child          =       addrconf_sysctl.addrconf_proto_dir,
-               },
-               {
-                       .ctl_name       =       0,      /* sentinel */
-               }
-       },
 };
 
-static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf *p)
+static int __addrconf_sysctl_register(struct net *net, char *dev_name,
+               int ctl_name, struct inet6_dev *idev, struct ipv6_devconf *p)
 {
        int i;
-       struct net_device *dev = idev ? idev->dev : NULL;
        struct addrconf_sysctl_table *t;
-       char *dev_name = NULL;
+
+#define ADDRCONF_CTL_PATH_DEV  3
+
+       struct ctl_path addrconf_ctl_path[] = {
+               { .procname = "net", .ctl_name = CTL_NET, },
+               { .procname = "ipv6", .ctl_name = NET_IPV6, },
+               { .procname = "conf", .ctl_name = NET_IPV6_CONF, },
+               { /* to be set */ },
+               { },
+       };
+
 
        t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
        if (t == NULL)
-               return;
+               goto out;
+
        for (i=0; t->addrconf_vars[i].data; i++) {
                t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
                t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
-       }
-       if (dev) {
-               dev_name = dev->name;
-               t->addrconf_dev[0].ctl_name = dev->ifindex;
-       } else {
-               dev_name = "default";
-               t->addrconf_dev[0].ctl_name = NET_PROTO_CONF_DEFAULT;
+               t->addrconf_vars[i].extra2 = net;
        }
 
        /*
@@ -4120,47 +4120,126 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
         * by sysctl and we wouldn't want anyone to change it under our feet
         * (see SIOCSIFNAME).
         */
-       dev_name = kstrdup(dev_name, GFP_KERNEL);
-       if (!dev_name)
-           goto free;
-
-       t->addrconf_dev[0].procname = dev_name;
+       t->dev_name = kstrdup(dev_name, GFP_KERNEL);
+       if (!t->dev_name)
+               goto free;
 
-       t->addrconf_dev[0].child = t->addrconf_vars;
-       t->addrconf_conf_dir[0].child = t->addrconf_dev;
-       t->addrconf_proto_dir[0].child = t->addrconf_conf_dir;
-       t->addrconf_root_dir[0].child = t->addrconf_proto_dir;
+       addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name;
+       addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].ctl_name = ctl_name;
 
-       t->sysctl_header = register_sysctl_table(t->addrconf_root_dir);
+       t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path,
+                       t->addrconf_vars);
        if (t->sysctl_header == NULL)
                goto free_procname;
-       else
-               p->sysctl = t;
-       return;
 
-       /* error path */
- free_procname:
-       kfree(dev_name);
- free:
+       p->sysctl = t;
+       return 0;
+
+free_procname:
+       kfree(t->dev_name);
+free:
        kfree(t);
+out:
+       return -ENOBUFS;
+}
 
-       return;
+static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
+{
+       struct addrconf_sysctl_table *t;
+
+       if (p->sysctl == NULL)
+               return;
+
+       t = p->sysctl;
+       p->sysctl = NULL;
+       unregister_sysctl_table(t->sysctl_header);
+       kfree(t->dev_name);
+       kfree(t);
 }
 
-static void addrconf_sysctl_unregister(struct ipv6_devconf *p)
+static void addrconf_sysctl_register(struct inet6_dev *idev)
 {
-       if (p->sysctl) {
-               struct addrconf_sysctl_table *t = p->sysctl;
-               p->sysctl = NULL;
-               unregister_sysctl_table(t->sysctl_header);
-               kfree(t->addrconf_dev[0].procname);
-               kfree(t);
-       }
+       neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6,
+                             NET_IPV6_NEIGH, "ipv6",
+                             &ndisc_ifinfo_sysctl_change,
+                             NULL);
+       __addrconf_sysctl_register(idev->dev->nd_net, idev->dev->name,
+                       idev->dev->ifindex, idev, &idev->cnf);
+}
+
+static void addrconf_sysctl_unregister(struct inet6_dev *idev)
+{
+       __addrconf_sysctl_unregister(&idev->cnf);
+       neigh_sysctl_unregister(idev->nd_parms);
 }
 
 
 #endif
 
+static int addrconf_init_net(struct net *net)
+{
+       int err;
+       struct ipv6_devconf *all, *dflt;
+
+       err = -ENOMEM;
+       all = &ipv6_devconf;
+       dflt = &ipv6_devconf_dflt;
+
+       if (net != &init_net) {
+               all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
+               if (all == NULL)
+                       goto err_alloc_all;
+
+               dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
+               if (dflt == NULL)
+                       goto err_alloc_dflt;
+       }
+
+       net->ipv6.devconf_all = all;
+       net->ipv6.devconf_dflt = dflt;
+
+#ifdef CONFIG_SYSCTL
+       err = __addrconf_sysctl_register(net, "all", NET_PROTO_CONF_ALL,
+                       NULL, all);
+       if (err < 0)
+               goto err_reg_all;
+
+       err = __addrconf_sysctl_register(net, "default", NET_PROTO_CONF_DEFAULT,
+                       NULL, dflt);
+       if (err < 0)
+               goto err_reg_dflt;
+#endif
+       return 0;
+
+#ifdef CONFIG_SYSCTL
+err_reg_dflt:
+       __addrconf_sysctl_unregister(all);
+err_reg_all:
+       kfree(dflt);
+#endif
+err_alloc_dflt:
+       kfree(all);
+err_alloc_all:
+       return err;
+}
+
+static void addrconf_exit_net(struct net *net)
+{
+#ifdef CONFIG_SYSCTL
+       __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);
+       __addrconf_sysctl_unregister(net->ipv6.devconf_all);
+#endif
+       if (net != &init_net) {
+               kfree(net->ipv6.devconf_dflt);
+               kfree(net->ipv6.devconf_all);
+       }
+}
+
+static struct pernet_operations addrconf_ops = {
+       .init = addrconf_init_net,
+       .exit = addrconf_exit_net,
+};
+
 /*
  *      Device notifier
  */
@@ -4185,7 +4264,15 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);
 
 int __init addrconf_init(void)
 {
-       int err = 0;
+       int err;
+
+       if ((err = ipv6_addr_label_init()) < 0) {
+               printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
+                       err);
+               return err;
+       }
+
+       register_pernet_subsys(&addrconf_ops);
 
        /* The addrconf netdev notifier requires that loopback_dev
         * has it's ipv6 private information allocated and setup
@@ -4210,7 +4297,7 @@ int __init addrconf_init(void)
                err = -ENOMEM;
        rtnl_unlock();
        if (err)
-               return err;
+               goto errlo;
 
        ip6_null_entry.u.dst.dev = init_net.loopback_dev;
        ip6_null_entry.rt6i_idev = in6_dev_get(init_net.loopback_dev);
@@ -4236,20 +4323,18 @@ int __init addrconf_init(void)
        __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
        __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);
 
-#ifdef CONFIG_SYSCTL
-       addrconf_sysctl.sysctl_header =
-               register_sysctl_table(addrconf_sysctl.addrconf_root_dir);
-       addrconf_sysctl_register(NULL, &ipv6_devconf_dflt);
-#endif
+       ipv6_addr_label_rtnl_register();
 
        return 0;
 errout:
        unregister_netdevice_notifier(&ipv6_dev_notf);
+errlo:
+       unregister_pernet_subsys(&addrconf_ops);
 
        return err;
 }
 
-void __exit addrconf_cleanup(void)
+void addrconf_cleanup(void)
 {
        struct net_device *dev;
        struct inet6_ifaddr *ifa;
@@ -4257,10 +4342,7 @@ void __exit addrconf_cleanup(void)
 
        unregister_netdevice_notifier(&ipv6_dev_notf);
 
-#ifdef CONFIG_SYSCTL
-       addrconf_sysctl_unregister(&ipv6_devconf_dflt);
-       addrconf_sysctl_unregister(&ipv6_devconf);
-#endif
+       unregister_pernet_subsys(&addrconf_ops);
 
        rtnl_lock();
 
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
new file mode 100644 (file)
index 0000000..a3c5a72
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * IPv6 Address Label subsystem
+ * for the IPv6 "Default" Source Address Selection
+ *
+ * Copyright (C)2007 USAGI/WIDE Project
+ */
+/*
+ * Author:
+ *     YOSHIFUJI Hideaki @ USAGI/WIDE Project <yoshfuji@linux-ipv6.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/in6.h>
+#include <net/addrconf.h>
+#include <linux/if_addrlabel.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#if 0
+#define ADDRLABEL(x...) printk(x)
+#else
+#define ADDRLABEL(x...) do { ; } while(0)
+#endif
+
+/*
+ * Policy Table
+ */
+struct ip6addrlbl_entry
+{
+       struct in6_addr prefix;
+       int prefixlen;
+       int ifindex;
+       int addrtype;
+       u32 label;
+       struct hlist_node list;
+       atomic_t refcnt;
+       struct rcu_head rcu;
+};
+
+static struct ip6addrlbl_table
+{
+       struct hlist_head head;
+       spinlock_t lock;
+       u32 seq;
+} ip6addrlbl_table;
+
+/*
+ * Default policy table (RFC3484 + extensions)
+ *
+ * prefix              addr_type       label
+ * -------------------------------------------------------------------------
+ * ::1/128             LOOPBACK        0
+ * ::/0                        N/A             1
+ * 2002::/16           N/A             2
+ * ::/96               COMPATv4        3
+ * ::ffff:0:0/96       V4MAPPED        4
+ * fc00::/7            N/A             5               ULA (RFC 4193)
+ * 2001::/32           N/A             6               Teredo (RFC 4380)
+ *
+ * Note: 0xffffffff is used if we do not have any policies.
+ */
+
+#define IPV6_ADDR_LABEL_DEFAULT        0xffffffffUL
+
+static const __initdata struct ip6addrlbl_init_table
+{
+       const struct in6_addr *prefix;
+       int prefixlen;
+       u32 label;
+} ip6addrlbl_init_table[] = {
+       {       /* ::/0 */
+               .prefix = &in6addr_any,
+               .label = 1,
+       },{     /* fc00::/7 */
+               .prefix = &(struct in6_addr){{{ 0xfc }}},
+               .prefixlen = 7,
+               .label = 5,
+       },{     /* 2002::/16 */
+               .prefix = &(struct in6_addr){{{ 0x20, 0x02 }}},
+               .prefixlen = 16,
+               .label = 2,
+       },{     /* 2001::/32 */
+               .prefix = &(struct in6_addr){{{ 0x20, 0x01 }}},
+               .prefixlen = 32,
+               .label = 6,
+       },{     /* ::ffff:0:0 */
+               .prefix = &(struct in6_addr){{{ [10] = 0xff, [11] = 0xff }}},
+               .prefixlen = 96,
+               .label = 4,
+       },{     /* ::/96 */
+               .prefix = &in6addr_any,
+               .prefixlen = 96,
+               .label = 3,
+       },{     /* ::1/128 */
+               .prefix = &in6addr_loopback,
+               .prefixlen = 128,
+               .label = 0,
+       }
+};
+
+/* Object management */
+static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
+{
+       kfree(p);
+}
+
+static void ip6addrlbl_free_rcu(struct rcu_head *h)
+{
+       ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
+}
+
+static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
+{
+       return atomic_inc_not_zero(&p->refcnt);
+}
+
+static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
+{
+       if (atomic_dec_and_test(&p->refcnt))
+               call_rcu(&p->rcu, ip6addrlbl_free_rcu);
+}
+
+/* Find label */
+static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
+                             const struct in6_addr *addr,
+                             int addrtype, int ifindex)
+{
+       if (p->ifindex && p->ifindex != ifindex)
+               return 0;
+       if (p->addrtype && p->addrtype != addrtype)
+               return 0;
+       if (!ipv6_prefix_equal(addr, &p->prefix, p->prefixlen))
+               return 0;
+       return 1;
+}
+
+static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr,
+                                                 int type, int ifindex)
+{
+       struct hlist_node *pos;
+       struct ip6addrlbl_entry *p;
+       hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
+               if (__ip6addrlbl_match(p, addr, type, ifindex))
+                       return p;
+       }
+       return NULL;
+}
+
+u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
+{
+       u32 label;
+       struct ip6addrlbl_entry *p;
+
+       type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;
+
+       rcu_read_lock();
+       p = __ipv6_addr_label(addr, type, ifindex);
+       label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
+       rcu_read_unlock();
+
+       ADDRLABEL(KERN_DEBUG "%s(addr=" NIP6_FMT ", type=%d, ifindex=%d) => %08x\n",
+                       __FUNCTION__,
+                       NIP6(*addr), type, ifindex,
+                       label);
+
+       return label;
+}
+
+/* allocate one entry */
+static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
+                                                int prefixlen, int ifindex,
+                                                u32 label)
+{
+       struct ip6addrlbl_entry *newp;
+       int addrtype;
+
+       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u)\n",
+                       __FUNCTION__,
+                       NIP6(*prefix), prefixlen,
+                       ifindex,
+                       (unsigned int)label);
+
+       addrtype = ipv6_addr_type(prefix) & (IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK);
+
+       switch (addrtype) {
+       case IPV6_ADDR_MAPPED:
+               if (prefixlen > 96)
+                       return ERR_PTR(-EINVAL);
+               if (prefixlen < 96)
+                       addrtype = 0;
+               break;
+       case IPV6_ADDR_COMPATv4:
+               if (prefixlen != 96)
+                       addrtype = 0;
+               break;
+       case IPV6_ADDR_LOOPBACK:
+               if (prefixlen != 128)
+                       addrtype = 0;
+               break;
+       }
+
+       newp = kmalloc(sizeof(*newp), GFP_KERNEL);
+       if (!newp)
+               return ERR_PTR(-ENOMEM);
+
+       ipv6_addr_prefix(&newp->prefix, prefix, prefixlen);
+       newp->prefixlen = prefixlen;
+       newp->ifindex = ifindex;
+       newp->addrtype = addrtype;
+       newp->label = label;
+       INIT_HLIST_NODE(&newp->list);
+       atomic_set(&newp->refcnt, 1);
+       return newp;
+}
+
+/* add a label */
+static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
+{
+       int ret = 0;
+
+       ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n",
+                       __FUNCTION__,
+                       newp, replace);
+
+       if (hlist_empty(&ip6addrlbl_table.head)) {
+               hlist_add_head_rcu(&newp->list, &ip6addrlbl_table.head);
+       } else {
+               struct hlist_node *pos, *n;
+               struct ip6addrlbl_entry *p = NULL;
+               hlist_for_each_entry_safe(p, pos, n,
+                                         &ip6addrlbl_table.head, list) {
+                       if (p->prefixlen == newp->prefixlen &&
+                           p->ifindex == newp->ifindex &&
+                           ipv6_addr_equal(&p->prefix, &newp->prefix)) {
+                               if (!replace) {
+                                       ret = -EEXIST;
+                                       goto out;
+                               }
+                               hlist_replace_rcu(&p->list, &newp->list);
+                               ip6addrlbl_put(p);
+                               goto out;
+                       } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
+                                  (p->prefixlen < newp->prefixlen)) {
+                               hlist_add_before_rcu(&newp->list, &p->list);
+                               goto out;
+                       }
+               }
+               hlist_add_after_rcu(&p->list, &newp->list);
+       }
+out:
+       if (!ret)
+               ip6addrlbl_table.seq++;
+       return ret;
+}
+
+/* add a label */
+static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
+                         int ifindex, u32 label, int replace)
+{
+       struct ip6addrlbl_entry *newp;
+       int ret = 0;
+
+       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n",
+                       __FUNCTION__,
+                       NIP6(*prefix), prefixlen,
+                       ifindex,
+                       (unsigned int)label,
+                       replace);
+
+       newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label);
+       if (IS_ERR(newp))
+               return PTR_ERR(newp);
+       spin_lock(&ip6addrlbl_table.lock);
+       ret = __ip6addrlbl_add(newp, replace);
+       spin_unlock(&ip6addrlbl_table.lock);
+       if (ret)
+               ip6addrlbl_free(newp);
+       return ret;
+}
+
+/* remove a label */
+static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
+                           int ifindex)
+{
+       struct ip6addrlbl_entry *p = NULL;
+       struct hlist_node *pos, *n;
+       int ret = -ESRCH;
+
+       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
+                       __FUNCTION__,
+                       NIP6(*prefix), prefixlen,
+                       ifindex);
+
+       hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
+               if (p->prefixlen == prefixlen &&
+                   p->ifindex == ifindex &&
+                   ipv6_addr_equal(&p->prefix, prefix)) {
+                       hlist_del_rcu(&p->list);
+                       ip6addrlbl_put(p);
+                       ret = 0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
+                         int ifindex)
+{
+       struct in6_addr prefix_buf;
+       int ret;
+
+       ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
+                       __FUNCTION__,
+                       NIP6(*prefix), prefixlen,
+                       ifindex);
+
+       ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
+       spin_lock(&ip6addrlbl_table.lock);
+       ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex);
+       spin_unlock(&ip6addrlbl_table.lock);
+       return ret;
+}
+
+/* add default label */
+static __init int ip6addrlbl_init(void)
+{
+       int err = 0;
+       int i;
+
+       ADDRLABEL(KERN_DEBUG "%s()\n", __FUNCTION__);
+
+       for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
+               int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix,
+                                        ip6addrlbl_init_table[i].prefixlen,
+                                        0,
+                                        ip6addrlbl_init_table[i].label, 0);
+               /* XXX: should we free all rules when we catch an error? */
+               if (ret && (!err || err != -ENOMEM))
+                       err = ret;
+       }
+       return err;
+}
+
+int __init ipv6_addr_label_init(void)
+{
+       spin_lock_init(&ip6addrlbl_table.lock);
+
+       return ip6addrlbl_init();
+}
+
+static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
+       [IFAL_ADDRESS]          = { .len = sizeof(struct in6_addr), },
+       [IFAL_LABEL]            = { .len = sizeof(u32), },
+};
+
+static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
+                            void *arg)
+{
+       struct net *net = skb->sk->sk_net;
+       struct ifaddrlblmsg *ifal;
+       struct nlattr *tb[IFAL_MAX+1];
+       struct in6_addr *pfx;
+       u32 label;
+       int err = 0;
+
+       if (net != &init_net)
+               return 0;
+
+       err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
+       if (err < 0)
+               return err;
+
+       ifal = nlmsg_data(nlh);
+
+       if (ifal->ifal_family != AF_INET6 ||
+           ifal->ifal_prefixlen > 128)
+               return -EINVAL;
+
+       if (ifal->ifal_index &&
+           !__dev_get_by_index(&init_net, ifal->ifal_index))
+               return -EINVAL;
+
+       if (!tb[IFAL_ADDRESS])
+               return -EINVAL;
+
+       pfx = nla_data(tb[IFAL_ADDRESS]);
+       if (!pfx)
+               return -EINVAL;
+
+       if (!tb[IFAL_LABEL])
+               return -EINVAL;
+       label = nla_get_u32(tb[IFAL_LABEL]);
+       if (label == IPV6_ADDR_LABEL_DEFAULT)
+               return -EINVAL;
+
+       switch(nlh->nlmsg_type) {
+       case RTM_NEWADDRLABEL:
+               err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen,
+                                    ifal->ifal_index, label,
+                                    nlh->nlmsg_flags & NLM_F_REPLACE);
+               break;
+       case RTM_DELADDRLABEL:
+               err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen,
+                                    ifal->ifal_index);
+               break;
+       default:
+               err = -EOPNOTSUPP;
+       }
+       return err;
+}
+
+static inline void ip6addrlbl_putmsg(struct nlmsghdr *nlh,
+                                    int prefixlen, int ifindex, u32 lseq)
+{
+       struct ifaddrlblmsg *ifal = nlmsg_data(nlh);
+       ifal->ifal_family = AF_INET6;
+       ifal->ifal_prefixlen = prefixlen;
+       ifal->ifal_flags = 0;
+       ifal->ifal_index = ifindex;
+       ifal->ifal_seq = lseq;
+};
+
+static int ip6addrlbl_fill(struct sk_buff *skb,
+                          struct ip6addrlbl_entry *p,
+                          u32 lseq,
+                          u32 pid, u32 seq, int event,
+                          unsigned int flags)
+{
+       struct nlmsghdr *nlh = nlmsg_put(skb, pid, seq, event,
+                                        sizeof(struct ifaddrlblmsg), flags);
+       if (!nlh)
+               return -EMSGSIZE;
+
+       ip6addrlbl_putmsg(nlh, p->prefixlen, p->ifindex, lseq);
+
+       if (nla_put(skb, IFAL_ADDRESS, 16, &p->prefix) < 0 ||
+           nla_put_u32(skb, IFAL_LABEL, p->label) < 0) {
+               nlmsg_cancel(skb, nlh);
+               return -EMSGSIZE;
+       }
+
+       return nlmsg_end(skb, nlh);
+}
+
+static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct net *net = skb->sk->sk_net;
+       struct ip6addrlbl_entry *p;
+       struct hlist_node *pos;
+       int idx = 0, s_idx = cb->args[0];
+       int err;
+
+       if (net != &init_net)
+               return 0;
+
+       rcu_read_lock();
+       hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
+               if (idx >= s_idx) {
+                       if ((err = ip6addrlbl_fill(skb, p,
+                                                  ip6addrlbl_table.seq,
+                                                  NETLINK_CB(cb->skb).pid,
+                                                  cb->nlh->nlmsg_seq,
+                                                  RTM_NEWADDRLABEL,
+                                                  NLM_F_MULTI)) <= 0)
+                               break;
+               }
+               idx++;
+       }
+       rcu_read_unlock();
+       cb->args[0] = idx;
+       return skb->len;
+}
+
+static inline int ip6addrlbl_msgsize(void)
+{
+       return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg))
+               + nla_total_size(16)    /* IFAL_ADDRESS */
+               + nla_total_size(4)     /* IFAL_LABEL */
+       );
+}
+
+static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
+                         void *arg)
+{
+       struct net *net = in_skb->sk->sk_net;
+       struct ifaddrlblmsg *ifal;
+       struct nlattr *tb[IFAL_MAX+1];
+       struct in6_addr *addr;
+       u32 lseq;
+       int err = 0;
+       struct ip6addrlbl_entry *p;
+       struct sk_buff *skb;
+
+       if (net != &init_net)
+               return 0;
+
+       err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
+       if (err < 0)
+               return err;
+
+       ifal = nlmsg_data(nlh);
+
+       if (ifal->ifal_family != AF_INET6 ||
+           ifal->ifal_prefixlen != 128)
+               return -EINVAL;
+
+       if (ifal->ifal_index &&
+           !__dev_get_by_index(&init_net, ifal->ifal_index))
+               return -EINVAL;
+
+       if (!tb[IFAL_ADDRESS])
+               return -EINVAL;
+
+       addr = nla_data(tb[IFAL_ADDRESS]);
+       if (!addr)
+               return -EINVAL;
+
+       rcu_read_lock();
+       p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index);
+       if (p && ip6addrlbl_hold(p))
+               p = NULL;
+       lseq = ip6addrlbl_table.seq;
+       rcu_read_unlock();
+
+       if (!p) {
+               err = -ESRCH;
+               goto out;
+       }
+
+       if (!(skb = nlmsg_new(ip6addrlbl_msgsize(), GFP_KERNEL))) {
+               ip6addrlbl_put(p);
+               return -ENOBUFS;
+       }
+
+       err = ip6addrlbl_fill(skb, p, lseq,
+                             NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
+                             RTM_NEWADDRLABEL, 0);
+
+       ip6addrlbl_put(p);
+
+       if (err < 0) {
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto out;
+       }
+
+       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
+out:
+       return err;
+}
+
+void __init ipv6_addr_label_rtnl_register(void)
+{
+       __rtnl_register(PF_INET6, RTM_NEWADDRLABEL, ip6addrlbl_newdel, NULL);
+       __rtnl_register(PF_INET6, RTM_DELADDRLABEL, ip6addrlbl_newdel, NULL);
+       __rtnl_register(PF_INET6, RTM_GETADDRLABEL, ip6addrlbl_get, ip6addrlbl_dump);
+}
+
index ecbd38894fdd1b2f971c1aeb25e36d1b74e961de..bddac0e8780f948f75b8de3d4fdb25e280080a2b 100644 (file)
@@ -66,9 +66,7 @@ MODULE_AUTHOR("Cast of dozens");
 MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
 MODULE_LICENSE("GPL");
 
-int sysctl_ipv6_bindv6only __read_mostly;
-
-/* The inetsw table contains everything that inet_create needs to
+/* The inetsw6 table contains everything that inet6_create needs to
  * build a new socket.
  */
 static struct list_head inetsw6[SOCK_MAX];
@@ -193,7 +191,7 @@ lookup_protocol:
        np->mcast_hops  = -1;
        np->mc_loop     = 1;
        np->pmtudisc    = IPV6_PMTUDISC_WANT;
-       np->ipv6only    = sysctl_ipv6_bindv6only;
+       np->ipv6only    = init_net.ipv6.sysctl.bindv6only;
 
        /* Init the ipv4 part of the socket since we can have sockets
         * using v6 API for ipv4.
@@ -280,7 +278,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        /* Check if the address belongs to the host. */
        if (addr_type == IPV6_ADDR_MAPPED) {
                v4addr = addr->sin6_addr.s6_addr32[3];
-               if (inet_addr_type(v4addr) != RTN_LOCAL) {
+               if (inet_addr_type(&init_net, v4addr) != RTN_LOCAL) {
                        err = -EADDRNOTAVAIL;
                        goto out;
                }
@@ -314,7 +312,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                         */
                        v4addr = LOOPBACK4_IPV6;
                        if (!(addr_type & IPV6_ADDR_MULTICAST)) {
-                               if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
+                               if (!ipv6_chk_addr(&init_net, &addr->sin6_addr,
+                                                  dev, 0)) {
                                        if (dev)
                                                dev_put(dev);
                                        err = -EADDRNOTAVAIL;
@@ -491,6 +490,7 @@ const struct proto_ops inet6_stream_ops = {
        .recvmsg           = sock_common_recvmsg,       /* ok           */
        .mmap              = sock_no_mmap,
        .sendpage          = tcp_sendpage,
+       .splice_read       = tcp_splice_read,
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_sock_common_setsockopt,
        .compat_getsockopt = compat_sock_common_getsockopt,
@@ -528,57 +528,23 @@ static struct net_proto_family inet6_family_ops = {
        .owner  = THIS_MODULE,
 };
 
-/* Same as inet6_dgram_ops, sans udp_poll.  */
-static const struct proto_ops inet6_sockraw_ops = {
-       .family            = PF_INET6,
-       .owner             = THIS_MODULE,
-       .release           = inet6_release,
-       .bind              = inet6_bind,
-       .connect           = inet_dgram_connect,        /* ok           */
-       .socketpair        = sock_no_socketpair,        /* a do nothing */
-       .accept            = sock_no_accept,            /* a do nothing */
-       .getname           = inet6_getname,
-       .poll              = datagram_poll,             /* ok           */
-       .ioctl             = inet6_ioctl,               /* must change  */
-       .listen            = sock_no_listen,            /* ok           */
-       .shutdown          = inet_shutdown,             /* ok           */
-       .setsockopt        = sock_common_setsockopt,    /* ok           */
-       .getsockopt        = sock_common_getsockopt,    /* ok           */
-       .sendmsg           = inet_sendmsg,              /* ok           */
-       .recvmsg           = sock_common_recvmsg,       /* ok           */
-       .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 struct inet_protosw rawv6_protosw = {
-       .type           = SOCK_RAW,
-       .protocol       = IPPROTO_IP,   /* wild card */
-       .prot           = &rawv6_prot,
-       .ops            = &inet6_sockraw_ops,
-       .capability     = CAP_NET_RAW,
-       .no_check       = UDP_CSUM_DEFAULT,
-       .flags          = INET_PROTOSW_REUSE,
-};
-
-void
-inet6_register_protosw(struct inet_protosw *p)
+int inet6_register_protosw(struct inet_protosw *p)
 {
        struct list_head *lh;
        struct inet_protosw *answer;
-       int protocol = p->protocol;
        struct list_head *last_perm;
+       int protocol = p->protocol;
+       int ret;
 
        spin_lock_bh(&inetsw6_lock);
 
+       ret = -EINVAL;
        if (p->type >= SOCK_MAX)
                goto out_illegal;
 
        /* If we are trying to override a permanent protocol, bail. */
        answer = NULL;
+       ret = -EPERM;
        last_perm = &inetsw6[p->type];
        list_for_each(lh, &inetsw6[p->type]) {
                answer = list_entry(lh, struct inet_protosw, list);
@@ -602,9 +568,10 @@ inet6_register_protosw(struct inet_protosw *p)
         * system automatically returns to the old behavior.
         */
        list_add_rcu(&p->list, last_perm);
+       ret = 0;
 out:
        spin_unlock_bh(&inetsw6_lock);
-       return;
+       return ret;
 
 out_permanent:
        printk(KERN_ERR "Attempt to override permanent protocol %d.\n",
@@ -713,20 +680,19 @@ EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
 
 static int __init init_ipv6_mibs(void)
 {
-       if (snmp_mib_init((void **)ipv6_statistics, sizeof (struct ipstats_mib),
-                         __alignof__(struct ipstats_mib)) < 0)
+       if (snmp_mib_init((void **)ipv6_statistics,
+                         sizeof(struct ipstats_mib)) < 0)
                goto err_ip_mib;
-       if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
-                         __alignof__(struct icmpv6_mib)) < 0)
+       if (snmp_mib_init((void **)icmpv6_statistics,
+                         sizeof(struct icmpv6_mib)) < 0)
                goto err_icmp_mib;
        if (snmp_mib_init((void **)icmpv6msg_statistics,
-           sizeof (struct icmpv6msg_mib), __alignof__(struct icmpv6_mib)) < 0)
+                         sizeof(struct icmpv6msg_mib)) < 0)
                goto err_icmpmsg_mib;
-       if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
-                         __alignof__(struct udp_mib)) < 0)
+       if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
                goto err_udp_mib;
-       if (snmp_mib_init((void **)udplite_stats_in6, sizeof (struct udp_mib),
-                         __alignof__(struct udp_mib)) < 0)
+       if (snmp_mib_init((void **)udplite_stats_in6,
+                         sizeof (struct udp_mib)) < 0)
                goto err_udplite_mib;
        return 0;
 
@@ -752,6 +718,32 @@ static void cleanup_ipv6_mibs(void)
        snmp_mib_free((void **)udplite_stats_in6);
 }
 
+static int inet6_net_init(struct net *net)
+{
+       net->ipv6.sysctl.bindv6only = 0;
+       net->ipv6.sysctl.flush_delay = 0;
+       net->ipv6.sysctl.ip6_rt_max_size = 4096;
+       net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
+       net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
+       net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
+       net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
+       net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
+       net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
+       net->ipv6.sysctl.icmpv6_time = 1*HZ;
+
+       return 0;
+}
+
+static void inet6_net_exit(struct net *net)
+{
+       return;
+}
+
+static struct pernet_operations inet6_net_ops = {
+       .init = inet6_net_init,
+       .exit = inet6_net_exit,
+};
+
 static int __init inet6_init(void)
 {
        struct sk_buff *dummy_skb;
@@ -768,7 +760,6 @@ static int __init inet6_init(void)
        __this_module.can_unload = &ipv6_unload;
 #endif
 #endif
-
        err = proto_register(&tcpv6_prot, 1);
        if (err)
                goto out;
@@ -793,14 +784,16 @@ static int __init inet6_init(void)
        /* We MUST register RAW sockets before we create the ICMP6,
         * IGMP6, or NDISC control sockets.
         */
-       inet6_register_protosw(&rawv6_protosw);
+       err = rawv6_init();
+       if (err)
+               goto out_unregister_raw_proto;
 
        /* Register the family here so that the init calls below will
         * be able to create sockets. (?? is this dangerous ??)
         */
        err = sock_register(&inet6_family_ops);
        if (err)
-               goto out_unregister_raw_proto;
+               goto out_sock_register_fail;
 
        /* Initialise ipv6 mibs */
        err = init_ipv6_mibs();
@@ -814,8 +807,14 @@ static int __init inet6_init(void)
         *      able to communicate via both network protocols.
         */
 
+       err = register_pernet_subsys(&inet6_net_ops);
+       if (err)
+               goto register_pernet_fail;
+
 #ifdef CONFIG_SYSCTL
-       ipv6_sysctl_register();
+       err = ipv6_sysctl_register();
+       if (err)
+               goto sysctl_fail;
 #endif
        err = icmpv6_init(&inet6_family_ops);
        if (err)
@@ -848,31 +847,61 @@ static int __init inet6_init(void)
        if (if6_proc_init())
                goto proc_if6_fail;
 #endif
-       ip6_route_init();
-       ip6_flowlabel_init();
+       err = ip6_route_init();
+       if (err)
+               goto ip6_route_fail;
+       err = ip6_flowlabel_init();
+       if (err)
+               goto ip6_flowlabel_fail;
        err = addrconf_init();
        if (err)
                goto addrconf_fail;
 
        /* Init v6 extension headers. */
-       ipv6_rthdr_init();
-       ipv6_frag_init();
-       ipv6_nodata_init();
-       ipv6_destopt_init();
+       err = ipv6_exthdrs_init();
+       if (err)
+               goto ipv6_exthdrs_fail;
+
+       err = ipv6_frag_init();
+       if (err)
+               goto ipv6_frag_fail;
 
        /* Init v6 transport protocols. */
-       udpv6_init();
-       udplitev6_init();
-       tcpv6_init();
+       err = udpv6_init();
+       if (err)
+               goto udpv6_fail;
 
-       ipv6_packet_init();
-       err = 0;
+       err = udplitev6_init();
+       if (err)
+               goto udplitev6_fail;
+
+       err = tcpv6_init();
+       if (err)
+               goto tcpv6_fail;
+
+       err = ipv6_packet_init();
+       if (err)
+               goto ipv6_packet_fail;
 out:
        return err;
 
+ipv6_packet_fail:
+       tcpv6_exit();
+tcpv6_fail:
+       udplitev6_exit();
+udplitev6_fail:
+       udpv6_exit();
+udpv6_fail:
+       ipv6_frag_exit();
+ipv6_frag_fail:
+       ipv6_exthdrs_exit();
+ipv6_exthdrs_fail:
+       addrconf_cleanup();
 addrconf_fail:
        ip6_flowlabel_cleanup();
+ip6_flowlabel_fail:
        ip6_route_cleanup();
+ip6_route_fail:
 #ifdef CONFIG_PROC_FS
        if6_proc_exit();
 proc_if6_fail:
@@ -899,10 +928,16 @@ ndisc_fail:
 icmp_fail:
 #ifdef CONFIG_SYSCTL
        ipv6_sysctl_unregister();
+sysctl_fail:
 #endif
+       unregister_pernet_subsys(&inet6_net_ops);
+register_pernet_fail:
        cleanup_ipv6_mibs();
 out_unregister_sock:
        sock_unregister(PF_INET6);
+       rtnl_unregister_all(PF_INET6);
+out_sock_register_fail:
+       rawv6_exit();
 out_unregister_raw_proto:
        proto_unregister(&rawv6_prot);
 out_unregister_udplite_proto:
@@ -922,9 +957,14 @@ static void __exit inet6_exit(void)
        /* Disallow any further netlink messages */
        rtnl_unregister_all(PF_INET6);
 
+       udpv6_exit();
+       udplitev6_exit();
+       tcpv6_exit();
+
        /* Cleanup code parts. */
        ipv6_packet_cleanup();
-
+       ipv6_frag_exit();
+       ipv6_exthdrs_exit();
        addrconf_cleanup();
        ip6_flowlabel_cleanup();
        ip6_route_cleanup();
@@ -943,9 +983,11 @@ static void __exit inet6_exit(void)
        igmp6_cleanup();
        ndisc_cleanup();
        icmpv6_cleanup();
+       rawv6_exit();
 #ifdef CONFIG_SYSCTL
        ipv6_sysctl_unregister();
 #endif
+       unregister_pernet_subsys(&inet6_net_ops);
        cleanup_ipv6_mibs();
        proto_unregister(&rawv6_prot);
        proto_unregister(&udplitev6_prot);
index 4eaf55072b1b05ff7c52537acb01eead7bd761f4..fb0d07a15e934678c8c91fbfa5bcf0be5718a50a 100644 (file)
@@ -370,6 +370,7 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
        ip6h->flow_lbl[2] = 0;
        ip6h->hop_limit   = 0;
 
+       spin_lock(&x->lock);
        {
                u8 auth_data[MAX_AH_AUTH_LEN];
 
@@ -378,14 +379,15 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
                skb_push(skb, hdr_len);
                err = ah_mac_digest(ahp, skb, ah->auth_data);
                if (err)
-                       goto free_out;
-               err = -EINVAL;
-               if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "ipsec ah authentication error\n");
-                       x->stats.integrity_failed++;
-                       goto free_out;
-               }
+                       goto unlock;
+               if (memcmp(ahp->work_icv, auth_data, ahp->icv_trunc_len))
+                       err = -EBADMSG;
        }
+unlock:
+       spin_unlock(&x->lock);
+
+       if (err)
+               goto free_out;
 
        skb->network_header += ah_hlen;
        memcpy(skb_network_header(skb), tmp_hdr, hdr_len);
index f915c4df9820085fb5a5ff5798c152f89e4f7f4d..9c7f83fbc3a1d28b89bf7f26115c4d8d39f92085 100644 (file)
@@ -89,7 +89,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
                return -EPERM;
        if (ipv6_addr_is_multicast(addr))
                return -EINVAL;
-       if (ipv6_chk_addr(addr, NULL, 0))
+       if (ipv6_chk_addr(&init_net, addr, NULL, 0))
                return -EINVAL;
 
        pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
@@ -504,6 +504,7 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
        read_lock(&dev_base_lock);
        return ac6_get_idx(seq, *pos);
@@ -518,6 +519,7 @@ static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ac6_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        struct ac6_iter_state *state = ac6_seq_private(seq);
        if (likely(state->idev != NULL)) {
index 5d4245ab4183fa0d47b4557471ac2b09f4459b47..94fa6ae77cfe28c6f92c04e336cc56aedfbf4507 100644 (file)
@@ -177,7 +177,7 @@ ipv4_connected:
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -549,7 +549,8 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                                                return -ENODEV;
                                }
                        }
-                       if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) {
+                       if (!ipv6_chk_addr(&init_net, &src_info->ipi6_addr,
+                                          dev, 0)) {
                                if (dev)
                                        dev_put(dev);
                                err = -EINVAL;
index 44405325467626a5ca473ef647872ec8cdb14753..5bd5292ad9fa9021cf31899355db8cd60857a165 100644 (file)
@@ -165,31 +165,32 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                goto out;
        }
 
+       if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       skb->ip_summed = CHECKSUM_NONE;
+
+       spin_lock(&x->lock);
+
        /* If integrity check is required, do this. */
        if (esp->auth.icv_full_len) {
                u8 sum[alen];
 
                ret = esp_mac_digest(esp, skb, 0, skb->len - alen);
                if (ret)
-                       goto out;
+                       goto unlock;
 
                if (skb_copy_bits(skb, skb->len - alen, sum, alen))
                        BUG();
 
                if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) {
-                       x->stats.integrity_failed++;
-                       ret = -EINVAL;
-                       goto out;
+                       ret = -EBADMSG;
+                       goto unlock;
                }
        }
 
-       if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0) {
-               ret = -EINVAL;
-               goto out;
-       }
-
-       skb->ip_summed = CHECKSUM_NONE;
-
        esph = (struct ip_esp_hdr *)skb->data;
        iph = ipv6_hdr(skb);
 
@@ -198,15 +199,13 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
 
        {
-               u8 nexthdr[2];
                struct scatterlist *sg = &esp->sgbuf[0];
-               u8 padlen;
 
                if (unlikely(nfrags > ESP_NUM_FAST_SG)) {
                        sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);
                        if (!sg) {
                                ret = -ENOMEM;
-                               goto out;
+                               goto unlock;
                        }
                }
                sg_init_table(sg, nfrags);
@@ -216,8 +215,17 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
                if (unlikely(sg != &esp->sgbuf[0]))
                        kfree(sg);
-               if (unlikely(ret))
-                       goto out;
+       }
+
+unlock:
+       spin_unlock(&x->lock);
+
+       if (unlikely(ret))
+               goto out;
+
+       {
+               u8 nexthdr[2];
+               u8 padlen;
 
                if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
                        BUG();
index 1e89efd38a0c6094317495cce83e9add082e69f5..3cd1c993d52b8fa6988c84140ca9fc387e55f312 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/in6.h>
 #include <linux/icmpv6.h>
 
+#include <net/dst.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 
@@ -307,38 +308,6 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
        return -1;
 }
 
-static struct inet6_protocol destopt_protocol = {
-       .handler        =       ipv6_destopt_rcv,
-       .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
-};
-
-void __init ipv6_destopt_init(void)
-{
-       if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
-               printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
-}
-
-/********************************
-  NONE header. No data in packet.
- ********************************/
-
-static int ipv6_nodata_rcv(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return 0;
-}
-
-static struct inet6_protocol nodata_protocol = {
-       .handler        =       ipv6_nodata_rcv,
-       .flags          =       INET6_PROTO_NOPOLICY,
-};
-
-void __init ipv6_nodata_init(void)
-{
-       if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
-               printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
-}
-
 /********************************
   Routing header.
  ********************************/
@@ -476,7 +445,7 @@ looped_back:
                        kfree_skb(skb);
                        return -1;
                }
-               if (!ipv6_chk_home_addr(addr)) {
+               if (!ipv6_chk_home_addr(&init_net, addr)) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INADDRERRORS);
                        kfree_skb(skb);
@@ -536,12 +505,48 @@ static struct inet6_protocol rthdr_protocol = {
        .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
 };
 
-void __init ipv6_rthdr_init(void)
+static struct inet6_protocol destopt_protocol = {
+       .handler        =       ipv6_destopt_rcv,
+       .flags          =       INET6_PROTO_NOPOLICY | INET6_PROTO_GSO_EXTHDR,
+};
+
+static struct inet6_protocol nodata_protocol = {
+       .handler        =       dst_discard,
+       .flags          =       INET6_PROTO_NOPOLICY,
+};
+
+int __init ipv6_exthdrs_init(void)
 {
-       if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
-               printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
+       int ret;
+
+       ret = inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+       if (ret)
+               goto out;
+
+       ret = inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
+       if (ret)
+               goto out_rthdr;
+
+       ret = inet6_add_protocol(&nodata_protocol, IPPROTO_NONE);
+       if (ret)
+               goto out_destopt;
+
+out:
+       return ret;
+out_rthdr:
+       inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+out_destopt:
+       inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
+       goto out;
 };
 
+void ipv6_exthdrs_exit(void)
+{
+       inet6_del_protocol(&nodata_protocol, IPPROTO_NONE);
+       inet6_del_protocol(&destopt_protocol, IPPROTO_DSTOPTS);
+       inet6_del_protocol(&rthdr_protocol, IPPROTO_ROUTING);
+}
+
 /**********************************
   Hop-by-hop options.
  **********************************/
index 428c6b0e26d8e7238530e6b3d1c886f5c398af98..695c0ca8a41708296384f9312fbfc79946cc1537 100644 (file)
@@ -223,7 +223,7 @@ nla_put_failure:
        return -ENOBUFS;
 }
 
-static u32 fib6_rule_default_pref(void)
+static u32 fib6_rule_default_pref(struct fib_rules_ops *ops)
 {
        return 0x3FFF;
 }
@@ -249,6 +249,7 @@ static struct fib_rules_ops fib6_rules_ops = {
        .policy                 = fib6_rule_policy,
        .rules_list             = LIST_HEAD_INIT(fib6_rules_ops.rules_list),
        .owner                  = THIS_MODULE,
+       .fro_net                = &init_net,
 };
 
 static int __init fib6_default_rules_init(void)
@@ -265,10 +266,23 @@ static int __init fib6_default_rules_init(void)
        return 0;
 }
 
-void __init fib6_rules_init(void)
+int __init fib6_rules_init(void)
 {
-       BUG_ON(fib6_default_rules_init());
-       fib_rules_register(&fib6_rules_ops);
+       int ret;
+
+       ret = fib6_default_rules_init();
+       if (ret)
+               goto out;
+
+       ret = fib_rules_register(&fib6_rules_ops);
+       if (ret)
+               goto out_default_rules_init;
+out:
+       return ret;
+
+out_default_rules_init:
+       fib_rules_cleanup_ops(&fib6_rules_ops);
+       goto out;
 }
 
 void fib6_rules_cleanup(void)
index f1240688dc5849ca469566f9830b473ac36a0814..cbb5b9cf84ad36eba8741bec98cb2409040d3c93 100644 (file)
@@ -63,6 +63,7 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 #include <net/icmp.h>
+#include <net/xfrm.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -86,7 +87,7 @@ static int icmpv6_rcv(struct sk_buff *skb);
 
 static struct inet6_protocol icmpv6_protocol = {
        .handler        =       icmpv6_rcv,
-       .flags          =       INET6_PROTO_FINAL,
+       .flags          =       INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
 static __inline__ int icmpv6_xmit_lock(void)
@@ -153,8 +154,6 @@ static int is_ineligible(struct sk_buff *skb)
        return 0;
 }
 
-static int sysctl_icmpv6_time __read_mostly = 1*HZ;
-
 /*
  * Check the ICMP output rate limit
  */
@@ -185,7 +184,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
                res = 1;
        } else {
                struct rt6_info *rt = (struct rt6_info *)dst;
-               int tmo = sysctl_icmpv6_time;
+               int tmo = init_net.ipv6.sysctl.icmpv6_time;
 
                /* Give more bandwidth to wider prefixes. */
                if (rt->rt6i_dst.plen < 128)
@@ -310,8 +309,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        struct ipv6_pinfo *np;
        struct in6_addr *saddr = NULL;
        struct dst_entry *dst;
+       struct dst_entry *dst2;
        struct icmp6hdr tmp_hdr;
        struct flowi fl;
+       struct flowi fl2;
        struct icmpv6_msg msg;
        int iif = 0;
        int addr_type = 0;
@@ -331,7 +332,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
         */
        addr_type = ipv6_addr_type(&hdr->daddr);
 
-       if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0))
+       if (ipv6_chk_addr(&init_net, &hdr->daddr, skb->dev, 0))
                saddr = &hdr->daddr;
 
        /*
@@ -418,9 +419,42 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
                goto out_dst_release;
        }
 
-       if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+       /* No need to clone since we're just using its address. */
+       dst2 = dst;
+
+       err = xfrm_lookup(&dst, &fl, sk, 0);
+       switch (err) {
+       case 0:
+               if (dst != dst2)
+                       goto route_done;
+               break;
+       case -EPERM:
+               dst = NULL;
+               break;
+       default:
+               goto out;
+       }
+
+       if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6))
+               goto out;
+
+       if (ip6_dst_lookup(sk, &dst2, &fl))
+               goto out;
+
+       err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
+       if (err == -ENOENT) {
+               if (!dst)
+                       goto out;
+               goto route_done;
+       }
+
+       dst_release(dst);
+       dst = dst2;
+
+       if (err)
                goto out;
 
+route_done:
        if (ipv6_addr_is_multicast(&fl.fl6_dst))
                hlimit = np->mcast_hops;
        else
@@ -555,9 +589,7 @@ out:
 
 static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
 {
-       struct in6_addr *saddr, *daddr;
        struct inet6_protocol *ipprot;
-       struct sock *sk;
        int inner_offset;
        int hash;
        u8 nexthdr;
@@ -579,9 +611,6 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
        if (!pskb_may_pull(skb, inner_offset+8))
                return;
 
-       saddr = &ipv6_hdr(skb)->saddr;
-       daddr = &ipv6_hdr(skb)->daddr;
-
        /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
           Without this we will not able f.e. to make source routed
           pmtu discovery.
@@ -597,15 +626,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
                ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
        rcu_read_unlock();
 
-       read_lock(&raw_v6_lock);
-       if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
-               while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
-                                           IP6CB(skb)->iif))) {
-                       rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
-                       sk = sk_next(sk);
-               }
-       }
-       read_unlock(&raw_v6_lock);
+       raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
 }
 
 /*
@@ -621,6 +642,25 @@ static int icmpv6_rcv(struct sk_buff *skb)
        struct icmp6hdr *hdr;
        int type;
 
+       if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+               int nh;
+
+               if (!(skb->sp && skb->sp->xvec[skb->sp->len - 1]->props.flags &
+                                XFRM_STATE_ICMP))
+                       goto drop_no_count;
+
+               if (!pskb_may_pull(skb, sizeof(*hdr) + sizeof(*orig_hdr)))
+                       goto drop_no_count;
+
+               nh = skb_network_offset(skb);
+               skb_set_network_header(skb, sizeof(*hdr));
+
+               if (!xfrm6_policy_check_reverse(NULL, XFRM_POLICY_IN, skb))
+                       goto drop_no_count;
+
+               skb_set_network_header(skb, nh);
+       }
+
        ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
 
        saddr = &ipv6_hdr(skb)->saddr;
@@ -643,8 +683,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
                }
        }
 
-       if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
-               goto discard_it;
+       __skb_pull(skb, sizeof(*hdr));
 
        hdr = icmp6_hdr(skb);
 
@@ -730,6 +769,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
 discard_it:
        ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS);
+drop_no_count:
        kfree_skb(skb);
        return 0;
 }
@@ -865,16 +905,26 @@ int icmpv6_err_convert(int type, int code, int *err)
 EXPORT_SYMBOL(icmpv6_err_convert);
 
 #ifdef CONFIG_SYSCTL
-ctl_table ipv6_icmp_table[] = {
+ctl_table ipv6_icmp_table_template[] = {
        {
                .ctl_name       = NET_IPV6_ICMP_RATELIMIT,
                .procname       = "ratelimit",
-               .data           = &sysctl_icmpv6_time,
+               .data           = &init_net.ipv6.sysctl.icmpv6_time,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
        { .ctl_name = 0 },
 };
+
+struct ctl_table *ipv6_icmp_sysctl_init(struct net *net)
+{
+       struct ctl_table *table;
+
+       table = kmemdup(ipv6_icmp_table_template,
+                       sizeof(ipv6_icmp_table_template),
+                       GFP_KERNEL);
+       return table;
+}
 #endif
 
index 0765d8bd380f623ad6b29291af39daa4ee77ad69..a66a7d8e281133f7f8a6000cf482b35bfe5c4cd9 100644 (file)
@@ -43,7 +43,7 @@ void __inet6_hash(struct inet_hashinfo *hashinfo,
        }
 
        __sk_add_node(sk, list);
-       sock_prot_inc_use(sk->sk_prot);
+       sock_prot_inuse_add(sk->sk_prot, 1);
        write_unlock(lock);
 }
 EXPORT_SYMBOL(__inet6_hash);
@@ -216,7 +216,7 @@ unique:
        BUG_TRAP(sk_unhashed(sk));
        __sk_add_node(sk, &head->chain);
        sk->sk_hash = hash;
-       sock_prot_inc_use(sk->sk_prot);
+       sock_prot_inuse_add(sk->sk_prot, 1);
        write_unlock(lock);
 
        if (twp != NULL) {
index 946cf389ab95716a27a98fda7ca448b99524993c..f93407cf651511ea9d4fa22b9c3f0f9ce94085fe 100644 (file)
@@ -361,6 +361,7 @@ end:
 
 static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        unsigned int h, s_h;
        unsigned int e = 0, s_e;
        struct rt6_rtnl_dump_arg arg;
@@ -369,6 +370,9 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
        struct hlist_node *node;
        int res = 0;
 
+       if (net != &init_net)
+               return 0;
+
        s_h = cb->args[0];
        s_e = cb->args[1];
 
@@ -677,13 +681,15 @@ static __inline__ void fib6_start_gc(struct rt6_info *rt)
 {
        if (ip6_fib_timer.expires == 0 &&
            (rt->rt6i_flags & (RTF_EXPIRES|RTF_CACHE)))
-               mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+               mod_timer(&ip6_fib_timer, jiffies +
+                         init_net.ipv6.sysctl.ip6_rt_gc_interval);
 }
 
 void fib6_force_start_gc(void)
 {
        if (ip6_fib_timer.expires == 0)
-               mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+               mod_timer(&ip6_fib_timer, jiffies +
+                         init_net.ipv6.sysctl.ip6_rt_gc_interval);
 }
 
 /*
@@ -1122,9 +1128,6 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp,
 
        rt->u.dst.rt6_next = NULL;
 
-       if (fn->leaf == NULL && fn->fn_flags&RTN_TL_ROOT)
-               fn->leaf = &ip6_null_entry;
-
        /* If it was last route, expunge its radix tree node */
        if (fn->leaf == NULL) {
                fn->fn_flags &= ~RTN_RTINFO;
@@ -1311,6 +1314,9 @@ static int fib6_walk(struct fib6_walker_t *w)
 
 static int fib6_clean_node(struct fib6_walker_t *w)
 {
+       struct nl_info info = {
+               .nl_net = &init_net,
+       };
        int res;
        struct rt6_info *rt;
        struct fib6_cleaner_t *c = container_of(w, struct fib6_cleaner_t, w);
@@ -1319,7 +1325,7 @@ static int fib6_clean_node(struct fib6_walker_t *w)
                res = c->func(rt, c->arg);
                if (res < 0) {
                        w->leaf = rt;
-                       res = fib6_del(rt, NULL);
+                       res = fib6_del(rt, &info);
                        if (res) {
 #if RT6_DEBUG >= 2
                                printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
@@ -1445,7 +1451,8 @@ void fib6_run_gc(unsigned long dummy)
 {
        if (dummy != ~0UL) {
                spin_lock_bh(&fib6_gc_lock);
-               gc_args.timeout = dummy ? (int)dummy : ip6_rt_gc_interval;
+               gc_args.timeout = dummy ? (int)dummy :
+                       init_net.ipv6.sysctl.ip6_rt_gc_interval;
        } else {
                local_bh_disable();
                if (!spin_trylock(&fib6_gc_lock)) {
@@ -1453,7 +1460,7 @@ void fib6_run_gc(unsigned long dummy)
                        local_bh_enable();
                        return;
                }
-               gc_args.timeout = ip6_rt_gc_interval;
+               gc_args.timeout = init_net.ipv6.sysctl.ip6_rt_gc_interval;
        }
        gc_args.more = 0;
 
@@ -1461,7 +1468,8 @@ void fib6_run_gc(unsigned long dummy)
        fib6_clean_all(fib6_age, 0, NULL);
 
        if (gc_args.more)
-               mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
+               mod_timer(&ip6_fib_timer, jiffies +
+                         init_net.ipv6.sysctl.ip6_rt_gc_interval);
        else {
                del_timer(&ip6_fib_timer);
                ip6_fib_timer.expires = 0;
@@ -1469,16 +1477,27 @@ void fib6_run_gc(unsigned long dummy)
        spin_unlock_bh(&fib6_gc_lock);
 }
 
-void __init fib6_init(void)
+int __init fib6_init(void)
 {
+       int ret;
        fib6_node_kmem = kmem_cache_create("fib6_nodes",
                                           sizeof(struct fib6_node),
-                                          0, SLAB_HWCACHE_ALIGN|SLAB_PANIC,
+                                          0, SLAB_HWCACHE_ALIGN,
                                           NULL);
+       if (!fib6_node_kmem)
+               return -ENOMEM;
 
        fib6_tables_init();
 
-       __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
+       ret = __rtnl_register(PF_INET6, RTM_GETROUTE, NULL, inet6_dump_fib);
+       if (ret)
+               goto out_kmem_cache_create;
+out:
+       return ret;
+
+out_kmem_cache_create:
+       kmem_cache_destroy(fib6_node_kmem);
+       goto out;
 }
 
 void fib6_gc_cleanup(void)
index b12cc22e7745d4f629a1abe1871cfce161e551aa..2b7d9ee98832f5d1a0afce7095bc8f8e10dea66f 100644 (file)
@@ -629,6 +629,7 @@ static struct ip6_flowlabel *ip6fl_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(ip6_fl_lock)
 {
        read_lock_bh(&ip6_fl_lock);
        return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -647,6 +648,7 @@ static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void ip6fl_seq_stop(struct seq_file *seq, void *v)
+       __releases(ip6_fl_lock)
 {
        read_unlock_bh(&ip6_fl_lock);
 }
@@ -692,20 +694,36 @@ static const struct file_operations ip6fl_seq_fops = {
        .llseek         =       seq_lseek,
        .release        =       seq_release_private,
 };
-#endif
 
+static int ip6_flowlabel_proc_init(struct net *net)
+{
+       if (!proc_net_fops_create(net, "ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops))
+               return -ENOMEM;
+       return 0;
+}
 
-void ip6_flowlabel_init(void)
+static void ip6_flowlabel_proc_fini(struct net *net)
 {
-#ifdef CONFIG_PROC_FS
-       proc_net_fops_create(&init_net, "ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
+       proc_net_remove(net, "ip6_flowlabel");
+}
+#else
+static inline int ip6_flowlabel_proc_init(struct net *net)
+{
+       return 0;
+}
+static inline void ip6_flowlabel_proc_fini(struct net *net)
+{
+       return ;
+}
 #endif
+
+int ip6_flowlabel_init(void)
+{
+       return ip6_flowlabel_proc_init(&init_net);
 }
 
 void ip6_flowlabel_cleanup(void)
 {
        del_timer(&ip6_fl_gc_timer);
-#ifdef CONFIG_PROC_FS
-       proc_net_remove(&init_net, "ip6_flowlabel");
-#endif
+       ip6_flowlabel_proc_fini(&init_net);
 }
index fac6f7f9dd73a7722831a0f4ed716e9f31c2d6e5..178aebc0427a1d05051598b9ab2f6b233abfbb66 100644 (file)
@@ -134,7 +134,8 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 
        rcu_read_unlock();
 
-       return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
+       return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL,
+                      ip6_rcv_finish);
 err:
        IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
 drop:
@@ -152,9 +153,8 @@ out:
 static int ip6_input_finish(struct sk_buff *skb)
 {
        struct inet6_protocol *ipprot;
-       struct sock *raw_sk;
        unsigned int nhoff;
-       int nexthdr;
+       int nexthdr, raw;
        u8 hash;
        struct inet6_dev *idev;
 
@@ -170,9 +170,7 @@ resubmit:
        nhoff = IP6CB(skb)->nhoff;
        nexthdr = skb_network_header(skb)[nhoff];
 
-       raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
-       if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
-               raw_sk = NULL;
+       raw = raw6_local_deliver(skb, nexthdr);
 
        hash = nexthdr & (MAX_INET_PROTOS - 1);
        if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) {
@@ -205,7 +203,7 @@ resubmit:
                else if (ret == 0)
                        IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
        } else {
-               if (!raw_sk) {
+               if (!raw) {
                        if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
                                IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS);
                                icmpv6_send(skb, ICMPV6_PARAMPROB,
@@ -229,7 +227,8 @@ discard:
 
 int ip6_input(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6,NF_IP6_LOCAL_IN, skb, skb->dev, NULL, ip6_input_finish);
+       return NF_HOOK(PF_INET6, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
+                      ip6_input_finish);
 }
 
 int ip6_mc_input(struct sk_buff *skb)
index 3bef30e4a23d870e6c8d55c253412ce1356f01ca..15c4f6cee3e6e54daf41bec34d5015fb7a5fdf4b 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 #include <linux/errno.h>
-#include <linux/types.h>
+#include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/socket.h>
 #include <linux/net.h>
@@ -70,6 +70,31 @@ static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *f
        spin_unlock_bh(&ip6_id_lock);
 }
 
+int __ip6_local_out(struct sk_buff *skb)
+{
+       int len;
+
+       len = skb->len - sizeof(struct ipv6hdr);
+       if (len > IPV6_MAXPLEN)
+               len = 0;
+       ipv6_hdr(skb)->payload_len = htons(len);
+
+       return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev,
+                      dst_output);
+}
+
+int ip6_local_out(struct sk_buff *skb)
+{
+       int err;
+
+       err = __ip6_local_out(skb);
+       if (likely(err == 1))
+               err = dst_output(skb);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(ip6_local_out);
+
 static int ip6_output_finish(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb->dst;
@@ -120,8 +145,8 @@ static int ip6_output2(struct sk_buff *skb)
                           is not supported in any case.
                         */
                        if (newskb)
-                               NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, newskb, NULL,
-                                       newskb->dev,
+                               NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, newskb,
+                                       NULL, newskb->dev,
                                        ip6_dev_loopback_xmit);
 
                        if (ipv6_hdr(skb)->hop_limit == 0) {
@@ -134,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
                IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
        }
 
-       return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
+       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
+                      ip6_output_finish);
 }
 
 static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
@@ -236,7 +262,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
                IP6_INC_STATS(ip6_dst_idev(skb->dst),
                              IPSTATS_MIB_OUTREQUESTS);
-               return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
+               return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
                                dst_output);
        }
 
@@ -423,7 +449,7 @@ int ip6_forward(struct sk_buff *skb)
 
        /* XXX: idev->cnf.proxy_ndp? */
        if (ipv6_devconf.proxy_ndp &&
-           pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
+           pneigh_lookup(&nd_tbl, &init_net, &hdr->daddr, skb->dev, 0)) {
                int proxied = ip6_forward_proxy_check(skb);
                if (proxied > 0)
                        return ip6_input(skb);
@@ -500,7 +526,8 @@ int ip6_forward(struct sk_buff *skb)
        hdr->hop_limit--;
 
        IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
-       return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
+       return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
+                      ip6_forward_finish);
 
 error:
        IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
@@ -909,7 +936,8 @@ static int ip6_dst_lookup_tail(struct sock *sk,
                        struct flowi fl_gw;
                        int redirect;
 
-                       ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1);
+                       ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
+                                             (*dst)->dev, 1);
 
                        redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
                        if (ifp)
@@ -1098,7 +1126,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
                inet->cork.length = 0;
                sk->sk_sndmsg_page = NULL;
                sk->sk_sndmsg_off = 0;
-               exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0);
+               exthdrlen = rt->u.dst.header_len + (opt ? opt->opt_flen : 0) -
+                           rt->rt6i_nfheader_len;
                length += exthdrlen;
                transhdrlen += exthdrlen;
        } else {
@@ -1113,7 +1142,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
 
        hh_len = LL_RESERVED_SPACE(rt->u.dst.dev);
 
-       fragheaderlen = sizeof(struct ipv6hdr) + rt->u.dst.nfheader_len + (opt ? opt->opt_nflen : 0);
+       fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
+                       (opt ? opt->opt_nflen : 0);
        maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
 
        if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
@@ -1401,10 +1431,6 @@ int ip6_push_pending_frames(struct sock *sk)
        *(__be32*)hdr = fl->fl6_flowlabel |
                     htonl(0x60000000 | ((int)np->cork.tclass << 20));
 
-       if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
-               hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
-       else
-               hdr->payload_len = 0;
        hdr->hop_limit = np->cork.hop_limit;
        hdr->nexthdr = proto;
        ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
@@ -1421,7 +1447,7 @@ int ip6_push_pending_frames(struct sock *sk)
                ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
        }
 
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
+       err = ip6_local_out(skb);
        if (err) {
                if (err > 0)
                        err = np->recverr ? net_xmit_errno(err) : 0;
index 5383b33db8ca606cb23edfed9cdfad018ef9a74d..9031e521c1df72ce10e1c94397de301e3e203317 100644 (file)
@@ -533,7 +533,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        fl.fl4_dst = eiph->saddr;
        fl.fl4_tos = RT_TOS(eiph->tos);
        fl.proto = IPPROTO_IPIP;
-       if (ip_route_output_key(&rt, &fl))
+       if (ip_route_output_key(&init_net, &rt, &fl))
                goto out;
 
        skb2->dev = rt->u.dst.dev;
@@ -545,7 +545,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                fl.fl4_dst = eiph->daddr;
                fl.fl4_src = eiph->saddr;
                fl.fl4_tos = eiph->tos;
-               if (ip_route_output_key(&rt, &fl) ||
+               if (ip_route_output_key(&init_net, &rt, &fl) ||
                    rt->u.dst.dev->type != ARPHRD_TUNNEL) {
                        ip_rt_put(rt);
                        goto out;
@@ -635,7 +635,7 @@ static void ip6ip6_dscp_ecn_decapsulate(struct ip6_tnl *t,
                                        struct sk_buff *skb)
 {
        if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
-               ipv6_copy_dscp(ipv6h, ipv6_hdr(skb));
+               ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb));
 
        if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
                IP6_ECN_set_ce(ipv6_hdr(skb));
@@ -653,8 +653,8 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
                        ldev = dev_get_by_index(&init_net, p->link);
 
                if ((ipv6_addr_is_multicast(&p->laddr) ||
-                    likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
-                   likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
+                    likely(ipv6_chk_addr(&init_net, &p->laddr, ldev, 0))) &&
+                   likely(!ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
                        ret = 1;
 
                if (ldev)
@@ -788,12 +788,12 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
                if (p->link)
                        ldev = dev_get_by_index(&init_net, p->link);
 
-               if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
+               if (unlikely(!ipv6_chk_addr(&init_net, &p->laddr, ldev, 0)))
                        printk(KERN_WARNING
                               "%s xmit: Local address not yet configured!\n",
                               p->name);
                else if (!ipv6_addr_is_multicast(&p->raddr) &&
-                        unlikely(ipv6_chk_addr(&p->raddr, NULL, 0)))
+                        unlikely(ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
                        printk(KERN_WARNING
                               "%s xmit: Routing loop! "
                               "Remote address found on this node!\n",
@@ -910,15 +910,13 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        *(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000);
        dsfield = INET_ECN_encapsulate(0, dsfield);
        ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
-       ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
        ipv6h->hop_limit = t->parms.hop_limit;
        ipv6h->nexthdr = proto;
        ipv6_addr_copy(&ipv6h->saddr, &fl->fl6_src);
        ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst);
        nf_reset(skb);
        pkt_len = skb->len;
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
-                     skb->dst->dev, dst_output);
+       err = ip6_local_out(skb);
 
        if (net_xmit_eval(err) == 0) {
                stats->tx_bytes += pkt_len;
index 0cd4056f9127e3434cbb63ed27ebcaddb404f54c..b276d04d6db52ea7dc2c1529d3351cc5a6e5b0aa 100644 (file)
@@ -190,7 +190,6 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
 {
        struct xfrm_state *t = NULL;
-       u8 mode = XFRM_MODE_TUNNEL;
 
        t = xfrm_state_alloc();
        if (!t)
@@ -204,9 +203,7 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
        memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
        memcpy(&t->sel, &x->sel, sizeof(t->sel));
        t->props.family = AF_INET6;
-       if (x->props.mode == XFRM_MODE_BEET)
-               mode = x->props.mode;
-       t->props.mode = mode;
+       t->props.mode = x->props.mode;
        memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
 
        if (xfrm_init_state(t))
@@ -405,22 +402,22 @@ static int ipcomp6_init_state(struct xfrm_state *x)
        if (x->encap)
                goto out;
 
-       err = -ENOMEM;
-       ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
-       if (!ipcd)
-               goto out;
-
        x->props.header_len = 0;
        switch (x->props.mode) {
-       case XFRM_MODE_BEET:
        case XFRM_MODE_TRANSPORT:
                break;
        case XFRM_MODE_TUNNEL:
                x->props.header_len += sizeof(struct ipv6hdr);
+               break;
        default:
-               goto error;
+               goto out;
        }
 
+       err = -ENOMEM;
+       ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
+       if (!ipcd)
+               goto out;
+
        mutex_lock(&ipcomp6_resource_mutex);
        if (!ipcomp6_alloc_scratches())
                goto error;
index 8c5f80fd03ada72af490ad8786a3e492a48d3c8c..bf2a686aa13d9ec9314e3a66c0d44c5ec3eaf986 100644 (file)
@@ -268,8 +268,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                                struct inet_connection_sock *icsk = inet_csk(sk);
 
                                local_bh_disable();
-                               sock_prot_dec_use(sk->sk_prot);
-                               sock_prot_inc_use(&tcp_prot);
+                               sock_prot_inuse_add(sk->sk_prot, -1);
+                               sock_prot_inuse_add(&tcp_prot, 1);
                                local_bh_enable();
                                sk->sk_prot = &tcp_prot;
                                icsk->icsk_af_ops = &ipv4_specific;
@@ -282,8 +282,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
                                if (sk->sk_protocol == IPPROTO_UDPLITE)
                                        prot = &udplite_prot;
                                local_bh_disable();
-                               sock_prot_dec_use(sk->sk_prot);
-                               sock_prot_inc_use(prot);
+                               sock_prot_inuse_add(sk->sk_prot, -1);
+                               sock_prot_inuse_add(prot, 1);
                                local_bh_enable();
                                sk->sk_prot = prot;
                                sk->sk_socket->ops = &inet_dgram_ops;
@@ -1128,9 +1128,10 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname,
 EXPORT_SYMBOL(compat_ipv6_getsockopt);
 #endif
 
-void __init ipv6_packet_init(void)
+int __init ipv6_packet_init(void)
 {
        dev_add_pack(&ipv6_packet_type);
+       return 0;
 }
 
 void ipv6_packet_cleanup(void)
index 331d728c2035920a8cbe220115ff492abd073660..ab228d1ea11484892a172eb1098195f5977477f2 100644 (file)
@@ -903,9 +903,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
                return -ENOMEM;
        }
 
-       init_timer(&mc->mca_timer);
-       mc->mca_timer.function = igmp6_timer_handler;
-       mc->mca_timer.data = (unsigned long) mc;
+       setup_timer(&mc->mca_timer, igmp6_timer_handler, (unsigned long)mc);
 
        ipv6_addr_copy(&mc->mca_addr, addr);
        mc->idev = idev;
@@ -1450,7 +1448,7 @@ static inline int mld_dev_queue_xmit2(struct sk_buff *skb)
 
 static inline int mld_dev_queue_xmit(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dev,
+       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
                       mld_dev_queue_xmit2);
 }
 
@@ -1471,7 +1469,7 @@ static void mld_sendpack(struct sk_buff *skb)
        pmr->csum = csum_ipv6_magic(&pip6->saddr, &pip6->daddr, mldlen,
                IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
                                             mldlen, 0));
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                mld_dev_queue_xmit);
        if (!err) {
                ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
@@ -1815,7 +1813,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 
        idev = in6_dev_get(skb->dev);
 
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
+       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                mld_dev_queue_xmit);
        if (!err) {
                ICMP6MSGOUT_INC_STATS(idev, type);
@@ -2259,14 +2257,12 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
        write_lock_bh(&idev->lock);
        rwlock_init(&idev->mc_lock);
        idev->mc_gq_running = 0;
-       init_timer(&idev->mc_gq_timer);
-       idev->mc_gq_timer.data = (unsigned long) idev;
-       idev->mc_gq_timer.function = &mld_gq_timer_expire;
+       setup_timer(&idev->mc_gq_timer, mld_gq_timer_expire,
+                       (unsigned long)idev);
        idev->mc_tomb = NULL;
        idev->mc_ifc_count = 0;
-       init_timer(&idev->mc_ifc_timer);
-       idev->mc_ifc_timer.data = (unsigned long) idev;
-       idev->mc_ifc_timer.function = &mld_ifc_timer_expire;
+       setup_timer(&idev->mc_ifc_timer, mld_ifc_timer_expire,
+                       (unsigned long)idev);
        idev->mc_qrv = MLD_QRV_DEFAULT;
        idev->mc_maxdelay = IGMP6_UNSOLICITED_IVAL;
        idev->mc_v1_seen = 0;
@@ -2377,6 +2373,7 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
        read_lock(&dev_base_lock);
        return igmp6_mc_get_idx(seq, *pos);
@@ -2391,6 +2388,7 @@ static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
        if (likely(state->idev != NULL)) {
@@ -2520,6 +2518,7 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(dev_base_lock)
 {
        read_lock(&dev_base_lock);
        return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -2537,6 +2536,7 @@ static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
+       __releases(dev_base_lock)
 {
        struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
        if (likely(state->im != NULL)) {
index 7fd841d410190382fe5ea1c4b31df9ebada0f07f..49d396620eac97e42d6c4602ac178d3cdfd9f1b8 100644 (file)
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
-static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
-{
-       return x->coaddr;
-}
-
 static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
 {
        return (n - len + 16) & 0x7;
@@ -133,12 +128,15 @@ static int mip6_destopt_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
        struct ipv6_destopt_hdr *destopt = (struct ipv6_destopt_hdr *)skb->data;
+       int err = destopt->nexthdr;
 
+       spin_lock(&x->lock);
        if (!ipv6_addr_equal(&iph->saddr, (struct in6_addr *)x->coaddr) &&
            !ipv6_addr_any((struct in6_addr *)x->coaddr))
-               return -ENOENT;
+               err = -ENOENT;
+       spin_unlock(&x->lock);
 
-       return destopt->nexthdr;
+       return err;
 }
 
 /* Destination Option Header is inserted.
@@ -337,25 +335,27 @@ static struct xfrm_type mip6_destopt_type =
        .description    = "MIP6DESTOPT",
        .owner          = THIS_MODULE,
        .proto          = IPPROTO_DSTOPTS,
-       .flags          = XFRM_TYPE_NON_FRAGMENT,
+       .flags          = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
        .init_state     = mip6_destopt_init_state,
        .destructor     = mip6_destopt_destroy,
        .input          = mip6_destopt_input,
        .output         = mip6_destopt_output,
        .reject         = mip6_destopt_reject,
        .hdr_offset     = mip6_destopt_offset,
-       .local_addr     = mip6_xfrm_addr,
 };
 
 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
+       int err = rt2->rt_hdr.nexthdr;
 
+       spin_lock(&x->lock);
        if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
            !ipv6_addr_any((struct in6_addr *)x->coaddr))
-               return -ENOENT;
+               err = -ENOENT;
+       spin_unlock(&x->lock);
 
-       return rt2->rt_hdr.nexthdr;
+       return err;
 }
 
 /* Routing Header type 2 is inserted.
@@ -467,13 +467,12 @@ static struct xfrm_type mip6_rthdr_type =
        .description    = "MIP6RT",
        .owner          = THIS_MODULE,
        .proto          = IPPROTO_ROUTING,
-       .flags          = XFRM_TYPE_NON_FRAGMENT,
+       .flags          = XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
        .init_state     = mip6_rthdr_init_state,
        .destructor     = mip6_rthdr_destroy,
        .input          = mip6_rthdr_input,
        .output         = mip6_rthdr_output,
        .hdr_offset     = mip6_rthdr_offset,
-       .remote_addr    = mip6_xfrm_addr,
 };
 
 static int __init mip6_init(void)
index 85947eae5bf7d2922f25c88a0d6283cd810395a2..0d33a7d32125b80f102d28e851202c16d2f14fed 100644 (file)
@@ -533,7 +533,8 @@ static void __ndisc_send(struct net_device *dev,
        idev = in6_dev_get(dst->dev);
        IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
 
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
+       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
+                     dst_output);
        if (!err) {
                ICMP6MSGOUT_INC_STATS(idev, type);
                ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
@@ -555,7 +556,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
        };
 
        /* for anycast or proxy, solicited_addr != src_addr */
-       ifp = ipv6_get_ifaddr(solicited_addr, dev, 1);
+       ifp = ipv6_get_ifaddr(&init_net, solicited_addr, dev, 1);
        if (ifp) {
                src_addr = solicited_addr;
                if (ifp->flags & IFA_F_OPTIMISTIC)
@@ -615,7 +616,8 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
         * suppress the inclusion of the sllao.
         */
        if (send_sllao) {
-               struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1);
+               struct inet6_ifaddr *ifp = ipv6_get_ifaddr(&init_net, saddr,
+                                                          dev, 1);
                if (ifp) {
                        if (ifp->flags & IFA_F_OPTIMISTIC)  {
                                send_sllao = 0;
@@ -652,7 +654,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
        struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
        int probes = atomic_read(&neigh->probes);
 
-       if (skb && ipv6_chk_addr(&ipv6_hdr(skb)->saddr, dev, 1))
+       if (skb && ipv6_chk_addr(&init_net, &ipv6_hdr(skb)->saddr, dev, 1))
                saddr = &ipv6_hdr(skb)->saddr;
 
        if ((probes -= neigh->parms->ucast_probes) < 0) {
@@ -740,7 +742,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
 
        inc = ipv6_addr_is_multicast(daddr);
 
-       if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) {
+       if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1)) != NULL) {
 
                if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) {
                        if (dad) {
@@ -788,7 +790,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                if (ipv6_chk_acast_addr(dev, &msg->target) ||
                    (idev->cnf.forwarding &&
                     (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
-                    (pneigh = pneigh_lookup(&nd_tbl,
+                    (pneigh = pneigh_lookup(&nd_tbl, &init_net,
                                             &msg->target, dev, 0)) != NULL)) {
                        if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
                            skb->pkt_type != PACKET_HOST &&
@@ -898,7 +900,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
                        return;
                }
        }
-       if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1))) {
+       if ((ifp = ipv6_get_ifaddr(&init_net, &msg->target, dev, 1))) {
                if (ifp->flags & IFA_F_TENTATIVE) {
                        addrconf_dad_failure(ifp);
                        return;
@@ -929,7 +931,7 @@ static void ndisc_recv_na(struct sk_buff *skb)
                 */
                if (lladdr && !memcmp(lladdr, dev->dev_addr, dev->addr_len) &&
                    ipv6_devconf.forwarding && ipv6_devconf.proxy_ndp &&
-                   pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
+                   pneigh_lookup(&nd_tbl, &init_net, &msg->target, dev, 0)) {
                        /* XXX: idev->cnf.prixy_ndp */
                        goto out;
                }
@@ -1048,7 +1050,8 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt)
                &ipv6_hdr(ra)->saddr);
        nlmsg_end(skb, nlh);
 
-       err = rtnl_notify(skb, 0, RTNLGRP_ND_USEROPT, NULL, GFP_ATOMIC);
+       err = rtnl_notify(skb, &init_net, 0, RTNLGRP_ND_USEROPT, NULL,
+                         GFP_ATOMIC);
        if (err < 0)
                goto errout;
 
@@ -1058,7 +1061,7 @@ nla_put_failure:
        nlmsg_free(skb);
        err = -EMSGSIZE;
 errout:
-       rtnl_set_sk_err(RTNLGRP_ND_USEROPT, err);
+       rtnl_set_sk_err(&init_net, RTNLGRP_ND_USEROPT, err);
 }
 
 static void ndisc_router_discovery(struct sk_buff *skb)
@@ -1294,11 +1297,11 @@ skip_defrtr:
        }
 
        if (ndopts.nd_useropts) {
-               struct nd_opt_hdr *opt;
-               for (opt = ndopts.nd_useropts;
-                    opt;
-                    opt = ndisc_next_useropt(opt, ndopts.nd_useropts_end)) {
-                               ndisc_ra_useropt(skb, opt);
+               struct nd_opt_hdr *p;
+               for (p = ndopts.nd_useropts;
+                    p;
+                    p = ndisc_next_useropt(p, ndopts.nd_useropts_end)) {
+                       ndisc_ra_useropt(skb, p);
                }
        }
 
@@ -1538,7 +1541,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        buff->dst = dst;
        idev = in6_dev_get(dst->dev);
        IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
+       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
+                     dst_output);
        if (!err) {
                ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT);
                ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
index b1326c2bf8aae10f8318739dc3e523c2591f80d7..2e06724dc34877c7b6f085aba43e294d4ae974d1 100644 (file)
@@ -8,6 +8,7 @@
 #include <net/ip6_route.h>
 #include <net/xfrm.h>
 #include <net/ip6_checksum.h>
+#include <net/netfilter/nf_queue.h>
 
 int ip6_route_me_harder(struct sk_buff *skb)
 {
@@ -56,11 +57,12 @@ struct ip6_rt_info {
        struct in6_addr saddr;
 };
 
-static void nf_ip6_saveroute(const struct sk_buff *skb, struct nf_info *info)
+static void nf_ip6_saveroute(const struct sk_buff *skb,
+                            struct nf_queue_entry *entry)
 {
-       struct ip6_rt_info *rt_info = nf_info_reroute(info);
+       struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
 
-       if (info->hook == NF_IP6_LOCAL_OUT) {
+       if (entry->hook == NF_INET_LOCAL_OUT) {
                struct ipv6hdr *iph = ipv6_hdr(skb);
 
                rt_info->daddr = iph->daddr;
@@ -68,11 +70,12 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, struct nf_info *info)
        }
 }
 
-static int nf_ip6_reroute(struct sk_buff *skb, const struct nf_info *info)
+static int nf_ip6_reroute(struct sk_buff *skb,
+                         const struct nf_queue_entry *entry)
 {
-       struct ip6_rt_info *rt_info = nf_info_reroute(info);
+       struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
 
-       if (info->hook == NF_IP6_LOCAL_OUT) {
+       if (entry->hook == NF_INET_LOCAL_OUT) {
                struct ipv6hdr *iph = ipv6_hdr(skb);
                if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
                    !ipv6_addr_equal(&iph->saddr, &rt_info->saddr))
@@ -81,6 +84,12 @@ static int nf_ip6_reroute(struct sk_buff *skb, const struct nf_info *info)
        return 0;
 }
 
+static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl)
+{
+       *dst = ip6_route_output(NULL, fl);
+       return (*dst)->error;
+}
+
 __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
                             unsigned int dataoff, u_int8_t protocol)
 {
@@ -89,7 +98,7 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
 
        switch (skb->ip_summed) {
        case CHECKSUM_COMPLETE:
-               if (hook != NF_IP6_PRE_ROUTING && hook != NF_IP6_LOCAL_IN)
+               if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
                        break;
                if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
                                     skb->len - dataoff, protocol,
@@ -115,9 +124,10 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
 
 EXPORT_SYMBOL(nf_ip6_checksum);
 
-static struct nf_afinfo nf_ip6_afinfo = {
+static const struct nf_afinfo nf_ip6_afinfo = {
        .family         = AF_INET6,
        .checksum       = nf_ip6_checksum,
+       .route          = nf_ip6_route,
        .saveroute      = nf_ip6_saveroute,
        .reroute        = nf_ip6_reroute,
        .route_key_size = sizeof(struct ip6_rt_info),
index 838b8ddee8c03d6e40becb72ff15795cd2ab06ca..4fc0b023cfd703c5a0aa3b81bd8f8e8e8517303d 100644 (file)
@@ -2,12 +2,13 @@
 # IP netfilter configuration
 #
 
-menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
-       depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
+menu "IPv6: Netfilter Configuration"
+       depends on INET && IPV6 && NETFILTER
 
 config NF_CONNTRACK_IPV6
-       tristate "IPv6 connection tracking support (EXPERIMENTAL)"
-       depends on INET && IPV6 && EXPERIMENTAL && NF_CONNTRACK
+       tristate "IPv6 connection tracking support"
+       depends on INET && IPV6 && NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        ---help---
          Connection tracking keeps a record of what packets have passed
          through your machine, in order to figure out how they are related
@@ -21,7 +22,8 @@ config NF_CONNTRACK_IPV6
 
 config IP6_NF_QUEUE
        tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
-       depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
+       depends on INET && IPV6 && NETFILTER
+       depends on NETFILTER_ADVANCED
        ---help---
 
          This option adds a queue handler to the kernel for IPv6
@@ -42,8 +44,9 @@ config IP6_NF_QUEUE
 
 config IP6_NF_IPTABLES
        tristate "IP6 tables support (required for filtering)"
-       depends on INET && IPV6 && EXPERIMENTAL
+       depends on INET && IPV6
        select NETFILTER_XTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          ip6tables is a general, extensible packet identification framework.
          Currently only the packet filtering and packet mangling subsystem
@@ -54,8 +57,9 @@ config IP6_NF_IPTABLES
 
 # The simple matches.
 config IP6_NF_MATCH_RT
-       tristate "Routing header match support"
+       tristate '"rt" Routing header match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          rt matching allows you to match packets based on the routing
          header of the packet.
@@ -63,8 +67,9 @@ config IP6_NF_MATCH_RT
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_OPTS
-       tristate "Hop-by-hop and Dst opts header match support"
+       tristate '"hopbyhop" and "dst" opts header match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This allows one to match packets based on the hop-by-hop
          and destination options headers of a packet.
@@ -72,8 +77,9 @@ config IP6_NF_MATCH_OPTS
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_FRAG
-       tristate "Fragmentation header match support"
+       tristate '"frag" Fragmentation header match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          frag matching allows you to match packets based on the fragmentation
          header of the packet.
@@ -81,26 +87,19 @@ config IP6_NF_MATCH_FRAG
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_HL
-       tristate "HL match support"
+       tristate '"hl" match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          HL matching allows you to match packets based on the hop
          limit of the packet.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-config IP6_NF_MATCH_OWNER
-       tristate "Owner match support"
-       depends on IP6_NF_IPTABLES
-       help
-         Packet owner matching allows you to match locally-generated packets
-         based on who created them: the user, group, process or session.
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP6_NF_MATCH_IPV6HEADER
-       tristate "IPv6 Extension Headers Match"
+       tristate '"ipv6header" IPv6 Extension Headers Match'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This module allows one to match packets based upon
          the ipv6 extension headers.
@@ -108,24 +107,27 @@ config IP6_NF_MATCH_IPV6HEADER
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_AH
-       tristate "AH match support"
+       tristate '"ah" match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This module allows one to match AH packets.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_MH
-       tristate "MH match support"
+       tristate '"mh" match support'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This module allows one to match MH packets.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_MATCH_EUI64
-       tristate "EUI64 address check"
+       tristate '"eui64" address check'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This module performs checking on the IPv6 source address
          Compares the last 64 bits with the EUI64 (delivered
@@ -137,6 +139,7 @@ config IP6_NF_MATCH_EUI64
 config IP6_NF_FILTER
        tristate "Packet filtering"
        depends on IP6_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          Packet filtering defines a table `filter', which has a series of
          rules for simple packet filtering at local input, forwarding and
@@ -147,6 +150,7 @@ config IP6_NF_FILTER
 config IP6_NF_TARGET_LOG
        tristate "LOG target support"
        depends on IP6_NF_FILTER
+       default m if NETFILTER_ADVANCED=n
        help
          This option adds a `LOG' target, which allows you to create rules in
          any iptables table which records the packet header to the syslog.
@@ -156,6 +160,7 @@ config IP6_NF_TARGET_LOG
 config IP6_NF_TARGET_REJECT
        tristate "REJECT target support"
        depends on IP6_NF_FILTER
+       default m if NETFILTER_ADVANCED=n
        help
          The REJECT target allows a filtering rule to specify that an ICMPv6
          error should be issued in response to an incoming packet, rather
@@ -166,6 +171,7 @@ config IP6_NF_TARGET_REJECT
 config IP6_NF_MANGLE
        tristate "Packet mangling"
        depends on IP6_NF_IPTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          This option adds a `mangle' table to iptables: see the man page for
          iptables(8).  This table is used for various packet alterations
@@ -176,27 +182,29 @@ config IP6_NF_MANGLE
 config IP6_NF_TARGET_HL
        tristate  'HL (hoplimit) target support'
        depends on IP6_NF_MANGLE
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `HL' target, which enables the user to decrement
          the hoplimit value of the IPv6 header or set it to a given (lower)
          value.
-       
+
          While it is safe to decrement the hoplimit value, this option also
          enables functionality to increment and set the hoplimit value of the
          IPv6 header to arbitrary values.  This is EXTREMELY DANGEROUS since
          you can easily create immortal packets that loop forever on the
-         network.  
+         network.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_RAW
        tristate  'raw table support (required for TRACE)'
        depends on IP6_NF_IPTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `raw' table to ip6tables. This table is the very
          first in the netfilter framework and hooks in at the PREROUTING
          and OUTPUT chains.
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
index e789ec44d23b2e5cacdf154bf4709372d4e00d88..fbf2c14ed887942aa316b274124b698010260007 100644 (file)
@@ -23,7 +23,6 @@ obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o
 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
 obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o
 obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o
-obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
 
 # targets
index e273605eef855469794849f9cdfd800d659e87e7..56b4ea6d29ed3c9780f0081d1a922899f92ba6f7 100644 (file)
@@ -29,6 +29,7 @@
 #include <net/sock.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
+#include <net/netfilter/nf_queue.h>
 #include <linux/netfilter_ipv4/ip_queue.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #define NET_IPQ_QMAX 2088
 #define NET_IPQ_QMAX_NAME "ip6_queue_maxlen"
 
-struct ipq_queue_entry {
-       struct list_head list;
-       struct nf_info *info;
-       struct sk_buff *skb;
-};
-
-typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long);
+typedef int (*ipq_cmpfn)(struct nf_queue_entry *, unsigned long);
 
 static unsigned char copy_mode __read_mostly = IPQ_COPY_NONE;
 static unsigned int queue_maxlen __read_mostly = IPQ_QMAX_DEFAULT;
@@ -58,70 +53,13 @@ static struct sock *ipqnl __read_mostly;
 static LIST_HEAD(queue_list);
 static DEFINE_MUTEX(ipqnl_mutex);
 
-static void
-ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
-{
-       local_bh_disable();
-       nf_reinject(entry->skb, entry->info, verdict);
-       local_bh_enable();
-       kfree(entry);
-}
-
 static inline void
-__ipq_enqueue_entry(struct ipq_queue_entry *entry)
+__ipq_enqueue_entry(struct nf_queue_entry *entry)
 {
-       list_add(&entry->list, &queue_list);
+       list_add_tail(&entry->list, &queue_list);
        queue_total++;
 }
 
-/*
- * Find and return a queued entry matched by cmpfn, or return the last
- * entry if cmpfn is NULL.
- */
-static inline struct ipq_queue_entry *
-__ipq_find_entry(ipq_cmpfn cmpfn, unsigned long data)
-{
-       struct list_head *p;
-
-       list_for_each_prev(p, &queue_list) {
-               struct ipq_queue_entry *entry = (struct ipq_queue_entry *)p;
-
-               if (!cmpfn || cmpfn(entry, data))
-                       return entry;
-       }
-       return NULL;
-}
-
-static inline void
-__ipq_dequeue_entry(struct ipq_queue_entry *entry)
-{
-       list_del(&entry->list);
-       queue_total--;
-}
-
-static inline struct ipq_queue_entry *
-__ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
-{
-       struct ipq_queue_entry *entry;
-
-       entry = __ipq_find_entry(cmpfn, data);
-       if (entry == NULL)
-               return NULL;
-
-       __ipq_dequeue_entry(entry);
-       return entry;
-}
-
-
-static inline void
-__ipq_flush(int verdict)
-{
-       struct ipq_queue_entry *entry;
-
-       while ((entry = __ipq_find_dequeue_entry(NULL, 0)))
-               ipq_issue_verdict(entry, verdict);
-}
-
 static inline int
 __ipq_set_mode(unsigned char mode, unsigned int range)
 {
@@ -148,36 +86,64 @@ __ipq_set_mode(unsigned char mode, unsigned int range)
        return status;
 }
 
+static void __ipq_flush(ipq_cmpfn cmpfn, unsigned long data);
+
 static inline void
 __ipq_reset(void)
 {
        peer_pid = 0;
        net_disable_timestamp();
        __ipq_set_mode(IPQ_COPY_NONE, 0);
-       __ipq_flush(NF_DROP);
+       __ipq_flush(NULL, 0);
 }
 
-static struct ipq_queue_entry *
-ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
+static struct nf_queue_entry *
+ipq_find_dequeue_entry(unsigned long id)
 {
-       struct ipq_queue_entry *entry;
+       struct nf_queue_entry *entry = NULL, *i;
 
        write_lock_bh(&queue_lock);
-       entry = __ipq_find_dequeue_entry(cmpfn, data);
+
+       list_for_each_entry(i, &queue_list, list) {
+               if ((unsigned long)i == id) {
+                       entry = i;
+                       break;
+               }
+       }
+
+       if (entry) {
+               list_del(&entry->list);
+               queue_total--;
+       }
+
        write_unlock_bh(&queue_lock);
        return entry;
 }
 
 static void
-ipq_flush(int verdict)
+__ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
+{
+       struct nf_queue_entry *entry, *next;
+
+       list_for_each_entry_safe(entry, next, &queue_list, list) {
+               if (!cmpfn || cmpfn(entry, data)) {
+                       list_del(&entry->list);
+                       queue_total--;
+                       nf_reinject(entry, NF_DROP);
+               }
+       }
+}
+
+static void
+ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
 {
        write_lock_bh(&queue_lock);
-       __ipq_flush(verdict);
+       __ipq_flush(cmpfn, data);
        write_unlock_bh(&queue_lock);
 }
 
 static struct sk_buff *
-ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
+ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
 {
        sk_buff_data_t old_tail;
        size_t size = 0;
@@ -234,20 +200,20 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
        pmsg->timestamp_sec   = tv.tv_sec;
        pmsg->timestamp_usec  = tv.tv_usec;
        pmsg->mark            = entry->skb->mark;
-       pmsg->hook            = entry->info->hook;
+       pmsg->hook            = entry->hook;
        pmsg->hw_protocol     = entry->skb->protocol;
 
-       if (entry->info->indev)
-               strcpy(pmsg->indev_name, entry->info->indev->name);
+       if (entry->indev)
+               strcpy(pmsg->indev_name, entry->indev->name);
        else
                pmsg->indev_name[0] = '\0';
 
-       if (entry->info->outdev)
-               strcpy(pmsg->outdev_name, entry->info->outdev->name);
+       if (entry->outdev)
+               strcpy(pmsg->outdev_name, entry->outdev->name);
        else
                pmsg->outdev_name[0] = '\0';
 
-       if (entry->info->indev && entry->skb->dev) {
+       if (entry->indev && entry->skb->dev) {
                pmsg->hw_type = entry->skb->dev->type;
                pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr);
        }
@@ -268,28 +234,17 @@ nlmsg_failure:
 }
 
 static int
-ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
-                  unsigned int queuenum, void *data)
+ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
 {
        int status = -EINVAL;
        struct sk_buff *nskb;
-       struct ipq_queue_entry *entry;
 
        if (copy_mode == IPQ_COPY_NONE)
                return -EAGAIN;
 
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       if (entry == NULL) {
-               printk(KERN_ERR "ip6_queue: OOM in ipq_enqueue_packet()\n");
-               return -ENOMEM;
-       }
-
-       entry->info = info;
-       entry->skb = skb;
-
        nskb = ipq_build_packet_message(entry, &status);
        if (nskb == NULL)
-               goto err_out_free;
+               return status;
 
        write_lock_bh(&queue_lock);
 
@@ -323,14 +278,11 @@ err_out_free_nskb:
 
 err_out_unlock:
        write_unlock_bh(&queue_lock);
-
-err_out_free:
-       kfree(entry);
        return status;
 }
 
 static int
-ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
+ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
 {
        int diff;
        int err;
@@ -365,21 +317,15 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
        return 0;
 }
 
-static inline int
-id_cmp(struct ipq_queue_entry *e, unsigned long id)
-{
-       return (id == (unsigned long )e);
-}
-
 static int
 ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
 {
-       struct ipq_queue_entry *entry;
+       struct nf_queue_entry *entry;
 
        if (vmsg->value > NF_MAX_VERDICT)
                return -EINVAL;
 
-       entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
+       entry = ipq_find_dequeue_entry(vmsg->id);
        if (entry == NULL)
                return -ENOENT;
        else {
@@ -389,7 +335,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
                        if (ipq_mangle_ipv6(vmsg, entry) < 0)
                                verdict = NF_DROP;
 
-               ipq_issue_verdict(entry, verdict);
+               nf_reinject(entry, verdict);
                return 0;
        }
 }
@@ -434,26 +380,32 @@ ipq_receive_peer(struct ipq_peer_msg *pmsg,
 }
 
 static int
-dev_cmp(struct ipq_queue_entry *entry, unsigned long ifindex)
+dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
 {
-       if (entry->info->indev)
-               if (entry->info->indev->ifindex == ifindex)
+       if (entry->indev)
+               if (entry->indev->ifindex == ifindex)
                        return 1;
 
-       if (entry->info->outdev)
-               if (entry->info->outdev->ifindex == ifindex)
+       if (entry->outdev)
+               if (entry->outdev->ifindex == ifindex)
                        return 1;
-
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (entry->skb->nf_bridge) {
+               if (entry->skb->nf_bridge->physindev &&
+                   entry->skb->nf_bridge->physindev->ifindex == ifindex)
+                       return 1;
+               if (entry->skb->nf_bridge->physoutdev &&
+                   entry->skb->nf_bridge->physoutdev->ifindex == ifindex)
+                       return 1;
+       }
+#endif
        return 0;
 }
 
 static void
 ipq_dev_drop(int ifindex)
 {
-       struct ipq_queue_entry *entry;
-
-       while ((entry = ipq_find_dequeue_entry(dev_cmp, ifindex)) != NULL)
-               ipq_issue_verdict(entry, NF_DROP);
+       ipq_flush(dev_cmp, ifindex);
 }
 
 #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
@@ -577,26 +529,6 @@ static ctl_table ipq_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table ipq_dir_table[] = {
-       {
-               .ctl_name       = NET_IPV6,
-               .procname       = "ipv6",
-               .mode           = 0555,
-               .child          = ipq_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipq_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipq_dir_table
-       },
-       { .ctl_name = 0 }
-};
-
 static int ip6_queue_show(struct seq_file *m, void *v)
 {
        read_lock_bh(&queue_lock);
@@ -634,7 +566,7 @@ static const struct file_operations ip6_queue_proc_fops = {
        .owner          = THIS_MODULE,
 };
 
-static struct nf_queue_handler nfqh = {
+static const struct nf_queue_handler nfqh = {
        .name   = "ip6_queue",
        .outfn  = &ipq_enqueue_packet,
 };
@@ -662,7 +594,7 @@ static int __init ip6_queue_init(void)
        }
 
        register_netdevice_notifier(&ipq_dev_notifier);
-       ipq_sysctl_header = register_sysctl_table(ipq_root_table);
+       ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table);
 
        status = nf_register_queue_handler(PF_INET6, &nfqh);
        if (status < 0) {
@@ -677,7 +609,7 @@ cleanup_sysctl:
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
 cleanup_ipqnl:
-       sock_release(ipqnl->sk_socket);
+       netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
 
@@ -690,13 +622,13 @@ static void __exit ip6_queue_fini(void)
 {
        nf_unregister_queue_handlers(&nfqh);
        synchronize_net();
-       ipq_flush(NF_DROP);
+       ipq_flush(NULL, 0);
 
        unregister_sysctl_table(ipq_sysctl_header);
        unregister_netdevice_notifier(&ipq_dev_notifier);
        proc_net_remove(&init_net, IPQ_PROC_FS_NAME);
 
-       sock_release(ipqnl->sk_socket);
+       netlink_kernel_release(ipqnl);
        mutex_lock(&ipqnl_mutex);
        mutex_unlock(&ipqnl_mutex);
 
index acaba153793198d6fb5262bac0688dd4fa4895c9..dd7860fea61f98752bed17073cc92dd2d52808e3 100644 (file)
 #include <linux/poison.h>
 #include <linux/icmpv6.h>
 #include <net/ipv6.h>
+#include <net/compat.h>
 #include <asm/uaccess.h>
 #include <linux/mutex.h>
 #include <linux/proc_fs.h>
+#include <linux/err.h>
 #include <linux/cpumask.h>
 
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_log.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("IPv6 packet filter");
 
-#define IPV6_HDR_LEN   (sizeof(struct ipv6hdr))
-#define IPV6_OPTHDR_LEN        (sizeof(struct ipv6_opt_hdr))
-
 /*#define DEBUG_IP_FIREWALL*/
 /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
 /*#define DEBUG_IP_FIREWALL_USER*/
@@ -76,12 +76,6 @@ do {                                                         \
 
    Hence the start of any table is given by get_table() below.  */
 
-#if 0
-#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
-#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
-#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0)
-#endif
-
 /* Check for an extension */
 int
 ip6t_ext_hdr(u8 nexthdr)
@@ -96,6 +90,7 @@ ip6t_ext_hdr(u8 nexthdr)
 }
 
 /* Returns whether matches rule or not. */
+/* Performance critical - called for every packet */
 static inline bool
 ip6_packet_match(const struct sk_buff *skb,
                 const char *indev,
@@ -108,7 +103,7 @@ ip6_packet_match(const struct sk_buff *skb,
        unsigned long ret;
        const struct ipv6hdr *ipv6 = ipv6_hdr(skb);
 
-#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
+#define FWINV(bool, invflg) ((bool) ^ !!(ip6info->invflags & (invflg)))
 
        if (FWINV(ipv6_masked_addr_cmp(&ipv6->saddr, &ip6info->smsk,
                                       &ip6info->src), IP6T_INV_SRCIP)
@@ -188,7 +183,7 @@ ip6_packet_match(const struct sk_buff *skb,
 }
 
 /* should be ip6 safe */
-static inline bool
+static bool
 ip6_checkentry(const struct ip6t_ip6 *ipv6)
 {
        if (ipv6->flags & ~IP6T_F_MASK) {
@@ -218,8 +213,9 @@ ip6t_error(struct sk_buff *skb,
        return NF_DROP;
 }
 
-static inline
-bool do_match(struct ip6t_entry_match *m,
+/* Performance critical - called for every packet */
+static inline bool
+do_match(struct ip6t_entry_match *m,
              const struct sk_buff *skb,
              const struct net_device *in,
              const struct net_device *out,
@@ -242,6 +238,7 @@ get_entry(void *base, unsigned int offset)
 }
 
 /* All zeroes == unconditional rule. */
+/* Mildly perf critical (only if packet tracing is on) */
 static inline int
 unconditional(const struct ip6t_ip6 *ipv6)
 {
@@ -257,12 +254,12 @@ unconditional(const struct ip6t_ip6 *ipv6)
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
 /* This cries for unification! */
-static const char *hooknames[] = {
-       [NF_IP6_PRE_ROUTING]            = "PREROUTING",
-       [NF_IP6_LOCAL_IN]               = "INPUT",
-       [NF_IP6_FORWARD]                = "FORWARD",
-       [NF_IP6_LOCAL_OUT]              = "OUTPUT",
-       [NF_IP6_POST_ROUTING]           = "POSTROUTING",
+static const char *const hooknames[] = {
+       [NF_INET_PRE_ROUTING]           = "PREROUTING",
+       [NF_INET_LOCAL_IN]              = "INPUT",
+       [NF_INET_FORWARD]               = "FORWARD",
+       [NF_INET_LOCAL_OUT]             = "OUTPUT",
+       [NF_INET_POST_ROUTING]          = "POSTROUTING",
 };
 
 enum nf_ip_trace_comments {
@@ -271,7 +268,7 @@ enum nf_ip_trace_comments {
        NF_IP6_TRACE_COMMENT_POLICY,
 };
 
-static const char *comments[] = {
+static const char *const comments[] = {
        [NF_IP6_TRACE_COMMENT_RULE]     = "rule",
        [NF_IP6_TRACE_COMMENT_RETURN]   = "return",
        [NF_IP6_TRACE_COMMENT_POLICY]   = "policy",
@@ -287,6 +284,7 @@ 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,
@@ -378,8 +376,8 @@ ip6t_do_table(struct sk_buff *skb,
         * match it. */
 
        read_lock_bh(&table->lock);
-       private = table->private;
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+       private = table->private;
        table_base = (void *)private->entries[smp_processor_id()];
        e = get_entry(table_base, private->hook_entry[hook]);
 
@@ -399,9 +397,8 @@ ip6t_do_table(struct sk_buff *skb,
                                goto no_match;
 
                        ADD_COUNTER(e->counters,
-                                   ntohs(ipv6_hdr(skb)->payload_len)
-                                   + IPV6_HDR_LEN,
-                                   1);
+                                   ntohs(ipv6_hdr(skb)->payload_len) +
+                                   sizeof(struct ipv6hdr), 1);
 
                        t = ip6t_get_target(e);
                        IP_NF_ASSERT(t->u.kernel.target);
@@ -502,11 +499,9 @@ mark_source_chains(struct xt_table_info *newinfo,
 
        /* No recursion; use packet counter to save back ptrs (reset
           to 0 as we leave), and comefrom to save source hook bitmask */
-       for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) {
+       for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
                unsigned int pos = newinfo->hook_entry[hook];
-               struct ip6t_entry *e
-                       = (struct ip6t_entry *)(entry0 + pos);
-               int visited = e->comefrom & (1 << hook);
+               struct ip6t_entry *e = (struct ip6t_entry *)(entry0 + pos);
 
                if (!(valid_hooks & (1 << hook)))
                        continue;
@@ -517,14 +512,14 @@ mark_source_chains(struct xt_table_info *newinfo,
                for (;;) {
                        struct ip6t_standard_target *t
                                = (void *)ip6t_get_target(e);
+                       int visited = e->comefrom & (1 << hook);
 
-                       if (e->comefrom & (1 << NF_IP6_NUMHOOKS)) {
+                       if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
                                printk("iptables: loop hook %u pos %u %08X.\n",
                                       hook, pos, e->comefrom);
                                return 0;
                        }
-                       e->comefrom
-                               |= ((1 << hook) | (1 << NF_IP6_NUMHOOKS));
+                       e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
 
                        /* Unconditional return/END. */
                        if ((e->target_offset == sizeof(struct ip6t_entry)
@@ -544,10 +539,10 @@ mark_source_chains(struct xt_table_info *newinfo,
                                /* Return: backtrack through the last
                                   big jump. */
                                do {
-                                       e->comefrom ^= (1<<NF_IP6_NUMHOOKS);
+                                       e->comefrom ^= (1<<NF_INET_NUMHOOKS);
 #ifdef DEBUG_IP_FIREWALL_USER
                                        if (e->comefrom
-                                           & (1 << NF_IP6_NUMHOOKS)) {
+                                           & (1 << NF_INET_NUMHOOKS)) {
                                                duprintf("Back unset "
                                                         "on hook %u "
                                                         "rule %u\n",
@@ -604,7 +599,7 @@ mark_source_chains(struct xt_table_info *newinfo,
        return 1;
 }
 
-static inline int
+static int
 cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
 {
        if (i && (*i)-- == 0)
@@ -616,102 +611,135 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
        return 0;
 }
 
-static inline int
-check_match(struct ip6t_entry_match *m,
-           const char *name,
-           const struct ip6t_ip6 *ipv6,
-           unsigned int hookmask,
-           unsigned int *i)
+static int
+check_entry(struct ip6t_entry *e, const char *name)
+{
+       struct ip6t_entry_target *t;
+
+       if (!ip6_checkentry(&e->ipv6)) {
+               duprintf("ip_tables: ip check failed %p %s.\n", e, name);
+               return -EINVAL;
+       }
+
+       if (e->target_offset + sizeof(struct ip6t_entry_target) >
+           e->next_offset)
+               return -EINVAL;
+
+       t = ip6t_get_target(e);
+       if (e->target_offset + t->u.target_size > e->next_offset)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int check_match(struct ip6t_entry_match *m, const char *name,
+                             const struct ip6t_ip6 *ipv6,
+                             unsigned int hookmask, unsigned int *i)
+{
+       struct xt_match *match;
+       int ret;
+
+       match = m->u.kernel.match;
+       ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
+                            name, hookmask, ipv6->proto,
+                            ipv6->invflags & IP6T_INV_PROTO);
+       if (!ret && m->u.kernel.match->checkentry
+           && !m->u.kernel.match->checkentry(name, ipv6, match, m->data,
+                                             hookmask)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+                        m->u.kernel.match->name);
+               ret = -EINVAL;
+       }
+       if (!ret)
+               (*i)++;
+       return ret;
+}
+
+static int
+find_check_match(struct ip6t_entry_match *m,
+                const char *name,
+                const struct ip6t_ip6 *ipv6,
+                unsigned int hookmask,
+                unsigned int *i)
 {
        struct xt_match *match;
        int ret;
 
        match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
-                                       m->u.user.revision),
+                                                     m->u.user.revision),
                                        "ip6t_%s", m->u.user.name);
        if (IS_ERR(match) || !match) {
-               duprintf("check_match: `%s' not found\n", m->u.user.name);
+               duprintf("find_check_match: `%s' not found\n", m->u.user.name);
                return match ? PTR_ERR(match) : -ENOENT;
        }
        m->u.kernel.match = match;
 
-       ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m),
-                            name, hookmask, ipv6->proto,
-                            ipv6->invflags & IP6T_INV_PROTO);
+       ret = check_match(m, name, ipv6, hookmask, i);
        if (ret)
                goto err;
 
-       if (m->u.kernel.match->checkentry
-           && !m->u.kernel.match->checkentry(name, ipv6, match,  m->data,
-                                             hookmask)) {
-               duprintf("ip_tables: check failed for `%s'.\n",
-                        m->u.kernel.match->name);
-               ret = -EINVAL;
-               goto err;
-       }
-
-       (*i)++;
        return 0;
 err:
        module_put(m->u.kernel.match->me);
        return ret;
 }
 
-static struct xt_target ip6t_standard_target;
-
-static inline int
-check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
-           unsigned int *i)
+static int check_target(struct ip6t_entry *e, const char *name)
 {
        struct ip6t_entry_target *t;
        struct xt_target *target;
        int ret;
-       unsigned int j;
 
-       if (!ip6_checkentry(&e->ipv6)) {
-               duprintf("ip_tables: ip check failed %p %s.\n", e, name);
-               return -EINVAL;
+       t = ip6t_get_target(e);
+       target = t->u.kernel.target;
+       ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
+                             name, e->comefrom, e->ipv6.proto,
+                             e->ipv6.invflags & IP6T_INV_PROTO);
+       if (!ret && t->u.kernel.target->checkentry
+           && !t->u.kernel.target->checkentry(name, e, target, t->data,
+                                              e->comefrom)) {
+               duprintf("ip_tables: check failed for `%s'.\n",
+                        t->u.kernel.target->name);
+               ret = -EINVAL;
        }
+       return ret;
+}
 
-       if (e->target_offset + sizeof(struct ip6t_entry_target) >
-                                                               e->next_offset)
-               return -EINVAL;
+static int
+find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
+                unsigned int *i)
+{
+       struct ip6t_entry_target *t;
+       struct xt_target *target;
+       int ret;
+       unsigned int j;
+
+       ret = check_entry(e, name);
+       if (ret)
+               return ret;
 
        j = 0;
-       ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
+       ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6,
+                                e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ip6t_get_target(e);
-       ret = -EINVAL;
-       if (e->target_offset + t->u.target_size > e->next_offset)
-                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET6,
                                                        t->u.user.name,
                                                        t->u.user.revision),
                                         "ip6t_%s", t->u.user.name);
        if (IS_ERR(target) || !target) {
-               duprintf("check_entry: `%s' not found\n", t->u.user.name);
+               duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
                ret = target ? PTR_ERR(target) : -ENOENT;
                goto cleanup_matches;
        }
        t->u.kernel.target = target;
 
-       ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
-                             name, e->comefrom, e->ipv6.proto,
-                             e->ipv6.invflags & IP6T_INV_PROTO);
+       ret = check_target(e, name);
        if (ret)
                goto err;
 
-       if (t->u.kernel.target->checkentry
-                  && !t->u.kernel.target->checkentry(name, e, target, t->data,
-                                                     e->comefrom)) {
-               duprintf("ip_tables: check failed for `%s'.\n",
-                        t->u.kernel.target->name);
-               ret = -EINVAL;
-               goto err;
-       }
-
        (*i)++;
        return 0;
  err:
@@ -721,7 +749,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
        return ret;
 }
 
-static inline int
+static int
 check_entry_size_and_hooks(struct ip6t_entry *e,
                           struct xt_table_info *newinfo,
                           unsigned char *base,
@@ -746,7 +774,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
        }
 
        /* Check hooks & underflows */
-       for (h = 0; h < NF_IP6_NUMHOOKS; h++) {
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
                if ((unsigned char *)e - base == hook_entries[h])
                        newinfo->hook_entry[h] = hook_entries[h];
                if ((unsigned char *)e - base == underflows[h])
@@ -764,7 +792,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
        return 0;
 }
 
-static inline int
+static int
 cleanup_entry(struct ip6t_entry *e, unsigned int *i)
 {
        struct ip6t_entry_target *t;
@@ -800,7 +828,7 @@ translate_table(const char *name,
        newinfo->number = number;
 
        /* Init all hooks to impossible value. */
-       for (i = 0; i < NF_IP6_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                newinfo->hook_entry[i] = 0xFFFFFFFF;
                newinfo->underflow[i] = 0xFFFFFFFF;
        }
@@ -824,7 +852,7 @@ translate_table(const char *name,
        }
 
        /* Check hooks all assigned */
-       for (i = 0; i < NF_IP6_NUMHOOKS; i++) {
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
                /* Only hooks which are valid */
                if (!(valid_hooks & (1 << i)))
                        continue;
@@ -846,7 +874,7 @@ translate_table(const char *name,
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                               check_entry, name, size, &i);
+                               find_check_entry, name, size, &i);
 
        if (ret != 0) {
                IP6T_ENTRY_ITERATE(entry0, newinfo->size,
@@ -860,7 +888,7 @@ translate_table(const char *name,
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
-       return 0;
+       return ret;
 }
 
 /* Gets counters. */
@@ -920,33 +948,49 @@ get_counters(const struct xt_table_info *t,
        }
 }
 
-static int
-copy_entries_to_user(unsigned int total_size,
-                    struct xt_table *table,
-                    void __user *userptr)
+static struct xt_counters *alloc_counters(struct xt_table *table)
 {
-       unsigned int off, num, countersize;
-       struct ip6t_entry *e;
+       unsigned int countersize;
        struct xt_counters *counters;
        struct xt_table_info *private = table->private;
-       int ret = 0;
-       void *loc_cpu_entry;
 
        /* We need atomic snapshot of counters: rest doesn't change
           (other than comefrom, which userspace doesn't care
           about). */
        countersize = sizeof(struct xt_counters) * private->number;
-       counters = vmalloc(countersize);
+       counters = vmalloc_node(countersize, numa_node_id());
 
        if (counters == NULL)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
 
        /* First, sum counters... */
        write_lock_bh(&table->lock);
        get_counters(private, counters);
        write_unlock_bh(&table->lock);
 
-       /* choose the copy that is on ourc node/cpu */
+       return counters;
+}
+
+static int
+copy_entries_to_user(unsigned int total_size,
+                    struct xt_table *table,
+                    void __user *userptr)
+{
+       unsigned int off, num;
+       struct ip6t_entry *e;
+       struct xt_counters *counters;
+       struct xt_table_info *private = table->private;
+       int ret = 0;
+       void *loc_cpu_entry;
+
+       counters = alloc_counters(table);
+       if (IS_ERR(counters))
+               return PTR_ERR(counters);
+
+       /* choose the copy that is on our node/cpu, ...
+        * This choice is lazy (because current thread is
+        * allowed to migrate to another cpu)
+        */
        loc_cpu_entry = private->entries[raw_smp_processor_id()];
        if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
                ret = -EFAULT;
@@ -1001,23 +1045,167 @@ copy_entries_to_user(unsigned int total_size,
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+static void compat_standard_from_user(void *dst, void *src)
+{
+       int v = *(compat_int_t *)src;
+
+       if (v > 0)
+               v += xt_compat_calc_jump(AF_INET6, v);
+       memcpy(dst, &v, sizeof(v));
+}
+
+static int compat_standard_to_user(void __user *dst, void *src)
+{
+       compat_int_t cv = *(int *)src;
+
+       if (cv > 0)
+               cv -= xt_compat_calc_jump(AF_INET6, cv);
+       return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
+}
+
+static inline int
+compat_calc_match(struct ip6t_entry_match *m, int *size)
+{
+       *size += xt_compat_match_offset(m->u.kernel.match);
+       return 0;
+}
+
+static int compat_calc_entry(struct ip6t_entry *e,
+                            const struct xt_table_info *info,
+                            void *base, struct xt_table_info *newinfo)
+{
+       struct ip6t_entry_target *t;
+       unsigned int entry_offset;
+       int off, i, ret;
+
+       off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
+       entry_offset = (void *)e - base;
+       IP6T_MATCH_ITERATE(e, compat_calc_match, &off);
+       t = ip6t_get_target(e);
+       off += xt_compat_target_offset(t->u.kernel.target);
+       newinfo->size -= off;
+       ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               if (info->hook_entry[i] &&
+                   (e < (struct ip6t_entry *)(base + info->hook_entry[i])))
+                       newinfo->hook_entry[i] -= off;
+               if (info->underflow[i] &&
+                   (e < (struct ip6t_entry *)(base + info->underflow[i])))
+                       newinfo->underflow[i] -= off;
+       }
+       return 0;
+}
+
+static int compat_table_info(const struct xt_table_info *info,
+                            struct xt_table_info *newinfo)
+{
+       void *loc_cpu_entry;
+
+       if (!newinfo || !info)
+               return -EINVAL;
+
+       /* we dont care about newinfo->entries[] */
+       memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
+       newinfo->initial_entries = 0;
+       loc_cpu_entry = info->entries[raw_smp_processor_id()];
+       return IP6T_ENTRY_ITERATE(loc_cpu_entry, info->size,
+                                 compat_calc_entry, info, loc_cpu_entry,
+                                 newinfo);
+}
+#endif
+
+static int get_info(void __user *user, int *len, int compat)
+{
+       char name[IP6T_TABLE_MAXNAMELEN];
+       struct xt_table *t;
+       int ret;
+
+       if (*len != sizeof(struct ip6t_getinfo)) {
+               duprintf("length %u != %zu\n", *len,
+                        sizeof(struct ip6t_getinfo));
+               return -EINVAL;
+       }
+
+       if (copy_from_user(name, user, sizeof(name)) != 0)
+               return -EFAULT;
+
+       name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
+#ifdef CONFIG_COMPAT
+       if (compat)
+               xt_compat_lock(AF_INET6);
+#endif
+       t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+                                   "ip6table_%s", name);
+       if (t && !IS_ERR(t)) {
+               struct ip6t_getinfo info;
+               struct xt_table_info *private = t->private;
+
+#ifdef CONFIG_COMPAT
+               if (compat) {
+                       struct xt_table_info tmp;
+                       ret = compat_table_info(private, &tmp);
+                       xt_compat_flush_offsets(AF_INET6);
+                       private = &tmp;
+               }
+#endif
+               info.valid_hooks = t->valid_hooks;
+               memcpy(info.hook_entry, private->hook_entry,
+                      sizeof(info.hook_entry));
+               memcpy(info.underflow, private->underflow,
+                      sizeof(info.underflow));
+               info.num_entries = private->number;
+               info.size = private->size;
+               strcpy(info.name, name);
+
+               if (copy_to_user(user, &info, *len) != 0)
+                       ret = -EFAULT;
+               else
+                       ret = 0;
+
+               xt_table_unlock(t);
+               module_put(t->me);
+       } else
+               ret = t ? PTR_ERR(t) : -ENOENT;
+#ifdef CONFIG_COMPAT
+       if (compat)
+               xt_compat_unlock(AF_INET6);
+#endif
+       return ret;
+}
+
 static int
-get_entries(const struct ip6t_get_entries *entries,
-           struct ip6t_get_entries __user *uptr)
+get_entries(struct ip6t_get_entries __user *uptr, int *len)
 {
        int ret;
+       struct ip6t_get_entries get;
        struct xt_table *t;
 
-       t = xt_find_table_lock(AF_INET6, entries->name);
+       if (*len < sizeof(get)) {
+               duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
+               return -EINVAL;
+       }
+       if (copy_from_user(&get, uptr, sizeof(get)) != 0)
+               return -EFAULT;
+       if (*len != sizeof(struct ip6t_get_entries) + get.size) {
+               duprintf("get_entries: %u != %zu\n",
+                        *len, sizeof(get) + get.size);
+               return -EINVAL;
+       }
+
+       t = xt_find_table_lock(AF_INET6, get.name);
        if (t && !IS_ERR(t)) {
                struct xt_table_info *private = t->private;
                duprintf("t->private->number = %u\n", private->number);
-               if (entries->size == private->size)
+               if (get.size == private->size)
                        ret = copy_entries_to_user(private->size,
                                                   t, uptr->entrytable);
                else {
                        duprintf("get_entries: I've got %u not %u!\n",
-                                private->size, entries->size);
+                                private->size, get.size);
                        ret = -EINVAL;
                }
                module_put(t->me);
@@ -1029,67 +1217,40 @@ get_entries(const struct ip6t_get_entries *entries,
 }
 
 static int
-do_replace(void __user *user, unsigned int len)
+__do_replace(const char *name, unsigned int valid_hooks,
+            struct xt_table_info *newinfo, unsigned int num_counters,
+            void __user *counters_ptr)
 {
        int ret;
-       struct ip6t_replace tmp;
        struct xt_table *t;
-       struct xt_table_info *newinfo, *oldinfo;
+       struct xt_table_info *oldinfo;
        struct xt_counters *counters;
-       void *loc_cpu_entry, *loc_cpu_old_entry;
-
-       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
-               return -EFAULT;
-
-       /* overflow check */
-       if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
-                       SMP_CACHE_BYTES)
-               return -ENOMEM;
-       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
-               return -ENOMEM;
-
-       newinfo = xt_alloc_table_info(tmp.size);
-       if (!newinfo)
-               return -ENOMEM;
-
-       /* choose the copy that is on our node/cpu */
-       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
-       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
-                          tmp.size) != 0) {
-               ret = -EFAULT;
-               goto free_newinfo;
-       }
+       void *loc_cpu_old_entry;
 
-       counters = vmalloc(tmp.num_counters * sizeof(struct xt_counters));
+       ret = 0;
+       counters = vmalloc_node(num_counters * sizeof(struct xt_counters),
+                               numa_node_id());
        if (!counters) {
                ret = -ENOMEM;
-               goto free_newinfo;
+               goto out;
        }
 
-       ret = translate_table(tmp.name, tmp.valid_hooks,
-                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
-                             tmp.hook_entry, tmp.underflow);
-       if (ret != 0)
-               goto free_newinfo_counters;
-
-       duprintf("ip_tables: Translated table\n");
-
-       t = try_then_request_module(xt_find_table_lock(AF_INET6, tmp.name),
-                                   "ip6table_%s", tmp.name);
+       t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
+                                   "ip6table_%s", name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free_newinfo_counters_untrans;
        }
 
        /* You lied! */
-       if (tmp.valid_hooks != t->valid_hooks) {
+       if (valid_hooks != t->valid_hooks) {
                duprintf("Valid hook crap: %08X vs %08X\n",
-                        tmp.valid_hooks, t->valid_hooks);
+                        valid_hooks, t->valid_hooks);
                ret = -EINVAL;
                goto put_module;
        }
 
-       oldinfo = xt_replace_table(t, tmp.num_counters, newinfo, &ret);
+       oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
        if (!oldinfo)
                goto put_module;
 
@@ -1107,10 +1268,11 @@ do_replace(void __user *user, unsigned int len)
        get_counters(oldinfo, counters);
        /* Decrease module usage counts and free resource */
        loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
-       IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+       IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,
+                          NULL);
        xt_free_table_info(oldinfo);
-       if (copy_to_user(tmp.counters, counters,
-                        sizeof(struct xt_counters) * tmp.num_counters) != 0)
+       if (copy_to_user(counters_ptr, counters,
+                        sizeof(struct xt_counters) * num_counters) != 0)
                ret = -EFAULT;
        vfree(counters);
        xt_table_unlock(t);
@@ -1120,62 +1282,135 @@ do_replace(void __user *user, unsigned int len)
        module_put(t->me);
        xt_table_unlock(t);
  free_newinfo_counters_untrans:
-       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
- free_newinfo_counters:
        vfree(counters);
- free_newinfo:
-       xt_free_table_info(newinfo);
+ out:
        return ret;
 }
 
-/* We're lazy, and add to the first CPU; overflow works its fey magic
- * and everything is OK. */
-static inline int
-add_counter_to_entry(struct ip6t_entry *e,
-                    const struct xt_counters addme[],
-                    unsigned int *i)
-{
-#if 0
-       duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n",
-                *i,
-                (long unsigned int)e->counters.pcnt,
-                (long unsigned int)e->counters.bcnt,
-                (long unsigned int)addme[*i].pcnt,
-                (long unsigned int)addme[*i].bcnt);
-#endif
-
-       ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
-
-       (*i)++;
-       return 0;
-}
-
 static int
-do_add_counters(void __user *user, unsigned int len)
+do_replace(void __user *user, unsigned int len)
 {
-       unsigned int i;
-       struct xt_counters_info tmp, *paddc;
-       struct xt_table_info *private;
-       struct xt_table *t;
-       int ret = 0;
+       int ret;
+       struct ip6t_replace tmp;
+       struct xt_table_info *newinfo;
        void *loc_cpu_entry;
 
        if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
                return -EFAULT;
 
-       if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct xt_counters))
-               return -EINVAL;
-
-       paddc = vmalloc(len);
-       if (!paddc)
+       /* overflow check */
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
                return -ENOMEM;
 
-       if (copy_from_user(paddc, user, len) != 0) {
-               ret = -EFAULT;
+       newinfo = xt_alloc_table_info(tmp.size);
+       if (!newinfo)
+               return -ENOMEM;
+
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
+                          tmp.size) != 0) {
+               ret = -EFAULT;
+               goto free_newinfo;
+       }
+
+       ret = translate_table(tmp.name, tmp.valid_hooks,
+                             newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
+                             tmp.hook_entry, tmp.underflow);
+       if (ret != 0)
+               goto free_newinfo;
+
+       duprintf("ip_tables: Translated table\n");
+
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, tmp.counters);
+       if (ret)
+               goto free_newinfo_untrans;
+       return 0;
+
+ free_newinfo_untrans:
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
+ free_newinfo:
+       xt_free_table_info(newinfo);
+       return ret;
+}
+
+/* We're lazy, and add to the first CPU; overflow works its fey magic
+ * and everything is OK. */
+static inline int
+add_counter_to_entry(struct ip6t_entry *e,
+                    const struct xt_counters addme[],
+                    unsigned int *i)
+{
+#if 0
+       duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n",
+                *i,
+                (long unsigned int)e->counters.pcnt,
+                (long unsigned int)e->counters.bcnt,
+                (long unsigned int)addme[*i].pcnt,
+                (long unsigned int)addme[*i].bcnt);
+#endif
+
+       ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt);
+
+       (*i)++;
+       return 0;
+}
+
+static int
+do_add_counters(void __user *user, unsigned int len, int compat)
+{
+       unsigned int i;
+       struct xt_counters_info tmp;
+       struct xt_counters *paddc;
+       unsigned int num_counters;
+       char *name;
+       int size;
+       void *ptmp;
+       struct xt_table *t;
+       struct xt_table_info *private;
+       int ret = 0;
+       void *loc_cpu_entry;
+#ifdef CONFIG_COMPAT
+       struct compat_xt_counters_info compat_tmp;
+
+       if (compat) {
+               ptmp = &compat_tmp;
+               size = sizeof(struct compat_xt_counters_info);
+       } else
+#endif
+       {
+               ptmp = &tmp;
+               size = sizeof(struct xt_counters_info);
+       }
+
+       if (copy_from_user(ptmp, user, size) != 0)
+               return -EFAULT;
+
+#ifdef CONFIG_COMPAT
+       if (compat) {
+               num_counters = compat_tmp.num_counters;
+               name = compat_tmp.name;
+       } else
+#endif
+       {
+               num_counters = tmp.num_counters;
+               name = tmp.name;
+       }
+
+       if (len != size + num_counters * sizeof(struct xt_counters))
+               return -EINVAL;
+
+       paddc = vmalloc_node(len - size, numa_node_id());
+       if (!paddc)
+               return -ENOMEM;
+
+       if (copy_from_user(paddc, user + size, len - size) != 0) {
+               ret = -EFAULT;
                goto free;
        }
 
-       t = xt_find_table_lock(AF_INET6, tmp.name);
+       t = xt_find_table_lock(AF_INET6, name);
        if (!t || IS_ERR(t)) {
                ret = t ? PTR_ERR(t) : -ENOENT;
                goto free;
@@ -1183,18 +1418,18 @@ do_add_counters(void __user *user, unsigned int len)
 
        write_lock_bh(&t->lock);
        private = t->private;
-       if (private->number != tmp.num_counters) {
+       if (private->number != num_counters) {
                ret = -EINVAL;
                goto unlock_up_free;
        }
 
        i = 0;
        /* Choose the copy that is on our node */
-       loc_cpu_entry = private->entries[smp_processor_id()];
+       loc_cpu_entry = private->entries[raw_smp_processor_id()];
        IP6T_ENTRY_ITERATE(loc_cpu_entry,
                          private->size,
                          add_counter_to_entry,
-                         paddc->counters,
+                         paddc,
                          &i);
  unlock_up_free:
        write_unlock_bh(&t->lock);
@@ -1206,8 +1441,433 @@ do_add_counters(void __user *user, unsigned int len)
        return ret;
 }
 
+#ifdef CONFIG_COMPAT
+struct compat_ip6t_replace {
+       char                    name[IP6T_TABLE_MAXNAMELEN];
+       u32                     valid_hooks;
+       u32                     num_entries;
+       u32                     size;
+       u32                     hook_entry[NF_INET_NUMHOOKS];
+       u32                     underflow[NF_INET_NUMHOOKS];
+       u32                     num_counters;
+       compat_uptr_t           counters;       /* struct ip6t_counters * */
+       struct compat_ip6t_entry entries[0];
+};
+
 static int
-do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
+compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+                         compat_uint_t *size, struct xt_counters *counters,
+                         unsigned int *i)
+{
+       struct ip6t_entry_target *t;
+       struct compat_ip6t_entry __user *ce;
+       u_int16_t target_offset, next_offset;
+       compat_uint_t origsize;
+       int ret;
+
+       ret = -EFAULT;
+       origsize = *size;
+       ce = (struct compat_ip6t_entry __user *)*dstptr;
+       if (copy_to_user(ce, e, sizeof(struct ip6t_entry)))
+               goto out;
+
+       if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i])))
+               goto out;
+
+       *dstptr += sizeof(struct compat_ip6t_entry);
+       *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
+
+       ret = IP6T_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size);
+       target_offset = e->target_offset - (origsize - *size);
+       if (ret)
+               goto out;
+       t = ip6t_get_target(e);
+       ret = xt_compat_target_to_user(t, dstptr, size);
+       if (ret)
+               goto out;
+       ret = -EFAULT;
+       next_offset = e->next_offset - (origsize - *size);
+       if (put_user(target_offset, &ce->target_offset))
+               goto out;
+       if (put_user(next_offset, &ce->next_offset))
+               goto out;
+
+       (*i)++;
+       return 0;
+out:
+       return ret;
+}
+
+static int
+compat_find_calc_match(struct ip6t_entry_match *m,
+                      const char *name,
+                      const struct ip6t_ip6 *ipv6,
+                      unsigned int hookmask,
+                      int *size, int *i)
+{
+       struct xt_match *match;
+
+       match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
+                                                     m->u.user.revision),
+                                       "ip6t_%s", m->u.user.name);
+       if (IS_ERR(match) || !match) {
+               duprintf("compat_check_calc_match: `%s' not found\n",
+                        m->u.user.name);
+               return match ? PTR_ERR(match) : -ENOENT;
+       }
+       m->u.kernel.match = match;
+       *size += xt_compat_match_offset(match);
+
+       (*i)++;
+       return 0;
+}
+
+static int
+compat_release_match(struct ip6t_entry_match *m, unsigned int *i)
+{
+       if (i && (*i)-- == 0)
+               return 1;
+
+       module_put(m->u.kernel.match->me);
+       return 0;
+}
+
+static int
+compat_release_entry(struct compat_ip6t_entry *e, unsigned int *i)
+{
+       struct ip6t_entry_target *t;
+
+       if (i && (*i)-- == 0)
+               return 1;
+
+       /* Cleanup all matches */
+       COMPAT_IP6T_MATCH_ITERATE(e, compat_release_match, NULL);
+       t = compat_ip6t_get_target(e);
+       module_put(t->u.kernel.target->me);
+       return 0;
+}
+
+static int
+check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
+                                 struct xt_table_info *newinfo,
+                                 unsigned int *size,
+                                 unsigned char *base,
+                                 unsigned char *limit,
+                                 unsigned int *hook_entries,
+                                 unsigned int *underflows,
+                                 unsigned int *i,
+                                 const char *name)
+{
+       struct ip6t_entry_target *t;
+       struct xt_target *target;
+       unsigned int entry_offset;
+       int ret, off, h, j;
+
+       duprintf("check_compat_entry_size_and_hooks %p\n", e);
+       if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0
+           || (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) {
+               duprintf("Bad offset %p, limit = %p\n", e, limit);
+               return -EINVAL;
+       }
+
+       if (e->next_offset < sizeof(struct compat_ip6t_entry) +
+                            sizeof(struct compat_xt_entry_target)) {
+               duprintf("checking: element %p size %u\n",
+                        e, e->next_offset);
+               return -EINVAL;
+       }
+
+       /* For purposes of check_entry casting the compat entry is fine */
+       ret = check_entry((struct ip6t_entry *)e, name);
+       if (ret)
+               return ret;
+
+       off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
+       entry_offset = (void *)e - (void *)base;
+       j = 0;
+       ret = COMPAT_IP6T_MATCH_ITERATE(e, compat_find_calc_match, name,
+                                       &e->ipv6, e->comefrom, &off, &j);
+       if (ret != 0)
+               goto release_matches;
+
+       t = compat_ip6t_get_target(e);
+       target = try_then_request_module(xt_find_target(AF_INET6,
+                                                       t->u.user.name,
+                                                       t->u.user.revision),
+                                        "ip6t_%s", t->u.user.name);
+       if (IS_ERR(target) || !target) {
+               duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
+                        t->u.user.name);
+               ret = target ? PTR_ERR(target) : -ENOENT;
+               goto release_matches;
+       }
+       t->u.kernel.target = target;
+
+       off += xt_compat_target_offset(target);
+       *size += off;
+       ret = xt_compat_add_offset(AF_INET6, entry_offset, off);
+       if (ret)
+               goto out;
+
+       /* Check hooks & underflows */
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+               if ((unsigned char *)e - base == hook_entries[h])
+                       newinfo->hook_entry[h] = hook_entries[h];
+               if ((unsigned char *)e - base == underflows[h])
+                       newinfo->underflow[h] = underflows[h];
+       }
+
+       /* Clear counters and comefrom */
+       memset(&e->counters, 0, sizeof(e->counters));
+       e->comefrom = 0;
+
+       (*i)++;
+       return 0;
+
+out:
+       module_put(t->u.kernel.target->me);
+release_matches:
+       IP6T_MATCH_ITERATE(e, compat_release_match, &j);
+       return ret;
+}
+
+static int
+compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
+                           unsigned int *size, const char *name,
+                           struct xt_table_info *newinfo, unsigned char *base)
+{
+       struct ip6t_entry_target *t;
+       struct xt_target *target;
+       struct ip6t_entry *de;
+       unsigned int origsize;
+       int ret, h;
+
+       ret = 0;
+       origsize = *size;
+       de = (struct ip6t_entry *)*dstptr;
+       memcpy(de, e, sizeof(struct ip6t_entry));
+       memcpy(&de->counters, &e->counters, sizeof(e->counters));
+
+       *dstptr += sizeof(struct ip6t_entry);
+       *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
+
+       ret = COMPAT_IP6T_MATCH_ITERATE(e, xt_compat_match_from_user,
+                                       dstptr, size);
+       if (ret)
+               return ret;
+       de->target_offset = e->target_offset - (origsize - *size);
+       t = compat_ip6t_get_target(e);
+       target = t->u.kernel.target;
+       xt_compat_target_from_user(t, dstptr, size);
+
+       de->next_offset = e->next_offset - (origsize - *size);
+       for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+               if ((unsigned char *)de - base < newinfo->hook_entry[h])
+                       newinfo->hook_entry[h] -= origsize - *size;
+               if ((unsigned char *)de - base < newinfo->underflow[h])
+                       newinfo->underflow[h] -= origsize - *size;
+       }
+       return ret;
+}
+
+static int compat_check_entry(struct ip6t_entry *e, const char *name,
+                                    unsigned int *i)
+{
+       int j, ret;
+
+       j = 0;
+       ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6,
+                                e->comefrom, &j);
+       if (ret)
+               goto cleanup_matches;
+
+       ret = check_target(e, name);
+       if (ret)
+               goto cleanup_matches;
+
+       (*i)++;
+       return 0;
+
+ cleanup_matches:
+       IP6T_MATCH_ITERATE(e, cleanup_match, &j);
+       return ret;
+}
+
+static int
+translate_compat_table(const char *name,
+                      unsigned int valid_hooks,
+                      struct xt_table_info **pinfo,
+                      void **pentry0,
+                      unsigned int total_size,
+                      unsigned int number,
+                      unsigned int *hook_entries,
+                      unsigned int *underflows)
+{
+       unsigned int i, j;
+       struct xt_table_info *newinfo, *info;
+       void *pos, *entry0, *entry1;
+       unsigned int size;
+       int ret;
+
+       info = *pinfo;
+       entry0 = *pentry0;
+       size = total_size;
+       info->number = number;
+
+       /* Init all hooks to impossible value. */
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               info->hook_entry[i] = 0xFFFFFFFF;
+               info->underflow[i] = 0xFFFFFFFF;
+       }
+
+       duprintf("translate_compat_table: size %u\n", info->size);
+       j = 0;
+       xt_compat_lock(AF_INET6);
+       /* Walk through entries, checking offsets. */
+       ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size,
+                                       check_compat_entry_size_and_hooks,
+                                       info, &size, entry0,
+                                       entry0 + total_size,
+                                       hook_entries, underflows, &j, name);
+       if (ret != 0)
+               goto out_unlock;
+
+       ret = -EINVAL;
+       if (j != number) {
+               duprintf("translate_compat_table: %u not %u entries\n",
+                        j, number);
+               goto out_unlock;
+       }
+
+       /* Check hooks all assigned */
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               /* Only hooks which are valid */
+               if (!(valid_hooks & (1 << i)))
+                       continue;
+               if (info->hook_entry[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid hook entry %u %u\n",
+                                i, hook_entries[i]);
+                       goto out_unlock;
+               }
+               if (info->underflow[i] == 0xFFFFFFFF) {
+                       duprintf("Invalid underflow %u %u\n",
+                                i, underflows[i]);
+                       goto out_unlock;
+               }
+       }
+
+       ret = -ENOMEM;
+       newinfo = xt_alloc_table_info(size);
+       if (!newinfo)
+               goto out_unlock;
+
+       newinfo->number = number;
+       for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+               newinfo->hook_entry[i] = info->hook_entry[i];
+               newinfo->underflow[i] = info->underflow[i];
+       }
+       entry1 = newinfo->entries[raw_smp_processor_id()];
+       pos = entry1;
+       size = total_size;
+       ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size,
+                                       compat_copy_entry_from_user,
+                                       &pos, &size, name, newinfo, entry1);
+       xt_compat_flush_offsets(AF_INET6);
+       xt_compat_unlock(AF_INET6);
+       if (ret)
+               goto free_newinfo;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry1))
+               goto free_newinfo;
+
+       i = 0;
+       ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
+                                name, &i);
+       if (ret) {
+               j -= i;
+               COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i,
+                                                  compat_release_entry, &j);
+               IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i);
+               xt_free_table_info(newinfo);
+               return ret;
+       }
+
+       /* And one copy for every other CPU */
+       for_each_possible_cpu(i)
+               if (newinfo->entries[i] && newinfo->entries[i] != entry1)
+                       memcpy(newinfo->entries[i], entry1, newinfo->size);
+
+       *pinfo = newinfo;
+       *pentry0 = entry1;
+       xt_free_table_info(info);
+       return 0;
+
+free_newinfo:
+       xt_free_table_info(newinfo);
+out:
+       COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
+       return ret;
+out_unlock:
+       xt_compat_flush_offsets(AF_INET6);
+       xt_compat_unlock(AF_INET6);
+       goto out;
+}
+
+static int
+compat_do_replace(void __user *user, unsigned int len)
+{
+       int ret;
+       struct compat_ip6t_replace tmp;
+       struct xt_table_info *newinfo;
+       void *loc_cpu_entry;
+
+       if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
+               return -EFAULT;
+
+       /* overflow check */
+       if (tmp.size >= INT_MAX / num_possible_cpus())
+               return -ENOMEM;
+       if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
+               return -ENOMEM;
+
+       newinfo = xt_alloc_table_info(tmp.size);
+       if (!newinfo)
+               return -ENOMEM;
+
+       /* choose the copy that is on our node/cpu */
+       loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+       if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
+                          tmp.size) != 0) {
+               ret = -EFAULT;
+               goto free_newinfo;
+       }
+
+       ret = translate_compat_table(tmp.name, tmp.valid_hooks,
+                                    &newinfo, &loc_cpu_entry, tmp.size,
+                                    tmp.num_entries, tmp.hook_entry,
+                                    tmp.underflow);
+       if (ret != 0)
+               goto free_newinfo;
+
+       duprintf("compat_do_replace: Translated table\n");
+
+       ret = __do_replace(tmp.name, tmp.valid_hooks, newinfo,
+                          tmp.num_counters, compat_ptr(tmp.counters));
+       if (ret)
+               goto free_newinfo_untrans;
+       return 0;
+
+ free_newinfo_untrans:
+       IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
+ free_newinfo:
+       xt_free_table_info(newinfo);
+       return ret;
+}
+
+static int
+compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user,
+                      unsigned int len)
 {
        int ret;
 
@@ -1216,11 +1876,11 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
 
        switch (cmd) {
        case IP6T_SO_SET_REPLACE:
-               ret = do_replace(user, len);
+               ret = compat_do_replace(user, len);
                break;
 
        case IP6T_SO_SET_ADD_COUNTERS:
-               ret = do_add_counters(user, len);
+               ret = do_add_counters(user, len, 1);
                break;
 
        default:
@@ -1231,75 +1891,155 @@ do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
        return ret;
 }
 
+struct compat_ip6t_get_entries {
+       char name[IP6T_TABLE_MAXNAMELEN];
+       compat_uint_t size;
+       struct compat_ip6t_entry entrytable[0];
+};
+
 static int
-do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
+                           void __user *userptr)
+{
+       struct xt_counters *counters;
+       struct xt_table_info *private = table->private;
+       void __user *pos;
+       unsigned int size;
+       int ret = 0;
+       void *loc_cpu_entry;
+       unsigned int i = 0;
+
+       counters = alloc_counters(table);
+       if (IS_ERR(counters))
+               return PTR_ERR(counters);
+
+       /* choose the copy that is on our node/cpu, ...
+        * This choice is lazy (because current thread is
+        * allowed to migrate to another cpu)
+        */
+       loc_cpu_entry = private->entries[raw_smp_processor_id()];
+       pos = userptr;
+       size = total_size;
+       ret = IP6T_ENTRY_ITERATE(loc_cpu_entry, total_size,
+                                compat_copy_entry_to_user,
+                                &pos, &size, counters, &i);
+
+       vfree(counters);
+       return ret;
+}
+
+static int
+compat_get_entries(struct compat_ip6t_get_entries __user *uptr, int *len)
 {
        int ret;
+       struct compat_ip6t_get_entries get;
+       struct xt_table *t;
 
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
+       if (*len < sizeof(get)) {
+               duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
+               return -EINVAL;
+       }
 
-       switch (cmd) {
-       case IP6T_SO_GET_INFO: {
-               char name[IP6T_TABLE_MAXNAMELEN];
-               struct xt_table *t;
+       if (copy_from_user(&get, uptr, sizeof(get)) != 0)
+               return -EFAULT;
 
-               if (*len != sizeof(struct ip6t_getinfo)) {
-                       duprintf("length %u != %u\n", *len,
-                                sizeof(struct ip6t_getinfo));
+       if (*len != sizeof(struct compat_ip6t_get_entries) + get.size) {
+               duprintf("compat_get_entries: %u != %zu\n",
+                        *len, sizeof(get) + get.size);
+               return -EINVAL;
+       }
+
+       xt_compat_lock(AF_INET6);
+       t = xt_find_table_lock(AF_INET6, get.name);
+       if (t && !IS_ERR(t)) {
+               struct xt_table_info *private = t->private;
+               struct xt_table_info info;
+               duprintf("t->private->number = %u\n", private->number);
+               ret = compat_table_info(private, &info);
+               if (!ret && get.size == info.size) {
+                       ret = compat_copy_entries_to_user(private->size,
+                                                         t, uptr->entrytable);
+               } else if (!ret) {
+                       duprintf("compat_get_entries: I've got %u not %u!\n",
+                                private->size, get.size);
                        ret = -EINVAL;
-                       break;
                }
+               xt_compat_flush_offsets(AF_INET6);
+               module_put(t->me);
+               xt_table_unlock(t);
+       } else
+               ret = t ? PTR_ERR(t) : -ENOENT;
 
-               if (copy_from_user(name, user, sizeof(name)) != 0) {
-                       ret = -EFAULT;
-                       break;
-               }
-               name[IP6T_TABLE_MAXNAMELEN-1] = '\0';
-
-               t = try_then_request_module(xt_find_table_lock(AF_INET6, name),
-                                           "ip6table_%s", name);
-               if (t && !IS_ERR(t)) {
-                       struct ip6t_getinfo info;
-                       struct xt_table_info *private = t->private;
-
-                       info.valid_hooks = t->valid_hooks;
-                       memcpy(info.hook_entry, private->hook_entry,
-                              sizeof(info.hook_entry));
-                       memcpy(info.underflow, private->underflow,
-                              sizeof(info.underflow));
-                       info.num_entries = private->number;
-                       info.size = private->size;
-                       memcpy(info.name, name, sizeof(info.name));
-
-                       if (copy_to_user(user, &info, *len) != 0)
-                               ret = -EFAULT;
-                       else
-                               ret = 0;
-                       xt_table_unlock(t);
-                       module_put(t->me);
-               } else
-                       ret = t ? PTR_ERR(t) : -ENOENT;
+       xt_compat_unlock(AF_INET6);
+       return ret;
+}
+
+static int do_ip6t_get_ctl(struct sock *, int, void __user *, int *);
+
+static int
+compat_do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+{
+       int ret;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case IP6T_SO_GET_INFO:
+               ret = get_info(user, len, 1);
+               break;
+       case IP6T_SO_GET_ENTRIES:
+               ret = compat_get_entries(user, len);
+               break;
+       default:
+               ret = do_ip6t_get_ctl(sk, cmd, user, len);
        }
-       break;
+       return ret;
+}
+#endif
 
-       case IP6T_SO_GET_ENTRIES: {
-               struct ip6t_get_entries get;
+static int
+do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
+{
+       int ret;
 
-               if (*len < sizeof(get)) {
-                       duprintf("get_entries: %u < %u\n", *len, sizeof(get));
-                       ret = -EINVAL;
-               } else if (copy_from_user(&get, user, sizeof(get)) != 0) {
-                       ret = -EFAULT;
-               } else if (*len != sizeof(struct ip6t_get_entries) + get.size) {
-                       duprintf("get_entries: %u != %u\n", *len,
-                                sizeof(struct ip6t_get_entries) + get.size);
-                       ret = -EINVAL;
-               } else
-                       ret = get_entries(&get, user);
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case IP6T_SO_SET_REPLACE:
+               ret = do_replace(user, len);
+               break;
+
+       case IP6T_SO_SET_ADD_COUNTERS:
+               ret = do_add_counters(user, len, 0);
                break;
+
+       default:
+               duprintf("do_ip6t_set_ctl:  unknown request %i\n", cmd);
+               ret = -EINVAL;
        }
 
+       return ret;
+}
+
+static int
+do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
+{
+       int ret;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       switch (cmd) {
+       case IP6T_SO_GET_INFO:
+               ret = get_info(user, len, 0);
+               break;
+
+       case IP6T_SO_GET_ENTRIES:
+               ret = get_entries(user, len);
+               break;
+
        case IP6T_SO_GET_REVISION_MATCH:
        case IP6T_SO_GET_REVISION_TARGET: {
                struct ip6t_get_revision rev;
@@ -1334,12 +2074,11 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
        return ret;
 }
 
-int ip6t_register_table(struct xt_table *table,
-                       const struct ip6t_replace *repl)
+int ip6t_register_table(struct xt_table *table, const struct ip6t_replace *repl)
 {
        int ret;
        struct xt_table_info *newinfo;
-       static struct xt_table_info bootstrap
+       struct xt_table_info bootstrap
                = { 0, 0, 0, { 0 }, { 0 }, { } };
        void *loc_cpu_entry;
 
@@ -1347,7 +2086,7 @@ int ip6t_register_table(struct xt_table *table,
        if (!newinfo)
                return -ENOMEM;
 
-       /* choose the copy on our node/cpu */
+       /* choose the copy on our node/cpu, but dont care about preemption */
        loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
        memcpy(loc_cpu_entry, repl->entries, repl->size);
 
@@ -1403,17 +2142,18 @@ icmp6_match(const struct sk_buff *skb,
           unsigned int protoff,
           bool *hotdrop)
 {
-       struct icmp6hdr _icmp, *ic;
+       struct icmp6hdr _icmph, *ic;
        const struct ip6t_icmp *icmpinfo = matchinfo;
 
        /* Must not be a fragment. */
        if (offset)
                return false;
 
-       ic = skb_header_pointer(skb, protoff, sizeof(_icmp), &_icmp);
+       ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph);
        if (ic == NULL) {
                /* We've been asked to examine this packet, and we
-                  can't.  Hence, no choice but to drop. */
+                * can't.  Hence, no choice but to drop.
+                */
                duprintf("Dropping evil ICMP tinygram.\n");
                *hotdrop = true;
                return false;
@@ -1445,6 +2185,11 @@ static struct xt_target ip6t_standard_target __read_mostly = {
        .name           = IP6T_STANDARD_TARGET,
        .targetsize     = sizeof(int),
        .family         = AF_INET6,
+#ifdef CONFIG_COMPAT
+       .compatsize     = sizeof(compat_int_t),
+       .compat_from_user = compat_standard_from_user,
+       .compat_to_user = compat_standard_to_user,
+#endif
 };
 
 static struct xt_target ip6t_error_target __read_mostly = {
@@ -1459,15 +2204,21 @@ static struct nf_sockopt_ops ip6t_sockopts = {
        .set_optmin     = IP6T_BASE_CTL,
        .set_optmax     = IP6T_SO_SET_MAX+1,
        .set            = do_ip6t_set_ctl,
+#ifdef CONFIG_COMPAT
+       .compat_set     = compat_do_ip6t_set_ctl,
+#endif
        .get_optmin     = IP6T_BASE_CTL,
        .get_optmax     = IP6T_SO_GET_MAX+1,
        .get            = do_ip6t_get_ctl,
+#ifdef CONFIG_COMPAT
+       .compat_get     = compat_do_ip6t_get_ctl,
+#endif
        .owner          = THIS_MODULE,
 };
 
 static struct xt_match icmp6_matchstruct __read_mostly = {
        .name           = "icmp6",
-       .match          = &icmp6_match,
+       .match          = icmp6_match,
        .matchsize      = sizeof(struct ip6t_icmp),
        .checkentry     = icmp6_checkentry,
        .proto          = IPPROTO_ICMPV6,
@@ -1516,6 +2267,7 @@ err1:
 static void __exit ip6_tables_fini(void)
 {
        nf_unregister_sockopt(&ip6t_sockopts);
+
        xt_unregister_match(&icmp6_matchstruct);
        xt_unregister_target(&ip6t_error_target);
        xt_unregister_target(&ip6t_standard_target);
index 9afc836fd454a0ab76d3fa3bcd5f5a7f15bf9950..d5f8fd5f29d3eb650ae514aa560aad3d3d485059 100644 (file)
 #include <linux/netfilter_ipv6/ip6t_HL.h>
 
 MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
-MODULE_DESCRIPTION("IP6 tables Hop Limit modification module");
+MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
 MODULE_LICENSE("GPL");
 
-static unsigned int ip6t_hl_target(struct sk_buff *skb,
-                                  const struct net_device *in,
-                                  const struct net_device *out,
-                                  unsigned int hooknum,
-                                  const struct xt_target *target,
-                                  const void *targinfo)
+static unsigned int
+hl_tg6(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
 {
        struct ipv6hdr *ip6h;
        const struct ip6t_HL_info *info = targinfo;
@@ -58,11 +56,10 @@ static unsigned int ip6t_hl_target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static bool ip6t_hl_checkentry(const char *tablename,
-               const void *entry,
-               const struct xt_target *target,
-               void *targinfo,
-               unsigned int hook_mask)
+static bool
+hl_tg6_check(const char *tablename, const void *entry,
+             const struct xt_target *target, void *targinfo,
+             unsigned int hook_mask)
 {
        const struct ip6t_HL_info *info = targinfo;
 
@@ -79,25 +76,25 @@ static bool ip6t_hl_checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target ip6t_HL __read_mostly = {
+static struct xt_target hl_tg6_reg __read_mostly = {
        .name           = "HL",
        .family         = AF_INET6,
-       .target         = ip6t_hl_target,
+       .target         = hl_tg6,
        .targetsize     = sizeof(struct ip6t_HL_info),
        .table          = "mangle",
-       .checkentry     = ip6t_hl_checkentry,
+       .checkentry     = hl_tg6_check,
        .me             = THIS_MODULE
 };
 
-static int __init ip6t_hl_init(void)
+static int __init hl_tg6_init(void)
 {
-       return xt_register_target(&ip6t_HL);
+       return xt_register_target(&hl_tg6_reg);
 }
 
-static void __exit ip6t_hl_fini(void)
+static void __exit hl_tg6_exit(void)
 {
-       xt_unregister_target(&ip6t_HL);
+       xt_unregister_target(&hl_tg6_reg);
 }
 
-module_init(ip6t_hl_init);
-module_exit(ip6t_hl_fini);
+module_init(hl_tg6_init);
+module_exit(hl_tg6_exit);
index 7a48c342df46d5c5b7dd63f1cec0b49f389ec630..86a613810b6993a4699d8e53de1e03ba4e6ed3d5 100644 (file)
 #include <linux/netfilter.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
+#include <net/netfilter/nf_log.h>
 
 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
-MODULE_DESCRIPTION("IP6 tables LOG target module");
+MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog");
 MODULE_LICENSE("GPL");
 
 struct in_device;
@@ -362,7 +363,9 @@ static void dump_packet(const struct nf_loginfo *info,
        if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
                read_lock_bh(&skb->sk->sk_callback_lock);
                if (skb->sk->sk_socket && skb->sk->sk_socket->file)
-                       printk("UID=%u ", skb->sk->sk_socket->file->f_uid);
+                       printk("UID=%u GID=%u",
+                               skb->sk->sk_socket->file->f_uid,
+                               skb->sk->sk_socket->file->f_gid);
                read_unlock_bh(&skb->sk->sk_callback_lock);
        }
 }
@@ -431,12 +434,9 @@ ip6t_log_packet(unsigned int pf,
 }
 
 static unsigned int
-ip6t_log_target(struct sk_buff *skb,
-               const struct net_device *in,
-               const struct net_device *out,
-               unsigned int hooknum,
-               const struct xt_target *target,
-               const void *targinfo)
+log_tg6(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
 {
        const struct ip6t_log_info *loginfo = targinfo;
        struct nf_loginfo li;
@@ -450,11 +450,10 @@ ip6t_log_target(struct sk_buff *skb,
 }
 
 
-static bool ip6t_log_checkentry(const char *tablename,
-                               const void *entry,
-                               const struct xt_target *target,
-                               void *targinfo,
-                               unsigned int hook_mask)
+static bool
+log_tg6_check(const char *tablename, const void *entry,
+              const struct xt_target *target, void *targinfo,
+              unsigned int hook_mask)
 {
        const struct ip6t_log_info *loginfo = targinfo;
 
@@ -470,37 +469,37 @@ static bool ip6t_log_checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target ip6t_log_reg __read_mostly = {
+static struct xt_target log_tg6_reg __read_mostly = {
        .name           = "LOG",
        .family         = AF_INET6,
-       .target         = ip6t_log_target,
+       .target         = log_tg6,
        .targetsize     = sizeof(struct ip6t_log_info),
-       .checkentry     = ip6t_log_checkentry,
+       .checkentry     = log_tg6_check,
        .me             = THIS_MODULE,
 };
 
-static struct nf_logger ip6t_logger = {
+static const struct nf_logger ip6t_logger = {
        .name           = "ip6t_LOG",
        .logfn          = &ip6t_log_packet,
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_log_init(void)
+static int __init log_tg6_init(void)
 {
        int ret;
 
-       ret = xt_register_target(&ip6t_log_reg);
+       ret = xt_register_target(&log_tg6_reg);
        if (ret < 0)
                return ret;
        nf_log_register(PF_INET6, &ip6t_logger);
        return 0;
 }
 
-static void __exit ip6t_log_fini(void)
+static void __exit log_tg6_exit(void)
 {
        nf_log_unregister(&ip6t_logger);
-       xt_unregister_target(&ip6t_log_reg);
+       xt_unregister_target(&log_tg6_reg);
 }
 
-module_init(ip6t_log_init);
-module_exit(ip6t_log_fini);
+module_init(log_tg6_init);
+module_exit(log_tg6_exit);
index 1a7d2917545d50cadf8a5a9f6640ec5b045f66c3..b23baa635fe0f591f8584123e9283244dbbec280 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/netfilter_ipv6/ip6t_REJECT.h>
 
 MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
-MODULE_DESCRIPTION("IP6 tables REJECT target module");
+MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
 MODULE_LICENSE("GPL");
 
 /* Send RST reply */
@@ -121,7 +121,6 @@ static void send_reset(struct sk_buff *oldskb)
        ip6h->version = 6;
        ip6h->hop_limit = dst_metric(dst, RTAX_HOPLIMIT);
        ip6h->nexthdr = IPPROTO_TCP;
-       ip6h->payload_len = htons(sizeof(struct tcphdr));
        ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr);
        ipv6_addr_copy(&ip6h->daddr, &oip6h->saddr);
 
@@ -159,25 +158,22 @@ static void send_reset(struct sk_buff *oldskb)
 
        nf_ct_attach(nskb, oldskb);
 
-       NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
-               dst_output);
+       ip6_local_out(nskb);
 }
 
 static inline void
 send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum)
 {
-       if (hooknum == NF_IP6_LOCAL_OUT && skb_in->dev == NULL)
+       if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
                skb_in->dev = init_net.loopback_dev;
 
        icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
 }
 
-static unsigned int reject6_target(struct sk_buff *skb,
-                          const struct net_device *in,
-                          const struct net_device *out,
-                          unsigned int hooknum,
-                          const struct xt_target *target,
-                          const void *targinfo)
+static unsigned int
+reject_tg6(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        const struct ip6t_reject_info *reject = targinfo;
 
@@ -216,11 +212,10 @@ static unsigned int reject6_target(struct sk_buff *skb,
        return NF_DROP;
 }
 
-static bool check(const char *tablename,
-                 const void *entry,
-                 const struct xt_target *target,
-                 void *targinfo,
-                 unsigned int hook_mask)
+static bool
+reject_tg6_check(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct ip6t_reject_info *rejinfo = targinfo;
        const struct ip6t_entry *e = entry;
@@ -239,27 +234,27 @@ static bool check(const char *tablename,
        return true;
 }
 
-static struct xt_target ip6t_reject_reg __read_mostly = {
+static struct xt_target reject_tg6_reg __read_mostly = {
        .name           = "REJECT",
        .family         = AF_INET6,
-       .target         = reject6_target,
+       .target         = reject_tg6,
        .targetsize     = sizeof(struct ip6t_reject_info),
        .table          = "filter",
-       .hooks          = (1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) |
-                         (1 << NF_IP6_LOCAL_OUT),
-       .checkentry     = check,
+       .hooks          = (1 << NF_INET_LOCAL_IN) | (1 << NF_INET_FORWARD) |
+                         (1 << NF_INET_LOCAL_OUT),
+       .checkentry     = reject_tg6_check,
        .me             = THIS_MODULE
 };
 
-static int __init ip6t_reject_init(void)
+static int __init reject_tg6_init(void)
 {
-       return xt_register_target(&ip6t_reject_reg);
+       return xt_register_target(&reject_tg6_reg);
 }
 
-static void __exit ip6t_reject_fini(void)
+static void __exit reject_tg6_exit(void)
 {
-       xt_unregister_target(&ip6t_reject_reg);
+       xt_unregister_target(&reject_tg6_reg);
 }
 
-module_init(ip6t_reject_init);
-module_exit(ip6t_reject_fini);
+module_init(reject_tg6_init);
+module_exit(reject_tg6_exit);
index 2a25fe25e0e0d236947a6f3c281b3e72415a3572..429629fd63b679e982a6c2489804e06d2c29fc4c 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/netfilter_ipv6/ip6t_ah.h>
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IPv6 AH match");
+MODULE_DESCRIPTION("Xtables: IPv6 IPsec-AH match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
@@ -37,14 +37,9 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+ah_mt6(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct ip_auth_hdr _ah;
        const struct ip_auth_hdr *ah;
@@ -100,11 +95,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-         const void *entry,
-         const struct xt_match *match,
-         void *matchinfo,
-         unsigned int hook_mask)
+ah_mt6_check(const char *tablename, const void *entry,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct ip6t_ah *ahinfo = matchinfo;
 
@@ -115,24 +108,24 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match ah_match __read_mostly = {
+static struct xt_match ah_mt6_reg __read_mostly = {
        .name           = "ah",
        .family         = AF_INET6,
-       .match          = match,
+       .match          = ah_mt6,
        .matchsize      = sizeof(struct ip6t_ah),
-       .checkentry     = checkentry,
+       .checkentry     = ah_mt6_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_ah_init(void)
+static int __init ah_mt6_init(void)
 {
-       return xt_register_match(&ah_match);
+       return xt_register_match(&ah_mt6_reg);
 }
 
-static void __exit ip6t_ah_fini(void)
+static void __exit ah_mt6_exit(void)
 {
-       xt_unregister_match(&ah_match);
+       xt_unregister_match(&ah_mt6_reg);
 }
 
-module_init(ip6t_ah_init);
-module_exit(ip6t_ah_fini);
+module_init(ah_mt6_init);
+module_exit(ah_mt6_exit);
index 41df9a578c7aa8f630f48a825b36d9111e90a032..8f331f12b2ec06d7c04379905047f896f40a74dd 100644 (file)
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 
-MODULE_DESCRIPTION("IPv6 EUI64 address checking match");
+MODULE_DESCRIPTION("Xtables: IPv6 EUI64 address match");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        unsigned char eui64[8];
        int i = 0;
@@ -62,25 +58,25 @@ match(const struct sk_buff *skb,
        return false;
 }
 
-static struct xt_match eui64_match __read_mostly = {
+static struct xt_match eui64_mt6_reg __read_mostly = {
        .name           = "eui64",
        .family         = AF_INET6,
-       .match          = match,
+       .match          = eui64_mt6,
        .matchsize      = sizeof(int),
-       .hooks          = (1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_IN) |
-                         (1 << NF_IP6_FORWARD),
+       .hooks          = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
+                         (1 << NF_INET_FORWARD),
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_eui64_init(void)
+static int __init eui64_mt6_init(void)
 {
-       return xt_register_match(&eui64_match);
+       return xt_register_match(&eui64_mt6_reg);
 }
 
-static void __exit ip6t_eui64_fini(void)
+static void __exit eui64_mt6_exit(void)
 {
-       xt_unregister_match(&eui64_match);
+       xt_unregister_match(&eui64_mt6_reg);
 }
 
-module_init(ip6t_eui64_init);
-module_exit(ip6t_eui64_fini);
+module_init(eui64_mt6_init);
+module_exit(eui64_mt6_exit);
index 968aeba020737856abb6e1de3f4803849c9c2e2e..e2bbc63dba5b752f85322de8181b0ed13e6729c9 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/netfilter_ipv6/ip6t_frag.h>
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IPv6 FRAG match");
+MODULE_DESCRIPTION("Xtables: IPv6 fragment match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 /* Returns 1 if the id is matched by the range, 0 otherwise */
@@ -35,14 +35,10 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+frag_mt6(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        struct frag_hdr _frag;
        const struct frag_hdr *fh;
@@ -116,11 +112,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *ip,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+frag_mt6_check(const char *tablename, const void *ip,
+               const struct xt_match *match, void *matchinfo,
+               unsigned int hook_mask)
 {
        const struct ip6t_frag *fraginfo = matchinfo;
 
@@ -131,24 +125,24 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match frag_match __read_mostly = {
+static struct xt_match frag_mt6_reg __read_mostly = {
        .name           = "frag",
        .family         = AF_INET6,
-       .match          = match,
+       .match          = frag_mt6,
        .matchsize      = sizeof(struct ip6t_frag),
-       .checkentry     = checkentry,
+       .checkentry     = frag_mt6_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_frag_init(void)
+static int __init frag_mt6_init(void)
 {
-       return xt_register_match(&frag_match);
+       return xt_register_match(&frag_mt6_reg);
 }
 
-static void __exit ip6t_frag_fini(void)
+static void __exit frag_mt6_exit(void)
 {
-       xt_unregister_match(&frag_match);
+       xt_unregister_match(&frag_mt6_reg);
 }
 
-module_init(ip6t_frag_init);
-module_exit(ip6t_frag_fini);
+module_init(frag_mt6_init);
+module_exit(frag_mt6_exit);
index e6ca6018b1eaaf0764608debfe1f0821b8a7fffd..62e39ace05888f72fcda1e3b54b3bcc2d366f005 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/netfilter_ipv6/ip6t_opts.h>
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IPv6 opts match");
+MODULE_DESCRIPTION("Xtables: IPv6 Hop-By-Hop and Destination Header match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 MODULE_ALIAS("ip6t_dst");
 
@@ -42,14 +42,10 @@ MODULE_ALIAS("ip6t_dst");
  */
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff,
+        bool *hotdrop)
 {
        struct ipv6_opt_hdr _optsh;
        const struct ipv6_opt_hdr *oh;
@@ -171,11 +167,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *entry,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+hbh_mt6_check(const char *tablename, const void *entry,
+              const struct xt_match *match, void *matchinfo,
+              unsigned int hook_mask)
 {
        const struct ip6t_opts *optsinfo = matchinfo;
 
@@ -186,36 +180,36 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match opts_match[] __read_mostly = {
+static struct xt_match hbh_mt6_reg[] __read_mostly = {
        {
                .name           = "hbh",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = hbh_mt6,
                .matchsize      = sizeof(struct ip6t_opts),
-               .checkentry     = checkentry,
+               .checkentry     = hbh_mt6_check,
                .me             = THIS_MODULE,
                .data           = NEXTHDR_HOP,
        },
        {
                .name           = "dst",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = hbh_mt6,
                .matchsize      = sizeof(struct ip6t_opts),
-               .checkentry     = checkentry,
+               .checkentry     = hbh_mt6_check,
                .me             = THIS_MODULE,
                .data           = NEXTHDR_DEST,
        },
 };
 
-static int __init ip6t_hbh_init(void)
+static int __init hbh_mt6_init(void)
 {
-       return xt_register_matches(opts_match, ARRAY_SIZE(opts_match));
+       return xt_register_matches(hbh_mt6_reg, ARRAY_SIZE(hbh_mt6_reg));
 }
 
-static void __exit ip6t_hbh_fini(void)
+static void __exit hbh_mt6_exit(void)
 {
-       xt_unregister_matches(opts_match, ARRAY_SIZE(opts_match));
+       xt_unregister_matches(hbh_mt6_reg, ARRAY_SIZE(hbh_mt6_reg));
 }
 
-module_init(ip6t_hbh_init);
-module_exit(ip6t_hbh_fini);
+module_init(hbh_mt6_init);
+module_exit(hbh_mt6_exit);
index ca29ec00dc188f7b2ab3a5021ed9ad6e4a8cb68d..345671673845699476e9cc49144f6a9b4df90af9 100644 (file)
 #include <linux/netfilter/x_tables.h>
 
 MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
-MODULE_DESCRIPTION("IP tables Hop Limit matching module");
+MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
 MODULE_LICENSE("GPL");
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in, const struct net_device *out,
-                 const struct xt_match *match, const void *matchinfo,
-                 int offset, unsigned int protoff, bool *hotdrop)
+static bool
+hl_mt6(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct ip6t_hl_info *info = matchinfo;
        const struct ipv6hdr *ip6h = ipv6_hdr(skb);
@@ -49,23 +49,23 @@ static bool match(const struct sk_buff *skb,
        return false;
 }
 
-static struct xt_match hl_match __read_mostly = {
+static struct xt_match hl_mt6_reg __read_mostly = {
        .name           = "hl",
        .family         = AF_INET6,
-       .match          = match,
+       .match          = hl_mt6,
        .matchsize      = sizeof(struct ip6t_hl_info),
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_hl_init(void)
+static int __init hl_mt6_init(void)
 {
-       return xt_register_match(&hl_match);
+       return xt_register_match(&hl_mt6_reg);
 }
 
-static void __exit ip6t_hl_fini(void)
+static void __exit hl_mt6_exit(void)
 {
-       xt_unregister_match(&hl_match);
+       xt_unregister_match(&hl_mt6_reg);
 }
 
-module_init(ip6t_hl_init);
-module_exit(ip6t_hl_fini);
+module_init(hl_mt6_init);
+module_exit(hl_mt6_exit);
index 2c65c2f9a4ab116ea3de849f810d554be10f57ad..3a940171f8297ac47669e658d2f8c80e5f5945ed 100644 (file)
 #include <linux/netfilter_ipv6/ip6t_ipv6header.h>
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IPv6 headers match");
+MODULE_DESCRIPTION("Xtables: IPv6 header types match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 static bool
-ipv6header_match(const struct sk_buff *skb,
-                const struct net_device *in,
-                const struct net_device *out,
-                const struct xt_match *match,
-                const void *matchinfo,
-                int offset,
-                unsigned int protoff,
-                bool *hotdrop)
+ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, const struct xt_match *match,
+               const void *matchinfo, int offset, unsigned int protoff,
+               bool *hotdrop)
 {
        const struct ip6t_ipv6header_info *info = matchinfo;
        unsigned int temp;
@@ -125,11 +121,9 @@ ipv6header_match(const struct sk_buff *skb,
 }
 
 static bool
-ipv6header_checkentry(const char *tablename,
-                     const void *ip,
-                     const struct xt_match *match,
-                     void *matchinfo,
-                     unsigned int hook_mask)
+ipv6header_mt6_check(const char *tablename, const void *ip,
+                     const struct xt_match *match, void *matchinfo,
+                     unsigned int hook_mask)
 {
        const struct ip6t_ipv6header_info *info = matchinfo;
 
@@ -141,25 +135,25 @@ ipv6header_checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match ip6t_ipv6header_match __read_mostly = {
+static struct xt_match ipv6header_mt6_reg __read_mostly = {
        .name           = "ipv6header",
        .family         = AF_INET6,
-       .match          = &ipv6header_match,
+       .match          = ipv6header_mt6,
        .matchsize      = sizeof(struct ip6t_ipv6header_info),
-       .checkentry     = &ipv6header_checkentry,
+       .checkentry     = ipv6header_mt6_check,
        .destroy        = NULL,
        .me             = THIS_MODULE,
 };
 
-static int __init ipv6header_init(void)
+static int __init ipv6header_mt6_init(void)
 {
-       return xt_register_match(&ip6t_ipv6header_match);
+       return xt_register_match(&ipv6header_mt6_reg);
 }
 
-static void __exit ipv6header_exit(void)
+static void __exit ipv6header_mt6_exit(void)
 {
-       xt_unregister_match(&ip6t_ipv6header_match);
+       xt_unregister_match(&ipv6header_mt6_reg);
 }
 
-module_init(ipv6header_init);
-module_exit(ipv6header_exit);
+module_init(ipv6header_mt6_init);
+module_exit(ipv6header_mt6_exit);
index 0fa714092dc948a0b0c29801f9597884839ba611..e06678d07ec8a8d6b52dd8c16436c4a34cb73611 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv6/ip6t_mh.h>
 
-MODULE_DESCRIPTION("ip6t_tables match for MH");
+MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match");
 MODULE_LICENSE("GPL");
 
 #ifdef DEBUG_IP_FIREWALL_USER
@@ -38,14 +38,9 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-        const struct net_device *in,
-        const struct net_device *out,
-        const struct xt_match *match,
-        const void *matchinfo,
-        int offset,
-        unsigned int protoff,
-        bool *hotdrop)
+mh_mt6(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct ip6_mh _mh;
        const struct ip6_mh *mh;
@@ -77,11 +72,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-mh_checkentry(const char *tablename,
-             const void *entry,
-             const struct xt_match *match,
-             void *matchinfo,
-             unsigned int hook_mask)
+mh_mt6_check(const char *tablename, const void *entry,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct ip6t_mh *mhinfo = matchinfo;
 
@@ -89,25 +82,25 @@ mh_checkentry(const char *tablename,
        return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
 }
 
-static struct xt_match mh_match __read_mostly = {
+static struct xt_match mh_mt6_reg __read_mostly = {
        .name           = "mh",
        .family         = AF_INET6,
-       .checkentry     = mh_checkentry,
-       .match          = match,
+       .checkentry     = mh_mt6_check,
+       .match          = mh_mt6,
        .matchsize      = sizeof(struct ip6t_mh),
        .proto          = IPPROTO_MH,
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_mh_init(void)
+static int __init mh_mt6_init(void)
 {
-       return xt_register_match(&mh_match);
+       return xt_register_match(&mh_mt6_reg);
 }
 
-static void __exit ip6t_mh_fini(void)
+static void __exit mh_mt6_exit(void)
 {
-       xt_unregister_match(&mh_match);
+       xt_unregister_match(&mh_mt6_reg);
 }
 
-module_init(ip6t_mh_init);
-module_exit(ip6t_mh_fini);
+module_init(mh_mt6_init);
+module_exit(mh_mt6_exit);
diff --git a/net/ipv6/netfilter/ip6t_owner.c b/net/ipv6/netfilter/ip6t_owner.c
deleted file mode 100644 (file)
index 6036613..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Kernel module to match various things tied to sockets associated with
-   locally generated outgoing packets. */
-
-/* (C) 2000-2001 Marc Boucher <marc@mbsi.ca>
- *
- * 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/skbuff.h>
-#include <linux/file.h>
-#include <linux/rcupdate.h>
-#include <net/sock.h>
-
-#include <linux/netfilter_ipv6/ip6t_owner.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <linux/netfilter/x_tables.h>
-
-MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("IP6 tables owner matching module");
-MODULE_LICENSE("GPL");
-
-
-static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
-{
-       const struct ip6t_owner_info *info = matchinfo;
-
-       if (!skb->sk || !skb->sk->sk_socket || !skb->sk->sk_socket->file)
-               return false;
-
-       if (info->match & IP6T_OWNER_UID)
-               if ((skb->sk->sk_socket->file->f_uid != info->uid) ^
-                   !!(info->invert & IP6T_OWNER_UID))
-                       return false;
-
-       if (info->match & IP6T_OWNER_GID)
-               if ((skb->sk->sk_socket->file->f_gid != info->gid) ^
-                   !!(info->invert & IP6T_OWNER_GID))
-                       return false;
-
-       return true;
-}
-
-static bool
-checkentry(const char *tablename,
-          const void *ip,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
-{
-       const struct ip6t_owner_info *info = matchinfo;
-
-       if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
-               printk("ipt_owner: pid and sid matching "
-                      "not supported anymore\n");
-               return false;
-       }
-       return true;
-}
-
-static struct xt_match owner_match __read_mostly = {
-       .name           = "owner",
-       .family         = AF_INET6,
-       .match          = match,
-       .matchsize      = sizeof(struct ip6t_owner_info),
-       .hooks          = (1 << NF_IP6_LOCAL_OUT) | (1 << NF_IP6_POST_ROUTING),
-       .checkentry     = checkentry,
-       .me             = THIS_MODULE,
-};
-
-static int __init ip6t_owner_init(void)
-{
-       return xt_register_match(&owner_match);
-}
-
-static void __exit ip6t_owner_fini(void)
-{
-       xt_unregister_match(&owner_match);
-}
-
-module_init(ip6t_owner_init);
-module_exit(ip6t_owner_fini);
index 357cea703bd9b3e505f088d5deaaf8212debdea9..12a9efe9886e86e7fa726722f5d2a4fc64bbd28e 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/netfilter_ipv6/ip6t_rt.h>
 
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("IPv6 RT match");
+MODULE_DESCRIPTION("Xtables: IPv6 Routing Header match");
 MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
 
 /* Returns 1 if the id is matched by the range, 0 otherwise */
@@ -37,14 +37,9 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+rt_mt6(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct ipv6_rt_hdr _route;
        const struct ipv6_rt_hdr *rh;
@@ -195,11 +190,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *entry,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+rt_mt6_check(const char *tablename, const void *entry,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct ip6t_rt *rtinfo = matchinfo;
 
@@ -218,24 +211,24 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match rt_match __read_mostly = {
+static struct xt_match rt_mt6_reg __read_mostly = {
        .name           = "rt",
        .family         = AF_INET6,
-       .match          = match,
+       .match          = rt_mt6,
        .matchsize      = sizeof(struct ip6t_rt),
-       .checkentry     = checkentry,
+       .checkentry     = rt_mt6_check,
        .me             = THIS_MODULE,
 };
 
-static int __init ip6t_rt_init(void)
+static int __init rt_mt6_init(void)
 {
-       return xt_register_match(&rt_match);
+       return xt_register_match(&rt_mt6_reg);
 }
 
-static void __exit ip6t_rt_fini(void)
+static void __exit rt_mt6_exit(void)
 {
-       xt_unregister_match(&rt_match);
+       xt_unregister_match(&rt_mt6_reg);
 }
 
-module_init(ip6t_rt_init);
-module_exit(ip6t_rt_fini);
+module_init(rt_mt6_init);
+module_exit(rt_mt6_exit);
index 1d26b202bf3017bd9abc6fc403b9dea09559d3f5..87d38d08aad090e92f7f2dc022d203a7fb5ad54e 100644 (file)
@@ -17,7 +17,9 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("ip6tables filter table");
 
-#define FILTER_VALID_HOOKS ((1 << NF_IP6_LOCAL_IN) | (1 << NF_IP6_FORWARD) | (1 << NF_IP6_LOCAL_OUT))
+#define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \
+                           (1 << NF_INET_FORWARD) | \
+                           (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -31,14 +33,14 @@ static struct
                .num_entries = 4,
                .size = sizeof(struct ip6t_standard) * 3 + sizeof(struct ip6t_error),
                .hook_entry = {
-                       [NF_IP6_LOCAL_IN] = 0,
-                       [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
-                       [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+                       [NF_INET_LOCAL_IN] = 0,
+                       [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
                },
                .underflow = {
-                       [NF_IP6_LOCAL_IN] = 0,
-                       [NF_IP6_FORWARD] = sizeof(struct ip6t_standard),
-                       [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
+                       [NF_INET_LOCAL_IN] = 0,
+                       [NF_INET_FORWARD] = sizeof(struct ip6t_standard),
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) * 2
                },
        },
        .entries = {
@@ -88,26 +90,26 @@ ip6t_local_out_hook(unsigned int hook,
        return ip6t_do_table(skb, hook, in, out, &packet_filter);
 }
 
-static struct nf_hook_ops ip6t_ops[] = {
+static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        {
                .hook           = ip6t_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP6_PRI_FILTER,
        },
        {
                .hook           = ip6t_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_FORWARD,
+               .hooknum        = NF_INET_FORWARD,
                .priority       = NF_IP6_PRI_FILTER,
        },
        {
                .hook           = ip6t_local_out_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP6_PRI_FILTER,
        },
 };
index a0b6381f1e8c1eae1bb77f6c88b7e7fa4542c7f6..d6082600bc5db6d260183e0da010252e6413a157 100644 (file)
@@ -15,11 +15,11 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("ip6tables mangle table");
 
-#define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | \
-                           (1 << NF_IP6_LOCAL_IN) | \
-                           (1 << NF_IP6_FORWARD) | \
-                           (1 << NF_IP6_LOCAL_OUT) | \
-                           (1 << NF_IP6_POST_ROUTING))
+#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
+                           (1 << NF_INET_LOCAL_IN) | \
+                           (1 << NF_INET_FORWARD) | \
+                           (1 << NF_INET_LOCAL_OUT) | \
+                           (1 << NF_INET_POST_ROUTING))
 
 static struct
 {
@@ -33,18 +33,18 @@ static struct
                .num_entries = 6,
                .size = sizeof(struct ip6t_standard) * 5 + sizeof(struct ip6t_error),
                .hook_entry = {
-                       [NF_IP6_PRE_ROUTING]    = 0,
-                       [NF_IP6_LOCAL_IN]       = sizeof(struct ip6t_standard),
-                       [NF_IP6_FORWARD]        = sizeof(struct ip6t_standard) * 2,
-                       [NF_IP6_LOCAL_OUT]      = sizeof(struct ip6t_standard) * 3,
-                       [NF_IP6_POST_ROUTING]   = sizeof(struct ip6t_standard) * 4,
+                       [NF_INET_PRE_ROUTING]   = 0,
+                       [NF_INET_LOCAL_IN]      = sizeof(struct ip6t_standard),
+                       [NF_INET_FORWARD]       = sizeof(struct ip6t_standard) * 2,
+                       [NF_INET_LOCAL_OUT]     = sizeof(struct ip6t_standard) * 3,
+                       [NF_INET_POST_ROUTING]  = sizeof(struct ip6t_standard) * 4,
                },
                .underflow = {
-                       [NF_IP6_PRE_ROUTING]    = 0,
-                       [NF_IP6_LOCAL_IN]       = sizeof(struct ip6t_standard),
-                       [NF_IP6_FORWARD]        = sizeof(struct ip6t_standard) * 2,
-                       [NF_IP6_LOCAL_OUT]      = sizeof(struct ip6t_standard) * 3,
-                       [NF_IP6_POST_ROUTING]   = sizeof(struct ip6t_standard) * 4,
+                       [NF_INET_PRE_ROUTING]   = 0,
+                       [NF_INET_LOCAL_IN]      = sizeof(struct ip6t_standard),
+                       [NF_INET_FORWARD]       = sizeof(struct ip6t_standard) * 2,
+                       [NF_INET_LOCAL_OUT]     = sizeof(struct ip6t_standard) * 3,
+                       [NF_INET_POST_ROUTING]  = sizeof(struct ip6t_standard) * 4,
                },
        },
        .entries = {
@@ -120,40 +120,40 @@ ip6t_local_hook(unsigned int hook,
        return ret;
 }
 
-static struct nf_hook_ops ip6t_ops[] = {
+static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        {
                .hook           = ip6t_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP6_PRI_MANGLE,
        },
        {
                .hook           = ip6t_local_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP6_PRI_MANGLE,
        },
        {
                .hook           = ip6t_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_FORWARD,
+               .hooknum        = NF_INET_FORWARD,
                .priority       = NF_IP6_PRI_MANGLE,
        },
        {
                .hook           = ip6t_local_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP6_PRI_MANGLE,
        },
        {
                .hook           = ip6t_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP6_PRI_MANGLE,
        },
 };
index 8f7109f991e6032b7c2f671f8678ebb14a3f06dd..eccbaaa104af264a3308208178abce7c30a0c64b 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/module.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 
-#define RAW_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
+#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
 
 static struct
 {
@@ -20,12 +20,12 @@ static struct
                .num_entries = 3,
                .size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
                .hook_entry = {
-                       [NF_IP6_PRE_ROUTING] = 0,
-                       [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard)
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
                },
                .underflow = {
-                       [NF_IP6_PRE_ROUTING] = 0,
-                       [NF_IP6_LOCAL_OUT] = sizeof(struct ip6t_standard)
+                       [NF_INET_PRE_ROUTING] = 0,
+                       [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard)
                },
        },
        .entries = {
@@ -54,18 +54,18 @@ ip6t_hook(unsigned int hook,
        return ip6t_do_table(skb, hook, in, out, &packet_raw);
 }
 
-static struct nf_hook_ops ip6t_ops[] = {
+static struct nf_hook_ops ip6t_ops[] __read_mostly = {
        {
          .hook = ip6t_hook,
          .pf = PF_INET6,
-         .hooknum = NF_IP6_PRE_ROUTING,
+         .hooknum = NF_INET_PRE_ROUTING,
          .priority = NF_IP6_PRI_FIRST,
          .owner = THIS_MODULE,
        },
        {
          .hook = ip6t_hook,
          .pf = PF_INET6,
-         .hooknum = NF_IP6_LOCAL_OUT,
+         .hooknum = NF_INET_LOCAL_OUT,
          .priority = NF_IP6_PRI_FIRST,
          .owner = THIS_MODULE,
        },
index ad74bab050477305a93153e586492dc663b7c3ee..2d7b0246475d898848290fc38120cd41d1d73aa9 100644 (file)
@@ -60,12 +60,6 @@ static int ipv6_print_tuple(struct seq_file *s,
                          NIP6(*((struct in6_addr *)tuple->dst.u3.ip6)));
 }
 
-static int ipv6_print_conntrack(struct seq_file *s,
-                               const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /*
  * Based on ipv6_skip_exthdr() in net/ipv6/exthdr.c
  *
@@ -258,80 +252,51 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
        return ipv6_conntrack_in(hooknum, skb, in, out, okfn);
 }
 
-static struct nf_hook_ops ipv6_conntrack_ops[] = {
+static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
        {
                .hook           = ipv6_defrag,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP6_PRI_CONNTRACK_DEFRAG,
        },
        {
                .hook           = ipv6_conntrack_in,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_PRE_ROUTING,
+               .hooknum        = NF_INET_PRE_ROUTING,
                .priority       = NF_IP6_PRI_CONNTRACK,
        },
        {
                .hook           = ipv6_conntrack_local,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP6_PRI_CONNTRACK,
        },
        {
                .hook           = ipv6_defrag,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_OUT,
+               .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP6_PRI_CONNTRACK_DEFRAG,
        },
        {
                .hook           = ipv6_confirm,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_POST_ROUTING,
+               .hooknum        = NF_INET_POST_ROUTING,
                .priority       = NF_IP6_PRI_LAST,
        },
        {
                .hook           = ipv6_confirm,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
-               .hooknum        = NF_IP6_LOCAL_IN,
+               .hooknum        = NF_INET_LOCAL_IN,
                .priority       = NF_IP6_PRI_LAST-1,
        },
 };
 
-#ifdef CONFIG_SYSCTL
-static ctl_table nf_ct_ipv6_sysctl_table[] = {
-       {
-               .procname       = "nf_conntrack_frag6_timeout",
-               .data           = &nf_frags_ctl.timeout,
-               .maxlen         = sizeof(unsigned int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-       },
-       {
-               .ctl_name       = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
-               .procname       = "nf_conntrack_frag6_low_thresh",
-               .data           = &nf_frags_ctl.low_thresh,
-               .maxlen         = sizeof(unsigned int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-       },
-       {
-               .ctl_name       = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
-               .procname       = "nf_conntrack_frag6_high_thresh",
-               .data           = &nf_frags_ctl.high_thresh,
-               .maxlen         = sizeof(unsigned int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
-       },
-       { .ctl_name = 0 }
-};
-#endif
-
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 
 #include <linux/netfilter/nfnetlink.h>
@@ -376,7 +341,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
        .pkt_to_tuple           = ipv6_pkt_to_tuple,
        .invert_tuple           = ipv6_invert_tuple,
        .print_tuple            = ipv6_print_tuple,
-       .print_conntrack        = ipv6_print_conntrack,
        .get_l4proto            = ipv6_get_l4proto,
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nlattr        = ipv6_tuple_to_nlattr,
index fd9123f3dc04dfc25472130744875548dd4de04b..da924c6b5f065676f526d723aa5501191ead8862 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
+#include <net/netfilter/nf_log.h>
 
 static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
 
@@ -74,13 +75,6 @@ static int icmpv6_print_tuple(struct seq_file *s,
                          ntohs(tuple->src.u.icmp.id));
 }
 
-/* Print out the private part of the conntrack. */
-static int icmpv6_print_conntrack(struct seq_file *s,
-                                 const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, or -1 for invalid. */
 static int icmpv6_packet(struct nf_conn *ct,
                       const struct sk_buff *skb,
@@ -192,7 +186,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
                return -NF_ACCEPT;
        }
 
-       if (nf_conntrack_checksum && hooknum == NF_IP6_PRE_ROUTING &&
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
                nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
                              "nf_ct_icmpv6: ICMPv6 checksum failed\n");
@@ -213,12 +207,9 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
 static int icmpv6_tuple_to_nlattr(struct sk_buff *skb,
                                  const struct nf_conntrack_tuple *t)
 {
-       NLA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t),
-               &t->src.u.icmp.id);
-       NLA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t),
-               &t->dst.u.icmp.type);
-       NLA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t),
-               &t->dst.u.icmp.code);
+       NLA_PUT_BE16(skb, CTA_PROTO_ICMPV6_ID, t->src.u.icmp.id);
+       NLA_PUT_U8(skb, CTA_PROTO_ICMPV6_TYPE, t->dst.u.icmp.type);
+       NLA_PUT_U8(skb, CTA_PROTO_ICMPV6_CODE, t->dst.u.icmp.code);
 
        return 0;
 
@@ -240,12 +231,9 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
            || !tb[CTA_PROTO_ICMPV6_ID])
                return -EINVAL;
 
-       tuple->dst.u.icmp.type =
-                       *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMPV6_TYPE]);
-       tuple->dst.u.icmp.code =
-                       *(u_int8_t *)nla_data(tb[CTA_PROTO_ICMPV6_CODE]);
-       tuple->src.u.icmp.id =
-                       *(__be16 *)nla_data(tb[CTA_PROTO_ICMPV6_ID]);
+       tuple->dst.u.icmp.type = nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
+       tuple->dst.u.icmp.code = nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
+       tuple->src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMPV6_ID]);
 
        if (tuple->dst.u.icmp.type < 128
            || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
@@ -280,7 +268,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
        .pkt_to_tuple           = icmpv6_pkt_to_tuple,
        .invert_tuple           = icmpv6_invert_tuple,
        .print_tuple            = icmpv6_print_tuple,
-       .print_conntrack        = icmpv6_print_conntrack,
        .packet                 = icmpv6_packet,
        .new                    = icmpv6_new,
        .error                  = icmpv6_error,
index e170c67c47a5b613c7681d05d0b0f73c784e9c46..022da6ce4c0f3a4548b8ba01fa860d4c8982d116 100644 (file)
@@ -70,14 +70,37 @@ struct nf_ct_frag6_queue
        __u16                   nhoffset;
 };
 
-struct inet_frags_ctl nf_frags_ctl __read_mostly = {
-       .high_thresh     = 256 * 1024,
-       .low_thresh      = 192 * 1024,
-       .timeout         = IPV6_FRAG_TIMEOUT,
-       .secret_interval = 10 * 60 * HZ,
-};
-
 static struct inet_frags nf_frags;
+static struct netns_frags nf_init_frags;
+
+#ifdef CONFIG_SYSCTL
+struct ctl_table nf_ct_ipv6_sysctl_table[] = {
+       {
+               .procname       = "nf_conntrack_frag6_timeout",
+               .data           = &nf_init_frags.timeout,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_jiffies,
+       },
+       {
+               .ctl_name       = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
+               .procname       = "nf_conntrack_frag6_low_thresh",
+               .data           = &nf_init_frags.low_thresh,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+       {
+               .ctl_name       = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
+               .procname       = "nf_conntrack_frag6_high_thresh",
+               .data           = &nf_init_frags.high_thresh,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
+       { .ctl_name = 0 }
+};
+#endif
 
 static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
                               struct in6_addr *daddr)
@@ -125,7 +148,7 @@ static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
 {
        if (work)
                *work -= skb->truesize;
-       atomic_sub(skb->truesize, &nf_frags.mem);
+       atomic_sub(skb->truesize, &nf_init_frags.mem);
        nf_skb_free(skb);
        kfree_skb(skb);
 }
@@ -147,7 +170,7 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
 
 static void nf_ct_frag6_evictor(void)
 {
-       inet_frag_evictor(&nf_frags);
+       inet_frag_evictor(&nf_init_frags, &nf_frags);
 }
 
 static void nf_ct_frag6_expire(unsigned long data)
@@ -183,7 +206,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
        arg.dst = dst;
        hash = ip6qhashfn(id, src, dst);
 
-       q = inet_frag_find(&nf_frags, &arg, hash);
+       q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
        if (q == NULL)
                goto oom;
 
@@ -352,7 +375,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
        skb->dev = NULL;
        fq->q.stamp = skb->tstamp;
        fq->q.meat += skb->len;
-       atomic_add(skb->truesize, &nf_frags.mem);
+       atomic_add(skb->truesize, &nf_init_frags.mem);
 
        /* The first fragment.
         * nhoffset is obtained from the first fragment, of course.
@@ -362,7 +385,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
                fq->q.last_in |= FIRST_IN;
        }
        write_lock(&nf_frags.lock);
-       list_move_tail(&fq->q.lru_list, &nf_frags.lru_list);
+       list_move_tail(&fq->q.lru_list, &nf_init_frags.lru_list);
        write_unlock(&nf_frags.lock);
        return 0;
 
@@ -429,7 +452,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
                clone->ip_summed = head->ip_summed;
 
                NFCT_FRAG6_CB(clone)->orig = NULL;
-               atomic_add(clone->truesize, &nf_frags.mem);
+               atomic_add(clone->truesize, &nf_init_frags.mem);
        }
 
        /* We have to remove fragment header from datagram and to relocate
@@ -443,7 +466,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
        skb_shinfo(head)->frag_list = head->next;
        skb_reset_transport_header(head);
        skb_push(head, head->data - skb_network_header(head));
-       atomic_sub(head->truesize, &nf_frags.mem);
+       atomic_sub(head->truesize, &nf_init_frags.mem);
 
        for (fp=head->next; fp; fp = fp->next) {
                head->data_len += fp->len;
@@ -453,7 +476,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
                else if (head->ip_summed == CHECKSUM_COMPLETE)
                        head->csum = csum_add(head->csum, fp->csum);
                head->truesize += fp->truesize;
-               atomic_sub(fp->truesize, &nf_frags.mem);
+               atomic_sub(fp->truesize, &nf_init_frags.mem);
        }
 
        head->next = NULL;
@@ -603,7 +626,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
                goto ret_orig;
        }
 
-       if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh)
+       if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
                nf_ct_frag6_evictor();
 
        fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr);
@@ -674,7 +697,6 @@ int nf_ct_frag6_kfree_frags(struct sk_buff *skb)
 
 int nf_ct_frag6_init(void)
 {
-       nf_frags.ctl = &nf_frags_ctl;
        nf_frags.hashfn = nf_hashfn;
        nf_frags.constructor = ip6_frag_init;
        nf_frags.destructor = NULL;
@@ -682,6 +704,11 @@ int nf_ct_frag6_init(void)
        nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
        nf_frags.match = ip6_frag_match;
        nf_frags.frag_expire = nf_ct_frag6_expire;
+       nf_frags.secret_interval = 10 * 60 * HZ;
+       nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
+       nf_init_frags.high_thresh = 256 * 1024;
+       nf_init_frags.low_thresh = 192 * 1024;
+       inet_frags_init_net(&nf_init_frags);
        inet_frags_init(&nf_frags);
 
        return 0;
@@ -691,6 +718,6 @@ void nf_ct_frag6_cleanup(void)
 {
        inet_frags_fini(&nf_frags);
 
-       nf_frags_ctl.low_thresh = 0;
+       nf_init_frags.low_thresh = 0;
        nf_ct_frag6_evictor();
 }
index 44937616057e77fb8d5fc61272ad7f1a30f9a8d2..35e502a72495f97efc72c7f386e25ca9d53f95e0 100644 (file)
@@ -27,6 +27,7 @@
 #include <net/ip.h>
 #include <net/sock.h>
 #include <net/tcp.h>
+#include <net/udp.h>
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 
@@ -35,15 +36,15 @@ static struct proc_dir_entry *proc_net_devsnmp6;
 static int sockstat6_seq_show(struct seq_file *seq, void *v)
 {
        seq_printf(seq, "TCP6: inuse %d\n",
-                      sock_prot_inuse(&tcpv6_prot));
+                      sock_prot_inuse_get(&tcpv6_prot));
        seq_printf(seq, "UDP6: inuse %d\n",
-                      sock_prot_inuse(&udpv6_prot));
+                      sock_prot_inuse_get(&udpv6_prot));
        seq_printf(seq, "UDPLITE6: inuse %d\n",
-                       sock_prot_inuse(&udplitev6_prot));
+                       sock_prot_inuse_get(&udplitev6_prot));
        seq_printf(seq, "RAW6: inuse %d\n",
-                      sock_prot_inuse(&rawv6_prot));
+                      sock_prot_inuse_get(&rawv6_prot));
        seq_printf(seq, "FRAG6: inuse %d memory %d\n",
-                      ip6_frag_nqueues(), ip6_frag_mem());
+                      ip6_frag_nqueues(&init_net), ip6_frag_mem(&init_net));
        return 0;
 }
 
index 807260d03586dd596314dc29614e33b3162861f0..4d880551fe6ab327260a09401d2a5a4f3c9e7315 100644 (file)
 #include <net/mip6.h>
 #endif
 
+#include <net/raw.h>
 #include <net/rawv6.h>
 #include <net/xfrm.h>
 
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
-struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
-DEFINE_RWLOCK(raw_v6_lock);
+static struct raw_hashinfo raw_v6_hashinfo = {
+       .lock = __RW_LOCK_UNLOCKED(),
+};
 
 static void raw_v6_hash(struct sock *sk)
 {
-       struct hlist_head *list = &raw_v6_htable[inet_sk(sk)->num &
-                                                (RAWV6_HTABLE_SIZE - 1)];
-
-       write_lock_bh(&raw_v6_lock);
-       sk_add_node(sk, list);
-       sock_prot_inc_use(sk->sk_prot);
-       write_unlock_bh(&raw_v6_lock);
+       raw_hash_sk(sk, &raw_v6_hashinfo);
 }
 
 static void raw_v6_unhash(struct sock *sk)
 {
-       write_lock_bh(&raw_v6_lock);
-       if (sk_del_node_init(sk))
-               sock_prot_dec_use(sk->sk_prot);
-       write_unlock_bh(&raw_v6_lock);
+       raw_unhash_sk(sk, &raw_v6_hashinfo);
 }
 
 
-/* Grumble... icmp and ip_input want to get at this... */
-struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
-                            struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
-                            int dif)
+static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
+               unsigned short num, struct in6_addr *loc_addr,
+               struct in6_addr *rmt_addr, int dif)
 {
        struct hlist_node *node;
        int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -95,6 +87,9 @@ struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
                if (inet_sk(sk)->num == num) {
                        struct ipv6_pinfo *np = inet6_sk(sk);
 
+                       if (sk->sk_net != net)
+                               continue;
+
                        if (!ipv6_addr_any(&np->daddr) &&
                            !ipv6_addr_equal(&np->daddr, rmt_addr))
                                continue;
@@ -167,21 +162,22 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
  *
  *     Caller owns SKB so we must make clones.
  */
-int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
+static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
 {
        struct in6_addr *saddr;
        struct in6_addr *daddr;
        struct sock *sk;
        int delivered = 0;
        __u8 hash;
+       struct net *net;
 
        saddr = &ipv6_hdr(skb)->saddr;
        daddr = saddr + 1;
 
        hash = nexthdr & (MAX_INET_PROTOS - 1);
 
-       read_lock(&raw_v6_lock);
-       sk = sk_head(&raw_v6_htable[hash]);
+       read_lock(&raw_v6_hashinfo.lock);
+       sk = sk_head(&raw_v6_hashinfo.ht[hash]);
 
        /*
         *      The first socket found will be delivered after
@@ -191,7 +187,8 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
        if (sk == NULL)
                goto out;
 
-       sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
+       net = skb->dev->nd_net;
+       sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif);
 
        while (sk) {
                int filtered;
@@ -234,14 +231,25 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
                                rawv6_rcv(sk, clone);
                        }
                }
-               sk = __raw_v6_lookup(sk_next(sk), nexthdr, daddr, saddr,
+               sk = __raw_v6_lookup(net, sk_next(sk), nexthdr, daddr, saddr,
                                     IP6CB(skb)->iif);
        }
 out:
-       read_unlock(&raw_v6_lock);
+       read_unlock(&raw_v6_hashinfo.lock);
        return delivered;
 }
 
+int raw6_local_deliver(struct sk_buff *skb, int nexthdr)
+{
+       struct sock *raw_sk;
+
+       raw_sk = sk_head(&raw_v6_hashinfo.ht[nexthdr & (MAX_INET_PROTOS - 1)]);
+       if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
+               raw_sk = NULL;
+
+       return raw_sk != NULL;
+}
+
 /* This cleans up af_inet6 a bit. -DaveM */
 static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
@@ -283,7 +291,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                        if (!sk->sk_bound_dev_if)
                                goto out;
 
-                       dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
+                       dev = dev_get_by_index(sk->sk_net, sk->sk_bound_dev_if);
                        if (!dev) {
                                err = -ENODEV;
                                goto out;
@@ -296,7 +304,8 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
                v4addr = LOOPBACK4_IPV6;
                if (!(addr_type & IPV6_ADDR_MULTICAST)) {
                        err = -EADDRNOTAVAIL;
-                       if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
+                       if (!ipv6_chk_addr(sk->sk_net, &addr->sin6_addr,
+                                          dev, 0)) {
                                if (dev)
                                        dev_put(dev);
                                goto out;
@@ -316,7 +325,7 @@ out:
        return err;
 }
 
-void rawv6_err(struct sock *sk, struct sk_buff *skb,
+static void rawv6_err(struct sock *sk, struct sk_buff *skb,
               struct inet6_skb_parm *opt,
               int type, int code, int offset, __be32 info)
 {
@@ -350,18 +359,45 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb,
        }
 }
 
+void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
+               int type, int code, int inner_offset, __be32 info)
+{
+       struct sock *sk;
+       int hash;
+       struct in6_addr *saddr, *daddr;
+       struct net *net;
+
+       hash = nexthdr & (RAW_HTABLE_SIZE - 1);
+
+       read_lock(&raw_v6_hashinfo.lock);
+       sk = sk_head(&raw_v6_hashinfo.ht[hash]);
+       if (sk != NULL) {
+               saddr = &ipv6_hdr(skb)->saddr;
+               daddr = &ipv6_hdr(skb)->daddr;
+               net = skb->dev->nd_net;
+
+               while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
+                                               IP6CB(skb)->iif))) {
+                       rawv6_err(sk, skb, NULL, type, code,
+                                       inner_offset, info);
+                       sk = sk_next(sk);
+               }
+       }
+       read_unlock(&raw_v6_hashinfo.lock);
+}
+
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
        if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
            skb_checksum_complete(skb)) {
-               /* FIXME: increment a raw6 drops counter here */
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return 0;
        }
 
        /* Charge it to the socket. */
        if (sock_queue_rcv_skb(sk,skb)<0) {
-               /* FIXME: increment a raw6 drops counter here */
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return 0;
        }
@@ -382,6 +418,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
        struct raw6_sock *rp = raw6_sk(sk);
 
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) {
+               atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
                return NET_RX_DROP;
        }
@@ -405,7 +442,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
 
        if (inet->hdrincl) {
                if (skb_checksum_complete(skb)) {
-                       /* FIXME: increment a raw6 drops counter here */
+                       atomic_inc(&sk->sk_drops);
                        kfree_skb(skb);
                        return 0;
                }
@@ -496,7 +533,7 @@ csum_copy_err:
           as some normal condition.
         */
        err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
-       /* FIXME: increment a raw6 drops counter here */
+       atomic_inc(&sk->sk_drops);
        goto out;
 }
 
@@ -618,7 +655,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
                goto error_fault;
 
        IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
-       err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
+       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                      dst_output);
        if (err > 0)
                err = np->recverr ? net_xmit_errno(err) : 0;
@@ -843,7 +880,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -1172,76 +1209,6 @@ struct proto rawv6_prot = {
 };
 
 #ifdef CONFIG_PROC_FS
-struct raw6_iter_state {
-       int bucket;
-};
-
-#define raw6_seq_private(seq) ((struct raw6_iter_state *)(seq)->private)
-
-static struct sock *raw6_get_first(struct seq_file *seq)
-{
-       struct sock *sk;
-       struct hlist_node *node;
-       struct raw6_iter_state* state = raw6_seq_private(seq);
-
-       for (state->bucket = 0; state->bucket < RAWV6_HTABLE_SIZE; ++state->bucket)
-               sk_for_each(sk, node, &raw_v6_htable[state->bucket])
-                       if (sk->sk_family == PF_INET6)
-                               goto out;
-       sk = NULL;
-out:
-       return sk;
-}
-
-static struct sock *raw6_get_next(struct seq_file *seq, struct sock *sk)
-{
-       struct raw6_iter_state* state = raw6_seq_private(seq);
-
-       do {
-               sk = sk_next(sk);
-try_again:
-               ;
-       } while (sk && sk->sk_family != PF_INET6);
-
-       if (!sk && ++state->bucket < RAWV6_HTABLE_SIZE) {
-               sk = sk_head(&raw_v6_htable[state->bucket]);
-               goto try_again;
-       }
-       return sk;
-}
-
-static struct sock *raw6_get_idx(struct seq_file *seq, loff_t pos)
-{
-       struct sock *sk = raw6_get_first(seq);
-       if (sk)
-               while (pos && (sk = raw6_get_next(seq, sk)) != NULL)
-                       --pos;
-       return pos ? NULL : sk;
-}
-
-static void *raw6_seq_start(struct seq_file *seq, loff_t *pos)
-{
-       read_lock(&raw_v6_lock);
-       return *pos ? raw6_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
-}
-
-static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-       struct sock *sk;
-
-       if (v == SEQ_START_TOKEN)
-               sk = raw6_get_first(seq);
-       else
-               sk = raw6_get_next(seq, v);
-       ++*pos;
-       return sk;
-}
-
-static void raw6_seq_stop(struct seq_file *seq, void *v)
-{
-       read_unlock(&raw_v6_lock);
-}
-
 static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
 {
        struct ipv6_pinfo *np = inet6_sk(sp);
@@ -1254,7 +1221,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
        srcp  = inet_sk(sp)->num;
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p\n",
+                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -1266,7 +1233,7 @@ static void raw6_sock_seq_show(struct seq_file *seq, struct sock *sp, int i)
                   0, 0L, 0,
                   sock_i_uid(sp), 0,
                   sock_i_ino(sp),
-                  atomic_read(&sp->sk_refcnt), sp);
+                  atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));
 }
 
 static int raw6_seq_show(struct seq_file *seq, void *v)
@@ -1277,23 +1244,22 @@ static int raw6_seq_show(struct seq_file *seq, void *v)
                           "local_address                         "
                           "remote_address                        "
                           "st tx_queue rx_queue tr tm->when retrnsmt"
-                          "   uid  timeout inode\n");
+                          "   uid  timeout inode  drops\n");
        else
-               raw6_sock_seq_show(seq, v, raw6_seq_private(seq)->bucket);
+               raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket);
        return 0;
 }
 
 static const struct seq_operations raw6_seq_ops = {
-       .start =        raw6_seq_start,
-       .next =         raw6_seq_next,
-       .stop =         raw6_seq_stop,
+       .start =        raw_seq_start,
+       .next =         raw_seq_next,
+       .stop =         raw_seq_stop,
        .show =         raw6_seq_show,
 };
 
 static int raw6_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &raw6_seq_ops,
-                       sizeof(struct raw6_iter_state));
+       return raw_seq_open(inode, file, &raw_v6_hashinfo, PF_INET6);
 }
 
 static const struct file_operations raw6_seq_fops = {
@@ -1301,18 +1267,86 @@ static const struct file_operations raw6_seq_fops = {
        .open =         raw6_seq_open,
        .read =         seq_read,
        .llseek =       seq_lseek,
-       .release =      seq_release_private,
+       .release =      seq_release_net,
 };
 
-int __init raw6_proc_init(void)
+static int raw6_init_net(struct net *net)
 {
-       if (!proc_net_fops_create(&init_net, "raw6", S_IRUGO, &raw6_seq_fops))
+       if (!proc_net_fops_create(net, "raw6", S_IRUGO, &raw6_seq_fops))
                return -ENOMEM;
+
        return 0;
 }
 
+static void raw6_exit_net(struct net *net)
+{
+       proc_net_remove(net, "raw6");
+}
+
+static struct pernet_operations raw6_net_ops = {
+       .init = raw6_init_net,
+       .exit = raw6_exit_net,
+};
+
+int __init raw6_proc_init(void)
+{
+       return register_pernet_subsys(&raw6_net_ops);
+}
+
 void raw6_proc_exit(void)
 {
-       proc_net_remove(&init_net, "raw6");
+       unregister_pernet_subsys(&raw6_net_ops);
 }
 #endif /* CONFIG_PROC_FS */
+
+/* Same as inet6_dgram_ops, sans udp_poll.  */
+static const struct proto_ops inet6_sockraw_ops = {
+       .family            = PF_INET6,
+       .owner             = THIS_MODULE,
+       .release           = inet6_release,
+       .bind              = inet6_bind,
+       .connect           = inet_dgram_connect,        /* ok           */
+       .socketpair        = sock_no_socketpair,        /* a do nothing */
+       .accept            = sock_no_accept,            /* a do nothing */
+       .getname           = inet6_getname,
+       .poll              = datagram_poll,             /* ok           */
+       .ioctl             = inet6_ioctl,               /* must change  */
+       .listen            = sock_no_listen,            /* ok           */
+       .shutdown          = inet_shutdown,             /* ok           */
+       .setsockopt        = sock_common_setsockopt,    /* ok           */
+       .getsockopt        = sock_common_getsockopt,    /* ok           */
+       .sendmsg           = inet_sendmsg,              /* ok           */
+       .recvmsg           = sock_common_recvmsg,       /* ok           */
+       .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 struct inet_protosw rawv6_protosw = {
+       .type           = SOCK_RAW,
+       .protocol       = IPPROTO_IP,   /* wild card */
+       .prot           = &rawv6_prot,
+       .ops            = &inet6_sockraw_ops,
+       .capability     = CAP_NET_RAW,
+       .no_check       = UDP_CSUM_DEFAULT,
+       .flags          = INET_PROTOSW_REUSE,
+};
+
+int __init rawv6_init(void)
+{
+       int ret;
+
+       ret = inet6_register_protosw(&rawv6_protosw);
+       if (ret)
+               goto out;
+out:
+       return ret;
+}
+
+void rawv6_exit(void)
+{
+       inet6_unregister_protosw(&rawv6_protosw);
+}
index 76c88a93b9b5a7714678a0ccb28aa140aa4e4998..f936d045a39da9436637421260e41b1613bf82db 100644 (file)
@@ -82,23 +82,16 @@ struct frag_queue
        __u16                   nhoffset;
 };
 
-struct inet_frags_ctl ip6_frags_ctl __read_mostly = {
-       .high_thresh     = 256 * 1024,
-       .low_thresh      = 192 * 1024,
-       .timeout         = IPV6_FRAG_TIMEOUT,
-       .secret_interval = 10 * 60 * HZ,
-};
-
 static struct inet_frags ip6_frags;
 
-int ip6_frag_nqueues(void)
+int ip6_frag_nqueues(struct net *net)
 {
-       return ip6_frags.nqueues;
+       return net->ipv6.frags.nqueues;
 }
 
-int ip6_frag_mem(void)
+int ip6_frag_mem(struct net *net)
 {
-       return atomic_read(&ip6_frags.mem);
+       return atomic_read(&net->ipv6.frags.mem);
 }
 
 static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
@@ -156,11 +149,12 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
 EXPORT_SYMBOL(ip6_frag_match);
 
 /* Memory Tracking Functions. */
-static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
+static inline void frag_kfree_skb(struct netns_frags *nf,
+               struct sk_buff *skb, int *work)
 {
        if (work)
                *work -= skb->truesize;
-       atomic_sub(skb->truesize, &ip6_frags.mem);
+       atomic_sub(skb->truesize, &nf->mem);
        kfree_skb(skb);
 }
 
@@ -190,11 +184,11 @@ static __inline__ void fq_kill(struct frag_queue *fq)
        inet_frag_kill(&fq->q, &ip6_frags);
 }
 
-static void ip6_evictor(struct inet6_dev *idev)
+static void ip6_evictor(struct net *net, struct inet6_dev *idev)
 {
        int evicted;
 
-       evicted = inet_frag_evictor(&ip6_frags);
+       evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
        if (evicted)
                IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted);
 }
@@ -241,7 +235,7 @@ out:
 }
 
 static __inline__ struct frag_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
+fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
        struct inet6_dev *idev)
 {
        struct inet_frag_queue *q;
@@ -253,7 +247,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
        arg.dst = dst;
        hash = ip6qhashfn(id, src, dst);
 
-       q = inet_frag_find(&ip6_frags, &arg, hash);
+       q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
        if (q == NULL)
                goto oom;
 
@@ -396,7 +390,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                                fq->q.fragments = next;
 
                        fq->q.meat -= free_it->len;
-                       frag_kfree_skb(free_it, NULL);
+                       frag_kfree_skb(fq->q.net, free_it, NULL);
                }
        }
 
@@ -416,7 +410,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
        }
        fq->q.stamp = skb->tstamp;
        fq->q.meat += skb->len;
-       atomic_add(skb->truesize, &ip6_frags.mem);
+       atomic_add(skb->truesize, &fq->q.net->mem);
 
        /* The first fragment.
         * nhoffset is obtained from the first fragment, of course.
@@ -430,7 +424,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                return ip6_frag_reasm(fq, prev, dev);
 
        write_lock(&ip6_frags.lock);
-       list_move_tail(&fq->q.lru_list, &ip6_frags.lru_list);
+       list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
        write_unlock(&ip6_frags.lock);
        return -1;
 
@@ -510,7 +504,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
                head->len -= clone->len;
                clone->csum = 0;
                clone->ip_summed = head->ip_summed;
-               atomic_add(clone->truesize, &ip6_frags.mem);
+               atomic_add(clone->truesize, &fq->q.net->mem);
        }
 
        /* We have to remove fragment header from datagram and to relocate
@@ -525,7 +519,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
        skb_shinfo(head)->frag_list = head->next;
        skb_reset_transport_header(head);
        skb_push(head, head->data - skb_network_header(head));
-       atomic_sub(head->truesize, &ip6_frags.mem);
+       atomic_sub(head->truesize, &fq->q.net->mem);
 
        for (fp=head->next; fp; fp = fp->next) {
                head->data_len += fp->len;
@@ -535,7 +529,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
                else if (head->ip_summed == CHECKSUM_COMPLETE)
                        head->csum = csum_add(head->csum, fp->csum);
                head->truesize += fp->truesize;
-               atomic_sub(fp->truesize, &ip6_frags.mem);
+               atomic_sub(fp->truesize, &fq->q.net->mem);
        }
 
        head->next = NULL;
@@ -575,6 +569,7 @@ 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;
 
        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
 
@@ -605,10 +600,11 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                return 1;
        }
 
-       if (atomic_read(&ip6_frags.mem) > ip6_frags_ctl.high_thresh)
-               ip6_evictor(ip6_dst_idev(skb->dst));
+       net = skb->dev->nd_net;
+       if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
+               ip6_evictor(net, ip6_dst_idev(skb->dst));
 
-       if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr,
+       if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
                          ip6_dst_idev(skb->dst))) != NULL) {
                int ret;
 
@@ -632,12 +628,127 @@ static struct inet6_protocol frag_protocol =
        .flags          =       INET6_PROTO_NOPOLICY,
 };
 
-void __init ipv6_frag_init(void)
+#ifdef CONFIG_SYSCTL
+static struct ctl_table ip6_frags_ctl_table[] = {
+       {
+               .ctl_name       = NET_IPV6_IP6FRAG_HIGH_THRESH,
+               .procname       = "ip6frag_high_thresh",
+               .data           = &init_net.ipv6.frags.high_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = NET_IPV6_IP6FRAG_LOW_THRESH,
+               .procname       = "ip6frag_low_thresh",
+               .data           = &init_net.ipv6.frags.low_thresh,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec
+       },
+       {
+               .ctl_name       = NET_IPV6_IP6FRAG_TIME,
+               .procname       = "ip6frag_time",
+               .data           = &init_net.ipv6.frags.timeout,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_jiffies,
+               .strategy       = &sysctl_jiffies,
+       },
+       {
+               .ctl_name       = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
+               .procname       = "ip6frag_secret_interval",
+               .data           = &ip6_frags.secret_interval,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec_jiffies,
+               .strategy       = &sysctl_jiffies
+       },
+       { }
+};
+
+static int ip6_frags_sysctl_register(struct net *net)
 {
-       if (inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT) < 0)
-               printk(KERN_ERR "ipv6_frag_init: Could not register protocol\n");
+       struct ctl_table *table;
+       struct ctl_table_header *hdr;
+
+       table = ip6_frags_ctl_table;
+       if (net != &init_net) {
+               table = kmemdup(table, sizeof(ip6_frags_ctl_table), GFP_KERNEL);
+               if (table == NULL)
+                       goto err_alloc;
+
+               table[0].data = &net->ipv6.frags.high_thresh;
+               table[1].data = &net->ipv6.frags.low_thresh;
+               table[2].data = &net->ipv6.frags.timeout;
+               table[3].mode &= ~0222;
+       }
+
+       hdr = register_net_sysctl_table(net, net_ipv6_ctl_path, table);
+       if (hdr == NULL)
+               goto err_reg;
+
+       net->ipv6.sysctl.frags_hdr = hdr;
+       return 0;
+
+err_reg:
+       if (net != &init_net)
+               kfree(table);
+err_alloc:
+       return -ENOMEM;
+}
+
+static void ip6_frags_sysctl_unregister(struct net *net)
+{
+       struct ctl_table *table;
+
+       table = net->ipv6.sysctl.frags_hdr->ctl_table_arg;
+       unregister_net_sysctl_table(net->ipv6.sysctl.frags_hdr);
+       kfree(table);
+}
+#else
+static inline int ip6_frags_sysctl_register(struct net *net)
+{
+       return 0;
+}
+
+static inline void ip6_frags_sysctl_unregister(struct net *net)
+{
+}
+#endif
+
+static int ipv6_frags_init_net(struct net *net)
+{
+       net->ipv6.frags.high_thresh = 256 * 1024;
+       net->ipv6.frags.low_thresh = 192 * 1024;
+       net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;
+
+       inet_frags_init_net(&net->ipv6.frags);
+
+       return ip6_frags_sysctl_register(net);
+}
+
+static void ipv6_frags_exit_net(struct net *net)
+{
+       ip6_frags_sysctl_unregister(net);
+       inet_frags_exit_net(&net->ipv6.frags, &ip6_frags);
+}
+
+static struct pernet_operations ip6_frags_ops = {
+       .init = ipv6_frags_init_net,
+       .exit = ipv6_frags_exit_net,
+};
+
+int __init ipv6_frag_init(void)
+{
+       int ret;
+
+       ret = inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT);
+       if (ret)
+               goto out;
+
+       register_pernet_subsys(&ip6_frags_ops);
 
-       ip6_frags.ctl = &ip6_frags_ctl;
        ip6_frags.hashfn = ip6_hashfn;
        ip6_frags.constructor = ip6_frag_init;
        ip6_frags.destructor = NULL;
@@ -645,5 +756,15 @@ void __init ipv6_frag_init(void)
        ip6_frags.qsize = sizeof(struct frag_queue);
        ip6_frags.match = ip6_frag_match;
        ip6_frags.frag_expire = ip6_frag_expire;
+       ip6_frags.secret_interval = 10 * 60 * HZ;
        inet_frags_init(&ip6_frags);
+out:
+       return ret;
+}
+
+void ipv6_frag_exit(void)
+{
+       inet_frags_fini(&ip6_frags);
+       unregister_pernet_subsys(&ip6_frags_ops);
+       inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
 }
index 20083e0d3995cf13fcb3c3853b04925c3b2612bc..4004c5f0b8d78eec1ad2ae6fbd2a3494645dac5c 100644 (file)
 
 #define CLONE_OFFLINK_ROUTE 0
 
-static int ip6_rt_max_size = 4096;
-static int ip6_rt_gc_min_interval = HZ / 2;
-static int ip6_rt_gc_timeout = 60*HZ;
-int ip6_rt_gc_interval = 30*HZ;
-static int ip6_rt_gc_elasticity = 9;
-static int ip6_rt_mtu_expires = 10*60*HZ;
-static int ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
-
 static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void            ip6_dst_destroy(struct dst_entry *);
 static void            ip6_dst_ifdown(struct dst_entry *,
                                       struct net_device *dev, int how);
-static int              ip6_dst_gc(void);
+static int              ip6_dst_gc(struct dst_ops *ops);
 
 static int             ip6_pkt_discard(struct sk_buff *skb);
 static int             ip6_pkt_discard_out(struct sk_buff *skb);
@@ -113,6 +105,7 @@ static struct dst_ops ip6_dst_ops = {
        .negative_advice        =       ip6_negative_advice,
        .link_failure           =       ip6_link_failure,
        .update_pmtu            =       ip6_rt_update_pmtu,
+       .local_out              =       ip6_local_out,
        .entry_size             =       sizeof(struct rt6_info),
 };
 
@@ -152,7 +145,6 @@ struct rt6_info ip6_null_entry = {
 
 static int ip6_pkt_prohibit(struct sk_buff *skb);
 static int ip6_pkt_prohibit_out(struct sk_buff *skb);
-static int ip6_pkt_blk_hole(struct sk_buff *skb);
 
 struct rt6_info ip6_prohibit_entry = {
        .u = {
@@ -181,8 +173,8 @@ struct rt6_info ip6_blk_hole_entry = {
                        .obsolete       = -1,
                        .error          = -EINVAL,
                        .metrics        = { [RTAX_HOPLIMIT - 1] = 255, },
-                       .input          = ip6_pkt_blk_hole,
-                       .output         = ip6_pkt_blk_hole,
+                       .input          = dst_discard,
+                       .output         = dst_discard,
                        .ops            = &ip6_dst_ops,
                        .path           = (struct dst_entry*)&ip6_blk_hole_entry,
                }
@@ -216,9 +208,12 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 {
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct inet6_dev *idev = rt->rt6i_idev;
+       struct net_device *loopback_dev =
+               dev->nd_net->loopback_dev;
 
-       if (dev != init_net.loopback_dev && idev != NULL && idev->dev == dev) {
-               struct inet6_dev *loopback_idev = in6_dev_get(init_net.loopback_dev);
+       if (dev != loopback_dev && idev != NULL && idev->dev == dev) {
+               struct inet6_dev *loopback_idev =
+                       in6_dev_get(loopback_dev);
                if (loopback_idev != NULL) {
                        rt->rt6i_idev = loopback_idev;
                        in6_dev_put(idev);
@@ -606,7 +601,10 @@ static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
 
 int ip6_ins_rt(struct rt6_info *rt)
 {
-       return __ip6_ins_rt(rt, NULL);
+       struct nl_info info = {
+               .nl_net = &init_net,
+       };
+       return __ip6_ins_rt(rt, &info);
 }
 
 static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
@@ -782,12 +780,6 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
 
 EXPORT_SYMBOL(ip6_route_output);
 
-static int ip6_blackhole_output(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return 0;
-}
-
 int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl)
 {
        struct rt6_info *ort = (struct rt6_info *) *dstp;
@@ -800,8 +792,8 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl
 
                atomic_set(&new->__refcnt, 1);
                new->__use = 1;
-               new->input = ip6_blackhole_output;
-               new->output = ip6_blackhole_output;
+               new->input = dst_discard;
+               new->output = dst_discard;
 
                memcpy(new->metrics, ort->u.dst.metrics, RTAX_MAX*sizeof(u32));
                new->dev = ort->u.dst.dev;
@@ -896,8 +888,8 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
 {
        mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
 
-       if (mtu < ip6_rt_min_advmss)
-               mtu = ip6_rt_min_advmss;
+       if (mtu < init_net.ipv6.sysctl.ip6_rt_min_advmss)
+               mtu = init_net.ipv6.sysctl.ip6_rt_min_advmss;
 
        /*
         * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and
@@ -991,25 +983,25 @@ int ndisc_dst_gc(int *more)
        return freed;
 }
 
-static int ip6_dst_gc(void)
+static int ip6_dst_gc(struct dst_ops *ops)
 {
        static unsigned expire = 30*HZ;
        static unsigned long last_gc;
        unsigned long now = jiffies;
 
-       if (time_after(last_gc + ip6_rt_gc_min_interval, now) &&
-           atomic_read(&ip6_dst_ops.entries) <= ip6_rt_max_size)
+       if (time_after(last_gc + init_net.ipv6.sysctl.ip6_rt_gc_min_interval, now) &&
+           atomic_read(&ip6_dst_ops.entries) <= init_net.ipv6.sysctl.ip6_rt_max_size)
                goto out;
 
        expire++;
        fib6_run_gc(expire);
        last_gc = now;
        if (atomic_read(&ip6_dst_ops.entries) < ip6_dst_ops.gc_thresh)
-               expire = ip6_rt_gc_timeout>>1;
+               expire = init_net.ipv6.sysctl.ip6_rt_gc_timeout>>1;
 
 out:
-       expire -= expire>>ip6_rt_gc_elasticity;
-       return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size);
+       expire -= expire>>init_net.ipv6.sysctl.ip6_rt_gc_elasticity;
+       return (atomic_read(&ip6_dst_ops.entries) > init_net.ipv6.sysctl.ip6_rt_max_size);
 }
 
 /* Clean host part of a prefix. Not necessary in radix tree,
@@ -1269,7 +1261,10 @@ static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
 
 int ip6_del_rt(struct rt6_info *rt)
 {
-       return __ip6_del_rt(rt, NULL);
+       struct nl_info info = {
+               .nl_net = &init_net,
+       };
+       return __ip6_del_rt(rt, &info);
 }
 
 static int ip6_route_del(struct fib6_config *cfg)
@@ -1514,7 +1509,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
                rt->u.dst.metrics[RTAX_MTU-1] = pmtu;
                if (allfrag)
                        rt->u.dst.metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG;
-               dst_set_expires(&rt->u.dst, ip6_rt_mtu_expires);
+               dst_set_expires(&rt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
                rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES;
                goto out;
        }
@@ -1540,7 +1535,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
                 * which is 10 mins. After 10 mins the decreased pmtu is expired
                 * and detecting PMTU increase will be automatically happened.
                 */
-               dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
+               dst_set_expires(&nrt->u.dst, init_net.ipv6.sysctl.ip6_rt_mtu_expires);
                nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
 
                ip6_ins_rt(nrt);
@@ -1665,6 +1660,8 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
        return rt;
 }
 
+EXPORT_SYMBOL(rt6_get_dflt_router);
+
 struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
                                     struct net_device *dev,
                                     unsigned int pref)
@@ -1766,8 +1763,7 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
  *     Drop the packet on the floor
  */
 
-static inline int ip6_pkt_drop(struct sk_buff *skb, int code,
-                              int ipstats_mib_noroutes)
+static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes)
 {
        int type;
        switch (ipstats_mib_noroutes) {
@@ -1811,12 +1807,6 @@ static int ip6_pkt_prohibit_out(struct sk_buff *skb)
        return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 }
 
-static int ip6_pkt_blk_hole(struct sk_buff *skb)
-{
-       kfree_skb(skb);
-       return 0;
-}
-
 #endif
 
 /*
@@ -2015,9 +2005,13 @@ errout:
 
 static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib6_config cfg;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = rtm_to_fib6_config(skb, nlh, &cfg);
        if (err < 0)
                return err;
@@ -2027,9 +2021,13 @@ static int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
 
 static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct fib6_config cfg;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = rtm_to_fib6_config(skb, nlh, &cfg);
        if (err < 0)
                return err;
@@ -2164,6 +2162,7 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
 
 static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
 {
+       struct net *net = in_skb->sk->sk_net;
        struct nlattr *tb[RTA_MAX+1];
        struct rt6_info *rt;
        struct sk_buff *skb;
@@ -2171,6 +2170,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        struct flowi fl;
        int err, iif = 0;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
        if (err < 0)
                goto errout;
@@ -2230,7 +2232,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
                goto errout;
        }
 
-       err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+       err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
 errout:
        return err;
 }
@@ -2238,32 +2240,29 @@ errout:
 void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
 {
        struct sk_buff *skb;
-       u32 pid = 0, seq = 0;
-       struct nlmsghdr *nlh = NULL;
-       int err = -ENOBUFS;
-
-       if (info) {
-               pid = info->pid;
-               nlh = info->nlh;
-               if (nlh)
-                       seq = nlh->nlmsg_seq;
-       }
+       u32 seq;
+       int err;
+
+       err = -ENOBUFS;
+       seq = info->nlh != NULL ? info->nlh->nlmsg_seq : 0;
 
        skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
        if (skb == NULL)
                goto errout;
 
-       err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
+       err = rt6_fill_node(skb, rt, NULL, NULL, 0,
+                               event, info->pid, seq, 0, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
                WARN_ON(err == -EMSGSIZE);
                kfree_skb(skb);
                goto errout;
        }
-       err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
+       err = rtnl_notify(skb, &init_net, info->pid,
+                               RTNLGRP_IPV6_ROUTE, info->nlh, gfp_any());
 errout:
        if (err < 0)
-               rtnl_set_sk_err(RTNLGRP_IPV6_ROUTE, err);
+               rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_ROUTE, err);
 }
 
 /*
@@ -2353,28 +2352,61 @@ static const struct file_operations rt6_stats_seq_fops = {
        .llseek  = seq_lseek,
        .release = single_release,
 };
+
+static int ipv6_route_proc_init(struct net *net)
+{
+       int ret = -ENOMEM;
+       if (!proc_net_fops_create(net, "ipv6_route",
+                                 0, &ipv6_route_proc_fops))
+               goto out;
+
+       if (!proc_net_fops_create(net, "rt6_stats",
+                                 S_IRUGO, &rt6_stats_seq_fops))
+               goto out_ipv6_route;
+
+       ret = 0;
+out:
+       return ret;
+out_ipv6_route:
+       proc_net_remove(net, "ipv6_route");
+       goto out;
+}
+
+static void ipv6_route_proc_fini(struct net *net)
+{
+       proc_net_remove(net, "ipv6_route");
+       proc_net_remove(net, "rt6_stats");
+}
+#else
+static inline int ipv6_route_proc_init(struct net *net)
+{
+       return 0;
+}
+static inline void ipv6_route_proc_fini(struct net *net)
+{
+       return ;
+}
 #endif /* CONFIG_PROC_FS */
 
 #ifdef CONFIG_SYSCTL
 
-static int flush_delay;
-
 static
 int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp,
                              void __user *buffer, size_t *lenp, loff_t *ppos)
 {
+       int delay = init_net.ipv6.sysctl.flush_delay;
        if (write) {
                proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
-               fib6_run_gc(flush_delay <= 0 ? ~0UL : (unsigned long)flush_delay);
+               fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay);
                return 0;
        } else
                return -EINVAL;
 }
 
-ctl_table ipv6_route_table[] = {
+ctl_table ipv6_route_table_template[] = {
        {
                .procname       =       "flush",
-               .data           =       &flush_delay,
+               .data           =       &init_net.ipv6.sysctl.flush_delay,
                .maxlen         =       sizeof(int),
                .mode           =       0200,
                .proc_handler   =       &ipv6_sysctl_rtcache_flush
@@ -2390,7 +2422,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MAX_SIZE,
                .procname       =       "max_size",
-               .data           =       &ip6_rt_max_size,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_max_size,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec,
@@ -2398,7 +2430,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL,
                .procname       =       "gc_min_interval",
-               .data           =       &ip6_rt_gc_min_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2407,7 +2439,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_TIMEOUT,
                .procname       =       "gc_timeout",
-               .data           =       &ip6_rt_gc_timeout,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_timeout,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2416,7 +2448,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_INTERVAL,
                .procname       =       "gc_interval",
-               .data           =       &ip6_rt_gc_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2425,7 +2457,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_ELASTICITY,
                .procname       =       "gc_elasticity",
-               .data           =       &ip6_rt_gc_elasticity,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_elasticity,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2434,7 +2466,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MTU_EXPIRES,
                .procname       =       "mtu_expires",
-               .data           =       &ip6_rt_mtu_expires,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_mtu_expires,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2443,7 +2475,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_MIN_ADVMSS,
                .procname       =       "min_adv_mss",
-               .data           =       &ip6_rt_min_advmss,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_min_advmss,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_jiffies,
@@ -2452,7 +2484,7 @@ ctl_table ipv6_route_table[] = {
        {
                .ctl_name       =       NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS,
                .procname       =       "gc_min_interval_ms",
-               .data           =       &ip6_rt_gc_min_interval,
+               .data           =       &init_net.ipv6.sysctl.ip6_rt_gc_min_interval,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
                .proc_handler   =       &proc_dointvec_ms_jiffies,
@@ -2461,42 +2493,74 @@ ctl_table ipv6_route_table[] = {
        { .ctl_name = 0 }
 };
 
+struct ctl_table *ipv6_route_sysctl_init(struct net *net)
+{
+       struct ctl_table *table;
+
+       table = kmemdup(ipv6_route_table_template,
+                       sizeof(ipv6_route_table_template),
+                       GFP_KERNEL);
+       return table;
+}
 #endif
 
-void __init ip6_route_init(void)
+int __init ip6_route_init(void)
 {
+       int ret;
+
        ip6_dst_ops.kmem_cachep =
                kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
-                                 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
+                                 SLAB_HWCACHE_ALIGN, NULL);
+       if (!ip6_dst_ops.kmem_cachep)
+               return -ENOMEM;
+
        ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops.kmem_cachep;
 
-       fib6_init();
-       proc_net_fops_create(&init_net, "ipv6_route", 0, &ipv6_route_proc_fops);
-       proc_net_fops_create(&init_net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
-#ifdef CONFIG_XFRM
-       xfrm6_init();
-#endif
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
-       fib6_rules_init();
-#endif
+       ret = fib6_init();
+       if (ret)
+               goto out_kmem_cache;
 
-       __rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL);
-       __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL);
-       __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL);
+       ret = ipv6_route_proc_init(&init_net);
+       if (ret)
+               goto out_fib6_init;
+
+       ret = xfrm6_init();
+       if (ret)
+               goto out_proc_init;
+
+       ret = fib6_rules_init();
+       if (ret)
+               goto xfrm6_init;
+
+       ret = -ENOBUFS;
+       if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL) ||
+           __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL) ||
+           __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL))
+               goto fib6_rules_init;
+
+       ret = 0;
+out:
+       return ret;
+
+fib6_rules_init:
+       fib6_rules_cleanup();
+xfrm6_init:
+       xfrm6_fini();
+out_proc_init:
+       ipv6_route_proc_fini(&init_net);
+out_fib6_init:
+       rt6_ifdown(NULL);
+       fib6_gc_cleanup();
+out_kmem_cache:
+       kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
+       goto out;
 }
 
 void ip6_route_cleanup(void)
 {
-#ifdef CONFIG_IPV6_MULTIPLE_TABLES
        fib6_rules_cleanup();
-#endif
-#ifdef CONFIG_PROC_FS
-       proc_net_remove(&init_net, "ipv6_route");
-       proc_net_remove(&init_net, "rt6_stats");
-#endif
-#ifdef CONFIG_XFRM
+       ipv6_route_proc_fini(&init_net);
        xfrm6_fini();
-#endif
        rt6_ifdown(NULL);
        fib6_gc_cleanup();
        kmem_cache_destroy(ip6_dst_ops.kmem_cachep);
index 71433d29d8846e162f0be47bf200768958bb9a44..e77239d02bf5323e014e8757f459c2505898431b 100644 (file)
@@ -16,6 +16,7 @@
  *     Changes:
  * Roger Venning <r.venning@telstra.com>:      6to4 support
  * Nate Thompson <nate@thebog.net>:            6to4 support
+ * Fred L. Templin <fltemplin@acm.org>:                isatap support
  */
 
 #include <linux/module.h>
@@ -182,6 +183,9 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int
        dev->init = ipip6_tunnel_init;
        nt->parms = *parms;
 
+       if (parms->i_flags & SIT_ISATAP)
+               dev->priv_flags |= IFF_ISATAP;
+
        if (register_netdevice(dev) < 0) {
                free_netdev(dev);
                goto failed;
@@ -364,6 +368,48 @@ static inline void ipip6_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
                IP6_ECN_set_ce(ipv6_hdr(skb));
 }
 
+/* ISATAP (RFC4214) - check source address */
+static int
+isatap_srcok(struct sk_buff *skb, struct iphdr *iph, struct net_device *dev)
+{
+       struct neighbour *neigh;
+       struct dst_entry *dst;
+       struct rt6_info *rt;
+       struct flowi fl;
+       struct in6_addr *addr6;
+       struct in6_addr rtr;
+       struct ipv6hdr *iph6;
+       int ok = 0;
+
+       /* from onlink default router */
+       ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+       ipv6_isatap_eui64(rtr.s6_addr + 8, iph->saddr);
+       if ((rt = rt6_get_dflt_router(&rtr, dev))) {
+               dst_release(&rt->u.dst);
+               return 1;
+       }
+
+       iph6 = ipv6_hdr(skb);
+       memset(&fl, 0, sizeof(fl));
+       fl.proto = iph6->nexthdr;
+       ipv6_addr_copy(&fl.fl6_dst, &iph6->saddr);
+       fl.oif = dev->ifindex;
+       security_skb_classify_flow(skb, &fl);
+
+       dst = ip6_route_output(NULL, &fl);
+       if (!dst->error && (dst->dev == dev) && (neigh = dst->neighbour)) {
+
+               addr6 = (struct in6_addr*)&neigh->primary_key;
+
+               /* from correct previous hop */
+               if (ipv6_addr_is_isatap(addr6) &&
+                   (addr6->s6_addr32[3] == iph->saddr))
+                       ok = 1;
+       }
+       dst_release(dst);
+       return ok;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
        struct iphdr *iph;
@@ -382,6 +428,14 @@ static int ipip6_rcv(struct sk_buff *skb)
                IPCB(skb)->flags = 0;
                skb->protocol = htons(ETH_P_IPV6);
                skb->pkt_type = PACKET_HOST;
+
+               if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
+                   !isatap_srcok(skb, iph, tunnel->dev)) {
+                       tunnel->stat.rx_errors++;
+                       read_unlock(&ipip6_lock);
+                       kfree_skb(skb);
+                       return 0;
+               }
                tunnel->stat.rx_packets++;
                tunnel->stat.rx_bytes += skb->len;
                skb->dev = tunnel->dev;
@@ -444,6 +498,29 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (skb->protocol != htons(ETH_P_IPV6))
                goto tx_error;
 
+       /* ISATAP (RFC4214) - must come before 6to4 */
+       if (dev->priv_flags & IFF_ISATAP) {
+               struct neighbour *neigh = NULL;
+
+               if (skb->dst)
+                       neigh = skb->dst->neighbour;
+
+               if (neigh == NULL) {
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "sit: nexthop == NULL\n");
+                       goto tx_error;
+               }
+
+               addr6 = (struct in6_addr*)&neigh->primary_key;
+               addr_type = ipv6_addr_type(addr6);
+
+               if ((addr_type & IPV6_ADDR_UNICAST) &&
+                    ipv6_addr_is_isatap(addr6))
+                       dst = addr6->s6_addr32[3];
+               else
+                       goto tx_error;
+       }
+
        if (!dst)
                dst = try_6to4(&iph6->daddr);
 
@@ -480,7 +557,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                                                .tos = RT_TOS(tos) } },
                                    .oif = tunnel->parms.link,
                                    .proto = IPPROTO_IPV6 };
-               if (ip_route_output_key(&rt, &fl)) {
+               if (ip_route_output_key(&init_net, &rt, &fl)) {
                        tunnel->stat.tx_carrier_errors++;
                        goto tx_error_icmp;
                }
@@ -592,6 +669,42 @@ tx_error:
        return 0;
 }
 
+static void ipip6_tunnel_bind_dev(struct net_device *dev)
+{
+       struct net_device *tdev = NULL;
+       struct ip_tunnel *tunnel;
+       struct iphdr *iph;
+
+       tunnel = netdev_priv(dev);
+       iph = &tunnel->parms.iph;
+
+       if (iph->daddr) {
+               struct flowi fl = { .nl_u = { .ip4_u =
+                                             { .daddr = iph->daddr,
+                                               .saddr = iph->saddr,
+                                               .tos = RT_TOS(iph->tos) } },
+                                   .oif = tunnel->parms.link,
+                                   .proto = IPPROTO_IPV6 };
+               struct rtable *rt;
+               if (!ip_route_output_key(&init_net, &rt, &fl)) {
+                       tdev = rt->u.dst.dev;
+                       ip_rt_put(rt);
+               }
+               dev->flags |= IFF_POINTOPOINT;
+       }
+
+       if (!tdev && tunnel->parms.link)
+               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
+
+       if (tdev) {
+               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
+               dev->mtu = tdev->mtu - sizeof(struct iphdr);
+               if (dev->mtu < IPV6_MIN_MTU)
+                       dev->mtu = IPV6_MIN_MTU;
+       }
+       dev->iflink = tunnel->parms.link;
+}
+
 static int
 ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -663,6 +776,11 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
                        if (cmd == SIOCCHGTUNNEL) {
                                t->parms.iph.ttl = p.iph.ttl;
                                t->parms.iph.tos = p.iph.tos;
+                               if (t->parms.link != p.link) {
+                                       t->parms.link = p.link;
+                                       ipip6_tunnel_bind_dev(dev);
+                                       netdev_state_change(dev);
+                               }
                        }
                        if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof(p)))
                                err = -EFAULT;
@@ -731,12 +849,9 @@ static void ipip6_tunnel_setup(struct net_device *dev)
 
 static int ipip6_tunnel_init(struct net_device *dev)
 {
-       struct net_device *tdev = NULL;
        struct ip_tunnel *tunnel;
-       struct iphdr *iph;
 
        tunnel = netdev_priv(dev);
-       iph = &tunnel->parms.iph;
 
        tunnel->dev = dev;
        strcpy(tunnel->parms.name, dev->name);
@@ -744,31 +859,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
        memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
        memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
 
-       if (iph->daddr) {
-               struct flowi fl = { .nl_u = { .ip4_u =
-                                             { .daddr = iph->daddr,
-                                               .saddr = iph->saddr,
-                                               .tos = RT_TOS(iph->tos) } },
-                                   .oif = tunnel->parms.link,
-                                   .proto = IPPROTO_IPV6 };
-               struct rtable *rt;
-               if (!ip_route_output_key(&rt, &fl)) {
-                       tdev = rt->u.dst.dev;
-                       ip_rt_put(rt);
-               }
-               dev->flags |= IFF_POINTOPOINT;
-       }
-
-       if (!tdev && tunnel->parms.link)
-               tdev = __dev_get_by_index(&init_net, tunnel->parms.link);
-
-       if (tdev) {
-               dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
-               dev->mtu = tdev->mtu - sizeof(struct iphdr);
-               if (dev->mtu < IPV6_MIN_MTU)
-                       dev->mtu = IPV6_MIN_MTU;
-       }
-       dev->iflink = tunnel->parms.link;
+       ipip6_tunnel_bind_dev(dev);
 
        return 0;
 }
index 68bb2548e469841ef139f79b7219f679e03179bc..408691b777c226c2d0468137d5839cd658f8523d 100644 (file)
 #include <net/addrconf.h>
 #include <net/inet_frag.h>
 
-#ifdef CONFIG_SYSCTL
-
-static ctl_table ipv6_table[] = {
+static ctl_table ipv6_table_template[] = {
        {
                .ctl_name       = NET_IPV6_ROUTE,
                .procname       = "route",
                .maxlen         = 0,
                .mode           = 0555,
-               .child          = ipv6_route_table
+               .child          = ipv6_route_table_template
        },
        {
                .ctl_name       = NET_IPV6_ICMP,
                .procname       = "icmp",
                .maxlen         = 0,
                .mode           = 0555,
-               .child          = ipv6_icmp_table
+               .child          = ipv6_icmp_table_template
        },
        {
                .ctl_name       = NET_IPV6_BINDV6ONLY,
                .procname       = "bindv6only",
-               .data           = &sysctl_ipv6_bindv6only,
+               .data           = &init_net.ipv6.sysctl.bindv6only,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
        },
-       {
-               .ctl_name       = NET_IPV6_IP6FRAG_HIGH_THRESH,
-               .procname       = "ip6frag_high_thresh",
-               .data           = &ip6_frags_ctl.high_thresh,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
-       {
-               .ctl_name       = NET_IPV6_IP6FRAG_LOW_THRESH,
-               .procname       = "ip6frag_low_thresh",
-               .data           = &ip6_frags_ctl.low_thresh,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec
-       },
-       {
-               .ctl_name       = NET_IPV6_IP6FRAG_TIME,
-               .procname       = "ip6frag_time",
-               .data           = &ip6_frags_ctl.timeout,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
-       },
-       {
-               .ctl_name       = NET_IPV6_IP6FRAG_SECRET_INTERVAL,
-               .procname       = "ip6frag_secret_interval",
-               .data           = &ip6_frags_ctl.secret_interval,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies
-       },
        {
                .ctl_name       = NET_IPV6_MLD_MAX_MSF,
                .procname       = "mld_max_msf",
@@ -84,39 +48,106 @@ static ctl_table ipv6_table[] = {
        { .ctl_name = 0 }
 };
 
-static struct ctl_table_header *ipv6_sysctl_header;
-
-static ctl_table ipv6_net_table[] = {
-       {
-               .ctl_name       = NET_IPV6,
-               .procname       = "ipv6",
-               .mode           = 0555,
-               .child          = ipv6_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table ipv6_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipv6_net_table
-       },
-       { .ctl_name = 0 }
+struct ctl_path net_ipv6_ctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipv6", .ctl_name = NET_IPV6, },
+       { },
 };
+EXPORT_SYMBOL_GPL(net_ipv6_ctl_path);
 
-void ipv6_sysctl_register(void)
+static int ipv6_sysctl_net_init(struct net *net)
 {
-       ipv6_sysctl_header = register_sysctl_table(ipv6_root_table);
+       struct ctl_table *ipv6_table;
+       struct ctl_table *ipv6_route_table;
+       struct ctl_table *ipv6_icmp_table;
+       int err;
+
+       err = -ENOMEM;
+       ipv6_table = kmemdup(ipv6_table_template, sizeof(ipv6_table_template),
+                            GFP_KERNEL);
+       if (!ipv6_table)
+               goto out;
+
+       ipv6_route_table = ipv6_route_sysctl_init(net);
+       if (!ipv6_route_table)
+               goto out_ipv6_table;
+
+       ipv6_icmp_table = ipv6_icmp_sysctl_init(net);
+       if (!ipv6_icmp_table)
+               goto out_ipv6_route_table;
+
+       ipv6_route_table[0].data = &net->ipv6.sysctl.flush_delay;
+       /* ipv6_route_table[1].data will be handled when we have
+          routes per namespace */
+       ipv6_route_table[2].data = &net->ipv6.sysctl.ip6_rt_max_size;
+       ipv6_route_table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval;
+       ipv6_route_table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout;
+       ipv6_route_table[5].data = &net->ipv6.sysctl.ip6_rt_gc_interval;
+       ipv6_route_table[6].data = &net->ipv6.sysctl.ip6_rt_gc_elasticity;
+       ipv6_route_table[7].data = &net->ipv6.sysctl.ip6_rt_mtu_expires;
+       ipv6_route_table[8].data = &net->ipv6.sysctl.ip6_rt_min_advmss;
+       ipv6_table[0].child = ipv6_route_table;
+
+       ipv6_icmp_table[0].data = &net->ipv6.sysctl.icmpv6_time;
+       ipv6_table[1].child = ipv6_icmp_table;
+
+       ipv6_table[2].data = &net->ipv6.sysctl.bindv6only;
+
+       /* We don't want this value to be per namespace, it should be global
+          to all namespaces, so make it read-only when we are not in the
+          init network namespace */
+       if (net != &init_net)
+               ipv6_table[3].mode = 0444;
+
+       net->ipv6.sysctl.table = register_net_sysctl_table(net, net_ipv6_ctl_path,
+                                                          ipv6_table);
+       if (!net->ipv6.sysctl.table)
+               return -ENOMEM;
+
+       if (!net->ipv6.sysctl.table)
+               goto out_ipv6_icmp_table;
+
+       err = 0;
+out:
+       return err;
+
+out_ipv6_icmp_table:
+       kfree(ipv6_icmp_table);
+out_ipv6_route_table:
+       kfree(ipv6_route_table);
+out_ipv6_table:
+       kfree(ipv6_table);
+       goto out;
 }
 
-void ipv6_sysctl_unregister(void)
+static void ipv6_sysctl_net_exit(struct net *net)
 {
-       unregister_sysctl_table(ipv6_sysctl_header);
-}
+       struct ctl_table *ipv6_table;
+       struct ctl_table *ipv6_route_table;
+       struct ctl_table *ipv6_icmp_table;
 
-#endif /* CONFIG_SYSCTL */
+       ipv6_table = net->ipv6.sysctl.table->ctl_table_arg;
+       ipv6_route_table = ipv6_table[0].child;
+       ipv6_icmp_table = ipv6_table[1].child;
 
+       unregister_net_sysctl_table(net->ipv6.sysctl.table);
 
+       kfree(ipv6_table);
+       kfree(ipv6_route_table);
+       kfree(ipv6_icmp_table);
+}
+
+static struct pernet_operations ipv6_sysctl_net_ops = {
+       .init = ipv6_sysctl_net_init,
+       .exit = ipv6_sysctl_net_exit,
+};
 
+int ipv6_sysctl_register(void)
+{
+       return register_pernet_subsys(&ipv6_sysctl_net_ops);
+}
+
+void ipv6_sysctl_unregister(void)
+{
+       unregister_pernet_subsys(&ipv6_sysctl_net_ops);
+}
index 93980c3b83e694460fe42ab4ed74e91f47649d2f..00c08399837d00e31d91b26906392367a2bc3a26 100644 (file)
@@ -265,7 +265,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -733,7 +733,7 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                   struct in6_addr *saddr,
                                   struct in6_addr *daddr,
                                   struct tcphdr *th, int protocol,
-                                  int tcplen)
+                                  unsigned int tcplen)
 {
        struct scatterlist sg[4];
        __u16 data_len;
@@ -818,7 +818,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
                                struct dst_entry *dst,
                                struct request_sock *req,
                                struct tcphdr *th, int protocol,
-                               int tcplen)
+                               unsigned int tcplen)
 {
        struct in6_addr *saddr, *daddr;
 
@@ -985,7 +985,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       int tot_len = sizeof(*th);
+       unsigned int tot_len = sizeof(*th);
 #ifdef CONFIG_TCP_MD5SIG
        struct tcp_md5sig_key *key;
 #endif
@@ -1085,7 +1085,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       int tot_len = sizeof(struct tcphdr);
+       unsigned int tot_len = sizeof(struct tcphdr);
        __be32 *topt;
 #ifdef CONFIG_TCP_MD5SIG
        struct tcp_md5sig_key *key;
@@ -2166,14 +2166,36 @@ static struct inet_protosw tcpv6_protosw = {
                                INET_PROTOSW_ICSK,
 };
 
-void __init tcpv6_init(void)
+int __init tcpv6_init(void)
 {
+       int ret;
+
+       ret = inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP);
+       if (ret)
+               goto out;
+
        /* register inet6 protocol */
-       if (inet6_add_protocol(&tcpv6_protocol, IPPROTO_TCP) < 0)
-               printk(KERN_ERR "tcpv6_init: Could not register protocol\n");
-       inet6_register_protosw(&tcpv6_protosw);
+       ret = inet6_register_protosw(&tcpv6_protosw);
+       if (ret)
+               goto out_tcpv6_protocol;
+
+       ret = inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6,
+                                      SOCK_RAW, IPPROTO_TCP);
+       if (ret)
+               goto out_tcpv6_protosw;
+out:
+       return ret;
 
-       if (inet_csk_ctl_sock_create(&tcp6_socket, PF_INET6, SOCK_RAW,
-                                    IPPROTO_TCP) < 0)
-               panic("Failed to create the TCPv6 control socket.\n");
+out_tcpv6_protocol:
+       inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
+out_tcpv6_protosw:
+       inet6_unregister_protosw(&tcpv6_protosw);
+       goto out;
+}
+
+void tcpv6_exit(void)
+{
+       sock_release(tcp6_socket);
+       inet6_unregister_protosw(&tcpv6_protosw);
+       inet6_del_protocol(&tcpv6_protocol, IPPROTO_TCP);
 }
index ee1cc3f8599fd110bca8e77e38e2e9f50b607402..bd4b9df8f614018322c6b9176f136d30db3dafac 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 
@@ -50,8 +51,6 @@
 #include <linux/seq_file.h>
 #include "udp_impl.h"
 
-DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
-
 static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
 {
        return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
@@ -121,6 +120,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
        struct inet_sock *inet = inet_sk(sk);
        struct sk_buff *skb;
        unsigned int ulen, copied;
+       int peeked;
        int err;
        int is_udplite = IS_UDPLITE(sk);
 
@@ -131,7 +131,8 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
                return ipv6_recv_error(sk, msg, len);
 
 try_again:
-       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+                                 &peeked, &err);
        if (!skb)
                goto out;
 
@@ -164,6 +165,9 @@ try_again:
        if (err)
                goto out_free;
 
+       if (!peeked)
+               UDP6_INC_STATS_USER(UDP_MIB_INDATAGRAMS, is_udplite);
+
        sock_recv_timestamp(msg, sk, skb);
 
        /* Copy the address. */
@@ -200,13 +204,17 @@ try_again:
                err = ulen;
 
 out_free:
+       lock_sock(sk);
        skb_free_datagram(sk, skb);
+       release_sock(sk);
 out:
        return err;
 
 csum_copy_err:
-       UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
-       skb_kill_datagram(sk, skb, flags);
+       lock_sock(sk);
+       if (!skb_kill_datagram(sk, skb, flags))
+               UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
+       release_sock(sk);
 
        if (flags & MSG_DONTWAIT)
                return -EAGAIN;
@@ -251,13 +259,14 @@ static __inline__ void udpv6_err(struct sk_buff *skb,
                                 struct inet6_skb_parm *opt, int type,
                                 int code, int offset, __be32 info     )
 {
-       return __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash);
+       __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash);
 }
 
 int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
        struct udp_sock *up = udp_sk(sk);
        int rc;
+       int is_udplite = IS_UDPLITE(sk);
 
        if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
                goto drop;
@@ -265,7 +274,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        /*
         * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
         */
-       if ((up->pcflag & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
+       if ((is_udplite & UDPLITE_RECV_CC)  &&  UDP_SKB_CB(skb)->partial_cov) {
 
                if (up->pcrlen == 0) {          /* full coverage was set  */
                        LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: partial coverage"
@@ -289,13 +298,13 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
        if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
                /* Note that an ENOMEM error is charged twice */
                if (rc == -ENOMEM)
-                       UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, up->pcflag);
+                       UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
                goto drop;
        }
-       UDP6_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
+
        return 0;
 drop:
-       UDP6_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
+       UDP6_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
        kfree_skb(skb);
        return -1;
 }
@@ -361,10 +370,21 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
        while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr,
                                        uh->source, saddr, dif))) {
                struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
-               if (buff)
-                       udpv6_queue_rcv_skb(sk2, buff);
+               if (buff) {
+                       bh_lock_sock_nested(sk2);
+                       if (!sock_owned_by_user(sk2))
+                               udpv6_queue_rcv_skb(sk2, buff);
+                       else
+                               sk_add_backlog(sk2, buff);
+                       bh_unlock_sock(sk2);
+               }
        }
-       udpv6_queue_rcv_skb(sk, skb);
+       bh_lock_sock_nested(sk);
+       if (!sock_owned_by_user(sk))
+               udpv6_queue_rcv_skb(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
 out:
        read_unlock(&udp_hash_lock);
        return 0;
@@ -477,7 +497,12 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
 
        /* deliver */
 
-       udpv6_queue_rcv_skb(sk, skb);
+       bh_lock_sock_nested(sk);
+       if (!sock_owned_by_user(sk))
+               udpv6_queue_rcv_skb(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
        sock_put(sk);
        return 0;
 
@@ -523,6 +548,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
        struct inet_sock *inet = inet_sk(sk);
        struct flowi *fl = &inet->cork.fl;
        int err = 0;
+       int is_udplite = IS_UDPLITE(sk);
        __wsum csum = 0;
 
        /* Grab the skbuff where UDP header space exists. */
@@ -538,7 +564,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
        uh->len = htons(up->len);
        uh->check = 0;
 
-       if (up->pcflag)
+       if (is_udplite)
                csum = udplite_csum_outgoing(sk, skb);
         else
                csum = udp_csum_outgoing(sk, skb);
@@ -554,7 +580,7 @@ out:
        up->len = 0;
        up->pending = 0;
        if (!err)
-               UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, up->pcflag);
+               UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
        return err;
 }
 
@@ -578,7 +604,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
        int err;
        int connected = 0;
-       int is_udplite = up->pcflag;
+       int is_udplite = IS_UDPLITE(sk);
        int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
 
        /* destination address check */
@@ -748,7 +774,7 @@ do_udp_sendmsg:
        if (final_p)
                ipv6_addr_copy(&fl.fl6_dst, final_p);
 
-       if ((err = __xfrm_lookup(&dst, &fl, sk, 1)) < 0) {
+       if ((err = __xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_WAIT)) < 0) {
                if (err == -EREMOTE)
                        err = ip6_dst_blackhole(sk, &dst, &fl);
                if (err < 0)
@@ -988,6 +1014,10 @@ struct proto udpv6_prot = {
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v6_get_port,
+       .memory_allocated  = &udp_memory_allocated,
+       .sysctl_mem        = sysctl_udp_mem,
+       .sysctl_wmem       = &sysctl_udp_wmem_min,
+       .sysctl_rmem       = &sysctl_udp_rmem_min,
        .obj_size          = sizeof(struct udp6_sock),
 #ifdef CONFIG_COMPAT
        .compat_setsockopt = compat_udpv6_setsockopt,
@@ -1007,9 +1037,27 @@ static struct inet_protosw udpv6_protosw = {
 };
 
 
-void __init udpv6_init(void)
+int __init udpv6_init(void)
+{
+       int ret;
+
+       ret = inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP);
+       if (ret)
+               goto out;
+
+       ret = inet6_register_protosw(&udpv6_protosw);
+       if (ret)
+               goto out_udpv6_protocol;
+out:
+       return ret;
+
+out_udpv6_protocol:
+       inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP);
+       goto out;
+}
+
+void udpv6_exit(void)
 {
-       if (inet6_add_protocol(&udpv6_protocol, IPPROTO_UDP) < 0)
-               printk(KERN_ERR "udpv6_init: Could not register protocol\n");
-       inet6_register_protosw(&udpv6_protosw);
+       inet6_unregister_protosw(&udpv6_protosw);
+       inet6_del_protocol(&udpv6_protocol, IPPROTO_UDP);
 }
index 2d3fda6012326e81dcc1acf3fe43414b5986580e..21be3a83e7bc4613a1959c12d17e469f82893a89 100644 (file)
@@ -5,6 +5,7 @@
 #include <net/protocol.h>
 #include <net/addrconf.h>
 #include <net/inet_common.h>
+#include <net/transp_v6.h>
 
 extern int     __udp6_lib_rcv(struct sk_buff *, struct hlist_head [], int );
 extern void    __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
index 5a0379f7141515f2ddc1841959ecde05f8a3ee66..87d4202522ee167400f6ee2121c407c68315a91c 100644 (file)
@@ -26,7 +26,7 @@ static void udplitev6_err(struct sk_buff *skb,
                          struct inet6_skb_parm *opt,
                          int type, int code, int offset, __be32 info)
 {
-       return __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash);
+       __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash);
 }
 
 static struct inet6_protocol udplitev6_protocol = {
@@ -77,12 +77,29 @@ static struct inet_protosw udplite6_protosw = {
        .flags          = INET_PROTOSW_PERMANENT,
 };
 
-void __init udplitev6_init(void)
+int __init udplitev6_init(void)
 {
-       if (inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE) < 0)
-               printk(KERN_ERR "%s: Could not register.\n", __FUNCTION__);
+       int ret;
 
-       inet6_register_protosw(&udplite6_protosw);
+       ret = inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
+       if (ret)
+               goto out;
+
+       ret = inet6_register_protosw(&udplite6_protosw);
+       if (ret)
+               goto out_udplitev6_protocol;
+out:
+       return ret;
+
+out_udplitev6_protocol:
+       inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
+       goto out;
+}
+
+void udplitev6_exit(void)
+{
+       inet6_unregister_protosw(&udplite6_protosw);
+       inet6_del_protocol(&udplitev6_protocol, IPPROTO_UDPLITE);
 }
 
 #ifdef CONFIG_PROC_FS
index 515783707e86b0338d003dab53fe9b2310652aa3..a4714d76ae6bd72e0a1379a70aa8153e0653eb46 100644 (file)
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
-int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+int xfrm6_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 {
-       int err;
-       __be32 seq;
-       struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];
-       struct xfrm_state *x;
-       int xfrm_nr = 0;
-       int decaps = 0;
-       unsigned int nhoff;
-
-       nhoff = IP6CB(skb)->nhoff;
-
-       seq = 0;
-       if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0)
-               goto drop;
-
-       do {
-               struct ipv6hdr *iph = ipv6_hdr(skb);
-
-               if (xfrm_nr == XFRM_MAX_DEPTH)
-                       goto drop;
-
-               x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,
-                                     nexthdr, AF_INET6);
-               if (x == NULL)
-                       goto drop;
-               spin_lock(&x->lock);
-               if (unlikely(x->km.state != XFRM_STATE_VALID))
-                       goto drop_unlock;
-
-               if (x->props.replay_window && xfrm_replay_check(x, seq))
-                       goto drop_unlock;
-
-               if (xfrm_state_check_expire(x))
-                       goto drop_unlock;
-
-               nexthdr = x->type->input(x, skb);
-               if (nexthdr <= 0)
-                       goto drop_unlock;
-
-               skb_network_header(skb)[nhoff] = nexthdr;
-
-               if (x->props.replay_window)
-                       xfrm_replay_advance(x, seq);
-
-               x->curlft.bytes += skb->len;
-               x->curlft.packets++;
-
-               spin_unlock(&x->lock);
-
-               xfrm_vec[xfrm_nr++] = x;
-
-               if (x->outer_mode->input(x, skb))
-                       goto drop;
-
-               if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-                       decaps = 1;
-                       break;
-               }
-
-               if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) < 0)
-                       goto drop;
-       } while (!err);
+       return xfrm6_extract_header(skb);
+}
 
-       /* Allocate new secpath or COW existing one. */
-       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-               struct sec_path *sp;
-               sp = secpath_dup(skb->sp);
-               if (!sp)
-                       goto drop;
-               if (skb->sp)
-                       secpath_put(skb->sp);
-               skb->sp = sp;
-       }
+int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
+{
+       XFRM_SPI_SKB_CB(skb)->family = AF_INET6;
+       XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct ipv6hdr, daddr);
+       return xfrm_input(skb, nexthdr, spi, 0);
+}
+EXPORT_SYMBOL(xfrm6_rcv_spi);
 
-       if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)
-               goto drop;
+int xfrm6_transport_finish(struct sk_buff *skb, int async)
+{
+       skb_network_header(skb)[IP6CB(skb)->nhoff] =
+               XFRM_MODE_SKB_CB(skb)->protocol;
 
-       memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,
-              xfrm_nr * sizeof(xfrm_vec[0]));
-       skb->sp->len += xfrm_nr;
-
-       nf_reset(skb);
-
-       if (decaps) {
-               dst_release(skb->dst);
-               skb->dst = NULL;
-               netif_rx(skb);
-               return -1;
-       } else {
-#ifdef CONFIG_NETFILTER
-               ipv6_hdr(skb)->payload_len = htons(skb->len);
-               __skb_push(skb, skb->data - skb_network_header(skb));
-
-               NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
-                       ip6_rcv_finish);
-               return -1;
-#else
+#ifndef CONFIG_NETFILTER
+       if (!async)
                return 1;
 #endif
-       }
 
-drop_unlock:
-       spin_unlock(&x->lock);
-       xfrm_state_put(x);
-drop:
-       while (--xfrm_nr >= 0)
-               xfrm_state_put(xfrm_vec[xfrm_nr]);
-       kfree_skb(skb);
+       ipv6_hdr(skb)->payload_len = htons(skb->len);
+       __skb_push(skb, skb->data - skb_network_header(skb));
+
+       NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+               ip6_rcv_finish);
        return -1;
 }
 
-EXPORT_SYMBOL(xfrm6_rcv_spi);
-
 int xfrm6_rcv(struct sk_buff *skb)
 {
        return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff],
@@ -144,10 +61,28 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
        struct xfrm_state *x = NULL;
        int wildcard = 0;
        xfrm_address_t *xany;
-       struct xfrm_state *xfrm_vec_one = NULL;
        int nh = 0;
        int i = 0;
 
+       /* Allocate new secpath or COW existing one. */
+       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+               struct sec_path *sp;
+
+               sp = secpath_dup(skb->sp);
+               if (!sp) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
+                       goto drop;
+               }
+               if (skb->sp)
+                       secpath_put(skb->sp);
+               skb->sp = sp;
+       }
+
+       if (1 + skb->sp->len == XFRM_MAX_DEPTH) {
+               XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+               goto drop;
+       }
+
        xany = (xfrm_address_t *)&in6addr_any;
 
        for (i = 0; i < 3; i++) {
@@ -200,47 +135,37 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
                        continue;
                }
 
+               spin_unlock(&x->lock);
+
                nh = x->type->input(x, skb);
                if (nh <= 0) {
-                       spin_unlock(&x->lock);
                        xfrm_state_put(x);
                        x = NULL;
                        continue;
                }
 
-               x->curlft.bytes += skb->len;
-               x->curlft.packets++;
-
-               spin_unlock(&x->lock);
-
-               xfrm_vec_one = x;
+               /* Found a state */
                break;
        }
 
-       if (!xfrm_vec_one)
+       if (!x) {
+               XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
+               xfrm_audit_state_notfound_simple(skb, AF_INET6);
                goto drop;
-
-       /* Allocate new secpath or COW existing one. */
-       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
-               struct sec_path *sp;
-               sp = secpath_dup(skb->sp);
-               if (!sp)
-                       goto drop;
-               if (skb->sp)
-                       secpath_put(skb->sp);
-               skb->sp = sp;
        }
 
-       if (1 + skb->sp->len > XFRM_MAX_DEPTH)
-               goto drop;
+       skb->sp->xvec[skb->sp->len++] = x;
+
+       spin_lock(&x->lock);
 
-       skb->sp->xvec[skb->sp->len] = xfrm_vec_one;
-       skb->sp->len ++;
+       x->curlft.bytes += skb->len;
+       x->curlft.packets++;
+
+       spin_unlock(&x->lock);
 
        return 1;
+
 drop:
-       if (xfrm_vec_one)
-               xfrm_state_put(xfrm_vec_one);
        return -1;
 }
 
index 2bfb4f05c14cdffec7f7c455e5ecf43f34acd4c9..0527d11c1ae37a304964cd5c85baf4d99e3b6fbe 100644 (file)
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
+static void xfrm6_beet_make_header(struct sk_buff *skb)
+{
+       struct ipv6hdr *iph = ipv6_hdr(skb);
+
+       iph->version = 6;
+
+       memcpy(iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
+              sizeof(iph->flow_lbl));
+       iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
+
+       ipv6_change_dsfield(iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
+       iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
+}
+
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per draft-nikander-esp-beet-mode-06.txt.
  */
 static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct ipv6hdr *iph, *top_iph;
-       u8 *prevhdr;
-       int hdr_len;
+       struct ipv6hdr *top_iph;
 
-       iph = ipv6_hdr(skb);
-
-       hdr_len = ip6_find_1stfragopt(skb, &prevhdr);
-
-       skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
        skb_set_network_header(skb, -x->props.header_len);
-       skb->transport_header = skb->network_header + hdr_len;
-       __skb_pull(skb, hdr_len);
+       skb->mac_header = skb->network_header +
+                         offsetof(struct ipv6hdr, nexthdr);
+       skb->transport_header = skb->network_header + sizeof(*top_iph);
+
+       xfrm6_beet_make_header(skb);
 
        top_iph = ipv6_hdr(skb);
-       memmove(top_iph, iph, hdr_len);
 
        ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
        ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
-
        return 0;
 }
 
@@ -52,19 +60,21 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
        struct ipv6hdr *ip6h;
        const unsigned char *old_mac;
        int size = sizeof(struct ipv6hdr);
-       int err = -EINVAL;
+       int err;
 
-       if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
+       err = skb_cow_head(skb, size + skb->mac_len);
+       if (err)
                goto out;
 
-       skb_push(skb, size);
-       memmove(skb->data, skb_network_header(skb), size);
+       __skb_push(skb, size);
        skb_reset_network_header(skb);
 
        old_mac = skb_mac_header(skb);
        skb_set_mac_header(skb, -skb->mac_len);
        memmove(skb_mac_header(skb), old_mac, skb->mac_len);
 
+       xfrm6_beet_make_header(skb);
+
        ip6h = ipv6_hdr(skb);
        ip6h->payload_len = htons(skb->len - size);
        ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6);
@@ -75,8 +85,10 @@ out:
 }
 
 static struct xfrm_mode xfrm6_beet_mode = {
-       .input = xfrm6_beet_input,
-       .output = xfrm6_beet_output,
+       .input2 = xfrm6_beet_input,
+       .input = xfrm_prepare_input,
+       .output2 = xfrm6_beet_output,
+       .output = xfrm6_prepare_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_BEET,
        .flags = XFRM_MODE_FLAG_TUNNEL,
index a7bc8c62317af220e6ba9ae95842286b4b7925c5..63d5d493098afd6b250e77b3ef15a880bd7232c7 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/spinlock.h>
 #include <linux/stringify.h>
 #include <linux/time.h>
 #include <net/ipv6.h>
index fd84e2217274a894ca69b1b7a23bfee81fab297f..0c742faaa30bb84cb309962208f9591b64fc5767 100644 (file)
@@ -25,46 +25,29 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
                IP6_ECN_set_ce(inner_iph);
 }
 
-static inline void ip6ip_ecn_decapsulate(struct sk_buff *skb)
-{
-       if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6_hdr(skb))))
-                       IP_ECN_set_ce(ipip_hdr(skb));
-}
-
 /* Add encapsulation header.
  *
  * The top IP header will be constructed per RFC 2401.
  */
-static int xfrm6_tunnel_output(struct xfrm_state *x, 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 xfrm_dst *xdst = (struct xfrm_dst*)dst;
-       struct ipv6hdr *iph, *top_iph;
+       struct ipv6hdr *top_iph;
        int dsfield;
 
-       iph = ipv6_hdr(skb);
-
        skb_set_network_header(skb, -x->props.header_len);
        skb->mac_header = skb->network_header +
                          offsetof(struct ipv6hdr, nexthdr);
-       skb->transport_header = skb->network_header + sizeof(*iph);
+       skb->transport_header = skb->network_header + sizeof(*top_iph);
        top_iph = ipv6_hdr(skb);
 
        top_iph->version = 6;
-       if (xdst->route->ops->family == AF_INET6) {
-               top_iph->priority = iph->priority;
-               top_iph->flow_lbl[0] = iph->flow_lbl[0];
-               top_iph->flow_lbl[1] = iph->flow_lbl[1];
-               top_iph->flow_lbl[2] = iph->flow_lbl[2];
-               top_iph->nexthdr = IPPROTO_IPV6;
-       } else {
-               top_iph->priority = 0;
-               top_iph->flow_lbl[0] = 0;
-               top_iph->flow_lbl[1] = 0;
-               top_iph->flow_lbl[2] = 0;
-               top_iph->nexthdr = IPPROTO_IPIP;
-       }
-       dsfield = ipv6_get_dsfield(top_iph);
+
+       memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
+              sizeof(top_iph->flow_lbl));
+       top_iph->nexthdr = x->inner_mode->afinfo->proto;
+
+       dsfield = XFRM_MODE_SKB_CB(skb)->tos;
        dsfield = INET_ECN_encapsulate(dsfield, dsfield);
        if (x->props.flags & XFRM_STATE_NOECN)
                dsfield &= ~INET_ECN_MASK;
@@ -72,18 +55,15 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        top_iph->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT);
        ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr);
        ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr);
-       skb->protocol = htons(ETH_P_IPV6);
        return 0;
 }
 
-static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
+static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err = -EINVAL;
        const unsigned char *old_mac;
-       const unsigned char *nh = skb_network_header(skb);
 
-       if (nh[IP6CB(skb)->nhoff] != IPPROTO_IPV6 &&
-           nh[IP6CB(skb)->nhoff] != IPPROTO_IPIP)
+       if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
                goto out;
        if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
                goto out;
@@ -92,17 +72,12 @@ static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
            (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
                goto out;
 
-       nh = skb_network_header(skb);
-       if (nh[IP6CB(skb)->nhoff] == IPPROTO_IPV6) {
-               if (x->props.flags & XFRM_STATE_DECAP_DSCP)
-                       ipv6_copy_dscp(ipv6_hdr(skb), ipipv6_hdr(skb));
-               if (!(x->props.flags & XFRM_STATE_NOECN))
-                       ipip6_ecn_decapsulate(skb);
-       } else {
-               if (!(x->props.flags & XFRM_STATE_NOECN))
-                       ip6ip_ecn_decapsulate(skb);
-               skb->protocol = htons(ETH_P_IP);
-       }
+       if (x->props.flags & XFRM_STATE_DECAP_DSCP)
+               ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
+                              ipipv6_hdr(skb));
+       if (!(x->props.flags & XFRM_STATE_NOECN))
+               ipip6_ecn_decapsulate(skb);
+
        old_mac = skb_mac_header(skb);
        skb_set_mac_header(skb, -skb->mac_len);
        memmove(skb_mac_header(skb), old_mac, skb->mac_len);
@@ -114,19 +89,21 @@ out:
 }
 
 static struct xfrm_mode xfrm6_tunnel_mode = {
-       .input = xfrm6_tunnel_input,
-       .output = xfrm6_tunnel_output,
+       .input2 = xfrm6_mode_tunnel_input,
+       .input = xfrm_prepare_input,
+       .output2 = xfrm6_mode_tunnel_output,
+       .output = xfrm6_prepare_output,
        .owner = THIS_MODULE,
        .encap = XFRM_MODE_TUNNEL,
        .flags = XFRM_MODE_FLAG_TUNNEL,
 };
 
-static int __init xfrm6_tunnel_init(void)
+static int __init xfrm6_mode_tunnel_init(void)
 {
        return xfrm_register_mode(&xfrm6_tunnel_mode, AF_INET6);
 }
 
-static void __exit xfrm6_tunnel_exit(void)
+static void __exit xfrm6_mode_tunnel_exit(void)
 {
        int err;
 
@@ -134,7 +111,7 @@ static void __exit xfrm6_tunnel_exit(void)
        BUG_ON(err);
 }
 
-module_init(xfrm6_tunnel_init);
-module_exit(xfrm6_tunnel_exit);
+module_init(xfrm6_mode_tunnel_init);
+module_exit(xfrm6_mode_tunnel_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_TUNNEL);
index 656976760ad47175afa8bc6ac7d2152d5e7f95b4..b34c58c656563851f25b548a84b82742beb72a1d 100644 (file)
  */
 
 #include <linux/if_ether.h>
-#include <linux/compiler.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/icmpv6.h>
 #include <linux/netfilter_ipv6.h>
+#include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/xfrm.h>
 
@@ -43,97 +45,50 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
        return ret;
 }
 
-static inline int xfrm6_output_one(struct sk_buff *skb)
+int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
-       struct xfrm_state *x = dst->xfrm;
-       struct ipv6hdr *iph;
        int err;
 
-       if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
-               err = xfrm6_tunnel_check_size(skb);
-               if (err)
-                       goto error_nolock;
-       }
-
-       err = xfrm_output(skb);
+       err = xfrm6_tunnel_check_size(skb);
        if (err)
-               goto error_nolock;
+               return err;
 
-       iph = ipv6_hdr(skb);
-       iph->payload_len = htons(skb->len - sizeof(*iph));
+       XFRM_MODE_SKB_CB(skb)->protocol = ipv6_hdr(skb)->nexthdr;
 
-       IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
-       err = 0;
-
-out_exit:
-       return err;
-error_nolock:
-       kfree_skb(skb);
-       goto out_exit;
+       return xfrm6_extract_header(skb);
 }
 
-static int xfrm6_output_finish2(struct sk_buff *skb)
+int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
 
-       while (likely((err = xfrm6_output_one(skb)) == 0)) {
-               nf_reset(skb);
-
-               err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
-                             skb->dst->dev, dst_output);
-               if (unlikely(err != 1))
-                       break;
+       err = x->inner_mode->afinfo->extract_output(x, skb);
+       if (err)
+               return err;
 
-               if (!skb->dst->xfrm)
-                       return dst_output(skb);
+       memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+#ifdef CONFIG_NETFILTER
+       IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
+#endif
 
-               err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
-                             skb->dst->dev, xfrm6_output_finish2);
-               if (unlikely(err != 1))
-                       break;
-       }
+       skb->protocol = htons(ETH_P_IPV6);
 
-       return err;
+       return x->outer_mode->output2(x, skb);
 }
+EXPORT_SYMBOL(xfrm6_prepare_output);
 
 static int xfrm6_output_finish(struct sk_buff *skb)
 {
-       struct sk_buff *segs;
-
-       if (!skb_is_gso(skb))
-               return xfrm6_output_finish2(skb);
+#ifdef CONFIG_NETFILTER
+       IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
+#endif
 
        skb->protocol = htons(ETH_P_IPV6);
-       segs = skb_gso_segment(skb, 0);
-       kfree_skb(skb);
-       if (unlikely(IS_ERR(segs)))
-               return PTR_ERR(segs);
-
-       do {
-               struct sk_buff *nskb = segs->next;
-               int err;
-
-               segs->next = NULL;
-               err = xfrm6_output_finish2(segs);
-
-               if (unlikely(err)) {
-                       while ((segs = nskb)) {
-                               nskb = segs->next;
-                               segs->next = NULL;
-                               kfree_skb(segs);
-                       }
-                       return err;
-               }
-
-               segs = nskb;
-       } while (segs);
-
-       return 0;
+       return xfrm_output(skb);
 }
 
 int xfrm6_output(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
+       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dst->dev,
                       xfrm6_output_finish);
 }
index b8e9eb445d744e63e9430fa5ede84810236fcccc..c25a6b527fc4e083184e718720f184a752625bc6 100644 (file)
  *
  */
 
-#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <net/addrconf.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
 static struct dst_ops xfrm6_dst_ops;
 static struct xfrm_policy_afinfo xfrm6_policy_afinfo;
 
-static int xfrm6_dst_lookup(struct xfrm_dst **xdst, struct flowi *fl)
+static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
+                                         xfrm_address_t *daddr)
 {
-       struct dst_entry *dst = ip6_route_output(NULL, fl);
-       int err = dst->error;
-       if (!err)
-               *xdst = (struct xfrm_dst *) dst;
-       else
+       struct flowi fl = {};
+       struct dst_entry *dst;
+       int err;
+
+       memcpy(&fl.fl6_dst, daddr, sizeof(fl.fl6_dst));
+       if (saddr)
+               memcpy(&fl.fl6_src, saddr, sizeof(fl.fl6_src));
+
+       dst = ip6_route_output(NULL, &fl);
+
+       err = dst->error;
+       if (dst->error) {
                dst_release(dst);
-       return err;
+               dst = ERR_PTR(err);
+       }
+
+       return dst;
 }
 
 static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
 {
-       struct rt6_info *rt;
-       struct flowi fl_tunnel = {
-               .nl_u = {
-                       .ip6_u = {
-                               .daddr = *(struct in6_addr *)&daddr->a6,
-                       },
-               },
-       };
-
-       if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
-               ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
-                              (struct in6_addr *)&saddr->a6);
-               dst_release(&rt->u.dst);
-               return 0;
-       }
-       return -EHOSTUNREACH;
+       struct dst_entry *dst;
+
+       dst = xfrm6_dst_lookup(0, NULL, daddr);
+       if (IS_ERR(dst))
+               return -EHOSTUNREACH;
+
+       ipv6_get_saddr(dst, (struct in6_addr *)&daddr->a6,
+                      (struct in6_addr *)&saddr->a6);
+       dst_release(dst);
+       return 0;
 }
 
 static struct dst_entry *
@@ -86,177 +93,53 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
        return dst;
 }
 
-static inline struct in6_addr*
-__xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr)
+static int xfrm6_get_tos(struct flowi *fl)
 {
-       return (x->type->remote_addr) ?
-               (struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) :
-               (struct in6_addr*)&x->id.daddr;
+       return 0;
 }
 
-static inline struct in6_addr*
-__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
+static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+                          int nfheader_len)
 {
-       return (x->type->local_addr) ?
-               (struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) :
-               (struct in6_addr*)&x->props.saddr;
-}
+       if (dst->ops->family == AF_INET6) {
+               struct rt6_info *rt = (struct rt6_info*)dst;
+               if (rt->rt6i_node)
+                       path->path_cookie = rt->rt6i_node->fn_sernum;
+       }
 
-static inline void
-__xfrm6_bundle_len_inc(int *len, int *nflen, struct xfrm_state *x)
-{
-       if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
-               *nflen += x->props.header_len;
-       else
-               *len += x->props.header_len;
-}
+       path->u.rt6.rt6i_nfheader_len = nfheader_len;
 
-static inline void
-__xfrm6_bundle_len_dec(int *len, int *nflen, struct xfrm_state *x)
-{
-       if (x->type->flags & XFRM_TYPE_NON_FRAGMENT)
-               *nflen -= x->props.header_len;
-       else
-               *len -= x->props.header_len;
+       return 0;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
-
-static int
-__xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-                     struct flowi *fl, struct dst_entry **dst_p)
+static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
 {
-       struct dst_entry *dst, *dst_prev;
-       struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
-       struct rt6_info *rt  = rt0;
-       struct flowi fl_tunnel = {
-               .nl_u = {
-                       .ip6_u = {
-                               .saddr = fl->fl6_src,
-                               .daddr = fl->fl6_dst,
-                       }
-               }
-       };
-       int i;
-       int err = 0;
-       int header_len = 0;
-       int nfheader_len = 0;
-       int trailer_len = 0;
-
-       dst = dst_prev = NULL;
-       dst_hold(&rt->u.dst);
-
-       for (i = 0; i < nx; i++) {
-               struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops);
-               struct xfrm_dst *xdst;
-
-               if (unlikely(dst1 == NULL)) {
-                       err = -ENOBUFS;
-                       dst_release(&rt->u.dst);
-                       goto error;
-               }
+       struct rt6_info *rt = (struct rt6_info*)xdst->route;
 
-               if (!dst)
-                       dst = dst1;
-               else {
-                       dst_prev->child = dst1;
-                       dst1->flags |= DST_NOHASH;
-                       dst_clone(dst1);
-               }
-
-               xdst = (struct xfrm_dst *)dst1;
-               xdst->route = &rt->u.dst;
-               xdst->genid = xfrm[i]->genid;
-               if (rt->rt6i_node)
-                       xdst->route_cookie = rt->rt6i_node->fn_sernum;
-
-               dst1->next = dst_prev;
-               dst_prev = dst1;
-
-               __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]);
-               trailer_len += xfrm[i]->props.trailer_len;
-
-               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-                       unsigned short encap_family = xfrm[i]->props.family;
-                       switch(encap_family) {
-                       case AF_INET:
-                               fl_tunnel.fl4_dst = xfrm[i]->id.daddr.a4;
-                               fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
-                               break;
-                       case AF_INET6:
-                               ipv6_addr_copy(&fl_tunnel.fl6_dst, __xfrm6_bundle_addr_remote(xfrm[i], &fl->fl6_dst));
-
-                               ipv6_addr_copy(&fl_tunnel.fl6_src, __xfrm6_bundle_addr_local(xfrm[i], &fl->fl6_src));
-                               break;
-                       default:
-                               BUG_ON(1);
-                       }
+       xdst->u.dst.dev = dev;
+       dev_hold(dev);
 
-                       err = xfrm_dst_lookup((struct xfrm_dst **) &rt,
-                                             &fl_tunnel, encap_family);
-                       if (err)
-                               goto error;
-               } else
-                       dst_hold(&rt->u.dst);
-       }
+       xdst->u.rt6.rt6i_idev = in6_dev_get(rt->u.dst.dev);
+       if (!xdst->u.rt6.rt6i_idev)
+               return -ENODEV;
 
-       dst_prev->child = &rt->u.dst;
-       dst->path = &rt->u.dst;
+       /* Sheit... I remember I did this right. Apparently,
+        * it was magically lost, so this code needs audit */
+       xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST |
+                                                  RTF_LOCAL);
+       xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
+       xdst->u.rt6.rt6i_node = rt->rt6i_node;
        if (rt->rt6i_node)
-               ((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum;
-
-       *dst_p = dst;
-       dst = dst_prev;
-
-       dst_prev = *dst_p;
-       i = 0;
-       for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
-               struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-
-               dst_prev->xfrm = xfrm[i++];
-               dst_prev->dev = rt->u.dst.dev;
-               if (rt->u.dst.dev)
-                       dev_hold(rt->u.dst.dev);
-               dst_prev->obsolete      = -1;
-               dst_prev->flags        |= DST_HOST;
-               dst_prev->lastuse       = jiffies;
-               dst_prev->header_len    = header_len;
-               dst_prev->nfheader_len  = nfheader_len;
-               dst_prev->trailer_len   = trailer_len;
-               memcpy(&dst_prev->metrics, &x->route->metrics, sizeof(dst_prev->metrics));
-
-               /* Copy neighbour for reachability confirmation */
-               dst_prev->neighbour     = neigh_clone(rt->u.dst.neighbour);
-               dst_prev->input         = rt->u.dst.input;
-               dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output;
-               /* Sheit... I remember I did this right. Apparently,
-                * it was magically lost, so this code needs audit */
-               x->u.rt6.rt6i_flags    = rt0->rt6i_flags&(RTF_ANYCAST|RTF_LOCAL);
-               x->u.rt6.rt6i_metric   = rt0->rt6i_metric;
-               x->u.rt6.rt6i_node     = rt0->rt6i_node;
-               x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
-               memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway));
-               x->u.rt6.rt6i_dst      = rt0->rt6i_dst;
-               x->u.rt6.rt6i_src      = rt0->rt6i_src;
-               x->u.rt6.rt6i_idev     = rt0->rt6i_idev;
-               in6_dev_hold(rt0->rt6i_idev);
-               __xfrm6_bundle_len_dec(&header_len, &nfheader_len, x->u.dst.xfrm);
-               trailer_len -= x->u.dst.xfrm->props.trailer_len;
-       }
+               xdst->route_cookie = rt->rt6i_node->fn_sernum;
+       xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
+       xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
+       xdst->u.rt6.rt6i_src = rt->rt6i_src;
 
-       xfrm_init_pmtu(dst);
        return 0;
-
-error:
-       if (dst)
-               dst_free(dst);
-       return err;
 }
 
 static inline void
-_decode_session6(struct sk_buff *skb, struct flowi *fl)
+_decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)
 {
        u16 offset = skb_network_header_len(skb);
        struct ipv6hdr *hdr = ipv6_hdr(skb);
@@ -265,8 +148,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
        u8 nexthdr = nh[IP6CB(skb)->nhoff];
 
        memset(fl, 0, sizeof(struct flowi));
-       ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
-       ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
+       ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr);
+       ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr);
 
        while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) {
                nh = skb_network_header(skb);
@@ -289,8 +172,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
                        if (pskb_may_pull(skb, nh + offset + 4 - skb->data)) {
                                __be16 *ports = (__be16 *)exthdr;
 
-                               fl->fl_ip_sport = ports[0];
-                               fl->fl_ip_dport = ports[1];
+                               fl->fl_ip_sport = ports[!!reverse];
+                               fl->fl_ip_dport = ports[!reverse];
                        }
                        fl->proto = nexthdr;
                        return;
@@ -329,7 +212,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
        }
 }
 
-static inline int xfrm6_garbage_collect(void)
+static inline int xfrm6_garbage_collect(struct dst_ops *ops)
 {
        xfrm6_policy_afinfo.garbage_collect();
        return (atomic_read(&xfrm6_dst_ops.entries) > xfrm6_dst_ops.gc_thresh*2);
@@ -362,7 +245,8 @@ static void xfrm6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
 
        xdst = (struct xfrm_dst *)dst;
        if (xdst->u.rt6.rt6i_idev->dev == dev) {
-               struct inet6_dev *loopback_idev = in6_dev_get(init_net.loopback_dev);
+               struct inet6_dev *loopback_idev =
+                       in6_dev_get(dev->nd_net->loopback_dev);
                BUG_ON(!loopback_idev);
 
                do {
@@ -385,6 +269,7 @@ static struct dst_ops xfrm6_dst_ops = {
        .update_pmtu =          xfrm6_update_pmtu,
        .destroy =              xfrm6_dst_destroy,
        .ifdown =               xfrm6_dst_ifdown,
+       .local_out =            __ip6_local_out,
        .gc_thresh =            1024,
        .entry_size =           sizeof(struct xfrm_dst),
 };
@@ -395,13 +280,15 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
        .dst_lookup =           xfrm6_dst_lookup,
        .get_saddr =            xfrm6_get_saddr,
        .find_bundle =          __xfrm6_find_bundle,
-       .bundle_create =        __xfrm6_bundle_create,
        .decode_session =       _decode_session6,
+       .get_tos =              xfrm6_get_tos,
+       .init_path =            xfrm6_init_path,
+       .fill_dst =             xfrm6_fill_dst,
 };
 
-static void __init xfrm6_policy_init(void)
+static int __init xfrm6_policy_init(void)
 {
-       xfrm_policy_register_afinfo(&xfrm6_policy_afinfo);
+       return xfrm_policy_register_afinfo(&xfrm6_policy_afinfo);
 }
 
 static void xfrm6_policy_fini(void)
@@ -409,10 +296,22 @@ static void xfrm6_policy_fini(void)
        xfrm_policy_unregister_afinfo(&xfrm6_policy_afinfo);
 }
 
-void __init xfrm6_init(void)
+int __init xfrm6_init(void)
 {
-       xfrm6_policy_init();
-       xfrm6_state_init();
+       int ret;
+
+       ret = xfrm6_policy_init();
+       if (ret)
+               goto out;
+
+       ret = xfrm6_state_init();
+       if (ret)
+               goto out_policy;
+out:
+       return ret;
+out_policy:
+       xfrm6_policy_fini();
+       goto out;
 }
 
 void xfrm6_fini(void)
index b392bee396f16341c2842aa20c3759c19afb0238..dc817e035e2338cb60fa78ec2e0cf9319eef986d 100644 (file)
@@ -14,6 +14,8 @@
 #include <net/xfrm.h>
 #include <linux/pfkeyv2.h>
 #include <linux/ipsec.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/dsfield.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 
@@ -168,18 +170,37 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n)
        return 0;
 }
 
+int xfrm6_extract_header(struct sk_buff *skb)
+{
+       struct ipv6hdr *iph = ipv6_hdr(skb);
+
+       XFRM_MODE_SKB_CB(skb)->id = 0;
+       XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
+       XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
+       XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
+       memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
+              sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
+
+       return 0;
+}
+
 static struct xfrm_state_afinfo xfrm6_state_afinfo = {
        .family                 = AF_INET6,
+       .proto                  = IPPROTO_IPV6,
+       .eth_proto              = htons(ETH_P_IPV6),
        .owner                  = THIS_MODULE,
        .init_tempsel           = __xfrm6_init_tempsel,
        .tmpl_sort              = __xfrm6_tmpl_sort,
        .state_sort             = __xfrm6_state_sort,
        .output                 = xfrm6_output,
+       .extract_input          = xfrm6_extract_input,
+       .extract_output         = xfrm6_extract_output,
+       .transport_finish       = xfrm6_transport_finish,
 };
 
-void __init xfrm6_state_init(void)
+int __init xfrm6_state_init(void)
 {
-       xfrm_state_register_afinfo(&xfrm6_state_afinfo);
+       return xfrm_state_register_afinfo(&xfrm6_state_afinfo);
 }
 
 void xfrm6_state_fini(void)
index 0cf52645053648c7444a86544537a2b54a0243a1..92fef864e85225a142fc778c8da4afc9e94cb5b9 100644 (file)
@@ -28,31 +28,17 @@ static struct ctl_table ipx_table[] = {
        { 0 },
 };
 
-static struct ctl_table ipx_dir_table[] = {
-       {
-               .ctl_name       = NET_IPX,
-               .procname       = "ipx",
-               .mode           = 0555,
-               .child          = ipx_table,
-       },
-       { 0 },
-};
-
-static struct ctl_table ipx_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = ipx_dir_table,
-       },
-       { 0 },
+static struct ctl_path ipx_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "ipx", .ctl_name = NET_IPX, },
+       { }
 };
 
 static struct ctl_table_header *ipx_table_header;
 
 void ipx_register_sysctl(void)
 {
-       ipx_table_header = register_sysctl_table(ipx_root_table);
+       ipx_table_header = register_sysctl_paths(ipx_path, ipx_table);
 }
 
 void ipx_unregister_sysctl(void)
index 07dfa7fdd2a02181c2448e74e7a371b25926cbaa..240b0cbfb532ce370b73722ac8565f787f5cd4f2 100644 (file)
@@ -2410,9 +2410,8 @@ bed:
 
                        /* Set watchdog timer to expire in <val> ms. */
                        self->errno = 0;
-                       init_timer(&self->watchdog);
-                       self->watchdog.function = irda_discovery_timeout;
-                       self->watchdog.data = (unsigned long) self;
+                       setup_timer(&self->watchdog, irda_discovery_timeout,
+                                       (unsigned long)self);
                        self->watchdog.expires = jiffies + (val * HZ/1000);
                        add_timer(&(self->watchdog));
 
index 2d63fa8e155641f1bf4937ee0c733041f97000e5..b825399fc16002dc98a3983c8475462286072afc 100644 (file)
@@ -362,6 +362,18 @@ void ircomm_process_data(struct ircomm_cb *self, struct sk_buff *skb)
 
        clen = skb->data[0];
 
+       /*
+        * Input validation check: a stir4200/mcp2150 combinations sometimes
+        * results in frames with clen > remaining packet size. These are
+        * illegal; if we throw away just this frame then it seems to carry on
+        * fine
+        */
+       if (unlikely(skb->len < (clen + 1))) {
+               IRDA_DEBUG(2, "%s() throwing away illegal frame\n",
+                          __FUNCTION__ );
+               return;
+       }
+
        /*
         * If there are any data hiding in the control channel, we must
         * deliver it first. The side effect is that the control channel
index 435b563d29a6904223236f881f317705ba8f888c..87185910d0eecfb49211acb4dad88871626bcf74 100644 (file)
@@ -57,20 +57,6 @@ static void __irda_task_delete(struct irda_task *task);
 static hashbin_t *dongles = NULL;
 static hashbin_t *tasks = NULL;
 
-#ifdef CONFIG_IRDA_DEBUG
-static const char *task_state[] = {
-       "IRDA_TASK_INIT",
-       "IRDA_TASK_DONE",
-       "IRDA_TASK_WAIT",
-       "IRDA_TASK_WAIT1",
-       "IRDA_TASK_WAIT2",
-       "IRDA_TASK_WAIT3",
-       "IRDA_TASK_CHILD_INIT",
-       "IRDA_TASK_CHILD_WAIT",
-       "IRDA_TASK_CHILD_DONE",
-};
-#endif /* CONFIG_IRDA_DEBUG */
-
 static void irda_task_timer_expired(void *data);
 
 int __init irda_device_init( void)
@@ -176,14 +162,6 @@ int irda_device_is_receiving(struct net_device *dev)
        return req.ifr_receiving;
 }
 
-void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state)
-{
-       IRDA_DEBUG(2, "%s(), state = %s\n", __FUNCTION__, task_state[state]);
-
-       task->state = state;
-}
-EXPORT_SYMBOL(irda_task_next_state);
-
 static void __irda_task_delete(struct irda_task *task)
 {
        del_timer(&task->timer);
@@ -191,14 +169,13 @@ static void __irda_task_delete(struct irda_task *task)
        kfree(task);
 }
 
-void irda_task_delete(struct irda_task *task)
+static void irda_task_delete(struct irda_task *task)
 {
        /* Unregister task */
        hashbin_remove(tasks, (long) task, NULL);
 
        __irda_task_delete(task);
 }
-EXPORT_SYMBOL(irda_task_delete);
 
 /*
  * Function irda_task_kick (task)
@@ -271,51 +248,6 @@ static int irda_task_kick(struct irda_task *task)
        return finished;
 }
 
-/*
- * Function irda_task_execute (instance, function, finished)
- *
- *    This function registers and tries to execute tasks that may take some
- *    time to complete. We do it this hairy way since we may have been
- *    called from interrupt context, so it's not possible to use
- *    schedule_timeout()
- * Two important notes :
- *     o Make sure you irda_task_delete(task); in case you delete the
- *       calling instance.
- *     o No real need to lock when calling this function, but you may
- *       want to lock within the task handler.
- * Jean II
- */
-struct irda_task *irda_task_execute(void *instance,
-                                   IRDA_TASK_CALLBACK function,
-                                   IRDA_TASK_CALLBACK finished,
-                                   struct irda_task *parent, void *param)
-{
-       struct irda_task *task;
-
-       IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
-       task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC);
-       if (!task)
-               return NULL;
-
-       task->state    = IRDA_TASK_INIT;
-       task->instance = instance;
-       task->function = function;
-       task->finished = finished;
-       task->parent   = parent;
-       task->param    = param;
-       task->magic    = IRDA_TASK_MAGIC;
-
-       init_timer(&task->timer);
-
-       /* Register task */
-       hashbin_insert(tasks, (irda_queue_t *) task, (long) task, NULL);
-
-       /* No time to waste, so lets get going! */
-       return irda_task_kick(task) ? NULL : task;
-}
-EXPORT_SYMBOL(irda_task_execute);
-
 /*
  * Function irda_task_timer_expired (data)
  *
@@ -364,105 +296,6 @@ struct net_device *alloc_irdadev(int sizeof_priv)
 }
 EXPORT_SYMBOL(alloc_irdadev);
 
-/*
- * Function irda_device_init_dongle (self, type, qos)
- *
- *    Initialize attached dongle.
- *
- * Important : request_module require us to call this function with
- * a process context and irq enabled. - Jean II
- */
-dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
-{
-       struct dongle_reg *reg;
-       dongle_t *dongle = kzalloc(sizeof(dongle_t), GFP_KERNEL);
-
-       might_sleep();
-
-       spin_lock(&dongles->hb_spinlock);
-       reg = hashbin_find(dongles, type, NULL);
-
-#ifdef CONFIG_KMOD
-       /* Try to load the module needed */
-       if (!reg && capable(CAP_SYS_MODULE)) {
-               spin_unlock(&dongles->hb_spinlock);
-
-               request_module("irda-dongle-%d", type);
-
-               spin_lock(&dongles->hb_spinlock);
-               reg = hashbin_find(dongles, type, NULL);
-       }
-#endif
-
-       if (!reg || !try_module_get(reg->owner) ) {
-               IRDA_ERROR("IrDA: Unable to find requested dongle type %x\n",
-                          type);
-               kfree(dongle);
-               dongle = NULL;
-       }
-       if (dongle) {
-               /* Bind the registration info to this particular instance */
-               dongle->issue = reg;
-               dongle->dev = dev;
-       }
-       spin_unlock(&dongles->hb_spinlock);
-       return dongle;
-}
-EXPORT_SYMBOL(irda_device_dongle_init);
-
-/*
- * Function irda_device_dongle_cleanup (dongle)
- */
-int irda_device_dongle_cleanup(dongle_t *dongle)
-{
-       IRDA_ASSERT(dongle != NULL, return -1;);
-
-       dongle->issue->close(dongle);
-       module_put(dongle->issue->owner);
-       kfree(dongle);
-
-       return 0;
-}
-EXPORT_SYMBOL(irda_device_dongle_cleanup);
-
-/*
- * Function irda_device_register_dongle (dongle)
- */
-int irda_device_register_dongle(struct dongle_reg *new)
-{
-       spin_lock(&dongles->hb_spinlock);
-       /* Check if this dongle has been registered before */
-       if (hashbin_find(dongles, new->type, NULL)) {
-               IRDA_MESSAGE("%s: Dongle type %x already registered\n",
-                            __FUNCTION__, new->type);
-       } else {
-               /* Insert IrDA dongle into hashbin */
-               hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
-       }
-       spin_unlock(&dongles->hb_spinlock);
-
-       return 0;
-}
-EXPORT_SYMBOL(irda_device_register_dongle);
-
-/*
- * Function irda_device_unregister_dongle (dongle)
- *
- *    Unregister dongle, and remove dongle from list of registered dongles
- *
- */
-void irda_device_unregister_dongle(struct dongle_reg *dongle)
-{
-       struct dongle *node;
-
-       spin_lock(&dongles->hb_spinlock);
-       node = hashbin_remove(dongles, dongle->type, NULL);
-       if (!node)
-               IRDA_ERROR("%s: dongle not found!\n", __FUNCTION__);
-       spin_unlock(&dongles->hb_spinlock);
-}
-EXPORT_SYMBOL(irda_device_unregister_dongle);
-
 #ifdef CONFIG_ISA_DMA_API
 /*
  * Function setup_dma (idev, buffer, count, mode)
index a86a5d83786b349bb92e773ad8d70c0d6340fe49..390a790886ebbd3e6006dd3f0638b0d2c0fba46d 100644 (file)
@@ -579,7 +579,7 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self,
        fp[n++] = ret_code;
 
        /* Insert list length (MSB first) */
-       tmp_be16 = __constant_htons(0x0001);
+       tmp_be16 = htons(0x0001);
        memcpy(fp+n, &tmp_be16, 2);  n += 2;
 
        /* Insert object identifier ( MSB first) */
index 4c33bf5c8354df31023de03c679b7ee6b02b642f..6af86eba7463259522b8530dfbf361e4624d464b 100644 (file)
@@ -1199,6 +1199,19 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
 
        switch (event) {
        case RECV_I_RSP: /* Optimize for the common case */
+               if (unlikely(skb->len <= LAP_ADDR_HEADER + LAP_CTRL_HEADER)) {
+                       /*
+                        * Input validation check: a stir4200/mcp2150
+                        * combination sometimes results in an empty i:rsp.
+                        * This makes no sense; we can just ignore the frame
+                        * and send an rr:cmd immediately. This happens before
+                        * changing nr or ns so triggers a retransmit
+                        */
+                       irlap_wait_min_turn_around(self, &self->qos_tx);
+                       irlap_send_rr_frame(self, CMD_FRAME);
+                       /* Keep state */
+                       break;
+               }
                /* FIXME: must check for remote_busy below */
 #ifdef CONFIG_IRDA_FAST_RR
                /*
@@ -1514,9 +1527,15 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
 
                /* N2 is the disconnect timer. Until we reach it, we retry */
                if (self->retry_count < self->N2) {
-                       /* Retry sending the pf bit to the secondary */
-                       irlap_wait_min_turn_around(self, &self->qos_tx);
-                       irlap_send_rr_frame(self, CMD_FRAME);
+                       if (skb_peek(&self->wx_list) == NULL) {
+                               /* Retry sending the pf bit to the secondary */
+                               IRDA_DEBUG(4, "nrm_p: resending rr");
+                               irlap_wait_min_turn_around(self, &self->qos_tx);
+                               irlap_send_rr_frame(self, CMD_FRAME);
+                       } else {
+                               IRDA_DEBUG(4, "nrm_p: resend frames");
+                               irlap_resend_rejected_frames(self, CMD_FRAME);
+                       }
 
                        irlap_start_final_timer(self, self->final_timeout);
                        self->retry_count++;
index f24cb755908e223c9c39eb9dd89d70e4d633dc48..135ac6907bbf16f703bcb38f42f97324bda62800 100644 (file)
@@ -103,9 +103,12 @@ int __init irlmp_init(void)
        irlmp->last_lsap_sel = 0x0f; /* Reserved 0x00-0x0f */
        strcpy(sysctl_devname, "Linux");
 
-       /* Do discovery every 3 seconds */
        init_timer(&irlmp->discovery_timer);
-       irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
+
+       /* Do discovery every 3 seconds, conditionaly */
+       if (sysctl_discovery)
+               irlmp_start_discovery_timer(irlmp,
+                                           sysctl_discovery_timeout*HZ);
 
        return 0;
 }
index 1bba87e7860943ac444d6f55b4aa78fa8c5dad30..150cd3f1129aeb833ad19638adbae35d2946c305 100644 (file)
@@ -174,9 +174,7 @@ void irlmp_discovery_timer_expired(void *data)
        /* We always cleanup the log (active & passive discovery) */
        irlmp_do_expiry();
 
-       /* Active discovery is conditional */
-       if (sysctl_discovery)
-               irlmp_do_discovery(sysctl_discovery_slots);
+       irlmp_do_discovery(sysctl_discovery_slots);
 
        /* Restart timer */
        irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
index 565cbf0421cd69124e372aa9274ef9a43b3da393..9ab3df15425db06014e0a2bb3e337cd687a8e729 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/init.h>
 
 #include <net/irda/irda.h>             /* irda_debug */
+#include <net/irda/irlmp.h>
+#include <net/irda/timer.h>
 #include <net/irda/irias_object.h>
 
 extern int  sysctl_discovery;
@@ -45,6 +47,8 @@ extern int  sysctl_max_noreply_time;
 extern int  sysctl_warn_noreply_time;
 extern int  sysctl_lap_keepalive_time;
 
+extern struct irlmp_cb *irlmp;
+
 /* this is needed for the proc_dointvec_minmax - Jean II */
 static int max_discovery_slots = 16;           /* ??? */
 static int min_discovery_slots = 1;
@@ -85,6 +89,27 @@ static int do_devname(ctl_table *table, int write, struct file *filp,
        return ret;
 }
 
+
+static int do_discovery(ctl_table *table, int write, struct file *filp,
+                    void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int ret;
+
+       ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);
+       if (ret)
+              return ret;
+
+       if (irlmp == NULL)
+              return -ENODEV;
+
+       if (sysctl_discovery)
+              irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout*HZ);
+       else
+              del_timer_sync(&irlmp->discovery_timer);
+
+       return ret;
+}
+
 /* One file */
 static ctl_table irda_table[] = {
        {
@@ -93,7 +118,8 @@ static ctl_table irda_table[] = {
                .data           = &sysctl_discovery,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec
+               .proc_handler   = &do_discovery,
+               .strategy       = &sysctl_intvec
        },
        {
                .ctl_name       = NET_IRDA_DEVNAME,
@@ -234,28 +260,10 @@ static ctl_table irda_table[] = {
        { .ctl_name = 0 }
 };
 
-/* One directory */
-static ctl_table irda_net_table[] = {
-       {
-               .ctl_name       = NET_IRDA,
-               .procname       = "irda",
-               .maxlen         = 0,
-               .mode           = 0555,
-               .child          = irda_table
-       },
-       { .ctl_name = 0 }
-};
-
-/* The parent directory */
-static ctl_table irda_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .maxlen         = 0,
-               .mode           = 0555,
-               .child          = irda_net_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path irda_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "irda", .ctl_name = NET_IRDA, },
+       { }
 };
 
 static struct ctl_table_header *irda_table_header;
@@ -268,7 +276,7 @@ static struct ctl_table_header *irda_table_header;
  */
 int __init irda_sysctl_register(void)
 {
-       irda_table_header = register_sysctl_table(irda_root_table);
+       irda_table_header = register_sysctl_paths(irda_path, irda_table);
        if (!irda_table_header)
                return -ENOMEM;
 
index aef6645803559c0e0695574a731dad158fa8a091..2255e3c082ed68d6c493f481b87b136a9b53a943 100644 (file)
@@ -94,13 +94,6 @@ static void iucv_sock_clear_timer(struct sock *sk)
        sk_stop_timer(sk, &sk->sk_timer);
 }
 
-static void iucv_sock_init_timer(struct sock *sk)
-{
-       init_timer(&sk->sk_timer);
-       sk->sk_timer.function = iucv_sock_timeout;
-       sk->sk_timer.data = (unsigned long)sk;
-}
-
 static struct sock *__iucv_get_sock_by_name(char *nm)
 {
        struct sock *sk;
@@ -238,7 +231,7 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
        sk->sk_protocol = proto;
        sk->sk_state    = IUCV_OPEN;
 
-       iucv_sock_init_timer(sk);
+       setup_timer(&sk->sk_timer, iucv_sock_timeout, (unsigned long)sk);
 
        iucv_sock_link(&iucv_sk_list, sk);
        return sk;
index 7698f6c459d6006f2ed587ec00c54c84a1901777..f13fe8821cbd7bf7817c6eacb85709aaca134492 100644 (file)
@@ -1492,7 +1492,7 @@ static void iucv_tasklet_fn(unsigned long ignored)
                [0x08] = iucv_message_pending,
                [0x09] = iucv_message_pending,
        };
-       struct list_head task_queue = LIST_HEAD_INIT(task_queue);
+       LIST_HEAD(task_queue);
        struct iucv_irq_list *p, *n;
 
        /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
@@ -1526,7 +1526,7 @@ static void iucv_tasklet_fn(unsigned long ignored)
 static void iucv_work_fn(struct work_struct *work)
 {
        typedef void iucv_irq_fn(struct iucv_irq_data *);
-       struct list_head work_queue = LIST_HEAD_INIT(work_queue);
+       LIST_HEAD(work_queue);
        struct iucv_irq_list *p, *n;
 
        /* Serialize tasklet, iucv_path_sever and iucv_path_connect. */
index 76dcd882f87b97e3c5195fe96e9e0a9eb5178c78..16b72b5570c303831aca6353d6a35b4ae901b473 100644 (file)
@@ -2291,8 +2291,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        return 0;
 
 out:
-       security_xfrm_policy_free(xp);
-       kfree(xp);
+       xfrm_policy_destroy(xp);
        return err;
 }
 
@@ -3236,8 +3235,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
        return xp;
 
 out:
-       security_xfrm_policy_free(xp);
-       kfree(xp);
+       xfrm_policy_destroy(xp);
        return NULL;
 }
 
index a2e7aa63fd8a4939af6d8cf687bd1302abfd86dd..2ba1bc4f3c3a27b5d1bfbc25cf7ab1f44c59985a 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/init.h>
 #include <net/lapb.h>
 
-static struct list_head lapb_list = LIST_HEAD_INIT(lapb_list);
+static LIST_HEAD(lapb_list);
 static DEFINE_RWLOCK(lapb_list_lock);
 
 /*
index 5c0b484237c81b0b370369f48d9449b796c3d9ac..441bc18f996d51d47d482a1a3c97ab8e8f2439b7 100644 (file)
@@ -831,25 +831,21 @@ static void llc_sk_init(struct sock* sk)
        llc->inc_cntr = llc->dec_cntr = 2;
        llc->dec_step = llc->connect_step = 1;
 
-       init_timer(&llc->ack_timer.timer);
+       setup_timer(&llc->ack_timer.timer, llc_conn_ack_tmr_cb,
+                       (unsigned long)sk);
        llc->ack_timer.expire         = sysctl_llc2_ack_timeout;
-       llc->ack_timer.timer.data     = (unsigned long)sk;
-       llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
 
-       init_timer(&llc->pf_cycle_timer.timer);
+       setup_timer(&llc->pf_cycle_timer.timer, llc_conn_pf_cycle_tmr_cb,
+                       (unsigned long)sk);
        llc->pf_cycle_timer.expire         = sysctl_llc2_p_timeout;
-       llc->pf_cycle_timer.timer.data     = (unsigned long)sk;
-       llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
 
-       init_timer(&llc->rej_sent_timer.timer);
+       setup_timer(&llc->rej_sent_timer.timer, llc_conn_rej_tmr_cb,
+                       (unsigned long)sk);
        llc->rej_sent_timer.expire         = sysctl_llc2_rej_timeout;
-       llc->rej_sent_timer.timer.data     = (unsigned long)sk;
-       llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
 
-       init_timer(&llc->busy_state_timer.timer);
+       setup_timer(&llc->busy_state_timer.timer, llc_conn_busy_tmr_cb,
+                       (unsigned long)sk);
        llc->busy_state_timer.expire         = sysctl_llc2_busy_timeout;
-       llc->busy_state_timer.timer.data     = (unsigned long)sk;
-       llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
 
        llc->n2 = 2;   /* max retransmit */
        llc->k  = 2;   /* tx win size, will adjust dynam */
index 576355a192ab062c804312f9ebccccebb56f7425..6f2ea2090322000f4c28aaf11ae414ed57519c55 100644 (file)
@@ -688,9 +688,8 @@ int __init llc_station_init(void)
        skb_queue_head_init(&llc_main_station.mac_pdu_q);
        skb_queue_head_init(&llc_main_station.ev_q.list);
        spin_lock_init(&llc_main_station.ev_q.lock);
-       init_timer(&llc_main_station.ack_timer);
-       llc_main_station.ack_timer.data     = (unsigned long)&llc_main_station;
-       llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
+       setup_timer(&llc_main_station.ack_timer, llc_station_ack_tmr_cb,
+                       (unsigned long)&llc_main_station);
        llc_main_station.ack_timer.expires  = jiffies +
                                                sysctl_llc_station_ack_timeout;
        skb = alloc_skb(0, GFP_ATOMIC);
index 46992d03601766503cc9250a25cda2b27ddccb3a..5bef1dcf18e3c1ec060dcdb4f4047376d2a0f417 100644 (file)
@@ -92,31 +92,17 @@ static struct ctl_table llc_table[] = {
        { 0 },
 };
 
-static struct ctl_table llc_dir_table[] = {
-       {
-               .ctl_name       = NET_LLC,
-               .procname       = "llc",
-               .mode           = 0555,
-               .child          = llc_table,
-       },
-       { 0 },
-};
-
-static struct ctl_table llc_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = llc_dir_table,
-       },
-       { 0 },
+static struct ctl_path llc_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "llc", .ctl_name = NET_LLC, },
+       { }
 };
 
 static struct ctl_table_header *llc_table_header;
 
 int __init llc_sysctl_init(void)
 {
-       llc_table_header = register_sysctl_table(llc_root_table);
+       llc_table_header = register_sysctl_paths(llc_path, llc_table);
 
        return llc_table_header ? 0 : -ENOMEM;
 }
index ce176e691afec86281ffb1130f848c53ff641f9e..09c255002e565dcba6606937d0c1a14409537212 100644 (file)
@@ -10,27 +10,84 @@ config MAC80211
        select CFG80211
        select NET_SCH_FIFO
        ---help---
-       This option enables the hardware independent IEEE 802.11
-       networking stack.
+         This option enables the hardware independent IEEE 802.11
+         networking stack.
 
-config MAC80211_RCSIMPLE
-       bool "'simple' rate control algorithm" if EMBEDDED
-       default y
-       depends on MAC80211
+menu "Rate control algorithm selection"
+       depends on MAC80211 != n
+
+choice
+       prompt "Default rate control algorithm"
+       default MAC80211_RC_DEFAULT_PID
+       ---help---
+         This option selects the default rate control algorithm
+         mac80211 will use. Note that this default can still be
+         overriden through the ieee80211_default_rc_algo module
+         parameter if different algorithms are available.
+
+config MAC80211_RC_DEFAULT_PID
+       bool "PID controller based rate control algorithm"
+       select MAC80211_RC_PID
+       ---help---
+         Select the PID controller based rate control as the
+         default rate control algorithm. You should choose
+         this unless you know what you are doing.
+
+config MAC80211_RC_DEFAULT_SIMPLE
+       bool "Simple rate control algorithm"
+       select MAC80211_RC_SIMPLE
+       ---help---
+         Select the simple rate control as the default rate
+         control algorithm. Note that this is a non-responsive,
+         dumb algorithm. You should choose the PID rate control
+         instead.
+
+config MAC80211_RC_DEFAULT_NONE
+       bool "No default algorithm"
+       depends on EMBEDDED
        help
-         This option allows you to turn off the 'simple' rate
-         control algorithm in mac80211. If you do turn it off,
-         you absolutely need another rate control algorithm.
+         Selecting this option will select no default algorithm
+         and allow you to not build any. Do not choose this
+         option unless you know your driver comes with another
+         suitable algorithm.
+endchoice
+
+comment "Selecting 'y' for an algorithm will"
+comment "build the algorithm into mac80211."
+
+config MAC80211_RC_DEFAULT
+       string
+       default "pid" if MAC80211_RC_DEFAULT_PID
+       default "simple" if MAC80211_RC_DEFAULT_SIMPLE
+       default ""
 
-         Say Y unless you know you will have another algorithm
-         available.
+config MAC80211_RC_PID
+       tristate "PID controller based rate control algorithm"
+       ---help---
+         This option enables a TX rate control algorithm for
+         mac80211 that uses a PID controller to select the TX
+         rate.
+
+         Say Y or M unless you're sure you want to use a
+         different rate control algorithm.
+
+config MAC80211_RC_SIMPLE
+       tristate "Simple rate control algorithm (DEPRECATED)"
+       ---help---
+         This option enables a very simple, non-responsive TX
+         rate control algorithm. This algorithm is deprecated
+         and will be removed from the kernel in the near future.
+         It has been replaced by the PID algorithm.
+
+         Say N unless you know what you are doing.
+endmenu
 
 config MAC80211_LEDS
        bool "Enable LED triggers"
        depends on MAC80211 && LEDS_TRIGGERS
        ---help---
-       This option enables a few LED triggers for different
-       packet receive/transmit events.
+         This option enables a few LED triggers for different
+         packet receive/transmit events.
 
 config MAC80211_DEBUGFS
        bool "Export mac80211 internals in DebugFS"
@@ -51,6 +108,16 @@ config MAC80211_DEBUG
          If you are not trying to debug or develop the ieee80211
          subsystem, you most likely want to say N here.
 
+config MAC80211_HT_DEBUG
+       bool "Enable HT debugging output"
+       depends on MAC80211_DEBUG
+       ---help---
+         This option enables 802.11n High Throughput features
+         debug tracing output.
+
+         If you are not trying to debug of develop the ieee80211
+         subsystem, you most likely want to say N here.
+
 config MAC80211_VERBOSE_DEBUG
        bool "Verbose debugging output"
        depends on MAC80211_DEBUG
index 1e6237b3484662ffe65a207a3a35a5bbd202f7d2..54f46bc80cfed4574f22d4dfa4e6cefbfaadf1b4 100644 (file)
@@ -1,11 +1,15 @@
 obj-$(CONFIG_MAC80211) += mac80211.o
 
-mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
-mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
-mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
-mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o
+# objects for PID algorithm
+rc80211_pid-y := rc80211_pid_algo.o
+rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
 
-mac80211-objs := \
+# build helper for PID algorithm
+rc-pid-y := $(rc80211_pid-y)
+rc-pid-m := rc80211_pid.o
+
+# mac80211 objects
+mac80211-y := \
        ieee80211.o \
        ieee80211_ioctl.o \
        sta_info.o \
@@ -23,5 +27,22 @@ mac80211-objs := \
        tx.o \
        key.o \
        util.o \
-       event.o \
-       $(mac80211-objs-y)
+       event.o
+
+mac80211-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
+mac80211-$(CONFIG_NET_SCHED) += wme.o
+mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
+       debugfs.o \
+       debugfs_sta.o \
+       debugfs_netdev.o \
+       debugfs_key.o
+
+
+# Build rate control algorithm(s)
+CFLAGS_rc80211_simple.o += -DRC80211_SIMPLE_COMPILE
+CFLAGS_rc80211_pid_algo.o += -DRC80211_PID_COMPILE
+mac80211-$(CONFIG_MAC80211_RC_SIMPLE) += rc80211_simple.o
+mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc-pid-$(CONFIG_MAC80211_RC_PID))
+
+# Modular rate algorithms are assigned to mac80211-m - make separate modules
+obj-m += $(mac80211-m)
index 9e2bc1fd0237dd83dc1bf923c3cb773bce79cf7d..22c9619ba7760e0d9e49c8fa8262a08f9deb6c64 100644 (file)
@@ -1,17 +1,20 @@
 /*
  * mac80211 configuration hooks for cfg80211
  *
- * Copyright 2006      Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006, 2007        Johannes Berg <johannes@sipsolutions.net>
  *
  * This file is GPLv2 as found in COPYING.
  */
 
+#include <linux/ieee80211.h>
 #include <linux/nl80211.h>
 #include <linux/rtnetlink.h>
 #include <net/net_namespace.h>
+#include <linux/rcupdate.h>
 #include <net/cfg80211.h>
 #include "ieee80211_i.h"
 #include "cfg.h"
+#include "ieee80211_rate.h"
 
 static enum ieee80211_if_types
 nl80211_type_to_mac80211_type(enum nl80211_iftype type)
@@ -90,7 +93,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-        if (sdata->type == IEEE80211_IF_TYPE_VLAN)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
                return -EOPNOTSUPP;
 
        ieee80211_if_reinit(dev);
@@ -99,8 +102,553 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
        return 0;
 }
 
+static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
+                            u8 key_idx, u8 *mac_addr,
+                            struct key_params *params)
+{
+       struct ieee80211_sub_if_data *sdata;
+       struct sta_info *sta = NULL;
+       enum ieee80211_key_alg alg;
+       int ret;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       switch (params->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               alg = ALG_WEP;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               alg = ALG_TKIP;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               alg = ALG_CCMP;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (mac_addr) {
+               sta = sta_info_get(sdata->local, mac_addr);
+               if (!sta)
+                       return -ENOENT;
+       }
+
+       ret = 0;
+       if (!ieee80211_key_alloc(sdata, sta, alg, key_idx,
+                                params->key_len, params->key))
+               ret = -ENOMEM;
+
+       if (sta)
+               sta_info_put(sta);
+
+       return ret;
+}
+
+static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
+                            u8 key_idx, u8 *mac_addr)
+{
+       struct ieee80211_sub_if_data *sdata;
+       struct sta_info *sta;
+       int ret;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (mac_addr) {
+               sta = sta_info_get(sdata->local, mac_addr);
+               if (!sta)
+                       return -ENOENT;
+
+               ret = 0;
+               if (sta->key)
+                       ieee80211_key_free(sta->key);
+               else
+                       ret = -ENOENT;
+
+               sta_info_put(sta);
+               return ret;
+       }
+
+       if (!sdata->keys[key_idx])
+               return -ENOENT;
+
+       ieee80211_key_free(sdata->keys[key_idx]);
+
+       return 0;
+}
+
+static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
+                            u8 key_idx, u8 *mac_addr, void *cookie,
+                            void (*callback)(void *cookie,
+                                             struct key_params *params))
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct sta_info *sta = NULL;
+       u8 seq[6] = {0};
+       struct key_params params;
+       struct ieee80211_key *key;
+       u32 iv32;
+       u16 iv16;
+       int err = -ENOENT;
+
+       if (mac_addr) {
+               sta = sta_info_get(sdata->local, mac_addr);
+               if (!sta)
+                       goto out;
+
+               key = sta->key;
+       } else
+               key = sdata->keys[key_idx];
+
+       if (!key)
+               goto out;
+
+       memset(&params, 0, sizeof(params));
+
+       switch (key->conf.alg) {
+       case ALG_TKIP:
+               params.cipher = WLAN_CIPHER_SUITE_TKIP;
+
+               iv32 = key->u.tkip.iv32;
+               iv16 = key->u.tkip.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);
+
+               seq[0] = iv16 & 0xff;
+               seq[1] = (iv16 >> 8) & 0xff;
+               seq[2] = iv32 & 0xff;
+               seq[3] = (iv32 >> 8) & 0xff;
+               seq[4] = (iv32 >> 16) & 0xff;
+               seq[5] = (iv32 >> 24) & 0xff;
+               params.seq = seq;
+               params.seq_len = 6;
+               break;
+       case ALG_CCMP:
+               params.cipher = WLAN_CIPHER_SUITE_CCMP;
+               seq[0] = key->u.ccmp.tx_pn[5];
+               seq[1] = key->u.ccmp.tx_pn[4];
+               seq[2] = key->u.ccmp.tx_pn[3];
+               seq[3] = key->u.ccmp.tx_pn[2];
+               seq[4] = key->u.ccmp.tx_pn[1];
+               seq[5] = key->u.ccmp.tx_pn[0];
+               params.seq = seq;
+               params.seq_len = 6;
+               break;
+       case ALG_WEP:
+               if (key->conf.keylen == 5)
+                       params.cipher = WLAN_CIPHER_SUITE_WEP40;
+               else
+                       params.cipher = WLAN_CIPHER_SUITE_WEP104;
+               break;
+       }
+
+       params.key = key->conf.key;
+       params.key_len = key->conf.keylen;
+
+       callback(cookie, &params);
+       err = 0;
+
+ out:
+       if (sta)
+               sta_info_put(sta);
+       return err;
+}
+
+static int ieee80211_config_default_key(struct wiphy *wiphy,
+                                       struct net_device *dev,
+                                       u8 key_idx)
+{
+       struct ieee80211_sub_if_data *sdata;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       ieee80211_set_default_key(sdata, key_idx);
+
+       return 0;
+}
+
+static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+                                u8 *mac, struct station_stats *stats)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+
+       sta = sta_info_get(local, mac);
+       if (!sta)
+               return -ENOENT;
+
+       /* XXX: verify sta->dev == dev */
+
+       stats->filled = STATION_STAT_INACTIVE_TIME |
+                       STATION_STAT_RX_BYTES |
+                       STATION_STAT_TX_BYTES;
+
+       stats->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
+       stats->rx_bytes = sta->rx_bytes;
+       stats->tx_bytes = sta->tx_bytes;
+
+       sta_info_put(sta);
+
+       return 0;
+}
+
+/*
+ * This handles both adding a beacon and setting new beacon info
+ */
+static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
+                                  struct beacon_parameters *params)
+{
+       struct beacon_data *new, *old;
+       int new_head_len, new_tail_len;
+       int size;
+       int err = -EINVAL;
+
+       old = sdata->u.ap.beacon;
+
+       /* head must not be zero-length */
+       if (params->head && !params->head_len)
+               return -EINVAL;
+
+       /*
+        * 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;
+               if (ieee80211_hw_config(sdata->local))
+                       return -EINVAL;
+               /*
+                * We updated some parameter so if below bails out
+                * it's not an error.
+                */
+               err = 0;
+       }
+
+       /* Need to have a beacon head if we don't have one yet */
+       if (!params->head && !old)
+               return err;
+
+       /* sorry, no way to start beaconing without dtim period */
+       if (!params->dtim_period && !old)
+               return err;
+
+       /* new or old head? */
+       if (params->head)
+               new_head_len = params->head_len;
+       else
+               new_head_len = old->head_len;
+
+       /* new or old tail? */
+       if (params->tail || !old)
+               /* params->tail_len will be zero for !params->tail */
+               new_tail_len = params->tail_len;
+       else
+               new_tail_len = old->tail_len;
+
+       size = sizeof(*new) + new_head_len + new_tail_len;
+
+       new = kzalloc(size, GFP_KERNEL);
+       if (!new)
+               return -ENOMEM;
+
+       /* start filling the new info now */
+
+       /* new or old dtim period? */
+       if (params->dtim_period)
+               new->dtim_period = params->dtim_period;
+       else
+               new->dtim_period = old->dtim_period;
+
+       /*
+        * pointers go into the block we allocated,
+        * memory is | beacon_data | head | tail |
+        */
+       new->head = ((u8 *) new) + sizeof(*new);
+       new->tail = new->head + new_head_len;
+       new->head_len = new_head_len;
+       new->tail_len = new_tail_len;
+
+       /* copy in head */
+       if (params->head)
+               memcpy(new->head, params->head, new_head_len);
+       else
+               memcpy(new->head, old->head, new_head_len);
+
+       /* copy in optional tail */
+       if (params->tail)
+               memcpy(new->tail, params->tail, new_tail_len);
+       else
+               if (old)
+                       memcpy(new->tail, old->tail, new_tail_len);
+
+       rcu_assign_pointer(sdata->u.ap.beacon, new);
+
+       synchronize_rcu();
+
+       kfree(old);
+
+       return ieee80211_if_config_beacon(sdata->dev);
+}
+
+static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
+                               struct beacon_parameters *params)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct beacon_data *old;
+
+       if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
+               return -EINVAL;
+
+       old = sdata->u.ap.beacon;
+
+       if (old)
+               return -EALREADY;
+
+       return ieee80211_config_beacon(sdata, params);
+}
+
+static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
+                               struct beacon_parameters *params)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct beacon_data *old;
+
+       if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
+               return -EINVAL;
+
+       old = sdata->u.ap.beacon;
+
+       if (!old)
+               return -ENOENT;
+
+       return ieee80211_config_beacon(sdata, params);
+}
+
+static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct beacon_data *old;
+
+       if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
+               return -EINVAL;
+
+       old = sdata->u.ap.beacon;
+
+       if (!old)
+               return -ENOENT;
+
+       rcu_assign_pointer(sdata->u.ap.beacon, NULL);
+       synchronize_rcu();
+       kfree(old);
+
+       return ieee80211_if_config_beacon(dev);
+}
+
+/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
+struct iapp_layer2_update {
+       u8 da[ETH_ALEN];        /* broadcast */
+       u8 sa[ETH_ALEN];        /* STA addr */
+       __be16 len;             /* 6 */
+       u8 dsap;                /* 0 */
+       u8 ssap;                /* 0 */
+       u8 control;
+       u8 xid_info[3];
+} __attribute__ ((packed));
+
+static void ieee80211_send_layer2_update(struct sta_info *sta)
+{
+       struct iapp_layer2_update *msg;
+       struct sk_buff *skb;
+
+       /* Send Level 2 Update Frame to update forwarding tables in layer 2
+        * bridge devices */
+
+       skb = dev_alloc_skb(sizeof(*msg));
+       if (!skb)
+               return;
+       msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
+
+       /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
+        * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
+
+       memset(msg->da, 0xff, ETH_ALEN);
+       memcpy(msg->sa, sta->addr, ETH_ALEN);
+       msg->len = htons(6);
+       msg->dsap = 0;
+       msg->ssap = 0x01;       /* NULL LSAP, CR Bit: Response */
+       msg->control = 0xaf;    /* XID response lsb.1111F101.
+                                * F=0 (no poll command; unsolicited frame) */
+       msg->xid_info[0] = 0x81;        /* XID format identifier */
+       msg->xid_info[1] = 1;   /* LLC types/classes: Type 1 LLC */
+       msg->xid_info[2] = 0;   /* XID sender's receive window size (RW) */
+
+       skb->dev = sta->dev;
+       skb->protocol = eth_type_trans(skb, sta->dev);
+       memset(skb->cb, 0, sizeof(skb->cb));
+       netif_rx(skb);
+}
+
+static void sta_apply_parameters(struct ieee80211_local *local,
+                                struct sta_info *sta,
+                                struct station_parameters *params)
+{
+       u32 rates;
+       int i, j;
+       struct ieee80211_hw_mode *mode;
+
+       if (params->station_flags & STATION_FLAG_CHANGED) {
+               sta->flags &= ~WLAN_STA_AUTHORIZED;
+               if (params->station_flags & STATION_FLAG_AUTHORIZED)
+                       sta->flags |= WLAN_STA_AUTHORIZED;
+
+               sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
+               if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
+                       sta->flags |= WLAN_STA_SHORT_PREAMBLE;
+
+               sta->flags &= ~WLAN_STA_WME;
+               if (params->station_flags & STATION_FLAG_WME)
+                       sta->flags |= WLAN_STA_WME;
+       }
+
+       if (params->aid) {
+               sta->aid = params->aid;
+               if (sta->aid > IEEE80211_MAX_AID)
+                       sta->aid = 0; /* XXX: should this be an error? */
+       }
+
+       if (params->listen_interval >= 0)
+               sta->listen_interval = params->listen_interval;
+
+       if (params->supported_rates) {
+               rates = 0;
+               mode = local->oper_hw_mode;
+               for (i = 0; i < params->supported_rates_len; i++) {
+                       int rate = (params->supported_rates[i] & 0x7f) * 5;
+                       for (j = 0; j < mode->num_rates; j++) {
+                               if (mode->rates[j].rate == rate)
+                                       rates |= BIT(j);
+                       }
+               }
+               sta->supp_rates = rates;
+       }
+}
+
+static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
+                                u8 *mac, struct station_parameters *params)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+       struct ieee80211_sub_if_data *sdata;
+
+       /* Prevent a race with changing the rate control algorithm */
+       if (!netif_running(dev))
+               return -ENETDOWN;
+
+       /* XXX: get sta belonging to dev */
+       sta = sta_info_get(local, mac);
+       if (sta) {
+               sta_info_put(sta);
+               return -EEXIST;
+       }
+
+       if (params->vlan) {
+               sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
+
+               if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
+                   sdata->vif.type != IEEE80211_IF_TYPE_AP)
+                       return -EINVAL;
+       } else
+               sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       sta = sta_info_add(local, dev, mac, GFP_KERNEL);
+       if (!sta)
+               return -ENOMEM;
+
+       sta->dev = sdata->dev;
+       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
+           sdata->vif.type == IEEE80211_IF_TYPE_AP)
+               ieee80211_send_layer2_update(sta);
+
+       sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
+
+       sta_apply_parameters(local, sta, params);
+
+       rate_control_rate_init(sta, local);
+
+       sta_info_put(sta);
+
+       return 0;
+}
+
+static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
+                                u8 *mac)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+
+       if (mac) {
+               /* XXX: get sta belonging to dev */
+               sta = sta_info_get(local, mac);
+               if (!sta)
+                       return -ENOENT;
+
+               sta_info_free(sta);
+               sta_info_put(sta);
+       } else
+               sta_info_flush(local, dev);
+
+       return 0;
+}
+
+static int ieee80211_change_station(struct wiphy *wiphy,
+                                   struct net_device *dev,
+                                   u8 *mac,
+                                   struct station_parameters *params)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+       struct ieee80211_sub_if_data *vlansdata;
+
+       /* XXX: get sta belonging to dev */
+       sta = sta_info_get(local, mac);
+       if (!sta)
+               return -ENOENT;
+
+       if (params->vlan && params->vlan != sta->dev) {
+               vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
+
+               if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
+                   vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
+                       return -EINVAL;
+
+               sta->dev = params->vlan;
+               ieee80211_send_layer2_update(sta);
+       }
+
+       sta_apply_parameters(local, sta, params);
+
+       sta_info_put(sta);
+
+       return 0;
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
        .change_virtual_intf = ieee80211_change_iface,
+       .add_key = ieee80211_add_key,
+       .del_key = ieee80211_del_key,
+       .get_key = ieee80211_get_key,
+       .set_default_key = ieee80211_config_default_key,
+       .add_beacon = ieee80211_add_beacon,
+       .set_beacon = ieee80211_set_beacon,
+       .del_beacon = ieee80211_del_beacon,
+       .add_station = ieee80211_add_station,
+       .del_station = ieee80211_del_station,
+       .change_station = ieee80211_change_station,
+       .get_station = ieee80211_get_station,
 };
index f0e6ab7eb624dbd937b5e272b2c3e285c4140ad3..829872a3ae8148d1069c2a898249a97b4098c400 100644 (file)
@@ -91,8 +91,7 @@ static const struct file_operations name##_ops = {                    \
 /* common attributes */
 IEEE80211_IF_FILE(channel_use, channel_use, DEC);
 IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
-IEEE80211_IF_FILE(eapol, eapol, DEC);
-IEEE80211_IF_FILE(ieee8021_x, ieee802_1x, DEC);
+IEEE80211_IF_FILE(ieee802_1x_pac, ieee802_1x_pac, DEC);
 
 /* STA/IBSS attributes */
 IEEE80211_IF_FILE(state, u.sta.state, DEC);
@@ -119,13 +118,12 @@ static ssize_t ieee80211_if_fmt_flags(
                 sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
                 sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
                 sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
-                sdata->flags & IEEE80211_SDATA_USE_PROTECTION ? "CTS prot\n" : "");
+                sdata->bss_conf.use_cts_prot ? "CTS prot\n" : "");
 }
 __IEEE80211_IF_FILE(flags);
 
 /* AP attributes */
 IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
-IEEE80211_IF_FILE(dtim_period, u.ap.dtim_period, DEC);
 IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
 IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC);
 IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC);
@@ -139,26 +137,6 @@ static ssize_t ieee80211_if_fmt_num_buffered_multicast(
 }
 __IEEE80211_IF_FILE(num_buffered_multicast);
 
-static ssize_t ieee80211_if_fmt_beacon_head_len(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       if (sdata->u.ap.beacon_head)
-               return scnprintf(buf, buflen, "%d\n",
-                                sdata->u.ap.beacon_head_len);
-       return scnprintf(buf, buflen, "\n");
-}
-__IEEE80211_IF_FILE(beacon_head_len);
-
-static ssize_t ieee80211_if_fmt_beacon_tail_len(
-       const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
-{
-       if (sdata->u.ap.beacon_tail)
-               return scnprintf(buf, buflen, "%d\n",
-                                sdata->u.ap.beacon_tail_len);
-       return scnprintf(buf, buflen, "\n");
-}
-__IEEE80211_IF_FILE(beacon_tail_len);
-
 /* WDS attributes */
 IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
 
@@ -170,8 +148,7 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_ADD(channel_use, sta);
        DEBUGFS_ADD(drop_unencrypted, sta);
-       DEBUGFS_ADD(eapol, sta);
-       DEBUGFS_ADD(ieee8021_x, sta);
+       DEBUGFS_ADD(ieee802_1x_pac, sta);
        DEBUGFS_ADD(state, sta);
        DEBUGFS_ADD(bssid, sta);
        DEBUGFS_ADD(prev_bssid, sta);
@@ -192,25 +169,20 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_ADD(channel_use, ap);
        DEBUGFS_ADD(drop_unencrypted, ap);
-       DEBUGFS_ADD(eapol, ap);
-       DEBUGFS_ADD(ieee8021_x, ap);
+       DEBUGFS_ADD(ieee802_1x_pac, ap);
        DEBUGFS_ADD(num_sta_ps, ap);
-       DEBUGFS_ADD(dtim_period, ap);
        DEBUGFS_ADD(dtim_count, ap);
        DEBUGFS_ADD(num_beacons, ap);
        DEBUGFS_ADD(force_unicast_rateidx, ap);
        DEBUGFS_ADD(max_ratectrl_rateidx, ap);
        DEBUGFS_ADD(num_buffered_multicast, ap);
-       DEBUGFS_ADD(beacon_head_len, ap);
-       DEBUGFS_ADD(beacon_tail_len, ap);
 }
 
 static void add_wds_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_ADD(channel_use, wds);
        DEBUGFS_ADD(drop_unencrypted, wds);
-       DEBUGFS_ADD(eapol, wds);
-       DEBUGFS_ADD(ieee8021_x, wds);
+       DEBUGFS_ADD(ieee802_1x_pac, wds);
        DEBUGFS_ADD(peer, wds);
 }
 
@@ -218,8 +190,7 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_ADD(channel_use, vlan);
        DEBUGFS_ADD(drop_unencrypted, vlan);
-       DEBUGFS_ADD(eapol, vlan);
-       DEBUGFS_ADD(ieee8021_x, vlan);
+       DEBUGFS_ADD(ieee802_1x_pac, vlan);
 }
 
 static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
@@ -231,7 +202,7 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
        if (!sdata->debugfsdir)
                return;
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_STA:
        case IEEE80211_IF_TYPE_IBSS:
                add_sta_files(sdata);
@@ -263,8 +234,7 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_DEL(channel_use, sta);
        DEBUGFS_DEL(drop_unencrypted, sta);
-       DEBUGFS_DEL(eapol, sta);
-       DEBUGFS_DEL(ieee8021_x, sta);
+       DEBUGFS_DEL(ieee802_1x_pac, sta);
        DEBUGFS_DEL(state, sta);
        DEBUGFS_DEL(bssid, sta);
        DEBUGFS_DEL(prev_bssid, sta);
@@ -285,25 +255,20 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_DEL(channel_use, ap);
        DEBUGFS_DEL(drop_unencrypted, ap);
-       DEBUGFS_DEL(eapol, ap);
-       DEBUGFS_DEL(ieee8021_x, ap);
+       DEBUGFS_DEL(ieee802_1x_pac, ap);
        DEBUGFS_DEL(num_sta_ps, ap);
-       DEBUGFS_DEL(dtim_period, ap);
        DEBUGFS_DEL(dtim_count, ap);
        DEBUGFS_DEL(num_beacons, ap);
        DEBUGFS_DEL(force_unicast_rateidx, ap);
        DEBUGFS_DEL(max_ratectrl_rateidx, ap);
        DEBUGFS_DEL(num_buffered_multicast, ap);
-       DEBUGFS_DEL(beacon_head_len, ap);
-       DEBUGFS_DEL(beacon_tail_len, ap);
 }
 
 static void del_wds_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_DEL(channel_use, wds);
        DEBUGFS_DEL(drop_unencrypted, wds);
-       DEBUGFS_DEL(eapol, wds);
-       DEBUGFS_DEL(ieee8021_x, wds);
+       DEBUGFS_DEL(ieee802_1x_pac, wds);
        DEBUGFS_DEL(peer, wds);
 }
 
@@ -311,8 +276,7 @@ static void del_vlan_files(struct ieee80211_sub_if_data *sdata)
 {
        DEBUGFS_DEL(channel_use, vlan);
        DEBUGFS_DEL(drop_unencrypted, vlan);
-       DEBUGFS_DEL(eapol, vlan);
-       DEBUGFS_DEL(ieee8021_x, vlan);
+       DEBUGFS_DEL(ieee802_1x_pac, vlan);
 }
 
 static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
@@ -362,7 +326,7 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
 
 void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata)
 {
-       del_files(sdata, sdata->type);
+       del_files(sdata, sdata->vif.type);
        debugfs_remove(sdata->debugfsdir);
        sdata->debugfsdir = NULL;
 }
index 6378850d85805860416e9e67f7b0e308e76e6e0a..5dcc2d61551fe2260f5a39e6fe323669b705323b 100644 (file)
@@ -34,6 +34,8 @@
 #include "debugfs.h"
 #include "debugfs_netdev.h"
 
+#define SUPP_MCS_SET_LEN 16
+
 /*
  * For seeing transmitted packets on monitor interfaces
  * we have a radiotap header too.
@@ -175,21 +177,21 @@ static int ieee80211_open(struct net_device *dev)
                        /*
                         * check whether it may have the same address
                         */
-                       if (!identical_mac_addr_allowed(sdata->type,
-                                                       nsdata->type))
+                       if (!identical_mac_addr_allowed(sdata->vif.type,
+                                                       nsdata->vif.type))
                                return -ENOTUNIQ;
 
                        /*
                         * can only add VLANs to enabled APs
                         */
-                       if (sdata->type == IEEE80211_IF_TYPE_VLAN &&
-                           nsdata->type == IEEE80211_IF_TYPE_AP &&
+                       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN &&
+                           nsdata->vif.type == IEEE80211_IF_TYPE_AP &&
                            netif_running(nsdata->dev))
                                sdata->u.vlan.ap = nsdata;
                }
        }
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_WDS:
                if (is_zero_ether_addr(sdata->u.wds.remote_addr))
                        return -ENOLINK;
@@ -217,9 +219,10 @@ static int ieee80211_open(struct net_device *dev)
                if (res)
                        return res;
                ieee80211_hw_config(local);
+               ieee80211_led_radio(local, local->hw.conf.radio_enabled);
        }
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_VLAN:
                list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans);
                /* no need to tell driver */
@@ -240,8 +243,8 @@ static int ieee80211_open(struct net_device *dev)
                sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
                /* fall through */
        default:
-               conf.if_id = dev->ifindex;
-               conf.type = sdata->type;
+               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);
                if (res && !local->open_count && local->ops->stop)
@@ -253,7 +256,7 @@ static int ieee80211_open(struct net_device *dev)
                ieee80211_reset_erp_info(dev);
                ieee80211_enable_keys(sdata);
 
-               if (sdata->type == IEEE80211_IF_TYPE_STA &&
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
                    !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
                        netif_carrier_off(dev);
                else
@@ -290,9 +293,20 @@ static int ieee80211_stop(struct net_device *dev)
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_if_init_conf conf;
+       struct sta_info *sta;
+       int i;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
+       list_for_each_entry(sta, &local->sta_list, list) {
+               if (sta->dev == dev)
+                       for (i = 0; i <  STA_TID_NUM; i++)
+                               ieee80211_sta_stop_rx_ba_session(sta->dev,
+                                               sta->addr, i,
+                                               WLAN_BACK_RECIPIENT,
+                                               WLAN_REASON_QSTA_LEAVE_QBSS);
+       }
+
        netif_stop_queue(dev);
 
        /*
@@ -309,10 +323,17 @@ static int ieee80211_stop(struct net_device *dev)
 
        dev_mc_unsync(local->mdev, dev);
 
-       /* down all dependent devices, that is VLANs */
-       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       /* APs need special treatment */
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                struct ieee80211_sub_if_data *vlan, *tmp;
+               struct beacon_data *old_beacon = sdata->u.ap.beacon;
 
+               /* remove beacon */
+               rcu_assign_pointer(sdata->u.ap.beacon, NULL);
+               synchronize_rcu();
+               kfree(old_beacon);
+
+               /* down all dependent devices, that is VLANs */
                list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans,
                                         u.vlan.list)
                        dev_close(vlan->dev);
@@ -321,7 +342,7 @@ static int ieee80211_stop(struct net_device *dev)
 
        local->open_count--;
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_VLAN:
                list_del(&sdata->u.vlan.list);
                sdata->u.vlan.ap = NULL;
@@ -350,11 +371,14 @@ static int ieee80211_stop(struct net_device *dev)
                synchronize_rcu();
                skb_queue_purge(&sdata->u.sta.skb_queue);
 
-               if (!local->ops->hw_scan &&
-                   local->scan_dev == sdata->dev) {
-                       local->sta_scanning = 0;
-                       cancel_delayed_work(&local->scan_work);
+               if (local->scan_dev == sdata->dev) {
+                       if (!local->ops->hw_scan) {
+                               local->sta_sw_scanning = 0;
+                               cancel_delayed_work(&local->scan_work);
+                       } else
+                               local->sta_hw_scanning = 0;
                }
+
                flush_workqueue(local->hw.workqueue);
 
                sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
@@ -363,8 +387,8 @@ static int ieee80211_stop(struct net_device *dev)
                sdata->u.sta.extra_ie_len = 0;
                /* fall through */
        default:
-               conf.if_id = dev->ifindex;
-               conf.type = sdata->type;
+               conf.vif = &sdata->vif;
+               conf.type = sdata->vif.type;
                conf.mac_addr = dev->dev_addr;
                /* disable all keys for as long as this netdev is down */
                ieee80211_disable_keys(sdata);
@@ -378,6 +402,8 @@ static int ieee80211_stop(struct net_device *dev)
                if (local->ops->stop)
                        local->ops->stop(local_to_hw(local));
 
+               ieee80211_led_radio(local, 0);
+
                tasklet_disable(&local->tx_pending_tasklet);
                tasklet_disable(&local->tasklet);
        }
@@ -485,20 +511,20 @@ static int __ieee80211_if_config(struct net_device *dev,
                return 0;
 
        memset(&conf, 0, sizeof(conf));
-       conf.type = sdata->type;
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       conf.type = sdata->vif.type;
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                conf.bssid = sdata->u.sta.bssid;
                conf.ssid = sdata->u.sta.ssid;
                conf.ssid_len = sdata->u.sta.ssid_len;
-       } else if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                conf.ssid = sdata->u.ap.ssid;
                conf.ssid_len = sdata->u.ap.ssid_len;
                conf.beacon = beacon;
                conf.beacon_control = control;
        }
        return local->ops->config_interface(local_to_hw(local),
-                                          dev->ifindex, &conf);
+                                           &sdata->vif, &conf);
 }
 
 int ieee80211_if_config(struct net_device *dev)
@@ -510,11 +536,13 @@ int ieee80211_if_config_beacon(struct net_device *dev)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_tx_control control;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sk_buff *skb;
 
        if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE))
                return 0;
-       skb = ieee80211_beacon_get(local_to_hw(local), dev->ifindex, &control);
+       skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif,
+                                  &control);
        if (!skb)
                return -ENOMEM;
        return __ieee80211_if_config(dev, skb, &control);
@@ -526,7 +554,7 @@ int ieee80211_hw_config(struct ieee80211_local *local)
        struct ieee80211_channel *chan;
        int ret = 0;
 
-       if (local->sta_scanning) {
+       if (local->sta_sw_scanning) {
                chan = local->scan_channel;
                mode = local->scan_hw_mode;
        } else {
@@ -560,25 +588,79 @@ int ieee80211_hw_config(struct ieee80211_local *local)
        return ret;
 }
 
-void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes)
+/**
+ * ieee80211_hw_config_ht should be used only after legacy configuration
+ * has been determined, as ht configuration depends upon the hardware's
+ * HT abilities for a _specific_ band.
+ */
+int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht,
+                          struct ieee80211_ht_info *req_ht_cap,
+                          struct ieee80211_ht_bss_info *req_bss_cap)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (local->ops->erp_ie_changed)
-               local->ops->erp_ie_changed(local_to_hw(local), changes,
-                       !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION),
-                       !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE));
+       struct ieee80211_conf *conf = &local->hw.conf;
+       struct ieee80211_hw_mode *mode = conf->mode;
+       int i;
+
+       /* HT is not supported */
+       if (!mode->ht_info.ht_supported) {
+               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
+               return -EOPNOTSUPP;
+       }
+
+       /* disable HT */
+       if (!enable_ht) {
+               conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE;
+       } else {
+               conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE;
+               conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap;
+               conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS);
+               conf->ht_conf.cap |=
+                       mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS;
+               conf->ht_bss_conf.primary_channel =
+                       req_bss_cap->primary_channel;
+               conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
+               conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
+               for (i = 0; i < SUPP_MCS_SET_LEN; i++)
+                       conf->ht_conf.supp_mcs_set[i] =
+                               mode->ht_info.supp_mcs_set[i] &
+                                 req_ht_cap->supp_mcs_set[i];
+
+               /* In STA mode, this gives us indication
+                * to the AP's mode of operation */
+               conf->ht_conf.ht_supported = 1;
+               conf->ht_conf.ampdu_factor = req_ht_cap->ampdu_factor;
+               conf->ht_conf.ampdu_density = req_ht_cap->ampdu_density;
+       }
+
+       local->ops->conf_ht(local_to_hw(local), &local->hw.conf);
+
+       return 0;
+}
+
+void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
+                                     u32 changed)
+{
+       struct ieee80211_local *local = sdata->local;
+
+       if (!changed)
+               return;
+
+       if (local->ops->bss_info_changed)
+               local->ops->bss_info_changed(local_to_hw(local),
+                                            &sdata->vif,
+                                            &sdata->bss_conf,
+                                            changed);
 }
 
 void ieee80211_reset_erp_info(struct net_device *dev)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       sdata->flags &= ~(IEEE80211_SDATA_USE_PROTECTION |
-                       IEEE80211_SDATA_SHORT_PREAMBLE);
-       ieee80211_erp_info_change_notify(dev,
-                                        IEEE80211_ERP_CHANGE_PROTECTION |
-                                        IEEE80211_ERP_CHANGE_PREAMBLE);
+       sdata->bss_conf.use_cts_prot = 0;
+       sdata->bss_conf.use_short_preamble = 0;
+       ieee80211_bss_info_change_notify(sdata,
+                                        BSS_CHANGED_ERP_CTS_PROT |
+                                        BSS_CHANGED_ERP_PREAMBLE);
 }
 
 void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
@@ -635,7 +717,7 @@ static void ieee80211_tasklet_handler(unsigned long data)
                case IEEE80211_RX_MSG:
                        /* status is in skb->cb */
                        memcpy(&rx_status, skb->cb, sizeof(rx_status));
-                       /* Clear skb->type in order to not confuse kernel
+                       /* Clear skb->pkt_type in order to not confuse kernel
                         * netstack. */
                        skb->pkt_type = 0;
                        __ieee80211_rx(local_to_hw(local), skb, &rx_status);
@@ -670,7 +752,7 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
        struct ieee80211_tx_packet_data *pkt_data;
 
        pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-       pkt_data->ifindex = control->ifindex;
+       pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex;
        pkt_data->flags = 0;
        if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS)
                pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
@@ -678,6 +760,8 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
                pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
        if (control->flags & IEEE80211_TXCTL_REQUEUE)
                pkt_data->flags |= IEEE80211_TXPD_REQUEUE;
+       if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME)
+               pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
        pkt_data->queue = control->queue;
 
        hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -805,10 +889,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
                        sta_info_put(sta);
                        return;
                }
-       } else {
-               /* FIXME: STUPID to call this with both local and local->mdev */
-               rate_control_tx_status(local, local->mdev, skb, status);
-       }
+       } else
+               rate_control_tx_status(local->mdev, skb, status);
 
        ieee80211_led_tx(local, 0);
 
@@ -894,7 +976,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
                if (!monitors || !skb)
                        goto out;
 
-               if (sdata->type == IEEE80211_IF_TYPE_MNTR) {
+               if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) {
                        if (!netif_running(sdata->dev))
                                continue;
                        monitors--;
@@ -1016,7 +1098,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        mdev->header_ops = &ieee80211_header_ops;
        mdev->set_multicast_list = ieee80211_master_set_multicast_list;
 
-       sdata->type = IEEE80211_IF_TYPE_AP;
+       sdata->vif.type = IEEE80211_IF_TYPE_AP;
        sdata->dev = mdev;
        sdata->local = local;
        sdata->u.ap.force_unicast_rateidx = -1;
@@ -1260,33 +1342,38 @@ static int __init ieee80211_init(void)
 
        BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
 
-#ifdef CONFIG_MAC80211_RCSIMPLE
-       ret = ieee80211_rate_control_register(&mac80211_rcsimple);
+       ret = rc80211_simple_init();
        if (ret)
-               return ret;
-#endif
+               goto fail;
+
+       ret = rc80211_pid_init();
+       if (ret)
+               goto fail_simple;
 
        ret = ieee80211_wme_register();
        if (ret) {
-#ifdef CONFIG_MAC80211_RCSIMPLE
-               ieee80211_rate_control_unregister(&mac80211_rcsimple);
-#endif
                printk(KERN_DEBUG "ieee80211_init: failed to "
                       "initialize WME (err=%d)\n", ret);
-               return ret;
+               goto fail_pid;
        }
 
        ieee80211_debugfs_netdev_init();
        ieee80211_regdomain_init();
 
        return 0;
+
+ fail_pid:
+       rc80211_simple_exit();
+ fail_simple:
+       rc80211_pid_exit();
+ fail:
+       return ret;
 }
 
 static void __exit ieee80211_exit(void)
 {
-#ifdef CONFIG_MAC80211_RCSIMPLE
-       ieee80211_rate_control_unregister(&mac80211_rcsimple);
-#endif
+       rc80211_simple_exit();
+       rc80211_pid_exit();
 
        ieee80211_wme_unregister();
        ieee80211_debugfs_netdev_exit();
index 72e1c93dd87e4f2bfe520c57d753bb2354a1be44..72ecbf7bf962d7d5f8d96465c2752cf9e512c088 100644 (file)
@@ -89,6 +89,8 @@ struct ieee80211_sta_bss {
        size_t rsn_ie_len;
        u8 *wmm_ie;
        size_t wmm_ie_len;
+       u8 *ht_ie;
+       size_t ht_ie_len;
 #define IEEE80211_MAX_SUPP_RATES 32
        u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
        size_t supp_rates_len;
@@ -121,6 +123,7 @@ typedef enum {
 /* frame is destined to interface currently processed (incl. multicast frames) */
 #define IEEE80211_TXRXD_RXRA_MATCH             BIT(5)
 #define IEEE80211_TXRXD_TX_INJECTED            BIT(6)
+#define IEEE80211_TXRXD_RX_AMSDU               BIT(7)
 struct ieee80211_txrx_data {
        struct sk_buff *skb;
        struct net_device *dev;
@@ -161,6 +164,7 @@ struct ieee80211_txrx_data {
 #define IEEE80211_TXPD_REQ_TX_STATUS   BIT(0)
 #define IEEE80211_TXPD_DO_NOT_ENCRYPT  BIT(1)
 #define IEEE80211_TXPD_REQUEUE         BIT(2)
+#define IEEE80211_TXPD_EAPOL_FRAME     BIT(3)
 /* Stored in sk_buff->cb */
 struct ieee80211_tx_packet_data {
        int ifindex;
@@ -186,9 +190,14 @@ typedef ieee80211_txrx_result (*ieee80211_tx_handler)
 typedef ieee80211_txrx_result (*ieee80211_rx_handler)
 (struct ieee80211_txrx_data *rx);
 
+struct beacon_data {
+       u8 *head, *tail;
+       int head_len, tail_len;
+       int dtim_period;
+};
+
 struct ieee80211_if_ap {
-       u8 *beacon_head, *beacon_tail;
-       int beacon_head_len, beacon_tail_len;
+       struct beacon_data *beacon;
 
        struct list_head vlans;
 
@@ -201,7 +210,7 @@ struct ieee80211_if_ap {
        u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)];
        atomic_t num_sta_ps; /* number of stations in PS mode */
        struct sk_buff_head ps_bc_buf;
-       int dtim_period, dtim_count;
+       int dtim_count;
        int force_unicast_rateidx; /* forced TX rateidx for unicast frames */
        int max_ratectrl_rateidx; /* max TX rateidx for rate control */
        int num_beacons; /* number of TXed beacon frames for this BSS */
@@ -282,15 +291,9 @@ struct ieee80211_if_sta {
 /* flags used in struct ieee80211_sub_if_data.flags */
 #define IEEE80211_SDATA_ALLMULTI       BIT(0)
 #define IEEE80211_SDATA_PROMISC                BIT(1)
-#define IEEE80211_SDATA_USE_PROTECTION BIT(2) /* CTS protect ERP frames */
-/* use short preamble with IEEE 802.11b: this flag is set when the AP or beacon
- * generator reports that there are no present stations that cannot support short
- * preambles */
-#define IEEE80211_SDATA_SHORT_PREAMBLE BIT(3)
-#define IEEE80211_SDATA_USERSPACE_MLME BIT(4)
+#define IEEE80211_SDATA_USERSPACE_MLME BIT(2)
 struct ieee80211_sub_if_data {
        struct list_head list;
-       enum ieee80211_if_types type;
 
        struct wireless_dev wdev;
 
@@ -303,11 +306,11 @@ struct ieee80211_sub_if_data {
        unsigned int flags;
 
        int drop_unencrypted;
-       int eapol; /* 0 = process EAPOL frames as normal data frames,
-                   * 1 = send EAPOL frames through wlan#ap to hostapd
-                   *     (default) */
-       int ieee802_1x; /* IEEE 802.1X PAE - drop packet to/from unauthorized
-                        * port */
+       /*
+        * IEEE 802.1X Port access control in effect,
+        * drop packets to/from unauthorized port
+        */
+       int ieee802_1x_pac;
 
        u16 sequence;
 
@@ -319,6 +322,15 @@ struct ieee80211_sub_if_data {
        struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
        struct ieee80211_key *default_key;
 
+       /*
+        * BSS configuration for this interface.
+        *
+        * FIXME: I feel bad putting this here when we already have a
+        *        bss pointer, but the bss pointer is just wrong when
+        *        you have multiple virtual STA mode interfaces...
+        *        This needs to be fixed.
+        */
+       struct ieee80211_bss_conf bss_conf;
        struct ieee80211_if_ap *bss; /* BSS that this device belongs to */
 
        union {
@@ -336,8 +348,7 @@ struct ieee80211_sub_if_data {
                struct {
                        struct dentry *channel_use;
                        struct dentry *drop_unencrypted;
-                       struct dentry *eapol;
-                       struct dentry *ieee8021_x;
+                       struct dentry *ieee802_1x_pac;
                        struct dentry *state;
                        struct dentry *bssid;
                        struct dentry *prev_bssid;
@@ -356,30 +367,24 @@ struct ieee80211_sub_if_data {
                struct {
                        struct dentry *channel_use;
                        struct dentry *drop_unencrypted;
-                       struct dentry *eapol;
-                       struct dentry *ieee8021_x;
+                       struct dentry *ieee802_1x_pac;
                        struct dentry *num_sta_ps;
-                       struct dentry *dtim_period;
                        struct dentry *dtim_count;
                        struct dentry *num_beacons;
                        struct dentry *force_unicast_rateidx;
                        struct dentry *max_ratectrl_rateidx;
                        struct dentry *num_buffered_multicast;
-                       struct dentry *beacon_head_len;
-                       struct dentry *beacon_tail_len;
                } ap;
                struct {
                        struct dentry *channel_use;
                        struct dentry *drop_unencrypted;
-                       struct dentry *eapol;
-                       struct dentry *ieee8021_x;
+                       struct dentry *ieee802_1x_pac;
                        struct dentry *peer;
                } wds;
                struct {
                        struct dentry *channel_use;
                        struct dentry *drop_unencrypted;
-                       struct dentry *eapol;
-                       struct dentry *ieee8021_x;
+                       struct dentry *ieee802_1x_pac;
                } vlan;
                struct {
                        struct dentry *mode;
@@ -387,8 +392,16 @@ struct ieee80211_sub_if_data {
                struct dentry *default_key;
        } debugfs;
 #endif
+       /* must be last, dynamically sized area in this! */
+       struct ieee80211_vif vif;
 };
 
+static inline
+struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
+{
+       return container_of(p, struct ieee80211_sub_if_data, vif);
+}
+
 #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev)
 
 enum {
@@ -470,7 +483,8 @@ struct ieee80211_local {
 
        struct list_head interfaces;
 
-       int sta_scanning;
+       bool sta_sw_scanning;
+       bool sta_hw_scanning;
        int scan_channel_idx;
        enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
        unsigned long last_scan_completed;
@@ -483,10 +497,6 @@ struct ieee80211_local {
        struct list_head sta_bss_list;
        struct ieee80211_sta_bss *sta_bss_hash[STA_HASH_SIZE];
        spinlock_t sta_bss_lock;
-#define IEEE80211_SCAN_MATCH_SSID BIT(0)
-#define IEEE80211_SCAN_WPA_ONLY BIT(1)
-#define IEEE80211_SCAN_EXTRA_INFO BIT(2)
-       int scan_flags;
 
        /* SNMP counters */
        /* dot11CountersTable */
@@ -503,8 +513,9 @@ struct ieee80211_local {
 
 #ifdef CONFIG_MAC80211_LEDS
        int tx_led_counter, rx_led_counter;
-       struct led_trigger *tx_led, *rx_led, *assoc_led;
-       char tx_led_name[32], rx_led_name[32], assoc_led_name[32];
+       struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led;
+       char tx_led_name[32], rx_led_name[32],
+            assoc_led_name[32], radio_led_name[32];
 #endif
 
        u32 channel_use;
@@ -708,6 +719,9 @@ int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
 void ieee80211_if_setup(struct net_device *dev);
 struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local,
                                          int phymode, int hwrate);
+int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht,
+                          struct ieee80211_ht_info *req_ht_cap,
+                          struct ieee80211_ht_bss_info *req_bss_cap);
 
 /* ieee80211_ioctl.c */
 extern const struct iw_handler_def ieee80211_iw_handler_def;
@@ -749,7 +763,8 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
 void ieee80211_sta_req_auth(struct net_device *dev,
                            struct ieee80211_if_sta *ifsta);
 int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
-void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
+ieee80211_txrx_result ieee80211_sta_rx_scan(struct net_device *dev,
+                                           struct sk_buff *skb,
                           struct ieee80211_rx_status *rx_status);
 void ieee80211_rx_bss_list_init(struct net_device *dev);
 void ieee80211_rx_bss_list_deinit(struct net_device *dev);
@@ -759,9 +774,17 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
                                         u8 *addr);
 int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason);
 int ieee80211_sta_disassociate(struct net_device *dev, u16 reason);
-void ieee80211_erp_info_change_notify(struct net_device *dev, u8 changes);
+void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
+                                     u32 changed);
 void ieee80211_reset_erp_info(struct net_device *dev);
-
+int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
+                                  struct ieee80211_ht_info *ht_info);
+int ieee80211_ht_addt_info_ie_to_ht_bss_info(
+                       struct ieee80211_ht_addt_info *ht_add_info_ie,
+                       struct ieee80211_ht_bss_info *bss_info);
+void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da,
+                               u16 tid, u16 initiator, u16 reason);
+void sta_rx_agg_session_timer_expired(unsigned long data);
 /* ieee80211_iface.c */
 int ieee80211_if_add(struct net_device *dev, const char *name,
                     struct net_device **new_dev, int type);
@@ -793,8 +816,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
 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);
-int ieee80211_is_eapol(const struct sk_buff *skb);
+u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
+                       enum ieee80211_if_types 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 net_device *dev, int keyidx,
index 43e505d294527ca1769c24da69b82c7b42ee6e66..92f1eb2da31152dfc0bdd35e5f5cb9dfb7ccc1dc 100644 (file)
@@ -22,7 +22,6 @@ void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata)
 
        /* Default values for sub-interface parameters */
        sdata->drop_unencrypted = 0;
-       sdata->eapol = 1;
        for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
                skb_queue_head_init(&sdata->fragments[i].skb_list);
 
@@ -48,7 +47,7 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
        int ret;
 
        ASSERT_RTNL();
-       ndev = alloc_netdev(sizeof(struct ieee80211_sub_if_data),
+       ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size,
                            name, ieee80211_if_setup);
        if (!ndev)
                return -ENOMEM;
@@ -67,7 +66,7 @@ int ieee80211_if_add(struct net_device *dev, const char *name,
        sdata = IEEE80211_DEV_TO_SUB_IF(ndev);
        ndev->ieee80211_ptr = &sdata->wdev;
        sdata->wdev.wiphy = local->hw.wiphy;
-       sdata->type = IEEE80211_IF_TYPE_AP;
+       sdata->vif.type = IEEE80211_IF_TYPE_AP;
        sdata->dev = ndev;
        sdata->local = local;
        ieee80211_if_sdata_init(sdata);
@@ -99,7 +98,7 @@ fail:
 void ieee80211_if_set_type(struct net_device *dev, int type)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       int oldtype = sdata->type;
+       int oldtype = sdata->vif.type;
 
        /*
         * We need to call this function on the master interface
@@ -117,7 +116,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
 
        /* most have no BSS pointer */
        sdata->bss = NULL;
-       sdata->type = type;
+       sdata->vif.type = type;
 
        switch (type) {
        case IEEE80211_IF_TYPE_WDS:
@@ -127,7 +126,6 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
                sdata->u.vlan.ap = NULL;
                break;
        case IEEE80211_IF_TYPE_AP:
-               sdata->u.ap.dtim_period = 2;
                sdata->u.ap.force_unicast_rateidx = -1;
                sdata->u.ap.max_ratectrl_rateidx = -1;
                skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
@@ -182,7 +180,7 @@ void ieee80211_if_reinit(struct net_device *dev)
 
        ieee80211_if_sdata_deinit(sdata);
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_INVALID:
                /* cannot happen */
                WARN_ON(1);
@@ -208,8 +206,7 @@ void ieee80211_if_reinit(struct net_device *dev)
                        }
                }
 
-               kfree(sdata->u.ap.beacon_head);
-               kfree(sdata->u.ap.beacon_tail);
+               kfree(sdata->u.ap.beacon);
 
                while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
                        local->total_ps_buffered--;
@@ -280,7 +277,7 @@ int ieee80211_if_remove(struct net_device *dev, const char *name, int id)
        ASSERT_RTNL();
 
        list_for_each_entry_safe(sdata, n, &local->interfaces, list) {
-               if ((sdata->type == id || id == -1) &&
+               if ((sdata->vif.type == id || id == -1) &&
                    strcmp(name, sdata->dev->name) == 0 &&
                    sdata->dev != local->mdev) {
                        list_del_rcu(&sdata->list);
index 308bbe4a13333b103bd4d31f676da35fadcb4e48..5024d3733834cc9938a0a32a213c301cf48577c7 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "ieee80211_led.h"
 #include "ieee80211_rate.h"
 #include "wpa.h"
 #include "aes_ccm.h"
@@ -111,8 +112,8 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
        if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
                return -EOPNOTSUPP;
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret = ieee80211_sta_set_extra_ie(dev, extra, data->length);
                if (ret)
                        return ret;
@@ -218,6 +219,8 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev,
        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
        IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
 
+       range->scan_capa |= IW_SCAN_CAPA_ESSID;
+
        return 0;
 }
 
@@ -229,7 +232,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int type;
 
-       if (sdata->type == IEEE80211_IF_TYPE_VLAN)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
                return -EOPNOTSUPP;
 
        switch (*mode) {
@@ -246,7 +249,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
                return -EINVAL;
        }
 
-       if (type == sdata->type)
+       if (type == sdata->vif.type)
                return 0;
        if (netif_running(dev))
                return -EBUSY;
@@ -265,7 +268,7 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_AP:
                *mode = IW_MODE_MASTER;
                break;
@@ -315,7 +318,7 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
        }
 
        if (set) {
-               if (local->sta_scanning)
+               if (local->sta_sw_scanning)
                        ret = 0;
                else
                        ret = ieee80211_hw_config(local);
@@ -333,13 +336,13 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                sdata->u.sta.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->type == IEEE80211_IF_TYPE_STA)
+                       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                                sdata->u.sta.flags |=
                                        IEEE80211_STA_AUTO_CHANNEL_SEL;
                        return 0;
@@ -385,8 +388,8 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                len--;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret;
                if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
                        if (len > IEEE80211_MAX_SSID_LEN)
@@ -406,7 +409,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                return 0;
        }
 
-       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                memcpy(sdata->u.ap.ssid, ssid, len);
                memset(sdata->u.ap.ssid + len, 0,
                       IEEE80211_MAX_SSID_LEN - len);
@@ -425,8 +428,8 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
 
        struct ieee80211_sub_if_data *sdata;
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int res = ieee80211_sta_get_ssid(dev, ssid, &len);
                if (res == 0) {
                        data->length = len;
@@ -436,7 +439,7 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
                return res;
        }
 
-       if (sdata->type == IEEE80211_IF_TYPE_AP) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
                len = sdata->u.ap.ssid_len;
                if (len > IW_ESSID_MAX_SIZE)
                        len = IW_ESSID_MAX_SIZE;
@@ -456,8 +459,8 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                int ret;
                if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
                        memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
@@ -476,7 +479,7 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
                        return ret;
                ieee80211_sta_req_auth(dev, &sdata->u.sta);
                return 0;
-       } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
+       } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
                if (memcmp(sdata->u.wds.remote_addr, (u8 *) &ap_addr->sa_data,
                           ETH_ALEN) == 0)
                        return 0;
@@ -494,12 +497,12 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                ap_addr->sa_family = ARPHRD_ETHER;
                memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
                return 0;
-       } else if (sdata->type == IEEE80211_IF_TYPE_WDS) {
+       } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
                ap_addr->sa_family = ARPHRD_ETHER;
                memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
                return 0;
@@ -513,7 +516,6 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
                                   struct iw_request_info *info,
                                   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);
        struct iw_scan_req *req = NULL;
        u8 *ssid = NULL;
@@ -522,23 +524,10 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
        if (!netif_running(dev))
                return -ENETDOWN;
 
-       switch (sdata->type) {
-       case IEEE80211_IF_TYPE_STA:
-       case IEEE80211_IF_TYPE_IBSS:
-               if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
-                       ssid = sdata->u.sta.ssid;
-                       ssid_len = sdata->u.sta.ssid_len;
-               }
-               break;
-       case IEEE80211_IF_TYPE_AP:
-               if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
-                       ssid = sdata->u.ap.ssid;
-                       ssid_len = sdata->u.ap.ssid_len;
-               }
-               break;
-       default:
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
+           sdata->vif.type != IEEE80211_IF_TYPE_AP)
                return -EOPNOTSUPP;
-       }
 
        /* if SSID was specified explicitly then use that */
        if (wrqu->data.length == sizeof(struct iw_scan_req) &&
@@ -558,8 +547,10 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
 {
        int res;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       if (local->sta_scanning)
+
+       if (local->sta_sw_scanning || local->sta_hw_scanning)
                return -EAGAIN;
+
        res = ieee80211_sta_scan_results(dev, extra, data->length);
        if (res >= 0) {
                data->length = res;
@@ -614,7 +605,7 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
                sta = sta_info_get(local, sdata->u.sta.bssid);
        else
                return -EOPNOTSUPP;
@@ -634,22 +625,36 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        bool need_reconfig = 0;
+       u8 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 (!data->txpower.fixed)
-               return -EINVAL;
 
-       if (local->hw.conf.power_level != data->txpower.value) {
-               local->hw.conf.power_level = data->txpower.value;
+       if (data->txpower.fixed) {
+               new_power_level = data->txpower.value;
+       } else {
+               /* Automatic power level. Get the px power from the current
+                * channel. */
+               struct ieee80211_channel* chan = local->oper_channel;
+               if (!chan)
+                       return -EINVAL;
+
+               new_power_level = chan->power_level;
+       }
+
+       if (local->hw.conf.power_level != new_power_level) {
+               local->hw.conf.power_level = new_power_level;
                need_reconfig = 1;
        }
+
        if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
                local->hw.conf.radio_enabled = !(data->txpower.disabled);
                need_reconfig = 1;
+               ieee80211_led_radio(local, local->hw.conf.radio_enabled);
        }
+
        if (need_reconfig) {
                ieee80211_hw_config(local);
                /* The return value of hw_config is not of big interest here,
@@ -814,8 +819,8 @@ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
        struct iw_mlme *mlme = (struct iw_mlme *) extra;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type != IEEE80211_IF_TYPE_STA &&
-           sdata->type != IEEE80211_IF_TYPE_IBSS)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
                return -EINVAL;
 
        switch (mlme->cmd) {
@@ -928,8 +933,11 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
        case IW_AUTH_KEY_MGMT:
                break;
+       case IW_AUTH_DROP_UNENCRYPTED:
+               sdata->drop_unencrypted = !!data->value;
+               break;
        case IW_AUTH_PRIVACY_INVOKED:
-               if (sdata->type != IEEE80211_IF_TYPE_STA)
+               if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                        ret = -EINVAL;
                else {
                        sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
@@ -944,8 +952,8 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
                }
                break;
        case IW_AUTH_80211_AUTH_ALG:
-               if (sdata->type == IEEE80211_IF_TYPE_STA ||
-                   sdata->type == IEEE80211_IF_TYPE_IBSS)
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+                   sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                        sdata->u.sta.auth_algs = data->value;
                else
                        ret = -EOPNOTSUPP;
@@ -965,8 +973,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sta_info *sta = NULL;
 
-       if (sdata->type == IEEE80211_IF_TYPE_STA ||
-           sdata->type == IEEE80211_IF_TYPE_IBSS)
+       if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+           sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                sta = sta_info_get(local, sdata->u.sta.bssid);
        if (!sta) {
                wstats->discard.fragment = 0;
@@ -994,8 +1002,8 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
 
        switch (data->flags & IW_AUTH_INDEX) {
        case IW_AUTH_80211_AUTH_ALG:
-               if (sdata->type == IEEE80211_IF_TYPE_STA ||
-                   sdata->type == IEEE80211_IF_TYPE_IBSS)
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+                   sdata->vif.type == IEEE80211_IF_TYPE_IBSS)
                        data->value = sdata->u.sta.auth_algs;
                else
                        ret = -EOPNOTSUPP;
index 4cf89af9d1009ffc528622d2e0f64a550c4614d4..f401484ab6d7d1502ba79051e79d3af9f2d32369 100644 (file)
@@ -43,6 +43,16 @@ void ieee80211_led_assoc(struct ieee80211_local *local, bool associated)
                led_trigger_event(local->assoc_led, LED_OFF);
 }
 
+void ieee80211_led_radio(struct ieee80211_local *local, bool enabled)
+{
+       if (unlikely(!local->radio_led))
+               return;
+       if (enabled)
+               led_trigger_event(local->radio_led, LED_FULL);
+       else
+               led_trigger_event(local->radio_led, LED_OFF);
+}
+
 void ieee80211_led_init(struct ieee80211_local *local)
 {
        local->rx_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
@@ -77,10 +87,25 @@ void ieee80211_led_init(struct ieee80211_local *local)
                        local->assoc_led = NULL;
                }
        }
+
+       local->radio_led = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
+       if (local->radio_led) {
+               snprintf(local->radio_led_name, sizeof(local->radio_led_name),
+                        "%sradio", wiphy_name(local->hw.wiphy));
+               local->radio_led->name = local->radio_led_name;
+               if (led_trigger_register(local->radio_led)) {
+                       kfree(local->radio_led);
+                       local->radio_led = NULL;
+               }
+       }
 }
 
 void ieee80211_led_exit(struct ieee80211_local *local)
 {
+       if (local->radio_led) {
+               led_trigger_unregister(local->radio_led);
+               kfree(local->radio_led);
+       }
        if (local->assoc_led) {
                led_trigger_unregister(local->assoc_led);
                kfree(local->assoc_led);
@@ -95,6 +120,16 @@ void ieee80211_led_exit(struct ieee80211_local *local)
        }
 }
 
+char *__ieee80211_get_radio_led_name(struct ieee80211_hw *hw)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+
+       if (local->radio_led)
+               return local->radio_led_name;
+       return NULL;
+}
+EXPORT_SYMBOL(__ieee80211_get_radio_led_name);
+
 char *__ieee80211_get_assoc_led_name(struct ieee80211_hw *hw)
 {
        struct ieee80211_local *local = hw_to_local(hw);
index 0feb22619835e0230df6e8bf9469d76e0e49f914..77b1e1ba60391120cb8eff79f57aa922466e2625 100644 (file)
@@ -16,6 +16,8 @@ extern void ieee80211_led_rx(struct ieee80211_local *local);
 extern void ieee80211_led_tx(struct ieee80211_local *local, int q);
 extern void ieee80211_led_assoc(struct ieee80211_local *local,
                                bool associated);
+extern void ieee80211_led_radio(struct ieee80211_local *local,
+                               bool enabled);
 extern void ieee80211_led_init(struct ieee80211_local *local);
 extern void ieee80211_led_exit(struct ieee80211_local *local);
 #else
@@ -29,6 +31,10 @@ static inline void ieee80211_led_assoc(struct ieee80211_local *local,
                                       bool associated)
 {
 }
+static inline void ieee80211_led_radio(struct ieee80211_local *local,
+                                      bool enabled)
+{
+}
 static inline void ieee80211_led_init(struct ieee80211_local *local)
 {
 }
index c3f2783937419a8c0afae47b302657288d647184..b957e67c5fba83dff74f2a1ced9c5a200a3b5217 100644 (file)
@@ -21,6 +21,11 @@ struct rate_control_alg {
 static LIST_HEAD(rate_ctrl_algs);
 static DEFINE_MUTEX(rate_ctrl_mutex);
 
+static char *ieee80211_default_rc_algo = CONFIG_MAC80211_RC_DEFAULT;
+module_param(ieee80211_default_rc_algo, charp, 0644);
+MODULE_PARM_DESC(ieee80211_default_rc_algo,
+                "Default rate control algorithm for mac80211 to use");
+
 int ieee80211_rate_control_register(struct rate_control_ops *ops)
 {
        struct rate_control_alg *alg;
@@ -89,21 +94,31 @@ ieee80211_try_rate_control_ops_get(const char *name)
        return ops;
 }
 
-/* Get the rate control algorithm. If `name' is NULL, get the first
- * available algorithm. */
+/* Get the rate control algorithm. */
 static struct rate_control_ops *
 ieee80211_rate_control_ops_get(const char *name)
 {
        struct rate_control_ops *ops;
+       const char *alg_name;
 
        if (!name)
-               name = "simple";
+               alg_name = ieee80211_default_rc_algo;
+       else
+               alg_name = name;
 
-       ops = ieee80211_try_rate_control_ops_get(name);
+       ops = ieee80211_try_rate_control_ops_get(alg_name);
        if (!ops) {
-               request_module("rc80211_%s", name);
-               ops = ieee80211_try_rate_control_ops_get(name);
+               request_module("rc80211_%s", alg_name);
+               ops = ieee80211_try_rate_control_ops_get(alg_name);
        }
+       if (!ops && name)
+               /* try default if specific alg requested but not found */
+               ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
+
+       /* try built-in one if specific alg requested but not found */
+       if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
+               ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
+
        return ops;
 }
 
@@ -147,6 +162,37 @@ static void rate_control_release(struct kref *kref)
        kfree(ctrl_ref);
 }
 
+void rate_control_get_rate(struct net_device *dev,
+                          struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                          struct rate_selection *sel)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct rate_control_ref *ref = local->rate_ctrl;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct sta_info *sta = sta_info_get(local, hdr->addr1);
+       int i;
+
+       memset(sel, 0, sizeof(struct rate_selection));
+
+       ref->ops->get_rate(ref->priv, dev, mode, skb, sel);
+
+       /* Select a non-ERP backup rate. */
+       if (!sel->nonerp) {
+               for (i = 0; i < mode->num_rates - 1; i++) {
+                       struct ieee80211_rate *rate = &mode->rates[i];
+                       if (sel->rate->rate < rate->rate)
+                               break;
+
+                       if (rate_supported(sta, mode, i) &&
+                           !(rate->flags & IEEE80211_RATE_ERP))
+                               sel->nonerp = rate;
+               }
+       }
+
+       if (sta)
+               sta_info_put(sta);
+}
+
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
 {
        kref_get(&ref->kref);
@@ -197,3 +243,4 @@ void rate_control_deinitialize(struct ieee80211_local *local)
        local->rate_ctrl = NULL;
        rate_control_put(ref);
 }
+
index 23688139ffb3ea399292ce2b6842f55c91371d34..73f19e8aa51ce0cc9efc4691a6d31c817e73c224 100644 (file)
 #include "ieee80211_i.h"
 #include "sta_info.h"
 
-#define RATE_CONTROL_NUM_DOWN 20
-#define RATE_CONTROL_NUM_UP   15
-
-
-struct rate_control_extra {
-       /* values from rate_control_get_rate() to the caller: */
-       struct ieee80211_rate *probe; /* probe with this rate, or NULL for no
-                                      * probing */
+struct rate_selection {
+       /* Selected transmission rate */
+       struct ieee80211_rate *rate;
+       /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */
        struct ieee80211_rate *nonerp;
-
-       /* parameters from the caller to rate_control_get_rate(): */
-       struct ieee80211_hw_mode *mode;
-       u16 ethertype;
+       /* probe with this rate, or NULL for no probing */
+       struct ieee80211_rate *probe;
 };
 
-
 struct rate_control_ops {
        struct module *module;
        const char *name;
        void (*tx_status)(void *priv, struct net_device *dev,
                          struct sk_buff *skb,
                          struct ieee80211_tx_status *status);
-       struct ieee80211_rate *(*get_rate)(void *priv, struct net_device *dev,
-                                          struct sk_buff *skb,
-                                          struct rate_control_extra *extra);
+       void (*get_rate)(void *priv, struct net_device *dev,
+                        struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                        struct rate_selection *sel);
        void (*rate_init)(void *priv, void *priv_sta,
                          struct ieee80211_local *local, struct sta_info *sta);
        void (*clear)(void *priv);
@@ -65,9 +58,6 @@ struct rate_control_ref {
        struct kref kref;
 };
 
-/* default 'simple' algorithm */
-extern struct rate_control_ops mac80211_rcsimple;
-
 int ieee80211_rate_control_register(struct rate_control_ops *ops);
 void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
 
@@ -75,25 +65,20 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
  * first available algorithm. */
 struct rate_control_ref *rate_control_alloc(const char *name,
                                            struct ieee80211_local *local);
+void rate_control_get_rate(struct net_device *dev,
+                          struct ieee80211_hw_mode *mode, struct sk_buff *skb,
+                          struct rate_selection *sel);
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
 void rate_control_put(struct rate_control_ref *ref);
 
-static inline void rate_control_tx_status(struct ieee80211_local *local,
-                                         struct net_device *dev,
+static inline void rate_control_tx_status(struct net_device *dev,
                                          struct sk_buff *skb,
                                          struct ieee80211_tx_status *status)
 {
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct rate_control_ref *ref = local->rate_ctrl;
-       ref->ops->tx_status(ref->priv, dev, skb, status);
-}
-
 
-static inline struct ieee80211_rate *
-rate_control_get_rate(struct ieee80211_local *local, struct net_device *dev,
-                     struct sk_buff *skb, struct rate_control_extra *extra)
-{
-       struct rate_control_ref *ref = local->rate_ctrl;
-       return ref->ops->get_rate(ref->priv, dev, skb, extra);
+       ref->ops->tx_status(ref->priv, dev, skb, status);
 }
 
 
@@ -142,10 +127,73 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
 #endif
 }
 
+static inline int
+rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index)
+{
+       return (sta == NULL || sta->supp_rates & BIT(index)) &&
+              (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED);
+}
+
+static inline int
+rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
+                 struct sta_info *sta)
+{
+       int i;
+
+       for (i = 0; i < mode->num_rates; i++) {
+               if (rate_supported(sta, mode, i))
+                       return i;
+       }
+
+       /* warn when we cannot find a rate. */
+       WARN_ON(1);
+
+       return 0;
+}
+
+static inline struct ieee80211_rate *
+rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode,
+           struct sta_info *sta)
+{
+       return &mode->rates[rate_lowest_index(local, mode, sta)];
+}
+
 
 /* functions for rate control related to a device */
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
                                 const char *name);
 void rate_control_deinitialize(struct ieee80211_local *local);
 
+
+/* Rate control algorithms */
+#if defined(RC80211_SIMPLE_COMPILE) || \
+       (defined(CONFIG_MAC80211_RC_SIMPLE) && \
+        !defined(CONFIG_MAC80211_RC_SIMPLE_MODULE))
+extern int rc80211_simple_init(void);
+extern void rc80211_simple_exit(void);
+#else
+static inline int rc80211_simple_init(void)
+{
+       return 0;
+}
+static inline void rc80211_simple_exit(void)
+{
+}
+#endif
+
+#if defined(RC80211_PID_COMPILE) || \
+       (defined(CONFIG_MAC80211_RC_PID) && \
+        !defined(CONFIG_MAC80211_RC_PID_MODULE))
+extern int rc80211_pid_init(void);
+extern void rc80211_pid_exit(void);
+#else
+static inline int rc80211_pid_init(void)
+{
+       return 0;
+}
+static inline void rc80211_pid_exit(void)
+{
+}
+#endif
+
 #endif /* IEEE80211_RATE_H */
index bee8080f2249ff5c0ab56a33293bd02dca7ea5ec..2019b4f0528d8f063e94e3bdcc6450b854765e60 100644 (file)
 
 #define ERP_INFO_USE_PROTECTION BIT(1)
 
+/* mgmt header + 1 byte action code */
+#define IEEE80211_MIN_ACTION_SIZE (24 + 1)
+
+#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
+#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
+#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
+
+/* next values represent the buffer size for A-MPDU frame.
+ * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */
+#define IEEE80211_MIN_AMPDU_BUF 0x8
+#define IEEE80211_MAX_AMPDU_BUF 0x40
+
 static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
                                     u8 *ssid, size_t ssid_len);
 static struct ieee80211_sta_bss *
@@ -90,7 +104,8 @@ struct ieee802_11_elems {
        u8 *ext_supp_rates;
        u8 *wmm_info;
        u8 *wmm_param;
-
+       u8 *ht_cap_elem;
+       u8 *ht_info_elem;
        /* length of them, respectively */
        u8 ssid_len;
        u8 supp_rates_len;
@@ -106,6 +121,8 @@ struct ieee802_11_elems {
        u8 ext_supp_rates_len;
        u8 wmm_info_len;
        u8 wmm_param_len;
+       u8 ht_cap_elem_len;
+       u8 ht_info_elem_len;
 };
 
 static void ieee802_11_parse_elems(u8 *start, size_t len,
@@ -190,6 +207,14 @@ static void ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->ext_supp_rates = pos;
                        elems->ext_supp_rates_len = elen;
                        break;
+               case WLAN_EID_HT_CAPABILITY:
+                       elems->ht_cap_elem = pos;
+                       elems->ht_cap_elem_len = elen;
+                       break;
+               case WLAN_EID_HT_EXTRA_INFO:
+                       elems->ht_info_elem = pos;
+                       elems->ht_info_elem_len = elen;
+                       break;
                default:
                        break;
                }
@@ -288,50 +313,89 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
 }
 
 
-static void ieee80211_handle_erp_ie(struct net_device *dev, u8 erp_value)
+static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
+                                  u8 erp_value)
 {
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
        struct ieee80211_if_sta *ifsta = &sdata->u.sta;
-       int use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
-       int preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
-       u8 changes = 0;
+       bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
+       bool preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
        DECLARE_MAC_BUF(mac);
+       u32 changed = 0;
 
-       if (use_protection != !!(sdata->flags & IEEE80211_SDATA_USE_PROTECTION)) {
+       if (use_protection != bss_conf->use_cts_prot) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
                               "%s)\n",
-                              dev->name,
+                              sdata->dev->name,
                               use_protection ? "enabled" : "disabled",
                               print_mac(mac, ifsta->bssid));
                }
-               if (use_protection)
-                       sdata->flags |= IEEE80211_SDATA_USE_PROTECTION;
-               else
-                       sdata->flags &= ~IEEE80211_SDATA_USE_PROTECTION;
-               changes |= IEEE80211_ERP_CHANGE_PROTECTION;
+               bss_conf->use_cts_prot = use_protection;
+               changed |= BSS_CHANGED_ERP_CTS_PROT;
        }
 
-       if (preamble_mode != !(sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE)) {
+       if (preamble_mode != bss_conf->use_short_preamble) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: switched to %s barker preamble"
                               " (BSSID=%s)\n",
-                              dev->name,
+                              sdata->dev->name,
                               (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ?
                                        "short" : "long",
                               print_mac(mac, ifsta->bssid));
                }
-               if (preamble_mode)
-                       sdata->flags &= ~IEEE80211_SDATA_SHORT_PREAMBLE;
-               else
-                       sdata->flags |= IEEE80211_SDATA_SHORT_PREAMBLE;
-               changes |= IEEE80211_ERP_CHANGE_PREAMBLE;
+               bss_conf->use_short_preamble = preamble_mode;
+               changed |= BSS_CHANGED_ERP_PREAMBLE;
        }
 
-       if (changes)
-               ieee80211_erp_info_change_notify(dev, changes);
+       return changed;
 }
 
+int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
+                                  struct ieee80211_ht_info *ht_info)
+{
+
+       if (ht_info == NULL)
+               return -EINVAL;
+
+       memset(ht_info, 0, sizeof(*ht_info));
+
+       if (ht_cap_ie) {
+               u8 ampdu_info = ht_cap_ie->ampdu_params_info;
+
+               ht_info->ht_supported = 1;
+               ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
+               ht_info->ampdu_factor =
+                       ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
+               ht_info->ampdu_density =
+                       (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
+               memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
+       } else
+               ht_info->ht_supported = 0;
+
+       return 0;
+}
+
+int ieee80211_ht_addt_info_ie_to_ht_bss_info(
+                       struct ieee80211_ht_addt_info *ht_add_info_ie,
+                       struct ieee80211_ht_bss_info *bss_info)
+{
+       if (bss_info == NULL)
+               return -EINVAL;
+
+       memset(bss_info, 0, sizeof(*bss_info));
+
+       if (ht_add_info_ie) {
+               u16 op_mode;
+               op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
+
+               bss_info->primary_channel = ht_add_info_ie->control_chan;
+               bss_info->bss_cap = ht_add_info_ie->ht_param;
+               bss_info->bss_op_mode = (u8)(op_mode & 0xff);
+       }
+
+       return 0;
+}
 
 static void ieee80211_sta_send_associnfo(struct net_device *dev,
                                         struct ieee80211_if_sta *ifsta)
@@ -388,20 +452,17 @@ static void ieee80211_set_associated(struct net_device *dev,
                                     struct ieee80211_if_sta *ifsta,
                                     bool assoc)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        union iwreq_data wrqu;
-
-       if (!!(ifsta->flags & IEEE80211_STA_ASSOCIATED) == assoc)
-               return;
+       u32 changed = BSS_CHANGED_ASSOC;
 
        if (assoc) {
-               struct ieee80211_sub_if_data *sdata;
                struct ieee80211_sta_bss *bss;
 
                ifsta->flags |= IEEE80211_STA_ASSOCIATED;
 
-               sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-               if (sdata->type != IEEE80211_IF_TYPE_STA)
+               if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                        return;
 
                bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
@@ -409,7 +470,8 @@ static void ieee80211_set_associated(struct net_device *dev,
                                           ifsta->ssid, ifsta->ssid_len);
                if (bss) {
                        if (bss->has_erp_value)
-                               ieee80211_handle_erp_ie(dev, bss->erp_value);
+                               changed |= ieee80211_handle_erp_ie(
+                                               sdata, bss->erp_value);
                        ieee80211_rx_bss_put(dev, bss);
                }
 
@@ -429,6 +491,8 @@ static void ieee80211_set_associated(struct net_device *dev,
        wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
        ifsta->last_probe = jiffies;
        ieee80211_led_assoc(local, assoc);
+
+       ieee80211_bss_info_change_notify(sdata, changed);
 }
 
 static void ieee80211_set_disassoc(struct net_device *dev,
@@ -630,6 +694,19 @@ static void ieee80211_send_assoc(struct net_device *dev,
                *pos++ = 1; /* WME ver */
                *pos++ = 0;
        }
+       /* wmm support is a must to HT */
+       if (wmm && mode->ht_info.ht_supported) {
+               __le16 tmp = cpu_to_le16(mode->ht_info.cap);
+               pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
+               *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);
+               *pos++ = (mode->ht_info.ampdu_factor |
+                               (mode->ht_info.ampdu_density << 2));
+               memcpy(pos, mode->ht_info.supp_mcs_set, 16);
+       }
 
        kfree(ifsta->assocreq_ies);
        ifsta->assocreq_ies_len = (skb->data + skb->len) - ies;
@@ -918,6 +995,320 @@ static void ieee80211_auth_challenge(struct net_device *dev,
                            elems.challenge_len + 2, 1);
 }
 
+static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid,
+                                       u8 dialog_token, u16 status, u16 policy,
+                                       u16 buf_size, u16 timeout)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_if_sta *ifsta = &sdata->u.sta;
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sk_buff *skb;
+       struct ieee80211_mgmt *mgmt;
+       u16 capab;
+
+       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 +
+                                       sizeof(mgmt->u.action.u.addba_resp));
+       if (!skb) {
+               printk(KERN_DEBUG "%s: failed to allocate buffer "
+                      "for addba resp frame\n", dev->name);
+               return;
+       }
+
+       skb_reserve(skb, local->hw.extra_tx_headroom);
+       mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
+       memset(mgmt, 0, 24);
+       memcpy(mgmt->da, da, ETH_ALEN);
+       memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
+               memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
+       else
+               memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
+       mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
+                                          IEEE80211_STYPE_ACTION);
+
+       skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
+       mgmt->u.action.category = WLAN_CATEGORY_BACK;
+       mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
+       mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
+
+       capab = (u16)(policy << 1);     /* bit 1 aggregation policy */
+       capab |= (u16)(tid << 2);       /* bit 5:2 TID number */
+       capab |= (u16)(buf_size << 6);  /* bit 15:6 max size of aggregation */
+
+       mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
+       mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
+       mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
+
+       ieee80211_sta_tx(dev, skb, 0);
+
+       return;
+}
+
+static void ieee80211_sta_process_addba_request(struct net_device *dev,
+                                               struct ieee80211_mgmt *mgmt,
+                                               size_t len)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hw *hw = &local->hw;
+       struct ieee80211_conf *conf = &hw->conf;
+       struct sta_info *sta;
+       struct tid_ampdu_rx *tid_agg_rx;
+       u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
+       u8 dialog_token;
+       int ret = -EOPNOTSUPP;
+       DECLARE_MAC_BUF(mac);
+
+       sta = sta_info_get(local, mgmt->sa);
+       if (!sta)
+               return;
+
+       /* extract session parameters from addba request frame */
+       dialog_token = mgmt->u.action.u.addba_req.dialog_token;
+       timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
+       start_seq_num =
+               le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
+
+       capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+       ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
+       tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+       buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
+
+       status = WLAN_STATUS_REQUEST_DECLINED;
+
+       /* sanity check for incoming parameters:
+        * check if configuration can support the BA policy
+        * and if buffer size does not exceeds max value */
+       if (((ba_policy != 1)
+               && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
+               || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
+               status = WLAN_STATUS_INVALID_QOS_PARAM;
+#ifdef CONFIG_MAC80211_HT_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "Block Ack Req with bad params from "
+                               "%s on tid %u. policy %d, buffer size %d\n",
+                               print_mac(mac, mgmt->sa), tid, ba_policy,
+                               buf_size);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+               goto end_no_lock;
+       }
+       /* determine default buffer size */
+       if (buf_size == 0) {
+               struct ieee80211_hw_mode *mode = conf->mode;
+               buf_size = IEEE80211_MIN_AMPDU_BUF;
+               buf_size = buf_size << mode->ht_info.ampdu_factor;
+       }
+
+       tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid];
+
+       /* examine state machine */
+       spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+
+       if (tid_agg_rx->state != HT_AGG_STATE_IDLE) {
+#ifdef CONFIG_MAC80211_HT_DEBUG
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "unexpected Block Ack Req from "
+                               "%s on tid %u\n",
+                               print_mac(mac, mgmt->sa), tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+               goto end;
+       }
+
+       /* prepare reordering buffer */
+       tid_agg_rx->reorder_buf =
+               kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC);
+       if ((!tid_agg_rx->reorder_buf) && net_ratelimit()) {
+               printk(KERN_ERR "can not allocate reordering buffer "
+                                               "to tid %d\n", tid);
+               goto end;
+       }
+       memset(tid_agg_rx->reorder_buf, 0,
+               buf_size * sizeof(struct sk_buf *));
+
+       if (local->ops->ampdu_action)
+               ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
+                                              sta->addr, tid, start_seq_num);
+#ifdef CONFIG_MAC80211_HT_DEBUG
+       printk(KERN_DEBUG "Rx A-MPDU on tid %d result %d", tid, ret);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
+       if (ret) {
+               kfree(tid_agg_rx->reorder_buf);
+               goto end;
+       }
+
+       /* change state and send addba resp */
+       tid_agg_rx->state = HT_AGG_STATE_OPERATIONAL;
+       tid_agg_rx->dialog_token = dialog_token;
+       tid_agg_rx->ssn = start_seq_num;
+       tid_agg_rx->head_seq_num = start_seq_num;
+       tid_agg_rx->buf_size = buf_size;
+       tid_agg_rx->timeout = timeout;
+       tid_agg_rx->stored_mpdu_num = 0;
+       status = WLAN_STATUS_SUCCESS;
+end:
+       spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+
+end_no_lock:
+       ieee80211_send_addba_resp(sta->dev, sta->addr, tid, dialog_token,
+                               status, 1, buf_size, timeout);
+       sta_info_put(sta);
+}
+
+static void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
+                                u16 initiator, u16 reason_code)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_if_sta *ifsta = &sdata->u.sta;
+       struct sk_buff *skb;
+       struct ieee80211_mgmt *mgmt;
+       u16 params;
+
+       skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 +
+                                       sizeof(mgmt->u.action.u.delba));
+
+       if (!skb) {
+               printk(KERN_ERR "%s: failed to allocate buffer "
+                                       "for delba frame\n", dev->name);
+               return;
+       }
+
+       skb_reserve(skb, local->hw.extra_tx_headroom);
+       mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
+       memset(mgmt, 0, 24);
+       memcpy(mgmt->da, da, ETH_ALEN);
+       memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
+       if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
+               memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
+       else
+               memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
+       mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
+                                       IEEE80211_STYPE_ACTION);
+
+       skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
+
+       mgmt->u.action.category = WLAN_CATEGORY_BACK;
+       mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+       params = (u16)(initiator << 11);        /* bit 11 initiator */
+       params |= (u16)(tid << 12);             /* bit 15:12 TID number */
+
+       mgmt->u.action.u.delba.params = cpu_to_le16(params);
+       mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
+
+       ieee80211_sta_tx(dev, skb, 0);
+}
+
+void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
+                                       u16 initiator, u16 reason)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hw *hw = &local->hw;
+       struct sta_info *sta;
+       int ret, i;
+
+       sta = sta_info_get(local, ra);
+       if (!sta)
+               return;
+
+       /* check if TID is in operational state */
+       spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+       if (sta->ampdu_mlme.tid_rx[tid].state
+                               != HT_AGG_STATE_OPERATIONAL) {
+               spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+               sta_info_put(sta);
+               return;
+       }
+       sta->ampdu_mlme.tid_rx[tid].state =
+               HT_AGG_STATE_REQ_STOP_BA_MSK |
+               (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
+               spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+
+       /* stop HW Rx aggregation. ampdu_action existence
+        * already verified in session init so we add the BUG_ON */
+       BUG_ON(!local->ops->ampdu_action);
+
+       ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
+                                       ra, tid, EINVAL);
+       if (ret)
+               printk(KERN_DEBUG "HW problem - can not stop rx "
+                               "aggergation for tid %d\n", tid);
+
+       /* shutdown timer has not expired */
+       if (initiator != WLAN_BACK_TIMER)
+               del_timer_sync(&sta->ampdu_mlme.tid_rx[tid].
+                                       session_timer);
+
+       /* check if this is a self generated aggregation halt */
+       if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
+               ieee80211_send_delba(dev, ra, tid, 0, reason);
+
+       /* free the reordering buffer */
+       for (i = 0; i < sta->ampdu_mlme.tid_rx[tid].buf_size; i++) {
+               if (sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]) {
+                       /* release the reordered frames */
+                       dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]);
+                       sta->ampdu_mlme.tid_rx[tid].stored_mpdu_num--;
+                       sta->ampdu_mlme.tid_rx[tid].reorder_buf[i] = NULL;
+               }
+       }
+       kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf);
+
+       sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE;
+       sta_info_put(sta);
+}
+
+static void ieee80211_sta_process_delba(struct net_device *dev,
+                       struct ieee80211_mgmt *mgmt, size_t len)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct sta_info *sta;
+       u16 tid, params;
+       u16 initiator;
+       DECLARE_MAC_BUF(mac);
+
+       sta = sta_info_get(local, mgmt->sa);
+       if (!sta)
+               return;
+
+       params = le16_to_cpu(mgmt->u.action.u.delba.params);
+       tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
+       initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
+
+#ifdef CONFIG_MAC80211_HT_DEBUG
+       if (net_ratelimit())
+               printk(KERN_DEBUG "delba from %s on tid %d reason code %d\n",
+                       print_mac(mac, mgmt->sa), tid,
+                       mgmt->u.action.u.delba.reason_code);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
+       if (initiator == WLAN_BACK_INITIATOR)
+               ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
+                                                WLAN_BACK_INITIATOR, 0);
+       sta_info_put(sta);
+}
+
+/*
+ * After receiving Block Ack Request (BAR) we activated a
+ * timer after each frame arrives from the originator.
+ * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
+ */
+void sta_rx_agg_session_timer_expired(unsigned long data)
+{
+       /* not an elegant detour, but there is no choice as the timer passes
+        * only one argument, and verious sta_info are needed here, so init
+        * flow in sta_info_add gives the TID as data, while the timer_to_id
+        * array gives the sta through container_of */
+       u8 *ptid = (u8 *)data;
+       u8 *timer_to_id = ptid - *ptid;
+       struct sta_info *sta = container_of(timer_to_id, struct sta_info,
+                                        timer_to_tid[0]);
+
+       printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
+       ieee80211_sta_stop_rx_ba_session(sta->dev, sta->addr, (u16)*ptid,
+                                        WLAN_BACK_TIMER,
+                                        WLAN_REASON_QSTA_TIMEOUT);
+}
+
 
 static void ieee80211_rx_mgmt_auth(struct net_device *dev,
                                   struct ieee80211_if_sta *ifsta,
@@ -929,7 +1320,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
        DECLARE_MAC_BUF(mac);
 
        if (ifsta->state != IEEE80211_AUTHENTICATE &&
-           sdata->type != IEEE80211_IF_TYPE_IBSS) {
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS) {
                printk(KERN_DEBUG "%s: authentication frame received from "
                       "%s, but not in authenticate state - ignored\n",
                       dev->name, print_mac(mac, mgmt->sa));
@@ -943,7 +1334,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
                return;
        }
 
-       if (sdata->type != IEEE80211_IF_TYPE_IBSS &&
+       if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
            memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) {
                printk(KERN_DEBUG "%s: authentication frame received from "
                       "unknown AP (SA=%s BSSID=%s) - "
@@ -952,7 +1343,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
                return;
        }
 
-       if (sdata->type != IEEE80211_IF_TYPE_IBSS &&
+       if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
            memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) {
                printk(KERN_DEBUG "%s: authentication frame received from "
                       "unknown BSSID (SA=%s BSSID=%s) - "
@@ -970,7 +1361,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
               dev->name, print_mac(mac, mgmt->sa), auth_alg,
               auth_transaction, status_code);
 
-       if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                /* IEEE 802.11 standard does not require authentication in IBSS
                 * networks and most implementations do not seem to use it.
                 * However, try to reply to authentication attempts if someone
@@ -1136,18 +1527,20 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev,
 }
 
 
-static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
+static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                                         struct ieee80211_if_sta *ifsta,
                                         struct ieee80211_mgmt *mgmt,
                                         size_t len,
                                         int reassoc)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_local *local = sdata->local;
+       struct net_device *dev = sdata->dev;
        struct ieee80211_hw_mode *mode;
        struct sta_info *sta;
        u32 rates;
        u16 capab_info, status_code, aid;
        struct ieee802_11_elems elems;
+       struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
        u8 *pos;
        int i, j;
        DECLARE_MAC_BUF(mac);
@@ -1210,20 +1603,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
                return;
        }
 
-       /* it probably doesn't, but if the frame includes an ERP value then
-        * update our stored copy */
-       if (elems.erp_info && elems.erp_info_len >= 1) {
-               struct ieee80211_sta_bss *bss
-                       = ieee80211_rx_bss_get(dev, ifsta->bssid,
-                                              local->hw.conf.channel,
-                                              ifsta->ssid, ifsta->ssid_len);
-               if (bss) {
-                       bss->erp_value = elems.erp_info[0];
-                       bss->has_erp_value = 1;
-                       ieee80211_rx_bss_put(dev, bss);
-               }
-       }
-
        printk(KERN_DEBUG "%s: associated\n", dev->name);
        ifsta->aid = aid;
        ifsta->ap_capab = capab_info;
@@ -1234,6 +1613,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
        if (ifsta->assocresp_ies)
                memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);
 
+       /* set AID, ieee80211_set_associated() will tell the driver */
+       bss_conf->aid = aid;
        ieee80211_set_associated(dev, ifsta, 1);
 
        /* Add STA entry for the AP */
@@ -1276,6 +1657,19 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
        }
        sta->supp_rates = rates;
 
+       if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param &&
+           local->ops->conf_ht) {
+               struct ieee80211_ht_bss_info bss_info;
+
+               ieee80211_ht_cap_ie_to_ht_info(
+                               (struct ieee80211_ht_cap *)
+                               elems.ht_cap_elem, &sta->ht_info);
+               ieee80211_ht_addt_info_ie_to_ht_bss_info(
+                               (struct ieee80211_ht_addt_info *)
+                               elems.ht_info_elem, &bss_info);
+               ieee80211_hw_config_ht(local, 1, &sta->ht_info, &bss_info);
+       }
+
        rate_control_rate_init(sta, local);
 
        if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
@@ -1380,6 +1774,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
        kfree(bss->wpa_ie);
        kfree(bss->rsn_ie);
        kfree(bss->wmm_ie);
+       kfree(bss->ht_ie);
        kfree(bss);
 }
 
@@ -1449,7 +1844,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
        timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
 
-       if (sdata->type == IEEE80211_IF_TYPE_IBSS && beacon &&
+       if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
            memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
                static unsigned long last_tsf_debug = 0;
@@ -1474,7 +1869,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
 
        ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
-       if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
+       if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
            memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
            (sta = sta_info_get(local, mgmt->sa))) {
                struct ieee80211_hw_mode *mode;
@@ -1483,8 +1878,18 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
                u32 supp_rates, prev_rates;
                int i, j;
 
-               mode = local->sta_scanning ?
+               mode = local->sta_sw_scanning ?
                       local->scan_hw_mode : local->oper_hw_mode;
+
+               if (local->sta_hw_scanning) {
+                       /* search for the correct mode matches the beacon */
+                       list_for_each_entry(mode, &local->modes_list, list)
+                               if (mode->mode == rx_status->phymode)
+                                       break;
+
+                       if (mode == NULL)
+                               mode = local->oper_hw_mode;
+               }
                rates = mode->rates;
                num_rates = mode->num_rates;
 
@@ -1627,7 +2032,22 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
                bss->wmm_ie = NULL;
                bss->wmm_ie_len = 0;
        }
-
+       if (elems.ht_cap_elem &&
+           (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len ||
+            memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) {
+               kfree(bss->ht_ie);
+               bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC);
+               if (bss->ht_ie) {
+                       memcpy(bss->ht_ie, elems.ht_cap_elem - 2,
+                              elems.ht_cap_elem_len + 2);
+                       bss->ht_ie_len = elems.ht_cap_elem_len + 2;
+               } else
+                       bss->ht_ie_len = 0;
+       } else if (!elems.ht_cap_elem && bss->ht_ie) {
+               kfree(bss->ht_ie);
+               bss->ht_ie = NULL;
+               bss->ht_ie_len = 0;
+       }
 
        bss->hw_mode = rx_status->phymode;
        bss->freq = rx_status->freq;
@@ -1672,11 +2092,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
        struct ieee80211_if_sta *ifsta;
        size_t baselen;
        struct ieee802_11_elems elems;
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_conf *conf = &local->hw.conf;
+       u32 changed = 0;
 
        ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1);
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type != IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                return;
        ifsta = &sdata->u.sta;
 
@@ -1692,12 +2115,31 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
        ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
 
        if (elems.erp_info && elems.erp_info_len >= 1)
-               ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
+               changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
+
+       if (elems.ht_cap_elem && elems.ht_info_elem &&
+           elems.wmm_param && local->ops->conf_ht &&
+           conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
+               struct ieee80211_ht_bss_info bss_info;
+
+               ieee80211_ht_addt_info_ie_to_ht_bss_info(
+                               (struct ieee80211_ht_addt_info *)
+                               elems.ht_info_elem, &bss_info);
+               /* check if AP changed bss inforamation */
+               if ((conf->ht_bss_conf.primary_channel !=
+                    bss_info.primary_channel) ||
+                   (conf->ht_bss_conf.bss_cap != bss_info.bss_cap) ||
+                   (conf->ht_bss_conf.bss_op_mode != bss_info.bss_op_mode))
+                       ieee80211_hw_config_ht(local, 1, &conf->ht_conf,
+                                               &bss_info);
+       }
 
        if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
                ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
                                         elems.wmm_param_len);
        }
+
+       ieee80211_bss_info_change_notify(sdata, changed);
 }
 
 
@@ -1719,7 +2161,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
        DECLARE_MAC_BUF(mac3);
 #endif
 
-       if (sdata->type != IEEE80211_IF_TYPE_IBSS ||
+       if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS ||
            ifsta->state != IEEE80211_IBSS_JOINED ||
            len < 24 + 2 || !ifsta->probe_resp)
                return;
@@ -1775,6 +2217,40 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
        ieee80211_sta_tx(dev, skb, 0);
 }
 
+static void ieee80211_rx_mgmt_action(struct net_device *dev,
+                                    struct ieee80211_if_sta *ifsta,
+                                    struct ieee80211_mgmt *mgmt,
+                                    size_t len)
+{
+       if (len < IEEE80211_MIN_ACTION_SIZE)
+               return;
+
+       switch (mgmt->u.action.category) {
+       case WLAN_CATEGORY_BACK:
+               switch (mgmt->u.action.u.addba_req.action_code) {
+               case WLAN_ACTION_ADDBA_REQ:
+                       if (len < (IEEE80211_MIN_ACTION_SIZE +
+                                  sizeof(mgmt->u.action.u.addba_req)))
+                               break;
+                       ieee80211_sta_process_addba_request(dev, mgmt, len);
+                       break;
+               case WLAN_ACTION_DELBA:
+                       if (len < (IEEE80211_MIN_ACTION_SIZE +
+                                  sizeof(mgmt->u.action.u.delba)))
+                               break;
+                       ieee80211_sta_process_delba(dev, mgmt, len);
+                       break;
+               default:
+                       if (net_ratelimit())
+                          printk(KERN_DEBUG "%s: Rx unknown A-MPDU action\n",
+                                       dev->name);
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+}
 
 void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
                           struct ieee80211_rx_status *rx_status)
@@ -1804,6 +2280,7 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
        case IEEE80211_STYPE_REASSOC_RESP:
        case IEEE80211_STYPE_DEAUTH:
        case IEEE80211_STYPE_DISASSOC:
+       case IEEE80211_STYPE_ACTION:
                skb_queue_tail(&ifsta->skb_queue, skb);
                queue_work(local->hw.workqueue, &ifsta->work);
                return;
@@ -1850,10 +2327,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
                ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len);
                break;
        case IEEE80211_STYPE_ASSOC_RESP:
-               ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, 0);
+               ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
                break;
        case IEEE80211_STYPE_REASSOC_RESP:
-               ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, 1);
+               ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
                break;
        case IEEE80211_STYPE_DEAUTH:
                ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len);
@@ -1861,37 +2338,48 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
        case IEEE80211_STYPE_DISASSOC:
                ieee80211_rx_mgmt_disassoc(dev, ifsta, mgmt, skb->len);
                break;
+       case IEEE80211_STYPE_ACTION:
+               ieee80211_rx_mgmt_action(dev, ifsta, mgmt, skb->len);
+               break;
        }
 
        kfree_skb(skb);
 }
 
 
-void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
-                          struct ieee80211_rx_status *rx_status)
+ieee80211_txrx_result
+ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
+                     struct ieee80211_rx_status *rx_status)
 {
        struct ieee80211_mgmt *mgmt;
        u16 fc;
 
-       if (skb->len < 24) {
-               dev_kfree_skb(skb);
-               return;
-       }
+       if (skb->len < 2)
+               return TXRX_DROP;
 
        mgmt = (struct ieee80211_mgmt *) skb->data;
        fc = le16_to_cpu(mgmt->frame_control);
 
+       if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
+               return TXRX_CONTINUE;
+
+       if (skb->len < 24)
+               return TXRX_DROP;
+
        if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
                if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) {
                        ieee80211_rx_mgmt_probe_resp(dev, mgmt,
                                                     skb->len, rx_status);
+                       dev_kfree_skb(skb);
+                       return TXRX_QUEUED;
                } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) {
                        ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len,
                                                 rx_status);
+                       dev_kfree_skb(skb);
+                       return TXRX_QUEUED;
                }
        }
-
-       dev_kfree_skb(skb);
+       return TXRX_CONTINUE;
 }
 
 
@@ -1981,13 +2469,13 @@ void ieee80211_sta_work(struct work_struct *work)
        if (!netif_running(dev))
                return;
 
-       if (local->sta_scanning)
+       if (local->sta_sw_scanning || local->sta_hw_scanning)
                return;
 
-       if (sdata->type != IEEE80211_IF_TYPE_STA &&
-           sdata->type != IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS) {
                printk(KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface "
-                      "(type=%d)\n", dev->name, sdata->type);
+                      "(type=%d)\n", dev->name, sdata->vif.type);
                return;
        }
        ifsta = &sdata->u.sta;
@@ -2082,7 +2570,7 @@ void ieee80211_sta_req_auth(struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (sdata->type != IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                return;
 
        if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
@@ -2204,9 +2692,8 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
        struct ieee80211_tx_control control;
-       struct ieee80211_rate *rate;
        struct ieee80211_hw_mode *mode;
-       struct rate_control_extra extra;
+       struct rate_selection ratesel;
        u8 *pos;
        struct ieee80211_sub_if_data *sdata;
 
@@ -2291,18 +2778,17 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
                }
 
                memset(&control, 0, sizeof(control));
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = local->oper_hw_mode;
-               rate = rate_control_get_rate(local, dev, skb, &extra);
-               if (!rate) {
+               rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel);
+               if (!ratesel.rate) {
                        printk(KERN_DEBUG "%s: Failed to determine TX rate "
                               "for IBSS beacon\n", dev->name);
                        break;
                }
+               control.vif = &sdata->vif;
                control.tx_rate =
-                       ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
-                       (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
-                       rate->val2 : rate->val;
+                       (sdata->bss_conf.use_short_preamble &&
+                       (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
+                       ratesel.rate->val2 : ratesel.rate->val;
                control.antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control.power_level = local->hw.conf.power_level;
                control.flags |= IEEE80211_TXCTL_NO_ACK;
@@ -2552,7 +3038,7 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len)
                ifsta->flags |= IEEE80211_STA_SSID_SET;
        else
                ifsta->flags &= ~IEEE80211_STA_SSID_SET;
-       if (sdata->type == IEEE80211_IF_TYPE_IBSS &&
+       if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
            !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
                ifsta->ibss_join_req = jiffies;
                ifsta->state = IEEE80211_IBSS_SEARCH;
@@ -2639,9 +3125,15 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
        union iwreq_data wrqu;
 
        local->last_scan_completed = jiffies;
-       wmb();
-       local->sta_scanning = 0;
+       memset(&wrqu, 0, sizeof(wrqu));
+       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
+
+       if (local->sta_hw_scanning) {
+               local->sta_hw_scanning = 0;
+               goto done;
+       }
 
+       local->sta_sw_scanning = 0;
        if (ieee80211_hw_config(local))
                printk(KERN_DEBUG "%s: failed to restore operational "
                       "channel after scan\n", dev->name);
@@ -2657,9 +3149,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
 
        netif_tx_unlock_bh(local->mdev);
 
-       memset(&wrqu, 0, sizeof(wrqu));
-       wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
-
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
 
@@ -2667,7 +3156,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
                if (sdata->dev == local->mdev)
                        continue;
 
-               if (sdata->type == IEEE80211_IF_TYPE_STA) {
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
                        if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)
                                ieee80211_send_nullfunc(local, sdata, 0);
                        ieee80211_sta_timer((unsigned long)sdata);
@@ -2677,8 +3166,9 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
        }
        rcu_read_unlock();
 
+done:
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
+       if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
                struct ieee80211_if_sta *ifsta = &sdata->u.sta;
                if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
                    (!ifsta->state == IEEE80211_IBSS_JOINED &&
@@ -2699,7 +3189,7 @@ void ieee80211_sta_scan_work(struct work_struct *work)
        int skip;
        unsigned long next_delay = 0;
 
-       if (!local->sta_scanning)
+       if (!local->sta_sw_scanning)
                return;
 
        switch (local->scan_state) {
@@ -2713,7 +3203,7 @@ void ieee80211_sta_scan_work(struct work_struct *work)
                skip = !(local->enabled_modes & (1 << mode->mode));
                chan = &mode->channels[local->scan_channel_idx];
                if (!(chan->flag & IEEE80211_CHAN_W_SCAN) ||
-                   (sdata->type == IEEE80211_IF_TYPE_IBSS &&
+                   (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
                     !(chan->flag & IEEE80211_CHAN_W_IBSS)) ||
                    (local->hw_modes & local->enabled_modes &
                     (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))
@@ -2762,7 +3252,7 @@ void ieee80211_sta_scan_work(struct work_struct *work)
                break;
        }
 
-       if (local->sta_scanning)
+       if (local->sta_sw_scanning)
                queue_delayed_work(local->hw.workqueue, &local->scan_work,
                                   next_delay);
 }
@@ -2794,7 +3284,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
          * ResultCode: SUCCESS, INVALID_PARAMETERS
         */
 
-       if (local->sta_scanning) {
+       if (local->sta_sw_scanning || local->sta_hw_scanning) {
                if (local->scan_dev == dev)
                        return 0;
                return -EBUSY;
@@ -2802,15 +3292,15 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
 
        if (local->ops->hw_scan) {
                int rc = local->ops->hw_scan(local_to_hw(local),
-                                           ssid, ssid_len);
+                                            ssid, ssid_len);
                if (!rc) {
-                       local->sta_scanning = 1;
+                       local->sta_hw_scanning = 1;
                        local->scan_dev = dev;
                }
                return rc;
        }
 
-       local->sta_scanning = 1;
+       local->sta_sw_scanning = 1;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
@@ -2821,7 +3311,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
                        continue;
 
                netif_stop_queue(sdata->dev);
-               if (sdata->type == IEEE80211_IF_TYPE_STA &&
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
                    (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED))
                        ieee80211_send_nullfunc(local, sdata, 1);
        }
@@ -2862,10 +3352,10 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
        struct ieee80211_if_sta *ifsta = &sdata->u.sta;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 
-       if (sdata->type != IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                return ieee80211_sta_start_scan(dev, ssid, ssid_len);
 
-       if (local->sta_scanning) {
+       if (local->sta_sw_scanning || local->sta_hw_scanning) {
                if (local->scan_dev == dev)
                        return 0;
                return -EBUSY;
@@ -2894,15 +3384,6 @@ ieee80211_sta_scan_result(struct net_device *dev,
        if (!(local->enabled_modes & (1 << bss->hw_mode)))
                return current_ev;
 
-       if (local->scan_flags & IEEE80211_SCAN_WPA_ONLY &&
-           !bss->wpa_ie && !bss->rsn_ie)
-               return current_ev;
-
-       if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID &&
-           (local->scan_ssid_len != bss->ssid_len ||
-            memcmp(local->scan_ssid, bss->ssid, bss->ssid_len) != 0))
-               return current_ev;
-
        memset(&iwe, 0, sizeof(iwe));
        iwe.cmd = SIOCGIWAP;
        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
@@ -3006,34 +3487,6 @@ ieee80211_sta_scan_result(struct net_device *dev,
                }
        }
 
-       do {
-               char *buf;
-
-               if (!(local->scan_flags & IEEE80211_SCAN_EXTRA_INFO))
-                       break;
-
-               buf = kmalloc(100, GFP_ATOMIC);
-               if (!buf)
-                       break;
-
-               memset(&iwe, 0, sizeof(iwe));
-               iwe.cmd = IWEVCUSTOM;
-               sprintf(buf, "bcn_int=%d", bss->beacon_int);
-               iwe.u.data.length = strlen(buf);
-               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
-                                                 buf);
-
-               memset(&iwe, 0, sizeof(iwe));
-               iwe.cmd = IWEVCUSTOM;
-               sprintf(buf, "capab=0x%04x", bss->capability);
-               iwe.u.data.length = strlen(buf);
-               current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
-                                                 buf);
-
-               kfree(buf);
-               break;
-       } while (0);
-
        return current_ev;
 }
 
@@ -3122,8 +3575,8 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason)
        printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n",
               dev->name, reason);
 
-       if (sdata->type != IEEE80211_IF_TYPE_STA &&
-           sdata->type != IEEE80211_IF_TYPE_IBSS)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA &&
+           sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
                return -EINVAL;
 
        ieee80211_send_deauth(dev, ifsta, reason);
@@ -3140,7 +3593,7 @@ int ieee80211_sta_disassociate(struct net_device *dev, u16 reason)
        printk(KERN_DEBUG "%s: disassociate(reason=%d)\n",
               dev->name, reason);
 
-       if (sdata->type != IEEE80211_IF_TYPE_STA)
+       if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
                return -EINVAL;
 
        if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
index 0b2328f7d67cdb7b3bc90990f50e0450461d309c..ed57fb8e82fc13ab9052fb4992524c572b1d2c6e 100644 (file)
@@ -49,8 +49,8 @@ static const u8 *get_mac_for_key(struct ieee80211_key *key)
         * address to indicate a transmit-only key.
         */
        if (key->conf.alg != ALG_WEP &&
-           (key->sdata->type == IEEE80211_IF_TYPE_AP ||
-            key->sdata->type == IEEE80211_IF_TYPE_VLAN))
+           (key->sdata->vif.type == IEEE80211_IF_TYPE_AP ||
+            key->sdata->vif.type == IEEE80211_IF_TYPE_VLAN))
                addr = zero_addr;
 
        if (key->sta)
@@ -172,7 +172,7 @@ struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata,
                if (sta->flags & WLAN_STA_WME)
                        key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
        } else {
-               if (sdata->type == IEEE80211_IF_TYPE_STA) {
+               if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
                        struct sta_info *ap;
 
                        /* same here, the AP could be using QoS */
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
new file mode 100644 (file)
index 0000000..04afc13
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
+ * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RC80211_PID_H
+#define RC80211_PID_H
+
+/* Sampling period for measuring percentage of failed frames in ms. */
+#define RC_PID_INTERVAL                        125
+
+/* Exponential averaging smoothness (used for I part of PID controller) */
+#define RC_PID_SMOOTHING_SHIFT         3
+#define RC_PID_SMOOTHING               (1 << RC_PID_SMOOTHING_SHIFT)
+
+/* Sharpening factor (used for D part of PID controller) */
+#define RC_PID_SHARPENING_FACTOR       0
+#define RC_PID_SHARPENING_DURATION     0
+
+/* Fixed point arithmetic shifting amount. */
+#define RC_PID_ARITH_SHIFT             8
+
+/* Fixed point arithmetic factor. */
+#define RC_PID_ARITH_FACTOR            (1 << RC_PID_ARITH_SHIFT)
+
+/* Proportional PID component coefficient. */
+#define RC_PID_COEFF_P                 15
+/* Integral PID component coefficient. */
+#define RC_PID_COEFF_I                 9
+/* Derivative PID component coefficient. */
+#define RC_PID_COEFF_D                 15
+
+/* Target failed frames rate for the PID controller. NB: This effectively gives
+ * maximum failed frames percentage we're willing to accept. If the wireless
+ * link quality is good, the controller will fail to adjust failed frames
+ * percentage to the target. This is intentional.
+ */
+#define RC_PID_TARGET_PF               14
+
+/* Rate behaviour normalization quantity over time. */
+#define RC_PID_NORM_OFFSET             3
+
+/* Push high rates right after loading. */
+#define RC_PID_FAST_START              0
+
+/* Arithmetic right shift for positive and negative values for ISO C. */
+#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
+       (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)
+
+enum rc_pid_event_type {
+       RC_PID_EVENT_TYPE_TX_STATUS,
+       RC_PID_EVENT_TYPE_RATE_CHANGE,
+       RC_PID_EVENT_TYPE_TX_RATE,
+       RC_PID_EVENT_TYPE_PF_SAMPLE,
+};
+
+union rc_pid_event_data {
+       /* RC_PID_EVENT_TX_STATUS */
+       struct {
+               struct ieee80211_tx_status tx_status;
+       };
+       /* RC_PID_EVENT_TYPE_RATE_CHANGE */
+       /* RC_PID_EVENT_TYPE_TX_RATE */
+       struct {
+               int index;
+               int rate;
+       };
+       /* RC_PID_EVENT_TYPE_PF_SAMPLE */
+       struct {
+               s32 pf_sample;
+               s32 prop_err;
+               s32 int_err;
+               s32 der_err;
+       };
+};
+
+struct rc_pid_event {
+       /* The time when the event occured */
+       unsigned long timestamp;
+
+       /* Event ID number */
+       unsigned int id;
+
+       /* Type of event */
+       enum rc_pid_event_type type;
+
+       /* type specific data */
+       union rc_pid_event_data data;
+};
+
+/* Size of the event ring buffer. */
+#define RC_PID_EVENT_RING_SIZE 32
+
+struct rc_pid_event_buffer {
+       /* Counter that generates event IDs */
+       unsigned int ev_count;
+
+       /* Ring buffer of events */
+       struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
+
+       /* Index to the entry in events_buf to be reused */
+       unsigned int next_entry;
+
+       /* Lock that guards against concurrent access to this buffer struct */
+       spinlock_t lock;
+
+       /* Wait queue for poll/select and blocking I/O */
+       wait_queue_head_t waitqueue;
+};
+
+struct rc_pid_events_file_info {
+       /* The event buffer we read */
+       struct rc_pid_event_buffer *events;
+
+       /* The entry we have should read next */
+       unsigned int next_entry;
+};
+
+/**
+ * struct rc_pid_debugfs_entries - tunable parameters
+ *
+ * Algorithm parameters, tunable via debugfs.
+ * @dir: the debugfs directory for a specific phy
+ * @target: target percentage for failed frames
+ * @sampling_period: error sampling interval in milliseconds
+ * @coeff_p: absolute value of the proportional coefficient
+ * @coeff_i: absolute value of the integral coefficient
+ * @coeff_d: absolute value of the derivative coefficient
+ * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
+ *     amount of smoothing introduced by the exponential moving average)
+ * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
+ *     amount of emphasis given to the derivative term after low activity
+ *     events)
+ * @sharpen_duration: duration of the sharpening effect after the detected low
+ *     activity event, relative to sampling_period
+ * @norm_offset: amount of normalization periodically performed on the learnt
+ *     rate behaviour values (lower means we should trust more what we learnt
+ *     about behaviour of rates, higher means we should trust more the natural
+ *     ordering of rates)
+ * @fast_start: if Y, push high rates right after initialization
+ */
+struct rc_pid_debugfs_entries {
+       struct dentry *dir;
+       struct dentry *target;
+       struct dentry *sampling_period;
+       struct dentry *coeff_p;
+       struct dentry *coeff_i;
+       struct dentry *coeff_d;
+       struct dentry *smoothing_shift;
+       struct dentry *sharpen_factor;
+       struct dentry *sharpen_duration;
+       struct dentry *norm_offset;
+       struct dentry *fast_start;
+};
+
+void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
+                                            struct ieee80211_tx_status *stat);
+
+void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
+                                              int index, int rate);
+
+void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
+                                          int index, int rate);
+
+void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
+                                            s32 pf_sample, s32 prop_err,
+                                            s32 int_err, s32 der_err);
+
+void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
+                                            struct dentry *dir);
+
+void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
+
+struct rc_pid_sta_info {
+       unsigned long last_change;
+       unsigned long last_sample;
+
+       u32 tx_num_failed;
+       u32 tx_num_xmit;
+
+       /* Average failed frames percentage error (i.e. actual vs. target
+        * percentage), scaled by RC_PID_SMOOTHING. This value is computed
+        * using using an exponential weighted average technique:
+        *
+        *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
+        * err_avg = ------------------------------------------
+        *                       RC_PID_SMOOTHING
+        *
+        * where err_avg is the new approximation, err_avg_old the previous one
+        * and err is the error w.r.t. to the current failed frames percentage
+        * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
+        * given to the previous estimate, resulting in smoother behavior (i.e.
+        * corresponding to a longer integration window).
+        *
+        * For computation, we actually don't use the above formula, but this
+        * one:
+        *
+        * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
+        *
+        * where:
+        *      err_avg_scaled = err * RC_PID_SMOOTHING
+        *      err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
+        *
+        * This avoids floating point numbers and the per_failed_old value can
+        * easily be obtained by shifting per_failed_old_scaled right by
+        * RC_PID_SMOOTHING_SHIFT.
+        */
+       s32 err_avg_sc;
+
+       /* Last framed failes percentage sample. */
+       u32 last_pf;
+
+       /* Sharpening needed. */
+       u8 sharp_cnt;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       /* Event buffer */
+       struct rc_pid_event_buffer events;
+
+       /* Events debugfs file entry */
+       struct dentry *events_entry;
+#endif
+};
+
+/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
+ * be tuned individually for each interface.
+ */
+struct rc_pid_rateinfo {
+
+       /* Map sorted rates to rates in ieee80211_hw_mode. */
+       int index;
+
+       /* Map rates in ieee80211_hw_mode to sorted rates. */
+       int rev_index;
+
+       /* Did we do any measurement on this rate? */
+       bool valid;
+
+       /* Comparison with the lowest rate. */
+       int diff;
+};
+
+struct rc_pid_info {
+
+       /* The failed frames percentage target. */
+       unsigned int target;
+
+       /* Rate at which failed frames percentage is sampled in 0.001s. */
+       unsigned int sampling_period;
+
+       /* P, I and D coefficients. */
+       int coeff_p;
+       int coeff_i;
+       int coeff_d;
+
+       /* Exponential averaging shift. */
+       unsigned int smoothing_shift;
+
+       /* Sharpening factor and duration. */
+       unsigned int sharpen_factor;
+       unsigned int sharpen_duration;
+
+       /* Normalization offset. */
+       unsigned int norm_offset;
+
+       /* Fast starst parameter. */
+       unsigned int fast_start;
+
+       /* Rates information. */
+       struct rc_pid_rateinfo *rinfo;
+
+       /* Index of the last used rate. */
+       int oldrate;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       /* Debugfs entries created for the parameters above. */
+       struct rc_pid_debugfs_entries dentries;
+#endif
+};
+
+#endif /* RC80211_PID_H */
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
new file mode 100644 (file)
index 0000000..554c4ba
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2002-2005, Instant802 Networks, Inc.
+ * Copyright 2005, Devicescape Software, Inc.
+ * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
+ * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/debugfs.h>
+#include <net/mac80211.h>
+#include "ieee80211_rate.h"
+
+#include "rc80211_pid.h"
+
+
+/* This is an implementation of a TX rate control algorithm that uses a PID
+ * controller. Given a target failed frames rate, the controller decides about
+ * TX rate changes to meet the target failed frames rate.
+ *
+ * The controller basically computes the following:
+ *
+ * adj = CP * err + CI * err_avg + CD * (err - last_err) * (1 + sharpening)
+ *
+ * where
+ *     adj     adjustment value that is used to switch TX rate (see below)
+ *     err     current error: target vs. current failed frames percentage
+ *     last_err        last error
+ *     err_avg average (i.e. poor man's integral) of recent errors
+ *     sharpening      non-zero when fast response is needed (i.e. right after
+ *                     association or no frames sent for a long time), heading
+ *                     to zero over time
+ *     CP      Proportional coefficient
+ *     CI      Integral coefficient
+ *     CD      Derivative coefficient
+ *
+ * CP, CI, CD are subject to careful tuning.
+ *
+ * The integral component uses a exponential moving average approach instead of
+ * an actual sliding window. The advantage is that we don't need to keep an
+ * array of the last N error values and computation is easier.
+ *
+ * Once we have the adj value, we map it to a rate by means of a learning
+ * algorithm. This algorithm keeps the state of the percentual failed frames
+ * difference between rates. The behaviour of the lowest available rate is kept
+ * as a reference value, and every time we switch between two rates, we compute
+ * the difference between the failed frames each rate exhibited. By doing so,
+ * we compare behaviours which different rates exhibited in adjacent timeslices,
+ * thus the comparison is minimally affected by external conditions. This
+ * difference gets propagated to the whole set of measurements, so that the
+ * reference is always the same. Periodically, we normalize this set so that
+ * recent events weigh the most. By comparing the adj value with this set, we
+ * avoid pejorative switches to lower rates and allow for switches to higher
+ * rates if they behaved well.
+ *
+ * Note that for the computations we use a fixed-point representation to avoid
+ * floating point arithmetic. Hence, all values are shifted left by
+ * RC_PID_ARITH_SHIFT.
+ */
+
+
+/* Shift the adjustment so that we won't switch to a lower rate if it exhibited
+ * a worse failed frames behaviour and we'll choose the highest rate whose
+ * failed frames behaviour is not worse than the one of the original rate
+ * target. While at it, check that the adjustment is within the ranges. Then,
+ * provide the new rate index. */
+static int rate_control_pid_shift_adjust(struct rc_pid_rateinfo *r,
+                                        int adj, int cur, int l)
+{
+       int i, j, k, tmp;
+
+       j = r[cur].rev_index;
+       i = j + adj;
+
+       if (i < 0)
+               return r[0].index;
+       if (i >= l - 1)
+               return r[l - 1].index;
+
+       tmp = i;
+
+       if (adj < 0) {
+               for (k = j; k >= i; k--)
+                       if (r[k].diff <= r[j].diff)
+                               tmp = k;
+       } else {
+               for (k = i + 1; k + i < l; k++)
+                       if (r[k].diff <= r[i].diff)
+                               tmp = k;
+       }
+
+       return r[tmp].index;
+}
+
+static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
+                                        struct sta_info *sta, int adj,
+                                        struct rc_pid_rateinfo *rinfo)
+{
+       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_hw_mode *mode;
+       int newidx;
+       int maxrate;
+       int back = (adj > 0) ? 1 : -1;
+
+       sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+
+       mode = local->oper_hw_mode;
+       maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1;
+
+       newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate,
+                                              mode->num_rates);
+
+       while (newidx != sta->txrate) {
+               if (rate_supported(sta, mode, newidx) &&
+                   (maxrate < 0 || newidx <= maxrate)) {
+                       sta->txrate = newidx;
+                       break;
+               }
+
+               newidx += back;
+       }
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       rate_control_pid_event_rate_change(
+               &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events,
+               newidx, mode->rates[newidx].rate);
+#endif
+}
+
+/* Normalize the failed frames per-rate differences. */
+static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
+{
+       int i, norm_offset = pinfo->norm_offset;
+       struct rc_pid_rateinfo *r = pinfo->rinfo;
+
+       if (r[0].diff > norm_offset)
+               r[0].diff -= norm_offset;
+       else if (r[0].diff < -norm_offset)
+               r[0].diff += norm_offset;
+       for (i = 0; i < l - 1; i++)
+               if (r[i + 1].diff > r[i].diff + norm_offset)
+                       r[i + 1].diff -= norm_offset;
+               else if (r[i + 1].diff <= r[i].diff)
+                       r[i + 1].diff += norm_offset;
+}
+
+static void rate_control_pid_sample(struct rc_pid_info *pinfo,
+                                   struct ieee80211_local *local,
+                                   struct sta_info *sta)
+{
+       struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
+       struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
+       struct ieee80211_hw_mode *mode;
+       u32 pf;
+       s32 err_avg;
+       u32 err_prop;
+       u32 err_int;
+       u32 err_der;
+       int adj, i, j, tmp;
+       unsigned long period;
+
+       mode = local->oper_hw_mode;
+       spinfo = sta->rate_ctrl_priv;
+
+       /* In case nothing happened during the previous control interval, turn
+        * the sharpening factor on. */
+       period = (HZ * pinfo->sampling_period + 500) / 1000;
+       if (!period)
+               period = 1;
+       if (jiffies - spinfo->last_sample > 2 * period)
+               spinfo->sharp_cnt = pinfo->sharpen_duration;
+
+       spinfo->last_sample = jiffies;
+
+       /* This should never happen, but in case, we assume the old sample is
+        * still a good measurement and copy it. */
+       if (unlikely(spinfo->tx_num_xmit == 0))
+               pf = spinfo->last_pf;
+       else {
+               pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
+               pf <<= RC_PID_ARITH_SHIFT;
+       }
+
+       spinfo->tx_num_xmit = 0;
+       spinfo->tx_num_failed = 0;
+
+       /* If we just switched rate, update the rate behaviour info. */
+       if (pinfo->oldrate != sta->txrate) {
+
+               i = rinfo[pinfo->oldrate].rev_index;
+               j = rinfo[sta->txrate].rev_index;
+
+               tmp = (pf - spinfo->last_pf);
+               tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT);
+
+               rinfo[j].diff = rinfo[i].diff + tmp;
+               pinfo->oldrate = sta->txrate;
+       }
+       rate_control_pid_normalize(pinfo, mode->num_rates);
+
+       /* Compute the proportional, integral and derivative errors. */
+       err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf;
+
+       err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift;
+       spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
+       err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift;
+
+       err_der = (pf - spinfo->last_pf) *
+                 (1 + pinfo->sharpen_factor * spinfo->sharp_cnt);
+       spinfo->last_pf = pf;
+       if (spinfo->sharp_cnt)
+                       spinfo->sharp_cnt--;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int,
+                                        err_der);
+#endif
+
+       /* Compute the controller output. */
+       adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i
+             + err_der * pinfo->coeff_d);
+       adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT);
+
+       /* Change rate. */
+       if (adj)
+               rate_control_pid_adjust_rate(local, sta, adj, rinfo);
+}
+
+static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
+                                      struct sk_buff *skb,
+                                      struct ieee80211_tx_status *status)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_sub_if_data *sdata;
+       struct rc_pid_info *pinfo = priv;
+       struct sta_info *sta;
+       struct rc_pid_sta_info *spinfo;
+       unsigned long period;
+
+       sta = sta_info_get(local, hdr->addr1);
+
+       if (!sta)
+               return;
+
+       /* Don't update the state if we're not controlling the rate. */
+       sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+       if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) {
+               sta->txrate = sdata->bss->max_ratectrl_rateidx;
+               return;
+       }
+
+       /* Ignore all frames that were sent with a different rate than the rate
+        * we currently advise mac80211 to use. */
+       if (status->control.rate != &local->oper_hw_mode->rates[sta->txrate])
+               goto ignore;
+
+       spinfo = sta->rate_ctrl_priv;
+       spinfo->tx_num_xmit++;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       rate_control_pid_event_tx_status(&spinfo->events, status);
+#endif
+
+       /* We count frames that totally failed to be transmitted as two bad
+        * frames, those that made it out but had some retries as one good and
+        * one bad frame. */
+       if (status->excessive_retries) {
+               spinfo->tx_num_failed += 2;
+               spinfo->tx_num_xmit++;
+       } else if (status->retry_count) {
+               spinfo->tx_num_failed++;
+               spinfo->tx_num_xmit++;
+       }
+
+       if (status->excessive_retries) {
+               sta->tx_retry_failed++;
+               sta->tx_num_consecutive_failures++;
+               sta->tx_num_mpdu_fail++;
+       } else {
+               sta->last_ack_rssi[0] = sta->last_ack_rssi[1];
+               sta->last_ack_rssi[1] = sta->last_ack_rssi[2];
+               sta->last_ack_rssi[2] = status->ack_signal;
+               sta->tx_num_consecutive_failures = 0;
+               sta->tx_num_mpdu_ok++;
+       }
+       sta->tx_retry_count += status->retry_count;
+       sta->tx_num_mpdu_fail += status->retry_count;
+
+       /* Update PID controller state. */
+       period = (HZ * pinfo->sampling_period + 500) / 1000;
+       if (!period)
+               period = 1;
+       if (time_after(jiffies, spinfo->last_sample + period))
+               rate_control_pid_sample(pinfo, local, sta);
+
+ignore:
+       sta_info_put(sta);
+}
+
+static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
+                                     struct ieee80211_hw_mode *mode,
+                                     struct sk_buff *skb,
+                                     struct rate_selection *sel)
+{
+       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct ieee80211_sub_if_data *sdata;
+       struct sta_info *sta;
+       int rateidx;
+       u16 fc;
+
+       sta = sta_info_get(local, hdr->addr1);
+
+       /* Send management frames and broadcast/multicast 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) || !sta) {
+               sel->rate = rate_lowest(local, mode, sta);
+               if (sta)
+                       sta_info_put(sta);
+               return;
+       }
+
+       /* If a forced rate is in effect, select it. */
+       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
+               sta->txrate = sdata->bss->force_unicast_rateidx;
+
+       rateidx = sta->txrate;
+
+       if (rateidx >= mode->num_rates)
+               rateidx = mode->num_rates - 1;
+
+       sta->last_txrate = rateidx;
+
+       sta_info_put(sta);
+
+       sel->rate = &mode->rates[rateidx];
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       rate_control_pid_event_tx_rate(
+               &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events,
+               rateidx, mode->rates[rateidx].rate);
+#endif
+}
+
+static void rate_control_pid_rate_init(void *priv, void *priv_sta,
+                                         struct ieee80211_local *local,
+                                         struct sta_info *sta)
+{
+       /* TODO: This routine should consider using RSSI from previous packets
+        * as we need to have IEEE 802.1X auth succeed immediately after assoc..
+        * Until that method is implemented, we will use the lowest supported
+        * rate as a workaround. */
+       sta->txrate = rate_lowest_index(local, local->oper_hw_mode, sta);
+}
+
+static void *rate_control_pid_alloc(struct ieee80211_local *local)
+{
+       struct rc_pid_info *pinfo;
+       struct rc_pid_rateinfo *rinfo;
+       struct ieee80211_hw_mode *mode;
+       int i, j, tmp;
+       bool s;
+#ifdef CONFIG_MAC80211_DEBUGFS
+       struct rc_pid_debugfs_entries *de;
+#endif
+
+       pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
+       if (!pinfo)
+               return NULL;
+
+       /* We can safely assume that oper_hw_mode won't change unless we get
+        * reinitialized. */
+       mode = local->oper_hw_mode;
+       rinfo = kmalloc(sizeof(*rinfo) * mode->num_rates, GFP_ATOMIC);
+       if (!rinfo) {
+               kfree(pinfo);
+               return NULL;
+       }
+
+       /* Sort the rates. This is optimized for the most common case (i.e.
+        * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
+        * mapping too. */
+       for (i = 0; i < mode->num_rates; i++) {
+               rinfo[i].index = i;
+               rinfo[i].rev_index = i;
+               if (pinfo->fast_start)
+                       rinfo[i].diff = 0;
+               else
+                       rinfo[i].diff = i * pinfo->norm_offset;
+       }
+       for (i = 1; i < mode->num_rates; i++) {
+               s = 0;
+               for (j = 0; j < mode->num_rates - i; j++)
+                       if (unlikely(mode->rates[rinfo[j].index].rate >
+                                    mode->rates[rinfo[j + 1].index].rate)) {
+                               tmp = rinfo[j].index;
+                               rinfo[j].index = rinfo[j + 1].index;
+                               rinfo[j + 1].index = tmp;
+                               rinfo[rinfo[j].index].rev_index = j;
+                               rinfo[rinfo[j + 1].index].rev_index = j + 1;
+                               s = 1;
+                       }
+               if (!s)
+                       break;
+       }
+
+       pinfo->target = RC_PID_TARGET_PF;
+       pinfo->sampling_period = RC_PID_INTERVAL;
+       pinfo->coeff_p = RC_PID_COEFF_P;
+       pinfo->coeff_i = RC_PID_COEFF_I;
+       pinfo->coeff_d = RC_PID_COEFF_D;
+       pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
+       pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
+       pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
+       pinfo->norm_offset = RC_PID_NORM_OFFSET;
+       pinfo->fast_start = RC_PID_FAST_START;
+       pinfo->rinfo = rinfo;
+       pinfo->oldrate = 0;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       de = &pinfo->dentries;
+       de->dir = debugfs_create_dir("rc80211_pid",
+                                    local->hw.wiphy->debugfsdir);
+       de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
+                                       de->dir, &pinfo->target);
+       de->sampling_period = debugfs_create_u32("sampling_period",
+                                                S_IRUSR | S_IWUSR, de->dir,
+                                                &pinfo->sampling_period);
+       de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
+                                        de->dir, &pinfo->coeff_p);
+       de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
+                                        de->dir, &pinfo->coeff_i);
+       de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
+                                        de->dir, &pinfo->coeff_d);
+       de->smoothing_shift = debugfs_create_u32("smoothing_shift",
+                                                S_IRUSR | S_IWUSR, de->dir,
+                                                &pinfo->smoothing_shift);
+       de->sharpen_factor = debugfs_create_u32("sharpen_factor",
+                                              S_IRUSR | S_IWUSR, de->dir,
+                                              &pinfo->sharpen_factor);
+       de->sharpen_duration = debugfs_create_u32("sharpen_duration",
+                                                 S_IRUSR | S_IWUSR, de->dir,
+                                                 &pinfo->sharpen_duration);
+       de->norm_offset = debugfs_create_u32("norm_offset",
+                                            S_IRUSR | S_IWUSR, de->dir,
+                                            &pinfo->norm_offset);
+       de->fast_start = debugfs_create_bool("fast_start",
+                                            S_IRUSR | S_IWUSR, de->dir,
+                                            &pinfo->fast_start);
+#endif
+
+       return pinfo;
+}
+
+static void rate_control_pid_free(void *priv)
+{
+       struct rc_pid_info *pinfo = priv;
+#ifdef CONFIG_MAC80211_DEBUGFS
+       struct rc_pid_debugfs_entries *de = &pinfo->dentries;
+
+       debugfs_remove(de->fast_start);
+       debugfs_remove(de->norm_offset);
+       debugfs_remove(de->sharpen_duration);
+       debugfs_remove(de->sharpen_factor);
+       debugfs_remove(de->smoothing_shift);
+       debugfs_remove(de->coeff_d);
+       debugfs_remove(de->coeff_i);
+       debugfs_remove(de->coeff_p);
+       debugfs_remove(de->sampling_period);
+       debugfs_remove(de->target);
+       debugfs_remove(de->dir);
+#endif
+
+       kfree(pinfo->rinfo);
+       kfree(pinfo);
+}
+
+static void rate_control_pid_clear(void *priv)
+{
+}
+
+static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
+{
+       struct rc_pid_sta_info *spinfo;
+
+       spinfo = kzalloc(sizeof(*spinfo), gfp);
+       if (spinfo == NULL)
+               return NULL;
+
+       spinfo->last_sample = jiffies;
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       spin_lock_init(&spinfo->events.lock);
+       init_waitqueue_head(&spinfo->events.waitqueue);
+#endif
+
+       return spinfo;
+}
+
+static void rate_control_pid_free_sta(void *priv, void *priv_sta)
+{
+       struct rc_pid_sta_info *spinfo = priv_sta;
+       kfree(spinfo);
+}
+
+static struct rate_control_ops mac80211_rcpid = {
+       .name = "pid",
+       .tx_status = rate_control_pid_tx_status,
+       .get_rate = rate_control_pid_get_rate,
+       .rate_init = rate_control_pid_rate_init,
+       .clear = rate_control_pid_clear,
+       .alloc = rate_control_pid_alloc,
+       .free = rate_control_pid_free,
+       .alloc_sta = rate_control_pid_alloc_sta,
+       .free_sta = rate_control_pid_free_sta,
+#ifdef CONFIG_MAC80211_DEBUGFS
+       .add_sta_debugfs = rate_control_pid_add_sta_debugfs,
+       .remove_sta_debugfs = rate_control_pid_remove_sta_debugfs,
+#endif
+};
+
+MODULE_DESCRIPTION("PID controller based rate control algorithm");
+MODULE_AUTHOR("Stefano Brivio");
+MODULE_AUTHOR("Mattias Nissler");
+MODULE_LICENSE("GPL");
+
+int __init rc80211_pid_init(void)
+{
+       return ieee80211_rate_control_register(&mac80211_rcpid);
+}
+
+void __exit rc80211_pid_exit(void)
+{
+       ieee80211_rate_control_unregister(&mac80211_rcpid);
+}
+
+#ifdef CONFIG_MAC80211_RC_PID_MODULE
+module_init(rc80211_pid_init);
+module_exit(rc80211_pid_exit);
+#endif
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
new file mode 100644 (file)
index 0000000..88b8dc9
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/poll.h>
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+
+#include <net/mac80211.h>
+#include "ieee80211_rate.h"
+
+#include "rc80211_pid.h"
+
+static void rate_control_pid_event(struct rc_pid_event_buffer *buf,
+                                  enum rc_pid_event_type type,
+                                  union rc_pid_event_data *data)
+{
+       struct rc_pid_event *ev;
+       unsigned long status;
+
+       spin_lock_irqsave(&buf->lock, status);
+       ev = &(buf->ring[buf->next_entry]);
+       buf->next_entry = (buf->next_entry + 1) % RC_PID_EVENT_RING_SIZE;
+
+       ev->timestamp = jiffies;
+       ev->id = buf->ev_count++;
+       ev->type = type;
+       ev->data = *data;
+
+       spin_unlock_irqrestore(&buf->lock, status);
+
+       wake_up_all(&buf->waitqueue);
+}
+
+void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
+                                            struct ieee80211_tx_status *stat)
+{
+       union rc_pid_event_data evd;
+
+       memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_status));
+       rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd);
+}
+
+void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
+                                              int index, int rate)
+{
+       union rc_pid_event_data evd;
+
+       evd.index = index;
+       evd.rate = rate;
+       rate_control_pid_event(buf, RC_PID_EVENT_TYPE_RATE_CHANGE, &evd);
+}
+
+void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
+                                          int index, int rate)
+{
+       union rc_pid_event_data evd;
+
+       evd.index = index;
+       evd.rate = rate;
+       rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_RATE, &evd);
+}
+
+void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
+                                            s32 pf_sample, s32 prop_err,
+                                            s32 int_err, s32 der_err)
+{
+       union rc_pid_event_data evd;
+
+       evd.pf_sample = pf_sample;
+       evd.prop_err = prop_err;
+       evd.int_err = int_err;
+       evd.der_err = der_err;
+       rate_control_pid_event(buf, RC_PID_EVENT_TYPE_PF_SAMPLE, &evd);
+}
+
+static int rate_control_pid_events_open(struct inode *inode, struct file *file)
+{
+       struct rc_pid_sta_info *sinfo = inode->i_private;
+       struct rc_pid_event_buffer *events = &sinfo->events;
+       struct rc_pid_events_file_info *file_info;
+       unsigned int status;
+
+       /* Allocate a state struct */
+       file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
+       if (file_info == NULL)
+               return -ENOMEM;
+
+       spin_lock_irqsave(&events->lock, status);
+
+       file_info->next_entry = events->next_entry;
+       file_info->events = events;
+
+       spin_unlock_irqrestore(&events->lock, status);
+
+       file->private_data = file_info;
+
+       return 0;
+}
+
+static int rate_control_pid_events_release(struct inode *inode,
+                                          struct file *file)
+{
+       struct rc_pid_events_file_info *file_info = file->private_data;
+
+       kfree(file_info);
+
+       return 0;
+}
+
+static unsigned int rate_control_pid_events_poll(struct file *file,
+                                                poll_table *wait)
+{
+       struct rc_pid_events_file_info *file_info = file->private_data;
+
+       poll_wait(file, &file_info->events->waitqueue, wait);
+
+       return POLLIN | POLLRDNORM;
+}
+
+#define RC_PID_PRINT_BUF_SIZE 64
+
+static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
+                                           size_t length, loff_t *offset)
+{
+       struct rc_pid_events_file_info *file_info = file->private_data;
+       struct rc_pid_event_buffer *events = file_info->events;
+       struct rc_pid_event *ev;
+       char pb[RC_PID_PRINT_BUF_SIZE];
+       int ret;
+       int p;
+       unsigned int status;
+
+       /* Check if there is something to read. */
+       if (events->next_entry == file_info->next_entry) {
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+
+               /* Wait */
+               ret = wait_event_interruptible(events->waitqueue,
+                               events->next_entry != file_info->next_entry);
+
+               if (ret)
+                       return ret;
+       }
+
+       /* Write out one event per call. I don't care whether it's a little
+        * inefficient, this is debugging code anyway. */
+       spin_lock_irqsave(&events->lock, status);
+
+       /* Get an event */
+       ev = &(events->ring[file_info->next_entry]);
+       file_info->next_entry = (file_info->next_entry + 1) %
+                               RC_PID_EVENT_RING_SIZE;
+
+       /* Print information about the event. Note that userpace needs to
+        * provide large enough buffers. */
+       length = length < RC_PID_PRINT_BUF_SIZE ?
+                length : RC_PID_PRINT_BUF_SIZE;
+       p = snprintf(pb, length, "%u %lu ", ev->id, ev->timestamp);
+       switch (ev->type) {
+       case RC_PID_EVENT_TYPE_TX_STATUS:
+               p += snprintf(pb + p, length - p, "tx_status %u %u",
+                             ev->data.tx_status.excessive_retries,
+                             ev->data.tx_status.retry_count);
+               break;
+       case RC_PID_EVENT_TYPE_RATE_CHANGE:
+               p += snprintf(pb + p, length - p, "rate_change %d %d",
+                             ev->data.index, ev->data.rate);
+               break;
+       case RC_PID_EVENT_TYPE_TX_RATE:
+               p += snprintf(pb + p, length - p, "tx_rate %d %d",
+                             ev->data.index, ev->data.rate);
+               break;
+       case RC_PID_EVENT_TYPE_PF_SAMPLE:
+               p += snprintf(pb + p, length - p,
+                             "pf_sample %d %d %d %d",
+                             ev->data.pf_sample, ev->data.prop_err,
+                             ev->data.int_err, ev->data.der_err);
+               break;
+       }
+       p += snprintf(pb + p, length - p, "\n");
+
+       spin_unlock_irqrestore(&events->lock, status);
+
+       if (copy_to_user(buf, pb, p))
+               return -EFAULT;
+
+       return p;
+}
+
+#undef RC_PID_PRINT_BUF_SIZE
+
+static struct file_operations rc_pid_fop_events = {
+       .owner = THIS_MODULE,
+       .read = rate_control_pid_events_read,
+       .poll = rate_control_pid_events_poll,
+       .open = rate_control_pid_events_open,
+       .release = rate_control_pid_events_release,
+};
+
+void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
+                                            struct dentry *dir)
+{
+       struct rc_pid_sta_info *spinfo = priv_sta;
+
+       spinfo->events_entry = debugfs_create_file("rc_pid_events", S_IRUGO,
+                                                  dir, spinfo,
+                                                  &rc_pid_fop_events);
+}
+
+void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta)
+{
+       struct rc_pid_sta_info *spinfo = priv_sta;
+
+       debugfs_remove(spinfo->events_entry);
+}
index da72737364e42bb5d8fc68255603befad39bd535..934676d687d6f9b674c837181603b91e4aad2a6f 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/compiler.h>
+#include <linux/module.h>
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
@@ -23,6 +24,8 @@
 /* This is a minimal implementation of TX rate controlling that can be used
  * as the default when no improved mechanisms are available. */
 
+#define RATE_CONTROL_NUM_DOWN 20
+#define RATE_CONTROL_NUM_UP   15
 
 #define RATE_CONTROL_EMERG_DEC 2
 #define RATE_CONTROL_INTERVAL (HZ / 20)
@@ -87,26 +90,6 @@ static void rate_control_rate_dec(struct ieee80211_local *local,
        }
 }
 
-
-static struct ieee80211_rate *
-rate_control_lowest_rate(struct ieee80211_local *local,
-                        struct ieee80211_hw_mode *mode)
-{
-       int i;
-
-       for (i = 0; i < mode->num_rates; i++) {
-               struct ieee80211_rate *rate = &mode->rates[i];
-
-               if (rate->flags & IEEE80211_RATE_SUPPORTED)
-                       return rate;
-       }
-
-       printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates "
-              "found\n");
-       return &mode->rates[0];
-}
-
-
 struct global_rate_control {
        int dummy;
 };
@@ -216,35 +199,33 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev,
 }
 
 
-static struct ieee80211_rate *
+static void
 rate_control_simple_get_rate(void *priv, struct net_device *dev,
+                            struct ieee80211_hw_mode *mode,
                             struct sk_buff *skb,
-                            struct rate_control_extra *extra)
+                            struct rate_selection *sel)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_sub_if_data *sdata;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_hw_mode *mode = extra->mode;
+       struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
-       int rateidx, nonerp_idx;
+       int rateidx;
        u16 fc;
 
-       memset(extra, 0, sizeof(*extra));
+       sta = sta_info_get(local, hdr->addr1);
 
+       /* Send management frames and broadcast/multicast data using lowest
+        * rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           (hdr->addr1[0] & 0x01)) {
-               /* Send management frames and broadcast/multicast data using
-                * lowest rate. */
-               /* TODO: this could probably be improved.. */
-               return rate_control_lowest_rate(local, mode);
+           is_multicast_ether_addr(hdr->addr1) || !sta) {
+               sel->rate = rate_lowest(local, mode, sta);
+               if (sta)
+                       sta_info_put(sta);
+               return;
        }
 
-       sta = sta_info_get(local, hdr->addr1);
-
-       if (!sta)
-               return rate_control_lowest_rate(local, mode);
-
+       /* If a forced rate is in effect, select it. */
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (sdata->bss && sdata->bss->force_unicast_rateidx > -1)
                sta->txrate = sdata->bss->force_unicast_rateidx;
@@ -255,17 +236,10 @@ rate_control_simple_get_rate(void *priv, struct net_device *dev,
                rateidx = mode->num_rates - 1;
 
        sta->last_txrate = rateidx;
-       nonerp_idx = rateidx;
-       while (nonerp_idx > 0 &&
-              ((mode->rates[nonerp_idx].flags & IEEE80211_RATE_ERP) ||
-               !(mode->rates[nonerp_idx].flags & IEEE80211_RATE_SUPPORTED) ||
-               !(sta->supp_rates & BIT(nonerp_idx))))
-               nonerp_idx--;
-       extra->nonerp = &mode->rates[nonerp_idx];
 
        sta_info_put(sta);
 
-       return &mode->rates[rateidx];
+       sel->rate = &mode->rates[rateidx];
 }
 
 
@@ -391,7 +365,7 @@ static void rate_control_simple_remove_sta_debugfs(void *priv, void *priv_sta)
 }
 #endif
 
-struct rate_control_ops mac80211_rcsimple = {
+static struct rate_control_ops mac80211_rcsimple = {
        .name = "simple",
        .tx_status = rate_control_simple_tx_status,
        .get_rate = rate_control_simple_get_rate,
@@ -406,3 +380,21 @@ struct rate_control_ops mac80211_rcsimple = {
        .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
 #endif
 };
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Simple rate control algorithm");
+
+int __init rc80211_simple_init(void)
+{
+       return ieee80211_rate_control_register(&mac80211_rcsimple);
+}
+
+void __exit rc80211_simple_exit(void)
+{
+       ieee80211_rate_control_unregister(&mac80211_rcsimple);
+}
+
+#ifdef CONFIG_MAC80211_RC_SIMPLE_MODULE
+module_init(rc80211_simple_init);
+module_exit(rc80211_simple_exit);
+#endif
index 00f908d9275e3e69a92daf1cc4d6741015d051d5..89e1e3070ec17e048bf9b79606d7b07935c14990 100644 (file)
 #include "tkip.h"
 #include "wme.h"
 
+u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+                               struct tid_ampdu_rx *tid_agg_rx,
+                               struct sk_buff *skb, u16 mpdu_seq_num,
+                               int bar_req);
 /*
  * monitor mode reception
  *
@@ -61,8 +65,12 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status,
                return 1;
        if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len))
                return 1;
-       if ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
-                       cpu_to_le16(IEEE80211_FTYPE_CTL))
+       if (((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) ==
+                       cpu_to_le16(IEEE80211_FTYPE_CTL)) &&
+           ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) !=
+                       cpu_to_le16(IEEE80211_STYPE_PSPOLL)) &&
+           ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) !=
+                       cpu_to_le16(IEEE80211_STYPE_BACK_REQ)))
                return 1;
        return 0;
 }
@@ -79,8 +87,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_rate *rate;
        int needed_headroom = 0;
-       struct ieee80211_rtap_hdr {
-               struct ieee80211_radiotap_header hdr;
+       struct ieee80211_radiotap_header *rthdr;
+       __le64 *rttsft = NULL;
+       struct ieee80211_rtap_fixed_data {
                u8 flags;
                u8 rate;
                __le16 chan_freq;
@@ -88,7 +97,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                u8 antsignal;
                u8 padding_for_rxflags;
                __le16 rx_flags;
-       } __attribute__ ((packed)) *rthdr;
+       } __attribute__ ((packed)) *rtfixed;
        struct sk_buff *skb, *skb2;
        struct net_device *prev_dev = NULL;
        int present_fcs_len = 0;
@@ -105,7 +114,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
        if (status->flag & RX_FLAG_RADIOTAP)
                rtap_len = ieee80211_get_radiotap_len(origskb->data);
        else
-               needed_headroom = sizeof(*rthdr);
+               /* room for radiotap header, always present fields and TSFT */
+               needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8;
 
        if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
                present_fcs_len = FCS_LEN;
@@ -133,7 +143,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                 * them allocate enough headroom to start with.
                 */
                if (skb_headroom(skb) < needed_headroom &&
-                   pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) {
+                   pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) {
                        dev_kfree_skb(skb);
                        return NULL;
                }
@@ -152,45 +162,59 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
 
        /* if necessary, prepend radiotap information */
        if (!(status->flag & RX_FLAG_RADIOTAP)) {
+               rtfixed = (void *) skb_push(skb, sizeof(*rtfixed));
+               rtap_len = sizeof(*rthdr) + sizeof(*rtfixed);
+               if (status->flag & RX_FLAG_TSFT) {
+                       rttsft = (void *) skb_push(skb, sizeof(*rttsft));
+                       rtap_len += 8;
+               }
                rthdr = (void *) skb_push(skb, sizeof(*rthdr));
                memset(rthdr, 0, sizeof(*rthdr));
-               rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
-               rthdr->hdr.it_present =
+               memset(rtfixed, 0, sizeof(*rtfixed));
+               rthdr->it_present =
                        cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
                                    (1 << IEEE80211_RADIOTAP_RATE) |
                                    (1 << IEEE80211_RADIOTAP_CHANNEL) |
                                    (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) |
                                    (1 << IEEE80211_RADIOTAP_RX_FLAGS));
-               rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ?
-                              IEEE80211_RADIOTAP_F_FCS : 0;
+               rtfixed->flags = 0;
+               if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
+                       rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS;
+
+               if (rttsft) {
+                       *rttsft = cpu_to_le64(status->mactime);
+                       rthdr->it_present |=
+                               cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT);
+               }
 
                /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */
-               rthdr->rx_flags = 0;
+               rtfixed->rx_flags = 0;
                if (status->flag &
                    (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
-                       rthdr->rx_flags |=
+                       rtfixed->rx_flags |=
                                cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS);
 
                rate = ieee80211_get_rate(local, status->phymode,
                                          status->rate);
                if (rate)
-                       rthdr->rate = rate->rate / 5;
+                       rtfixed->rate = rate->rate / 5;
 
-               rthdr->chan_freq = cpu_to_le16(status->freq);
+               rtfixed->chan_freq = cpu_to_le16(status->freq);
 
                if (status->phymode == MODE_IEEE80211A)
-                       rthdr->chan_flags =
+                       rtfixed->chan_flags =
                                cpu_to_le16(IEEE80211_CHAN_OFDM |
                                            IEEE80211_CHAN_5GHZ);
                else
-                       rthdr->chan_flags =
+                       rtfixed->chan_flags =
                                cpu_to_le16(IEEE80211_CHAN_DYN |
                                            IEEE80211_CHAN_2GHZ);
 
-               rthdr->antsignal = status->ssi;
+               rtfixed->antsignal = status->ssi;
+               rthdr->it_len = cpu_to_le16(rtap_len);
        }
 
-       skb_set_mac_header(skb, 0);
+       skb_reset_mac_header(skb);
        skb->ip_summed = CHECKSUM_UNNECESSARY;
        skb->pkt_type = PACKET_OTHERHOST;
        skb->protocol = htons(ETH_P_802_2);
@@ -199,7 +223,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
                if (!netif_running(sdata->dev))
                        continue;
 
-               if (sdata->type != IEEE80211_IF_TYPE_MNTR)
+               if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR)
                        continue;
 
                if (prev_dev) {
@@ -243,6 +267,10 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
                u8 *qc = data + ieee80211_get_hdrlen(rx->fc) - QOS_CONTROL_LEN;
                /* frame has qos control */
                tid = qc[0] & QOS_CONTROL_TID_MASK;
+               if (qc[0] & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+                       rx->flags |= IEEE80211_TXRXD_RX_AMSDU;
+               else
+                       rx->flags &= ~IEEE80211_TXRXD_RX_AMSDU;
        } else {
                if (unlikely((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)) {
                        /* Separate TID for management frames */
@@ -266,11 +294,11 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx)
        return TXRX_CONTINUE;
 }
 
-static ieee80211_txrx_result
-ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
+
+static u32 ieee80211_rx_load_stats(struct ieee80211_local *local,
+                             struct sk_buff *skb,
+                             struct ieee80211_rx_status *status)
 {
-       struct ieee80211_local *local = rx->local;
-       struct sk_buff *skb = rx->skb;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        u32 load = 0, hdrtime;
        struct ieee80211_rate *rate;
@@ -284,7 +312,7 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
 
        rate = &mode->rates[0];
        for (i = 0; i < mode->num_rates; i++) {
-               if (mode->rates[i].val == rx->u.rx.status->rate) {
+               if (mode->rates[i].val == status->rate) {
                        rate = &mode->rates[i];
                        break;
                }
@@ -308,16 +336,13 @@ ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx)
 
        /* Divide channel_use by 8 to avoid wrapping around the counter */
        load >>= CHAN_UTIL_SHIFT;
-       local->channel_use_raw += load;
-       rx->u.rx.load = load;
 
-       return TXRX_CONTINUE;
+       return load;
 }
 
 ieee80211_rx_handler ieee80211_rx_pre_handlers[] =
 {
        ieee80211_rx_h_parse_qos,
-       ieee80211_rx_h_load_stats,
        NULL
 };
 
@@ -338,8 +363,14 @@ ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
        struct ieee80211_local *local = rx->local;
        struct sk_buff *skb = rx->skb;
 
-       if (unlikely(local->sta_scanning != 0)) {
-               ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status);
+       if (unlikely(local->sta_hw_scanning))
+               return ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status);
+
+       if (unlikely(local->sta_sw_scanning)) {
+               /* drop all the other packets during a software scan anyway */
+               if (ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status)
+                   != TXRX_QUEUED)
+                       dev_kfree_skb(skb);
                return TXRX_QUEUED;
        }
 
@@ -377,18 +408,6 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
                return TXRX_DROP;
        }
 
-       if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-               rx->skb->pkt_type = PACKET_OTHERHOST;
-       else if (compare_ether_addr(rx->dev->dev_addr, hdr->addr1) == 0)
-               rx->skb->pkt_type = PACKET_HOST;
-       else if (is_multicast_ether_addr(hdr->addr1)) {
-               if (is_broadcast_ether_addr(hdr->addr1))
-                       rx->skb->pkt_type = PACKET_BROADCAST;
-               else
-                       rx->skb->pkt_type = PACKET_MULTICAST;
-       } else
-               rx->skb->pkt_type = PACKET_OTHERHOST;
-
        /* Drop disallowed frame classes based on STA auth/assoc state;
         * IEEE 802.11, Chap 5.5.
         *
@@ -400,7 +419,7 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
        if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA ||
                      ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
                       (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
-                    rx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
+                    rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
                     (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) {
                if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
                     !(rx->fc & IEEE80211_FCTL_TODS) &&
@@ -620,13 +639,14 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx)
        /* Update last_rx only for IBSS packets which are for the current
         * BSSID to avoid keeping the current IBSS network alive in cases where
         * other STAs are using different BSSID. */
-       if (rx->sdata->type == IEEE80211_IF_TYPE_IBSS) {
-               u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len);
+       if (rx->sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
+               u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
+                                               IEEE80211_IF_TYPE_IBSS);
                if (compare_ether_addr(bssid, rx->sdata->u.sta.bssid) == 0)
                        sta->last_rx = jiffies;
        } else
        if (!is_multicast_ether_addr(hdr->addr1) ||
-           rx->sdata->type == IEEE80211_IF_TYPE_STA) {
+           rx->sdata->vif.type == IEEE80211_IF_TYPE_STA) {
                /* Update last_rx only for unicast frames in order to prevent
                 * the Probe Request frames (the only broadcast frames from a
                 * STA in infrastructure mode) from keeping a connection alive.
@@ -870,6 +890,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx)
 static ieee80211_txrx_result
 ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
 {
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
        struct sk_buff *skb;
        int no_pending_pkts;
        DECLARE_MAC_BUF(mac);
@@ -880,6 +901,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
                   !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)))
                return TXRX_CONTINUE;
 
+       if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) &&
+           (sdata->vif.type != IEEE80211_IF_TYPE_VLAN))
+               return TXRX_DROP;
+
        skb = skb_dequeue(&rx->sta->tx_filtered);
        if (!skb) {
                skb = skb_dequeue(&rx->sta->ps_tx_buf);
@@ -956,68 +981,54 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx)
        return TXRX_CONTINUE;
 }
 
-static ieee80211_txrx_result
-ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx)
+static int
+ieee80211_802_1x_port_control(struct ieee80211_txrx_data *rx)
 {
-       if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) &&
-           rx->sdata->type != IEEE80211_IF_TYPE_STA &&
-           (rx->flags & IEEE80211_TXRXD_RXRA_MATCH))
-               return TXRX_CONTINUE;
-
-       if (unlikely(rx->sdata->ieee802_1x &&
-                    (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
-                    (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
-                    (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)) &&
-                    !ieee80211_is_eapol(rx->skb))) {
+       if (unlikely(rx->sdata->ieee802_1x_pac &&
+                    (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)))) {
 #ifdef CONFIG_MAC80211_DEBUG
-               struct ieee80211_hdr *hdr =
-                       (struct ieee80211_hdr *) rx->skb->data;
-               DECLARE_MAC_BUF(mac);
-               printk(KERN_DEBUG "%s: dropped frame from %s"
-                      " (unauthorized port)\n", rx->dev->name,
-                      print_mac(mac, hdr->addr2));
+               printk(KERN_DEBUG "%s: dropped frame "
+                      "(unauthorized port)\n", rx->dev->name);
 #endif /* CONFIG_MAC80211_DEBUG */
-               return TXRX_DROP;
+               return -EACCES;
        }
 
-       return TXRX_CONTINUE;
+       return 0;
 }
 
-static ieee80211_txrx_result
-ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
+static int
+ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx)
 {
        /*
         * Pass through unencrypted frames if the hardware has
         * decrypted them already.
         */
        if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED)
-               return TXRX_CONTINUE;
+               return 0;
 
        /* Drop unencrypted frames if key is set. */
        if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
                     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
                     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
-                    (rx->key || rx->sdata->drop_unencrypted) &&
-                    (rx->sdata->eapol == 0 || !ieee80211_is_eapol(rx->skb)))) {
+                    (rx->key || rx->sdata->drop_unencrypted))) {
                if (net_ratelimit())
                        printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
                               "encryption\n", rx->dev->name);
-               return TXRX_DROP;
+               return -EACCES;
        }
-       return TXRX_CONTINUE;
+       return 0;
 }
 
-static ieee80211_txrx_result
-ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
+static int
+ieee80211_data_to_8023(struct ieee80211_txrx_data *rx)
 {
        struct net_device *dev = rx->dev;
-       struct ieee80211_local *local = rx->local;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
        u16 fc, hdrlen, ethertype;
        u8 *payload;
        u8 dst[ETH_ALEN];
        u8 src[ETH_ALEN];
-       struct sk_buff *skb = rx->skb, *skb2;
+       struct sk_buff *skb = rx->skb;
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        DECLARE_MAC_BUF(mac);
        DECLARE_MAC_BUF(mac2);
@@ -1025,11 +1036,9 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
        DECLARE_MAC_BUF(mac4);
 
        fc = rx->fc;
-       if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
-               return TXRX_CONTINUE;
 
        if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-               return TXRX_DROP;
+               return -1;
 
        hdrlen = ieee80211_get_hdrlen(fc);
 
@@ -1049,8 +1058,8 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                memcpy(dst, hdr->addr3, ETH_ALEN);
                memcpy(src, hdr->addr2, ETH_ALEN);
 
-               if (unlikely(sdata->type != IEEE80211_IF_TYPE_AP &&
-                            sdata->type != IEEE80211_IF_TYPE_VLAN)) {
+               if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP &&
+                            sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) {
                        if (net_ratelimit())
                                printk(KERN_DEBUG "%s: dropped ToDS frame "
                                       "(BSSID=%s SA=%s DA=%s)\n",
@@ -1058,7 +1067,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                                       print_mac(mac, hdr->addr1),
                                       print_mac(mac2, hdr->addr2),
                                       print_mac(mac3, hdr->addr3));
-                       return TXRX_DROP;
+                       return -1;
                }
                break;
        case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
@@ -1066,7 +1075,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                memcpy(dst, hdr->addr3, ETH_ALEN);
                memcpy(src, hdr->addr4, ETH_ALEN);
 
-               if (unlikely(sdata->type != IEEE80211_IF_TYPE_WDS)) {
+               if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS)) {
                        if (net_ratelimit())
                                printk(KERN_DEBUG "%s: dropped FromDS&ToDS "
                                       "frame (RA=%s TA=%s DA=%s SA=%s)\n",
@@ -1075,7 +1084,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                                       print_mac(mac2, hdr->addr2),
                                       print_mac(mac3, hdr->addr3),
                                       print_mac(mac4, hdr->addr4));
-                       return TXRX_DROP;
+                       return -1;
                }
                break;
        case IEEE80211_FCTL_FROMDS:
@@ -1083,17 +1092,17 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                memcpy(dst, hdr->addr1, ETH_ALEN);
                memcpy(src, hdr->addr3, ETH_ALEN);
 
-               if (sdata->type != IEEE80211_IF_TYPE_STA ||
+               if (sdata->vif.type != IEEE80211_IF_TYPE_STA ||
                    (is_multicast_ether_addr(dst) &&
                     !compare_ether_addr(src, dev->dev_addr)))
-                       return TXRX_DROP;
+                       return -1;
                break;
        case 0:
                /* DA SA BSSID */
                memcpy(dst, hdr->addr1, ETH_ALEN);
                memcpy(src, hdr->addr2, ETH_ALEN);
 
-               if (sdata->type != IEEE80211_IF_TYPE_IBSS) {
+               if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) {
                        if (net_ratelimit()) {
                                printk(KERN_DEBUG "%s: dropped IBSS frame "
                                       "(DA=%s SA=%s BSSID=%s)\n",
@@ -1102,21 +1111,20 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                                       print_mac(mac2, hdr->addr2),
                                       print_mac(mac3, hdr->addr3));
                        }
-                       return TXRX_DROP;
+                       return -1;
                }
                break;
        }
 
-       payload = skb->data + hdrlen;
-
        if (unlikely(skb->len - hdrlen < 8)) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: RX too short data frame "
                               "payload\n", dev->name);
                }
-               return TXRX_DROP;
+               return -1;
        }
 
+       payload = skb->data + hdrlen;
        ethertype = (payload[6] << 8) | payload[7];
 
        if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
@@ -1130,6 +1138,7 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
        } else {
                struct ethhdr *ehdr;
                __be16 len;
+
                skb_pull(skb, hdrlen);
                len = htons(skb->len);
                ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
@@ -1137,36 +1146,72 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                memcpy(ehdr->h_source, src, ETH_ALEN);
                ehdr->h_proto = len;
        }
-       skb->dev = dev;
+       return 0;
+}
 
-       skb2 = NULL;
+/*
+ * requires that rx->skb is a frame with ethernet header
+ */
+static bool ieee80211_frame_allowed(struct ieee80211_txrx_data *rx)
+{
+       static const u8 pae_group_addr[ETH_ALEN]
+               = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
+       struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
 
-       dev->stats.rx_packets++;
-       dev->stats.rx_bytes += skb->len;
+       /*
+        * Allow EAPOL frames to us/the PAE group address regardless
+        * of whether the frame was encrypted or not.
+        */
+       if (ehdr->h_proto == htons(ETH_P_PAE) &&
+           (compare_ether_addr(ehdr->h_dest, rx->dev->dev_addr) == 0 ||
+            compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0))
+               return true;
+
+       if (ieee80211_802_1x_port_control(rx) ||
+           ieee80211_drop_unencrypted(rx))
+               return false;
 
-       if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP
-           || sdata->type == IEEE80211_IF_TYPE_VLAN) &&
+       return true;
+}
+
+/*
+ * requires that rx->skb is a frame with ethernet header
+ */
+static void
+ieee80211_deliver_skb(struct ieee80211_txrx_data *rx)
+{
+       struct net_device *dev = rx->dev;
+       struct ieee80211_local *local = rx->local;
+       struct sk_buff *skb, *xmit_skb;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
+       struct sta_info *dsta;
+
+       skb = rx->skb;
+       xmit_skb = NULL;
+
+       if (local->bridge_packets && (sdata->vif.type == IEEE80211_IF_TYPE_AP ||
+                                     sdata->vif.type == IEEE80211_IF_TYPE_VLAN) &&
            (rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) {
-               if (is_multicast_ether_addr(skb->data)) {
-                       /* send multicast frames both to higher layers in
-                        * local net stack and back to the wireless media */
-                       skb2 = skb_copy(skb, GFP_ATOMIC);
-                       if (!skb2 && net_ratelimit())
+               if (is_multicast_ether_addr(ehdr->h_dest)) {
+                       /*
+                        * send multicast frames both to higher layers in
+                        * local net stack and back to the wireless medium
+                        */
+                       xmit_skb = skb_copy(skb, GFP_ATOMIC);
+                       if (!xmit_skb && net_ratelimit())
                                printk(KERN_DEBUG "%s: failed to clone "
                                       "multicast frame\n", dev->name);
                } else {
-                       struct sta_info *dsta;
                        dsta = sta_info_get(local, skb->data);
-                       if (dsta && !dsta->dev) {
-                               if (net_ratelimit())
-                                       printk(KERN_DEBUG "Station with null "
-                                              "dev structure!\n");
-                       } else if (dsta && dsta->dev == dev) {
-                               /* Destination station is associated to this
-                                * AP, so send the frame directly to it and
-                                * do not pass the frame to local net stack.
+                       if (dsta && dsta->dev == dev) {
+                               /*
+                                * The destination station is associated to
+                                * this AP (in this VLAN), so send the frame
+                                * directly to it and do not pass it to local
+                                * net stack.
                                 */
-                               skb2 = skb;
+                               xmit_skb = skb;
                                skb = NULL;
                        }
                        if (dsta)
@@ -1181,17 +1226,206 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
                netif_rx(skb);
        }
 
-       if (skb2) {
+       if (xmit_skb) {
                /* send to wireless media */
-               skb2->protocol = __constant_htons(ETH_P_802_3);
-               skb_set_network_header(skb2, 0);
-               skb_set_mac_header(skb2, 0);
-               dev_queue_xmit(skb2);
+               xmit_skb->protocol = htons(ETH_P_802_3);
+               skb_reset_network_header(xmit_skb);
+               skb_reset_mac_header(xmit_skb);
+               dev_queue_xmit(xmit_skb);
        }
+}
+
+static ieee80211_txrx_result
+ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx)
+{
+       struct net_device *dev = rx->dev;
+       struct ieee80211_local *local = rx->local;
+       u16 fc, ethertype;
+       u8 *payload;
+       struct sk_buff *skb = rx->skb, *frame = NULL;
+       const struct ethhdr *eth;
+       int remaining, err;
+       u8 dst[ETH_ALEN];
+       u8 src[ETH_ALEN];
+       DECLARE_MAC_BUF(mac);
+
+       fc = rx->fc;
+       if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
+               return TXRX_CONTINUE;
+
+       if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
+               return TXRX_DROP;
+
+       if (!(rx->flags & IEEE80211_TXRXD_RX_AMSDU))
+               return TXRX_CONTINUE;
+
+       err = ieee80211_data_to_8023(rx);
+       if (unlikely(err))
+               return TXRX_DROP;
+
+       skb->dev = dev;
+
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += skb->len;
+
+       /* skip the wrapping header */
+       eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
+       if (!eth)
+               return TXRX_DROP;
+
+       while (skb != frame) {
+               u8 padding;
+               __be16 len = eth->h_proto;
+               unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len);
+
+               remaining = skb->len;
+               memcpy(dst, eth->h_dest, ETH_ALEN);
+               memcpy(src, eth->h_source, ETH_ALEN);
+
+               padding = ((4 - subframe_len) & 0x3);
+               /* the last MSDU has no padding */
+               if (subframe_len > remaining) {
+                       printk(KERN_DEBUG "%s: wrong buffer size", dev->name);
+                       return TXRX_DROP;
+               }
+
+               skb_pull(skb, sizeof(struct ethhdr));
+               /* if last subframe reuse skb */
+               if (remaining <= subframe_len + padding)
+                       frame = skb;
+               else {
+                       frame = dev_alloc_skb(local->hw.extra_tx_headroom +
+                                             subframe_len);
+
+                       if (frame == NULL)
+                               return TXRX_DROP;
+
+                       skb_reserve(frame, local->hw.extra_tx_headroom +
+                                   sizeof(struct ethhdr));
+                       memcpy(skb_put(frame, ntohs(len)), skb->data,
+                               ntohs(len));
+
+                       eth = (struct ethhdr *) skb_pull(skb, ntohs(len) +
+                                                       padding);
+                       if (!eth) {
+                               printk(KERN_DEBUG "%s: wrong buffer size ",
+                                      dev->name);
+                               dev_kfree_skb(frame);
+                               return TXRX_DROP;
+                       }
+               }
+
+               skb_reset_network_header(frame);
+               frame->dev = dev;
+               frame->priority = skb->priority;
+               rx->skb = frame;
+
+               payload = frame->data;
+               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(frame, 6);
+                       memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
+                       memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
+               } else {
+                       memcpy(skb_push(frame, sizeof(__be16)),
+                              &len, sizeof(__be16));
+                       memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
+                       memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
+               }
+
+               if (!ieee80211_frame_allowed(rx)) {
+                       if (skb == frame) /* last frame */
+                               return TXRX_DROP;
+                       dev_kfree_skb(frame);
+                       continue;
+               }
+
+               ieee80211_deliver_skb(rx);
+       }
+
+       return TXRX_QUEUED;
+}
+
+static ieee80211_txrx_result
+ieee80211_rx_h_data(struct ieee80211_txrx_data *rx)
+{
+       struct net_device *dev = rx->dev;
+       u16 fc;
+       int err;
+
+       fc = rx->fc;
+       if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
+               return TXRX_CONTINUE;
+
+       if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
+               return TXRX_DROP;
+
+       err = ieee80211_data_to_8023(rx);
+       if (unlikely(err))
+               return TXRX_DROP;
+
+       if (!ieee80211_frame_allowed(rx))
+               return TXRX_DROP;
+
+       rx->skb->dev = dev;
+
+       dev->stats.rx_packets++;
+       dev->stats.rx_bytes += rx->skb->len;
+
+       ieee80211_deliver_skb(rx);
 
        return TXRX_QUEUED;
 }
 
+static ieee80211_txrx_result
+ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx)
+{
+       struct ieee80211_local *local = rx->local;
+       struct ieee80211_hw *hw = &local->hw;
+       struct sk_buff *skb = rx->skb;
+       struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data;
+       struct tid_ampdu_rx *tid_agg_rx;
+       u16 start_seq_num;
+       u16 tid;
+
+       if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL))
+               return TXRX_CONTINUE;
+
+       if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) {
+               if (!rx->sta)
+                       return TXRX_CONTINUE;
+               tid = le16_to_cpu(bar->control) >> 12;
+               tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]);
+               if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL)
+                       return TXRX_CONTINUE;
+
+               start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
+
+               /* reset session timer */
+               if (tid_agg_rx->timeout) {
+                       unsigned long expires =
+                               jiffies + (tid_agg_rx->timeout / 1000) * HZ;
+                       mod_timer(&tid_agg_rx->session_timer, expires);
+               }
+
+               /* manage reordering buffer according to requested */
+               /* sequence number */
+               rcu_read_lock();
+               ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL,
+                                                start_seq_num, 1);
+               rcu_read_unlock();
+               return TXRX_DROP;
+       }
+
+       return TXRX_CONTINUE;
+}
+
 static ieee80211_txrx_result
 ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx)
 {
@@ -1201,8 +1435,8 @@ ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx)
                return TXRX_DROP;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
-       if ((sdata->type == IEEE80211_IF_TYPE_STA ||
-            sdata->type == IEEE80211_IF_TYPE_IBSS) &&
+       if ((sdata->vif.type == IEEE80211_IF_TYPE_STA ||
+            sdata->vif.type == IEEE80211_IF_TYPE_IBSS) &&
            !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
                ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status);
        else
@@ -1294,7 +1528,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
                goto ignore;
        }
 
-       if (rx->sdata->type == IEEE80211_IF_TYPE_AP && keyidx) {
+       if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) {
                /*
                 * APs with pairwise keys should never receive Michael MIC
                 * errors for non-zero keyidx because these are reserved for
@@ -1341,9 +1575,9 @@ ieee80211_rx_handler ieee80211_rx_handlers[] =
         * are not passed to user space by these functions
         */
        ieee80211_rx_h_remove_qos_control,
-       ieee80211_rx_h_802_1x_pae,
-       ieee80211_rx_h_drop_unencrypted,
+       ieee80211_rx_h_amsdu,
        ieee80211_rx_h_data,
+       ieee80211_rx_h_ctrl,
        ieee80211_rx_h_mgmt,
        NULL
 };
@@ -1356,7 +1590,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
 {
        int multicast = is_multicast_ether_addr(hdr->addr1);
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_STA:
                if (!bssid)
                        return 0;
@@ -1427,11 +1661,13 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
 }
 
 /*
- * This is the receive path handler. It is called by a low level driver when an
- * 802.11 MPDU is received from the hardware.
+ * This is the actual Rx frames handler. as it blongs to Rx path it must
+ * be called with rcu_read_lock protection.
  */
-void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
-                   struct ieee80211_rx_status *status)
+static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
+                                        struct sk_buff *skb,
+                                        struct ieee80211_rx_status *status,
+                                        u32 load)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
@@ -1439,29 +1675,11 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
        struct ieee80211_hdr *hdr;
        struct ieee80211_txrx_data rx;
        u16 type;
-       int prepres;
+       int prepares;
        struct ieee80211_sub_if_data *prev = NULL;
        struct sk_buff *skb_new;
        u8 *bssid;
-
-       /*
-        * key references and virtual interfaces are protected using RCU
-        * and this requires that we are in a read-side RCU section during
-        * receive processing
-        */
-       rcu_read_lock();
-
-       /*
-        * Frames with failed FCS/PLCP checksum are not returned,
-        * all other frames are returned without radiotap header
-        * if it was previously present.
-        * Also, frames with less than 16 bytes are dropped.
-        */
-       skb = ieee80211_rx_monitor(local, skb, status);
-       if (!skb) {
-               rcu_read_unlock();
-               return;
-       }
+       int hdrlen;
 
        hdr = (struct ieee80211_hdr *) skb->data;
        memset(&rx, 0, sizeof(rx));
@@ -1469,9 +1687,22 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
        rx.local = local;
 
        rx.u.rx.status = status;
+       rx.u.rx.load = load;
        rx.fc = le16_to_cpu(hdr->frame_control);
        type = rx.fc & IEEE80211_FCTL_FTYPE;
 
+       /*
+        * Drivers are required to align the payload data to a four-byte
+        * boundary, so the last two bits of the address where it starts
+        * may not be set. The header is required to be directly before
+        * the payload data, padding like atheros hardware adds which is
+        * inbetween the 802.11 header and the payload is not supported,
+        * the driver is required to move the 802.11 header further back
+        * in that case.
+        */
+       hdrlen = ieee80211_get_hdrlen(rx.fc);
+       WARN_ON_ONCE(((unsigned long)(skb->data + hdrlen)) & 3);
+
        if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT)
                local->dot11ReceivedFragmentCount++;
 
@@ -1486,7 +1717,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                goto end;
        }
 
-       if (unlikely(local->sta_scanning))
+       if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning))
                rx.flags |= IEEE80211_TXRXD_RXIN_SCAN;
 
        if (__ieee80211_invoke_rx_handlers(local, local->rx_pre_handlers, &rx,
@@ -1501,25 +1732,23 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx,
                                             rx.sta);
                sta_info_put(sta);
-               rcu_read_unlock();
                return;
        }
 
-       bssid = ieee80211_get_bssid(hdr, skb->len);
-
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                if (!netif_running(sdata->dev))
                        continue;
 
-               if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+               if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR)
                        continue;
 
+               bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
                rx.flags |= IEEE80211_TXRXD_RXRA_MATCH;
-               prepres = prepare_for_handlers(sdata, bssid, &rx, hdr);
+               prepares = prepare_for_handlers(sdata, bssid, &rx, hdr);
                /* prepare_for_handlers can change sta */
                sta = rx.sta;
 
-               if (!prepres)
+               if (!prepares)
                        continue;
 
                /*
@@ -1547,6 +1776,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                                       prev->dev->name);
                        continue;
                }
+               rx.fc = le16_to_cpu(hdr->frame_control);
                rx.skb = skb_new;
                rx.dev = prev->dev;
                rx.sdata = prev;
@@ -1555,6 +1785,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                prev = sdata;
        }
        if (prev) {
+               rx.fc = le16_to_cpu(hdr->frame_control);
                rx.skb = skb;
                rx.dev = prev->dev;
                rx.sdata = prev;
@@ -1564,10 +1795,230 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                dev_kfree_skb(skb);
 
  end:
-       rcu_read_unlock();
+       if (sta)
+               sta_info_put(sta);
+}
+
+#define SEQ_MODULO 0x1000
+#define SEQ_MASK   0xfff
+
+static inline int seq_less(u16 sq1, u16 sq2)
+{
+       return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1));
+}
+
+static inline u16 seq_inc(u16 sq)
+{
+       return ((sq + 1) & SEQ_MASK);
+}
+
+static inline u16 seq_sub(u16 sq1, u16 sq2)
+{
+       return ((sq1 - sq2) & SEQ_MASK);
+}
+
+
+/*
+ * As it function blongs to Rx path it must be called with
+ * the proper rcu_read_lock protection for its flow.
+ */
+u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+                               struct tid_ampdu_rx *tid_agg_rx,
+                               struct sk_buff *skb, 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;
+       u32 pkt_load;
+
+       buf_size = tid_agg_rx->buf_size;
+       head_seq_num = tid_agg_rx->head_seq_num;
+
+       /* frame with out of date sequence number */
+       if (seq_less(mpdu_seq_num, head_seq_num)) {
+               dev_kfree_skb(skb);
+               return 1;
+       }
+
+       /* if frame sequence number exceeds our buffering window size or
+        * block Ack Request arrived - release stored frames */
+       if ((!seq_less(mpdu_seq_num, head_seq_num + buf_size)) || (bar_req)) {
+               /* new head to the ordering buffer */
+               if (bar_req)
+                       head_seq_num = mpdu_seq_num;
+               else
+                       head_seq_num =
+                               seq_inc(seq_sub(mpdu_seq_num, buf_size));
+               /* release stored frames up to new head to stack */
+               while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) {
+                       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));
+                               pkt_load = ieee80211_rx_load_stats(local,
+                                               tid_agg_rx->reorder_buf[index],
+                                               &status);
+                               __ieee80211_rx_handle_packet(hw,
+                                       tid_agg_rx->reorder_buf[index],
+                                       &status, pkt_load);
+                               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 (bar_req)
+                       return 1;
+       }
+
+       /* now the new frame is always in the range of the reordering */
+       /* buffer window */
+       index = seq_sub(mpdu_seq_num, tid_agg_rx->ssn)
+                               % tid_agg_rx->buf_size;
+       /* check if we already stored this frame */
+       if (tid_agg_rx->reorder_buf[index]) {
+               dev_kfree_skb(skb);
+               return 1;
+       }
 
+       /* if arrived mpdu is in the right order and nothing else stored */
+       /* release it immediately */
+       if (mpdu_seq_num == tid_agg_rx->head_seq_num &&
+                       tid_agg_rx->stored_mpdu_num == 0) {
+               tid_agg_rx->head_seq_num =
+                       seq_inc(tid_agg_rx->head_seq_num);
+               return 0;
+       }
+
+       /* put the frame in the reordering buffer */
+       tid_agg_rx->reorder_buf[index] = skb;
+       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));
+               pkt_load = ieee80211_rx_load_stats(local,
+                                       tid_agg_rx->reorder_buf[index],
+                                       &status);
+               __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
+                                               &status, pkt_load);
+               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);
+               index = seq_sub(tid_agg_rx->head_seq_num,
+                       tid_agg_rx->ssn) % tid_agg_rx->buf_size;
+       }
+       return 1;
+}
+
+static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
+                                    struct sk_buff *skb)
+{
+       struct ieee80211_hw *hw = &local->hw;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       struct sta_info *sta;
+       struct tid_ampdu_rx *tid_agg_rx;
+       u16 fc, sc;
+       u16 mpdu_seq_num;
+       u8 ret = 0, *qc;
+       int tid;
+
+       sta = sta_info_get(local, hdr->addr2);
+       if (!sta)
+               return ret;
+
+       fc = le16_to_cpu(hdr->frame_control);
+
+       /* filter the QoS data rx stream according to
+        * STA/TID and check if this STA/TID is on aggregation */
+       if (!WLAN_FC_IS_QOS_DATA(fc))
+               goto end_reorder;
+
+       qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN;
+       tid = qc[0] & QOS_CONTROL_TID_MASK;
+       tid_agg_rx = &(sta->ampdu_mlme.tid_rx[tid]);
+
+       if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL)
+               goto end_reorder;
+
+       /* null data frames are excluded */
+       if (unlikely(fc & IEEE80211_STYPE_QOS_NULLFUNC))
+               goto end_reorder;
+
+       /* new un-ordered ampdu frame - process it */
+
+       /* reset session timer */
+       if (tid_agg_rx->timeout) {
+               unsigned long expires =
+                       jiffies + (tid_agg_rx->timeout / 1000) * HZ;
+               mod_timer(&tid_agg_rx->session_timer, expires);
+       }
+
+       /* if this mpdu is fragmented - terminate rx aggregation session */
+       sc = le16_to_cpu(hdr->seq_ctrl);
+       if (sc & IEEE80211_SCTL_FRAG) {
+               ieee80211_sta_stop_rx_ba_session(sta->dev, sta->addr,
+                       tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
+               ret = 1;
+               goto end_reorder;
+       }
+
+       /* according to mpdu sequence number deal with reordering buffer */
+       mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4;
+       ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb,
+                                               mpdu_seq_num, 0);
+end_reorder:
        if (sta)
                sta_info_put(sta);
+       return ret;
+}
+
+/*
+ * This is the receive path handler. It is called by a low level driver when an
+ * 802.11 MPDU is received from the hardware.
+ */
+void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
+                   struct ieee80211_rx_status *status)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       u32 pkt_load;
+
+       /*
+        * key references and virtual interfaces are protected using RCU
+        * and this requires that we are in a read-side RCU section during
+        * receive processing
+        */
+       rcu_read_lock();
+
+       /*
+        * Frames with failed FCS/PLCP checksum are not returned,
+        * all other frames are returned without radiotap header
+        * if it was previously present.
+        * Also, frames with less than 16 bytes are dropped.
+        */
+       skb = ieee80211_rx_monitor(local, skb, status);
+       if (!skb) {
+               rcu_read_unlock();
+               return;
+       }
+
+       pkt_load = ieee80211_rx_load_stats(local, skb, status);
+       local->channel_use_raw += pkt_load;
+
+       if (!ieee80211_rx_reorder_ampdu(local, skb))
+               __ieee80211_rx_handle_packet(hw, skb, status, pkt_load);
+
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(__ieee80211_rx);
 
index cfd8ee9adad0e13df8a57d6c95190b15ce3212ab..1f74bd296357bd8785acff1816a635dc98e34d2e 100644 (file)
@@ -104,6 +104,7 @@ static void sta_info_release(struct kref *kref)
        struct sta_info *sta = container_of(kref, struct sta_info, kref);
        struct ieee80211_local *local = sta->local;
        struct sk_buff *skb;
+       int i;
 
        /* free sta structure; it has already been removed from
         * hash table etc. external structures. Make sure that all
@@ -116,6 +117,8 @@ static void sta_info_release(struct kref *kref)
        while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
                dev_kfree_skb_any(skb);
        }
+       for (i = 0; i <  STA_TID_NUM; i++)
+               del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer);
        rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
        rate_control_put(sta->rate_ctrl);
        kfree(sta);
@@ -133,6 +136,7 @@ struct sta_info * sta_info_add(struct ieee80211_local *local,
                               struct net_device *dev, u8 *addr, gfp_t gfp)
 {
        struct sta_info *sta;
+       int i;
        DECLARE_MAC_BUF(mac);
 
        sta = kzalloc(sizeof(*sta), gfp);
@@ -152,6 +156,19 @@ struct sta_info * sta_info_add(struct ieee80211_local *local,
        memcpy(sta->addr, addr, ETH_ALEN);
        sta->local = local;
        sta->dev = dev;
+       spin_lock_init(&sta->ampdu_mlme.ampdu_rx);
+       for (i = 0; i < STA_TID_NUM; i++) {
+               /* timer_to_tid must be initialized with identity mapping to
+                * enable session_timer's data differentiation. refer to
+                * sta_rx_agg_session_timer_expired for useage */
+               sta->timer_to_tid[i] = i;
+               /* rx timers */
+               sta->ampdu_mlme.tid_rx[i].session_timer.function =
+                       sta_rx_agg_session_timer_expired;
+               sta->ampdu_mlme.tid_rx[i].session_timer.data =
+                       (unsigned long)&sta->timer_to_tid[i];
+               init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer);
+       }
        skb_queue_head_init(&sta->ps_tx_buf);
        skb_queue_head_init(&sta->tx_filtered);
        __sta_info_get(sta);    /* sta used by caller, decremented by
@@ -160,9 +177,16 @@ struct sta_info * sta_info_add(struct ieee80211_local *local,
        list_add(&sta->list, &local->sta_list);
        local->num_sta++;
        sta_info_hash_add(local, sta);
-       if (local->ops->sta_notify)
-               local->ops->sta_notify(local_to_hw(local), dev->ifindex,
-                                       STA_NOTIFY_ADD, addr);
+       if (local->ops->sta_notify) {
+               struct ieee80211_sub_if_data *sdata;
+
+               sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+               if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
+                       sdata = sdata->u.vlan.ap;
+
+               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
+                                      STA_NOTIFY_ADD, addr);
+       }
        write_unlock_bh(&local->sta_lock);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -230,9 +254,17 @@ void sta_info_free(struct sta_info *sta)
        ieee80211_key_free(sta->key);
        sta->key = NULL;
 
-       if (local->ops->sta_notify)
-               local->ops->sta_notify(local_to_hw(local), sta->dev->ifindex,
-                                       STA_NOTIFY_REMOVE, sta->addr);
+       if (local->ops->sta_notify) {
+               struct ieee80211_sub_if_data *sdata;
+
+               sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev);
+
+               if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
+                       sdata = sdata->u.vlan.ap;
+
+               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
+                                      STA_NOTIFY_REMOVE, sta->addr);
+       }
 
        rate_control_remove_sta_debugfs(sta);
        ieee80211_sta_debugfs_remove(sta);
@@ -346,11 +378,10 @@ void sta_info_init(struct ieee80211_local *local)
        rwlock_init(&local->sta_lock);
        INIT_LIST_HEAD(&local->sta_list);
 
-       init_timer(&local->sta_cleanup);
+       setup_timer(&local->sta_cleanup, sta_info_cleanup,
+                   (unsigned long)local);
        local->sta_cleanup.expires =
                round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
-       local->sta_cleanup.data = (unsigned long) local;
-       local->sta_cleanup.function = sta_info_cleanup;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        INIT_WORK(&local->sta_debugfs_add, sta_info_debugfs_add_task);
index 8f7ebe41c0246a91d687a1ac91e79509dc062b5f..96fe3ed950385f652e83f936bc53e7c10b91bb88 100644 (file)
 #define WLAN_STA_WME BIT(9)
 #define WLAN_STA_WDS BIT(27)
 
+#define STA_TID_NUM 16
+#define ADDBA_RESP_INTERVAL HZ
+
+#define HT_AGG_STATE_INITIATOR_SHIFT   (4)
+
+#define HT_AGG_STATE_REQ_STOP_BA_MSK   BIT(3)
+
+#define HT_AGG_STATE_IDLE              (0x0)
+#define HT_AGG_STATE_OPERATIONAL       (0x7)
+
+/**
+ * struct tid_ampdu_rx - TID aggregation information (Rx).
+ *
+ * @state: TID's state in session state machine.
+ * @dialog_token: dialog token for aggregation session
+ * @ssn: Starting Sequence Number expected to be aggregated.
+ * @buf_size: buffer size for incoming A-MPDUs
+ * @timeout: reset timer value.
+ * @head_seq_num: head sequence number in reordering buffer.
+ * @stored_mpdu_num: number of MPDUs in reordering buffer
+ * @reorder_buf: buffer to reorder incoming aggregated MPDUs
+ * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
+ */
+struct tid_ampdu_rx {
+       u8 state;
+       u8 dialog_token;
+       u16 ssn;
+       u16 buf_size;
+       u16 timeout;
+       u16 head_seq_num;
+       u16 stored_mpdu_num;
+       struct sk_buff **reorder_buf;
+       struct timer_list session_timer;
+};
+
+/**
+ * struct sta_ampdu_mlme - STA aggregation information.
+ *
+ * @tid_agg_info_rx: aggregation info for Rx per TID
+ * @ampdu_rx: for locking sections in aggregation Rx flow
+ */
+struct sta_ampdu_mlme {
+       struct tid_ampdu_rx tid_rx[STA_TID_NUM];
+       spinlock_t ampdu_rx;
+};
 
 struct sta_info {
        struct kref kref;
@@ -99,6 +144,11 @@ struct sta_info {
 
        u16 listen_interval;
 
+       struct ieee80211_ht_info ht_info; /* 802.11n HT capabilities
+                                            of this STA */
+       struct sta_ampdu_mlme ampdu_mlme;
+       u8 timer_to_tid[STA_TID_NUM];   /* convert timer id to tid */
+
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct sta_info_debugfsdentries {
                struct dentry *dir;
index 1a531543bccb79df167148c001ee0c26c45bb079..67b509edd431024ea62623d023f5cf309005af64 100644 (file)
@@ -176,7 +176,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr,
         * to closest integer */
 
        dur = ieee80211_frame_duration(local, 10, rate, erp,
-                      tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
+                               tx->sdata->bss_conf.use_short_preamble);
 
        if (next_frag_len) {
                /* Frame is fragmented: duration increases with time needed to
@@ -185,8 +185,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr,
                /* next fragment */
                dur += ieee80211_frame_duration(local, next_frag_len,
                                txrate->rate, erp,
-                               tx->sdata->flags &
-                                       IEEE80211_SDATA_SHORT_PREAMBLE);
+                               tx->sdata->bss_conf.use_short_preamble);
        }
 
        return dur;
@@ -225,7 +224,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
        if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED))
                return TXRX_CONTINUE;
 
-       if (unlikely(tx->local->sta_scanning != 0) &&
+       if (unlikely(tx->local->sta_sw_scanning) &&
            ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
             (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
                return TXRX_DROP;
@@ -237,7 +236,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
 
        if (likely(tx->flags & IEEE80211_TXRXD_TXUNICAST)) {
                if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
-                            tx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
+                            tx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
                             (tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                        DECLARE_MAC_BUF(mac);
@@ -251,7 +250,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
        } else {
                if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
                             tx->local->num_sta == 0 &&
-                            tx->sdata->type != IEEE80211_IF_TYPE_IBSS)) {
+                            tx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS)) {
                        /*
                         * No associated STAs - no need to send multicast
                         * frames.
@@ -261,18 +260,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
                return TXRX_CONTINUE;
        }
 
-       if (unlikely(/* !injected && */ tx->sdata->ieee802_1x &&
-                    !(sta_flags & WLAN_STA_AUTHORIZED))) {
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
-               DECLARE_MAC_BUF(mac);
-               printk(KERN_DEBUG "%s: dropped frame to %s"
-                      " (unauthorized port)\n", tx->dev->name,
-                      print_mac(mac, hdr->addr1));
-#endif
-               I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port);
-               return TXRX_DROP;
-       }
-
        return TXRX_CONTINUE;
 }
 
@@ -306,7 +293,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
        list_for_each_entry_rcu(sdata, &local->interfaces, list) {
                struct ieee80211_if_ap *ap;
                if (sdata->dev == local->mdev ||
-                   sdata->type != IEEE80211_IF_TYPE_AP)
+                   sdata->vif.type != IEEE80211_IF_TYPE_AP)
                        continue;
                ap = &sdata->u.ap;
                skb = skb_dequeue(&ap->ps_bc_buf);
@@ -334,16 +321,27 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
               wiphy_name(local->hw.wiphy), purged);
 }
 
-static inline ieee80211_txrx_result
+static ieee80211_txrx_result
 ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
-       /* broadcast/multicast frame */
-       /* If any of the associated stations is in power save mode,
-        * the frame is buffered to be sent after DTIM beacon frame */
-       if ((tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) &&
-           tx->sdata->type != IEEE80211_IF_TYPE_WDS &&
-           tx->sdata->bss && atomic_read(&tx->sdata->bss->num_sta_ps) &&
-           !(tx->fc & IEEE80211_FCTL_ORDER)) {
+       /*
+        * broadcast/multicast frame
+        *
+        * If any of the associated stations is in power save mode,
+        * the frame is buffered to be sent after DTIM beacon frame.
+        * This is done either by the hardware or us.
+        */
+
+       /* not AP/IBSS or ordered frame */
+       if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER))
+               return TXRX_CONTINUE;
+
+       /* no stations in PS mode */
+       if (!atomic_read(&tx->sdata->bss->num_sta_ps))
+               return TXRX_CONTINUE;
+
+       /* buffered in mac80211 */
+       if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) {
                if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
                        purge_old_ps_buffers(tx->local);
                if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >=
@@ -360,10 +358,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx)
                return TXRX_QUEUED;
        }
 
+       /* buffered in hardware */
+       tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM;
+
        return TXRX_CONTINUE;
 }
 
-static inline ieee80211_txrx_result
+static ieee80211_txrx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
 {
        struct sta_info *sta = tx->sta;
@@ -420,7 +421,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
        return TXRX_CONTINUE;
 }
 
-
 static ieee80211_txrx_result
 ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
 {
@@ -433,13 +433,11 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
                return ieee80211_tx_h_multicast_ps_buf(tx);
 }
 
-
-
-
 static ieee80211_txrx_result
 ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
 {
        struct ieee80211_key *key;
+       u16 fc = tx->fc;
 
        if (unlikely(tx->u.tx.control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT))
                tx->key = NULL;
@@ -448,19 +446,38 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx)
        else if ((key = rcu_dereference(tx->sdata->default_key)))
                tx->key = key;
        else if (tx->sdata->drop_unencrypted &&
-                !(tx->sdata->eapol && ieee80211_is_eapol(tx->skb))) {
+                !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) &&
+                !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) {
                I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted);
                return TXRX_DROP;
-       } else {
+       } else
                tx->key = NULL;
-               tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
-       }
 
        if (tx->key) {
+               u16 ftype, stype;
+
                tx->key->tx_rx_count++;
                /* TODO: add threshold stuff again */
+
+               switch (tx->key->conf.alg) {
+               case ALG_WEP:
+                       ftype = fc & IEEE80211_FCTL_FTYPE;
+                       stype = fc & IEEE80211_FCTL_STYPE;
+
+                       if (ftype == IEEE80211_FTYPE_MGMT &&
+                           stype == IEEE80211_STYPE_AUTH)
+                               break;
+               case ALG_TKIP:
+               case ALG_CCMP:
+                       if (!WLAN_FC_DATA_PRESENT(fc))
+                               tx->key = NULL;
+                       break;
+               }
        }
 
+       if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+               tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
+
        return TXRX_CONTINUE;
 }
 
@@ -567,21 +584,17 @@ ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx)
 static ieee80211_txrx_result
 ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
 {
-       struct rate_control_extra extra;
+       struct rate_selection rsel;
 
        if (likely(!tx->u.tx.rate)) {
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = tx->u.tx.mode;
-               extra.ethertype = tx->ethertype;
-
-               tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
-                                                     tx->skb, &extra);
-               if (unlikely(extra.probe != NULL)) {
+               rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel);
+               tx->u.tx.rate = rsel.rate;
+               if (unlikely(rsel.probe != NULL)) {
                        tx->u.tx.control->flags |=
                                IEEE80211_TXCTL_RATE_CTRL_PROBE;
                        tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
                        tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
-                       tx->u.tx.rate = extra.probe;
+                       tx->u.tx.rate = rsel.probe;
                } else
                        tx->u.tx.control->alt_retry_rate = -1;
 
@@ -591,15 +604,15 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
                tx->u.tx.control->alt_retry_rate = -1;
 
        if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
-           (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
-           (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) {
+           tx->sdata->bss_conf.use_cts_prot &&
+           (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) {
                tx->u.tx.last_frag_rate = tx->u.tx.rate;
-               if (extra.probe)
+               if (rsel.probe)
                        tx->flags &= ~IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
                else
                        tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
-               tx->u.tx.rate = extra.nonerp;
-               tx->u.tx.control->rate = extra.nonerp;
+               tx->u.tx.rate = rsel.nonerp;
+               tx->u.tx.control->rate = rsel.nonerp;
                tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE;
        } else {
                tx->u.tx.last_frag_rate = tx->u.tx.rate;
@@ -653,7 +666,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
        if (mode->mode == MODE_IEEE80211G &&
            (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) &&
            (tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
-           (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
+           tx->sdata->bss_conf.use_cts_prot &&
            !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))
                control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;
 
@@ -662,7 +675,7 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
         * available on the network at the current point in time. */
        if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
            (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) &&
-           (tx->sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
+           tx->sdata->bss_conf.use_short_preamble &&
            (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
                tx->u.tx.control->tx_rate = tx->u.tx.rate->val2;
        }
@@ -706,15 +719,6 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
                }
        }
 
-       /*
-        * Tell hardware to not encrypt when we had sw crypto.
-        * Because we use the same flag to internally indicate that
-        * no (software) encryption should be done, we have to set it
-        * after all crypto handlers.
-        */
-       if (tx->key && !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
-               tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
-
        return TXRX_CONTINUE;
 }
 
@@ -927,7 +931,6 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr;
        struct ieee80211_sub_if_data *sdata;
-       ieee80211_txrx_result res = TXRX_CONTINUE;
 
        int hdrlen;
 
@@ -945,7 +948,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 
        /* process and remove the injection radiotap header */
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
+       if (unlikely(sdata->vif.type == IEEE80211_IF_TYPE_MNTR)) {
                if (__ieee80211_parse_tx_radiotap(tx, skb) == TXRX_DROP)
                        return TXRX_DROP;
 
@@ -992,12 +995,10 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
        }
        control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;
 
-       return res;
+       return TXRX_CONTINUE;
 }
 
-/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
- * finished with it.
- *
+/*
  * NB: @tx is uninitialised when passed in here
  */
 static int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
@@ -1018,6 +1019,7 @@ static int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
                return -ENODEV;
        /* initialises tx with control */
        __ieee80211_tx_prepare(tx, skb, dev, control);
+       dev_put(dev);
        return 0;
 }
 
@@ -1248,14 +1250,16 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
                }
        }
 
-       control.ifindex = odev->ifindex;
-       control.type = osdata->type;
+       control.vif = &osdata->vif;
+       control.type = osdata->vif.type;
        if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS)
                control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS;
        if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT)
                control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
        if (pkt_data->flags & IEEE80211_TXPD_REQUEUE)
                control.flags |= IEEE80211_TXCTL_REQUEUE;
+       if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME)
+               control.flags |= IEEE80211_TXCTL_EAPOL_FRAME;
        control.queue = pkt_data->queue;
 
        ret = ieee80211_tx(odev, skb, &control);
@@ -1348,6 +1352,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        int encaps_len, skip_header_bytes;
        int nh_pos, h_pos;
        struct sta_info *sta;
+       u32 sta_flags = 0;
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (unlikely(skb->len < ETH_HLEN)) {
@@ -1363,10 +1368,9 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        /* convert Ethernet header to proper 802.11 header (based on
         * operation mode) */
        ethertype = (skb->data[12] << 8) | skb->data[13];
-       /* TODO: handling for 802.1x authorized/unauthorized port */
        fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
 
-       switch (sdata->type) {
+       switch (sdata->vif.type) {
        case IEEE80211_IF_TYPE_AP:
        case IEEE80211_IF_TYPE_VLAN:
                fc |= IEEE80211_FCTL_FROMDS;
@@ -1405,16 +1409,42 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
                goto fail;
        }
 
-       /* receiver is QoS enabled, use a QoS type frame */
        sta = sta_info_get(local, hdr.addr1);
        if (sta) {
-               if (sta->flags & WLAN_STA_WME) {
-                       fc |= IEEE80211_STYPE_QOS_DATA;
-                       hdrlen += 2;
-               }
+               sta_flags = sta->flags;
                sta_info_put(sta);
        }
 
+       /* receiver is QoS enabled, use a QoS type frame */
+       if (sta_flags & WLAN_STA_WME) {
+               fc |= IEEE80211_STYPE_QOS_DATA;
+               hdrlen += 2;
+       }
+
+       /*
+        * If port access control is enabled, drop frames to unauthorised
+        * stations unless they are EAPOL frames from the local station.
+        */
+       if (unlikely(sdata->ieee802_1x_pac &&
+                    !(sta_flags & WLAN_STA_AUTHORIZED) &&
+                    !(ethertype == ETH_P_PAE &&
+                      compare_ether_addr(dev->dev_addr,
+                                         skb->data + ETH_ALEN) == 0))) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+               DECLARE_MAC_BUF(mac);
+
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: dropped frame to %s"
+                              " (unauthorized port)\n", dev->name,
+                              print_mac(mac, hdr.addr1));
+#endif
+
+               I802_DEBUG_INC(local->tx_handlers_drop_unauth_port);
+
+               ret = 0;
+               goto fail;
+       }
+
        hdr.frame_control = cpu_to_le16(fc);
        hdr.duration_id = 0;
        hdr.seq_ctrl = 0;
@@ -1503,6 +1533,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
        memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
        pkt_data->ifindex = dev->ifindex;
+       if (ethertype == ETH_P_PAE)
+               pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME;
 
        skb->dev = local->mdev;
        dev->stats.tx_packets++;
@@ -1527,64 +1559,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        return ret;
 }
 
-/*
- * This is the transmit routine for the 802.11 type interfaces
- * called by upper layers of the linux networking
- * stack when it has a frame to transmit
- */
-int ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_tx_packet_data *pkt_data;
-       struct ieee80211_hdr *hdr;
-       u16 fc;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-       if (skb->len < 10) {
-               dev_kfree_skb(skb);
-               return 0;
-       }
-
-       if (skb_headroom(skb) < sdata->local->tx_headroom) {
-               if (pskb_expand_head(skb, sdata->local->tx_headroom,
-                                    0, GFP_ATOMIC)) {
-                       dev_kfree_skb(skb);
-                       return 0;
-               }
-       }
-
-       hdr = (struct ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-
-       pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
-       memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-       pkt_data->ifindex = sdata->dev->ifindex;
-
-       skb->priority = 20; /* use hardcoded priority for mgmt TX queue */
-       skb->dev = sdata->local->mdev;
-
-       /*
-        * We're using the protocol field of the the frame control header
-        * to request TX callback for hostapd. BIT(1) is checked.
-        */
-       if ((fc & BIT(1)) == BIT(1)) {
-               pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS;
-               fc &= ~BIT(1);
-               hdr->frame_control = cpu_to_le16(fc);
-       }
-
-       if (!(fc & IEEE80211_FCTL_PROTECTED))
-               pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT;
-
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += skb->len;
-
-       dev_queue_xmit(skb);
-
-       return 0;
-}
-
 /* helper functions for pending packets for when queues are stopped */
 
 void ieee80211_clear_tx_pending(struct ieee80211_local *local)
@@ -1653,7 +1627,8 @@ void ieee80211_tx_pending(unsigned long data)
 
 static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
                                     struct ieee80211_if_ap *bss,
-                                    struct sk_buff *skb)
+                                    struct sk_buff *skb,
+                                    struct beacon_data *beacon)
 {
        u8 *pos, *tim;
        int aid0 = 0;
@@ -1669,7 +1644,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
                                          IEEE80211_MAX_AID+1);
 
        if (bss->dtim_count == 0)
-               bss->dtim_count = bss->dtim_period - 1;
+               bss->dtim_count = beacon->dtim_period - 1;
        else
                bss->dtim_count--;
 
@@ -1677,7 +1652,7 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
        *pos++ = WLAN_EID_TIM;
        *pos++ = 4;
        *pos++ = bss->dtim_count;
-       *pos++ = bss->dtim_period;
+       *pos++ = beacon->dtim_period;
 
        if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf))
                aid0 = 1;
@@ -1715,7 +1690,8 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
        read_unlock_bh(&local->sta_lock);
 }
 
-struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
+struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
                                     struct ieee80211_tx_control *control)
 {
        struct ieee80211_local *local = hw_to_local(hw);
@@ -1723,68 +1699,64 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
        struct net_device *bdev;
        struct ieee80211_sub_if_data *sdata = NULL;
        struct ieee80211_if_ap *ap = NULL;
-       struct ieee80211_rate *rate;
-       struct rate_control_extra extra;
-       u8 *b_head, *b_tail;
-       int bh_len, bt_len;
-
-       bdev = dev_get_by_index(&init_net, if_id);
-       if (bdev) {
-               sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
-               ap = &sdata->u.ap;
-               dev_put(bdev);
-       }
+       struct rate_selection rsel;
+       struct beacon_data *beacon;
+
+       rcu_read_lock();
 
-       if (!ap || sdata->type != IEEE80211_IF_TYPE_AP ||
-           !ap->beacon_head) {
+       sdata = vif_to_sdata(vif);
+       bdev = sdata->dev;
+       ap = &sdata->u.ap;
+
+       beacon = rcu_dereference(ap->beacon);
+
+       if (!ap || sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                if (net_ratelimit())
-                       printk(KERN_DEBUG "no beacon data avail for idx=%d "
-                              "(%s)\n", if_id, bdev ? bdev->name : "N/A");
+                       printk(KERN_DEBUG "no beacon data avail for %s\n",
+                              bdev->name);
 #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
-               return NULL;
+               skb = NULL;
+               goto out;
        }
 
-       /* Assume we are generating the normal beacon locally */
-       b_head = ap->beacon_head;
-       b_tail = ap->beacon_tail;
-       bh_len = ap->beacon_head_len;
-       bt_len = ap->beacon_tail_len;
-
-       skb = dev_alloc_skb(local->tx_headroom +
-               bh_len + bt_len + 256 /* maximum TIM len */);
+       /* headroom, head length, tail length and maximum TIM length */
+       skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
+                           beacon->tail_len + 256);
        if (!skb)
-               return NULL;
+               goto out;
 
        skb_reserve(skb, local->tx_headroom);
-       memcpy(skb_put(skb, bh_len), b_head, bh_len);
+       memcpy(skb_put(skb, beacon->head_len), beacon->head,
+              beacon->head_len);
 
        ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data);
 
-       ieee80211_beacon_add_tim(local, ap, skb);
+       ieee80211_beacon_add_tim(local, ap, skb, beacon);
 
-       if (b_tail) {
-               memcpy(skb_put(skb, bt_len), b_tail, bt_len);
-       }
+       if (beacon->tail)
+               memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
+                      beacon->tail_len);
 
        if (control) {
-               memset(&extra, 0, sizeof(extra));
-               extra.mode = local->oper_hw_mode;
-
-               rate = rate_control_get_rate(local, local->mdev, skb, &extra);
-               if (!rate) {
+               rate_control_get_rate(local->mdev, local->oper_hw_mode, skb,
+                                     &rsel);
+               if (!rsel.rate) {
                        if (net_ratelimit()) {
-                               printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate "
-                                      "found\n", wiphy_name(local->hw.wiphy));
+                               printk(KERN_DEBUG "%s: ieee80211_beacon_get: "
+                                      "no rate found\n",
+                                      wiphy_name(local->hw.wiphy));
                        }
                        dev_kfree_skb(skb);
-                       return NULL;
+                       skb = NULL;
+                       goto out;
                }
 
+               control->vif = vif;
                control->tx_rate =
-                       ((sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE) &&
-                       (rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
-                       rate->val2 : rate->val;
+                       (sdata->bss_conf.use_short_preamble &&
+                       (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ?
+                       rsel.rate->val2 : rsel.rate->val;
                control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
                control->power_level = local->hw.conf.power_level;
                control->flags |= IEEE80211_TXCTL_NO_ACK;
@@ -1793,11 +1765,14 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
        }
 
        ap->num_beacons++;
+
+ out:
+       rcu_read_unlock();
        return skb;
 }
 EXPORT_SYMBOL(ieee80211_beacon_get);
 
-void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                       const void *frame, size_t frame_len,
                       const struct ieee80211_tx_control *frame_txctl,
                       struct ieee80211_rts *rts)
@@ -1807,13 +1782,14 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, int if_id,
 
        fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS;
        rts->frame_control = cpu_to_le16(fctl);
-       rts->duration = ieee80211_rts_duration(hw, if_id, frame_len, frame_txctl);
+       rts->duration = ieee80211_rts_duration(hw, vif, frame_len,
+                                              frame_txctl);
        memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
        memcpy(rts->ta, hdr->addr2, sizeof(rts->ta));
 }
 EXPORT_SYMBOL(ieee80211_rts_get);
 
-void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
+void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                             const void *frame, size_t frame_len,
                             const struct ieee80211_tx_control *frame_txctl,
                             struct ieee80211_cts *cts)
@@ -1823,13 +1799,15 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, int if_id,
 
        fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
        cts->frame_control = cpu_to_le16(fctl);
-       cts->duration = ieee80211_ctstoself_duration(hw, if_id, frame_len, frame_txctl);
+       cts->duration = ieee80211_ctstoself_duration(hw, vif,
+                                                    frame_len, frame_txctl);
        memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
 }
 EXPORT_SYMBOL(ieee80211_ctstoself_get);
 
 struct sk_buff *
-ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
+ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
+                         struct ieee80211_vif *vif,
                          struct ieee80211_tx_control *control)
 {
        struct ieee80211_local *local = hw_to_local(hw);
@@ -1841,16 +1819,25 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
        struct net_device *bdev;
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_if_ap *bss = NULL;
+       struct beacon_data *beacon;
 
-       bdev = dev_get_by_index(&init_net, if_id);
-       if (bdev) {
-               sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
-               bss = &sdata->u.ap;
-               dev_put(bdev);
-       }
-       if (!bss || sdata->type != IEEE80211_IF_TYPE_AP || !bss->beacon_head)
+       sdata = vif_to_sdata(vif);
+       bdev = sdata->dev;
+
+
+       if (!bss)
                return NULL;
 
+       rcu_read_lock();
+       beacon = rcu_dereference(bss->beacon);
+
+       if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon ||
+           !beacon->head) {
+               rcu_read_unlock();
+               return NULL;
+       }
+       rcu_read_unlock();
+
        if (bss->dtim_count != 0)
                return NULL; /* send buffered bc/mc only after DTIM beacon */
        memset(control, 0, sizeof(*control));
@@ -1883,7 +1870,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
                if (res == TXRX_DROP || res == TXRX_QUEUED)
                        break;
        }
-       dev_put(tx.dev);
        skb = tx.skb; /* handlers are allowed to change skb */
 
        if (res == TXRX_DROP) {
index 5a0564e1dbd6ca387c5c44d854bcd2b38fc0e84a..5e631ce98d7e6656c807329e8a9d9b8ac73ad599 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bitmap.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
+#include <net/rtnetlink.h>
 
 #include "ieee80211_i.h"
 #include "ieee80211_rate.h"
@@ -39,10 +40,6 @@ const unsigned char rfc1042_header[] =
 const unsigned char bridge_tunnel_header[] =
        { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
 
-/* No encapsulation header if EtherType < 0x600 (=length) */
-static const unsigned char eapol_header[] =
-       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
-
 
 static int rate_list_match(const int *rate_list, int rate)
 {
@@ -130,17 +127,21 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
        }
 }
 
-u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
+u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
+                       enum ieee80211_if_types type)
 {
        u16 fc;
 
-       if (len < 24)
+        /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
+       if (len < 16)
                return NULL;
 
        fc = le16_to_cpu(hdr->frame_control);
 
        switch (fc & IEEE80211_FCTL_FTYPE) {
        case IEEE80211_FTYPE_DATA:
+               if (len < 24) /* drop incorrect hdr len (data) */
+                       return NULL;
                switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
                case IEEE80211_FCTL_TODS:
                        return hdr->addr1;
@@ -153,10 +154,24 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len)
                }
                break;
        case IEEE80211_FTYPE_MGMT:
+               if (len < 24) /* drop incorrect hdr len (mgmt) */
+                       return NULL;
                return hdr->addr3;
        case IEEE80211_FTYPE_CTL:
                if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)
                        return hdr->addr1;
+               else if ((fc & IEEE80211_FCTL_STYPE) ==
+                                               IEEE80211_STYPE_BACK_REQ) {
+                       switch (type) {
+                       case IEEE80211_IF_TYPE_STA:
+                               return hdr->addr2;
+                       case IEEE80211_IF_TYPE_AP:
+                       case IEEE80211_IF_TYPE_VLAN:
+                               return hdr->addr1;
+                       default:
+                               return NULL;
+                       }
+               }
                else
                        return NULL;
        }
@@ -217,31 +232,6 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
 
-int ieee80211_is_eapol(const struct sk_buff *skb)
-{
-       const struct ieee80211_hdr *hdr;
-       u16 fc;
-       int hdrlen;
-
-       if (unlikely(skb->len < 10))
-               return 0;
-
-       hdr = (const struct ieee80211_hdr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
-               return 0;
-
-       hdrlen = ieee80211_get_hdrlen(fc);
-
-       if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
-                    memcmp(skb->data + hdrlen, eapol_header,
-                           sizeof(eapol_header)) == 0))
-               return 1;
-
-       return 0;
-}
-
 void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
@@ -312,45 +302,35 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
 }
 
 /* Exported duration function for driver use */
-__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
+                                       struct ieee80211_vif *vif,
                                        size_t frame_len, int rate)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct net_device *bdev = dev_get_by_index(&init_net, if_id);
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
        u16 dur;
        int erp;
 
-       if (unlikely(!bdev))
-               return 0;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
        erp = ieee80211_is_erp_rate(hw->conf.phymode, rate);
-       dur = ieee80211_frame_duration(local, frame_len, rate,
-                      erp, sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE);
+       dur = ieee80211_frame_duration(local, frame_len, rate, erp,
+                                      sdata->bss_conf.use_short_preamble);
 
-       dev_put(bdev);
        return cpu_to_le16(dur);
 }
 EXPORT_SYMBOL(ieee80211_generic_frame_duration);
 
-__le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
-                             size_t frame_len,
+__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif, size_t frame_len,
                              const struct ieee80211_tx_control *frame_txctl)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate;
-       struct net_device *bdev = dev_get_by_index(&init_net, if_id);
-       struct ieee80211_sub_if_data *sdata;
-       int short_preamble;
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       bool short_preamble;
        int erp;
        u16 dur;
 
-       if (unlikely(!bdev))
-               return 0;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
-       short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE;
+       short_preamble = sdata->bss_conf.use_short_preamble;
 
        rate = frame_txctl->rts_rate;
        erp = !!(rate->flags & IEEE80211_RATE_ERP);
@@ -365,28 +345,23 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, int if_id,
        dur += ieee80211_frame_duration(local, 10, rate->rate,
                                        erp, short_preamble);
 
-       dev_put(bdev);
        return cpu_to_le16(dur);
 }
 EXPORT_SYMBOL(ieee80211_rts_duration);
 
-__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
+__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
                                    size_t frame_len,
                                    const struct ieee80211_tx_control *frame_txctl)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_rate *rate;
-       struct net_device *bdev = dev_get_by_index(&init_net, if_id);
-       struct ieee80211_sub_if_data *sdata;
-       int short_preamble;
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       bool short_preamble;
        int erp;
        u16 dur;
 
-       if (unlikely(!bdev))
-               return 0;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(bdev);
-       short_preamble = sdata->flags & IEEE80211_SDATA_SHORT_PREAMBLE;
+       short_preamble = sdata->bss_conf.use_short_preamble;
 
        rate = frame_txctl->rts_rate;
        erp = !!(rate->flags & IEEE80211_RATE_ERP);
@@ -400,7 +375,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, int if_id,
                                                erp, short_preamble);
        }
 
-       dev_put(bdev);
        return cpu_to_le16(dur);
 }
 EXPORT_SYMBOL(ieee80211_ctstoself_duration);
@@ -484,3 +458,37 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
                ieee80211_wake_queue(hw, i);
 }
 EXPORT_SYMBOL(ieee80211_wake_queues);
+
+void ieee80211_iterate_active_interfaces(
+       struct ieee80211_hw *hw,
+       void (*iterator)(void *data, u8 *mac,
+                        struct ieee80211_vif *vif),
+       void *data)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+       struct ieee80211_sub_if_data *sdata;
+
+       rcu_read_lock();
+
+       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+               switch (sdata->vif.type) {
+               case IEEE80211_IF_TYPE_INVALID:
+               case IEEE80211_IF_TYPE_MNTR:
+               case IEEE80211_IF_TYPE_VLAN:
+                       continue;
+               case IEEE80211_IF_TYPE_AP:
+               case IEEE80211_IF_TYPE_STA:
+               case IEEE80211_IF_TYPE_IBSS:
+               case IEEE80211_IF_TYPE_WDS:
+                       break;
+               }
+               if (sdata->dev == local->mdev)
+                       continue;
+               if (netif_running(sdata->dev))
+                       iterator(data, sdata->dev->dev_addr,
+                                &sdata->vif);
+       }
+
+       rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
index b5f3413403bd27c0d2646f2b210bfc36123cc8c8..a0cff72a580baf1389ab07c2c5a86a9cb928d006 100644 (file)
@@ -349,16 +349,6 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb)
 ieee80211_txrx_result
 ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       u16 fc;
-
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA &&
-            ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
-             (fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)))
-               return TXRX_CONTINUE;
-
        tx->u.tx.control->iv_len = WEP_IV_LEN;
        tx->u.tx.control->icv_len = WEP_ICV_LEN;
        ieee80211_tx_set_iswep(tx);
index 5b8a157975a35dd452bc6e03e17f5dafcae09788..4e236599dd31cf0831f99157877571c120834d9c 100644 (file)
@@ -28,6 +28,7 @@ struct ieee80211_sched_data
        struct sk_buff_head requeued[TC_80211_MAX_QUEUES];
 };
 
+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 inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd)
@@ -54,12 +55,12 @@ static inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd)
                return skb->priority - 256;
 
        /* check there is a valid IP header present */
-       offset = ieee80211_get_hdrlen_from_skb(skb) + 8 /* LLC + proto */;
-       if (skb->protocol != __constant_htons(ETH_P_IP) ||
-           skb->len < offset + sizeof(*ip))
+       offset = ieee80211_get_hdrlen_from_skb(skb);
+       if (skb->len < offset + sizeof(llc_ip_hdr) + sizeof(*ip) ||
+           memcmp(skb->data + offset, llc_ip_hdr, sizeof(llc_ip_hdr)))
                return 0;
 
-       ip = (struct iphdr *) (skb->data + offset);
+       ip = (struct iphdr *) (skb->data + offset + sizeof(llc_ip_hdr));
 
        dscp = ip->tos & 0xfc;
        if (dscp & 0x1c)
@@ -296,16 +297,16 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
 
 
 /* called whenever parameters are updated on existing qdisc */
-static int wme_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt)
+static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
 {
 /*     struct ieee80211_sched_data *q = qdisc_priv(qd);
 */
        /* check our options block is the right size */
        /* copy any options to our local structure */
 /*     Ignore options block for now - always use static mapping
-       struct tc_ieee80211_qopt *qopt = RTA_DATA(opt);
+       struct tc_ieee80211_qopt *qopt = nla_data(opt);
 
-       if (opt->rta_len < RTA_LENGTH(sizeof(*qopt)))
+       if (opt->nla_len < nla_attr_size(sizeof(*qopt)))
                return -EINVAL;
        memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue));
 */
@@ -314,7 +315,7 @@ static int wme_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt)
 
 
 /* called during initial creation of qdisc on device */
-static int wme_qdiscop_init(struct Qdisc *qd, struct rtattr *opt)
+static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
 {
        struct ieee80211_sched_data *q = qdisc_priv(qd);
        struct net_device *dev = qd->dev;
@@ -369,10 +370,10 @@ static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
        struct tc_ieee80211_qopt opt;
 
        memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1);
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
 */     return skb->len;
 /*
-rtattr_failure:
+nla_put_failure:
        skb_trim(skb, p - skb->data);*/
        return -1;
 }
@@ -443,7 +444,7 @@ static void wme_classop_put(struct Qdisc *q, unsigned long cl)
 
 
 static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent,
-                             struct rtattr **tca, unsigned long *arg)
+                             struct nlattr **tca, unsigned long *arg)
 {
        unsigned long cl = *arg;
        struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
@@ -527,7 +528,7 @@ static struct tcf_proto ** wme_classop_find_tcf(struct Qdisc *qd,
 
 /* this qdisc is classful (i.e. has classes, some of which may have leaf qdiscs attached)
  * - these are the operations on the classes */
-static struct Qdisc_class_ops class_ops =
+static const struct Qdisc_class_ops class_ops =
 {
        .graft = wme_classop_graft,
        .leaf = wme_classop_leaf,
@@ -547,7 +548,7 @@ static struct Qdisc_class_ops class_ops =
 
 
 /* queueing discipline operations */
-static struct Qdisc_ops wme_qdisc_ops =
+static struct Qdisc_ops wme_qdisc_ops __read_mostly =
 {
        .next = NULL,
        .cl_ops = &class_ops,
index 20cec1cb956fb38d6506139d757d8a983cf126d7..6f04311cf0a07922727ace9373291ce5f04b9270 100644 (file)
@@ -245,16 +245,9 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx,
 ieee80211_txrx_result
 ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       u16 fc;
        struct sk_buff *skb = tx->skb;
        int wpa_test = 0, test = 0;
 
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (!WLAN_FC_DATA_PRESENT(fc))
-               return TXRX_CONTINUE;
-
        tx->u.tx.control->icv_len = TKIP_ICV_LEN;
        tx->u.tx.control->iv_len = TKIP_IV_LEN;
        ieee80211_tx_set_iswep(tx);
@@ -501,16 +494,9 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx,
 ieee80211_txrx_result
 ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx)
 {
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
-       u16 fc;
        struct sk_buff *skb = tx->skb;
        int test = 0;
 
-       fc = le16_to_cpu(hdr->frame_control);
-
-       if (!WLAN_FC_DATA_PRESENT(fc))
-               return TXRX_CONTINUE;
-
        tx->u.tx.control->icv_len = CCMP_MIC_LEN;
        tx->u.tx.control->iv_len = CCMP_HDR_LEN;
        ieee80211_tx_set_iswep(tx);
index 21a9fcc0379671a251a34c9d312c1cfdd874bf08..daf5b881064da7d1ba507f8f532ef6f1c5bc5af3 100644 (file)
@@ -2,21 +2,20 @@ menu "Core Netfilter Configuration"
        depends on NET && INET && NETFILTER
 
 config NETFILTER_NETLINK
-       tristate "Netfilter netlink interface"
-       help
-         If this option is enabled, the kernel will include support
-         for the new netfilter netlink interface.
+       tristate
 
 config NETFILTER_NETLINK_QUEUE
        tristate "Netfilter NFQUEUE over NFNETLINK interface"
-       depends on NETFILTER_NETLINK
+       depends on NETFILTER_ADVANCED
+       select NETFILTER_NETLINK
        help
          If this option is enabled, the kernel will include support
          for queueing packets via NFNETLINK.
          
 config NETFILTER_NETLINK_LOG
        tristate "Netfilter LOG over NFNETLINK interface"
-       depends on NETFILTER_NETLINK
+       default m if NETFILTER_ADVANCED=n
+       select NETFILTER_NETLINK
        help
          If this option is enabled, the kernel will include support
          for logging packets via NFNETLINK.
@@ -25,9 +24,9 @@ config NETFILTER_NETLINK_LOG
          and is also scheduled to replace the old syslog-based ipt_LOG
          and ip6t_LOG modules.
 
-# Rename this to NF_CONNTRACK in a 2.6.25
-config NF_CONNTRACK_ENABLED
+config NF_CONNTRACK
        tristate "Netfilter connection tracking support"
+       default m if NETFILTER_ADVANCED=n
        help
          Connection tracking keeps a record of what packets have passed
          through your machine, in order to figure out how they are related
@@ -40,12 +39,9 @@ config NF_CONNTRACK_ENABLED
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-config NF_CONNTRACK
-       tristate
-       default NF_CONNTRACK_ENABLED
-
 config NF_CT_ACCT
        bool "Connection tracking flow accounting"
+       depends on NETFILTER_ADVANCED
        depends on NF_CONNTRACK
        help
          If this option is enabled, the connection tracking code will
@@ -58,6 +54,7 @@ config NF_CT_ACCT
 
 config NF_CONNTRACK_MARK
        bool  'Connection mark tracking support'
+       depends on NETFILTER_ADVANCED
        depends on NF_CONNTRACK
        help
          This option enables support for connection marks, used by the
@@ -68,6 +65,7 @@ config NF_CONNTRACK_MARK
 config NF_CONNTRACK_SECMARK
        bool  'Connection tracking security mark support'
        depends on NF_CONNTRACK && NETWORK_SECMARK
+       default m if NETFILTER_ADVANCED=n
        help
          This option enables security markings to be applied to
          connections.  Typically they are copied to connections from
@@ -78,8 +76,9 @@ config NF_CONNTRACK_SECMARK
          If unsure, say 'N'.
 
 config NF_CONNTRACK_EVENTS
-       bool "Connection tracking events (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && NF_CONNTRACK
+       bool "Connection tracking events"
+       depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          If this option is enabled, the connection tracking code will
          provide a notifier chain that can be used by other kernel code
@@ -94,7 +93,7 @@ config NF_CT_PROTO_GRE
 config NF_CT_PROTO_SCTP
        tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
        depends on EXPERIMENTAL && NF_CONNTRACK
-       default n
+       depends on NETFILTER_ADVANCED
        help
          With this option enabled, the layer 3 independent connection
          tracking code will be able to do state tracking on SCTP connections.
@@ -103,8 +102,9 @@ config NF_CT_PROTO_SCTP
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
 config NF_CT_PROTO_UDPLITE
-       tristate 'UDP-Lite protocol connection tracking support (EXPERIMENTAL)'
-       depends on EXPERIMENTAL && NF_CONNTRACK
+       tristate 'UDP-Lite protocol connection tracking support'
+       depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          With this option enabled, the layer 3 independent connection
          tracking code will be able to do state tracking on UDP-Lite
@@ -115,6 +115,7 @@ config NF_CT_PROTO_UDPLITE
 config NF_CONNTRACK_AMANDA
        tristate "Amanda backup protocol support"
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        select TEXTSEARCH
        select TEXTSEARCH_KMP
        help
@@ -130,6 +131,7 @@ config NF_CONNTRACK_AMANDA
 config NF_CONNTRACK_FTP
        tristate "FTP protocol support"
        depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        help
          Tracking FTP connections is problematic: special helpers are
          required for tracking them, and doing masquerading and other forms
@@ -142,8 +144,9 @@ config NF_CONNTRACK_FTP
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NF_CONNTRACK_H323
-       tristate "H.323 protocol support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && NF_CONNTRACK && (IPV6 || IPV6=n)
+       tristate "H.323 protocol support"
+       depends on NF_CONNTRACK && (IPV6 || IPV6=n)
+       depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
          important VoIP protocols, it is widely used by voice hardware and
@@ -163,6 +166,7 @@ config NF_CONNTRACK_H323
 config NF_CONNTRACK_IRC
        tristate "IRC protocol support"
        depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        help
          There is a commonly-used extension to IRC called
          Direct Client-to-Client Protocol (DCC).  This enables users to send
@@ -176,8 +180,9 @@ config NF_CONNTRACK_IRC
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NF_CONNTRACK_NETBIOS_NS
-       tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && NF_CONNTRACK
+       tristate "NetBIOS name service protocol support"
+       depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          NetBIOS name service requests are sent as broadcast messages from an
          unprivileged port and responded to with unicast messages to the
@@ -197,6 +202,7 @@ config NF_CONNTRACK_NETBIOS_NS
 config NF_CONNTRACK_PPTP
        tristate "PPtP protocol support"
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        select NF_CT_PROTO_GRE
        help
          This module adds support for PPTP (Point to Point Tunnelling
@@ -216,6 +222,7 @@ config NF_CONNTRACK_PPTP
 config NF_CONNTRACK_SANE
        tristate "SANE protocol support (EXPERIMENTAL)"
        depends on EXPERIMENTAL && NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          SANE is a protocol for remote access to scanners as implemented
          by the 'saned' daemon. Like FTP, it uses separate control and
@@ -227,8 +234,9 @@ config NF_CONNTRACK_SANE
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NF_CONNTRACK_SIP
-       tristate "SIP protocol support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && NF_CONNTRACK
+       tristate "SIP protocol support"
+       depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        help
          SIP is an application-layer control protocol that can establish,
          modify, and terminate multimedia sessions (conferences) such as
@@ -241,6 +249,7 @@ config NF_CONNTRACK_SIP
 config NF_CONNTRACK_TFTP
        tristate "TFTP protocol support"
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          TFTP connection tracking helper, this is required depending
          on how restrictive your ruleset is.
@@ -250,15 +259,17 @@ config NF_CONNTRACK_TFTP
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NF_CT_NETLINK
-       tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
-       depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
-       depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+       tristate 'Connection tracking netlink interface'
+       depends on NF_CONNTRACK
+       select NETFILTER_NETLINK
        depends on NF_NAT=n || NF_NAT
+       default m if NETFILTER_ADVANCED=n
        help
          This option enables support for a netlink-based userspace interface
 
 config NETFILTER_XTABLES
        tristate "Netfilter Xtables support (required for ip_tables)"
+       default m if NETFILTER_ADVANCED=n
        help
          This is required if you intend to use any of ip_tables,
          ip6_tables or arp_tables.
@@ -268,6 +279,7 @@ config NETFILTER_XTABLES
 config NETFILTER_XT_TARGET_CLASSIFY
        tristate '"CLASSIFY" target support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `CLASSIFY' target, which enables the user to set
          the priority of a packet. Some qdiscs can use this value for
@@ -282,31 +294,38 @@ config NETFILTER_XT_TARGET_CONNMARK
        depends on NETFILTER_XTABLES
        depends on IP_NF_MANGLE || IP6_NF_MANGLE
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        select NF_CONNTRACK_MARK
        help
          This option adds a `CONNMARK' target, which allows one to manipulate
          the connection mark value.  Similar to the MARK target, but
          affects the connection mark value rather than the packet mark value.
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  The module will be called
          ipt_CONNMARK.ko.  If unsure, say `N'.
 
 config NETFILTER_XT_TARGET_DSCP
-       tristate '"DSCP" target support'
+       tristate '"DSCP" and "TOS" target support'
        depends on NETFILTER_XTABLES
        depends on IP_NF_MANGLE || IP6_NF_MANGLE
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `DSCP' target, which allows you to manipulate
          the IPv4/IPv6 header DSCP field (differentiated services codepoint).
 
          The DSCP field can have any value between 0x0 and 0x3f inclusive.
 
+         It also adds the "TOS" target, which allows you to create rules in
+         the "mangle" table which alter the Type Of Service field of an IPv4
+         or the Priority field of an IPv6 packet, prior to routing.
+
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NETFILTER_XT_TARGET_MARK
        tristate '"MARK" target support'
        depends on NETFILTER_XTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          This option adds a `MARK' target, which allows you to create rules
          in the `mangle' table which alter the netfilter mark (nfmark) field
@@ -320,6 +339,7 @@ config NETFILTER_XT_TARGET_MARK
 config NETFILTER_XT_TARGET_NFQUEUE
        tristate '"NFQUEUE" target Support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This target replaced the old obsolete QUEUE target.
 
@@ -331,6 +351,7 @@ config NETFILTER_XT_TARGET_NFQUEUE
 config NETFILTER_XT_TARGET_NFLOG
        tristate '"NFLOG" target support'
        depends on NETFILTER_XTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          This option enables the NFLOG target, which allows to LOG
          messages through the netfilter logging API, which can use
@@ -344,19 +365,32 @@ config NETFILTER_XT_TARGET_NOTRACK
        depends on NETFILTER_XTABLES
        depends on IP_NF_RAW || IP6_NF_RAW
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          The NOTRACK target allows a select rule to specify
          which packets *not* to enter the conntrack/NAT
          subsystem with all the consequences (no ICMP error tracking,
          no protocol helpers for the selected packets).
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_TARGET_RATEEST
+       tristate '"RATEEST" target support'
+       depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
+       help
+         This option adds a `RATEEST' target, which allows to measure
+         rates similar to TC estimators. The `rateest' match can be
+         used to match on the measured rates.
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_TRACE
        tristate  '"TRACE" target support'
        depends on NETFILTER_XTABLES
        depends on IP_NF_RAW || IP6_NF_RAW
+       depends on NETFILTER_ADVANCED
        help
          The TRACE target allows you to mark packets so that the kernel
          will log every rule which match the packets as those traverse
@@ -368,6 +402,7 @@ config NETFILTER_XT_TARGET_TRACE
 config NETFILTER_XT_TARGET_SECMARK
        tristate '"SECMARK" target support'
        depends on NETFILTER_XTABLES && NETWORK_SECMARK
+       default m if NETFILTER_ADVANCED=n
        help
          The SECMARK target allows security marking of network
          packets, for use with security subsystems.
@@ -377,6 +412,7 @@ config NETFILTER_XT_TARGET_SECMARK
 config NETFILTER_XT_TARGET_CONNSECMARK
        tristate '"CONNSECMARK" target support'
        depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
+       default m if NETFILTER_ADVANCED=n
        help
          The CONNSECMARK target copies security markings from packets
          to connections, and restores security markings from connections
@@ -388,6 +424,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK
 config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
        depends on NETFILTER_XTABLES && (IPV6 || IPV6=n)
+       default m if NETFILTER_ADVANCED=n
        ---help---
          This option adds a `TCPMSS' target, which allows you to alter the
          MSS value of TCP SYN packets, to control the maximum size for that
@@ -411,9 +448,19 @@ config NETFILTER_XT_TARGET_TCPMSS
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_TCPOPTSTRIP
+       tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
+       depends on EXPERIMENTAL && NETFILTER_XTABLES
+       depends on IP_NF_MANGLE || IP6_NF_MANGLE
+       depends on NETFILTER_ADVANCED
+       help
+         This option adds a "TCPOPTSTRIP" target, which allows you to strip
+         TCP options from TCP packets.
+
 config NETFILTER_XT_MATCH_COMMENT
        tristate  '"comment" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `comment' dummy-match, which allows you to put
          comments in your iptables ruleset.
@@ -425,6 +472,7 @@ config NETFILTER_XT_MATCH_CONNBYTES
        tristate  '"connbytes" per-connection counter match support'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        select NF_CT_ACCT
        help
          This option adds a `connbytes' match, which allows you to match the
@@ -437,6 +485,7 @@ config NETFILTER_XT_MATCH_CONNLIMIT
        tristate '"connlimit" match support"'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        ---help---
          This match allows you to match against the number of parallel
          connections to a server per client IP address (or address block).
@@ -445,11 +494,12 @@ config NETFILTER_XT_MATCH_CONNMARK
        tristate  '"connmark" connection mark match support'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        select NF_CONNTRACK_MARK
        help
          This option adds a `connmark' match, which allows you to match the
          connection mark value previously set for the session by `CONNMARK'. 
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  The module will be called
          ipt_connmark.ko.  If unsure, say `N'.
@@ -458,6 +508,7 @@ config NETFILTER_XT_MATCH_CONNTRACK
        tristate '"conntrack" connection tracking match support'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        help
          This is a general conntrack match module, a superset of the state match.
 
@@ -468,8 +519,9 @@ config NETFILTER_XT_MATCH_CONNTRACK
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NETFILTER_XT_MATCH_DCCP
-       tristate  '"DCCP" protocol match support'
+       tristate '"dccp" protocol match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          With this option enabled, you will be able to use the iptables
          `dccp' match in order to match on DCCP source/destination ports
@@ -479,19 +531,25 @@ config NETFILTER_XT_MATCH_DCCP
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
 config NETFILTER_XT_MATCH_DSCP
-       tristate '"DSCP" match support'
+       tristate '"dscp" and "tos" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `DSCP' match, which allows you to match against
          the IPv4/IPv6 header DSCP field (differentiated services codepoint).
 
          The DSCP field can have any value between 0x0 and 0x3f inclusive.
 
+         It will also add a "tos" match, which allows you to match packets
+         based on the Type Of Service fields of the IPv4 packet (which share
+         the same bits as DSCP).
+
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NETFILTER_XT_MATCH_ESP
-       tristate '"ESP" match support'
+       tristate '"esp" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This match extension allows you to match a range of SPIs
          inside ESP header of IPSec packets.
@@ -502,15 +560,28 @@ config NETFILTER_XT_MATCH_HELPER
        tristate '"helper" match support'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
        help
          Helper matching allows you to match packets in dynamic connections
          tracked by a conntrack-helper, ie. ip_conntrack_ftp
 
          To compile it as a module, choose M here.  If unsure, say Y.
 
+config NETFILTER_XT_MATCH_IPRANGE
+       tristate '"iprange" address range match support'
+       depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
+       ---help---
+       This option adds a "iprange" match, which allows you to match based on
+       an IP address range. (Normal iptables only matches on single addresses
+       with an optional mask.)
+
+       If unsure, say M.
+
 config NETFILTER_XT_MATCH_LENGTH
        tristate '"length" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option allows you to match the length of a packet against a
          specific value or range of values.
@@ -520,6 +591,7 @@ config NETFILTER_XT_MATCH_LENGTH
 config NETFILTER_XT_MATCH_LIMIT
        tristate '"limit" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          limit matching allows you to control the rate at which a rule can be
          matched: mainly useful in combination with the LOG target ("LOG
@@ -530,6 +602,7 @@ config NETFILTER_XT_MATCH_LIMIT
 config NETFILTER_XT_MATCH_MAC
        tristate '"mac" address match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          MAC matching allows you to match packets based on the source
          Ethernet address of the packet.
@@ -539,6 +612,7 @@ config NETFILTER_XT_MATCH_MAC
 config NETFILTER_XT_MATCH_MARK
        tristate '"mark" match support'
        depends on NETFILTER_XTABLES
+       default m if NETFILTER_ADVANCED=n
        help
          Netfilter mark matching allows you to match packets based on the
          `nfmark' value in the packet.  This can be set by the MARK target
@@ -546,9 +620,19 @@ config NETFILTER_XT_MATCH_MARK
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_OWNER
+       tristate '"owner" match support'
+       depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
+       ---help---
+       Socket owner matching allows you to match locally-generated packets
+       based on who created the socket: the user or group. It is also
+       possible to check whether a socket actually exists.
+
 config NETFILTER_XT_MATCH_POLICY
        tristate 'IPsec "policy" match support'
        depends on NETFILTER_XTABLES && XFRM
+       default m if NETFILTER_ADVANCED=n
        help
          Policy matching allows you to match packets based on the
          IPsec policy that was used during decapsulation/will
@@ -557,8 +641,9 @@ config NETFILTER_XT_MATCH_POLICY
          To compile it as a module, choose M here.  If unsure, say N.
 
 config NETFILTER_XT_MATCH_MULTIPORT
-       tristate "Multiple port match support"
+       tristate '"multiport" Multiple port match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          Multiport matching allows you to match TCP or UDP packets based on
          a series of source or destination ports: normally a rule can only
@@ -569,6 +654,7 @@ config NETFILTER_XT_MATCH_MULTIPORT
 config NETFILTER_XT_MATCH_PHYSDEV
        tristate '"physdev" match support'
        depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER
+       depends on NETFILTER_ADVANCED
        help
          Physdev packet matching matches against the physical bridge ports
          the IP packet arrived on or will leave by.
@@ -578,6 +664,7 @@ config NETFILTER_XT_MATCH_PHYSDEV
 config NETFILTER_XT_MATCH_PKTTYPE
        tristate '"pkttype" packet type match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          Packet type matching allows you to match a packet by
          its "class", eg. BROADCAST, MULTICAST, ...
@@ -590,6 +677,7 @@ config NETFILTER_XT_MATCH_PKTTYPE
 config NETFILTER_XT_MATCH_QUOTA
        tristate '"quota" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `quota' match, which allows to match on a
          byte counter.
@@ -597,23 +685,36 @@ config NETFILTER_XT_MATCH_QUOTA
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_MATCH_RATEEST
+       tristate '"rateest" match support'
+       depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
+       select NETFILTER_XT_TARGET_RATEEST
+       help
+         This option adds a `rateest' match, which allows to match on the
+         rate estimated by the RATEEST target.
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_REALM
        tristate  '"realm" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        select NET_CLS_ROUTE
        help
          This option adds a `realm' match, which allows you to use the realm
          key from the routing subsystem inside iptables.
-       
+
          This match pretty much resembles the CONFIG_NET_CLS_ROUTE4 option 
          in tc world.
-       
+
          If you want to compile it as a module, say M here and read
          <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
 config NETFILTER_XT_MATCH_SCTP
        tristate  '"sctp" protocol match support (EXPERIMENTAL)'
        depends on NETFILTER_XTABLES && EXPERIMENTAL
+       depends on NETFILTER_ADVANCED
        help
          With this option enabled, you will be able to use the 
          `sctp' match in order to match on SCTP source/destination ports
@@ -626,6 +727,7 @@ config NETFILTER_XT_MATCH_STATE
        tristate '"state" match support'
        depends on NETFILTER_XTABLES
        depends on NF_CONNTRACK
+       default m if NETFILTER_ADVANCED=n
        help
          Connection state matching allows you to match packets based on their
          relationship to a tracked connection (ie. previous packets).  This
@@ -636,6 +738,7 @@ config NETFILTER_XT_MATCH_STATE
 config NETFILTER_XT_MATCH_STATISTIC
        tristate '"statistic" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `statistic' match, which allows you to match
          on packets periodically or randomly with a given percentage.
@@ -645,6 +748,7 @@ config NETFILTER_XT_MATCH_STATISTIC
 config NETFILTER_XT_MATCH_STRING
        tristate  '"string" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        select TEXTSEARCH
        select TEXTSEARCH_KMP
        select TEXTSEARCH_BM
@@ -658,6 +762,7 @@ config NETFILTER_XT_MATCH_STRING
 config NETFILTER_XT_MATCH_TCPMSS
        tristate '"tcpmss" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `tcpmss' match, which allows you to examine the
          MSS value of TCP SYN packets, which control the maximum packet size
@@ -668,6 +773,7 @@ config NETFILTER_XT_MATCH_TCPMSS
 config NETFILTER_XT_MATCH_TIME
        tristate '"time" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        ---help---
          This option adds a "time" match, which allows you to match based on
          the packet arrival time (at the machine which netfilter is running)
@@ -682,6 +788,7 @@ config NETFILTER_XT_MATCH_TIME
 config NETFILTER_XT_MATCH_U32
        tristate '"u32" match support'
        depends on NETFILTER_XTABLES
+       depends on NETFILTER_ADVANCED
        ---help---
          u32 allows you to extract quantities of up to 4 bytes from a packet,
          AND them with specified masks, shift them by specified amounts and
@@ -695,6 +802,7 @@ config NETFILTER_XT_MATCH_U32
 config NETFILTER_XT_MATCH_HASHLIMIT
        tristate '"hashlimit" match support'
        depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
+       depends on NETFILTER_ADVANCED
        help
          This option adds a `hashlimit' match.
 
index ad0e36ebea3d3f17a18bc973175d1d8358284bef..ea7508387f957fcf7327d962ad2340867d8b03ce 100644 (file)
@@ -4,7 +4,6 @@ nf_conntrack-y  := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_exp
 nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
 
 obj-$(CONFIG_NETFILTER) = netfilter.o
-obj-$(CONFIG_SYSCTL) += nf_sysctl.o
 
 obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
 obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
@@ -46,8 +45,10 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
 # matches
@@ -61,15 +62,18 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
 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_OWNER) += xt_owner.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
index bed9ba01e8eced0641d9f293b45ab2e68e32c26b..c4065b8f9a95f6abb66242a3c3a9f8a7990da552 100644 (file)
 
 static DEFINE_MUTEX(afinfo_mutex);
 
-struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly;
+const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly;
 EXPORT_SYMBOL(nf_afinfo);
 
-int nf_register_afinfo(struct nf_afinfo *afinfo)
+int nf_register_afinfo(const struct nf_afinfo *afinfo)
 {
        int err;
 
@@ -42,7 +42,7 @@ int nf_register_afinfo(struct nf_afinfo *afinfo)
 }
 EXPORT_SYMBOL_GPL(nf_register_afinfo);
 
-void nf_unregister_afinfo(struct nf_afinfo *afinfo)
+void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
 {
        mutex_lock(&afinfo_mutex);
        rcu_assign_pointer(nf_afinfo[afinfo->family], NULL);
@@ -51,28 +51,23 @@ void nf_unregister_afinfo(struct nf_afinfo *afinfo)
 }
 EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
 
-/* In this code, we can be waiting indefinitely for userspace to
- * service a packet if a hook returns NF_QUEUE.  We could keep a count
- * of skbuffs queued for userspace, and not deregister a hook unless
- * this is zero, but that sucks.  Now, we simply check when the
- * packets come back: if the hook is gone, the packet is discarded. */
 struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly;
 EXPORT_SYMBOL(nf_hooks);
 static DEFINE_MUTEX(nf_hook_mutex);
 
 int nf_register_hook(struct nf_hook_ops *reg)
 {
-       struct list_head *i;
+       struct nf_hook_ops *elem;
        int err;
 
        err = mutex_lock_interruptible(&nf_hook_mutex);
        if (err < 0)
                return err;
-       list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {
-               if (reg->priority < ((struct nf_hook_ops *)i)->priority)
+       list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
+               if (reg->priority < elem->priority)
                        break;
        }
-       list_add_rcu(&reg->list, i->prev);
+       list_add_rcu(&reg->list, elem->list.prev);
        mutex_unlock(&nf_hook_mutex);
        return 0;
 }
@@ -183,8 +178,7 @@ next_hook:
        } else if (verdict == NF_DROP) {
                kfree_skb(skb);
                ret = -EPERM;
-       } else if ((verdict & NF_VERDICT_MASK)  == NF_QUEUE) {
-               NFDEBUG("nf_hook: Verdict = QUEUE.\n");
+       } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
                if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
                              verdict >> NF_VERDICT_BITS))
                        goto next_hook;
@@ -217,22 +211,6 @@ int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)
 }
 EXPORT_SYMBOL(skb_make_writable);
 
-void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
-                           __be32 from, __be32 to, int pseudohdr)
-{
-       __be32 diff[] = { ~from, to };
-       if (skb->ip_summed != CHECKSUM_PARTIAL) {
-               *sum = csum_fold(csum_partial(diff, sizeof(diff),
-                               ~csum_unfold(*sum)));
-               if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
-                       skb->csum = ~csum_partial(diff, sizeof(diff),
-                                               ~skb->csum);
-       } else if (pseudohdr)
-               *sum = ~csum_fold(csum_partial(diff, sizeof(diff),
-                               csum_unfold(*sum)));
-}
-EXPORT_SYMBOL(nf_proto_csum_replace4);
-
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 /* This does not belong here, but locally generated errors need it if connection
    tracking in use: without this, connection may not be in hash table, and hence
@@ -294,3 +272,12 @@ void __init netfilter_init(void)
        if (netfilter_log_init() < 0)
                panic("cannot initialize nf_log");
 }
+
+#ifdef CONFIG_SYSCTL
+struct ctl_path nf_net_netfilter_sysctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "netfilter", .ctl_name = NET_NETFILTER, },
+       { }
+};
+EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path);
+#endif /* CONFIG_SYSCTL */
index a4d5cdeb0110c73fbf52ddc35cb6221741228600..078fff0335ad2170ca06a60ad781fcfa0d08018e 100644 (file)
@@ -81,7 +81,7 @@ static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple,
                   ((__force __u16)tuple->src.u.all << 16) |
                    (__force __u16)tuple->dst.u.all);
 
-       return jhash_2words(a, b, rnd) % size;
+       return ((u64)jhash_2words(a, b, rnd) * size) >> 32;
 }
 
 static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple)
@@ -831,10 +831,8 @@ EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
 int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
                               const struct nf_conntrack_tuple *tuple)
 {
-       NLA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t),
-               &tuple->src.u.tcp.port);
-       NLA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t),
-               &tuple->dst.u.tcp.port);
+       NLA_PUT_BE16(skb, CTA_PROTO_SRC_PORT, tuple->src.u.tcp.port);
+       NLA_PUT_BE16(skb, CTA_PROTO_DST_PORT, tuple->dst.u.tcp.port);
        return 0;
 
 nla_put_failure:
@@ -854,8 +852,8 @@ int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
        if (!tb[CTA_PROTO_SRC_PORT] || !tb[CTA_PROTO_DST_PORT])
                return -EINVAL;
 
-       t->src.u.tcp.port = *(__be16 *)nla_data(tb[CTA_PROTO_SRC_PORT]);
-       t->dst.u.tcp.port = *(__be16 *)nla_data(tb[CTA_PROTO_DST_PORT]);
+       t->src.u.tcp.port = nla_get_be16(tb[CTA_PROTO_SRC_PORT]);
+       t->dst.u.tcp.port = nla_get_be16(tb[CTA_PROTO_DST_PORT]);
 
        return 0;
 }
@@ -863,7 +861,7 @@ EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple);
 #endif
 
 /* Used by ipt_REJECT and ip6t_REJECT. */
-void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
+static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
 {
        struct nf_conn *ct;
        enum ip_conntrack_info ctinfo;
@@ -880,7 +878,6 @@ void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
        nskb->nfctinfo = ctinfo;
        nf_conntrack_get(nskb->nfct);
 }
-EXPORT_SYMBOL_GPL(__nf_conntrack_attach);
 
 static inline int
 do_iter(const struct nf_conntrack_tuple_hash *i,
@@ -1124,7 +1121,7 @@ int __init nf_conntrack_init(void)
                goto out_fini_expect;
 
        /* For use by REJECT target */
-       rcu_assign_pointer(ip_ct_attach, __nf_conntrack_attach);
+       rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
        rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
 
        /* Set up fake conntrack:
index 175c8d1a199219ee57144b9c1d0574c4374abf01..e0cd9d00aa61e872f2f769c142e065a529fcdf23 100644 (file)
@@ -73,15 +73,17 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect)
 
 static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple)
 {
+       unsigned int hash;
+
        if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
                get_random_bytes(&nf_ct_expect_hash_rnd, 4);
                nf_ct_expect_hash_rnd_initted = 1;
        }
 
-       return jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
+       hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
                      (((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
-                      (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd) %
-              nf_ct_expect_hsize;
+                      (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd);
+       return ((u64)hash * nf_ct_expect_hsize) >> 32;
 }
 
 struct nf_conntrack_expect *
@@ -226,8 +228,8 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
 EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
 
 void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
-                      union nf_conntrack_address *saddr,
-                      union nf_conntrack_address *daddr,
+                      union nf_inet_addr *saddr,
+                      union nf_inet_addr *daddr,
                       u_int8_t proto, __be16 *src, __be16 *dst)
 {
        int len;
index 6df259067f7e2c8251ecd657b0fc831bc51e4df8..6770baf2e845f1fafc0904f5251a3a6ed53e7a5a 100644 (file)
@@ -358,7 +358,7 @@ static int help(struct sk_buff *skb,
        unsigned int matchlen, matchoff;
        struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
        struct nf_conntrack_expect *exp;
-       union nf_conntrack_address *daddr;
+       union nf_inet_addr *daddr;
        struct nf_conntrack_man cmd = {};
        unsigned int i;
        int found = 0, ends_in_nl;
index a869403b229419562f6749b347b6ad7f8955e220..ff66fba514fd0c2ffe64a78e51bafb5761ceee54 100644 (file)
@@ -100,10 +100,10 @@ typedef struct {
 } bitstr_t;
 
 /* Tool Functions */
-#define INC_BIT(bs) if((++bs->bit)>7){bs->cur++;bs->bit=0;}
-#define INC_BITS(bs,b) if((bs->bit+=b)>7){bs->cur+=bs->bit>>3;bs->bit&=7;}
-#define BYTE_ALIGN(bs) if(bs->bit){bs->cur++;bs->bit=0;}
-#define CHECK_BOUND(bs,n) if(bs->cur+(n)>bs->end)return(H323_ERROR_BOUND)
+#define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;}
+#define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;}
+#define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;}
+#define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND)
 static unsigned get_len(bitstr_t * bs);
 static unsigned get_bit(bitstr_t * bs);
 static unsigned get_bits(bitstr_t * bs, unsigned b);
index f23fd9598e199d3b6be8cada071222db7b6a61ee..872c1aa3124c2945fae2d8a5be2672d1242a447e 100644 (file)
@@ -50,12 +50,12 @@ MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
 int (*set_h245_addr_hook) (struct sk_buff *skb,
                           unsigned char **data, int dataoff,
                           H245_TransportAddress *taddr,
-                          union nf_conntrack_address *addr, __be16 port)
+                          union nf_inet_addr *addr, __be16 port)
                           __read_mostly;
 int (*set_h225_addr_hook) (struct sk_buff *skb,
                           unsigned char **data, int dataoff,
                           TransportAddress *taddr,
-                          union nf_conntrack_address *addr, __be16 port)
+                          union nf_inet_addr *addr, __be16 port)
                           __read_mostly;
 int (*set_sig_addr_hook) (struct sk_buff *skb,
                          struct nf_conn *ct,
@@ -214,7 +214,7 @@ static int get_tpkt_data(struct sk_buff *skb, unsigned int protoff,
 /****************************************************************************/
 static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
                         H245_TransportAddress *taddr,
-                        union nf_conntrack_address *addr, __be16 *port)
+                        union nf_inet_addr *addr, __be16 *port)
 {
        unsigned char *p;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -257,7 +257,7 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct,
        int ret = 0;
        __be16 port;
        __be16 rtp_port, rtcp_port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *rtp_exp;
        struct nf_conntrack_expect *rtcp_exp;
        typeof(nat_rtp_rtcp_hook) nat_rtp_rtcp;
@@ -330,7 +330,7 @@ static int expect_t120(struct sk_buff *skb,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
        typeof(nat_t120_hook) nat_t120;
 
@@ -623,7 +623,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
 /****************************************************************************/
 int get_h225_addr(struct nf_conn *ct, unsigned char *data,
                  TransportAddress *taddr,
-                 union nf_conntrack_address *addr, __be16 *port)
+                 union nf_inet_addr *addr, __be16 *port)
 {
        unsigned char *p;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -662,7 +662,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
        typeof(nat_h245_hook) nat_h245;
 
@@ -704,13 +704,19 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
 
 /* If the calling party is on the same side of the forward-to party,
  * we don't need to track the second call */
-static int callforward_do_filter(union nf_conntrack_address *src,
-                                union nf_conntrack_address *dst,
+static int callforward_do_filter(union nf_inet_addr *src,
+                                union nf_inet_addr *dst,
                                 int family)
 {
+       const struct nf_afinfo *afinfo;
        struct flowi fl1, fl2;
        int ret = 0;
 
+       /* rcu_read_lock()ed by nf_hook_slow() */
+       afinfo = nf_get_afinfo(family);
+       if (!afinfo)
+               return 0;
+
        memset(&fl1, 0, sizeof(fl1));
        memset(&fl2, 0, sizeof(fl2));
 
@@ -720,8 +726,8 @@ static int callforward_do_filter(union nf_conntrack_address *src,
 
                fl1.fl4_dst = src->ip;
                fl2.fl4_dst = dst->ip;
-               if (ip_route_output_key(&rt1, &fl1) == 0) {
-                       if (ip_route_output_key(&rt2, &fl2) == 0) {
+               if (!afinfo->route((struct dst_entry **)&rt1, &fl1)) {
+                       if (!afinfo->route((struct dst_entry **)&rt2, &fl2)) {
                                if (rt1->rt_gateway == rt2->rt_gateway &&
                                    rt1->u.dst.dev  == rt2->u.dst.dev)
                                        ret = 1;
@@ -731,16 +737,15 @@ static int callforward_do_filter(union nf_conntrack_address *src,
                }
                break;
        }
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#if defined(CONFIG_NF_CONNTRACK_IPV6) || \
+    defined(CONFIG_NF_CONNTRACK_IPV6_MODULE)
        case AF_INET6: {
                struct rt6_info *rt1, *rt2;
 
                memcpy(&fl1.fl6_dst, src, sizeof(fl1.fl6_dst));
                memcpy(&fl2.fl6_dst, dst, sizeof(fl2.fl6_dst));
-               rt1 = (struct rt6_info *)ip6_route_output(NULL, &fl1);
-               if (rt1) {
-                       rt2 = (struct rt6_info *)ip6_route_output(NULL, &fl2);
-                       if (rt2) {
+               if (!afinfo->route((struct dst_entry **)&rt1, &fl1)) {
+                       if (!afinfo->route((struct dst_entry **)&rt2, &fl2)) {
                                if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway,
                                            sizeof(rt1->rt6i_gateway)) &&
                                    rt1->u.dst.dev == rt2->u.dst.dev)
@@ -767,7 +772,7 @@ static int expect_callforwarding(struct sk_buff *skb,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
        typeof(nat_callforwarding_hook) nat_callforwarding;
 
@@ -823,7 +828,7 @@ static int process_setup(struct sk_buff *skb, struct nf_conn *ct,
        int ret;
        int i;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        typeof(set_h225_addr_hook) set_h225_addr;
 
        pr_debug("nf_ct_q931: Setup\n");
@@ -1195,7 +1200,7 @@ static unsigned char *get_udp_data(struct sk_buff *skb, unsigned int protoff,
 
 /****************************************************************************/
 static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
-                                              union nf_conntrack_address *addr,
+                                              union nf_inet_addr *addr,
                                               __be16 port)
 {
        struct nf_conntrack_expect *exp;
@@ -1237,7 +1242,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct,
        int ret = 0;
        int i;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
        typeof(nat_q931_hook) nat_q931;
 
@@ -1306,7 +1311,7 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
 
        pr_debug("nf_ct_ras: GCF\n");
@@ -1466,7 +1471,7 @@ static int process_arq(struct sk_buff *skb, struct nf_conn *ct,
        struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
        int dir = CTINFO2DIR(ctinfo);
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        typeof(set_h225_addr_hook) set_h225_addr;
 
        pr_debug("nf_ct_ras: ARQ\n");
@@ -1508,7 +1513,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
        typeof(set_sig_addr_hook) set_sig_addr;
 
@@ -1571,7 +1576,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct,
        int dir = CTINFO2DIR(ctinfo);
        int ret = 0;
        __be16 port;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        struct nf_conntrack_expect *exp;
 
        pr_debug("nf_ct_ras: LCF\n");
index 991c52c9a28b6b53e9d106cfa1b6f1a082080962..8e914e5ffea84f9497fee492bbdf097a84b661f5 100644 (file)
@@ -55,12 +55,6 @@ static int generic_print_tuple(struct seq_file *s,
        return 0;
 }
 
-static int generic_print_conntrack(struct seq_file *s,
-                               const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 static int generic_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
                               unsigned int *dataoff, u_int8_t *protonum)
 {
@@ -75,7 +69,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_generic __read_mostly = {
        .pkt_to_tuple    = generic_pkt_to_tuple,
        .invert_tuple    = generic_invert_tuple,
        .print_tuple     = generic_print_tuple,
-       .print_conntrack = generic_print_conntrack,
        .get_l4proto     = generic_get_l4proto,
 };
 EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);
index 7d231243754ac089dbbf0f61f2eef20bd0908395..38141f104db7cfda21817140dce88f1d02bb0747 100644 (file)
@@ -59,7 +59,7 @@ ctnetlink_dump_tuples_proto(struct sk_buff *skb,
        nest_parms = nla_nest_start(skb, CTA_TUPLE_PROTO | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
-       NLA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
+       NLA_PUT_U8(skb, CTA_PROTO_NUM, tuple->dst.protonum);
 
        if (likely(l4proto->tuple_to_nlattr))
                ret = l4proto->tuple_to_nlattr(skb, tuple);
@@ -95,7 +95,7 @@ nla_put_failure:
        return -1;
 }
 
-static inline int
+static int
 ctnetlink_dump_tuples(struct sk_buff *skb,
                      const struct nf_conntrack_tuple *tuple)
 {
@@ -120,8 +120,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
 static inline int
 ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
 {
-       __be32 status = htonl((u_int32_t) ct->status);
-       NLA_PUT(skb, CTA_STATUS, sizeof(status), &status);
+       NLA_PUT_BE32(skb, CTA_STATUS, htonl(ct->status));
        return 0;
 
 nla_put_failure:
@@ -131,15 +130,12 @@ nla_put_failure:
 static inline int
 ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
 {
-       long timeout_l = ct->timeout.expires - jiffies;
-       __be32 timeout;
+       long timeout = (ct->timeout.expires - jiffies) / HZ;
 
-       if (timeout_l < 0)
+       if (timeout < 0)
                timeout = 0;
-       else
-               timeout = htonl(timeout_l / HZ);
 
-       NLA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout);
+       NLA_PUT_BE32(skb, CTA_TIMEOUT, htonl(timeout));
        return 0;
 
 nla_put_failure:
@@ -193,7 +189,7 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
        nest_helper = nla_nest_start(skb, CTA_HELP | NLA_F_NESTED);
        if (!nest_helper)
                goto nla_put_failure;
-       NLA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name);
+       NLA_PUT_STRING(skb, CTA_HELP_NAME, helper->name);
 
        if (helper->to_nlattr)
                helper->to_nlattr(skb, ct);
@@ -209,23 +205,21 @@ nla_put_failure:
 }
 
 #ifdef CONFIG_NF_CT_ACCT
-static inline int
+static int
 ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
                        enum ip_conntrack_dir dir)
 {
        enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
        struct nlattr *nest_count;
-       __be32 tmp;
 
        nest_count = nla_nest_start(skb, type | NLA_F_NESTED);
        if (!nest_count)
                goto nla_put_failure;
 
-       tmp = htonl(ct->counters[dir].packets);
-       NLA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
-
-       tmp = htonl(ct->counters[dir].bytes);
-       NLA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+       NLA_PUT_BE32(skb, CTA_COUNTERS32_PACKETS,
+                    htonl(ct->counters[dir].packets));
+       NLA_PUT_BE32(skb, CTA_COUNTERS32_BYTES,
+                    htonl(ct->counters[dir].bytes));
 
        nla_nest_end(skb, nest_count);
 
@@ -242,9 +236,7 @@ nla_put_failure:
 static inline int
 ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
 {
-       __be32 mark = htonl(ct->mark);
-
-       NLA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
+       NLA_PUT_BE32(skb, CTA_MARK, htonl(ct->mark));
        return 0;
 
 nla_put_failure:
@@ -254,11 +246,95 @@ nla_put_failure:
 #define ctnetlink_dump_mark(a, b) (0)
 #endif
 
+#ifdef CONFIG_NF_CONNTRACK_SECMARK
+static inline int
+ctnetlink_dump_secmark(struct sk_buff *skb, const struct nf_conn *ct)
+{
+       NLA_PUT_BE32(skb, CTA_SECMARK, htonl(ct->secmark));
+       return 0;
+
+nla_put_failure:
+       return -1;
+}
+#else
+#define ctnetlink_dump_secmark(a, b) (0)
+#endif
+
+#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
+
+static inline int
+ctnetlink_dump_master(struct sk_buff *skb, const struct nf_conn *ct)
+{
+       struct nlattr *nest_parms;
+
+       if (!(ct->status & IPS_EXPECTED))
+               return 0;
+
+       nest_parms = nla_nest_start(skb, CTA_TUPLE_MASTER | NLA_F_NESTED);
+       if (!nest_parms)
+               goto nla_put_failure;
+       if (ctnetlink_dump_tuples(skb, master_tuple(ct)) < 0)
+               goto nla_put_failure;
+       nla_nest_end(skb, nest_parms);
+
+       return 0;
+
+nla_put_failure:
+       return -1;
+}
+
+#ifdef CONFIG_NF_NAT_NEEDED
+static int
+dump_nat_seq_adj(struct sk_buff *skb, const struct nf_nat_seq *natseq, int type)
+{
+       struct nlattr *nest_parms;
+
+       nest_parms = nla_nest_start(skb, type | NLA_F_NESTED);
+       if (!nest_parms)
+               goto nla_put_failure;
+
+       NLA_PUT_BE32(skb, CTA_NAT_SEQ_CORRECTION_POS,
+                    htonl(natseq->correction_pos));
+       NLA_PUT_BE32(skb, CTA_NAT_SEQ_OFFSET_BEFORE,
+                    htonl(natseq->offset_before));
+       NLA_PUT_BE32(skb, CTA_NAT_SEQ_OFFSET_AFTER,
+                    htonl(natseq->offset_after));
+
+       nla_nest_end(skb, nest_parms);
+
+       return 0;
+
+nla_put_failure:
+       return -1;
+}
+
+static inline int
+ctnetlink_dump_nat_seq_adj(struct sk_buff *skb, const struct nf_conn *ct)
+{
+       struct nf_nat_seq *natseq;
+       struct nf_conn_nat *nat = nfct_nat(ct);
+
+       if (!(ct->status & IPS_SEQ_ADJUST) || !nat)
+               return 0;
+
+       natseq = &nat->seq[IP_CT_DIR_ORIGINAL];
+       if (dump_nat_seq_adj(skb, natseq, CTA_NAT_SEQ_ADJ_ORIG) == -1)
+               return -1;
+
+       natseq = &nat->seq[IP_CT_DIR_REPLY];
+       if (dump_nat_seq_adj(skb, natseq, CTA_NAT_SEQ_ADJ_REPLY) == -1)
+               return -1;
+
+       return 0;
+}
+#else
+#define ctnetlink_dump_nat_seq_adj(a, b) (0)
+#endif
+
 static inline int
 ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
 {
-       __be32 id = htonl((unsigned long)ct);
-       NLA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
+       NLA_PUT_BE32(skb, CTA_ID, htonl((unsigned long)ct));
        return 0;
 
 nla_put_failure:
@@ -268,9 +344,7 @@ nla_put_failure:
 static inline int
 ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
 {
-       __be32 use = htonl(atomic_read(&ct->ct_general.use));
-
-       NLA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
+       NLA_PUT_BE32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use)));
        return 0;
 
 nla_put_failure:
@@ -320,8 +394,11 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
            ctnetlink_dump_protoinfo(skb, ct) < 0 ||
            ctnetlink_dump_helpinfo(skb, ct) < 0 ||
            ctnetlink_dump_mark(skb, ct) < 0 ||
+           ctnetlink_dump_secmark(skb, ct) < 0 ||
            ctnetlink_dump_id(skb, ct) < 0 ||
-           ctnetlink_dump_use(skb, ct) < 0)
+           ctnetlink_dump_use(skb, ct) < 0 ||
+           ctnetlink_dump_master(skb, ct) < 0 ||
+           ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
                goto nla_put_failure;
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
@@ -419,11 +496,24 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
                    && ctnetlink_dump_mark(skb, ct) < 0)
                        goto nla_put_failure;
 #endif
+#ifdef CONFIG_NF_CONNTRACK_SECMARK
+               if ((events & IPCT_SECMARK || ct->secmark)
+                   && ctnetlink_dump_secmark(skb, ct) < 0)
+                       goto nla_put_failure;
+#endif
 
                if (events & IPCT_COUNTER_FILLING &&
                    (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
                     ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
                        goto nla_put_failure;
+
+               if (events & IPCT_RELATED &&
+                   ctnetlink_dump_master(skb, ct) < 0)
+                       goto nla_put_failure;
+
+               if (events & IPCT_NATSEQADJ &&
+                   ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
+                       goto nla_put_failure;
        }
 
        nlh->nlmsg_len = skb->tail - b;
@@ -444,7 +534,7 @@ static int ctnetlink_done(struct netlink_callback *cb)
        return 0;
 }
 
-#define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
+#define L3PROTO(ct) (ct)->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
 
 static int
 ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
@@ -542,7 +632,7 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr,
 
        if (!tb[CTA_PROTO_NUM])
                return -EINVAL;
-       tuple->dst.protonum = *(u_int8_t *)nla_data(tb[CTA_PROTO_NUM]);
+       tuple->dst.protonum = nla_get_u8(tb[CTA_PROTO_NUM]);
 
        l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
 
@@ -558,7 +648,7 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr,
        return ret;
 }
 
-static inline int
+static int
 ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
                      enum ctattr_tuple type, u_int8_t l3num)
 {
@@ -605,7 +695,7 @@ static int nfnetlink_parse_nat_proto(struct nlattr *attr,
                                     struct nf_nat_range *range)
 {
        struct nlattr *tb[CTA_PROTONAT_MAX+1];
-       struct nf_nat_protocol *npt;
+       const struct nf_nat_protocol *npt;
        int err;
 
        err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
@@ -647,12 +737,12 @@ nfnetlink_parse_nat(struct nlattr *nat,
                return err;
 
        if (tb[CTA_NAT_MINIP])
-               range->min_ip = *(__be32 *)nla_data(tb[CTA_NAT_MINIP]);
+               range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
 
        if (!tb[CTA_NAT_MAXIP])
                range->max_ip = range->min_ip;
        else
-               range->max_ip = *(__be32 *)nla_data(tb[CTA_NAT_MAXIP]);
+               range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
 
        if (range->min_ip)
                range->flags |= IP_NAT_RANGE_MAP_IPS;
@@ -722,7 +812,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        ct = nf_ct_tuplehash_to_ctrack(h);
 
        if (cda[CTA_ID]) {
-               u_int32_t id = ntohl(*(__be32 *)nla_data(cda[CTA_ID]));
+               u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID]));
                if (id != (u32)(unsigned long)ct) {
                        nf_ct_put(ct);
                        return -ENOENT;
@@ -798,11 +888,11 @@ out:
        return err;
 }
 
-static inline int
+static int
 ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
 {
        unsigned long d;
-       unsigned int status = ntohl(*(__be32 *)nla_data(cda[CTA_STATUS]));
+       unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
        d = ct->status ^ status;
 
        if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -828,19 +918,17 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
                        if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
                                                &range) < 0)
                                return -EINVAL;
-                       if (nf_nat_initialized(ct,
-                                              HOOK2MANIP(NF_IP_PRE_ROUTING)))
+                       if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
                                return -EEXIST;
-                       nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
+                       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
                }
                if (cda[CTA_NAT_SRC]) {
                        if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
                                                &range) < 0)
                                return -EINVAL;
-                       if (nf_nat_initialized(ct,
-                                              HOOK2MANIP(NF_IP_POST_ROUTING)))
+                       if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
                                return -EEXIST;
-                       nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+                       nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
                }
 #endif
        }
@@ -904,7 +992,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
 static inline int
 ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
 {
-       u_int32_t timeout = ntohl(*(__be32 *)nla_data(cda[CTA_TIMEOUT]));
+       u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
 
        if (!del_timer(&ct->timeout))
                return -ETIME;
@@ -935,6 +1023,66 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
        return err;
 }
 
+#ifdef CONFIG_NF_NAT_NEEDED
+static inline int
+change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
+{
+       struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
+
+       nla_parse_nested(cda, CTA_NAT_SEQ_MAX, attr, NULL);
+
+       if (!cda[CTA_NAT_SEQ_CORRECTION_POS])
+               return -EINVAL;
+
+       natseq->correction_pos =
+               ntohl(nla_get_be32(cda[CTA_NAT_SEQ_CORRECTION_POS]));
+
+       if (!cda[CTA_NAT_SEQ_OFFSET_BEFORE])
+               return -EINVAL;
+
+       natseq->offset_before =
+               ntohl(nla_get_be32(cda[CTA_NAT_SEQ_OFFSET_BEFORE]));
+
+       if (!cda[CTA_NAT_SEQ_OFFSET_AFTER])
+               return -EINVAL;
+
+       natseq->offset_after =
+               ntohl(nla_get_be32(cda[CTA_NAT_SEQ_OFFSET_AFTER]));
+
+       return 0;
+}
+
+static int
+ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
+{
+       int ret = 0;
+       struct nf_conn_nat *nat = nfct_nat(ct);
+
+       if (!nat)
+               return 0;
+
+       if (cda[CTA_NAT_SEQ_ADJ_ORIG]) {
+               ret = change_nat_seq_adj(&nat->seq[IP_CT_DIR_ORIGINAL],
+                                        cda[CTA_NAT_SEQ_ADJ_ORIG]);
+               if (ret < 0)
+                       return ret;
+
+               ct->status |= IPS_SEQ_ADJUST;
+       }
+
+       if (cda[CTA_NAT_SEQ_ADJ_REPLY]) {
+               ret = change_nat_seq_adj(&nat->seq[IP_CT_DIR_REPLY],
+                                        cda[CTA_NAT_SEQ_ADJ_REPLY]);
+               if (ret < 0)
+                       return ret;
+
+               ct->status |= IPS_SEQ_ADJUST;
+       }
+
+       return 0;
+}
+#endif
+
 static int
 ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
 {
@@ -966,7 +1114,15 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
 
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK])
-               ct->mark = ntohl(*(__be32 *)nla_data(cda[CTA_MARK]));
+               ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
+#endif
+
+#ifdef CONFIG_NF_NAT_NEEDED
+       if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) {
+               err = ctnetlink_change_nat_seq_adj(ct, cda);
+               if (err < 0)
+                       return err;
+       }
 #endif
 
        return 0;
@@ -989,7 +1145,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
 
        if (!cda[CTA_TIMEOUT])
                goto err;
-       ct->timeout.expires = ntohl(*(__be32 *)nla_data(cda[CTA_TIMEOUT]));
+       ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
 
        ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
        ct->status |= IPS_CONFIRMED;
@@ -1008,7 +1164,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
 
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK])
-               ct->mark = ntohl(*(__be32 *)nla_data(cda[CTA_MARK]));
+               ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
 #endif
 
        helper = nf_ct_helper_find_get(rtuple);
@@ -1193,13 +1349,15 @@ nla_put_failure:
        return -1;
 }
 
-static inline int
+static int
 ctnetlink_exp_dump_expect(struct sk_buff *skb,
                          const struct nf_conntrack_expect *exp)
 {
        struct nf_conn *master = exp->master;
-       __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
-       __be32 id = htonl((unsigned long)exp);
+       long timeout = (exp->timeout.expires - jiffies) / HZ;
+
+       if (timeout < 0)
+               timeout = 0;
 
        if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
                goto nla_put_failure;
@@ -1210,8 +1368,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
                                 CTA_EXPECT_MASTER) < 0)
                goto nla_put_failure;
 
-       NLA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
-       NLA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
+       NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout));
+       NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp));
 
        return 0;
 
@@ -1384,7 +1542,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
                return -ENOENT;
 
        if (cda[CTA_EXPECT_ID]) {
-               __be32 id = *(__be32 *)nla_data(cda[CTA_EXPECT_ID]);
+               __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
                if (ntohl(id) != (u32)(unsigned long)exp) {
                        nf_ct_expect_put(exp);
                        return -ENOENT;
@@ -1438,7 +1596,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                        return -ENOENT;
 
                if (cda[CTA_EXPECT_ID]) {
-                       __be32 id = *(__be32 *)nla_data(cda[CTA_EXPECT_ID]);
+                       __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
                        if (ntohl(id) != (u32)(unsigned long)exp) {
                                nf_ct_expect_put(exp);
                                return -ENOENT;
index 6d947068c58fe864986d23f520ce2ae9a5fee89f..8595b5946acf03bb78c58ab9dfbbe617067df404 100644 (file)
@@ -36,11 +36,11 @@ static DEFINE_MUTEX(nf_ct_proto_mutex);
 
 #ifdef CONFIG_SYSCTL
 static int
-nf_ct_register_sysctl(struct ctl_table_header **header, struct ctl_table *path,
+nf_ct_register_sysctl(struct ctl_table_header **header, struct ctl_path *path,
                      struct ctl_table *table, unsigned int *users)
 {
        if (*header == NULL) {
-               *header = nf_register_sysctl_table(path, table);
+               *header = register_sysctl_paths(path, table);
                if (*header == NULL)
                        return -ENOMEM;
        }
@@ -55,7 +55,8 @@ nf_ct_unregister_sysctl(struct ctl_table_header **header,
 {
        if (users != NULL && --*users > 0)
                return;
-       nf_unregister_sysctl_table(*header, table);
+
+       unregister_sysctl_table(*header);
        *header = NULL;
 }
 #endif
index 13f8191796420584c109b3f971093965ed91c08b..22c5dcb6306aad685f1aa0c4d8b31ff4e8d31aa9 100644 (file)
@@ -40,13 +40,6 @@ static int generic_print_tuple(struct seq_file *s,
        return 0;
 }
 
-/* Print out the private part of the conntrack. */
-static int generic_print_conntrack(struct seq_file *s,
-                                  const struct nf_conn *state)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, or -1 for invalid. */
 static int packet(struct nf_conn *conntrack,
                  const struct sk_buff *skb,
@@ -104,7 +97,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_generic __read_mostly =
        .pkt_to_tuple           = generic_pkt_to_tuple,
        .invert_tuple           = generic_invert_tuple,
        .print_tuple            = generic_print_tuple,
-       .print_conntrack        = generic_print_conntrack,
        .packet                 = packet,
        .new                    = new,
 #ifdef CONFIG_SYSCTL
index cb046751059278d602848b4126d530a37bc165bf..21d29e782baf3ae0970efac12e8587b934fa1f47 100644 (file)
@@ -49,24 +49,15 @@ static const char *sctp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS  * 24 HOURS
 
-static unsigned int nf_ct_sctp_timeout_closed __read_mostly          =  10 SECS;
-static unsigned int nf_ct_sctp_timeout_cookie_wait __read_mostly     =   3 SECS;
-static unsigned int nf_ct_sctp_timeout_cookie_echoed __read_mostly   =   3 SECS;
-static unsigned int nf_ct_sctp_timeout_established __read_mostly     =   5 DAYS;
-static unsigned int nf_ct_sctp_timeout_shutdown_sent __read_mostly   = 300 SECS / 1000;
-static unsigned int nf_ct_sctp_timeout_shutdown_recd __read_mostly   = 300 SECS / 1000;
-static unsigned int nf_ct_sctp_timeout_shutdown_ack_sent __read_mostly = 3 SECS;
-
-static unsigned int * sctp_timeouts[]
-= { NULL,                                  /* SCTP_CONNTRACK_NONE  */
-    &nf_ct_sctp_timeout_closed,                   /* SCTP_CONNTRACK_CLOSED */
-    &nf_ct_sctp_timeout_cookie_wait,       /* SCTP_CONNTRACK_COOKIE_WAIT */
-    &nf_ct_sctp_timeout_cookie_echoed,     /* SCTP_CONNTRACK_COOKIE_ECHOED */
-    &nf_ct_sctp_timeout_established,       /* SCTP_CONNTRACK_ESTABLISHED */
-    &nf_ct_sctp_timeout_shutdown_sent,     /* SCTP_CONNTRACK_SHUTDOWN_SENT */
-    &nf_ct_sctp_timeout_shutdown_recd,     /* SCTP_CONNTRACK_SHUTDOWN_RECD */
-    &nf_ct_sctp_timeout_shutdown_ack_sent  /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
- };
+static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
+       [SCTP_CONNTRACK_CLOSED]                 = 10 SECS,
+       [SCTP_CONNTRACK_COOKIE_WAIT]            = 3 SECS,
+       [SCTP_CONNTRACK_COOKIE_ECHOED]          = 3 SECS,
+       [SCTP_CONNTRACK_ESTABLISHED]            = 5 DAYS,
+       [SCTP_CONNTRACK_SHUTDOWN_SENT]          = 300 SECS / 1000,
+       [SCTP_CONNTRACK_SHUTDOWN_RECD]          = 300 SECS / 1000,
+       [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]      = 3 SECS,
+};
 
 #define sNO SCTP_CONNTRACK_NONE
 #define        sCL SCTP_CONNTRACK_CLOSED
@@ -110,7 +101,7 @@ cookie echoed to closed.
 */
 
 /* SCTP conntrack state transitions */
-static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
+static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
        {
 /*     ORIGINAL        */
 /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
@@ -173,29 +164,28 @@ 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 *conntrack)
+static int sctp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
 {
        enum sctp_conntrack state;
 
        read_lock_bh(&sctp_lock);
-       state = conntrack->proto.sctp.state;
+       state = ct->proto.sctp.state;
        read_unlock_bh(&sctp_lock);
 
        return seq_printf(s, "%s ", sctp_conntrack_names[state]);
 }
 
 #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count)    \
-for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0;             \
-       offset < skb->len &&                                            \
-       (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch));   \
-       offset += (ntohs(sch->length) + 3) & ~3, count++)
+for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0;       \
+       (offset) < (skb)->len &&                                        \
+       ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch)));   \
+       (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
 
 /* Some validity checks to make sure the chunks are fine */
-static int do_basic_checks(struct nf_conn *conntrack,
+static int do_basic_checks(struct nf_conn *ct,
                           const struct sk_buff *skb,
                           unsigned int dataoff,
-                          char *map)
+                          unsigned long *map)
 {
        u_int32_t offset, count;
        sctp_chunkhdr_t _sch, *sch;
@@ -206,76 +196,83 @@ static int do_basic_checks(struct nf_conn *conntrack,
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
                pr_debug("Chunk Num: %d  Type: %d\n", count, sch->type);
 
-               if (sch->type == SCTP_CID_INIT
-                       || sch->type == SCTP_CID_INIT_ACK
-                       || sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
+               if (sch->type == SCTP_CID_INIT ||
+                   sch->type == SCTP_CID_INIT_ACK ||
+                   sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
                        flag = 1;
-               }
 
                /*
                 * Cookie Ack/Echo chunks not the first OR
                 * Init / Init Ack / Shutdown compl chunks not the only chunks
                 * OR zero-length.
                 */
-               if (((sch->type == SCTP_CID_COOKIE_ACK
-                       || sch->type == SCTP_CID_COOKIE_ECHO
-                       || flag)
-                     && count !=0) || !sch->length) {
+               if (((sch->type == SCTP_CID_COOKIE_ACK ||
+                     sch->type == SCTP_CID_COOKIE_ECHO ||
+                     flag) &&
+                    count != 0) || !sch->length) {
                        pr_debug("Basic checks failed\n");
                        return 1;
                }
 
-               if (map) {
-                       set_bit(sch->type, (void *)map);
-               }
+               if (map)
+                       set_bit(sch->type, map);
        }
 
        pr_debug("Basic checks passed\n");
        return count == 0;
 }
 
-static int new_state(enum ip_conntrack_dir dir,
-                    enum sctp_conntrack cur_state,
-                    int chunk_type)
+static int sctp_new_state(enum ip_conntrack_dir dir,
+                         enum sctp_conntrack cur_state,
+                         int chunk_type)
 {
        int i;
 
        pr_debug("Chunk type: %d\n", chunk_type);
 
        switch (chunk_type) {
-               case SCTP_CID_INIT:
-                       pr_debug("SCTP_CID_INIT\n");
-                       i = 0; break;
-               case SCTP_CID_INIT_ACK:
-                       pr_debug("SCTP_CID_INIT_ACK\n");
-                       i = 1; break;
-               case SCTP_CID_ABORT:
-                       pr_debug("SCTP_CID_ABORT\n");
-                       i = 2; break;
-               case SCTP_CID_SHUTDOWN:
-                       pr_debug("SCTP_CID_SHUTDOWN\n");
-                       i = 3; break;
-               case SCTP_CID_SHUTDOWN_ACK:
-                       pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
-                       i = 4; break;
-               case SCTP_CID_ERROR:
-                       pr_debug("SCTP_CID_ERROR\n");
-                       i = 5; break;
-               case SCTP_CID_COOKIE_ECHO:
-                       pr_debug("SCTP_CID_COOKIE_ECHO\n");
-                       i = 6; break;
-               case SCTP_CID_COOKIE_ACK:
-                       pr_debug("SCTP_CID_COOKIE_ACK\n");
-                       i = 7; break;
-               case SCTP_CID_SHUTDOWN_COMPLETE:
-                       pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
-                       i = 8; break;
-               default:
-                       /* Other chunks like DATA, SACK, HEARTBEAT and
-                       its ACK do not cause a change in state */
-                       pr_debug("Unknown chunk type, Will stay in %s\n",
-                                sctp_conntrack_names[cur_state]);
-                       return cur_state;
+       case SCTP_CID_INIT:
+               pr_debug("SCTP_CID_INIT\n");
+               i = 0;
+               break;
+       case SCTP_CID_INIT_ACK:
+               pr_debug("SCTP_CID_INIT_ACK\n");
+               i = 1;
+               break;
+       case SCTP_CID_ABORT:
+               pr_debug("SCTP_CID_ABORT\n");
+               i = 2;
+               break;
+       case SCTP_CID_SHUTDOWN:
+               pr_debug("SCTP_CID_SHUTDOWN\n");
+               i = 3;
+               break;
+       case SCTP_CID_SHUTDOWN_ACK:
+               pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
+               i = 4;
+               break;
+       case SCTP_CID_ERROR:
+               pr_debug("SCTP_CID_ERROR\n");
+               i = 5;
+               break;
+       case SCTP_CID_COOKIE_ECHO:
+               pr_debug("SCTP_CID_COOKIE_ECHO\n");
+               i = 6;
+               break;
+       case SCTP_CID_COOKIE_ACK:
+               pr_debug("SCTP_CID_COOKIE_ACK\n");
+               i = 7;
+               break;
+       case SCTP_CID_SHUTDOWN_COMPLETE:
+               pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
+               i = 8;
+               break;
+       default:
+               /* Other chunks like DATA, SACK, HEARTBEAT and
+               its ACK do not cause a change in state */
+               pr_debug("Unknown chunk type, Will stay in %s\n",
+                        sctp_conntrack_names[cur_state]);
+               return cur_state;
        }
 
        pr_debug("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s\n",
@@ -285,154 +282,145 @@ static int new_state(enum ip_conntrack_dir dir,
        return sctp_conntracks[dir][i][cur_state];
 }
 
-/* Returns verdict for packet, or -1 for invalid. */
-static int sctp_packet(struct nf_conn *conntrack,
+/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
+static int sctp_packet(struct nf_conn *ct,
                       const struct sk_buff *skb,
                       unsigned int dataoff,
                       enum ip_conntrack_info ctinfo,
                       int pf,
                       unsigned int hooknum)
 {
-       enum sctp_conntrack newconntrack, oldsctpstate;
+       enum sctp_conntrack new_state, old_state;
+       enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
        sctp_sctphdr_t _sctph, *sh;
        sctp_chunkhdr_t _sch, *sch;
        u_int32_t offset, count;
-       char map[256 / sizeof (char)] = {0};
+       unsigned long map[256 / sizeof(unsigned long)] = { 0 };
 
        sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
        if (sh == NULL)
-               return -1;
+               goto out;
 
-       if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
-               return -1;
+       if (do_basic_checks(ct, skb, dataoff, map) != 0)
+               goto out;
 
        /* Check the verification tag (Sec 8.5) */
-       if (!test_bit(SCTP_CID_INIT, (void *)map)
-               && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)
-               && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map)
-               && !test_bit(SCTP_CID_ABORT, (void *)map)
-               && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map)
-               && (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
+       if (!test_bit(SCTP_CID_INIT, map) &&
+           !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
+           !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
+           !test_bit(SCTP_CID_ABORT, map) &&
+           !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
+           sh->vtag != ct->proto.sctp.vtag[dir]) {
                pr_debug("Verification tag check failed\n");
-               return -1;
+               goto out;
        }
 
-       oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
+       old_state = new_state = SCTP_CONNTRACK_MAX;
+       write_lock_bh(&sctp_lock);
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
-               write_lock_bh(&sctp_lock);
-
                /* Special cases of Verification tag check (Sec 8.5.1) */
                if (sch->type == SCTP_CID_INIT) {
                        /* Sec 8.5.1 (A) */
-                       if (sh->vtag != 0) {
-                               write_unlock_bh(&sctp_lock);
-                               return -1;
-                       }
+                       if (sh->vtag != 0)
+                               goto out_unlock;
                } else if (sch->type == SCTP_CID_ABORT) {
                        /* Sec 8.5.1 (B) */
-                       if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
-                               && !(sh->vtag == conntrack->proto.sctp.vtag
-                                                       [1 - CTINFO2DIR(ctinfo)])) {
-                               write_unlock_bh(&sctp_lock);
-                               return -1;
-                       }
+                       if (sh->vtag != ct->proto.sctp.vtag[dir] &&
+                           sh->vtag != ct->proto.sctp.vtag[!dir])
+                               goto out_unlock;
                } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
                        /* Sec 8.5.1 (C) */
-                       if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])
-                               && !(sh->vtag == conntrack->proto.sctp.vtag
-                                                       [1 - CTINFO2DIR(ctinfo)]
-                                       && (sch->flags & 1))) {
-                               write_unlock_bh(&sctp_lock);
-                               return -1;
-                       }
+                       if (sh->vtag != ct->proto.sctp.vtag[dir] &&
+                           sh->vtag != ct->proto.sctp.vtag[!dir] &&
+                           sch->flags & SCTP_CHUNK_FLAG_T)
+                               goto out_unlock;
                } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
                        /* Sec 8.5.1 (D) */
-                       if (!(sh->vtag == conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) {
-                               write_unlock_bh(&sctp_lock);
-                               return -1;
-                       }
+                       if (sh->vtag != ct->proto.sctp.vtag[dir])
+                               goto out_unlock;
                }
 
-               oldsctpstate = conntrack->proto.sctp.state;
-               newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
+               old_state = ct->proto.sctp.state;
+               new_state = sctp_new_state(dir, old_state, sch->type);
 
                /* Invalid */
-               if (newconntrack == SCTP_CONNTRACK_MAX) {
+               if (new_state == SCTP_CONNTRACK_MAX) {
                        pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
                                 "conntrack=%u\n",
-                                CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
-                       write_unlock_bh(&sctp_lock);
-                       return -1;
+                                dir, sch->type, old_state);
+                       goto out_unlock;
                }
 
                /* If it is an INIT or an INIT ACK note down the vtag */
-               if (sch->type == SCTP_CID_INIT
-                       || sch->type == SCTP_CID_INIT_ACK) {
+               if (sch->type == SCTP_CID_INIT ||
+                   sch->type == SCTP_CID_INIT_ACK) {
                        sctp_inithdr_t _inithdr, *ih;
 
                        ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
                                                sizeof(_inithdr), &_inithdr);
-                       if (ih == NULL) {
-                                       write_unlock_bh(&sctp_lock);
-                                       return -1;
-                       }
+                       if (ih == NULL)
+                               goto out_unlock;
                        pr_debug("Setting vtag %x for dir %d\n",
-                                ih->init_tag, !CTINFO2DIR(ctinfo));
-                       conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
+                                ih->init_tag, !dir);
+                       ct->proto.sctp.vtag[!dir] = ih->init_tag;
                }
 
-               conntrack->proto.sctp.state = newconntrack;
-               if (oldsctpstate != newconntrack)
+               ct->proto.sctp.state = new_state;
+               if (old_state != new_state)
                        nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
-               write_unlock_bh(&sctp_lock);
        }
+       write_unlock_bh(&sctp_lock);
 
-       nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
+       nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
 
-       if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED
-               && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
-               && newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
+       if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
+           dir == IP_CT_DIR_REPLY &&
+           new_state == SCTP_CONNTRACK_ESTABLISHED) {
                pr_debug("Setting assured bit\n");
-               set_bit(IPS_ASSURED_BIT, &conntrack->status);
+               set_bit(IPS_ASSURED_BIT, &ct->status);
                nf_conntrack_event_cache(IPCT_STATUS, skb);
        }
 
        return NF_ACCEPT;
+
+out_unlock:
+       write_unlock_bh(&sctp_lock);
+out:
+       return -NF_ACCEPT;
 }
 
 /* Called when a new connection for this protocol found. */
-static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
+static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
                    unsigned int dataoff)
 {
-       enum sctp_conntrack newconntrack;
+       enum sctp_conntrack new_state;
        sctp_sctphdr_t _sctph, *sh;
        sctp_chunkhdr_t _sch, *sch;
        u_int32_t offset, count;
-       char map[256 / sizeof (char)] = {0};
+       unsigned long map[256 / sizeof(unsigned long)] = { 0 };
 
        sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
        if (sh == NULL)
                return 0;
 
-       if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
+       if (do_basic_checks(ct, skb, dataoff, map) != 0)
                return 0;
 
        /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
-       if ((test_bit (SCTP_CID_ABORT, (void *)map))
-               || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map))
-               || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) {
+       if (test_bit(SCTP_CID_ABORT, map) ||
+           test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
+           test_bit(SCTP_CID_COOKIE_ACK, map))
                return 0;
-       }
 
-       newconntrack = SCTP_CONNTRACK_MAX;
+       new_state = SCTP_CONNTRACK_MAX;
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
                /* Don't need lock here: this conntrack not in circulation yet */
-               newconntrack = new_state(IP_CT_DIR_ORIGINAL,
-                                        SCTP_CONNTRACK_NONE, sch->type);
+               new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
+                                          SCTP_CONNTRACK_NONE, sch->type);
 
                /* Invalid: delete conntrack */
-               if (newconntrack == SCTP_CONNTRACK_NONE ||
-                   newconntrack == SCTP_CONNTRACK_MAX) {
+               if (new_state == SCTP_CONNTRACK_NONE ||
+                   new_state == SCTP_CONNTRACK_MAX) {
                        pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
                        return 0;
                }
@@ -450,7 +438,7 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
                                pr_debug("Setting vtag %x for new conn\n",
                                         ih->init_tag);
 
-                               conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
+                               ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
                                                                ih->init_tag;
                        } else {
                                /* Sec 8.5.1 (A) */
@@ -462,10 +450,10 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
                else {
                        pr_debug("Setting vtag %x for new conn OOTB\n",
                                 sh->vtag);
-                       conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
+                       ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
                }
 
-               conntrack->proto.sctp.state = newconntrack;
+               ct->proto.sctp.state = new_state;
        }
 
        return 1;
@@ -477,49 +465,49 @@ static struct ctl_table_header *sctp_sysctl_header;
 static struct ctl_table sctp_sysctl_table[] = {
        {
                .procname       = "nf_conntrack_sctp_timeout_closed",
-               .data           = &nf_ct_sctp_timeout_closed,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_cookie_wait",
-               .data           = &nf_ct_sctp_timeout_cookie_wait,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_cookie_echoed",
-               .data           = &nf_ct_sctp_timeout_cookie_echoed,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_established",
-               .data           = &nf_ct_sctp_timeout_established,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_sent",
-               .data           = &nf_ct_sctp_timeout_shutdown_sent,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_recd",
-               .data           = &nf_ct_sctp_timeout_shutdown_recd,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
-               .data           = &nf_ct_sctp_timeout_shutdown_ack_sent,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
@@ -533,49 +521,49 @@ static struct ctl_table sctp_sysctl_table[] = {
 static struct ctl_table sctp_compat_sysctl_table[] = {
        {
                .procname       = "ip_conntrack_sctp_timeout_closed",
-               .data           = &nf_ct_sctp_timeout_closed,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_cookie_wait",
-               .data           = &nf_ct_sctp_timeout_cookie_wait,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_cookie_echoed",
-               .data           = &nf_ct_sctp_timeout_cookie_echoed,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_established",
-               .data           = &nf_ct_sctp_timeout_established,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_sent",
-               .data           = &nf_ct_sctp_timeout_shutdown_sent,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_recd",
-               .data           = &nf_ct_sctp_timeout_shutdown_recd,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
-               .data           = &nf_ct_sctp_timeout_shutdown_ack_sent,
+               .data           = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
@@ -598,6 +586,11 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
        .packet                 = sctp_packet,
        .new                    = sctp_new,
        .me                     = THIS_MODULE,
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
+#endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &sctp_sysctl_table_users,
        .ctl_table_header       = &sctp_sysctl_header,
@@ -619,6 +612,11 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
        .packet                 = sctp_packet,
        .new                    = sctp_new,
        .me                     = THIS_MODULE,
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+       .tuple_to_nlattr        = nf_ct_port_tuple_to_nlattr,
+       .nlattr_to_tuple        = nf_ct_port_nlattr_to_tuple,
+       .nla_policy             = nf_ct_port_nla_policy,
+#endif
 #ifdef CONFIG_SYSCTL
        .ctl_table_users        = &sctp_sysctl_table_users,
        .ctl_table_header       = &sctp_sysctl_header,
index 7a3f64c1aca6f346581c0ef0bc54427f2fb75d14..64c9b910419c052395b1e431b84e262f11fa13b5 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_log.h>
 
 /* Protects conntrack->proto.tcp */
 static DEFINE_RWLOCK(tcp_lock);
@@ -63,32 +64,21 @@ static const char *tcp_conntrack_names[] = {
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-static unsigned int nf_ct_tcp_timeout_syn_sent __read_mostly =      2 MINS;
-static unsigned int nf_ct_tcp_timeout_syn_recv __read_mostly =     60 SECS;
-static unsigned int nf_ct_tcp_timeout_established __read_mostly =   5 DAYS;
-static unsigned int nf_ct_tcp_timeout_fin_wait __read_mostly =      2 MINS;
-static unsigned int nf_ct_tcp_timeout_close_wait __read_mostly =   60 SECS;
-static unsigned int nf_ct_tcp_timeout_last_ack __read_mostly =     30 SECS;
-static unsigned int nf_ct_tcp_timeout_time_wait __read_mostly =     2 MINS;
-static unsigned int nf_ct_tcp_timeout_close __read_mostly =        10 SECS;
-
 /* RFC1122 says the R2 limit should be at least 100 seconds.
    Linux uses 15 packets as limit, which corresponds
    to ~13-30min depending on RTO. */
 static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly =   5 MINS;
 
-static unsigned int * tcp_timeouts[] = {
-    NULL,                              /* TCP_CONNTRACK_NONE */
-    &nf_ct_tcp_timeout_syn_sent,       /* TCP_CONNTRACK_SYN_SENT, */
-    &nf_ct_tcp_timeout_syn_recv,       /* TCP_CONNTRACK_SYN_RECV, */
-    &nf_ct_tcp_timeout_established,    /* TCP_CONNTRACK_ESTABLISHED, */
-    &nf_ct_tcp_timeout_fin_wait,       /* TCP_CONNTRACK_FIN_WAIT, */
-    &nf_ct_tcp_timeout_close_wait,     /* TCP_CONNTRACK_CLOSE_WAIT, */
-    &nf_ct_tcp_timeout_last_ack,       /* TCP_CONNTRACK_LAST_ACK, */
-    &nf_ct_tcp_timeout_time_wait,      /* TCP_CONNTRACK_TIME_WAIT, */
-    &nf_ct_tcp_timeout_close,          /* TCP_CONNTRACK_CLOSE, */
-    NULL,                              /* TCP_CONNTRACK_LISTEN */
- };
+static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
+       [TCP_CONNTRACK_SYN_SENT]        = 2 MINS,
+       [TCP_CONNTRACK_SYN_RECV]        = 60 SECS,
+       [TCP_CONNTRACK_ESTABLISHED]     = 5 DAYS,
+       [TCP_CONNTRACK_FIN_WAIT]        = 2 MINS,
+       [TCP_CONNTRACK_CLOSE_WAIT]      = 60 SECS,
+       [TCP_CONNTRACK_LAST_ACK]        = 30 SECS,
+       [TCP_CONNTRACK_TIME_WAIT]       = 2 MINS,
+       [TCP_CONNTRACK_CLOSE]           = 10 SECS,
+};
 
 #define sNO TCP_CONNTRACK_NONE
 #define sSS TCP_CONNTRACK_SYN_SENT
@@ -148,7 +138,7 @@ enum tcp_bit_set {
  *     if they are invalid
  *     or we do not support the request (simultaneous open)
  */
-static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
        {
 /* ORIGINAL */
 /*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
@@ -783,9 +773,7 @@ static int tcp_error(struct sk_buff *skb,
         * because the checksum is assumed to be correct.
         */
        /* FIXME: Source route IP option packets --RR */
-       if (nf_conntrack_checksum &&
-           ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
                if (LOG_INVALID(IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -942,8 +930,8 @@ static int tcp_packet(struct nf_conn *conntrack,
                || new_state == TCP_CONNTRACK_CLOSE))
                conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
        timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans
-                 && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
-                 ? nf_ct_tcp_timeout_max_retrans : *tcp_timeouts[new_state];
+                 && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans
+                 ? nf_ct_tcp_timeout_max_retrans : tcp_timeouts[new_state];
        write_unlock_bh(&tcp_lock);
 
        nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb);
@@ -1074,14 +1062,13 @@ static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
        if (!nest_parms)
                goto nla_put_failure;
 
-       NLA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
-               &ct->proto.tcp.state);
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_STATE, ct->proto.tcp.state);
 
-       NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),
-               &ct->proto.tcp.seen[0].td_scale);
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
+                  ct->proto.tcp.seen[0].td_scale);
 
-       NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),
-               &ct->proto.tcp.seen[1].td_scale);
+       NLA_PUT_U8(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY,
+                  ct->proto.tcp.seen[1].td_scale);
 
        tmp.flags = ct->proto.tcp.seen[0].flags;
        NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
@@ -1128,8 +1115,7 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
                return -EINVAL;
 
        write_lock_bh(&tcp_lock);
-       ct->proto.tcp.state =
-               *(u_int8_t *)nla_data(tb[CTA_PROTOINFO_TCP_STATE]);
+       ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
 
        if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
                struct nf_ct_tcp_flags *attr =
@@ -1149,10 +1135,10 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
            tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
            ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
            ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
-               ct->proto.tcp.seen[0].td_scale = *(u_int8_t *)
-                       nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
-               ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)
-                       nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
+               ct->proto.tcp.seen[0].td_scale =
+                       nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
+               ct->proto.tcp.seen[1].td_scale =
+                       nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
        }
        write_unlock_bh(&tcp_lock);
 
@@ -1166,56 +1152,56 @@ static struct ctl_table_header *tcp_sysctl_header;
 static struct ctl_table tcp_sysctl_table[] = {
        {
                .procname       = "nf_conntrack_tcp_timeout_syn_sent",
-               .data           = &nf_ct_tcp_timeout_syn_sent,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_syn_recv",
-               .data           = &nf_ct_tcp_timeout_syn_recv,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_established",
-               .data           = &nf_ct_tcp_timeout_established,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_fin_wait",
-               .data           = &nf_ct_tcp_timeout_fin_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_close_wait",
-               .data           = &nf_ct_tcp_timeout_close_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_last_ack",
-               .data           = &nf_ct_tcp_timeout_last_ack,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_time_wait",
-               .data           = &nf_ct_tcp_timeout_time_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "nf_conntrack_tcp_timeout_close",
-               .data           = &nf_ct_tcp_timeout_close,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
@@ -1260,56 +1246,56 @@ static struct ctl_table tcp_sysctl_table[] = {
 static struct ctl_table tcp_compat_sysctl_table[] = {
        {
                .procname       = "ip_conntrack_tcp_timeout_syn_sent",
-               .data           = &nf_ct_tcp_timeout_syn_sent,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_syn_recv",
-               .data           = &nf_ct_tcp_timeout_syn_recv,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_established",
-               .data           = &nf_ct_tcp_timeout_established,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_ESTABLISHED],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_fin_wait",
-               .data           = &nf_ct_tcp_timeout_fin_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_FIN_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_close_wait",
-               .data           = &nf_ct_tcp_timeout_close_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_last_ack",
-               .data           = &nf_ct_tcp_timeout_last_ack,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_LAST_ACK],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_time_wait",
-               .data           = &nf_ct_tcp_timeout_time_wait,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_TIME_WAIT],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
        },
        {
                .procname       = "ip_conntrack_tcp_timeout_close",
-               .data           = &nf_ct_tcp_timeout_close,
+               .data           = &tcp_timeouts[TCP_CONNTRACK_CLOSE],
                .maxlen         = sizeof(unsigned int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec_jiffies,
index b3e7ecb080e624575bf630b13d52c8abd6000d0c..3848754110820894c241d568779c1643fc3623bf 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_log.h>
 
 static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ;
 static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ;
@@ -59,13 +60,6 @@ static int udp_print_tuple(struct seq_file *s,
                          ntohs(tuple->dst.u.udp.port));
 }
 
-/* Print out the private part of the conntrack. */
-static int udp_print_conntrack(struct seq_file *s,
-                              const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, and may modify conntracktype */
 static int udp_packet(struct nf_conn *conntrack,
                      const struct sk_buff *skb,
@@ -128,9 +122,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
         * We skip checking packets on the outgoing path
         * because the checksum is assumed to be correct.
         * FIXME: Source route IP option packets --RR */
-       if (nf_conntrack_checksum &&
-           ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING)) &&
+       if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING &&
            nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
                if (LOG_INVALID(IPPROTO_UDP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
@@ -194,7 +186,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
        .pkt_to_tuple           = udp_pkt_to_tuple,
        .invert_tuple           = udp_invert_tuple,
        .print_tuple            = udp_print_tuple,
-       .print_conntrack        = udp_print_conntrack,
        .packet                 = udp_packet,
        .new                    = udp_new,
        .error                  = udp_error,
@@ -222,7 +213,6 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
        .pkt_to_tuple           = udp_pkt_to_tuple,
        .invert_tuple           = udp_invert_tuple,
        .print_tuple            = udp_print_tuple,
-       .print_conntrack        = udp_print_conntrack,
        .packet                 = udp_packet,
        .new                    = udp_new,
        .error                  = udp_error,
index b8981dd922bed6efe20c2b2727e8e673410b4d20..070056d9bcd6f52dd7459c98df33ce8585d24f52 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/netfilter_ipv6.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
+#include <net/netfilter/nf_log.h>
 
 static unsigned int nf_ct_udplite_timeout __read_mostly = 30*HZ;
 static unsigned int nf_ct_udplite_timeout_stream __read_mostly = 180*HZ;
@@ -58,13 +59,6 @@ static int udplite_print_tuple(struct seq_file *s,
                          ntohs(tuple->dst.u.udp.port));
 }
 
-/* Print out the private part of the conntrack. */
-static int udplite_print_conntrack(struct seq_file *s,
-                                  const struct nf_conn *conntrack)
-{
-       return 0;
-}
-
 /* Returns verdict for packet, and may modify conntracktype */
 static int udplite_packet(struct nf_conn *conntrack,
                          const struct sk_buff *skb,
@@ -133,8 +127,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
 
        /* Checksum invalid? Ignore. */
        if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) &&
-           ((pf == PF_INET && hooknum == NF_IP_PRE_ROUTING) ||
-            (pf == PF_INET6 && hooknum == NF_IP6_PRE_ROUTING))) {
+           hooknum == NF_INET_PRE_ROUTING) {
                if (pf == PF_INET) {
                        struct iphdr *iph = ip_hdr(skb);
 
@@ -198,7 +191,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
        .pkt_to_tuple           = udplite_pkt_to_tuple,
        .invert_tuple           = udplite_invert_tuple,
        .print_tuple            = udplite_print_tuple,
-       .print_conntrack        = udplite_print_conntrack,
        .packet                 = udplite_packet,
        .new                    = udplite_new,
        .error                  = udplite_error,
@@ -222,7 +214,6 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 __read_mostly =
        .pkt_to_tuple           = udplite_pkt_to_tuple,
        .invert_tuple           = udplite_invert_tuple,
        .print_tuple            = udplite_print_tuple,
-       .print_conntrack        = udplite_print_conntrack,
        .packet                 = udplite_packet,
        .new                    = udplite_new,
        .error                  = udplite_error,
index 515abffc4a09807d3a06a4097eb826458e45c57f..47d8947cf26348124698a0c90cbdc0323766b1d2 100644 (file)
@@ -247,7 +247,7 @@ static int skp_digits_len(struct nf_conn *ct, const char *dptr,
 }
 
 static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
-                     union nf_conntrack_address *addr, const char *limit)
+                     union nf_inet_addr *addr, const char *limit)
 {
        const char *end;
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
@@ -275,7 +275,7 @@ static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
 static int epaddr_len(struct nf_conn *ct, const char *dptr,
                      const char *limit, int *shift)
 {
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        const char *aux = dptr;
 
        if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
@@ -366,7 +366,7 @@ EXPORT_SYMBOL_GPL(ct_sip_get_info);
 static int set_expected_rtp(struct sk_buff *skb,
                            struct nf_conn *ct,
                            enum ip_conntrack_info ctinfo,
-                           union nf_conntrack_address *addr,
+                           union nf_inet_addr *addr,
                            __be16 port,
                            const char *dptr)
 {
@@ -403,7 +403,7 @@ static int sip_help(struct sk_buff *skb,
                    enum ip_conntrack_info ctinfo)
 {
        int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
-       union nf_conntrack_address addr;
+       union nf_inet_addr addr;
        unsigned int dataoff, datalen;
        const char *dptr;
        int ret = NF_ACCEPT;
index 9efdd37fc19543a1e57b013ff51686ad2b1c406a..696074a037c1a10a1e1177854a2f303da8434541 100644 (file)
@@ -142,10 +142,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
                       ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
                return -ENOSPC;
 
-       if (l3proto->print_conntrack(s, conntrack))
-               return -ENOSPC;
-
-       if (l4proto->print_conntrack(s, conntrack))
+       if (l4proto->print_conntrack && l4proto->print_conntrack(s, conntrack))
                return -ENOSPC;
 
        if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
@@ -383,15 +380,11 @@ static ctl_table nf_ct_netfilter_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table nf_ct_net_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = nf_ct_netfilter_table,
-       },
-       { .ctl_name = 0 }
+struct ctl_path nf_ct_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { }
 };
+
 EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
 #endif /* CONFIG_SYSCTL */
 
@@ -418,7 +411,8 @@ static int __init nf_conntrack_standalone_init(void)
        proc_stat->owner = THIS_MODULE;
 #endif
 #ifdef CONFIG_SYSCTL
-       nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table);
+       nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path,
+                       nf_ct_netfilter_table);
        if (nf_ct_sysctl_header == NULL) {
                printk("nf_conntrack: can't register to sysctl.\n");
                ret = -ENOMEM;
index d67c4fbf6031ec487e9205098e01d787de5fe033..4f5f2885fcac31de3d43f2eceba9c8ba8ebf75eb 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/netfilter.h>
 #include <linux/seq_file.h>
 #include <net/protocol.h>
+#include <net/netfilter/nf_log.h>
 
 #include "nf_internals.h"
 
 
 #define NF_LOG_PREFIXLEN               128
 
-static struct nf_logger *nf_loggers[NPROTO];
+static const struct nf_logger *nf_loggers[NPROTO] __read_mostly;
 static DEFINE_MUTEX(nf_log_mutex);
 
 /* return EBUSY if somebody else is registered, EEXIST if the same logger
  * is registred, 0 on success. */
-int nf_log_register(int pf, struct nf_logger *logger)
+int nf_log_register(int pf, const struct nf_logger *logger)
 {
        int ret;
 
@@ -57,7 +58,7 @@ void nf_log_unregister_pf(int pf)
 }
 EXPORT_SYMBOL(nf_log_unregister_pf);
 
-void nf_log_unregister(struct nf_logger *logger)
+void nf_log_unregister(const struct nf_logger *logger)
 {
        int i;
 
@@ -77,12 +78,12 @@ void nf_log_packet(int pf,
                   const struct sk_buff *skb,
                   const struct net_device *in,
                   const struct net_device *out,
-                  struct nf_loginfo *loginfo,
+                  const struct nf_loginfo *loginfo,
                   const char *fmt, ...)
 {
        va_list args;
        char prefix[NF_LOG_PREFIXLEN];
-       struct nf_logger *logger;
+       const struct nf_logger *logger;
 
        rcu_read_lock();
        logger = rcu_dereference(nf_loggers[pf]);
@@ -90,7 +91,6 @@ void nf_log_packet(int pf,
                va_start(args, fmt);
                vsnprintf(prefix, sizeof(prefix), fmt, args);
                va_end(args);
-               /* We must read logging before nf_logfn[pf] */
                logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix);
        } else if (net_ratelimit()) {
                printk(KERN_WARNING "nf_log_packet: can\'t log since "
index 0cef1433d660d2fbd5925f2197f296821fdbcae2..bfc2928c19120f4c5994ae616066b1f030ba2a01 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/seq_file.h>
 #include <linux/rcupdate.h>
 #include <net/protocol.h>
+#include <net/netfilter/nf_queue.h>
 
 #include "nf_internals.h"
 
  * long term mutex.  The handler must provide an an outfn() to accept packets
  * for queueing and must reinject all packets it receives, no matter what.
  */
-static struct nf_queue_handler *queue_handler[NPROTO];
+static const struct nf_queue_handler *queue_handler[NPROTO];
 
 static DEFINE_MUTEX(queue_handler_mutex);
 
 /* return EBUSY when somebody else is registered, return EEXIST if the
  * same handler is registered, return 0 in case of success. */
-int nf_register_queue_handler(int pf, struct nf_queue_handler *qh)
+int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh)
 {
        int ret;
 
@@ -44,7 +45,7 @@ int nf_register_queue_handler(int pf, struct nf_queue_handler *qh)
 EXPORT_SYMBOL(nf_register_queue_handler);
 
 /* The caller must flush their queue before this */
-int nf_unregister_queue_handler(int pf, struct nf_queue_handler *qh)
+int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh)
 {
        if (pf >= NPROTO)
                return -EINVAL;
@@ -64,7 +65,7 @@ int nf_unregister_queue_handler(int pf, struct nf_queue_handler *qh)
 }
 EXPORT_SYMBOL(nf_unregister_queue_handler);
 
-void nf_unregister_queue_handlers(struct nf_queue_handler *qh)
+void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
 {
        int pf;
 
@@ -79,6 +80,27 @@ void nf_unregister_queue_handlers(struct nf_queue_handler *qh)
 }
 EXPORT_SYMBOL_GPL(nf_unregister_queue_handlers);
 
+static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
+{
+       /* Release those devices we held, or Alexey will kill me. */
+       if (entry->indev)
+               dev_put(entry->indev);
+       if (entry->outdev)
+               dev_put(entry->outdev);
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (entry->skb->nf_bridge) {
+               struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
+
+               if (nf_bridge->physindev)
+                       dev_put(nf_bridge->physindev);
+               if (nf_bridge->physoutdev)
+                       dev_put(nf_bridge->physoutdev);
+       }
+#endif
+       /* Drop reference to owner of hook which queued us. */
+       module_put(entry->elem->owner);
+}
+
 /*
  * Any packet that leaves via this function must come back
  * through nf_reinject().
@@ -92,84 +114,79 @@ static int __nf_queue(struct sk_buff *skb,
                      unsigned int queuenum)
 {
        int status;
-       struct nf_info *info;
+       struct nf_queue_entry *entry = NULL;
 #ifdef CONFIG_BRIDGE_NETFILTER
-       struct net_device *physindev = NULL;
-       struct net_device *physoutdev = NULL;
+       struct net_device *physindev;
+       struct net_device *physoutdev;
 #endif
-       struct nf_afinfo *afinfo;
-       struct nf_queue_handler *qh;
+       const struct nf_afinfo *afinfo;
+       const struct nf_queue_handler *qh;
 
        /* QUEUE == DROP if noone is waiting, to be safe. */
        rcu_read_lock();
 
        qh = rcu_dereference(queue_handler[pf]);
-       if (!qh) {
-               rcu_read_unlock();
-               kfree_skb(skb);
-               return 1;
-       }
+       if (!qh)
+               goto err_unlock;
 
        afinfo = nf_get_afinfo(pf);
-       if (!afinfo) {
-               rcu_read_unlock();
-               kfree_skb(skb);
-               return 1;
-       }
-
-       info = kmalloc(sizeof(*info) + afinfo->route_key_size, GFP_ATOMIC);
-       if (!info) {
-               if (net_ratelimit())
-                       printk(KERN_ERR "OOM queueing packet %p\n",
-                              skb);
-               rcu_read_unlock();
-               kfree_skb(skb);
-               return 1;
-       }
-
-       *info = (struct nf_info) {
-               (struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn };
+       if (!afinfo)
+               goto err_unlock;
+
+       entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC);
+       if (!entry)
+               goto err_unlock;
+
+       *entry = (struct nf_queue_entry) {
+               .skb    = skb,
+               .elem   = list_entry(elem, struct nf_hook_ops, list),
+               .pf     = pf,
+               .hook   = hook,
+               .indev  = indev,
+               .outdev = outdev,
+               .okfn   = okfn,
+       };
 
        /* If it's going away, ignore hook. */
-       if (!try_module_get(info->elem->owner)) {
+       if (!try_module_get(entry->elem->owner)) {
                rcu_read_unlock();
-               kfree(info);
+               kfree(entry);
                return 0;
        }
 
        /* Bump dev refs so they don't vanish while packet is out */
-       if (indev) dev_hold(indev);
-       if (outdev) dev_hold(outdev);
-
+       if (indev)
+               dev_hold(indev);
+       if (outdev)
+               dev_hold(outdev);
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (skb->nf_bridge) {
                physindev = skb->nf_bridge->physindev;
-               if (physindev) dev_hold(physindev);
+               if (physindev)
+                       dev_hold(physindev);
                physoutdev = skb->nf_bridge->physoutdev;
-               if (physoutdev) dev_hold(physoutdev);
+               if (physoutdev)
+                       dev_hold(physoutdev);
        }
 #endif
-       afinfo->saveroute(skb, info);
-       status = qh->outfn(skb, info, queuenum, qh->data);
+       afinfo->saveroute(skb, entry);
+       status = qh->outfn(entry, queuenum);
 
        rcu_read_unlock();
 
        if (status < 0) {
-               /* James M doesn't say fuck enough. */
-               if (indev) dev_put(indev);
-               if (outdev) dev_put(outdev);
-#ifdef CONFIG_BRIDGE_NETFILTER
-               if (physindev) dev_put(physindev);
-               if (physoutdev) dev_put(physoutdev);
-#endif
-               module_put(info->elem->owner);
-               kfree(info);
-               kfree_skb(skb);
-
-               return 1;
+               nf_queue_entry_release_refs(entry);
+               goto err;
        }
 
        return 1;
+
+err_unlock:
+       rcu_read_unlock();
+err:
+       kfree_skb(skb);
+       kfree(entry);
+       return 1;
 }
 
 int nf_queue(struct sk_buff *skb,
@@ -212,41 +229,15 @@ int nf_queue(struct sk_buff *skb,
        return 1;
 }
 
-void nf_reinject(struct sk_buff *skb, struct nf_info *info,
-                unsigned int verdict)
+void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
 {
-       struct list_head *elem = &info->elem->list;
-       struct list_head *i;
-       struct nf_afinfo *afinfo;
+       struct sk_buff *skb = entry->skb;
+       struct list_head *elem = &entry->elem->list;
+       const struct nf_afinfo *afinfo;
 
        rcu_read_lock();
 
-       /* Release those devices we held, or Alexey will kill me. */
-       if (info->indev) dev_put(info->indev);
-       if (info->outdev) dev_put(info->outdev);
-#ifdef CONFIG_BRIDGE_NETFILTER
-       if (skb->nf_bridge) {
-               if (skb->nf_bridge->physindev)
-                       dev_put(skb->nf_bridge->physindev);
-               if (skb->nf_bridge->physoutdev)
-                       dev_put(skb->nf_bridge->physoutdev);
-       }
-#endif
-
-       /* Drop reference to owner of hook which queued us. */
-       module_put(info->elem->owner);
-
-       list_for_each_rcu(i, &nf_hooks[info->pf][info->hook]) {
-               if (i == elem)
-                       break;
-       }
-
-       if (i == &nf_hooks[info->pf][info->hook]) {
-               /* The module which sent it to userspace is gone. */
-               NFDEBUG("%s: module disappeared, dropping packet.\n",
-                       __FUNCTION__);
-               verdict = NF_DROP;
-       }
+       nf_queue_entry_release_refs(entry);
 
        /* Continue traversal iff userspace said ok... */
        if (verdict == NF_REPEAT) {
@@ -255,28 +246,30 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
        }
 
        if (verdict == NF_ACCEPT) {
-               afinfo = nf_get_afinfo(info->pf);
-               if (!afinfo || afinfo->reroute(skb, info) < 0)
+               afinfo = nf_get_afinfo(entry->pf);
+               if (!afinfo || afinfo->reroute(skb, entry) < 0)
                        verdict = NF_DROP;
        }
 
        if (verdict == NF_ACCEPT) {
        next_hook:
-               verdict = nf_iterate(&nf_hooks[info->pf][info->hook],
-                                    skb, info->hook,
-                                    info->indev, info->outdev, &elem,
-                                    info->okfn, INT_MIN);
+               verdict = nf_iterate(&nf_hooks[entry->pf][entry->hook],
+                                    skb, entry->hook,
+                                    entry->indev, entry->outdev, &elem,
+                                    entry->okfn, INT_MIN);
        }
 
        switch (verdict & NF_VERDICT_MASK) {
        case NF_ACCEPT:
        case NF_STOP:
-               info->okfn(skb);
+               local_bh_disable();
+               entry->okfn(skb);
+               local_bh_enable();
        case NF_STOLEN:
                break;
        case NF_QUEUE:
-               if (!__nf_queue(skb, elem, info->pf, info->hook,
-                               info->indev, info->outdev, info->okfn,
+               if (!__nf_queue(skb, elem, entry->pf, entry->hook,
+                               entry->indev, entry->outdev, entry->okfn,
                                verdict >> NF_VERDICT_BITS))
                        goto next_hook;
                break;
@@ -284,7 +277,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
                kfree_skb(skb);
        }
        rcu_read_unlock();
-       kfree(info);
+       kfree(entry);
        return;
 }
 EXPORT_SYMBOL(nf_reinject);
@@ -317,7 +310,7 @@ static int seq_show(struct seq_file *s, void *v)
 {
        int ret;
        loff_t *pos = v;
-       struct nf_queue_handler *qh;
+       const struct nf_queue_handler *qh;
 
        rcu_read_lock();
        qh = rcu_dereference(queue_handler[*pos]);
diff --git a/net/netfilter/nf_sysctl.c b/net/netfilter/nf_sysctl.c
deleted file mode 100644 (file)
index ee34589..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-/* nf_sysctl.c netfilter sysctl registration/unregistation
- *
- * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
- */
-#include <linux/module.h>
-#include <linux/sysctl.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-
-static void
-path_free(struct ctl_table *path, struct ctl_table *table)
-{
-       struct ctl_table *t, *next;
-
-       for (t = path; t != NULL && t != table; t = next) {
-               next = t->child;
-               kfree(t);
-       }
-}
-
-static struct ctl_table *
-path_dup(struct ctl_table *path, struct ctl_table *table)
-{
-       struct ctl_table *t, *last = NULL, *tmp;
-
-       for (t = path; t != NULL; t = t->child) {
-               /* twice the size since path elements are terminated by an
-                * empty element */
-               tmp = kmemdup(t, 2 * sizeof(*t), GFP_KERNEL);
-               if (tmp == NULL) {
-                       if (last != NULL)
-                               path_free(path, table);
-                       return NULL;
-               }
-
-               if (last != NULL)
-                       last->child = tmp;
-               else
-                       path = tmp;
-               last = tmp;
-       }
-
-       if (last != NULL)
-               last->child = table;
-       else
-               path = table;
-
-       return path;
-}
-
-struct ctl_table_header *
-nf_register_sysctl_table(struct ctl_table *path, struct ctl_table *table)
-{
-       struct ctl_table_header *header;
-
-       path = path_dup(path, table);
-       if (path == NULL)
-               return NULL;
-       header = register_sysctl_table(path);
-       if (header == NULL)
-               path_free(path, table);
-       return header;
-}
-EXPORT_SYMBOL_GPL(nf_register_sysctl_table);
-
-void
-nf_unregister_sysctl_table(struct ctl_table_header *header,
-                          struct ctl_table *table)
-{
-       struct ctl_table *path = header->ctl_table;
-
-       unregister_sysctl_table(header);
-       path_free(path, table);
-}
-EXPORT_SYMBOL_GPL(nf_unregister_sysctl_table);
-
-/* net/netfilter */
-static struct ctl_table nf_net_netfilter_table[] = {
-       {
-               .ctl_name       = NET_NETFILTER,
-               .procname       = "netfilter",
-               .mode           = 0555,
-       },
-       {
-               .ctl_name       = 0
-       }
-};
-struct ctl_table nf_net_netfilter_sysctl_path[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = nf_net_netfilter_table,
-       },
-       {
-               .ctl_name       = 0
-       }
-};
-EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path);
-
-/* net/ipv4/netfilter */
-static struct ctl_table nf_net_ipv4_netfilter_table[] = {
-       {
-               .ctl_name       = NET_IPV4_NETFILTER,
-               .procname       = "netfilter",
-               .mode           = 0555,
-       },
-       {
-               .ctl_name       = 0
-       }
-};
-static struct ctl_table nf_net_ipv4_table[] = {
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = nf_net_ipv4_netfilter_table,
-       },
-       {
-               .ctl_name       = 0
-       }
-};
-struct ctl_table nf_net_ipv4_netfilter_sysctl_path[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = nf_net_ipv4_table,
-       },
-       {
-               .ctl_name       = 0
-       }
-};
-EXPORT_SYMBOL_GPL(nf_net_ipv4_netfilter_sysctl_path);
index 2128542995f79279fb026bcc4688eef46b434305..b75c9c4a995d885c1ac12339b0afff9d1d24db31 100644 (file)
@@ -179,7 +179,7 @@ static void nfnetlink_rcv(struct sk_buff *skb)
 static void __exit nfnetlink_exit(void)
 {
        printk("Removing netfilter NETLINK layer.\n");
-       sock_release(nfnl->sk_socket);
+       netlink_kernel_release(nfnl);
        return;
 }
 
index 2c7bd2eb0294400ed1175749f41281ed4f7b735b..5013cb97ce2ba82c481023ba552461f5185bbc8d 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/jhash.h>
 #include <linux/random.h>
 #include <net/sock.h>
+#include <net/netfilter/nf_log.h>
 
 #include <asm/atomic.h>
 
 #define PRINTR(x, args...)     do { if (net_ratelimit()) \
                                     printk(x, ## args); } while (0);
 
-#if 0
-#define UDEBUG(x, args ...)    printk(KERN_DEBUG "%s(%d):%s(): " x,       \
-                                       __FILE__, __LINE__, __FUNCTION__,  \
-                                       ## args)
-#else
-#define UDEBUG(x, ...)
-#endif
-
 struct nfulnl_instance {
        struct hlist_node hlist;        /* global list of instances */
        spinlock_t lock;
@@ -92,8 +85,6 @@ __instance_lookup(u_int16_t group_num)
        struct hlist_node *pos;
        struct nfulnl_instance *inst;
 
-       UDEBUG("entering (group_num=%u)\n", group_num);
-
        head = &instance_table[instance_hashfn(group_num)];
        hlist_for_each_entry(inst, pos, head, hlist) {
                if (inst->group_num == group_num)
@@ -126,7 +117,6 @@ static void
 instance_put(struct nfulnl_instance *inst)
 {
        if (inst && atomic_dec_and_test(&inst->use)) {
-               UDEBUG("kfree(inst=%p)\n", inst);
                kfree(inst);
                module_put(THIS_MODULE);
        }
@@ -138,23 +128,23 @@ static struct nfulnl_instance *
 instance_create(u_int16_t group_num, int pid)
 {
        struct nfulnl_instance *inst;
-
-       UDEBUG("entering (group_num=%u, pid=%d)\n", group_num,
-               pid);
+       int err;
 
        write_lock_bh(&instances_lock);
        if (__instance_lookup(group_num)) {
-               inst = NULL;
-               UDEBUG("aborting, instance already exists\n");
+               err = -EEXIST;
                goto out_unlock;
        }
 
        inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
-       if (!inst)
+       if (!inst) {
+               err = -ENOMEM;
                goto out_unlock;
+       }
 
        if (!try_module_get(THIS_MODULE)) {
                kfree(inst);
+               err = -EAGAIN;
                goto out_unlock;
        }
 
@@ -177,16 +167,13 @@ instance_create(u_int16_t group_num, int pid)
        hlist_add_head(&inst->hlist,
                       &instance_table[instance_hashfn(group_num)]);
 
-       UDEBUG("newly added node: %p, next=%p\n", &inst->hlist,
-               inst->hlist.next);
-
        write_unlock_bh(&instances_lock);
 
        return inst;
 
 out_unlock:
        write_unlock_bh(&instances_lock);
-       return NULL;
+       return ERR_PTR(err);
 }
 
 static void __nfulnl_flush(struct nfulnl_instance *inst);
@@ -195,9 +182,6 @@ static void
 __instance_destroy(struct nfulnl_instance *inst)
 {
        /* first pull it out of the global list */
-       UDEBUG("removing instance %p (queuenum=%u) from hash\n",
-               inst, inst->group_num);
-
        hlist_del(&inst->hlist);
 
        /* then flush all pending packets from skb */
@@ -305,8 +289,6 @@ nfulnl_alloc_skb(unsigned int inst_size, unsigned int pkt_size)
        struct sk_buff *skb;
        unsigned int n;
 
-       UDEBUG("entered (%u, %u)\n", inst_size, pkt_size);
-
        /* alloc skb which should be big enough for a whole multipart
         * message.  WARNING: has to be <= 128k due to slab restrictions */
 
@@ -341,10 +323,6 @@ __nfulnl_send(struct nfulnl_instance *inst)
                          sizeof(struct nfgenmsg));
 
        status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT);
-       if (status < 0) {
-               UDEBUG("netlink_unicast() failed\n");
-               /* FIXME: statistics */
-       }
 
        inst->qlen = 0;
        inst->skb = NULL;
@@ -368,8 +346,6 @@ nfulnl_timer(unsigned long data)
 {
        struct nfulnl_instance *inst = (struct nfulnl_instance *)data;
 
-       UDEBUG("timer function called, flushing buffer\n");
-
        spin_lock_bh(&inst->lock);
        if (inst->skb)
                __nfulnl_send(inst);
@@ -396,8 +372,6 @@ __build_packet_message(struct nfulnl_instance *inst,
        __be32 tmp_uint;
        sk_buff_data_t old_tail = inst->skb->tail;
 
-       UDEBUG("entered\n");
-
        nlh = NLMSG_PUT(inst->skb, 0, 0,
                        NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
                        sizeof(struct nfgenmsg));
@@ -415,32 +389,27 @@ __build_packet_message(struct nfulnl_instance *inst,
                NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix);
 
        if (indev) {
-               tmp_uint = htonl(indev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
-               NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint),
-                       &tmp_uint);
+               NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+                            htonl(indev->ifindex));
 #else
                if (pf == PF_BRIDGE) {
                        /* Case 1: outdev is physical input device, we need to
                         * look for bridge group (when called from
                         * netfilter_bridge) */
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
-                               sizeof(tmp_uint), &tmp_uint);
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+                                    htonl(indev->ifindex));
                        /* this is the bridge group "brX" */
-                       tmp_uint = htonl(indev->br_port->br->dev->ifindex);
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
-                               sizeof(tmp_uint), &tmp_uint);
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+                                    htonl(indev->br_port->br->dev->ifindex));
                } else {
                        /* Case 2: indev is bridge group, we need to look for
                         * physical device (when called from ipv4) */
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
-                               sizeof(tmp_uint), &tmp_uint);
-                       if (skb->nf_bridge && skb->nf_bridge->physindev) {
-                               tmp_uint =
-                                   htonl(skb->nf_bridge->physindev->ifindex);
-                               NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
-                                       sizeof(tmp_uint), &tmp_uint);
-                       }
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+                                    htonl(indev->ifindex));
+                       if (skb->nf_bridge && skb->nf_bridge->physindev)
+                               NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+                                            htonl(skb->nf_bridge->physindev->ifindex));
                }
 #endif
        }
@@ -448,38 +417,32 @@ __build_packet_message(struct nfulnl_instance *inst,
        if (outdev) {
                tmp_uint = htonl(outdev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
-               NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint),
-                       &tmp_uint);
+               NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+                            htonl(outdev->ifindex));
 #else
                if (pf == PF_BRIDGE) {
                        /* Case 1: outdev is physical output device, we need to
                         * look for bridge group (when called from
                         * netfilter_bridge) */
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
-                               sizeof(tmp_uint), &tmp_uint);
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+                                    htonl(outdev->ifindex));
                        /* this is the bridge group "brX" */
-                       tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
-                               sizeof(tmp_uint), &tmp_uint);
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+                                    htonl(outdev->br_port->br->dev->ifindex));
                } else {
                        /* Case 2: indev is a bridge group, we need to look
                         * for physical device (when called from ipv4) */
-                       NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
-                               sizeof(tmp_uint), &tmp_uint);
-                       if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
-                               tmp_uint =
-                                   htonl(skb->nf_bridge->physoutdev->ifindex);
-                               NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
-                                       sizeof(tmp_uint), &tmp_uint);
-                       }
+                       NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+                                    htonl(outdev->ifindex));
+                       if (skb->nf_bridge && skb->nf_bridge->physoutdev)
+                               NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+                                            htonl(skb->nf_bridge->physoutdev->ifindex));
                }
 #endif
        }
 
-       if (skb->mark) {
-               tmp_uint = htonl(skb->mark);
-               NLA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint);
-       }
+       if (skb->mark)
+               NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
 
        if (indev && skb->dev) {
                struct nfulnl_msg_packet_hw phw;
@@ -504,23 +467,23 @@ __build_packet_message(struct nfulnl_instance *inst,
                read_lock_bh(&skb->sk->sk_callback_lock);
                if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
                        __be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
+                       __be32 gid = htons(skb->sk->sk_socket->file->f_gid);
                        /* need to unlock here since NLA_PUT may goto */
                        read_unlock_bh(&skb->sk->sk_callback_lock);
-                       NLA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid);
+                       NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
+                       NLA_PUT_BE32(inst->skb, NFULA_GID, gid);
                } else
                        read_unlock_bh(&skb->sk->sk_callback_lock);
        }
 
        /* local sequence number */
-       if (inst->flags & NFULNL_CFG_F_SEQ) {
-               tmp_uint = htonl(inst->seq++);
-               NLA_PUT(inst->skb, NFULA_SEQ, sizeof(tmp_uint), &tmp_uint);
-       }
+       if (inst->flags & NFULNL_CFG_F_SEQ)
+               NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++));
+
        /* global sequence number */
-       if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) {
-               tmp_uint = htonl(atomic_inc_return(&global_seq));
-               NLA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint);
-       }
+       if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
+               NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL,
+                            htonl(atomic_inc_return(&global_seq)));
 
        if (data_len) {
                struct nlattr *nla;
@@ -543,7 +506,6 @@ __build_packet_message(struct nfulnl_instance *inst,
        return 0;
 
 nlmsg_failure:
-       UDEBUG("nlmsg_failure\n");
 nla_put_failure:
        PRINTR(KERN_ERR "nfnetlink_log: error creating log nlmsg\n");
        return -1;
@@ -604,12 +566,11 @@ nfulnl_log_packet(unsigned int pf,
 #endif
                + nla_total_size(sizeof(u_int32_t))     /* mark */
                + nla_total_size(sizeof(u_int32_t))     /* uid */
+               + nla_total_size(sizeof(u_int32_t))     /* gid */
                + nla_total_size(plen)                  /* prefix */
                + nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
                + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
 
-       UDEBUG("initial size=%u\n", size);
-
        spin_lock_bh(&inst->lock);
 
        if (inst->flags & NFULNL_CFG_F_SEQ)
@@ -636,7 +597,6 @@ nfulnl_log_packet(unsigned int pf,
                        data_len = inst->copy_range;
 
                size += nla_total_size(data_len);
-               UDEBUG("copy_packet, therefore size now %u\n", size);
                break;
 
        default:
@@ -647,8 +607,6 @@ nfulnl_log_packet(unsigned int pf,
            size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
                /* either the queue len is too high or we don't have
                 * enough room in the skb left. flush to userspace. */
-               UDEBUG("flushing old skb\n");
-
                __nfulnl_flush(inst);
        }
 
@@ -658,7 +616,6 @@ nfulnl_log_packet(unsigned int pf,
                        goto alloc_failure;
        }
 
-       UDEBUG("qlen %d, qthreshold %d\n", inst->qlen, qthreshold);
        inst->qlen++;
 
        __build_packet_message(inst, skb, data_len, pf,
@@ -680,7 +637,6 @@ unlock_and_release:
        return;
 
 alloc_failure:
-       UDEBUG("error allocating skb\n");
        /* FIXME: statistics */
        goto unlock_and_release;
 }
@@ -703,7 +659,6 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
                        struct hlist_head *head = &instance_table[i];
 
                        hlist_for_each_entry_safe(inst, tmp, t2, head, hlist) {
-                               UDEBUG("node = %p\n", inst);
                                if ((n->net == &init_net) &&
                                    (n->pid == inst->peer_pid))
                                        __instance_destroy(inst);
@@ -725,7 +680,7 @@ nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
        return -ENOTSUPP;
 }
 
-static struct nf_logger nfulnl_logger = {
+static const struct nf_logger nfulnl_logger = {
        .name   = "nfnetlink_log",
        .logfn  = &nfulnl_log_packet,
        .me     = THIS_MODULE,
@@ -749,14 +704,17 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
        struct nfulnl_instance *inst;
        int ret = 0;
 
-       UDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type));
-
        inst = instance_lookup_get(group_num);
+       if (inst && inst->peer_pid != NETLINK_CB(skb).pid) {
+               ret = -EPERM;
+               goto out_put;
+       }
+
        if (nfula[NFULA_CFG_CMD]) {
                u_int8_t pf = nfmsg->nfgen_family;
                struct nfulnl_msg_config_cmd *cmd;
+
                cmd = nla_data(nfula[NFULA_CFG_CMD]);
-               UDEBUG("found CFG_CMD for\n");
 
                switch (cmd->command) {
                case NFULNL_CFG_CMD_BIND:
@@ -767,8 +725,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
                        inst = instance_create(group_num,
                                               NETLINK_CB(skb).pid);
-                       if (!inst) {
-                               ret = -EINVAL;
+                       if (IS_ERR(inst)) {
+                               ret = PTR_ERR(inst);
                                goto out;
                        }
                        break;
@@ -778,78 +736,71 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                                goto out;
                        }
 
-                       if (inst->peer_pid != NETLINK_CB(skb).pid) {
-                               ret = -EPERM;
-                               goto out_put;
-                       }
-
                        instance_destroy(inst);
                        goto out;
                case NFULNL_CFG_CMD_PF_BIND:
-                       UDEBUG("registering log handler for pf=%u\n", pf);
                        ret = nf_log_register(pf, &nfulnl_logger);
                        break;
                case NFULNL_CFG_CMD_PF_UNBIND:
-                       UDEBUG("unregistering log handler for pf=%u\n", pf);
                        /* This is a bug and a feature.  We cannot unregister
                         * other handlers, like nfnetlink_inst can */
                        nf_log_unregister_pf(pf);
                        break;
                default:
-                       ret = -EINVAL;
+                       ret = -ENOTSUPP;
                        break;
                }
-
-               if (!inst)
-                       goto out;
-       } else {
-               if (!inst) {
-                       UDEBUG("no config command, and no instance for "
-                               "group=%u pid=%u =>ENOENT\n",
-                               group_num, NETLINK_CB(skb).pid);
-                       ret = -ENOENT;
-                       goto out;
-               }
-
-               if (inst->peer_pid != NETLINK_CB(skb).pid) {
-                       UDEBUG("no config command, and wrong pid\n");
-                       ret = -EPERM;
-                       goto out_put;
-               }
        }
 
        if (nfula[NFULA_CFG_MODE]) {
                struct nfulnl_msg_config_mode *params;
                params = nla_data(nfula[NFULA_CFG_MODE]);
 
+               if (!inst) {
+                       ret = -ENODEV;
+                       goto out;
+               }
                nfulnl_set_mode(inst, params->copy_mode,
                                ntohl(params->copy_range));
        }
 
        if (nfula[NFULA_CFG_TIMEOUT]) {
-               __be32 timeout =
-                       *(__be32 *)nla_data(nfula[NFULA_CFG_TIMEOUT]);
+               __be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]);
 
+               if (!inst) {
+                       ret = -ENODEV;
+                       goto out;
+               }
                nfulnl_set_timeout(inst, ntohl(timeout));
        }
 
        if (nfula[NFULA_CFG_NLBUFSIZ]) {
-               __be32 nlbufsiz =
-                       *(__be32 *)nla_data(nfula[NFULA_CFG_NLBUFSIZ]);
+               __be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]);
 
+               if (!inst) {
+                       ret = -ENODEV;
+                       goto out;
+               }
                nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz));
        }
 
        if (nfula[NFULA_CFG_QTHRESH]) {
-               __be32 qthresh =
-                       *(__be32 *)nla_data(nfula[NFULA_CFG_QTHRESH]);
+               __be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]);
 
+               if (!inst) {
+                       ret = -ENODEV;
+                       goto out;
+               }
                nfulnl_set_qthresh(inst, ntohl(qthresh));
        }
 
        if (nfula[NFULA_CFG_FLAGS]) {
-               __be16 flags =
-                       *(__be16 *)nla_data(nfula[NFULA_CFG_FLAGS]);
+               __be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]);
+
+               if (!inst) {
+                       ret = -ENODEV;
+                       goto out;
+               }
                nfulnl_set_flags(inst, ntohs(flags));
        }
 
index 3ceeffcf6f9de65cd5386d0a7e9d73d11cdacdc6..51476f82bb54733af8f997d782284bbeafa1eae2 100644 (file)
@@ -3,6 +3,7 @@
  * userspace via nfetlink.
  *
  * (C) 2005 by Harald Welte <laforge@netfilter.org>
+ * (C) 2007 by Patrick McHardy <kaber@trash.net>
  *
  * Based on the old ipv4-only ip_queue.c:
  * (C) 2000-2002 James Morris <jmorris@intercode.com.au>
@@ -27,6 +28,7 @@
 #include <linux/netfilter/nfnetlink_queue.h>
 #include <linux/list.h>
 #include <net/sock.h>
+#include <net/netfilter/nf_queue.h>
 
 #include <asm/atomic.h>
 
 
 #define NFQNL_QMAX_DEFAULT 1024
 
-#if 0
-#define QDEBUG(x, args ...)    printk(KERN_DEBUG "%s(%d):%s(): " x,       \
-                                       __FILE__, __LINE__, __FUNCTION__,  \
-                                       ## args)
-#else
-#define QDEBUG(x, ...)
-#endif
-
-struct nfqnl_queue_entry {
-       struct list_head list;
-       struct nf_info *info;
-       struct sk_buff *skb;
-       unsigned int id;
-};
-
 struct nfqnl_instance {
        struct hlist_node hlist;                /* global list of queues */
-       atomic_t use;
+       struct rcu_head rcu;
 
        int peer_pid;
        unsigned int queue_maxlen;
@@ -62,7 +49,7 @@ struct nfqnl_instance {
        unsigned int queue_dropped;
        unsigned int queue_user_dropped;
 
-       atomic_t id_sequence;                   /* 'sequence' of pkt ids */
+       unsigned int id_sequence;               /* 'sequence' of pkt ids */
 
        u_int16_t queue_num;                    /* number of this queue */
        u_int8_t copy_mode;
@@ -72,12 +59,12 @@ struct nfqnl_instance {
        struct list_head queue_list;            /* packets in queue */
 };
 
-typedef int (*nfqnl_cmpfn)(struct nfqnl_queue_entry *, unsigned long);
+typedef int (*nfqnl_cmpfn)(struct nf_queue_entry *, unsigned long);
 
-static DEFINE_RWLOCK(instances_lock);
+static DEFINE_SPINLOCK(instances_lock);
 
 #define INSTANCE_BUCKETS       16
-static struct hlist_head instance_table[INSTANCE_BUCKETS];
+static struct hlist_head instance_table[INSTANCE_BUCKETS] __read_mostly;
 
 static inline u_int8_t instance_hashfn(u_int16_t queue_num)
 {
@@ -85,258 +72,146 @@ static inline u_int8_t instance_hashfn(u_int16_t queue_num)
 }
 
 static struct nfqnl_instance *
-__instance_lookup(u_int16_t queue_num)
+instance_lookup(u_int16_t queue_num)
 {
        struct hlist_head *head;
        struct hlist_node *pos;
        struct nfqnl_instance *inst;
 
        head = &instance_table[instance_hashfn(queue_num)];
-       hlist_for_each_entry(inst, pos, head, hlist) {
+       hlist_for_each_entry_rcu(inst, pos, head, hlist) {
                if (inst->queue_num == queue_num)
                        return inst;
        }
        return NULL;
 }
 
-static struct nfqnl_instance *
-instance_lookup_get(u_int16_t queue_num)
-{
-       struct nfqnl_instance *inst;
-
-       read_lock_bh(&instances_lock);
-       inst = __instance_lookup(queue_num);
-       if (inst)
-               atomic_inc(&inst->use);
-       read_unlock_bh(&instances_lock);
-
-       return inst;
-}
-
-static void
-instance_put(struct nfqnl_instance *inst)
-{
-       if (inst && atomic_dec_and_test(&inst->use)) {
-               QDEBUG("kfree(inst=%p)\n", inst);
-               kfree(inst);
-       }
-}
-
 static struct nfqnl_instance *
 instance_create(u_int16_t queue_num, int pid)
 {
        struct nfqnl_instance *inst;
+       unsigned int h;
+       int err;
 
-       QDEBUG("entering for queue_num=%u, pid=%d\n", queue_num, pid);
-
-       write_lock_bh(&instances_lock);
-       if (__instance_lookup(queue_num)) {
-               inst = NULL;
-               QDEBUG("aborting, instance already exists\n");
+       spin_lock(&instances_lock);
+       if (instance_lookup(queue_num)) {
+               err = -EEXIST;
                goto out_unlock;
        }
 
        inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
-       if (!inst)
+       if (!inst) {
+               err = -ENOMEM;
                goto out_unlock;
+       }
 
        inst->queue_num = queue_num;
        inst->peer_pid = pid;
        inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
        inst->copy_range = 0xfffff;
        inst->copy_mode = NFQNL_COPY_NONE;
-       atomic_set(&inst->id_sequence, 0);
-       /* needs to be two, since we _put() after creation */
-       atomic_set(&inst->use, 2);
        spin_lock_init(&inst->lock);
        INIT_LIST_HEAD(&inst->queue_list);
+       INIT_RCU_HEAD(&inst->rcu);
 
-       if (!try_module_get(THIS_MODULE))
+       if (!try_module_get(THIS_MODULE)) {
+               err = -EAGAIN;
                goto out_free;
+       }
 
-       hlist_add_head(&inst->hlist,
-                      &instance_table[instance_hashfn(queue_num)]);
-
-       write_unlock_bh(&instances_lock);
+       h = instance_hashfn(queue_num);
+       hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
 
-       QDEBUG("successfully created new instance\n");
+       spin_unlock(&instances_lock);
 
        return inst;
 
 out_free:
        kfree(inst);
 out_unlock:
-       write_unlock_bh(&instances_lock);
-       return NULL;
+       spin_unlock(&instances_lock);
+       return ERR_PTR(err);
 }
 
-static void nfqnl_flush(struct nfqnl_instance *queue, int verdict);
+static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
+                       unsigned long data);
 
 static void
-_instance_destroy2(struct nfqnl_instance *inst, int lock)
+instance_destroy_rcu(struct rcu_head *head)
 {
-       /* first pull it out of the global list */
-       if (lock)
-               write_lock_bh(&instances_lock);
-
-       QDEBUG("removing instance %p (queuenum=%u) from hash\n",
-               inst, inst->queue_num);
-       hlist_del(&inst->hlist);
-
-       if (lock)
-               write_unlock_bh(&instances_lock);
-
-       /* then flush all pending skbs from the queue */
-       nfqnl_flush(inst, NF_DROP);
-
-       /* and finally put the refcount */
-       instance_put(inst);
+       struct nfqnl_instance *inst = container_of(head, struct nfqnl_instance,
+                                                  rcu);
 
+       nfqnl_flush(inst, NULL, 0);
+       kfree(inst);
        module_put(THIS_MODULE);
 }
 
-static inline void
+static void
 __instance_destroy(struct nfqnl_instance *inst)
 {
-       _instance_destroy2(inst, 0);
+       hlist_del_rcu(&inst->hlist);
+       call_rcu(&inst->rcu, instance_destroy_rcu);
 }
 
-static inline void
-instance_destroy(struct nfqnl_instance *inst)
-{
-       _instance_destroy2(inst, 1);
-}
-
-
-
 static void
-issue_verdict(struct nfqnl_queue_entry *entry, int verdict)
+instance_destroy(struct nfqnl_instance *inst)
 {
-       QDEBUG("entering for entry %p, verdict %u\n", entry, verdict);
-
-       /* TCP input path (and probably other bits) assume to be called
-        * from softirq context, not from syscall, like issue_verdict is
-        * called.  TCP input path deadlocks with locks taken from timer
-        * softirq, e.g.  We therefore emulate this by local_bh_disable() */
-
-       local_bh_disable();
-       nf_reinject(entry->skb, entry->info, verdict);
-       local_bh_enable();
-
-       kfree(entry);
+       spin_lock(&instances_lock);
+       __instance_destroy(inst);
+       spin_unlock(&instances_lock);
 }
 
 static inline void
-__enqueue_entry(struct nfqnl_instance *queue,
-                     struct nfqnl_queue_entry *entry)
+__enqueue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry)
 {
-       list_add(&entry->list, &queue->queue_list);
+       list_add_tail(&entry->list, &queue->queue_list);
        queue->queue_total++;
 }
 
-/*
- * Find and return a queued entry matched by cmpfn, or return the last
- * entry if cmpfn is NULL.
- */
-static inline struct nfqnl_queue_entry *
-__find_entry(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
-                  unsigned long data)
+static struct nf_queue_entry *
+find_dequeue_entry(struct nfqnl_instance *queue, unsigned int id)
 {
-       struct list_head *p;
+       struct nf_queue_entry *entry = NULL, *i;
 
-       list_for_each_prev(p, &queue->queue_list) {
-               struct nfqnl_queue_entry *entry = (struct nfqnl_queue_entry *)p;
+       spin_lock_bh(&queue->lock);
 
-               if (!cmpfn || cmpfn(entry, data))
-                       return entry;
+       list_for_each_entry(i, &queue->queue_list, list) {
+               if (i->id == id) {
+                       entry = i;
+                       break;
+               }
        }
-       return NULL;
-}
-
-static inline void
-__dequeue_entry(struct nfqnl_instance *q, struct nfqnl_queue_entry *entry)
-{
-       list_del(&entry->list);
-       q->queue_total--;
-}
-
-static inline struct nfqnl_queue_entry *
-__find_dequeue_entry(struct nfqnl_instance *queue,
-                    nfqnl_cmpfn cmpfn, unsigned long data)
-{
-       struct nfqnl_queue_entry *entry;
-
-       entry = __find_entry(queue, cmpfn, data);
-       if (entry == NULL)
-               return NULL;
-
-       __dequeue_entry(queue, entry);
-       return entry;
-}
-
-
-static inline void
-__nfqnl_flush(struct nfqnl_instance *queue, int verdict)
-{
-       struct nfqnl_queue_entry *entry;
-
-       while ((entry = __find_dequeue_entry(queue, NULL, 0)))
-               issue_verdict(entry, verdict);
-}
-
-static inline int
-__nfqnl_set_mode(struct nfqnl_instance *queue,
-                unsigned char mode, unsigned int range)
-{
-       int status = 0;
-
-       switch (mode) {
-       case NFQNL_COPY_NONE:
-       case NFQNL_COPY_META:
-               queue->copy_mode = mode;
-               queue->copy_range = 0;
-               break;
-
-       case NFQNL_COPY_PACKET:
-               queue->copy_mode = mode;
-               /* we're using struct nlattr which has 16bit nla_len */
-               if (range > 0xffff)
-                       queue->copy_range = 0xffff;
-               else
-                       queue->copy_range = range;
-               break;
-
-       default:
-               status = -EINVAL;
 
+       if (entry) {
+               list_del(&entry->list);
+               queue->queue_total--;
        }
-       return status;
-}
 
-static struct nfqnl_queue_entry *
-find_dequeue_entry(struct nfqnl_instance *queue,
-                        nfqnl_cmpfn cmpfn, unsigned long data)
-{
-       struct nfqnl_queue_entry *entry;
-
-       spin_lock_bh(&queue->lock);
-       entry = __find_dequeue_entry(queue, cmpfn, data);
        spin_unlock_bh(&queue->lock);
 
        return entry;
 }
 
 static void
-nfqnl_flush(struct nfqnl_instance *queue, int verdict)
+nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
 {
+       struct nf_queue_entry *entry, *next;
+
        spin_lock_bh(&queue->lock);
-       __nfqnl_flush(queue, verdict);
+       list_for_each_entry_safe(entry, next, &queue->queue_list, list) {
+               if (!cmpfn || cmpfn(entry, data)) {
+                       list_del(&entry->list);
+                       queue->queue_total--;
+                       nf_reinject(entry, NF_DROP);
+               }
+       }
        spin_unlock_bh(&queue->lock);
 }
 
 static struct sk_buff *
 nfqnl_build_packet_message(struct nfqnl_instance *queue,
-                          struct nfqnl_queue_entry *entry, int *errp)
+                          struct nf_queue_entry *entry)
 {
        sk_buff_data_t old_tail;
        size_t size;
@@ -345,13 +220,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
        struct nfqnl_msg_packet_hdr pmsg;
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       struct nf_info *entinf = entry->info;
        struct sk_buff *entskb = entry->skb;
        struct net_device *indev;
        struct net_device *outdev;
-       __be32 tmp_uint;
-
-       QDEBUG("entered\n");
 
        size =    NLMSG_ALIGN(sizeof(struct nfgenmsg))
                + nla_total_size(sizeof(struct nfqnl_msg_packet_hdr))
@@ -365,11 +236,11 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                + nla_total_size(sizeof(struct nfqnl_msg_packet_hw))
                + nla_total_size(sizeof(struct nfqnl_msg_packet_timestamp));
 
-       outdev = entinf->outdev;
+       outdev = entry->outdev;
 
        spin_lock_bh(&queue->lock);
 
-       switch (queue->copy_mode) {
+       switch ((enum nfqnl_config_mode)queue->copy_mode) {
        case NFQNL_COPY_META:
        case NFQNL_COPY_NONE:
                data_len = 0;
@@ -378,7 +249,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
        case NFQNL_COPY_PACKET:
                if ((entskb->ip_summed == CHECKSUM_PARTIAL ||
                     entskb->ip_summed == CHECKSUM_COMPLETE) &&
-                   (*errp = skb_checksum_help(entskb))) {
+                   skb_checksum_help(entskb)) {
                        spin_unlock_bh(&queue->lock);
                        return NULL;
                }
@@ -390,13 +261,10 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
 
                size += nla_total_size(data_len);
                break;
-
-       default:
-               *errp = -EINVAL;
-               spin_unlock_bh(&queue->lock);
-               return NULL;
        }
 
+       entry->id = queue->id_sequence++;
+
        spin_unlock_bh(&queue->lock);
 
        skb = alloc_skb(size, GFP_ATOMIC);
@@ -408,81 +276,69 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                        NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
                        sizeof(struct nfgenmsg));
        nfmsg = NLMSG_DATA(nlh);
-       nfmsg->nfgen_family = entinf->pf;
+       nfmsg->nfgen_family = entry->pf;
        nfmsg->version = NFNETLINK_V0;
        nfmsg->res_id = htons(queue->queue_num);
 
        pmsg.packet_id          = htonl(entry->id);
        pmsg.hw_protocol        = entskb->protocol;
-       pmsg.hook               = entinf->hook;
+       pmsg.hook               = entry->hook;
 
        NLA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg);
 
-       indev = entinf->indev;
+       indev = entry->indev;
        if (indev) {
-               tmp_uint = htonl(indev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
-               NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
+               NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex));
 #else
-               if (entinf->pf == PF_BRIDGE) {
+               if (entry->pf == PF_BRIDGE) {
                        /* Case 1: indev is physical input device, we need to
                         * look for bridge group (when called from
                         * netfilter_bridge) */
-                       NLA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint),
-                               &tmp_uint);
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
+                                    htonl(indev->ifindex));
                        /* this is the bridge group "brX" */
-                       tmp_uint = htonl(indev->br_port->br->dev->ifindex);
-                       NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
-                               &tmp_uint);
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
+                                    htonl(indev->br_port->br->dev->ifindex));
                } else {
                        /* Case 2: indev is bridge group, we need to look for
                         * physical device (when called from ipv4) */
-                       NLA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
-                               &tmp_uint);
-                       if (entskb->nf_bridge
-                           && entskb->nf_bridge->physindev) {
-                               tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex);
-                               NLA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
-                                       sizeof(tmp_uint), &tmp_uint);
-                       }
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
+                                    htonl(indev->ifindex));
+                       if (entskb->nf_bridge && entskb->nf_bridge->physindev)
+                               NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
+                                            htonl(entskb->nf_bridge->physindev->ifindex));
                }
 #endif
        }
 
        if (outdev) {
-               tmp_uint = htonl(outdev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
-               NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
+               NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex));
 #else
-               if (entinf->pf == PF_BRIDGE) {
+               if (entry->pf == PF_BRIDGE) {
                        /* Case 1: outdev is physical output device, we need to
                         * look for bridge group (when called from
                         * netfilter_bridge) */
-                       NLA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
-                               &tmp_uint);
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+                                    htonl(outdev->ifindex));
                        /* this is the bridge group "brX" */
-                       tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
-                       NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
-                               &tmp_uint);
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
+                                    htonl(outdev->br_port->br->dev->ifindex));
                } else {
                        /* Case 2: outdev is bridge group, we need to look for
                         * physical output device (when called from ipv4) */
-                       NLA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
-                               &tmp_uint);
-                       if (entskb->nf_bridge
-                           && entskb->nf_bridge->physoutdev) {
-                               tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex);
-                               NLA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
-                                       sizeof(tmp_uint), &tmp_uint);
-                       }
+                       NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
+                                    htonl(outdev->ifindex));
+                       if (entskb->nf_bridge && entskb->nf_bridge->physoutdev)
+                               NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
+                                            htonl(entskb->nf_bridge->physoutdev->ifindex));
                }
 #endif
        }
 
-       if (entskb->mark) {
-               tmp_uint = htonl(entskb->mark);
-               NLA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint);
-       }
+       if (entskb->mark)
+               NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
 
        if (indev && entskb->dev) {
                struct nfqnl_msg_packet_hw phw;
@@ -526,51 +382,29 @@ nlmsg_failure:
 nla_put_failure:
        if (skb)
                kfree_skb(skb);
-       *errp = -EINVAL;
        if (net_ratelimit())
                printk(KERN_ERR "nf_queue: error creating packet message\n");
        return NULL;
 }
 
 static int
-nfqnl_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
-                    unsigned int queuenum, void *data)
+nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
 {
-       int status = -EINVAL;
        struct sk_buff *nskb;
        struct nfqnl_instance *queue;
-       struct nfqnl_queue_entry *entry;
-
-       QDEBUG("entered\n");
-
-       queue = instance_lookup_get(queuenum);
-       if (!queue) {
-               QDEBUG("no queue instance matching\n");
-               return -EINVAL;
-       }
-
-       if (queue->copy_mode == NFQNL_COPY_NONE) {
-               QDEBUG("mode COPY_NONE, aborting\n");
-               status = -EAGAIN;
-               goto err_out_put;
-       }
+       int err;
 
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       if (entry == NULL) {
-               if (net_ratelimit())
-                       printk(KERN_ERR
-                               "nf_queue: OOM in nfqnl_enqueue_packet()\n");
-               status = -ENOMEM;
-               goto err_out_put;
-       }
+       /* rcu_read_lock()ed by nf_hook_slow() */
+       queue = instance_lookup(queuenum);
+       if (!queue)
+               goto err_out;
 
-       entry->info = info;
-       entry->skb = skb;
-       entry->id = atomic_inc_return(&queue->id_sequence);
+       if (queue->copy_mode == NFQNL_COPY_NONE)
+               goto err_out;
 
-       nskb = nfqnl_build_packet_message(queue, entry, &status);
+       nskb = nfqnl_build_packet_message(queue, entry);
        if (nskb == NULL)
-               goto err_out_free;
+               goto err_out;
 
        spin_lock_bh(&queue->lock);
 
@@ -579,7 +413,6 @@ nfqnl_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
 
        if (queue->queue_total >= queue->queue_maxlen) {
                queue->queue_dropped++;
-               status = -ENOSPC;
                if (net_ratelimit())
                          printk(KERN_WARNING "nf_queue: full at %d entries, "
                                 "dropping packets(s). Dropped: %d\n",
@@ -588,8 +421,8 @@ nfqnl_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
        }
 
        /* nfnetlink_unicast will either free the nskb or add it to a socket */
-       status = nfnetlink_unicast(nskb, queue->peer_pid, MSG_DONTWAIT);
-       if (status < 0) {
+       err = nfnetlink_unicast(nskb, queue->peer_pid, MSG_DONTWAIT);
+       if (err < 0) {
                queue->queue_user_dropped++;
                goto err_out_unlock;
        }
@@ -597,24 +430,18 @@ nfqnl_enqueue_packet(struct sk_buff *skb, struct nf_info *info,
        __enqueue_entry(queue, entry);
 
        spin_unlock_bh(&queue->lock);
-       instance_put(queue);
-       return status;
+       return 0;
 
 err_out_free_nskb:
        kfree_skb(nskb);
-
 err_out_unlock:
        spin_unlock_bh(&queue->lock);
-
-err_out_free:
-       kfree(entry);
-err_out_put:
-       instance_put(queue);
-       return status;
+err_out:
+       return -1;
 }
 
 static int
-nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
+nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
 {
        int diff;
        int err;
@@ -645,35 +472,46 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
        return 0;
 }
 
-static inline int
-id_cmp(struct nfqnl_queue_entry *e, unsigned long id)
-{
-       return (id == e->id);
-}
-
 static int
 nfqnl_set_mode(struct nfqnl_instance *queue,
               unsigned char mode, unsigned int range)
 {
-       int status;
+       int status = 0;
 
        spin_lock_bh(&queue->lock);
-       status = __nfqnl_set_mode(queue, mode, range);
+       switch (mode) {
+       case NFQNL_COPY_NONE:
+       case NFQNL_COPY_META:
+               queue->copy_mode = mode;
+               queue->copy_range = 0;
+               break;
+
+       case NFQNL_COPY_PACKET:
+               queue->copy_mode = mode;
+               /* we're using struct nlattr which has 16bit nla_len */
+               if (range > 0xffff)
+                       queue->copy_range = 0xffff;
+               else
+                       queue->copy_range = range;
+               break;
+
+       default:
+               status = -EINVAL;
+
+       }
        spin_unlock_bh(&queue->lock);
 
        return status;
 }
 
 static int
-dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex)
+dev_cmp(struct nf_queue_entry *entry, unsigned long ifindex)
 {
-       struct nf_info *entinf = entry->info;
-
-       if (entinf->indev)
-               if (entinf->indev->ifindex == ifindex)
+       if (entry->indev)
+               if (entry->indev->ifindex == ifindex)
                        return 1;
-       if (entinf->outdev)
-               if (entinf->outdev->ifindex == ifindex)
+       if (entry->outdev)
+               if (entry->outdev->ifindex == ifindex)
                        return 1;
 #ifdef CONFIG_BRIDGE_NETFILTER
        if (entry->skb->nf_bridge) {
@@ -695,27 +533,18 @@ nfqnl_dev_drop(int ifindex)
 {
        int i;
 
-       QDEBUG("entering for ifindex %u\n", ifindex);
-
-       /* this only looks like we have to hold the readlock for a way too long
-        * time, issue_verdict(),  nf_reinject(), ... - but we always only
-        * issue NF_DROP, which is processed directly in nf_reinject() */
-       read_lock_bh(&instances_lock);
+       rcu_read_lock();
 
-       for  (i = 0; i < INSTANCE_BUCKETS; i++) {
+       for (i = 0; i < INSTANCE_BUCKETS; i++) {
                struct hlist_node *tmp;
                struct nfqnl_instance *inst;
                struct hlist_head *head = &instance_table[i];
 
-               hlist_for_each_entry(inst, tmp, head, hlist) {
-                       struct nfqnl_queue_entry *entry;
-                       while ((entry = find_dequeue_entry(inst, dev_cmp,
-                                                          ifindex)) != NULL)
-                               issue_verdict(entry, NF_DROP);
-               }
+               hlist_for_each_entry_rcu(inst, tmp, head, hlist)
+                       nfqnl_flush(inst, dev_cmp, ifindex);
        }
 
-       read_unlock_bh(&instances_lock);
+       rcu_read_unlock();
 }
 
 #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
@@ -750,8 +579,8 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
                int i;
 
                /* destroy all instances for this pid */
-               write_lock_bh(&instances_lock);
-               for  (i = 0; i < INSTANCE_BUCKETS; i++) {
+               spin_lock(&instances_lock);
+               for (i = 0; i < INSTANCE_BUCKETS; i++) {
                        struct hlist_node *tmp, *t2;
                        struct nfqnl_instance *inst;
                        struct hlist_head *head = &instance_table[i];
@@ -762,7 +591,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
                                        __instance_destroy(inst);
                        }
                }
-               write_unlock_bh(&instances_lock);
+               spin_unlock(&instances_lock);
        }
        return NOTIFY_DONE;
 }
@@ -787,21 +616,24 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        struct nfqnl_msg_verdict_hdr *vhdr;
        struct nfqnl_instance *queue;
        unsigned int verdict;
-       struct nfqnl_queue_entry *entry;
+       struct nf_queue_entry *entry;
        int err;
 
-       queue = instance_lookup_get(queue_num);
-       if (!queue)
-               return -ENODEV;
+       rcu_read_lock();
+       queue = instance_lookup(queue_num);
+       if (!queue) {
+               err = -ENODEV;
+               goto err_out_unlock;
+       }
 
        if (queue->peer_pid != NETLINK_CB(skb).pid) {
                err = -EPERM;
-               goto err_out_put;
+               goto err_out_unlock;
        }
 
        if (!nfqa[NFQA_VERDICT_HDR]) {
                err = -EINVAL;
-               goto err_out_put;
+               goto err_out_unlock;
        }
 
        vhdr = nla_data(nfqa[NFQA_VERDICT_HDR]);
@@ -809,14 +641,15 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
 
        if ((verdict & NF_VERDICT_MASK) > NF_MAX_VERDICT) {
                err = -EINVAL;
-               goto err_out_put;
+               goto err_out_unlock;
        }
 
-       entry = find_dequeue_entry(queue, id_cmp, ntohl(vhdr->id));
+       entry = find_dequeue_entry(queue, ntohl(vhdr->id));
        if (entry == NULL) {
                err = -ENOENT;
-               goto err_out_put;
+               goto err_out_unlock;
        }
+       rcu_read_unlock();
 
        if (nfqa[NFQA_PAYLOAD]) {
                if (nfqnl_mangle(nla_data(nfqa[NFQA_PAYLOAD]),
@@ -825,15 +658,13 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
        }
 
        if (nfqa[NFQA_MARK])
-               entry->skb->mark = ntohl(*(__be32 *)
-                                        nla_data(nfqa[NFQA_MARK]));
+               entry->skb->mark = ntohl(nla_get_be32(nfqa[NFQA_MARK]));
 
-       issue_verdict(entry, verdict);
-       instance_put(queue);
+       nf_reinject(entry, verdict);
        return 0;
 
-err_out_put:
-       instance_put(queue);
+err_out_unlock:
+       rcu_read_unlock();
        return err;
 }
 
@@ -849,7 +680,7 @@ static const struct nla_policy nfqa_cfg_policy[NFQA_CFG_MAX+1] = {
        [NFQA_CFG_PARAMS]       = { .len = sizeof(struct nfqnl_msg_config_params) },
 };
 
-static struct nf_queue_handler nfqh = {
+static const struct nf_queue_handler nfqh = {
        .name   = "nf_queue",
        .outfn  = &nfqnl_enqueue_packet,
 };
@@ -861,70 +692,72 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
        struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
        u_int16_t queue_num = ntohs(nfmsg->res_id);
        struct nfqnl_instance *queue;
+       struct nfqnl_msg_config_cmd *cmd = NULL;
        int ret = 0;
 
-       QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type));
-
-       queue = instance_lookup_get(queue_num);
        if (nfqa[NFQA_CFG_CMD]) {
-               struct nfqnl_msg_config_cmd *cmd;
                cmd = nla_data(nfqa[NFQA_CFG_CMD]);
-               QDEBUG("found CFG_CMD\n");
 
+               /* Commands without queue context - might sleep */
                switch (cmd->command) {
-               case NFQNL_CFG_CMD_BIND:
-                       if (queue)
-                               return -EBUSY;
+               case NFQNL_CFG_CMD_PF_BIND:
+                       ret = nf_register_queue_handler(ntohs(cmd->pf),
+                                                       &nfqh);
+                       break;
+               case NFQNL_CFG_CMD_PF_UNBIND:
+                       ret = nf_unregister_queue_handler(ntohs(cmd->pf),
+                                                         &nfqh);
+                       break;
+               default:
+                       break;
+               }
+
+               if (ret < 0)
+                       return ret;
+       }
+
+       rcu_read_lock();
+       queue = instance_lookup(queue_num);
+       if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
+               ret = -EPERM;
+               goto err_out_unlock;
+       }
 
+       if (cmd != NULL) {
+               switch (cmd->command) {
+               case NFQNL_CFG_CMD_BIND:
+                       if (queue) {
+                               ret = -EBUSY;
+                               goto err_out_unlock;
+                       }
                        queue = instance_create(queue_num, NETLINK_CB(skb).pid);
-                       if (!queue)
-                               return -EINVAL;
+                       if (IS_ERR(queue)) {
+                               ret = PTR_ERR(queue);
+                               goto err_out_unlock;
+                       }
                        break;
                case NFQNL_CFG_CMD_UNBIND:
-                       if (!queue)
-                               return -ENODEV;
-
-                       if (queue->peer_pid != NETLINK_CB(skb).pid) {
-                               ret = -EPERM;
-                               goto out_put;
+                       if (!queue) {
+                               ret = -ENODEV;
+                               goto err_out_unlock;
                        }
-
                        instance_destroy(queue);
                        break;
                case NFQNL_CFG_CMD_PF_BIND:
-                       QDEBUG("registering queue handler for pf=%u\n",
-                               ntohs(cmd->pf));
-                       ret = nf_register_queue_handler(ntohs(cmd->pf), &nfqh);
-                       break;
                case NFQNL_CFG_CMD_PF_UNBIND:
-                       QDEBUG("unregistering queue handler for pf=%u\n",
-                               ntohs(cmd->pf));
-                       ret = nf_unregister_queue_handler(ntohs(cmd->pf), &nfqh);
                        break;
                default:
-                       ret = -EINVAL;
+                       ret = -ENOTSUPP;
                        break;
                }
-       } else {
-               if (!queue) {
-                       QDEBUG("no config command, and no instance ENOENT\n");
-                       ret = -ENOENT;
-                       goto out_put;
-               }
-
-               if (queue->peer_pid != NETLINK_CB(skb).pid) {
-                       QDEBUG("no config command, and wrong pid\n");
-                       ret = -EPERM;
-                       goto out_put;
-               }
        }
 
        if (nfqa[NFQA_CFG_PARAMS]) {
                struct nfqnl_msg_config_params *params;
 
                if (!queue) {
-                       ret = -ENOENT;
-                       goto out_put;
+                       ret = -ENODEV;
+                       goto err_out_unlock;
                }
                params = nla_data(nfqa[NFQA_CFG_PARAMS]);
                nfqnl_set_mode(queue, params->copy_mode,
@@ -933,14 +766,19 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
        if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) {
                __be32 *queue_maxlen;
+
+               if (!queue) {
+                       ret = -ENODEV;
+                       goto err_out_unlock;
+               }
                queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]);
                spin_lock_bh(&queue->lock);
                queue->queue_maxlen = ntohl(*queue_maxlen);
                spin_unlock_bh(&queue->lock);
        }
 
-out_put:
-       instance_put(queue);
+err_out_unlock:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1008,7 +846,7 @@ static struct hlist_node *get_idx(struct seq_file *seq, loff_t pos)
 
 static void *seq_start(struct seq_file *seq, loff_t *pos)
 {
-       read_lock_bh(&instances_lock);
+       spin_lock(&instances_lock);
        return get_idx(seq, *pos);
 }
 
@@ -1020,7 +858,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 
 static void seq_stop(struct seq_file *s, void *v)
 {
-       read_unlock_bh(&instances_lock);
+       spin_unlock(&instances_lock);
 }
 
 static int seq_show(struct seq_file *s, void *v)
@@ -1032,8 +870,7 @@ static int seq_show(struct seq_file *s, void *v)
                          inst->peer_pid, inst->queue_total,
                          inst->copy_mode, inst->copy_range,
                          inst->queue_dropped, inst->queue_user_dropped,
-                         atomic_read(&inst->id_sequence),
-                         atomic_read(&inst->use));
+                         inst->id_sequence, 1);
 }
 
 static const struct seq_operations nfqnl_seq_ops = {
index b6160e41eb1ca978e070631b0fc631dbe6d409d5..8d4fca96a4a719a054ee3ac0cb02643dc90113ba 100644 (file)
@@ -34,12 +34,21 @@ MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module");
 
 #define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
 
+struct compat_delta {
+       struct compat_delta *next;
+       unsigned int offset;
+       short delta;
+};
+
 struct xt_af {
        struct mutex mutex;
        struct list_head match;
        struct list_head target;
        struct list_head tables;
+#ifdef CONFIG_COMPAT
        struct mutex compat_mutex;
+       struct compat_delta *compat_offsets;
+#endif
 };
 
 static struct xt_af *xt;
@@ -335,6 +344,54 @@ int xt_check_match(const struct xt_match *match, unsigned short family,
 EXPORT_SYMBOL_GPL(xt_check_match);
 
 #ifdef CONFIG_COMPAT
+int xt_compat_add_offset(int af, unsigned int offset, short delta)
+{
+       struct compat_delta *tmp;
+
+       tmp = kmalloc(sizeof(struct compat_delta), GFP_KERNEL);
+       if (!tmp)
+               return -ENOMEM;
+
+       tmp->offset = offset;
+       tmp->delta = delta;
+
+       if (xt[af].compat_offsets) {
+               tmp->next = xt[af].compat_offsets->next;
+               xt[af].compat_offsets->next = tmp;
+       } else {
+               xt[af].compat_offsets = tmp;
+               tmp->next = NULL;
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(xt_compat_add_offset);
+
+void xt_compat_flush_offsets(int af)
+{
+       struct compat_delta *tmp, *next;
+
+       if (xt[af].compat_offsets) {
+               for (tmp = xt[af].compat_offsets; tmp; tmp = next) {
+                       next = tmp->next;
+                       kfree(tmp);
+               }
+               xt[af].compat_offsets = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(xt_compat_flush_offsets);
+
+short xt_compat_calc_jump(int af, unsigned int offset)
+{
+       struct compat_delta *tmp;
+       short delta;
+
+       for (tmp = xt[af].compat_offsets, delta = 0; tmp; tmp = tmp->next)
+               if (tmp->offset < offset)
+                       delta += tmp->delta;
+       return delta;
+}
+EXPORT_SYMBOL_GPL(xt_compat_calc_jump);
+
 int xt_compat_match_offset(struct xt_match *match)
 {
        u_int16_t csize = match->compatsize ? : match->matchsize;
@@ -342,8 +399,8 @@ int xt_compat_match_offset(struct xt_match *match)
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_offset);
 
-void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
-                              int *size)
+int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+                             int *size)
 {
        struct xt_match *match = m->u.kernel.match;
        struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
@@ -365,6 +422,7 @@ void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
 
        *size += off;
        *dstptr += msize;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
 
@@ -499,7 +557,7 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
        if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages)
                return NULL;
 
-       newinfo = kzalloc(sizeof(struct xt_table_info), GFP_KERNEL);
+       newinfo = kzalloc(XT_TABLE_INFO_SZ, GFP_KERNEL);
        if (!newinfo)
                return NULL;
 
@@ -872,6 +930,7 @@ static int __init xt_init(void)
                mutex_init(&xt[i].mutex);
 #ifdef CONFIG_COMPAT
                mutex_init(&xt[i].compat_mutex);
+               xt[i].compat_offsets = NULL;
 #endif
                INIT_LIST_HEAD(&xt[i].target);
                INIT_LIST_HEAD(&xt[i].match);
index 77eeae658d4295652174632f51891e82655a61f5..77a52bf83225db48f8eaceda0362af0f4cd47dff 100644 (file)
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("iptables qdisc classification target module");
+MODULE_DESCRIPTION("Xtables: Qdisc classification");
 MODULE_ALIAS("ipt_CLASSIFY");
 MODULE_ALIAS("ip6t_CLASSIFY");
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+classify_tg(struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, unsigned int hooknum,
+            const struct xt_target *target, const void *targinfo)
 {
        const struct xt_classify_target_info *clinfo = targinfo;
 
@@ -40,42 +37,41 @@ target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static struct xt_target xt_classify_target[] __read_mostly = {
+static struct xt_target classify_tg_reg[] __read_mostly = {
        {
                .family         = AF_INET,
                .name           = "CLASSIFY",
-               .target         = target,
+               .target         = classify_tg,
                .targetsize     = sizeof(struct xt_classify_target_info),
                .table          = "mangle",
-               .hooks          = (1 << NF_IP_LOCAL_OUT) |
-                                 (1 << NF_IP_FORWARD) |
-                                 (1 << NF_IP_POST_ROUTING),
+               .hooks          = (1 << NF_INET_LOCAL_OUT) |
+                                 (1 << NF_INET_FORWARD) |
+                                 (1 << NF_INET_POST_ROUTING),
                .me             = THIS_MODULE,
        },
        {
                .name           = "CLASSIFY",
                .family         = AF_INET6,
-               .target         = target,
+               .target         = classify_tg,
                .targetsize     = sizeof(struct xt_classify_target_info),
                .table          = "mangle",
-               .hooks          = (1 << NF_IP6_LOCAL_OUT) |
-                                 (1 << NF_IP6_FORWARD) |
-                                 (1 << NF_IP6_POST_ROUTING),
+               .hooks          = (1 << NF_INET_LOCAL_OUT) |
+                                 (1 << NF_INET_FORWARD) |
+                                 (1 << NF_INET_POST_ROUTING),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_classify_init(void)
+static int __init classify_tg_init(void)
 {
-       return xt_register_targets(xt_classify_target,
-                                  ARRAY_SIZE(xt_classify_target));
+       return xt_register_targets(classify_tg_reg,
+              ARRAY_SIZE(classify_tg_reg));
 }
 
-static void __exit xt_classify_fini(void)
+static void __exit classify_tg_exit(void)
 {
-       xt_unregister_targets(xt_classify_target,
-                             ARRAY_SIZE(xt_classify_target));
+       xt_unregister_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg));
 }
 
-module_init(xt_classify_init);
-module_exit(xt_classify_fini);
+module_init(classify_tg_init);
+module_exit(classify_tg_exit);
index 0621ca7de3b0e24b924a108aa124e069d87379ac..5fecfb4794b108c497f4fe9935fee9956965727d 100644 (file)
@@ -1,8 +1,10 @@
-/* This kernel module is used to modify the connection mark values, or
- * to optionally restore the skb nfmark from the connection mark
+/*
+ *     xt_CONNMARK - Netfilter module to modify the connection mark values
  *
- * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- * by Henrik Nordstrom <hno@marasystems.com>
+ *     Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ *     by Henrik Nordstrom <hno@marasystems.com>
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ *     Jan Engelhardt <jengelh@computergmbh.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
@@ -24,7 +26,7 @@
 #include <net/checksum.h>
 
 MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
-MODULE_DESCRIPTION("IP tables CONNMARK matching module");
+MODULE_DESCRIPTION("Xtables: connection mark modification");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_CONNMARK");
 MODULE_ALIAS("ip6t_CONNMARK");
@@ -34,12 +36,9 @@ MODULE_ALIAS("ip6t_CONNMARK");
 #include <net/netfilter/nf_conntrack_ecache.h>
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, unsigned int hooknum,
+               const struct xt_target *target, const void *targinfo)
 {
        const struct xt_connmark_target_info *markinfo = targinfo;
        struct nf_conn *ct;
@@ -77,12 +76,50 @@ target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
+static unsigned int
+connmark_tg(struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, unsigned int hooknum,
+            const struct xt_target *target, const void *targinfo)
+{
+       const struct xt_connmark_tginfo1 *info = targinfo;
+       enum ip_conntrack_info ctinfo;
+       struct nf_conn *ct;
+       u_int32_t newmark;
+
+       ct = nf_ct_get(skb, &ctinfo);
+       if (ct == NULL)
+               return XT_CONTINUE;
+
+       switch (info->mode) {
+       case XT_CONNMARK_SET:
+               newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
+               if (ct->mark != newmark) {
+                       ct->mark = newmark;
+                       nf_conntrack_event_cache(IPCT_MARK, skb);
+               }
+               break;
+       case XT_CONNMARK_SAVE:
+               newmark = (ct->mark & ~info->ctmask) ^
+                         (skb->mark & info->nfmask);
+               if (ct->mark != newmark) {
+                       ct->mark = newmark;
+                       nf_conntrack_event_cache(IPCT_MARK, skb);
+               }
+               break;
+       case XT_CONNMARK_RESTORE:
+               newmark = (skb->mark & ~info->nfmask) ^
+                         (ct->mark & info->ctmask);
+               skb->mark = newmark;
+               break;
+       }
+
+       return XT_CONTINUE;
+}
+
 static bool
-checkentry(const char *tablename,
-          const void *entry,
-          const struct xt_target *target,
-          void *targinfo,
-          unsigned int hook_mask)
+connmark_tg_check_v0(const char *tablename, const void *entry,
+                     const struct xt_target *target, void *targinfo,
+                     unsigned int hook_mask)
 {
        const struct xt_connmark_target_info *matchinfo = targinfo;
 
@@ -100,14 +137,27 @@ checkentry(const char *tablename,
        }
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", target->family);
+                                   "proto=%u\n", target->family);
+               return false;
+       }
+       return true;
+}
+
+static bool
+connmark_tg_check(const char *tablename, const void *entry,
+                  const struct xt_target *target, void *targinfo,
+                  unsigned int hook_mask)
+{
+       if (nf_ct_l3proto_try_module_get(target->family) < 0) {
+               printk(KERN_WARNING "cannot load conntrack support for "
+                      "proto=%u\n", target->family);
                return false;
        }
        return true;
 }
 
 static void
-destroy(const struct xt_target *target, void *targinfo)
+connmark_tg_destroy(const struct xt_target *target, void *targinfo)
 {
        nf_ct_l3proto_module_put(target->family);
 }
@@ -120,7 +170,7 @@ struct compat_xt_connmark_target_info {
        u_int16_t       __pad2;
 };
 
-static void compat_from_user(void *dst, void *src)
+static void connmark_tg_compat_from_user_v0(void *dst, void *src)
 {
        const struct compat_xt_connmark_target_info *cm = src;
        struct xt_connmark_target_info m = {
@@ -131,7 +181,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int connmark_tg_compat_to_user_v0(void __user *dst, void *src)
 {
        const struct xt_connmark_target_info *m = src;
        struct compat_xt_connmark_target_info cm = {
@@ -143,43 +193,69 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_connmark_target[] __read_mostly = {
+static struct xt_target connmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNMARK",
+               .revision       = 0,
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .destroy        = destroy,
-               .target         = target,
+               .checkentry     = connmark_tg_check_v0,
+               .destroy        = connmark_tg_destroy,
+               .target         = connmark_tg_v0,
                .targetsize     = sizeof(struct xt_connmark_target_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_connmark_target_info),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = connmark_tg_compat_from_user_v0,
+               .compat_to_user = connmark_tg_compat_to_user_v0,
 #endif
                .me             = THIS_MODULE
        },
        {
                .name           = "CONNMARK",
+               .revision       = 0,
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .destroy        = destroy,
-               .target         = target,
+               .checkentry     = connmark_tg_check_v0,
+               .destroy        = connmark_tg_destroy,
+               .target         = connmark_tg_v0,
                .targetsize     = sizeof(struct xt_connmark_target_info),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_connmark_target_info),
+               .compat_from_user = connmark_tg_compat_from_user_v0,
+               .compat_to_user = connmark_tg_compat_to_user_v0,
+#endif
                .me             = THIS_MODULE
        },
+       {
+               .name           = "CONNMARK",
+               .revision       = 1,
+               .family         = AF_INET,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg,
+               .targetsize     = sizeof(struct xt_connmark_tginfo1),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "CONNMARK",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .checkentry     = connmark_tg_check,
+               .target         = connmark_tg,
+               .targetsize     = sizeof(struct xt_connmark_tginfo1),
+               .destroy        = connmark_tg_destroy,
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_connmark_init(void)
+static int __init connmark_tg_init(void)
 {
-       return xt_register_targets(xt_connmark_target,
-                                  ARRAY_SIZE(xt_connmark_target));
+       return xt_register_targets(connmark_tg_reg,
+              ARRAY_SIZE(connmark_tg_reg));
 }
 
-static void __exit xt_connmark_fini(void)
+static void __exit connmark_tg_exit(void)
 {
-       xt_unregister_targets(xt_connmark_target,
-                             ARRAY_SIZE(xt_connmark_target));
+       xt_unregister_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg));
 }
 
-module_init(xt_connmark_init);
-module_exit(xt_connmark_fini);
+module_init(connmark_tg_init);
+module_exit(connmark_tg_exit);
index d8feba9bdb489dfba98f3ab4fb742bbc204004ea..1faa9136195dbd7a8fde07dad72a55b6c758788b 100644 (file)
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_CONNSECMARK.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 
 #define PFX "CONNSECMARK: "
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
-MODULE_DESCRIPTION("ip[6]tables CONNSECMARK module");
+MODULE_DESCRIPTION("Xtables: target for copying between connection and security mark");
 MODULE_ALIAS("ipt_CONNSECMARK");
 MODULE_ALIAS("ip6t_CONNSECMARK");
 
@@ -40,8 +41,10 @@ static void secmark_save(const struct sk_buff *skb)
                enum ip_conntrack_info ctinfo;
 
                ct = nf_ct_get(skb, &ctinfo);
-               if (ct && !ct->secmark)
+               if (ct && !ct->secmark) {
                        ct->secmark = skb->secmark;
+                       nf_conntrack_event_cache(IPCT_SECMARK, skb);
+               }
        }
 }
 
@@ -61,10 +64,10 @@ static void secmark_restore(struct sk_buff *skb)
        }
 }
 
-static unsigned int target(struct sk_buff *skb, const struct net_device *in,
-                          const struct net_device *out, unsigned int hooknum,
-                          const struct xt_target *target,
-                          const void *targinfo)
+static unsigned int
+connsecmark_tg(struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, unsigned int hooknum,
+               const struct xt_target *target, const void *targinfo)
 {
        const struct xt_connsecmark_target_info *info = targinfo;
 
@@ -84,9 +87,10 @@ static unsigned int target(struct sk_buff *skb, const struct net_device *in,
        return XT_CONTINUE;
 }
 
-static bool checkentry(const char *tablename, const void *entry,
-                      const struct xt_target *target, void *targinfo,
-                      unsigned int hook_mask)
+static bool
+connsecmark_tg_check(const char *tablename, const void *entry,
+                     const struct xt_target *target, void *targinfo,
+                     unsigned int hook_mask)
 {
        const struct xt_connsecmark_target_info *info = targinfo;
 
@@ -102,25 +106,25 @@ static bool checkentry(const char *tablename, const void *entry,
 
        if (nf_ct_l3proto_try_module_get(target->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", target->family);
+                                   "proto=%u\n", target->family);
                return false;
        }
        return true;
 }
 
 static void
-destroy(const struct xt_target *target, void *targinfo)
+connsecmark_tg_destroy(const struct xt_target *target, void *targinfo)
 {
        nf_ct_l3proto_module_put(target->family);
 }
 
-static struct xt_target xt_connsecmark_target[] __read_mostly = {
+static struct xt_target connsecmark_tg_reg[] __read_mostly = {
        {
                .name           = "CONNSECMARK",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .destroy        = destroy,
-               .target         = target,
+               .checkentry     = connsecmark_tg_check,
+               .destroy        = connsecmark_tg_destroy,
+               .target         = connsecmark_tg,
                .targetsize     = sizeof(struct xt_connsecmark_target_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
@@ -128,26 +132,26 @@ static struct xt_target xt_connsecmark_target[] __read_mostly = {
        {
                .name           = "CONNSECMARK",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .destroy        = destroy,
-               .target         = target,
+               .checkentry     = connsecmark_tg_check,
+               .destroy        = connsecmark_tg_destroy,
+               .target         = connsecmark_tg,
                .targetsize     = sizeof(struct xt_connsecmark_target_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_connsecmark_init(void)
+static int __init connsecmark_tg_init(void)
 {
-       return xt_register_targets(xt_connsecmark_target,
-                                  ARRAY_SIZE(xt_connsecmark_target));
+       return xt_register_targets(connsecmark_tg_reg,
+              ARRAY_SIZE(connsecmark_tg_reg));
 }
 
-static void __exit xt_connsecmark_fini(void)
+static void __exit connsecmark_tg_exit(void)
 {
-       xt_unregister_targets(xt_connsecmark_target,
-                             ARRAY_SIZE(xt_connsecmark_target));
+       xt_unregister_targets(connsecmark_tg_reg,
+                             ARRAY_SIZE(connsecmark_tg_reg));
 }
 
-module_init(xt_connsecmark_init);
-module_exit(xt_connsecmark_fini);
+module_init(connsecmark_tg_init);
+module_exit(connsecmark_tg_exit);
index 6322a933ab71b1b855ef9e056b9ef0aaf2b80325..97efd74c04fef2c91899c3d773b184bf96d2dfdc 100644 (file)
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_DSCP.h>
+#include <linux/netfilter_ipv4/ipt_TOS.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("x_tables DSCP modification module");
+MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_DSCP");
 MODULE_ALIAS("ip6t_DSCP");
+MODULE_ALIAS("ipt_TOS");
+MODULE_ALIAS("ip6t_TOS");
 
-static unsigned int target(struct sk_buff *skb,
-                          const struct net_device *in,
-                          const struct net_device *out,
-                          unsigned int hooknum,
-                          const struct xt_target *target,
-                          const void *targinfo)
+static unsigned int
+dscp_tg(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
 {
        const struct xt_DSCP_info *dinfo = targinfo;
        u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -46,12 +47,10 @@ static unsigned int target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static unsigned int target6(struct sk_buff *skb,
-                           const struct net_device *in,
-                           const struct net_device *out,
-                           unsigned int hooknum,
-                           const struct xt_target *target,
-                           const void *targinfo)
+static unsigned int
+dscp_tg6(struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, unsigned int hooknum,
+         const struct xt_target *target, const void *targinfo)
 {
        const struct xt_DSCP_info *dinfo = targinfo;
        u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -66,11 +65,10 @@ static unsigned int target6(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static bool checkentry(const char *tablename,
-                      const void *e_void,
-                      const struct xt_target *target,
-                      void *targinfo,
-                      unsigned int hook_mask)
+static bool
+dscp_tg_check(const char *tablename, const void *e_void,
+              const struct xt_target *target, void *targinfo,
+              unsigned int hook_mask)
 {
        const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp;
 
@@ -81,12 +79,95 @@ static bool checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_target xt_dscp_target[] __read_mostly = {
+static unsigned int
+tos_tg_v0(struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, unsigned int hooknum,
+          const struct xt_target *target, const void *targinfo)
+{
+       const struct ipt_tos_target_info *info = targinfo;
+       struct iphdr *iph = ip_hdr(skb);
+       u_int8_t oldtos;
+
+       if ((iph->tos & IPTOS_TOS_MASK) != info->tos) {
+               if (!skb_make_writable(skb, sizeof(struct iphdr)))
+                       return NF_DROP;
+
+               iph      = ip_hdr(skb);
+               oldtos   = iph->tos;
+               iph->tos = (iph->tos & IPTOS_PREC_MASK) | info->tos;
+               csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
+       }
+
+       return XT_CONTINUE;
+}
+
+static bool
+tos_tg_check_v0(const char *tablename, const void *e_void,
+                const struct xt_target *target, void *targinfo,
+                unsigned int hook_mask)
+{
+       const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos;
+
+       if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
+           tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
+           tos != IPTOS_NORMALSVC) {
+               printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
+               return false;
+       }
+
+       return true;
+}
+
+static unsigned int
+tos_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
+{
+       const struct xt_tos_target_info *info = targinfo;
+       struct iphdr *iph = ip_hdr(skb);
+       u_int8_t orig, nv;
+
+       orig = ipv4_get_dsfield(iph);
+       nv   = (orig & ~info->tos_mask) ^ info->tos_value;
+
+       if (orig != nv) {
+               if (!skb_make_writable(skb, sizeof(struct iphdr)))
+                       return NF_DROP;
+               iph = ip_hdr(skb);
+               ipv4_change_dsfield(iph, 0, nv);
+       }
+
+       return XT_CONTINUE;
+}
+
+static unsigned int
+tos_tg6(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
+{
+       const struct xt_tos_target_info *info = targinfo;
+       struct ipv6hdr *iph = ipv6_hdr(skb);
+       u_int8_t orig, nv;
+
+       orig = ipv6_get_dsfield(iph);
+       nv   = (orig & info->tos_mask) ^ info->tos_value;
+
+       if (orig != nv) {
+               if (!skb_make_writable(skb, sizeof(struct iphdr)))
+                       return NF_DROP;
+               iph = ipv6_hdr(skb);
+               ipv6_change_dsfield(iph, 0, nv);
+       }
+
+       return XT_CONTINUE;
+}
+
+static struct xt_target dscp_tg_reg[] __read_mostly = {
        {
                .name           = "DSCP",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .target         = target,
+               .checkentry     = dscp_tg_check,
+               .target         = dscp_tg,
                .targetsize     = sizeof(struct xt_DSCP_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
@@ -94,23 +175,51 @@ static struct xt_target xt_dscp_target[] __read_mostly = {
        {
                .name           = "DSCP",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .target         = target6,
+               .checkentry     = dscp_tg_check,
+               .target         = dscp_tg6,
                .targetsize     = sizeof(struct xt_DSCP_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
        },
+       {
+               .name           = "TOS",
+               .revision       = 0,
+               .family         = AF_INET,
+               .table          = "mangle",
+               .target         = tos_tg_v0,
+               .targetsize     = sizeof(struct ipt_tos_target_info),
+               .checkentry     = tos_tg_check_v0,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "TOS",
+               .revision       = 1,
+               .family         = AF_INET,
+               .table          = "mangle",
+               .target         = tos_tg,
+               .targetsize     = sizeof(struct xt_tos_target_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "TOS",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .table          = "mangle",
+               .target         = tos_tg6,
+               .targetsize     = sizeof(struct xt_tos_target_info),
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_dscp_target_init(void)
+static int __init dscp_tg_init(void)
 {
-       return xt_register_targets(xt_dscp_target, ARRAY_SIZE(xt_dscp_target));
+       return xt_register_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg));
 }
 
-static void __exit xt_dscp_target_fini(void)
+static void __exit dscp_tg_exit(void)
 {
-       xt_unregister_targets(xt_dscp_target, ARRAY_SIZE(xt_dscp_target));
+       xt_unregister_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg));
 }
 
-module_init(xt_dscp_target_init);
-module_exit(xt_dscp_target_fini);
+module_init(dscp_tg_init);
+module_exit(dscp_tg_exit);
index bc6503d77d75437d051c863a3b7771da8948a943..f9ce20b58981c757c85980557a919b276919299e 100644 (file)
@@ -1,10 +1,13 @@
-/* This is a module which is used for setting the NFMARK field of an skb. */
-
-/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+/*
+ *     xt_MARK - Netfilter module to modify the NFMARK field of an skb
+ *
+ *     (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ *     Jan Engelhardt <jengelh@computergmbh.de>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ *     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>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("ip[6]tables MARK modification module");
+MODULE_DESCRIPTION("Xtables: packet mark modification");
 MODULE_ALIAS("ipt_MARK");
 MODULE_ALIAS("ip6t_MARK");
 
 static unsigned int
-target_v0(struct sk_buff *skb,
-         const struct net_device *in,
-         const struct net_device *out,
-         unsigned int hooknum,
-         const struct xt_target *target,
-         const void *targinfo)
+mark_tg_v0(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        const struct xt_mark_target_info *markinfo = targinfo;
 
@@ -36,12 +36,9 @@ target_v0(struct sk_buff *skb,
 }
 
 static unsigned int
-target_v1(struct sk_buff *skb,
-         const struct net_device *in,
-         const struct net_device *out,
-         unsigned int hooknum,
-         const struct xt_target *target,
-         const void *targinfo)
+mark_tg_v1(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        const struct xt_mark_target_info_v1 *markinfo = targinfo;
        int mark = 0;
@@ -64,13 +61,21 @@ target_v1(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
+static unsigned int
+mark_tg(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
+{
+       const struct xt_mark_tginfo2 *info = targinfo;
+
+       skb->mark = (skb->mark & ~info->mask) ^ info->mark;
+       return XT_CONTINUE;
+}
 
 static bool
-checkentry_v0(const char *tablename,
-             const void *entry,
-             const struct xt_target *target,
-             void *targinfo,
-             unsigned int hook_mask)
+mark_tg_check_v0(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_mark_target_info *markinfo = targinfo;
 
@@ -82,11 +87,9 @@ checkentry_v0(const char *tablename,
 }
 
 static bool
-checkentry_v1(const char *tablename,
-             const void *entry,
-             const struct xt_target *target,
-             void *targinfo,
-             unsigned int hook_mask)
+mark_tg_check_v1(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_mark_target_info_v1 *markinfo = targinfo;
 
@@ -105,6 +108,28 @@ checkentry_v1(const char *tablename,
 }
 
 #ifdef CONFIG_COMPAT
+struct compat_xt_mark_target_info {
+       compat_ulong_t  mark;
+};
+
+static void mark_tg_compat_from_user_v0(void *dst, void *src)
+{
+       const struct compat_xt_mark_target_info *cm = src;
+       struct xt_mark_target_info m = {
+               .mark   = cm->mark,
+       };
+       memcpy(dst, &m, sizeof(m));
+}
+
+static int mark_tg_compat_to_user_v0(void __user *dst, void *src)
+{
+       const struct xt_mark_target_info *m = src;
+       struct compat_xt_mark_target_info cm = {
+               .mark   = m->mark,
+       };
+       return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
+}
+
 struct compat_xt_mark_target_info_v1 {
        compat_ulong_t  mark;
        u_int8_t        mode;
@@ -112,7 +137,7 @@ struct compat_xt_mark_target_info_v1 {
        u_int16_t       __pad2;
 };
 
-static void compat_from_user_v1(void *dst, void *src)
+static void mark_tg_compat_from_user_v1(void *dst, void *src)
 {
        const struct compat_xt_mark_target_info_v1 *cm = src;
        struct xt_mark_target_info_v1 m = {
@@ -122,7 +147,7 @@ static void compat_from_user_v1(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user_v1(void __user *dst, void *src)
+static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
 {
        const struct xt_mark_target_info_v1 *m = src;
        struct compat_xt_mark_target_info_v1 cm = {
@@ -133,14 +158,19 @@ static int compat_to_user_v1(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_target xt_mark_target[] __read_mostly = {
+static struct xt_target mark_tg_reg[] __read_mostly = {
        {
                .name           = "MARK",
                .family         = AF_INET,
                .revision       = 0,
-               .checkentry     = checkentry_v0,
-               .target         = target_v0,
+               .checkentry     = mark_tg_check_v0,
+               .target         = mark_tg_v0,
                .targetsize     = sizeof(struct xt_mark_target_info),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_mark_target_info),
+               .compat_from_user = mark_tg_compat_from_user_v0,
+               .compat_to_user = mark_tg_compat_to_user_v0,
+#endif
                .table          = "mangle",
                .me             = THIS_MODULE,
        },
@@ -148,13 +178,13 @@ static struct xt_target xt_mark_target[] __read_mostly = {
                .name           = "MARK",
                .family         = AF_INET,
                .revision       = 1,
-               .checkentry     = checkentry_v1,
-               .target         = target_v1,
+               .checkentry     = mark_tg_check_v1,
+               .target         = mark_tg_v1,
                .targetsize     = sizeof(struct xt_mark_target_info_v1),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_mark_target_info_v1),
-               .compat_from_user = compat_from_user_v1,
-               .compat_to_user = compat_to_user_v1,
+               .compat_from_user = mark_tg_compat_from_user_v1,
+               .compat_to_user = mark_tg_compat_to_user_v1,
 #endif
                .table          = "mangle",
                .me             = THIS_MODULE,
@@ -163,23 +193,59 @@ static struct xt_target xt_mark_target[] __read_mostly = {
                .name           = "MARK",
                .family         = AF_INET6,
                .revision       = 0,
-               .checkentry     = checkentry_v0,
-               .target         = target_v0,
+               .checkentry     = mark_tg_check_v0,
+               .target         = mark_tg_v0,
                .targetsize     = sizeof(struct xt_mark_target_info),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_mark_target_info),
+               .compat_from_user = mark_tg_compat_from_user_v0,
+               .compat_to_user = mark_tg_compat_to_user_v0,
+#endif
+               .table          = "mangle",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "MARK",
+               .family         = AF_INET6,
+               .revision       = 1,
+               .checkentry     = mark_tg_check_v1,
+               .target         = mark_tg_v1,
+               .targetsize     = sizeof(struct xt_mark_target_info_v1),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_mark_target_info_v1),
+               .compat_from_user = mark_tg_compat_from_user_v1,
+               .compat_to_user = mark_tg_compat_to_user_v1,
+#endif
                .table          = "mangle",
                .me             = THIS_MODULE,
        },
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = AF_INET,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "MARK",
+               .revision       = 2,
+               .family         = AF_INET6,
+               .target         = mark_tg,
+               .targetsize     = sizeof(struct xt_mark_tginfo2),
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_mark_init(void)
+static int __init mark_tg_init(void)
 {
-       return xt_register_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target));
+       return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
 }
 
-static void __exit xt_mark_fini(void)
+static void __exit mark_tg_exit(void)
 {
-       xt_unregister_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target));
+       xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
 }
 
-module_init(xt_mark_init);
-module_exit(xt_mark_fini);
+module_init(mark_tg_init);
+module_exit(mark_tg_exit);
index 9fb449ffbf8bef0af176ce7ad474147e6b4eb1d1..19ae8efae6551a76d326de6b8757b8b3a5db86e8 100644 (file)
 
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_NFLOG.h>
+#include <net/netfilter/nf_log.h>
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_DESCRIPTION("x_tables NFLOG target");
+MODULE_DESCRIPTION("Xtables: packet logging to netlink using NFLOG");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_NFLOG");
 MODULE_ALIAS("ip6t_NFLOG");
 
 static unsigned int
-nflog_target(struct sk_buff *skb,
-            const struct net_device *in, const struct net_device *out,
-            unsigned int hooknum, const struct xt_target *target,
-            const void *targinfo)
+nflog_tg(struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, unsigned int hooknum,
+         const struct xt_target *target, const void *targinfo)
 {
        const struct xt_nflog_info *info = targinfo;
        struct nf_loginfo li;
@@ -39,9 +39,9 @@ nflog_target(struct sk_buff *skb,
 }
 
 static bool
-nflog_checkentry(const char *tablename, const void *entry,
-                const struct xt_target *target, void *targetinfo,
-                unsigned int hookmask)
+nflog_tg_check(const char *tablename, const void *entry,
+               const struct xt_target *target, void *targetinfo,
+               unsigned int hookmask)
 {
        const struct xt_nflog_info *info = targetinfo;
 
@@ -52,35 +52,34 @@ nflog_checkentry(const char *tablename, const void *entry,
        return true;
 }
 
-static struct xt_target xt_nflog_target[] __read_mostly = {
+static struct xt_target nflog_tg_reg[] __read_mostly = {
        {
                .name           = "NFLOG",
                .family         = AF_INET,
-               .checkentry     = nflog_checkentry,
-               .target         = nflog_target,
+               .checkentry     = nflog_tg_check,
+               .target         = nflog_tg,
                .targetsize     = sizeof(struct xt_nflog_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "NFLOG",
                .family         = AF_INET6,
-               .checkentry     = nflog_checkentry,
-               .target         = nflog_target,
+               .checkentry     = nflog_tg_check,
+               .target         = nflog_tg,
                .targetsize     = sizeof(struct xt_nflog_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_nflog_init(void)
+static int __init nflog_tg_init(void)
 {
-       return xt_register_targets(xt_nflog_target,
-                                  ARRAY_SIZE(xt_nflog_target));
+       return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
-static void __exit xt_nflog_fini(void)
+static void __exit nflog_tg_exit(void)
 {
-       xt_unregister_targets(xt_nflog_target, ARRAY_SIZE(xt_nflog_target));
+       xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg));
 }
 
-module_init(xt_nflog_init);
-module_exit(xt_nflog_fini);
+module_init(nflog_tg_init);
+module_exit(nflog_tg_exit);
index c3984e9f766a361c2a6d82f445f27aeba00c3fec..beb24d19a56f7373bee6c535fe329e1b7a1f6ea5 100644 (file)
 #include <linux/netfilter/xt_NFQUEUE.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("[ip,ip6,arp]_tables NFQUEUE target");
+MODULE_DESCRIPTION("Xtables: packet forwarding to netlink");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_NFQUEUE");
 MODULE_ALIAS("ip6t_NFQUEUE");
 MODULE_ALIAS("arpt_NFQUEUE");
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+nfqueue_tg(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        const struct xt_NFQ_info *tinfo = targinfo;
 
        return NF_QUEUE_NR(tinfo->queuenum);
 }
 
-static struct xt_target xt_nfqueue_target[] __read_mostly = {
+static struct xt_target nfqueue_tg_reg[] __read_mostly = {
        {
                .name           = "NFQUEUE",
                .family         = AF_INET,
-               .target         = target,
+               .target         = nfqueue_tg,
                .targetsize     = sizeof(struct xt_NFQ_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "NFQUEUE",
                .family         = AF_INET6,
-               .target         = target,
+               .target         = nfqueue_tg,
                .targetsize     = sizeof(struct xt_NFQ_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "NFQUEUE",
                .family         = NF_ARP,
-               .target         = target,
+               .target         = nfqueue_tg,
                .targetsize     = sizeof(struct xt_NFQ_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_nfqueue_init(void)
+static int __init nfqueue_tg_init(void)
 {
-       return xt_register_targets(xt_nfqueue_target,
-                                  ARRAY_SIZE(xt_nfqueue_target));
+       return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
 }
 
-static void __exit xt_nfqueue_fini(void)
+static void __exit nfqueue_tg_exit(void)
 {
-       xt_unregister_targets(xt_nfqueue_target, ARRAY_SIZE(xt_nfqueue_target));
+       xt_unregister_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
 }
 
-module_init(xt_nfqueue_init);
-module_exit(xt_nfqueue_fini);
+module_init(nfqueue_tg_init);
+module_exit(nfqueue_tg_exit);
index 4976ce186615e51c3159c74fbbec4c68807a3dd4..6c9de611eb8d8c006de8ebfbd188a4d378ab6123 100644 (file)
@@ -7,17 +7,15 @@
 #include <linux/netfilter/x_tables.h>
 #include <net/netfilter/nf_conntrack.h>
 
+MODULE_DESCRIPTION("Xtables: Disabling connection tracking for packets");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_NOTRACK");
 MODULE_ALIAS("ip6t_NOTRACK");
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+notrack_tg(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        /* Previously seen (loopback)? Ignore. */
        if (skb->nfct != NULL)
@@ -34,33 +32,32 @@ target(struct sk_buff *skb,
        return XT_CONTINUE;
 }
 
-static struct xt_target xt_notrack_target[] __read_mostly = {
+static struct xt_target notrack_tg_reg[] __read_mostly = {
        {
                .name           = "NOTRACK",
                .family         = AF_INET,
-               .target         = target,
+               .target         = notrack_tg,
                .table          = "raw",
                .me             = THIS_MODULE,
        },
        {
                .name           = "NOTRACK",
                .family         = AF_INET6,
-               .target         = target,
+               .target         = notrack_tg,
                .table          = "raw",
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_notrack_init(void)
+static int __init notrack_tg_init(void)
 {
-       return xt_register_targets(xt_notrack_target,
-                                  ARRAY_SIZE(xt_notrack_target));
+       return xt_register_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg));
 }
 
-static void __exit xt_notrack_fini(void)
+static void __exit notrack_tg_exit(void)
 {
-       xt_unregister_targets(xt_notrack_target, ARRAY_SIZE(xt_notrack_target));
+       xt_unregister_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg));
 }
 
-module_init(xt_notrack_init);
-module_exit(xt_notrack_fini);
+module_init(notrack_tg_init);
+module_exit(notrack_tg_exit);
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
new file mode 100644 (file)
index 0000000..24c73ba
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * (C) 2007 Patrick McHardy <kaber@trash.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/module.h>
+#include <linux/skbuff.h>
+#include <linux/gen_stats.h>
+#include <linux/jhash.h>
+#include <linux/rtnetlink.h>
+#include <linux/random.h>
+#include <net/gen_stats.h>
+#include <net/netlink.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_RATEEST.h>
+#include <net/netfilter/xt_rateest.h>
+
+static DEFINE_MUTEX(xt_rateest_mutex);
+
+#define RATEEST_HSIZE  16
+static struct hlist_head rateest_hash[RATEEST_HSIZE] __read_mostly;
+static unsigned int jhash_rnd __read_mostly;
+
+static unsigned int xt_rateest_hash(const char *name)
+{
+       return jhash(name, FIELD_SIZEOF(struct xt_rateest, name), jhash_rnd) &
+              (RATEEST_HSIZE - 1);
+}
+
+static void xt_rateest_hash_insert(struct xt_rateest *est)
+{
+       unsigned int h;
+
+       h = xt_rateest_hash(est->name);
+       hlist_add_head(&est->list, &rateest_hash[h]);
+}
+
+struct xt_rateest *xt_rateest_lookup(const char *name)
+{
+       struct xt_rateest *est;
+       struct hlist_node *n;
+       unsigned int h;
+
+       h = xt_rateest_hash(name);
+       mutex_lock(&xt_rateest_mutex);
+       hlist_for_each_entry(est, n, &rateest_hash[h], list) {
+               if (strcmp(est->name, name) == 0) {
+                       est->refcnt++;
+                       mutex_unlock(&xt_rateest_mutex);
+                       return est;
+               }
+       }
+       mutex_unlock(&xt_rateest_mutex);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(xt_rateest_lookup);
+
+void xt_rateest_put(struct xt_rateest *est)
+{
+       mutex_lock(&xt_rateest_mutex);
+       if (--est->refcnt == 0) {
+               hlist_del(&est->list);
+               gen_kill_estimator(&est->bstats, &est->rstats);
+               kfree(est);
+       }
+       mutex_unlock(&xt_rateest_mutex);
+}
+EXPORT_SYMBOL_GPL(xt_rateest_put);
+
+static unsigned int
+xt_rateest_tg(struct sk_buff *skb,
+             const struct net_device *in,
+             const struct net_device *out,
+             unsigned int hooknum,
+             const struct xt_target *target,
+             const void *targinfo)
+{
+       const struct xt_rateest_target_info *info = targinfo;
+       struct gnet_stats_basic *stats = &info->est->bstats;
+
+       spin_lock_bh(&info->est->lock);
+       stats->bytes += skb->len;
+       stats->packets++;
+       spin_unlock_bh(&info->est->lock);
+
+       return XT_CONTINUE;
+}
+
+static bool
+xt_rateest_tg_checkentry(const char *tablename,
+                        const void *entry,
+                        const struct xt_target *target,
+                        void *targinfo,
+                        unsigned int hook_mask)
+{
+       struct xt_rateest_target_info *info = (void *)targinfo;
+       struct xt_rateest *est;
+       struct {
+               struct nlattr           opt;
+               struct gnet_estimator   est;
+       } cfg;
+
+       est = xt_rateest_lookup(info->name);
+       if (est) {
+               /*
+                * If estimator parameters are specified, they must match the
+                * existing estimator.
+                */
+               if ((!info->interval && !info->ewma_log) ||
+                   (info->interval != est->params.interval ||
+                    info->ewma_log != est->params.ewma_log)) {
+                       xt_rateest_put(est);
+                       return false;
+               }
+               info->est = est;
+               return true;
+       }
+
+       est = kzalloc(sizeof(*est), GFP_KERNEL);
+       if (!est)
+               goto err1;
+
+       strlcpy(est->name, info->name, sizeof(est->name));
+       spin_lock_init(&est->lock);
+       est->refcnt             = 1;
+       est->params.interval    = info->interval;
+       est->params.ewma_log    = info->ewma_log;
+
+       cfg.opt.nla_len         = nla_attr_size(sizeof(cfg.est));
+       cfg.opt.nla_type        = TCA_STATS_RATE_EST;
+       cfg.est.interval        = info->interval;
+       cfg.est.ewma_log        = info->ewma_log;
+
+       if (gen_new_estimator(&est->bstats, &est->rstats, &est->lock,
+                             &cfg.opt) < 0)
+               goto err2;
+
+       info->est = est;
+       xt_rateest_hash_insert(est);
+
+       return true;
+
+err2:
+       kfree(est);
+err1:
+       return false;
+}
+
+static void xt_rateest_tg_destroy(const struct xt_target *target,
+                                 void *targinfo)
+{
+       struct xt_rateest_target_info *info = targinfo;
+
+       xt_rateest_put(info->est);
+}
+
+static struct xt_target xt_rateest_target[] __read_mostly = {
+       {
+               .family         = AF_INET,
+               .name           = "RATEEST",
+               .target         = xt_rateest_tg,
+               .checkentry     = xt_rateest_tg_checkentry,
+               .destroy        = xt_rateest_tg_destroy,
+               .targetsize     = sizeof(struct xt_rateest_target_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .family         = AF_INET6,
+               .name           = "RATEEST",
+               .target         = xt_rateest_tg,
+               .checkentry     = xt_rateest_tg_checkentry,
+               .destroy        = xt_rateest_tg_destroy,
+               .targetsize     = sizeof(struct xt_rateest_target_info),
+               .me             = THIS_MODULE,
+       },
+};
+
+static int __init xt_rateest_tg_init(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(rateest_hash); i++)
+               INIT_HLIST_HEAD(&rateest_hash[i]);
+
+       get_random_bytes(&jhash_rnd, sizeof(jhash_rnd));
+       return xt_register_targets(xt_rateest_target,
+                                  ARRAY_SIZE(xt_rateest_target));
+}
+
+static void __exit xt_rateest_tg_fini(void)
+{
+       xt_unregister_targets(xt_rateest_target, ARRAY_SIZE(xt_rateest_target));
+}
+
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Xtables: packet rate estimator");
+MODULE_ALIAS("ipt_RATEEST");
+MODULE_ALIAS("ip6t_RATEEST");
+module_init(xt_rateest_tg_init);
+module_exit(xt_rateest_tg_fini);
index 235806eb6ecd725c1b43d3598483922d339bd6e0..b11b3ecbb39d70f37862ab34c0a2ad522103288b 100644 (file)
@@ -20,7 +20,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
-MODULE_DESCRIPTION("ip[6]tables SECMARK modification module");
+MODULE_DESCRIPTION("Xtables: packet security mark modification");
 MODULE_ALIAS("ipt_SECMARK");
 MODULE_ALIAS("ip6t_SECMARK");
 
@@ -28,10 +28,10 @@ MODULE_ALIAS("ip6t_SECMARK");
 
 static u8 mode;
 
-static unsigned int target(struct sk_buff *skb, const struct net_device *in,
-                          const struct net_device *out, unsigned int hooknum,
-                          const struct xt_target *target,
-                          const void *targinfo)
+static unsigned int
+secmark_tg(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        u32 secmark = 0;
        const struct xt_secmark_target_info *info = targinfo;
@@ -81,9 +81,10 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info)
        return true;
 }
 
-static bool checkentry(const char *tablename, const void *entry,
-                      const struct xt_target *target, void *targinfo,
-                      unsigned int hook_mask)
+static bool
+secmark_tg_check(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        struct xt_secmark_target_info *info = targinfo;
 
@@ -109,12 +110,12 @@ static bool checkentry(const char *tablename, const void *entry,
        return true;
 }
 
-static struct xt_target xt_secmark_target[] __read_mostly = {
+static struct xt_target secmark_tg_reg[] __read_mostly = {
        {
                .name           = "SECMARK",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .target         = target,
+               .checkentry     = secmark_tg_check,
+               .target         = secmark_tg,
                .targetsize     = sizeof(struct xt_secmark_target_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
@@ -122,24 +123,23 @@ static struct xt_target xt_secmark_target[] __read_mostly = {
        {
                .name           = "SECMARK",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .target         = target,
+               .checkentry     = secmark_tg_check,
+               .target         = secmark_tg,
                .targetsize     = sizeof(struct xt_secmark_target_info),
                .table          = "mangle",
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_secmark_init(void)
+static int __init secmark_tg_init(void)
 {
-       return xt_register_targets(xt_secmark_target,
-                                  ARRAY_SIZE(xt_secmark_target));
+       return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
 }
 
-static void __exit xt_secmark_fini(void)
+static void __exit secmark_tg_exit(void)
 {
-       xt_unregister_targets(xt_secmark_target, ARRAY_SIZE(xt_secmark_target));
+       xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg));
 }
 
-module_init(xt_secmark_init);
-module_exit(xt_secmark_fini);
+module_init(secmark_tg_init);
+module_exit(secmark_tg_exit);
index 8e76d1f52fbe3079cf574e41b9750d2b77d2f264..60e3767cc71deb40f61e0d8ecaf9c87a76fc8996 100644 (file)
@@ -24,7 +24,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("x_tables TCP MSS modification module");
+MODULE_DESCRIPTION("Xtables: TCP Maximum Segment Size (MSS) adjustment");
 MODULE_ALIAS("ipt_TCPMSS");
 MODULE_ALIAS("ip6t_TCPMSS");
 
@@ -88,15 +88,19 @@ tcpmss_mangle_packet(struct sk_buff *skb,
 
                        oldmss = (opt[i+2] << 8) | opt[i+3];
 
-                       if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
-                           oldmss <= newmss)
+                       /* Never increase MSS, even when setting it, as
+                        * doing so results in problems for hosts that rely
+                        * on MSS being set correctly.
+                        */
+                       if (oldmss <= newmss)
                                return 0;
 
                        opt[i+2] = (newmss & 0xff00) >> 8;
                        opt[i+3] = newmss & 0x00ff;
 
-                       nf_proto_csum_replace2(&tcph->check, skb,
-                                              htons(oldmss), htons(newmss), 0);
+                       inet_proto_csum_replace2(&tcph->check, skb,
+                                                htons(oldmss), htons(newmss),
+                                                0);
                        return 0;
                }
        }
@@ -117,29 +121,26 @@ tcpmss_mangle_packet(struct sk_buff *skb,
        opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
        memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
 
-       nf_proto_csum_replace2(&tcph->check, skb,
-                              htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
+       inet_proto_csum_replace2(&tcph->check, skb,
+                                htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
        opt[0] = TCPOPT_MSS;
        opt[1] = TCPOLEN_MSS;
        opt[2] = (newmss & 0xff00) >> 8;
        opt[3] = newmss & 0x00ff;
 
-       nf_proto_csum_replace4(&tcph->check, skb, 0, *((__be32 *)opt), 0);
+       inet_proto_csum_replace4(&tcph->check, skb, 0, *((__be32 *)opt), 0);
 
        oldval = ((__be16 *)tcph)[6];
        tcph->doff += TCPOLEN_MSS/4;
-       nf_proto_csum_replace2(&tcph->check, skb,
-                               oldval, ((__be16 *)tcph)[6], 0);
+       inet_proto_csum_replace2(&tcph->check, skb,
+                                oldval, ((__be16 *)tcph)[6], 0);
        return TCPOLEN_MSS;
 }
 
 static unsigned int
-xt_tcpmss_target4(struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 unsigned int hooknum,
-                 const struct xt_target *target,
-                 const void *targinfo)
+tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        struct iphdr *iph = ip_hdr(skb);
        __be16 newlen;
@@ -152,7 +153,7 @@ xt_tcpmss_target4(struct sk_buff *skb,
        if (ret > 0) {
                iph = ip_hdr(skb);
                newlen = htons(ntohs(iph->tot_len) + ret);
-               nf_csum_replace2(&iph->check, iph->tot_len, newlen);
+               csum_replace2(&iph->check, iph->tot_len, newlen);
                iph->tot_len = newlen;
        }
        return XT_CONTINUE;
@@ -160,12 +161,9 @@ xt_tcpmss_target4(struct sk_buff *skb,
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static unsigned int
-xt_tcpmss_target6(struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 unsigned int hooknum,
-                 const struct xt_target *target,
-                 const void *targinfo)
+tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, unsigned int hooknum,
+           const struct xt_target *target, const void *targinfo)
 {
        struct ipv6hdr *ipv6h = ipv6_hdr(skb);
        u8 nexthdr;
@@ -204,19 +202,17 @@ static inline bool find_syn_match(const struct xt_entry_match *m)
 }
 
 static bool
-xt_tcpmss_checkentry4(const char *tablename,
-                     const void *entry,
-                     const struct xt_target *target,
-                     void *targinfo,
-                     unsigned int hook_mask)
+tcpmss_tg4_check(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_tcpmss_info *info = targinfo;
        const struct ipt_entry *e = entry;
 
        if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
-           (hook_mask & ~((1 << NF_IP_FORWARD) |
-                          (1 << NF_IP_LOCAL_OUT) |
-                          (1 << NF_IP_POST_ROUTING))) != 0) {
+           (hook_mask & ~((1 << NF_INET_FORWARD) |
+                          (1 << NF_INET_LOCAL_OUT) |
+                          (1 << NF_INET_POST_ROUTING))) != 0) {
                printk("xt_TCPMSS: path-MTU clamping only supported in "
                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
                return false;
@@ -229,19 +225,17 @@ xt_tcpmss_checkentry4(const char *tablename,
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static bool
-xt_tcpmss_checkentry6(const char *tablename,
-                     const void *entry,
-                     const struct xt_target *target,
-                     void *targinfo,
-                     unsigned int hook_mask)
+tcpmss_tg6_check(const char *tablename, const void *entry,
+                 const struct xt_target *target, void *targinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_tcpmss_info *info = targinfo;
        const struct ip6t_entry *e = entry;
 
        if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
-           (hook_mask & ~((1 << NF_IP6_FORWARD) |
-                          (1 << NF_IP6_LOCAL_OUT) |
-                          (1 << NF_IP6_POST_ROUTING))) != 0) {
+           (hook_mask & ~((1 << NF_INET_FORWARD) |
+                          (1 << NF_INET_LOCAL_OUT) |
+                          (1 << NF_INET_POST_ROUTING))) != 0) {
                printk("xt_TCPMSS: path-MTU clamping only supported in "
                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
                return false;
@@ -253,12 +247,12 @@ xt_tcpmss_checkentry6(const char *tablename,
 }
 #endif
 
-static struct xt_target xt_tcpmss_reg[] __read_mostly = {
+static struct xt_target tcpmss_tg_reg[] __read_mostly = {
        {
                .family         = AF_INET,
                .name           = "TCPMSS",
-               .checkentry     = xt_tcpmss_checkentry4,
-               .target         = xt_tcpmss_target4,
+               .checkentry     = tcpmss_tg4_check,
+               .target         = tcpmss_tg4,
                .targetsize     = sizeof(struct xt_tcpmss_info),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
@@ -267,8 +261,8 @@ static struct xt_target xt_tcpmss_reg[] __read_mostly = {
        {
                .family         = AF_INET6,
                .name           = "TCPMSS",
-               .checkentry     = xt_tcpmss_checkentry6,
-               .target         = xt_tcpmss_target6,
+               .checkentry     = tcpmss_tg6_check,
+               .target         = tcpmss_tg6,
                .targetsize     = sizeof(struct xt_tcpmss_info),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
@@ -276,15 +270,15 @@ static struct xt_target xt_tcpmss_reg[] __read_mostly = {
 #endif
 };
 
-static int __init xt_tcpmss_init(void)
+static int __init tcpmss_tg_init(void)
 {
-       return xt_register_targets(xt_tcpmss_reg, ARRAY_SIZE(xt_tcpmss_reg));
+       return xt_register_targets(tcpmss_tg_reg, ARRAY_SIZE(tcpmss_tg_reg));
 }
 
-static void __exit xt_tcpmss_fini(void)
+static void __exit tcpmss_tg_exit(void)
 {
-       xt_unregister_targets(xt_tcpmss_reg, ARRAY_SIZE(xt_tcpmss_reg));
+       xt_unregister_targets(tcpmss_tg_reg, ARRAY_SIZE(tcpmss_tg_reg));
 }
 
-module_init(xt_tcpmss_init);
-module_exit(xt_tcpmss_fini);
+module_init(tcpmss_tg_init);
+module_exit(tcpmss_tg_exit);
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
new file mode 100644 (file)
index 0000000..3b2aa56
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * A module for stripping a specific TCP option from TCP packets.
+ *
+ * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org>
+ * Copyright Â© CC Computer Consultants GmbH, 2007
+ * Contact: Jan Engelhardt <jengelh@computergmbh.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/tcp.h>
+#include <net/ipv6.h>
+#include <net/tcp.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TCPOPTSTRIP.h>
+
+static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
+{
+       /* Beware zero-length options: make finite progress */
+       if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
+               return 1;
+       else
+               return opt[offset+1];
+}
+
+static unsigned int
+tcpoptstrip_mangle_packet(struct sk_buff *skb,
+                         const struct xt_tcpoptstrip_target_info *info,
+                         unsigned int tcphoff, unsigned int minlen)
+{
+       unsigned int optl, i, j;
+       struct tcphdr *tcph;
+       u_int16_t n, o;
+       u_int8_t *opt;
+
+       if (!skb_make_writable(skb, skb->len))
+               return NF_DROP;
+
+       tcph = (struct tcphdr *)(skb_network_header(skb) + tcphoff);
+       opt  = (u_int8_t *)tcph;
+
+       /*
+        * Walk through all TCP options - if we find some option to remove,
+        * set all octets to %TCPOPT_NOP and adjust checksum.
+        */
+       for (i = sizeof(struct tcphdr); i < tcp_hdrlen(skb); i += optl) {
+               optl = optlen(opt, i);
+
+               if (i + optl > tcp_hdrlen(skb))
+                       break;
+
+               if (!tcpoptstrip_test_bit(info->strip_bmap, opt[i]))
+                       continue;
+
+               for (j = 0; j < optl; ++j) {
+                       o = opt[i+j];
+                       n = TCPOPT_NOP;
+                       if ((i + j) % 2 == 0) {
+                               o <<= 8;
+                               n <<= 8;
+                       }
+                       inet_proto_csum_replace2(&tcph->check, skb, htons(o),
+                                                htons(n), 0);
+               }
+               memset(opt + i, TCPOPT_NOP, optl);
+       }
+
+       return XT_CONTINUE;
+}
+
+static unsigned int
+tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, unsigned int hooknum,
+               const struct xt_target *target, const void *targinfo)
+{
+       return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb),
+              sizeof(struct iphdr) + sizeof(struct tcphdr));
+}
+
+#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
+static unsigned int
+tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, unsigned int hooknum,
+               const struct xt_target *target, const void *targinfo)
+{
+       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+       unsigned int tcphoff;
+       u_int8_t nexthdr;
+
+       nexthdr = ipv6h->nexthdr;
+       tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
+       if (tcphoff < 0)
+               return NF_DROP;
+
+       return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff,
+              sizeof(*ipv6h) + sizeof(struct tcphdr));
+}
+#endif
+
+static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
+       {
+               .name       = "TCPOPTSTRIP",
+               .family     = AF_INET,
+               .table      = "mangle",
+               .proto      = IPPROTO_TCP,
+               .target     = tcpoptstrip_tg4,
+               .targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+               .me         = THIS_MODULE,
+       },
+#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
+       {
+               .name       = "TCPOPTSTRIP",
+               .family     = AF_INET6,
+               .table      = "mangle",
+               .proto      = IPPROTO_TCP,
+               .target     = tcpoptstrip_tg6,
+               .targetsize = sizeof(struct xt_tcpoptstrip_target_info),
+               .me         = THIS_MODULE,
+       },
+#endif
+};
+
+static int __init tcpoptstrip_tg_init(void)
+{
+       return xt_register_targets(tcpoptstrip_tg_reg,
+                                  ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+static void __exit tcpoptstrip_tg_exit(void)
+{
+       xt_unregister_targets(tcpoptstrip_tg_reg,
+                             ARRAY_SIZE(tcpoptstrip_tg_reg));
+}
+
+module_init(tcpoptstrip_tg_init);
+module_exit(tcpoptstrip_tg_exit);
+MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("Xtables: TCP option stripping");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TCPOPTSTRIP");
+MODULE_ALIAS("ip6t_TCPOPTSTRIP");
index 26c5d08ab2c27f48903d74dbd2744acc72fb027b..30dab79a343888161bd0e6a6740d49bb57c97253 100644 (file)
@@ -5,49 +5,46 @@
 
 #include <linux/netfilter/x_tables.h>
 
+MODULE_DESCRIPTION("Xtables: packet flow tracing");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_TRACE");
 MODULE_ALIAS("ip6t_TRACE");
 
 static unsigned int
-target(struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       unsigned int hooknum,
-       const struct xt_target *target,
-       const void *targinfo)
+trace_tg(struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, unsigned int hooknum,
+         const struct xt_target *target, const void *targinfo)
 {
        skb->nf_trace = 1;
        return XT_CONTINUE;
 }
 
-static struct xt_target xt_trace_target[] __read_mostly = {
+static struct xt_target trace_tg_reg[] __read_mostly = {
        {
                .name           = "TRACE",
                .family         = AF_INET,
-               .target         = target,
+               .target         = trace_tg,
                .table          = "raw",
                .me             = THIS_MODULE,
        },
        {
                .name           = "TRACE",
                .family         = AF_INET6,
-               .target         = target,
+               .target         = trace_tg,
                .table          = "raw",
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_trace_init(void)
+static int __init trace_tg_init(void)
 {
-       return xt_register_targets(xt_trace_target,
-                                  ARRAY_SIZE(xt_trace_target));
+       return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
-static void __exit xt_trace_fini(void)
+static void __exit trace_tg_exit(void)
 {
-       xt_unregister_targets(xt_trace_target, ARRAY_SIZE(xt_trace_target));
+       xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg));
 }
 
-module_init(xt_trace_init);
-module_exit(xt_trace_fini);
+module_init(trace_tg_init);
+module_exit(trace_tg_exit);
index 64bcdb0fe1e6797d7687fda7dc481478f377164d..89f47364e84851dfd1f3f9af61ec3d3b63697419 100644 (file)
 #include <linux/netfilter/xt_comment.h>
 
 MODULE_AUTHOR("Brad Fisher <brad@info-link.net>");
-MODULE_DESCRIPTION("iptables comment match module");
+MODULE_DESCRIPTION("Xtables: No-op match which can be tagged with a comment");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_comment");
 MODULE_ALIAS("ip6t_comment");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protooff,
-      bool *hotdrop)
+comment_mt(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protooff,
+           bool *hotdrop)
 {
        /* We always match */
        return true;
 }
 
-static struct xt_match xt_comment_match[] __read_mostly = {
+static struct xt_match comment_mt_reg[] __read_mostly = {
        {
                .name           = "comment",
                .family         = AF_INET,
-               .match          = match,
+               .match          = comment_mt,
                .matchsize      = sizeof(struct xt_comment_info),
                .me             = THIS_MODULE
        },
        {
                .name           = "comment",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = comment_mt,
                .matchsize      = sizeof(struct xt_comment_info),
                .me             = THIS_MODULE
        },
 };
 
-static int __init xt_comment_init(void)
+static int __init comment_mt_init(void)
 {
-       return xt_register_matches(xt_comment_match,
-                                  ARRAY_SIZE(xt_comment_match));
+       return xt_register_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg));
 }
 
-static void __exit xt_comment_fini(void)
+static void __exit comment_mt_exit(void)
 {
-       xt_unregister_matches(xt_comment_match, ARRAY_SIZE(xt_comment_match));
+       xt_unregister_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg));
 }
 
-module_init(xt_comment_init);
-module_exit(xt_comment_fini);
+module_init(comment_mt_init);
+module_exit(comment_mt_exit);
index 9ec50139b9a177d559236790b3f0351c7ba9ef71..b15e7e2fa14328612cdf4de25150cc62604e8a58 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("iptables match for matching number of pkts/bytes per connection");
+MODULE_DESCRIPTION("Xtables: Number of packets/bytes per connection matching");
 MODULE_ALIAS("ipt_connbytes");
 MODULE_ALIAS("ip6t_connbytes");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
 {
        const struct xt_connbytes_info *sinfo = matchinfo;
        const struct nf_conn *ct;
@@ -96,11 +92,10 @@ match(const struct sk_buff *skb,
                return what >= sinfo->count.from;
 }
 
-static bool check(const char *tablename,
-                 const void *ip,
-                 const struct xt_match *match,
-                 void *matchinfo,
-                 unsigned int hook_mask)
+static bool
+connbytes_mt_check(const char *tablename, const void *ip,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        const struct xt_connbytes_info *sinfo = matchinfo;
 
@@ -116,7 +111,7 @@ static bool check(const char *tablename,
 
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", match->family);
+                                   "proto=%u\n", match->family);
                return false;
        }
 
@@ -124,43 +119,42 @@ static bool check(const char *tablename,
 }
 
 static void
-destroy(const struct xt_match *match, void *matchinfo)
+connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_connbytes_match[] __read_mostly = {
+static struct xt_match connbytes_mt_reg[] __read_mostly = {
        {
                .name           = "connbytes",
                .family         = AF_INET,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = connbytes_mt_check,
+               .match          = connbytes_mt,
+               .destroy        = connbytes_mt_destroy,
                .matchsize      = sizeof(struct xt_connbytes_info),
                .me             = THIS_MODULE
        },
        {
                .name           = "connbytes",
                .family         = AF_INET6,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = connbytes_mt_check,
+               .match          = connbytes_mt,
+               .destroy        = connbytes_mt_destroy,
                .matchsize      = sizeof(struct xt_connbytes_info),
                .me             = THIS_MODULE
        },
 };
 
-static int __init xt_connbytes_init(void)
+static int __init connbytes_mt_init(void)
 {
-       return xt_register_matches(xt_connbytes_match,
-                                  ARRAY_SIZE(xt_connbytes_match));
+       return xt_register_matches(connbytes_mt_reg,
+              ARRAY_SIZE(connbytes_mt_reg));
 }
 
-static void __exit xt_connbytes_fini(void)
+static void __exit connbytes_mt_exit(void)
 {
-       xt_unregister_matches(xt_connbytes_match,
-                             ARRAY_SIZE(xt_connbytes_match));
+       xt_unregister_matches(connbytes_mt_reg, ARRAY_SIZE(connbytes_mt_reg));
 }
 
-module_init(xt_connbytes_init);
-module_exit(xt_connbytes_fini);
+module_init(connbytes_mt_init);
+module_exit(connbytes_mt_exit);
index d7becf08a93a3481fe587842f47f60d871f882d3..e00ecd974fa3cf9882b406d5c33157f1fd29d93c 100644 (file)
@@ -53,10 +53,10 @@ static inline unsigned int connlimit_iphash(__be32 addr)
 }
 
 static inline unsigned int
-connlimit_iphash6(const union nf_conntrack_address *addr,
-                 const union nf_conntrack_address *mask)
+connlimit_iphash6(const union nf_inet_addr *addr,
+                  const union nf_inet_addr *mask)
 {
-       union nf_conntrack_address res;
+       union nf_inet_addr res;
        unsigned int i;
 
        if (unlikely(!connlimit_rnd_inited)) {
@@ -81,14 +81,14 @@ static inline bool already_closed(const struct nf_conn *conn)
 }
 
 static inline unsigned int
-same_source_net(const union nf_conntrack_address *addr,
-               const union nf_conntrack_address *mask,
-               const union nf_conntrack_address *u3, unsigned int family)
+same_source_net(const union nf_inet_addr *addr,
+               const union nf_inet_addr *mask,
+               const union nf_inet_addr *u3, unsigned int family)
 {
        if (family == AF_INET) {
                return (addr->ip & mask->ip) == (u3->ip & mask->ip);
        } else {
-               union nf_conntrack_address lh, rh;
+               union nf_inet_addr lh, rh;
                unsigned int i;
 
                for (i = 0; i < ARRAY_SIZE(addr->ip6); ++i) {
@@ -102,8 +102,8 @@ same_source_net(const union nf_conntrack_address *addr,
 
 static int count_them(struct xt_connlimit_data *data,
                      const struct nf_conntrack_tuple *tuple,
-                     const union nf_conntrack_address *addr,
-                     const union nf_conntrack_address *mask,
+                     const union nf_inet_addr *addr,
+                     const union nf_inet_addr *mask,
                      const struct xt_match *match)
 {
        struct nf_conntrack_tuple_hash *found;
@@ -178,15 +178,14 @@ static int count_them(struct xt_connlimit_data *data,
        return matches;
 }
 
-static bool connlimit_match(const struct sk_buff *skb,
-                           const struct net_device *in,
-                           const struct net_device *out,
-                           const struct xt_match *match,
-                           const void *matchinfo, int offset,
-                           unsigned int protoff, bool *hotdrop)
+static bool
+connlimit_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
 {
        const struct xt_connlimit_info *info = matchinfo;
-       union nf_conntrack_address addr, mask;
+       union nf_inet_addr addr;
        struct nf_conntrack_tuple tuple;
        const struct nf_conntrack_tuple *tuple_ptr = &tuple;
        enum ip_conntrack_info ctinfo;
@@ -203,15 +202,14 @@ static bool connlimit_match(const struct sk_buff *skb,
        if (match->family == AF_INET6) {
                const struct ipv6hdr *iph = ipv6_hdr(skb);
                memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr));
-               memcpy(&mask.ip6, info->v6_mask, sizeof(info->v6_mask));
        } else {
                const struct iphdr *iph = ip_hdr(skb);
                addr.ip = iph->saddr;
-               mask.ip = info->v4_mask;
        }
 
        spin_lock_bh(&info->data->lock);
-       connections = count_them(info->data, tuple_ptr, &addr, &mask, match);
+       connections = count_them(info->data, tuple_ptr, &addr,
+                                &info->mask, match);
        spin_unlock_bh(&info->data->lock);
 
        if (connections < 0) {
@@ -227,9 +225,10 @@ static bool connlimit_match(const struct sk_buff *skb,
        return false;
 }
 
-static bool connlimit_check(const char *tablename, const void *ip,
-                           const struct xt_match *match, void *matchinfo,
-                           unsigned int hook_mask)
+static bool
+connlimit_mt_check(const char *tablename, const void *ip,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        struct xt_connlimit_info *info = matchinfo;
        unsigned int i;
@@ -254,7 +253,8 @@ static bool connlimit_check(const char *tablename, const void *ip,
        return true;
 }
 
-static void connlimit_destroy(const struct xt_match *match, void *matchinfo)
+static void
+connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        struct xt_connlimit_info *info = matchinfo;
        struct xt_connlimit_conn *conn;
@@ -274,41 +274,42 @@ static void connlimit_destroy(const struct xt_match *match, void *matchinfo)
        kfree(info->data);
 }
 
-static struct xt_match connlimit_reg[] __read_mostly = {
+static struct xt_match connlimit_mt_reg[] __read_mostly = {
        {
                .name       = "connlimit",
                .family     = AF_INET,
-               .checkentry = connlimit_check,
-               .match      = connlimit_match,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
                .matchsize  = sizeof(struct xt_connlimit_info),
-               .destroy    = connlimit_destroy,
+               .destroy    = connlimit_mt_destroy,
                .me         = THIS_MODULE,
        },
        {
                .name       = "connlimit",
                .family     = AF_INET6,
-               .checkentry = connlimit_check,
-               .match      = connlimit_match,
+               .checkentry = connlimit_mt_check,
+               .match      = connlimit_mt,
                .matchsize  = sizeof(struct xt_connlimit_info),
-               .destroy    = connlimit_destroy,
+               .destroy    = connlimit_mt_destroy,
                .me         = THIS_MODULE,
        },
 };
 
-static int __init xt_connlimit_init(void)
+static int __init connlimit_mt_init(void)
 {
-       return xt_register_matches(connlimit_reg, ARRAY_SIZE(connlimit_reg));
+       return xt_register_matches(connlimit_mt_reg,
+              ARRAY_SIZE(connlimit_mt_reg));
 }
 
-static void __exit xt_connlimit_exit(void)
+static void __exit connlimit_mt_exit(void)
 {
-       xt_unregister_matches(connlimit_reg, ARRAY_SIZE(connlimit_reg));
+       xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg));
 }
 
-module_init(xt_connlimit_init);
-module_exit(xt_connlimit_exit);
+module_init(connlimit_mt_init);
+module_exit(connlimit_mt_exit);
 MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
-MODULE_DESCRIPTION("netfilter xt_connlimit match module");
+MODULE_DESCRIPTION("Xtables: Number of connections matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connlimit");
 MODULE_ALIAS("ip6t_connlimit");
index 9f67920af41fd54a3857701dbfc941abd26d823c..aaa1b96691f942c43dd393945264917c661c49fd 100644 (file)
@@ -1,8 +1,10 @@
-/* This kernel module matches connection mark values set by the
- * CONNMARK target
+/*
+ *     xt_connmark - Netfilter module to match connection mark values
  *
- * Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- * by Henrik Nordstrom <hno@marasystems.com>
+ *     Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
+ *     by Henrik Nordstrom <hno@marasystems.com>
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ *     Jan Engelhardt <jengelh@computergmbh.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
 #include <linux/netfilter/xt_connmark.h>
 
 MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
-MODULE_DESCRIPTION("IP tables connmark match module");
+MODULE_DESCRIPTION("Xtables: connection mark match");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_connmark");
 MODULE_ALIAS("ip6t_connmark");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+connmark_mt(const struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, const struct xt_match *match,
+            const void *matchinfo, int offset, unsigned int protoff,
+            bool *hotdrop)
+{
+       const struct xt_connmark_mtinfo1 *info = matchinfo;
+       enum ip_conntrack_info ctinfo;
+       const struct nf_conn *ct;
+
+       ct = nf_ct_get(skb, &ctinfo);
+       if (ct == NULL)
+               return false;
+
+       return ((ct->mark & info->mask) == info->mark) ^ info->invert;
+}
+
+static bool
+connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+               const struct net_device *out, const struct xt_match *match,
+               const void *matchinfo, int offset, unsigned int protoff,
+               bool *hotdrop)
 {
        const struct xt_connmark_info *info = matchinfo;
        const struct nf_conn *ct;
@@ -53,11 +68,9 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *ip,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+connmark_mt_check_v0(const char *tablename, const void *ip,
+                     const struct xt_match *match, void *matchinfo,
+                     unsigned int hook_mask)
 {
        const struct xt_connmark_info *cm = matchinfo;
 
@@ -67,14 +80,27 @@ checkentry(const char *tablename,
        }
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", match->family);
+                                   "proto=%u\n", match->family);
+               return false;
+       }
+       return true;
+}
+
+static bool
+connmark_mt_check(const char *tablename, const void *ip,
+                  const struct xt_match *match, void *matchinfo,
+                  unsigned int hook_mask)
+{
+       if (nf_ct_l3proto_try_module_get(match->family) < 0) {
+               printk(KERN_WARNING "cannot load conntrack support for "
+                      "proto=%u\n", match->family);
                return false;
        }
        return true;
 }
 
 static void
-destroy(const struct xt_match *match, void *matchinfo)
+connmark_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        nf_ct_l3proto_module_put(match->family);
 }
@@ -87,7 +113,7 @@ struct compat_xt_connmark_info {
        u_int16_t       __pad2;
 };
 
-static void compat_from_user(void *dst, void *src)
+static void connmark_mt_compat_from_user_v0(void *dst, void *src)
 {
        const struct compat_xt_connmark_info *cm = src;
        struct xt_connmark_info m = {
@@ -98,7 +124,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int connmark_mt_compat_to_user_v0(void __user *dst, void *src)
 {
        const struct xt_connmark_info *m = src;
        struct compat_xt_connmark_info cm = {
@@ -110,42 +136,69 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_connmark_match[] __read_mostly = {
+static struct xt_match connmark_mt_reg[] __read_mostly = {
        {
                .name           = "connmark",
+               .revision       = 0,
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = connmark_mt_check_v0,
+               .match          = connmark_mt_v0,
+               .destroy        = connmark_mt_destroy,
                .matchsize      = sizeof(struct xt_connmark_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_connmark_info),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = connmark_mt_compat_from_user_v0,
+               .compat_to_user = connmark_mt_compat_to_user_v0,
 #endif
                .me             = THIS_MODULE
        },
        {
                .name           = "connmark",
+               .revision       = 0,
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = connmark_mt_check_v0,
+               .match          = connmark_mt_v0,
+               .destroy        = connmark_mt_destroy,
                .matchsize      = sizeof(struct xt_connmark_info),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_connmark_info),
+               .compat_from_user = connmark_mt_compat_from_user_v0,
+               .compat_to_user = connmark_mt_compat_to_user_v0,
+#endif
                .me             = THIS_MODULE
        },
+       {
+               .name           = "connmark",
+               .revision       = 1,
+               .family         = AF_INET,
+               .checkentry     = connmark_mt_check,
+               .match          = connmark_mt,
+               .matchsize      = sizeof(struct xt_connmark_mtinfo1),
+               .destroy        = connmark_mt_destroy,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "connmark",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .checkentry     = connmark_mt_check,
+               .match          = connmark_mt,
+               .matchsize      = sizeof(struct xt_connmark_mtinfo1),
+               .destroy        = connmark_mt_destroy,
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_connmark_init(void)
+static int __init connmark_mt_init(void)
 {
-       return xt_register_matches(xt_connmark_match,
-                                  ARRAY_SIZE(xt_connmark_match));
+       return xt_register_matches(connmark_mt_reg,
+              ARRAY_SIZE(connmark_mt_reg));
 }
 
-static void __exit xt_connmark_fini(void)
+static void __exit connmark_mt_exit(void)
 {
-       xt_unregister_matches(xt_connmark_match, ARRAY_SIZE(xt_connmark_match));
+       xt_unregister_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg));
 }
 
-module_init(xt_connmark_init);
-module_exit(xt_connmark_fini);
+module_init(connmark_mt_init);
+module_exit(connmark_mt_exit);
index ca4b69f020a8a1eb608f395d9b82d05fb07340a5..e92190eafcc5b2cc74ed1a748a73bc7676990472 100644 (file)
@@ -1,33 +1,34 @@
-/* Kernel module to match connection tracking information.
- * Superset of Rusty's minimalistic state match.
+/*
+ *     xt_conntrack - Netfilter module to match connection tracking
+ *     information. (Superset of Rusty's minimalistic state match.)
  *
- * (C) 2001  Marc Boucher (marc@mbsi.ca).
+ *     (C) 2001  Marc Boucher (marc@mbsi.ca).
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ *     Jan Engelhardt <jengelh@computergmbh.de>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ *     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/skbuff.h>
+#include <net/ipv6.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_conntrack.h>
 #include <net/netfilter/nf_conntrack.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("iptables connection tracking match module");
+MODULE_DESCRIPTION("Xtables: connection tracking state match");
 MODULE_ALIAS("ipt_conntrack");
+MODULE_ALIAS("ip6t_conntrack");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, const struct xt_match *match,
+                const void *matchinfo, int offset, unsigned int protoff,
+                bool *hotdrop)
 {
        const struct xt_conntrack_info *sinfo = matchinfo;
        const struct nf_conn *ct;
@@ -36,7 +37,7 @@ match(const struct sk_buff *skb,
 
        ct = nf_ct_get(skb, &ctinfo);
 
-#define FWINV(bool,invflg) ((bool) ^ !!(sinfo->invflags & invflg))
+#define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & (invflg)))
 
        if (ct == &nf_conntrack_untracked)
                statebit = XT_CONNTRACK_STATE_UNTRACKED;
@@ -112,24 +113,152 @@ match(const struct sk_buff *skb,
                        return false;
        }
        return true;
+#undef FWINV
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *ip,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+conntrack_addrcmp(const union nf_inet_addr *kaddr,
+                  const union nf_inet_addr *uaddr,
+                  const union nf_inet_addr *umask, unsigned int l3proto)
+{
+       if (l3proto == AF_INET)
+               return (kaddr->ip & umask->ip) == uaddr->ip;
+       else if (l3proto == AF_INET6)
+               return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6,
+                      &uaddr->in6) == 0;
+       else
+               return false;
+}
+
+static inline bool
+conntrack_mt_origsrc(const struct nf_conn *ct,
+                     const struct xt_conntrack_mtinfo1 *info,
+                     unsigned int family)
+{
+       return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
+              &info->origsrc_addr, &info->origsrc_mask, family);
+}
+
+static inline bool
+conntrack_mt_origdst(const struct nf_conn *ct,
+                     const struct xt_conntrack_mtinfo1 *info,
+                     unsigned int family)
+{
+       return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3,
+              &info->origdst_addr, &info->origdst_mask, family);
+}
+
+static inline bool
+conntrack_mt_replsrc(const struct nf_conn *ct,
+                     const struct xt_conntrack_mtinfo1 *info,
+                     unsigned int family)
+{
+       return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3,
+              &info->replsrc_addr, &info->replsrc_mask, family);
+}
+
+static inline bool
+conntrack_mt_repldst(const struct nf_conn *ct,
+                     const struct xt_conntrack_mtinfo1 *info,
+                     unsigned int family)
+{
+       return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3,
+              &info->repldst_addr, &info->repldst_mask, family);
+}
+
+static bool
+conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
+{
+       const struct xt_conntrack_mtinfo1 *info = matchinfo;
+       enum ip_conntrack_info ctinfo;
+       const struct nf_conn *ct;
+       unsigned int statebit;
+
+       ct = nf_ct_get(skb, &ctinfo);
+
+       if (ct == &nf_conntrack_untracked)
+               statebit = XT_CONNTRACK_STATE_UNTRACKED;
+       else if (ct != NULL)
+               statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
+       else
+               statebit = XT_CONNTRACK_STATE_INVALID;
+
+       if (info->match_flags & XT_CONNTRACK_STATE) {
+               if (ct != NULL) {
+                       if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
+                               statebit |= XT_CONNTRACK_STATE_SNAT;
+                       if (test_bit(IPS_DST_NAT_BIT, &ct->status))
+                               statebit |= XT_CONNTRACK_STATE_DNAT;
+               }
+               if ((info->state_mask & statebit) ^
+                   !(info->invert_flags & XT_CONNTRACK_STATE))
+                       return false;
+       }
+
+       if (ct == NULL)
+               return info->match_flags & XT_CONNTRACK_STATE;
+
+       if ((info->match_flags & XT_CONNTRACK_PROTO) &&
+           ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
+           info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+               return false;
+
+       if (info->match_flags & XT_CONNTRACK_ORIGSRC)
+               if (conntrack_mt_origsrc(ct, info, match->family) ^
+                   !(info->invert_flags & XT_CONNTRACK_ORIGSRC))
+                       return false;
+
+       if (info->match_flags & XT_CONNTRACK_ORIGDST)
+               if (conntrack_mt_origdst(ct, info, match->family) ^
+                   !(info->invert_flags & XT_CONNTRACK_ORIGDST))
+                       return false;
+
+       if (info->match_flags & XT_CONNTRACK_REPLSRC)
+               if (conntrack_mt_replsrc(ct, info, match->family) ^
+                   !(info->invert_flags & XT_CONNTRACK_REPLSRC))
+                       return false;
+
+       if (info->match_flags & XT_CONNTRACK_REPLDST)
+               if (conntrack_mt_repldst(ct, info, match->family) ^
+                   !(info->invert_flags & XT_CONNTRACK_REPLDST))
+                       return false;
+
+       if ((info->match_flags & XT_CONNTRACK_STATUS) &&
+           (!!(info->status_mask & ct->status) ^
+           !(info->invert_flags & XT_CONNTRACK_STATUS)))
+               return false;
+
+       if (info->match_flags & XT_CONNTRACK_EXPIRES) {
+               unsigned long expires = 0;
+
+               if (timer_pending(&ct->timeout))
+                       expires = (ct->timeout.expires - jiffies) / HZ;
+               if ((expires >= info->expires_min &&
+                   expires <= info->expires_max) ^
+                   !(info->invert_flags & XT_CONNTRACK_EXPIRES))
+                       return false;
+       }
+       return true;
+}
+
+static bool
+conntrack_mt_check(const char *tablename, const void *ip,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", match->family);
+                                   "proto=%u\n", match->family);
                return false;
        }
        return true;
 }
 
-static void destroy(const struct xt_match *match, void *matchinfo)
+static void
+conntrack_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        nf_ct_l3proto_module_put(match->family);
 }
@@ -148,7 +277,7 @@ struct compat_xt_conntrack_info
        u_int8_t                        invflags;
 };
 
-static void compat_from_user(void *dst, void *src)
+static void conntrack_mt_compat_from_user_v0(void *dst, void *src)
 {
        const struct compat_xt_conntrack_info *cm = src;
        struct xt_conntrack_info m = {
@@ -165,7 +294,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src)
 {
        const struct xt_conntrack_info *m = src;
        struct compat_xt_conntrack_info cm = {
@@ -183,30 +312,54 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif
 
-static struct xt_match conntrack_match __read_mostly = {
-       .name           = "conntrack",
-       .match          = match,
-       .checkentry     = checkentry,
-       .destroy        = destroy,
-       .matchsize      = sizeof(struct xt_conntrack_info),
+static struct xt_match conntrack_mt_reg[] __read_mostly = {
+       {
+               .name       = "conntrack",
+               .revision   = 0,
+               .family     = AF_INET,
+               .match      = conntrack_mt_v0,
+               .checkentry = conntrack_mt_check,
+               .destroy    = conntrack_mt_destroy,
+               .matchsize  = sizeof(struct xt_conntrack_info),
+               .me         = THIS_MODULE,
 #ifdef CONFIG_COMPAT
-       .compatsize     = sizeof(struct compat_xt_conntrack_info),
-       .compat_from_user = compat_from_user,
-       .compat_to_user = compat_to_user,
+               .compatsize       = sizeof(struct compat_xt_conntrack_info),
+               .compat_from_user = conntrack_mt_compat_from_user_v0,
+               .compat_to_user   = conntrack_mt_compat_to_user_v0,
 #endif
-       .family         = AF_INET,
-       .me             = THIS_MODULE,
+       },
+       {
+               .name       = "conntrack",
+               .revision   = 1,
+               .family     = AF_INET,
+               .matchsize  = sizeof(struct xt_conntrack_mtinfo1),
+               .match      = conntrack_mt,
+               .checkentry = conntrack_mt_check,
+               .destroy    = conntrack_mt_destroy,
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "conntrack",
+               .revision   = 1,
+               .family     = AF_INET6,
+               .matchsize  = sizeof(struct xt_conntrack_mtinfo1),
+               .match      = conntrack_mt,
+               .checkentry = conntrack_mt_check,
+               .destroy    = conntrack_mt_destroy,
+               .me         = THIS_MODULE,
+       },
 };
 
-static int __init xt_conntrack_init(void)
+static int __init conntrack_mt_init(void)
 {
-       return xt_register_match(&conntrack_match);
+       return xt_register_matches(conntrack_mt_reg,
+              ARRAY_SIZE(conntrack_mt_reg));
 }
 
-static void __exit xt_conntrack_fini(void)
+static void __exit conntrack_mt_exit(void)
 {
-       xt_unregister_match(&conntrack_match);
+       xt_unregister_matches(conntrack_mt_reg, ARRAY_SIZE(conntrack_mt_reg));
 }
 
-module_init(xt_conntrack_init);
-module_exit(xt_conntrack_fini);
+module_init(conntrack_mt_init);
+module_exit(conntrack_mt_exit);
index c2b1b24ee335a256ece4cccc1bb6f057b759a0ae..667f45e72cd96a7e5a7a96de12974fe863e7fe0b 100644 (file)
@@ -22,7 +22,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("Match for DCCP protocol packets");
+MODULE_DESCRIPTION("Xtables: DCCP protocol packet match");
 MODULE_ALIAS("ipt_dccp");
 MODULE_ALIAS("ip6t_dccp");
 
@@ -93,14 +93,9 @@ match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+dccp_mt(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct xt_dccp_info *info = matchinfo;
        struct dccp_hdr _dh, *dh;
@@ -128,11 +123,9 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *inf,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+dccp_mt_check(const char *tablename, const void *inf,
+              const struct xt_match *match, void *matchinfo,
+              unsigned int hook_mask)
 {
        const struct xt_dccp_info *info = matchinfo;
 
@@ -141,12 +134,12 @@ checkentry(const char *tablename,
                && !(info->invflags & ~info->flags);
 }
 
-static struct xt_match xt_dccp_match[] __read_mostly = {
+static struct xt_match dccp_mt_reg[] __read_mostly = {
        {
                .name           = "dccp",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = dccp_mt_check,
+               .match          = dccp_mt,
                .matchsize      = sizeof(struct xt_dccp_info),
                .proto          = IPPROTO_DCCP,
                .me             = THIS_MODULE,
@@ -154,15 +147,15 @@ static struct xt_match xt_dccp_match[] __read_mostly = {
        {
                .name           = "dccp",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = dccp_mt_check,
+               .match          = dccp_mt,
                .matchsize      = sizeof(struct xt_dccp_info),
                .proto          = IPPROTO_DCCP,
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_dccp_init(void)
+static int __init dccp_mt_init(void)
 {
        int ret;
 
@@ -172,7 +165,7 @@ static int __init xt_dccp_init(void)
        dccp_optbuf = kmalloc(256 * 4, GFP_KERNEL);
        if (!dccp_optbuf)
                return -ENOMEM;
-       ret = xt_register_matches(xt_dccp_match, ARRAY_SIZE(xt_dccp_match));
+       ret = xt_register_matches(dccp_mt_reg, ARRAY_SIZE(dccp_mt_reg));
        if (ret)
                goto out_kfree;
        return ret;
@@ -182,11 +175,11 @@ out_kfree:
        return ret;
 }
 
-static void __exit xt_dccp_fini(void)
+static void __exit dccp_mt_exit(void)
 {
-       xt_unregister_matches(xt_dccp_match, ARRAY_SIZE(xt_dccp_match));
+       xt_unregister_matches(dccp_mt_reg, ARRAY_SIZE(dccp_mt_reg));
        kfree(dccp_optbuf);
 }
 
-module_init(xt_dccp_init);
-module_exit(xt_dccp_fini);
+module_init(dccp_mt_init);
+module_exit(dccp_mt_exit);
index dde6d66e0d338aef43cb80d85afd0b6e6ca62376..26f4aab9c42943ce4bcb7cf57bc3630ac3bdc3e1 100644 (file)
 #include <linux/ipv6.h>
 #include <net/dsfield.h>
 
-#include <linux/netfilter/xt_dscp.h>
 #include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_dscp.h>
+#include <linux/netfilter_ipv4/ipt_tos.h>
 
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("x_tables DSCP matching module");
+MODULE_DESCRIPTION("Xtables: DSCP/TOS field match");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_dscp");
 MODULE_ALIAS("ip6t_dscp");
+MODULE_ALIAS("ipt_tos");
+MODULE_ALIAS("ip6t_tos");
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 const struct xt_match *match,
-                 const void *matchinfo,
-                 int offset,
-                 unsigned int protoff,
-                 bool *hotdrop)
+static bool
+dscp_mt(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct xt_dscp_info *info = matchinfo;
        u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -37,14 +36,11 @@ static bool match(const struct sk_buff *skb,
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static bool match6(const struct sk_buff *skb,
-                  const struct net_device *in,
-                  const struct net_device *out,
-                  const struct xt_match *match,
-                  const void *matchinfo,
-                  int offset,
-                  unsigned int protoff,
-                  bool *hotdrop)
+static bool
+dscp_mt6(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        const struct xt_dscp_info *info = matchinfo;
        u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
@@ -52,11 +48,10 @@ static bool match6(const struct sk_buff *skb,
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static bool checkentry(const char *tablename,
-                      const void *info,
-                      const struct xt_match *match,
-                      void *matchinfo,
-                      unsigned int hook_mask)
+static bool
+dscp_mt_check(const char *tablename, const void *info,
+              const struct xt_match *match, void *matchinfo,
+              unsigned int hook_mask)
 {
        const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp;
 
@@ -68,34 +63,83 @@ static bool checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match xt_dscp_match[] __read_mostly = {
+static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+                      const struct net_device *out,
+                      const struct xt_match *match, const void *matchinfo,
+                      int offset, unsigned int protoff, bool *hotdrop)
+{
+       const struct ipt_tos_info *info = matchinfo;
+
+       return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
+}
+
+static bool tos_mt(const struct sk_buff *skb, const struct net_device *in,
+                   const struct net_device *out, const struct xt_match *match,
+                   const void *matchinfo, int offset, unsigned int protoff,
+                   bool *hotdrop)
+{
+       const struct xt_tos_match_info *info = matchinfo;
+
+       if (match->family == AF_INET)
+               return ((ip_hdr(skb)->tos & info->tos_mask) ==
+                      info->tos_value) ^ !!info->invert;
+       else
+               return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) ==
+                      info->tos_value) ^ !!info->invert;
+}
+
+static struct xt_match dscp_mt_reg[] __read_mostly = {
        {
                .name           = "dscp",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = dscp_mt_check,
+               .match          = dscp_mt,
                .matchsize      = sizeof(struct xt_dscp_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "dscp",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match6,
+               .checkentry     = dscp_mt_check,
+               .match          = dscp_mt6,
                .matchsize      = sizeof(struct xt_dscp_info),
                .me             = THIS_MODULE,
        },
+       {
+               .name           = "tos",
+               .revision       = 0,
+               .family         = AF_INET,
+               .match          = tos_mt_v0,
+               .matchsize      = sizeof(struct ipt_tos_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "tos",
+               .revision       = 1,
+               .family         = AF_INET,
+               .match          = tos_mt,
+               .matchsize      = sizeof(struct xt_tos_match_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "tos",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .match          = tos_mt,
+               .matchsize      = sizeof(struct xt_tos_match_info),
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_dscp_match_init(void)
+static int __init dscp_mt_init(void)
 {
-       return xt_register_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match));
+       return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg));
 }
 
-static void __exit xt_dscp_match_fini(void)
+static void __exit dscp_mt_exit(void)
 {
-       xt_unregister_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match));
+       xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg));
 }
 
-module_init(xt_dscp_match_init);
-module_exit(xt_dscp_match_fini);
+module_init(dscp_mt_init);
+module_exit(dscp_mt_exit);
index b11378e001b6acb639873491606a62e16de8217d..71c7c378526697da8ec274253e72a45e0acceb13 100644 (file)
@@ -20,7 +20,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
-MODULE_DESCRIPTION("x_tables ESP SPI match module");
+MODULE_DESCRIPTION("Xtables: IPsec-ESP packet match");
 MODULE_ALIAS("ipt_esp");
 MODULE_ALIAS("ip6t_esp");
 
@@ -43,14 +43,9 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+esp_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct ip_esp_hdr _esp, *eh;
        const struct xt_esp *espinfo = matchinfo;
@@ -75,11 +70,9 @@ match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *ip_void,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+esp_mt_check(const char *tablename, const void *ip_void,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct xt_esp *espinfo = matchinfo;
 
@@ -91,12 +84,12 @@ checkentry(const char *tablename,
        return true;
 }
 
-static struct xt_match xt_esp_match[] __read_mostly = {
+static struct xt_match esp_mt_reg[] __read_mostly = {
        {
                .name           = "esp",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = esp_mt_check,
+               .match          = esp_mt,
                .matchsize      = sizeof(struct xt_esp),
                .proto          = IPPROTO_ESP,
                .me             = THIS_MODULE,
@@ -104,23 +97,23 @@ static struct xt_match xt_esp_match[] __read_mostly = {
        {
                .name           = "esp",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = esp_mt_check,
+               .match          = esp_mt,
                .matchsize      = sizeof(struct xt_esp),
                .proto          = IPPROTO_ESP,
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_esp_init(void)
+static int __init esp_mt_init(void)
 {
-       return xt_register_matches(xt_esp_match, ARRAY_SIZE(xt_esp_match));
+       return xt_register_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
 }
 
-static void __exit xt_esp_cleanup(void)
+static void __exit esp_mt_exit(void)
 {
-       xt_unregister_matches(xt_esp_match, ARRAY_SIZE(xt_esp_match));
+       xt_unregister_matches(esp_mt_reg, ARRAY_SIZE(esp_mt_reg));
 }
 
-module_init(xt_esp_init);
-module_exit(xt_esp_cleanup);
+module_init(esp_mt_init);
+module_exit(esp_mt_exit);
index 2ef44d8560c154d944ea66e28e6505bc77c6222e..d479ca980115af614e25ef411917d7f83c4e4044 100644 (file)
 #include <linux/mm.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 #include <linux/ipv6.h>
+#include <net/ipv6.h>
+#endif
+
 #include <net/net_namespace.h>
 
 #include <linux/netfilter/x_tables.h>
@@ -31,7 +35,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("iptables match for limiting per hash-bucket");
+MODULE_DESCRIPTION("Xtables: per hash-bucket rate-limit match");
 MODULE_ALIAS("ipt_hashlimit");
 MODULE_ALIAS("ip6t_hashlimit");
 
@@ -47,10 +51,12 @@ struct dsthash_dst {
                        __be32 src;
                        __be32 dst;
                } ip;
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
                struct {
                        __be32 src[4];
                        __be32 dst[4];
                } ip6;
+#endif
        } addr;
        __be16 src_port;
        __be16 dst_port;
@@ -104,7 +110,16 @@ static inline bool dst_cmp(const struct dsthash_ent *ent,
 static u_int32_t
 hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
 {
-       return jhash(dst, sizeof(*dst), ht->rnd) % ht->cfg.size;
+       u_int32_t hash = jhash2((const u32 *)dst,
+                               sizeof(*dst)/sizeof(u32),
+                               ht->rnd);
+       /*
+        * Instead of returning hash % ht->cfg.size (implying a divide)
+        * we return the high 32 bits of the (hash * ht->cfg.size) that will
+        * give results between [0 and cfg.size-1] and same hash distribution,
+        * but using a multiply, less expensive than a divide
+        */
+       return ((u64)hash * ht->cfg.size) >> 32;
 }
 
 static struct dsthash_ent *
@@ -379,7 +394,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
                   const struct sk_buff *skb, unsigned int protoff)
 {
        __be16 _ports[2], *ports;
-       int nexthdr;
+       u8 nexthdr;
 
        memset(dst, 0, sizeof(*dst));
 
@@ -407,8 +422,9 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
                if (!(hinfo->cfg.mode &
                      (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
                        return 0;
-               nexthdr = ipv6_find_hdr(skb, &protoff, -1, NULL);
-               if (nexthdr < 0)
+               nexthdr = ipv6_hdr(skb)->nexthdr;
+               protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
+               if ((int)protoff < 0)
                        return -1;
                break;
 #endif
@@ -441,14 +457,10 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
 }
 
 static bool
-hashlimit_match(const struct sk_buff *skb,
-               const struct net_device *in,
-               const struct net_device *out,
-               const struct xt_match *match,
-               const void *matchinfo,
-               int offset,
-               unsigned int protoff,
-               bool *hotdrop)
+hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
 {
        const struct xt_hashlimit_info *r =
                ((const struct xt_hashlimit_info *)matchinfo)->u.master;
@@ -500,11 +512,9 @@ hotdrop:
 }
 
 static bool
-hashlimit_checkentry(const char *tablename,
-                    const void *inf,
-                    const struct xt_match *match,
-                    void *matchinfo,
-                    unsigned int hook_mask)
+hashlimit_mt_check(const char *tablename, const void *inf,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        struct xt_hashlimit_info *r = matchinfo;
 
@@ -548,7 +558,7 @@ hashlimit_checkentry(const char *tablename,
 }
 
 static void
-hashlimit_destroy(const struct xt_match *match, void *matchinfo)
+hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        const struct xt_hashlimit_info *r = matchinfo;
 
@@ -563,7 +573,7 @@ struct compat_xt_hashlimit_info {
        compat_uptr_t master;
 };
 
-static void compat_from_user(void *dst, void *src)
+static void hashlimit_mt_compat_from_user(void *dst, void *src)
 {
        int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
 
@@ -571,7 +581,7 @@ static void compat_from_user(void *dst, void *src)
        memset(dst + off, 0, sizeof(struct compat_xt_hashlimit_info) - off);
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int hashlimit_mt_compat_to_user(void __user *dst, void *src)
 {
        int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
 
@@ -579,35 +589,37 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif
 
-static struct xt_match xt_hashlimit[] __read_mostly = {
+static struct xt_match hashlimit_mt_reg[] __read_mostly = {
        {
                .name           = "hashlimit",
                .family         = AF_INET,
-               .match          = hashlimit_match,
+               .match          = hashlimit_mt,
                .matchsize      = sizeof(struct xt_hashlimit_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_hashlimit_info),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = hashlimit_mt_compat_from_user,
+               .compat_to_user = hashlimit_mt_compat_to_user,
 #endif
-               .checkentry     = hashlimit_checkentry,
-               .destroy        = hashlimit_destroy,
+               .checkentry     = hashlimit_mt_check,
+               .destroy        = hashlimit_mt_destroy,
                .me             = THIS_MODULE
        },
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        {
                .name           = "hashlimit",
                .family         = AF_INET6,
-               .match          = hashlimit_match,
+               .match          = hashlimit_mt,
                .matchsize      = sizeof(struct xt_hashlimit_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_hashlimit_info),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = hashlimit_mt_compat_from_user,
+               .compat_to_user = hashlimit_mt_compat_to_user,
 #endif
-               .checkentry     = hashlimit_checkentry,
-               .destroy        = hashlimit_destroy,
+               .checkentry     = hashlimit_mt_check,
+               .destroy        = hashlimit_mt_destroy,
                .me             = THIS_MODULE
        },
+#endif
 };
 
 /* PROC stuff */
@@ -670,6 +682,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        case AF_INET6:
                return seq_printf(s, "%ld " NIP6_FMT ":%u->"
                                     NIP6_FMT ":%u %u %u %u\n",
@@ -680,6 +693,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
+#endif
        default:
                BUG();
                return 0;
@@ -728,11 +742,12 @@ static const struct file_operations dl_file_ops = {
        .release = seq_release
 };
 
-static int __init xt_hashlimit_init(void)
+static int __init hashlimit_mt_init(void)
 {
        int err;
 
-       err = xt_register_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
+       err = xt_register_matches(hashlimit_mt_reg,
+             ARRAY_SIZE(hashlimit_mt_reg));
        if (err < 0)
                goto err1;
 
@@ -750,31 +765,36 @@ static int __init xt_hashlimit_init(void)
                                "entry\n");
                goto err3;
        }
+       err = 0;
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", init_net.proc_net);
        if (!hashlimit_procdir6) {
                printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
                                "entry\n");
-               goto err4;
+               err = -ENOMEM;
        }
-       return 0;
-err4:
+#endif
+       if (!err)
+               return 0;
        remove_proc_entry("ipt_hashlimit", init_net.proc_net);
 err3:
        kmem_cache_destroy(hashlimit_cachep);
 err2:
-       xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
+       xt_unregister_matches(hashlimit_mt_reg, ARRAY_SIZE(hashlimit_mt_reg));
 err1:
        return err;
 
 }
 
-static void __exit xt_hashlimit_fini(void)
+static void __exit hashlimit_mt_exit(void)
 {
        remove_proc_entry("ipt_hashlimit", init_net.proc_net);
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        remove_proc_entry("ip6t_hashlimit", init_net.proc_net);
+#endif
        kmem_cache_destroy(hashlimit_cachep);
-       xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
+       xt_unregister_matches(hashlimit_mt_reg, ARRAY_SIZE(hashlimit_mt_reg));
 }
 
-module_init(xt_hashlimit_init);
-module_exit(xt_hashlimit_fini);
+module_init(hashlimit_mt_init);
+module_exit(hashlimit_mt_exit);
index d842c4a6d63f6b97843db892dea44b36c7ac986b..dada2905d66ef445e7fa6b7659532155cf18d377 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
-MODULE_DESCRIPTION("iptables helper match module");
+MODULE_DESCRIPTION("Xtables: Related connection matching");
 MODULE_ALIAS("ipt_helper");
 MODULE_ALIAS("ip6t_helper");
 
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+helper_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct xt_helper_info *info = matchinfo;
        const struct nf_conn *ct;
@@ -61,61 +57,57 @@ match(const struct sk_buff *skb,
        return ret;
 }
 
-static bool check(const char *tablename,
-                 const void *inf,
-                 const struct xt_match *match,
-                 void *matchinfo,
-                 unsigned int hook_mask)
+static bool
+helper_mt_check(const char *tablename, const void *inf,
+                const struct xt_match *match, void *matchinfo,
+                unsigned int hook_mask)
 {
        struct xt_helper_info *info = matchinfo;
 
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", match->family);
+                                   "proto=%u\n", match->family);
                return false;
        }
        info->name[29] = '\0';
        return true;
 }
 
-static void
-destroy(const struct xt_match *match, void *matchinfo)
+static void helper_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_helper_match[] __read_mostly = {
+static struct xt_match helper_mt_reg[] __read_mostly = {
        {
                .name           = "helper",
                .family         = AF_INET,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = helper_mt_check,
+               .match          = helper_mt,
+               .destroy        = helper_mt_destroy,
                .matchsize      = sizeof(struct xt_helper_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "helper",
                .family         = AF_INET6,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = helper_mt_check,
+               .match          = helper_mt,
+               .destroy        = helper_mt_destroy,
                .matchsize      = sizeof(struct xt_helper_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_helper_init(void)
+static int __init helper_mt_init(void)
 {
-       return xt_register_matches(xt_helper_match,
-                                  ARRAY_SIZE(xt_helper_match));
+       return xt_register_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg));
 }
 
-static void __exit xt_helper_fini(void)
+static void __exit helper_mt_exit(void)
 {
-       xt_unregister_matches(xt_helper_match, ARRAY_SIZE(xt_helper_match));
+       xt_unregister_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg));
 }
 
-module_init(xt_helper_init);
-module_exit(xt_helper_fini);
-
+module_init(helper_mt_init);
+module_exit(helper_mt_exit);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
new file mode 100644 (file)
index 0000000..dbea0e0
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *     xt_iprange - Netfilter module to match IP address ranges
+ *
+ *     (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *     (C) CC Computer Consultants GmbH, 2008
+ *
+ *     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/skbuff.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_ipv4/ipt_iprange.h>
+
+static bool
+iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+              const struct net_device *out, const struct xt_match *match,
+              const void *matchinfo, int offset, unsigned int protoff,
+              bool *hotdrop)
+{
+       const struct ipt_iprange_info *info = matchinfo;
+       const struct iphdr *iph = ip_hdr(skb);
+
+       if (info->flags & IPRANGE_SRC) {
+               if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
+                         || ntohl(iph->saddr) > ntohl(info->src.max_ip))
+                        ^ !!(info->flags & IPRANGE_SRC_INV)) {
+                       pr_debug("src IP %u.%u.%u.%u NOT in range %s"
+                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
+                                NIPQUAD(iph->saddr),
+                                info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
+                                NIPQUAD(info->src.min_ip),
+                                NIPQUAD(info->src.max_ip));
+                       return false;
+               }
+       }
+       if (info->flags & IPRANGE_DST) {
+               if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
+                         || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
+                        ^ !!(info->flags & IPRANGE_DST_INV)) {
+                       pr_debug("dst IP %u.%u.%u.%u NOT in range %s"
+                                "%u.%u.%u.%u-%u.%u.%u.%u\n",
+                                NIPQUAD(iph->daddr),
+                                info->flags & IPRANGE_DST_INV ? "(INV) " : "",
+                                NIPQUAD(info->dst.min_ip),
+                                NIPQUAD(info->dst.max_ip));
+                       return false;
+               }
+       }
+       return true;
+}
+
+static bool
+iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, const struct xt_match *match,
+            const void *matchinfo, int offset, unsigned int protoff,
+            bool *hotdrop)
+{
+       const struct xt_iprange_mtinfo *info = matchinfo;
+       const struct iphdr *iph = ip_hdr(skb);
+       bool m;
+
+       if (info->flags & IPRANGE_SRC) {
+               m  = ntohl(iph->saddr) < ntohl(info->src_min.ip);
+               m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
+               m ^= info->flags & IPRANGE_SRC_INV;
+               if (m) {
+                       pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
+                                NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+                                NIPQUAD(iph->saddr),
+                                (info->flags & IPRANGE_SRC_INV) ? "(INV) " : "",
+                                NIPQUAD(info->src_max.ip),
+                                NIPQUAD(info->src_max.ip));
+                       return false;
+               }
+       }
+       if (info->flags & IPRANGE_DST) {
+               m  = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
+               m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
+               m ^= info->flags & IPRANGE_DST_INV;
+               if (m) {
+                       pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
+                                NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
+                                NIPQUAD(iph->daddr),
+                                (info->flags & IPRANGE_DST_INV) ? "(INV) " : "",
+                                NIPQUAD(info->dst_min.ip),
+                                NIPQUAD(info->dst_max.ip));
+                       return false;
+               }
+       }
+       return true;
+}
+
+static inline int
+iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
+{
+       unsigned int i;
+       int r;
+
+       for (i = 0; i < 4; ++i) {
+               r = a->s6_addr32[i] - b->s6_addr32[i];
+               if (r != 0)
+                       return r;
+       }
+
+       return 0;
+}
+
+static bool
+iprange_mt6(const struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, const struct xt_match *match,
+            const void *matchinfo, int offset, unsigned int protoff,
+            bool *hotdrop)
+{
+       const struct xt_iprange_mtinfo *info = matchinfo;
+       const struct ipv6hdr *iph = ipv6_hdr(skb);
+       bool m;
+
+       if (info->flags & IPRANGE_SRC) {
+               m  = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
+               m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
+               m ^= info->flags & IPRANGE_SRC_INV;
+               if (m)
+                       return false;
+       }
+       if (info->flags & IPRANGE_DST) {
+               m  = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
+               m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
+               m ^= info->flags & IPRANGE_DST_INV;
+               if (m)
+                       return false;
+       }
+       return true;
+}
+
+static struct xt_match iprange_mt_reg[] __read_mostly = {
+       {
+               .name      = "iprange",
+               .revision  = 0,
+               .family    = AF_INET,
+               .match     = iprange_mt_v0,
+               .matchsize = sizeof(struct ipt_iprange_info),
+               .me        = THIS_MODULE,
+       },
+       {
+               .name      = "iprange",
+               .revision  = 1,
+               .family    = AF_INET6,
+               .match     = iprange_mt4,
+               .matchsize = sizeof(struct xt_iprange_mtinfo),
+               .me        = THIS_MODULE,
+       },
+       {
+               .name      = "iprange",
+               .revision  = 1,
+               .family    = AF_INET6,
+               .match     = iprange_mt6,
+               .matchsize = sizeof(struct xt_iprange_mtinfo),
+               .me        = THIS_MODULE,
+       },
+};
+
+static int __init iprange_mt_init(void)
+{
+       return xt_register_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
+}
+
+static void __exit iprange_mt_exit(void)
+{
+       xt_unregister_matches(iprange_mt_reg, ARRAY_SIZE(iprange_mt_reg));
+}
+
+module_init(iprange_mt_init);
+module_exit(iprange_mt_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
index 3dad173d9735706608d47b01edf6006a2589c621..b8640f97295007166a27d31eb9db1d8e4255b766 100644 (file)
 #include <linux/netfilter/x_tables.h>
 
 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
-MODULE_DESCRIPTION("IP tables packet length matching module");
+MODULE_DESCRIPTION("Xtables: Packet length (Layer3,4,5) match");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_length");
 MODULE_ALIAS("ip6t_length");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+length_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct xt_length_info *info = matchinfo;
        u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
@@ -37,14 +33,10 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-match6(const struct sk_buff *skb,
-       const struct net_device *in,
-       const struct net_device *out,
-       const struct xt_match *match,
-       const void *matchinfo,
-       int offset,
-       unsigned int protoff,
-       bool *hotdrop)
+length_mt6(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protoff,
+           bool *hotdrop)
 {
        const struct xt_length_info *info = matchinfo;
        const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
@@ -53,33 +45,32 @@ match6(const struct sk_buff *skb,
        return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
 }
 
-static struct xt_match xt_length_match[] __read_mostly = {
+static struct xt_match length_mt_reg[] __read_mostly = {
        {
                .name           = "length",
                .family         = AF_INET,
-               .match          = match,
+               .match          = length_mt,
                .matchsize      = sizeof(struct xt_length_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "length",
                .family         = AF_INET6,
-               .match          = match6,
+               .match          = length_mt6,
                .matchsize      = sizeof(struct xt_length_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_length_init(void)
+static int __init length_mt_init(void)
 {
-       return xt_register_matches(xt_length_match,
-                                  ARRAY_SIZE(xt_length_match));
+       return xt_register_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
 }
 
-static void __exit xt_length_fini(void)
+static void __exit length_mt_exit(void)
 {
-       xt_unregister_matches(xt_length_match, ARRAY_SIZE(xt_length_match));
+       xt_unregister_matches(length_mt_reg, ARRAY_SIZE(length_mt_reg));
 }
 
-module_init(xt_length_init);
-module_exit(xt_length_fini);
+module_init(length_mt_init);
+module_exit(length_mt_exit);
index f263a77e57b729106a4b5948f74de7ccf566bae3..aad9ab8d2046d884ec596beb927cd481648cae93 100644 (file)
@@ -16,7 +16,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Herve Eychenne <rv@wallfire.org>");
-MODULE_DESCRIPTION("iptables rate limit match");
+MODULE_DESCRIPTION("Xtables: rate-limit match");
 MODULE_ALIAS("ipt_limit");
 MODULE_ALIAS("ip6t_limit");
 
@@ -58,14 +58,10 @@ static DEFINE_SPINLOCK(limit_lock);
 #define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
 
 static bool
-ipt_limit_match(const struct sk_buff *skb,
-               const struct net_device *in,
-               const struct net_device *out,
-               const struct xt_match *match,
-               const void *matchinfo,
-               int offset,
-               unsigned int protoff,
-               bool *hotdrop)
+limit_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        struct xt_rateinfo *r =
                ((const struct xt_rateinfo *)matchinfo)->master;
@@ -100,11 +96,9 @@ user2credits(u_int32_t user)
 }
 
 static bool
-ipt_limit_checkentry(const char *tablename,
-                    const void *inf,
-                    const struct xt_match *match,
-                    void *matchinfo,
-                    unsigned int hook_mask)
+limit_mt_check(const char *tablename, const void *inf,
+               const struct xt_match *match, void *matchinfo,
+               unsigned int hook_mask)
 {
        struct xt_rateinfo *r = matchinfo;
 
@@ -143,7 +137,7 @@ struct compat_xt_rateinfo {
 
 /* To keep the full "prev" timestamp, the upper 32 bits are stored in the
  * master pointer, which does not need to be preserved. */
-static void compat_from_user(void *dst, void *src)
+static void limit_mt_compat_from_user(void *dst, void *src)
 {
        const struct compat_xt_rateinfo *cm = src;
        struct xt_rateinfo m = {
@@ -157,7 +151,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int limit_mt_compat_to_user(void __user *dst, void *src)
 {
        const struct xt_rateinfo *m = src;
        struct compat_xt_rateinfo cm = {
@@ -173,39 +167,44 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_limit_match[] __read_mostly = {
+static struct xt_match limit_mt_reg[] __read_mostly = {
        {
                .name           = "limit",
                .family         = AF_INET,
-               .checkentry     = ipt_limit_checkentry,
-               .match          = ipt_limit_match,
+               .checkentry     = limit_mt_check,
+               .match          = limit_mt,
                .matchsize      = sizeof(struct xt_rateinfo),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_rateinfo),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = limit_mt_compat_from_user,
+               .compat_to_user = limit_mt_compat_to_user,
 #endif
                .me             = THIS_MODULE,
        },
        {
                .name           = "limit",
                .family         = AF_INET6,
-               .checkentry     = ipt_limit_checkentry,
-               .match          = ipt_limit_match,
+               .checkentry     = limit_mt_check,
+               .match          = limit_mt,
                .matchsize      = sizeof(struct xt_rateinfo),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_rateinfo),
+               .compat_from_user = limit_mt_compat_from_user,
+               .compat_to_user = limit_mt_compat_to_user,
+#endif
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_limit_init(void)
+static int __init limit_mt_init(void)
 {
-       return xt_register_matches(xt_limit_match, ARRAY_SIZE(xt_limit_match));
+       return xt_register_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg));
 }
 
-static void __exit xt_limit_fini(void)
+static void __exit limit_mt_exit(void)
 {
-       xt_unregister_matches(xt_limit_match, ARRAY_SIZE(xt_limit_match));
+       xt_unregister_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg));
 }
 
-module_init(xt_limit_init);
-module_exit(xt_limit_fini);
+module_init(limit_mt_init);
+module_exit(limit_mt_exit);
index 00490d777a0faa81209aca5a220d2651bc0153d2..b3e96a0ec1765d3618e759492aec29702e4d47cc 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("iptables mac matching module");
+MODULE_DESCRIPTION("Xtables: MAC address match");
 MODULE_ALIAS("ipt_mac");
 MODULE_ALIAS("ip6t_mac");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+mac_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
     const struct xt_mac_info *info = matchinfo;
 
@@ -44,38 +39,38 @@ match(const struct sk_buff *skb,
                ^ info->invert);
 }
 
-static struct xt_match xt_mac_match[] __read_mostly = {
+static struct xt_match mac_mt_reg[] __read_mostly = {
        {
                .name           = "mac",
                .family         = AF_INET,
-               .match          = match,
+               .match          = mac_mt,
                .matchsize      = sizeof(struct xt_mac_info),
-               .hooks          = (1 << NF_IP_PRE_ROUTING) |
-                                 (1 << NF_IP_LOCAL_IN) |
-                                 (1 << NF_IP_FORWARD),
+               .hooks          = (1 << NF_INET_PRE_ROUTING) |
+                                 (1 << NF_INET_LOCAL_IN) |
+                                 (1 << NF_INET_FORWARD),
                .me             = THIS_MODULE,
        },
        {
                .name           = "mac",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = mac_mt,
                .matchsize      = sizeof(struct xt_mac_info),
-               .hooks          = (1 << NF_IP6_PRE_ROUTING) |
-                                 (1 << NF_IP6_LOCAL_IN) |
-                                 (1 << NF_IP6_FORWARD),
+               .hooks          = (1 << NF_INET_PRE_ROUTING) |
+                                 (1 << NF_INET_LOCAL_IN) |
+                                 (1 << NF_INET_FORWARD),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_mac_init(void)
+static int __init mac_mt_init(void)
 {
-       return xt_register_matches(xt_mac_match, ARRAY_SIZE(xt_mac_match));
+       return xt_register_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg));
 }
 
-static void __exit xt_mac_fini(void)
+static void __exit mac_mt_exit(void)
 {
-       xt_unregister_matches(xt_mac_match, ARRAY_SIZE(xt_mac_match));
+       xt_unregister_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg));
 }
 
-module_init(xt_mac_init);
-module_exit(xt_mac_fini);
+module_init(mac_mt_init);
+module_exit(mac_mt_exit);
index c02a7f8f3925023aebb859d715c42588cb09512f..9f78f6120fbd4c37ba0793e0cd1e3f78e944a085 100644 (file)
@@ -1,10 +1,13 @@
-/* Kernel module to match NFMARK values. */
-
-/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+/*
+ *     xt_mark - Netfilter module to match NFMARK value
+ *
+ *     (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *     Copyright Â© CC Computer Consultants GmbH, 2007 - 2008
+ *     Jan Engelhardt <jengelh@computergmbh.de>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ *     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>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("iptables mark matching module");
+MODULE_DESCRIPTION("Xtables: packet mark match");
 MODULE_ALIAS("ipt_mark");
 MODULE_ALIAS("ip6t_mark");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+mark_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protoff,
+           bool *hotdrop)
 {
        const struct xt_mark_info *info = matchinfo;
 
@@ -35,11 +34,19 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *entry,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+mark_mt(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
+{
+       const struct xt_mark_mtinfo1 *info = matchinfo;
+
+       return ((skb->mark & info->mask) == info->mark) ^ info->invert;
+}
+
+static bool
+mark_mt_check_v0(const char *tablename, const void *entry,
+                 const struct xt_match *match, void *matchinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_mark_info *minfo = matchinfo;
 
@@ -58,7 +65,7 @@ struct compat_xt_mark_info {
        u_int16_t       __pad2;
 };
 
-static void compat_from_user(void *dst, void *src)
+static void mark_mt_compat_from_user_v0(void *dst, void *src)
 {
        const struct compat_xt_mark_info *cm = src;
        struct xt_mark_info m = {
@@ -69,7 +76,7 @@ static void compat_from_user(void *dst, void *src)
        memcpy(dst, &m, sizeof(m));
 }
 
-static int compat_to_user(void __user *dst, void *src)
+static int mark_mt_compat_to_user_v0(void __user *dst, void *src)
 {
        const struct xt_mark_info *m = src;
        struct compat_xt_mark_info cm = {
@@ -81,39 +88,62 @@ static int compat_to_user(void __user *dst, void *src)
 }
 #endif /* CONFIG_COMPAT */
 
-static struct xt_match xt_mark_match[] __read_mostly = {
+static struct xt_match mark_mt_reg[] __read_mostly = {
        {
                .name           = "mark",
+               .revision       = 0,
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = mark_mt_check_v0,
+               .match          = mark_mt_v0,
                .matchsize      = sizeof(struct xt_mark_info),
 #ifdef CONFIG_COMPAT
                .compatsize     = sizeof(struct compat_xt_mark_info),
-               .compat_from_user = compat_from_user,
-               .compat_to_user = compat_to_user,
+               .compat_from_user = mark_mt_compat_from_user_v0,
+               .compat_to_user = mark_mt_compat_to_user_v0,
 #endif
                .me             = THIS_MODULE,
        },
        {
                .name           = "mark",
+               .revision       = 0,
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = mark_mt_check_v0,
+               .match          = mark_mt_v0,
                .matchsize      = sizeof(struct xt_mark_info),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_mark_info),
+               .compat_from_user = mark_mt_compat_from_user_v0,
+               .compat_to_user = mark_mt_compat_to_user_v0,
+#endif
                .me             = THIS_MODULE,
        },
+       {
+               .name           = "mark",
+               .revision       = 1,
+               .family         = AF_INET,
+               .match          = mark_mt,
+               .matchsize      = sizeof(struct xt_mark_mtinfo1),
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "mark",
+               .revision       = 1,
+               .family         = AF_INET6,
+               .match          = mark_mt,
+               .matchsize      = sizeof(struct xt_mark_mtinfo1),
+               .me             = THIS_MODULE,
+       },
 };
 
-static int __init xt_mark_init(void)
+static int __init mark_mt_init(void)
 {
-       return xt_register_matches(xt_mark_match, ARRAY_SIZE(xt_mark_match));
+       return xt_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
 }
 
-static void __exit xt_mark_fini(void)
+static void __exit mark_mt_exit(void)
 {
-       xt_unregister_matches(xt_mark_match, ARRAY_SIZE(xt_mark_match));
+       xt_unregister_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg));
 }
 
-module_init(xt_mark_init);
-module_exit(xt_mark_fini);
+module_init(mark_mt_init);
+module_exit(mark_mt_exit);
index e8ae10284acd7e49c74b7ab544412f6ac0cf94f9..31daa8192422e21965a9106dee45c5e19b6dc3f8 100644 (file)
@@ -22,7 +22,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("x_tables multiple port match module");
+MODULE_DESCRIPTION("Xtables: multiple port matching for TCP, UDP, UDP-Lite, SCTP and DCCP");
 MODULE_ALIAS("ipt_multiport");
 MODULE_ALIAS("ip6t_multiport");
 
@@ -34,8 +34,8 @@ MODULE_ALIAS("ip6t_multiport");
 
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
 static inline bool
-ports_match(const u_int16_t *portlist, enum xt_multiport_flags flags,
-           u_int8_t count, u_int16_t src, u_int16_t dst)
+ports_match_v0(const u_int16_t *portlist, enum xt_multiport_flags flags,
+              u_int8_t count, u_int16_t src, u_int16_t dst)
 {
        unsigned int i;
        for (i = 0; i < count; i++) {
@@ -95,14 +95,10 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+                const struct net_device *out, const struct xt_match *match,
+                const void *matchinfo, int offset, unsigned int protoff,
+                bool *hotdrop)
 {
        __be16 _ports[2], *pptr;
        const struct xt_multiport *multiinfo = matchinfo;
@@ -120,20 +116,15 @@ match(const struct sk_buff *skb,
                return false;
        }
 
-       return ports_match(multiinfo->ports,
-                          multiinfo->flags, multiinfo->count,
-                          ntohs(pptr[0]), ntohs(pptr[1]));
+       return ports_match_v0(multiinfo->ports, multiinfo->flags,
+              multiinfo->count, ntohs(pptr[0]), ntohs(pptr[1]));
 }
 
 static bool
-match_v1(const struct sk_buff *skb,
-        const struct net_device *in,
-        const struct net_device *out,
-        const struct xt_match *match,
-        const void *matchinfo,
-        int offset,
-        unsigned int protoff,
-        bool *hotdrop)
+multiport_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
 {
        __be16 _ports[2], *pptr;
        const struct xt_multiport_v1 *multiinfo = matchinfo;
@@ -173,11 +164,9 @@ check(u_int16_t proto,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-checkentry(const char *tablename,
-          const void *info,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+multiport_mt_check_v0(const char *tablename, const void *info,
+                      const struct xt_match *match, void *matchinfo,
+                      unsigned int hook_mask)
 {
        const struct ipt_ip *ip = info;
        const struct xt_multiport *multiinfo = matchinfo;
@@ -187,11 +176,9 @@ checkentry(const char *tablename,
 }
 
 static bool
-checkentry_v1(const char *tablename,
-             const void *info,
-             const struct xt_match *match,
-             void *matchinfo,
-             unsigned int hook_mask)
+multiport_mt_check(const char *tablename, const void *info,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        const struct ipt_ip *ip = info;
        const struct xt_multiport_v1 *multiinfo = matchinfo;
@@ -201,11 +188,9 @@ checkentry_v1(const char *tablename,
 }
 
 static bool
-checkentry6(const char *tablename,
-           const void *info,
-           const struct xt_match *match,
-           void *matchinfo,
-           unsigned int hook_mask)
+multiport_mt6_check_v0(const char *tablename, const void *info,
+                       const struct xt_match *match, void *matchinfo,
+                       unsigned int hook_mask)
 {
        const struct ip6t_ip6 *ip = info;
        const struct xt_multiport *multiinfo = matchinfo;
@@ -215,11 +200,9 @@ checkentry6(const char *tablename,
 }
 
 static bool
-checkentry6_v1(const char *tablename,
-              const void *info,
-              const struct xt_match *match,
-              void *matchinfo,
-              unsigned int hook_mask)
+multiport_mt6_check(const char *tablename, const void *info,
+                    const struct xt_match *match, void *matchinfo,
+                    unsigned int hook_mask)
 {
        const struct ip6t_ip6 *ip = info;
        const struct xt_multiport_v1 *multiinfo = matchinfo;
@@ -228,13 +211,13 @@ checkentry6_v1(const char *tablename,
                     multiinfo->count);
 }
 
-static struct xt_match xt_multiport_match[] __read_mostly = {
+static struct xt_match multiport_mt_reg[] __read_mostly = {
        {
                .name           = "multiport",
                .family         = AF_INET,
                .revision       = 0,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = multiport_mt_check_v0,
+               .match          = multiport_mt_v0,
                .matchsize      = sizeof(struct xt_multiport),
                .me             = THIS_MODULE,
        },
@@ -242,8 +225,8 @@ static struct xt_match xt_multiport_match[] __read_mostly = {
                .name           = "multiport",
                .family         = AF_INET,
                .revision       = 1,
-               .checkentry     = checkentry_v1,
-               .match          = match_v1,
+               .checkentry     = multiport_mt_check,
+               .match          = multiport_mt,
                .matchsize      = sizeof(struct xt_multiport_v1),
                .me             = THIS_MODULE,
        },
@@ -251,8 +234,8 @@ static struct xt_match xt_multiport_match[] __read_mostly = {
                .name           = "multiport",
                .family         = AF_INET6,
                .revision       = 0,
-               .checkentry     = checkentry6,
-               .match          = match,
+               .checkentry     = multiport_mt6_check_v0,
+               .match          = multiport_mt_v0,
                .matchsize      = sizeof(struct xt_multiport),
                .me             = THIS_MODULE,
        },
@@ -260,24 +243,23 @@ static struct xt_match xt_multiport_match[] __read_mostly = {
                .name           = "multiport",
                .family         = AF_INET6,
                .revision       = 1,
-               .checkentry     = checkentry6_v1,
-               .match          = match_v1,
+               .checkentry     = multiport_mt6_check,
+               .match          = multiport_mt,
                .matchsize      = sizeof(struct xt_multiport_v1),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_multiport_init(void)
+static int __init multiport_mt_init(void)
 {
-       return xt_register_matches(xt_multiport_match,
-                                  ARRAY_SIZE(xt_multiport_match));
+       return xt_register_matches(multiport_mt_reg,
+              ARRAY_SIZE(multiport_mt_reg));
 }
 
-static void __exit xt_multiport_fini(void)
+static void __exit multiport_mt_exit(void)
 {
-       xt_unregister_matches(xt_multiport_match,
-                             ARRAY_SIZE(xt_multiport_match));
+       xt_unregister_matches(multiport_mt_reg, ARRAY_SIZE(multiport_mt_reg));
 }
 
-module_init(xt_multiport_init);
-module_exit(xt_multiport_fini);
+module_init(multiport_mt_init);
+module_exit(multiport_mt_exit);
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
new file mode 100644 (file)
index 0000000..d382f9c
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Kernel module to match various things tied to sockets associated with
+ * locally generated outgoing packets.
+ *
+ * (C) 2000 Marc Boucher <marc@mbsi.ca>
+ *
+ * Copyright Â© CC Computer Consultants GmbH, 2007
+ * Contact: <jengelh@computergmbh.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/file.h>
+#include <net/sock.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_owner.h>
+#include <linux/netfilter_ipv4/ipt_owner.h>
+#include <linux/netfilter_ipv6/ip6t_owner.h>
+
+static bool
+owner_mt_v0(const struct sk_buff *skb, const struct net_device *in,
+            const struct net_device *out, const struct xt_match *match,
+            const void *matchinfo, int offset, unsigned int protoff,
+            bool *hotdrop)
+{
+       const struct ipt_owner_info *info = matchinfo;
+       const struct file *filp;
+
+       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+               return false;
+
+       filp = skb->sk->sk_socket->file;
+       if (filp == NULL)
+               return false;
+
+       if (info->match & IPT_OWNER_UID)
+               if ((filp->f_uid != info->uid) ^
+                   !!(info->invert & IPT_OWNER_UID))
+                       return false;
+
+       if (info->match & IPT_OWNER_GID)
+               if ((filp->f_gid != info->gid) ^
+                   !!(info->invert & IPT_OWNER_GID))
+                       return false;
+
+       return true;
+}
+
+static bool
+owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
+{
+       const struct ip6t_owner_info *info = matchinfo;
+       const struct file *filp;
+
+       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+               return false;
+
+       filp = skb->sk->sk_socket->file;
+       if (filp == NULL)
+               return false;
+
+       if (info->match & IP6T_OWNER_UID)
+               if ((filp->f_uid != info->uid) ^
+                   !!(info->invert & IP6T_OWNER_UID))
+                       return false;
+
+       if (info->match & IP6T_OWNER_GID)
+               if ((filp->f_gid != info->gid) ^
+                   !!(info->invert & IP6T_OWNER_GID))
+                       return false;
+
+       return true;
+}
+
+static bool
+owner_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
+{
+       const struct xt_owner_match_info *info = matchinfo;
+       const struct file *filp;
+
+       if (skb->sk == NULL || skb->sk->sk_socket == NULL)
+               return (info->match ^ info->invert) == 0;
+       else if (info->match & info->invert & XT_OWNER_SOCKET)
+               /*
+                * Socket exists but user wanted ! --socket-exists.
+                * (Single ampersands intended.)
+                */
+               return false;
+
+       filp = skb->sk->sk_socket->file;
+       if (filp == NULL)
+               return ((info->match ^ info->invert) &
+                      (XT_OWNER_UID | XT_OWNER_GID)) == 0;
+
+       if (info->match & XT_OWNER_UID)
+               if ((filp->f_uid != info->uid) ^
+                   !!(info->invert & XT_OWNER_UID))
+                       return false;
+
+       if (info->match & XT_OWNER_GID)
+               if ((filp->f_gid != info->gid) ^
+                   !!(info->invert & XT_OWNER_GID))
+                       return false;
+
+       return true;
+}
+
+static bool
+owner_mt_check_v0(const char *tablename, const void *ip,
+                  const struct xt_match *match, void *matchinfo,
+                  unsigned int hook_mask)
+{
+       const struct ipt_owner_info *info = matchinfo;
+
+       if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
+               printk(KERN_WARNING KBUILD_MODNAME
+                      ": PID, SID and command matching is not "
+                      "supported anymore\n");
+               return false;
+       }
+
+       return true;
+}
+
+static bool
+owner_mt6_check_v0(const char *tablename, const void *ip,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
+{
+       const struct ip6t_owner_info *info = matchinfo;
+
+       if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
+               printk(KERN_WARNING KBUILD_MODNAME
+                      ": PID and SID matching is not supported anymore\n");
+               return false;
+       }
+
+       return true;
+}
+
+static struct xt_match owner_mt_reg[] __read_mostly = {
+       {
+               .name       = "owner",
+               .revision   = 0,
+               .family     = AF_INET,
+               .match      = owner_mt_v0,
+               .matchsize  = sizeof(struct ipt_owner_info),
+               .checkentry = owner_mt_check_v0,
+               .hooks      = (1 << NF_INET_LOCAL_OUT) |
+                             (1 << NF_INET_POST_ROUTING),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "owner",
+               .revision   = 0,
+               .family     = AF_INET6,
+               .match      = owner_mt6_v0,
+               .matchsize  = sizeof(struct ip6t_owner_info),
+               .checkentry = owner_mt6_check_v0,
+               .hooks      = (1 << NF_INET_LOCAL_OUT) |
+                             (1 << NF_INET_POST_ROUTING),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "owner",
+               .revision   = 1,
+               .family     = AF_INET,
+               .match      = owner_mt,
+               .matchsize  = sizeof(struct xt_owner_match_info),
+               .hooks      = (1 << NF_INET_LOCAL_OUT) |
+                             (1 << NF_INET_POST_ROUTING),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "owner",
+               .revision   = 1,
+               .family     = AF_INET6,
+               .match      = owner_mt,
+               .matchsize  = sizeof(struct xt_owner_match_info),
+               .hooks      = (1 << NF_INET_LOCAL_OUT) |
+                             (1 << NF_INET_POST_ROUTING),
+               .me         = THIS_MODULE,
+       },
+};
+
+static int __init owner_mt_init(void)
+{
+       return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+}
+
+static void __exit owner_mt_exit(void)
+{
+       xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg));
+}
+
+module_init(owner_mt_init);
+module_exit(owner_mt_exit);
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_DESCRIPTION("Xtables: socket owner matching");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_owner");
+MODULE_ALIAS("ip6t_owner");
index a4bab043a6d1b185122a108ec3ae27fa6b776db6..4ec1094bda929771fbe13e403f3fcb98e0fa2b8e 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
-MODULE_DESCRIPTION("iptables bridge physical device match module");
+MODULE_DESCRIPTION("Xtables: Bridge physical device match");
 MODULE_ALIAS("ipt_physdev");
 MODULE_ALIAS("ip6t_physdev");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+physdev_mt(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protoff,
+           bool *hotdrop)
 {
        int i;
        static const char nulldevname[IFNAMSIZ];
@@ -99,11 +95,9 @@ match_outdev:
 }
 
 static bool
-checkentry(const char *tablename,
-                      const void *ip,
-                      const struct xt_match *match,
-                      void *matchinfo,
-                      unsigned int hook_mask)
+physdev_mt_check(const char *tablename, const void *ip,
+                 const struct xt_match *match, void *matchinfo,
+                 unsigned int hook_mask)
 {
        const struct xt_physdev_info *info = matchinfo;
 
@@ -113,46 +107,45 @@ checkentry(const char *tablename,
        if (info->bitmask & XT_PHYSDEV_OP_OUT &&
            (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
-           hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
-                        (1 << NF_IP_POST_ROUTING))) {
+           hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
+                        (1 << NF_INET_POST_ROUTING))) {
                printk(KERN_WARNING "physdev match: using --physdev-out in the "
                       "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
                       "traffic is not supported anymore.\n");
-               if (hook_mask & (1 << NF_IP_LOCAL_OUT))
+               if (hook_mask & (1 << NF_INET_LOCAL_OUT))
                        return false;
        }
        return true;
 }
 
-static struct xt_match xt_physdev_match[] __read_mostly = {
+static struct xt_match physdev_mt_reg[] __read_mostly = {
        {
                .name           = "physdev",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = physdev_mt_check,
+               .match          = physdev_mt,
                .matchsize      = sizeof(struct xt_physdev_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "physdev",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = physdev_mt_check,
+               .match          = physdev_mt,
                .matchsize      = sizeof(struct xt_physdev_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_physdev_init(void)
+static int __init physdev_mt_init(void)
 {
-       return xt_register_matches(xt_physdev_match,
-                                  ARRAY_SIZE(xt_physdev_match));
+       return xt_register_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg));
 }
 
-static void __exit xt_physdev_fini(void)
+static void __exit physdev_mt_exit(void)
 {
-       xt_unregister_matches(xt_physdev_match, ARRAY_SIZE(xt_physdev_match));
+       xt_unregister_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg));
 }
 
-module_init(xt_physdev_init);
-module_exit(xt_physdev_fini);
+module_init(physdev_mt_init);
+module_exit(physdev_mt_exit);
index a52925f12f35e58ec25188130e63be13edf623a4..7936f7e23254bcfdaf1a8a867f9bf9b41129c8a9 100644 (file)
 #include <linux/if_packet.h>
 #include <linux/in.h>
 #include <linux/ip.h>
+#include <linux/ipv6.h>
 
 #include <linux/netfilter/xt_pkttype.h>
 #include <linux/netfilter/x_tables.h>
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Michal Ludvig <michal@logix.cz>");
-MODULE_DESCRIPTION("IP tables match to match on linklayer packet type");
+MODULE_DESCRIPTION("Xtables: link layer packet type match");
 MODULE_ALIAS("ipt_pkttype");
 MODULE_ALIAS("ip6t_pkttype");
 
-static bool match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+static bool
+pkttype_mt(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protoff,
+           bool *hotdrop)
 {
-       u_int8_t type;
        const struct xt_pkttype_info *info = matchinfo;
+       u_int8_t type;
 
-       if (skb->pkt_type == PACKET_LOOPBACK)
-               type = MULTICAST(ip_hdr(skb)->daddr)
-                       ? PACKET_MULTICAST
-                       : PACKET_BROADCAST;
-       else
+       if (skb->pkt_type != PACKET_LOOPBACK)
                type = skb->pkt_type;
+       else if (match->family == AF_INET &&
+           ipv4_is_multicast(ip_hdr(skb)->daddr))
+               type = PACKET_MULTICAST;
+       else if (match->family == AF_INET6 &&
+           ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
+               type = PACKET_MULTICAST;
+       else
+               type = PACKET_BROADCAST;
 
        return (type == info->pkttype) ^ info->invert;
 }
 
-static struct xt_match xt_pkttype_match[] __read_mostly = {
+static struct xt_match pkttype_mt_reg[] __read_mostly = {
        {
                .name           = "pkttype",
                .family         = AF_INET,
-               .match          = match,
+               .match          = pkttype_mt,
                .matchsize      = sizeof(struct xt_pkttype_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "pkttype",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = pkttype_mt,
                .matchsize      = sizeof(struct xt_pkttype_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_pkttype_init(void)
+static int __init pkttype_mt_init(void)
 {
-       return xt_register_matches(xt_pkttype_match,
-                                  ARRAY_SIZE(xt_pkttype_match));
+       return xt_register_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg));
 }
 
-static void __exit xt_pkttype_fini(void)
+static void __exit pkttype_mt_exit(void)
 {
-       xt_unregister_matches(xt_pkttype_match, ARRAY_SIZE(xt_pkttype_match));
+       xt_unregister_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg));
 }
 
-module_init(xt_pkttype_init);
-module_exit(xt_pkttype_fini);
+module_init(pkttype_mt_init);
+module_exit(pkttype_mt_exit);
index 6d6d3b7fcbb5c18b88f8021a8c096debcceffe86..9e918add2282943632476f501e8a473884183fe8 100644 (file)
 #include <linux/init.h>
 #include <net/xfrm.h>
 
+#include <linux/netfilter.h>
 #include <linux/netfilter/xt_policy.h>
 #include <linux/netfilter/x_tables.h>
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_DESCRIPTION("Xtables IPsec policy matching module");
+MODULE_DESCRIPTION("Xtables: IPsec policy match");
 MODULE_LICENSE("GPL");
 
 static inline bool
-xt_addr_cmp(const union xt_policy_addr *a1, const union xt_policy_addr *m,
-           const union xt_policy_addr *a2, unsigned short family)
+xt_addr_cmp(const union nf_inet_addr *a1, const union nf_inet_addr *m,
+           const union nf_inet_addr *a2, unsigned short family)
 {
        switch (family) {
        case AF_INET:
-               return !((a1->a4.s_addr ^ a2->a4.s_addr) & m->a4.s_addr);
+               return ((a1->ip ^ a2->ip) & m->ip) == 0;
        case AF_INET6:
-               return !ipv6_masked_addr_cmp(&a1->a6, &m->a6, &a2->a6);
+               return ipv6_masked_addr_cmp(&a1->in6, &m->in6, &a2->in6) == 0;
        }
        return false;
 }
 
-static inline bool
+static bool
 match_xfrm_state(const struct xfrm_state *x, const struct xt_policy_elem *e,
                 unsigned short family)
 {
 #define MATCH_ADDR(x,y,z)      (!e->match.x ||                        \
-                                (xt_addr_cmp(&e->x, &e->y, z, family) \
+                                (xt_addr_cmp(&e->x, &e->y, (const union nf_inet_addr *)(z), family) \
                                  ^ e->invert.x))
 #define MATCH(x,y)             (!e->match.x || ((e->x == (y)) ^ e->invert.x))
 
-       return MATCH_ADDR(saddr, smask, (union xt_policy_addr *)&x->props.saddr) &&
-              MATCH_ADDR(daddr, dmask, (union xt_policy_addr *)&x->id.daddr) &&
+       return MATCH_ADDR(saddr, smask, &x->props.saddr) &&
+              MATCH_ADDR(daddr, dmask, &x->id.daddr) &&
               MATCH(proto, x->id.proto) &&
               MATCH(mode, x->props.mode) &&
               MATCH(spi, x->id.spi) &&
@@ -108,14 +109,11 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
        return strict ? i == info->len : 0;
 }
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 const struct xt_match *match,
-                 const void *matchinfo,
-                 int offset,
-                 unsigned int protoff,
-                 bool *hotdrop)
+static bool
+policy_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct xt_policy_info *info = matchinfo;
        int ret;
@@ -133,9 +131,10 @@ static bool match(const struct sk_buff *skb,
        return ret;
 }
 
-static bool checkentry(const char *tablename, const void *ip_void,
-                      const struct xt_match *match,
-                      void *matchinfo, unsigned int hook_mask)
+static bool
+policy_mt_check(const char *tablename, const void *ip_void,
+                const struct xt_match *match, void *matchinfo,
+                unsigned int hook_mask)
 {
        struct xt_policy_info *info = matchinfo;
 
@@ -144,14 +143,13 @@ static bool checkentry(const char *tablename, const void *ip_void,
                                "outgoing policy selected\n");
                return false;
        }
-       /* hook values are equal for IPv4 and IPv6 */
-       if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+       if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN)
            && info->flags & XT_POLICY_MATCH_OUT) {
                printk(KERN_ERR "xt_policy: output policy not valid in "
                                "PRE_ROUTING and INPUT\n");
                return false;
        }
-       if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+       if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT)
            && info->flags & XT_POLICY_MATCH_IN) {
                printk(KERN_ERR "xt_policy: input policy not valid in "
                                "POST_ROUTING and OUTPUT\n");
@@ -164,37 +162,36 @@ static bool checkentry(const char *tablename, const void *ip_void,
        return true;
 }
 
-static struct xt_match xt_policy_match[] __read_mostly = {
+static struct xt_match policy_mt_reg[] __read_mostly = {
        {
                .name           = "policy",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = policy_mt_check,
+               .match          = policy_mt,
                .matchsize      = sizeof(struct xt_policy_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "policy",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = policy_mt_check,
+               .match          = policy_mt,
                .matchsize      = sizeof(struct xt_policy_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init init(void)
+static int __init policy_mt_init(void)
 {
-       return xt_register_matches(xt_policy_match,
-                                  ARRAY_SIZE(xt_policy_match));
+       return xt_register_matches(policy_mt_reg, ARRAY_SIZE(policy_mt_reg));
 }
 
-static void __exit fini(void)
+static void __exit policy_mt_exit(void)
 {
-       xt_unregister_matches(xt_policy_match, ARRAY_SIZE(xt_policy_match));
+       xt_unregister_matches(policy_mt_reg, ARRAY_SIZE(policy_mt_reg));
 }
 
-module_init(init);
-module_exit(fini);
+module_init(policy_mt_init);
+module_exit(policy_mt_exit);
 MODULE_ALIAS("ipt_policy");
 MODULE_ALIAS("ip6t_policy");
index dae97445b87b498f7e9d770dad26488485d15123..3b021d0c522ab938c6b28c1b8052fddd4e2de49f 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Sam Johnston <samj@samj.net>");
+MODULE_DESCRIPTION("Xtables: countdown quota match");
 MODULE_ALIAS("ipt_quota");
 MODULE_ALIAS("ip6t_quota");
 
 static DEFINE_SPINLOCK(quota_lock);
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in, const struct net_device *out,
-      const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, bool *hotdrop)
+quota_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        struct xt_quota_info *q =
                ((const struct xt_quota_info *)matchinfo)->master;
@@ -40,9 +41,9 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename, const void *entry,
-          const struct xt_match *match, void *matchinfo,
-          unsigned int hook_mask)
+quota_mt_check(const char *tablename, const void *entry,
+               const struct xt_match *match, void *matchinfo,
+               unsigned int hook_mask)
 {
        struct xt_quota_info *q = matchinfo;
 
@@ -53,34 +54,34 @@ checkentry(const char *tablename, const void *entry,
        return true;
 }
 
-static struct xt_match xt_quota_match[] __read_mostly = {
+static struct xt_match quota_mt_reg[] __read_mostly = {
        {
                .name           = "quota",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = quota_mt_check,
+               .match          = quota_mt,
                .matchsize      = sizeof(struct xt_quota_info),
                .me             = THIS_MODULE
        },
        {
                .name           = "quota",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = quota_mt_check,
+               .match          = quota_mt,
                .matchsize      = sizeof(struct xt_quota_info),
                .me             = THIS_MODULE
        },
 };
 
-static int __init xt_quota_init(void)
+static int __init quota_mt_init(void)
 {
-       return xt_register_matches(xt_quota_match, ARRAY_SIZE(xt_quota_match));
+       return xt_register_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg));
 }
 
-static void __exit xt_quota_fini(void)
+static void __exit quota_mt_exit(void)
 {
-       xt_unregister_matches(xt_quota_match, ARRAY_SIZE(xt_quota_match));
+       xt_unregister_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg));
 }
 
-module_init(xt_quota_init);
-module_exit(xt_quota_fini);
+module_init(quota_mt_init);
+module_exit(quota_mt_exit);
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
new file mode 100644 (file)
index 0000000..fdb86a5
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * (C) 2007 Patrick McHardy <kaber@trash.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/module.h>
+#include <linux/skbuff.h>
+#include <linux/gen_stats.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_rateest.h>
+#include <net/netfilter/xt_rateest.h>
+
+
+static bool xt_rateest_mt(const struct sk_buff *skb,
+                         const struct net_device *in,
+                         const struct net_device *out,
+                         const struct xt_match *match,
+                         const void *matchinfo,
+                         int offset,
+                         unsigned int protoff,
+                         bool *hotdrop)
+{
+       const struct xt_rateest_match_info *info = matchinfo;
+       struct gnet_stats_rate_est *r;
+       u_int32_t bps1, bps2, pps1, pps2;
+       bool ret = true;
+
+       spin_lock_bh(&info->est1->lock);
+       r = &info->est1->rstats;
+       if (info->flags & XT_RATEEST_MATCH_DELTA) {
+               bps1 = info->bps1 >= r->bps ? info->bps1 - r->bps : 0;
+               pps1 = info->pps1 >= r->pps ? info->pps1 - r->pps : 0;
+       } else {
+               bps1 = r->bps;
+               pps1 = r->pps;
+       }
+       spin_unlock_bh(&info->est1->lock);
+
+       if (info->flags & XT_RATEEST_MATCH_ABS) {
+               bps2 = info->bps2;
+               pps2 = info->pps2;
+       } else {
+               spin_lock_bh(&info->est2->lock);
+               r = &info->est2->rstats;
+               if (info->flags & XT_RATEEST_MATCH_DELTA) {
+                       bps2 = info->bps2 >= r->bps ? info->bps2 - r->bps : 0;
+                       pps2 = info->pps2 >= r->pps ? info->pps2 - r->pps : 0;
+               } else {
+                       bps2 = r->bps;
+                       pps2 = r->pps;
+               }
+               spin_unlock_bh(&info->est2->lock);
+       }
+
+       switch (info->mode) {
+       case XT_RATEEST_MATCH_LT:
+               if (info->flags & XT_RATEEST_MATCH_BPS)
+                       ret &= bps1 < bps2;
+               if (info->flags & XT_RATEEST_MATCH_PPS)
+                       ret &= pps1 < pps2;
+               break;
+       case XT_RATEEST_MATCH_GT:
+               if (info->flags & XT_RATEEST_MATCH_BPS)
+                       ret &= bps1 > bps2;
+               if (info->flags & XT_RATEEST_MATCH_PPS)
+                       ret &= pps1 > pps2;
+               break;
+       case XT_RATEEST_MATCH_EQ:
+               if (info->flags & XT_RATEEST_MATCH_BPS)
+                       ret &= bps1 == bps2;
+               if (info->flags & XT_RATEEST_MATCH_PPS)
+                       ret &= pps2 == pps2;
+               break;
+       }
+
+       ret ^= info->flags & XT_RATEEST_MATCH_INVERT ? true : false;
+       return ret;
+}
+
+static bool xt_rateest_mt_checkentry(const char *tablename,
+                                    const void *ip,
+                                    const struct xt_match *match,
+                                    void *matchinfo,
+                                    unsigned int hook_mask)
+{
+       struct xt_rateest_match_info *info = (void *)matchinfo;
+       struct xt_rateest *est1, *est2;
+
+       if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
+                                    XT_RATEEST_MATCH_REL)) != 1)
+               goto err1;
+
+       if (!(info->flags & (XT_RATEEST_MATCH_BPS | XT_RATEEST_MATCH_PPS)))
+               goto err1;
+
+       switch (info->mode) {
+       case XT_RATEEST_MATCH_EQ:
+       case XT_RATEEST_MATCH_LT:
+       case XT_RATEEST_MATCH_GT:
+               break;
+       default:
+               goto err1;
+       }
+
+       est1 = xt_rateest_lookup(info->name1);
+       if (!est1)
+               goto err1;
+
+       if (info->flags & XT_RATEEST_MATCH_REL) {
+               est2 = xt_rateest_lookup(info->name2);
+               if (!est2)
+                       goto err2;
+       } else
+               est2 = NULL;
+
+
+       info->est1 = est1;
+       info->est2 = est2;
+       return true;
+
+err2:
+       xt_rateest_put(est1);
+err1:
+       return false;
+}
+
+static void xt_rateest_mt_destroy(const struct xt_match *match,
+                                 void *matchinfo)
+{
+       struct xt_rateest_match_info *info = (void *)matchinfo;
+
+       xt_rateest_put(info->est1);
+       if (info->est2)
+               xt_rateest_put(info->est2);
+}
+
+static struct xt_match xt_rateest_match[] __read_mostly = {
+       {
+               .family         = AF_INET,
+               .name           = "rateest",
+               .match          = xt_rateest_mt,
+               .checkentry     = xt_rateest_mt_checkentry,
+               .destroy        = xt_rateest_mt_destroy,
+               .matchsize      = sizeof(struct xt_rateest_match_info),
+               .me             = THIS_MODULE,
+       },
+       {
+               .family         = AF_INET6,
+               .name           = "rateest",
+               .match          = xt_rateest_mt,
+               .checkentry     = xt_rateest_mt_checkentry,
+               .destroy        = xt_rateest_mt_destroy,
+               .matchsize      = sizeof(struct xt_rateest_match_info),
+               .me             = THIS_MODULE,
+       },
+};
+
+static int __init xt_rateest_mt_init(void)
+{
+       return xt_register_matches(xt_rateest_match,
+                                  ARRAY_SIZE(xt_rateest_match));
+}
+
+static void __exit xt_rateest_mt_fini(void)
+{
+       xt_unregister_matches(xt_rateest_match, ARRAY_SIZE(xt_rateest_match));
+}
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("xtables rate estimator match");
+MODULE_ALIAS("ipt_rateest");
+MODULE_ALIAS("ip6t_rateest");
+module_init(xt_rateest_mt_init);
+module_exit(xt_rateest_mt_fini);
index cc3e76d77a9931f7f697188967465b78d998748b..7df1627c536f27a350010948a2d2778c6d03639d 100644 (file)
 
 MODULE_AUTHOR("Sampsa Ranta <sampsa@netsonic.fi>");
 MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("X_tables realm match");
+MODULE_DESCRIPTION("Xtables: Routing realm match");
 MODULE_ALIAS("ipt_realm");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+realm_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        const struct xt_realm_info *info = matchinfo;
        const struct dst_entry *dst = skb->dst;
@@ -37,25 +33,25 @@ match(const struct sk_buff *skb,
        return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
 }
 
-static struct xt_match realm_match __read_mostly = {
+static struct xt_match realm_mt_reg __read_mostly = {
        .name           = "realm",
-       .match          = match,
+       .match          = realm_mt,
        .matchsize      = sizeof(struct xt_realm_info),
-       .hooks          = (1 << NF_IP_POST_ROUTING) | (1 << NF_IP_FORWARD) |
-                         (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_LOCAL_IN),
+       .hooks          = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) |
+                         (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN),
        .family         = AF_INET,
        .me             = THIS_MODULE
 };
 
-static int __init xt_realm_init(void)
+static int __init realm_mt_init(void)
 {
-       return xt_register_match(&realm_match);
+       return xt_register_match(&realm_mt_reg);
 }
 
-static void __exit xt_realm_fini(void)
+static void __exit realm_mt_exit(void)
 {
-       xt_unregister_match(&realm_match);
+       xt_unregister_match(&realm_mt_reg);
 }
 
-module_init(xt_realm_init);
-module_exit(xt_realm_fini);
+module_init(realm_mt_init);
+module_exit(realm_mt_exit);
index 3358273a47b78f6567396de97619dab08a403ec6..b718ec64333d285f772fe40cfc9ce7bef7bb70d0 100644 (file)
@@ -11,7 +11,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Kiran Kumar Immidi");
-MODULE_DESCRIPTION("Match for SCTP protocol packets");
+MODULE_DESCRIPTION("Xtables: SCTP protocol packet match");
 MODULE_ALIAS("ipt_sctp");
 MODULE_ALIAS("ip6t_sctp");
 
@@ -116,14 +116,9 @@ match_packet(const struct sk_buff *skb,
 }
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+sctp_mt(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct xt_sctp_info *info = matchinfo;
        sctp_sctphdr_t _sh, *sh;
@@ -153,11 +148,9 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename,
-          const void *inf,
-          const struct xt_match *match,
-          void *matchinfo,
-          unsigned int hook_mask)
+sctp_mt_check(const char *tablename, const void *inf,
+              const struct xt_match *match, void *matchinfo,
+              unsigned int hook_mask)
 {
        const struct xt_sctp_info *info = matchinfo;
 
@@ -171,12 +164,12 @@ checkentry(const char *tablename,
                                | SCTP_CHUNK_MATCH_ONLY)));
 }
 
-static struct xt_match xt_sctp_match[] __read_mostly = {
+static struct xt_match sctp_mt_reg[] __read_mostly = {
        {
                .name           = "sctp",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = sctp_mt_check,
+               .match          = sctp_mt,
                .matchsize      = sizeof(struct xt_sctp_info),
                .proto          = IPPROTO_SCTP,
                .me             = THIS_MODULE
@@ -184,23 +177,23 @@ static struct xt_match xt_sctp_match[] __read_mostly = {
        {
                .name           = "sctp",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = sctp_mt_check,
+               .match          = sctp_mt,
                .matchsize      = sizeof(struct xt_sctp_info),
                .proto          = IPPROTO_SCTP,
                .me             = THIS_MODULE
        },
 };
 
-static int __init xt_sctp_init(void)
+static int __init sctp_mt_init(void)
 {
-       return xt_register_matches(xt_sctp_match, ARRAY_SIZE(xt_sctp_match));
+       return xt_register_matches(sctp_mt_reg, ARRAY_SIZE(sctp_mt_reg));
 }
 
-static void __exit xt_sctp_fini(void)
+static void __exit sctp_mt_exit(void)
 {
-       xt_unregister_matches(xt_sctp_match, ARRAY_SIZE(xt_sctp_match));
+       xt_unregister_matches(sctp_mt_reg, ARRAY_SIZE(sctp_mt_reg));
 }
 
-module_init(xt_sctp_init);
-module_exit(xt_sctp_fini);
+module_init(sctp_mt_init);
+module_exit(sctp_mt_exit);
index e0a528df19a78349f29596782c35175fdc7c24d4..a776dc36a19343ae678cf192baa7ae680c4e1478 100644 (file)
@@ -21,14 +21,10 @@ MODULE_ALIAS("ipt_state");
 MODULE_ALIAS("ip6t_state");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+state_mt(const struct sk_buff *skb, const struct net_device *in,
+         const struct net_device *out, const struct xt_match *match,
+         const void *matchinfo, int offset, unsigned int protoff,
+         bool *hotdrop)
 {
        const struct xt_state_info *sinfo = matchinfo;
        enum ip_conntrack_info ctinfo;
@@ -44,56 +40,54 @@ match(const struct sk_buff *skb,
        return (sinfo->statemask & statebit);
 }
 
-static bool check(const char *tablename,
-                 const void *inf,
-                 const struct xt_match *match,
-                 void *matchinfo,
-                 unsigned int hook_mask)
+static bool
+state_mt_check(const char *tablename, const void *inf,
+               const struct xt_match *match, void *matchinfo,
+               unsigned int hook_mask)
 {
        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
                printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%d\n", match->family);
+                                   "proto=%u\n", match->family);
                return false;
        }
        return true;
 }
 
-static void
-destroy(const struct xt_match *match, void *matchinfo)
+static void state_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        nf_ct_l3proto_module_put(match->family);
 }
 
-static struct xt_match xt_state_match[] __read_mostly = {
+static struct xt_match state_mt_reg[] __read_mostly = {
        {
                .name           = "state",
                .family         = AF_INET,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = state_mt_check,
+               .match          = state_mt,
+               .destroy        = state_mt_destroy,
                .matchsize      = sizeof(struct xt_state_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "state",
                .family         = AF_INET6,
-               .checkentry     = check,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = state_mt_check,
+               .match          = state_mt,
+               .destroy        = state_mt_destroy,
                .matchsize      = sizeof(struct xt_state_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_state_init(void)
+static int __init state_mt_init(void)
 {
-       return xt_register_matches(xt_state_match, ARRAY_SIZE(xt_state_match));
+       return xt_register_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg));
 }
 
-static void __exit xt_state_fini(void)
+static void __exit state_mt_exit(void)
 {
-       xt_unregister_matches(xt_state_match, ARRAY_SIZE(xt_state_match));
+       xt_unregister_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg));
 }
 
-module_init(xt_state_init);
-module_exit(xt_state_fini);
+module_init(state_mt_init);
+module_exit(state_mt_exit);
index 4089dae4e2865ae9f99377d307195ff69127f07b..43133080da7da422b5ebd16c4dd515807b8767ce 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_DESCRIPTION("xtables statistical match module");
+MODULE_DESCRIPTION("Xtables: statistics-based matching (\"Nth\", random)");
 MODULE_ALIAS("ipt_statistic");
 MODULE_ALIAS("ip6t_statistic");
 
 static DEFINE_SPINLOCK(nth_lock);
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in, const struct net_device *out,
-      const struct xt_match *match, const void *matchinfo,
-      int offset, unsigned int protoff, bool *hotdrop)
+statistic_mt(const struct sk_buff *skb, const struct net_device *in,
+             const struct net_device *out, const struct xt_match *match,
+             const void *matchinfo, int offset, unsigned int protoff,
+             bool *hotdrop)
 {
        struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo;
        bool ret = info->flags & XT_STATISTIC_INVERT;
@@ -53,9 +53,9 @@ match(const struct sk_buff *skb,
 }
 
 static bool
-checkentry(const char *tablename, const void *entry,
-          const struct xt_match *match, void *matchinfo,
-          unsigned int hook_mask)
+statistic_mt_check(const char *tablename, const void *entry,
+                   const struct xt_match *match, void *matchinfo,
+                   unsigned int hook_mask)
 {
        struct xt_statistic_info *info = matchinfo;
 
@@ -66,36 +66,36 @@ checkentry(const char *tablename, const void *entry,
        return true;
 }
 
-static struct xt_match xt_statistic_match[] __read_mostly = {
+static struct xt_match statistic_mt_reg[] __read_mostly = {
        {
                .name           = "statistic",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = statistic_mt_check,
+               .match          = statistic_mt,
                .matchsize      = sizeof(struct xt_statistic_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "statistic",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
+               .checkentry     = statistic_mt_check,
+               .match          = statistic_mt,
                .matchsize      = sizeof(struct xt_statistic_info),
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_statistic_init(void)
+static int __init statistic_mt_init(void)
 {
-       return xt_register_matches(xt_statistic_match,
-                                  ARRAY_SIZE(xt_statistic_match));
+       return xt_register_matches(statistic_mt_reg,
+              ARRAY_SIZE(statistic_mt_reg));
 }
 
-static void __exit xt_statistic_fini(void)
+static void __exit statistic_mt_exit(void)
 {
-       xt_unregister_matches(xt_statistic_match,
-                             ARRAY_SIZE(xt_statistic_match));
+       xt_unregister_matches(statistic_mt_reg,
+                             ARRAY_SIZE(statistic_mt_reg));
 }
 
-module_init(xt_statistic_init);
-module_exit(xt_statistic_fini);
+module_init(statistic_mt_init);
+module_exit(statistic_mt_exit);
index 864133442cdac6c35f0f50edb81664565bf65b47..72f694d947f462802a929cb026984d5888beee1c 100644 (file)
 #include <linux/textsearch.h>
 
 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@eurodev.net>");
-MODULE_DESCRIPTION("IP tables string match module");
+MODULE_DESCRIPTION("Xtables: string-based matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_string");
 MODULE_ALIAS("ip6t_string");
 
-static bool match(const struct sk_buff *skb,
-                 const struct net_device *in,
-                 const struct net_device *out,
-                 const struct xt_match *match,
-                 const void *matchinfo,
-                 int offset,
-                 unsigned int protoff,
-                 bool *hotdrop)
+static bool
+string_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct xt_string_info *conf = matchinfo;
        struct ts_state state;
@@ -40,13 +37,12 @@ static bool match(const struct sk_buff *skb,
                             != UINT_MAX) ^ conf->invert;
 }
 
-#define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m)
+#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m))
 
-static bool checkentry(const char *tablename,
-                      const void *ip,
-                      const struct xt_match *match,
-                      void *matchinfo,
-                      unsigned int hook_mask)
+static bool
+string_mt_check(const char *tablename, const void *ip,
+                const struct xt_match *match, void *matchinfo,
+                unsigned int hook_mask)
 {
        struct xt_string_info *conf = matchinfo;
        struct ts_config *ts_conf;
@@ -68,41 +64,41 @@ static bool checkentry(const char *tablename,
        return true;
 }
 
-static void destroy(const struct xt_match *match, void *matchinfo)
+static void string_mt_destroy(const struct xt_match *match, void *matchinfo)
 {
        textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config);
 }
 
-static struct xt_match xt_string_match[] __read_mostly = {
+static struct xt_match string_mt_reg[] __read_mostly = {
        {
                .name           = "string",
                .family         = AF_INET,
-               .checkentry     = checkentry,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = string_mt_check,
+               .match          = string_mt,
+               .destroy        = string_mt_destroy,
                .matchsize      = sizeof(struct xt_string_info),
                .me             = THIS_MODULE
        },
        {
                .name           = "string",
                .family         = AF_INET6,
-               .checkentry     = checkentry,
-               .match          = match,
-               .destroy        = destroy,
+               .checkentry     = string_mt_check,
+               .match          = string_mt,
+               .destroy        = string_mt_destroy,
                .matchsize      = sizeof(struct xt_string_info),
                .me             = THIS_MODULE
        },
 };
 
-static int __init xt_string_init(void)
+static int __init string_mt_init(void)
 {
-       return xt_register_matches(xt_string_match, ARRAY_SIZE(xt_string_match));
+       return xt_register_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg));
 }
 
-static void __exit xt_string_fini(void)
+static void __exit string_mt_exit(void)
 {
-       xt_unregister_matches(xt_string_match, ARRAY_SIZE(xt_string_match));
+       xt_unregister_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg));
 }
 
-module_init(xt_string_init);
-module_exit(xt_string_fini);
+module_init(string_mt_init);
+module_exit(string_mt_exit);
index 84d401bfafad2be0fe528f9d3cd1996c15aa71df..d7a5b27fe81eae02b52bc122617b03c9e3d9d0e7 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("iptables TCP MSS match module");
+MODULE_DESCRIPTION("Xtables: TCP MSS match");
 MODULE_ALIAS("ipt_tcpmss");
 MODULE_ALIAS("ip6t_tcpmss");
 
 static bool
-match(const struct sk_buff *skb,
-      const struct net_device *in,
-      const struct net_device *out,
-      const struct xt_match *match,
-      const void *matchinfo,
-      int offset,
-      unsigned int protoff,
-      bool *hotdrop)
+tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
 {
        const struct xt_tcpmss_match_info *info = matchinfo;
        struct tcphdr _tcph, *th;
@@ -82,11 +78,11 @@ dropit:
        return false;
 }
 
-static struct xt_match xt_tcpmss_match[] __read_mostly = {
+static struct xt_match tcpmss_mt_reg[] __read_mostly = {
        {
                .name           = "tcpmss",
                .family         = AF_INET,
-               .match          = match,
+               .match          = tcpmss_mt,
                .matchsize      = sizeof(struct xt_tcpmss_match_info),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
@@ -94,23 +90,22 @@ static struct xt_match xt_tcpmss_match[] __read_mostly = {
        {
                .name           = "tcpmss",
                .family         = AF_INET6,
-               .match          = match,
+               .match          = tcpmss_mt,
                .matchsize      = sizeof(struct xt_tcpmss_match_info),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_tcpmss_init(void)
+static int __init tcpmss_mt_init(void)
 {
-       return xt_register_matches(xt_tcpmss_match,
-                                  ARRAY_SIZE(xt_tcpmss_match));
+       return xt_register_matches(tcpmss_mt_reg, ARRAY_SIZE(tcpmss_mt_reg));
 }
 
-static void __exit xt_tcpmss_fini(void)
+static void __exit tcpmss_mt_exit(void)
 {
-       xt_unregister_matches(xt_tcpmss_match, ARRAY_SIZE(xt_tcpmss_match));
+       xt_unregister_matches(tcpmss_mt_reg, ARRAY_SIZE(tcpmss_mt_reg));
 }
 
-module_init(xt_tcpmss_init);
-module_exit(xt_tcpmss_fini);
+module_init(tcpmss_mt_init);
+module_exit(tcpmss_mt_exit);
index 223f9bded672dcfc3e3ea01e130b37e9fa15e53d..4fa3b669f691d6956e2b11b24c5059eebe7f385b 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 
-MODULE_DESCRIPTION("x_tables match for TCP and UDP(-Lite), supports IPv4 and IPv6");
+MODULE_DESCRIPTION("Xtables: TCP, UDP and UDP-Lite match");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("xt_tcp");
 MODULE_ALIAS("xt_udp");
@@ -68,14 +68,9 @@ tcp_find_option(u_int8_t option,
 }
 
 static bool
-tcp_match(const struct sk_buff *skb,
-         const struct net_device *in,
-         const struct net_device *out,
-         const struct xt_match *match,
-         const void *matchinfo,
-         int offset,
-         unsigned int protoff,
-         bool *hotdrop)
+tcp_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct tcphdr _tcph, *th;
        const struct xt_tcp *tcpinfo = matchinfo;
@@ -134,11 +129,9 @@ tcp_match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-tcp_checkentry(const char *tablename,
-              const void *info,
-              const struct xt_match *match,
-              void *matchinfo,
-              unsigned int hook_mask)
+tcp_mt_check(const char *tablename, const void *info,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct xt_tcp *tcpinfo = matchinfo;
 
@@ -147,14 +140,9 @@ tcp_checkentry(const char *tablename,
 }
 
 static bool
-udp_match(const struct sk_buff *skb,
-         const struct net_device *in,
-         const struct net_device *out,
-         const struct xt_match *match,
-         const void *matchinfo,
-         int offset,
-         unsigned int protoff,
-         bool *hotdrop)
+udp_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        struct udphdr _udph, *uh;
        const struct xt_udp *udpinfo = matchinfo;
@@ -182,11 +170,9 @@ udp_match(const struct sk_buff *skb,
 
 /* Called when user tries to insert an entry of this type. */
 static bool
-udp_checkentry(const char *tablename,
-              const void *info,
-              const struct xt_match *match,
-              void *matchinfo,
-              unsigned int hook_mask)
+udp_mt_check(const char *tablename, const void *info,
+             const struct xt_match *match, void *matchinfo,
+             unsigned int hook_mask)
 {
        const struct xt_udp *udpinfo = matchinfo;
 
@@ -194,12 +180,12 @@ udp_checkentry(const char *tablename,
        return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
 }
 
-static struct xt_match xt_tcpudp_match[] __read_mostly = {
+static struct xt_match tcpudp_mt_reg[] __read_mostly = {
        {
                .name           = "tcp",
                .family         = AF_INET,
-               .checkentry     = tcp_checkentry,
-               .match          = tcp_match,
+               .checkentry     = tcp_mt_check,
+               .match          = tcp_mt,
                .matchsize      = sizeof(struct xt_tcp),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
@@ -207,8 +193,8 @@ static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "tcp",
                .family         = AF_INET6,
-               .checkentry     = tcp_checkentry,
-               .match          = tcp_match,
+               .checkentry     = tcp_mt_check,
+               .match          = tcp_mt,
                .matchsize      = sizeof(struct xt_tcp),
                .proto          = IPPROTO_TCP,
                .me             = THIS_MODULE,
@@ -216,8 +202,8 @@ static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "udp",
                .family         = AF_INET,
-               .checkentry     = udp_checkentry,
-               .match          = udp_match,
+               .checkentry     = udp_mt_check,
+               .match          = udp_mt,
                .matchsize      = sizeof(struct xt_udp),
                .proto          = IPPROTO_UDP,
                .me             = THIS_MODULE,
@@ -225,8 +211,8 @@ static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "udp",
                .family         = AF_INET6,
-               .checkentry     = udp_checkentry,
-               .match          = udp_match,
+               .checkentry     = udp_mt_check,
+               .match          = udp_mt,
                .matchsize      = sizeof(struct xt_udp),
                .proto          = IPPROTO_UDP,
                .me             = THIS_MODULE,
@@ -234,8 +220,8 @@ static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "udplite",
                .family         = AF_INET,
-               .checkentry     = udp_checkentry,
-               .match          = udp_match,
+               .checkentry     = udp_mt_check,
+               .match          = udp_mt,
                .matchsize      = sizeof(struct xt_udp),
                .proto          = IPPROTO_UDPLITE,
                .me             = THIS_MODULE,
@@ -243,24 +229,23 @@ static struct xt_match xt_tcpudp_match[] __read_mostly = {
        {
                .name           = "udplite",
                .family         = AF_INET6,
-               .checkentry     = udp_checkentry,
-               .match          = udp_match,
+               .checkentry     = udp_mt_check,
+               .match          = udp_mt,
                .matchsize      = sizeof(struct xt_udp),
                .proto          = IPPROTO_UDPLITE,
                .me             = THIS_MODULE,
        },
 };
 
-static int __init xt_tcpudp_init(void)
+static int __init tcpudp_mt_init(void)
 {
-       return xt_register_matches(xt_tcpudp_match,
-                                  ARRAY_SIZE(xt_tcpudp_match));
+       return xt_register_matches(tcpudp_mt_reg, ARRAY_SIZE(tcpudp_mt_reg));
 }
 
-static void __exit xt_tcpudp_fini(void)
+static void __exit tcpudp_mt_exit(void)
 {
-       xt_unregister_matches(xt_tcpudp_match, ARRAY_SIZE(xt_tcpudp_match));
+       xt_unregister_matches(tcpudp_mt_reg, ARRAY_SIZE(tcpudp_mt_reg));
 }
 
-module_init(xt_tcpudp_init);
-module_exit(xt_tcpudp_fini);
+module_init(tcpudp_mt_init);
+module_exit(tcpudp_mt_exit);
index f9c55dcd894b70e9cef74203a27f2d747d4f2d8e..e9a8794bc3ab6020c27cb6b73c24efd2b79201d1 100644 (file)
@@ -147,11 +147,10 @@ static void localtime_3(struct xtm *r, time_t time)
        return;
 }
 
-static bool xt_time_match(const struct sk_buff *skb,
-                          const struct net_device *in,
-                          const struct net_device *out,
-                          const struct xt_match *match, const void *matchinfo,
-                          int offset, unsigned int protoff, bool *hotdrop)
+static bool
+time_mt(const struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, const struct xt_match *match,
+        const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct xt_time_info *info = matchinfo;
        unsigned int packet_time;
@@ -216,9 +215,10 @@ static bool xt_time_match(const struct sk_buff *skb,
        return true;
 }
 
-static bool xt_time_check(const char *tablename, const void *ip,
-                          const struct xt_match *match, void *matchinfo,
-                          unsigned int hook_mask)
+static bool
+time_mt_check(const char *tablename, const void *ip,
+              const struct xt_match *match, void *matchinfo,
+              unsigned int hook_mask)
 {
        struct xt_time_info *info = matchinfo;
 
@@ -232,39 +232,39 @@ static bool xt_time_check(const char *tablename, const void *ip,
        return true;
 }
 
-static struct xt_match xt_time_reg[] __read_mostly = {
+static struct xt_match time_mt_reg[] __read_mostly = {
        {
                .name       = "time",
                .family     = AF_INET,
-               .match      = xt_time_match,
+               .match      = time_mt,
                .matchsize  = sizeof(struct xt_time_info),
-               .checkentry = xt_time_check,
+               .checkentry = time_mt_check,
                .me         = THIS_MODULE,
        },
        {
                .name       = "time",
                .family     = AF_INET6,
-               .match      = xt_time_match,
+               .match      = time_mt,
                .matchsize  = sizeof(struct xt_time_info),
-               .checkentry = xt_time_check,
+               .checkentry = time_mt_check,
                .me         = THIS_MODULE,
        },
 };
 
-static int __init xt_time_init(void)
+static int __init time_mt_init(void)
 {
-       return xt_register_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg));
+       return xt_register_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg));
 }
 
-static void __exit xt_time_exit(void)
+static void __exit time_mt_exit(void)
 {
-       xt_unregister_matches(xt_time_reg, ARRAY_SIZE(xt_time_reg));
+       xt_unregister_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg));
 }
 
-module_init(xt_time_init);
-module_exit(xt_time_exit);
+module_init(time_mt_init);
+module_exit(time_mt_exit);
 MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
-MODULE_DESCRIPTION("netfilter time match");
+MODULE_DESCRIPTION("Xtables: time-based matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_time");
 MODULE_ALIAS("ip6t_time");
index af75b8c3f20b988af0df06b74382cee68e07c4cf..9b8ed390a8e087ae4d24ae7ff872a4d5fb93d322 100644 (file)
@@ -88,11 +88,10 @@ static bool u32_match_it(const struct xt_u32 *data,
        return true;
 }
 
-static bool u32_match(const struct sk_buff *skb,
-                     const struct net_device *in,
-                     const struct net_device *out,
-                     const struct xt_match *match, const void *matchinfo,
-                     int offset, unsigned int protoff, bool *hotdrop)
+static bool
+u32_mt(const struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, const struct xt_match *match,
+       const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
 {
        const struct xt_u32 *data = matchinfo;
        bool ret;
@@ -101,37 +100,37 @@ static bool u32_match(const struct sk_buff *skb,
        return ret ^ data->invert;
 }
 
-static struct xt_match u32_reg[] __read_mostly = {
+static struct xt_match u32_mt_reg[] __read_mostly = {
        {
                .name       = "u32",
                .family     = AF_INET,
-               .match      = u32_match,
+               .match      = u32_mt,
                .matchsize  = sizeof(struct xt_u32),
                .me         = THIS_MODULE,
        },
        {
                .name       = "u32",
                .family     = AF_INET6,
-               .match      = u32_match,
+               .match      = u32_mt,
                .matchsize  = sizeof(struct xt_u32),
                .me         = THIS_MODULE,
        },
 };
 
-static int __init xt_u32_init(void)
+static int __init u32_mt_init(void)
 {
-       return xt_register_matches(u32_reg, ARRAY_SIZE(u32_reg));
+       return xt_register_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg));
 }
 
-static void __exit xt_u32_exit(void)
+static void __exit u32_mt_exit(void)
 {
-       xt_unregister_matches(u32_reg, ARRAY_SIZE(u32_reg));
+       xt_unregister_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg));
 }
 
-module_init(xt_u32_init);
-module_exit(xt_u32_exit);
+module_init(u32_mt_init);
+module_exit(u32_mt_exit);
 MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
-MODULE_DESCRIPTION("netfilter u32 match module");
+MODULE_DESCRIPTION("Xtables: arbitrary byte matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_u32");
 MODULE_ALIAS("ip6t_u32");
index de3988ba1f46c45dd0831caeb71b4de0dedb0a63..6b178e1247b5c3672e3857486d2d1346903181c2 100644 (file)
@@ -156,7 +156,7 @@ static void netlink_sock_destruct(struct sock *sk)
        skb_queue_purge(&sk->sk_receive_queue);
 
        if (!sock_flag(sk, SOCK_DEAD)) {
-               printk("Freeing alive netlink socket %p\n", sk);
+               printk(KERN_ERR "Freeing alive netlink socket %p\n", sk);
                return;
        }
        BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
@@ -164,13 +164,14 @@ static void netlink_sock_destruct(struct sock *sk)
        BUG_TRAP(!nlk_sk(sk)->groups);
 }
 
-/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on SMP.
- * Look, when several writers sleep and reader wakes them up, all but one
+/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
+ * SMP. Look, when several writers sleep and reader wakes them up, all but one
  * immediately hit write lock and grab all the cpus. Exclusive sleep solves
  * this, _but_ remember, it adds useless work on UP machines.
  */
 
 static void netlink_table_grab(void)
+       __acquires(nl_table_lock)
 {
        write_lock_irq(&nl_table_lock);
 
@@ -178,7 +179,7 @@ static void netlink_table_grab(void)
                DECLARE_WAITQUEUE(wait, current);
 
                add_wait_queue_exclusive(&nl_table_wait, &wait);
-               for(;;) {
+               for (;;) {
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        if (atomic_read(&nl_table_users) == 0)
                                break;
@@ -192,13 +193,14 @@ static void netlink_table_grab(void)
        }
 }
 
-static __inline__ void netlink_table_ungrab(void)
+static void netlink_table_ungrab(void)
+       __releases(nl_table_lock)
 {
        write_unlock_irq(&nl_table_lock);
        wake_up(&nl_table_wait);
 }
 
-static __inline__ void
+static inline void
 netlink_lock_table(void)
 {
        /* read_lock() synchronizes us to netlink_table_grab */
@@ -208,14 +210,15 @@ netlink_lock_table(void)
        read_unlock(&nl_table_lock);
 }
 
-static __inline__ void
+static inline void
 netlink_unlock_table(void)
 {
        if (atomic_dec_and_test(&nl_table_users))
                wake_up(&nl_table_wait);
 }
 
-static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid)
+static inline struct sock *netlink_lookup(struct net *net, int protocol,
+                                         u32 pid)
 {
        struct nl_pid_hash *hash = &nl_table[protocol].hash;
        struct hlist_head *head;
@@ -236,13 +239,14 @@ found:
        return sk;
 }
 
-static inline struct hlist_head *nl_pid_hash_alloc(size_t size)
+static inline struct hlist_head *nl_pid_hash_zalloc(size_t size)
 {
        if (size <= PAGE_SIZE)
-               return kmalloc(size, GFP_ATOMIC);
+               return kzalloc(size, GFP_ATOMIC);
        else
                return (struct hlist_head *)
-                       __get_free_pages(GFP_ATOMIC, get_order(size));
+                       __get_free_pages(GFP_ATOMIC | __GFP_ZERO,
+                                        get_order(size));
 }
 
 static inline void nl_pid_hash_free(struct hlist_head *table, size_t size)
@@ -271,11 +275,10 @@ static int nl_pid_hash_rehash(struct nl_pid_hash *hash, int grow)
                size *= 2;
        }
 
-       table = nl_pid_hash_alloc(size);
+       table = nl_pid_hash_zalloc(size);
        if (!table)
                return 0;
 
-       memset(table, 0, size);
        otable = hash->table;
        hash->table = table;
        hash->mask = mask;
@@ -428,7 +431,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
                return -ESOCKTNOSUPPORT;
 
-       if (protocol<0 || protocol >= MAX_LINKS)
+       if (protocol < 0 || protocol >= MAX_LINKS)
                return -EPROTONOSUPPORT;
 
        netlink_lock_table();
@@ -445,7 +448,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
        cb_mutex = nl_table[protocol].cb_mutex;
        netlink_unlock_table();
 
-       if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0)
+       err = __netlink_create(net, sock, cb_mutex, protocol);
+       if (err < 0)
                goto out_module;
 
        nlk = nlk_sk(sock->sk);
@@ -494,9 +498,12 @@ static int netlink_release(struct socket *sock)
 
        netlink_table_grab();
        if (netlink_is_kernel(sk)) {
-               kfree(nl_table[sk->sk_protocol].listeners);
-               nl_table[sk->sk_protocol].module = NULL;
-               nl_table[sk->sk_protocol].registered = 0;
+               BUG_ON(nl_table[sk->sk_protocol].registered == 0);
+               if (--nl_table[sk->sk_protocol].registered == 0) {
+                       kfree(nl_table[sk->sk_protocol].listeners);
+                       nl_table[sk->sk_protocol].module = NULL;
+                       nl_table[sk->sk_protocol].registered = 0;
+               }
        } else if (nlk->subscriptions)
                netlink_update_listeners(sk);
        netlink_table_ungrab();
@@ -590,7 +597,7 @@ static int netlink_realloc_groups(struct sock *sk)
                err = -ENOMEM;
                goto out_unlock;
        }
-       memset((char*)new_groups + NLGRPSZ(nlk->ngroups), 0,
+       memset((char *)new_groups + NLGRPSZ(nlk->ngroups), 0,
               NLGRPSZ(groups) - NLGRPSZ(nlk->ngroups));
 
        nlk->groups = new_groups;
@@ -600,7 +607,8 @@ static int netlink_realloc_groups(struct sock *sk)
        return err;
 }
 
-static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
+static int netlink_bind(struct socket *sock, struct sockaddr *addr,
+                       int addr_len)
 {
        struct sock *sk = sock->sk;
        struct net *net = sk->sk_net;
@@ -651,7 +659,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        int err = 0;
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
-       struct sockaddr_nl *nladdr=(struct sockaddr_nl*)addr;
+       struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 
        if (addr->sa_family == AF_UNSPEC) {
                sk->sk_state    = NETLINK_UNCONNECTED;
@@ -678,11 +686,12 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        return err;
 }
 
-static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
+static int netlink_getname(struct socket *sock, struct sockaddr *addr,
+                          int *addr_len, int peer)
 {
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
-       struct sockaddr_nl *nladdr=(struct sockaddr_nl *)addr;
+       struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 
        nladdr->nl_family = AF_NETLINK;
        nladdr->nl_pad = 0;
@@ -885,6 +894,7 @@ retry:
 
        return netlink_sendskb(sk, skb);
 }
+EXPORT_SYMBOL(netlink_unicast);
 
 int netlink_has_listeners(struct sock *sk, unsigned int group)
 {
@@ -905,7 +915,8 @@ int netlink_has_listeners(struct sock *sk, unsigned int group)
 }
 EXPORT_SYMBOL_GPL(netlink_has_listeners);
 
-static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
+static inline int netlink_broadcast_deliver(struct sock *sk,
+                                           struct sk_buff *skb)
 {
        struct netlink_sock *nlk = nlk_sk(sk);
 
@@ -1026,6 +1037,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
                return -ENOBUFS;
        return -ESRCH;
 }
+EXPORT_SYMBOL(netlink_broadcast);
 
 struct netlink_set_err_data {
        struct sock *exclude_sk;
@@ -1182,7 +1194,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
        struct sock *sk = sock->sk;
        struct netlink_sock *nlk = nlk_sk(sk);
-       struct sockaddr_nl *addr=msg->msg_name;
+       struct sockaddr_nl *addr = msg->msg_name;
        u32 dst_pid;
        u32 dst_group;
        struct sk_buff *skb;
@@ -1221,7 +1233,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
                goto out;
        err = -ENOBUFS;
        skb = alloc_skb(len, GFP_KERNEL);
-       if (skb==NULL)
+       if (skb == NULL)
                goto out;
 
        NETLINK_CB(skb).pid     = nlk->pid;
@@ -1237,7 +1249,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
         */
 
        err = -EFAULT;
-       if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
+       if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
                kfree_skb(skb);
                goto out;
        }
@@ -1276,8 +1288,8 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
 
        copied = 0;
 
-       skb = skb_recv_datagram(sk,flags,noblock,&err);
-       if (skb==NULL)
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (skb == NULL)
                goto out;
 
        msg->msg_namelen = 0;
@@ -1292,7 +1304,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
        if (msg->msg_name) {
-               struct sockaddr_nl *addr = (struct sockaddr_nl*)msg->msg_name;
+               struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name;
                addr->nl_family = AF_NETLINK;
                addr->nl_pad    = 0;
                addr->nl_pid    = NETLINK_CB(skb).pid;
@@ -1344,7 +1356,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
 
        BUG_ON(!nl_table);
 
-       if (unit<0 || unit>=MAX_LINKS)
+       if (unit < 0 || unit >= MAX_LINKS)
                return NULL;
 
        if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
@@ -1380,9 +1392,13 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
                nl_table[unit].registered = 1;
        } else {
                kfree(listeners);
+               nl_table[unit].registered++;
        }
        netlink_table_ungrab();
 
+       /* Do not hold an extra referrence to a namespace as this socket is
+        * internal to a namespace and does not prevent it to stop. */
+       put_net(net);
        return sk;
 
 out_sock_release:
@@ -1390,6 +1406,30 @@ out_sock_release:
        sock_release(sock);
        return NULL;
 }
+EXPORT_SYMBOL(netlink_kernel_create);
+
+
+void
+netlink_kernel_release(struct sock *sk)
+{
+       if (sk == NULL || sk->sk_socket == NULL)
+               return;
+
+       /*
+        * Last sock_put should drop referrence to sk->sk_net. It has already
+        * been dropped in netlink_kernel_create. Taking referrence to stopping
+        * namespace is not an option.
+        * Take referrence to a socket to remove it from netlink lookup table
+        * _alive_ and after that destroy it in the context of init_net.
+        */
+       sock_hold(sk);
+       sock_release(sk->sk_socket);
+
+       sk->sk_net = get_net(&init_net);
+       sock_put(sk);
+}
+EXPORT_SYMBOL(netlink_kernel_release);
+
 
 /**
  * netlink_change_ngroups - change number of multicast groups
@@ -1461,6 +1501,7 @@ void netlink_set_nonroot(int protocol, unsigned int flags)
        if ((unsigned int)protocol < MAX_LINKS)
                nl_table[protocol].nl_nonroot = flags;
 }
+EXPORT_SYMBOL(netlink_set_nonroot);
 
 static void netlink_destroy_callback(struct netlink_callback *cb)
 {
@@ -1529,8 +1570,9 @@ errout:
 
 int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
                       struct nlmsghdr *nlh,
-                      int (*dump)(struct sk_buff *skb, struct netlink_callback*),
-                      int (*done)(struct netlink_callback*))
+                      int (*dump)(struct sk_buff *skb,
+                                  struct netlink_callback *),
+                      int (*done)(struct netlink_callback *))
 {
        struct netlink_callback *cb;
        struct sock *sk;
@@ -1571,6 +1613,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
         */
        return -EINTR;
 }
+EXPORT_SYMBOL(netlink_dump_start);
 
 void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
 {
@@ -1605,6 +1648,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
        memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh));
        netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
 }
+EXPORT_SYMBOL(netlink_ack);
 
 int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
                                                     struct nlmsghdr *))
@@ -1638,7 +1682,7 @@ ack:
                        netlink_ack(skb, nlh, err);
 
 skip:
-               msglen = NLMSG_ALIGN(nlh->nlmsg_len);
+               msglen = NLMSG_ALIGN(nlh->nlmsg_len);
                if (msglen > skb->len)
                        msglen = skb->len;
                skb_pull(skb, msglen);
@@ -1646,6 +1690,7 @@ skip:
 
        return 0;
 }
+EXPORT_SYMBOL(netlink_rcv_skb);
 
 /**
  * nlmsg_notify - send a notification netlink message
@@ -1678,10 +1723,11 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
 
        return err;
 }
+EXPORT_SYMBOL(nlmsg_notify);
 
 #ifdef CONFIG_PROC_FS
 struct nl_seq_iter {
-       struct net *net;
+       struct seq_net_private p;
        int link;
        int hash_idx;
 };
@@ -1694,12 +1740,12 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
        struct hlist_node *node;
        loff_t off = 0;
 
-       for (i=0; i<MAX_LINKS; i++) {
+       for (i = 0; i < MAX_LINKS; i++) {
                struct nl_pid_hash *hash = &nl_table[i].hash;
 
                for (j = 0; j <= hash->mask; j++) {
                        sk_for_each(s, node, &hash->table[j]) {
-                               if (iter->net != s->sk_net)
+                               if (iter->p.net != s->sk_net)
                                        continue;
                                if (off == pos) {
                                        iter->link = i;
@@ -1714,6 +1760,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
 }
 
 static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(nl_table_lock)
 {
        read_lock(&nl_table_lock);
        return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : SEQ_START_TOKEN;
@@ -1734,7 +1781,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        s = v;
        do {
                s = sk_next(s);
-       } while (s && (iter->net != s->sk_net));
+       } while (s && (iter->p.net != s->sk_net));
        if (s)
                return s;
 
@@ -1746,7 +1793,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 
                for (; j <= hash->mask; j++) {
                        s = sk_head(&hash->table[j]);
-                       while (s && (iter->net != s->sk_net))
+                       while (s && (iter->p.net != s->sk_net))
                                s = sk_next(s);
                        if (s) {
                                iter->link = i;
@@ -1762,6 +1809,7 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void netlink_seq_stop(struct seq_file *seq, void *v)
+       __releases(nl_table_lock)
 {
        read_unlock(&nl_table_lock);
 }
@@ -1802,27 +1850,8 @@ static const struct seq_operations netlink_seq_ops = {
 
 static int netlink_seq_open(struct inode *inode, struct file *file)
 {
-       struct nl_seq_iter *iter;
-
-       iter = __seq_open_private(file, &netlink_seq_ops, sizeof(*iter));
-       if (!iter)
-               return -ENOMEM;
-
-       iter->net = get_proc_net(inode);
-       if (!iter->net) {
-               seq_release_private(inode, file);
-               return -ENXIO;
-       }
-
-       return 0;
-}
-
-static int netlink_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct nl_seq_iter *iter = seq->private;
-       put_net(iter->net);
-       return seq_release_private(inode, file);
+       return seq_open_net(inode, file, &netlink_seq_ops,
+                               sizeof(struct nl_seq_iter));
 }
 
 static const struct file_operations netlink_seq_fops = {
@@ -1830,7 +1859,7 @@ static const struct file_operations netlink_seq_fops = {
        .open           = netlink_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = netlink_seq_release,
+       .release        = seq_release_net,
 };
 
 #endif
@@ -1839,11 +1868,13 @@ int netlink_register_notifier(struct notifier_block *nb)
 {
        return atomic_notifier_chain_register(&netlink_chain, nb);
 }
+EXPORT_SYMBOL(netlink_register_notifier);
 
 int netlink_unregister_notifier(struct notifier_block *nb)
 {
        return atomic_notifier_chain_unregister(&netlink_chain, nb);
 }
+EXPORT_SYMBOL(netlink_unregister_notifier);
 
 static const struct proto_ops netlink_ops = {
        .family =       PF_NETLINK,
@@ -1922,7 +1953,7 @@ static int __init netlink_proto_init(void)
        for (i = 0; i < MAX_LINKS; i++) {
                struct nl_pid_hash *hash = &nl_table[i].hash;
 
-               hash->table = nl_pid_hash_alloc(1 * sizeof(*hash->table));
+               hash->table = nl_pid_hash_zalloc(1 * sizeof(*hash->table));
                if (!hash->table) {
                        while (i-- > 0)
                                nl_pid_hash_free(nl_table[i].hash.table,
@@ -1930,7 +1961,6 @@ static int __init netlink_proto_init(void)
                        kfree(nl_table);
                        goto panic;
                }
-               memset(hash->table, 0, 1 * sizeof(*hash->table));
                hash->max_shift = order;
                hash->shift = 0;
                hash->mask = 0;
@@ -1948,14 +1978,3 @@ panic:
 }
 
 core_initcall(netlink_proto_init);
-
-EXPORT_SYMBOL(netlink_ack);
-EXPORT_SYMBOL(netlink_rcv_skb);
-EXPORT_SYMBOL(netlink_broadcast);
-EXPORT_SYMBOL(netlink_dump_start);
-EXPORT_SYMBOL(netlink_kernel_create);
-EXPORT_SYMBOL(netlink_register_notifier);
-EXPORT_SYMBOL(netlink_set_nonroot);
-EXPORT_SYMBOL(netlink_unicast);
-EXPORT_SYMBOL(netlink_unregister_notifier);
-EXPORT_SYMBOL(nlmsg_notify);
index ec39d12c2423347463e766fc83bda5ef9861901a..feb326f4a752fb4813e2448d6a450e3d93892757 100644 (file)
@@ -430,6 +430,24 @@ int nla_put_nohdr(struct sk_buff *skb, int attrlen, const void *data)
        return 0;
 }
 
+/**
+ * nla_append - Add a netlink attribute without header or padding
+ * @skb: socket buffer to add attribute to
+ * @attrlen: length of attribute payload
+ * @data: head of attribute payload
+ *
+ * Returns -1 if the tailroom of the skb is insufficient to store
+ * the attribute payload.
+ */
+int nla_append(struct sk_buff *skb, int attrlen, const void *data)
+{
+       if (unlikely(skb_tailroom(skb) < NLA_ALIGN(attrlen)))
+               return -1;
+
+       memcpy(skb_put(skb, attrlen), data, attrlen);
+       return 0;
+}
+
 EXPORT_SYMBOL(nla_validate);
 EXPORT_SYMBOL(nla_parse);
 EXPORT_SYMBOL(nla_find);
@@ -445,3 +463,4 @@ EXPORT_SYMBOL(nla_put_nohdr);
 EXPORT_SYMBOL(nla_memcpy);
 EXPORT_SYMBOL(nla_memcmp);
 EXPORT_SYMBOL(nla_strcmp);
+EXPORT_SYMBOL(nla_append);
index 6cfaad952c6cdcbd36e5991355b1673f7394d211..1cb98e88f5e1cef557699464d6d9519ac14c9a85 100644 (file)
@@ -40,21 +40,10 @@ void nr_init_timers(struct sock *sk)
 {
        struct nr_sock *nr = nr_sk(sk);
 
-       init_timer(&nr->t1timer);
-       nr->t1timer.data     = (unsigned long)sk;
-       nr->t1timer.function = &nr_t1timer_expiry;
-
-       init_timer(&nr->t2timer);
-       nr->t2timer.data     = (unsigned long)sk;
-       nr->t2timer.function = &nr_t2timer_expiry;
-
-       init_timer(&nr->t4timer);
-       nr->t4timer.data     = (unsigned long)sk;
-       nr->t4timer.function = &nr_t4timer_expiry;
-
-       init_timer(&nr->idletimer);
-       nr->idletimer.data     = (unsigned long)sk;
-       nr->idletimer.function = &nr_idletimer_expiry;
+       setup_timer(&nr->t1timer, nr_t1timer_expiry, (unsigned long)sk);
+       setup_timer(&nr->t2timer, nr_t2timer_expiry, (unsigned long)sk);
+       setup_timer(&nr->t4timer, nr_t4timer_expiry, (unsigned long)sk);
+       setup_timer(&nr->idletimer, nr_idletimer_expiry, (unsigned long)sk);
 
        /* initialized by sock_init_data */
        sk->sk_timer.data     = (unsigned long)sk;
index 2ea68da01fb836bf8f8ae5fa4b70c13686df12e7..34c96c9674dfd838c9061d2a0afde9211ea4bed3 100644 (file)
@@ -170,29 +170,15 @@ static ctl_table nr_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table nr_dir_table[] = {
-       {
-               .ctl_name       = NET_NETROM,
-               .procname       = "netrom",
-               .mode           = 0555,
-               .child          = nr_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table nr_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = nr_dir_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path nr_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "netrom", .ctl_name = NET_NETROM, },
+       { }
 };
 
 void __init nr_register_sysctl(void)
 {
-       nr_table_header = register_sysctl_table(nr_root_table);
+       nr_table_header = register_sysctl_paths(nr_path, nr_table);
 }
 
 void nr_unregister_sysctl(void)
index 8a7807dbba012bdc03b0b49a8a1f35a02e9ee288..b8b827c7062d3a7a50f6032f76cdd61bfdf634dd 100644 (file)
@@ -135,10 +135,6 @@ dev->hard_header == NULL (ll header is added by device, we cannot control it)
    packet classifier depends on it.
  */
 
-/* List of all packet sockets. */
-static HLIST_HEAD(packet_sklist);
-static DEFINE_RWLOCK(packet_sklist_lock);
-
 /* Private packet socket structures. */
 
 struct packet_mclist
@@ -246,9 +242,6 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
        struct sock *sk;
        struct sockaddr_pkt *spkt;
 
-       if (dev->nd_net != &init_net)
-               goto out;
-
        /*
         *      When we registered the protocol we saved the socket in the data
         *      field for just this event.
@@ -270,6 +263,9 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
        if (skb->pkt_type == PACKET_LOOPBACK)
                goto out;
 
+       if (dev->nd_net != sk->sk_net)
+               goto out;
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
                goto oom;
 
@@ -341,7 +337,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
         */
 
        saddr->spkt_device[13] = 0;
-       dev = dev_get_by_name(&init_net, saddr->spkt_device);
+       dev = dev_get_by_name(sk->sk_net, saddr->spkt_device);
        err = -ENODEV;
        if (dev == NULL)
                goto out_unlock;
@@ -449,15 +445,15 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
        int skb_len = skb->len;
        unsigned int snaplen, res;
 
-       if (dev->nd_net != &init_net)
-               goto drop;
-
        if (skb->pkt_type == PACKET_LOOPBACK)
                goto drop;
 
        sk = pt->af_packet_priv;
        po = pkt_sk(sk);
 
+       if (dev->nd_net != sk->sk_net)
+               goto drop;
+
        skb->dev = dev;
 
        if (dev->header_ops) {
@@ -566,15 +562,15 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
        struct sk_buff *copy_skb = NULL;
        struct timeval tv;
 
-       if (dev->nd_net != &init_net)
-               goto drop;
-
        if (skb->pkt_type == PACKET_LOOPBACK)
                goto drop;
 
        sk = pt->af_packet_priv;
        po = pkt_sk(sk);
 
+       if (dev->nd_net != sk->sk_net)
+               goto drop;
+
        if (dev->header_ops) {
                if (sk->sk_type != SOCK_DGRAM)
                        skb_push(skb, skb->data - skb_mac_header(skb));
@@ -732,7 +728,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
        }
 
 
-       dev = dev_get_by_index(&init_net, ifindex);
+       dev = dev_get_by_index(sk->sk_net, ifindex);
        err = -ENXIO;
        if (dev == NULL)
                goto out_unlock;
@@ -799,15 +795,17 @@ static int packet_release(struct socket *sock)
 {
        struct sock *sk = sock->sk;
        struct packet_sock *po;
+       struct net *net;
 
        if (!sk)
                return 0;
 
+       net = sk->sk_net;
        po = pkt_sk(sk);
 
-       write_lock_bh(&packet_sklist_lock);
+       write_lock_bh(&net->packet.sklist_lock);
        sk_del_node_init(sk);
-       write_unlock_bh(&packet_sklist_lock);
+       write_unlock_bh(&net->packet.sklist_lock);
 
        /*
         *      Unhook packet receive handler.
@@ -916,7 +914,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add
                return -EINVAL;
        strlcpy(name,uaddr->sa_data,sizeof(name));
 
-       dev = dev_get_by_name(&init_net, name);
+       dev = dev_get_by_name(sk->sk_net, name);
        if (dev) {
                err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
                dev_put(dev);
@@ -943,7 +941,7 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len
 
        if (sll->sll_ifindex) {
                err = -ENODEV;
-               dev = dev_get_by_index(&init_net, sll->sll_ifindex);
+               dev = dev_get_by_index(sk->sk_net, sll->sll_ifindex);
                if (dev == NULL)
                        goto out;
        }
@@ -972,9 +970,6 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
        __be16 proto = (__force __be16)protocol; /* weird, but documented */
        int err;
 
-       if (net != &init_net)
-               return -EAFNOSUPPORT;
-
        if (!capable(CAP_NET_RAW))
                return -EPERM;
        if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
@@ -1020,9 +1015,9 @@ static int packet_create(struct net *net, struct socket *sock, int protocol)
                po->running = 1;
        }
 
-       write_lock_bh(&packet_sklist_lock);
-       sk_add_node(sk, &packet_sklist);
-       write_unlock_bh(&packet_sklist_lock);
+       write_lock_bh(&net->packet.sklist_lock);
+       sk_add_node(sk, &net->packet.sklist);
+       write_unlock_bh(&net->packet.sklist_lock);
        return(0);
 out:
        return err;
@@ -1140,7 +1135,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,
                return -EOPNOTSUPP;
 
        uaddr->sa_family = AF_PACKET;
-       dev = dev_get_by_index(&init_net, pkt_sk(sk)->ifindex);
+       dev = dev_get_by_index(sk->sk_net, pkt_sk(sk)->ifindex);
        if (dev) {
                strlcpy(uaddr->sa_data, dev->name, 15);
                dev_put(dev);
@@ -1165,7 +1160,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
        sll->sll_family = AF_PACKET;
        sll->sll_ifindex = po->ifindex;
        sll->sll_protocol = po->num;
-       dev = dev_get_by_index(&init_net, po->ifindex);
+       dev = dev_get_by_index(sk->sk_net, po->ifindex);
        if (dev) {
                sll->sll_hatype = dev->type;
                sll->sll_halen = dev->addr_len;
@@ -1217,7 +1212,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
        rtnl_lock();
 
        err = -ENODEV;
-       dev = __dev_get_by_index(&init_net, mreq->mr_ifindex);
+       dev = __dev_get_by_index(sk->sk_net, mreq->mr_ifindex);
        if (!dev)
                goto done;
 
@@ -1271,7 +1266,7 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
                        if (--ml->count == 0) {
                                struct net_device *dev;
                                *mlp = ml->next;
-                               dev = dev_get_by_index(&init_net, ml->ifindex);
+                               dev = dev_get_by_index(sk->sk_net, ml->ifindex);
                                if (dev) {
                                        packet_dev_mc(dev, ml, -1);
                                        dev_put(dev);
@@ -1299,7 +1294,7 @@ static void packet_flush_mclist(struct sock *sk)
                struct net_device *dev;
 
                po->mclist = ml->next;
-               if ((dev = dev_get_by_index(&init_net, ml->ifindex)) != NULL) {
+               if ((dev = dev_get_by_index(sk->sk_net, ml->ifindex)) != NULL) {
                        packet_dev_mc(dev, ml, -1);
                        dev_put(dev);
                }
@@ -1455,12 +1450,10 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
        struct sock *sk;
        struct hlist_node *node;
        struct net_device *dev = data;
+       struct net *net = dev->nd_net;
 
-       if (dev->nd_net != &init_net)
-               return NOTIFY_DONE;
-
-       read_lock(&packet_sklist_lock);
-       sk_for_each(sk, node, &packet_sklist) {
+       read_lock(&net->packet.sklist_lock);
+       sk_for_each(sk, node, &net->packet.sklist) {
                struct packet_sock *po = pkt_sk(sk);
 
                switch (msg) {
@@ -1499,7 +1492,7 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
                        break;
                }
        }
-       read_unlock(&packet_sklist_lock);
+       read_unlock(&net->packet.sklist_lock);
        return NOTIFY_DONE;
 }
 
@@ -1547,6 +1540,8 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
                case SIOCGIFDSTADDR:
                case SIOCSIFDSTADDR:
                case SIOCSIFFLAGS:
+                       if (sk->sk_net != &init_net)
+                               return -ENOIOCTLCMD;
                        return inet_dgram_ops.ioctl(sock, cmd, arg);
 #endif
 
@@ -1862,12 +1857,12 @@ static struct notifier_block packet_netdev_notifier = {
 };
 
 #ifdef CONFIG_PROC_FS
-static inline struct sock *packet_seq_idx(loff_t off)
+static inline struct sock *packet_seq_idx(struct net *net, loff_t off)
 {
        struct sock *s;
        struct hlist_node *node;
 
-       sk_for_each(s, node, &packet_sklist) {
+       sk_for_each(s, node, &net->packet.sklist) {
                if (!off--)
                        return s;
        }
@@ -1875,22 +1870,27 @@ static inline struct sock *packet_seq_idx(loff_t off)
 }
 
 static void *packet_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(seq_file_net(seq)->packet.sklist_lock)
 {
-       read_lock(&packet_sklist_lock);
-       return *pos ? packet_seq_idx(*pos - 1) : SEQ_START_TOKEN;
+       struct net *net = seq_file_net(seq);
+       read_lock(&net->packet.sklist_lock);
+       return *pos ? packet_seq_idx(net, *pos - 1) : SEQ_START_TOKEN;
 }
 
 static void *packet_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+       struct net *net = seq_file_net(seq);
        ++*pos;
        return  (v == SEQ_START_TOKEN)
-               ? sk_head(&packet_sklist)
+               ? sk_head(&net->packet.sklist)
                : sk_next((struct sock*)v) ;
 }
 
 static void packet_seq_stop(struct seq_file *seq, void *v)
+       __releases(seq_file_net(seq)->packet.sklist_lock)
 {
-       read_unlock(&packet_sklist_lock);
+       struct net *net = seq_file_net(seq);
+       read_unlock(&net->packet.sklist_lock);
 }
 
 static int packet_seq_show(struct seq_file *seq, void *v)
@@ -1926,7 +1926,8 @@ static const struct seq_operations packet_seq_ops = {
 
 static int packet_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open(file, &packet_seq_ops);
+       return seq_open_net(inode, file, &packet_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations packet_seq_fops = {
@@ -1934,15 +1935,37 @@ static const struct file_operations packet_seq_fops = {
        .open           = packet_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release,
+       .release        = seq_release_net,
 };
 
 #endif
 
+static int packet_net_init(struct net *net)
+{
+       rwlock_init(&net->packet.sklist_lock);
+       INIT_HLIST_HEAD(&net->packet.sklist);
+
+       if (!proc_net_fops_create(net, "packet", 0, &packet_seq_fops))
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void packet_net_exit(struct net *net)
+{
+       proc_net_remove(net, "packet");
+}
+
+static struct pernet_operations packet_net_ops = {
+       .init = packet_net_init,
+       .exit = packet_net_exit,
+};
+
+
 static void __exit packet_exit(void)
 {
-       proc_net_remove(&init_net, "packet");
        unregister_netdevice_notifier(&packet_netdev_notifier);
+       unregister_pernet_subsys(&packet_net_ops);
        sock_unregister(PF_PACKET);
        proto_unregister(&packet_proto);
 }
@@ -1955,8 +1978,8 @@ static int __init packet_init(void)
                goto out;
 
        sock_register(&packet_family_ops);
+       register_pernet_subsys(&packet_net_ops);
        register_netdevice_notifier(&packet_netdev_notifier);
-       proc_net_fops_create(&init_net, "packet", 0, &packet_seq_fops);
 out:
        return rc;
 }
index ed2d65cd80106db4510bb708c8514ce4aa17fea6..4a31a81059abb93a34c176d14e41b33e1f2e6fd8 100644 (file)
@@ -116,7 +116,7 @@ int rosecmp(rose_address *addr1, rose_address *addr2)
  */
 int rosecmpm(rose_address *addr1, rose_address *addr2, unsigned short mask)
 {
-       int i, j;
+       unsigned int i, j;
 
        if (mask > 10)
                return 1;
@@ -345,10 +345,9 @@ void rose_destroy_socket(struct sock *sk)
        if (atomic_read(&sk->sk_wmem_alloc) ||
            atomic_read(&sk->sk_rmem_alloc)) {
                /* Defer: outstanding buffers */
-               init_timer(&sk->sk_timer);
+               setup_timer(&sk->sk_timer, rose_destroy_timer,
+                               (unsigned long)sk);
                sk->sk_timer.expires  = jiffies + 10 * HZ;
-               sk->sk_timer.function = rose_destroy_timer;
-               sk->sk_timer.data     = (unsigned long)sk;
                add_timer(&sk->sk_timer);
        } else
                sock_put(sk);
@@ -974,8 +973,8 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
         */
        memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
 
-       len  = (((skb->data[3] >> 4) & 0x0F) + 1) / 2;
-       len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2;
+       len  = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
+       len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
        if (!rose_parse_facilities(skb->data + len + 4, &facilities)) {
                rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76);
                return 0;
@@ -1378,6 +1377,7 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
 #ifdef CONFIG_PROC_FS
 static void *rose_info_start(struct seq_file *seq, loff_t *pos)
+       __acquires(rose_list_lock)
 {
        int i;
        struct sock *s;
@@ -1405,6 +1405,7 @@ static void *rose_info_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rose_info_stop(struct seq_file *seq, void *v)
+       __releases(rose_list_lock)
 {
        spin_unlock_bh(&rose_list_lock);
 }
index 4ee0879d354064cad674b5423a3f9de40ef5ca38..7f7fcb46b4fa00371201dee0e83f17819db9c5e3 100644 (file)
@@ -182,7 +182,7 @@ static int rose_state3_machine(struct sock *sk, struct sk_buff *skb, int framety
                                break;
                        }
                        if (atomic_read(&sk->sk_rmem_alloc) >
-                           (sk->sk_rcvbuf / 2))
+                           (sk->sk_rcvbuf >> 1))
                                rose->condition |= ROSE_COND_OWN_RX_BUSY;
                }
                /*
index 540c0f26ffeeae0d5afb0caab156815deabbebaa..fb9359fb2358f243b4904bd52f642dee30ad9b55 100644 (file)
@@ -994,8 +994,8 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
                goto out;
        }
 
-       len  = (((skb->data[3] >> 4) & 0x0F) + 1) / 2;
-       len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2;
+       len  = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
+       len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
 
        memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
 
@@ -1068,6 +1068,7 @@ out:
 #ifdef CONFIG_PROC_FS
 
 static void *rose_node_start(struct seq_file *seq, loff_t *pos)
+       __acquires(rose_neigh_list_lock)
 {
        struct rose_node *rose_node;
        int i = 1;
@@ -1091,6 +1092,7 @@ static void *rose_node_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rose_node_stop(struct seq_file *seq, void *v)
+       __releases(rose_neigh_list_lock)
 {
        spin_unlock_bh(&rose_neigh_list_lock);
 }
@@ -1144,6 +1146,7 @@ const struct file_operations rose_nodes_fops = {
 };
 
 static void *rose_neigh_start(struct seq_file *seq, loff_t *pos)
+       __acquires(rose_neigh_list_lock)
 {
        struct rose_neigh *rose_neigh;
        int i = 1;
@@ -1167,6 +1170,7 @@ static void *rose_neigh_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rose_neigh_stop(struct seq_file *seq, void *v)
+       __releases(rose_neigh_list_lock)
 {
        spin_unlock_bh(&rose_neigh_list_lock);
 }
@@ -1227,6 +1231,7 @@ const struct file_operations rose_neigh_fops = {
 
 
 static void *rose_route_start(struct seq_file *seq, loff_t *pos)
+       __acquires(rose_route_list_lock)
 {
        struct rose_route *rose_route;
        int i = 1;
@@ -1250,6 +1255,7 @@ static void *rose_route_next(struct seq_file *seq, void *v, loff_t *pos)
 }
 
 static void rose_route_stop(struct seq_file *seq, void *v)
+       __releases(rose_route_list_lock)
 {
        spin_unlock_bh(&rose_route_list_lock);
 }
index 455b0555a6695518621ca558a19c77acf6410534..20be3485a97f9981971481b0915a01157e0e24e1 100644 (file)
@@ -138,29 +138,15 @@ static ctl_table rose_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table rose_dir_table[] = {
-       {
-               .ctl_name       = NET_ROSE,
-               .procname       = "rose",
-               .mode           = 0555,
-               .child          = rose_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table rose_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = rose_dir_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path rose_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "rose", .ctl_name = NET_ROSE, },
+       { }
 };
 
 void __init rose_register_sysctl(void)
 {
-       rose_table_header = register_sysctl_table(rose_root_table);
+       rose_table_header = register_sysctl_paths(rose_path, rose_table);
 }
 
 void rose_unregister_sysctl(void)
index d6389450c4bffee0da440bccfbc49857fa258417..5e82f1c0afbbee2120f489447ae4b7092e7aed18 100644 (file)
@@ -65,7 +65,7 @@ static void rxrpc_write_space(struct sock *sk)
        if (rxrpc_writable(sk)) {
                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                        wake_up_interruptible(sk->sk_sleep);
-               sk_wake_async(sk, 2, POLL_OUT);
+               sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        }
        read_unlock(&sk->sk_callback_lock);
 }
index d6667f7bc85edab71ecfa411f87d202d10b5fcd0..3869a58667521264be908a61c35adee9a1ec9a67 100644 (file)
@@ -651,7 +651,7 @@ rxrpc_incoming_connection(struct rxrpc_transport *trans,
 
        candidate->trans = trans;
        candidate->epoch = hdr->epoch;
-       candidate->cid = hdr->cid & __constant_cpu_to_be32(RXRPC_CIDMASK);
+       candidate->cid = hdr->cid & cpu_to_be32(RXRPC_CIDMASK);
        candidate->service_id = hdr->serviceId;
        candidate->security_ix = hdr->securityIndex;
        candidate->in_clientflag = RXRPC_CLIENT_INITIATED;
index 91b5bbb003e26b53496cfda72b687e009487e9ba..f8a699e929628d6293363092df50313f6ad5a8b2 100644 (file)
@@ -20,6 +20,7 @@
 #include <net/sock.h>
 #include <net/af_rxrpc.h>
 #include <net/ip.h>
+#include <net/udp.h>
 #include "ar-internal.h"
 
 unsigned long rxrpc_ack_timeout = 1;
@@ -594,7 +595,7 @@ dead_call:
        read_unlock_bh(&conn->lock);
 
        if (sp->hdr.flags & RXRPC_CLIENT_INITIATED &&
-           sp->hdr.seq == __constant_cpu_to_be32(1)) {
+           sp->hdr.seq == cpu_to_be32(1)) {
                _debug("incoming call");
                skb_queue_tail(&conn->trans->local->accept_queue, skb);
                rxrpc_queue_work(&conn->trans->local->acceptor);
@@ -707,10 +708,13 @@ void rxrpc_data_ready(struct sock *sk, int count)
        if (skb_checksum_complete(skb)) {
                rxrpc_free_skb(skb);
                rxrpc_put_local(local);
+               UDP_INC_STATS_BH(UDP_MIB_INERRORS, 0);
                _leave(" [CSUM failed]");
                return;
        }
 
+       UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, 0);
+
        /* the socket buffer we have is owned by UDP, with UDP's data all over
         * it, but we really want our own */
        skb_orphan(skb);
@@ -770,7 +774,7 @@ cant_route_call:
        _debug("can't route call");
        if (sp->hdr.flags & RXRPC_CLIENT_INITIATED &&
            sp->hdr.type == RXRPC_PACKET_TYPE_DATA) {
-               if (sp->hdr.seq == __constant_cpu_to_be32(1)) {
+               if (sp->hdr.seq == cpu_to_be32(1)) {
                        _debug("first packet");
                        skb_queue_tail(&local->accept_queue, skb);
                        rxrpc_queue_work(&local->acceptor);
index 90fa107a8af99bc82fa7a6fd5a28d13885c121a0..2abe2081a5e83b9a9ea848872f266ab4f1a711a1 100644 (file)
@@ -57,7 +57,7 @@ static void rxrpc_assess_MTU_size(struct rxrpc_peer *peer)
                BUG();
        }
 
-       ret = ip_route_output_key(&rt, &fl);
+       ret = ip_route_output_key(&init_net, &rt, &fl);
        if (ret < 0) {
                _leave(" [route err %d]", ret);
                return;
index 8e69d6993833be8c1aa9ceaaab8cdacd11b1248f..f48434adb7c242a5cae2e6cdbd074a43951aac1d 100644 (file)
@@ -284,7 +284,7 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
 
        /* calculate the security checksum */
        x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
-       x |= sp->hdr.seq & __constant_cpu_to_be32(0x3fffffff);
+       x |= sp->hdr.seq & cpu_to_be32(0x3fffffff);
        tmpbuf.x[0] = sp->hdr.callNumber;
        tmpbuf.x[1] = x;
 
@@ -518,7 +518,7 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
 
        /* validate the security checksum */
        x = htonl(call->channel << (32 - RXRPC_CIDSHIFT));
-       x |= sp->hdr.seq & __constant_cpu_to_be32(0x3fffffff);
+       x |= sp->hdr.seq & cpu_to_be32(0x3fffffff);
        tmpbuf.x[0] = call->call_id;
        tmpbuf.x[1] = x;
 
index 9c15c4888d1250481cc42dc58d59922915b25ca6..87af7c913d815e470e55b9274206ec5e320b1f1c 100644 (file)
@@ -198,6 +198,7 @@ config NET_SCH_NETEM
 
 config NET_SCH_INGRESS
        tristate "Ingress Qdisc"
+       depends on NET_CLS_ACT || NETFILTER
        ---help---
          Say Y here if you want to use classifiers for incoming packets.
          If unsure, say Y.
@@ -445,7 +446,6 @@ config NET_ACT_IPT
 config NET_ACT_NAT
         tristate "Stateless NAT"
         depends on NET_CLS_ACT
-        select NETFILTER
         ---help---
          Say Y here to do stateless NAT on IPv4 packets.  You should use
          netfilter for NAT unless you know what you are doing.
@@ -476,15 +476,6 @@ config NET_ACT_SIMP
          To compile this code as a module, choose M here: the
          module will be called simple.
 
-config NET_CLS_POLICE
-       bool "Traffic Policing (obsolete)"
-       select NET_CLS_ACT
-       select NET_ACT_POLICE
-       ---help---
-         Say Y here if you want to do traffic policing, i.e. strict
-         bandwidth limiting. This option is obsolete and just selects
-         the option replacing it. It will be removed in the future.
-
 config NET_CLS_IND
        bool "Incoming device classification"
        depends on NET_CLS_U32 || NET_CLS_FW
index 72cdb0fade205b3cc77df614de151eb5e6c114a6..0b8eb235bc136fff1eeb349f72c549a5ce4df3df 100644 (file)
@@ -18,6 +18,9 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/kmod.h>
+#include <linux/err.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
 #include <net/sch_generic.h>
 #include <net/act_api.h>
 #include <net/netlink.h>
@@ -66,7 +69,7 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
 {
        struct tcf_common *p;
        int err = 0, index = -1,i = 0, s_i = 0, n_i = 0;
-       struct rtattr *r ;
+       struct nlattr *nest;
 
        read_lock_bh(hinfo->lock);
 
@@ -81,15 +84,17 @@ static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
                                continue;
                        a->priv = p;
                        a->order = n_i;
-                       r = (struct rtattr *)skb_tail_pointer(skb);
-                       RTA_PUT(skb, a->order, 0, NULL);
+
+                       nest = nla_nest_start(skb, a->order);
+                       if (nest == NULL)
+                               goto nla_put_failure;
                        err = tcf_action_dump_1(skb, a, 0, 0);
                        if (err < 0) {
                                index--;
-                               nlmsg_trim(skb, r);
+                               nlmsg_trim(skb, nest);
                                goto done;
                        }
-                       r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
+                       nla_nest_end(skb, nest);
                        n_i++;
                        if (n_i >= TCA_ACT_MAX_PRIO)
                                goto done;
@@ -101,8 +106,8 @@ done:
                cb->args[0] += n_i;
        return n_i;
 
-rtattr_failure:
-       nlmsg_trim(skb, r);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        goto done;
 }
 
@@ -110,12 +115,13 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
                          struct tcf_hashinfo *hinfo)
 {
        struct tcf_common *p, *s_p;
-       struct rtattr *r ;
+       struct nlattr *nest;
        int i= 0, n_i = 0;
 
-       r = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, a->order, 0, NULL);
-       RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
+       nest = nla_nest_start(skb, a->order);
+       if (nest == NULL)
+               goto nla_put_failure;
+       NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
        for (i = 0; i < (hinfo->hmask + 1); i++) {
                p = hinfo->htab[tcf_hash(i, hinfo->hmask)];
 
@@ -127,12 +133,12 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a,
                        p = s_p;
                }
        }
-       RTA_PUT(skb, TCA_FCNT, 4, &n_i);
-       r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
+       NLA_PUT_U32(skb, TCA_FCNT, n_i);
+       nla_nest_end(skb, nest);
 
        return n_i;
-rtattr_failure:
-       nlmsg_trim(skb, r);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -EINVAL;
 }
 
@@ -209,7 +215,7 @@ struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind,
 }
 EXPORT_SYMBOL(tcf_hash_check);
 
-struct tcf_common *tcf_hash_create(u32 index, struct rtattr *est, struct tc_action *a, int size, int bind, u32 *idx_gen, struct tcf_hashinfo *hinfo)
+struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, int size, int bind, u32 *idx_gen, struct tcf_hashinfo *hinfo)
 {
        struct tcf_common *p = kzalloc(size, GFP_KERNEL);
 
@@ -261,6 +267,7 @@ int tcf_register_action(struct tc_action_ops *act)
        write_unlock(&act_mod_lock);
        return 0;
 }
+EXPORT_SYMBOL(tcf_register_action);
 
 int tcf_unregister_action(struct tc_action_ops *act)
 {
@@ -279,6 +286,7 @@ int tcf_unregister_action(struct tc_action_ops *act)
        write_unlock(&act_mod_lock);
        return err;
 }
+EXPORT_SYMBOL(tcf_unregister_action);
 
 /* lookup by name */
 static struct tc_action_ops *tc_lookup_action_n(char *kind)
@@ -301,15 +309,15 @@ static struct tc_action_ops *tc_lookup_action_n(char *kind)
        return a;
 }
 
-/* lookup by rtattr */
-static struct tc_action_ops *tc_lookup_action(struct rtattr *kind)
+/* lookup by nlattr */
+static struct tc_action_ops *tc_lookup_action(struct nlattr *kind)
 {
        struct tc_action_ops *a = NULL;
 
        if (kind) {
                read_lock(&act_mod_lock);
                for (a = act_base; a; a = a->next) {
-                       if (rtattr_strcmp(kind, a->kind) == 0) {
+                       if (nla_strcmp(kind, a->kind) == 0) {
                                if (!try_module_get(a->owner)) {
                                        read_unlock(&act_mod_lock);
                                        return NULL;
@@ -375,6 +383,7 @@ repeat:
 exec_done:
        return ret;
 }
+EXPORT_SYMBOL(tcf_action_exec);
 
 void tcf_action_destroy(struct tc_action *act, int bind)
 {
@@ -409,73 +418,77 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 {
        int err = -EINVAL;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *r;
+       struct nlattr *nest;
 
        if (a->ops == NULL || a->ops->dump == NULL)
                return err;
 
-       RTA_PUT(skb, TCA_KIND, IFNAMSIZ, a->ops->kind);
+       NLA_PUT_STRING(skb, TCA_KIND, a->ops->kind);
        if (tcf_action_copy_stats(skb, a, 0))
-               goto rtattr_failure;
-       r = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+               goto nla_put_failure;
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
        if ((err = tcf_action_dump_old(skb, a, bind, ref)) > 0) {
-               r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
+               nla_nest_end(skb, nest);
                return err;
        }
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
+EXPORT_SYMBOL(tcf_action_dump_1);
 
 int
 tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
 {
        struct tc_action *a;
        int err = -EINVAL;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *r ;
+       struct nlattr *nest;
 
        while ((a = act) != NULL) {
-               r = (struct rtattr *)skb_tail_pointer(skb);
                act = a->next;
-               RTA_PUT(skb, a->order, 0, NULL);
+               nest = nla_nest_start(skb, a->order);
+               if (nest == NULL)
+                       goto nla_put_failure;
                err = tcf_action_dump_1(skb, a, bind, ref);
                if (err < 0)
                        goto errout;
-               r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
+               nla_nest_end(skb, nest);
        }
 
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        err = -EINVAL;
 errout:
-       nlmsg_trim(skb, b);
+       nla_nest_cancel(skb, nest);
        return err;
 }
 
-struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
-                                   char *name, int ovr, int bind, int *err)
+struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
+                                   char *name, int ovr, int bind)
 {
        struct tc_action *a;
        struct tc_action_ops *a_o;
        char act_name[IFNAMSIZ];
-       struct rtattr *tb[TCA_ACT_MAX+1];
-       struct rtattr *kind;
-
-       *err = -EINVAL;
+       struct nlattr *tb[TCA_ACT_MAX+1];
+       struct nlattr *kind;
+       int err;
 
        if (name == NULL) {
-               if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
+               err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+               if (err < 0)
                        goto err_out;
-               kind = tb[TCA_ACT_KIND-1];
+               err = -EINVAL;
+               kind = tb[TCA_ACT_KIND];
                if (kind == NULL)
                        goto err_out;
-               if (rtattr_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
+               if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
                        goto err_out;
        } else {
+               err = -EINVAL;
                if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
                        goto err_out;
        }
@@ -496,36 +509,35 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
                 * indicate this using -EAGAIN.
                 */
                if (a_o != NULL) {
-                       *err = -EAGAIN;
+                       err = -EAGAIN;
                        goto err_mod;
                }
 #endif
-               *err = -ENOENT;
+               err = -ENOENT;
                goto err_out;
        }
 
-       *err = -ENOMEM;
+       err = -ENOMEM;
        a = kzalloc(sizeof(*a), GFP_KERNEL);
        if (a == NULL)
                goto err_mod;
 
        /* backward compatibility for policer */
        if (name == NULL)
-               *err = a_o->init(tb[TCA_ACT_OPTIONS-1], est, a, ovr, bind);
+               err = a_o->init(tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
        else
-               *err = a_o->init(rta, est, a, ovr, bind);
-       if (*err < 0)
+               err = a_o->init(nla, est, a, ovr, bind);
+       if (err < 0)
                goto err_free;
 
        /* module count goes up only when brand new policy is created
           if it exists and is only bound to in a_o->init() then
           ACT_P_CREATED is not returned (a zero is).
        */
-       if (*err != ACT_P_CREATED)
+       if (err != ACT_P_CREATED)
                module_put(a_o->owner);
        a->ops = a_o;
 
-       *err = 0;
        return a;
 
 err_free:
@@ -533,26 +545,26 @@ err_free:
 err_mod:
        module_put(a_o->owner);
 err_out:
-       return NULL;
+       return ERR_PTR(err);
 }
 
-struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est,
-                                 char *name, int ovr, int bind, int *err)
+struct tc_action *tcf_action_init(struct nlattr *nla, struct nlattr *est,
+                                 char *name, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
+       struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
        struct tc_action *head = NULL, *act, *act_prev = NULL;
+       int err;
        int i;
 
-       if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) {
-               *err = -EINVAL;
-               return head;
-       }
+       err = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
+       if (err < 0)
+               return ERR_PTR(err);
 
-       for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
-               act = tcf_action_init_1(tb[i], est, name, ovr, bind, err);
-               if (act == NULL)
+       for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+               act = tcf_action_init_1(tb[i], est, name, ovr, bind);
+               if (IS_ERR(act))
                        goto err;
-               act->order = i+1;
+               act->order = i;
 
                if (head == NULL)
                        head = act;
@@ -565,7 +577,7 @@ struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est,
 err:
        if (head != NULL)
                tcf_action_destroy(head, bind);
-       return NULL;
+       return act;
 }
 
 int tcf_action_copy_stats(struct sk_buff *skb, struct tc_action *a,
@@ -619,7 +631,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
        struct tcamsg *t;
        struct nlmsghdr *nlh;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *x;
+       struct nlattr *nest;
 
        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags);
 
@@ -628,18 +640,19 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq,
        t->tca__pad1 = 0;
        t->tca__pad2 = 0;
 
-       x = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+       nest = nla_nest_start(skb, TCA_ACT_TAB);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (tcf_action_dump(skb, a, bind, ref) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
+       nla_nest_end(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
 nlmsg_failure:
        nlmsg_trim(skb, b);
        return -1;
@@ -658,48 +671,51 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
                return -EINVAL;
        }
 
-       return rtnl_unicast(skb, pid);
+       return rtnl_unicast(skb, &init_net, pid);
 }
 
 static struct tc_action *
-tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err)
+tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 {
-       struct rtattr *tb[TCA_ACT_MAX+1];
+       struct nlattr *tb[TCA_ACT_MAX+1];
        struct tc_action *a;
        int index;
+       int err;
 
-       *err = -EINVAL;
-       if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
-               return NULL;
+       err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+       if (err < 0)
+               goto err_out;
 
-       if (tb[TCA_ACT_INDEX - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_ACT_INDEX - 1]) < sizeof(index))
-               return NULL;
-       index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]);
+       err = -EINVAL;
+       if (tb[TCA_ACT_INDEX] == NULL ||
+           nla_len(tb[TCA_ACT_INDEX]) < sizeof(index))
+               goto err_out;
+       index = nla_get_u32(tb[TCA_ACT_INDEX]);
 
-       *err = -ENOMEM;
+       err = -ENOMEM;
        a = kzalloc(sizeof(struct tc_action), GFP_KERNEL);
        if (a == NULL)
-               return NULL;
+               goto err_out;
 
-       *err = -EINVAL;
-       a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]);
+       err = -EINVAL;
+       a->ops = tc_lookup_action(tb[TCA_ACT_KIND]);
        if (a->ops == NULL)
                goto err_free;
        if (a->ops->lookup == NULL)
                goto err_mod;
-       *err = -ENOENT;
+       err = -ENOENT;
        if (a->ops->lookup(a, index) == 0)
                goto err_mod;
 
        module_put(a->ops->owner);
-       *err = 0;
        return a;
+
 err_mod:
        module_put(a->ops->owner);
 err_free:
        kfree(a);
-       return NULL;
+err_out:
+       return ERR_PTR(err);
 }
 
 static void cleanup_a(struct tc_action *act)
@@ -725,16 +741,16 @@ static struct tc_action *create_a(int i)
        return act;
 }
 
-static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
+static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
 {
        struct sk_buff *skb;
        unsigned char *b;
        struct nlmsghdr *nlh;
        struct tcamsg *t;
        struct netlink_callback dcb;
-       struct rtattr *x;
-       struct rtattr *tb[TCA_ACT_MAX+1];
-       struct rtattr *kind;
+       struct nlattr *nest;
+       struct nlattr *tb[TCA_ACT_MAX+1];
+       struct nlattr *kind;
        struct tc_action *a = create_a(0);
        int err = -EINVAL;
 
@@ -752,10 +768,12 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
 
        b = skb_tail_pointer(skb);
 
-       if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0)
+       err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
+       if (err < 0)
                goto err_out;
 
-       kind = tb[TCA_ACT_KIND-1];
+       err = -EINVAL;
+       kind = tb[TCA_ACT_KIND];
        a->ops = tc_lookup_action(kind);
        if (a->ops == NULL)
                goto err_out;
@@ -766,26 +784,27 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid)
        t->tca__pad1 = 0;
        t->tca__pad2 = 0;
 
-       x = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+       nest = nla_nest_start(skb, TCA_ACT_TAB);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        err = a->ops->walk(skb, &dcb, RTM_DELACTION, a);
        if (err < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
+       nla_nest_end(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        nlh->nlmsg_flags |= NLM_F_ROOT;
        module_put(a->ops->owner);
        kfree(a);
-       err = rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+       err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
        if (err > 0)
                return 0;
 
        return err;
 
-rtattr_failure:
+nla_put_failure:
 nlmsg_failure:
        module_put(a->ops->owner);
 err_out:
@@ -795,25 +814,28 @@ err_out:
 }
 
 static int
-tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event)
+tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
 {
-       int i, ret = 0;
-       struct rtattr *tb[TCA_ACT_MAX_PRIO+1];
+       int i, ret;
+       struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
        struct tc_action *head = NULL, *act, *act_prev = NULL;
 
-       if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0)
-               return -EINVAL;
+       ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL);
+       if (ret < 0)
+               return ret;
 
        if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
                if (tb[0] != NULL && tb[1] == NULL)
                        return tca_action_flush(tb[0], n, pid);
        }
 
-       for (i=0; i < TCA_ACT_MAX_PRIO && tb[i]; i++) {
-               act = tcf_action_get_1(tb[i], n, pid, &ret);
-               if (act == NULL)
+       for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+               act = tcf_action_get_1(tb[i], n, pid);
+               if (IS_ERR(act)) {
+                       ret = PTR_ERR(act);
                        goto err;
-               act->order = i+1;
+               }
+               act->order = i;
 
                if (head == NULL)
                        head = act;
@@ -842,7 +864,7 @@ tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event)
 
                /* now do the delete */
                tcf_action_destroy(head, 0);
-               ret = rtnetlink_send(skb, pid, RTNLGRP_TC,
+               ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
                                     n->nlmsg_flags&NLM_F_ECHO);
                if (ret > 0)
                        return 0;
@@ -859,7 +881,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
        struct tcamsg *t;
        struct nlmsghdr *nlh;
        struct sk_buff *skb;
-       struct rtattr *x;
+       struct nlattr *nest;
        unsigned char *b;
        int err = 0;
 
@@ -875,23 +897,24 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
        t->tca__pad1 = 0;
        t->tca__pad2 = 0;
 
-       x = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+       nest = nla_nest_start(skb, TCA_ACT_TAB);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (tcf_action_dump(skb, a, 0, 0) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
+       nla_nest_end(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        NETLINK_CB(skb).dst_group = RTNLGRP_TC;
 
-       err = rtnetlink_send(skb, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
+       err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
        if (err > 0)
                err = 0;
        return err;
 
-rtattr_failure:
+nla_put_failure:
 nlmsg_failure:
        kfree_skb(skb);
        return -1;
@@ -899,16 +922,20 @@ nlmsg_failure:
 
 
 static int
-tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int ovr)
+tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
 {
        int ret = 0;
        struct tc_action *act;
        struct tc_action *a;
        u32 seq = n->nlmsg_seq;
 
-       act = tcf_action_init(rta, NULL, NULL, ovr, 0, &ret);
+       act = tcf_action_init(nla, NULL, NULL, ovr, 0);
        if (act == NULL)
                goto done;
+       if (IS_ERR(act)) {
+               ret = PTR_ERR(act);
+               goto done;
+       }
 
        /* dump then free all the actions after update; inserted policy
         * stays intact
@@ -924,11 +951,19 @@ done:
 
 static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
-       struct rtattr **tca = arg;
+       struct net *net = skb->sk->sk_net;
+       struct nlattr *tca[TCA_ACT_MAX + 1];
        u32 pid = skb ? NETLINK_CB(skb).pid : 0;
        int ret = 0, ovr = 0;
 
-       if (tca[TCA_ACT_TAB-1] == NULL) {
+       if (net != &init_net)
+               return -EINVAL;
+
+       ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
+       if (ret < 0)
+               return ret;
+
+       if (tca[TCA_ACT_TAB] == NULL) {
                printk("tc_ctl_action: received NO action attribs\n");
                return -EINVAL;
        }
@@ -946,15 +981,15 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                if (n->nlmsg_flags&NLM_F_REPLACE)
                        ovr = 1;
 replay:
-               ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr);
+               ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr);
                if (ret == -EAGAIN)
                        goto replay;
                break;
        case RTM_DELACTION:
-               ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION);
+               ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION);
                break;
        case RTM_GETACTION:
-               ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_GETACTION);
+               ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION);
                break;
        default:
                BUG();
@@ -963,33 +998,30 @@ replay:
        return ret;
 }
 
-static struct rtattr *
+static struct nlattr *
 find_dump_kind(struct nlmsghdr *n)
 {
-       struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
-       struct rtattr *tb[TCA_ACT_MAX_PRIO + 1];
-       struct rtattr *rta[TCAA_MAX + 1];
-       struct rtattr *kind;
-       int min_len = NLMSG_LENGTH(sizeof(struct tcamsg));
-       int attrlen = n->nlmsg_len - NLMSG_ALIGN(min_len);
-       struct rtattr *attr = (void *) n + NLMSG_ALIGN(min_len);
-
-       if (rtattr_parse(rta, TCAA_MAX, attr, attrlen) < 0)
+       struct nlattr *tb1, *tb2[TCA_ACT_MAX+1];
+       struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
+       struct nlattr *nla[TCAA_MAX + 1];
+       struct nlattr *kind;
+
+       if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX, NULL) < 0)
                return NULL;
-       tb1 = rta[TCA_ACT_TAB - 1];
+       tb1 = nla[TCA_ACT_TAB];
        if (tb1 == NULL)
                return NULL;
 
-       if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(tb1),
-                        NLMSG_ALIGN(RTA_PAYLOAD(tb1))) < 0)
-               return NULL;
-       if (tb[0] == NULL)
+       if (nla_parse(tb, TCA_ACT_MAX_PRIO, nla_data(tb1),
+                     NLMSG_ALIGN(nla_len(tb1)), NULL) < 0)
                return NULL;
 
-       if (rtattr_parse(tb2, TCA_ACT_MAX, RTA_DATA(tb[0]),
-                        RTA_PAYLOAD(tb[0])) < 0)
+       if (tb[1] == NULL)
                return NULL;
-       kind = tb2[TCA_ACT_KIND-1];
+       if (nla_parse(tb2, TCA_ACT_MAX, nla_data(tb[1]),
+                     nla_len(tb[1]), NULL) < 0)
+               return NULL;
+       kind = tb2[TCA_ACT_KIND];
 
        return kind;
 }
@@ -997,14 +1029,18 @@ find_dump_kind(struct nlmsghdr *n)
 static int
 tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        struct nlmsghdr *nlh;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *x;
+       struct nlattr *nest;
        struct tc_action_ops *a_o;
        struct tc_action a;
        int ret = 0;
        struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
-       struct rtattr *kind = find_dump_kind(cb->nlh);
+       struct nlattr *kind = find_dump_kind(cb->nlh);
+
+       if (net != &init_net)
+               return 0;
 
        if (kind == NULL) {
                printk("tc_dump_action: action bad kind\n");
@@ -1021,7 +1057,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
 
        if (a_o->walk == NULL) {
                printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind);
-               goto rtattr_failure;
+               goto nla_put_failure;
        }
 
        nlh = NLMSG_PUT(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
@@ -1031,18 +1067,19 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
        t->tca__pad1 = 0;
        t->tca__pad2 = 0;
 
-       x = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_ACT_TAB, 0, NULL);
+       nest = nla_nest_start(skb, TCA_ACT_TAB);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        ret = a_o->walk(skb, cb, RTM_GETACTION, &a);
        if (ret < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (ret > 0) {
-               x->rta_len = skb_tail_pointer(skb) - (u8 *)x;
+               nla_nest_end(skb, nest);
                ret = skb->len;
        } else
-               nlmsg_trim(skb, x);
+               nla_nest_cancel(skb, nest);
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        if (NETLINK_CB(cb->skb).pid && ret)
@@ -1050,7 +1087,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
        module_put(a_o->owner);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
 nlmsg_failure:
        module_put(a_o->owner);
        nlmsg_trim(skb, b);
@@ -1067,8 +1104,3 @@ static int __init tc_action_init(void)
 }
 
 subsys_initcall(tc_action_init);
-
-EXPORT_SYMBOL(tcf_register_action);
-EXPORT_SYMBOL(tcf_unregister_action);
-EXPORT_SYMBOL(tcf_action_exec);
-EXPORT_SYMBOL(tcf_action_dump_1);
index a9631e426d916c81fbe752cd5357d75e50f4dace..422872c4f14b9e2afe86261f3e03e7d5d3526c3b 100644 (file)
@@ -53,28 +53,34 @@ typedef int (*g_rand)(struct tcf_gact *gact);
 static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ };
 #endif /* CONFIG_GACT_PROB */
 
-static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {
+       [TCA_GACT_PARMS]        = { .len = sizeof(struct tc_gact) },
+       [TCA_GACT_PROB]         = { .len = sizeof(struct tc_gact_p) },
+};
+
+static int tcf_gact_init(struct nlattr *nla, struct nlattr *est,
                         struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_GACT_MAX];
+       struct nlattr *tb[TCA_GACT_MAX + 1];
        struct tc_gact *parm;
        struct tcf_gact *gact;
        struct tcf_common *pc;
        int ret = 0;
+       int err;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_GACT_PARMS - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_GACT_PARMS - 1]) < sizeof(*parm))
+       err = nla_parse_nested(tb, TCA_GACT_MAX, nla, gact_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_GACT_PARMS] == NULL)
                return -EINVAL;
-       parm = RTA_DATA(tb[TCA_GACT_PARMS - 1]);
+       parm = nla_data(tb[TCA_GACT_PARMS]);
 
-       if (tb[TCA_GACT_PROB-1] != NULL)
-#ifdef CONFIG_GACT_PROB
-               if (RTA_PAYLOAD(tb[TCA_GACT_PROB-1]) < sizeof(struct tc_gact_p))
-                       return -EINVAL;
-#else
+#ifndef CONFIG_GACT_PROB
+       if (tb[TCA_GACT_PROB] != NULL)
                return -EOPNOTSUPP;
 #endif
 
@@ -97,8 +103,8 @@ static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
        spin_lock_bh(&gact->tcf_lock);
        gact->tcf_action = parm->action;
 #ifdef CONFIG_GACT_PROB
-       if (tb[TCA_GACT_PROB-1] != NULL) {
-               struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]);
+       if (tb[TCA_GACT_PROB] != NULL) {
+               struct tc_gact_p *p_parm = nla_data(tb[TCA_GACT_PROB]);
                gact->tcfg_paction = p_parm->paction;
                gact->tcfg_pval    = p_parm->pval;
                gact->tcfg_ptype   = p_parm->ptype;
@@ -154,23 +160,23 @@ static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
        opt.refcnt = gact->tcf_refcnt - ref;
        opt.bindcnt = gact->tcf_bindcnt - bind;
        opt.action = gact->tcf_action;
-       RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
 #ifdef CONFIG_GACT_PROB
        if (gact->tcfg_ptype) {
                struct tc_gact_p p_opt;
                p_opt.paction = gact->tcfg_paction;
                p_opt.pval = gact->tcfg_pval;
                p_opt.ptype = gact->tcfg_ptype;
-               RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
+               NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
        }
 #endif
        t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(gact->tcf_tm.expires);
-       RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
+       NLA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
index fa006e06ce3308270b51211135e72cc978ef9b2b..da696fd3e34125c7f232ae937a83d5bb1286887f 100644 (file)
@@ -92,10 +92,17 @@ static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
        return ret;
 }
 
-static int tcf_ipt_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
+       [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ },
+       [TCA_IPT_HOOK]  = { .type = NLA_U32 },
+       [TCA_IPT_INDEX] = { .type = NLA_U32 },
+       [TCA_IPT_TARG]  = { .len = sizeof(struct ipt_entry_target) },
+};
+
+static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
                        struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_IPT_MAX];
+       struct nlattr *tb[TCA_IPT_MAX + 1];
        struct tcf_ipt *ipt;
        struct tcf_common *pc;
        struct ipt_entry_target *td, *t;
@@ -104,22 +111,24 @@ static int tcf_ipt_init(struct rtattr *rta, struct rtattr *est,
        u32 hook = 0;
        u32 index = 0;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_IPT_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_IPT_HOOK-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_IPT_HOOK-1]) < sizeof(u32))
+       err = nla_parse_nested(tb, TCA_IPT_MAX, nla, ipt_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_IPT_HOOK] == NULL)
                return -EINVAL;
-       if (tb[TCA_IPT_TARG-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < sizeof(*t))
+       if (tb[TCA_IPT_TARG] == NULL)
                return -EINVAL;
-       td = (struct ipt_entry_target *)RTA_DATA(tb[TCA_IPT_TARG-1]);
-       if (RTA_PAYLOAD(tb[TCA_IPT_TARG-1]) < td->u.target_size)
+
+       td = (struct ipt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
+       if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size)
                return -EINVAL;
 
-       if (tb[TCA_IPT_INDEX-1] != NULL &&
-           RTA_PAYLOAD(tb[TCA_IPT_INDEX-1]) >= sizeof(u32))
-               index = *(u32 *)RTA_DATA(tb[TCA_IPT_INDEX-1]);
+       if (tb[TCA_IPT_INDEX] != NULL)
+               index = nla_get_u32(tb[TCA_IPT_INDEX]);
 
        pc = tcf_hash_check(index, a, bind, &ipt_hash_info);
        if (!pc) {
@@ -136,14 +145,14 @@ static int tcf_ipt_init(struct rtattr *rta, struct rtattr *est,
        }
        ipt = to_ipt(pc);
 
-       hook = *(u32 *)RTA_DATA(tb[TCA_IPT_HOOK-1]);
+       hook = nla_get_u32(tb[TCA_IPT_HOOK]);
 
        err = -ENOMEM;
        tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
        if (unlikely(!tname))
                goto err1;
-       if (tb[TCA_IPT_TABLE - 1] == NULL ||
-           rtattr_strlcpy(tname, tb[TCA_IPT_TABLE-1], IFNAMSIZ) >= IFNAMSIZ)
+       if (tb[TCA_IPT_TABLE] == NULL ||
+           nla_strlcpy(tname, tb[TCA_IPT_TABLE], IFNAMSIZ) >= IFNAMSIZ)
                strcpy(tname, "mangle");
 
        t = kmemdup(td, td->u.target_size, GFP_KERNEL);
@@ -243,25 +252,25 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
 
        t = kmemdup(ipt->tcfi_t, ipt->tcfi_t->u.user.target_size, GFP_ATOMIC);
        if (unlikely(!t))
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        c.bindcnt = ipt->tcf_bindcnt - bind;
        c.refcnt = ipt->tcf_refcnt - ref;
        strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
 
-       RTA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
-       RTA_PUT(skb, TCA_IPT_INDEX, 4, &ipt->tcf_index);
-       RTA_PUT(skb, TCA_IPT_HOOK, 4, &ipt->tcfi_hook);
-       RTA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
-       RTA_PUT(skb, TCA_IPT_TABLE, IFNAMSIZ, ipt->tcfi_tname);
+       NLA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
+       NLA_PUT_U32(skb, TCA_IPT_INDEX, ipt->tcf_index);
+       NLA_PUT_U32(skb, TCA_IPT_HOOK, ipt->tcfi_hook);
+       NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
+       NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname);
        tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install);
        tm.lastuse = jiffies_to_clock_t(jiffies - ipt->tcf_tm.lastuse);
        tm.expires = jiffies_to_clock_t(ipt->tcf_tm.expires);
-       RTA_PUT(skb, TCA_IPT_TM, sizeof (tm), &tm);
+       NLA_PUT(skb, TCA_IPT_TM, sizeof (tm), &tm);
        kfree(t);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        kfree(t);
        return -1;
index c3fde9180f9d713ac6f358628b1e7737a2cc08c9..1aff005d95cda6d713bbeca85c88280228ed5f98 100644 (file)
@@ -54,24 +54,31 @@ static inline int tcf_mirred_release(struct tcf_mirred *m, int bind)
        return 0;
 }
 
-static int tcf_mirred_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
+       [TCA_MIRRED_PARMS]      = { .len = sizeof(struct tc_mirred) },
+};
+
+static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
                           struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_MIRRED_MAX];
+       struct nlattr *tb[TCA_MIRRED_MAX + 1];
        struct tc_mirred *parm;
        struct tcf_mirred *m;
        struct tcf_common *pc;
        struct net_device *dev = NULL;
-       int ret = 0;
+       int ret = 0, err;
        int ok_push = 0;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_MIRRED_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_MIRRED_PARMS-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_MIRRED_PARMS-1]) < sizeof(*parm))
+       err = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_MIRRED_PARMS] == NULL)
                return -EINVAL;
-       parm = RTA_DATA(tb[TCA_MIRRED_PARMS-1]);
+       parm = nla_data(tb[TCA_MIRRED_PARMS]);
 
        if (parm->ifindex) {
                dev = __dev_get_by_index(&init_net, parm->ifindex);
@@ -207,14 +214,14 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
        opt.bindcnt = m->tcf_bindcnt - bind;
        opt.eaction = m->tcfm_eaction;
        opt.ifindex = m->tcfm_ifindex;
-       RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
        t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(m->tcf_tm.expires);
-       RTA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
+       NLA_PUT(skb, TCA_MIRRED_TM, sizeof(t), &t);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
index c96273bcaf9cbce08531b01f5ccdf785ef320c4c..0a3c8339767a9f71fe3011da3267af2b6b634391 100644 (file)
@@ -40,22 +40,29 @@ static struct tcf_hashinfo nat_hash_info = {
        .lock   =       &nat_lock,
 };
 
-static int tcf_nat_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
+       [TCA_NAT_PARMS] = { .len = sizeof(struct tc_nat) },
+};
+
+static int tcf_nat_init(struct nlattr *nla, struct nlattr *est,
                        struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_NAT_MAX];
+       struct nlattr *tb[TCA_NAT_MAX + 1];
        struct tc_nat *parm;
-       int ret = 0;
+       int ret = 0, err;
        struct tcf_nat *p;
        struct tcf_common *pc;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_NAT_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_NAT_PARMS - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_NAT_PARMS - 1]) < sizeof(*parm))
+       err = nla_parse_nested(tb, TCA_NAT_MAX, nla, nat_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_NAT_PARMS] == NULL)
                return -EINVAL;
-       parm = RTA_DATA(tb[TCA_NAT_PARMS - 1]);
+       parm = nla_data(tb[TCA_NAT_PARMS]);
 
        pc = tcf_hash_check(parm->index, a, bind, &nat_hash_info);
        if (!pc) {
@@ -151,7 +158,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
                else
                        iph->daddr = new_addr;
 
-               nf_csum_replace4(&iph->check, addr, new_addr);
+               csum_replace4(&iph->check, addr, new_addr);
        }
 
        ihl = iph->ihl * 4;
@@ -169,7 +176,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
                        goto drop;
 
                tcph = (void *)(skb_network_header(skb) + ihl);
-               nf_proto_csum_replace4(&tcph->check, skb, addr, new_addr, 1);
+               inet_proto_csum_replace4(&tcph->check, skb, addr, new_addr, 1);
                break;
        }
        case IPPROTO_UDP:
@@ -184,8 +191,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
 
                udph = (void *)(skb_network_header(skb) + ihl);
                if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) {
-                       nf_proto_csum_replace4(&udph->check, skb, addr,
-                                              new_addr, 1);
+                       inet_proto_csum_replace4(&udph->check, skb, addr,
+                                                new_addr, 1);
                        if (!udph->check)
                                udph->check = CSUM_MANGLED_0;
                }
@@ -232,8 +239,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
                else
                        iph->saddr = new_addr;
 
-               nf_proto_csum_replace4(&icmph->checksum, skb, addr, new_addr,
-                                      1);
+               inet_proto_csum_replace4(&icmph->checksum, skb, addr, new_addr,
+                                        1);
                break;
        }
        default:
@@ -275,17 +282,17 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
        opt->refcnt = p->tcf_refcnt - ref;
        opt->bindcnt = p->tcf_bindcnt - bind;
 
-       RTA_PUT(skb, TCA_NAT_PARMS, s, opt);
+       NLA_PUT(skb, TCA_NAT_PARMS, s, opt);
        t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
-       RTA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
+       NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
 
        kfree(opt);
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        kfree(opt);
        return -1;
index b46fab5fb323a131946ce418b6d97c8889a941f3..3cc4cb9e500ec972e0d451d046f0824da470a311 100644 (file)
@@ -33,26 +33,33 @@ static struct tcf_hashinfo pedit_hash_info = {
        .lock   =       &pedit_lock,
 };
 
-static int tcf_pedit_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
+       [TCA_PEDIT_PARMS]       = { .len = sizeof(struct tcf_pedit) },
+};
+
+static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
                          struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_PEDIT_MAX];
+       struct nlattr *tb[TCA_PEDIT_MAX + 1];
        struct tc_pedit *parm;
-       int ret = 0;
+       int ret = 0, err;
        struct tcf_pedit *p;
        struct tcf_common *pc;
        struct tc_pedit_key *keys = NULL;
        int ksize;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_PEDIT_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_PEDIT_PARMS - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm))
+       err = nla_parse_nested(tb, TCA_PEDIT_MAX, nla, pedit_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_PEDIT_PARMS] == NULL)
                return -EINVAL;
-       parm = RTA_DATA(tb[TCA_PEDIT_PARMS-1]);
+       parm = nla_data(tb[TCA_PEDIT_PARMS]);
        ksize = parm->nkeys * sizeof(struct tc_pedit_key);
-       if (RTA_PAYLOAD(tb[TCA_PEDIT_PARMS-1]) < sizeof(*parm) + ksize)
+       if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize)
                return -EINVAL;
 
        pc = tcf_hash_check(parm->index, a, bind, &pedit_hash_info);
@@ -206,15 +213,15 @@ static int tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,
        opt->refcnt = p->tcf_refcnt - ref;
        opt->bindcnt = p->tcf_bindcnt - bind;
 
-       RTA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
+       NLA_PUT(skb, TCA_PEDIT_PARMS, s, opt);
        t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
-       RTA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
+       NLA_PUT(skb, TCA_PEDIT_TM, sizeof(t), &t);
        kfree(opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        kfree(opt);
        return -1;
index a73e3e6d87ea378f3f72b36b69d3ca3266061949..0898120bbcc0b64ecf79e8ec589a7dad6c0cda70 100644 (file)
@@ -54,7 +54,7 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
 {
        struct tcf_common *p;
        int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
-       struct rtattr *r;
+       struct nlattr *nest;
 
        read_lock_bh(&police_lock);
 
@@ -69,18 +69,19 @@ static int tcf_act_police_walker(struct sk_buff *skb, struct netlink_callback *c
                                continue;
                        a->priv = p;
                        a->order = index;
-                       r = (struct rtattr *)skb_tail_pointer(skb);
-                       RTA_PUT(skb, a->order, 0, NULL);
+                       nest = nla_nest_start(skb, a->order);
+                       if (nest == NULL)
+                               goto nla_put_failure;
                        if (type == RTM_DELACTION)
                                err = tcf_action_dump_1(skb, a, 0, 1);
                        else
                                err = tcf_action_dump_1(skb, a, 0, 0);
                        if (err < 0) {
                                index--;
-                               nlmsg_trim(skb, r);
+                               nla_nest_cancel(skb, nest);
                                goto done;
                        }
-                       r->rta_len = skb_tail_pointer(skb) - (u8 *)r;
+                       nla_nest_end(skb, nest);
                        n_i++;
                }
        }
@@ -90,8 +91,8 @@ done:
                cb->args[0] += n_i;
        return n_i;
 
-rtattr_failure:
-       nlmsg_trim(skb, r);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        goto done;
 }
 
@@ -118,33 +119,37 @@ static void tcf_police_destroy(struct tcf_police *p)
        BUG_TRAP(0);
 }
 
-static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
+       [TCA_POLICE_RATE]       = { .len = TC_RTAB_SIZE },
+       [TCA_POLICE_PEAKRATE]   = { .len = TC_RTAB_SIZE },
+       [TCA_POLICE_AVRATE]     = { .type = NLA_U32 },
+       [TCA_POLICE_RESULT]     = { .type = NLA_U32 },
+};
+
+static int tcf_act_police_locate(struct nlattr *nla, struct nlattr *est,
                                 struct tc_action *a, int ovr, int bind)
 {
        unsigned h;
        int ret = 0, err;
-       struct rtattr *tb[TCA_POLICE_MAX];
+       struct nlattr *tb[TCA_POLICE_MAX + 1];
        struct tc_police *parm;
        struct tcf_police *police;
        struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
        int size;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_POLICE_TBF-1] == NULL)
-               return -EINVAL;
-       size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]);
-       if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat))
-               return -EINVAL;
-       parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
+       err = nla_parse_nested(tb, TCA_POLICE_MAX, nla, police_policy);
+       if (err < 0)
+               return err;
 
-       if (tb[TCA_POLICE_RESULT-1] != NULL &&
-           RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+       if (tb[TCA_POLICE_TBF] == NULL)
                return -EINVAL;
-       if (tb[TCA_POLICE_RESULT-1] != NULL &&
-           RTA_PAYLOAD(tb[TCA_POLICE_RESULT-1]) != sizeof(u32))
+       size = nla_len(tb[TCA_POLICE_TBF]);
+       if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat))
                return -EINVAL;
+       parm = nla_data(tb[TCA_POLICE_TBF]);
 
        if (parm->index) {
                struct tcf_common *pc;
@@ -174,12 +179,12 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
 override:
        if (parm->rate.rate) {
                err = -ENOMEM;
-               R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE-1]);
+               R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
                if (R_tab == NULL)
                        goto failure;
                if (parm->peakrate.rate) {
                        P_tab = qdisc_get_rtab(&parm->peakrate,
-                                              tb[TCA_POLICE_PEAKRATE-1]);
+                                              tb[TCA_POLICE_PEAKRATE]);
                        if (P_tab == NULL) {
                                qdisc_put_rtab(R_tab);
                                goto failure;
@@ -197,8 +202,8 @@ override:
                police->tcfp_P_tab = P_tab;
        }
 
-       if (tb[TCA_POLICE_RESULT-1])
-               police->tcfp_result = *(u32*)RTA_DATA(tb[TCA_POLICE_RESULT-1]);
+       if (tb[TCA_POLICE_RESULT])
+               police->tcfp_result = nla_get_u32(tb[TCA_POLICE_RESULT]);
        police->tcfp_toks = police->tcfp_burst = parm->burst;
        police->tcfp_mtu = parm->mtu;
        if (police->tcfp_mtu == 0) {
@@ -210,9 +215,8 @@ override:
                police->tcfp_ptoks = L2T_P(police, police->tcfp_mtu);
        police->tcf_action = parm->action;
 
-       if (tb[TCA_POLICE_AVRATE-1])
-               police->tcfp_ewma_rate =
-                       *(u32*)RTA_DATA(tb[TCA_POLICE_AVRATE-1]);
+       if (tb[TCA_POLICE_AVRATE])
+               police->tcfp_ewma_rate = nla_get_u32(tb[TCA_POLICE_AVRATE]);
        if (est)
                gen_replace_estimator(&police->tcf_bstats,
                                      &police->tcf_rate_est,
@@ -332,15 +336,14 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
                opt.peakrate = police->tcfp_P_tab->rate;
        else
                memset(&opt.peakrate, 0, sizeof(opt.peakrate));
-       RTA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
        if (police->tcfp_result)
-               RTA_PUT(skb, TCA_POLICE_RESULT, sizeof(int),
-                       &police->tcfp_result);
+               NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result);
        if (police->tcfp_ewma_rate)
-               RTA_PUT(skb, TCA_POLICE_AVRATE, 4, &police->tcfp_ewma_rate);
+               NLA_PUT_U32(skb, TCA_POLICE_AVRATE, police->tcfp_ewma_rate);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
index fb84ef33d14f75d82281ab21b932ebea416e1e6f..fbde461b716cc90dc8de261870078ed7c42b8703 100644 (file)
@@ -84,30 +84,37 @@ static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
        return alloc_defdata(d, datalen, defdata);
 }
 
-static int tcf_simp_init(struct rtattr *rta, struct rtattr *est,
+static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
+       [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
+};
+
+static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
                         struct tc_action *a, int ovr, int bind)
 {
-       struct rtattr *tb[TCA_DEF_MAX];
+       struct nlattr *tb[TCA_DEF_MAX + 1];
        struct tc_defact *parm;
        struct tcf_defact *d;
        struct tcf_common *pc;
        void *defdata;
        u32 datalen = 0;
-       int ret = 0;
+       int ret = 0, err;
 
-       if (rta == NULL || rtattr_parse_nested(tb, TCA_DEF_MAX, rta) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_DEF_PARMS - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_DEF_PARMS - 1]) < sizeof(*parm))
+       err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_DEF_PARMS] == NULL)
                return -EINVAL;
 
-       parm = RTA_DATA(tb[TCA_DEF_PARMS - 1]);
-       defdata = RTA_DATA(tb[TCA_DEF_DATA - 1]);
+       parm = nla_data(tb[TCA_DEF_PARMS]);
+       defdata = nla_data(tb[TCA_DEF_DATA]);
        if (defdata == NULL)
                return -EINVAL;
 
-       datalen = RTA_PAYLOAD(tb[TCA_DEF_DATA - 1]);
+       datalen = nla_len(tb[TCA_DEF_DATA]);
        if (datalen <= 0)
                return -EINVAL;
 
@@ -164,15 +171,15 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
        opt.refcnt = d->tcf_refcnt - ref;
        opt.bindcnt = d->tcf_bindcnt - bind;
        opt.action = d->tcf_action;
-       RTA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
-       RTA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata);
+       NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata);
        t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
        t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
        t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
-       RTA_PUT(skb, TCA_DEF_TM, sizeof(t), &t);
+       NLA_PUT(skb, TCA_DEF_TM, sizeof(t), &t);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
index 03657976fd501f9715840750e51bf9029f1c631d..3377ca0d0a0c8470bc13e539fb4047820ed20b85 100644 (file)
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/netlink.h>
+#include <linux/err.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 #include <net/pkt_cls.h>
 
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
 /* The list of all installed classifier types */
 
-static struct tcf_proto_ops *tcf_proto_base;
+static struct tcf_proto_ops *tcf_proto_base __read_mostly;
 
 /* Protects list of registered TC modules. It is pure SMP lock. */
 static DEFINE_RWLOCK(cls_mod_lock);
 
 /* Find classifier type by string name */
 
-static struct tcf_proto_ops * tcf_proto_lookup_ops(struct rtattr *kind)
+static struct tcf_proto_ops *tcf_proto_lookup_ops(struct nlattr *kind)
 {
        struct tcf_proto_ops *t = NULL;
 
        if (kind) {
                read_lock(&cls_mod_lock);
                for (t = tcf_proto_base; t; t = t->next) {
-                       if (rtattr_strcmp(kind, t->kind) == 0) {
+                       if (nla_strcmp(kind, t->kind) == 0) {
                                if (!try_module_get(t->owner))
                                        t = NULL;
                                break;
@@ -79,6 +76,7 @@ out:
        write_unlock(&cls_mod_lock);
        return rc;
 }
+EXPORT_SYMBOL(register_tcf_proto_ops);
 
 int unregister_tcf_proto_ops(struct tcf_proto_ops *ops)
 {
@@ -98,6 +96,7 @@ out:
        write_unlock(&cls_mod_lock);
        return rc;
 }
+EXPORT_SYMBOL(unregister_tcf_proto_ops);
 
 static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
                          struct tcf_proto *tp, unsigned long fh, int event);
@@ -105,9 +104,9 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
 
 /* Select new prio value from the range, managed by kernel. */
 
-static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp)
+static inline u32 tcf_auto_prio(struct tcf_proto *tp)
 {
-       u32 first = TC_H_MAKE(0xC0000000U,0U);
+       u32 first = TC_H_MAKE(0xC0000000U, 0U);
 
        if (tp)
                first = tp->prio-1;
@@ -119,7 +118,8 @@ static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp)
 
 static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
-       struct rtattr **tca;
+       struct net *net = skb->sk->sk_net;
+       struct nlattr *tca[TCA_MAX + 1];
        struct tcmsg *t;
        u32 protocol;
        u32 prio;
@@ -130,13 +130,15 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        struct tcf_proto **back, **chain;
        struct tcf_proto *tp;
        struct tcf_proto_ops *tp_ops;
-       struct Qdisc_class_ops *cops;
+       const struct Qdisc_class_ops *cops;
        unsigned long cl;
        unsigned long fh;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
 replay:
-       tca = arg;
        t = NLMSG_DATA(n);
        protocol = TC_H_MIN(t->tcm_info);
        prio = TC_H_MAJ(t->tcm_info);
@@ -148,21 +150,29 @@ replay:
                /* If no priority is given, user wants we allocated it. */
                if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
                        return -ENOENT;
-               prio = TC_H_MAKE(0x80000000U,0U);
+               prio = TC_H_MAKE(0x80000000U, 0U);
        }
 
        /* Find head of filter chain. */
 
        /* Find link */
-       if ((dev = __dev_get_by_index(&init_net, t->tcm_ifindex)) == NULL)
+       dev = __dev_get_by_index(&init_net, t->tcm_ifindex);
+       if (dev == NULL)
                return -ENODEV;
 
+       err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
+       if (err < 0)
+               return err;
+
        /* Find qdisc */
        if (!parent) {
                q = dev->qdisc_sleeping;
                parent = q->handle;
-       } else if ((q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent))) == NULL)
-               return -EINVAL;
+       } else {
+               q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent));
+               if (q == NULL)
+                       return -EINVAL;
+       }
 
        /* Is it classful? */
        if ((cops = q->ops->cl_ops) == NULL)
@@ -196,7 +206,7 @@ replay:
        if (tp == NULL) {
                /* Proto-tcf does not exist, create new one */
 
-               if (tca[TCA_KIND-1] == NULL || !protocol)
+               if (tca[TCA_KIND] == NULL || !protocol)
                        goto errout;
 
                err = -ENOENT;
@@ -207,17 +217,18 @@ replay:
                /* Create new proto tcf */
 
                err = -ENOBUFS;
-               if ((tp = kzalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
+               tp = kzalloc(sizeof(*tp), GFP_KERNEL);
+               if (tp == NULL)
                        goto errout;
                err = -EINVAL;
-               tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
+               tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
                if (tp_ops == NULL) {
 #ifdef CONFIG_KMOD
-                       struct rtattr *kind = tca[TCA_KIND-1];
+                       struct nlattr *kind = tca[TCA_KIND];
                        char name[IFNAMSIZ];
 
                        if (kind != NULL &&
-                           rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+                           nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
                                rtnl_unlock();
                                request_module("cls_%s", name);
                                rtnl_lock();
@@ -243,7 +254,9 @@ replay:
                tp->q = q;
                tp->classify = tp_ops->classify;
                tp->classid = parent;
-               if ((err = tp_ops->init(tp)) != 0) {
+
+               err = tp_ops->init(tp);
+               if (err != 0) {
                        module_put(tp_ops->owner);
                        kfree(tp);
                        goto errout;
@@ -254,7 +267,7 @@ replay:
                *back = tp;
                qdisc_unlock_tree(dev);
 
-       } else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
+       } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
                goto errout;
 
        fh = tp->ops->get(tp, t->tcm_handle);
@@ -272,13 +285,14 @@ replay:
                }
 
                err = -ENOENT;
-               if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
+               if (n->nlmsg_type != RTM_NEWTFILTER ||
+                   !(n->nlmsg_flags & NLM_F_CREATE))
                        goto errout;
        } else {
                switch (n->nlmsg_type) {
                case RTM_NEWTFILTER:
                        err = -EEXIST;
-                       if (n->nlmsg_flags&NLM_F_EXCL)
+                       if (n->nlmsg_flags & NLM_F_EXCL)
                                goto errout;
                        break;
                case RTM_DELTFILTER:
@@ -308,9 +322,8 @@ errout:
        return err;
 }
 
-static int
-tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
-             u32 pid, u32 seq, u16 flags, int event)
+static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
+                        unsigned long fh, u32 pid, u32 seq, u16 flags, int event)
 {
        struct tcmsg *tcm;
        struct nlmsghdr  *nlh;
@@ -324,18 +337,18 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
        tcm->tcm_ifindex = tp->q->dev->ifindex;
        tcm->tcm_parent = tp->classid;
        tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
-       RTA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind);
+       NLA_PUT_STRING(skb, TCA_KIND, tp->ops->kind);
        tcm->tcm_handle = fh;
        if (RTM_DELTFILTER != event) {
                tcm->tcm_handle = 0;
                if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0)
-                       goto rtattr_failure;
+                       goto nla_put_failure;
        }
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
 nlmsg_failure:
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -355,19 +368,20 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
                return -EINVAL;
        }
 
-       return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+       return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC,
+                             n->nlmsg_flags & NLM_F_ECHO);
 }
 
-struct tcf_dump_args
-{
+struct tcf_dump_args {
        struct tcf_walker w;
        struct sk_buff *skb;
        struct netlink_callback *cb;
 };
 
-static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, struct tcf_walker *arg)
+static int tcf_node_dump(struct tcf_proto *tp, unsigned long n,
+                        struct tcf_walker *arg)
 {
-       struct tcf_dump_args *a = (void*)arg;
+       struct tcf_dump_args *a = (void *)arg;
 
        return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).pid,
                             a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER);
@@ -375,16 +389,20 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, struct tcf_walke
 
 static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int t;
        int s_t;
        struct net_device *dev;
        struct Qdisc *q;
        struct tcf_proto *tp, **chain;
-       struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
+       struct tcmsg *tcm = (struct tcmsg *)NLMSG_DATA(cb->nlh);
        unsigned long cl = 0;
-       struct Qdisc_class_ops *cops;
+       const struct Qdisc_class_ops *cops;
        struct tcf_dump_args arg;
 
+       if (net != &init_net)
+               return 0;
+
        if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
                return skb->len;
        if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
@@ -421,9 +439,10 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
                        memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
                if (cb->args[1] == 0) {
                        if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).pid,
-                                         cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER) <= 0) {
+                                         cb->nlh->nlmsg_seq, NLM_F_MULTI,
+                                         RTM_NEWTFILTER) <= 0)
                                break;
-                       }
+
                        cb->args[1] = 1;
                }
                if (tp->ops->walk == NULL)
@@ -450,8 +469,7 @@ out:
        return skb->len;
 }
 
-void
-tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
+void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (exts->action) {
@@ -460,49 +478,48 @@ tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
        }
 #endif
 }
+EXPORT_SYMBOL(tcf_exts_destroy);
 
-
-int
-tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb,
-                 struct rtattr *rate_tlv, struct tcf_exts *exts,
+int tcf_exts_validate(struct tcf_proto *tp, struct nlattr **tb,
+                 struct nlattr *rate_tlv, struct tcf_exts *exts,
                  struct tcf_ext_map *map)
 {
        memset(exts, 0, sizeof(*exts));
 
 #ifdef CONFIG_NET_CLS_ACT
        {
-               int err;
                struct tc_action *act;
 
-               if (map->police && tb[map->police-1]) {
-                       act = tcf_action_init_1(tb[map->police-1], rate_tlv, "police",
-                               TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
-                       if (act == NULL)
-                               return err;
+               if (map->police && tb[map->police]) {
+                       act = tcf_action_init_1(tb[map->police], rate_tlv,
+                                               "police", TCA_ACT_NOREPLACE,
+                                               TCA_ACT_BIND);
+                       if (IS_ERR(act))
+                               return PTR_ERR(act);
 
                        act->type = TCA_OLD_COMPAT;
                        exts->action = act;
-               } else if (map->action && tb[map->action-1]) {
-                       act = tcf_action_init(tb[map->action-1], rate_tlv, NULL,
-                               TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err);
-                       if (act == NULL)
-                               return err;
+               } else if (map->action && tb[map->action]) {
+                       act = tcf_action_init(tb[map->action], rate_tlv, NULL,
+                                             TCA_ACT_NOREPLACE, TCA_ACT_BIND);
+                       if (IS_ERR(act))
+                               return PTR_ERR(act);
 
                        exts->action = act;
                }
        }
 #else
-       if ((map->action && tb[map->action-1]) ||
-           (map->police && tb[map->police-1]))
+       if ((map->action && tb[map->action]) ||
+           (map->police && tb[map->police]))
                return -EOPNOTSUPP;
 #endif
 
        return 0;
 }
+EXPORT_SYMBOL(tcf_exts_validate);
 
-void
-tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
-               struct tcf_exts *src)
+void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
+                    struct tcf_exts *src)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (src->action) {
@@ -515,9 +532,9 @@ tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
        }
 #endif
 }
+EXPORT_SYMBOL(tcf_exts_change);
 
-int
-tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
+int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
              struct tcf_ext_map *map)
 {
 #ifdef CONFIG_NET_CLS_ACT
@@ -527,39 +544,45 @@ tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts,
                 * to work with both old and new modes of entering
                 * tc data even if iproute2  was newer - jhs
                 */
-               struct rtattr *p_rta = (struct rtattr *)skb_tail_pointer(skb);
+               struct nlattr *nest;
 
                if (exts->action->type != TCA_OLD_COMPAT) {
-                       RTA_PUT(skb, map->action, 0, NULL);
+                       nest = nla_nest_start(skb, map->action);
+                       if (nest == NULL)
+                               goto nla_put_failure;
                        if (tcf_action_dump(skb, exts->action, 0, 0) < 0)
-                               goto rtattr_failure;
-                       p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
+                               goto nla_put_failure;
+                       nla_nest_end(skb, nest);
                } else if (map->police) {
-                       RTA_PUT(skb, map->police, 0, NULL);
+                       nest = nla_nest_start(skb, map->police);
+                       if (nest == NULL)
+                               goto nla_put_failure;
                        if (tcf_action_dump_old(skb, exts->action, 0, 0) < 0)
-                               goto rtattr_failure;
-                       p_rta->rta_len = skb_tail_pointer(skb) - (u8 *)p_rta;
+                               goto nla_put_failure;
+                       nla_nest_end(skb, nest);
                }
        }
 #endif
        return 0;
-rtattr_failure: __attribute__ ((unused))
+nla_put_failure: __attribute__ ((unused))
        return -1;
 }
+EXPORT_SYMBOL(tcf_exts_dump);
 
-int
-tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
-                   struct tcf_ext_map *map)
+
+int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts,
+                       struct tcf_ext_map *map)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (exts->action)
                if (tcf_action_copy_stats(skb, exts->action, 1) < 0)
-                       goto rtattr_failure;
+                       goto nla_put_failure;
 #endif
        return 0;
-rtattr_failure: __attribute__ ((unused))
+nla_put_failure: __attribute__ ((unused))
        return -1;
 }
+EXPORT_SYMBOL(tcf_exts_dump_stats);
 
 static int __init tc_filter_init(void)
 {
@@ -572,11 +595,3 @@ static int __init tc_filter_init(void)
 }
 
 subsys_initcall(tc_filter_init);
-
-EXPORT_SYMBOL(register_tcf_proto_ops);
-EXPORT_SYMBOL(unregister_tcf_proto_ops);
-EXPORT_SYMBOL(tcf_exts_validate);
-EXPORT_SYMBOL(tcf_exts_destroy);
-EXPORT_SYMBOL(tcf_exts_change);
-EXPORT_SYMBOL(tcf_exts_dump);
-EXPORT_SYMBOL(tcf_exts_dump_stats);
index 8dbcf2771a4611e921fdb37d75f05a2ccea63f4b..bfb4342ea88cfe982e6ac1b77a36c891f9cda575 100644 (file)
@@ -129,28 +129,29 @@ static int basic_delete(struct tcf_proto *tp, unsigned long arg)
        return -ENOENT;
 }
 
+static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = {
+       [TCA_BASIC_CLASSID]     = { .type = NLA_U32 },
+       [TCA_BASIC_EMATCHES]    = { .type = NLA_NESTED },
+};
+
 static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f,
-                                 unsigned long base, struct rtattr **tb,
-                                 struct rtattr *est)
+                                 unsigned long base, struct nlattr **tb,
+                                 struct nlattr *est)
 {
        int err = -EINVAL;
        struct tcf_exts e;
        struct tcf_ematch_tree t;
 
-       if (tb[TCA_BASIC_CLASSID-1])
-               if (RTA_PAYLOAD(tb[TCA_BASIC_CLASSID-1]) < sizeof(u32))
-                       return err;
-
        err = tcf_exts_validate(tp, tb, est, &e, &basic_ext_map);
        if (err < 0)
                return err;
 
-       err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES-1], &t);
+       err = tcf_em_tree_validate(tp, tb[TCA_BASIC_EMATCHES], &t);
        if (err < 0)
                goto errout;
 
-       if (tb[TCA_BASIC_CLASSID-1]) {
-               f->res.classid = *(u32*)RTA_DATA(tb[TCA_BASIC_CLASSID-1]);
+       if (tb[TCA_BASIC_CLASSID]) {
+               f->res.classid = nla_get_u32(tb[TCA_BASIC_CLASSID]);
                tcf_bind_filter(tp, &f->res, base);
        }
 
@@ -164,23 +165,25 @@ errout:
 }
 
 static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
-                       struct rtattr **tca, unsigned long *arg)
+                       struct nlattr **tca, unsigned long *arg)
 {
-       int err = -EINVAL;
+       int err;
        struct basic_head *head = (struct basic_head *) tp->root;
-       struct rtattr *tb[TCA_BASIC_MAX];
+       struct nlattr *tb[TCA_BASIC_MAX + 1];
        struct basic_filter *f = (struct basic_filter *) *arg;
 
-       if (tca[TCA_OPTIONS-1] == NULL)
+       if (tca[TCA_OPTIONS] == NULL)
                return -EINVAL;
 
-       if (rtattr_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS-1]) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS],
+                              basic_policy);
+       if (err < 0)
+               return err;
 
        if (f != NULL) {
                if (handle && f->handle != handle)
                        return -EINVAL;
-               return basic_set_parms(tp, f, base, tb, tca[TCA_RATE-1]);
+               return basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
        }
 
        err = -ENOBUFS;
@@ -206,7 +209,7 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle,
                f->handle = head->hgenerator;
        }
 
-       err = basic_set_parms(tp, f, base, tb, tca[TCA_RATE-1]);
+       err = basic_set_parms(tp, f, base, tb, tca[TCA_RATE]);
        if (err < 0)
                goto errout;
 
@@ -245,33 +248,33 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh,
                      struct sk_buff *skb, struct tcmsg *t)
 {
        struct basic_filter *f = (struct basic_filter *) fh;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
        if (f == NULL)
                return skb->len;
 
        t->tcm_handle = f->handle;
 
-       rta = (struct rtattr *) b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (f->res.classid)
-               RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid);
+               NLA_PUT_U32(skb, TCA_BASIC_CLASSID, f->res.classid);
 
        if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 ||
            tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
-static struct tcf_proto_ops cls_basic_ops = {
+static struct tcf_proto_ops cls_basic_ops __read_mostly = {
        .kind           =       "basic",
        .classify       =       basic_classify,
        .init           =       basic_init,
index 8adbd6a37d1475cbee48622b0cbbc230725be13e..436a6e7c438e2c8484d130ced225bf590e55e267 100644 (file)
@@ -186,39 +186,41 @@ out:
        return -EINVAL;
 }
 
+static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {
+       [TCA_FW_CLASSID]        = { .type = NLA_U32 },
+       [TCA_FW_INDEV]          = { .type = NLA_STRING, .len = IFNAMSIZ },
+       [TCA_FW_MASK]           = { .type = NLA_U32 },
+};
+
 static int
 fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
-       struct rtattr **tb, struct rtattr **tca, unsigned long base)
+       struct nlattr **tb, struct nlattr **tca, unsigned long base)
 {
        struct fw_head *head = (struct fw_head *)tp->root;
        struct tcf_exts e;
        u32 mask;
        int err;
 
-       err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &fw_ext_map);
+       err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &fw_ext_map);
        if (err < 0)
                return err;
 
        err = -EINVAL;
-       if (tb[TCA_FW_CLASSID-1]) {
-               if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32))
-                       goto errout;
-               f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
+       if (tb[TCA_FW_CLASSID]) {
+               f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]);
                tcf_bind_filter(tp, &f->res, base);
        }
 
 #ifdef CONFIG_NET_CLS_IND
-       if (tb[TCA_FW_INDEV-1]) {
-               err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV-1]);
+       if (tb[TCA_FW_INDEV]) {
+               err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV]);
                if (err < 0)
                        goto errout;
        }
 #endif /* CONFIG_NET_CLS_IND */
 
-       if (tb[TCA_FW_MASK-1]) {
-               if (RTA_PAYLOAD(tb[TCA_FW_MASK-1]) != sizeof(u32))
-                       goto errout;
-               mask = *(u32*)RTA_DATA(tb[TCA_FW_MASK-1]);
+       if (tb[TCA_FW_MASK]) {
+               mask = nla_get_u32(tb[TCA_FW_MASK]);
                if (mask != head->mask)
                        goto errout;
        } else if (head->mask != 0xFFFFFFFF)
@@ -234,20 +236,21 @@ errout:
 
 static int fw_change(struct tcf_proto *tp, unsigned long base,
                     u32 handle,
-                    struct rtattr **tca,
+                    struct nlattr **tca,
                     unsigned long *arg)
 {
        struct fw_head *head = (struct fw_head*)tp->root;
        struct fw_filter *f = (struct fw_filter *) *arg;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_FW_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_FW_MAX + 1];
        int err;
 
        if (!opt)
                return handle ? -EINVAL : 0;
 
-       if (rtattr_parse_nested(tb, TCA_FW_MAX, opt) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_FW_MAX, opt, fw_policy);
+       if (err < 0)
+               return err;
 
        if (f != NULL) {
                if (f->id != handle && handle)
@@ -260,11 +263,8 @@ static int fw_change(struct tcf_proto *tp, unsigned long base,
 
        if (head == NULL) {
                u32 mask = 0xFFFFFFFF;
-               if (tb[TCA_FW_MASK-1]) {
-                       if (RTA_PAYLOAD(tb[TCA_FW_MASK-1]) != sizeof(u32))
-                               return -EINVAL;
-                       mask = *(u32*)RTA_DATA(tb[TCA_FW_MASK-1]);
-               }
+               if (tb[TCA_FW_MASK])
+                       mask = nla_get_u32(tb[TCA_FW_MASK]);
 
                head = kzalloc(sizeof(struct fw_head), GFP_KERNEL);
                if (head == NULL)
@@ -333,7 +333,7 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
        struct fw_head *head = (struct fw_head *)tp->root;
        struct fw_filter *f = (struct fw_filter*)fh;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
        if (f == NULL)
                return skb->len;
@@ -343,35 +343,35 @@ static int fw_dump(struct tcf_proto *tp, unsigned long fh,
        if (!f->res.classid && !tcf_exts_is_available(&f->exts))
                return skb->len;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (f->res.classid)
-               RTA_PUT(skb, TCA_FW_CLASSID, 4, &f->res.classid);
+               NLA_PUT_U32(skb, TCA_FW_CLASSID, f->res.classid);
 #ifdef CONFIG_NET_CLS_IND
        if (strlen(f->indev))
-               RTA_PUT(skb, TCA_FW_INDEV, IFNAMSIZ, f->indev);
+               NLA_PUT_STRING(skb, TCA_FW_INDEV, f->indev);
 #endif /* CONFIG_NET_CLS_IND */
        if (head->mask != 0xFFFFFFFF)
-               RTA_PUT(skb, TCA_FW_MASK, 4, &head->mask);
+               NLA_PUT_U32(skb, TCA_FW_MASK, head->mask);
 
        if (tcf_exts_dump(skb, &f->exts, &fw_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
 
        if (tcf_exts_dump_stats(skb, &f->exts, &fw_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
 
-static struct tcf_proto_ops cls_fw_ops = {
-       .next           =       NULL,
+static struct tcf_proto_ops cls_fw_ops __read_mostly = {
        .kind           =       "fw",
        .classify       =       fw_classify,
        .init           =       fw_init,
index 0a8409c1d28ae4d3c4cdeeb346625a8ef01beee1..f7e7d3955d289f5cd5585bc06bbc9285e56a9834 100644 (file)
@@ -323,9 +323,16 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg)
        return 0;
 }
 
+static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
+       [TCA_ROUTE4_CLASSID]    = { .type = NLA_U32 },
+       [TCA_ROUTE4_TO]         = { .type = NLA_U32 },
+       [TCA_ROUTE4_FROM]       = { .type = NLA_U32 },
+       [TCA_ROUTE4_IIF]        = { .type = NLA_U32 },
+};
+
 static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
        struct route4_filter *f, u32 handle, struct route4_head *head,
-       struct rtattr **tb, struct rtattr *est, int new)
+       struct nlattr **tb, struct nlattr *est, int new)
 {
        int err;
        u32 id = 0, to = 0, nhandle = 0x8000;
@@ -339,34 +346,24 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
                return err;
 
        err = -EINVAL;
-       if (tb[TCA_ROUTE4_CLASSID-1])
-               if (RTA_PAYLOAD(tb[TCA_ROUTE4_CLASSID-1]) < sizeof(u32))
-                       goto errout;
-
-       if (tb[TCA_ROUTE4_TO-1]) {
+       if (tb[TCA_ROUTE4_TO]) {
                if (new && handle & 0x8000)
                        goto errout;
-               if (RTA_PAYLOAD(tb[TCA_ROUTE4_TO-1]) < sizeof(u32))
-                       goto errout;
-               to = *(u32*)RTA_DATA(tb[TCA_ROUTE4_TO-1]);
+               to = nla_get_u32(tb[TCA_ROUTE4_TO]);
                if (to > 0xFF)
                        goto errout;
                nhandle = to;
        }
 
-       if (tb[TCA_ROUTE4_FROM-1]) {
-               if (tb[TCA_ROUTE4_IIF-1])
+       if (tb[TCA_ROUTE4_FROM]) {
+               if (tb[TCA_ROUTE4_IIF])
                        goto errout;
-               if (RTA_PAYLOAD(tb[TCA_ROUTE4_FROM-1]) < sizeof(u32))
-                       goto errout;
-               id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_FROM-1]);
+               id = nla_get_u32(tb[TCA_ROUTE4_FROM]);
                if (id > 0xFF)
                        goto errout;
                nhandle |= id << 16;
-       } else if (tb[TCA_ROUTE4_IIF-1]) {
-               if (RTA_PAYLOAD(tb[TCA_ROUTE4_IIF-1]) < sizeof(u32))
-                       goto errout;
-               id = *(u32*)RTA_DATA(tb[TCA_ROUTE4_IIF-1]);
+       } else if (tb[TCA_ROUTE4_IIF]) {
+               id = nla_get_u32(tb[TCA_ROUTE4_IIF]);
                if (id > 0x7FFF)
                        goto errout;
                nhandle |= (id | 0x8000) << 16;
@@ -398,20 +395,20 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base,
        }
 
        tcf_tree_lock(tp);
-       if (tb[TCA_ROUTE4_TO-1])
+       if (tb[TCA_ROUTE4_TO])
                f->id = to;
 
-       if (tb[TCA_ROUTE4_FROM-1])
+       if (tb[TCA_ROUTE4_FROM])
                f->id = to | id<<16;
-       else if (tb[TCA_ROUTE4_IIF-1])
+       else if (tb[TCA_ROUTE4_IIF])
                f->iif = id;
 
        f->handle = nhandle;
        f->bkt = b;
        tcf_tree_unlock(tp);
 
-       if (tb[TCA_ROUTE4_CLASSID-1]) {
-               f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
+       if (tb[TCA_ROUTE4_CLASSID]) {
+               f->res.classid = nla_get_u32(tb[TCA_ROUTE4_CLASSID]);
                tcf_bind_filter(tp, &f->res, base);
        }
 
@@ -425,14 +422,14 @@ errout:
 
 static int route4_change(struct tcf_proto *tp, unsigned long base,
                       u32 handle,
-                      struct rtattr **tca,
+                      struct nlattr **tca,
                       unsigned long *arg)
 {
        struct route4_head *head = tp->root;
        struct route4_filter *f, *f1, **fp;
        struct route4_bucket *b;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_ROUTE4_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_ROUTE4_MAX + 1];
        unsigned int h, th;
        u32 old_handle = 0;
        int err;
@@ -440,8 +437,9 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
        if (opt == NULL)
                return handle ? -EINVAL : 0;
 
-       if (rtattr_parse_nested(tb, TCA_ROUTE4_MAX, opt) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, route4_policy);
+       if (err < 0)
+               return err;
 
        if ((f = (struct route4_filter*)*arg) != NULL) {
                if (f->handle != handle && handle)
@@ -451,7 +449,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
                        old_handle = f->handle;
 
                err = route4_set_parms(tp, base, f, handle, head, tb,
-                       tca[TCA_RATE-1], 0);
+                       tca[TCA_RATE], 0);
                if (err < 0)
                        return err;
 
@@ -474,7 +472,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base,
                goto errout;
 
        err = route4_set_parms(tp, base, f, handle, head, tb,
-               tca[TCA_RATE-1], 1);
+               tca[TCA_RATE], 1);
        if (err < 0)
                goto errout;
 
@@ -550,7 +548,7 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 {
        struct route4_filter *f = (struct route4_filter*)fh;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
        u32 id;
 
        if (f == NULL)
@@ -558,40 +556,40 @@ static int route4_dump(struct tcf_proto *tp, unsigned long fh,
 
        t->tcm_handle = f->handle;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (!(f->handle&0x8000)) {
                id = f->id&0xFF;
-               RTA_PUT(skb, TCA_ROUTE4_TO, sizeof(id), &id);
+               NLA_PUT_U32(skb, TCA_ROUTE4_TO, id);
        }
        if (f->handle&0x80000000) {
                if ((f->handle>>16) != 0xFFFF)
-                       RTA_PUT(skb, TCA_ROUTE4_IIF, sizeof(f->iif), &f->iif);
+                       NLA_PUT_U32(skb, TCA_ROUTE4_IIF, f->iif);
        } else {
                id = f->id>>16;
-               RTA_PUT(skb, TCA_ROUTE4_FROM, sizeof(id), &id);
+               NLA_PUT_U32(skb, TCA_ROUTE4_FROM, id);
        }
        if (f->res.classid)
-               RTA_PUT(skb, TCA_ROUTE4_CLASSID, 4, &f->res.classid);
+               NLA_PUT_U32(skb, TCA_ROUTE4_CLASSID, f->res.classid);
 
        if (tcf_exts_dump(skb, &f->exts, &route_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
 
        if (tcf_exts_dump_stats(skb, &f->exts, &route_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
 
-static struct tcf_proto_ops cls_route4_ops = {
-       .next           =       NULL,
+static struct tcf_proto_ops cls_route4_ops __read_mostly = {
        .kind           =       "route",
        .classify       =       route4_classify,
        .init           =       route4_init,
index 22f9ede70e8fb47dbf02b8900c1f1a146c5caa60..7034ea4530e578c0e59da24ece7dc1790125d4cb 100644 (file)
@@ -397,17 +397,26 @@ static u32 gen_tunnel(struct rsvp_head *data)
        return 0;
 }
 
+static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
+       [TCA_RSVP_CLASSID]      = { .type = NLA_U32 },
+       [TCA_RSVP_DST]          = { .type = NLA_BINARY,
+                                   .len = RSVP_DST_LEN * sizeof(u32) },
+       [TCA_RSVP_SRC]          = { .type = NLA_BINARY,
+                                   .len = RSVP_DST_LEN * sizeof(u32) },
+       [TCA_RSVP_PINFO]        = { .len = sizeof(struct tc_rsvp_pinfo) },
+};
+
 static int rsvp_change(struct tcf_proto *tp, unsigned long base,
                       u32 handle,
-                      struct rtattr **tca,
+                      struct nlattr **tca,
                       unsigned long *arg)
 {
        struct rsvp_head *data = tp->root;
        struct rsvp_filter *f, **fp;
        struct rsvp_session *s, **sp;
        struct tc_rsvp_pinfo *pinfo = NULL;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_RSVP_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS-1];
+       struct nlattr *tb[TCA_RSVP_MAX + 1];
        struct tcf_exts e;
        unsigned h1, h2;
        __be32 *dst;
@@ -416,8 +425,9 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
        if (opt == NULL)
                return handle ? -EINVAL : 0;
 
-       if (rtattr_parse_nested(tb, TCA_RSVP_MAX, opt) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, rsvp_policy);
+       if (err < 0)
+               return err;
 
        err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &rsvp_ext_map);
        if (err < 0)
@@ -429,7 +439,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
                if (f->handle != handle && handle)
                        goto errout2;
                if (tb[TCA_RSVP_CLASSID-1]) {
-                       f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
+                       f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]);
                        tcf_bind_filter(tp, &f->res, base);
                }
 
@@ -451,31 +461,18 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
 
        h2 = 16;
        if (tb[TCA_RSVP_SRC-1]) {
-               err = -EINVAL;
-               if (RTA_PAYLOAD(tb[TCA_RSVP_SRC-1]) != sizeof(f->src))
-                       goto errout;
-               memcpy(f->src, RTA_DATA(tb[TCA_RSVP_SRC-1]), sizeof(f->src));
+               memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src));
                h2 = hash_src(f->src);
        }
        if (tb[TCA_RSVP_PINFO-1]) {
-               err = -EINVAL;
-               if (RTA_PAYLOAD(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo))
-                       goto errout;
-               pinfo = RTA_DATA(tb[TCA_RSVP_PINFO-1]);
+               pinfo = nla_data(tb[TCA_RSVP_PINFO-1]);
                f->spi = pinfo->spi;
                f->tunnelhdr = pinfo->tunnelhdr;
        }
-       if (tb[TCA_RSVP_CLASSID-1]) {
-               err = -EINVAL;
-               if (RTA_PAYLOAD(tb[TCA_RSVP_CLASSID-1]) != 4)
-                       goto errout;
-               f->res.classid = *(u32*)RTA_DATA(tb[TCA_RSVP_CLASSID-1]);
-       }
+       if (tb[TCA_RSVP_CLASSID-1])
+               f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]);
 
-       err = -EINVAL;
-       if (RTA_PAYLOAD(tb[TCA_RSVP_DST-1]) != sizeof(f->src))
-               goto errout;
-       dst = RTA_DATA(tb[TCA_RSVP_DST-1]);
+       dst = nla_data(tb[TCA_RSVP_DST-1]);
        h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0);
 
        err = -ENOMEM;
@@ -594,7 +591,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
        struct rsvp_filter *f = (struct rsvp_filter*)fh;
        struct rsvp_session *s;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
        struct tc_rsvp_pinfo pinfo;
 
        if (f == NULL)
@@ -603,33 +600,33 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh,
 
        t->tcm_handle = f->handle;
 
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
-
-       RTA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst);
+       NLA_PUT(skb, TCA_RSVP_DST, sizeof(s->dst), &s->dst);
        pinfo.dpi = s->dpi;
        pinfo.spi = f->spi;
        pinfo.protocol = s->protocol;
        pinfo.tunnelid = s->tunnelid;
        pinfo.tunnelhdr = f->tunnelhdr;
        pinfo.pad = 0;
-       RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
+       NLA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo);
        if (f->res.classid)
-               RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid);
+               NLA_PUT_U32(skb, TCA_RSVP_CLASSID, f->res.classid);
        if (((f->handle>>8)&0xFF) != 16)
-               RTA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
+               NLA_PUT(skb, TCA_RSVP_SRC, sizeof(f->src), f->src);
 
        if (tcf_exts_dump(skb, &f->exts, &rsvp_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
 
        if (tcf_exts_dump_stats(skb, &f->exts, &rsvp_ext_map) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
index 2314820a080a3d7e94b4e523c1dc242ce1c493b7..ee60b2d1705de6b90a9c1f4dbe29436535a10f47 100644 (file)
 #define DEFAULT_HASH_SIZE      64      /* optimized for diffserv */
 
 
-#if 1 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
-
 #define        PRIV(tp)        ((struct tcindex_data *) (tp)->root)
 
 
@@ -104,7 +91,8 @@ static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
        struct tcindex_filter_result *f;
        int key = (skb->tc_index & p->mask) >> p->shift;
 
-       D2PRINTK("tcindex_classify(skb %p,tp %p,res %p),p %p\n",skb,tp,res,p);
+       pr_debug("tcindex_classify(skb %p,tp %p,res %p),p %p\n",
+                skb, tp, res, p);
 
        f = tcindex_lookup(p, key);
        if (!f) {
@@ -112,11 +100,11 @@ static int tcindex_classify(struct sk_buff *skb, struct tcf_proto *tp,
                        return -1;
                res->classid = TC_H_MAKE(TC_H_MAJ(tp->q->handle), key);
                res->class = 0;
-               D2PRINTK("alg 0x%x\n",res->classid);
+               pr_debug("alg 0x%x\n", res->classid);
                return 0;
        }
        *res = f->res;
-       D2PRINTK("map 0x%x\n",res->classid);
+       pr_debug("map 0x%x\n", res->classid);
 
        return tcf_exts_exec(skb, &f->exts, res);
 }
@@ -127,7 +115,7 @@ static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle)
        struct tcindex_data *p = PRIV(tp);
        struct tcindex_filter_result *r;
 
-       DPRINTK("tcindex_get(tp %p,handle 0x%08x)\n",tp,handle);
+       pr_debug("tcindex_get(tp %p,handle 0x%08x)\n", tp, handle);
        if (p->perfect && handle >= p->alloc_hash)
                return 0;
        r = tcindex_lookup(p, handle);
@@ -137,7 +125,7 @@ static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle)
 
 static void tcindex_put(struct tcf_proto *tp, unsigned long f)
 {
-       DPRINTK("tcindex_put(tp %p,f 0x%lx)\n",tp,f);
+       pr_debug("tcindex_put(tp %p,f 0x%lx)\n", tp, f);
 }
 
 
@@ -145,8 +133,8 @@ static int tcindex_init(struct tcf_proto *tp)
 {
        struct tcindex_data *p;
 
-       DPRINTK("tcindex_init(tp %p)\n",tp);
-       p = kzalloc(sizeof(struct tcindex_data),GFP_KERNEL);
+       pr_debug("tcindex_init(tp %p)\n", tp);
+       p = kzalloc(sizeof(struct tcindex_data), GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
@@ -166,7 +154,7 @@ __tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock)
        struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
        struct tcindex_filter *f = NULL;
 
-       DPRINTK("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n",tp,arg,p,f);
+       pr_debug("tcindex_delete(tp %p,arg 0x%lx),p %p,f %p\n", tp, arg, p, f);
        if (p->perfect) {
                if (!r->res.class)
                        return -ENOENT;
@@ -205,10 +193,18 @@ valid_perfect_hash(struct tcindex_data *p)
        return  p->hash > (p->mask >> p->shift);
 }
 
+static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = {
+       [TCA_TCINDEX_HASH]              = { .type = NLA_U32 },
+       [TCA_TCINDEX_MASK]              = { .type = NLA_U16 },
+       [TCA_TCINDEX_SHIFT]             = { .type = NLA_U32 },
+       [TCA_TCINDEX_FALL_THROUGH]      = { .type = NLA_U32 },
+       [TCA_TCINDEX_CLASSID]           = { .type = NLA_U32 },
+};
+
 static int
 tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
                  struct tcindex_data *p, struct tcindex_filter_result *r,
-                 struct rtattr **tb, struct rtattr *est)
+                 struct nlattr **tb, struct nlattr *est)
 {
        int err, balloc = 0;
        struct tcindex_filter_result new_filter_result, *old_r = r;
@@ -229,24 +225,14 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
        else
                memset(&cr, 0, sizeof(cr));
 
-       err = -EINVAL;
-       if (tb[TCA_TCINDEX_HASH-1]) {
-               if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH-1]) < sizeof(u32))
-                       goto errout;
-               cp.hash = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_HASH-1]);
-       }
+       if (tb[TCA_TCINDEX_HASH])
+               cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
 
-       if (tb[TCA_TCINDEX_MASK-1]) {
-               if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK-1]) < sizeof(u16))
-                       goto errout;
-               cp.mask = *(u16 *) RTA_DATA(tb[TCA_TCINDEX_MASK-1]);
-       }
+       if (tb[TCA_TCINDEX_MASK])
+               cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
 
-       if (tb[TCA_TCINDEX_SHIFT-1]) {
-               if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT-1]) < sizeof(int))
-                       goto errout;
-               cp.shift = *(int *) RTA_DATA(tb[TCA_TCINDEX_SHIFT-1]);
-       }
+       if (tb[TCA_TCINDEX_SHIFT])
+               cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
 
        err = -EBUSY;
        /* Hash already allocated, make sure that we still meet the
@@ -260,12 +246,8 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
                goto errout;
 
        err = -EINVAL;
-       if (tb[TCA_TCINDEX_FALL_THROUGH-1]) {
-               if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH-1]) < sizeof(u32))
-                       goto errout;
-               cp.fall_through =
-                       *(u32 *) RTA_DATA(tb[TCA_TCINDEX_FALL_THROUGH-1]);
-       }
+       if (tb[TCA_TCINDEX_FALL_THROUGH])
+               cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
 
        if (!cp.hash) {
                /* Hash not specified, use perfect hash if the upper limit
@@ -316,8 +298,8 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle,
                        goto errout_alloc;
        }
 
-       if (tb[TCA_TCINDEX_CLASSID-1]) {
-               cr.res.classid = *(u32 *) RTA_DATA(tb[TCA_TCINDEX_CLASSID-1]);
+       if (tb[TCA_TCINDEX_CLASSID]) {
+               cr.res.classid = nla_get_u32(tb[TCA_TCINDEX_CLASSID]);
                tcf_bind_filter(tp, &cr.res, base);
        }
 
@@ -356,34 +338,36 @@ errout:
 
 static int
 tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle,
-              struct rtattr **tca, unsigned long *arg)
+              struct nlattr **tca, unsigned long *arg)
 {
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_TCINDEX_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_TCINDEX_MAX + 1];
        struct tcindex_data *p = PRIV(tp);
        struct tcindex_filter_result *r = (struct tcindex_filter_result *) *arg;
+       int err;
 
-       DPRINTK("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
+       pr_debug("tcindex_change(tp %p,handle 0x%08x,tca %p,arg %p),opt %p,"
            "p %p,r %p,*arg 0x%lx\n",
            tp, handle, tca, arg, opt, p, r, arg ? *arg : 0L);
 
        if (!opt)
                return 0;
 
-       if (rtattr_parse_nested(tb, TCA_TCINDEX_MAX, opt) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, tcindex_policy);
+       if (err < 0)
+               return err;
 
-       return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE-1]);
+       return tcindex_set_parms(tp, base, handle, p, r, tb, tca[TCA_RATE]);
 }
 
 
 static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
 {
        struct tcindex_data *p = PRIV(tp);
-       struct tcindex_filter *f,*next;
+       struct tcindex_filter *f, *next;
        int i;
 
-       DPRINTK("tcindex_walk(tp %p,walker %p),p %p\n",tp,walker,p);
+       pr_debug("tcindex_walk(tp %p,walker %p),p %p\n", tp, walker, p);
        if (p->perfect) {
                for (i = 0; i < p->hash; i++) {
                        if (!p->perfect[i].res.class)
@@ -405,7 +389,7 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
                for (f = p->h[i]; f; f = next) {
                        next = f->next;
                        if (walker->count >= walker->skip) {
-                               if (walker->fn(tp,(unsigned long) &f->result,
+                               if (walker->fn(tp, (unsigned long) &f->result,
                                    walker) < 0) {
                                        walker->stop = 1;
                                        return;
@@ -429,11 +413,11 @@ static void tcindex_destroy(struct tcf_proto *tp)
        struct tcindex_data *p = PRIV(tp);
        struct tcf_walker walker;
 
-       DPRINTK("tcindex_destroy(tp %p),p %p\n",tp,p);
+       pr_debug("tcindex_destroy(tp %p),p %p\n", tp, p);
        walker.count = 0;
        walker.skip = 0;
        walker.fn = &tcindex_destroy_element;
-       tcindex_walk(tp,&walker);
+       tcindex_walk(tp, &walker);
        kfree(p->perfect);
        kfree(p->h);
        kfree(p);
@@ -447,21 +431,23 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
        struct tcindex_data *p = PRIV(tp);
        struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh;
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
+
+       pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
+                tp, fh, skb, t, p, r, b);
+       pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h);
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
-       DPRINTK("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n",
-           tp,fh,skb,t,p,r,b);
-       DPRINTK("p->perfect %p p->h %p\n",p->perfect,p->h);
-       rta = (struct rtattr *) b;
-       RTA_PUT(skb,TCA_OPTIONS,0,NULL);
        if (!fh) {
                t->tcm_handle = ~0; /* whatever ... */
-               RTA_PUT(skb,TCA_TCINDEX_HASH,sizeof(p->hash),&p->hash);
-               RTA_PUT(skb,TCA_TCINDEX_MASK,sizeof(p->mask),&p->mask);
-               RTA_PUT(skb,TCA_TCINDEX_SHIFT,sizeof(p->shift),&p->shift);
-               RTA_PUT(skb,TCA_TCINDEX_FALL_THROUGH,sizeof(p->fall_through),
-                   &p->fall_through);
-               rta->rta_len = skb_tail_pointer(skb) - b;
+               NLA_PUT_U32(skb, TCA_TCINDEX_HASH, p->hash);
+               NLA_PUT_U16(skb, TCA_TCINDEX_MASK, p->mask);
+               NLA_PUT_U32(skb, TCA_TCINDEX_SHIFT, p->shift);
+               NLA_PUT_U32(skb, TCA_TCINDEX_FALL_THROUGH, p->fall_through);
+               nla_nest_end(skb, nest);
        } else {
                if (p->perfect) {
                        t->tcm_handle = r-p->perfect;
@@ -478,27 +464,26 @@ static int tcindex_dump(struct tcf_proto *tp, unsigned long fh,
                                }
                        }
                }
-               DPRINTK("handle = %d\n",t->tcm_handle);
+               pr_debug("handle = %d\n", t->tcm_handle);
                if (r->res.class)
-                       RTA_PUT(skb, TCA_TCINDEX_CLASSID, 4, &r->res.classid);
+                       NLA_PUT_U32(skb, TCA_TCINDEX_CLASSID, r->res.classid);
 
                if (tcf_exts_dump(skb, &r->exts, &tcindex_ext_map) < 0)
-                       goto rtattr_failure;
-               rta->rta_len = skb_tail_pointer(skb) - b;
+                       goto nla_put_failure;
+               nla_nest_end(skb, nest);
 
                if (tcf_exts_dump_stats(skb, &r->exts, &tcindex_ext_map) < 0)
-                       goto rtattr_failure;
+                       goto nla_put_failure;
        }
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
 
-static struct tcf_proto_ops cls_tcindex_ops = {
-       .next           =       NULL,
+static struct tcf_proto_ops cls_tcindex_ops __read_mostly = {
        .kind           =       "tcindex",
        .classify       =       tcindex_classify,
        .init           =       tcindex_init,
index c3900820916425f23fbbcc93db63151a9b81305b..e8a7756891234dd2f74e23fbb3cc608ec77241da 100644 (file)
@@ -460,10 +460,20 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle)
        return handle|(i>0xFFF ? 0xFFF : i);
 }
 
+static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
+       [TCA_U32_CLASSID]       = { .type = NLA_U32 },
+       [TCA_U32_HASH]          = { .type = NLA_U32 },
+       [TCA_U32_LINK]          = { .type = NLA_U32 },
+       [TCA_U32_DIVISOR]       = { .type = NLA_U32 },
+       [TCA_U32_SEL]           = { .len = sizeof(struct tc_u32_sel) },
+       [TCA_U32_INDEV]         = { .type = NLA_STRING, .len = IFNAMSIZ },
+       [TCA_U32_MARK]          = { .len = sizeof(struct tc_u32_mark) },
+};
+
 static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
                         struct tc_u_hnode *ht,
-                        struct tc_u_knode *n, struct rtattr **tb,
-                        struct rtattr *est)
+                        struct tc_u_knode *n, struct nlattr **tb,
+                        struct nlattr *est)
 {
        int err;
        struct tcf_exts e;
@@ -473,8 +483,8 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
                return err;
 
        err = -EINVAL;
-       if (tb[TCA_U32_LINK-1]) {
-               u32 handle = *(u32*)RTA_DATA(tb[TCA_U32_LINK-1]);
+       if (tb[TCA_U32_LINK]) {
+               u32 handle = nla_get_u32(tb[TCA_U32_LINK]);
                struct tc_u_hnode *ht_down = NULL;
 
                if (TC_U32_KEY(handle))
@@ -495,14 +505,14 @@ static int u32_set_parms(struct tcf_proto *tp, unsigned long base,
                if (ht_down)
                        ht_down->refcnt--;
        }
-       if (tb[TCA_U32_CLASSID-1]) {
-               n->res.classid = *(u32*)RTA_DATA(tb[TCA_U32_CLASSID-1]);
+       if (tb[TCA_U32_CLASSID]) {
+               n->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
                tcf_bind_filter(tp, &n->res, base);
        }
 
 #ifdef CONFIG_NET_CLS_IND
-       if (tb[TCA_U32_INDEV-1]) {
-               err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV-1]);
+       if (tb[TCA_U32_INDEV]) {
+               err = tcf_change_indev(tp, n->indev, tb[TCA_U32_INDEV]);
                if (err < 0)
                        goto errout;
        }
@@ -516,33 +526,34 @@ errout:
 }
 
 static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
-                     struct rtattr **tca,
+                     struct nlattr **tca,
                      unsigned long *arg)
 {
        struct tc_u_common *tp_c = tp->data;
        struct tc_u_hnode *ht;
        struct tc_u_knode *n;
        struct tc_u32_sel *s;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_U32_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_U32_MAX + 1];
        u32 htid;
        int err;
 
        if (opt == NULL)
                return handle ? -EINVAL : 0;
 
-       if (rtattr_parse_nested(tb, TCA_U32_MAX, opt) < 0)
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_U32_MAX, opt, u32_policy);
+       if (err < 0)
+               return err;
 
        if ((n = (struct tc_u_knode*)*arg) != NULL) {
                if (TC_U32_KEY(n->handle) == 0)
                        return -EINVAL;
 
-               return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE-1]);
+               return u32_set_parms(tp, base, n->ht_up, n, tb, tca[TCA_RATE]);
        }
 
-       if (tb[TCA_U32_DIVISOR-1]) {
-               unsigned divisor = *(unsigned*)RTA_DATA(tb[TCA_U32_DIVISOR-1]);
+       if (tb[TCA_U32_DIVISOR]) {
+               unsigned divisor = nla_get_u32(tb[TCA_U32_DIVISOR]);
 
                if (--divisor > 0x100)
                        return -EINVAL;
@@ -567,8 +578,8 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
                return 0;
        }
 
-       if (tb[TCA_U32_HASH-1]) {
-               htid = *(unsigned*)RTA_DATA(tb[TCA_U32_HASH-1]);
+       if (tb[TCA_U32_HASH]) {
+               htid = nla_get_u32(tb[TCA_U32_HASH]);
                if (TC_U32_HTID(htid) == TC_U32_ROOT) {
                        ht = tp->root;
                        htid = ht->handle;
@@ -592,11 +603,10 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
        } else
                handle = gen_new_kid(ht, htid);
 
-       if (tb[TCA_U32_SEL-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_U32_SEL-1]) < sizeof(struct tc_u32_sel))
+       if (tb[TCA_U32_SEL] == NULL)
                return -EINVAL;
 
-       s = RTA_DATA(tb[TCA_U32_SEL-1]);
+       s = nla_data(tb[TCA_U32_SEL]);
 
        n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL);
        if (n == NULL)
@@ -616,23 +626,16 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
        n->fshift = s->hmask ? ffs(ntohl(s->hmask)) - 1 : 0;
 
 #ifdef CONFIG_CLS_U32_MARK
-       if (tb[TCA_U32_MARK-1]) {
+       if (tb[TCA_U32_MARK]) {
                struct tc_u32_mark *mark;
 
-               if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) {
-#ifdef CONFIG_CLS_U32_PERF
-                       kfree(n->pf);
-#endif
-                       kfree(n);
-                       return -EINVAL;
-               }
-               mark = RTA_DATA(tb[TCA_U32_MARK-1]);
+               mark = nla_data(tb[TCA_U32_MARK]);
                memcpy(&n->mark, mark, sizeof(struct tc_u32_mark));
                n->mark.success = 0;
        }
 #endif
 
-       err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]);
+       err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE]);
        if (err == 0) {
                struct tc_u_knode **ins;
                for (ins = &ht->ht[TC_U32_HASH(handle)]; *ins; ins = &(*ins)->next)
@@ -693,66 +696,66 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
                     struct sk_buff *skb, struct tcmsg *t)
 {
        struct tc_u_knode *n = (struct tc_u_knode*)fh;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
        if (n == NULL)
                return skb->len;
 
        t->tcm_handle = n->handle;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        if (TC_U32_KEY(n->handle) == 0) {
                struct tc_u_hnode *ht = (struct tc_u_hnode*)fh;
                u32 divisor = ht->divisor+1;
-               RTA_PUT(skb, TCA_U32_DIVISOR, 4, &divisor);
+               NLA_PUT_U32(skb, TCA_U32_DIVISOR, divisor);
        } else {
-               RTA_PUT(skb, TCA_U32_SEL,
+               NLA_PUT(skb, TCA_U32_SEL,
                        sizeof(n->sel) + n->sel.nkeys*sizeof(struct tc_u32_key),
                        &n->sel);
                if (n->ht_up) {
                        u32 htid = n->handle & 0xFFFFF000;
-                       RTA_PUT(skb, TCA_U32_HASH, 4, &htid);
+                       NLA_PUT_U32(skb, TCA_U32_HASH, htid);
                }
                if (n->res.classid)
-                       RTA_PUT(skb, TCA_U32_CLASSID, 4, &n->res.classid);
+                       NLA_PUT_U32(skb, TCA_U32_CLASSID, n->res.classid);
                if (n->ht_down)
-                       RTA_PUT(skb, TCA_U32_LINK, 4, &n->ht_down->handle);
+                       NLA_PUT_U32(skb, TCA_U32_LINK, n->ht_down->handle);
 
 #ifdef CONFIG_CLS_U32_MARK
                if (n->mark.val || n->mark.mask)
-                       RTA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
+                       NLA_PUT(skb, TCA_U32_MARK, sizeof(n->mark), &n->mark);
 #endif
 
                if (tcf_exts_dump(skb, &n->exts, &u32_ext_map) < 0)
-                       goto rtattr_failure;
+                       goto nla_put_failure;
 
 #ifdef CONFIG_NET_CLS_IND
                if(strlen(n->indev))
-                       RTA_PUT(skb, TCA_U32_INDEV, IFNAMSIZ, n->indev);
+                       NLA_PUT_STRING(skb, TCA_U32_INDEV, n->indev);
 #endif
 #ifdef CONFIG_CLS_U32_PERF
-               RTA_PUT(skb, TCA_U32_PCNT,
+               NLA_PUT(skb, TCA_U32_PCNT,
                sizeof(struct tc_u32_pcnt) + n->sel.nkeys*sizeof(u64),
                        n->pf);
 #endif
        }
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla_nest_end(skb, nest);
+
        if (TC_U32_KEY(n->handle))
                if (tcf_exts_dump_stats(skb, &n->exts, &u32_ext_map) < 0)
-                       goto rtattr_failure;
+                       goto nla_put_failure;
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
-static struct tcf_proto_ops cls_u32_ops = {
-       .next           =       NULL,
+static struct tcf_proto_ops cls_u32_ops __read_mostly = {
        .kind           =       "u32",
        .classify       =       u32_classify,
        .init           =       u32_init,
index ceda8890ab0edae550482da852ffc72e68603770..a1e5619b1876c8477c85a07936f85806159ea290 100644 (file)
@@ -542,11 +542,11 @@ static int meta_var_compare(struct meta_obj *a, struct meta_obj *b)
        return r;
 }
 
-static int meta_var_change(struct meta_value *dst, struct rtattr *rta)
+static int meta_var_change(struct meta_value *dst, struct nlattr *nla)
 {
-       int len = RTA_PAYLOAD(rta);
+       int len = nla_len(nla);
 
-       dst->val = (unsigned long)kmemdup(RTA_DATA(rta), len, GFP_KERNEL);
+       dst->val = (unsigned long)kmemdup(nla_data(nla), len, GFP_KERNEL);
        if (dst->val == 0UL)
                return -ENOMEM;
        dst->len = len;
@@ -570,10 +570,10 @@ static void meta_var_apply_extras(struct meta_value *v,
 static int meta_var_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
 {
        if (v->val && v->len)
-               RTA_PUT(skb, tlv, v->len, (void *) v->val);
+               NLA_PUT(skb, tlv, v->len, (void *) v->val);
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
@@ -594,13 +594,13 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b)
                return 1;
 }
 
-static int meta_int_change(struct meta_value *dst, struct rtattr *rta)
+static int meta_int_change(struct meta_value *dst, struct nlattr *nla)
 {
-       if (RTA_PAYLOAD(rta) >= sizeof(unsigned long)) {
-               dst->val = *(unsigned long *) RTA_DATA(rta);
+       if (nla_len(nla) >= sizeof(unsigned long)) {
+               dst->val = *(unsigned long *) nla_data(nla);
                dst->len = sizeof(unsigned long);
-       } else if (RTA_PAYLOAD(rta) == sizeof(u32)) {
-               dst->val = *(u32 *) RTA_DATA(rta);
+       } else if (nla_len(nla) == sizeof(u32)) {
+               dst->val = nla_get_u32(nla);
                dst->len = sizeof(u32);
        } else
                return -EINVAL;
@@ -621,15 +621,14 @@ static void meta_int_apply_extras(struct meta_value *v,
 static int meta_int_dump(struct sk_buff *skb, struct meta_value *v, int tlv)
 {
        if (v->len == sizeof(unsigned long))
-               RTA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
+               NLA_PUT(skb, tlv, sizeof(unsigned long), &v->val);
        else if (v->len == sizeof(u32)) {
-               u32 d = v->val;
-               RTA_PUT(skb, tlv, sizeof(d), &d);
+               NLA_PUT_U32(skb, tlv, v->val);
        }
 
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
@@ -641,7 +640,7 @@ struct meta_type_ops
 {
        void    (*destroy)(struct meta_value *);
        int     (*compare)(struct meta_obj *, struct meta_obj *);
-       int     (*change)(struct meta_value *, struct rtattr *);
+       int     (*change)(struct meta_value *, struct nlattr *);
        void    (*apply_extras)(struct meta_value *, struct meta_obj *);
        int     (*dump)(struct sk_buff *, struct meta_value *, int);
 };
@@ -729,13 +728,13 @@ static inline void meta_delete(struct meta_match *meta)
        kfree(meta);
 }
 
-static inline int meta_change_data(struct meta_value *dst, struct rtattr *rta)
+static inline int meta_change_data(struct meta_value *dst, struct nlattr *nla)
 {
-       if (rta) {
-               if (RTA_PAYLOAD(rta) == 0)
+       if (nla) {
+               if (nla_len(nla) == 0)
                        return -EINVAL;
 
-               return meta_type_ops(dst)->change(dst, rta);
+               return meta_type_ops(dst)->change(dst, nla);
        }
 
        return 0;
@@ -746,21 +745,26 @@ static inline int meta_is_supported(struct meta_value *val)
        return (!meta_id(val) || meta_ops(val)->get);
 }
 
+static const struct nla_policy meta_policy[TCA_EM_META_MAX + 1] = {
+       [TCA_EM_META_HDR]       = { .len = sizeof(struct tcf_meta_hdr) },
+};
+
 static int em_meta_change(struct tcf_proto *tp, void *data, int len,
                          struct tcf_ematch *m)
 {
-       int err = -EINVAL;
-       struct rtattr *tb[TCA_EM_META_MAX];
+       int err;
+       struct nlattr *tb[TCA_EM_META_MAX + 1];
        struct tcf_meta_hdr *hdr;
        struct meta_match *meta = NULL;
 
-       if (rtattr_parse(tb, TCA_EM_META_MAX, data, len) < 0)
+       err = nla_parse(tb, TCA_EM_META_MAX, data, len, meta_policy);
+       if (err < 0)
                goto errout;
 
-       if (tb[TCA_EM_META_HDR-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_EM_META_HDR-1]) < sizeof(*hdr))
+       err = -EINVAL;
+       if (tb[TCA_EM_META_HDR] == NULL)
                goto errout;
-       hdr = RTA_DATA(tb[TCA_EM_META_HDR-1]);
+       hdr = nla_data(tb[TCA_EM_META_HDR]);
 
        if (TCF_META_TYPE(hdr->left.kind) != TCF_META_TYPE(hdr->right.kind) ||
            TCF_META_TYPE(hdr->left.kind) > TCF_META_TYPE_MAX ||
@@ -781,8 +785,8 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len,
                goto errout;
        }
 
-       if (meta_change_data(&meta->lvalue, tb[TCA_EM_META_LVALUE-1]) < 0 ||
-           meta_change_data(&meta->rvalue, tb[TCA_EM_META_RVALUE-1]) < 0)
+       if (meta_change_data(&meta->lvalue, tb[TCA_EM_META_LVALUE]) < 0 ||
+           meta_change_data(&meta->rvalue, tb[TCA_EM_META_RVALUE]) < 0)
                goto errout;
 
        m->datalen = sizeof(*meta);
@@ -811,16 +815,16 @@ static int em_meta_dump(struct sk_buff *skb, struct tcf_ematch *em)
        memcpy(&hdr.left, &meta->lvalue.hdr, sizeof(hdr.left));
        memcpy(&hdr.right, &meta->rvalue.hdr, sizeof(hdr.right));
 
-       RTA_PUT(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr);
+       NLA_PUT(skb, TCA_EM_META_HDR, sizeof(hdr), &hdr);
 
        ops = meta_type_ops(&meta->lvalue);
        if (ops->dump(skb, &meta->lvalue, TCA_EM_META_LVALUE) < 0 ||
            ops->dump(skb, &meta->rvalue, TCA_EM_META_RVALUE) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
index d5cd86efb7d08fa8f3564f5edb89aee9557e5840..853c5ead87fd3691c4e699eebb9c6b34bc64f9aa 100644 (file)
@@ -118,11 +118,14 @@ static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m)
        conf.pattern_len = textsearch_get_pattern_len(tm->config);
        conf.pad = 0;
 
-       RTA_PUT_NOHDR(skb, sizeof(conf), &conf);
-       RTA_APPEND(skb, conf.pattern_len, textsearch_get_pattern(tm->config));
+       if (nla_put_nohdr(skb, sizeof(conf), &conf) < 0)
+               goto nla_put_failure;
+       if (nla_append(skb, conf.pattern_len,
+                      textsearch_get_pattern(tm->config)) < 0)
+               goto nla_put_failure;
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
index f3a104e323bddd50c299c74c928a95038f1f5af5..74ff918455a2acc2885f5fce5e9da30db3d527fa 100644 (file)
@@ -141,6 +141,7 @@ errout:
        write_unlock(&ematch_mod_lock);
        return err;
 }
+EXPORT_SYMBOL(tcf_em_register);
 
 /**
  * tcf_em_unregister - unregster and extended match
@@ -171,6 +172,7 @@ out:
        write_unlock(&ematch_mod_lock);
        return err;
 }
+EXPORT_SYMBOL(tcf_em_unregister);
 
 static inline struct tcf_ematch * tcf_em_get_match(struct tcf_ematch_tree *tree,
                                                   int index)
@@ -181,11 +183,11 @@ static inline struct tcf_ematch * tcf_em_get_match(struct tcf_ematch_tree *tree,
 
 static int tcf_em_validate(struct tcf_proto *tp,
                           struct tcf_ematch_tree_hdr *tree_hdr,
-                          struct tcf_ematch *em, struct rtattr *rta, int idx)
+                          struct tcf_ematch *em, struct nlattr *nla, int idx)
 {
        int err = -EINVAL;
-       struct tcf_ematch_hdr *em_hdr = RTA_DATA(rta);
-       int data_len = RTA_PAYLOAD(rta) - sizeof(*em_hdr);
+       struct tcf_ematch_hdr *em_hdr = nla_data(nla);
+       int data_len = nla_len(nla) - sizeof(*em_hdr);
        void *data = (void *) em_hdr + sizeof(*em_hdr);
 
        if (!TCF_EM_REL_VALID(em_hdr->flags))
@@ -280,15 +282,20 @@ errout:
        return err;
 }
 
+static const struct nla_policy em_policy[TCA_EMATCH_TREE_MAX + 1] = {
+       [TCA_EMATCH_TREE_HDR]   = { .len = sizeof(struct tcf_ematch_tree_hdr) },
+       [TCA_EMATCH_TREE_LIST]  = { .type = NLA_NESTED },
+};
+
 /**
  * tcf_em_tree_validate - validate ematch config TLV and build ematch tree
  *
  * @tp: classifier kind handle
- * @rta: ematch tree configuration TLV
+ * @nla: ematch tree configuration TLV
  * @tree: destination ematch tree variable to store the resulting
  *        ematch tree.
  *
- * This function validates the given configuration TLV @rta and builds an
+ * This function validates the given configuration TLV @nla and builds an
  * ematch tree in @tree. The resulting tree must later be copied into
  * the private classifier data using tcf_em_tree_change(). You MUST NOT
  * provide the ematch tree variable of the private classifier data directly,
@@ -296,45 +303,43 @@ errout:
  *
  * Returns a negative error code if the configuration TLV contains errors.
  */
-int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
+int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
                         struct tcf_ematch_tree *tree)
 {
-       int idx, list_len, matches_len, err = -EINVAL;
-       struct rtattr *tb[TCA_EMATCH_TREE_MAX];
-       struct rtattr *rt_match, *rt_hdr, *rt_list;
+       int idx, list_len, matches_len, err;
+       struct nlattr *tb[TCA_EMATCH_TREE_MAX + 1];
+       struct nlattr *rt_match, *rt_hdr, *rt_list;
        struct tcf_ematch_tree_hdr *tree_hdr;
        struct tcf_ematch *em;
 
-       if (!rta) {
+       if (!nla) {
                memset(tree, 0, sizeof(*tree));
                return 0;
        }
 
-       if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
+       err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, em_policy);
+       if (err < 0)
                goto errout;
 
-       rt_hdr = tb[TCA_EMATCH_TREE_HDR-1];
-       rt_list = tb[TCA_EMATCH_TREE_LIST-1];
+       err = -EINVAL;
+       rt_hdr = tb[TCA_EMATCH_TREE_HDR];
+       rt_list = tb[TCA_EMATCH_TREE_LIST];
 
        if (rt_hdr == NULL || rt_list == NULL)
                goto errout;
 
-       if (RTA_PAYLOAD(rt_hdr) < sizeof(*tree_hdr) ||
-           RTA_PAYLOAD(rt_list) < sizeof(*rt_match))
-               goto errout;
-
-       tree_hdr = RTA_DATA(rt_hdr);
+       tree_hdr = nla_data(rt_hdr);
        memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr));
 
-       rt_match = RTA_DATA(rt_list);
-       list_len = RTA_PAYLOAD(rt_list);
+       rt_match = nla_data(rt_list);
+       list_len = nla_len(rt_list);
        matches_len = tree_hdr->nmatches * sizeof(*em);
 
        tree->matches = kzalloc(matches_len, GFP_KERNEL);
        if (tree->matches == NULL)
                goto errout;
 
-       /* We do not use rtattr_parse_nested here because the maximum
+       /* We do not use nla_parse_nested here because the maximum
         * number of attributes is unknown. This saves us the allocation
         * for a tb buffer which would serve no purpose at all.
         *
@@ -342,16 +347,16 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
         * provided, their type must be incremental from 1 to n. Even
         * if it does not serve any real purpose, a failure of sticking
         * to this policy will result in parsing failure. */
-       for (idx = 0; RTA_OK(rt_match, list_len); idx++) {
+       for (idx = 0; nla_ok(rt_match, list_len); idx++) {
                err = -EINVAL;
 
-               if (rt_match->rta_type != (idx + 1))
+               if (rt_match->nla_type != (idx + 1))
                        goto errout_abort;
 
                if (idx >= tree_hdr->nmatches)
                        goto errout_abort;
 
-               if (RTA_PAYLOAD(rt_match) < sizeof(struct tcf_ematch_hdr))
+               if (nla_len(rt_match) < sizeof(struct tcf_ematch_hdr))
                        goto errout_abort;
 
                em = tcf_em_get_match(tree, idx);
@@ -360,7 +365,7 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
                if (err < 0)
                        goto errout_abort;
 
-               rt_match = RTA_NEXT(rt_match, list_len);
+               rt_match = nla_next(rt_match, &list_len);
        }
 
        /* Check if the number of matches provided by userspace actually
@@ -380,6 +385,7 @@ errout_abort:
        tcf_em_tree_destroy(tp, tree);
        return err;
 }
+EXPORT_SYMBOL(tcf_em_tree_validate);
 
 /**
  * tcf_em_tree_destroy - destroy an ematch tree
@@ -413,6 +419,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
        tree->hdr.nmatches = 0;
        kfree(tree->matches);
 }
+EXPORT_SYMBOL(tcf_em_tree_destroy);
 
 /**
  * tcf_em_tree_dump - dump ematch tree into a rtnl message
@@ -430,18 +437,22 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
 {
        int i;
        u8 *tail;
-       struct rtattr *top_start = (struct rtattr *)skb_tail_pointer(skb);
-       struct rtattr *list_start;
+       struct nlattr *top_start;
+       struct nlattr *list_start;
+
+       top_start = nla_nest_start(skb, tlv);
+       if (top_start == NULL)
+               goto nla_put_failure;
 
-       RTA_PUT(skb, tlv, 0, NULL);
-       RTA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
+       NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
 
-       list_start = (struct rtattr *)skb_tail_pointer(skb);
-       RTA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL);
+       list_start = nla_nest_start(skb, TCA_EMATCH_TREE_LIST);
+       if (list_start == NULL)
+               goto nla_put_failure;
 
        tail = skb_tail_pointer(skb);
        for (i = 0; i < tree->hdr.nmatches; i++) {
-               struct rtattr *match_start = (struct rtattr *)tail;
+               struct nlattr *match_start = (struct nlattr *)tail;
                struct tcf_ematch *em = tcf_em_get_match(tree, i);
                struct tcf_ematch_hdr em_hdr = {
                        .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER,
@@ -449,29 +460,30 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
                        .flags = em->flags
                };
 
-               RTA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr);
+               NLA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr);
 
                if (em->ops && em->ops->dump) {
                        if (em->ops->dump(skb, em) < 0)
-                               goto rtattr_failure;
+                               goto nla_put_failure;
                } else if (tcf_em_is_container(em) || tcf_em_is_simple(em)) {
                        u32 u = em->data;
-                       RTA_PUT_NOHDR(skb, sizeof(u), &u);
+                       nla_put_nohdr(skb, sizeof(u), &u);
                } else if (em->datalen > 0)
-                       RTA_PUT_NOHDR(skb, em->datalen, (void *) em->data);
+                       nla_put_nohdr(skb, em->datalen, (void *) em->data);
 
                tail = skb_tail_pointer(skb);
-               match_start->rta_len = tail - (u8 *)match_start;
+               match_start->nla_len = tail - (u8 *)match_start;
        }
 
-       list_start->rta_len = tail - (u8 *)list_start;
-       top_start->rta_len = tail - (u8 *)top_start;
+       nla_nest_end(skb, list_start);
+       nla_nest_end(skb, top_start);
 
        return 0;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
+EXPORT_SYMBOL(tcf_em_tree_dump);
 
 static inline int tcf_em_match(struct sk_buff *skb, struct tcf_ematch *em,
                               struct tcf_pkt_info *info)
@@ -529,10 +541,4 @@ stack_overflow:
                printk("Local stack overflow, increase NET_EMATCH_STACK\n");
        return -1;
 }
-
-EXPORT_SYMBOL(tcf_em_register);
-EXPORT_SYMBOL(tcf_em_unregister);
-EXPORT_SYMBOL(tcf_em_tree_validate);
-EXPORT_SYMBOL(tcf_em_tree_destroy);
-EXPORT_SYMBOL(tcf_em_tree_dump);
 EXPORT_SYMBOL(__tcf_em_tree_match);
index 8ae137e3522b44e0cb8a5e6ccb191f10b47984e8..7e3c048ba9b1f1421d74435608924d77d36b50f4 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/hrtimer.h>
 
 #include <net/net_namespace.h>
+#include <net/sock.h>
 #include <net/netlink.h>
 #include <net/pkt_sched.h>
 
@@ -157,6 +158,7 @@ out:
        write_unlock(&qdisc_mod_lock);
        return rc;
 }
+EXPORT_SYMBOL(register_qdisc);
 
 int unregister_qdisc(struct Qdisc_ops *qops)
 {
@@ -175,6 +177,7 @@ int unregister_qdisc(struct Qdisc_ops *qops)
        write_unlock(&qdisc_mod_lock);
        return err;
 }
+EXPORT_SYMBOL(unregister_qdisc);
 
 /* We know handle. Find qdisc among all qdisc's attached to device
    (root qdisc, all its children, children of children etc.)
@@ -195,7 +198,7 @@ static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
 {
        unsigned long cl;
        struct Qdisc *leaf;
-       struct Qdisc_class_ops *cops = p->ops->cl_ops;
+       const struct Qdisc_class_ops *cops = p->ops->cl_ops;
 
        if (cops == NULL)
                return NULL;
@@ -210,14 +213,14 @@ static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
 
 /* Find queueing discipline by name */
 
-static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind)
+static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind)
 {
        struct Qdisc_ops *q = NULL;
 
        if (kind) {
                read_lock(&qdisc_mod_lock);
                for (q = qdisc_base; q; q = q->next) {
-                       if (rtattr_strcmp(kind, q->id) == 0) {
+                       if (nla_strcmp(kind, q->id) == 0) {
                                if (!try_module_get(q->owner))
                                        q = NULL;
                                break;
@@ -230,7 +233,7 @@ static struct Qdisc_ops *qdisc_lookup_ops(struct rtattr *kind)
 
 static struct qdisc_rate_table *qdisc_rtab_list;
 
-struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab)
+struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *tab)
 {
        struct qdisc_rate_table *rtab;
 
@@ -241,19 +244,21 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *ta
                }
        }
 
-       if (tab == NULL || r->rate == 0 || r->cell_log == 0 || RTA_PAYLOAD(tab) != 1024)
+       if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
+           nla_len(tab) != TC_RTAB_SIZE)
                return NULL;
 
        rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
        if (rtab) {
                rtab->rate = *r;
                rtab->refcnt = 1;
-               memcpy(rtab->data, RTA_DATA(tab), 1024);
+               memcpy(rtab->data, nla_data(tab), 1024);
                rtab->next = qdisc_rtab_list;
                qdisc_rtab_list = rtab;
        }
        return rtab;
 }
+EXPORT_SYMBOL(qdisc_get_rtab);
 
 void qdisc_put_rtab(struct qdisc_rate_table *tab)
 {
@@ -270,6 +275,7 @@ void qdisc_put_rtab(struct qdisc_rate_table *tab)
                }
        }
 }
+EXPORT_SYMBOL(qdisc_put_rtab);
 
 static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
 {
@@ -373,7 +379,7 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
 
 void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
 {
-       struct Qdisc_class_ops *cops;
+       const struct Qdisc_class_ops *cops;
        unsigned long cl;
        u32 parentid;
 
@@ -417,7 +423,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
                        *old = dev_graft_qdisc(dev, new);
                }
        } else {
-               struct Qdisc_class_ops *cops = parent->ops->cl_ops;
+               const struct Qdisc_class_ops *cops = parent->ops->cl_ops;
 
                err = -EINVAL;
 
@@ -440,10 +446,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 
 static struct Qdisc *
 qdisc_create(struct net_device *dev, u32 parent, u32 handle,
-          struct rtattr **tca, int *errp)
+          struct nlattr **tca, int *errp)
 {
        int err;
-       struct rtattr *kind = tca[TCA_KIND-1];
+       struct nlattr *kind = tca[TCA_KIND];
        struct Qdisc *sch;
        struct Qdisc_ops *ops;
 
@@ -451,7 +457,7 @@ qdisc_create(struct net_device *dev, u32 parent, u32 handle,
 #ifdef CONFIG_KMOD
        if (ops == NULL && kind != NULL) {
                char name[IFNAMSIZ];
-               if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
+               if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
                        /* We dropped the RTNL semaphore in order to
                         * perform the module load.  So, even if we
                         * succeeded in loading the module we have to
@@ -504,11 +510,11 @@ qdisc_create(struct net_device *dev, u32 parent, u32 handle,
 
        sch->handle = handle;
 
-       if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
-               if (tca[TCA_RATE-1]) {
+       if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) {
+               if (tca[TCA_RATE]) {
                        err = gen_new_estimator(&sch->bstats, &sch->rate_est,
                                                sch->stats_lock,
-                                               tca[TCA_RATE-1]);
+                                               tca[TCA_RATE]);
                        if (err) {
                                /*
                                 * Any broken qdiscs that would require
@@ -536,20 +542,20 @@ err_out:
        return NULL;
 }
 
-static int qdisc_change(struct Qdisc *sch, struct rtattr **tca)
+static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
 {
-       if (tca[TCA_OPTIONS-1]) {
+       if (tca[TCA_OPTIONS]) {
                int err;
 
                if (sch->ops->change == NULL)
                        return -EINVAL;
-               err = sch->ops->change(sch, tca[TCA_OPTIONS-1]);
+               err = sch->ops->change(sch, tca[TCA_OPTIONS]);
                if (err)
                        return err;
        }
-       if (tca[TCA_RATE-1])
+       if (tca[TCA_RATE])
                gen_replace_estimator(&sch->bstats, &sch->rate_est,
-                       sch->stats_lock, tca[TCA_RATE-1]);
+                       sch->stats_lock, tca[TCA_RATE]);
        return 0;
 }
 
@@ -581,7 +587,7 @@ static int
 check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
 {
        struct Qdisc *leaf;
-       struct Qdisc_class_ops *cops = q->ops->cl_ops;
+       const struct Qdisc_class_ops *cops = q->ops->cl_ops;
        struct check_loop_arg *arg = (struct check_loop_arg *)w;
 
        leaf = cops->leaf(q, cl);
@@ -599,17 +605,25 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
 
 static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct tcmsg *tcm = NLMSG_DATA(n);
-       struct rtattr **tca = arg;
+       struct nlattr *tca[TCA_MAX + 1];
        struct net_device *dev;
        u32 clid = tcm->tcm_parent;
        struct Qdisc *q = NULL;
        struct Qdisc *p = NULL;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
                return -ENODEV;
 
+       err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
+       if (err < 0)
+               return err;
+
        if (clid) {
                if (clid != TC_H_ROOT) {
                        if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) {
@@ -632,7 +646,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                        return -ENOENT;
        }
 
-       if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id))
+       if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
                return -EINVAL;
 
        if (n->nlmsg_type == RTM_DELQDISC) {
@@ -660,23 +674,30 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 
 static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct tcmsg *tcm;
-       struct rtattr **tca;
+       struct nlattr *tca[TCA_MAX + 1];
        struct net_device *dev;
        u32 clid;
        struct Qdisc *q, *p;
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
 replay:
        /* Reinit, just in case something touches this. */
        tcm = NLMSG_DATA(n);
-       tca = arg;
        clid = tcm->tcm_parent;
        q = p = NULL;
 
        if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
                return -ENODEV;
 
+       err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
+       if (err < 0)
+               return err;
+
        if (clid) {
                if (clid != TC_H_ROOT) {
                        if (clid != TC_H_INGRESS) {
@@ -704,7 +725,7 @@ replay:
                                        goto create_n_graft;
                                if (n->nlmsg_flags&NLM_F_EXCL)
                                        return -EEXIST;
-                               if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id))
+                               if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
                                        return -EINVAL;
                                if (q == p ||
                                    (p && check_loop(q, p, 0)))
@@ -737,8 +758,8 @@ replay:
                                if ((n->nlmsg_flags&NLM_F_CREATE) &&
                                    (n->nlmsg_flags&NLM_F_REPLACE) &&
                                    ((n->nlmsg_flags&NLM_F_EXCL) ||
-                                    (tca[TCA_KIND-1] &&
-                                     rtattr_strcmp(tca[TCA_KIND-1], q->ops->id))))
+                                    (tca[TCA_KIND] &&
+                                     nla_strcmp(tca[TCA_KIND], q->ops->id))))
                                        goto create_n_graft;
                        }
                }
@@ -753,7 +774,7 @@ replay:
                return -ENOENT;
        if (n->nlmsg_flags&NLM_F_EXCL)
                return -EEXIST;
-       if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], q->ops->id))
+       if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
                return -EINVAL;
        err = qdisc_change(q, tca);
        if (err == 0)
@@ -814,31 +835,31 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
        tcm->tcm_parent = clid;
        tcm->tcm_handle = q->handle;
        tcm->tcm_info = atomic_read(&q->refcnt);
-       RTA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id);
+       NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
        if (q->ops->dump && q->ops->dump(q, skb) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
        q->qstats.qlen = q->q.qlen;
 
        if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
                        TCA_XSTATS, q->stats_lock, &d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
            gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
            gnet_stats_copy_queue(&d, &q->qstats) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (gnet_stats_finish_copy(&d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
 nlmsg_failure:
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -863,7 +884,7 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
        }
 
        if (skb->len)
-               return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+               return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
 
 err_out:
        kfree_skb(skb);
@@ -872,11 +893,15 @@ err_out:
 
 static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int idx, q_idx;
        int s_idx, s_q_idx;
        struct net_device *dev;
        struct Qdisc *q;
 
+       if (net != &init_net)
+               return 0;
+
        s_idx = cb->args[0];
        s_q_idx = q_idx = cb->args[1];
        read_lock(&dev_base_lock);
@@ -920,11 +945,12 @@ done:
 
 static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct tcmsg *tcm = NLMSG_DATA(n);
-       struct rtattr **tca = arg;
+       struct nlattr *tca[TCA_MAX + 1];
        struct net_device *dev;
        struct Qdisc *q = NULL;
-       struct Qdisc_class_ops *cops;
+       const struct Qdisc_class_ops *cops;
        unsigned long cl = 0;
        unsigned long new_cl;
        u32 pid = tcm->tcm_parent;
@@ -932,9 +958,16 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        u32 qid = TC_H_MAJ(clid);
        int err;
 
+       if (net != &init_net)
+               return -EINVAL;
+
        if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
                return -ENODEV;
 
+       err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
+       if (err < 0)
+               return err;
+
        /*
           parent == TC_H_UNSPEC - unspecified parent.
           parent == TC_H_ROOT   - class is root, which has no parent.
@@ -1039,7 +1072,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
        struct nlmsghdr  *nlh;
        unsigned char *b = skb_tail_pointer(skb);
        struct gnet_dump d;
-       struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
+       const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
 
        nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
        tcm = NLMSG_DATA(nlh);
@@ -1048,25 +1081,25 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
        tcm->tcm_parent = q->handle;
        tcm->tcm_handle = q->handle;
        tcm->tcm_info = 0;
-       RTA_PUT(skb, TCA_KIND, IFNAMSIZ, q->ops->id);
+       NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
        if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
                        TCA_XSTATS, q->stats_lock, &d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if (gnet_stats_finish_copy(&d) < 0)
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        nlh->nlmsg_len = skb_tail_pointer(skb) - b;
        return skb->len;
 
 nlmsg_failure:
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1086,7 +1119,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
                return -EINVAL;
        }
 
-       return rtnetlink_send(skb, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
+       return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
 }
 
 struct qdisc_dump_args
@@ -1106,6 +1139,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk
 
 static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct net *net = skb->sk->sk_net;
        int t;
        int s_t;
        struct net_device *dev;
@@ -1113,6 +1147,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
        struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
        struct qdisc_dump_args arg;
 
+       if (net != &init_net)
+               return 0;
+
        if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
                return 0;
        if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
@@ -1268,8 +1305,3 @@ static int __init pktsched_init(void)
 }
 
 subsys_initcall(pktsched_init);
-
-EXPORT_SYMBOL(qdisc_get_rtab);
-EXPORT_SYMBOL(qdisc_put_rtab);
-EXPORT_SYMBOL(register_qdisc);
-EXPORT_SYMBOL(unregister_qdisc);
index ddc4f2c54379791de9d60bd9829c68dad52c5e54..33527341638427c3bf9e97385a7f7d5ba37f07d8 100644 (file)
 
 extern struct socket *sockfd_lookup(int fd, int *err); /* @@@ fix this */
 
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
 /*
  * The ATM queuing discipline provides a framework for invoking classifiers
  * (aka "filters"), which in turn select classes of this queuing discipline.
@@ -49,7 +37,6 @@ extern struct socket *sockfd_lookup(int fd, int *err);        /* @@@ fix this */
  *  - should lock the flow while there is data in the queue (?)
  */
 
-#define PRIV(sch) qdisc_priv(sch)
 #define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back))
 
 struct atm_flow_data {
@@ -57,7 +44,7 @@ struct atm_flow_data {
        struct tcf_proto        *filter_list;
        struct atm_vcc          *vcc;   /* VCC; NULL if VCC is closed */
        void                    (*old_pop)(struct atm_vcc *vcc,
-                                          struct sk_buff * skb); /* chaining */
+                                          struct sk_buff *skb); /* chaining */
        struct atm_qdisc_data   *parent;        /* parent qdisc */
        struct socket           *sock;          /* for closing */
        u32                     classid;        /* x:y type ID */
@@ -84,17 +71,17 @@ static int find_flow(struct atm_qdisc_data *qdisc, struct atm_flow_data *flow)
 {
        struct atm_flow_data *walk;
 
-       DPRINTK("find_flow(qdisc %p,flow %p)\n", qdisc, flow);
+       pr_debug("find_flow(qdisc %p,flow %p)\n", qdisc, flow);
        for (walk = qdisc->flows; walk; walk = walk->next)
                if (walk == flow)
                        return 1;
-       DPRINTK("find_flow: not found\n");
+       pr_debug("find_flow: not found\n");
        return 0;
 }
 
 static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
        for (flow = p->flows; flow; flow = flow->next)
@@ -106,10 +93,10 @@ static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
 static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
                        struct Qdisc *new, struct Qdisc **old)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)arg;
 
-       DPRINTK("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n",
+       pr_debug("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n",
                sch, p, flow, new, old);
        if (!find_flow(p, flow))
                return -EINVAL;
@@ -125,20 +112,20 @@ static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl)
 {
        struct atm_flow_data *flow = (struct atm_flow_data *)cl;
 
-       DPRINTK("atm_tc_leaf(sch %p,flow %p)\n", sch, flow);
+       pr_debug("atm_tc_leaf(sch %p,flow %p)\n", sch, flow);
        return flow ? flow->q : NULL;
 }
 
 static unsigned long atm_tc_get(struct Qdisc *sch, u32 classid)
 {
-       struct atm_qdisc_data *p __maybe_unused = PRIV(sch);
+       struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
-       DPRINTK("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
+       pr_debug("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
        flow = lookup_flow(sch, classid);
        if (flow)
                flow->ref++;
-       DPRINTK("atm_tc_get: flow %p\n", flow);
+       pr_debug("atm_tc_get: flow %p\n", flow);
        return (unsigned long)flow;
 }
 
@@ -155,14 +142,14 @@ static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
  */
 static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)cl;
        struct atm_flow_data **prev;
 
-       DPRINTK("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+       pr_debug("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
        if (--flow->ref)
                return;
-       DPRINTK("atm_tc_put: destroying\n");
+       pr_debug("atm_tc_put: destroying\n");
        for (prev = &p->flows; *prev; prev = &(*prev)->next)
                if (*prev == flow)
                        break;
@@ -171,11 +158,11 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
                return;
        }
        *prev = flow->next;
-       DPRINTK("atm_tc_put: qdisc %p\n", flow->q);
+       pr_debug("atm_tc_put: qdisc %p\n", flow->q);
        qdisc_destroy(flow->q);
        tcf_destroy_chain(flow->filter_list);
        if (flow->sock) {
-               DPRINTK("atm_tc_put: f_count %d\n",
+               pr_debug("atm_tc_put: f_count %d\n",
                        file_count(flow->sock->file));
                flow->vcc->pop = flow->old_pop;
                sockfd_put(flow->sock);
@@ -194,7 +181,7 @@ static void sch_atm_pop(struct atm_vcc *vcc, struct sk_buff *skb)
 {
        struct atm_qdisc_data *p = VCC2FLOW(vcc)->parent;
 
-       D2PRINTK("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n", vcc, skb, p);
+       pr_debug("sch_atm_pop(vcc %p,skb %p,[qdisc %p])\n", vcc, skb, p);
        VCC2FLOW(vcc)->old_pop(vcc, skb);
        tasklet_schedule(&p->task);
 }
@@ -208,19 +195,24 @@ static const u8 llc_oui_ip[] = {
        0x08, 0x00
 };                             /* Ethertype IP (0800) */
 
+static const struct nla_policy atm_policy[TCA_ATM_MAX + 1] = {
+       [TCA_ATM_FD]            = { .type = NLA_U32 },
+       [TCA_ATM_EXCESS]        = { .type = NLA_U32 },
+};
+
 static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
-                        struct rtattr **tca, unsigned long *arg)
+                        struct nlattr **tca, unsigned long *arg)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)*arg;
        struct atm_flow_data *excess = NULL;
-       struct rtattr *opt = tca[TCA_OPTIONS - 1];
-       struct rtattr *tb[TCA_ATM_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_ATM_MAX + 1];
        struct socket *sock;
        int fd, error, hdr_len;
        void *hdr;
 
-       DPRINTK("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
+       pr_debug("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
                "flow %p,opt %p)\n", sch, p, classid, parent, flow, opt);
        /*
         * The concept of parents doesn't apply for this qdisc.
@@ -236,34 +228,38 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
         */
        if (flow)
                return -EBUSY;
-       if (opt == NULL || rtattr_parse_nested(tb, TCA_ATM_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
-       if (!tb[TCA_ATM_FD - 1] || RTA_PAYLOAD(tb[TCA_ATM_FD - 1]) < sizeof(fd))
+
+       error = nla_parse_nested(tb, TCA_ATM_MAX, opt, atm_policy);
+       if (error < 0)
+               return error;
+
+       if (!tb[TCA_ATM_FD])
                return -EINVAL;
-       fd = *(int *)RTA_DATA(tb[TCA_ATM_FD - 1]);
-       DPRINTK("atm_tc_change: fd %d\n", fd);
-       if (tb[TCA_ATM_HDR - 1]) {
-               hdr_len = RTA_PAYLOAD(tb[TCA_ATM_HDR - 1]);
-               hdr = RTA_DATA(tb[TCA_ATM_HDR - 1]);
+       fd = nla_get_u32(tb[TCA_ATM_FD]);
+       pr_debug("atm_tc_change: fd %d\n", fd);
+       if (tb[TCA_ATM_HDR]) {
+               hdr_len = nla_len(tb[TCA_ATM_HDR]);
+               hdr = nla_data(tb[TCA_ATM_HDR]);
        } else {
                hdr_len = RFC1483LLC_LEN;
                hdr = NULL;     /* default LLC/SNAP for IP */
        }
-       if (!tb[TCA_ATM_EXCESS - 1])
+       if (!tb[TCA_ATM_EXCESS])
                excess = NULL;
        else {
-               if (RTA_PAYLOAD(tb[TCA_ATM_EXCESS - 1]) != sizeof(u32))
-                       return -EINVAL;
                excess = (struct atm_flow_data *)
-                       atm_tc_get(sch, *(u32 *)RTA_DATA(tb[TCA_ATM_EXCESS - 1]));
+                       atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
                if (!excess)
                        return -ENOENT;
        }
-       DPRINTK("atm_tc_change: type %d, payload %d, hdr_len %d\n",
-               opt->rta_type, RTA_PAYLOAD(opt), hdr_len);
-       if (!(sock = sockfd_lookup(fd, &error)))
+       pr_debug("atm_tc_change: type %d, payload %d, hdr_len %d\n",
+                opt->nla_type, nla_len(opt), hdr_len);
+       sock = sockfd_lookup(fd, &error);
+       if (!sock)
                return error;   /* f_count++ */
-       DPRINTK("atm_tc_change: f_count %d\n", file_count(sock->file));
+       pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file));
        if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
                error = -EPROTOTYPE;
                goto err_out;
@@ -272,7 +268,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
           on vcc->send */
        if (classid) {
                if (TC_H_MAJ(classid ^ sch->handle)) {
-                       DPRINTK("atm_tc_change: classid mismatch\n");
+                       pr_debug("atm_tc_change: classid mismatch\n");
                        error = -EINVAL;
                        goto err_out;
                }
@@ -286,26 +282,28 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 
                for (i = 1; i < 0x8000; i++) {
                        classid = TC_H_MAKE(sch->handle, 0x8000 | i);
-                       if (!(cl = atm_tc_get(sch, classid)))
+                       cl = atm_tc_get(sch, classid);
+                       if (!cl)
                                break;
                        atm_tc_put(sch, cl);
                }
        }
-       DPRINTK("atm_tc_change: new id %x\n", classid);
+       pr_debug("atm_tc_change: new id %x\n", classid);
        flow = kzalloc(sizeof(struct atm_flow_data) + hdr_len, GFP_KERNEL);
-       DPRINTK("atm_tc_change: flow %p\n", flow);
+       pr_debug("atm_tc_change: flow %p\n", flow);
        if (!flow) {
                error = -ENOBUFS;
                goto err_out;
        }
        flow->filter_list = NULL;
-       if (!(flow->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
+       flow->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
+       if (!flow->q)
                flow->q = &noop_qdisc;
-       DPRINTK("atm_tc_change: qdisc %p\n", flow->q);
+       pr_debug("atm_tc_change: qdisc %p\n", flow->q);
        flow->sock = sock;
        flow->vcc = ATM_SD(sock);       /* speedup */
        flow->vcc->user_back = flow;
-       DPRINTK("atm_tc_change: vcc %p\n", flow->vcc);
+       pr_debug("atm_tc_change: vcc %p\n", flow->vcc);
        flow->old_pop = flow->vcc->pop;
        flow->parent = p;
        flow->vcc->pop = sch_atm_pop;
@@ -330,11 +328,11 @@ err_out:
 
 static int atm_tc_delete(struct Qdisc *sch, unsigned long arg)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)arg;
 
-       DPRINTK("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
-       if (!find_flow(PRIV(sch), flow))
+       pr_debug("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+       if (!find_flow(qdisc_priv(sch), flow))
                return -EINVAL;
        if (flow->filter_list || flow == &p->link)
                return -EBUSY;
@@ -354,10 +352,10 @@ static int atm_tc_delete(struct Qdisc *sch, unsigned long arg)
 
 static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
-       DPRINTK("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
+       pr_debug("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
        if (walker->stop)
                return;
        for (flow = p->flows; flow; flow = flow->next) {
@@ -372,10 +370,10 @@ static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 
 static struct tcf_proto **atm_tc_find_tcf(struct Qdisc *sch, unsigned long cl)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)cl;
 
-       DPRINTK("atm_tc_find_tcf(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
+       pr_debug("atm_tc_find_tcf(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
        return flow ? &flow->filter_list : &p->link.filter_list;
 }
 
@@ -383,13 +381,13 @@ static struct tcf_proto **atm_tc_find_tcf(struct Qdisc *sch, unsigned long cl)
 
 static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = NULL;      /* @@@ */
        struct tcf_result res;
        int result;
        int ret = NET_XMIT_POLICED;
 
-       D2PRINTK("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+       pr_debug("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
        result = TC_POLICE_OK;  /* be nice to gcc */
        if (TC_H_MAJ(skb->priority) != sch->handle ||
            !(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority)))
@@ -430,7 +428,8 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 #endif
        }
 
-       if ((ret = flow->q->enqueue(skb, flow->q)) != 0) {
+       ret = flow->q->enqueue(skb, flow->q);
+       if (ret != 0) {
 drop: __maybe_unused
                sch->qstats.drops++;
                if (flow)
@@ -468,11 +467,11 @@ drop: __maybe_unused
 static void sch_atm_dequeue(unsigned long data)
 {
        struct Qdisc *sch = (struct Qdisc *)data;
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
        struct sk_buff *skb;
 
-       D2PRINTK("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p);
        for (flow = p->link.next; flow; flow = flow->next)
                /*
                 * If traffic is properly shaped, this won't generate nasty
@@ -483,7 +482,7 @@ static void sch_atm_dequeue(unsigned long data)
                                (void)flow->q->ops->requeue(skb, flow->q);
                                break;
                        }
-                       D2PRINTK("atm_tc_dequeue: sending on class %p\n", flow);
+                       pr_debug("atm_tc_dequeue: sending on class %p\n", flow);
                        /* remove any LL header somebody else has attached */
                        skb_pull(skb, skb_network_offset(skb));
                        if (skb_headroom(skb) < flow->hdr_len) {
@@ -495,7 +494,7 @@ static void sch_atm_dequeue(unsigned long data)
                                        continue;
                                skb = new;
                        }
-                       D2PRINTK("sch_atm_dequeue: ip %p, data %p\n",
+                       pr_debug("sch_atm_dequeue: ip %p, data %p\n",
                                 skb_network_header(skb), skb->data);
                        ATM_SKB(skb)->vcc = flow->vcc;
                        memcpy(skb_push(skb, flow->hdr_len), flow->hdr,
@@ -509,10 +508,10 @@ static void sch_atm_dequeue(unsigned long data)
 
 static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct sk_buff *skb;
 
-       D2PRINTK("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("atm_tc_dequeue(sch %p,[qdisc %p])\n", sch, p);
        tasklet_schedule(&p->task);
        skb = p->link.q->dequeue(p->link.q);
        if (skb)
@@ -522,10 +521,10 @@ static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
 
 static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        int ret;
 
-       D2PRINTK("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+       pr_debug("atm_tc_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
        ret = p->link.q->ops->requeue(skb, p->link.q);
        if (!ret) {
                sch->q.qlen++;
@@ -539,27 +538,27 @@ static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
 
 static unsigned int atm_tc_drop(struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
        unsigned int len;
 
-       DPRINTK("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
        for (flow = p->flows; flow; flow = flow->next)
                if (flow->q->ops->drop && (len = flow->q->ops->drop(flow->q)))
                        return len;
        return 0;
 }
 
-static int atm_tc_init(struct Qdisc *sch, struct rtattr *opt)
+static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
 
-       DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
+       pr_debug("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
        p->flows = &p->link;
-       if (!(p->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
-                                           sch->handle)))
+       p->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle);
+       if (!p->link.q)
                p->link.q = &noop_qdisc;
-       DPRINTK("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
+       pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q);
        p->link.filter_list = NULL;
        p->link.vcc = NULL;
        p->link.sock = NULL;
@@ -572,10 +571,10 @@ static int atm_tc_init(struct Qdisc *sch, struct rtattr *opt)
 
 static void atm_tc_reset(struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
-       DPRINTK("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
        for (flow = p->flows; flow; flow = flow->next)
                qdisc_reset(flow->q);
        sch->q.qlen = 0;
@@ -583,10 +582,10 @@ static void atm_tc_reset(struct Qdisc *sch)
 
 static void atm_tc_destroy(struct Qdisc *sch)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
-       DPRINTK("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
        /* races ? */
        while ((flow = p->flows)) {
                tcf_destroy_chain(flow->filter_list);
@@ -608,20 +607,22 @@ static void atm_tc_destroy(struct Qdisc *sch)
 static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
                             struct sk_buff *skb, struct tcmsg *tcm)
 {
-       struct atm_qdisc_data *p = PRIV(sch);
+       struct atm_qdisc_data *p = qdisc_priv(sch);
        struct atm_flow_data *flow = (struct atm_flow_data *)cl;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
-       DPRINTK("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
+       pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
                sch, p, flow, skb, tcm);
        if (!find_flow(p, flow))
                return -EINVAL;
        tcm->tcm_handle = flow->classid;
        tcm->tcm_info = flow->q->handle;
-       rta = (struct rtattr *)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
-       RTA_PUT(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr);
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
+
+       NLA_PUT(skb, TCA_ATM_HDR, flow->hdr_len, flow->hdr);
        if (flow->vcc) {
                struct sockaddr_atmpvc pvc;
                int state;
@@ -630,22 +631,21 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
                pvc.sap_addr.itf = flow->vcc->dev ? flow->vcc->dev->number : -1;
                pvc.sap_addr.vpi = flow->vcc->vpi;
                pvc.sap_addr.vci = flow->vcc->vci;
-               RTA_PUT(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc);
+               NLA_PUT(skb, TCA_ATM_ADDR, sizeof(pvc), &pvc);
                state = ATM_VF2VS(flow->vcc->flags);
-               RTA_PUT(skb, TCA_ATM_STATE, sizeof(state), &state);
+               NLA_PUT_U32(skb, TCA_ATM_STATE, state);
        }
        if (flow->excess)
-               RTA_PUT(skb, TCA_ATM_EXCESS, sizeof(u32), &flow->classid);
+               NLA_PUT_U32(skb, TCA_ATM_EXCESS, flow->classid);
        else {
-               static u32 zero;
-
-               RTA_PUT(skb, TCA_ATM_EXCESS, sizeof(zero), &zero);
+               NLA_PUT_U32(skb, TCA_ATM_EXCESS, 0);
        }
-       rta->rta_len = skb_tail_pointer(skb) - b;
+
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 static int
@@ -668,7 +668,7 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb)
        return 0;
 }
 
-static struct Qdisc_class_ops atm_class_ops = {
+static const struct Qdisc_class_ops atm_class_ops = {
        .graft          = atm_tc_graft,
        .leaf           = atm_tc_leaf,
        .get            = atm_tc_get,
@@ -683,7 +683,7 @@ static struct Qdisc_class_ops atm_class_ops = {
        .dump_stats     = atm_tc_dump_class_stats,
 };
 
-static struct Qdisc_ops atm_qdisc_ops = {
+static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
        .cl_ops         = &atm_class_ops,
        .id             = "atm",
        .priv_size      = sizeof(struct atm_qdisc_data),
index f914fc43a12478b9db41d037647b7ffe714fd5ee..507fb488bc985a18d13e0d79d95720b704118153 100644 (file)
@@ -28,7 +28,7 @@ static struct sk_buff *blackhole_dequeue(struct Qdisc *sch)
        return NULL;
 }
 
-static struct Qdisc_ops blackhole_qdisc_ops = {
+static struct Qdisc_ops blackhole_qdisc_ops __read_mostly = {
        .id             = "blackhole",
        .priv_size      = 0,
        .enqueue        = blackhole_enqueue,
index 4de3744e65c35cdf688b1c134749535f42ca6e07..09969c1fbc08f287cb8b6bbc749e8a360fb9ea26 100644 (file)
@@ -1377,24 +1377,33 @@ static int cbq_set_fopt(struct cbq_class *cl, struct tc_cbq_fopt *fopt)
        return 0;
 }
 
-static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
+static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
+       [TCA_CBQ_LSSOPT]        = { .len = sizeof(struct tc_cbq_lssopt) },
+       [TCA_CBQ_WRROPT]        = { .len = sizeof(struct tc_cbq_wrropt) },
+       [TCA_CBQ_FOPT]          = { .len = sizeof(struct tc_cbq_fopt) },
+       [TCA_CBQ_OVL_STRATEGY]  = { .len = sizeof(struct tc_cbq_ovl) },
+       [TCA_CBQ_RATE]          = { .len = sizeof(struct tc_ratespec) },
+       [TCA_CBQ_RTAB]          = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+       [TCA_CBQ_POLICE]        = { .len = sizeof(struct tc_cbq_police) },
+};
+
+static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct cbq_sched_data *q = qdisc_priv(sch);
-       struct rtattr *tb[TCA_CBQ_MAX];
+       struct nlattr *tb[TCA_CBQ_MAX + 1];
        struct tc_ratespec *r;
+       int err;
 
-       if (rtattr_parse_nested(tb, TCA_CBQ_MAX, opt) < 0 ||
-           tb[TCA_CBQ_RTAB-1] == NULL || tb[TCA_CBQ_RATE-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_CBQ_RATE-1]) < sizeof(struct tc_ratespec))
-               return -EINVAL;
+       err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
+       if (err < 0)
+               return err;
 
-       if (tb[TCA_CBQ_LSSOPT-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT-1]) < sizeof(struct tc_cbq_lssopt))
+       if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL)
                return -EINVAL;
 
-       r = RTA_DATA(tb[TCA_CBQ_RATE-1]);
+       r = nla_data(tb[TCA_CBQ_RATE]);
 
-       if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB-1])) == NULL)
+       if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB])) == NULL)
                return -EINVAL;
 
        q->link.refcnt = 1;
@@ -1427,8 +1436,8 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
 
        cbq_link_class(&q->link);
 
-       if (tb[TCA_CBQ_LSSOPT-1])
-               cbq_set_lss(&q->link, RTA_DATA(tb[TCA_CBQ_LSSOPT-1]));
+       if (tb[TCA_CBQ_LSSOPT])
+               cbq_set_lss(&q->link, nla_data(tb[TCA_CBQ_LSSOPT]));
 
        cbq_addprio(q, &q->link);
        return 0;
@@ -1438,10 +1447,10 @@ static __inline__ int cbq_dump_rate(struct sk_buff *skb, struct cbq_class *cl)
 {
        unsigned char *b = skb_tail_pointer(skb);
 
-       RTA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
+       NLA_PUT(skb, TCA_CBQ_RATE, sizeof(cl->R_tab->rate), &cl->R_tab->rate);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1463,10 +1472,10 @@ static __inline__ int cbq_dump_lss(struct sk_buff *skb, struct cbq_class *cl)
        opt.minidle = (u32)(-cl->minidle);
        opt.offtime = cl->offtime;
        opt.change = ~0;
-       RTA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_CBQ_LSSOPT, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1481,10 +1490,10 @@ static __inline__ int cbq_dump_wrr(struct sk_buff *skb, struct cbq_class *cl)
        opt.priority = cl->priority+1;
        opt.cpriority = cl->cpriority+1;
        opt.weight = cl->weight;
-       RTA_PUT(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_CBQ_WRROPT, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1498,10 +1507,10 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl)
        opt.priority2 = cl->priority2+1;
        opt.pad = 0;
        opt.penalty = cl->penalty;
-       RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1515,11 +1524,11 @@ static __inline__ int cbq_dump_fopt(struct sk_buff *skb, struct cbq_class *cl)
                opt.split = cl->split ? cl->split->classid : 0;
                opt.defmap = cl->defmap;
                opt.defchange = ~0;
-               RTA_PUT(skb, TCA_CBQ_FOPT, sizeof(opt), &opt);
+               NLA_PUT(skb, TCA_CBQ_FOPT, sizeof(opt), &opt);
        }
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1534,11 +1543,11 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl)
                opt.police = cl->police;
                opt.__res1 = 0;
                opt.__res2 = 0;
-               RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
+               NLA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt);
        }
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1561,18 +1570,18 @@ static int cbq_dump_attr(struct sk_buff *skb, struct cbq_class *cl)
 static int cbq_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct cbq_sched_data *q = qdisc_priv(sch);
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
        if (cbq_dump_attr(skb, &q->link) < 0)
-               goto rtattr_failure;
-       rta->rta_len = skb_tail_pointer(skb) - b;
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1590,8 +1599,7 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
               struct sk_buff *skb, struct tcmsg *tcm)
 {
        struct cbq_class *cl = (struct cbq_class*)arg;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
        if (cl->tparent)
                tcm->tcm_parent = cl->tparent->classid;
@@ -1600,15 +1608,16 @@ cbq_dump_class(struct Qdisc *sch, unsigned long arg,
        tcm->tcm_handle = cl->classid;
        tcm->tcm_info = cl->q->handle;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
        if (cbq_dump_attr(skb, cl) < 0)
-               goto rtattr_failure;
-       rta->rta_len = skb_tail_pointer(skb) - b;
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1753,45 +1762,23 @@ static void cbq_put(struct Qdisc *sch, unsigned long arg)
 }
 
 static int
-cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **tca,
+cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
                 unsigned long *arg)
 {
        int err;
        struct cbq_sched_data *q = qdisc_priv(sch);
        struct cbq_class *cl = (struct cbq_class*)*arg;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_CBQ_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_CBQ_MAX + 1];
        struct cbq_class *parent;
        struct qdisc_rate_table *rtab = NULL;
 
-       if (opt==NULL || rtattr_parse_nested(tb, TCA_CBQ_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
 
-       if (tb[TCA_CBQ_OVL_STRATEGY-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_OVL_STRATEGY-1]) < sizeof(struct tc_cbq_ovl))
-               return -EINVAL;
-
-       if (tb[TCA_CBQ_FOPT-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_FOPT-1]) < sizeof(struct tc_cbq_fopt))
-               return -EINVAL;
-
-       if (tb[TCA_CBQ_RATE-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_RATE-1]) < sizeof(struct tc_ratespec))
-                       return -EINVAL;
-
-       if (tb[TCA_CBQ_LSSOPT-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_LSSOPT-1]) < sizeof(struct tc_cbq_lssopt))
-                       return -EINVAL;
-
-       if (tb[TCA_CBQ_WRROPT-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_WRROPT-1]) < sizeof(struct tc_cbq_wrropt))
-                       return -EINVAL;
-
-#ifdef CONFIG_NET_CLS_ACT
-       if (tb[TCA_CBQ_POLICE-1] &&
-           RTA_PAYLOAD(tb[TCA_CBQ_POLICE-1]) < sizeof(struct tc_cbq_police))
-                       return -EINVAL;
-#endif
+       err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
+       if (err < 0)
+               return err;
 
        if (cl) {
                /* Check parent */
@@ -1802,8 +1789,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
                                return -EINVAL;
                }
 
-               if (tb[TCA_CBQ_RATE-1]) {
-                       rtab = qdisc_get_rtab(RTA_DATA(tb[TCA_CBQ_RATE-1]), tb[TCA_CBQ_RTAB-1]);
+               if (tb[TCA_CBQ_RATE]) {
+                       rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
                        if (rtab == NULL)
                                return -EINVAL;
                }
@@ -1819,45 +1806,45 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
                        qdisc_put_rtab(rtab);
                }
 
-               if (tb[TCA_CBQ_LSSOPT-1])
-                       cbq_set_lss(cl, RTA_DATA(tb[TCA_CBQ_LSSOPT-1]));
+               if (tb[TCA_CBQ_LSSOPT])
+                       cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
 
-               if (tb[TCA_CBQ_WRROPT-1]) {
+               if (tb[TCA_CBQ_WRROPT]) {
                        cbq_rmprio(q, cl);
-                       cbq_set_wrr(cl, RTA_DATA(tb[TCA_CBQ_WRROPT-1]));
+                       cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
                }
 
-               if (tb[TCA_CBQ_OVL_STRATEGY-1])
-                       cbq_set_overlimit(cl, RTA_DATA(tb[TCA_CBQ_OVL_STRATEGY-1]));
+               if (tb[TCA_CBQ_OVL_STRATEGY])
+                       cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
 
 #ifdef CONFIG_NET_CLS_ACT
-               if (tb[TCA_CBQ_POLICE-1])
-                       cbq_set_police(cl, RTA_DATA(tb[TCA_CBQ_POLICE-1]));
+               if (tb[TCA_CBQ_POLICE])
+                       cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
 #endif
 
-               if (tb[TCA_CBQ_FOPT-1])
-                       cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1]));
+               if (tb[TCA_CBQ_FOPT])
+                       cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
 
                if (cl->q->q.qlen)
                        cbq_activate_class(cl);
 
                sch_tree_unlock(sch);
 
-               if (tca[TCA_RATE-1])
+               if (tca[TCA_RATE])
                        gen_replace_estimator(&cl->bstats, &cl->rate_est,
                                              &sch->dev->queue_lock,
-                                             tca[TCA_RATE-1]);
+                                             tca[TCA_RATE]);
                return 0;
        }
 
        if (parentid == TC_H_ROOT)
                return -EINVAL;
 
-       if (tb[TCA_CBQ_WRROPT-1] == NULL || tb[TCA_CBQ_RATE-1] == NULL ||
-           tb[TCA_CBQ_LSSOPT-1] == NULL)
+       if (tb[TCA_CBQ_WRROPT] == NULL || tb[TCA_CBQ_RATE] == NULL ||
+           tb[TCA_CBQ_LSSOPT] == NULL)
                return -EINVAL;
 
-       rtab = qdisc_get_rtab(RTA_DATA(tb[TCA_CBQ_RATE-1]), tb[TCA_CBQ_RTAB-1]);
+       rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
        if (rtab == NULL)
                return -EINVAL;
 
@@ -1912,8 +1899,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
                cl->share = cl->tparent;
        cbq_adjust_levels(parent);
        cl->minidle = -0x7FFFFFFF;
-       cbq_set_lss(cl, RTA_DATA(tb[TCA_CBQ_LSSOPT-1]));
-       cbq_set_wrr(cl, RTA_DATA(tb[TCA_CBQ_WRROPT-1]));
+       cbq_set_lss(cl, nla_data(tb[TCA_CBQ_LSSOPT]));
+       cbq_set_wrr(cl, nla_data(tb[TCA_CBQ_WRROPT]));
        if (cl->ewma_log==0)
                cl->ewma_log = q->link.ewma_log;
        if (cl->maxidle==0)
@@ -1921,19 +1908,19 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
        if (cl->avpkt==0)
                cl->avpkt = q->link.avpkt;
        cl->overlimit = cbq_ovl_classic;
-       if (tb[TCA_CBQ_OVL_STRATEGY-1])
-               cbq_set_overlimit(cl, RTA_DATA(tb[TCA_CBQ_OVL_STRATEGY-1]));
+       if (tb[TCA_CBQ_OVL_STRATEGY])
+               cbq_set_overlimit(cl, nla_data(tb[TCA_CBQ_OVL_STRATEGY]));
 #ifdef CONFIG_NET_CLS_ACT
-       if (tb[TCA_CBQ_POLICE-1])
-               cbq_set_police(cl, RTA_DATA(tb[TCA_CBQ_POLICE-1]));
+       if (tb[TCA_CBQ_POLICE])
+               cbq_set_police(cl, nla_data(tb[TCA_CBQ_POLICE]));
 #endif
-       if (tb[TCA_CBQ_FOPT-1])
-               cbq_set_fopt(cl, RTA_DATA(tb[TCA_CBQ_FOPT-1]));
+       if (tb[TCA_CBQ_FOPT])
+               cbq_set_fopt(cl, nla_data(tb[TCA_CBQ_FOPT]));
        sch_tree_unlock(sch);
 
-       if (tca[TCA_RATE-1])
+       if (tca[TCA_RATE])
                gen_new_estimator(&cl->bstats, &cl->rate_est,
-                                 &sch->dev->queue_lock, tca[TCA_RATE-1]);
+                                 &sch->dev->queue_lock, tca[TCA_RATE]);
 
        *arg = (unsigned long)cl;
        return 0;
@@ -2045,7 +2032,7 @@ static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
        }
 }
 
-static struct Qdisc_class_ops cbq_class_ops = {
+static const struct Qdisc_class_ops cbq_class_ops = {
        .graft          =       cbq_graft,
        .leaf           =       cbq_leaf,
        .qlen_notify    =       cbq_qlen_notify,
@@ -2061,7 +2048,7 @@ static struct Qdisc_class_ops cbq_class_ops = {
        .dump_stats     =       cbq_dump_class_stats,
 };
 
-static struct Qdisc_ops cbq_qdisc_ops = {
+static struct Qdisc_ops cbq_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &cbq_class_ops,
        .id             =       "cbq",
index 60f89199e3da861f8c1af675fa402f071328c3d5..0df911fd67b1bddbcfc38c69fc3f7d5ee12799c1 100644 (file)
 #include <linux/errno.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
+#include <linux/bitops.h>
 #include <net/pkt_sched.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
 #include <asm/byteorder.h>
 
-
-#if 0 /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0 /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
-
-#define PRIV(sch) ((struct dsmark_qdisc_data *) qdisc_priv(sch))
-
-
 /*
  * classid     class           marking
  * -------     -----           -------
@@ -60,17 +44,6 @@ struct dsmark_qdisc_data {
        int                     set_tc_index;
 };
 
-static inline int dsmark_valid_indices(u16 indices)
-{
-       while (indices != 1) {
-               if (indices & 1)
-                       return 0;
-               indices >>= 1;
-       }
-
-       return 1;
-}
-
 static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
 {
        return (index <= p->indices && index > 0);
@@ -81,9 +54,9 @@ static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
 static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
                        struct Qdisc *new, struct Qdisc **old)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
-       DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
+       pr_debug("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",
                sch, p, new, old);
 
        if (new == NULL) {
@@ -104,13 +77,14 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
 
 static struct Qdisc *dsmark_leaf(struct Qdisc *sch, unsigned long arg)
 {
-       return PRIV(sch)->q;
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       return p->q;
 }
 
 static unsigned long dsmark_get(struct Qdisc *sch, u32 classid)
 {
-       DPRINTK("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
-               sch, PRIV(sch), classid);
+       pr_debug("dsmark_get(sch %p,[qdisc %p],classid %x)\n",
+               sch, qdisc_priv(sch), classid);
 
        return TC_H_MIN(classid) + 1;
 }
@@ -125,44 +99,56 @@ static void dsmark_put(struct Qdisc *sch, unsigned long cl)
 {
 }
 
+static const struct nla_policy dsmark_policy[TCA_DSMARK_MAX + 1] = {
+       [TCA_DSMARK_INDICES]            = { .type = NLA_U16 },
+       [TCA_DSMARK_DEFAULT_INDEX]      = { .type = NLA_U16 },
+       [TCA_DSMARK_SET_TC_INDEX]       = { .type = NLA_FLAG },
+       [TCA_DSMARK_MASK]               = { .type = NLA_U8 },
+       [TCA_DSMARK_VALUE]              = { .type = NLA_U8 },
+};
+
 static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
-                        struct rtattr **tca, unsigned long *arg)
+                        struct nlattr **tca, unsigned long *arg)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_DSMARK_MAX];
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_DSMARK_MAX + 1];
        int err = -EINVAL;
        u8 mask = 0;
 
-       DPRINTK("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
+       pr_debug("dsmark_change(sch %p,[qdisc %p],classid %x,parent %x),"
                "arg 0x%lx\n", sch, p, classid, parent, *arg);
 
        if (!dsmark_valid_index(p, *arg)) {
                err = -ENOENT;
-               goto rtattr_failure;
+               goto errout;
        }
 
-       if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt))
-               goto rtattr_failure;
+       if (!opt)
+               goto errout;
 
-       if (tb[TCA_DSMARK_MASK-1])
-               mask = RTA_GET_U8(tb[TCA_DSMARK_MASK-1]);
+       err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, dsmark_policy);
+       if (err < 0)
+               goto errout;
+
+       if (tb[TCA_DSMARK_MASK])
+               mask = nla_get_u8(tb[TCA_DSMARK_MASK]);
 
-       if (tb[TCA_DSMARK_VALUE-1])
-               p->value[*arg-1] = RTA_GET_U8(tb[TCA_DSMARK_VALUE-1]);
+       if (tb[TCA_DSMARK_VALUE])
+               p->value[*arg-1] = nla_get_u8(tb[TCA_DSMARK_VALUE]);
 
-       if (tb[TCA_DSMARK_MASK-1])
+       if (tb[TCA_DSMARK_MASK])
                p->mask[*arg-1] = mask;
 
        err = 0;
 
-rtattr_failure:
+errout:
        return err;
 }
 
 static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
        if (!dsmark_valid_index(p, arg))
                return -EINVAL;
@@ -173,12 +159,12 @@ static int dsmark_delete(struct Qdisc *sch, unsigned long arg)
        return 0;
 }
 
-static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker)
+static void dsmark_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
        int i;
 
-       DPRINTK("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
+       pr_debug("dsmark_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
 
        if (walker->stop)
                return;
@@ -197,34 +183,42 @@ ignore:
        }
 }
 
-static struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,unsigned long cl)
+static inline struct tcf_proto **dsmark_find_tcf(struct Qdisc *sch,
+                                                unsigned long cl)
 {
-       return &PRIV(sch)->filter_list;
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       return &p->filter_list;
 }
 
 /* --------------------------- Qdisc operations ---------------------------- */
 
-static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
+static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
        int err;
 
-       D2PRINTK("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+       pr_debug("dsmark_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
 
        if (p->set_tc_index) {
-               /* FIXME: Safe with non-linear skbs? --RR */
                switch (skb->protocol) {
-                       case __constant_htons(ETH_P_IP):
-                               skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
-                                       & ~INET_ECN_MASK;
-                               break;
-                       case __constant_htons(ETH_P_IPV6):
-                               skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
-                                       & ~INET_ECN_MASK;
-                               break;
-                       default:
-                               skb->tc_index = 0;
-                               break;
+               case __constant_htons(ETH_P_IP):
+                       if (skb_cow_head(skb, sizeof(struct iphdr)))
+                               goto drop;
+
+                       skb->tc_index = ipv4_get_dsfield(ip_hdr(skb))
+                               & ~INET_ECN_MASK;
+                       break;
+
+               case __constant_htons(ETH_P_IPV6):
+                       if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
+                               goto drop;
+
+                       skb->tc_index = ipv6_get_dsfield(ipv6_hdr(skb))
+                               & ~INET_ECN_MASK;
+                       break;
+               default:
+                       skb->tc_index = 0;
+                       break;
                }
        }
 
@@ -234,7 +228,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
                struct tcf_result res;
                int result = tc_classify(skb, p->filter_list, &res);
 
-               D2PRINTK("result %d class 0x%04x\n", result, res.classid);
+               pr_debug("result %d class 0x%04x\n", result, res.classid);
 
                switch (result) {
 #ifdef CONFIG_NET_CLS_ACT
@@ -242,14 +236,14 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
                case TC_ACT_STOLEN:
                        kfree_skb(skb);
                        return NET_XMIT_SUCCESS;
+
                case TC_ACT_SHOT:
-                       kfree_skb(skb);
-                       sch->qstats.drops++;
-                       return NET_XMIT_BYPASS;
+                       goto drop;
 #endif
                case TC_ACT_OK:
                        skb->tc_index = TC_H_MIN(res.classid);
                        break;
+
                default:
                        if (p->default_index != NO_DEFAULT_INDEX)
                                skb->tc_index = p->default_index;
@@ -257,7 +251,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
                }
        }
 
-       err = p->q->enqueue(skb,p->q);
+       err = p->q->enqueue(skb, p->q);
        if (err != NET_XMIT_SUCCESS) {
                sch->qstats.drops++;
                return err;
@@ -268,15 +262,20 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
        sch->q.qlen++;
 
        return NET_XMIT_SUCCESS;
+
+drop:
+       kfree_skb(skb);
+       sch->qstats.drops++;
+       return NET_XMIT_BYPASS;
 }
 
 static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
        struct sk_buff *skb;
        u32 index;
 
-       D2PRINTK("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("dsmark_dequeue(sch %p,[qdisc %p])\n", sch, p);
 
        skb = p->q->ops->dequeue(p->q);
        if (skb == NULL)
@@ -285,39 +284,39 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
        sch->q.qlen--;
 
        index = skb->tc_index & (p->indices - 1);
-       D2PRINTK("index %d->%d\n", skb->tc_index, index);
+       pr_debug("index %d->%d\n", skb->tc_index, index);
 
        switch (skb->protocol) {
-               case __constant_htons(ETH_P_IP):
-                       ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
-                                           p->value[index]);
-                       break;
-               case __constant_htons(ETH_P_IPV6):
-                       ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
-                                           p->value[index]);
+       case __constant_htons(ETH_P_IP):
+               ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
+                                   p->value[index]);
                        break;
-               default:
-                       /*
-                        * Only complain if a change was actually attempted.
-                        * This way, we can send non-IP traffic through dsmark
-                        * and don't need yet another qdisc as a bypass.
-                        */
-                       if (p->mask[index] != 0xff || p->value[index])
-                               printk(KERN_WARNING "dsmark_dequeue: "
-                                      "unsupported protocol %d\n",
-                                      ntohs(skb->protocol));
+       case __constant_htons(ETH_P_IPV6):
+               ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
+                                   p->value[index]);
                        break;
+       default:
+               /*
+                * Only complain if a change was actually attempted.
+                * This way, we can send non-IP traffic through dsmark
+                * and don't need yet another qdisc as a bypass.
+                */
+               if (p->mask[index] != 0xff || p->value[index])
+                       printk(KERN_WARNING
+                              "dsmark_dequeue: unsupported protocol %d\n",
+                              ntohs(skb->protocol));
+               break;
        }
 
        return skb;
 }
 
-static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
+static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
        int err;
 
-       D2PRINTK("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
+       pr_debug("dsmark_requeue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
 
        err = p->q->ops->requeue(skb, p->q);
        if (err != NET_XMIT_SUCCESS) {
@@ -333,10 +332,10 @@ static int dsmark_requeue(struct sk_buff *skb,struct Qdisc *sch)
 
 static unsigned int dsmark_drop(struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
        unsigned int len;
 
-       DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
 
        if (p->q->ops->drop == NULL)
                return 0;
@@ -348,26 +347,32 @@ static unsigned int dsmark_drop(struct Qdisc *sch)
        return len;
 }
 
-static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
+static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
-       struct rtattr *tb[TCA_DSMARK_MAX];
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       struct nlattr *tb[TCA_DSMARK_MAX + 1];
        int err = -EINVAL;
        u32 default_index = NO_DEFAULT_INDEX;
        u16 indices;
        u8 *mask;
 
-       DPRINTK("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
+       pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
 
-       if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt) < 0)
+       if (!opt)
                goto errout;
 
-       indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]);
-       if (!indices || !dsmark_valid_indices(indices))
+       err = nla_parse_nested(tb, TCA_DSMARK_MAX, opt, dsmark_policy);
+       if (err < 0)
+               goto errout;
+
+       err = -EINVAL;
+       indices = nla_get_u16(tb[TCA_DSMARK_INDICES]);
+
+       if (hweight32(indices) != 1)
                goto errout;
 
-       if (tb[TCA_DSMARK_DEFAULT_INDEX-1])
-               default_index = RTA_GET_U16(tb[TCA_DSMARK_DEFAULT_INDEX-1]);
+       if (tb[TCA_DSMARK_DEFAULT_INDEX])
+               default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]);
 
        mask = kmalloc(indices * 2, GFP_KERNEL);
        if (mask == NULL) {
@@ -383,34 +388,33 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
 
        p->indices = indices;
        p->default_index = default_index;
-       p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]);
+       p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]);
 
        p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle);
        if (p->q == NULL)
                p->q = &noop_qdisc;
 
-       DPRINTK("dsmark_init: qdisc %p\n", p->q);
+       pr_debug("dsmark_init: qdisc %p\n", p->q);
 
        err = 0;
 errout:
-rtattr_failure:
        return err;
 }
 
 static void dsmark_reset(struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
-       DPRINTK("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("dsmark_reset(sch %p,[qdisc %p])\n", sch, p);
        qdisc_reset(p->q);
        sch->q.qlen = 0;
 }
 
 static void dsmark_destroy(struct Qdisc *sch)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
-       DPRINTK("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
+       pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
 
        tcf_destroy_chain(p->filter_list);
        qdisc_destroy(p->q);
@@ -420,10 +424,10 @@ static void dsmark_destroy(struct Qdisc *sch)
 static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl,
                             struct sk_buff *skb, struct tcmsg *tcm)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
-       struct rtattr *opts = NULL;
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       struct nlattr *opts = NULL;
 
-       DPRINTK("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl);
+       pr_debug("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl);
 
        if (!dsmark_valid_index(p, cl))
                return -EINVAL;
@@ -431,37 +435,41 @@ static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl,
        tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl-1);
        tcm->tcm_info = p->q->handle;
 
-       opts = RTA_NEST(skb, TCA_OPTIONS);
-       RTA_PUT_U8(skb,TCA_DSMARK_MASK, p->mask[cl-1]);
-       RTA_PUT_U8(skb,TCA_DSMARK_VALUE, p->value[cl-1]);
+       opts = nla_nest_start(skb, TCA_OPTIONS);
+       if (opts == NULL)
+               goto nla_put_failure;
+       NLA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl-1]);
+       NLA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl-1]);
 
-       return RTA_NEST_END(skb, opts);
+       return nla_nest_end(skb, opts);
 
-rtattr_failure:
-       return RTA_NEST_CANCEL(skb, opts);
+nla_put_failure:
+       return nla_nest_cancel(skb, opts);
 }
 
 static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
-       struct dsmark_qdisc_data *p = PRIV(sch);
-       struct rtattr *opts = NULL;
+       struct dsmark_qdisc_data *p = qdisc_priv(sch);
+       struct nlattr *opts = NULL;
 
-       opts = RTA_NEST(skb, TCA_OPTIONS);
-       RTA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices);
+       opts = nla_nest_start(skb, TCA_OPTIONS);
+       if (opts == NULL)
+               goto nla_put_failure;
+       NLA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices);
 
        if (p->default_index != NO_DEFAULT_INDEX)
-               RTA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index);
+               NLA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index);
 
        if (p->set_tc_index)
-               RTA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX);
+               NLA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX);
 
-       return RTA_NEST_END(skb, opts);
+       return nla_nest_end(skb, opts);
 
-rtattr_failure:
-       return RTA_NEST_CANCEL(skb, opts);
+nla_put_failure:
+       return nla_nest_cancel(skb, opts);
 }
 
-static struct Qdisc_class_ops dsmark_class_ops = {
+static const struct Qdisc_class_ops dsmark_class_ops = {
        .graft          =       dsmark_graft,
        .leaf           =       dsmark_leaf,
        .get            =       dsmark_get,
@@ -475,7 +483,7 @@ static struct Qdisc_class_ops dsmark_class_ops = {
        .dump           =       dsmark_dump_class,
 };
 
-static struct Qdisc_ops dsmark_qdisc_ops = {
+static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &dsmark_class_ops,
        .id             =       "dsmark",
index c264308f17c1f66f6f7e6c61ca309fa5378f5645..95ed48221652df8aaf081af418c3042fbc76a72c 100644 (file)
@@ -43,7 +43,7 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
        return qdisc_reshape_fail(skb, sch);
 }
 
-static int fifo_init(struct Qdisc *sch, struct rtattr *opt)
+static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct fifo_sched_data *q = qdisc_priv(sch);
 
@@ -55,9 +55,9 @@ static int fifo_init(struct Qdisc *sch, struct rtattr *opt)
 
                q->limit = limit;
        } else {
-               struct tc_fifo_qopt *ctl = RTA_DATA(opt);
+               struct tc_fifo_qopt *ctl = nla_data(opt);
 
-               if (RTA_PAYLOAD(opt) < sizeof(*ctl))
+               if (nla_len(opt) < sizeof(*ctl))
                        return -EINVAL;
 
                q->limit = ctl->limit;
@@ -71,14 +71,14 @@ static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct fifo_sched_data *q = qdisc_priv(sch);
        struct tc_fifo_qopt opt = { .limit = q->limit };
 
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
-struct Qdisc_ops pfifo_qdisc_ops = {
+struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
        .id             =       "pfifo",
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       pfifo_enqueue,
@@ -91,8 +91,9 @@ struct Qdisc_ops pfifo_qdisc_ops = {
        .dump           =       fifo_dump,
        .owner          =       THIS_MODULE,
 };
+EXPORT_SYMBOL(pfifo_qdisc_ops);
 
-struct Qdisc_ops bfifo_qdisc_ops = {
+struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
        .id             =       "bfifo",
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       bfifo_enqueue,
@@ -105,6 +106,4 @@ struct Qdisc_ops bfifo_qdisc_ops = {
        .dump           =       fifo_dump,
        .owner          =       THIS_MODULE,
 };
-
 EXPORT_SYMBOL(bfifo_qdisc_ops);
-EXPORT_SYMBOL(pfifo_qdisc_ops);
index e595e6570ce054245c6f8e355b7612a01521526b..10b5c0887fff3068c887da695dbca63854a97de2 100644 (file)
  */
 
 void qdisc_lock_tree(struct net_device *dev)
+       __acquires(dev->queue_lock)
+       __acquires(dev->ingress_lock)
 {
        spin_lock_bh(&dev->queue_lock);
        spin_lock(&dev->ingress_lock);
 }
+EXPORT_SYMBOL(qdisc_lock_tree);
 
 void qdisc_unlock_tree(struct net_device *dev)
+       __releases(dev->ingress_lock)
+       __releases(dev->queue_lock)
 {
        spin_unlock(&dev->ingress_lock);
        spin_unlock_bh(&dev->queue_lock);
 }
+EXPORT_SYMBOL(qdisc_unlock_tree);
 
 static inline int qdisc_qlen(struct Qdisc *q)
 {
@@ -211,13 +217,6 @@ static void dev_watchdog(unsigned long arg)
        dev_put(dev);
 }
 
-static void dev_watchdog_init(struct net_device *dev)
-{
-       init_timer(&dev->watchdog_timer);
-       dev->watchdog_timer.data = (unsigned long)dev;
-       dev->watchdog_timer.function = dev_watchdog;
-}
-
 void __netdev_watchdog_up(struct net_device *dev)
 {
        if (dev->tx_timeout) {
@@ -256,6 +255,7 @@ void netif_carrier_on(struct net_device *dev)
                        __netdev_watchdog_up(dev);
        }
 }
+EXPORT_SYMBOL(netif_carrier_on);
 
 /**
  *     netif_carrier_off - clear carrier
@@ -268,6 +268,7 @@ void netif_carrier_off(struct net_device *dev)
        if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state))
                linkwatch_fire_event(dev);
 }
+EXPORT_SYMBOL(netif_carrier_off);
 
 /* "NOOP" scheduler: the best scheduler, recommended for all interfaces
    under all circumstances. It is difficult to invent anything faster or
@@ -294,7 +295,7 @@ static int noop_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
        return NET_XMIT_CN;
 }
 
-struct Qdisc_ops noop_qdisc_ops = {
+struct Qdisc_ops noop_qdisc_ops __read_mostly = {
        .id             =       "noop",
        .priv_size      =       0,
        .enqueue        =       noop_enqueue,
@@ -310,8 +311,9 @@ struct Qdisc noop_qdisc = {
        .ops            =       &noop_qdisc_ops,
        .list           =       LIST_HEAD_INIT(noop_qdisc.list),
 };
+EXPORT_SYMBOL(noop_qdisc);
 
-static struct Qdisc_ops noqueue_qdisc_ops = {
+static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
        .id             =       "noqueue",
        .priv_size      =       0,
        .enqueue        =       noop_enqueue,
@@ -395,14 +397,14 @@ static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
        struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
 
        memcpy(&opt.priomap, prio2band, TC_PRIO_MAX+1);
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
-static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
+static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
 {
        int prio;
        struct sk_buff_head *list = qdisc_priv(qdisc);
@@ -413,7 +415,7 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct rtattr *opt)
        return 0;
 }
 
-static struct Qdisc_ops pfifo_fast_ops = {
+static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
        .id             =       "pfifo_fast",
        .priv_size      =       PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
        .enqueue        =       pfifo_fast_enqueue,
@@ -474,16 +476,18 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
 errout:
        return NULL;
 }
+EXPORT_SYMBOL(qdisc_create_dflt);
 
 /* Under dev->queue_lock and BH! */
 
 void qdisc_reset(struct Qdisc *qdisc)
 {
-       struct Qdisc_ops *ops = qdisc->ops;
+       const struct Qdisc_ops *ops = qdisc->ops;
 
        if (ops->reset)
                ops->reset(qdisc);
 }
+EXPORT_SYMBOL(qdisc_reset);
 
 /* this is the rcu callback function to clean up a qdisc when there
  * are no further references to it */
@@ -498,7 +502,7 @@ static void __qdisc_destroy(struct rcu_head *head)
 
 void qdisc_destroy(struct Qdisc *qdisc)
 {
-       struct Qdisc_ops  *ops = qdisc->ops;
+       const struct Qdisc_ops  *ops = qdisc->ops;
 
        if (qdisc->flags & TCQ_F_BUILTIN ||
            !atomic_dec_and_test(&qdisc->refcnt))
@@ -515,6 +519,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
        dev_put(qdisc->dev);
        call_rcu(&qdisc->q_rcu, __qdisc_destroy);
 }
+EXPORT_SYMBOL(qdisc_destroy);
 
 void dev_activate(struct net_device *dev)
 {
@@ -608,7 +613,7 @@ void dev_init_scheduler(struct net_device *dev)
        INIT_LIST_HEAD(&dev->qdisc_list);
        qdisc_unlock_tree(dev);
 
-       dev_watchdog_init(dev);
+       setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev);
 }
 
 void dev_shutdown(struct net_device *dev)
@@ -629,12 +634,3 @@ void dev_shutdown(struct net_device *dev)
        BUG_TRAP(!timer_pending(&dev->watchdog_timer));
        qdisc_unlock_tree(dev);
 }
-
-EXPORT_SYMBOL(netif_carrier_on);
-EXPORT_SYMBOL(netif_carrier_off);
-EXPORT_SYMBOL(noop_qdisc);
-EXPORT_SYMBOL(qdisc_create_dflt);
-EXPORT_SYMBOL(qdisc_destroy);
-EXPORT_SYMBOL(qdisc_reset);
-EXPORT_SYMBOL(qdisc_lock_tree);
-EXPORT_SYMBOL(qdisc_unlock_tree);
index 3cc6dda02e2e0a1297ecc8a2d5a7e3707a4b556c..3a9d226ff1e41eba0492168f3166e4a9a3cb8f15 100644 (file)
@@ -350,16 +350,16 @@ static inline void gred_destroy_vq(struct gred_sched_data *q)
        kfree(q);
 }
 
-static inline int gred_change_table_def(struct Qdisc *sch, struct rtattr *dps)
+static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps)
 {
        struct gred_sched *table = qdisc_priv(sch);
        struct tc_gred_sopt *sopt;
        int i;
 
-       if (dps == NULL || RTA_PAYLOAD(dps) < sizeof(*sopt))
+       if (dps == NULL)
                return -EINVAL;
 
-       sopt = RTA_DATA(dps);
+       sopt = nla_data(dps);
 
        if (sopt->DPs > MAX_DPs || sopt->DPs == 0 || sopt->def_DP >= sopt->DPs)
                return -EINVAL;
@@ -425,28 +425,37 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
        return 0;
 }
 
-static int gred_change(struct Qdisc *sch, struct rtattr *opt)
+static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = {
+       [TCA_GRED_PARMS]        = { .len = sizeof(struct tc_gred_qopt) },
+       [TCA_GRED_STAB]         = { .len = 256 },
+       [TCA_GRED_DPS]          = { .len = sizeof(struct tc_gred_sopt) },
+};
+
+static int gred_change(struct Qdisc *sch, struct nlattr *opt)
 {
        struct gred_sched *table = qdisc_priv(sch);
        struct tc_gred_qopt *ctl;
-       struct rtattr *tb[TCA_GRED_MAX];
-       int err = -EINVAL, prio = GRED_DEF_PRIO;
+       struct nlattr *tb[TCA_GRED_MAX + 1];
+       int err, prio = GRED_DEF_PRIO;
        u8 *stab;
 
-       if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
 
-       if (tb[TCA_GRED_PARMS-1] == NULL && tb[TCA_GRED_STAB-1] == NULL)
+       err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_GRED_PARMS] == NULL && tb[TCA_GRED_STAB] == NULL)
                return gred_change_table_def(sch, opt);
 
-       if (tb[TCA_GRED_PARMS-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_GRED_PARMS-1]) < sizeof(*ctl) ||
-           tb[TCA_GRED_STAB-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_GRED_STAB-1]) < 256)
+       if (tb[TCA_GRED_PARMS] == NULL ||
+           tb[TCA_GRED_STAB] == NULL)
                return -EINVAL;
 
-       ctl = RTA_DATA(tb[TCA_GRED_PARMS-1]);
-       stab = RTA_DATA(tb[TCA_GRED_STAB-1]);
+       err = -EINVAL;
+       ctl = nla_data(tb[TCA_GRED_PARMS]);
+       stab = nla_data(tb[TCA_GRED_STAB]);
 
        if (ctl->DP >= table->DPs)
                goto errout;
@@ -486,23 +495,28 @@ errout:
        return err;
 }
 
-static int gred_init(struct Qdisc *sch, struct rtattr *opt)
+static int gred_init(struct Qdisc *sch, struct nlattr *opt)
 {
-       struct rtattr *tb[TCA_GRED_MAX];
+       struct nlattr *tb[TCA_GRED_MAX + 1];
+       int err;
 
-       if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
 
-       if (tb[TCA_GRED_PARMS-1] || tb[TCA_GRED_STAB-1])
+       err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_GRED_PARMS] || tb[TCA_GRED_STAB])
                return -EINVAL;
 
-       return gred_change_table_def(sch, tb[TCA_GRED_DPS-1]);
+       return gred_change_table_def(sch, tb[TCA_GRED_DPS]);
 }
 
 static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct gred_sched *table = qdisc_priv(sch);
-       struct rtattr *parms, *opts = NULL;
+       struct nlattr *parms, *opts = NULL;
        int i;
        struct tc_gred_sopt sopt = {
                .DPs    = table->DPs,
@@ -511,9 +525,13 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
                .flags  = table->red_flags,
        };
 
-       opts = RTA_NEST(skb, TCA_OPTIONS);
-       RTA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
-       parms = RTA_NEST(skb, TCA_GRED_PARMS);
+       opts = nla_nest_start(skb, TCA_OPTIONS);
+       if (opts == NULL)
+               goto nla_put_failure;
+       NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
+       parms = nla_nest_start(skb, TCA_GRED_PARMS);
+       if (parms == NULL)
+               goto nla_put_failure;
 
        for (i = 0; i < MAX_DPs; i++) {
                struct gred_sched_data *q = table->tab[i];
@@ -555,15 +573,16 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
                opt.qave = red_calc_qavg(&q->parms, q->parms.qavg);
 
 append_opt:
-               RTA_APPEND(skb, sizeof(opt), &opt);
+               if (nla_append(skb, sizeof(opt), &opt) < 0)
+                       goto nla_put_failure;
        }
 
-       RTA_NEST_END(skb, parms);
+       nla_nest_end(skb, parms);
 
-       return RTA_NEST_END(skb, opts);
+       return nla_nest_end(skb, opts);
 
-rtattr_failure:
-       return RTA_NEST_CANCEL(skb, opts);
+nla_put_failure:
+       return nla_nest_cancel(skb, opts);
 }
 
 static void gred_destroy(struct Qdisc *sch)
@@ -577,7 +596,7 @@ static void gred_destroy(struct Qdisc *sch)
        }
 }
 
-static struct Qdisc_ops gred_qdisc_ops = {
+static struct Qdisc_ops gred_qdisc_ops __read_mostly = {
        .id             =       "gred",
        .priv_size      =       sizeof(struct gred_sched),
        .enqueue        =       gred_enqueue,
index a6ad491e434b90bb7fb866ac743adea3180224b5..87293d0db1d7fe1d64a162eefbc70c49278ffd6b 100644 (file)
@@ -986,41 +986,46 @@ hfsc_change_usc(struct hfsc_class *cl, struct tc_service_curve *usc,
        cl->cl_flags |= HFSC_USC;
 }
 
+static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = {
+       [TCA_HFSC_RSC]  = { .len = sizeof(struct tc_service_curve) },
+       [TCA_HFSC_FSC]  = { .len = sizeof(struct tc_service_curve) },
+       [TCA_HFSC_USC]  = { .len = sizeof(struct tc_service_curve) },
+};
+
 static int
 hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-                 struct rtattr **tca, unsigned long *arg)
+                 struct nlattr **tca, unsigned long *arg)
 {
        struct hfsc_sched *q = qdisc_priv(sch);
        struct hfsc_class *cl = (struct hfsc_class *)*arg;
        struct hfsc_class *parent = NULL;
-       struct rtattr *opt = tca[TCA_OPTIONS-1];
-       struct rtattr *tb[TCA_HFSC_MAX];
+       struct nlattr *opt = tca[TCA_OPTIONS];
+       struct nlattr *tb[TCA_HFSC_MAX + 1];
        struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL;
        u64 cur_time;
+       int err;
 
-       if (opt == NULL || rtattr_parse_nested(tb, TCA_HFSC_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
 
-       if (tb[TCA_HFSC_RSC-1]) {
-               if (RTA_PAYLOAD(tb[TCA_HFSC_RSC-1]) < sizeof(*rsc))
-                       return -EINVAL;
-               rsc = RTA_DATA(tb[TCA_HFSC_RSC-1]);
+       err = nla_parse_nested(tb, TCA_HFSC_MAX, opt, hfsc_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_HFSC_RSC]) {
+               rsc = nla_data(tb[TCA_HFSC_RSC]);
                if (rsc->m1 == 0 && rsc->m2 == 0)
                        rsc = NULL;
        }
 
-       if (tb[TCA_HFSC_FSC-1]) {
-               if (RTA_PAYLOAD(tb[TCA_HFSC_FSC-1]) < sizeof(*fsc))
-                       return -EINVAL;
-               fsc = RTA_DATA(tb[TCA_HFSC_FSC-1]);
+       if (tb[TCA_HFSC_FSC]) {
+               fsc = nla_data(tb[TCA_HFSC_FSC]);
                if (fsc->m1 == 0 && fsc->m2 == 0)
                        fsc = NULL;
        }
 
-       if (tb[TCA_HFSC_USC-1]) {
-               if (RTA_PAYLOAD(tb[TCA_HFSC_USC-1]) < sizeof(*usc))
-                       return -EINVAL;
-               usc = RTA_DATA(tb[TCA_HFSC_USC-1]);
+       if (tb[TCA_HFSC_USC]) {
+               usc = nla_data(tb[TCA_HFSC_USC]);
                if (usc->m1 == 0 && usc->m2 == 0)
                        usc = NULL;
        }
@@ -1050,10 +1055,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
                }
                sch_tree_unlock(sch);
 
-               if (tca[TCA_RATE-1])
+               if (tca[TCA_RATE])
                        gen_replace_estimator(&cl->bstats, &cl->rate_est,
                                              &sch->dev->queue_lock,
-                                             tca[TCA_RATE-1]);
+                                             tca[TCA_RATE]);
                return 0;
        }
 
@@ -1106,9 +1111,9 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
        cl->cl_pcvtoff = parent->cl_cvtoff;
        sch_tree_unlock(sch);
 
-       if (tca[TCA_RATE-1])
+       if (tca[TCA_RATE])
                gen_new_estimator(&cl->bstats, &cl->rate_est,
-                                 &sch->dev->queue_lock, tca[TCA_RATE-1]);
+                                 &sch->dev->queue_lock, tca[TCA_RATE]);
        *arg = (unsigned long)cl;
        return 0;
 }
@@ -1304,11 +1309,11 @@ hfsc_dump_sc(struct sk_buff *skb, int attr, struct internal_sc *sc)
        tsc.m1 = sm2m(sc->sm1);
        tsc.d  = dx2d(sc->dx);
        tsc.m2 = sm2m(sc->sm2);
-       RTA_PUT(skb, attr, sizeof(tsc), &tsc);
+       NLA_PUT(skb, attr, sizeof(tsc), &tsc);
 
        return skb->len;
 
rtattr_failure:
nla_put_failure:
        return -1;
 }
 
@@ -1317,19 +1322,19 @@ hfsc_dump_curves(struct sk_buff *skb, struct hfsc_class *cl)
 {
        if ((cl->cl_flags & HFSC_RSC) &&
            (hfsc_dump_sc(skb, TCA_HFSC_RSC, &cl->cl_rsc) < 0))
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if ((cl->cl_flags & HFSC_FSC) &&
            (hfsc_dump_sc(skb, TCA_HFSC_FSC, &cl->cl_fsc) < 0))
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        if ((cl->cl_flags & HFSC_USC) &&
            (hfsc_dump_sc(skb, TCA_HFSC_USC, &cl->cl_usc) < 0))
-               goto rtattr_failure;
+               goto nla_put_failure;
 
        return skb->len;
 
rtattr_failure:
nla_put_failure:
        return -1;
 }
 
@@ -1338,22 +1343,23 @@ hfsc_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
                struct tcmsg *tcm)
 {
        struct hfsc_class *cl = (struct hfsc_class *)arg;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta = (struct rtattr *)b;
+       struct nlattr *nest;
 
        tcm->tcm_parent = cl->cl_parent ? cl->cl_parent->classid : TC_H_ROOT;
        tcm->tcm_handle = cl->classid;
        if (cl->level == 0)
                tcm->tcm_info = cl->qdisc->handle;
 
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
        if (hfsc_dump_curves(skb, cl) < 0)
-               goto rtattr_failure;
-       rta->rta_len = skb_tail_pointer(skb) - b;
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
        return skb->len;
 
rtattr_failure:
-       nlmsg_trim(skb, b);
nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1423,15 +1429,15 @@ hfsc_schedule_watchdog(struct Qdisc *sch)
 }
 
 static int
-hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
+hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
 {
        struct hfsc_sched *q = qdisc_priv(sch);
        struct tc_hfsc_qopt *qopt;
        unsigned int i;
 
-       if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
+       if (opt == NULL || nla_len(opt) < sizeof(*qopt))
                return -EINVAL;
-       qopt = RTA_DATA(opt);
+       qopt = nla_data(opt);
 
        q->defcls = qopt->defcls;
        for (i = 0; i < HFSC_HSIZE; i++)
@@ -1459,14 +1465,14 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
 }
 
 static int
-hfsc_change_qdisc(struct Qdisc *sch, struct rtattr *opt)
+hfsc_change_qdisc(struct Qdisc *sch, struct nlattr *opt)
 {
        struct hfsc_sched *q = qdisc_priv(sch);
        struct tc_hfsc_qopt *qopt;
 
-       if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
+       if (opt == NULL || nla_len(opt) < sizeof(*qopt))
                return -EINVAL;
-       qopt = RTA_DATA(opt);
+       qopt = nla_data(opt);
 
        sch_tree_lock(sch);
        q->defcls = qopt->defcls;
@@ -1550,10 +1556,10 @@ hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
        struct tc_hfsc_qopt qopt;
 
        qopt.defcls = q->defcls;
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
        return skb->len;
 
rtattr_failure:
nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -1698,7 +1704,7 @@ hfsc_drop(struct Qdisc *sch)
        return 0;
 }
 
-static struct Qdisc_class_ops hfsc_class_ops = {
+static const struct Qdisc_class_ops hfsc_class_ops = {
        .change         = hfsc_change_class,
        .delete         = hfsc_delete_class,
        .graft          = hfsc_graft_class,
@@ -1714,7 +1720,7 @@ static struct Qdisc_class_ops hfsc_class_ops = {
        .walk           = hfsc_walk
 };
 
-static struct Qdisc_ops hfsc_qdisc_ops = {
+static struct Qdisc_ops hfsc_qdisc_ops __read_mostly = {
        .id             = "hfsc",
        .init           = hfsc_init_qdisc,
        .change         = hfsc_change_qdisc,
index 5e608a64935af6b644c6ecf3596f7dd84c32d35a..e1a579efc215a930d3ece2d3f4938446550f57f0 100644 (file)
@@ -214,10 +214,6 @@ static inline struct htb_class *htb_find(u32 handle, struct Qdisc *sch)
  * then finish and return direct queue.
  */
 #define HTB_DIRECT (struct htb_class*)-1
-static inline u32 htb_classid(struct htb_class *cl)
-{
-       return (cl && cl != HTB_DIRECT) ? cl->classid : TC_H_UNSPEC;
-}
 
 static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
                                      int *qerr)
@@ -996,19 +992,33 @@ static void htb_reset(struct Qdisc *sch)
                INIT_LIST_HEAD(q->drops + i);
 }
 
-static int htb_init(struct Qdisc *sch, struct rtattr *opt)
+static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = {
+       [TCA_HTB_PARMS] = { .len = sizeof(struct tc_htb_opt) },
+       [TCA_HTB_INIT]  = { .len = sizeof(struct tc_htb_glob) },
+       [TCA_HTB_CTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+       [TCA_HTB_RTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+};
+
+static int htb_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct htb_sched *q = qdisc_priv(sch);
-       struct rtattr *tb[TCA_HTB_INIT];
+       struct nlattr *tb[TCA_HTB_INIT + 1];
        struct tc_htb_glob *gopt;
+       int err;
        int i;
-       if (!opt || rtattr_parse_nested(tb, TCA_HTB_INIT, opt) ||
-           tb[TCA_HTB_INIT - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_HTB_INIT - 1]) < sizeof(*gopt)) {
+
+       if (!opt)
+               return -EINVAL;
+
+       err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_HTB_INIT] == NULL) {
                printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
                return -EINVAL;
        }
-       gopt = RTA_DATA(tb[TCA_HTB_INIT - 1]);
+       gopt = nla_data(tb[TCA_HTB_INIT]);
        if (gopt->version != HTB_VER >> 16) {
                printk(KERN_ERR
                       "HTB: need tc/htb version %d (minor is %d), you have %d\n",
@@ -1039,25 +1049,29 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt)
 static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct htb_sched *q = qdisc_priv(sch);
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
        struct tc_htb_glob gopt;
+
        spin_lock_bh(&sch->dev->queue_lock);
-       gopt.direct_pkts = q->direct_pkts;
 
+       gopt.direct_pkts = q->direct_pkts;
        gopt.version = HTB_VER;
        gopt.rate2quantum = q->rate2quantum;
        gopt.defcls = q->defcls;
        gopt.debug = 0;
-       rta = (struct rtattr *)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
-       RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
-       rta->rta_len = skb_tail_pointer(skb) - b;
+
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
+       NLA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
+       nla_nest_end(skb, nest);
+
        spin_unlock_bh(&sch->dev->queue_lock);
        return skb->len;
-rtattr_failure:
+
+nla_put_failure:
        spin_unlock_bh(&sch->dev->queue_lock);
-       nlmsg_trim(skb, skb_tail_pointer(skb));
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1065,8 +1079,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
                          struct sk_buff *skb, struct tcmsg *tcm)
 {
        struct htb_class *cl = (struct htb_class *)arg;
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
        struct tc_htb_opt opt;
 
        spin_lock_bh(&sch->dev->queue_lock);
@@ -1075,8 +1088,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        if (!cl->level && cl->un.leaf.q)
                tcm->tcm_info = cl->un.leaf.q->handle;
 
-       rta = (struct rtattr *)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        memset(&opt, 0, sizeof(opt));
 
@@ -1087,13 +1101,15 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
        opt.quantum = cl->un.leaf.quantum;
        opt.prio = cl->un.leaf.prio;
        opt.level = cl->level;
-       RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       NLA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
+
+       nla_nest_end(skb, nest);
        spin_unlock_bh(&sch->dev->queue_lock);
        return skb->len;
-rtattr_failure:
+
+nla_put_failure:
        spin_unlock_bh(&sch->dev->queue_lock);
-       nlmsg_trim(skb, b);
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -1294,29 +1310,35 @@ static void htb_put(struct Qdisc *sch, unsigned long arg)
 }
 
 static int htb_change_class(struct Qdisc *sch, u32 classid,
-                           u32 parentid, struct rtattr **tca,
+                           u32 parentid, struct nlattr **tca,
                            unsigned long *arg)
 {
        int err = -EINVAL;
        struct htb_sched *q = qdisc_priv(sch);
        struct htb_class *cl = (struct htb_class *)*arg, *parent;
-       struct rtattr *opt = tca[TCA_OPTIONS - 1];
+       struct nlattr *opt = tca[TCA_OPTIONS];
        struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
-       struct rtattr *tb[TCA_HTB_RTAB];
+       struct nlattr *tb[TCA_HTB_RTAB + 1];
        struct tc_htb_opt *hopt;
 
        /* extract all subattrs from opt attr */
-       if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) ||
-           tb[TCA_HTB_PARMS - 1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_HTB_PARMS - 1]) < sizeof(*hopt))
+       if (!opt)
+               goto failure;
+
+       err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy);
+       if (err < 0)
+               goto failure;
+
+       err = -EINVAL;
+       if (tb[TCA_HTB_PARMS] == NULL)
                goto failure;
 
        parent = parentid == TC_H_ROOT ? NULL : htb_find(parentid, sch);
 
-       hopt = RTA_DATA(tb[TCA_HTB_PARMS - 1]);
+       hopt = nla_data(tb[TCA_HTB_PARMS]);
 
-       rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB - 1]);
-       ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB - 1]);
+       rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]);
+       ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]);
        if (!rtab || !ctab)
                goto failure;
 
@@ -1324,12 +1346,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                struct Qdisc *new_q;
                int prio;
                struct {
-                       struct rtattr           rta;
+                       struct nlattr           nla;
                        struct gnet_estimator   opt;
                } est = {
-                       .rta = {
-                               .rta_len        = RTA_LENGTH(sizeof(est.opt)),
-                               .rta_type       = TCA_RATE,
+                       .nla = {
+                               .nla_len        = nla_attr_size(sizeof(est.opt)),
+                               .nla_type       = TCA_RATE,
                        },
                        .opt = {
                                /* 4s interval, 16s averaging constant */
@@ -1354,7 +1376,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 
                gen_new_estimator(&cl->bstats, &cl->rate_est,
                                  &sch->dev->queue_lock,
-                                 tca[TCA_RATE-1] ? : &est.rta);
+                                 tca[TCA_RATE] ? : &est.nla);
                cl->refcnt = 1;
                INIT_LIST_HEAD(&cl->sibling);
                INIT_HLIST_NODE(&cl->hlist);
@@ -1407,10 +1429,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
                list_add_tail(&cl->sibling,
                              parent ? &parent->children : &q->root);
        } else {
-               if (tca[TCA_RATE-1])
+               if (tca[TCA_RATE])
                        gen_replace_estimator(&cl->bstats, &cl->rate_est,
                                              &sch->dev->queue_lock,
-                                             tca[TCA_RATE-1]);
+                                             tca[TCA_RATE]);
                sch_tree_lock(sch);
        }
 
@@ -1529,7 +1551,7 @@ static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg)
        }
 }
 
-static struct Qdisc_class_ops htb_class_ops = {
+static const struct Qdisc_class_ops htb_class_ops = {
        .graft          =       htb_graft,
        .leaf           =       htb_leaf,
        .qlen_notify    =       htb_qlen_notify,
@@ -1545,7 +1567,7 @@ static struct Qdisc_class_ops htb_class_ops = {
        .dump_stats     =       htb_dump_class_stats,
 };
 
-static struct Qdisc_ops htb_qdisc_ops = {
+static struct Qdisc_ops htb_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &htb_class_ops,
        .id             =       "htb",
index 3f8335e6ea2eb51acac63d034fd9664a215a447e..3f72d528273cc4f5a7ff9664d623a428ed718324 100644 (file)
 #include <net/pkt_sched.h>
 
 
-#undef DEBUG_INGRESS
-
-#ifdef DEBUG_INGRESS  /* control */
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#if 0  /* data */
-#define D2PRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define D2PRINTK(format,args...)
-#endif
-
-
-#define PRIV(sch) qdisc_priv(sch)
-
-
-/* Thanks to Doron Oz for this hack
-*/
-#ifndef CONFIG_NET_CLS_ACT
-#ifdef CONFIG_NETFILTER
+/* Thanks to Doron Oz for this hack */
+#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
 static int nf_registered;
 #endif
-#endif
 
 struct ingress_qdisc_data {
-       struct Qdisc            *q;
        struct tcf_proto        *filter_list;
 };
 
-
 /* ------------------------- Class/flow operations ------------------------- */
 
-
-static int ingress_graft(struct Qdisc *sch,unsigned long arg,
-    struct Qdisc *new,struct Qdisc **old)
+static int ingress_graft(struct Qdisc *sch, unsigned long arg,
+                        struct Qdisc *new, struct Qdisc **old)
 {
-#ifdef DEBUG_INGRESS
-       struct ingress_qdisc_data *p = PRIV(sch);
-#endif
-
-       DPRINTK("ingress_graft(sch %p,[qdisc %p],new %p,old %p)\n",
-               sch, p, new, old);
-       DPRINTK("\n ingress_graft: You cannot add qdiscs to classes");
-       return 1;
+       return -EOPNOTSUPP;
 }
 
-
 static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
 {
        return NULL;
 }
 
-
-static unsigned long ingress_get(struct Qdisc *sch,u32 classid)
+static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
 {
-#ifdef DEBUG_INGRESS
-       struct ingress_qdisc_data *p = PRIV(sch);
-#endif
-       DPRINTK("ingress_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
        return TC_H_MIN(classid) + 1;
 }
 
-
 static unsigned long ingress_bind_filter(struct Qdisc *sch,
-    unsigned long parent, u32 classid)
+                                        unsigned long parent, u32 classid)
 {
        return ingress_get(sch, classid);
 }
 
-
 static void ingress_put(struct Qdisc *sch, unsigned long cl)
 {
 }
 
-
 static int ingress_change(struct Qdisc *sch, u32 classid, u32 parent,
-    struct rtattr **tca, unsigned long *arg)
+                         struct nlattr **tca, unsigned long *arg)
 {
-#ifdef DEBUG_INGRESS
-       struct ingress_qdisc_data *p = PRIV(sch);
-#endif
-       DPRINTK("ingress_change(sch %p,[qdisc %p],classid %x,parent %x),"
-               "arg 0x%lx\n", sch, p, classid, parent, *arg);
-       DPRINTK("No effect. sch_ingress doesn't maintain classes at the moment");
        return 0;
 }
 
-
-
-static void ingress_walk(struct Qdisc *sch,struct qdisc_walker *walker)
+static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
-#ifdef DEBUG_INGRESS
-       struct ingress_qdisc_data *p = PRIV(sch);
-#endif
-       DPRINTK("ingress_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
-       DPRINTK("No effect. sch_ingress doesn't maintain classes at the moment");
+       return;
 }
 
-
-static struct tcf_proto **ingress_find_tcf(struct Qdisc *sch,unsigned long cl)
+static struct tcf_proto **ingress_find_tcf(struct Qdisc *sch, unsigned long cl)
 {
-       struct ingress_qdisc_data *p = PRIV(sch);
+       struct ingress_qdisc_data *p = qdisc_priv(sch);
 
        return &p->filter_list;
 }
 
-
 /* --------------------------- Qdisc operations ---------------------------- */
 
-
-static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
+static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
-       struct ingress_qdisc_data *p = PRIV(sch);
+       struct ingress_qdisc_data *p = qdisc_priv(sch);
        struct tcf_result res;
        int result;
 
-       D2PRINTK("ingress_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
        result = tc_classify(skb, p->filter_list, &res);
-       D2PRINTK("result %d class 0x%04x\n", result, res.classid);
+
        /*
         * Unlike normal "enqueue" functions, ingress_enqueue returns a
         * firewall FW_* code.
@@ -148,23 +92,22 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
        sch->bstats.packets++;
        sch->bstats.bytes += skb->len;
        switch (result) {
-               case TC_ACT_SHOT:
-                       result = TC_ACT_SHOT;
-                       sch->qstats.drops++;
-                       break;
-               case TC_ACT_STOLEN:
-               case TC_ACT_QUEUED:
-                       result = TC_ACT_STOLEN;
-                       break;
-               case TC_ACT_RECLASSIFY:
-               case TC_ACT_OK:
-                       skb->tc_index = TC_H_MIN(res.classid);
-               default:
-                       result = TC_ACT_OK;
-                       break;
+       case TC_ACT_SHOT:
+               result = TC_ACT_SHOT;
+               sch->qstats.drops++;
+               break;
+       case TC_ACT_STOLEN:
+       case TC_ACT_QUEUED:
+               result = TC_ACT_STOLEN;
+               break;
+       case TC_ACT_RECLASSIFY:
+       case TC_ACT_OK:
+               skb->tc_index = TC_H_MIN(res.classid);
+       default:
+               result = TC_ACT_OK;
+               break;
        }
 #else
-       D2PRINTK("Overriding result to ACCEPT\n");
        result = NF_ACCEPT;
        sch->bstats.packets++;
        sch->bstats.bytes += skb->len;
@@ -173,39 +116,8 @@ static int ingress_enqueue(struct sk_buff *skb,struct Qdisc *sch)
        return result;
 }
 
-
-static struct sk_buff *ingress_dequeue(struct Qdisc *sch)
-{
-/*
-       struct ingress_qdisc_data *p = PRIV(sch);
-       D2PRINTK("ingress_dequeue(sch %p,[qdisc %p])\n",sch,PRIV(p));
-*/
-       return NULL;
-}
-
-
-static int ingress_requeue(struct sk_buff *skb,struct Qdisc *sch)
-{
-/*
-       struct ingress_qdisc_data *p = PRIV(sch);
-       D2PRINTK("ingress_requeue(skb %p,sch %p,[qdisc %p])\n",skb,sch,PRIV(p));
-*/
-       return 0;
-}
-
-static unsigned int ingress_drop(struct Qdisc *sch)
-{
-#ifdef DEBUG_INGRESS
-       struct ingress_qdisc_data *p = PRIV(sch);
-#endif
-       DPRINTK("ingress_drop(sch %p,[qdisc %p])\n", sch, p);
-       return 0;
-}
-
-#ifndef CONFIG_NET_CLS_ACT
-#ifdef CONFIG_NETFILTER
-static unsigned int
-ing_hook(unsigned int hook, struct sk_buff *skb,
+#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
+static unsigned int ing_hook(unsigned int hook, struct sk_buff *skb,
                             const struct net_device *indev,
                             const struct net_device *outdev,
                             int (*okfn)(struct sk_buff *))
@@ -213,12 +125,7 @@ ing_hook(unsigned int hook, struct sk_buff *skb,
 
        struct Qdisc *q;
        struct net_device *dev = skb->dev;
-       int fwres=NF_ACCEPT;
-
-       DPRINTK("ing_hook: skb %s dev=%s len=%u\n",
-               skb->sk ? "(owned)" : "(unowned)",
-               skb->dev ? skb->dev->name : "(no dev)",
-               skb->len);
+       int fwres = NF_ACCEPT;
 
        if (dev->qdisc_ingress) {
                spin_lock(&dev->ingress_lock);
@@ -231,168 +138,101 @@ ing_hook(unsigned int hook, struct sk_buff *skb,
 }
 
 /* after ipt_filter */
-static struct nf_hook_ops ing_ops = {
-       .hook           = ing_hook,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET,
-       .hooknum        = NF_IP_PRE_ROUTING,
-       .priority       = NF_IP_PRI_FILTER + 1,
-};
-
-static struct nf_hook_ops ing6_ops = {
-       .hook           = ing_hook,
-       .owner          = THIS_MODULE,
-       .pf             = PF_INET6,
-       .hooknum        = NF_IP6_PRE_ROUTING,
-       .priority       = NF_IP6_PRI_FILTER + 1,
+static struct nf_hook_ops ing_ops[] __read_mostly = {
+       {
+               .hook           = ing_hook,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET,
+               .hooknum        = NF_INET_PRE_ROUTING,
+               .priority       = NF_IP_PRI_FILTER + 1,
+       },
+       {
+               .hook           = ing_hook,
+               .owner          = THIS_MODULE,
+               .pf             = PF_INET6,
+               .hooknum        = NF_INET_PRE_ROUTING,
+               .priority       = NF_IP6_PRI_FILTER + 1,
+       },
 };
-
-#endif
 #endif
 
-static int ingress_init(struct Qdisc *sch,struct rtattr *opt)
+static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
 {
-       struct ingress_qdisc_data *p = PRIV(sch);
-
-/* Make sure either netfilter or preferably CLS_ACT is
-* compiled in */
-#ifndef CONFIG_NET_CLS_ACT
-#ifndef CONFIG_NETFILTER
-       printk("You MUST compile classifier actions into the kernel\n");
-       return -EINVAL;
-#else
+#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
        printk("Ingress scheduler: Classifier actions prefered over netfilter\n");
-#endif
-#endif
 
-#ifndef CONFIG_NET_CLS_ACT
-#ifdef CONFIG_NETFILTER
        if (!nf_registered) {
-               if (nf_register_hook(&ing_ops) < 0) {
+               if (nf_register_hooks(ing_ops, ARRAY_SIZE(ing_ops)) < 0) {
                        printk("ingress qdisc registration error \n");
                        return -EINVAL;
                }
                nf_registered++;
-
-               if (nf_register_hook(&ing6_ops) < 0) {
-                       printk("IPv6 ingress qdisc registration error, " \
-                           "disabling IPv6 support.\n");
-               } else
-                       nf_registered++;
        }
 #endif
-#endif
-
-       DPRINTK("ingress_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
-       p->q = &noop_qdisc;
        return 0;
 }
 
-
-static void ingress_reset(struct Qdisc *sch)
-{
-       struct ingress_qdisc_data *p = PRIV(sch);
-
-       DPRINTK("ingress_reset(sch %p,[qdisc %p])\n", sch, p);
-
-/*
-#if 0
-*/
-/* for future use */
-       qdisc_reset(p->q);
-/*
-#endif
-*/
-}
-
-/* ------------------------------------------------------------- */
-
-
 /* ------------------------------------------------------------- */
 
 static void ingress_destroy(struct Qdisc *sch)
 {
-       struct ingress_qdisc_data *p = PRIV(sch);
+       struct ingress_qdisc_data *p = qdisc_priv(sch);
 
-       DPRINTK("ingress_destroy(sch %p,[qdisc %p])\n", sch, p);
        tcf_destroy_chain(p->filter_list);
-#if 0
-/* for future use */
-       qdisc_destroy(p->q);
-#endif
 }
 
-
 static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
 
-       rta = (struct rtattr *) b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
-static struct Qdisc_class_ops ingress_class_ops = {
+static const struct Qdisc_class_ops ingress_class_ops = {
        .graft          =       ingress_graft,
        .leaf           =       ingress_leaf,
        .get            =       ingress_get,
        .put            =       ingress_put,
        .change         =       ingress_change,
-       .delete         =       NULL,
        .walk           =       ingress_walk,
        .tcf_chain      =       ingress_find_tcf,
        .bind_tcf       =       ingress_bind_filter,
        .unbind_tcf     =       ingress_put,
-       .dump           =       NULL,
 };
 
-static struct Qdisc_ops ingress_qdisc_ops = {
-       .next           =       NULL,
+static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
        .cl_ops         =       &ingress_class_ops,
        .id             =       "ingress",
        .priv_size      =       sizeof(struct ingress_qdisc_data),
        .enqueue        =       ingress_enqueue,
-       .dequeue        =       ingress_dequeue,
-       .requeue        =       ingress_requeue,
-       .drop           =       ingress_drop,
        .init           =       ingress_init,
-       .reset          =       ingress_reset,
        .destroy        =       ingress_destroy,
-       .change         =       NULL,
        .dump           =       ingress_dump,
        .owner          =       THIS_MODULE,
 };
 
 static int __init ingress_module_init(void)
 {
-       int ret = 0;
-
-       if ((ret = register_qdisc(&ingress_qdisc_ops)) < 0) {
-               printk("Unable to register Ingress qdisc\n");
-               return ret;
-       }
-
-       return ret;
+       return register_qdisc(&ingress_qdisc_ops);
 }
+
 static void __exit ingress_module_exit(void)
 {
        unregister_qdisc(&ingress_qdisc_ops);
-#ifndef CONFIG_NET_CLS_ACT
-#ifdef CONFIG_NETFILTER
-       if (nf_registered) {
-               nf_unregister_hook(&ing_ops);
-               if (nf_registered > 1)
-                       nf_unregister_hook(&ing6_ops);
-       }
-#endif
+#if !defined(CONFIG_NET_CLS_ACT) && defined(CONFIG_NETFILTER)
+       if (nf_registered)
+               nf_unregister_hooks(ing_ops, ARRAY_SIZE(ing_ops));
 #endif
 }
+
 module_init(ingress_module_init)
 module_exit(ingress_module_exit)
 MODULE_LICENSE("GPL");
index 9e5e87e81f002433cf6cac0ea4ac3f8db519b3fc..c9c649b26eaa1d943b404ccbd4aea3be98fa661d 100644 (file)
@@ -313,21 +313,21 @@ static void netem_reset(struct Qdisc *sch)
 /* Pass size change message down to embedded FIFO */
 static int set_fifo_limit(struct Qdisc *q, int limit)
 {
-       struct rtattr *rta;
+       struct nlattr *nla;
        int ret = -ENOMEM;
 
        /* Hack to avoid sending change message to non-FIFO */
        if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
                return 0;
 
-       rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
-       if (rta) {
-               rta->rta_type = RTM_NEWQDISC;
-               rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
-               ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
+       nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
+       if (nla) {
+               nla->nla_type = RTM_NEWQDISC;
+               nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt));
+               ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit;
 
-               ret = q->ops->change(q, rta);
-               kfree(rta);
+               ret = q->ops->change(q, nla);
+               kfree(nla);
        }
        return ret;
 }
@@ -336,11 +336,11 @@ static int set_fifo_limit(struct Qdisc *q, int limit)
  * Distribution data is a variable size payload containing
  * signed 16 bit values.
  */
-static int get_dist_table(struct Qdisc *sch, const struct rtattr *attr)
+static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
-       unsigned long n = RTA_PAYLOAD(attr)/sizeof(__s16);
-       const __s16 *data = RTA_DATA(attr);
+       unsigned long n = nla_len(attr)/sizeof(__s16);
+       const __s16 *data = nla_data(attr);
        struct disttable *d;
        int i;
 
@@ -363,13 +363,10 @@ static int get_dist_table(struct Qdisc *sch, const struct rtattr *attr)
        return 0;
 }
 
-static int get_correlation(struct Qdisc *sch, const struct rtattr *attr)
+static int get_correlation(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
-       const struct tc_netem_corr *c = RTA_DATA(attr);
-
-       if (RTA_PAYLOAD(attr) != sizeof(*c))
-               return -EINVAL;
+       const struct tc_netem_corr *c = nla_data(attr);
 
        init_crandom(&q->delay_cor, c->delay_corr);
        init_crandom(&q->loss_cor, c->loss_corr);
@@ -377,43 +374,48 @@ static int get_correlation(struct Qdisc *sch, const struct rtattr *attr)
        return 0;
 }
 
-static int get_reorder(struct Qdisc *sch, const struct rtattr *attr)
+static int get_reorder(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
-       const struct tc_netem_reorder *r = RTA_DATA(attr);
-
-       if (RTA_PAYLOAD(attr) != sizeof(*r))
-               return -EINVAL;
+       const struct tc_netem_reorder *r = nla_data(attr);
 
        q->reorder = r->probability;
        init_crandom(&q->reorder_cor, r->correlation);
        return 0;
 }
 
-static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr)
+static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
-       const struct tc_netem_corrupt *r = RTA_DATA(attr);
-
-       if (RTA_PAYLOAD(attr) != sizeof(*r))
-               return -EINVAL;
+       const struct tc_netem_corrupt *r = nla_data(attr);
 
        q->corrupt = r->probability;
        init_crandom(&q->corrupt_cor, r->correlation);
        return 0;
 }
 
+static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
+       [TCA_NETEM_CORR]        = { .len = sizeof(struct tc_netem_corr) },
+       [TCA_NETEM_REORDER]     = { .len = sizeof(struct tc_netem_reorder) },
+       [TCA_NETEM_CORRUPT]     = { .len = sizeof(struct tc_netem_corrupt) },
+};
+
 /* Parse netlink message to set options */
-static int netem_change(struct Qdisc *sch, struct rtattr *opt)
+static int netem_change(struct Qdisc *sch, struct nlattr *opt)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
+       struct nlattr *tb[TCA_NETEM_MAX + 1];
        struct tc_netem_qopt *qopt;
        int ret;
 
-       if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(*qopt))
+       if (opt == NULL)
                return -EINVAL;
 
-       qopt = RTA_DATA(opt);
+       ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, netem_policy,
+                                     qopt, sizeof(*qopt));
+       if (ret < 0)
+               return ret;
+
        ret = set_fifo_limit(q->qdisc, qopt->limit);
        if (ret) {
                pr_debug("netem: can't set fifo limit\n");
@@ -434,39 +436,28 @@ static int netem_change(struct Qdisc *sch, struct rtattr *opt)
        if (q->gap)
                q->reorder = ~0;
 
-       /* Handle nested options after initial queue options.
-        * Should have put all options in nested format but too late now.
-        */
-       if (RTA_PAYLOAD(opt) > sizeof(*qopt)) {
-               struct rtattr *tb[TCA_NETEM_MAX];
-               if (rtattr_parse(tb, TCA_NETEM_MAX,
-                                RTA_DATA(opt) + sizeof(*qopt),
-                                RTA_PAYLOAD(opt) - sizeof(*qopt)))
-                       return -EINVAL;
-
-               if (tb[TCA_NETEM_CORR-1]) {
-                       ret = get_correlation(sch, tb[TCA_NETEM_CORR-1]);
-                       if (ret)
-                               return ret;
-               }
+       if (tb[TCA_NETEM_CORR]) {
+               ret = get_correlation(sch, tb[TCA_NETEM_CORR]);
+               if (ret)
+                       return ret;
+       }
 
-               if (tb[TCA_NETEM_DELAY_DIST-1]) {
-                       ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST-1]);
-                       if (ret)
-                               return ret;
-               }
+       if (tb[TCA_NETEM_DELAY_DIST]) {
+               ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]);
+               if (ret)
+                       return ret;
+       }
 
-               if (tb[TCA_NETEM_REORDER-1]) {
-                       ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
-                       if (ret)
-                               return ret;
-               }
+       if (tb[TCA_NETEM_REORDER]) {
+               ret = get_reorder(sch, tb[TCA_NETEM_REORDER]);
+               if (ret)
+                       return ret;
+       }
 
-               if (tb[TCA_NETEM_CORRUPT-1]) {
-                       ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]);
-                       if (ret)
-                               return ret;
-               }
+       if (tb[TCA_NETEM_CORRUPT]) {
+               ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]);
+               if (ret)
+                       return ret;
        }
 
        return 0;
@@ -515,13 +506,13 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
        return qdisc_reshape_fail(nskb, sch);
 }
 
-static int tfifo_init(struct Qdisc *sch, struct rtattr *opt)
+static int tfifo_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct fifo_sched_data *q = qdisc_priv(sch);
 
        if (opt) {
-               struct tc_fifo_qopt *ctl = RTA_DATA(opt);
-               if (RTA_PAYLOAD(opt) < sizeof(*ctl))
+               struct tc_fifo_qopt *ctl = nla_data(opt);
+               if (nla_len(opt) < sizeof(*ctl))
                        return -EINVAL;
 
                q->limit = ctl->limit;
@@ -537,14 +528,14 @@ static int tfifo_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct fifo_sched_data *q = qdisc_priv(sch);
        struct tc_fifo_qopt opt = { .limit = q->limit };
 
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        return -1;
 }
 
-static struct Qdisc_ops tfifo_qdisc_ops = {
+static struct Qdisc_ops tfifo_qdisc_ops __read_mostly = {
        .id             =       "tfifo",
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       tfifo_enqueue,
@@ -557,7 +548,7 @@ static struct Qdisc_ops tfifo_qdisc_ops = {
        .dump           =       tfifo_dump,
 };
 
-static int netem_init(struct Qdisc *sch, struct rtattr *opt)
+static int netem_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct netem_sched_data *q = qdisc_priv(sch);
        int ret;
@@ -595,7 +586,7 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        const struct netem_sched_data *q = qdisc_priv(sch);
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta = (struct rtattr *) b;
+       struct nlattr *nla = (struct nlattr *) b;
        struct tc_netem_qopt qopt;
        struct tc_netem_corr cor;
        struct tc_netem_reorder reorder;
@@ -607,26 +598,26 @@ static int netem_dump(struct Qdisc *sch, struct sk_buff *skb)
        qopt.loss = q->loss;
        qopt.gap = q->gap;
        qopt.duplicate = q->duplicate;
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(qopt), &qopt);
 
        cor.delay_corr = q->delay_cor.rho;
        cor.loss_corr = q->loss_cor.rho;
        cor.dup_corr = q->dup_cor.rho;
-       RTA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);
+       NLA_PUT(skb, TCA_NETEM_CORR, sizeof(cor), &cor);
 
        reorder.probability = q->reorder;
        reorder.correlation = q->reorder_cor.rho;
-       RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
+       NLA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
 
        corrupt.probability = q->corrupt;
        corrupt.correlation = q->corrupt_cor.rho;
-       RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+       NLA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
 
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       nla->nla_len = skb_tail_pointer(skb) - b;
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -678,7 +669,7 @@ static void netem_put(struct Qdisc *sch, unsigned long arg)
 }
 
 static int netem_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-                           struct rtattr **tca, unsigned long *arg)
+                           struct nlattr **tca, unsigned long *arg)
 {
        return -ENOSYS;
 }
@@ -705,7 +696,7 @@ static struct tcf_proto **netem_find_tcf(struct Qdisc *sch, unsigned long cl)
        return NULL;
 }
 
-static struct Qdisc_class_ops netem_class_ops = {
+static const struct Qdisc_class_ops netem_class_ops = {
        .graft          =       netem_graft,
        .leaf           =       netem_leaf,
        .get            =       netem_get,
@@ -717,7 +708,7 @@ static struct Qdisc_class_ops netem_class_ops = {
        .dump           =       netem_dump_class,
 };
 
-static struct Qdisc_ops netem_qdisc_ops = {
+static struct Qdisc_ops netem_qdisc_ops __read_mostly = {
        .id             =       "netem",
        .cl_ops         =       &netem_class_ops,
        .priv_size      =       sizeof(struct netem_sched_data),
index de894096e44252e6cc8da2ff548071a82b295685..4aa2b45dad0a80232ed1d1d1c2fbabf33b19ec8f 100644 (file)
@@ -224,16 +224,19 @@ prio_destroy(struct Qdisc* sch)
                qdisc_destroy(q->queues[prio]);
 }
 
-static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
+static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
        struct tc_prio_qopt *qopt;
-       struct rtattr *tb[TCA_PRIO_MAX];
+       struct nlattr *tb[TCA_PRIO_MAX + 1];
+       int err;
        int i;
 
-       if (rtattr_parse_nested_compat(tb, TCA_PRIO_MAX, opt, qopt,
-                                      sizeof(*qopt)))
-               return -EINVAL;
+       err = nla_parse_nested_compat(tb, TCA_PRIO_MAX, opt, NULL, qopt,
+                                     sizeof(*qopt));
+       if (err < 0)
+               return err;
+
        q->bands = qopt->bands;
        /* If we're multiqueue, make sure the number of incoming bands
         * matches the number of queues on the device we're associating with.
@@ -242,7 +245,7 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
         * only one that is enabled for multiqueue, since it's the only one
         * that interacts with the underlying device.
         */
-       q->mq = RTA_GET_FLAG(tb[TCA_PRIO_MQ - 1]);
+       q->mq = nla_get_flag(tb[TCA_PRIO_MQ]);
        if (q->mq) {
                if (sch->parent != TC_H_ROOT)
                        return -EINVAL;
@@ -296,7 +299,7 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
        return 0;
 }
 
-static int prio_init(struct Qdisc *sch, struct rtattr *opt)
+static int prio_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
        int i;
@@ -319,20 +322,24 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct prio_sched_data *q = qdisc_priv(sch);
        unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *nest;
+       struct nlattr *nest;
        struct tc_prio_qopt opt;
 
        opt.bands = q->bands;
        memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1);
 
-       nest = RTA_NEST_COMPAT(skb, TCA_OPTIONS, sizeof(opt), &opt);
-       if (q->mq)
-               RTA_PUT_FLAG(skb, TCA_PRIO_MQ);
-       RTA_NEST_COMPAT_END(skb, nest);
+       nest = nla_nest_compat_start(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       if (nest == NULL)
+               goto nla_put_failure;
+       if (q->mq) {
+               if (nla_put_flag(skb, TCA_PRIO_MQ) < 0)
+                       goto nla_put_failure;
+       }
+       nla_nest_compat_end(skb, nest);
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
@@ -392,7 +399,7 @@ static void prio_put(struct Qdisc *q, unsigned long cl)
        return;
 }
 
-static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct rtattr **tca, unsigned long *arg)
+static int prio_change(struct Qdisc *sch, u32 handle, u32 parent, struct nlattr **tca, unsigned long *arg)
 {
        unsigned long cl = *arg;
        struct prio_sched_data *q = qdisc_priv(sch);
@@ -468,7 +475,7 @@ static struct tcf_proto ** prio_find_tcf(struct Qdisc *sch, unsigned long cl)
        return &q->filter_list;
 }
 
-static struct Qdisc_class_ops prio_class_ops = {
+static const struct Qdisc_class_ops prio_class_ops = {
        .graft          =       prio_graft,
        .leaf           =       prio_leaf,
        .get            =       prio_get,
@@ -483,7 +490,7 @@ static struct Qdisc_class_ops prio_class_ops = {
        .dump_stats     =       prio_dump_class_stats,
 };
 
-static struct Qdisc_ops prio_qdisc_ops = {
+static struct Qdisc_ops prio_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &prio_class_ops,
        .id             =       "prio",
@@ -500,7 +507,7 @@ static struct Qdisc_ops prio_qdisc_ops = {
        .owner          =       THIS_MODULE,
 };
 
-static struct Qdisc_ops rr_qdisc_ops = {
+static struct Qdisc_ops rr_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &prio_class_ops,
        .id             =       "rr",
index 9b95fefb70f46b881c8cb21f57a461561db024c9..3dcd493f4f4a93b6d1e064f8214d83082cfee31b 100644 (file)
@@ -177,21 +177,21 @@ static void red_destroy(struct Qdisc *sch)
 static struct Qdisc *red_create_dflt(struct Qdisc *sch, u32 limit)
 {
        struct Qdisc *q;
-       struct rtattr *rta;
+       struct nlattr *nla;
        int ret;
 
        q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
                              TC_H_MAKE(sch->handle, 1));
        if (q) {
-               rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)),
+               nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)),
                              GFP_KERNEL);
-               if (rta) {
-                       rta->rta_type = RTM_NEWQDISC;
-                       rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
-                       ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
+               if (nla) {
+                       nla->nla_type = RTM_NEWQDISC;
+                       nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt));
+                       ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit;
 
-                       ret = q->ops->change(q, rta);
-                       kfree(rta);
+                       ret = q->ops->change(q, nla);
+                       kfree(nla);
 
                        if (ret == 0)
                                return q;
@@ -201,23 +201,31 @@ static struct Qdisc *red_create_dflt(struct Qdisc *sch, u32 limit)
        return NULL;
 }
 
-static int red_change(struct Qdisc *sch, struct rtattr *opt)
+static const struct nla_policy red_policy[TCA_RED_MAX + 1] = {
+       [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) },
+       [TCA_RED_STAB]  = { .len = RED_STAB_SIZE },
+};
+
+static int red_change(struct Qdisc *sch, struct nlattr *opt)
 {
        struct red_sched_data *q = qdisc_priv(sch);
-       struct rtattr *tb[TCA_RED_MAX];
+       struct nlattr *tb[TCA_RED_MAX + 1];
        struct tc_red_qopt *ctl;
        struct Qdisc *child = NULL;
+       int err;
 
-       if (opt == NULL || rtattr_parse_nested(tb, TCA_RED_MAX, opt))
+       if (opt == NULL)
                return -EINVAL;
 
-       if (tb[TCA_RED_PARMS-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) ||
-           tb[TCA_RED_STAB-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < RED_STAB_SIZE)
+       err = nla_parse_nested(tb, TCA_RED_MAX, opt, red_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_RED_PARMS] == NULL ||
+           tb[TCA_RED_STAB] == NULL)
                return -EINVAL;
 
-       ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
+       ctl = nla_data(tb[TCA_RED_PARMS]);
 
        if (ctl->limit > 0) {
                child = red_create_dflt(sch, ctl->limit);
@@ -235,7 +243,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
 
        red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
                                 ctl->Plog, ctl->Scell_log,
-                                RTA_DATA(tb[TCA_RED_STAB-1]));
+                                nla_data(tb[TCA_RED_STAB]));
 
        if (skb_queue_empty(&sch->q))
                red_end_of_idle_period(&q->parms);
@@ -244,7 +252,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
        return 0;
 }
 
-static int red_init(struct Qdisc* sch, struct rtattr *opt)
+static int red_init(struct Qdisc* sch, struct nlattr *opt)
 {
        struct red_sched_data *q = qdisc_priv(sch);
 
@@ -255,7 +263,7 @@ static int red_init(struct Qdisc* sch, struct rtattr *opt)
 static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct red_sched_data *q = qdisc_priv(sch);
-       struct rtattr *opts = NULL;
+       struct nlattr *opts = NULL;
        struct tc_red_qopt opt = {
                .limit          = q->limit,
                .flags          = q->flags,
@@ -266,12 +274,14 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
                .Scell_log      = q->parms.Scell_log,
        };
 
-       opts = RTA_NEST(skb, TCA_OPTIONS);
-       RTA_PUT(skb, TCA_RED_PARMS, sizeof(opt), &opt);
-       return RTA_NEST_END(skb, opts);
+       opts = nla_nest_start(skb, TCA_OPTIONS);
+       if (opts == NULL)
+               goto nla_put_failure;
+       NLA_PUT(skb, TCA_RED_PARMS, sizeof(opt), &opt);
+       return nla_nest_end(skb, opts);
 
-rtattr_failure:
-       return RTA_NEST_CANCEL(skb, opts);
+nla_put_failure:
+       return nla_nest_cancel(skb, opts);
 }
 
 static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
@@ -332,7 +342,7 @@ static void red_put(struct Qdisc *sch, unsigned long arg)
 }
 
 static int red_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-                           struct rtattr **tca, unsigned long *arg)
+                           struct nlattr **tca, unsigned long *arg)
 {
        return -ENOSYS;
 }
@@ -359,7 +369,7 @@ static struct tcf_proto **red_find_tcf(struct Qdisc *sch, unsigned long cl)
        return NULL;
 }
 
-static struct Qdisc_class_ops red_class_ops = {
+static const struct Qdisc_class_ops red_class_ops = {
        .graft          =       red_graft,
        .leaf           =       red_leaf,
        .get            =       red_get,
@@ -371,7 +381,7 @@ static struct Qdisc_class_ops red_class_ops = {
        .dump           =       red_dump_class,
 };
 
-static struct Qdisc_ops red_qdisc_ops = {
+static struct Qdisc_ops red_qdisc_ops __read_mostly = {
        .id             =       "red",
        .priv_size      =       sizeof(struct red_sched_data),
        .cl_ops         =       &red_class_ops,
index b542c875e154411cfaaf3d78abe443d9e5e4931d..91af539ab6e69f972eb3edcea0aab2fdee6c516e 100644 (file)
@@ -122,7 +122,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
        {
                const struct iphdr *iph = ip_hdr(skb);
                h = iph->daddr;
-               h2 = iph->saddr^iph->protocol;
+               h2 = iph->saddr ^ iph->protocol;
                if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
                    (iph->protocol == IPPROTO_TCP ||
                     iph->protocol == IPPROTO_UDP ||
@@ -137,7 +137,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
        {
                struct ipv6hdr *iph = ipv6_hdr(skb);
                h = iph->daddr.s6_addr32[3];
-               h2 = iph->saddr.s6_addr32[3]^iph->nexthdr;
+               h2 = iph->saddr.s6_addr32[3] ^ iph->nexthdr;
                if (iph->nexthdr == IPPROTO_TCP ||
                    iph->nexthdr == IPPROTO_UDP ||
                    iph->nexthdr == IPPROTO_UDPLITE ||
@@ -148,9 +148,10 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
                break;
        }
        default:
-               h = (u32)(unsigned long)skb->dst^skb->protocol;
-               h2 = (u32)(unsigned long)skb->sk;
+               h = (unsigned long)skb->dst ^ skb->protocol;
+               h2 = (unsigned long)skb->sk;
        }
+
        return sfq_fold_hash(q, h, h2);
 }
 
@@ -208,7 +209,7 @@ static unsigned int sfq_drop(struct Qdisc *sch)
           drop a packet from it */
 
        if (d > 1) {
-               sfq_index x = q->dep[d+SFQ_DEPTH].next;
+               sfq_index x = q->dep[d + SFQ_DEPTH].next;
                skb = q->qs[x].prev;
                len = skb->len;
                __skb_unlink(skb, &q->qs[x]);
@@ -241,7 +242,7 @@ static unsigned int sfq_drop(struct Qdisc *sch)
 }
 
 static int
-sfq_enqueue(struct sk_buff *skb, struct Qdiscsch)
+sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned hash = sfq_hash(q, skb);
@@ -252,6 +253,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
                q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
                q->hash[x] = hash;
        }
+
        /* If selected queue has length q->limit, this means that
         * all another queues are empty and that we do simple tail drop,
         * i.e. drop _this_ packet.
@@ -284,7 +286,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 }
 
 static int
-sfq_requeue(struct sk_buff *skb, struct Qdiscsch)
+sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        unsigned hash = sfq_hash(q, skb);
@@ -295,6 +297,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                q->ht[hash] = x = q->dep[SFQ_DEPTH].next;
                q->hash[x] = hash;
        }
+
        sch->qstats.backlog += skb->len;
        __skb_queue_head(&q->qs[x], skb);
        /* If selected queue has length q->limit+1, this means that
@@ -310,6 +313,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                kfree_skb(skb);
                return NET_XMIT_CN;
        }
+
        sfq_inc(q, x);
        if (q->qs[x].qlen == 1) {               /* The flow is new */
                if (q->tail == SFQ_DEPTH) {     /* It is the first flow */
@@ -322,6 +326,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                        q->tail = x;
                }
        }
+
        if (++sch->q.qlen <= q->limit) {
                sch->qstats.requeues++;
                return 0;
@@ -336,7 +341,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
 
 
 static struct sk_buff *
-sfq_dequeue(struct Qdiscsch)
+sfq_dequeue(struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        struct sk_buff *skb;
@@ -373,7 +378,7 @@ sfq_dequeue(struct Qdisc* sch)
 }
 
 static void
-sfq_reset(struct Qdiscsch)
+sfq_reset(struct Qdisc *sch)
 {
        struct sk_buff *skb;
 
@@ -383,27 +388,27 @@ sfq_reset(struct Qdisc* sch)
 
 static void sfq_perturbation(unsigned long arg)
 {
-       struct Qdisc *sch = (struct Qdisc*)arg;
+       struct Qdisc *sch = (struct Qdisc *)arg;
        struct sfq_sched_data *q = qdisc_priv(sch);
 
-       get_random_bytes(&q->perturbation, 4);
+       q->perturbation = net_random();
 
        if (q->perturb_period)
                mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
 }
 
-static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
+static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
-       struct tc_sfq_qopt *ctl = RTA_DATA(opt);
+       struct tc_sfq_qopt *ctl = nla_data(opt);
        unsigned int qlen;
 
-       if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
+       if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
                return -EINVAL;
 
        sch_tree_lock(sch);
        q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
-       q->perturb_period = ctl->perturb_period*HZ;
+       q->perturb_period = ctl->perturb_period * HZ;
        if (ctl->limit)
                q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 1);
 
@@ -415,41 +420,44 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
        del_timer(&q->perturb_timer);
        if (q->perturb_period) {
                mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
-               get_random_bytes(&q->perturbation, 4);
+               q->perturbation = net_random();
        }
        sch_tree_unlock(sch);
        return 0;
 }
 
-static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
+static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
        int i;
 
-       init_timer(&q->perturb_timer);
-       q->perturb_timer.data = (unsigned long)sch;
        q->perturb_timer.function = sfq_perturbation;
+       q->perturb_timer.data = (unsigned long)sch;;
+       init_timer_deferrable(&q->perturb_timer);
 
-       for (i=0; i<SFQ_HASH_DIVISOR; i++)
+       for (i = 0; i < SFQ_HASH_DIVISOR; i++)
                q->ht[i] = SFQ_DEPTH;
-       for (i=0; i<SFQ_DEPTH; i++) {
+
+       for (i = 0; i < SFQ_DEPTH; i++) {
                skb_queue_head_init(&q->qs[i]);
-               q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH;
-               q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH;
+               q->dep[i + SFQ_DEPTH].next = i + SFQ_DEPTH;
+               q->dep[i + SFQ_DEPTH].prev = i + SFQ_DEPTH;
        }
+
        q->limit = SFQ_DEPTH - 1;
        q->max_depth = 0;
        q->tail = SFQ_DEPTH;
        if (opt == NULL) {
                q->quantum = psched_mtu(sch->dev);
                q->perturb_period = 0;
-               get_random_bytes(&q->perturbation, 4);
+               q->perturbation = net_random();
        } else {
                int err = sfq_change(sch, opt);
                if (err)
                        return err;
        }
-       for (i=0; i<SFQ_DEPTH; i++)
+
+       for (i = 0; i < SFQ_DEPTH; i++)
                sfq_link(q, i);
        return 0;
 }
@@ -467,22 +475,22 @@ static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
        struct tc_sfq_qopt opt;
 
        opt.quantum = q->quantum;
-       opt.perturb_period = q->perturb_period/HZ;
+       opt.perturb_period = q->perturb_period / HZ;
 
        opt.limit = q->limit;
        opt.divisor = SFQ_HASH_DIVISOR;
        opt.flows = q->limit;
 
-       RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+       NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
 
        return skb->len;
 
-rtattr_failure:
+nla_put_failure:
        nlmsg_trim(skb, b);
        return -1;
 }
 
-static struct Qdisc_ops sfq_qdisc_ops = {
+static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       NULL,
        .id             =       "sfq",
index b0d81098b0eee58acff75961491975ad45d2bb65..0b7d78f59d8cb727c1ac0506a5cbdf8cd36f153f 100644 (file)
@@ -245,20 +245,21 @@ static void tbf_reset(struct Qdisc* sch)
 static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
 {
        struct Qdisc *q;
-       struct rtattr *rta;
+       struct nlattr *nla;
        int ret;
 
        q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
                              TC_H_MAKE(sch->handle, 1));
        if (q) {
-               rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
-               if (rta) {
-                       rta->rta_type = RTM_NEWQDISC;
-                       rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
-                       ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
+               nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)),
+                             GFP_KERNEL);
+               if (nla) {
+                       nla->nla_type = RTM_NEWQDISC;
+                       nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt));
+                       ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit;
 
-                       ret = q->ops->change(q, rta);
-                       kfree(rta);
+                       ret = q->ops->change(q, nla);
+                       kfree(nla);
 
                        if (ret == 0)
                                return q;
@@ -269,30 +270,39 @@ static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
        return NULL;
 }
 
-static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
+static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = {
+       [TCA_TBF_PARMS] = { .len = sizeof(struct tc_tbf_qopt) },
+       [TCA_TBF_RTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+       [TCA_TBF_PTAB]  = { .type = NLA_BINARY, .len = TC_RTAB_SIZE },
+};
+
+static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
 {
-       int err = -EINVAL;
+       int err;
        struct tbf_sched_data *q = qdisc_priv(sch);
-       struct rtattr *tb[TCA_TBF_PTAB];
+       struct nlattr *tb[TCA_TBF_PTAB + 1];
        struct tc_tbf_qopt *qopt;
        struct qdisc_rate_table *rtab = NULL;
        struct qdisc_rate_table *ptab = NULL;
        struct Qdisc *child = NULL;
        int max_size,n;
 
-       if (rtattr_parse_nested(tb, TCA_TBF_PTAB, opt) ||
-           tb[TCA_TBF_PARMS-1] == NULL ||
-           RTA_PAYLOAD(tb[TCA_TBF_PARMS-1]) < sizeof(*qopt))
+       err = nla_parse_nested(tb, TCA_TBF_PTAB, opt, tbf_policy);
+       if (err < 0)
+               return err;
+
+       err = -EINVAL;
+       if (tb[TCA_TBF_PARMS] == NULL)
                goto done;
 
-       qopt = RTA_DATA(tb[TCA_TBF_PARMS-1]);
-       rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB-1]);
+       qopt = nla_data(tb[TCA_TBF_PARMS]);
+       rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
        if (rtab == NULL)
                goto done;
 
        if (qopt->peakrate.rate) {
                if (qopt->peakrate.rate > qopt->rate.rate)
-                       ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB-1]);
+                       ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
                if (ptab == NULL)
                        goto done;
        }
@@ -339,7 +349,7 @@ done:
        return err;
 }
 
-static int tbf_init(struct Qdisc* sch, struct rtattr *opt)
+static int tbf_init(struct Qdisc* sch, struct nlattr *opt)
 {
        struct tbf_sched_data *q = qdisc_priv(sch);
 
@@ -370,12 +380,12 @@ static void tbf_destroy(struct Qdisc *sch)
 static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
        struct tbf_sched_data *q = qdisc_priv(sch);
-       unsigned char *b = skb_tail_pointer(skb);
-       struct rtattr *rta;
+       struct nlattr *nest;
        struct tc_tbf_qopt opt;
 
-       rta = (struct rtattr*)b;
-       RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+       nest = nla_nest_start(skb, TCA_OPTIONS);
+       if (nest == NULL)
+               goto nla_put_failure;
 
        opt.limit = q->limit;
        opt.rate = q->R_tab->rate;
@@ -385,13 +395,13 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb)
                memset(&opt.peakrate, 0, sizeof(opt.peakrate));
        opt.mtu = q->mtu;
        opt.buffer = q->buffer;
-       RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt);
-       rta->rta_len = skb_tail_pointer(skb) - b;
+       NLA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt);
 
+       nla_nest_end(skb, nest);
        return skb->len;
 
-rtattr_failure:
-       nlmsg_trim(skb, b);
+nla_put_failure:
+       nla_nest_cancel(skb, nest);
        return -1;
 }
 
@@ -442,7 +452,7 @@ static void tbf_put(struct Qdisc *sch, unsigned long arg)
 }
 
 static int tbf_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-                           struct rtattr **tca, unsigned long *arg)
+                           struct nlattr **tca, unsigned long *arg)
 {
        return -ENOSYS;
 }
@@ -469,7 +479,7 @@ static struct tcf_proto **tbf_find_tcf(struct Qdisc *sch, unsigned long cl)
        return NULL;
 }
 
-static struct Qdisc_class_ops tbf_class_ops =
+static const struct Qdisc_class_ops tbf_class_ops =
 {
        .graft          =       tbf_graft,
        .leaf           =       tbf_leaf,
@@ -482,7 +492,7 @@ static struct Qdisc_class_ops tbf_class_ops =
        .dump           =       tbf_dump_class,
 };
 
-static struct Qdisc_ops tbf_qdisc_ops = {
+static struct Qdisc_ops tbf_qdisc_ops __read_mostly = {
        .next           =       NULL,
        .cl_ops         =       &tbf_class_ops,
        .id             =       "tbf",
index c0ed06d4a5046516c1e67d2b8f15df2aca07ae8b..1411c7b1fbdc4de0f7103cfb559a78369a4195cc 100644 (file)
@@ -168,7 +168,7 @@ teql_destroy(struct Qdisc* sch)
        }
 }
 
-static int teql_qdisc_init(struct Qdisc *sch, struct rtattr *opt)
+static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct net_device *dev = sch->dev;
        struct teql_master *m = (struct teql_master*)sch->ops;
index 5390bc792159c7a4fdc190308f74a0c2fe9add62..0b79f869c4eafcbf94a5210cc23aab9a0ac7e36a 100644 (file)
@@ -10,6 +10,7 @@ menuconfig IP_SCTP
        select CRYPTO_HMAC
        select CRYPTO_SHA1
        select CRYPTO_MD5 if SCTP_HMAC_MD5
+       select LIBCRC32C
        ---help---
          Stream Control Transmission Protocol
 
index 1da7204d9b42c5bd9eec93304642a8c85221b416..f5356b9d5ee361c11f9038c0627aeb6b3ad8f1cd 100644 (file)
@@ -9,7 +9,7 @@ sctp-y := sm_statetable.o sm_statefuns.o sm_sideeffect.o \
          transport.o chunk.o sm_make_chunk.o ulpevent.o \
          inqueue.o outqueue.o ulpqueue.o command.o \
          tsnmap.o bind_addr.o socket.o primitive.o \
-         output.o input.o debug.o ssnmap.o proc.o crc32c.o \
+         output.o input.o debug.o ssnmap.o proc.o \
          auth.o
 
 sctp-$(CONFIG_SCTP_DBG_OBJCNT) += objcnt.o
index 013e3d3ab0f1a6217868785c5d160b0acb0eacb8..a016e78061f4399cd4ce19f9276905de286baf89 100644 (file)
@@ -61,6 +61,7 @@
 
 /* Forward declarations for internal functions. */
 static void sctp_assoc_bh_rcv(struct work_struct *work);
+static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc);
 
 
 /* 1st Level Abstractions. */
@@ -167,11 +168,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
                sp->autoclose * HZ;
 
        /* Initilizes the timers */
-       for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) {
-               init_timer(&asoc->timers[i]);
-               asoc->timers[i].function = sctp_timer_events[i];
-               asoc->timers[i].data = (unsigned long) asoc;
-       }
+       for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i)
+               setup_timer(&asoc->timers[i], sctp_timer_events[i],
+                               (unsigned long)asoc);
 
        /* Pull default initialization values from the sock options.
         * Note: This assumes that the values have already been
@@ -244,6 +243,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
        asoc->addip_serial = asoc->c.initial_tsn;
 
        INIT_LIST_HEAD(&asoc->addip_chunk_list);
+       INIT_LIST_HEAD(&asoc->asconf_ack_list);
 
        /* Make an empty list of remote transport addresses.  */
        INIT_LIST_HEAD(&asoc->peer.transport_addr_list);
@@ -433,8 +433,7 @@ void sctp_association_free(struct sctp_association *asoc)
        asoc->peer.transport_count = 0;
 
        /* Free any cached ASCONF_ACK chunk. */
-       if (asoc->addip_last_asconf_ack)
-               sctp_chunk_free(asoc->addip_last_asconf_ack);
+       sctp_assoc_free_asconf_acks(asoc);
 
        /* Free any cached ASCONF chunk. */
        if (asoc->addip_last_asconf)
@@ -732,6 +731,23 @@ struct sctp_transport *sctp_assoc_lookup_paddr(
        return NULL;
 }
 
+/* Remove all transports except a give one */
+void sctp_assoc_del_nonprimary_peers(struct sctp_association *asoc,
+                                    struct sctp_transport *primary)
+{
+       struct sctp_transport   *temp;
+       struct sctp_transport   *t;
+
+       list_for_each_entry_safe(t, temp, &asoc->peer.transport_addr_list,
+                                transports) {
+               /* if the current transport is not the primary one, delete it */
+               if (t != primary)
+                       sctp_assoc_rm_peer(asoc, t);
+       }
+
+       return;
+}
+
 /* Engage in transport control operations.
  * Mark the transport up or down and send a notification to the user.
  * Select and update the new active and retran paths.
@@ -1470,3 +1486,56 @@ retry:
        asoc->assoc_id = (sctp_assoc_t) assoc_id;
        return error;
 }
+
+/* Free asconf_ack cache */
+static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc)
+{
+       struct sctp_chunk *ack;
+       struct sctp_chunk *tmp;
+
+       list_for_each_entry_safe(ack, tmp, &asoc->asconf_ack_list,
+                               transmitted_list) {
+               list_del_init(&ack->transmitted_list);
+               sctp_chunk_free(ack);
+       }
+}
+
+/* Clean up the ASCONF_ACK queue */
+void sctp_assoc_clean_asconf_ack_cache(const struct sctp_association *asoc)
+{
+       struct sctp_chunk *ack;
+       struct sctp_chunk *tmp;
+
+       /* We can remove all the entries from the queue upto
+        * the "Peer-Sequence-Number".
+        */
+       list_for_each_entry_safe(ack, tmp, &asoc->asconf_ack_list,
+                               transmitted_list) {
+               if (ack->subh.addip_hdr->serial ==
+                               htonl(asoc->peer.addip_serial))
+                       break;
+
+               list_del_init(&ack->transmitted_list);
+               sctp_chunk_free(ack);
+       }
+}
+
+/* Find the ASCONF_ACK whose serial number matches ASCONF */
+struct sctp_chunk *sctp_assoc_lookup_asconf_ack(
+                                       const struct sctp_association *asoc,
+                                       __be32 serial)
+{
+       struct sctp_chunk *ack = NULL;
+
+       /* Walk through the list of cached ASCONF-ACKs and find the
+        * ack chunk whose serial number matches that of the request.
+        */
+       list_for_each_entry(ack, &asoc->asconf_ack_list, transmitted_list) {
+               if (ack->subh.addip_hdr->serial == serial) {
+                       sctp_chunk_hold(ack);
+                       break;
+               }
+       }
+
+       return ack;
+}
index 6a7d01091f0c5533345a162db38ef61e3bab228b..13fbfb449a5544347d824a5d85408adc3d78b96d 100644 (file)
@@ -171,7 +171,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp)
 
 /* Add an address to the bind address list in the SCTP_bind_addr structure. */
 int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
-                      __u8 use_as_src, gfp_t gfp)
+                      __u8 addr_state, gfp_t gfp)
 {
        struct sctp_sockaddr_entry *addr;
 
@@ -188,7 +188,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
        if (!addr->a.v4.sin_port)
                addr->a.v4.sin_port = htons(bp->port);
 
-       addr->use_as_src = use_as_src;
+       addr->state = addr_state;
        addr->valid = 1;
 
        INIT_LIST_HEAD(&addr->list);
@@ -312,7 +312,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
                }
 
                af->from_addr_param(&addr, rawaddr, htons(port), 0);
-               retval = sctp_add_bind_addr(bp, &addr, 1, gfp);
+               retval = sctp_add_bind_addr(bp, &addr, SCTP_ADDR_SRC, gfp);
                if (retval) {
                        /* Can't finish building the list, clean up. */
                        sctp_bind_addr_clean(bp);
@@ -353,6 +353,32 @@ int sctp_bind_addr_match(struct sctp_bind_addr *bp,
        return match;
 }
 
+/* Get the state of the entry in the bind_addr_list */
+int sctp_bind_addr_state(const struct sctp_bind_addr *bp,
+                        const union sctp_addr *addr)
+{
+       struct sctp_sockaddr_entry *laddr;
+       struct sctp_af *af;
+       int state = -1;
+
+       af = sctp_get_af_specific(addr->sa.sa_family);
+       if (unlikely(!af))
+               return state;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(laddr, &bp->address_list, list) {
+               if (!laddr->valid)
+                       continue;
+               if (af->cmp_addr(&laddr->a, addr)) {
+                       state = laddr->state;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return state;
+}
+
 /* Find the first address in the bind address list that is not present in
  * the addrs packed array.
  */
@@ -411,7 +437,8 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
                    (((AF_INET6 == addr->sa.sa_family) &&
                      (flags & SCTP_ADDR6_ALLOWED) &&
                      (flags & SCTP_ADDR6_PEERSUPP))))
-                       error = sctp_add_bind_addr(dest, addr, 1, gfp);
+                       error = sctp_add_bind_addr(dest, addr, SCTP_ADDR_SRC,
+                                                   gfp);
        }
 
        return error;
diff --git a/net/sctp/crc32c.c b/net/sctp/crc32c.c
deleted file mode 100644 (file)
index 181edab..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/* SCTP kernel reference Implementation
- * Copyright (c) 1999-2001 Motorola, Inc.
- * Copyright (c) 2001-2003 International Business Machines, Corp.
- *
- * This file is part of the SCTP kernel reference Implementation
- *
- * SCTP Checksum functions
- *
- * The SCTP reference implementation 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, or (at your option)
- * any later version.
- *
- * The SCTP reference implementation 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 GNU CC; see the file COPYING.  If not, write to
- * the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Please send any bug reports or fixes you make to the
- * email address(es):
- *    lksctp developers <lksctp-developers@lists.sourceforge.net>
- *
- * Or submit a bug report through the following website:
- *    http://www.sf.net/projects/lksctp
- *
- * Written or modified by:
- *    Dinakaran Joseph
- *    Jon Grimm <jgrimm@us.ibm.com>
- *    Sridhar Samudrala <sri@us.ibm.com>
- *
- * Any bugs reported given to us we will try to fix... any fixes shared will
- * be incorporated into the next SCTP release.
- */
-
-/* The following code has been taken directly from
- * draft-ietf-tsvwg-sctpcsum-03.txt
- *
- * The code has now been modified specifically for SCTP knowledge.
- */
-
-#include <linux/types.h>
-#include <net/sctp/sctp.h>
-
-#define CRC32C_POLY 0x1EDC6F41
-#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-/* Copyright 2001, D. Otis.  Use this program, code or tables    */
-/* extracted from it, as desired without restriction.            */
-/*                                                               */
-/* 32 Bit Reflected CRC table generation for SCTP.               */
-/* To accommodate serial byte data being shifted out least       */
-/* significant bit first, the table's 32 bit words are reflected */
-/* which flips both byte and bit MS and LS positions.  The CRC   */
-/* is calculated MS bits first from the perspective of the serial*/
-/* stream.  The x^32 term is implied and the x^0 term may also   */
-/* be shown as +1.  The polynomial code used is 0x1EDC6F41.      */
-/* Castagnoli93                                                  */
-/* x^32+x^28+x^27+x^26+x^25+x^23+x^22+x^20+x^19+x^18+x^14+x^13+  */
-/* x^11+x^10+x^9+x^8+x^6+x^0                                     */
-/* Guy Castagnoli Stefan Braeuer and Martin Herrman              */
-/* "Optimization of Cyclic Redundancy-Check Codes                */
-/* with 24 and 32 Parity Bits",                                  */
-/* IEEE Transactions on Communications, Vol.41, No.6, June 1993  */
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-static const __u32 crc_c[256] = {
-       0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-       0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-       0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-       0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-       0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-       0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-       0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-       0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-       0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-       0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-       0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-       0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-       0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-       0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-       0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-       0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-       0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-       0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-       0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-       0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-       0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-       0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-       0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-       0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-       0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-       0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-       0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-       0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-       0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-       0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-       0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-       0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-       0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-       0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-       0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-       0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-       0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-       0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-       0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-       0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-       0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-       0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-       0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-       0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-       0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-       0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-       0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-       0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-       0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-       0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-       0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-       0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-       0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-       0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-       0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-       0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-       0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-       0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-       0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-       0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-       0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-       0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-       0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-       0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
-};
-
-__u32 sctp_start_cksum(__u8 *buffer, __u16 length)
-{
-       __u32 crc32 = ~(__u32) 0;
-       __u32 i;
-
-       /* Optimize this routine to be SCTP specific, knowing how
-        * to skip the checksum field of the SCTP header.
-        */
-
-       /* Calculate CRC up to the checksum. */
-       for (i = 0; i < (sizeof(struct sctphdr) - sizeof(__u32)); i++)
-               CRC32C(crc32, buffer[i]);
-
-       /* Skip checksum field of the header. */
-       for (i = 0; i < sizeof(__u32); i++)
-               CRC32C(crc32, 0);
-
-       /* Calculate the rest of the CRC. */
-       for (i = sizeof(struct sctphdr); i < length ; i++)
-               CRC32C(crc32, buffer[i]);
-
-       return crc32;
-}
-
-__u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
-{
-       __u32 i;
-
-       for (i = 0; i < length ; i++)
-               CRC32C(crc32, buffer[i]);
-
-       return crc32;
-}
-
-#if 0
-__u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32)
-{
-       __u32 i;
-       __u32 *_to = (__u32 *)to;
-       __u32 *_from = (__u32 *)from;
-
-       for (i = 0; i < (length/4); i++) {
-               _to[i] = _from[i];
-               CRC32C(crc32, from[i*4]);
-               CRC32C(crc32, from[i*4+1]);
-               CRC32C(crc32, from[i*4+2]);
-               CRC32C(crc32, from[i*4+3]);
-       }
-
-       return crc32;
-}
-#endif  /*  0  */
-
-__u32 sctp_end_cksum(__u32 crc32)
-{
-       __u32 result;
-       __u8 byte0, byte1, byte2, byte3;
-
-       result = ~crc32;
-
-       /*  result  now holds the negated polynomial remainder;
-        *  since the table and algorithm is "reflected" [williams95].
-        *  That is,  result has the same value as if we mapped the message
-        *  to a polyomial, computed the host-bit-order polynomial
-        *  remainder, performed final negation, then did an end-for-end
-        *  bit-reversal.
-        *  Note that a 32-bit bit-reversal is identical to four inplace
-        *  8-bit reversals followed by an end-for-end byteswap.
-        *  In other words, the bytes of each bit are in the right order,
-        *  but the bytes have been byteswapped.  So we now do an explicit
-        *  byteswap.  On a little-endian machine, this byteswap and
-        *  the final ntohl cancel out and could be elided.
-        */
-       byte0 = result & 0xff;
-       byte1 = (result>>8) & 0xff;
-       byte2 = (result>>16) & 0xff;
-       byte3 = (result>>24) & 0xff;
-
-       crc32 = ((byte0 << 24) |
-                (byte1 << 16) |
-                (byte2 << 8)  |
-                byte3);
-       return crc32;
-}
index 91ae463b079b13bf62c89fa7d8e7529e7af85685..d695f710fc77d0e986f599674873c6e6975603bd 100644 (file)
@@ -60,6 +60,7 @@
 #include <net/xfrm.h>
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
+#include <net/sctp/checksum.h>
 
 /* Forward declarations for internal helpers. */
 static int sctp_rcv_ootb(struct sk_buff *);
@@ -890,14 +891,6 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
 
        ch = (sctp_chunkhdr_t *) skb->data;
 
-       /* The code below will attempt to walk the chunk and extract
-        * parameter information.  Before we do that, we need to verify
-        * that the chunk length doesn't cause overflow.  Otherwise, we'll
-        * walk off the end.
-        */
-       if (WORD_ROUND(ntohs(ch->length)) > skb->len)
-               return NULL;
-
        /*
         * This code will NOT touch anything inside the chunk--it is
         * strictly READ-ONLY.
@@ -934,6 +927,44 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
        return NULL;
 }
 
+/* ADD-IP, Section 5.2
+ * When an endpoint receives an ASCONF Chunk from the remote peer
+ * special procedures may be needed to identify the association the
+ * ASCONF Chunk is associated with. To properly find the association
+ * the following procedures SHOULD be followed:
+ *
+ * D2) If the association is not found, use the address found in the
+ * Address Parameter TLV combined with the port number found in the
+ * SCTP common header. If found proceed to rule D4.
+ *
+ * D2-ext) If more than one ASCONF Chunks are packed together, use the
+ * address found in the ASCONF Address Parameter TLV of each of the
+ * subsequent ASCONF Chunks. If found, proceed to rule D4.
+ */
+static struct sctp_association *__sctp_rcv_asconf_lookup(
+                                       sctp_chunkhdr_t *ch,
+                                       const union sctp_addr *laddr,
+                                       __be32 peer_port,
+                                       struct sctp_transport **transportp)
+{
+       sctp_addip_chunk_t *asconf = (struct sctp_addip_chunk *)ch;
+       struct sctp_af *af;
+       union sctp_addr_param *param;
+       union sctp_addr paddr;
+
+       /* Skip over the ADDIP header and find the Address parameter */
+       param = (union sctp_addr_param *)(asconf + 1);
+
+       af = sctp_get_af_specific(param_type2af(param->v4.param_hdr.type));
+       if (unlikely(!af))
+               return NULL;
+
+       af->from_addr_param(&paddr, param, peer_port, 0);
+
+       return __sctp_lookup_association(laddr, &paddr, transportp);
+}
+
+
 /* SCTP-AUTH, Section 6.3:
 *    If the receiver does not find a STCB for a packet containing an AUTH
 *    chunk as the first chunk and not a COOKIE-ECHO chunk as the second
@@ -942,20 +973,64 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
 *
 * This means that any chunks that can help us identify the association need
 * to be looked at to find this assocation.
-*
-* TODO: The only chunk currently defined that can do that is ASCONF, but we
-* don't support that functionality yet.
 */
-static struct sctp_association *__sctp_rcv_auth_lookup(struct sk_buff *skb,
-                                     const union sctp_addr *paddr,
+static struct sctp_association *__sctp_rcv_walk_lookup(struct sk_buff *skb,
                                      const union sctp_addr *laddr,
                                      struct sctp_transport **transportp)
 {
-       /* XXX - walk through the chunks looking for something that can
-        * help us find the association.  INIT, and INIT-ACK are not permitted.
-        * That leaves ASCONF, but we don't support that yet.
+       struct sctp_association *asoc = NULL;
+       sctp_chunkhdr_t *ch;
+       int have_auth = 0;
+       unsigned int chunk_num = 1;
+       __u8 *ch_end;
+
+       /* Walk through the chunks looking for AUTH or ASCONF chunks
+        * to help us find the association.
         */
-       return NULL;
+       ch = (sctp_chunkhdr_t *) skb->data;
+       do {
+               /* Break out if chunk length is less then minimal. */
+               if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
+                       break;
+
+               ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+               if (ch_end > skb_tail_pointer(skb))
+                       break;
+
+               switch(ch->type) {
+                   case SCTP_CID_AUTH:
+                           have_auth = chunk_num;
+                           break;
+
+                   case SCTP_CID_COOKIE_ECHO:
+                           /* If a packet arrives containing an AUTH chunk as
+                            * a first chunk, a COOKIE-ECHO chunk as the second
+                            * chunk, and possibly more chunks after them, and
+                            * the receiver does not have an STCB for that
+                            * packet, then authentication is based on
+                            * the contents of the COOKIE- ECHO chunk.
+                            */
+                           if (have_auth == 1 && chunk_num == 2)
+                                   return NULL;
+                           break;
+
+                   case SCTP_CID_ASCONF:
+                           if (have_auth || sctp_addip_noauth)
+                                   asoc = __sctp_rcv_asconf_lookup(ch, laddr,
+                                                       sctp_hdr(skb)->source,
+                                                       transportp);
+                   default:
+                           break;
+               }
+
+               if (asoc)
+                       break;
+
+               ch = (sctp_chunkhdr_t *) ch_end;
+               chunk_num++;
+       } while (ch_end < skb_tail_pointer(skb));
+
+       return asoc;
 }
 
 /*
@@ -965,7 +1040,6 @@ static struct sctp_association *__sctp_rcv_auth_lookup(struct sk_buff *skb,
  * chunks.
  */
 static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
-                                     const union sctp_addr *paddr,
                                      const union sctp_addr *laddr,
                                      struct sctp_transport **transportp)
 {
@@ -973,6 +1047,14 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
 
        ch = (sctp_chunkhdr_t *) skb->data;
 
+       /* The code below will attempt to walk the chunk and extract
+        * parameter information.  Before we do that, we need to verify
+        * that the chunk length doesn't cause overflow.  Otherwise, we'll
+        * walk off the end.
+        */
+       if (WORD_ROUND(ntohs(ch->length)) > skb->len)
+               return NULL;
+
        /* If this is INIT/INIT-ACK look inside the chunk too. */
        switch (ch->type) {
        case SCTP_CID_INIT:
@@ -980,11 +1062,12 @@ static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
                return __sctp_rcv_init_lookup(skb, laddr, transportp);
                break;
 
-       case SCTP_CID_AUTH:
-               return __sctp_rcv_auth_lookup(skb, paddr, laddr, transportp);
+       default:
+               return __sctp_rcv_walk_lookup(skb, laddr, transportp);
                break;
        }
 
+
        return NULL;
 }
 
@@ -1003,7 +1086,7 @@ static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
         * parameters within the INIT or INIT-ACK.
         */
        if (!asoc)
-               asoc = __sctp_rcv_lookup_harder(skb, paddr, laddr, transportp);
+               asoc = __sctp_rcv_lookup_harder(skb, laddr, transportp);
 
        return asoc;
 }
index 7f31ff638bc63fd521bd84ec4ca901451e832fe5..74f106a7a7e9d2fc0be78c2c6c46cd50400e4808 100644 (file)
@@ -330,7 +330,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc,
        list_for_each_entry_rcu(laddr, &bp->address_list, list) {
                if (!laddr->valid)
                        continue;
-               if ((laddr->use_as_src) &&
+               if ((laddr->state == SCTP_ADDR_SRC) &&
                    (laddr->a.sa.sa_family == AF_INET6) &&
                    (scope <= sctp_scope(&laddr->a))) {
                        bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
@@ -556,7 +556,7 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
        if (!(type & IPV6_ADDR_UNICAST))
                return 0;
 
-       return ipv6_chk_addr(in6, NULL, 0);
+       return ipv6_chk_addr(&init_net, in6, NULL, 0);
 }
 
 /* This function checks if the address is a valid address to be used for
@@ -858,7 +858,8 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
                        dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
                        if (!dev)
                                return 0;
-                       if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) {
+                       if (!ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
+                                          dev, 0)) {
                                dev_put(dev);
                                return 0;
                        }
index 847639d542c01777fac96dba2badfa0e49cc47d6..5e811b91f21c8b6922fa37e7ca6fad3910c9e99c 100644 (file)
@@ -60,6 +60,7 @@
 
 #include <net/sctp/sctp.h>
 #include <net/sctp/sm.h>
+#include <net/sctp/checksum.h>
 
 /* Forward declarations for private helpers. */
 static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
index fa76f235169bfac3cedcb8517d4c62b0cd8daa5c..a42af865c2ef21336761653337b8995644910697 100644 (file)
@@ -716,7 +716,29 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                new_transport = chunk->transport;
 
                if (!new_transport) {
-                       new_transport = asoc->peer.active_path;
+                       /*
+                        * If we have a prior transport pointer, see if
+                        * the destination address of the chunk
+                        * matches the destination address of the
+                        * current transport.  If not a match, then
+                        * try to look up the transport with a given
+                        * destination address.  We do this because
+                        * after processing ASCONFs, we may have new
+                        * transports created.
+                        */
+                       if (transport &&
+                           sctp_cmp_addr_exact(&chunk->dest,
+                                               &transport->ipaddr))
+                                       new_transport = transport;
+                       else
+                               new_transport = sctp_assoc_lookup_paddr(asoc,
+                                                               &chunk->dest);
+
+                       /* if we still don't have a new transport, then
+                        * use the current active path.
+                        */
+                       if (!new_transport)
+                               new_transport = asoc->peer.active_path;
                } else if ((new_transport->state == SCTP_INACTIVE) ||
                           (new_transport->state == SCTP_UNCONFIRMED)) {
                        /* If the chunk is Heartbeat or Heartbeat Ack,
@@ -729,9 +751,12 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                         * address of the IP datagram containing the
                         * HEARTBEAT chunk to which this ack is responding.
                         * ...
+                        *
+                        * ASCONF_ACKs also must be sent to the source.
                         */
                        if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT &&
-                           chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK)
+                           chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK &&
+                           chunk->chunk_hdr->type != SCTP_CID_ASCONF_ACK)
                                new_transport = asoc->peer.active_path;
                }
 
index d50f610d1b02a4b44ffde9dee0d651f5d01fa49e..1339742e49f177c714a578d51d1edb52026350b0 100644 (file)
@@ -229,8 +229,8 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
                            (((AF_INET6 == addr->a.sa.sa_family) &&
                              (copy_flags & SCTP_ADDR6_ALLOWED) &&
                              (copy_flags & SCTP_ADDR6_PEERSUPP)))) {
-                               error = sctp_add_bind_addr(bp, &addr->a, 1,
-                                                   GFP_ATOMIC);
+                               error = sctp_add_bind_addr(bp, &addr->a,
+                                                   SCTP_ADDR_SRC, GFP_ATOMIC);
                                if (error)
                                        goto end_copy;
                        }
@@ -359,7 +359,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
                              const struct sk_buff *skb)
 {
        /* Is this a non-unicast address or a unusable SCTP address? */
-       if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr))
+       if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr))
                return 0;
 
        /* Is this a broadcast address? */
@@ -372,7 +372,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
 /* Should this be available for binding?   */
 static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp)
 {
-       int ret = inet_addr_type(addr->v4.sin_addr.s_addr);
+       int ret = inet_addr_type(&init_net, addr->v4.sin_addr.s_addr);
 
 
        if (addr->v4.sin_addr.s_addr != INADDR_ANY &&
@@ -408,13 +408,15 @@ static sctp_scope_t sctp_v4_scope(union sctp_addr *addr)
         */
 
        /* Check for unusable SCTP addresses. */
-       if (IS_IPV4_UNUSABLE_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       if (IS_IPV4_UNUSABLE_ADDRESS(addr->v4.sin_addr.s_addr)) {
                retval =  SCTP_SCOPE_UNUSABLE;
-       } else if (LOOPBACK(addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_loopback(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_LOOPBACK;
-       } else if (IS_IPV4_LINK_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_linklocal_169(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_LINK;
-       } else if (IS_IPV4_PRIVATE_ADDRESS(&addr->v4.sin_addr.s_addr)) {
+       } else if (ipv4_is_private_10(addr->v4.sin_addr.s_addr) ||
+                  ipv4_is_private_172(addr->v4.sin_addr.s_addr) ||
+                  ipv4_is_private_192(addr->v4.sin_addr.s_addr)) {
                retval = SCTP_SCOPE_PRIVATE;
        } else {
                retval = SCTP_SCOPE_GLOBAL;
@@ -452,7 +454,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
                          __FUNCTION__, NIPQUAD(fl.fl4_dst),
                          NIPQUAD(fl.fl4_src));
 
-       if (!ip_route_output_key(&rt, &fl)) {
+       if (!ip_route_output_key(&init_net, &rt, &fl)) {
                dst = &rt->u.dst;
        }
 
@@ -470,7 +472,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
                 */
                rcu_read_lock();
                list_for_each_entry_rcu(laddr, &bp->address_list, list) {
-                       if (!laddr->valid || !laddr->use_as_src)
+                       if (!laddr->valid || (laddr->state != SCTP_ADDR_SRC))
                                continue;
                        sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
                        if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
@@ -492,10 +494,10 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
        list_for_each_entry_rcu(laddr, &bp->address_list, list) {
                if (!laddr->valid)
                        continue;
-               if ((laddr->use_as_src) &&
+               if ((laddr->state == SCTP_ADDR_SRC) &&
                    (AF_INET == laddr->a.sa.sa_family)) {
                        fl.fl4_src = laddr->a.v4.sin_addr.s_addr;
-                       if (!ip_route_output_key(&rt, &fl)) {
+                       if (!ip_route_output_key(&init_net, &rt, &fl)) {
                                dst = &rt->u.dst;
                                goto out_unlock;
                        }
@@ -1107,7 +1109,7 @@ SCTP_STATIC __init int sctp_init(void)
        sysctl_sctp_rmem[1] = (1500 *(sizeof(struct sk_buff) + 1));
        sysctl_sctp_rmem[2] = max(sysctl_sctp_rmem[1], max_share);
 
-       sysctl_sctp_wmem[0] = SK_STREAM_MEM_QUANTUM;
+       sysctl_sctp_wmem[0] = SK_MEM_QUANTUM;
        sysctl_sctp_wmem[1] = 16*1024;
        sysctl_sctp_wmem[2] = max(64*1024, max_share);
 
index 3cc629d3c9ff80593c24d128dfcdc729111b89dc..dd98763c8b006de560201e454b5003d1197df828 100644 (file)
@@ -1275,6 +1275,9 @@ nodata:
 /* Release the memory occupied by a chunk.  */
 static void sctp_chunk_destroy(struct sctp_chunk *chunk)
 {
+       BUG_ON(!list_empty(&chunk->list));
+       list_del_init(&chunk->transmitted_list);
+
        /* Free the chunk skb data and the SCTP_chunk stub itself. */
        dev_kfree_skb(chunk->skb);
 
@@ -1285,9 +1288,6 @@ static void sctp_chunk_destroy(struct sctp_chunk *chunk)
 /* Possibly, free the chunk.  */
 void sctp_chunk_free(struct sctp_chunk *chunk)
 {
-       BUG_ON(!list_empty(&chunk->list));
-       list_del_init(&chunk->transmitted_list);
-
        /* Release our reference on the message tracker. */
        if (chunk->msg)
                sctp_datamsg_put(chunk->msg);
@@ -1692,8 +1692,8 @@ no_hmac:
 
        /* Also, add the destination address. */
        if (list_empty(&retval->base.bind_addr.address_list)) {
-               sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1,
-                               GFP_ATOMIC);
+               sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest,
+                               SCTP_ADDR_SRC, GFP_ATOMIC);
        }
 
        retval->next_tsn = retval->c.initial_tsn;
@@ -1836,6 +1836,39 @@ static int sctp_process_hn_param(const struct sctp_association *asoc,
        return 0;
 }
 
+static int sctp_verify_ext_param(union sctp_params param)
+{
+       __u16 num_ext = ntohs(param.p->length) - sizeof(sctp_paramhdr_t);
+       int have_auth = 0;
+       int have_asconf = 0;
+       int i;
+
+       for (i = 0; i < num_ext; i++) {
+               switch (param.ext->chunks[i]) {
+                   case SCTP_CID_AUTH:
+                           have_auth = 1;
+                           break;
+                   case SCTP_CID_ASCONF:
+                   case SCTP_CID_ASCONF_ACK:
+                           have_asconf = 1;
+                           break;
+               }
+       }
+
+       /* ADD-IP Security: The draft requires us to ABORT or ignore the
+        * INIT/INIT-ACK if ADD-IP is listed, but AUTH is not.  Do this
+        * only if ADD-IP is turned on and we are not backward-compatible
+        * mode.
+        */
+       if (sctp_addip_noauth)
+               return 1;
+
+       if (sctp_addip_enable && !have_auth && have_asconf)
+               return 0;
+
+       return 1;
+}
+
 static void sctp_process_ext_param(struct sctp_association *asoc,
                                    union sctp_params param)
 {
@@ -1966,9 +1999,18 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
        case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
        case SCTP_PARAM_ECN_CAPABLE:
        case SCTP_PARAM_ADAPTATION_LAYER_IND:
+               break;
+
        case SCTP_PARAM_SUPPORTED_EXT:
+               if (!sctp_verify_ext_param(param))
+                       return SCTP_IERROR_ABORT;
                break;
 
+       case SCTP_PARAM_SET_PRIMARY:
+               if (sctp_addip_enable)
+                       break;
+               goto fallthrough;
+
        case SCTP_PARAM_HOST_NAME_ADDRESS:
                /* Tell the peer, we won't support this param.  */
                sctp_process_hn_param(asoc, param, chunk, err_chunk);
@@ -2134,10 +2176,11 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
                                        !asoc->peer.peer_hmacs))
                asoc->peer.auth_capable = 0;
 
-
-       /* If the peer claims support for ADD-IP without support
-        * for AUTH, disable support for ADD-IP.
-        * Do this only if backward compatible mode is turned off.
+       /* In a non-backward compatible mode, if the peer claims
+        * support for ADD-IP but not AUTH,  the ADD-IP spec states
+        * that we MUST ABORT the association. Section 6.  The section
+        * also give us an option to silently ignore the packet, which
+        * is what we'll do here.
         */
        if (!sctp_addip_noauth &&
             (asoc->peer.asconf_capable && !asoc->peer.auth_capable)) {
@@ -2145,6 +2188,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
                                                  SCTP_PARAM_DEL_IP |
                                                  SCTP_PARAM_SET_PRIMARY);
                asoc->peer.asconf_capable = 0;
+               goto clean_up;
        }
 
        /* Walk list of transports, removing transports in the UNKNOWN state. */
@@ -2286,6 +2330,8 @@ static int sctp_process_param(struct sctp_association *asoc,
        sctp_scope_t scope;
        time_t stale;
        struct sctp_af *af;
+       union sctp_addr_param *addr_param;
+       struct sctp_transport *t;
 
        /* We maintain all INIT parameters in network byte order all the
         * time.  This allows us to not worry about whether the parameters
@@ -2376,6 +2422,26 @@ static int sctp_process_param(struct sctp_association *asoc,
                asoc->peer.adaptation_ind = param.aind->adaptation_ind;
                break;
 
+       case SCTP_PARAM_SET_PRIMARY:
+               addr_param = param.v + sizeof(sctp_addip_param_t);
+
+               af = sctp_get_af_specific(param_type2af(param.p->type));
+               af->from_addr_param(&addr, addr_param,
+                                   htons(asoc->peer.port), 0);
+
+               /* if the address is invalid, we can't process it.
+                * XXX: see spec for what to do.
+                */
+               if (!af->addr_valid(&addr, NULL, NULL))
+                       break;
+
+               t = sctp_assoc_lookup_paddr(asoc, &addr);
+               if (!t)
+                       break;
+
+               sctp_assoc_set_primary(asoc, t);
+               break;
+
        case SCTP_PARAM_SUPPORTED_EXT:
                sctp_process_ext_param(asoc, param);
                break;
@@ -2727,7 +2793,6 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
        struct sctp_transport *peer;
        struct sctp_af *af;
        union sctp_addr addr;
-       struct list_head *pos;
        union sctp_addr_param *addr_param;
 
        addr_param = (union sctp_addr_param *)
@@ -2738,8 +2803,24 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
                return SCTP_ERROR_INV_PARAM;
 
        af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
+
+       /* ADDIP 4.2.1  This parameter MUST NOT contain a broadcast
+        * or multicast address.
+        * (note: wildcard is permitted and requires special handling so
+        *  make sure we check for that)
+        */
+       if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
+               return SCTP_ERROR_INV_PARAM;
+
        switch (asconf_param->param_hdr.type) {
        case SCTP_PARAM_ADD_IP:
+               /* Section 4.2.1:
+                * If the address 0.0.0.0 or ::0 is provided, the source
+                * address of the packet MUST be added.
+                */
+               if (af->is_any(&addr))
+                       memcpy(&addr, &asconf->source, sizeof(addr));
+
                /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
                 * request and does not have the local resources to add this
                 * new address to the association, it MUST return an Error
@@ -2761,8 +2842,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
                 * MUST send an Error Cause TLV with the error cause set to the
                 * new error code 'Request to Delete Last Remaining IP Address'.
                 */
-               pos = asoc->peer.transport_addr_list.next;
-               if (pos->next == &asoc->peer.transport_addr_list)
+               if (asoc->peer.transport_count == 1)
                        return SCTP_ERROR_DEL_LAST_IP;
 
                /* ADDIP 4.3 D8) If a request is received to delete an IP
@@ -2775,9 +2855,27 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
                if (sctp_cmp_addr_exact(sctp_source(asconf), &addr))
                        return SCTP_ERROR_DEL_SRC_IP;
 
-               sctp_assoc_del_peer(asoc, &addr);
+               /* Section 4.2.2
+                * If the address 0.0.0.0 or ::0 is provided, all
+                * addresses of the peer except the source address of the
+                * packet MUST be deleted.
+                */
+               if (af->is_any(&addr)) {
+                       sctp_assoc_set_primary(asoc, asconf->transport);
+                       sctp_assoc_del_nonprimary_peers(asoc,
+                                                       asconf->transport);
+               } else
+                       sctp_assoc_del_peer(asoc, &addr);
                break;
        case SCTP_PARAM_SET_PRIMARY:
+               /* ADDIP Section 4.2.4
+                * If the address 0.0.0.0 or ::0 is provided, the receiver
+                * MAY mark the source address of the packet as its
+                * primary.
+                */
+               if (af->is_any(&addr))
+                       memcpy(&addr.v4, sctp_source(asconf), sizeof(addr));
+
                peer = sctp_assoc_lookup_paddr(asoc, &addr);
                if (!peer)
                        return SCTP_ERROR_INV_PARAM;
@@ -2921,11 +3019,9 @@ done:
         * after freeing the reference to old asconf ack if any.
         */
        if (asconf_ack) {
-               if (asoc->addip_last_asconf_ack)
-                       sctp_chunk_free(asoc->addip_last_asconf_ack);
-
                sctp_chunk_hold(asconf_ack);
-               asoc->addip_last_asconf_ack = asconf_ack;
+               list_add_tail(&asconf_ack->transmitted_list,
+                             &asoc->asconf_ack_list);
        }
 
        return asconf_ack;
@@ -2959,7 +3055,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
                local_bh_disable();
                list_for_each_entry(saddr, &bp->address_list, list) {
                        if (sctp_cmp_addr_exact(&saddr->a, &addr))
-                               saddr->use_as_src = 1;
+                               saddr->state = SCTP_ADDR_SRC;
                }
                local_bh_enable();
                break;
index d247ed4ee42369c69aa8c8a3f26c83a370e906fc..61cbd5a8dd0c4954c212cacaf7f46f403ca1408b 100644 (file)
@@ -143,6 +143,12 @@ static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
                                    const sctp_subtype_t type,
                                    struct sctp_chunk *chunk);
 
+static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
+                                       const struct sctp_association *asoc,
+                                       const sctp_subtype_t type,
+                                       void *arg,
+                                       sctp_cmd_seq_t *commands);
+
 /* Small helper function that checks if the chunk length
  * is of the appropriate length.  The 'required_length' argument
  * is set to be the size of a specific chunk we are testing.
@@ -475,7 +481,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
        sctp_init_chunk_t *initchunk;
        struct sctp_chunk *err_chunk;
        struct sctp_packet *packet;
-       sctp_error_t error;
 
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -500,8 +505,12 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                              (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
                              &err_chunk)) {
 
+               sctp_error_t error = SCTP_ERROR_NO_RESOURCE;
+
                /* This chunk contains fatal error. It is to be discarded.
-                * Send an ABORT, with causes if there is any.
+                * Send an ABORT, with causes.  If there are no causes,
+                * then there wasn't enough memory.  Just terminate
+                * the association.
                 */
                if (err_chunk) {
                        packet = sctp_abort_pkt_new(ep, asoc, arg,
@@ -517,12 +526,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                                                SCTP_PACKET(packet));
                                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
                                error = SCTP_ERROR_INV_PARAM;
-                       } else {
-                               error = SCTP_ERROR_NO_RESOURCE;
                        }
-               } else {
-                       sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
-                       error = SCTP_ERROR_INV_PARAM;
                }
 
                /* SCTP-AUTH, Section 6.3:
@@ -2073,11 +2077,20 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
        if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* ADD-IP: Special case for ABORT chunks
+        * F4)  One special consideration is that ABORT Chunks arriving
+        * destined to the IP address being deleted MUST be
+        * ignored (see Section 5.3.1 for further details).
+        */
+       if (SCTP_ADDR_DEL ==
+                   sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
+               return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+
        /* Stop the T5-shutdown guard timer.  */
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 
-       return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+       return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
 }
 
 /*
@@ -2109,6 +2122,15 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
        if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* ADD-IP: Special case for ABORT chunks
+        * F4)  One special consideration is that ABORT Chunks arriving
+        * destined to the IP address being deleted MUST be
+        * ignored (see Section 5.3.1 for further details).
+        */
+       if (SCTP_ADDR_DEL ==
+                   sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
+               return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+
        /* Stop the T2-shutdown timer. */
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
@@ -2117,7 +2139,7 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const struct sctp_endpoint *ep,
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
 
-       return sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+       return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
 }
 
 /*
@@ -2344,8 +2366,6 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
                                        sctp_cmd_seq_t *commands)
 {
        struct sctp_chunk *chunk = arg;
-       unsigned len;
-       __be16 error = SCTP_ERROR_NO_ERROR;
 
        if (!sctp_vtag_verify_either(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2363,6 +2383,28 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
        if (!sctp_chunk_length_valid(chunk, sizeof(sctp_abort_chunk_t)))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+       /* ADD-IP: Special case for ABORT chunks
+        * F4)  One special consideration is that ABORT Chunks arriving
+        * destined to the IP address being deleted MUST be
+        * ignored (see Section 5.3.1 for further details).
+        */
+       if (SCTP_ADDR_DEL ==
+                   sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
+               return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+
+       return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
+}
+
+static sctp_disposition_t __sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
+                                       const struct sctp_association *asoc,
+                                       const sctp_subtype_t type,
+                                       void *arg,
+                                       sctp_cmd_seq_t *commands)
+{
+       struct sctp_chunk *chunk = arg;
+       unsigned len;
+       __be16 error = SCTP_ERROR_NO_ERROR;
+
        /* See if we have an error cause code in the chunk.  */
        len = ntohs(chunk->chunk_hdr->length);
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
@@ -3377,6 +3419,15 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
        }
 
+       /* ADD-IP: Section 4.1.1
+        * This chunk MUST be sent in an authenticated way by using
+        * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk
+        * is received unauthenticated it MUST be silently discarded as
+        * described in [I-D.ietf-tsvwg-sctp-auth].
+        */
+       if (!sctp_addip_noauth && !chunk->auth)
+               return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+
        /* Make sure that the ASCONF ADDIP chunk has a valid length.  */
        if (!sctp_chunk_length_valid(chunk, sizeof(sctp_addip_chunk_t)))
                return sctp_sf_violation_chunklen(ep, asoc, type, arg,
@@ -3393,48 +3444,68 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
 
        /* Verify the ASCONF chunk before processing it. */
        if (!sctp_verify_asconf(asoc,
-           (sctp_paramhdr_t *)((void *)addr_param + length),
-           (void *)chunk->chunk_end,
-           &err_param))
+                           (sctp_paramhdr_t *)((void *)addr_param + length),
+                           (void *)chunk->chunk_end,
+                           &err_param))
                return sctp_sf_violation_paramlen(ep, asoc, type,
-                          (void *)&err_param, commands);
+                                                 (void *)&err_param, commands);
 
-       /* ADDIP 4.2 C1) Compare the value of the serial number to the value
+       /* ADDIP 5.2 E1) Compare the value of the serial number to the value
         * the endpoint stored in a new association variable
         * 'Peer-Serial-Number'.
         */
        if (serial == asoc->peer.addip_serial + 1) {
-               /* ADDIP 4.2 C2) If the value found in the serial number is
-                * equal to the ('Peer-Serial-Number' + 1), the endpoint MUST
-                * do V1-V5.
+               /* If this is the first instance of ASCONF in the packet,
+                * we can clean our old ASCONF-ACKs.
+                */
+               if (!chunk->has_asconf)
+                       sctp_assoc_clean_asconf_ack_cache(asoc);
+
+               /* ADDIP 5.2 E4) When the Sequence Number matches the next one
+                * expected, process the ASCONF as described below and after
+                * processing the ASCONF Chunk, append an ASCONF-ACK Chunk to
+                * the response packet and cache a copy of it (in the event it
+                * later needs to be retransmitted).
+                *
+                * Essentially, do V1-V5.
                 */
                asconf_ack = sctp_process_asconf((struct sctp_association *)
                                                 asoc, chunk);
                if (!asconf_ack)
                        return SCTP_DISPOSITION_NOMEM;
-       } else if (serial == asoc->peer.addip_serial) {
-               /* ADDIP 4.2 C3) If the value found in the serial number is
-                * equal to the value stored in the 'Peer-Serial-Number'
-                * IMPLEMENTATION NOTE: As an optimization a receiver may wish
-                * to save the last ASCONF-ACK for some predetermined period of
-                * time and instead of re-processing the ASCONF (with the same
-                * serial number) it may just re-transmit the ASCONF-ACK.
+       } else if (serial < asoc->peer.addip_serial + 1) {
+               /* ADDIP 5.2 E2)
+                * If the value found in the Sequence Number is less than the
+                * ('Peer- Sequence-Number' + 1), simply skip to the next
+                * ASCONF, and include in the outbound response packet
+                * any previously cached ASCONF-ACK response that was
+                * sent and saved that matches the Sequence Number of the
+                * ASCONF.  Note: It is possible that no cached ASCONF-ACK
+                * Chunk exists.  This will occur when an older ASCONF
+                * arrives out of order.  In such a case, the receiver
+                * should skip the ASCONF Chunk and not include ASCONF-ACK
+                * Chunk for that chunk.
                 */
-               if (asoc->addip_last_asconf_ack)
-                       asconf_ack = asoc->addip_last_asconf_ack;
-               else
+               asconf_ack = sctp_assoc_lookup_asconf_ack(asoc, hdr->serial);
+               if (!asconf_ack)
                        return SCTP_DISPOSITION_DISCARD;
        } else {
-               /* ADDIP 4.2 C4) Otherwise, the ASCONF Chunk is discarded since
+               /* ADDIP 5.2 E5) Otherwise, the ASCONF Chunk is discarded since
                 * it must be either a stale packet or from an attacker.
                 */
                return SCTP_DISPOSITION_DISCARD;
        }
 
-       /* ADDIP 4.2 C5) In both cases C2 and C3 the ASCONF-ACK MUST be sent
-        * back to the source address contained in the IP header of the ASCONF
-        * being responded to.
+       /* ADDIP 5.2 E6)  The destination address of the SCTP packet
+        * containing the ASCONF-ACK Chunks MUST be the source address of
+        * the SCTP packet that held the ASCONF Chunks.
+        *
+        * To do this properly, we'll set the destination address of the chunk
+        * and at the transmit time, will try look up the transport to use.
+        * Since ASCONFs may be bundled, the correct transport may not be
+        * created untill we process the entire packet, thus this workaround.
         */
+       asconf_ack->dest = chunk->source;
        sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(asconf_ack));
 
        return SCTP_DISPOSITION_CONSUME;
@@ -3463,6 +3534,15 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
        }
 
+       /* ADD-IP, Section 4.1.2:
+        * This chunk MUST be sent in an authenticated way by using
+        * the mechanism defined in [I-D.ietf-tsvwg-sctp-auth]. If this chunk
+        * is received unauthenticated it MUST be silently discarded as
+        * described in [I-D.ietf-tsvwg-sctp-auth].
+        */
+       if (!sctp_addip_noauth && !asconf_ack->auth)
+               return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
+
        /* Make sure that the ADDIP chunk has a valid length.  */
        if (!sctp_chunk_length_valid(asconf_ack, sizeof(sctp_addip_chunk_t)))
                return sctp_sf_violation_chunklen(ep, asoc, type, arg,
@@ -5763,7 +5843,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
        /*
         * Also try to renege to limit our memory usage in the event that
         * we are under memory pressure
-        * If we can't renege, don't worry about it, the sk_stream_rmem_schedule
+        * If we can't renege, don't worry about it, the sk_rmem_schedule
         * in sctp_ulpevent_make_rcvmsg will drop the frame if we grow our
         * memory usage too much
         */
index a93a4bc8f68f2bb8cd48619032e45cf7fca9b3d4..e6016e41ffa0ac88db0f7bb2da6fdfb134f6b38f 100644 (file)
@@ -457,11 +457,11 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][
        /* SCTP_STATE_ESTABLISHED */ \
        TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
        /* SCTP_STATE_SHUTDOWN_PENDING */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
        /* SCTP_STATE_SHUTDOWN_SENT */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
        TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
 } /* TYPE_SCTP_ASCONF */
@@ -478,11 +478,11 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][
        /* SCTP_STATE_ESTABLISHED */ \
        TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
        /* SCTP_STATE_SHUTDOWN_PENDING */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
        /* SCTP_STATE_SHUTDOWN_SENT */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-       TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
+       TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
        TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
 } /* TYPE_SCTP_ASCONF_ACK */
@@ -691,11 +691,11 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
        /* SCTP_STATE_ESTABLISHED */ \
        TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
        /* SCTP_STATE_SHUTDOWN_PENDING */ \
-       TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
+       TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
        /* SCTP_STATE_SHUTDOWN_SENT */ \
-       TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
+       TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
-       TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
+       TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
        TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
 } /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
index ea9649ca0b2a0be135247b7fee9cfba251c7ec15..710df67a67857184c43060fce807f1809411db4e 100644 (file)
@@ -174,7 +174,8 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
                                sizeof(struct sctp_chunk);
 
        atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
-       sk_charge_skb(sk, chunk->skb);
+       sk->sk_wmem_queued += chunk->skb->truesize;
+       sk_mem_charge(sk, chunk->skb->truesize);
 }
 
 /* Verify that this is a valid address. */
@@ -390,7 +391,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
        /* Add the address to the bind address list.
         * Use GFP_ATOMIC since BHs will be disabled.
         */
-       ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC);
+       ret = sctp_add_bind_addr(bp, addr, SCTP_ADDR_SRC, GFP_ATOMIC);
 
        /* Copy back into socket for getsockname() use. */
        if (!ret) {
@@ -585,8 +586,8 @@ static int sctp_send_asconf_add_ip(struct sock              *sk,
                        addr = (union sctp_addr *)addr_buf;
                        af = sctp_get_af_specific(addr->v4.sin_family);
                        memcpy(&saveaddr, addr, af->sockaddr_len);
-                       retval = sctp_add_bind_addr(bp, &saveaddr, 0,
-                                                   GFP_ATOMIC);
+                       retval = sctp_add_bind_addr(bp, &saveaddr,
+                                                   SCTP_ADDR_NEW, GFP_ATOMIC);
                        addr_buf += af->sockaddr_len;
                }
        }
@@ -777,7 +778,7 @@ static int sctp_send_asconf_del_ip(struct sock              *sk,
                        af = sctp_get_af_specific(laddr->v4.sin_family);
                        list_for_each_entry(saddr, &bp->address_list, list) {
                                if (sctp_cmp_addr_exact(&saddr->a, laddr))
-                                       saddr->use_as_src = 0;
+                                       saddr->state = SCTP_ADDR_DEL;
                        }
                        addr_buf += af->sockaddr_len;
                }
@@ -6008,7 +6009,8 @@ static void __sctp_write_space(struct sctp_association *asoc)
                         */
                        if (sock->fasync_list &&
                            !(sk->sk_shutdown & SEND_SHUTDOWN))
-                               sock_wake_async(sock, 2, POLL_OUT);
+                               sock_wake_async(sock,
+                                               SOCK_WAKE_SPACE, POLL_OUT);
                }
        }
 }
@@ -6034,10 +6036,10 @@ static void sctp_wfree(struct sk_buff *skb)
        atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
 
        /*
-        * This undoes what is done via sk_charge_skb
+        * This undoes what is done via sctp_set_owner_w and sk_mem_charge
         */
        sk->sk_wmem_queued   -= skb->truesize;
-       sk->sk_forward_alloc += skb->truesize;
+       sk_mem_uncharge(sk, skb->truesize);
 
        sock_wfree(skb);
        __sctp_write_space(asoc);
@@ -6058,9 +6060,9 @@ void sctp_sock_rfree(struct sk_buff *skb)
        atomic_sub(event->rmem_len, &sk->sk_rmem_alloc);
 
        /*
-        * Mimic the behavior of sk_stream_rfree
+        * Mimic the behavior of sock_rfree
         */
-       sk->sk_forward_alloc += event->rmem_len;
+       sk_mem_uncharge(sk, event->rmem_len);
 }
 
 
index da4f15734fb11f4e739059d5d0be49300ca3bbe8..5eb6ea829b5440b749199b08be6d15951b3eade0 100644 (file)
@@ -275,24 +275,10 @@ static ctl_table sctp_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table sctp_net_table[] = {
-       {
-               .ctl_name       = NET_SCTP,
-               .procname       = "sctp",
-               .mode           = 0555,
-               .child          = sctp_table
-       },
-       { .ctl_name = 0 }
-};
-
-static ctl_table sctp_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = sctp_net_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path sctp_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "sctp", .ctl_name = NET_SCTP, },
+       { }
 };
 
 static struct ctl_table_header * sctp_sysctl_header;
@@ -300,7 +286,7 @@ static struct ctl_table_header * sctp_sysctl_header;
 /* Sysctl registration.  */
 void sctp_sysctl_register(void)
 {
-       sctp_sysctl_header = register_sysctl_table(sctp_root_table);
+       sctp_sysctl_header = register_sysctl_paths(sctp_path, sctp_table);
 }
 
 /* Sysctl deregistration.  */
index d55ce83a020b7a32059b92758afa790e4d912e4e..dfa109341aeb1fb3c88d2abc0c47130478a06e3b 100644 (file)
@@ -99,15 +99,10 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
        INIT_LIST_HEAD(&peer->send_ready);
        INIT_LIST_HEAD(&peer->transports);
 
-       /* Set up the retransmission timer.  */
-       init_timer(&peer->T3_rtx_timer);
-       peer->T3_rtx_timer.function = sctp_generate_t3_rtx_event;
-       peer->T3_rtx_timer.data = (unsigned long)peer;
-
-       /* Set up the heartbeat timer. */
-       init_timer(&peer->hb_timer);
-       peer->hb_timer.function = sctp_generate_heartbeat_event;
-       peer->hb_timer.data = (unsigned long)peer;
+       setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event,
+                       (unsigned long)peer);
+       setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
+                       (unsigned long)peer);
 
        /* Initialize the 64-bit random nonce sent with heartbeat. */
        get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
index 307314356e1662317c25be57050f79f366a9395e..047c27df98f441aa8b8e3f33427a5436bfb41f74 100644 (file)
@@ -700,7 +700,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
        if (rx_count >= asoc->base.sk->sk_rcvbuf) {
 
                if ((asoc->base.sk->sk_userlocks & SOCK_RCVBUF_LOCK) ||
-                  (!sk_stream_rmem_schedule(asoc->base.sk, chunk->skb)))
+                   (!sk_rmem_schedule(asoc->base.sk, chunk->skb->truesize)))
                        goto fail;
        }
 
index 1733fa29a50180fdcdd8bfc47b8cf78d37f5a583..c25caefa3bcb4b3ddb0b0dc36bd96019d368427e 100644 (file)
@@ -1046,7 +1046,7 @@ void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk,
                sctp_ulpq_partial_delivery(ulpq, chunk, gfp);
        }
 
-       sk_stream_mem_reclaim(asoc->base.sk);
+       sk_mem_reclaim(asoc->base.sk);
        return;
 }
 
index 74784dfe8e5b2b6d304c68e34e9ba4c8194123e3..7651de0085028dc4d02b15e5844e239dd938d01e 100644 (file)
@@ -112,6 +112,9 @@ static long compat_sock_ioctl(struct file *file,
 static int sock_fasync(int fd, struct file *filp, int on);
 static ssize_t sock_sendpage(struct file *file, struct page *page,
                             int offset, size_t size, loff_t *ppos, int more);
+static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
+                               struct pipe_inode_info *pipe, size_t len,
+                               unsigned int flags);
 
 /*
  *     Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
@@ -134,6 +137,7 @@ static const struct file_operations socket_file_ops = {
        .fasync =       sock_fasync,
        .sendpage =     sock_sendpage,
        .splice_write = generic_splice_sendpage,
+       .splice_read =  sock_splice_read,
 };
 
 /*
@@ -691,6 +695,15 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
        return sock->ops->sendpage(sock, page, offset, size, flags);
 }
 
+static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
+                               struct pipe_inode_info *pipe, size_t len,
+                               unsigned int flags)
+{
+       struct socket *sock = file->private_data;
+
+       return sock->ops->splice_read(sock, ppos, pipe, len, flags);
+}
+
 static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
                                         struct sock_iocb *siocb)
 {
@@ -1057,20 +1070,19 @@ int sock_wake_async(struct socket *sock, int how, int band)
        if (!sock || !sock->fasync_list)
                return -1;
        switch (how) {
-       case 1:
-
+       case SOCK_WAKE_WAITD:
                if (test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
                        break;
                goto call_kill;
-       case 2:
+       case SOCK_WAKE_SPACE:
                if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags))
                        break;
                /* fall through */
-       case 0:
+       case SOCK_WAKE_IO:
 call_kill:
                __kill_fasync(sock->fasync_list, SIGIO, band);
                break;
-       case 3:
+       case SOCK_WAKE_URG:
                __kill_fasync(sock->fasync_list, SIGURG, band);
        }
        return 0;
@@ -1353,17 +1365,17 @@ asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen)
  *     ready for listening.
  */
 
-int sysctl_somaxconn __read_mostly = SOMAXCONN;
-
 asmlinkage long sys_listen(int fd, int backlog)
 {
        struct socket *sock;
        int err, fput_needed;
+       int somaxconn;
 
        sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (sock) {
-               if ((unsigned)backlog > sysctl_somaxconn)
-                       backlog = sysctl_somaxconn;
+               somaxconn = sock->sk->sk_net->sysctl_somaxconn;
+               if ((unsigned)backlog > somaxconn)
+                       backlog = somaxconn;
 
                err = security_socket_listen(sock, backlog);
                if (!err)
@@ -1581,16 +1593,11 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
        struct msghdr msg;
        struct iovec iov;
        int fput_needed;
-       struct file *sock_file;
 
-       sock_file = fget_light(fd, &fput_needed);
-       err = -EBADF;
-       if (!sock_file)
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
+       if (!sock)
                goto out;
 
-       sock = sock_from_file(sock_file, &err);
-       if (!sock)
-               goto out_put;
        iov.iov_base = buff;
        iov.iov_len = len;
        msg.msg_name = NULL;
@@ -1612,7 +1619,7 @@ asmlinkage long sys_sendto(int fd, void __user *buff, size_t len,
        err = sock_sendmsg(sock, &msg, len);
 
 out_put:
-       fput_light(sock_file, fput_needed);
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 }
@@ -1641,17 +1648,11 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
        struct msghdr msg;
        char address[MAX_SOCK_ADDR];
        int err, err2;
-       struct file *sock_file;
        int fput_needed;
 
-       sock_file = fget_light(fd, &fput_needed);
-       err = -EBADF;
-       if (!sock_file)
-               goto out;
-
-       sock = sock_from_file(sock_file, &err);
+       sock = sockfd_lookup_light(fd, &err, &fput_needed);
        if (!sock)
-               goto out_put;
+               goto out;
 
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
@@ -1670,8 +1671,8 @@ asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size,
                if (err2 < 0)
                        err = err2;
        }
-out_put:
-       fput_light(sock_file, fput_needed);
+
+       fput_light(sock->file, fput_needed);
 out:
        return err;
 }
index 8e05557414cebfd522ea5dd0a056d6d95399588d..73f053d0cc7a4f7eee6d65954f5383cb6d6fa18e 100644 (file)
@@ -1127,6 +1127,7 @@ struct handle {
 };
 
 static void *c_start(struct seq_file *m, loff_t *pos)
+       __acquires(cd->hash_lock)
 {
        loff_t n = *pos;
        unsigned hash, entry;
@@ -1183,6 +1184,7 @@ static void *c_next(struct seq_file *m, void *p, loff_t *pos)
 }
 
 static void c_stop(struct seq_file *m, void *p)
+       __releases(cd->hash_lock)
 {
        struct cache_detail *cd = ((struct handle*)m->private)->cd;
        read_unlock(&cd->hash_lock);
index c98873f39aec49bc4d4af57f60f34d23a20123c4..eed5dd9819cde8ddc48e147954852d515a77f7ef 100644 (file)
@@ -811,9 +811,8 @@ EXPORT_SYMBOL_GPL(rpc_free);
 void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
 {
        memset(task, 0, sizeof(*task));
-       init_timer(&task->tk_timer);
-       task->tk_timer.data     = (unsigned long) task;
-       task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer;
+       setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer,
+                       (unsigned long)task);
        atomic_set(&task->tk_count, 1);
        task->tk_client = clnt;
        task->tk_flags  = flags;
index cd641c8634f044c6bb580c2d725bdb908e97849d..fb92f51405c5d5a2a9016eb980c4536fc455121b 100644 (file)
@@ -1011,9 +1011,8 @@ found:
        INIT_LIST_HEAD(&xprt->free);
        INIT_LIST_HEAD(&xprt->recv);
        INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
-       init_timer(&xprt->timer);
-       xprt->timer.function = xprt_init_autodisconnect;
-       xprt->timer.data = (unsigned long) xprt;
+       setup_timer(&xprt->timer, xprt_init_autodisconnect,
+                       (unsigned long)xprt);
        xprt->last_used = jiffies;
        xprt->cwnd = RPC_INITCWND;
        xprt->bind_index = 0;
index ee8de7af2a5bd8b0b757d2f581f1cb8c127e235b..1aa1580cda6d82c247d202596ddfa9676d8f1e08 100644 (file)
@@ -380,7 +380,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
        headerp->rm_xid = rqst->rq_xid;
        headerp->rm_vers = xdr_one;
        headerp->rm_credit = htonl(r_xprt->rx_buf.rb_max_requests);
-       headerp->rm_type = __constant_htonl(RDMA_MSG);
+       headerp->rm_type = htonl(RDMA_MSG);
 
        /*
         * Chunks needed for results?
@@ -458,11 +458,11 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
                                                RPCRDMA_INLINE_PAD_VALUE(rqst));
 
                if (padlen) {
-                       headerp->rm_type = __constant_htonl(RDMA_MSGP);
+                       headerp->rm_type = htonl(RDMA_MSGP);
                        headerp->rm_body.rm_padded.rm_align =
                                htonl(RPCRDMA_INLINE_PAD_VALUE(rqst));
                        headerp->rm_body.rm_padded.rm_thresh =
-                               __constant_htonl(RPCRDMA_INLINE_PAD_THRESH);
+                               htonl(RPCRDMA_INLINE_PAD_THRESH);
                        headerp->rm_body.rm_padded.rm_pempty[0] = xdr_zero;
                        headerp->rm_body.rm_padded.rm_pempty[1] = xdr_zero;
                        headerp->rm_body.rm_padded.rm_pempty[2] = xdr_zero;
index 2f630a512ab753f7e2df18a42a2abb02f04893ba..6fa52f44de0fd1b43f8630ae7d50ef0805be06a1 100644 (file)
@@ -838,8 +838,12 @@ static void xs_udp_data_ready(struct sock *sk, int len)
                copied = repsize;
 
        /* Suck it into the iovec, verify checksum if not done by hw. */
-       if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb))
+       if (csum_partial_copy_to_xdr(&rovr->rq_private_buf, skb)) {
+               UDPX_INC_STATS_BH(sk, UDP_MIB_INERRORS);
                goto out_unlock;
+       }
+
+       UDPX_INC_STATS_BH(sk, UDP_MIB_INDATAGRAMS);
 
        /* Something worked... */
        dst_confirm(skb->dst);
index cd4eafbab1b8e265b70657033cc9a1047a16bce2..665e856675a4e449268789a295a40e119ee876b9 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/mm.h>
 #include <linux/sysctl.h>
+#include <linux/nsproxy.h>
 
 #include <net/sock.h>
 
 #include <linux/if_tr.h>
 #endif
 
-struct ctl_table net_table[] = {
-       {
-               .ctl_name       = NET_CORE,
-               .procname       = "core",
-               .mode           = 0555,
-               .child          = core_table,
-       },
-#ifdef CONFIG_INET
-       {
-               .ctl_name       = NET_IPV4,
-               .procname       = "ipv4",
-               .mode           = 0555,
-               .child          = ipv4_table
-       },
-#endif
-#ifdef CONFIG_TR
-       {
-               .ctl_name       = NET_TR,
-               .procname       = "token-ring",
-               .mode           = 0555,
-               .child          = tr_table,
-       },
-#endif
-       { 0 },
+static struct list_head *
+net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
+{
+       return &namespaces->net_ns->sysctl_table_headers;
+}
+
+static struct ctl_table_root net_sysctl_root = {
+       .lookup = net_ctl_header_lookup,
+};
+
+static int sysctl_net_init(struct net *net)
+{
+       INIT_LIST_HEAD(&net->sysctl_table_headers);
+       return 0;
+}
+
+static void sysctl_net_exit(struct net *net)
+{
+       WARN_ON(!list_empty(&net->sysctl_table_headers));
+       return;
+}
+
+static struct pernet_operations sysctl_pernet_ops = {
+       .init = sysctl_net_init,
+       .exit = sysctl_net_exit,
 };
+
+static __init int sysctl_init(void)
+{
+       int ret;
+       ret = register_pernet_subsys(&sysctl_pernet_ops);
+       if (ret)
+               goto out;
+       register_sysctl_root(&net_sysctl_root);
+out:
+       return ret;
+}
+subsys_initcall(sysctl_init);
+
+struct ctl_table_header *register_net_sysctl_table(struct net *net,
+       const struct ctl_path *path, struct ctl_table *table)
+{
+       struct nsproxy namespaces;
+       namespaces = *current->nsproxy;
+       namespaces.net_ns = net;
+       return __register_sysctl_paths(&net_sysctl_root,
+                                       &namespaces, path, table);
+}
+EXPORT_SYMBOL_GPL(register_net_sysctl_table);
+
+void unregister_net_sysctl_table(struct ctl_table_header *header)
+{
+       return unregister_sysctl_table(header);
+}
+EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);
index e40ada964d6e9ce4794b30c98ab6f2516ac70427..feabca5808201be3083b015ae15ced8012574bfe 100644 (file)
@@ -212,9 +212,7 @@ static inline void k_init_timer(struct timer_list *timer, Handler routine,
                                unsigned long argument)
 {
        dbg("initializing timer %p\n", timer);
-       init_timer(timer);
-       timer->function = routine;
-       timer->data = argument;
+       setup_timer(timer, routine, argument);
 }
 
 /**
index 76088153524cf2da2d22f20a4ccdef77643a15be..f508614ca59b4125fa77e94728057205bf9f8f57 100644 (file)
@@ -340,7 +340,7 @@ int tipc_portunreliable(u32 ref, unsigned int *isunreliable)
        if (!p_ptr)
                return -EINVAL;
        *isunreliable = port_unreliable(p_ptr);
-       spin_unlock_bh(p_ptr->publ.lock);
+       tipc_port_unlock(p_ptr);
        return TIPC_OK;
 }
 
@@ -369,7 +369,7 @@ int tipc_portunreturnable(u32 ref, unsigned int *isunrejectable)
        if (!p_ptr)
                return -EINVAL;
        *isunrejectable = port_unreturnable(p_ptr);
-       spin_unlock_bh(p_ptr->publ.lock);
+       tipc_port_unlock(p_ptr);
        return TIPC_OK;
 }
 
@@ -843,7 +843,7 @@ static void port_dispatcher_sigh(void *dummy)
                                u32 peer_port = port_peerport(p_ptr);
                                u32 peer_node = port_peernode(p_ptr);
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (unlikely(!connected)) {
                                        if (unlikely(published))
                                                goto reject;
@@ -867,7 +867,7 @@ static void port_dispatcher_sigh(void *dummy)
                case TIPC_DIRECT_MSG:{
                                tipc_msg_event cb = up_ptr->msg_cb;
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (unlikely(connected))
                                        goto reject;
                                if (unlikely(!cb))
@@ -882,7 +882,7 @@ static void port_dispatcher_sigh(void *dummy)
                case TIPC_NAMED_MSG:{
                                tipc_named_msg_event cb = up_ptr->named_msg_cb;
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (unlikely(connected))
                                        goto reject;
                                if (unlikely(!cb))
@@ -913,7 +913,7 @@ err:
                                u32 peer_port = port_peerport(p_ptr);
                                u32 peer_node = port_peernode(p_ptr);
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (!connected || !cb)
                                        break;
                                if (msg_origport(msg) != peer_port)
@@ -929,7 +929,7 @@ err:
                case TIPC_DIRECT_MSG:{
                                tipc_msg_err_event cb = up_ptr->err_cb;
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (connected || !cb)
                                        break;
                                skb_pull(buf, msg_hdr_sz(msg));
@@ -942,7 +942,7 @@ err:
                                tipc_named_msg_err_event cb =
                                        up_ptr->named_err_cb;
 
-                               spin_unlock_bh(p_ptr->publ.lock);
+                               tipc_port_unlock(p_ptr);
                                if (connected || !cb)
                                        break;
                                dseq.type =  msg_nametype(msg);
@@ -1107,7 +1107,7 @@ int tipc_portimportance(u32 ref, unsigned int *importance)
        if (!p_ptr)
                return -EINVAL;
        *importance = (unsigned int)msg_importance(&p_ptr->publ.phdr);
-       spin_unlock_bh(p_ptr->publ.lock);
+       tipc_port_unlock(p_ptr);
        return TIPC_OK;
 }
 
@@ -1122,7 +1122,7 @@ int tipc_set_portimportance(u32 ref, unsigned int imp)
        if (!p_ptr)
                return -EINVAL;
        msg_set_importance(&p_ptr->publ.phdr, (u32)imp);
-       spin_unlock_bh(p_ptr->publ.lock);
+       tipc_port_unlock(p_ptr);
        return TIPC_OK;
 }
 
index 060bba4567d2588d2ceafce255e75ee84aa55b27..eea75888805e151d2d26ffae2518971ee330349d 100644 (file)
 #include <net/checksum.h>
 #include <linux/security.h>
 
-int sysctl_unix_max_dgram_qlen __read_mostly = 10;
-
 static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
 static DEFINE_SPINLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
@@ -127,32 +125,6 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define UNIX_ABSTRACT(sk)      (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
 
-static struct sock *first_unix_socket(int *i)
-{
-       for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
-               if (!hlist_empty(&unix_socket_table[*i]))
-                       return __sk_head(&unix_socket_table[*i]);
-       }
-       return NULL;
-}
-
-static struct sock *next_unix_socket(int *i, struct sock *s)
-{
-       struct sock *next = sk_next(s);
-       /* More in this chain? */
-       if (next)
-               return next;
-       /* Look for next non-empty chain. */
-       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
-               if (!hlist_empty(&unix_socket_table[*i]))
-                       return __sk_head(&unix_socket_table[*i]);
-       }
-       return NULL;
-}
-
-#define forall_unix_sockets(i, s) \
-       for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s)))
-
 #ifdef CONFIG_SECURITY_NETWORK
 static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
 {
@@ -270,7 +242,8 @@ static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
        spin_unlock(&unix_table_lock);
 }
 
-static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
+static struct sock *__unix_find_socket_byname(struct net *net,
+                                             struct sockaddr_un *sunname,
                                              int len, int type, unsigned hash)
 {
        struct sock *s;
@@ -279,6 +252,9 @@ static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
        sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
                struct unix_sock *u = unix_sk(s);
 
+               if (s->sk_net != net)
+                       continue;
+
                if (u->addr->len == len &&
                    !memcmp(u->addr->name, sunname, len))
                        goto found;
@@ -288,21 +264,22 @@ found:
        return s;
 }
 
-static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
+static inline struct sock *unix_find_socket_byname(struct net *net,
+                                                  struct sockaddr_un *sunname,
                                                   int len, int type,
                                                   unsigned hash)
 {
        struct sock *s;
 
        spin_lock(&unix_table_lock);
-       s = __unix_find_socket_byname(sunname, len, type, hash);
+       s = __unix_find_socket_byname(net, sunname, len, type, hash);
        if (s)
                sock_hold(s);
        spin_unlock(&unix_table_lock);
        return s;
 }
 
-static struct sock *unix_find_socket_byinode(struct inode *i)
+static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
 {
        struct sock *s;
        struct hlist_node *node;
@@ -312,6 +289,9 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
                    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
                struct dentry *dentry = unix_sk(s)->dentry;
 
+               if (s->sk_net != net)
+                       continue;
+
                if(dentry && dentry->d_inode == i)
                {
                        sock_hold(s);
@@ -335,7 +315,7 @@ static void unix_write_space(struct sock *sk)
        if (unix_writable(sk)) {
                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
                        wake_up_interruptible_sync(sk->sk_sleep);
-               sk_wake_async(sk, 2, POLL_OUT);
+               sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
        }
        read_unlock(&sk->sk_callback_lock);
 }
@@ -421,7 +401,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
                        unix_state_unlock(skpair);
                        skpair->sk_state_change(skpair);
                        read_lock(&skpair->sk_callback_lock);
-                       sk_wake_async(skpair,1,POLL_HUP);
+                       sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
                        read_unlock(&skpair->sk_callback_lock);
                }
                sock_put(skpair); /* It may now die */
@@ -612,7 +592,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
                                &af_unix_sk_receive_queue_lock_key);
 
        sk->sk_write_space      = unix_write_space;
-       sk->sk_max_ack_backlog  = sysctl_unix_max_dgram_qlen;
+       sk->sk_max_ack_backlog  = net->unx.sysctl_max_dgram_qlen;
        sk->sk_destruct         = unix_sock_destructor;
        u         = unix_sk(sk);
        u->dentry = NULL;
@@ -631,9 +611,6 @@ out:
 
 static int unix_create(struct net *net, struct socket *sock, int protocol)
 {
-       if (net != &init_net)
-               return -EAFNOSUPPORT;
-
        if (protocol && protocol != PF_UNIX)
                return -EPROTONOSUPPORT;
 
@@ -677,6 +654,7 @@ static int unix_release(struct socket *sock)
 static int unix_autobind(struct socket *sock)
 {
        struct sock *sk = sock->sk;
+       struct net *net = sk->sk_net;
        struct unix_sock *u = unix_sk(sk);
        static u32 ordernum = 1;
        struct unix_address * addr;
@@ -703,7 +681,7 @@ retry:
        spin_lock(&unix_table_lock);
        ordernum = (ordernum+1)&0xFFFFF;
 
-       if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
+       if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
                                      addr->hash)) {
                spin_unlock(&unix_table_lock);
                /* Sanity yield. It is unusual case, but yet... */
@@ -723,7 +701,8 @@ out:        mutex_unlock(&u->readlock);
        return err;
 }
 
-static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
+static struct sock *unix_find_other(struct net *net,
+                                   struct sockaddr_un *sunname, int len,
                                    int type, unsigned hash, int *error)
 {
        struct sock *u;
@@ -741,7 +720,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
                err = -ECONNREFUSED;
                if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
                        goto put_fail;
-               u=unix_find_socket_byinode(nd.dentry->d_inode);
+               u=unix_find_socket_byinode(net, nd.dentry->d_inode);
                if (!u)
                        goto put_fail;
 
@@ -757,7 +736,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
                }
        } else {
                err = -ECONNREFUSED;
-               u=unix_find_socket_byname(sunname, len, type, hash);
+               u=unix_find_socket_byname(net, sunname, len, type, hash);
                if (u) {
                        struct dentry *dentry;
                        dentry = unix_sk(u)->dentry;
@@ -779,6 +758,7 @@ fail:
 static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sock *sk = sock->sk;
+       struct net *net = sk->sk_net;
        struct unix_sock *u = unix_sk(sk);
        struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
        struct dentry * dentry = NULL;
@@ -853,7 +833,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 
        if (!sunaddr->sun_path[0]) {
                err = -EADDRINUSE;
-               if (__unix_find_socket_byname(sunaddr, addr_len,
+               if (__unix_find_socket_byname(net, sunaddr, addr_len,
                                              sk->sk_type, hash)) {
                        unix_release_addr(addr);
                        goto out_unlock;
@@ -919,6 +899,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                              int alen, int flags)
 {
        struct sock *sk = sock->sk;
+       struct net *net = sk->sk_net;
        struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
        struct sock *other;
        unsigned hash;
@@ -935,7 +916,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
                        goto out;
 
 restart:
-               other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
+               other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
                if (!other)
                        goto out;
 
@@ -1015,6 +996,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 {
        struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
        struct sock *sk = sock->sk;
+       struct net *net = sk->sk_net;
        struct unix_sock *u = unix_sk(sk), *newu, *otheru;
        struct sock *newsk = NULL;
        struct sock *other = NULL;
@@ -1054,7 +1036,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 
 restart:
        /*  Find listening sock. */
-       other = unix_find_other(sunaddr, addr_len, sk->sk_type, hash, &err);
+       other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
        if (!other)
                goto out;
 
@@ -1330,6 +1312,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
 {
        struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
        struct sock *sk = sock->sk;
+       struct net *net = sk->sk_net;
        struct unix_sock *u = unix_sk(sk);
        struct sockaddr_un *sunaddr=msg->msg_name;
        struct sock *other = NULL;
@@ -1393,7 +1376,7 @@ restart:
                if (sunaddr == NULL)
                        goto out_free;
 
-               other = unix_find_other(sunaddr, namelen, sk->sk_type,
+               other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
                                        hash, &err);
                if (other==NULL)
                        goto out_free;
@@ -1915,9 +1898,9 @@ static int unix_shutdown(struct socket *sock, int mode)
                        other->sk_state_change(other);
                        read_lock(&other->sk_callback_lock);
                        if (peer_mode == SHUTDOWN_MASK)
-                               sk_wake_async(other,1,POLL_HUP);
+                               sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
                        else if (peer_mode & RCV_SHUTDOWN)
-                               sk_wake_async(other,1,POLL_IN);
+                               sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
                        read_unlock(&other->sk_callback_lock);
                }
                if (other)
@@ -2006,12 +1989,41 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
 
 
 #ifdef CONFIG_PROC_FS
-static struct sock *unix_seq_idx(int *iter, loff_t pos)
+static struct sock *first_unix_socket(int *i)
+{
+       for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
+               if (!hlist_empty(&unix_socket_table[*i]))
+                       return __sk_head(&unix_socket_table[*i]);
+       }
+       return NULL;
+}
+
+static struct sock *next_unix_socket(int *i, struct sock *s)
+{
+       struct sock *next = sk_next(s);
+       /* More in this chain? */
+       if (next)
+               return next;
+       /* Look for next non-empty chain. */
+       for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
+               if (!hlist_empty(&unix_socket_table[*i]))
+                       return __sk_head(&unix_socket_table[*i]);
+       }
+       return NULL;
+}
+
+struct unix_iter_state {
+       struct seq_net_private p;
+       int i;
+};
+static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
 {
        loff_t off = 0;
        struct sock *s;
 
-       for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
+       for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
+               if (s->sk_net != iter->p.net)
+                       continue;
                if (off == pos)
                        return s;
                ++off;
@@ -2021,21 +2033,30 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos)
 
 
 static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
+       __acquires(unix_table_lock)
 {
+       struct unix_iter_state *iter = seq->private;
        spin_lock(&unix_table_lock);
-       return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
+       return *pos ? unix_seq_idx(iter, *pos - 1) : ((void *) 1);
 }
 
 static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
+       struct unix_iter_state *iter = seq->private;
+       struct sock *sk = v;
        ++*pos;
 
        if (v == (void *)1)
-               return first_unix_socket(seq->private);
-       return next_unix_socket(seq->private, v);
+               sk = first_unix_socket(&iter->i);
+       else
+               sk = next_unix_socket(&iter->i, sk);
+       while (sk && (sk->sk_net != iter->p.net))
+               sk = next_unix_socket(&iter->i, sk);
+       return sk;
 }
 
 static void unix_seq_stop(struct seq_file *seq, void *v)
+       __releases(unix_table_lock)
 {
        spin_unlock(&unix_table_lock);
 }
@@ -2094,7 +2115,8 @@ static const struct seq_operations unix_seq_ops = {
 
 static int unix_seq_open(struct inode *inode, struct file *file)
 {
-       return seq_open_private(file, &unix_seq_ops, sizeof(int));
+       return seq_open_net(inode, file, &unix_seq_ops,
+                           sizeof(struct unix_iter_state));
 }
 
 static const struct file_operations unix_seq_fops = {
@@ -2102,7 +2124,7 @@ static const struct file_operations unix_seq_fops = {
        .open           = unix_seq_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
-       .release        = seq_release_private,
+       .release        = seq_release_net,
 };
 
 #endif
@@ -2113,6 +2135,37 @@ static struct net_proto_family unix_family_ops = {
        .owner  = THIS_MODULE,
 };
 
+
+static int unix_net_init(struct net *net)
+{
+       int error = -ENOMEM;
+
+       net->unx.sysctl_max_dgram_qlen = 10;
+       if (unix_sysctl_register(net))
+               goto out;
+
+#ifdef CONFIG_PROC_FS
+       if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops)) {
+               unix_sysctl_unregister(net);
+               goto out;
+       }
+#endif
+       error = 0;
+out:
+       return 0;
+}
+
+static void unix_net_exit(struct net *net)
+{
+       unix_sysctl_unregister(net);
+       proc_net_remove(net, "unix");
+}
+
+static struct pernet_operations unix_net_ops = {
+       .init = unix_net_init,
+       .exit = unix_net_exit,
+};
+
 static int __init af_unix_init(void)
 {
        int rc = -1;
@@ -2128,10 +2181,7 @@ static int __init af_unix_init(void)
        }
 
        sock_register(&unix_family_ops);
-#ifdef CONFIG_PROC_FS
-       proc_net_fops_create(&init_net, "unix", 0, &unix_seq_fops);
-#endif
-       unix_sysctl_register();
+       register_pernet_subsys(&unix_net_ops);
 out:
        return rc;
 }
@@ -2139,9 +2189,8 @@ out:
 static void __exit af_unix_exit(void)
 {
        sock_unregister(PF_UNIX);
-       unix_sysctl_unregister();
-       proc_net_remove(&init_net, "unix");
        proto_unregister(&unix_proto);
+       unregister_pernet_subsys(&unix_net_ops);
 }
 
 module_init(af_unix_init);
index eb0bd57ebadac12b613e0881f9b6566aa0185cc6..77513d7e35f2522251452754deaa4c1b949a2ed3 100644 (file)
@@ -18,7 +18,7 @@ static ctl_table unix_table[] = {
        {
                .ctl_name       = NET_UNIX_MAX_DGRAM_QLEN,
                .procname       = "max_dgram_qlen",
-               .data           = &sysctl_unix_max_dgram_qlen,
+               .data           = &init_net.unx.sysctl_max_dgram_qlen,
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = &proc_dointvec
@@ -26,35 +26,39 @@ static ctl_table unix_table[] = {
        { .ctl_name = 0 }
 };
 
-static ctl_table unix_net_table[] = {
-       {
-               .ctl_name       = NET_UNIX,
-               .procname       = "unix",
-               .mode           = 0555,
-               .child          = unix_table
-       },
-       { .ctl_name = 0 }
+static struct ctl_path unix_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "unix", .ctl_name = NET_UNIX, },
+       { },
 };
 
-static ctl_table unix_root_table[] = {
-       {
-               .ctl_name       = CTL_NET,
-               .procname       = "net",
-               .mode           = 0555,
-               .child          = unix_net_table
-       },
-       { .ctl_name = 0 }
-};
+int unix_sysctl_register(struct net *net)
+{
+       struct ctl_table *table;
 
-static struct ctl_table_header * unix_sysctl_header;
+       table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL);
+       if (table == NULL)
+               goto err_alloc;
 
-void unix_sysctl_register(void)
-{
-       unix_sysctl_header = register_sysctl_table(unix_root_table);
+       table[0].data = &net->unx.sysctl_max_dgram_qlen;
+       net->unx.ctl = register_net_sysctl_table(net, unix_path, table);
+       if (net->unx.ctl == NULL)
+               goto err_reg;
+
+       return 0;
+
+err_reg:
+       kfree(table);
+err_alloc:
+       return -ENOMEM;
 }
 
-void unix_sysctl_unregister(void)
+void unix_sysctl_unregister(struct net *net)
 {
-       unregister_sysctl_table(unix_sysctl_header);
+       struct ctl_table *table;
+
+       table = net->unx.ctl->ctl_table_arg;
+       unregister_sysctl_table(net->unx.ctl);
+       kfree(table);
 }
 
index 6426055a8be01c5e7bd44c981827bc845d537aa3..79270903bda6f2bb02553baff2b71137d87bdfd2 100644 (file)
@@ -6,13 +6,13 @@ config NL80211
        depends on CFG80211
        default y
        ---help---
-         This option turns on the new netlink interface
-         (nl80211) support in cfg80211.
+         This option turns on the new netlink interface
+         (nl80211) support in cfg80211.
 
-         If =n, drivers using mac80211 will be configured via
-         wireless extension support provided by that subsystem.
+         If =n, drivers using mac80211 will be configured via
+         wireless extension support provided by that subsystem.
 
-         If unsure, say Y.
+         If unsure, say Y.
 
 config WIRELESS_EXT
        bool "Wireless extensions"
index febc33bc9c09f644e21a37c1eebebf0c07b04e5b..cfc5fc5f9e753a133a90e06fcdfd10c7b95075b8 100644 (file)
@@ -184,6 +184,9 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
        struct cfg80211_registered_device *drv;
        int alloc_size;
 
+       WARN_ON(!ops->add_key && ops->del_key);
+       WARN_ON(ops->add_key && !ops->del_key);
+
        alloc_size = sizeof(*drv) + sizeof_priv;
 
        drv = kzalloc(alloc_size, GFP_KERNEL);
index 48b0d453e4e161cb243130f295cfd0573bd9874d..e3a214f63f9178e6689c2749ba7b275795718652 100644 (file)
@@ -61,6 +61,27 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
        [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
        [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
+
+       [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
+
+       [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
+                                   .len = WLAN_MAX_KEY_LEN },
+       [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
+       [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
+       [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
+
+       [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
+       [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
+       [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
+                                      .len = IEEE80211_MAX_DATA_LEN },
+       [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
+                                      .len = IEEE80211_MAX_DATA_LEN },
+       [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
+       [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
+       [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
+       [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
+                                              .len = NL80211_MAX_SUPP_RATES },
+       [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
 };
 
 /* message building helper */
@@ -335,6 +356,655 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+struct get_key_cookie {
+       struct sk_buff *msg;
+       int error;
+};
+
+static void get_key_callback(void *c, struct key_params *params)
+{
+       struct get_key_cookie *cookie = c;
+
+       if (params->key)
+               NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
+                       params->key_len, params->key);
+
+       if (params->seq)
+               NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
+                       params->seq_len, params->seq);
+
+       if (params->cipher)
+               NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
+                           params->cipher);
+
+       return;
+ nla_put_failure:
+       cookie->error = 1;
+}
+
+static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       u8 key_idx = 0;
+       u8 *mac_addr = NULL;
+       struct get_key_cookie cookie = {
+               .error = 0,
+       };
+       void *hdr;
+       struct sk_buff *msg;
+
+       if (info->attrs[NL80211_ATTR_KEY_IDX])
+               key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+
+       if (key_idx > 3)
+               return -EINVAL;
+
+       if (info->attrs[NL80211_ATTR_MAC])
+               mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->get_key) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!msg) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+                            NL80211_CMD_NEW_KEY);
+
+       if (IS_ERR(hdr)) {
+               err = PTR_ERR(hdr);
+               goto out;
+       }
+
+       cookie.msg = msg;
+
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
+       if (mac_addr)
+               NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+
+       rtnl_lock();
+       err = drv->ops->get_key(&drv->wiphy, dev, key_idx, mac_addr,
+                               &cookie, get_key_callback);
+       rtnl_unlock();
+
+       if (err)
+               goto out;
+
+       if (cookie.error)
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+       err = genlmsg_unicast(msg, info->snd_pid);
+       goto out;
+
+ nla_put_failure:
+       err = -ENOBUFS;
+       nlmsg_free(msg);
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       u8 key_idx;
+
+       if (!info->attrs[NL80211_ATTR_KEY_IDX])
+               return -EINVAL;
+
+       key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+
+       if (key_idx > 3)
+               return -EINVAL;
+
+       /* currently only support setting default key */
+       if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])
+               return -EINVAL;
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->set_default_key) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->set_default_key(&drv->wiphy, dev, key_idx);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       struct key_params params;
+       u8 key_idx = 0;
+       u8 *mac_addr = NULL;
+
+       memset(&params, 0, sizeof(params));
+
+       if (!info->attrs[NL80211_ATTR_KEY_CIPHER])
+               return -EINVAL;
+
+       if (info->attrs[NL80211_ATTR_KEY_DATA]) {
+               params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
+               params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
+       }
+
+       if (info->attrs[NL80211_ATTR_KEY_IDX])
+               key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+
+       params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
+
+       if (info->attrs[NL80211_ATTR_MAC])
+               mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       if (key_idx > 3)
+               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;
+       default:
+               return -EINVAL;
+       }
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->add_key) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->add_key(&drv->wiphy, dev, key_idx, mac_addr, &params);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       u8 key_idx = 0;
+       u8 *mac_addr = NULL;
+
+       if (info->attrs[NL80211_ATTR_KEY_IDX])
+               key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
+
+       if (key_idx > 3)
+               return -EINVAL;
+
+       if (info->attrs[NL80211_ATTR_MAC])
+               mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->del_key) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
+{
+        int (*call)(struct wiphy *wiphy, struct net_device *dev,
+                   struct beacon_parameters *info);
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       struct beacon_parameters params;
+       int haveinfo = 0;
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       switch (info->genlhdr->cmd) {
+       case NL80211_CMD_NEW_BEACON:
+               /* these are required for NEW_BEACON */
+               if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
+                   !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
+                   !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
+                       err = -EINVAL;
+                       goto out;
+               }
+
+               call = drv->ops->add_beacon;
+               break;
+       case NL80211_CMD_SET_BEACON:
+               call = drv->ops->set_beacon;
+               break;
+       default:
+               WARN_ON(1);
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (!call) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       memset(&params, 0, sizeof(params));
+
+       if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
+               params.interval =
+                   nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+               haveinfo = 1;
+       }
+
+       if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
+               params.dtim_period =
+                   nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
+               haveinfo = 1;
+       }
+
+       if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
+               params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+               params.head_len =
+                   nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
+               haveinfo = 1;
+       }
+
+       if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
+               params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
+               params.tail_len =
+                   nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
+               haveinfo = 1;
+       }
+
+       if (!haveinfo) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = call(&drv->wiphy, dev, &params);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->del_beacon) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->del_beacon(&drv->wiphy, dev);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+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 },
+};
+
+static int parse_station_flags(struct nlattr *nla, u32 *staflags)
+{
+       struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
+       int flag;
+
+       *staflags = 0;
+
+       if (!nla)
+               return 0;
+
+       if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
+                            nla, sta_flags_policy))
+               return -EINVAL;
+
+       *staflags = STATION_FLAG_CHANGED;
+
+       for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
+               if (flags[flag])
+                       *staflags |= (1<<flag);
+
+       return 0;
+}
+
+static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
+                               int flags, struct net_device *dev,
+                               u8 *mac_addr, struct station_stats *stats)
+{
+       void *hdr;
+       struct nlattr *statsattr;
+
+       hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
+       if (!hdr)
+               return -1;
+
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+
+       statsattr = nla_nest_start(msg, NL80211_ATTR_STA_STATS);
+       if (!statsattr)
+               goto nla_put_failure;
+       if (stats->filled & STATION_STAT_INACTIVE_TIME)
+               NLA_PUT_U32(msg, NL80211_STA_STAT_INACTIVE_TIME,
+                           stats->inactive_time);
+       if (stats->filled & STATION_STAT_RX_BYTES)
+               NLA_PUT_U32(msg, NL80211_STA_STAT_RX_BYTES,
+                           stats->rx_bytes);
+       if (stats->filled & STATION_STAT_TX_BYTES)
+               NLA_PUT_U32(msg, NL80211_STA_STAT_TX_BYTES,
+                           stats->tx_bytes);
+
+       nla_nest_end(msg, statsattr);
+
+       return genlmsg_end(msg, hdr);
+
+ nla_put_failure:
+       return genlmsg_cancel(msg, hdr);
+}
+
+
+static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       struct station_stats stats;
+       struct sk_buff *msg;
+       u8 *mac_addr = NULL;
+
+       memset(&stats, 0, sizeof(stats));
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->get_station) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->get_station(&drv->wiphy, dev, mac_addr, &stats);
+       rtnl_unlock();
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!msg)
+               goto out;
+
+       if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
+                                dev, mac_addr, &stats) < 0)
+               goto out_free;
+
+       err = genlmsg_unicast(msg, info->snd_pid);
+       goto out;
+
+ out_free:
+       nlmsg_free(msg);
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+/*
+ * Get vlan interface making sure it is on the right wiphy.
+ */
+static int get_vlan(struct nlattr *vlanattr,
+                   struct cfg80211_registered_device *rdev,
+                   struct net_device **vlan)
+{
+       *vlan = NULL;
+
+       if (vlanattr) {
+               *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr));
+               if (!*vlan)
+                       return -ENODEV;
+               if (!(*vlan)->ieee80211_ptr)
+                       return -EINVAL;
+               if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       struct station_parameters params;
+       u8 *mac_addr = NULL;
+
+       memset(&params, 0, sizeof(params));
+
+       params.listen_interval = -1;
+
+       if (info->attrs[NL80211_ATTR_STA_AID])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
+               params.supported_rates =
+                       nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
+               params.supported_rates_len =
+                       nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
+       }
+
+       if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
+               params.listen_interval =
+                   nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
+
+       if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
+                               &params.station_flags))
+               return -EINVAL;
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+       if (err)
+               goto out;
+
+       if (!drv->ops->change_station) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->change_station(&drv->wiphy, dev, mac_addr, &params);
+       rtnl_unlock();
+
+ out:
+       if (params.vlan)
+               dev_put(params.vlan);
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       struct station_parameters params;
+       u8 *mac_addr = NULL;
+
+       memset(&params, 0, sizeof(params));
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_STA_AID])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
+               return -EINVAL;
+
+       mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+       params.supported_rates =
+               nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
+       params.supported_rates_len =
+               nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
+       params.listen_interval =
+               nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
+       params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
+
+       if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
+                               &params.station_flags))
+               return -EINVAL;
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
+       if (err)
+               goto out;
+
+       if (!drv->ops->add_station) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->add_station(&drv->wiphy, dev, mac_addr, &params);
+       rtnl_unlock();
+
+ out:
+       if (params.vlan)
+               dev_put(params.vlan);
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
+static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       int err;
+       struct net_device *dev;
+       u8 *mac_addr = NULL;
+
+       if (info->attrs[NL80211_ATTR_MAC])
+               mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       err = get_drv_dev_by_info_ifindex(info, &drv, &dev);
+       if (err)
+               return err;
+
+       if (!drv->ops->del_station) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       rtnl_lock();
+       err = drv->ops->del_station(&drv->wiphy, dev, mac_addr);
+       rtnl_unlock();
+
+ out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+       return err;
+}
+
 static struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_WIPHY,
@@ -374,6 +1044,73 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
        },
+       {
+               .cmd = NL80211_CMD_GET_KEY,
+               .doit = nl80211_get_key,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_SET_KEY,
+               .doit = nl80211_set_key,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_NEW_KEY,
+               .doit = nl80211_new_key,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_DEL_KEY,
+               .doit = nl80211_del_key,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_SET_BEACON,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .doit = nl80211_addset_beacon,
+       },
+       {
+               .cmd = NL80211_CMD_NEW_BEACON,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .doit = nl80211_addset_beacon,
+       },
+       {
+               .cmd = NL80211_CMD_DEL_BEACON,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .doit = nl80211_del_beacon,
+       },
+       {
+               .cmd = NL80211_CMD_GET_STATION,
+               .doit = nl80211_get_station,
+               /* TODO: implement dumpit */
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_SET_STATION,
+               .doit = nl80211_set_station,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_NEW_STATION,
+               .doit = nl80211_new_station,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_DEL_STATION,
+               .doit = nl80211_del_station,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
 };
 
 /* multicast groups */
index 47e80cc2077c23fd207ce01478f8761f4c0baa05..2c569b63e7d8f07dfca46b9e56c463d0bf13dd5b 100644 (file)
@@ -417,20 +417,6 @@ static const int event_type_size[] = {
        IW_EV_QUAL_LEN,                 /* IW_HEADER_TYPE_QUAL */
 };
 
-/* Size (in bytes) of various events, as packed */
-static const int event_type_pk_size[] = {
-       IW_EV_LCP_PK_LEN,               /* IW_HEADER_TYPE_NULL */
-       0,
-       IW_EV_CHAR_PK_LEN,              /* IW_HEADER_TYPE_CHAR */
-       0,
-       IW_EV_UINT_PK_LEN,              /* IW_HEADER_TYPE_UINT */
-       IW_EV_FREQ_PK_LEN,              /* IW_HEADER_TYPE_FREQ */
-       IW_EV_ADDR_PK_LEN,              /* IW_HEADER_TYPE_ADDR */
-       0,
-       IW_EV_POINT_PK_LEN,             /* Without variable payload */
-       IW_EV_PARAM_PK_LEN,             /* IW_HEADER_TYPE_PARAM */
-       IW_EV_QUAL_PK_LEN,              /* IW_HEADER_TYPE_QUAL */
-};
 
 /************************ COMMON SUBROUTINES ************************/
 /*
@@ -673,26 +659,8 @@ static const struct seq_operations wireless_seq_ops = {
 
 static int wireless_seq_open(struct inode *inode, struct file *file)
 {
-       struct seq_file *seq;
-       int res;
-       res = seq_open(file, &wireless_seq_ops);
-       if (!res) {
-               seq = file->private_data;
-               seq->private = get_proc_net(inode);
-               if (!seq->private) {
-                       seq_release(inode, file);
-                       res = -ENXIO;
-               }
-       }
-       return res;
-}
-
-static int wireless_seq_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-       struct net *net = seq->private;
-       put_net(net);
-       return seq_release(inode, file);
+       return seq_open_net(inode, file, &wireless_seq_ops,
+                           sizeof(struct seq_net_private));
 }
 
 static const struct file_operations wireless_seq_fops = {
@@ -700,7 +668,7 @@ static const struct file_operations wireless_seq_fops = {
        .open    = wireless_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = wireless_seq_release,
+       .release = seq_release_net,
 };
 
 int wext_proc_init(struct net *net)
@@ -1137,7 +1105,7 @@ static void wireless_nlevent_process(unsigned long data)
        struct sk_buff *skb;
 
        while ((skb = skb_dequeue(&wireless_nlevent_queue)))
-               rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
+               rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
 }
 
 static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0);
@@ -1189,6 +1157,9 @@ static void rtmsg_iwinfo(struct net_device *dev, char *event, int event_len)
        struct sk_buff *skb;
        int err;
 
+       if (dev->nd_net != &init_net)
+               return;
+
        skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!skb)
                return;
index 92cfe8e3e0b8d24133b6e5e07cafa6d5d27328e2..07fad7ccf83204c137b90fb0bfc906dd25a0dfbf 100644 (file)
@@ -83,9 +83,9 @@ struct compat_x25_subscrip_struct {
 int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
                  struct x25_address *calling_addr)
 {
-       int called_len, calling_len;
+       unsigned int called_len, calling_len;
        char *called, *calling;
-       int i;
+       unsigned int i;
 
        called_len  = (*p >> 0) & 0x0F;
        calling_len = (*p >> 4) & 0x0F;
index a59b77f18234d498748d8dac63f55889eb742f03..6ebda25c24e96a4471ee7eb8aa3db69b2411075d 100644 (file)
@@ -84,29 +84,15 @@ static struct ctl_table x25_table[] = {
        { 0, },
 };
 
-static struct ctl_table x25_dir_table[] = {
-       {
-               .ctl_name =     NET_X25,
-               .procname =     "x25",
-               .mode =         0555,
-               .child =        x25_table,
-       },
-       { 0, },
-};
-
-static struct ctl_table x25_root_table[] = {
-       {
-               .ctl_name =     CTL_NET,
-               .procname =     "net",
-               .mode =         0555,
-               .child =        x25_dir_table,
-       },
-       { 0, },
+static struct ctl_path x25_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "x25", .ctl_name = NET_X25, },
+       { }
 };
 
 void __init x25_register_sysctl(void)
 {
-       x25_table_header = register_sysctl_table(x25_root_table);
+       x25_table_header = register_sysctl_paths(x25_path, x25_table);
 }
 
 void x25_unregister_sysctl(void)
index dec404afa11333830ac69330ce2d6ef4a7fa357a..a21f6646eb3a85cd1275708ba53960ed085402da 100644 (file)
@@ -205,9 +205,7 @@ int x25_create_facilities(unsigned char *buffer,
        }
 
        if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) {
-               unsigned bytecount = (dte_facs->calling_len % 2) ?
-                                       dte_facs->calling_len / 2 + 1 :
-                                       dte_facs->calling_len / 2;
+               unsigned bytecount = (dte_facs->calling_len + 1) >> 1;
                *p++ = X25_FAC_CALLING_AE;
                *p++ = 1 + bytecount;
                *p++ = dte_facs->calling_len;
index 34478035e05edd64131525b438eab2bedc55791c..056a55f3a8719f9bc6e7ff2336b16cc5e6994292 100644 (file)
@@ -12,7 +12,7 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
-struct list_head x25_forward_list = LIST_HEAD_INIT(x25_forward_list);
+LIST_HEAD(x25_forward_list);
 DEFINE_RWLOCK(x25_forward_list_lock);
 
 int x25_forward_call(struct x25_address *dest_addr, struct x25_neigh *from,
index 1c88762c27943858bbc55394eb0fec6cbf053932..7d7c3abf38b573fa64f1bb35026dc5bf80cdcd3c 100644 (file)
@@ -247,7 +247,7 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                                        break;
                                }
                                if (atomic_read(&sk->sk_rmem_alloc) >
-                                   (sk->sk_rcvbuf / 2))
+                                   (sk->sk_rcvbuf >> 1))
                                        x25->condition |= X25_COND_OWN_RX_BUSY;
                        }
                        /*
index 741ce95d4ad156b65f12a5693776a20a60d91d03..e4e1b6e495386c6cb1673a9e29143e1681bea6f6 100644 (file)
@@ -30,7 +30,7 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
-static struct list_head x25_neigh_list = LIST_HEAD_INIT(x25_neigh_list);
+static LIST_HEAD(x25_neigh_list);
 static DEFINE_RWLOCK(x25_neigh_list_lock);
 
 static void x25_t20timer_expiry(unsigned long);
@@ -247,10 +247,7 @@ void x25_link_device_up(struct net_device *dev)
                return;
 
        skb_queue_head_init(&nb->queue);
-
-       init_timer(&nb->t20timer);
-       nb->t20timer.data     = (unsigned long)nb;
-       nb->t20timer.function = &x25_t20timer_expiry;
+       setup_timer(&nb->t20timer, x25_t20timer_expiry, (unsigned long)nb);
 
        dev_hold(dev);
        nb->dev      = dev;
index 7d55e50c936f9a2fe11daeba85ece6099815b858..3f52b09bed033fbb8f77e4b37342fd757183744d 100644 (file)
@@ -41,6 +41,7 @@ found:
 }
 
 static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
+       __acquires(x25_route_list_lock)
 {
        loff_t l = *pos;
 
@@ -70,6 +71,7 @@ out:
 }
 
 static void x25_seq_route_stop(struct seq_file *seq, void *v)
+       __releases(x25_route_list_lock)
 {
        read_unlock_bh(&x25_route_list_lock);
 }
@@ -105,6 +107,7 @@ found:
 }
 
 static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
+       __acquires(x25_list_lock)
 {
        loff_t l = *pos;
 
@@ -127,6 +130,7 @@ out:
 }
 
 static void x25_seq_socket_stop(struct seq_file *seq, void *v)
+       __releases(x25_list_lock)
 {
        read_unlock_bh(&x25_list_lock);
 }
@@ -183,6 +187,7 @@ found:
 }
 
 static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
+       __acquires(x25_forward_list_lock)
 {
        loff_t l = *pos;
 
@@ -213,6 +218,7 @@ out:
 }
 
 static void x25_seq_forward_stop(struct seq_file *seq, void *v)
+       __releases(x25_forward_list_lock)
 {
        read_unlock_bh(&x25_forward_list_lock);
 }
@@ -287,7 +293,7 @@ static const struct file_operations x25_seq_route_fops = {
        .release        = seq_release,
 };
 
-static struct file_operations x25_seq_forward_fops = {
+static const struct file_operations x25_seq_forward_fops = {
        .owner          = THIS_MODULE,
        .open           = x25_seq_forward_open,
        .read           = seq_read,
index 86b5b4da097c5c17065b17c87160555b2fa94ea0..2c999ccf504a82741961e6a2420ccb07fef13b03 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <net/x25.h>
 
-struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
+LIST_HEAD(x25_route_list);
 DEFINE_RWLOCK(x25_route_list_lock);
 
 /*
index 8d6220aa5d0fd5748814659e5a2d7068c91cdf57..511a5986af3e65b5a55153bfd6ad896d70994934 100644 (file)
@@ -359,7 +359,7 @@ void x25_check_rbuf(struct sock *sk)
 {
        struct x25_sock *x25 = x25_sk(sk);
 
-       if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf / 2) &&
+       if (atomic_read(&sk->sk_rmem_alloc) < (sk->sk_rcvbuf >> 1) &&
            (x25->condition & X25_COND_OWN_RX_BUSY)) {
                x25->condition &= ~X25_COND_OWN_RX_BUSY;
                x25->condition &= ~X25_COND_ACK_PENDING;
index 2af190dc5b014ef8f544772d188c668e367f3a90..d3e3e54db936a738d13de9756799796b40dc9dc3 100644 (file)
@@ -33,9 +33,7 @@ void x25_init_timers(struct sock *sk)
 {
        struct x25_sock *x25 = x25_sk(sk);
 
-       init_timer(&x25->timer);
-       x25->timer.data     = (unsigned long)sk;
-       x25->timer.function = &x25_timer_expiry;
+       setup_timer(&x25->timer, x25_timer_expiry, (unsigned long)sk);
 
        /* initialized by sock_init_data */
        sk->sk_timer.data     = (unsigned long)sk;
index 577a4f821b9879d580a965092b5372b4f6cd213a..8f9dbec319be471688fdc78a4cea4815809406ba 100644 (file)
@@ -3,6 +3,7 @@
 #
 config XFRM
        bool
+       select CRYPTO
        depends on NET
 
 config XFRM_USER
@@ -35,6 +36,16 @@ config XFRM_MIGRATE
 
          If unsure, say N.
 
+config XFRM_STATISTICS
+       bool "Transformation statistics (EXPERIMENTAL)"
+       depends on XFRM && PROC_FS && EXPERIMENTAL
+       ---help---
+         This statistics is not a SNMP/MIB specification but shows
+         statistics about transformation error (or almost error) factor
+         at packet processing for developer.
+
+         If unsure, say N.
+
 config NET_KEY
        tristate "PF_KEY sockets"
        select XFRM
index 45744a3d3a51ed240e8eee2c780b8837a2ba395e..332cfb0ff566af1e59433e989c1c545929f24e81 100644 (file)
@@ -4,5 +4,6 @@
 
 obj-$(CONFIG_XFRM) := xfrm_policy.o xfrm_state.o xfrm_hash.o \
                      xfrm_input.o xfrm_output.o xfrm_algo.o
+obj-$(CONFIG_XFRM_STATISTICS) += xfrm_proc.o
 obj-$(CONFIG_XFRM_USER) += xfrm_user.o
 
index 1686f64c4352c2ee19d565d54017608474a98b83..b5c5347aed666096c33d0fadbbab0065753ddd08 100644 (file)
@@ -486,7 +486,6 @@ EXPORT_SYMBOL_GPL(xfrm_ealg_get_byidx);
  */
 void xfrm_probe_algs(void)
 {
-#ifdef CONFIG_CRYPTO
        int i, status;
 
        BUG_ON(in_softirq());
@@ -511,7 +510,6 @@ void xfrm_probe_algs(void)
                if (calg_list[i].available != status)
                        calg_list[i].available = status;
        }
-#endif
 }
 EXPORT_SYMBOL_GPL(xfrm_probe_algs);
 
index 55ab5792af56ecdfd2e5cafe0de0cd697246f475..a2023ec52329ef66b95e14dc94f7086e5683e534 100644 (file)
@@ -17,17 +17,14 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz)
        struct hlist_head *n;
 
        if (sz <= PAGE_SIZE)
-               n = kmalloc(sz, GFP_KERNEL);
+               n = kzalloc(sz, GFP_KERNEL);
        else if (hashdist)
-               n = __vmalloc(sz, GFP_KERNEL, PAGE_KERNEL);
+               n = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
        else
                n = (struct hlist_head *)
-                       __get_free_pages(GFP_KERNEL | __GFP_NOWARN,
+                       __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
                                         get_order(sz));
 
-       if (n)
-               memset(n, 0, sz);
-
        return n;
 }
 
index cb97fda1b6dfa196aedea7e091599cb944b61950..039e7019c48a4e56b40354177e553752568f6793 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/netdevice.h>
+#include <net/dst.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 
@@ -81,6 +83,180 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 }
 EXPORT_SYMBOL(xfrm_parse_spi);
 
+int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
+{
+       int err;
+
+       err = x->outer_mode->afinfo->extract_input(x, skb);
+       if (err)
+               return err;
+
+       skb->protocol = x->inner_mode->afinfo->eth_proto;
+       return x->inner_mode->input2(x, skb);
+}
+EXPORT_SYMBOL(xfrm_prepare_input);
+
+int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
+{
+       int err;
+       __be32 seq;
+       struct xfrm_state *x;
+       xfrm_address_t *daddr;
+       unsigned int family;
+       int decaps = 0;
+       int async = 0;
+
+       /* A negative encap_type indicates async resumption. */
+       if (encap_type < 0) {
+               async = 1;
+               x = xfrm_input_state(skb);
+               seq = XFRM_SKB_CB(skb)->seq;
+               goto resume;
+       }
+
+       /* Allocate new secpath or COW existing one. */
+       if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {
+               struct sec_path *sp;
+
+               sp = secpath_dup(skb->sp);
+               if (!sp) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINERROR);
+                       goto drop;
+               }
+               if (skb->sp)
+                       secpath_put(skb->sp);
+               skb->sp = sp;
+       }
+
+       daddr = (xfrm_address_t *)(skb_network_header(skb) +
+                                  XFRM_SPI_SKB_CB(skb)->daddroff);
+       family = XFRM_SPI_SKB_CB(skb)->family;
+
+       seq = 0;
+       if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) {
+               XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+               goto drop;
+       }
+
+       do {
+               if (skb->sp->len == XFRM_MAX_DEPTH) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
+                       goto drop;
+               }
+
+               x = xfrm_state_lookup(daddr, spi, nexthdr, family);
+               if (x == NULL) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINNOSTATES);
+                       xfrm_audit_state_notfound(skb, family, spi, seq);
+                       goto drop;
+               }
+
+               skb->sp->xvec[skb->sp->len++] = x;
+
+               spin_lock(&x->lock);
+               if (unlikely(x->km.state != XFRM_STATE_VALID)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+                       goto drop_unlock;
+               }
+
+               if ((x->encap ? x->encap->encap_type : 0) != encap_type) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEINVALID);
+                       goto drop_unlock;
+               }
+
+               if (x->props.replay_window && xfrm_replay_check(x, skb, seq)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSEQOUTOFWINDOW);
+                       goto drop_unlock;
+               }
+
+               if (xfrm_state_check_expire(x)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEEXPIRED);
+                       goto drop_unlock;
+               }
+
+               spin_unlock(&x->lock);
+
+               XFRM_SKB_CB(skb)->seq = seq;
+
+               nexthdr = x->type->input(x, skb);
+
+               if (nexthdr == -EINPROGRESS)
+                       return 0;
+
+resume:
+               spin_lock(&x->lock);
+               if (nexthdr <= 0) {
+                       if (nexthdr == -EBADMSG) {
+                               xfrm_audit_state_icvfail(x, skb,
+                                                        x->type->proto);
+                               x->stats.integrity_failed++;
+                       }
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEPROTOERROR);
+                       goto drop_unlock;
+               }
+
+               /* only the first xfrm gets the encap type */
+               encap_type = 0;
+
+               if (x->props.replay_window)
+                       xfrm_replay_advance(x, seq);
+
+               x->curlft.bytes += skb->len;
+               x->curlft.packets++;
+
+               spin_unlock(&x->lock);
+
+               XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
+
+               if (x->inner_mode->input(x, skb)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR);
+                       goto drop;
+               }
+
+               if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) {
+                       decaps = 1;
+                       break;
+               }
+
+               /*
+                * We need the inner address.  However, we only get here for
+                * transport mode so the outer address is identical.
+                */
+               daddr = &x->id.daddr;
+               family = x->outer_mode->afinfo->family;
+
+               err = xfrm_parse_spi(skb, nexthdr, &spi, &seq);
+               if (err < 0) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
+                       goto drop;
+               }
+       } while (!err);
+
+       nf_reset(skb);
+
+       if (decaps) {
+               dst_release(skb->dst);
+               skb->dst = NULL;
+               netif_rx(skb);
+               return 0;
+       } else {
+               return x->inner_mode->afinfo->transport_finish(skb, async);
+       }
+
+drop_unlock:
+       spin_unlock(&x->lock);
+drop:
+       kfree_skb(skb);
+       return 0;
+}
+EXPORT_SYMBOL(xfrm_input);
+
+int xfrm_input_resume(struct sk_buff *skb, int nexthdr)
+{
+       return xfrm_input(skb, nexthdr, 0, -1);
+}
+EXPORT_SYMBOL(xfrm_input_resume);
+
 void __init xfrm_input_init(void)
 {
        secpath_cachep = kmem_cache_create("secpath_cache",
index f4bfd6c4565119f9f3be6cb80547922b930b4f73..f4a1047a55737929efd37f989c53fc18adea6b53 100644 (file)
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/netfilter.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <net/dst.h>
 #include <net/xfrm.h>
 
+static int xfrm_output2(struct sk_buff *skb);
+
 static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
-       int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev)
+       struct dst_entry *dst = skb->dst;
+       int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
                - skb_headroom(skb);
 
        if (nhead > 0)
@@ -29,54 +33,63 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
        return 0;
 }
 
-static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
-{
-       int err = xfrm_state_check_expire(x);
-       if (err < 0)
-               goto err;
-       err = xfrm_state_check_space(x, skb);
-err:
-       return err;
-}
-
-int xfrm_output(struct sk_buff *skb)
+static int xfrm_output_one(struct sk_buff *skb, int err)
 {
        struct dst_entry *dst = skb->dst;
        struct xfrm_state *x = dst->xfrm;
-       int err;
 
-       if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               err = skb_checksum_help(skb);
-               if (err)
-                       goto error_nolock;
-       }
+       if (err <= 0)
+               goto resume;
 
        do {
+               err = xfrm_state_check_space(x, skb);
+               if (err) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+                       goto error_nolock;
+               }
+
+               err = x->outer_mode->output(x, skb);
+               if (err) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEMODEERROR);
+                       goto error_nolock;
+               }
+
                spin_lock_bh(&x->lock);
-               err = xfrm_state_check(x, skb);
-               if (err)
+               err = xfrm_state_check_expire(x);
+               if (err) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEEXPIRED);
                        goto error;
+               }
 
                if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
                        XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
+                       if (unlikely(x->replay.oseq == 0)) {
+                               x->replay.oseq--;
+                               xfrm_audit_state_replay_overflow(x, skb);
+                               err = -EOVERFLOW;
+                               goto error;
+                       }
                        if (xfrm_aevent_is_on())
                                xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
                }
 
-               err = x->outer_mode->output(x, skb);
-               if (err)
-                       goto error;
-
                x->curlft.bytes += skb->len;
                x->curlft.packets++;
 
                spin_unlock_bh(&x->lock);
 
                err = x->type->output(x, skb);
-               if (err)
+               if (err == -EINPROGRESS)
+                       goto out_exit;
+
+resume:
+               if (err) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATEPROTOERROR);
                        goto error_nolock;
+               }
 
                if (!(skb->dst = dst_pop(dst))) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
                        err = -EHOSTUNREACH;
                        goto error_nolock;
                }
@@ -86,10 +99,97 @@ int xfrm_output(struct sk_buff *skb)
 
        err = 0;
 
-error_nolock:
+out_exit:
        return err;
 error:
        spin_unlock_bh(&x->lock);
-       goto error_nolock;
+error_nolock:
+       kfree_skb(skb);
+       goto out_exit;
+}
+
+int xfrm_output_resume(struct sk_buff *skb, int err)
+{
+       while (likely((err = xfrm_output_one(skb, err)) == 0)) {
+               struct xfrm_state *x;
+
+               nf_reset(skb);
+
+               err = skb->dst->ops->local_out(skb);
+               if (unlikely(err != 1))
+                       goto out;
+
+               x = skb->dst->xfrm;
+               if (!x)
+                       return dst_output(skb);
+
+               err = nf_hook(x->inner_mode->afinfo->family,
+                             NF_INET_POST_ROUTING, skb,
+                             NULL, skb->dst->dev, xfrm_output2);
+               if (unlikely(err != 1))
+                       goto out;
+       }
+
+       if (err == -EINPROGRESS)
+               err = 0;
+
+out:
+       return err;
+}
+EXPORT_SYMBOL_GPL(xfrm_output_resume);
+
+static int xfrm_output2(struct sk_buff *skb)
+{
+       return xfrm_output_resume(skb, 1);
+}
+
+static int xfrm_output_gso(struct sk_buff *skb)
+{
+       struct sk_buff *segs;
+
+       segs = skb_gso_segment(skb, 0);
+       kfree_skb(skb);
+       if (unlikely(IS_ERR(segs)))
+               return PTR_ERR(segs);
+
+       do {
+               struct sk_buff *nskb = segs->next;
+               int err;
+
+               segs->next = NULL;
+               err = xfrm_output2(segs);
+
+               if (unlikely(err)) {
+                       while ((segs = nskb)) {
+                               nskb = segs->next;
+                               segs->next = NULL;
+                               kfree_skb(segs);
+                       }
+                       return err;
+               }
+
+               segs = nskb;
+       } while (segs);
+
+       return 0;
+}
+
+int xfrm_output(struct sk_buff *skb)
+{
+       int err;
+
+       if (skb_is_gso(skb))
+               return xfrm_output_gso(skb);
+
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               err = skb_checksum_help(skb);
+               if (err) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTERROR);
+                       kfree_skb(skb);
+                       return err;
+               }
+       }
+
+       return xfrm_output2(skb);
 }
 EXPORT_SYMBOL_GPL(xfrm_output);
index 26b846e11bfb3241f268f86c7daa45c872a65164..47219f98053f86217027245dc81b42fbdf4d57e5 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
 #include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/cache.h>
+#include <linux/audit.h>
+#include <net/dst.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
+#ifdef CONFIG_XFRM_STATISTICS
+#include <net/snmp.h>
+#endif
 
 #include "xfrm_hash.h"
 
 int sysctl_xfrm_larval_drop __read_mostly;
 
+#ifdef CONFIG_XFRM_STATISTICS
+DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
+EXPORT_SYMBOL(xfrm_statistics);
+#endif
+
 DEFINE_MUTEX(xfrm_cfg_mutex);
 EXPORT_SYMBOL(xfrm_cfg_mutex);
 
@@ -49,6 +60,7 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
 
 static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
 static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
+static void xfrm_init_pmtu(struct dst_entry *dst);
 
 static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -84,23 +96,27 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
        return 0;
 }
 
-int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
-                   unsigned short family)
+static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
+                                               int family)
 {
-       struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
-       int err = 0;
+       xfrm_address_t *saddr = &x->props.saddr;
+       xfrm_address_t *daddr = &x->id.daddr;
+       struct xfrm_policy_afinfo *afinfo;
+       struct dst_entry *dst;
+
+       if (x->type->flags & XFRM_TYPE_LOCAL_COADDR)
+               saddr = x->coaddr;
+       if (x->type->flags & XFRM_TYPE_REMOTE_COADDR)
+               daddr = x->coaddr;
 
+       afinfo = xfrm_policy_get_afinfo(family);
        if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
+               return ERR_PTR(-EAFNOSUPPORT);
 
-       if (likely(afinfo->dst_lookup != NULL))
-               err = afinfo->dst_lookup(dst, fl);
-       else
-               err = -EINVAL;
+       dst = afinfo->dst_lookup(tos, saddr, daddr);
        xfrm_policy_put_afinfo(afinfo);
-       return err;
+       return dst;
 }
-EXPORT_SYMBOL(xfrm_dst_lookup);
 
 static inline unsigned long make_jiffies(long secs)
 {
@@ -196,9 +212,8 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
                INIT_HLIST_NODE(&policy->byidx);
                rwlock_init(&policy->lock);
                atomic_set(&policy->refcnt, 1);
-               init_timer(&policy->timer);
-               policy->timer.data = (unsigned long)policy;
-               policy->timer.function = xfrm_policy_timer;
+               setup_timer(&policy->timer, xfrm_policy_timer,
+                               (unsigned long)policy);
        }
        return policy;
 }
@@ -206,7 +221,7 @@ EXPORT_SYMBOL(xfrm_policy_alloc);
 
 /* Destroy xfrm_policy: descendant resources must be released to this moment. */
 
-void __xfrm_policy_destroy(struct xfrm_policy *policy)
+void xfrm_policy_destroy(struct xfrm_policy *policy)
 {
        BUG_ON(!policy->dead);
 
@@ -218,7 +233,7 @@ void __xfrm_policy_destroy(struct xfrm_policy *policy)
        security_xfrm_policy_free(policy);
        kfree(policy);
 }
-EXPORT_SYMBOL(__xfrm_policy_destroy);
+EXPORT_SYMBOL(xfrm_policy_destroy);
 
 static void xfrm_policy_gc_kill(struct xfrm_policy *policy)
 {
@@ -1230,24 +1245,185 @@ xfrm_find_bundle(struct flowi *fl, struct xfrm_policy *policy, unsigned short fa
        return x;
 }
 
-/* Allocate chain of dst_entry's, attach known xfrm's, calculate
- * all the metrics... Shortly, bundle a bundle.
- */
+static inline int xfrm_get_tos(struct flowi *fl, int family)
+{
+       struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
+       int tos;
 
-static int
-xfrm_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int nx,
-                  struct flowi *fl, struct dst_entry **dst_p,
-                  unsigned short family)
+       if (!afinfo)
+               return -EINVAL;
+
+       tos = afinfo->get_tos(fl);
+
+       xfrm_policy_put_afinfo(afinfo);
+
+       return tos;
+}
+
+static inline struct xfrm_dst *xfrm_alloc_dst(int family)
 {
-       int err;
        struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
-       if (unlikely(afinfo == NULL))
+       struct xfrm_dst *xdst;
+
+       if (!afinfo)
+               return ERR_PTR(-EINVAL);
+
+       xdst = dst_alloc(afinfo->dst_ops) ?: ERR_PTR(-ENOBUFS);
+
+       xfrm_policy_put_afinfo(afinfo);
+
+       return xdst;
+}
+
+static inline int xfrm_init_path(struct xfrm_dst *path, struct dst_entry *dst,
+                                int nfheader_len)
+{
+       struct xfrm_policy_afinfo *afinfo =
+               xfrm_policy_get_afinfo(dst->ops->family);
+       int err;
+
+       if (!afinfo)
                return -EINVAL;
-       err = afinfo->bundle_create(policy, xfrm, nx, fl, dst_p);
+
+       err = afinfo->init_path(path, dst, nfheader_len);
+
        xfrm_policy_put_afinfo(afinfo);
+
        return err;
 }
 
+static inline int xfrm_fill_dst(struct xfrm_dst *xdst, struct net_device *dev)
+{
+       struct xfrm_policy_afinfo *afinfo =
+               xfrm_policy_get_afinfo(xdst->u.dst.ops->family);
+       int err;
+
+       if (!afinfo)
+               return -EINVAL;
+
+       err = afinfo->fill_dst(xdst, dev);
+
+       xfrm_policy_put_afinfo(afinfo);
+
+       return err;
+}
+
+/* Allocate chain of dst_entry's, attach known xfrm's, calculate
+ * all the metrics... Shortly, bundle a bundle.
+ */
+
+static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
+                                           struct xfrm_state **xfrm, int nx,
+                                           struct flowi *fl,
+                                           struct dst_entry *dst)
+{
+       unsigned long now = jiffies;
+       struct net_device *dev;
+       struct dst_entry *dst_prev = NULL;
+       struct dst_entry *dst0 = NULL;
+       int i = 0;
+       int err;
+       int header_len = 0;
+       int nfheader_len = 0;
+       int trailer_len = 0;
+       int tos;
+       int family = policy->selector.family;
+
+       tos = xfrm_get_tos(fl, family);
+       err = tos;
+       if (tos < 0)
+               goto put_states;
+
+       dst_hold(dst);
+
+       for (; i < nx; i++) {
+               struct xfrm_dst *xdst = xfrm_alloc_dst(family);
+               struct dst_entry *dst1 = &xdst->u.dst;
+
+               err = PTR_ERR(xdst);
+               if (IS_ERR(xdst)) {
+                       dst_release(dst);
+                       goto put_states;
+               }
+
+               if (!dst_prev)
+                       dst0 = dst1;
+               else {
+                       dst_prev->child = dst_clone(dst1);
+                       dst1->flags |= DST_NOHASH;
+               }
+
+               xdst->route = dst;
+               memcpy(&dst1->metrics, &dst->metrics, sizeof(dst->metrics));
+
+               if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
+                       family = xfrm[i]->props.family;
+                       dst = xfrm_dst_lookup(xfrm[i], tos, family);
+                       err = PTR_ERR(dst);
+                       if (IS_ERR(dst))
+                               goto put_states;
+               } else
+                       dst_hold(dst);
+
+               dst1->xfrm = xfrm[i];
+               xdst->genid = xfrm[i]->genid;
+
+               dst1->obsolete = -1;
+               dst1->flags |= DST_HOST;
+               dst1->lastuse = now;
+
+               dst1->input = dst_discard;
+               dst1->output = xfrm[i]->outer_mode->afinfo->output;
+
+               dst1->next = dst_prev;
+               dst_prev = dst1;
+
+               header_len += xfrm[i]->props.header_len;
+               if (xfrm[i]->type->flags & XFRM_TYPE_NON_FRAGMENT)
+                       nfheader_len += xfrm[i]->props.header_len;
+               trailer_len += xfrm[i]->props.trailer_len;
+       }
+
+       dst_prev->child = dst;
+       dst0->path = dst;
+
+       err = -ENODEV;
+       dev = dst->dev;
+       if (!dev)
+               goto free_dst;
+
+       /* Copy neighbout for reachability confirmation */
+       dst0->neighbour = neigh_clone(dst->neighbour);
+
+       xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len);
+       xfrm_init_pmtu(dst_prev);
+
+       for (dst_prev = dst0; dst_prev != dst; dst_prev = dst_prev->child) {
+               struct xfrm_dst *xdst = (struct xfrm_dst *)dst_prev;
+
+               err = xfrm_fill_dst(xdst, dev);
+               if (err)
+                       goto free_dst;
+
+               dst_prev->header_len = header_len;
+               dst_prev->trailer_len = trailer_len;
+               header_len -= xdst->u.dst.xfrm->props.header_len;
+               trailer_len -= xdst->u.dst.xfrm->props.trailer_len;
+       }
+
+out:
+       return dst0;
+
+put_states:
+       for (; i < nx; i++)
+               xfrm_state_put(xfrm[i]);
+free_dst:
+       if (dst0)
+               dst_free(dst0);
+       dst0 = ERR_PTR(err);
+       goto out;
+}
+
 static int inline
 xfrm_dst_alloc_copy(void **target, void *src, int size)
 {
@@ -1319,36 +1495,46 @@ restart:
        if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
                policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
                err = PTR_ERR(policy);
-               if (IS_ERR(policy))
+               if (IS_ERR(policy)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
                        goto dropdst;
+               }
        }
 
        if (!policy) {
                /* To accelerate a bit...  */
                if ((dst_orig->flags & DST_NOXFRM) ||
                    !xfrm_policy_count[XFRM_POLICY_OUT])
-                       return 0;
+                       goto nopol;
 
                policy = flow_cache_lookup(fl, dst_orig->ops->family,
                                           dir, xfrm_policy_lookup);
                err = PTR_ERR(policy);
-               if (IS_ERR(policy))
+               if (IS_ERR(policy)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
                        goto dropdst;
+               }
        }
 
        if (!policy)
-               return 0;
+               goto nopol;
 
        family = dst_orig->ops->family;
-       policy->curlft.use_time = get_seconds();
        pols[0] = policy;
        npols ++;
        xfrm_nr += pols[0]->xfrm_nr;
 
+       err = -ENOENT;
+       if ((flags & XFRM_LOOKUP_ICMP) && !(policy->flags & XFRM_POLICY_ICMP))
+               goto error;
+
+       policy->curlft.use_time = get_seconds();
+
        switch (policy->action) {
        default:
        case XFRM_POLICY_BLOCK:
                /* Prohibit the flow */
+               XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
                err = -EPERM;
                goto error;
 
@@ -1368,6 +1554,7 @@ restart:
                 */
                dst = xfrm_find_bundle(fl, policy, family);
                if (IS_ERR(dst)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
                        err = PTR_ERR(dst);
                        goto error;
                }
@@ -1382,10 +1569,12 @@ restart:
                                                            XFRM_POLICY_OUT);
                        if (pols[1]) {
                                if (IS_ERR(pols[1])) {
+                                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLERROR);
                                        err = PTR_ERR(pols[1]);
                                        goto error;
                                }
                                if (pols[1]->action == XFRM_POLICY_BLOCK) {
+                                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLBLOCK);
                                        err = -EPERM;
                                        goto error;
                                }
@@ -1416,10 +1605,11 @@ restart:
                                /* EREMOTE tells the caller to generate
                                 * a one-shot blackhole route.
                                 */
+                               XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
                                xfrm_pol_put(policy);
                                return -EREMOTE;
                        }
-                       if (err == -EAGAIN && flags) {
+                       if (err == -EAGAIN && (flags & XFRM_LOOKUP_WAIT)) {
                                DECLARE_WAITQUEUE(wait, current);
 
                                add_wait_queue(&km_waitq, &wait);
@@ -1431,6 +1621,7 @@ restart:
                                nx = xfrm_tmpl_resolve(pols, npols, fl, xfrm, family);
 
                                if (nx == -EAGAIN && signal_pending(current)) {
+                                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
                                        err = -ERESTART;
                                        goto error;
                                }
@@ -1441,8 +1632,10 @@ restart:
                                }
                                err = nx;
                        }
-                       if (err < 0)
+                       if (err < 0) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMOUTNOSTATES);
                                goto error;
+                       }
                }
                if (nx == 0) {
                        /* Flow passes not transformed. */
@@ -1450,13 +1643,10 @@ restart:
                        return 0;
                }
 
-               dst = dst_orig;
-               err = xfrm_bundle_create(policy, xfrm, nx, fl, &dst, family);
-
-               if (unlikely(err)) {
-                       int i;
-                       for (i=0; i<nx; i++)
-                               xfrm_state_put(xfrm[i]);
+               dst = xfrm_bundle_create(policy, xfrm, nx, fl, dst_orig);
+               err = PTR_ERR(dst);
+               if (IS_ERR(dst)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLEGENERROR);
                        goto error;
                }
 
@@ -1477,6 +1667,10 @@ restart:
                        if (dst)
                                dst_free(dst);
 
+                       if (pol_dead)
+                               XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
+                       else
+                               XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
                        err = -EHOSTUNREACH;
                        goto error;
                }
@@ -1489,6 +1683,7 @@ restart:
                        write_unlock_bh(&policy->lock);
                        if (dst)
                                dst_free(dst);
+                       XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
                        goto error;
                }
 
@@ -1508,6 +1703,12 @@ dropdst:
        dst_release(dst_orig);
        *dst_p = NULL;
        return err;
+
+nopol:
+       err = -ENOENT;
+       if (flags & XFRM_LOOKUP_ICMP)
+               goto dropdst;
+       return 0;
 }
 EXPORT_SYMBOL(__xfrm_lookup);
 
@@ -1591,8 +1792,8 @@ xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start,
        return start;
 }
 
-int
-xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
+int __xfrm_decode_session(struct sk_buff *skb, struct flowi *fl,
+                         unsigned int family, int reverse)
 {
        struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
        int err;
@@ -1600,12 +1801,12 @@ xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family
        if (unlikely(afinfo == NULL))
                return -EAFNOSUPPORT;
 
-       afinfo->decode_session(skb, fl);
+       afinfo->decode_session(skb, fl, reverse);
        err = security_xfrm_decode_session(skb, &fl->secid);
        xfrm_policy_put_afinfo(afinfo);
        return err;
 }
-EXPORT_SYMBOL(xfrm_decode_session);
+EXPORT_SYMBOL(__xfrm_decode_session);
 
 static inline int secpath_has_nontransport(struct sec_path *sp, int k, int *idxp)
 {
@@ -1627,12 +1828,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
        int npols = 0;
        int xfrm_nr;
        int pi;
+       int reverse;
        struct flowi fl;
-       u8 fl_dir = policy_to_flow_dir(dir);
+       u8 fl_dir;
        int xerr_idx = -1;
 
-       if (xfrm_decode_session(skb, &fl, family) < 0)
+       reverse = dir & ~XFRM_POLICY_MASK;
+       dir &= XFRM_POLICY_MASK;
+       fl_dir = policy_to_flow_dir(dir);
+
+       if (__xfrm_decode_session(skb, &fl, family, reverse) < 0) {
+               XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
                return 0;
+       }
+
        nf_nat_decode_session(skb, &fl, family);
 
        /* First, check used SA against their selectors. */
@@ -1641,28 +1850,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 
                for (i=skb->sp->len-1; i>=0; i--) {
                        struct xfrm_state *x = skb->sp->xvec[i];
-                       if (!xfrm_selector_match(&x->sel, &fl, family))
+                       if (!xfrm_selector_match(&x->sel, &fl, family)) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMISMATCH);
                                return 0;
+                       }
                }
        }
 
        pol = NULL;
        if (sk && sk->sk_policy[dir]) {
                pol = xfrm_sk_policy_lookup(sk, dir, &fl);
-               if (IS_ERR(pol))
+               if (IS_ERR(pol)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
                        return 0;
+               }
        }
 
        if (!pol)
                pol = flow_cache_lookup(&fl, family, fl_dir,
                                        xfrm_policy_lookup);
 
-       if (IS_ERR(pol))
+       if (IS_ERR(pol)) {
+               XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
                return 0;
+       }
 
        if (!pol) {
                if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
                        xfrm_secpath_reject(xerr_idx, skb, &fl);
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINNOPOLS);
                        return 0;
                }
                return 1;
@@ -1678,8 +1894,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
                                                    &fl, family,
                                                    XFRM_POLICY_IN);
                if (pols[1]) {
-                       if (IS_ERR(pols[1]))
+                       if (IS_ERR(pols[1])) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMINPOLERROR);
                                return 0;
+                       }
                        pols[1]->curlft.use_time = get_seconds();
                        npols ++;
                }
@@ -1700,10 +1918,14 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
 
                for (pi = 0; pi < npols; pi++) {
                        if (pols[pi] != pol &&
-                           pols[pi]->action != XFRM_POLICY_ALLOW)
+                           pols[pi]->action != XFRM_POLICY_ALLOW) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
                                goto reject;
-                       if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH)
+                       }
+                       if (ti + pols[pi]->xfrm_nr >= XFRM_MAX_DEPTH) {
+                               XFRM_INC_STATS(LINUX_MIB_XFRMINBUFFERERROR);
                                goto reject_error;
+                       }
                        for (i = 0; i < pols[pi]->xfrm_nr; i++)
                                tpp[ti++] = &pols[pi]->xfrm_vec[i];
                }
@@ -1725,16 +1947,20 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
                                if (k < -1)
                                        /* "-2 - errored_index" returned */
                                        xerr_idx = -(2+k);
+                               XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
                                goto reject;
                        }
                }
 
-               if (secpath_has_nontransport(sp, k, &xerr_idx))
+               if (secpath_has_nontransport(sp, k, &xerr_idx)) {
+                       XFRM_INC_STATS(LINUX_MIB_XFRMINTMPLMISMATCH);
                        goto reject;
+               }
 
                xfrm_pols_put(pols, npols);
                return 1;
        }
+       XFRM_INC_STATS(LINUX_MIB_XFRMINPOLBLOCK);
 
 reject:
        xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -1748,8 +1974,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
        struct flowi fl;
 
-       if (xfrm_decode_session(skb, &fl, family) < 0)
+       if (xfrm_decode_session(skb, &fl, family) < 0) {
+               /* XXX: we should have something like FWDHDRERROR here. */
+               XFRM_INC_STATS(LINUX_MIB_XFRMINHDRERROR);
                return 0;
+       }
 
        return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
 }
@@ -1793,7 +2022,7 @@ static int stale_bundle(struct dst_entry *dst)
 void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
 {
        while ((dst = dst->child) && dst->xfrm && dst->dev == dev) {
-               dst->dev = init_net.loopback_dev;
+               dst->dev = dev->nd_net->loopback_dev;
                dev_hold(dst->dev);
                dev_put(dev);
        }
@@ -1882,7 +2111,7 @@ static int xfrm_flush_bundles(void)
        return 0;
 }
 
-void xfrm_init_pmtu(struct dst_entry *dst)
+static void xfrm_init_pmtu(struct dst_entry *dst)
 {
        do {
                struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
@@ -1903,8 +2132,6 @@ void xfrm_init_pmtu(struct dst_entry *dst)
        } while ((dst = dst->next));
 }
 
-EXPORT_SYMBOL(xfrm_init_pmtu);
-
 /* Check that the bundle accepts the flow and its components are
  * still valid.
  */
@@ -2082,6 +2309,16 @@ static struct notifier_block xfrm_dev_notifier = {
        0
 };
 
+#ifdef CONFIG_XFRM_STATISTICS
+static int __init xfrm_statistics_init(void)
+{
+       if (snmp_mib_init((void **)xfrm_statistics,
+                         sizeof(struct linux_xfrm_mib)) < 0)
+               return -ENOMEM;
+       return 0;
+}
+#endif
+
 static void __init xfrm_policy_init(void)
 {
        unsigned int hmask, sz;
@@ -2118,71 +2355,81 @@ static void __init xfrm_policy_init(void)
 
 void __init xfrm_init(void)
 {
+#ifdef CONFIG_XFRM_STATISTICS
+       xfrm_statistics_init();
+#endif
        xfrm_state_init();
        xfrm_policy_init();
        xfrm_input_init();
+#ifdef CONFIG_XFRM_STATISTICS
+       xfrm_proc_init();
+#endif
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-static inline void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
-                                               struct audit_buffer *audit_buf)
+static void xfrm_audit_common_policyinfo(struct xfrm_policy *xp,
+                                        struct audit_buffer *audit_buf)
 {
-       if (xp->security)
+       struct xfrm_sec_ctx *ctx = xp->security;
+       struct xfrm_selector *sel = &xp->selector;
+
+       if (ctx)
                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
-                                xp->security->ctx_alg, xp->security->ctx_doi,
-                                xp->security->ctx_str);
+                                ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
 
-       switch(xp->selector.family) {
+       switch(sel->family) {
        case AF_INET:
-               audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
-                                NIPQUAD(xp->selector.saddr.a4),
-                                NIPQUAD(xp->selector.daddr.a4));
+               audit_log_format(audit_buf, " src=" NIPQUAD_FMT,
+                                NIPQUAD(sel->saddr.a4));
+               if (sel->prefixlen_s != 32)
+                       audit_log_format(audit_buf, " src_prefixlen=%d",
+                                        sel->prefixlen_s);
+               audit_log_format(audit_buf, " dst=" NIPQUAD_FMT,
+                                NIPQUAD(sel->daddr.a4));
+               if (sel->prefixlen_d != 32)
+                       audit_log_format(audit_buf, " dst_prefixlen=%d",
+                                        sel->prefixlen_d);
                break;
        case AF_INET6:
-               {
-                       struct in6_addr saddr6, daddr6;
-
-                       memcpy(&saddr6, xp->selector.saddr.a6,
-                               sizeof(struct in6_addr));
-                       memcpy(&daddr6, xp->selector.daddr.a6,
-                               sizeof(struct in6_addr));
-                       audit_log_format(audit_buf,
-                               " src=" NIP6_FMT " dst=" NIP6_FMT,
-                               NIP6(saddr6), NIP6(daddr6));
-               }
+               audit_log_format(audit_buf, " src=" NIP6_FMT,
+                                NIP6(*(struct in6_addr *)sel->saddr.a6));
+               if (sel->prefixlen_s != 128)
+                       audit_log_format(audit_buf, " src_prefixlen=%d",
+                                        sel->prefixlen_s);
+               audit_log_format(audit_buf, " dst=" NIP6_FMT,
+                                NIP6(*(struct in6_addr *)sel->daddr.a6));
+               if (sel->prefixlen_d != 128)
+                       audit_log_format(audit_buf, " dst_prefixlen=%d",
+                                        sel->prefixlen_d);
                break;
        }
 }
 
-void
-xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
+                          u32 auid, u32 secid)
 {
        struct audit_buffer *audit_buf;
-       extern int audit_enabled;
 
-       if (audit_enabled == 0)
-               return;
-       audit_buf = xfrm_audit_start(auid, sid);
+       audit_buf = xfrm_audit_start("SPD-add");
        if (audit_buf == NULL)
                return;
-       audit_log_format(audit_buf, " op=SPD-add res=%u", result);
+       xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+       audit_log_format(audit_buf, " res=%u", result);
        xfrm_audit_common_policyinfo(xp, audit_buf);
        audit_log_end(audit_buf);
 }
 EXPORT_SYMBOL_GPL(xfrm_audit_policy_add);
 
-void
-xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
+void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
+                             u32 auid, u32 secid)
 {
        struct audit_buffer *audit_buf;
-       extern int audit_enabled;
 
-       if (audit_enabled == 0)
-               return;
-       audit_buf = xfrm_audit_start(auid, sid);
+       audit_buf = xfrm_audit_start("SPD-delete");
        if (audit_buf == NULL)
                return;
-       audit_log_format(audit_buf, " op=SPD-delete res=%u", result);
+       xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+       audit_log_format(audit_buf, " res=%u", result);
        xfrm_audit_common_policyinfo(xp, audit_buf);
        audit_log_end(audit_buf);
 }
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
new file mode 100644 (file)
index 0000000..31d0354
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * xfrm_proc.c
+ *
+ * Copyright (C)2006-2007 USAGI/WIDE Project
+ *
+ * Authors:    Masahide NAKAMURA <nakam@linux-ipv6.org>
+ *
+ * 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/proc_fs.h>
+#include <linux/seq_file.h>
+#include <net/snmp.h>
+#include <net/xfrm.h>
+
+static struct snmp_mib xfrm_mib_list[] = {
+       SNMP_MIB_ITEM("XfrmInError", LINUX_MIB_XFRMINERROR),
+       SNMP_MIB_ITEM("XfrmInBufferError", LINUX_MIB_XFRMINBUFFERERROR),
+       SNMP_MIB_ITEM("XfrmInHdrError", LINUX_MIB_XFRMINHDRERROR),
+       SNMP_MIB_ITEM("XfrmInNoStates", LINUX_MIB_XFRMINNOSTATES),
+       SNMP_MIB_ITEM("XfrmInStateProtoError", LINUX_MIB_XFRMINSTATEPROTOERROR),
+       SNMP_MIB_ITEM("XfrmInStateModeError", LINUX_MIB_XFRMINSTATEMODEERROR),
+       SNMP_MIB_ITEM("XfrmInSeqOutOfWindow", LINUX_MIB_XFRMINSEQOUTOFWINDOW),
+       SNMP_MIB_ITEM("XfrmInStateExpired", LINUX_MIB_XFRMINSTATEEXPIRED),
+       SNMP_MIB_ITEM("XfrmInStateMismatch", LINUX_MIB_XFRMINSTATEMISMATCH),
+       SNMP_MIB_ITEM("XfrmInStateInvalid", LINUX_MIB_XFRMINSTATEINVALID),
+       SNMP_MIB_ITEM("XfrmInTmplMismatch", LINUX_MIB_XFRMINTMPLMISMATCH),
+       SNMP_MIB_ITEM("XfrmInNoPols", LINUX_MIB_XFRMINNOPOLS),
+       SNMP_MIB_ITEM("XfrmInPolBlock", LINUX_MIB_XFRMINPOLBLOCK),
+       SNMP_MIB_ITEM("XfrmInPolError", LINUX_MIB_XFRMINPOLERROR),
+       SNMP_MIB_ITEM("XfrmOutError", LINUX_MIB_XFRMOUTERROR),
+       SNMP_MIB_ITEM("XfrmOutBundleGenError", LINUX_MIB_XFRMOUTBUNDLEGENERROR),
+       SNMP_MIB_ITEM("XfrmOutBundleCheckError", LINUX_MIB_XFRMOUTBUNDLECHECKERROR),
+       SNMP_MIB_ITEM("XfrmOutNoStates", LINUX_MIB_XFRMOUTNOSTATES),
+       SNMP_MIB_ITEM("XfrmOutStateProtoError", LINUX_MIB_XFRMOUTSTATEPROTOERROR),
+       SNMP_MIB_ITEM("XfrmOutStateModeError", LINUX_MIB_XFRMOUTSTATEMODEERROR),
+       SNMP_MIB_ITEM("XfrmOutStateExpired", LINUX_MIB_XFRMOUTSTATEEXPIRED),
+       SNMP_MIB_ITEM("XfrmOutPolBlock", LINUX_MIB_XFRMOUTPOLBLOCK),
+       SNMP_MIB_ITEM("XfrmOutPolDead", LINUX_MIB_XFRMOUTPOLDEAD),
+       SNMP_MIB_ITEM("XfrmOutPolError", LINUX_MIB_XFRMOUTPOLERROR),
+       SNMP_MIB_SENTINEL
+};
+
+static unsigned long
+fold_field(void *mib[], int offt)
+{
+        unsigned long res = 0;
+        int i;
+
+        for_each_possible_cpu(i) {
+                res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt);
+                res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt);
+        }
+        return res;
+}
+
+static int xfrm_statistics_seq_show(struct seq_file *seq, void *v)
+{
+       int i;
+       for (i=0; xfrm_mib_list[i].name; i++)
+               seq_printf(seq, "%-24s\t%lu\n", xfrm_mib_list[i].name,
+                          fold_field((void **)xfrm_statistics,
+                                     xfrm_mib_list[i].entry));
+       return 0;
+}
+
+static int xfrm_statistics_seq_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, xfrm_statistics_seq_show, NULL);
+}
+
+static struct file_operations xfrm_statistics_seq_fops = {
+       .owner   = THIS_MODULE,
+       .open    = xfrm_statistics_seq_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release,
+};
+
+int __init xfrm_proc_init(void)
+{
+       int rc = 0;
+
+       if (!proc_net_fops_create(&init_net, "xfrm_stat", S_IRUGO,
+                                 &xfrm_statistics_seq_fops))
+               goto stat_fail;
+
+ out:
+       return rc;
+
+ stat_fail:
+       rc = -ENOMEM;
+       goto out;
+}
index f26aaaca1fae78dd92efe9d4e456e2dc1e60d822..3003503d0c94937d570795fcbabf8ce155155130 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/ipsec.h>
 #include <linux/module.h>
 #include <linux/cache.h>
+#include <linux/audit.h>
 #include <asm/uaccess.h>
 
 #include "xfrm_hash.h"
@@ -60,6 +61,13 @@ static unsigned int xfrm_state_genid;
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
+#ifdef CONFIG_AUDITSYSCALL
+static void xfrm_audit_state_replay(struct xfrm_state *x,
+                                   struct sk_buff *skb, __be32 net_seq);
+#else
+#define xfrm_audit_state_replay(x, s, sq)      do { ; } while (0)
+#endif /* CONFIG_AUDITSYSCALL */
+
 static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr,
                                         xfrm_address_t *saddr,
                                         u32 reqid,
@@ -203,6 +211,7 @@ static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family)
 }
 
 static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo)
+       __releases(xfrm_state_afinfo_lock)
 {
        write_unlock_bh(&xfrm_state_afinfo_lock);
 }
@@ -504,12 +513,9 @@ struct xfrm_state *xfrm_state_alloc(void)
                INIT_HLIST_NODE(&x->bydst);
                INIT_HLIST_NODE(&x->bysrc);
                INIT_HLIST_NODE(&x->byspi);
-               init_timer(&x->timer);
-               x->timer.function = xfrm_timer_handler;
-               x->timer.data     = (unsigned long)x;
-               init_timer(&x->rtimer);
-               x->rtimer.function = xfrm_replay_timer_handler;
-               x->rtimer.data     = (unsigned long)x;
+               setup_timer(&x->timer, xfrm_timer_handler, (unsigned long)x);
+               setup_timer(&x->rtimer, xfrm_replay_timer_handler,
+                               (unsigned long)x);
                x->curlft.add_time = get_seconds();
                x->lft.soft_byte_limit = XFRM_INF;
                x->lft.soft_packet_limit = XFRM_INF;
@@ -759,7 +765,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                struct xfrm_policy *pol, int *err,
                unsigned short family)
 {
-       unsigned int h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
+       unsigned int h;
        struct hlist_node *entry;
        struct xfrm_state *x, *x0;
        int acquire_in_progress = 0;
@@ -767,6 +773,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
        struct xfrm_state *best = NULL;
 
        spin_lock_bh(&xfrm_state_lock);
+       h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
        hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
                if (x->props.family == family &&
                    x->props.reqid == tmpl->reqid &&
@@ -868,11 +875,12 @@ struct xfrm_state *
 xfrm_stateonly_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                    unsigned short family, u8 mode, u8 proto, u32 reqid)
 {
-       unsigned int h = xfrm_dst_hash(daddr, saddr, reqid, family);
+       unsigned int h;
        struct xfrm_state *rx = NULL, *x = NULL;
        struct hlist_node *entry;
 
        spin_lock(&xfrm_state_lock);
+       h = xfrm_dst_hash(daddr, saddr, reqid, family);
        hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
                if (x->props.family == family &&
                    x->props.reqid == reqid &&
@@ -1092,7 +1100,7 @@ out:
 EXPORT_SYMBOL(xfrm_state_add);
 
 #ifdef CONFIG_XFRM_MIGRATE
-struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
+static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
 {
        int err = -ENOMEM;
        struct xfrm_state *x = xfrm_state_alloc();
@@ -1167,7 +1175,6 @@ struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
        kfree(x);
        return NULL;
 }
-EXPORT_SYMBOL(xfrm_state_clone);
 
 /* xfrm_state_lock is held */
 struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m)
@@ -1609,13 +1616,14 @@ static void xfrm_replay_timer_handler(unsigned long data)
        spin_unlock(&x->lock);
 }
 
-int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
+int xfrm_replay_check(struct xfrm_state *x,
+                     struct sk_buff *skb, __be32 net_seq)
 {
        u32 diff;
        u32 seq = ntohl(net_seq);
 
        if (unlikely(seq == 0))
-               return -EINVAL;
+               goto err;
 
        if (likely(seq > x->replay.seq))
                return 0;
@@ -1624,14 +1632,18 @@ int xfrm_replay_check(struct xfrm_state *x, __be32 net_seq)
        if (diff >= min_t(unsigned int, x->props.replay_window,
                          sizeof(x->replay.bitmap) * 8)) {
                x->stats.replay_window++;
-               return -EINVAL;
+               goto err;
        }
 
        if (x->replay.bitmap & (1U << diff)) {
                x->stats.replay++;
-               return -EINVAL;
+               goto err;
        }
        return 0;
+
+err:
+       xfrm_audit_state_replay(x, skb, net_seq);
+       return -EINVAL;
 }
 EXPORT_SYMBOL(xfrm_replay_check);
 
@@ -1657,7 +1669,7 @@ void xfrm_replay_advance(struct xfrm_state *x, __be32 net_seq)
 }
 EXPORT_SYMBOL(xfrm_replay_advance);
 
-static struct list_head xfrm_km_list = LIST_HEAD_INIT(xfrm_km_list);
+static LIST_HEAD(xfrm_km_list);
 static DEFINE_RWLOCK(xfrm_km_lock);
 
 void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c)
@@ -1897,6 +1909,7 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
 }
 
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo)
+       __releases(xfrm_state_afinfo_lock)
 {
        read_unlock(&xfrm_state_afinfo_lock);
 }
@@ -1996,73 +2009,172 @@ void __init xfrm_state_init(void)
 }
 
 #ifdef CONFIG_AUDITSYSCALL
-static inline void xfrm_audit_common_stateinfo(struct xfrm_state *x,
-                                              struct audit_buffer *audit_buf)
+static void xfrm_audit_helper_sainfo(struct xfrm_state *x,
+                                    struct audit_buffer *audit_buf)
 {
-       if (x->security)
+       struct xfrm_sec_ctx *ctx = x->security;
+       u32 spi = ntohl(x->id.spi);
+
+       if (ctx)
                audit_log_format(audit_buf, " sec_alg=%u sec_doi=%u sec_obj=%s",
-                                x->security->ctx_alg, x->security->ctx_doi,
-                                x->security->ctx_str);
+                                ctx->ctx_alg, ctx->ctx_doi, ctx->ctx_str);
 
        switch(x->props.family) {
        case AF_INET:
-               audit_log_format(audit_buf, " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
+               audit_log_format(audit_buf,
+                                " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
                                 NIPQUAD(x->props.saddr.a4),
                                 NIPQUAD(x->id.daddr.a4));
                break;
        case AF_INET6:
-               {
-                       struct in6_addr saddr6, daddr6;
-
-                       memcpy(&saddr6, x->props.saddr.a6,
-                               sizeof(struct in6_addr));
-                       memcpy(&daddr6, x->id.daddr.a6,
-                               sizeof(struct in6_addr));
-                       audit_log_format(audit_buf,
-                                        " src=" NIP6_FMT " dst=" NIP6_FMT,
-                                        NIP6(saddr6), NIP6(daddr6));
-               }
+               audit_log_format(audit_buf,
+                                " src=" NIP6_FMT " dst=" NIP6_FMT,
+                                NIP6(*(struct in6_addr *)x->props.saddr.a6),
+                                NIP6(*(struct in6_addr *)x->id.daddr.a6));
                break;
        }
+
+       audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
 }
 
-void
-xfrm_audit_state_add(struct xfrm_state *x, int result, u32 auid, u32 sid)
+static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
+                                     struct audit_buffer *audit_buf)
+{
+       struct iphdr *iph4;
+       struct ipv6hdr *iph6;
+
+       switch (family) {
+       case AF_INET:
+               iph4 = ip_hdr(skb);
+               audit_log_format(audit_buf,
+                                " src=" NIPQUAD_FMT " dst=" NIPQUAD_FMT,
+                                NIPQUAD(iph4->saddr),
+                                NIPQUAD(iph4->daddr));
+               break;
+       case AF_INET6:
+               iph6 = ipv6_hdr(skb);
+               audit_log_format(audit_buf,
+                                " src=" NIP6_FMT " dst=" NIP6_FMT
+                                " flowlbl=0x%x%x%x",
+                                NIP6(iph6->saddr),
+                                NIP6(iph6->daddr),
+                                iph6->flow_lbl[0] & 0x0f,
+                                iph6->flow_lbl[1],
+                                iph6->flow_lbl[2]);
+               break;
+       }
+}
+
+void xfrm_audit_state_add(struct xfrm_state *x, int result,
+                         u32 auid, u32 secid)
 {
        struct audit_buffer *audit_buf;
-       u32 spi;
-       extern int audit_enabled;
 
-       if (audit_enabled == 0)
+       audit_buf = xfrm_audit_start("SAD-add");
+       if (audit_buf == NULL)
                return;
-       audit_buf = xfrm_audit_start(auid, sid);
+       xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+       xfrm_audit_helper_sainfo(x, audit_buf);
+       audit_log_format(audit_buf, " res=%u", result);
+       audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
+
+void xfrm_audit_state_delete(struct xfrm_state *x, int result,
+                            u32 auid, u32 secid)
+{
+       struct audit_buffer *audit_buf;
+
+       audit_buf = xfrm_audit_start("SAD-delete");
        if (audit_buf == NULL)
                return;
-       audit_log_format(audit_buf, " op=SAD-add res=%u",result);
-       xfrm_audit_common_stateinfo(x, audit_buf);
+       xfrm_audit_helper_usrinfo(auid, secid, audit_buf);
+       xfrm_audit_helper_sainfo(x, audit_buf);
+       audit_log_format(audit_buf, " res=%u", result);
+       audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
+
+void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
+                                     struct sk_buff *skb)
+{
+       struct audit_buffer *audit_buf;
+       u32 spi;
+
+       audit_buf = xfrm_audit_start("SA-replay-overflow");
+       if (audit_buf == NULL)
+               return;
+       xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
+       /* don't record the sequence number because it's inherent in this kind
+        * of audit message */
        spi = ntohl(x->id.spi);
        audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
        audit_log_end(audit_buf);
 }
-EXPORT_SYMBOL_GPL(xfrm_audit_state_add);
+EXPORT_SYMBOL_GPL(xfrm_audit_state_replay_overflow);
 
-void
-xfrm_audit_state_delete(struct xfrm_state *x, int result, u32 auid, u32 sid)
+static void xfrm_audit_state_replay(struct xfrm_state *x,
+                            struct sk_buff *skb, __be32 net_seq)
 {
        struct audit_buffer *audit_buf;
        u32 spi;
-       extern int audit_enabled;
 
-       if (audit_enabled == 0)
-               return;
-       audit_buf = xfrm_audit_start(auid, sid);
+       audit_buf = xfrm_audit_start("SA-replayed-pkt");
        if (audit_buf == NULL)
                return;
-       audit_log_format(audit_buf, " op=SAD-delete res=%u",result);
-       xfrm_audit_common_stateinfo(x, audit_buf);
+       xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
        spi = ntohl(x->id.spi);
-       audit_log_format(audit_buf, " spi=%u(0x%x)", spi, spi);
+       audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+                        spi, spi, ntohl(net_seq));
        audit_log_end(audit_buf);
 }
-EXPORT_SYMBOL_GPL(xfrm_audit_state_delete);
+
+void xfrm_audit_state_notfound_simple(struct sk_buff *skb, u16 family)
+{
+       struct audit_buffer *audit_buf;
+
+       audit_buf = xfrm_audit_start("SA-notfound");
+       if (audit_buf == NULL)
+               return;
+       xfrm_audit_helper_pktinfo(skb, family, audit_buf);
+       audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound_simple);
+
+void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
+                              __be32 net_spi, __be32 net_seq)
+{
+       struct audit_buffer *audit_buf;
+       u32 spi;
+
+       audit_buf = xfrm_audit_start("SA-notfound");
+       if (audit_buf == NULL)
+               return;
+       xfrm_audit_helper_pktinfo(skb, family, audit_buf);
+       spi = ntohl(net_spi);
+       audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+                        spi, spi, ntohl(net_seq));
+       audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_notfound);
+
+void xfrm_audit_state_icvfail(struct xfrm_state *x,
+                             struct sk_buff *skb, u8 proto)
+{
+       struct audit_buffer *audit_buf;
+       __be32 net_spi;
+       __be32 net_seq;
+
+       audit_buf = xfrm_audit_start("SA-icv-failure");
+       if (audit_buf == NULL)
+               return;
+       xfrm_audit_helper_pktinfo(skb, x->props.family, audit_buf);
+       if (xfrm_parse_spi(skb, proto, &net_spi, &net_seq) == 0) {
+               u32 spi = ntohl(net_spi);
+               audit_log_format(audit_buf, " spi=%u(0x%x) seqno=%u",
+                                spi, spi, ntohl(net_seq));
+       }
+       audit_log_end(audit_buf);
+}
+EXPORT_SYMBOL_GPL(xfrm_audit_state_icvfail);
 #endif /* CONFIG_AUDITSYSCALL */
index c4f6419b176943bd54752c644f0b4cc937587327..e0ccdf26781360fc8c2860ddbb3b33ec0dafc7d0 100644 (file)
@@ -1043,7 +1043,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
        return xp;
  error:
        *errp = err;
-       kfree(xp);
+       xfrm_policy_destroy(xp);
        return NULL;
 }
 
@@ -1986,8 +1986,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
        if (x->coaddr)
                l += nla_total_size(sizeof(*x->coaddr));
 
-       /* Must count this as this may become non-zero behind our back. */
-       l += nla_total_size(sizeof(x->lastused));
+       /* Must count x->lastused as it may become non-zero behind our back. */
+       l += nla_total_size(sizeof(u64));
 
        return l;
 }
@@ -2420,7 +2420,7 @@ static void __exit xfrm_user_exit(void)
        xfrm_unregister_km(&netlink_mgr);
        rcu_assign_pointer(xfrm_nl, NULL);
        synchronize_rcu();
-       sock_release(nlsk->sk_socket);
+       netlink_kernel_release(nlsk);
 }
 
 module_init(xfrm_user_init);
index 0396354fff9521b7146ff1aff96e3f9c384a6857..64d414efb404e67d614d5279c8b44fac9431d1f4 100644 (file)
@@ -5281,7 +5281,7 @@ static struct nf_hook_ops selinux_ipv4_op = {
        .hook =         selinux_ipv4_postroute_last,
        .owner =        THIS_MODULE,
        .pf =           PF_INET,
-       .hooknum =      NF_IP_POST_ROUTING,
+       .hooknum =      NF_INET_POST_ROUTING,
        .priority =     NF_IP_PRI_SELINUX_LAST,
 };
 
@@ -5291,7 +5291,7 @@ static struct nf_hook_ops selinux_ipv6_op = {
        .hook =         selinux_ipv6_postroute_last,
        .owner =        THIS_MODULE,
        .pf =           PF_INET6,
-       .hooknum =      NF_IP6_POST_ROUTING,
+       .hooknum =      NF_INET_POST_ROUTING,
        .priority =     NF_IP6_PRI_SELINUX_LAST,
 };